From 63cd36819dda0d1ac8799b55d0a9fa865b133282 Mon Sep 17 00:00:00 2001 From: trackers-love Date: Mon, 1 Dec 2025 17:36:58 +0800 Subject: [PATCH 1/2] remove submodule gitlink for utshell-0.5.0 --- utshell-0.5.0 | 1 - 1 file changed, 1 deletion(-) delete mode 160000 utshell-0.5.0 diff --git a/utshell-0.5.0 b/utshell-0.5.0 deleted file mode 160000 index 4d3931b1..00000000 --- a/utshell-0.5.0 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4d3931b17305a1ce3771653afe001c37479e445b -- Gitee From 308313b621c745926e12fed032237c29b003fa68 Mon Sep 17 00:00:00 2001 From: trackers-love Date: Mon, 1 Dec 2025 17:38:35 +0800 Subject: [PATCH 2/2] restore utshell-0.5.0 contents as regular directory --- utshell-0.5.0/COPYING | 674 + utshell-0.5.0/Cargo.toml | 42 + utshell-0.5.0/Makefile | 52 + utshell-0.5.0/README.md | 51 + utshell-0.5.0/README.zh_CN.md | 45 + utshell-0.5.0/build.rs | 106 + utshell-0.5.0/config/.utshell_logout | 2 + utshell-0.5.0/config/.utshell_profile | 12 + utshell-0.5.0/config/.utshellrc | 16 + utshell-0.5.0/config/utshellrc | 98 + utshell-0.5.0/lib/Makefile | 26 + utshell-0.5.0/lib/glob/Makefile | 167 + utshell-0.5.0/lib/glob/Makefile.in | 167 + utshell-0.5.0/lib/glob/collsyms.h | 140 + utshell-0.5.0/lib/glob/doc/Makefile | 5 + utshell-0.5.0/lib/glob/doc/glob.texi | 1 + utshell-0.5.0/lib/glob/glob.c | 1554 ++ utshell-0.5.0/lib/glob/glob.h | 46 + utshell-0.5.0/lib/glob/glob_loop.c | 84 + utshell-0.5.0/lib/glob/gm_loop.c | 208 + utshell-0.5.0/lib/glob/gmisc.c | 108 + utshell-0.5.0/lib/glob/ndir.h | 50 + utshell-0.5.0/lib/glob/sm_loop.c | 942 + utshell-0.5.0/lib/glob/smatch.c | 617 + utshell-0.5.0/lib/glob/strmatch.c | 79 + utshell-0.5.0/lib/glob/strmatch.h | 64 + utshell-0.5.0/lib/glob/xmbsrtowcs.c | 523 + utshell-0.5.0/lib/include/alias.h | 74 + utshell-0.5.0/lib/include/ansi_stdlib.h | 54 + utshell-0.5.0/lib/include/array.h | 128 + utshell-0.5.0/lib/include/arrayfunc.h | 101 + utshell-0.5.0/lib/include/assoc.h | 66 + utshell-0.5.0/lib/include/bashansi.h | 42 + utshell-0.5.0/lib/include/bashintl.h | 55 + utshell-0.5.0/lib/include/bashjmp.h | 47 + utshell-0.5.0/lib/include/bashtypes.h | 43 + utshell-0.5.0/lib/include/builtins.h | 69 + utshell-0.5.0/lib/include/chartypes.h | 113 + utshell-0.5.0/lib/include/command.h | 409 + utshell-0.5.0/lib/include/config-bot.h | 208 + utshell-0.5.0/lib/include/config-top.h | 200 + utshell-0.5.0/lib/include/config.h | 1250 ++ utshell-0.5.0/lib/include/conftypes.h | 59 + utshell-0.5.0/lib/include/dispose_cmd.h | 41 + utshell-0.5.0/lib/include/error.h | 74 + utshell-0.5.0/lib/include/externs.h | 549 + utshell-0.5.0/lib/include/filecntl.h | 53 + utshell-0.5.0/lib/include/general.h | 372 + utshell-0.5.0/lib/include/gettext.h | 70 + utshell-0.5.0/lib/include/hashlib.h | 93 + utshell-0.5.0/lib/include/make_cmd.h | 73 + utshell-0.5.0/lib/include/maxpath.h | 75 + utshell-0.5.0/lib/include/memalloc.h | 62 + utshell-0.5.0/lib/include/ocache.h | 133 + utshell-0.5.0/lib/include/pathnames.h | 33 + utshell-0.5.0/lib/include/posixdir.h | 71 + utshell-0.5.0/lib/include/posixjmp.h | 46 + utshell-0.5.0/lib/include/posixselect.h | 47 + utshell-0.5.0/lib/include/posixstat.h | 162 + utshell-0.5.0/lib/include/posixtime.h | 61 + utshell-0.5.0/lib/include/posixwait.h | 107 + utshell-0.5.0/lib/include/quit.h | 82 + utshell-0.5.0/lib/include/shell.h | 231 + utshell-0.5.0/lib/include/shmbchar.h | 112 + utshell-0.5.0/lib/include/shmbutil.h | 551 + utshell-0.5.0/lib/include/shtty.h | 112 + utshell-0.5.0/lib/include/sig.h | 141 + utshell-0.5.0/lib/include/stat-time.h | 214 + utshell-0.5.0/lib/include/stdc.h | 89 + utshell-0.5.0/lib/include/strmatch.h | 64 + utshell-0.5.0/lib/include/subst.h | 355 + utshell-0.5.0/lib/include/syntax.h | 107 + utshell-0.5.0/lib/include/systimes.h | 55 + utshell-0.5.0/lib/include/tilde.h | 80 + utshell-0.5.0/lib/include/trap.h | 129 + utshell-0.5.0/lib/include/typemax.h | 131 + utshell-0.5.0/lib/include/unionwait.h | 98 + utshell-0.5.0/lib/include/unwind_prot.h | 53 + utshell-0.5.0/lib/include/variables.h | 459 + utshell-0.5.0/lib/include/xmalloc.h | 67 + utshell-0.5.0/lib/intl/ChangeLog | 4 + utshell-0.5.0/lib/intl/Makefile | 472 + utshell-0.5.0/lib/intl/Makefile.in | 472 + utshell-0.5.0/lib/intl/VERSION | 1 + utshell-0.5.0/lib/intl/bindtextdom.c | 376 + utshell-0.5.0/lib/intl/config.charset | 465 + utshell-0.5.0/lib/intl/dcgettext.c | 61 + utshell-0.5.0/lib/intl/dcigettext.c | 1248 ++ utshell-0.5.0/lib/intl/dcngettext.c | 62 + utshell-0.5.0/lib/intl/dgettext.c | 61 + utshell-0.5.0/lib/intl/dngettext.c | 63 + utshell-0.5.0/lib/intl/eval-plural.h | 116 + utshell-0.5.0/lib/intl/explodename.c | 195 + utshell-0.5.0/lib/intl/finddomain.c | 197 + utshell-0.5.0/lib/intl/gettext.c | 66 + utshell-0.5.0/lib/intl/gettextP.h | 226 + utshell-0.5.0/lib/intl/gmo.h | 150 + utshell-0.5.0/lib/intl/hash-string.h | 61 + utshell-0.5.0/lib/intl/intl-compat.c | 152 + utshell-0.5.0/lib/intl/l10nflist.c | 459 + utshell-0.5.0/lib/intl/libgnuintl.h.in | 311 + utshell-0.5.0/lib/intl/loadinfo.h | 159 + utshell-0.5.0/lib/intl/loadmsgcat.c | 1336 ++ utshell-0.5.0/lib/intl/localcharset.c | 399 + utshell-0.5.0/lib/intl/localcharset.h | 43 + utshell-0.5.0/lib/intl/locale.alias | 78 + utshell-0.5.0/lib/intl/localealias.c | 427 + utshell-0.5.0/lib/intl/localename.c | 774 + utshell-0.5.0/lib/intl/log.c | 106 + utshell-0.5.0/lib/intl/ngettext.c | 70 + utshell-0.5.0/lib/intl/os2compat.c | 100 + utshell-0.5.0/lib/intl/os2compat.h | 48 + utshell-0.5.0/lib/intl/osdep.c | 26 + utshell-0.5.0/lib/intl/plural-exp.c | 158 + utshell-0.5.0/lib/intl/plural-exp.h | 128 + utshell-0.5.0/lib/intl/plural.c | 1679 ++ utshell-0.5.0/lib/intl/plural.y | 411 + utshell-0.5.0/lib/intl/ref-add.sin | 29 + utshell-0.5.0/lib/intl/ref-del.sin | 24 + utshell-0.5.0/lib/intl/relocatable.c | 440 + utshell-0.5.0/lib/intl/relocatable.h | 69 + utshell-0.5.0/lib/intl/textdomain.c | 144 + utshell-0.5.0/lib/malloc/Makefile | 138 + utshell-0.5.0/lib/malloc/Makefile.in | 138 + utshell-0.5.0/lib/malloc/alloca.c | 482 + utshell-0.5.0/lib/malloc/getpagesize.h | 60 + utshell-0.5.0/lib/malloc/i386-alloca.s | 16 + utshell-0.5.0/lib/malloc/imalloc.h | 173 + utshell-0.5.0/lib/malloc/malloc.c | 1481 ++ utshell-0.5.0/lib/malloc/mstats.h | 114 + utshell-0.5.0/lib/malloc/shmalloc.h | 70 + utshell-0.5.0/lib/malloc/stats.c | 213 + utshell-0.5.0/lib/malloc/stub.c | 22 + utshell-0.5.0/lib/malloc/table.c | 429 + utshell-0.5.0/lib/malloc/table.h | 116 + utshell-0.5.0/lib/malloc/trace.c | 126 + utshell-0.5.0/lib/malloc/watch.c | 151 + utshell-0.5.0/lib/malloc/watch.h | 41 + utshell-0.5.0/lib/malloc/x386-alloca.s | 63 + utshell-0.5.0/lib/malloc/xleaktrace | 47 + utshell-0.5.0/lib/malloc/xmalloc.c | 94 + utshell-0.5.0/lib/r2c.c | 38 + utshell-0.5.0/lib/r2c.o | Bin 0 -> 1664 bytes utshell-0.5.0/lib/r2c/Makefile | 26 + utshell-0.5.0/lib/r2c/libr2c.a | Bin 0 -> 6788 bytes utshell-0.5.0/lib/r2c/r2c.c | 40 + utshell-0.5.0/lib/r2c/r2c.o | Bin 0 -> 6624 bytes utshell-0.5.0/lib/readline/COPYING | 674 + utshell-0.5.0/lib/readline/ChangeLog | 403 + utshell-0.5.0/lib/readline/Makefile | 394 + utshell-0.5.0/lib/readline/Makefile.in | 394 + utshell-0.5.0/lib/readline/README | 6 + utshell-0.5.0/lib/readline/STANDALONE | 2 + utshell-0.5.0/lib/readline/ansi_stdlib.h | 54 + utshell-0.5.0/lib/readline/bind.c | 2970 +++ utshell-0.5.0/lib/readline/callback.c | 360 + utshell-0.5.0/lib/readline/chardefs.h | 164 + utshell-0.5.0/lib/readline/colors.c | 301 + utshell-0.5.0/lib/readline/colors.h | 126 + utshell-0.5.0/lib/readline/compat.c | 106 + utshell-0.5.0/lib/readline/complete.c | 2990 +++ utshell-0.5.0/lib/readline/display.c | 3557 +++ utshell-0.5.0/lib/readline/doc/fdl.texi | 506 + utshell-0.5.0/lib/readline/doc/history.texi | 85 + utshell-0.5.0/lib/readline/doc/hstech.texi | 602 + utshell-0.5.0/lib/readline/doc/hsuser.texi | 527 + utshell-0.5.0/lib/readline/doc/rlman.texi | 84 + utshell-0.5.0/lib/readline/doc/rltech.texi | 2757 +++ utshell-0.5.0/lib/readline/doc/rluser.texi | 2422 ++ utshell-0.5.0/lib/readline/doc/rluserman.texi | 70 + utshell-0.5.0/lib/readline/doc/version.texi | 10 + utshell-0.5.0/lib/readline/emacs_keymap.c | 872 + utshell-0.5.0/lib/readline/examples/Inputrc | 81 + utshell-0.5.0/lib/readline/examples/Makefile | 44 + .../lib/readline/examples/excallback.c | 196 + utshell-0.5.0/lib/readline/examples/fileman.c | 506 + .../lib/readline/examples/histexamp.c | 125 + .../lib/readline/examples/manexamp.c | 111 + .../lib/readline/examples/rl-callbacktest.c | 90 + utshell-0.5.0/lib/readline/examples/rl.c | 158 + utshell-0.5.0/lib/readline/examples/rlcat.c | 179 + utshell-0.5.0/lib/readline/examples/rltest.c | 93 + utshell-0.5.0/lib/readline/funmap.c | 271 + utshell-0.5.0/lib/readline/histexpand.c | 1695 ++ utshell-0.5.0/lib/readline/histfile.c | 835 + utshell-0.5.0/lib/readline/histlib.h | 85 + utshell-0.5.0/lib/readline/history.c | 607 + utshell-0.5.0/lib/readline/history.h | 286 + utshell-0.5.0/lib/readline/histsearch.c | 287 + utshell-0.5.0/lib/readline/input.c | 715 + utshell-0.5.0/lib/readline/isearch.c | 890 + utshell-0.5.0/lib/readline/keymaps.c | 174 + utshell-0.5.0/lib/readline/keymaps.h | 100 + utshell-0.5.0/lib/readline/kill.c | 866 + utshell-0.5.0/lib/readline/macro.c | 332 + utshell-0.5.0/lib/readline/mbutil.c | 524 + utshell-0.5.0/lib/readline/misc.c | 737 + utshell-0.5.0/lib/readline/nls.c | 290 + utshell-0.5.0/lib/readline/parens.c | 180 + utshell-0.5.0/lib/readline/parse-colors.c | 440 + utshell-0.5.0/lib/readline/parse-colors.h | 46 + utshell-0.5.0/lib/readline/posixdir.h | 71 + utshell-0.5.0/lib/readline/posixjmp.h | 46 + utshell-0.5.0/lib/readline/posixselect.h | 47 + utshell-0.5.0/lib/readline/posixstat.h | 162 + utshell-0.5.0/lib/readline/readline.c | 1581 ++ utshell-0.5.0/lib/readline/readline.h | 969 + utshell-0.5.0/lib/readline/rlconf.h | 79 + utshell-0.5.0/lib/readline/rldefs.h | 166 + utshell-0.5.0/lib/readline/rlmbutil.h | 213 + utshell-0.5.0/lib/readline/rlprivate.h | 605 + utshell-0.5.0/lib/readline/rlshell.h | 33 + utshell-0.5.0/lib/readline/rlstdc.h | 57 + utshell-0.5.0/lib/readline/rltty.c | 991 + utshell-0.5.0/lib/readline/rltty.h | 80 + utshell-0.5.0/lib/readline/rltypedefs.h | 100 + utshell-0.5.0/lib/readline/rlwinsize.h | 58 + utshell-0.5.0/lib/readline/savestring.c | 40 + utshell-0.5.0/lib/readline/search.c | 695 + utshell-0.5.0/lib/readline/shell.c | 214 + utshell-0.5.0/lib/readline/signals.c | 779 + utshell-0.5.0/lib/readline/tcap.h | 60 + utshell-0.5.0/lib/readline/terminal.c | 845 + utshell-0.5.0/lib/readline/text.c | 1880 ++ utshell-0.5.0/lib/readline/tilde.c | 493 + utshell-0.5.0/lib/readline/tilde.h | 80 + utshell-0.5.0/lib/readline/undo.c | 367 + utshell-0.5.0/lib/readline/util.c | 576 + utshell-0.5.0/lib/readline/vi_keymap.c | 875 + utshell-0.5.0/lib/readline/vi_mode.c | 2408 ++ utshell-0.5.0/lib/readline/xfree.c | 49 + utshell-0.5.0/lib/readline/xmalloc.c | 75 + utshell-0.5.0/lib/readline/xmalloc.h | 45 + utshell-0.5.0/lib/sh/Makefile | 641 + utshell-0.5.0/lib/sh/Makefile.in | 639 + utshell-0.5.0/lib/sh/casemod.c | 273 + utshell-0.5.0/lib/sh/clktck.c | 61 + utshell-0.5.0/lib/sh/clock.c | 87 + utshell-0.5.0/lib/sh/dprintf.c | 70 + utshell-0.5.0/lib/sh/eaccess.c | 244 + utshell-0.5.0/lib/sh/fmtullong.c | 31 + utshell-0.5.0/lib/sh/fmtulong.c | 191 + utshell-0.5.0/lib/sh/fmtumax.c | 27 + utshell-0.5.0/lib/sh/fnxform.c | 199 + utshell-0.5.0/lib/sh/fpurge.c | 232 + utshell-0.5.0/lib/sh/getcwd.c | 356 + utshell-0.5.0/lib/sh/getenv.c | 233 + utshell-0.5.0/lib/sh/gettimeofday.c | 35 + utshell-0.5.0/lib/sh/inet_aton.c | 214 + utshell-0.5.0/lib/sh/input_avail.c | 165 + utshell-0.5.0/lib/sh/itos.c | 84 + utshell-0.5.0/lib/sh/mailstat.c | 159 + utshell-0.5.0/lib/sh/makepath.c | 128 + utshell-0.5.0/lib/sh/mbscasecmp.c | 79 + utshell-0.5.0/lib/sh/mbschr.c | 91 + utshell-0.5.0/lib/sh/mbscmp.c | 77 + utshell-0.5.0/lib/sh/memset.c | 29 + utshell-0.5.0/lib/sh/mktime.c | 438 + utshell-0.5.0/lib/sh/netconn.c | 82 + utshell-0.5.0/lib/sh/netopen.c | 351 + utshell-0.5.0/lib/sh/oslib.c | 301 + utshell-0.5.0/lib/sh/pathcanon.c | 234 + utshell-0.5.0/lib/sh/pathphys.c | 296 + utshell-0.5.0/lib/sh/random.c | 240 + utshell-0.5.0/lib/sh/rename.c | 76 + utshell-0.5.0/lib/sh/setlinebuf.c | 63 + utshell-0.5.0/lib/sh/shmatch.c | 123 + utshell-0.5.0/lib/sh/shmbchar.c | 137 + utshell-0.5.0/lib/sh/shquote.c | 434 + utshell-0.5.0/lib/sh/shtty.c | 330 + utshell-0.5.0/lib/sh/snprintf.c | 2221 ++ utshell-0.5.0/lib/sh/spell.c | 212 + utshell-0.5.0/lib/sh/strcasecmp.c | 84 + utshell-0.5.0/lib/sh/strcasestr.c | 46 + utshell-0.5.0/lib/sh/strchrnul.c | 35 + utshell-0.5.0/lib/sh/strdup.c | 42 + utshell-0.5.0/lib/sh/strerror.c | 74 + utshell-0.5.0/lib/sh/strftime.c | 1015 + utshell-0.5.0/lib/sh/stringlist.c | 297 + utshell-0.5.0/lib/sh/stringvec.c | 272 + utshell-0.5.0/lib/sh/strnlen.c | 49 + utshell-0.5.0/lib/sh/strpbrk.c | 49 + utshell-0.5.0/lib/sh/strstr.c | 125 + utshell-0.5.0/lib/sh/strtod.c | 207 + utshell-0.5.0/lib/sh/strtoimax.c | 113 + utshell-0.5.0/lib/sh/strtol.c | 259 + utshell-0.5.0/lib/sh/strtoll.c | 30 + utshell-0.5.0/lib/sh/strtoul.c | 30 + utshell-0.5.0/lib/sh/strtoull.c | 31 + utshell-0.5.0/lib/sh/strtoumax.c | 113 + utshell-0.5.0/lib/sh/strtrans.c | 400 + utshell-0.5.0/lib/sh/times.c | 77 + utshell-0.5.0/lib/sh/timeval.c | 179 + utshell-0.5.0/lib/sh/tmpfile.c | 311 + utshell-0.5.0/lib/sh/uconvert.c | 124 + utshell-0.5.0/lib/sh/ufuncs.c | 140 + utshell-0.5.0/lib/sh/unicode.c | 339 + utshell-0.5.0/lib/sh/utf8.c | 196 + utshell-0.5.0/lib/sh/vprint.c | 85 + utshell-0.5.0/lib/sh/wcsdup.c | 44 + utshell-0.5.0/lib/sh/wcsnwidth.c | 56 + utshell-0.5.0/lib/sh/wcswidth.c | 46 + utshell-0.5.0/lib/sh/winsize.c | 98 + utshell-0.5.0/lib/sh/zcatfd.c | 74 + utshell-0.5.0/lib/sh/zgetline.c | 125 + utshell-0.5.0/lib/sh/zmapfd.c | 93 + utshell-0.5.0/lib/sh/zread.c | 224 + utshell-0.5.0/lib/sh/zwrite.c | 64 + utshell-0.5.0/lib/support/config.sub | 1828 ++ utshell-0.5.0/lib/termcap/Makefile | 91 + utshell-0.5.0/lib/termcap/Makefile.in | 92 + utshell-0.5.0/lib/termcap/ltcap.h | 30 + utshell-0.5.0/lib/termcap/termcap.c | 817 + utshell-0.5.0/lib/termcap/termcap.h | 63 + utshell-0.5.0/lib/termcap/test/a | Bin 0 -> 16408 bytes utshell-0.5.0/lib/termcap/test/libglob.a | Bin 0 -> 332852 bytes utshell-0.5.0/lib/termcap/test/libtermcap.a | Bin 0 -> 78036 bytes utshell-0.5.0/lib/termcap/test/main.c | 4 + utshell-0.5.0/lib/termcap/tparam.c | 345 + utshell-0.5.0/lib/termcap/version.c | 22 + utshell-0.5.0/lib/test/libtest.a | Bin 0 -> 1692 bytes utshell-0.5.0/lib/test/libtest1.a | Bin 0 -> 1692 bytes utshell-0.5.0/lib/test/test.c | 5 + utshell-0.5.0/lib/test/test.o | Bin 0 -> 1544 bytes utshell-0.5.0/lib/test/test1.c | 5 + utshell-0.5.0/lib/test/test1.o | Bin 0 -> 1544 bytes utshell-0.5.0/lib/tilde/Makefile | 124 + utshell-0.5.0/lib/tilde/Makefile.in | 124 + utshell-0.5.0/lib/tilde/README | 5 + utshell-0.5.0/lib/tilde/shell.c | 79 + utshell-0.5.0/lib/tilde/tilde.c | 493 + utshell-0.5.0/lib/tilde/tilde.h | 80 + utshell-0.5.0/resources/en-US/message.ftl | 1806 ++ utshell-0.5.0/resources/zh-CN/message.ftl | 1640 ++ utshell-0.5.0/resources/zh-HK/message.ftl | 1638 ++ utshell-0.5.0/src/1.sh | 6 + utshell-0.5.0/src/1.txt | 50 + utshell-0.5.0/src/README.txt | 57 + utshell-0.5.0/src/alias.rs | 495 + utshell-0.5.0/src/array.rs | 1021 + utshell-0.5.0/src/arrayfunc.rs | 1958 ++ utshell-0.5.0/src/assoc.rs | 685 + utshell-0.5.0/src/bashhist.rs | 822 + utshell-0.5.0/src/bashline.rs | 4825 ++++ utshell-0.5.0/src/bin/utshell.rs | 20 + utshell-0.5.0/src/bin/utshellversion.rs | 186 + utshell-0.5.0/src/brace.rs | 828 + utshell-0.5.0/src/bracecomp.rs | 211 + utshell-0.5.0/src/builtins/alias.rs | 322 + utshell-0.5.0/src/builtins/bashgetopt.rs | 179 + utshell-0.5.0/src/builtins/bind.rs | 418 + utshell-0.5.0/src/builtins/break_1.rs | 102 + utshell-0.5.0/src/builtins/builtin.rs | 38 + utshell-0.5.0/src/builtins/builtins.rs | 1480 ++ utshell-0.5.0/src/builtins/caller.rs | 119 + utshell-0.5.0/src/builtins/cd.rs | 564 + utshell-0.5.0/src/builtins/cmd.rs | 76 + utshell-0.5.0/src/builtins/colon.rs | 20 + utshell-0.5.0/src/builtins/command.rs | 121 + utshell-0.5.0/src/builtins/common.rs | 1192 + utshell-0.5.0/src/builtins/complete.rs | 1090 + utshell-0.5.0/src/builtins/declare.rs | 1279 ++ utshell-0.5.0/src/builtins/echo.rs | 156 + utshell-0.5.0/src/builtins/enable.rs | 543 + utshell-0.5.0/src/builtins/eval.rs | 32 + utshell-0.5.0/src/builtins/evalfile.rs | 552 + utshell-0.5.0/src/builtins/evalstring.rs | 894 + utshell-0.5.0/src/builtins/exec.rs | 239 + utshell-0.5.0/src/builtins/exec_cmd.rs | 953 + utshell-0.5.0/src/builtins/exit.rs | 154 + utshell-0.5.0/src/builtins/fc.rs | 884 + utshell-0.5.0/src/builtins/fg_bg.rs | 161 + utshell-0.5.0/src/builtins/getopt.rs | 157 + utshell-0.5.0/src/builtins/getopts.rs | 289 + utshell-0.5.0/src/builtins/hash.rs | 346 + utshell-0.5.0/src/builtins/help.rs | 500 + utshell-0.5.0/src/builtins/history.rs | 412 + utshell-0.5.0/src/builtins/jobs.rs | 278 + utshell-0.5.0/src/builtins/kill.rs | 252 + utshell-0.5.0/src/builtins/let_1.rs | 88 + utshell-0.5.0/src/builtins/mapfile.rs | 313 + utshell-0.5.0/src/builtins/printf.rs | 1573 ++ utshell-0.5.0/src/builtins/pushd.rs | 831 + utshell-0.5.0/src/builtins/read.rs | 1245 ++ utshell-0.5.0/src/builtins/return_1.rs | 40 + utshell-0.5.0/src/builtins/set.rs | 1290 ++ utshell-0.5.0/src/builtins/setattr.rs | 735 + utshell-0.5.0/src/builtins/shift.rs | 67 + utshell-0.5.0/src/builtins/shopt.rs | 1239 ++ utshell-0.5.0/src/builtins/signal.rs | 874 + utshell-0.5.0/src/builtins/source.rs | 185 + utshell-0.5.0/src/builtins/suspend.rs | 63 + utshell-0.5.0/src/builtins/test.rs | 30 + utshell-0.5.0/src/builtins/times.rs | 37 + utshell-0.5.0/src/builtins/trap.rs | 261 + utshell-0.5.0/src/builtins/type_1.rs | 443 + utshell-0.5.0/src/builtins/ulimit.rs | 788 + utshell-0.5.0/src/builtins/umask.rs | 306 + utshell-0.5.0/src/builtins/wait.rs | 310 + utshell-0.5.0/src/copycmd.rs | 394 + utshell-0.5.0/src/dispose_cmd.rs | 234 + utshell-0.5.0/src/error.rs | 146 + utshell-0.5.0/src/eval.rs | 362 + utshell-0.5.0/src/execute_cmd.rs | 5571 +++++ utshell-0.5.0/src/expr.rs | 1587 ++ utshell-0.5.0/src/findcmd.rs | 586 + utshell-0.5.0/src/flags.rs | 194 + utshell-0.5.0/src/general.rs | 1808 ++ utshell-0.5.0/src/hashcmd.rs | 160 + utshell-0.5.0/src/hashlib.rs | 411 + utshell-0.5.0/src/input.rs | 660 + utshell-0.5.0/src/jobs.rs | 4489 ++++ utshell-0.5.0/src/lib.rs | 106 + utshell-0.5.0/src/list.rs | 48 + utshell-0.5.0/src/local.rs | 630 + utshell-0.5.0/src/mailcheck.rs | 534 + utshell-0.5.0/src/make_cmd.rs | 907 + utshell-0.5.0/src/nojobs.rs | 347 + utshell-0.5.0/src/pathexp.rs | 857 + utshell-0.5.0/src/pcomplete.rs | 2278 ++ utshell-0.5.0/src/pcomplib.rs | 214 + utshell-0.5.0/src/print_cmd.rs | 1677 ++ utshell-0.5.0/src/readline.rs | 7465 +++++++ utshell-0.5.0/src/redir.rs | 1335 ++ utshell-0.5.0/src/sig.rs | 680 + utshell-0.5.0/src/src_common.rs | 11566 ++++++++++ utshell-0.5.0/src/stringlib.rs | 257 + utshell-0.5.0/src/subst.rs | 18429 ++++++++++++++++ utshell-0.5.0/src/syntax.rs | 280 + utshell-0.5.0/src/test.rs | 1139 + utshell-0.5.0/src/trap.rs | 1405 ++ utshell-0.5.0/src/unwind_prot.rs | 813 + utshell-0.5.0/src/utshell.rs | 1821 ++ utshell-0.5.0/src/variables.rs | 6747 ++++++ utshell-0.5.0/src/version.rs | 123 + utshell-0.5.0/src/y_tab.rs | 13191 +++++++++++ utshell-0.5.0/variable/Makefile | 33 + utshell-0.5.0/variable/alias.h | 74 + utshell-0.5.0/variable/array.c | 192 + utshell-0.5.0/variable/array.h | 128 + utshell-0.5.0/variable/arrayfunc.h | 101 + utshell-0.5.0/variable/assoc.h | 66 + utshell-0.5.0/variable/bashansi.h | 42 + utshell-0.5.0/variable/bashgetopt.h | 42 + utshell-0.5.0/variable/bashhist.h | 90 + utshell-0.5.0/variable/bashintl.h | 55 + utshell-0.5.0/variable/bashjmp.h | 47 + utshell-0.5.0/variable/bashline.h | 70 + utshell-0.5.0/variable/bashtypes.h | 43 + utshell-0.5.0/variable/builtext.h | 188 + utshell-0.5.0/variable/builtins.h | 69 + utshell-0.5.0/variable/chardefs.h | 164 + utshell-0.5.0/variable/chartypes.h | 113 + utshell-0.5.0/variable/command.h | 409 + utshell-0.5.0/variable/common.c | 118 + utshell-0.5.0/variable/common.h | 252 + utshell-0.5.0/variable/config-bot.h | 208 + utshell-0.5.0/variable/config-top.h | 200 + utshell-0.5.0/variable/config.h | 1208 + utshell-0.5.0/variable/conftypes.h | 59 + utshell-0.5.0/variable/dispose_cmd.h | 41 + utshell-0.5.0/variable/error.c | 415 + utshell-0.5.0/variable/error.h | 74 + utshell-0.5.0/variable/execute_cmd.h | 127 + utshell-0.5.0/variable/externs.h | 549 + utshell-0.5.0/variable/flags.h | 88 + utshell-0.5.0/variable/general.h | 372 + utshell-0.5.0/variable/gettext.h | 70 + utshell-0.5.0/variable/glob.h | 46 + utshell-0.5.0/variable/hashlib.c | 170 + utshell-0.5.0/variable/hashlib.h | 93 + utshell-0.5.0/variable/history.h | 286 + utshell-0.5.0/variable/input.h | 136 + utshell-0.5.0/variable/jobs.h | 323 + utshell-0.5.0/variable/keymaps.h | 100 + utshell-0.5.0/variable/make_cmd.h | 73 + utshell-0.5.0/variable/maxpath.h | 75 + utshell-0.5.0/variable/ocache.h | 133 + utshell-0.5.0/variable/parser.h | 101 + utshell-0.5.0/variable/pathexp.h | 108 + utshell-0.5.0/variable/pathnames.h | 33 + utshell-0.5.0/variable/pcomplete.c | 124 + utshell-0.5.0/variable/pcomplete.h | 178 + utshell-0.5.0/variable/posixjmp.h | 46 + utshell-0.5.0/variable/posixstat.h | 162 + utshell-0.5.0/variable/posixtime.h | 61 + utshell-0.5.0/variable/posixwait.h | 107 + utshell-0.5.0/variable/print_cmd.c | 185 + utshell-0.5.0/variable/printf.c | 102 + utshell-0.5.0/variable/quit.h | 82 + utshell-0.5.0/variable/readline.h | 969 + utshell-0.5.0/variable/rlconf.h | 79 + utshell-0.5.0/variable/rlstdc.h | 57 + utshell-0.5.0/variable/rltypedefs.h | 100 + utshell-0.5.0/variable/shell.h | 231 + utshell-0.5.0/variable/shmbchar.h | 112 + utshell-0.5.0/variable/shmbutil.h | 551 + utshell-0.5.0/variable/sig.h | 141 + utshell-0.5.0/variable/siglist.h | 45 + utshell-0.5.0/variable/stdc.h | 89 + utshell-0.5.0/variable/strmatch.h | 64 + utshell-0.5.0/variable/subst.h | 355 + utshell-0.5.0/variable/syntax.h | 107 + utshell-0.5.0/variable/tilde.h | 80 + utshell-0.5.0/variable/trap.h | 129 + utshell-0.5.0/variable/unwind_prot.h | 53 + utshell-0.5.0/variable/variables.h | 459 + utshell-0.5.0/variable/xmalloc.h | 67 + .../vendor/async-trait/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/async-trait/Cargo.toml | 63 + .../vendor/async-trait/LICENSE-APACHE | 176 + utshell-0.5.0/vendor/async-trait/LICENSE-MIT | 23 + utshell-0.5.0/vendor/async-trait/README.md | 275 + utshell-0.5.0/vendor/async-trait/build.rs | 31 + utshell-0.5.0/vendor/async-trait/src/args.rs | 36 + utshell-0.5.0/vendor/async-trait/src/bound.rs | 48 + .../vendor/async-trait/src/expand.rs | 484 + utshell-0.5.0/vendor/async-trait/src/lib.rs | 356 + .../vendor/async-trait/src/lifetime.rs | 112 + utshell-0.5.0/vendor/async-trait/src/parse.rs | 34 + .../vendor/async-trait/src/receiver.rs | 172 + .../vendor/async-trait/src/verbatim.rs | 34 + .../vendor/async-trait/tests/compiletest.rs | 7 + .../vendor/async-trait/tests/executor/mod.rs | 36 + .../vendor/async-trait/tests/test.rs | 1605 ++ .../tests/ui/arg-implementation-detail.rs | 22 + .../tests/ui/arg-implementation-detail.stderr | 5 + .../async-trait/tests/ui/bare-trait-object.rs | 15 + .../tests/ui/bare-trait-object.stderr | 14 + .../tests/ui/consider-restricting.rs | 26 + .../tests/ui/consider-restricting.stderr | 33 + .../async-trait/tests/ui/delimiter-span.rs | 24 + .../tests/ui/delimiter-span.stderr | 21 + .../tests/ui/lifetime-defined-here.rs | 23 + .../tests/ui/lifetime-defined-here.stderr | 29 + .../async-trait/tests/ui/lifetime-span.rs | 36 + .../async-trait/tests/ui/lifetime-span.stderr | 24 + .../tests/ui/missing-async-in-impl.rs | 15 + .../tests/ui/missing-async-in-impl.stderr | 8 + .../tests/ui/missing-async-in-trait.rs | 15 + .../tests/ui/missing-async-in-trait.stderr | 8 + .../async-trait/tests/ui/missing-body.rs | 15 + .../async-trait/tests/ui/missing-body.stderr | 7 + .../vendor/async-trait/tests/ui/must-use.rs | 21 + .../async-trait/tests/ui/must-use.stderr | 23 + .../tests/ui/no-attribute-macro.rs | 13 + .../tests/ui/no-attribute-macro.stderr | 16 + .../vendor/async-trait/tests/ui/self-span.rs | 30 + .../async-trait/tests/ui/self-span.stderr | 27 + .../tests/ui/send-not-implemented.rs | 22 + .../tests/ui/send-not-implemented.stderr | 42 + .../async-trait/tests/ui/unreachable.rs | 20 + .../async-trait/tests/ui/unreachable.stderr | 14 + .../async-trait/tests/ui/unsupported-self.rs | 15 + .../tests/ui/unsupported-self.stderr | 5 + .../vendor/autocfg/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/autocfg/Cargo.lock | 7 + utshell-0.5.0/vendor/autocfg/Cargo.toml | 24 + utshell-0.5.0/vendor/autocfg/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/autocfg/LICENSE-MIT | 25 + utshell-0.5.0/vendor/autocfg/README.md | 95 + .../vendor/autocfg/examples/integers.rs | 9 + .../vendor/autocfg/examples/paths.rs | 22 + .../vendor/autocfg/examples/traits.rs | 26 + .../vendor/autocfg/examples/versions.rs | 9 + utshell-0.5.0/vendor/autocfg/src/error.rs | 69 + utshell-0.5.0/vendor/autocfg/src/lib.rs | 453 + utshell-0.5.0/vendor/autocfg/src/tests.rs | 174 + utshell-0.5.0/vendor/autocfg/src/version.rs | 60 + .../vendor/autocfg/tests/rustflags.rs | 33 + .../vendor/bitflags/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/bitflags/CHANGELOG.md | 206 + .../vendor/bitflags/CODE_OF_CONDUCT.md | 73 + utshell-0.5.0/vendor/bitflags/Cargo.toml | 58 + utshell-0.5.0/vendor/bitflags/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/bitflags/LICENSE-MIT | 25 + utshell-0.5.0/vendor/bitflags/README.md | 32 + .../vendor/bitflags/src/example_generated.rs | 14 + utshell-0.5.0/vendor/bitflags/src/lib.rs | 1729 ++ utshell-0.5.0/vendor/bitflags/tests/basic.rs | 20 + .../bitflags/tests/compile-fail/impls/copy.rs | 10 + .../tests/compile-fail/impls/copy.stderr.beta | 27 + .../bitflags/tests/compile-fail/impls/eq.rs | 10 + .../tests/compile-fail/impls/eq.stderr.beta | 55 + .../non_integer_base/all_defined.rs | 123 + .../non_integer_base/all_defined.stderr.beta | 27 + .../non_integer_base/all_missing.rs | 13 + .../non_integer_base/all_missing.stderr.beta | 13 + .../compile-fail/visibility/private_field.rs | 13 + .../visibility/private_field.stderr.beta | 10 + .../compile-fail/visibility/private_flags.rs | 18 + .../visibility/private_flags.stderr.beta | 18 + .../compile-fail/visibility/pub_const.rs | 9 + .../visibility/pub_const.stderr.beta | 5 + .../tests/compile-pass/impls/convert.rs | 17 + .../tests/compile-pass/impls/default.rs | 10 + .../compile-pass/impls/inherent_methods.rs | 15 + .../tests/compile-pass/redefinition/core.rs | 14 + .../compile-pass/redefinition/stringify.rs | 19 + .../bitflags/tests/compile-pass/repr/c.rs | 10 + .../tests/compile-pass/repr/transparent.rs | 10 + .../compile-pass/visibility/bits_field.rs | 11 + .../tests/compile-pass/visibility/pub_in.rs | 19 + .../vendor/bitflags/tests/compile.rs | 63 + .../vendor/cfg-if/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/cfg-if/Cargo.toml | 36 + utshell-0.5.0/vendor/cfg-if/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/cfg-if/LICENSE-MIT | 25 + utshell-0.5.0/vendor/cfg-if/README.md | 47 + utshell-0.5.0/vendor/cfg-if/src/lib.rs | 176 + utshell-0.5.0/vendor/cfg-if/tests/xcrate.rs | 14 + .../vendor/chunky-vec/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/chunky-vec/Cargo.toml | 24 + .../vendor/chunky-vec/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/chunky-vec/LICENSE-MIT | 27 + utshell-0.5.0/vendor/chunky-vec/README.md | 6 + utshell-0.5.0/vendor/chunky-vec/src/lib.rs | 343 + .../vendor/displaydoc/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/displaydoc/CHANGELOG.md | 50 + utshell-0.5.0/vendor/displaydoc/Cargo.lock | 264 + utshell-0.5.0/vendor/displaydoc/Cargo.toml | 114 + .../vendor/displaydoc/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/displaydoc/LICENSE-MIT | 23 + utshell-0.5.0/vendor/displaydoc/README.md | 115 + utshell-0.5.0/vendor/displaydoc/README.tpl | 23 + .../vendor/displaydoc/examples/simple.rs | 36 + utshell-0.5.0/vendor/displaydoc/src/attr.rs | 137 + utshell-0.5.0/vendor/displaydoc/src/expand.rs | 410 + utshell-0.5.0/vendor/displaydoc/src/fmt.rs | 159 + utshell-0.5.0/vendor/displaydoc/src/lib.rs | 187 + .../vendor/displaydoc/tests/compile_tests.rs | 29 + .../vendor/displaydoc/tests/happy.rs | 152 + .../displaydoc/tests/no_std/enum_prefix.rs | 36 + .../tests/no_std/enum_prefix_missing.rs | 35 + .../tests/no_std/enum_prefix_missing.stderr | 22 + .../displaydoc/tests/no_std/multi_line.rs | 37 + .../displaydoc/tests/no_std/multi_line.stderr | 22 + .../tests/no_std/multi_line_allow.rs | 38 + .../vendor/displaydoc/tests/no_std/with.rs | 32 + .../vendor/displaydoc/tests/no_std/without.rs | 28 + .../displaydoc/tests/no_std/without.stderr | 22 + .../vendor/displaydoc/tests/num_in_field.rs | 22 + .../displaydoc/tests/std/enum_prefix.rs | 36 + .../tests/std/enum_prefix_missing.rs | 35 + .../tests/std/enum_prefix_missing.stderr | 22 + .../vendor/displaydoc/tests/std/multi_line.rs | 1 + .../displaydoc/tests/std/multi_line.stderr | 22 + .../displaydoc/tests/std/multi_line_allow.rs | 38 + .../vendor/displaydoc/tests/std/multiple.rs | 38 + .../vendor/displaydoc/tests/std/without.rs | 1 + .../displaydoc/tests/std/without.stderr | 22 + .../vendor/displaydoc/tests/variantless.rs | 6 + .../vendor/displaydoc/update-readme.sh | 5 + .../vendor/dunce/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/dunce/Cargo.toml | 42 + utshell-0.5.0/vendor/dunce/LICENSE | 121 + utshell-0.5.0/vendor/dunce/README.md | 17 + utshell-0.5.0/vendor/dunce/src/lib.rs | 324 + .../vendor/elsa/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/elsa/Cargo.lock | 39 + utshell-0.5.0/vendor/elsa/Cargo.toml | 47 + utshell-0.5.0/vendor/elsa/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/elsa/LICENSE-MIT | 27 + utshell-0.5.0/vendor/elsa/README.md | 19 + utshell-0.5.0/vendor/elsa/examples/arena.rs | 56 + .../vendor/elsa/examples/fluentresource.rs | 50 + .../vendor/elsa/examples/mutable_arena.rs | 79 + .../vendor/elsa/examples/string_interner.rs | 61 + utshell-0.5.0/vendor/elsa/examples/sync.rs | 26 + utshell-0.5.0/vendor/elsa/src/index_map.rs | 237 + utshell-0.5.0/vendor/elsa/src/index_set.rs | 182 + utshell-0.5.0/vendor/elsa/src/lib.rs | 29 + utshell-0.5.0/vendor/elsa/src/map.rs | 497 + utshell-0.5.0/vendor/elsa/src/sync.rs | 858 + utshell-0.5.0/vendor/elsa/src/vec.rs | 347 + .../vendor/fluent-bundle/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/fluent-bundle/Cargo.toml | 78 + .../vendor/fluent-bundle/LICENSE-APACHE | 201 + .../vendor/fluent-bundle/LICENSE-MIT | 19 + utshell-0.5.0/vendor/fluent-bundle/README.md | 111 + .../vendor/fluent-bundle/benches/resolver.rs | 168 + .../fluent-bundle/benches/resolver_iai.rs | 79 + .../vendor/fluent-bundle/examples/README.md | 6 + .../vendor/fluent-bundle/src/args.rs | 120 + .../vendor/fluent-bundle/src/bundle.rs | 615 + .../vendor/fluent-bundle/src/concurrent.rs | 59 + .../vendor/fluent-bundle/src/entry.rs | 62 + .../vendor/fluent-bundle/src/errors.rs | 86 + utshell-0.5.0/vendor/fluent-bundle/src/lib.rs | 127 + .../vendor/fluent-bundle/src/memoizer.rs | 18 + .../vendor/fluent-bundle/src/message.rs | 274 + .../fluent-bundle/src/resolver/errors.rs | 96 + .../fluent-bundle/src/resolver/expression.rs | 66 + .../src/resolver/inline_expression.rs | 181 + .../vendor/fluent-bundle/src/resolver/mod.rs | 42 + .../fluent-bundle/src/resolver/pattern.rs | 108 + .../fluent-bundle/src/resolver/scope.rs | 141 + .../vendor/fluent-bundle/src/resource.rs | 171 + .../vendor/fluent-bundle/src/types/mod.rs | 202 + .../vendor/fluent-bundle/src/types/number.rs | 252 + .../vendor/fluent-bundle/src/types/plural.rs | 22 + .../fluent-fallback/.cargo-checksum.json | 1 + .../vendor/fluent-fallback/CHANGELOG.md | 68 + .../vendor/fluent-fallback/Cargo.lock | 415 + .../vendor/fluent-fallback/Cargo.toml | 74 + .../vendor/fluent-fallback/LICENSE-APACHE | 201 + .../vendor/fluent-fallback/LICENSE-MIT | 19 + .../vendor/fluent-fallback/README.md | 102 + .../examples/resources/en-US/simple.ftl | 7 + .../examples/resources/pl/simple.ftl | 8 + .../examples/simple-fallback.rs | 237 + .../vendor/fluent-fallback/src/bundles.rs | 426 + .../vendor/fluent-fallback/src/cache.rs | 253 + .../vendor/fluent-fallback/src/env.rs | 84 + .../vendor/fluent-fallback/src/errors.rs | 71 + .../vendor/fluent-fallback/src/generator.rs | 41 + .../vendor/fluent-fallback/src/lib.rs | 118 + .../fluent-fallback/src/localization.rs | 137 + .../fluent-fallback/src/pin_cell/README.md | 2 + .../fluent-fallback/src/pin_cell/mod.rs | 97 + .../fluent-fallback/src/pin_cell/pin_mut.rs | 50 + .../fluent-fallback/src/pin_cell/pin_ref.rs | 47 + .../vendor/fluent-fallback/src/types.rs | 141 + .../tests/localization_test.rs | 518 + .../tests/resources/en-US/test.ftl | 4 + .../tests/resources/en-US/test2.ftl | 10 + .../tests/resources/pl/test.ftl | 4 + .../tests/resources/pl/test2.ftl | 9 + .../fluent-langneg/.cargo-checksum.json | 1 + .../vendor/fluent-langneg/Cargo.toml | 61 + utshell-0.5.0/vendor/fluent-langneg/README.md | 113 + .../fluent-langneg/benches/negotiate.rs | 40 + .../fluent-langneg/src/accepted_languages.rs | 41 + .../vendor/fluent-langneg/src/lib.rs | 49 + .../src/negotiate/likely_subtags.rs | 39 + .../fluent-langneg/src/negotiate/mod.rs | 233 + .../vendor/fluent-resmgr/.cargo-checksum.json | 1 + .../vendor/fluent-resmgr/CHANGELOG.md | 30 + utshell-0.5.0/vendor/fluent-resmgr/Cargo.lock | 395 + utshell-0.5.0/vendor/fluent-resmgr/Cargo.toml | 63 + .../vendor/fluent-resmgr/LICENSE-APACHE | 201 + .../vendor/fluent-resmgr/LICENSE-MIT | 19 + utshell-0.5.0/vendor/fluent-resmgr/README.md | 99 + .../examples/resources/en-US/common.ftl | 1 + .../examples/resources/en-US/errors.ftl | 2 + .../examples/resources/en-US/simple.ftl | 5 + .../examples/resources/pl/common.ftl | 1 + .../examples/resources/pl/errors.ftl | 2 + .../examples/resources/pl/simple.ftl | 6 + .../fluent-resmgr/examples/simple-resmgr.rs | 151 + utshell-0.5.0/vendor/fluent-resmgr/src/lib.rs | 3 + .../fluent-resmgr/src/resource_manager.rs | 140 + .../fluent-resmgr/tests/localization_test.rs | 46 + .../tests/resources/en-US/test.ftl | 1 + .../fluent-resmgr/tests/resources/pl/test.ftl | 2 + .../vendor/fluent-syntax/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/fluent-syntax/Cargo.lock | 672 + utshell-0.5.0/vendor/fluent-syntax/Cargo.toml | 78 + .../vendor/fluent-syntax/LICENSE-APACHE | 201 + .../vendor/fluent-syntax/LICENSE-MIT | 19 + utshell-0.5.0/vendor/fluent-syntax/README.md | 63 + .../fluent-syntax/benches/contexts/README.md | 4 + .../vendor/fluent-syntax/benches/parser.rs | 141 + .../fluent-syntax/benches/parser_iai.rs | 15 + .../vendor/fluent-syntax/src/ast/helper.rs | 25 + .../vendor/fluent-syntax/src/ast/mod.rs | 1446 ++ .../vendor/fluent-syntax/src/bin/parser.rs | 42 + .../fluent-syntax/src/bin/update_fixtures.rs | 44 + utshell-0.5.0/vendor/fluent-syntax/src/lib.rs | 51 + .../fluent-syntax/src/parser/comment.rs | 89 + .../vendor/fluent-syntax/src/parser/core.rs | 307 + .../vendor/fluent-syntax/src/parser/errors.rs | 169 + .../fluent-syntax/src/parser/expression.rs | 224 + .../vendor/fluent-syntax/src/parser/helper.rs | 169 + .../vendor/fluent-syntax/src/parser/macros.rs | 11 + .../vendor/fluent-syntax/src/parser/mod.rs | 278 + .../fluent-syntax/src/parser/pattern.rs | 207 + .../fluent-syntax/src/parser/runtime.rs | 61 + .../vendor/fluent-syntax/src/parser/slice.rs | 25 + .../vendor/fluent-syntax/src/unicode.rs | 159 + .../futures-channel/.cargo-checksum.json | 1 + .../vendor/futures-channel/Cargo.toml | 52 + .../vendor/futures-channel/LICENSE-APACHE | 202 + .../vendor/futures-channel/LICENSE-MIT | 26 + .../vendor/futures-channel/README.md | 23 + .../futures-channel/benches/sync_mpsc.rs | 135 + .../vendor/futures-channel/src/lib.rs | 42 + .../vendor/futures-channel/src/lock.rs | 102 + .../vendor/futures-channel/src/mpsc/mod.rs | 1372 ++ .../vendor/futures-channel/src/mpsc/queue.rs | 174 + .../futures-channel/src/mpsc/sink_impl.rs | 73 + .../vendor/futures-channel/src/oneshot.rs | 488 + .../vendor/futures-channel/tests/channel.rs | 66 + .../futures-channel/tests/mpsc-close.rs | 299 + .../futures-channel/tests/mpsc-size_hint.rs | 40 + .../vendor/futures-channel/tests/mpsc.rs | 657 + .../vendor/futures-channel/tests/oneshot.rs | 256 + .../vendor/futures-core/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures-core/Cargo.toml | 45 + .../vendor/futures-core/LICENSE-APACHE | 202 + utshell-0.5.0/vendor/futures-core/LICENSE-MIT | 26 + utshell-0.5.0/vendor/futures-core/README.md | 23 + .../vendor/futures-core/src/future.rs | 103 + utshell-0.5.0/vendor/futures-core/src/lib.rs | 27 + .../vendor/futures-core/src/stream.rs | 235 + .../src/task/__internal/atomic_waker.rs | 421 + .../futures-core/src/task/__internal/mod.rs | 7 + .../vendor/futures-core/src/task/mod.rs | 10 + .../vendor/futures-core/src/task/poll.rs | 12 + .../futures-executor/.cargo-checksum.json | 1 + .../vendor/futures-executor/Cargo.toml | 60 + .../vendor/futures-executor/LICENSE-APACHE | 202 + .../vendor/futures-executor/LICENSE-MIT | 26 + .../vendor/futures-executor/README.md | 23 + .../futures-executor/benches/thread_notify.rs | 109 + .../vendor/futures-executor/src/enter.rs | 80 + .../vendor/futures-executor/src/lib.rs | 76 + .../vendor/futures-executor/src/local_pool.rs | 402 + .../futures-executor/src/thread_pool.rs | 380 + .../futures-executor/src/unpark_mutex.rs | 137 + .../futures-executor/tests/local_pool.rs | 496 + .../vendor/futures-io/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures-io/Cargo.toml | 37 + .../vendor/futures-io/LICENSE-APACHE | 202 + utshell-0.5.0/vendor/futures-io/LICENSE-MIT | 26 + utshell-0.5.0/vendor/futures-io/README.md | 23 + utshell-0.5.0/vendor/futures-io/src/lib.rs | 558 + .../vendor/futures-macro/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures-macro/Cargo.toml | 37 + .../vendor/futures-macro/LICENSE-APACHE | 202 + .../vendor/futures-macro/LICENSE-MIT | 26 + .../vendor/futures-macro/src/executor.rs | 56 + .../vendor/futures-macro/src/join.rs | 144 + utshell-0.5.0/vendor/futures-macro/src/lib.rs | 61 + .../vendor/futures-macro/src/select.rs | 330 + .../vendor/futures-macro/src/stream_select.rs | 113 + .../vendor/futures-sink/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures-sink/Cargo.toml | 33 + .../vendor/futures-sink/LICENSE-APACHE | 202 + utshell-0.5.0/vendor/futures-sink/LICENSE-MIT | 26 + utshell-0.5.0/vendor/futures-sink/README.md | 23 + utshell-0.5.0/vendor/futures-sink/src/lib.rs | 240 + .../vendor/futures-task/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures-task/Cargo.toml | 37 + .../vendor/futures-task/LICENSE-APACHE | 202 + utshell-0.5.0/vendor/futures-task/LICENSE-MIT | 26 + utshell-0.5.0/vendor/futures-task/README.md | 23 + .../vendor/futures-task/src/arc_wake.rs | 49 + .../vendor/futures-task/src/future_obj.rs | 335 + utshell-0.5.0/vendor/futures-task/src/lib.rs | 50 + .../vendor/futures-task/src/noop_waker.rs | 63 + .../vendor/futures-task/src/spawn.rs | 192 + .../vendor/futures-task/src/waker.rs | 59 + .../vendor/futures-task/src/waker_ref.rs | 66 + .../vendor/futures-util/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures-util/Cargo.toml | 135 + .../vendor/futures-util/LICENSE-APACHE | 202 + utshell-0.5.0/vendor/futures-util/LICENSE-MIT | 26 + utshell-0.5.0/vendor/futures-util/README.md | 23 + .../vendor/futures-util/benches/bilock.rs | 68 + .../futures-util/benches/flatten_unordered.rs | 58 + .../futures-util/benches/futures_unordered.rs | 43 + .../vendor/futures-util/benches/select.rs | 35 + .../vendor/futures-util/src/abortable.rs | 209 + .../futures-util/src/async_await/join_mod.rs | 110 + .../futures-util/src/async_await/mod.rs | 60 + .../futures-util/src/async_await/pending.rs | 43 + .../futures-util/src/async_await/poll.rs | 39 + .../futures-util/src/async_await/random.rs | 54 + .../src/async_await/select_mod.rs | 336 + .../src/async_await/stream_select_mod.rs | 38 + .../futures-util/src/compat/compat01as03.rs | 454 + .../futures-util/src/compat/compat03as01.rs | 265 + .../futures-util/src/compat/executor.rs | 86 + .../vendor/futures-util/src/compat/mod.rs | 22 + utshell-0.5.0/vendor/futures-util/src/fns.rs | 372 + .../futures-util/src/future/abortable.rs | 19 + .../vendor/futures-util/src/future/either.rs | 317 + .../src/future/future/catch_unwind.rs | 38 + .../futures-util/src/future/future/flatten.rs | 153 + .../futures-util/src/future/future/fuse.rs | 91 + .../futures-util/src/future/future/map.rs | 66 + .../futures-util/src/future/future/mod.rs | 606 + .../src/future/future/remote_handle.rs | 126 + .../futures-util/src/future/future/shared.rs | 409 + .../vendor/futures-util/src/future/join.rs | 217 + .../futures-util/src/future/join_all.rs | 167 + .../vendor/futures-util/src/future/lazy.rs | 60 + .../futures-util/src/future/maybe_done.rs | 104 + .../vendor/futures-util/src/future/mod.rs | 131 + .../vendor/futures-util/src/future/option.rs | 64 + .../vendor/futures-util/src/future/pending.rs | 55 + .../vendor/futures-util/src/future/poll_fn.rs | 58 + .../futures-util/src/future/poll_immediate.rs | 126 + .../vendor/futures-util/src/future/ready.rs | 82 + .../vendor/futures-util/src/future/select.rs | 134 + .../futures-util/src/future/select_all.rs | 75 + .../futures-util/src/future/select_ok.rs | 85 + .../src/future/try_future/into_future.rs | 36 + .../futures-util/src/future/try_future/mod.rs | 625 + .../src/future/try_future/try_flatten.rs | 162 + .../src/future/try_future/try_flatten_err.rs | 62 + .../futures-util/src/future/try_join.rs | 256 + .../futures-util/src/future/try_join_all.rs | 201 + .../futures-util/src/future/try_maybe_done.rs | 92 + .../futures-util/src/future/try_select.rs | 85 + .../vendor/futures-util/src/io/allow_std.rs | 200 + .../vendor/futures-util/src/io/buf_reader.rs | 263 + .../vendor/futures-util/src/io/buf_writer.rs | 224 + .../vendor/futures-util/src/io/chain.rs | 142 + .../vendor/futures-util/src/io/close.rs | 28 + .../vendor/futures-util/src/io/copy.rs | 58 + .../vendor/futures-util/src/io/copy_buf.rs | 78 + .../futures-util/src/io/copy_buf_abortable.rs | 124 + .../vendor/futures-util/src/io/cursor.rs | 232 + .../vendor/futures-util/src/io/empty.rs | 59 + .../vendor/futures-util/src/io/fill_buf.rs | 47 + .../vendor/futures-util/src/io/flush.rs | 31 + .../vendor/futures-util/src/io/into_sink.rs | 82 + .../vendor/futures-util/src/io/line_writer.rs | 155 + .../vendor/futures-util/src/io/lines.rs | 47 + .../vendor/futures-util/src/io/mod.rs | 841 + .../vendor/futures-util/src/io/read.rs | 30 + .../vendor/futures-util/src/io/read_exact.rs | 42 + .../vendor/futures-util/src/io/read_line.rs | 58 + .../vendor/futures-util/src/io/read_to_end.rs | 91 + .../futures-util/src/io/read_to_string.rs | 59 + .../vendor/futures-util/src/io/read_until.rs | 60 + .../futures-util/src/io/read_vectored.rs | 30 + .../vendor/futures-util/src/io/repeat.rs | 66 + .../vendor/futures-util/src/io/seek.rs | 30 + .../vendor/futures-util/src/io/sink.rs | 67 + .../vendor/futures-util/src/io/split.rs | 129 + .../vendor/futures-util/src/io/take.rs | 125 + .../vendor/futures-util/src/io/window.rs | 104 + .../vendor/futures-util/src/io/write.rs | 30 + .../vendor/futures-util/src/io/write_all.rs | 43 + .../futures-util/src/io/write_all_vectored.rs | 193 + .../futures-util/src/io/write_vectored.rs | 30 + utshell-0.5.0/vendor/futures-util/src/lib.rs | 337 + .../vendor/futures-util/src/lock/bilock.rs | 298 + .../vendor/futures-util/src/lock/mod.rs | 27 + .../vendor/futures-util/src/lock/mutex.rs | 551 + .../vendor/futures-util/src/never.rs | 18 + .../vendor/futures-util/src/sink/buffer.rs | 105 + .../vendor/futures-util/src/sink/close.rs | 32 + .../vendor/futures-util/src/sink/drain.rs | 59 + .../vendor/futures-util/src/sink/err_into.rs | 57 + .../vendor/futures-util/src/sink/fanout.rs | 111 + .../vendor/futures-util/src/sink/feed.rs | 43 + .../vendor/futures-util/src/sink/flush.rs | 36 + .../vendor/futures-util/src/sink/map_err.rs | 65 + .../vendor/futures-util/src/sink/mod.rs | 344 + .../vendor/futures-util/src/sink/send.rs | 41 + .../vendor/futures-util/src/sink/send_all.rs | 100 + .../vendor/futures-util/src/sink/unfold.rs | 89 + .../vendor/futures-util/src/sink/with.rs | 134 + .../futures-util/src/sink/with_flat_map.rs | 127 + .../futures-util/src/stream/abortable.rs | 19 + .../vendor/futures-util/src/stream/empty.rs | 45 + .../src/stream/futures_ordered.rs | 249 + .../src/stream/futures_unordered/abort.rs | 12 + .../src/stream/futures_unordered/iter.rs | 172 + .../src/stream/futures_unordered/mod.rs | 652 + .../futures_unordered/ready_to_run_queue.rs | 109 + .../src/stream/futures_unordered/task.rs | 125 + .../vendor/futures-util/src/stream/iter.rs | 49 + .../vendor/futures-util/src/stream/mod.rs | 148 + .../vendor/futures-util/src/stream/once.rs | 67 + .../vendor/futures-util/src/stream/pending.rs | 45 + .../vendor/futures-util/src/stream/poll_fn.rs | 57 + .../futures-util/src/stream/poll_immediate.rs | 80 + .../vendor/futures-util/src/stream/repeat.rs | 58 + .../futures-util/src/stream/repeat_with.rs | 93 + .../vendor/futures-util/src/stream/select.rs | 117 + .../futures-util/src/stream/select_all.rs | 249 + .../src/stream/select_with_strategy.rs | 304 + .../futures-util/src/stream/stream/all.rs | 93 + .../futures-util/src/stream/stream/any.rs | 93 + .../src/stream/stream/buffer_unordered.rs | 120 + .../src/stream/stream/buffered.rs | 118 + .../src/stream/stream/catch_unwind.rs | 61 + .../futures-util/src/stream/stream/chain.rs | 76 + .../futures-util/src/stream/stream/chunks.rs | 103 + .../futures-util/src/stream/stream/collect.rs | 56 + .../futures-util/src/stream/stream/concat.rs | 62 + .../futures-util/src/stream/stream/count.rs | 53 + .../futures-util/src/stream/stream/cycle.rs | 68 + .../src/stream/stream/enumerate.rs | 64 + .../futures-util/src/stream/stream/filter.rs | 117 + .../src/stream/stream/filter_map.rs | 111 + .../futures-util/src/stream/stream/flatten.rs | 73 + .../src/stream/stream/flatten_unordered.rs | 536 + .../futures-util/src/stream/stream/fold.rs | 88 + .../src/stream/stream/for_each.rs | 78 + .../src/stream/stream/for_each_concurrent.rs | 119 + .../futures-util/src/stream/stream/forward.rs | 75 + .../futures-util/src/stream/stream/fuse.rs | 75 + .../src/stream/stream/into_future.rs | 90 + .../futures-util/src/stream/stream/map.rs | 77 + .../futures-util/src/stream/stream/mod.rs | 1697 ++ .../futures-util/src/stream/stream/next.rs | 34 + .../futures-util/src/stream/stream/peek.rs | 433 + .../src/stream/stream/ready_chunks.rs | 93 + .../futures-util/src/stream/stream/scan.rs | 128 + .../src/stream/stream/select_next_some.rs | 42 + .../futures-util/src/stream/stream/skip.rs | 70 + .../src/stream/stream/skip_while.rs | 124 + .../futures-util/src/stream/stream/split.rs | 224 + .../futures-util/src/stream/stream/take.rs | 86 + .../src/stream/stream/take_until.rs | 170 + .../src/stream/stream/take_while.rs | 124 + .../futures-util/src/stream/stream/then.rs | 101 + .../futures-util/src/stream/stream/unzip.rs | 63 + .../futures-util/src/stream/stream/zip.rs | 128 + .../src/stream/try_stream/and_then.rs | 105 + .../src/stream/try_stream/into_async_read.rs | 166 + .../src/stream/try_stream/into_stream.rs | 52 + .../futures-util/src/stream/try_stream/mod.rs | 1251 ++ .../src/stream/try_stream/or_else.rs | 109 + .../src/stream/try_stream/try_all.rs | 98 + .../src/stream/try_stream/try_any.rs | 98 + .../stream/try_stream/try_buffer_unordered.rs | 86 + .../src/stream/try_stream/try_buffered.rs | 87 + .../src/stream/try_stream/try_chunks.rs | 132 + .../src/stream/try_stream/try_collect.rs | 52 + .../src/stream/try_stream/try_concat.rs | 51 + .../src/stream/try_stream/try_filter.rs | 112 + .../src/stream/try_stream/try_filter_map.rs | 106 + .../src/stream/try_stream/try_flatten.rs | 84 + .../try_stream/try_flatten_unordered.rs | 176 + .../src/stream/try_stream/try_fold.rs | 93 + .../src/stream/try_stream/try_for_each.rs | 68 + .../try_stream/try_for_each_concurrent.rs | 133 + .../src/stream/try_stream/try_next.rs | 34 + .../src/stream/try_stream/try_ready_chunks.rs | 126 + .../src/stream/try_stream/try_skip_while.rs | 120 + .../src/stream/try_stream/try_take_while.rs | 129 + .../src/stream/try_stream/try_unfold.rs | 122 + .../vendor/futures-util/src/stream/unfold.rs | 119 + .../vendor/futures-util/src/task/mod.rs | 40 + .../vendor/futures-util/src/task/spawn.rs | 169 + .../vendor/futures-util/src/unfold_state.rs | 39 + .../vendor/futures/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/futures/Cargo.toml | 147 + utshell-0.5.0/vendor/futures/LICENSE-APACHE | 202 + utshell-0.5.0/vendor/futures/LICENSE-MIT | 26 + utshell-0.5.0/vendor/futures/README.md | 61 + utshell-0.5.0/vendor/futures/src/lib.rs | 260 + .../vendor/futures/tests/_require_features.rs | 13 + .../futures/tests/async_await_macros.rs | 393 + .../vendor/futures/tests/auto_traits.rs | 1898 ++ utshell-0.5.0/vendor/futures/tests/bilock.rs | 104 + utshell-0.5.0/vendor/futures/tests/compat.rs | 16 + .../vendor/futures/tests/eager_drop.rs | 121 + .../vendor/futures/tests/eventual.rs | 179 + .../vendor/futures/tests/future_abortable.rs | 44 + .../futures/tests/future_basic_combinators.rs | 104 + .../vendor/futures/tests/future_fuse.rs | 12 + .../vendor/futures/tests/future_inspect.rs | 16 + .../vendor/futures/tests/future_join.rs | 32 + .../vendor/futures/tests/future_join_all.rs | 41 + .../vendor/futures/tests/future_obj.rs | 33 + .../vendor/futures/tests/future_select_all.rs | 25 + .../vendor/futures/tests/future_select_ok.rs | 30 + .../vendor/futures/tests/future_shared.rs | 273 + .../tests/future_try_flatten_stream.rs | 83 + .../futures/tests/future_try_join_all.rs | 46 + .../vendor/futures/tests/io_buf_reader.rs | 432 + .../vendor/futures/tests/io_buf_writer.rs | 239 + .../vendor/futures/tests/io_cursor.rs | 30 + .../vendor/futures/tests/io_line_writer.rs | 73 + .../vendor/futures/tests/io_lines.rs | 60 + utshell-0.5.0/vendor/futures/tests/io_read.rs | 64 + .../vendor/futures/tests/io_read_exact.rs | 17 + .../vendor/futures/tests/io_read_line.rs | 58 + .../vendor/futures/tests/io_read_to_end.rs | 65 + .../vendor/futures/tests/io_read_to_string.rs | 44 + .../vendor/futures/tests/io_read_until.rs | 60 + .../vendor/futures/tests/io_window.rs | 30 + .../vendor/futures/tests/io_write.rs | 65 + .../vendor/futures/tests/lock_mutex.rs | 69 + .../futures/tests/macro_comma_support.rs | 43 + .../vendor/futures/tests/object_safety.rs | 49 + utshell-0.5.0/vendor/futures/tests/oneshot.rs | 78 + .../vendor/futures/tests/ready_queue.rs | 148 + utshell-0.5.0/vendor/futures/tests/recurse.rs | 25 + utshell-0.5.0/vendor/futures/tests/sink.rs | 554 + .../vendor/futures/tests/sink_fanout.rs | 24 + utshell-0.5.0/vendor/futures/tests/stream.rs | 577 + .../vendor/futures/tests/stream_abortable.rs | 46 + .../futures/tests/stream_buffer_unordered.rs | 73 + .../futures/tests/stream_catch_unwind.rs | 27 + .../futures/tests/stream_futures_ordered.rs | 172 + .../futures/tests/stream_futures_unordered.rs | 408 + .../futures/tests/stream_into_async_read.rs | 94 + .../vendor/futures/tests/stream_peekable.rs | 58 + .../vendor/futures/tests/stream_select_all.rs | 197 + .../futures/tests/stream_select_next_some.rs | 86 + .../vendor/futures/tests/stream_split.rs | 57 + .../vendor/futures/tests/stream_try_stream.rs | 183 + .../vendor/futures/tests/stream_unfold.rs | 32 + .../vendor/futures/tests/task_arc_wake.rs | 79 + .../vendor/futures/tests/task_atomic_waker.rs | 48 + .../vendor/futures/tests/test_macro.rs | 20 + .../vendor/futures/tests/try_join.rs | 35 + .../vendor/futures/tests_disabled/all.rs | 400 + .../vendor/futures/tests_disabled/stream.rs | 368 + .../vendor/intl-memoizer/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/intl-memoizer/Cargo.toml | 35 + .../vendor/intl-memoizer/LICENSE-APACHE | 201 + .../vendor/intl-memoizer/LICENSE-MIT | 19 + utshell-0.5.0/vendor/intl-memoizer/README.md | 65 + .../vendor/intl-memoizer/src/concurrent.rs | 39 + utshell-0.5.0/vendor/intl-memoizer/src/lib.rs | 140 + .../intl_pluralrules/.cargo-checksum.json | 1 + .../vendor/intl_pluralrules/Cargo.toml | 66 + .../vendor/intl_pluralrules/README.md | 42 + .../intl_pluralrules/benches/pluralrules.rs | 69 + .../vendor/intl_pluralrules/src/lib.rs | 225 + .../vendor/intl_pluralrules/src/operands.rs | 186 + .../vendor/intl_pluralrules/src/rules.rs | 3187 +++ .../vendor/lazy_static/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/lazy_static/Cargo.toml | 46 + .../vendor/lazy_static/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/lazy_static/LICENSE-MIT | 25 + utshell-0.5.0/vendor/lazy_static/README.md | 79 + .../vendor/lazy_static/src/core_lazy.rs | 31 + .../vendor/lazy_static/src/inline_lazy.rs | 57 + utshell-0.5.0/vendor/lazy_static/src/lib.rs | 215 + .../vendor/lazy_static/tests/no_std.rs | 20 + .../vendor/lazy_static/tests/test.rs | 164 + .../vendor/libc/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/libc/CONTRIBUTING.md | 100 + utshell-0.5.0/vendor/libc/Cargo.toml | 175 + utshell-0.5.0/vendor/libc/LICENSE-APACHE | 176 + utshell-0.5.0/vendor/libc/LICENSE-MIT | 25 + utshell-0.5.0/vendor/libc/README.md | 118 + utshell-0.5.0/vendor/libc/build.rs | 297 + utshell-0.5.0/vendor/libc/rustfmt.toml | 1 + .../vendor/libc/src/fixed_width_ints.rs | 99 + .../vendor/libc/src/fuchsia/aarch64.rs | 67 + .../vendor/libc/src/fuchsia/align.rs | 142 + utshell-0.5.0/vendor/libc/src/fuchsia/mod.rs | 4393 ++++ .../vendor/libc/src/fuchsia/no_align.rs | 129 + .../vendor/libc/src/fuchsia/riscv64.rs | 44 + .../vendor/libc/src/fuchsia/x86_64.rs | 152 + .../vendor/libc/src/hermit/aarch64.rs | 2 + utshell-0.5.0/vendor/libc/src/hermit/mod.rs | 61 + .../vendor/libc/src/hermit/x86_64.rs | 2 + utshell-0.5.0/vendor/libc/src/lib.rs | 165 + utshell-0.5.0/vendor/libc/src/macros.rs | 349 + utshell-0.5.0/vendor/libc/src/psp.rs | 4177 ++++ utshell-0.5.0/vendor/libc/src/sgx.rs | 47 + .../vendor/libc/src/solid/aarch64.rs | 4 + utshell-0.5.0/vendor/libc/src/solid/arm.rs | 4 + utshell-0.5.0/vendor/libc/src/solid/mod.rs | 904 + utshell-0.5.0/vendor/libc/src/switch.rs | 49 + utshell-0.5.0/vendor/libc/src/teeos/mod.rs | 1385 ++ utshell-0.5.0/vendor/libc/src/unix/aix/mod.rs | 3362 +++ .../vendor/libc/src/unix/aix/powerpc64.rs | 644 + utshell-0.5.0/vendor/libc/src/unix/align.rs | 6 + .../libc/src/unix/bsd/apple/b32/align.rs | 7 + .../vendor/libc/src/unix/bsd/apple/b32/mod.rs | 119 + .../src/unix/bsd/apple/b64/aarch64/align.rs | 55 + .../src/unix/bsd/apple/b64/aarch64/mod.rs | 14 + .../libc/src/unix/bsd/apple/b64/align.rs | 7 + .../vendor/libc/src/unix/bsd/apple/b64/mod.rs | 124 + .../src/unix/bsd/apple/b64/x86_64/align.rs | 7 + .../libc/src/unix/bsd/apple/b64/x86_64/mod.rs | 180 + .../libc/src/unix/bsd/apple/long_array.rs | 8 + .../vendor/libc/src/unix/bsd/apple/mod.rs | 6528 ++++++ .../unix/bsd/freebsdlike/dragonfly/errno.rs | 13 + .../src/unix/bsd/freebsdlike/dragonfly/mod.rs | 1732 ++ .../unix/bsd/freebsdlike/freebsd/aarch64.rs | 146 + .../src/unix/bsd/freebsdlike/freebsd/arm.rs | 50 + .../bsd/freebsdlike/freebsd/freebsd11/b64.rs | 32 + .../bsd/freebsdlike/freebsd/freebsd11/mod.rs | 488 + .../bsd/freebsdlike/freebsd/freebsd12/b64.rs | 34 + .../bsd/freebsdlike/freebsd/freebsd12/mod.rs | 505 + .../freebsdlike/freebsd/freebsd12/x86_64.rs | 5 + .../bsd/freebsdlike/freebsd/freebsd13/b64.rs | 34 + .../bsd/freebsdlike/freebsd/freebsd13/mod.rs | 546 + .../freebsdlike/freebsd/freebsd13/x86_64.rs | 5 + .../bsd/freebsdlike/freebsd/freebsd14/b64.rs | 34 + .../bsd/freebsdlike/freebsd/freebsd14/mod.rs | 546 + .../freebsdlike/freebsd/freebsd14/x86_64.rs | 12 + .../bsd/freebsdlike/freebsd/freebsd15/b64.rs | 34 + .../bsd/freebsdlike/freebsd/freebsd15/mod.rs | 546 + .../freebsdlike/freebsd/freebsd15/x86_64.rs | 12 + .../src/unix/bsd/freebsdlike/freebsd/mod.rs | 5758 +++++ .../unix/bsd/freebsdlike/freebsd/powerpc.rs | 47 + .../unix/bsd/freebsdlike/freebsd/powerpc64.rs | 47 + .../unix/bsd/freebsdlike/freebsd/riscv64.rs | 154 + .../src/unix/bsd/freebsdlike/freebsd/x86.rs | 201 + .../bsd/freebsdlike/freebsd/x86_64/align.rs | 197 + .../bsd/freebsdlike/freebsd/x86_64/mod.rs | 334 + .../libc/src/unix/bsd/freebsdlike/mod.rs | 1918 ++ utshell-0.5.0/vendor/libc/src/unix/bsd/mod.rs | 932 + .../libc/src/unix/bsd/netbsdlike/mod.rs | 863 + .../src/unix/bsd/netbsdlike/netbsd/aarch64.rs | 162 + .../src/unix/bsd/netbsdlike/netbsd/arm.rs | 81 + .../src/unix/bsd/netbsdlike/netbsd/mips.rs | 21 + .../src/unix/bsd/netbsdlike/netbsd/mod.rs | 3148 +++ .../src/unix/bsd/netbsdlike/netbsd/powerpc.rs | 21 + .../src/unix/bsd/netbsdlike/netbsd/riscv64.rs | 21 + .../src/unix/bsd/netbsdlike/netbsd/sparc64.rs | 8 + .../src/unix/bsd/netbsdlike/netbsd/x86.rs | 15 + .../src/unix/bsd/netbsdlike/netbsd/x86_64.rs | 67 + .../unix/bsd/netbsdlike/openbsd/aarch64.rs | 30 + .../src/unix/bsd/netbsdlike/openbsd/arm.rs | 16 + .../src/unix/bsd/netbsdlike/openbsd/mips64.rs | 8 + .../src/unix/bsd/netbsdlike/openbsd/mod.rs | 2209 ++ .../unix/bsd/netbsdlike/openbsd/powerpc.rs | 16 + .../unix/bsd/netbsdlike/openbsd/powerpc64.rs | 16 + .../unix/bsd/netbsdlike/openbsd/riscv64.rs | 35 + .../unix/bsd/netbsdlike/openbsd/sparc64.rs | 8 + .../src/unix/bsd/netbsdlike/openbsd/x86.rs | 16 + .../src/unix/bsd/netbsdlike/openbsd/x86_64.rs | 130 + .../vendor/libc/src/unix/haiku/b32.rs | 20 + .../vendor/libc/src/unix/haiku/b64.rs | 20 + .../vendor/libc/src/unix/haiku/mod.rs | 2105 ++ .../vendor/libc/src/unix/haiku/native.rs | 1488 ++ .../vendor/libc/src/unix/haiku/x86_64.rs | 264 + .../vendor/libc/src/unix/hurd/align.rs | 1 + .../vendor/libc/src/unix/hurd/b32.rs | 93 + .../vendor/libc/src/unix/hurd/b64.rs | 95 + .../vendor/libc/src/unix/hurd/mod.rs | 4687 ++++ .../vendor/libc/src/unix/hurd/no_align.rs | 1 + .../src/unix/linux_like/android/b32/arm.rs | 550 + .../src/unix/linux_like/android/b32/mod.rs | 244 + .../unix/linux_like/android/b32/x86/align.rs | 7 + .../unix/linux_like/android/b32/x86/mod.rs | 622 + .../linux_like/android/b64/aarch64/align.rs | 29 + .../linux_like/android/b64/aarch64/int128.rs | 7 + .../linux_like/android/b64/aarch64/mod.rs | 430 + .../src/unix/linux_like/android/b64/mod.rs | 355 + .../linux_like/android/b64/riscv64/align.rs | 7 + .../linux_like/android/b64/riscv64/mod.rs | 353 + .../linux_like/android/b64/x86_64/align.rs | 7 + .../unix/linux_like/android/b64/x86_64/mod.rs | 802 + .../libc/src/unix/linux_like/android/mod.rs | 4176 ++++ .../src/unix/linux_like/emscripten/align.rs | 74 + .../src/unix/linux_like/emscripten/lfs64.rs | 213 + .../src/unix/linux_like/emscripten/mod.rs | 1794 ++ .../unix/linux_like/emscripten/no_align.rs | 63 + .../libc/src/unix/linux_like/linux/align.rs | 205 + .../unix/linux_like/linux/arch/generic/mod.rs | 333 + .../unix/linux_like/linux/arch/mips/mod.rs | 323 + .../src/unix/linux_like/linux/arch/mod.rs | 18 + .../unix/linux_like/linux/arch/powerpc/mod.rs | 277 + .../unix/linux_like/linux/arch/sparc/mod.rs | 259 + .../src/unix/linux_like/linux/gnu/align.rs | 13 + .../linux_like/linux/gnu/b32/arm/align.rs | 53 + .../unix/linux_like/linux/gnu/b32/arm/mod.rs | 864 + .../linux_like/linux/gnu/b32/csky/align.rs | 7 + .../unix/linux_like/linux/gnu/b32/csky/mod.rs | 741 + .../linux_like/linux/gnu/b32/m68k/align.rs | 7 + .../unix/linux_like/linux/gnu/b32/m68k/mod.rs | 850 + .../linux_like/linux/gnu/b32/mips/align.rs | 7 + .../unix/linux_like/linux/gnu/b32/mips/mod.rs | 819 + .../src/unix/linux_like/linux/gnu/b32/mod.rs | 361 + .../unix/linux_like/linux/gnu/b32/powerpc.rs | 825 + .../linux_like/linux/gnu/b32/riscv32/align.rs | 44 + .../linux_like/linux/gnu/b32/riscv32/mod.rs | 813 + .../linux_like/linux/gnu/b32/sparc/align.rs | 7 + .../linux_like/linux/gnu/b32/sparc/mod.rs | 857 + .../linux_like/linux/gnu/b32/x86/align.rs | 7 + .../unix/linux_like/linux/gnu/b32/x86/mod.rs | 1100 + .../linux_like/linux/gnu/b64/aarch64/align.rs | 51 + .../linux/gnu/b64/aarch64/fallback.rs | 8 + .../linux_like/linux/gnu/b64/aarch64/ilp32.rs | 64 + .../linux/gnu/b64/aarch64/int128.rs | 7 + .../linux_like/linux/gnu/b64/aarch64/lp64.rs | 73 + .../linux_like/linux/gnu/b64/aarch64/mod.rs | 937 + .../linux/gnu/b64/loongarch64/align.rs | 40 + .../linux/gnu/b64/loongarch64/mod.rs | 900 + .../linux_like/linux/gnu/b64/mips64/align.rs | 7 + .../linux_like/linux/gnu/b64/mips64/mod.rs | 934 + .../src/unix/linux_like/linux/gnu/b64/mod.rs | 128 + .../linux/gnu/b64/powerpc64/align.rs | 7 + .../linux_like/linux/gnu/b64/powerpc64/mod.rs | 979 + .../linux_like/linux/gnu/b64/riscv64/align.rs | 44 + .../linux_like/linux/gnu/b64/riscv64/mod.rs | 852 + .../unix/linux_like/linux/gnu/b64/s390x.rs | 964 + .../linux_like/linux/gnu/b64/sparc64/align.rs | 7 + .../linux_like/linux/gnu/b64/sparc64/mod.rs | 931 + .../linux_like/linux/gnu/b64/x86_64/align.rs | 24 + .../linux_like/linux/gnu/b64/x86_64/mod.rs | 824 + .../linux/gnu/b64/x86_64/not_x32.rs | 451 + .../linux_like/linux/gnu/b64/x86_64/x32.rs | 404 + .../libc/src/unix/linux_like/linux/gnu/mod.rs | 1593 ++ .../src/unix/linux_like/linux/gnu/no_align.rs | 10 + .../libc/src/unix/linux_like/linux/mod.rs | 5689 +++++ .../linux_like/linux/musl/b32/arm/align.rs | 7 + .../unix/linux_like/linux/musl/b32/arm/mod.rs | 853 + .../unix/linux_like/linux/musl/b32/hexagon.rs | 667 + .../linux_like/linux/musl/b32/mips/align.rs | 7 + .../linux_like/linux/musl/b32/mips/mod.rs | 788 + .../src/unix/linux_like/linux/musl/b32/mod.rs | 65 + .../unix/linux_like/linux/musl/b32/powerpc.rs | 802 + .../linux/musl/b32/riscv32/align.rs | 7 + .../linux_like/linux/musl/b32/riscv32/mod.rs | 798 + .../linux_like/linux/musl/b32/x86/align.rs | 7 + .../unix/linux_like/linux/musl/b32/x86/mod.rs | 968 + .../linux/musl/b64/aarch64/align.rs | 42 + .../linux/musl/b64/aarch64/int128.rs | 7 + .../linux_like/linux/musl/b64/aarch64/mod.rs | 658 + .../unix/linux_like/linux/musl/b64/mips64.rs | 688 + .../src/unix/linux_like/linux/musl/b64/mod.rs | 163 + .../linux_like/linux/musl/b64/powerpc64.rs | 695 + .../linux/musl/b64/riscv64/align.rs | 44 + .../linux_like/linux/musl/b64/riscv64/mod.rs | 727 + .../unix/linux_like/linux/musl/b64/s390x.rs | 724 + .../linux_like/linux/musl/b64/x86_64/align.rs | 25 + .../linux_like/linux/musl/b64/x86_64/mod.rs | 915 + .../src/unix/linux_like/linux/musl/lfs64.rs | 241 + .../src/unix/linux_like/linux/musl/mod.rs | 927 + .../src/unix/linux_like/linux/no_align.rs | 144 + .../unix/linux_like/linux/non_exhaustive.rs | 9 + .../src/unix/linux_like/linux/uclibc/align.rs | 28 + .../unix/linux_like/linux/uclibc/arm/align.rs | 13 + .../unix/linux_like/linux/uclibc/arm/mod.rs | 925 + .../linux_like/linux/uclibc/arm/no_align.rs | 10 + .../linux/uclibc/mips/mips32/align.rs | 13 + .../linux/uclibc/mips/mips32/mod.rs | 692 + .../linux/uclibc/mips/mips32/no_align.rs | 10 + .../linux/uclibc/mips/mips64/align.rs | 10 + .../linux/uclibc/mips/mips64/mod.rs | 207 + .../linux/uclibc/mips/mips64/no_align.rs | 7 + .../unix/linux_like/linux/uclibc/mips/mod.rs | 310 + .../src/unix/linux_like/linux/uclibc/mod.rs | 392 + .../unix/linux_like/linux/uclibc/no_align.rs | 53 + .../linux_like/linux/uclibc/x86_64/l4re.rs | 53 + .../linux_like/linux/uclibc/x86_64/mod.rs | 345 + .../linux_like/linux/uclibc/x86_64/other.rs | 5 + .../vendor/libc/src/unix/linux_like/mod.rs | 1899 ++ utshell-0.5.0/vendor/libc/src/unix/mod.rs | 1616 ++ .../libc/src/unix/newlib/aarch64/mod.rs | 54 + .../vendor/libc/src/unix/newlib/align.rs | 61 + .../vendor/libc/src/unix/newlib/arm/mod.rs | 56 + .../vendor/libc/src/unix/newlib/espidf/mod.rs | 110 + .../vendor/libc/src/unix/newlib/generic.rs | 33 + .../libc/src/unix/newlib/horizon/mod.rs | 270 + .../vendor/libc/src/unix/newlib/mod.rs | 798 + .../vendor/libc/src/unix/newlib/no_align.rs | 51 + .../libc/src/unix/newlib/powerpc/mod.rs | 16 + .../vendor/libc/src/unix/newlib/vita/mod.rs | 236 + .../vendor/libc/src/unix/no_align.rs | 6 + .../vendor/libc/src/unix/nto/aarch64.rs | 36 + utshell-0.5.0/vendor/libc/src/unix/nto/mod.rs | 3508 +++ .../vendor/libc/src/unix/nto/neutrino.rs | 1288 ++ .../vendor/libc/src/unix/nto/x86_64.rs | 132 + .../vendor/libc/src/unix/redox/mod.rs | 1416 ++ .../vendor/libc/src/unix/solarish/compat.rs | 220 + .../vendor/libc/src/unix/solarish/illumos.rs | 88 + .../vendor/libc/src/unix/solarish/mod.rs | 3309 +++ .../vendor/libc/src/unix/solarish/solaris.rs | 101 + .../vendor/libc/src/unix/solarish/x86.rs | 29 + .../vendor/libc/src/unix/solarish/x86_64.rs | 190 + .../libc/src/unix/solarish/x86_common.rs | 65 + .../vendor/libc/src/vxworks/aarch64.rs | 4 + utshell-0.5.0/vendor/libc/src/vxworks/arm.rs | 4 + utshell-0.5.0/vendor/libc/src/vxworks/mod.rs | 1947 ++ .../vendor/libc/src/vxworks/powerpc.rs | 4 + .../vendor/libc/src/vxworks/powerpc64.rs | 4 + utshell-0.5.0/vendor/libc/src/vxworks/x86.rs | 4 + .../vendor/libc/src/vxworks/x86_64.rs | 4 + utshell-0.5.0/vendor/libc/src/wasi.rs | 831 + .../vendor/libc/src/windows/gnu/align.rs | 19 + .../vendor/libc/src/windows/gnu/mod.rs | 23 + utshell-0.5.0/vendor/libc/src/windows/mod.rs | 601 + .../vendor/libc/src/windows/msvc/mod.rs | 20 + utshell-0.5.0/vendor/libc/src/xous.rs | 49 + utshell-0.5.0/vendor/libc/tests/const_fn.rs | 5 + .../vendor/memchr/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/memchr/COPYING | 3 + utshell-0.5.0/vendor/memchr/Cargo.toml | 78 + utshell-0.5.0/vendor/memchr/LICENSE-MIT | 21 + utshell-0.5.0/vendor/memchr/README.md | 107 + utshell-0.5.0/vendor/memchr/UNLICENSE | 24 + utshell-0.5.0/vendor/memchr/build.rs | 88 + utshell-0.5.0/vendor/memchr/rustfmt.toml | 2 + .../memchr/scripts/make-byte-frequency-table | 74 + utshell-0.5.0/vendor/memchr/src/cow.rs | 97 + utshell-0.5.0/vendor/memchr/src/lib.rs | 181 + utshell-0.5.0/vendor/memchr/src/memchr/c.rs | 44 + .../vendor/memchr/src/memchr/fallback.rs | 329 + .../vendor/memchr/src/memchr/iter.rs | 173 + utshell-0.5.0/vendor/memchr/src/memchr/mod.rs | 410 + .../vendor/memchr/src/memchr/naive.rs | 25 + .../vendor/memchr/src/memchr/x86/avx.rs | 755 + .../vendor/memchr/src/memchr/x86/mod.rs | 148 + .../vendor/memchr/src/memchr/x86/sse2.rs | 791 + .../vendor/memchr/src/memchr/x86/sse42.rs | 72 + .../memchr/src/memmem/byte_frequencies.rs | 258 + .../vendor/memchr/src/memmem/genericsimd.rs | 266 + utshell-0.5.0/vendor/memchr/src/memmem/mod.rs | 1321 ++ .../memchr/src/memmem/prefilter/fallback.rs | 122 + .../src/memmem/prefilter/genericsimd.rs | 207 + .../vendor/memchr/src/memmem/prefilter/mod.rs | 570 + .../memchr/src/memmem/prefilter/wasm.rs | 39 + .../memchr/src/memmem/prefilter/x86/avx.rs | 46 + .../memchr/src/memmem/prefilter/x86/mod.rs | 5 + .../memchr/src/memmem/prefilter/x86/sse.rs | 42 + .../vendor/memchr/src/memmem/rabinkarp.rs | 233 + .../vendor/memchr/src/memmem/rarebytes.rs | 136 + .../vendor/memchr/src/memmem/twoway.rs | 878 + .../vendor/memchr/src/memmem/util.rs | 88 + .../vendor/memchr/src/memmem/vector.rs | 131 + .../vendor/memchr/src/memmem/wasm.rs | 75 + .../vendor/memchr/src/memmem/x86/avx.rs | 139 + .../vendor/memchr/src/memmem/x86/mod.rs | 2 + .../vendor/memchr/src/memmem/x86/sse.rs | 89 + .../vendor/memchr/src/tests/memchr/iter.rs | 230 + .../vendor/memchr/src/tests/memchr/memchr.rs | 134 + .../vendor/memchr/src/tests/memchr/mod.rs | 7 + .../vendor/memchr/src/tests/memchr/simple.rs | 23 + .../memchr/src/tests/memchr/testdata.rs | 351 + utshell-0.5.0/vendor/memchr/src/tests/mod.rs | 15 + .../memchr/src/tests/x86_64-soft_float.json | 15 + .../vendor/memoffset/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/memoffset/Cargo.toml | 29 + utshell-0.5.0/vendor/memoffset/LICENSE | 19 + utshell-0.5.0/vendor/memoffset/README.md | 65 + utshell-0.5.0/vendor/memoffset/build.rs | 22 + utshell-0.5.0/vendor/memoffset/ci/miri.sh | 14 + utshell-0.5.0/vendor/memoffset/src/lib.rs | 92 + .../vendor/memoffset/src/offset_of.rs | 282 + .../vendor/memoffset/src/raw_field.rs | 117 + utshell-0.5.0/vendor/memoffset/src/span_of.rs | 256 + utshell-0.5.0/vendor/nix/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/nix/CHANGELOG.md | 1442 ++ utshell-0.5.0/vendor/nix/Cargo.toml | 185 + utshell-0.5.0/vendor/nix/LICENSE | 21 + utshell-0.5.0/vendor/nix/README.md | 105 + utshell-0.5.0/vendor/nix/src/dir.rs | 259 + utshell-0.5.0/vendor/nix/src/env.rs | 64 + utshell-0.5.0/vendor/nix/src/errno.rs | 3286 +++ utshell-0.5.0/vendor/nix/src/fcntl.rs | 882 + utshell-0.5.0/vendor/nix/src/features.rs | 124 + utshell-0.5.0/vendor/nix/src/ifaddrs.rs | 213 + utshell-0.5.0/vendor/nix/src/kmod.rs | 122 + utshell-0.5.0/vendor/nix/src/lib.rs | 334 + utshell-0.5.0/vendor/nix/src/macros.rs | 328 + utshell-0.5.0/vendor/nix/src/mount/bsd.rs | 443 + utshell-0.5.0/vendor/nix/src/mount/linux.rs | 112 + utshell-0.5.0/vendor/nix/src/mount/mod.rs | 23 + utshell-0.5.0/vendor/nix/src/mqueue.rs | 248 + utshell-0.5.0/vendor/nix/src/net/if_.rs | 468 + utshell-0.5.0/vendor/nix/src/net/mod.rs | 4 + utshell-0.5.0/vendor/nix/src/poll.rs | 175 + utshell-0.5.0/vendor/nix/src/pty.rs | 371 + utshell-0.5.0/vendor/nix/src/sched.rs | 294 + utshell-0.5.0/vendor/nix/src/sys/aio.rs | 1244 ++ utshell-0.5.0/vendor/nix/src/sys/epoll.rs | 108 + utshell-0.5.0/vendor/nix/src/sys/event.rs | 346 + utshell-0.5.0/vendor/nix/src/sys/eventfd.rs | 17 + utshell-0.5.0/vendor/nix/src/sys/inotify.rs | 257 + utshell-0.5.0/vendor/nix/src/sys/ioctl/bsd.rs | 129 + .../vendor/nix/src/sys/ioctl/linux.rs | 172 + utshell-0.5.0/vendor/nix/src/sys/ioctl/mod.rs | 786 + utshell-0.5.0/vendor/nix/src/sys/memfd.rs | 47 + utshell-0.5.0/vendor/nix/src/sys/mman.rs | 569 + utshell-0.5.0/vendor/nix/src/sys/mod.rs | 228 + .../vendor/nix/src/sys/personality.rs | 97 + utshell-0.5.0/vendor/nix/src/sys/pthread.rs | 43 + .../vendor/nix/src/sys/ptrace/bsd.rs | 187 + .../vendor/nix/src/sys/ptrace/linux.rs | 504 + .../vendor/nix/src/sys/ptrace/mod.rs | 22 + utshell-0.5.0/vendor/nix/src/sys/quota.rs | 277 + utshell-0.5.0/vendor/nix/src/sys/reboot.rs | 52 + utshell-0.5.0/vendor/nix/src/sys/resource.rs | 437 + utshell-0.5.0/vendor/nix/src/sys/select.rs | 434 + utshell-0.5.0/vendor/nix/src/sys/sendfile.rs | 277 + utshell-0.5.0/vendor/nix/src/sys/signal.rs | 1347 ++ utshell-0.5.0/vendor/nix/src/sys/signalfd.rs | 171 + .../vendor/nix/src/sys/socket/addr.rs | 2973 +++ .../vendor/nix/src/sys/socket/mod.rs | 2254 ++ .../vendor/nix/src/sys/socket/sockopt.rs | 1031 + utshell-0.5.0/vendor/nix/src/sys/stat.rs | 436 + utshell-0.5.0/vendor/nix/src/sys/statfs.rs | 764 + utshell-0.5.0/vendor/nix/src/sys/statvfs.rs | 174 + utshell-0.5.0/vendor/nix/src/sys/sysinfo.rs | 83 + utshell-0.5.0/vendor/nix/src/sys/termios.rs | 1118 + utshell-0.5.0/vendor/nix/src/sys/time.rs | 809 + utshell-0.5.0/vendor/nix/src/sys/timer.rs | 179 + utshell-0.5.0/vendor/nix/src/sys/timerfd.rs | 205 + utshell-0.5.0/vendor/nix/src/sys/uio.rs | 270 + utshell-0.5.0/vendor/nix/src/sys/utsname.rs | 77 + utshell-0.5.0/vendor/nix/src/sys/wait.rs | 381 + utshell-0.5.0/vendor/nix/src/time.rs | 269 + utshell-0.5.0/vendor/nix/src/ucontext.rs | 43 + utshell-0.5.0/vendor/nix/src/unistd.rs | 3352 +++ utshell-0.5.0/vendor/nix/test/common/mod.rs | 149 + utshell-0.5.0/vendor/nix/test/sys/mod.rs | 60 + utshell-0.5.0/vendor/nix/test/sys/test_aio.rs | 626 + .../vendor/nix/test/sys/test_aio_drop.rs | 35 + .../vendor/nix/test/sys/test_epoll.rs | 24 + .../vendor/nix/test/sys/test_inotify.rs | 65 + .../vendor/nix/test/sys/test_ioctl.rs | 376 + .../vendor/nix/test/sys/test_mman.rs | 117 + .../vendor/nix/test/sys/test_pthread.rs | 22 + .../vendor/nix/test/sys/test_ptrace.rs | 275 + .../vendor/nix/test/sys/test_select.rs | 81 + .../vendor/nix/test/sys/test_signal.rs | 147 + .../vendor/nix/test/sys/test_signalfd.rs | 27 + .../vendor/nix/test/sys/test_socket.rs | 2557 +++ .../vendor/nix/test/sys/test_sockopt.rs | 356 + .../vendor/nix/test/sys/test_stat.rs | 29 + .../vendor/nix/test/sys/test_sysinfo.rs | 20 + .../vendor/nix/test/sys/test_termios.rs | 136 + .../vendor/nix/test/sys/test_timerfd.rs | 69 + utshell-0.5.0/vendor/nix/test/sys/test_uio.rs | 270 + .../vendor/nix/test/sys/test_wait.rs | 257 + utshell-0.5.0/vendor/nix/test/test.rs | 123 + .../vendor/nix/test/test_clearenv.rs | 9 + utshell-0.5.0/vendor/nix/test/test_dir.rs | 65 + utshell-0.5.0/vendor/nix/test/test_fcntl.rs | 565 + .../nix/test/test_kmod/hello_mod/Makefile | 7 + .../nix/test/test_kmod/hello_mod/hello.c | 26 + .../vendor/nix/test/test_kmod/mod.rs | 188 + utshell-0.5.0/vendor/nix/test/test_mount.rs | 271 + utshell-0.5.0/vendor/nix/test/test_mq.rs | 190 + utshell-0.5.0/vendor/nix/test/test_net.rs | 19 + .../vendor/nix/test/test_nix_path.rs | 1 + utshell-0.5.0/vendor/nix/test/test_nmount.rs | 49 + utshell-0.5.0/vendor/nix/test/test_poll.rs | 84 + utshell-0.5.0/vendor/nix/test/test_pty.rs | 313 + .../vendor/nix/test/test_ptymaster_drop.rs | 20 + .../vendor/nix/test/test_resource.rs | 34 + utshell-0.5.0/vendor/nix/test/test_sched.rs | 35 + .../vendor/nix/test/test_sendfile.rs | 208 + utshell-0.5.0/vendor/nix/test/test_stat.rs | 421 + utshell-0.5.0/vendor/nix/test/test_time.rs | 59 + utshell-0.5.0/vendor/nix/test/test_timer.rs | 102 + utshell-0.5.0/vendor/nix/test/test_unistd.rs | 1378 ++ .../vendor/once_cell/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/once_cell/CHANGELOG.md | 220 + utshell-0.5.0/vendor/once_cell/Cargo.lock | 173 + utshell-0.5.0/vendor/once_cell/Cargo.toml | 109 + utshell-0.5.0/vendor/once_cell/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/once_cell/LICENSE-MIT | 23 + utshell-0.5.0/vendor/once_cell/README.md | 58 + utshell-0.5.0/vendor/once_cell/bors.toml | 2 + .../vendor/once_cell/examples/bench.rs | 28 + .../once_cell/examples/bench_acquire.rs | 39 + .../examples/bench_vs_lazy_static.rs | 51 + .../vendor/once_cell/examples/lazy_static.rs | 36 + .../examples/reentrant_init_deadlocks.rs | 14 + .../vendor/once_cell/examples/regex.rs | 49 + .../examples/test_synchronization.rs | 38 + utshell-0.5.0/vendor/once_cell/src/imp_cs.rs | 78 + utshell-0.5.0/vendor/once_cell/src/imp_pl.rs | 174 + utshell-0.5.0/vendor/once_cell/src/imp_std.rs | 425 + utshell-0.5.0/vendor/once_cell/src/lib.rs | 1428 ++ utshell-0.5.0/vendor/once_cell/src/race.rs | 419 + utshell-0.5.0/vendor/once_cell/tests/it.rs | 977 + .../pin-project-lite/.cargo-checksum.json | 1 + .../vendor/pin-project-lite/CHANGELOG.md | 242 + .../vendor/pin-project-lite/Cargo.toml | 69 + .../vendor/pin-project-lite/LICENSE-APACHE | 177 + .../vendor/pin-project-lite/LICENSE-MIT | 23 + .../vendor/pin-project-lite/README.md | 130 + .../vendor/pin-project-lite/src/lib.rs | 1682 ++ .../pin-project-lite/tests/auxiliary/mod.rs | 12 + .../pin-project-lite/tests/compiletest.rs | 16 + .../pin-project-lite/tests/drop_order.rs | 169 + .../tests/expand/default/enum.expanded.rs | 143 + .../tests/expand/default/enum.rs | 17 + .../tests/expand/default/struct.expanded.rs | 90 + .../tests/expand/default/struct.rs | 11 + .../tests/expand/multifields/enum.expanded.rs | 89 + .../tests/expand/multifields/enum.rs | 18 + .../expand/multifields/struct.expanded.rs | 151 + .../tests/expand/multifields/struct.rs | 15 + .../tests/expand/naming/enum-all.expanded.rs | 143 + .../tests/expand/naming/enum-all.rs | 17 + .../tests/expand/naming/enum-mut.expanded.rs | 64 + .../tests/expand/naming/enum-mut.rs | 15 + .../tests/expand/naming/enum-none.expanded.rs | 26 + .../tests/expand/naming/enum-none.rs | 14 + .../tests/expand/naming/enum-ref.expanded.rs | 64 + .../tests/expand/naming/enum-ref.rs | 15 + .../expand/naming/struct-all.expanded.rs | 128 + .../tests/expand/naming/struct-all.rs | 14 + .../expand/naming/struct-mut.expanded.rs | 90 + .../tests/expand/naming/struct-mut.rs | 12 + .../expand/naming/struct-none.expanded.rs | 90 + .../tests/expand/naming/struct-none.rs | 11 + .../expand/naming/struct-ref.expanded.rs | 90 + .../tests/expand/naming/struct-ref.rs | 12 + .../tests/expand/not_unpin/enum.expanded.rs | 99 + .../tests/expand/not_unpin/enum.rs | 17 + .../tests/expand/not_unpin/struct.expanded.rs | 88 + .../tests/expand/not_unpin/struct.rs | 14 + .../tests/expand/pinned_drop/enum.expanded.rs | 112 + .../tests/expand/pinned_drop/enum.rs | 23 + .../expand/pinned_drop/struct.expanded.rs | 101 + .../tests/expand/pinned_drop/struct.rs | 18 + .../tests/expand/pub/enum.expanded.rs | 101 + .../pin-project-lite/tests/expand/pub/enum.rs | 16 + .../tests/expand/pub/struct.expanded.rs | 90 + .../tests/expand/pub/struct.rs | 11 + .../pin-project-lite/tests/expandtest.rs | 44 + .../pin-project-lite/tests/include/basic.rs | 35 + .../vendor/pin-project-lite/tests/lint.rs | 281 + .../pin-project-lite/tests/proper_unpin.rs | 100 + .../vendor/pin-project-lite/tests/test.rs | 698 + .../tests/ui/pin_project/conflict-drop.rs | 15 + .../tests/ui/pin_project/conflict-drop.stderr | 16 + .../tests/ui/pin_project/conflict-unpin.rs | 64 + .../ui/pin_project/conflict-unpin.stderr | 84 + .../tests/ui/pin_project/invalid-bounds.rs | 93 + .../ui/pin_project/invalid-bounds.stderr | 470 + .../tests/ui/pin_project/invalid.rs | 25 + .../tests/ui/pin_project/invalid.stderr | 53 + .../pin_project/overlapping_lifetime_names.rs | 10 + .../overlapping_lifetime_names.stderr | 75 + .../pin_project/overlapping_unpin_struct.rs | 20 + .../overlapping_unpin_struct.stderr | 34 + .../tests/ui/pin_project/packed.rs | 19 + .../tests/ui/pin_project/packed.stderr | 101 + .../tests/ui/pin_project/unpin_sneaky.rs | 12 + .../tests/ui/pin_project/unpin_sneaky.stderr | 5 + .../tests/ui/pin_project/unsupported.rs | 27 + .../tests/ui/pin_project/unsupported.stderr | 115 + .../tests/ui/pinned_drop/call-drop-inner.rs | 17 + .../ui/pinned_drop/call-drop-inner.stderr | 21 + .../ui/pinned_drop/conditional-drop-impl.rs | 26 + .../pinned_drop/conditional-drop-impl.stderr | 36 + .../vendor/pin-utils/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/pin-utils/Cargo.toml | 22 + utshell-0.5.0/vendor/pin-utils/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/pin-utils/LICENSE-MIT | 25 + utshell-0.5.0/vendor/pin-utils/README.md | 42 + utshell-0.5.0/vendor/pin-utils/src/lib.rs | 17 + .../vendor/pin-utils/src/projection.rs | 100 + .../vendor/pin-utils/src/stack_pin.rs | 25 + .../vendor/pin-utils/tests/projection.rs | 27 + .../vendor/pin-utils/tests/stack_pin.rs | 21 + .../vendor/proc-macro2/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/proc-macro2/Cargo.toml | 76 + .../vendor/proc-macro2/LICENSE-APACHE | 176 + utshell-0.5.0/vendor/proc-macro2/LICENSE-MIT | 23 + utshell-0.5.0/vendor/proc-macro2/README.md | 94 + utshell-0.5.0/vendor/proc-macro2/build.rs | 202 + .../vendor/proc-macro2/build/probe.rs | 25 + .../vendor/proc-macro2/rust-toolchain.toml | 2 + .../vendor/proc-macro2/src/detection.rs | 75 + utshell-0.5.0/vendor/proc-macro2/src/extra.rs | 151 + .../vendor/proc-macro2/src/fallback.rs | 1170 + utshell-0.5.0/vendor/proc-macro2/src/lib.rs | 1345 ++ .../vendor/proc-macro2/src/location.rs | 29 + .../vendor/proc-macro2/src/marker.rs | 17 + utshell-0.5.0/vendor/proc-macro2/src/parse.rs | 996 + utshell-0.5.0/vendor/proc-macro2/src/rcvec.rs | 145 + .../vendor/proc-macro2/src/wrapper.rs | 954 + .../vendor/proc-macro2/tests/comments.rs | 105 + .../vendor/proc-macro2/tests/features.rs | 8 + .../vendor/proc-macro2/tests/marker.rs | 99 + .../vendor/proc-macro2/tests/test.rs | 795 + .../vendor/proc-macro2/tests/test_fmt.rs | 28 + .../vendor/proc-macro2/tests/test_size.rs | 42 + .../vendor/quote/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/quote/Cargo.toml | 50 + utshell-0.5.0/vendor/quote/LICENSE-APACHE | 176 + utshell-0.5.0/vendor/quote/LICENSE-MIT | 23 + utshell-0.5.0/vendor/quote/README.md | 272 + .../vendor/quote/rust-toolchain.toml | 2 + utshell-0.5.0/vendor/quote/src/ext.rs | 110 + utshell-0.5.0/vendor/quote/src/format.rs | 168 + .../vendor/quote/src/ident_fragment.rs | 88 + utshell-0.5.0/vendor/quote/src/lib.rs | 1444 ++ utshell-0.5.0/vendor/quote/src/runtime.rs | 530 + utshell-0.5.0/vendor/quote/src/spanned.rs | 50 + utshell-0.5.0/vendor/quote/src/to_tokens.rs | 209 + .../vendor/quote/tests/compiletest.rs | 7 + utshell-0.5.0/vendor/quote/tests/test.rs | 549 + .../ui/does-not-have-iter-interpolated-dup.rs | 9 + ...does-not-have-iter-interpolated-dup.stderr | 11 + .../ui/does-not-have-iter-interpolated.rs | 9 + .../ui/does-not-have-iter-interpolated.stderr | 11 + .../tests/ui/does-not-have-iter-separated.rs | 5 + .../ui/does-not-have-iter-separated.stderr | 10 + .../quote/tests/ui/does-not-have-iter.rs | 5 + .../quote/tests/ui/does-not-have-iter.stderr | 10 + .../vendor/quote/tests/ui/not-quotable.rs | 7 + .../vendor/quote/tests/ui/not-quotable.stderr | 20 + .../vendor/quote/tests/ui/not-repeatable.rs | 8 + .../quote/tests/ui/not-repeatable.stderr | 35 + .../vendor/quote/tests/ui/wrong-type-span.rs | 7 + .../quote/tests/ui/wrong-type-span.stderr | 10 + .../vendor/rustc-hash/.cargo-checksum.json | 1 + .../vendor/rustc-hash/CODE_OF_CONDUCT.md | 40 + utshell-0.5.0/vendor/rustc-hash/Cargo.toml | 25 + .../vendor/rustc-hash/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/rustc-hash/LICENSE-MIT | 23 + utshell-0.5.0/vendor/rustc-hash/README.md | 38 + utshell-0.5.0/vendor/rustc-hash/src/lib.rs | 148 + .../self_cell-0.10.3/.cargo-checksum.json | 1 + .../vendor/self_cell-0.10.3/Cargo.toml | 45 + utshell-0.5.0/vendor/self_cell-0.10.3/LICENSE | 201 + .../vendor/self_cell-0.10.3/README.md | 18 + .../vendor/self_cell-0.10.3/src/lib.rs | 162 + .../vendor/self_cell/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/self_cell/Cargo.toml | 48 + utshell-0.5.0/vendor/self_cell/LICENSE | 201 + utshell-0.5.0/vendor/self_cell/README.md | 184 + utshell-0.5.0/vendor/self_cell/src/lib.rs | 670 + .../vendor/self_cell/src/unsafe_self_cell.rs | 225 + .../vendor/slab/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/slab/CHANGELOG.md | 54 + utshell-0.5.0/vendor/slab/Cargo.toml | 55 + utshell-0.5.0/vendor/slab/LICENSE | 25 + utshell-0.5.0/vendor/slab/README.md | 51 + utshell-0.5.0/vendor/slab/build.rs | 24 + utshell-0.5.0/vendor/slab/src/builder.rs | 63 + utshell-0.5.0/vendor/slab/src/lib.rs | 1589 ++ utshell-0.5.0/vendor/slab/src/serde.rs | 62 + utshell-0.5.0/vendor/slab/tests/serde.rs | 49 + utshell-0.5.0/vendor/slab/tests/slab.rs | 733 + .../vendor/smallvec/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/smallvec/Cargo.toml | 72 + utshell-0.5.0/vendor/smallvec/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/smallvec/LICENSE-MIT | 25 + utshell-0.5.0/vendor/smallvec/README.md | 26 + .../vendor/smallvec/benches/bench.rs | 312 + .../vendor/smallvec/debug_metadata/README.md | 111 + .../smallvec/debug_metadata/smallvec.natvis | 35 + .../vendor/smallvec/scripts/run_miri.sh | 24 + .../vendor/smallvec/src/arbitrary.rs | 19 + utshell-0.5.0/vendor/smallvec/src/lib.rs | 2471 +++ .../vendor/smallvec/src/specialization.rs | 19 + utshell-0.5.0/vendor/smallvec/src/tests.rs | 1025 + .../smallvec/tests/debugger_visualizer.rs | 68 + utshell-0.5.0/vendor/smallvec/tests/macro.rs | 24 + .../stable_deref_trait/.cargo-checksum.json | 1 + .../vendor/stable_deref_trait/Cargo.toml | 27 + .../vendor/stable_deref_trait/LICENSE-APACHE | 201 + .../vendor/stable_deref_trait/LICENSE-MIT | 25 + .../vendor/stable_deref_trait/README.md | 23 + .../vendor/stable_deref_trait/src/lib.rs | 189 + utshell-0.5.0/vendor/syn/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/syn/Cargo.toml | 147 + utshell-0.5.0/vendor/syn/LICENSE-APACHE | 176 + utshell-0.5.0/vendor/syn/LICENSE-MIT | 23 + utshell-0.5.0/vendor/syn/README.md | 284 + utshell-0.5.0/vendor/syn/benches/file.rs | 57 + utshell-0.5.0/vendor/syn/benches/rust.rs | 182 + utshell-0.5.0/vendor/syn/src/attr.rs | 793 + utshell-0.5.0/vendor/syn/src/bigint.rs | 66 + utshell-0.5.0/vendor/syn/src/buffer.rs | 432 + .../vendor/syn/src/custom_keyword.rs | 259 + .../vendor/syn/src/custom_punctuation.rs | 302 + utshell-0.5.0/vendor/syn/src/data.rs | 423 + utshell-0.5.0/vendor/syn/src/derive.rs | 259 + utshell-0.5.0/vendor/syn/src/discouraged.rs | 225 + utshell-0.5.0/vendor/syn/src/drops.rs | 58 + utshell-0.5.0/vendor/syn/src/error.rs | 467 + utshell-0.5.0/vendor/syn/src/export.rs | 73 + utshell-0.5.0/vendor/syn/src/expr.rs | 3574 +++ utshell-0.5.0/vendor/syn/src/ext.rs | 136 + utshell-0.5.0/vendor/syn/src/file.rs | 130 + utshell-0.5.0/vendor/syn/src/gen/clone.rs | 2208 ++ utshell-0.5.0/vendor/syn/src/gen/debug.rs | 3159 +++ utshell-0.5.0/vendor/syn/src/gen/eq.rs | 2239 ++ utshell-0.5.0/vendor/syn/src/gen/fold.rs | 3760 ++++ utshell-0.5.0/vendor/syn/src/gen/hash.rs | 2803 +++ utshell-0.5.0/vendor/syn/src/gen/visit.rs | 3848 ++++ utshell-0.5.0/vendor/syn/src/gen/visit_mut.rs | 3845 ++++ utshell-0.5.0/vendor/syn/src/gen_helper.rs | 34 + utshell-0.5.0/vendor/syn/src/generics.rs | 1250 ++ utshell-0.5.0/vendor/syn/src/group.rs | 291 + utshell-0.5.0/vendor/syn/src/ident.rs | 108 + utshell-0.5.0/vendor/syn/src/item.rs | 3450 +++ utshell-0.5.0/vendor/syn/src/lib.rs | 1005 + utshell-0.5.0/vendor/syn/src/lifetime.rs | 156 + utshell-0.5.0/vendor/syn/src/lit.rs | 1639 ++ utshell-0.5.0/vendor/syn/src/lookahead.rs | 169 + utshell-0.5.0/vendor/syn/src/mac.rs | 215 + utshell-0.5.0/vendor/syn/src/macros.rs | 176 + utshell-0.5.0/vendor/syn/src/meta.rs | 427 + utshell-0.5.0/vendor/syn/src/op.rs | 219 + utshell-0.5.0/vendor/syn/src/parse.rs | 1381 ++ .../vendor/syn/src/parse_macro_input.rs | 128 + utshell-0.5.0/vendor/syn/src/parse_quote.rs | 210 + utshell-0.5.0/vendor/syn/src/pat.rs | 947 + utshell-0.5.0/vendor/syn/src/path.rs | 907 + utshell-0.5.0/vendor/syn/src/print.rs | 16 + utshell-0.5.0/vendor/syn/src/punctuated.rs | 1109 + utshell-0.5.0/vendor/syn/src/restriction.rs | 176 + utshell-0.5.0/vendor/syn/src/sealed.rs | 4 + utshell-0.5.0/vendor/syn/src/span.rs | 63 + utshell-0.5.0/vendor/syn/src/spanned.rs | 118 + utshell-0.5.0/vendor/syn/src/stmt.rs | 468 + utshell-0.5.0/vendor/syn/src/thread.rs | 60 + utshell-0.5.0/vendor/syn/src/token.rs | 1138 + utshell-0.5.0/vendor/syn/src/tt.rs | 107 + utshell-0.5.0/vendor/syn/src/ty.rs | 1216 + utshell-0.5.0/vendor/syn/src/verbatim.rs | 33 + utshell-0.5.0/vendor/syn/src/whitespace.rs | 65 + utshell-0.5.0/vendor/syn/tests/common/eq.rs | 889 + utshell-0.5.0/vendor/syn/tests/common/mod.rs | 28 + .../vendor/syn/tests/common/parse.rs | 51 + utshell-0.5.0/vendor/syn/tests/debug/gen.rs | 5157 +++++ utshell-0.5.0/vendor/syn/tests/debug/mod.rs | 147 + utshell-0.5.0/vendor/syn/tests/macros/mod.rs | 93 + utshell-0.5.0/vendor/syn/tests/regression.rs | 5 + .../vendor/syn/tests/regression/issue1108.rs | 5 + .../vendor/syn/tests/regression/issue1235.rs | 32 + utshell-0.5.0/vendor/syn/tests/repo/mod.rs | 375 + .../vendor/syn/tests/repo/progress.rs | 37 + .../vendor/syn/tests/test_asyncness.rs | 43 + .../vendor/syn/tests/test_attribute.rs | 225 + .../vendor/syn/tests/test_derive_input.rs | 781 + utshell-0.5.0/vendor/syn/tests/test_expr.rs | 540 + .../vendor/syn/tests/test_generics.rs | 282 + .../vendor/syn/tests/test_grouping.rs | 53 + utshell-0.5.0/vendor/syn/tests/test_ident.rs | 85 + utshell-0.5.0/vendor/syn/tests/test_item.rs | 332 + .../vendor/syn/tests/test_iterators.rs | 70 + utshell-0.5.0/vendor/syn/tests/test_lit.rs | 273 + utshell-0.5.0/vendor/syn/tests/test_meta.rs | 154 + .../vendor/syn/tests/test_parse_buffer.rs | 92 + .../vendor/syn/tests/test_parse_quote.rs | 164 + .../vendor/syn/tests/test_parse_stream.rs | 14 + utshell-0.5.0/vendor/syn/tests/test_pat.rs | 152 + utshell-0.5.0/vendor/syn/tests/test_path.rs | 130 + .../vendor/syn/tests/test_precedence.rs | 548 + .../vendor/syn/tests/test_receiver.rs | 321 + .../vendor/syn/tests/test_round_trip.rs | 239 + .../vendor/syn/tests/test_shebang.rs | 67 + .../vendor/syn/tests/test_should_parse.rs | 45 + utshell-0.5.0/vendor/syn/tests/test_size.rs | 36 + utshell-0.5.0/vendor/syn/tests/test_stmt.rs | 322 + .../vendor/syn/tests/test_token_trees.rs | 32 + utshell-0.5.0/vendor/syn/tests/test_ty.rs | 397 + .../vendor/syn/tests/test_visibility.rs | 144 + utshell-0.5.0/vendor/syn/tests/zzz_stable.rs | 33 + .../thiserror-impl/.cargo-checksum.json | 1 + .../vendor/thiserror-impl/Cargo.toml | 36 + .../vendor/thiserror-impl/LICENSE-APACHE | 176 + .../vendor/thiserror-impl/LICENSE-MIT | 23 + .../vendor/thiserror-impl/src/ast.rs | 161 + .../vendor/thiserror-impl/src/attr.rs | 236 + .../vendor/thiserror-impl/src/expand.rs | 562 + .../vendor/thiserror-impl/src/fmt.rs | 173 + .../vendor/thiserror-impl/src/generics.rs | 83 + .../vendor/thiserror-impl/src/lib.rs | 36 + .../vendor/thiserror-impl/src/prop.rs | 147 + .../vendor/thiserror-impl/src/span.rs | 15 + .../vendor/thiserror-impl/src/valid.rs | 237 + .../vendor/thiserror/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/thiserror/Cargo.toml | 48 + utshell-0.5.0/vendor/thiserror/LICENSE-APACHE | 176 + utshell-0.5.0/vendor/thiserror/LICENSE-MIT | 23 + utshell-0.5.0/vendor/thiserror/README.md | 222 + utshell-0.5.0/vendor/thiserror/build.rs | 119 + utshell-0.5.0/vendor/thiserror/build/probe.rs | 32 + .../vendor/thiserror/rust-toolchain.toml | 2 + utshell-0.5.0/vendor/thiserror/src/aserror.rs | 50 + utshell-0.5.0/vendor/thiserror/src/display.rs | 40 + utshell-0.5.0/vendor/thiserror/src/lib.rs | 260 + utshell-0.5.0/vendor/thiserror/src/provide.rs | 20 + .../vendor/thiserror/tests/compiletest.rs | 7 + .../vendor/thiserror/tests/test_backtrace.rs | 274 + .../vendor/thiserror/tests/test_deprecated.rs | 10 + .../vendor/thiserror/tests/test_display.rs | 358 + .../vendor/thiserror/tests/test_error.rs | 56 + .../vendor/thiserror/tests/test_expr.rs | 88 + .../vendor/thiserror/tests/test_from.rs | 64 + .../vendor/thiserror/tests/test_generics.rs | 161 + .../vendor/thiserror/tests/test_lints.rs | 18 + .../vendor/thiserror/tests/test_option.rs | 105 + .../vendor/thiserror/tests/test_path.rs | 37 + .../vendor/thiserror/tests/test_source.rs | 65 + .../thiserror/tests/test_transparent.rs | 78 + .../thiserror/tests/ui/bad-field-attr.rs | 7 + .../thiserror/tests/ui/bad-field-attr.stderr | 5 + .../thiserror/tests/ui/concat-display.rs | 15 + .../thiserror/tests/ui/concat-display.stderr | 10 + .../tests/ui/duplicate-enum-source.rs | 13 + .../tests/ui/duplicate-enum-source.stderr | 5 + .../thiserror/tests/ui/duplicate-fmt.rs | 8 + .../thiserror/tests/ui/duplicate-fmt.stderr | 5 + .../tests/ui/duplicate-struct-source.rs | 11 + .../tests/ui/duplicate-struct-source.stderr | 5 + .../tests/ui/duplicate-transparent.rs | 8 + .../tests/ui/duplicate-transparent.stderr | 5 + .../tests/ui/fallback-impl-with-display.rs | 14 + .../ui/fallback-impl-with-display.stderr | 16 + .../tests/ui/from-backtrace-backtrace.rs | 15 + .../tests/ui/from-backtrace-backtrace.stderr | 5 + .../thiserror/tests/ui/from-not-source.rs | 11 + .../thiserror/tests/ui/from-not-source.stderr | 5 + .../tests/ui/invalid-input-impl-anyway.rs | 11 + .../tests/ui/invalid-input-impl-anyway.stderr | 5 + .../vendor/thiserror/tests/ui/lifetime.rs | 24 + .../vendor/thiserror/tests/ui/lifetime.stderr | 11 + .../thiserror/tests/ui/missing-display.rs | 9 + .../thiserror/tests/ui/missing-display.stderr | 13 + .../vendor/thiserror/tests/ui/missing-fmt.rs | 10 + .../thiserror/tests/ui/missing-fmt.stderr | 5 + .../vendor/thiserror/tests/ui/no-display.rs | 12 + .../thiserror/tests/ui/no-display.stderr | 20 + .../tests/ui/source-enum-not-error.rs | 12 + .../tests/ui/source-enum-not-error.stderr | 22 + .../ui/source-enum-unnamed-field-not-error.rs | 12 + ...source-enum-unnamed-field-not-error.stderr | 22 + .../tests/ui/source-struct-not-error.rs | 12 + .../tests/ui/source-struct-not-error.stderr | 20 + .../source-struct-unnamed-field-not-error.rs | 10 + ...urce-struct-unnamed-field-not-error.stderr | 20 + .../thiserror/tests/ui/transparent-display.rs | 8 + .../tests/ui/transparent-display.stderr | 5 + .../tests/ui/transparent-enum-many.rs | 9 + .../tests/ui/transparent-enum-many.stderr | 6 + .../tests/ui/transparent-enum-not-error.rs | 9 + .../ui/transparent-enum-not-error.stderr | 20 + .../tests/ui/transparent-enum-source.rs | 9 + .../tests/ui/transparent-enum-source.stderr | 5 + ...ransparent-enum-unnamed-field-not-error.rs | 9 + ...parent-enum-unnamed-field-not-error.stderr | 20 + .../tests/ui/transparent-struct-many.rs | 10 + .../tests/ui/transparent-struct-many.stderr | 5 + .../tests/ui/transparent-struct-not-error.rs | 9 + .../ui/transparent-struct-not-error.stderr | 18 + .../tests/ui/transparent-struct-source.rs | 7 + .../tests/ui/transparent-struct-source.stderr | 5 + ...nsparent-struct-unnamed-field-not-error.rs | 7 + ...rent-struct-unnamed-field-not-error.stderr | 18 + .../tests/ui/unexpected-field-fmt.rs | 11 + .../tests/ui/unexpected-field-fmt.stderr | 5 + .../tests/ui/unexpected-struct-source.rs | 7 + .../tests/ui/unexpected-struct-source.stderr | 5 + .../vendor/thiserror/tests/ui/union.rs | 9 + .../vendor/thiserror/tests/ui/union.stderr | 8 + .../vendor/tinystr/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/tinystr/Cargo.toml | 120 + utshell-0.5.0/vendor/tinystr/LICENSE | 51 + utshell-0.5.0/vendor/tinystr/README.md | 53 + .../vendor/tinystr/benches/common/mod.rs | 79 + .../vendor/tinystr/benches/construct.rs | 89 + .../vendor/tinystr/benches/overview.rs | 165 + utshell-0.5.0/vendor/tinystr/benches/read.rs | 34 + utshell-0.5.0/vendor/tinystr/benches/serde.rs | 37 + utshell-0.5.0/vendor/tinystr/src/ascii.rs | 982 + utshell-0.5.0/vendor/tinystr/src/asciibyte.rs | 145 + utshell-0.5.0/vendor/tinystr/src/databake.rs | 21 + utshell-0.5.0/vendor/tinystr/src/error.rs | 19 + utshell-0.5.0/vendor/tinystr/src/int_ops.rs | 315 + utshell-0.5.0/vendor/tinystr/src/lib.rs | 116 + utshell-0.5.0/vendor/tinystr/src/macros.rs | 32 + utshell-0.5.0/vendor/tinystr/src/serde.rs | 91 + utshell-0.5.0/vendor/tinystr/src/ule.rs | 76 + utshell-0.5.0/vendor/tinystr/tests/serde.rs | 39 + .../vendor/type-map/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/type-map/Cargo.toml | 24 + utshell-0.5.0/vendor/type-map/README.md | 11 + utshell-0.5.0/vendor/type-map/src/lib.rs | 349 + .../unic-langid-impl/.cargo-checksum.json | 1 + .../vendor/unic-langid-impl/Cargo.lock | 587 + .../vendor/unic-langid-impl/Cargo.toml | 88 + .../vendor/unic-langid-impl/LICENSE-APACHE | 201 + .../vendor/unic-langid-impl/LICENSE-MIT | 23 + .../vendor/unic-langid-impl/README.md | 1 + .../unic-langid-impl/benches/canonicalize.rs | 50 + .../vendor/unic-langid-impl/benches/langid.rs | 84 + .../benches/likely_subtags.rs | 88 + .../vendor/unic-langid-impl/benches/parser.rs | 82 + .../data/cldr-misc-full/README.md | 29 + .../src/bin/generate_layout.rs | 147 + .../src/bin/generate_likelysubtags.rs | 201 + .../vendor/unic-langid-impl/src/errors.rs | 29 + .../unic-langid-impl/src/layout_table.rs | 12 + .../vendor/unic-langid-impl/src/lib.rs | 530 + .../unic-langid-impl/src/likelysubtags/mod.rs | 136 + .../src/likelysubtags/tables.rs | 10695 +++++++++ .../unic-langid-impl/src/parser/errors.rs | 20 + .../vendor/unic-langid-impl/src/parser/mod.rs | 83 + .../vendor/unic-langid-impl/src/serde.rs | 60 + .../unic-langid-impl/src/subtags/language.rs | 108 + .../unic-langid-impl/src/subtags/mod.rs | 9 + .../unic-langid-impl/src/subtags/region.rs | 74 + .../unic-langid-impl/src/subtags/script.rs | 62 + .../unic-langid-impl/src/subtags/variant.rs | 78 + .../tests/canonicalize_test.rs | 13 + .../vendor/unic-langid-impl/tests/fixtures.rs | 75 + .../tests/language_identifier_test.rs | 202 + .../unic-langid-impl/tests/likelysubtags.rs | 113 + .../vendor/unic-langid/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/unic-langid/Cargo.toml | 46 + .../vendor/unic-langid/LICENSE-APACHE | 201 + utshell-0.5.0/vendor/unic-langid/LICENSE-MIT | 23 + utshell-0.5.0/vendor/unic-langid/README.md | 70 + utshell-0.5.0/vendor/unic-langid/src/lib.rs | 136 + .../vendor/unic-langid/tests/langid.rs | 72 + .../vendor/unicode-ident/.cargo-checksum.json | 1 + utshell-0.5.0/vendor/unicode-ident/Cargo.toml | 63 + .../vendor/unicode-ident/LICENSE-APACHE | 176 + .../vendor/unicode-ident/LICENSE-MIT | 23 + .../vendor/unicode-ident/LICENSE-UNICODE | 46 + utshell-0.5.0/vendor/unicode-ident/README.md | 283 + .../vendor/unicode-ident/benches/xid.rs | 124 + utshell-0.5.0/vendor/unicode-ident/src/lib.rs | 269 + .../vendor/unicode-ident/src/tables.rs | 651 + .../vendor/unicode-ident/tests/compare.rs | 67 + .../vendor/unicode-ident/tests/fst/mod.rs | 11 + .../unicode-ident/tests/fst/xid_continue.fst | Bin 0 -> 73249 bytes .../unicode-ident/tests/fst/xid_start.fst | Bin 0 -> 65487 bytes .../vendor/unicode-ident/tests/roaring/mod.rs | 21 + .../vendor/unicode-ident/tests/static_size.rs | 95 + .../vendor/unicode-ident/tests/tables/mod.rs | 7 + .../unicode-ident/tests/tables/tables.rs | 347 + .../vendor/unicode-ident/tests/trie/mod.rs | 7 + .../vendor/unicode-ident/tests/trie/trie.rs | 445 + 2017 files changed, 606759 insertions(+) create mode 100644 utshell-0.5.0/COPYING create mode 100644 utshell-0.5.0/Cargo.toml create mode 100644 utshell-0.5.0/Makefile create mode 100644 utshell-0.5.0/README.md create mode 100644 utshell-0.5.0/README.zh_CN.md create mode 100644 utshell-0.5.0/build.rs create mode 100644 utshell-0.5.0/config/.utshell_logout create mode 100644 utshell-0.5.0/config/.utshell_profile create mode 100644 utshell-0.5.0/config/.utshellrc create mode 100644 utshell-0.5.0/config/utshellrc create mode 100644 utshell-0.5.0/lib/Makefile create mode 100644 utshell-0.5.0/lib/glob/Makefile create mode 100644 utshell-0.5.0/lib/glob/Makefile.in create mode 100644 utshell-0.5.0/lib/glob/collsyms.h create mode 100644 utshell-0.5.0/lib/glob/doc/Makefile create mode 100644 utshell-0.5.0/lib/glob/doc/glob.texi create mode 100644 utshell-0.5.0/lib/glob/glob.c create mode 100644 utshell-0.5.0/lib/glob/glob.h create mode 100644 utshell-0.5.0/lib/glob/glob_loop.c create mode 100644 utshell-0.5.0/lib/glob/gm_loop.c create mode 100644 utshell-0.5.0/lib/glob/gmisc.c create mode 100644 utshell-0.5.0/lib/glob/ndir.h create mode 100644 utshell-0.5.0/lib/glob/sm_loop.c create mode 100644 utshell-0.5.0/lib/glob/smatch.c create mode 100644 utshell-0.5.0/lib/glob/strmatch.c create mode 100644 utshell-0.5.0/lib/glob/strmatch.h create mode 100644 utshell-0.5.0/lib/glob/xmbsrtowcs.c create mode 100644 utshell-0.5.0/lib/include/alias.h create mode 100644 utshell-0.5.0/lib/include/ansi_stdlib.h create mode 100644 utshell-0.5.0/lib/include/array.h create mode 100644 utshell-0.5.0/lib/include/arrayfunc.h create mode 100644 utshell-0.5.0/lib/include/assoc.h create mode 100644 utshell-0.5.0/lib/include/bashansi.h create mode 100644 utshell-0.5.0/lib/include/bashintl.h create mode 100644 utshell-0.5.0/lib/include/bashjmp.h create mode 100644 utshell-0.5.0/lib/include/bashtypes.h create mode 100644 utshell-0.5.0/lib/include/builtins.h create mode 100644 utshell-0.5.0/lib/include/chartypes.h create mode 100644 utshell-0.5.0/lib/include/command.h create mode 100644 utshell-0.5.0/lib/include/config-bot.h create mode 100644 utshell-0.5.0/lib/include/config-top.h create mode 100644 utshell-0.5.0/lib/include/config.h create mode 100644 utshell-0.5.0/lib/include/conftypes.h create mode 100644 utshell-0.5.0/lib/include/dispose_cmd.h create mode 100644 utshell-0.5.0/lib/include/error.h create mode 100644 utshell-0.5.0/lib/include/externs.h create mode 100644 utshell-0.5.0/lib/include/filecntl.h create mode 100644 utshell-0.5.0/lib/include/general.h create mode 100644 utshell-0.5.0/lib/include/gettext.h create mode 100644 utshell-0.5.0/lib/include/hashlib.h create mode 100644 utshell-0.5.0/lib/include/make_cmd.h create mode 100644 utshell-0.5.0/lib/include/maxpath.h create mode 100644 utshell-0.5.0/lib/include/memalloc.h create mode 100644 utshell-0.5.0/lib/include/ocache.h create mode 100644 utshell-0.5.0/lib/include/pathnames.h create mode 100644 utshell-0.5.0/lib/include/posixdir.h create mode 100644 utshell-0.5.0/lib/include/posixjmp.h create mode 100644 utshell-0.5.0/lib/include/posixselect.h create mode 100644 utshell-0.5.0/lib/include/posixstat.h create mode 100644 utshell-0.5.0/lib/include/posixtime.h create mode 100644 utshell-0.5.0/lib/include/posixwait.h create mode 100644 utshell-0.5.0/lib/include/quit.h create mode 100644 utshell-0.5.0/lib/include/shell.h create mode 100644 utshell-0.5.0/lib/include/shmbchar.h create mode 100644 utshell-0.5.0/lib/include/shmbutil.h create mode 100644 utshell-0.5.0/lib/include/shtty.h create mode 100644 utshell-0.5.0/lib/include/sig.h create mode 100644 utshell-0.5.0/lib/include/stat-time.h create mode 100644 utshell-0.5.0/lib/include/stdc.h create mode 100644 utshell-0.5.0/lib/include/strmatch.h create mode 100644 utshell-0.5.0/lib/include/subst.h create mode 100644 utshell-0.5.0/lib/include/syntax.h create mode 100644 utshell-0.5.0/lib/include/systimes.h create mode 100644 utshell-0.5.0/lib/include/tilde.h create mode 100644 utshell-0.5.0/lib/include/trap.h create mode 100644 utshell-0.5.0/lib/include/typemax.h create mode 100644 utshell-0.5.0/lib/include/unionwait.h create mode 100644 utshell-0.5.0/lib/include/unwind_prot.h create mode 100644 utshell-0.5.0/lib/include/variables.h create mode 100644 utshell-0.5.0/lib/include/xmalloc.h create mode 100644 utshell-0.5.0/lib/intl/ChangeLog create mode 100644 utshell-0.5.0/lib/intl/Makefile create mode 100644 utshell-0.5.0/lib/intl/Makefile.in create mode 100644 utshell-0.5.0/lib/intl/VERSION create mode 100644 utshell-0.5.0/lib/intl/bindtextdom.c create mode 100644 utshell-0.5.0/lib/intl/config.charset create mode 100644 utshell-0.5.0/lib/intl/dcgettext.c create mode 100644 utshell-0.5.0/lib/intl/dcigettext.c create mode 100644 utshell-0.5.0/lib/intl/dcngettext.c create mode 100644 utshell-0.5.0/lib/intl/dgettext.c create mode 100644 utshell-0.5.0/lib/intl/dngettext.c create mode 100644 utshell-0.5.0/lib/intl/eval-plural.h create mode 100644 utshell-0.5.0/lib/intl/explodename.c create mode 100644 utshell-0.5.0/lib/intl/finddomain.c create mode 100644 utshell-0.5.0/lib/intl/gettext.c create mode 100644 utshell-0.5.0/lib/intl/gettextP.h create mode 100644 utshell-0.5.0/lib/intl/gmo.h create mode 100644 utshell-0.5.0/lib/intl/hash-string.h create mode 100644 utshell-0.5.0/lib/intl/intl-compat.c create mode 100644 utshell-0.5.0/lib/intl/l10nflist.c create mode 100644 utshell-0.5.0/lib/intl/libgnuintl.h.in create mode 100644 utshell-0.5.0/lib/intl/loadinfo.h create mode 100644 utshell-0.5.0/lib/intl/loadmsgcat.c create mode 100644 utshell-0.5.0/lib/intl/localcharset.c create mode 100644 utshell-0.5.0/lib/intl/localcharset.h create mode 100644 utshell-0.5.0/lib/intl/locale.alias create mode 100644 utshell-0.5.0/lib/intl/localealias.c create mode 100644 utshell-0.5.0/lib/intl/localename.c create mode 100644 utshell-0.5.0/lib/intl/log.c create mode 100644 utshell-0.5.0/lib/intl/ngettext.c create mode 100644 utshell-0.5.0/lib/intl/os2compat.c create mode 100644 utshell-0.5.0/lib/intl/os2compat.h create mode 100644 utshell-0.5.0/lib/intl/osdep.c create mode 100644 utshell-0.5.0/lib/intl/plural-exp.c create mode 100644 utshell-0.5.0/lib/intl/plural-exp.h create mode 100644 utshell-0.5.0/lib/intl/plural.c create mode 100644 utshell-0.5.0/lib/intl/plural.y create mode 100755 utshell-0.5.0/lib/intl/ref-add.sin create mode 100755 utshell-0.5.0/lib/intl/ref-del.sin create mode 100644 utshell-0.5.0/lib/intl/relocatable.c create mode 100644 utshell-0.5.0/lib/intl/relocatable.h create mode 100644 utshell-0.5.0/lib/intl/textdomain.c create mode 100644 utshell-0.5.0/lib/malloc/Makefile create mode 100644 utshell-0.5.0/lib/malloc/Makefile.in create mode 100644 utshell-0.5.0/lib/malloc/alloca.c create mode 100644 utshell-0.5.0/lib/malloc/getpagesize.h create mode 100644 utshell-0.5.0/lib/malloc/i386-alloca.s create mode 100644 utshell-0.5.0/lib/malloc/imalloc.h create mode 100644 utshell-0.5.0/lib/malloc/malloc.c create mode 100644 utshell-0.5.0/lib/malloc/mstats.h create mode 100644 utshell-0.5.0/lib/malloc/shmalloc.h create mode 100644 utshell-0.5.0/lib/malloc/stats.c create mode 100644 utshell-0.5.0/lib/malloc/stub.c create mode 100644 utshell-0.5.0/lib/malloc/table.c create mode 100644 utshell-0.5.0/lib/malloc/table.h create mode 100644 utshell-0.5.0/lib/malloc/trace.c create mode 100644 utshell-0.5.0/lib/malloc/watch.c create mode 100644 utshell-0.5.0/lib/malloc/watch.h create mode 100644 utshell-0.5.0/lib/malloc/x386-alloca.s create mode 100755 utshell-0.5.0/lib/malloc/xleaktrace create mode 100644 utshell-0.5.0/lib/malloc/xmalloc.c create mode 100644 utshell-0.5.0/lib/r2c.c create mode 100644 utshell-0.5.0/lib/r2c.o create mode 100644 utshell-0.5.0/lib/r2c/Makefile create mode 100644 utshell-0.5.0/lib/r2c/libr2c.a create mode 100644 utshell-0.5.0/lib/r2c/r2c.c create mode 100644 utshell-0.5.0/lib/r2c/r2c.o create mode 100644 utshell-0.5.0/lib/readline/COPYING create mode 100644 utshell-0.5.0/lib/readline/ChangeLog create mode 100644 utshell-0.5.0/lib/readline/Makefile create mode 100644 utshell-0.5.0/lib/readline/Makefile.in create mode 100644 utshell-0.5.0/lib/readline/README create mode 100644 utshell-0.5.0/lib/readline/STANDALONE create mode 100644 utshell-0.5.0/lib/readline/ansi_stdlib.h create mode 100644 utshell-0.5.0/lib/readline/bind.c create mode 100644 utshell-0.5.0/lib/readline/callback.c create mode 100644 utshell-0.5.0/lib/readline/chardefs.h create mode 100644 utshell-0.5.0/lib/readline/colors.c create mode 100644 utshell-0.5.0/lib/readline/colors.h create mode 100644 utshell-0.5.0/lib/readline/compat.c create mode 100644 utshell-0.5.0/lib/readline/complete.c create mode 100644 utshell-0.5.0/lib/readline/display.c create mode 100644 utshell-0.5.0/lib/readline/doc/fdl.texi create mode 100644 utshell-0.5.0/lib/readline/doc/history.texi create mode 100644 utshell-0.5.0/lib/readline/doc/hstech.texi create mode 100644 utshell-0.5.0/lib/readline/doc/hsuser.texi create mode 100644 utshell-0.5.0/lib/readline/doc/rlman.texi create mode 100644 utshell-0.5.0/lib/readline/doc/rltech.texi create mode 100644 utshell-0.5.0/lib/readline/doc/rluser.texi create mode 100644 utshell-0.5.0/lib/readline/doc/rluserman.texi create mode 100644 utshell-0.5.0/lib/readline/doc/version.texi create mode 100644 utshell-0.5.0/lib/readline/emacs_keymap.c create mode 100644 utshell-0.5.0/lib/readline/examples/Inputrc create mode 100644 utshell-0.5.0/lib/readline/examples/Makefile create mode 100644 utshell-0.5.0/lib/readline/examples/excallback.c create mode 100644 utshell-0.5.0/lib/readline/examples/fileman.c create mode 100644 utshell-0.5.0/lib/readline/examples/histexamp.c create mode 100644 utshell-0.5.0/lib/readline/examples/manexamp.c create mode 100644 utshell-0.5.0/lib/readline/examples/rl-callbacktest.c create mode 100644 utshell-0.5.0/lib/readline/examples/rl.c create mode 100644 utshell-0.5.0/lib/readline/examples/rlcat.c create mode 100644 utshell-0.5.0/lib/readline/examples/rltest.c create mode 100644 utshell-0.5.0/lib/readline/funmap.c create mode 100644 utshell-0.5.0/lib/readline/histexpand.c create mode 100644 utshell-0.5.0/lib/readline/histfile.c create mode 100644 utshell-0.5.0/lib/readline/histlib.h create mode 100644 utshell-0.5.0/lib/readline/history.c create mode 100644 utshell-0.5.0/lib/readline/history.h create mode 100644 utshell-0.5.0/lib/readline/histsearch.c create mode 100644 utshell-0.5.0/lib/readline/input.c create mode 100644 utshell-0.5.0/lib/readline/isearch.c create mode 100644 utshell-0.5.0/lib/readline/keymaps.c create mode 100644 utshell-0.5.0/lib/readline/keymaps.h create mode 100644 utshell-0.5.0/lib/readline/kill.c create mode 100644 utshell-0.5.0/lib/readline/macro.c create mode 100644 utshell-0.5.0/lib/readline/mbutil.c create mode 100644 utshell-0.5.0/lib/readline/misc.c create mode 100644 utshell-0.5.0/lib/readline/nls.c create mode 100644 utshell-0.5.0/lib/readline/parens.c create mode 100644 utshell-0.5.0/lib/readline/parse-colors.c create mode 100644 utshell-0.5.0/lib/readline/parse-colors.h create mode 100644 utshell-0.5.0/lib/readline/posixdir.h create mode 100644 utshell-0.5.0/lib/readline/posixjmp.h create mode 100644 utshell-0.5.0/lib/readline/posixselect.h create mode 100644 utshell-0.5.0/lib/readline/posixstat.h create mode 100644 utshell-0.5.0/lib/readline/readline.c create mode 100644 utshell-0.5.0/lib/readline/readline.h create mode 100644 utshell-0.5.0/lib/readline/rlconf.h create mode 100644 utshell-0.5.0/lib/readline/rldefs.h create mode 100644 utshell-0.5.0/lib/readline/rlmbutil.h create mode 100644 utshell-0.5.0/lib/readline/rlprivate.h create mode 100644 utshell-0.5.0/lib/readline/rlshell.h create mode 100644 utshell-0.5.0/lib/readline/rlstdc.h create mode 100644 utshell-0.5.0/lib/readline/rltty.c create mode 100644 utshell-0.5.0/lib/readline/rltty.h create mode 100644 utshell-0.5.0/lib/readline/rltypedefs.h create mode 100644 utshell-0.5.0/lib/readline/rlwinsize.h create mode 100644 utshell-0.5.0/lib/readline/savestring.c create mode 100644 utshell-0.5.0/lib/readline/search.c create mode 100644 utshell-0.5.0/lib/readline/shell.c create mode 100644 utshell-0.5.0/lib/readline/signals.c create mode 100644 utshell-0.5.0/lib/readline/tcap.h create mode 100644 utshell-0.5.0/lib/readline/terminal.c create mode 100644 utshell-0.5.0/lib/readline/text.c create mode 100644 utshell-0.5.0/lib/readline/tilde.c create mode 100644 utshell-0.5.0/lib/readline/tilde.h create mode 100644 utshell-0.5.0/lib/readline/undo.c create mode 100644 utshell-0.5.0/lib/readline/util.c create mode 100644 utshell-0.5.0/lib/readline/vi_keymap.c create mode 100644 utshell-0.5.0/lib/readline/vi_mode.c create mode 100644 utshell-0.5.0/lib/readline/xfree.c create mode 100644 utshell-0.5.0/lib/readline/xmalloc.c create mode 100644 utshell-0.5.0/lib/readline/xmalloc.h create mode 100644 utshell-0.5.0/lib/sh/Makefile create mode 100644 utshell-0.5.0/lib/sh/Makefile.in create mode 100644 utshell-0.5.0/lib/sh/casemod.c create mode 100644 utshell-0.5.0/lib/sh/clktck.c create mode 100644 utshell-0.5.0/lib/sh/clock.c create mode 100644 utshell-0.5.0/lib/sh/dprintf.c create mode 100644 utshell-0.5.0/lib/sh/eaccess.c create mode 100644 utshell-0.5.0/lib/sh/fmtullong.c create mode 100644 utshell-0.5.0/lib/sh/fmtulong.c create mode 100644 utshell-0.5.0/lib/sh/fmtumax.c create mode 100644 utshell-0.5.0/lib/sh/fnxform.c create mode 100644 utshell-0.5.0/lib/sh/fpurge.c create mode 100644 utshell-0.5.0/lib/sh/getcwd.c create mode 100644 utshell-0.5.0/lib/sh/getenv.c create mode 100644 utshell-0.5.0/lib/sh/gettimeofday.c create mode 100644 utshell-0.5.0/lib/sh/inet_aton.c create mode 100644 utshell-0.5.0/lib/sh/input_avail.c create mode 100644 utshell-0.5.0/lib/sh/itos.c create mode 100644 utshell-0.5.0/lib/sh/mailstat.c create mode 100644 utshell-0.5.0/lib/sh/makepath.c create mode 100644 utshell-0.5.0/lib/sh/mbscasecmp.c create mode 100644 utshell-0.5.0/lib/sh/mbschr.c create mode 100644 utshell-0.5.0/lib/sh/mbscmp.c create mode 100644 utshell-0.5.0/lib/sh/memset.c create mode 100644 utshell-0.5.0/lib/sh/mktime.c create mode 100644 utshell-0.5.0/lib/sh/netconn.c create mode 100644 utshell-0.5.0/lib/sh/netopen.c create mode 100644 utshell-0.5.0/lib/sh/oslib.c create mode 100644 utshell-0.5.0/lib/sh/pathcanon.c create mode 100644 utshell-0.5.0/lib/sh/pathphys.c create mode 100644 utshell-0.5.0/lib/sh/random.c create mode 100644 utshell-0.5.0/lib/sh/rename.c create mode 100644 utshell-0.5.0/lib/sh/setlinebuf.c create mode 100644 utshell-0.5.0/lib/sh/shmatch.c create mode 100644 utshell-0.5.0/lib/sh/shmbchar.c create mode 100644 utshell-0.5.0/lib/sh/shquote.c create mode 100644 utshell-0.5.0/lib/sh/shtty.c create mode 100644 utshell-0.5.0/lib/sh/snprintf.c create mode 100644 utshell-0.5.0/lib/sh/spell.c create mode 100644 utshell-0.5.0/lib/sh/strcasecmp.c create mode 100644 utshell-0.5.0/lib/sh/strcasestr.c create mode 100644 utshell-0.5.0/lib/sh/strchrnul.c create mode 100644 utshell-0.5.0/lib/sh/strdup.c create mode 100644 utshell-0.5.0/lib/sh/strerror.c create mode 100644 utshell-0.5.0/lib/sh/strftime.c create mode 100644 utshell-0.5.0/lib/sh/stringlist.c create mode 100644 utshell-0.5.0/lib/sh/stringvec.c create mode 100644 utshell-0.5.0/lib/sh/strnlen.c create mode 100644 utshell-0.5.0/lib/sh/strpbrk.c create mode 100644 utshell-0.5.0/lib/sh/strstr.c create mode 100644 utshell-0.5.0/lib/sh/strtod.c create mode 100644 utshell-0.5.0/lib/sh/strtoimax.c create mode 100644 utshell-0.5.0/lib/sh/strtol.c create mode 100644 utshell-0.5.0/lib/sh/strtoll.c create mode 100644 utshell-0.5.0/lib/sh/strtoul.c create mode 100644 utshell-0.5.0/lib/sh/strtoull.c create mode 100644 utshell-0.5.0/lib/sh/strtoumax.c create mode 100644 utshell-0.5.0/lib/sh/strtrans.c create mode 100644 utshell-0.5.0/lib/sh/times.c create mode 100644 utshell-0.5.0/lib/sh/timeval.c create mode 100644 utshell-0.5.0/lib/sh/tmpfile.c create mode 100644 utshell-0.5.0/lib/sh/uconvert.c create mode 100644 utshell-0.5.0/lib/sh/ufuncs.c create mode 100644 utshell-0.5.0/lib/sh/unicode.c create mode 100644 utshell-0.5.0/lib/sh/utf8.c create mode 100644 utshell-0.5.0/lib/sh/vprint.c create mode 100644 utshell-0.5.0/lib/sh/wcsdup.c create mode 100644 utshell-0.5.0/lib/sh/wcsnwidth.c create mode 100644 utshell-0.5.0/lib/sh/wcswidth.c create mode 100644 utshell-0.5.0/lib/sh/winsize.c create mode 100644 utshell-0.5.0/lib/sh/zcatfd.c create mode 100644 utshell-0.5.0/lib/sh/zgetline.c create mode 100644 utshell-0.5.0/lib/sh/zmapfd.c create mode 100644 utshell-0.5.0/lib/sh/zread.c create mode 100644 utshell-0.5.0/lib/sh/zwrite.c create mode 100755 utshell-0.5.0/lib/support/config.sub create mode 100644 utshell-0.5.0/lib/termcap/Makefile create mode 100644 utshell-0.5.0/lib/termcap/Makefile.in create mode 100644 utshell-0.5.0/lib/termcap/ltcap.h create mode 100644 utshell-0.5.0/lib/termcap/termcap.c create mode 100644 utshell-0.5.0/lib/termcap/termcap.h create mode 100755 utshell-0.5.0/lib/termcap/test/a create mode 100644 utshell-0.5.0/lib/termcap/test/libglob.a create mode 100644 utshell-0.5.0/lib/termcap/test/libtermcap.a create mode 100644 utshell-0.5.0/lib/termcap/test/main.c create mode 100644 utshell-0.5.0/lib/termcap/tparam.c create mode 100644 utshell-0.5.0/lib/termcap/version.c create mode 100644 utshell-0.5.0/lib/test/libtest.a create mode 100644 utshell-0.5.0/lib/test/libtest1.a create mode 100644 utshell-0.5.0/lib/test/test.c create mode 100644 utshell-0.5.0/lib/test/test.o create mode 100644 utshell-0.5.0/lib/test/test1.c create mode 100644 utshell-0.5.0/lib/test/test1.o create mode 100644 utshell-0.5.0/lib/tilde/Makefile create mode 100644 utshell-0.5.0/lib/tilde/Makefile.in create mode 100644 utshell-0.5.0/lib/tilde/README create mode 100644 utshell-0.5.0/lib/tilde/shell.c create mode 100644 utshell-0.5.0/lib/tilde/tilde.c create mode 100644 utshell-0.5.0/lib/tilde/tilde.h create mode 100644 utshell-0.5.0/resources/en-US/message.ftl create mode 100644 utshell-0.5.0/resources/zh-CN/message.ftl create mode 100644 utshell-0.5.0/resources/zh-HK/message.ftl create mode 100644 utshell-0.5.0/src/1.sh create mode 100644 utshell-0.5.0/src/1.txt create mode 100644 utshell-0.5.0/src/README.txt create mode 100644 utshell-0.5.0/src/alias.rs create mode 100644 utshell-0.5.0/src/array.rs create mode 100644 utshell-0.5.0/src/arrayfunc.rs create mode 100644 utshell-0.5.0/src/assoc.rs create mode 100644 utshell-0.5.0/src/bashhist.rs create mode 100644 utshell-0.5.0/src/bashline.rs create mode 100644 utshell-0.5.0/src/bin/utshell.rs create mode 100644 utshell-0.5.0/src/bin/utshellversion.rs create mode 100644 utshell-0.5.0/src/brace.rs create mode 100644 utshell-0.5.0/src/bracecomp.rs create mode 100644 utshell-0.5.0/src/builtins/alias.rs create mode 100644 utshell-0.5.0/src/builtins/bashgetopt.rs create mode 100644 utshell-0.5.0/src/builtins/bind.rs create mode 100644 utshell-0.5.0/src/builtins/break_1.rs create mode 100644 utshell-0.5.0/src/builtins/builtin.rs create mode 100644 utshell-0.5.0/src/builtins/builtins.rs create mode 100644 utshell-0.5.0/src/builtins/caller.rs create mode 100644 utshell-0.5.0/src/builtins/cd.rs create mode 100644 utshell-0.5.0/src/builtins/cmd.rs create mode 100644 utshell-0.5.0/src/builtins/colon.rs create mode 100644 utshell-0.5.0/src/builtins/command.rs create mode 100644 utshell-0.5.0/src/builtins/common.rs create mode 100644 utshell-0.5.0/src/builtins/complete.rs create mode 100644 utshell-0.5.0/src/builtins/declare.rs create mode 100644 utshell-0.5.0/src/builtins/echo.rs create mode 100644 utshell-0.5.0/src/builtins/enable.rs create mode 100644 utshell-0.5.0/src/builtins/eval.rs create mode 100644 utshell-0.5.0/src/builtins/evalfile.rs create mode 100644 utshell-0.5.0/src/builtins/evalstring.rs create mode 100644 utshell-0.5.0/src/builtins/exec.rs create mode 100644 utshell-0.5.0/src/builtins/exec_cmd.rs create mode 100644 utshell-0.5.0/src/builtins/exit.rs create mode 100644 utshell-0.5.0/src/builtins/fc.rs create mode 100644 utshell-0.5.0/src/builtins/fg_bg.rs create mode 100644 utshell-0.5.0/src/builtins/getopt.rs create mode 100644 utshell-0.5.0/src/builtins/getopts.rs create mode 100644 utshell-0.5.0/src/builtins/hash.rs create mode 100644 utshell-0.5.0/src/builtins/help.rs create mode 100644 utshell-0.5.0/src/builtins/history.rs create mode 100644 utshell-0.5.0/src/builtins/jobs.rs create mode 100644 utshell-0.5.0/src/builtins/kill.rs create mode 100644 utshell-0.5.0/src/builtins/let_1.rs create mode 100644 utshell-0.5.0/src/builtins/mapfile.rs create mode 100644 utshell-0.5.0/src/builtins/printf.rs create mode 100644 utshell-0.5.0/src/builtins/pushd.rs create mode 100644 utshell-0.5.0/src/builtins/read.rs create mode 100644 utshell-0.5.0/src/builtins/return_1.rs create mode 100644 utshell-0.5.0/src/builtins/set.rs create mode 100644 utshell-0.5.0/src/builtins/setattr.rs create mode 100644 utshell-0.5.0/src/builtins/shift.rs create mode 100644 utshell-0.5.0/src/builtins/shopt.rs create mode 100644 utshell-0.5.0/src/builtins/signal.rs create mode 100644 utshell-0.5.0/src/builtins/source.rs create mode 100644 utshell-0.5.0/src/builtins/suspend.rs create mode 100644 utshell-0.5.0/src/builtins/test.rs create mode 100644 utshell-0.5.0/src/builtins/times.rs create mode 100644 utshell-0.5.0/src/builtins/trap.rs create mode 100644 utshell-0.5.0/src/builtins/type_1.rs create mode 100644 utshell-0.5.0/src/builtins/ulimit.rs create mode 100644 utshell-0.5.0/src/builtins/umask.rs create mode 100644 utshell-0.5.0/src/builtins/wait.rs create mode 100644 utshell-0.5.0/src/copycmd.rs create mode 100644 utshell-0.5.0/src/dispose_cmd.rs create mode 100644 utshell-0.5.0/src/error.rs create mode 100644 utshell-0.5.0/src/eval.rs create mode 100644 utshell-0.5.0/src/execute_cmd.rs create mode 100644 utshell-0.5.0/src/expr.rs create mode 100644 utshell-0.5.0/src/findcmd.rs create mode 100644 utshell-0.5.0/src/flags.rs create mode 100644 utshell-0.5.0/src/general.rs create mode 100644 utshell-0.5.0/src/hashcmd.rs create mode 100644 utshell-0.5.0/src/hashlib.rs create mode 100644 utshell-0.5.0/src/input.rs create mode 100644 utshell-0.5.0/src/jobs.rs create mode 100644 utshell-0.5.0/src/lib.rs create mode 100644 utshell-0.5.0/src/list.rs create mode 100644 utshell-0.5.0/src/local.rs create mode 100644 utshell-0.5.0/src/mailcheck.rs create mode 100644 utshell-0.5.0/src/make_cmd.rs create mode 100644 utshell-0.5.0/src/nojobs.rs create mode 100644 utshell-0.5.0/src/pathexp.rs create mode 100644 utshell-0.5.0/src/pcomplete.rs create mode 100644 utshell-0.5.0/src/pcomplib.rs create mode 100644 utshell-0.5.0/src/print_cmd.rs create mode 100644 utshell-0.5.0/src/readline.rs create mode 100644 utshell-0.5.0/src/redir.rs create mode 100644 utshell-0.5.0/src/sig.rs create mode 100644 utshell-0.5.0/src/src_common.rs create mode 100644 utshell-0.5.0/src/stringlib.rs create mode 100644 utshell-0.5.0/src/subst.rs create mode 100644 utshell-0.5.0/src/syntax.rs create mode 100644 utshell-0.5.0/src/test.rs create mode 100644 utshell-0.5.0/src/trap.rs create mode 100644 utshell-0.5.0/src/unwind_prot.rs create mode 100644 utshell-0.5.0/src/utshell.rs create mode 100644 utshell-0.5.0/src/variables.rs create mode 100644 utshell-0.5.0/src/version.rs create mode 100644 utshell-0.5.0/src/y_tab.rs create mode 100644 utshell-0.5.0/variable/Makefile create mode 100644 utshell-0.5.0/variable/alias.h create mode 100644 utshell-0.5.0/variable/array.c create mode 100644 utshell-0.5.0/variable/array.h create mode 100644 utshell-0.5.0/variable/arrayfunc.h create mode 100644 utshell-0.5.0/variable/assoc.h create mode 100644 utshell-0.5.0/variable/bashansi.h create mode 100644 utshell-0.5.0/variable/bashgetopt.h create mode 100644 utshell-0.5.0/variable/bashhist.h create mode 100644 utshell-0.5.0/variable/bashintl.h create mode 100644 utshell-0.5.0/variable/bashjmp.h create mode 100644 utshell-0.5.0/variable/bashline.h create mode 100644 utshell-0.5.0/variable/bashtypes.h create mode 100644 utshell-0.5.0/variable/builtext.h create mode 100644 utshell-0.5.0/variable/builtins.h create mode 100644 utshell-0.5.0/variable/chardefs.h create mode 100644 utshell-0.5.0/variable/chartypes.h create mode 100644 utshell-0.5.0/variable/command.h create mode 100644 utshell-0.5.0/variable/common.c create mode 100644 utshell-0.5.0/variable/common.h create mode 100644 utshell-0.5.0/variable/config-bot.h create mode 100644 utshell-0.5.0/variable/config-top.h create mode 100644 utshell-0.5.0/variable/config.h create mode 100644 utshell-0.5.0/variable/conftypes.h create mode 100644 utshell-0.5.0/variable/dispose_cmd.h create mode 100644 utshell-0.5.0/variable/error.c create mode 100644 utshell-0.5.0/variable/error.h create mode 100644 utshell-0.5.0/variable/execute_cmd.h create mode 100644 utshell-0.5.0/variable/externs.h create mode 100644 utshell-0.5.0/variable/flags.h create mode 100644 utshell-0.5.0/variable/general.h create mode 100644 utshell-0.5.0/variable/gettext.h create mode 100644 utshell-0.5.0/variable/glob.h create mode 100644 utshell-0.5.0/variable/hashlib.c create mode 100644 utshell-0.5.0/variable/hashlib.h create mode 100644 utshell-0.5.0/variable/history.h create mode 100644 utshell-0.5.0/variable/input.h create mode 100644 utshell-0.5.0/variable/jobs.h create mode 100644 utshell-0.5.0/variable/keymaps.h create mode 100644 utshell-0.5.0/variable/make_cmd.h create mode 100644 utshell-0.5.0/variable/maxpath.h create mode 100644 utshell-0.5.0/variable/ocache.h create mode 100644 utshell-0.5.0/variable/parser.h create mode 100644 utshell-0.5.0/variable/pathexp.h create mode 100644 utshell-0.5.0/variable/pathnames.h create mode 100644 utshell-0.5.0/variable/pcomplete.c create mode 100644 utshell-0.5.0/variable/pcomplete.h create mode 100644 utshell-0.5.0/variable/posixjmp.h create mode 100644 utshell-0.5.0/variable/posixstat.h create mode 100644 utshell-0.5.0/variable/posixtime.h create mode 100644 utshell-0.5.0/variable/posixwait.h create mode 100644 utshell-0.5.0/variable/print_cmd.c create mode 100644 utshell-0.5.0/variable/printf.c create mode 100644 utshell-0.5.0/variable/quit.h create mode 100644 utshell-0.5.0/variable/readline.h create mode 100644 utshell-0.5.0/variable/rlconf.h create mode 100644 utshell-0.5.0/variable/rlstdc.h create mode 100644 utshell-0.5.0/variable/rltypedefs.h create mode 100644 utshell-0.5.0/variable/shell.h create mode 100644 utshell-0.5.0/variable/shmbchar.h create mode 100644 utshell-0.5.0/variable/shmbutil.h create mode 100644 utshell-0.5.0/variable/sig.h create mode 100644 utshell-0.5.0/variable/siglist.h create mode 100644 utshell-0.5.0/variable/stdc.h create mode 100644 utshell-0.5.0/variable/strmatch.h create mode 100644 utshell-0.5.0/variable/subst.h create mode 100644 utshell-0.5.0/variable/syntax.h create mode 100644 utshell-0.5.0/variable/tilde.h create mode 100644 utshell-0.5.0/variable/trap.h create mode 100644 utshell-0.5.0/variable/unwind_prot.h create mode 100644 utshell-0.5.0/variable/variables.h create mode 100644 utshell-0.5.0/variable/xmalloc.h create mode 100644 utshell-0.5.0/vendor/async-trait/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/async-trait/Cargo.toml create mode 100644 utshell-0.5.0/vendor/async-trait/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/async-trait/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/async-trait/README.md create mode 100644 utshell-0.5.0/vendor/async-trait/build.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/args.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/bound.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/expand.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/lib.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/lifetime.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/parse.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/receiver.rs create mode 100644 utshell-0.5.0/vendor/async-trait/src/verbatim.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/compiletest.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/executor/mod.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/test.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/must-use.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/must-use.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/self-span.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/self-span.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.stderr create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.rs create mode 100644 utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.stderr create mode 100644 utshell-0.5.0/vendor/autocfg/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/autocfg/Cargo.lock create mode 100644 utshell-0.5.0/vendor/autocfg/Cargo.toml create mode 100644 utshell-0.5.0/vendor/autocfg/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/autocfg/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/autocfg/README.md create mode 100644 utshell-0.5.0/vendor/autocfg/examples/integers.rs create mode 100644 utshell-0.5.0/vendor/autocfg/examples/paths.rs create mode 100644 utshell-0.5.0/vendor/autocfg/examples/traits.rs create mode 100644 utshell-0.5.0/vendor/autocfg/examples/versions.rs create mode 100644 utshell-0.5.0/vendor/autocfg/src/error.rs create mode 100644 utshell-0.5.0/vendor/autocfg/src/lib.rs create mode 100644 utshell-0.5.0/vendor/autocfg/src/tests.rs create mode 100644 utshell-0.5.0/vendor/autocfg/src/version.rs create mode 100644 utshell-0.5.0/vendor/autocfg/tests/rustflags.rs create mode 100644 utshell-0.5.0/vendor/bitflags/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/bitflags/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/bitflags/CODE_OF_CONDUCT.md create mode 100644 utshell-0.5.0/vendor/bitflags/Cargo.toml create mode 100644 utshell-0.5.0/vendor/bitflags/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/bitflags/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/bitflags/README.md create mode 100644 utshell-0.5.0/vendor/bitflags/src/example_generated.rs create mode 100644 utshell-0.5.0/vendor/bitflags/src/lib.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/basic.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/convert.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/default.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/inherent_methods.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/core.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/stringify.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/c.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/transparent.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/bits_field.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/pub_in.rs create mode 100644 utshell-0.5.0/vendor/bitflags/tests/compile.rs create mode 100644 utshell-0.5.0/vendor/cfg-if/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/cfg-if/Cargo.toml create mode 100644 utshell-0.5.0/vendor/cfg-if/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/cfg-if/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/cfg-if/README.md create mode 100644 utshell-0.5.0/vendor/cfg-if/src/lib.rs create mode 100644 utshell-0.5.0/vendor/cfg-if/tests/xcrate.rs create mode 100644 utshell-0.5.0/vendor/chunky-vec/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/chunky-vec/Cargo.toml create mode 100644 utshell-0.5.0/vendor/chunky-vec/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/chunky-vec/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/chunky-vec/README.md create mode 100644 utshell-0.5.0/vendor/chunky-vec/src/lib.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/displaydoc/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/displaydoc/Cargo.lock create mode 100644 utshell-0.5.0/vendor/displaydoc/Cargo.toml create mode 100644 utshell-0.5.0/vendor/displaydoc/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/displaydoc/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/displaydoc/README.md create mode 100644 utshell-0.5.0/vendor/displaydoc/README.tpl create mode 100644 utshell-0.5.0/vendor/displaydoc/examples/simple.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/src/attr.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/src/expand.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/src/fmt.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/src/lib.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/compile_tests.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/happy.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.stderr create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.stderr create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line_allow.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/with.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/without.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/no_std/without.stderr create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/num_in_field.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.stderr create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.stderr create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/multi_line_allow.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/multiple.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/without.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/std/without.stderr create mode 100644 utshell-0.5.0/vendor/displaydoc/tests/variantless.rs create mode 100644 utshell-0.5.0/vendor/displaydoc/update-readme.sh create mode 100644 utshell-0.5.0/vendor/dunce/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/dunce/Cargo.toml create mode 100644 utshell-0.5.0/vendor/dunce/LICENSE create mode 100644 utshell-0.5.0/vendor/dunce/README.md create mode 100644 utshell-0.5.0/vendor/dunce/src/lib.rs create mode 100644 utshell-0.5.0/vendor/elsa/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/elsa/Cargo.lock create mode 100644 utshell-0.5.0/vendor/elsa/Cargo.toml create mode 100644 utshell-0.5.0/vendor/elsa/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/elsa/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/elsa/README.md create mode 100644 utshell-0.5.0/vendor/elsa/examples/arena.rs create mode 100644 utshell-0.5.0/vendor/elsa/examples/fluentresource.rs create mode 100644 utshell-0.5.0/vendor/elsa/examples/mutable_arena.rs create mode 100644 utshell-0.5.0/vendor/elsa/examples/string_interner.rs create mode 100644 utshell-0.5.0/vendor/elsa/examples/sync.rs create mode 100644 utshell-0.5.0/vendor/elsa/src/index_map.rs create mode 100644 utshell-0.5.0/vendor/elsa/src/index_set.rs create mode 100644 utshell-0.5.0/vendor/elsa/src/lib.rs create mode 100644 utshell-0.5.0/vendor/elsa/src/map.rs create mode 100644 utshell-0.5.0/vendor/elsa/src/sync.rs create mode 100644 utshell-0.5.0/vendor/elsa/src/vec.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/fluent-bundle/Cargo.toml create mode 100644 utshell-0.5.0/vendor/fluent-bundle/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/fluent-bundle/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/fluent-bundle/README.md create mode 100644 utshell-0.5.0/vendor/fluent-bundle/benches/resolver.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/benches/resolver_iai.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/examples/README.md create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/args.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/bundle.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/concurrent.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/entry.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/errors.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/lib.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/memoizer.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/message.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resolver/errors.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resolver/expression.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resolver/inline_expression.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resolver/mod.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resolver/pattern.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resolver/scope.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/resource.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/types/mod.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/types/number.rs create mode 100644 utshell-0.5.0/vendor/fluent-bundle/src/types/plural.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/fluent-fallback/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/fluent-fallback/Cargo.lock create mode 100644 utshell-0.5.0/vendor/fluent-fallback/Cargo.toml create mode 100644 utshell-0.5.0/vendor/fluent-fallback/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/fluent-fallback/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/fluent-fallback/README.md create mode 100644 utshell-0.5.0/vendor/fluent-fallback/examples/resources/en-US/simple.ftl create mode 100644 utshell-0.5.0/vendor/fluent-fallback/examples/resources/pl/simple.ftl create mode 100644 utshell-0.5.0/vendor/fluent-fallback/examples/simple-fallback.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/bundles.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/cache.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/env.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/errors.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/generator.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/lib.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/localization.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/README.md create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/mod.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_mut.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_ref.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/src/types.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/tests/localization_test.rs create mode 100644 utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test.ftl create mode 100644 utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test2.ftl create mode 100644 utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test.ftl create mode 100644 utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test2.ftl create mode 100644 utshell-0.5.0/vendor/fluent-langneg/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/fluent-langneg/Cargo.toml create mode 100644 utshell-0.5.0/vendor/fluent-langneg/README.md create mode 100644 utshell-0.5.0/vendor/fluent-langneg/benches/negotiate.rs create mode 100644 utshell-0.5.0/vendor/fluent-langneg/src/accepted_languages.rs create mode 100644 utshell-0.5.0/vendor/fluent-langneg/src/lib.rs create mode 100644 utshell-0.5.0/vendor/fluent-langneg/src/negotiate/likely_subtags.rs create mode 100644 utshell-0.5.0/vendor/fluent-langneg/src/negotiate/mod.rs create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/Cargo.lock create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/Cargo.toml create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/README.md create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/common.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/errors.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/simple.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/common.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/errors.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/simple.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/examples/simple-resmgr.rs create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/src/lib.rs create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/src/resource_manager.rs create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/tests/localization_test.rs create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/tests/resources/en-US/test.ftl create mode 100644 utshell-0.5.0/vendor/fluent-resmgr/tests/resources/pl/test.ftl create mode 100644 utshell-0.5.0/vendor/fluent-syntax/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/fluent-syntax/Cargo.lock create mode 100644 utshell-0.5.0/vendor/fluent-syntax/Cargo.toml create mode 100644 utshell-0.5.0/vendor/fluent-syntax/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/fluent-syntax/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/fluent-syntax/README.md create mode 100644 utshell-0.5.0/vendor/fluent-syntax/benches/contexts/README.md create mode 100644 utshell-0.5.0/vendor/fluent-syntax/benches/parser.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/benches/parser_iai.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/ast/helper.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/ast/mod.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/bin/parser.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/bin/update_fixtures.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/lib.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/comment.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/core.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/errors.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/expression.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/helper.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/macros.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/mod.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/pattern.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/runtime.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/parser/slice.rs create mode 100644 utshell-0.5.0/vendor/fluent-syntax/src/unicode.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-channel/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-channel/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-channel/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-channel/README.md create mode 100644 utshell-0.5.0/vendor/futures-channel/benches/sync_mpsc.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/src/lock.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/src/mpsc/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/src/mpsc/queue.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/src/mpsc/sink_impl.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/src/oneshot.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/tests/channel.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/tests/mpsc-close.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/tests/mpsc-size_hint.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/tests/mpsc.rs create mode 100644 utshell-0.5.0/vendor/futures-channel/tests/oneshot.rs create mode 100644 utshell-0.5.0/vendor/futures-core/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-core/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-core/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-core/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-core/README.md create mode 100644 utshell-0.5.0/vendor/futures-core/src/future.rs create mode 100644 utshell-0.5.0/vendor/futures-core/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-core/src/stream.rs create mode 100644 utshell-0.5.0/vendor/futures-core/src/task/__internal/atomic_waker.rs create mode 100644 utshell-0.5.0/vendor/futures-core/src/task/__internal/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-core/src/task/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-core/src/task/poll.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-executor/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-executor/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-executor/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-executor/README.md create mode 100644 utshell-0.5.0/vendor/futures-executor/benches/thread_notify.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/src/enter.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/src/local_pool.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/src/thread_pool.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/src/unpark_mutex.rs create mode 100644 utshell-0.5.0/vendor/futures-executor/tests/local_pool.rs create mode 100644 utshell-0.5.0/vendor/futures-io/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-io/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-io/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-io/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-io/README.md create mode 100644 utshell-0.5.0/vendor/futures-io/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-macro/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-macro/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-macro/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-macro/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-macro/src/executor.rs create mode 100644 utshell-0.5.0/vendor/futures-macro/src/join.rs create mode 100644 utshell-0.5.0/vendor/futures-macro/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-macro/src/select.rs create mode 100644 utshell-0.5.0/vendor/futures-macro/src/stream_select.rs create mode 100644 utshell-0.5.0/vendor/futures-sink/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-sink/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-sink/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-sink/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-sink/README.md create mode 100644 utshell-0.5.0/vendor/futures-sink/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-task/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-task/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-task/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-task/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-task/README.md create mode 100644 utshell-0.5.0/vendor/futures-task/src/arc_wake.rs create mode 100644 utshell-0.5.0/vendor/futures-task/src/future_obj.rs create mode 100644 utshell-0.5.0/vendor/futures-task/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-task/src/noop_waker.rs create mode 100644 utshell-0.5.0/vendor/futures-task/src/spawn.rs create mode 100644 utshell-0.5.0/vendor/futures-task/src/waker.rs create mode 100644 utshell-0.5.0/vendor/futures-task/src/waker_ref.rs create mode 100644 utshell-0.5.0/vendor/futures-util/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures-util/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures-util/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures-util/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures-util/README.md create mode 100644 utshell-0.5.0/vendor/futures-util/benches/bilock.rs create mode 100644 utshell-0.5.0/vendor/futures-util/benches/flatten_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/benches/futures_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/benches/select.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/abortable.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/join_mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/pending.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/poll.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/random.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/select_mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/async_await/stream_select_mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/compat/compat01as03.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/compat/compat03as01.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/compat/executor.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/compat/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/fns.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/abortable.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/either.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/catch_unwind.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/flatten.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/fuse.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/map.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/remote_handle.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/future/shared.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/join.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/join_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/lazy.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/maybe_done.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/option.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/pending.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/poll_fn.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/poll_immediate.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/ready.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/select.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/select_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/select_ok.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_future/into_future.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_future/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten_err.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_join.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_join_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_maybe_done.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/future/try_select.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/allow_std.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/buf_reader.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/buf_writer.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/chain.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/close.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/copy.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/copy_buf.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/copy_buf_abortable.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/cursor.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/empty.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/fill_buf.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/flush.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/into_sink.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/line_writer.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/lines.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read_exact.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read_line.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read_to_end.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read_to_string.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read_until.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/read_vectored.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/repeat.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/seek.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/sink.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/split.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/take.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/window.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/write.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/write_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/write_all_vectored.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/io/write_vectored.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/lock/bilock.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/lock/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/lock/mutex.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/never.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/buffer.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/close.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/drain.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/err_into.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/fanout.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/feed.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/flush.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/map_err.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/send.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/send_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/unfold.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/with.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/sink/with_flat_map.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/abortable.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/empty.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/futures_ordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/abort.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/iter.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/task.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/iter.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/once.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/pending.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/poll_fn.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/poll_immediate.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/repeat.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/repeat_with.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/select.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/select_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/select_with_strategy.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/any.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/buffer_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/buffered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/catch_unwind.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/chain.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/chunks.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/collect.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/concat.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/count.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/cycle.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/enumerate.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/filter.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/filter_map.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/fold.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each_concurrent.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/forward.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/fuse.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/into_future.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/map.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/next.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/peek.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/ready_chunks.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/scan.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/select_next_some.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/skip.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/skip_while.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/split.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/take.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/take_until.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/take_while.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/then.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/unzip.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/stream/zip.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/and_then.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_async_read.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_stream.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/or_else.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_all.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_any.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffer_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_chunks.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_collect.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_concat.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter_map.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_fold.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each_concurrent.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_next.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_ready_chunks.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_skip_while.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_take_while.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_unfold.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/stream/unfold.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/task/mod.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/task/spawn.rs create mode 100644 utshell-0.5.0/vendor/futures-util/src/unfold_state.rs create mode 100644 utshell-0.5.0/vendor/futures/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/futures/Cargo.toml create mode 100644 utshell-0.5.0/vendor/futures/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/futures/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/futures/README.md create mode 100644 utshell-0.5.0/vendor/futures/src/lib.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/_require_features.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/async_await_macros.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/auto_traits.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/bilock.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/compat.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/eager_drop.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/eventual.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_abortable.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_basic_combinators.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_fuse.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_inspect.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_join.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_join_all.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_obj.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_select_all.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_select_ok.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_shared.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_try_flatten_stream.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/future_try_join_all.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_buf_reader.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_buf_writer.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_cursor.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_line_writer.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_lines.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_read.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_read_exact.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_read_line.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_read_to_end.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_read_to_string.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_read_until.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_window.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/io_write.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/lock_mutex.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/macro_comma_support.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/object_safety.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/oneshot.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/ready_queue.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/recurse.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/sink.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/sink_fanout.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_abortable.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_buffer_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_catch_unwind.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_futures_ordered.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_futures_unordered.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_into_async_read.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_peekable.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_select_all.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_select_next_some.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_split.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_try_stream.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/stream_unfold.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/task_arc_wake.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/task_atomic_waker.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/test_macro.rs create mode 100644 utshell-0.5.0/vendor/futures/tests/try_join.rs create mode 100644 utshell-0.5.0/vendor/futures/tests_disabled/all.rs create mode 100644 utshell-0.5.0/vendor/futures/tests_disabled/stream.rs create mode 100644 utshell-0.5.0/vendor/intl-memoizer/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/intl-memoizer/Cargo.toml create mode 100644 utshell-0.5.0/vendor/intl-memoizer/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/intl-memoizer/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/intl-memoizer/README.md create mode 100644 utshell-0.5.0/vendor/intl-memoizer/src/concurrent.rs create mode 100644 utshell-0.5.0/vendor/intl-memoizer/src/lib.rs create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/Cargo.toml create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/README.md create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/benches/pluralrules.rs create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/src/lib.rs create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/src/operands.rs create mode 100644 utshell-0.5.0/vendor/intl_pluralrules/src/rules.rs create mode 100644 utshell-0.5.0/vendor/lazy_static/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/lazy_static/Cargo.toml create mode 100644 utshell-0.5.0/vendor/lazy_static/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/lazy_static/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/lazy_static/README.md create mode 100644 utshell-0.5.0/vendor/lazy_static/src/core_lazy.rs create mode 100644 utshell-0.5.0/vendor/lazy_static/src/inline_lazy.rs create mode 100644 utshell-0.5.0/vendor/lazy_static/src/lib.rs create mode 100644 utshell-0.5.0/vendor/lazy_static/tests/no_std.rs create mode 100644 utshell-0.5.0/vendor/lazy_static/tests/test.rs create mode 100644 utshell-0.5.0/vendor/libc/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/libc/CONTRIBUTING.md create mode 100644 utshell-0.5.0/vendor/libc/Cargo.toml create mode 100644 utshell-0.5.0/vendor/libc/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/libc/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/libc/README.md create mode 100644 utshell-0.5.0/vendor/libc/build.rs create mode 100644 utshell-0.5.0/vendor/libc/rustfmt.toml create mode 100644 utshell-0.5.0/vendor/libc/src/fixed_width_ints.rs create mode 100644 utshell-0.5.0/vendor/libc/src/fuchsia/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/fuchsia/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/fuchsia/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/fuchsia/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/fuchsia/riscv64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/fuchsia/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/hermit/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/hermit/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/hermit/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/lib.rs create mode 100644 utshell-0.5.0/vendor/libc/src/macros.rs create mode 100644 utshell-0.5.0/vendor/libc/src/psp.rs create mode 100644 utshell-0.5.0/vendor/libc/src/sgx.rs create mode 100644 utshell-0.5.0/vendor/libc/src/solid/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/solid/arm.rs create mode 100644 utshell-0.5.0/vendor/libc/src/solid/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/switch.rs create mode 100644 utshell-0.5.0/vendor/libc/src/teeos/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/aix/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/aix/powerpc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/long_array.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/apple/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/haiku/b32.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/haiku/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/haiku/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/haiku/native.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/haiku/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/hurd/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/hurd/b32.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/hurd/b64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/hurd/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/hurd/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/arm.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/android/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/linux_like/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/aarch64/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/arm/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/espidf/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/generic.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/horizon/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/powerpc/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/newlib/vita/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/no_align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/nto/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/nto/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/nto/neutrino.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/nto/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/redox/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/compat.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/illumos.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/solaris.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/x86.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/unix/solarish/x86_common.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/aarch64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/arm.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/powerpc.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/powerpc64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/x86.rs create mode 100644 utshell-0.5.0/vendor/libc/src/vxworks/x86_64.rs create mode 100644 utshell-0.5.0/vendor/libc/src/wasi.rs create mode 100644 utshell-0.5.0/vendor/libc/src/windows/gnu/align.rs create mode 100644 utshell-0.5.0/vendor/libc/src/windows/gnu/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/windows/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/windows/msvc/mod.rs create mode 100644 utshell-0.5.0/vendor/libc/src/xous.rs create mode 100644 utshell-0.5.0/vendor/libc/tests/const_fn.rs create mode 100644 utshell-0.5.0/vendor/memchr/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/memchr/COPYING create mode 100644 utshell-0.5.0/vendor/memchr/Cargo.toml create mode 100644 utshell-0.5.0/vendor/memchr/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/memchr/README.md create mode 100644 utshell-0.5.0/vendor/memchr/UNLICENSE create mode 100644 utshell-0.5.0/vendor/memchr/build.rs create mode 100644 utshell-0.5.0/vendor/memchr/rustfmt.toml create mode 100755 utshell-0.5.0/vendor/memchr/scripts/make-byte-frequency-table create mode 100644 utshell-0.5.0/vendor/memchr/src/cow.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/lib.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/c.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/fallback.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/iter.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/naive.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/x86/avx.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/x86/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/x86/sse2.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memchr/x86/sse42.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/byte_frequencies.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/genericsimd.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/fallback.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/genericsimd.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/wasm.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/avx.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/sse.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/rabinkarp.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/rarebytes.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/twoway.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/util.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/vector.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/wasm.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/x86/avx.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/x86/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/memmem/x86/sse.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/memchr/iter.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/memchr/memchr.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/memchr/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/memchr/simple.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/memchr/testdata.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/mod.rs create mode 100644 utshell-0.5.0/vendor/memchr/src/tests/x86_64-soft_float.json create mode 100644 utshell-0.5.0/vendor/memoffset/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/memoffset/Cargo.toml create mode 100644 utshell-0.5.0/vendor/memoffset/LICENSE create mode 100644 utshell-0.5.0/vendor/memoffset/README.md create mode 100644 utshell-0.5.0/vendor/memoffset/build.rs create mode 100755 utshell-0.5.0/vendor/memoffset/ci/miri.sh create mode 100644 utshell-0.5.0/vendor/memoffset/src/lib.rs create mode 100644 utshell-0.5.0/vendor/memoffset/src/offset_of.rs create mode 100644 utshell-0.5.0/vendor/memoffset/src/raw_field.rs create mode 100644 utshell-0.5.0/vendor/memoffset/src/span_of.rs create mode 100644 utshell-0.5.0/vendor/nix/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/nix/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/nix/Cargo.toml create mode 100644 utshell-0.5.0/vendor/nix/LICENSE create mode 100644 utshell-0.5.0/vendor/nix/README.md create mode 100644 utshell-0.5.0/vendor/nix/src/dir.rs create mode 100644 utshell-0.5.0/vendor/nix/src/env.rs create mode 100644 utshell-0.5.0/vendor/nix/src/errno.rs create mode 100644 utshell-0.5.0/vendor/nix/src/fcntl.rs create mode 100644 utshell-0.5.0/vendor/nix/src/features.rs create mode 100644 utshell-0.5.0/vendor/nix/src/ifaddrs.rs create mode 100644 utshell-0.5.0/vendor/nix/src/kmod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/lib.rs create mode 100644 utshell-0.5.0/vendor/nix/src/macros.rs create mode 100644 utshell-0.5.0/vendor/nix/src/mount/bsd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/mount/linux.rs create mode 100644 utshell-0.5.0/vendor/nix/src/mount/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/mqueue.rs create mode 100644 utshell-0.5.0/vendor/nix/src/net/if_.rs create mode 100644 utshell-0.5.0/vendor/nix/src/net/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/poll.rs create mode 100644 utshell-0.5.0/vendor/nix/src/pty.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sched.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/aio.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/epoll.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/event.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/eventfd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/inotify.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/ioctl/bsd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/ioctl/linux.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/ioctl/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/memfd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/mman.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/personality.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/pthread.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/ptrace/bsd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/ptrace/linux.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/ptrace/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/quota.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/reboot.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/resource.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/select.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/sendfile.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/signal.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/signalfd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/socket/addr.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/socket/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/socket/sockopt.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/stat.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/statfs.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/statvfs.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/sysinfo.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/termios.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/time.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/timer.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/timerfd.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/uio.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/utsname.rs create mode 100644 utshell-0.5.0/vendor/nix/src/sys/wait.rs create mode 100644 utshell-0.5.0/vendor/nix/src/time.rs create mode 100644 utshell-0.5.0/vendor/nix/src/ucontext.rs create mode 100644 utshell-0.5.0/vendor/nix/src/unistd.rs create mode 100644 utshell-0.5.0/vendor/nix/test/common/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_aio.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_aio_drop.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_epoll.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_inotify.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_ioctl.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_mman.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_pthread.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_ptrace.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_select.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_signal.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_signalfd.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_socket.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_sockopt.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_stat.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_sysinfo.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_termios.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_timerfd.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_uio.rs create mode 100644 utshell-0.5.0/vendor/nix/test/sys/test_wait.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_clearenv.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_dir.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_fcntl.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/Makefile create mode 100644 utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/hello.c create mode 100644 utshell-0.5.0/vendor/nix/test/test_kmod/mod.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_mount.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_mq.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_net.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_nix_path.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_nmount.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_poll.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_pty.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_ptymaster_drop.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_resource.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_sched.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_sendfile.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_stat.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_time.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_timer.rs create mode 100644 utshell-0.5.0/vendor/nix/test/test_unistd.rs create mode 100644 utshell-0.5.0/vendor/once_cell/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/once_cell/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/once_cell/Cargo.lock create mode 100644 utshell-0.5.0/vendor/once_cell/Cargo.toml create mode 100644 utshell-0.5.0/vendor/once_cell/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/once_cell/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/once_cell/README.md create mode 100644 utshell-0.5.0/vendor/once_cell/bors.toml create mode 100644 utshell-0.5.0/vendor/once_cell/examples/bench.rs create mode 100644 utshell-0.5.0/vendor/once_cell/examples/bench_acquire.rs create mode 100644 utshell-0.5.0/vendor/once_cell/examples/bench_vs_lazy_static.rs create mode 100644 utshell-0.5.0/vendor/once_cell/examples/lazy_static.rs create mode 100644 utshell-0.5.0/vendor/once_cell/examples/reentrant_init_deadlocks.rs create mode 100644 utshell-0.5.0/vendor/once_cell/examples/regex.rs create mode 100644 utshell-0.5.0/vendor/once_cell/examples/test_synchronization.rs create mode 100644 utshell-0.5.0/vendor/once_cell/src/imp_cs.rs create mode 100644 utshell-0.5.0/vendor/once_cell/src/imp_pl.rs create mode 100644 utshell-0.5.0/vendor/once_cell/src/imp_std.rs create mode 100644 utshell-0.5.0/vendor/once_cell/src/lib.rs create mode 100644 utshell-0.5.0/vendor/once_cell/src/race.rs create mode 100644 utshell-0.5.0/vendor/once_cell/tests/it.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/pin-project-lite/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/pin-project-lite/Cargo.toml create mode 100644 utshell-0.5.0/vendor/pin-project-lite/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/pin-project-lite/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/pin-project-lite/README.md create mode 100644 utshell-0.5.0/vendor/pin-project-lite/src/lib.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/auxiliary/mod.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/compiletest.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/drop_order.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.expanded.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/expandtest.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/include/basic.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/lint.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/proper_unpin.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/test.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.stderr create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.rs create mode 100644 utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.stderr create mode 100644 utshell-0.5.0/vendor/pin-utils/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/pin-utils/Cargo.toml create mode 100644 utshell-0.5.0/vendor/pin-utils/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/pin-utils/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/pin-utils/README.md create mode 100644 utshell-0.5.0/vendor/pin-utils/src/lib.rs create mode 100644 utshell-0.5.0/vendor/pin-utils/src/projection.rs create mode 100644 utshell-0.5.0/vendor/pin-utils/src/stack_pin.rs create mode 100644 utshell-0.5.0/vendor/pin-utils/tests/projection.rs create mode 100644 utshell-0.5.0/vendor/pin-utils/tests/stack_pin.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/proc-macro2/Cargo.toml create mode 100644 utshell-0.5.0/vendor/proc-macro2/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/proc-macro2/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/proc-macro2/README.md create mode 100644 utshell-0.5.0/vendor/proc-macro2/build.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/build/probe.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/rust-toolchain.toml create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/detection.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/extra.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/fallback.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/lib.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/location.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/marker.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/parse.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/rcvec.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/src/wrapper.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/tests/comments.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/tests/features.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/tests/marker.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/tests/test.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/tests/test_fmt.rs create mode 100644 utshell-0.5.0/vendor/proc-macro2/tests/test_size.rs create mode 100644 utshell-0.5.0/vendor/quote/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/quote/Cargo.toml create mode 100644 utshell-0.5.0/vendor/quote/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/quote/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/quote/README.md create mode 100644 utshell-0.5.0/vendor/quote/rust-toolchain.toml create mode 100644 utshell-0.5.0/vendor/quote/src/ext.rs create mode 100644 utshell-0.5.0/vendor/quote/src/format.rs create mode 100644 utshell-0.5.0/vendor/quote/src/ident_fragment.rs create mode 100644 utshell-0.5.0/vendor/quote/src/lib.rs create mode 100644 utshell-0.5.0/vendor/quote/src/runtime.rs create mode 100644 utshell-0.5.0/vendor/quote/src/spanned.rs create mode 100644 utshell-0.5.0/vendor/quote/src/to_tokens.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/compiletest.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/test.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.stderr create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.stderr create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/not-quotable.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/not-quotable.stderr create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.stderr create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.rs create mode 100644 utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.stderr create mode 100644 utshell-0.5.0/vendor/rustc-hash/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/rustc-hash/CODE_OF_CONDUCT.md create mode 100644 utshell-0.5.0/vendor/rustc-hash/Cargo.toml create mode 100644 utshell-0.5.0/vendor/rustc-hash/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/rustc-hash/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/rustc-hash/README.md create mode 100644 utshell-0.5.0/vendor/rustc-hash/src/lib.rs create mode 100644 utshell-0.5.0/vendor/self_cell-0.10.3/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/self_cell-0.10.3/Cargo.toml create mode 100644 utshell-0.5.0/vendor/self_cell-0.10.3/LICENSE create mode 100644 utshell-0.5.0/vendor/self_cell-0.10.3/README.md create mode 100644 utshell-0.5.0/vendor/self_cell-0.10.3/src/lib.rs create mode 100644 utshell-0.5.0/vendor/self_cell/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/self_cell/Cargo.toml create mode 100644 utshell-0.5.0/vendor/self_cell/LICENSE create mode 100644 utshell-0.5.0/vendor/self_cell/README.md create mode 100644 utshell-0.5.0/vendor/self_cell/src/lib.rs create mode 100644 utshell-0.5.0/vendor/self_cell/src/unsafe_self_cell.rs create mode 100644 utshell-0.5.0/vendor/slab/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/slab/CHANGELOG.md create mode 100644 utshell-0.5.0/vendor/slab/Cargo.toml create mode 100644 utshell-0.5.0/vendor/slab/LICENSE create mode 100644 utshell-0.5.0/vendor/slab/README.md create mode 100644 utshell-0.5.0/vendor/slab/build.rs create mode 100644 utshell-0.5.0/vendor/slab/src/builder.rs create mode 100644 utshell-0.5.0/vendor/slab/src/lib.rs create mode 100644 utshell-0.5.0/vendor/slab/src/serde.rs create mode 100644 utshell-0.5.0/vendor/slab/tests/serde.rs create mode 100644 utshell-0.5.0/vendor/slab/tests/slab.rs create mode 100644 utshell-0.5.0/vendor/smallvec/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/smallvec/Cargo.toml create mode 100644 utshell-0.5.0/vendor/smallvec/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/smallvec/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/smallvec/README.md create mode 100644 utshell-0.5.0/vendor/smallvec/benches/bench.rs create mode 100644 utshell-0.5.0/vendor/smallvec/debug_metadata/README.md create mode 100644 utshell-0.5.0/vendor/smallvec/debug_metadata/smallvec.natvis create mode 100644 utshell-0.5.0/vendor/smallvec/scripts/run_miri.sh create mode 100644 utshell-0.5.0/vendor/smallvec/src/arbitrary.rs create mode 100644 utshell-0.5.0/vendor/smallvec/src/lib.rs create mode 100644 utshell-0.5.0/vendor/smallvec/src/specialization.rs create mode 100644 utshell-0.5.0/vendor/smallvec/src/tests.rs create mode 100644 utshell-0.5.0/vendor/smallvec/tests/debugger_visualizer.rs create mode 100644 utshell-0.5.0/vendor/smallvec/tests/macro.rs create mode 100644 utshell-0.5.0/vendor/stable_deref_trait/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/stable_deref_trait/Cargo.toml create mode 100644 utshell-0.5.0/vendor/stable_deref_trait/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/stable_deref_trait/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/stable_deref_trait/README.md create mode 100644 utshell-0.5.0/vendor/stable_deref_trait/src/lib.rs create mode 100644 utshell-0.5.0/vendor/syn/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/syn/Cargo.toml create mode 100644 utshell-0.5.0/vendor/syn/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/syn/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/syn/README.md create mode 100644 utshell-0.5.0/vendor/syn/benches/file.rs create mode 100644 utshell-0.5.0/vendor/syn/benches/rust.rs create mode 100644 utshell-0.5.0/vendor/syn/src/attr.rs create mode 100644 utshell-0.5.0/vendor/syn/src/bigint.rs create mode 100644 utshell-0.5.0/vendor/syn/src/buffer.rs create mode 100644 utshell-0.5.0/vendor/syn/src/custom_keyword.rs create mode 100644 utshell-0.5.0/vendor/syn/src/custom_punctuation.rs create mode 100644 utshell-0.5.0/vendor/syn/src/data.rs create mode 100644 utshell-0.5.0/vendor/syn/src/derive.rs create mode 100644 utshell-0.5.0/vendor/syn/src/discouraged.rs create mode 100644 utshell-0.5.0/vendor/syn/src/drops.rs create mode 100644 utshell-0.5.0/vendor/syn/src/error.rs create mode 100644 utshell-0.5.0/vendor/syn/src/export.rs create mode 100644 utshell-0.5.0/vendor/syn/src/expr.rs create mode 100644 utshell-0.5.0/vendor/syn/src/ext.rs create mode 100644 utshell-0.5.0/vendor/syn/src/file.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/clone.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/debug.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/eq.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/fold.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/hash.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/visit.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen/visit_mut.rs create mode 100644 utshell-0.5.0/vendor/syn/src/gen_helper.rs create mode 100644 utshell-0.5.0/vendor/syn/src/generics.rs create mode 100644 utshell-0.5.0/vendor/syn/src/group.rs create mode 100644 utshell-0.5.0/vendor/syn/src/ident.rs create mode 100644 utshell-0.5.0/vendor/syn/src/item.rs create mode 100644 utshell-0.5.0/vendor/syn/src/lib.rs create mode 100644 utshell-0.5.0/vendor/syn/src/lifetime.rs create mode 100644 utshell-0.5.0/vendor/syn/src/lit.rs create mode 100644 utshell-0.5.0/vendor/syn/src/lookahead.rs create mode 100644 utshell-0.5.0/vendor/syn/src/mac.rs create mode 100644 utshell-0.5.0/vendor/syn/src/macros.rs create mode 100644 utshell-0.5.0/vendor/syn/src/meta.rs create mode 100644 utshell-0.5.0/vendor/syn/src/op.rs create mode 100644 utshell-0.5.0/vendor/syn/src/parse.rs create mode 100644 utshell-0.5.0/vendor/syn/src/parse_macro_input.rs create mode 100644 utshell-0.5.0/vendor/syn/src/parse_quote.rs create mode 100644 utshell-0.5.0/vendor/syn/src/pat.rs create mode 100644 utshell-0.5.0/vendor/syn/src/path.rs create mode 100644 utshell-0.5.0/vendor/syn/src/print.rs create mode 100644 utshell-0.5.0/vendor/syn/src/punctuated.rs create mode 100644 utshell-0.5.0/vendor/syn/src/restriction.rs create mode 100644 utshell-0.5.0/vendor/syn/src/sealed.rs create mode 100644 utshell-0.5.0/vendor/syn/src/span.rs create mode 100644 utshell-0.5.0/vendor/syn/src/spanned.rs create mode 100644 utshell-0.5.0/vendor/syn/src/stmt.rs create mode 100644 utshell-0.5.0/vendor/syn/src/thread.rs create mode 100644 utshell-0.5.0/vendor/syn/src/token.rs create mode 100644 utshell-0.5.0/vendor/syn/src/tt.rs create mode 100644 utshell-0.5.0/vendor/syn/src/ty.rs create mode 100644 utshell-0.5.0/vendor/syn/src/verbatim.rs create mode 100644 utshell-0.5.0/vendor/syn/src/whitespace.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/common/eq.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/common/mod.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/common/parse.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/debug/gen.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/debug/mod.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/macros/mod.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/regression.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/regression/issue1108.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/regression/issue1235.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/repo/mod.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/repo/progress.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_asyncness.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_attribute.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_derive_input.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_expr.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_generics.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_grouping.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_ident.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_item.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_iterators.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_lit.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_meta.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_parse_buffer.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_parse_quote.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_parse_stream.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_pat.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_path.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_precedence.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_receiver.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_round_trip.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_shebang.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_should_parse.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_size.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_stmt.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_token_trees.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_ty.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/test_visibility.rs create mode 100644 utshell-0.5.0/vendor/syn/tests/zzz_stable.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/thiserror-impl/Cargo.toml create mode 100644 utshell-0.5.0/vendor/thiserror-impl/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/thiserror-impl/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/ast.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/attr.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/expand.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/fmt.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/generics.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/lib.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/prop.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/span.rs create mode 100644 utshell-0.5.0/vendor/thiserror-impl/src/valid.rs create mode 100644 utshell-0.5.0/vendor/thiserror/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/thiserror/Cargo.toml create mode 100644 utshell-0.5.0/vendor/thiserror/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/thiserror/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/thiserror/README.md create mode 100644 utshell-0.5.0/vendor/thiserror/build.rs create mode 100644 utshell-0.5.0/vendor/thiserror/build/probe.rs create mode 100644 utshell-0.5.0/vendor/thiserror/rust-toolchain.toml create mode 100644 utshell-0.5.0/vendor/thiserror/src/aserror.rs create mode 100644 utshell-0.5.0/vendor/thiserror/src/display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/src/lib.rs create mode 100644 utshell-0.5.0/vendor/thiserror/src/provide.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/compiletest.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_backtrace.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_deprecated.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_expr.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_from.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_generics.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_lints.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_option.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_path.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/test_transparent.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/bad-field-attr.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/bad-field-attr.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/concat-display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/concat-display.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-enum-source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-enum-source.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-fmt.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-fmt.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-struct-source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-struct-source.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-transparent.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/duplicate-transparent.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/fallback-impl-with-display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/fallback-impl-with-display.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/from-backtrace-backtrace.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/from-backtrace-backtrace.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/from-not-source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/from-not-source.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/invalid-input-impl-anyway.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/invalid-input-impl-anyway.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/lifetime.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/lifetime.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/missing-display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/missing-display.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/missing-fmt.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/missing-fmt.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/no-display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/no-display.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-enum-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-enum-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-enum-unnamed-field-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-enum-unnamed-field-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-struct-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-struct-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-struct-unnamed-field-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/source-struct-unnamed-field-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-display.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-display.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-many.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-many.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-source.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-unnamed-field-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-enum-unnamed-field-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-many.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-many.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-source.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-unnamed-field-not-error.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/transparent-struct-unnamed-field-not-error.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/unexpected-field-fmt.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/unexpected-field-fmt.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/unexpected-struct-source.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/unexpected-struct-source.stderr create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/union.rs create mode 100644 utshell-0.5.0/vendor/thiserror/tests/ui/union.stderr create mode 100644 utshell-0.5.0/vendor/tinystr/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/tinystr/Cargo.toml create mode 100644 utshell-0.5.0/vendor/tinystr/LICENSE create mode 100644 utshell-0.5.0/vendor/tinystr/README.md create mode 100644 utshell-0.5.0/vendor/tinystr/benches/common/mod.rs create mode 100644 utshell-0.5.0/vendor/tinystr/benches/construct.rs create mode 100644 utshell-0.5.0/vendor/tinystr/benches/overview.rs create mode 100644 utshell-0.5.0/vendor/tinystr/benches/read.rs create mode 100644 utshell-0.5.0/vendor/tinystr/benches/serde.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/ascii.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/asciibyte.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/databake.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/error.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/int_ops.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/lib.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/macros.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/serde.rs create mode 100644 utshell-0.5.0/vendor/tinystr/src/ule.rs create mode 100644 utshell-0.5.0/vendor/tinystr/tests/serde.rs create mode 100644 utshell-0.5.0/vendor/type-map/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/type-map/Cargo.toml create mode 100755 utshell-0.5.0/vendor/type-map/README.md create mode 100755 utshell-0.5.0/vendor/type-map/src/lib.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/Cargo.lock create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/Cargo.toml create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/README.md create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/benches/canonicalize.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/benches/langid.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/benches/likely_subtags.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/benches/parser.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/data/cldr-misc-full/README.md create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/bin/generate_layout.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/bin/generate_likelysubtags.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/errors.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/layout_table.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/lib.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/likelysubtags/mod.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/likelysubtags/tables.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/parser/errors.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/parser/mod.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/serde.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/subtags/language.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/subtags/mod.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/subtags/region.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/subtags/script.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/src/subtags/variant.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/tests/canonicalize_test.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/tests/fixtures.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/tests/language_identifier_test.rs create mode 100644 utshell-0.5.0/vendor/unic-langid-impl/tests/likelysubtags.rs create mode 100644 utshell-0.5.0/vendor/unic-langid/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/unic-langid/Cargo.toml create mode 100644 utshell-0.5.0/vendor/unic-langid/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/unic-langid/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/unic-langid/README.md create mode 100644 utshell-0.5.0/vendor/unic-langid/src/lib.rs create mode 100644 utshell-0.5.0/vendor/unic-langid/tests/langid.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/.cargo-checksum.json create mode 100644 utshell-0.5.0/vendor/unicode-ident/Cargo.toml create mode 100644 utshell-0.5.0/vendor/unicode-ident/LICENSE-APACHE create mode 100644 utshell-0.5.0/vendor/unicode-ident/LICENSE-MIT create mode 100644 utshell-0.5.0/vendor/unicode-ident/LICENSE-UNICODE create mode 100644 utshell-0.5.0/vendor/unicode-ident/README.md create mode 100644 utshell-0.5.0/vendor/unicode-ident/benches/xid.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/src/lib.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/src/tables.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/compare.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/fst/mod.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/fst/xid_continue.fst create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/fst/xid_start.fst create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/roaring/mod.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/static_size.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/tables/mod.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/tables/tables.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/trie/mod.rs create mode 100644 utshell-0.5.0/vendor/unicode-ident/tests/trie/trie.rs diff --git a/utshell-0.5.0/COPYING b/utshell-0.5.0/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/utshell-0.5.0/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/utshell-0.5.0/Cargo.toml b/utshell-0.5.0/Cargo.toml new file mode 100644 index 00000000..caff1d6d --- /dev/null +++ b/utshell-0.5.0/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "utshell" +version = "0.1.0" +edition = "2018" + +build = "./build.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libc = "*" +nix = "0.25.0" +lazy_static = "1.4.0" +#fluent = "*" +unic-langid = "0.9.4" +fluent-resmgr = "0.0.6" +fluent-bundle = "0.15.2" +intl_pluralrules = "7.0.2" +tinystr = "=0.7.1" + + +#调试使用,用于打å°å‡½æ•°å称和所在行数 +#stdext = "0.3.1" + + +[build_dependencies] +dunce = "1.0.0" + +[lib] +name = "builtins" +path = "src/lib.rs" +crate-type = ["staticlib","rlib"] + + +#[[bin]] +#name = "utshell" +#path = "src/main.rs" + +#[[bin]] +#name = "utshellversion" +#path = "src/utshellversion.rs" + diff --git a/utshell-0.5.0/Makefile b/utshell-0.5.0/Makefile new file mode 100644 index 00000000..38fba727 --- /dev/null +++ b/utshell-0.5.0/Makefile @@ -0,0 +1,52 @@ +prefix = /usr/bin +bindir = /usr/bin +translationdir = /usr/share/utshell/resources + +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALLMODE = -m 0755 +INSTALLMODE2 = -m 0555 + +TOP_DIR = $(PWD) +LANGSRC = resources +BIN_DIR = target/debug +CONFIG_DIR = config + +LIB_DIR := $(TOP_DIR)/variable \ + $(TOP_DIR)/lib/glob \ + $(TOP_DIR)/lib/readline \ + $(TOP_DIR)/lib/sh \ + $(TOP_DIR)/lib/termcap \ + $(TOP_DIR)/lib/tilde + + +.PHONY:all +all:build_lib build_utshell +build_lib: + -for libdir in ${LIB_DIR}; do \ + (cd $$libdir && make) ;\ + done +build_utshell: + cargo build + +install: + mkdir -p $(DESTDIR)$(bindir) + mkdir -p $(DESTDIR)/root + mkdir -p $(DESTDIR)/etc + install -m 0755 $(BIN_DIR)/utshell $(DESTDIR)$(bindir)/utshell + install -m 0644 $(CONFIG_DIR)/.utshellrc $(DESTDIR)/root/.utshellrc + install -m 0644 $(CONFIG_DIR)/.utshell_profile $(DESTDIR)/root/.utshell_profile + install -m 0644 $(CONFIG_DIR)/.utshell_logout $(DESTDIR)/root/.utshell_logout + install -m 0644 $(CONFIG_DIR)/utshellrc $(DESTDIR)/etc/utshellrc + -( $(INSTALL_DATA) -D $(INSTALLMMODE2) $(LANGSRC)/zh-CN/* -t $(DESTDIR)$(translationdir)/zh-CN ) + -( $(INSTALL_DATA) -D $(INSTALLMMODE2) $(LANGSRC)/zh-HK/* -t $(DESTDIR)$(translationdir)/zh-HK ) + -( $(INSTALL_DATA) -D $(INSTALLMMODE2) $(LANGSRC)/en-US/* -t $(DESTDIR)$(translationdir)/en-US ) + +.PHONY:clean +clean: + -for libdir in ${LIB_DIR}; do \ + (cd $$libdir && make clean) ;\ + done + + cargo clean + rm -rf Cargo.lock diff --git a/utshell-0.5.0/README.md b/utshell-0.5.0/README.md new file mode 100644 index 00000000..b92164fd --- /dev/null +++ b/utshell-0.5.0/README.md @@ -0,0 +1,51 @@ +# utshell + + +utshell is use rust rewrote bash. and enhanced security. +now it is base on bash. and we will gradually remove dependence on bash. + +### Dependencies + +glibc, bash + +### Build dependencies + +glibc, bash + +## Installation + + +### Build from source code + +./configure +make +make install + +## Documentations + +If any, link the documentation here. Please ensure the linked pages can be accessible from the public internet. + +- Link 1 +- Link 2 +- ... + +## Getting help + +- [Official Forum](https://bbs.deepin.org/) for generic discussion and help. +- [Developer Center](https://github.com/linuxdeepin/developer-center) for BUG report and suggestions. +- [Wiki](https://wiki.deepin.org/) +(按照项目实际情况放帮助链接) + +## Getting involved + +We encourage you to report issues and contribute changes + +- [Contribution guide for developers](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en) (English) +- [Translate for your language on Transifex](#) *please update to the actual Transifex link of this project* +(按照项目实际情况放贡献指å—链接) + +## License + +License description here. The license name is suggested to use the same one as [SPDX license identifier](https://spdx.org/licenses). Following is an example: + +utshell is licensed under [GPL-3.0-or-later](LICENSE) diff --git a/utshell-0.5.0/README.zh_CN.md b/utshell-0.5.0/README.zh_CN.md new file mode 100644 index 00000000..6ceb27f7 --- /dev/null +++ b/utshell-0.5.0/README.zh_CN.md @@ -0,0 +1,45 @@ +# 项目åç§° + + +版æƒé€šçŸ¥ +utshell属于统信软件产å“,本产å“在GPL v3版本下å‘行 +utshell是对bash的一次é‡å†™ï¼Œå¹¶å¢žå¼ºäº†å®‰å…¨æ€§ã€‚ + +### ä¾èµ– + +glibc bash + +### 编译ä¾èµ– + +glibc bash + +## 安装 + +如果是UOS桌é¢ç‰ˆæœ¬ï¼Œè¯·æ‰§è¡Œï¼š +sudo apt install utshell +如果是UOSæœåŠ¡å™¨ç‰ˆæœ¬ï¼Œè¯·æ‰§è¡Œï¼š +sudo dnf install utshell + +### 构建过程 + +项目构建步骤 + +## 文档 + + +## 帮助 + +- [官方论å›](https://bbs.deepin.org/) +- [å¼€å‘者中心](https://github.com/linuxdeepin/developer-center) +- [Wiki](https://wiki.deepin.org/) + +## è´¡çŒ®æŒ‡å— + +我们鼓励您报告问题并åšå‡ºæ›´æ”¹ + +- [å¼€å‘者代ç è´¡çŒ®æŒ‡å—](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers) + +## å¼€æºè®¸å¯è¯ + +许å¯è¯è¯´æ˜Žï¼Œå»ºè®®ä½¿ç”¨SPDX规范æè¿°è®¸å¯è¯ã€‚例如: +[utshell] 在 [GPL-3.0-or-later]下å‘布。 diff --git a/utshell-0.5.0/build.rs b/utshell-0.5.0/build.rs new file mode 100644 index 00000000..fd981525 --- /dev/null +++ b/utshell-0.5.0/build.rs @@ -0,0 +1,106 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +extern crate dunce; + +use std::{env, path::PathBuf}; + +fn main() { + // let library_name_r = "r2c"; + let library_name_test = "test"; + let library_name_glob = "glob"; + let library_name_tilde = "tilde"; + let library_name_readline = "readline"; + let library_name_history = "history"; + let library_name_sh = "sh"; + //let library_name_termcap = "termcap"; + let library_name_var_params = "var_params"; + + let root_r = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + + // let library_dir_r = dunce::canonicalize(root_r.join("lib/r2c")).unwrap(); + let library_dir_test = dunce::canonicalize(root_r.join("lib/test")).unwrap(); + let library_dir_glob = dunce::canonicalize(root_r.join("lib/glob")).unwrap(); + let library_dir_tilde = dunce::canonicalize(root_r.join("lib/tilde")).unwrap(); + let library_dir_readline = dunce::canonicalize(root_r.join("lib/readline")).unwrap(); + let library_dir_history = dunce::canonicalize(root_r.join("lib/readline")).unwrap(); + let library_dir_sh = dunce::canonicalize(root_r.join("lib/sh")).unwrap(); + //let library_dir_termcap = dunce::canonicalize(root_r.join("lib/termcap")).unwrap(); + let library_dir_var_params = dunce::canonicalize(root_r.join("variable")).unwrap(); + + // println!("cargo:rustc-link-lib=static={}", library_name_r); + println!("cargo:rustc-link-lib=static={}", library_name_test); + println!("cargo:rustc-link-lib=static={}", library_name_glob); + println!("cargo:rustc-link-lib=static={}", library_name_tilde); + println!("cargo:rustc-link-lib=static={}", library_name_readline); + println!("cargo:rustc-link-lib=static={}", library_name_history); + println!("cargo:rustc-link-lib=static={}", library_name_sh); + //println!("cargo:rustc-link-lib=static={}", library_name_termcap); + println!("cargo:rustc-link-lib=static={}", library_name_var_params); + + // println!("cargo:rustc-link-search=native={}", env::join_paths(&[library_dir_r]).unwrap().to_str().unwrap()); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_test]) + .unwrap() + .to_str() + .unwrap() + ); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_glob]) + .unwrap() + .to_str() + .unwrap() + ); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_tilde]) + .unwrap() + .to_str() + .unwrap() + ); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_readline]) + .unwrap() + .to_str() + .unwrap() + ); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_history]) + .unwrap() + .to_str() + .unwrap() + ); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_sh]) + .unwrap() + .to_str() + .unwrap() + ); + //println!("cargo:rustc-link-search=native={}", env::join_paths(&[library_dir_termcap]).unwrap().to_str().unwrap()); + println!( + "cargo:rustc-link-search=native={}", + env::join_paths(&[library_dir_var_params]) + .unwrap() + .to_str() + .unwrap() + ); + + println!("cargo:rustc-link-search=native=/usr/lib64/"); + + // let library_name_v = "builtins_variables"; + + // let root_v = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + + // let library_dir_v = dunce::canonicalize(root_v.join("variable")).unwrap(); + + // println!("cargo:rustc-link-lib=static={}", library_name_v); + + // println!("cargo:rustc-link-search=native={}", env::join_paths(&[library_dir_v]).unwrap().to_str().unwrap()); +} diff --git a/utshell-0.5.0/config/.utshell_logout b/utshell-0.5.0/config/.utshell_logout new file mode 100644 index 00000000..6db763fd --- /dev/null +++ b/utshell-0.5.0/config/.utshell_logout @@ -0,0 +1,2 @@ +# ~/.utshell_logout + diff --git a/utshell-0.5.0/config/.utshell_profile b/utshell-0.5.0/config/.utshell_profile new file mode 100644 index 00000000..9b5294a5 --- /dev/null +++ b/utshell-0.5.0/config/.utshell_profile @@ -0,0 +1,12 @@ +# .utshell_profile + +# Get the aliases and functions +if [ -f ~/.utshellrc ]; then + . ~/.utshellrc +fi + +# User specific environment and startup programs + +PATH=$PATH:$HOME/bin + +export PATH diff --git a/utshell-0.5.0/config/.utshellrc b/utshell-0.5.0/config/.utshellrc new file mode 100644 index 00000000..deb8dfb0 --- /dev/null +++ b/utshell-0.5.0/config/.utshellrc @@ -0,0 +1,16 @@ +# .utshellrc + +# User specific aliases and functions + +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +# 设置历å²å‘½ä»¤ä¿å­˜åœ°å€ +export HISTFILE=~/.utshell_history + + +# Source global definitions +if [ -f /etc/utshellrc ]; then + . /etc/utshellrc +fi diff --git a/utshell-0.5.0/config/utshellrc b/utshell-0.5.0/config/utshellrc new file mode 100644 index 00000000..3c84ec9a --- /dev/null +++ b/utshell-0.5.0/config/utshellrc @@ -0,0 +1,98 @@ +# /etc/utshellrc + +# System wide functions and aliases +# Environment stuff goes in /etc/profile + +# It's NOT a good idea to change this file unless you know what you +# are doing. It's much better to create a custom.sh shell script in +# /etc/profile.d/ to make custom changes to your environment, as this +# will prevent the need for merging in future updates. + + +# Prevent doublesourcing +if [ -z "$BASHRCSOURCED" ]; then + BASHRCSOURCED="Y" + + # are we an interactive shell? + if [ "$PS1" ]; then + if [ -z "$PROMPT_COMMAND" ]; then + case $TERM in + xterm*|vte*) + if [ -e /etc/sysconfig/bash-prompt-xterm ]; then + PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm + else + PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"' + fi + ;; + screen*) + if [ -e /etc/sysconfig/bash-prompt-screen ]; then + PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen + else + PROMPT_COMMAND='printf "\033k%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"' + fi + ;; + *) + [ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default + ;; + esac + fi + # Turn on parallel history + shopt -s histappend + history -a + # Turn on checkwinsize + shopt -s checkwinsize + [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ " + # You might want to have e.g. tty in prompt (e.g. more virtual machines) + # and console windows + # If you want to do so, just add e.g. + # if [ "$PS1" ]; then + # PS1="[\u@\h:\l \W]\\$ " + # fi + # to your custom modification shell script in /etc/profile.d/ directory + fi + + if ! shopt -q login_shell ; then # We're not a login shell + # Need to redefine pathmunge, it gets undefined at the end of /etc/profile + pathmunge () { + case ":${PATH}:" in + *:"$1":*) + ;; + *) + if [ "$2" = "after" ] ; then + PATH=$PATH:$1 + else + PATH=$1:$PATH + fi + esac + } + + # By default, we want umask to get set. This sets it for non-login shell. + # Current threshold for system reserved uid/gids is 200 + # You could check uidgid reservation validity in + # /usr/share/doc/setup-*/uidgid file + if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then + umask 002 + else + umask 022 + fi + + SHELL=/bin/utshell + # Only display echos from profile.d scripts if we are no login shell + # and interactive - otherwise just process them to set envvars + for i in /etc/profile.d/*.sh; do + if [ -r "$i" ]; then + if [ "$PS1" ]; then + . "$i" + else + . "$i" >/dev/null + fi + fi + done + + unset i + unset -f pathmunge + fi + +fi +# vim:ts=4:sw=4 +if [ -n "$(lscpu | grep 'Cluster(s):')" ]; then NewLANG=`echo $LANG` && LANG=en_US.UTF-8 && NewLANGUAGE=`echo $LANGUAGE` && LANGUAGE=en_US && export OMP_NUM_THREADS=$[ `lscpu | grep "Cluster(s):" | awk -F": " '{print $2}'` * `lscpu | grep "Core(s) per cluster:" | awk -F": " '{print $2}'` * `lscpu | grep "Thread(s) per core:" | awk -F": " '{print $2}'`] && LANG=`echo $NewLANG` && unset NewLANG && unset $NewLANG && LANGUAGE=`echo $NewLANGUAGE` && unset NewLANGUAGE && unset $NewLANGUAGE;else NewLANG=`echo $LANG` && LANG=en_US.UTF-8 && NewLANGUAGE=`echo $LANGUAGE` && LANGUAGE=en_US && export OMP_NUM_THREADS=$[ `lscpu | grep "Socket(s):" | awk -F": " '{print $2}'` * `lscpu | grep "Core(s) per socket:" | awk -F ": " '{print $2}'` * `lscpu | grep "Thread(s) per core:" | awk -F": " '{print $2}'`] && LANG=`echo $NewLANG` && unset NewLANG && unset $NewLANG && LANGUAGE=`echo $NewLANGUAGE` && unset NewLANGUAGE && unset $NewLANGUAGE ;fi diff --git a/utshell-0.5.0/lib/Makefile b/utshell-0.5.0/lib/Makefile new file mode 100644 index 00000000..c2d0f0e7 --- /dev/null +++ b/utshell-0.5.0/lib/Makefile @@ -0,0 +1,26 @@ +all:libr2c.a + + +CC = gcc +AR = ar + +CFLAGS = -c -g +AFLAGS = -r + +OBJS = r2c.o + +SOURS = r2c.c + +LIBNAME = libr2c.a + +libr2c.a:$(OBJS) + $(AR) $(AFLAGS) libr2c.a $(OBJS) + +$(OBJS):$(SOURS) + $(CC) $(CFLAGS) $< -o $@ + +r2c.o:r2c.c + +.PHONY:clean +clean: + rm -rf *.o *.a diff --git a/utshell-0.5.0/lib/glob/Makefile b/utshell-0.5.0/lib/glob/Makefile new file mode 100644 index 00000000..e2664ae9 --- /dev/null +++ b/utshell-0.5.0/lib/glob/Makefile @@ -0,0 +1,167 @@ +## -*- text -*- #################################################### +# # +# Makefile for the GNU Glob Library. # +# # +#################################################################### +# +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = . + +topdir = ../include/ +BUILD_DIR = ../include + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CC = gcc +RANLIB = ranlib +AR = ar +ARFLAGS = cr +RM = rm -f +CP = cp +MV = mv + +SHELL = /bin/sh + +PROFILE_FLAGS = + +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security -fPIC + +LOCAL_CFLAGS = +CPPFLAGS = +LDFLAGS = -L./lib/termcap -rdynamic + +DEFS = -DHAVE_CONFIG_H +LOCAL_DEFS = -DSHELL + +BASHINCDIR = ${topdir} + +INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib + +CCFLAGS = $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) ${INCLUDES} $(CPPFLAGS) \ + $(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS} + +# Here is a rule for making .o files from .c files that doesn't force +# the type of the machine (like -sun3) into the flags. +.c.o: + $(RM) $@ + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libglob.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/glob.c $(srcdir)/strmatch.c $(srcdir)/smatch.c \ + $(srcdir)/xmbsrtowcs.c + +# The header files for this library. +HSOURCES = $(srcdir)/strmatch.h + +OBJECTS = glob.o strmatch.o smatch.o xmbsrtowcs.o gmisc.o + +# The texinfo files which document this library. +DOCSOURCE = doc/glob.texi +DOCOBJECT = doc/glob.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +###################################################################### + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +what-tar: + @for file in $(THINGS_TO_TAR); do \ + echo $(selfdir)$$file; \ + done + +documentation: force + -(cd doc; $(MAKE) $(MFLAGS)) +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + +clean: + rm -f $(OBJECTS) $(LIBRARY_NAME) + +realclean distclean maintainer-clean: clean + $(RM) -f Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +#${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile +# -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h ) + +###################################################################### +# # +# Dependencies for the object files which make up this library. # +# # +###################################################################### + +smatch.o: strmatch.h +smatch.o: $(BUILD_DIR)/config.h +smatch.o: $(BASHINCDIR)/chartypes.h +smatch.o: $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h +smatch.o: $(BASHINCDIR)/shmbutil.h +smatch.o: $(topdir)/xmalloc.h + +strmatch.o: strmatch.h +strmatch.o: $(BUILD_DIR)/config.h +strmatch.o: $(BASHINCDIR)/stdc.h + +glob.o: $(BUILD_DIR)/config.h +glob.o: $(topdir)/shell.h $(BUILD_DIR)/pathnames.h +glob.o: $(topdir)/bashtypes.h $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h +glob.o: $(BASHINCDIR)/posixstat.h $(BASHINCDIR)/memalloc.h +glob.o: strmatch.h glob.h +glob.o: $(BASHINCDIR)/shmbutil.h +glob.o: $(topdir)/xmalloc.h + +gmisc.o: $(BUILD_DIR)/config.h +gmisc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h +gmisc.o: $(BASHINCDIR)/shmbutil.h + +xmbsrtowcs.o: ${BUILD_DIR}/config.h +xmbsrtowcs.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +xmbsrtowcs.o: ${BASHINCDIR}/shmbutil.h + +# Rules for deficient makes, like SunOS and Solaris +glob.o: glob.c +gmisc.o: gmisc.c +strmatch.o: strmatch.c +smatch.o: smatch.c +xmbsrtowcs.o: xmbsrtowcs.c + +# dependencies for C files that include other C files +glob.o: glob_loop.c +gmisc.o: gm_loop.c +smatch.o: sm_loop.c diff --git a/utshell-0.5.0/lib/glob/Makefile.in b/utshell-0.5.0/lib/glob/Makefile.in new file mode 100644 index 00000000..1e745a1d --- /dev/null +++ b/utshell-0.5.0/lib/glob/Makefile.in @@ -0,0 +1,167 @@ +## -*- text -*- #################################################### +# # +# Makefile for the GNU Glob Library. # +# # +#################################################################### +# +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = @srcdir@ +VPATH = @srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv + +SHELL = @MAKE_SHELL@ + +PROFILE_FLAGS = @PROFILE_FLAGS@ + +CFLAGS = @CFLAGS@ + +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +BASHINCDIR = ${topdir}/include + +INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib + +CCFLAGS = $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) ${INCLUDES} $(CPPFLAGS) \ + $(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS} + +# Here is a rule for making .o files from .c files that doesn't force +# the type of the machine (like -sun3) into the flags. +.c.o: + $(RM) $@ + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libglob.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/glob.c $(srcdir)/strmatch.c $(srcdir)/smatch.c \ + $(srcdir)/xmbsrtowcs.c + +# The header files for this library. +HSOURCES = $(srcdir)/strmatch.h + +OBJECTS = glob.o strmatch.o smatch.o xmbsrtowcs.o gmisc.o + +# The texinfo files which document this library. +DOCSOURCE = doc/glob.texi +DOCOBJECT = doc/glob.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +###################################################################### + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +what-tar: + @for file in $(THINGS_TO_TAR); do \ + echo $(selfdir)$$file; \ + done + +documentation: force + -(cd doc; $(MAKE) $(MFLAGS)) +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + +clean: + rm -f $(OBJECTS) $(LIBRARY_NAME) + +realclean distclean maintainer-clean: clean + $(RM) -f Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile + -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h ) + +###################################################################### +# # +# Dependencies for the object files which make up this library. # +# # +###################################################################### + +smatch.o: strmatch.h +smatch.o: $(BUILD_DIR)/config.h +smatch.o: $(BASHINCDIR)/chartypes.h +smatch.o: $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h +smatch.o: $(BASHINCDIR)/shmbutil.h +smatch.o: $(topdir)/xmalloc.h + +strmatch.o: strmatch.h +strmatch.o: $(BUILD_DIR)/config.h +strmatch.o: $(BASHINCDIR)/stdc.h + +glob.o: $(BUILD_DIR)/config.h +glob.o: $(topdir)/shell.h $(BUILD_DIR)/pathnames.h +glob.o: $(topdir)/bashtypes.h $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h +glob.o: $(BASHINCDIR)/posixstat.h $(BASHINCDIR)/memalloc.h +glob.o: strmatch.h glob.h +glob.o: $(BASHINCDIR)/shmbutil.h +glob.o: $(topdir)/xmalloc.h + +gmisc.o: $(BUILD_DIR)/config.h +gmisc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/ansi_stdlib.h $(topdir)/bashansi.h +gmisc.o: $(BASHINCDIR)/shmbutil.h + +xmbsrtowcs.o: ${BUILD_DIR}/config.h +xmbsrtowcs.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +xmbsrtowcs.o: ${BASHINCDIR}/shmbutil.h + +# Rules for deficient makes, like SunOS and Solaris +glob.o: glob.c +gmisc.o: gmisc.c +strmatch.o: strmatch.c +smatch.o: smatch.c +xmbsrtowcs.o: xmbsrtowcs.c + +# dependencies for C files that include other C files +glob.o: glob_loop.c +gmisc.o: gm_loop.c +smatch.o: sm_loop.c diff --git a/utshell-0.5.0/lib/glob/collsyms.h b/utshell-0.5.0/lib/glob/collsyms.h new file mode 100644 index 00000000..d56df611 --- /dev/null +++ b/utshell-0.5.0/lib/glob/collsyms.h @@ -0,0 +1,140 @@ +/* collsyms.h -- collating symbol names and their corresponding characters + (in ascii) as given by POSIX.2 in table 2.8. */ + +/* Copyright (C) 1997-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* The upper-case letters, lower-case letters, and digits are omitted from + this table. The digits are not included in the table in the POSIX.2 + spec. The upper and lower case letters are translated by the code + in smatch.c:collsym(). */ + +typedef struct _COLLSYM { + XCHAR *name; + CHAR code; +} __COLLSYM; + +static __COLLSYM POSIXCOLL [] = +{ + { L("NUL"), L('\0') }, + { L("SOH"), L('\001') }, + { L("STX"), L('\002') }, + { L("ETX"), L('\003') }, + { L("EOT"), L('\004') }, + { L("ENQ"), L('\005') }, + { L("ACK"), L('\006') }, +#ifdef __STDC__ + { L("alert"), L('\a') }, +#else + { L("alert"), L('\007') }, +#endif + { L("BS"), L('\010') }, + { L("backspace"), L('\b') }, + { L("HT"), L('\011') }, + { L("tab"), L('\t') }, + { L("LF"), L('\012') }, + { L("newline"), L('\n') }, + { L("VT"), L('\013') }, + { L("vertical-tab"), L('\v') }, + { L("FF"), L('\014') }, + { L("form-feed"), L('\f') }, + { L("CR"), L('\015') }, + { L("carriage-return"), L('\r') }, + { L("SO"), L('\016') }, + { L("SI"), L('\017') }, + { L("DLE"), L('\020') }, + { L("DC1"), L('\021') }, + { L("DC2"), L('\022') }, + { L("DC3"), L('\023') }, + { L("DC4"), L('\024') }, + { L("NAK"), L('\025') }, + { L("SYN"), L('\026') }, + { L("ETB"), L('\027') }, + { L("CAN"), L('\030') }, + { L("EM"), L('\031') }, + { L("SUB"), L('\032') }, + { L("ESC"), L('\033') }, + { L("IS4"), L('\034') }, + { L("FS"), L('\034') }, + { L("IS3"), L('\035') }, + { L("GS"), L('\035') }, + { L("IS2"), L('\036') }, + { L("RS"), L('\036') }, + { L("IS1"), L('\037') }, + { L("US"), L('\037') }, + { L("space"), L(' ') }, + { L("exclamation-mark"), L('!') }, + { L("quotation-mark"), L('"') }, + { L("number-sign"), L('#') }, + { L("dollar-sign"), L('$') }, + { L("percent-sign"), L('%') }, + { L("ampersand"), L('&') }, + { L("apostrophe"), L('\'') }, + { L("left-parenthesis"), L('(') }, + { L("right-parenthesis"), L(')') }, + { L("asterisk"), L('*') }, + { L("plus-sign"), L('+') }, + { L("comma"), L(',') }, + { L("hyphen"), L('-') }, + { L("hyphen-minus"), L('-') }, + { L("minus"), L('-') }, /* extension from POSIX.2 */ + { L("dash"), L('-') }, /* extension from POSIX.2 */ + { L("period"), L('.') }, + { L("full-stop"), L('.') }, + { L("slash"), L('/') }, + { L("solidus"), L('/') }, /* extension from POSIX.2 */ + { L("zero"), L('0') }, + { L("one"), L('1') }, + { L("two"), L('2') }, + { L("three"), L('3') }, + { L("four"), L('4') }, + { L("five"), L('5') }, + { L("six"), L('6') }, + { L("seven"), L('7') }, + { L("eight"), L('8') }, + { L("nine"), L('9') }, + { L("colon"), L(':') }, + { L("semicolon"), L(';') }, + { L("less-than-sign"), L('<') }, + { L("equals-sign"), L('=') }, + { L("greater-than-sign"), L('>') }, + { L("question-mark"), L('?') }, + { L("commercial-at"), L('@') }, + /* upper-case letters omitted */ + { L("left-square-bracket"), L('[') }, + { L("backslash"), L('\\') }, + { L("reverse-solidus"), L('\\') }, + { L("right-square-bracket"), L(']') }, + { L("circumflex"), L('^') }, + { L("circumflex-accent"), L('^') }, /* extension from POSIX.2 */ + { L("underscore"), L('_') }, + { L("grave-accent"), L('`') }, + /* lower-case letters omitted */ + { L("left-brace"), L('{') }, /* extension from POSIX.2 */ + { L("left-curly-bracket"), L('{') }, + { L("vertical-line"), L('|') }, + { L("right-brace"), L('}') }, /* extension from POSIX.2 */ + { L("right-curly-bracket"), L('}') }, + { L("tilde"), L('~') }, + { L("DEL"), L('\177') }, + { 0, 0 }, +}; + +#undef _COLLSYM +#undef __COLLSYM +#undef POSIXCOLL diff --git a/utshell-0.5.0/lib/glob/doc/Makefile b/utshell-0.5.0/lib/glob/doc/Makefile new file mode 100644 index 00000000..8dca6067 --- /dev/null +++ b/utshell-0.5.0/lib/glob/doc/Makefile @@ -0,0 +1,5 @@ +all: + cp glob.texi glob.info + +clean distclean mostlyclean maintainer-clean: + rm -f glob.?? glob.info diff --git a/utshell-0.5.0/lib/glob/doc/glob.texi b/utshell-0.5.0/lib/glob/doc/glob.texi new file mode 100644 index 00000000..0262ef11 --- /dev/null +++ b/utshell-0.5.0/lib/glob/doc/glob.texi @@ -0,0 +1 @@ +Nothing happens here. diff --git a/utshell-0.5.0/lib/glob/glob.c b/utshell-0.5.0/lib/glob/glob.c new file mode 100644 index 00000000..eb6277f0 --- /dev/null +++ b/utshell-0.5.0/lib/glob/glob.c @@ -0,0 +1,1554 @@ +/* glob.c -- file-name wildcard pattern matching for Bash. + + Copyright (C) 1985-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* To whomever it may concern: I have never seen the code which most + Unix programs use to perform this function. I wrote this from scratch + based on specifications for the pattern matching. --RMS. */ + +#include + +#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX) + #pragma alloca +#endif /* _AIX && RISC6000 && !__GNUC__ */ + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "bashansi.h" +#include "posixdir.h" +#include "posixstat.h" +#include "shmbutil.h" +#include "xmalloc.h" + +#include "filecntl.h" +#if !defined (F_OK) +# define F_OK 0 +#endif + +#include "stdc.h" +#include "memalloc.h" + +#include + +#include "shell.h" +#include "general.h" + +#include "glob.h" +#include "strmatch.h" + +#if !defined (HAVE_BCOPY) && !defined (bcopy) +# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n))) +#endif /* !HAVE_BCOPY && !bcopy */ + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* __STDC__ */ +#endif /* !NULL */ + +#if !defined (FREE) +# define FREE(x) if (x) free (x) +#endif + +/* Don't try to alloca() more than this much memory for `struct globval' + in glob_vector() */ +#ifndef ALLOCA_MAX +# define ALLOCA_MAX 100000 +#endif + +struct globval + { + struct globval *next; + char *name; + }; + +extern void throw_to_top_level PARAMS((void)); +extern int sh_eaccess PARAMS((const char *, int)); +extern char *sh_makepath PARAMS((const char *, const char *, int)); +extern int signal_is_pending PARAMS((int)); +extern void run_pending_traps PARAMS((void)); + +extern int extended_glob; + +/* Global variable which controls whether or not * matches .*. + Non-zero means don't match .*. */ +int noglob_dot_filenames = 1; + +/* Global variable which controls whether or not filename globbing + is done without regard to case. */ +int glob_ignore_case = 0; + +/* Global variable controlling whether globbing ever returns . or .. + regardless of the pattern. If set to 1, no glob pattern will ever + match `.' or `..'. Disabled by default. */ +int glob_always_skip_dot_and_dotdot = 0; + +/* Global variable to return to signify an error in globbing. */ +char *glob_error_return; + +static struct globval finddirs_error_return; + +/* Some forward declarations. */ +static int skipname PARAMS((char *, char *, int)); +#if HANDLE_MULTIBYTE +static int mbskipname PARAMS((char *, char *, int)); +#endif +void udequote_pathname PARAMS((char *)); +#if HANDLE_MULTIBYTE +void wcdequote_pathname PARAMS((wchar_t *)); +static void wdequote_pathname PARAMS((char *)); +#else +# define dequote_pathname udequote_pathname +#endif +static void dequote_pathname PARAMS((char *)); +static int glob_testdir PARAMS((char *, int)); +static char **glob_dir_to_array PARAMS((char *, char **, int)); + +/* Make sure these names continue to agree with what's in smatch.c */ +extern char *glob_patscan PARAMS((char *, char *, int)); +extern wchar_t *glob_patscan_wc PARAMS((wchar_t *, wchar_t *, int)); + +/* And this from gmisc.c/gm_loop.c */ +extern int wextglob_pattern_p PARAMS((wchar_t *)); + +extern char *glob_dirscan PARAMS((char *, int)); + +/* Compile `glob_loop.c' for single-byte characters. */ +#define GCHAR unsigned char +#define CHAR char +#define INT int +#define L(CS) CS +#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p +#include "glob_loop.c" + +/* Compile `glob_loop.c' again for multibyte characters. */ +#if HANDLE_MULTIBYTE + +#define GCHAR wchar_t +#define CHAR wchar_t +#define INT wint_t +#define L(CS) L##CS +#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p +#include "glob_loop.c" + +#endif /* HANDLE_MULTIBYTE */ + +/* And now a function that calls either the single-byte or multibyte version + of internal_glob_pattern_p. */ +int +glob_pattern_p (pattern) + const char *pattern; +{ +#if HANDLE_MULTIBYTE + size_t n; + wchar_t *wpattern; + int r; + + if (MB_CUR_MAX == 1 || mbsmbchar (pattern) == 0) + return (internal_glob_pattern_p ((unsigned char *)pattern)); + + /* Convert strings to wide chars, and call the multibyte version. */ + n = xdupmbstowcs (&wpattern, NULL, pattern); + if (n == (size_t)-1) + /* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */ + return (internal_glob_pattern_p ((unsigned char *)pattern)); + + r = internal_glob_wpattern_p (wpattern); + free (wpattern); + + return r; +#else + return (internal_glob_pattern_p ((unsigned char *)pattern)); +#endif +} + +#if EXTENDED_GLOB +/* Return 1 if all subpatterns in the extended globbing pattern PAT indicate + that the name should be skipped. XXX - doesn't handle pattern negation, + not sure if it should */ +static int +extglob_skipname (pat, dname, flags) + char *pat, *dname; + int flags; +{ + char *pp, *pe, *t, *se; + int n, r, negate, wild, nullpat; + + negate = *pat == '!'; + wild = *pat == '*' || *pat == '?'; + pp = pat + 2; + se = pp + strlen (pp) - 1; /* end of string */ + pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */ + /* we should check for invalid extglob pattern here */ + if (pe == 0) + return 0; + + /* if pe != se we have more of the pattern at the end of the extglob + pattern. Check the easy case first ( */ + if (pe == se && *pe == ')' && (t = strchr (pp, '|')) == 0) + { + *pe = '\0'; +#if defined (HANDLE_MULTIBYTE) + r = mbskipname (pp, dname, flags); +#else + r = skipname (pp, dname, flags); /*(*/ +#endif + *pe = ')'; + if (wild && pe[1]) /* if we can match zero instances, check further */ + return (skipname (pe+1, dname, flags)); + return r; + } + + /* Is the extglob pattern between the parens the null pattern? The null + pattern can match nothing, so should we check any remaining portion of + the pattern? */ + nullpat = pe >= (pat + 2) && pe[-2] == '(' && pe[-1] == ')'; + + /* check every subpattern */ + while (t = glob_patscan (pp, pe, '|')) + { + n = t[-1]; /* ( */ + if (extglob_pattern_p (pp) && n == ')') + t[-1] = n; /* no-op for now */ + else + t[-1] = '\0'; +#if defined (HANDLE_MULTIBYTE) + r = mbskipname (pp, dname, flags); +#else + r = skipname (pp, dname, flags); +#endif + t[-1] = n; + if (r == 0) /* if any pattern says not skip, we don't skip */ + return r; + pp = t; + } /*(*/ + + /* glob_patscan might find end of string */ + if (pp == se) + return r; + + /* but if it doesn't then we didn't match a leading dot */ + if (wild && *pe) /* if we can match zero instances, check further */ + return (skipname (pe, dname, flags)); + return 1; +} +#endif + +/* Return 1 if DNAME should be skipped according to PAT. Mostly concerned + with matching leading `.'. */ +static int +skipname (pat, dname, flags) + char *pat; + char *dname; + int flags; +{ +#if EXTENDED_GLOB + if (extglob_pattern_p (pat)) /* XXX */ + return (extglob_skipname (pat, dname, flags)); +#endif + + if (glob_always_skip_dot_and_dotdot && DOT_OR_DOTDOT (dname)) + return 1; + + /* If a leading dot need not be explicitly matched, and the pattern + doesn't start with a `.', don't match `.' or `..' */ + if (noglob_dot_filenames == 0 && pat[0] != '.' && + (pat[0] != '\\' || pat[1] != '.') && + DOT_OR_DOTDOT (dname)) + return 1; + + /* If a dot must be explicitly matched, check to see if they do. */ + else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' && + (pat[0] != '\\' || pat[1] != '.')) + return 1; + + return 0; +} + +#if HANDLE_MULTIBYTE + +static int +wskipname (pat, dname, flags) + wchar_t *pat, *dname; + int flags; +{ + if (glob_always_skip_dot_and_dotdot && WDOT_OR_DOTDOT (dname)) + return 1; + + /* If a leading dot need not be explicitly matched, and the + pattern doesn't start with a `.', don't match `.' or `..' */ + if (noglob_dot_filenames == 0 && pat[0] != L'.' && + (pat[0] != L'\\' || pat[1] != L'.') && + WDOT_OR_DOTDOT (dname)) + return 1; + + /* If a leading dot must be explicitly matched, check to see if the + pattern and dirname both have one. */ + else if (noglob_dot_filenames && dname[0] == L'.' && + pat[0] != L'.' && + (pat[0] != L'\\' || pat[1] != L'.')) + return 1; + + return 0; +} + +static int +wextglob_skipname (pat, dname, flags) + wchar_t *pat, *dname; + int flags; +{ +#if EXTENDED_GLOB + wchar_t *pp, *pe, *t, n, *se; + int r, negate, wild, nullpat; + + negate = *pat == L'!'; + wild = *pat == L'*' || *pat == L'?'; + pp = pat + 2; + se = pp + wcslen (pp) - 1; /*(*/ + pe = glob_patscan_wc (pp, se, 0); + + if (pe == se && *pe == ')' && (t = wcschr (pp, L'|')) == 0) + { + *pe = L'\0'; + r = wskipname (pp, dname, flags); /*(*/ + *pe = L')'; + if (wild && pe[1] != L'\0') + return (wskipname (pe+1, dname, flags)); + return r; + } + + /* Is the extglob pattern between the parens the null pattern? The null + pattern can match nothing, so should we check any remaining portion of + the pattern? */ + nullpat = pe >= (pat + 2) && pe[-2] == L'(' && pe[-1] == L')'; + + /* check every subpattern */ + while (t = glob_patscan_wc (pp, pe, '|')) + { + n = t[-1]; /* ( */ + if (wextglob_pattern_p (pp) && n == L')') + t[-1] = n; /* no-op for now */ + else + t[-1] = L'\0'; + r = wskipname (pp, dname, flags); + t[-1] = n; + if (r == 0) + return 0; + pp = t; + } + + if (pp == pe) /* glob_patscan_wc might find end of pattern */ + return r; + + /* but if it doesn't then we didn't match a leading dot */ + if (wild && *pe != L'\0') + return (wskipname (pe, dname, flags)); + return 1; +#else + return (wskipname (pat, dname, flags)); +#endif +} + +/* Return 1 if DNAME should be skipped according to PAT. Handles multibyte + characters in PAT and DNAME. Mostly concerned with matching leading `.'. */ +static int +mbskipname (pat, dname, flags) + char *pat, *dname; + int flags; +{ + int ret, ext; + wchar_t *pat_wc, *dn_wc; + size_t pat_n, dn_n; + + if (mbsmbchar (dname) == 0 && mbsmbchar (pat) == 0) + return (skipname (pat, dname, flags)); + + ext = 0; +#if EXTENDED_GLOB + ext = extglob_pattern_p (pat); +#endif + + pat_wc = dn_wc = (wchar_t *)NULL; + + pat_n = xdupmbstowcs (&pat_wc, NULL, pat); + if (pat_n != (size_t)-1) + dn_n = xdupmbstowcs (&dn_wc, NULL, dname); + + ret = 0; + if (pat_n != (size_t)-1 && dn_n !=(size_t)-1) + ret = ext ? wextglob_skipname (pat_wc, dn_wc, flags) : wskipname (pat_wc, dn_wc, flags); + else + ret = skipname (pat, dname, flags); + + FREE (pat_wc); + FREE (dn_wc); + + return ret; +} +#endif /* HANDLE_MULTIBYTE */ + +/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */ +void +udequote_pathname (pathname) + char *pathname; +{ + register int i, j; + + for (i = j = 0; pathname && pathname[i]; ) + { + if (pathname[i] == '\\') + i++; + + pathname[j++] = pathname[i++]; + + if (pathname[i - 1] == 0) + break; + } + if (pathname) + pathname[j] = '\0'; +} + +#if HANDLE_MULTIBYTE +/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */ +void +wcdequote_pathname (wpathname) + wchar_t *wpathname; +{ + int i, j; + + for (i = j = 0; wpathname && wpathname[i]; ) + { + if (wpathname[i] == L'\\') + i++; + + wpathname[j++] = wpathname[i++]; + + if (wpathname[i - 1] == L'\0') + break; + } + if (wpathname) + wpathname[j] = L'\0'; +} + +static void +wdequote_pathname (pathname) + char *pathname; +{ + mbstate_t ps; + size_t len, n; + wchar_t *wpathname; + int i, j; + wchar_t *orig_wpathname; + + if (mbsmbchar (pathname) == 0) + { + udequote_pathname (pathname); + return; + } + + len = strlen (pathname); + /* Convert the strings into wide characters. */ + n = xdupmbstowcs (&wpathname, NULL, pathname); + if (n == (size_t) -1) + { + /* Something wrong. Fall back to single-byte */ + udequote_pathname (pathname); + return; + } + orig_wpathname = wpathname; + + wcdequote_pathname (wpathname); + + /* Convert the wide character string into unibyte character set. */ + memset (&ps, '\0', sizeof(mbstate_t)); + n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps); + if (n == (size_t)-1 || (wpathname && *wpathname != 0)) /* what? now you tell me? */ + { + wpathname = orig_wpathname; + memset (&ps, '\0', sizeof(mbstate_t)); + n = xwcsrtombs (pathname, (const wchar_t **)&wpathname, len, &ps); + } + pathname[len] = '\0'; + + /* Can't just free wpathname here; wcsrtombs changes it in many cases. */ + free (orig_wpathname); +} + +static void +dequote_pathname (pathname) + char *pathname; +{ + if (MB_CUR_MAX > 1) + wdequote_pathname (pathname); + else + udequote_pathname (pathname); +} +#endif /* HANDLE_MULTIBYTE */ + +/* Test whether NAME exists. */ + +#if defined (HAVE_LSTAT) +# define GLOB_TESTNAME(name) (lstat (name, &finfo)) +#else /* !HAVE_LSTAT */ +# if !defined (AFS) +# define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK)) +# else /* AFS */ +# define GLOB_TESTNAME(name) (access (name, F_OK)) +# endif /* AFS */ +#endif /* !HAVE_LSTAT */ + +/* Return 0 if DIR is a directory, -2 if DIR is a symlink, -1 otherwise. */ +static int +glob_testdir (dir, flags) + char *dir; + int flags; +{ + struct stat finfo; + int r; + +/*itrace("glob_testdir: testing %s" flags = %d, dir, flags);*/ +#if defined (HAVE_LSTAT) + r = (flags & GX_ALLDIRS) ? lstat (dir, &finfo) : stat (dir, &finfo); +#else + r = stat (dir, &finfo); +#endif + if (r < 0) + return (-1); + +#if defined (S_ISLNK) + if (S_ISLNK (finfo.st_mode)) + return (-2); +#endif + + if (S_ISDIR (finfo.st_mode) == 0) + return (-1); + + return (0); +} + +/* Recursively scan SDIR for directories matching PAT (PAT is always `**'). + FLAGS is simply passed down to the recursive call to glob_vector. Returns + a list of matching directory names. EP, if non-null, is set to the last + element of the returned list. NP, if non-null, is set to the number of + directories in the returned list. These two variables exist for the + convenience of the caller (always glob_vector). */ +static struct globval * +finddirs (pat, sdir, flags, ep, np) + char *pat; + char *sdir; + int flags; + struct globval **ep; + int *np; +{ + char **r, *n; + int ndirs; + struct globval *ret, *e, *g; + +/*itrace("finddirs: pat = `%s' sdir = `%s' flags = 0x%x", pat, sdir, flags);*/ + e = ret = 0; + r = glob_vector (pat, sdir, flags); + if (r == 0 || r[0] == 0) + { + if (np) + *np = 0; + if (ep) + *ep = 0; + if (r && r != &glob_error_return) + free (r); + return (struct globval *)0; + } + for (ndirs = 0; r[ndirs] != 0; ndirs++) + { + g = (struct globval *) malloc (sizeof (struct globval)); + if (g == 0) + { + while (ret) /* free list built so far */ + { + g = ret->next; + free (ret); + ret = g; + } + + free (r); + if (np) + *np = 0; + if (ep) + *ep = 0; + return (&finddirs_error_return); + } + if (e == 0) + e = g; + + g->next = ret; + ret = g; + + g->name = r[ndirs]; + } + + free (r); + if (ep) + *ep = e; + if (np) + *np = ndirs; + + return ret; +} + +/* Return a vector of names of files in directory DIR + whose names match glob pattern PAT. + The names are not in any particular order. + Wildcards at the beginning of PAT do not match an initial period. + + The vector is terminated by an element that is a null pointer. + + To free the space allocated, first free the vector's elements, + then free the vector. + + Return 0 if cannot get enough memory to hold the pointer + and the names. + + Return -1 if cannot access directory DIR. + Look in errno for more information. */ + +char ** +glob_vector (pat, dir, flags) + char *pat; + char *dir; + int flags; +{ + DIR *d; + register struct dirent *dp; + struct globval *lastlink, *e, *dirlist; + register struct globval *nextlink; + register char *nextname, *npat, *subdir; + unsigned int count; + int lose, skip, ndirs, isdir, sdlen, add_current, patlen; + register char **name_vector; + register unsigned int i; + int mflags; /* Flags passed to strmatch (). */ + int pflags; /* flags passed to sh_makepath () */ + int hasglob; /* return value from glob_pattern_p */ + int nalloca; + struct globval *firstmalloc, *tmplink; + char *convfn; + + lastlink = 0; + count = lose = skip = add_current = 0; + + firstmalloc = 0; + nalloca = 0; + + name_vector = NULL; + +/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/ + /* If PAT is empty, skip the loop, but return one (empty) filename. */ + if (pat == 0 || *pat == '\0') + { + if (glob_testdir (dir, 0) < 0) + return ((char **) &glob_error_return); + + nextlink = (struct globval *)alloca (sizeof (struct globval)); + if (nextlink == NULL) + return ((char **) NULL); + + nextlink->next = (struct globval *)0; + nextname = (char *) malloc (1); + if (nextname == 0) + lose = 1; + else + { + lastlink = nextlink; + nextlink->name = nextname; + nextname[0] = '\0'; + count = 1; + } + + skip = 1; + } + + patlen = (pat && *pat) ? strlen (pat) : 0; + + /* If the filename pattern (PAT) does not contain any globbing characters, + or contains a pattern with only backslash escapes (hasglob == 2), + we can dispense with reading the directory, and just see if there is + a filename `DIR/PAT'. If there is, and we can access it, just make the + vector to return and bail immediately. */ + hasglob = 0; + if (skip == 0 && ((hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2)) + { + int dirlen; + struct stat finfo; + + if (glob_testdir (dir, 0) < 0) + return ((char **) &glob_error_return); + + dirlen = strlen (dir); + nextname = (char *)malloc (dirlen + patlen + 2); + npat = (char *)malloc (patlen + 1); + if (nextname == 0 || npat == 0) + { + FREE (nextname); + FREE (npat); + lose = 1; + } + else + { + strcpy (npat, pat); + dequote_pathname (npat); + + strcpy (nextname, dir); + nextname[dirlen++] = '/'; + strcpy (nextname + dirlen, npat); + + if (GLOB_TESTNAME (nextname) >= 0) + { + free (nextname); + nextlink = (struct globval *)alloca (sizeof (struct globval)); + if (nextlink) + { + nextlink->next = (struct globval *)0; + lastlink = nextlink; + nextlink->name = npat; + count = 1; + } + else + { + free (npat); + lose = 1; + } + } + else + { + free (nextname); + free (npat); + } + } + + skip = 1; + } + + if (skip == 0) + { + /* Open the directory, punting immediately if we cannot. If opendir + is not robust (i.e., it opens non-directories successfully), test + that DIR is a directory and punt if it's not. */ +#if defined (OPENDIR_NOT_ROBUST) + if (glob_testdir (dir, 0) < 0) + return ((char **) &glob_error_return); +#endif + + d = opendir (dir); + if (d == NULL) + return ((char **) &glob_error_return); + + /* Compute the flags that will be passed to strmatch(). We don't + need to do this every time through the loop. */ + mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME; + +#ifdef FNM_CASEFOLD + if (glob_ignore_case) + mflags |= FNM_CASEFOLD; +#endif + + if (extended_glob) + mflags |= FNM_EXTMATCH; + + add_current = ((flags & (GX_ALLDIRS|GX_ADDCURDIR)) == (GX_ALLDIRS|GX_ADDCURDIR)); + + /* Scan the directory, finding all names that match. + For each name that matches, allocate a struct globval + on the stack and store the name in it. + Chain those structs together; lastlink is the front of the chain. */ + while (1) + { + /* Make globbing interruptible in the shell. */ + if (interrupt_state || terminating_signal) + { + lose = 1; + break; + } + else if (signal_is_pending (SIGINT)) /* XXX - make SIGINT traps responsive */ + { + lose = 1; + break; + } + + dp = readdir (d); + if (dp == NULL) + break; + + /* If this directory entry is not to be used, try again. */ + if (REAL_DIR_ENTRY (dp) == 0) + continue; + +#if 0 + if (dp->d_name == 0 || *dp->d_name == 0) + continue; +#endif + +#if HANDLE_MULTIBYTE + if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name, flags)) + continue; + else +#endif + if (skipname (pat, dp->d_name, flags)) + continue; + + /* If we're only interested in directories, don't bother with files */ + if (flags & (GX_MATCHDIRS|GX_ALLDIRS)) + { + pflags = (flags & GX_ALLDIRS) ? MP_RMDOT : 0; + if (flags & GX_NULLDIR) + pflags |= MP_IGNDOT; + subdir = sh_makepath (dir, dp->d_name, pflags); + isdir = glob_testdir (subdir, flags); + if (isdir < 0 && (flags & GX_MATCHDIRS)) + { + free (subdir); + continue; + } + } + + if (flags & GX_ALLDIRS) + { + if (isdir == 0) + { + dirlist = finddirs (pat, subdir, (flags & ~GX_ADDCURDIR), &e, &ndirs); + if (dirlist == &finddirs_error_return) + { + free (subdir); + lose = 1; + break; + } + if (ndirs) /* add recursive directories to list */ + { + if (firstmalloc == 0) + firstmalloc = e; + e->next = lastlink; + lastlink = dirlist; + count += ndirs; + } + } + + /* XXX - should we even add this if it's not a directory? */ + nextlink = (struct globval *) malloc (sizeof (struct globval)); + if (firstmalloc == 0) + firstmalloc = nextlink; + sdlen = strlen (subdir); + nextname = (char *) malloc (sdlen + 1); + if (nextlink == 0 || nextname == 0) + { + FREE (nextlink); + FREE (nextname); + free (subdir); + lose = 1; + break; + } + nextlink->next = lastlink; + lastlink = nextlink; + nextlink->name = nextname; + bcopy (subdir, nextname, sdlen + 1); + free (subdir); + ++count; + continue; + } + else if (flags & GX_MATCHDIRS) + free (subdir); + + convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp)); + if (strmatch (pat, convfn, mflags) != FNM_NOMATCH) + { + if (nalloca < ALLOCA_MAX) + { + nextlink = (struct globval *) alloca (sizeof (struct globval)); + nalloca += sizeof (struct globval); + } + else + { + nextlink = (struct globval *) malloc (sizeof (struct globval)); + if (firstmalloc == 0) + firstmalloc = nextlink; + } + + nextname = (char *) malloc (D_NAMLEN (dp) + 1); + if (nextlink == 0 || nextname == 0) + { + FREE (nextlink); + FREE (nextname); + lose = 1; + break; + } + nextlink->next = lastlink; + lastlink = nextlink; + nextlink->name = nextname; + bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1); + ++count; + } + } + + (void) closedir (d); + } + + /* compat: if GX_ADDCURDIR, add the passed directory also. Add an empty + directory name as a placeholder if GX_NULLDIR (in which case the passed + directory name is "."). */ + if (add_current) + { + sdlen = strlen (dir); + nextname = (char *)malloc (sdlen + 1); + nextlink = (struct globval *) malloc (sizeof (struct globval)); + if (nextlink == 0 || nextname == 0) + { + FREE (nextlink); + FREE (nextname); + lose = 1; + } + else + { + nextlink->name = nextname; + nextlink->next = lastlink; + lastlink = nextlink; + if (flags & GX_NULLDIR) + nextname[0] = '\0'; + else + bcopy (dir, nextname, sdlen + 1); + ++count; + } + } + + if (lose == 0) + { + name_vector = (char **) malloc ((count + 1) * sizeof (char *)); + lose |= name_vector == NULL; + } + + /* Have we run out of memory? */ + if (lose) + { + tmplink = 0; + + /* Here free the strings we have got. */ + while (lastlink) + { + /* Since we build the list in reverse order, the first N entries + will be allocated with malloc, if firstmalloc is set, from + lastlink to firstmalloc. */ + if (firstmalloc) + { + if (lastlink == firstmalloc) + firstmalloc = 0; + tmplink = lastlink; + } + else + tmplink = 0; + free (lastlink->name); + lastlink = lastlink->next; + FREE (tmplink); + } + + /* Don't call QUIT; here; let higher layers deal with it. */ + + return ((char **)NULL); + } + + /* Copy the name pointers from the linked list into the vector. */ + for (tmplink = lastlink, i = 0; i < count; ++i) + { + name_vector[i] = tmplink->name; + tmplink = tmplink->next; + } + + name_vector[count] = NULL; + + /* If we allocated some of the struct globvals, free them now. */ + if (firstmalloc) + { + tmplink = 0; + while (lastlink) + { + tmplink = lastlink; + if (lastlink == firstmalloc) + lastlink = firstmalloc = 0; + else + lastlink = lastlink->next; + free (tmplink); + } + } + + return (name_vector); +} + +/* Return a new array which is the concatenation of each string in ARRAY + to DIR. This function expects you to pass in an allocated ARRAY, and + it takes care of free()ing that array. Thus, you might think of this + function as side-effecting ARRAY. This should handle GX_MARKDIRS. */ +static char ** +glob_dir_to_array (dir, array, flags) + char *dir, **array; + int flags; +{ + register unsigned int i, l; + int add_slash; + char **result, *new; + struct stat sb; + + l = strlen (dir); + if (l == 0) + { + if (flags & GX_MARKDIRS) + for (i = 0; array[i]; i++) + { + if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode)) + { + l = strlen (array[i]); + new = (char *)realloc (array[i], l + 2); + if (new == 0) + return NULL; + new[l] = '/'; + new[l+1] = '\0'; + array[i] = new; + } + } + return (array); + } + + add_slash = dir[l - 1] != '/'; + + i = 0; + while (array[i] != NULL) + ++i; + + result = (char **) malloc ((i + 1) * sizeof (char *)); + if (result == NULL) + return (NULL); + + for (i = 0; array[i] != NULL; i++) + { + /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */ + result[i] = (char *) malloc (l + strlen (array[i]) + 3); + + if (result[i] == NULL) + { + int ind; + for (ind = 0; ind < i; ind++) + free (result[ind]); + free (result); + return (NULL); + } + + strcpy (result[i], dir); + if (add_slash) + result[i][l] = '/'; + if (array[i][0]) + { + strcpy (result[i] + l + add_slash, array[i]); + if (flags & GX_MARKDIRS) + { + if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode)) + { + size_t rlen; + rlen = strlen (result[i]); + result[i][rlen] = '/'; + result[i][rlen+1] = '\0'; + } + } + } + else + result[i][l+add_slash] = '\0'; + } + result[i] = NULL; + + /* Free the input array. */ + for (i = 0; array[i] != NULL; i++) + free (array[i]); + free ((char *) array); + + return (result); +} + +/* Do globbing on PATHNAME. Return an array of pathnames that match, + marking the end of the array with a null-pointer as an element. + If no pathnames match, then the array is empty (first element is null). + If there isn't enough memory, then return NULL. + If a file system error occurs, return -1; `errno' has the error code. */ +char ** +glob_filename (pathname, flags) + char *pathname; + int flags; +{ + char **result, **new_result; + unsigned int result_size; + char *directory_name, *filename, *dname, *fn; + unsigned int directory_len; + int free_dirname; /* flag */ + int dflags, hasglob; + + result = (char **) malloc (sizeof (char *)); + result_size = 1; + if (result == NULL) + return (NULL); + + result[0] = NULL; + + directory_name = NULL; + + /* Find the filename. */ + filename = strrchr (pathname, '/'); +#if defined (EXTENDED_GLOB) + if (filename && extended_glob) + { + fn = glob_dirscan (pathname, '/'); +#if DEBUG_MATCHING + if (fn != filename) + fprintf (stderr, "glob_filename: glob_dirscan: fn (%s) != filename (%s)\n", fn ? fn : "(null)", filename); +#endif + filename = fn; + } +#endif + + if (filename == NULL) + { + filename = pathname; + directory_name = ""; + directory_len = 0; + free_dirname = 0; + } + else + { + directory_len = (filename - pathname) + 1; + directory_name = (char *) malloc (directory_len + 1); + + if (directory_name == 0) /* allocation failed? */ + { + free (result); + return (NULL); + } + + bcopy (pathname, directory_name, directory_len); + directory_name[directory_len] = '\0'; + ++filename; + free_dirname = 1; + } + + hasglob = 0; + /* If directory_name contains globbing characters, then we + have to expand the previous levels. Just recurse. + If glob_pattern_p returns != [0,1] we have a pattern that has backslash + quotes but no unquoted glob pattern characters. We dequote it below. */ + if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1) + { + char **directories, *d, *p; + register unsigned int i; + int all_starstar, last_starstar; + + all_starstar = last_starstar = 0; + d = directory_name; + dflags = flags & ~GX_MARKDIRS; + /* Collapse a sequence of ** patterns separated by one or more slashes + to a single ** terminated by a slash or NUL */ + if ((flags & GX_GLOBSTAR) && d[0] == '*' && d[1] == '*' && (d[2] == '/' || d[2] == '\0')) + { + p = d; + while (d[0] == '*' && d[1] == '*' && (d[2] == '/' || d[2] == '\0')) + { + p = d; + if (d[2]) + { + d += 3; + while (*d == '/') + d++; + if (*d == 0) + break; + } + } + if (*d == 0) + all_starstar = 1; + d = p; + dflags |= GX_ALLDIRS|GX_ADDCURDIR; + directory_len = strlen (d); + } + + /* If there is a non [star][star]/ component in directory_name, we + still need to collapse trailing sequences of [star][star]/ into + a single one and note that the directory name ends with [star][star], + so we can compensate if filename is [star][star] */ + if ((flags & GX_GLOBSTAR) && all_starstar == 0) + { + int dl, prev; + prev = dl = directory_len; + while (dl >= 4 && d[dl - 1] == '/' && + d[dl - 2] == '*' && + d[dl - 3] == '*' && + d[dl - 4] == '/') + prev = dl, dl -= 3; + if (dl != directory_len) + last_starstar = 1; + directory_len = prev; + } + + /* If the directory name ends in [star][star]/ but the filename is + [star][star], just remove the final [star][star] from the directory + so we don't have to scan everything twice. */ + if (last_starstar && directory_len > 4 && + filename[0] == '*' && filename[1] == '*' && filename[2] == 0) + { + directory_len -= 3; + } + + if (d[directory_len - 1] == '/') + d[directory_len - 1] = '\0'; + + directories = glob_filename (d, dflags|GX_RECURSE); + + if (free_dirname) + { + free (directory_name); + directory_name = NULL; + } + + if (directories == NULL) + goto memory_error; + else if (directories == (char **)&glob_error_return) + { + free ((char *) result); + return ((char **) &glob_error_return); + } + else if (*directories == NULL) + { + free ((char *) directories); + free ((char *) result); + return ((char **) &glob_error_return); + } + + /* If we have something like [star][star]/[star][star], it's no use to + glob **, then do it again, and throw half the results away. */ + if (all_starstar && filename[0] == '*' && filename[1] == '*' && filename[2] == 0) + { + free ((char *) directories); + free (directory_name); + directory_name = NULL; + directory_len = 0; + goto only_filename; + } + + /* We have successfully globbed the preceding directory name. + For each name in DIRECTORIES, call glob_vector on it and + FILENAME. Concatenate the results together. */ + for (i = 0; directories[i] != NULL; ++i) + { + char **temp_results; + int shouldbreak; + + shouldbreak = 0; + /* XXX -- we've recursively scanned any directories resulting from + a `**', so turn off the flag. We turn it on again below if + filename is `**' */ + /* Scan directory even on a NULL filename. That way, `*h/' + returns only directories ending in `h', instead of all + files ending in `h' with a `/' appended. */ + dname = directories[i]; + dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR); + /* last_starstar? */ + if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') + dflags |= GX_ALLDIRS|GX_ADDCURDIR; + if (dname[0] == '\0' && filename[0]) + { + dflags |= GX_NULLDIR; + dname = "."; /* treat null directory name and non-null filename as current directory */ + } + + /* Special handling for symlinks to directories with globstar on */ + if (all_starstar && (dflags & GX_NULLDIR) == 0) + { + int dlen; + + /* If we have a directory name that is not null (GX_NULLDIR above) + and is a symlink to a directory, we return the symlink if + we're not `descending' into it (filename[0] == 0) and return + glob_error_return (which causes the code below to skip the + name) otherwise. I should fold this into a test that does both + checks instead of calling stat twice. */ + if (glob_testdir (dname, flags|GX_ALLDIRS) == -2 && glob_testdir (dname, 0) == 0) + { + if (filename[0] != 0) + temp_results = (char **)&glob_error_return; /* skip */ + else + { + /* Construct array to pass to glob_dir_to_array */ + temp_results = (char **)malloc (2 * sizeof (char *)); + if (temp_results == NULL) + goto memory_error; + temp_results[0] = (char *)malloc (1); + if (temp_results[0] == 0) + { + free (temp_results); + goto memory_error; + } + **temp_results = '\0'; + temp_results[1] = NULL; + dflags |= GX_SYMLINK; /* mostly for debugging */ + } + } + else + temp_results = glob_vector (filename, dname, dflags); + } + else + temp_results = glob_vector (filename, dname, dflags); + + /* Handle error cases. */ + if (temp_results == NULL) + goto memory_error; + else if (temp_results == (char **)&glob_error_return) + /* This filename is probably not a directory. Ignore it. */ + ; + else + { + char **array; + register unsigned int l; + + /* If we're expanding **, we don't need to glue the directory + name to the results; we've already done it in glob_vector */ + if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && (filename[2] == '\0' || filename[2] == '/')) + { + /* When do we remove null elements from temp_results? And + how to avoid duplicate elements in the final result? */ + /* If (dflags & GX_NULLDIR) glob_filename potentially left a + NULL placeholder in the temp results just in case + glob_vector/glob_dir_to_array did something with it, but + if it didn't, and we're not supposed to be passing them + through for some reason ((flags & GX_NULLDIR) == 0) we + need to remove all the NULL elements from the beginning + of TEMP_RESULTS. */ + /* If we have a null directory name and ** as the filename, + we have just searched for everything from the current + directory on down. Break now (shouldbreak = 1) to avoid + duplicate entries in the final result. */ +#define NULL_PLACEHOLDER(x) ((x) && *(x) && **(x) == 0) + if ((dflags & GX_NULLDIR) && (flags & GX_NULLDIR) == 0 && + NULL_PLACEHOLDER (temp_results)) +#undef NULL_PLACEHOLDER + { + register int i, n; + for (n = 0; temp_results[n] && *temp_results[n] == 0; n++) + ; + i = n; + do + temp_results[i - n] = temp_results[i]; + while (temp_results[i++] != 0); + array = temp_results; + shouldbreak = 1; + } + else + array = temp_results; + } + else if (dflags & GX_SYMLINK) + array = glob_dir_to_array (directories[i], temp_results, flags); + else + array = glob_dir_to_array (directories[i], temp_results, flags); + l = 0; + while (array[l] != NULL) + ++l; + + new_result = (char **)realloc (result, (result_size + l) * sizeof (char *)); + + if (new_result == NULL) + { + for (l = 0; array[l]; ++l) + free (array[l]); + free ((char *)array); + goto memory_error; + } + result = new_result; + + for (l = 0; array[l] != NULL; ++l) + result[result_size++ - 1] = array[l]; + + result[result_size - 1] = NULL; + + /* Note that the elements of ARRAY are not freed. */ + if (array != temp_results) + free ((char *) array); + else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') + free (temp_results); /* expanding ** case above */ + + if (shouldbreak) + break; + } + } + /* Free the directories. */ + for (i = 0; directories[i]; i++) + free (directories[i]); + + free ((char *) directories); + + return (result); + } + +only_filename: + /* If there is only a directory name, return it. */ + if (*filename == '\0') + { + result = (char **) realloc ((char *) result, 2 * sizeof (char *)); + if (result == NULL) + { + if (free_dirname) + free (directory_name); + return (NULL); + } + /* If we have a directory name with quoted characters, and we are + being called recursively to glob the directory portion of a pathname, + we need to dequote the directory name before returning it so the + caller can read the directory */ + if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) != 0) + { + dequote_pathname (directory_name); + directory_len = strlen (directory_name); + } + + /* We could check whether or not the dequoted directory_name is a + directory and return it here, returning the original directory_name + if not, but we don't do that. We do return the dequoted directory + name if we're not being called recursively and the dequoted name + corresponds to an actual directory. For better backwards compatibility, + we can return &glob_error_return unconditionally in this case. */ + + if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0) + { + dequote_pathname (directory_name); + if (glob_testdir (directory_name, 0) < 0) + { + if (free_dirname) + free (directory_name); + return ((char **)&glob_error_return); + } + } + + /* Handle GX_MARKDIRS here. */ + result[0] = (char *) malloc (directory_len + 1); + if (result[0] == NULL) + goto memory_error; + bcopy (directory_name, result[0], directory_len + 1); + if (free_dirname) + free (directory_name); + result[1] = NULL; + return (result); + } + else + { + char **temp_results; + + /* There are no unquoted globbing characters in DIRECTORY_NAME. + Dequote it before we try to open the directory since there may + be quoted globbing characters which should be treated verbatim. */ + if (directory_len > 0) + dequote_pathname (directory_name); + + /* We allocated a small array called RESULT, which we won't be using. + Free that memory now. */ + free (result); + + /* Just return what glob_vector () returns appended to the + directory name. */ + /* If flags & GX_ALLDIRS, we're called recursively */ + dflags = flags & ~GX_MARKDIRS; + if (directory_len == 0) + dflags |= GX_NULLDIR; + if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') + { + dflags |= GX_ALLDIRS|GX_ADDCURDIR; +#if 0 + /* If we want all directories (dflags & GX_ALLDIRS) and we're not + being called recursively as something like `echo [star][star]/[star].o' + ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from + adding a null directory name to the front of the temp_results + array. We turn off ADDCURDIR if not called recursively and + dlen == 0 */ +#endif + if (directory_len == 0 && (flags & GX_ALLDIRS) == 0) + dflags &= ~GX_ADDCURDIR; + } + temp_results = glob_vector (filename, + (directory_len == 0 ? "." : directory_name), + dflags); + + if (temp_results == NULL || temp_results == (char **)&glob_error_return) + { + if (free_dirname) + free (directory_name); + QUIT; /* XXX - shell */ + run_pending_traps (); + return (temp_results); + } + + result = glob_dir_to_array ((dflags & GX_ALLDIRS) ? "" : directory_name, temp_results, flags); + + if (free_dirname) + free (directory_name); + return (result); + } + + /* We get to memory_error if the program has run out of memory, or + if this is the shell, and we have been interrupted. */ + memory_error: + if (result != NULL) + { + register unsigned int i; + for (i = 0; result[i] != NULL; ++i) + free (result[i]); + free ((char *) result); + } + + if (free_dirname && directory_name) + free (directory_name); + + QUIT; + run_pending_traps (); + + return (NULL); +} + +#if defined (TEST) + +main (argc, argv) + int argc; + char **argv; +{ + unsigned int i; + + for (i = 1; i < argc; ++i) + { + char **value = glob_filename (argv[i], 0); + if (value == NULL) + puts ("Out of memory."); + else if (value == &glob_error_return) + perror (argv[i]); + else + for (i = 0; value[i] != NULL; i++) + puts (value[i]); + } + + exit (0); +} +#endif /* TEST. */ diff --git a/utshell-0.5.0/lib/glob/glob.h b/utshell-0.5.0/lib/glob/glob.h new file mode 100644 index 00000000..ca3a66cf --- /dev/null +++ b/utshell-0.5.0/lib/glob/glob.h @@ -0,0 +1,46 @@ +/* File-name wildcard pattern matching for GNU. + Copyright (C) 1985-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include "stdc.h" + +#define GX_MARKDIRS 0x001 /* mark directory names with trailing `/' */ +#define GX_NOCASE 0x002 /* ignore case */ +#define GX_MATCHDOT 0x004 /* match `.' literally */ +#define GX_MATCHDIRS 0x008 /* match only directory names */ +#define GX_ALLDIRS 0x010 /* match all directory names, no others */ +#define GX_NULLDIR 0x100 /* internal -- no directory preceding pattern */ +#define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */ +#define GX_GLOBSTAR 0x400 /* turn on special handling of ** */ +#define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */ +#define GX_SYMLINK 0x1000 /* internal -- symlink to a directory */ + +extern int glob_pattern_p PARAMS((const char *)); +extern char **glob_vector PARAMS((char *, char *, int)); +extern char **glob_filename PARAMS((char *, int)); + +extern int extglob_pattern_p PARAMS((const char *)); + +extern char *glob_error_return; +extern int noglob_dot_filenames; +extern int glob_ignore_case; + +#endif /* _GLOB_H_ */ diff --git a/utshell-0.5.0/lib/glob/glob_loop.c b/utshell-0.5.0/lib/glob/glob_loop.c new file mode 100644 index 00000000..467e7ae3 --- /dev/null +++ b/utshell-0.5.0/lib/glob/glob_loop.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +static int INTERNAL_GLOB_PATTERN_P PARAMS((const GCHAR *)); + +/* Return nonzero if PATTERN has any special globbing chars in it. + Compiled twice, once each for single-byte and multibyte characters. */ +static int +INTERNAL_GLOB_PATTERN_P (pattern) + const GCHAR *pattern; +{ + register const GCHAR *p; + register GCHAR c; + int bopen, bsquote; + + p = pattern; + bopen = bsquote = 0; + + while ((c = *p++) != L('\0')) + switch (c) + { + case L('?'): + case L('*'): + return 1; + + case L('['): /* Only accept an open brace if there is a close */ + bopen++; /* brace to match it. Bracket expressions must be */ + continue; /* complete, according to Posix.2 */ + case L(']'): + if (bopen) + return 1; + continue; + + case L('+'): /* extended matching operators */ + case L('@'): + case L('!'): + if (*p == L('(')) /*) */ + return 1; + continue; + + case L('\\'): + /* Don't let the pattern end in a backslash (GMATCH returns no match + if the pattern ends in a backslash anyway), but otherwise note that + we have seen this, since the matching engine uses backslash as an + escape character and it can be removed. We return 2 later if we + have seen only backslash-escaped characters, so interested callers + know they can shortcut and just dequote the pathname. */ + if (*p != L('\0')) + { + p++; + bsquote = 1; + continue; + } + else /* (*p == L('\0')) */ + return 0; + } + +#if 0 + return bsquote ? 2 : 0; +#else + return (0); +#endif +} + +#undef INTERNAL_GLOB_PATTERN_P +#undef L +#undef INT +#undef CHAR +#undef GCHAR diff --git a/utshell-0.5.0/lib/glob/gm_loop.c b/utshell-0.5.0/lib/glob/gm_loop.c new file mode 100644 index 00000000..ac516f82 --- /dev/null +++ b/utshell-0.5.0/lib/glob/gm_loop.c @@ -0,0 +1,208 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if EXTENDED_GLOB +int +EXTGLOB_PATTERN_P (pat) + const CHAR *pat; +{ + switch (pat[0]) + { + case L('*'): + case L('+'): + case L('!'): + case L('@'): + case L('?'): + return (pat[1] == L('(')); /* ) */ + default: + return 0; + } + + return 0; +} +#endif + +/* Return 1 of the first character of STRING could match the first + character of pattern PAT. Compiled to both single and wiide character + versions. FLAGS is a subset of strmatch flags; used to do case-insensitive + matching for now. */ +int +MATCH_PATTERN_CHAR (pat, string, flags) + CHAR *pat, *string; + int flags; +{ + CHAR c; + + if (*string == 0) + return (*pat == L('*')); /* XXX - allow only * to match empty string */ + + switch (c = *pat++) + { + default: + return (FOLD(*string) == FOLD(c)); + case L('\\'): + return (FOLD(*string) == FOLD(*pat)); + case L('?'): + return (*pat == L('(') ? 1 : (*string != L'\0')); + case L('*'): + return (1); + case L('+'): + case L('!'): + case L('@'): + return (*pat == L('(') ? 1 : (FOLD(*string) == FOLD(c))); + case L('['): + return (*string != L('\0')); + } +} + +int +MATCHLEN (pat, max) + CHAR *pat; + size_t max; +{ + CHAR c; + int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; + + if (*pat == 0) + return (0); + + matlen = in_cclass = in_collsym = in_equiv = 0; + while (c = *pat++) + { + switch (c) + { + default: + matlen++; + break; + case L('\\'): + if (*pat == 0) + return ++matlen; + else + { + matlen++; + pat++; + } + break; + case L('?'): + if (*pat == LPAREN) + return (matlen = -1); /* XXX for now */ + else + matlen++; + break; + case L('*'): + return (matlen = -1); + case L('+'): + case L('!'): + case L('@'): + if (*pat == LPAREN) + return (matlen = -1); /* XXX for now */ + else + matlen++; + break; + case L('['): + /* scan for ending `]', skipping over embedded [:...:] */ + bracklen = 1; + c = *pat++; + do + { + if (c == 0) + { + pat--; /* back up to NUL */ + matlen += bracklen; + goto bad_bracket; + } + else if (c == L('\\')) + { + /* *pat == backslash-escaped character */ + bracklen++; + /* If the backslash or backslash-escape ends the string, + bail. The ++pat skips over the backslash escape */ + if (*pat == 0 || *++pat == 0) + { + matlen += bracklen; + goto bad_bracket; + } + } + else if (c == L('[') && *pat == L(':')) /* character class */ + { + pat++; + bracklen++; + in_cclass = 1; + } + else if (in_cclass && c == L(':') && *pat == L(']')) + { + pat++; + bracklen++; + in_cclass = 0; + } + else if (c == L('[') && *pat == L('.')) /* collating symbol */ + { + pat++; + bracklen++; + if (*pat == L(']')) /* right bracket can appear as collating symbol */ + { + pat++; + bracklen++; + } + in_collsym = 1; + } + else if (in_collsym && c == L('.') && *pat == L(']')) + { + pat++; + bracklen++; + in_collsym = 0; + } + else if (c == L('[') && *pat == L('=')) /* equivalence class */ + { + pat++; + bracklen++; + if (*pat == L(']')) /* right bracket can appear as equivalence class */ + { + pat++; + bracklen++; + } + in_equiv = 1; + } + else if (in_equiv && c == L('=') && *pat == L(']')) + { + pat++; + bracklen++; + in_equiv = 0; + } + else + bracklen++; + } + while ((c = *pat++) != L(']')); + matlen++; /* bracket expression can only match one char */ +bad_bracket: + break; + } + } + + return matlen; +} + +#undef EXTGLOB_PATTERN_P +#undef MATCH_PATTERN_CHAR +#undef MATCHLEN +#undef FOLD +#undef L +#undef LPAREN +#undef RPAREN +#undef INT +#undef CHAR diff --git a/utshell-0.5.0/lib/glob/gmisc.c b/utshell-0.5.0/lib/glob/gmisc.c new file mode 100644 index 00000000..f3d74cea --- /dev/null +++ b/utshell-0.5.0/lib/glob/gmisc.c @@ -0,0 +1,108 @@ +/* gmisc.c -- miscellaneous pattern matching utility functions for Bash. + + Copyright (C) 2010-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "bashansi.h" +#include "shmbutil.h" +#include "chartypes.h" + +#include "stdc.h" + +#ifndef FNM_CASEFOLD +# include "strmatch.h" +#endif +#include "glob.h" + +/* Make sure these names continue to agree with what's in smatch.c */ +extern char *glob_patscan PARAMS((char *, char *, int)); + +/* Compile `gm_loop.c' for single-byte characters. */ +#define CHAR char +#define INT int +#define L(CS) CS +#define EXTGLOB_PATTERN_P extglob_pattern_p +#define MATCH_PATTERN_CHAR match_pattern_char +#define MATCHLEN umatchlen +#define FOLD(c) ((flags & FNM_CASEFOLD) \ + ? TOLOWER ((unsigned char)c) \ + : ((unsigned char)c)) +#ifndef LPAREN +#define LPAREN '(' +#define RPAREN ')' +#endif +#include "gm_loop.c" + +/* Compile `gm_loop.c' again for multibyte characters. */ +#if HANDLE_MULTIBYTE + +#define CHAR wchar_t +#define INT wint_t +#define L(CS) L##CS +#define EXTGLOB_PATTERN_P wextglob_pattern_p +#define MATCH_PATTERN_CHAR match_pattern_wchar +#define MATCHLEN wmatchlen + +#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c)) +#define LPAREN L'(' +#define RPAREN L')' +#include "gm_loop.c" + +#endif /* HANDLE_MULTIBYTE */ + + +#if defined (EXTENDED_GLOB) +/* Skip characters in PAT and return the final occurrence of DIRSEP. This + is only called when extended_glob is set, so we have to skip over extglob + patterns x(...) */ +char * +glob_dirscan (pat, dirsep) + char *pat; + int dirsep; +{ + char *p, *d, *pe, *se; + + d = pe = se = 0; + for (p = pat; p && *p; p++) + { + if (extglob_pattern_p (p)) + { + if (se == 0) + se = p + strlen (p) - 1; + pe = glob_patscan (p + 2, se, 0); + if (pe == 0) + continue; + else if (*pe == 0) + break; + p = pe - 1; /* will do increment above */ + continue; + } + if (*p == dirsep) + d = p; + } + return d; +} +#endif /* EXTENDED_GLOB */ diff --git a/utshell-0.5.0/lib/glob/ndir.h b/utshell-0.5.0/lib/glob/ndir.h new file mode 100644 index 00000000..31261eb0 --- /dev/null +++ b/utshell-0.5.0/lib/glob/ndir.h @@ -0,0 +1,50 @@ +/* -- definitions for 4.2BSD-compatible directory access. + last edit: 09-Jul-1983 D A Gwyn. */ + +#if defined (VMS) +# if !defined (FAB$C_BID) +# include +# endif +# if !defined (NAM$C_BID) +# include +# endif +# if !defined (RMS$_SUC) +# include +# endif +# include "dir.h" +#endif /* VMS */ + +/* Size of directory block. */ +#define DIRBLKSIZ 512 + +/* NOTE: MAXNAMLEN must be one less than a multiple of 4 */ + +#if defined (VMS) +# define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */ +# define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */ +#else +# define MAXNAMLEN 15 /* Maximum filename length. */ +#endif /* VMS */ + +/* Data from readdir (). */ +struct direct { + long d_ino; /* Inode number of entry. */ + unsigned short d_reclen; /* Length of this record. */ + unsigned short d_namlen; /* Length of string in d_name. */ + char d_name[MAXNAMLEN + 1]; /* Name of file. */ +}; + +/* Stream data from opendir (). */ +typedef struct { + int dd_fd; /* File descriptor. */ + int dd_loc; /* Offset in block. */ + int dd_size; /* Amount of valid data. */ + char dd_buf[DIRBLKSIZ]; /* Directory block. */ +} DIR; + +extern DIR *opendir (); +extern struct direct *readdir (); +extern long telldir (); +extern void seekdir (), closedir (); + +#define rewinddir(dirp) seekdir (dirp, 0L) diff --git a/utshell-0.5.0/lib/glob/sm_loop.c b/utshell-0.5.0/lib/glob/sm_loop.c new file mode 100644 index 00000000..a98c14bd --- /dev/null +++ b/utshell-0.5.0/lib/glob/sm_loop.c @@ -0,0 +1,942 @@ +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +struct STRUCT +{ + CHAR *pattern; + CHAR *string; +}; + +int FCT PARAMS((CHAR *, CHAR *, int)); + +static int GMATCH PARAMS((CHAR *, CHAR *, CHAR *, CHAR *, struct STRUCT *, int)); +static CHAR *PARSE_COLLSYM PARAMS((CHAR *, INT *)); +static CHAR *BRACKMATCH PARAMS((CHAR *, U_CHAR, int)); +static int EXTMATCH PARAMS((INT, CHAR *, CHAR *, CHAR *, CHAR *, int)); + +extern void DEQUOTE_PATHNAME PARAMS((CHAR *)); + +/*static*/ CHAR *PATSCAN PARAMS((CHAR *, CHAR *, INT)); + +int +FCT (pattern, string, flags) + CHAR *pattern; + CHAR *string; + int flags; +{ + CHAR *se, *pe; + + if (string == 0 || pattern == 0) + return FNM_NOMATCH; + + se = string + STRLEN ((XCHAR *)string); + pe = pattern + STRLEN ((XCHAR *)pattern); + + return (GMATCH (string, se, pattern, pe, (struct STRUCT *)NULL, flags)); +} + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, FNM_NOMATCH if not. */ +static int +GMATCH (string, se, pattern, pe, ends, flags) + CHAR *string, *se; + CHAR *pattern, *pe; + struct STRUCT *ends; + int flags; +{ + CHAR *p, *n; /* pattern, string */ + INT c; /* current pattern character - XXX U_CHAR? */ + INT sc; /* current string character - XXX U_CHAR? */ + + p = pattern; + n = string; + + if (string == 0 || pattern == 0) + return FNM_NOMATCH; + +#if DEBUG_MATCHING +fprintf(stderr, "gmatch: string = %s; se = %s\n", string, se); +fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe); +#endif + + while (p < pe) + { + c = *p++; + c = FOLD (c); + + sc = n < se ? *n : '\0'; + +#ifdef EXTENDED_GLOB + /* EXTMATCH () will handle recursively calling GMATCH, so we can + just return what EXTMATCH() returns. */ + if ((flags & FNM_EXTMATCH) && *p == L('(') && + (c == L('+') || c == L('*') || c == L('?') || c == L('@') || c == L('!'))) /* ) */ + { + int lflags; + /* If we're not matching the start of the string, we're not + concerned about the special cases for matching `.' */ + lflags = (n == string) ? flags : (flags & ~FNM_PERIOD); + return (EXTMATCH (c, n, se, p, pe, lflags)); + } +#endif /* EXTENDED_GLOB */ + + switch (c) + { + case L('?'): /* Match single character */ + if (sc == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_PATHNAME) && sc == L('/')) + /* If we are matching a pathname, `?' can never match a `/'. */ + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && sc == L('.') && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/')))) + /* `?' cannot match a `.' if it is the first character of the + string or if it is the first character following a slash and + we are matching a pathname. */ + return FNM_NOMATCH; + break; + + case L('\\'): /* backslash escape removes special meaning */ + if (p == pe && sc == '\\' && (n+1 == se)) + break; + + if (p == pe) + return FNM_NOMATCH; + + if ((flags & FNM_NOESCAPE) == 0) + { + c = *p++; + /* A trailing `\' cannot match. */ + if (p > pe) + return FNM_NOMATCH; + c = FOLD (c); + } + if (FOLD (sc) != (U_CHAR)c) + return FNM_NOMATCH; + break; + + case L('*'): /* Match zero or more characters */ + /* See below for the reason for using this. It avoids backtracking + back to a previous `*'. Picked up from glibc. */ + if (ends != NULL) + { + ends->pattern = p - 1; + ends->string = n; + return (0); + } + + if ((flags & FNM_PERIOD) && sc == L('.') && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/')))) + /* `*' cannot match a `.' if it is the first character of the + string or if it is the first character following a slash and + we are matching a pathname. */ + return FNM_NOMATCH; + + if (p == pe) + return 0; + + /* Collapse multiple consecutive `*' and `?', but make sure that + one character of the string is consumed for each `?'. */ + for (c = *p++; (c == L('?') || c == L('*')); c = *p++) + { + if ((flags & FNM_PATHNAME) && sc == L('/')) + /* A slash does not match a wildcard under FNM_PATHNAME. */ + return FNM_NOMATCH; +#ifdef EXTENDED_GLOB + else if ((flags & FNM_EXTMATCH) && c == L('?') && *p == L('(')) /* ) */ + { + CHAR *newn; + + /* We can match 0 or 1 times. If we match, return success */ + if (EXTMATCH (c, n, se, p, pe, flags) == 0) + return (0); + + /* We didn't match the extended glob pattern, but + that's OK, since we can match 0 or 1 occurrences. + We need to skip the glob pattern and see if we + match the rest of the string. */ + newn = PATSCAN (p + 1, pe, 0); + /* If NEWN is 0, we have an ill-formed pattern. */ + p = newn ? newn : pe; + } +#endif + else if (c == L('?')) + { + if (sc == L('\0')) + return FNM_NOMATCH; + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + fewer than three characters. */ + n++; + sc = n < se ? *n : '\0'; + } + +#ifdef EXTENDED_GLOB + /* Handle ******(patlist) */ + if ((flags & FNM_EXTMATCH) && c == L('*') && *p == L('(')) /*)*/ + { + CHAR *newn; + /* We need to check whether or not the extended glob + pattern matches the remainder of the string. + If it does, we match the entire pattern. */ + for (newn = n; newn < se; ++newn) + { + if (EXTMATCH (c, newn, se, p, pe, flags) == 0) + return (0); + } + /* We didn't match the extended glob pattern, but + that's OK, since we can match 0 or more occurrences. + We need to skip the glob pattern and see if we + match the rest of the string. */ + newn = PATSCAN (p + 1, pe, 0); + /* If NEWN is 0, we have an ill-formed pattern. */ + p = newn ? newn : pe; + } +#endif + if (p == pe) + break; + } + + /* The wildcards are the last element of the pattern. The name + cannot match completely if we are looking for a pathname and + it contains another slash, unless FNM_LEADING_DIR is set. */ + if (c == L('\0')) + { + int r = (flags & FNM_PATHNAME) == 0 ? 0 : FNM_NOMATCH; + if (flags & FNM_PATHNAME) + { + if (flags & FNM_LEADING_DIR) + r = 0; + else if (MEMCHR (n, L('/'), se - n) == NULL) + r = 0; + } + return r; + } + + /* If we've hit the end of the pattern and the last character of + the pattern was handled by the loop above, we've succeeded. + Otherwise, we need to match that last character. */ + if (p == pe && (c == L('?') || c == L('*'))) + return (0); + + /* If we've hit the end of the string and the rest of the pattern + is something that matches the empty string, we can succeed. */ +#if defined (EXTENDED_GLOB) + if (n == se && ((flags & FNM_EXTMATCH) && (c == L('!') || c == L('?')) && *p == L('('))) + { + --p; + if (EXTMATCH (c, n, se, p, pe, flags) == 0) + return (c == L('!') ? FNM_NOMATCH : 0); + return (c == L('!') ? 0 : FNM_NOMATCH); + } +#endif + + /* If we stop at a slash in the pattern and we are looking for a + pathname ([star]/foo), then consume enough of the string to stop + at any slash and then try to match the rest of the pattern. If + the string doesn't contain a slash, fail */ + if (c == L('/') && (flags & FNM_PATHNAME)) + { + while (n < se && *n != L('/')) + ++n; + if (n < se && *n == L('/') && (GMATCH (n+1, se, p, pe, NULL, flags) == 0)) + return 0; + return FNM_NOMATCH; /* XXX */ + } + + /* General case, use recursion. */ + { + U_CHAR c1; + const CHAR *endp; + struct STRUCT end; + + end.pattern = NULL; + endp = MEMCHR (n, (flags & FNM_PATHNAME) ? L('/') : L('\0'), se - n); + if (endp == 0) + endp = se; + + c1 = ((flags & FNM_NOESCAPE) == 0 && c == L('\\')) ? *p : c; + c1 = FOLD (c1); + for (--p; n < endp; ++n) + { + /* Only call strmatch if the first character indicates a + possible match. We can check the first character if + we're not doing an extended glob match. */ + if ((flags & FNM_EXTMATCH) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/ + continue; + + /* If we're doing an extended glob match and the pattern is not + one of the extended glob patterns, we can check the first + character. */ + if ((flags & FNM_EXTMATCH) && p[1] != L('(') && /*)*/ + STRCHR (L("?*+@!"), *p) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/ + continue; + + /* Otherwise, we just recurse. */ + if (GMATCH (n, se, p, pe, &end, flags & ~FNM_PERIOD) == 0) + { + if (end.pattern == NULL) + return (0); + break; + } + } + /* This is a clever idea from glibc, used to avoid backtracking + to a `*' that appears earlier in the pattern. We get away + without saving se and pe because they are always the same, + even in the recursive calls to gmatch */ + if (end.pattern != NULL) + { + p = end.pattern; + n = end.string; + continue; + } + + return FNM_NOMATCH; + } + + case L('['): + { + if (sc == L('\0') || n == se) + return FNM_NOMATCH; + + /* A character class cannot match a `.' if it is the first + character of the string or if it is the first character + following a slash and we are matching a pathname. */ + if ((flags & FNM_PERIOD) && sc == L('.') && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/')))) + return (FNM_NOMATCH); + + p = BRACKMATCH (p, sc, flags); + if (p == 0) + return FNM_NOMATCH; + } + break; + + default: + if ((U_CHAR)c != FOLD (sc)) + return (FNM_NOMATCH); + } + + ++n; + } + + if (n == se) + return (0); + + if ((flags & FNM_LEADING_DIR) && *n == L('/')) + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return (FNM_NOMATCH); +} + +/* Parse a bracket expression collating symbol ([.sym.]) starting at P, find + the value of the symbol, and move P past the collating symbol expression. + The value is returned in *VP, if VP is not null. */ +static CHAR * +PARSE_COLLSYM (p, vp) + CHAR *p; + INT *vp; +{ + register int pc; + INT val; + + p++; /* move past the `.' */ + + for (pc = 0; p[pc]; pc++) + if (p[pc] == L('.') && p[pc+1] == L(']')) + break; + if (p[pc] == 0) + { + if (vp) + *vp = INVALID; + return (p + pc); + } + val = COLLSYM (p, pc); + if (vp) + *vp = val; + return (p + pc + 2); +} + +/* Use prototype definition here because of type promotion. */ +static CHAR * +#if defined (PROTOTYPES) +BRACKMATCH (CHAR *p, U_CHAR test, int flags) +#else +BRACKMATCH (p, test, flags) + CHAR *p; + U_CHAR test; + int flags; +#endif +{ + register CHAR cstart, cend, c; + register int not; /* Nonzero if the sense of the character class is inverted. */ + int brcnt, forcecoll, isrange; + INT pc; + CHAR *savep; + CHAR *brchrp; + U_CHAR orig_test; + + orig_test = test; + test = FOLD (orig_test); + + savep = p; + + /* POSIX.2 3.13.1 says that an exclamation mark (`!') shall replace the + circumflex (`^') in its role in a `nonmatching list'. A bracket + expression starting with an unquoted circumflex character produces + unspecified results. This implementation treats the two identically. */ + if (not = (*p == L('!') || *p == L('^'))) + ++p; + + c = *p++; + for (;;) + { + /* Initialize cstart and cend in case `-' is the last + character of the pattern. */ + cstart = cend = c; + forcecoll = 0; + + /* POSIX.2 equivalence class: [=c=]. See POSIX.2 2.8.3.2. Find + the end of the equivalence class, move the pattern pointer past + it, and check for equivalence. XXX - this handles only + single-character equivalence classes, which is wrong, or at + least incomplete. */ + if (c == L('[') && *p == L('=') && p[2] == L('=') && p[3] == L(']')) + { + pc = FOLD (p[1]); + p += 4; + if (COLLEQUIV (test, pc)) + { +/*[*/ /* Move past the closing `]', since the first thing we do at + the `matched:' label is back p up one. */ + p++; + goto matched; + } + else + { + c = *p++; + if (c == L('\0')) + return ((test == L('[')) ? savep : (CHAR *)0); /*]*/ + c = FOLD (c); + continue; + } + } + + /* POSIX.2 character class expression. See POSIX.2 2.8.3.2. */ + if (c == L('[') && *p == L(':')) + { + CHAR *close, *ccname; + + pc = 0; /* make sure invalid char classes don't match. */ + /* Find end of character class name */ + for (close = p + 1; *close != '\0'; close++) + if (*close == L(':') && *(close+1) == L(']')) + break; + + if (*close != L('\0')) + { + ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR)); + if (ccname == 0) + pc = 0; + else + { + bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR)); + *(ccname + (close - p - 1)) = L('\0'); + /* As a result of a POSIX discussion, char class names are + allowed to be quoted (?) */ + DEQUOTE_PATHNAME (ccname); + pc = IS_CCLASS (orig_test, (XCHAR *)ccname); + } + if (pc == -1) + { + /* CCNAME is not a valid character class in the current + locale. In addition to noting no match (pc = 0), we have + a choice about what to do with the invalid charclass. + Posix leaves the behavior unspecified, but we're going + to skip over the charclass and keep going instead of + testing ORIG_TEST against each character in the class + string. If we don't want to do that, take out the update + of P. */ + pc = 0; + p = close + 2; + } + else + p = close + 2; /* move past the closing `]' */ + + free (ccname); + } + + if (pc) + { +/*[*/ /* Move past the closing `]', since the first thing we do at + the `matched:' label is back p up one. */ + p++; + goto matched; + } + else + { + /* continue the loop here, since this expression can't be + the first part of a range expression. */ + c = *p++; + if (c == L('\0')) + return ((test == L('[')) ? savep : (CHAR *)0); + else if (c == L(']')) + break; + c = FOLD (c); + continue; + } + } + + /* POSIX.2 collating symbols. See POSIX.2 2.8.3.2. Find the end of + the symbol name, make sure it is terminated by `.]', translate + the name to a character using the external table, and do the + comparison. */ + if (c == L('[') && *p == L('.')) + { + p = PARSE_COLLSYM (p, &pc); + /* An invalid collating symbol cannot be the first point of a + range. If it is, we set cstart to one greater than `test', + so any comparisons later will fail. */ + cstart = (pc == INVALID) ? test + 1 : pc; + forcecoll = 1; + } + + if (!(flags & FNM_NOESCAPE) && c == L('\\')) + { + if (*p == '\0') + return (CHAR *)0; + cstart = cend = *p++; + } + + cstart = cend = FOLD (cstart); + isrange = 0; + + /* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that + is not preceded by a backslash and is not part of a bracket + expression produces undefined results.' This implementation + treats the `[' as just a character to be matched if there is + not a closing `]'. */ + if (c == L('\0')) + return ((test == L('[')) ? savep : (CHAR *)0); + + c = *p++; + c = FOLD (c); + + if (c == L('\0')) + return ((test == L('[')) ? savep : (CHAR *)0); + + if ((flags & FNM_PATHNAME) && c == L('/')) + /* [/] can never match when matching a pathname. */ + return (CHAR *)0; + + /* This introduces a range, unless the `-' is the last + character of the class. Find the end of the range + and move past it. */ + if (c == L('-') && *p != L(']')) + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == L('\\')) + cend = *p++; + if (cend == L('\0')) + return (CHAR *)0; + if (cend == L('[') && *p == L('.')) + { + p = PARSE_COLLSYM (p, &pc); + /* An invalid collating symbol cannot be the second part of a + range expression. If we get one, we set cend to one fewer + than the test character to make sure the range test fails. */ + cend = (pc == INVALID) ? test - 1 : pc; + forcecoll = 1; + } + cend = FOLD (cend); + + c = *p++; + + /* POSIX.2 2.8.3.2: ``The ending range point shall collate + equal to or higher than the starting range point; otherwise + the expression shall be treated as invalid.'' Note that this + applies to only the range expression; the rest of the bracket + expression is still checked for matches. */ + if (RANGECMP (cstart, cend, forcecoll) > 0) + { + if (c == L(']')) + break; + c = FOLD (c); + continue; + } + isrange = 1; + } + + if (isrange == 0 && test == cstart) + goto matched; + if (isrange && RANGECMP (test, cstart, forcecoll) >= 0 && RANGECMP (test, cend, forcecoll) <= 0) + goto matched; + + if (c == L(']')) + break; + } + /* No match. */ + return (!not ? (CHAR *)0 : p); + +matched: + /* Skip the rest of the [...] that already matched. */ + c = *--p; + brcnt = 1; + brchrp = 0; + while (brcnt > 0) + { + int oc; + + /* A `[' without a matching `]' is just another character to match. */ + if (c == L('\0')) + return ((test == L('[')) ? savep : (CHAR *)0); + + oc = c; + c = *p++; + if (c == L('[') && (*p == L('=') || *p == L(':') || *p == L('.'))) + { + brcnt++; + brchrp = p++; /* skip over the char after the left bracket */ + if ((c = *p) == L('\0')) + return ((test == L('[')) ? savep : (CHAR *)0); + /* If *brchrp == ':' we should check that the rest of the characters + form a valid character class name. We don't do that yet, but we + keep BRCHRP in case we want to. */ + } + /* We only want to check brchrp if we set it above. */ + else if (c == L(']') && brcnt > 1 && brchrp != 0 && oc == *brchrp) + { + brcnt--; + brchrp = 0; /* just in case */ + } + /* Left bracket loses its special meaning inside a bracket expression. + It is only valid when followed by a `.', `=', or `:', which we check + for above. Technically the right bracket can appear in a collating + symbol, so we check for that here. Otherwise, it terminates the + bracket expression. */ + else if (c == L(']') && (brchrp == 0 || *brchrp != L('.')) && brcnt >= 1) + brcnt = 0; + else if (!(flags & FNM_NOESCAPE) && c == L('\\')) + { + if (*p == '\0') + return (CHAR *)0; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + } + return (not ? (CHAR *)0 : p); +} + +#if defined (EXTENDED_GLOB) +/* ksh-like extended pattern matching: + + [?*+@!](pat-list) + + where pat-list is a list of one or patterns separated by `|'. Operation + is as follows: + + ?(patlist) match zero or one of the given patterns + *(patlist) match zero or more of the given patterns + +(patlist) match one or more of the given patterns + @(patlist) match exactly one of the given patterns + !(patlist) match anything except one of the given patterns +*/ + +/* Scan a pattern starting at STRING and ending at END, keeping track of + embedded () and []. If DELIM is 0, we scan until a matching `)' + because we're scanning a `patlist'. Otherwise, we scan until we see + DELIM. In all cases, we never scan past END. The return value is the + first character after the matching DELIM or NULL if the pattern is + empty or invalid. */ +/*static*/ CHAR * +PATSCAN (string, end, delim) + CHAR *string, *end; + INT delim; +{ + int pnest, bnest, skip; + INT cchar; + CHAR *s, c, *bfirst; + + pnest = bnest = skip = 0; + cchar = 0; + bfirst = NULL; + + if (string == end) + return (NULL); + + for (s = string; c = *s; s++) + { + if (s >= end) + return (s); + if (skip) + { + skip = 0; + continue; + } + switch (c) + { + case L('\\'): + skip = 1; + break; + + case L('\0'): + return ((CHAR *)NULL); + + /* `[' is not special inside a bracket expression, but it may + introduce one of the special POSIX bracket expressions + ([.SYM.], [=c=], [: ... :]) that needs special handling. */ + case L('['): + if (bnest == 0) + { + bfirst = s + 1; + if (*bfirst == L('!') || *bfirst == L('^')) + bfirst++; + bnest++; + } + else if (s[1] == L(':') || s[1] == L('.') || s[1] == L('=')) + cchar = s[1]; + break; + + /* `]' is not special if it's the first char (after a leading `!' + or `^') in a bracket expression or if it's part of one of the + special POSIX bracket expressions ([.SYM.], [=c=], [: ... :]) */ + case L(']'): + if (bnest) + { + if (cchar && s[-1] == cchar) + cchar = 0; + else if (s != bfirst) + { + bnest--; + bfirst = 0; + } + } + break; + + case L('('): + if (bnest == 0) + pnest++; + break; + + case L(')'): + if (bnest == 0 && pnest-- <= 0) + return ++s; + break; + + case L('|'): + if (bnest == 0 && pnest == 0 && delim == L('|')) + return ++s; + break; + } + } + + return (NULL); +} + +/* Return 0 if dequoted pattern matches S in the current locale. */ +static int +STRCOMPARE (p, pe, s, se) + CHAR *p, *pe, *s, *se; +{ + int ret; + CHAR c1, c2; + int l1, l2; + + l1 = pe - p; + l2 = se - s; + + if (l1 != l2) + return (FNM_NOMATCH); /* unequal lengths, can't be identical */ + + c1 = *pe; + c2 = *se; + + if (c1 != 0) + *pe = '\0'; + if (c2 != 0) + *se = '\0'; + +#if HAVE_MULTIBYTE || defined (HAVE_STRCOLL) + ret = STRCOLL ((XCHAR *)p, (XCHAR *)s); +#else + ret = STRCMP ((XCHAR *)p, (XCHAR *)s); +#endif + + if (c1 != 0) + *pe = c1; + if (c2 != 0) + *se = c2; + + return (ret == 0 ? ret : FNM_NOMATCH); +} + +/* Match a ksh extended pattern specifier. Return FNM_NOMATCH on failure or + 0 on success. This is handed the entire rest of the pattern and string + the first time an extended pattern specifier is encountered, so it calls + gmatch recursively. */ +static int +EXTMATCH (xc, s, se, p, pe, flags) + INT xc; /* select which operation */ + CHAR *s, *se; + CHAR *p, *pe; + int flags; +{ + CHAR *prest; /* pointer to rest of pattern */ + CHAR *psub; /* pointer to sub-pattern */ + CHAR *pnext; /* pointer to next sub-pattern */ + CHAR *srest; /* pointer to rest of string */ + int m1, m2, xflags; /* xflags = flags passed to recursive matches */ + +#if DEBUG_MATCHING +fprintf(stderr, "extmatch: xc = %c\n", xc); +fprintf(stderr, "extmatch: s = %s; se = %s\n", s, se); +fprintf(stderr, "extmatch: p = %s; pe = %s\n", p, pe); +fprintf(stderr, "extmatch: flags = %d\n", flags); +#endif + + prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */ + if (prest == 0) + /* If PREST is 0, we failed to scan a valid pattern. In this + case, we just want to compare the two as strings. */ + return (STRCOMPARE (p - 1, pe, s, se)); + + switch (xc) + { + case L('+'): /* match one or more occurrences */ + case L('*'): /* match zero or more occurrences */ + /* If we can get away with no matches, don't even bother. Just + call GMATCH on the rest of the pattern and return success if + it succeeds. */ + if (xc == L('*') && (GMATCH (s, se, prest, pe, NULL, flags) == 0)) + return 0; + + /* OK, we have to do this the hard way. First, we make sure one of + the subpatterns matches, then we try to match the rest of the + string. */ + for (psub = p + 1; ; psub = pnext) + { + pnext = PATSCAN (psub, pe, L('|')); + for (srest = s; srest <= se; srest++) + { + /* Match this substring (S -> SREST) against this + subpattern (psub -> pnext - 1) */ + m1 = GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0; + /* OK, we matched a subpattern, so make sure the rest of the + string matches the rest of the pattern. Also handle + multiple matches of the pattern. */ + if (m1) + { + /* if srest > s, we are not at start of string */ + xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags; + m2 = (GMATCH (srest, se, prest, pe, NULL, xflags) == 0) || + (s != srest && GMATCH (srest, se, p - 1, pe, NULL, xflags) == 0); + } + if (m1 && m2) + return (0); + } + if (pnext == prest) + break; + } + return (FNM_NOMATCH); + + case L('?'): /* match zero or one of the patterns */ + case L('@'): /* match one (or more) of the patterns */ + /* If we can get away with no matches, don't even bother. Just + call gmatch on the rest of the pattern and return success if + it succeeds. */ + if (xc == L('?') && (GMATCH (s, se, prest, pe, NULL, flags) == 0)) + return 0; + + /* OK, we have to do this the hard way. First, we see if one of + the subpatterns matches, then, if it does, we try to match the + rest of the string. */ + for (psub = p + 1; ; psub = pnext) + { + pnext = PATSCAN (psub, pe, L('|')); + srest = (prest == pe) ? se : s; + for ( ; srest <= se; srest++) + { + /* if srest > s, we are not at start of string */ + xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags; + if (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0 && + GMATCH (srest, se, prest, pe, NULL, xflags) == 0) + return (0); + } + if (pnext == prest) + break; + } + return (FNM_NOMATCH); + + case '!': /* match anything *except* one of the patterns */ + for (srest = s; srest <= se; srest++) + { + m1 = 0; + for (psub = p + 1; ; psub = pnext) + { + pnext = PATSCAN (psub, pe, L('|')); + /* If one of the patterns matches, just bail immediately. */ + if (m1 = (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0)) + break; + if (pnext == prest) + break; + } + + /* If nothing matched, but the string starts with a period and we + need to match periods explicitly, don't return this as a match, + even for negation. Might need to do this only if srest == s. */ + if (m1 == 0 && *s == '.' && (flags & FNM_PERIOD)) + return (FNM_NOMATCH); + + /* if srest > s, we are not at start of string */ + xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags; + if (m1 == 0 && GMATCH (srest, se, prest, pe, NULL, xflags) == 0) + return (0); + } + return (FNM_NOMATCH); + } + + return (FNM_NOMATCH); +} +#endif /* EXTENDED_GLOB */ + +#undef IS_CCLASS +#undef FOLD +#undef CHAR +#undef U_CHAR +#undef XCHAR +#undef INT +#undef INVALID +#undef FCT +#undef GMATCH +#undef COLLSYM +#undef PARSE_COLLSYM +#undef PATSCAN +#undef STRCOMPARE +#undef EXTMATCH +#undef DEQUOTE_PATHNAME +#undef STRUCT +#undef BRACKMATCH +#undef STRCHR +#undef STRCOLL +#undef STRLEN +#undef STRCMP +#undef MEMCHR +#undef COLLEQUIV +#undef RANGECMP +#undef L diff --git a/utshell-0.5.0/lib/glob/smatch.c b/utshell-0.5.0/lib/glob/smatch.c new file mode 100644 index 00000000..a58456d7 --- /dev/null +++ b/utshell-0.5.0/lib/glob/smatch.c @@ -0,0 +1,617 @@ +/* strmatch.c -- ksh-like extended pattern matching for the shell and filename + globbing. */ + +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include /* for debugging */ + +#include "strmatch.h" +#include + +#include "bashansi.h" +#include "shmbutil.h" +#include "xmalloc.h" + +#include + +#if !defined (errno) +extern int errno; +#endif + +#if FNMATCH_EQUIV_FALLBACK +/* We don't include in order to avoid namespace collisions; the + internal strmatch still uses the FNM_ constants. */ +extern int fnmatch (const char *, const char *, int); +#endif + +/* First, compile `sm_loop.c' for single-byte characters. */ +#define CHAR unsigned char +#define U_CHAR unsigned char +#define XCHAR char +#define INT int +#define L(CS) CS +#define INVALID -1 + +#undef STREQ +#undef STREQN +#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) +#define STREQN(a, b, n) ((a)[0] == (b)[0] && strncmp(a, b, n) == 0) + +#ifndef GLOBASCII_DEFAULT +# define GLOBASCII_DEFAULT 0 +#endif + +int glob_asciirange = GLOBASCII_DEFAULT; + +#if FNMATCH_EQUIV_FALLBACK +/* Construct a string w1 = "c1" and a pattern w2 = "[[=c2=]]" and pass them + to fnmatch to see if wide characters c1 and c2 collate as members of the + same equivalence class. We can't really do this portably any other way */ +static int +_fnmatch_fallback (s, p) + int s, p; /* string char, patchar */ +{ + char s1[2]; /* string */ + char s2[8]; /* constructed pattern */ + + s1[0] = (unsigned char)s; + s1[1] = '\0'; + + /* reconstruct the pattern */ + s2[0] = s2[1] = '['; + s2[2] = '='; + s2[3] = (unsigned char)p; + s2[4] = '='; + s2[5] = s2[6] = ']'; + s2[7] = '\0'; + + return (fnmatch ((const char *)s2, (const char *)s1, 0)); +} +#endif + +/* We use strcoll(3) for range comparisons in bracket expressions, + even though it can have unwanted side effects in locales + other than POSIX or US. For instance, in the de locale, [A-Z] matches + all characters. If GLOB_ASCIIRANGE is non-zero, and we're not forcing + the use of strcoll (e.g., for explicit collating symbols), we use + straight ordering as if in the C locale. */ + +#if defined (HAVE_STRCOLL) +/* Helper functions for collating symbol equivalence. */ + +/* Return 0 if C1 == C2 or collates equally if FORCECOLL is non-zero. */ +static int +charcmp (c1, c2, forcecoll) + int c1, c2; + int forcecoll; +{ + static char s1[2] = { ' ', '\0' }; + static char s2[2] = { ' ', '\0' }; + int ret; + + /* Eight bits only. Period. */ + c1 &= 0xFF; + c2 &= 0xFF; + + if (c1 == c2) + return (0); + + if (forcecoll == 0 && glob_asciirange) + return (c1 - c2); + + s1[0] = c1; + s2[0] = c2; + + return (strcoll (s1, s2)); +} + +static int +rangecmp (c1, c2, forcecoll) + int c1, c2; + int forcecoll; +{ + int r; + + r = charcmp (c1, c2, forcecoll); + + /* We impose a total ordering here by returning c1-c2 if charcmp returns 0 */ + if (r != 0) + return r; + return (c1 - c2); /* impose total ordering */ +} +#else /* !HAVE_STRCOLL */ +# define rangecmp(c1, c2, f) ((int)(c1) - (int)(c2)) +#endif /* !HAVE_STRCOLL */ + +#if defined (HAVE_STRCOLL) +/* Returns 1 if chars C and EQUIV collate equally in the current locale. */ +static int +collequiv (c, equiv) + int c, equiv; +{ + if (charcmp (c, equiv, 1) == 0) + return 1; + +#if FNMATCH_EQUIV_FALLBACK + return (_fnmatch_fallback (c, equiv) == 0); +#else + return 0; +#endif + +} +#else +# define collequiv(c, equiv) ((c) == (equiv)) +#endif + +#define _COLLSYM _collsym +#define __COLLSYM __collsym +#define POSIXCOLL posix_collsyms +#include "collsyms.h" + +static int +collsym (s, len) + CHAR *s; + int len; +{ + register struct _collsym *csp; + char *x; + + x = (char *)s; + for (csp = posix_collsyms; csp->name; csp++) + { + if (STREQN(csp->name, x, len) && csp->name[len] == '\0') + return (csp->code); + } + if (len == 1) + return s[0]; + return INVALID; +} + +/* unibyte character classification */ +#if !defined (isascii) && !defined (HAVE_ISASCII) +# define isascii(c) ((unsigned int)(c) <= 0177) +#endif + +enum char_class + { + CC_NO_CLASS = 0, + CC_ASCII, CC_ALNUM, CC_ALPHA, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH, + CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_WORD, CC_XDIGIT + }; + +static char const *const cclass_name[] = + { + "", + "ascii", "alnum", "alpha", "blank", "cntrl", "digit", "graph", + "lower", "print", "punct", "space", "upper", "word", "xdigit" + }; + +#define N_CHAR_CLASS (sizeof(cclass_name) / sizeof (cclass_name[0])) + +static enum char_class +is_valid_cclass (name) + const char *name; +{ + enum char_class ret; + int i; + + ret = CC_NO_CLASS; + + for (i = 1; i < N_CHAR_CLASS; i++) + { + if (STREQ (name, cclass_name[i])) + { + ret = (enum char_class)i; + break; + } + } + + return ret; +} + +static int +cclass_test (c, char_class) + int c; + enum char_class char_class; +{ + int result; + + switch (char_class) + { + case CC_ASCII: + result = isascii (c); + break; + case CC_ALNUM: + result = ISALNUM (c); + break; + case CC_ALPHA: + result = ISALPHA (c); + break; + case CC_BLANK: + result = ISBLANK (c); + break; + case CC_CNTRL: + result = ISCNTRL (c); + break; + case CC_DIGIT: + result = ISDIGIT (c); + break; + case CC_GRAPH: + result = ISGRAPH (c); + break; + case CC_LOWER: + result = ISLOWER (c); + break; + case CC_PRINT: + result = ISPRINT (c); + break; + case CC_PUNCT: + result = ISPUNCT (c); + break; + case CC_SPACE: + result = ISSPACE (c); + break; + case CC_UPPER: + result = ISUPPER (c); + break; + case CC_WORD: + result = (ISALNUM (c) || c == '_'); + break; + case CC_XDIGIT: + result = ISXDIGIT (c); + break; + default: + result = -1; + break; + } + + return result; +} + +static int +is_cclass (c, name) + int c; + const char *name; +{ + enum char_class char_class; + int result; + + char_class = is_valid_cclass (name); + if (char_class == CC_NO_CLASS) + return -1; + + result = cclass_test (c, char_class); + return (result); +} + +/* Now include `sm_loop.c' for single-byte characters. */ +/* The result of FOLD is an `unsigned char' */ +# define FOLD(c) ((flags & FNM_CASEFOLD) \ + ? TOLOWER ((unsigned char)c) \ + : ((unsigned char)c)) + +#define FCT internal_strmatch +#define GMATCH gmatch +#define COLLSYM collsym +#define PARSE_COLLSYM parse_collsym +#define BRACKMATCH brackmatch +#define PATSCAN glob_patscan +#define STRCOMPARE strcompare +#define EXTMATCH extmatch +#define DEQUOTE_PATHNAME udequote_pathname +#define STRUCT smat_struct +#define STRCHR(S, C) strchr((S), (C)) +#define MEMCHR(S, C, N) memchr((S), (C), (N)) +#define STRCOLL(S1, S2) strcoll((S1), (S2)) +#define STRLEN(S) strlen(S) +#define STRCMP(S1, S2) strcmp((S1), (S2)) +#define RANGECMP(C1, C2, F) rangecmp((C1), (C2), (F)) +#define COLLEQUIV(C1, C2) collequiv((C1), (C2)) +#define CTYPE_T enum char_class +#define IS_CCLASS(C, S) is_cclass((C), (S)) +#include "sm_loop.c" + +#if HANDLE_MULTIBYTE + +# define CHAR wchar_t +# define U_CHAR wint_t +# define XCHAR wchar_t +# define INT wint_t +# define L(CS) L##CS +# define INVALID WEOF + +# undef STREQ +# undef STREQN +# define STREQ(s1, s2) ((wcscmp (s1, s2) == 0)) +# define STREQN(a, b, n) ((a)[0] == (b)[0] && wcsncmp(a, b, n) == 0) + +extern char *mbsmbchar PARAMS((const char *)); + +#if FNMATCH_EQUIV_FALLBACK +/* Construct a string w1 = "c1" and a pattern w2 = "[[=c2=]]" and pass them + to fnmatch to see if wide characters c1 and c2 collate as members of the + same equivalence class. We can't really do this portably any other way */ +static int +_fnmatch_fallback_wc (c1, c2) + wchar_t c1, c2; /* string char, patchar */ +{ + char w1[MB_LEN_MAX+1]; /* string */ + char w2[MB_LEN_MAX+8]; /* constructed pattern */ + int l1, l2; + + l1 = wctomb (w1, c1); + if (l1 == -1) + return (2); + w1[l1] = '\0'; + + /* reconstruct the pattern */ + w2[0] = w2[1] = '['; + w2[2] = '='; + l2 = wctomb (w2+3, c2); + if (l2 == -1) + return (2); + w2[l2+3] = '='; + w2[l2+4] = w2[l2+5] = ']'; + w2[l2+6] = '\0'; + + return (fnmatch ((const char *)w2, (const char *)w1, 0)); +} +#endif + +static int +charcmp_wc (c1, c2, forcecoll) + wint_t c1, c2; + int forcecoll; +{ + static wchar_t s1[2] = { L' ', L'\0' }; + static wchar_t s2[2] = { L' ', L'\0' }; + int r; + + if (c1 == c2) + return 0; + + if (forcecoll == 0 && glob_asciirange && c1 <= UCHAR_MAX && c2 <= UCHAR_MAX) + return ((int)(c1 - c2)); + + s1[0] = c1; + s2[0] = c2; + + return (wcscoll (s1, s2)); +} + +static int +rangecmp_wc (c1, c2, forcecoll) + wint_t c1, c2; + int forcecoll; +{ + int r; + + r = charcmp_wc (c1, c2, forcecoll); + + /* We impose a total ordering here by returning c1-c2 if charcmp returns 0, + as we do above in the single-byte case. */ + if (r != 0 || forcecoll) + return r; + return ((int)(c1 - c2)); /* impose total ordering */ +} + +/* Returns 1 if wide chars C and EQUIV collate equally in the current locale. */ +static int +collequiv_wc (c, equiv) + wint_t c, equiv; +{ + wchar_t s, p; + + if (charcmp_wc (c, equiv, 1) == 0) + return 1; + +#if FNMATCH_EQUIV_FALLBACK +/* We check explicitly for success (fnmatch returns 0) to avoid problems if + our local definition of FNM_NOMATCH (strmatch.h) doesn't match the + system's (fnmatch.h). We don't care about error return values here. */ + + s = c; + p = equiv; + return (_fnmatch_fallback_wc (s, p) == 0); +#else + return 0; +#endif +} + +/* Helper function for collating symbol. */ +# define _COLLSYM _collwcsym +# define __COLLSYM __collwcsym +# define POSIXCOLL posix_collwcsyms +# include "collsyms.h" + +static wint_t +collwcsym (s, len) + wchar_t *s; + int len; +{ + register struct _collwcsym *csp; + + for (csp = posix_collwcsyms; csp->name; csp++) + { + if (STREQN(csp->name, s, len) && csp->name[len] == L'\0') + return (csp->code); + } + if (len == 1) + return s[0]; + return INVALID; +} + +static int +is_wcclass (wc, name) + wint_t wc; + wchar_t *name; +{ + char *mbs; + mbstate_t state; + size_t mbslength; + wctype_t desc; + int want_word; + + if ((wctype ("ascii") == (wctype_t)0) && (wcscmp (name, L"ascii") == 0)) + { + int c; + + if ((c = wctob (wc)) == EOF) + return 0; + else + return (c <= 0x7F); + } + + want_word = (wcscmp (name, L"word") == 0); + if (want_word) + name = L"alnum"; + + memset (&state, '\0', sizeof (mbstate_t)); + mbs = (char *) malloc (wcslen(name) * MB_CUR_MAX + 1); + if (mbs == 0) + return -1; + mbslength = wcsrtombs (mbs, (const wchar_t **)&name, (wcslen(name) * MB_CUR_MAX + 1), &state); + + if (mbslength == (size_t)-1 || mbslength == (size_t)-2) + { + free (mbs); + return -1; + } + desc = wctype (mbs); + free (mbs); + + if (desc == (wctype_t)0) + return -1; + + if (want_word) + return (iswctype (wc, desc) || wc == L'_'); + else + return (iswctype (wc, desc)); +} + +/* Return 1 if there are no char class [:class:] expressions (degenerate case) + or only posix-specified (C locale supported) char class expressions in + PATTERN. These are the ones where it's safe to punt to the single-byte + code, since wide character support allows locale-defined char classes. + This only uses single-byte code, but is only needed to support multibyte + locales. */ +static int +posix_cclass_only (pattern) + char *pattern; +{ + char *p, *p1; + char cc[16]; /* sufficient for all valid posix char class names */ + enum char_class valid; + + p = pattern; + while (p = strchr (p, '[')) + { + if (p[1] != ':') + { + p++; + continue; + } + p += 2; /* skip past "[:" */ + /* Find end of char class expression */ + for (p1 = p; *p1; p1++) + if (*p1 == ':' && p1[1] == ']') + break; + if (*p1 == 0) /* no char class expression found */ + break; + /* Find char class name and validate it against posix char classes */ + if ((p1 - p) >= sizeof (cc)) + return 0; + bcopy (p, cc, p1 - p); + cc[p1 - p] = '\0'; + valid = is_valid_cclass (cc); + if (valid == CC_NO_CLASS) + return 0; /* found unrecognized char class name */ + + p = p1 + 2; /* found posix char class name */ + } + + return 1; /* no char class names or only posix */ +} + +/* Now include `sm_loop.c' for multibyte characters. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c)) +#define FCT internal_wstrmatch +#define GMATCH gmatch_wc +#define COLLSYM collwcsym +#define PARSE_COLLSYM parse_collwcsym +#define BRACKMATCH brackmatch_wc +#define PATSCAN glob_patscan_wc +#define STRCOMPARE wscompare +#define EXTMATCH extmatch_wc +#define DEQUOTE_PATHNAME wcdequote_pathname +#define STRUCT wcsmat_struct +#define STRCHR(S, C) wcschr((S), (C)) +#define MEMCHR(S, C, N) wmemchr((S), (C), (N)) +#define STRCOLL(S1, S2) wcscoll((S1), (S2)) +#define STRLEN(S) wcslen(S) +#define STRCMP(S1, S2) wcscmp((S1), (S2)) +#define RANGECMP(C1, C2, F) rangecmp_wc((C1), (C2), (F)) +#define COLLEQUIV(C1, C2) collequiv_wc((C1), (C2)) +#define CTYPE_T enum char_class +#define IS_CCLASS(C, S) is_wcclass((C), (S)) +#include "sm_loop.c" + +#endif /* HAVE_MULTIBYTE */ + +int +xstrmatch (pattern, string, flags) + char *pattern; + char *string; + int flags; +{ +#if HANDLE_MULTIBYTE + int ret; + size_t n; + wchar_t *wpattern, *wstring; + size_t plen, slen, mplen, mslen; + + if (MB_CUR_MAX == 1) + return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); + + if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern)) + return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); + + n = xdupmbstowcs (&wpattern, NULL, pattern); + if (n == (size_t)-1 || n == (size_t)-2) + return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); + + n = xdupmbstowcs (&wstring, NULL, string); + if (n == (size_t)-1 || n == (size_t)-2) + { + free (wpattern); + return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); + } + + ret = internal_wstrmatch (wpattern, wstring, flags); + + free (wpattern); + free (wstring); + + return ret; +#else + return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); +#endif /* !HANDLE_MULTIBYTE */ +} diff --git a/utshell-0.5.0/lib/glob/strmatch.c b/utshell-0.5.0/lib/glob/strmatch.c new file mode 100644 index 00000000..5b7b49fb --- /dev/null +++ b/utshell-0.5.0/lib/glob/strmatch.c @@ -0,0 +1,79 @@ +/* strmatch.c -- ksh-like extended pattern matching for the shell and filename + globbing. */ + +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include "stdc.h" +#include "strmatch.h" + +extern int xstrmatch PARAMS((char *, char *, int)); +#if defined (HANDLE_MULTIBYTE) +extern int internal_wstrmatch PARAMS((wchar_t *, wchar_t *, int)); +#endif + +int +strmatch (pattern, string, flags) + char *pattern; + char *string; + int flags; +{ + if (string == 0 || pattern == 0) + return FNM_NOMATCH; + + return (xstrmatch (pattern, string, flags)); +} + +#if defined (HANDLE_MULTIBYTE) +int +wcsmatch (wpattern, wstring, flags) + wchar_t *wpattern; + wchar_t *wstring; + int flags; +{ + if (wstring == 0 || wpattern == 0) + return (FNM_NOMATCH); + + return (internal_wstrmatch (wpattern, wstring, flags)); +} +#endif + +#ifdef TEST +main (c, v) + int c; + char **v; +{ + char *string, *pat; + + string = v[1]; + pat = v[2]; + + if (strmatch (pat, string, 0) == 0) + { + printf ("%s matches %s\n", string, pat); + exit (0); + } + else + { + printf ("%s does not match %s\n", string, pat); + exit (1); + } +} +#endif diff --git a/utshell-0.5.0/lib/glob/strmatch.h b/utshell-0.5.0/lib/glob/strmatch.h new file mode 100644 index 00000000..fa7be7bb --- /dev/null +++ b/utshell-0.5.0/lib/glob/strmatch.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _STRMATCH_H +#define _STRMATCH_H 1 + +#include + +#include "stdc.h" + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `strmatch'. */ + +/* standard flags are like fnmatch(3). */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +/* extended flags not available in most libc fnmatch versions, but we undef + them to avoid any possible warnings. */ +#undef FNM_LEADING_DIR +#undef FNM_CASEFOLD +#undef FNM_EXTMATCH + +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ + +#define FNM_FIRSTCHAR (1 << 6) /* Match only the first character */ + +/* Value returned by `strmatch' if STRING does not match PATTERN. */ +#undef FNM_NOMATCH + +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int strmatch PARAMS((char *, char *, int)); + +#if HANDLE_MULTIBYTE +extern int wcsmatch PARAMS((wchar_t *, wchar_t *, int)); +#endif + +#endif /* _STRMATCH_H */ diff --git a/utshell-0.5.0/lib/glob/xmbsrtowcs.c b/utshell-0.5.0/lib/glob/xmbsrtowcs.c new file mode 100644 index 00000000..17250c30 --- /dev/null +++ b/utshell-0.5.0/lib/glob/xmbsrtowcs.c @@ -0,0 +1,523 @@ +/* xmbsrtowcs.c -- replacement function for mbsrtowcs */ + +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Ask for GNU extensions to get extern declaration for mbsnrtowcs if + available via glibc. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#include + +#include + +/* , and are included in "shmbutil.h". + If , , mbsrtowcs(), exist, HANDLE_MULTIBYTE + is defined as 1. */ +#include + +#if HANDLE_MULTIBYTE + +#include +#if !defined (errno) +extern int errno; +#endif + +#define WSBUF_INC 32 + +#ifndef FREE +# define FREE(x) do { if (x) free (x); } while (0) +#endif + +#if ! HAVE_STRCHRNUL +extern char *strchrnul PARAMS((const char *, int)); +#endif + +/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>. + So, this function is made for converting 0x5c to U<0x5c>. */ + +static mbstate_t local_state; +static int local_state_use = 0; + +size_t +xmbsrtowcs (dest, src, len, pstate) + wchar_t *dest; + const char **src; + size_t len; + mbstate_t *pstate; +{ + mbstate_t *ps; + size_t mblength, wclength, n; + + ps = pstate; + if (pstate == NULL) + { + if (!local_state_use) + { + memset (&local_state, '\0', sizeof(mbstate_t)); + local_state_use = 1; + } + ps = &local_state; + } + + n = strlen (*src); + + if (dest == NULL) + { + wchar_t *wsbuf; + const char *mbs; + mbstate_t psbuf; + + /* It doesn't matter if malloc fails here, since mbsrtowcs should do + the right thing with a NULL first argument. */ + wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t)); + mbs = *src; + psbuf = *ps; + + wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf); + + if (wsbuf) + free (wsbuf); + return wclength; + } + + for (wclength = 0; wclength < len; wclength++, dest++) + { + if (mbsinit(ps)) + { + if (**src == '\0') + { + *dest = L'\0'; + *src = NULL; + return (wclength); + } + else if (**src == '\\') + { + *dest = L'\\'; + mblength = 1; + } + else + mblength = mbrtowc(dest, *src, n, ps); + } + else + mblength = mbrtowc(dest, *src, n, ps); + + /* Cannot convert multibyte character to wide character. */ + if (mblength == (size_t)-1 || mblength == (size_t)-2) + return (size_t)-1; + + *src += mblength; + n -= mblength; + + /* The multibyte string has been completely converted, + including the terminating '\0'. */ + if (*dest == L'\0') + { + *src = NULL; + break; + } + } + + return (wclength); +} + +#if HAVE_MBSNRTOWCS +/* Convert a multibyte string to a wide character string. Memory for the + new wide character string is obtained with malloc. + + Fast multiple-character version of xdupmbstowcs used when the indices are + not required and mbsnrtowcs is available. */ + +static size_t +xdupmbstowcs2 (destp, src) + wchar_t **destp; /* Store the pointer to the wide character string */ + const char *src; /* Multibyte character string */ +{ + const char *p; /* Conversion start position of src */ + wchar_t *wsbuf; /* Buffer for wide characters. */ + size_t wsbuf_size; /* Size of WSBUF */ + size_t wcnum; /* Number of wide characters in WSBUF */ + mbstate_t state; /* Conversion State */ + size_t n, wcslength; /* Number of wide characters produced by the conversion. */ + const char *end_or_backslash; + size_t nms; /* Number of multibyte characters to convert at one time. */ + mbstate_t tmp_state; + const char *tmp_p; + + memset (&state, '\0', sizeof(mbstate_t)); + + wsbuf_size = 0; + wsbuf = NULL; + + p = src; + wcnum = 0; + do + { + end_or_backslash = strchrnul(p, '\\'); + nms = end_or_backslash - p; + if (*end_or_backslash == '\0') + nms++; + + /* Compute the number of produced wide-characters. */ + tmp_p = p; + tmp_state = state; + + if (nms == 0 && *p == '\\') /* special initial case */ + nms = wcslength = 1; + else + wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state); + + if (wcslength == 0) + { + tmp_p = p; /* will need below */ + tmp_state = state; + wcslength = 1; /* take a single byte */ + } + + /* Conversion failed. */ + if (wcslength == (size_t)-1) + { + free (wsbuf); + *destp = NULL; + return (size_t)-1; + } + + /* Resize the buffer if it is not large enough. */ + if (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */ + { + wchar_t *wstmp; + + while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */ + wsbuf_size += WSBUF_INC; + + wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t)); + if (wstmp == NULL) + { + free (wsbuf); + *destp = NULL; + return (size_t)-1; + } + wsbuf = wstmp; + } + + /* Perform the conversion. This is assumed to return 'wcslength'. + It may set 'p' to NULL. */ + n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state); + + if (n == 0 && p == 0) + { + wsbuf[wcnum] = L'\0'; + break; + } + + /* Compensate for taking single byte on wcs conversion failure above. */ + if (wcslength == 1 && (n == 0 || n == (size_t)-1)) + { + state = tmp_state; + p = tmp_p; + wsbuf[wcnum] = *p; + if (*p == 0) + break; + else + { + wcnum++; p++; + } + } + else + wcnum += wcslength; + + if (mbsinit (&state) && (p != NULL) && (*p == '\\')) + { + wsbuf[wcnum++] = L'\\'; + p++; + } + } + while (p != NULL); + + *destp = wsbuf; + + /* Return the length of the wide character string, not including `\0'. */ + return wcnum; +} +#endif /* HAVE_MBSNRTOWCS */ + +/* Convert a multibyte string to a wide character string. Memory for the + new wide character string is obtained with malloc. + + The return value is the length of the wide character string. Returns a + pointer to the wide character string in DESTP. If INDICESP is not NULL, + INDICESP stores the pointer to the pointer array. Each pointer is to + the first byte of each multibyte character. Memory for the pointer array + is obtained with malloc, too. + If conversion is failed, the return value is (size_t)-1 and the values + of DESTP and INDICESP are NULL. */ + +size_t +xdupmbstowcs (destp, indicesp, src) + wchar_t **destp; /* Store the pointer to the wide character string */ + char ***indicesp; /* Store the pointer to the pointer array. */ + const char *src; /* Multibyte character string */ +{ + const char *p; /* Conversion start position of src */ + wchar_t wc; /* Created wide character by conversion */ + wchar_t *wsbuf; /* Buffer for wide characters. */ + char **indices; /* Buffer for indices. */ + size_t wsbuf_size; /* Size of WSBUF */ + size_t wcnum; /* Number of wide characters in WSBUF */ + mbstate_t state; /* Conversion State */ + + /* In case SRC or DESP is NULL, conversion doesn't take place. */ + if (src == NULL || destp == NULL) + { + if (destp) + *destp = NULL; + if (indicesp) + *indicesp = NULL; + return (size_t)-1; + } + +#if HAVE_MBSNRTOWCS + if (indicesp == NULL) + return (xdupmbstowcs2 (destp, src)); +#endif + + memset (&state, '\0', sizeof(mbstate_t)); + wsbuf_size = WSBUF_INC; + + wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t)); + if (wsbuf == NULL) + { + *destp = NULL; + if (indicesp) + *indicesp = NULL; + return (size_t)-1; + } + + indices = NULL; + if (indicesp) + { + indices = (char **) malloc (wsbuf_size * sizeof(char *)); + if (indices == NULL) + { + free (wsbuf); + *destp = NULL; + *indicesp = NULL; + return (size_t)-1; + } + } + + p = src; + wcnum = 0; + do + { + size_t mblength; /* Byte length of one multibyte character. */ + + if (mbsinit (&state)) + { + if (*p == '\0') + { + wc = L'\0'; + mblength = 1; + } + else if (*p == '\\') + { + wc = L'\\'; + mblength = 1; + } + else + mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state); + } + else + mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state); + + /* Conversion failed. */ + if (MB_INVALIDCH (mblength)) + { + free (wsbuf); + FREE (indices); + *destp = NULL; + if (indicesp) + *indicesp = NULL; + return (size_t)-1; + } + + ++wcnum; + + /* Resize buffers when they are not large enough. */ + if (wsbuf_size < wcnum) + { + wchar_t *wstmp; + char **idxtmp; + + wsbuf_size += WSBUF_INC; + + wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t)); + if (wstmp == NULL) + { + free (wsbuf); + FREE (indices); + *destp = NULL; + if (indicesp) + *indicesp = NULL; + return (size_t)-1; + } + wsbuf = wstmp; + + if (indicesp) + { + idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char *)); + if (idxtmp == NULL) + { + free (wsbuf); + free (indices); + *destp = NULL; + if (indicesp) + *indicesp = NULL; + return (size_t)-1; + } + indices = idxtmp; + } + } + + wsbuf[wcnum - 1] = wc; + if (indices) + indices[wcnum - 1] = (char *)p; + p += mblength; + } + while (MB_NULLWCH (wc) == 0); + + /* Return the length of the wide character string, not including `\0'. */ + *destp = wsbuf; + if (indicesp != NULL) + *indicesp = indices; + + return (wcnum - 1); +} + +/* Convert wide character string to multibyte character string. Treat invalid + wide characters as bytes. Used only in unusual circumstances. + + Written by Bruno Haible , 2008, adapted by Chet Ramey + for use in Bash. */ + +/* Convert wide character string *SRCP to a multibyte character string and + store the result in DEST. Store at most LEN bytes in DEST. */ +size_t +xwcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) +{ + const wchar_t *src; + size_t cur_max; /* XXX - locale_cur_max */ + char buf[64], *destptr, *tmp_dest; + unsigned char uc; + mbstate_t prev_state; + + cur_max = MB_CUR_MAX; + if (cur_max > sizeof (buf)) /* Holy cow. */ + return (size_t)-1; + + src = *srcp; + + if (dest != NULL) + { + destptr = dest; + + for (; len > 0; src++) + { + wchar_t wc; + size_t ret; + + wc = *src; + /* If we have room, store directly into DEST. */ + tmp_dest = destptr; + ret = wcrtomb (len >= cur_max ? destptr : buf, wc, ps); + + if (ret == (size_t)(-1)) /* XXX */ + { + /* Since this is used for globbing and other uses of filenames, + treat invalid wide character sequences as bytes. This is + intended to be symmetric with xdupmbstowcs2. */ +handle_byte: + destptr = tmp_dest; /* in case wcrtomb modified it */ + uc = wc; + ret = 1; + if (len >= cur_max) + *destptr = uc; + else + buf[0] = uc; + if (ps) + memset (ps, 0, sizeof (mbstate_t)); + } + + if (ret > cur_max) /* Holy cow */ + goto bad_input; + + if (len < ret) + break; + + if (len < cur_max) + memcpy (destptr, buf, ret); + + if (wc == 0) + { + src = NULL; + /* Here mbsinit (ps). */ + break; + } + destptr += ret; + len -= ret; + } + *srcp = src; + return destptr - dest; + } + else + { + /* Ignore dest and len, don't store *srcp at the end, and + don't clobber *ps. */ + mbstate_t state = *ps; + size_t totalcount = 0; + + for (;; src++) + { + wchar_t wc; + size_t ret; + + wc = *src; + ret = wcrtomb (buf, wc, &state); + + if (ret == (size_t)(-1)) + goto bad_input2; + if (wc == 0) + { + /* Here mbsinit (&state). */ + break; + } + totalcount += ret; + } + return totalcount; + } + +bad_input: + *srcp = src; +bad_input2: + errno = EILSEQ; + return (size_t)(-1); +} + +#endif /* HANDLE_MULTIBYTE */ diff --git a/utshell-0.5.0/lib/include/alias.h b/utshell-0.5.0/lib/include/alias.h new file mode 100644 index 00000000..2c7feda8 --- /dev/null +++ b/utshell-0.5.0/lib/include/alias.h @@ -0,0 +1,74 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* alias.h -- structure definitions. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_ALIAS_H_) +#define _ALIAS_H_ + +#include "stdc.h" + +#include "hashlib.h" + +typedef struct alias { + char *name; + char *value; + char flags; +} alias_t; + +/* Values for `flags' member of struct alias. */ +#define AL_EXPANDNEXT 0x1 +#define AL_BEINGEXPANDED 0x2 + +/* The list of known aliases. */ +extern HASH_TABLE *aliases; + +extern void initialize_aliases PARAMS((void)); + +/* Scan the list of aliases looking for one with NAME. Return NULL + if the alias doesn't exist, else a pointer to the alias. */ +extern alias_t *find_alias PARAMS((char *)); + +/* Return the value of the alias for NAME, or NULL if there is none. */ +extern char *get_alias_value PARAMS((char *)); + +/* Make a new alias from NAME and VALUE. If NAME can be found, + then replace its value. */ +extern void add_alias PARAMS((char *, char *)); + +/* Remove the alias with name NAME from the alias list. Returns + the index of the removed alias, or -1 if the alias didn't exist. */ +extern int remove_alias PARAMS((char *)); + +/* Remove all aliases. */ +extern void delete_all_aliases PARAMS((void)); + +/* Return an array of all defined aliases. */ +extern alias_t **all_aliases PARAMS((void)); + +/* Expand a single word for aliases. */ +extern char *alias_expand_word PARAMS((char *)); + +/* Return a new line, with any aliases expanded. */ +extern char *alias_expand PARAMS((char *)); + +/* Helper definition for the parser */ +extern void clear_string_list_expander PARAMS((alias_t *)); + +#endif /* _ALIAS_H_ */ diff --git a/utshell-0.5.0/lib/include/ansi_stdlib.h b/utshell-0.5.0/lib/include/ansi_stdlib.h new file mode 100644 index 00000000..7dc2ee0c --- /dev/null +++ b/utshell-0.5.0/lib/include/ansi_stdlib.h @@ -0,0 +1,54 @@ +/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */ +/* A minimal stdlib.h containing extern declarations for those functions + that bash uses. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_STDLIB_H_) +#define _STDLIB_H_ 1 + +/* String conversion functions. */ +extern int atoi (); + +extern double atof (); +extern double strtod (); + +/* Memory allocation functions. */ +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +extern PTR_T malloc (); +extern PTR_T realloc (); +extern void free (); + +/* Other miscellaneous functions. */ +extern void abort (); +extern void exit (); +extern char *getenv (); +extern void qsort (); + +#endif /* _STDLIB_H */ diff --git a/utshell-0.5.0/lib/include/array.h b/utshell-0.5.0/lib/include/array.h new file mode 100644 index 00000000..8a0e00a2 --- /dev/null +++ b/utshell-0.5.0/lib/include/array.h @@ -0,0 +1,128 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* array.h -- definitions for the interface exported by array.c that allows + the rest of the shell to manipulate array variables. */ + +/* Copyright (C) 1997-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + + +#ifndef _ARRAY_H_ +#define _ARRAY_H_ + +#include "stdc.h" + +typedef intmax_t arrayind_t; + +enum atype {array_indexed, array_assoc}; /* only array_indexed used */ + +typedef struct array { + enum atype type; + arrayind_t max_index; + int num_elements; + struct array_element *head; + struct array_element *lastref; +} ARRAY; + +typedef struct array_element { + arrayind_t ind; + char *value; + struct array_element *next, *prev; +} ARRAY_ELEMENT; + +typedef int sh_ae_map_func_t PARAMS((ARRAY_ELEMENT *, void *)); + +/* Basic operations on entire arrays */ +extern ARRAY *array_create PARAMS((void)); +extern void array_flush PARAMS((ARRAY *)); +extern void array_dispose PARAMS((ARRAY *)); +extern ARRAY *array_copy PARAMS((ARRAY *)); +extern ARRAY *array_slice PARAMS((ARRAY *, ARRAY_ELEMENT *, ARRAY_ELEMENT *)); +extern void array_walk PARAMS((ARRAY *, sh_ae_map_func_t *, void *)); + +extern ARRAY_ELEMENT *array_shift PARAMS((ARRAY *, int, int)); +extern int array_rshift PARAMS((ARRAY *, int, char *)); +extern ARRAY_ELEMENT *array_unshift_element PARAMS((ARRAY *)); +extern int array_shift_element PARAMS((ARRAY *, char *)); + +extern ARRAY *array_quote PARAMS((ARRAY *)); +extern ARRAY *array_quote_escapes PARAMS((ARRAY *)); +extern ARRAY *array_dequote PARAMS((ARRAY *)); +extern ARRAY *array_dequote_escapes PARAMS((ARRAY *)); +extern ARRAY *array_remove_quoted_nulls PARAMS((ARRAY *)); + +extern char *array_subrange PARAMS((ARRAY *, arrayind_t, arrayind_t, int, int, int)); +extern char *array_patsub PARAMS((ARRAY *, char *, char *, int)); +extern char *array_modcase PARAMS((ARRAY *, char *, int, int)); + +/* Basic operations on array elements. */ +extern ARRAY_ELEMENT *array_create_element PARAMS((arrayind_t, char *)); +extern ARRAY_ELEMENT *array_copy_element PARAMS((ARRAY_ELEMENT *)); +extern void array_dispose_element PARAMS((ARRAY_ELEMENT *)); + +extern int array_insert PARAMS((ARRAY *, arrayind_t, char *)); +extern ARRAY_ELEMENT *array_remove PARAMS((ARRAY *, arrayind_t)); +extern char *array_reference PARAMS((ARRAY *, arrayind_t)); + +/* Converting to and from arrays */ +extern WORD_LIST *array_to_word_list PARAMS((ARRAY *)); +extern ARRAY *array_from_word_list PARAMS((WORD_LIST *)); +extern WORD_LIST *array_keys_to_word_list PARAMS((ARRAY *)); + +extern ARRAY *array_assign_list PARAMS((ARRAY *, WORD_LIST *)); + +extern char **array_to_argv PARAMS((ARRAY *, int *)); + +extern char *array_to_kvpair PARAMS((ARRAY *, int)); +extern char *array_to_assign PARAMS((ARRAY *, int)); +extern char *array_to_string PARAMS((ARRAY *, char *, int)); +extern ARRAY *array_from_string PARAMS((char *, char *)); + +/* Flags for array_shift */ +#define AS_DISPOSE 0x01 + +#define array_num_elements(a) ((a)->num_elements) +#define array_max_index(a) ((a)->max_index) +#define array_first_index(a) ((a)->head->next->ind) +#define array_head(a) ((a)->head) +#define array_empty(a) ((a)->num_elements == 0) + +#define element_value(ae) ((ae)->value) +#define element_index(ae) ((ae)->ind) +#define element_forw(ae) ((ae)->next) +#define element_back(ae) ((ae)->prev) + +#define set_element_value(ae, val) ((ae)->value = (val)) + +/* Convenience */ +#define array_push(a,v) \ + do { array_rshift ((a), 1, (v)); } while (0) +#define array_pop(a) \ + do { array_dispose_element (array_shift ((a), 1, 0)); } while (0) + +#define GET_ARRAY_FROM_VAR(n, v, a) \ + do { \ + (v) = find_variable (n); \ + (a) = ((v) && array_p ((v))) ? array_cell (v) : (ARRAY *)0; \ + } while (0) + +#define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*') + +/* In eval.c, but uses ARRAY * */ +extern int execute_array_command PARAMS((ARRAY *, void *)); + +#endif /* _ARRAY_H_ */ diff --git a/utshell-0.5.0/lib/include/arrayfunc.h b/utshell-0.5.0/lib/include/arrayfunc.h new file mode 100644 index 00000000..2420ccf9 --- /dev/null +++ b/utshell-0.5.0/lib/include/arrayfunc.h @@ -0,0 +1,101 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* arrayfunc.h -- declarations for miscellaneous array functions in arrayfunc.c */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_ARRAYFUNC_H_) +#define _ARRAYFUNC_H_ + +/* Must include variables.h before including this file. */ + +#if defined (ARRAY_VARS) + +/* This variable means to not expand associative array subscripts more than + once, when performing variable expansion. */ +extern int assoc_expand_once; + +/* The analog for indexed array subscripts */ +extern int array_expand_once; + +/* Flags for array_value_internal and callers array_value/get_array_value */ +#define AV_ALLOWALL 0x001 +#define AV_QUOTED 0x002 +#define AV_USEIND 0x004 +#define AV_USEVAL 0x008 /* XXX - should move this */ +#define AV_ASSIGNRHS 0x010 /* no splitting, special case ${a[@]} */ +#define AV_NOEXPAND 0x020 /* don't run assoc subscripts through word expansion */ + +/* Flags for valid_array_reference. Value 1 is reserved for skipsubscript() */ +#define VA_NOEXPAND 0x001 +#define VA_ONEWORD 0x002 + +extern SHELL_VAR *convert_var_to_array PARAMS((SHELL_VAR *)); +extern SHELL_VAR *convert_var_to_assoc PARAMS((SHELL_VAR *)); + +extern char *make_array_variable_value PARAMS((SHELL_VAR *, arrayind_t, char *, char *, int)); + +extern SHELL_VAR *bind_array_variable PARAMS((char *, arrayind_t, char *, int)); +extern SHELL_VAR *bind_array_element PARAMS((SHELL_VAR *, arrayind_t, char *, int)); +extern SHELL_VAR *assign_array_element PARAMS((char *, char *, int)); + +extern SHELL_VAR *bind_assoc_variable PARAMS((SHELL_VAR *, char *, char *, char *, int)); + +extern SHELL_VAR *find_or_make_array_variable PARAMS((char *, int)); + +extern SHELL_VAR *assign_array_from_string PARAMS((char *, char *, int)); +extern SHELL_VAR *assign_array_var_from_word_list PARAMS((SHELL_VAR *, WORD_LIST *, int)); + +extern WORD_LIST *expand_compound_array_assignment PARAMS((SHELL_VAR *, char *, int)); +extern void assign_compound_array_list PARAMS((SHELL_VAR *, WORD_LIST *, int)); +extern SHELL_VAR *assign_array_var_from_string PARAMS((SHELL_VAR *, char *, int)); + +extern char *expand_and_quote_assoc_word PARAMS((char *, int)); +extern void quote_compound_array_list PARAMS((WORD_LIST *, int)); + +extern int kvpair_assignment_p PARAMS((WORD_LIST *)); +extern char *expand_and_quote_kvpair_word PARAMS((char *)); + +extern int unbind_array_element PARAMS((SHELL_VAR *, char *, int)); +extern int skipsubscript PARAMS((const char *, int, int)); + +extern void print_array_assignment PARAMS((SHELL_VAR *, int)); +extern void print_assoc_assignment PARAMS((SHELL_VAR *, int)); + +extern arrayind_t array_expand_index PARAMS((SHELL_VAR *, char *, int, int)); +extern int valid_array_reference PARAMS((const char *, int)); +extern char *array_value PARAMS((const char *, int, int, int *, arrayind_t *)); +extern char *get_array_value PARAMS((const char *, int, int *, arrayind_t *)); + +extern char *array_keys PARAMS((char *, int, int)); + +extern char *array_variable_name PARAMS((const char *, int, char **, int *)); +extern SHELL_VAR *array_variable_part PARAMS((const char *, int, char **, int *)); + +#else + +#define AV_ALLOWALL 0 +#define AV_QUOTED 0 +#define AV_USEIND 0 +#define AV_ASSIGNRHS 0 + +#define VA_ONEWORD 0 + +#endif + +#endif /* !_ARRAYFUNC_H_ */ diff --git a/utshell-0.5.0/lib/include/assoc.h b/utshell-0.5.0/lib/include/assoc.h new file mode 100644 index 00000000..7143836f --- /dev/null +++ b/utshell-0.5.0/lib/include/assoc.h @@ -0,0 +1,66 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* assoc.h -- definitions for the interface exported by assoc.c that allows + the rest of the shell to manipulate associative array variables. */ + +/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _ASSOC_H_ +#define _ASSOC_H_ + +#include "stdc.h" +#include "hashlib.h" + +#define ASSOC_HASH_BUCKETS 1024 + +#define assoc_empty(h) ((h)->nentries == 0) +#define assoc_num_elements(h) ((h)->nentries) + +#define assoc_create(n) (hash_create((n))) + +#define assoc_copy(h) (hash_copy((h), 0)) + +#define assoc_walk(h, f) (hash_walk((h), (f)) + +extern void assoc_dispose PARAMS((HASH_TABLE *)); +extern void assoc_flush PARAMS((HASH_TABLE *)); + +extern int assoc_insert PARAMS((HASH_TABLE *, char *, char *)); +extern PTR_T assoc_replace PARAMS((HASH_TABLE *, char *, char *)); +extern void assoc_remove PARAMS((HASH_TABLE *, char *)); + +extern char *assoc_reference PARAMS((HASH_TABLE *, char *)); + +extern char *assoc_subrange PARAMS((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int)); +extern char *assoc_patsub PARAMS((HASH_TABLE *, char *, char *, int)); +extern char *assoc_modcase PARAMS((HASH_TABLE *, char *, int, int)); + +extern HASH_TABLE *assoc_quote PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_quote_escapes PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_dequote PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_dequote_escapes PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_remove_quoted_nulls PARAMS((HASH_TABLE *)); + +extern char *assoc_to_kvpair PARAMS((HASH_TABLE *, int)); +extern char *assoc_to_assign PARAMS((HASH_TABLE *, int)); + +extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *)); +extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *)); + +extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int)); +#endif /* _ASSOC_H_ */ diff --git a/utshell-0.5.0/lib/include/bashansi.h b/utshell-0.5.0/lib/include/bashansi.h new file mode 100644 index 00000000..0010de95 --- /dev/null +++ b/utshell-0.5.0/lib/include/bashansi.h @@ -0,0 +1,42 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashansi.h -- Typically included information required by picky compilers. */ + +/* Copyright (C) 1993-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHANSI_H_) +#define _BASHANSI_H_ + +#if defined (HAVE_STRING_H) +# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H) +# include +# endif +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STRINGS_H) +# include +#endif /* !HAVE_STRINGS_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* !HAVE_STDLIB_H */ + +#endif /* !_BASHANSI_H_ */ diff --git a/utshell-0.5.0/lib/include/bashintl.h b/utshell-0.5.0/lib/include/bashintl.h new file mode 100644 index 00000000..90810cbe --- /dev/null +++ b/utshell-0.5.0/lib/include/bashintl.h @@ -0,0 +1,55 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashintl.h -- Internationalization functions and defines. */ + +/* Copyright (C) 1996-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHINTL_H_) +#define _BASHINTL_H_ + +#if defined (BUILDTOOL) +# undef ENABLE_NLS +# define ENABLE_NLS 0 +#endif + +/* Include this *after* config.h */ +#include "gettext.h" + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#define _(msgid) gettext(msgid) +#define N_(msgid) msgid +#define D_(d, msgid) dgettext(d, msgid) + +#define P_(m1, m2, n) ngettext(m1, m2, n) + +#if defined (HAVE_SETLOCALE) && !defined (LC_ALL) +# undef HAVE_SETLOCALE +#endif + +#if !defined (HAVE_SETLOCALE) +# define setlocale(cat, loc) +#endif + +#if !defined (HAVE_LOCALE_H) || !defined (HAVE_LOCALECONV) +# define locale_decpoint() '.' +#endif + +#endif /* !_BASHINTL_H_ */ diff --git a/utshell-0.5.0/lib/include/bashjmp.h b/utshell-0.5.0/lib/include/bashjmp.h new file mode 100644 index 00000000..bfcf102f --- /dev/null +++ b/utshell-0.5.0/lib/include/bashjmp.h @@ -0,0 +1,47 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashjmp.h -- wrapper for setjmp.h with necessary bash definitions. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _BASHJMP_H_ +#define _BASHJMP_H_ + +#include "posixjmp.h" + +extern procenv_t top_level; +extern procenv_t subshell_top_level; +extern procenv_t return_catch; /* used by `return' builtin */ +extern procenv_t wait_intr_buf; + +extern int no_longjmp_on_fatal_error; + +#define SHFUNC_RETURN() sh_longjmp (return_catch, 1) + +#define COPY_PROCENV(old, save) \ + xbcopy ((char *)old, (char *)save, sizeof (procenv_t)); + +/* Values for the second argument to longjmp/siglongjmp. */ +#define NOT_JUMPED 0 /* Not returning from a longjmp. */ +#define FORCE_EOF 1 /* We want to stop parsing. */ +#define DISCARD 2 /* Discard current command. */ +#define EXITPROG 3 /* Unconditionally exit the program now. */ +#define ERREXIT 4 /* Exit due to error condition */ +#define SIGEXIT 5 /* Exit due to fatal terminating signal */ + +#endif /* _BASHJMP_H_ */ diff --git a/utshell-0.5.0/lib/include/bashtypes.h b/utshell-0.5.0/lib/include/bashtypes.h new file mode 100644 index 00000000..33eda19a --- /dev/null +++ b/utshell-0.5.0/lib/include/bashtypes.h @@ -0,0 +1,43 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashtypes.h -- Bash system types. */ + +/* Copyright (C) 1993-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHTYPES_H_) +# define _BASHTYPES_H_ + +#if defined (CRAY) +# define word __word +#endif + +#include + +#if defined (CRAY) +# undef word +#endif + +#if defined (HAVE_INTTYPES_H) +# include +#endif + +#if HAVE_STDINT_H +# include +#endif + +#endif /* _BASHTYPES_H_ */ diff --git a/utshell-0.5.0/lib/include/builtins.h b/utshell-0.5.0/lib/include/builtins.h new file mode 100644 index 00000000..f57437bb --- /dev/null +++ b/utshell-0.5.0/lib/include/builtins.h @@ -0,0 +1,69 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* builtins.h -- What a builtin looks like, and where to find them. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef BUILTINS_H +#define BUILTINS_H + +#include "config.h" + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "command.h" +#include "general.h" + +#if defined (ALIAS) +#include "alias.h" +#endif + +/* Flags describing various things about a builtin. */ +#define BUILTIN_ENABLED 0x01 /* This builtin is enabled. */ +#define BUILTIN_DELETED 0x02 /* This has been deleted with enable -d. */ +#define STATIC_BUILTIN 0x04 /* This builtin is not dynamically loaded. */ +#define SPECIAL_BUILTIN 0x08 /* This is a Posix `special' builtin. */ +#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ +#define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */ +#define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */ +#define REQUIRES_BUILTIN 0x80 /* This builtin requires other files. */ + +#define BASE_INDENT 4 + +/* The thing that we build the array of builtins out of. */ +struct builtin { + char *name; /* The name that the user types. */ + sh_builtin_func_t *function; /* The address of the invoked function. */ + int flags; /* One of the #defines above. */ + char * const *long_doc; /* NULL terminated array of strings. */ + const char *short_doc; /* Short version of documentation. */ + char *handle; /* for future use */ +}; + +/* Found in builtins.c, created by builtins/mkbuiltins. */ +extern int num_shell_builtins; /* Number of shell builtins. */ +extern struct builtin static_shell_builtins[]; +extern struct builtin *shell_builtins; +extern struct builtin *current_builtin; + +#endif /* BUILTINS_H */ diff --git a/utshell-0.5.0/lib/include/chartypes.h b/utshell-0.5.0/lib/include/chartypes.h new file mode 100644 index 00000000..098cfb96 --- /dev/null +++ b/utshell-0.5.0/lib/include/chartypes.h @@ -0,0 +1,113 @@ +/* chartypes.h -- extend ctype.h */ + +/* Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _SH_CHARTYPES_H +#define _SH_CHARTYPES_H + +#include + +/* Jim Meyering writes: + + "... Some ctype macros are valid only for character codes that + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when + using /bin/cc or gcc but without giving an ansi option). So, all + ctype uses should be through macros like ISPRINT... If + STDC_HEADERS is defined, then autoconf has verified that the ctype + macros don't need to be guarded with references to isascii. ... + Defining IN_CTYPE_DOMAIN to 1 should let any compiler worth its salt + eliminate the && through constant folding." + Solaris defines some of these symbols so we must undefine them first. */ + +#if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#if !defined (isspace) && !defined (HAVE_ISSPACE) +# define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f') +#endif + +#if !defined (isprint) && !defined (HAVE_ISPRINT) +# define isprint(c) (isalpha((unsigned char)c) || isdigit((unsigned char)c) || ispunct((unsigned char)c)) +#endif + +#if defined (isblank) || defined (HAVE_ISBLANK) +# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank ((unsigned char)c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif + +#if defined (isgraph) || defined (HAVE_ISGRAPH) +# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c)) +#else +# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c) && !isspace ((unsigned char)c)) +#endif + +#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) +# define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#undef ISPRINT + +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c)) +#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c)) +#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c)) +#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c)) +#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char)c)) +#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c)) +#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct ((unsigned char)c)) +#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char)c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c)) +#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c)) + +#define ISLETTER(c) (ISALPHA(c)) + +#define DIGIT(c) ((c) >= '0' && (c) <= '9') + +#define ISWORD(c) (ISLETTER(c) || DIGIT(c) || ((c) == '_')) + +#define HEXVALUE(c) \ + (((c) >= 'a' && (c) <= 'f') \ + ? (c)-'a'+10 \ + : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') + +#ifndef ISOCTAL +# define ISOCTAL(c) ((c) >= '0' && (c) <= '7') +#endif +#define OCTVALUE(c) ((c) - '0') + +#define TODIGIT(c) ((c) - '0') +#define TOCHAR(c) ((c) + '0') + +#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c)) +#define TOUPPER(c) (ISLOWER(c) ? toupper(c) : (c)) + +#ifndef TOCTRL + /* letter to control char -- ASCII. The TOUPPER is in there so \ce and + \cE will map to the same character in $'...' expansions. */ +# define TOCTRL(x) ((x) == '?' ? 0x7f : (TOUPPER(x) & 0x1f)) +#endif +#ifndef UNCTRL + /* control char to letter -- ASCII */ +# define UNCTRL(x) (TOUPPER(x) ^ 0x40) +#endif + +#endif /* _SH_CHARTYPES_H */ diff --git a/utshell-0.5.0/lib/include/command.h b/utshell-0.5.0/lib/include/command.h new file mode 100644 index 00000000..6dc337fb --- /dev/null +++ b/utshell-0.5.0/lib/include/command.h @@ -0,0 +1,409 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* command.h -- The structures used internally to represent commands, and + the extern declarations of the functions used to create them. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_COMMAND_H_) +#define _COMMAND_H_ + +#include "stdc.h" + +/* Instructions describing what kind of thing to do for a redirection. */ +enum r_instruction { + r_output_direction, r_input_direction, r_inputa_direction, + r_appending_to, r_reading_until, r_reading_string, + r_duplicating_input, r_duplicating_output, r_deblank_reading_until, + r_close_this, r_err_and_out, r_input_output, r_output_force, + r_duplicating_input_word, r_duplicating_output_word, + r_move_input, r_move_output, r_move_input_word, r_move_output_word, + r_append_err_and_out +}; + +/* Redirection flags; values for rflags */ +#define REDIR_VARASSIGN 0x01 + +/* Redirection errors. */ +#define AMBIGUOUS_REDIRECT -1 +#define NOCLOBBER_REDIRECT -2 +#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */ +#define HEREDOC_REDIRECT -4 /* here-doc temp file can't be created */ +#define BADVAR_REDIRECT -5 /* something wrong with {varname}redir */ + +#define CLOBBERING_REDIRECT(ri) \ + (ri == r_output_direction || ri == r_err_and_out) + +#define OUTPUT_REDIRECT(ri) \ + (ri == r_output_direction || ri == r_input_output || ri == r_err_and_out || ri == r_append_err_and_out) + +#define INPUT_REDIRECT(ri) \ + (ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output) + +#define WRITE_REDIRECT(ri) \ + (ri == r_output_direction || \ + ri == r_input_output || \ + ri == r_err_and_out || \ + ri == r_appending_to || \ + ri == r_append_err_and_out || \ + ri == r_output_force) + +/* redirection needs translation */ +#define TRANSLATE_REDIRECT(ri) \ + (ri == r_duplicating_input_word || ri == r_duplicating_output_word || \ + ri == r_move_input_word || ri == r_move_output_word) + +/* Command Types: */ +enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, + cm_connection, cm_function_def, cm_until, cm_group, + cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc }; + +/* Possible values for the `flags' field of a WORD_DESC. */ +#define W_HASDOLLAR (1 << 0) /* Dollar sign present. */ +#define W_QUOTED (1 << 1) /* Some form of quote character is present. */ +#define W_ASSIGNMENT (1 << 2) /* This word is a variable assignment. */ +#define W_SPLITSPACE (1 << 3) /* Split this word on " " regardless of IFS */ +#define W_NOSPLIT (1 << 4) /* Do not perform word splitting on this word because ifs is empty string. */ +#define W_NOGLOB (1 << 5) /* Do not perform globbing on this word. */ +#define W_NOSPLIT2 (1 << 6) /* Don't split word except for $@ expansion (using spaces) because context does not allow it. */ +#define W_TILDEEXP (1 << 7) /* Tilde expand this assignment word */ +#define W_DOLLARAT (1 << 8) /* $@ and its special handling -- UNUSED */ +#define W_DOLLARSTAR (1 << 9) /* $* and its special handling -- UNUSED */ +#define W_NOCOMSUB (1 << 10) /* Don't perform command substitution on this word */ +#define W_ASSIGNRHS (1 << 11) /* Word is rhs of an assignment statement */ +#define W_NOTILDE (1 << 12) /* Don't perform tilde expansion on this word */ +#define W_ITILDE (1 << 13) /* Internal flag for word expansion */ +#define W_EXPANDRHS (1 << 14) /* Expanding word in ${paramOPword} */ +#define W_COMPASSIGN (1 << 15) /* Compound assignment */ +#define W_ASSNBLTIN (1 << 16) /* word is a builtin command that takes assignments */ +#define W_ASSIGNARG (1 << 17) /* word is assignment argument to command */ +#define W_HASQUOTEDNULL (1 << 18) /* word contains a quoted null character */ +#define W_DQUOTE (1 << 19) /* word should be treated as if double-quoted */ +#define W_NOPROCSUB (1 << 20) /* don't perform process substitution */ +#define W_SAWQUOTEDNULL (1 << 21) /* word contained a quoted null that was removed */ +#define W_ASSIGNASSOC (1 << 22) /* word looks like associative array assignment */ +#define W_ASSIGNARRAY (1 << 23) /* word looks like a compound indexed array assignment */ +#define W_ARRAYIND (1 << 24) /* word is an array index being expanded */ +#define W_ASSNGLOBAL (1 << 25) /* word is a global assignment to declare (declare/typeset -g) */ +#define W_NOBRACE (1 << 26) /* Don't perform brace expansion */ +#define W_COMPLETE (1 << 27) /* word is being expanded for completion */ +#define W_CHKLOCAL (1 << 28) /* check for local vars on assignment */ +#define W_NOASSNTILDE (1 << 29) /* don't do tilde expansion like an assignment statement */ +#define W_FORCELOCAL (1 << 30) /* force assignments to be to local variables, non-fatal on assignment errors */ + +/* Flags for the `pflags' argument to param_expand() and various + parameter_brace_expand_xxx functions; also used for string_list_dollar_at */ +#define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ +#define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */ +#define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */ +#define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */ +#define PF_COMPLETE 0x10 /* same as W_COMPLETE, sets SX_COMPLETE */ +#define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */ +#define PF_ALLINDS 0x40 /* array, act as if [@] was supplied */ + +/* Possible values for subshell_environment */ +#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */ +#define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */ +#define SUBSHELL_COMSUB 0x04 /* subshell caused by `command` or $(command) */ +#define SUBSHELL_FORK 0x08 /* subshell caused by executing a disk command */ +#define SUBSHELL_PIPE 0x10 /* subshell from a pipeline element */ +#define SUBSHELL_PROCSUB 0x20 /* subshell caused by <(command) or >(command) */ +#define SUBSHELL_COPROC 0x40 /* subshell from a coproc pipeline */ +#define SUBSHELL_RESETTRAP 0x80 /* subshell needs to reset trap strings on first call to trap */ + +/* A structure which represents a word. */ +typedef struct word_desc { + char *word; /* Zero terminated string. */ + int flags; /* Flags associated with this word. */ +} WORD_DESC; + +/* A linked list of words. */ +typedef struct word_list { + struct word_list *next; + WORD_DESC *word; +} WORD_LIST; + + +/* **************************************************************** */ +/* */ +/* Shell Command Structs */ +/* */ +/* **************************************************************** */ + +/* What a redirection descriptor looks like. If the redirection instruction + is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise + use the file in FILENAME. Out-of-range descriptors are identified by a + negative DEST. */ + +typedef union { + int dest; /* Place to redirect REDIRECTOR to, or ... */ + WORD_DESC *filename; /* filename to redirect to. */ +} REDIRECTEE; + +/* Structure describing a redirection. If REDIRECTOR is negative, the parser + (or translator in redir.c) encountered an out-of-range file descriptor. */ +typedef struct redirect { + struct redirect *next; /* Next element, or NULL. */ + REDIRECTEE redirector; /* Descriptor or varname to be redirected. */ + int rflags; /* Private flags for this redirection */ + int flags; /* Flag value for `open'. */ + enum r_instruction instruction; /* What to do with the information. */ + REDIRECTEE redirectee; /* File descriptor or filename */ + char *here_doc_eof; /* The word that appeared in <flags. */ +#define CMD_WANT_SUBSHELL 0x01 /* User wants a subshell: ( command ) */ +#define CMD_FORCE_SUBSHELL 0x02 /* Shell needs to force a subshell. */ +#define CMD_INVERT_RETURN 0x04 /* Invert the exit value. */ +#define CMD_IGNORE_RETURN 0x08 /* Ignore the exit value. For set -e. */ +#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */ +#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */ +#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */ +#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */ +#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */ +#define CMD_AMPERSAND 0x200 /* command & */ +#define CMD_STDIN_REDIR 0x400 /* async command needs implicit . +*/ + +/*********************************************************/ +/* Modify or set defines based on the configure results. */ +/*********************************************************/ + +#if !defined (HAVE_VPRINTF) && defined (HAVE_DOPRNT) +# define USE_VFPRINTF_EMULATION +# define HAVE_VPRINTF +#endif + +#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRLIMIT) +# define HAVE_RESOURCE +#endif + +#if !defined (GETPGRP_VOID) +# define HAVE_BSD_PGRP +#endif + +/* Try this without testing __STDC__ for the time being. */ +#if defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +#else +# if defined (HAVE_VARARGS_H) +# define PREFER_VARARGS +# define USE_VARARGS +# endif +#endif + +#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && defined (HAVE_NETINET_IN_H) +# define HAVE_NETWORK +#endif + +#if defined (HAVE_REGEX_H) && defined (HAVE_REGCOMP) && defined (HAVE_REGEXEC) +# define HAVE_POSIX_REGEXP +#endif + +/* backwards compatibility between different autoconf versions */ +#if HAVE_DECL_SYS_SIGLIST && !defined (SYS_SIGLIST_DECLARED) +# define SYS_SIGLIST_DECLARED +#endif + +/***********************************************************************/ +/* Unset defines based on what configure reports as missing or broken. */ +/***********************************************************************/ + +/* Ultrix botches type-ahead when switching from canonical to + non-canonical mode, at least through version 4.3 */ +#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix) +# define TERMIOS_MISSING +#endif + +/* If we have a getcwd(3), but one that does not dynamically allocate memory, + #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do + not do this on Solaris, because their implementation of loopback mounts + breaks the traditional file system assumptions that getcwd uses. */ +#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS) +# undef HAVE_GETCWD +#endif + +#if !defined (HAVE_DEV_FD) && defined (NAMED_PIPES_MISSING) +# undef PROCESS_SUBSTITUTION +#endif + +#if defined (JOB_CONTROL_MISSING) +# undef JOB_CONTROL +#endif + +#if defined (STRCOLL_BROKEN) +# undef HAVE_STRCOLL +#endif + +#if !defined (HAVE_POSIX_REGEXP) +# undef COND_REGEXP +#endif + +#if !HAVE_MKSTEMP +# undef USE_MKSTEMP +#endif + +#if !HAVE_MKDTEMP +# undef USE_MKDTMP +#endif + +/* If the shell is called by this name, it will become restricted. */ +#if defined (RESTRICTED_SHELL) +# define RESTRICTED_SHELL_NAME "rbash" +#endif + +/***********************************************************/ +/* Make sure feature defines have necessary prerequisites. */ +/***********************************************************/ + +/* BANG_HISTORY requires HISTORY. */ +#if defined (BANG_HISTORY) && !defined (HISTORY) +# define HISTORY +#endif /* BANG_HISTORY && !HISTORY */ + +#if defined (READLINE) && !defined (HISTORY) +# define HISTORY +#endif + +#if defined (PROGRAMMABLE_COMPLETION) && !defined (READLINE) +# undef PROGRAMMABLE_COMPLETION +#endif + +#if !defined (V9_ECHO) +# undef DEFAULT_ECHO_TO_XPG +#endif + +#if !defined (PROMPT_STRING_DECODE) +# undef PPROMPT +# define PPROMPT "$ " +#endif + +#if !defined (HAVE_SYSLOG) || !defined (HAVE_SYSLOG_H) +# undef SYSLOG_HISTORY +#endif + +/************************************************/ +/* check multibyte capability for I18N code */ +/************************************************/ + +/* For platforms which support the ISO C amendment 1 functionality we + support user defined character classes. */ +/* Solaris 2.5 has a bug: must be included before . */ +#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H) +# include +# include +# if defined (HAVE_ISWCTYPE) && \ + defined (HAVE_ISWLOWER) && \ + defined (HAVE_ISWUPPER) && \ + defined (HAVE_MBSRTOWCS) && \ + defined (HAVE_MBRTOWC) && \ + defined (HAVE_MBRLEN) && \ + defined (HAVE_TOWLOWER) && \ + defined (HAVE_TOWUPPER) && \ + defined (HAVE_WCHAR_T) && \ + defined (HAVE_WCTYPE_T) && \ + defined (HAVE_WINT_T) && \ + defined (HAVE_WCWIDTH) && \ + defined (HAVE_WCTYPE) + /* system is supposed to support XPG5 */ +# define HANDLE_MULTIBYTE 1 +# endif +#endif + +/* If we don't want multibyte chars even on a system that supports them, let + the configuring user turn multibyte support off. */ +#if defined (NO_MULTIBYTE_SUPPORT) +# undef HANDLE_MULTIBYTE +#endif + +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ +#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T) +# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0) +# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0) +# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0) +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +# define mbrlen(s, n, ps) (mbrlen) (s, n, 0) +# define mbstate_t int +#endif + +/* Make sure MB_LEN_MAX is at least 16 (some systems define + MB_LEN_MAX as 1) */ +#ifdef HANDLE_MULTIBYTE +# include +# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16) +# undef MB_LEN_MAX +# endif +# if !defined (MB_LEN_MAX) +# define MB_LEN_MAX 16 +# endif +#endif + +/************************************************/ +/* end of multibyte capability checks for I18N */ +/************************************************/ + +/******************************************************************/ +/* Placeholder for builders to #undef any unwanted features from */ +/* config-top.h or created by configure (such as the default mail */ +/* file for mail checking). */ +/******************************************************************/ + +/* If you don't want bash to provide a default mail file to check. */ +/* #undef DEFAULT_MAIL_DIRECTORY */ diff --git a/utshell-0.5.0/lib/include/config-top.h b/utshell-0.5.0/lib/include/config-top.h new file mode 100644 index 00000000..04ea05fe --- /dev/null +++ b/utshell-0.5.0/lib/include/config-top.h @@ -0,0 +1,200 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* config-top.h - various user-settable options not under the control of autoconf. */ + +/* Copyright (C) 2002-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to + continue processing arguments after one of them fails. This is + what POSIX.2 specifies. */ +#define CONTINUE_AFTER_KILL_ERROR + +#define NON_INTERACTIVE_LOGIN_SHELLS + +/* Define BREAK_COMPLAINS if you want the non-standard, but useful + error messages about `break' and `continue' out of context. */ +#define BREAK_COMPLAINS + +/* Define CD_COMPLAINS if you want the non-standard, but sometimes-desired + error messages about multiple directory arguments to `cd'. */ +#define CD_COMPLAINS + +/* Define BUFFERED_INPUT if you want the shell to do its own input + buffering, rather than using stdio. Do not undefine this; it's + required to preserve semantics required by POSIX. */ +#define BUFFERED_INPUT + +/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute + `command' whenever possible. This is a big efficiency improvement. */ +#define ONESHOT + +/* Define V9_ECHO if you want to give the echo builtin backslash-escape + interpretation using the -e option, in the style of the Bell Labs 9th + Edition version of echo. You cannot emulate the System V echo behavior + without this option. */ +#define V9_ECHO + +/* Define DONT_REPORT_SIGPIPE if you don't want to see `Broken pipe' messages + when a job like `cat jobs.c | exit 1' terminates due to a SIGPIPE. */ +#define DONT_REPORT_SIGPIPE + +/* Define DONT_REPORT_SIGTERM if you don't want to see `Terminates' message + when a job exits due to SIGTERM, since that's the default signal sent + by the kill builtin. */ +#define DONT_REPORT_SIGTERM + +/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins + like `echo' and `printf' to report errors when output does not succeed + due to EPIPE. */ +#define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS + +/* The default value of the PATH variable. */ +#ifndef DEFAULT_PATH_VALUE +#define DEFAULT_PATH_VALUE \ + "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:." +#endif + +/* If you want to unconditionally set a value for PATH in every restricted + shell, set this. */ +/* #define RBASH_STATIC_PATH_VALUE "/rbin:/usr/rbin" */ + +/* The value for PATH when invoking `command -p'. This is only used when + the Posix.2 confstr () function, or CS_PATH define are not present. */ +#ifndef STANDARD_UTILS_PATH +#define STANDARD_UTILS_PATH \ + "/bin:/usr/bin:/usr/sbin:/sbin" +#endif + +/* Default primary and secondary prompt strings. */ +#define PPROMPT "\\s-\\v\\$ " +#define SPROMPT "> " + +/* Undefine this if you don't want the ksh-compatible behavior of reprinting + the select menu after a valid choice is made only if REPLY is set to NULL + in the body of the select command. The menu is always reprinted if the + reply to the select query is an empty line. */ +#define KSH_COMPATIBLE_SELECT + +/* Default interactive shell startup file. */ +// #define DEFAULT_BASHRC "~/.bashrc" +#define DEFAULT_BASHRC "~/.utshellrc" + +/* System-wide .bashrc file for interactive shells. */ +/* #define SYS_BASHRC "/etc/bash.bashrc" */ + +/* System-wide .bash_logout for login shells. */ +// #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" +#define SYS_BASH_LOGOUT "/etc/utshell.utshell_logout" + +/* Define this to make non-interactive shells begun with argv[0][0] == '-' + run the startup files when not in posix mode. */ +/* #define NON_INTERACTIVE_LOGIN_SHELLS */ + +/* Define this if you want bash to try to check whether it's being run by + sshd and source the .bashrc if so (like the rshd behavior). This checks + for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment, + which can be fooled under certain not-uncommon circumstances. */ +#define SSH_SOURCE_BASHRC + +/* Define if you want the case-toggling operators (~[~]) and the + `capcase' variable attribute (declare -c). */ +/* TAG: bash-5.2 disable */ +#define CASEMOD_TOGGLECASE +#define CASEMOD_CAPCASE + +/* This is used as the name of a shell function to call when a command + name is not found. If you want to name it something other than the + default ("command_not_found_handle"), change it here. */ +/* #define NOTFOUND_HOOK "command_not_found_handle" */ + +/* Define if you want each line saved to the history list in bashhist.c: + bash_add_history() to be sent to syslog(). */ +/* #define SYSLOG_HISTORY */ +#if defined (SYSLOG_HISTORY) +# define SYSLOG_FACILITY LOG_USER +# define SYSLOG_LEVEL LOG_INFO +# define OPENLOG_OPTS LOG_PID +#endif + +/* Define if you want syslogging history to be controllable at runtime via a + shell option; if defined, the value is the default for the syslog_history + shopt option */ +#if defined (SYSLOG_HISTORY) +/* #define SYSLOG_SHOPT 1 */ +#endif + +/* Define if you want to include code in shell.c to support wordexp(3) */ +/* #define WORDEXP_OPTION */ + +/* Define as 1 if you want to enable code that implements multiple coprocs + executing simultaneously */ +#ifndef MULTIPLE_COPROCS +# define MULTIPLE_COPROCS 0 +#endif + +/* Define to 0 if you want the checkwinsize option off by default, 1 if you + want it on. */ +#define CHECKWINSIZE_DEFAULT 1 + +/* Define to 1 if you want to optimize for sequential array assignment when + using indexed arrays, 0 if you want bash-4.2 behavior, which favors + random access but is O(N) for each array assignment. */ +#define OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT 1 + +/* Define to 1 if you want to be able to export indexed arrays to processes + using the foo=([0]=one [1]=two) and so on */ +/* #define ARRAY_EXPORT 1 */ + +/* Define to 1 if you want the shell to exit if it is running setuid and its + attempt to drop privilege using setuid(getuid()) fails with errno == EAGAIN */ +/* #define EXIT_ON_SETUID_FAILURE 1 */ + +/* Define to 1 if you want the shell to re-check $PATH if a hashed filename + no longer exists. This behavior is the default in Posix mode. */ +#define CHECKHASH_DEFAULT 0 + +/* Define to the maximum level of recursion you want for the eval builtin + and trap handlers (since traps are run as if run by eval). + 0 means the limit is not active. */ +#define EVALNEST_MAX 0 + +/* Define to the maximum level of recursion you want for the source/. builtin. + 0 means the limit is not active. */ +#define SOURCENEST_MAX 0 + +/* Define to use libc mktemp/mkstemp instead of replacements in lib/sh/tmpfile.c */ +#define USE_MKTEMP +#define USE_MKSTEMP +#define USE_MKDTEMP + +/* Define to force the value of OLDPWD inherited from the environment to be a + directory */ +#define OLDPWD_CHECK_DIRECTORY 1 + +/* Define to set the initial size of the history list ($HISTSIZE). This must + be a string. */ +/*#define HISTSIZE_DEFAULT "500"*/ + +/* Define to 0 if you want history expansion to be disabled by default in + interactive shells; define to 1 for the historical behavior of enabling + when the shell is interactive. */ +#define HISTEXPAND_DEFAULT 1 + +/* Undefine or define to 0 if you don't want to allow associative array + assignment using a compound list of key-value pairs. */ +#define ASSOC_KVPAIR_ASSIGNMENT 1 diff --git a/utshell-0.5.0/lib/include/config.h b/utshell-0.5.0/lib/include/config.h new file mode 100644 index 00000000..e7263782 --- /dev/null +++ b/utshell-0.5.0/lib/include/config.h @@ -0,0 +1,1250 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h -- Configuration file for bash. */ + +/* Copyright (C) 1987-2009,2011-2012,2013-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* Template settings for autoconf */ + +#define __EXTENSIONS__ 1 +#define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 +/* #undef _POSIX_SOURCE */ +/* #undef _POSIX_1_SOURCE */ +#define _POSIX_PTHREAD_SEMANTICS 1 +#define _TANDEM_SOURCE 1 +/* #undef _MINIX */ + +/* Configuration feature settings controllable by autoconf. */ + +/* Define JOB_CONTROL if your operating system supports + BSD-like job control. */ +#define JOB_CONTROL 1 + +/* Define ALIAS if you want the alias features. */ +#define ALIAS 1 + +/* Define PUSHD_AND_POPD if you want those commands to be compiled in. + (Also the `dirs' commands.) */ +#define PUSHD_AND_POPD 1 + +/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh: + foo{a,b} -> fooa foob. Even if this is compiled in (the default) you + can turn it off at shell startup with `-nobraceexpansion', or during + shell execution with `set +o braceexpand'. */ +#define BRACE_EXPANSION 1 + +/* Define READLINE to get the nifty/glitzy editing features. + This is on by default. You can turn it off interactively + with the -nolineediting flag. */ +#define READLINE 1 + +/* Define BANG_HISTORY if you want to have Csh style "!" history expansion. + This is unrelated to READLINE. */ +#define BANG_HISTORY 1 + +/* Define HISTORY if you want to have access to previously typed commands. + + If both HISTORY and READLINE are defined, you can get at the commands + with line editing commands, and you can directly manipulate the history + from the command line. + + If only HISTORY is defined, the `fc' and `history' builtins are + available. */ +#define HISTORY 1 + +/* Define this if you want completion that puts all alternatives into + a brace expansion shell expression. */ +#if defined (BRACE_EXPANSION) && defined (READLINE) +# define BRACE_COMPLETION +#endif /* BRACE_EXPANSION */ + +/* Define DEFAULT_ECHO_TO_XPG if you want the echo builtin to interpret + the backslash-escape characters by default, like the XPG Single Unix + Specification V2 for echo. + This requires that V9_ECHO be defined. */ +/* #undef DEFAULT_ECHO_TO_XPG */ + +/* Define HELP_BUILTIN if you want the `help' shell builtin and the long + documentation strings compiled into the shell. */ +#define HELP_BUILTIN 1 + +/* Define RESTRICTED_SHELL if you want the generated shell to have the + ability to be a restricted one. The shell thus generated can become + restricted by being run with the name "rbash", or by setting the -r + flag. */ +#define RESTRICTED_SHELL 1 + +/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the + shell builtin "foo", even if it has been disabled with "enable -n foo". */ +/* #undef DISABLED_BUILTINS */ + +/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process + substitution features "<(file)". */ +/* Right now, you cannot do this on machines without fully operational + FIFO support. This currently include NeXT and Alliant. */ +#define PROCESS_SUBSTITUTION 1 + +/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special + characters in PS1 and PS2 expanded. Variable expansion will still be + performed. */ +#define PROMPT_STRING_DECODE 1 + +/* Define SELECT_COMMAND if you want the Korn-shell style `select' command: + select word in word_list; do command_list; done */ +#define SELECT_COMMAND 1 + +/* Define COMMAND_TIMING of you want the ksh-style `time' reserved word and + the ability to time pipelines, functions, and builtins. */ +#define COMMAND_TIMING 1 + +/* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */ +#define ARRAY_VARS 1 + +/* Define DPAREN_ARITHMETIC if you want the ksh-style ((...)) arithmetic + evaluation command. */ +#define DPAREN_ARITHMETIC 1 + +/* Define EXTENDED_GLOB if you want the ksh-style [*+@?!](patlist) extended + pattern matching. */ +#define EXTENDED_GLOB 1 + +/* Define EXTGLOB_DEFAULT to the value you'd like the extglob shell option + to have by default */ +#define EXTGLOB_DEFAULT 0 + +/* Define COND_COMMAND if you want the ksh-style [[...]] conditional + command. */ +#define COND_COMMAND 1 + +/* Define COND_REGEXP if you want extended regular expression matching and the + =~ binary operator in the [[...]] conditional command. */ +#define COND_REGEXP 1 + +/* Define COPROCESS_SUPPORT if you want support for ksh-like coprocesses and + the `coproc' reserved word */ +#define COPROCESS_SUPPORT 1 + +/* Define ARITH_FOR_COMMAND if you want the ksh93-style + for (( init; test; step )) do list; done + arithmetic for command. */ +#define ARITH_FOR_COMMAND 1 + +/* Define NETWORK_REDIRECTIONS if you want /dev/(tcp|udp)/host/port to open + socket connections when used in redirections */ +#define NETWORK_REDIRECTIONS 1 + +/* Define PROGRAMMABLE_COMPLETION for the programmable completion features + and the complete builtin. */ +#define PROGRAMMABLE_COMPLETION 1 + +/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte + characters, even if the OS supports them. */ +/* #undef NO_MULTIBYTE_SUPPORT */ + +/* Define DEBUGGER if you want to compile in some features used only by the + bash debugger. */ +#define DEBUGGER 1 + +/* Define STRICT_POSIX if you want bash to be strictly posix.2 conformant by + default (except for echo; that is controlled separately). */ +/* #undef STRICT_POSIX */ + +/* Define MEMSCRAMBLE if you want the bash malloc and free to scramble + memory contents on malloc() and free(). */ +#define MEMSCRAMBLE 1 + +/* Define for case-modifying variable attributes; variables modified on + assignment */ +#define CASEMOD_ATTRS 1 + +/* Define for case-modifying word expansions */ +#define CASEMOD_EXPANSIONS 1 + +/* Define to make the `direxpand' shopt option enabled by default. */ +/* #undef DIRCOMPLETE_EXPAND_DEFAULT */ + +/* Define to make the `globasciiranges' shopt option enabled by default. */ +#define GLOBASCII_DEFAULT 1 + +/* Define to allow functions to be imported from the environment. */ +#define FUNCTION_IMPORT 1 + +/* Define AFS if you are using Transarc's AFS. */ +/* #undef AFS */ + +#define ENABLE_NLS 1 + +/* End of configuration settings controllable by autoconf. */ +/* Other settable options appear in config-top.h. */ + +#include "config-top.h" + +/* Beginning of autoconf additions. */ + +/* Characteristics of the C compiler */ +/* #undef const */ + +/* #undef inline */ + +#define restrict __restrict__ + +/* #undef volatile */ + +/* Define if cpp supports the ANSI-C stringizing `#' operator */ +#define HAVE_STRINGIZE 1 + +/* Define if the compiler supports `long double' variables. */ +#define HAVE_LONG_DOUBLE 1 + +#define PROTOTYPES 1 +#define __PROTOTYPES 1 + +/* #undef __CHAR_UNSIGNED__ */ + +/* Define if the compiler supports `long long' variables. */ +#define HAVE_LONG_LONG 1 + +#define HAVE_UNSIGNED_LONG_LONG 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 8 + +/* The number of bytes in a pointer to char. */ +#define SIZEOF_CHAR_P 8 + +/* The number of bytes in a double (hopefully 8). */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in an `intmax_t'. */ +#define SIZEOF_INTMAX_T 8 + +/* The number of bytes in a `long long', if we have one. */ +#define SIZEOF_LONG_LONG 8 + +/* The number of bytes in a `wchar_t', if supported */ +#define SIZEOF_WCHAR_T 4 + +/* System paths */ + +#define DEFAULT_MAIL_DIRECTORY "/var/mail" + +/* Characteristics of the system's header files and libraries that affect + the compilation environment. */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to use GNU libc extensions */ +#define _GNU_SOURCE 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Memory management functions. */ + +/* Define if using the bash version of malloc in lib/malloc/malloc.c */ +/* #undef USING_BASH_MALLOC */ + +/* #undef DISABLE_MALLOC_WRAPPERS */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if major/minor/makedev is defined in */ +/* #undef MAJOR_IN_MAKEDEV */ + +/* Define if major/minor/makedev is defined in */ +#define MAJOR_IN_SYSMACROS 1 + +/* SYSTEM TYPES */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `int' if doesn't define. */ +/* #undef sigset_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define to `short' if doesn't define. */ +#define bits16_t short + +/* Define to `unsigned short' if doesn't define. */ +#define u_bits16_t unsigned short + +/* Define to `int' if doesn't define. */ +#define bits32_t int + +/* Define to `unsigned int' if doesn't define. */ +#define u_bits32_t unsigned int + +/* Define to `double' if doesn't define. */ +#define bits64_t char * + +/* Define to `unsigned int' if doesn't define. */ +/* #undef u_int */ + +/* Define to `unsigned long' if doesn't define. */ +/* #undef u_long */ + +/* Define to `int' if doesn't define. */ +/* #undef ptrdiff_t */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define to `int' if doesn't define. */ +/* #undef ssize_t */ + +/* Define to `long' if doesn't define. */ +/* #undef intmax_t */ + +/* Define to `unsigned long' if doesn't define. */ +/* #undef uintmax_t */ + +/* Define to integer type wide enough to hold a pointer if doesn't define. */ +/* #undef uintptr_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define to `long' if doesn't define. */ +/* #undef clock_t */ + +/* Define to `long' if doesn't define. */ +/* #undef time_t */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `unsigned int' if doesn't define. */ +/* #undef socklen_t */ + +/* Define to `int' if doesn't define. */ +/* #undef sig_atomic_t */ + +#define HAVE_MBSTATE_T 1 + +/* Define if you have quad_t in . */ +#define HAVE_QUAD_T 1 + +/* Define if you have wchar_t in . */ +#define HAVE_WCHAR_T 1 + +/* Define if you have wctype_t in . */ +#define HAVE_WCTYPE_T 1 + +/* Define if you have wint_t in . */ +#define HAVE_WINT_T 1 + +#define RLIMTYPE rlim_t + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +#define GETGROUPS_T gid_t + +/* Characteristics of the machine archictecture. */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the machine architecture is big-endian. */ +/* #undef WORDS_BIGENDIAN */ + +/* Check for the presence of certain non-function symbols in the system + libraries. */ + +/* Define if `sys_siglist' is declared by or . */ +#define HAVE_DECL_SYS_SIGLIST 1 +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define if `_sys_siglist' is declared by or . */ +#define UNDER_SYS_SIGLIST_DECLARED 1 + +#define HAVE_SYS_SIGLIST 1 + +#define HAVE_UNDER_SYS_SIGLIST 1 + +#define HAVE_SYS_ERRLIST 1 + +/* #undef HAVE_TZNAME */ +/* #undef HAVE_DECL_TZNAME */ + +/* Characteristics of some of the system structures. */ + +#define HAVE_STRUCT_DIRENT_D_INO 1 + +#define HAVE_STRUCT_DIRENT_D_FILENO 1 + +/* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */ + +/* #undef TIOCSTAT_IN_SYS_IOCTL */ + +#define FIONREAD_IN_SYS_IOCTL 1 + +#define GWINSZ_IN_SYS_IOCTL 1 + +#define STRUCT_WINSIZE_IN_SYS_IOCTL 1 + +/* #undef TM_IN_SYS_TIME */ + +/* #undef STRUCT_WINSIZE_IN_TERMIOS */ + +/* #undef SPEED_T_IN_SYS_TYPES */ + +#define TERMIOS_LDISC 1 + +#define TERMIO_LDISC 1 + +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 + +#define HAVE_STRUCT_TM_TM_ZONE 1 +#define HAVE_TM_ZONE 1 + +#define HAVE_TIMEVAL 1 + +#define HAVE_STRUCT_TIMEZONE 1 + +#define WEXITSTATUS_OFFSET 8 + +#define HAVE_STRUCT_TIMESPEC 1 +#define TIME_H_DEFINES_STRUCT_TIMESPEC 1 +/* #undef SYS_TIME_H_DEFINES_STRUCT_TIMESPEC */ +/* #undef PTHREAD_H_DEFINES_STRUCT_TIMESPEC */ + +#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1 +#define TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC 1 +/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */ +/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */ +/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */ + +/* Characteristics of definitions in the system header files. */ + +#define HAVE_GETPW_DECLS 1 + +/* #undef HAVE_RESOURCE */ + +/* #undef HAVE_LIBC_FNM_EXTMATCH */ + +/* Define if you have and it defines AUDIT_USER_TTY */ +#define HAVE_DECL_AUDIT_USER_TTY 1 + +#define HAVE_DECL_CONFSTR 1 + +#define HAVE_DECL_PRINTF 1 + +#define HAVE_DECL_SBRK 1 + +#define HAVE_DECL_STRCPY 1 + +#define HAVE_DECL_STRSIGNAL 1 + +#define HAVE_DECL_STRTOLD 1 + +/* #undef PRI_MACROS_BROKEN */ + +/* #undef STRTOLD_BROKEN */ + +/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */ +/* #undef WCONTINUED_BROKEN */ + +/* These are checked with BASH_CHECK_DECL */ + +#define HAVE_DECL_STRTOIMAX 1 +#define HAVE_DECL_STRTOL 1 +#define HAVE_DECL_STRTOLL 1 +#define HAVE_DECL_STRTOUL 1 +#define HAVE_DECL_STRTOULL 1 +#define HAVE_DECL_STRTOUMAX 1 + +/* Characteristics of system calls and C library functions. */ + +/* Define if the `getpgrp' function takes no argument. */ +#define GETPGRP_VOID 1 + +/* #undef NAMED_PIPES_MISSING */ + +/* #undef OPENDIR_NOT_ROBUST */ + +#define PGRP_PIPE 1 + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* #undef STAT_MACROS_BROKEN */ + +#define ULIMIT_MAXFDS 1 + +#define CAN_REDEFINE_GETENV 1 + +#define HAVE_STD_PUTENV 1 + +#define HAVE_STD_UNSETENV 1 + +#define HAVE_PRINTF_A_FORMAT 1 + +/* #undef CTYPE_NON_ASCII */ + +/* Define if you have and nl_langinfo(CODESET). */ +#define HAVE_LANGINFO_CODESET 1 + +/* Characteristics of properties exported by the kernel. */ + +/* Define if the kernel can exec files beginning with #! */ +#define HAVE_HASH_BANG_EXEC 1 + +/* Define if you have the /dev/fd devices to map open files into the file system. */ +#define HAVE_DEV_FD 1 + +/* Defined to /dev/fd or /proc/self/fd (linux). */ +#define DEV_FD_PREFIX "/dev/fd/" + +/* Define if you have the /dev/stdin device. */ +#define HAVE_DEV_STDIN 1 + +/* The type of iconv's `inbuf' argument */ +#define ICONV_CONST + +/* Type and behavior of signal handling functions. */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if return type of signal handlers is void */ +#define VOID_SIGHANDLER 1 + +/* #undef MUST_REINSTALL_SIGHANDLERS */ + +/* #undef HAVE_BSD_SIGNALS */ + +#define HAVE_POSIX_SIGNALS 1 + +/* #undef HAVE_USG_SIGHOLD */ + +/* #undef UNUSABLE_RT_SIGNALS */ + +/* Presence of system and C library functions. */ + +/* Define if you have the arc4random function. */ +/* #undef HAVE_ARC4RANDOM */ + +/* Define if you have the asprintf function. */ +#define HAVE_ASPRINTF 1 + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bzero function. */ +#define HAVE_BZERO 1 + +/* Define if you have the chown function. */ +#define HAVE_CHOWN 1 + +/* Define if you have the confstr function. */ +#define HAVE_CONFSTR 1 + +/* Define if you have the dlclose function. */ +#define HAVE_DLCLOSE 1 + +/* Define if you have the dlopen function. */ +#define HAVE_DLOPEN 1 + +/* Define if you have the dlsym function. */ +#define HAVE_DLSYM 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have the dprintf function. */ +#define HAVE_DPRINTF 1 + +/* Define if you have the dup2 function. */ +#define HAVE_DUP2 1 + +/* Define if you have the eaccess function. */ +#define HAVE_EACCESS 1 + +/* Define if you have the faccessat function. */ +#define HAVE_FACCESSAT 1 + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the fnmatch function. */ +#define HAVE_FNMATCH 1 + +/* Can fnmatch be used as a fallback to match [=equiv=] with collation weights? */ +#define FNMATCH_EQUIV_FALLBACK 1 + +/* Define if you have the fpurge/__fpurge function. */ +/* #undef HAVE_FPURGE */ +#define HAVE___FPURGE 1 +#define HAVE_DECL_FPURGE 0 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getentropy function. */ +#define HAVE_GETENTROPY 1 + +/* Define if you have the getdtablesize function. */ +#define HAVE_GETDTABLESIZE 1 + +/* Define if you have the getgroups function. */ +#define HAVE_GETGROUPS 1 + +/* Define if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + +/* Define if you have the getpwent function. */ +#define HAVE_GETPWENT 1 + +/* Define if you have the getpwnam function. */ +#define HAVE_GETPWNAM 1 + +/* Define if you have the getpwuid function. */ +#define HAVE_GETPWUID 1 + +/* Define if you have the getrandom function. */ +#define HAVE_GETRANDOM 1 + +/* Define if you have the getrlimit function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the getservbyname function. */ +#define HAVE_GETSERVBYNAME 1 + +/* Define if you have the getservent function. */ +#define HAVE_GETSERVENT 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the getwd function. */ +/* #undef HAVE_GETWD */ + +/* Define if you have the iconv function. */ +#define HAVE_ICONV 1 + +/* Define if you have the imaxdiv function. */ +#define HAVE_IMAXDIV 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the isascii function. */ +#define HAVE_ISASCII 1 + +/* Define if you have the isblank function. */ +#define HAVE_ISBLANK 1 + +/* Define if you have the isgraph function. */ +#define HAVE_ISGRAPH 1 + +/* Define if you have the isprint function. */ +#define HAVE_ISPRINT 1 + +/* Define if you have the isspace function. */ +#define HAVE_ISSPACE 1 + +/* Define if you have the iswctype function. */ +#define HAVE_ISWCTYPE 1 + +/* Define if you have the iswlower function. */ +#define HAVE_ISWLOWER 1 + +/* Define if you have the iswupper function. */ +#define HAVE_ISWUPPER 1 + +/* Define if you have the isxdigit function. */ +#define HAVE_ISXDIGIT 1 + +/* Define if you have the kill function. */ +#define HAVE_KILL 1 + +/* Define if you have the killpg function. */ +#define HAVE_KILLPG 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the locale_charset function. */ +/* #undef HAVE_LOCALE_CHARSET */ + +/* Define if you have the mbrlen function. */ +#define HAVE_MBRLEN 1 + +/* Define if you have the mbrtowc function. */ +#define HAVE_MBRTOWC 1 + +/* Define if you have the mbscasecmp function. */ +/* #undef HAVE_MBSCASECMP */ + +/* Define if you have the mbschr function. */ +/* #undef HAVE_MBSCHR */ + +/* Define if you have the mbscmp function. */ +/* #undef HAVE_MBSCMP */ + +/* Define if you have the mbsnrtowcs function. */ +#define HAVE_MBSNRTOWCS 1 + +/* Define if you have the mbsrtowcs function. */ +#define HAVE_MBSRTOWCS 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the mkdtemp function. */ +#define HAVE_MKDTEMP 1 + +/* Define if you have the mkfifo function. */ +#define HAVE_MKFIFO 1 + +/* Define if you have the mkstemp function. */ +#define HAVE_MKSTEMP 1 + +/* Define if you have the pathconf function. */ +#define HAVE_PATHCONF 1 + +/* Define if you have the pselect function. */ +#define HAVE_PSELECT 1 + +/* Define if you have the pread function. */ +#define HAVE_PREAD 1 + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the raise function. */ +#define HAVE_RAISE 1 + +/* Define if you have the random function. */ +#define HAVE_RANDOM 1 + +/* Define if you have the readlink function. */ +#define HAVE_READLINK 1 + +/* Define if you have the regcomp function. */ +#define HAVE_REGCOMP 1 + +/* Define if you have the regexec function. */ +#define HAVE_REGEXEC 1 + +/* Define if you have the rename function. */ +#define HAVE_RENAME 1 + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the setdtablesize function. */ +/* #undef HAVE_SETDTABLESIZE */ + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the setitimer function. */ +#define HAVE_SETITIMER 1 + +/* Define if you have the setlinebuf function. */ +#define HAVE_SETLINEBUF 1 + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setostype function. */ +/* #undef HAVE_SETOSTYPE */ + +/* Define if you have the setregid function. */ +/* #undef HAVE_SETREGID */ +#define HAVE_DECL_SETREGID 1 + +/* Define if you have the setregid function. */ +#define HAVE_SETRESGID 1 +/* #undef HAVE_DECL_SETRESGID */ + +/* Define if you have the setresuid function. */ +#define HAVE_SETRESUID 1 +/* #undef HAVE_DECL_SETRESUID */ + +/* Define if you have the setvbuf function. */ +#define HAVE_SETVBUF 1 + +/* Define if you have the siginterrupt function. */ +#define HAVE_SIGINTERRUPT 1 + +/* Define if you have the POSIX.1-style sigsetjmp function. */ +#define HAVE_POSIX_SIGSETJMP 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strcasestr function. */ +#define HAVE_STRCASESTR 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strchrnul function. */ +#define HAVE_STRCHRNUL 1 + +/* Define if you have the strcoll function. */ +#define HAVE_STRCOLL 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have the strnlen function. */ +#define HAVE_STRNLEN 1 + +/* Define if you have the strpbrk function. */ +#define HAVE_STRPBRK 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtoimax function. */ +#define HAVE_STRTOIMAX 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoll function. */ +#define HAVE_STRTOLL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the strtoull function. */ +#define HAVE_STRTOULL 1 + +/* Define if you have the strtoumax function. */ +#define HAVE_STRTOUMAX 1 + +/* Define if you have the strsignal function or macro. */ +#define HAVE_STRSIGNAL 1 + +/* Define if you have the sysconf function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have the syslog function. */ +#define HAVE_SYSLOG 1 + +/* Define if you have the tcgetattr function. */ +#define HAVE_TCGETATTR 1 + +/* Define if you have the tcgetpgrp function. */ +#define HAVE_TCGETPGRP 1 + +/* Define if you have the times function. */ +#define HAVE_TIMES 1 + +/* Define if you have the towlower function. */ +#define HAVE_TOWLOWER 1 + +/* Define if you have the towupper function. */ +#define HAVE_TOWUPPER 1 + +/* Define if you have the ttyname function. */ +#define HAVE_TTYNAME 1 + +/* Define if you have the tzset function. */ +#define HAVE_TZSET 1 + +/* Define if you have the ulimit function. */ +#define HAVE_ULIMIT 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the unsetenv function. */ +#define HAVE_UNSETENV 1 + +/* Define if you have the vasprintf function. */ +#define HAVE_VASPRINTF 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the waitpid function. */ +#define HAVE_WAITPID 1 + +/* Define if you have the wait3 function. */ +#define HAVE_WAIT3 1 + +/* Define if you have the wcrtomb function. */ +#define HAVE_WCRTOMB 1 + +/* Define if you have the wcscoll function. */ +#define HAVE_WCSCOLL 1 + +/* Define if you have the wcsdup function. */ +#define HAVE_WCSDUP 1 + +/* Define if you have the wctype function. */ +#define HAVE_WCTYPE 1 + +/* Define if you have the wcswidth function. */ +#define HAVE_WCSWIDTH 1 + +/* Define if you have the wcwidth function. */ +#define HAVE_WCWIDTH 1 + +/* and if it works */ +/* #undef WCWIDTH_BROKEN */ + +/* Presence of certain system include files. */ + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_ELF_H */ + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_LANGINFO_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIBAUDIT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LIBINTL_H */ + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MBSTR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTEM_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_RANDOM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_STREAM_H */ + +/* Define if you have */ +#define HAVE_SYS_TIME_H 1 + +#define TIME_WITH_SYS_TIME 1 + +/* Define if you have */ +#define HAVE_SYS_TIMES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_TERMCAP_H */ + +/* Define if you have the header file. */ +#define HAVE_TERMIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_ULIMIT_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_VARARGS_H */ + +/* Define if you have the header file. */ +#define HAVE_WCHAR_H 1 + +/* Define if you have the header file. */ +#define HAVE_WCTYPE_H 1 + +/* Presence of certain system libraries. */ + +#define HAVE_LIBDL 1 + +/* #undef HAVE_LIBSUN */ + +/* #undef HAVE_LIBSOCKET */ + +/* Are we running the GNU C library, version 2.1 or later? */ +/* #undef GLIBC21 */ + +/* Are we running SVR5 (UnixWare 7)? */ +/* #undef SVR5 */ + +/* Are we running SVR4.2? */ +/* #undef SVR4_2 */ + +/* Are we running some version of SVR4? */ +/* #undef SVR4 */ + +/* Define if job control is unusable or unsupported. */ +/* #undef JOB_CONTROL_MISSING */ + +/* Do we need to define _KERNEL to get the RLIMIT_* defines from + ? */ +/* #undef RLIMIT_NEEDS_KERNEL */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Do strcoll(3) and strcmp(3) give different results in the default locale? */ +/* #undef STRCOLL_BROKEN */ + +/* #undef DUP2_BROKEN */ + +/* #undef GETCWD_BROKEN */ + +/* #undef DEV_FD_STAT_BROKEN */ + +/* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */ + +/* Define if you have the header file. */ +#define HAVE_ARGZ_H 1 + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDIO_EXT_H 1 + +/* Define if you have the `dcgettext' function. */ +#define HAVE_DCGETTEXT 1 + +/* Define if you have the `localeconv' function. */ +#define HAVE_LOCALECONV 1 + +/* Define if your system has a working `malloc' function. */ +/* #undef HAVE_MALLOC */ + +/* Define if you have the `mempcpy' function. */ +#define HAVE_MEMPCPY 1 + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if you have the `mremap' function. */ +#define HAVE_MREMAP 1 + +/* Define if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define if you have the `nl_langinfo' function. */ +/* #undef HAVE_NL_LANGINFO */ + +/* Define if you have the `stpcpy' function. */ +#define HAVE_STPCPY 1 + +/* Define if you have the `strcspn' function. */ +#define HAVE_STRCSPN 1 + +/* Define if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the `__argz_count' function. */ +#define HAVE___ARGZ_COUNT 1 + +/* Define if you have the `__argz_next' function. */ +#define HAVE___ARGZ_NEXT 1 + +/* Define if you have the `__argz_stringify' function. */ +#define HAVE___ARGZ_STRINGIFY 1 + +/* End additions for lib/intl */ + + +/* Additions for lib/readline */ + +/* Define if you have and it defines AUDIT_USER_TTY */ +#define HAVE_DECL_AUDIT_USER_TTY 1 + +/* End additions for lib/readline */ + +#include "config-bot.h" + +#endif /* _CONFIG_H_ */ diff --git a/utshell-0.5.0/lib/include/conftypes.h b/utshell-0.5.0/lib/include/conftypes.h new file mode 100644 index 00000000..ea677ccd --- /dev/null +++ b/utshell-0.5.0/lib/include/conftypes.h @@ -0,0 +1,59 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* conftypes.h -- defines for build and host system. */ + +/* Copyright (C) 2001, 2005, 2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_CONFTYPES_H_) +#define _CONFTYPES_H_ + +/* Placeholder for future modifications if cross-compiling or building a + `fat' binary, e.g. on Apple Rhapsody. These values are used in multiple + files, so they appear here. */ +#if !defined (RHAPSODY) && !defined (MACOSX) +# define HOSTTYPE CONF_HOSTTYPE +# define OSTYPE CONF_OSTYPE +# define MACHTYPE CONF_MACHTYPE +#else /* RHAPSODY */ +# if defined(__powerpc__) || defined(__ppc__) +# define HOSTTYPE "powerpc" +# elif defined(__i386__) +# define HOSTTYPE "i386" +# else +# define HOSTTYPE CONF_HOSTTYPE +# endif + +# define OSTYPE CONF_OSTYPE +# define VENDOR CONF_VENDOR + +# define MACHTYPE HOSTTYPE "-" VENDOR "-" OSTYPE +#endif /* RHAPSODY */ + +#ifndef HOSTTYPE +# define HOSTTYPE "unknown" +#endif + +#ifndef OSTYPE +# define OSTYPE "unknown" +#endif + +#ifndef MACHTYPE +# define MACHTYPE "unknown" +#endif + +#endif /* _CONFTYPES_H_ */ diff --git a/utshell-0.5.0/lib/include/dispose_cmd.h b/utshell-0.5.0/lib/include/dispose_cmd.h new file mode 100644 index 00000000..7d5d6c32 --- /dev/null +++ b/utshell-0.5.0/lib/include/dispose_cmd.h @@ -0,0 +1,41 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* dispose_cmd.h -- Functions appearing in dispose_cmd.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_DISPOSE_CMD_H_) +#define _DISPOSE_CMD_H_ + +#include "stdc.h" + +extern void dispose_command PARAMS((COMMAND *)); +extern void dispose_word_desc PARAMS((WORD_DESC *)); +extern void dispose_word PARAMS((WORD_DESC *)); +extern void dispose_words PARAMS((WORD_LIST *)); +extern void dispose_word_array PARAMS((char **)); +extern void dispose_redirects PARAMS((REDIRECT *)); + +#if defined (COND_COMMAND) +extern void dispose_cond_node PARAMS((COND_COM *)); +#endif + +extern void dispose_function_def_contents PARAMS((FUNCTION_DEF *)); +extern void dispose_function_def PARAMS((FUNCTION_DEF *)); + +#endif /* !_DISPOSE_CMD_H_ */ diff --git a/utshell-0.5.0/lib/include/error.h b/utshell-0.5.0/lib/include/error.h new file mode 100644 index 00000000..ecd6f0c8 --- /dev/null +++ b/utshell-0.5.0/lib/include/error.h @@ -0,0 +1,74 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* error.h -- External declarations of functions appearing in error.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_ERROR_H_) +#define _ERROR_H_ + +#include "stdc.h" + +/* Get the name of the shell or shell script for an error message. */ +extern char *get_name_for_error PARAMS((void)); + +/* Report an error having to do with FILENAME. */ +extern void file_error PARAMS((const char *)); + +/* Report a programmer's error, and abort. Pass REASON, and ARG1 ... ARG5. */ +extern void programming_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* General error reporting. Pass FORMAT and ARG1 ... ARG5. */ +extern void report_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Error messages for parts of the parser that don't call report_syntax_error */ +extern void parser_error PARAMS((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); + +/* Report an unrecoverable error and exit. Pass FORMAT and ARG1 ... ARG5. */ +extern void fatal_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report a system error, like BSD warn(3). */ +extern void sys_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report an internal error. */ +extern void internal_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report an internal warning. */ +extern void internal_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report an internal informational notice. */ +extern void internal_inform PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Debugging functions, not enabled in released version. */ +extern char *strescape PARAMS((const char *)); +extern void itrace PARAMS((const char *, ...)) __attribute__ ((__format__ (printf, 1, 2))); +extern void trace PARAMS((const char *, ...)) __attribute__ ((__format__ (printf, 1, 2))); + +/* Report an error having to do with command parsing or execution. */ +extern void command_error PARAMS((const char *, int, int, int)); + +extern char *command_errstr PARAMS((int)); + +/* Specific error message functions that eventually call report_error or + internal_error. */ + +extern void err_badarraysub PARAMS((const char *)); +extern void err_unboundvar PARAMS((const char *)); +extern void err_readonly PARAMS((const char *)); + +#endif /* !_ERROR_H_ */ diff --git a/utshell-0.5.0/lib/include/externs.h b/utshell-0.5.0/lib/include/externs.h new file mode 100644 index 00000000..d87cf67a --- /dev/null +++ b/utshell-0.5.0/lib/include/externs.h @@ -0,0 +1,549 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* externs.h -- extern function declarations which do not appear in their + own header file. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Make sure that this is included *after* config.h! */ + +#if !defined (_EXTERNS_H_) +# define _EXTERNS_H_ + +#include "stdc.h" + +/* Functions from expr.c. */ +#define EXP_EXPANDED 0x01 + +extern intmax_t evalexp PARAMS((char *, int, int *)); + +/* Functions from print_cmd.c. */ +#define FUNC_MULTILINE 0x01 +#define FUNC_EXTERNAL 0x02 + +extern char *make_command_string PARAMS((COMMAND *)); +extern char *named_function_string PARAMS((char *, COMMAND *, int)); + +extern void print_command PARAMS((COMMAND *)); +extern void print_simple_command PARAMS((SIMPLE_COM *)); +extern void print_word_list PARAMS((WORD_LIST *, char *)); + +/* debugger support */ +extern void print_for_command_head PARAMS((FOR_COM *)); +#if defined (SELECT_COMMAND) +extern void print_select_command_head PARAMS((SELECT_COM *)); +#endif +extern void print_case_command_head PARAMS((CASE_COM *)); +#if defined (DPAREN_ARITHMETIC) +extern void print_arith_command PARAMS((WORD_LIST *)); +#endif +#if defined (COND_COMMAND) +extern void print_cond_command PARAMS((COND_COM *)); +#endif + +/* set -x support */ +extern void xtrace_init PARAMS((void)); +#ifdef NEED_XTRACE_SET_DECL +extern void xtrace_set PARAMS((int, FILE *)); +#endif +extern void xtrace_fdchk PARAMS((int)); +extern void xtrace_reset PARAMS((void)); +extern char *indirection_level_string PARAMS((void)); +extern void xtrace_print_assignment PARAMS((char *, char *, int, int)); +extern void xtrace_print_word_list PARAMS((WORD_LIST *, int)); +extern void xtrace_print_for_command_head PARAMS((FOR_COM *)); +#if defined (SELECT_COMMAND) +extern void xtrace_print_select_command_head PARAMS((SELECT_COM *)); +#endif +extern void xtrace_print_case_command_head PARAMS((CASE_COM *)); +#if defined (DPAREN_ARITHMETIC) +extern void xtrace_print_arith_cmd PARAMS((WORD_LIST *)); +#endif +#if defined (COND_COMMAND) +extern void xtrace_print_cond_term PARAMS((int, int, WORD_DESC *, char *, char *)); +#endif + +/* Functions from shell.c. */ +extern void exit_shell PARAMS((int)) __attribute__((__noreturn__)); +extern void sh_exit PARAMS((int)) __attribute__((__noreturn__)); +extern void subshell_exit PARAMS((int)) __attribute__((__noreturn__)); +extern void set_exit_status PARAMS((int)); +extern void disable_priv_mode PARAMS((void)); +extern void unbind_args PARAMS((void)); + +#if defined (RESTRICTED_SHELL) +extern int shell_is_restricted PARAMS((char *)); +extern int maybe_make_restricted PARAMS((char *)); +#endif + +extern void unset_bash_input PARAMS((int)); +extern void get_current_user_info PARAMS((void)); + +/* Functions from eval.c. */ +extern int reader_loop PARAMS((void)); +extern int pretty_print_loop PARAMS((void)); +extern int parse_command PARAMS((void)); +extern int read_command PARAMS((void)); + +/* Functions from braces.c. */ +#if defined (BRACE_EXPANSION) +extern char **brace_expand PARAMS((char *)); +#endif + +/* Miscellaneous functions from parse.y */ +extern int yyparse PARAMS((void)); +extern int return_EOF PARAMS((void)); +extern void push_token PARAMS((int)); +extern char *xparse_dolparen PARAMS((char *, char *, int *, int)); +extern void reset_parser PARAMS((void)); +extern void reset_readahead_token PARAMS((void)); +extern WORD_LIST *parse_string_to_word_list PARAMS((char *, int, const char *)); + +extern int parser_will_prompt PARAMS((void)); +extern int parser_in_command_position PARAMS((void)); + +extern void free_pushed_string_input PARAMS((void)); + +extern int parser_expanding_alias PARAMS((void)); +extern void parser_save_alias PARAMS((void)); +extern void parser_restore_alias PARAMS((void)); + +extern void clear_shell_input_line PARAMS((void)); + +extern char *decode_prompt_string PARAMS((char *)); + +extern int get_current_prompt_level PARAMS((void)); +extern void set_current_prompt_level PARAMS((int)); + +#if defined (HISTORY) +extern char *history_delimiting_chars PARAMS((const char *)); +#endif + +/* Declarations for functions defined in locale.c */ +extern void set_default_locale PARAMS((void)); +extern void set_default_locale_vars PARAMS((void)); +extern int set_locale_var PARAMS((char *, char *)); +extern int set_lang PARAMS((char *, char *)); +extern void set_default_lang PARAMS((void)); +extern char *get_locale_var PARAMS((char *)); +extern char *localetrans PARAMS((char *, int, int *)); +extern char *mk_msgstr PARAMS((char *, int *)); +extern char *localeexpand PARAMS((char *, int, int, int, int *)); +#ifndef locale_decpoint +extern int locale_decpoint PARAMS((void)); +#endif + +/* Declarations for functions defined in list.c. */ +extern void list_walk PARAMS((GENERIC_LIST *, sh_glist_func_t *)); +extern void wlist_walk PARAMS((WORD_LIST *, sh_icpfunc_t *)); +extern GENERIC_LIST *list_reverse (); +extern int list_length (); +extern GENERIC_LIST *list_append (); +extern GENERIC_LIST *list_remove (); + +/* Declarations for functions defined in stringlib.c */ +extern int find_string_in_alist PARAMS((char *, STRING_INT_ALIST *, int)); +extern char *find_token_in_alist PARAMS((int, STRING_INT_ALIST *, int)); +extern int find_index_in_alist PARAMS((char *, STRING_INT_ALIST *, int)); + +extern char *substring PARAMS((const char *, int, int)); +extern char *strsub PARAMS((char *, char *, char *, int)); +extern char *strcreplace PARAMS((char *, int, const char *, int)); +extern void strip_leading PARAMS((char *)); +extern void strip_trailing PARAMS((char *, int, int)); +extern void xbcopy PARAMS((char *, char *, int)); + +/* Functions from version.c. */ +extern char *shell_version_string PARAMS((void)); +extern void show_shell_version PARAMS((int)); + +/* Functions from the bash library, lib/sh/libsh.a. These should really + go into a separate include file. */ + +/* declarations for functions defined in lib/sh/casemod.c */ +extern char *sh_modcase PARAMS((const char *, char *, int)); + +/* Defines for flags argument to sh_modcase. These need to agree with what's + in lib/sh/casemode.c */ +#define CASE_LOWER 0x0001 +#define CASE_UPPER 0x0002 +#define CASE_CAPITALIZE 0x0004 +#define CASE_UNCAP 0x0008 +#define CASE_TOGGLE 0x0010 +#define CASE_TOGGLEALL 0x0020 +#define CASE_UPFIRST 0x0040 +#define CASE_LOWFIRST 0x0080 + +#define CASE_USEWORDS 0x1000 + +/* declarations for functions defined in lib/sh/clktck.c */ +extern long get_clk_tck PARAMS((void)); + +/* declarations for functions defined in lib/sh/clock.c */ +extern void clock_t_to_secs (); +extern void print_clock_t (); + +/* Declarations for functions defined in lib/sh/dprintf.c */ +#if !defined (HAVE_DPRINTF) +extern void dprintf PARAMS((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); +#endif + +/* Declarations for functions defined in lib/sh/fmtulong.c */ +#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ +#define FL_ADDBASE 0x02 /* add base# prefix to converted value */ +#define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ +#define FL_UNSIGNED 0x08 /* don't add any sign */ + +extern char *fmtulong PARAMS((unsigned long int, int, char *, size_t, int)); + +/* Declarations for functions defined in lib/sh/fmtulong.c */ +#if defined (HAVE_LONG_LONG) +extern char *fmtullong PARAMS((unsigned long long int, int, char *, size_t, int)); +#endif + +/* Declarations for functions defined in lib/sh/fmtumax.c */ +extern char *fmtumax PARAMS((uintmax_t, int, char *, size_t, int)); + +/* Declarations for functions defined in lib/sh/fnxform.c */ +extern char *fnx_fromfs PARAMS((char *, size_t)); +extern char *fnx_tofs PARAMS((char *, size_t)); + +/* Declarations for functions defined in lib/sh/fpurge.c */ + +#if defined NEED_FPURGE_DECL +#if !HAVE_DECL_FPURGE + +#if HAVE_FPURGE +# define fpurge _bash_fpurge +#endif +extern int fpurge PARAMS((FILE *stream)); + +#endif /* HAVE_DECL_FPURGE */ +#endif /* NEED_FPURGE_DECL */ + +/* Declarations for functions defined in lib/sh/getcwd.c */ +#if !defined (HAVE_GETCWD) +extern char *getcwd PARAMS((char *, size_t)); +#endif + +/* Declarations for functions defined in lib/sh/input_avail.c */ +extern int input_avail PARAMS((int)); + +/* Declarations for functions defined in lib/sh/itos.c */ +extern char *inttostr PARAMS((intmax_t, char *, size_t)); +extern char *itos PARAMS((intmax_t)); +extern char *mitos PARAMS((intmax_t)); +extern char *uinttostr PARAMS((uintmax_t, char *, size_t)); +extern char *uitos PARAMS((uintmax_t)); + +/* declarations for functions defined in lib/sh/makepath.c */ +#define MP_DOTILDE 0x01 +#define MP_DOCWD 0x02 +#define MP_RMDOT 0x04 +#define MP_IGNDOT 0x08 + +extern char *sh_makepath PARAMS((const char *, const char *, int)); + +/* declarations for functions defined in lib/sh/mbscasecmp.c */ +#if !defined (HAVE_MBSCASECMP) +extern char *mbscasecmp PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/mbschr.c */ +#if !defined (HAVE_MBSCHR) +extern char *mbschr PARAMS((const char *, int)); +#endif + +/* declarations for functions defined in lib/sh/mbscmp.c */ +#if !defined (HAVE_MBSCMP) +extern char *mbscmp PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/netconn.c */ +extern int isnetconn PARAMS((int)); + +/* declarations for functions defined in lib/sh/netopen.c */ +extern int netopen PARAMS((char *)); + +/* Declarations for functions defined in lib/sh/oslib.c */ + +#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN) +extern int dup2 PARAMS((int, int)); +#endif + +#if !defined (HAVE_GETDTABLESIZE) +extern int getdtablesize PARAMS((void)); +#endif /* !HAVE_GETDTABLESIZE */ + +#if !defined (HAVE_GETHOSTNAME) +extern int gethostname PARAMS((char *, int)); +#endif /* !HAVE_GETHOSTNAME */ + +extern int getmaxgroups PARAMS((void)); +extern long getmaxchild PARAMS((void)); + +/* declarations for functions defined in lib/sh/pathcanon.c */ +#define PATH_CHECKDOTDOT 0x0001 +#define PATH_CHECKEXISTS 0x0002 +#define PATH_HARDPATH 0x0004 +#define PATH_NOALLOC 0x0008 + +extern char *sh_canonpath PARAMS((char *, int)); + +/* declarations for functions defined in lib/sh/pathphys.c */ +extern char *sh_physpath PARAMS((char *, int)); +extern char *sh_realpath PARAMS((const char *, char *)); + +/* declarations for functions defined in lib/sh/random.c */ +extern int brand PARAMS((void)); +extern void sbrand PARAMS((unsigned long)); /* set bash random number generator. */ +extern void seedrand PARAMS((void)); /* seed generator randomly */ +extern void seedrand32 PARAMS((void)); +extern u_bits32_t get_urandom32 PARAMS((void)); + +/* declarations for functions defined in lib/sh/setlinebuf.c */ +#ifdef NEED_SH_SETLINEBUF_DECL +extern int sh_setlinebuf PARAMS((FILE *)); +#endif + +/* declarations for functions defined in lib/sh/shaccess.c */ +extern int sh_eaccess PARAMS((const char *, int)); + +/* declarations for functions defined in lib/sh/shmatch.c */ +extern int sh_regmatch PARAMS((const char *, const char *, int)); + +/* defines for flags argument to sh_regmatch. */ +#define SHMAT_SUBEXP 0x001 /* save subexpressions in SH_REMATCH */ +#define SHMAT_PWARN 0x002 /* print a warning message on invalid regexp */ + +/* declarations for functions defined in lib/sh/shmbchar.c */ +extern size_t mbstrlen PARAMS((const char *)); +extern char *mbsmbchar PARAMS((const char *)); +extern int sh_mbsnlen PARAMS((const char *, size_t, int)); + +/* declarations for functions defined in lib/sh/shquote.c */ +extern char *sh_single_quote PARAMS((const char *)); +extern char *sh_double_quote PARAMS((const char *)); +extern char *sh_mkdoublequoted PARAMS((const char *, int, int)); +extern char *sh_un_double_quote PARAMS((char *)); +extern char *sh_backslash_quote PARAMS((char *, const char *, int)); +extern char *sh_backslash_quote_for_double_quotes PARAMS((char *)); +extern char *sh_quote_reusable PARAMS((char *, int)); +extern int sh_contains_shell_metas PARAMS((const char *)); +extern int sh_contains_quotes PARAMS((const char *)); + +/* declarations for functions defined in lib/sh/spell.c */ +extern int spname PARAMS((char *, char *)); +extern char *dirspell PARAMS((char *)); + +/* declarations for functions defined in lib/sh/strcasecmp.c */ +#if !defined (HAVE_STRCASECMP) +extern int strncasecmp PARAMS((const char *, const char *, size_t)); +extern int strcasecmp PARAMS((const char *, const char *)); +#endif /* HAVE_STRCASECMP */ + +/* declarations for functions defined in lib/sh/strcasestr.c */ +#if ! HAVE_STRCASESTR +extern char *strcasestr PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/strchrnul.c */ +#if ! HAVE_STRCHRNUL +extern char *strchrnul PARAMS((const char *, int)); +#endif + +/* declarations for functions defined in lib/sh/strerror.c */ +#if !defined (HAVE_STRERROR) && !defined (strerror) +extern char *strerror PARAMS((int)); +#endif + +/* declarations for functions defined in lib/sh/strftime.c */ +#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL) +extern size_t strftime PARAMS((char *, size_t, const char *, const struct tm *)); +#endif + +/* declarations for functions and structures defined in lib/sh/stringlist.c */ + +/* This is a general-purpose argv-style array struct. */ +typedef struct _list_of_strings { + char **list; + int list_size; + int list_len; +} STRINGLIST; + +typedef int sh_strlist_map_func_t PARAMS((char *)); + +extern STRINGLIST *strlist_create PARAMS((int)); +extern STRINGLIST *strlist_resize PARAMS((STRINGLIST *, int)); +extern void strlist_flush PARAMS((STRINGLIST *)); +extern void strlist_dispose PARAMS((STRINGLIST *)); +extern int strlist_remove PARAMS((STRINGLIST *, char *)); +extern STRINGLIST *strlist_copy PARAMS((STRINGLIST *)); +extern STRINGLIST *strlist_merge PARAMS((STRINGLIST *, STRINGLIST *)); +extern STRINGLIST *strlist_append PARAMS((STRINGLIST *, STRINGLIST *)); +extern STRINGLIST *strlist_prefix_suffix PARAMS((STRINGLIST *, char *, char *)); +extern void strlist_print PARAMS((STRINGLIST *, char *)); +extern void strlist_walk PARAMS((STRINGLIST *, sh_strlist_map_func_t *)); +extern void strlist_sort PARAMS((STRINGLIST *)); + +/* declarations for functions defined in lib/sh/stringvec.c */ + +extern char **strvec_create PARAMS((int)); +extern char **strvec_resize PARAMS((char **, int)); +extern char **strvec_mcreate PARAMS((int)); +extern char **strvec_mresize PARAMS((char **, int)); +extern void strvec_flush PARAMS((char **)); +extern void strvec_dispose PARAMS((char **)); +extern int strvec_remove PARAMS((char **, char *)); +extern int strvec_len PARAMS((char **)); +extern int strvec_search PARAMS((char **, char *)); +extern char **strvec_copy PARAMS((char **)); +extern int strvec_posixcmp PARAMS((char **, char **)); +extern int strvec_strcmp PARAMS((char **, char **)); +extern void strvec_sort PARAMS((char **, int)); + +extern char **strvec_from_word_list PARAMS((WORD_LIST *, int, int, int *)); +extern WORD_LIST *strvec_to_word_list PARAMS((char **, int, int)); + +/* declarations for functions defined in lib/sh/strnlen.c */ +#if !defined (HAVE_STRNLEN) +extern size_t strnlen PARAMS((const char *, size_t)); +#endif + +/* declarations for functions defined in lib/sh/strpbrk.c */ +#if !defined (HAVE_STRPBRK) +extern char *strpbrk PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/strtod.c */ +#if !defined (HAVE_STRTOD) +extern double strtod PARAMS((const char *, char **)); +#endif + +/* declarations for functions defined in lib/sh/strtol.c */ +#if !HAVE_DECL_STRTOL +extern long strtol PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtoll.c */ +#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOLL +extern long long strtoll PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtoul.c */ +#if !HAVE_DECL_STRTOUL +extern unsigned long strtoul PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtoull.c */ +#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOULL +extern unsigned long long strtoull PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strimax.c */ +#if !HAVE_DECL_STRTOIMAX +extern intmax_t strtoimax PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strumax.c */ +#if !HAVE_DECL_STRTOUMAX +extern uintmax_t strtoumax PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtrans.c */ +extern char *ansicstr PARAMS((char *, int, int, int *, int *)); +extern char *ansic_quote PARAMS((char *, int, int *)); +extern int ansic_shouldquote PARAMS((const char *)); +extern char *ansiexpand PARAMS((char *, int, int, int *)); + +/* declarations for functions defined in lib/sh/timeval.c. No prototypes + so we don't have to count on having a definition of struct timeval in + scope when this file is included. */ +extern void timeval_to_secs (); +extern void print_timeval (); + +/* declarations for functions defined in lib/sh/tmpfile.c */ +#define MT_USETMPDIR 0x0001 +#define MT_READWRITE 0x0002 +#define MT_USERANDOM 0x0004 +#define MT_TEMPLATE 0x0008 + +extern char *sh_mktmpname PARAMS((char *, int)); +extern int sh_mktmpfd PARAMS((char *, int, char **)); +/* extern FILE *sh_mktmpfp PARAMS((char *, int, char **)); */ +extern char *sh_mktmpdir PARAMS((char *, int)); + +/* declarations for functions defined in lib/sh/uconvert.c */ +extern int uconvert PARAMS((char *, long *, long *, char **)); + +/* declarations for functions defined in lib/sh/ufuncs.c */ +extern unsigned int falarm PARAMS((unsigned int, unsigned int)); +extern unsigned int fsleep PARAMS((unsigned int, unsigned int)); + +/* declarations for functions defined in lib/sh/unicode.c */ +extern int u32cconv PARAMS((unsigned long, char *)); +extern void u32reset PARAMS((void)); + +/* declarations for functions defined in lib/sh/utf8.c */ +extern char *utf8_mbschr PARAMS((const char *, int)); +extern int utf8_mbscmp PARAMS((const char *, const char *)); +extern char *utf8_mbsmbchar PARAMS((const char *)); +extern int utf8_mbsnlen PARAMS((const char *, size_t, int)); +extern int utf8_mblen PARAMS((const char *, size_t)); +extern size_t utf8_mbstrlen PARAMS((const char *)); + +/* declarations for functions defined in lib/sh/wcsnwidth.c */ +#if defined (HANDLE_MULTIBYTE) +extern int wcsnwidth PARAMS((const wchar_t *, size_t, int)); +#endif + +/* declarations for functions defined in lib/sh/winsize.c */ +extern void get_new_window_size PARAMS((int, int *, int *)); + +/* declarations for functions defined in lib/sh/zcatfd.c */ +extern int zcatfd PARAMS((int, int, char *)); + +/* declarations for functions defined in lib/sh/zgetline.c */ +extern ssize_t zgetline PARAMS((int, char **, size_t *, int, int)); + +/* declarations for functions defined in lib/sh/zmapfd.c */ +extern int zmapfd PARAMS((int, char **, char *)); + +/* declarations for functions defined in lib/sh/zread.c */ +extern ssize_t zread PARAMS((int, char *, size_t)); +extern ssize_t zreadretry PARAMS((int, char *, size_t)); +extern ssize_t zreadintr PARAMS((int, char *, size_t)); +extern ssize_t zreadc PARAMS((int, char *)); +extern ssize_t zreadcintr PARAMS((int, char *)); +extern ssize_t zreadn PARAMS((int, char *, size_t)); +extern void zreset PARAMS((void)); +extern void zsyncfd PARAMS((int)); + +/* declarations for functions defined in lib/sh/zwrite.c */ +extern int zwrite PARAMS((int, char *, size_t)); + +/* declarations for functions defined in lib/glob/gmisc.c */ +extern int match_pattern_char PARAMS((char *, char *, int)); +extern int umatchlen PARAMS((char *, size_t)); + +#if defined (HANDLE_MULTIBYTE) +extern int match_pattern_wchar PARAMS((wchar_t *, wchar_t *, int)); +extern int wmatchlen PARAMS((wchar_t *, size_t)); +#endif + +#endif /* _EXTERNS_H_ */ diff --git a/utshell-0.5.0/lib/include/filecntl.h b/utshell-0.5.0/lib/include/filecntl.h new file mode 100644 index 00000000..9bcbab8d --- /dev/null +++ b/utshell-0.5.0/lib/include/filecntl.h @@ -0,0 +1,53 @@ +/* filecntl.h - Definitions to set file descriptors to close-on-exec. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_FILECNTL_H_) +#define _FILECNTL_H_ + +#include + +/* Definitions to set file descriptors to close-on-exec, the Posix way. */ +#if !defined (FD_CLOEXEC) +#define FD_CLOEXEC 1 +#endif + +#define FD_NCLOEXEC 0 + +#define SET_CLOSE_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_CLOEXEC)) +#define SET_OPEN_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_NCLOEXEC)) + +/* How to open a file in non-blocking mode, the Posix.1 way. */ +#if !defined (O_NONBLOCK) +# if defined (O_NDELAY) +# define O_NONBLOCK O_NDELAY +# else +# define O_NONBLOCK 0 +# endif +#endif + +/* Make sure O_BINARY and O_TEXT are defined to avoid Windows-specific code. */ +#if !defined (O_BINARY) +# define O_BINARY 0 +#endif +#if !defined (O_TEXT) +# define O_TEXT 0 +#endif + +#endif /* ! _FILECNTL_H_ */ diff --git a/utshell-0.5.0/lib/include/general.h b/utshell-0.5.0/lib/include/general.h new file mode 100644 index 00000000..1c1d1c67 --- /dev/null +++ b/utshell-0.5.0/lib/include/general.h @@ -0,0 +1,372 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* general.h -- defines that everybody likes to use. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_GENERAL_H_) +#define _GENERAL_H_ + +#include "stdc.h" + +#include "bashtypes.h" +#include "chartypes.h" + +#if defined (HAVE_SYS_RESOURCE_H) && defined (RLIMTYPE) +# if defined (HAVE_SYS_TIME_H) +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include "xmalloc.h" + +/* NULL pointer type. */ +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* Hardly used anymore */ +#define pointer_to_int(x) (int)((char *)x - (char *)0) + +#if defined (alpha) && defined (__GNUC__) && !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif + +#if !defined (strcpy) && (defined (HAVE_DECL_STRCPY) && !HAVE_DECL_STRCPY) +extern char *strcpy PARAMS((char *, const char *)); +#endif + +#if !defined (savestring) +# define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x)) +#endif + +#ifndef member +# define member(c, s) ((c) ? ((char *)mbschr ((s), (c)) != (char *)NULL) : 0) +#endif + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifndef CHAR_MAX +# ifdef __CHAR_UNSIGNED__ +# define CHAR_MAX 0xff +# else +# define CHAR_MAX 0x7f +# endif +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* The width in bits of the integer type or expression T. + Padding bits are not supported; this is checked at compile-time below. */ +#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) + +/* Bound on length of the string representing an unsigned integer + value representable in B bits. log10 (2.0) < 146/485. The + smallest value of B where this bound is not tight is 2621. */ +#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((TYPE_WIDTH (t) - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) + +/* Updated version adapted from gnulib/intprops.h, not used right now. + Changes the approximation of log10(2) from 302/1000 to 146/485. */ +#if 0 +#define INT_STRLEN_BOUND(t) \ + (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - TYPE_SIGNED (t)) + TYPE_SIGNED(t)) +#endif + +/* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + +/* Define exactly what a legal shell identifier consists of. */ +#define legal_variable_starter(c) (ISALPHA(c) || (c == '_')) +#define legal_variable_char(c) (ISALNUM(c) || c == '_') + +/* Definitions used in subst.c and by the `read' builtin for field + splitting. */ +#define spctabnl(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') + +/* All structs which contain a `next' field should have that field + as the first field in the struct. This means that functions + can be written to handle the general case for linked lists. */ +typedef struct g_list { + struct g_list *next; +} GENERIC_LIST; + +/* Here is a generic structure for associating character strings + with integers. It is used in the parser for shell tokenization. */ +typedef struct { + char *word; + int token; +} STRING_INT_ALIST; + +/* A macro to avoid making an unnecessary function call. */ +#define REVERSE_LIST(list, type) \ + ((list && list->next) ? (type)list_reverse ((GENERIC_LIST *)list) \ + : (type)(list)) + +#if __GNUC__ > 1 +# define FASTCOPY(s, d, n) __builtin_memcpy ((d), (s), (n)) +#else /* !__GNUC__ */ +# if !defined (HAVE_BCOPY) +# if !defined (HAVE_MEMMOVE) +# define FASTCOPY(s, d, n) memcpy ((d), (s), (n)) +# else +# define FASTCOPY(s, d, n) memmove ((d), (s), (n)) +# endif /* !HAVE_MEMMOVE */ +# else /* HAVE_BCOPY */ +# define FASTCOPY(s, d, n) bcopy ((s), (d), (n)) +# endif /* HAVE_BCOPY */ +#endif /* !__GNUC__ */ + +/* String comparisons that possibly save a function call each. */ +#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) +#define STREQN(a, b, n) ((n == 0) ? (1) \ + : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)) + +/* More convenience definitions that possibly save system or libc calls. */ +#define STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0) +#define FREE(s) do { if (s) free (s); s = NULL; } while (0) +#define MEMBER(c, s) (((c) && c == (s)[0] && !(s)[1]) || (member(c, s))) + +/* A fairly hairy macro to check whether an allocated string has more room, + and to resize it using xrealloc if it does not. + STR is the string (char *) + CIND is the current index into the string (int) + ROOM is the amount of additional room we need in the string (int) + CSIZE is the currently-allocated size of STR (int) + SINCR is how much to increment CSIZE before calling xrealloc (int) */ + +#define RESIZE_MALLOCED_BUFFER(str, cind, room, csize, sincr) \ + do { \ + if ((cind) + (room) >= csize) \ + { \ + while ((cind) + (room) >= csize) \ + csize += (sincr); \ + str = xrealloc (str, csize); \ + } \ + } while (0) + +/* Function pointers can be declared as (Function *)foo. */ +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); /* no longer used */ +typedef char **CPPFunction (); /* no longer used */ +#endif /* _FUNCTION_DEF */ + +#ifndef SH_FUNCTION_TYPEDEF +# define SH_FUNCTION_TYPEDEF + +/* Shell function typedefs with prototypes */ +/* `Generic' function pointer typedefs */ + +typedef int sh_intfunc_t PARAMS((int)); +typedef int sh_ivoidfunc_t PARAMS((void)); +typedef int sh_icpfunc_t PARAMS((char *)); +typedef int sh_icppfunc_t PARAMS((char **)); +typedef int sh_iptrfunc_t PARAMS((PTR_T)); + +typedef void sh_voidfunc_t PARAMS((void)); +typedef void sh_vintfunc_t PARAMS((int)); +typedef void sh_vcpfunc_t PARAMS((char *)); +typedef void sh_vcppfunc_t PARAMS((char **)); +typedef void sh_vptrfunc_t PARAMS((PTR_T)); + +typedef int sh_wdesc_func_t PARAMS((WORD_DESC *)); +typedef int sh_wlist_func_t PARAMS((WORD_LIST *)); + +typedef int sh_glist_func_t PARAMS((GENERIC_LIST *)); + +typedef char *sh_string_func_t PARAMS((char *)); /* like savestring, et al. */ + +typedef int sh_msg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ +typedef void sh_vmsg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ + +/* Specific function pointer typedefs. Most of these could be done + with #defines. */ +typedef void sh_sv_func_t PARAMS((char *)); /* sh_vcpfunc_t */ +typedef void sh_free_func_t PARAMS((PTR_T)); /* sh_vptrfunc_t */ +typedef void sh_resetsig_func_t PARAMS((int)); /* sh_vintfunc_t */ + +typedef int sh_ignore_func_t PARAMS((const char *)); /* sh_icpfunc_t */ + +typedef int sh_assign_func_t PARAMS((const char *)); +typedef int sh_wassign_func_t PARAMS((WORD_DESC *, int)); + +typedef int sh_load_func_t PARAMS((char *)); +typedef void sh_unload_func_t PARAMS((char *)); + +typedef int sh_builtin_func_t PARAMS((WORD_LIST *)); /* sh_wlist_func_t */ + +#endif /* SH_FUNCTION_TYPEDEF */ + +#define NOW ((time_t) time ((time_t *) 0)) +#define GETTIME(tv) gettimeofday(&(tv), NULL) + +/* Some defines for calling file status functions. */ +#define FS_EXISTS 0x1 +#define FS_EXECABLE 0x2 +#define FS_EXEC_PREFERRED 0x4 +#define FS_EXEC_ONLY 0x8 +#define FS_DIRECTORY 0x10 +#define FS_NODIRS 0x20 +#define FS_READABLE 0x40 + +/* Default maximum for move_to_high_fd */ +#define HIGH_FD_MAX 256 + +/* The type of function passed as the fourth argument to qsort(3). */ +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +/* Some useful definitions for Unix pathnames. Argument convention: + x == string, c == character */ + +#if !defined (__CYGWIN__) +# define ABSPATH(x) ((x)[0] == '/') +# define RELPATH(x) ((x)[0] != '/') +#else /* __CYGWIN__ */ +# define ABSPATH(x) (((x)[0] && ISALPHA((unsigned char)(x)[0]) && (x)[1] == ':') || ISDIRSEP((x)[0])) +# define RELPATH(x) (ABSPATH(x) == 0) +#endif /* __CYGWIN__ */ + +#define ROOTEDPATH(x) (ABSPATH(x)) + +#define DIRSEP '/' +#if !defined (__CYGWIN__) +# define ISDIRSEP(c) ((c) == '/') +#else +# define ISDIRSEP(c) ((c) == '/' || (c) == '\\') +#endif /* __CYGWIN__ */ +#define PATHSEP(c) (ISDIRSEP(c) || (c) == 0) + +#define DOT_OR_DOTDOT(s) (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) +#if defined (HANDLE_MULTIBYTE) +#define WDOT_OR_DOTDOT(w) (w[0] == L'.' && (w[1] == L'\0' || (w[1] == L'.' && w[2] == L'\0'))) +#endif + +#if 0 +/* Declarations for functions defined in xmalloc.c */ +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); +#endif + +/* Declarations for functions defined in general.c */ +extern void posix_initialize PARAMS((int)); + +extern int num_posix_options PARAMS((void)); +extern char *get_posix_options PARAMS((char *)); +extern void set_posix_options PARAMS((const char *)); + +extern void save_posix_options PARAMS((void)); + +#if defined (RLIMTYPE) +extern RLIMTYPE string_to_rlimtype PARAMS((char *)); +extern void print_rlimtype PARAMS((RLIMTYPE, int)); +#endif + +extern int all_digits PARAMS((const char *)); +extern int legal_number PARAMS((const char *, intmax_t *)); +extern int legal_identifier PARAMS((const char *)); +extern int importable_function_name PARAMS((const char *, size_t)); +extern int exportable_function_name PARAMS((const char *)); +extern int check_identifier PARAMS((WORD_DESC *, int)); +extern int valid_nameref_value PARAMS((const char *, int)); +extern int check_selfref PARAMS((const char *, char *, int)); +extern int legal_alias_name PARAMS((const char *, int)); +extern int line_isblank PARAMS((const char *)); +extern int assignment PARAMS((const char *, int)); + +extern int sh_unset_nodelay_mode PARAMS((int)); +extern int sh_setclexec PARAMS((int)); +extern int sh_validfd PARAMS((int)); +extern int fd_ispipe PARAMS((int)); +extern void check_dev_tty PARAMS((void)); +extern int move_to_high_fd PARAMS((int, int, int)); +extern int check_binary_file PARAMS((const char *, int)); + +#ifdef _POSIXSTAT_H_ +extern int same_file PARAMS((const char *, const char *, struct stat *, struct stat *)); +#endif + +extern int sh_openpipe PARAMS((int *)); +extern int sh_closepipe PARAMS((int *)); + +extern int file_exists PARAMS((const char *)); +extern int file_isdir PARAMS((const char *)); +extern int file_iswdir PARAMS((const char *)); +extern int path_dot_or_dotdot PARAMS((const char *)); +extern int absolute_pathname PARAMS((const char *)); +extern int absolute_program PARAMS((const char *)); + +extern char *make_absolute PARAMS((const char *, const char *)); +extern char *base_pathname PARAMS((char *)); +extern char *full_pathname PARAMS((char *)); +extern char *polite_directory_format PARAMS((char *)); +extern char *trim_pathname PARAMS((char *, int)); +extern char *printable_filename PARAMS((char *, int)); + +extern char *extract_colon_unit PARAMS((char *, int *)); + +extern void tilde_initialize PARAMS((void)); +extern char *bash_tilde_find_word PARAMS((const char *, int, int *)); +extern char *bash_tilde_expand PARAMS((const char *, int)); + +extern int group_member PARAMS((gid_t)); +extern char **get_group_list PARAMS((int *)); +extern int *get_group_array PARAMS((int *)); + +extern char *conf_standard_path PARAMS((void)); +extern int default_columns PARAMS((void)); + +#endif /* _GENERAL_H_ */ diff --git a/utshell-0.5.0/lib/include/gettext.h b/utshell-0.5.0/lib/include/gettext.h new file mode 100644 index 00000000..97a1f36d --- /dev/null +++ b/utshell-0.5.0/lib/include/gettext.h @@ -0,0 +1,70 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff --git a/utshell-0.5.0/lib/include/hashlib.h b/utshell-0.5.0/lib/include/hashlib.h new file mode 100644 index 00000000..6cf0406c --- /dev/null +++ b/utshell-0.5.0/lib/include/hashlib.h @@ -0,0 +1,93 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* hashlib.h -- the data structures used in hashing in Bash. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_HASHLIB_H_) +#define _HASHLIB_H_ + +#include "stdc.h" + +#ifndef PTR_T +# ifdef __STDC__ +# define PTR_T void * +# else +# define PTR_T char * +# endif +#endif + +typedef struct bucket_contents { + struct bucket_contents *next; /* Link to next hashed key in this bucket. */ + char *key; /* What we look up. */ + PTR_T data; /* What we really want. */ + unsigned int khash; /* What key hashes to */ + int times_found; /* Number of times this item has been found. */ +} BUCKET_CONTENTS; + +typedef struct hash_table { + BUCKET_CONTENTS **bucket_array; /* Where the data is kept. */ + int nbuckets; /* How many buckets does this table have. */ + int nentries; /* How many entries does this table have. */ +} HASH_TABLE; + +typedef int hash_wfunc PARAMS((BUCKET_CONTENTS *)); + +/* Operations on tables as a whole */ +extern HASH_TABLE *hash_create PARAMS((int)); +extern HASH_TABLE *hash_copy PARAMS((HASH_TABLE *, sh_string_func_t *)); +extern void hash_flush PARAMS((HASH_TABLE *, sh_free_func_t *)); +extern void hash_dispose PARAMS((HASH_TABLE *)); +extern void hash_walk PARAMS((HASH_TABLE *, hash_wfunc *)); + +/* Operations to extract information from or pieces of tables */ +extern int hash_bucket PARAMS((const char *, HASH_TABLE *)); +extern int hash_size PARAMS((HASH_TABLE *)); + +/* Operations on hash table entries */ +extern BUCKET_CONTENTS *hash_search PARAMS((const char *, HASH_TABLE *, int)); +extern BUCKET_CONTENTS *hash_insert PARAMS((char *, HASH_TABLE *, int)); +extern BUCKET_CONTENTS *hash_remove PARAMS((const char *, HASH_TABLE *, int)); + +/* Miscellaneous */ +extern unsigned int hash_string PARAMS((const char *)); + +/* Redefine the function as a macro for speed. */ +#define hash_items(bucket, table) \ + ((table && (bucket < table->nbuckets)) ? \ + table->bucket_array[bucket] : \ + (BUCKET_CONTENTS *)NULL) + +/* Default number of buckets in the hash table. */ +#define DEFAULT_HASH_BUCKETS 128 /* must be power of two */ + +#define HASH_ENTRIES(ht) ((ht) ? (ht)->nentries : 0) + +/* flags for hash_search and hash_insert */ +#define HASH_NOSRCH 0x01 +#define HASH_CREATE 0x02 + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +#endif /* _HASHLIB_H */ diff --git a/utshell-0.5.0/lib/include/make_cmd.h b/utshell-0.5.0/lib/include/make_cmd.h new file mode 100644 index 00000000..ddfa964c --- /dev/null +++ b/utshell-0.5.0/lib/include/make_cmd.h @@ -0,0 +1,73 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* make_cmd.h -- Declarations of functions found in make_cmd.c */ + +/* Copyright (C) 1993-2009,2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_MAKE_CMD_H_) +#define _MAKE_CMD_H_ + +#include "stdc.h" + +extern int here_doc_first_line; + +extern void cmd_init PARAMS((void)); + +extern WORD_DESC *alloc_word_desc PARAMS((void)); +extern WORD_DESC *make_bare_word PARAMS((const char *)); +extern WORD_DESC *make_word_flags PARAMS((WORD_DESC *, const char *)); +extern WORD_DESC *make_word PARAMS((const char *)); +extern WORD_DESC *make_word_from_token PARAMS((int)); + +extern WORD_LIST *make_word_list PARAMS((WORD_DESC *, WORD_LIST *)); + +#define add_string_to_list(s, l) make_word_list (make_word(s), (l)) + +extern COMMAND *make_command PARAMS((enum command_type, SIMPLE_COM *)); +extern COMMAND *command_connect PARAMS((COMMAND *, COMMAND *, int)); +extern COMMAND *make_for_command PARAMS((WORD_DESC *, WORD_LIST *, COMMAND *, int)); +extern COMMAND *make_group_command PARAMS((COMMAND *)); +extern COMMAND *make_case_command PARAMS((WORD_DESC *, PATTERN_LIST *, int)); +extern PATTERN_LIST *make_pattern_list PARAMS((WORD_LIST *, COMMAND *)); +extern COMMAND *make_if_command PARAMS((COMMAND *, COMMAND *, COMMAND *)); +extern COMMAND *make_while_command PARAMS((COMMAND *, COMMAND *)); +extern COMMAND *make_until_command PARAMS((COMMAND *, COMMAND *)); +extern COMMAND *make_bare_simple_command PARAMS((void)); +extern COMMAND *make_simple_command PARAMS((ELEMENT, COMMAND *)); +extern void make_here_document PARAMS((REDIRECT *, int)); +extern REDIRECT *make_redirection PARAMS((REDIRECTEE, enum r_instruction, REDIRECTEE, int)); +extern COMMAND *make_function_def PARAMS((WORD_DESC *, COMMAND *, int, int)); +extern COMMAND *clean_simple_command PARAMS((COMMAND *)); + +extern COMMAND *make_arith_command PARAMS((WORD_LIST *)); + +extern COMMAND *make_select_command PARAMS((WORD_DESC *, WORD_LIST *, COMMAND *, int)); + +#if defined (COND_COMMAND) +extern COND_COM *make_cond_node PARAMS((int, WORD_DESC *, COND_COM *, COND_COM *)); +extern COMMAND *make_cond_command PARAMS((COND_COM *)); +#endif + +extern COMMAND *make_arith_for_command PARAMS((WORD_LIST *, COMMAND *, int)); + +extern COMMAND *make_subshell_command PARAMS((COMMAND *)); +extern COMMAND *make_coproc_command PARAMS((char *, COMMAND *)); + +extern COMMAND *connect_async_list PARAMS((COMMAND *, COMMAND *, int)); + +#endif /* !_MAKE_CMD_H */ diff --git a/utshell-0.5.0/lib/include/maxpath.h b/utshell-0.5.0/lib/include/maxpath.h new file mode 100644 index 00000000..db2e1fb4 --- /dev/null +++ b/utshell-0.5.0/lib/include/maxpath.h @@ -0,0 +1,75 @@ +/* maxpath.h - Find out what this system thinks PATH_MAX and NAME_MAX are. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_MAXPATH_H_) +#define _MAXPATH_H_ + +/* These values are supposed to be in or one of the files + it includes. */ +#if defined (HAVE_LIMITS_H) +# include +#endif /* !HAVE_LIMITS_H */ + +/* If PATH_MAX is not defined, look for MAXPATHLEN */ +#if !defined (PATH_MAX) +# if defined (HAVE_SYS_PARAM_H) +# include +# define maxpath_param_h +# endif +# if defined (MAXPATHLEN) && !defined (PATH_MAX) +# define PATH_MAX MAXPATHLEN +# endif /* MAXPATHLEN && !PATH_MAX */ +#endif /* !PATH_MAX */ + +/* If NAME_MAX is not defined, look for MAXNAMLEN */ +#if !defined (NAME_MAX) +# if defined (HAVE_SYS_PARAM_H) && !defined (maxpath_param_h) +# include +# endif +# if defined (MAXNAMLEN) && !defined (NAME_MAX) +# define NAME_MAX MAXNAMLEN +# endif /* MAXNAMLEN && !NAME_MAX */ +#endif /* !NAME_MAX */ + +/* Default POSIX values */ +#if !defined (PATH_MAX) && defined (_POSIX_PATH_MAX) +# define PATH_MAX _POSIX_PATH_MAX +#endif + +#if !defined (NAME_MAX) && defined (_POSIX_NAME_MAX) +# define NAME_MAX _POSIX_NAME_MAX +#endif + + +/* Default values */ +#if !defined (PATH_MAX) +# define PATH_MAX 1024 +#endif + +#if !defined (NAME_MAX) +# define NAME_MAX 14 +#endif + +#if PATH_MAX < 1024 +# undef PATH_MAX +# define PATH_MAX 1024 +#endif + +#endif /* _MAXPATH_H_ */ diff --git a/utshell-0.5.0/lib/include/memalloc.h b/utshell-0.5.0/lib/include/memalloc.h new file mode 100644 index 00000000..57318b9d --- /dev/null +++ b/utshell-0.5.0/lib/include/memalloc.h @@ -0,0 +1,62 @@ +/* memalloc.h -- consolidate code for including alloca.h or malloc.h and + defining alloca. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_MEMALLOC_H_) +# define _MEMALLOC_H_ + +#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H) +# define HAVE_ALLOCA_H +#endif + +#if defined (__GNUC__) && !defined (HAVE_ALLOCA) +# define HAVE_ALLOCA +#endif + +#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA) && !defined (C_ALLOCA) +# define HAVE_ALLOCA +#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */ + +#if defined (__GNUC__) && !defined (C_ALLOCA) +# undef alloca +# define alloca __builtin_alloca +#else /* !__GNUC__ || C_ALLOCA */ +# if defined (HAVE_ALLOCA_H) && !defined (C_ALLOCA) +# if defined (IBMESA) +# include +# else /* !IBMESA */ +# include +# endif /* !IBMESA */ +# else /* !HAVE_ALLOCA_H || C_ALLOCA */ +# if defined (__hpux) && defined (__STDC__) && !defined (alloca) +extern void *alloca (); +# else +# if !defined (alloca) +# if defined (__STDC__) +extern void *alloca (size_t); +# else +extern char *alloca (); +# endif /* !__STDC__ */ +# endif /* !alloca */ +# endif /* !__hpux || !__STDC__ && !alloca */ +# endif /* !HAVE_ALLOCA_H || C_ALLOCA */ +#endif /* !__GNUC__ || C_ALLOCA */ + +#endif /* _MEMALLOC_H_ */ diff --git a/utshell-0.5.0/lib/include/ocache.h b/utshell-0.5.0/lib/include/ocache.h new file mode 100644 index 00000000..c596c272 --- /dev/null +++ b/utshell-0.5.0/lib/include/ocache.h @@ -0,0 +1,133 @@ +/* ocache.h -- a minimal object caching implementation. */ + +/* Copyright (C) 2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_OCACHE_H_) +#define _OCACHE_H_ 1 + +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +#define OC_MEMSET(memp, xch, nbytes) \ +do { \ + if ((nbytes) <= 32) { \ + register char * mzp = (char *)(memp); \ + unsigned long mctmp = (nbytes); \ + register long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = xch; \ + case 7: *mzp++ = xch; \ + case 6: *mzp++ = xch; \ + case 5: *mzp++ = xch; \ + case 4: *mzp++ = xch; \ + case 3: *mzp++ = xch; \ + case 2: *mzp++ = xch; \ + case 1: *mzp++ = xch; if(mcn <= 0) break; mcn--; } \ + } \ + } else \ + memset ((memp), (xch), (nbytes)); \ +} while(0) + +typedef struct objcache { + PTR_T data; + int cs; /* cache size, number of objects */ + int nc; /* number of cache entries */ +} sh_obj_cache_t; + +/* Create an object cache C of N pointers to OTYPE. */ +#define ocache_create(c, otype, n) \ + do { \ + (c).data = xmalloc((n) * sizeof (otype *)); \ + (c).cs = (n); \ + (c).nc = 0; \ + } while (0) + +/* Destroy an object cache C. */ +#define ocache_destroy(c) \ + do { \ + if ((c).data) \ + xfree ((c).data); \ + (c).data = 0; \ + (c).cs = (c).nc = 0; \ + } while (0) + +/* Free all cached items, which are pointers to OTYPE, in object cache C. */ +#define ocache_flush(c, otype) \ + do { \ + while ((c).nc > 0) \ + xfree (((otype **)((c).data))[--(c).nc]); \ + } while (0) + +/* + * Allocate a new item of type pointer to OTYPE, using data from object + * cache C if any cached items exist, otherwise calling xmalloc. Return + * the object in R. + */ +#define ocache_alloc(c, otype, r) \ + do { \ + if ((c).nc > 0) { \ + (r) = (otype *)((otype **)((c).data))[--(c).nc]; \ + } else \ + (r) = (otype *)xmalloc (sizeof (otype)); \ + } while (0) + +/* + * Free an item R of type pointer to OTYPE, adding to object cache C if + * there is room and calling xfree if the cache is full. If R is added + * to the object cache, the contents are scrambled. + */ +#define ocache_free(c, otype, r) \ + do { \ + if ((c).nc < (c).cs) { \ + OC_MEMSET ((r), 0xdf, sizeof(otype)); \ + ((otype **)((c).data))[(c).nc++] = (r); \ + } else \ + xfree (r); \ + } while (0) + +/* + * One may declare and use an object cache as (for instance): + * + * sh_obj_cache_t wdcache = {0, 0, 0}; + * sh_obj_cache_t wlcache = {0, 0, 0}; + * + * ocache_create(wdcache, WORD_DESC, 30); + * ocache_create(wlcache, WORD_LIST, 30); + * + * WORD_DESC *wd; + * ocache_alloc (wdcache, WORD_DESC, wd); + * + * WORD_LIST *wl; + * ocache_alloc (wlcache, WORD_LIST, wl); + * + * ocache_free(wdcache, WORD_DESC, wd); + * ocache_free(wlcache, WORD_LIST, wl); + * + * The use is almost arbitrary. + */ + +#endif /* _OCACHE_H */ diff --git a/utshell-0.5.0/lib/include/pathnames.h b/utshell-0.5.0/lib/include/pathnames.h new file mode 100644 index 00000000..02ed0445 --- /dev/null +++ b/utshell-0.5.0/lib/include/pathnames.h @@ -0,0 +1,33 @@ +/* pathnames.h -- absolute filenames that bash wants for various defaults. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_PATHNAMES_H_) +#define _PATHNAMES_H_ + +/* The default file for hostname completion. */ +#define DEFAULT_HOSTS_FILE "/etc/hosts" + +/* The default login shell startup file. */ +#define SYS_PROFILE "/etc/profile" + +/* The default location of the bash debugger initialization/startup file. */ +#define DEBUGGER_START_FILE "/usr/local/share/utshelldb/utshelldb-main.inc" + +#endif /* _PATHNAMES_H */ diff --git a/utshell-0.5.0/lib/include/posixdir.h b/utshell-0.5.0/lib/include/posixdir.h new file mode 100644 index 00000000..af5be801 --- /dev/null +++ b/utshell-0.5.0/lib/include/posixdir.h @@ -0,0 +1,71 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991,2012 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of or . */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include +# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN) +# define D_NAMLEN(d) ((d)->d_namlen) +# else +# define D_NAMLEN(d) (strlen ((d)->d_name)) +# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */ +#else +# if defined (HAVE_SYS_NDIR_H) +# include +# endif +# if defined (HAVE_SYS_DIR_H) +# include +# endif +# if defined (HAVE_NDIR_H) +# include +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +/* The bash code fairly consistently uses d_fileno; make sure it's available */ +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO) +# define d_fileno d_ino +#endif + +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +#if !defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO) +# define REAL_DIR_ENTRY(dp) 1 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* _POSIX_SOURCE */ + +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (BROKEN_DIRENT_D_INO) +# define D_INO_AVAILABLE +#endif + +/* Signal the rest of the code that it can safely use dirent.d_fileno */ +#if defined (D_INO_AVAILABLE) || defined (HAVE_STRUCT_DIRENT_D_FILENO) +# define D_FILENO_AVAILABLE 1 +#endif + +#endif /* !_POSIXDIR_H_ */ diff --git a/utshell-0.5.0/lib/include/posixjmp.h b/utshell-0.5.0/lib/include/posixjmp.h new file mode 100644 index 00000000..9c7e99ed --- /dev/null +++ b/utshell-0.5.0/lib/include/posixjmp.h @@ -0,0 +1,46 @@ +/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ + +/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXJMP_H_ +#define _POSIXJMP_H_ + +#include + +/* This *must* be included *after* config.h */ + +#if defined (HAVE_POSIX_SIGSETJMP) +# define procenv_t sigjmp_buf + +# define setjmp_nosigs(x) sigsetjmp((x), 0) +# define setjmp_sigs(x) sigsetjmp((x), 1) + +# define _rl_longjmp(x, n) siglongjmp((x), (n)) +# define sh_longjmp(x, n) siglongjmp((x), (n)) +#else +# define procenv_t jmp_buf + +# define setjmp_nosigs setjmp +# define setjmp_sigs setjmp + +# define _rl_longjmp(x, n) longjmp((x), (n)) +# define sh_longjmp(x, n) longjmp((x), (n)) +#endif + +#endif /* _POSIXJMP_H_ */ diff --git a/utshell-0.5.0/lib/include/posixselect.h b/utshell-0.5.0/lib/include/posixselect.h new file mode 100644 index 00000000..da6a1ace --- /dev/null +++ b/utshell-0.5.0/lib/include/posixselect.h @@ -0,0 +1,47 @@ +/* posixselect.h -- wrapper for select(2) includes and definitions */ + +/* Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXSELECT_H_ +#define _POSIXSELECT_H_ + +#if defined (FD_SET) && !defined (HAVE_SELECT) +# define HAVE_SELECT 1 +#endif + +#if defined (HAVE_SELECT) +# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) +# include +# endif +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#ifndef USEC_PER_SEC +# define USEC_PER_SEC 1000000 +#endif + +#define USEC_TO_TIMEVAL(us, tv) \ +do { \ + (tv).tv_sec = (us) / USEC_PER_SEC; \ + (tv).tv_usec = (us) % USEC_PER_SEC; \ +} while (0) + +#endif /* _POSIXSELECT_H_ */ diff --git a/utshell-0.5.0/lib/include/posixstat.h b/utshell-0.5.0/lib/include/posixstat.h new file mode 100644 index 00000000..b6077860 --- /dev/null +++ b/utshell-0.5.0/lib/include/posixstat.h @@ -0,0 +1,162 @@ +/* posixstat.h -- Posix stat(2) definitions for systems that + don't have them. */ + +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of . + It relies on the local sys/stat.h to work though. */ +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ + +#include + +#if defined (STAT_MACROS_BROKEN) +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISREG +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ + +/* Posix 1003.1 5.6.1.1 file types */ + +/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but + do not provide the S_IS* macros that Posix requires. */ + +#if defined (_S_IFMT) && !defined (S_IFMT) +#define S_IFMT _S_IFMT +#endif +#if defined (_S_IFIFO) && !defined (S_IFIFO) +#define S_IFIFO _S_IFIFO +#endif +#if defined (_S_IFCHR) && !defined (S_IFCHR) +#define S_IFCHR _S_IFCHR +#endif +#if defined (_S_IFDIR) && !defined (S_IFDIR) +#define S_IFDIR _S_IFDIR +#endif +#if defined (_S_IFBLK) && !defined (S_IFBLK) +#define S_IFBLK _S_IFBLK +#endif +#if defined (_S_IFREG) && !defined (S_IFREG) +#define S_IFREG _S_IFREG +#endif +#if defined (_S_IFLNK) && !defined (S_IFLNK) +#define S_IFLNK _S_IFLNK +#endif +#if defined (_S_IFSOCK) && !defined (S_IFSOCK) +#define S_IFSOCK _S_IFSOCK +#endif + +/* Test for each symbol individually and define the ones necessary (some + systems claiming Posix compatibility define some but not all). */ + +#if defined (S_IFBLK) && !defined (S_ISBLK) +#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ +#endif + +#if defined (S_IFCHR) && !defined (S_ISCHR) +#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ +#endif + +#if defined (S_IFDIR) && !defined (S_ISDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ +#endif + +#if defined (S_IFREG) && !defined (S_ISREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ +#endif + +#if defined (S_IFIFO) && !defined (S_ISFIFO) +#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ +#endif + +#if defined (S_IFLNK) && !defined (S_ISLNK) +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ +#endif + +#if defined (S_IFSOCK) && !defined (S_ISSOCK) +#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ +#endif + +/* + * POSIX 1003.1 5.6.1.2 File Modes + */ + +#if !defined (S_IRWXU) +# if !defined (S_IREAD) +# define S_IREAD 00400 +# define S_IWRITE 00200 +# define S_IEXEC 00100 +# endif /* S_IREAD */ + +# if !defined (S_IRUSR) +# define S_IRUSR S_IREAD /* read, owner */ +# define S_IWUSR S_IWRITE /* write, owner */ +# define S_IXUSR S_IEXEC /* execute, owner */ + +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ + +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IRUSR */ + +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#else /* !S_IRWXU */ + /* S_IRWXU is defined, but "group" and "other" bits might not be + (happens in certain versions of MinGW). */ +# if !defined (S_IRGRP) +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ +# endif /* !S_IRGRP */ + +# if !defined (S_IROTH) +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IROTH */ +# if !defined (S_IRWXG) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# endif +# if !defined (S_IRWXO) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +# endif +#endif /* !S_IRWXU */ + +/* These are non-standard, but are used in builtins.c$symbolic_umask() */ +#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#endif /* _POSIXSTAT_H_ */ diff --git a/utshell-0.5.0/lib/include/posixtime.h b/utshell-0.5.0/lib/include/posixtime.h new file mode 100644 index 00000000..a83e436b --- /dev/null +++ b/utshell-0.5.0/lib/include/posixtime.h @@ -0,0 +1,61 @@ +/* posixtime.h -- wrapper for time.h, sys/times.h mess. */ + +/* Copyright (C) 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXTIME_H_ +#define _POSIXTIME_H_ + +/* include this after config.h */ +/* Some systems require this, mostly for the definition of `struct timezone'. + For example, Dynix/ptx has that definition in rather than + sys/time.h */ +#if defined (TIME_WITH_SYS_TIME) +# include +# include +#else +# if defined (HAVE_SYS_TIME_H) +# include +# else +# include +# endif +#endif + +#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK) +# if !defined (CLK_TCK) +# if defined (HZ) +# define CLK_TCK HZ +# else +# define CLK_TCK 60 /* 60HZ */ +# endif +# endif /* !CLK_TCK */ +#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */ + +#if !HAVE_TIMEVAL +struct timeval +{ + time_t tv_sec; + long int tv_usec; +}; +#endif + +#if !HAVE_GETTIMEOFDAY +extern int gettimeofday PARAMS((struct timeval *, void *)); +#endif + +#endif /* _POSIXTIME_H_ */ diff --git a/utshell-0.5.0/lib/include/posixwait.h b/utshell-0.5.0/lib/include/posixwait.h new file mode 100644 index 00000000..63b59c24 --- /dev/null +++ b/utshell-0.5.0/lib/include/posixwait.h @@ -0,0 +1,107 @@ +/* posixwait.h -- job control definitions from POSIX 1003.1 */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_POSIXWAIT_H_) +# define _POSIXWAIT_H_ + +/* If _POSIX_VERSION is not defined, we assume that defines + a `union wait' and various macros used to manipulate it. Look in + unionwait.h for the things we expect to find. */ +#if defined (HAVE_SYS_WAIT_H) +# include +#else /* !HAVE_SYS_WAIT_H */ +# if !defined (_POSIX_VERSION) +# include "unionwait.h" +# endif +#endif /* !HAVE_SYS_WAIT_H */ + +/* How to get the status of a job. For Posix, this is just an + int, but for other systems we have to crack the union wait. */ +#if !defined (_POSIX_VERSION) +typedef union wait WAIT; +# define WSTATUS(t) (t.w_status) +#else /* _POSIX_VERSION */ +typedef int WAIT; +# define WSTATUS(t) (t) +#endif /* _POSIX_VERSION */ + +/* Make sure that parameters to wait3 are defined. */ +#if !defined (WNOHANG) +# define WNOHANG 1 +# define WUNTRACED 2 +#endif /* WNOHANG */ + +/* More Posix P1003.1 definitions. In the POSIX versions, the parameter is + passed as an `int', in the non-POSIX version, as `union wait'. */ +#if defined (_POSIX_VERSION) + +# if !defined (WSTOPSIG) +# define WSTOPSIG(s) ((s) >> 8) +# endif /* !WSTOPSIG */ + +# if !defined (WTERMSIG) +# define WTERMSIG(s) ((s) & 0177) +# endif /* !WTERMSIG */ + +# if !defined (WEXITSTATUS) +# define WEXITSTATUS(s) ((s) >> 8) +# endif /* !WEXITSTATUS */ + +# if !defined (WIFSTOPPED) +# define WIFSTOPPED(s) (((s) & 0177) == 0177) +# endif /* !WIFSTOPPED */ + +# if !defined (WIFEXITED) +# define WIFEXITED(s) (((s) & 0377) == 0) +# endif /* !WIFEXITED */ + +# if !defined (WIFSIGNALED) +# define WIFSIGNALED(s) (!WIFSTOPPED(s) && !WIFEXITED(s)) +# endif /* !WIFSIGNALED */ + +# if !defined (WIFCORED) +# if defined (WCOREDUMP) +# define WIFCORED(s) (WCOREDUMP(s)) +# else +# define WIFCORED(s) ((s) & 0200) +# endif +# endif /* !WIFCORED */ + +#else /* !_POSIX_VERSION */ + +# if !defined (WSTOPSIG) +# define WSTOPSIG(s) ((s).w_stopsig) +# endif /* !WSTOPSIG */ + +# if !defined (WTERMSIG) +# define WTERMSIG(s) ((s).w_termsig) +# endif /* !WTERMSIG */ + +# if !defined (WEXITSTATUS) +# define WEXITSTATUS(s) ((s).w_retcode) +# endif /* !WEXITSTATUS */ + +# if !defined (WIFCORED) +# define WIFCORED(s) ((s).w_coredump) +# endif /* !WIFCORED */ + +#endif /* !_POSIX_VERSION */ + +#endif /* !_POSIXWAIT_H_ */ diff --git a/utshell-0.5.0/lib/include/quit.h b/utshell-0.5.0/lib/include/quit.h new file mode 100644 index 00000000..6470ed5d --- /dev/null +++ b/utshell-0.5.0/lib/include/quit.h @@ -0,0 +1,82 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* quit.h -- How to handle SIGINT gracefully. */ + +/* Copyright (C) 1993-2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_QUIT_H_) +#define _QUIT_H_ + +#include "sig.h" /* for sig_atomic_t */ + +/* Non-zero means SIGINT has already occurred. */ +extern volatile sig_atomic_t interrupt_state; +extern volatile sig_atomic_t terminating_signal; + +/* Macro to call a great deal. SIGINT just sets the interrupt_state variable. + When it is safe, put QUIT in the code, and the "interrupt" will take + place. The same scheme is used for terminating signals (e.g., SIGHUP) + and the terminating_signal variable. That calls a function which will + end up exiting the shell. */ +#define QUIT \ + do { \ + if (terminating_signal) termsig_handler (terminating_signal); \ + if (interrupt_state) throw_to_top_level (); \ + } while (0) + +#define CHECK_ALRM \ + do { \ + if (sigalrm_seen) \ + sh_longjmp (alrmbuf, 1); \ + } while (0) + +#define SETINTERRUPT interrupt_state = 1 +#define CLRINTERRUPT interrupt_state = 0 + +#define ADDINTERRUPT interrupt_state++ +#define DELINTERRUPT interrupt_state-- + +#define ISINTERRUPT interrupt_state != 0 + +/* The same sort of thing, this time just for signals that would ordinarily + cause the shell to terminate. */ + +#define CHECK_TERMSIG \ + do { \ + if (terminating_signal) termsig_handler (terminating_signal); \ + } while (0) + +#define LASTSIG() \ + (terminating_signal ? terminating_signal : (interrupt_state ? SIGINT : 0)) + +#define CHECK_WAIT_INTR \ + do { \ + if (wait_intr_flag && wait_signal_received && this_shell_builtin && (this_shell_builtin == wait_builtin)) \ + sh_longjmp (wait_intr_buf, 1); \ + } while (0) + +#define RESET_SIGTERM \ + do { \ + sigterm_received = 0; \ + } while (0) + +#define CHECK_SIGTERM \ + do { \ + if (sigterm_received) termsig_handler (SIGTERM); \ + } while (0) +#endif /* _QUIT_H_ */ diff --git a/utshell-0.5.0/lib/include/shell.h b/utshell-0.5.0/lib/include/shell.h new file mode 100644 index 00000000..bda3c37d --- /dev/null +++ b/utshell-0.5.0/lib/include/shell.h @@ -0,0 +1,231 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* shell.h -- The data structures used by the shell */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "bashjmp.h" + +#include "command.h" +#include "syntax.h" +#include "general.h" +#include "error.h" +#include "variables.h" +#include "arrayfunc.h" +#include "quit.h" +#include "maxpath.h" +#include "unwind_prot.h" +#include "dispose_cmd.h" +#include "make_cmd.h" +#include "ocache.h" +#include "subst.h" +#include "sig.h" +#include "pathnames.h" +#include "externs.h" + +extern int EOF_Reached; + +#define NO_PIPE -1 +#define REDIRECT_BOTH -2 + +#define NO_VARIABLE -1 + +/* Values that can be returned by execute_command (). */ +#define EXECUTION_FAILURE 1 +#define EXECUTION_SUCCESS 0 + +/* Usage messages by builtins result in a return status of 2. */ +#define EX_BADUSAGE 2 + +#define EX_MISCERROR 2 + +/* Special exit statuses used by the shell, internally and externally. */ +#define EX_RETRYFAIL 124 +#define EX_WEXPCOMSUB 125 +#define EX_BINARY_FILE 126 +#define EX_NOEXEC 126 +#define EX_NOINPUT 126 +#define EX_NOTFOUND 127 + +#define EX_SHERRBASE 256 /* all special error values are > this. */ + +#define EX_BADSYNTAX 257 /* shell syntax error */ +#define EX_USAGE 258 /* syntax error in usage */ +#define EX_REDIRFAIL 259 /* redirection failed */ +#define EX_BADASSIGN 260 /* variable assignment error */ +#define EX_EXPFAIL 261 /* word expansion failed */ +#define EX_DISKFALLBACK 262 /* fall back to disk command from builtin */ + +/* Flag values that control parameter pattern substitution. */ +#define MATCH_ANY 0x000 +#define MATCH_BEG 0x001 +#define MATCH_END 0x002 + +#define MATCH_TYPEMASK 0x003 + +#define MATCH_GLOBREP 0x010 +#define MATCH_QUOTED 0x020 +#define MATCH_ASSIGNRHS 0x040 +#define MATCH_STARSUB 0x080 + +/* Some needed external declarations. */ +extern char **shell_environment; +extern WORD_LIST *rest_of_args; + +/* Generalized global variables. */ +extern char *command_execution_string; + +extern int debugging_mode; +extern int executing, login_shell; +extern int interactive, interactive_shell; +extern int startup_state; +extern int reading_shell_script; +extern int shell_initialized; +extern int rpm_requires; +extern int bash_argv_initialized; +extern int subshell_environment; +extern int current_command_number; +extern int indirection_level; +extern int shell_compatibility_level; +extern int running_under_emacs; + +extern int posixly_correct; +extern int no_line_editing; + +extern char *shell_name; +extern char *current_host_name; + +extern int subshell_argc; +extern char **subshell_argv; +extern char **subshell_envp; + +/* variables managed using shopt */ +extern int hup_on_exit; +extern int check_jobs_at_exit; +extern int autocd; +extern int check_window_size; + +/* from version.c */ +extern int build_version, patch_level; +extern char *dist_version, *release_status; + +extern int locale_mb_cur_max; +extern int locale_utf8locale; + +/* Structure to pass around that holds a bitmap of file descriptors + to close, and the size of that structure. Used in execute_cmd.c. */ +struct fd_bitmap { + int size; + char *bitmap; +}; + +#define FD_BITMAP_SIZE 32 + +#define CTLESC '\001' +#define CTLNUL '\177' + +/* Information about the current user. */ +struct user_info { + uid_t uid, euid; + gid_t gid, egid; + char *user_name; + char *shell; /* shell from the password file */ + char *home_dir; +}; + +extern struct user_info current_user; + +/* Force gcc to not clobber X on a longjmp(). Old versions of gcc mangle + this badly. */ +#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 8) +# define USE_VAR(x) ((void) &(x)) +#else +# define USE_VAR(x) +#endif + +#define HEREDOC_MAX 16 + +/* Structure in which to save partial parsing state when doing things like + PROMPT_COMMAND and bash_execute_unix_command execution. */ + +typedef struct _sh_parser_state_t { + + /* parsing state */ + int parser_state; + int *token_state; + + char *token; + int token_buffer_size; + + /* input line state -- line number saved elsewhere */ + int input_line_terminator; + int eof_encountered; + +#if defined (HANDLE_MULTIBYTE) + /* Nothing right now for multibyte state, but might want something later. */ +#endif + + char **prompt_string_pointer; + + /* history state affecting or modified by the parser */ + int current_command_line_count; +#if defined (HISTORY) + int remember_on_history; + int history_expansion_inhibited; +#endif + + /* execution state possibly modified by the parser */ + int last_command_exit_value; +#if defined (ARRAY_VARS) + ARRAY *pipestatus; +#endif + sh_builtin_func_t *last_shell_builtin, *this_shell_builtin; + + /* flags state affecting the parser */ + int expand_aliases; + int echo_input_at_read; + int need_here_doc; + int here_doc_first_line; + + /* structures affecting the parser */ + REDIRECT *redir_stack[HEREDOC_MAX]; +} sh_parser_state_t; + +typedef struct _sh_input_line_state_t { + char *input_line; + size_t input_line_index; + size_t input_line_size; + size_t input_line_len; +#if defined (HANDLE_MULTIBYTE) + char *input_property; + size_t input_propsize; +#endif +} sh_input_line_state_t; + +/* Let's try declaring these here. */ +extern char *parser_remaining_input PARAMS((void)); + +extern sh_parser_state_t *save_parser_state PARAMS((sh_parser_state_t *)); +extern void restore_parser_state PARAMS((sh_parser_state_t *)); + +extern sh_input_line_state_t *save_input_line_state PARAMS((sh_input_line_state_t *)); +extern void restore_input_line_state PARAMS((sh_input_line_state_t *)); diff --git a/utshell-0.5.0/lib/include/shmbchar.h b/utshell-0.5.0/lib/include/shmbchar.h new file mode 100644 index 00000000..a4f3f247 --- /dev/null +++ b/utshell-0.5.0/lib/include/shmbchar.h @@ -0,0 +1,112 @@ +/* Multibyte character data type. + Copyright (C) 2001, 2005-2007, 2009-2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible . */ + +#ifndef _SHMBCHAR_H +#define _SHMBCHAR_H 1 + +#if defined (HANDLE_MULTIBYTE) + +#include + +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.1 has a bug: and must be included before + . */ +#include +#include +#include +#include + + +/* is_basic(c) tests whether the single-byte character c is in the + ISO C "basic character set". */ + +#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) +/* The character set is ISO-646, not EBCDIC. */ +# define IS_BASIC_ASCII 1 + +extern const unsigned int is_basic_table[]; + +static inline int +is_basic (char c) +{ + return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31)) + & 1; +} + +#else + +static inline int +is_basic (char c) +{ + switch (c) + { + case '\b': case '\r': case '\n': + case '\t': case '\v': case '\f': + case ' ': case '!': case '"': case '#': case '%': + case '&': case '\'': case '(': case ')': case '*': + case '+': case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': + case '?': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': + case 'Z': + case '[': case '\\': case ']': case '^': case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': + case 'z': case '{': case '|': case '}': case '~': + return 1; + default: + return 0; + } +} + +#endif + +#endif /* HANDLE_MULTIBYTE */ +#endif /* _SHMBCHAR_H */ diff --git a/utshell-0.5.0/lib/include/shmbutil.h b/utshell-0.5.0/lib/include/shmbutil.h new file mode 100644 index 00000000..835fb80c --- /dev/null +++ b/utshell-0.5.0/lib/include/shmbutil.h @@ -0,0 +1,551 @@ +/* shmbutil.h -- utility functions for multibyte characters. */ + +/* Copyright (C) 2002-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_SH_MBUTIL_H_) +#define _SH_MBUTIL_H_ + +#include "stdc.h" + +/* Include config.h for HANDLE_MULTIBYTE */ +#include + +#if defined (HANDLE_MULTIBYTE) +#include "shmbchar.h" + +extern size_t xwcsrtombs PARAMS((char *, const wchar_t **, size_t, mbstate_t *)); +extern size_t xmbsrtowcs PARAMS((wchar_t *, const char **, size_t, mbstate_t *)); +extern size_t xdupmbstowcs PARAMS((wchar_t **, char ***, const char *)); + +extern size_t mbstrlen PARAMS((const char *)); + +extern char *xstrchr PARAMS((const char *, int)); + +extern int locale_mb_cur_max; /* XXX */ +extern int locale_utf8locale; /* XXX */ + +#ifndef MB_INVALIDCH +#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2) +#define MB_NULLWCH(x) ((x) == 0) +#endif + +#define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0) +#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s)) + +#define MBLEN(s, n) ((MB_CUR_MAX > 1) ? mblen ((s), (n)) : 1) +#define MBRLEN(s, n, p) ((MB_CUR_MAX > 1) ? mbrlen ((s), (n), (p)) : 1) + +#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0) +#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0) +#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80) + +#else /* !HANDLE_MULTIBYTE */ + +#undef MB_LEN_MAX +#undef MB_CUR_MAX + +#define MB_LEN_MAX 1 +#define MB_CUR_MAX 1 + +#undef xstrchr +#define xstrchr(s, c) strchr(s, c) + +#ifndef MB_INVALIDCH +#define MB_INVALIDCH(x) (0) +#define MB_NULLWCH(x) (0) +#endif + +#define MB_STRLEN(s) (STRLEN(s)) + +#define MBLEN(s, n) 1 +#define MBRLEN(s, n, p) 1 + +#ifndef wchar_t +# define wchar_t int +#endif + +#define UTF8_SINGLEBYTE(c) (1) +#define UTF8_MBFIRSTCHAR(c) (0) + +#endif /* !HANDLE_MULTIBYTE */ + +/* Declare and initialize a multibyte state. Call must be terminated + with `;'. */ +#if defined (HANDLE_MULTIBYTE) +# define DECLARE_MBSTATE \ + mbstate_t state; \ + memset (&state, '\0', sizeof (mbstate_t)) +#else +# define DECLARE_MBSTATE +#endif /* !HANDLE_MULTIBYTE */ + +/* Initialize or reinitialize a multibyte state named `state'. Call must be + terminated with `;'. */ +#if defined (HANDLE_MULTIBYTE) +# define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t)) +#else +# define INITIALIZE_MBSTATE +#endif /* !HANDLE_MULTIBYTE */ + +/* Advance one (possibly multi-byte) character in string _STR of length + _STRSIZE, starting at index _I. STATE must have already been declared. */ +#if defined (HANDLE_MULTIBYTE) +# define ADVANCE_CHAR(_str, _strsize, _i) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _f; \ +\ + _f = is_basic ((_str)[_i]); \ + if (_f) \ + mblength = 1; \ + else if (locale_utf8locale && (((_str)[_i] & 0x80) == 0)) \ + mblength = (_str)[_i] != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \ + } \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + (_i)++; \ + } \ + else if (mblength == 0) \ + (_i)++; \ + else \ + (_i) += mblength; \ + } \ + else \ + (_i)++; \ + } \ + while (0) +#else +# define ADVANCE_CHAR(_str, _strsize, _i) (_i)++ +#endif /* !HANDLE_MULTIBYTE */ + +/* Advance one (possibly multibyte) character in the string _STR of length + _STRSIZE. + SPECIAL: assume that _STR will be incremented by 1 after this call. */ +#if defined (HANDLE_MULTIBYTE) +# define ADVANCE_CHAR_P(_str, _strsize) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _f; \ +\ + _f = is_basic (*(_str)); \ + if (_f) \ + mblength = 1; \ + else if (locale_utf8locale && ((*(_str) & 0x80) == 0)) \ + mblength = *(_str) != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_str), (_strsize), &state); \ + } \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + (_str) += (mblength < 1) ? 0 : (mblength - 1); \ + } \ + } \ + while (0) +#else +# define ADVANCE_CHAR_P(_str, _strsize) +#endif /* !HANDLE_MULTIBYTE */ + +/* Back up one (possibly multi-byte) character in string _STR of length + _STRSIZE, starting at index _I. STATE must have already been declared. */ +#if defined (HANDLE_MULTIBYTE) +# define BACKUP_CHAR(_str, _strsize, _i) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _x, _p; /* _x == temp index into string, _p == prev index */ \ +\ + _x = _p = 0; \ + while (_x < (_i)) \ + { \ + state_bak = state; \ + mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + _x++; \ + } \ + else if (mblength == 0) \ + _x++; \ + else \ + { \ + _p = _x; /* _p == start of prev mbchar */ \ + _x += mblength; \ + } \ + } \ + (_i) = _p; \ + } \ + else \ + (_i)--; \ + } \ + while (0) +#else +# define BACKUP_CHAR(_str, _strsize, _i) (_i)-- +#endif /* !HANDLE_MULTIBYTE */ + +/* Back up one (possibly multibyte) character in the string _BASE of length + _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ). + SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */ +#if defined (HANDLE_MULTIBYTE) +# define BACKUP_CHAR_P(_base, _strsize, _str) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \ +\ + _x = _p = _base; \ + while (_x < (_str)) \ + { \ + state_bak = state; \ + mblength = mbrlen (_x, (_strsize) - _x, &state); \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + _x++; \ + } \ + else if (mblength == 0) \ + _x++; \ + else \ + { \ + _p = _x; /* _p == start of prev mbchar */ \ + _x += mblength; \ + } \ + } \ + (_str) = _p; \ + } \ + else \ + (_str)--; \ + } \ + while (0) +#else +# define BACKUP_CHAR_P(_base, _strsize, _str) (_str)-- +#endif /* !HANDLE_MULTIBYTE */ + +/* Copy a single character from the string _SRC to the string _DST. + _SRCEND is a pointer to the end of _SRC. */ +#if defined (HANDLE_MULTIBYTE) +# define COPY_CHAR_P(_dst, _src, _srcend) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _k; \ +\ + _k = is_basic (*(_src)); \ + if (_k) \ + mblength = 1; \ + else if (locale_utf8locale && ((*(_src) & 0x80) == 0)) \ + mblength = *(_src) != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src), (_srcend) - (_src), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + for (_k = 0; _k < mblength; _k++) \ + *(_dst)++ = *(_src)++; \ + } \ + else \ + *(_dst)++ = *(_src)++; \ + } \ + while (0) +#else +# define COPY_CHAR_P(_dst, _src, _srcend) *(_dst)++ = *(_src)++ +#endif /* !HANDLE_MULTIBYTE */ + +/* Copy a single character from the string _SRC at index _SI to the string + _DST at index _DI. _SRCEND is a pointer to the end of _SRC. */ +#if defined (HANDLE_MULTIBYTE) +# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _k; \ +\ + _k = is_basic (*((_src) + (_si))); \ + if (_k) \ + mblength = 1; \ + else \ + {\ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + for (_k = 0; _k < mblength; _k++) \ + _dst[_di++] = _src[_si++]; \ + } \ + else \ + _dst[_di++] = _src[_si++]; \ + } \ + while (0) +#else +# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) _dst[_di++] = _src[_si++] +#endif /* !HANDLE_MULTIBYTE */ + +/**************************************************************** + * * + * The following are only guaranteed to work in subst.c * + * * + ****************************************************************/ + +#if defined (HANDLE_MULTIBYTE) +# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _i; \ +\ + _i = is_basic (*((_src) + (_si))); \ + if (_i) \ + mblength = 1; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + temp = xmalloc (mblength + 2); \ + temp[0] = _escchar; \ + for (_i = 0; _i < mblength; _i++) \ + temp[_i + 1] = _src[_si++]; \ + temp[mblength + 1] = '\0'; \ +\ + goto add_string; \ + } \ + else \ + { \ + _dst[0] = _escchar; \ + _dst[1] = _sc; \ + } \ + } \ + while (0) +#else +# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \ + _dst[0] = _escchar; \ + _dst[1] = _sc +#endif /* !HANDLE_MULTIBYTE */ + +#if defined (HANDLE_MULTIBYTE) +# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _i; \ +\ + _i = is_basic (*((_src) + (_si))); \ + if (_i) \ + mblength = 1; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + FASTCOPY(((_src) + (_si)), (_dst), mblength); \ +\ + (_dst) += mblength; \ + (_si) += mblength; \ + } \ + else \ + { \ + *(_dst)++ = _src[(_si)]; \ + (_si)++; \ + } \ + } \ + while (0) +#else +# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \ + *(_dst)++ = _src[(_si)]; \ + (_si)++ +#endif /* !HANDLE_MULTIBYTE */ + +#if HANDLE_MULTIBYTE +# define SADD_MBCHAR(_dst, _src, _si, _srcsize) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + int i; \ + mbstate_t state_bak; \ + size_t mblength; \ +\ + i = is_basic (*((_src) + (_si))); \ + if (i) \ + mblength = 1; \ + else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ + mblength = (_src)[_si] != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ + } \ + if (mblength == (size_t)-1 || mblength == (size_t)-2) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + if (mblength < 1) \ + mblength = 1; \ +\ + _dst = (char *)xmalloc (mblength + 1); \ + for (i = 0; i < mblength; i++) \ + (_dst)[i] = (_src)[(_si)++]; \ + (_dst)[mblength] = '\0'; \ +\ + goto add_string; \ + } \ + } \ + while (0) + +#else +# define SADD_MBCHAR(_dst, _src, _si, _srcsize) +#endif + +/* Watch out when using this -- it's just straight textual substitution */ +#if defined (HANDLE_MULTIBYTE) +# define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \ +\ + int i; \ + mbstate_t state_bak; \ + size_t mblength; \ +\ + i = is_basic (*((_src) + (_si))); \ + if (i) \ + mblength = 1; \ + else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ + mblength = (_src)[_si] != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ + } \ + if (mblength == (size_t)-1 || mblength == (size_t)-2) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + if (mblength < 1) \ + mblength = 1; \ +\ + (_dst) = (char *)xmalloc (mblength + 2); \ + (_dst)[0] = CTLESC; \ + for (i = 0; i < mblength; i++) \ + (_dst)[i+1] = (_src)[(_si)++]; \ + (_dst)[mblength+1] = '\0'; \ +\ + goto add_string + +# define SADD_MBCHAR_BODY(_dst, _src, _si, _srcsize) \ +\ + int i; \ + mbstate_t state_bak; \ + size_t mblength; \ +\ + i = is_basic (*((_src) + (_si))); \ + if (i) \ + mblength = 1; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ + } \ + if (mblength == (size_t)-1 || mblength == (size_t)-2) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + if (mblength < 1) \ + mblength = 1; \ +\ + (_dst) = (char *)xmalloc (mblength + 1); \ + for (i = 0; i < mblength; i++) \ + (_dst)[i+1] = (_src)[(_si)++]; \ + (_dst)[mblength+1] = '\0'; \ +\ + goto add_string + +#endif /* HANDLE_MULTIBYTE */ +#endif /* _SH_MBUTIL_H_ */ diff --git a/utshell-0.5.0/lib/include/shtty.h b/utshell-0.5.0/lib/include/shtty.h new file mode 100644 index 00000000..fdf379b8 --- /dev/null +++ b/utshell-0.5.0/lib/include/shtty.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. */ + +/* This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* + * shtty.h -- include the correct system-dependent files to manipulate the + * tty + */ + +#ifndef __SH_TTY_H_ +#define __SH_TTY_H_ + +#include "stdc.h" + +#if defined (_POSIX_VERSION) && defined (HAVE_TERMIOS_H) && defined (HAVE_TCGETATTR) && !defined (TERMIOS_MISSING) +# define TERMIOS_TTY_DRIVER +#else +# if defined (HAVE_TERMIO_H) +# define TERMIO_TTY_DRIVER +# else +# define NEW_TTY_DRIVER +# endif +#endif + +/* + * The _POSIX_SOURCE define is to avoid multiple symbol definitions + * between sys/ioctl.h and termios.h. Ditto for the test against SunOS4 + * and the undefining of several symbols. + */ + +#ifdef TERMIOS_TTY_DRIVER +# if (defined (SunOS4) || defined (SunOS5)) && !defined (_POSIX_SOURCE) +# define _POSIX_SOURCE +# endif +# if defined (SunOS4) +# undef ECHO +# undef NOFLSH +# undef TOSTOP +# endif /* SunOS4 */ +# include +# define TTYSTRUCT struct termios +#else +# ifdef TERMIO_TTY_DRIVER +# include +# define TTYSTRUCT struct termio +# else /* NEW_TTY_DRIVER */ +# include +# define TTYSTRUCT struct sgttyb +# endif +#endif + +/* Functions imported from lib/sh/shtty.c */ + +/* Get and set terminal attributes for the file descriptor passed as + an argument. */ +extern int ttgetattr PARAMS((int, TTYSTRUCT *)); +extern int ttsetattr PARAMS((int, TTYSTRUCT *)); + +/* Save and restore the terminal's attributes from static storage. */ +extern void ttsave PARAMS((void)); +extern void ttrestore PARAMS((void)); + +/* Return the attributes corresponding to the file descriptor (0 or 1) + passed as an argument. */ +extern TTYSTRUCT *ttattr PARAMS((int)); + +/* These functions only operate on the passed TTYSTRUCT; they don't + actually change anything with the kernel's current tty settings. */ +extern int tt_setonechar PARAMS((TTYSTRUCT *)); +extern int tt_setnoecho PARAMS((TTYSTRUCT *)); +extern int tt_seteightbit PARAMS((TTYSTRUCT *)); +extern int tt_setnocanon PARAMS((TTYSTRUCT *)); +extern int tt_setcbreak PARAMS((TTYSTRUCT *)); + +/* These functions are all generally mutually exclusive. If you call + more than one (bracketed with calls to ttsave and ttrestore, of + course), the right thing will happen, but more system calls will be + executed than absolutely necessary. You can do all of this yourself + with the other functions; these are only conveniences. */ + +/* These functions work with a given file descriptor and set terminal + attributes */ +extern int ttfd_onechar PARAMS((int, TTYSTRUCT *)); +extern int ttfd_noecho PARAMS((int, TTYSTRUCT *)); +extern int ttfd_eightbit PARAMS((int, TTYSTRUCT *)); +extern int ttfd_nocanon PARAMS((int, TTYSTRUCT *)); + +extern int ttfd_cbreak PARAMS((int, TTYSTRUCT *)); + +/* These functions work with fd 0 and the TTYSTRUCT saved with ttsave () */ +extern int ttonechar PARAMS((void)); +extern int ttnoecho PARAMS((void)); +extern int tteightbit PARAMS((void)); +extern int ttnocanon PARAMS((void)); + +extern int ttcbreak PARAMS((void)); + +#endif diff --git a/utshell-0.5.0/lib/include/sig.h b/utshell-0.5.0/lib/include/sig.h new file mode 100644 index 00000000..4f90a889 --- /dev/null +++ b/utshell-0.5.0/lib/include/sig.h @@ -0,0 +1,141 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* sig.h -- header file for signal handler definitions. */ + +/* Copyright (C) 1994-2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Make sure that this is included *after* config.h! */ + +#if !defined (_SIG_H_) +# define _SIG_H_ + +#include "stdc.h" + +#include /* for sig_atomic_t */ + +#if !defined (SIGABRT) && defined (SIGIOT) +# define SIGABRT SIGIOT +#endif + +#define sighandler RETSIGTYPE +typedef RETSIGTYPE SigHandler PARAMS((int)); + +#if defined (VOID_SIGHANDLER) +# define SIGRETURN(n) return +#else +# define SIGRETURN(n) return(n) +#endif /* !VOID_SIGHANDLER */ + +/* Here is a definition for set_signal_handler () which simply expands to + a call to signal () for non-Posix systems. The code for set_signal_handler + in the Posix case resides in general.c. */ +#if !defined (HAVE_POSIX_SIGNALS) +# define set_signal_handler(sig, handler) (SigHandler *)signal (sig, handler) +#else +extern SigHandler *set_signal_handler PARAMS((int, SigHandler *)); /* in sig.c */ +#endif /* _POSIX_VERSION */ + +#if !defined (SIGCHLD) && defined (SIGCLD) +# define SIGCHLD SIGCLD +#endif + +#if !defined (HAVE_POSIX_SIGNALS) && !defined (sigmask) +# define sigmask(x) (1 << ((x)-1)) +#endif /* !HAVE_POSIX_SIGNALS && !sigmask */ + +#if !defined (HAVE_POSIX_SIGNALS) +# if !defined (SIG_BLOCK) +# define SIG_BLOCK 2 +# define SIG_SETMASK 3 +# endif /* SIG_BLOCK */ + +/* sigset_t defined in config.h */ + +/* Make sure there is nothing inside the signal set. */ +# define sigemptyset(set) (*(set) = 0) + +/* Initialize the signal set to hold all signals. */ +# define sigfillset(set) (*set) = sigmask (NSIG) - 1 + +/* Add SIG to the contents of SET. */ +# define sigaddset(set, sig) *(set) |= sigmask (sig) + +/* Delete SIG from signal set SET. */ +# define sigdelset(set, sig) *(set) &= ~sigmask (sig) + +/* Is SIG a member of the signal set SET? */ +# define sigismember(set, sig) ((*(set) & sigmask (sig)) != 0) + +/* Suspend the process until the reception of one of the signals + not present in SET. */ +# define sigsuspend(set) sigpause (*(set)) +#endif /* !HAVE_POSIX_SIGNALS */ + +/* These definitions are used both in POSIX and non-POSIX implementations. */ + +#define BLOCK_SIGNAL(sig, nvar, ovar) \ +do { \ + sigemptyset (&nvar); \ + sigaddset (&nvar, sig); \ + sigemptyset (&ovar); \ + sigprocmask (SIG_BLOCK, &nvar, &ovar); \ +} while (0) + +#define UNBLOCK_SIGNAL(ovar) sigprocmask (SIG_SETMASK, &ovar, (sigset_t *) NULL) + +#if defined (HAVE_POSIX_SIGNALS) +# define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar) +# define UNBLOCK_CHILD(ovar) UNBLOCK_SIGNAL(ovar) +#else /* !HAVE_POSIX_SIGNALS */ +# define BLOCK_CHILD(nvar, ovar) ovar = sigblock (sigmask (SIGCHLD)) +# define UNBLOCK_CHILD(ovar) sigsetmask (ovar) +#endif /* !HAVE_POSIX_SIGNALS */ + +/* Extern variables */ +extern volatile sig_atomic_t sigwinch_received; +extern volatile sig_atomic_t sigterm_received; + +extern int interrupt_immediately; /* no longer used */ +extern int terminate_immediately; + +/* Functions from sig.c. */ +extern sighandler termsig_sighandler PARAMS((int)); +extern void termsig_handler PARAMS((int)); +extern sighandler sigint_sighandler PARAMS((int)); +extern void initialize_signals PARAMS((int)); +extern void initialize_terminating_signals PARAMS((void)); +extern void reset_terminating_signals PARAMS((void)); +extern void top_level_cleanup PARAMS((void)); +extern void throw_to_top_level PARAMS((void)); +extern void jump_to_top_level PARAMS((int)) __attribute__((__noreturn__)); +extern void restore_sigmask PARAMS((void)); + +extern sighandler sigwinch_sighandler PARAMS((int)); +extern void set_sigwinch_handler PARAMS((void)); +extern void unset_sigwinch_handler PARAMS((void)); + +extern sighandler sigterm_sighandler PARAMS((int)); + +/* Functions defined in trap.c. */ +extern SigHandler *set_sigint_handler PARAMS((void)); +extern SigHandler *trap_to_sighandler PARAMS((int)); +extern sighandler trap_handler PARAMS((int)); + +extern int block_trapped_signals PARAMS((sigset_t *, sigset_t *)); +extern int unblock_trapped_signals PARAMS((sigset_t *)); +#endif /* _SIG_H_ */ diff --git a/utshell-0.5.0/lib/include/stat-time.h b/utshell-0.5.0/lib/include/stat-time.h new file mode 100644 index 00000000..e04cc619 --- /dev/null +++ b/utshell-0.5.0/lib/include/stat-time.h @@ -0,0 +1,214 @@ +/* stat-related time functions. + + Copyright (C) 2005, 2007, 2009-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert. */ + +#ifndef STAT_TIME_H +#define STAT_TIME_H 1 + +#include + +#if defined (TIME_H_DEFINES_STRUCT_TIMESPEC) +# include +#elif defined (SYS_TIME_H_DEFINES_STRUCT_TIMESPEC) +# include +#elif defined (PTHREAD_H_DEFINES_STRUCT_TIMESPEC) +# include +#endif + +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec +{ + time_t tv_sec; + long int tv_nsec; +}; +#endif + +/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type + struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST, + ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST, + if available. ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim + for access, status change, data modification, or birth (creation) + time respectively. + + These macros are private to stat-time.h. */ +#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC +# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC +# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim) +# else +# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec) +# endif +#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC +# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec) +#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC +# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec) +#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC +# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec) +#endif + +/* Return the nanosecond component of *ST's access time. */ +static inline long int +get_stat_atime_ns (struct stat const *st) +{ +# if defined STAT_TIMESPEC + return STAT_TIMESPEC (st, st_atim).tv_nsec; +# elif defined STAT_TIMESPEC_NS + return STAT_TIMESPEC_NS (st, st_atim); +# else + return 0; +# endif +} + +/* Return the nanosecond component of *ST's status change time. */ +static inline long int +get_stat_ctime_ns (struct stat const *st) +{ +# if defined STAT_TIMESPEC + return STAT_TIMESPEC (st, st_ctim).tv_nsec; +# elif defined STAT_TIMESPEC_NS + return STAT_TIMESPEC_NS (st, st_ctim); +# else + return 0; +# endif +} + +/* Return the nanosecond component of *ST's data modification time. */ +static inline long int +get_stat_mtime_ns (struct stat const *st) +{ +# if defined STAT_TIMESPEC + return STAT_TIMESPEC (st, st_mtim).tv_nsec; +# elif defined STAT_TIMESPEC_NS + return STAT_TIMESPEC_NS (st, st_mtim); +# else + return 0; +# endif +} + +/* Return the nanosecond component of *ST's birth time. */ +static inline long int +get_stat_birthtime_ns (struct stat const *st) +{ +# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC + return STAT_TIMESPEC (st, st_birthtim).tv_nsec; +# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC + return STAT_TIMESPEC_NS (st, st_birthtim); +# else + /* Avoid a "parameter unused" warning. */ + (void) st; + return 0; +# endif +} + +/* Return *ST's access time. */ +static inline struct timespec +get_stat_atime (struct stat const *st) +{ +#ifdef STAT_TIMESPEC + return STAT_TIMESPEC (st, st_atim); +#else + struct timespec t; + t.tv_sec = st->st_atime; + t.tv_nsec = get_stat_atime_ns (st); + return t; +#endif +} + +/* Return *ST's status change time. */ +static inline struct timespec +get_stat_ctime (struct stat const *st) +{ +#ifdef STAT_TIMESPEC + return STAT_TIMESPEC (st, st_ctim); +#else + struct timespec t; + t.tv_sec = st->st_ctime; + t.tv_nsec = get_stat_ctime_ns (st); + return t; +#endif +} + +/* Return *ST's data modification time. */ +static inline struct timespec +get_stat_mtime (struct stat const *st) +{ +#ifdef STAT_TIMESPEC + return STAT_TIMESPEC (st, st_mtim); +#else + struct timespec t; + t.tv_sec = st->st_mtime; + t.tv_nsec = get_stat_mtime_ns (st); + return t; +#endif +} + +static inline int +timespec_cmp (struct timespec a, struct timespec b) +{ + return (a.tv_sec < b.tv_sec + ? -1 + : (a.tv_sec > b.tv_sec + ? 1 + : (int) (a.tv_nsec - b.tv_nsec))); +} + +/* Return *ST's birth time, if available; otherwise return a value + with tv_sec and tv_nsec both equal to -1. */ +static inline struct timespec +get_stat_birthtime (struct stat const *st) +{ + struct timespec t; + +#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ + || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) + t = STAT_TIMESPEC (st, st_birthtim); +#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC + t.tv_sec = st->st_birthtime; + t.tv_nsec = st->st_birthtimensec; +#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* Native Windows platforms (but not Cygwin) put the "file creation + time" in st_ctime (!). See + . */ + t.tv_sec = st->st_ctime; + t.tv_nsec = 0; +#else + /* Birth time is not supported. */ + t.tv_sec = -1; + t.tv_nsec = -1; + /* Avoid a "parameter unused" warning. */ + (void) st; +#endif + +#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ + || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \ + || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) + /* FreeBSD and NetBSD sometimes signal the absence of knowledge by + using zero. Attempt to work around this problem. Alas, this can + report failure even for valid time stamps. Also, NetBSD + sometimes returns junk in the birth time fields; work around this + bug if it is detected. */ + if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) + { + t.tv_sec = -1; + t.tv_nsec = -1; + } +#endif + + return t; +} + +#endif diff --git a/utshell-0.5.0/lib/include/stdc.h b/utshell-0.5.0/lib/include/stdc.h new file mode 100644 index 00000000..7b9282cc --- /dev/null +++ b/utshell-0.5.0/lib/include/stdc.h @@ -0,0 +1,89 @@ +/* stdc.h -- macros to make source compile on both ANSI C and K&R C + compilers. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_STDC_H_) +#define _STDC_H_ + +/* Adapted from BSD /usr/include/sys/cdefs.h. */ + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +/* Fortify, at least, has trouble with this definition */ +#if defined (HAVE_STRINGIZE) +# define CPP_STRING(x) #x +#else +# define CPP_STRING(x) "x" +#endif + +#if !defined (__STDC__) + +#if defined (__GNUC__) /* gcc with -traditional */ +# if !defined (signed) +# define signed __signed +# endif +# if !defined (volatile) +# define volatile __volatile +# endif +#else /* !__GNUC__ */ +# if !defined (inline) +# define inline +# endif +# if !defined (signed) +# define signed +# endif +# if !defined (volatile) +# define volatile +# endif +#endif /* !__GNUC__ */ + +#endif /* !__STDC__ */ + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(x) +# endif +#endif + +/* For those situations when gcc handles inlining a particular function but + other compilers complain. */ +#ifdef __GNUC__ +# define INLINE inline +#else +# define INLINE +#endif + +#if defined (PREFER_STDARG) +# define SH_VA_START(va, arg) va_start(va, arg) +#else +# define SH_VA_START(va, arg) va_start(va) +#endif + +#endif /* !_STDC_H_ */ diff --git a/utshell-0.5.0/lib/include/strmatch.h b/utshell-0.5.0/lib/include/strmatch.h new file mode 100644 index 00000000..fa7be7bb --- /dev/null +++ b/utshell-0.5.0/lib/include/strmatch.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _STRMATCH_H +#define _STRMATCH_H 1 + +#include + +#include "stdc.h" + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `strmatch'. */ + +/* standard flags are like fnmatch(3). */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +/* extended flags not available in most libc fnmatch versions, but we undef + them to avoid any possible warnings. */ +#undef FNM_LEADING_DIR +#undef FNM_CASEFOLD +#undef FNM_EXTMATCH + +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ + +#define FNM_FIRSTCHAR (1 << 6) /* Match only the first character */ + +/* Value returned by `strmatch' if STRING does not match PATTERN. */ +#undef FNM_NOMATCH + +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int strmatch PARAMS((char *, char *, int)); + +#if HANDLE_MULTIBYTE +extern int wcsmatch PARAMS((wchar_t *, wchar_t *, int)); +#endif + +#endif /* _STRMATCH_H */ diff --git a/utshell-0.5.0/lib/include/subst.h b/utshell-0.5.0/lib/include/subst.h new file mode 100644 index 00000000..838ee1e6 --- /dev/null +++ b/utshell-0.5.0/lib/include/subst.h @@ -0,0 +1,355 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* subst.h -- Names of externally visible functions in subst.c. */ + +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_SUBST_H_) +#define _SUBST_H_ + +#include "stdc.h" + +/* Constants which specify how to handle backslashes and quoting in + expand_word_internal (). Q_DOUBLE_QUOTES means to use the function + slashify_in_quotes () to decide whether the backslash should be + retained. Q_HERE_DOCUMENT means slashify_in_here_document () to + decide whether to retain the backslash. Q_KEEP_BACKSLASH means + to unconditionally retain the backslash. Q_PATQUOTE means that we're + expanding a pattern ${var%#[#%]pattern} in an expansion surrounded + by double quotes. Q_DOLBRACE means we are expanding a ${...} word, so + backslashes should also escape { and } and be removed. */ +#define Q_DOUBLE_QUOTES 0x001 +#define Q_HERE_DOCUMENT 0x002 +#define Q_KEEP_BACKSLASH 0x004 +#define Q_PATQUOTE 0x008 +#define Q_QUOTED 0x010 +#define Q_ADDEDQUOTES 0x020 +#define Q_QUOTEDNULL 0x040 +#define Q_DOLBRACE 0x080 +#define Q_ARITH 0x100 /* expanding string for arithmetic evaluation */ +#define Q_ARRAYSUB 0x200 /* expanding indexed array subscript */ + +/* Flag values controlling how assignment statements are treated. */ +#define ASS_APPEND 0x0001 +#define ASS_MKLOCAL 0x0002 +#define ASS_MKASSOC 0x0004 +#define ASS_MKGLOBAL 0x0008 /* force global assignment */ +#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */ +#define ASS_FORCE 0x0020 /* force assignment even to readonly variable */ +#define ASS_CHKLOCAL 0x0040 /* check local variable before assignment */ +#define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */ +#define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */ +#define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */ +#define ASS_NOINVIS 0x0400 /* don't resolve local invisible variables */ + +/* Flags for the string extraction functions. */ +#define SX_NOALLOC 0x0001 /* just skip; don't return substring */ +#define SX_VARNAME 0x0002 /* variable name; for string_extract () */ +#define SX_REQMATCH 0x0004 /* closing/matching delimiter required */ +#define SX_COMMAND 0x0008 /* extracting a shell script/command */ +#define SX_NOCTLESC 0x0010 /* don't honor CTLESC quoting */ +#define SX_NOESCCTLNUL 0x0020 /* don't let CTLESC quote CTLNUL */ +#define SX_NOLONGJMP 0x0040 /* don't longjmp on fatal error */ +#define SX_ARITHSUB 0x0080 /* extracting $(( ... )) (currently unused) */ +#define SX_POSIXEXP 0x0100 /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */ +#define SX_WORD 0x0200 /* extracting word in ${param op word} */ +#define SX_COMPLETE 0x0400 /* extracting word for completion */ +#define SX_STRIPDQ 0x0800 /* strip double quotes when extracting double-quoted string */ + +/* Remove backslashes which are quoting backquotes from STRING. Modifies + STRING, and returns a pointer to it. */ +extern char * de_backslash PARAMS((char *)); + +/* Replace instances of \! in a string with !. */ +extern void unquote_bang PARAMS((char *)); + +/* Extract the $( construct in STRING, and return a new string. + Start extracting at (SINDEX) as if we had just seen "$(". + Make (SINDEX) get the position just after the matching ")". + XFLAGS is additional flags to pass to other extraction functions, */ +extern char *extract_command_subst PARAMS((char *, int *, int)); + +/* Extract the $[ construct in STRING, and return a new string. + Start extracting at (SINDEX) as if we had just seen "$[". + Make (SINDEX) get the position just after the matching "]". */ +extern char *extract_arithmetic_subst PARAMS((char *, int *)); + +#if defined (PROCESS_SUBSTITUTION) +/* Extract the <( or >( construct in STRING, and return a new string. + Start extracting at (SINDEX) as if we had just seen "<(". + Make (SINDEX) get the position just after the matching ")". */ +extern char *extract_process_subst PARAMS((char *, char *, int *, int)); +#endif /* PROCESS_SUBSTITUTION */ + +/* Extract the name of the variable to bind to from the assignment string. */ +extern char *assignment_name PARAMS((char *)); + +/* Return a single string of all the words present in LIST, separating + each word with SEP. */ +extern char *string_list_internal PARAMS((WORD_LIST *, char *)); + +/* Return a single string of all the words present in LIST, separating + each word with a space. */ +extern char *string_list PARAMS((WORD_LIST *)); + +/* Turn $* into a single string, obeying POSIX rules. */ +extern char *string_list_dollar_star PARAMS((WORD_LIST *, int, int)); + +/* Expand $@ into a single string, obeying POSIX rules. */ +extern char *string_list_dollar_at PARAMS((WORD_LIST *, int, int)); + +/* Turn the positional parameters into a string, understanding quoting and + the various subtleties of using the first character of $IFS as the + separator. Calls string_list_dollar_at, string_list_dollar_star, and + string_list as appropriate. */ +extern char *string_list_pos_params PARAMS((int, WORD_LIST *, int, int)); + +/* Perform quoted null character removal on each element of LIST. + This modifies LIST. */ +extern void word_list_remove_quoted_nulls PARAMS((WORD_LIST *)); + +/* This performs word splitting and quoted null character removal on + STRING. */ +extern WORD_LIST *list_string PARAMS((char *, char *, int)); + +extern char *ifs_firstchar PARAMS((int *)); +extern char *get_word_from_string PARAMS((char **, char *, char **)); +extern char *strip_trailing_ifs_whitespace PARAMS((char *, char *, int)); + +/* Given STRING, an assignment string, get the value of the right side + of the `=', and bind it to the left side. If EXPAND is true, then + perform tilde expansion, parameter expansion, command substitution, + and arithmetic expansion on the right-hand side. Do not perform word + splitting on the result of expansion. */ +extern int do_assignment PARAMS((char *)); +extern int do_assignment_no_expand PARAMS((char *)); +extern int do_word_assignment PARAMS((WORD_DESC *, int)); + +/* Append SOURCE to TARGET at INDEX. SIZE is the current amount + of space allocated to TARGET. SOURCE can be NULL, in which + case nothing happens. Gets rid of SOURCE by free ()ing it. + Returns TARGET in case the location has changed. */ +extern char *sub_append_string PARAMS((char *, char *, int *, size_t *)); + +/* Append the textual representation of NUMBER to TARGET. + INDEX and SIZE are as in SUB_APPEND_STRING. */ +extern char *sub_append_number PARAMS((intmax_t, char *, int *, int *)); + +/* Return the word list that corresponds to `$*'. */ +extern WORD_LIST *list_rest_of_args PARAMS((void)); + +/* Make a single large string out of the dollar digit variables, + and the rest_of_args. If DOLLAR_STAR is 1, then obey the special + case of "$*" with respect to IFS. */ +extern char *string_rest_of_args PARAMS((int)); + +/* Expand STRING by performing parameter expansion, command substitution, + and arithmetic expansion. Dequote the resulting WORD_LIST before + returning it, but do not perform word splitting. The call to + remove_quoted_nulls () is made here because word splitting normally + takes care of quote removal. */ +extern WORD_LIST *expand_string_unsplit PARAMS((char *, int)); + +/* Expand the rhs of an assignment statement. */ +extern WORD_LIST *expand_string_assignment PARAMS((char *, int)); + +/* Expand a prompt string. */ +extern WORD_LIST *expand_prompt_string PARAMS((char *, int, int)); + +/* Expand STRING just as if you were expanding a word. This also returns + a list of words. Note that filename globbing is *NOT* done for word + or string expansion, just when the shell is expanding a command. This + does parameter expansion, command substitution, arithmetic expansion, + and word splitting. Dequote the resultant WORD_LIST before returning. */ +extern WORD_LIST *expand_string PARAMS((char *, int)); + +/* Convenience functions that expand strings to strings, taking care of + converting the WORD_LIST * returned by the expand_string* functions + to a string and deallocating the WORD_LIST *. */ +extern char *expand_string_to_string PARAMS((char *, int)); +extern char *expand_string_unsplit_to_string PARAMS((char *, int)); +extern char *expand_assignment_string_to_string PARAMS((char *, int)); + +/* Expand an arithmetic expression string */ +extern char *expand_arith_string PARAMS((char *, int)); + +/* De-quote quoted characters in STRING. */ +extern char *dequote_string PARAMS((char *)); + +/* De-quote CTLESC-escaped CTLESC or CTLNUL characters in STRING. */ +extern char *dequote_escapes PARAMS((const char *)); + +extern WORD_DESC *dequote_word PARAMS((WORD_DESC *)); + +/* De-quote quoted characters in each word in LIST. */ +extern WORD_LIST *dequote_list PARAMS((WORD_LIST *)); + +/* Expand WORD, performing word splitting on the result. This does + parameter expansion, command substitution, arithmetic expansion, + word splitting, and quote removal. */ +extern WORD_LIST *expand_word PARAMS((WORD_DESC *, int)); + +/* Expand WORD, but do not perform word splitting on the result. This + does parameter expansion, command substitution, arithmetic expansion, + and quote removal. */ +extern WORD_LIST *expand_word_unsplit PARAMS((WORD_DESC *, int)); +extern WORD_LIST *expand_word_leave_quoted PARAMS((WORD_DESC *, int)); + +/* Return the value of a positional parameter. This handles values > 10. */ +extern char *get_dollar_var_value PARAMS((intmax_t)); + +/* Quote a string to protect it from word splitting. */ +extern char *quote_string PARAMS((char *)); + +/* Quote escape characters (characters special to internals of expansion) + in a string. */ +extern char *quote_escapes PARAMS((const char *)); + +/* And remove such quoted special characters. */ +extern char *remove_quoted_escapes PARAMS((char *)); + +/* Remove CTLNUL characters from STRING unless they are quoted with CTLESC. */ +extern char *remove_quoted_nulls PARAMS((char *)); + +/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the + backslash quoting rules for within double quotes. */ +extern char *string_quote_removal PARAMS((char *, int)); + +/* Perform quote removal on word WORD. This allocates and returns a new + WORD_DESC *. */ +extern WORD_DESC *word_quote_removal PARAMS((WORD_DESC *, int)); + +/* Perform quote removal on all words in LIST. If QUOTED is non-zero, + the members of the list are treated as if they are surrounded by + double quotes. Return a new list, or NULL if LIST is NULL. */ +extern WORD_LIST *word_list_quote_removal PARAMS((WORD_LIST *, int)); + +/* Called when IFS is changed to maintain some private variables. */ +extern void setifs PARAMS((SHELL_VAR *)); + +/* Return the value of $IFS, or " \t\n" if IFS is unset. */ +extern char *getifs PARAMS((void)); + +/* This splits a single word into a WORD LIST on $IFS, but only if the word + is not quoted. list_string () performs quote removal for us, even if we + don't do any splitting. */ +extern WORD_LIST *word_split PARAMS((WORD_DESC *, char *)); + +/* Take the list of words in LIST and do the various substitutions. Return + a new list of words which is the expanded list, and without things like + variable assignments. */ +extern WORD_LIST *expand_words PARAMS((WORD_LIST *)); + +/* Same as expand_words (), but doesn't hack variable or environment + variables. */ +extern WORD_LIST *expand_words_no_vars PARAMS((WORD_LIST *)); + +/* Perform the `normal shell expansions' on a WORD_LIST. These are + brace expansion, tilde expansion, parameter and variable substitution, + command substitution, arithmetic expansion, and word splitting. */ +extern WORD_LIST *expand_words_shellexp PARAMS((WORD_LIST *)); + +extern WORD_DESC *command_substitute PARAMS((char *, int, int)); +extern char *pat_subst PARAMS((char *, char *, char *, int)); + +#if defined (PROCESS_SUBSTITUTION) +extern int fifos_pending PARAMS((void)); +extern int num_fifos PARAMS((void)); +extern void unlink_fifo_list PARAMS((void)); +extern void unlink_all_fifos PARAMS((void)); +extern void unlink_fifo PARAMS((int)); + +extern void *copy_fifo_list PARAMS((int *)); +extern void close_new_fifos PARAMS((void *, int)); + +extern void clear_fifo_list PARAMS((void)); + +extern int find_procsub_child PARAMS((pid_t)); +extern void set_procsub_status PARAMS((int, pid_t, int)); + +extern void wait_procsubs PARAMS((void)); +extern void reap_procsubs PARAMS((void)); +#endif + +extern WORD_LIST *list_string_with_quotes PARAMS((char *)); + +#if defined (ARRAY_VARS) +extern char *extract_array_assignment_list PARAMS((char *, int *)); +#endif + +#if defined (COND_COMMAND) +extern char *remove_backslashes PARAMS((char *)); +extern char *cond_expand_word PARAMS((WORD_DESC *, int)); +#endif + +/* Flags for skip_to_delim */ +#define SD_NOJMP 0x001 /* don't longjmp on fatal error. */ +#define SD_INVERT 0x002 /* look for chars NOT in passed set */ +#define SD_NOQUOTEDELIM 0x004 /* don't let single or double quotes act as delimiters */ +#define SD_NOSKIPCMD 0x008 /* don't skip over $(, <(, or >( command/process substitution; parse them as commands */ +#define SD_EXTGLOB 0x010 /* skip over extended globbing patterns if appropriate */ +#define SD_IGNOREQUOTE 0x020 /* single and double quotes are not special */ +#define SD_GLOB 0x040 /* skip over glob patterns like bracket expressions */ +#define SD_NOPROCSUB 0x080 /* don't parse process substitutions as commands */ +#define SD_COMPLETE 0x100 /* skip_to_delim during completion */ +#define SD_HISTEXP 0x200 /* skip_to_delim during history expansion */ +#define SD_ARITHEXP 0x400 /* skip_to_delim during arithmetic expansion */ + +extern int skip_to_delim PARAMS((char *, int, char *, int)); + +#if defined (BANG_HISTORY) +extern int skip_to_histexp PARAMS((char *, int, char *, int)); +#endif + +#if defined (READLINE) +extern int char_is_quoted PARAMS((char *, int)); +extern int unclosed_pair PARAMS((char *, int, char *)); +extern WORD_LIST *split_at_delims PARAMS((char *, int, char *, int, int, int *, int *)); +#endif + +/* Variables used to keep track of the characters in IFS. */ +extern SHELL_VAR *ifs_var; +extern char *ifs_value; +extern unsigned char ifs_cmap[]; +extern int ifs_is_set, ifs_is_null; + +#if defined (HANDLE_MULTIBYTE) +extern unsigned char ifs_firstc[]; +extern size_t ifs_firstc_len; +#else +extern unsigned char ifs_firstc; +#endif + +extern int assigning_in_environment; +extern int expanding_redir; +extern int inherit_errexit; + +extern pid_t last_command_subst_pid; + +/* Evaluates to 1 if C is a character in $IFS. */ +#define isifs(c) (ifs_cmap[(unsigned char)(c)] != 0) + +/* How to determine the quoted state of the character C. */ +#define QUOTED_CHAR(c) ((c) == CTLESC) + +/* Is the first character of STRING a quoted NULL character? */ +#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0') + +extern void invalidate_cached_quoted_dollar_at PARAMS((void)); + +#endif /* !_SUBST_H_ */ diff --git a/utshell-0.5.0/lib/include/syntax.h b/utshell-0.5.0/lib/include/syntax.h new file mode 100644 index 00000000..5d9eedd0 --- /dev/null +++ b/utshell-0.5.0/lib/include/syntax.h @@ -0,0 +1,107 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* syntax.h -- Syntax definitions for the shell */ + +/* Copyright (C) 2000, 2001, 2005, 2008, 2009-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _SYNTAX_H_ +#define _SYNTAX_H_ + +/* Defines for use by mksyntax.c */ + +#define slashify_in_quotes "\\`$\"\n" +#define slashify_in_here_document "\\`$" + +#define shell_meta_chars "()<>;&|" +#define shell_break_chars "()<>;&| \t\n" + +#define shell_quote_chars "\"`'" + +#if defined (PROCESS_SUBSTITUTION) +# define shell_exp_chars "$<>" +#else +# define shell_exp_chars "$" +#endif + +#if defined (EXTENDED_GLOB) +# define ext_glob_chars "@*+?!" +#else +# define ext_glob_chars "" +#endif +#define shell_glob_chars "*?[]^" + +/* Defines shared by mksyntax.c and the rest of the shell code. */ + +/* Values for character flags in syntax tables */ + +#define CWORD 0x0000 /* nothing special; an ordinary character */ +#define CSHMETA 0x0001 /* shell meta character */ +#define CSHBRK 0x0002 /* shell break character */ +#define CBACKQ 0x0004 /* back quote */ +#define CQUOTE 0x0008 /* shell quote character */ +#define CSPECL 0x0010 /* special character that needs quoting */ +#define CEXP 0x0020 /* shell expansion character */ +#define CBSDQUOTE 0x0040 /* characters escaped by backslash in double quotes */ +#define CBSHDOC 0x0080 /* characters escaped by backslash in here doc */ +#define CGLOB 0x0100 /* globbing characters */ +#define CXGLOB 0x0200 /* extended globbing characters */ +#define CXQUOTE 0x0400 /* cquote + backslash */ +#define CSPECVAR 0x0800 /* single-character shell variable name */ +#define CSUBSTOP 0x1000 /* values of OP for ${word[:]OPstuff} */ +#define CBLANK 0x2000 /* whitespace (blank) character */ + +/* Defines for use by the rest of the shell. */ +extern int sh_syntaxtab[]; +extern int sh_syntabsiz; + +#define shellmeta(c) (sh_syntaxtab[(unsigned char)(c)] & CSHMETA) +#define shellbreak(c) (sh_syntaxtab[(unsigned char)(c)] & CSHBRK) +#define shellquote(c) (sh_syntaxtab[(unsigned char)(c)] & CQUOTE) +#define shellxquote(c) (sh_syntaxtab[(unsigned char)(c)] & CXQUOTE) + +#define shellblank(c) (sh_syntaxtab[(unsigned char)(c)] & CBLANK) + +#define parserblank(c) ((c) == ' ' || (c) == '\t') + +#define issyntype(c, t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) != 0) +#define notsyntype(c,t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) == 0) + +#if defined (PROCESS_SUBSTITUTION) +# define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>') +#else +# define shellexp(c) ((c) == '$') +#endif + +#if defined (EXTENDED_GLOB) +# define PATTERN_CHAR(c) \ + ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!') +#else +# define PATTERN_CHAR(c) 0 +#endif + +#define GLOB_CHAR(c) \ + ((c) == '*' || (c) == '?' || (c) == '[' || (c) == ']' || (c) == '^') + +#define CTLESC '\001' +#define CTLNUL '\177' + +#if !defined (HAVE_ISBLANK) && !defined (isblank) +# define isblank(x) ((x) == ' ' || (x) == '\t') +#endif + +#endif /* _SYNTAX_H_ */ diff --git a/utshell-0.5.0/lib/include/systimes.h b/utshell-0.5.0/lib/include/systimes.h new file mode 100644 index 00000000..aefcab7f --- /dev/null +++ b/utshell-0.5.0/lib/include/systimes.h @@ -0,0 +1,55 @@ +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* + * POSIX Standard: 4.5.2 Process Times + */ + +/* + * If we don't have a standard system clock_t type, this must be included + * after config.h + */ + +#ifndef _BASH_SYSTIMES_H +#define _BASH_SYSTIMES_H 1 + +#if defined (HAVE_SYS_TIMES_H) +# include +#else /* !HAVE_SYS_TIMES_H */ + +#include + +/* Structure describing CPU time used by a process and its children. */ +struct tms + { + clock_t tms_utime; /* User CPU time. */ + clock_t tms_stime; /* System CPU time. */ + + clock_t tms_cutime; /* User CPU time of dead children. */ + clock_t tms_cstime; /* System CPU time of dead children. */ + }; + +/* Store the CPU time used by this process and all its + dead descendants in BUFFER. + Return the elapsed real time from an arbitrary point in the + past (the bash emulation uses the epoch), or (clock_t) -1 for + errors. All times are in CLK_TCKths of a second. */ +extern clock_t times PARAMS((struct tms *buffer)); + +#endif /* !HAVE_SYS_TIMES_H */ +#endif /* _BASH_SYSTIMES_H */ diff --git a/utshell-0.5.0/lib/include/tilde.h b/utshell-0.5.0/lib/include/tilde.h new file mode 100644 index 00000000..e26dd047 --- /dev/null +++ b/utshell-0.5.0/lib/include/tilde.h @@ -0,0 +1,80 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992-2009 Free Software Foundation, Inc. + + This file contains the Readline Library (Readline), a set of + routines for providing Emacs style line input to programs that ask + for it. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +/* Find the portion of the string beginning with ~ that should be expanded. */ +extern char *tilde_find_word PARAMS((const char *, int, int *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/utshell-0.5.0/lib/include/trap.h b/utshell-0.5.0/lib/include/trap.h new file mode 100644 index 00000000..3ed96502 --- /dev/null +++ b/utshell-0.5.0/lib/include/trap.h @@ -0,0 +1,129 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* trap.h -- data structures used in the trap mechanism. */ + +/* Copyright (C) 1993-2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_TRAP_H_) +#define _TRAP_H_ + +#include "stdc.h" + +#if !defined (SIG_DFL) +#include "bashtypes.h" +#include +#endif /* SIG_DFL */ + +#if !defined (NSIG) +#define NSIG 64 +#endif /* !NSIG */ + +#define NO_SIG -1 +#define DEFAULT_SIG SIG_DFL +#define IGNORE_SIG SIG_IGN + +/* Special shell trap names. */ +#define DEBUG_TRAP NSIG +#define ERROR_TRAP NSIG+1 +#define RETURN_TRAP NSIG+2 +#define EXIT_TRAP 0 + +/* system signals plus special bash traps */ +#define BASH_NSIG NSIG+3 + +/* Flags values for decode_signal() */ +#define DSIG_SIGPREFIX 0x01 /* don't allow `SIG' PREFIX */ +#define DSIG_NOCASE 0x02 /* case-insensitive comparison */ + +/* A value which can never be the target of a trap handler. */ +#define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps + +#define signal_object_p(x,f) (decode_signal (x,f) != NO_SIG) + +#define TRAP_STRING(s) \ + (signal_is_trapped (s) && signal_is_ignored (s) == 0) ? trap_list[s] \ + : (char *)NULL + +extern char *trap_list[]; + +extern int trapped_signal_received; +extern int wait_signal_received; +extern int running_trap; +extern int trap_saved_exit_value; +extern int suppress_debug_trap_verbose; + +/* Externally-visible functions declared in trap.c. */ +extern void initialize_traps PARAMS((void)); + +extern void run_pending_traps PARAMS((void)); + +extern void queue_sigchld_trap PARAMS((int)); +extern void maybe_set_sigchld_trap PARAMS((char *)); +extern void set_impossible_sigchld_trap PARAMS((void)); +extern void set_sigchld_trap PARAMS((char *)); + +extern void set_debug_trap PARAMS((char *)); +extern void set_error_trap PARAMS((char *)); +extern void set_return_trap PARAMS((char *)); + +extern void maybe_set_debug_trap PARAMS((char *)); +extern void maybe_set_error_trap PARAMS((char *)); +extern void maybe_set_return_trap PARAMS((char *)); + +extern void set_sigint_trap PARAMS((char *)); +extern void set_signal PARAMS((int, char *)); + +extern void restore_default_signal PARAMS((int)); +extern void ignore_signal PARAMS((int)); +extern int run_exit_trap PARAMS((void)); +extern void run_trap_cleanup PARAMS((int)); +extern int run_debug_trap PARAMS((void)); +extern void run_error_trap PARAMS((void)); +extern void run_return_trap PARAMS((void)); + +extern void free_trap_strings PARAMS((void)); +extern void reset_signal_handlers PARAMS((void)); +extern void restore_original_signals PARAMS((void)); + +extern void get_original_signal PARAMS((int)); +extern void get_all_original_signals PARAMS((void)); + +extern char *signal_name PARAMS((int)); + +extern int decode_signal PARAMS((char *, int)); +extern void run_interrupt_trap PARAMS((int)); +extern int maybe_call_trap_handler PARAMS((int)); +extern int signal_is_special PARAMS((int)); +extern int signal_is_trapped PARAMS((int)); +extern int signal_is_pending PARAMS((int)); +extern int signal_is_ignored PARAMS((int)); +extern int signal_is_hard_ignored PARAMS((int)); +extern void set_signal_hard_ignored PARAMS((int)); +extern void set_signal_ignored PARAMS((int)); +extern int signal_in_progress PARAMS((int)); + +extern void set_trap_state PARAMS((int)); + +extern int next_pending_trap PARAMS((int)); +extern int first_pending_trap PARAMS((void)); +extern void clear_pending_traps PARAMS((void)); +extern int any_signals_trapped PARAMS((void)); +extern void check_signals PARAMS((void)); +extern void check_signals_and_traps PARAMS((void)); + +#endif /* _TRAP_H_ */ diff --git a/utshell-0.5.0/lib/include/typemax.h b/utshell-0.5.0/lib/include/typemax.h new file mode 100644 index 00000000..9f6732ee --- /dev/null +++ b/utshell-0.5.0/lib/include/typemax.h @@ -0,0 +1,131 @@ +/* typemax.h -- encapsulate max values for long, long long, etc. */ + +/* Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* + * NOTE: This should be included after config.h, limits.h, stdint.h, and + * inttypes.h + */ + +#ifndef _SH_TYPEMAX_H +#define _SH_TYPEMAX_H + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#ifndef TYPE_SIGNED +# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +#endif + +#ifndef TYPE_SIGNED_MAGNITUDE +# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) +#endif + +#ifndef TYPE_WIDTH +# define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) +#endif + +#ifndef TYPE_MINIMUM +# define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) +#endif + +#ifndef TYPE_MAXIMUM +# define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) //01111111 +#endif + +#ifdef HAVE_LONG_LONG +# ifndef LLONG_MAX +# define LLONG_MAX TYPE_MAXIMUM(long long int) +# define LLONG_MIN TYPE_MINIMUM(long long int) +# endif +# ifndef ULLONG_MAX +# define ULLONG_MAX TYPE_MAXIMUM(unsigned long long int) +# endif +#endif + +#ifndef ULONG_MAX +# define ULONG_MAX ((unsigned long) ~(unsigned long) 0) +#endif + +#ifndef LONG_MAX +# define LONG_MAX ((long int) (ULONG_MAX >> 1)) +# define LONG_MIN ((long int) (-LONG_MAX - 1L)) +#endif + +#ifndef INT_MAX /* ouch */ +# define INT_MAX TYPE_MAXIMUM(int) +# define INT_MIN TYPE_MINIMUM(int) +# define UINT_MAX ((unsigned int) ~(unsigned int)0) +#endif + +/* workaround for gcc bug in versions < 2.7 */ +#if defined (HAVE_LONG_LONG) && __GNUC__ == 2 && __GNUC_MINOR__ < 7 +static const unsigned long long int maxquad = ULLONG_MAX; +# undef ULLONG_MAX +# define ULLONG_MAX maxquad +#endif + +#if !defined (INTMAX_MAX) || !defined (INTMAX_MIN) + +#if SIZEOF_INTMAX_T == SIZEOF_LONG_LONG +# define INTMAX_MAX LLONG_MAX +# define INTMAX_MIN LLONG_MIN +#elif SIZEOF_INTMAX_T == SIZEOF_LONG +# define INTMAX_MAX LONG_MAX +# define INTMAX_MIN LONG_MIN +#else +# define INTMAX_MAX INT_MAX +# define INTMAX_MIN INT_MIN +#endif + +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX 32767 /* POSIX minimum max */ +#endif + +#ifndef SIZE_MAX +# define SIZE_MAX 65535 /* POSIX minimum max */ +#endif + +#ifndef sh_imaxabs +# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x)) +#endif + +/* Handle signed arithmetic overflow and underflow. Have to do it this way + to avoid compilers optimizing out simpler overflow checks. */ + +/* Make sure that a+b does not exceed MAXV or is smaller than MINV (if b < 0). + Assumes that b > 0 if a > 0 and b < 0 if a < 0 */ +#define ADDOVERFLOW(a,b,minv,maxv) \ + ((((a) > 0) && ((b) > ((maxv) - (a)))) || \ + (((a) < 0) && ((b) < ((minv) - (a))))) + +/* Make sure that a-b is not smaller than MINV or exceeds MAXV (if b < 0). + Assumes that b > 0 if a > 0 and b < 0 if a < 0 */ +#define SUBOVERFLOW(a,b,minv,maxv) \ + ((((b) > 0) && ((a) < ((minv) + (b)))) || \ + (((b) < 0) && ((a) > ((maxv) + (b))))) + +#endif /* _SH_TYPEMAX_H */ diff --git a/utshell-0.5.0/lib/include/unionwait.h b/utshell-0.5.0/lib/include/unionwait.h new file mode 100644 index 00000000..b1b4dfaf --- /dev/null +++ b/utshell-0.5.0/lib/include/unionwait.h @@ -0,0 +1,98 @@ +/* unionwait.h -- definitions for using a `union wait' on systems without + one. */ + +/* Copyright (C) 1996 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _UNIONWAIT_H +#define _UNIONWAIT_H + +#if !defined (WORDS_BIGENDIAN) +union wait + { + int w_status; /* used in syscall */ + + /* Terminated process status. */ + struct + { + unsigned short + w_Termsig : 7, /* termination signal */ + w_Coredump : 1, /* core dump indicator */ + w_Retcode : 8, /* exit code if w_termsig==0 */ + w_Fill1 : 16; /* high 16 bits unused */ + } w_T; + + /* Stopped process status. Returned + only for traced children unless requested + with the WUNTRACED option bit. */ + struct + { + unsigned short + w_Stopval : 8, /* == W_STOPPED if stopped */ + w_Stopsig : 8, /* actually zero on XENIX */ + w_Fill2 : 16; /* high 16 bits unused */ + } w_S; + }; + +#else /* WORDS_BIGENDIAN */ + +/* This is for big-endian machines like the IBM RT, HP 9000, or Sun-3 */ + +union wait + { + int w_status; /* used in syscall */ + + /* Terminated process status. */ + struct + { + unsigned short w_Fill1 : 16; /* high 16 bits unused */ + unsigned w_Retcode : 8; /* exit code if w_termsig==0 */ + unsigned w_Coredump : 1; /* core dump indicator */ + unsigned w_Termsig : 7; /* termination signal */ + } w_T; + + /* Stopped process status. Returned + only for traced children unless requested + with the WUNTRACED option bit. */ + struct + { + unsigned short w_Fill2 : 16; /* high 16 bits unused */ + unsigned w_Stopsig : 8; /* signal that stopped us */ + unsigned w_Stopval : 8; /* == W_STOPPED if stopped */ + } w_S; + }; + +#endif /* WORDS_BIGENDIAN */ + +#define w_termsig w_T.w_Termsig +#define w_coredump w_T.w_Coredump +#define w_retcode w_T.w_Retcode +#define w_stopval w_S.w_Stopval +#define w_stopsig w_S.w_Stopsig + +#define WSTOPPED 0177 +#define WIFSTOPPED(x) ((x).w_stopval == WSTOPPED) +#define WIFEXITED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig == 0) +#define WIFSIGNALED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig != 0) + +#define WTERMSIG(x) ((x).w_termsig) +#define WSTOPSIG(x) ((x).w_stopsig) +#define WEXITSTATUS(x) ((x).w_retcode) +#define WIFCORED(x) ((x).w_coredump) + +#endif /* _UNIONWAIT_H */ diff --git a/utshell-0.5.0/lib/include/unwind_prot.h b/utshell-0.5.0/lib/include/unwind_prot.h new file mode 100644 index 00000000..db3e4eba --- /dev/null +++ b/utshell-0.5.0/lib/include/unwind_prot.h @@ -0,0 +1,53 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* unwind_prot.h - Macros and functions for hacking unwind protection. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_UNWIND_PROT_H) +#define _UNWIND_PROT_H + +extern void uwp_init PARAMS((void)); + +/* Run a function without interrupts. */ +extern void begin_unwind_frame PARAMS((char *)); +extern void discard_unwind_frame PARAMS((char *)); +extern void run_unwind_frame PARAMS((char *)); +extern void add_unwind_protect (); /* Not portable to arbitrary C99 hosts. */ +extern void remove_unwind_protect PARAMS((void)); +extern void run_unwind_protects PARAMS((void)); +extern void clear_unwind_protect_list PARAMS((int)); +extern int have_unwind_protects PARAMS((void)); +extern int unwind_protect_tag_on_stack PARAMS((const char *)); +extern void uwp_init PARAMS((void)); + +/* Define for people who like their code to look a certain way. */ +#define end_unwind_frame() + +/* How to protect a variable. */ +#define unwind_protect_var(X) unwind_protect_mem ((char *)&(X), sizeof (X)) +extern void unwind_protect_mem PARAMS((char *, int)); + +/* Backwards compatibility */ +#define unwind_protect_int unwind_protect_var +#define unwind_protect_short unwind_protect_var +#define unwind_protect_string unwind_protect_var +#define unwind_protect_pointer unwind_protect_var +#define unwind_protect_jmp_buf unwind_protect_var + +#endif /* _UNWIND_PROT_H */ diff --git a/utshell-0.5.0/lib/include/variables.h b/utshell-0.5.0/lib/include/variables.h new file mode 100644 index 00000000..d7074e40 --- /dev/null +++ b/utshell-0.5.0/lib/include/variables.h @@ -0,0 +1,459 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* variables.h -- data structures for shell variables. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_VARIABLES_H_) +#define _VARIABLES_H_ + +#include "stdc.h" +#include "array.h" +#include "assoc.h" + +/* Shell variables and functions are stored in hash tables. */ +#include "hashlib.h" + +#include "conftypes.h" + +/* A variable context. */ +typedef struct var_context { + char *name; /* empty or NULL means global context */ + int scope; /* 0 means global context */ + int flags; + struct var_context *up; /* previous function calls */ + struct var_context *down; /* down towards global context */ + HASH_TABLE *table; /* variables at this scope */ +} VAR_CONTEXT; + +/* Flags for var_context->flags */ +#define VC_HASLOCAL 0x01 +#define VC_HASTMPVAR 0x02 +#define VC_FUNCENV 0x04 /* also function if name != NULL */ +#define VC_BLTNENV 0x08 /* builtin_env */ +#define VC_TEMPENV 0x10 /* temporary_env */ + +#define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV) + +/* Accessing macros */ +#define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0) +#define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0) +#define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV) + +#define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0) + +#define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0) +#define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0) + +/* What a shell variable looks like. */ + +typedef struct variable *sh_var_value_func_t PARAMS((struct variable *)); +typedef struct variable *sh_var_assign_func_t PARAMS((struct variable *, char *, arrayind_t, char *)); + +/* For the future */ +union _value { + char *s; /* string value */ + intmax_t i; /* int value */ + COMMAND *f; /* function */ + ARRAY *a; /* array */ + HASH_TABLE *h; /* associative array */ + double d; /* floating point number */ +#if defined (HAVE_LONG_DOUBLE) + long double ld; /* long double */ +#endif + struct variable *v; /* possible indirect variable use */ + void *opaque; /* opaque data for future use */ +}; + +typedef struct variable { + char *name; /* Symbol that the user types. */ + char *value; /* Value that is returned. */ + char *exportstr; /* String for the environment. */ + sh_var_value_func_t *dynamic_value; /* Function called to return a `dynamic' + value for a variable, like $SECONDS + or $RANDOM. */ + sh_var_assign_func_t *assign_func; /* Function called when this `special + variable' is assigned a value in + bind_variable. */ + int attributes; /* export, readonly, array, invisible... */ + int context; /* Which context this variable belongs to. */ +} SHELL_VAR; + +typedef struct _vlist { + SHELL_VAR **list; + size_t list_size; /* allocated size */ + size_t list_len; /* current number of entries */ +} VARLIST; + +/* The various attributes that a given variable can have. */ +/* First, the user-visible attributes */ +#define att_exported 0x0000001 /* export to environment */ +#define att_readonly 0x0000002 /* cannot change */ +#define att_array 0x0000004 /* value is an array */ +#define att_function 0x0000008 /* value is a function */ +#define att_integer 0x0000010 /* internal representation is int */ +#define att_local 0x0000020 /* variable is local to a function */ +#define att_assoc 0x0000040 /* variable is an associative array */ +#define att_trace 0x0000080 /* function is traced with DEBUG trap */ +#define att_uppercase 0x0000100 /* word converted to uppercase on assignment */ +#define att_lowercase 0x0000200 /* word converted to lowercase on assignment */ +#define att_capcase 0x0000400 /* word capitalized on assignment */ +#define att_nameref 0x0000800 /* word is a name reference */ + +#define user_attrs (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase|att_nameref) + +#define attmask_user 0x0000fff + +/* Internal attributes used for bookkeeping */ +#define att_invisible 0x0001000 /* cannot see */ +#define att_nounset 0x0002000 /* cannot unset */ +#define att_noassign 0x0004000 /* assignment not allowed */ +#define att_imported 0x0008000 /* came from environment */ +#define att_special 0x0010000 /* requires special handling */ +#define att_nofree 0x0020000 /* do not free value on unset */ +#define att_regenerate 0x0040000 /* regenerate when exported */ + +#define attmask_int 0x00ff000 + +/* Internal attributes used for variable scoping. */ +#define att_tempvar 0x0100000 /* variable came from the temp environment */ +#define att_propagate 0x0200000 /* propagate to previous scope */ + +#define attmask_scope 0x0f00000 + +#define exported_p(var) ((((var)->attributes) & (att_exported))) +#define readonly_p(var) ((((var)->attributes) & (att_readonly))) +#define array_p(var) ((((var)->attributes) & (att_array))) +#define function_p(var) ((((var)->attributes) & (att_function))) +#define integer_p(var) ((((var)->attributes) & (att_integer))) +#define local_p(var) ((((var)->attributes) & (att_local))) +#define assoc_p(var) ((((var)->attributes) & (att_assoc))) +#define trace_p(var) ((((var)->attributes) & (att_trace))) +#define uppercase_p(var) ((((var)->attributes) & (att_uppercase))) +#define lowercase_p(var) ((((var)->attributes) & (att_lowercase))) +#define capcase_p(var) ((((var)->attributes) & (att_capcase))) +#define nameref_p(var) ((((var)->attributes) & (att_nameref))) + +#define invisible_p(var) ((((var)->attributes) & (att_invisible))) +#define non_unsettable_p(var) ((((var)->attributes) & (att_nounset))) +#define noassign_p(var) ((((var)->attributes) & (att_noassign))) +#define imported_p(var) ((((var)->attributes) & (att_imported))) +#define specialvar_p(var) ((((var)->attributes) & (att_special))) +#define nofree_p(var) ((((var)->attributes) & (att_nofree))) +#define regen_p(var) ((((var)->attributes) & (att_regenerate))) + +#define tempvar_p(var) ((((var)->attributes) & (att_tempvar))) +#define propagate_p(var) ((((var)->attributes) & (att_propagate))) + +/* Variable names: lvalues */ +#define name_cell(var) ((var)->name) + +/* Accessing variable values: rvalues */ +#define value_cell(var) ((var)->value) +#define function_cell(var) (COMMAND *)((var)->value) +#define array_cell(var) (ARRAY *)((var)->value) +#define assoc_cell(var) (HASH_TABLE *)((var)->value) +#define nameref_cell(var) ((var)->value) /* so it can change later */ + +#define NAMEREF_MAX 8 /* only 8 levels of nameref indirection */ + +#define var_isset(var) ((var)->value != 0) +#define var_isunset(var) ((var)->value == 0) +#define var_isnull(var) ((var)->value && *(var)->value == 0) + +/* Assigning variable values: lvalues */ +#define var_setvalue(var, str) ((var)->value = (str)) +#define var_setfunc(var, func) ((var)->value = (char *)(func)) +#define var_setarray(var, arr) ((var)->value = (char *)(arr)) +#define var_setassoc(var, arr) ((var)->value = (char *)(arr)) +#define var_setref(var, str) ((var)->value = (str)) + +/* Make VAR be auto-exported. */ +#define set_auto_export(var) \ + do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0) + +#define SETVARATTR(var, attr, undo) \ + ((undo == 0) ? ((var)->attributes |= (attr)) \ + : ((var)->attributes &= ~(attr))) + +#define VSETATTR(var, attr) ((var)->attributes |= (attr)) +#define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr)) + +#define VGETFLAGS(var) ((var)->attributes) + +#define VSETFLAGS(var, flags) ((var)->attributes = (flags)) +#define VCLRFLAGS(var) ((var)->attributes = 0) + +/* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */ +#define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL +#define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL +#define SET_EXPORTSTR(var, value) (var)->exportstr = (value) +#define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL + +#define FREE_EXPORTSTR(var) \ + do { if ((var)->exportstr) free ((var)->exportstr); } while (0) + +#define CACHE_IMPORTSTR(var, value) \ + (var)->exportstr = savestring (value) + +#define INVALIDATE_EXPORTSTR(var) \ + do { \ + if ((var)->exportstr) \ + { \ + free ((var)->exportstr); \ + (var)->exportstr = (char *)NULL; \ + } \ + } while (0) + +#define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0') + +/* Flag values for make_local_variable and its array counterparts */ +#define MKLOC_ASSOCOK 0x01 +#define MKLOC_ARRAYOK 0x02 +#define MKLOC_INHERIT 0x04 + +/* Special value for nameref with invalid value for creation or assignment */ +extern SHELL_VAR nameref_invalid_value; +#define INVALID_NAMEREF_VALUE (void *)&nameref_invalid_value + +/* Stuff for hacking variables. */ +typedef int sh_var_map_func_t PARAMS((SHELL_VAR *)); + +/* Where we keep the variables and functions */ +extern VAR_CONTEXT *global_variables; +extern VAR_CONTEXT *shell_variables; + +extern HASH_TABLE *shell_functions; +extern HASH_TABLE *temporary_env; + +extern int variable_context; +extern char *dollar_vars[]; +extern char **export_env; + +extern int tempenv_assign_error; +extern int array_needs_making; +extern int shell_level; + +/* XXX */ +extern WORD_LIST *rest_of_args; +extern int posparam_count; +extern pid_t dollar_dollar_pid; + +extern int localvar_inherit; /* declared in variables.c */ + +extern void initialize_shell_variables PARAMS((char **, int)); + +extern int validate_inherited_value PARAMS((SHELL_VAR *, int)); + +extern SHELL_VAR *set_if_not PARAMS((char *, char *)); + +extern void sh_set_lines_and_columns PARAMS((int, int)); +extern void set_pwd PARAMS((void)); +extern void set_ppid PARAMS((void)); +extern void make_funcname_visible PARAMS((int)); + +extern SHELL_VAR *var_lookup PARAMS((const char *, VAR_CONTEXT *)); + +extern SHELL_VAR *find_function PARAMS((const char *)); +extern FUNCTION_DEF *find_function_def PARAMS((const char *)); +extern SHELL_VAR *find_variable PARAMS((const char *)); +extern SHELL_VAR *find_variable_noref PARAMS((const char *)); +extern SHELL_VAR *find_variable_last_nameref PARAMS((const char *, int)); +extern SHELL_VAR *find_global_variable_last_nameref PARAMS((const char *, int)); +extern SHELL_VAR *find_variable_nameref PARAMS((SHELL_VAR *)); +extern SHELL_VAR *find_variable_nameref_for_create PARAMS((const char *, int)); +extern SHELL_VAR *find_variable_nameref_for_assignment PARAMS((const char *, int)); +/*extern SHELL_VAR *find_variable_internal PARAMS((const char *, int));*/ +extern SHELL_VAR *find_variable_tempenv PARAMS((const char *)); +extern SHELL_VAR *find_variable_notempenv PARAMS((const char *)); +extern SHELL_VAR *find_global_variable PARAMS((const char *)); +extern SHELL_VAR *find_global_variable_noref PARAMS((const char *)); +extern SHELL_VAR *find_shell_variable PARAMS((const char *)); +extern SHELL_VAR *find_tempenv_variable PARAMS((const char *)); +extern SHELL_VAR *find_variable_no_invisible PARAMS((const char *)); +extern SHELL_VAR *find_variable_for_assignment PARAMS((const char *)); +extern char *nameref_transform_name PARAMS((char *, int)); +extern SHELL_VAR *copy_variable PARAMS((SHELL_VAR *)); +extern SHELL_VAR *make_local_variable PARAMS((const char *, int)); +extern SHELL_VAR *bind_variable PARAMS((const char *, char *, int)); +extern SHELL_VAR *bind_global_variable PARAMS((const char *, char *, int)); +extern SHELL_VAR *bind_function PARAMS((const char *, COMMAND *)); + +extern void bind_function_def PARAMS((const char *, FUNCTION_DEF *, int)); + +extern SHELL_VAR **map_over PARAMS((sh_var_map_func_t *, VAR_CONTEXT *)); +SHELL_VAR **map_over_funcs PARAMS((sh_var_map_func_t *)); + +extern SHELL_VAR **all_shell_variables PARAMS((void)); +extern SHELL_VAR **all_shell_functions PARAMS((void)); +extern SHELL_VAR **all_visible_variables PARAMS((void)); +extern SHELL_VAR **all_visible_functions PARAMS((void)); +extern SHELL_VAR **all_exported_variables PARAMS((void)); +extern SHELL_VAR **local_exported_variables PARAMS((void)); +extern SHELL_VAR **all_local_variables PARAMS((int)); +#if defined (ARRAY_VARS) +extern SHELL_VAR **all_array_variables PARAMS((void)); +#endif +extern char **all_variables_matching_prefix PARAMS((const char *)); + +extern char **make_var_array PARAMS((HASH_TABLE *)); +extern char **add_or_supercede_exported_var PARAMS((char *, int)); + +extern char *get_variable_value PARAMS((SHELL_VAR *)); +extern char *get_string_value PARAMS((const char *)); +extern char *sh_get_env_value PARAMS((const char *)); +extern char *make_variable_value PARAMS((SHELL_VAR *, char *, int)); + +extern SHELL_VAR *bind_variable_value PARAMS((SHELL_VAR *, char *, int)); +extern SHELL_VAR *bind_int_variable PARAMS((char *, char *, int)); +extern SHELL_VAR *bind_var_to_int PARAMS((char *, intmax_t)); + +extern int assign_in_env PARAMS((WORD_DESC *, int)); + +extern int unbind_variable PARAMS((const char *)); +extern int check_unbind_variable PARAMS((const char *)); +extern int unbind_nameref PARAMS((const char *)); +extern int unbind_variable_noref PARAMS((const char *)); +extern int unbind_func PARAMS((const char *)); +extern int unbind_function_def PARAMS((const char *)); +extern int delete_var PARAMS((const char *, VAR_CONTEXT *)); +extern int makunbound PARAMS((const char *, VAR_CONTEXT *)); +extern int kill_local_variable PARAMS((const char *)); +extern void delete_all_variables PARAMS((HASH_TABLE *)); +extern void delete_all_contexts PARAMS((VAR_CONTEXT *)); + +extern VAR_CONTEXT *new_var_context PARAMS((char *, int)); +extern void dispose_var_context PARAMS((VAR_CONTEXT *)); +extern VAR_CONTEXT *push_var_context PARAMS((char *, int, HASH_TABLE *)); +extern void pop_var_context PARAMS((void)); +extern VAR_CONTEXT *push_scope PARAMS((int, HASH_TABLE *)); +extern void pop_scope PARAMS((int)); + +extern void clear_dollar_vars PARAMS((void)); + +extern void push_context PARAMS((char *, int, HASH_TABLE *)); +extern void pop_context PARAMS((void)); +extern void push_dollar_vars PARAMS((void)); +extern void pop_dollar_vars PARAMS((void)); +extern void dispose_saved_dollar_vars PARAMS((void)); + +extern void init_bash_argv PARAMS((void)); +extern void save_bash_argv PARAMS((void)); +extern void push_args PARAMS((WORD_LIST *)); +extern void pop_args PARAMS((void)); + +extern void adjust_shell_level PARAMS((int)); +extern void non_unsettable PARAMS((char *)); +extern void dispose_variable PARAMS((SHELL_VAR *)); +extern void dispose_used_env_vars PARAMS((void)); +extern void dispose_function_env PARAMS((void)); +extern void dispose_builtin_env PARAMS((void)); +extern void merge_temporary_env PARAMS((void)); +extern void flush_temporary_env PARAMS((void)); +extern void merge_builtin_env PARAMS((void)); +extern void kill_all_local_variables PARAMS((void)); + +extern void set_var_read_only PARAMS((char *)); +extern void set_func_read_only PARAMS((const char *)); +extern void set_var_auto_export PARAMS((char *)); +extern void set_func_auto_export PARAMS((const char *)); + +extern void sort_variables PARAMS((SHELL_VAR **)); + +extern int chkexport PARAMS((char *)); +extern void maybe_make_export_env PARAMS((void)); +extern void update_export_env_inplace PARAMS((char *, int, char *)); +extern void put_command_name_into_env PARAMS((char *)); +extern void put_gnu_argv_flags_into_env PARAMS((intmax_t, char *)); + +extern void print_var_list PARAMS((SHELL_VAR **)); +extern void print_func_list PARAMS((SHELL_VAR **)); +extern void print_assignment PARAMS((SHELL_VAR *)); +extern void print_var_value PARAMS((SHELL_VAR *, int)); +extern void print_var_function PARAMS((SHELL_VAR *)); + +#if defined (ARRAY_VARS) +extern SHELL_VAR *make_new_array_variable PARAMS((char *)); +extern SHELL_VAR *make_local_array_variable PARAMS((char *, int)); + +extern SHELL_VAR *make_new_assoc_variable PARAMS((char *)); +extern SHELL_VAR *make_local_assoc_variable PARAMS((char *, int)); + +extern void set_pipestatus_array PARAMS((int *, int)); +extern ARRAY *save_pipestatus_array PARAMS((void)); +extern void restore_pipestatus_array PARAMS((ARRAY *)); +#endif + +extern void set_pipestatus_from_exit PARAMS((int)); + +/* The variable in NAME has just had its state changed. Check to see if it + is one of the special ones where something special happens. */ +extern void stupidly_hack_special_variables PARAMS((char *)); + +/* Reinitialize some special variables that have external effects upon unset + when the shell reinitializes itself. */ +extern void reinit_special_variables PARAMS((void)); + +extern int get_random_number PARAMS((void)); + +/* The `special variable' functions that get called when a particular + variable is set. */ +extern void sv_ifs PARAMS((char *)); +extern void sv_path PARAMS((char *)); +extern void sv_mail PARAMS((char *)); +extern void sv_funcnest PARAMS((char *)); +extern void sv_execignore PARAMS((char *)); +extern void sv_globignore PARAMS((char *)); +extern void sv_ignoreeof PARAMS((char *)); +extern void sv_strict_posix PARAMS((char *)); +extern void sv_optind PARAMS((char *)); +extern void sv_opterr PARAMS((char *)); +extern void sv_locale PARAMS((char *)); +extern void sv_xtracefd PARAMS((char *)); +extern void sv_shcompat PARAMS((char *)); + +#if defined (READLINE) +extern void sv_comp_wordbreaks PARAMS((char *)); +extern void sv_terminal PARAMS((char *)); +extern void sv_hostfile PARAMS((char *)); +extern void sv_winsize PARAMS((char *)); +#endif + +#if defined (__CYGWIN__) +extern void sv_home PARAMS((char *)); +#endif + +#if defined (HISTORY) +extern void sv_histsize PARAMS((char *)); +extern void sv_histignore PARAMS((char *)); +extern void sv_history_control PARAMS((char *)); +# if defined (BANG_HISTORY) +extern void sv_histchars PARAMS((char *)); +# endif +extern void sv_histtimefmt PARAMS((char *)); +#endif /* HISTORY */ + +#if defined (HAVE_TZSET) +extern void sv_tz PARAMS((char *)); +#endif + +#if defined (JOB_CONTROL) +extern void sv_childmax PARAMS((char *)); +#endif + +#endif /* !_VARIABLES_H_ */ diff --git a/utshell-0.5.0/lib/include/xmalloc.h b/utshell-0.5.0/lib/include/xmalloc.h new file mode 100644 index 00000000..752b8b19 --- /dev/null +++ b/utshell-0.5.0/lib/include/xmalloc.h @@ -0,0 +1,67 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* xmalloc.h -- defines for the `x' memory allocation functions */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_XMALLOC_H_) +#define _XMALLOC_H_ + +#include "stdc.h" +#include "bashansi.h" + +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +/* Allocation functions in xmalloc.c */ +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); + +#if defined(USING_BASH_MALLOC) && !defined (DISABLE_MALLOC_WRAPPERS) +extern PTR_T sh_xmalloc PARAMS((size_t, const char *, int)); +extern PTR_T sh_xrealloc PARAMS((void *, size_t, const char *, int)); +extern void sh_xfree PARAMS((void *, const char *, int)); + +#define xmalloc(x) sh_xmalloc((x), __FILE__, __LINE__) +#define xrealloc(x, n) sh_xrealloc((x), (n), __FILE__, __LINE__) +#define xfree(x) sh_xfree((x), __FILE__, __LINE__) + +#ifdef free +#undef free +#endif +#define free(x) sh_xfree((x), __FILE__, __LINE__) + +extern PTR_T sh_malloc PARAMS((size_t, const char *, int)); + +#ifdef malloc +#undef malloc +#endif +#define malloc(x) sh_malloc((x), __FILE__, __LINE__) + +#endif /* USING_BASH_MALLOC */ + +#endif /* _XMALLOC_H_ */ diff --git a/utshell-0.5.0/lib/intl/ChangeLog b/utshell-0.5.0/lib/intl/ChangeLog new file mode 100644 index 00000000..eed2d21a --- /dev/null +++ b/utshell-0.5.0/lib/intl/ChangeLog @@ -0,0 +1,4 @@ +2003-05-22 GNU + + * Version 0.12.1 released. + diff --git a/utshell-0.5.0/lib/intl/Makefile b/utshell-0.5.0/lib/intl/Makefile new file mode 100644 index 00000000..a75d2d36 --- /dev/null +++ b/utshell-0.5.0/lib/intl/Makefile @@ -0,0 +1,472 @@ +# Makefile for directory with message catalog handling library of GNU gettext +# Copyright (C) 1995-1998, 2000-2003, 2008,2009 Free Software Foundation, Inc. +# + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PACKAGE = utshell +VERSION = 0.1-release + +SHELL = /bin/sh + +srcdir = . +top_srcdir = ../.. +top_builddir = /root/utshell-0.5 + + +prefix = /usr/local +exec_prefix = ${prefix} +transform = s,x,x, + +datarootdir = ${prefix}/share + +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include +datadir = ${datarootdir} +localedir = ${datarootdir}/locale + +gettextsrcdir = $(datadir)/gettext/intl +aliaspath = $(localedir) +subdir = intl + + + +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +MKINSTALLDIRS = @MKINSTALLDIRS@ +mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) + +l = + +AR = ar +CC = gcc +LIBTOOL = @LIBTOOL@ +RANLIB = ranlib +YACC = bison -y -d +YFLAGS = --name-prefix=__gettext + +ARFLAGS = cr + +LOCAL_DEFS = -DSHELL + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \ +-DLIBDIR=\"$(prefix)/libdata\" -DIN_LIBINTL \ +-DENABLE_RELOCATABLE=1 -DIN_LIBRARY -DINSTALLDIR=\"$(libdir)\" -DNO_XMALLOC \ +-Dset_relocation_prefix=libintl_set_relocation_prefix \ +-Drelocate=libintl_relocate \ +-DDEPENDS_ON_LIBICONV=1 -DHAVE_CONFIG_H ${LOCAL_DEFS} +CPPFLAGS = +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security +LDFLAGS = -L./lib/termcap +LIBS = -ldl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +HEADERS = \ + gmo.h \ + gettextP.h \ + hash-string.h \ + loadinfo.h \ + plural-exp.h \ + eval-plural.h \ + localcharset.h \ + relocatable.h \ + os2compat.h \ + libgnuintl.h.in +SOURCES = \ + bindtextdom.c \ + dcgettext.c \ + dgettext.c \ + gettext.c \ + finddomain.c \ + loadmsgcat.c \ + localealias.c \ + textdomain.c \ + l10nflist.c \ + explodename.c \ + dcigettext.c \ + dcngettext.c \ + dngettext.c \ + ngettext.c \ + plural.y \ + plural-exp.c \ + localcharset.c \ + relocatable.c \ + localename.c \ + log.c \ + osdep.c \ + os2compat.c \ + intl-compat.c +OBJECTS = \ + bindtextdom.$lo \ + dcgettext.$lo \ + dgettext.$lo \ + gettext.$lo \ + finddomain.$lo \ + loadmsgcat.$lo \ + localealias.$lo \ + textdomain.$lo \ + l10nflist.$lo \ + explodename.$lo \ + dcigettext.$lo \ + dcngettext.$lo \ + dngettext.$lo \ + ngettext.$lo \ + plural.$lo \ + plural-exp.$lo \ + localcharset.$lo \ + relocatable.$lo \ + localename.$lo \ + log.$lo \ + osdep.$lo \ + intl-compat.$lo +DISTFILES.common = Makefile.in \ +config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES) +DISTFILES.generated = plural.c +DISTFILES.normal = VERSION +DISTFILES.gettext = COPYING.LIB-2.0 COPYING.LIB-2.1 libintl.glibc \ +Makefile.vms libgnuintl.h.msvc-shared README.woe32 Makefile.msvc +DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c \ +COPYING.LIB-2 gettext.h libgettext.h plural-eval.c libgnuintl.h + +all: all-no +all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed +all-no: all-no-no +all-no-yes: libgnuintl.$la +all-no-no: + +libintl.a libgnuintl.a: $(OBJECTS) + rm -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + $(RANLIB) $@ + +libintl.la libgnuintl.la: $(OBJECTS) + $(LIBTOOL) --mode=link \ + $(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \ + $(OBJECTS) $(LIBS) \ + -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \ + -rpath $(libdir) \ + -no-undefined + +# Libtool's library version information for libintl. +# Before making a gettext release, the gettext maintainer must change this +# according to the libtool documentation, section "Library interface versions". +# Maintainers of other packages that include the intl directory must *not* +# change these values. +LTV_CURRENT=5 +LTV_REVISION=0 +LTV_AGE=3 + +.SUFFIXES: +.SUFFIXES: .c .y .o .lo .sin .sed + +.c.o: + $(COMPILE) $< + +.y.c: + $(YACC) $(YFLAGS) --output $@ $< + rm -f $*.h + +bindtextdom.lo: $(srcdir)/bindtextdom.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c +dcgettext.lo: $(srcdir)/dcgettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcgettext.c +dgettext.lo: $(srcdir)/dgettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dgettext.c +gettext.lo: $(srcdir)/gettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/gettext.c +finddomain.lo: $(srcdir)/finddomain.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/finddomain.c +loadmsgcat.lo: $(srcdir)/loadmsgcat.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c +localealias.lo: $(srcdir)/localealias.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localealias.c +textdomain.lo: $(srcdir)/textdomain.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/textdomain.c +l10nflist.lo: $(srcdir)/l10nflist.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/l10nflist.c +explodename.lo: $(srcdir)/explodename.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/explodename.c +dcigettext.lo: $(srcdir)/dcigettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcigettext.c +dcngettext.lo: $(srcdir)/dcngettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcngettext.c +dngettext.lo: $(srcdir)/dngettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dngettext.c +ngettext.lo: $(srcdir)/ngettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/ngettext.c +plural.lo: $(srcdir)/plural.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural.c +plural-exp.lo: $(srcdir)/plural-exp.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural-exp.c +localcharset.lo: $(srcdir)/localcharset.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localcharset.c +relocatable.lo: $(srcdir)/relocatable.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/relocatable.c +localename.lo: $(srcdir)/localename.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localename.c +log.lo: $(srcdir)/log.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/log.c +osdep.lo: $(srcdir)/osdep.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/osdep.c +intl-compat.lo: $(srcdir)/intl-compat.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/intl-compat.c + +ref-add.sed: $(srcdir)/ref-add.sin + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-ref-add.sed + mv t-ref-add.sed ref-add.sed +ref-del.sed: $(srcdir)/ref-del.sin + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-del.sin > t-ref-del.sed + mv t-ref-del.sed ref-del.sed + +INCLUDES = -I. -I$(srcdir) -I${top_builddir} -I${top_srcdir} + +libgnuintl.h: $(srcdir)/libgnuintl.h.in + cp $(srcdir)/libgnuintl.h.in libgnuintl.h + +libintl.h: libgnuintl.h + cmp libgnuintl.h libintl.h || cp libgnuintl.h libintl.h + +charset.alias: $(srcdir)/config.charset + $(SHELL) $(srcdir)/config.charset 'x86_64-pc-linux-gnu' > t-$@ + mv t-$@ $@ + +check: all + +# We must not install the libintl.h/libintl.a files if we are on a +# system which has the GNU gettext() function in its C library or in a +# separate library. +# If you want to use the one which comes with this version of the +# package, you have to use `configure --with-included-gettext'. +install: install-exec install-data +install-exec: all + if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ + && test 'no' = yes; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ + $(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \ + $(LIBTOOL) --mode=install \ + $(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \ + if test "@RELOCATABLE@" = yes; then \ + dependencies=`sed -n -e 's,^dependency_libs=\(.*\),\1,p' < $(DESTDIR)$(libdir)/libintl.la | sed -e "s,^',," -e "s,'\$$,,"`; \ + if test -n "$dependencies"; then \ + rm -f $(DESTDIR)$(libdir)/libintl.la; \ + fi; \ + fi; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools" \ + && test 'no' = no; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir); \ + $(LIBTOOL) --mode=install \ + $(INSTALL_DATA) libgnuintl.$la $(DESTDIR)$(libdir)/libgnuintl.$la; \ + rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ + $(INSTALL_DATA) $(DESTDIR)$(libdir)/libgnuintl.so $(DESTDIR)$(libdir)/preloadable_libintl.so; \ + $(LIBTOOL) --mode=uninstall \ + rm -f $(DESTDIR)$(libdir)/libgnuintl.$la; \ + else \ + : ; \ + fi + if test 'no' = yes; then \ + $(mkinstalldirs) $(DESTDIR)$(localedir); \ + test -f $(DESTDIR)$(localedir)/locale.alias \ + && orig=$(DESTDIR)$(localedir)/locale.alias \ + || orig=$(srcdir)/locale.alias; \ + temp=$(DESTDIR)$(localedir)/t-locale.alias; \ + dest=$(DESTDIR)$(localedir)/locale.alias; \ + sed -f ref-add.sed $$orig > $$temp; \ + $(INSTALL_DATA) $$temp $$dest; \ + rm -f $$temp; \ + else \ + : ; \ + fi +install-data: all + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ + $(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \ + $(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \ + dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \ + for file in $$dists; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \ + dists="$(DISTFILES.generated)"; \ + for file in $$dists; do \ + if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ + $(INSTALL_DATA) $$dir/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + dists="$(DISTFILES.obsolete)"; \ + for file in $$dists; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +install-strip: install + +installdirs: + if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ + && test 'no' = yes; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools" \ + && test 'no' = no; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir); \ + else \ + : ; \ + fi + if test 'no' = yes; then \ + test yes != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ + $(mkinstalldirs) $(DESTDIR)$(localedir); \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ + && test 'no' = yes; then \ + rm -f $(DESTDIR)$(includedir)/libintl.h; \ + $(LIBTOOL) --mode=uninstall \ + rm -f $(DESTDIR)$(libdir)/libintl.$la; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools" \ + && test 'no' = no; then \ + rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ + else \ + : ; \ + fi + if test 'no' = yes; then \ + if test -f $(DESTDIR)$(prefix)/libdata/charset.alias; then \ + temp=$(DESTDIR)$(prefix)/libdata/t-charset.alias; \ + dest=$(DESTDIR)$(prefix)/libdata/charset.alias; \ + sed -f ref-del.sed $$dest > $$temp; \ + if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ + rm -f $$dest; \ + else \ + $(INSTALL_DATA) $$temp $$dest; \ + fi; \ + rm -f $$temp; \ + fi; \ + if test -f $(DESTDIR)$(localedir)/locale.alias; then \ + temp=$(DESTDIR)$(localedir)/t-locale.alias; \ + dest=$(DESTDIR)$(localedir)/locale.alias; \ + sed -f ref-del.sed $$dest > $$temp; \ + if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ + rm -f $$dest; \ + else \ + $(INSTALL_DATA) $$temp $$dest; \ + fi; \ + rm -f $$temp; \ + fi; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in VERSION ChangeLog COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common) $(DISTFILES.generated); do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +info dvi ps pdf html: + +$(OBJECTS): ${top_builddir}/config.h libgnuintl.h +bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h +dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h +explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h +dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h +dcigettext.$lo: $(srcdir)/eval-plural.h +localcharset.$lo: $(srcdir)/localcharset.h +localealias.$lo localcharset.$lo relocatable.$lo: $(srcdir)/relocatable.h + +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) + +ctags: CTAGS + +CTAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && ctags -o $$here/CTAGS $(HEADERS) $(SOURCES) + +id: ID + +ID: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) + + +mostlyclean: + rm -f *.a *.la *.o *.obj *.lo core core.* + rm -f libgnuintl.h libintl.h charset.alias ref-add.sed ref-del.sed + rm -f -r .libs _libs + +clean: mostlyclean + +distclean: clean + rm -f Makefile ID TAGS + if test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; then \ + rm -f ChangeLog.inst $(DISTFILES.normal); \ + else \ + : ; \ + fi + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + + +# GNU gettext needs not contain the file `VERSION' but contains some +# other files which should not be distributed in other packages. +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: Makefile + if test "$(PACKAGE)" = "gettext-tools"; then \ + : ; \ + else \ + if test "$(PACKAGE)" = "gettext-runtime"; then \ + additional="$(DISTFILES.gettext)"; \ + else \ + additional="$(DISTFILES.normal)"; \ + fi; \ + $(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \ + for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \ + if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ + cp -p $$dir/$$file $(distdir); \ + done; \ + fi + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status +# This would be more efficient, but doesn't work any more with autoconf-2.57, +# when AC_CONFIG_FILES([intl/Makefile:somedir/Makefile.in]) is used. +# cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/utshell-0.5.0/lib/intl/Makefile.in b/utshell-0.5.0/lib/intl/Makefile.in new file mode 100644 index 00000000..00fdb612 --- /dev/null +++ b/utshell-0.5.0/lib/intl/Makefile.in @@ -0,0 +1,472 @@ +# Makefile for directory with message catalog handling library of GNU gettext +# Copyright (C) 1995-1998, 2000-2003, 2008,2009 Free Software Foundation, Inc. +# + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @BUILD_DIR@ +VPATH = $(srcdir) + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +transform = @program_transform_name@ + +datarootdir = @datarootdir@ + +libdir = @libdir@ +includedir = @includedir@ +datadir = @datadir@ +localedir = @localedir@ + +gettextsrcdir = $(datadir)/gettext/intl +aliaspath = $(localedir) +subdir = intl + +@SET_MAKE@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) + +l = @INTL_LIBTOOL_SUFFIX_PREFIX@ + +AR = @AR@ +CC = @CC@ +LIBTOOL = @LIBTOOL@ +RANLIB = @RANLIB@ +YACC = @INTLBISON@ -y -d +YFLAGS = --name-prefix=__gettext + +ARFLAGS = @ARFLAGS@ + +LOCAL_DEFS = @LOCAL_DEFS@ + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \ +-DLIBDIR=\"$(prefix)/libdata\" -DIN_LIBINTL \ +-DENABLE_RELOCATABLE=1 -DIN_LIBRARY -DINSTALLDIR=\"$(libdir)\" -DNO_XMALLOC \ +-Dset_relocation_prefix=libintl_set_relocation_prefix \ +-Drelocate=libintl_relocate \ +-DDEPENDS_ON_LIBICONV=1 @DEFS@ ${LOCAL_DEFS} +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +HEADERS = \ + gmo.h \ + gettextP.h \ + hash-string.h \ + loadinfo.h \ + plural-exp.h \ + eval-plural.h \ + localcharset.h \ + relocatable.h \ + os2compat.h \ + libgnuintl.h.in +SOURCES = \ + bindtextdom.c \ + dcgettext.c \ + dgettext.c \ + gettext.c \ + finddomain.c \ + loadmsgcat.c \ + localealias.c \ + textdomain.c \ + l10nflist.c \ + explodename.c \ + dcigettext.c \ + dcngettext.c \ + dngettext.c \ + ngettext.c \ + plural.y \ + plural-exp.c \ + localcharset.c \ + relocatable.c \ + localename.c \ + log.c \ + osdep.c \ + os2compat.c \ + intl-compat.c +OBJECTS = \ + bindtextdom.$lo \ + dcgettext.$lo \ + dgettext.$lo \ + gettext.$lo \ + finddomain.$lo \ + loadmsgcat.$lo \ + localealias.$lo \ + textdomain.$lo \ + l10nflist.$lo \ + explodename.$lo \ + dcigettext.$lo \ + dcngettext.$lo \ + dngettext.$lo \ + ngettext.$lo \ + plural.$lo \ + plural-exp.$lo \ + localcharset.$lo \ + relocatable.$lo \ + localename.$lo \ + log.$lo \ + osdep.$lo \ + intl-compat.$lo +DISTFILES.common = Makefile.in \ +config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES) +DISTFILES.generated = plural.c +DISTFILES.normal = VERSION +DISTFILES.gettext = COPYING.LIB-2.0 COPYING.LIB-2.1 libintl.glibc \ +Makefile.vms libgnuintl.h.msvc-shared README.woe32 Makefile.msvc +DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c \ +COPYING.LIB-2 gettext.h libgettext.h plural-eval.c libgnuintl.h + +all: all-@USE_INCLUDED_LIBINTL@ +all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed +all-no: all-no-@BUILD_INCLUDED_LIBINTL@ +all-no-yes: libgnuintl.$la +all-no-no: + +libintl.a libgnuintl.a: $(OBJECTS) + rm -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + $(RANLIB) $@ + +libintl.la libgnuintl.la: $(OBJECTS) + $(LIBTOOL) --mode=link \ + $(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \ + $(OBJECTS) @LTLIBICONV@ $(LIBS) \ + -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \ + -rpath $(libdir) \ + -no-undefined + +# Libtool's library version information for libintl. +# Before making a gettext release, the gettext maintainer must change this +# according to the libtool documentation, section "Library interface versions". +# Maintainers of other packages that include the intl directory must *not* +# change these values. +LTV_CURRENT=5 +LTV_REVISION=0 +LTV_AGE=3 + +.SUFFIXES: +.SUFFIXES: .c .y .o .lo .sin .sed + +.c.o: + $(COMPILE) $< + +.y.c: + $(YACC) $(YFLAGS) --output $@ $< + rm -f $*.h + +bindtextdom.lo: $(srcdir)/bindtextdom.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c +dcgettext.lo: $(srcdir)/dcgettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcgettext.c +dgettext.lo: $(srcdir)/dgettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dgettext.c +gettext.lo: $(srcdir)/gettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/gettext.c +finddomain.lo: $(srcdir)/finddomain.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/finddomain.c +loadmsgcat.lo: $(srcdir)/loadmsgcat.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c +localealias.lo: $(srcdir)/localealias.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localealias.c +textdomain.lo: $(srcdir)/textdomain.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/textdomain.c +l10nflist.lo: $(srcdir)/l10nflist.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/l10nflist.c +explodename.lo: $(srcdir)/explodename.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/explodename.c +dcigettext.lo: $(srcdir)/dcigettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcigettext.c +dcngettext.lo: $(srcdir)/dcngettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcngettext.c +dngettext.lo: $(srcdir)/dngettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dngettext.c +ngettext.lo: $(srcdir)/ngettext.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/ngettext.c +plural.lo: $(srcdir)/plural.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural.c +plural-exp.lo: $(srcdir)/plural-exp.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural-exp.c +localcharset.lo: $(srcdir)/localcharset.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localcharset.c +relocatable.lo: $(srcdir)/relocatable.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/relocatable.c +localename.lo: $(srcdir)/localename.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localename.c +log.lo: $(srcdir)/log.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/log.c +osdep.lo: $(srcdir)/osdep.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/osdep.c +intl-compat.lo: $(srcdir)/intl-compat.c + $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/intl-compat.c + +ref-add.sed: $(srcdir)/ref-add.sin + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-ref-add.sed + mv t-ref-add.sed ref-add.sed +ref-del.sed: $(srcdir)/ref-del.sin + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-del.sin > t-ref-del.sed + mv t-ref-del.sed ref-del.sed + +INCLUDES = -I. -I$(srcdir) -I${top_builddir} -I${top_srcdir} + +libgnuintl.h: $(srcdir)/libgnuintl.h.in + cp $(srcdir)/libgnuintl.h.in libgnuintl.h + +libintl.h: libgnuintl.h + cmp libgnuintl.h libintl.h || cp libgnuintl.h libintl.h + +charset.alias: $(srcdir)/config.charset + $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ + mv t-$@ $@ + +check: all + +# We must not install the libintl.h/libintl.a files if we are on a +# system which has the GNU gettext() function in its C library or in a +# separate library. +# If you want to use the one which comes with this version of the +# package, you have to use `configure --with-included-gettext'. +install: install-exec install-data +install-exec: all + if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ + && test '@USE_INCLUDED_LIBINTL@' = yes; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ + $(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \ + $(LIBTOOL) --mode=install \ + $(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \ + if test "@RELOCATABLE@" = yes; then \ + dependencies=`sed -n -e 's,^dependency_libs=\(.*\),\1,p' < $(DESTDIR)$(libdir)/libintl.la | sed -e "s,^',," -e "s,'\$$,,"`; \ + if test -n "$dependencies"; then \ + rm -f $(DESTDIR)$(libdir)/libintl.la; \ + fi; \ + fi; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools" \ + && test '@USE_INCLUDED_LIBINTL@' = no; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir); \ + $(LIBTOOL) --mode=install \ + $(INSTALL_DATA) libgnuintl.$la $(DESTDIR)$(libdir)/libgnuintl.$la; \ + rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ + $(INSTALL_DATA) $(DESTDIR)$(libdir)/libgnuintl.so $(DESTDIR)$(libdir)/preloadable_libintl.so; \ + $(LIBTOOL) --mode=uninstall \ + rm -f $(DESTDIR)$(libdir)/libgnuintl.$la; \ + else \ + : ; \ + fi + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + $(mkinstalldirs) $(DESTDIR)$(localedir); \ + test -f $(DESTDIR)$(localedir)/locale.alias \ + && orig=$(DESTDIR)$(localedir)/locale.alias \ + || orig=$(srcdir)/locale.alias; \ + temp=$(DESTDIR)$(localedir)/t-locale.alias; \ + dest=$(DESTDIR)$(localedir)/locale.alias; \ + sed -f ref-add.sed $$orig > $$temp; \ + $(INSTALL_DATA) $$temp $$dest; \ + rm -f $$temp; \ + else \ + : ; \ + fi +install-data: all + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ + $(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \ + $(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \ + dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \ + for file in $$dists; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \ + dists="$(DISTFILES.generated)"; \ + for file in $$dists; do \ + if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ + $(INSTALL_DATA) $$dir/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + dists="$(DISTFILES.obsolete)"; \ + for file in $$dists; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +install-strip: install + +installdirs: + if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ + && test '@USE_INCLUDED_LIBINTL@' = yes; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools" \ + && test '@USE_INCLUDED_LIBINTL@' = no; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir); \ + else \ + : ; \ + fi + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ + $(mkinstalldirs) $(DESTDIR)$(localedir); \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ + && test '@USE_INCLUDED_LIBINTL@' = yes; then \ + rm -f $(DESTDIR)$(includedir)/libintl.h; \ + $(LIBTOOL) --mode=uninstall \ + rm -f $(DESTDIR)$(libdir)/libintl.$la; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools" \ + && test '@USE_INCLUDED_LIBINTL@' = no; then \ + rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ + else \ + : ; \ + fi + if test '@USE_INCLUDED_LIBINTL@' = yes; then \ + if test -f $(DESTDIR)$(prefix)/libdata/charset.alias; then \ + temp=$(DESTDIR)$(prefix)/libdata/t-charset.alias; \ + dest=$(DESTDIR)$(prefix)/libdata/charset.alias; \ + sed -f ref-del.sed $$dest > $$temp; \ + if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ + rm -f $$dest; \ + else \ + $(INSTALL_DATA) $$temp $$dest; \ + fi; \ + rm -f $$temp; \ + fi; \ + if test -f $(DESTDIR)$(localedir)/locale.alias; then \ + temp=$(DESTDIR)$(localedir)/t-locale.alias; \ + dest=$(DESTDIR)$(localedir)/locale.alias; \ + sed -f ref-del.sed $$dest > $$temp; \ + if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ + rm -f $$dest; \ + else \ + $(INSTALL_DATA) $$temp $$dest; \ + fi; \ + rm -f $$temp; \ + fi; \ + else \ + : ; \ + fi + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in VERSION ChangeLog COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common) $(DISTFILES.generated); do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +info dvi ps pdf html: + +$(OBJECTS): ${top_builddir}/config.h libgnuintl.h +bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h +dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h +explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h +dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h +dcigettext.$lo: $(srcdir)/eval-plural.h +localcharset.$lo: $(srcdir)/localcharset.h +localealias.$lo localcharset.$lo relocatable.$lo: $(srcdir)/relocatable.h + +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) + +ctags: CTAGS + +CTAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && ctags -o $$here/CTAGS $(HEADERS) $(SOURCES) + +id: ID + +ID: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) + + +mostlyclean: + rm -f *.a *.la *.o *.obj *.lo core core.* + rm -f libgnuintl.h libintl.h charset.alias ref-add.sed ref-del.sed + rm -f -r .libs _libs + +clean: mostlyclean + +distclean: clean + rm -f Makefile ID TAGS + if test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; then \ + rm -f ChangeLog.inst $(DISTFILES.normal); \ + else \ + : ; \ + fi + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + + +# GNU gettext needs not contain the file `VERSION' but contains some +# other files which should not be distributed in other packages. +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: Makefile + if test "$(PACKAGE)" = "gettext-tools"; then \ + : ; \ + else \ + if test "$(PACKAGE)" = "gettext-runtime"; then \ + additional="$(DISTFILES.gettext)"; \ + else \ + additional="$(DISTFILES.normal)"; \ + fi; \ + $(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \ + for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \ + if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ + cp -p $$dir/$$file $(distdir); \ + done; \ + fi + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status +# This would be more efficient, but doesn't work any more with autoconf-2.57, +# when AC_CONFIG_FILES([intl/Makefile:somedir/Makefile.in]) is used. +# cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/utshell-0.5.0/lib/intl/VERSION b/utshell-0.5.0/lib/intl/VERSION new file mode 100644 index 00000000..13031835 --- /dev/null +++ b/utshell-0.5.0/lib/intl/VERSION @@ -0,0 +1 @@ +GNU gettext library from gettext-0.12.1 diff --git a/utshell-0.5.0/lib/intl/bindtextdom.c b/utshell-0.5.0/lib/intl/bindtextdom.c new file mode 100644 index 00000000..ef5479e3 --- /dev/null +++ b/utshell-0.5.0/lib/intl/bindtextdom.c @@ -0,0 +1,376 @@ +/* bindtextdom.c - Implementation of the bindtextdomain(3) function */ + +/* Copyright (C) 1995-1998, 2000, 2001, 2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif +#include "gettextP.h" + +#ifdef _LIBC +/* We have to handle multi-threaded applications. */ +# include +#else +/* Provide dummy implementation if this is outside glibc. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +#endif + +/* The internal variables in the standalone libintl.a must have different + names than the internal variables in GNU libc, otherwise programs + using libintl.a cannot be linked statically. */ +#if !defined _LIBC +# define _nl_default_dirname libintl_nl_default_dirname +# define _nl_domain_bindings libintl_nl_domain_bindings +#endif + +/* Some compilers, like SunOS4 cc, don't have offsetof in . */ +#ifndef offsetof +# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) +#endif + +/* @@ end of prolog @@ */ + +/* Contains the default location of the message catalogs. */ +extern const char _nl_default_dirname[]; +#ifdef _LIBC +extern const char _nl_default_dirname_internal[] attribute_hidden; +#else +# define INTUSE(name) name +#endif + +/* List with bindings of specific domains. */ +extern struct binding *_nl_domain_bindings; + +/* Lock variable to protect the global data in the gettext implementation. */ +__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define BINDTEXTDOMAIN __bindtextdomain +# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define BINDTEXTDOMAIN libintl_bindtextdomain +# define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset +#endif + +/* Prototypes for local functions. */ +static void set_binding_values PARAMS ((const char *domainname, + const char **dirnamep, + const char **codesetp)); + +/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP + to be used for the DOMAINNAME message catalog. + If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not + modified, only the current value is returned. + If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither + modified nor returned. */ +static void +set_binding_values (domainname, dirnamep, codesetp) + const char *domainname; + const char **dirnamep; + const char **codesetp; +{ + struct binding *binding; + int modified; + + /* Some sanity checks. */ + if (domainname == NULL || domainname[0] == '\0') + { + if (dirnamep) + *dirnamep = NULL; + if (codesetp) + *codesetp = NULL; + return; + } + + __libc_rwlock_wrlock (_nl_state_lock); + + modified = 0; + + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (binding != NULL) + { + if (dirnamep) + { + const char *dirname = *dirnamep; + + if (dirname == NULL) + /* The current binding has be to returned. */ + *dirnamep = binding->dirname; + else + { + /* The domain is already bound. If the new value and the old + one are equal we simply do nothing. Otherwise replace the + old binding. */ + char *result = binding->dirname; + if (strcmp (dirname, result) != 0) + { + if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0) + result = (char *) INTUSE(_nl_default_dirname); + else + { +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (dirname); +#else + size_t len = strlen (dirname) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result != NULL, 1)) + memcpy (result, dirname, len); +#endif + } + + if (__builtin_expect (result != NULL, 1)) + { + if (binding->dirname != INTUSE(_nl_default_dirname)) + free (binding->dirname); + + binding->dirname = result; + modified = 1; + } + } + *dirnamep = result; + } + } + + if (codesetp) + { + const char *codeset = *codesetp; + + if (codeset == NULL) + /* The current binding has be to returned. */ + *codesetp = binding->codeset; + else + { + /* The domain is already bound. If the new value and the old + one are equal we simply do nothing. Otherwise replace the + old binding. */ + char *result = binding->codeset; + if (result == NULL || strcmp (codeset, result) != 0) + { +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (codeset); +#else + size_t len = strlen (codeset) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result != NULL, 1)) + memcpy (result, codeset, len); +#endif + + if (__builtin_expect (result != NULL, 1)) + { + if (binding->codeset != NULL) + free (binding->codeset); + + binding->codeset = result; + binding->codeset_cntr++; + modified = 1; + } + } + *codesetp = result; + } + } + } + else if ((dirnamep == NULL || *dirnamep == NULL) + && (codesetp == NULL || *codesetp == NULL)) + { + /* Simply return the default values. */ + if (dirnamep) + *dirnamep = INTUSE(_nl_default_dirname); + if (codesetp) + *codesetp = NULL; + } + else + { + /* We have to create a new binding. */ + size_t len = strlen (domainname) + 1; + struct binding *new_binding = + (struct binding *) malloc (offsetof (struct binding, domainname) + len); + + if (__builtin_expect (new_binding == NULL, 0)) + goto failed; + + memcpy (new_binding->domainname, domainname, len); + + if (dirnamep) + { + const char *dirname = *dirnamep; + + if (dirname == NULL) + /* The default value. */ + dirname = INTUSE(_nl_default_dirname); + else + { + if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0) + dirname = INTUSE(_nl_default_dirname); + else + { + char *result; +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (dirname); + if (__builtin_expect (result == NULL, 0)) + goto failed_dirname; +#else + size_t len = strlen (dirname) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result == NULL, 0)) + goto failed_dirname; + memcpy (result, dirname, len); +#endif + dirname = result; + } + } + *dirnamep = dirname; + new_binding->dirname = (char *) dirname; + } + else + /* The default value. */ + new_binding->dirname = (char *) INTUSE(_nl_default_dirname); + + new_binding->codeset_cntr = 0; + + if (codesetp) + { + const char *codeset = *codesetp; + + if (codeset != NULL) + { + char *result; + +#if defined _LIBC || defined HAVE_STRDUP + result = strdup (codeset); + if (__builtin_expect (result == NULL, 0)) + goto failed_codeset; +#else + size_t len = strlen (codeset) + 1; + result = (char *) malloc (len); + if (__builtin_expect (result == NULL, 0)) + goto failed_codeset; + memcpy (result, codeset, len); +#endif + codeset = result; + new_binding->codeset_cntr++; + } + *codesetp = codeset; + new_binding->codeset = (char *) codeset; + } + else + new_binding->codeset = NULL; + + /* Now enqueue it. */ + if (_nl_domain_bindings == NULL + || strcmp (domainname, _nl_domain_bindings->domainname) < 0) + { + new_binding->next = _nl_domain_bindings; + _nl_domain_bindings = new_binding; + } + else + { + binding = _nl_domain_bindings; + while (binding->next != NULL + && strcmp (domainname, binding->next->domainname) > 0) + binding = binding->next; + + new_binding->next = binding->next; + binding->next = new_binding; + } + + modified = 1; + + /* Here we deal with memory allocation failures. */ + if (0) + { + failed_codeset: + if (new_binding->dirname != INTUSE(_nl_default_dirname)) + free (new_binding->dirname); + failed_dirname: + free (new_binding); + failed: + if (dirnamep) + *dirnamep = NULL; + if (codesetp) + *codesetp = NULL; + } + } + + /* If we modified any binding, we flush the caches. */ + if (modified) + ++_nl_msg_cat_cntr; + + __libc_rwlock_unlock (_nl_state_lock); +} + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +char * +BINDTEXTDOMAIN (domainname, dirname) + const char *domainname; + const char *dirname; +{ + set_binding_values (domainname, &dirname, NULL); + return (char *) dirname; +} + +/* Specify the character encoding in which the messages from the + DOMAINNAME message catalog will be returned. */ +char * +BIND_TEXTDOMAIN_CODESET (domainname, codeset) + const char *domainname; + const char *codeset; +{ + set_binding_values (domainname, NULL, &codeset); + return (char *) codeset; +} + +#ifdef _LIBC +/* Aliases for function names in GNU C Library. */ +weak_alias (__bindtextdomain, bindtextdomain); +weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset); +#endif diff --git a/utshell-0.5.0/lib/intl/config.charset b/utshell-0.5.0/lib/intl/config.charset new file mode 100644 index 00000000..10c44397 --- /dev/null +++ b/utshell-0.5.0/lib/intl/config.charset @@ -0,0 +1,465 @@ +#! /bin/sh +# Output a system dependent table of character encoding aliases. +# +# Copyright (C) 2000-2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# The table consists of lines of the form +# ALIAS CANONICAL +# +# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". +# ALIAS is compared in a case sensitive way. +# +# CANONICAL is the GNU canonical name for this character encoding. +# It must be an encoding supported by libiconv. Support by GNU libc is +# also desirable. CANONICAL is case insensitive. Usually an upper case +# MIME charset name is preferred. +# The current list of GNU canonical charset names is as follows. +# +# name used by which systems a MIME name? +# ASCII, ANSI_X3.4-1968 glibc solaris freebsd +# ISO-8859-1 glibc aix hpux irix osf solaris freebsd yes +# ISO-8859-2 glibc aix hpux irix osf solaris freebsd yes +# ISO-8859-3 glibc solaris yes +# ISO-8859-4 osf solaris freebsd yes +# ISO-8859-5 glibc aix hpux irix osf solaris freebsd yes +# ISO-8859-6 glibc aix hpux solaris yes +# ISO-8859-7 glibc aix hpux irix osf solaris yes +# ISO-8859-8 glibc aix hpux osf solaris yes +# ISO-8859-9 glibc aix hpux irix osf solaris yes +# ISO-8859-13 glibc +# ISO-8859-14 glibc +# ISO-8859-15 glibc aix osf solaris freebsd +# KOI8-R glibc solaris freebsd yes +# KOI8-U glibc freebsd yes +# KOI8-T glibc +# CP437 dos +# CP775 dos +# CP850 aix osf dos +# CP852 dos +# CP855 dos +# CP856 aix +# CP857 dos +# CP861 dos +# CP862 dos +# CP864 dos +# CP865 dos +# CP866 freebsd dos +# CP869 dos +# CP874 woe32 dos +# CP922 aix +# CP932 aix woe32 dos +# CP943 aix +# CP949 osf woe32 dos +# CP950 woe32 dos +# CP1046 aix +# CP1124 aix +# CP1125 dos +# CP1129 aix +# CP1250 woe32 +# CP1251 glibc solaris woe32 +# CP1252 aix woe32 +# CP1253 woe32 +# CP1254 woe32 +# CP1255 glibc woe32 +# CP1256 woe32 +# CP1257 woe32 +# GB2312 glibc aix hpux irix solaris freebsd yes +# EUC-JP glibc aix hpux irix osf solaris freebsd yes +# EUC-KR glibc aix hpux irix osf solaris freebsd yes +# EUC-TW glibc aix hpux irix osf solaris +# BIG5 glibc aix hpux osf solaris freebsd yes +# BIG5-HKSCS glibc solaris +# GBK glibc aix osf solaris woe32 dos +# GB18030 glibc solaris +# SHIFT_JIS hpux osf solaris freebsd yes +# JOHAB glibc solaris woe32 +# TIS-620 glibc aix hpux osf solaris +# VISCII glibc yes +# TCVN5712-1 glibc +# GEORGIAN-PS glibc +# HP-ROMAN8 hpux +# HP-ARABIC8 hpux +# HP-GREEK8 hpux +# HP-HEBREW8 hpux +# HP-TURKISH8 hpux +# HP-KANA8 hpux +# DEC-KANJI osf +# DEC-HANYU osf +# UTF-8 glibc aix hpux osf solaris yes +# +# Note: Names which are not marked as being a MIME name should not be used in +# Internet protocols for information interchange (mail, news, etc.). +# +# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications +# must understand both names and treat them as equivalent. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + +host="$1" +os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` +echo "# This file contains a table of character encoding aliases," +echo "# suitable for operating system '${os}'." +echo "# It was automatically generated from config.charset." +# List of references, updated during installation: +echo "# Packages using this file: " +case "$os" in + linux* | *-gnu*) + # With glibc-2.1 or newer, we don't need any canonicalization, + # because glibc has iconv and both glibc and libiconv support all + # GNU canonical names directly. Therefore, the Makefile does not + # need to install the alias file at all. + # The following applies only to glibc-2.0.x and older libcs. + echo "ISO_646.IRV:1983 ASCII" + ;; + aix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "IBM-850 CP850" + echo "IBM-856 CP856" + echo "IBM-921 ISO-8859-13" + echo "IBM-922 CP922" + echo "IBM-932 CP932" + echo "IBM-943 CP943" + echo "IBM-1046 CP1046" + echo "IBM-1124 CP1124" + echo "IBM-1129 CP1129" + echo "IBM-1252 CP1252" + echo "IBM-eucCN GB2312" + echo "IBM-eucJP EUC-JP" + echo "IBM-eucKR EUC-KR" + echo "IBM-eucTW EUC-TW" + echo "big5 BIG5" + echo "GBK GBK" + echo "TIS-620 TIS-620" + echo "UTF-8 UTF-8" + ;; + hpux*) + echo "iso88591 ISO-8859-1" + echo "iso88592 ISO-8859-2" + echo "iso88595 ISO-8859-5" + echo "iso88596 ISO-8859-6" + echo "iso88597 ISO-8859-7" + echo "iso88598 ISO-8859-8" + echo "iso88599 ISO-8859-9" + echo "iso885915 ISO-8859-15" + echo "roman8 HP-ROMAN8" + echo "arabic8 HP-ARABIC8" + echo "greek8 HP-GREEK8" + echo "hebrew8 HP-HEBREW8" + echo "turkish8 HP-TURKISH8" + echo "kana8 HP-KANA8" + echo "tis620 TIS-620" + echo "big5 BIG5" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "hp15CN GB2312" + #echo "ccdc ?" # what is this? + echo "SJIS SHIFT_JIS" + echo "utf8 UTF-8" + ;; + irix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + ;; + osf*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "cp850 CP850" + echo "big5 BIG5" + echo "dechanyu DEC-HANYU" + echo "dechanzi GB2312" + echo "deckanji DEC-KANJI" + echo "deckorean EUC-KR" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "GBK GBK" + echo "KSC5601 CP949" + echo "sdeckanji EUC-JP" + echo "SJIS SHIFT_JIS" + echo "TACTIS TIS-620" + echo "UTF-8 UTF-8" + ;; + solaris*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-3 ISO-8859-3" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "koi8-r KOI8-R" + echo "ansi-1251 CP1251" + echo "BIG5 BIG5" + echo "Big5-HKSCS BIG5-HKSCS" + echo "gb2312 GB2312" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "cns11643 EUC-TW" + echo "5601 EUC-KR" + echo "ko_KR.johap92 JOHAB" + echo "eucJP EUC-JP" + echo "PCK SHIFT_JIS" + echo "TIS620.2533 TIS-620" + #echo "sun_eu_greek ?" # what is this? + echo "UTF-8 UTF-8" + ;; + freebsd* | os2*) + # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just + # reuse FreeBSD's locale data for OS/2. + echo "C ASCII" + echo "US-ASCII ASCII" + for l in la_LN lt_LN; do + echo "$l.ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ + lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do + echo "$l.ISO_8859-1 ISO-8859-1" + echo "$l.DIS_8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do + echo "$l.ISO_8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO_8859-4 ISO-8859-4" + done + for l in ru_RU ru_SU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO_8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ja_JP.Shift_JIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + netbsd*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-15 ISO-8859-15" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "BIG5 BIG5" + echo "SJIS SHIFT_JIS" + ;; + beos*) + # BeOS has a single locale, and it has UTF-8 encoding. + echo "* UTF-8" + ;; + msdosdjgpp*) + # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "#" + echo "# The encodings given here may not all be correct." + echo "# If you find that the encoding given for your language and" + echo "# country is not the one your DOS machine actually uses, just" + echo "# correct it in this file, and send a mail to" + echo "# Juan Manuel Guerrero " + echo "# and Bruno Haible ." + echo "#" + echo "C ASCII" + # ISO-8859-1 languages + echo "ca CP850" + echo "ca_ES CP850" + echo "da CP865" # not CP850 ?? + echo "da_DK CP865" # not CP850 ?? + echo "de CP850" + echo "de_AT CP850" + echo "de_CH CP850" + echo "de_DE CP850" + echo "en CP850" + echo "en_AU CP850" # not CP437 ?? + echo "en_CA CP850" + echo "en_GB CP850" + echo "en_NZ CP437" + echo "en_US CP437" + echo "en_ZA CP850" # not CP437 ?? + echo "es CP850" + echo "es_AR CP850" + echo "es_BO CP850" + echo "es_CL CP850" + echo "es_CO CP850" + echo "es_CR CP850" + echo "es_CU CP850" + echo "es_DO CP850" + echo "es_EC CP850" + echo "es_ES CP850" + echo "es_GT CP850" + echo "es_HN CP850" + echo "es_MX CP850" + echo "es_NI CP850" + echo "es_PA CP850" + echo "es_PY CP850" + echo "es_PE CP850" + echo "es_SV CP850" + echo "es_UY CP850" + echo "es_VE CP850" + echo "et CP850" + echo "et_EE CP850" + echo "eu CP850" + echo "eu_ES CP850" + echo "fi CP850" + echo "fi_FI CP850" + echo "fr CP850" + echo "fr_BE CP850" + echo "fr_CA CP850" + echo "fr_CH CP850" + echo "fr_FR CP850" + echo "ga CP850" + echo "ga_IE CP850" + echo "gd CP850" + echo "gd_GB CP850" + echo "gl CP850" + echo "gl_ES CP850" + echo "id CP850" # not CP437 ?? + echo "id_ID CP850" # not CP437 ?? + echo "is CP861" # not CP850 ?? + echo "is_IS CP861" # not CP850 ?? + echo "it CP850" + echo "it_CH CP850" + echo "it_IT CP850" + echo "lt CP775" + echo "lt_LT CP775" + echo "lv CP775" + echo "lv_LV CP775" + echo "nb CP865" # not CP850 ?? + echo "nb_NO CP865" # not CP850 ?? + echo "nl CP850" + echo "nl_BE CP850" + echo "nl_NL CP850" + echo "nn CP865" # not CP850 ?? + echo "nn_NO CP865" # not CP850 ?? + echo "no CP865" # not CP850 ?? + echo "no_NO CP865" # not CP850 ?? + echo "pt CP850" + echo "pt_BR CP850" + echo "pt_PT CP850" + echo "sv CP850" + echo "sv_SE CP850" + # ISO-8859-2 languages + echo "cs CP852" + echo "cs_CZ CP852" + echo "hr CP852" + echo "hr_HR CP852" + echo "hu CP852" + echo "hu_HU CP852" + echo "pl CP852" + echo "pl_PL CP852" + echo "ro CP852" + echo "ro_RO CP852" + echo "sk CP852" + echo "sk_SK CP852" + echo "sl CP852" + echo "sl_SI CP852" + echo "sq CP852" + echo "sq_AL CP852" + echo "sr CP852" # CP852 or CP866 or CP855 ?? + echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? + # ISO-8859-3 languages + echo "mt CP850" + echo "mt_MT CP850" + # ISO-8859-5 languages + echo "be CP866" + echo "be_BE CP866" + echo "bg CP866" # not CP855 ?? + echo "bg_BG CP866" # not CP855 ?? + echo "mk CP866" # not CP855 ?? + echo "mk_MK CP866" # not CP855 ?? + echo "ru CP866" + echo "ru_RU CP866" + echo "uk CP1125" + echo "uk_UA CP1125" + # ISO-8859-6 languages + echo "ar CP864" + echo "ar_AE CP864" + echo "ar_DZ CP864" + echo "ar_EG CP864" + echo "ar_IQ CP864" + echo "ar_IR CP864" + echo "ar_JO CP864" + echo "ar_KW CP864" + echo "ar_MA CP864" + echo "ar_OM CP864" + echo "ar_QA CP864" + echo "ar_SA CP864" + echo "ar_SY CP864" + # ISO-8859-7 languages + echo "el CP869" + echo "el_GR CP869" + # ISO-8859-8 languages + echo "he CP862" + echo "he_IL CP862" + # ISO-8859-9 languages + echo "tr CP857" + echo "tr_TR CP857" + # Japanese + echo "ja CP932" + echo "ja_JP CP932" + # Chinese + echo "zh_CN GBK" + echo "zh_TW CP950" # not CP938 ?? + # Korean + echo "kr CP949" # not CP934 ?? + echo "kr_KR CP949" # not CP934 ?? + # Thai + echo "th CP874" + echo "th_TH CP874" + # Other + echo "eo CP850" + echo "eo_EO CP850" + ;; +esac diff --git a/utshell-0.5.0/lib/intl/dcgettext.c b/utshell-0.5.0/lib/intl/dcgettext.c new file mode 100644 index 00000000..c156ca24 --- /dev/null +++ b/utshell-0.5.0/lib/intl/dcgettext.c @@ -0,0 +1,61 @@ +/* dcgettext.c - Implementation of the dcgettext(3) function. */ + +/* Copyright (C) 1995-1999, 2000, 2001, 2002, 2006-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DCGETTEXT __dcgettext +# define DCIGETTEXT __dcigettext +#else +# define DCGETTEXT libintl_dcgettext +# define DCIGETTEXT libintl_dcigettext +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +char * +DCGETTEXT (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ + return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +INTDEF(__dcgettext) +weak_alias (__dcgettext, dcgettext); +#endif diff --git a/utshell-0.5.0/lib/intl/dcigettext.c b/utshell-0.5.0/lib/intl/dcigettext.c new file mode 100644 index 00000000..c0f347e3 --- /dev/null +++ b/utshell-0.5.0/lib/intl/dcigettext.c @@ -0,0 +1,1248 @@ +/* dcigettext.c - Implementation of the internal dcigettext function. */ + +/* Copyright (C) 1995-1999, 2000-2003, 2006-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Tell glibc's to provide a prototype for mempcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +#include +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(val) errno = (val) +#endif + +#include +#include +#include + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include + +#ifdef _LIBC + /* Guess whether integer division by zero raises signal SIGFPE. + Set to 1 only if you know for sure. In case of doubt, set to 0. */ +# if defined __alpha__ || defined __arm__ || defined __i386__ \ + || defined __m68k__ || defined __s390__ +# define INTDIV0_RAISES_SIGFPE 1 +# else +# define INTDIV0_RAISES_SIGFPE 0 +# endif +#endif +#if !INTDIV0_RAISES_SIGFPE +# include +#endif + +#if defined HAVE_SYS_PARAM_H || defined _LIBC +# include +#endif + +#include "gettextP.h" +#include "plural-exp.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif +#include "hash-string.h" + +/* Thread safetyness. */ +#ifdef _LIBC +# include +#else +/* Provide dummy implementation if this is outside glibc. */ +# define __libc_lock_define_initialized(CLASS, NAME) +# define __libc_lock_lock(NAME) +# define __libc_lock_unlock(NAME) +# define __libc_rwlock_define_initialized(CLASS, NAME) +# define __libc_rwlock_rdlock(NAME) +# define __libc_rwlock_unlock(NAME) +#endif + +/* Alignment of types. */ +#if defined __GNUC__ && __GNUC__ >= 2 +# define alignof(TYPE) __alignof__ (TYPE) +#else +# define alignof(TYPE) \ + ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2) +#endif + +/* The internal variables in the standalone libintl.a must have different + names than the internal variables in GNU libc, otherwise programs + using libintl.a cannot be linked statically. */ +#if !defined _LIBC +# define _nl_default_default_domain libintl_nl_default_default_domain +# define _nl_current_default_domain libintl_nl_current_default_domain +# define _nl_default_dirname libintl_nl_default_dirname +# define _nl_domain_bindings libintl_nl_domain_bindings +#endif + +/* Some compilers, like SunOS4 cc, don't have offsetof in . */ +#ifndef offsetof +# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) +#endif + +/* @@ end of prolog @@ */ + +#if defined (SHELL) && !defined (HAVE_GETCWD) +# define HAVE_GETCWD +#endif + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define getcwd __getcwd +# ifndef stpcpy +# define stpcpy __stpcpy +# endif +# define tfind __tfind +#else +# if !defined HAVE_GETCWD +char *getwd (); +# define getcwd(buf, max) getwd (buf) +# else +char *getcwd (); +# endif +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +# ifndef HAVE_MEMPCPY +static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); +# endif +#endif + +/* Amount to increase buffer size by in each try. */ +#define PATH_INCR 32 + +/* The following is from pathmax.h. */ +/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define + PATH_MAX but might cause redefinition warnings when sys/param.h is + later included (as on MORE/BSD 4.3). */ +#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__) +# include +#endif + +#ifndef _POSIX_PATH_MAX +# define _POSIX_PATH_MAX 255 +#endif + +#if !defined PATH_MAX && defined _PC_PATH_MAX +# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) +#endif + +/* Don't include sys/param.h if it already has been. */ +#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN +# include +#endif + +#if !defined PATH_MAX && defined MAXPATHLEN +# define PATH_MAX MAXPATHLEN +#endif + +#ifndef PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +#endif + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, + it may be concatenated to a directory pathname. + IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. + */ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) +# define IS_PATH_WITH_DIR(P) \ + (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) +# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) +#endif + +/* This is the type used for the search tree where known translations + are stored. */ +struct known_translation_t +{ + /* Domain in which to search. */ + char *domainname; + + /* The category. */ + int category; + + /* State of the catalog counter at the point the string was found. */ + int counter; + + /* Catalog where the string was found. */ + struct loaded_l10nfile *domain; + + /* And finally the translation. */ + const char *translation; + size_t translation_length; + + /* Pointer to the string in question. */ + char msgid[ZERO]; +}; + +/* Root of the search tree with known translations. We can use this + only if the system provides the `tsearch' function family. */ +#if defined HAVE_TSEARCH || defined _LIBC +# include + +static void *root; + +# ifdef _LIBC +# define tsearch __tsearch +# endif + +/* Function to compare two entries in the table of known translations. */ +static int transcmp PARAMS ((const void *p1, const void *p2)); +static int +transcmp (p1, p2) + const void *p1; + const void *p2; +{ + const struct known_translation_t *s1; + const struct known_translation_t *s2; + int result; + + s1 = (const struct known_translation_t *) p1; + s2 = (const struct known_translation_t *) p2; + + result = strcmp (s1->msgid, s2->msgid); + if (result == 0) + { + result = strcmp (s1->domainname, s2->domainname); + if (result == 0) + /* We compare the category last (though this is the cheapest + operation) since it is hopefully always the same (namely + LC_MESSAGES). */ + result = s1->category - s2->category; + } + + return result; +} +#endif + +#ifndef INTVARDEF +# define INTVARDEF(name) +#endif +#ifndef INTUSE +# define INTUSE(name) name +#endif + +/* Name of the default domain used for gettext(3) prior any call to + textdomain(3). The default value for this is "messages". */ +const char _nl_default_default_domain[] attribute_hidden = "messages"; + +/* Value used as the default domain for gettext(3). */ +const char *_nl_current_default_domain attribute_hidden + = _nl_default_default_domain; + +/* Contains the default location of the message catalogs. */ +#if defined __EMX__ +extern const char _nl_default_dirname[]; +#else +const char _nl_default_dirname[] = LOCALEDIR; +INTVARDEF (_nl_default_dirname) +#endif + +/* List with bindings of specific domains created by bindtextdomain() + calls. */ +struct binding *_nl_domain_bindings; + +/* Prototypes for local functions. */ +static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain, + unsigned long int n, + const char *translation, + size_t translation_len)) + internal_function; +static const char *guess_category_value PARAMS ((int category, + const char *categoryname)) + internal_function; +#ifdef _LIBC +# include "../locale/localeinfo.h" +# define category_to_name(category) _nl_category_names[category] +#else +static const char *category_to_name PARAMS ((int category)) internal_function; +#endif + + +/* For those loosing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +/* Nothing has to be done. */ +# define freea(p) /* nothing */ +# define ADD_BLOCK(list, address) /* nothing */ +# define FREE_BLOCKS(list) /* nothing */ +#else +struct block_list +{ + void *address; + struct block_list *next; +}; +# define ADD_BLOCK(list, addr) \ + do { \ + struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ + /* If we cannot get a free block we cannot add the new element to \ + the list. */ \ + if (newp != NULL) { \ + newp->address = (addr); \ + newp->next = (list); \ + (list) = newp; \ + } \ + } while (0) +# define FREE_BLOCKS(list) \ + do { \ + while (list != NULL) { \ + struct block_list *old = list; \ + list = list->next; \ + free (old->address); \ + free (old); \ + } \ + } while (0) +# undef alloca +# define alloca(size) (malloc (size)) +# define freea(p) free (p) +#endif /* have alloca */ + + +#ifdef _LIBC +/* List of blocks allocated for translations. */ +typedef struct transmem_list +{ + struct transmem_list *next; + char data[ZERO]; +} transmem_block_t; +static struct transmem_list *transmem_list; +#else +typedef unsigned char transmem_block_t; +#endif + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DCIGETTEXT __dcigettext +#else +# define DCIGETTEXT libintl_dcigettext +#endif + +/* Lock variable to protect the global data in the gettext implementation. */ +#ifdef _LIBC +__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden) +#endif + +/* Checking whether the binaries runs SUID must be done and glibc provides + easier methods therefore we make a difference here. */ +#ifdef _LIBC +# define ENABLE_SECURE __libc_enable_secure +# define DETERMINE_SECURE +#else +# ifndef HAVE_GETUID +# define getuid() 0 +# endif +# ifndef HAVE_GETGID +# define getgid() 0 +# endif +# ifndef HAVE_GETEUID +# define geteuid() getuid() +# endif +# ifndef HAVE_GETEGID +# define getegid() getgid() +# endif +static int enable_secure; +# define ENABLE_SECURE (enable_secure == 1) +# define DETERMINE_SECURE \ + if (enable_secure == 0) \ + { \ + if (getuid () != geteuid () || getgid () != getegid ()) \ + enable_secure = 1; \ + else \ + enable_secure = -1; \ + } +#endif + +#ifndef HAVE_RAISE +# define raise(x) kill (getpid (), (x)) +#endif + +/* Get the function to evaluate the plural expression. */ +#include "eval-plural.h" + +/* Look up MSGID in the DOMAINNAME message catalog for the current + CATEGORY locale and, if PLURAL is nonzero, search over string + depending on the plural form determined by N. */ +char * +DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) + const char *domainname; + const char *msgid1; + const char *msgid2; + int plural; + unsigned long int n; + int category; +{ +#ifndef HAVE_ALLOCA + struct block_list *block_list = NULL; +#endif + struct loaded_l10nfile *domain; + struct binding *binding; + const char *categoryname; + const char *categoryvalue; + char *dirname, *xdomainname; + char *single_locale; + char *retval; + size_t retlen; + int saved_errno; +#if defined HAVE_TSEARCH || defined _LIBC + struct known_translation_t *search; + struct known_translation_t **foundp = NULL; + size_t msgid_len; +#endif + size_t domainname_len; + + /* If no real MSGID is given return NULL. */ + if (msgid1 == NULL) + return NULL; + +#ifdef _LIBC + if (category < 0 || category >= __LC_LAST || category == LC_ALL) + /* Bogus. */ + return (plural == 0 + ? (char *) msgid1 + /* Use the Germanic plural rule. */ + : n == 1 ? (char *) msgid1 : (char *) msgid2); +#endif + + __libc_rwlock_rdlock (_nl_state_lock); + + /* If DOMAINNAME is NULL, we are interested in the default domain. If + CATEGORY is not LC_MESSAGES this might not make much sense but the + definition left this undefined. */ + if (domainname == NULL) + domainname = _nl_current_default_domain; + + /* OS/2 specific: backward compatibility with older libintl versions */ +#ifdef LC_MESSAGES_COMPAT + if (category == LC_MESSAGES_COMPAT) + category = LC_MESSAGES; +#endif + +#if defined HAVE_TSEARCH || defined _LIBC + msgid_len = strlen (msgid1) + 1; + + /* Try to find the translation among those which we found at + some time. */ + search = (struct known_translation_t *) + alloca (offsetof (struct known_translation_t, msgid) + msgid_len); + memcpy (search->msgid, msgid1, msgid_len); + search->domainname = (char *) domainname; + search->category = category; + + foundp = (struct known_translation_t **) tfind (search, &root, transcmp); + freea (search); + if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr) + { + /* Now deal with plural. */ + if (plural) + retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation, + (*foundp)->translation_length); + else + retval = (char *) (*foundp)->translation; + + __libc_rwlock_unlock (_nl_state_lock); + return retval; + } +#endif + + /* Preserve the `errno' value. */ + saved_errno = errno; + + /* See whether this is a SUID binary or not. */ + DETERMINE_SECURE; + + /* First find matching binding. */ + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (binding == NULL) + dirname = (char *) INTUSE(_nl_default_dirname); + else if (IS_ABSOLUTE_PATH (binding->dirname)) + dirname = binding->dirname; + else + { + /* We have a relative path. Make it absolute now. */ + size_t dirname_len = strlen (binding->dirname) + 1; + size_t path_max; + char *ret; + + path_max = (unsigned int) PATH_MAX; + path_max += 2; /* The getcwd docs say to do this. */ + + for (;;) + { + dirname = (char *) alloca (path_max + dirname_len); + ADD_BLOCK (block_list, dirname); + + __set_errno (0); + ret = getcwd (dirname, path_max); + if (ret != NULL || errno != ERANGE) + break; + + path_max += path_max / 2; + path_max += PATH_INCR; + } + + if (ret == NULL) + /* We cannot get the current working directory. Don't signal an + error but simply return the default string. */ + goto return_untranslated; + + stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); + } + + /* Now determine the symbolic name of CATEGORY and its value. */ + categoryname = category_to_name (category); + categoryvalue = guess_category_value (category, categoryname); + + domainname_len = strlen (domainname); + xdomainname = (char *) alloca (strlen (categoryname) + + domainname_len + 5); + ADD_BLOCK (block_list, xdomainname); + + stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), + domainname, domainname_len), + ".mo"); + + /* Creating working area. */ + single_locale = (char *) alloca (strlen (categoryvalue) + 1); + ADD_BLOCK (block_list, single_locale); + + + /* Search for the given string. This is a loop because we perhaps + got an ordered list of languages to consider for the translation. */ + while (1) + { + /* Make CATEGORYVALUE point to the next element of the list. */ + while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') + ++categoryvalue; + if (categoryvalue[0] == '\0') + { + /* The whole contents of CATEGORYVALUE has been searched but + no valid entry has been found. We solve this situation + by implicitly appending a "C" entry, i.e. no translation + will take place. */ + single_locale[0] = 'C'; + single_locale[1] = '\0'; + } + else + { + char *cp = single_locale; + while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') + *cp++ = *categoryvalue++; + *cp = '\0'; + + /* When this is a SUID binary we must not allow accessing files + outside the dedicated directories. */ + if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale)) + /* Ingore this entry. */ + continue; + } + + /* If the current locale value is C (or POSIX) we don't load a + domain. Return the MSGID. */ + if (strcmp (single_locale, "C") == 0 + || strcmp (single_locale, "POSIX") == 0) + break; + + /* Find structure describing the message catalog matching the + DOMAINNAME and CATEGORY. */ + domain = _nl_find_domain (dirname, single_locale, xdomainname, binding); + + if (domain != NULL) + { + retval = _nl_find_msg (domain, binding, msgid1, &retlen); + + if (retval == NULL) + { + int cnt; + + for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) + { + retval = _nl_find_msg (domain->successor[cnt], binding, + msgid1, &retlen); + + if (retval != NULL) + { + domain = domain->successor[cnt]; + break; + } + } + } + + if (retval != NULL) + { + /* Found the translation of MSGID1 in domain DOMAIN: + starting at RETVAL, RETLEN bytes. */ + FREE_BLOCKS (block_list); +#if defined HAVE_TSEARCH || defined _LIBC + if (foundp == NULL) + { + /* Create a new entry and add it to the search tree. */ + struct known_translation_t *newp; + + newp = (struct known_translation_t *) + malloc (offsetof (struct known_translation_t, msgid) + + msgid_len + domainname_len + 1); + if (newp != NULL) + { + newp->domainname = + mempcpy (newp->msgid, msgid1, msgid_len); + memcpy (newp->domainname, domainname, domainname_len + 1); + newp->category = category; + newp->counter = _nl_msg_cat_cntr; + newp->domain = domain; + newp->translation = retval; + newp->translation_length = retlen; + + /* Insert the entry in the search tree. */ + foundp = (struct known_translation_t **) + tsearch (newp, &root, transcmp); + if (foundp == NULL + || __builtin_expect (*foundp != newp, 0)) + /* The insert failed. */ + free (newp); + } + } + else + { + /* We can update the existing entry. */ + (*foundp)->counter = _nl_msg_cat_cntr; + (*foundp)->domain = domain; + (*foundp)->translation = retval; + (*foundp)->translation_length = retlen; + } +#endif + __set_errno (saved_errno); + + /* Now deal with plural. */ + if (plural) + retval = plural_lookup (domain, n, retval, retlen); + + __libc_rwlock_unlock (_nl_state_lock); + return retval; + } + } + } + + return_untranslated: + /* Return the untranslated MSGID. */ + FREE_BLOCKS (block_list); + __libc_rwlock_unlock (_nl_state_lock); +#ifndef _LIBC + if (!ENABLE_SECURE) + { + extern void _nl_log_untranslated PARAMS ((const char *logfilename, + const char *domainname, + const char *msgid1, + const char *msgid2, + int plural)); + const char *logfilename = getenv ("GETTEXT_LOG_UNTRANSLATED"); + + if (logfilename != NULL && logfilename[0] != '\0') + _nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural); + } +#endif + __set_errno (saved_errno); + return (plural == 0 + ? (char *) msgid1 + /* Use the Germanic plural rule. */ + : n == 1 ? (char *) msgid1 : (char *) msgid2); +} + + +char * +internal_function +_nl_find_msg (domain_file, domainbinding, msgid, lengthp) + struct loaded_l10nfile *domain_file; + struct binding *domainbinding; + const char *msgid; + size_t *lengthp; +{ + struct loaded_domain *domain; + nls_uint32 nstrings; + size_t act; + char *result; + size_t resultlen; + + if (domain_file->decided == 0) + _nl_load_domain (domain_file, domainbinding); + + if (domain_file->data == NULL) + return NULL; + + domain = (struct loaded_domain *) domain_file->data; + + nstrings = domain->nstrings; + + /* Locate the MSGID and its translation. */ + if (domain->hash_tab != NULL) + { + /* Use the hashing table. */ + nls_uint32 len = strlen (msgid); + nls_uint32 hash_val = hash_string (msgid); + nls_uint32 idx = hash_val % domain->hash_size; + nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); + + while (1) + { + nls_uint32 nstr = + W (domain->must_swap_hash_tab, domain->hash_tab[idx]); + + if (nstr == 0) + /* Hash table entry is empty. */ + return NULL; + + nstr--; + + /* Compare msgid with the original string at index nstr. + We compare the lengths with >=, not ==, because plural entries + are represented by strings with an embedded NUL. */ + if (nstr < nstrings + ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len + && (strcmp (msgid, + domain->data + W (domain->must_swap, + domain->orig_tab[nstr].offset)) + == 0) + : domain->orig_sysdep_tab[nstr - nstrings].length > len + && (strcmp (msgid, + domain->orig_sysdep_tab[nstr - nstrings].pointer) + == 0)) + { + act = nstr; + goto found; + } + + if (idx >= domain->hash_size - incr) + idx -= domain->hash_size - incr; + else + idx += incr; + } + /* NOTREACHED */ + } + else + { + /* Try the default method: binary search in the sorted array of + messages. */ + size_t top, bottom; + + bottom = 0; + top = nstrings; + while (bottom < top) + { + int cmp_val; + + act = (bottom + top) / 2; + cmp_val = strcmp (msgid, (domain->data + + W (domain->must_swap, + domain->orig_tab[act].offset))); + if (cmp_val < 0) + top = act; + else if (cmp_val > 0) + bottom = act + 1; + else + goto found; + } + /* No translation was found. */ + return NULL; + } + + found: + /* The translation was found at index ACT. If we have to convert the + string to use a different character set, this is the time. */ + if (act < nstrings) + { + result = (char *) + (domain->data + W (domain->must_swap, domain->trans_tab[act].offset)); + resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1; + } + else + { + result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer; + resultlen = domain->trans_sysdep_tab[act - nstrings].length; + } + +#if defined _LIBC || HAVE_ICONV + if (domain->codeset_cntr + != (domainbinding != NULL ? domainbinding->codeset_cntr : 0)) + { + /* The domain's codeset has changed through bind_textdomain_codeset() + since the message catalog was initialized or last accessed. We + have to reinitialize the converter. */ + _nl_free_domain_conv (domain); + _nl_init_domain_conv (domain_file, domain, domainbinding); + } + + if ( +# ifdef _LIBC + domain->conv != (__gconv_t) -1 +# else +# if HAVE_ICONV + domain->conv != (iconv_t) -1 +# endif +# endif + ) + { + /* We are supposed to do a conversion. First allocate an + appropriate table with the same structure as the table + of translations in the file, where we can put the pointers + to the converted strings in. + There is a slight complication with plural entries. They + are represented by consecutive NUL terminated strings. We + handle this case by converting RESULTLEN bytes, including + NULs. */ + + if (domain->conv_tab == NULL + && ((domain->conv_tab = + (char **) calloc (nstrings + domain->n_sysdep_strings, + sizeof (char *))) + == NULL)) + /* Mark that we didn't succeed allocating a table. */ + domain->conv_tab = (char **) -1; + + if (__builtin_expect (domain->conv_tab == (char **) -1, 0)) + /* Nothing we can do, no more memory. */ + goto converted; + + if (domain->conv_tab[act] == NULL) + { + /* We haven't used this string so far, so it is not + translated yet. Do this now. */ + /* We use a bit more efficient memory handling. + We allocate always larger blocks which get used over + time. This is faster than many small allocations. */ + __libc_lock_define_initialized (static, lock) +# define INITIAL_BLOCK_SIZE 4080 + static unsigned char *freemem; + static size_t freemem_size; + + const unsigned char *inbuf; + unsigned char *outbuf; + int malloc_count; +# ifndef _LIBC + transmem_block_t *transmem_list = NULL; +# endif + + __libc_lock_lock (lock); + + inbuf = (const unsigned char *) result; + outbuf = freemem + sizeof (size_t); + + malloc_count = 0; + while (1) + { + transmem_block_t *newmem; +# ifdef _LIBC + size_t non_reversible; + int res; + + if (freemem_size < sizeof (size_t)) + goto resize_freemem; + + res = __gconv (domain->conv, + &inbuf, inbuf + resultlen, + &outbuf, + outbuf + freemem_size - sizeof (size_t), + &non_reversible); + + if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT) + break; + + if (res != __GCONV_FULL_OUTPUT) + { + __libc_lock_unlock (lock); + goto converted; + } + + inbuf = result; +# else +# if HAVE_ICONV + const char *inptr = (const char *) inbuf; + size_t inleft = resultlen; + char *outptr = (char *) outbuf; + size_t outleft; + + if (freemem_size < sizeof (size_t)) + goto resize_freemem; + + outleft = freemem_size - sizeof (size_t); + if (iconv (domain->conv, + (ICONV_CONST char **) &inptr, &inleft, + &outptr, &outleft) + != (size_t) (-1)) + { + outbuf = (unsigned char *) outptr; + break; + } + if (errno != E2BIG) + { + __libc_lock_unlock (lock); + goto converted; + } +# endif +# endif + + resize_freemem: + /* We must allocate a new buffer or resize the old one. */ + if (malloc_count > 0) + { + ++malloc_count; + freemem_size = malloc_count * INITIAL_BLOCK_SIZE; + newmem = (transmem_block_t *) realloc (transmem_list, + freemem_size); +# ifdef _LIBC + if (newmem != NULL) + transmem_list = transmem_list->next; + else + { + struct transmem_list *old = transmem_list; + + transmem_list = transmem_list->next; + free (old); + } +# endif + } + else + { + malloc_count = 1; + freemem_size = INITIAL_BLOCK_SIZE; + newmem = (transmem_block_t *) malloc (freemem_size); + } + if (__builtin_expect (newmem == NULL, 0)) + { + freemem = NULL; + freemem_size = 0; + __libc_lock_unlock (lock); + goto converted; + } + +# ifdef _LIBC + /* Add the block to the list of blocks we have to free + at some point. */ + newmem->next = transmem_list; + transmem_list = newmem; + + freemem = newmem->data; + freemem_size -= offsetof (struct transmem_list, data); +# else + transmem_list = newmem; + freemem = newmem; +# endif + + outbuf = freemem + sizeof (size_t); + } + + /* We have now in our buffer a converted string. Put this + into the table of conversions. */ + *(size_t *) freemem = outbuf - freemem - sizeof (size_t); + domain->conv_tab[act] = (char *) freemem; + /* Shrink freemem, but keep it aligned. */ + freemem_size -= outbuf - freemem; + freemem = outbuf; + freemem += freemem_size & (alignof (size_t) - 1); + freemem_size = freemem_size & ~ (alignof (size_t) - 1); + + __libc_lock_unlock (lock); + } + + /* Now domain->conv_tab[act] contains the translation of all + the plural variants. */ + result = domain->conv_tab[act] + sizeof (size_t); + resultlen = *(size_t *) domain->conv_tab[act]; + } + + converted: + /* The result string is converted. */ + +#endif /* _LIBC || HAVE_ICONV */ + + *lengthp = resultlen; + return result; +} + + +/* Look up a plural variant. */ +static char * +internal_function +plural_lookup (domain, n, translation, translation_len) + struct loaded_l10nfile *domain; + unsigned long int n; + const char *translation; + size_t translation_len; +{ + struct loaded_domain *domaindata = (struct loaded_domain *) domain->data; + unsigned long int index; + const char *p; + + index = plural_eval (domaindata->plural, n); + if (index >= domaindata->nplurals) + /* This should never happen. It means the plural expression and the + given maximum value do not match. */ + index = 0; + + /* Skip INDEX strings at TRANSLATION. */ + p = translation; + while (index-- > 0) + { +#ifdef _LIBC + p = __rawmemchr (p, '\0'); +#else + p = strchr (p, '\0'); +#endif + /* And skip over the NUL byte. */ + p++; + + if (p >= translation + translation_len) + /* This should never happen. It means the plural expression + evaluated to a value larger than the number of variants + available for MSGID1. */ + return (char *) translation; + } + return (char *) p; +} + +#ifndef _LIBC +/* Return string representation of locale CATEGORY. */ +static const char * +internal_function +category_to_name (category) + int category; +{ + const char *retval; + + switch (category) + { +#ifdef LC_COLLATE + case LC_COLLATE: + retval = "LC_COLLATE"; + break; +#endif +#ifdef LC_CTYPE + case LC_CTYPE: + retval = "LC_CTYPE"; + break; +#endif +#ifdef LC_MONETARY + case LC_MONETARY: + retval = "LC_MONETARY"; + break; +#endif +#ifdef LC_NUMERIC + case LC_NUMERIC: + retval = "LC_NUMERIC"; + break; +#endif +#ifdef LC_TIME + case LC_TIME: + retval = "LC_TIME"; + break; +#endif +#ifdef LC_MESSAGES + case LC_MESSAGES: + retval = "LC_MESSAGES"; + break; +#endif +#ifdef LC_RESPONSE + case LC_RESPONSE: + retval = "LC_RESPONSE"; + break; +#endif +#ifdef LC_ALL + case LC_ALL: + /* This might not make sense but is perhaps better than any other + value. */ + retval = "LC_ALL"; + break; +#endif + default: + /* If you have a better idea for a default value let me know. */ + retval = "LC_XXX"; + } + + return retval; +} +#endif + +/* Guess value of current locale from value of the environment variables. */ +static const char * +internal_function +guess_category_value (category, categoryname) + int category; + const char *categoryname; +{ + const char *language; + const char *retval; + + /* The highest priority value is the `LANGUAGE' environment + variable. But we don't use the value if the currently selected + locale is the C locale. This is a GNU extension. */ + language = getenv ("LANGUAGE"); + if (language != NULL && language[0] == '\0') + language = NULL; + + /* We have to proceed with the POSIX methods of looking to `LC_ALL', + `LC_xxx', and `LANG'. On some systems this can be done by the + `setlocale' function itself. */ +#ifdef _LIBC + retval = __current_locale_name (category); +#else + retval = _nl_locale_name (category, categoryname); +#endif + + /* Ignore LANGUAGE if the locale is set to "C" because + 1. "C" locale usually uses the ASCII encoding, and most international + messages use non-ASCII characters. These characters get displayed + as question marks (if using glibc's iconv()) or as invalid 8-bit + characters (because other iconv()s refuse to convert most non-ASCII + characters to ASCII). In any case, the output is ugly. + 2. The precise output of some programs in the "C" locale is specified + by POSIX and should not depend on environment variables like + "LANGUAGE". We allow such programs to use gettext(). */ + return language != NULL && strcmp (retval, "C") != 0 ? language : retval; +} + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif + +#if !_LIBC && !HAVE_MEMPCPY +static void * +mempcpy (dest, src, n) + void *dest; + const void *src; + size_t n; +{ + return (void *) ((char *) memcpy (dest, src, n) + n); +} +#endif + + +#ifdef _LIBC +/* If we want to free all resources we have to do some work at + program's end. */ +libc_freeres_fn (free_mem) +{ + void *old; + + while (_nl_domain_bindings != NULL) + { + struct binding *oldp = _nl_domain_bindings; + _nl_domain_bindings = _nl_domain_bindings->next; + if (oldp->dirname != INTUSE(_nl_default_dirname)) + /* Yes, this is a pointer comparison. */ + free (oldp->dirname); + free (oldp->codeset); + free (oldp); + } + + if (_nl_current_default_domain != _nl_default_default_domain) + /* Yes, again a pointer comparison. */ + free ((char *) _nl_current_default_domain); + + /* Remove the search tree with the known translations. */ + __tdestroy (root, free); + root = NULL; + + while (transmem_list != NULL) + { + old = transmem_list; + transmem_list = transmem_list->next; + free (old); + } +} +#endif diff --git a/utshell-0.5.0/lib/intl/dcngettext.c b/utshell-0.5.0/lib/intl/dcngettext.c new file mode 100644 index 00000000..3d70b18f --- /dev/null +++ b/utshell-0.5.0/lib/intl/dcngettext.c @@ -0,0 +1,62 @@ +/* dcngettext.c - Implementation of the dcngettext(3) function. */ + +/* Copyright (C) 1995-1999, 2000, 2001, 2002, 2006-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DCNGETTEXT __dcngettext +# define DCIGETTEXT __dcigettext +#else +# define DCNGETTEXT libintl_dcngettext +# define DCIGETTEXT libintl_dcigettext +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +char * +DCNGETTEXT (domainname, msgid1, msgid2, n, category) + const char *domainname; + const char *msgid1; + const char *msgid2; + unsigned long int n; + int category; +{ + return DCIGETTEXT (domainname, msgid1, msgid2, 1, n, category); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dcngettext, dcngettext); +#endif diff --git a/utshell-0.5.0/lib/intl/dgettext.c b/utshell-0.5.0/lib/intl/dgettext.c new file mode 100644 index 00000000..53516314 --- /dev/null +++ b/utshell-0.5.0/lib/intl/dgettext.c @@ -0,0 +1,61 @@ +/* dgettext.c - Implementation of the dgettext(3) function. */ + +/* Copyright (C) 1995-1997, 2000, 2001, 2002, 2006-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DGETTEXT __dgettext +# define DCGETTEXT INTUSE(__dcgettext) +#else +# define DGETTEXT libintl_dgettext +# define DCGETTEXT libintl_dcgettext +#endif + +/* Look up MSGID in the DOMAINNAME message catalog of the current + LC_MESSAGES locale. */ +char * +DGETTEXT (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return DCGETTEXT (domainname, msgid, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dgettext, dgettext); +#endif diff --git a/utshell-0.5.0/lib/intl/dngettext.c b/utshell-0.5.0/lib/intl/dngettext.c new file mode 100644 index 00000000..4276f3b2 --- /dev/null +++ b/utshell-0.5.0/lib/intl/dngettext.c @@ -0,0 +1,63 @@ +/* dngettext.c - Implementation of the dngettext(3) function. */ + +/* Copyright (C) 1995-1997, 2000, 2001, 2002, 2005, 2006, 2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DNGETTEXT __dngettext +# define DCNGETTEXT __dcngettext +#else +# define DNGETTEXT libintl_dngettext +# define DCNGETTEXT libintl_dcngettext +#endif + +/* Look up MSGID in the DOMAINNAME message catalog of the current + LC_MESSAGES locale and skip message according to the plural form. */ +char * +DNGETTEXT (domainname, msgid1, msgid2, n) + const char *domainname; + const char *msgid1; + const char *msgid2; + unsigned long int n; +{ + return DCNGETTEXT (domainname, msgid1, msgid2, n, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dngettext, dngettext); +#endif diff --git a/utshell-0.5.0/lib/intl/eval-plural.h b/utshell-0.5.0/lib/intl/eval-plural.h new file mode 100644 index 00000000..3441c74e --- /dev/null +++ b/utshell-0.5.0/lib/intl/eval-plural.h @@ -0,0 +1,116 @@ +/* eval-plural.c - Plural expression evaluation. */ + +/* Copyright (C) 2000-2002, 2006-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef STATIC +#define STATIC static +#endif + +/* Evaluate the plural expression and return an index value. */ +STATIC unsigned long int plural_eval PARAMS ((struct expression *pexp, + unsigned long int n)) + internal_function; + +STATIC +unsigned long int +internal_function +plural_eval (pexp, n) + struct expression *pexp; + unsigned long int n; +{ + switch (pexp->nargs) + { + case 0: + switch (pexp->operation) + { + case var: + return n; + case num: + return pexp->val.num; + default: + break; + } + /* NOTREACHED */ + break; + case 1: + { + /* pexp->operation must be lnot. */ + unsigned long int arg = plural_eval (pexp->val.args[0], n); + return ! arg; + } + case 2: + { + unsigned long int leftarg = plural_eval (pexp->val.args[0], n); + if (pexp->operation == lor) + return leftarg || plural_eval (pexp->val.args[1], n); + else if (pexp->operation == land) + return leftarg && plural_eval (pexp->val.args[1], n); + else + { + unsigned long int rightarg = plural_eval (pexp->val.args[1], n); + + switch (pexp->operation) + { + case mult: + return leftarg * rightarg; + case divide: +#if !INTDIV0_RAISES_SIGFPE + if (rightarg == 0) + raise (SIGFPE); +#endif + return leftarg / rightarg; + case module: +#if !INTDIV0_RAISES_SIGFPE + if (rightarg == 0) + raise (SIGFPE); +#endif + return leftarg % rightarg; + case plus: + return leftarg + rightarg; + case minus: + return leftarg - rightarg; + case less_than: + return leftarg < rightarg; + case greater_than: + return leftarg > rightarg; + case less_or_equal: + return leftarg <= rightarg; + case greater_or_equal: + return leftarg >= rightarg; + case equal: + return leftarg == rightarg; + case not_equal: + return leftarg != rightarg; + default: + break; + } + } + /* NOTREACHED */ + break; + } + case 3: + { + /* pexp->operation must be qmop. */ + unsigned long int boolarg = plural_eval (pexp->val.args[0], n); + return plural_eval (pexp->val.args[boolarg ? 1 : 2], n); + } + } + /* NOTREACHED */ + return 0; +} diff --git a/utshell-0.5.0/lib/intl/explodename.c b/utshell-0.5.0/lib/intl/explodename.c new file mode 100644 index 00000000..adc36402 --- /dev/null +++ b/utshell-0.5.0/lib/intl/explodename.c @@ -0,0 +1,195 @@ +/* explodename.c */ + +/* Copyright (C) 1995-1998, 2000, 2001, 2005-2009 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +char * +_nl_find_language (name) + const char *name; +{ + while (name[0] != '\0' && name[0] != '_' && name[0] != '@' + && name[0] != '+' && name[0] != ',') + ++name; + + return (char *) name; +} + + +int +_nl_explode_name (name, language, modifier, territory, codeset, + normalized_codeset, special, sponsor, revision) + char *name; + const char **language; + const char **modifier; + const char **territory; + const char **codeset; + const char **normalized_codeset; + const char **special; + const char **sponsor; + const char **revision; +{ + enum { undecided, xpg, cen } syntax; + char *cp; + int mask; + + *modifier = NULL; + *territory = NULL; + *codeset = NULL; + *normalized_codeset = NULL; + *special = NULL; + *sponsor = NULL; + *revision = NULL; + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = 0; + syntax = undecided; + *language = cp = name; + cp = _nl_find_language (*language); + + if (*language == cp) + /* This does not make sense: language has to be specified. Use + this entry as it is without exploding. Perhaps it is an alias. */ + cp = strchr (*language, '\0'); + else if (cp[0] == '_') + { + /* Next is the territory. */ + cp[0] = '\0'; + *territory = ++cp; + + while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' + && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= TERRITORY; + + if (cp[0] == '.') + { + /* Next is the codeset. */ + syntax = xpg; + cp[0] = '\0'; + *codeset = ++cp; + + while (cp[0] != '\0' && cp[0] != '@') + ++cp; + + mask |= XPG_CODESET; + + if (*codeset != cp && (*codeset)[0] != '\0') + { + *normalized_codeset = _nl_normalize_codeset (*codeset, + cp - *codeset); + if (strcmp (*codeset, *normalized_codeset) == 0) + free ((char *) *normalized_codeset); + else + mask |= XPG_NORM_CODESET; + } + } + } + + if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) + { + /* Next is the modifier. */ + syntax = cp[0] == '@' ? xpg : cen; + cp[0] = '\0'; + *modifier = ++cp; + + while (syntax == cen && cp[0] != '\0' && cp[0] != '+' + && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= XPG_MODIFIER | CEN_AUDIENCE; + } + + if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) + { + syntax = cen; + + if (cp[0] == '+') + { + /* Next is special application (CEN syntax). */ + cp[0] = '\0'; + *special = ++cp; + + while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= CEN_SPECIAL; + } + + if (cp[0] == ',') + { + /* Next is sponsor (CEN syntax). */ + cp[0] = '\0'; + *sponsor = ++cp; + + while (cp[0] != '\0' && cp[0] != '_') + ++cp; + + mask |= CEN_SPONSOR; + } + + if (cp[0] == '_') + { + /* Next is revision (CEN syntax). */ + cp[0] = '\0'; + *revision = ++cp; + + mask |= CEN_REVISION; + } + } + + /* For CEN syntax values it might be important to have the + separator character in the file name, not for XPG syntax. */ + if (syntax == xpg) + { + if (*territory != NULL && (*territory)[0] == '\0') + mask &= ~TERRITORY; + + if (*codeset != NULL && (*codeset)[0] == '\0') + mask &= ~XPG_CODESET; + + if (*modifier != NULL && (*modifier)[0] == '\0') + mask &= ~XPG_MODIFIER; + } + + return mask; +} diff --git a/utshell-0.5.0/lib/intl/finddomain.c b/utshell-0.5.0/lib/intl/finddomain.c new file mode 100644 index 00000000..69a3586e --- /dev/null +++ b/utshell-0.5.0/lib/intl/finddomain.c @@ -0,0 +1,197 @@ +/* finddomain.c - Handle list of needed message catalogs */ + +/* Copyright (C) 1995-1999, 2000, 2001, 2005-2009 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ +/* List of already loaded domains. */ +static struct loaded_l10nfile *_nl_loaded_domains; + + +/* Return a data structure describing the message catalog described by + the DOMAINNAME and CATEGORY parameters with respect to the currently + established bindings. */ +struct loaded_l10nfile * +internal_function +_nl_find_domain (dirname, locale, domainname, domainbinding) + const char *dirname; + char *locale; + const char *domainname; + struct binding *domainbinding; +{ + struct loaded_l10nfile *retval; + const char *language; + const char *modifier; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *special; + const char *sponsor; + const char *revision; + const char *alias_value; + int mask; + + /* LOCALE can consist of up to four recognized parts for the XPG syntax: + + language[_territory[.codeset]][@modifier] + + and six parts for the CEN syntax: + + language[_territory][+audience][+special][,[sponsor][_revision]] + + Beside the first part all of them are allowed to be missing. If + the full specified locale is not found, the less specific one are + looked for. The various parts will be stripped off according to + the following order: + (1) revision + (2) sponsor + (3) special + (4) codeset + (5) normalized codeset + (6) territory + (7) audience/modifier + */ + + /* If we have already tested for this locale entry there has to + be one data set in the list of loaded domains. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, 0, locale, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, domainname, 0); + if (retval != NULL) + { + /* We know something about this locale. */ + int cnt; + + if (retval->decided == 0) + _nl_load_domain (retval, domainbinding); + + if (retval->data != NULL) + return retval; + + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt], domainbinding); + + if (retval->successor[cnt]->data != NULL) + break; + } + return cnt >= 0 ? retval : NULL; + /* NOTREACHED */ + } + + /* See whether the locale value is an alias. If yes its value + *overwrites* the alias name. No test for the original value is + done. */ + alias_value = _nl_expand_alias (locale); + if (alias_value != NULL) + { +#if defined _LIBC || defined HAVE_STRDUP + locale = strdup (alias_value); + if (locale == NULL) + return NULL; +#else + size_t len = strlen (alias_value) + 1; + locale = (char *) malloc (len); + if (locale == NULL) + return NULL; + + memcpy (locale, alias_value, len); +#endif + } + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = _nl_explode_name (locale, &language, &modifier, &territory, + &codeset, &normalized_codeset, &special, + &sponsor, &revision); + + /* Create all possible locale entries which might be interested in + generalization. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, mask, language, territory, + codeset, normalized_codeset, modifier, special, + sponsor, revision, domainname, 1); + if (retval == NULL) + /* This means we are out of core. */ + return NULL; + + if (retval->decided == 0) + _nl_load_domain (retval, domainbinding); + if (retval->data == NULL) + { + int cnt; + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt], domainbinding); + if (retval->successor[cnt]->data != NULL) + break; + } + } + + /* The room for an alias was dynamically allocated. Free it now. */ + if (alias_value != NULL) + free (locale); + + /* The space for normalized_codeset is dynamically allocated. Free it. */ + if (mask & XPG_NORM_CODESET) + free ((void *) normalized_codeset); + + return retval; +} + + +#ifdef _LIBC +libc_freeres_fn (free_mem) +{ + struct loaded_l10nfile *runp = _nl_loaded_domains; + + while (runp != NULL) + { + struct loaded_l10nfile *here = runp; + if (runp->data != NULL) + _nl_unload_domain ((struct loaded_domain *) runp->data); + runp = runp->next; + free ((char *) here->filename); + free (here); + } +} +#endif diff --git a/utshell-0.5.0/lib/intl/gettext.c b/utshell-0.5.0/lib/intl/gettext.c new file mode 100644 index 00000000..fd3fa0ff --- /dev/null +++ b/utshell-0.5.0/lib/intl/gettext.c @@ -0,0 +1,66 @@ +/* gettext.c - Implementation of gettext(3) function. */ + +/* Copyright (C) 1995, 1997, 2000, 2001, 2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define __need_NULL +# include +#else +# include /* Just for NULL. */ +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define GETTEXT __gettext +# define DCGETTEXT INTUSE(__dcgettext) +#else +# define GETTEXT libintl_gettext +# define DCGETTEXT libintl_dcgettext +#endif + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +char * +GETTEXT (msgid) + const char *msgid; +{ + return DCGETTEXT (NULL, msgid, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__gettext, gettext); +#endif diff --git a/utshell-0.5.0/lib/intl/gettextP.h b/utshell-0.5.0/lib/intl/gettextP.h new file mode 100644 index 00000000..5c137e51 --- /dev/null +++ b/utshell-0.5.0/lib/intl/gettextP.h @@ -0,0 +1,226 @@ +/* gettextP.h - Header describing internals of libintl library. */ + +/* Copyright (C) 1995-1999, 2000-2003, 2005-2009 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _GETTEXTP_H +#define _GETTEXTP_H + +#include /* Get size_t. */ + +#ifdef _LIBC +# include "../iconv/gconv_int.h" +#else +# if HAVE_ICONV +# include +# endif +#endif + +#include "loadinfo.h" + +#include "gmo.h" /* Get nls_uint32. */ + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + +/* Tell the compiler when a conditional or integer expression is + almost always true or almost always false. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + +#ifndef W +# define W(flag, data) ((flag) ? SWAP (data) : (data)) +#endif + + +#ifdef _LIBC +# include +# define SWAP(i) bswap_32 (i) +#else +static inline nls_uint32 +SWAP (i) + nls_uint32 i; +{ + return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); +} +#endif + + +/* In-memory representation of system dependent string. */ +struct sysdep_string_desc +{ + /* Length of addressed string, including the trailing NUL. */ + size_t length; + /* Pointer to addressed string. */ + const char *pointer; +}; + +/* The representation of an opened message catalog. */ +struct loaded_domain +{ + /* Pointer to memory containing the .mo file. */ + const char *data; + /* 1 if the memory is mmap()ed, 0 if the memory is malloc()ed. */ + int use_mmap; + /* Size of mmap()ed memory. */ + size_t mmap_size; + /* 1 if the .mo file uses a different endianness than this machine. */ + int must_swap; + /* Pointer to additional malloc()ed memory. */ + void *malloced; + + /* Number of static strings pairs. */ + nls_uint32 nstrings; + /* Pointer to descriptors of original strings in the file. */ + const struct string_desc *orig_tab; + /* Pointer to descriptors of translated strings in the file. */ + const struct string_desc *trans_tab; + + /* Number of system dependent strings pairs. */ + nls_uint32 n_sysdep_strings; + /* Pointer to descriptors of original sysdep strings. */ + const struct sysdep_string_desc *orig_sysdep_tab; + /* Pointer to descriptors of translated sysdep strings. */ + const struct sysdep_string_desc *trans_sysdep_tab; + + /* Size of hash table. */ + nls_uint32 hash_size; + /* Pointer to hash table. */ + const nls_uint32 *hash_tab; + /* 1 if the hash table uses a different endianness than this machine. */ + int must_swap_hash_tab; + + int codeset_cntr; +#ifdef _LIBC + __gconv_t conv; +#else +# if HAVE_ICONV + iconv_t conv; +# endif +#endif + char **conv_tab; + + struct expression *plural; + unsigned long int nplurals; +}; + +/* We want to allocate a string at the end of the struct. But ISO C + doesn't allow zero sized arrays. */ +#ifdef __GNUC__ +# define ZERO 0 +#else +# define ZERO 1 +#endif + +/* A set of settings bound to a message domain. Used to store settings + from bindtextdomain() and bind_textdomain_codeset(). */ +struct binding +{ + struct binding *next; + char *dirname; + int codeset_cntr; /* Incremented each time codeset changes. */ + char *codeset; + char domainname[ZERO]; +}; + +/* A counter which is incremented each time some previous translations + become invalid. + This variable is part of the external ABI of the GNU libintl. */ +extern int _nl_msg_cat_cntr; + +#ifndef _LIBC +const char *_nl_locale_name PARAMS ((int category, const char *categoryname)); +#endif + +struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, + char *__locale, + const char *__domainname, + struct binding *__domainbinding)) + internal_function; +void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain, + struct binding *__domainbinding)) + internal_function; +void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) + internal_function; +const char *_nl_init_domain_conv PARAMS ((struct loaded_l10nfile *__domain_file, + struct loaded_domain *__domain, + struct binding *__domainbinding)) + internal_function; +void _nl_free_domain_conv PARAMS ((struct loaded_domain *__domain)) + internal_function; + +char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file, + struct binding *domainbinding, + const char *msgid, size_t *lengthp)) + internal_function; + +#ifdef _LIBC +extern char *__gettext PARAMS ((const char *__msgid)); +extern char *__dgettext PARAMS ((const char *__domainname, + const char *__msgid)); +extern char *__dcgettext PARAMS ((const char *__domainname, + const char *__msgid, int __category)); +extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2, + unsigned long int __n)); +extern char *__dngettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int n)); +extern char *__dcngettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category)); +extern char *__dcigettext PARAMS ((const char *__domainname, + const char *__msgid1, const char *__msgid2, + int __plural, unsigned long int __n, + int __category)); +extern char *__textdomain PARAMS ((const char *__domainname)); +extern char *__bindtextdomain PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname, + const char *__codeset)); +#else +/* Declare the exported libintl_* functions, in a way that allows us to + call them under their real name. */ +# define _INTL_REDIRECT_MACROS +# include "libgnuintl.h" +extern char *libintl_dcigettext PARAMS ((const char *__domainname, + const char *__msgid1, + const char *__msgid2, + int __plural, unsigned long int __n, + int __category)); +#endif + +/* @@ begin of epilog @@ */ + +#endif /* gettextP.h */ diff --git a/utshell-0.5.0/lib/intl/gmo.h b/utshell-0.5.0/lib/intl/gmo.h new file mode 100644 index 00000000..2c578512 --- /dev/null +++ b/utshell-0.5.0/lib/intl/gmo.h @@ -0,0 +1,150 @@ +/* gmo.h - Description of GNU message catalog format: general file layout. */ + +/* Copyright (C) 1995, 1997, 2000-2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _GETTEXT_H +#define _GETTEXT_H 1 + +#include + +/* @@ end of prolog @@ */ + +/* The magic number of the GNU message catalog format. */ +#define _MAGIC 0x950412de +#define _MAGIC_SWAPPED 0xde120495 + +/* Revision number of the currently used .mo (binary) file format. */ +#define MO_REVISION_NUMBER 0 + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work + when cross-compiling. */ + +#if __STDC__ +# define UINT_MAX_32_BITS 4294967295U +#else +# define UINT_MAX_32_BITS 0xFFFFFFFF +#endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +#ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +#endif + +#if UINT_MAX == UINT_MAX_32_BITS +typedef unsigned nls_uint32; +#else +# if USHRT_MAX == UINT_MAX_32_BITS +typedef unsigned short nls_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS +typedef unsigned long nls_uint32; +# else + /* The following line is intended to throw an error. Using #error is + not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +#endif + + +/* Header for binary .mo file format. */ +struct mo_file_header +{ + /* The magic number. */ + nls_uint32 magic; + /* The revision number of the file format. */ + nls_uint32 revision; + + /* The following are only used in .mo files with major revision 0. */ + + /* The number of strings pairs. */ + nls_uint32 nstrings; + /* Offset of table with start offsets of original strings. */ + nls_uint32 orig_tab_offset; + /* Offset of table with start offsets of translated strings. */ + nls_uint32 trans_tab_offset; + /* Size of hash table. */ + nls_uint32 hash_tab_size; + /* Offset of first hash table entry. */ + nls_uint32 hash_tab_offset; + + /* The following are only used in .mo files with minor revision >= 1. */ + + /* The number of system dependent segments. */ + nls_uint32 n_sysdep_segments; + /* Offset of table describing system dependent segments. */ + nls_uint32 sysdep_segments_offset; + /* The number of system dependent strings pairs. */ + nls_uint32 n_sysdep_strings; + /* Offset of table with start offsets of original sysdep strings. */ + nls_uint32 orig_sysdep_tab_offset; + /* Offset of table with start offsets of translated sysdep strings. */ + nls_uint32 trans_sysdep_tab_offset; +}; + +/* Descriptor for static string contained in the binary .mo file. */ +struct string_desc +{ + /* Length of addressed string, not including the trailing NUL. */ + nls_uint32 length; + /* Offset of string in file. */ + nls_uint32 offset; +}; + +/* The following are only used in .mo files with minor revision >= 1. */ + +/* Descriptor for system dependent string segment. */ +struct sysdep_segment +{ + /* Length of addressed string, including the trailing NUL. */ + nls_uint32 length; + /* Offset of string in file. */ + nls_uint32 offset; +}; + +/* Descriptor for system dependent string. */ +struct sysdep_string +{ + /* Offset of static string segments in file. */ + nls_uint32 offset; + /* Alternating sequence of static and system dependent segments. + The last segment is a static segment, including the trailing NUL. */ + struct segment_pair + { + /* Size of static segment. */ + nls_uint32 segsize; + /* Reference to system dependent string segment, or ~0 at the end. */ + nls_uint32 sysdepref; + } segments[1]; +}; + +/* Marker for the end of the segments[] array. This has the value 0xFFFFFFFF, + regardless whether 'int' is 16 bit, 32 bit, or 64 bit. */ +#define SEGMENTS_END ((nls_uint32) ~0) + +/* @@ begin of epilog @@ */ + +#endif /* gettext.h */ diff --git a/utshell-0.5.0/lib/intl/hash-string.h b/utshell-0.5.0/lib/intl/hash-string.h new file mode 100644 index 00000000..b5a7d413 --- /dev/null +++ b/utshell-0.5.0/lib/intl/hash-string.h @@ -0,0 +1,61 @@ +/* hash-string.h - Description of GNU message catalog format: string hashing function. */ + +/* Copyright (C) 1995, 1997, 1998, 2000, 2001, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif +#endif + +/* We assume to have `unsigned long int' value with at least 32 bits. */ +#define HASHWORDBITS 32 + + +/* Defines the so called `hashpjw' function by P.J. Weinberger + [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + 1986, 1987 Bell Telephone Laboratories, Inc.] */ +static unsigned long int hash_string PARAMS ((const char *__str_param)); + +static inline unsigned long int +hash_string (str_param) + const char *str_param; +{ + unsigned long int hval, g; + const char *str = str_param; + + /* Compute the hash value for the given string. */ + hval = 0; + while (*str != '\0') + { + hval <<= 4; + hval += (unsigned long int) *str++; + g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); + if (g != 0) + { + hval ^= g >> (HASHWORDBITS - 8); + hval ^= g; + } + } + return hval; +} diff --git a/utshell-0.5.0/lib/intl/intl-compat.c b/utshell-0.5.0/lib/intl/intl-compat.c new file mode 100644 index 00000000..7f323499 --- /dev/null +++ b/utshell-0.5.0/lib/intl/intl-compat.c @@ -0,0 +1,152 @@ +/* intl-compat.c - Stub functions to call gettext functions from GNU gettext library. */ + +/* Copyright (C) 1995, 2000-2003, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +/* This file redirects the gettext functions (without prefix) to those + defined in the included GNU libintl library (with "libintl_" prefix). + It is compiled into libintl in order to make the AM_GNU_GETTEXT test + of gettext <= 0.11.2 work with the libintl library >= 0.11.3 which + has the redirections primarily in the include file. + It is also compiled into libgnuintl so that libgnuintl.so can be used + as LD_PRELOADable library on glibc systems, to provide the extra + features that the functions in the libc don't have (namely, logging). */ + + +#undef gettext +#undef dgettext +#undef dcgettext +#undef ngettext +#undef dngettext +#undef dcngettext +#undef textdomain +#undef bindtextdomain +#undef bind_textdomain_codeset + + +/* When building a DLL, we must export some functions. Note that because + the functions are only defined for binary backward compatibility, we + don't need to use __declspec(dllimport) in any case. */ +#if defined _MSC_VER && BUILDING_DLL +# define DLL_EXPORTED __declspec(dllexport) +#else +# define DLL_EXPORTED +#endif + + +DLL_EXPORTED +char * +gettext (msgid) + const char *msgid; +{ + return libintl_gettext (msgid); +} + + +DLL_EXPORTED +char * +dgettext (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return libintl_dgettext (domainname, msgid); +} + + +DLL_EXPORTED +char * +dcgettext (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ + return libintl_dcgettext (domainname, msgid, category); +} + + +DLL_EXPORTED +char * +ngettext (msgid1, msgid2, n) + const char *msgid1; + const char *msgid2; + unsigned long int n; +{ + return libintl_ngettext (msgid1, msgid2, n); +} + + +DLL_EXPORTED +char * +dngettext (domainname, msgid1, msgid2, n) + const char *domainname; + const char *msgid1; + const char *msgid2; + unsigned long int n; +{ + return libintl_dngettext (domainname, msgid1, msgid2, n); +} + + +DLL_EXPORTED +char * +dcngettext (domainname, msgid1, msgid2, n, category) + const char *domainname; + const char *msgid1; + const char *msgid2; + unsigned long int n; + int category; +{ + return libintl_dcngettext (domainname, msgid1, msgid2, n, category); +} + + +DLL_EXPORTED +char * +textdomain (domainname) + const char *domainname; +{ + return libintl_textdomain (domainname); +} + + +DLL_EXPORTED +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ + return libintl_bindtextdomain (domainname, dirname); +} + + +DLL_EXPORTED +char * +bind_textdomain_codeset (domainname, codeset) + const char *domainname; + const char *codeset; +{ + return libintl_bind_textdomain_codeset (domainname, codeset); +} diff --git a/utshell-0.5.0/lib/intl/l10nflist.c b/utshell-0.5.0/lib/intl/l10nflist.c new file mode 100644 index 00000000..4ce284a2 --- /dev/null +++ b/utshell-0.5.0/lib/intl/l10nflist.c @@ -0,0 +1,459 @@ +/* l10nflist.c - make localization file list. */ + +/* Copyright (C) 1995-1999, 2000, 2001, 2002, 2005-2009 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Tell glibc's to provide a prototype for stpcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#if defined _LIBC || defined HAVE_ARGZ_H +# include +#endif +#include +#include +#include + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# ifndef stpcpy +# define stpcpy(dest, src) __stpcpy(dest, src) +# endif +#else +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +#endif + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, + it may be concatenated to a directory pathname. + */ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) +#endif + +/* Define function which are usually not available. */ + +#if !defined _LIBC && !defined HAVE___ARGZ_COUNT +/* Returns the number of strings in ARGZ. */ +static size_t argz_count__ PARAMS ((const char *argz, size_t len)); + +static size_t +argz_count__ (argz, len) + const char *argz; + size_t len; +{ + size_t count = 0; + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len + 1; + len -= part_len + 1; + count++; + } + return count; +} +# undef __argz_count +# define __argz_count(argz, len) argz_count__ (argz, len) +#else +# ifdef _LIBC +# define __argz_count(argz, len) INTUSE(__argz_count) (argz, len) +# endif +#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ + +#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY +/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's + except the last into the character SEP. */ +static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); + +static void +argz_stringify__ (argz, len, sep) + char *argz; + size_t len; + int sep; +{ + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len; + len -= part_len + 1; + if (len > 0) + *argz++ = sep; + } +} +# undef __argz_stringify +# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) +#else +# ifdef _LIBC +# define __argz_stringify(argz, len, sep) \ + INTUSE(__argz_stringify) (argz, len, sep) +# endif +#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ + +#if !defined _LIBC && !defined HAVE___ARGZ_NEXT +static char *argz_next__ PARAMS ((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next__ (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + if (entry) + { + if (entry < argz + argz_len) + entry = strchr (entry, '\0') + 1; + + return entry >= argz + argz_len ? NULL : (char *) entry; + } + else + if (argz_len > 0) + return argz; + else + return 0; +} +# undef __argz_next +# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) +#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ + + +/* Return number of bits set in X. */ +static int pop PARAMS ((int x)); + +static inline int +pop (x) + int x; +{ + /* We assume that no more than 16 bits are used. */ + x = ((x & ~0x5555) >> 1) + (x & 0x5555); + x = ((x & ~0x3333) >> 2) + (x & 0x3333); + x = ((x >> 4) + x) & 0x0f0f; + x = ((x >> 8) + x) & 0xff; + + return x; +} + + +struct loaded_l10nfile * +_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, + territory, codeset, normalized_codeset, modifier, special, + sponsor, revision, filename, do_allocate) + struct loaded_l10nfile **l10nfile_list; + const char *dirlist; + size_t dirlist_len; + int mask; + const char *language; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *modifier; + const char *special; + const char *sponsor; + const char *revision; + const char *filename; + int do_allocate; +{ + char *abs_filename; + struct loaded_l10nfile **lastp; + struct loaded_l10nfile *retval; + char *cp; + size_t dirlist_count; + size_t entries; + int cnt; + + /* If LANGUAGE contains an absolute directory specification, we ignore + DIRLIST. */ + if (IS_ABSOLUTE_PATH (language)) + dirlist_len = 0; + + /* Allocate room for the full file name. */ + abs_filename = (char *) malloc (dirlist_len + + strlen (language) + + ((mask & TERRITORY) != 0 + ? strlen (territory) + 1 : 0) + + ((mask & XPG_CODESET) != 0 + ? strlen (codeset) + 1 : 0) + + ((mask & XPG_NORM_CODESET) != 0 + ? strlen (normalized_codeset) + 1 : 0) + + (((mask & XPG_MODIFIER) != 0 + || (mask & CEN_AUDIENCE) != 0) + ? strlen (modifier) + 1 : 0) + + ((mask & CEN_SPECIAL) != 0 + ? strlen (special) + 1 : 0) + + (((mask & CEN_SPONSOR) != 0 + || (mask & CEN_REVISION) != 0) + ? (1 + ((mask & CEN_SPONSOR) != 0 + ? strlen (sponsor) : 0) + + ((mask & CEN_REVISION) != 0 + ? strlen (revision) + 1 : 0)) : 0) + + 1 + strlen (filename) + 1); + + if (abs_filename == NULL) + return NULL; + + /* Construct file name. */ + cp = abs_filename; + if (dirlist_len > 0) + { + memcpy (cp, dirlist, dirlist_len); + __argz_stringify (cp, dirlist_len, PATH_SEPARATOR); + cp += dirlist_len; + cp[-1] = '/'; + } + + cp = stpcpy (cp, language); + + if ((mask & TERRITORY) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, territory); + } + if ((mask & XPG_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, codeset); + } + if ((mask & XPG_NORM_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, normalized_codeset); + } + if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) + { + /* This component can be part of both syntaxes but has different + leading characters. For CEN we use `+', else `@'. */ + *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; + cp = stpcpy (cp, modifier); + } + if ((mask & CEN_SPECIAL) != 0) + { + *cp++ = '+'; + cp = stpcpy (cp, special); + } + if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) + { + *cp++ = ','; + if ((mask & CEN_SPONSOR) != 0) + cp = stpcpy (cp, sponsor); + if ((mask & CEN_REVISION) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, revision); + } + } + + *cp++ = '/'; + stpcpy (cp, filename); + + /* Look in list of already loaded domains whether it is already + available. */ + lastp = l10nfile_list; + for (retval = *l10nfile_list; retval != NULL; retval = retval->next) + if (retval->filename != NULL) + { + int compare = strcmp (retval->filename, abs_filename); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It's not in the list. */ + retval = NULL; + break; + } + + lastp = &retval->next; + } + + if (retval != NULL || do_allocate == 0) + { + free (abs_filename); + return retval; + } + + dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1); + + /* Allocate a new loaded_l10nfile. */ + retval = + (struct loaded_l10nfile *) + malloc (sizeof (*retval) + + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0)) + * sizeof (struct loaded_l10nfile *))); + if (retval == NULL) + { + free (abs_filename); + return NULL; + } + + retval->filename = abs_filename; + + /* We set retval->data to NULL here; it is filled in later. + Setting retval->decided to 1 here means that retval does not + correspond to a real file (dirlist_count > 1) or is not worth + looking up (if an unnormalized codeset was specified). */ + retval->decided = (dirlist_count > 1 + || ((mask & XPG_CODESET) != 0 + && (mask & XPG_NORM_CODESET) != 0)); + retval->data = NULL; + + retval->next = *lastp; + *lastp = retval; + + entries = 0; + /* Recurse to fill the inheritance list of RETVAL. + If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL + entry does not correspond to a real file; retval->filename contains + colons. In this case we loop across all elements of DIRLIST and + across all bit patterns dominated by MASK. + If the DIRLIST is a single directory or entirely redundant (i.e. + DIRLIST_COUNT == 1), we loop across all bit patterns dominated by + MASK, excluding MASK itself. + In either case, we loop down from MASK to 0. This has the effect + that the extra bits in the locale name are dropped in this order: + first the modifier, then the territory, then the codeset, then the + normalized_codeset. */ + for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt) + if ((cnt & ~mask) == 0 + && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) + && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) + { + if (dirlist_count > 1) + { + /* Iterate over all elements of the DIRLIST. */ + char *dir = NULL; + + while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) + != NULL) + retval->successor[entries++] + = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, + cnt, language, territory, codeset, + normalized_codeset, modifier, special, + sponsor, revision, filename, 1); + } + else + retval->successor[entries++] + = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, + cnt, language, territory, codeset, + normalized_codeset, modifier, special, + sponsor, revision, filename, 1); + } + retval->successor[entries] = NULL; + + return retval; +} + +/* Normalize codeset name. There is no standard for the codeset + names. Normalization allows the user to use any of the common + names. The return value is dynamically allocated and has to be + freed by the caller. */ +const char * +_nl_normalize_codeset (codeset, name_len) + const char *codeset; + size_t name_len; +{ + int len = 0; + int only_digit = 1; + char *retval; + char *wp; + size_t cnt; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalnum ((unsigned char) codeset[cnt])) + { + ++len; + + if (isalpha ((unsigned char) codeset[cnt])) + only_digit = 0; + } + + retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); + + if (retval != NULL) + { + if (only_digit) + wp = stpcpy (retval, "iso"); + else + wp = retval; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalpha ((unsigned char) codeset[cnt])) + *wp++ = tolower ((unsigned char) codeset[cnt]); + else if (isdigit ((unsigned char) codeset[cnt])) + *wp++ = codeset[cnt]; + + *wp = '\0'; + } + + return (const char *) retval; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/utshell-0.5.0/lib/intl/libgnuintl.h.in b/utshell-0.5.0/lib/intl/libgnuintl.h.in new file mode 100644 index 00000000..14f9cf97 --- /dev/null +++ b/utshell-0.5.0/lib/intl/libgnuintl.h.in @@ -0,0 +1,311 @@ +/* libgnuintl.h - Message catalogs for internationalization. */ + +/* Copyright (C) 1995-1997, 2000-2003, 2004-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _LIBINTL_H +#define _LIBINTL_H 1 + +#include + +/* The LC_MESSAGES locale category is the category used by the functions + gettext() and dgettext(). It is specified in POSIX, but not in ANSI C. + On systems that don't define it, use an arbitrary value instead. + On Solaris, defines __LOCALE_H (or _LOCALE_H in Solaris 2.5) + then includes (i.e. this file!) and then only defines + LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES + in this case. */ +#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun)) +# define LC_MESSAGES 1729 +#endif + +/* We define an additional symbol to signal that we use the GNU + implementation of gettext. */ +#define __USE_GNU_GETTEXT 1 + +/* Provide information about the supported file formats. Returns the + maximum minor revision number supported for a given major revision. */ +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \ + ((major) == 0 ? 1 : -1) + +/* Resolve a platform specific conflict on DJGPP. GNU gettext takes + precedence over _conio_gettext. */ +#ifdef __DJGPP__ +# undef gettext +#endif + +/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers + used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */ +#ifndef _INTL_PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define _INTL_PARAMS(args) args +# else +# define _INTL_PARAMS(args) () +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* We redirect the functions to those prefixed with "libintl_". This is + necessary, because some systems define gettext/textdomain/... in the C + library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer). + If we used the unprefixed names, there would be cases where the + definition in the C library would override the one in the libintl.so + shared library. Recall that on ELF systems, the symbols are looked + up in the following order: + 1. in the executable, + 2. in the shared libraries specified on the link command line, in order, + 3. in the dependencies of the shared libraries specified on the link + command line, + 4. in the dlopen()ed shared libraries, in the order in which they were + dlopen()ed. + The definition in the C library would override the one in libintl.so if + either + * -lc is given on the link command line and -lintl isn't, or + * -lc is given on the link command line before -lintl, or + * libintl.so is a dependency of a dlopen()ed shared library but not + linked to the executable at link time. + Since Solaris gettext() behaves differently than GNU gettext(), this + would be unacceptable. + + The redirection happens by default through macros in C, so that &gettext + is independent of the compilation unit, but through inline functions in + C++, in order not to interfere with the name mangling of class fields or + class methods called 'gettext'. */ + +/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS. + If he doesn't, we choose the method. A third possible method is + _INTL_REDIRECT_ASM, supported only by GCC. */ +#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS) +# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus) +# define _INTL_REDIRECT_ASM +# else +# ifdef __cplusplus +# define _INTL_REDIRECT_INLINE +# else +# define _INTL_REDIRECT_MACROS +# endif +# endif +#endif +/* Auxiliary macros. */ +#ifdef _INTL_REDIRECT_ASM +# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname)) +# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring +# define _INTL_STRINGIFY(prefix) #prefix +#else +# define _INTL_ASM(cname) +#endif + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_gettext (const char *__msgid); +static inline char *gettext (const char *__msgid) +{ + return libintl_gettext (__msgid); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define gettext libintl_gettext +#endif +extern char *gettext _INTL_PARAMS ((const char *__msgid)) + _INTL_ASM (libintl_gettext); +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current + LC_MESSAGES locale. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_dgettext (const char *__domainname, const char *__msgid); +static inline char *dgettext (const char *__domainname, const char *__msgid) +{ + return libintl_dgettext (__domainname, __msgid); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define dgettext libintl_dgettext +#endif +extern char *dgettext _INTL_PARAMS ((const char *__domainname, + const char *__msgid)) + _INTL_ASM (libintl_dgettext); +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_dcgettext (const char *__domainname, const char *__msgid, + int __category); +static inline char *dcgettext (const char *__domainname, const char *__msgid, + int __category) +{ + return libintl_dcgettext (__domainname, __msgid, __category); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define dcgettext libintl_dcgettext +#endif +extern char *dcgettext _INTL_PARAMS ((const char *__domainname, + const char *__msgid, + int __category)) + _INTL_ASM (libintl_dcgettext); +#endif + + +/* Similar to `gettext' but select the plural form corresponding to the + number N. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2, + unsigned long int __n); +static inline char *ngettext (const char *__msgid1, const char *__msgid2, + unsigned long int __n) +{ + return libintl_ngettext (__msgid1, __msgid2, __n); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define ngettext libintl_ngettext +#endif +extern char *ngettext _INTL_PARAMS ((const char *__msgid1, + const char *__msgid2, + unsigned long int __n)) + _INTL_ASM (libintl_ngettext); +#endif + +/* Similar to `dgettext' but select the plural form corresponding to the + number N. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_dngettext (const char *__domainname, const char *__msgid1, + const char *__msgid2, unsigned long int __n); +static inline char *dngettext (const char *__domainname, const char *__msgid1, + const char *__msgid2, unsigned long int __n) +{ + return libintl_dngettext (__domainname, __msgid1, __msgid2, __n); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define dngettext libintl_dngettext +#endif +extern char *dngettext _INTL_PARAMS ((const char *__domainname, + const char *__msgid1, + const char *__msgid2, + unsigned long int __n)) + _INTL_ASM (libintl_dngettext); +#endif + +/* Similar to `dcgettext' but select the plural form corresponding to the + number N. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_dcngettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category); +static inline char *dcngettext (const char *__domainname, + const char *__msgid1, const char *__msgid2, + unsigned long int __n, int __category) +{ + return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define dcngettext libintl_dcngettext +#endif +extern char *dcngettext _INTL_PARAMS ((const char *__domainname, + const char *__msgid1, + const char *__msgid2, + unsigned long int __n, + int __category)) + _INTL_ASM (libintl_dcngettext); +#endif + + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_textdomain (const char *__domainname); +static inline char *textdomain (const char *__domainname) +{ + return libintl_textdomain (__domainname); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define textdomain libintl_textdomain +#endif +extern char *textdomain _INTL_PARAMS ((const char *__domainname)) + _INTL_ASM (libintl_textdomain); +#endif + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_bindtextdomain (const char *__domainname, + const char *__dirname); +static inline char *bindtextdomain (const char *__domainname, + const char *__dirname) +{ + return libintl_bindtextdomain (__domainname, __dirname); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define bindtextdomain libintl_bindtextdomain +#endif +extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname, + const char *__dirname)) + _INTL_ASM (libintl_bindtextdomain); +#endif + +/* Specify the character encoding in which the messages from the + DOMAINNAME message catalog will be returned. */ +#ifdef _INTL_REDIRECT_INLINE +extern char *libintl_bind_textdomain_codeset (const char *__domainname, + const char *__codeset); +static inline char *bind_textdomain_codeset (const char *__domainname, + const char *__codeset) +{ + return libintl_bind_textdomain_codeset (__domainname, __codeset); +} +#else +#ifdef _INTL_REDIRECT_MACROS +# define bind_textdomain_codeset libintl_bind_textdomain_codeset +#endif +extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname, + const char *__codeset)) + _INTL_ASM (libintl_bind_textdomain_codeset); +#endif + + +/* Support for relocatable packages. */ + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +#define libintl_set_relocation_prefix libintl_set_relocation_prefix +extern void + libintl_set_relocation_prefix _INTL_PARAMS ((const char *orig_prefix, + const char *curr_prefix)); + + +#ifdef __cplusplus +} +#endif + +#endif /* libintl.h */ diff --git a/utshell-0.5.0/lib/intl/loadinfo.h b/utshell-0.5.0/lib/intl/loadinfo.h new file mode 100644 index 00000000..d06a2773 --- /dev/null +++ b/utshell-0.5.0/lib/intl/loadinfo.h @@ -0,0 +1,159 @@ +/* loadinfo.c */ + +/* Copyright (C) 1996-1999, 2000-2002, 2005-2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _LOADINFO_H +#define _LOADINFO_H 1 + +/* Declarations of locale dependent catalog lookup functions. + Implemented in + + localealias.c Possibly replace a locale name by another. + explodename.c Split a locale name into its various fields. + l10nflist.c Generate a list of filenames of possible message catalogs. + finddomain.c Find and open the relevant message catalogs. + + The main function _nl_find_domain() in finddomain.c is declared + in gettextP.h. + */ + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +/* Tell the compiler when a conditional or integer expression is + almost always true or almost always false. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + +/* Separator in PATH like lists of pathnames. */ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define PATH_SEPARATOR ';' +#else + /* Unix */ +# define PATH_SEPARATOR ':' +#endif + +/* Encoding of locale name parts. */ +#define CEN_REVISION 1 +#define CEN_SPONSOR 2 +#define CEN_SPECIAL 4 +#define XPG_NORM_CODESET 8 +#define XPG_CODESET 16 +#define TERRITORY 32 +#define CEN_AUDIENCE 64 +#define XPG_MODIFIER 128 + +#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) +#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) + + +struct loaded_l10nfile +{ + const char *filename; + int decided; + + const void *data; + + struct loaded_l10nfile *next; + struct loaded_l10nfile *successor[1]; +}; + + +/* Normalize codeset name. There is no standard for the codeset + names. Normalization allows the user to use any of the common + names. The return value is dynamically allocated and has to be + freed by the caller. */ +extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, + size_t name_len)); + +/* Lookup a locale dependent file. + *L10NFILE_LIST denotes a pool of lookup results of locale dependent + files of the same kind, sorted in decreasing order of ->filename. + DIRLIST and DIRLIST_LEN are an argz list of directories in which to + look, containing at least one directory (i.e. DIRLIST_LEN > 0). + MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER, + SPECIAL, SPONSOR, REVISION are the pieces of the locale name, as + produced by _nl_explode_name(). FILENAME is the filename suffix. + The return value is the lookup result, either found in *L10NFILE_LIST, + or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL. + If the return value is non-NULL, it is added to *L10NFILE_LIST, and + its ->next field denotes the chaining inside *L10NFILE_LIST, and + furthermore its ->successor[] field contains a list of other lookup + results from which this lookup result inherits. */ +extern struct loaded_l10nfile * +_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, + const char *dirlist, size_t dirlist_len, int mask, + const char *language, const char *territory, + const char *codeset, + const char *normalized_codeset, + const char *modifier, const char *special, + const char *sponsor, const char *revision, + const char *filename, int do_allocate)); + +/* Lookup the real locale name for a locale alias NAME, or NULL if + NAME is not a locale alias (but possibly a real locale name). + The return value is statically allocated and must not be freed. */ +extern const char *_nl_expand_alias PARAMS ((const char *name)); + +/* Split a locale name NAME into its pieces: language, modifier, + territory, codeset, special, sponsor, revision. + NAME gets destructively modified: NUL bytes are inserted here and + there. *LANGUAGE gets assigned NAME. Each of *MODIFIER, *TERRITORY, + *CODESET, *SPECIAL, *SPONSOR, *REVISION gets assigned either a + pointer into the old NAME string, or NULL. *NORMALIZED_CODESET + gets assigned the expanded *CODESET, if it is different from *CODESET; + this one is dynamically allocated and has to be freed by the caller. + The return value is a bitmask, where each bit corresponds to one + filled-in value: + XPG_MODIFIER, CEN_AUDIENCE for *MODIFIER, + TERRITORY for *TERRITORY, + XPG_CODESET for *CODESET, + XPG_NORM_CODESET for *NORMALIZED_CODESET, + CEN_SPECIAL for *SPECIAL, + CEN_SPONSOR for *SPONSOR, + CEN_REVISION for *REVISION. + */ +extern int _nl_explode_name PARAMS ((char *name, const char **language, + const char **modifier, + const char **territory, + const char **codeset, + const char **normalized_codeset, + const char **special, + const char **sponsor, + const char **revision)); + +/* Split a locale name NAME into a leading language part and all the + rest. Return a pointer to the first character after the language, + i.e. to the first byte of the rest. */ +extern char *_nl_find_language PARAMS ((const char *name)); + +#endif /* loadinfo.h */ diff --git a/utshell-0.5.0/lib/intl/loadmsgcat.c b/utshell-0.5.0/lib/intl/loadmsgcat.c new file mode 100644 index 00000000..adbd7b4f --- /dev/null +++ b/utshell-0.5.0/lib/intl/loadmsgcat.c @@ -0,0 +1,1336 @@ +/* loadmsgcat.c - Load needed message catalogs. */ + +/* Copyright (C) 1995-1999, 2000-2003, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Tell glibc's to provide a prototype for mempcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +# undef alloca +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +#include +#include + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#ifdef _LIBC +# include +# include +#endif + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || (defined _LIBC && defined _POSIX_MAPPED_FILES) +# include +# undef HAVE_MMAP +# define HAVE_MMAP 1 +#else +# undef HAVE_MMAP +#endif + +#if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC +# include +#endif +#if defined HAVE_INTTYPES_H || defined _LIBC +# include +#endif + +#include "gmo.h" +#include "gettextP.h" +#include "hash-string.h" +#include "plural-exp.h" + +#ifdef _LIBC +# include "../locale/localeinfo.h" +#endif + +/* Provide fallback values for macros that ought to be defined in . + Note that our fallback values need not be literal strings, because we don't + use them with preprocessor string concatenation. */ +#if !defined PRId8 || PRI_MACROS_BROKEN +# undef PRId8 +# define PRId8 "d" +#endif +#if !defined PRIi8 || PRI_MACROS_BROKEN +# undef PRIi8 +# define PRIi8 "i" +#endif +#if !defined PRIo8 || PRI_MACROS_BROKEN +# undef PRIo8 +# define PRIo8 "o" +#endif +#if !defined PRIu8 || PRI_MACROS_BROKEN +# undef PRIu8 +# define PRIu8 "u" +#endif +#if !defined PRIx8 || PRI_MACROS_BROKEN +# undef PRIx8 +# define PRIx8 "x" +#endif +#if !defined PRIX8 || PRI_MACROS_BROKEN +# undef PRIX8 +# define PRIX8 "X" +#endif +#if !defined PRId16 || PRI_MACROS_BROKEN +# undef PRId16 +# define PRId16 "d" +#endif +#if !defined PRIi16 || PRI_MACROS_BROKEN +# undef PRIi16 +# define PRIi16 "i" +#endif +#if !defined PRIo16 || PRI_MACROS_BROKEN +# undef PRIo16 +# define PRIo16 "o" +#endif +#if !defined PRIu16 || PRI_MACROS_BROKEN +# undef PRIu16 +# define PRIu16 "u" +#endif +#if !defined PRIx16 || PRI_MACROS_BROKEN +# undef PRIx16 +# define PRIx16 "x" +#endif +#if !defined PRIX16 || PRI_MACROS_BROKEN +# undef PRIX16 +# define PRIX16 "X" +#endif +#if !defined PRId32 || PRI_MACROS_BROKEN +# undef PRId32 +# define PRId32 "d" +#endif +#if !defined PRIi32 || PRI_MACROS_BROKEN +# undef PRIi32 +# define PRIi32 "i" +#endif +#if !defined PRIo32 || PRI_MACROS_BROKEN +# undef PRIo32 +# define PRIo32 "o" +#endif +#if !defined PRIu32 || PRI_MACROS_BROKEN +# undef PRIu32 +# define PRIu32 "u" +#endif +#if !defined PRIx32 || PRI_MACROS_BROKEN +# undef PRIx32 +# define PRIx32 "x" +#endif +#if !defined PRIX32 || PRI_MACROS_BROKEN +# undef PRIX32 +# define PRIX32 "X" +#endif +#if !defined PRId64 || PRI_MACROS_BROKEN +# undef PRId64 +# define PRId64 (sizeof (long) == 8 ? "ld" : "lld") +#endif +#if !defined PRIi64 || PRI_MACROS_BROKEN +# undef PRIi64 +# define PRIi64 (sizeof (long) == 8 ? "li" : "lli") +#endif +#if !defined PRIo64 || PRI_MACROS_BROKEN +# undef PRIo64 +# define PRIo64 (sizeof (long) == 8 ? "lo" : "llo") +#endif +#if !defined PRIu64 || PRI_MACROS_BROKEN +# undef PRIu64 +# define PRIu64 (sizeof (long) == 8 ? "lu" : "llu") +#endif +#if !defined PRIx64 || PRI_MACROS_BROKEN +# undef PRIx64 +# define PRIx64 (sizeof (long) == 8 ? "lx" : "llx") +#endif +#if !defined PRIX64 || PRI_MACROS_BROKEN +# undef PRIX64 +# define PRIX64 (sizeof (long) == 8 ? "lX" : "llX") +#endif +#if !defined PRIdLEAST8 || PRI_MACROS_BROKEN +# undef PRIdLEAST8 +# define PRIdLEAST8 "d" +#endif +#if !defined PRIiLEAST8 || PRI_MACROS_BROKEN +# undef PRIiLEAST8 +# define PRIiLEAST8 "i" +#endif +#if !defined PRIoLEAST8 || PRI_MACROS_BROKEN +# undef PRIoLEAST8 +# define PRIoLEAST8 "o" +#endif +#if !defined PRIuLEAST8 || PRI_MACROS_BROKEN +# undef PRIuLEAST8 +# define PRIuLEAST8 "u" +#endif +#if !defined PRIxLEAST8 || PRI_MACROS_BROKEN +# undef PRIxLEAST8 +# define PRIxLEAST8 "x" +#endif +#if !defined PRIXLEAST8 || PRI_MACROS_BROKEN +# undef PRIXLEAST8 +# define PRIXLEAST8 "X" +#endif +#if !defined PRIdLEAST16 || PRI_MACROS_BROKEN +# undef PRIdLEAST16 +# define PRIdLEAST16 "d" +#endif +#if !defined PRIiLEAST16 || PRI_MACROS_BROKEN +# undef PRIiLEAST16 +# define PRIiLEAST16 "i" +#endif +#if !defined PRIoLEAST16 || PRI_MACROS_BROKEN +# undef PRIoLEAST16 +# define PRIoLEAST16 "o" +#endif +#if !defined PRIuLEAST16 || PRI_MACROS_BROKEN +# undef PRIuLEAST16 +# define PRIuLEAST16 "u" +#endif +#if !defined PRIxLEAST16 || PRI_MACROS_BROKEN +# undef PRIxLEAST16 +# define PRIxLEAST16 "x" +#endif +#if !defined PRIXLEAST16 || PRI_MACROS_BROKEN +# undef PRIXLEAST16 +# define PRIXLEAST16 "X" +#endif +#if !defined PRIdLEAST32 || PRI_MACROS_BROKEN +# undef PRIdLEAST32 +# define PRIdLEAST32 "d" +#endif +#if !defined PRIiLEAST32 || PRI_MACROS_BROKEN +# undef PRIiLEAST32 +# define PRIiLEAST32 "i" +#endif +#if !defined PRIoLEAST32 || PRI_MACROS_BROKEN +# undef PRIoLEAST32 +# define PRIoLEAST32 "o" +#endif +#if !defined PRIuLEAST32 || PRI_MACROS_BROKEN +# undef PRIuLEAST32 +# define PRIuLEAST32 "u" +#endif +#if !defined PRIxLEAST32 || PRI_MACROS_BROKEN +# undef PRIxLEAST32 +# define PRIxLEAST32 "x" +#endif +#if !defined PRIXLEAST32 || PRI_MACROS_BROKEN +# undef PRIXLEAST32 +# define PRIXLEAST32 "X" +#endif +#if !defined PRIdLEAST64 || PRI_MACROS_BROKEN +# undef PRIdLEAST64 +# define PRIdLEAST64 PRId64 +#endif +#if !defined PRIiLEAST64 || PRI_MACROS_BROKEN +# undef PRIiLEAST64 +# define PRIiLEAST64 PRIi64 +#endif +#if !defined PRIoLEAST64 || PRI_MACROS_BROKEN +# undef PRIoLEAST64 +# define PRIoLEAST64 PRIo64 +#endif +#if !defined PRIuLEAST64 || PRI_MACROS_BROKEN +# undef PRIuLEAST64 +# define PRIuLEAST64 PRIu64 +#endif +#if !defined PRIxLEAST64 || PRI_MACROS_BROKEN +# undef PRIxLEAST64 +# define PRIxLEAST64 PRIx64 +#endif +#if !defined PRIXLEAST64 || PRI_MACROS_BROKEN +# undef PRIXLEAST64 +# define PRIXLEAST64 PRIX64 +#endif +#if !defined PRIdFAST8 || PRI_MACROS_BROKEN +# undef PRIdFAST8 +# define PRIdFAST8 "d" +#endif +#if !defined PRIiFAST8 || PRI_MACROS_BROKEN +# undef PRIiFAST8 +# define PRIiFAST8 "i" +#endif +#if !defined PRIoFAST8 || PRI_MACROS_BROKEN +# undef PRIoFAST8 +# define PRIoFAST8 "o" +#endif +#if !defined PRIuFAST8 || PRI_MACROS_BROKEN +# undef PRIuFAST8 +# define PRIuFAST8 "u" +#endif +#if !defined PRIxFAST8 || PRI_MACROS_BROKEN +# undef PRIxFAST8 +# define PRIxFAST8 "x" +#endif +#if !defined PRIXFAST8 || PRI_MACROS_BROKEN +# undef PRIXFAST8 +# define PRIXFAST8 "X" +#endif +#if !defined PRIdFAST16 || PRI_MACROS_BROKEN +# undef PRIdFAST16 +# define PRIdFAST16 "d" +#endif +#if !defined PRIiFAST16 || PRI_MACROS_BROKEN +# undef PRIiFAST16 +# define PRIiFAST16 "i" +#endif +#if !defined PRIoFAST16 || PRI_MACROS_BROKEN +# undef PRIoFAST16 +# define PRIoFAST16 "o" +#endif +#if !defined PRIuFAST16 || PRI_MACROS_BROKEN +# undef PRIuFAST16 +# define PRIuFAST16 "u" +#endif +#if !defined PRIxFAST16 || PRI_MACROS_BROKEN +# undef PRIxFAST16 +# define PRIxFAST16 "x" +#endif +#if !defined PRIXFAST16 || PRI_MACROS_BROKEN +# undef PRIXFAST16 +# define PRIXFAST16 "X" +#endif +#if !defined PRIdFAST32 || PRI_MACROS_BROKEN +# undef PRIdFAST32 +# define PRIdFAST32 "d" +#endif +#if !defined PRIiFAST32 || PRI_MACROS_BROKEN +# undef PRIiFAST32 +# define PRIiFAST32 "i" +#endif +#if !defined PRIoFAST32 || PRI_MACROS_BROKEN +# undef PRIoFAST32 +# define PRIoFAST32 "o" +#endif +#if !defined PRIuFAST32 || PRI_MACROS_BROKEN +# undef PRIuFAST32 +# define PRIuFAST32 "u" +#endif +#if !defined PRIxFAST32 || PRI_MACROS_BROKEN +# undef PRIxFAST32 +# define PRIxFAST32 "x" +#endif +#if !defined PRIXFAST32 || PRI_MACROS_BROKEN +# undef PRIXFAST32 +# define PRIXFAST32 "X" +#endif +#if !defined PRIdFAST64 || PRI_MACROS_BROKEN +# undef PRIdFAST64 +# define PRIdFAST64 PRId64 +#endif +#if !defined PRIiFAST64 || PRI_MACROS_BROKEN +# undef PRIiFAST64 +# define PRIiFAST64 PRIi64 +#endif +#if !defined PRIoFAST64 || PRI_MACROS_BROKEN +# undef PRIoFAST64 +# define PRIoFAST64 PRIo64 +#endif +#if !defined PRIuFAST64 || PRI_MACROS_BROKEN +# undef PRIuFAST64 +# define PRIuFAST64 PRIu64 +#endif +#if !defined PRIxFAST64 || PRI_MACROS_BROKEN +# undef PRIxFAST64 +# define PRIxFAST64 PRIx64 +#endif +#if !defined PRIXFAST64 || PRI_MACROS_BROKEN +# undef PRIXFAST64 +# define PRIXFAST64 PRIX64 +#endif +#if !defined PRIdMAX || PRI_MACROS_BROKEN +# undef PRIdMAX +# define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld") +#endif +#if !defined PRIiMAX || PRI_MACROS_BROKEN +# undef PRIiMAX +# define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli") +#endif +#if !defined PRIoMAX || PRI_MACROS_BROKEN +# undef PRIoMAX +# define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo") +#endif +#if !defined PRIuMAX || PRI_MACROS_BROKEN +# undef PRIuMAX +# define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu") +#endif +#if !defined PRIxMAX || PRI_MACROS_BROKEN +# undef PRIxMAX +# define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx") +#endif +#if !defined PRIXMAX || PRI_MACROS_BROKEN +# undef PRIXMAX +# define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX") +#endif +#if !defined PRIdPTR || PRI_MACROS_BROKEN +# undef PRIdPTR +# define PRIdPTR \ + (sizeof (void *) == sizeof (long) ? "ld" : \ + sizeof (void *) == sizeof (int) ? "d" : \ + "lld") +#endif +#if !defined PRIiPTR || PRI_MACROS_BROKEN +# undef PRIiPTR +# define PRIiPTR \ + (sizeof (void *) == sizeof (long) ? "li" : \ + sizeof (void *) == sizeof (int) ? "i" : \ + "lli") +#endif +#if !defined PRIoPTR || PRI_MACROS_BROKEN +# undef PRIoPTR +# define PRIoPTR \ + (sizeof (void *) == sizeof (long) ? "lo" : \ + sizeof (void *) == sizeof (int) ? "o" : \ + "llo") +#endif +#if !defined PRIuPTR || PRI_MACROS_BROKEN +# undef PRIuPTR +# define PRIuPTR \ + (sizeof (void *) == sizeof (long) ? "lu" : \ + sizeof (void *) == sizeof (int) ? "u" : \ + "llu") +#endif +#if !defined PRIxPTR || PRI_MACROS_BROKEN +# undef PRIxPTR +# define PRIxPTR \ + (sizeof (void *) == sizeof (long) ? "lx" : \ + sizeof (void *) == sizeof (int) ? "x" : \ + "llx") +#endif +#if !defined PRIXPTR || PRI_MACROS_BROKEN +# undef PRIXPTR +# define PRIXPTR \ + (sizeof (void *) == sizeof (long) ? "lX" : \ + sizeof (void *) == sizeof (int) ? "X" : \ + "llX") +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ISO C functions. This is required by the standard + because some ISO C functions will require linking with this object + file and the name space must not be polluted. */ +# define open __open +# define close __close +# define read __read +# define mmap __mmap +# define munmap __munmap +#endif + +/* For those losing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +# define freea(p) /* nothing */ +#else +# define alloca(n) malloc (n) +# define freea(p) free (p) +#endif + +/* For systems that distinguish between text and binary I/O. + O_BINARY is usually declared in . */ +#if !defined O_BINARY && defined _O_BINARY + /* For MSC-compatible compilers. */ +# define O_BINARY _O_BINARY +# define O_TEXT _O_TEXT +#endif +#ifdef __BEOS__ + /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ +# undef O_BINARY +# undef O_TEXT +#endif +/* On reasonable systems, binary I/O is the default. */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif + + +/* Prototypes for local functions. Needed to ensure compiler checking of + function argument counts despite of K&R C function definition syntax. */ +static const char *get_sysdep_segment_value PARAMS ((const char *name)); + + +/* We need a sign, whether a new catalog was loaded, which can be associated + with all translations. This is important if the translations are + cached by one of GCC's features. */ +int _nl_msg_cat_cntr; + + +/* Expand a system dependent string segment. Return NULL if unsupported. */ +static const char * +get_sysdep_segment_value (name) + const char *name; +{ + /* Test for an ISO C 99 section 7.8.1 format string directive. + Syntax: + P R I { d | i | o | u | x | X } + { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */ + /* We don't use a table of 14 times 6 'const char *' strings here, because + data relocations cost startup time. */ + if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I') + { + if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u' + || name[3] == 'x' || name[3] == 'X') + { + if (name[4] == '8' && name[5] == '\0') + { + if (name[3] == 'd') + return PRId8; + if (name[3] == 'i') + return PRIi8; + if (name[3] == 'o') + return PRIo8; + if (name[3] == 'u') + return PRIu8; + if (name[3] == 'x') + return PRIx8; + if (name[3] == 'X') + return PRIX8; + abort (); + } + if (name[4] == '1' && name[5] == '6' && name[6] == '\0') + { + if (name[3] == 'd') + return PRId16; + if (name[3] == 'i') + return PRIi16; + if (name[3] == 'o') + return PRIo16; + if (name[3] == 'u') + return PRIu16; + if (name[3] == 'x') + return PRIx16; + if (name[3] == 'X') + return PRIX16; + abort (); + } + if (name[4] == '3' && name[5] == '2' && name[6] == '\0') + { + if (name[3] == 'd') + return PRId32; + if (name[3] == 'i') + return PRIi32; + if (name[3] == 'o') + return PRIo32; + if (name[3] == 'u') + return PRIu32; + if (name[3] == 'x') + return PRIx32; + if (name[3] == 'X') + return PRIX32; + abort (); + } + if (name[4] == '6' && name[5] == '4' && name[6] == '\0') + { + if (name[3] == 'd') + return PRId64; + if (name[3] == 'i') + return PRIi64; + if (name[3] == 'o') + return PRIo64; + if (name[3] == 'u') + return PRIu64; + if (name[3] == 'x') + return PRIx64; + if (name[3] == 'X') + return PRIX64; + abort (); + } + if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A' + && name[7] == 'S' && name[8] == 'T') + { + if (name[9] == '8' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST8; + if (name[3] == 'i') + return PRIiLEAST8; + if (name[3] == 'o') + return PRIoLEAST8; + if (name[3] == 'u') + return PRIuLEAST8; + if (name[3] == 'x') + return PRIxLEAST8; + if (name[3] == 'X') + return PRIXLEAST8; + abort (); + } + if (name[9] == '1' && name[10] == '6' && name[11] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST16; + if (name[3] == 'i') + return PRIiLEAST16; + if (name[3] == 'o') + return PRIoLEAST16; + if (name[3] == 'u') + return PRIuLEAST16; + if (name[3] == 'x') + return PRIxLEAST16; + if (name[3] == 'X') + return PRIXLEAST16; + abort (); + } + if (name[9] == '3' && name[10] == '2' && name[11] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST32; + if (name[3] == 'i') + return PRIiLEAST32; + if (name[3] == 'o') + return PRIoLEAST32; + if (name[3] == 'u') + return PRIuLEAST32; + if (name[3] == 'x') + return PRIxLEAST32; + if (name[3] == 'X') + return PRIXLEAST32; + abort (); + } + if (name[9] == '6' && name[10] == '4' && name[11] == '\0') + { + if (name[3] == 'd') + return PRIdLEAST64; + if (name[3] == 'i') + return PRIiLEAST64; + if (name[3] == 'o') + return PRIoLEAST64; + if (name[3] == 'u') + return PRIuLEAST64; + if (name[3] == 'x') + return PRIxLEAST64; + if (name[3] == 'X') + return PRIXLEAST64; + abort (); + } + } + if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S' + && name[7] == 'T') + { + if (name[8] == '8' && name[9] == '\0') + { + if (name[3] == 'd') + return PRIdFAST8; + if (name[3] == 'i') + return PRIiFAST8; + if (name[3] == 'o') + return PRIoFAST8; + if (name[3] == 'u') + return PRIuFAST8; + if (name[3] == 'x') + return PRIxFAST8; + if (name[3] == 'X') + return PRIXFAST8; + abort (); + } + if (name[8] == '1' && name[9] == '6' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdFAST16; + if (name[3] == 'i') + return PRIiFAST16; + if (name[3] == 'o') + return PRIoFAST16; + if (name[3] == 'u') + return PRIuFAST16; + if (name[3] == 'x') + return PRIxFAST16; + if (name[3] == 'X') + return PRIXFAST16; + abort (); + } + if (name[8] == '3' && name[9] == '2' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdFAST32; + if (name[3] == 'i') + return PRIiFAST32; + if (name[3] == 'o') + return PRIoFAST32; + if (name[3] == 'u') + return PRIuFAST32; + if (name[3] == 'x') + return PRIxFAST32; + if (name[3] == 'X') + return PRIXFAST32; + abort (); + } + if (name[8] == '6' && name[9] == '4' && name[10] == '\0') + { + if (name[3] == 'd') + return PRIdFAST64; + if (name[3] == 'i') + return PRIiFAST64; + if (name[3] == 'o') + return PRIoFAST64; + if (name[3] == 'u') + return PRIuFAST64; + if (name[3] == 'x') + return PRIxFAST64; + if (name[3] == 'X') + return PRIXFAST64; + abort (); + } + } + if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X' + && name[7] == '\0') + { + if (name[3] == 'd') + return PRIdMAX; + if (name[3] == 'i') + return PRIiMAX; + if (name[3] == 'o') + return PRIoMAX; + if (name[3] == 'u') + return PRIuMAX; + if (name[3] == 'x') + return PRIxMAX; + if (name[3] == 'X') + return PRIXMAX; + abort (); + } + if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R' + && name[7] == '\0') + { + if (name[3] == 'd') + return PRIdPTR; + if (name[3] == 'i') + return PRIiPTR; + if (name[3] == 'o') + return PRIoPTR; + if (name[3] == 'u') + return PRIuPTR; + if (name[3] == 'x') + return PRIxPTR; + if (name[3] == 'X') + return PRIXPTR; + abort (); + } + } + } + /* Other system dependent strings are not valid. */ + return NULL; +} + +/* Initialize the codeset dependent parts of an opened message catalog. + Return the header entry. */ +const char * +internal_function +_nl_init_domain_conv (domain_file, domain, domainbinding) + struct loaded_l10nfile *domain_file; + struct loaded_domain *domain; + struct binding *domainbinding; +{ + /* Find out about the character set the file is encoded with. + This can be found (in textual form) in the entry "". If this + entry does not exist or if this does not contain the `charset=' + information, we will assume the charset matches the one the + current locale and we don't have to perform any conversion. */ + char *nullentry; + size_t nullentrylen; + + /* Preinitialize fields, to avoid recursion during _nl_find_msg. */ + domain->codeset_cntr = + (domainbinding != NULL ? domainbinding->codeset_cntr : 0); +#ifdef _LIBC + domain->conv = (__gconv_t) -1; +#else +# if HAVE_ICONV + domain->conv = (iconv_t) -1; +# endif +#endif + domain->conv_tab = NULL; + + /* Get the header entry. */ + nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen); + + if (nullentry != NULL) + { +#if defined _LIBC || HAVE_ICONV + const char *charsetstr; + + charsetstr = strstr (nullentry, "charset="); + if (charsetstr != NULL) + { + size_t len; + char *charset; + const char *outcharset; + + charsetstr += strlen ("charset="); + len = strcspn (charsetstr, " \t\n"); + + charset = (char *) alloca (len + 1); +# if defined _LIBC || HAVE_MEMPCPY + *((char *) mempcpy (charset, charsetstr, len)) = '\0'; +# else + memcpy (charset, charsetstr, len); + charset[len] = '\0'; +# endif + + /* The output charset should normally be determined by the + locale. But sometimes the locale is not used or not correctly + set up, so we provide a possibility for the user to override + this. Moreover, the value specified through + bind_textdomain_codeset overrides both. */ + if (domainbinding != NULL && domainbinding->codeset != NULL) + outcharset = domainbinding->codeset; + else + { + outcharset = getenv ("OUTPUT_CHARSET"); + if (outcharset == NULL || outcharset[0] == '\0') + { +# ifdef _LIBC + outcharset = _NL_CURRENT (LC_CTYPE, CODESET); +# else +# if HAVE_ICONV + extern const char *locale_charset PARAMS ((void)); + outcharset = locale_charset (); +# endif +# endif + } + } + +# ifdef _LIBC + /* We always want to use transliteration. */ + outcharset = norm_add_slashes (outcharset, "TRANSLIT"); + charset = norm_add_slashes (charset, NULL); + if (__gconv_open (outcharset, charset, &domain->conv, + GCONV_AVOID_NOCONV) + != __GCONV_OK) + domain->conv = (__gconv_t) -1; +# else +# if HAVE_ICONV + /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, + we want to use transliteration. */ +# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ + || _LIBICONV_VERSION >= 0x0105 + if (strchr (outcharset, '/') == NULL) + { + char *tmp; + + len = strlen (outcharset); + tmp = (char *) alloca (len + 10 + 1); + memcpy (tmp, outcharset, len); + memcpy (tmp + len, "//TRANSLIT", 10 + 1); + outcharset = tmp; + + domain->conv = iconv_open (outcharset, charset); + + freea (outcharset); + } + else +# endif + domain->conv = iconv_open (outcharset, charset); +# endif +# endif + + freea (charset); + } +#endif /* _LIBC || HAVE_ICONV */ + } + + return nullentry; +} + +/* Frees the codeset dependent parts of an opened message catalog. */ +void +internal_function +_nl_free_domain_conv (domain) + struct loaded_domain *domain; +{ + if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1) + free (domain->conv_tab); + +#ifdef _LIBC + if (domain->conv != (__gconv_t) -1) + __gconv_close (domain->conv); +#else +# if HAVE_ICONV + if (domain->conv != (iconv_t) -1) + iconv_close (domain->conv); +# endif +#endif +} + +/* Load the message catalogs specified by FILENAME. If it is no valid + message catalog do nothing. */ +void +internal_function +_nl_load_domain (domain_file, domainbinding) + struct loaded_l10nfile *domain_file; + struct binding *domainbinding; +{ + int fd; + size_t size; +#ifdef _LIBC + struct stat64 st; +#else + struct stat st; +#endif + struct mo_file_header *data = (struct mo_file_header *) -1; + int use_mmap = 0; + struct loaded_domain *domain; + int revision; + const char *nullentry; + + domain_file->decided = 1; + domain_file->data = NULL; + + /* Note that it would be useless to store domainbinding in domain_file + because domainbinding might be == NULL now but != NULL later (after + a call to bind_textdomain_codeset). */ + + /* If the record does not represent a valid locale the FILENAME + might be NULL. This can happen when according to the given + specification the locale file name is different for XPG and CEN + syntax. */ + if (domain_file->filename == NULL) + return; + + /* Try to open the addressed file. */ + fd = open (domain_file->filename, O_RDONLY | O_BINARY); + if (fd == -1) + return; + + /* We must know about the size of the file. */ + if ( +#ifdef _LIBC + __builtin_expect (fstat64 (fd, &st) != 0, 0) +#else + __builtin_expect (fstat (fd, &st) != 0, 0) +#endif + || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0) + || __builtin_expect (size < sizeof (struct mo_file_header), 0)) + { + /* Something went wrong. */ + close (fd); + return; + } + +#ifdef HAVE_MMAP + /* Now we are ready to load the file. If mmap() is available we try + this first. If not available or it failed we try to load it. */ + data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, + MAP_PRIVATE, fd, 0); + + if (__builtin_expect (data != (struct mo_file_header *) -1, 1)) + { + /* mmap() call was successful. */ + close (fd); + use_mmap = 1; + } +#endif + + /* If the data is not yet available (i.e. mmap'ed) we try to load + it manually. */ + if (data == (struct mo_file_header *) -1) + { + size_t to_read; + char *read_ptr; + + data = (struct mo_file_header *) malloc (size); + if (data == NULL) + { + if (use_mmap == 0) + close (fd); + return; + } + + to_read = size; + read_ptr = (char *) data; + do + { + long int nb = (long int) read (fd, read_ptr, to_read); + if (nb <= 0) + { +#ifdef EINTR + if (nb == -1 && errno == EINTR) + continue; +#endif + close (fd); + return; + } + read_ptr += nb; + to_read -= nb; + } + while (to_read > 0); + + close (fd); + } + + /* Using the magic number we can test whether it really is a message + catalog file. */ + if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED, + 0)) + { + /* The magic number is wrong: not a message catalog file. */ +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + return; + } + + domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); + if (domain == NULL) + { +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + return; + } + domain_file->data = domain; + + domain->data = (char *) data; + domain->use_mmap = use_mmap; + domain->mmap_size = size; + domain->must_swap = data->magic != _MAGIC; + domain->malloced = NULL; + + /* Fill in the information about the available tables. */ + revision = W (domain->must_swap, data->revision); + /* We support only the major revision 0. */ + switch (revision >> 16) + { + case 0: + domain->nstrings = W (domain->must_swap, data->nstrings); + domain->orig_tab = (const struct string_desc *) + ((char *) data + W (domain->must_swap, data->orig_tab_offset)); + domain->trans_tab = (const struct string_desc *) + ((char *) data + W (domain->must_swap, data->trans_tab_offset)); + domain->hash_size = W (domain->must_swap, data->hash_tab_size); + domain->hash_tab = + (domain->hash_size > 2 + ? (const nls_uint32 *) + ((char *) data + W (domain->must_swap, data->hash_tab_offset)) + : NULL); + domain->must_swap_hash_tab = domain->must_swap; + + /* Now dispatch on the minor revision. */ + switch (revision & 0xffff) + { + case 0: + domain->n_sysdep_strings = 0; + domain->orig_sysdep_tab = NULL; + domain->trans_sysdep_tab = NULL; + break; + case 1: + default: + { + nls_uint32 n_sysdep_strings; + + if (domain->hash_tab == NULL) + /* This is invalid. These minor revisions need a hash table. */ + goto invalid; + + n_sysdep_strings = + W (domain->must_swap, data->n_sysdep_strings); + if (n_sysdep_strings > 0) + { + nls_uint32 n_sysdep_segments; + const struct sysdep_segment *sysdep_segments; + const char **sysdep_segment_values; + const nls_uint32 *orig_sysdep_tab; + const nls_uint32 *trans_sysdep_tab; + size_t memneed; + char *mem; + struct sysdep_string_desc *inmem_orig_sysdep_tab; + struct sysdep_string_desc *inmem_trans_sysdep_tab; + nls_uint32 *inmem_hash_tab; + unsigned int i; + + /* Get the values of the system dependent segments. */ + n_sysdep_segments = + W (domain->must_swap, data->n_sysdep_segments); + sysdep_segments = (const struct sysdep_segment *) + ((char *) data + + W (domain->must_swap, data->sysdep_segments_offset)); + sysdep_segment_values = + alloca (n_sysdep_segments * sizeof (const char *)); + for (i = 0; i < n_sysdep_segments; i++) + { + const char *name = + (char *) data + + W (domain->must_swap, sysdep_segments[i].offset); + nls_uint32 namelen = + W (domain->must_swap, sysdep_segments[i].length); + + if (!(namelen > 0 && name[namelen - 1] == '\0')) + { + freea (sysdep_segment_values); + goto invalid; + } + + sysdep_segment_values[i] = get_sysdep_segment_value (name); + } + + orig_sysdep_tab = (const nls_uint32 *) + ((char *) data + + W (domain->must_swap, data->orig_sysdep_tab_offset)); + trans_sysdep_tab = (const nls_uint32 *) + ((char *) data + + W (domain->must_swap, data->trans_sysdep_tab_offset)); + + /* Compute the amount of additional memory needed for the + system dependent strings and the augmented hash table. */ + memneed = 2 * n_sysdep_strings + * sizeof (struct sysdep_string_desc) + + domain->hash_size * sizeof (nls_uint32); + for (i = 0; i < 2 * n_sysdep_strings; i++) + { + const struct sysdep_string *sysdep_string = + (const struct sysdep_string *) + ((char *) data + + W (domain->must_swap, + i < n_sysdep_strings + ? orig_sysdep_tab[i] + : trans_sysdep_tab[i - n_sysdep_strings])); + size_t need = 0; + const struct segment_pair *p = sysdep_string->segments; + + if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END) + for (p = sysdep_string->segments;; p++) + { + nls_uint32 sysdepref; + + need += W (domain->must_swap, p->segsize); + + sysdepref = W (domain->must_swap, p->sysdepref); + if (sysdepref == SEGMENTS_END) + break; + + if (sysdepref >= n_sysdep_segments) + { + /* Invalid. */ + freea (sysdep_segment_values); + goto invalid; + } + + need += strlen (sysdep_segment_values[sysdepref]); + } + + memneed += need; + } + + /* Allocate additional memory. */ + mem = (char *) malloc (memneed); + if (mem == NULL) + goto invalid; + + domain->malloced = mem; + inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem; + mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); + inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem; + mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); + inmem_hash_tab = (nls_uint32 *) mem; + mem += domain->hash_size * sizeof (nls_uint32); + + /* Compute the system dependent strings. */ + for (i = 0; i < 2 * n_sysdep_strings; i++) + { + const struct sysdep_string *sysdep_string = + (const struct sysdep_string *) + ((char *) data + + W (domain->must_swap, + i < n_sysdep_strings + ? orig_sysdep_tab[i] + : trans_sysdep_tab[i - n_sysdep_strings])); + const char *static_segments = + (char *) data + + W (domain->must_swap, sysdep_string->offset); + const struct segment_pair *p = sysdep_string->segments; + + /* Concatenate the segments, and fill + inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and + inmem_trans_sysdep_tab[i-n_sysdep_strings] (for + i >= n_sysdep_strings). */ + + if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END) + { + /* Only one static segment. */ + inmem_orig_sysdep_tab[i].length = + W (domain->must_swap, p->segsize); + inmem_orig_sysdep_tab[i].pointer = static_segments; + } + else + { + inmem_orig_sysdep_tab[i].pointer = mem; + + for (p = sysdep_string->segments;; p++) + { + nls_uint32 segsize = + W (domain->must_swap, p->segsize); + nls_uint32 sysdepref = + W (domain->must_swap, p->sysdepref); + size_t n; + + if (segsize > 0) + { + memcpy (mem, static_segments, segsize); + mem += segsize; + static_segments += segsize; + } + + if (sysdepref == SEGMENTS_END) + break; + + n = strlen (sysdep_segment_values[sysdepref]); + memcpy (mem, sysdep_segment_values[sysdepref], n); + mem += n; + } + + inmem_orig_sysdep_tab[i].length = + mem - inmem_orig_sysdep_tab[i].pointer; + } + } + + /* Compute the augmented hash table. */ + for (i = 0; i < domain->hash_size; i++) + inmem_hash_tab[i] = + W (domain->must_swap_hash_tab, domain->hash_tab[i]); + for (i = 0; i < n_sysdep_strings; i++) + { + const char *msgid = inmem_orig_sysdep_tab[i].pointer; + nls_uint32 hash_val = hash_string (msgid); + nls_uint32 idx = hash_val % domain->hash_size; + nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); + + for (;;) + { + if (inmem_hash_tab[idx] == 0) + { + /* Hash table entry is empty. Use it. */ + inmem_hash_tab[idx] = 1 + domain->nstrings + i; + break; + } + + if (idx >= domain->hash_size - incr) + idx -= domain->hash_size - incr; + else + idx += incr; + } + } + + freea (sysdep_segment_values); + + domain->n_sysdep_strings = n_sysdep_strings; + domain->orig_sysdep_tab = inmem_orig_sysdep_tab; + domain->trans_sysdep_tab = inmem_trans_sysdep_tab; + + domain->hash_tab = inmem_hash_tab; + domain->must_swap_hash_tab = 0; + } + else + { + domain->n_sysdep_strings = 0; + domain->orig_sysdep_tab = NULL; + domain->trans_sysdep_tab = NULL; + } + } + break; + } + break; + default: + /* This is an invalid revision. */ + invalid: + /* This is an invalid .mo file. */ + if (domain->malloced) + free (domain->malloced); +#ifdef HAVE_MMAP + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + free (domain); + domain_file->data = NULL; + return; + } + + /* Now initialize the character set converter from the character set + the file is encoded with (found in the header entry) to the domain's + specified character set or the locale's character set. */ + nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding); + + /* Also look for a plural specification. */ + EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); +} + + +#ifdef _LIBC +void +internal_function +_nl_unload_domain (domain) + struct loaded_domain *domain; +{ + if (domain->plural != &__gettext_germanic_plural) + __gettext_free_exp (domain->plural); + + _nl_free_domain_conv (domain); + + if (domain->malloced) + free (domain->malloced); + +# ifdef _POSIX_MAPPED_FILES + if (domain->use_mmap) + munmap ((caddr_t) domain->data, domain->mmap_size); + else +# endif /* _POSIX_MAPPED_FILES */ + free ((void *) domain->data); + + free (domain); +} +#endif diff --git a/utshell-0.5.0/lib/intl/localcharset.c b/utshell-0.5.0/lib/intl/localcharset.c new file mode 100644 index 00000000..6983d0bf --- /dev/null +++ b/utshell-0.5.0/lib/intl/localcharset.c @@ -0,0 +1,399 @@ +/* localcharset.c - Determine a canonical name for the current locale's character encoding. */ + +/* Copyright (C) 2000-2003, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Written by Bruno Haible . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include "localcharset.h" + +#if HAVE_STDDEF_H +# include +#endif + +#include +#if HAVE_STRING_H +# include +#else +# include +#endif +#if HAVE_STDLIB_H +# include +#endif + +#if defined _WIN32 || defined __WIN32__ +# undef WIN32 /* avoid warning on mingw32 */ +# define WIN32 +#endif + +#if defined __EMX__ +/* Assume EMX program runs on OS/2, even if compiled under DOS. */ +# define OS2 +#endif + +#if !defined WIN32 +# if HAVE_LANGINFO_CODESET +# include +# else +# if HAVE_SETLOCALE +# include +# endif +# endif +#elif defined WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#endif +#if defined OS2 +# define INCL_DOS +# include +#endif + +#if ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#endif + +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif + +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif + +#ifdef HAVE_GETC_UNLOCKED +# undef getc +# define getc getc_unlocked +#endif + +/* The following static variable is declared 'volatile' to avoid a + possible multithread problem in the function get_charset_aliases. If we + are running in a threaded environment, and if two threads initialize + 'charset_aliases' simultaneously, both will produce the same value, + and everything will be ok if the two assignments to 'charset_aliases' + are atomic. But I don't know what will happen if the two assignments mix. */ +#if __STDC__ != 1 +# define volatile /* empty */ +#endif +/* Pointer to the contents of the charset.alias file, if it has already been + read, else NULL. Its format is: + ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ +static const char * volatile charset_aliases; + +/* Return a pointer to the contents of the charset.alias file. */ +static const char * +get_charset_aliases () +{ + const char *cp; + + cp = charset_aliases; + if (cp == NULL) + { +#if !(defined VMS || defined WIN32) + FILE *fp; + const char *dir = relocate (LIBDIR); + const char *base = "charset.alias"; + char *file_name; + + /* Concatenate dir and base into freshly allocated file_name. */ + { + size_t dir_len = strlen (dir); + size_t base_len = strlen (base); + int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); + file_name = (char *) malloc (dir_len + add_slash + base_len + 1); + if (file_name != NULL) + { + memcpy (file_name, dir, dir_len); + if (add_slash) + file_name[dir_len] = DIRECTORY_SEPARATOR; + memcpy (file_name + dir_len + add_slash, base, base_len + 1); + } + } + + if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) + /* Out of memory or file not found, treat it as empty. */ + cp = ""; + else + { + /* Parse the file's contents. */ + int c; + char buf1[50+1]; + char buf2[50+1]; + char *res_ptr = NULL; + size_t res_size = 0; + size_t l1, l2; + + for (;;) + { + c = getc (fp); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') + { + /* Skip comment, to end of line. */ + do + c = getc (fp); + while (!(c == EOF || c == '\n')); + if (c == EOF) + break; + continue; + } + ungetc (c, fp); + if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) + break; + l1 = strlen (buf1); + l2 = strlen (buf2); + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = (char *) malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = (char *) realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); + strcpy (res_ptr + res_size - (l2 + 1), buf2); + } + fclose (fp); + if (res_size == 0) + cp = ""; + else + { + *(res_ptr + res_size) = '\0'; + cp = res_ptr; + } + } + + if (file_name != NULL) + free (file_name); + +#else + +# if defined VMS + /* To avoid the troubles of an extra file charset.alias_vms in the + sources of many GNU packages, simply inline the aliases here. */ + /* The list of encodings is taken from the OpenVMS 7.3-1 documentation + "Compaq C Run-Time Library Reference Manual for OpenVMS systems" + section 10.7 "Handling Different Character Sets". */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-8" "\0" "ISO-8859-8" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + /* Japanese */ + "eucJP" "\0" "EUC-JP" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "DECKANJI" "\0" "DEC-KANJI" "\0" + "SDECKANJI" "\0" "EUC-JP" "\0" + /* Chinese */ + "eucTW" "\0" "EUC-TW" "\0" + "DECHANYU" "\0" "DEC-HANYU" "\0" + "DECHANZI" "\0" "GB2312" "\0" + /* Korean */ + "DECKOREAN" "\0" "EUC-KR" "\0"; +# endif + +# if defined WIN32 + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + + cp = "CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0" + "CP20127" "\0" "ASCII" "\0" + "CP20866" "\0" "KOI8-R" "\0" + "CP21866" "\0" "KOI8-RU" "\0" + "CP28591" "\0" "ISO-8859-1" "\0" + "CP28592" "\0" "ISO-8859-2" "\0" + "CP28593" "\0" "ISO-8859-3" "\0" + "CP28594" "\0" "ISO-8859-4" "\0" + "CP28595" "\0" "ISO-8859-5" "\0" + "CP28596" "\0" "ISO-8859-6" "\0" + "CP28597" "\0" "ISO-8859-7" "\0" + "CP28598" "\0" "ISO-8859-8" "\0" + "CP28599" "\0" "ISO-8859-9" "\0" + "CP28605" "\0" "ISO-8859-15" "\0"; +# endif +#endif + + charset_aliases = cp; + } + + return cp; +} + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ + +#ifdef STATIC +STATIC +#endif +const char * +locale_charset () +{ + const char *codeset; + const char *aliases; + +#if !(defined WIN32 || defined OS2) + +# if HAVE_LANGINFO_CODESET + + /* Most systems support nl_langinfo (CODESET) nowadays. */ + codeset = nl_langinfo (CODESET); + +# else + + /* On old systems which lack it, use setlocale or getenv. */ + const char *locale = NULL; + + /* But most old systems don't have a complete set of locales. Some + (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't + use setlocale here; it would return "C" when it doesn't support the + locale name the user has set. */ +# if HAVE_SETLOCALE && 0 + locale = setlocale (LC_CTYPE, NULL); +# endif + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + } + + /* On some old systems, one used to set locale = "iso8859_1". On others, + you set it to "language_COUNTRY.charset". In any case, we resolve it + through the charset.alias file. */ + codeset = locale; + +# endif + +#elif defined WIN32 + + static char buf[2 + 10 + 1]; + + /* Woe32 has a function returning the locale's codepage as a number. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + +#elif defined OS2 + + const char *locale; + static char buf[2 + 10 + 1]; + ULONG cp[3]; + ULONG cplen; + + /* Allow user to override the codeset, as set in the operating system, + with standard language environment variables. */ + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + + /* Resolve through the charset.alias file. */ + codeset = locale; + } + else + { + /* OS/2 has a function returning the locale's codepage as a number. */ + if (DosQueryCp (sizeof (cp), cp, &cplen)) + codeset = ""; + else + { + sprintf (buf, "CP%u", cp[0]); + codeset = buf; + } + } + +#endif + + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + + /* Resolve alias. */ + for (aliases = get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (strcmp (codeset, aliases) == 0 + || (aliases[0] == '*' && aliases[1] == '\0')) + { + codeset = aliases + strlen (aliases) + 1; + break; + } + + /* Don't return an empty string. GNU libc and GNU libiconv interpret + the empty string as denoting "the locale's character encoding", + thus GNU libiconv would call this function a second time. */ + if (codeset[0] == '\0') + codeset = "ASCII"; + + return codeset; +} diff --git a/utshell-0.5.0/lib/intl/localcharset.h b/utshell-0.5.0/lib/intl/localcharset.h new file mode 100644 index 00000000..e5299589 --- /dev/null +++ b/utshell-0.5.0/lib/intl/localcharset.h @@ -0,0 +1,43 @@ +/* localcharset.h - Determine a canonical name for the current locale's character encoding. */ + +/* Copyright (C) 2000-2003, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _LOCALCHARSET_H +#define _LOCALCHARSET_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ +extern const char * locale_charset (void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _LOCALCHARSET_H */ diff --git a/utshell-0.5.0/lib/intl/locale.alias b/utshell-0.5.0/lib/intl/locale.alias new file mode 100644 index 00000000..51dd21e7 --- /dev/null +++ b/utshell-0.5.0/lib/intl/locale.alias @@ -0,0 +1,78 @@ +# locale.alias - Locale name alias data base. +# +# Copyright (C) 1996,1997,1998,1999,2000,2001,2005-2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# The format of this file is the same as for the corresponding file of +# the X Window System, which normally can be found in +# /usr/lib/X11/locale/locale.alias +# A single line contains two fields: an alias and a substitution value. +# All entries are case independent. + +# Note: This file is far from being complete. If you have a value for +# your own site which you think might be useful for others too, share +# it with the rest of us. Send it using the `glibcbug' script to +# bugs@gnu.org. + +# Packages using this file: + +bokmal no_NO.ISO-8859-1 +bokmål no_NO.ISO-8859-1 +catalan ca_ES.ISO-8859-1 +croatian hr_HR.ISO-8859-2 +czech cs_CZ.ISO-8859-2 +danish da_DK.ISO-8859-1 +dansk da_DK.ISO-8859-1 +deutsch de_DE.ISO-8859-1 +dutch nl_NL.ISO-8859-1 +eesti et_EE.ISO-8859-1 +estonian et_EE.ISO-8859-1 +finnish fi_FI.ISO-8859-1 +français fr_FR.ISO-8859-1 +french fr_FR.ISO-8859-1 +galego gl_ES.ISO-8859-1 +galician gl_ES.ISO-8859-1 +german de_DE.ISO-8859-1 +greek el_GR.ISO-8859-7 +hebrew he_IL.ISO-8859-8 +hrvatski hr_HR.ISO-8859-2 +hungarian hu_HU.ISO-8859-2 +icelandic is_IS.ISO-8859-1 +italian it_IT.ISO-8859-1 +japanese ja_JP.eucJP +japanese.euc ja_JP.eucJP +ja_JP ja_JP.eucJP +ja_JP.ujis ja_JP.eucJP +japanese.sjis ja_JP.SJIS +korean ko_KR.eucKR +korean.euc ko_KR.eucKR +ko_KR ko_KR.eucKR +lithuanian lt_LT.ISO-8859-13 +nb_NO no_NO.ISO-8859-1 +nb_NO.ISO-8859-1 no_NO.ISO-8859-1 +norwegian no_NO.ISO-8859-1 +nynorsk nn_NO.ISO-8859-1 +polish pl_PL.ISO-8859-2 +portuguese pt_PT.ISO-8859-1 +romanian ro_RO.ISO-8859-2 +russian ru_RU.ISO-8859-5 +slovak sk_SK.ISO-8859-2 +slovene sl_SI.ISO-8859-2 +slovenian sl_SI.ISO-8859-2 +spanish es_ES.ISO-8859-1 +swedish sv_SE.ISO-8859-1 +thai th_TH.TIS-620 +turkish tr_TR.ISO-8859-9 diff --git a/utshell-0.5.0/lib/intl/localealias.c b/utshell-0.5.0/lib/intl/localealias.c new file mode 100644 index 00000000..7a730dbf --- /dev/null +++ b/utshell-0.5.0/lib/intl/localealias.c @@ -0,0 +1,427 @@ +/* localealias.c - Handle aliases for locale names. */ + +/* Copyright (C) 1995-1999, 2000-2001, 2003, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Tell glibc's to provide a prototype for mempcpy(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#if defined _LIBC || defined HAVE___FSETLOCKING +# include +#endif +#include + +#ifdef __GNUC__ +# undef alloca +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +#include +#include + +#include "gettextP.h" + +#if ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define strcasecmp __strcasecmp + +# ifndef mempcpy +# define mempcpy __mempcpy +# endif +# define HAVE_MEMPCPY 1 +# define HAVE___FSETLOCKING 1 + +/* We need locking here since we can be called from different places. */ +# include + +__libc_lock_define_initialized (static, lock); +#endif + +#ifndef internal_function +# define internal_function +#endif + +/* Some optimizations for glibc. */ +#ifdef _LIBC +# define FEOF(fp) feof_unlocked (fp) +# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp) +#else +# define FEOF(fp) feof (fp) +# define FGETS(buf, n, fp) fgets (buf, n, fp) +#endif + +/* For those losing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +# define freea(p) /* nothing */ +#else +# define alloca(n) malloc (n) +# define freea(p) free (p) +#endif + +#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED +# undef fgets +# define fgets(buf, len, s) fgets_unlocked (buf, len, s) +#endif +#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED +# undef feof +# define feof(s) feof_unlocked (s) +#endif + + +struct alias_map +{ + const char *alias; + const char *value; +}; + + +#ifndef _LIBC +# define libc_freeres_ptr(decl) decl +#endif + +libc_freeres_ptr (static char *string_space); +static size_t string_space_act; +static size_t string_space_max; +libc_freeres_ptr (static struct alias_map *map); +static size_t nmap; +static size_t maxmap; + + +/* Prototypes for local functions. */ +static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) + internal_function; +static int extend_alias_table PARAMS ((void)); +static int alias_compare PARAMS ((const struct alias_map *map1, + const struct alias_map *map2)); + + +const char * +_nl_expand_alias (name) + const char *name; +{ + static const char *locale_alias_path; + struct alias_map *retval; + const char *result = NULL; + size_t added; + +#ifdef _LIBC + __libc_lock_lock (lock); +#endif + + if (locale_alias_path == NULL) + locale_alias_path = LOCALE_ALIAS_PATH; + + do + { + struct alias_map item; + + item.alias = name; + + if (nmap > 0) + retval = (struct alias_map *) bsearch (&item, map, nmap, + sizeof (struct alias_map), + (int (*) PARAMS ((const void *, + const void *)) + ) alias_compare); + else + retval = NULL; + + /* We really found an alias. Return the value. */ + if (retval != NULL) + { + result = retval->value; + break; + } + + /* Perhaps we can find another alias file. */ + added = 0; + while (added == 0 && locale_alias_path[0] != '\0') + { + const char *start; + + while (locale_alias_path[0] == PATH_SEPARATOR) + ++locale_alias_path; + start = locale_alias_path; + + while (locale_alias_path[0] != '\0' + && locale_alias_path[0] != PATH_SEPARATOR) + ++locale_alias_path; + + if (start < locale_alias_path) + added = read_alias_file (start, locale_alias_path - start); + } + } + while (added != 0); + +#ifdef _LIBC + __libc_lock_unlock (lock); +#endif + + return result; +} + + +static size_t +internal_function +read_alias_file (fname, fname_len) + const char *fname; + int fname_len; +{ + FILE *fp; + char *full_fname; + size_t added; + static const char aliasfile[] = "/locale.alias"; + + full_fname = (char *) alloca (fname_len + sizeof aliasfile); +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (full_fname, fname, fname_len), + aliasfile, sizeof aliasfile); +#else + memcpy (full_fname, fname, fname_len); + memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); +#endif + + fp = fopen (relocate (full_fname), "r"); + freea (full_fname); + if (fp == NULL) + return 0; + +#ifdef HAVE___FSETLOCKING + /* No threads present. */ + __fsetlocking (fp, FSETLOCKING_BYCALLER); +#endif + + added = 0; + while (!FEOF (fp)) + { + /* It is a reasonable approach to use a fix buffer here because + a) we are only interested in the first two fields + b) these fields must be usable as file names and so must not + be that long + We avoid a multi-kilobyte buffer here since this would use up + stack space which we might not have if the program ran out of + memory. */ + char buf[400]; + char *alias; + char *value; + char *cp; + + if (FGETS (buf, sizeof buf, fp) == NULL) + /* EOF reached. */ + break; + + cp = buf; + /* Ignore leading white space. */ + while (isspace ((unsigned char) cp[0])) + ++cp; + + /* A leading '#' signals a comment line. */ + if (cp[0] != '\0' && cp[0] != '#') + { + alias = cp++; + while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) + ++cp; + /* Terminate alias name. */ + if (cp[0] != '\0') + *cp++ = '\0'; + + /* Now look for the beginning of the value. */ + while (isspace ((unsigned char) cp[0])) + ++cp; + + if (cp[0] != '\0') + { + size_t alias_len; + size_t value_len; + + value = cp++; + while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) + ++cp; + /* Terminate value. */ + if (cp[0] == '\n') + { + /* This has to be done to make the following test + for the end of line possible. We are looking for + the terminating '\n' which do not overwrite here. */ + *cp++ = '\0'; + *cp = '\n'; + } + else if (cp[0] != '\0') + *cp++ = '\0'; + + if (nmap >= maxmap) + if (__builtin_expect (extend_alias_table (), 0)) + { + fclose (fp); + return added; + } + + alias_len = strlen (alias) + 1; + value_len = strlen (value) + 1; + + if (string_space_act + alias_len + value_len > string_space_max) + { + /* Increase size of memory pool. */ + size_t new_size = (string_space_max + + (alias_len + value_len > 1024 + ? alias_len + value_len : 1024)); + char *new_pool = (char *) realloc (string_space, new_size); + if (new_pool == NULL) + { + fclose (fp); + return added; + } + + if (__builtin_expect (string_space != new_pool, 0)) + { + size_t i; + + for (i = 0; i < nmap; i++) + { + map[i].alias += new_pool - string_space; + map[i].value += new_pool - string_space; + } + } + + string_space = new_pool; + string_space_max = new_size; + } + + map[nmap].alias = memcpy (&string_space[string_space_act], + alias, alias_len); + string_space_act += alias_len; + + map[nmap].value = memcpy (&string_space[string_space_act], + value, value_len); + string_space_act += value_len; + + ++nmap; + ++added; + } + } + + /* Possibly not the whole line fits into the buffer. Ignore + the rest of the line. */ + while (strchr (buf, '\n') == NULL) + if (FGETS (buf, sizeof buf, fp) == NULL) + /* Make sure the inner loop will be left. The outer loop + will exit at the `feof' test. */ + break; + } + + /* Should we test for ferror()? I think we have to silently ignore + errors. --drepper */ + fclose (fp); + + if (added > 0) + qsort (map, nmap, sizeof (struct alias_map), + (int (*) PARAMS ((const void *, const void *))) alias_compare); + + return added; +} + + +static int +extend_alias_table () +{ + size_t new_size; + struct alias_map *new_map; + + new_size = maxmap == 0 ? 100 : 2 * maxmap; + new_map = (struct alias_map *) realloc (map, (new_size + * sizeof (struct alias_map))); + if (new_map == NULL) + /* Simply don't extend: we don't have any more core. */ + return -1; + + map = new_map; + maxmap = new_size; + return 0; +} + + +static int +alias_compare (map1, map2) + const struct alias_map *map1; + const struct alias_map *map2; +{ +#if defined _LIBC || defined HAVE_STRCASECMP + return strcasecmp (map1->alias, map2->alias); +#else + const unsigned char *p1 = (const unsigned char *) map1->alias; + const unsigned char *p2 = (const unsigned char *) map2->alias; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + /* I know this seems to be odd but the tolower() function in + some systems libc cannot handle nonalpha characters. */ + c1 = isupper (*p1) ? tolower (*p1) : *p1; + c2 = isupper (*p2) ? tolower (*p2) : *p2; + if (c1 == '\0') + break; + ++p1; + ++p2; + } + while (c1 == c2); + + return c1 - c2; +#endif +} diff --git a/utshell-0.5.0/lib/intl/localename.c b/utshell-0.5.0/lib/intl/localename.c new file mode 100644 index 00000000..795a34fb --- /dev/null +++ b/utshell-0.5.0/lib/intl/localename.c @@ -0,0 +1,774 @@ +/* localename.c - Determine the current selected locale. */ + +/* Copyright (C) 1995-1999, 2000-2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Written by Ulrich Drepper , 1995. */ +/* Win32 code written by Tor Lillqvist . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#if defined _WIN32 || defined __WIN32__ +# undef WIN32 /* avoid warning on mingw32 */ +# define WIN32 +#endif + +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include +/* Mingw headers don't have latest language and sublanguage codes. */ +# ifndef LANG_AFRIKAANS +# define LANG_AFRIKAANS 0x36 +# endif +# ifndef LANG_ALBANIAN +# define LANG_ALBANIAN 0x1c +# endif +# ifndef LANG_ARABIC +# define LANG_ARABIC 0x01 +# endif +# ifndef LANG_ARMENIAN +# define LANG_ARMENIAN 0x2b +# endif +# ifndef LANG_ASSAMESE +# define LANG_ASSAMESE 0x4d +# endif +# ifndef LANG_AZERI +# define LANG_AZERI 0x2c +# endif +# ifndef LANG_BASQUE +# define LANG_BASQUE 0x2d +# endif +# ifndef LANG_BELARUSIAN +# define LANG_BELARUSIAN 0x23 +# endif +# ifndef LANG_BENGALI +# define LANG_BENGALI 0x45 +# endif +# ifndef LANG_CATALAN +# define LANG_CATALAN 0x03 +# endif +# ifndef LANG_DIVEHI +# define LANG_DIVEHI 0x65 +# endif +# ifndef LANG_ESTONIAN +# define LANG_ESTONIAN 0x25 +# endif +# ifndef LANG_FAEROESE +# define LANG_FAEROESE 0x38 +# endif +# ifndef LANG_FARSI +# define LANG_FARSI 0x29 +# endif +# ifndef LANG_GALICIAN +# define LANG_GALICIAN 0x56 +# endif +# ifndef LANG_GEORGIAN +# define LANG_GEORGIAN 0x37 +# endif +# ifndef LANG_GUJARATI +# define LANG_GUJARATI 0x47 +# endif +# ifndef LANG_HEBREW +# define LANG_HEBREW 0x0d +# endif +# ifndef LANG_HINDI +# define LANG_HINDI 0x39 +# endif +# ifndef LANG_INDONESIAN +# define LANG_INDONESIAN 0x21 +# endif +# ifndef LANG_KANNADA +# define LANG_KANNADA 0x4b +# endif +# ifndef LANG_KASHMIRI +# define LANG_KASHMIRI 0x60 +# endif +# ifndef LANG_KAZAK +# define LANG_KAZAK 0x3f +# endif +# ifndef LANG_KONKANI +# define LANG_KONKANI 0x57 +# endif +# ifndef LANG_KYRGYZ +# define LANG_KYRGYZ 0x40 +# endif +# ifndef LANG_LATVIAN +# define LANG_LATVIAN 0x26 +# endif +# ifndef LANG_LITHUANIAN +# define LANG_LITHUANIAN 0x27 +# endif +# ifndef LANG_MACEDONIAN +# define LANG_MACEDONIAN 0x2f +# endif +# ifndef LANG_MALAY +# define LANG_MALAY 0x3e +# endif +# ifndef LANG_MALAYALAM +# define LANG_MALAYALAM 0x4c +# endif +# ifndef LANG_MANIPURI +# define LANG_MANIPURI 0x58 +# endif +# ifndef LANG_MARATHI +# define LANG_MARATHI 0x4e +# endif +# ifndef LANG_MONGOLIAN +# define LANG_MONGOLIAN 0x50 +# endif +# ifndef LANG_NEPALI +# define LANG_NEPALI 0x61 +# endif +# ifndef LANG_ORIYA +# define LANG_ORIYA 0x48 +# endif +# ifndef LANG_PUNJABI +# define LANG_PUNJABI 0x46 +# endif +# ifndef LANG_SANSKRIT +# define LANG_SANSKRIT 0x4f +# endif +# ifndef LANG_SERBIAN +# define LANG_SERBIAN 0x1a +# endif +# ifndef LANG_SINDHI +# define LANG_SINDHI 0x59 +# endif +# ifndef LANG_SLOVAK +# define LANG_SLOVAK 0x1b +# endif +# ifndef LANG_SORBIAN +# define LANG_SORBIAN 0x2e +# endif +# ifndef LANG_SWAHILI +# define LANG_SWAHILI 0x41 +# endif +# ifndef LANG_SYRIAC +# define LANG_SYRIAC 0x5a +# endif +# ifndef LANG_TAMIL +# define LANG_TAMIL 0x49 +# endif +# ifndef LANG_TATAR +# define LANG_TATAR 0x44 +# endif +# ifndef LANG_TELUGU +# define LANG_TELUGU 0x4a +# endif +# ifndef LANG_THAI +# define LANG_THAI 0x1e +# endif +# ifndef LANG_UKRAINIAN +# define LANG_UKRAINIAN 0x22 +# endif +# ifndef LANG_URDU +# define LANG_URDU 0x20 +# endif +# ifndef LANG_UZBEK +# define LANG_UZBEK 0x43 +# endif +# ifndef LANG_VIETNAMESE +# define LANG_VIETNAMESE 0x2a +# endif +# ifndef SUBLANG_ARABIC_SAUDI_ARABIA +# define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 +# endif +# ifndef SUBLANG_ARABIC_IRAQ +# define SUBLANG_ARABIC_IRAQ 0x02 +# endif +# ifndef SUBLANG_ARABIC_EGYPT +# define SUBLANG_ARABIC_EGYPT 0x03 +# endif +# ifndef SUBLANG_ARABIC_LIBYA +# define SUBLANG_ARABIC_LIBYA 0x04 +# endif +# ifndef SUBLANG_ARABIC_ALGERIA +# define SUBLANG_ARABIC_ALGERIA 0x05 +# endif +# ifndef SUBLANG_ARABIC_MOROCCO +# define SUBLANG_ARABIC_MOROCCO 0x06 +# endif +# ifndef SUBLANG_ARABIC_TUNISIA +# define SUBLANG_ARABIC_TUNISIA 0x07 +# endif +# ifndef SUBLANG_ARABIC_OMAN +# define SUBLANG_ARABIC_OMAN 0x08 +# endif +# ifndef SUBLANG_ARABIC_YEMEN +# define SUBLANG_ARABIC_YEMEN 0x09 +# endif +# ifndef SUBLANG_ARABIC_SYRIA +# define SUBLANG_ARABIC_SYRIA 0x0a +# endif +# ifndef SUBLANG_ARABIC_JORDAN +# define SUBLANG_ARABIC_JORDAN 0x0b +# endif +# ifndef SUBLANG_ARABIC_LEBANON +# define SUBLANG_ARABIC_LEBANON 0x0c +# endif +# ifndef SUBLANG_ARABIC_KUWAIT +# define SUBLANG_ARABIC_KUWAIT 0x0d +# endif +# ifndef SUBLANG_ARABIC_UAE +# define SUBLANG_ARABIC_UAE 0x0e +# endif +# ifndef SUBLANG_ARABIC_BAHRAIN +# define SUBLANG_ARABIC_BAHRAIN 0x0f +# endif +# ifndef SUBLANG_ARABIC_QATAR +# define SUBLANG_ARABIC_QATAR 0x10 +# endif +# ifndef SUBLANG_AZERI_LATIN +# define SUBLANG_AZERI_LATIN 0x01 +# endif +# ifndef SUBLANG_AZERI_CYRILLIC +# define SUBLANG_AZERI_CYRILLIC 0x02 +# endif +# ifndef SUBLANG_CHINESE_MACAU +# define SUBLANG_CHINESE_MACAU 0x05 +# endif +# ifndef SUBLANG_ENGLISH_SOUTH_AFRICA +# define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 +# endif +# ifndef SUBLANG_ENGLISH_JAMAICA +# define SUBLANG_ENGLISH_JAMAICA 0x08 +# endif +# ifndef SUBLANG_ENGLISH_CARIBBEAN +# define SUBLANG_ENGLISH_CARIBBEAN 0x09 +# endif +# ifndef SUBLANG_ENGLISH_BELIZE +# define SUBLANG_ENGLISH_BELIZE 0x0a +# endif +# ifndef SUBLANG_ENGLISH_TRINIDAD +# define SUBLANG_ENGLISH_TRINIDAD 0x0b +# endif +# ifndef SUBLANG_ENGLISH_ZIMBABWE +# define SUBLANG_ENGLISH_ZIMBABWE 0x0c +# endif +# ifndef SUBLANG_ENGLISH_PHILIPPINES +# define SUBLANG_ENGLISH_PHILIPPINES 0x0d +# endif +# ifndef SUBLANG_FRENCH_LUXEMBOURG +# define SUBLANG_FRENCH_LUXEMBOURG 0x05 +# endif +# ifndef SUBLANG_FRENCH_MONACO +# define SUBLANG_FRENCH_MONACO 0x06 +# endif +# ifndef SUBLANG_GERMAN_LUXEMBOURG +# define SUBLANG_GERMAN_LUXEMBOURG 0x04 +# endif +# ifndef SUBLANG_GERMAN_LIECHTENSTEIN +# define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 +# endif +# ifndef SUBLANG_KASHMIRI_INDIA +# define SUBLANG_KASHMIRI_INDIA 0x02 +# endif +# ifndef SUBLANG_MALAY_MALAYSIA +# define SUBLANG_MALAY_MALAYSIA 0x01 +# endif +# ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM +# define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 +# endif +# ifndef SUBLANG_NEPALI_INDIA +# define SUBLANG_NEPALI_INDIA 0x02 +# endif +# ifndef SUBLANG_SERBIAN_LATIN +# define SUBLANG_SERBIAN_LATIN 0x02 +# endif +# ifndef SUBLANG_SERBIAN_CYRILLIC +# define SUBLANG_SERBIAN_CYRILLIC 0x03 +# endif +# ifndef SUBLANG_SPANISH_GUATEMALA +# define SUBLANG_SPANISH_GUATEMALA 0x04 +# endif +# ifndef SUBLANG_SPANISH_COSTA_RICA +# define SUBLANG_SPANISH_COSTA_RICA 0x05 +# endif +# ifndef SUBLANG_SPANISH_PANAMA +# define SUBLANG_SPANISH_PANAMA 0x06 +# endif +# ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC +# define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 +# endif +# ifndef SUBLANG_SPANISH_VENEZUELA +# define SUBLANG_SPANISH_VENEZUELA 0x08 +# endif +# ifndef SUBLANG_SPANISH_COLOMBIA +# define SUBLANG_SPANISH_COLOMBIA 0x09 +# endif +# ifndef SUBLANG_SPANISH_PERU +# define SUBLANG_SPANISH_PERU 0x0a +# endif +# ifndef SUBLANG_SPANISH_ARGENTINA +# define SUBLANG_SPANISH_ARGENTINA 0x0b +# endif +# ifndef SUBLANG_SPANISH_ECUADOR +# define SUBLANG_SPANISH_ECUADOR 0x0c +# endif +# ifndef SUBLANG_SPANISH_CHILE +# define SUBLANG_SPANISH_CHILE 0x0d +# endif +# ifndef SUBLANG_SPANISH_URUGUAY +# define SUBLANG_SPANISH_URUGUAY 0x0e +# endif +# ifndef SUBLANG_SPANISH_PARAGUAY +# define SUBLANG_SPANISH_PARAGUAY 0x0f +# endif +# ifndef SUBLANG_SPANISH_BOLIVIA +# define SUBLANG_SPANISH_BOLIVIA 0x10 +# endif +# ifndef SUBLANG_SPANISH_EL_SALVADOR +# define SUBLANG_SPANISH_EL_SALVADOR 0x11 +# endif +# ifndef SUBLANG_SPANISH_HONDURAS +# define SUBLANG_SPANISH_HONDURAS 0x12 +# endif +# ifndef SUBLANG_SPANISH_NICARAGUA +# define SUBLANG_SPANISH_NICARAGUA 0x13 +# endif +# ifndef SUBLANG_SPANISH_PUERTO_RICO +# define SUBLANG_SPANISH_PUERTO_RICO 0x14 +# endif +# ifndef SUBLANG_SWEDISH_FINLAND +# define SUBLANG_SWEDISH_FINLAND 0x02 +# endif +# ifndef SUBLANG_URDU_PAKISTAN +# define SUBLANG_URDU_PAKISTAN 0x01 +# endif +# ifndef SUBLANG_URDU_INDIA +# define SUBLANG_URDU_INDIA 0x02 +# endif +# ifndef SUBLANG_UZBEK_LATIN +# define SUBLANG_UZBEK_LATIN 0x01 +# endif +# ifndef SUBLANG_UZBEK_CYRILLIC +# define SUBLANG_UZBEK_CYRILLIC 0x02 +# endif +#endif + +/* XPG3 defines the result of 'setlocale (category, NULL)' as: + "Directs 'setlocale()' to query 'category' and return the current + setting of 'local'." + However it does not specify the exact format. Neither do SUSV2 and + ISO C 99. So we can use this feature only on selected systems (e.g. + those using GNU C Library). */ +#if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2) +# define HAVE_LOCALE_NULL +#endif + +/* Determine the current locale's name, and canonicalize it into XPG syntax + language[_territory[.codeset]][@modifier] + The codeset part in the result is not reliable; the locale_charset() + should be used for codeset information instead. + The result must not be freed; it is statically allocated. */ + +const char * +_nl_locale_name (category, categoryname) + int category; + const char *categoryname; +{ + const char *retval; + +#ifndef WIN32 + + /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'. + On some systems this can be done by the 'setlocale' function itself. */ +# if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL + retval = setlocale (category, NULL); +# else + /* Setting of LC_ALL overwrites all other. */ + retval = getenv ("LC_ALL"); + if (retval == NULL || retval[0] == '\0') + { + /* Next comes the name of the desired category. */ + retval = getenv (categoryname); + if (retval == NULL || retval[0] == '\0') + { + /* Last possibility is the LANG environment variable. */ + retval = getenv ("LANG"); + if (retval == NULL || retval[0] == '\0') + /* We use C as the default domain. POSIX says this is + implementation defined. */ + retval = "C"; + } + } +# endif + + return retval; + +#else /* WIN32 */ + + /* Return an XPG style locale name language[_territory][@modifier]. + Don't even bother determining the codeset; it's not useful in this + context, because message catalogs are not specific to a single + codeset. */ + + LCID lcid; + LANGID langid; + int primary, sub; + + /* Let the user override the system settings through environment + variables, as on POSIX systems. */ + retval = getenv ("LC_ALL"); + if (retval != NULL && retval[0] != '\0') + return retval; + retval = getenv (categoryname); + if (retval != NULL && retval[0] != '\0') + return retval; + retval = getenv ("LANG"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* Use native Win32 API locale ID. */ + lcid = GetThreadLocale (); + + /* Strip off the sorting rules, keep only the language part. */ + langid = LANGIDFROMLCID (lcid); + + /* Split into language and territory part. */ + primary = PRIMARYLANGID (langid); + sub = SUBLANGID (langid); + + /* Dispatch on language. + See also http://www.unicode.org/unicode/onlinedat/languages.html . + For details about languages, see http://www.ethnologue.com/ . */ + switch (primary) + { + case LANG_AFRIKAANS: return "af_ZA"; + case LANG_ALBANIAN: return "sq_AL"; + case 0x5e: /* AMHARIC */ return "am_ET"; + case LANG_ARABIC: + switch (sub) + { + case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA"; + case SUBLANG_ARABIC_IRAQ: return "ar_IQ"; + case SUBLANG_ARABIC_EGYPT: return "ar_EG"; + case SUBLANG_ARABIC_LIBYA: return "ar_LY"; + case SUBLANG_ARABIC_ALGERIA: return "ar_DZ"; + case SUBLANG_ARABIC_MOROCCO: return "ar_MA"; + case SUBLANG_ARABIC_TUNISIA: return "ar_TN"; + case SUBLANG_ARABIC_OMAN: return "ar_OM"; + case SUBLANG_ARABIC_YEMEN: return "ar_YE"; + case SUBLANG_ARABIC_SYRIA: return "ar_SY"; + case SUBLANG_ARABIC_JORDAN: return "ar_JO"; + case SUBLANG_ARABIC_LEBANON: return "ar_LB"; + case SUBLANG_ARABIC_KUWAIT: return "ar_KW"; + case SUBLANG_ARABIC_UAE: return "ar_AE"; + case SUBLANG_ARABIC_BAHRAIN: return "ar_BH"; + case SUBLANG_ARABIC_QATAR: return "ar_QA"; + } + return "ar"; + case LANG_ARMENIAN: return "hy_AM"; + case LANG_ASSAMESE: return "as_IN"; + case LANG_AZERI: + switch (sub) + { + /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */ + case SUBLANG_AZERI_LATIN: return "az_AZ@latin"; + case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic"; + } + return "az"; + case LANG_BASQUE: + return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */ + case LANG_BELARUSIAN: return "be_BY"; + case LANG_BENGALI: return "bn_IN"; + case LANG_BULGARIAN: return "bg_BG"; + case 0x55: /* BURMESE */ return "my_MM"; + case 0x53: /* CAMBODIAN */ return "km_KH"; + case LANG_CATALAN: return "ca_ES"; + case 0x5c: /* CHEROKEE */ return "chr_US"; + case LANG_CHINESE: + switch (sub) + { + case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW"; + case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN"; + case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; + case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; + case SUBLANG_CHINESE_MACAU: return "zh_MO"; + } + return "zh"; + case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN + * What used to be called Serbo-Croatian + * should really now be two separate + * languages because of political reasons. + * (Says tml, who knows nothing about Serbian + * or Croatian.) + * (I can feel those flames coming already.) + */ + switch (sub) + { + case SUBLANG_DEFAULT: return "hr_HR"; + case SUBLANG_SERBIAN_LATIN: return "sr_YU"; + case SUBLANG_SERBIAN_CYRILLIC: return "sr_YU@cyrillic"; + } + return "hr"; + case LANG_CZECH: return "cs_CZ"; + case LANG_DANISH: return "da_DK"; + case LANG_DIVEHI: return "div_MV"; + case LANG_DUTCH: + switch (sub) + { + case SUBLANG_DUTCH: return "nl_NL"; + case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE"; + } + return "nl"; + case 0x66: /* EDO */ return "bin_NG"; + case LANG_ENGLISH: + switch (sub) + { + /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought + * English was the language spoken in England. + * Oh well. + */ + case SUBLANG_ENGLISH_US: return "en_US"; + case SUBLANG_ENGLISH_UK: return "en_GB"; + case SUBLANG_ENGLISH_AUS: return "en_AU"; + case SUBLANG_ENGLISH_CAN: return "en_CA"; + case SUBLANG_ENGLISH_NZ: return "en_NZ"; + case SUBLANG_ENGLISH_EIRE: return "en_IE"; + case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA"; + case SUBLANG_ENGLISH_JAMAICA: return "en_JM"; + case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */ + case SUBLANG_ENGLISH_BELIZE: return "en_BZ"; + case SUBLANG_ENGLISH_TRINIDAD: return "en_TT"; + case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW"; + case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH"; + } + return "en"; + case LANG_ESTONIAN: return "et_EE"; + case LANG_FAEROESE: return "fo_FO"; + case LANG_FARSI: return "fa_IR"; + case LANG_FINNISH: return "fi_FI"; + case LANG_FRENCH: + switch (sub) + { + case SUBLANG_FRENCH: return "fr_FR"; + case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE"; + case SUBLANG_FRENCH_CANADIAN: return "fr_CA"; + case SUBLANG_FRENCH_SWISS: return "fr_CH"; + case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU"; + case SUBLANG_FRENCH_MONACO: return "fr_MC"; + } + return "fr"; + case 0x62: /* FRISIAN */ return "fy_NL"; + case 0x67: /* FULFULDE */ return "ful_NG"; + case 0x3c: /* GAELIC */ + switch (sub) + { + case 0x01: /* SCOTTISH */ return "gd_GB"; + case 0x02: /* IRISH */ return "ga_IE"; + } + return "C"; + case LANG_GALICIAN: return "gl_ES"; + case LANG_GEORGIAN: return "ka_GE"; + case LANG_GERMAN: + switch (sub) + { + case SUBLANG_GERMAN: return "de_DE"; + case SUBLANG_GERMAN_SWISS: return "de_CH"; + case SUBLANG_GERMAN_AUSTRIAN: return "de_AT"; + case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU"; + case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI"; + } + return "de"; + case LANG_GREEK: return "el_GR"; + case 0x74: /* GUARANI */ return "gn_PY"; + case LANG_GUJARATI: return "gu_IN"; + case 0x68: /* HAUSA */ return "ha_NG"; + case 0x75: /* HAWAIIAN */ + /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers) + or Hawaii Creole English ("cpe_US", 600000 speakers)? */ + return "cpe_US"; + case LANG_HEBREW: return "he_IL"; + case LANG_HINDI: return "hi_IN"; + case LANG_HUNGARIAN: return "hu_HU"; + case 0x69: /* IBIBIO */ return "nic_NG"; + case LANG_ICELANDIC: return "is_IS"; + case 0x70: /* IGBO */ return "ibo_NG"; + case LANG_INDONESIAN: return "id_ID"; + case 0x5d: /* INUKTITUT */ return "iu_CA"; + case LANG_ITALIAN: + switch (sub) + { + case SUBLANG_ITALIAN: return "it_IT"; + case SUBLANG_ITALIAN_SWISS: return "it_CH"; + } + return "it"; + case LANG_JAPANESE: return "ja_JP"; + case LANG_KANNADA: return "kn_IN"; + case 0x71: /* KANURI */ return "kau_NG"; + case LANG_KASHMIRI: + switch (sub) + { + case SUBLANG_DEFAULT: return "ks_PK"; + case SUBLANG_KASHMIRI_INDIA: return "ks_IN"; + } + return "ks"; + case LANG_KAZAK: return "kk_KZ"; + case LANG_KONKANI: + /* FIXME: Adjust this when such locales appear on Unix. */ + return "kok_IN"; + case LANG_KOREAN: return "ko_KR"; + case LANG_KYRGYZ: return "ky_KG"; + case 0x54: /* LAO */ return "lo_LA"; + case 0x76: /* LATIN */ return "la_VA"; + case LANG_LATVIAN: return "lv_LV"; + case LANG_LITHUANIAN: return "lt_LT"; + case LANG_MACEDONIAN: return "mk_MK"; + case LANG_MALAY: + switch (sub) + { + case SUBLANG_MALAY_MALAYSIA: return "ms_MY"; + case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN"; + } + return "ms"; + case LANG_MALAYALAM: return "ml_IN"; + case 0x3a: /* MALTESE */ return "mt_MT"; + case LANG_MANIPURI: + /* FIXME: Adjust this when such locales appear on Unix. */ + return "mni_IN"; + case LANG_MARATHI: return "mr_IN"; + case LANG_MONGOLIAN: + return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */ + case LANG_NEPALI: + switch (sub) + { + case SUBLANG_DEFAULT: return "ne_NP"; + case SUBLANG_NEPALI_INDIA: return "ne_IN"; + } + return "ne"; + case LANG_NORWEGIAN: + switch (sub) + { + case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO"; + case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO"; + } + return "no"; + case LANG_ORIYA: return "or_IN"; + case 0x72: /* OROMO */ return "om_ET"; + case 0x79: /* PAPIAMENTU */ return "pap_AN"; + case 0x63: /* PASHTO */ + return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */ + case LANG_POLISH: return "pl_PL"; + case LANG_PORTUGUESE: + switch (sub) + { + case SUBLANG_PORTUGUESE: return "pt_PT"; + /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT. + Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */ + case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR"; + } + return "pt"; + case LANG_PUNJABI: return "pa_IN"; + case 0x17: /* RHAETO-ROMANCE */ return "rm_CH"; + case LANG_ROMANIAN: return "ro_RO"; + case LANG_RUSSIAN: + return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA". */ + case 0x3b: /* SAMI */ return "se_NO"; + case LANG_SANSKRIT: return "sa_IN"; + case LANG_SINDHI: return "sd"; + case 0x5b: /* SINHALESE */ return "si_LK"; + case LANG_SLOVAK: return "sk_SK"; + case LANG_SLOVENIAN: return "sl_SI"; + case 0x77: /* SOMALI */ return "so_SO"; + case LANG_SORBIAN: + /* FIXME: Adjust this when such locales appear on Unix. */ + return "wen_DE"; + case LANG_SPANISH: + switch (sub) + { + case SUBLANG_SPANISH: return "es_ES"; + case SUBLANG_SPANISH_MEXICAN: return "es_MX"; + case SUBLANG_SPANISH_MODERN: + return "es_ES@modern"; /* not seen on Unix */ + case SUBLANG_SPANISH_GUATEMALA: return "es_GT"; + case SUBLANG_SPANISH_COSTA_RICA: return "es_CR"; + case SUBLANG_SPANISH_PANAMA: return "es_PA"; + case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO"; + case SUBLANG_SPANISH_VENEZUELA: return "es_VE"; + case SUBLANG_SPANISH_COLOMBIA: return "es_CO"; + case SUBLANG_SPANISH_PERU: return "es_PE"; + case SUBLANG_SPANISH_ARGENTINA: return "es_AR"; + case SUBLANG_SPANISH_ECUADOR: return "es_EC"; + case SUBLANG_SPANISH_CHILE: return "es_CL"; + case SUBLANG_SPANISH_URUGUAY: return "es_UY"; + case SUBLANG_SPANISH_PARAGUAY: return "es_PY"; + case SUBLANG_SPANISH_BOLIVIA: return "es_BO"; + case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV"; + case SUBLANG_SPANISH_HONDURAS: return "es_HN"; + case SUBLANG_SPANISH_NICARAGUA: return "es_NI"; + case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR"; + } + return "es"; + case 0x30: /* SUTU */ return "bnt_TZ"; + case LANG_SWAHILI: return "sw_KE"; + case LANG_SWEDISH: + switch (sub) + { + case SUBLANG_DEFAULT: return "sv_SE"; + case SUBLANG_SWEDISH_FINLAND: return "sv_FI"; + } + return "sv"; + case LANG_SYRIAC: return "syr_TR"; /* An extinct language. */ + case 0x64: /* TAGALOG */ return "tl_PH"; + case 0x28: /* TAJIK */ return "tg_TJ"; + case 0x5f: /* TAMAZIGHT */ return "ber_MA"; + case LANG_TAMIL: + return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */ + case LANG_TATAR: return "tt_RU"; + case LANG_TELUGU: return "te_IN"; + case LANG_THAI: return "th_TH"; + case 0x51: /* TIBETAN */ return "bo_CN"; + case 0x73: /* TIGRINYA */ return "ti_ET"; + case 0x31: /* TSONGA */ return "ts_ZA"; + case LANG_TURKISH: return "tr_TR"; + case 0x42: /* TURKMEN */ return "tk_TM"; + case LANG_UKRAINIAN: return "uk_UA"; + case LANG_URDU: + switch (sub) + { + case SUBLANG_URDU_PAKISTAN: return "ur_PK"; + case SUBLANG_URDU_INDIA: return "ur_IN"; + } + return "ur"; + case LANG_UZBEK: + switch (sub) + { + /* FIXME: Adjust this when Uzbek locales appear on Unix. */ + case SUBLANG_UZBEK_LATIN: return "uz_UZ@latin"; + case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic"; + } + return "uz"; + case 0x33: /* VENDA */ return "ven_ZA"; + case LANG_VIETNAMESE: return "vi_VN"; + case 0x52: /* WELSH */ return "cy_GB"; + case 0x34: /* XHOSA */ return "xh_ZA"; + case 0x78: /* YI */ return "sit_CN"; + case 0x3d: /* YIDDISH */ return "yi_IL"; + case 0x6a: /* YORUBA */ return "yo_NG"; + case 0x35: /* ZULU */ return "zu_ZA"; + default: return "C"; + } + +#endif +} diff --git a/utshell-0.5.0/lib/intl/log.c b/utshell-0.5.0/lib/intl/log.c new file mode 100644 index 00000000..e527e879 --- /dev/null +++ b/utshell-0.5.0/lib/intl/log.c @@ -0,0 +1,106 @@ +/* log.c - Log file output. */ + +/* Copyright (C) 2003, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Written by Bruno Haible . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +/* Print an ASCII string with quotes and escape sequences where needed. */ +static void +print_escaped (stream, str) + FILE *stream; + const char *str; +{ + putc ('"', stream); + for (; *str != '\0'; str++) + if (*str == '\n') + { + fputs ("\\n\"", stream); + if (str[1] == '\0') + return; + fputs ("\n\"", stream); + } + else + { + if (*str == '"' || *str == '\\') + putc ('\\', stream); + putc (*str, stream); + } + putc ('"', stream); +} + +/* Add to the log file an entry denoting a failed translation. */ +void +_nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural) + const char *logfilename; + const char *domainname; + const char *msgid1; + const char *msgid2; + int plural; +{ + static char *last_logfilename = NULL; + static FILE *last_logfile = NULL; + FILE *logfile; + + /* Can we reuse the last opened logfile? */ + if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0) + { + /* Close the last used logfile. */ + if (last_logfilename != NULL) + { + if (last_logfile != NULL) + { + fclose (last_logfile); + last_logfile = NULL; + } + free (last_logfilename); + last_logfilename = NULL; + } + /* Open the logfile. */ + last_logfilename = (char *) malloc (strlen (logfilename) + 1); + if (last_logfilename == NULL) + return; + strcpy (last_logfilename, logfilename); + last_logfile = fopen (logfilename, "a"); + if (last_logfile == NULL) + return; + } + logfile = last_logfile; + + fprintf (logfile, "domain "); + print_escaped (logfile, domainname); + fprintf (logfile, "\nmsgid "); + print_escaped (logfile, msgid1); + if (plural) + { + fprintf (logfile, "\nmsgid_plural "); + print_escaped (logfile, msgid2); + fprintf (logfile, "\nmsgstr[0] \"\"\n"); + } + else + fprintf (logfile, "\nmsgstr \"\"\n"); + putc ('\n', logfile); +} diff --git a/utshell-0.5.0/lib/intl/ngettext.c b/utshell-0.5.0/lib/intl/ngettext.c new file mode 100644 index 00000000..95aafccd --- /dev/null +++ b/utshell-0.5.0/lib/intl/ngettext.c @@ -0,0 +1,70 @@ +/* ngettext.c - Implementation of ngettext(3) function. */ + +/* Copyright (C) 1995, 1997, 2000, 2001, 2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define __need_NULL +# include +#else +# include /* Just for NULL. */ +#endif + +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif + +#include + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define NGETTEXT __ngettext +# define DCNGETTEXT __dcngettext +#else +# define NGETTEXT libintl_ngettext +# define DCNGETTEXT libintl_dcngettext +#endif + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +char * +NGETTEXT (msgid1, msgid2, n) + const char *msgid1; + const char *msgid2; + unsigned long int n; +{ + return DCNGETTEXT (NULL, msgid1, msgid2, n, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__ngettext, ngettext); +#endif diff --git a/utshell-0.5.0/lib/intl/os2compat.c b/utshell-0.5.0/lib/intl/os2compat.c new file mode 100644 index 00000000..1aa9dff8 --- /dev/null +++ b/utshell-0.5.0/lib/intl/os2compat.c @@ -0,0 +1,100 @@ +/* os2compat.c - OS/2 compatibility functions. */ + +/* Copyright (C) 2001-2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#define OS2_AWARE +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +/* A version of getenv() that works from DLLs */ +extern unsigned long DosScanEnv (const unsigned char *pszName, unsigned char **ppszValue); + +char * +_nl_getenv (const char *name) +{ + unsigned char *value; + if (DosScanEnv (name, &value)) + return NULL; + else + return value; +} + +/* A fixed size buffer. */ +char libintl_nl_default_dirname[MAXPATHLEN+1]; + +char *_nlos2_libdir = NULL; +char *_nlos2_localealiaspath = NULL; +char *_nlos2_localedir = NULL; + +static __attribute__((constructor)) void +nlos2_initialize () +{ + char *root = getenv ("UNIXROOT"); + char *gnulocaledir = getenv ("GNULOCALEDIR"); + + _nlos2_libdir = gnulocaledir; + if (!_nlos2_libdir) + { + if (root) + { + size_t sl = strlen (root); + _nlos2_libdir = (char *) malloc (sl + strlen (LIBDIR) + 1); + memcpy (_nlos2_libdir, root, sl); + memcpy (_nlos2_libdir + sl, LIBDIR, strlen (LIBDIR) + 1); + } + else + _nlos2_libdir = LIBDIR; + } + + _nlos2_localealiaspath = gnulocaledir; + if (!_nlos2_localealiaspath) + { + if (root) + { + size_t sl = strlen (root); + _nlos2_localealiaspath = (char *) malloc (sl + strlen (LOCALE_ALIAS_PATH) + 1); + memcpy (_nlos2_localealiaspath, root, sl); + memcpy (_nlos2_localealiaspath + sl, LOCALE_ALIAS_PATH, strlen (LOCALE_ALIAS_PATH) + 1); + } + else + _nlos2_localealiaspath = LOCALE_ALIAS_PATH; + } + + _nlos2_localedir = gnulocaledir; + if (!_nlos2_localedir) + { + if (root) + { + size_t sl = strlen (root); + _nlos2_localedir = (char *) malloc (sl + strlen (LOCALEDIR) + 1); + memcpy (_nlos2_localedir, root, sl); + memcpy (_nlos2_localedir + sl, LOCALEDIR, strlen (LOCALEDIR) + 1); + } + else + _nlos2_localedir = LOCALEDIR; + } + + if (strlen (_nlos2_localedir) <= MAXPATHLEN) + strcpy (libintl_nl_default_dirname, _nlos2_localedir); +} diff --git a/utshell-0.5.0/lib/intl/os2compat.h b/utshell-0.5.0/lib/intl/os2compat.h new file mode 100644 index 00000000..8de31830 --- /dev/null +++ b/utshell-0.5.0/lib/intl/os2compat.h @@ -0,0 +1,48 @@ +/* os2compat.h - OS/2 compatibility defines. */ + +/* This file is intended to be included from config.h + Copyright (C) 2001-2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* When included from os2compat.h we need all the original definitions */ +#ifndef OS2_AWARE + +#undef LIBDIR +#define LIBDIR _nlos2_libdir +extern char *_nlos2_libdir; + +#undef LOCALEDIR +#define LOCALEDIR _nlos2_localedir +extern char *_nlos2_localedir; + +#undef LOCALE_ALIAS_PATH +#define LOCALE_ALIAS_PATH _nlos2_localealiaspath +extern char *_nlos2_localealiaspath; + +#endif + +#undef HAVE_STRCASECMP +#define HAVE_STRCASECMP 1 +#define strcasecmp stricmp +#define strncasecmp strnicmp + +/* We have our own getenv() which works even if library is compiled as DLL */ +#define getenv _nl_getenv + +/* Older versions of gettext used -1 as the value of LC_MESSAGES */ +#define LC_MESSAGES_COMPAT (-1) diff --git a/utshell-0.5.0/lib/intl/osdep.c b/utshell-0.5.0/lib/intl/osdep.c new file mode 100644 index 00000000..b0300222 --- /dev/null +++ b/utshell-0.5.0/lib/intl/osdep.c @@ -0,0 +1,26 @@ +/* osdep.c - OS dependent parts of libintl. */ + +/* Copyright (C) 2001-2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if defined __EMX__ +# include "os2compat.c" +#else +/* Avoid AIX compiler warning. */ +typedef int dummy; +#endif diff --git a/utshell-0.5.0/lib/intl/plural-exp.c b/utshell-0.5.0/lib/intl/plural-exp.c new file mode 100644 index 00000000..9ed3b16f --- /dev/null +++ b/utshell-0.5.0/lib/intl/plural-exp.c @@ -0,0 +1,158 @@ +/* plural-exp.c - Expression parsing for plural form selection. */ + +/* Copyright (C) 2000, 2001, 2005-2009 Free Software Foundation, Inc. + Written by Ulrich Drepper , 2000. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "plural-exp.h" + +#if (defined __GNUC__ && !defined __APPLE_CC__) \ + || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) + +/* These structs are the constant expression for the germanic plural + form determination. It represents the expression "n != 1". */ +static const struct expression plvar = +{ + .nargs = 0, + .operation = var, +}; +static const struct expression plone = +{ + .nargs = 0, + .operation = num, + .val = + { + .num = 1 + } +}; +struct expression GERMANIC_PLURAL = +{ + .nargs = 2, + .operation = not_equal, + .val = + { + .args = + { + [0] = (struct expression *) &plvar, + [1] = (struct expression *) &plone + } + } +}; + +# define INIT_GERMANIC_PLURAL() + +#else + +/* For compilers without support for ISO C 99 struct/union initializers: + Initialization at run-time. */ + +static struct expression plvar; +static struct expression plone; +struct expression GERMANIC_PLURAL; + +static void +init_germanic_plural () +{ + if (plone.val.num == 0) + { + plvar.nargs = 0; + plvar.operation = var; + + plone.nargs = 0; + plone.operation = num; + plone.val.num = 1; + + GERMANIC_PLURAL.nargs = 2; + GERMANIC_PLURAL.operation = not_equal; + GERMANIC_PLURAL.val.args[0] = &plvar; + GERMANIC_PLURAL.val.args[1] = &plone; + } +} + +# define INIT_GERMANIC_PLURAL() init_germanic_plural () + +#endif + +void +internal_function +EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp) + const char *nullentry; + struct expression **pluralp; + unsigned long int *npluralsp; +{ + if (nullentry != NULL) + { + const char *plural; + const char *nplurals; + + plural = strstr (nullentry, "plural="); + nplurals = strstr (nullentry, "nplurals="); + if (plural == NULL || nplurals == NULL) + goto no_plural; + else + { + char *endp; + unsigned long int n; + struct parse_args args; + + /* First get the number. */ + nplurals += 9; + while (*nplurals != '\0' && isspace ((unsigned char) *nplurals)) + ++nplurals; + if (!(*nplurals >= '0' && *nplurals <= '9')) + goto no_plural; +#if defined HAVE_STRTOUL || defined _LIBC + n = strtoul (nplurals, &endp, 10); +#else + for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++) + n = n * 10 + (*endp - '0'); +#endif + if (nplurals == endp) + goto no_plural; + *npluralsp = n; + + /* Due to the restrictions bison imposes onto the interface of the + scanner function we have to put the input string and the result + passed up from the parser into the same structure which address + is passed down to the parser. */ + plural += 7; + args.cp = plural; + if (PLURAL_PARSE (&args) != 0) + goto no_plural; + *pluralp = args.res; + } + } + else + { + /* By default we are using the Germanic form: singular form only + for `one', the plural form otherwise. Yes, this is also what + English is using since English is a Germanic language. */ + no_plural: + INIT_GERMANIC_PLURAL (); + *pluralp = &GERMANIC_PLURAL; + *npluralsp = 2; + } +} diff --git a/utshell-0.5.0/lib/intl/plural-exp.h b/utshell-0.5.0/lib/intl/plural-exp.h new file mode 100644 index 00000000..dcb0dae0 --- /dev/null +++ b/utshell-0.5.0/lib/intl/plural-exp.h @@ -0,0 +1,128 @@ +/* plural-exp.h - defines for expression parsing and evaluation for plural form selection. */ + +/* Copyright (C) 2000, 2001, 2002, 2005-2009 Free Software Foundation, Inc. + Written by Ulrich Drepper , 2000. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _PLURAL_EXP_H +#define _PLURAL_EXP_H + +#ifndef PARAMS +# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + + +/* This is the representation of the expressions to determine the + plural form. */ +struct expression +{ + int nargs; /* Number of arguments. */ + enum operator + { + /* Without arguments: */ + var, /* The variable "n". */ + num, /* Decimal number. */ + /* Unary operators: */ + lnot, /* Logical NOT. */ + /* Binary operators: */ + mult, /* Multiplication. */ + divide, /* Division. */ + module, /* Modulo operation. */ + plus, /* Addition. */ + minus, /* Subtraction. */ + less_than, /* Comparison. */ + greater_than, /* Comparison. */ + less_or_equal, /* Comparison. */ + greater_or_equal, /* Comparison. */ + equal, /* Comparison for equality. */ + not_equal, /* Comparison for inequality. */ + land, /* Logical AND. */ + lor, /* Logical OR. */ + /* Ternary operators: */ + qmop /* Question mark operator. */ + } operation; + union + { + unsigned long int num; /* Number value for `num'. */ + struct expression *args[3]; /* Up to three arguments. */ + } val; +}; + +/* This is the data structure to pass information to the parser and get + the result in a thread-safe way. */ +struct parse_args +{ + const char *cp; + struct expression *res; +}; + + +/* Names for the libintl functions are a problem. This source code is used + 1. in the GNU C Library library, + 2. in the GNU libintl library, + 3. in the GNU gettext tools. + The function names in each situation must be different, to allow for + binary incompatible changes in 'struct expression'. Furthermore, + 1. in the GNU C Library library, the names have a __ prefix, + 2.+3. in the GNU libintl library and in the GNU gettext tools, the names + must follow ANSI C and not start with __. + So we have to distinguish the three cases. */ +#ifdef _LIBC +# define FREE_EXPRESSION __gettext_free_exp +# define PLURAL_PARSE __gettextparse +# define GERMANIC_PLURAL __gettext_germanic_plural +# define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural +#elif defined (IN_LIBINTL) +# define FREE_EXPRESSION libintl_gettext_free_exp +# define PLURAL_PARSE libintl_gettextparse +# define GERMANIC_PLURAL libintl_gettext_germanic_plural +# define EXTRACT_PLURAL_EXPRESSION libintl_gettext_extract_plural +#else +# define FREE_EXPRESSION free_plural_expression +# define PLURAL_PARSE parse_plural_expression +# define GERMANIC_PLURAL germanic_plural +# define EXTRACT_PLURAL_EXPRESSION extract_plural_expression +#endif + +extern void FREE_EXPRESSION PARAMS ((struct expression *exp)) + internal_function; +extern int PLURAL_PARSE PARAMS ((void *arg)); +extern struct expression GERMANIC_PLURAL attribute_hidden; +extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry, + struct expression **pluralp, + unsigned long int *npluralsp)) + internal_function; + +#if !defined (_LIBC) && !defined (IN_LIBINTL) +extern unsigned long int plural_eval PARAMS ((struct expression *pexp, + unsigned long int n)); +#endif + +#endif /* _PLURAL_EXP_H */ diff --git a/utshell-0.5.0/lib/intl/plural.c b/utshell-0.5.0/lib/intl/plural.c new file mode 100644 index 00000000..a0031513 --- /dev/null +++ b/utshell-0.5.0/lib/intl/plural.c @@ -0,0 +1,1679 @@ +/* A Bison parser, made by GNU Bison 2.0. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse __gettextparse +#define yylex __gettextlex +#define yyerror __gettexterror +#define yylval __gettextlval +#define yychar __gettextchar +#define yydebug __gettextdebug +#define yynerrs __gettextnerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + EQUOP2 = 258, + CMPOP2 = 259, + ADDOP2 = 260, + MULOP2 = 261, + NUMBER = 262 + }; +#endif +#define EQUOP2 258 +#define CMPOP2 259 +#define ADDOP2 260 +#define MULOP2 261 +#define NUMBER 262 + + + + +/* Copy the first part of user declarations. */ +#line 1 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + +/* plural.y - Expression parsing for plural form selection. */ + +/* Copyright (C) 2000, 2001, 2005-2009 Free Software Foundation, Inc. + Written by Ulrich Drepper , 2000. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* The bison generated parser uses alloca. AIX 3 forces us to put this + declaration at the beginning of the file. The declaration in bison's + skeleton file comes too late. This must come before + because may include arbitrary system headers. */ +#if defined _AIX && !defined __GNUC__ + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "plural-exp.h" + +/* The main function generated by the parser is called __gettextparse, + but we want it to be called PLURAL_PARSE. */ +#ifndef _LIBC +# define __gettextparse PLURAL_PARSE +#endif + +#define YYLEX_PARAM &((struct parse_args *) arg)->cp +#define YYPARSE_PARAM arg + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 51 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" +typedef union YYSTYPE { + unsigned long int num; + enum operator op; + struct expression *exp; +} YYSTYPE; +/* Line 190 of yacc.c. */ +#line 152 "/usr/src/local/bash/bash-20080814/lib/intl/plural.c" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ +#line 57 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + +/* Prototypes for local functions. */ +static struct expression *new_exp PARAMS ((int nargs, enum operator op, + struct expression * const *args)); +static inline struct expression *new_exp_0 PARAMS ((enum operator op)); +static inline struct expression *new_exp_1 PARAMS ((enum operator op, + struct expression *right)); +static struct expression *new_exp_2 PARAMS ((enum operator op, + struct expression *left, + struct expression *right)); +static inline struct expression *new_exp_3 PARAMS ((enum operator op, + struct expression *bexp, + struct expression *tbranch, + struct expression *fbranch)); +static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); +static void yyerror PARAMS ((const char *str)); + +/* Allocation of expressions. */ + +static struct expression * +new_exp (nargs, op, args) + int nargs; + enum operator op; + struct expression * const *args; +{ + int i; + struct expression *newp; + + /* If any of the argument could not be malloc'ed, just return NULL. */ + for (i = nargs - 1; i >= 0; i--) + if (args[i] == NULL) + goto fail; + + /* Allocate a new expression. */ + newp = (struct expression *) malloc (sizeof (*newp)); + if (newp != NULL) + { + newp->nargs = nargs; + newp->operation = op; + for (i = nargs - 1; i >= 0; i--) + newp->val.args[i] = args[i]; + return newp; + } + + fail: + for (i = nargs - 1; i >= 0; i--) + FREE_EXPRESSION (args[i]); + + return NULL; +} + +static inline struct expression * +new_exp_0 (op) + enum operator op; +{ + return new_exp (0, op, NULL); +} + +static inline struct expression * +new_exp_1 (op, right) + enum operator op; + struct expression *right; +{ + struct expression *args[1]; + + args[0] = right; + return new_exp (1, op, args); +} + +static struct expression * +new_exp_2 (op, left, right) + enum operator op; + struct expression *left; + struct expression *right; +{ + struct expression *args[2]; + + args[0] = left; + args[1] = right; + return new_exp (2, op, args); +} + +static inline struct expression * +new_exp_3 (op, bexp, tbranch, fbranch) + enum operator op; + struct expression *bexp; + struct expression *tbranch; + struct expression *fbranch; +{ + struct expression *args[3]; + + args[0] = bexp; + args[1] = tbranch; + args[2] = fbranch; + return new_exp (3, op, args); +} + + + +/* Line 213 of yacc.c. */ +#line 262 "/usr/src/local/bash/bash-20080814/lib/intl/plural.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# else +# define YYSTACK_ALLOC alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 9 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 54 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 16 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 3 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 13 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 27 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 262 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 10, 2, 2, 2, 2, 5, 2, + 14, 15, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, + 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 6, 7, + 8, 9, 11 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 5, 11, 15, 19, 23, 27, 31, + 35, 38, 40, 42 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 17, 0, -1, 18, -1, 18, 3, 18, 12, 18, + -1, 18, 4, 18, -1, 18, 5, 18, -1, 18, + 6, 18, -1, 18, 7, 18, -1, 18, 8, 18, + -1, 18, 9, 18, -1, 10, 18, -1, 13, -1, + 11, -1, 14, 18, 15, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned char yyrline[] = +{ + 0, 176, 176, 184, 188, 192, 196, 200, 204, 208, + 212, 216, 220, 225 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "'?'", "'|'", "'&'", "EQUOP2", "CMPOP2", + "ADDOP2", "MULOP2", "'!'", "NUMBER", "':'", "'n'", "'('", "')'", + "$accept", "start", "exp", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 63, 124, 38, 258, 259, 260, 261, + 33, 262, 58, 110, 40, 41 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 5, 3, 3, 3, 3, 3, 3, + 2, 1, 1, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 0, 0, 12, 11, 0, 0, 2, 10, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, + 5, 6, 7, 8, 9, 0, 3 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 5, 6 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -10 +static const yysigned_char yypact[] = +{ + -9, -9, -10, -10, -9, 8, 36, -10, 13, -10, + -9, -9, -9, -9, -9, -9, -9, -10, 26, 41, + 45, 18, -2, 14, -10, -9, 36 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -10, -10, -1 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const unsigned char yytable[] = +{ + 7, 1, 2, 8, 3, 4, 15, 16, 9, 18, + 19, 20, 21, 22, 23, 24, 10, 11, 12, 13, + 14, 15, 16, 16, 26, 14, 15, 16, 17, 10, + 11, 12, 13, 14, 15, 16, 0, 0, 25, 10, + 11, 12, 13, 14, 15, 16, 12, 13, 14, 15, + 16, 13, 14, 15, 16 +}; + +static const yysigned_char yycheck[] = +{ + 1, 10, 11, 4, 13, 14, 8, 9, 0, 10, + 11, 12, 13, 14, 15, 16, 3, 4, 5, 6, + 7, 8, 9, 9, 25, 7, 8, 9, 15, 3, + 4, 5, 6, 7, 8, 9, -1, -1, 12, 3, + 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, + 9, 6, 7, 8, 9 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 10, 11, 13, 14, 17, 18, 18, 18, 0, + 3, 4, 5, 6, 7, 8, 9, 15, 18, 18, + 18, 18, 18, 18, 18, 12, 18 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + /* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + + yyvsp[0] = yylval; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a look-ahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to look-ahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 177 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + if ((yyvsp[0].exp) == NULL) + YYABORT; + ((struct parse_args *) arg)->res = (yyvsp[0].exp); + } + break; + + case 3: +#line 185 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_3 (qmop, (yyvsp[-4].exp), (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 4: +#line 189 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_2 (lor, (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 5: +#line 193 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_2 (land, (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 6: +#line 197 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 7: +#line 201 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 8: +#line 205 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 9: +#line 209 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_2 ((yyvsp[-1].op), (yyvsp[-2].exp), (yyvsp[0].exp)); + } + break; + + case 10: +#line 213 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_1 (lnot, (yyvsp[0].exp)); + } + break; + + case 11: +#line 217 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = new_exp_0 (var); + } + break; + + case 12: +#line 221 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + if (((yyval.exp) = new_exp_0 (num)) != NULL) + (yyval.exp)->val.num = (yyvsp[0].num); + } + break; + + case 13: +#line 226 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + { + (yyval.exp) = (yyvsp[-1].exp); + } + break; + + + } + +/* Line 1037 of yacc.c. */ +#line 1270 "/usr/src/local/bash/bash-20080814/lib/intl/plural.c" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + yydestruct ("Error: popping", + yystos[*yyssp], yyvsp); + } + } + else + { + yydestruct ("Error: discarding", yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + +yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yydestruct ("Error: discarding lookahead", + yytoken, &yylval); + yychar = YYEMPTY; + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 231 "/usr/src/local/bash/bash-20080814/lib/intl/plural.y" + + +void +internal_function +FREE_EXPRESSION (exp) + struct expression *exp; +{ + if (exp == NULL) + return; + + /* Handle the recursive case. */ + switch (exp->nargs) + { + case 3: + FREE_EXPRESSION (exp->val.args[2]); + /* FALLTHROUGH */ + case 2: + FREE_EXPRESSION (exp->val.args[1]); + /* FALLTHROUGH */ + case 1: + FREE_EXPRESSION (exp->val.args[0]); + /* FALLTHROUGH */ + default: + break; + } + + free (exp); +} + + +static int +yylex (lval, pexp) + YYSTYPE *lval; + const char **pexp; +{ + const char *exp = *pexp; + int result; + + while (1) + { + if (exp[0] == '\0') + { + *pexp = exp; + return YYEOF; + } + + if (exp[0] != ' ' && exp[0] != '\t') + break; + + ++exp; + } + + result = *exp++; + switch (result) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + unsigned long int n = result - '0'; + while (exp[0] >= '0' && exp[0] <= '9') + { + n *= 10; + n += exp[0] - '0'; + ++exp; + } + lval->num = n; + result = NUMBER; + } + break; + + case '=': + if (exp[0] == '=') + { + ++exp; + lval->op = equal; + result = EQUOP2; + } + else + result = YYERRCODE; + break; + + case '!': + if (exp[0] == '=') + { + ++exp; + lval->op = not_equal; + result = EQUOP2; + } + break; + + case '&': + case '|': + if (exp[0] == result) + ++exp; + else + result = YYERRCODE; + break; + + case '<': + if (exp[0] == '=') + { + ++exp; + lval->op = less_or_equal; + } + else + lval->op = less_than; + result = CMPOP2; + break; + + case '>': + if (exp[0] == '=') + { + ++exp; + lval->op = greater_or_equal; + } + else + lval->op = greater_than; + result = CMPOP2; + break; + + case '*': + lval->op = mult; + result = MULOP2; + break; + + case '/': + lval->op = divide; + result = MULOP2; + break; + + case '%': + lval->op = module; + result = MULOP2; + break; + + case '+': + lval->op = plus; + result = ADDOP2; + break; + + case '-': + lval->op = minus; + result = ADDOP2; + break; + + case 'n': + case '?': + case ':': + case '(': + case ')': + /* Nothing, just return the character. */ + break; + + case ';': + case '\n': + case '\0': + /* Be safe and let the user call this function again. */ + --exp; + result = YYEOF; + break; + + default: + result = YYERRCODE; +#if YYDEBUG != 0 + --exp; +#endif + break; + } + + *pexp = exp; + + return result; +} + + +static void +yyerror (str) + const char *str; +{ + /* Do nothing. We don't print error messages here. */ +} diff --git a/utshell-0.5.0/lib/intl/plural.y b/utshell-0.5.0/lib/intl/plural.y new file mode 100644 index 00000000..8b8cec7e --- /dev/null +++ b/utshell-0.5.0/lib/intl/plural.y @@ -0,0 +1,411 @@ +%{ +/* plural.y - Expression parsing for plural form selection. */ + +/* Copyright (C) 2000, 2001, 2005-2009 Free Software Foundation, Inc. + Written by Ulrich Drepper , 2000. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* The bison generated parser uses alloca. AIX 3 forces us to put this + declaration at the beginning of the file. The declaration in bison's + skeleton file comes too late. This must come before + because may include arbitrary system headers. */ +#if defined _AIX && !defined __GNUC__ + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "plural-exp.h" + +/* The main function generated by the parser is called __gettextparse, + but we want it to be called PLURAL_PARSE. */ +#ifndef _LIBC +# define __gettextparse PLURAL_PARSE +#endif + +#define YYLEX_PARAM &((struct parse_args *) arg)->cp +#define YYPARSE_PARAM arg +%} +%pure_parser +%expect 7 + +%union { + unsigned long int num; + enum operator op; + struct expression *exp; +} + +%{ +/* Prototypes for local functions. */ +static struct expression *new_exp PARAMS ((int nargs, enum operator op, + struct expression * const *args)); +static inline struct expression *new_exp_0 PARAMS ((enum operator op)); +static inline struct expression *new_exp_1 PARAMS ((enum operator op, + struct expression *right)); +static struct expression *new_exp_2 PARAMS ((enum operator op, + struct expression *left, + struct expression *right)); +static inline struct expression *new_exp_3 PARAMS ((enum operator op, + struct expression *bexp, + struct expression *tbranch, + struct expression *fbranch)); +static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); +static void yyerror PARAMS ((const char *str)); + +/* Allocation of expressions. */ + +static struct expression * +new_exp (nargs, op, args) + int nargs; + enum operator op; + struct expression * const *args; +{ + int i; + struct expression *newp; + + /* If any of the argument could not be malloc'ed, just return NULL. */ + for (i = nargs - 1; i >= 0; i--) + if (args[i] == NULL) + goto fail; + + /* Allocate a new expression. */ + newp = (struct expression *) malloc (sizeof (*newp)); + if (newp != NULL) + { + newp->nargs = nargs; + newp->operation = op; + for (i = nargs - 1; i >= 0; i--) + newp->val.args[i] = args[i]; + return newp; + } + + fail: + for (i = nargs - 1; i >= 0; i--) + FREE_EXPRESSION (args[i]); + + return NULL; +} + +static inline struct expression * +new_exp_0 (op) + enum operator op; +{ + return new_exp (0, op, NULL); +} + +static inline struct expression * +new_exp_1 (op, right) + enum operator op; + struct expression *right; +{ + struct expression *args[1]; + + args[0] = right; + return new_exp (1, op, args); +} + +static struct expression * +new_exp_2 (op, left, right) + enum operator op; + struct expression *left; + struct expression *right; +{ + struct expression *args[2]; + + args[0] = left; + args[1] = right; + return new_exp (2, op, args); +} + +static inline struct expression * +new_exp_3 (op, bexp, tbranch, fbranch) + enum operator op; + struct expression *bexp; + struct expression *tbranch; + struct expression *fbranch; +{ + struct expression *args[3]; + + args[0] = bexp; + args[1] = tbranch; + args[2] = fbranch; + return new_exp (3, op, args); +} + +%} + +/* This declares that all operators have the same associativity and the + precedence order as in C. See [Harbison, Steele: C, A Reference Manual]. + There is no unary minus and no bitwise operators. + Operators with the same syntactic behaviour have been merged into a single + token, to save space in the array generated by bison. */ +%right '?' /* ? */ +%left '|' /* || */ +%left '&' /* && */ +%left EQUOP2 /* == != */ +%left CMPOP2 /* < > <= >= */ +%left ADDOP2 /* + - */ +%left MULOP2 /* * / % */ +%right '!' /* ! */ + +%token EQUOP2 CMPOP2 ADDOP2 MULOP2 +%token NUMBER +%type exp + +%% + +start: exp + { + if ($1 == NULL) + YYABORT; + ((struct parse_args *) arg)->res = $1; + } + ; + +exp: exp '?' exp ':' exp + { + $$ = new_exp_3 (qmop, $1, $3, $5); + } + | exp '|' exp + { + $$ = new_exp_2 (lor, $1, $3); + } + | exp '&' exp + { + $$ = new_exp_2 (land, $1, $3); + } + | exp EQUOP2 exp + { + $$ = new_exp_2 ($2, $1, $3); + } + | exp CMPOP2 exp + { + $$ = new_exp_2 ($2, $1, $3); + } + | exp ADDOP2 exp + { + $$ = new_exp_2 ($2, $1, $3); + } + | exp MULOP2 exp + { + $$ = new_exp_2 ($2, $1, $3); + } + | '!' exp + { + $$ = new_exp_1 (lnot, $2); + } + | 'n' + { + $$ = new_exp_0 (var); + } + | NUMBER + { + if (($$ = new_exp_0 (num)) != NULL) + $$->val.num = $1; + } + | '(' exp ')' + { + $$ = $2; + } + ; + +%% + +void +internal_function +FREE_EXPRESSION (exp) + struct expression *exp; +{ + if (exp == NULL) + return; + + /* Handle the recursive case. */ + switch (exp->nargs) + { + case 3: + FREE_EXPRESSION (exp->val.args[2]); + /* FALLTHROUGH */ + case 2: + FREE_EXPRESSION (exp->val.args[1]); + /* FALLTHROUGH */ + case 1: + FREE_EXPRESSION (exp->val.args[0]); + /* FALLTHROUGH */ + default: + break; + } + + free (exp); +} + + +static int +yylex (lval, pexp) + YYSTYPE *lval; + const char **pexp; +{ + const char *exp = *pexp; + int result; + + while (1) + { + if (exp[0] == '\0') + { + *pexp = exp; + return YYEOF; + } + + if (exp[0] != ' ' && exp[0] != '\t') + break; + + ++exp; + } + + result = *exp++; + switch (result) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + unsigned long int n = result - '0'; + while (exp[0] >= '0' && exp[0] <= '9') + { + n *= 10; + n += exp[0] - '0'; + ++exp; + } + lval->num = n; + result = NUMBER; + } + break; + + case '=': + if (exp[0] == '=') + { + ++exp; + lval->op = equal; + result = EQUOP2; + } + else + result = YYERRCODE; + break; + + case '!': + if (exp[0] == '=') + { + ++exp; + lval->op = not_equal; + result = EQUOP2; + } + break; + + case '&': + case '|': + if (exp[0] == result) + ++exp; + else + result = YYERRCODE; + break; + + case '<': + if (exp[0] == '=') + { + ++exp; + lval->op = less_or_equal; + } + else + lval->op = less_than; + result = CMPOP2; + break; + + case '>': + if (exp[0] == '=') + { + ++exp; + lval->op = greater_or_equal; + } + else + lval->op = greater_than; + result = CMPOP2; + break; + + case '*': + lval->op = mult; + result = MULOP2; + break; + + case '/': + lval->op = divide; + result = MULOP2; + break; + + case '%': + lval->op = module; + result = MULOP2; + break; + + case '+': + lval->op = plus; + result = ADDOP2; + break; + + case '-': + lval->op = minus; + result = ADDOP2; + break; + + case 'n': + case '?': + case ':': + case '(': + case ')': + /* Nothing, just return the character. */ + break; + + case ';': + case '\n': + case '\0': + /* Be safe and let the user call this function again. */ + --exp; + result = YYEOF; + break; + + default: + result = YYERRCODE; +#if YYDEBUG != 0 + --exp; +#endif + break; + } + + *pexp = exp; + + return result; +} + + +static void +yyerror (str) + const char *str; +{ + /* Do nothing. We don't print error messages here. */ +} diff --git a/utshell-0.5.0/lib/intl/ref-add.sin b/utshell-0.5.0/lib/intl/ref-add.sin new file mode 100755 index 00000000..6fd32ed9 --- /dev/null +++ b/utshell-0.5.0/lib/intl/ref-add.sin @@ -0,0 +1,29 @@ +# Add this package to a list of references stored in a text file. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + ta + :a + s/ @PACKAGE@ / @PACKAGE@ / + tb + s/ $/ @PACKAGE@ / + :b + s/^/# Packages using this file:/ +} diff --git a/utshell-0.5.0/lib/intl/ref-del.sin b/utshell-0.5.0/lib/intl/ref-del.sin new file mode 100755 index 00000000..65ce9afa --- /dev/null +++ b/utshell-0.5.0/lib/intl/ref-del.sin @@ -0,0 +1,24 @@ +# Remove this package from a list of references stored in a text file. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + s/ @PACKAGE@ / / + s/^/# Packages using this file:/ +} diff --git a/utshell-0.5.0/lib/intl/relocatable.c b/utshell-0.5.0/lib/intl/relocatable.c new file mode 100644 index 00000000..34b2b183 --- /dev/null +++ b/utshell-0.5.0/lib/intl/relocatable.c @@ -0,0 +1,440 @@ +/* relocatable.c - Provide relocatable packages. */ + +/* Copyright (C) 2003, 2005-2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Tell glibc's to provide a prototype for getline(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Specification. */ +#include "relocatable.h" + +#if ENABLE_RELOCATABLE + +#include +#include +#include +#include + +#ifdef NO_XMALLOC +# define xmalloc malloc +#else +# include "xmalloc.h" +#endif + +#if DEPENDS_ON_LIBCHARSET +# include +#endif +#if DEPENDS_ON_LIBICONV && HAVE_ICONV +# include +#endif +#if DEPENDS_ON_LIBINTL && ENABLE_NLS +# include +#endif + +/* Faked cheap 'bool'. */ +#undef bool +#undef false +#undef true +#define bool int +#define false 0 +#define true 1 + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. + */ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_PATH_WITH_DIR(P) \ + (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) +# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) +# define FILESYSTEM_PREFIX_LEN(P) 0 +#endif + +/* Original installation prefix. */ +static char *orig_prefix; +static size_t orig_prefix_len; +/* Current installation prefix. */ +static char *curr_prefix; +static size_t curr_prefix_len; +/* These prefixes do not end in a slash. Anything that will be concatenated + to them must start with a slash. */ + +/* Sets the original and the current installation prefix of this module. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +static void +set_this_relocation_prefix (const char *orig_prefix_arg, + const char *curr_prefix_arg) +{ + if (orig_prefix_arg != NULL && curr_prefix_arg != NULL + /* Optimization: if orig_prefix and curr_prefix are equal, the + relocation is a nop. */ + && strcmp (orig_prefix_arg, curr_prefix_arg) != 0) + { + /* Duplicate the argument strings. */ + char *memory; + + orig_prefix_len = strlen (orig_prefix_arg); + curr_prefix_len = strlen (curr_prefix_arg); + memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1); +#ifdef NO_XMALLOC + if (memory != NULL) +#endif + { + memcpy (memory, orig_prefix_arg, orig_prefix_len + 1); + orig_prefix = memory; + memory += orig_prefix_len + 1; + memcpy (memory, curr_prefix_arg, curr_prefix_len + 1); + curr_prefix = memory; + return; + } + } + orig_prefix = NULL; + curr_prefix = NULL; + /* Don't worry about wasted memory here - this function is usually only + called once. */ +} + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +void +set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg) +{ + set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg); + + /* Now notify all dependent libraries. */ +#if DEPENDS_ON_LIBCHARSET + libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); +#endif +#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109 + libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); +#endif +#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix + libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); +#endif +} + +/* Convenience function: + Computes the current installation prefix, based on the original + installation prefix, the original installation directory of a particular + file, and the current pathname of this file. Returns NULL upon failure. */ +#ifdef IN_LIBRARY +#define compute_curr_prefix local_compute_curr_prefix +static +#endif +const char * +compute_curr_prefix (const char *orig_installprefix, + const char *orig_installdir, + const char *curr_pathname) +{ + const char *curr_installdir; + const char *rel_installdir; + + if (curr_pathname == NULL) + return NULL; + + /* Determine the relative installation directory, relative to the prefix. + This is simply the difference between orig_installprefix and + orig_installdir. */ + if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix)) + != 0) + /* Shouldn't happen - nothing should be installed outside $(prefix). */ + return NULL; + rel_installdir = orig_installdir + strlen (orig_installprefix); + + /* Determine the current installation directory. */ + { + const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname); + const char *p = curr_pathname + strlen (curr_pathname); + char *q; + + while (p > p_base) + { + p--; + if (ISSLASH (*p)) + break; + } + + q = (char *) xmalloc (p - curr_pathname + 1); +#ifdef NO_XMALLOC + if (q == NULL) + return NULL; +#endif + memcpy (q, curr_pathname, p - curr_pathname); + q[p - curr_pathname] = '\0'; + curr_installdir = q; + } + + /* Compute the current installation prefix by removing the trailing + rel_installdir from it. */ + { + const char *rp = rel_installdir + strlen (rel_installdir); + const char *cp = curr_installdir + strlen (curr_installdir); + const char *cp_base = + curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir); + + while (rp > rel_installdir && cp > cp_base) + { + bool same = false; + const char *rpi = rp; + const char *cpi = cp; + + while (rpi > rel_installdir && cpi > cp_base) + { + rpi--; + cpi--; + if (ISSLASH (*rpi) || ISSLASH (*cpi)) + { + if (ISSLASH (*rpi) && ISSLASH (*cpi)) + same = true; + break; + } +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS - case insignificant filesystem */ + if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi) + != (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi)) + break; +#else + if (*rpi != *cpi) + break; +#endif + } + if (!same) + break; + /* The last pathname component was the same. opi and cpi now point + to the slash before it. */ + rp = rpi; + cp = cpi; + } + + if (rp > rel_installdir) + /* Unexpected: The curr_installdir does not end with rel_installdir. */ + return NULL; + + { + size_t curr_prefix_len = cp - curr_installdir; + char *curr_prefix; + + curr_prefix = (char *) xmalloc (curr_prefix_len + 1); +#ifdef NO_XMALLOC + if (curr_prefix == NULL) + return NULL; +#endif + memcpy (curr_prefix, curr_installdir, curr_prefix_len); + curr_prefix[curr_prefix_len] = '\0'; + + return curr_prefix; + } + } +} + +#if defined PIC && defined INSTALLDIR + +/* Full pathname of shared library, or NULL. */ +static char *shared_library_fullname; + +#if defined _WIN32 || defined __WIN32__ + +/* Determine the full pathname of the shared library when it is loaded. */ + +BOOL WINAPI +DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved) +{ + (void) reserved; + + if (event == DLL_PROCESS_ATTACH) + { + /* The DLL is being loaded into an application's address range. */ + static char location[MAX_PATH]; + + if (!GetModuleFileName (module_handle, location, sizeof (location))) + /* Shouldn't happen. */ + return FALSE; + + if (!IS_PATH_WITH_DIR (location)) + /* Shouldn't happen. */ + return FALSE; + + shared_library_fullname = strdup (location); + } + + return TRUE; +} + +#else /* Unix */ + +static void +find_shared_library_fullname () +{ +#ifdef __linux__ + FILE *fp; + + /* Open the current process' maps file. It describes one VMA per line. */ + fp = fopen ("/proc/self/maps", "r"); + if (fp) + { + unsigned long address = (unsigned long) &find_shared_library_fullname; + for (;;) + { + unsigned long start, end; + int c; + + if (fscanf (fp, "%lx-%lx", &start, &end) != 2) + break; + if (address >= start && address <= end - 1) + { + /* Found it. Now see if this line contains a filename. */ + while (c = getc (fp), c != EOF && c != '\n' && c != '/') + continue; + if (c == '/') + { + size_t size; + int len; + + ungetc (c, fp); + shared_library_fullname = NULL; size = 0; + len = getline (&shared_library_fullname, &size, fp); + if (len >= 0) + { + /* Success: filled shared_library_fullname. */ + if (len > 0 && shared_library_fullname[len - 1] == '\n') + shared_library_fullname[len - 1] = '\0'; + } + } + break; + } + while (c = getc (fp), c != EOF && c != '\n') + continue; + } + fclose (fp); + } +#endif +} + +#endif /* WIN32 / Unix */ + +/* Return the full pathname of the current shared library. + Return NULL if unknown. + Guaranteed to work only on Linux and Woe32. */ +static char * +get_shared_library_fullname () +{ +#if !(defined _WIN32 || defined __WIN32__) + static bool tried_find_shared_library_fullname; + if (!tried_find_shared_library_fullname) + { + find_shared_library_fullname (); + tried_find_shared_library_fullname = true; + } +#endif + return shared_library_fullname; +} + +#endif /* PIC */ + +/* Returns the pathname, relocated according to the current installation + directory. */ +const char * +relocate (const char *pathname) +{ +#if defined PIC && defined INSTALLDIR + static int initialized; + + /* Initialization code for a shared library. */ + if (!initialized) + { + /* At this point, orig_prefix and curr_prefix likely have already been + set through the main program's set_program_name_and_installdir + function. This is sufficient in the case that the library has + initially been installed in the same orig_prefix. But we can do + better, to also cover the cases that 1. it has been installed + in a different prefix before being moved to orig_prefix and (later) + to curr_prefix, 2. unlike the program, it has not moved away from + orig_prefix. */ + const char *orig_installprefix = INSTALLPREFIX; + const char *orig_installdir = INSTALLDIR; + const char *curr_prefix_better; + + curr_prefix_better = + compute_curr_prefix (orig_installprefix, orig_installdir, + get_shared_library_fullname ()); + if (curr_prefix_better == NULL) + curr_prefix_better = curr_prefix; + + set_relocation_prefix (orig_installprefix, curr_prefix_better); + + initialized = 1; + } +#endif + + /* Note: It is not necessary to perform case insensitive comparison here, + even for DOS-like filesystems, because the pathname argument was + typically created from the same Makefile variable as orig_prefix came + from. */ + if (orig_prefix != NULL && curr_prefix != NULL + && strncmp (pathname, orig_prefix, orig_prefix_len) == 0) + { + if (pathname[orig_prefix_len] == '\0') + /* pathname equals orig_prefix. */ + return curr_prefix; + if (ISSLASH (pathname[orig_prefix_len])) + { + /* pathname starts with orig_prefix. */ + const char *pathname_tail = &pathname[orig_prefix_len]; + char *result = + (char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1); + +#ifdef NO_XMALLOC + if (result != NULL) +#endif + { + memcpy (result, curr_prefix, curr_prefix_len); + strcpy (result + curr_prefix_len, pathname_tail); + return result; + } + } + } + /* Nothing to relocate. */ + return pathname; +} + +#endif diff --git a/utshell-0.5.0/lib/intl/relocatable.h b/utshell-0.5.0/lib/intl/relocatable.h new file mode 100644 index 00000000..de57f446 --- /dev/null +++ b/utshell-0.5.0/lib/intl/relocatable.h @@ -0,0 +1,69 @@ +/* relocatable.h - Provide relocatable packages. */ + +/* Copyright (C) 2003, 2005-2009 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _RELOCATABLE_H +#define _RELOCATABLE_H + +/* This can be enabled through the configure --enable-relocatable option. */ +#if ENABLE_RELOCATABLE + +/* When building a DLL, we must export some functions. Note that because + this is a private .h file, we don't need to use __declspec(dllimport) + in any case. */ +#if defined _MSC_VER && BUILDING_DLL +# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport) +#else +# define RELOCATABLE_DLL_EXPORTED +#endif + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +extern RELOCATABLE_DLL_EXPORTED void + set_relocation_prefix (const char *orig_prefix, + const char *curr_prefix); + +/* Returns the pathname, relocated according to the current installation + directory. */ +extern const char * relocate (const char *pathname); + +/* Memory management: relocate() leaks memory, because it has to construct + a fresh pathname. If this is a problem because your program calls + relocate() frequently, think about caching the result. */ + +/* Convenience function: + Computes the current installation prefix, based on the original + installation prefix, the original installation directory of a particular + file, and the current pathname of this file. Returns NULL upon failure. */ +extern const char * compute_curr_prefix (const char *orig_installprefix, + const char *orig_installdir, + const char *curr_pathname); + +#else + +/* By default, we use the hardwired pathnames. */ +#define relocate(pathname) (pathname) + +#endif + +#endif /* _RELOCATABLE_H */ diff --git a/utshell-0.5.0/lib/intl/textdomain.c b/utshell-0.5.0/lib/intl/textdomain.c new file mode 100644 index 00000000..4bb0e800 --- /dev/null +++ b/utshell-0.5.0/lib/intl/textdomain.c @@ -0,0 +1,144 @@ +/* textdomain.c - Implementation of the textdomain(3) function. */ + +/* Copyright (C) 1995-1998, 2000, 2001, 2002, 2005-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#ifdef _LIBC +# include +#else +# include "libgnuintl.h" +#endif +#include "gettextP.h" + +#ifdef _LIBC +/* We have to handle multi-threaded applications. */ +# include +#else +/* Provide dummy implementation if this is outside glibc. */ +# define __libc_rwlock_define(CLASS, NAME) +# define __libc_rwlock_wrlock(NAME) +# define __libc_rwlock_unlock(NAME) +#endif + +/* The internal variables in the standalone libintl.a must have different + names than the internal variables in GNU libc, otherwise programs + using libintl.a cannot be linked statically. */ +#if !defined _LIBC +# define _nl_default_default_domain libintl_nl_default_default_domain +# define _nl_current_default_domain libintl_nl_current_default_domain +#endif + +/* @@ end of prolog @@ */ + +/* Name of the default text domain. */ +extern const char _nl_default_default_domain[] attribute_hidden; + +/* Default text domain in which entries for gettext(3) are to be found. */ +extern const char *_nl_current_default_domain attribute_hidden; + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define TEXTDOMAIN __textdomain +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define TEXTDOMAIN libintl_textdomain +#endif + +/* Lock variable to protect the global data in the gettext implementation. */ +__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +char * +TEXTDOMAIN (domainname) + const char *domainname; +{ + char *new_domain; + char *old_domain; + + /* A NULL pointer requests the current setting. */ + if (domainname == NULL) + return (char *) _nl_current_default_domain; + + __libc_rwlock_wrlock (_nl_state_lock); + + old_domain = (char *) _nl_current_default_domain; + + /* If domain name is the null string set to default domain "messages". */ + if (domainname[0] == '\0' + || strcmp (domainname, _nl_default_default_domain) == 0) + { + _nl_current_default_domain = _nl_default_default_domain; + new_domain = (char *) _nl_current_default_domain; + } + else if (strcmp (domainname, old_domain) == 0) + /* This can happen and people will use it to signal that some + environment variable changed. */ + new_domain = old_domain; + else + { + /* If the following malloc fails `_nl_current_default_domain' + will be NULL. This value will be returned and so signals we + are out of core. */ +#if defined _LIBC || defined HAVE_STRDUP + new_domain = strdup (domainname); +#else + size_t len = strlen (domainname) + 1; + new_domain = (char *) malloc (len); + if (new_domain != NULL) + memcpy (new_domain, domainname, len); +#endif + + if (new_domain != NULL) + _nl_current_default_domain = new_domain; + } + + /* We use this possibility to signal a change of the loaded catalogs + since this is most likely the case and there is no other easy we + to do it. Do it only when the call was successful. */ + if (new_domain != NULL) + { + ++_nl_msg_cat_cntr; + + if (old_domain != new_domain && old_domain != _nl_default_default_domain) + free (old_domain); + } + + __libc_rwlock_unlock (_nl_state_lock); + + return new_domain; +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__textdomain, textdomain); +#endif diff --git a/utshell-0.5.0/lib/malloc/Makefile b/utshell-0.5.0/lib/malloc/Makefile new file mode 100644 index 00000000..bf777c26 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/Makefile @@ -0,0 +1,138 @@ +# Skeleton Makefile for the GNU malloc code +# +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = . + +topdir = ../.. +BUILD_DIR = /root/utshell-0.5 + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CC = gcc +RANLIB = ranlib +AR = ar +ARFLAGS = cr +RM = rm -f +CP = cp +MV = mv + +SHELL = /bin/sh + +PROFILE_FLAGS = + +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security +LOCAL_CFLAGS = +CPPFLAGS = +LDFLAGS = -L./lib/termcap + +DEFS = -DHAVE_CONFIG_H +LOCAL_DEFS = -DSHELL + +LIBBUILD = ${BUILD_DIR}/lib + +BASHINCDIR = ${topdir}/include + +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = +LIBINTL_H = + +INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib $(INTL_INC) + +CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \ + $(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS) + +.c.o: + $(CC) $(CCFLAGS) -c $< + +.s.o: + $(CC) $(CCFLAGS) -c $< + +MALLOC_SOURCE = malloc.c +STUB_SOURCE = stub.c + +ALLOCA_SOURCE = alloca.c +ALLOCA_OBJECT = alloca.o + +MALLOC_SRC = +MALLOC = @MALLOC@ +ALLOCA = + +MALLOC_OBJS = malloc.o $(ALLOCA) trace.o stats.o table.o watch.o +STUB_OBJS = $(ALLOCA) stub.o + +.PHONY: malloc stubmalloc + +all: malloc + +malloc: ${MALLOC_OBJS} + ${RM} libmalloc.a + ${AR} ${ARFLAGS} libmalloc.a ${MALLOC_OBJS} + -test -n "$(RANLIB)" && $(RANLIB) libmalloc.a + +stubmalloc: ${STUB_OBJS} + ${RM} libmalloc.a + ${AR} ${ARFLAGS} libmalloc.a ${STUB_OBJS} + -test -n "$(RANLIB)" && $(RANLIB) libmalloc.a + +alloca: ${ALLOCA} + ${RM} libmalloc.a + ${AR} ${ARFLAGS} libmalloc.a ${ALLOCA} + -test -n "$(RANLIB)" && $(RANLIB) libmalloc.a + +alloca.o: $(srcdir)/$(ALLOCA_SOURCE) + $(CC) $(CCFLAGS) -c $(srcdir)/$(ALLOCA_SOURCE) + @- if test "$(ALLOCA_OBJECT)" != alloca.o ; then \ + mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \ + fi + +mostlyclean clean: + $(RM) *.o libmalloc.a + +distclean realclean maintainer-clean: clean + $(RM) Makefile + +alloca.o: $(BUILD_DIR)/config.h +malloc.o: $(BUILD_DIR)/config.h $(topdir)/bashtypes.h getpagesize.h +xmalloc.o: $(BUILD_DIR)/config.h $(BASHINCDIR)/ansi_stdlib.h +trace.o: ${BUILD_DIR}/config.h +stats.o: ${BUILD_DIR}/config.h +table.o: ${BUILD_DIR}/config.h +watch.o: ${BUILD_DIR}/config.h + +malloc.o: ${srcdir}/imalloc.h ${srcdir}/mstats.h +malloc.o: ${srcdir}/table.h ${srcdir}/watch.h +stats.o: ${srcdir}/imalloc.h ${srcdir}/mstats.h +trace.o: ${srcdir}/imalloc.h +table.o: ${srcdir}/imalloc.h ${srcdir}/table.h +watch.o: ${srcdir}/imalloc.h ${srcdir}/watch.h + +malloc.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +stats.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +trace.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +table.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +watch.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +# Rules for deficient makes, like SunOS and Solaris +stub.o: stub.c +malloc.o: malloc.c +table.o: table.c +trace.o: trace.c +stats.o: stats.c +watch.o: watch.c diff --git a/utshell-0.5.0/lib/malloc/Makefile.in b/utshell-0.5.0/lib/malloc/Makefile.in new file mode 100644 index 00000000..0ef3cfd5 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/Makefile.in @@ -0,0 +1,138 @@ +# Skeleton Makefile for the GNU malloc code +# +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = @srcdir@ +VPATH = @srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv + +SHELL = @MAKE_SHELL@ + +PROFILE_FLAGS = @PROFILE_FLAGS@ + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +LIBBUILD = ${BUILD_DIR}/lib + +BASHINCDIR = ${topdir}/include + +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = @INTL_INC@ +LIBINTL_H = @LIBINTL_H@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib $(INTL_INC) + +CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \ + $(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS) + +.c.o: + $(CC) $(CCFLAGS) -c $< + +.s.o: + $(CC) $(CCFLAGS) -c $< + +MALLOC_SOURCE = malloc.c +STUB_SOURCE = stub.c + +ALLOCA_SOURCE = alloca.c +ALLOCA_OBJECT = alloca.o + +MALLOC_SRC = @MALLOC_SRC@ +MALLOC = @MALLOC@ +ALLOCA = @ALLOCA@ + +MALLOC_OBJS = malloc.o $(ALLOCA) trace.o stats.o table.o watch.o +STUB_OBJS = $(ALLOCA) stub.o + +.PHONY: malloc stubmalloc + +all: malloc + +malloc: ${MALLOC_OBJS} + ${RM} libmalloc.a + ${AR} ${ARFLAGS} libmalloc.a ${MALLOC_OBJS} + -test -n "$(RANLIB)" && $(RANLIB) libmalloc.a + +stubmalloc: ${STUB_OBJS} + ${RM} libmalloc.a + ${AR} ${ARFLAGS} libmalloc.a ${STUB_OBJS} + -test -n "$(RANLIB)" && $(RANLIB) libmalloc.a + +alloca: ${ALLOCA} + ${RM} libmalloc.a + ${AR} ${ARFLAGS} libmalloc.a ${ALLOCA} + -test -n "$(RANLIB)" && $(RANLIB) libmalloc.a + +alloca.o: $(srcdir)/$(ALLOCA_SOURCE) + $(CC) $(CCFLAGS) -c $(srcdir)/$(ALLOCA_SOURCE) + @- if test "$(ALLOCA_OBJECT)" != alloca.o ; then \ + mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \ + fi + +mostlyclean clean: + $(RM) *.o libmalloc.a + +distclean realclean maintainer-clean: clean + $(RM) Makefile + +alloca.o: $(BUILD_DIR)/config.h +malloc.o: $(BUILD_DIR)/config.h $(topdir)/bashtypes.h getpagesize.h +xmalloc.o: $(BUILD_DIR)/config.h $(BASHINCDIR)/ansi_stdlib.h +trace.o: ${BUILD_DIR}/config.h +stats.o: ${BUILD_DIR}/config.h +table.o: ${BUILD_DIR}/config.h +watch.o: ${BUILD_DIR}/config.h + +malloc.o: ${srcdir}/imalloc.h ${srcdir}/mstats.h +malloc.o: ${srcdir}/table.h ${srcdir}/watch.h +stats.o: ${srcdir}/imalloc.h ${srcdir}/mstats.h +trace.o: ${srcdir}/imalloc.h +table.o: ${srcdir}/imalloc.h ${srcdir}/table.h +watch.o: ${srcdir}/imalloc.h ${srcdir}/watch.h + +malloc.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +stats.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +trace.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +table.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +watch.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +# Rules for deficient makes, like SunOS and Solaris +stub.o: stub.c +malloc.o: malloc.c +table.o: table.c +trace.o: trace.c +stats.o: stats.c +watch.o: watch.c diff --git a/utshell-0.5.0/lib/malloc/alloca.c b/utshell-0.5.0/lib/malloc/alloca.c new file mode 100644 index 00000000..26319c2d --- /dev/null +++ b/utshell-0.5.0/lib/malloc/alloca.c @@ -0,0 +1,482 @@ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +#include /* for size_t */ + +/* If alloca is defined somewhere, this file is not needed. */ +#ifndef alloca + +#ifdef emacs +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +#else +#define ADDRESS_FUNCTION(arg) &(arg) +#endif /* CRAY && CRAY_STACKSEG_END */ + +#if __STDC__ +typedef void *pointer; +#else +typedef char *pointer; +#endif + +#define NULL 0 + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. */ + +#ifndef emacs +#define malloc xmalloc +extern pointer xmalloc (); +#endif + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* Direction unknown. */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +#else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +#define STACK_DIR stack_dir + +static void +find_stack_direction () +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +#endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +pointer +alloca (size) + size_t size; +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = malloc (sizeof (header) + size); + /* Address of header. */ + + ((header *) new)->h.next = last_alloca_header; + ((header *) new)->h.deep = depth; + + last_alloca_header = (header *) new; + + /* User storage begins just after header. */ + + return (pointer) ((char *) new + sizeof (header)); + } +} + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) + +#ifdef DEBUG_I00AFUNC +#include +#endif + +#ifndef CRAY_STACK +#define CRAY_STACK +#ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +#else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +#endif /* CRAY2 */ +#endif /* not CRAY_STACK */ + +#ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +#else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + /* This might be _getb67() or GETB67 () or getb67 () */ + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +#endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +#endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +#endif /* not CRAY2 */ +#endif /* CRAY && CRAY_STACKSEG_END */ + +#endif /* no alloca */ +#endif /* !__GNUC__ || __GNUC__ < 2 */ diff --git a/utshell-0.5.0/lib/malloc/getpagesize.h b/utshell-0.5.0/lib/malloc/getpagesize.h new file mode 100644 index 00000000..a59eabeb --- /dev/null +++ b/utshell-0.5.0/lib/malloc/getpagesize.h @@ -0,0 +1,60 @@ +/* Emulation of getpagesize() for systems that need it. + Copyright (C) 1991-2003 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +# if defined (_SC_PAGESIZE) +# define getpagesize() sysconf(_SC_PAGESIZE) +# else +# if defined (_SC_PAGE_SIZE) +# define getpagesize() sysconf(_SC_PAGE_SIZE) +# endif /* _SC_PAGE_SIZE */ +# endif /* _SC_PAGESIZE */ +#endif + +#if !defined (getpagesize) +# if defined (HAVE_SYS_PARAM_H) +# include +# endif +# if defined (PAGESIZE) +# define getpagesize() PAGESIZE +# else /* !PAGESIZE */ +# if defined (EXEC_PAGESIZE) +# define getpagesize() EXEC_PAGESIZE +# else /* !EXEC_PAGESIZE */ +# if defined (NBPG) +# if !defined (CLSIZE) +# define CLSIZE 1 +# endif /* !CLSIZE */ +# define getpagesize() (NBPG * CLSIZE) +# else /* !NBPG */ +# if defined (NBPC) +# define getpagesize() NBPC +# endif /* NBPC */ +# endif /* !NBPG */ +# endif /* !EXEC_PAGESIZE */ +# endif /* !PAGESIZE */ +#endif /* !getpagesize */ + +#if !defined (getpagesize) +# define getpagesize() 4096 /* Just punt and use reasonable value */ +#endif diff --git a/utshell-0.5.0/lib/malloc/i386-alloca.s b/utshell-0.5.0/lib/malloc/i386-alloca.s new file mode 100644 index 00000000..01b2cfed --- /dev/null +++ b/utshell-0.5.0/lib/malloc/i386-alloca.s @@ -0,0 +1,16 @@ + .file "alloca.s" + .text + .align 4 + .def alloca; .val alloca; .scl 2; .type 044; .endef + .globl alloca +alloca: + popl %edx + popl %eax + addl $3,%eax + andl $0xfffffffc,%eax + subl %eax,%esp + movl %esp,%eax + pushl %eax + pushl %edx + ret + .def alloca; .val .; .scl -1; .endef diff --git a/utshell-0.5.0/lib/malloc/imalloc.h b/utshell-0.5.0/lib/malloc/imalloc.h new file mode 100644 index 00000000..d07adac2 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/imalloc.h @@ -0,0 +1,173 @@ +/* imalloc.h -- internal malloc definitions shared by source files. */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Must be included *after* config.h */ + +#ifndef _IMALLOC_H +#define _IMALLOC_H + +#ifdef MALLOC_DEBUG +#define MALLOC_STATS +#define MALLOC_TRACE +#define MALLOC_REGISTER +#define MALLOC_WATCH +#endif + +#define MALLOC_WRAPFUNCS + +/* Generic pointer type. */ +#ifndef PTR_T +# if defined (__STDC__) +# define PTR_T void * +# else +# define PTR_T char * +# endif +#endif + +#if !defined (NULL) +# define NULL 0 +#endif + +#if !defined (CPP_STRING) +# if defined (HAVE_STRINGIZE) +# define CPP_STRING(x) #x +# else +# define CPP_STRING(x) "x" +# endif /* !HAVE_STRINGIZE */ +#endif /* !__STRING */ + +#if __GNUC__ > 1 +# define FASTCOPY(s, d, n) __builtin_memcpy (d, s, n) +#else /* !__GNUC__ */ +# if !defined (HAVE_BCOPY) +# if !defined (HAVE_MEMMOVE) +# define FASTCOPY(s, d, n) memcpy (d, s, n) +# else +# define FASTCOPY(s, d, n) memmove (d, s, n) +# endif /* !HAVE_MEMMOVE */ +# else /* HAVE_BCOPY */ +# define FASTCOPY(s, d, n) bcopy (s, d, n) +# endif /* HAVE_BCOPY */ +#endif /* !__GNUC__ */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +/* Use Duff's device for good zeroing/copying performance. DO NOT call the + Duff's device macros with NBYTES == 0. */ + +#define MALLOC_BZERO(charp, nbytes) \ +do { \ + if ((nbytes) <= 32) { \ + size_t * mzp = (size_t *)(charp); \ + unsigned long mctmp = (nbytes)/sizeof(size_t); \ + long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = 0; \ + case 7: *mzp++ = 0; \ + case 6: *mzp++ = 0; \ + case 5: *mzp++ = 0; \ + case 4: *mzp++ = 0; \ + case 3: *mzp++ = 0; \ + case 2: *mzp++ = 0; \ + case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \ + } \ + else \ + memset ((charp), 0, (nbytes)); \ +} while(0) + +#define MALLOC_ZERO(charp, nbytes) \ +do { \ + size_t mzsz = (nbytes); \ + if (mzsz <= 9 * sizeof(mzsz) { \ + size_t *mz = (size_t *)(charp); \ + if(mzsz >= 5*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; \ + if(mzsz >= 7*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; \ + if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; }}} \ + *mz++ = 0; \ + *mz++ = 0; \ + *mz = 0; \ + } else \ + memset ((charp), 0, mzsz); \ +} while (0) + +#define MALLOC_MEMSET(charp, xch, nbytes) \ +do { \ + if ((nbytes) <= 32) { \ + register char * mzp = (charp); \ + unsigned long mctmp = (nbytes); \ + register long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = xch; \ + case 7: *mzp++ = xch; \ + case 6: *mzp++ = xch; \ + case 5: *mzp++ = xch; \ + case 4: *mzp++ = xch; \ + case 3: *mzp++ = xch; \ + case 2: *mzp++ = xch; \ + case 1: *mzp++ = xch; if(mcn <= 0) break; mcn--; } \ + } \ + } else \ + memset ((charp), (xch), (nbytes)); \ +} while(0) + +#define MALLOC_MEMCPY(dest,src,nbytes) \ +do { \ + if ((nbytes) <= 32) { \ + size_t* mcsrc = (size_t*) src; \ + size_t* mcdst = (size_t*) dest; \ + unsigned long mctmp = (nbytes)/sizeof(size_t); \ + long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \ + switch (mctmp) { \ + case 0: for(;;) { *mcdst++ = *mcsrc++; \ + case 7: *mcdst++ = *mcsrc++; \ + case 6: *mcdst++ = *mcsrc++; \ + case 5: *mcdst++ = *mcsrc++; \ + case 4: *mcdst++ = *mcsrc++; \ + case 3: *mcdst++ = *mcsrc++; \ + case 2: *mcdst++ = *mcsrc++; \ + case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \ + } else \ + memcpy ((dest), (src), (nbytes)) \ +} while(0) + +#if defined (SHELL) +# include "bashintl.h" +#else +# define _(x) x +#endif + +#include + +extern void _malloc_block_signals PARAMS((sigset_t *, sigset_t *)); +extern void _malloc_unblock_signals PARAMS((sigset_t *, sigset_t *)); + +#endif /* _IMALLOC_H */ diff --git a/utshell-0.5.0/lib/malloc/malloc.c b/utshell-0.5.0/lib/malloc/malloc.c new file mode 100644 index 00000000..439f8ef1 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/malloc.c @@ -0,0 +1,1481 @@ +/* malloc.c - dynamic memory allocation for bash. */ + +/* Copyright (C) 1985-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* + * @(#)nmalloc.c 1 (Caltech) 2/21/82 + * + * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs + * + * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD. + * + * [VERY] old explanation: + * + * This is a very fast storage allocator. It allocates blocks of a small + * number of different sizes, and keeps free lists of each size. Blocks + * that don't exactly fit are passed up to the next larger size. In this + * implementation, the available sizes are (2^n)-4 (or -16) bytes long. + * This is designed for use in a program that uses vast quantities of + * memory, but bombs when it runs out. To make it a little better, it + * warns the user when he starts to get near the end. + * + * June 84, ACT: modified rcheck code to check the range given to malloc, + * rather than the range determined by the 2-power used. + * + * Jan 85, RMS: calls malloc_warning to issue warning on nearly full. + * No longer Emacs-specific; can serve as all-purpose malloc for GNU. + * You should call malloc_init to reinitialize after loading dumped Emacs. + * Call malloc_stats to get info on memory stats if MALLOC_STATS turned on. + * realloc knows how to return same block given, just changing its size, + * if the power of 2 is correct. + */ + +/* + * nextf[i] is the pointer to the next free block of size 2^(i+3). The + * smallest allocatable block is 8 bytes. The overhead information will + * go in the first int of the block, and the returned pointer will point + * to the second. + */ + +/* Define MEMSCRAMBLE to have free() write 0xcf into memory as it's freed, to + uncover callers that refer to freed memory, and to have malloc() write 0xdf + into memory as it's allocated to avoid referring to previous contents. */ + +/* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE; + handled by configure. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif /* HAVE_CONFIG_H */ + +#if defined (SHELL) +# include "bashtypes.h" +# include "stdc.h" +#else +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +/* Determine which kind of system this is. */ +#include + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif +#include +#include + +#if !defined (botch) +#include +#endif + +#if defined (HAVE_MMAP) +#include +#endif + +/* Define getpagesize () if the system does not. */ +#ifndef HAVE_GETPAGESIZE +# include "getpagesize.h" +#endif + +#include "imalloc.h" +#ifdef MALLOC_STATS +# include "mstats.h" +#endif +#ifdef MALLOC_REGISTER +# include "table.h" +#endif +#ifdef MALLOC_WATCH +# include "watch.h" +#endif + +#ifdef powerof2 +# undef powerof2 +#endif +/* Could also use (((x) & -(x)) == (x)) */ +#define powerof2(x) ((((x) - 1) & (x)) == 0) + +/* System-specific omissions. */ +#ifdef HPUX +# define NO_VALLOC +#endif + +/* SIZEOF_LONG * 4 - 2, usable bins from 1..NBUCKETS-1 */ +#define NBUCKETS 30 + +#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ +#define ISFREE ((char) 0x54) /* magic byte that implies free block */ + /* this is for error checking only */ +#define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by + memalign, with the rest of the word + being the distance to the true + beginning of the block. */ + + +/* We have a flag indicating whether memory is allocated, an index in + nextf[], a size field, and a sentinel value to determine whether or + not a caller wrote before the start of allocated memory; to realloc() + memory we either copy mh_nbytes or just change mh_nbytes if there is + enough room in the block for the new size. Range checking is always + done. */ +union mhead { +#if SIZEOF_CHAR_P == 8 + bits64_t mh_align[2]; /* 16 */ +#else + bits64_t mh_align; /* 8 */ +#endif + struct { + char mi_alloc; /* ISALLOC or ISFREE */ /* 1 */ + char mi_index; /* index in nextf[] */ /* 1 */ + /* Remainder are valid only when block is allocated */ + u_bits16_t mi_magic2; /* should be == MAGIC2 */ /* 2 */ + u_bits32_t mi_nbytes; /* # of bytes allocated */ /* 4 */ +#if SIZEOF_CHAR_P == 8 + char mi_magic8[8]; /* MAGIC1 guard bytes */ /* 8 */ +#endif + } minfo; +}; +#define mh_alloc minfo.mi_alloc +#define mh_index minfo.mi_index +#define mh_nbytes minfo.mi_nbytes +#define mh_magic2 minfo.mi_magic2 +#define mh_magic8 minfo.mi_magic8 + +#define MOVERHEAD sizeof(union mhead) + +#if SIZEOF_CHAR_P == 8 +#define MALIGN_MASK 15 +#else +#define MALIGN_MASK 7 /* one less than desired alignment */ +#endif + +typedef union _malloc_guard { + char s[4]; + u_bits32_t i; +} mguard_t; + +/* Access free-list pointer of a block. + It is stored at block + sizeof (char *). + This is not a field in the minfo structure member of union mhead + because we want sizeof (union mhead) + to describe the overhead for when the block is in use, + and we do not want the free-list pointer to count in that. */ + +/* If SIZEOF_CHAR_P == 8, this goes into the mh_magic8 buffer at the end of + the rest of the struct. This may need adjusting. */ +#define CHAIN(a) \ + (*(union mhead **) (sizeof (char *) + (char *) (a))) + +/* To implement range checking, we write magic values in at the beginning + and end of each allocated block, and make sure they are undisturbed + whenever a free or a realloc occurs. */ + +/* Written in the bytes before the block's real space (-SIZEOF_CHAR_P bytes) */ +#define MAGIC1 0x55 +#define MAGIC2 0x5555 +#define MSLOP 4 /* 4 bytes extra for u_bits32_t size */ + +/* How many bytes are actually allocated for a request of size N -- + rounded up to nearest multiple of 2*SIZEOF_CHAR_P after accounting for + malloc overhead. */ +#define ALLOCATED_BYTES(n) \ + (((n) + MOVERHEAD + MSLOP + MALIGN_MASK) & ~MALIGN_MASK) + +#define ASSERT(p) \ + do \ + { \ + if (!(p)) xbotch((PTR_T)0, ERR_ASSERT_FAILED, CPP_STRING(p), file, line); \ + } \ + while (0) + +/* Minimum and maximum bucket indices for block splitting (and to bound + the search for a block to split). */ +#define SPLIT_MIN 2 /* XXX - was 3 */ +#define SPLIT_MID 11 +#define SPLIT_MAX 14 + +/* Minimum and maximum bucket indices for block coalescing. */ +#define COMBINE_MIN 2 +#define COMBINE_MAX (pagebucket - 1) /* XXX */ + +#define LESSCORE_MIN 10 +#define LESSCORE_FRC 13 + +#define STARTBUCK 1 + +/* Should we use mmap for large allocations? */ +#if defined (HAVE_MMAP) +# if defined (MAP_ANON) && !defined (MAP_ANONYMOUS) +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif + +#if defined (HAVE_MMAP) && defined (MAP_ANONYMOUS) +# define USE_MMAP +#endif + +#if defined (USE_MMAP) +# define MMAP_THRESHOLD 14 /* must be >= SPLIT_MAX, COMBINE_MAX */ +#else +# define MMAP_THRESHOLD (8 * SIZEOF_LONG) +#endif + +/* Flags for the internal functions. */ +#define MALLOC_WRAPPER 0x01 /* wrapper function */ +#define MALLOC_INTERNAL 0x02 /* internal function calling another */ +#define MALLOC_NOTRACE 0x04 /* don't trace this allocation or free */ +#define MALLOC_NOREG 0x08 /* don't register this allocation or free */ + +/* Future use. */ +#define ERR_DUPFREE 0x01 +#define ERR_UNALLOC 0x02 +#define ERR_UNDERFLOW 0x04 +#define ERR_ASSERT_FAILED 0x08 + +/* Evaluates to true if NB is appropriate for bucket NU. NB is adjusted + appropriately by the caller to account for malloc overhead. This only + checks that the recorded size is not too big for the bucket. We + can't check whether or not it's in between NU and NU-1 because we + might have encountered a busy bucket when allocating and moved up to + the next size. */ +#define IN_BUCKET(nb, nu) ((nb) <= binsizes[(nu)]) + +/* Use this when we want to be sure that NB is in bucket NU. */ +#define RIGHT_BUCKET(nb, nu) \ + (((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)])) + +/* nextf[i] is free list of blocks of size 2**(i + 3) */ + +static union mhead *nextf[NBUCKETS]; + +/* busy[i] is nonzero while allocation or free of block size i is in progress. */ + +static char busy[NBUCKETS]; + +static int pagesz; /* system page size. */ +static int pagebucket; /* bucket for requests a page in size */ +static int maxbuck; /* highest bucket receiving allocation request. */ + +static char *memtop; /* top of heap */ + +static const unsigned long binsizes[NBUCKETS] = { + 8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL, + 8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL, + 1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL, + 67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL, + 2147483648UL, 4294967295UL +}; + +/* binsizes[x] == (1 << ((x) + 3)) */ +#define binsize(x) binsizes[(x)] + +#if !defined (errno) +extern int errno; +#endif + +/* Declarations for internal functions */ +static PTR_T internal_malloc PARAMS((size_t, const char *, int, int)); +static PTR_T internal_realloc PARAMS((PTR_T, size_t, const char *, int, int)); +static void internal_free PARAMS((PTR_T, const char *, int, int)); +static PTR_T internal_memalign PARAMS((size_t, size_t, const char *, int, int)); +#ifndef NO_CALLOC +static PTR_T internal_calloc PARAMS((size_t, size_t, const char *, int, int)); +static void internal_cfree PARAMS((PTR_T, const char *, int, int)); +#endif +#ifndef NO_VALLOC +static PTR_T internal_valloc PARAMS((size_t, const char *, int, int)); +#endif + +#if defined (botch) +extern void botch (); +#else +static void botch PARAMS((const char *, const char *, int)); +#endif +static void xbotch PARAMS((PTR_T, int, const char *, const char *, int)); + +#if !HAVE_DECL_SBRK +extern char *sbrk (); +#endif /* !HAVE_DECL_SBRK */ + +#ifdef SHELL +extern int running_trap; +extern int signal_is_trapped PARAMS((int)); +#endif + +#ifdef MALLOC_STATS +struct _malstats _mstats; +#endif /* MALLOC_STATS */ + +/* Debugging variables available to applications. */ +int malloc_flags = 0; /* future use */ +int malloc_trace = 0; /* trace allocations and frees to stderr */ +int malloc_register = 0; /* future use */ + +/* Use a variable in case we want to dynamically adapt it in the future */ +int malloc_mmap_threshold = MMAP_THRESHOLD; + +#ifdef MALLOC_TRACE +char _malloc_trace_buckets[NBUCKETS]; + +/* These should really go into a header file. */ +extern void mtrace_alloc PARAMS((const char *, PTR_T, size_t, const char *, int)); +extern void mtrace_free PARAMS((PTR_T, int, const char *, int)); +#endif + +#if !defined (botch) +static void +botch (s, file, line) + const char *s; + const char *file; + int line; +{ + fprintf (stderr, _("malloc: failed assertion: %s\n"), s); + (void)fflush (stderr); + abort (); +} +#endif + +/* print the file and line number that caused the assertion failure and + call botch() to do whatever the application wants with the information */ +static void +xbotch (mem, e, s, file, line) + PTR_T mem; + int e; + const char *s; + const char *file; + int line; +{ + fprintf (stderr, _("\r\nmalloc: %s:%d: assertion botched\r\n"), + file ? file : _("unknown"), line); +#ifdef MALLOC_REGISTER + if (mem != NULL && malloc_register) + mregister_describe_mem (mem, stderr); +#endif + (void)fflush (stderr); + botch(s, file, line); +} + +/* Coalesce two adjacent free blocks off the free list for size NU - 1, + as long as we can find two adjacent free blocks. nextf[NU -1] is + assumed to not be busy; the caller (morecore()) checks for this. + BUSY[NU] must be set to 1. */ +static void +bcoalesce (nu) + register int nu; +{ + register union mhead *mp, *mp1, *mp2; + register int nbuck; + unsigned long siz; + + nbuck = nu - 1; + if (nextf[nbuck] == 0 || busy[nbuck]) + return; + + busy[nbuck] = 1; + siz = binsize (nbuck); + + mp2 = mp1 = nextf[nbuck]; + mp = CHAIN (mp1); + while (mp && mp != (union mhead *)((char *)mp1 + siz)) + { + mp2 = mp1; + mp1 = mp; + mp = CHAIN (mp); + } + + if (mp == 0) + { + busy[nbuck] = 0; + return; + } + + /* OK, now we have mp1 pointing to the block we want to add to nextf[NU]. + CHAIN(mp2) must equal mp1. Check that mp1 and mp are adjacent. */ + if (mp2 != mp1 && CHAIN(mp2) != mp1) + { + busy[nbuck] = 0; + xbotch ((PTR_T)0, 0, "bcoalesce: CHAIN(mp2) != mp1", (char *)NULL, 0); + } + +#ifdef MALLOC_DEBUG + if (CHAIN (mp1) != (union mhead *)((char *)mp1 + siz)) + { + busy[nbuck] = 0; + return; /* not adjacent */ + } +#endif + + /* Since they are adjacent, remove them from the free list */ + if (mp1 == nextf[nbuck]) + nextf[nbuck] = CHAIN (mp); + else + CHAIN (mp2) = CHAIN (mp); + busy[nbuck] = 0; + +#ifdef MALLOC_STATS + _mstats.tbcoalesce++; + _mstats.ncoalesce[nbuck]++; +#endif + + /* And add the combined two blocks to nextf[NU]. */ + mp1->mh_alloc = ISFREE; + mp1->mh_index = nu; + CHAIN (mp1) = nextf[nu]; + nextf[nu] = mp1; +} + +/* Split a block at index > NU (but less than SPLIT_MAX) into a set of + blocks of the correct size, and attach them to nextf[NU]. nextf[NU] + is assumed to be empty. Must be called with signals blocked (e.g., + by morecore()). BUSY[NU] must be set to 1. */ +static void +bsplit (nu) + register int nu; +{ + register union mhead *mp; + int nbuck, nblks, split_max; + unsigned long siz; + + split_max = (maxbuck > SPLIT_MAX) ? maxbuck : SPLIT_MAX; + + if (nu >= SPLIT_MID) + { + for (nbuck = split_max; nbuck > nu; nbuck--) + { + if (busy[nbuck] || nextf[nbuck] == 0) + continue; + break; + } + } + else + { + for (nbuck = nu + 1; nbuck <= split_max; nbuck++) + { + if (busy[nbuck] || nextf[nbuck] == 0) + continue; + break; + } + } + + if (nbuck > split_max || nbuck <= nu) + return; + + /* XXX might want to split only if nextf[nbuck] has >= 2 blocks free + and nbuck is below some threshold. */ + + /* Remove the block from the chain of larger blocks. */ + busy[nbuck] = 1; + mp = nextf[nbuck]; + nextf[nbuck] = CHAIN (mp); + busy[nbuck] = 0; + +#ifdef MALLOC_STATS + _mstats.tbsplit++; + _mstats.nsplit[nbuck]++; +#endif + + /* Figure out how many blocks we'll get. */ + siz = binsize (nu); + nblks = binsize (nbuck) / siz; + + /* Split the block and put it on the requested chain. */ + nextf[nu] = mp; + while (1) + { + mp->mh_alloc = ISFREE; + mp->mh_index = nu; + if (--nblks <= 0) break; + CHAIN (mp) = (union mhead *)((char *)mp + siz); + mp = (union mhead *)((char *)mp + siz); + } + CHAIN (mp) = 0; +} + +/* Take the memory block MP and add it to a chain < NU. NU is the right bucket, + but is busy. This avoids memory orphaning. */ +static void +xsplit (mp, nu) + union mhead *mp; + int nu; +{ + union mhead *nh; + int nbuck, nblks, split_max; + unsigned long siz; + + nbuck = nu - 1; + while (nbuck >= SPLIT_MIN && busy[nbuck]) + nbuck--; + if (nbuck < SPLIT_MIN) + return; + +#ifdef MALLOC_STATS + _mstats.tbsplit++; + _mstats.nsplit[nu]++; +#endif + + /* Figure out how many blocks we'll get. */ + siz = binsize (nu); /* original block size */ + nblks = siz / binsize (nbuck); /* should be 2 most of the time */ + + /* And add it to nextf[nbuck] */ + siz = binsize (nbuck); /* XXX - resetting here */ + nh = mp; + while (1) + { + mp->mh_alloc = ISFREE; + mp->mh_index = nbuck; + if (--nblks <= 0) break; + CHAIN (mp) = (union mhead *)((char *)mp + siz); + mp = (union mhead *)((char *)mp + siz); + } + busy[nbuck] = 1; + CHAIN (mp) = nextf[nbuck]; + nextf[nbuck] = nh; + busy[nbuck] = 0; +} + +void +_malloc_block_signals (setp, osetp) + sigset_t *setp, *osetp; +{ +#ifdef HAVE_POSIX_SIGNALS + sigfillset (setp); + sigemptyset (osetp); + sigprocmask (SIG_BLOCK, setp, osetp); +#else +# if defined (HAVE_BSD_SIGNALS) + *osetp = sigsetmask (-1); +# endif +#endif +} + +void +_malloc_unblock_signals (setp, osetp) + sigset_t *setp, *osetp; +{ +#ifdef HAVE_POSIX_SIGNALS + sigprocmask (SIG_SETMASK, osetp, (sigset_t *)NULL); +#else +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (*osetp); +# endif +#endif +} + +/* Return some memory to the system by reducing the break. This is only + called with NU > pagebucket, so we're always assured of giving back + more than one page of memory. */ +static void +lesscore (nu) /* give system back some memory */ + register int nu; /* size index we're discarding */ +{ + long siz; + + siz = binsize (nu); + /* Should check for errors here, I guess. */ + sbrk (-siz); + memtop -= siz; + +#ifdef MALLOC_STATS + _mstats.nsbrk++; + _mstats.tsbrk -= siz; + _mstats.nlesscore[nu]++; +#endif +} + +/* Ask system for more memory; add to NEXTF[NU]. BUSY[NU] must be set to 1. */ +static void +morecore (nu) + register int nu; /* size index to get more of */ +{ + register union mhead *mp; + register int nblks; + register long siz; + long sbrk_amt; /* amount to get via sbrk() */ + sigset_t set, oset; + int blocked_sigs; + + /* Block all signals in case we are executed from a signal handler. */ + blocked_sigs = 0; +#ifdef SHELL +# if defined (SIGCHLD) + if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) +# else + if (running_trap || signal_is_trapped (SIGINT)) +# endif +#endif + { + _malloc_block_signals (&set, &oset); + blocked_sigs = 1; + } + + siz = binsize (nu); /* size of desired block for nextf[nu] */ + + if (siz < 0) + goto morecore_done; /* oops */ + +#ifdef MALLOC_STATS + _mstats.nmorecore[nu]++; +#endif + + /* Try to split a larger block here, if we're within the range of sizes + to split. */ + if (nu >= SPLIT_MIN && nu <= malloc_mmap_threshold) + { + bsplit (nu); + if (nextf[nu] != 0) + goto morecore_done; + } + + /* Try to coalesce two adjacent blocks from the free list on nextf[nu - 1], + if we can, and we're within the range of the block coalescing limits. */ + if (nu >= COMBINE_MIN && nu < COMBINE_MAX && nu <= malloc_mmap_threshold && busy[nu - 1] == 0 && nextf[nu - 1]) + { + bcoalesce (nu); + if (nextf[nu] != 0) + goto morecore_done; + } + + /* Take at least a page, and figure out how many blocks of the requested + size we're getting. */ + if (siz <= pagesz) + { + sbrk_amt = pagesz; + nblks = sbrk_amt / siz; + } + else + { + /* We always want to request an integral multiple of the page size + from the kernel, so let's compute whether or not `siz' is such + an amount. If it is, we can just request it. If not, we want + the smallest integral multiple of pagesize that is larger than + `siz' and will satisfy the request. */ + sbrk_amt = siz & (pagesz - 1); + if (sbrk_amt == 0) + sbrk_amt = siz; + else + sbrk_amt = siz + pagesz - sbrk_amt; + nblks = 1; + } + +#if defined (USE_MMAP) + if (nu > malloc_mmap_threshold) + { + mp = (union mhead *)mmap (0, sbrk_amt, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if ((void *)mp == MAP_FAILED) + goto morecore_done; + nextf[nu] = mp; + mp->mh_alloc = ISFREE; + mp->mh_index = nu; + CHAIN (mp) = 0; +#ifdef MALLOC_STATS + _mstats.nmmap++; + _mstats.tmmap += sbrk_amt; +#endif + goto morecore_done; + } +#endif + + +#ifdef MALLOC_STATS + _mstats.nsbrk++; + _mstats.tsbrk += sbrk_amt; +#endif + + mp = (union mhead *) sbrk (sbrk_amt); + + /* Totally out of memory. */ + if ((long)mp == -1) + goto morecore_done; + + memtop += sbrk_amt; + + /* shouldn't happen, but just in case -- require 8- or 16-byte alignment */ + if ((long)mp & MALIGN_MASK) + { + mp = (union mhead *) (((long)mp + MALIGN_MASK) & ~MALIGN_MASK); + nblks--; + } + + /* save new header and link the nblks blocks together */ + nextf[nu] = mp; + while (1) + { + mp->mh_alloc = ISFREE; + mp->mh_index = nu; + if (--nblks <= 0) break; + CHAIN (mp) = (union mhead *)((char *)mp + siz); + mp = (union mhead *)((char *)mp + siz); + } + CHAIN (mp) = 0; + +morecore_done: + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); +} + +static void +malloc_debug_dummy () +{ + write (1, "malloc_debug_dummy\n", 19); +} + +#if SIZEOF_CHAR_P == 8 +#define PREPOP_BIN 3 +#define PREPOP_SIZE 64 +#else +#define PREPOP_BIN 2 +#define PREPOP_SIZE 32 +#endif + +static int +pagealign () +{ + register int nunits; + register union mhead *mp; + long sbrk_needed; + char *curbrk; + + pagesz = getpagesize (); + if (pagesz < 1024) + pagesz = 1024; + + /* OK, how much do we need to allocate to make things page-aligned? + Some of this partial page will be wasted space, but we'll use as + much as we can. Once we figure out how much to advance the break + pointer, go ahead and do it. */ + memtop = curbrk = sbrk (0); + sbrk_needed = pagesz - ((long)curbrk & (pagesz - 1)); /* sbrk(0) % pagesz */ + if (sbrk_needed < 0) + sbrk_needed += pagesz; + + /* Now allocate the wasted space. */ + if (sbrk_needed) + { +#ifdef MALLOC_STATS + _mstats.nsbrk++; + _mstats.tsbrk += sbrk_needed; +#endif + curbrk = sbrk (sbrk_needed); + if ((long)curbrk == -1) + return -1; + memtop += sbrk_needed; + + /* Take the memory which would otherwise be wasted and populate the most + popular bin (3 == 64 bytes) with it. Add whatever we need to curbrk + to make things 64-byte aligned, compute how many 64-byte chunks we're + going to get, and set up the bin. */ + curbrk += sbrk_needed & (PREPOP_SIZE - 1); + sbrk_needed -= sbrk_needed & (PREPOP_SIZE - 1); + nunits = sbrk_needed / PREPOP_SIZE; + + if (nunits > 0) + { + mp = (union mhead *)curbrk; + + nextf[PREPOP_BIN] = mp; + while (1) + { + mp->mh_alloc = ISFREE; + mp->mh_index = PREPOP_BIN; + if (--nunits <= 0) break; + CHAIN(mp) = (union mhead *)((char *)mp + PREPOP_SIZE); + mp = (union mhead *)((char *)mp + PREPOP_SIZE); + } + CHAIN(mp) = 0; + } + } + + /* compute which bin corresponds to the page size. */ + for (nunits = 7; nunits < NBUCKETS; nunits++) + if (pagesz <= binsize(nunits)) + break; + pagebucket = nunits; + + return 0; +} + +static PTR_T +internal_malloc (n, file, line, flags) /* get a block */ + size_t n; + const char *file; + int line, flags; +{ + register union mhead *p; + register int nunits; + register char *m, *z; + long nbytes; + mguard_t mg; + + /* Get the system page size and align break pointer so future sbrks will + be page-aligned. The page size must be at least 1K -- anything + smaller is increased. */ + if (pagesz == 0) + if (pagealign () < 0) + return ((PTR_T)NULL); + + /* Figure out how many bytes are required, rounding up to the nearest + multiple of 8, then figure out which nextf[] area to use. Try to + be smart about where to start searching -- if the number of bytes + needed is greater than the page size, we can start at pagebucket. */ + nbytes = ALLOCATED_BYTES(n); + nunits = (nbytes <= (pagesz >> 1)) ? STARTBUCK : pagebucket; + for ( ; nunits < NBUCKETS; nunits++) + if (nbytes <= binsize(nunits)) + break; + + /* Silently reject too-large requests. XXX - can increase this if HAVE_MMAP */ + if (nunits >= NBUCKETS) + return ((PTR_T) NULL); + + /* In case this is reentrant use of malloc from signal handler, + pick a block size that no other malloc level is currently + trying to allocate. That's the easiest harmless way not to + interfere with the other level of execution. */ +#ifdef MALLOC_STATS + if (busy[nunits]) _mstats.nrecurse++; +#endif + while (busy[nunits]) nunits++; + busy[nunits] = 1; + + if (nunits > maxbuck) + maxbuck = nunits; + + /* If there are no blocks of the appropriate size, go get some */ + if (nextf[nunits] == 0) + morecore (nunits); + + /* Get one block off the list, and set the new list head */ + if ((p = nextf[nunits]) == NULL) + { + busy[nunits] = 0; + return NULL; + } + nextf[nunits] = CHAIN (p); + busy[nunits] = 0; + + /* Check for free block clobbered */ + /* If not for this check, we would gobble a clobbered free chain ptr + and bomb out on the NEXT allocate of this size block */ + if (p->mh_alloc != ISFREE || p->mh_index != nunits) + xbotch ((PTR_T)(p+1), 0, _("malloc: block on free list clobbered"), file, line); + + /* Fill in the info, and set up the magic numbers for range checking. */ + p->mh_alloc = ISALLOC; + p->mh_magic2 = MAGIC2; + p->mh_nbytes = n; + +#if SIZEOF_CHAR_P == 8 + /* Begin guard */ + MALLOC_MEMSET ((char *)p->mh_magic8, MAGIC1, 8); +#endif + + /* End guard */ + mg.i = n; + z = mg.s; + m = (char *) (p + 1) + n; + *m++ = *z++, *m++ = *z++, *m++ = *z++, *m++ = *z++; + +#ifdef MEMSCRAMBLE + if (n) + MALLOC_MEMSET ((char *)(p + 1), 0xdf, n); /* scramble previous contents */ +#endif +#ifdef MALLOC_STATS + _mstats.nmalloc[nunits]++; + _mstats.tmalloc[nunits]++; + _mstats.nmal++; + _mstats.bytesreq += n; +#endif /* MALLOC_STATS */ + +#ifdef MALLOC_TRACE + if (malloc_trace && (flags & MALLOC_NOTRACE) == 0) + mtrace_alloc ("malloc", p + 1, n, file, line); + else if (_malloc_trace_buckets[nunits]) + mtrace_alloc ("malloc", p + 1, n, file, line); +#endif + +#ifdef MALLOC_REGISTER + if (malloc_register && (flags & MALLOC_NOREG) == 0) + mregister_alloc ("malloc", p + 1, n, file, line); +#endif + +#ifdef MALLOC_WATCH + if (_malloc_nwatch > 0) + _malloc_ckwatch (p + 1, file, line, W_ALLOC, n); +#endif + +#if defined (MALLOC_DEBUG) + z = (char *) (p + 1); + /* Check alignment of returned pointer */ + if ((unsigned long)z & MALIGN_MASK) + fprintf (stderr, "malloc: %s:%d: warning: request for %d bytes not aligned on %d byte boundary\r\n", + file ? file : _("unknown"), line, p->mh_nbytes, MALIGN_MASK+1); +#endif + + return (PTR_T) (p + 1); +} + +static void +internal_free (mem, file, line, flags) + PTR_T mem; + const char *file; + int line, flags; +{ + register union mhead *p; + register char *ap, *z; + register int nunits; + register unsigned int nbytes; + int ubytes; /* caller-requested size */ + mguard_t mg; + + if ((ap = (char *)mem) == 0) + return; + + p = (union mhead *) ap - 1; + + if (p->mh_alloc == ISMEMALIGN) + { + ap -= p->mh_nbytes; + p = (union mhead *) ap - 1; + } + +#if defined (MALLOC_TRACE) || defined (MALLOC_REGISTER) || defined (MALLOC_WATCH) + if (malloc_trace || malloc_register || _malloc_nwatch > 0) + ubytes = p->mh_nbytes; +#endif + + if (p->mh_alloc != ISALLOC) + { + if (p->mh_alloc == ISFREE) + xbotch (mem, ERR_DUPFREE, + _("free: called with already freed block argument"), file, line); + else + xbotch (mem, ERR_UNALLOC, + _("free: called with unallocated block argument"), file, line); + } + + ASSERT (p->mh_magic2 == MAGIC2); + + nunits = p->mh_index; + nbytes = ALLOCATED_BYTES(p->mh_nbytes); + /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user + are now used for the number of bytes allocated, a simple check of + mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'. + We sanity-check the value of mh_nbytes against the size of the blocks + in the appropriate bucket before we use it. This can still cause problems + and obscure errors if mh_nbytes is wrong but still within range; the + checks against the size recorded at the end of the chunk will probably + fail then. Using MALLOC_REGISTER will help here, since it saves the + original number of bytes requested. */ + + if (IN_BUCKET(nbytes, nunits) == 0) + xbotch (mem, ERR_UNDERFLOW, + _("free: underflow detected; mh_nbytes out of range"), file, line); +#if SIZEOF_CHAR_P == 8 + { + int i; + for (i = 0, z = p->mh_magic8; i < 8; i++) + if (*z++ != MAGIC1) + xbotch (mem, ERR_UNDERFLOW, + _("free: underflow detected; magic8 corrupted"), file, line); + } +#endif + + ap += p->mh_nbytes; + z = mg.s; + *z++ = *ap++, *z++ = *ap++, *z++ = *ap++, *z++ = *ap++; + if (mg.i != p->mh_nbytes) + xbotch (mem, ERR_ASSERT_FAILED, _("free: start and end chunk sizes differ"), file, line); + +#if defined (USE_MMAP) + if (nunits > malloc_mmap_threshold) + { + munmap (p, binsize (nunits)); +#if defined (MALLOC_STATS) + _mstats.nlesscore[nunits]++; +#endif + goto free_return; + } +#endif + +#if GLIBC21 + if (nunits >= LESSCORE_MIN && ((char *)p + binsize(nunits) == sbrk (0))) +#else + if (nunits >= LESSCORE_MIN && ((char *)p + binsize(nunits) == memtop)) +#endif + { + /* If above LESSCORE_FRC, give back unconditionally. This should be set + high enough to be infrequently encountered. If between LESSCORE_MIN + and LESSCORE_FRC, call lesscore if the bucket is marked as busy or if + there's already a block on the free list. */ + if ((nunits >= LESSCORE_FRC) || busy[nunits] || nextf[nunits] != 0) + { + lesscore (nunits); + /* keeps the tracing and registering code in one place */ + goto free_return; + } + } + +#ifdef MEMSCRAMBLE + if (p->mh_nbytes) + MALLOC_MEMSET (mem, 0xcf, p->mh_nbytes); +#endif + + ASSERT (nunits < NBUCKETS); + + if (busy[nunits] == 1) + { + xsplit (p, nunits); /* split block and add to different chain */ + goto free_return; + } + + p->mh_alloc = ISFREE; + /* Protect against signal handlers calling malloc. */ + busy[nunits] = 1; + /* Put this block on the free list. */ + CHAIN (p) = nextf[nunits]; + nextf[nunits] = p; + busy[nunits] = 0; + +free_return: + ; /* Empty statement in case this is the end of the function */ + +#ifdef MALLOC_STATS + _mstats.nmalloc[nunits]--; + _mstats.nfre++; +#endif /* MALLOC_STATS */ + +#ifdef MALLOC_TRACE + if (malloc_trace && (flags & MALLOC_NOTRACE) == 0) + mtrace_free (mem, ubytes, file, line); + else if (_malloc_trace_buckets[nunits]) + mtrace_free (mem, ubytes, file, line); +#endif + +#ifdef MALLOC_REGISTER + if (malloc_register && (flags & MALLOC_NOREG) == 0) + mregister_free (mem, ubytes, file, line); +#endif + +#ifdef MALLOC_WATCH + if (_malloc_nwatch > 0) + _malloc_ckwatch (mem, file, line, W_FREE, ubytes); +#endif +} + +static PTR_T +internal_realloc (mem, n, file, line, flags) + PTR_T mem; + register size_t n; + const char *file; + int line, flags; +{ + register union mhead *p; + register u_bits32_t tocopy; + register unsigned int nbytes; + register int nunits; + register char *m, *z; + mguard_t mg; + +#ifdef MALLOC_STATS + _mstats.nrealloc++; +#endif + + if (n == 0) + { + internal_free (mem, file, line, MALLOC_INTERNAL); + return (NULL); + } + if ((p = (union mhead *) mem) == 0) + return internal_malloc (n, file, line, MALLOC_INTERNAL); + + p--; + nunits = p->mh_index; + ASSERT (nunits < NBUCKETS); + + if (p->mh_alloc != ISALLOC) + xbotch (mem, ERR_UNALLOC, + _("realloc: called with unallocated block argument"), file, line); + + ASSERT (p->mh_magic2 == MAGIC2); + nbytes = ALLOCATED_BYTES(p->mh_nbytes); + /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user + are now used for the number of bytes allocated, a simple check of + mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'. + We sanity-check the value of mh_nbytes against the size of the blocks + in the appropriate bucket before we use it. This can still cause problems + and obscure errors if mh_nbytes is wrong but still within range; the + checks against the size recorded at the end of the chunk will probably + fail then. Using MALLOC_REGISTER will help here, since it saves the + original number of bytes requested. */ + if (IN_BUCKET(nbytes, nunits) == 0) + xbotch (mem, ERR_UNDERFLOW, + _("realloc: underflow detected; mh_nbytes out of range"), file, line); +#if SIZEOF_CHAR_P == 8 + { + int i; + for (i = 0, z = p->mh_magic8; i < 8; i++) + if (*z++ != MAGIC1) + xbotch (mem, ERR_UNDERFLOW, + _("realloc: underflow detected; magic8 corrupted"), file, line); + + } +#endif + + m = (char *)mem + (tocopy = p->mh_nbytes); + z = mg.s; + *z++ = *m++, *z++ = *m++, *z++ = *m++, *z++ = *m++; + if (mg.i != p->mh_nbytes) + xbotch (mem, ERR_ASSERT_FAILED, _("realloc: start and end chunk sizes differ"), file, line); + +#ifdef MALLOC_WATCH + if (_malloc_nwatch > 0) + _malloc_ckwatch (p + 1, file, line, W_REALLOC, n); +#endif +#ifdef MALLOC_STATS + _mstats.bytesreq += (n < tocopy) ? 0 : n - tocopy; +#endif + + /* If we're reallocating to the same size as previously, return now */ + if (n == p->mh_nbytes) + return mem; + + /* See if desired size rounds to same power of 2 as actual size. */ + nbytes = ALLOCATED_BYTES(n); + + /* If ok, use the same block, just marking its size as changed. */ + if (RIGHT_BUCKET(nbytes, nunits) || RIGHT_BUCKET(nbytes, nunits-1)) + { + /* Compensate for increment above. */ + m -= 4; + + *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0; + m = (char *)mem + (p->mh_nbytes = n); + + mg.i = n; + z = mg.s; + *m++ = *z++, *m++ = *z++, *m++ = *z++, *m++ = *z++; + + return mem; + } + + if (n < tocopy) + tocopy = n; + +#ifdef MALLOC_STATS + _mstats.nrcopy++; +#endif + + /* If we are using mmap and have mremap, we could use it here. */ + + if ((m = internal_malloc (n, file, line, MALLOC_INTERNAL|MALLOC_NOTRACE|MALLOC_NOREG)) == 0) + return 0; + FASTCOPY (mem, m, tocopy); + internal_free (mem, file, line, MALLOC_INTERNAL); + +#ifdef MALLOC_TRACE + if (malloc_trace && (flags & MALLOC_NOTRACE) == 0) + mtrace_alloc ("realloc", m, n, file, line); + else if (_malloc_trace_buckets[nunits]) + mtrace_alloc ("realloc", m, n, file, line); +#endif + +#ifdef MALLOC_REGISTER + if (malloc_register && (flags & MALLOC_NOREG) == 0) + mregister_alloc ("realloc", m, n, file, line); +#endif + +#ifdef MALLOC_WATCH + if (_malloc_nwatch > 0) + _malloc_ckwatch (m, file, line, W_RESIZED, n); +#endif + + return m; +} + +static PTR_T +internal_memalign (alignment, size, file, line, flags) + size_t alignment; + size_t size; + const char *file; + int line, flags; +{ + register char *ptr; + register char *aligned; + register union mhead *p; + + ptr = internal_malloc (size + alignment, file, line, MALLOC_INTERNAL); + + if (ptr == 0) + return 0; + /* If entire block has the desired alignment, just accept it. */ + if (((long) ptr & (alignment - 1)) == 0) + return ptr; + /* Otherwise, get address of byte in the block that has that alignment. */ + aligned = (char *) (((long) ptr + alignment - 1) & (~alignment + 1)); + + /* Store a suitable indication of how to free the block, + so that free can find the true beginning of it. */ + p = (union mhead *) aligned - 1; + p->mh_nbytes = aligned - ptr; + p->mh_alloc = ISMEMALIGN; + + return aligned; +} + +int +posix_memalign (memptr, alignment, size) + void **memptr; + size_t alignment, size; +{ + void *mem; + + /* Perform posix-mandated error checking here */ + if ((alignment % sizeof (void *) != 0) || alignment == 0) + return EINVAL; + else if (powerof2 (alignment) == 0) + return EINVAL; + + mem = internal_memalign (alignment, size, (char *)0, 0, 0); + if (mem != 0) + { + *memptr = mem; + return 0; + } + return ENOMEM; +} + +size_t +malloc_usable_size (mem) + void *mem; +{ + register union mhead *p; + register char *ap; + register int maxbytes; + + + if ((ap = (char *)mem) == 0) + return 0; + + /* Find the true start of the memory block to discover which bin */ + p = (union mhead *) ap - 1; + if (p->mh_alloc == ISMEMALIGN) + { + ap -= p->mh_nbytes; + p = (union mhead *) ap - 1; + } + + /* XXX - should we return 0 if ISFREE? */ + maxbytes = binsize(p->mh_index); + + /* So the usable size is the maximum number of bytes in the bin less the + malloc overhead */ + maxbytes -= MOVERHEAD + MSLOP; + return (maxbytes); +} + +#if !defined (NO_VALLOC) +/* This runs into trouble with getpagesize on HPUX, and Multimax machines. + Patching out seems cleaner than the ugly fix needed. */ +static PTR_T +internal_valloc (size, file, line, flags) + size_t size; + const char *file; + int line, flags; +{ + return internal_memalign (getpagesize (), size, file, line, flags|MALLOC_INTERNAL); +} +#endif /* !NO_VALLOC */ + +#ifndef NO_CALLOC +static PTR_T +internal_calloc (n, s, file, line, flags) + size_t n, s; + const char *file; + int line, flags; +{ + size_t total; + PTR_T result; + + total = n * s; + result = internal_malloc (total, file, line, flags|MALLOC_INTERNAL); + if (result) + memset (result, 0, total); + return result; +} + +static void +internal_cfree (p, file, line, flags) + PTR_T p; + const char *file; + int line, flags; +{ + internal_free (p, file, line, flags|MALLOC_INTERNAL); +} +#endif /* !NO_CALLOC */ + +#ifdef MALLOC_STATS +int +malloc_free_blocks (size) + int size; +{ + int nfree; + register union mhead *p; + + nfree = 0; + for (p = nextf[size]; p; p = CHAIN (p)) + nfree++; + + return nfree; +} +#endif + +#if defined (MALLOC_WRAPFUNCS) +PTR_T +sh_malloc (bytes, file, line) + size_t bytes; + const char *file; + int line; +{ + return internal_malloc (bytes, file, line, MALLOC_WRAPPER); +} + +PTR_T +sh_realloc (ptr, size, file, line) + PTR_T ptr; + size_t size; + const char *file; + int line; +{ + return internal_realloc (ptr, size, file, line, MALLOC_WRAPPER); +} + +void +sh_free (mem, file, line) + PTR_T mem; + const char *file; + int line; +{ + internal_free (mem, file, line, MALLOC_WRAPPER); +} + +PTR_T +sh_memalign (alignment, size, file, line) + size_t alignment; + size_t size; + const char *file; + int line; +{ + return internal_memalign (alignment, size, file, line, MALLOC_WRAPPER); +} + +#ifndef NO_CALLOC +PTR_T +sh_calloc (n, s, file, line) + size_t n, s; + const char *file; + int line; +{ + return internal_calloc (n, s, file, line, MALLOC_WRAPPER); +} + +void +sh_cfree (mem, file, line) + PTR_T mem; + const char *file; + int line; +{ + internal_cfree (mem, file, line, MALLOC_WRAPPER); +} +#endif + +#ifndef NO_VALLOC +PTR_T +sh_valloc (size, file, line) + size_t size; + const char *file; + int line; +{ + return internal_valloc (size, file, line, MALLOC_WRAPPER); +} +#endif /* !NO_VALLOC */ + +#endif /* MALLOC_WRAPFUNCS */ + +/* Externally-available functions that call their internal counterparts. */ + +PTR_T +malloc (size) + size_t size; +{ + return internal_malloc (size, (char *)NULL, 0, 0); +} + +PTR_T +realloc (mem, nbytes) + PTR_T mem; + size_t nbytes; +{ + return internal_realloc (mem, nbytes, (char *)NULL, 0, 0); +} + +void +free (mem) + PTR_T mem; +{ + internal_free (mem, (char *)NULL, 0, 0); +} + +PTR_T +memalign (alignment, size) + size_t alignment; + size_t size; +{ + return internal_memalign (alignment, size, (char *)NULL, 0, 0); +} + +#ifndef NO_VALLOC +PTR_T +valloc (size) + size_t size; +{ + return internal_valloc (size, (char *)NULL, 0, 0); +} +#endif + +#ifndef NO_CALLOC +PTR_T +calloc (n, s) + size_t n, s; +{ + return internal_calloc (n, s, (char *)NULL, 0, 0); +} + +void +cfree (mem) + PTR_T mem; +{ + internal_cfree (mem, (char *)NULL, 0, 0); +} +#endif diff --git a/utshell-0.5.0/lib/malloc/mstats.h b/utshell-0.5.0/lib/malloc/mstats.h new file mode 100644 index 00000000..ce8aaeca --- /dev/null +++ b/utshell-0.5.0/lib/malloc/mstats.h @@ -0,0 +1,114 @@ +/* mstats.h - definitions for malloc statistics */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _MSTATS_H +#define _MSTATS_H + +#include "imalloc.h" + +#ifdef MALLOC_STATS + +/* This needs to change if the definition in malloc.c changes */ +#ifndef NBUCKETS +# define NBUCKETS 30 +#endif + +/* + * NMALLOC[i] is the difference between the number of mallocs and frees + * for a given block size. TMALLOC[i] is the total number of mallocs for + * a given block size. NMORECORE[i] is the total number of calls to + * morecore(i). NLESSCORE[i] is the total number of calls to lesscore(i). + * + * NMAL and NFRE are counts of the number of calls to malloc() and free(), + * respectively. NREALLOC is the total number of calls to realloc(); + * NRCOPY is the number of times realloc() had to allocate new memory and + * copy to it. NRECURSE is a count of the number of recursive calls to + * malloc() for the same bucket size, which can be caused by calls to + * malloc() from a signal handler. + * + * NSBRK is the number of calls to sbrk() (whether by morecore() or for + * alignment); TSBRK is the total number of bytes requested from the kernel + * with sbrk(). + * + * BYTESUSED is the total number of bytes consumed by blocks currently in + * use; BYTESFREE is the total number of bytes currently on all of the free + * lists. BYTESREQ is the total number of bytes requested by the caller + * via calls to malloc() and realloc(). + * + * TBSPLIT is the number of times a larger block was split to satisfy a + * smaller request. NSPLIT[i] is the number of times a block of size I was + * split. + * + * TBCOALESCE is the number of times two adjacent smaller blocks off the free + * list were combined to satisfy a larger request. + */ +struct _malstats { + int nmalloc[NBUCKETS]; + int tmalloc[NBUCKETS]; + int nmorecore[NBUCKETS]; + int nlesscore[NBUCKETS]; + int nmal; + int nfre; + int nrealloc; + int nrcopy; + int nrecurse; + int nsbrk; + bits32_t tsbrk; + bits32_t bytesused; + bits32_t bytesfree; + u_bits32_t bytesreq; + int tbsplit; + int nsplit[NBUCKETS]; + int tbcoalesce; + int ncoalesce[NBUCKETS]; + int nmmap; + bits32_t tmmap; +}; + +/* Return statistics describing allocation of blocks of size BLOCKSIZE. + NFREE is the number of free blocks for this allocation size. NUSED + is the number of blocks in use. NMAL is the number of requests for + blocks of size BLOCKSIZE. NMORECORE is the number of times we had + to call MORECORE to repopulate the free list for this bucket. + NLESSCORE is the number of times we gave memory back to the system + from this bucket. NSPLIT is the number of times a block of this size + was split to satisfy a smaller request. NCOALESCE is the number of + times two blocks of this size were combined to satisfy a larger + request. */ +struct bucket_stats { + u_bits32_t blocksize; + int nfree; + int nused; + int nmal; + int nmorecore; + int nlesscore; + int nsplit; + int ncoalesce; + int nmmap; /* currently unused */ +}; + +extern struct bucket_stats malloc_bucket_stats PARAMS((int)); +extern struct _malstats malloc_stats PARAMS((void)); +extern void print_malloc_stats PARAMS((char *)); +extern void trace_malloc_stats PARAMS((char *, char *)); + +#endif /* MALLOC_STATS */ + +#endif /* _MSTATS_H */ diff --git a/utshell-0.5.0/lib/malloc/shmalloc.h b/utshell-0.5.0/lib/malloc/shmalloc.h new file mode 100644 index 00000000..d51193eb --- /dev/null +++ b/utshell-0.5.0/lib/malloc/shmalloc.h @@ -0,0 +1,70 @@ +/* Functions (currently) for use by the shell to do malloc debugging and + tracking. */ +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _SH_MALLOC_H +#define _SH_MALLOC_H + +#ifndef PARAMS +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + + +extern PTR_T sh_malloc PARAMS((size_t, const char *, int)); +extern PTR_T sh_realloc PARAMS((PTR_T, size_t, const char *, int)); +extern void sh_free PARAMS((PTR_T, const char *, int)); + +extern PTR_T sh_memalign PARAMS((size_t, size_t, const char *, int)); + +extern PTR_T sh_calloc PARAMS((size_t, size_t, const char *, int)); +extern void sh_cfree PARAMS((PTR_T, const char *, int)); + +extern PTR_T sh_valloc PARAMS((size_t, const char *, int)); + +/* trace.c */ +extern int malloc_set_trace PARAMS((int)); +extern void malloc_set_tracefp (); /* full prototype requires stdio.h */ +extern void malloc_set_tracefn PARAMS((char *, char *)); + +/* table.c */ +extern void mregister_dump_table PARAMS((void)); +extern void mregister_table_init PARAMS((void)); +extern int malloc_set_register PARAMS((int)); + +/* stats.c */ +extern void print_malloc_stats PARAMS((char *)); +extern void fprint_malloc_stats (); /* full prototype requires stdio.h */ +extern void trace_malloc_stats PARAMS((char *, char *)); + +#endif diff --git a/utshell-0.5.0/lib/malloc/stats.c b/utshell-0.5.0/lib/malloc/stats.c new file mode 100644 index 00000000..b38df9f4 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/stats.c @@ -0,0 +1,213 @@ +/* stats.c - malloc statistics */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "imalloc.h" + +#ifdef MALLOC_STATS + +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include + +#include "mstats.h" + +extern int malloc_free_blocks PARAMS((int)); + +extern int malloc_mmap_threshold; + +extern struct _malstats _mstats; + +extern FILE *_imalloc_fopen PARAMS((char *, char *, char *, char *, size_t)); + +struct bucket_stats +malloc_bucket_stats (size) + int size; +{ + struct bucket_stats v; + + v.nfree = 0; + + if (size < 0 || size >= NBUCKETS) + { + v.blocksize = 0; + v.nused = v.nmal = v.nmorecore = v.nlesscore = v.nsplit = 0; + return v; + } + + v.blocksize = 1 << (size + 3); + v.nused = _mstats.nmalloc[size]; + v.nmal = _mstats.tmalloc[size]; + v.nmorecore = _mstats.nmorecore[size]; + v.nlesscore = _mstats.nlesscore[size]; + v.nsplit = _mstats.nsplit[size]; + v.ncoalesce = _mstats.ncoalesce[size]; + + v.nfree = malloc_free_blocks (size); /* call back to malloc.c */ + + return v; +} + +/* Return a copy of _MSTATS, with two additional fields filled in: + BYTESFREE is the total number of bytes on free lists. BYTESUSED + is the total number of bytes in use. These two fields are fairly + expensive to compute, so we do it only when asked to. */ +struct _malstats +malloc_stats () +{ + struct _malstats result; + struct bucket_stats v; + register int i; + + result = _mstats; + result.bytesused = result.bytesfree = 0; + for (i = 0; i < NBUCKETS; i++) + { + v = malloc_bucket_stats (i); + result.bytesfree += v.nfree * v.blocksize; + result.bytesused += v.nused * v.blocksize; + } + return (result); +} + +static void +_print_malloc_stats (s, fp) + char *s; + FILE *fp; +{ + register int i; + unsigned long totused, totfree; + struct bucket_stats v; + + fprintf (fp, "Memory allocation statistics: %s\n size\tfree\tin use\ttotal\tmorecore lesscore split\tcoalesce\n", s ? s : ""); + for (i = totused = totfree = 0; i < NBUCKETS; i++) + { + v = malloc_bucket_stats (i); + /* Show where the mmap threshold is; sizes greater than this use mmap to + allocate and munmap to free (munmap shows up as lesscore). */ + if (i == malloc_mmap_threshold+1) + fprintf (fp, "--------\n"); + if (v.nmal > 0) + fprintf (fp, "%8lu\t%4d\t%6d\t%5d%8d\t%8d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce); + totfree += v.nfree * v.blocksize; + totused += v.nused * v.blocksize; + } + fprintf (fp, "\nTotal bytes in use: %lu, total bytes free: %lu\n", + totused, totfree); + fprintf (fp, "\nTotal bytes requested by application: %lu\n", (unsigned long)_mstats.bytesreq); + fprintf (fp, "Total mallocs: %d, total frees: %d, total reallocs: %d (%d copies)\n", + _mstats.nmal, _mstats.nfre, _mstats.nrealloc, _mstats.nrcopy); + fprintf (fp, "Total sbrks: %d, total bytes via sbrk: %d\n", + _mstats.nsbrk, _mstats.tsbrk); + fprintf (fp, "Total mmaps: %d, total bytes via mmap: %d\n", + _mstats.nmmap, _mstats.tmmap); + fprintf (fp, "Total blocks split: %d, total block coalesces: %d\n", + _mstats.tbsplit, _mstats.tbcoalesce); +} + +void +print_malloc_stats (s) + char *s; +{ + _print_malloc_stats (s, stderr); +} + +void +fprint_malloc_stats (s, fp) + char *s; + FILE *fp; +{ + _print_malloc_stats (s, fp); +} + +#define TRACEROOT "/var/tmp/maltrace/stats." + +void +trace_malloc_stats (s, fn) + char *s, *fn; +{ + FILE *fp; + char defname[sizeof (TRACEROOT) + 64]; + static char mallbuf[1024]; + + fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname)); + if (fp) + { + setvbuf (fp, mallbuf, _IOFBF, sizeof (mallbuf)); + _print_malloc_stats (s, fp); + fflush(fp); + fclose(fp); + } +} + +#endif /* MALLOC_STATS */ + +#if defined (MALLOC_STATS) || defined (MALLOC_TRACE) +FILE * +_imalloc_fopen (s, fn, def, defbuf, defsiz) + char *s; + char *fn; + char *def; + char *defbuf; + size_t defsiz; +{ + char fname[1024]; + long l; + FILE *fp; + + l = (long)getpid (); + if (fn == 0) + { + sprintf (defbuf, "%s%ld", def, l); + fp = fopen(defbuf, "w"); + } + else + { + char *p, *q, *r; + char pidbuf[32]; + int sp; + + sprintf (pidbuf, "%ld", l); + if ((strlen (pidbuf) + strlen (fn) + 2) >= sizeof (fname)) + return ((FILE *)0); + for (sp = 0, p = fname, q = fn; *q; ) + { + if (sp == 0 && *q == '%' && q[1] == 'p') + { + sp = 1; + for (r = pidbuf; *r; ) + *p++ = *r++; + q += 2; + } + else + *p++ = *q++; + } + *p = '\0'; + fp = fopen (fname, "w"); + } + + return fp; +} +#endif /* MALLOC_STATS || MALLOC_TRACE */ diff --git a/utshell-0.5.0/lib/malloc/stub.c b/utshell-0.5.0/lib/malloc/stub.c new file mode 100644 index 00000000..a60a624a --- /dev/null +++ b/utshell-0.5.0/lib/malloc/stub.c @@ -0,0 +1,22 @@ +/* Copyright (C) 1993-2003 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +void +bash_malloc_stub() +{ +} diff --git a/utshell-0.5.0/lib/malloc/table.c b/utshell-0.5.0/lib/malloc/table.c new file mode 100644 index 00000000..e6acbf4a --- /dev/null +++ b/utshell-0.5.0/lib/malloc/table.c @@ -0,0 +1,429 @@ +/* table.c - bookkeeping functions for allocated memory */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "imalloc.h" +#include "table.h" + +#ifdef SHELL +extern int running_trap; +extern int signal_is_trapped PARAMS((int)); +#endif + +extern int malloc_register; + +#ifdef MALLOC_REGISTER + +extern FILE *_imalloc_fopen PARAMS((char *, char *, char *, char *, size_t)); + +#define FIND_ALLOC 0x01 /* find slot for new allocation */ +#define FIND_EXIST 0x02 /* find slot for existing entry for free() or search */ + +static int table_count = 0; +static int table_allocated = 0; +static int table_bucket_index = REG_TABLE_SIZE-1; +static mr_table_t mem_table[REG_TABLE_SIZE]; +static mr_table_t mem_overflow; + +#ifndef STREQ +#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) +#endif + +static int location_table_index = 0; +static int location_table_count = 0; +static ma_table_t mlocation_table[REG_TABLE_SIZE]; + +/* + * NOTE: taken from dmalloc (http://dmalloc.com) and modified. + */ +static unsigned int +mt_hash (key) + const PTR_T key; +{ + unsigned int a, b, c; + unsigned long x; + + /* set up the internal state */ + a = 0x9e3779b9; /* the golden ratio; an arbitrary value */ + x = (unsigned long)key; /* truncation is OK */ + b = x >> 8; + c = x >> 3; /* XXX - was >> 4 */ + + HASH_MIX(a, b, c); + return c; +} + +#if 0 +static unsigned int +which_bucket (mem) + PTR_T mem; +{ + return (mt_hash ((unsigned char *)mem) & (REG_TABLE_SIZE-1)); +} + +#else +#define which_bucket(mem) (mt_hash ((unsigned char *)(mem)) & (REG_TABLE_SIZE-1)); + +#define next_bucket() ((table_bucket_index + 1) & (REG_TABLE_SIZE-1)) +#define next_entry(mem) ((mem == mem_table + REG_TABLE_SIZE - 1) ? mem_table : ++mem) + +#define prev_bucket() (table_bucket_index == 0 ? REG_TABLE_SIZE-1 : table_bucket_index-1) +#define prev_entry(mem) ((mem == mem_table) ? mem_table + REG_TABLE_SIZE - 1 : mem - 1) +#endif + +static mr_table_t * +find_entry (mem, flags) + PTR_T mem; + int flags; +{ + unsigned int bucket; + register mr_table_t *tp; + mr_table_t *endp; + + if (mem_overflow.mem == mem) + return (&mem_overflow); + + /* If we want to insert an allocation entry just use the next slot */ + if (flags & FIND_ALLOC) + { + table_bucket_index = next_bucket(); + table_count++; + tp = mem_table + table_bucket_index; + memset(tp, 0, sizeof (mr_table_t)); /* overwrite next existing entry */ + return tp; + } + + tp = endp = mem_table + table_bucket_index; + + /* search for last allocation corresponding to MEM, return entry pointer */ + while (1) + { + if (tp->mem == mem) + return (tp); + + tp = prev_entry (tp); + + /* if we went all the way around and didn't find it, return NULL */ + if (tp == endp) + return ((mr_table_t *)NULL); + } + + return (mr_table_t *)NULL; +} + +mr_table_t * +mr_table_entry (mem) + PTR_T mem; +{ + return (find_entry (mem, FIND_EXIST)); +} + +void +mregister_describe_mem (mem, fp) + PTR_T mem; + FILE *fp; +{ + mr_table_t *entry; + + entry = find_entry (mem, FIND_EXIST); + if (entry == 0) + return; + fprintf (fp, "malloc: %p: %s: last %s from %s:%d\n", + mem, + (entry->flags & MT_ALLOC) ? "allocated" : "free", + (entry->flags & MT_ALLOC) ? "allocated" : "freed", + entry->file ? entry->file : "unknown", + entry->line); +} + +void +mregister_alloc (tag, mem, size, file, line) + const char *tag; + PTR_T mem; + size_t size; + const char *file; + int line; +{ + mr_table_t *tentry; + sigset_t set, oset; + int blocked_sigs; + + /* Block all signals in case we are executed from a signal handler. */ + blocked_sigs = 0; +#ifdef SHELL + if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) +#endif + { + _malloc_block_signals (&set, &oset); + blocked_sigs = 1; + } + + mlocation_register_alloc (file, line); + + tentry = find_entry (mem, FIND_ALLOC); + + if (tentry == 0) + { + /* oops. table is full. punt. */ + fprintf (stderr, _("register_alloc: alloc table is full with FIND_ALLOC?\n")); + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); + return; + } + + if (tentry->flags & MT_ALLOC) + { + /* oops. bad bookkeeping. ignore for now */ + fprintf (stderr, _("register_alloc: %p already in table as allocated?\n"), mem); + } + + tentry->mem = mem; + tentry->size = size; + tentry->func = tag; + tentry->flags = MT_ALLOC; + tentry->file = file; + tentry->line = line; + tentry->nalloc++; + + if (tentry != &mem_overflow) + table_allocated++; + + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); +} + +void +mregister_free (mem, size, file, line) + PTR_T mem; + int size; + const char *file; + int line; +{ + mr_table_t *tentry; + sigset_t set, oset; + int blocked_sigs; + + /* Block all signals in case we are executed from a signal handler. */ + blocked_sigs = 0; +#ifdef SHELL + if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) +#endif + { + _malloc_block_signals (&set, &oset); + blocked_sigs = 1; + } + + tentry = find_entry (mem, FIND_EXIST); + if (tentry == 0) + { + /* oops. not found. */ +#if 0 + fprintf (stderr, "register_free: %p not in allocation table?\n", mem); +#endif + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); + return; + } + if (tentry->flags & MT_FREE) + { + /* oops. bad bookkeeping. ignore for now */ + fprintf (stderr, _("register_free: %p already in table as free?\n"), mem); + } + + tentry->flags = MT_FREE; + tentry->func = "free"; + tentry->file = file; + tentry->line = line; + tentry->nfree++; + + if (tentry != &mem_overflow) + table_allocated--; + + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); +} + +/* If we ever add more flags, this will require changes. */ +static char * +_entry_flags(x) + int x; +{ + if (x & MT_FREE) + return "free"; + else if (x & MT_ALLOC) + return "allocated"; + else + return "undetermined?"; +} + +static void +_register_dump_table(fp) + FILE *fp; +{ + register int i; + mr_table_t entry; + + for (i = 0; i < REG_TABLE_SIZE; i++) + { + entry = mem_table[i]; + if (entry.mem) + fprintf (fp, "%s[%d] %p:%zu:%s:%s:%s:%d:%d:%d\n", + (i == table_bucket_index) ? "*" : "", + i, + entry.mem, entry.size, + _entry_flags(entry.flags), + entry.func ? entry.func : "unknown", + entry.file ? entry.file : "unknown", + entry.line, + entry.nalloc, entry.nfree); + } +} + +void +mregister_dump_table() +{ + _register_dump_table (stderr); +} + +void +mregister_table_init () +{ + memset (mem_table, 0, sizeof(mr_table_t) * REG_TABLE_SIZE); + memset (&mem_overflow, 0, sizeof (mr_table_t)); + table_count = 0; +} + +/* Simple for now */ + +static ma_table_t * +find_location_entry (file, line) + const char *file; + int line; +{ + register ma_table_t *tp, *endp; + + endp = mlocation_table + location_table_count; + for (tp = mlocation_table; tp <= endp; tp++) + { + if (tp->line == line && STREQ (file, tp->file)) + return tp; + } + return (ma_table_t *)NULL; +} + +void +mlocation_register_alloc (file, line) + const char *file; + int line; +{ + ma_table_t *lentry; + const char *nfile; + + if (file == 0) + { + mlocation_table[0].nalloc++; + return; + } + + nfile = strrchr (file, '/'); + if (nfile) + nfile++; + else + nfile = file; + + lentry = find_location_entry (nfile, line); + if (lentry == 0) + { + location_table_index++; + if (location_table_index == REG_TABLE_SIZE) + location_table_index = 1; /* slot 0 reserved */ + lentry = mlocation_table + location_table_index; + lentry->file = nfile; + lentry->line = line; + lentry->nalloc = 1; + if (location_table_count < REG_TABLE_SIZE) + location_table_count++; /* clamp at REG_TABLE_SIZE for now */ + } + else + lentry->nalloc++; +} + +static void +_location_dump_table (fp) + FILE *fp; +{ + register ma_table_t *tp, *endp; + + endp = mlocation_table + location_table_count; + for (tp = mlocation_table; tp < endp; tp++) + fprintf (fp, "%s:%d\t%d\n", tp->file ? tp->file : "unknown", + tp->line ? tp->line : 0, + tp->nalloc); +} + +void +mlocation_dump_table () +{ + _location_dump_table (stderr); +} + +#define LOCROOT "/var/tmp/maltrace/locations." + +void +mlocation_write_table () +{ + FILE *fp; + char defname[sizeof (LOCROOT) + 64]; + + fp = _imalloc_fopen ((char *)NULL, (char *)NULL, LOCROOT, defname, sizeof (defname)); + if (fp == 0) + return; /* XXX - no error message yet */ + _location_dump_table (fp); + fclose (fp); +} + +void +mlocation_table_init () +{ + memset (mlocation_table, 0, sizeof (ma_table_t) * REG_TABLE_SIZE); + mlocation_table[0].file = ""; /* reserve slot 0 for unknown locations */ + mlocation_table[0].line = 0; + mlocation_table[0].nalloc = 0; + location_table_count = 1; +} + +#endif /* MALLOC_REGISTER */ + +int +malloc_set_register(n) + int n; +{ + int old; + + old = malloc_register; + malloc_register = n; + return old; +} diff --git a/utshell-0.5.0/lib/malloc/table.h b/utshell-0.5.0/lib/malloc/table.h new file mode 100644 index 00000000..92866cf2 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/table.h @@ -0,0 +1,116 @@ +/* table.h - definitions for tables for keeping track of allocated memory */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _MTABLE_H +#define _MTABLE_H + +#include "imalloc.h" + +#ifdef MALLOC_REGISTER + +/* values for flags byte. */ +#define MT_ALLOC 0x01 +#define MT_FREE 0x02 + +/* + * Memory table entry. + * + * MEM is the address of the allocated pointer. + * SIZE is the requested allocation size. + * FLAGS includes either MT_ALLOC (MEM is allocated) or MT_FREE (MEM is + * not allocated). Other flags later. + * FUNC is set to the name of the function doing the allocation (from the + * `tag' argument to register_alloc(). + * FILE and LINE are the filename and line number of the last allocation + * and free (depending on STATUS) of MEM. + * NALLOC and NFREE are incremented on each allocation that returns MEM or + * each free of MEM, respectively (way to keep track of memory reuse + * and how well the free lists are working). + * + */ +typedef struct mr_table { + PTR_T mem; + size_t size; + char flags; + const char *func; + const char *file; + int line; + int nalloc, nfree; +} mr_table_t; + +#define REG_TABLE_SIZE 8192 + +extern mr_table_t *mr_table_entry PARAMS((PTR_T)); +extern void mregister_alloc PARAMS((const char *, PTR_T, size_t, const char *, int)); +extern void mregister_free PARAMS((PTR_T, int, const char *, int)); +extern void mregister_describe_mem (); +extern void mregister_dump_table PARAMS((void)); +extern void mregister_table_init PARAMS((void)); + +typedef struct ma_table { + const char *file; + int line; + int nalloc; +} ma_table_t; + +extern void mlocation_register_alloc PARAMS((const char *, int)); +extern void mlocation_table_init PARAMS((void)); +extern void mlocation_dump_table PARAMS((void)); +extern void mlocation_write_table PARAMS((void)); + +/* NOTE: HASH_MIX taken from dmalloc (http://dmalloc.com) */ + +/* + * void HASH_MIX + * + * DESCRIPTION: + * + * Mix 3 32-bit values reversibly. For every delta with one or two + * bits set, and the deltas of all three high bits or all three low + * bits, whether the original value of a,b,c is almost all zero or is + * uniformly distributed. + * + * If HASH_MIX() is run forward or backward, at least 32 bits in a,b,c + * have at least 1/4 probability of changing. If mix() is run + * forward, every bit of c will change between 1/3 and 2/3 of the + * time. (Well, 22/100 and 78/100 for some 2-bit deltas.) + * + * HASH_MIX() takes 36 machine instructions, but only 18 cycles on a + * superscalar machine (like a Pentium or a Sparc). No faster mixer + * seems to work, that's the result of my brute-force search. There + * were about 2^68 hashes to choose from. I only tested about a + * billion of those. + */ +#define HASH_MIX(a, b, c) \ + do { \ + a -= b; a -= c; a ^= (c >> 13); \ + b -= c; b -= a; b ^= (a << 8); \ + c -= a; c -= b; c ^= (b >> 13); \ + a -= b; a -= c; a ^= (c >> 12); \ + b -= c; b -= a; b ^= (a << 16); \ + c -= a; c -= b; c ^= (b >> 5); \ + a -= b; a -= c; a ^= (c >> 3); \ + b -= c; b -= a; b ^= (a << 10); \ + c -= a; c -= b; c ^= (b >> 15); \ + } while(0) + +#endif /* MALLOC_REGISTER */ + +#endif /* _MTABLE_H */ diff --git a/utshell-0.5.0/lib/malloc/trace.c b/utshell-0.5.0/lib/malloc/trace.c new file mode 100644 index 00000000..391ca9d8 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/trace.c @@ -0,0 +1,126 @@ +/* trace.c - tracing functions for malloc */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "imalloc.h" + +extern int malloc_trace; + +static int _mtrace_verbose = 0; + +#ifdef MALLOC_TRACE + +extern FILE *_imalloc_fopen PARAMS((char *, char *, char *, char *, size_t)); + +FILE *_mtrace_fp = NULL; +extern char _malloc_trace_buckets[]; + +void +mtrace_alloc (tag, mem, size, file, line) + const char *tag; + PTR_T mem; + size_t size; + const char *file; + int line; +{ + if (_mtrace_fp == NULL) + _mtrace_fp = stderr; + + if (_mtrace_verbose) + fprintf (_mtrace_fp, "alloc: %s: %p (%zu bytes) from '%s:%d'\n", + tag, mem, size, file ? file : "unknown", line); + else + fprintf (_mtrace_fp, "alloc:%p:%zu:%s:%d\n", + mem, size, file ? file : "unknown", line); +} + +void +mtrace_free (mem, size, file, line) + PTR_T mem; + int size; + const char *file; + int line; +{ + if (_mtrace_fp == NULL) + _mtrace_fp = stderr; + + if (_mtrace_verbose) + fprintf (_mtrace_fp, "free: %p (%d bytes) from '%s:%d'\n", + mem, size, file ? file : "unknown", line); + else + fprintf (_mtrace_fp, "free:%p:%d:%s:%d\n", + mem, size, file ? file : "unknown", line); +} +#endif /* MALLOC_TRACE */ + +int +malloc_set_trace (n) + int n; +{ + int old; + + old = malloc_trace; + malloc_trace = n; + _mtrace_verbose = (n > 1); + return old; +} + +void +malloc_set_tracefp (fp) + FILE *fp; +{ +#ifdef MALLOC_TRACE + _mtrace_fp = fp ? fp : stderr; +#endif +} + +void +malloc_trace_bin (n) + int n; +{ +#ifdef MALLOC_TRACE + _malloc_trace_buckets[n] = 1; +#endif +} + +#define TRACEROOT "/var/tmp/maltrace/trace." + +void +malloc_set_tracefn (s, fn) + char *s; + char *fn; +{ +#ifdef MALLOC_TRACE + FILE *fp; + char defname[sizeof (TRACEROOT) + 64]; + + fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname)); + if (fp) + malloc_set_tracefp (fp); +#endif +} diff --git a/utshell-0.5.0/lib/malloc/watch.c b/utshell-0.5.0/lib/malloc/watch.c new file mode 100644 index 00000000..00c8a824 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/watch.c @@ -0,0 +1,151 @@ +/* watch.c - watchpoint functions for malloc */ + +/* Copyright (C) 2001-2003 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "imalloc.h" + +#ifdef MALLOC_WATCH +#include "watch.h" + +#define WATCH_MAX 32 + +int _malloc_nwatch; +static PTR_T _malloc_watch_list[WATCH_MAX]; + +static void +watch_warn (addr, file, line, type, data) + PTR_T addr; + const char *file; + int line, type; + unsigned long data; +{ + char *tag; + + if (type == W_ALLOC) + tag = "allocated"; + else if (type == W_FREE) + tag = "freed"; + else if (type == W_REALLOC) + tag = "requesting resize"; + else if (type == W_RESIZED) + tag = "just resized"; + else + tag = "bug: unknown operation"; + + fprintf (stderr, "malloc: watch alert: %p %s ", addr, tag); + if (data != (unsigned long)-1) + fprintf (stderr, "(size %lu) ", data); + fprintf (stderr, "from '%s:%d'\n", file ? file : "unknown", line); +} + +void +_malloc_ckwatch (addr, file, line, type, data) + PTR_T addr; + const char *file; + int line, type; + unsigned long data; +{ + register int i; + + for (i = _malloc_nwatch - 1; i >= 0; i--) + { + if (_malloc_watch_list[i] == addr) + { + watch_warn (addr, file, line, type, data); + return; + } + } +} +#endif /* MALLOC_WATCH */ + +PTR_T +malloc_watch (addr) + PTR_T addr; +{ + register int i; + PTR_T ret; + + if (addr == 0) + return addr; + ret = (PTR_T)0; + +#ifdef MALLOC_WATCH + for (i = _malloc_nwatch - 1; i >= 0; i--) + { + if (_malloc_watch_list[i] == addr) + break; + } + if (i < 0) + { + if (_malloc_nwatch == WATCH_MAX) /* full, take out first */ + { + ret = _malloc_watch_list[0]; + _malloc_nwatch--; + for (i = 0; i < _malloc_nwatch; i++) + _malloc_watch_list[i] = _malloc_watch_list[i+1]; + } + _malloc_watch_list[_malloc_nwatch++] = addr; + } +#endif + + return ret; +} + +/* Remove a watchpoint set on ADDR. If ADDR is NULL, remove all + watchpoints. Returns ADDR if everything went OK, NULL if ADDR was + not being watched. */ +PTR_T +malloc_unwatch (addr) + PTR_T addr; +{ +#ifdef MALLOC_WATCH + register int i; + + if (addr == 0) + { + for (i = 0; i < _malloc_nwatch; i++) + _malloc_watch_list[i] = (PTR_T)0; + _malloc_nwatch = 0; + return ((PTR_T)0); + } + else + { + for (i = 0; i < _malloc_nwatch; i++) + { + if (_malloc_watch_list[i] == addr) + break; + } + if (i == _malloc_nwatch) + return ((PTR_T)0); /* not found */ + /* shuffle everything from i+1 to end down 1 */ + _malloc_nwatch--; + for ( ; i < _malloc_nwatch; i++) + _malloc_watch_list[i] = _malloc_watch_list[i+1]; + return addr; + } +#else + return ((PTR_T)0); +#endif +} diff --git a/utshell-0.5.0/lib/malloc/watch.h b/utshell-0.5.0/lib/malloc/watch.h new file mode 100644 index 00000000..2a0f4970 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/watch.h @@ -0,0 +1,41 @@ +/* watch.h - definitions for tables for keeping track of allocated memory */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _MWATCH_H +#define _MWATCH_H + +#include "imalloc.h" + +#ifdef MALLOC_WATCH + +/* `Events' for watchpoints */ + +#define W_ALLOC 0x01 +#define W_FREE 0x02 +#define W_REALLOC 0x04 +#define W_RESIZED 0x08 + +extern int _malloc_nwatch; + +extern void _malloc_ckwatch PARAMS((PTR_T, const char *, int, int, unsigned long)); + +#endif /* MALLOC_WATCH */ + +#endif /* _MWATCH_H */ diff --git a/utshell-0.5.0/lib/malloc/x386-alloca.s b/utshell-0.5.0/lib/malloc/x386-alloca.s new file mode 100644 index 00000000..112d33cc --- /dev/null +++ b/utshell-0.5.0/lib/malloc/x386-alloca.s @@ -0,0 +1,63 @@ +;; alloca386.s 1.2 +;; GNU-compatible stack allocation function for Xenix/386. +;; Written by Chip Salzenberg at ComDev. +;; Last modified 90/01/11 +;;> Is your alloca clearly better than the one in i386-alloca.s? I haven't +;;> looked at either. +;; +;;They're different because Xenix/386 has a different assembler. SCO +;;Xenix has the Microsoft C compiler and the Microsoft macro assembler, +;;called "masm". MASM's assembler syntax is quite different from AT&T's +;;in all sorts of ways. Xenix people can't use the AT&T version. +;;-- +;;Chip Salzenberg at ComDev/TCT , + + TITLE $alloca386 + + .386 +DGROUP GROUP CONST, _BSS, _DATA +_DATA SEGMENT DWORD USE32 PUBLIC 'DATA' +_DATA ENDS +_BSS SEGMENT DWORD USE32 PUBLIC 'BSS' +_BSS ENDS +CONST SEGMENT DWORD USE32 PUBLIC 'CONST' +CONST ENDS +_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE' + ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP + + PUBLIC _alloca +_alloca PROC NEAR + +; Get argument. + pop edx ; edx -> return address + pop eax ; eax = amount to allocate + +; Validate allocation amount. + add eax,3 + and eax,not 3 + cmp eax,0 + jg aa_size_ok + mov eax,4 +aa_size_ok: + +; Allocate stack space. + mov ecx,esp ; ecx -> old stack pointer + sub esp,eax ; perform allocation + mov eax,esp ; eax -> new stack pointer + +; Copy the three saved register variables from old stack top to new stack top. +; They may not be there. So we waste twelve bytes. Big fat hairy deal. + push DWORD PTR 8[ecx] + push DWORD PTR 4[ecx] + push DWORD PTR 0[ecx] + +; Push something so the caller can pop it off. + push eax + +; Return to caller. + jmp edx + +_alloca ENDP + +_TEXT ENDS + END diff --git a/utshell-0.5.0/lib/malloc/xleaktrace b/utshell-0.5.0/lib/malloc/xleaktrace new file mode 100755 index 00000000..d7e3cd55 --- /dev/null +++ b/utshell-0.5.0/lib/malloc/xleaktrace @@ -0,0 +1,47 @@ +#! /usr/bin/awk -f +# +# xleaktrace - print unfreed memory using input generated by compact malloc +# tracing (malloc_set_trace(1)) +# +# NOTE: we ignore `realloc' tags because they're just extra information +# +# Copyright (c) 2001 Chester Ramey +# Permission is hereby granted to deal in this Software without restriction. +# THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. +# +# Chet Ramey +# chet@po.cwru.edu +# +BEGIN { + FS=":"; +} + +$1 == "alloc" { + alloc[$2] = 1; + + size[$2] = $3; + file[$2] = $4; + line[$2] = $5; + +# printf "allocated: %s %d %d %s %d\n", $2, alloc[$2], size[$2], file[$2], line[$2]; + } + +$1 == "free" { + if ($2 in alloc) { + alloc[$2] = 0; +# printf "freed: %s %d\n", $2, alloc[$2]; + } else + printf "freeing unallocated pointer: %s\n", $2; + + } + +END { + printf "unfreed memory\n"; + for (ptr in alloc) { + if (alloc[ptr] == 1) { + printf "%s (%d) from %s:%d\n", ptr, size[ptr], file[ptr], line[ptr]; + } + } +} + + diff --git a/utshell-0.5.0/lib/malloc/xmalloc.c b/utshell-0.5.0/lib/malloc/xmalloc.c new file mode 100644 index 00000000..f6dec67a --- /dev/null +++ b/utshell-0.5.0/lib/malloc/xmalloc.c @@ -0,0 +1,94 @@ +/* xmalloc.c -- safe versions of malloc and realloc */ + +/* Copyright (C) 1991-2003 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +/* **************************************************************** */ +/* */ +/* Memory Allocation and Deallocation. */ +/* */ +/* **************************************************************** */ + +static void +memory_error_and_abort (fname) + char *fname; +{ + fprintf (stderr, "%s: out of virtual memory\n", fname); + exit (2); +} + +/* Return a pointer to free()able block of memory large enough + to hold BYTES number of bytes. If the memory cannot be allocated, + print an error message and abort. */ +PTR_T +xmalloc (bytes) + size_t bytes; +{ + PTR_T temp; + + temp = malloc (bytes); + if (temp == 0) + memory_error_and_abort ("xmalloc"); + return (temp); +} + +PTR_T +xrealloc (pointer, bytes) + PTR_T pointer; + size_t bytes; +{ + PTR_T temp; + + temp = pointer ? realloc (pointer, bytes) : malloc (bytes); + + if (temp == 0) + memory_error_and_abort ("xrealloc"); + return (temp); +} + +void +xfree (string) + PTR_T string; +{ + if (string) + free (string); +} diff --git a/utshell-0.5.0/lib/r2c.c b/utshell-0.5.0/lib/r2c.c new file mode 100644 index 00000000..b597f9a7 --- /dev/null +++ b/utshell-0.5.0/lib/r2c.c @@ -0,0 +1,38 @@ +#include + +#include + + + +int add(int i1, int i2) { + + return i1+i2; + +} + + + +void replace(__int8_t s[3], __int8_t d[3]) { + + int i = 0; + + for (i = 0; i < 3 ; i++) { + + s[i] += 33; + + } + + memset(d, 0xFF, sizeof(*d)*3); + + return; + +} + + + +void add_v2(int i1, int i2, int *ouput) { + + *ouput = i1 + i2; + + return; +} \ No newline at end of file diff --git a/utshell-0.5.0/lib/r2c.o b/utshell-0.5.0/lib/r2c.o new file mode 100644 index 0000000000000000000000000000000000000000..b1b1b2f3da83543a4734ab7d689acbcf430c871c GIT binary patch literal 1664 zcmbtT&ubG=5S~r6Ra-UwIEWS8UZhg{XzM{KB9XB6A!0$uL9x`$=4ruhBiXG)B`O5O zB?vi+e~1SUBKA=96g-KiUW9-i>aEB^o!NbpuG{sZUwCikee=!CX7=q<>+0p4VF1H` zi?DrS7T{Ta+b>3L5r$z1$};#CG{azJvt16`)~3;&UnNeqewZ?7_GGZKzGj7#q0RTP zwiQaJE8A928r_3$;H4b>g9<*qD7385Xf?y!lh3GIe@orpZQ&+^wH_7ge2m(}tz}T& z(Ct5SHdgL^tS zfD_2mB1D=?2MW(~rTqhQC_s*47bu9hOB=^?l}JGGTf`$y(#G+daXwL5pxN(&pY&IE zAfNeW0P^_DLLMt+ArAvtG*%h>3%`2@Ps+oI=ixaHX`au~Y>+#GtAHzw<491Q$2t(r ziv0StBOI`+Rj8}`OSYrHRj#Leq81)ZYdQGZp?|s$SGX0!)O-#tEk;p0%=2^JPVxLa zAiRgJZ&%Rz_1G@5S6556@KwVHQMG*=M8)$!I5pQ*%g8O)d?jYDl_xykcJ6_Qhg9N~3r`g{7@9>ECBuGm+^&U-zyW18QKmU8Lt6PQ1RKJn=r z_?1K%NcTU38mjrP`BRunH79W;!Trr7i9YvdJCop&(qG9#!sk4u=FlN7dB>ud7B*O@ zEzghXE9hj+|BEgtwUFjd-yG-j{4;x_uA%#z+S0c{x#@hWo1Q&V@Jja|r9%R`T%S3F QURJ)T$s2uT?4s`OrUOxaso2&yR(BNI$IK~hj2FGSi9ZXBCk^sHl$F+CMKAiio z4Ji!?C}Ha&85BV)K}DprqODq?sA^HE(yEC>nqM?h6n>-?Y7~hoNTF3#q1H-z&dizJ z_1H*Nj6zHE>O#qa6v=7D>9x`YxMtA1f%c+jJ15MGGJwzCqFEMu3O zOL`wy`&bKWW~0%<$I+8_Lxtma3+|m81M}DyJ+lp)J9xPg~xn;n>sCT>Q-I;!2Q|1~=kZCgMU-aXxLa$sINd3@gU-S@!m_HS{8 z-uxUc(ZUTr=$sg)aD2Yt-j5bW@6C?R&q5-91oL}^hPlIUrOZqwADYfvnPeOL5CT+y zJ7a!6_gb!(U9Oes9@IUzmT!i}>-Qn@R`906@74SqdpPEn-Zd==G|?(WkB*IAp{H{W zxN{`z&bQ7$kI*lyLcP*|39jVnL!C#zRnh710J|z6Sj9%)bJz;dQ*{A!zW|#!Xb_;6 zgB1d7<{%`%77o@4@B{}P0&L}=SAcCC^a;?%K~#X99PATd7Y7FfcyiegT5|NqS9;2tbJ(JG4Gwl;OH_{tP=Mot=X)4498CN^PnS4=VZkeWK+Bg|peH@XB z7bBBT9ATM!Zh{YJBwWi#=o&lANdiJ2G2AA+PaW-iYk6pWjPx#O&HPaz$)yT5-+Xx(Vu7V{2o zYVUju9=-Jf;-d%^q!8`cH<&ilpslL)`RCxd{1VXkL*WO&&OpP@sd!nPR2Q^fC>WL!uP7B3b$LZOv4F>dx3O$} z%k+9>A}qIMQDh6X6HgKTh^Pgcd~>GxQ8%IbrM`9@({X*ccfc+&}QN@$}AJ z!vh9`=hQB~2eW1tUyJgC3gW;q$^~ESxLfm|3;D93`Oab?CHZq@d}A3ecNEJ+Tq7y+ z69akty^A*X-aii62&YAMyJY{yE|gDEukn#}&SX_^iTD6MkOd|4#UX!mp#n_`bqFMEqriKSSgG zOyNHx{2PV;5#hHLK1p%@tnk+f|5f4Bln>TSC~}>LDb9UC7x_8DI`vEY28z?D@INN| zhZUY^wn5=vrZ}4wet`Hvh5t4M+OP0$5I?5y_~D9@Rrt%qA5-{)#J{5OPl+(>RfYd2 z@vkZTG{yO)!tWw{UEx2XIPWO@Y2x2k_%_0SQ}}a)KUMfkgy$9h9f~h2O1Zy3C%a`d z56LG8uU7bjWZ$XqR|s!Y_+Js0`z+&cqBt4F{!QZLx)$xp?wn$eU+XBZEBr4AUsd?` zg*p43!pDgJNa0^4{Hel!NcR6G9@9ouo)_z(&PS2?zd`fbq43WLGd4)PjMGK@d4(ss zc%ox`c@|(F{|JXx#z79{KcZR0hlt1AX)2uQQ+S!rn8M5Xvao$L3*{ZOjwRZZ)GRX- z3p?hF!@|764aaSpg{`~*yf(n%C?W59jiZ8HW0}-FBc#B_}fl<#jA;(k#As69QLUQ zSHTafxIXxm%L*!`qC_@Ai@sQ!qR9GTE$GP8?SWlf_$LNM`eXiBXQ}z)A5v;epx9m-e?;k2Aj^R5Qsd9j z`0_r(@v+uc$3G4n#*}%2%Hf3^~4RPlNSR{)g~|1`^`e(nb2o_AGQsy=2AM zcgVk-LtVA~32{oA>;(DGC;{aBCH)#GORe7(TE8e6;`-q`S^CR$#eCGU(d9mkf147< paQG*y>W}w?@`wP#*sWUL6zgt*7SBHj9ZUJ&qx`Q*M{3pe`yWRw43hu= literal 0 HcmV?d00001 diff --git a/utshell-0.5.0/lib/r2c/r2c.c b/utshell-0.5.0/lib/r2c/r2c.c new file mode 100644 index 00000000..bfc3779b --- /dev/null +++ b/utshell-0.5.0/lib/r2c/r2c.c @@ -0,0 +1,40 @@ +#include + +#include + + + +int add(int i1, int i2) { + int c = 0; + printf("hello world! call me libr2c.a \n"); + int y = 1; + return i1+i2; + +} + + + +void replace(__int8_t s[3], __int8_t d[3]) { + + int i = 0; + + for (i = 0; i < 3 ; i++) { + + s[i] += 33; + + } + + memset(d, 0xFF, sizeof(*d)*3); + + return; + +} + + + +void add_v2(int i1, int i2, int *ouput) { + + *ouput = i1 + i2; + + return; +} diff --git a/utshell-0.5.0/lib/r2c/r2c.o b/utshell-0.5.0/lib/r2c/r2c.o new file mode 100644 index 0000000000000000000000000000000000000000..344cf3025b657915327f3c20a3efefb413f1bfec GIT binary patch literal 6624 zcmbVQeQZZ%r>m<;N!-?ee^dwdUtll56Yff zOE*L1_4^QcYj{=T_iBEQJsfjQ@2d7Bs%W*MMaN37(KC4m%sCQz=R0PgMaUOcpj_*} z1W&T`q0GJCs_FKx2faEVSk0rpXR#JwW8DRi{Q_*_pjm)k4web9nS-zZTR2!Fz~daO z7ho#~y#j3Gpih844q^iAoas3!#&;=mDLPvChN z!i)ex&Vt&U00);&Ldy>XIMneRfXf0L z=HXls;9GUO!RD#}Mtv86YXXe%*#00u!v6v|cuOpj?(6s|=+(oI)jSdmU|s8f0u*Zf z*wBCrhH*9GPC<4n08%?r7NgOs zP`ZVyt$YaeJZHxsG;C<)Y^daK0x=Zr;wkiJGcB|fCC}Ldp%j4C0_&xC@$y=dyYX_{4rVX{Ceq$&2iGp5mLxtgv4peIDgyA+vv>hEXzK1(7 z=)Pqac6Fd}NQd`^jNG$~u@)doLqVdon)P{M-3C1_ux{tdL_ORw)G9gyb%b{|}X@b9B;NsK}VrlZ+%WUfW5f%<)JXFFLLWB8<{@ zEH~*GgG0juK){AAOJI>H0120bebhEg%gSbKN0>3agVl*i0^iH@`uBB@tJh!G1Fo)} z(%1Fqb^p>ErgYuWgUnOoU9T_4%Co9j*Fn(sWc|t=O=Pe%e5WDoH4Cr#x|p_W8-aRIHv7Ho!q36;0j$y!Qh<3 z(3w%lri{Y)xNSPjGAFa~q{#=9htV+X$&OE%yem6hu$(YnP4436Ha=l032FsHm=4Q%? zC$eVcs`I@e%**>9oMf_QzQ7L(`YpiNan!h`5Dwej-@hfiX0%|7aYr_Fbw2_}Z>@lM z6d{8YMLYHlrp+{KD;j+MIXIVJ0vdl<_yw>t*!+^Gzp*w43cz98R&0dAFC5wKNpJ;h zKg3(+C?Ne#+Qo2JIw0V`c zuWa-(o|Z^hs=Xr1C}AmhS)&ve)Luv!suizD6&5vlMLMy7$Aq_~Vt(YM4VPS1FP)#m zuO>gzUM3Tf&(VL3^nVC77MaY@8N_tL*gZV5Yv-^rGB~(@;3?y&ox6qy3z`M^7wlPHy)Ib zs5poGHR9V9UfSa=jRn<8mk`Knk%WRiDt8IaBNo~33j&tTlH@<7e*39i@?Rx>SmAxd z?^pO|i9ew5r-&a{_;%uR3O`NwIfef_;S&nKh9=|t3jYA{mlggD_4_l0|CI1=6#hqq z-%|J#`T4WLUnl%mh0jntm@{FK^E^y`?hCra&k@$CUFtWJpB9DxG3h_3@IXppKS%fzg}+32Ug6&+|1zVL>-%%kTSDWIe3I}=g+EC8 z-3ot&@HU126=Au~(*Gv%lU4NJAYRUENuTu2Df;-ej^#Cl{{`Wz3jdx^XTMYUIPo7U z{40b%QTPu?|KG%8*eJ^TVl7?WGXB?TTssv0Y4S5jy!6vU{CR~Zx^$zXe|Z;R8~+H0 zTKYi_%YQ_*hz}EwvC~jE)2HwahL5tmP$ru8q(`{&ZJR%@hS|aILDQ9kKX$50Y&|irR5im@LT~u{A;ieewAez zrBX2>TcAc;%uTV#{9!f7$kX<~CSK%wU1C|Q{jY-t^!Y{YyTKNHR_+;qO!lv4glhlW z$sTPgi@bksD}kx@o585s{Ef+uX<=~wP*mq{4{)kapx8&~6pFm31X`?n7#gbCKS2Gi zmxffUx(9%-8bACKgGJh7{FrB{@#7y-s!yQUUh02DX;dJ~f^N0`=cs?V&#-^YwblNQ z1BX6koFMXYiIUOZD;q=hFYD8wUCsUwzR;kA`Lq0xcCtPTO;RpvG4>s@ujEixb$>#f z5+*xA_A`nDIetmM3PQE{yF&99BSoA)d?!nLIj + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/utshell-0.5.0/lib/readline/ChangeLog b/utshell-0.5.0/lib/readline/ChangeLog new file mode 100644 index 00000000..1cf0c004 --- /dev/null +++ b/utshell-0.5.0/lib/readline/ChangeLog @@ -0,0 +1,403 @@ +Tue Mar 23 14:36:51 1993 Brian Fox (bfox@eos.crseo.ucsb.edu) + + * readline.c (rl_copy): Changed name to rl_copy_text. + +Mon Mar 22 19:16:05 1993 Brian Fox (bfox@eos.crseo.ucsb.edu) + + * dispose_cmd.c, several other files. Declare dispose_xxx () as + "void". + + * builtins/hashcom.h: Make declarations of hashed_filenames be + "extern" to keep the SGI compiler happy. + + * readline.c (rl_initialize_everything): Assign values to + out_stream and in_stream immediately, since + output_character_function () can be called before + readline_internal () is called. + +Tue Dec 8 09:30:56 1992 Brian Fox (bfox@cubit) + + * readline.c (rl_init_terminal) Set PC from BC, not from *buffer. + +Mon Nov 30 09:35:47 1992 Brian Fox (bfox@cubit) + + * readline.c (invoking_keyseqs_in_map, rl_parse_and_bind) Allow + backslash to quote characters, such as backslash, double quote, + and space. Backslash quotes all character indiscriminately. + + * funmap.c (vi_keymap) Fix type in "vi-replace" declaration. + +Fri Nov 20 10:55:05 1992 Brian Fox (bfox@cubit) + + * readline.c (init_terminal_io, rl_prep_terminal): FINALLY! + Declare and use termcap variable `ospeed' when setting up terminal + parameters. + +Thu Oct 8 08:53:07 1992 Brian J. Fox (bfox@helios) + + * Makefile, this directory: Include (as links to the canonical + sources), tilde.c, tilde.h, posixstat.h and xmalloc.c. + +Tue Sep 29 13:07:21 1992 Brian J. Fox (bfox@helios) + + * readline.c (init_terminal_io) Don't set arrow keys if the key + sequences that represent them are already set. + + * readline.c (rl_function_of_keyseq) New function returns the first + function (or macro) found while searching a key sequence. + +Mon Sep 28 00:34:04 1992 Brian J. Fox (bfox@helios) + + * readline.c (LibraryVersion) New static char * contains current + version number. Version is at 2.0. + + * readline.c (rl_complete_internal): Incorporated clean changes + from gilmore (gnu@cygnus.com) to support quoted substrings within + completion functions. + + * readline.c (many locations) Added support for the _GO32_, + whatever that is. Patches supplied by Cygnus, typed in by hand, + with cleanups. + +Sun Aug 16 12:46:24 1992 Brian Fox (bfox@cubit) + + * readline.c (init_terminal_io): Find out the values of the keypad + arrows and bind them to appropriate RL functions if present. + +Mon Aug 10 18:13:24 1992 Brian Fox (bfox@cubit) + + * history.c (stifle_history): A negative argument to stifle + becomes zero. + +Tue Jul 28 09:28:41 1992 Brian Fox (bfox@cubit) + + * readline.c (rl_variable_bind): New local structure describes + booleans by name and address; code in rl_variable_bind () looks at + structure to set simple variables. + + * parens.c (rl_insert_close): New variable rl_blink_matching_paren + is non-zero if we want to blink the matching open when a close is + inserted. If FD_SET is defined, rl_blink_matching_paren defaults + to 1, else 0. If FD_SET is not defined, and + rl_blink_matching_paren is non-zero, the close character(s) are/is + simply inserted. + +Wed Jul 22 20:03:59 1992 Brian Fox (bfox@cubit) + + * history.c, readline.c, vi_mode.c: Cause the functions strchr () + and strrchr () to be used instead of index () and rindex () + throughout the source. + +Mon Jul 13 11:34:07 1992 Brian Fox (bfox@cubit) + + * readline.c: (rl_variable_bind) New variable "meta-flag" if "on" + means force the use of the 8th bit as Meta bit. Internal variable + is called meta_flag. + +Thu Jul 9 10:37:56 1992 Brian Fox (bfox@cubit) + + * history.c (get_history_event) Change INDEX to LOCAL_INDEX. If + compiling for the shell, allow shell metacharacters to separate + history tokens as they would for shell tokens. + +Sat Jul 4 19:29:12 1992 Brian Fox (bfox@cubit) + + * vi_keymap.c: According to Posix, TAB self-inserts instead of + doing completion. + + * vi_mode.c: (rl_vi_yank_arg) Enter VI insert mode after yanking + an arg from the previous line. + + * search.c: New file takes over vi style searching and implements + non-incremental searching the history. + + Makefile: Add search.c and search.o. + + funmap.c: Add names for non-incremental-forward-search-history and + non-incremental-reverse-search-history. + + readline.h: Add extern definitions for non-incremental searching. + + vi_mode.c: Remove old search code; add calls to code in search.c. + +Fri Jul 3 10:36:33 1992 Brian Fox (bfox@cubit) + + * readline.c (rl_delete_horizontal_space); New function deletes + all whitespace surrounding point. + + funmap.c: Add "delete-horizontal-space". + emacs_keymap.c: Put rl_delete_horizontal_space () on M-\. + + * readline.c (rl_set_signals, rl_clear_signals); New function + rl_set_sighandler () is either defined in a Posix way (if + HAVE_POSIX_SIGNALS is defined) or in a BSD way. Function is + called from rl_set_signals () and rl_clear_signals (). + +Fri May 8 12:50:15 1992 Brian Fox (bfox@cubit) + + * readline.c: (readline_default_bindings) Do comparisons with + _POSIX_VDISABLE casted to `unsigned char'. Change tty characters + to be unsigned char. + +Thu Apr 30 12:36:35 1992 Brian Fox (bfox@cubit) + + * readline.c: (rl_getc) Handle "read would block" error on + non-blocking IO streams. + + * readline.c: (rl_signal_handler): Unblock only the signal that we + have caught, not all signals. + +Sun Feb 23 03:33:09 1992 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: Many functions. Use only the macros META_CHAR and + UNMETA to deal with meta characters. Prior to this, we used + numeric values and tests. + + * readline.c (rl_complete_internal) Report exactly the number of + possible completions, not the number + 1. + + * vi_mode.c (rl_do_move) Do not change the cursor position when + using `cw' or `cW'. + + * vi_mode.c (rl_vi_complete) Enter insert mode after completing + with `*' or `\'. + +Fri Feb 21 05:58:18 1992 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (rl_dispatch) Increment rl_key_sequence_length for + meta characters that map onto ESC map. + +Mon Feb 10 01:41:35 1992 Brian Fox (bfox at gnuwest.fsf.org) + + * history.c (history_do_write) Build a buffer of all of the lines + to write and write them in one fell swoop (lower overhead than + calling write () for each line). Suggested by Peter Ho. + + * readline.c: Include hbullx20 as well as hpux for determining + USGr3ness. + + * readline.c (rl_unix_word_rubout) As per the "Now REMEMBER" + comment, pass arguments to rl_kill_text () in the correct order to + preserve prepending and appending of killed text. + + * readline.c (rl_search_history) malloc (), realloc (), and free + () SEARCH_STRING so that there are no static limits on searching. + + * vi_mode.c (rl_vi_subst) Don't forget to end the undo group. + +Fri Jan 31 14:51:02 1992 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (rl_signal_handler): Zero the current history entry's + pointer after freeing the undo_list when SIGINT received. + Reformat a couple of functions. + +Sat Jan 25 13:47:35 1992 Brian Fox (bfox at bears) + + * readline.c (parser_if): free () TNAME after use. + +Tue Jan 21 01:01:35 1992 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (rl_redisplay) and (rl_character_len): Display + Control characters as "^c" and Meta characters as "\234", instead + of "C-C" and "M-C". + +Sun Dec 29 10:59:00 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (init_terminal_io) Default to environment variables + LINES and COLUMNS before termcap entry values. If all else fails, + then assume 80x24 terminal. + +Sat Dec 28 16:33:11 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: If this machine is USG and it is hpux, then define + USGr3. + + * history.c: Cosmetic fixes. + +Thu Nov 21 00:10:12 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * vi_mode.c: (rl_do_move) Place cursor at end of line, never at + next to last character. + +Thu Nov 14 05:08:01 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * history.c (get_history_event) Non-anchored searches can have a + return index of greater than zero from get_history_event (). + +Fri Nov 1 07:02:13 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (rl_translate_keyseq) Make C-? translate to RUBOUT + unconditionally. + +Mon Oct 28 11:34:52 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c; Use Posix directory routines and macros. + + * funmap.c; Add entry for call-last-kbd-macro. + + * readline.c (rl_prep_term); Use system EOF character on POSIX + systems also. + +Thu Oct 3 16:19:53 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c; Make a distinction between having a TERMIOS tty + driver, and having POSIX signal handling. You might one without + the other. New defines used HAVE_POSIX_SIGNALS, and + TERMIOS_TTY_DRIVER. + +Tue Jul 30 22:37:26 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: rl_getc () If a call to read () returns without an + error, but with zero characters, the file is empty, so return EOF. + +Thu Jul 11 20:58:38 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: (rl_get_next_history, rl_get_previous_history) + Reallocate the buffer space if the line being moved to is longer + the the current space allocated. Amazing that no one has found + this bug until now. + +Sun Jul 7 02:37:05 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c:(rl_parse_and_bind) Allow leading whitespace. + Make sure TERMIO and TERMIOS systems treat CR and NL + disctinctly. + +Tue Jun 25 04:09:27 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: Rework parsing conditionals to pay attention to the + prior states of the conditional stack. This makes $if statements + work correctly. + +Mon Jun 24 20:45:59 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: support for displaying key binding information + includes the functions rl_list_funmap_names (), + invoking_keyseqs_in_map (), rl_invoking_keyseqs (), + rl_dump_functions (), and rl_function_dumper (). + + funmap.c: support for same includes rl_funmap_names (). + + readline.c, funmap.c: no longer define STATIC_MALLOC. However, + update both version of xrealloc () to handle a null pointer. + +Thu Apr 25 12:03:49 1991 Brian Fox (bfox at gnuwest.fsf.org) + + * vi_mode.c (rl_vi_fword, fWord, etc. All functions use + the macro `isident()'. Fixed movement bug which prevents + continious movement through the text. + +Fri Jul 27 16:47:01 1990 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (parser_if) Allow "$if term=foo" construct. + +Wed May 23 16:10:33 1990 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c (rl_dispatch) Correctly remember the last command + executed. Fixed typo in username_completion_function (). + +Mon Apr 9 19:55:48 1990 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: username_completion_function (); For text passed in + with a leading `~', remember that this could be a filename (after + it is completed). + +Thu Apr 5 13:44:24 1990 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: rl_search_history (): Correctly handle case of an + unfound search string, but a graceful exit (as with ESC). + + * readline.c: rl_restart_output (); The Apollo passes the address + of the file descriptor to TIOCSTART, not the descriptor itself. + +Tue Mar 20 05:38:55 1990 Brian Fox (bfox at gnuwest.fsf.org) + + * readline.c: rl_complete (); second call in a row causes possible + completions to be listed. + + * readline.c: rl_redisplay (), added prompt_this_line variable + which is the first character character following \n in prompt. + +Sun Mar 11 04:32:03 1990 Brian Fox (bfox at gnuwest.fsf.org) + + * Signals are now supposedly handled inside of SYSV compilation. + +Wed Jan 17 19:24:09 1990 Brian Fox (bfox at sbphy.ucsb.edu) + + * history.c: history_expand (); fixed overwriting memory error, + added needed argument to call to get_history_event (). + +Thu Jan 11 10:54:04 1990 Brian Fox (bfox at sbphy.ucsb.edu) + + * readline.c: added mark_modified_lines to control the + display of an asterisk on modified history lines. Also + added a user variable called mark-modified-lines to the + `set' command. + +Thu Jan 4 10:38:05 1990 Brian Fox (bfox at sbphy.ucsb.edu) + + * readline.c: start_insert (). Only use IC if we don't have an im + capability. + +Fri Sep 8 09:00:45 1989 Brian Fox (bfox at aurel) + + * readline.c: rl_prep_terminal (). Only turn on 8th bit + as meta-bit iff the terminal is not using parity. + +Sun Sep 3 08:57:40 1989 Brian Fox (bfox at aurel) + + * readline.c: start_insert (). Uses multiple + insertion call in cases where that makes sense. + + rl_insert (). Read type-ahead buffer for additional + keys that are bound to rl_insert, and insert them + all at once. Make insertion of single keys given + with an argument much more efficient. + +Tue Aug 8 18:13:57 1989 Brian Fox (bfox at aurel) + + * readline.c: Changed handling of EOF. readline () returns + (char *)EOF or consed string. The EOF character is read from the + tty, or if the tty doesn't have one, defaults to C-d. + + * readline.c: Added support for event driven programs. + rl_event_hook is the address of a function you want called + while Readline is waiting for input. + + * readline.c: Cleanup time. Functions without type declarations + do not use return with a value. + + * history.c: history_expand () has new variable which is the + characters to ignore immediately following history_expansion_char. + +Sun Jul 16 08:14:00 1989 Brian Fox (bfox at aurel) + + * rl_prep_terminal () + BSD version turns off C-s, C-q, C-y, C-v. + + * readline.c -- rl_prep_terminal () + SYSV version hacks readline_echoing_p. + BSD version turns on passing of the 8th bit for the duration + of reading the line. + +Tue Jul 11 06:25:01 1989 Brian Fox (bfox at aurel) + + * readline.c: new variable rl_tilde_expander. + If non-null, this contains the address of a function to call if + the standard meaning for expanding a tilde fails. The function is + called with the text sans tilde (as in "foo"), and returns a + malloc()'ed string which is the expansion, or a NULL pointer if + there is no expansion. + + * readline.h - new file chardefs.h + Separates things that only readline.c needs from the standard + header file publishing interesting things about readline. + + * readline.c: + readline_default_bindings () now looks at terminal chararacters + and binds those as well. + +Wed Jun 28 20:20:51 1989 Brian Fox (bfox at aurel) + + * Made readline and history into independent libraries. + diff --git a/utshell-0.5.0/lib/readline/Makefile b/utshell-0.5.0/lib/readline/Makefile new file mode 100644 index 00000000..8de4ab38 --- /dev/null +++ b/utshell-0.5.0/lib/readline/Makefile @@ -0,0 +1,394 @@ +## -*- text -*- ############################################################# +# # +# Makefile for the Bash versions of the GNU Readline and History Libraries. # +# # +############################################################################# + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PACKAGE = utshell +VERSION = 0.1-release + +PACKAGE_BUGREPORT = bug-utshell@gnu.org +PACKAGE_NAME = utshell +PACKAGE_STRING = utshell 0.1-release +PACKAGE_VERSION = 0.1-release + +srcdir = . + +topdir = ../.. +BUILD_DIR = ../include + +datarootdir = ${prefix}/share + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CC = gcc +RANLIB = ranlib +AR = ar +ARFLAGS = cr +RM = rm -f +CP = cp +MV = mv + +SHELL = /bin/sh + +# Programs to make tags files. +ETAGS = etags -tw +CTAGS = ctags -tw + +DEBUG = + +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security -fPIC +LOCAL_CFLAGS = ${DEBUG} +CPPFLAGS = +LDFLAGS = -L./lib/termcap + +DEFS = -DHAVE_CONFIG_H +LOCAL_DEFS = -DSHELL + +INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib + +CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} \ + $(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS} + +.c.o: + ${RM} $@ + $(CC) -c $(CCFLAGS) $< + +# The name of the main library target. +LIBRARY_NAME = libreadline.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \ + $(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \ + $(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \ + $(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \ + $(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \ + $(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \ + $(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c \ + $(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \ + $(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \ + $(srcdir)/shell.c $(srcdir)/tilde.c $(srcdir)/savestring.c \ + $(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \ + $(srcdir)/colors.c $(srcdir)/parse-colors.c \ + $(srcdir)/mbutil.c $(srcdir)/xfree.c + +# The header files for this library. +HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ + posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \ + ansi_stdlib.h rlstdc.h tcap.h xmalloc.h rlprivate.h rlshell.h \ + rltypedefs.h rlmbutil.h colors.h parse-colors.h + +HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o savestring.o \ + mbutil.o +TILDEOBJ = tilde.o +COLORSOBJ = colors.o parse-colors.o +OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ + rltty.o complete.o bind.o isearch.o display.o signals.o \ + util.o kill.o undo.o macro.o input.o callback.o terminal.o \ + text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) $(COLORSOBJ) \ + xmalloc.o xfree.o compat.o + +# The texinfo files which document this library. +DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo +DOCOBJECT = doc/readline.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]* + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h \ + rlstdc.h rlconf.h rltypedefs.h + +########################################################################## + +all: libreadline.a libhistory.a + +libreadline.a: $(OBJECTS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +libhistory.a: $(HISTOBJ) xmalloc.o xfree.o + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o xfree.o + -test -n "$(RANLIB)" && $(RANLIB) $@ + +documentation: force + test -d doc || mkdir doc + -( cd doc && $(MAKE) $(MFLAGS) ) + +# Since tilde.c is shared between readline and bash, make sure we compile +# it with the right flags when it's built as part of readline +tilde.o: tilde.c + rm -f $@ + $(CC) $(CCFLAGS) -DREADLINE_LIBRARY -c $(srcdir)/tilde.c + +force: + +install: + @echo "This version of the readline library should not be installed." + +uninstall: + @echo "This version of the readline library should not be installed." + +TAGS: force + $(ETAGS) $(CSOURCES) $(HSOURCES) + +tags: force + $(CTAGS) $(CSOURCES) $(HSOURCES) + +clean: force + $(RM) $(OBJECTS) *.a + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +distclean maintainer-clean: clean + $(RM) Makefile + $(RM) TAGS tags + +# Dependencies +bind.o: ansi_stdlib.h posixstat.h +bind.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +bind.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +bind.o: history.h rlstdc.h +callback.o: rlconf.h ansi_stdlib.h +callback.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +callback.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +compat.o: ${BUILD_DIR}/config.h +compat.o: rlstdc.h rltypedefs.h +complete.o: ansi_stdlib.h posixdir.h posixstat.h +complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +complete.o: colors.h +display.o: ansi_stdlib.h posixstat.h +display.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +display.o: tcap.h +display.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +display.o: history.h rlstdc.h +funmap.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +funmap.o: rlconf.h ansi_stdlib.h rlstdc.h +funmap.o: ${BUILD_DIR}/config.h +histexpand.o: ansi_stdlib.h +histexpand.o: history.h histlib.h rlstdc.h +histexpand.o: ${BUILD_DIR}/config.h +histfile.o: ansi_stdlib.h +histfile.o: history.h histlib.h rlstdc.h +histfile.o: ${BUILD_DIR}/config.h +history.o: ansi_stdlib.h +history.o: history.h histlib.h rlstdc.h +history.o: ${BUILD_DIR}/config.h +histsearch.o: ansi_stdlib.h +histsearch.o: history.h histlib.h rlstdc.h +histsearch.o: ${BUILD_DIR}/config.h +input.o: ansi_stdlib.h +input.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +input.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +isearch.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +isearch.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +isearch.o: ansi_stdlib.h history.h rlstdc.h +keymaps.o: emacs_keymap.c vi_keymap.c +keymaps.o: keymaps.h rltypedefs.h chardefs.h rlconf.h ansi_stdlib.h +keymaps.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +keymaps.o: ${BUILD_DIR}/config.h rlstdc.h +kill.o: ansi_stdlib.h +kill.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +kill.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +kill.o: history.h rlstdc.h +macro.o: ansi_stdlib.h +macro.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +macro.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +macro.o: history.h rlstdc.h +mbutil.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h rlmbutil.h +mbutil.o: readline.h keymaps.h rltypedefs.h chardefs.h rlstdc.h +misc.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +misc.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +misc.o: history.h rlstdc.h ansi_stdlib.h +nls.o: ansi_stdlib.h +nls.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +nls.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +nls.o: history.h rlstdc.h +parens.o: rlconf.h +parens.o: ${BUILD_DIR}/config.h +parens.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +readline.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +readline.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +readline.o: history.h rlstdc.h +readline.o: posixstat.h ansi_stdlib.h posixjmp.h +rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +rltty.o: rltty.h +rltty.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +savestring.o: ${BUILD_DIR}/config.h +search.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +search.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +search.o: ansi_stdlib.h history.h rlstdc.h +shell.o: ${BUILD_DIR}/config.h ansi_stdlib.h +signals.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +signals.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +signals.o: history.h rlstdc.h +terminal.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +terminal.o: tcap.h +terminal.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +terminal.o: history.h rlstdc.h +text.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +text.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +text.o: history.h rlstdc.h ansi_stdlib.h +rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +tilde.o: ansi_stdlib.h +tilde.o: ${BUILD_DIR}/config.h +tilde.o: tilde.h +undo.o: ansi_stdlib.h +undo.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +undo.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +undo.o: history.h rlstdc.h xmalloc.h +util.o: posixjmp.h ansi_stdlib.h +util.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +util.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +vi_mode.o: history.h ansi_stdlib.h rlstdc.h +xmalloc.o: ${BUILD_DIR}/config.h ansi_stdlib.h +xfree.o: ${BUILD_DIR}/config.h ansi_stdlib.h + +colors.o: ${BUILD_DIR}/config.h colors.h +colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +colors.o: rlconf.h +colors.o: ansi_stdlib.h posixstat.h +parse-colors.o: ${BUILD_DIR}/config.h colors.h parse-colors.h +parse-colors.o: rldefs.h rlconf.h +parse-colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h + +bind.o: rlshell.h +histfile.o: rlshell.h +nls.o: rlshell.h +readline.o: rlshell.h +shell.o: rlshell.h +terminal.o: rlshell.h +histexpand.o: rlshell.h + +bind.o: rlprivate.h +callback.o: rlprivate.h +complete.o: rlprivate.h +display.o: rlprivate.h +input.o: rlprivate.h +isearch.o: rlprivate.h +kill.o: rlprivate.h +macro.o: rlprivate.h +mbutil.o: rlprivate.h +misc.o: rlprivate.h +nls.o: rlprivate.h +parens.o: rlprivate.h +readline.o: rlprivate.h +rltty.o: rlprivate.h +search.o: rlprivate.h +signals.o: rlprivate.h +terminal.o: rlprivate.h +text.o: rlprivate.h +undo.o: rlprivate.h +util.o: rlprivate.h +vi_mode.o: rlprivate.h +colors.o: rlprivate.h +parse-colors.o: rlprivate.h + +bind.o: xmalloc.h +complete.o: xmalloc.h +display.o: xmalloc.h +funmap.o: xmalloc.h +histexpand.o: xmalloc.h +histfile.o: xmalloc.h +history.o: xmalloc.h +input.o: xmalloc.h +isearch.o: xmalloc.h +keymaps.o: xmalloc.h +kill.o: xmalloc.h +macro.o: xmalloc.h +mbutil.o: xmalloc.h +misc.o: xmalloc.h +readline.o: xmalloc.h +savestring.o: xmalloc.h +search.o: xmalloc.h +shell.o: xmalloc.h +terminal.o: xmalloc.h +text.o: xmalloc.h +tilde.o: xmalloc.h +undo.o: xmalloc.h +util.o: xmalloc.h +vi_mode.o: xmalloc.h +xfree.o: xmalloc.h +xmalloc.o: xmalloc.h +colors.o: xmalloc.h +parse-colors.o: xmalloc.h + +complete.o: rlmbutil.h +display.o: rlmbutil.h +histexpand.o: rlmbutil.h +input.o: rlmbutil.h +isearch.o: rlmbutil.h +mbutil.o: rlmbutil.h +misc.o: rlmbutil.h +readline.o: rlmbutil.h +search.o: rlmbutil.h +text.o: rlmbutil.h +vi_mode.o: rlmbutil.h +colors.o: rlmbutil.h +parse-colors.o: rlmbutil.h + +# Rules for deficient makes, like SunOS and Solaris +bind.o: bind.c +callback.o: callback.c +compat.o: compat.c +complete.o: complete.c +display.o: display.c +funmap.o: funmap.c +input.o: input.c +isearch.o: isearch.c +keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c +kill.o: kill.c +macro.o: macro.c +mbutil.o: mbutil.c +misc.o: misc.c +nls.o: nls.c +parens.o: parens.c +readline.o: readline.c +rltty.o: rltty.c +savestring.o: savestring.c +search.o: search.c +shell.o: shell.c +signals.o: signals.c +terminal.o: terminal.c +text.o: text.c +tilde.o: tilde.c +undo.o: undo.c +util.o: util.c +vi_mode.o: vi_mode.c +xfree.o: xfree.c +xmalloc.o: xmalloc.c + +colors.o: colors.c +parse-colors.o: parse-colors.c + +histexpand.o: histexpand.c +histfile.o: histfile.c +history.o: history.c +histsearch.o: histsearch.c diff --git a/utshell-0.5.0/lib/readline/Makefile.in b/utshell-0.5.0/lib/readline/Makefile.in new file mode 100644 index 00000000..2f417b27 --- /dev/null +++ b/utshell-0.5.0/lib/readline/Makefile.in @@ -0,0 +1,394 @@ +## -*- text -*- ############################################################# +# # +# Makefile for the Bash versions of the GNU Readline and History Libraries. # +# # +############################################################################# + +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + +srcdir = @srcdir@ +VPATH = @srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +datarootdir = @datarootdir@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv + +SHELL = @MAKE_SHELL@ + +# Programs to make tags files. +ETAGS = etags -tw +CTAGS = ctags -tw + +DEBUG = @DEBUG@ + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG} +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib + +CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} \ + $(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS} + +.c.o: + ${RM} $@ + $(CC) -c $(CCFLAGS) $< + +# The name of the main library target. +LIBRARY_NAME = libreadline.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \ + $(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \ + $(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \ + $(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \ + $(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \ + $(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \ + $(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c \ + $(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \ + $(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \ + $(srcdir)/shell.c $(srcdir)/tilde.c $(srcdir)/savestring.c \ + $(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \ + $(srcdir)/colors.c $(srcdir)/parse-colors.c \ + $(srcdir)/mbutil.c $(srcdir)/xfree.c + +# The header files for this library. +HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ + posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \ + ansi_stdlib.h rlstdc.h tcap.h xmalloc.h rlprivate.h rlshell.h \ + rltypedefs.h rlmbutil.h colors.h parse-colors.h + +HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o savestring.o \ + mbutil.o +TILDEOBJ = tilde.o +COLORSOBJ = colors.o parse-colors.o +OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ + rltty.o complete.o bind.o isearch.o display.o signals.o \ + util.o kill.o undo.o macro.o input.o callback.o terminal.o \ + text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) $(COLORSOBJ) \ + xmalloc.o xfree.o compat.o + +# The texinfo files which document this library. +DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo +DOCOBJECT = doc/readline.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]* + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h \ + rlstdc.h rlconf.h rltypedefs.h + +########################################################################## + +all: libreadline.a libhistory.a + +libreadline.a: $(OBJECTS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +libhistory.a: $(HISTOBJ) xmalloc.o xfree.o + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o xfree.o + -test -n "$(RANLIB)" && $(RANLIB) $@ + +documentation: force + test -d doc || mkdir doc + -( cd doc && $(MAKE) $(MFLAGS) ) + +# Since tilde.c is shared between readline and bash, make sure we compile +# it with the right flags when it's built as part of readline +tilde.o: tilde.c + rm -f $@ + $(CC) $(CCFLAGS) -DREADLINE_LIBRARY -c $(srcdir)/tilde.c + +force: + +install: + @echo "This version of the readline library should not be installed." + +uninstall: + @echo "This version of the readline library should not be installed." + +TAGS: force + $(ETAGS) $(CSOURCES) $(HSOURCES) + +tags: force + $(CTAGS) $(CSOURCES) $(HSOURCES) + +clean: force + $(RM) $(OBJECTS) *.a + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +distclean maintainer-clean: clean + $(RM) Makefile + $(RM) TAGS tags + +# Dependencies +bind.o: ansi_stdlib.h posixstat.h +bind.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +bind.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +bind.o: history.h rlstdc.h +callback.o: rlconf.h ansi_stdlib.h +callback.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +callback.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +compat.o: ${BUILD_DIR}/config.h +compat.o: rlstdc.h rltypedefs.h +complete.o: ansi_stdlib.h posixdir.h posixstat.h +complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +complete.o: colors.h +display.o: ansi_stdlib.h posixstat.h +display.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +display.o: tcap.h +display.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +display.o: history.h rlstdc.h +funmap.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +funmap.o: rlconf.h ansi_stdlib.h rlstdc.h +funmap.o: ${BUILD_DIR}/config.h +histexpand.o: ansi_stdlib.h +histexpand.o: history.h histlib.h rlstdc.h +histexpand.o: ${BUILD_DIR}/config.h +histfile.o: ansi_stdlib.h +histfile.o: history.h histlib.h rlstdc.h +histfile.o: ${BUILD_DIR}/config.h +history.o: ansi_stdlib.h +history.o: history.h histlib.h rlstdc.h +history.o: ${BUILD_DIR}/config.h +histsearch.o: ansi_stdlib.h +histsearch.o: history.h histlib.h rlstdc.h +histsearch.o: ${BUILD_DIR}/config.h +input.o: ansi_stdlib.h +input.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +input.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +isearch.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +isearch.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +isearch.o: ansi_stdlib.h history.h rlstdc.h +keymaps.o: emacs_keymap.c vi_keymap.c +keymaps.o: keymaps.h rltypedefs.h chardefs.h rlconf.h ansi_stdlib.h +keymaps.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +keymaps.o: ${BUILD_DIR}/config.h rlstdc.h +kill.o: ansi_stdlib.h +kill.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +kill.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +kill.o: history.h rlstdc.h +macro.o: ansi_stdlib.h +macro.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +macro.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +macro.o: history.h rlstdc.h +mbutil.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h rlmbutil.h +mbutil.o: readline.h keymaps.h rltypedefs.h chardefs.h rlstdc.h +misc.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +misc.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +misc.o: history.h rlstdc.h ansi_stdlib.h +nls.o: ansi_stdlib.h +nls.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +nls.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +nls.o: history.h rlstdc.h +parens.o: rlconf.h +parens.o: ${BUILD_DIR}/config.h +parens.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +readline.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +readline.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +readline.o: history.h rlstdc.h +readline.o: posixstat.h ansi_stdlib.h posixjmp.h +rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +rltty.o: rltty.h +rltty.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +savestring.o: ${BUILD_DIR}/config.h +search.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +search.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +search.o: ansi_stdlib.h history.h rlstdc.h +shell.o: ${BUILD_DIR}/config.h ansi_stdlib.h +signals.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +signals.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +signals.o: history.h rlstdc.h +terminal.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +terminal.o: tcap.h +terminal.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +terminal.o: history.h rlstdc.h +text.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +text.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +text.o: history.h rlstdc.h ansi_stdlib.h +rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +tilde.o: ansi_stdlib.h +tilde.o: ${BUILD_DIR}/config.h +tilde.o: tilde.h +undo.o: ansi_stdlib.h +undo.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +undo.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +undo.o: history.h rlstdc.h xmalloc.h +util.o: posixjmp.h ansi_stdlib.h +util.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +util.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +vi_mode.o: history.h ansi_stdlib.h rlstdc.h +xmalloc.o: ${BUILD_DIR}/config.h ansi_stdlib.h +xfree.o: ${BUILD_DIR}/config.h ansi_stdlib.h + +colors.o: ${BUILD_DIR}/config.h colors.h +colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +colors.o: rlconf.h +colors.o: ansi_stdlib.h posixstat.h +parse-colors.o: ${BUILD_DIR}/config.h colors.h parse-colors.h +parse-colors.o: rldefs.h rlconf.h +parse-colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h + +bind.o: rlshell.h +histfile.o: rlshell.h +nls.o: rlshell.h +readline.o: rlshell.h +shell.o: rlshell.h +terminal.o: rlshell.h +histexpand.o: rlshell.h + +bind.o: rlprivate.h +callback.o: rlprivate.h +complete.o: rlprivate.h +display.o: rlprivate.h +input.o: rlprivate.h +isearch.o: rlprivate.h +kill.o: rlprivate.h +macro.o: rlprivate.h +mbutil.o: rlprivate.h +misc.o: rlprivate.h +nls.o: rlprivate.h +parens.o: rlprivate.h +readline.o: rlprivate.h +rltty.o: rlprivate.h +search.o: rlprivate.h +signals.o: rlprivate.h +terminal.o: rlprivate.h +text.o: rlprivate.h +undo.o: rlprivate.h +util.o: rlprivate.h +vi_mode.o: rlprivate.h +colors.o: rlprivate.h +parse-colors.o: rlprivate.h + +bind.o: xmalloc.h +complete.o: xmalloc.h +display.o: xmalloc.h +funmap.o: xmalloc.h +histexpand.o: xmalloc.h +histfile.o: xmalloc.h +history.o: xmalloc.h +input.o: xmalloc.h +isearch.o: xmalloc.h +keymaps.o: xmalloc.h +kill.o: xmalloc.h +macro.o: xmalloc.h +mbutil.o: xmalloc.h +misc.o: xmalloc.h +readline.o: xmalloc.h +savestring.o: xmalloc.h +search.o: xmalloc.h +shell.o: xmalloc.h +terminal.o: xmalloc.h +text.o: xmalloc.h +tilde.o: xmalloc.h +undo.o: xmalloc.h +util.o: xmalloc.h +vi_mode.o: xmalloc.h +xfree.o: xmalloc.h +xmalloc.o: xmalloc.h +colors.o: xmalloc.h +parse-colors.o: xmalloc.h + +complete.o: rlmbutil.h +display.o: rlmbutil.h +histexpand.o: rlmbutil.h +input.o: rlmbutil.h +isearch.o: rlmbutil.h +mbutil.o: rlmbutil.h +misc.o: rlmbutil.h +readline.o: rlmbutil.h +search.o: rlmbutil.h +text.o: rlmbutil.h +vi_mode.o: rlmbutil.h +colors.o: rlmbutil.h +parse-colors.o: rlmbutil.h + +# Rules for deficient makes, like SunOS and Solaris +bind.o: bind.c +callback.o: callback.c +compat.o: compat.c +complete.o: complete.c +display.o: display.c +funmap.o: funmap.c +input.o: input.c +isearch.o: isearch.c +keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c +kill.o: kill.c +macro.o: macro.c +mbutil.o: mbutil.c +misc.o: misc.c +nls.o: nls.c +parens.o: parens.c +readline.o: readline.c +rltty.o: rltty.c +savestring.o: savestring.c +search.o: search.c +shell.o: shell.c +signals.o: signals.c +terminal.o: terminal.c +text.o: text.c +tilde.o: tilde.c +undo.o: undo.c +util.o: util.c +vi_mode.o: vi_mode.c +xfree.o: xfree.c +xmalloc.o: xmalloc.c + +colors.o: colors.c +parse-colors.o: parse-colors.c + +histexpand.o: histexpand.c +histfile.o: histfile.c +history.o: history.c +histsearch.o: histsearch.c diff --git a/utshell-0.5.0/lib/readline/README b/utshell-0.5.0/lib/readline/README new file mode 100644 index 00000000..131471ca --- /dev/null +++ b/utshell-0.5.0/lib/readline/README @@ -0,0 +1,6 @@ +This is the distribution of the Gnu Readline library. See the file +STANDALONE for a description of the #defines that can be passed via +the makefile to build readline on different systems. + +The file rlconf.h contains defines that enable and disable certain +readline features. diff --git a/utshell-0.5.0/lib/readline/STANDALONE b/utshell-0.5.0/lib/readline/STANDALONE new file mode 100644 index 00000000..c6b5cbd3 --- /dev/null +++ b/utshell-0.5.0/lib/readline/STANDALONE @@ -0,0 +1,2 @@ +This is not to be built as a standalone library to be installed in some +public place; get the full readline distribution instead. diff --git a/utshell-0.5.0/lib/readline/ansi_stdlib.h b/utshell-0.5.0/lib/readline/ansi_stdlib.h new file mode 100644 index 00000000..7dc2ee0c --- /dev/null +++ b/utshell-0.5.0/lib/readline/ansi_stdlib.h @@ -0,0 +1,54 @@ +/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */ +/* A minimal stdlib.h containing extern declarations for those functions + that bash uses. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_STDLIB_H_) +#define _STDLIB_H_ 1 + +/* String conversion functions. */ +extern int atoi (); + +extern double atof (); +extern double strtod (); + +/* Memory allocation functions. */ +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +extern PTR_T malloc (); +extern PTR_T realloc (); +extern void free (); + +/* Other miscellaneous functions. */ +extern void abort (); +extern void exit (); +extern char *getenv (); +extern void qsort (); + +#endif /* _STDLIB_H */ diff --git a/utshell-0.5.0/lib/readline/bind.c b/utshell-0.5.0/lib/readline/bind.c new file mode 100644 index 00000000..87596dce --- /dev/null +++ b/utshell-0.5.0/lib/readline/bind.c @@ -0,0 +1,2970 @@ +/* bind.c -- key binding and startup file support for the readline library. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (__TANDEM) +# include +#endif + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "posixstat.h" + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +/* Variables exported by this file. */ +Keymap rl_binding_keymap; + +static int _rl_skip_to_delim PARAMS((char *, int, int)); + +#if defined (USE_VARARGS) && defined (PREFER_STDARG) +static void _rl_init_file_error (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#else +static void _rl_init_file_error (); +#endif + +static rl_command_func_t *_rl_function_of_keyseq_internal PARAMS((const char *, size_t, Keymap, int *)); + +static char *_rl_read_file PARAMS((char *, size_t *)); +static int _rl_read_init_file PARAMS((const char *, int)); +static int glean_key_from_name PARAMS((char *)); + +static int find_boolean_var PARAMS((const char *)); +static int find_string_var PARAMS((const char *)); + +static const char *boolean_varname PARAMS((int)); +static const char *string_varname PARAMS((int)); + +static char *_rl_get_string_variable_value PARAMS((const char *)); +static int substring_member_of_array PARAMS((const char *, const char * const *)); + +static int _rl_get_keymap_by_name PARAMS((const char *)); +static int _rl_get_keymap_by_map PARAMS((Keymap)); + +static int currently_reading_init_file; + +/* used only in this file */ +static int _rl_prefer_visible_bell = 1; + +#define OP_EQ 1 +#define OP_NE 2 +#define OP_GT 3 +#define OP_GE 4 +#define OP_LT 5 +#define OP_LE 6 + +#define OPSTART(c) ((c) == '=' || (c) == '!' || (c) == '<' || (c) == '>') +#define CMPSTART(c) ((c) == '=' || (c) == '!') + +/* **************************************************************** */ +/* */ +/* Binding keys */ +/* */ +/* **************************************************************** */ + +/* rl_add_defun (char *name, rl_command_func_t *function, int key) + Add NAME to the list of named functions. Make FUNCTION be the function + that gets called. If KEY is not -1, then bind it. */ +int +rl_add_defun (const char *name, rl_command_func_t *function, int key) +{ + if (key != -1) + rl_bind_key (key, function); + rl_add_funmap_entry (name, function); + return 0; +} + +/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */ +int +rl_bind_key (int key, rl_command_func_t *function) +{ + char keyseq[4]; + int l; + + if (key < 0 || key > largest_char) + return (key); + + /* Want to make this a multi-character key sequence with an ESC prefix */ + if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) + { + if (_rl_keymap[ESC].type == ISKMAP) + { + Keymap escmap; + + escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC); + key = UNMETA (key); + escmap[key].type = ISFUNC; + escmap[key].function = function; + return (0); + } + + /* Otherwise, let's just let rl_generic_bind handle the key sequence. + We start it off with ESC here and let the code below add the rest + of the sequence. */ + keyseq[0] = ESC; + l = 1; + key = UNMETA(key); + goto bind_keyseq; + } + + /* If it's bound to a function or macro, just overwrite. Otherwise we have + to treat it as a key sequence so rl_generic_bind handles shadow keymaps + for us. If we are binding '\' or \C-@ (NUL) make sure to escape it so + it makes it through the call to rl_translate_keyseq. */ + if (_rl_keymap[key].type != ISKMAP) + { + if (_rl_keymap[key].type == ISMACR) + xfree ((char *)_rl_keymap[key].function); + _rl_keymap[key].type = ISFUNC; + _rl_keymap[key].function = function; + } + else + { + l = 0; +bind_keyseq: + if (key == '\\') + { + keyseq[l++] = '\\'; + keyseq[l++] = '\\'; + } + else if (key == '\0') + { + keyseq[l++] = '\\'; + keyseq[l++] = '0'; + } + else + keyseq[l++] = key; + keyseq[l] = '\0'; + rl_bind_keyseq (keyseq, function); + } + rl_binding_keymap = _rl_keymap; + return (0); +} + +/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid + KEY. */ +int +rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map) +{ + int result; + Keymap oldmap; + + oldmap = _rl_keymap; + _rl_keymap = map; + result = rl_bind_key (key, function); + _rl_keymap = oldmap; + return (result); +} + +/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right + now, this is always used to attempt to bind the arrow keys. */ +int +rl_bind_key_if_unbound_in_map (int key, rl_command_func_t *default_func, Keymap kmap) +{ + char *keyseq; + + keyseq = rl_untranslate_keyseq ((unsigned char)key); + return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)); +} + +int +rl_bind_key_if_unbound (int key, rl_command_func_t *default_func) +{ + char *keyseq; + + keyseq = rl_untranslate_keyseq ((unsigned char)key); + return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); +} + +/* Make KEY do nothing in the currently selected keymap. + Returns non-zero in case of error. This is not the same as self-insert; + this makes it a dead key. */ +int +rl_unbind_key (int key) +{ + return (rl_bind_key (key, (rl_command_func_t *)NULL)); +} + +/* Make KEY do nothing in MAP. Returns non-zero in case of error. */ +int +rl_unbind_key_in_map (int key, Keymap map) +{ + return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map)); +} + +/* Unbind all keys bound to FUNCTION in MAP. */ +int +rl_unbind_function_in_map (rl_command_func_t *func, Keymap map) +{ + register int i, rval; + + for (i = rval = 0; i < KEYMAP_SIZE; i++) + { + if (map[i].type == ISFUNC && map[i].function == func) + { + map[i].function = (rl_command_func_t *)NULL; + rval = 1; + } + else if (map[i].type == ISKMAP) /* TAG:readline-8.1 */ + { + int r; + r = rl_unbind_function_in_map (func, FUNCTION_TO_KEYMAP (map, i)); + if (r == 1) + rval = 1; + } + } + return rval; +} + +/* Unbind all keys bound to COMMAND, which is a bindable command name, in MAP */ +int +rl_unbind_command_in_map (const char *command, Keymap map) +{ + rl_command_func_t *func; + + func = rl_named_function (command); + if (func == 0) + return 0; + return (rl_unbind_function_in_map (func, map)); +} + +/* Bind the key sequence represented by the string KEYSEQ to + FUNCTION, starting in the current keymap. This makes new + keymaps as necessary. */ +int +rl_bind_keyseq (const char *keyseq, rl_command_func_t *function) +{ + return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap)); +} + +/* Bind the key sequence represented by the string KEYSEQ to + FUNCTION. This makes new keymaps as necessary. The initial + place to do bindings is in MAP. */ +int +rl_bind_keyseq_in_map (const char *keyseq, rl_command_func_t *function, Keymap map) +{ + return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); +} + +/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */ +int +rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map) +{ + return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); +} + +/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right + now, this is always used to attempt to bind the arrow keys, hence the + check for rl_vi_movement_mode. */ +int +rl_bind_keyseq_if_unbound_in_map (const char *keyseq, rl_command_func_t *default_func, Keymap kmap) +{ + rl_command_func_t *func; + char *keys; + int keys_len; + + if (keyseq) + { + /* Handle key sequences that require translations and `raw' ones that + don't. This might be a problem with backslashes. */ + keys = (char *)xmalloc (1 + (2 * strlen (keyseq))); + if (rl_translate_keyseq (keyseq, keys, &keys_len)) + { + xfree (keys); + return -1; + } + func = rl_function_of_keyseq_len (keys, keys_len, kmap, (int *)NULL); + xfree (keys); +#if defined (VI_MODE) + if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode) +#else + if (!func || func == rl_do_lowercase_version) +#endif + return (rl_bind_keyseq_in_map (keyseq, default_func, kmap)); + else + return 1; + } + return 0; +} + +int +rl_bind_keyseq_if_unbound (const char *keyseq, rl_command_func_t *default_func) +{ + return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); +} + +/* Bind the key sequence represented by the string KEYSEQ to + the string of characters MACRO. This makes new keymaps as + necessary. The initial place to do bindings is in MAP. */ +int +rl_macro_bind (const char *keyseq, const char *macro, Keymap map) +{ + char *macro_keys; + int macro_keys_len; + + macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1); + + if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len)) + { + xfree (macro_keys); + return -1; + } + rl_generic_bind (ISMACR, keyseq, macro_keys, map); + return 0; +} + +/* Bind the key sequence represented by the string KEYSEQ to + the arbitrary pointer DATA. TYPE says what kind of data is + pointed to by DATA, right now this can be a function (ISFUNC), + a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps + as necessary. The initial place to do bindings is in MAP. */ +int +rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) +{ + char *keys; + int keys_len, prevkey, ic; + register int i; + KEYMAP_ENTRY k; + Keymap prevmap; + + k.function = 0; + + /* If no keys to bind to, exit right away. */ + if (keyseq == 0 || *keyseq == 0) + { + if (type == ISMACR) + xfree (data); + return -1; + } + + keys = (char *)xmalloc (1 + (2 * strlen (keyseq))); + + /* Translate the ASCII representation of KEYSEQ into an array of + characters. Stuff the characters into KEYS, and the length of + KEYS into KEYS_LEN. */ + if (rl_translate_keyseq (keyseq, keys, &keys_len)) + { + xfree (keys); + return -1; + } + + prevmap = map; + prevkey = keys[0]; + + /* Bind keys, making new keymaps as necessary. */ + for (i = 0; i < keys_len; i++) + { + unsigned char uc = keys[i]; + + if (i > 0) + prevkey = ic; + + ic = uc; + if (ic < 0 || ic >= KEYMAP_SIZE) + { + xfree (keys); + return -1; + } + + /* We now rely on rl_translate_keyseq to do this conversion, so this + check is superfluous. */ +#if 0 + if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) + { + ic = UNMETA (ic); + if (map[ESC].type == ISKMAP) + { + prevmap = map; + map = FUNCTION_TO_KEYMAP (map, ESC); + } + } +#endif + + if ((i + 1) < keys_len) + { + if (map[ic].type != ISKMAP) + { + /* We allow subsequences of keys. If a keymap is being + created that will `shadow' an existing function or macro + key binding, we save that keybinding into the ANYOTHERKEY + index in the new map. The dispatch code will look there + to find the function to execute if the subsequence is not + matched. ANYOTHERKEY was chosen to be greater than + UCHAR_MAX. */ + k = map[ic]; + + map[ic].type = ISKMAP; + map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); + } + prevmap = map; + map = FUNCTION_TO_KEYMAP (map, ic); + /* The dispatch code will return this function if no matching + key sequence is found in the keymap. This (with a little + help from the dispatch code in readline.c) allows `a' to be + mapped to something, `abc' to be mapped to something else, + and the function bound to `a' to be executed when the user + types `abx', leaving `bx' in the input queue. */ + if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR)) + { + map[ANYOTHERKEY] = k; + k.function = 0; + } + } + else + { + if (map[ic].type == ISKMAP) + { + prevmap = map; + map = FUNCTION_TO_KEYMAP (map, ic); + ic = ANYOTHERKEY; + /* If we're trying to override a keymap with a null function + (e.g., trying to unbind it), we can't use a null pointer + here because that's indistinguishable from having not been + overridden. We use a special bindable function that does + nothing. */ + if (type == ISFUNC && data == 0) + data = (char *)_rl_null_function; + } + if (map[ic].type == ISMACR) + xfree ((char *)map[ic].function); + + map[ic].function = KEYMAP_TO_FUNCTION (data); + map[ic].type = type; + } + + rl_binding_keymap = map; + + } + + /* If we unbound a key (type == ISFUNC, data == 0), and the prev keymap + points to the keymap where we unbound the key (sanity check), and the + current binding keymap is empty (rl_empty_keymap() returns non-zero), + and the binding keymap has ANYOTHERKEY set with type == ISFUNC + (overridden function), delete the now-empty keymap, take the previously- + overridden function and remove the override. */ + /* Right now, this only works one level back. */ + if (type == ISFUNC && data == 0 && + prevmap[prevkey].type == ISKMAP && + (FUNCTION_TO_KEYMAP(prevmap, prevkey) == rl_binding_keymap) && + rl_binding_keymap[ANYOTHERKEY].type == ISFUNC && + rl_empty_keymap (rl_binding_keymap)) + { + prevmap[prevkey].type = rl_binding_keymap[ANYOTHERKEY].type; + prevmap[prevkey].function = rl_binding_keymap[ANYOTHERKEY].function; + rl_discard_keymap (rl_binding_keymap); + rl_binding_keymap = prevmap; + } + + xfree (keys); + return 0; +} + +/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, + an array of characters. LEN gets the final length of ARRAY. Return + non-zero if there was an error parsing SEQ. */ +int +rl_translate_keyseq (const char *seq, char *array, int *len) +{ + register int i, l, temp; + int has_control, has_meta; + unsigned char c; + + has_control = 0; + has_meta = 0; + + /* When there are incomplete prefixes \C- or \M- (has_control || has_meta) + without base character at the end of SEQ, they are processed as the + prefixes for '\0'. + */ + for (i = l = 0; (c = seq[i]) || has_control || has_meta; i++) + { + /* Only backslashes followed by a non-null character are handled + specially. Trailing backslash (backslash followed by '\0') is + processed as a normal character. + */ + if (c == '\\' && seq[i + 1] != '\0') + { + c = seq[++i]; + + /* Handle \C- and \M- prefixes. */ + if (c == 'C' && seq[i + 1] == '-') + { + i++; + has_control = 1; + continue; + } + else if (c == 'M' && seq[i + 1] == '-') + { + i++; + has_meta = 1; + continue; + } + + /* Translate other backslash-escaped characters. These are the + same escape sequences that bash's `echo' and `printf' builtins + handle, with the addition of \d -> RUBOUT. A backslash + preceding a character that is not special is stripped. */ + switch (c) + { + case 'a': + c = '\007'; + break; + case 'b': + c = '\b'; + break; + case 'd': + c = RUBOUT; /* readline-specific */ + break; + case 'e': + c = ESC; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = NEWLINE; + break; + case 'r': + c = RETURN; + break; + case 't': + c = TAB; + break; + case 'v': + c = 0x0B; + break; + case '\\': + c = '\\'; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + i++; + for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++) + c = (c * 8) + OCTVALUE (seq[i]); + i--; /* auto-increment in for loop */ + c &= largest_char; + break; + case 'x': + i++; + for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++) + c = (c * 16) + HEXVALUE (seq[i]); + if (temp == 2) + c = 'x'; + i--; /* auto-increment in for loop */ + c &= largest_char; + break; + default: /* backslashes before non-special chars just add the char */ + c &= largest_char; + break; /* the backslash is stripped */ + } + } + + /* Process \C- and \M- flags */ + if (has_control) + { + /* Special treatment for C-? */ + c = (c == '?') ? RUBOUT : CTRL (_rl_to_upper (c)); + has_control = 0; + } + if (has_meta) + { + c = META (c); + has_meta = 0; + } + + /* If convert-meta is turned on, convert a meta char to a key sequence */ + if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii) + { + array[l++] = ESC; /* ESC is meta-prefix */ + array[l++] = UNMETA (c); + } + else + array[l++] = (c); + + /* Null characters may be processed for incomplete prefixes at the end of + sequence */ + if (seq[i] == '\0') + break; + } + + *len = l; + array[l] = '\0'; + return (0); +} + +static int +_rl_isescape (int c) +{ + switch (c) + { + case '\007': + case '\b': + case '\f': + case '\n': + case '\r': + case TAB: + case 0x0b: return (1); + default: return (0); + } +} + +static int +_rl_escchar (int c) +{ + switch (c) + { + case '\007': return ('a'); + case '\b': return ('b'); + case '\f': return ('f'); + case '\n': return ('n'); + case '\r': return ('r'); + case TAB: return ('t'); + case 0x0b: return ('v'); + default: return (c); + } +} + +char * +rl_untranslate_keyseq (int seq) +{ + static char kseq[16]; + int i, c; + + i = 0; + c = seq; + if (META_CHAR (c)) + { + kseq[i++] = '\\'; + kseq[i++] = 'M'; + kseq[i++] = '-'; + c = UNMETA (c); + } + else if (c == ESC) + { + kseq[i++] = '\\'; + c = 'e'; + } + else if (CTRL_CHAR (c)) + { + kseq[i++] = '\\'; + kseq[i++] = 'C'; + kseq[i++] = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + else if (c == RUBOUT) + { + kseq[i++] = '\\'; + kseq[i++] = 'C'; + kseq[i++] = '-'; + c = '?'; + } + + if (c == ESC) + { + kseq[i++] = '\\'; + c = 'e'; + } + else if (c == '\\' || c == '"') + { + kseq[i++] = '\\'; + } + + kseq[i++] = (unsigned char) c; + kseq[i] = '\0'; + return kseq; +} + +char * +_rl_untranslate_macro_value (char *seq, int use_escapes) +{ + char *ret, *r, *s; + int c; + + r = ret = (char *)xmalloc (7 * strlen (seq) + 1); + for (s = seq; *s; s++) + { + c = *s; + if (META_CHAR (c)) + { + *r++ = '\\'; + *r++ = 'M'; + *r++ = '-'; + c = UNMETA (c); + } + else if (c == ESC) + { + *r++ = '\\'; + c = 'e'; + } + else if (CTRL_CHAR (c)) + { + *r++ = '\\'; + if (use_escapes && _rl_isescape (c)) + c = _rl_escchar (c); + else + { + *r++ = 'C'; + *r++ = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + } + else if (c == RUBOUT) + { + *r++ = '\\'; + *r++ = 'C'; + *r++ = '-'; + c = '?'; + } + + if (c == ESC) + { + *r++ = '\\'; + c = 'e'; + } + else if (c == '\\' || c == '"') + *r++ = '\\'; + + *r++ = (unsigned char)c; + } + *r = '\0'; + return ret; +} + +/* Return a pointer to the function that STRING represents. + If STRING doesn't have a matching function, then a NULL pointer + is returned. The string match is case-insensitive. */ +rl_command_func_t * +rl_named_function (const char *string) +{ + register int i; + + rl_initialize_funmap (); + + for (i = 0; funmap[i]; i++) + if (_rl_stricmp (funmap[i]->name, string) == 0) + return (funmap[i]->function); + return ((rl_command_func_t *)NULL); +} + +/* Return the function (or macro) definition which would be invoked via + KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is + used. TYPE, if non-NULL, is a pointer to an int which will receive the + type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), + or ISMACR (macro). */ +static rl_command_func_t * +_rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int *type) +{ + register int i; + + if (map == 0) + map = _rl_keymap; + + for (i = 0; keyseq && i < len; i++) + { + unsigned char ic = keyseq[i]; + + if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) + { + if (map[ESC].type == ISKMAP) + { + map = FUNCTION_TO_KEYMAP (map, ESC); + ic = UNMETA (ic); + } + /* XXX - should we just return NULL here, since this obviously + doesn't match? */ + else + { + if (type) + *type = map[ESC].type; + + return (map[ESC].function); + } + } + + if (map[ic].type == ISKMAP) + { + /* If this is the last key in the key sequence, return the + map. */ + if (i + 1 == len) + { + if (type) + *type = ISKMAP; + + return (map[ic].function); + } + else + map = FUNCTION_TO_KEYMAP (map, ic); + } + /* If we're not at the end of the key sequence, and the current key + is bound to something other than a keymap, then the entire key + sequence is not bound. */ + else if (map[ic].type != ISKMAP && i+1 < len) + return ((rl_command_func_t *)NULL); + else /* map[ic].type != ISKMAP && i+1 == len */ + { + if (type) + *type = map[ic].type; + + return (map[ic].function); + } + } + return ((rl_command_func_t *) NULL); +} + +rl_command_func_t * +rl_function_of_keyseq (const char *keyseq, Keymap map, int *type) +{ + return _rl_function_of_keyseq_internal (keyseq, strlen (keyseq), map, type); +} + +rl_command_func_t * +rl_function_of_keyseq_len (const char *keyseq, size_t len, Keymap map, int *type) +{ + return _rl_function_of_keyseq_internal (keyseq, len, map, type); +} + +/* The last key bindings file read. */ +static char *last_readline_init_file = (char *)NULL; + +/* The file we're currently reading key bindings from. */ +static const char *current_readline_init_file; +static int current_readline_init_include_level; +static int current_readline_init_lineno; + +/* Read FILENAME into a locally-allocated buffer and return the buffer. + The size of the buffer is returned in *SIZEP. Returns NULL if any + errors were encountered. */ +static char * +_rl_read_file (char *filename, size_t *sizep) +{ + struct stat finfo; + size_t file_size; + char *buffer; + int i, file; + + file = -1; + if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0)) + { + if (file >= 0) + close (file); + return ((char *)NULL); + } + + file_size = (size_t)finfo.st_size; + + /* check for overflow on very large files */ + if (file_size != finfo.st_size || file_size + 1 < file_size) + { + if (file >= 0) + close (file); +#if defined (EFBIG) + errno = EFBIG; +#endif + return ((char *)NULL); + } + + /* Read the file into BUFFER. */ + buffer = (char *)xmalloc (file_size + 1); + i = read (file, buffer, file_size); + close (file); + + if (i < 0) + { + xfree (buffer); + return ((char *)NULL); + } + + RL_CHECK_SIGNALS (); + + buffer[i] = '\0'; + if (sizep) + *sizep = i; + + return (buffer); +} + +/* Re-read the current keybindings file. */ +int +rl_re_read_init_file (int count, int ignore) +{ + int r; + r = rl_read_init_file ((const char *)NULL); + rl_set_keymap_from_edit_mode (); + return r; +} + +/* Do key bindings from a file. If FILENAME is NULL it defaults + to the first non-null filename from this list: + 1. the filename used for the previous call + 2. the value of the shell variable `INPUTRC' + 3. ~/.inputrc + 4. /etc/inputrc + If the file existed and could be opened and read, 0 is returned, + otherwise errno is returned. */ +int +rl_read_init_file (const char *filename) +{ + /* Default the filename. */ + if (filename == 0) + filename = last_readline_init_file; + if (filename == 0) + filename = sh_get_env_value ("INPUTRC"); + if (filename == 0 || *filename == 0) + { + filename = DEFAULT_INPUTRC; + /* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */ + if (_rl_read_init_file (filename, 0) == 0) + return 0; + filename = SYS_INPUTRC; + } + +#if defined (__MSDOS__) + if (_rl_read_init_file (filename, 0) == 0) + return 0; + filename = "~/_inputrc"; +#endif + return (_rl_read_init_file (filename, 0)); +} + +static int +_rl_read_init_file (const char *filename, int include_level) +{ + register int i; + char *buffer, *openname, *line, *end; + size_t file_size; + + current_readline_init_file = filename; + current_readline_init_include_level = include_level; + + openname = tilde_expand (filename); + buffer = _rl_read_file (openname, &file_size); + xfree (openname); + + RL_CHECK_SIGNALS (); + if (buffer == 0) + return (errno); + + if (include_level == 0 && filename != last_readline_init_file) + { + FREE (last_readline_init_file); + last_readline_init_file = savestring (filename); + } + + currently_reading_init_file = 1; + + /* Loop over the lines in the file. Lines that start with `#' are + comments; all other lines are commands for readline initialization. */ + current_readline_init_lineno = 1; + line = buffer; + end = buffer + file_size; + while (line < end) + { + /* Find the end of this line. */ + for (i = 0; line + i != end && line[i] != '\n'; i++); + +#if defined (__CYGWIN__) + /* ``Be liberal in what you accept.'' */ + if (line[i] == '\n' && line[i-1] == '\r') + line[i - 1] = '\0'; +#endif + + /* Mark end of line. */ + line[i] = '\0'; + + /* Skip leading whitespace. */ + while (*line && whitespace (*line)) + { + line++; + i--; + } + + /* If the line is not a comment, then parse it. */ + if (*line && *line != '#') + rl_parse_and_bind (line); + + /* Move to the next line. */ + line += i + 1; + current_readline_init_lineno++; + } + + xfree (buffer); + currently_reading_init_file = 0; + return (0); +} + +static void +#if defined (PREFER_STDARG) +_rl_init_file_error (const char *format, ...) +#else +_rl_init_file_error (va_alist) + va_dcl +#endif +{ + va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + + fprintf (stderr, "readline: "); + if (currently_reading_init_file) + fprintf (stderr, "%s: line %d: ", current_readline_init_file, + current_readline_init_lineno); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + fflush (stderr); + + va_end (args); +} + +/* **************************************************************** */ +/* */ +/* Parser Helper Functions */ +/* */ +/* **************************************************************** */ + +static int +parse_comparison_op (s, indp) + const char *s; + int *indp; +{ + int i, peekc, op; + + if (OPSTART (s[*indp]) == 0) + return -1; + i = *indp; + peekc = s[i] ? s[i+1] : 0; + op = -1; + + if (s[i] == '=') + { + op = OP_EQ; + if (peekc == '=') + i++; + i++; + } + else if (s[i] == '!' && peekc == '=') + { + op = OP_NE; + i += 2; + } + else if (s[i] == '<' && peekc == '=') + { + op = OP_LE; + i += 2; + } + else if (s[i] == '>' && peekc == '=') + { + op = OP_GE; + i += 2; + } + else if (s[i] == '<') + { + op = OP_LT; + i += 1; + } + else if (s[i] == '>') + { + op = OP_GT; + i += 1; + } + + *indp = i; + return op; +} + +/* **************************************************************** */ +/* */ +/* Parser Directives */ +/* */ +/* **************************************************************** */ + +typedef int _rl_parser_func_t PARAMS((char *)); + +/* Things that mean `Control'. */ +const char * const _rl_possible_control_prefixes[] = { + "Control-", "C-", "CTRL-", (const char *)NULL +}; + +const char * const _rl_possible_meta_prefixes[] = { + "Meta", "M-", (const char *)NULL +}; + +/* Conditionals. */ + +/* Calling programs set this to have their argv[0]. */ +const char *rl_readline_name = "other"; + +/* Stack of previous values of parsing_conditionalized_out. */ +static unsigned char *if_stack = (unsigned char *)NULL; +static int if_stack_depth; +static int if_stack_size; + +/* Push _rl_parsing_conditionalized_out, and set parser state based + on ARGS. */ +static int +parser_if (char *args) +{ + int i, llen, boolvar, strvar; + + boolvar = strvar = -1; + + /* Push parser state. */ + if (if_stack_depth + 1 >= if_stack_size) + { + if (!if_stack) + if_stack = (unsigned char *)xmalloc (if_stack_size = 20); + else + if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); + } + if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out; + + /* If parsing is turned off, then nothing can turn it back on except + for finding the matching endif. In that case, return right now. */ + if (_rl_parsing_conditionalized_out) + return 0; + + llen = strlen (args); + + /* Isolate first argument. */ + for (i = 0; args[i] && !whitespace (args[i]); i++); + + if (args[i]) + args[i++] = '\0'; + + /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this + isn't term=foo, or mode=emacs, then check to see if the first + word in ARGS is the same as the value stored in rl_readline_name. */ + if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0) + { + char *tem, *tname; + + /* Terminals like "aaa-60" are equivalent to "aaa". */ + tname = savestring (rl_terminal_name); + tem = strchr (tname, '-'); + if (tem) + *tem = '\0'; + + /* Test the `long' and `short' forms of the terminal name so that + if someone has a `sun-cmd' and does not want to have bindings + that will be executed if the terminal is a `sun', they can put + `$if term=sun-cmd' into their .inputrc. */ + _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && + _rl_stricmp (args + 5, rl_terminal_name); + xfree (tname); + } +#if defined (VI_MODE) + else if (_rl_strnicmp (args, "mode=", 5) == 0) + { + int mode; + + if (_rl_stricmp (args + 5, "emacs") == 0) + mode = emacs_mode; + else if (_rl_stricmp (args + 5, "vi") == 0) + mode = vi_mode; + else + mode = no_mode; + + _rl_parsing_conditionalized_out = mode != rl_editing_mode; + } +#endif /* VI_MODE */ + else if (_rl_strnicmp (args, "version", 7) == 0) + { + int rlversion, versionarg, op, previ, major, minor; + + _rl_parsing_conditionalized_out = 1; + rlversion = RL_VERSION_MAJOR*10 + RL_VERSION_MINOR; + /* if "version" is separated from the operator by whitespace, or the + operand is separated from the operator by whitespace, restore it. + We're more liberal with allowed whitespace for this variable. */ + if (i > 0 && i <= llen && args[i-1] == '\0') + args[i-1] = ' '; + args[llen] = '\0'; /* just in case */ + for (i = 7; whitespace (args[i]); i++) + ; + if (OPSTART(args[i]) == 0) + { + _rl_init_file_error ("comparison operator expected, found `%s'", args[i] ? args + i : "end-of-line"); + return 0; + } + previ = i; + op = parse_comparison_op (args, &i); + if (op <= 0) + { + _rl_init_file_error ("comparison operator expected, found `%s'", args+previ); + return 0; + } + for ( ; args[i] && whitespace (args[i]); i++) + ; + if (args[i] == 0 || _rl_digit_p (args[i]) == 0) + { + _rl_init_file_error ("numeric argument expected, found `%s'", args+i); + return 0; + } + major = minor = 0; + previ = i; + for ( ; args[i] && _rl_digit_p (args[i]); i++) + major = major*10 + _rl_digit_value (args[i]); + if (args[i] == '.') + { + if (args[i + 1] && _rl_digit_p (args [i + 1]) == 0) + { + _rl_init_file_error ("numeric argument expected, found `%s'", args+previ); + return 0; + } + for (++i; args[i] && _rl_digit_p (args[i]); i++) + minor = minor*10 + _rl_digit_value (args[i]); + } + /* optional - check for trailing garbage on the line, allow whitespace + and a trailing comment */ + previ = i; + for ( ; args[i] && whitespace (args[i]); i++) + ; + if (args[i] && args[i] != '#') + { + _rl_init_file_error ("trailing garbage on line: `%s'", args+previ); + return 0; + } + versionarg = major*10 + minor; + + switch (op) + { + case OP_EQ: + _rl_parsing_conditionalized_out = rlversion == versionarg; + break; + case OP_NE: + _rl_parsing_conditionalized_out = rlversion != versionarg; + break; + case OP_GT: + _rl_parsing_conditionalized_out = rlversion > versionarg; + break; + case OP_GE: + _rl_parsing_conditionalized_out = rlversion >= versionarg; + break; + case OP_LT: + _rl_parsing_conditionalized_out = rlversion < versionarg; + break; + case OP_LE: + _rl_parsing_conditionalized_out = rlversion <= versionarg; + break; + } + } + /* Check to see if the first word in ARGS is the same as the + value stored in rl_readline_name. */ + else if (_rl_stricmp (args, rl_readline_name) == 0) + _rl_parsing_conditionalized_out = 0; + else if ((boolvar = find_boolean_var (args)) >= 0 || (strvar = find_string_var (args)) >= 0) + { + int op, previ; + size_t vlen; + const char *vname; + char *valuearg, *vval, prevc; + + _rl_parsing_conditionalized_out = 1; + vname = (boolvar >= 0) ? boolean_varname (boolvar) : string_varname (strvar); + vlen = strlen (vname); + if (i > 0 && i <= llen && args[i-1] == '\0') + args[i-1] = ' '; + args[llen] = '\0'; /* just in case */ + for (i = vlen; whitespace (args[i]); i++) + ; + if (CMPSTART(args[i]) == 0) + { + _rl_init_file_error ("equality comparison operator expected, found `%s'", args[i] ? args + i : "end-of-line"); + return 0; + } + previ = i; + op = parse_comparison_op (args, &i); + if (op != OP_EQ && op != OP_NE) + { + _rl_init_file_error ("equality comparison operator expected, found `%s'", args+previ); + return 0; + } + for ( ; args[i] && whitespace (args[i]); i++) + ; + if (args[i] == 0) + { + _rl_init_file_error ("argument expected, found `%s'", args+i); + return 0; + } + previ = i; + valuearg = args + i; + for ( ; args[i] && whitespace (args[i]) == 0; i++) + ; + prevc = args[i]; + args[i] = '\0'; /* null-terminate valuearg */ + vval = rl_variable_value (vname); + if (op == OP_EQ) + _rl_parsing_conditionalized_out = _rl_stricmp (vval, valuearg) != 0; + else if (op == OP_NE) + _rl_parsing_conditionalized_out = _rl_stricmp (vval, valuearg) == 0; + args[i] = prevc; + } + else + _rl_parsing_conditionalized_out = 1; + return 0; +} + +/* Invert the current parser state if there is anything on the stack. */ +static int +parser_else (char *args) +{ + register int i; + + if (if_stack_depth == 0) + { + _rl_init_file_error ("$else found without matching $if"); + return 0; + } + +#if 0 + /* Check the previous (n - 1) levels of the stack to make sure that + we haven't previously turned off parsing. */ + for (i = 0; i < if_stack_depth - 1; i++) +#else + /* Check the previous (n) levels of the stack to make sure that + we haven't previously turned off parsing. */ + for (i = 0; i < if_stack_depth; i++) +#endif + if (if_stack[i] == 1) + return 0; + + /* Invert the state of parsing if at top level. */ + _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out; + return 0; +} + +/* Terminate a conditional, popping the value of + _rl_parsing_conditionalized_out from the stack. */ +static int +parser_endif (char *args) +{ + if (if_stack_depth) + _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; + else + _rl_init_file_error ("$endif without matching $if"); + return 0; +} + +static int +parser_include (char *args) +{ + const char *old_init_file; + char *e; + int old_line_number, old_include_level, r; + + if (_rl_parsing_conditionalized_out) + return (0); + + old_init_file = current_readline_init_file; + old_line_number = current_readline_init_lineno; + old_include_level = current_readline_init_include_level; + + e = strchr (args, '\n'); + if (e) + *e = '\0'; + r = _rl_read_init_file ((const char *)args, old_include_level + 1); + + current_readline_init_file = old_init_file; + current_readline_init_lineno = old_line_number; + current_readline_init_include_level = old_include_level; + + return r; +} + +/* Associate textual names with actual functions. */ +static const struct { + const char * const name; + _rl_parser_func_t *function; +} parser_directives [] = { + { "if", parser_if }, + { "endif", parser_endif }, + { "else", parser_else }, + { "include", parser_include }, + { (char *)0x0, (_rl_parser_func_t *)0x0 } +}; + +/* Handle a parser directive. STATEMENT is the line of the directive + without any leading `$'. */ +static int +handle_parser_directive (char *statement) +{ + register int i; + char *directive, *args; + + /* Isolate the actual directive. */ + + /* Skip whitespace. */ + for (i = 0; whitespace (statement[i]); i++); + + directive = &statement[i]; + + for (; statement[i] && !whitespace (statement[i]); i++); + + if (statement[i]) + statement[i++] = '\0'; + + for (; statement[i] && whitespace (statement[i]); i++); + + args = &statement[i]; + + /* Lookup the command, and act on it. */ + for (i = 0; parser_directives[i].name; i++) + if (_rl_stricmp (directive, parser_directives[i].name) == 0) + { + (*parser_directives[i].function) (args); + return (0); + } + + /* display an error message about the unknown parser directive */ + _rl_init_file_error ("%s: unknown parser directive", directive); + return (1); +} + +/* Start at STRING[START] and look for DELIM. Return I where STRING[I] == + DELIM or STRING[I] == 0. DELIM is usually a double quote. */ +static int +_rl_skip_to_delim (char *string, int start, int delim) +{ + int i, c, passc; + + for (i = start,passc = 0; c = string[i]; i++) + { + if (passc) + { + passc = 0; + if (c == 0) + break; + continue; + } + + if (c == '\\') + { + passc = 1; + continue; + } + + if (c == delim) + break; + } + + return i; +} + +/* Read the binding command from STRING and perform it. + A key binding command looks like: Keyname: function-name\0, + a variable binding command looks like: set variable value. + A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ +int +rl_parse_and_bind (char *string) +{ + char *funname, *kname; + register int c, i; + int key, equivalency, foundmod, foundsep; + + while (string && whitespace (*string)) + string++; + + if (string == 0 || *string == 0 || *string == '#') + return 0; + + /* If this is a parser directive, act on it. */ + if (*string == '$') + { + handle_parser_directive (&string[1]); + return 0; + } + + /* If we aren't supposed to be parsing right now, then we're done. */ + if (_rl_parsing_conditionalized_out) + return 0; + + i = 0; + /* If this keyname is a complex key expression surrounded by quotes, + advance to after the matching close quote. This code allows the + backslash to quote characters in the key expression. */ + if (*string == '"') + { + i = _rl_skip_to_delim (string, 1, '"'); + + /* If we didn't find a closing quote, abort the line. */ + if (string[i] == '\0') + { + _rl_init_file_error ("%s: no closing `\"' in key binding", string); + return 1; + } + else + i++; /* skip past closing double quote */ + } + + /* Advance to the colon (:) or whitespace which separates the two objects. */ + for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); + + if (i == 0) + { + _rl_init_file_error ("`%s': invalid key binding: missing key sequence", string); + return 1; + } + + equivalency = (c == ':' && string[i + 1] == '='); + + foundsep = c != 0; + + /* Mark the end of the command (or keyname). */ + if (string[i]) + string[i++] = '\0'; + + /* If doing assignment, skip the '=' sign as well. */ + if (equivalency) + string[i++] = '\0'; + + /* If this is a command to set a variable, then do that. */ + if (_rl_stricmp (string, "set") == 0) + { + char *var, *value, *e; + int s; + + var = string + i; + /* Make VAR point to start of variable name. */ + while (*var && whitespace (*var)) var++; + + /* Make VALUE point to start of value string. */ + value = var; + while (*value && whitespace (*value) == 0) value++; + if (*value) + *value++ = '\0'; + while (*value && whitespace (*value)) value++; + + /* Strip trailing whitespace from values of boolean variables. */ + if (find_boolean_var (var) >= 0) + { + /* just read a whitespace-delimited word or empty string */ + for (e = value; *e && whitespace (*e) == 0; e++) + ; + if (e > value) + *e = '\0'; /* cut off everything trailing */ + } + else if ((i = find_string_var (var)) >= 0) + { + /* Allow quoted strings in variable values */ + if (*value == '"') + { + i = _rl_skip_to_delim (value, 1, *value); + value[i] = '\0'; + value++; /* skip past the quote */ + } + else + { + /* remove trailing whitespace */ + e = value + strlen (value) - 1; + while (e >= value && whitespace (*e)) + e--; + e++; /* skip back to whitespace or EOS */ + + if (*e && e >= value) + *e = '\0'; + } + } + else + { + /* avoid calling rl_variable_bind just to find this out */ + _rl_init_file_error ("%s: unknown variable name", var); + return 1; + } + + rl_variable_bind (var, value); + return 0; + } + + /* Skip any whitespace between keyname and funname. */ + for (; string[i] && whitespace (string[i]); i++); + funname = &string[i]; + + /* Now isolate funname. + For straight function names just look for whitespace, since + that will signify the end of the string. But this could be a + macro definition. In that case, the string is quoted, so skip + to the matching delimiter. We allow the backslash to quote the + delimiter characters in the macro body. */ + /* This code exists to allow whitespace in macro expansions, which + would otherwise be gobbled up by the next `for' loop.*/ + /* XXX - it may be desirable to allow backslash quoting only if " is + the quoted string delimiter, like the shell. */ + if (*funname == '\'' || *funname == '"') + { + i = _rl_skip_to_delim (string, i+1, *funname); + if (string[i]) + i++; + else + { + _rl_init_file_error ("`%s': missing closing quote for macro", funname); + return 1; + } + } + + /* Advance to the end of the string. */ + for (; string[i] && whitespace (string[i]) == 0; i++); + + /* No extra whitespace at the end of the string. */ + string[i] = '\0'; + + /* Handle equivalency bindings here. Make the left-hand side be exactly + whatever the right-hand evaluates to, including keymaps. */ + if (equivalency) + { + return 0; + } + + if (foundsep == 0) + { + _rl_init_file_error ("%s: no key sequence terminator", string); + return 1; + } + + /* If this is a new-style key-binding, then do the binding with + rl_bind_keyseq (). Otherwise, let the older code deal with it. */ + if (*string == '"') + { + char *seq; + register int j, k, passc; + + seq = (char *)xmalloc (1 + strlen (string)); + for (j = 1, k = passc = 0; string[j]; j++) + { + /* Allow backslash to quote characters, but leave them in place. + This allows a string to end with a backslash quoting another + backslash, or with a backslash quoting a double quote. The + backslashes are left in place for rl_translate_keyseq (). */ + if (passc || (string[j] == '\\')) + { + seq[k++] = string[j]; + passc = !passc; + continue; + } + + if (string[j] == '"') + break; + + seq[k++] = string[j]; + } + seq[k] = '\0'; + + /* Binding macro? */ + if (*funname == '\'' || *funname == '"') + { + j = strlen (funname); + + /* Remove the delimiting quotes from each end of FUNNAME. */ + if (j && funname[j - 1] == *funname) + funname[j - 1] = '\0'; + + rl_macro_bind (seq, &funname[1], _rl_keymap); + } + else + rl_bind_keyseq (seq, rl_named_function (funname)); + + xfree (seq); + return 0; + } + + /* Get the actual character we want to deal with. */ + kname = strrchr (string, '-'); + if (kname == 0) + kname = string; + else + kname++; + + key = glean_key_from_name (kname); + + /* Add in control and meta bits. */ + foundmod = 0; + if (substring_member_of_array (string, _rl_possible_control_prefixes)) + { + key = CTRL (_rl_to_upper (key)); + foundmod = 1; + } + + if (substring_member_of_array (string, _rl_possible_meta_prefixes)) + { + key = META (key); + foundmod = 1; + } + + if (foundmod == 0 && kname != string) + { + _rl_init_file_error ("%s: unknown key modifier", string); + return 1; + } + + /* Temporary. Handle old-style keyname with macro-binding. */ + if (*funname == '\'' || *funname == '"') + { + char useq[2]; + int fl = strlen (funname); + + useq[0] = key; useq[1] = '\0'; + if (fl && funname[fl - 1] == *funname) + funname[fl - 1] = '\0'; + + rl_macro_bind (useq, &funname[1], _rl_keymap); + } +#if defined (PREFIX_META_HACK) + /* Ugly, but working hack to keep prefix-meta around. */ + else if (_rl_stricmp (funname, "prefix-meta") == 0) + { + char seq[2]; + + seq[0] = key; + seq[1] = '\0'; + rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap); + } +#endif /* PREFIX_META_HACK */ + else + rl_bind_key (key, rl_named_function (funname)); + + return 0; +} + +/* Simple structure for boolean readline variables (i.e., those that can + have one of two values; either "On" or 1 for truth, or "Off" or 0 for + false. */ + +#define V_SPECIAL 0x1 + +static const struct { + const char * const name; + int *value; + int flags; +} boolean_varlist [] = { + { "bind-tty-special-chars", &_rl_bind_stty_chars, 0 }, + { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL }, + { "byte-oriented", &rl_byte_oriented, 0 }, +#if defined (COLOR_SUPPORT) + { "colored-completion-prefix",&_rl_colored_completion_prefix, 0 }, + { "colored-stats", &_rl_colored_stats, 0 }, +#endif + { "completion-ignore-case", &_rl_completion_case_fold, 0 }, + { "completion-map-case", &_rl_completion_case_map, 0 }, + { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 }, + { "disable-completion", &rl_inhibit_completion, 0 }, + { "echo-control-characters", &_rl_echo_control_chars, 0 }, + { "enable-bracketed-paste", &_rl_enable_bracketed_paste, V_SPECIAL }, + { "enable-keypad", &_rl_enable_keypad, 0 }, + { "enable-meta-key", &_rl_enable_meta, 0 }, + { "expand-tilde", &rl_complete_with_tilde_expansion, 0 }, + { "history-preserve-point", &_rl_history_preserve_point, 0 }, + { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 }, + { "input-meta", &_rl_meta_flag, 0 }, + { "mark-directories", &_rl_complete_mark_directories, 0 }, + { "mark-modified-lines", &_rl_mark_modified_lines, 0 }, + { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 }, + { "match-hidden-files", &_rl_match_hidden_files, 0 }, + { "menu-complete-display-prefix", &_rl_menu_complete_prefix_first, 0 }, + { "meta-flag", &_rl_meta_flag, 0 }, + { "output-meta", &_rl_output_meta_chars, 0 }, + { "page-completions", &_rl_page_completions, 0 }, + { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL }, + { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 }, + { "revert-all-at-newline", &_rl_revert_all_at_newline, 0 }, + { "show-all-if-ambiguous", &_rl_complete_show_all, 0 }, + { "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 }, + { "show-mode-in-prompt", &_rl_show_mode_in_prompt, 0 }, + { "skip-completed-text", &_rl_skip_completed_text, 0 }, +#if defined (VISIBLE_STATS) + { "visible-stats", &rl_visible_stats, 0 }, +#endif /* VISIBLE_STATS */ + { (char *)NULL, (int *)NULL, 0 } +}; + +static int +find_boolean_var (const char *name) +{ + register int i; + + for (i = 0; boolean_varlist[i].name; i++) + if (_rl_stricmp (name, boolean_varlist[i].name) == 0) + return i; + return -1; +} + +static const char * +boolean_varname (int i) +{ + return ((i >= 0) ? boolean_varlist[i].name : (char *)NULL); +} + +/* Hooks for handling special boolean variables, where a + function needs to be called or another variable needs + to be changed when they're changed. */ +static void +hack_special_boolean_var (int i) +{ + const char *name; + + name = boolean_varlist[i].name; + + if (_rl_stricmp (name, "blink-matching-paren") == 0) + _rl_enable_paren_matching (rl_blink_matching_paren); + else if (_rl_stricmp (name, "prefer-visible-bell") == 0) + { + if (_rl_prefer_visible_bell) + _rl_bell_preference = VISIBLE_BELL; + else + _rl_bell_preference = AUDIBLE_BELL; + } + else if (_rl_stricmp (name, "show-mode-in-prompt") == 0) + _rl_reset_prompt (); + else if (_rl_stricmp (name, "enable-bracketed-paste") == 0) + _rl_enable_active_region = _rl_enable_bracketed_paste; +} + +typedef int _rl_sv_func_t PARAMS((const char *)); + +/* These *must* correspond to the array indices for the appropriate + string variable. (Though they're not used right now.) */ +#define V_BELLSTYLE 0 +#define V_COMBEGIN 1 +#define V_EDITMODE 2 +#define V_ISRCHTERM 3 +#define V_KEYMAP 4 + +#define V_STRING 1 +#define V_INT 2 + +/* Forward declarations */ +static int sv_bell_style PARAMS((const char *)); +static int sv_combegin PARAMS((const char *)); +static int sv_dispprefix PARAMS((const char *)); +static int sv_compquery PARAMS((const char *)); +static int sv_compwidth PARAMS((const char *)); +static int sv_editmode PARAMS((const char *)); +static int sv_emacs_modestr PARAMS((const char *)); +static int sv_histsize PARAMS((const char *)); +static int sv_isrchterm PARAMS((const char *)); +static int sv_keymap PARAMS((const char *)); +static int sv_seqtimeout PARAMS((const char *)); +static int sv_viins_modestr PARAMS((const char *)); +static int sv_vicmd_modestr PARAMS((const char *)); + +static const struct { + const char * const name; + int flags; + _rl_sv_func_t *set_func; +} string_varlist[] = { + { "bell-style", V_STRING, sv_bell_style }, + { "comment-begin", V_STRING, sv_combegin }, + { "completion-display-width", V_INT, sv_compwidth }, + { "completion-prefix-display-length", V_INT, sv_dispprefix }, + { "completion-query-items", V_INT, sv_compquery }, + { "editing-mode", V_STRING, sv_editmode }, + { "emacs-mode-string", V_STRING, sv_emacs_modestr }, + { "history-size", V_INT, sv_histsize }, + { "isearch-terminators", V_STRING, sv_isrchterm }, + { "keymap", V_STRING, sv_keymap }, + { "keyseq-timeout", V_INT, sv_seqtimeout }, + { "vi-cmd-mode-string", V_STRING, sv_vicmd_modestr }, + { "vi-ins-mode-string", V_STRING, sv_viins_modestr }, + { (char *)NULL, 0, (_rl_sv_func_t *)0 } +}; + +static int +find_string_var (const char *name) +{ + register int i; + + for (i = 0; string_varlist[i].name; i++) + if (_rl_stricmp (name, string_varlist[i].name) == 0) + return i; + return -1; +} + +static const char * +string_varname (int i) +{ + return ((i >= 0) ? string_varlist[i].name : (char *)NULL); +} + +/* A boolean value that can appear in a `set variable' command is true if + the value is null or empty, `on' (case-insensitive), or "1". All other + values result in 0 (false). */ +static int +bool_to_int (const char *value) +{ + return (value == 0 || *value == '\0' || + (_rl_stricmp (value, "on") == 0) || + (value[0] == '1' && value[1] == '\0')); +} + +char * +rl_variable_value (const char *name) +{ + register int i; + + /* Check for simple variables first. */ + i = find_boolean_var (name); + if (i >= 0) + return (*boolean_varlist[i].value ? "on" : "off"); + + i = find_string_var (name); + if (i >= 0) + return (_rl_get_string_variable_value (string_varlist[i].name)); + + /* Unknown variable names return NULL. */ + return (char *)NULL; +} + +int +rl_variable_bind (const char *name, const char *value) +{ + register int i; + int v; + + /* Check for simple variables first. */ + i = find_boolean_var (name); + if (i >= 0) + { + *boolean_varlist[i].value = bool_to_int (value); + if (boolean_varlist[i].flags & V_SPECIAL) + hack_special_boolean_var (i); + return 0; + } + + i = find_string_var (name); + + /* For the time being, string names without a handler function are simply + ignored. */ + if (i < 0 || string_varlist[i].set_func == 0) + { + if (i < 0) + _rl_init_file_error ("%s: unknown variable name", name); + return 0; + } + + v = (*string_varlist[i].set_func) (value); + if (v != 0) + _rl_init_file_error ("%s: could not set value to `%s'", name, value); + return v; +} + +static int +sv_editmode (const char *value) +{ + if (_rl_strnicmp (value, "vi", 2) == 0) + { +#if defined (VI_MODE) + _rl_keymap = vi_insertion_keymap; + rl_editing_mode = vi_mode; +#endif /* VI_MODE */ + return 0; + } + else if (_rl_strnicmp (value, "emacs", 5) == 0) + { + _rl_keymap = emacs_standard_keymap; + rl_editing_mode = emacs_mode; + return 0; + } + return 1; +} + +static int +sv_combegin (const char *value) +{ + if (value && *value) + { + FREE (_rl_comment_begin); + _rl_comment_begin = savestring (value); + return 0; + } + return 1; +} + +static int +sv_dispprefix (const char *value) +{ + int nval = 0; + + if (value && *value) + { + nval = atoi (value); + if (nval < 0) + nval = 0; + } + _rl_completion_prefix_display_length = nval; + return 0; +} + +static int +sv_compquery (const char *value) +{ + int nval = 100; + + if (value && *value) + { + nval = atoi (value); + if (nval < 0) + nval = 0; + } + rl_completion_query_items = nval; + return 0; +} + +static int +sv_compwidth (const char *value) +{ + int nval = -1; + + if (value && *value) + nval = atoi (value); + + _rl_completion_columns = nval; + return 0; +} + +static int +sv_histsize (const char *value) +{ + int nval; + + nval = 500; + if (value && *value) + { + nval = atoi (value); + if (nval < 0) + { + unstifle_history (); + return 0; + } + } + stifle_history (nval); + return 0; +} + +static int +sv_keymap (const char *value) +{ + Keymap kmap; + + kmap = rl_get_keymap_by_name (value); + if (kmap) + { + rl_set_keymap (kmap); + return 0; + } + return 1; +} + +static int +sv_seqtimeout (const char *value) +{ + int nval; + + nval = 0; + if (value && *value) + { + nval = atoi (value); + if (nval < 0) + nval = 0; + } + _rl_keyseq_timeout = nval; + return 0; +} + +static int +sv_bell_style (const char *value) +{ + if (value == 0 || *value == '\0') + _rl_bell_preference = AUDIBLE_BELL; + else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0) + _rl_bell_preference = NO_BELL; + else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0) + _rl_bell_preference = AUDIBLE_BELL; + else if (_rl_stricmp (value, "visible") == 0) + _rl_bell_preference = VISIBLE_BELL; + else + return 1; + return 0; +} + +static int +sv_isrchterm (const char *value) +{ + int beg, end, delim; + char *v; + + if (value == 0) + return 1; + + /* Isolate the value and translate it into a character string. */ + v = savestring (value); + FREE (_rl_isearch_terminators); + if (v[0] == '"' || v[0] == '\'') + { + delim = v[0]; + for (beg = end = 1; v[end] && v[end] != delim; end++) + ; + } + else + { + for (beg = end = 0; v[end] && whitespace (v[end]) == 0; end++) + ; + } + + v[end] = '\0'; + + /* The value starts at v + beg. Translate it into a character string. */ + _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1); + rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end); + _rl_isearch_terminators[end] = '\0'; + + xfree (v); + return 0; +} + +extern char *_rl_emacs_mode_str; + +static int +sv_emacs_modestr (const char *value) +{ + if (value && *value) + { + FREE (_rl_emacs_mode_str); + _rl_emacs_mode_str = (char *)xmalloc (2 * strlen (value) + 1); + rl_translate_keyseq (value, _rl_emacs_mode_str, &_rl_emacs_modestr_len); + _rl_emacs_mode_str[_rl_emacs_modestr_len] = '\0'; + return 0; + } + else if (value) + { + FREE (_rl_emacs_mode_str); + _rl_emacs_mode_str = (char *)xmalloc (1); + _rl_emacs_mode_str[_rl_emacs_modestr_len = 0] = '\0'; + return 0; + } + else if (value == 0) + { + FREE (_rl_emacs_mode_str); + _rl_emacs_mode_str = 0; /* prompt_modestr does the right thing */ + _rl_emacs_modestr_len = 0; + return 0; + } + return 1; +} + +static int +sv_viins_modestr (const char *value) +{ + if (value && *value) + { + FREE (_rl_vi_ins_mode_str); + _rl_vi_ins_mode_str = (char *)xmalloc (2 * strlen (value) + 1); + rl_translate_keyseq (value, _rl_vi_ins_mode_str, &_rl_vi_ins_modestr_len); + _rl_vi_ins_mode_str[_rl_vi_ins_modestr_len] = '\0'; + return 0; + } + else if (value) + { + FREE (_rl_vi_ins_mode_str); + _rl_vi_ins_mode_str = (char *)xmalloc (1); + _rl_vi_ins_mode_str[_rl_vi_ins_modestr_len = 0] = '\0'; + return 0; + } + else if (value == 0) + { + FREE (_rl_vi_ins_mode_str); + _rl_vi_ins_mode_str = 0; /* prompt_modestr does the right thing */ + _rl_vi_ins_modestr_len = 0; + return 0; + } + return 1; +} + +static int +sv_vicmd_modestr (const char *value) +{ + if (value && *value) + { + FREE (_rl_vi_cmd_mode_str); + _rl_vi_cmd_mode_str = (char *)xmalloc (2 * strlen (value) + 1); + rl_translate_keyseq (value, _rl_vi_cmd_mode_str, &_rl_vi_cmd_modestr_len); + _rl_vi_cmd_mode_str[_rl_vi_cmd_modestr_len] = '\0'; + return 0; + } + else if (value) + { + FREE (_rl_vi_cmd_mode_str); + _rl_vi_cmd_mode_str = (char *)xmalloc (1); + _rl_vi_cmd_mode_str[_rl_vi_cmd_modestr_len = 0] = '\0'; + return 0; + } + else if (value == 0) + { + FREE (_rl_vi_cmd_mode_str); + _rl_vi_cmd_mode_str = 0; /* prompt_modestr does the right thing */ + _rl_vi_cmd_modestr_len = 0; + return 0; + } + return 1; +} + +/* Return the character which matches NAME. + For example, `Space' returns ' '. */ + +typedef struct { + const char * const name; + int value; +} assoc_list; + +static const assoc_list name_key_alist[] = { + { "DEL", 0x7f }, + { "ESC", '\033' }, + { "Escape", '\033' }, + { "LFD", '\n' }, + { "Newline", '\n' }, + { "RET", '\r' }, + { "Return", '\r' }, + { "Rubout", 0x7f }, + { "SPC", ' ' }, + { "Space", ' ' }, + { "Tab", 0x09 }, + { (char *)0x0, 0 } +}; + +static int +glean_key_from_name (char *name) +{ + register int i; + + for (i = 0; name_key_alist[i].name; i++) + if (_rl_stricmp (name, name_key_alist[i].name) == 0) + return (name_key_alist[i].value); + + return (*(unsigned char *)name); /* XXX was return (*name) */ +} + +/* Auxiliary functions to manage keymaps. */ +struct name_and_keymap { + char *name; + Keymap map; +}; + +static struct name_and_keymap builtin_keymap_names[] = { + { "emacs", emacs_standard_keymap }, + { "emacs-standard", emacs_standard_keymap }, + { "emacs-meta", emacs_meta_keymap }, + { "emacs-ctlx", emacs_ctlx_keymap }, +#if defined (VI_MODE) + { "vi", vi_movement_keymap }, + { "vi-move", vi_movement_keymap }, + { "vi-command", vi_movement_keymap }, + { "vi-insert", vi_insertion_keymap }, +#endif /* VI_MODE */ + { (char *)0x0, (Keymap)0x0 } +}; + +/* -1 for NULL entry */ +#define NUM_BUILTIN_KEYMAPS (sizeof (builtin_keymap_names) / sizeof (builtin_keymap_names[0]) - 1) + +static struct name_and_keymap *keymap_names = builtin_keymap_names; + +static int +_rl_get_keymap_by_name (const char *name) +{ + register int i; + + for (i = 0; keymap_names[i].name; i++) + if (_rl_stricmp (name, keymap_names[i].name) == 0) + return (i); + return -1; +} + +Keymap +rl_get_keymap_by_name (const char *name) +{ + int i; + + i = _rl_get_keymap_by_name (name); + return ((i >= 0) ? keymap_names[i].map : (Keymap) NULL); +} + +static int +_rl_get_keymap_by_map (Keymap map) +{ + register int i; + + for (i = 0; keymap_names[i].name; i++) + if (map == keymap_names[i].map) + return (i); + return -1; +} + +char * +rl_get_keymap_name (Keymap map) +{ + int i; + + i = _rl_get_keymap_by_map (map); + return ((i >= 0) ? keymap_names[i].name : (char *)NULL); +} + +int +rl_set_keymap_name (const char *name, Keymap map) +{ + int i, ni, mi; + + /* First check whether or not we're trying to rename a builtin keymap */ + mi = _rl_get_keymap_by_map (map); + if (mi >= 0 && mi < NUM_BUILTIN_KEYMAPS) + return -1; + + /* Then reject attempts to set one of the builtin names to a new map */ + ni = _rl_get_keymap_by_name (name); + if (ni >= 0 && ni < NUM_BUILTIN_KEYMAPS) + return -1; + + /* Renaming a keymap we already added */ + if (mi >= 0) /* XXX - could be >= NUM_BUILTIN_KEYMAPS */ + { + xfree (keymap_names[mi].name); + keymap_names[mi].name = savestring (name); + return mi; + } + + /* Associating new keymap with existing name */ + if (ni >= 0) + { + keymap_names[ni].map = map; + return ni; + } + + for (i = 0; keymap_names[i].name; i++) + ; + + if (keymap_names == builtin_keymap_names) + { + keymap_names = xmalloc ((i + 2) * sizeof (struct name_and_keymap)); + memcpy (keymap_names, builtin_keymap_names, i * sizeof (struct name_and_keymap)); + } + else + keymap_names = xrealloc (keymap_names, (i + 2) * sizeof (struct name_and_keymap)); + + keymap_names[i].name = savestring (name); + keymap_names[i].map = map; + + keymap_names[i+1].name = NULL; + keymap_names[i+1].map = NULL; + + return i; +} + +void +rl_set_keymap (Keymap map) +{ + if (map) + _rl_keymap = map; +} + +Keymap +rl_get_keymap (void) +{ + return (_rl_keymap); +} + +void +rl_set_keymap_from_edit_mode (void) +{ + if (rl_editing_mode == emacs_mode) + _rl_keymap = emacs_standard_keymap; +#if defined (VI_MODE) + else if (rl_editing_mode == vi_mode) + _rl_keymap = vi_insertion_keymap; +#endif /* VI_MODE */ +} + +char * +rl_get_keymap_name_from_edit_mode (void) +{ + if (rl_editing_mode == emacs_mode) + return "emacs"; +#if defined (VI_MODE) + else if (rl_editing_mode == vi_mode) + return "vi"; +#endif /* VI_MODE */ + else + return "none"; +} + +/* **************************************************************** */ +/* */ +/* Key Binding and Function Information */ +/* */ +/* **************************************************************** */ + +/* Each of the following functions produces information about the + state of keybindings and functions known to Readline. The info + is always printed to rl_outstream, and in such a way that it can + be read back in (i.e., passed to rl_parse_and_bind ()). */ + +/* Print the names of functions known to Readline. */ +void +rl_list_funmap_names (void) +{ + register int i; + const char **funmap_names; + + funmap_names = rl_funmap_names (); + + if (!funmap_names) + return; + + for (i = 0; funmap_names[i]; i++) + fprintf (rl_outstream, "%s\n", funmap_names[i]); + + xfree (funmap_names); +} + +static char * +_rl_get_keyname (int key) +{ + char *keyname; + int i, c; + + keyname = (char *)xmalloc (8); + + c = key; + /* Since this is going to be used to write out keysequence-function + pairs for possible inclusion in an inputrc file, we don't want to + do any special meta processing on KEY. */ + +#if 1 + /* XXX - Experimental */ + /* We might want to do this, but the old version of the code did not. */ + + /* If this is an escape character, we don't want to do any more processing. + Just add the special ESC key sequence and return. */ + if (c == ESC) + { + keyname[0] = '\\'; + keyname[1] = 'e'; + keyname[2] = '\0'; + return keyname; + } +#endif + + /* RUBOUT is translated directly into \C-? */ + if (key == RUBOUT) + { + keyname[0] = '\\'; + keyname[1] = 'C'; + keyname[2] = '-'; + keyname[3] = '?'; + keyname[4] = '\0'; + return keyname; + } + + i = 0; + /* Now add special prefixes needed for control characters. This can + potentially change C. */ + if (CTRL_CHAR (c)) + { + keyname[i++] = '\\'; + keyname[i++] = 'C'; + keyname[i++] = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + + /* XXX experimental code. Turn the characters that are not ASCII or + ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237). + This changes C. */ + if (c >= 128 && c <= 159) + { + keyname[i++] = '\\'; + keyname[i++] = '2'; + c -= 128; + keyname[i++] = (c / 8) + '0'; + c = (c % 8) + '0'; + } + + /* Now, if the character needs to be quoted with a backslash, do that. */ + if (c == '\\' || c == '"') + keyname[i++] = '\\'; + + /* Now add the key, terminate the string, and return it. */ + keyname[i++] = (char) c; + keyname[i] = '\0'; + + return keyname; +} + +/* Return a NULL terminated array of strings which represent the key + sequences that are used to invoke FUNCTION in MAP. */ +char ** +rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map) +{ + register int key; + char **result; + int result_index, result_size; + + result = (char **)NULL; + result_index = result_size = 0; + + for (key = 0; key < KEYMAP_SIZE; key++) + { + switch (map[key].type) + { + case ISMACR: + /* Macros match, if, and only if, the pointers are identical. + Thus, they are treated exactly like functions in here. */ + case ISFUNC: + /* If the function in the keymap is the one we are looking for, + then add the current KEY to the list of invoking keys. */ + if (map[key].function == function) + { + char *keyname; + + keyname = _rl_get_keyname (key); + + if (result_index + 2 > result_size) + { + result_size += 10; + result = (char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index++] = keyname; + result[result_index] = (char *)NULL; + } + break; + + case ISKMAP: + { + char **seqs; + register int i; + + /* Find the list of keyseqs in this map which have FUNCTION as + their target. Add the key sequences found to RESULT. */ + if (map[key].function) + seqs = + rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key)); + else + break; + + if (seqs == 0) + break; + + for (i = 0; seqs[i]; i++) + { + char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); + + if (key == ESC) + { + /* If ESC is the meta prefix and we're converting chars + with the eighth bit set to ESC-prefixed sequences, then + we can use \M-. Otherwise we need to use the sequence + for ESC. */ + if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP) + sprintf (keyname, "\\M-"); + else + sprintf (keyname, "\\e"); + } + else + { + int c = key, l = 0; + if (CTRL_CHAR (c) || c == RUBOUT) + { + keyname[l++] = '\\'; + keyname[l++] = 'C'; + keyname[l++] = '-'; + c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c)); + } + + if (c == '\\' || c == '"') + keyname[l++] = '\\'; + + keyname[l++] = (char) c; + keyname[l++] = '\0'; + } + + strcat (keyname, seqs[i]); + xfree (seqs[i]); + + if (result_index + 2 > result_size) + { + result_size += 10; + result = (char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index++] = keyname; + result[result_index] = (char *)NULL; + } + + xfree (seqs); + } + break; + } + } + return (result); +} + +/* Return a NULL terminated array of strings which represent the key + sequences that can be used to invoke FUNCTION using the current keymap. */ +char ** +rl_invoking_keyseqs (rl_command_func_t *function) +{ + return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); +} + +/* Print all of the functions and their bindings to rl_outstream. If + PRINT_READABLY is non-zero, then print the output in such a way + that it can be read back in. */ +void +rl_function_dumper (int print_readably) +{ + register int i; + const char **names; + const char *name; + + names = rl_funmap_names (); + + fprintf (rl_outstream, "\n"); + + for (i = 0; name = names[i]; i++) + { + rl_command_func_t *function; + char **invokers; + + function = rl_named_function (name); + invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap); + + if (print_readably) + { + if (!invokers) + fprintf (rl_outstream, "# %s (not bound)\n", name); + else + { + register int j; + + for (j = 0; invokers[j]; j++) + { + fprintf (rl_outstream, "\"%s\": %s\n", + invokers[j], name); + xfree (invokers[j]); + } + + xfree (invokers); + } + } + else + { + if (!invokers) + fprintf (rl_outstream, "%s is not bound to any keys\n", + name); + else + { + register int j; + + fprintf (rl_outstream, "%s can be found on ", name); + + for (j = 0; invokers[j] && j < 5; j++) + { + fprintf (rl_outstream, "\"%s\"%s", invokers[j], + invokers[j + 1] ? ", " : ".\n"); + } + + if (j == 5 && invokers[j]) + fprintf (rl_outstream, "...\n"); + + for (j = 0; invokers[j]; j++) + xfree (invokers[j]); + + xfree (invokers); + } + } + } + + xfree (names); +} + +/* Print all of the current functions and their bindings to + rl_outstream. If an explicit argument is given, then print + the output in such a way that it can be read back in. */ +int +rl_dump_functions (int count, int key) +{ + if (rl_dispatching) + fprintf (rl_outstream, "\r\n"); + rl_function_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +static void +_rl_macro_dumper_internal (int print_readably, Keymap map, char *prefix) +{ + register int key; + char *keyname, *out; + int prefix_len; + + for (key = 0; key < KEYMAP_SIZE; key++) + { + switch (map[key].type) + { + case ISMACR: + keyname = _rl_get_keyname (key); + out = _rl_untranslate_macro_value ((char *)map[key].function, 0); + + if (print_readably) + fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "", + keyname, + out ? out : ""); + else + fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "", + keyname, + out ? out : ""); + xfree (keyname); + xfree (out); + break; + case ISFUNC: + break; + case ISKMAP: + prefix_len = prefix ? strlen (prefix) : 0; + if (key == ESC) + { + keyname = (char *)xmalloc (3 + prefix_len); + if (prefix) + strcpy (keyname, prefix); + keyname[prefix_len] = '\\'; + keyname[prefix_len + 1] = 'e'; + keyname[prefix_len + 2] = '\0'; + } + else + { + keyname = _rl_get_keyname (key); + if (prefix) + { + out = (char *)xmalloc (strlen (keyname) + prefix_len + 1); + strcpy (out, prefix); + strcpy (out + prefix_len, keyname); + xfree (keyname); + keyname = out; + } + } + + _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname); + xfree (keyname); + break; + } + } +} + +void +rl_macro_dumper (int print_readably) +{ + _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); +} + +int +rl_dump_macros (int count, int key) +{ + if (rl_dispatching) + fprintf (rl_outstream, "\r\n"); + rl_macro_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +static char * +_rl_get_string_variable_value (const char *name) +{ + static char numbuf[32]; + char *ret; + + if (_rl_stricmp (name, "bell-style") == 0) + { + switch (_rl_bell_preference) + { + case NO_BELL: + return "none"; + case VISIBLE_BELL: + return "visible"; + case AUDIBLE_BELL: + default: + return "audible"; + } + } + else if (_rl_stricmp (name, "comment-begin") == 0) + return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); + else if (_rl_stricmp (name, "completion-display-width") == 0) + { + sprintf (numbuf, "%d", _rl_completion_columns); + return (numbuf); + } + else if (_rl_stricmp (name, "completion-prefix-display-length") == 0) + { + sprintf (numbuf, "%d", _rl_completion_prefix_display_length); + return (numbuf); + } + else if (_rl_stricmp (name, "completion-query-items") == 0) + { + sprintf (numbuf, "%d", rl_completion_query_items); + return (numbuf); + } + else if (_rl_stricmp (name, "editing-mode") == 0) + return (rl_get_keymap_name_from_edit_mode ()); + else if (_rl_stricmp (name, "history-size") == 0) + { + sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : 0); + return (numbuf); + } + else if (_rl_stricmp (name, "isearch-terminators") == 0) + { + if (_rl_isearch_terminators == 0) + return 0; + ret = _rl_untranslate_macro_value (_rl_isearch_terminators, 0); + if (ret) + { + strncpy (numbuf, ret, sizeof (numbuf) - 1); + xfree (ret); + numbuf[sizeof(numbuf) - 1] = '\0'; + } + else + numbuf[0] = '\0'; + return numbuf; + } + else if (_rl_stricmp (name, "keymap") == 0) + { + ret = rl_get_keymap_name (_rl_keymap); + if (ret == 0) + ret = rl_get_keymap_name_from_edit_mode (); + return (ret ? ret : "none"); + } + else if (_rl_stricmp (name, "keyseq-timeout") == 0) + { + sprintf (numbuf, "%d", _rl_keyseq_timeout); + return (numbuf); + } + else if (_rl_stricmp (name, "emacs-mode-string") == 0) + return (_rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT); + else if (_rl_stricmp (name, "vi-cmd-mode-string") == 0) + return (_rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT); + else if (_rl_stricmp (name, "vi-ins-mode-string") == 0) + return (_rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT); + else + return (0); +} + +void +rl_variable_dumper (int print_readably) +{ + int i; + char *v; + + for (i = 0; boolean_varlist[i].name; i++) + { + if (print_readably) + fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name, + *boolean_varlist[i].value ? "on" : "off"); + else + fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name, + *boolean_varlist[i].value ? "on" : "off"); + } + + for (i = 0; string_varlist[i].name; i++) + { + v = _rl_get_string_variable_value (string_varlist[i].name); + if (v == 0) /* _rl_isearch_terminators can be NULL */ + continue; + if (print_readably) + fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v); + else + fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v); + } +} + +/* Print all of the current variables and their values to + rl_outstream. If an explicit argument is given, then print + the output in such a way that it can be read back in. */ +int +rl_dump_variables (int count, int key) +{ + if (rl_dispatching) + fprintf (rl_outstream, "\r\n"); + rl_variable_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +/* Return non-zero if any members of ARRAY are a substring in STRING. */ +static int +substring_member_of_array (const char *string, const char * const *array) +{ + while (*array) + { + if (_rl_strindex (string, *array)) + return (1); + array++; + } + return (0); +} diff --git a/utshell-0.5.0/lib/readline/callback.c b/utshell-0.5.0/lib/readline/callback.c new file mode 100644 index 00000000..a466cf9b --- /dev/null +++ b/utshell-0.5.0/lib/readline/callback.c @@ -0,0 +1,360 @@ +/* callback.c -- functions to use readline as an X `callback' mechanism. */ + +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include "rlconf.h" + +#if defined (READLINE_CALLBACKS) + +#include + +#ifdef HAVE_STDLIB_H +# include +#else +# include "ansi_stdlib.h" +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "readline.h" +#include "rlprivate.h" +#include "xmalloc.h" + +/* Private data for callback registration functions. See comments in + rl_callback_read_char for more details. */ +_rl_callback_func_t *_rl_callback_func = 0; +_rl_callback_generic_arg *_rl_callback_data = 0; + +/* Applications can set this to non-zero to have readline's signal handlers + installed during the entire duration of reading a complete line, as in + readline-6.2. This should be used with care, because it can result in + readline receiving signals and not handling them until it's called again + via rl_callback_read_char, thereby stealing them from the application. + By default, signal handlers are only active while readline is active. */ +int rl_persistent_signal_handlers = 0; + +/* **************************************************************** */ +/* */ +/* Callback Readline Functions */ +/* */ +/* **************************************************************** */ + +/* Allow using readline in situations where a program may have multiple + things to handle at once, and dispatches them via select(). Call + rl_callback_handler_install() with the prompt and a function to call + whenever a complete line of input is ready. The user must then + call rl_callback_read_char() every time some input is available, and + rl_callback_read_char() will call the user's function with the complete + text read in at each end of line. The terminal is kept prepped + all the time, except during calls to the user's function. Signal + handlers are only installed when the application calls back into + readline, so readline doesn't `steal' signals from the application. */ + +rl_vcpfunc_t *rl_linefunc; /* user callback function */ +static int in_handler; /* terminal_prepped and signals set? */ + +/* Make sure the terminal is set up, initialize readline, and prompt. */ +static void +_rl_callback_newline (void) +{ + rl_initialize (); + + if (in_handler == 0) + { + in_handler = 1; + + if (rl_prep_term_function) + (*rl_prep_term_function) (_rl_meta_flag); + +#if defined (HANDLE_SIGNALS) + if (rl_persistent_signal_handlers) + rl_set_signals (); +#endif + } + + readline_internal_setup (); + RL_CHECK_SIGNALS (); +} + +/* Install a readline handler, set up the terminal, and issue the prompt. */ +void +rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc) +{ + rl_set_prompt (prompt); + RL_SETSTATE (RL_STATE_CALLBACK); + rl_linefunc = linefunc; + _rl_callback_newline (); +} + +#if defined (HANDLE_SIGNALS) +#define CALLBACK_READ_RETURN() \ + do { \ + if (rl_persistent_signal_handlers == 0) \ + rl_clear_signals (); \ + return; \ + } while (0) +#else +#define CALLBACK_READ_RETURN() return +#endif + +/* Read one character, and dispatch to the handler if it ends the line. */ +void +rl_callback_read_char (void) +{ + char *line; + int eof, jcode; + static procenv_t olevel; + + if (rl_linefunc == NULL) + { + _rl_errmsg ("readline_callback_read_char() called with no handler!"); + abort (); + } + + memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t)); +#if defined (HAVE_POSIX_SIGSETJMP) + jcode = sigsetjmp (_rl_top_level, 0); +#else + jcode = setjmp (_rl_top_level); +#endif + if (jcode) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); + CALLBACK_READ_RETURN (); + } + +#if defined (HANDLE_SIGNALS) + /* Install signal handlers only when readline has control. */ + if (rl_persistent_signal_handlers == 0) + rl_set_signals (); +#endif + + do + { + RL_CHECK_SIGNALS (); + if (RL_ISSTATE (RL_STATE_ISEARCH)) + { + eof = _rl_isearch_callback (_rl_iscxt); + if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) + rl_callback_read_char (); + + CALLBACK_READ_RETURN (); + } + else if (RL_ISSTATE (RL_STATE_NSEARCH)) + { + eof = _rl_nsearch_callback (_rl_nscxt); + + CALLBACK_READ_RETURN (); + } +#if defined (VI_MODE) + /* States that can occur while in state VIMOTION have to be checked + before RL_STATE_VIMOTION */ + else if (RL_ISSTATE (RL_STATE_CHARSEARCH)) + { + int k; + + k = _rl_callback_data->i2; + + eof = (*_rl_callback_func) (_rl_callback_data); + /* If the function `deregisters' itself, make sure the data is + cleaned up. */ + if (_rl_callback_func == 0) /* XXX - just sanity check */ + { + if (_rl_callback_data) + { + _rl_callback_data_dispose (_rl_callback_data); + _rl_callback_data = 0; + } + } + + /* Messy case where vi motion command can be char search */ + if (RL_ISSTATE (RL_STATE_VIMOTION)) + { + _rl_vi_domove_motion_cleanup (k, _rl_vimvcxt); + _rl_internal_char_cleanup (); + CALLBACK_READ_RETURN (); + } + + _rl_internal_char_cleanup (); + } + else if (RL_ISSTATE (RL_STATE_VIMOTION)) + { + eof = _rl_vi_domove_callback (_rl_vimvcxt); + /* Should handle everything, including cleanup, numeric arguments, + and turning off RL_STATE_VIMOTION */ + if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) + _rl_internal_char_cleanup (); + + CALLBACK_READ_RETURN (); + } +#endif + else if (RL_ISSTATE (RL_STATE_NUMERICARG)) + { + eof = _rl_arg_callback (_rl_argcxt); + if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING)) + rl_callback_read_char (); + /* XXX - this should handle _rl_last_command_was_kill better */ + else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) + _rl_internal_char_cleanup (); + + CALLBACK_READ_RETURN (); + } + else if (RL_ISSTATE (RL_STATE_MULTIKEY)) + { + eof = _rl_dispatch_callback (_rl_kscxt); /* For now */ + while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED)) + eof = _rl_dispatch_callback (_rl_kscxt); + if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0) + { + _rl_internal_char_cleanup (); + _rl_want_redisplay = 1; + } + } + else if (_rl_callback_func) + { + /* This allows functions that simply need to read an additional + character (like quoted-insert) to register a function to be + called when input is available. _rl_callback_data is a + pointer to a struct that has the argument count originally + passed to the registering function and space for any additional + parameters. */ + eof = (*_rl_callback_func) (_rl_callback_data); + /* If the function `deregisters' itself, make sure the data is + cleaned up. */ + if (_rl_callback_func == 0) + { + if (_rl_callback_data) + { + _rl_callback_data_dispose (_rl_callback_data); + _rl_callback_data = 0; + } + _rl_internal_char_cleanup (); + } + } + else + eof = readline_internal_char (); + + RL_CHECK_SIGNALS (); + if (rl_done == 0 && _rl_want_redisplay) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + } + + if (rl_done) + { + line = readline_internal_teardown (eof); + + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + in_handler = 0; + (*rl_linefunc) (line); + + /* If the user did not clear out the line, do it for him. */ + if (rl_line_buffer[0]) + _rl_init_line_state (); + + /* Redisplay the prompt if readline_handler_{install,remove} + not called. */ + if (in_handler == 0 && rl_linefunc) + _rl_callback_newline (); + } + } + while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT)); + + CALLBACK_READ_RETURN (); +} + +/* Remove the handler, and make sure the terminal is in its normal state. */ +void +rl_callback_handler_remove (void) +{ + rl_linefunc = NULL; + RL_UNSETSTATE (RL_STATE_CALLBACK); + RL_CHECK_SIGNALS (); + if (in_handler) + { + in_handler = 0; + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + } +} + +_rl_callback_generic_arg * +_rl_callback_data_alloc (int count) +{ + _rl_callback_generic_arg *arg; + + arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg)); + arg->count = count; + + arg->i1 = arg->i2 = 0; + + return arg; +} + +void +_rl_callback_data_dispose (_rl_callback_generic_arg *arg) +{ + xfree (arg); +} + +/* Make sure that this agrees with cases in rl_callback_read_char */ +void +rl_callback_sigcleanup (void) +{ + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + return; + + if (RL_ISSTATE (RL_STATE_ISEARCH)) + _rl_isearch_cleanup (_rl_iscxt, 0); + else if (RL_ISSTATE (RL_STATE_NSEARCH)) + _rl_nsearch_cleanup (_rl_nscxt, 0); + else if (RL_ISSTATE (RL_STATE_VIMOTION)) + RL_UNSETSTATE (RL_STATE_VIMOTION); + else if (RL_ISSTATE (RL_STATE_NUMERICARG)) + { + _rl_argcxt = 0; + RL_UNSETSTATE (RL_STATE_NUMERICARG); + } + else if (RL_ISSTATE (RL_STATE_MULTIKEY)) + RL_UNSETSTATE (RL_STATE_MULTIKEY); + if (RL_ISSTATE (RL_STATE_CHARSEARCH)) + RL_UNSETSTATE (RL_STATE_CHARSEARCH); + + _rl_callback_func = 0; +} +#endif diff --git a/utshell-0.5.0/lib/readline/chardefs.h b/utshell-0.5.0/lib/readline/chardefs.h new file mode 100644 index 00000000..3cf1326a --- /dev/null +++ b/utshell-0.5.0/lib/readline/chardefs.h @@ -0,0 +1,164 @@ +/* chardefs.h -- Character definitions for readline. */ + +/* Copyright (C) 1994-2015 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#ifndef _CHARDEFS_H_ +#define _CHARDEFS_H_ + +#include + +#if defined (HAVE_CONFIG_H) +# if defined (HAVE_STRING_H) +# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H) +# include +# endif +# include +# endif /* HAVE_STRING_H */ +# if defined (HAVE_STRINGS_H) +# include +# endif /* HAVE_STRINGS_H */ +#else +# include +#endif /* !HAVE_CONFIG_H */ + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifdef CTRL +# undef CTRL +#endif +#ifdef UNCTRL +# undef UNCTRL +#endif + +/* Some character stuff. */ +#define control_character_threshold 0x020 /* Smaller than this is control. */ +#define control_character_mask 0x1f /* 0x20 - 1 */ +#define meta_character_threshold 0x07f /* Larger than this is Meta. */ +#define control_character_bit 0x40 /* 0x000000, must be off. */ +#define meta_character_bit 0x080 /* x0000000, must be on. */ +#define largest_char 255 /* Largest character value. */ + +#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) +#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) + +#define CTRL(c) ((c) & control_character_mask) +#define META(c) ((c) | meta_character_bit) + +#define UNMETA(c) ((c) & (~meta_character_bit)) +#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit)) + +#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII)) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus) +# define isxdigit(c) (isdigit((unsigned char)(c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#if defined (CTYPE_NON_ASCII) +# define NON_NEGATIVE(c) 1 +#else +# define NON_NEGATIVE(c) ((unsigned char)(c) == (c)) +#endif + +/* Some systems define these; we want our definitions. */ +#undef ISPRINT + +/* Beware: these only work with single-byte ASCII characters. */ + +#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c)) +#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c)) +#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c)) +#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c)) +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c)) +#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c)) + +#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c)) +#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c)) +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') + +#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c)) +#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c)) + +#ifndef _rl_to_upper +# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c)) +# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c)) +#endif + +#ifndef _rl_digit_value +# define _rl_digit_value(x) ((x) - '0') +#endif + +#ifndef _rl_isident +# define _rl_isident(c) (ISALNUM(c) || (c) == '_') +#endif + +#ifndef ISOCTAL +# define ISOCTAL(c) ((c) >= '0' && (c) <= '7') +#endif +#define OCTVALUE(c) ((c) - '0') + +#define HEXVALUE(c) \ + (((c) >= 'a' && (c) <= 'f') \ + ? (c)-'a'+10 \ + : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') + +#ifndef NEWLINE +#define NEWLINE '\n' +#endif + +#ifndef RETURN +#define RETURN CTRL('M') +#endif + +#ifndef RUBOUT +#define RUBOUT 0x7f +#endif + +#ifndef TAB +#define TAB '\t' +#endif + +#ifdef ABORT_CHAR +#undef ABORT_CHAR +#endif +#define ABORT_CHAR CTRL('G') + +#ifdef PAGE +#undef PAGE +#endif +#define PAGE CTRL('L') + +#ifdef SPACE +#undef SPACE +#endif +#define SPACE ' ' /* XXX - was 0x20 */ + +#ifdef ESC +#undef ESC +#endif +#define ESC CTRL('[') + +#endif /* _CHARDEFS_H_ */ diff --git a/utshell-0.5.0/lib/readline/colors.c b/utshell-0.5.0/lib/readline/colors.c new file mode 100644 index 00000000..9e37527e --- /dev/null +++ b/utshell-0.5.0/lib/readline/colors.c @@ -0,0 +1,301 @@ +/* `dir', `vdir' and `ls' directory listing programs for GNU. + + Modified by Chet Ramey for Readline. + + Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017, 2019 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Richard Stallman and David MacKenzie. */ + +/* Color support by Peter Anvin and Dennis + Flaherty based on original patches by + Greg Lee . */ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include "rlconf.h" + +#if defined __TANDEM +# define _XOPEN_SOURCE_EXTENDED 1 +# define _TANDEM_SOURCE 1 +# include +# include +#endif + +#include + +#include "posixstat.h" // stat related macros (S_ISREG, ...) +#include // S_ISUID + +#ifndef S_ISDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +// strlen() +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +// abort() +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "readline.h" +#include "rldefs.h" + +#ifdef COLOR_SUPPORT + +#include "xmalloc.h" +#include "colors.h" + +static bool is_colored (enum indicator_no type); +static void restore_default_color (void); + +COLOR_EXT_TYPE *_rl_color_ext_list = 0; + +/* Output a color indicator (which may contain nulls). */ +void +_rl_put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, rl_outstream); +} + +static bool +is_colored (enum indicator_no colored_filetype) +{ + size_t len = _rl_color_indicator[colored_filetype].len; + char const *s = _rl_color_indicator[colored_filetype].string; + return ! (len == 0 + || (len == 1 && strncmp (s, "0", 1) == 0) + || (len == 2 && strncmp (s, "00", 2) == 0)); +} + +static void +restore_default_color (void) +{ + _rl_put_indicator (&_rl_color_indicator[C_LEFT]); + _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); +} + +void +_rl_set_normal_color (void) +{ + if (is_colored (C_NORM)) + { + _rl_put_indicator (&_rl_color_indicator[C_LEFT]); + _rl_put_indicator (&_rl_color_indicator[C_NORM]); + _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); + } +} + +bool +_rl_print_prefix_color (void) +{ + struct bin_str *s; + + /* What do we want to use for the prefix? Let's try cyan first, see colors.h */ + s = &_rl_color_indicator[C_PREFIX]; + if (s->string != NULL) + { + if (is_colored (C_NORM)) + restore_default_color (); + _rl_put_indicator (&_rl_color_indicator[C_LEFT]); + _rl_put_indicator (s); + _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); + return 0; + } + else + return 1; +} + +/* Returns whether any color sequence was printed. */ +bool +_rl_print_color_indicator (const char *f) +{ + enum indicator_no colored_filetype; + COLOR_EXT_TYPE *ext; /* Color extension */ + size_t len; /* Length of name */ + + const char* name; + char *filename; + struct stat astat, linkstat; + mode_t mode; + int linkok; /* 1 == ok, 0 == dangling symlink, -1 == missing */ + int stat_ok; + + name = f; + + /* This should already have undergone tilde expansion */ + filename = 0; + if (rl_filename_stat_hook) + { + filename = savestring (f); + (*rl_filename_stat_hook) (&filename); + name = filename; + } + +#if defined (HAVE_LSTAT) + stat_ok = lstat(name, &astat); +#else + stat_ok = stat(name, &astat); +#endif + if (stat_ok == 0) + { + mode = astat.st_mode; +#if defined (HAVE_LSTAT) + if (S_ISLNK (mode)) + { + linkok = stat (name, &linkstat) == 0; + if (linkok && strncmp (_rl_color_indicator[C_LINK].string, "target", 6) == 0) + mode = linkstat.st_mode; + } + else +#endif + linkok = 1; + } + else + linkok = -1; + + /* Is this a nonexistent file? If so, linkok == -1. */ + + if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL) + colored_filetype = C_MISSING; + else if (linkok == 0 && _rl_color_indicator[C_ORPHAN].string != NULL) + colored_filetype = C_ORPHAN; /* dangling symlink */ + else if(stat_ok != 0) + { + static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS; + colored_filetype = filetype_indicator[normal]; //f->filetype]; + } + else + { + if (S_ISREG (mode)) + { + colored_filetype = C_FILE; + +#if defined (S_ISUID) + if ((mode & S_ISUID) != 0 && is_colored (C_SETUID)) + colored_filetype = C_SETUID; + else +#endif +#if defined (S_ISGID) + if ((mode & S_ISGID) != 0 && is_colored (C_SETGID)) + colored_filetype = C_SETGID; + else +#endif + if (is_colored (C_CAP) && 0) //f->has_capability) + colored_filetype = C_CAP; + else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC)) + colored_filetype = C_EXEC; + else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK)) + colored_filetype = C_MULTIHARDLINK; + } + else if (S_ISDIR (mode)) + { + colored_filetype = C_DIR; + +#if defined (S_ISVTX) + if ((mode & S_ISVTX) && (mode & S_IWOTH) + && is_colored (C_STICKY_OTHER_WRITABLE)) + colored_filetype = C_STICKY_OTHER_WRITABLE; + else +#endif + if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE)) + colored_filetype = C_OTHER_WRITABLE; +#if defined (S_ISVTX) + else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY)) + colored_filetype = C_STICKY; +#endif + } +#if defined (S_ISLNK) + else if (S_ISLNK (mode)) + colored_filetype = C_LINK; +#endif + else if (S_ISFIFO (mode)) + colored_filetype = C_FIFO; +#if defined (S_ISSOCK) + else if (S_ISSOCK (mode)) + colored_filetype = C_SOCK; +#endif + else if (S_ISBLK (mode)) + colored_filetype = C_BLK; + else if (S_ISCHR (mode)) + colored_filetype = C_CHR; + else + { + /* Classify a file of some other type as C_ORPHAN. */ + colored_filetype = C_ORPHAN; + } + } + + /* Check the file's suffix only if still classified as C_FILE. */ + ext = NULL; + if (colored_filetype == C_FILE) + { + /* Test if NAME has a recognized suffix. */ + len = strlen (name); + name += len; /* Pointer to final \0. */ + for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next) + { + if (ext->ext.len <= len + && strncmp (name - ext->ext.len, ext->ext.string, + ext->ext.len) == 0) + break; + } + } + + free (filename); /* NULL or savestring return value */ + + { + const struct bin_str *const s + = ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype]; + if (s->string != NULL) + { + /* Need to reset so not dealing with attribute combinations */ + if (is_colored (C_NORM)) + restore_default_color (); + _rl_put_indicator (&_rl_color_indicator[C_LEFT]); + _rl_put_indicator (s); + _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); + return 0; + } + else + return 1; + } +} + +void +_rl_prep_non_filename_text (void) +{ + if (_rl_color_indicator[C_END].string != NULL) + _rl_put_indicator (&_rl_color_indicator[C_END]); + else + { + _rl_put_indicator (&_rl_color_indicator[C_LEFT]); + _rl_put_indicator (&_rl_color_indicator[C_RESET]); + _rl_put_indicator (&_rl_color_indicator[C_RIGHT]); + } +} +#endif /* COLOR_SUPPORT */ diff --git a/utshell-0.5.0/lib/readline/colors.h b/utshell-0.5.0/lib/readline/colors.h new file mode 100644 index 00000000..6561ad90 --- /dev/null +++ b/utshell-0.5.0/lib/readline/colors.h @@ -0,0 +1,126 @@ +/* `dir', `vdir' and `ls' directory listing programs for GNU. + + Modified by Chet Ramey for Readline. + + Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Richard Stallman and David MacKenzie. */ + +/* Color support by Peter Anvin and Dennis + Flaherty based on original patches by + Greg Lee . */ + +#ifndef _COLORS_H_ +#define _COLORS_H_ + +#include // size_t + +#if defined(__TANDEM) && defined(HAVE_STDBOOL_H) && (__STDC_VERSION__ < 199901L) +typedef int _Bool; +#endif + +#if defined (HAVE_STDBOOL_H) +# include // bool +#else +typedef int _rl_bool_t; + +#ifdef bool +# undef bool +#endif +#define bool _rl_bool_t + +#ifndef true +# define true 1 +# define false 0 +#endif + +#endif /* !HAVE_STDBOOL_H */ + +/* Null is a valid character in a color indicator (think about Epson + printers, for example) so we have to use a length/buffer string + type. */ +struct bin_str + { + size_t len; + const char *string; + }; + +/* file type indicators (dir, sock, fifo, ...) + Default value is initialized in parse-colors.c. + It is then modified from the values of $LS_COLORS. */ +extern struct bin_str _rl_color_indicator[]; + +/* The LS_COLORS variable is in a termcap-like format. */ +typedef struct _color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct _color_ext_type *next; /* Next in list */ + } COLOR_EXT_TYPE; + +/* file extensions indicators (.txt, .log, .jpg, ...) + Values are taken from $LS_COLORS in rl_parse_colors(). */ +extern COLOR_EXT_TYPE *_rl_color_ext_list; + +#define FILETYPE_INDICATORS \ + { \ + C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \ + C_LINK, C_SOCK, C_FILE, C_DIR \ + } + +/* Whether we used any colors in the output so far. If so, we will + need to restore the default color later. If not, we will need to + call prep_non_filename_text before using color for the first time. */ + +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, + C_FIFO, C_SOCK, + C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID, + C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK, + C_CLR_TO_EOL + }; + + +#if !S_IXUGO +# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) +#endif + +enum filetype + { + unknown, + fifo, + chardev, + directory, + blockdev, + normal, + symbolic_link, + sock, + whiteout, + arg_directory + }; + +/* Prefix color, currently same as socket */ +#define C_PREFIX C_SOCK + +extern void _rl_put_indicator (const struct bin_str *ind); +extern void _rl_set_normal_color (void); +extern bool _rl_print_prefix_color (void); +extern bool _rl_print_color_indicator (const char *f); +extern void _rl_prep_non_filename_text (void); + +#endif /* !_COLORS_H_ */ diff --git a/utshell-0.5.0/lib/readline/compat.c b/utshell-0.5.0/lib/readline/compat.c new file mode 100644 index 00000000..3ade3629 --- /dev/null +++ b/utshell-0.5.0/lib/readline/compat.c @@ -0,0 +1,106 @@ +/* compat.c -- backwards compatibility functions. */ + +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#include "rlstdc.h" +#include "rltypedefs.h" + +extern void rl_free_undo_list PARAMS((void)); +extern int rl_maybe_save_line PARAMS((void)); +extern int rl_maybe_unsave_line PARAMS((void)); +extern int rl_maybe_replace_line PARAMS((void)); + +extern int rl_crlf PARAMS((void)); +extern int rl_ding PARAMS((void)); +extern int rl_alphabetic PARAMS((int)); + +extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)); +extern char *rl_username_completion_function PARAMS((const char *, int)); +extern char *rl_filename_completion_function PARAMS((const char *, int)); + +/* Provide backwards-compatible entry points for old function names. */ + +void +free_undo_list (void) +{ + rl_free_undo_list (); +} + +int +maybe_replace_line (void) +{ + return rl_maybe_replace_line (); +} + +int +maybe_save_line (void) +{ + return rl_maybe_save_line (); +} + +int +maybe_unsave_line (void) +{ + return rl_maybe_unsave_line (); +} + +int +ding (void) +{ + return rl_ding (); +} + +int +crlf (void) +{ + return rl_crlf (); +} + +int +alphabetic (int c) +{ + return rl_alphabetic (c); +} + +char ** +completion_matches (const char *s, rl_compentry_func_t *f) +{ + return rl_completion_matches (s, f); +} + +char * +username_completion_function (const char *s, int i) +{ + return rl_username_completion_function (s, i); +} + +char * +filename_completion_function (const char *s, int i) +{ + return rl_filename_completion_function (s, i); +} diff --git a/utshell-0.5.0/lib/readline/complete.c b/utshell-0.5.0/lib/readline/complete.c new file mode 100644 index 00000000..fc5c3adb --- /dev/null +++ b/utshell-0.5.0/lib/readline/complete.c @@ -0,0 +1,2990 @@ +/* complete.c -- filename completion for readline. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (__TANDEM) +# define _XOPEN_SOURCE_EXTENDED 1 +#endif + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#if defined (__TANDEM) +# include +#endif +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if defined (HAVE_PWD_H) +#include +#endif + +#include "posixdir.h" +#include "posixstat.h" + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "xmalloc.h" +#include "rlprivate.h" + +#if defined (COLOR_SUPPORT) +# include "colors.h" +#endif + +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +#ifdef HAVE_LSTAT +# define LSTAT lstat +#else +# define LSTAT stat +#endif + +/* Unix version of a hidden file. Could be different on other systems. */ +#define HIDDEN_FILE(fname) ((fname)[0] == '.') + +/* Most systems don't declare getpwent in if _POSIX_SOURCE is + defined. */ +#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)) +extern struct passwd *getpwent PARAMS((void)); +#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */ + +/* If non-zero, then this is the address of a function to call when + completing a word would normally display the list of possible matches. + This function is called instead of actually doing the display. + It takes three arguments: (char **matches, int num_matches, int max_length) + where MATCHES is the array of strings that matched, NUM_MATCHES is the + number of strings in that array, and MAX_LENGTH is the length of the + longest string in that array. */ +rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL; + +#if defined (VISIBLE_STATS) || defined (COLOR_SUPPORT) +# if !defined (X_OK) +# define X_OK 1 +# endif +#endif + +#if defined (VISIBLE_STATS) +static int stat_char PARAMS((char *)); +#endif + +#if defined (COLOR_SUPPORT) +static int colored_stat_start PARAMS((const char *)); +static void colored_stat_end PARAMS((void)); +static int colored_prefix_start PARAMS((void)); +static void colored_prefix_end PARAMS((void)); +#endif + +static int path_isdir PARAMS((const char *)); + +static char *rl_quote_filename PARAMS((char *, int, char *)); + +static void _rl_complete_sigcleanup PARAMS((int, void *)); + +static void set_completion_defaults PARAMS((int)); +static int get_y_or_n PARAMS((int)); +static int _rl_internal_pager PARAMS((int)); +static char *printable_part PARAMS((char *)); +static int fnwidth PARAMS((const char *)); +static int fnprint PARAMS((const char *, int, const char *)); +static int print_filename PARAMS((char *, char *, int)); + +static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int)); + +static char **remove_duplicate_matches PARAMS((char **)); +static void insert_match PARAMS((char *, int, int, char *)); +static int append_to_match PARAMS((char *, int, int, int)); +static void insert_all_matches PARAMS((char **, int, char *)); +static int complete_fncmp PARAMS((const char *, int, const char *, int)); +static void display_matches PARAMS((char **)); +static int compute_lcd_of_matches PARAMS((char **, int, const char *)); +static int postprocess_matches PARAMS((char ***, int)); +static int compare_match PARAMS((char *, const char *)); +static int complete_get_screenwidth PARAMS((void)); + +static char *make_quoted_replacement PARAMS((char *, int, char *)); + +/* **************************************************************** */ +/* */ +/* Completion matching, from readline's point of view. */ +/* */ +/* **************************************************************** */ + +/* Variables known only to the readline library. */ + +/* If non-zero, non-unique completions always show the list of matches. */ +int _rl_complete_show_all = 0; + +/* If non-zero, non-unique completions show the list of matches, unless it + is not possible to do partial completion and modify the line. */ +int _rl_complete_show_unmodified = 0; + +/* If non-zero, completed directory names have a slash appended. */ +int _rl_complete_mark_directories = 1; + +/* If non-zero, the symlinked directory completion behavior introduced in + readline-4.2a is disabled, and symlinks that point to directories have + a slash appended (subject to the value of _rl_complete_mark_directories). + This is user-settable via the mark-symlinked-directories variable. */ +int _rl_complete_mark_symlink_dirs = 0; + +/* If non-zero, completions are printed horizontally in alphabetical order, + like `ls -x'. */ +int _rl_print_completions_horizontally; + +/* Non-zero means that case is not significant in filename completion. */ +#if (defined (__MSDOS__) && !defined (__DJGPP__)) || (defined (_WIN32) && !defined (__CYGWIN__)) +int _rl_completion_case_fold = 1; +#else +int _rl_completion_case_fold = 0; +#endif + +/* Non-zero means that `-' and `_' are equivalent when comparing filenames + for completion. */ +int _rl_completion_case_map = 0; + +/* If zero, don't match hidden files (filenames beginning with a `.' on + Unix) when doing filename completion. */ +int _rl_match_hidden_files = 1; + +/* Length in characters of a common prefix replaced with an ellipsis (`...') + when displaying completion matches. Matches whose printable portion has + more than this number of displaying characters in common will have the common + display prefix replaced with an ellipsis. */ +int _rl_completion_prefix_display_length = 0; + +/* The readline-private number of screen columns to use when displaying + matches. If < 0 or > _rl_screenwidth, it is ignored. */ +int _rl_completion_columns = -1; + +#if defined (COLOR_SUPPORT) +/* Non-zero means to use colors to indicate file type when listing possible + completions. The colors used are taken from $LS_COLORS, if set. */ +int _rl_colored_stats = 0; + +/* Non-zero means to use a color (currently magenta) to indicate the common + prefix of a set of possible word completions. */ +int _rl_colored_completion_prefix = 0; +#endif + +/* If non-zero, when completing in the middle of a word, don't insert + characters from the match that match characters following point in + the word. This means, for instance, completing when the cursor is + after the `e' in `Makefile' won't result in `Makefilefile'. */ +int _rl_skip_completed_text = 0; + +/* If non-zero, menu completion displays the common prefix first in the + cycle of possible completions instead of the last. */ +int _rl_menu_complete_prefix_first = 0; + +/* Global variables available to applications using readline. */ + +#if defined (VISIBLE_STATS) +/* Non-zero means add an additional character to each filename displayed + during listing completion iff rl_filename_completion_desired which helps + to indicate the type of file being listed. */ +int rl_visible_stats = 0; +#endif /* VISIBLE_STATS */ + +/* If non-zero, then this is the address of a function to call when + completing on a directory name. The function is called with + the address of a string (the current directory name) as an arg. */ +rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL; + +rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; + +rl_icppfunc_t *rl_filename_stat_hook = (rl_icppfunc_t *)NULL; + +/* If non-zero, this is the address of a function to call when reading + directory entries from the filesystem for completion and comparing + them to the partial word to be completed. The function should + either return its first argument (if no conversion takes place) or + newly-allocated memory. This can, for instance, convert filenames + between character sets for comparison against what's typed at the + keyboard. The returned value is what is added to the list of + matches. The second argument is the length of the filename to be + converted. */ +rl_dequote_func_t *rl_filename_rewrite_hook = (rl_dequote_func_t *)NULL; + +/* Non-zero means readline completion functions perform tilde expansion. */ +int rl_complete_with_tilde_expansion = 0; + +/* Pointer to the generator function for completion_matches (). + NULL means to use rl_filename_completion_function (), the default filename + completer. */ +rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL; + +/* Pointer to generator function for rl_menu_complete (). NULL means to use + *rl_completion_entry_function (see above). */ +rl_compentry_func_t *rl_menu_completion_entry_function = (rl_compentry_func_t *)NULL; + +/* Pointer to alternative function to create matches. + Function is called with TEXT, START, and END. + START and END are indices in RL_LINE_BUFFER saying what the boundaries + of TEXT are. + If this function exists and returns NULL then call the value of + rl_completion_entry_function to try to match, otherwise use the + array of strings returned. */ +rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL; + +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +int rl_attempted_completion_over = 0; + +/* Set to a character indicating the type of completion being performed + by rl_complete_internal, available for use by application completion + functions. */ +int rl_completion_type = 0; + +/* Up to this many items will be displayed in response to a + possible-completions call. After that, we ask the user if + she is sure she wants to see them all. A negative value means + don't ask. */ +int rl_completion_query_items = 100; + +int _rl_page_completions = 1; + +/* The basic list of characters that signal a break between words for the + completer routine. The contents of this variable is what breaks words + in the shell, i.e. " \t\n\"\\'`@$><=" */ +const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */ + +/* List of basic quoting characters. */ +const char *rl_basic_quote_characters = "\"'"; + +/* The list of characters that signal a break between words for + rl_complete_internal. The default list is the contents of + rl_basic_word_break_characters. */ +/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL; + +/* Hook function to allow an application to set the completion word + break characters before readline breaks up the line. Allows + position-dependent word break characters. */ +rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +const char *rl_completer_quote_characters = (const char *)NULL; + +/* List of characters that should be quoted in filenames by the completer. */ +const char *rl_filename_quote_characters = (const char *)NULL; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +const char *rl_special_prefixes = (const char *)NULL; + +/* If non-zero, then disallow duplicates in the matches. */ +int rl_ignore_completion_duplicates = 1; + +/* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ +int rl_filename_completion_desired = 0; + +/* Non-zero means that the results of the matches are to be quoted using + double quotes (or an application-specific quoting mechanism) if the + filename contains any characters in rl_filename_quote_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ +int rl_filename_quoting_desired = 1; + +/* This function, if defined, is called by the completer when real + filename completion is done, after all the matching names have been + generated. It is passed a (char**) known as matches in the code below. + It consists of a NULL-terminated array of pointers to potential + matching strings. The 1st element (matches[0]) is the maximal + substring that is common to all matches. This function can re-arrange + the list of matches as required, but all elements of the array must be + free()'d if they are deleted. The main intent of this function is + to implement FIGNORE a la SunOS csh. */ +rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL; + +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. Readline doesn't do anything + with this; it's set only by applications. */ +rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL; + +/* If non-zero, the completion functions don't append anything except a + possible closing quote. This is set to 0 by rl_complete_internal and + may be changed by an application-specific completion function. */ +int rl_completion_suppress_append = 0; + +/* Character appended to completed words when at the end of the line. The + default is a space. */ +int rl_completion_append_character = ' '; + +/* If non-zero, the completion functions don't append any closing quote. + This is set to 0 by rl_complete_internal and may be changed by an + application-specific completion function. */ +int rl_completion_suppress_quote = 0; + +/* Set to any quote character readline thinks it finds before any application + completion function is called. */ +int rl_completion_quote_character; + +/* Set to a non-zero value if readline found quoting anywhere in the word to + be completed; set before any application completion function is called. */ +int rl_completion_found_quote; + +/* If non-zero, a slash will be appended to completed filenames that are + symbolic links to directory names, subject to the value of the + mark-directories variable (which is user-settable). This exists so + that application completion functions can override the user's preference + (set via the mark-symlinked-directories variable) if appropriate. + It's set to the value of _rl_complete_mark_symlink_dirs in + rl_complete_internal before any application-specific completion + function is called, so without that function doing anything, the user's + preferences are honored. */ +int rl_completion_mark_symlink_dirs; + +/* If non-zero, inhibit completion (temporarily). */ +int rl_inhibit_completion; + +/* Set to the last key used to invoke one of the completion functions */ +int rl_completion_invoking_key; + +/* If non-zero, sort the completion matches. On by default. */ +int rl_sort_completion_matches = 1; + +/* Variables local to this file. */ + +/* Local variable states what happened during the last completion attempt. */ +static int completion_changed_buffer; +static int last_completion_failed = 0; + +/* The result of the query to the user about displaying completion matches */ +static int completion_y_or_n; + +static int _rl_complete_display_matches_interrupt = 0; + +/*************************************/ +/* */ +/* Bindable completion functions */ +/* */ +/*************************************/ + +/* Complete the word at or before point. You have supplied the function + that does the initial simple matching selection algorithm (see + rl_completion_matches ()). The default is to do filename completion. */ +int +rl_complete (int ignore, int invoking_key) +{ + rl_completion_invoking_key = invoking_key; + + if (rl_inhibit_completion) + return (_rl_insert_char (ignore, invoking_key)); +#if 0 + else if (rl_last_func == rl_complete && completion_changed_buffer == 0 && last_completion_failed == 0) +#else + else if (rl_last_func == rl_complete && completion_changed_buffer == 0) +#endif + return (rl_complete_internal ('?')); + else if (_rl_complete_show_all) + return (rl_complete_internal ('!')); + else if (_rl_complete_show_unmodified) + return (rl_complete_internal ('@')); + else + return (rl_complete_internal (TAB)); +} + +/* List the possible completions. See description of rl_complete (). */ +int +rl_possible_completions (int ignore, int invoking_key) +{ + rl_completion_invoking_key = invoking_key; + return (rl_complete_internal ('?')); +} + +int +rl_insert_completions (int ignore, int invoking_key) +{ + rl_completion_invoking_key = invoking_key; + return (rl_complete_internal ('*')); +} + +/* Return the correct value to pass to rl_complete_internal performing + the same tests as rl_complete. This allows consecutive calls to an + application's completion function to list possible completions and for + an application-specific completion function to honor the + show-all-if-ambiguous readline variable. */ +int +rl_completion_mode (rl_command_func_t *cfunc) +{ + if (rl_last_func == cfunc && !completion_changed_buffer) + return '?'; + else if (_rl_complete_show_all) + return '!'; + else if (_rl_complete_show_unmodified) + return '@'; + else + return TAB; +} + +/************************************/ +/* */ +/* Completion utility functions */ +/* */ +/************************************/ + +/* Reset public readline state on a signal or other event. */ +void +_rl_reset_completion_state (void) +{ + rl_completion_found_quote = 0; + rl_completion_quote_character = 0; +} + +static void +_rl_complete_sigcleanup (int sig, void *ptr) +{ + if (sig == SIGINT) /* XXX - for now */ + { + _rl_free_match_list ((char **)ptr); + _rl_complete_display_matches_interrupt = 1; + } +} + +/* Set default values for readline word completion. These are the variables + that application completion functions can change or inspect. */ +static void +set_completion_defaults (int what_to_do) +{ + /* Only the completion entry function can change these. */ + rl_filename_completion_desired = 0; + rl_filename_quoting_desired = 1; + rl_completion_type = what_to_do; + rl_completion_suppress_append = rl_completion_suppress_quote = 0; + rl_completion_append_character = ' '; + + /* The completion entry function may optionally change this. */ + rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs; + + /* Reset private state. */ + _rl_complete_display_matches_interrupt = 0; +} + +/* The user must press "y" or "n". Non-zero return means "y" pressed. */ +static int +get_y_or_n (int for_pager) +{ + int c; + + /* For now, disable pager in callback mode, until we later convert to state + driven functions. Have to wait until next major version to add new + state definition, since it will change value of RL_STATE_DONE. */ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return 1; +#endif + + for (;;) + { + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (c == 'y' || c == 'Y' || c == ' ') + return (1); + if (c == 'n' || c == 'N' || c == RUBOUT) + return (0); + if (c == ABORT_CHAR || c < 0) + _rl_abort_internal (); + if (for_pager && (c == NEWLINE || c == RETURN)) + return (2); + if (for_pager && (c == 'q' || c == 'Q')) + return (0); + rl_ding (); + } +} + +static int +_rl_internal_pager (int lines) +{ + int i; + + fprintf (rl_outstream, "--More--"); + fflush (rl_outstream); + i = get_y_or_n (1); + _rl_erase_entire_line (); + if (i == 0) + return -1; + else if (i == 2) + return (lines - 1); + else + return 0; +} + +static int +path_isdir (const char *filename) +{ + struct stat finfo; + + return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)); +} + +#if defined (VISIBLE_STATS) +/* Return the character which best describes FILENAME. + `@' for symbolic links + `/' for directories + `*' for executables + `=' for sockets + `|' for FIFOs + `%' for character special devices + `#' for block special devices */ +static int +stat_char (char *filename) +{ + struct stat finfo; + int character, r; + char *f; + const char *fn; + + /* Short-circuit a //server on cygwin, since that will always behave as + a directory. */ +#if __CYGWIN__ + if (filename[0] == '/' && filename[1] == '/' && strchr (filename+2, '/') == 0) + return '/'; +#endif + + f = 0; + if (rl_filename_stat_hook) + { + f = savestring (filename); + (*rl_filename_stat_hook) (&f); + fn = f; + } + else + fn = filename; + +#if defined (HAVE_LSTAT) && defined (S_ISLNK) + r = lstat (fn, &finfo); +#else + r = stat (fn, &finfo); +#endif + + if (r == -1) + { + xfree (f); + return (0); + } + + character = 0; + if (S_ISDIR (finfo.st_mode)) + character = '/'; +#if defined (S_ISCHR) + else if (S_ISCHR (finfo.st_mode)) + character = '%'; +#endif /* S_ISCHR */ +#if defined (S_ISBLK) + else if (S_ISBLK (finfo.st_mode)) + character = '#'; +#endif /* S_ISBLK */ +#if defined (S_ISLNK) + else if (S_ISLNK (finfo.st_mode)) + character = '@'; +#endif /* S_ISLNK */ +#if defined (S_ISSOCK) + else if (S_ISSOCK (finfo.st_mode)) + character = '='; +#endif /* S_ISSOCK */ +#if defined (S_ISFIFO) + else if (S_ISFIFO (finfo.st_mode)) + character = '|'; +#endif + else if (S_ISREG (finfo.st_mode)) + { +#if defined (_WIN32) && !defined (__CYGWIN__) + char *ext; + + /* Windows doesn't do access and X_OK; check file extension instead */ + ext = strrchr (fn, '.'); + if (ext && (_rl_stricmp (ext, ".exe") == 0 || + _rl_stricmp (ext, ".cmd") == 0 || + _rl_stricmp (ext, ".bat") == 0 || + _rl_stricmp (ext, ".com") == 0)) + character = '*'; +#else + if (access (filename, X_OK) == 0) + character = '*'; +#endif + } + + xfree (f); + return (character); +} +#endif /* VISIBLE_STATS */ + +#if defined (COLOR_SUPPORT) +static int +colored_stat_start (const char *filename) +{ + _rl_set_normal_color (); + return (_rl_print_color_indicator (filename)); +} + +static void +colored_stat_end (void) +{ + _rl_prep_non_filename_text (); + _rl_put_indicator (&_rl_color_indicator[C_CLR_TO_EOL]); +} + +static int +colored_prefix_start (void) +{ + _rl_set_normal_color (); + return (_rl_print_prefix_color ()); +} + +static void +colored_prefix_end (void) +{ + colored_stat_end (); /* for now */ +} +#endif + +/* Return the portion of PATHNAME that should be output when listing + possible completions. If we are hacking filename completion, we + are only interested in the basename, the portion following the + final slash. Otherwise, we return what we were passed. Since + printing empty strings is not very informative, if we're doing + filename completion, and the basename is the empty string, we look + for the previous slash and return the portion following that. If + there's no previous slash, we just return what we were passed. */ +static char * +printable_part (char *pathname) +{ + char *temp, *x; + + if (rl_filename_completion_desired == 0) /* don't need to do anything */ + return (pathname); + + temp = strrchr (pathname, '/'); +#if defined (__MSDOS__) || defined (_WIN32) + if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':') + temp = pathname + 1; +#endif + + if (temp == 0 || *temp == '\0') + return (pathname); + else if (temp[1] == 0 && temp == pathname) + return (pathname); + /* If the basename is NULL, we might have a pathname like '/usr/src/'. + Look for a previous slash and, if one is found, return the portion + following that slash. If there's no previous slash, just return the + pathname we were passed. */ + else if (temp[1] == '\0') + { + for (x = temp - 1; x > pathname; x--) + if (*x == '/') + break; + return ((*x == '/') ? x + 1 : pathname); + } + else + return ++temp; +} + +/* Compute width of STRING when displayed on screen by print_filename */ +static int +fnwidth (const char *string) +{ + int width, pos; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + int left, w; + size_t clen; + wchar_t wc; + + left = strlen (string) + 1; + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + width = pos = 0; + while (string[pos]) + { + if (CTRL_CHAR (string[pos]) || string[pos] == RUBOUT) + { + width += 2; + pos++; + } + else + { +#if defined (HANDLE_MULTIBYTE) + clen = mbrtowc (&wc, string + pos, left - pos, &ps); + if (MB_INVALIDCH (clen)) + { + width++; + pos++; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (clen)) + break; + else + { + pos += clen; + w = WCWIDTH (wc); + width += (w >= 0) ? w : 1; + } +#else + width++; + pos++; +#endif + } + } + + return width; +} + +#define ELLIPSIS_LEN 3 + +static int +fnprint (const char *to_print, int prefix_bytes, const char *real_pathname) +{ + int printed_len, w; + const char *s; + int common_prefix_len, print_len; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + const char *end; + size_t tlen; + int width; + wchar_t wc; + + print_len = strlen (to_print); + end = to_print + print_len + 1; + memset (&ps, 0, sizeof (mbstate_t)); +#else + print_len = strlen (to_print); +#endif + + printed_len = common_prefix_len = 0; + + /* Don't print only the ellipsis if the common prefix is one of the + possible completions. Only cut off prefix_bytes if we're going to be + printing the ellipsis, which takes precedence over coloring the + completion prefix (see print_filename() below). */ + if (_rl_completion_prefix_display_length > 0 && prefix_bytes >= print_len) + prefix_bytes = 0; + +#if defined (COLOR_SUPPORT) + if (_rl_colored_stats && (prefix_bytes == 0 || _rl_colored_completion_prefix <= 0)) + colored_stat_start (real_pathname); +#endif + + if (prefix_bytes && _rl_completion_prefix_display_length > 0) + { + char ellipsis; + + ellipsis = (to_print[prefix_bytes] == '.') ? '_' : '.'; + for (w = 0; w < ELLIPSIS_LEN; w++) + putc (ellipsis, rl_outstream); + printed_len = ELLIPSIS_LEN; + } +#if defined (COLOR_SUPPORT) + else if (prefix_bytes && _rl_colored_completion_prefix > 0) + { + common_prefix_len = prefix_bytes; + prefix_bytes = 0; + /* XXX - print color indicator start here */ + colored_prefix_start (); + } +#endif + + s = to_print + prefix_bytes; + while (*s) + { + if (CTRL_CHAR (*s)) + { + putc ('^', rl_outstream); + putc (UNCTRL (*s), rl_outstream); + printed_len += 2; + s++; +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + } + else if (*s == RUBOUT) + { + putc ('^', rl_outstream); + putc ('?', rl_outstream); + printed_len += 2; + s++; +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + } + else + { +#if defined (HANDLE_MULTIBYTE) + tlen = mbrtowc (&wc, s, end - s, &ps); + if (MB_INVALIDCH (tlen)) + { + tlen = 1; + width = 1; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (tlen)) + break; + else + { + w = WCWIDTH (wc); + width = (w >= 0) ? w : 1; + } + fwrite (s, 1, tlen, rl_outstream); + s += tlen; + printed_len += width; +#else + putc (*s, rl_outstream); + s++; + printed_len++; +#endif + } + if (common_prefix_len > 0 && (s - to_print) >= common_prefix_len) + { +#if defined (COLOR_SUPPORT) + /* printed bytes = s - to_print */ + /* printed bytes should never be > but check for paranoia's sake */ + colored_prefix_end (); + if (_rl_colored_stats) + colored_stat_start (real_pathname); /* XXX - experiment */ +#endif + common_prefix_len = 0; + } + } + +#if defined (COLOR_SUPPORT) + /* XXX - unconditional for now */ + if (_rl_colored_stats) + colored_stat_end (); +#endif + + return printed_len; +} + +/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we + are using it, check for and output a single character for `special' + filenames. Return the number of characters we output. */ + +static int +print_filename (char *to_print, char *full_pathname, int prefix_bytes) +{ + int printed_len, extension_char, slen, tlen; + char *s, c, *new_full_pathname, *dn; + + extension_char = 0; +#if defined (COLOR_SUPPORT) + /* Defer printing if we want to prefix with a color indicator */ + if (_rl_colored_stats == 0 || rl_filename_completion_desired == 0) +#endif + printed_len = fnprint (to_print, prefix_bytes, to_print); + + if (rl_filename_completion_desired && ( +#if defined (VISIBLE_STATS) + rl_visible_stats || +#endif +#if defined (COLOR_SUPPORT) + _rl_colored_stats || +#endif + _rl_complete_mark_directories)) + { + /* If to_print != full_pathname, to_print is the basename of the + path passed. In this case, we try to expand the directory + name before checking for the stat character. */ + if (to_print != full_pathname) + { + /* Terminate the directory name. */ + c = to_print[-1]; + to_print[-1] = '\0'; + + /* If setting the last slash in full_pathname to a NUL results in + full_pathname being the empty string, we are trying to complete + files in the root directory. If we pass a null string to the + bash directory completion hook, for example, it will expand it + to the current directory. We just want the `/'. */ + if (full_pathname == 0 || *full_pathname == 0) + dn = "/"; + else if (full_pathname[0] != '/') + dn = full_pathname; + else if (full_pathname[1] == 0) + dn = "//"; /* restore trailing slash to `//' */ + else if (full_pathname[1] == '/' && full_pathname[2] == 0) + dn = "/"; /* don't turn /// into // */ + else + dn = full_pathname; + s = tilde_expand (dn); + if (rl_directory_completion_hook) + (*rl_directory_completion_hook) (&s); + + slen = strlen (s); + tlen = strlen (to_print); + new_full_pathname = (char *)xmalloc (slen + tlen + 2); + strcpy (new_full_pathname, s); + if (s[slen - 1] == '/') + slen--; + else + new_full_pathname[slen] = '/'; + strcpy (new_full_pathname + slen + 1, to_print); + +#if defined (VISIBLE_STATS) + if (rl_visible_stats) + extension_char = stat_char (new_full_pathname); + else +#endif + if (_rl_complete_mark_directories) + { + dn = 0; + if (rl_directory_completion_hook == 0 && rl_filename_stat_hook) + { + dn = savestring (new_full_pathname); + (*rl_filename_stat_hook) (&dn); + xfree (new_full_pathname); + new_full_pathname = dn; + } + if (path_isdir (new_full_pathname)) + extension_char = '/'; + } + + /* Move colored-stats code inside fnprint() */ +#if defined (COLOR_SUPPORT) + if (_rl_colored_stats) + printed_len = fnprint (to_print, prefix_bytes, new_full_pathname); +#endif + + xfree (new_full_pathname); + to_print[-1] = c; + } + else + { + s = tilde_expand (full_pathname); +#if defined (VISIBLE_STATS) + if (rl_visible_stats) + extension_char = stat_char (s); + else +#endif + if (_rl_complete_mark_directories && path_isdir (s)) + extension_char = '/'; + + /* Move colored-stats code inside fnprint() */ +#if defined (COLOR_SUPPORT) + if (_rl_colored_stats) + printed_len = fnprint (to_print, prefix_bytes, s); +#endif + } + + xfree (s); + if (extension_char) + { + putc (extension_char, rl_outstream); + printed_len++; + } + } + + return printed_len; +} + +static char * +rl_quote_filename (char *s, int rtype, char *qcp) +{ + char *r; + + r = (char *)xmalloc (strlen (s) + 2); + *r = *rl_completer_quote_characters; + strcpy (r + 1, s); + if (qcp) + *qcp = *rl_completer_quote_characters; + return r; +} + +/* Find the bounds of the current word for completion purposes, and leave + rl_point set to the end of the word. This function skips quoted + substrings (characters between matched pairs of characters in + rl_completer_quote_characters). First we try to find an unclosed + quoted substring on which to do matching. If one is not found, we use + the word break characters to find the boundaries of the current word. + We call an application-specific function to decide whether or not a + particular word break character is quoted; if that function returns a + non-zero result, the character does not break a word. This function + returns the opening quote character if we found an unclosed quoted + substring, '\0' otherwise. FP, if non-null, is set to a value saying + which (shell-like) quote characters we found (single quote, double + quote, or backslash) anywhere in the string. DP, if non-null, is set to + the value of the delimiter character that caused a word break. */ + +char +_rl_find_completion_word (int *fp, int *dp) +{ + int scan, end, found_quote, delimiter, pass_next, isbrk; + char quote_char, *brkchars; + + end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + brkchars = 0; + if (rl_completion_word_break_hook) + brkchars = (*rl_completion_word_break_hook) (); + if (brkchars == 0) + brkchars = rl_completer_word_break_characters; + + if (rl_completer_quote_characters) + { + /* We have a list of characters which can be used in pairs to + quote substrings for the completer. Try to find the start + of an unclosed quoted substring. */ + /* FOUND_QUOTE is set so we know what kind of quotes we found. */ + for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY)) + { + if (pass_next) + { + pass_next = 0; + continue; + } + + /* Shell-like semantics for single quotes -- don't allow backslash + to quote anything in single quotes, especially not the closing + quote. If you don't like this, take out the check on the value + of quote_char. */ + if (quote_char != '\'' && rl_line_buffer[scan] == '\\') + { + pass_next = 1; + found_quote |= RL_QF_BACKSLASH; + continue; + } + + if (quote_char != '\0') + { + /* Ignore everything until the matching close quote char. */ + if (rl_line_buffer[scan] == quote_char) + { + /* Found matching close. Abandon this substring. */ + quote_char = '\0'; + rl_point = end; + } + } + else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan])) + { + /* Found start of a quoted substring. */ + quote_char = rl_line_buffer[scan]; + rl_point = scan + 1; + /* Shell-like quoting conventions. */ + if (quote_char == '\'') + found_quote |= RL_QF_SINGLE_QUOTE; + else if (quote_char == '"') + found_quote |= RL_QF_DOUBLE_QUOTE; + else + found_quote |= RL_QF_OTHER_QUOTE; + } + } + } + + if (rl_point == end && quote_char == '\0') + { + /* We didn't find an unclosed quoted substring upon which to do + completion, so use the word break characters to find the + substring on which to complete. */ + while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY)) + { + scan = rl_line_buffer[rl_point]; + + if (strchr (brkchars, scan) == 0) + continue; + + /* Call the application-specific function to tell us whether + this word break character is quoted and should be skipped. */ + if (rl_char_is_quoted_p && found_quote && + (*rl_char_is_quoted_p) (rl_line_buffer, rl_point)) + continue; + + /* Convoluted code, but it avoids an n^2 algorithm with calls + to char_is_quoted. */ + break; + } + } + + /* If we are at an unquoted word break, then advance past it. */ + scan = rl_line_buffer[rl_point]; + + /* If there is an application-specific function to say whether or not + a character is quoted and we found a quote character, let that + function decide whether or not a character is a word break, even + if it is found in rl_completer_word_break_characters. Don't bother + if we're at the end of the line, though. */ + if (scan) + { + if (rl_char_is_quoted_p) + isbrk = (found_quote == 0 || + (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) && + strchr (brkchars, scan) != 0; + else + isbrk = strchr (brkchars, scan) != 0; + + if (isbrk) + { + /* If the character that caused the word break was a quoting + character, then remember it as the delimiter. */ + if (rl_basic_quote_characters && + strchr (rl_basic_quote_characters, scan) && + (end - rl_point) > 1) + delimiter = scan; + + /* If the character isn't needed to determine something special + about what kind of completion to perform, then advance past it. */ + if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0) + rl_point++; + } + } + + if (fp) + *fp = found_quote; + if (dp) + *dp = delimiter; + + return (quote_char); +} + +static char ** +gen_completion_matches (char *text, int start, int end, rl_compentry_func_t *our_func, int found_quote, int quote_char) +{ + char **matches; + + rl_completion_found_quote = found_quote; + rl_completion_quote_character = quote_char; + + /* If the user wants to TRY to complete, but then wants to give + up and use the default completion function, they set the + variable rl_attempted_completion_function. */ + if (rl_attempted_completion_function) + { + matches = (*rl_attempted_completion_function) (text, start, end); + if (RL_SIG_RECEIVED()) + { + _rl_free_match_list (matches); + matches = 0; + RL_CHECK_SIGNALS (); + } + + if (matches || rl_attempted_completion_over) + { + rl_attempted_completion_over = 0; + return (matches); + } + } + + /* XXX -- filename dequoting moved into rl_filename_completion_function */ + + /* rl_completion_matches will check for signals as well to avoid a long + delay while reading a directory. */ + matches = rl_completion_matches (text, our_func); + if (RL_SIG_RECEIVED()) + { + _rl_free_match_list (matches); + matches = 0; + RL_CHECK_SIGNALS (); + } + return matches; +} + +/* Filter out duplicates in MATCHES. This frees up the strings in + MATCHES. */ +static char ** +remove_duplicate_matches (char **matches) +{ + char *lowest_common; + int i, j, newlen; + char dead_slot; + char **temp_array; + + /* Sort the items. */ + for (i = 0; matches[i]; i++) + ; + + /* Sort the array without matches[0], since we need it to + stay in place no matter what. */ + if (i && rl_sort_completion_matches) + qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + + /* Remember the lowest common denominator for it may be unique. */ + lowest_common = savestring (matches[0]); + + for (i = newlen = 0; matches[i + 1]; i++) + { + if (strcmp (matches[i], matches[i + 1]) == 0) + { + xfree (matches[i]); + matches[i] = (char *)&dead_slot; + } + else + newlen++; + } + + /* We have marked all the dead slots with (char *)&dead_slot. + Copy all the non-dead entries into a new array. */ + temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *)); + for (i = j = 1; matches[i]; i++) + { + if (matches[i] != (char *)&dead_slot) + temp_array[j++] = matches[i]; + } + temp_array[j] = (char *)NULL; + + if (matches[0] != (char *)&dead_slot) + xfree (matches[0]); + + /* Place the lowest common denominator back in [0]. */ + temp_array[0] = lowest_common; + + /* If there is one string left, and it is identical to the + lowest common denominator, then the LCD is the string to + insert. */ + if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0) + { + xfree (temp_array[1]); + temp_array[1] = (char *)NULL; + } + return (temp_array); +} + +/* Find the common prefix of the list of matches, and put it into + matches[0]. */ +static int +compute_lcd_of_matches (char **match_list, int matches, const char *text) +{ + register int i, c1, c2, si; + int low; /* Count of max-matched characters. */ + int lx; + char *dtext; /* dequoted TEXT, if needed */ +#if defined (HANDLE_MULTIBYTE) + int v; + size_t v1, v2; + mbstate_t ps1, ps2; + wchar_t wc1, wc2; +#endif + + /* If only one match, just use that. Otherwise, compare each + member of the list with the next, finding out where they + stop matching. */ + if (matches == 1) + { + match_list[0] = match_list[1]; + match_list[1] = (char *)NULL; + return 1; + } + + for (i = 1, low = 100000; i < matches; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + memset (&ps1, 0, sizeof (mbstate_t)); + memset (&ps2, 0, sizeof (mbstate_t)); + } +#endif + for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++) + { + if (_rl_completion_case_fold) + { + c1 = _rl_to_lower (c1); + c2 = _rl_to_lower (c2); + } +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + v1 = mbrtowc(&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1); + v2 = mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2); + if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) + { + if (c1 != c2) /* do byte comparison */ + break; + continue; + } + if (_rl_completion_case_fold) + { + wc1 = towlower (wc1); + wc2 = towlower (wc2); + } + if (wc1 != wc2) + break; + else if (v1 > 1) + si += v1 - 1; + } + else +#endif + if (c1 != c2) + break; + } + + if (low > si) + low = si; + } + + /* If there were multiple matches, but none matched up to even the + first character, and the user typed something, use that as the + value of matches[0]. */ + if (low == 0 && text && *text) + { + match_list[0] = (char *)xmalloc (strlen (text) + 1); + strcpy (match_list[0], text); + } + else + { + match_list[0] = (char *)xmalloc (low + 1); + + /* XXX - this might need changes in the presence of multibyte chars */ + + /* If we are ignoring case, try to preserve the case of the string + the user typed in the face of multiple matches differing in case. */ + if (_rl_completion_case_fold) + { + /* We're making an assumption here: + IF we're completing filenames AND + the application has defined a filename dequoting function AND + we found a quote character AND + the application has requested filename quoting + THEN + we assume that TEXT was dequoted before checking against + the file system and needs to be dequoted here before we + check against the list of matches + FI */ + dtext = (char *)NULL; + if (rl_filename_completion_desired && + rl_filename_dequoting_function && + rl_completion_found_quote && + rl_filename_quoting_desired) + { + dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); + text = dtext; + } + + /* sort the list to get consistent answers. */ + if (rl_sort_completion_matches) + qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); + + si = strlen (text); + lx = (si <= low) ? si : low; /* check shorter of text and matches */ + /* Try to preserve the case of what the user typed in the presence of + multiple matches: check each match for something that matches + what the user typed taking case into account; use it up to common + length of matches if one is found. If not, just use first match. */ + for (i = 1; i <= matches; i++) + if (strncmp (match_list[i], text, lx) == 0) + { + strncpy (match_list[0], match_list[i], low); + break; + } + /* no casematch, use first entry */ + if (i > matches) + strncpy (match_list[0], match_list[1], low); + + FREE (dtext); + } + else + strncpy (match_list[0], match_list[1], low); + + match_list[0][low] = '\0'; + } + + return matches; +} + +static int +postprocess_matches (char ***matchesp, int matching_filenames) +{ + char *t, **matches, **temp_matches; + int nmatch, i; + + matches = *matchesp; + + if (matches == 0) + return 0; + + /* It seems to me that in all the cases we handle we would like + to ignore duplicate possibilities. Scan for the text to + insert being identical to the other completions. */ + if (rl_ignore_completion_duplicates) + { + temp_matches = remove_duplicate_matches (matches); + xfree (matches); + matches = temp_matches; + } + + /* If we are matching filenames, then here is our chance to + do clever processing by re-examining the list. Call the + ignore function with the array as a parameter. It can + munge the array, deleting matches as it desires. */ + if (rl_ignore_some_completions_function && matching_filenames) + { + for (nmatch = 1; matches[nmatch]; nmatch++) + ; + (void)(*rl_ignore_some_completions_function) (matches); + if (matches == 0 || matches[0] == 0) + { + FREE (matches); + *matchesp = (char **)0; + return 0; + } + else + { + /* If we removed some matches, recompute the common prefix. */ + for (i = 1; matches[i]; i++) + ; + if (i > 1 && i < nmatch) + { + t = matches[0]; + compute_lcd_of_matches (matches, i - 1, t); + FREE (t); + } + } + } + + *matchesp = matches; + return (1); +} + +static int +complete_get_screenwidth (void) +{ + int cols; + char *envcols; + + cols = _rl_completion_columns; + if (cols >= 0 && cols <= _rl_screenwidth) + return cols; + envcols = getenv ("COLUMNS"); + if (envcols && *envcols) + cols = atoi (envcols); + if (cols >= 0 && cols <= _rl_screenwidth) + return cols; + return _rl_screenwidth; +} + +/* A convenience function for displaying a list of strings in + columnar format on readline's output stream. MATCHES is the list + of strings, in argv format, LEN is the number of strings in MATCHES, + and MAX is the length of the longest string in MATCHES. */ +void +rl_display_match_list (char **matches, int len, int max) +{ + int count, limit, printed_len, lines, cols; + int i, j, k, l, common_length, sind; + char *temp, *t; + + /* Find the length of the prefix common to all items: length as displayed + characters (common_length) and as a byte index into the matches (sind) */ + common_length = sind = 0; + if (_rl_completion_prefix_display_length > 0) + { + t = printable_part (matches[0]); + /* check again in case of /usr/src/ */ + temp = rl_filename_completion_desired ? strrchr (t, '/') : 0; + common_length = temp ? fnwidth (temp) : fnwidth (t); + sind = temp ? strlen (temp) : strlen (t); + if (common_length > max || sind > max) + common_length = sind = 0; + + if (common_length > _rl_completion_prefix_display_length && common_length > ELLIPSIS_LEN) + max -= common_length - ELLIPSIS_LEN; + else + common_length = sind = 0; + } +#if defined (COLOR_SUPPORT) + else if (_rl_colored_completion_prefix > 0) + { + t = printable_part (matches[0]); + temp = rl_filename_completion_desired ? strrchr (t, '/') : 0; + common_length = temp ? fnwidth (temp) : fnwidth (t); + sind = temp ? RL_STRLEN (temp+1) : RL_STRLEN (t); /* want portion after final slash */ + if (common_length > max || sind > max) + common_length = sind = 0; + } +#endif + + /* How many items of MAX length can we fit in the screen window? */ + cols = complete_get_screenwidth (); + max += 2; + limit = cols / max; + if (limit != 1 && (limit * max == cols)) + limit--; + + /* If cols == 0, limit will end up -1 */ + if (cols < _rl_screenwidth && limit < 0) + limit = 1; + + /* Avoid a possible floating exception. If max > cols, + limit will be 0 and a divide-by-zero fault will result. */ + if (limit == 0) + limit = 1; + + /* How many iterations of the printing loop? */ + count = (len + (limit - 1)) / limit; + + /* Watch out for special case. If LEN is less than LIMIT, then + just do the inner printing loop. + 0 < len <= limit implies count = 1. */ + + /* Sort the items if they are not already sorted. */ + if (rl_ignore_completion_duplicates == 0 && rl_sort_completion_matches) + qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + + rl_crlf (); + + lines = 0; + if (_rl_print_completions_horizontally == 0) + { + /* Print the sorted items, up-and-down alphabetically, like ls. */ + for (i = 1; i <= count; i++) + { + for (j = 0, l = i; j < limit; j++) + { + if (l > len || matches[l] == 0) + break; + else + { + temp = printable_part (matches[l]); + printed_len = print_filename (temp, matches[l], sind); + + if (j + 1 < limit) + { + if (max <= printed_len) + putc (' ', rl_outstream); + else + for (k = 0; k < max - printed_len; k++) + putc (' ', rl_outstream); + } + } + l += count; + } + rl_crlf (); +#if defined (SIGWINCH) + if (RL_SIG_RECEIVED () && RL_SIGWINCH_RECEIVED() == 0) +#else + if (RL_SIG_RECEIVED ()) +#endif + return; + lines++; + if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count) + { + lines = _rl_internal_pager (lines); + if (lines < 0) + return; + } + } + } + else + { + /* Print the sorted items, across alphabetically, like ls -x. */ + for (i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + printed_len = print_filename (temp, matches[i], sind); + /* Have we reached the end of this line? */ +#if defined (SIGWINCH) + if (RL_SIG_RECEIVED () && RL_SIGWINCH_RECEIVED() == 0) +#else + if (RL_SIG_RECEIVED ()) +#endif + return; + if (matches[i+1]) + { + if (limit == 1 || (i && (limit > 1) && (i % limit) == 0)) + { + rl_crlf (); + lines++; + if (_rl_page_completions && lines >= _rl_screenheight - 1) + { + lines = _rl_internal_pager (lines); + if (lines < 0) + return; + } + } + else if (max <= printed_len) + putc (' ', rl_outstream); + else + for (k = 0; k < max - printed_len; k++) + putc (' ', rl_outstream); + } + } + rl_crlf (); + } +} + +/* Display MATCHES, a list of matching filenames in argv format. This + handles the simple case -- a single match -- first. If there is more + than one match, we compute the number of strings in the list and the + length of the longest string, which will be needed by the display + function. If the application wants to handle displaying the list of + matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the + address of a function, and we just call it. If we're handling the + display ourselves, we just call rl_display_match_list. We also check + that the list of matches doesn't exceed the user-settable threshold, + and ask the user if he wants to see the list if there are more matches + than RL_COMPLETION_QUERY_ITEMS. */ +static void +display_matches (char **matches) +{ + int len, max, i; + char *temp; + + /* Move to the last visible line of a possibly-multiple-line command. */ + _rl_move_vert (_rl_vis_botlin); + + /* Handle simple case first. What if there is only one answer? */ + if (matches[1] == 0) + { + temp = printable_part (matches[0]); + rl_crlf (); + print_filename (temp, matches[0], 0); + rl_crlf (); + + rl_forced_update_display (); + rl_display_fixed = 1; + + return; + } + + /* There is more than one answer. Find out how many there are, + and find the maximum printed length of a single entry. */ + for (max = 0, i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + len = fnwidth (temp); + + if (len > max) + max = len; + } + + len = i - 1; + + /* If the caller has defined a display hook, then call that now. */ + if (rl_completion_display_matches_hook) + { + (*rl_completion_display_matches_hook) (matches, len, max); + return; + } + + /* If there are many items, then ask the user if she really wants to + see them all. */ + if (rl_completion_query_items > 0 && len >= rl_completion_query_items) + { + rl_crlf (); + fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len); + fflush (rl_outstream); + if ((completion_y_or_n = get_y_or_n (0)) == 0) + { + rl_crlf (); + + rl_forced_update_display (); + rl_display_fixed = 1; + + return; + } + } + + rl_display_match_list (matches, len, max); + + rl_forced_update_display (); + rl_display_fixed = 1; +} + +/* qc == pointer to quoting character, if any */ +static char * +make_quoted_replacement (char *match, int mtype, char *qc) +{ + int should_quote, do_replace; + char *replacement; + + /* If we are doing completion on quoted substrings, and any matches + contain any of the completer_word_break_characters, then auto- + matically prepend the substring with a quote character (just pick + the first one from the list of such) if it does not already begin + with a quote string. FIXME: Need to remove any such automatically + inserted quote character when it no longer is necessary, such as + if we change the string we are completing on and the new set of + matches don't require a quoted substring. */ + replacement = match; + + should_quote = match && rl_completer_quote_characters && + rl_filename_completion_desired && + rl_filename_quoting_desired; + + if (should_quote) + should_quote = should_quote && (!qc || !*qc || + (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc))); + + if (should_quote) + { + /* If there is a single match, see if we need to quote it. + This also checks whether the common prefix of several + matches needs to be quoted. */ + should_quote = rl_filename_quote_characters + ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0) + : 0; + + do_replace = should_quote ? mtype : NO_MATCH; + /* Quote the replacement, since we found an embedded + word break character in a potential match. */ + if (do_replace != NO_MATCH && rl_filename_quoting_function) + replacement = (*rl_filename_quoting_function) (match, do_replace, qc); + } + return (replacement); +} + +static void +insert_match (char *match, int start, int mtype, char *qc) +{ + char *replacement, *r; + char oqc; + int end, rlen; + + oqc = qc ? *qc : '\0'; + replacement = make_quoted_replacement (match, mtype, qc); + + /* Now insert the match. */ + if (replacement) + { + rlen = strlen (replacement); + /* Don't double an opening quote character. */ + if (qc && *qc && start && rl_line_buffer[start - 1] == *qc && + replacement[0] == *qc) + start--; + /* If make_quoted_replacement changed the quoting character, remove + the opening quote and insert the (fully-quoted) replacement. */ + else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc && + replacement[0] != oqc) + start--; + end = rl_point - 1; + /* Don't double a closing quote character */ + if (qc && *qc && end && rl_line_buffer[rl_point] == *qc && replacement[rlen - 1] == *qc) + end++; + if (_rl_skip_completed_text) + { + r = replacement; + while (start < rl_end && *r && rl_line_buffer[start] == *r) + { + start++; + r++; + } + if (start <= end || *r) + _rl_replace_text (r, start, end); + rl_point = start + strlen (r); + } + else + _rl_replace_text (replacement, start, end); + if (replacement != match) + xfree (replacement); + } +} + +/* Append any necessary closing quote and a separator character to the + just-inserted match. If the user has specified that directories + should be marked by a trailing `/', append one of those instead. The + default trailing character is a space. Returns the number of characters + appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS + has them) and don't add a suffix for a symlink to a directory. A + nontrivial match is one that actually adds to the word being completed. + The variable rl_completion_mark_symlink_dirs controls this behavior + (it's initially set to the what the user has chosen, indicated by the + value of _rl_complete_mark_symlink_dirs, but may be modified by an + application's completion function). */ +static int +append_to_match (char *text, int delimiter, int quote_char, int nontrivial_match) +{ + char temp_string[4], *filename, *fn; + int temp_string_index, s; + struct stat finfo; + + temp_string_index = 0; + if (quote_char && rl_point && rl_completion_suppress_quote == 0 && + rl_line_buffer[rl_point - 1] != quote_char) + temp_string[temp_string_index++] = quote_char; + + if (delimiter) + temp_string[temp_string_index++] = delimiter; + else if (rl_completion_suppress_append == 0 && rl_completion_append_character) + temp_string[temp_string_index++] = rl_completion_append_character; + + temp_string[temp_string_index++] = '\0'; + + if (rl_filename_completion_desired) + { + filename = tilde_expand (text); + if (rl_filename_stat_hook) + { + fn = savestring (filename); + (*rl_filename_stat_hook) (&fn); + xfree (filename); + filename = fn; + } + s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0) + ? LSTAT (filename, &finfo) + : stat (filename, &finfo); + if (s == 0 && S_ISDIR (finfo.st_mode)) + { + if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */) + { + /* This is clumsy. Avoid putting in a double slash if point + is at the end of the line and the previous character is a + slash. */ + if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/') + ; + else if (rl_line_buffer[rl_point] != '/') + rl_insert_text ("/"); + } + } +#ifdef S_ISLNK + /* Don't add anything if the filename is a symlink and resolves to a + directory. */ + else if (s == 0 && S_ISLNK (finfo.st_mode) && path_isdir (filename)) + ; +#endif + else + { + if (rl_point == rl_end && temp_string_index) + rl_insert_text (temp_string); + } + xfree (filename); + } + else + { + if (rl_point == rl_end && temp_string_index) + rl_insert_text (temp_string); + } + + return (temp_string_index); +} + +static void +insert_all_matches (char **matches, int point, char *qc) +{ + int i; + char *rp; + + rl_begin_undo_group (); + /* remove any opening quote character; make_quoted_replacement will add + it back. */ + if (qc && *qc && point && rl_line_buffer[point - 1] == *qc) + point--; + rl_delete_text (point, rl_point); + rl_point = point; + + if (matches[1]) + { + for (i = 1; matches[i]; i++) + { + rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc); + rl_insert_text (rp); + rl_insert_text (" "); + if (rp != matches[i]) + xfree (rp); + } + } + else + { + rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc); + rl_insert_text (rp); + rl_insert_text (" "); + if (rp != matches[0]) + xfree (rp); + } + rl_end_undo_group (); +} + +void +_rl_free_match_list (char **matches) +{ + register int i; + + if (matches == 0) + return; + + for (i = 0; matches[i]; i++) + xfree (matches[i]); + xfree (matches); +} + +/* Compare a possibly-quoted filename TEXT from the line buffer and a possible + MATCH that is the product of filename completion, which acts on the dequoted + text. */ +static int +compare_match (char *text, const char *match) +{ + char *temp; + int r; + + if (rl_filename_completion_desired && rl_filename_quoting_desired && + rl_completion_found_quote && rl_filename_dequoting_function) + { + temp = (*rl_filename_dequoting_function) (text, rl_completion_quote_character); + r = strcmp (temp, match); + free (temp); + return r; + } + return (strcmp (text, match)); +} + +/* Complete the word at or before point. + WHAT_TO_DO says what to do with the completion. + `?' means list the possible completions. + TAB means do standard completion. + `*' means insert all of the possible completions. + `!' means to do standard completion, and list all possible completions if + there is more than one. + `@' means to do standard completion, and list all possible completions if + there is more than one and partial completion is not possible. */ +int +rl_complete_internal (int what_to_do) +{ + char **matches; + rl_compentry_func_t *our_func; + int start, end, delimiter, found_quote, i, nontrivial_lcd; + char *text, *saved_line_buffer; + char quote_char; + int tlen, mlen, saved_last_completion_failed; + + RL_SETSTATE(RL_STATE_COMPLETING); + + saved_last_completion_failed = last_completion_failed; + + set_completion_defaults (what_to_do); + + saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL; + our_func = rl_completion_entry_function + ? rl_completion_entry_function + : rl_filename_completion_function; + /* We now look backwards for the start of a filename/variable word. */ + end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = _rl_find_completion_word (&found_quote, &delimiter); + + start = rl_point; + rl_point = end; + + text = rl_copy_text (start, end); + matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char); + /* nontrivial_lcd is set if the common prefix adds something to the word + being completed. */ + nontrivial_lcd = matches && compare_match (text, matches[0]) != 0; + if (what_to_do == '!' || what_to_do == '@') + tlen = strlen (text); + xfree (text); + + if (matches == 0) + { + rl_ding (); + FREE (saved_line_buffer); + completion_changed_buffer = 0; + last_completion_failed = 1; + RL_UNSETSTATE(RL_STATE_COMPLETING); + _rl_reset_completion_state (); + return (0); + } + + /* If we are matching filenames, the attempted completion function will + have set rl_filename_completion_desired to a non-zero value. The basic + rl_filename_completion_function does this. */ + i = rl_filename_completion_desired; + + if (postprocess_matches (&matches, i) == 0) + { + rl_ding (); + FREE (saved_line_buffer); + completion_changed_buffer = 0; + last_completion_failed = 1; + RL_UNSETSTATE(RL_STATE_COMPLETING); + _rl_reset_completion_state (); + return (0); + } + + if (matches && matches[0] && *matches[0]) + last_completion_failed = 0; + + switch (what_to_do) + { + case TAB: + case '!': + case '@': + /* Insert the first match with proper quoting. */ + if (what_to_do == TAB) + { + if (*matches[0]) + insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); + } + else if (*matches[0] && matches[1] == 0) + /* should we perform the check only if there are multiple matches? */ + insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); + else if (*matches[0]) /* what_to_do != TAB && multiple matches */ + { + mlen = *matches[0] ? strlen (matches[0]) : 0; + if (mlen >= tlen) + insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); + } + + /* If there are more matches, ring the bell to indicate. + If we are in vi mode, Posix.2 says to not ring the bell. + If the `show-all-if-ambiguous' variable is set, display + all the matches immediately. Otherwise, if this was the + only match, and we are hacking files, check the file to + see if it was a directory. If so, and the `mark-directories' + variable is set, add a '/' to the name. If not, and we + are at the end of the line, then add a space. */ + if (matches[1]) + { + if (what_to_do == '!') + { + display_matches (matches); + break; + } + else if (what_to_do == '@') + { + if (nontrivial_lcd == 0) + display_matches (matches); + break; + } + else if (rl_editing_mode != vi_mode) + rl_ding (); /* There are other matches remaining. */ + } + else + append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd); + + break; + + case '*': + insert_all_matches (matches, start, "e_char); + break; + + case '?': + /* Let's try to insert a single match here if the last completion failed + but this attempt returned a single match. */ + if (saved_last_completion_failed && matches[0] && *matches[0] && matches[1] == 0) + { + insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); + append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd); + break; + } + + if (rl_completion_display_matches_hook == 0) + { + _rl_sigcleanup = _rl_complete_sigcleanup; + _rl_sigcleanarg = matches; + _rl_complete_display_matches_interrupt = 0; + } + display_matches (matches); + if (_rl_complete_display_matches_interrupt) + { + matches = 0; /* already freed by rl_complete_sigcleanup */ + _rl_complete_display_matches_interrupt = 0; + if (rl_signal_event_hook) + (*rl_signal_event_hook) (); /* XXX */ + } + _rl_sigcleanup = 0; + _rl_sigcleanarg = 0; + break; + + default: + _rl_ttymsg ("bad value %d for what_to_do in rl_complete", what_to_do); + rl_ding (); + FREE (saved_line_buffer); + RL_UNSETSTATE(RL_STATE_COMPLETING); + _rl_free_match_list (matches); + _rl_reset_completion_state (); + return 1; + } + + _rl_free_match_list (matches); + + /* Check to see if the line has changed through all of this manipulation. */ + if (saved_line_buffer) + { + completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0; + xfree (saved_line_buffer); + } + + RL_UNSETSTATE(RL_STATE_COMPLETING); + _rl_reset_completion_state (); + + RL_CHECK_SIGNALS (); + return 0; +} + +/***************************************************************/ +/* */ +/* Application-callable completion match generator functions */ +/* */ +/***************************************************************/ + +/* Return an array of (char *) which is a list of completions for TEXT. + If there are no completions, return a NULL pointer. + The first entry in the returned array is the substitution for TEXT. + The remaining entries are the possible completions. + The array is terminated with a NULL pointer. + + ENTRY_FUNCTION is a function of two args, and returns a (char *). + The first argument is TEXT. + The second is a state argument; it should be zero on the first call, and + non-zero on subsequent calls. It returns a NULL pointer to the caller + when there are no more matches. + */ +char ** +rl_completion_matches (const char *text, rl_compentry_func_t *entry_function) +{ + register int i; + + /* Number of slots in match_list. */ + int match_list_size; + + /* The list of matches. */ + char **match_list; + + /* Number of matches actually found. */ + int matches; + + /* Temporary string binder. */ + char *string; + + matches = 0; + match_list_size = 10; + match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); + match_list[1] = (char *)NULL; + + while (string = (*entry_function) (text, matches)) + { + if (RL_SIG_RECEIVED ()) + { + /* Start at 1 because we don't set matches[0] in this function. + Only free the list members if we're building match list from + rl_filename_completion_function, since we know that doesn't + free the strings it returns. */ + if (entry_function == rl_filename_completion_function) + { + for (i = 1; match_list[i]; i++) + xfree (match_list[i]); + } + xfree (match_list); + match_list = 0; + match_list_size = 0; + matches = 0; + RL_CHECK_SIGNALS (); + } + + if (matches + 1 >= match_list_size) + match_list = (char **)xrealloc + (match_list, ((match_list_size += 10) + 1) * sizeof (char *)); + + if (match_list == 0) + return (match_list); + + match_list[++matches] = string; + match_list[matches + 1] = (char *)NULL; + } + + /* If there were any matches, then look through them finding out the + lowest common denominator. That then becomes match_list[0]. */ + if (matches) + compute_lcd_of_matches (match_list, matches, text); + else /* There were no matches. */ + { + xfree (match_list); + match_list = (char **)NULL; + } + return (match_list); +} + +/* A completion function for usernames. + TEXT contains a partial username preceded by a random + character (usually `~'). */ +char * +rl_username_completion_function (const char *text, int state) +{ +#if defined (__WIN32__) || defined (__OPENNT) + return (char *)NULL; +#else /* !__WIN32__ && !__OPENNT) */ + static char *username = (char *)NULL; + static struct passwd *entry; + static int namelen, first_char, first_char_loc; + char *value; + + if (state == 0) + { + FREE (username); + + first_char = *text; + first_char_loc = first_char == '~'; + + username = savestring (&text[first_char_loc]); + namelen = strlen (username); +#if defined (HAVE_GETPWENT) + setpwent (); +#endif + } + +#if defined (HAVE_GETPWENT) + while (entry = getpwent ()) + { + /* Null usernames should result in all users as possible completions. */ + if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) + break; + } +#endif + + if (entry == 0) + { +#if defined (HAVE_GETPWENT) + endpwent (); +#endif + return ((char *)NULL); + } + else + { + value = (char *)xmalloc (2 + strlen (entry->pw_name)); + + *value = *text; + + strcpy (value + first_char_loc, entry->pw_name); + + if (first_char == '~') + rl_filename_completion_desired = 1; + + return (value); + } +#endif /* !__WIN32__ && !__OPENNT */ +} + +/* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME + (FILENAME_LEN). If _rl_completion_case_fold is set, compare without + regard to the alphabetic case of characters. If + _rl_completion_case_map is set, make `-' and `_' equivalent. CONVFN is + the possibly-converted directory entry; FILENAME is what the user typed. */ +static int +complete_fncmp (const char *convfn, int convlen, const char *filename, int filename_len) +{ + register char *s1, *s2; + int d, len; +#if defined (HANDLE_MULTIBYTE) + size_t v1, v2; + mbstate_t ps1, ps2; + wchar_t wc1, wc2; +#endif + +#if defined (HANDLE_MULTIBYTE) + memset (&ps1, 0, sizeof (mbstate_t)); + memset (&ps2, 0, sizeof (mbstate_t)); +#endif + + if (filename_len == 0) + return 1; + if (convlen < filename_len) + return 0; + + len = filename_len; + s1 = (char *)convfn; + s2 = (char *)filename; + + /* Otherwise, if these match up to the length of filename, then + it is a match. */ + if (_rl_completion_case_fold && _rl_completion_case_map) + { + /* Case-insensitive comparison treating _ and - as equivalent */ +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + do + { + v1 = mbrtowc (&wc1, s1, convlen, &ps1); + v2 = mbrtowc (&wc2, s2, filename_len, &ps2); + if (v1 == 0 && v2 == 0) + return 1; + else if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) + { + if (*s1 != *s2) /* do byte comparison */ + return 0; + else if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_')) + return 0; + s1++; s2++; len--; + continue; + } + wc1 = towlower (wc1); + wc2 = towlower (wc2); + s1 += v1; + s2 += v1; + len -= v1; + if ((wc1 == L'-' || wc1 == L'_') && (wc2 == L'-' || wc2 == L'_')) + continue; + if (wc1 != wc2) + return 0; + } + while (len != 0); + } + else +#endif + { + do + { + d = _rl_to_lower (*s1) - _rl_to_lower (*s2); + /* *s1 == [-_] && *s2 == [-_] */ + if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_')) + d = 0; + if (d != 0) + return 0; + s1++; s2++; /* already checked convlen >= filename_len */ + } + while (--len != 0); + } + + return 1; + } + else if (_rl_completion_case_fold) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + do + { + v1 = mbrtowc (&wc1, s1, convlen, &ps1); + v2 = mbrtowc (&wc2, s2, filename_len, &ps2); + if (v1 == 0 && v2 == 0) + return 1; + else if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) + { + if (*s1 != *s2) /* do byte comparison */ + return 0; + s1++; s2++; len--; + continue; + } + wc1 = towlower (wc1); + wc2 = towlower (wc2); + if (wc1 != wc2) + return 0; + s1 += v1; + s2 += v1; + len -= v1; + } + while (len != 0); + return 1; + } + else +#endif + if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) && + (convlen >= filename_len) && + (_rl_strnicmp (filename, convfn, filename_len) == 0)) + return 1; + } + else + { + if ((convfn[0] == filename[0]) && + (convlen >= filename_len) && + (strncmp (filename, convfn, filename_len) == 0)) + return 1; + } + return 0; +} + +/* Okay, now we write the entry_function for filename completion. In the + general case. Note that completion in the shell is a little different + because of all the pathnames that must be followed when looking up the + completion for a command. */ +char * +rl_filename_completion_function (const char *text, int state) +{ + static DIR *directory = (DIR *)NULL; + static char *filename = (char *)NULL; + static char *dirname = (char *)NULL; + static char *users_dirname = (char *)NULL; + static int filename_len; + char *temp, *dentry, *convfn; + int dirlen, dentlen, convlen; + int tilde_dirname; + struct dirent *entry; + + /* If we don't have any state, then do some initialization. */ + if (state == 0) + { + /* If we were interrupted before closing the directory or reading + all of its contents, close it. */ + if (directory) + { + closedir (directory); + directory = (DIR *)NULL; + } + FREE (dirname); + FREE (filename); + FREE (users_dirname); + + filename = savestring (text); + if (*text == 0) + text = "."; + dirname = savestring (text); + + temp = strrchr (dirname, '/'); + +#if defined (__MSDOS__) || defined (_WIN32) + /* special hack for //X/... */ + if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/') + temp = strrchr (dirname + 3, '/'); +#endif + + if (temp) + { + strcpy (filename, ++temp); + *temp = '\0'; + } +#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN__)) + /* searches from current directory on the drive */ + else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':') + { + strcpy (filename, dirname + 2); + dirname[2] = '\0'; + } +#endif + else + { + dirname[0] = '.'; + dirname[1] = '\0'; + } + + /* We aren't done yet. We also support the "~user" syntax. */ + + /* Save the version of the directory that the user typed, dequoting + it if necessary. */ + if (rl_completion_found_quote && rl_filename_dequoting_function) + users_dirname = (*rl_filename_dequoting_function) (dirname, rl_completion_quote_character); + else + users_dirname = savestring (dirname); + + tilde_dirname = 0; + if (*dirname == '~') + { + temp = tilde_expand (dirname); + xfree (dirname); + dirname = temp; + tilde_dirname = 1; + } + + /* We have saved the possibly-dequoted version of the directory name + the user typed. Now transform the directory name we're going to + pass to opendir(2). The directory rewrite hook modifies only the + directory name; the directory completion hook modifies both the + directory name passed to opendir(2) and the version the user + typed. Both the directory completion and rewrite hooks should perform + any necessary dequoting. The hook functions return 1 if they modify + the directory name argument. If either hook returns 0, it should + not modify the directory name pointer passed as an argument. */ + if (rl_directory_rewrite_hook) + (*rl_directory_rewrite_hook) (&dirname); + else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname)) + { + xfree (users_dirname); + users_dirname = savestring (dirname); + } + else if (tilde_dirname == 0 && rl_completion_found_quote && rl_filename_dequoting_function) + { + /* delete single and double quotes */ + xfree (dirname); + dirname = savestring (users_dirname); + } + directory = opendir (dirname); + + /* Now dequote a non-null filename. FILENAME will not be NULL, but may + be empty. */ + if (*filename && rl_completion_found_quote && rl_filename_dequoting_function) + { + /* delete single and double quotes */ + temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character); + xfree (filename); + filename = temp; + } + filename_len = strlen (filename); + + rl_filename_completion_desired = 1; + } + + /* At this point we should entertain the possibility of hacking wildcarded + filenames, like /usr/man/man/te. If the directory name + contains globbing characters, then build an array of directories, and + then map over that list while completing. */ + /* *** UNIMPLEMENTED *** */ + + /* Now that we have some state, we can read the directory. */ + + entry = (struct dirent *)NULL; + while (directory && (entry = readdir (directory))) + { + convfn = dentry = entry->d_name; + convlen = dentlen = D_NAMLEN (entry); + + if (rl_filename_rewrite_hook) + { + convfn = (*rl_filename_rewrite_hook) (dentry, dentlen); + convlen = (convfn == dentry) ? dentlen : strlen (convfn); + } + + /* Special case for no filename. If the user has disabled the + `match-hidden-files' variable, skip filenames beginning with `.'. + All other entries except "." and ".." match. */ + if (filename_len == 0) + { + if (_rl_match_hidden_files == 0 && HIDDEN_FILE (convfn)) + continue; + + if (convfn[0] != '.' || + (convfn[1] && (convfn[1] != '.' || convfn[2]))) + break; + } + else + { + if (complete_fncmp (convfn, convlen, filename, filename_len)) + break; + } + } + + if (entry == 0) + { + if (directory) + { + closedir (directory); + directory = (DIR *)NULL; + } + if (dirname) + { + xfree (dirname); + dirname = (char *)NULL; + } + if (filename) + { + xfree (filename); + filename = (char *)NULL; + } + if (users_dirname) + { + xfree (users_dirname); + users_dirname = (char *)NULL; + } + + return (char *)NULL; + } + else + { + /* dirname && (strcmp (dirname, ".") != 0) */ + if (dirname && (dirname[0] != '.' || dirname[1])) + { + if (rl_complete_with_tilde_expansion && *users_dirname == '~') + { + dirlen = strlen (dirname); + temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry)); + strcpy (temp, dirname); + /* Canonicalization cuts off any final slash present. We + may need to add it back. */ + if (dirname[dirlen - 1] != '/') + { + temp[dirlen++] = '/'; + temp[dirlen] = '\0'; + } + } + else + { + dirlen = strlen (users_dirname); + temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry)); + strcpy (temp, users_dirname); + /* Make sure that temp has a trailing slash here. */ + if (users_dirname[dirlen - 1] != '/') + temp[dirlen++] = '/'; + } + + strcpy (temp + dirlen, convfn); + } + else + temp = savestring (convfn); + + if (convfn != dentry) + xfree (convfn); + + return (temp); + } +} + +/* An initial implementation of a menu completion function a la tcsh. The + first time (if the last readline command was not rl_old_menu_complete), we + generate the list of matches. This code is very similar to the code in + rl_complete_internal -- there should be a way to combine the two. Then, + for each item in the list of matches, we insert the match in an undoable + fashion, with the appropriate character appended (this happens on the + second and subsequent consecutive calls to rl_old_menu_complete). When we + hit the end of the match list, we restore the original unmatched text, + ring the bell, and reset the counter to zero. */ +int +rl_old_menu_complete (int count, int invoking_key) +{ + rl_compentry_func_t *our_func; + int matching_filenames, found_quote; + + static char *orig_text; + static char **matches = (char **)0; + static int match_list_index = 0; + static int match_list_size = 0; + static int orig_start, orig_end; + static char quote_char; + static int delimiter; + + /* The first time through, we generate the list of matches and set things + up to insert them. */ + if (rl_last_func != rl_old_menu_complete) + { + /* Clean up from previous call, if any. */ + FREE (orig_text); + if (matches) + _rl_free_match_list (matches); + + match_list_index = match_list_size = 0; + matches = (char **)NULL; + + rl_completion_invoking_key = invoking_key; + + RL_SETSTATE(RL_STATE_COMPLETING); + + /* Only the completion entry function can change these. */ + set_completion_defaults ('%'); + + our_func = rl_menu_completion_entry_function; + if (our_func == 0) + our_func = rl_completion_entry_function + ? rl_completion_entry_function + : rl_filename_completion_function; + + /* We now look backwards for the start of a filename/variable word. */ + orig_end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = _rl_find_completion_word (&found_quote, &delimiter); + + orig_start = rl_point; + rl_point = orig_end; + + orig_text = rl_copy_text (orig_start, orig_end); + matches = gen_completion_matches (orig_text, orig_start, orig_end, + our_func, found_quote, quote_char); + + /* If we are matching filenames, the attempted completion function will + have set rl_filename_completion_desired to a non-zero value. The basic + rl_filename_completion_function does this. */ + matching_filenames = rl_filename_completion_desired; + + if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + FREE (orig_text); + orig_text = (char *)0; + completion_changed_buffer = 0; + RL_UNSETSTATE(RL_STATE_COMPLETING); + return (0); + } + + RL_UNSETSTATE(RL_STATE_COMPLETING); + + for (match_list_size = 0; matches[match_list_size]; match_list_size++) + ; + /* matches[0] is lcd if match_list_size > 1, but the circular buffer + code below should take care of it. */ + + if (match_list_size > 1 && _rl_complete_show_all) + display_matches (matches); + } + + /* Now we have the list of matches. Replace the text between + rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with + matches[match_list_index], and add any necessary closing char. */ + + if (matches == 0 || match_list_size == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + completion_changed_buffer = 0; + return (0); + } + + match_list_index += count; + if (match_list_index < 0) + { + while (match_list_index < 0) + match_list_index += match_list_size; + } + else + match_list_index %= match_list_size; + + if (match_list_index == 0 && match_list_size > 1) + { + rl_ding (); + insert_match (orig_text, orig_start, MULT_MATCH, "e_char); + } + else + { + insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); + append_to_match (matches[match_list_index], delimiter, quote_char, + compare_match (orig_text, matches[match_list_index])); + } + + completion_changed_buffer = 1; + return (0); +} + +/* The current version of menu completion. + The differences between this function and the original are: + +1. It honors the maximum number of completions variable (completion-query-items) +2. It appends to the word as usual if there is only one match +3. It displays the common prefix if there is one, and makes it the first menu + choice if the menu-complete-display-prefix option is enabled +*/ + +int +rl_menu_complete (int count, int ignore) +{ + rl_compentry_func_t *our_func; + int matching_filenames, found_quote; + + static char *orig_text; + static char **matches = (char **)0; + static int match_list_index = 0; + static int match_list_size = 0; + static int nontrivial_lcd = 0; + static int full_completion = 0; /* set to 1 if menu completion should reinitialize on next call */ + static int orig_start, orig_end; + static char quote_char; + static int delimiter, cstate; + + /* The first time through, we generate the list of matches and set things + up to insert them. */ + if ((rl_last_func != rl_menu_complete && rl_last_func != rl_backward_menu_complete) || full_completion) + { + /* Clean up from previous call, if any. */ + FREE (orig_text); + if (matches) + _rl_free_match_list (matches); + + match_list_index = match_list_size = 0; + matches = (char **)NULL; + + full_completion = 0; + + RL_SETSTATE(RL_STATE_COMPLETING); + + /* Only the completion entry function can change these. */ + set_completion_defaults ('%'); + + our_func = rl_menu_completion_entry_function; + if (our_func == 0) + our_func = rl_completion_entry_function + ? rl_completion_entry_function + : rl_filename_completion_function; + + /* We now look backwards for the start of a filename/variable word. */ + orig_end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = _rl_find_completion_word (&found_quote, &delimiter); + + orig_start = rl_point; + rl_point = orig_end; + + orig_text = rl_copy_text (orig_start, orig_end); + matches = gen_completion_matches (orig_text, orig_start, orig_end, + our_func, found_quote, quote_char); + + nontrivial_lcd = matches && compare_match (orig_text, matches[0]) != 0; + + /* If we are matching filenames, the attempted completion function will + have set rl_filename_completion_desired to a non-zero value. The basic + rl_filename_completion_function does this. */ + matching_filenames = rl_filename_completion_desired; + + if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + FREE (orig_text); + orig_text = (char *)0; + completion_changed_buffer = 0; + RL_UNSETSTATE(RL_STATE_COMPLETING); + return (0); + } + + RL_UNSETSTATE(RL_STATE_COMPLETING); + + for (match_list_size = 0; matches[match_list_size]; match_list_size++) + ; + + if (match_list_size == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + match_list_index = 0; + completion_changed_buffer = 0; + return (0); + } + + /* matches[0] is lcd if match_list_size > 1, but the circular buffer + code below should take care of it. */ + if (*matches[0]) + { + insert_match (matches[0], orig_start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); + orig_end = orig_start + strlen (matches[0]); + completion_changed_buffer = STREQ (orig_text, matches[0]) == 0; + } + + if (match_list_size > 1 && _rl_complete_show_all) + { + display_matches (matches); + /* If there are so many matches that the user has to be asked + whether or not he wants to see the matches, menu completion + is unwieldy. */ + if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + full_completion = 1; + return (0); + } + else if (_rl_menu_complete_prefix_first) + { + rl_ding (); + return (0); + } + } + else if (match_list_size <= 1) + { + append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd); + full_completion = 1; + return (0); + } + else if (_rl_menu_complete_prefix_first && match_list_size > 1) + { + rl_ding (); + return (0); + } + } + + /* Now we have the list of matches. Replace the text between + rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with + matches[match_list_index], and add any necessary closing char. */ + + if (matches == 0 || match_list_size == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + completion_changed_buffer = 0; + return (0); + } + + match_list_index += count; + if (match_list_index < 0) + { + while (match_list_index < 0) + match_list_index += match_list_size; + } + else + match_list_index %= match_list_size; + + if (match_list_index == 0 && match_list_size > 1) + { + rl_ding (); + insert_match (matches[0], orig_start, MULT_MATCH, "e_char); + } + else + { + insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); + append_to_match (matches[match_list_index], delimiter, quote_char, + compare_match (orig_text, matches[match_list_index])); + } + + completion_changed_buffer = 1; + return (0); +} + +int +rl_backward_menu_complete (int count, int key) +{ + /* Positive arguments to backward-menu-complete translate into negative + arguments for menu-complete, and vice versa. */ + return (rl_menu_complete (-count, key)); +} diff --git a/utshell-0.5.0/lib/readline/display.c b/utshell-0.5.0/lib/readline/display.c new file mode 100644 index 00000000..38b3d0e7 --- /dev/null +++ b/utshell-0.5.0/lib/readline/display.c @@ -0,0 +1,3557 @@ +/* display.c -- readline redisplay facility. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include "posixstat.h" + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +#ifdef __MSDOS__ +# include +#endif + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Termcap library stuff. */ +#include "tcap.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +static void putc_face PARAMS((int, int, char *)); +static void puts_face PARAMS((const char *, const char *, int)); +static void norm_face PARAMS((char *, int)); + +static void update_line PARAMS((char *, char *, char *, char *, int, int, int, int)); +static void space_to_eol PARAMS((int)); +static void delete_chars PARAMS((int)); +static void insert_some_chars PARAMS((char *, int, int)); +static void open_some_spaces PARAMS((int)); +static void cr PARAMS((void)); +static void redraw_prompt PARAMS((char *)); +static void _rl_move_cursor_relative PARAMS((int, const char *, const char *)); + +/* Values for FLAGS */ +#define PMT_MULTILINE 0x01 + +static char *expand_prompt PARAMS((char *, int, int *, int *, int *, int *)); + +#define DEFAULT_LINE_BUFFER_SIZE 1024 + +/* State of visible and invisible lines. */ +struct line_state + { + char *line; + char *lface; + int *lbreaks; + int lbsize; +#if defined (HANDLE_MULTIBYTE) + int wbsize; + int *wrapped_line; +#endif + }; + +/* The line display buffers. One is the line currently displayed on + the screen. The other is the line about to be displayed. */ +static struct line_state line_state_array[2]; +static struct line_state *line_state_visible = &line_state_array[0]; +static struct line_state *line_state_invisible = &line_state_array[1]; +static int line_structures_initialized = 0; + +/* Backwards-compatible names. */ +#define inv_lbreaks (line_state_invisible->lbreaks) +#define inv_lbsize (line_state_invisible->lbsize) +#define vis_lbreaks (line_state_visible->lbreaks) +#define vis_lbsize (line_state_visible->lbsize) + +#define visible_line (line_state_visible->line) +#define vis_face (line_state_visible->lface) +#define invisible_line (line_state_invisible->line) +#define inv_face (line_state_invisible->lface) + +#if defined (HANDLE_MULTIBYTE) +static int _rl_col_width PARAMS((const char *, int, int, int)); +#else +# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s)) +#endif + +/* Heuristic used to decide whether it is faster to move from CUR to NEW + by backing up or outputting a carriage return and moving forward. CUR + and NEW are either both buffer positions or absolute screen positions. */ +#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new))) + +/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a + buffer index in others. This macro is used when deciding whether the + current cursor position is in the middle of a prompt string containing + invisible characters. XXX - might need to take `modmark' into account. */ +/* XXX - only valid when tested against _rl_last_c_pos; buffer indices need + to use prompt_last_invisible directly. */ +#define PROMPT_ENDING_INDEX \ + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) + +#define FACE_NORMAL '0' +#define FACE_STANDOUT '1' +#define FACE_INVALID ((char)1) + +/* **************************************************************** */ +/* */ +/* Display stuff */ +/* */ +/* **************************************************************** */ + +/* This is the stuff that is hard for me. I never seem to write good + display routines in C. Let's see how I do this time. */ + +/* (PWP) Well... Good for a simple line updater, but totally ignores + the problems of input lines longer than the screen width. + + update_line and the code that calls it makes a multiple line, + automatically wrapping line update. Careful attention needs + to be paid to the vertical position variables. */ + +/* Keep two buffers; one which reflects the current contents of the + screen, and the other to draw what we think the new contents should + be. Then compare the buffers, and make whatever changes to the + screen itself that we should. Finally, make the buffer that we + just drew into be the one which reflects the current contents of the + screen, and place the cursor where it belongs. + + Commands that want to can fix the display themselves, and then let + this function know that the display has been fixed by setting the + RL_DISPLAY_FIXED variable. This is good for efficiency. */ + +/* Application-specific redisplay function. */ +rl_voidfunc_t *rl_redisplay_function = rl_redisplay; + +/* Global variables declared here. */ +/* What YOU turn on when you have handled all redisplay yourself. */ +int rl_display_fixed = 0; + +/* The stuff that gets printed out before the actual text of the line. + This is usually pointing to rl_prompt. */ +char *rl_display_prompt = (char *)NULL; + +/* Variables used to include the editing mode in the prompt. */ +char *_rl_emacs_mode_str; +int _rl_emacs_modestr_len; + +char *_rl_vi_ins_mode_str; +int _rl_vi_ins_modestr_len; + +char *_rl_vi_cmd_mode_str; +int _rl_vi_cmd_modestr_len; + +/* Pseudo-global variables declared here. */ + +/* Hints for other parts of readline to give to the display engine. */ +int _rl_suppress_redisplay = 0; +int _rl_want_redisplay = 0; + +/* The visible cursor position. If you print some text, adjust this. */ +/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale + supporting multibyte characters, and an absolute cursor position when + in such a locale. This is an artifact of the donated multibyte support. + Care must be taken when modifying its value. */ +int _rl_last_c_pos = 0; +int _rl_last_v_pos = 0; + +/* Number of physical lines consumed by the current line buffer currently + on screen minus 1. */ +int _rl_vis_botlin = 0; + +static int _rl_quick_redisplay = 0; + +/* This is a hint update_line gives to rl_redisplay that it has adjusted the + value of _rl_last_c_pos *and* taken the presence of any invisible chars in + the prompt into account. rl_redisplay notes this and does not do the + adjustment itself. */ +static int cpos_adjusted; + +/* The index into the line buffer corresponding to the cursor position */ +static int cpos_buffer_position; + +/* A flag to note when we're displaying the first line of the prompt */ +static int displaying_prompt_first_line; +/* The number of multibyte characters in the prompt, if any */ +static int prompt_multibyte_chars; + +static int _rl_inv_botlin = 0; + +/* Variables used only in this file. */ +/* The last left edge of text that was displayed. This is used when + doing horizontal scrolling. It shifts in thirds of a screenwidth. */ +static int last_lmargin; + +/* A buffer for `modeline' messages. */ +static char *msg_buf = 0; +static int msg_bufsiz = 0; + +/* Non-zero forces the redisplay even if we thought it was unnecessary. */ +static int forced_display; + +/* Default and initial buffer size. Can grow. */ +static int line_size = 0; + +/* Set to a non-zero value if horizontal scrolling has been enabled + automatically because the terminal was resized to height 1. */ +static int horizontal_scrolling_autoset = 0; /* explicit initialization */ + +/* Variables to keep track of the expanded prompt string, which may + include invisible characters. */ + +static char *local_prompt, *local_prompt_prefix; +static int local_prompt_len; +static int prompt_prefix_length; +/* Number of chars in the buffer that contribute to visible chars on the screen. + This might be different from the number of physical chars in the presence + of multibyte characters */ +static int prompt_visible_length; + +/* The number of invisible characters in the line currently being + displayed on the screen. */ +static int visible_wrap_offset; + +/* The number of invisible characters in the prompt string. Static so it + can be shared between rl_redisplay and update_line */ +static int wrap_offset; + +/* The index of the last invisible character in the prompt string. */ +static int prompt_last_invisible; + +/* The length (buffer offset) of the first line of the last (possibly + multi-line) buffer displayed on the screen. */ +static int visible_first_line_len; + +/* Number of invisible characters on the first physical line of the prompt. + Only valid when the number of physical characters in the prompt exceeds + (or is equal to) _rl_screenwidth. */ +static int prompt_invis_chars_first_line; + +static int prompt_last_screen_line; + +static int prompt_physical_chars; + +/* An array of indexes into the prompt string where we will break physical + screen lines. It's easier to compute in expand_prompt and use later in + rl_redisplay instead of having rl_redisplay try to guess about invisible + characters in the prompt or use heuristics about where they are. */ +static int *local_prompt_newlines; + +/* set to a non-zero value by rl_redisplay if we are marking modified history + lines and the current line is so marked. */ +static int modmark; + +static int line_totbytes; + +/* Variables to save and restore prompt and display information. */ + +/* These are getting numerous enough that it's time to create a struct. */ + +static char *saved_local_prompt; +static char *saved_local_prefix; +static int *saved_local_prompt_newlines; + +static int saved_last_invisible; +static int saved_visible_length; +static int saved_prefix_length; +static int saved_local_length; +static int saved_invis_chars_first_line; +static int saved_physical_chars; + +/* Return a string indicating the editing mode, for use in the prompt. */ + +static char * +prompt_modestr (int *lenp) +{ + if (rl_editing_mode == emacs_mode) + { + if (lenp) + *lenp = _rl_emacs_mode_str ? _rl_emacs_modestr_len : RL_EMACS_MODESTR_DEFLEN; + return _rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT; + } + else if (_rl_keymap == vi_insertion_keymap) + { + if (lenp) + *lenp = _rl_vi_ins_mode_str ? _rl_vi_ins_modestr_len : RL_VI_INS_MODESTR_DEFLEN; + return _rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT; /* vi insert mode */ + } + else + { + if (lenp) + *lenp = _rl_vi_cmd_mode_str ? _rl_vi_cmd_modestr_len : RL_VI_CMD_MODESTR_DEFLEN; + return _rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT; /* vi command mode */ + } +} + +/* Expand the prompt string S and return the number of visible + characters in *LP, if LP is not null. This is currently more-or-less + a placeholder for expansion. LIP, if non-null is a place to store the + index of the last invisible character in the returned string. NIFLP, + if non-zero, is a place to store the number of invisible characters in + the first prompt line. The previous are used as byte counts -- indexes + into a character buffer. *VLP gets the number of physical characters in + the expanded prompt (visible length) */ + +/* Current implementation: + \001 (^A) start non-visible characters + \002 (^B) end non-visible characters + all characters except \001 and \002 (following a \001) are copied to + the returned string; all characters except those between \001 and + \002 are assumed to be `visible'. */ + +/* Possible values for FLAGS: + PMT_MULTILINE caller indicates that this is part of a multiline prompt +*/ + +/* This approximates the number of lines the prompt will take when displayed */ +#define APPROX_DIV(n, d) (((n) < (d)) ? 1 : ((n) / (d)) + 1) + +static char * +expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) +{ + char *r, *ret, *p, *igstart, *nprompt, *ms; + int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; + int mlen, newlines, newlines_guess, bound; + int mb_cur_max; + + /* We only expand the mode string for the last line of a multiline prompt + (a prompt with embedded newlines). */ + ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0; + if (ms) + { + l = strlen (pmt); + nprompt = (char *)xmalloc (l + mlen + 1); + memcpy (nprompt, ms, mlen); + strcpy (nprompt + mlen, pmt); + } + else + nprompt = pmt; + + mb_cur_max = MB_CUR_MAX; + + if (_rl_screenwidth == 0) + _rl_get_screen_size (0, 0); /* avoid division by zero */ + + /* Short-circuit if we can. We can do this if we are treating the prompt as + a sequence of bytes and there are no invisible characters in the prompt + to deal with. Since we populate local_prompt_newlines, we have to run + through the rest of the function if this prompt looks like it's going to + be longer than one screen line. */ + if ((mb_cur_max <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0) + { + l = strlen (nprompt); + if (l < (_rl_screenwidth > 0 ? _rl_screenwidth : 80)) + { + r = (nprompt == pmt) ? savestring (pmt) : nprompt; + if (lp) + *lp = l; + if (lip) + *lip = 0; + if (niflp) + *niflp = 0; + if (vlp) + *vlp = l; + + local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * 2); + local_prompt_newlines[0] = 0; + local_prompt_newlines[1] = -1; + + return r; + } + } + + l = strlen (nprompt); /* XXX */ + r = ret = (char *)xmalloc (l + 1); + + /* Guess at how many screen lines the prompt will take to size the array that + keeps track of where the line wraps happen */ + newlines_guess = (_rl_screenwidth > 0) ? APPROX_DIV(l, _rl_screenwidth) : APPROX_DIV(l, 80); + local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1)); + local_prompt_newlines[newlines = 0] = 0; + for (rl = 1; rl <= newlines_guess; rl++) + local_prompt_newlines[rl] = -1; + + rl = physchars = 0; /* mode string now part of nprompt */ + invfl = 0; /* invisible chars in first line of prompt */ + invflset = 0; /* we only want to set invfl once */ + igstart = 0; /* we're not ignoring any characters yet */ + + for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++) + { + /* This code strips the invisible character string markers + RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ + if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */ + { + ignoring = 1; + igstart = p; + continue; + } + else if (ignoring && *p == RL_PROMPT_END_IGNORE) + { + ignoring = 0; + if (p != (igstart + 1)) + last = r - ret - 1; + continue; + } + else + { +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + pind = p - nprompt; + ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO); + l = ind - pind; + while (l--) + *r++ = *p++; + if (!ignoring) + { + /* rl ends up being assigned to prompt_visible_length, + which is the number of characters in the buffer that + contribute to characters on the screen, which might + not be the same as the number of physical characters + on the screen in the presence of multibyte characters */ + rl += ind - pind; + physchars += _rl_col_width (nprompt, pind, ind, 0); + } + else + ninvis += ind - pind; + p--; /* compensate for later increment */ + } + else +#endif + { + *r++ = *p; + if (!ignoring) + { + rl++; /* visible length byte counter */ + physchars++; + } + else + ninvis++; /* invisible chars byte counter */ + } + + if (invflset == 0 && physchars >= _rl_screenwidth) + { + invfl = ninvis; + invflset = 1; + } + + if (physchars >= (bound = (newlines + 1) * _rl_screenwidth) && local_prompt_newlines[newlines+1] == -1) + { + int new; + if (physchars > bound) /* should rarely happen */ + { +#if defined (HANDLE_MULTIBYTE) + *r = '\0'; /* need null-termination for strlen */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY); + else +#endif + new = r - ret - (physchars - bound); /* XXX */ + } + else + new = r - ret; + local_prompt_newlines[++newlines] = new; + } + } + } + + if (rl < _rl_screenwidth) + invfl = ninvis; + + *r = '\0'; + if (lp) + *lp = rl; + if (lip) + *lip = last; + if (niflp) + *niflp = invfl; + if (vlp) + *vlp = physchars; + + if (nprompt != pmt) + free (nprompt); + + return ret; +} + +/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from + PMT and return the rest of PMT. */ +char * +_rl_strip_prompt (char *pmt) +{ + char *ret; + + ret = expand_prompt (pmt, 0, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL); + return ret; +} + +void +_rl_reset_prompt (void) +{ + rl_visible_prompt_length = rl_expand_prompt (rl_prompt); +} + +/* + * Expand the prompt string into the various display components, if + * necessary. + * + * local_prompt = expanded last line of string in rl_display_prompt + * (portion after the final newline) + * local_prompt_prefix = portion before last newline of rl_display_prompt, + * expanded via expand_prompt + * prompt_visible_length = number of visible characters in local_prompt + * prompt_prefix_length = number of visible characters in local_prompt_prefix + * + * It also tries to keep track of the number of invisible characters in the + * prompt string, and where they are. + * + * This function is called once per call to readline(). It may also be + * called arbitrarily to expand the primary prompt. + * + * The return value is the number of visible characters on the last line + * of the (possibly multi-line) prompt. In this case, multi-line means + * there are embedded newlines in the prompt string itself, not that the + * number of physical characters exceeds the screen width and the prompt + * wraps. + */ +int +rl_expand_prompt (char *prompt) +{ + char *p, *t; + int c; + + /* Clear out any saved values. */ + FREE (local_prompt); + FREE (local_prompt_prefix); + + local_prompt = local_prompt_prefix = (char *)0; + local_prompt_len = 0; + prompt_last_invisible = prompt_invis_chars_first_line = 0; + prompt_visible_length = prompt_physical_chars = 0; + + if (prompt == 0 || *prompt == 0) + return (0); + + p = strrchr (prompt, '\n'); + if (p == 0) + { + /* The prompt is only one logical line, though it might wrap. */ + local_prompt = expand_prompt (prompt, 0, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_prefix = (char *)0; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; + return (prompt_visible_length); + } + else + { + /* The prompt spans multiple lines. */ + t = ++p; + c = *t; *t = '\0'; + /* The portion of the prompt string up to and including the + final newline is now null-terminated. */ + local_prompt_prefix = expand_prompt (prompt, PMT_MULTILINE, + &prompt_prefix_length, + (int *)NULL, + (int *)NULL, + (int *)NULL); + *t = c; + + local_prompt = expand_prompt (p, PMT_MULTILINE, + &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; + return (prompt_prefix_length); + } +} + +/* Allocate the various line structures, making sure they can hold MINSIZE + bytes. If the existing line size can accommodate MINSIZE bytes, don't do + anything. */ +static void +realloc_line (int minsize) +{ + int minimum_size; + int newsize, delta; + + minimum_size = DEFAULT_LINE_BUFFER_SIZE; + if (minsize < minimum_size) + minsize = minimum_size; + if (minsize <= _rl_screenwidth) /* XXX - for gdb */ + minsize = _rl_screenwidth + 1; + if (line_size >= minsize) + return; + + newsize = minimum_size; + while (newsize < minsize) + newsize *= 2; + + visible_line = (char *)xrealloc (visible_line, newsize); + vis_face = (char *)xrealloc (vis_face, newsize); + + invisible_line = (char *)xrealloc (invisible_line, newsize); + inv_face = (char *)xrealloc (inv_face, newsize); + + delta = newsize - line_size; + memset (visible_line + line_size, 0, delta); + memset (vis_face + line_size, FACE_NORMAL, delta); + memset (invisible_line + line_size, 1, delta); + memset (inv_face + line_size, FACE_INVALID, delta); + + line_size = newsize; +} + +/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated + arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE + and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is + increased. If the lines have already been allocated, this ensures that + they can hold at least MINSIZE characters. */ +static void +init_line_structures (int minsize) +{ + if (invisible_line == 0) /* initialize it */ + { + if (line_size > minsize) + minsize = line_size; + } + realloc_line (minsize); + + if (vis_lbreaks == 0) + { + /* should be enough. */ + inv_lbsize = vis_lbsize = 256; + +#if defined (HANDLE_MULTIBYTE) + line_state_visible->wbsize = vis_lbsize; + line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int)); + + line_state_invisible->wbsize = inv_lbsize; + line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int)); +#endif + + inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int)); + vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int)); + inv_lbreaks[0] = vis_lbreaks[0] = 0; + } + + line_structures_initialized = 1; +} + +/* Convenience functions to add chars to the invisible line that update the + face information at the same time. */ +static void /* XXX - change this */ +invis_addc (int *outp, char c, char face) +{ + realloc_line (*outp + 1); + invisible_line[*outp] = c; + inv_face[*outp] = face; + *outp += 1; +} + +static void +invis_adds (int *outp, const char *str, int n, char face) +{ + int i; + + for (i = 0; i < n; i++) + invis_addc (outp, str[i], face); +} + +static void +invis_nul (int *outp) +{ + invis_addc (outp, '\0', 0); + *outp -= 1; +} + +static void +set_active_region (int *beg, int *end) +{ + if (rl_point >= 0 && rl_point <= rl_end && rl_mark >= 0 && rl_mark <= rl_end) + { + *beg = (rl_mark < rl_point) ? rl_mark : rl_point; + *end = (rl_mark < rl_point) ? rl_point : rl_mark; + } +} + +/* Do whatever tests are necessary and tell update_line that it can do a + quick, dumb redisplay on the assumption that there are so many + differences between the old and new lines that it would be a waste to + compute all the differences. + Right now, it just sets _rl_quick_redisplay if the current visible line + is a single line (so we don't have to move vertically or mess with line + wrapping). */ +void +_rl_optimize_redisplay (void) +{ + if (_rl_vis_botlin == 0) + _rl_quick_redisplay = 1; +} + +/* Basic redisplay algorithm. See comments inline. */ +void +rl_redisplay (void) +{ + int in, out, c, linenum, cursor_linenum; + int inv_botlin, lb_botlin, lb_linenum, o_cpos; + int newlines, lpos, temp, n0, num, prompt_lines_estimate; + char *prompt_this_line; + char cur_face; + int hl_begin, hl_end; + int mb_cur_max = MB_CUR_MAX; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc; + size_t wc_bytes; + int wc_width; + mbstate_t ps; + int _rl_wrapped_multicolumn = 0; +#endif + + if (_rl_echoing_p == 0) + return; + + /* Block keyboard interrupts because this function manipulates global + data structures. */ + _rl_block_sigint (); + RL_SETSTATE (RL_STATE_REDISPLAYING); + + cur_face = FACE_NORMAL; + /* Can turn this into an array for multiple highlighted objects in addition + to the region */ + hl_begin = hl_end = -1; + + if (rl_mark_active_p ()) + set_active_region (&hl_begin, &hl_end); + + if (!rl_display_prompt) + rl_display_prompt = ""; + + if (line_structures_initialized == 0) + { + init_line_structures (0); + rl_on_new_line (); + } + else if (line_size <= _rl_screenwidth) + init_line_structures (_rl_screenwidth + 1); + + /* Enable horizontal scrolling automatically for terminals of height 1 + where wrapping lines doesn't work. Disable it as soon as the terminal + height is increased again if it was automatically enabled. */ + if (_rl_screenheight <= 1) + { + if (_rl_horizontal_scroll_mode == 0) + horizontal_scrolling_autoset = 1; + _rl_horizontal_scroll_mode = 1; + } + else if (horizontal_scrolling_autoset) + _rl_horizontal_scroll_mode = 0; + + /* Draw the line into the buffer. */ + cpos_buffer_position = -1; + + prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars; + + out = inv_botlin = 0; + + /* Mark the line as modified or not. We only do this for history + lines. */ + modmark = 0; + if (_rl_mark_modified_lines && current_history () && rl_undo_list) + { + invis_addc (&out, '*', cur_face); + invis_nul (&out); + modmark = 1; + } + + /* If someone thought that the redisplay was handled, but the currently + visible line has a different modification state than the one about + to become visible, then correct the caller's misconception. */ + if (visible_line[0] != invisible_line[0]) + rl_display_fixed = 0; + + /* If the prompt to be displayed is the `primary' readline prompt (the + one passed to readline()), use the values we have already expanded. + If not, use what's already in rl_display_prompt. WRAP_OFFSET is the + number of non-visible characters (bytes) in the prompt string. */ + /* This is where we output the characters in the prompt before the last + newline, if any. If there aren't any embedded newlines, we don't + write anything. Copy the last line of the prompt string into the line in + any case */ + if (rl_display_prompt == rl_prompt || local_prompt) + { + if (local_prompt_prefix && forced_display) + _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); + + if (local_prompt_len > 0) + invis_adds (&out, local_prompt, local_prompt_len, cur_face); + invis_nul (&out); + wrap_offset = local_prompt_len - prompt_visible_length; + } + else + { + int pmtlen; + prompt_this_line = strrchr (rl_display_prompt, '\n'); + if (!prompt_this_line) + prompt_this_line = rl_display_prompt; + else + { + prompt_this_line++; + pmtlen = prompt_this_line - rl_display_prompt; /* temp var */ + if (forced_display) + { + _rl_output_some_chars (rl_display_prompt, pmtlen); + /* Make sure we are at column zero even after a newline, + regardless of the state of terminal output processing. */ + if (pmtlen < 2 || prompt_this_line[-2] != '\r') + cr (); + } + } + + prompt_physical_chars = pmtlen = strlen (prompt_this_line); /* XXX */ + invis_adds (&out, prompt_this_line, pmtlen, cur_face); + invis_nul (&out); + wrap_offset = prompt_invis_chars_first_line = 0; + } + +#if defined (HANDLE_MULTIBYTE) +#define CHECK_INV_LBREAKS() \ + do { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + if (newlines >= (line_state_invisible->wbsize - 2)) \ + { \ + line_state_invisible->wbsize *= 2; \ + line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ + } \ + } while (0) +#else +#define CHECK_INV_LBREAKS() \ + do { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + } while (0) +#endif /* !HANDLE_MULTIBYTE */ + +#if defined (HANDLE_MULTIBYTE) +#define CHECK_LPOS() \ + do { \ + lpos++; \ + if (lpos >= _rl_screenwidth) \ + { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + inv_lbreaks[++newlines] = out; \ + if (newlines >= (line_state_invisible->wbsize - 2)) \ + { \ + line_state_invisible->wbsize *= 2; \ + line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ + } \ + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \ + lpos = 0; \ + } \ + } while (0) +#else +#define CHECK_LPOS() \ + do { \ + lpos++; \ + if (lpos >= _rl_screenwidth) \ + { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + inv_lbreaks[++newlines] = out; \ + lpos = 0; \ + } \ + } while (0) +#endif + + /* inv_lbreaks[i] is where line i starts in the buffer. */ + inv_lbreaks[newlines = 0] = 0; + /* lpos is a physical cursor position, so it needs to be adjusted by the + number of invisible characters in the prompt, per line. We compute + the line breaks in the prompt string in expand_prompt, taking invisible + characters into account, and if lpos exceeds the screen width, we copy + the data in the loop below. */ + lpos = prompt_physical_chars + modmark; + +#if defined (HANDLE_MULTIBYTE) + memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int)); + num = 0; +#endif + + /* prompt_invis_chars_first_line is the number of invisible characters (bytes) + in the first physical line of the prompt. + wrap_offset - prompt_invis_chars_first_line is usually the number of + invis chars on the second (or, more generally, last) line. */ + + /* This is zero-based, used to set the newlines */ + prompt_lines_estimate = lpos / _rl_screenwidth; + + /* what if lpos is already >= _rl_screenwidth before we start drawing the + contents of the command line? */ + if (lpos >= _rl_screenwidth) + { + temp = 0; + + /* first copy the linebreaks array we computed in expand_prompt */ + while (local_prompt_newlines[newlines+1] != -1) + { + temp = local_prompt_newlines[newlines+1]; + inv_lbreaks[++newlines] = temp; + } + + /* Now set lpos from the last newline */ + if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) + lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line); + else + lpos -= (_rl_screenwidth * newlines); + } + + prompt_last_screen_line = newlines; + + /* Draw the rest of the line (after the prompt) into invisible_line, keeping + track of where the cursor is (cpos_buffer_position), the number of the + line containing the cursor (lb_linenum), the last line number (lb_botlin + and inv_botlin). + It maintains an array of line breaks for display (inv_lbreaks). + This handles expanding tabs for display and displaying meta characters. */ + lb_linenum = 0; +#if defined (HANDLE_MULTIBYTE) + in = 0; + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[0])) + { + wc = (wchar_t)rl_line_buffer[0]; + wc_bytes = 1; + } + else + wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); + } + else + wc_bytes = 1; + while (in < rl_end) +#else + for (in = 0; in < rl_end; in++) +#endif + { + if (in == hl_begin) + cur_face = FACE_STANDOUT; + else if (in == hl_end) + cur_face = FACE_NORMAL; + + c = (unsigned char)rl_line_buffer[in]; + +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + if (MB_INVALIDCH (wc_bytes)) + { + /* Byte sequence is invalid or shortened. Assume that the + first byte represents a character. */ + wc_bytes = 1; + /* Assume that a character occupies a single column. */ + wc_width = 1; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (wc_bytes)) + break; /* Found '\0' */ + else + { + temp = WCWIDTH (wc); + wc_width = (temp >= 0) ? temp : 1; + } + } +#endif + + if (in == rl_point) + { + cpos_buffer_position = out; + lb_linenum = newlines; + } + +#if defined (HANDLE_MULTIBYTE) + if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */ +#else + if (META_CHAR (c)) +#endif + { + if (_rl_output_meta_chars == 0) + { + char obuf[5]; + int olen; + + olen = sprintf (obuf, "\\%o", c); + + if (lpos + olen >= _rl_screenwidth) + { + temp = _rl_screenwidth - lpos; + CHECK_INV_LBREAKS (); + inv_lbreaks[++newlines] = out + temp; +#if defined (HANDLE_MULTIBYTE) + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; +#endif + lpos = olen - temp; + } + else + lpos += olen; + + for (temp = 0; temp < olen; temp++) + { + invis_addc (&out, obuf[temp], cur_face); + CHECK_LPOS (); + } + } + else + { + invis_addc (&out, c, cur_face); + CHECK_LPOS(); + } + } +#if defined (DISPLAY_TABS) + else if (c == '\t') + { + register int newout; + + newout = out + 8 - lpos % 8; + temp = newout - out; + if (lpos + temp >= _rl_screenwidth) + { + register int temp2; + temp2 = _rl_screenwidth - lpos; + CHECK_INV_LBREAKS (); + inv_lbreaks[++newlines] = out + temp2; +#if defined (HANDLE_MULTIBYTE) + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; +#endif + lpos = temp - temp2; + while (out < newout) + invis_addc (&out, ' ', cur_face); + } + else + { + while (out < newout) + invis_addc (&out, ' ', cur_face); + lpos += temp; + } + } +#endif + else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) + { + invis_addc (&out, '\0', cur_face); + CHECK_INV_LBREAKS (); + inv_lbreaks[++newlines] = out; +#if defined (HANDLE_MULTIBYTE) + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; +#endif + lpos = 0; + } + else if (CTRL_CHAR (c) || c == RUBOUT) + { + invis_addc (&out, '^', cur_face); + CHECK_LPOS(); + invis_addc (&out, CTRL_CHAR (c) ? UNCTRL (c) : '?', cur_face); + CHECK_LPOS(); + } + else + { +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + register int i; + + _rl_wrapped_multicolumn = 0; + + if (_rl_screenwidth < lpos + wc_width) + for (i = lpos; i < _rl_screenwidth; i++) + { + /* The space will be removed in update_line() */ + invis_addc (&out, ' ', cur_face); + _rl_wrapped_multicolumn++; + CHECK_LPOS(); + } + if (in == rl_point) + { + cpos_buffer_position = out; + lb_linenum = newlines; + } + for (i = in; i < in+wc_bytes; i++) + invis_addc (&out, rl_line_buffer[i], cur_face); + for (i = 0; i < wc_width; i++) + CHECK_LPOS(); + } + else + { + invis_addc (&out, c, cur_face); + CHECK_LPOS(); + } +#else + invis_addc (&out, c, cur_face); + CHECK_LPOS(); +#endif + } + +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + in += wc_bytes; + if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[in])) + { + wc = (wchar_t)rl_line_buffer[in]; + wc_bytes = 1; + memset (&ps, 0, sizeof (mbstate_t)); /* re-init state */ + } + else + wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); + } + else + in++; +#endif + } + invis_nul (&out); + line_totbytes = out; + if (cpos_buffer_position < 0) + { + cpos_buffer_position = out; + lb_linenum = newlines; + } + + /* If we are switching from one line to multiple wrapped lines, we don't + want to do a dumb update (or we want to make it smarter). */ + if (_rl_quick_redisplay && newlines > 0) + _rl_quick_redisplay = 0; + + inv_botlin = lb_botlin = _rl_inv_botlin = newlines; + CHECK_INV_LBREAKS (); + inv_lbreaks[newlines+1] = out; +#if defined (HANDLE_MULTIBYTE) + /* This should be 0 anyway */ + line_state_invisible->wrapped_line[newlines+1] = _rl_wrapped_multicolumn; +#endif + cursor_linenum = lb_linenum; + + /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed. + CURSOR_LINENUM == line number where the cursor should be placed. */ + + /* PWP: now is when things get a bit hairy. The visible and invisible + line buffers are really multiple lines, which would wrap every + (screenwidth - 1) characters. Go through each in turn, finding + the changed region and updating it. The line order is top to bottom. */ + + /* If we can move the cursor up and down, then use multiple lines, + otherwise, let long lines display in a single terminal line, and + horizontally scroll it. */ + displaying_prompt_first_line = 1; + if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) + { + int nleft, pos, changed_screen_line, tx; + + if (!rl_display_fixed || forced_display) + { + forced_display = 0; + + /* If we have more than a screenful of material to display, then + only display a screenful. We should display the last screen, + not the first. */ + if (out >= _rl_screenchars) + { +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + out = _rl_find_prev_mbchar (invisible_line, _rl_screenchars, MB_FIND_ANY); + else +#endif + out = _rl_screenchars - 1; + } + + /* The first line is at character position 0 in the buffer. The + second and subsequent lines start at inv_lbreaks[N], offset by + OFFSET (which has already been calculated above). */ + +#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset) +#define WRAP_OFFSET(line, offset) ((line == 0) \ + ? (offset ? INVIS_FIRST() : 0) \ + : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0)) +#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) +#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) +#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) +#define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) +#define VIS_FACE(line) (vis_face + vis_lbreaks[line]) +#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) +#define VIS_LINE_FACE(line) ((line) > _rl_vis_botlin) ? "" : VIS_FACE(line) +#define INV_LINE(line) (invisible_line + inv_lbreaks[line]) +#define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line]) + +#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \ + _rl_last_c_pos != o_cpos && \ + _rl_last_c_pos > wrap_offset && \ + o_cpos < prompt_last_invisible) + + + /* We don't want to highlight anything that's going to be off the top + of the display; if the current line takes up more than an entire + screen, just mark the lines that won't be displayed as having a + `normal' face. + It's imperfect, but better than display corruption. */ + if (rl_mark_active_p () && inv_botlin > _rl_screenheight) + { + int extra; + + extra = inv_botlin - _rl_screenheight; + for (linenum = 0; linenum <= extra; linenum++) + norm_face (INV_LINE_FACE(linenum), INV_LLEN (linenum)); + } + + /* For each line in the buffer, do the updating display. */ + for (linenum = 0; linenum <= inv_botlin; linenum++) + { + /* This can lead us astray if we execute a program that changes + the locale from a non-multibyte to a multibyte one. */ + o_cpos = _rl_last_c_pos; + cpos_adjusted = 0; + update_line (VIS_LINE(linenum), VIS_LINE_FACE(linenum), + INV_LINE(linenum), INV_LINE_FACE(linenum), + linenum, + VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); + + /* update_line potentially changes _rl_last_c_pos, but doesn't + take invisible characters into account, since _rl_last_c_pos + is an absolute cursor position in a multibyte locale. We + choose to (mostly) compensate for that here, rather than + change update_line itself. There are several cases in which + update_line adjusts _rl_last_c_pos itself (so it can pass + _rl_move_cursor_relative accurate values); it communicates + this back by setting cpos_adjusted. If we assume that + _rl_last_c_pos is correct (an absolute cursor position) each + time update_line is called, then we can assume in our + calculations that o_cpos does not need to be adjusted by + wrap_offset. */ + if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT()) + _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ + else if (cpos_adjusted == 0 && + linenum == prompt_last_screen_line && + prompt_physical_chars > _rl_screenwidth && + (mb_cur_max > 1 && rl_byte_oriented == 0) && + _rl_last_c_pos != o_cpos && + _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) /* XXX - rethink this last one */ + /* This assumes that all the invisible characters are split + between the first and last lines of the prompt, if the + prompt consumes more than two lines. It's usually right */ + /* XXX - not sure this is ever executed */ + _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line); + + /* If this is the line with the prompt, we might need to + compensate for invisible characters in the new line. Do + this only if there is not more than one new line (which + implies that we completely overwrite the old visible line) + and the new line is shorter than the old. Make sure we are + at the end of the new line before clearing. */ + if (linenum == 0 && + inv_botlin == 0 && _rl_last_c_pos == out && + (wrap_offset > visible_wrap_offset) && + (_rl_last_c_pos < visible_first_line_len)) + { + if (mb_cur_max > 1 && rl_byte_oriented == 0) + nleft = _rl_screenwidth - _rl_last_c_pos; + else + nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; + if (nleft) + _rl_clear_to_eol (nleft); + } +#if 0 + /* This segment is intended to handle the case where the old + visible prompt has invisible characters and the new line + to be displayed needs to clear the rest of the old characters + out (e.g., when printing the i-search prompt): in general, + the case of the new line being shorter than the old. We need + to be at the end of the new line and the old line needs to be + longer than the current cursor position. It's not perfect, + since it uses the byte length of the first line, but this will + at worst result in some extra clear-to-end-of-lines. We can't + use the prompt length variables because they may not + correspond to the visible line (see printing the i-search + prompt above). The tests for differing numbers of invisible + characters may not matter and can probably be removed. */ + else if (linenum == 0 && + linenum == prompt_last_screen_line && + _rl_last_c_pos == out && + _rl_last_c_pos < visible_first_line_len && + visible_wrap_offset && + visible_wrap_offset != wrap_offset) + { + if (mb_cur_max > 1 && rl_byte_oriented == 0) + nleft = _rl_screenwidth - _rl_last_c_pos; + else + nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; + if (nleft) + _rl_clear_to_eol (nleft); + } +#endif + + /* Since the new first line is now visible, save its length. */ + if (linenum == 0) + visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset; + } + + /* We may have deleted some lines. If so, clear the left over + blank ones at the bottom out. */ + if (_rl_vis_botlin > inv_botlin) + { + char *tt; + for (; linenum <= _rl_vis_botlin; linenum++) + { + tt = VIS_CHARS (linenum); + _rl_move_vert (linenum); + _rl_move_cursor_relative (0, tt, VIS_FACE(linenum)); + _rl_clear_to_eol + ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth); + } + } + _rl_vis_botlin = inv_botlin; + + /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a + different screen line during this redisplay. */ + changed_screen_line = _rl_last_v_pos != cursor_linenum; + if (changed_screen_line) + { + _rl_move_vert (cursor_linenum); + /* If we moved up to the line with the prompt using _rl_term_up, + the physical cursor position on the screen stays the same, + but the buffer position needs to be adjusted to account + for invisible characters. */ + if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset) + _rl_last_c_pos += wrap_offset; + } + + /* Now we move the cursor to where it needs to be. First, make + sure we are on the correct line (cursor_linenum). */ + + /* We have to reprint the prompt if it contains invisible + characters, since it's not generally OK to just reprint + the characters from the current cursor position. But we + only need to reprint it if the cursor is before the last + invisible character in the prompt string. */ + /* XXX - why not use local_prompt_len? */ + nleft = prompt_visible_length + wrap_offset; + if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && + _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt) + { + _rl_cr (); + if (modmark) + _rl_output_some_chars ("*", 1); + + _rl_output_some_chars (local_prompt, nleft); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark; + else + _rl_last_c_pos = nleft + modmark; + } + + /* Where on that line? And where does that line start + in the buffer? */ + pos = inv_lbreaks[cursor_linenum]; + /* nleft == number of characters (bytes) in the line buffer between + the start of the line and the desired cursor position. */ + nleft = cpos_buffer_position - pos; + + /* NLEFT is now a number of characters in a buffer. When in a + multibyte locale, however, _rl_last_c_pos is an absolute cursor + position that doesn't take invisible characters in the prompt + into account. We use a fudge factor to compensate. */ + + /* Since _rl_backspace() doesn't know about invisible characters in + the prompt, and there's no good way to tell it, we compensate for + those characters here and call _rl_backspace() directly if + necessary */ + if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) + { + /* TX == new physical cursor position in multibyte locale. */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset; + else + tx = nleft; + if (tx >= 0 && _rl_last_c_pos > tx) + { + _rl_backspace (_rl_last_c_pos - tx); /* XXX */ + _rl_last_c_pos = tx; + } + } + + /* We need to note that in a multibyte locale we are dealing with + _rl_last_c_pos as an absolute cursor position, but moving to a + point specified by a buffer position (NLEFT) that doesn't take + invisible characters into account. */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + _rl_move_cursor_relative (nleft, &invisible_line[pos], &inv_face[pos]); + else if (nleft != _rl_last_c_pos) + _rl_move_cursor_relative (nleft, &invisible_line[pos], &inv_face[pos]); + } + } + else /* Do horizontal scrolling. Much simpler */ + { +#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) + int lmargin, ndisp, nleft, phys_c_pos, t; + + /* Always at top line. */ + _rl_last_v_pos = 0; + + /* Compute where in the buffer the displayed line should start. This + will be LMARGIN. */ + + /* The number of characters that will be displayed before the cursor. */ + ndisp = cpos_buffer_position - wrap_offset; + nleft = prompt_visible_length + wrap_offset; + /* Where the new cursor position will be on the screen. This can be + longer than SCREENWIDTH; if it is, lmargin will be adjusted. */ + phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset); + t = _rl_screenwidth / 3; + + /* If the number of characters had already exceeded the screenwidth, + last_lmargin will be > 0. */ + + /* If the number of characters to be displayed is more than the screen + width, compute the starting offset so that the cursor is about + two-thirds of the way across the screen. */ + if (phys_c_pos > _rl_screenwidth - 2) + { + lmargin = cpos_buffer_position - (2 * t); + if (lmargin < 0) + lmargin = 0; + /* If the left margin would be in the middle of a prompt with + invisible characters, don't display the prompt at all. */ + if (wrap_offset && lmargin > 0 && lmargin < nleft) + lmargin = nleft; + } + else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */ + lmargin = 0; + else if (phys_c_pos < 1) + { + /* If we are moving back towards the beginning of the line and + the last margin is no longer correct, compute a new one. */ + lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */ + if (wrap_offset && lmargin > 0 && lmargin < nleft) + lmargin = nleft; + } + else + lmargin = last_lmargin; + + displaying_prompt_first_line = lmargin < nleft; + + /* If the first character on the screen isn't the first character + in the display line, indicate this with a special character. */ + if (lmargin > 0) + invisible_line[lmargin] = '<'; + + /* If SCREENWIDTH characters starting at LMARGIN do not encompass + the whole line, indicate that with a special character at the + right edge of the screen. If LMARGIN is 0, we need to take the + wrap offset into account. */ + t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; + if (t > 0 && t < out) + invisible_line[t - 1] = '>'; + + if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin) + { + forced_display = 0; + o_cpos = _rl_last_c_pos; + cpos_adjusted = 0; + update_line (&visible_line[last_lmargin], &vis_face[last_lmargin], + &invisible_line[lmargin], &inv_face[lmargin], + 0, + _rl_screenwidth + visible_wrap_offset, + _rl_screenwidth + (lmargin ? 0 : wrap_offset), + 0); + + if ((mb_cur_max > 1 && rl_byte_oriented == 0) && + displaying_prompt_first_line && OLD_CPOS_IN_PROMPT()) + _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ + + /* If the visible new line is shorter than the old, but the number + of invisible characters is greater, and we are at the end of + the new line, we need to clear to eol. */ + t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset); + if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) && + (_rl_last_c_pos == out) && displaying_prompt_first_line && + t < visible_first_line_len) + { + nleft = _rl_screenwidth - t; + _rl_clear_to_eol (nleft); + } + visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset); + if (visible_first_line_len > _rl_screenwidth) + visible_first_line_len = _rl_screenwidth; + + _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin], &inv_face[lmargin]); + last_lmargin = lmargin; + } + } + fflush (rl_outstream); + + /* Swap visible and non-visible lines. */ + { + struct line_state *vtemp = line_state_visible; + + line_state_visible = line_state_invisible; + line_state_invisible = vtemp; + + rl_display_fixed = 0; + /* If we are displaying on a single line, and last_lmargin is > 0, we + are not displaying any invisible characters, so set visible_wrap_offset + to 0. */ + if (_rl_horizontal_scroll_mode && last_lmargin) + visible_wrap_offset = 0; + else + visible_wrap_offset = wrap_offset; + + _rl_quick_redisplay = 0; + } + + RL_UNSETSTATE (RL_STATE_REDISPLAYING); + _rl_release_sigint (); +} + +static void +putc_face (int c, int face, char *cur_face) +{ + char cf; + cf = *cur_face; + if (cf != face) + { + if (cf != FACE_NORMAL && cf != FACE_STANDOUT) + return; + if (face != FACE_NORMAL && face != FACE_STANDOUT) + return; + if (face == FACE_STANDOUT && cf == FACE_NORMAL) + _rl_standout_on (); + if (face == FACE_NORMAL && cf == FACE_STANDOUT) + _rl_standout_off (); + *cur_face = face; + } + if (c != EOF) + putc (c, rl_outstream); +} + +static void +puts_face (const char *str, const char *face, int n) +{ + int i; + char cur_face; + + for (cur_face = FACE_NORMAL, i = 0; i < n; i++) + putc_face (str[i], face[i], &cur_face); + putc_face (EOF, FACE_NORMAL, &cur_face); +} + +static void +norm_face (char *face, int n) +{ + memset (face, FACE_NORMAL, n); +} + +#define ADJUST_CPOS(x) do { _rl_last_c_pos -= (x) ; cpos_adjusted = 1; } while (0) + +/* PWP: update_line() is based on finding the middle difference of each + line on the screen; vis: + + /old first difference + /beginning of line | /old last same /old EOL + v v v v +old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as +new: eddie> Oh, my little buggy says to me, as lurgid as + ^ ^ ^ ^ + \beginning of line | \new last same \new end of line + \new first difference + + All are character pointers for the sake of speed. Special cases for + no differences, as well as for end of line additions must be handled. + + Could be made even smarter, but this works well enough */ +static void +update_line (char *old, char *old_face, char *new, char *new_face, int current_line, int omax, int nmax, int inv_botlin) +{ + char *ofd, *ols, *oe, *nfd, *nls, *ne; + char *ofdf, *nfdf, *olsf, *nlsf; + int temp, lendiff, wsatend, od, nd, twidth, o_cpos; + int current_invis_chars; + int col_lendiff, col_temp; + int bytes_to_insert; + int mb_cur_max = MB_CUR_MAX; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps_new, ps_old; + int new_offset, old_offset; +#endif + + /* If we're at the right edge of a terminal that supports xn, we're + ready to wrap around, so do so. This fixes problems with knowing + the exact cursor position and cut-and-paste with certain terminal + emulators. In this calculation, TEMP is the physical screen + position of the cursor. */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + temp = _rl_last_c_pos; + else + temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset); + if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode + && _rl_last_v_pos == current_line - 1) + { + /* We're going to wrap around by writing the first character of NEW to + the screen and dealing with changes to what's visible by modifying + OLD to match it. Complicated by the presence of multi-width + characters at the end of the line or beginning of the new one. */ + /* old is always somewhere in visible_line; new is always somewhere in + invisible_line. These should always be null-terminated. */ +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + wchar_t wc; + mbstate_t ps; + int oldwidth, newwidth; + int oldbytes, newbytes; + size_t ret; + + /* This fixes only double-column characters, but if the wrapped + character consumes more than three columns, spaces will be + inserted in the string buffer. */ + /* XXX remember that we are working on the invisible line right now; + we don't swap visible and invisible until just before rl_redisplay + returns */ + /* This will remove the extra placeholder space we added with + _rl_wrapped_multicolumn */ + if (current_line < line_state_invisible->wbsize && line_state_invisible->wrapped_line[current_line] > 0) + _rl_clear_to_eol (line_state_invisible->wrapped_line[current_line]); + + /* 1. how many screen positions does first char in old consume? */ + memset (&ps, 0, sizeof (mbstate_t)); + ret = mbrtowc (&wc, old, mb_cur_max, &ps); + oldbytes = ret; + if (MB_INVALIDCH (ret)) + { + oldwidth = 1; + oldbytes = 1; + } + else if (MB_NULLWCH (ret)) + oldwidth = 0; + else + oldwidth = WCWIDTH (wc); + if (oldwidth < 0) + oldwidth = 1; + + /* 2. how many screen positions does the first char in new consume? */ + memset (&ps, 0, sizeof (mbstate_t)); + ret = mbrtowc (&wc, new, mb_cur_max, &ps); + newbytes = ret; + if (MB_INVALIDCH (ret)) + { + newwidth = 1; + newbytes = 1; + } + else if (MB_NULLWCH (ret)) + newwidth = 0; + else + newwidth = WCWIDTH (wc); + if (newwidth < 0) + newwidth = 1; + + /* 3. if the new width is less than the old width, we need to keep + going in new until we have consumed at least that many screen + positions, and figure out how many bytes that will take */ + while (newbytes < nmax && newwidth < oldwidth) + { + int t; + + ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps); + if (MB_INVALIDCH (ret)) + { + newwidth += 1; + newbytes += 1; + } + else if (MB_NULLWCH (ret)) + break; + else + { + t = WCWIDTH (wc); + newwidth += (t >= 0) ? t : 1; + newbytes += ret; + } + } + /* 4. If the new width is more than the old width, keep going in old + until we have consumed exactly that many screen positions, and + figure out how many bytes that will take. This is an optimization */ + while (oldbytes < omax && oldwidth < newwidth) + { + int t; + + ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps); + if (MB_INVALIDCH (ret)) + { + oldwidth += 1; + oldbytes += 1; + } + else if (MB_NULLWCH (ret)) + break; + else + { + t = WCWIDTH (wc); + oldwidth += (t >= 0) ? t : 1; + oldbytes += ret; + } + } + /* 5. write the first newbytes of new, which takes newwidth. This is + where the screen wrapping takes place, and we are now writing + characters onto the new line. We need to fix up old so it + accurately reflects what is on the screen after the + _rl_output_some_chars below. */ + if (newwidth > 0) + { + int count, i, j; + char *optr; + + puts_face (new, new_face, newbytes); + _rl_last_c_pos = newwidth; + _rl_last_v_pos++; + + /* 5a. If the number of screen positions doesn't match, punt + and do a dumb update. + 5b. If the number of bytes is greater in the new line than + the old, do a dumb update, because there is no guarantee we + can extend the old line enough to fit the new bytes. */ + if (newwidth != oldwidth || newbytes > oldbytes) + { + oe = old + omax; + ne = new + nmax; + nd = newbytes; + nfd = new + nd; + ofdf = old_face + oldbytes; + nfdf = new_face + newbytes; + + goto dumb_update; + } + if (oldbytes != 0 && newbytes != 0) + { + /* We have written as many bytes from new as we need to + consume the first character of old. Fix up `old' so it + reflects the new screen contents. We use +1 in the + memmove call to copy the trailing NUL. */ + /* (strlen(old+oldbytes) == (omax - oldbytes - 1)) */ + + /* Don't bother trying to fit the bytes if the number of bytes + doesn't change. */ + if (oldbytes != newbytes) + { + memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1); + memmove (old_face+newbytes, old_face+oldbytes, strlen (old+oldbytes) + 1); + } + memcpy (old, new, newbytes); + memcpy (old_face, new_face, newbytes); + j = newbytes - oldbytes; + omax += j; + /* Fix up indices if we copy data from one line to another */ + for (i = current_line+1; j != 0 && i <= inv_botlin+1 && i <=_rl_vis_botlin+1; i++) + vis_lbreaks[i] += j; + } + } + else + { + putc (' ', rl_outstream); + _rl_last_c_pos = 1; + _rl_last_v_pos++; + if (old[0] && new[0]) + { + old[0] = new[0]; + old_face[0] = new_face[0]; + } + } + } + else +#endif + { + if (new[0]) + puts_face (new, new_face, 1); + else + putc (' ', rl_outstream); + _rl_last_c_pos = 1; + _rl_last_v_pos++; + if (old[0] && new[0]) + { + old[0] = new[0]; + old_face[0] = new_face[0]; + } + } + } + + /* We know that we are dealing with a single screen line here */ + if (_rl_quick_redisplay) + { + nfd = new; + nfdf = new_face; + ofd = old; + ofdf = old_face; + for (od = 0, oe = ofd; od < omax && *oe; oe++, od++); + for (nd = 0, ne = nfd; nd < nmax && *ne; ne++, nd++); + od = nd = 0; + _rl_move_cursor_relative (0, old, old_face); + + bytes_to_insert = ne - nfd; + if (bytes_to_insert < local_prompt_len) /* ??? */ + goto dumb_update; + + /* output the prompt, output the line contents, clear the rest */ + _rl_output_some_chars (nfd, local_prompt_len); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + _rl_last_c_pos = prompt_physical_chars; + else + _rl_last_c_pos = local_prompt_len; + + bytes_to_insert -= local_prompt_len; + if (bytes_to_insert > 0) + { + puts_face (new+local_prompt_len, nfdf+local_prompt_len, bytes_to_insert); + if (mb_cur_max > 1 && rl_byte_oriented) + _rl_last_c_pos += _rl_col_width (new, local_prompt_len, ne-new, 1); + else + _rl_last_c_pos += bytes_to_insert; + } + + /* See comments at dumb_update: for an explanation of this heuristic */ + if (nmax < omax) + goto clear_rest_of_line; + else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset))) + goto clear_rest_of_line; + else + return; + } + + /* Find first difference. */ +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + /* See if the old line is a subset of the new line, so that the + only change is adding characters. */ + temp = (omax < nmax) ? omax : nmax; + if (memcmp (old, new, temp) == 0 && memcmp (old_face, new_face, temp) == 0) + { + new_offset = old_offset = temp; /* adding at the end */ + ofd = old + temp; + ofdf = old_face + temp; + nfd = new + temp; + nfdf = new_face + temp; + } + else + { + memset (&ps_new, 0, sizeof(mbstate_t)); + memset (&ps_old, 0, sizeof(mbstate_t)); + + /* Are the old and new lines the same? */ + if (omax == nmax && memcmp (new, old, omax) == 0 && memcmp (new_face, old_face, omax) == 0) + { + old_offset = omax; + new_offset = nmax; + ofd = old + omax; + ofdf = old_face + omax; + nfd = new + nmax; + nfdf = new_face + nmax; + } + else + { + /* Go through the line from the beginning and find the first + difference. We assume that faces change at (possibly multi- + byte) character boundaries. */ + new_offset = old_offset = 0; + for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face; + (ofd - old < omax) && *ofd && + _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new) && + *ofdf == *nfdf; ) + { + old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY); + new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY); + + ofd = old + old_offset; + ofdf = old_face + old_offset; + nfd = new + new_offset; + nfdf = new_face + new_offset; + } + } + } + } + else +#endif + for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face; + (ofd - old < omax) && *ofd && (*ofd == *nfd) && (*ofdf == *nfdf); + ofd++, nfd++, ofdf++, nfdf++) + ; + + /* Move to the end of the screen line. ND and OD are used to keep track + of the distance between ne and new and oe and old, respectively, to + move a subtraction out of each loop. */ + for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++); + for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++); + + /* If no difference, continue to next line. */ + if (ofd == oe && nfd == ne) + return; + +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0 && _rl_utf8locale) + { + wchar_t wc; + mbstate_t ps = { 0 }; + int t; + + /* If the first character in the difference is a zero-width character, + assume it's a combining character and back one up so the two base + characters no longer compare equivalently. */ + t = mbrtowc (&wc, ofd, mb_cur_max, &ps); + if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0) + { + old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY); + new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY); + ofd = old + old_offset; /* equal by definition */ + ofdf = old_face + old_offset; + nfd = new + new_offset; + nfdf = new_face + new_offset; + } + } +#endif + + wsatend = 1; /* flag for trailing whitespace */ + +#if defined (HANDLE_MULTIBYTE) + /* Find the last character that is the same between the two lines. This + bounds the region that needs to change. */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); + olsf = old_face + (ols - old); + nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); + nlsf = new_face + (nls - new); + + while ((ols > ofd) && (nls > nfd)) + { + memset (&ps_old, 0, sizeof (mbstate_t)); + memset (&ps_new, 0, sizeof (mbstate_t)); + + if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0 || + *olsf != *nlsf) + break; + + if (*ols == ' ') + wsatend = 0; + + ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY); + olsf = old_face + (ols - old); + nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY); + nlsf = new_face + (nls - new); + } + } + else + { +#endif /* HANDLE_MULTIBYTE */ + ols = oe - 1; /* find last same */ + olsf = old_face + (ols - old); + nls = ne - 1; + nlsf = new_face + (nls - new); + while ((ols > ofd) && (nls > nfd) && (*ols == *nls) && (*olsf == *nlsf)) + { + if (*ols != ' ') + wsatend = 0; + ols--; olsf--; + nls--; nlsf--; + } +#if defined (HANDLE_MULTIBYTE) + } +#endif + + if (wsatend) + { + ols = oe; + olsf = old_face + (ols - old); + nls = ne; + nlsf = new_face + (nls - new); + } +#if defined (HANDLE_MULTIBYTE) + /* This may not work for stateful encoding, but who cares? To handle + stateful encoding properly, we have to scan each string from the + beginning and compare. */ + else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0 || *olsf != *nlsf) +#else + else if (*ols != *nls || *olsf != *nlsf) +#endif + { + if (*ols) /* don't step past the NUL */ + { + if (mb_cur_max > 1 && rl_byte_oriented == 0) + ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY); + else + ols++; + } + if (*nls) + { + if (mb_cur_max > 1 && rl_byte_oriented == 0) + nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY); + else + nls++; + } + olsf = old_face + (ols - old); + nlsf = new_face + (nls - new); + } + + /* count of invisible characters in the current invisible line. */ + current_invis_chars = W_OFFSET (current_line, wrap_offset); + if (_rl_last_v_pos != current_line) + { + _rl_move_vert (current_line); + /* We have moved up to a new screen line. This line may or may not have + invisible characters on it, but we do our best to recalculate + visible_wrap_offset based on what we know. */ + if (current_line == 0) + visible_wrap_offset = prompt_invis_chars_first_line; /* XXX */ +#if 0 /* XXX - not yet */ + else if (current_line == prompt_last_screen_line && wrap_offset > prompt_invis_chars_first_line) + visible_wrap_offset = wrap_offset - prompt_invis_chars_first_line +#endif + if ((mb_cur_max == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset) + _rl_last_c_pos += visible_wrap_offset; + } + + /* If this is the first line and there are invisible characters in the + prompt string, and the prompt string has not changed, and the current + cursor position is before the last invisible character in the prompt, + and the index of the character to move to is past the end of the prompt + string, then redraw the entire prompt string. We can only do this + reliably if the terminal supports a `cr' capability. + + This can also happen if the prompt string has changed, and the first + difference in the line is in the middle of the prompt string, after a + sequence of invisible characters (worst case) and before the end of + the prompt. In this case, we have to redraw the entire prompt string + so that the entire sequence of invisible characters is drawn. We need + to handle the worst case, when the difference is after (or in the middle + of) a sequence of invisible characters that changes the text color and + before the sequence that restores the text color to normal. Then we have + to make sure that the lines still differ -- if they don't, we can + return immediately. + + This is not an efficiency hack -- there is a problem with redrawing + portions of the prompt string if they contain terminal escape + sequences (like drawing the `unbold' sequence without a corresponding + `bold') that manifests itself on certain terminals. */ + + lendiff = local_prompt_len; + if (lendiff > nmax) + lendiff = nmax; + od = ofd - old; /* index of first difference in visible line */ + nd = nfd - new; /* nd, od are buffer indexes */ + if (current_line == 0 && !_rl_horizontal_scroll_mode && + _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && + (((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= prompt_last_invisible)) || + ((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX))) + { + _rl_cr (); + if (modmark) + _rl_output_some_chars ("*", 1); + _rl_output_some_chars (local_prompt, lendiff); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + /* If we just output the entire prompt string we can take advantage + of knowing the number of physical characters in the prompt. If + the prompt wraps lines (lendiff clamped at nmax), we can't. */ + if (lendiff == local_prompt_len) + _rl_last_c_pos = prompt_physical_chars + modmark; + else + /* We take wrap_offset into account here so we can pass correct + information to _rl_move_cursor_relative. */ + _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark; + cpos_adjusted = 1; + } + else + _rl_last_c_pos = lendiff + modmark; + + /* Now if we have printed the prompt string because the first difference + was within the prompt, see if we need to recompute where the lines + differ. Check whether where we are now is past the last place where + the old and new lines are the same and short-circuit now if we are. */ + if ((od <= prompt_last_invisible || nd <= prompt_last_invisible) && + omax == nmax && + lendiff > (ols-old) && lendiff > (nls-new)) + return; + + /* XXX - we need to fix up our calculations if we are now past the + old ofd/nfd and the prompt length (or line length) has changed. + We punt on the problem and do a dumb update. We'd like to be able + to just output the prompt from the beginning of the line up to the + first difference, but you don't know the number of invisible + characters in that case. + This needs a lot of work to be efficient, but it usually doesn't matter. */ + if ((od <= prompt_last_invisible || nd <= prompt_last_invisible)) + { + nfd = new + lendiff; /* number of characters we output above */ + nfdf = new_face + lendiff; + nd = lendiff; + + /* Do a dumb update and return */ +dumb_update: + temp = ne - nfd; + if (temp > 0) + { + puts_face (nfd, nfdf, temp); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + _rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1); + /* Need to adjust here based on wrap_offset. Guess that if + this is the line containing the last line of the prompt + we need to adjust by + wrap_offset-prompt_invis_chars_first_line + on the assumption that this is the number of invisible + characters in the last line of the prompt. */ + if (wrap_offset > prompt_invis_chars_first_line && + current_line == prompt_last_screen_line && + prompt_physical_chars > _rl_screenwidth && + _rl_horizontal_scroll_mode == 0) + ADJUST_CPOS (wrap_offset - prompt_invis_chars_first_line); + + /* If we just output a new line including the prompt, and + the prompt includes invisible characters, we need to + account for them in the _rl_last_c_pos calculation, since + _rl_col_width does not. This happens when other code does + a goto dumb_update; */ + else if (current_line == 0 && + nfd == new && + prompt_invis_chars_first_line && + local_prompt_len <= temp && + wrap_offset >= prompt_invis_chars_first_line && + _rl_horizontal_scroll_mode == 0) + ADJUST_CPOS (prompt_invis_chars_first_line); + } + else + _rl_last_c_pos += temp; + } + /* This is a useful heuristic, but what we really want is to clear + if the new number of visible screen characters is less than the + old number of visible screen characters. If the prompt has changed, + we don't really have enough information about the visible line to + know for sure, so we use another heuristic calclulation below. */ + if (nmax < omax) + goto clear_rest_of_line; /* XXX */ + else if ((nmax - W_OFFSET(current_line, wrap_offset)) < (omax - W_OFFSET (current_line, visible_wrap_offset))) + goto clear_rest_of_line; + else + return; + } + } + + o_cpos = _rl_last_c_pos; + + /* When this function returns, _rl_last_c_pos is correct, and an absolute + cursor position in multibyte mode, but a buffer index when not in a + multibyte locale. */ + _rl_move_cursor_relative (od, old, old_face); + +#if defined (HANDLE_MULTIBYTE) + /* We need to indicate that the cursor position is correct in the presence of + invisible characters in the prompt string. Let's see if setting this when + we make sure we're at the end of the drawn prompt string works. */ + if (current_line == 0 && mb_cur_max > 1 && rl_byte_oriented == 0 && + (_rl_last_c_pos > 0 || o_cpos > 0) && + _rl_last_c_pos == prompt_physical_chars) + cpos_adjusted = 1; +#endif + + /* if (len (new) > len (old)) + lendiff == difference in buffer (bytes) + col_lendiff == difference on screen (columns) + When not using multibyte characters, these are equal */ + lendiff = (nls - nfd) - (ols - ofd); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + int newchars, newwidth, newind; + int oldchars, oldwidth, oldind; + + newchars = nls - new; + oldchars = ols - old; + + /* If we can do it, try to adjust nls and ols so that nls-new will + contain the entire new prompt string. That way we can use + prompt_physical_chars and not have to recompute column widths. + _rl_col_width adds wrap_offset and expects the caller to compensate, + which we do below, so we do the same thing if we don't call + _rl_col_width. + We don't have to compare, since we know the characters are the same. + The check of differing numbers of invisible chars may be extraneous. + XXX - experimental */ + if (current_line == 0 && nfd == new && newchars > prompt_last_invisible && + newchars <= local_prompt_len && + local_prompt_len <= nmax && + current_invis_chars != visible_wrap_offset) + { + while (newchars < nmax && oldchars < omax && newchars < local_prompt_len) + { +#if defined (HANDLE_MULTIBYTE) + newind = _rl_find_next_mbchar (new, newchars, 1, MB_FIND_NONZERO); + oldind = _rl_find_next_mbchar (old, oldchars, 1, MB_FIND_NONZERO); + + nls += newind - newchars; + ols += oldind - oldchars; + + newchars = newind; + oldchars = oldind; +#else + nls++; ols++; + newchars++; oldchars++; +#endif + } + newwidth = (newchars == local_prompt_len) ? prompt_physical_chars + wrap_offset + : _rl_col_width (new, 0, nls - new, 1); + /* if we changed nls and ols, we need to recompute lendiff */ + lendiff = (nls - nfd) - (ols - ofd); + + nlsf = new_face + (nls - new); + olsf = old_face + (ols - old); + } + else + newwidth = _rl_col_width (new, nfd - new, nls - new, 1); + + oldwidth = _rl_col_width (old, ofd - old, ols - old, 1); + + col_lendiff = newwidth - oldwidth; + } + else + col_lendiff = lendiff; + + /* col_lendiff uses _rl_col_width(), which doesn't know about whether or not + the multibyte characters it counts are invisible, so unless we're printing + the entire prompt string (in which case we can use prompt_physical_chars) + the count is short by the number of bytes in the invisible multibyte + characters - the number of multibyte characters. + + We don't have a good way to solve this without moving to something like + a bitmap that indicates which characters are visible and which are + invisible. We fix it up (imperfectly) in the caller and by trying to use + the entire prompt string wherever we can. */ + + /* If we are changing the number of invisible characters in a line, and + the spot of first difference is before the end of the invisible chars, + lendiff needs to be adjusted. */ + if (current_line == 0 && current_invis_chars != visible_wrap_offset) + { + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + lendiff += visible_wrap_offset - current_invis_chars; + col_lendiff += visible_wrap_offset - current_invis_chars; + } + else + { + lendiff += visible_wrap_offset - current_invis_chars; + col_lendiff = lendiff; + } + } + + /* We use temp as a count of the number of bytes from the first difference + to the end of the new line. col_temp is the corresponding number of + screen columns. A `dumb' update moves to the spot of first difference + and writes TEMP bytes. */ + /* Insert (diff (len (old), len (new)) ch. */ + temp = ne - nfd; + if (mb_cur_max > 1 && rl_byte_oriented == 0) + col_temp = _rl_col_width (new, nfd - new, ne - new, 1); + else + col_temp = temp; + + /* how many bytes from the new line buffer to write to the display */ + bytes_to_insert = nls - nfd; + + /* col_lendiff > 0 if we are adding characters to the line */ + if (col_lendiff > 0) /* XXX - was lendiff */ + { + /* Non-zero if we're increasing the number of lines. */ + int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; + + /* If col_lendiff is > 0, implying that the new string takes up more + screen real estate than the old, but lendiff is < 0, meaning that it + takes fewer bytes, we need to just output the characters starting + from the first difference. These will overwrite what is on the + display, so there's no reason to do a smart update. This can really + only happen in a multibyte environment. */ + if (lendiff < 0) + { + puts_face (nfd, nfdf, temp); + _rl_last_c_pos += col_temp; + /* If nfd begins before any invisible characters in the prompt, + adjust _rl_last_c_pos to account for wrap_offset and set + cpos_adjusted to let the caller know. */ + if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) + ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ + return; + } + /* Sometimes it is cheaper to print the characters rather than + use the terminal's capabilities. If we're growing the number + of lines, make sure we actually cause the new line to wrap + around on auto-wrapping terminals. */ + else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl)) + { + /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and + _rl_horizontal_scroll_mode == 1, inserting the characters with + _rl_term_IC or _rl_term_ic will screw up the screen because of the + invisible characters. We need to just draw them. */ + /* The same thing happens if we're trying to draw before the last + invisible character in the prompt string or we're increasing the + number of invisible characters in the line and we're not drawing + the entire prompt string. */ + if (*ols && ((_rl_horizontal_scroll_mode && + _rl_last_c_pos == 0 && + lendiff > prompt_visible_length && + current_invis_chars > 0) == 0) && + (((mb_cur_max > 1 && rl_byte_oriented == 0) && + current_line == 0 && wrap_offset && + ((nfd - new) <= prompt_last_invisible) && + (col_lendiff < prompt_visible_length)) == 0) && + (visible_wrap_offset >= current_invis_chars)) + { + open_some_spaces (col_lendiff); + puts_face (nfd, nfdf, bytes_to_insert); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); + else + _rl_last_c_pos += bytes_to_insert; + } + else if ((mb_cur_max == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0) + { + /* At the end of a line the characters do not have to + be "inserted". They can just be placed on the screen. */ + puts_face (nfd, nfdf, temp); + _rl_last_c_pos += col_temp; + return; + } + else /* just write from first difference to end of new line */ + { + puts_face (nfd, nfdf, temp); + _rl_last_c_pos += col_temp; + /* If nfd begins before the last invisible character in the + prompt, adjust _rl_last_c_pos to account for wrap_offset + and set cpos_adjusted to let the caller know. */ + if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) + ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ + return; + } + + if (bytes_to_insert > lendiff) + { + /* If nfd begins before the last invisible character in the + prompt, adjust _rl_last_c_pos to account for wrap_offset + and set cpos_adjusted to let the caller know. */ + if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) + ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ + } + } + else + { + /* cannot insert chars, write to EOL */ + puts_face (nfd, nfdf, temp); + _rl_last_c_pos += col_temp; + /* If we're in a multibyte locale and were before the last invisible + char in the current line (which implies we just output some invisible + characters) we need to adjust _rl_last_c_pos, since it represents + a physical character position. */ + /* The current_line*rl_screenwidth+prompt_invis_chars_first_line is a + crude attempt to compute how far into the new line buffer we are. + It doesn't work well in the face of multibyte characters and needs + to be rethought. XXX */ + if ((mb_cur_max > 1 && rl_byte_oriented == 0) && + current_line == prompt_last_screen_line && wrap_offset && + displaying_prompt_first_line && + wrap_offset != prompt_invis_chars_first_line && + ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth+prompt_invis_chars_first_line)))) + ADJUST_CPOS (wrap_offset - prompt_invis_chars_first_line); + + /* XXX - what happens if wrap_offset == prompt_invis_chars_first_line + and we are drawing the first line (current_line == 0)? We should + adjust by _rl_last_c_pos -= prompt_invis_chars_first_line */ + } + } + else /* Delete characters from line. */ + { + /* If possible and inexpensive to use terminal deletion, then do so. */ + if (_rl_term_dc && (2 * col_temp) >= -col_lendiff) + { + /* If all we're doing is erasing the invisible characters in the + prompt string, don't bother. It screws up the assumptions + about what's on the screen. */ + if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 && + displaying_prompt_first_line && + -lendiff == visible_wrap_offset) + col_lendiff = 0; + + /* If we have moved lmargin and we're shrinking the line, we've + already moved the cursor to the first character of the new line, + so deleting -col_lendiff characters will mess up the cursor + position calculation */ + if (_rl_horizontal_scroll_mode && displaying_prompt_first_line == 0 && + col_lendiff && _rl_last_c_pos < -col_lendiff) + col_lendiff = 0; + + if (col_lendiff) + delete_chars (-col_lendiff); /* delete (diff) characters */ + + /* Copy (new) chars to screen from first diff to last match, + overwriting what is there. */ + if (bytes_to_insert > 0) + { + /* If nfd begins at the prompt, or before the invisible + characters in the prompt, we need to adjust _rl_last_c_pos + in a multibyte locale to account for the wrap offset and + set cpos_adjusted accordingly. */ + puts_face (nfd, nfdf, bytes_to_insert); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + /* This still doesn't take into account whether or not the + characters that this counts are invisible. */ + _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); + if (current_line == 0 && wrap_offset && + displaying_prompt_first_line && + prompt_invis_chars_first_line && + _rl_last_c_pos >= prompt_invis_chars_first_line && + ((nfd - new) <= prompt_last_invisible)) + ADJUST_CPOS (prompt_invis_chars_first_line); + +#if 1 +#ifdef HANDLE_MULTIBYTE + /* If we write a non-space into the last screen column, + remove the note that we added a space to compensate for + a multibyte double-width character that didn't fit, since + it's only valid for what was previously there. */ + /* XXX - watch this */ + if (_rl_last_c_pos == _rl_screenwidth && + line_state_invisible->wrapped_line[current_line+1] && + nfd[bytes_to_insert-1] != ' ') + line_state_invisible->wrapped_line[current_line+1] = 0; +#endif +#endif + } + else + _rl_last_c_pos += bytes_to_insert; + + /* XXX - we only want to do this if we are at the end of the line + so we move there with _rl_move_cursor_relative */ + if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new))) + { + _rl_move_cursor_relative (ne-new, new, new_face); + goto clear_rest_of_line; + } + } + } + /* Otherwise, print over the existing material. */ + else + { + if (temp > 0) + { + /* If nfd begins at the prompt, or before the invisible + characters in the prompt, we need to adjust _rl_last_c_pos + in a multibyte locale to account for the wrap offset and + set cpos_adjusted accordingly. */ + puts_face (nfd, nfdf, temp); + _rl_last_c_pos += col_temp; /* XXX */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + if (current_line == 0 && wrap_offset && + displaying_prompt_first_line && + _rl_last_c_pos > wrap_offset && + ((nfd - new) <= prompt_last_invisible)) + ADJUST_CPOS (wrap_offset); /* XXX - prompt_invis_chars_first_line? */ + } + } +clear_rest_of_line: + lendiff = (oe - old) - (ne - new); + if (mb_cur_max > 1 && rl_byte_oriented == 0) + col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1); + else + col_lendiff = lendiff; + + /* If we've already printed over the entire width of the screen, + including the old material, then col_lendiff doesn't matter and + space_to_eol will insert too many spaces. XXX - maybe we should + adjust col_lendiff based on the difference between _rl_last_c_pos + and _rl_screenwidth */ + if (col_lendiff && ((mb_cur_max == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth))) + { + if (_rl_term_autowrap && current_line < inv_botlin) + space_to_eol (col_lendiff); + else + _rl_clear_to_eol (col_lendiff); + } + } + } +} + +/* Tell the update routines that we have moved onto a new (empty) line. */ +int +rl_on_new_line (void) +{ + if (visible_line) + visible_line[0] = '\0'; + + _rl_last_c_pos = _rl_last_v_pos = 0; + _rl_vis_botlin = last_lmargin = 0; + if (vis_lbreaks) + vis_lbreaks[0] = vis_lbreaks[1] = 0; + visible_wrap_offset = 0; + return 0; +} + +/* Clear all screen lines occupied by the current readline line buffer + (visible line) */ +int +rl_clear_visible_line (void) +{ + int curr_line; + + /* Make sure we move to column 0 so we clear the entire line */ + _rl_cr (); + _rl_last_c_pos = 0; + + /* Move to the last screen line of the current visible line */ + _rl_move_vert (_rl_vis_botlin); + + /* And erase screen lines going up to line 0 (first visible line) */ + for (curr_line = _rl_last_v_pos; curr_line >= 0; curr_line--) + { + _rl_move_vert (curr_line); + _rl_clear_to_eol (0); + } + + return 0; +} + +/* Tell the update routines that we have moved onto a new line with the + prompt already displayed. Code originally from the version of readline + distributed with CLISP. rl_expand_prompt must have already been called + (explicitly or implicitly). This still doesn't work exactly right; it + should use expand_prompt() */ +int +rl_on_new_line_with_prompt (void) +{ + int prompt_size, i, l, real_screenwidth, newlines; + char *prompt_last_line, *lprompt; + + /* Initialize visible_line and invisible_line to ensure that they can hold + the already-displayed prompt. */ + prompt_size = strlen (rl_prompt) + 1; + init_line_structures (prompt_size); + + /* Make sure the line structures hold the already-displayed prompt for + redisplay. */ + lprompt = local_prompt ? local_prompt : rl_prompt; + strcpy (visible_line, lprompt); + strcpy (invisible_line, lprompt); + + /* If the prompt contains newlines, take the last tail. */ + prompt_last_line = strrchr (rl_prompt, '\n'); + if (!prompt_last_line) + prompt_last_line = rl_prompt; + + l = strlen (prompt_last_line); + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */ + else + _rl_last_c_pos = l; + + /* Dissect prompt_last_line into screen lines. Note that here we have + to use the real screenwidth. Readline's notion of screenwidth might be + one less, see terminal.c. */ + real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1); + _rl_last_v_pos = l / real_screenwidth; + /* If the prompt length is a multiple of real_screenwidth, we don't know + whether the cursor is at the end of the last line, or already at the + beginning of the next line. Output a newline just to be safe. */ + if (l > 0 && (l % real_screenwidth) == 0) + _rl_output_some_chars ("\n", 1); + last_lmargin = 0; + + newlines = 0; i = 0; + while (i <= l) + { + _rl_vis_botlin = newlines; + vis_lbreaks[newlines++] = i; + i += real_screenwidth; + } + vis_lbreaks[newlines] = l; + visible_wrap_offset = 0; + + rl_display_prompt = rl_prompt; /* XXX - make sure it's set */ + + return 0; +} + +/* Actually update the display, period. */ +int +rl_forced_update_display (void) +{ + register char *temp; + + if (visible_line) + { + temp = visible_line; + while (*temp) + *temp++ = '\0'; + } + rl_on_new_line (); + forced_display++; + (*rl_redisplay_function) (); + return 0; +} + +/* Redraw only the last line of a multi-line prompt. */ +void +rl_redraw_prompt_last_line (void) +{ + char *t; + + t = strrchr (rl_display_prompt, '\n'); + if (t) + redraw_prompt (++t); + else + rl_forced_update_display (); +} + +/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices. + (Well, when we don't have multibyte characters, _rl_last_c_pos is a + buffer index.) + DATA is the contents of the screen line of interest; i.e., where + the movement is being done. + DATA is always the visible line or the invisible line */ +static void +_rl_move_cursor_relative (int new, const char *data, const char *dataf) +{ + register int i; + int woff; /* number of invisible chars on current line */ + int cpos, dpos; /* current and desired cursor positions */ + int adjust; + int in_invisline; + int mb_cur_max = MB_CUR_MAX; + + woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset); + cpos = _rl_last_c_pos; + + if (cpos == 0 && cpos == new) + return; + +#if defined (HANDLE_MULTIBYTE) + /* If we have multibyte characters, NEW is indexed by the buffer point in + a multibyte string, but _rl_last_c_pos is the display position. In + this case, NEW's display position is not obvious and must be + calculated. We need to account for invisible characters in this line, + as long as we are past them and they are counted by _rl_col_width. */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + adjust = 1; + /* Try to short-circuit common cases and eliminate a bunch of multibyte + character function calls. */ + /* 1. prompt string */ + if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0) + { + dpos = prompt_physical_chars; + cpos_adjusted = 1; + adjust = 0; + } + /* 2. prompt_string + line contents */ + else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0) + { + dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1); + cpos_adjusted = 1; + adjust = 0; + } + else + dpos = _rl_col_width (data, 0, new, 1); + + if (displaying_prompt_first_line == 0) + adjust = 0; + + /* yet another special case: printing the last line of a prompt with + multibyte characters and invisible characters whose printable length + exceeds the screen width with the last invisible character + (prompt_last_invisible) in the last line. IN_INVISLINE is the + offset of DATA in invisible_line */ + in_invisline = 0; + if (data > invisible_line && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1]) + in_invisline = data - invisible_line; + + /* Use NEW when comparing against the last invisible character in the + prompt string, since they're both buffer indices and DPOS is a + desired display position. */ + /* NEW is relative to the current displayed line, while + PROMPT_LAST_INVISIBLE is relative to the entire (wrapped) line. + Need a way to reconcile these two variables by turning NEW into a + buffer position relative to the start of the line */ + if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */ + (new+in_invisline > prompt_last_invisible) || /* invisible line */ + (prompt_physical_chars >= _rl_screenwidth && /* visible line */ + _rl_last_v_pos == prompt_last_screen_line && + wrap_offset >= woff && dpos >= woff && + new > (prompt_last_invisible-(vis_lbreaks[_rl_last_v_pos])-wrap_offset)))) + /* XXX last comparison might need to be >= */ + { + dpos -= woff; + /* Since this will be assigned to _rl_last_c_pos at the end (more + precisely, _rl_last_c_pos == dpos when this function returns), + let the caller know. */ + cpos_adjusted = 1; + } + } + else +#endif + dpos = new; + + /* If we don't have to do anything, then return. */ + if (cpos == dpos) + return; + + /* It may be faster to output a CR, and then move forwards instead + of moving backwards. */ + /* i == current physical cursor position. */ +#if defined (HANDLE_MULTIBYTE) + if (mb_cur_max > 1 && rl_byte_oriented == 0) + i = _rl_last_c_pos; + else +#endif + i = _rl_last_c_pos - woff; + if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) || + (_rl_term_autowrap && i == _rl_screenwidth)) + { + _rl_cr (); + cpos = _rl_last_c_pos = 0; + } + + if (cpos < dpos) + { + /* Move the cursor forward. We do it by printing the command + to move the cursor forward if there is one, else print that + portion of the output buffer again. Which is cheaper? */ + + /* The above comment is left here for posterity. It is faster + to print one character (non-control) than to print a control + sequence telling the terminal to move forward one character. + That kind of control is for people who don't know what the + data is underneath the cursor. */ + + /* However, we need a handle on where the current display position is + in the buffer for the immediately preceding comment to be true. + In multibyte locales, we don't currently have that info available. + Without it, we don't know where the data we have to display begins + in the buffer and we have to go back to the beginning of the screen + line. In this case, we can use the terminal sequence to move forward + if it's available. */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + { + if (_rl_term_forward_char) + { + for (i = cpos; i < dpos; i++) + tputs (_rl_term_forward_char, 1, _rl_output_character_function); + } + else + { + _rl_cr (); + puts_face (data, dataf, new); + } + } + else + puts_face (data + cpos, dataf + cpos, new - cpos); + } + +#if defined (HANDLE_MULTIBYTE) + /* NEW points to the buffer point, but _rl_last_c_pos is the display point. + The byte length of the string is probably bigger than the column width + of the string, which means that if NEW == _rl_last_c_pos, then NEW's + display point is less than _rl_last_c_pos. */ +#endif + else if (cpos > dpos) + _rl_backspace (cpos - dpos); + + _rl_last_c_pos = dpos; +} + +/* PWP: move the cursor up or down. */ +void +_rl_move_vert (int to) +{ + register int delta, i; + + if (_rl_last_v_pos == to || to > _rl_screenheight) + return; + + if ((delta = to - _rl_last_v_pos) > 0) + { + for (i = 0; i < delta; i++) + putc ('\n', rl_outstream); + _rl_cr (); + _rl_last_c_pos = 0; + } + else + { /* delta < 0 */ +#ifdef __DJGPP__ + int row, col; + + fflush (rl_outstream); + ScreenGetCursor (&row, &col); + ScreenSetCursor (row + delta, col); + i = -delta; +#else + if (_rl_term_up && *_rl_term_up) + for (i = 0; i < -delta; i++) + tputs (_rl_term_up, 1, _rl_output_character_function); +#endif /* !__DJGPP__ */ + } + + _rl_last_v_pos = to; /* Now TO is here */ +} + +/* Physically print C on rl_outstream. This is for functions which know + how to optimize the display. Return the number of characters output. */ +int +rl_show_char (int c) +{ + int n = 1; + if (META_CHAR (c) && (_rl_output_meta_chars == 0)) + { + fprintf (rl_outstream, "M-"); + n += 2; + c = UNMETA (c); + } + +#if defined (DISPLAY_TABS) + if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT) +#else + if (CTRL_CHAR (c) || c == RUBOUT) +#endif /* !DISPLAY_TABS */ + { + fprintf (rl_outstream, "C-"); + n += 2; + c = CTRL_CHAR (c) ? UNCTRL (c) : '?'; + } + + putc (c, rl_outstream); + fflush (rl_outstream); + return n; +} + +int +rl_character_len (int c, int pos) +{ + unsigned char uc; + + uc = (unsigned char)c; + + if (META_CHAR (uc)) + return ((_rl_output_meta_chars == 0) ? 4 : 1); + + if (uc == '\t') + { +#if defined (DISPLAY_TABS) + return (((pos | 7) + 1) - pos); +#else + return (2); +#endif /* !DISPLAY_TABS */ + } + + if (CTRL_CHAR (c) || c == RUBOUT) + return (2); + + return ((ISPRINT (uc)) ? 1 : 2); +} +/* How to print things in the "echo-area". The prompt is treated as a + mini-modeline. */ +static int msg_saved_prompt = 0; + +#if defined (USE_VARARGS) +int +#if defined (PREFER_STDARG) +rl_message (const char *format, ...) +#else +rl_message (va_alist) + va_dcl +#endif +{ + va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif +#if defined (HAVE_VSNPRINTF) + int bneed; +#endif + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + + if (msg_buf == 0) + msg_buf = xmalloc (msg_bufsiz = 128); + +#if defined (HAVE_VSNPRINTF) + bneed = vsnprintf (msg_buf, msg_bufsiz, format, args); + if (bneed >= msg_bufsiz - 1) + { + msg_bufsiz = bneed + 1; + msg_buf = xrealloc (msg_buf, msg_bufsiz); + va_end (args); + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + vsnprintf (msg_buf, msg_bufsiz - 1, format, args); + } +#else + vsprintf (msg_buf, format, args); + msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */ +#endif + va_end (args); + + if (saved_local_prompt == 0) + { + rl_save_prompt (); + msg_saved_prompt = 1; + } + else if (local_prompt != saved_local_prompt) + { + FREE (local_prompt); + FREE (local_prompt_prefix); + local_prompt = (char *)NULL; + } + rl_display_prompt = msg_buf; + local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_prefix = (char *)NULL; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; + (*rl_redisplay_function) (); + + return 0; +} +#else /* !USE_VARARGS */ +int +rl_message (format, arg1, arg2) + char *format; +{ + if (msg_buf == 0) + msg_buf = xmalloc (msg_bufsiz = 128); + + sprintf (msg_buf, format, arg1, arg2); + msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */ + + rl_display_prompt = msg_buf; + if (saved_local_prompt == 0) + { + rl_save_prompt (); + msg_saved_prompt = 1; + } + else if (local_prompt != saved_local_prompt) + { + FREE (local_prompt); + FREE (local_prompt_prefix); + local_prompt = (char *)NULL; + } + local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_prefix = (char *)NULL; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; + (*rl_redisplay_function) (); + + return 0; +} +#endif /* !USE_VARARGS */ + +/* How to clear things from the "echo-area". */ +int +rl_clear_message (void) +{ + rl_display_prompt = rl_prompt; + if (msg_saved_prompt) + { + rl_restore_prompt (); + msg_saved_prompt = 0; + } + (*rl_redisplay_function) (); + return 0; +} + +int +rl_reset_line_state (void) +{ + rl_on_new_line (); + + rl_display_prompt = rl_prompt ? rl_prompt : ""; + forced_display = 1; + return 0; +} + +/* Save all of the variables associated with the prompt and its display. Most + of the complexity is dealing with the invisible characters in the prompt + string and where they are. There are enough of these that I should consider + a struct. */ +void +rl_save_prompt (void) +{ + saved_local_prompt = local_prompt; + saved_local_prefix = local_prompt_prefix; + saved_prefix_length = prompt_prefix_length; + saved_local_length = local_prompt_len; + saved_last_invisible = prompt_last_invisible; + saved_visible_length = prompt_visible_length; + saved_invis_chars_first_line = prompt_invis_chars_first_line; + saved_physical_chars = prompt_physical_chars; + saved_local_prompt_newlines = local_prompt_newlines; + + local_prompt = local_prompt_prefix = (char *)0; + local_prompt_len = 0; + local_prompt_newlines = (int *)0; + + prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; + prompt_invis_chars_first_line = prompt_physical_chars = 0; +} + +void +rl_restore_prompt (void) +{ + FREE (local_prompt); + FREE (local_prompt_prefix); + FREE (local_prompt_newlines); + + local_prompt = saved_local_prompt; + local_prompt_prefix = saved_local_prefix; + local_prompt_len = saved_local_length; + local_prompt_newlines = saved_local_prompt_newlines; + + prompt_prefix_length = saved_prefix_length; + prompt_last_invisible = saved_last_invisible; + prompt_visible_length = saved_visible_length; + prompt_invis_chars_first_line = saved_invis_chars_first_line; + prompt_physical_chars = saved_physical_chars; + + /* can test saved_local_prompt to see if prompt info has been saved. */ + saved_local_prompt = saved_local_prefix = (char *)0; + saved_local_length = 0; + saved_last_invisible = saved_visible_length = saved_prefix_length = 0; + saved_invis_chars_first_line = saved_physical_chars = 0; + saved_local_prompt_newlines = 0; +} + +char * +_rl_make_prompt_for_search (int pchar) +{ + int len; + char *pmt, *p; + + rl_save_prompt (); + + /* We've saved the prompt, and can do anything with the various prompt + strings we need before they're restored. We want the unexpanded + portion of the prompt string after any final newline. */ + p = rl_prompt ? strrchr (rl_prompt, '\n') : 0; + if (p == 0) + { + len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; + pmt = (char *)xmalloc (len + 2); + if (len) + strcpy (pmt, rl_prompt); + pmt[len] = pchar; + pmt[len+1] = '\0'; + } + else + { + p++; + len = strlen (p); + pmt = (char *)xmalloc (len + 2); + if (len) + strcpy (pmt, p); + pmt[len] = pchar; + pmt[len+1] = '\0'; + } + + /* will be overwritten by expand_prompt, called from rl_message */ + prompt_physical_chars = saved_physical_chars + 1; + return pmt; +} + +/* Quick redisplay hack when erasing characters at the end of the line. */ +void +_rl_erase_at_end_of_line (int l) +{ + register int i; + + _rl_backspace (l); + for (i = 0; i < l; i++) + putc (' ', rl_outstream); + _rl_backspace (l); + for (i = 0; i < l; i++) + visible_line[--_rl_last_c_pos] = '\0'; + rl_display_fixed++; +} + +/* Clear to the end of the line. COUNT is the minimum + number of character spaces to clear, but we use a terminal escape + sequence if available. */ +void +_rl_clear_to_eol (int count) +{ +#ifndef __MSDOS__ + if (_rl_term_clreol) + tputs (_rl_term_clreol, 1, _rl_output_character_function); + else +#endif + if (count) + space_to_eol (count); +} + +/* Clear to the end of the line using spaces. COUNT is the minimum + number of character spaces to clear, */ +static void +space_to_eol (int count) +{ + register int i; + + for (i = 0; i < count; i++) + putc (' ', rl_outstream); + + _rl_last_c_pos += count; +} + +void +_rl_clear_screen (int clrscr) +{ +#if defined (__DJGPP__) + ScreenClear (); + ScreenSetCursor (0, 0); +#else + if (_rl_term_clrpag) + { + tputs (_rl_term_clrpag, 1, _rl_output_character_function); + if (clrscr && _rl_term_clrscroll) + tputs (_rl_term_clrscroll, 1, _rl_output_character_function); + } + else + rl_crlf (); +#endif /* __DJGPP__ */ +} + +/* Insert COUNT characters from STRING to the output stream at column COL. */ +static void +insert_some_chars (char *string, int count, int col) +{ + open_some_spaces (col); + _rl_output_some_chars (string, count); +} + +/* Insert COL spaces, keeping the cursor at the same position. We follow the + ncurses documentation and use either im/ei with explicit spaces, or IC/ic + by itself. We assume there will either be ei or we don't need to use it. */ +static void +open_some_spaces (int col) +{ +#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION)) + char *buffer; + register int i; + + /* If IC is defined, then we do not have to "enter" insert mode. */ + if (_rl_term_IC) + { + buffer = tgoto (_rl_term_IC, 0, col); + tputs (buffer, 1, _rl_output_character_function); + } + else if (_rl_term_im && *_rl_term_im) + { + tputs (_rl_term_im, 1, _rl_output_character_function); + /* just output the desired number of spaces */ + for (i = col; i--; ) + _rl_output_character_function (' '); + /* If there is a string to turn off insert mode, use it now. */ + if (_rl_term_ei && *_rl_term_ei) + tputs (_rl_term_ei, 1, _rl_output_character_function); + /* and move back the right number of spaces */ + _rl_backspace (col); + } + else if (_rl_term_ic && *_rl_term_ic) + { + /* If there is a special command for inserting characters, then + use that first to open up the space. */ + for (i = col; i--; ) + tputs (_rl_term_ic, 1, _rl_output_character_function); + } +#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/ +} + +/* Delete COUNT characters from the display line. */ +static void +delete_chars (int count) +{ + if (count > _rl_screenwidth) /* XXX */ + return; + +#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION)) + if (_rl_term_DC && *_rl_term_DC) + { + char *buffer; + buffer = tgoto (_rl_term_DC, count, count); + tputs (buffer, count, _rl_output_character_function); + } + else + { + if (_rl_term_dc && *_rl_term_dc) + while (count--) + tputs (_rl_term_dc, 1, _rl_output_character_function); + } +#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/ +} + +void +_rl_update_final (void) +{ + int full_lines, woff, botline_length; + + if (line_structures_initialized == 0) + return; + + full_lines = 0; + /* If the cursor is the only thing on an otherwise-blank last line, + compensate so we don't print an extra CRLF. */ + if (_rl_vis_botlin && _rl_last_c_pos == 0 && + visible_line[vis_lbreaks[_rl_vis_botlin]] == 0) + { + _rl_vis_botlin--; + full_lines = 1; + } + _rl_move_vert (_rl_vis_botlin); + woff = W_OFFSET(_rl_vis_botlin, wrap_offset); + botline_length = VIS_LLEN(_rl_vis_botlin) - woff; + /* If we've wrapped lines, remove the final xterm line-wrap flag. */ + if (full_lines && _rl_term_autowrap && botline_length == _rl_screenwidth) + { + char *last_line, *last_face; + + /* LAST_LINE includes invisible characters, so if you want to get the + last character of the first line, you have to take WOFF into account. + This needs to be done for both calls to _rl_move_cursor_relative, + which takes a buffer position as the first argument, and any direct + subscripts of LAST_LINE. */ + last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */ + last_face = &vis_face[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */ + cpos_buffer_position = -1; /* don't know where we are in buffer */ + _rl_move_cursor_relative (_rl_screenwidth - 1 + woff, last_line, last_face); /* XXX */ + _rl_clear_to_eol (0); + puts_face (&last_line[_rl_screenwidth - 1 + woff], + &last_face[_rl_screenwidth - 1 + woff], 1); + } + _rl_vis_botlin = 0; + if (botline_length > 0 || _rl_last_c_pos > 0) + rl_crlf (); + fflush (rl_outstream); + rl_display_fixed++; +} + +/* Move to the start of the current line. */ +static void +cr (void) +{ + _rl_cr (); + _rl_last_c_pos = 0; +} + +/* Redraw the last line of a multi-line prompt that may possibly contain + terminal escape sequences. Called with the cursor at column 0 of the + line to draw the prompt on. */ +static void +redraw_prompt (char *t) +{ + char *oldp; + + oldp = rl_display_prompt; + rl_save_prompt (); + + rl_display_prompt = t; + local_prompt = expand_prompt (t, PMT_MULTILINE, + &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line, + &prompt_physical_chars); + local_prompt_prefix = (char *)NULL; + local_prompt_len = local_prompt ? strlen (local_prompt) : 0; + + rl_forced_update_display (); + + rl_display_prompt = oldp; + rl_restore_prompt(); +} + +/* Redisplay the current line after a SIGWINCH is received. */ +void +_rl_redisplay_after_sigwinch (void) +{ + char *t; + + /* Clear the last line (assuming that the screen size change will result in + either more or fewer characters on that line only) and put the cursor at + column 0. Make sure the right thing happens if we have wrapped to a new + screen line. */ + if (_rl_term_cr) + { + _rl_move_vert (_rl_vis_botlin); + + _rl_cr (); + _rl_last_c_pos = 0; + +#if !defined (__MSDOS__) + if (_rl_term_clreol) + tputs (_rl_term_clreol, 1, _rl_output_character_function); + else +#endif + { + space_to_eol (_rl_screenwidth); + _rl_cr (); + } + + if (_rl_last_v_pos > 0) + _rl_move_vert (0); + } + else + rl_crlf (); + + /* Redraw only the last line of a multi-line prompt. */ + t = strrchr (rl_display_prompt, '\n'); + if (t) + redraw_prompt (++t); + else + rl_forced_update_display (); +} + +void +_rl_clean_up_for_exit (void) +{ + if (_rl_echoing_p) + { + if (_rl_vis_botlin > 0) /* minor optimization plus bug fix */ + _rl_move_vert (_rl_vis_botlin); + _rl_vis_botlin = 0; + fflush (rl_outstream); + rl_restart_output (1, 0); + } +} + +void +_rl_erase_entire_line (void) +{ + cr (); + _rl_clear_to_eol (0); + cr (); + fflush (rl_outstream); +} + +void +_rl_ttyflush (void) +{ + fflush (rl_outstream); +} + +/* return the `current display line' of the cursor -- the number of lines to + move up to get to the first screen line of the current readline line. */ +int +_rl_current_display_line (void) +{ + int ret, nleft; + + /* Find out whether or not there might be invisible characters in the + editing buffer. */ + if (rl_display_prompt == rl_prompt) + nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length; + else + nleft = _rl_last_c_pos - _rl_screenwidth; + + if (nleft > 0) + ret = 1 + nleft / _rl_screenwidth; + else + ret = 0; + + return ret; +} + +void +_rl_refresh_line (void) +{ + rl_clear_visible_line (); + rl_redraw_prompt_last_line (); + rl_keep_mark_active (); +} + +#if defined (HANDLE_MULTIBYTE) +/* Calculate the number of screen columns occupied by STR from START to END. + In the case of multibyte characters with stateful encoding, we have to + scan from the beginning of the string to take the state into account. */ +static int +_rl_col_width (const char *str, int start, int end, int flags) +{ + wchar_t wc; + mbstate_t ps; + int tmp, point, width, max; + + if (end <= start) + return 0; + if (MB_CUR_MAX == 1 || rl_byte_oriented) + /* this can happen in some cases where it's inconvenient to check */ + return (end - start); + + memset (&ps, 0, sizeof (mbstate_t)); + + point = 0; + max = end; + + /* Try to short-circuit common cases. The adjustment to remove wrap_offset + is done by the caller. */ + /* 1. prompt string */ + if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0) + return (prompt_physical_chars + wrap_offset); + /* 2. prompt string + line contents */ + else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0) + { + tmp = prompt_physical_chars + wrap_offset; + /* XXX - try to call ourselves recursively with non-prompt portion */ + tmp += _rl_col_width (str, local_prompt_len, end, flags); + return (tmp); + } + + while (point < start) + { + if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point])) + { + memset (&ps, 0, sizeof (mbstate_t)); + tmp = 1; + } + else + tmp = mbrlen (str + point, max, &ps); + if (MB_INVALIDCH ((size_t)tmp)) + { + /* In this case, the bytes are invalid or too short to compose a + multibyte character, so we assume that the first byte represents + a single character. */ + point++; + max--; + + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (tmp)) + break; /* Found '\0' */ + else + { + point += tmp; + max -= tmp; + } + } + + /* If START is not a byte that starts a character, then POINT will be + greater than START. In this case, assume that (POINT - START) gives + a byte count that is the number of columns of difference. */ + width = point - start; + + while (point < end) + { + if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point])) + { + tmp = 1; + wc = (wchar_t) str[point]; + } + else + tmp = mbrtowc (&wc, str + point, max, &ps); + if (MB_INVALIDCH ((size_t)tmp)) + { + /* In this case, the bytes are invalid or too short to compose a + multibyte character, so we assume that the first byte represents + a single character. */ + point++; + max--; + + /* and assume that the byte occupies a single column. */ + width++; + + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (tmp)) + break; /* Found '\0' */ + else + { + point += tmp; + max -= tmp; + tmp = WCWIDTH(wc); + width += (tmp >= 0) ? tmp : 1; + } + } + + width += point - end; + + return width; +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/utshell-0.5.0/lib/readline/doc/fdl.texi b/utshell-0.5.0/lib/readline/doc/fdl.texi new file mode 100644 index 00000000..8805f1a4 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/fdl.texi @@ -0,0 +1,506 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +@sc{ascii} without markup, Texinfo input format, La@TeX{} input +format, @acronym{SGML} or @acronym{XML} using a publicly available +@acronym{DTD}, and standard-conforming simple @acronym{HTML}, +PostScript or @acronym{PDF} designed for human modification. Examples +of transparent image formats include @acronym{PNG}, @acronym{XCF} and +@acronym{JPG}. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, @acronym{SGML} or +@acronym{XML} for which the @acronym{DTD} and/or processing tools are +not generally available, and the machine-generated @acronym{HTML}, +PostScript or @acronym{PDF} produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.'' line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: + diff --git a/utshell-0.5.0/lib/readline/doc/history.texi b/utshell-0.5.0/lib/readline/doc/history.texi new file mode 100644 index 00000000..7a3a4767 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/history.texi @@ -0,0 +1,85 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header (This is for running Texinfo on a region.) +@setfilename history.info +@settitle GNU History Library +@include version.texi + +@c %**end of header (This is for running Texinfo on a region.) + +@copying +This document describes the GNU History library +(version @value{VERSION}, @value{UPDATED}), +a programming tool that provides a consistent user interface for +recalling lines of previously typed input. + +Copyright @copyright{} 1988--2020 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the section entitled +``GNU Free Documentation License''. + +@end quotation +@end copying + +@dircategory Libraries +@direntry +* History: (history). The GNU history library API. +@end direntry + +@titlepage +@title GNU History Library +@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}. +@subtitle @value{UPDATED-MONTH} +@author Chet Ramey, Case Western Reserve University +@author Brian Fox, Free Software Foundation + +@page + +@vskip 0pt plus 1filll +@insertcopying + +@end titlepage + +@contents + +@ifnottex +@node Top +@top GNU History Library + +This document describes the GNU History library, a programming tool that +provides a consistent user interface for recalling lines of previously +typed input. + +@menu +* Using History Interactively:: GNU History User's Manual. +* Programming with GNU History:: GNU History Programmer's Manual. +* GNU Free Documentation License:: License for copying this manual. +* Concept Index:: Index of concepts described in this manual. +* Function and Variable Index:: Index of externally visible functions + and variables. +@end menu +@end ifnottex + +@syncodeindex fn vr + +@include hsuser.texi +@include hstech.texi + +@node GNU Free Documentation License +@appendix GNU Free Documentation License + +@include fdl.texi + +@node Concept Index +@appendix Concept Index +@printindex cp + +@node Function and Variable Index +@appendix Function and Variable Index +@printindex vr + +@bye diff --git a/utshell-0.5.0/lib/readline/doc/hstech.texi b/utshell-0.5.0/lib/readline/doc/hstech.texi new file mode 100644 index 00000000..7ac11953 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/hstech.texi @@ -0,0 +1,602 @@ +@ignore +This file documents the user interface to the GNU History library. + +Copyright (C) 1988-2020 Free Software Foundation, Inc. +Authored by Brian Fox and Chet Ramey. + +Permission is granted to make and distribute verbatim copies of this manual +provided the copyright notice and this permission notice are preserved on +all copies. + +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission notice +identical to this one except for the removal of this paragraph (this +paragraph not being relevant to the printed manual). + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +GNU Copyright statement is available to the distributee, and provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end ignore + +@node Programming with GNU History +@chapter Programming with GNU History + +This chapter describes how to interface programs that you write +with the @sc{gnu} History Library. +It should be considered a technical guide. +For information on the interactive use of @sc{gnu} History, @pxref{Using +History Interactively}. + +@menu +* Introduction to History:: What is the GNU History library for? +* History Storage:: How information is stored. +* History Functions:: Functions that you can use. +* History Variables:: Variables that control behaviour. +* History Programming Example:: Example of using the GNU History Library. +@end menu + +@node Introduction to History +@section Introduction to History + +Many programs read input from the user a line at a time. The @sc{gnu} +History library is able to keep track of those lines, associate arbitrary +data with each line, and utilize information from previous lines in +composing new ones. + +A programmer using the History library has available functions +for remembering lines on a history list, associating arbitrary data +with a line, removing lines from the list, searching through the list +for a line containing an arbitrary text string, and referencing any line +in the list directly. In addition, a history @dfn{expansion} function +is available which provides for a consistent user interface across +different programs. + +The user using programs written with the History library has the +benefit of a consistent user interface with a set of well-known +commands for manipulating the text of previous lines and using that text +in new commands. The basic history manipulation commands are similar to +the history substitution provided by @code{csh}. + +The programmer can also use the Readline library, which +includes some history manipulation by default, and has the added +advantage of command line editing. + +Before declaring any functions using any functionality the History +library provides in other code, an application writer should include +the file @code{} in any file that uses the +History library's features. It supplies extern declarations for all +of the library's public functions and variables, and declares all of +the public data structures. + +@node History Storage +@section History Storage + +The history list is an array of history entries. A history entry is +declared as follows: + +@example +typedef void *histdata_t; + +typedef struct _hist_entry @{ + char *line; + char *timestamp; + histdata_t data; +@} HIST_ENTRY; +@end example + +The history list itself might therefore be declared as + +@example +HIST_ENTRY **the_history_list; +@end example + +The state of the History library is encapsulated into a single structure: + +@example +/* + * A structure used to pass around the current state of the history. + */ +typedef struct _hist_state @{ + HIST_ENTRY **entries; /* Pointer to the entries themselves. */ + int offset; /* The location pointer within this array. */ + int length; /* Number of elements within this array. */ + int size; /* Number of slots allocated to this array. */ + int flags; +@} HISTORY_STATE; +@end example + +If the flags member includes @code{HS_STIFLED}, the history has been +stifled. + +@node History Functions +@section History Functions + +This section describes the calling sequence for the various functions +exported by the @sc{gnu} History library. + +@menu +* Initializing History and State Management:: Functions to call when you + want to use history in a + program. +* History List Management:: Functions used to manage the list + of history entries. +* Information About the History List:: Functions returning information about + the history list. +* Moving Around the History List:: Functions used to change the position + in the history list. +* Searching the History List:: Functions to search the history list + for entries containing a string. +* Managing the History File:: Functions that read and write a file + containing the history list. +* History Expansion:: Functions to perform csh-like history + expansion. +@end menu + +@node Initializing History and State Management +@subsection Initializing History and State Management + +This section describes functions used to initialize and manage +the state of the History library when you want to use the history +functions in your program. + +@deftypefun void using_history (void) +Begin a session in which the history functions might be used. This +initializes the interactive variables. +@end deftypefun + +@deftypefun {HISTORY_STATE *} history_get_history_state (void) +Return a structure describing the current state of the input history. +@end deftypefun + +@deftypefun void history_set_history_state (HISTORY_STATE *state) +Set the state of the history list according to @var{state}. +@end deftypefun + +@node History List Management +@subsection History List Management + +These functions manage individual entries on the history list, or set +parameters managing the list itself. + +@deftypefun void add_history (const char *string) +Place @var{string} at the end of the history list. The associated data +field (if any) is set to @code{NULL}. +If the maximum number of history entries has been set using +@code{stifle_history()}, and the new number of history entries would exceed +that maximum, the oldest history entry is removed. +@end deftypefun + +@deftypefun void add_history_time (const char *string) +Change the time stamp associated with the most recent history entry to +@var{string}. +@end deftypefun + +@deftypefun {HIST_ENTRY *} remove_history (int which) +Remove history entry at offset @var{which} from the history. The +removed element is returned so you can free the line, data, +and containing structure. +@end deftypefun + +@deftypefun {histdata_t} free_history_entry (HIST_ENTRY *histent) +Free the history entry @var{histent} and any history library private +data associated with it. Returns the application-specific data +so the caller can dispose of it. +@end deftypefun + +@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data) +Make the history entry at offset @var{which} have @var{line} and @var{data}. +This returns the old entry so the caller can dispose of any +application-specific data. In the case +of an invalid @var{which}, a @code{NULL} pointer is returned. +@end deftypefun + +@deftypefun void clear_history (void) +Clear the history list by deleting all the entries. +@end deftypefun + +@deftypefun void stifle_history (int max) +Stifle the history list, remembering only the last @var{max} entries. +The history list will contain only @var{max} entries at a time. +@end deftypefun + +@deftypefun int unstifle_history (void) +Stop stifling the history. This returns the previously-set +maximum number of history entries (as set by @code{stifle_history()}). +The value is positive if the history was +stifled, negative if it wasn't. +@end deftypefun + +@deftypefun int history_is_stifled (void) +Returns non-zero if the history is stifled, zero if it is not. +@end deftypefun + +@node Information About the History List +@subsection Information About the History List + +These functions return information about the entire history list or +individual list entries. + +@deftypefun {HIST_ENTRY **} history_list (void) +Return a @code{NULL} terminated array of @code{HIST_ENTRY *} which is the +current input history. Element 0 of this list is the beginning of time. +If there is no history, return @code{NULL}. +@end deftypefun + +@deftypefun int where_history (void) +Returns the offset of the current history element. +@end deftypefun + +@deftypefun {HIST_ENTRY *} current_history (void) +Return the history entry at the current position, as determined by +@code{where_history()}. If there is no entry there, return a @code{NULL} +pointer. +@end deftypefun + +@deftypefun {HIST_ENTRY *} history_get (int offset) +Return the history entry at position @var{offset}. +The range of valid +values of @var{offset} starts at @code{history_base} and ends at +@var{history_length} - 1 (@pxref{History Variables}). +If there is no entry there, or if @var{offset} is outside the valid +range, return a @code{NULL} pointer. +@end deftypefun + +@deftypefun time_t history_get_time (HIST_ENTRY *entry) +Return the time stamp associated with the history entry @var{entry}. +If the timestamp is missing or invalid, return 0. +@end deftypefun + +@deftypefun int history_total_bytes (void) +Return the number of bytes that the primary history entries are using. +This function returns the sum of the lengths of all the lines in the +history. +@end deftypefun + +@node Moving Around the History List +@subsection Moving Around the History List + +These functions allow the current index into the history list to be +set or changed. + +@deftypefun int history_set_pos (int pos) +Set the current history offset to @var{pos}, an absolute index +into the list. +Returns 1 on success, 0 if @var{pos} is less than zero or greater +than the number of history entries. +@end deftypefun + +@deftypefun {HIST_ENTRY *} previous_history (void) +Back up the current history offset to the previous history entry, and +return a pointer to that entry. If there is no previous entry, return +a @code{NULL} pointer. +@end deftypefun + +@deftypefun {HIST_ENTRY *} next_history (void) +If the current history offset refers to a valid history entry, +increment the current history offset. +If the possibly-incremented history offset refers to a valid history +entry, return a pointer to that entry; +otherwise, return a @code{BNULL} pointer. +@end deftypefun + +@node Searching the History List +@subsection Searching the History List +@cindex History Searching + +These functions allow searching of the history list for entries containing +a specific string. Searching may be performed both forward and backward +from the current history position. The search may be @dfn{anchored}, +meaning that the string must match at the beginning of the history entry. +@cindex anchored search + +@deftypefun int history_search (const char *string, int direction) +Search the history for @var{string}, starting at the current history offset. +If @var{direction} is less than 0, then the search is through +previous entries, otherwise through subsequent entries. +If @var{string} is found, then +the current history index is set to that history entry, and the value +returned is the offset in the line of the entry where +@var{string} was found. Otherwise, nothing is changed, and a -1 is +returned. +@end deftypefun + +@deftypefun int history_search_prefix (const char *string, int direction) +Search the history for @var{string}, starting at the current history +offset. The search is anchored: matching lines must begin with +@var{string}. If @var{direction} is less than 0, then the search is +through previous entries, otherwise through subsequent entries. +If @var{string} is found, then the +current history index is set to that entry, and the return value is 0. +Otherwise, nothing is changed, and a -1 is returned. +@end deftypefun + +@deftypefun int history_search_pos (const char *string, int direction, int pos) +Search for @var{string} in the history list, starting at @var{pos}, an +absolute index into the list. If @var{direction} is negative, the search +proceeds backward from @var{pos}, otherwise forward. Returns the absolute +index of the history element where @var{string} was found, or -1 otherwise. +@end deftypefun + +@node Managing the History File +@subsection Managing the History File + +The History library can read the history from and write it to a file. +This section documents the functions for managing a history file. + +@deftypefun int read_history (const char *filename) +Add the contents of @var{filename} to the history list, a line at a time. +If @var{filename} is @code{NULL}, then read from @file{~/.history}. +Returns 0 if successful, or @code{errno} if not. +@end deftypefun + +@deftypefun int read_history_range (const char *filename, int from, int to) +Read a range of lines from @var{filename}, adding them to the history list. +Start reading at line @var{from} and end at @var{to}. +If @var{from} is zero, start at the beginning. If @var{to} is less than +@var{from}, then read until the end of the file. If @var{filename} is +@code{NULL}, then read from @file{~/.history}. Returns 0 if successful, +or @code{errno} if not. +@end deftypefun + +@deftypefun int write_history (const char *filename) +Write the current history to @var{filename}, overwriting @var{filename} +if necessary. +If @var{filename} is @code{NULL}, then write the history list to +@file{~/.history}. +Returns 0 on success, or @code{errno} on a read or write error. +@end deftypefun + +@deftypefun int append_history (int nelements, const char *filename) +Append the last @var{nelements} of the history list to @var{filename}. +If @var{filename} is @code{NULL}, then append to @file{~/.history}. +Returns 0 on success, or @code{errno} on a read or write error. +@end deftypefun + +@deftypefun int history_truncate_file (const char *filename, int nlines) +Truncate the history file @var{filename}, leaving only the last +@var{nlines} lines. +If @var{filename} is @code{NULL}, then @file{~/.history} is truncated. +Returns 0 on success, or @code{errno} on failure. +@end deftypefun + +@node History Expansion +@subsection History Expansion + +These functions implement history expansion. + +@deftypefun int history_expand (char *string, char **output) +Expand @var{string}, placing the result into @var{output}, a pointer +to a string (@pxref{History Interaction}). Returns: +@table @code +@item 0 +If no expansions took place (or, if the only change in +the text was the removal of escape characters preceding the history expansion +character); +@item 1 +if expansions did take place; +@item -1 +if there was an error in expansion; +@item 2 +if the returned line should be displayed, but not executed, +as with the @code{:p} modifier (@pxref{Modifiers}). +@end table + +If an error occurred in expansion, then @var{output} contains a descriptive +error message. +@end deftypefun + +@deftypefun {char *} get_history_event (const char *string, int *cindex, int qchar) +Returns the text of the history event beginning at @var{string} + +@var{*cindex}. @var{*cindex} is modified to point to after the event +specifier. At function entry, @var{cindex} points to the index into +@var{string} where the history event specification begins. @var{qchar} +is a character that is allowed to end the event specification in addition +to the ``normal'' terminating characters. +@end deftypefun + +@deftypefun {char **} history_tokenize (const char *string) +Return an array of tokens parsed out of @var{string}, much as the +shell might. The tokens are split on the characters in the +@var{history_word_delimiters} variable, +and shell quoting conventions are obeyed as described below. +@end deftypefun + +@deftypefun {char *} history_arg_extract (int first, int last, const char *string) +Extract a string segment consisting of the @var{first} through @var{last} +arguments present in @var{string}. Arguments are split using +@code{history_tokenize}. +@end deftypefun + +@node History Variables +@section History Variables + +This section describes the externally-visible variables exported by +the @sc{gnu} History Library. + +@deftypevar int history_base +The logical offset of the first entry in the history list. +@end deftypevar + +@deftypevar int history_length +The number of entries currently stored in the history list. +@end deftypevar + +@deftypevar int history_max_entries +The maximum number of history entries. This must be changed using +@code{stifle_history()}. +@end deftypevar + +@deftypevar int history_write_timestamps +If non-zero, timestamps are written to the history file, so they can be +preserved between sessions. The default value is 0, meaning that +timestamps are not saved. + +The current timestamp format uses the value of @var{history_comment_char} +to delimit timestamp entries in the history file. If that variable does +not have a value (the default), timestamps will not be written. +@end deftypevar + +@deftypevar char history_expansion_char +The character that introduces a history event. The default is @samp{!}. +Setting this to 0 inhibits history expansion. +@end deftypevar + +@deftypevar char history_subst_char +The character that invokes word substitution if found at the start of +a line. The default is @samp{^}. +@end deftypevar + +@deftypevar char history_comment_char +During tokenization, if this character is seen as the first character +of a word, then it and all subsequent characters up to a newline are +ignored, suppressing history expansion for the remainder of the line. +This is disabled by default. +@end deftypevar + +@deftypevar {char *} history_word_delimiters +The characters that separate tokens for @code{history_tokenize()}. +The default value is @code{" \t\n()<>;&|"}. +@end deftypevar + +@deftypevar {char *} history_search_delimiter_chars +The list of additional characters which can delimit a history search +string, in addition to space, TAB, @samp{:} and @samp{?} in the case of +a substring search. The default is empty. +@end deftypevar + +@deftypevar {char *} history_no_expand_chars +The list of characters which inhibit history expansion if found immediately +following @var{history_expansion_char}. The default is space, tab, newline, +carriage return, and @samp{=}. +@end deftypevar + +@deftypevar int history_quotes_inhibit_expansion +If non-zero, the history expansion code implements shell-like quoting: +single-quoted words are not scanned for the history expansion +character or the history comment character, and double-quoted words may +have history expansion performed, since single quotes are not special +within double quotes. +The default value is 0. +@end deftypevar + +@deftypevar int history_quoting_state +An application may set this variable to indicate that the current line +being expanded is subject to existing quoting. If set to @samp{'}, the +history expansion function will assume that the line is single-quoted and +inhibit expansion until it reads an unquoted closing single quote; if set +to @samp{"}, history expansion will assume the line is double quoted until +it reads an unquoted closing double quote. If set to zero, the default, +the history expansion function will assume the line is not quoted and +treat quote characters within the line as described above. +This is only effective if @var{history_quotes_inhibit_expansion} is set. +@end deftypevar + +@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function +This should be set to the address of a function that takes two arguments: +a @code{char *} (@var{string}) +and an @code{int} index into that string (@var{i}). +It should return a non-zero value if the history expansion starting at +@var{string[i]} should not be performed; zero if the expansion should +be done. +It is intended for use by applications like Bash that use the history +expansion character for additional purposes. +By default, this variable is set to @code{NULL}. +@end deftypevar + +@node History Programming Example +@section History Programming Example + +The following program demonstrates simple use of the @sc{gnu} History Library. + +@smallexample +#include +#include + +main (argc, argv) + int argc; + char **argv; +@{ + char line[1024], *t; + int len, done = 0; + + line[0] = 0; + + using_history (); + while (!done) + @{ + printf ("history$ "); + fflush (stdout); + t = fgets (line, sizeof (line) - 1, stdin); + if (t && *t) + @{ + len = strlen (t); + if (t[len - 1] == '\n') + t[len - 1] = '\0'; + @} + + if (!t) + strcpy (line, "quit"); + + if (line[0]) + @{ + char *expansion; + int result; + + result = history_expand (line, &expansion); + if (result) + fprintf (stderr, "%s\n", expansion); + + if (result < 0 || result == 2) + @{ + free (expansion); + continue; + @} + + add_history (expansion); + strncpy (line, expansion, sizeof (line) - 1); + free (expansion); + @} + + if (strcmp (line, "quit") == 0) + done = 1; + else if (strcmp (line, "save") == 0) + write_history ("history_file"); + else if (strcmp (line, "read") == 0) + read_history ("history_file"); + else if (strcmp (line, "list") == 0) + @{ + register HIST_ENTRY **the_list; + register int i; + + the_list = history_list (); + if (the_list) + for (i = 0; the_list[i]; i++) + printf ("%d: %s\n", i + history_base, the_list[i]->line); + @} + else if (strncmp (line, "delete", 6) == 0) + @{ + int which; + if ((sscanf (line + 6, "%d", &which)) == 1) + @{ + HIST_ENTRY *entry = remove_history (which); + if (!entry) + fprintf (stderr, "No such entry %d\n", which); + else + @{ + free (entry->line); + free (entry); + @} + @} + else + @{ + fprintf (stderr, "non-numeric arg given to `delete'\n"); + @} + @} + @} +@} +@end smallexample diff --git a/utshell-0.5.0/lib/readline/doc/hsuser.texi b/utshell-0.5.0/lib/readline/doc/hsuser.texi new file mode 100644 index 00000000..76706fd2 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/hsuser.texi @@ -0,0 +1,527 @@ +@ignore +This file documents the user interface to the GNU History library. + +Copyright (C) 1988--2020 Free Software Foundation, Inc. +Authored by Brian Fox and Chet Ramey. + +Permission is granted to make and distribute verbatim copies of this manual +provided the copyright notice and this permission notice are preserved on +all copies. + +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission notice +identical to this one except for the removal of this paragraph (this +paragraph not being relevant to the printed manual). + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +GNU Copyright statement is available to the distributee, and provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end ignore + +@node Using History Interactively +@chapter Using History Interactively + +@ifclear BashFeatures +@defcodeindex bt +@end ifclear + +@ifset BashFeatures +This chapter describes how to use the @sc{gnu} History Library +interactively, from a user's standpoint. +It should be considered a user's guide. +For information on using the @sc{gnu} History Library in other programs, +see the @sc{gnu} Readline Library Manual. +@end ifset +@ifclear BashFeatures +This chapter describes how to use the @sc{gnu} History Library interactively, +from a user's standpoint. It should be considered a user's guide. For +information on using the @sc{gnu} History Library in your own programs, +@pxref{Programming with GNU History}. +@end ifclear + +@ifset BashFeatures +@menu +* Bash History Facilities:: How Bash lets you manipulate your command + history. +* Bash History Builtins:: The Bash builtin commands that manipulate + the command history. +* History Interaction:: What it feels like using History as a user. +@end menu +@end ifset +@ifclear BashFeatures +@menu +* History Interaction:: What it feels like using History as a user. +@end menu +@end ifclear + +@ifset BashFeatures +@node Bash History Facilities +@section Bash History Facilities +@cindex command history +@cindex history list + +When the @option{-o history} option to the @code{set} builtin +is enabled (@pxref{The Set Builtin}), +the shell provides access to the @dfn{command history}, +the list of commands previously typed. +The value of the @env{HISTSIZE} shell variable is used as the +number of commands to save in a history list. +The text of the last @env{$HISTSIZE} +commands (default 500) is saved. +The shell stores each command in the history list prior to +parameter and variable expansion +but after history expansion is performed, subject to the +values of the shell variables +@env{HISTIGNORE} and @env{HISTCONTROL}. + +When the shell starts up, the history is initialized from the +file named by the @env{HISTFILE} variable (default @file{~/.utshell_history}). +The file named by the value of @env{HISTFILE} is truncated, if +necessary, to contain no more than the number of lines specified by +the value of the @env{HISTFILESIZE} variable. +When a shell with history enabled exits, the last +@env{$HISTSIZE} lines are copied from the history list to the file +named by @env{$HISTFILE}. +If the @code{histappend} shell option is set (@pxref{Bash Builtins}), +the lines are appended to the history file, +otherwise the history file is overwritten. +If @env{HISTFILE} +is unset, or if the history file is unwritable, the history is not saved. +After saving the history, the history file is truncated +to contain no more than @env{$HISTFILESIZE} lines. +If @env{HISTFILESIZE} is unset, or set to null, a non-numeric value, or +a numeric value less than zero, the history file is not truncated. + +If the @env{HISTTIMEFORMAT} is set, the time stamp information +associated with each history entry is written to the history file, +marked with the history comment character. +When the history file is read, lines beginning with the history +comment character followed immediately by a digit are interpreted +as timestamps for the following history entry. + +The builtin command @code{fc} may be used to list or edit and re-execute +a portion of the history list. +The @code{history} builtin may be used to display or modify the history +list and manipulate the history file. +When using command-line editing, search commands +are available in each editing mode that provide access to the +history list (@pxref{Commands For History}). + +The shell allows control over which commands are saved on the history +list. The @env{HISTCONTROL} and @env{HISTIGNORE} +variables may be set to cause the shell to save only a subset of the +commands entered. +The @code{cmdhist} +shell option, if enabled, causes the shell to attempt to save each +line of a multi-line command in the same history entry, adding +semicolons where necessary to preserve syntactic correctness. +The @code{lithist} +shell option causes the shell to save the command with embedded newlines +instead of semicolons. +The @code{shopt} builtin is used to set these options. +@xref{The Shopt Builtin}, for a description of @code{shopt}. + +@node Bash History Builtins +@section Bash History Builtins +@cindex history builtins + +Bash provides two builtin commands which manipulate the +history list and history file. + +@table @code + +@item fc +@btindex fc +@example +@code{fc [-e @var{ename}] [-lnr] [@var{first}] [@var{last}]} +@code{fc -s [@var{pat}=@var{rep}] [@var{command}]} +@end example + +The first form selects a range of commands from @var{first} to +@var{last} from the history list and displays or edits and re-executes +them. +Both @var{first} and +@var{last} may be specified as a string (to locate the most recent +command beginning with that string) or as a number (an index into the +history list, where a negative number is used as an offset from the +current command number). + +When listing, a @var{first} or @var{last} of 0 is equivalent to -1 +and -0 is equivalent to the current command (usually the @code{fc} +command); +otherwise 0 is equivalent to -1 and -0 is invalid. + +If @var{last} is not specified, it is set to +@var{first}. If @var{first} is not specified, it is set to the previous +command for editing and @minus{}16 for listing. If the @option{-l} flag is +given, the commands are listed on standard output. The @option{-n} flag +suppresses the command numbers when listing. The @option{-r} flag +reverses the order of the listing. Otherwise, the editor given by +@var{ename} is invoked on a file containing those commands. If +@var{ename} is not given, the value of the following variable expansion +is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the +value of the @env{FCEDIT} variable if set, or the value of the +@env{EDITOR} variable if that is set, or @code{vi} if neither is set. +When editing is complete, the edited commands are echoed and executed. + +In the second form, @var{command} is re-executed after each instance +of @var{pat} in the selected command is replaced by @var{rep}. +@var{command} is interpreted the same as @var{first} above. + +A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so +that typing @samp{r cc} runs the last command beginning with @code{cc} +and typing @samp{r} re-executes the last command (@pxref{Aliases}). + +@item history +@btindex history +@example +history [@var{n}] +history -c +history -d @var{offset} +history -d @var{start}-@var{end} +history [-anrw] [@var{filename}] +history -ps @var{arg} +@end example + +With no options, display the history list with line numbers. +Lines prefixed with a @samp{*} have been modified. +An argument of @var{n} lists only the last @var{n} lines. +If the shell variable @env{HISTTIMEFORMAT} is set and not null, +it is used as a format string for @var{strftime} to display +the time stamp associated with each displayed history entry. +No intervening blank is printed between the formatted time stamp +and the history line. + +Options, if supplied, have the following meanings: + +@table @code +@item -c +Clear the history list. This may be combined +with the other options to replace the history list completely. + +@item -d @var{offset} +Delete the history entry at position @var{offset}. +If @var{offset} is positive, it should be specified as it appears when +the history is displayed. +If @var{offset} is negative, it is interpreted as relative to one greater +than the last history position, so negative indices count back from the +end of the history, and an index of @samp{-1} refers to the current +@code{history -d} command. + +@item -d @var{start}-@var{end} +Delete the history entries between positions @var{start} and @var{end}, +inclusive. Positive and negative values for @var{start} and @var{end} +are interpreted as described above. + +@item -a +Append the new history lines to the history file. +These are history lines entered since the beginning of the current +Bash session, but not already appended to the history file. + +@item -n +Append the history lines not already read from the history file +to the current history list. These are lines appended to the history +file since the beginning of the current Bash session. + +@item -r +Read the history file and append its contents to +the history list. + +@item -w +Write out the current history list to the history file. + +@item -p +Perform history substitution on the @var{arg}s and display the result +on the standard output, without storing the results in the history list. + +@item -s +The @var{arg}s are added to the end of +the history list as a single entry. + +@end table + +When any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options is +used, if @var{filename} +is given, then it is used as the history file. If not, then +the value of the @env{HISTFILE} variable is used. + +@end table +@end ifset + +@node History Interaction +@section History Expansion +@cindex history expansion + +The History library provides a history expansion feature that is similar +to the history expansion provided by @code{csh}. This section +describes the syntax used to manipulate the history information. + +History expansions introduce words from the history list into +the input stream, making it easy to repeat commands, insert the +arguments to a previous command into the current input line, or +fix errors in previous commands quickly. + +@ifset BashFeatures +History expansion is performed immediately after a complete line +is read, before the shell breaks it into words, and is performed +on each line individually. Bash attempts to inform the history +expansion functions about quoting still in effect from previous lines. +@end ifset + +History expansion takes place in two parts. The first is to determine +which line from the history list should be used during substitution. +The second is to select portions of that line for inclusion into the +current one. The line selected from the history is called the +@dfn{event}, and the portions of that line that are acted upon are +called @dfn{words}. Various @dfn{modifiers} are available to manipulate +the selected words. The line is broken into words in the same fashion +that Bash does, so that several words +surrounded by quotes are considered one word. +History expansions are introduced by the appearance of the +history expansion character, which is @samp{!} by default. + +History expansion implements shell-like quoting conventions: +a backslash can be used to remove the special handling for the next character; +single quotes enclose verbatim sequences of characters, and can be used to +inhibit history expansion; +and characters enclosed within double quotes may be subject to history +expansion, since backslash can escape the history expansion character, +but single quotes may not, since they are not treated specially within +double quotes. + +@ifset BashFeatures +When using the shell, only @samp{\} and @samp{'} may be used to escape the +history expansion character, but the history expansion character is +also treated as quoted if it immediately precedes the closing double quote +in a double-quoted string. +@end ifset + +@ifset BashFeatures +Several shell options settable with the @code{shopt} +builtin (@pxref{The Shopt Builtin}) may be used to tailor +the behavior of history expansion. If the +@code{histverify} shell option is enabled, and Readline +is being used, history substitutions are not immediately passed to +the shell parser. +Instead, the expanded line is reloaded into the Readline +editing buffer for further modification. +If Readline is being used, and the @code{histreedit} +shell option is enabled, a failed history expansion will be +reloaded into the Readline editing buffer for correction. +The @option{-p} option to the @code{history} builtin command +may be used to see what a history expansion will do before using it. +The @option{-s} option to the @code{history} builtin may be used to +add commands to the end of the history list without actually executing +them, so that they are available for subsequent recall. +This is most useful in conjunction with Readline. + +The shell allows control of the various characters used by the +history expansion mechanism with the @code{histchars} variable, +as explained above (@pxref{Bash Variables}). The shell uses +the history comment character to mark history timestamps when +writing the history file. +@end ifset + +@menu +* Event Designators:: How to specify which history line to use. +* Word Designators:: Specifying which words are of interest. +* Modifiers:: Modifying the results of substitution. +@end menu + +@node Event Designators +@subsection Event Designators +@cindex event designators + +An event designator is a reference to a command line entry in the +history list. +Unless the reference is absolute, events are relative to the current +position in the history list. +@cindex history events + +@table @asis + +@item @code{!} +@ifset BashFeatures +Start a history substitution, except when followed by a space, tab, +the end of the line, @samp{=} or @samp{(} (when the +@code{extglob} shell option is enabled using the @code{shopt} builtin). +@end ifset +@ifclear BashFeatures +Start a history substitution, except when followed by a space, tab, +the end of the line, or @samp{=}. +@end ifclear + +@item @code{!@var{n}} +Refer to command line @var{n}. + +@item @code{!-@var{n}} +Refer to the command @var{n} lines back. + +@item @code{!!} +Refer to the previous command. This is a synonym for @samp{!-1}. + +@item @code{!@var{string}} +Refer to the most recent command +preceding the current position in the history list +starting with @var{string}. + +@item @code{!?@var{string}[?]} +Refer to the most recent command +preceding the current position in the history list +containing @var{string}. +The trailing +@samp{?} may be omitted if the @var{string} is followed immediately by +a newline. +If @var{string} is missing, the string from the most recent search is used; +it is an error if there is no previous search string. + +@item @code{^@var{string1}^@var{string2}^} +Quick Substitution. Repeat the last command, replacing @var{string1} +with @var{string2}. Equivalent to +@code{!!:s^@var{string1}^@var{string2}^}. + +@item @code{!#} +The entire command line typed so far. + +@end table + +@node Word Designators +@subsection Word Designators + +Word designators are used to select desired words from the event. +A @samp{:} separates the event specification from the word designator. It +may be omitted if the word designator begins with a @samp{^}, @samp{$}, +@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning +of the line, with the first word being denoted by 0 (zero). Words are +inserted into the current line separated by single spaces. + +@need 0.75 +For example, + +@table @code +@item !! +designates the preceding command. When you type this, the preceding +command is repeated in toto. + +@item !!:$ +designates the last argument of the preceding command. This may be +shortened to @code{!$}. + +@item !fi:2 +designates the second argument of the most recent command starting with +the letters @code{fi}. +@end table + +@need 0.75 +Here are the word designators: + +@table @code + +@item 0 (zero) +The @code{0}th word. For many applications, this is the command word. + +@item @var{n} +The @var{n}th word. + +@item ^ +The first argument; that is, word 1. + +@item $ +The last argument. + +@item % +The first word matched by the most recent @samp{?@var{string}?} search, +if the search string begins with a character that is part of a word. + +@item @var{x}-@var{y} +A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}. + +@item * +All of the words, except the @code{0}th. This is a synonym for @samp{1-$}. +It is not an error to use @samp{*} if there is just one word in the event; +the empty string is returned in that case. + +@item @var{x}* +Abbreviates @samp{@var{x}-$} + +@item @var{x}- +Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word. +If @samp{x} is missing, it defaults to 0. + +@end table + +If a word designator is supplied without an event specification, the +previous command is used as the event. + +@node Modifiers +@subsection Modifiers + +After the optional word designator, you can add a sequence of one or more +of the following modifiers, each preceded by a @samp{:}. +These modify, or edit, the word or words selected from the history event. + +@table @code + +@item h +Remove a trailing pathname component, leaving only the head. + +@item t +Remove all leading pathname components, leaving the tail. + +@item r +Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving +the basename. + +@item e +Remove all but the trailing suffix. + +@item p +Print the new command but do not execute it. + +@ifset BashFeatures +@item q +Quote the substituted words, escaping further substitutions. + +@item x +Quote the substituted words as with @samp{q}, +but break into words at spaces, tabs, and newlines. +The @samp{q} and @samp{x} modifiers are mutually exclusive; the last one +supplied is used. +@end ifset + +@item s/@var{old}/@var{new}/ +Substitute @var{new} for the first occurrence of @var{old} in the +event line. +Any character may be used as the delimiter in place of @samp{/}. +The delimiter may be quoted in @var{old} and @var{new} +with a single backslash. If @samp{&} appears in @var{new}, +it is replaced by @var{old}. A single backslash will quote +the @samp{&}. +If @var{old} is null, it is set to the last @var{old} +substituted, or, if no previous history substitutions took place, +the last @var{string} +in a !?@var{string}@code{[?]} +search. +If @var{new} is is null, each matching @var{old} is deleted. +The final delimiter is optional if it is the last +character on the input line. + +@item & +Repeat the previous substitution. + +@item g +@itemx a +Cause changes to be applied over the entire event line. Used in +conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/}, +or with @samp{&}. + +@item G +Apply the following @samp{s} or @samp{&} modifier once to each word +in the event. + +@end table diff --git a/utshell-0.5.0/lib/readline/doc/rlman.texi b/utshell-0.5.0/lib/readline/doc/rlman.texi new file mode 100644 index 00000000..ec7487b7 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/rlman.texi @@ -0,0 +1,84 @@ +\input texinfo @c -*-texinfo-*- +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename readline.info +@settitle GNU Readline Library +@include version.texi + +@comment %**end of header (This is for running Texinfo on a region.) +@synindex vr fn + +@copying +This manual describes the GNU Readline Library +(version @value{VERSION}, @value{UPDATED}), a library which aids in the +consistency of user interface across discrete programs which provide +a command line interface. + +Copyright @copyright{} 1988--2020 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the section entitled +``GNU Free Documentation License''. + +@end quotation +@end copying + +@dircategory Libraries +@direntry +* Readline: (readline). The GNU readline library API. +@end direntry + +@titlepage +@title GNU Readline Library +@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}. +@subtitle @value{UPDATED-MONTH} +@author Chet Ramey, Case Western Reserve University +@author Brian Fox, Free Software Foundation + +@page +@vskip 0pt plus 1filll +@insertcopying + +@end titlepage + +@contents + +@ifnottex +@node Top +@top GNU Readline Library + +This document describes the GNU Readline Library, a utility which aids +in the consistency of user interface across discrete programs which +provide a command line interface. +The Readline home page is @url{http://www.gnu.org/software/readline/}. + +@menu +* Command Line Editing:: GNU Readline User's Manual. +* Programming with GNU Readline:: GNU Readline Programmer's Manual. +* GNU Free Documentation License:: License for copying this manual. +* Concept Index:: Index of concepts described in this manual. +* Function and Variable Index:: Index of externally visible functions + and variables. +@end menu +@end ifnottex + +@include rluser.texi +@include rltech.texi + +@node GNU Free Documentation License +@appendix GNU Free Documentation License + +@include fdl.texi + +@node Concept Index +@unnumbered Concept Index +@printindex cp + +@node Function and Variable Index +@unnumbered Function and Variable Index +@printindex fn + +@bye diff --git a/utshell-0.5.0/lib/readline/doc/rltech.texi b/utshell-0.5.0/lib/readline/doc/rltech.texi new file mode 100644 index 00000000..bbf57c23 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/rltech.texi @@ -0,0 +1,2757 @@ +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename rltech.info +@comment %**end of header (This is for running Texinfo on a region.) + +@ifinfo +This document describes the GNU Readline Library, a utility for aiding +in the consistency of user interface across discrete programs that need +to provide a command line interface. + +Copyright (C) 1988--2020 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +pare preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). +@end ignore + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the Foundation. +@end ifinfo + +@node Programming with GNU Readline +@chapter Programming with GNU Readline + +This chapter describes the interface between the @sc{gnu} Readline Library and +other programs. If you are a programmer, and you wish to include the +features found in @sc{gnu} Readline +such as completion, line editing, and interactive history manipulation +in your own programs, this section is for you. + +@menu +* Basic Behavior:: Using the default behavior of Readline. +* Custom Functions:: Adding your own functions to Readline. +* Readline Variables:: Variables accessible to custom + functions. +* Readline Convenience Functions:: Functions which Readline supplies to + aid in writing your own custom + functions. +* Readline Signal Handling:: How Readline behaves when it receives signals. +* Custom Completers:: Supplanting or supplementing Readline's + completion functions. +@end menu + +@node Basic Behavior +@section Basic Behavior + +Many programs provide a command line interface, such as @code{mail}, +@code{ftp}, and @code{sh}. For such programs, the default behaviour of +Readline is sufficient. This section describes how to use Readline in +the simplest way possible, perhaps to replace calls in your code to +@code{gets()} or @code{fgets()}. + +@findex readline +@cindex readline, function + +The function @code{readline()} prints a prompt @var{prompt} +and then reads and returns a single line of text from the user. +If @var{prompt} is @code{NULL} or the empty string, no prompt is displayed. +The line @code{readline} returns is allocated with @code{malloc()}; +the caller should @code{free()} the line when it has finished with it. +The declaration for @code{readline} in ANSI C is + +@example +@code{char *readline (const char *@var{prompt});} +@end example + +@noindent +So, one might say +@example +@code{char *line = readline ("Enter a line: ");} +@end example +@noindent +in order to read a line of text from the user. +The line returned has the final newline removed, so only the +text remains. + +If @code{readline} encounters an @code{EOF} while reading the line, and the +line is empty at that point, then @code{(char *)NULL} is returned. +Otherwise, the line is ended just as if a newline had been typed. + +Readline performs some expansion on the @var{prompt} before it is +displayed on the screen. See the description of @code{rl_expand_prompt} +(@pxref{Redisplay}) for additional details, especially if @var{prompt} +will contain characters that do not consume physical screen space when +displayed. + +If you want the user to be able to get at the line later, (with +@key{C-p} for example), you must call @code{add_history()} to save the +line away in a @dfn{history} list of such lines. + +@example +@code{add_history (line)}; +@end example + +@noindent +For full details on the GNU History Library, see the associated manual. + +It is preferable to avoid saving empty lines on the history list, since +users rarely have a burning need to reuse a blank line. Here is +a function which usefully replaces the standard @code{gets()} library +function, and has the advantage of no static buffer to overflow: + +@example +/* A static variable for holding the line. */ +static char *line_read = (char *)NULL; + +/* Read a string, and return a pointer to it. + Returns NULL on EOF. */ +char * +rl_gets () +@{ + /* If the buffer has already been allocated, + return the memory to the free pool. */ + if (line_read) + @{ + free (line_read); + line_read = (char *)NULL; + @} + + /* Get a line from the user. */ + line_read = readline (""); + + /* If the line has any text in it, + save it on the history. */ + if (line_read && *line_read) + add_history (line_read); + + return (line_read); +@} +@end example + +This function gives the user the default behaviour of @key{TAB} +completion: completion on file names. If you do not want Readline to +complete on filenames, you can change the binding of the @key{TAB} key +with @code{rl_bind_key()}. + +@example +@code{int rl_bind_key (int @var{key}, rl_command_func_t *@var{function});} +@end example + +@code{rl_bind_key()} takes two arguments: @var{key} is the character that +you want to bind, and @var{function} is the address of the function to +call when @var{key} is pressed. Binding @key{TAB} to @code{rl_insert()} +makes @key{TAB} insert itself. +@code{rl_bind_key()} returns non-zero if @var{key} is not a valid +ASCII character code (between 0 and 255). + +Thus, to disable the default @key{TAB} behavior, the following suffices: +@example +@code{rl_bind_key ('\t', rl_insert);} +@end example + +This code should be executed once at the start of your program; you +might write a function called @code{initialize_readline()} which +performs this and other desired initializations, such as installing +custom completers (@pxref{Custom Completers}). + +@node Custom Functions +@section Custom Functions + +Readline provides many functions for manipulating the text of +the line, but it isn't possible to anticipate the needs of all +programs. This section describes the various functions and variables +defined within the Readline library which allow a user program to add +customized functionality to Readline. + +Before declaring any functions that customize Readline's behavior, or +using any functionality Readline provides in other code, an +application writer should include the file @code{} +in any file that uses Readline's features. Since some of the definitions +in @code{readline.h} use the @code{stdio} library, the file +@code{} should be included before @code{readline.h}. + +@code{readline.h} defines a C preprocessor variable that should +be treated as an integer, @code{RL_READLINE_VERSION}, which may +be used to conditionally compile application code depending on +the installed Readline version. The value is a hexadecimal +encoding of the major and minor version numbers of the library, +of the form 0x@var{MMmm}. @var{MM} is the two-digit major +version number; @var{mm} is the two-digit minor version number. +For Readline 4.2, for example, the value of +@code{RL_READLINE_VERSION} would be @code{0x0402}. + +@menu +* Readline Typedefs:: C declarations to make code readable. +* Function Writing:: Variables and calling conventions. +@end menu + +@node Readline Typedefs +@subsection Readline Typedefs + +For readability, we declare a number of new object types, all pointers +to functions. + +The reason for declaring these new types is to make it easier to write +code describing pointers to C functions with appropriately prototyped +arguments and return values. + +For instance, say we want to declare a variable @var{func} as a pointer +to a function which takes two @code{int} arguments and returns an +@code{int} (this is the type of all of the Readline bindable functions). +Instead of the classic C declaration + +@code{int (*func)();} + +@noindent +or the ANSI-C style declaration + +@code{int (*func)(int, int);} + +@noindent +we may write + +@code{rl_command_func_t *func;} + +The full list of function pointer types available is + +@table @code +@item typedef int rl_command_func_t (int, int); + +@item typedef char *rl_compentry_func_t (const char *, int); + +@item typedef char **rl_completion_func_t (const char *, int, int); + +@item typedef char *rl_quote_func_t (char *, int, char *); + +@item typedef char *rl_dequote_func_t (char *, int); + +@item typedef int rl_compignore_func_t (char **); + +@item typedef void rl_compdisp_func_t (char **, int, int); + +@item typedef int rl_hook_func_t (void); + +@item typedef int rl_getc_func_t (FILE *); + +@item typedef int rl_linebuf_func_t (char *, int); + +@item typedef int rl_intfunc_t (int); +@item #define rl_ivoidfunc_t rl_hook_func_t +@item typedef int rl_icpfunc_t (char *); +@item typedef int rl_icppfunc_t (char **); + +@item typedef void rl_voidfunc_t (void); +@item typedef void rl_vintfunc_t (int); +@item typedef void rl_vcpfunc_t (char *); +@item typedef void rl_vcppfunc_t (char **); + +@end table + +@node Function Writing +@subsection Writing a New Function + +In order to write new functions for Readline, you need to know the +calling conventions for keyboard-invoked functions, and the names of the +variables that describe the current state of the line read so far. + +The calling sequence for a command @code{foo} looks like + +@example +@code{int foo (int count, int key)} +@end example + +@noindent +where @var{count} is the numeric argument (or 1 if defaulted) and +@var{key} is the key that invoked this function. + +It is completely up to the function as to what should be done with the +numeric argument. Some functions use it as a repeat count, some +as a flag, and others to choose alternate behavior (refreshing the current +line as opposed to refreshing the screen, for example). Some choose to +ignore it. In general, if a +function uses the numeric argument as a repeat count, it should be able +to do something useful with both negative and positive arguments. +At the very least, it should be aware that it can be passed a +negative argument. + +A command function should return 0 if its action completes successfully, +and a value greater than zero if some error occurs. +This is the convention obeyed by all of the builtin Readline bindable +command functions. + +@node Readline Variables +@section Readline Variables + +These variables are available to function writers. + +@deftypevar {char *} rl_line_buffer +This is the line gathered so far. You are welcome to modify the +contents of the line, but see @ref{Allowing Undoing}. The +function @code{rl_extend_line_buffer} is available to increase +the memory allocated to @code{rl_line_buffer}. +@end deftypevar + +@deftypevar int rl_point +The offset of the current cursor position in @code{rl_line_buffer} +(the @emph{point}). +@end deftypevar + +@deftypevar int rl_end +The number of characters present in @code{rl_line_buffer}. When +@code{rl_point} is at the end of the line, @code{rl_point} and +@code{rl_end} are equal. +@end deftypevar + +@deftypevar int rl_mark +The @var{mark} (saved position) in the current line. If set, the mark +and point define a @emph{region}. +@end deftypevar + +@deftypevar int rl_done +Setting this to a non-zero value causes Readline to return the current +line immediately. +@end deftypevar + +@deftypevar int rl_num_chars_to_read +Setting this to a positive value before calling @code{readline()} causes +Readline to return after accepting that many characters, rather +than reading up to a character bound to @code{accept-line}. +@end deftypevar + +@deftypevar int rl_pending_input +Setting this to a value makes it the next keystroke read. This is a +way to stuff a single character into the input stream. +@end deftypevar + +@deftypevar int rl_dispatching +Set to a non-zero value if a function is being called from a key binding; +zero otherwise. Application functions can test this to discover whether +they were called directly or by Readline's dispatching mechanism. +@end deftypevar + +@deftypevar int rl_erase_empty_line +Setting this to a non-zero value causes Readline to completely erase +the current line, including any prompt, any time a newline is typed as +the only character on an otherwise-empty line. The cursor is moved to +the beginning of the newly-blank line. +@end deftypevar + +@deftypevar {char *} rl_prompt +The prompt Readline uses. This is set from the argument to +@code{readline()}, and should not be assigned to directly. +The @code{rl_set_prompt()} function (@pxref{Redisplay}) may +be used to modify the prompt string after calling @code{readline()}. +@end deftypevar + +@deftypevar {char *} rl_display_prompt +The string displayed as the prompt. This is usually identical to +@var{rl_prompt}, but may be changed temporarily by functions that +use the prompt string as a message area, such as incremental search. +@end deftypevar + +@deftypevar int rl_already_prompted +If an application wishes to display the prompt itself, rather than have +Readline do it the first time @code{readline()} is called, it should set +this variable to a non-zero value after displaying the prompt. +The prompt must also be passed as the argument to @code{readline()} so +the redisplay functions can update the display properly. +The calling application is responsible for managing the value; Readline +never sets it. +@end deftypevar + +@deftypevar {const char *} rl_library_version +The version number of this revision of the library. +@end deftypevar + +@deftypevar int rl_readline_version +An integer encoding the current version of the library. The encoding is +of the form 0x@var{MMmm}, where @var{MM} is the two-digit major version +number, and @var{mm} is the two-digit minor version number. +For example, for Readline-4.2, @code{rl_readline_version} would have the +value 0x0402. +@end deftypevar + +@deftypevar {int} rl_gnu_readline_p +Always set to 1, denoting that this is @sc{gnu} readline rather than some +emulation. +@end deftypevar + +@deftypevar {const char *} rl_terminal_name +The terminal type, used for initialization. If not set by the application, +Readline sets this to the value of the @env{TERM} environment variable +the first time it is called. +@end deftypevar + +@deftypevar {const char *} rl_readline_name +This variable is set to a unique name by each application using Readline. +The value allows conditional parsing of the inputrc file +(@pxref{Conditional Init Constructs}). +@end deftypevar + +@deftypevar {FILE *} rl_instream +The stdio stream from which Readline reads input. +If @code{NULL}, Readline defaults to @var{stdin}. +@end deftypevar + +@deftypevar {FILE *} rl_outstream +The stdio stream to which Readline performs output. +If @code{NULL}, Readline defaults to @var{stdout}. +@end deftypevar + +@deftypevar int rl_prefer_env_winsize +If non-zero, Readline gives values found in the @env{LINES} and +@env{COLUMNS} environment variables greater precedence than values fetched +from the kernel when computing the screen dimensions. +@end deftypevar + +@deftypevar {rl_command_func_t *} rl_last_func +The address of the last command function Readline executed. May be used to +test whether or not a function is being executed twice in succession, for +example. +@end deftypevar + +@deftypevar {rl_hook_func_t *} rl_startup_hook +If non-zero, this is the address of a function to call just +before @code{readline} prints the first prompt. +@end deftypevar + +@deftypevar {rl_hook_func_t *} rl_pre_input_hook +If non-zero, this is the address of a function to call after +the first prompt has been printed and just before @code{readline} +starts reading input characters. +@end deftypevar + +@deftypevar {rl_hook_func_t *} rl_event_hook +If non-zero, this is the address of a function to call periodically +when Readline is waiting for terminal input. +By default, this will be called at most ten times a second if there +is no keyboard input. +@end deftypevar + +@deftypevar {rl_getc_func_t *} rl_getc_function +If non-zero, Readline will call indirectly through this pointer +to get a character from the input stream. By default, it is set to +@code{rl_getc}, the default Readline character input function +(@pxref{Character Input}). +In general, an application that sets @var{rl_getc_function} should consider +setting @var{rl_input_available_hook} as well. +@end deftypevar + +@deftypevar {rl_hook_func_t *} rl_signal_event_hook +If non-zero, this is the address of a function to call if a read system +call is interrupted when Readline is reading terminal input. +@end deftypevar + +@deftypevar {rl_hook_func_t *} rl_input_available_hook +If non-zero, Readline will use this function's return value when it needs +to determine whether or not there is available input on the current input +source. +The default hook checks @code{rl_instream}; if an application is using a +different input source, it should set the hook appropriately. +Readline queries for available input when implementing intra-key-sequence +timeouts during input and incremental searches. +This may use an application-specific timeout before returning a value; +Readline uses the value passed to @code{rl_set_keyboard_input_timeout()} +or the value of the user-settable @var{keyseq-timeout} variable. +This is designed for use by applications using Readline's callback interface +(@pxref{Alternate Interface}), which may not use the traditional +@code{read(2)} and file descriptor interface, or other applications using +a different input mechanism. +If an application uses an input mechanism or hook that can potentially exceed +the value of @var{keyseq-timeout}, it should increase the timeout or set +this hook appropriately even when not using the callback interface. +In general, an application that sets @var{rl_getc_function} should consider +setting @var{rl_input_available_hook} as well. +@end deftypevar + +@deftypevar {rl_voidfunc_t *} rl_redisplay_function +If non-zero, Readline will call indirectly through this pointer +to update the display with the current contents of the editing buffer. +By default, it is set to @code{rl_redisplay}, the default Readline +redisplay function (@pxref{Redisplay}). +@end deftypevar + +@deftypevar {rl_vintfunc_t *} rl_prep_term_function +If non-zero, Readline will call indirectly through this pointer +to initialize the terminal. The function takes a single argument, an +@code{int} flag that says whether or not to use eight-bit characters. +By default, this is set to @code{rl_prep_terminal} +(@pxref{Terminal Management}). +@end deftypevar + +@deftypevar {rl_voidfunc_t *} rl_deprep_term_function +If non-zero, Readline will call indirectly through this pointer +to reset the terminal. This function should undo the effects of +@code{rl_prep_term_function}. +By default, this is set to @code{rl_deprep_terminal} +(@pxref{Terminal Management}). +@end deftypevar + +@deftypevar {Keymap} rl_executing_keymap +This variable is set to the keymap (@pxref{Keymaps}) in which the +currently executing readline function was found. +@end deftypevar + +@deftypevar {Keymap} rl_binding_keymap +This variable is set to the keymap (@pxref{Keymaps}) in which the +last key binding occurred. +@end deftypevar + +@deftypevar {char *} rl_executing_macro +This variable is set to the text of any currently-executing macro. +@end deftypevar + +@deftypevar int rl_executing_key +The key that caused the dispatch to the currently-executing Readline function. +@end deftypevar + +@deftypevar {char *} rl_executing_keyseq +The full key sequence that caused the dispatch to the currently-executing +Readline function. +@end deftypevar + +@deftypevar int rl_key_sequence_length +The number of characters in @var{rl_executing_keyseq}. +@end deftypevar + +@deftypevar {int} rl_readline_state +A variable with bit values that encapsulate the current Readline state. +A bit is set with the @code{RL_SETSTATE} macro, and unset with the +@code{RL_UNSETSTATE} macro. Use the @code{RL_ISSTATE} macro to test +whether a particular state bit is set. Current state bits include: + +@table @code +@item RL_STATE_NONE +Readline has not yet been called, nor has it begun to initialize. +@item RL_STATE_INITIALIZING +Readline is initializing its internal data structures. +@item RL_STATE_INITIALIZED +Readline has completed its initialization. +@item RL_STATE_TERMPREPPED +Readline has modified the terminal modes to do its own input and redisplay. +@item RL_STATE_READCMD +Readline is reading a command from the keyboard. +@item RL_STATE_METANEXT +Readline is reading more input after reading the meta-prefix character. +@item RL_STATE_DISPATCHING +Readline is dispatching to a command. +@item RL_STATE_MOREINPUT +Readline is reading more input while executing an editing command. +@item RL_STATE_ISEARCH +Readline is performing an incremental history search. +@item RL_STATE_NSEARCH +Readline is performing a non-incremental history search. +@item RL_STATE_SEARCH +Readline is searching backward or forward through the history for a string. +@item RL_STATE_NUMERICARG +Readline is reading a numeric argument. +@item RL_STATE_MACROINPUT +Readline is currently getting its input from a previously-defined keyboard +macro. +@item RL_STATE_MACRODEF +Readline is currently reading characters defining a keyboard macro. +@item RL_STATE_OVERWRITE +Readline is in overwrite mode. +@item RL_STATE_COMPLETING +Readline is performing word completion. +@item RL_STATE_SIGHANDLER +Readline is currently executing the readline signal handler. +@item RL_STATE_UNDOING +Readline is performing an undo. +@item RL_STATE_INPUTPENDING +Readline has input pending due to a call to @code{rl_execute_next()}. +@item RL_STATE_TTYCSAVED +Readline has saved the values of the terminal's special characters. +@item RL_STATE_CALLBACK +Readline is currently using the alternate (callback) interface +(@pxref{Alternate Interface}). +@item RL_STATE_VIMOTION +Readline is reading the argument to a vi-mode "motion" command. +@item RL_STATE_MULTIKEY +Readline is reading a multiple-keystroke command. +@item RL_STATE_VICMDONCE +Readline has entered vi command (movement) mode at least one time during +the current call to @code{readline()}. +@item RL_STATE_DONE +Readline has read a key sequence bound to @code{accept-line} +and is about to return the line to the caller. +@end table + +@end deftypevar + +@deftypevar {int} rl_explicit_arg +Set to a non-zero value if an explicit numeric argument was specified by +the user. Only valid in a bindable command function. +@end deftypevar + +@deftypevar {int} rl_numeric_arg +Set to the value of any numeric argument explicitly specified by the user +before executing the current Readline function. Only valid in a bindable +command function. +@end deftypevar + +@deftypevar {int} rl_editing_mode +Set to a value denoting Readline's current editing mode. A value of +@var{1} means Readline is currently in emacs mode; @var{0} +means that vi mode is active. +@end deftypevar + + +@node Readline Convenience Functions +@section Readline Convenience Functions + +@menu +* Function Naming:: How to give a function you write a name. +* Keymaps:: Making keymaps. +* Binding Keys:: Changing Keymaps. +* Associating Function Names and Bindings:: Translate function names to + key sequences. +* Allowing Undoing:: How to make your functions undoable. +* Redisplay:: Functions to control line display. +* Modifying Text:: Functions to modify @code{rl_line_buffer}. +* Character Input:: Functions to read keyboard input. +* Terminal Management:: Functions to manage terminal settings. +* Utility Functions:: Generally useful functions and hooks. +* Miscellaneous Functions:: Functions that don't fall into any category. +* Alternate Interface:: Using Readline in a `callback' fashion. +* A Readline Example:: An example Readline function. +* Alternate Interface Example:: An example program using the alternate interface. +@end menu + +@node Function Naming +@subsection Naming a Function + +The user can dynamically change the bindings of keys while using +Readline. This is done by representing the function with a descriptive +name. The user is able to type the descriptive name when referring to +the function. Thus, in an init file, one might find + +@example +Meta-Rubout: backward-kill-word +@end example + +This binds the keystroke @key{Meta-Rubout} to the function +@emph{descriptively} named @code{backward-kill-word}. You, as the +programmer, should bind the functions you write to descriptive names as +well. Readline provides a function for doing that: + +@deftypefun int rl_add_defun (const char *name, rl_command_func_t *function, int key) +Add @var{name} to the list of named functions. Make @var{function} be +the function that gets called. If @var{key} is not -1, then bind it to +@var{function} using @code{rl_bind_key()}. +@end deftypefun + +Using this function alone is sufficient for most applications. +It is the recommended way to add a few functions to the default +functions that Readline has built in. +If you need to do something other than adding a function to Readline, +you may need to use the underlying functions described below. + +@node Keymaps +@subsection Selecting a Keymap + +Key bindings take place on a @dfn{keymap}. The keymap is the +association between the keys that the user types and the functions that +get run. You can make your own keymaps, copy existing keymaps, and tell +Readline which keymap to use. + +@deftypefun Keymap rl_make_bare_keymap (void) +Returns a new, empty keymap. The space for the keymap is allocated with +@code{malloc()}; the caller should free it by calling +@code{rl_free_keymap()} when done. +@end deftypefun + +@deftypefun Keymap rl_copy_keymap (Keymap map) +Return a new keymap which is a copy of @var{map}. +@end deftypefun + +@deftypefun Keymap rl_make_keymap (void) +Return a new keymap with the printing characters bound to rl_insert, +the lowercase Meta characters bound to run their equivalents, and +the Meta digits bound to produce numeric arguments. +@end deftypefun + +@deftypefun void rl_discard_keymap (Keymap keymap) +Free the storage associated with the data in @var{keymap}. +The caller should free @var{keymap}. +@end deftypefun + +@deftypefun void rl_free_keymap (Keymap keymap) +Free all storage associated with @var{keymap}. This calls +@code{rl_discard_keymap} to free subordindate keymaps and macros. +@end deftypefun + +@deftypefun int rl_empty_keymap (Keymap keymap) +Return non-zero if there are no keys bound to functions in @var{keymap}; +zero if there are any keys bound. +@end deftypefun + +Readline has several internal keymaps. These functions allow you to +change which keymap is active. + +@deftypefun Keymap rl_get_keymap (void) +Returns the currently active keymap. +@end deftypefun + +@deftypefun void rl_set_keymap (Keymap keymap) +Makes @var{keymap} the currently active keymap. +@end deftypefun + +@deftypefun Keymap rl_get_keymap_by_name (const char *name) +Return the keymap matching @var{name}. @var{name} is one which would +be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}). +@end deftypefun + +@deftypefun {char *} rl_get_keymap_name (Keymap keymap) +Return the name matching @var{keymap}. @var{name} is one which would +be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}). +@end deftypefun + +@deftypefun int rl_set_keymap_name (const char *name, Keymap keymap) +Set the name of @var{keymap}. This name will then be "registered" and +available for use in a @code{set keymap} inputrc directive +@pxref{Readline Init File}). +The @var{name} may not be one of Readline's builtin keymap names; +you may not add a different name for one of Readline's builtin keymaps. +You may replace the name associated with a given keymap by calling this +function more than once with the same @var{keymap} argument. +You may associate a registered @var{name} with a new keymap by calling this +function more than once with the same @var{name} argument. +There is no way to remove a named keymap once the name has been +registered. +Readline will make a copy of @var{name}. +The return value is greater than zero unless @var{name} is one of +Readline's builtin keymap names or @var{keymap} is one of Readline's +builtin keymaps. +@end deftypefun + +@node Binding Keys +@subsection Binding Keys + +Key sequences are associate with functions through the keymap. +Readline has several internal keymaps: @code{emacs_standard_keymap}, +@code{emacs_meta_keymap}, @code{emacs_ctlx_keymap}, +@code{vi_movement_keymap}, and @code{vi_insertion_keymap}. +@code{emacs_standard_keymap} is the default, and the examples in +this manual assume that. + +Since @code{readline()} installs a set of default key bindings the first +time it is called, there is always the danger that a custom binding +installed before the first call to @code{readline()} will be overridden. +An alternate mechanism is to install custom key bindings in an +initialization function assigned to the @code{rl_startup_hook} variable +(@pxref{Readline Variables}). + +These functions manage key bindings. + +@deftypefun int rl_bind_key (int key, rl_command_func_t *function) +Binds @var{key} to @var{function} in the currently active keymap. +Returns non-zero in the case of an invalid @var{key}. +@end deftypefun + +@deftypefun int rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map) +Bind @var{key} to @var{function} in @var{map}. +Returns non-zero in the case of an invalid @var{key}. +@end deftypefun + +@deftypefun int rl_bind_key_if_unbound (int key, rl_command_func_t *function) +Binds @var{key} to @var{function} if it is not already bound in the +currently active keymap. +Returns non-zero in the case of an invalid @var{key} or if @var{key} is +already bound. +@end deftypefun + +@deftypefun int rl_bind_key_if_unbound_in_map (int key, rl_command_func_t *function, Keymap map) +Binds @var{key} to @var{function} if it is not already bound in @var{map}. +Returns non-zero in the case of an invalid @var{key} or if @var{key} is +already bound. +@end deftypefun + +@deftypefun int rl_unbind_key (int key) +Bind @var{key} to the null function in the currently active keymap. +Returns non-zero in case of error. +@end deftypefun + +@deftypefun int rl_unbind_key_in_map (int key, Keymap map) +Bind @var{key} to the null function in @var{map}. +Returns non-zero in case of error. +@end deftypefun + +@deftypefun int rl_unbind_function_in_map (rl_command_func_t *function, Keymap map) +Unbind all keys that execute @var{function} in @var{map}. +@end deftypefun + +@deftypefun int rl_unbind_command_in_map (const char *command, Keymap map) +Unbind all keys that are bound to @var{command} in @var{map}. +@end deftypefun + +@deftypefun int rl_bind_keyseq (const char *keyseq, rl_command_func_t *function) +Bind the key sequence represented by the string @var{keyseq} to the function +@var{function}, beginning in the current keymap. +This makes new keymaps as necessary. +The return value is non-zero if @var{keyseq} is invalid. +@end deftypefun + +@deftypefun int rl_bind_keyseq_in_map (const char *keyseq, rl_command_func_t *function, Keymap map) +Bind the key sequence represented by the string @var{keyseq} to the function +@var{function}. This makes new keymaps as necessary. +Initial bindings are performed in @var{map}. +The return value is non-zero if @var{keyseq} is invalid. +@end deftypefun + +@deftypefun int rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map) +Equivalent to @code{rl_bind_keyseq_in_map}. +@end deftypefun + +@deftypefun int rl_bind_keyseq_if_unbound (const char *keyseq, rl_command_func_t *function) +Binds @var{keyseq} to @var{function} if it is not already bound in the +currently active keymap. +Returns non-zero in the case of an invalid @var{keyseq} or if @var{keyseq} is +already bound. +@end deftypefun + +@deftypefun int rl_bind_keyseq_if_unbound_in_map (const char *keyseq, rl_command_func_t *function, Keymap map) +Binds @var{keyseq} to @var{function} if it is not already bound in @var{map}. +Returns non-zero in the case of an invalid @var{keyseq} or if @var{keyseq} is +already bound. +@end deftypefun + +@deftypefun int rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) +Bind the key sequence represented by the string @var{keyseq} to the arbitrary +pointer @var{data}. @var{type} says what kind of data is pointed to by +@var{data}; this can be a function (@code{ISFUNC}), a macro +(@code{ISMACR}), or a keymap (@code{ISKMAP}). This makes new keymaps as +necessary. The initial keymap in which to do bindings is @var{map}. +@end deftypefun + +@deftypefun int rl_parse_and_bind (char *line) +Parse @var{line} as if it had been read from the @code{inputrc} file and +perform any key bindings and variable assignments found +(@pxref{Readline Init File}). +@end deftypefun + +@deftypefun int rl_read_init_file (const char *filename) +Read keybindings and variable assignments from @var{filename} +(@pxref{Readline Init File}). +@end deftypefun + +@node Associating Function Names and Bindings +@subsection Associating Function Names and Bindings + +These functions allow you to find out what keys invoke named functions +and the functions invoked by a particular key sequence. You may also +associate a new function name with an arbitrary function. + +@deftypefun {rl_command_func_t *} rl_named_function (const char *name) +Return the function with name @var{name}. +@end deftypefun + +@deftypefun {rl_command_func_t *} rl_function_of_keyseq (const char *keyseq, Keymap map, int *type) +Return the function invoked by @var{keyseq} in keymap @var{map}. +If @var{map} is @code{NULL}, the current keymap is used. If @var{type} is +not @code{NULL}, the type of the object is returned in the @code{int} variable +it points to (one of @code{ISFUNC}, @code{ISKMAP}, or @code{ISMACR}). +It takes a "translated" key sequence and should not be used if the key sequence +can include NUL. +@end deftypefun + +@deftypefun {rl_command_func_t *} rl_function_of_keyseq_len (const char *keyseq, size_t len, Keymap map, int *type) +Return the function invoked by @var{keyseq} of length @var{len} +in keymap @var{map}. Equivalent to @code{rl_function_of_keyseq} with the +addition of the @var{len} parameter. +It takes a "translated" key sequence and should be used if the key sequence +can include NUL. +@end deftypefun + +@deftypefun {char **} rl_invoking_keyseqs (rl_command_func_t *function) +Return an array of strings representing the key sequences used to +invoke @var{function} in the current keymap. +@end deftypefun + +@deftypefun {char **} rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map) +Return an array of strings representing the key sequences used to +invoke @var{function} in the keymap @var{map}. +@end deftypefun + +@deftypefun void rl_function_dumper (int readable) +Print the readline function names and the key sequences currently +bound to them to @code{rl_outstream}. If @var{readable} is non-zero, +the list is formatted in such a way that it can be made part of an +@code{inputrc} file and re-read. +@end deftypefun + +@deftypefun void rl_list_funmap_names (void) +Print the names of all bindable Readline functions to @code{rl_outstream}. +@end deftypefun + +@deftypefun {const char **} rl_funmap_names (void) +Return a NULL terminated array of known function names. The array is +sorted. The array itself is allocated, but not the strings inside. You +should free the array, but not the pointers, using @code{free} or +@code{rl_free} when you are done. +@end deftypefun + +@deftypefun int rl_add_funmap_entry (const char *name, rl_command_func_t *function) +Add @var{name} to the list of bindable Readline command names, and make +@var{function} the function to be called when @var{name} is invoked. +@end deftypefun + +@node Allowing Undoing +@subsection Allowing Undoing + +Supporting the undo command is a painless thing, and makes your +functions much more useful. It is certainly easy to try +something if you know you can undo it. + +If your function simply inserts text once, or deletes text once, and +uses @code{rl_insert_text()} or @code{rl_delete_text()} to do it, then +undoing is already done for you automatically. + +If you do multiple insertions or multiple deletions, or any combination +of these operations, you should group them together into one operation. +This is done with @code{rl_begin_undo_group()} and +@code{rl_end_undo_group()}. + +The types of events that can be undone are: + +@smallexample +enum undo_code @{ UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END @}; +@end smallexample + +Notice that @code{UNDO_DELETE} means to insert some text, and +@code{UNDO_INSERT} means to delete some text. That is, the undo code +tells what to undo, not how to undo it. @code{UNDO_BEGIN} and +@code{UNDO_END} are tags added by @code{rl_begin_undo_group()} and +@code{rl_end_undo_group()}. + +@deftypefun int rl_begin_undo_group (void) +Begins saving undo information in a group construct. The undo +information usually comes from calls to @code{rl_insert_text()} and +@code{rl_delete_text()}, but could be the result of calls to +@code{rl_add_undo()}. +@end deftypefun + +@deftypefun int rl_end_undo_group (void) +Closes the current undo group started with @code{rl_begin_undo_group +()}. There should be one call to @code{rl_end_undo_group()} +for each call to @code{rl_begin_undo_group()}. +@end deftypefun + +@deftypefun void rl_add_undo (enum undo_code what, int start, int end, char *text) +Remember how to undo an event (according to @var{what}). The affected +text runs from @var{start} to @var{end}, and encompasses @var{text}. +@end deftypefun + +@deftypefun void rl_free_undo_list (void) +Free the existing undo list. +@end deftypefun + +@deftypefun int rl_do_undo (void) +Undo the first thing on the undo list. Returns @code{0} if there was +nothing to undo, non-zero if something was undone. +@end deftypefun + +Finally, if you neither insert nor delete text, but directly modify the +existing text (e.g., change its case), call @code{rl_modifying()} +once, just before you modify the text. You must supply the indices of +the text range that you are going to modify. + +@deftypefun int rl_modifying (int start, int end) +Tell Readline to save the text between @var{start} and @var{end} as a +single undo unit. It is assumed that you will subsequently modify +that text. +@end deftypefun + +@node Redisplay +@subsection Redisplay + +@deftypefun void rl_redisplay (void) +Change what's displayed on the screen to reflect the current contents +of @code{rl_line_buffer}. +@end deftypefun + +@deftypefun int rl_forced_update_display (void) +Force the line to be updated and redisplayed, whether or not +Readline thinks the screen display is correct. +@end deftypefun + +@deftypefun int rl_on_new_line (void) +Tell the update functions that we have moved onto a new (empty) line, +usually after outputting a newline. +@end deftypefun + +@deftypefun int rl_on_new_line_with_prompt (void) +Tell the update functions that we have moved onto a new line, with +@var{rl_prompt} already displayed. +This could be used by applications that want to output the prompt string +themselves, but still need Readline to know the prompt string length for +redisplay. +It should be used after setting @var{rl_already_prompted}. +@end deftypefun + +@deftypefun int rl_clear_visible_line (void) +Clear the screen lines corresponding to the current line's contents. +@end deftypefun + +@deftypefun int rl_reset_line_state (void) +Reset the display state to a clean state and redisplay the current line +starting on a new line. +@end deftypefun + +@deftypefun int rl_crlf (void) +Move the cursor to the start of the next screen line. +@end deftypefun + +@deftypefun int rl_show_char (int c) +Display character @var{c} on @code{rl_outstream}. +If Readline has not been set to display meta characters directly, this +will convert meta characters to a meta-prefixed key sequence. +This is intended for use by applications which wish to do their own +redisplay. +@end deftypefun + +@deftypefun int rl_message (const char *, @dots{}) +The arguments are a format string as would be supplied to @code{printf}, +possibly containing conversion specifications such as @samp{%d}, and +any additional arguments necessary to satisfy the conversion specifications. +The resulting string is displayed in the @dfn{echo area}. The echo area +is also used to display numeric arguments and search strings. +You should call @code{rl_save_prompt} to save the prompt information +before calling this function. +@end deftypefun + +@deftypefun int rl_clear_message (void) +Clear the message in the echo area. If the prompt was saved with a call to +@code{rl_save_prompt} before the last call to @code{rl_message}, +call @code{rl_restore_prompt} before calling this function. +@end deftypefun + +@deftypefun void rl_save_prompt (void) +Save the local Readline prompt display state in preparation for +displaying a new message in the message area with @code{rl_message()}. +@end deftypefun + +@deftypefun void rl_restore_prompt (void) +Restore the local Readline prompt display state saved by the most +recent call to @code{rl_save_prompt}. +if @code{rl_save_prompt} was called to save the prompt before a call +to @code{rl_message}, this function should be called before the +corresponding call to @code{rl_clear_message}. +@end deftypefun + +@deftypefun int rl_expand_prompt (char *prompt) +Expand any special character sequences in @var{prompt} and set up the +local Readline prompt redisplay variables. +This function is called by @code{readline()}. It may also be called to +expand the primary prompt if the @code{rl_on_new_line_with_prompt()} +function or @code{rl_already_prompted} variable is used. +It returns the number of visible characters on the last line of the +(possibly multi-line) prompt. +Applications may indicate that the prompt contains characters that take +up no physical screen space when displayed by bracketing a sequence of +such characters with the special markers @code{RL_PROMPT_START_IGNORE} +and @code{RL_PROMPT_END_IGNORE} (declared in @file{readline.h}). This may +be used to embed terminal-specific escape sequences in prompts. +@end deftypefun + +@deftypefun int rl_set_prompt (const char *prompt) +Make Readline use @var{prompt} for subsequent redisplay. This calls +@code{rl_expand_prompt()} to expand the prompt and sets @code{rl_prompt} +to the result. +@end deftypefun + +@node Modifying Text +@subsection Modifying Text + +@deftypefun int rl_insert_text (const char *text) +Insert @var{text} into the line at the current cursor position. +Returns the number of characters inserted. +@end deftypefun + +@deftypefun int rl_delete_text (int start, int end) +Delete the text between @var{start} and @var{end} in the current line. +Returns the number of characters deleted. +@end deftypefun + +@deftypefun {char *} rl_copy_text (int start, int end) +Return a copy of the text between @var{start} and @var{end} in +the current line. +@end deftypefun + +@deftypefun int rl_kill_text (int start, int end) +Copy the text between @var{start} and @var{end} in the current line +to the kill ring, appending or prepending to the last kill if the +last command was a kill command. The text is deleted. +If @var{start} is less than @var{end}, +the text is appended, otherwise prepended. If the last command was +not a kill, a new kill ring slot is used. +@end deftypefun + +@deftypefun int rl_push_macro_input (char *macro) +Cause @var{macro} to be inserted into the line, as if it had been invoked +by a key bound to a macro. Not especially useful; use +@code{rl_insert_text()} instead. +@end deftypefun + +@node Character Input +@subsection Character Input + +@deftypefun int rl_read_key (void) +Return the next character available from Readline's current input stream. +This handles input inserted into +the input stream via @var{rl_pending_input} (@pxref{Readline Variables}) +and @code{rl_stuff_char()}, macros, and characters read from the keyboard. +While waiting for input, this function will call any function assigned to +the @code{rl_event_hook} variable. +@end deftypefun + +@deftypefun int rl_getc (FILE *stream) +Return the next character available from @var{stream}, which is assumed to +be the keyboard. +@end deftypefun + +@deftypefun int rl_stuff_char (int c) +Insert @var{c} into the Readline input stream. It will be "read" +before Readline attempts to read characters from the terminal with +@code{rl_read_key()}. Up to 512 characters may be pushed back. +@code{rl_stuff_char} returns 1 if the character was successfully inserted; +0 otherwise. +@end deftypefun + +@deftypefun int rl_execute_next (int c) +Make @var{c} be the next command to be executed when @code{rl_read_key()} +is called. This sets @var{rl_pending_input}. +@end deftypefun + +@deftypefun int rl_clear_pending_input (void) +Unset @var{rl_pending_input}, effectively negating the effect of any +previous call to @code{rl_execute_next()}. This works only if the +pending input has not already been read with @code{rl_read_key()}. +@end deftypefun + +@deftypefun int rl_set_keyboard_input_timeout (int u) +While waiting for keyboard input in @code{rl_read_key()}, Readline will +wait for @var{u} microseconds for input before calling any function +assigned to @code{rl_event_hook}. @var{u} must be greater than or equal +to zero (a zero-length timeout is equivalent to a poll). +The default waiting period is one-tenth of a second. +Returns the old timeout value. +@end deftypefun + +@node Terminal Management +@subsection Terminal Management + +@deftypefun void rl_prep_terminal (int meta_flag) +Modify the terminal settings for Readline's use, so @code{readline()} +can read a single character at a time from the keyboard. +The @var{meta_flag} argument should be non-zero if Readline should +read eight-bit input. +@end deftypefun + +@deftypefun void rl_deprep_terminal (void) +Undo the effects of @code{rl_prep_terminal()}, leaving the terminal in +the state in which it was before the most recent call to +@code{rl_prep_terminal()}. +@end deftypefun + +@deftypefun void rl_tty_set_default_bindings (Keymap kmap) +Read the operating system's terminal editing characters (as would be +displayed by @code{stty}) to their Readline equivalents. +The bindings are performed in @var{kmap}. +@end deftypefun + +@deftypefun void rl_tty_unset_default_bindings (Keymap kmap) +Reset the bindings manipulated by @code{rl_tty_set_default_bindings} so +that the terminal editing characters are bound to @code{rl_insert}. +The bindings are performed in @var{kmap}. +@end deftypefun + +@deftypefun int rl_tty_set_echoing (int value) +Set Readline's idea of whether or not it is echoing output to its output +stream (@var{rl_outstream}). If @var{value} is 0, Readline does not display +output to @var{rl_outstream}; any other value enables output. The initial +value is set when Readline initializes the terminal settings. +This function returns the previous value. +@end deftypefun + +@deftypefun int rl_reset_terminal (const char *terminal_name) +Reinitialize Readline's idea of the terminal settings using +@var{terminal_name} as the terminal type (e.g., @code{vt100}). +If @var{terminal_name} is @code{NULL}, the value of the @code{TERM} +environment variable is used. +@end deftypefun + +@node Utility Functions +@subsection Utility Functions + +@deftypefun int rl_save_state (struct readline_state *sp) +Save a snapshot of Readline's internal state to @var{sp}. +The contents of the @var{readline_state} structure are documented +in @file{readline.h}. +The caller is responsible for allocating the structure. +@end deftypefun + +@deftypefun int rl_restore_state (struct readline_state *sp) +Restore Readline's internal state to that stored in @var{sp}, which must +have been saved by a call to @code{rl_save_state}. +The contents of the @var{readline_state} structure are documented +in @file{readline.h}. +The caller is responsible for freeing the structure. +@end deftypefun + +@deftypefun void rl_free (void *mem) +Deallocate the memory pointed to by @var{mem}. @var{mem} must have been +allocated by @code{malloc}. +@end deftypefun + +@deftypefun void rl_replace_line (const char *text, int clear_undo) +Replace the contents of @code{rl_line_buffer} with @var{text}. +The point and mark are preserved, if possible. +If @var{clear_undo} is non-zero, the undo list associated with the +current line is cleared. +@end deftypefun + +@deftypefun void rl_extend_line_buffer (int len) +Ensure that @code{rl_line_buffer} has enough space to hold @var{len} +characters, possibly reallocating it if necessary. +@end deftypefun + +@deftypefun int rl_initialize (void) +Initialize or re-initialize Readline's internal state. +It's not strictly necessary to call this; @code{readline()} calls it before +reading any input. +@end deftypefun + +@deftypefun int rl_ding (void) +Ring the terminal bell, obeying the setting of @code{bell-style}. +@end deftypefun + +@deftypefun int rl_alphabetic (int c) +Return 1 if @var{c} is an alphabetic character. +@end deftypefun + +@deftypefun void rl_display_match_list (char **matches, int len, int max) +A convenience function for displaying a list of strings in +columnar format on Readline's output stream. @code{matches} is the list +of strings, in argv format, such as a list of completion matches. +@code{len} is the number of strings in @code{matches}, and @code{max} +is the length of the longest string in @code{matches}. This function uses +the setting of @code{print-completions-horizontally} to select how the +matches are displayed (@pxref{Readline Init File Syntax}). +When displaying completions, this function sets the number of columns used +for display to the value of @code{completion-display-width}, the value of +the environment variable @env{COLUMNS}, or the screen width, in that order. +@end deftypefun + +The following are implemented as macros, defined in @code{chardefs.h}. +Applications should refrain from using them. + +@deftypefun int _rl_uppercase_p (int c) +Return 1 if @var{c} is an uppercase alphabetic character. +@end deftypefun + +@deftypefun int _rl_lowercase_p (int c) +Return 1 if @var{c} is a lowercase alphabetic character. +@end deftypefun + +@deftypefun int _rl_digit_p (int c) +Return 1 if @var{c} is a numeric character. +@end deftypefun + +@deftypefun int _rl_to_upper (int c) +If @var{c} is a lowercase alphabetic character, return the corresponding +uppercase character. +@end deftypefun + +@deftypefun int _rl_to_lower (int c) +If @var{c} is an uppercase alphabetic character, return the corresponding +lowercase character. +@end deftypefun + +@deftypefun int _rl_digit_value (int c) +If @var{c} is a number, return the value it represents. +@end deftypefun + +@node Miscellaneous Functions +@subsection Miscellaneous Functions + +@deftypefun int rl_macro_bind (const char *keyseq, const char *macro, Keymap map) +Bind the key sequence @var{keyseq} to invoke the macro @var{macro}. +The binding is performed in @var{map}. When @var{keyseq} is invoked, the +@var{macro} will be inserted into the line. This function is deprecated; +use @code{rl_generic_bind()} instead. +@end deftypefun + +@deftypefun void rl_macro_dumper (int readable) +Print the key sequences bound to macros and their values, using +the current keymap, to @code{rl_outstream}. +If @var{readable} is non-zero, the list is formatted in such a way +that it can be made part of an @code{inputrc} file and re-read. +@end deftypefun + +@deftypefun int rl_variable_bind (const char *variable, const char *value) +Make the Readline variable @var{variable} have @var{value}. +This behaves as if the readline command +@samp{set @var{variable} @var{value}} had been executed in an @code{inputrc} +file (@pxref{Readline Init File Syntax}). +@end deftypefun + +@deftypefun {char *} rl_variable_value (const char *variable) +Return a string representing the value of the Readline variable @var{variable}. +For boolean variables, this string is either @samp{on} or @samp{off}. +@end deftypefun + +@deftypefun void rl_variable_dumper (int readable) +Print the readline variable names and their current values +to @code{rl_outstream}. +If @var{readable} is non-zero, the list is formatted in such a way +that it can be made part of an @code{inputrc} file and re-read. +@end deftypefun + +@deftypefun int rl_set_paren_blink_timeout (int u) +Set the time interval (in microseconds) that Readline waits when showing +a balancing character when @code{blink-matching-paren} has been enabled. +@end deftypefun + +@deftypefun {char *} rl_get_termcap (const char *cap) +Retrieve the string value of the termcap capability @var{cap}. +Readline fetches the termcap entry for the current terminal name and +uses those capabilities to move around the screen line and perform other +terminal-specific operations, like erasing a line. Readline does not +use all of a terminal's capabilities, and this function will return +values for only those capabilities Readline uses. +@end deftypefun + +@deftypefun {void} rl_clear_history (void) +Clear the history list by deleting all of the entries, in the same manner +as the History library's @code{clear_history()} function. +This differs from @code{clear_history} because it frees private data +Readline saves in the history list. +@end deftypefun + +@deftypefun {void} rl_activate_mark (void) +Enable an @emph{active} mark. +When this is enabled, the text between point and mark (the @var{region}) is +displayed in the terminal's standout mode (a @var{face}). +This is called by various readline functions that set the mark and insert +text, and is available for applications to call. +@end deftypefun + +@deftypefun {void} rl_deactivate_mark (void) +Turn off the active mark. +@end deftypefun + +@deftypefun {void} rl_keep_mark_active (void) +Indicate that the mark should remain active when the current readline function +completes and after redisplay occurs. +In most cases, the mark remains active for only the duration of a single +bindable readline function. +@end deftypefun + +@deftypefun {int} rl_mark_active_p (void) +Return a non-zero value if the mark is currently active; zero otherwise. +@end deftypefun + +@node Alternate Interface +@subsection Alternate Interface + +An alternate interface is available to plain @code{readline()}. Some +applications need to interleave keyboard I/O with file, device, or +window system I/O, typically by using a main loop to @code{select()} +on various file descriptors. To accommodate this need, readline can +also be invoked as a `callback' function from an event loop. There +are functions available to make this easy. + +@deftypefun void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler) +Set up the terminal for readline I/O and display the initial +expanded value of @var{prompt}. Save the value of @var{lhandler} to +use as a handler function to call when a complete line of input has been +entered. +The handler function receives the text of the line as an argument. +As with @code{readline()}, the handler function should @code{free} the +line when it it finished with it. +@end deftypefun + +@deftypefun void rl_callback_read_char (void) +Whenever an application determines that keyboard input is available, it +should call @code{rl_callback_read_char()}, which will read the next +character from the current input source. +If that character completes the line, @code{rl_callback_read_char} will +invoke the @var{lhandler} function installed by +@code{rl_callback_handler_install} to process the line. +Before calling the @var{lhandler} function, the terminal settings are +reset to the values they had before calling +@code{rl_callback_handler_install}. +If the @var{lhandler} function returns, +and the line handler remains installed, +the terminal settings are modified for Readline's use again. +@code{EOF} is indicated by calling @var{lhandler} with a +@code{NULL} line. +@end deftypefun + +@deftypefun void rl_callback_sigcleanup (void) +Clean up any internal state the callback interface uses to maintain state +between calls to rl_callback_read_char (e.g., the state of any active +incremental searches). This is intended to be used by applications that +wish to perform their own signal handling; Readline's internal signal handler +calls this when appropriate. +@end deftypefun + +@deftypefun void rl_callback_handler_remove (void) +Restore the terminal to its initial state and remove the line handler. +You may call this function from within a callback as well as independently. +If the @var{lhandler} installed by @code{rl_callback_handler_install} +does not exit the program, either this function or the function referred +to by the value of @code{rl_deprep_term_function} should be called before +the program exits to reset the terminal settings. +@end deftypefun + +@node A Readline Example +@subsection A Readline Example + +Here is a function which changes lowercase characters to their uppercase +equivalents, and uppercase characters to lowercase. If +this function was bound to @samp{M-c}, then typing @samp{M-c} would +change the case of the character under point. Typing @samp{M-1 0 M-c} +would change the case of the following 10 characters, leaving the cursor on +the last character changed. + +@example +/* Invert the case of the COUNT following characters. */ +int +invert_case_line (count, key) + int count, key; +@{ + register int start, end, i; + + start = rl_point; + + if (rl_point >= rl_end) + return (0); + + if (count < 0) + @{ + direction = -1; + count = -count; + @} + else + direction = 1; + + /* Find the end of the range to modify. */ + end = start + (count * direction); + + /* Force it to be within range. */ + if (end > rl_end) + end = rl_end; + else if (end < 0) + end = 0; + + if (start == end) + return (0); + + if (start > end) + @{ + int temp = start; + start = end; + end = temp; + @} + + /* Tell readline that we are modifying the line, + so it will save the undo information. */ + rl_modifying (start, end); + + for (i = start; i != end; i++) + @{ + if (_rl_uppercase_p (rl_line_buffer[i])) + rl_line_buffer[i] = _rl_to_lower (rl_line_buffer[i]); + else if (_rl_lowercase_p (rl_line_buffer[i])) + rl_line_buffer[i] = _rl_to_upper (rl_line_buffer[i]); + @} + /* Move point to on top of the last character changed. */ + rl_point = (direction == 1) ? end - 1 : start; + return (0); +@} +@end example + +@node Alternate Interface Example +@subsection Alternate Interface Example + +Here is a complete program that illustrates Readline's alternate interface. +It reads lines from the terminal and displays them, providing the +standard history and TAB completion functions. +It understands the EOF character or "exit" to exit the program. + +@example +/* Standard include files. stdio.h is required. */ +#include +#include +#include +#include + +/* Used for select(2) */ +#include +#include + +#include + +#include + +/* Standard readline include files. */ +#include +#include + +static void cb_linehandler (char *); +static void sighandler (int); + +int running; +int sigwinch_received; +const char *prompt = "rltest$ "; + +/* Handle SIGWINCH and window size changes when readline is not active and + reading a character. */ +static void +sighandler (int sig) +@{ + sigwinch_received = 1; +@} + +/* Callback function called for each line when accept-line executed, EOF + seen, or EOF character read. This sets a flag and returns; it could + also call exit(3). */ +static void +cb_linehandler (char *line) +@{ + /* Can use ^D (stty eof) or `exit' to exit. */ + if (line == NULL || strcmp (line, "exit") == 0) + @{ + if (line == 0) + printf ("\n"); + printf ("exit\n"); + /* This function needs to be called to reset the terminal settings, + and calling it from the line handler keeps one extra prompt from + being displayed. */ + rl_callback_handler_remove (); + + running = 0; + @} + else + @{ + if (*line) + add_history (line); + printf ("input line: %s\n", line); + free (line); + @} +@} + +int +main (int c, char **v) +@{ + fd_set fds; + int r; + + /* Set the default locale values according to environment variables. */ + setlocale (LC_ALL, ""); + + /* Handle window size changes when readline is not active and reading + characters. */ + signal (SIGWINCH, sighandler); + + /* Install the line handler. */ + rl_callback_handler_install (prompt, cb_linehandler); + + /* Enter a simple event loop. This waits until something is available + to read on readline's input stream (defaults to standard input) and + calls the builtin character read callback to read it. It does not + have to modify the user's terminal settings. */ + running = 1; + while (running) + @{ + FD_ZERO (&fds); + FD_SET (fileno (rl_instream), &fds); + + r = select (FD_SETSIZE, &fds, NULL, NULL, NULL); + if (r < 0 && errno != EINTR) + @{ + perror ("rltest: select"); + rl_callback_handler_remove (); + break; + @} + if (sigwinch_received) + @{ + rl_resize_terminal (); + sigwinch_received = 0; + @} + if (r < 0) + continue; + + if (FD_ISSET (fileno (rl_instream), &fds)) + rl_callback_read_char (); + @} + + printf ("rltest: Event loop has exited\n"); + return 0; +@} +@end example + +@node Readline Signal Handling +@section Readline Signal Handling + +Signals are asynchronous events sent to a process by the Unix kernel, +sometimes on behalf of another process. They are intended to indicate +exceptional events, like a user pressing the interrupt key on his terminal, +or a network connection being broken. There is a class of signals that can +be sent to the process currently reading input from the keyboard. Since +Readline changes the terminal attributes when it is called, it needs to +perform special processing when such a signal is received in order to +restore the terminal to a sane state, or provide application writers with +functions to do so manually. + +Readline contains an internal signal handler that is installed for a +number of signals (@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, +@code{SIGHUP}, +@code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}). +When one of these signals is received, the signal handler +will reset the terminal attributes to those that were in effect before +@code{readline()} was called, reset the signal handling to what it was +before @code{readline()} was called, and resend the signal to the calling +application. +If and when the calling application's signal handler returns, Readline +will reinitialize the terminal and continue to accept input. +When a @code{SIGINT} is received, the Readline signal handler performs +some additional work, which will cause any partially-entered line to be +aborted (see the description of @code{rl_free_line_state()} below). + +There is an additional Readline signal handler, for @code{SIGWINCH}, which +the kernel sends to a process whenever the terminal's size changes (for +example, if a user resizes an @code{xterm}). The Readline @code{SIGWINCH} +handler updates Readline's internal screen size information, and then calls +any @code{SIGWINCH} signal handler the calling application has installed. +Readline calls the application's @code{SIGWINCH} signal handler without +resetting the terminal to its original state. If the application's signal +handler does more than update its idea of the terminal size and return (for +example, a @code{longjmp} back to a main processing loop), it @emph{must} +call @code{rl_cleanup_after_signal()} (described below), to restore the +terminal state. + +When an application is using the callback interface +(@pxref{Alternate Interface}), Readline installs signal handlers only for +the duration of the call to @code{rl_callback_read_char}. Applications +using the callback interface should be prepared to clean up Readline's +state if they wish to handle the signal before the line handler completes +and restores the terminal state. + +If an application using the callback interface wishes to have Readline +install its signal handlers at the time the application calls +@code{rl_callback_handler_install} and remove them only when a complete +line of input has been read, it should set the +@code{rl_persistent_signal_handlers} variable to a non-zero value. +This allows an application to defer all of the handling of the signals +Readline catches to Readline. +Applications should use this variable with care; it can result in Readline +catching signals and not acting on them (or allowing the application to react +to them) until the application calls @code{rl_callback_read_char}. This +can result in an application becoming less responsive to keyboard signals +like SIGINT. +If an application does not want or need to perform any signal handling, or +does not need to do any processing between calls to @code{rl_callback_read_char}, +setting this variable may be desirable. + +Readline provides two variables that allow application writers to +control whether or not it will catch certain signals and act on them +when they are received. It is important that applications change the +values of these variables only when calling @code{readline()}, not in +a signal handler, so Readline's internal signal state is not corrupted. + +@deftypevar int rl_catch_signals +If this variable is non-zero, Readline will install signal handlers for +@code{SIGINT}, @code{SIGQUIT}, @code{SIGTERM}, @code{SIGHUP}, @code{SIGALRM}, +@code{SIGTSTP}, @code{SIGTTIN}, and @code{SIGTTOU}. + +The default value of @code{rl_catch_signals} is 1. +@end deftypevar + +@deftypevar int rl_catch_sigwinch +If this variable is set to a non-zero value, +Readline will install a signal handler for @code{SIGWINCH}. + +The default value of @code{rl_catch_sigwinch} is 1. +@end deftypevar + +@deftypevar int rl_persistent_signal_handlers +If an application using the callback interface wishes Readline's signal +handlers to be installed and active during the set of calls to +@code{rl_callback_read_char} that constitutes an entire single line, +it should set this variable to a non-zero value. + +The default value of @code{rl_persistent_signal_handlers} is 0. +@end deftypevar + +@deftypevar int rl_change_environment +If this variable is set to a non-zero value, +and Readline is handling @code{SIGWINCH}, Readline will modify the +@var{LINES} and @var{COLUMNS} environment variables upon receipt of a +@code{SIGWINCH} + +The default value of @code{rl_change_environment} is 1. +@end deftypevar + +If an application does not wish to have Readline catch any signals, or +to handle signals other than those Readline catches (@code{SIGHUP}, +for example), +Readline provides convenience functions to do the necessary terminal +and internal state cleanup upon receipt of a signal. + +@deftypefun int rl_pending_signal (void) +Return the signal number of the most recent signal Readline received but +has not yet handled, or 0 if there is no pending signal. +@end deftypefun + +@deftypefun void rl_cleanup_after_signal (void) +This function will reset the state of the terminal to what it was before +@code{readline()} was called, and remove the Readline signal handlers for +all signals, depending on the values of @code{rl_catch_signals} and +@code{rl_catch_sigwinch}. +@end deftypefun + +@deftypefun void rl_free_line_state (void) +This will free any partial state associated with the current input line +(undo information, any partial history entry, any partially-entered +keyboard macro, and any partially-entered numeric argument). This +should be called before @code{rl_cleanup_after_signal()}. The +Readline signal handler for @code{SIGINT} calls this to abort the +current input line. +@end deftypefun + +@deftypefun void rl_reset_after_signal (void) +This will reinitialize the terminal and reinstall any Readline signal +handlers, depending on the values of @code{rl_catch_signals} and +@code{rl_catch_sigwinch}. +@end deftypefun + +If an application wants to force Readline to handle any signals that +have arrived while it has been executing, @code{rl_check_signals()} +will call Readline's internal signal handler if there are any pending +signals. This is primarily intended for those applications that use +a custom @code{rl_getc_function} (@pxref{Readline Variables}) and wish +to handle signals received while waiting for input. + +@deftypefun void rl_check_signals (void) +If there are any pending signals, call Readline's internal signal handling +functions to process them. @code{rl_pending_signal()} can be used independently +to determine whether or not there are any pending signals. +@end deftypefun + +If an application does not wish Readline to catch @code{SIGWINCH}, it may +call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force +Readline to update its idea of the terminal size when it receives +a @code{SIGWINCH}. + +@deftypefun void rl_echo_signal_char (int sig) +If an application wishes to install its own signal handlers, but still +have readline display characters that generate signals, calling this +function with @var{sig} set to @code{SIGINT}, @code{SIGQUIT}, or +@code{SIGTSTP} will display the character generating that signal. +@end deftypefun + +@deftypefun void rl_resize_terminal (void) +Update Readline's internal screen size by reading values from the kernel. +@end deftypefun + +@deftypefun void rl_set_screen_size (int rows, int cols) +Set Readline's idea of the terminal size to @var{rows} rows and +@var{cols} columns. If either @var{rows} or @var{columns} is less than +or equal to 0, Readline's idea of that terminal dimension is unchanged. +This is intended to tell Readline the physical dimensions of the terminal, +and is used internally to calculate the maximum number of characters that +may appear on a single line and on the screen. +@end deftypefun + +If an application does not want to install a @code{SIGWINCH} handler, but +is still interested in the screen dimensions, it may query Readline's idea +of the screen size. + +@deftypefun void rl_get_screen_size (int *rows, int *cols) +Return Readline's idea of the terminal's size in the +variables pointed to by the arguments. +@end deftypefun + +@deftypefun void rl_reset_screen_size (void) +Cause Readline to reobtain the screen size and recalculate its dimensions. +@end deftypefun + +The following functions install and remove Readline's signal handlers. + +@deftypefun int rl_set_signals (void) +Install Readline's signal handler for @code{SIGINT}, @code{SIGQUIT}, +@code{SIGTERM}, @code{SIGHUP}, @code{SIGALRM}, @code{SIGTSTP}, @code{SIGTTIN}, +@code{SIGTTOU}, and @code{SIGWINCH}, depending on the values of +@code{rl_catch_signals} and @code{rl_catch_sigwinch}. +@end deftypefun + +@deftypefun int rl_clear_signals (void) +Remove all of the Readline signal handlers installed by +@code{rl_set_signals()}. +@end deftypefun + +@node Custom Completers +@section Custom Completers +@cindex application-specific completion functions + +Typically, a program that reads commands from the user has a way of +disambiguating commands and data. If your program is one of these, then +it can provide completion for commands, data, or both. +The following sections describe how your program and Readline +cooperate to provide this service. + +@menu +* How Completing Works:: The logic used to do completion. +* Completion Functions:: Functions provided by Readline. +* Completion Variables:: Variables which control completion. +* A Short Completion Example:: An example of writing completer subroutines. +@end menu + +@node How Completing Works +@subsection How Completing Works + +In order to complete some text, the full list of possible completions +must be available. That is, it is not possible to accurately +expand a partial word without knowing all of the possible words +which make sense in that context. The Readline library provides +the user interface to completion, and two of the most common +completion functions: filename and username. For completing other types +of text, you must write your own completion function. This section +describes exactly what such functions must do, and provides an example. + +There are three major functions used to perform completion: + +@enumerate +@item +The user-interface function @code{rl_complete()}. This function is +called with the same arguments as other bindable Readline functions: +@var{count} and @var{invoking_key}. +It isolates the word to be completed and calls +@code{rl_completion_matches()} to generate a list of possible completions. +It then either lists the possible completions, inserts the possible +completions, or actually performs the +completion, depending on which behavior is desired. + +@item +The internal function @code{rl_completion_matches()} uses an +application-supplied @dfn{generator} function to generate the list of +possible matches, and then returns the array of these matches. +The caller should place the address of its generator function in +@code{rl_completion_entry_function}. + +@item +The generator function is called repeatedly from +@code{rl_completion_matches()}, returning a string each time. The +arguments to the generator function are @var{text} and @var{state}. +@var{text} is the partial word to be completed. @var{state} is zero the +first time the function is called, allowing the generator to perform +any necessary initialization, and a positive non-zero integer for +each subsequent call. The generator function returns +@code{(char *)NULL} to inform @code{rl_completion_matches()} that there are +no more possibilities left. Usually the generator function computes the +list of possible completions when @var{state} is zero, and returns them +one at a time on subsequent calls. Each string the generator function +returns as a match must be allocated with @code{malloc()}; Readline +frees the strings when it has finished with them. +Such a generator function is referred to as an +@dfn{application-specific completion function}. + +@end enumerate + +@deftypefun int rl_complete (int ignore, int invoking_key) +Complete the word at or before point. You have supplied the function +that does the initial simple matching selection algorithm (see +@code{rl_completion_matches()}). The default is to do filename completion. +@end deftypefun + +@deftypevar {rl_compentry_func_t *} rl_completion_entry_function +This is a pointer to the generator function for +@code{rl_completion_matches()}. +If the value of @code{rl_completion_entry_function} is +@code{NULL} then the default filename generator +function, @code{rl_filename_completion_function()}, is used. +An @dfn{application-specific completion function} is a function whose +address is assigned to @code{rl_completion_entry_function} and whose +return values are used to generate possible completions. +@end deftypevar + +@node Completion Functions +@subsection Completion Functions + +Here is the complete list of callable completion functions present in +Readline. + +@deftypefun int rl_complete_internal (int what_to_do) +Complete the word at or before point. @var{what_to_do} says what to do +with the completion. A value of @samp{?} means list the possible +completions. @samp{TAB} means do standard completion. @samp{*} means +insert all of the possible completions. @samp{!} means to display +all of the possible completions, if there is more than one, as well as +performing partial completion. @samp{@@} is similar to @samp{!}, but +possible completions are not listed if the possible completions share +a common prefix. +@end deftypefun + +@deftypefun int rl_complete (int ignore, int invoking_key) +Complete the word at or before point. You have supplied the function +that does the initial simple matching selection algorithm (see +@code{rl_completion_matches()} and @code{rl_completion_entry_function}). +The default is to do filename +completion. This calls @code{rl_complete_internal()} with an +argument depending on @var{invoking_key}. +@end deftypefun + +@deftypefun int rl_possible_completions (int count, int invoking_key) +List the possible completions. See description of @code{rl_complete +()}. This calls @code{rl_complete_internal()} with an argument of +@samp{?}. +@end deftypefun + +@deftypefun int rl_insert_completions (int count, int invoking_key) +Insert the list of possible completions into the line, deleting the +partially-completed word. See description of @code{rl_complete()}. +This calls @code{rl_complete_internal()} with an argument of @samp{*}. +@end deftypefun + +@deftypefun int rl_completion_mode (rl_command_func_t *cfunc) +Returns the appropriate value to pass to @code{rl_complete_internal()} +depending on whether @var{cfunc} was called twice in succession and +the values of the @code{show-all-if-ambiguous} and +@code{show-all-if-unmodified} variables. +Application-specific completion functions may use this function to present +the same interface as @code{rl_complete()}. +@end deftypefun + +@deftypefun {char **} rl_completion_matches (const char *text, rl_compentry_func_t *entry_func) +Returns an array of strings which is a list of completions for +@var{text}. If there are no completions, returns @code{NULL}. +The first entry in the returned array is the substitution for @var{text}. +The remaining entries are the possible completions. The array is +terminated with a @code{NULL} pointer. + +@var{entry_func} is a function of two args, and returns a +@code{char *}. The first argument is @var{text}. The second is a +state argument; it is zero on the first call, and non-zero on subsequent +calls. @var{entry_func} returns a @code{NULL} pointer to the caller +when there are no more matches. +@end deftypefun + +@deftypefun {char *} rl_filename_completion_function (const char *text, int state) +A generator function for filename completion in the general case. +@var{text} is a partial filename. +The Bash source is a useful reference for writing application-specific +completion functions (the Bash completion functions call this and other +Readline functions). +@end deftypefun + +@deftypefun {char *} rl_username_completion_function (const char *text, int state) +A completion generator for usernames. @var{text} contains a partial +username preceded by a random character (usually @samp{~}). As with all +completion generators, @var{state} is zero on the first call and non-zero +for subsequent calls. +@end deftypefun + +@node Completion Variables +@subsection Completion Variables + +@deftypevar {rl_compentry_func_t *} rl_completion_entry_function +A pointer to the generator function for @code{rl_completion_matches()}. +@code{NULL} means to use @code{rl_filename_completion_function()}, +the default filename completer. +@end deftypevar + +@deftypevar {rl_completion_func_t *} rl_attempted_completion_function +A pointer to an alternative function to create matches. +The function is called with @var{text}, @var{start}, and @var{end}. +@var{start} and @var{end} are indices in @code{rl_line_buffer} defining +the boundaries of @var{text}, which is a character string. +If this function exists and returns @code{NULL}, or if this variable is +set to @code{NULL}, then @code{rl_complete()} will call the value of +@code{rl_completion_entry_function} to generate matches, otherwise the +array of strings returned will be used. +If this function sets the @code{rl_attempted_completion_over} +variable to a non-zero value, Readline will not perform its default +completion even if this function returns no matches. +@end deftypevar + +@deftypevar {rl_quote_func_t *} rl_filename_quoting_function +A pointer to a function that will quote a filename in an +application-specific fashion. This is called if filename completion is being +attempted and one of the characters in @code{rl_filename_quote_characters} +appears in a completed filename. The function is called with +@var{text}, @var{match_type}, and @var{quote_pointer}. The @var{text} +is the filename to be quoted. The @var{match_type} is either +@code{SINGLE_MATCH}, if there is only one completion match, or +@code{MULT_MATCH}. Some functions use this to decide whether or not to +insert a closing quote character. The @var{quote_pointer} is a pointer +to any opening quote character the user typed. Some functions choose +to reset this character. +@end deftypevar + +@deftypevar {rl_dequote_func_t *} rl_filename_dequoting_function +A pointer to a function that will remove application-specific quoting +characters from a filename before completion is attempted, so those +characters do not interfere with matching the text against names in +the filesystem. It is called with @var{text}, the text of the word +to be dequoted, and @var{quote_char}, which is the quoting character +that delimits the filename (usually @samp{'} or @samp{"}). If +@var{quote_char} is zero, the filename was not in an embedded string. +@end deftypevar + +@deftypevar {rl_linebuf_func_t *} rl_char_is_quoted_p +A pointer to a function to call that determines whether or not a specific +character in the line buffer is quoted, according to whatever quoting +mechanism the program calling Readline uses. The function is called with +two arguments: @var{text}, the text of the line, and @var{index}, the +index of the character in the line. It is used to decide whether a +character found in @code{rl_completer_word_break_characters} should be +used to break words for the completer. +@end deftypevar + +@deftypevar {rl_compignore_func_t *} rl_ignore_some_completions_function +This function, if defined, is called by the completer when real filename +completion is done, after all the matching names have been generated. +It is passed a @code{NULL} terminated array of matches. +The first element (@code{matches[0]}) is the +maximal substring common to all matches. This function can +re-arrange the list of matches as required, but each element deleted +from the array must be freed. +@end deftypevar + +@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook +This function, if defined, is allowed to modify the directory portion +of filenames Readline completes. +It could be used to expand symbolic links or shell variables in pathnames. +It is called with the address of a string (the current directory name) as an +argument, and may modify that string. +If the string is replaced with a new string, the old value should be freed. +Any modified directory name should have a trailing slash. +The modified value will be used as part of the completion, replacing +the directory portion of the pathname the user typed. +At the least, even if no other expansion is performed, this function should +remove any quote characters from the directory name, because its result will +be passed directly to @code{opendir()}. + +The directory completion hook returns an integer that should be non-zero if +the function modifies its directory argument. +The function should not modify the directory argument if it returns 0. +@end deftypevar + +@deftypevar {rl_icppfunc_t *} rl_directory_rewrite_hook; +If non-zero, this is the address of a function to call when completing +a directory name. This function takes the address of the directory name +to be modified as an argument. Unlike @code{rl_directory_completion_hook}, +it only modifies the directory name used in @code{opendir}, not what is +displayed when the possible completions are printed or inserted. It is +called before rl_directory_completion_hook. +At the least, even if no other expansion is performed, this function should +remove any quote characters from the directory name, because its result will +be passed directly to @code{opendir()}. + +The directory rewrite hook returns an integer that should be non-zero if +the function modifies its directory argument. +The function should not modify the directory argument if it returns 0. +@end deftypevar + +@deftypevar {rl_icppfunc_t *} rl_filename_stat_hook +If non-zero, this is the address of a function for the completer to +call before deciding which character to append to a completed name. +This function modifies its filename name argument, and the modified value +is passed to @code{stat()} to determine the file's type and characteristics. +This function does not need to remove quote characters from the filename. + +The stat hook returns an integer that should be non-zero if +the function modifies its directory argument. +The function should not modify the directory argument if it returns 0. +@end deftypevar + +@deftypevar {rl_dequote_func_t *} rl_filename_rewrite_hook +If non-zero, this is the address of a function called when reading +directory entries from the filesystem for completion and comparing +them to the partial word to be completed. The function should +perform any necessary application or system-specific conversion on +the filename, such as converting between character sets or converting +from a filesystem format to a character input format. +The function takes two arguments: @var{fname}, the filename to be converted, +and @var{fnlen}, its length in bytes. +It must either return its first argument (if no conversion takes place) +or the converted filename in newly-allocated memory. The converted +form is used to compare against the word to be completed, and, if it +matches, is added to the list of matches. Readline will free the +allocated string. +@end deftypevar + +@deftypevar {rl_compdisp_func_t *} rl_completion_display_matches_hook +If non-zero, then this is the address of a function to call when +completing a word would normally display the list of possible matches. +This function is called in lieu of Readline displaying the list. +It takes three arguments: +(@code{char **}@var{matches}, @code{int} @var{num_matches}, @code{int} @var{max_length}) +where @var{matches} is the array of matching strings, +@var{num_matches} is the number of strings in that array, and +@var{max_length} is the length of the longest string in that array. +Readline provides a convenience function, @code{rl_display_match_list}, +that takes care of doing the display to Readline's output stream. +You may call that function from this hook. +@end deftypevar + +@deftypevar {const char *} rl_basic_word_break_characters +The basic list of characters that signal a break between words for the +completer routine. The default value of this variable is the characters +which break words for completion in Bash: +@code{" \t\n\"\\'`@@$><=;|&@{("}. +@end deftypevar + +@deftypevar {const char *} rl_basic_quote_characters +A list of quote characters which can cause a word break. +@end deftypevar + +@deftypevar {const char *} rl_completer_word_break_characters +The list of characters that signal a break between words for +@code{rl_complete_internal()}. The default list is the value of +@code{rl_basic_word_break_characters}. +@end deftypevar + +@deftypevar {rl_cpvfunc_t *} rl_completion_word_break_hook +If non-zero, this is the address of a function to call when Readline is +deciding where to separate words for word completion. It should return +a character string like @code{rl_completer_word_break_characters} to be +used to perform the current completion. The function may choose to set +@code{rl_completer_word_break_characters} itself. If the function +returns @code{NULL}, @code{rl_completer_word_break_characters} is used. +@end deftypevar + +@deftypevar {const char *} rl_completer_quote_characters +A list of characters which can be used to quote a substring of the line. +Completion occurs on the entire substring, and within the substring +@code{rl_completer_word_break_characters} are treated as any other character, +unless they also appear within this list. +@end deftypevar + +@deftypevar {const char *} rl_filename_quote_characters +A list of characters that cause a filename to be quoted by the completer +when they appear in a completed filename. The default is the null string. +@end deftypevar + +@deftypevar {const char *} rl_special_prefixes +The list of characters that are word break characters, but should be +left in @var{text} when it is passed to the completion function. +Programs can use this to help determine what kind of completing to do. +For instance, Bash sets this variable to "$@@" so that it can complete +shell variables and hostnames. +@end deftypevar + +@deftypevar int rl_completion_query_items +Up to this many items will be displayed in response to a +possible-completions call. After that, readline asks the user if she is sure +she wants to see them all. The default value is 100. A negative value +indicates that Readline should never ask the user. +@end deftypevar + +@deftypevar {int} rl_completion_append_character +When a single completion alternative matches at the end of the command +line, this character is appended to the inserted completion text. The +default is a space character (@samp{ }). Setting this to the null +character (@samp{\0}) prevents anything being appended automatically. +This can be changed in application-specific completion functions to +provide the ``most sensible word separator character'' according to +an application-specific command line syntax specification. +It is set to the default before any application-specific completion function +is called, and may only be changed within such a function. +@end deftypevar + +@deftypevar int rl_completion_suppress_append +If non-zero, @var{rl_completion_append_character} is not appended to +matches at the end of the command line, as described above. +It is set to 0 before any application-specific completion function +is called, and may only be changed within such a function. +@end deftypevar + +@deftypevar int rl_completion_quote_character +When Readline is completing quoted text, as delimited by one of the +characters in @var{rl_completer_quote_characters}, it sets this variable +to the quoting character found. +This is set before any application-specific completion function is called. +@end deftypevar + +@deftypevar int rl_completion_suppress_quote +If non-zero, Readline does not append a matching quote character when +performing completion on a quoted string. +It is set to 0 before any application-specific completion function +is called, and may only be changed within such a function. +@end deftypevar + +@deftypevar int rl_completion_found_quote +When Readline is completing quoted text, it sets this variable +to a non-zero value if the word being completed contains or is delimited +by any quoting characters, including backslashes. +This is set before any application-specific completion function is called. +@end deftypevar + +@deftypevar int rl_completion_mark_symlink_dirs +If non-zero, a slash will be appended to completed filenames that are +symbolic links to directory names, subject to the value of the +user-settable @var{mark-directories} variable. +This variable exists so that application-specific completion functions +can override the user's global preference (set via the +@var{mark-symlinked-directories} Readline variable) if appropriate. +This variable is set to the user's preference before any +application-specific completion function is called, so unless that +function modifies the value, the user's preferences are honored. +@end deftypevar + +@deftypevar int rl_ignore_completion_duplicates +If non-zero, then duplicates in the matches are removed. +The default is 1. +@end deftypevar + +@deftypevar int rl_filename_completion_desired +Non-zero means that the results of the matches are to be treated as +filenames. This is @emph{always} zero when completion is attempted, +and can only be changed +within an application-specific completion function. If it is set to a +non-zero value by such a function, directory names have a slash appended +and Readline attempts to quote completed filenames if they contain any +characters in @code{rl_filename_quote_characters} and +@code{rl_filename_quoting_desired} is set to a non-zero value. +@end deftypevar + +@deftypevar int rl_filename_quoting_desired +Non-zero means that the results of the matches are to be quoted using +double quotes (or an application-specific quoting mechanism) if the +completed filename contains any characters in +@code{rl_filename_quote_chars}. This is @emph{always} non-zero +when completion is attempted, and can only be changed within an +application-specific completion function. +The quoting is effected via a call to the function pointed to +by @code{rl_filename_quoting_function}. +@end deftypevar + +@deftypevar int rl_attempted_completion_over +If an application-specific completion function assigned to +@code{rl_attempted_completion_function} sets this variable to a non-zero +value, Readline will not perform its default filename completion even +if the application's completion function returns no matches. +It should be set only by an application's completion function. +@end deftypevar + +@deftypevar int rl_sort_completion_matches +If an application sets this variable to 0, Readline will not sort the +list of completions (which implies that it cannot remove any duplicate +completions). The default value is 1, which means that Readline will +sort the completions and, depending on the value of +@code{rl_ignore_completion_duplicates}, will attempt to remove duplicate +matches. +@end deftypevar + +@deftypevar int rl_completion_type +Set to a character describing the type of completion Readline is currently +attempting; see the description of @code{rl_complete_internal()} +(@pxref{Completion Functions}) for the list of characters. +This is set to the appropriate value before any application-specific +completion function is called, allowing such functions to present +the same interface as @code{rl_complete()}. +@end deftypevar + +@deftypevar int rl_completion_invoking_key +Set to the final character in the key sequence that invoked one of the +completion functions that call @code{rl_complete_internal()}. This is +set to the appropriate value before any application-specific completion +function is called. +@end deftypevar + +@deftypevar int rl_inhibit_completion +If this variable is non-zero, completion is inhibited. The completion +character will be inserted as any other bound to @code{self-insert}. +@end deftypevar + +@node A Short Completion Example +@subsection A Short Completion Example + +Here is a small application demonstrating the use of the GNU Readline +library. It is called @code{fileman}, and the source code resides in +@file{examples/fileman.c}. This sample application provides +completion of command names, line editing features, and access to the +history list. + +@page +@smallexample +/* fileman.c -- A tiny application which demonstrates how to use the + GNU Readline library. This application interactively allows users + to manipulate files and their modes. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#ifdef HAVE_SYS_FILE_H +# include +#endif +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#ifdef HAVE_STDLIB_H +# include +#endif + +#include + +#include +#include + +extern char *xmalloc PARAMS((size_t)); + +/* The names of functions that actually do the manipulation. */ +int com_list PARAMS((char *)); +int com_view PARAMS((char *)); +int com_rename PARAMS((char *)); +int com_stat PARAMS((char *)); +int com_pwd PARAMS((char *)); +int com_delete PARAMS((char *)); +int com_help PARAMS((char *)); +int com_cd PARAMS((char *)); +int com_quit PARAMS((char *)); + +/* A structure which contains information on the commands this program + can understand. */ + +typedef struct @{ + char *name; /* User printable name of the function. */ + rl_icpfunc_t *func; /* Function to call to do the job. */ + char *doc; /* Documentation for this function. */ +@} COMMAND; + +COMMAND commands[] = @{ + @{ "cd", com_cd, "Change to directory DIR" @}, + @{ "delete", com_delete, "Delete FILE" @}, + @{ "help", com_help, "Display this text" @}, + @{ "?", com_help, "Synonym for `help'" @}, + @{ "list", com_list, "List files in DIR" @}, + @{ "ls", com_list, "Synonym for `list'" @}, + @{ "pwd", com_pwd, "Print the current working directory" @}, + @{ "quit", com_quit, "Quit using Fileman" @}, + @{ "rename", com_rename, "Rename FILE to NEWNAME" @}, + @{ "stat", com_stat, "Print out statistics on FILE" @}, + @{ "view", com_view, "View the contents of FILE" @}, + @{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL @} +@}; + +/* Forward declarations. */ +char *stripwhite (); +COMMAND *find_command (); + +/* The name of this program, as taken from argv[0]. */ +char *progname; + +/* When non-zero, this global means the user is done using this program. */ +int done; + +char * +dupstr (s) + char *s; +@{ + char *r; + + r = xmalloc (strlen (s) + 1); + strcpy (r, s); + return (r); +@} + +main (argc, argv) + int argc; + char **argv; +@{ + char *line, *s; + + progname = argv[0]; + + initialize_readline (); /* Bind our completer. */ + + /* Loop reading and executing lines until the user quits. */ + for ( ; done == 0; ) + @{ + line = readline ("FileMan: "); + + if (!line) + break; + + /* Remove leading and trailing whitespace from the line. + Then, if there is anything left, add it to the history list + and execute it. */ + s = stripwhite (line); + + if (*s) + @{ + add_history (s); + execute_line (s); + @} + + free (line); + @} + exit (0); +@} + +/* Execute a command line. */ +int +execute_line (line) + char *line; +@{ + register int i; + COMMAND *command; + char *word; + + /* Isolate the command word. */ + i = 0; + while (line[i] && whitespace (line[i])) + i++; + word = line + i; + + while (line[i] && !whitespace (line[i])) + i++; + + if (line[i]) + line[i++] = '\0'; + + command = find_command (word); + + if (!command) + @{ + fprintf (stderr, "%s: No such command for FileMan.\n", word); + return (-1); + @} + + /* Get argument to command, if any. */ + while (whitespace (line[i])) + i++; + + word = line + i; + + /* Call the function. */ + return ((*(command->func)) (word)); +@} + +/* Look up NAME as the name of a command, and return a pointer to that + command. Return a NULL pointer if NAME isn't a command name. */ +COMMAND * +find_command (name) + char *name; +@{ + register int i; + + for (i = 0; commands[i].name; i++) + if (strcmp (name, commands[i].name) == 0) + return (&commands[i]); + + return ((COMMAND *)NULL); +@} + +/* Strip whitespace from the start and end of STRING. Return a pointer + into STRING. */ +char * +stripwhite (string) + char *string; +@{ + register char *s, *t; + + for (s = string; whitespace (*s); s++) + ; + + if (*s == 0) + return (s); + + t = s + strlen (s) - 1; + while (t > s && whitespace (*t)) + t--; + *++t = '\0'; + + return s; +@} + +/* **************************************************************** */ +/* */ +/* Interface to Readline Completion */ +/* */ +/* **************************************************************** */ + +char *command_generator PARAMS((const char *, int)); +char **fileman_completion PARAMS((const char *, int, int)); + +/* Tell the GNU Readline library how to complete. We want to try to complete + on command names if this is the first word in the line, or on filenames + if not. */ +initialize_readline () +@{ + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "FileMan"; + + /* Tell the completer that we want a crack first. */ + rl_attempted_completion_function = fileman_completion; +@} + +/* Attempt to complete on the contents of TEXT. START and END bound the + region of rl_line_buffer that contains the word to complete. TEXT is + the word to complete. We can use the entire contents of rl_line_buffer + in case we want to do some simple parsing. Return the array of matches, + or NULL if there aren't any. */ +char ** +fileman_completion (text, start, end) + const char *text; + int start, end; +@{ + char **matches; + + matches = (char **)NULL; + + /* If this word is at the start of the line, then it is a command + to complete. Otherwise it is the name of a file in the current + directory. */ + if (start == 0) + matches = rl_completion_matches (text, command_generator); + + return (matches); +@} + +/* Generator function for command completion. STATE lets us know whether + to start from scratch; without any state (i.e. STATE == 0), then we + start at the top of the list. */ +char * +command_generator (text, state) + const char *text; + int state; +@{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + @{ + list_index = 0; + len = strlen (text); + @} + + /* Return the next name which partially matches from the command list. */ + while (name = commands[list_index].name) + @{ + list_index++; + + if (strncmp (name, text, len) == 0) + return (dupstr(name)); + @} + + /* If no names matched, then return NULL. */ + return ((char *)NULL); +@} + +/* **************************************************************** */ +/* */ +/* FileMan Commands */ +/* */ +/* **************************************************************** */ + +/* String to pass to system (). This is for the LIST, VIEW and RENAME + commands. */ +static char syscom[1024]; + +/* List the file(s) named in arg. */ +com_list (arg) + char *arg; +@{ + if (!arg) + arg = ""; + + sprintf (syscom, "ls -FClg %s", arg); + return (system (syscom)); +@} + +com_view (arg) + char *arg; +@{ + if (!valid_argument ("view", arg)) + return 1; + +#if defined (__MSDOS__) + /* more.com doesn't grok slashes in pathnames */ + sprintf (syscom, "less %s", arg); +#else + sprintf (syscom, "more %s", arg); +#endif + return (system (syscom)); +@} + +com_rename (arg) + char *arg; +@{ + too_dangerous ("rename"); + return (1); +@} + +com_stat (arg) + char *arg; +@{ + struct stat finfo; + + if (!valid_argument ("stat", arg)) + return (1); + + if (stat (arg, &finfo) == -1) + @{ + perror (arg); + return (1); + @} + + printf ("Statistics for `%s':\n", arg); + + printf ("%s has %d link%s, and is %d byte%s in length.\n", + arg, + finfo.st_nlink, + (finfo.st_nlink == 1) ? "" : "s", + finfo.st_size, + (finfo.st_size == 1) ? "" : "s"); + printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); + printf (" Last access at: %s", ctime (&finfo.st_atime)); + printf (" Last modified at: %s", ctime (&finfo.st_mtime)); + return (0); +@} + +com_delete (arg) + char *arg; +@{ + too_dangerous ("delete"); + return (1); +@} + +/* Print out help for ARG, or for all of the commands if ARG is + not present. */ +com_help (arg) + char *arg; +@{ + register int i; + int printed = 0; + + for (i = 0; commands[i].name; i++) + @{ + if (!*arg || (strcmp (arg, commands[i].name) == 0)) + @{ + printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); + printed++; + @} + @} + + if (!printed) + @{ + printf ("No commands match `%s'. Possibilities are:\n", arg); + + for (i = 0; commands[i].name; i++) + @{ + /* Print in six columns. */ + if (printed == 6) + @{ + printed = 0; + printf ("\n"); + @} + + printf ("%s\t", commands[i].name); + printed++; + @} + + if (printed) + printf ("\n"); + @} + return (0); +@} + +/* Change to the directory ARG. */ +com_cd (arg) + char *arg; +@{ + if (chdir (arg) == -1) + @{ + perror (arg); + return 1; + @} + + com_pwd (""); + return (0); +@} + +/* Print out the current working directory. */ +com_pwd (ignore) + char *ignore; +@{ + char dir[1024], *s; + + s = getcwd (dir, sizeof(dir) - 1); + if (s == 0) + @{ + printf ("Error getting pwd: %s\n", dir); + return 1; + @} + + printf ("Current directory is %s\n", dir); + return 0; +@} + +/* The user wishes to quit using this program. Just set DONE non-zero. */ +com_quit (arg) + char *arg; +@{ + done = 1; + return (0); +@} + +/* Function which tells you that you can't do this. */ +too_dangerous (caller) + char *caller; +@{ + fprintf (stderr, + "%s: Too dangerous for me to distribute. Write it yourself.\n", + caller); +@} + +/* Return non-zero if ARG is a valid argument for CALLER, else print + an error message and return zero. */ +int +valid_argument (caller, arg) + char *caller, *arg; +@{ + if (!arg || !*arg) + @{ + fprintf (stderr, "%s: Argument required.\n", caller); + return (0); + @} + + return (1); +@} +@end smallexample diff --git a/utshell-0.5.0/lib/readline/doc/rluser.texi b/utshell-0.5.0/lib/readline/doc/rluser.texi new file mode 100644 index 00000000..26b0ff07 --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/rluser.texi @@ -0,0 +1,2422 @@ +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename rluser.info +@comment %**end of header (This is for running Texinfo on a region.) + +@ignore +This file documents the end user interface to the GNU command line +editing features. It is to be an appendix to manuals for programs which +use these features. There is a document entitled "readline.texinfo" +which contains both end-user and programmer documentation for the +GNU Readline Library. + +Copyright (C) 1988--2020 Free Software Foundation, Inc. + +Authored by Brian Fox and Chet Ramey. + +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission notice +identical to this one except for the removal of this paragraph (this +paragraph not being relevant to the printed manual). + +Permission is granted to make and distribute verbatim copies of this manual +provided the copyright notice and this permission notice are preserved on +all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +GNU Copyright statement is available to the distributee, and provided that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end ignore + +@comment If you are including this manual as an appendix, then set the +@comment variable readline-appendix. + +@ifclear BashFeatures +@defcodeindex bt +@end ifclear + +@node Command Line Editing +@chapter Command Line Editing + +This chapter describes the basic features of the @sc{gnu} +command line editing interface. +@ifset BashFeatures +Command line editing is provided by the Readline library, which is +used by several different programs, including Bash. +Command line editing is enabled by default when using an interactive shell, +unless the @option{--noediting} option is supplied at shell invocation. +Line editing is also used when using the @option{-e} option to the +@code{read} builtin command (@pxref{Bash Builtins}). +By default, the line editing commands are similar to those of Emacs. +A vi-style line editing interface is also available. +Line editing can be enabled at any time using the @option{-o emacs} or +@option{-o vi} options to the @code{set} builtin command +(@pxref{The Set Builtin}), or disabled using the @option{+o emacs} or +@option{+o vi} options to @code{set}. +@end ifset + +@menu +* Introduction and Notation:: Notation used in this text. +* Readline Interaction:: The minimum set of commands for editing a line. +* Readline Init File:: Customizing Readline from a user's view. +* Bindable Readline Commands:: A description of most of the Readline commands + available for binding +* Readline vi Mode:: A short description of how to make Readline + behave like the vi editor. +@ifset BashFeatures +* Programmable Completion:: How to specify the possible completions for + a specific command. +* Programmable Completion Builtins:: Builtin commands to specify how to + complete arguments for a particular command. +* A Programmable Completion Example:: An example shell function for + generating possible completions. +@end ifset +@end menu + +@node Introduction and Notation +@section Introduction to Line Editing + +The following paragraphs describe the notation used to represent +keystrokes. + +The text @kbd{C-k} is read as `Control-K' and describes the character +produced when the @key{k} key is pressed while the Control key +is depressed. + +The text @kbd{M-k} is read as `Meta-K' and describes the character +produced when the Meta key (if you have one) is depressed, and the @key{k} +key is pressed. +The Meta key is labeled @key{ALT} on many keyboards. +On keyboards with two keys labeled @key{ALT} (usually to either side of +the space bar), the @key{ALT} on the left side is generally set to +work as a Meta key. +The @key{ALT} key on the right may also be configured to work as a +Meta key or may be configured as some other modifier, such as a +Compose key for typing accented characters. + +If you do not have a Meta or @key{ALT} key, or another key working as +a Meta key, the identical keystroke can be generated by typing @key{ESC} +@emph{first}, and then typing @key{k}. +Either process is known as @dfn{metafying} the @key{k} key. + +The text @kbd{M-C-k} is read as `Meta-Control-k' and describes the +character produced by @dfn{metafying} @kbd{C-k}. + +In addition, several keys have their own names. Specifically, +@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all +stand for themselves when seen in this text, or in an init file +(@pxref{Readline Init File}). +If your keyboard lacks a @key{LFD} key, typing @key{C-j} will +produce the desired character. +The @key{RET} key may be labeled @key{Return} or @key{Enter} on +some keyboards. + +@node Readline Interaction +@section Readline Interaction +@cindex interaction, readline + +Often during an interactive session you type in a long line of text, +only to notice that the first word on the line is misspelled. The +Readline library gives you a set of commands for manipulating the text +as you type it in, allowing you to just fix your typo, and not forcing +you to retype the majority of the line. Using these editing commands, +you move the cursor to the place that needs correction, and delete or +insert the text of the corrections. Then, when you are satisfied with +the line, you simply press @key{RET}. You do not have to be at the +end of the line to press @key{RET}; the entire line is accepted +regardless of the location of the cursor within the line. + +@menu +* Readline Bare Essentials:: The least you need to know about Readline. +* Readline Movement Commands:: Moving about the input line. +* Readline Killing Commands:: How to delete text, and how to get it back! +* Readline Arguments:: Giving numeric arguments to commands. +* Searching:: Searching through previous lines. +@end menu + +@node Readline Bare Essentials +@subsection Readline Bare Essentials +@cindex notation, readline +@cindex command editing +@cindex editing command lines + +In order to enter characters into the line, simply type them. The typed +character appears where the cursor was, and then the cursor moves one +space to the right. If you mistype a character, you can use your +erase character to back up and delete the mistyped character. + +Sometimes you may mistype a character, and +not notice the error until you have typed several other characters. In +that case, you can type @kbd{C-b} to move the cursor to the left, and then +correct your mistake. Afterwards, you can move the cursor to the right +with @kbd{C-f}. + +When you add text in the middle of a line, you will notice that characters +to the right of the cursor are `pushed over' to make room for the text +that you have inserted. Likewise, when you delete text behind the cursor, +characters to the right of the cursor are `pulled back' to fill in the +blank space created by the removal of the text. A list of the bare +essentials for editing the text of an input line follows. + +@table @asis +@item @kbd{C-b} +Move back one character. +@item @kbd{C-f} +Move forward one character. +@item @key{DEL} or @key{Backspace} +Delete the character to the left of the cursor. +@item @kbd{C-d} +Delete the character underneath the cursor. +@item @w{Printing characters} +Insert the character into the line at the cursor. +@item @kbd{C-_} or @kbd{C-x C-u} +Undo the last editing command. You can undo all the way back to an +empty line. +@end table + +@noindent +(Depending on your configuration, the @key{Backspace} key be set to +delete the character to the left of the cursor and the @key{DEL} key set +to delete the character underneath the cursor, like @kbd{C-d}, rather +than the character to the left of the cursor.) + +@node Readline Movement Commands +@subsection Readline Movement Commands + + +The above table describes the most basic keystrokes that you need +in order to do editing of the input line. For your convenience, many +other commands have been added in addition to @kbd{C-b}, @kbd{C-f}, +@kbd{C-d}, and @key{DEL}. Here are some commands for moving more rapidly +about the line. + +@table @kbd +@item C-a +Move to the start of the line. +@item C-e +Move to the end of the line. +@item M-f +Move forward a word, where a word is composed of letters and digits. +@item M-b +Move backward a word. +@item C-l +Clear the screen, reprinting the current line at the top. +@end table + +Notice how @kbd{C-f} moves forward a character, while @kbd{M-f} moves +forward a word. It is a loose convention that control keystrokes +operate on characters while meta keystrokes operate on words. + +@node Readline Killing Commands +@subsection Readline Killing Commands + +@cindex killing text +@cindex yanking text + +@dfn{Killing} text means to delete the text from the line, but to save +it away for later use, usually by @dfn{yanking} (re-inserting) +it back into the line. +(`Cut' and `paste' are more recent jargon for `kill' and `yank'.) + +If the description for a command says that it `kills' text, then you can +be sure that you can get the text back in a different (or the same) +place later. + +When you use a kill command, the text is saved in a @dfn{kill-ring}. +Any number of consecutive kills save all of the killed text together, so +that when you yank it back, you get it all. The kill +ring is not line specific; the text that you killed on a previously +typed line is available to be yanked back later, when you are typing +another line. +@cindex kill ring + +Here is the list of commands for killing text. + +@table @kbd +@item C-k +Kill the text from the current cursor position to the end of the line. + +@item M-d +Kill from the cursor to the end of the current word, or, if between +words, to the end of the next word. +Word boundaries are the same as those used by @kbd{M-f}. + +@item M-@key{DEL} +Kill from the cursor the start of the current word, or, if between +words, to the start of the previous word. +Word boundaries are the same as those used by @kbd{M-b}. + +@item C-w +Kill from the cursor to the previous whitespace. This is different than +@kbd{M-@key{DEL}} because the word boundaries differ. + +@end table + +Here is how to @dfn{yank} the text back into the line. Yanking +means to copy the most-recently-killed text from the kill buffer. + +@table @kbd +@item C-y +Yank the most recently killed text back into the buffer at the cursor. + +@item M-y +Rotate the kill-ring, and yank the new top. You can only do this if +the prior command is @kbd{C-y} or @kbd{M-y}. +@end table + +@node Readline Arguments +@subsection Readline Arguments + +You can pass numeric arguments to Readline commands. Sometimes the +argument acts as a repeat count, other times it is the @i{sign} of the +argument that is significant. If you pass a negative argument to a +command which normally acts in a forward direction, that command will +act in a backward direction. For example, to kill text back to the +start of the line, you might type @samp{M-- C-k}. + +The general way to pass numeric arguments to a command is to type meta +digits before the command. If the first `digit' typed is a minus +sign (@samp{-}), then the sign of the argument will be negative. Once +you have typed one meta digit to get the argument started, you can type +the remainder of the digits, and then the command. For example, to give +the @kbd{C-d} command an argument of 10, you could type @samp{M-1 0 C-d}, +which will delete the next ten characters on the input line. + +@node Searching +@subsection Searching for Commands in the History + +Readline provides commands for searching through the command history +@ifset BashFeatures +(@pxref{Bash History Facilities}) +@end ifset +for lines containing a specified string. +There are two search modes: @dfn{incremental} and @dfn{non-incremental}. + +Incremental searches begin before the user has finished typing the +search string. +As each character of the search string is typed, Readline displays +the next entry from the history matching the string typed so far. +An incremental search requires only as many characters as needed to +find the desired history entry. +To search backward in the history for a particular string, type +@kbd{C-r}. Typing @kbd{C-s} searches forward through the history. +The characters present in the value of the @code{isearch-terminators} variable +are used to terminate an incremental search. +If that variable has not been assigned a value, the @key{ESC} and +@kbd{C-J} characters will terminate an incremental search. +@kbd{C-g} will abort an incremental search and restore the original line. +When the search is terminated, the history entry containing the +search string becomes the current line. + +To find other matching entries in the history list, type @kbd{C-r} or +@kbd{C-s} as appropriate. +This will search backward or forward in the history for the next +entry matching the search string typed so far. +Any other key sequence bound to a Readline command will terminate +the search and execute that command. +For instance, a @key{RET} will terminate the search and accept +the line, thereby executing the command from the history list. +A movement command will terminate the search, make the last line found +the current line, and begin editing. + +Readline remembers the last incremental search string. If two +@kbd{C-r}s are typed without any intervening characters defining a new +search string, any remembered search string is used. + +Non-incremental searches read the entire search string before starting +to search for matching history lines. The search string may be +typed by the user or be part of the contents of the current line. + +@node Readline Init File +@section Readline Init File +@cindex initialization file, readline + +Although the Readline library comes with a set of Emacs-like +keybindings installed by default, it is possible to use a different set +of keybindings. +Any user can customize programs that use Readline by putting +commands in an @dfn{inputrc} file, conventionally in his home directory. +The name of this +@ifset BashFeatures +file is taken from the value of the shell variable @env{INPUTRC}. If +@end ifset +@ifclear BashFeatures +file is taken from the value of the environment variable @env{INPUTRC}. If +@end ifclear +that variable is unset, the default is @file{~/.inputrc}. If that +file does not exist or cannot be read, the ultimate default is +@file{/etc/inputrc}. +@ifset BashFeatures +The @w{@code{bind}} builtin command can also be used to set Readline +keybindings and variables. +@xref{Bash Builtins}. +@end ifset + +When a program which uses the Readline library starts up, the +init file is read, and the key bindings are set. + +In addition, the @code{C-x C-r} command re-reads this init file, thus +incorporating any changes that you might have made to it. + +@menu +* Readline Init File Syntax:: Syntax for the commands in the inputrc file. + +* Conditional Init Constructs:: Conditional key bindings in the inputrc file. + +* Sample Init File:: An example inputrc file. +@end menu + +@node Readline Init File Syntax +@subsection Readline Init File Syntax + +There are only a few basic constructs allowed in the +Readline init file. Blank lines are ignored. +Lines beginning with a @samp{#} are comments. +Lines beginning with a @samp{$} indicate conditional +constructs (@pxref{Conditional Init Constructs}). Other lines +denote variable settings and key bindings. + +@table @asis +@item Variable Settings +You can modify the run-time behavior of Readline by +altering the values of variables in Readline +using the @code{set} command within the init file. +The syntax is simple: + +@example +set @var{variable} @var{value} +@end example + +@noindent +Here, for example, is how to +change from the default Emacs-like key binding to use +@code{vi} line editing commands: + +@example +set editing-mode vi +@end example + +Variable names and values, where appropriate, are recognized without regard +to case. Unrecognized variable names are ignored. + +Boolean variables (those that can be set to on or off) are set to on if +the value is null or empty, @var{on} (case-insensitive), or 1. Any other +value results in the variable being set to off. + +@ifset BashFeatures +The @w{@code{bind -V}} command lists the current Readline variable names +and values. @xref{Bash Builtins}. +@end ifset + +A great deal of run-time behavior is changeable with the following +variables. + +@cindex variables, readline +@table @code + +@item bell-style +@vindex bell-style +Controls what happens when Readline wants to ring the terminal bell. +If set to @samp{none}, Readline never rings the bell. If set to +@samp{visible}, Readline uses a visible bell if one is available. +If set to @samp{audible} (the default), Readline attempts to ring +the terminal's bell. + +@item bind-tty-special-chars +@vindex bind-tty-special-chars +If set to @samp{on} (the default), Readline attempts to bind the control +characters treated specially by the kernel's terminal driver to their +Readline equivalents. + +@item blink-matching-paren +@vindex blink-matching-paren +If set to @samp{on}, Readline attempts to briefly move the cursor to an +opening parenthesis when a closing parenthesis is inserted. The default +is @samp{off}. + +@item colored-completion-prefix +@vindex colored-completion-prefix +If set to @samp{on}, when listing completions, Readline displays the +common prefix of the set of possible completions using a different color. +The color definitions are taken from the value of the @env{LS_COLORS} +environment variable. +The default is @samp{off}. + +@item colored-stats +@vindex colored-stats +If set to @samp{on}, Readline displays possible completions using different +colors to indicate their file type. +The color definitions are taken from the value of the @env{LS_COLORS} +environment variable. +The default is @samp{off}. + +@item comment-begin +@vindex comment-begin +The string to insert at the beginning of the line when the +@code{insert-comment} command is executed. The default value +is @code{"#"}. + +@item completion-display-width +@vindex completion-display-width +The number of screen columns used to display possible matches +when performing completion. +The value is ignored if it is less than 0 or greater than the terminal +screen width. +A value of 0 will cause matches to be displayed one per line. +The default value is -1. + +@item completion-ignore-case +@vindex completion-ignore-case +If set to @samp{on}, Readline performs filename matching and completion +in a case-insensitive fashion. +The default value is @samp{off}. + +@item completion-map-case +@vindex completion-map-case +If set to @samp{on}, and @var{completion-ignore-case} is enabled, Readline +treats hyphens (@samp{-}) and underscores (@samp{_}) as equivalent when +performing case-insensitive filename matching and completion. +The default value is @samp{off}. + +@item completion-prefix-display-length +@vindex completion-prefix-display-length +The length in characters of the common prefix of a list of possible +completions that is displayed without modification. When set to a +value greater than zero, common prefixes longer than this value are +replaced with an ellipsis when displaying possible completions. + +@item completion-query-items +@vindex completion-query-items +The number of possible completions that determines when the user is +asked whether the list of possibilities should be displayed. +If the number of possible completions is greater than or equal to this value, +Readline will ask whether or not the user wishes to view them; +otherwise, they are simply listed. +This variable must be set to an integer value greater than or equal to 0. +A negative value means Readline should never ask. +The default limit is @code{100}. + +@item convert-meta +@vindex convert-meta +If set to @samp{on}, Readline will convert characters with the +eighth bit set to an @sc{ascii} key sequence by stripping the eighth +bit and prefixing an @key{ESC} character, converting them to a +meta-prefixed key sequence. The default value is @samp{on}, but +will be set to @samp{off} if the locale is one that contains +eight-bit characters. + +@item disable-completion +@vindex disable-completion +If set to @samp{On}, Readline will inhibit word completion. +Completion characters will be inserted into the line as if they had +been mapped to @code{self-insert}. The default is @samp{off}. + +@item echo-control-characters +@vindex echo-control-characters +When set to @samp{on}, on operating systems that indicate they support it, +readline echoes a character corresponding to a signal generated from the +keyboard. The default is @samp{on}. + +@item editing-mode +@vindex editing-mode +The @code{editing-mode} variable controls which default set of +key bindings is used. By default, Readline starts up in Emacs editing +mode, where the keystrokes are most similar to Emacs. This variable can be +set to either @samp{emacs} or @samp{vi}. + +@item emacs-mode-string +@vindex emacs-mode-string +If the @var{show-mode-in-prompt} variable is enabled, +this string is displayed immediately before the last line of the primary +prompt when emacs editing mode is active. The value is expanded like a +key binding, so the standard set of meta- and control prefixes and +backslash escape sequences is available. +Use the @samp{\1} and @samp{\2} escapes to begin and end sequences of +non-printing characters, which can be used to embed a terminal control +sequence into the mode string. +The default is @samp{@@}. + +@item enable-bracketed-paste +@vindex enable-bracketed-paste +When set to @samp{On}, Readline will configure the terminal in a way +that will enable it to insert each paste into the editing buffer as a +single string of characters, instead of treating each character as if +it had been read from the keyboard. This can prevent pasted characters +from being interpreted as editing commands. The default is @samp{On}. + +@item enable-keypad +@vindex enable-keypad +When set to @samp{on}, Readline will try to enable the application +keypad when it is called. Some systems need this to enable the +arrow keys. The default is @samp{off}. + +@item enable-meta-key +When set to @samp{on}, Readline will try to enable any meta modifier +key the terminal claims to support when it is called. On many terminals, +the meta key is used to send eight-bit characters. +The default is @samp{on}. + +@item expand-tilde +@vindex expand-tilde +If set to @samp{on}, tilde expansion is performed when Readline +attempts word completion. The default is @samp{off}. + +@item history-preserve-point +@vindex history-preserve-point +If set to @samp{on}, the history code attempts to place the point (the +current cursor position) at the +same location on each history line retrieved with @code{previous-history} +or @code{next-history}. The default is @samp{off}. + +@item history-size +@vindex history-size +Set the maximum number of history entries saved in the history list. +If set to zero, any existing history entries are deleted and no new entries +are saved. +If set to a value less than zero, the number of history entries is not +limited. +By default, the number of history entries is not limited. +If an attempt is made to set @var{history-size} to a non-numeric value, +the maximum number of history entries will be set to 500. + +@item horizontal-scroll-mode +@vindex horizontal-scroll-mode +This variable can be set to either @samp{on} or @samp{off}. Setting it +to @samp{on} means that the text of the lines being edited will scroll +horizontally on a single screen line when they are longer than the width +of the screen, instead of wrapping onto a new screen line. +This variable is automatically set to @samp{on} for terminals of height 1. +By default, this variable is set to @samp{off}. + +@item input-meta +@vindex input-meta +@vindex meta-flag +If set to @samp{on}, Readline will enable eight-bit input (it +will not clear the eighth bit in the characters it reads), +regardless of what the terminal claims it can support. The +default value is @samp{off}, but Readline will set it to @samp{on} if the +locale contains eight-bit characters. +The name @code{meta-flag} is a synonym for this variable. + +@item isearch-terminators +@vindex isearch-terminators +The string of characters that should terminate an incremental search without +subsequently executing the character as a command (@pxref{Searching}). +If this variable has not been given a value, the characters @key{ESC} and +@kbd{C-J} will terminate an incremental search. + +@item keymap +@vindex keymap +Sets Readline's idea of the current keymap for key binding commands. +Built-in @code{keymap} names are +@code{emacs}, +@code{emacs-standard}, +@code{emacs-meta}, +@code{emacs-ctlx}, +@code{vi}, +@code{vi-move}, +@code{vi-command}, and +@code{vi-insert}. +@code{vi} is equivalent to @code{vi-command} (@code{vi-move} is also a +synonym); @code{emacs} is equivalent to @code{emacs-standard}. +Applications may add additional names. +The default value is @code{emacs}. +The value of the @code{editing-mode} variable also affects the +default keymap. + +@item keyseq-timeout +Specifies the duration Readline will wait for a character when reading an +ambiguous key sequence (one that can form a complete key sequence using +the input read so far, or can take additional input to complete a longer +key sequence). +If no input is received within the timeout, Readline will use the shorter +but complete key sequence. +Readline uses this value to determine whether or not input is +available on the current input source (@code{rl_instream} by default). +The value is specified in milliseconds, so a value of 1000 means that +Readline will wait one second for additional input. +If this variable is set to a value less than or equal to zero, or to a +non-numeric value, Readline will wait until another key is pressed to +decide which key sequence to complete. +The default value is @code{500}. + +@item mark-directories +If set to @samp{on}, completed directory names have a slash +appended. The default is @samp{on}. + +@item mark-modified-lines +@vindex mark-modified-lines +This variable, when set to @samp{on}, causes Readline to display an +asterisk (@samp{*}) at the start of history lines which have been modified. +This variable is @samp{off} by default. + +@item mark-symlinked-directories +@vindex mark-symlinked-directories +If set to @samp{on}, completed names which are symbolic links +to directories have a slash appended (subject to the value of +@code{mark-directories}). +The default is @samp{off}. + +@item match-hidden-files +@vindex match-hidden-files +This variable, when set to @samp{on}, causes Readline to match files whose +names begin with a @samp{.} (hidden files) when performing filename +completion. +If set to @samp{off}, the leading @samp{.} must be +supplied by the user in the filename to be completed. +This variable is @samp{on} by default. + +@item menu-complete-display-prefix +@vindex menu-complete-display-prefix +If set to @samp{on}, menu completion displays the common prefix of the +list of possible completions (which may be empty) before cycling through +the list. The default is @samp{off}. + +@item output-meta +@vindex output-meta +If set to @samp{on}, Readline will display characters with the +eighth bit set directly rather than as a meta-prefixed escape +sequence. +The default is @samp{off}, but Readline will set it to @samp{on} if the +locale contains eight-bit characters. + +@item page-completions +@vindex page-completions +If set to @samp{on}, Readline uses an internal @code{more}-like pager +to display a screenful of possible completions at a time. +This variable is @samp{on} by default. + +@item print-completions-horizontally +If set to @samp{on}, Readline will display completions with matches +sorted horizontally in alphabetical order, rather than down the screen. +The default is @samp{off}. + +@item revert-all-at-newline +@vindex revert-all-at-newline +If set to @samp{on}, Readline will undo all changes to history lines +before returning when @code{accept-line} is executed. By default, +history lines may be modified and retain individual undo lists across +calls to @code{readline}. The default is @samp{off}. + +@item show-all-if-ambiguous +@vindex show-all-if-ambiguous +This alters the default behavior of the completion functions. If +set to @samp{on}, +words which have more than one possible completion cause the +matches to be listed immediately instead of ringing the bell. +The default value is @samp{off}. + +@item show-all-if-unmodified +@vindex show-all-if-unmodified +This alters the default behavior of the completion functions in +a fashion similar to @var{show-all-if-ambiguous}. +If set to @samp{on}, +words which have more than one possible completion without any +possible partial completion (the possible completions don't share +a common prefix) cause the matches to be listed immediately instead +of ringing the bell. +The default value is @samp{off}. + +@item show-mode-in-prompt +@vindex show-mode-in-prompt +If set to @samp{on}, add a string to the beginning of the prompt +indicating the editing mode: emacs, vi command, or vi insertion. +The mode strings are user-settable (e.g., @var{emacs-mode-string}). +The default value is @samp{off}. + +@item skip-completed-text +@vindex skip-completed-text +If set to @samp{on}, this alters the default completion behavior when +inserting a single match into the line. It's only active when +performing completion in the middle of a word. If enabled, readline +does not insert characters from the completion that match characters +after point in the word being completed, so portions of the word +following the cursor are not duplicated. +For instance, if this is enabled, attempting completion when the cursor +is after the @samp{e} in @samp{Makefile} will result in @samp{Makefile} +rather than @samp{Makefilefile}, assuming there is a single possible +completion. +The default value is @samp{off}. + +@item vi-cmd-mode-string +@vindex vi-cmd-mode-string +If the @var{show-mode-in-prompt} variable is enabled, +this string is displayed immediately before the last line of the primary +prompt when vi editing mode is active and in command mode. +The value is expanded like a +key binding, so the standard set of meta- and control prefixes and +backslash escape sequences is available. +Use the @samp{\1} and @samp{\2} escapes to begin and end sequences of +non-printing characters, which can be used to embed a terminal control +sequence into the mode string. +The default is @samp{(cmd)}. + +@item vi-ins-mode-string +@vindex vi-ins-mode-string +If the @var{show-mode-in-prompt} variable is enabled, +this string is displayed immediately before the last line of the primary +prompt when vi editing mode is active and in insertion mode. +The value is expanded like a +key binding, so the standard set of meta- and control prefixes and +backslash escape sequences is available. +Use the @samp{\1} and @samp{\2} escapes to begin and end sequences of +non-printing characters, which can be used to embed a terminal control +sequence into the mode string. +The default is @samp{(ins)}. + +@item visible-stats +@vindex visible-stats +If set to @samp{on}, a character denoting a file's type +is appended to the filename when listing possible +completions. The default is @samp{off}. + +@end table + +@item Key Bindings +The syntax for controlling key bindings in the init file is +simple. First you need to find the name of the command that you +want to change. The following sections contain tables of the command +name, the default keybinding, if any, and a short description of what +the command does. + +Once you know the name of the command, simply place on a line +in the init file the name of the key +you wish to bind the command to, a colon, and then the name of the +command. +There can be no space between the key name and the colon -- that will be +interpreted as part of the key name. +The name of the key can be expressed in different ways, depending on +what you find most comfortable. + +In addition to command names, readline allows keys to be bound +to a string that is inserted when the key is pressed (a @var{macro}). + +@ifset BashFeatures +The @w{@code{bind -p}} command displays Readline function names and +bindings in a format that can put directly into an initialization file. +@xref{Bash Builtins}. +@end ifset + +@table @asis +@item @w{@var{keyname}: @var{function-name} or @var{macro}} +@var{keyname} is the name of a key spelled out in English. For example: +@example +Control-u: universal-argument +Meta-Rubout: backward-kill-word +Control-o: "> output" +@end example + +In the example above, @kbd{C-u} is bound to the function +@code{universal-argument}, +@kbd{M-DEL} is bound to the function @code{backward-kill-word}, and +@kbd{C-o} is bound to run the macro +expressed on the right hand side (that is, to insert the text +@samp{> output} into the line). + +A number of symbolic character names are recognized while +processing this key binding syntax: +@var{DEL}, +@var{ESC}, +@var{ESCAPE}, +@var{LFD}, +@var{NEWLINE}, +@var{RET}, +@var{RETURN}, +@var{RUBOUT}, +@var{SPACE}, +@var{SPC}, +and +@var{TAB}. + +@item @w{"@var{keyseq}": @var{function-name} or @var{macro}} +@var{keyseq} differs from @var{keyname} above in that strings +denoting an entire key sequence can be specified, by placing +the key sequence in double quotes. Some @sc{gnu} Emacs style key +escapes can be used, as in the following example, but the +special character names are not recognized. + +@example +"\C-u": universal-argument +"\C-x\C-r": re-read-init-file +"\e[11~": "Function Key 1" +@end example + +In the above example, @kbd{C-u} is again bound to the function +@code{universal-argument} (just as it was in the first example), +@samp{@kbd{C-x} @kbd{C-r}} is bound to the function @code{re-read-init-file}, +and @samp{@key{ESC} @key{[} @key{1} @key{1} @key{~}} is bound to insert +the text @samp{Function Key 1}. + +@end table + +The following @sc{gnu} Emacs style escape sequences are available when +specifying key sequences: + +@table @code +@item @kbd{\C-} +control prefix +@item @kbd{\M-} +meta prefix +@item @kbd{\e} +an escape character +@item @kbd{\\} +backslash +@item @kbd{\"} +@key{"}, a double quotation mark +@item @kbd{\'} +@key{'}, a single quote or apostrophe +@end table + +In addition to the @sc{gnu} Emacs style escape sequences, a second +set of backslash escapes is available: + +@table @code +@item \a +alert (bell) +@item \b +backspace +@item \d +delete +@item \f +form feed +@item \n +newline +@item \r +carriage return +@item \t +horizontal tab +@item \v +vertical tab +@item \@var{nnn} +the eight-bit character whose value is the octal value @var{nnn} +(one to three digits) +@item \x@var{HH} +the eight-bit character whose value is the hexadecimal value @var{HH} +(one or two hex digits) +@end table + +When entering the text of a macro, single or double quotes must +be used to indicate a macro definition. +Unquoted text is assumed to be a function name. +In the macro body, the backslash escapes described above are expanded. +Backslash will quote any other character in the macro text, +including @samp{"} and @samp{'}. +For example, the following binding will make @samp{@kbd{C-x} \} +insert a single @samp{\} into the line: +@example +"\C-x\\": "\\" +@end example + +@end table + +@node Conditional Init Constructs +@subsection Conditional Init Constructs + +Readline implements a facility similar in spirit to the conditional +compilation features of the C preprocessor which allows key +bindings and variable settings to be performed as the result +of tests. There are four parser directives used. + +@table @code +@item $if +The @code{$if} construct allows bindings to be made based on the +editing mode, the terminal being used, or the application using +Readline. The text of the test, after any comparison operator, +extends to the end of the line; +unless otherwise noted, no characters are required to isolate it. + +@table @code +@item mode +The @code{mode=} form of the @code{$if} directive is used to test +whether Readline is in @code{emacs} or @code{vi} mode. +This may be used in conjunction +with the @samp{set keymap} command, for instance, to set bindings in +the @code{emacs-standard} and @code{emacs-ctlx} keymaps only if +Readline is starting out in @code{emacs} mode. + +@item term +The @code{term=} form may be used to include terminal-specific +key bindings, perhaps to bind the key sequences output by the +terminal's function keys. The word on the right side of the +@samp{=} is tested against both the full name of the terminal and +the portion of the terminal name before the first @samp{-}. This +allows @code{sun} to match both @code{sun} and @code{sun-cmd}, +for instance. + +@item version +The @code{version} test may be used to perform comparisons against +specific Readline versions. +The @code{version} expands to the current Readline version. +The set of comparison operators includes +@samp{=} (and @samp{==}), @samp{!=}, @samp{<=}, @samp{>=}, @samp{<}, +and @samp{>}. +The version number supplied on the right side of the operator consists +of a major version number, an optional decimal point, and an optional +minor version (e.g., @samp{7.1}). If the minor version is omitted, it +is assumed to be @samp{0}. +The operator may be separated from the string @code{version} and +from the version number argument by whitespace. +The following example sets a variable if the Readline version being used +is 7.0 or newer: +@example +$if version >= 7.0 +set show-mode-in-prompt on +$endif +@end example + +@item application +The @var{application} construct is used to include +application-specific settings. Each program using the Readline +library sets the @var{application name}, and you can test for +a particular value. +This could be used to bind key sequences to functions useful for +a specific program. For instance, the following command adds a +key sequence that quotes the current or previous word in Bash: +@example +$if Bash +# Quote the current or previous word +"\C-xq": "\eb\"\ef\"" +$endif +@end example + +@item variable +The @var{variable} construct provides simple equality tests for Readline +variables and values. +The permitted comparison operators are @samp{=}, @samp{==}, and @samp{!=}. +The variable name must be separated from the comparison operator by +whitespace; the operator may be separated from the value on the right hand +side by whitespace. +Both string and boolean variables may be tested. Boolean variables must be +tested against the values @var{on} and @var{off}. +The following example is equivalent to the @code{mode=emacs} test described +above: +@example +$if editing-mode == emacs +set show-mode-in-prompt on +$endif +@end example +@end table + +@item $endif +This command, as seen in the previous example, terminates an +@code{$if} command. + +@item $else +Commands in this branch of the @code{$if} directive are executed if +the test fails. + +@item $include +This directive takes a single filename as an argument and reads commands +and bindings from that file. +For example, the following directive reads from @file{/etc/inputrc}: +@example +$include /etc/inputrc +@end example +@end table + +@node Sample Init File +@subsection Sample Init File + +Here is an example of an @var{inputrc} file. This illustrates key +binding, variable assignment, and conditional syntax. + +@example +@page +# This file controls the behaviour of line input editing for +# programs that use the GNU Readline library. Existing +# programs include FTP, Bash, and GDB. +# +# You can re-read the inputrc file with C-x C-r. +# Lines beginning with '#' are comments. +# +# First, include any system-wide bindings and variable +# assignments from /etc/Inputrc +$include /etc/Inputrc + +# +# Set various bindings for emacs mode. + +set editing-mode emacs + +$if mode=emacs + +Meta-Control-h: backward-kill-word Text after the function name is ignored + +# +# Arrow keys in keypad mode +# +#"\M-OD": backward-char +#"\M-OC": forward-char +#"\M-OA": previous-history +#"\M-OB": next-history +# +# Arrow keys in ANSI mode +# +"\M-[D": backward-char +"\M-[C": forward-char +"\M-[A": previous-history +"\M-[B": next-history +# +# Arrow keys in 8 bit keypad mode +# +#"\M-\C-OD": backward-char +#"\M-\C-OC": forward-char +#"\M-\C-OA": previous-history +#"\M-\C-OB": next-history +# +# Arrow keys in 8 bit ANSI mode +# +#"\M-\C-[D": backward-char +#"\M-\C-[C": forward-char +#"\M-\C-[A": previous-history +#"\M-\C-[B": next-history + +C-q: quoted-insert + +$endif + +# An old-style binding. This happens to be the default. +TAB: complete + +# Macros that are convenient for shell interaction +$if Bash +# edit the path +"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f" +# prepare to type a quoted word -- +# insert open and close double quotes +# and move to just after the open quote +"\C-x\"": "\"\"\C-b" +# insert a backslash (testing backslash escapes +# in sequences and macros) +"\C-x\\": "\\" +# Quote the current or previous word +"\C-xq": "\eb\"\ef\"" +# Add a binding to refresh the line, which is unbound +"\C-xr": redraw-current-line +# Edit variable on current line. +"\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" +$endif + +# use a visible bell if one is available +set bell-style visible + +# don't strip characters to 7 bits when reading +set input-meta on + +# allow iso-latin1 characters to be inserted rather +# than converted to prefix-meta sequences +set convert-meta off + +# display characters with the eighth bit set directly +# rather than as meta-prefixed characters +set output-meta on + +# if there are 150 or more possible completions for a word, +# ask whether or not the user wants to see all of them +set completion-query-items 150 + +# For FTP +$if Ftp +"\C-xg": "get \M-?" +"\C-xt": "put \M-?" +"\M-.": yank-last-arg +$endif +@end example + +@node Bindable Readline Commands +@section Bindable Readline Commands + +@menu +* Commands For Moving:: Moving about the line. +* Commands For History:: Getting at previous lines. +* Commands For Text:: Commands for changing text. +* Commands For Killing:: Commands for killing and yanking. +* Numeric Arguments:: Specifying numeric arguments, repeat counts. +* Commands For Completion:: Getting Readline to do the typing for you. +* Keyboard Macros:: Saving and re-executing typed characters +* Miscellaneous Commands:: Other miscellaneous commands. +@end menu + +This section describes Readline commands that may be bound to key +sequences. +@ifset BashFeatures +You can list your key bindings by executing +@w{@code{bind -P}} or, for a more terse format, suitable for an +@var{inputrc} file, @w{@code{bind -p}}. (@xref{Bash Builtins}.) +@end ifset +Command names without an accompanying key sequence are unbound by default. + +In the following descriptions, @dfn{point} refers to the current cursor +position, and @dfn{mark} refers to a cursor position saved by the +@code{set-mark} command. +The text between the point and mark is referred to as the @dfn{region}. + +@node Commands For Moving +@subsection Commands For Moving +@ftable @code +@item beginning-of-line (C-a) +Move to the start of the current line. + +@item end-of-line (C-e) +Move to the end of the line. + +@item forward-char (C-f) +Move forward a character. + +@item backward-char (C-b) +Move back a character. + +@item forward-word (M-f) +Move forward to the end of the next word. +Words are composed of letters and digits. + +@item backward-word (M-b) +Move back to the start of the current or previous word. +Words are composed of letters and digits. + +@ifset BashFeatures +@item shell-forward-word (M-C-f) +Move forward to the end of the next word. +Words are delimited by non-quoted shell metacharacters. + +@item shell-backward-word (M-C-b) +Move back to the start of the current or previous word. +Words are delimited by non-quoted shell metacharacters. +@end ifset + +@item previous-screen-line () +Attempt to move point to the same physical screen column on the previous +physical screen line. This will not have the desired effect if the current +Readline line does not take up more than one physical line or if point is not +greater than the length of the prompt plus the screen width. + +@item next-screen-line () +Attempt to move point to the same physical screen column on the next +physical screen line. This will not have the desired effect if the current +Readline line does not take up more than one physical line or if the length +of the current Readline line is not greater than the length of the prompt +plus the screen width. + +@item clear-display (M-C-l) +Clear the screen and, if possible, the terminal's scrollback buffer, +then redraw the current line, +leaving the current line at the top of the screen. + +@item clear-screen (C-l) +Clear the screen, +then redraw the current line, +leaving the current line at the top of the screen. + +@item redraw-current-line () +Refresh the current line. By default, this is unbound. + +@end ftable + +@node Commands For History +@subsection Commands For Manipulating The History + +@ftable @code +@item accept-line (Newline or Return) +@ifset BashFeatures +Accept the line regardless of where the cursor is. +If this line is +non-empty, add it to the history list according to the setting of +the @env{HISTCONTROL} and @env{HISTIGNORE} variables. +If this line is a modified history line, then restore the history line +to its original state. +@end ifset +@ifclear BashFeatures +Accept the line regardless of where the cursor is. +If this line is +non-empty, it may be added to the history list for future recall with +@code{add_history()}. +If this line is a modified history line, the history line is restored +to its original state. +@end ifclear + +@item previous-history (C-p) +Move `back' through the history list, fetching the previous command. + +@item next-history (C-n) +Move `forward' through the history list, fetching the next command. + +@item beginning-of-history (M-<) +Move to the first line in the history. + +@item end-of-history (M->) +Move to the end of the input history, i.e., the line currently +being entered. + +@item reverse-search-history (C-r) +Search backward starting at the current line and moving `up' through +the history as necessary. This is an incremental search. +This command sets the region to the matched text and activates the mark. + +@item forward-search-history (C-s) +Search forward starting at the current line and moving `down' through +the history as necessary. This is an incremental search. +This command sets the region to the matched text and activates the mark. + +@item non-incremental-reverse-search-history (M-p) +Search backward starting at the current line and moving `up' +through the history as necessary using a non-incremental search +for a string supplied by the user. +The search string may match anywhere in a history line. + +@item non-incremental-forward-search-history (M-n) +Search forward starting at the current line and moving `down' +through the history as necessary using a non-incremental search +for a string supplied by the user. +The search string may match anywhere in a history line. + +@item history-search-forward () +Search forward through the history for the string of characters +between the start of the current line and the point. +The search string must match at the beginning of a history line. +This is a non-incremental search. +By default, this command is unbound. + +@item history-search-backward () +Search backward through the history for the string of characters +between the start of the current line and the point. +The search string must match at the beginning of a history line. +This is a non-incremental search. +By default, this command is unbound. + +@item history-substring-search-forward () +Search forward through the history for the string of characters +between the start of the current line and the point. +The search string may match anywhere in a history line. +This is a non-incremental search. +By default, this command is unbound. + +@item history-substring-search-backward () +Search backward through the history for the string of characters +between the start of the current line and the point. +The search string may match anywhere in a history line. +This is a non-incremental search. +By default, this command is unbound. + +@item yank-nth-arg (M-C-y) +Insert the first argument to the previous command (usually +the second word on the previous line) at point. +With an argument @var{n}, +insert the @var{n}th word from the previous command (the words +in the previous command begin with word 0). A negative argument +inserts the @var{n}th word from the end of the previous command. +Once the argument @var{n} is computed, the argument is extracted +as if the @samp{!@var{n}} history expansion had been specified. + +@item yank-last-arg (M-. or M-_) +Insert last argument to the previous command (the last word of the +previous history entry). +With a numeric argument, behave exactly like @code{yank-nth-arg}. +Successive calls to @code{yank-last-arg} move back through the history +list, inserting the last word (or the word specified by the argument to +the first call) of each line in turn. +Any numeric argument supplied to these successive calls determines +the direction to move through the history. A negative argument switches +the direction through the history (back or forward). +The history expansion facilities are used to extract the last argument, +as if the @samp{!$} history expansion had been specified. + +@item operate-and-get-next (C-o) +Accept the current line for return to the calling application as if a +newline had been entered, +and fetch the next line relative to the current line from the history +for editing. +A numeric argument, if supplied, specifies the history entry to use instead +of the current line. + +@end ftable + +@node Commands For Text +@subsection Commands For Changing Text + +@ftable @code + +@item @i{end-of-file} (usually C-d) +The character indicating end-of-file as set, for example, by +@code{stty}. If this character is read when there are no characters +on the line, and point is at the beginning of the line, Readline +interprets it as the end of input and returns @sc{eof}. + +@item delete-char (C-d) +Delete the character at point. If this function is bound to the +same character as the tty @sc{eof} character, as @kbd{C-d} +commonly is, see above for the effects. + +@item backward-delete-char (Rubout) +Delete the character behind the cursor. A numeric argument means +to kill the characters instead of deleting them. + +@item forward-backward-delete-char () +Delete the character under the cursor, unless the cursor is at the +end of the line, in which case the character behind the cursor is +deleted. By default, this is not bound to a key. + +@item quoted-insert (C-q or C-v) +Add the next character typed to the line verbatim. This is +how to insert key sequences like @kbd{C-q}, for example. + +@ifclear BashFeatures +@item tab-insert (M-@key{TAB}) +Insert a tab character. +@end ifclear + +@item self-insert (a, b, A, 1, !, @dots{}) +Insert yourself. + +@item bracketed-paste-begin () +This function is intended to be bound to the "bracketed paste" escape +sequence sent by some terminals, and such a binding is assigned by default. +It allows Readline to insert the pasted text as a single unit without treating +each character as if it had been read from the keyboard. The characters +are inserted as if each one was bound to @code{self-insert} instead of +executing any editing commands. + +Bracketed paste sets the region (the characters between point and the mark) +to the inserted text. It uses the concept of an @emph{active mark}: when the +mark is active, Readline redisplay uses the terminal's standout mode to +denote the region. + +@item transpose-chars (C-t) +Drag the character before the cursor forward over +the character at the cursor, moving the +cursor forward as well. If the insertion point +is at the end of the line, then this +transposes the last two characters of the line. +Negative arguments have no effect. + +@item transpose-words (M-t) +Drag the word before point past the word after point, +moving point past that word as well. +If the insertion point is at the end of the line, this transposes +the last two words on the line. + +@item upcase-word (M-u) +Uppercase the current (or following) word. With a negative argument, +uppercase the previous word, but do not move the cursor. + +@item downcase-word (M-l) +Lowercase the current (or following) word. With a negative argument, +lowercase the previous word, but do not move the cursor. + +@item capitalize-word (M-c) +Capitalize the current (or following) word. With a negative argument, +capitalize the previous word, but do not move the cursor. + +@item overwrite-mode () +Toggle overwrite mode. With an explicit positive numeric argument, +switches to overwrite mode. With an explicit non-positive numeric +argument, switches to insert mode. This command affects only +@code{emacs} mode; @code{vi} mode does overwrite differently. +Each call to @code{readline()} starts in insert mode. + +In overwrite mode, characters bound to @code{self-insert} replace +the text at point rather than pushing the text to the right. +Characters bound to @code{backward-delete-char} replace the character +before point with a space. + +By default, this command is unbound. + +@end ftable + +@node Commands For Killing +@subsection Killing And Yanking + +@ftable @code + +@item kill-line (C-k) +Kill the text from point to the end of the line. +With a negative numeric argument, kill backward from the cursor to the +beginning of the current line. + +@item backward-kill-line (C-x Rubout) +Kill backward from the cursor to the beginning of the current line. +With a negative numeric argument, kill forward from the cursor to the +end of the current line. + +@item unix-line-discard (C-u) +Kill backward from the cursor to the beginning of the current line. + +@item kill-whole-line () +Kill all characters on the current line, no matter where point is. +By default, this is unbound. + +@item kill-word (M-d) +Kill from point to the end of the current word, or if between +words, to the end of the next word. +Word boundaries are the same as @code{forward-word}. + +@item backward-kill-word (M-@key{DEL}) +Kill the word behind point. +Word boundaries are the same as @code{backward-word}. + +@ifset BashFeatures +@item shell-kill-word (M-C-d) +Kill from point to the end of the current word, or if between +words, to the end of the next word. +Word boundaries are the same as @code{shell-forward-word}. + +@item shell-backward-kill-word () +Kill the word behind point. +Word boundaries are the same as @code{shell-backward-word}. +@end ifset + +@item shell-transpose-words (M-C-t) +Drag the word before point past the word after point, +moving point past that word as well. +If the insertion point is at the end of the line, this transposes +the last two words on the line. +Word boundaries are the same as @code{shell-forward-word} and +@code{shell-backward-word}. + +@item unix-word-rubout (C-w) +Kill the word behind point, using white space as a word boundary. +The killed text is saved on the kill-ring. + +@item unix-filename-rubout () +Kill the word behind point, using white space and the slash character +as the word boundaries. +The killed text is saved on the kill-ring. + +@item delete-horizontal-space () +Delete all spaces and tabs around point. By default, this is unbound. + +@item kill-region () +Kill the text in the current region. +By default, this command is unbound. + +@item copy-region-as-kill () +Copy the text in the region to the kill buffer, so it can be yanked +right away. By default, this command is unbound. + +@item copy-backward-word () +Copy the word before point to the kill buffer. +The word boundaries are the same as @code{backward-word}. +By default, this command is unbound. + +@item copy-forward-word () +Copy the word following point to the kill buffer. +The word boundaries are the same as @code{forward-word}. +By default, this command is unbound. + +@item yank (C-y) +Yank the top of the kill ring into the buffer at point. + +@item yank-pop (M-y) +Rotate the kill-ring, and yank the new top. You can only do this if +the prior command is @code{yank} or @code{yank-pop}. +@end ftable + +@node Numeric Arguments +@subsection Specifying Numeric Arguments +@ftable @code + +@item digit-argument (@kbd{M-0}, @kbd{M-1}, @dots{} @kbd{M--}) +Add this digit to the argument already accumulating, or start a new +argument. @kbd{M--} starts a negative argument. + +@item universal-argument () +This is another way to specify an argument. +If this command is followed by one or more digits, optionally with a +leading minus sign, those digits define the argument. +If the command is followed by digits, executing @code{universal-argument} +again ends the numeric argument, but is otherwise ignored. +As a special case, if this command is immediately followed by a +character that is neither a digit nor minus sign, the argument count +for the next command is multiplied by four. +The argument count is initially one, so executing this function the +first time makes the argument count four, a second time makes the +argument count sixteen, and so on. +By default, this is not bound to a key. +@end ftable + +@node Commands For Completion +@subsection Letting Readline Type For You + +@ftable @code +@item complete (@key{TAB}) +Attempt to perform completion on the text before point. +The actual completion performed is application-specific. +@ifset BashFeatures +Bash attempts completion treating the text as a variable (if the +text begins with @samp{$}), username (if the text begins with +@samp{~}), hostname (if the text begins with @samp{@@}), or +command (including aliases and functions) in turn. If none +of these produces a match, filename completion is attempted. +@end ifset +@ifclear BashFeatures +The default is filename completion. +@end ifclear + +@item possible-completions (M-?) +List the possible completions of the text before point. +When displaying completions, Readline sets the number of columns used +for display to the value of @code{completion-display-width}, the value of +the environment variable @env{COLUMNS}, or the screen width, in that order. + +@item insert-completions (M-*) +Insert all completions of the text before point that would have +been generated by @code{possible-completions}. + +@item menu-complete () +Similar to @code{complete}, but replaces the word to be completed +with a single match from the list of possible completions. +Repeated execution of @code{menu-complete} steps through the list +of possible completions, inserting each match in turn. +At the end of the list of completions, the bell is rung +(subject to the setting of @code{bell-style}) +and the original text is restored. +An argument of @var{n} moves @var{n} positions forward in the list +of matches; a negative argument may be used to move backward +through the list. +This command is intended to be bound to @key{TAB}, but is unbound +by default. + +@item menu-complete-backward () +Identical to @code{menu-complete}, but moves backward through the list +of possible completions, as if @code{menu-complete} had been given a +negative argument. + +@item delete-char-or-list () +Deletes the character under the cursor if not at the beginning or +end of the line (like @code{delete-char}). +If at the end of the line, behaves identically to +@code{possible-completions}. +This command is unbound by default. + +@ifset BashFeatures +@item complete-filename (M-/) +Attempt filename completion on the text before point. + +@item possible-filename-completions (C-x /) +List the possible completions of the text before point, +treating it as a filename. + +@item complete-username (M-~) +Attempt completion on the text before point, treating +it as a username. + +@item possible-username-completions (C-x ~) +List the possible completions of the text before point, +treating it as a username. + +@item complete-variable (M-$) +Attempt completion on the text before point, treating +it as a shell variable. + +@item possible-variable-completions (C-x $) +List the possible completions of the text before point, +treating it as a shell variable. + +@item complete-hostname (M-@@) +Attempt completion on the text before point, treating +it as a hostname. + +@item possible-hostname-completions (C-x @@) +List the possible completions of the text before point, +treating it as a hostname. + +@item complete-command (M-!) +Attempt completion on the text before point, treating +it as a command name. Command completion attempts to +match the text against aliases, reserved words, shell +functions, shell builtins, and finally executable filenames, +in that order. + +@item possible-command-completions (C-x !) +List the possible completions of the text before point, +treating it as a command name. + +@item dynamic-complete-history (M-@key{TAB}) +Attempt completion on the text before point, comparing +the text against lines from the history list for possible +completion matches. + +@item dabbrev-expand () +Attempt menu completion on the text before point, comparing +the text against lines from the history list for possible +completion matches. + +@item complete-into-braces (M-@{) +Perform filename completion and insert the list of possible completions +enclosed within braces so the list is available to the shell +(@pxref{Brace Expansion}). + +@end ifset +@end ftable + +@node Keyboard Macros +@subsection Keyboard Macros +@ftable @code + +@item start-kbd-macro (C-x () +Begin saving the characters typed into the current keyboard macro. + +@item end-kbd-macro (C-x )) +Stop saving the characters typed into the current keyboard macro +and save the definition. + +@item call-last-kbd-macro (C-x e) +Re-execute the last keyboard macro defined, by making the characters +in the macro appear as if typed at the keyboard. + +@item print-last-kbd-macro () +Print the last keboard macro defined in a format suitable for the +@var{inputrc} file. + +@end ftable + +@node Miscellaneous Commands +@subsection Some Miscellaneous Commands +@ftable @code + +@item re-read-init-file (C-x C-r) +Read in the contents of the @var{inputrc} file, and incorporate +any bindings or variable assignments found there. + +@item abort (C-g) +Abort the current editing command and +ring the terminal's bell (subject to the setting of +@code{bell-style}). + +@item do-lowercase-version (M-A, M-B, M-@var{x}, @dots{}) +If the metafied character @var{x} is upper case, run the command +that is bound to the corresponding metafied lower case character. +The behavior is undefined if @var{x} is already lower case. + +@item prefix-meta (@key{ESC}) +Metafy the next character typed. This is for keyboards +without a meta key. Typing @samp{@key{ESC} f} is equivalent to typing +@kbd{M-f}. + +@item undo (C-_ or C-x C-u) +Incremental undo, separately remembered for each line. + +@item revert-line (M-r) +Undo all changes made to this line. This is like executing the @code{undo} +command enough times to get back to the beginning. + +@ifset BashFeatures +@item tilde-expand (M-&) +@end ifset +@ifclear BashFeatures +@item tilde-expand (M-~) +@end ifclear +Perform tilde expansion on the current word. + +@item set-mark (C-@@) +Set the mark to the point. If a +numeric argument is supplied, the mark is set to that position. + +@item exchange-point-and-mark (C-x C-x) +Swap the point with the mark. The current cursor position is set to +the saved position, and the old cursor position is saved as the mark. + +@item character-search (C-]) +A character is read and point is moved to the next occurrence of that +character. A negative count searches for previous occurrences. + +@item character-search-backward (M-C-]) +A character is read and point is moved to the previous occurrence +of that character. A negative count searches for subsequent +occurrences. + +@item skip-csi-sequence () +Read enough characters to consume a multi-key sequence such as those +defined for keys like Home and End. Such sequences begin with a +Control Sequence Indicator (CSI), usually ESC-[. If this sequence is +bound to "\e[", keys producing such sequences will have no effect +unless explicitly bound to a readline command, instead of inserting +stray characters into the editing buffer. This is unbound by default, +but usually bound to ESC-[. + +@item insert-comment (M-#) +Without a numeric argument, the value of the @code{comment-begin} +variable is inserted at the beginning of the current line. +If a numeric argument is supplied, this command acts as a toggle: if +the characters at the beginning of the line do not match the value +of @code{comment-begin}, the value is inserted, otherwise +the characters in @code{comment-begin} are deleted from the beginning of +the line. +In either case, the line is accepted as if a newline had been typed. +@ifset BashFeatures +The default value of @code{comment-begin} causes this command +to make the current line a shell comment. +If a numeric argument causes the comment character to be removed, the line +will be executed by the shell. +@end ifset + +@item dump-functions () +Print all of the functions and their key bindings to the +Readline output stream. If a numeric argument is supplied, +the output is formatted in such a way that it can be made part +of an @var{inputrc} file. This command is unbound by default. + +@item dump-variables () +Print all of the settable variables and their values to the +Readline output stream. If a numeric argument is supplied, +the output is formatted in such a way that it can be made part +of an @var{inputrc} file. This command is unbound by default. + +@item dump-macros () +Print all of the Readline key sequences bound to macros and the +strings they output. If a numeric argument is supplied, +the output is formatted in such a way that it can be made part +of an @var{inputrc} file. This command is unbound by default. + +@ifset BashFeatures +@item glob-complete-word (M-g) +The word before point is treated as a pattern for pathname expansion, +with an asterisk implicitly appended. This pattern is used to +generate a list of matching file names for possible completions. + +@item glob-expand-word (C-x *) +The word before point is treated as a pattern for pathname expansion, +and the list of matching file names is inserted, replacing the word. +If a numeric argument is supplied, a @samp{*} is appended before +pathname expansion. + +@item glob-list-expansions (C-x g) +The list of expansions that would have been generated by +@code{glob-expand-word} is displayed, and the line is redrawn. +If a numeric argument is supplied, a @samp{*} is appended before +pathname expansion. + +@item display-shell-version (C-x C-v) +Display version information about the current instance of Bash. + +@item shell-expand-line (M-C-e) +Expand the line as the shell does. +This performs alias and history expansion as well as all of the shell +word expansions (@pxref{Shell Expansions}). + +@item history-expand-line (M-^) +Perform history expansion on the current line. + +@item magic-space () +Perform history expansion on the current line and insert a space +(@pxref{History Interaction}). + +@item alias-expand-line () +Perform alias expansion on the current line (@pxref{Aliases}). + +@item history-and-alias-expand-line () +Perform history and alias expansion on the current line. + +@item insert-last-argument (M-. or M-_) +A synonym for @code{yank-last-arg}. + +@item edit-and-execute-command (C-x C-e) +Invoke an editor on the current command line, and execute the result as shell +commands. +Bash attempts to invoke +@code{$VISUAL}, @code{$EDITOR}, and @code{emacs} +as the editor, in that order. + +@end ifset + +@ifclear BashFeatures +@item emacs-editing-mode (C-e) +When in @code{vi} command mode, this causes a switch to @code{emacs} +editing mode. + +@item vi-editing-mode (M-C-j) +When in @code{emacs} editing mode, this causes a switch to @code{vi} +editing mode. + +@end ifclear + +@end ftable + +@node Readline vi Mode +@section Readline vi Mode + +While the Readline library does not have a full set of @code{vi} +editing functions, it does contain enough to allow simple editing +of the line. The Readline @code{vi} mode behaves as specified in +the @sc{posix} standard. + +@ifset BashFeatures +In order to switch interactively between @code{emacs} and @code{vi} +editing modes, use the @samp{set -o emacs} and @samp{set -o vi} +commands (@pxref{The Set Builtin}). +@end ifset +@ifclear BashFeatures +In order to switch interactively between @code{emacs} and @code{vi} +editing modes, use the command @kbd{M-C-j} (bound to emacs-editing-mode +when in @code{vi} mode and to vi-editing-mode in @code{emacs} mode). +@end ifclear +The Readline default is @code{emacs} mode. + +When you enter a line in @code{vi} mode, you are already placed in +`insertion' mode, as if you had typed an @samp{i}. Pressing @key{ESC} +switches you into `command' mode, where you can edit the text of the +line with the standard @code{vi} movement keys, move to previous +history lines with @samp{k} and subsequent lines with @samp{j}, and +so forth. + +@ifset BashFeatures +@node Programmable Completion +@section Programmable Completion +@cindex programmable completion + +When word completion is attempted for an argument to a command for +which a completion specification (a @var{compspec}) has been defined +using the @code{complete} builtin (@pxref{Programmable Completion Builtins}), +the programmable completion facilities are invoked. + +First, the command name is identified. +If a compspec has been defined for that command, the +compspec is used to generate the list of possible completions for the word. +If the command word is the empty string (completion attempted at the +beginning of an empty line), any compspec defined with +the @option{-E} option to @code{complete} is used. +If the command word is a full pathname, a compspec for the full +pathname is searched for first. +If no compspec is found for the full pathname, an attempt is made to +find a compspec for the portion following the final slash. +If those searches do not result in a compspec, any compspec defined with +the @option{-D} option to @code{complete} is used as the default. +If there is no default compspec, Bash attempts alias expansion +on the command word as a final resort, and attempts to find a compspec +for the command word from any successful expansion + +Once a compspec has been found, it is used to generate the list of +matching words. +If a compspec is not found, the default Bash completion +described above (@pxref{Commands For Completion}) is performed. + +First, the actions specified by the compspec are used. +Only matches which are prefixed by the word being completed are +returned. +When the @option{-f} or @option{-d} option is used for filename or +directory name completion, the shell variable @env{FIGNORE} is +used to filter the matches. +@xref{Bash Variables}, for a description of @env{FIGNORE}. + +Any completions specified by a filename expansion pattern to the +@option{-G} option are generated next. +The words generated by the pattern need not match the word being completed. +The @env{GLOBIGNORE} shell variable is not used to filter the matches, +but the @env{FIGNORE} shell variable is used. + +Next, the string specified as the argument to the @option{-W} option +is considered. +The string is first split using the characters in the @env{IFS} +special variable as delimiters. +Shell quoting is honored within the string, in order to provide a +mechanism for the words to contain shell metacharacters or characters +in the value of @env{IFS}. +Each word is then expanded using +brace expansion, tilde expansion, parameter and variable expansion, +command substitution, and arithmetic expansion, +as described above (@pxref{Shell Expansions}). +The results are split using the rules described above +(@pxref{Word Splitting}). +The results of the expansion are prefix-matched against the word being +completed, and the matching words become the possible completions. + +After these matches have been generated, any shell function or command +specified with the @option{-F} and @option{-C} options is invoked. +When the command or function is invoked, the @env{COMP_LINE}, +@env{COMP_POINT}, @env{COMP_KEY}, and @env{COMP_TYPE} variables are +assigned values as described above (@pxref{Bash Variables}). +If a shell function is being invoked, the @env{COMP_WORDS} and +@env{COMP_CWORD} variables are also set. +When the function or command is invoked, the first argument ($1) is the +name of the command whose arguments are being completed, the +second argument ($2) is the word being completed, and the third argument +($3) is the word preceding the word being completed on the current command +line. +No filtering of the generated completions against the word being completed +is performed; the function or command has complete freedom in generating +the matches. + +Any function specified with @option{-F} is invoked first. +The function may use any of the shell facilities, including the +@code{compgen} and @code{compopt} builtins described below +(@pxref{Programmable Completion Builtins}), to generate the matches. +It must put the possible completions in the @env{COMPREPLY} array +variable, one per array element. + +Next, any command specified with the @option{-C} option is invoked +in an environment equivalent to command substitution. +It should print a list of completions, one per line, to +the standard output. +Backslash may be used to escape a newline, if necessary. + +After all of the possible completions are generated, any filter +specified with the @option{-X} option is applied to the list. +The filter is a pattern as used for pathname expansion; a @samp{&} +in the pattern is replaced with the text of the word being completed. +A literal @samp{&} may be escaped with a backslash; the backslash +is removed before attempting a match. +Any completion that matches the pattern will be removed from the list. +A leading @samp{!} negates the pattern; in this case any completion +not matching the pattern will be removed. +If the @code{nocasematch} shell option +(see the description of @code{shopt} in @ref{The Shopt Builtin}) +is enabled, the match is performed without regard to the case +of alphabetic characters. + +Finally, any prefix and suffix specified with the @option{-P} and @option{-S} +options are added to each member of the completion list, and the result is +returned to the Readline completion code as the list of possible +completions. + +If the previously-applied actions do not generate any matches, and the +@option{-o dirnames} option was supplied to @code{complete} when the +compspec was defined, directory name completion is attempted. + +If the @option{-o plusdirs} option was supplied to @code{complete} when +the compspec was defined, directory name completion is attempted and any +matches are added to the results of the other actions. + +By default, if a compspec is found, whatever it generates is returned to +the completion code as the full set of possible completions. +The default Bash completions are not attempted, and the Readline default +of filename completion is disabled. +If the @option{-o bashdefault} option was supplied to @code{complete} when +the compspec was defined, the default Bash completions are attempted +if the compspec generates no matches. +If the @option{-o default} option was supplied to @code{complete} when the +compspec was defined, Readline's default completion will be performed +if the compspec (and, if attempted, the default Bash completions) +generate no matches. + +When a compspec indicates that directory name completion is desired, +the programmable completion functions force Readline to append a slash +to completed names which are symbolic links to directories, subject to +the value of the @var{mark-directories} Readline variable, regardless +of the setting of the @var{mark-symlinked-directories} Readline variable. + +There is some support for dynamically modifying completions. This is +most useful when used in combination with a default completion specified +with @option{-D}. It's possible for shell functions executed as completion +handlers to indicate that completion should be retried by returning an +exit status of 124. If a shell function returns 124, and changes +the compspec associated with the command on which completion is being +attempted (supplied as the first argument when the function is executed), +programmable completion restarts from the beginning, with an +attempt to find a new compspec for that command. This allows a set of +completions to be built dynamically as completion is attempted, rather than +being loaded all at once. + +For instance, assuming that there is a library of compspecs, each kept in a +file corresponding to the name of the command, the following default +completion function would load completions dynamically: + +@example +_completion_loader() +@{ + . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124 +@} +complete -D -F _completion_loader -o bashdefault -o default +@end example + +@node Programmable Completion Builtins +@section Programmable Completion Builtins +@cindex completion builtins + +Three builtin commands are available to manipulate the programmable completion +facilities: one to specify how the arguments to a particular command are to +be completed, and two to modify the completion as it is happening. + +@table @code +@item compgen +@btindex compgen +@example +@code{compgen [@var{option}] [@var{word}]} +@end example + +Generate possible completion matches for @var{word} according to +the @var{option}s, which may be any option accepted by the +@code{complete} +builtin with the exception of @option{-p} and @option{-r}, and write +the matches to the standard output. +When using the @option{-F} or @option{-C} options, the various shell variables +set by the programmable completion facilities, while available, will not +have useful values. + +The matches will be generated in the same way as if the programmable +completion code had generated them directly from a completion specification +with the same flags. +If @var{word} is specified, only those completions matching @var{word} +will be displayed. + +The return value is true unless an invalid option is supplied, or no +matches were generated. + +@item complete +@btindex complete +@example +@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}] [-G @var{globpat}] +[-W @var{wordlist}] [-F @var{function}] [-C @var{command}] [-X @var{filterpat}] +[-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]} +@code{complete -pr [-DEI] [@var{name} @dots{}]} +@end example + +Specify how arguments to each @var{name} should be completed. +If the @option{-p} option is supplied, or if no options are supplied, existing +completion specifications are printed in a way that allows them to be +reused as input. +The @option{-r} option removes a completion specification for +each @var{name}, or, if no @var{name}s are supplied, all +completion specifications. +The @option{-D} option indicates that other supplied options and actions should +apply to the ``default'' command completion; that is, completion attempted +on a command for which no completion has previously been defined. +The @option{-E} option indicates that other supplied options and actions should +apply to ``empty'' command completion; that is, completion attempted on a +blank line. +The @option{-I} option indicates that other supplied options and actions should +apply to completion on the initial non-assignment word on the line, or after a +command delimiter such as @samp{;} or @samp{|}, which is usually command +name completion. +If multiple options are supplied, the @option{-D} option takes precedence +over @option{-E}, and both take precedence over @option{-I}. +If any of @option{-D}, @option{-E}, or @option{-I} are supplied, any other +@var{name} arguments are ignored; these completions only apply to the case +specified by the option. + +The process of applying these completion specifications when word completion +is attempted is described above (@pxref{Programmable Completion}). + +Other options, if specified, have the following meanings. +The arguments to the @option{-G}, @option{-W}, and @option{-X} options +(and, if necessary, the @option{-P} and @option{-S} options) +should be quoted to protect them from expansion before the +@code{complete} builtin is invoked. + + +@table @code +@item -o @var{comp-option} +The @var{comp-option} controls several aspects of the compspec's behavior +beyond the simple generation of completions. +@var{comp-option} may be one of: + +@table @code + +@item bashdefault +Perform the rest of the default Bash completions if the compspec +generates no matches. + +@item default +Use Readline's default filename completion if the compspec generates +no matches. + +@item dirnames +Perform directory name completion if the compspec generates no matches. + +@item filenames +Tell Readline that the compspec generates filenames, so it can perform any +filename-specific processing (like adding a slash to directory names, +quoting special characters, or suppressing trailing spaces). +This option is intended to be used with shell functions specified +with @option{-F}. + +@item noquote +Tell Readline not to quote the completed words if they are filenames +(quoting filenames is the default). + +@item nosort +Tell Readline not to sort the list of possible completions alphabetically. + +@item nospace +Tell Readline not to append a space (the default) to words completed at +the end of the line. + +@item plusdirs +After any matches defined by the compspec are generated, +directory name completion is attempted and any +matches are added to the results of the other actions. + +@end table + +@item -A @var{action} +The @var{action} may be one of the following to generate a list of possible +completions: + +@table @code +@item alias +Alias names. May also be specified as @option{-a}. + +@item arrayvar +Array variable names. + +@item binding +Readline key binding names (@pxref{Bindable Readline Commands}). + +@item builtin +Names of shell builtin commands. May also be specified as @option{-b}. + +@item command +Command names. May also be specified as @option{-c}. + +@item directory +Directory names. May also be specified as @option{-d}. + +@item disabled +Names of disabled shell builtins. + +@item enabled +Names of enabled shell builtins. + +@item export +Names of exported shell variables. May also be specified as @option{-e}. + +@item file +File names. May also be specified as @option{-f}. + +@item function +Names of shell functions. + +@item group +Group names. May also be specified as @option{-g}. + +@item helptopic +Help topics as accepted by the @code{help} builtin (@pxref{Bash Builtins}). + +@item hostname +Hostnames, as taken from the file specified by the +@env{HOSTFILE} shell variable (@pxref{Bash Variables}). + +@item job +Job names, if job control is active. May also be specified as @option{-j}. + +@item keyword +Shell reserved words. May also be specified as @option{-k}. + +@item running +Names of running jobs, if job control is active. + +@item service +Service names. May also be specified as @option{-s}. + +@item setopt +Valid arguments for the @option{-o} option to the @code{set} builtin +(@pxref{The Set Builtin}). + +@item shopt +Shell option names as accepted by the @code{shopt} builtin +(@pxref{Bash Builtins}). + +@item signal +Signal names. + +@item stopped +Names of stopped jobs, if job control is active. + +@item user +User names. May also be specified as @option{-u}. + +@item variable +Names of all shell variables. May also be specified as @option{-v}. +@end table + +@item -C @var{command} +@var{command} is executed in a subshell environment, and its output is +used as the possible completions. + +@item -F @var{function} +The shell function @var{function} is executed in the current shell +environment. +When it is executed, $1 is the name of the command whose arguments are +being completed, $2 is the word being completed, and $3 is the word +preceding the word being completed, as described above +(@pxref{Programmable Completion}). +When it finishes, the possible completions are retrieved from the value +of the @env{COMPREPLY} array variable. + +@item -G @var{globpat} +The filename expansion pattern @var{globpat} is expanded to generate +the possible completions. + +@item -P @var{prefix} +@var{prefix} is added at the beginning of each possible completion +after all other options have been applied. + +@item -S @var{suffix} +@var{suffix} is appended to each possible completion +after all other options have been applied. + +@item -W @var{wordlist} +The @var{wordlist} is split using the characters in the +@env{IFS} special variable as delimiters, and each resultant word +is expanded. +The possible completions are the members of the resultant list which +match the word being completed. + +@item -X @var{filterpat} +@var{filterpat} is a pattern as used for filename expansion. +It is applied to the list of possible completions generated by the +preceding options and arguments, and each completion matching +@var{filterpat} is removed from the list. +A leading @samp{!} in @var{filterpat} negates the pattern; in this +case, any completion not matching @var{filterpat} is removed. +@end table + +The return value is true unless an invalid option is supplied, an option +other than @option{-p} or @option{-r} is supplied without a @var{name} +argument, an attempt is made to remove a completion specification for +a @var{name} for which no specification exists, or +an error occurs adding a completion specification. + +@item compopt +@btindex compopt +@example +@code{compopt} [-o @var{option}] [-DEI] [+o @var{option}] [@var{name}] +@end example +Modify completion options for each @var{name} according to the +@var{option}s, or for the currently-executing completion if no @var{name}s +are supplied. +If no @var{option}s are given, display the completion options for each +@var{name} or the current completion. +The possible values of @var{option} are those valid for the @code{complete} +builtin described above. +The @option{-D} option indicates that other supplied options should +apply to the ``default'' command completion; that is, completion attempted +on a command for which no completion has previously been defined. +The @option{-E} option indicates that other supplied options should +apply to ``empty'' command completion; that is, completion attempted on a +blank line. +The @option{-I} option indicates that other supplied options should +apply to completion on the initial non-assignment word on the line, or after a +command delimiter such as @samp{;} or @samp{|}, which is usually command +name completion. + +If multiple options are supplied, the @option{-D} option takes precedence +over @option{-E}, and both take precedence over @option{-I} + +The return value is true unless an invalid option is supplied, an attempt +is made to modify the options for a @var{name} for which no completion +specification exists, or an output error occurs. + +@end table + +@node A Programmable Completion Example +@section A Programmable Completion Example + +The most common way to obtain additional completion functionality beyond +the default actions @code{complete} and @code{compgen} provide is to use +a shell function and bind it to a particular command using @code{complete -F}. + +The following function provides completions for the @code{cd} builtin. +It is a reasonably good example of what shell functions must do when +used for completion. This function uses the word passed as @code{$2} +to determine the directory name to complete. You can also use the +@code{COMP_WORDS} array variable; the current word is indexed by the +@code{COMP_CWORD} variable. + +The function relies on the @code{complete} and @code{compgen} builtins +to do much of the work, adding only the things that the Bash @code{cd} +does beyond accepting basic directory names: +tilde expansion (@pxref{Tilde Expansion}), +searching directories in @var{$CDPATH}, which is described above +(@pxref{Bourne Shell Builtins}), +and basic support for the @code{cdable_vars} shell option +(@pxref{The Shopt Builtin}). +@code{_comp_cd} modifies the value of @var{IFS} so that it contains only +a newline to accommodate file names containing spaces and tabs -- +@code{compgen} prints the possible completions it generates one per line. + +Possible completions go into the @var{COMPREPLY} array variable, one +completion per array element. The programmable completion system retrieves +the completions from there when the function returns. + +@example +# A completion function for the cd builtin +# based on the cd completion function from the bash_completion package +_comp_cd() +@{ + local IFS=$' \t\n' # normalize IFS + local cur _skipdot _cdpath + local i j k + + # Tilde expansion, which also expands tilde to full pathname + case "$2" in + \~*) eval cur="$2" ;; + *) cur=$2 ;; + esac + + # no cdpath or absolute pathname -- straight directory completion + if [[ -z "$@{CDPATH:-@}" ]] || [[ "$cur" == @@(./*|../*|/*) ]]; then + # compgen prints paths one per line; could also use while loop + IFS=$'\n' + COMPREPLY=( $(compgen -d -- "$cur") ) + IFS=$' \t\n' + # CDPATH+directories in the current directory if not in CDPATH + else + IFS=$'\n' + _skipdot=false + # preprocess CDPATH to convert null directory names to . + _cdpath=$@{CDPATH/#:/.:@} + _cdpath=$@{_cdpath//::/:.:@} + _cdpath=$@{_cdpath/%:/:.@} + for i in $@{_cdpath//:/$'\n'@}; do + if [[ $i -ef . ]]; then _skipdot=true; fi + k="$@{#COMPREPLY[@@]@}" + for j in $( compgen -d -- "$i/$cur" ); do + COMPREPLY[k++]=$@{j#$i/@} # cut off directory + done + done + $_skipdot || COMPREPLY+=( $(compgen -d -- "$cur") ) + IFS=$' \t\n' + fi + + # variable names if appropriate shell option set and no completions + if shopt -q cdable_vars && [[ $@{#COMPREPLY[@@]@} -eq 0 ]]; then + COMPREPLY=( $(compgen -v -- "$cur") ) + fi + + return 0 +@} +@end example + +We install the completion function using the @option{-F} option to +@code{complete}: + +@example +# Tell readline to quote appropriate and append slashes to directories; +# use the bash default completion for other arguments +complete -o filenames -o nospace -o bashdefault -F _comp_cd cd +@end example + +@noindent +Since we'd like Bash and Readline to take care of some +of the other details for us, we use several other options to tell Bash +and Readline what to do. The @option{-o filenames} option tells Readline +that the possible completions should be treated as filenames, and quoted +appropriately. That option will also cause Readline to append a slash to +filenames it can determine are directories (which is why we might want to +extend @code{_comp_cd} to append a slash if we're using directories found +via @var{CDPATH}: Readline can't tell those completions are directories). +The @option{-o nospace} option tells Readline to not append a space +character to the directory name, in case we want to append to it. +The @option{-o bashdefault} option brings in the rest of the "Bash default" +completions -- possible completion that Bash adds to the default Readline +set. These include things like command name completion, variable completion +for words beginning with @samp{$} or @samp{$@{}, completions containing pathname +expansion patterns (@pxref{Filename Expansion}), and so on. + +Once installed using @code{complete}, @code{_comp_cd} will be called every +time we attempt word completion for a @code{cd} command. + +Many more examples -- an extensive collection of completions for most of +the common GNU, Unix, and Linux commands -- are available as part of the +bash_completion project. This is installed by default on many GNU/Linux +distributions. Originally written by Ian Macdonald, the project now lives +at @url{https://github.com/scop/bash-completion/}. There are ports for +other systems such as Solaris and Mac OS X. + +An older version of the bash_completion package is distributed with bash +in the @file{examples/complete} subdirectory. + +@end ifset diff --git a/utshell-0.5.0/lib/readline/doc/rluserman.texi b/utshell-0.5.0/lib/readline/doc/rluserman.texi new file mode 100644 index 00000000..6e8e848b --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/rluserman.texi @@ -0,0 +1,70 @@ +\input texinfo @c -*-texinfo-*- +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename rluserman.info +@settitle GNU Readline Library +@include version.texi + +@comment %**end of header (This is for running Texinfo on a region.) + +@copying +This manual describes the end user interface of the GNU Readline Library +(version @value{VERSION}, @value{UPDATED}), a library which aids in the +consistency of user interface across discrete programs which provide +a command line interface. + +Copyright @copyright{} 1988--2020 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the section entitled +``GNU Free Documentation License''. + +@end quotation +@end copying + +@dircategory Libraries +@direntry +* RLuserman: (rluserman). The GNU readline library User's Manual. +@end direntry + +@titlepage +@title GNU Readline Library User Interface +@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}. +@subtitle @value{UPDATED-MONTH} +@author Chet Ramey, Case Western Reserve University +@author Brian Fox, Free Software Foundation + +@page +@vskip 0pt plus 1filll +@insertcopying + +@end titlepage + +@contents + +@ifnottex +@node Top +@top GNU Readline Library + +This document describes the end user interface of the GNU Readline Library, +a utility which aids in the consistency of user interface across discrete +programs which provide a command line interface. +The Readline home page is @url{http://www.gnu.org/software/readline/}. + +@menu +* Command Line Editing:: GNU Readline User's Manual. +* GNU Free Documentation License:: License for copying this manual. +@end menu +@end ifnottex + +@include rluser.texi + +@node GNU Free Documentation License +@appendix GNU Free Documentation License + +@include fdl.texi + +@bye diff --git a/utshell-0.5.0/lib/readline/doc/version.texi b/utshell-0.5.0/lib/readline/doc/version.texi new file mode 100644 index 00000000..abb9cb6b --- /dev/null +++ b/utshell-0.5.0/lib/readline/doc/version.texi @@ -0,0 +1,10 @@ +@ignore +Copyright (C) 1988-2020 Free Software Foundation, Inc. +@end ignore + +@set EDITION 8.1 +@set VERSION 8.1 +@set UPDATED 29 October 2020 +@set UPDATED-MONTH October 2020 + +@set LASTCHANGE Thu Oct 29 16:49:01 EDT 2020 diff --git a/utshell-0.5.0/lib/readline/emacs_keymap.c b/utshell-0.5.0/lib/readline/emacs_keymap.c new file mode 100644 index 00000000..02597dad --- /dev/null +++ b/utshell-0.5.0/lib/readline/emacs_keymap.c @@ -0,0 +1,872 @@ +/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */ + +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (BUFSIZ) +#include +#endif /* !BUFSIZ */ + +#include "readline.h" + +/* An array of function pointers, one for each possible key. + If the type byte is ISKMAP, then the pointer is the address of + a keymap. */ + +KEYMAP_ENTRY_ARRAY emacs_standard_keymap = { + + /* Control keys. */ + { ISFUNC, rl_set_mark }, /* Control-@ */ + { ISFUNC, rl_beg_of_line }, /* Control-a */ + { ISFUNC, rl_backward_char }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, rl_delete }, /* Control-d */ + { ISFUNC, rl_end_of_line }, /* Control-e */ + { ISFUNC, rl_forward_char }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, rl_rubout }, /* Control-h */ + { ISFUNC, rl_complete }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, rl_clear_screen }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_get_next_history }, /* Control-n */ + { ISFUNC, rl_operate_and_get_next }, /* Control-o */ + { ISFUNC, rl_get_previous_history }, /* Control-p */ + { ISFUNC, rl_quoted_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISKMAP, (rl_command_func_t *)emacs_ctlx_keymap }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + { ISKMAP, (rl_command_func_t *)emacs_meta_keymap }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, rl_char_search }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_undo_command }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_insert }, /* SPACE */ + { ISFUNC, rl_insert }, /* ! */ + { ISFUNC, rl_insert }, /* " */ + { ISFUNC, rl_insert }, /* # */ + { ISFUNC, rl_insert }, /* $ */ + { ISFUNC, rl_insert }, /* % */ + { ISFUNC, rl_insert }, /* & */ + { ISFUNC, rl_insert }, /* ' */ + { ISFUNC, rl_insert }, /* ( */ + { ISFUNC, rl_insert }, /* ) */ + { ISFUNC, rl_insert }, /* * */ + { ISFUNC, rl_insert }, /* + */ + { ISFUNC, rl_insert }, /* , */ + { ISFUNC, rl_insert }, /* - */ + { ISFUNC, rl_insert }, /* . */ + { ISFUNC, rl_insert }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_insert }, /* 0 */ + { ISFUNC, rl_insert }, /* 1 */ + { ISFUNC, rl_insert }, /* 2 */ + { ISFUNC, rl_insert }, /* 3 */ + { ISFUNC, rl_insert }, /* 4 */ + { ISFUNC, rl_insert }, /* 5 */ + { ISFUNC, rl_insert }, /* 6 */ + { ISFUNC, rl_insert }, /* 7 */ + { ISFUNC, rl_insert }, /* 8 */ + { ISFUNC, rl_insert }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, rl_insert }, /* : */ + { ISFUNC, rl_insert }, /* ; */ + { ISFUNC, rl_insert }, /* < */ + { ISFUNC, rl_insert }, /* = */ + { ISFUNC, rl_insert }, /* > */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_insert }, /* A */ + { ISFUNC, rl_insert }, /* B */ + { ISFUNC, rl_insert }, /* C */ + { ISFUNC, rl_insert }, /* D */ + { ISFUNC, rl_insert }, /* E */ + { ISFUNC, rl_insert }, /* F */ + { ISFUNC, rl_insert }, /* G */ + { ISFUNC, rl_insert }, /* H */ + { ISFUNC, rl_insert }, /* I */ + { ISFUNC, rl_insert }, /* J */ + { ISFUNC, rl_insert }, /* K */ + { ISFUNC, rl_insert }, /* L */ + { ISFUNC, rl_insert }, /* M */ + { ISFUNC, rl_insert }, /* N */ + { ISFUNC, rl_insert }, /* O */ + { ISFUNC, rl_insert }, /* P */ + { ISFUNC, rl_insert }, /* Q */ + { ISFUNC, rl_insert }, /* R */ + { ISFUNC, rl_insert }, /* S */ + { ISFUNC, rl_insert }, /* T */ + { ISFUNC, rl_insert }, /* U */ + { ISFUNC, rl_insert }, /* V */ + { ISFUNC, rl_insert }, /* W */ + { ISFUNC, rl_insert }, /* X */ + { ISFUNC, rl_insert }, /* Y */ + { ISFUNC, rl_insert }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_insert }, /* [ */ + { ISFUNC, rl_insert }, /* \ */ + { ISFUNC, rl_insert }, /* ] */ + { ISFUNC, rl_insert }, /* ^ */ + { ISFUNC, rl_insert }, /* _ */ + { ISFUNC, rl_insert }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_insert }, /* a */ + { ISFUNC, rl_insert }, /* b */ + { ISFUNC, rl_insert }, /* c */ + { ISFUNC, rl_insert }, /* d */ + { ISFUNC, rl_insert }, /* e */ + { ISFUNC, rl_insert }, /* f */ + { ISFUNC, rl_insert }, /* g */ + { ISFUNC, rl_insert }, /* h */ + { ISFUNC, rl_insert }, /* i */ + { ISFUNC, rl_insert }, /* j */ + { ISFUNC, rl_insert }, /* k */ + { ISFUNC, rl_insert }, /* l */ + { ISFUNC, rl_insert }, /* m */ + { ISFUNC, rl_insert }, /* n */ + { ISFUNC, rl_insert }, /* o */ + { ISFUNC, rl_insert }, /* p */ + { ISFUNC, rl_insert }, /* q */ + { ISFUNC, rl_insert }, /* r */ + { ISFUNC, rl_insert }, /* s */ + { ISFUNC, rl_insert }, /* t */ + { ISFUNC, rl_insert }, /* u */ + { ISFUNC, rl_insert }, /* v */ + { ISFUNC, rl_insert }, /* w */ + { ISFUNC, rl_insert }, /* x */ + { ISFUNC, rl_insert }, /* y */ + { ISFUNC, rl_insert }, /* z */ + + /* Final punctuation. */ + { ISFUNC, rl_insert }, /* { */ + { ISFUNC, rl_insert }, /* | */ + { ISFUNC, rl_insert }, /* } */ + { ISFUNC, rl_insert }, /* ~ */ + { ISFUNC, rl_rubout }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Pure 8-bit characters (128 - 159). + These might be used in some + character sets. */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + + /* ISO Latin-1 characters (160 - 255) */ + { ISFUNC, rl_insert }, /* No-break space */ + { ISFUNC, rl_insert }, /* Inverted exclamation mark */ + { ISFUNC, rl_insert }, /* Cent sign */ + { ISFUNC, rl_insert }, /* Pound sign */ + { ISFUNC, rl_insert }, /* Currency sign */ + { ISFUNC, rl_insert }, /* Yen sign */ + { ISFUNC, rl_insert }, /* Broken bar */ + { ISFUNC, rl_insert }, /* Section sign */ + { ISFUNC, rl_insert }, /* Diaeresis */ + { ISFUNC, rl_insert }, /* Copyright sign */ + { ISFUNC, rl_insert }, /* Feminine ordinal indicator */ + { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Not sign */ + { ISFUNC, rl_insert }, /* Soft hyphen */ + { ISFUNC, rl_insert }, /* Registered sign */ + { ISFUNC, rl_insert }, /* Macron */ + { ISFUNC, rl_insert }, /* Degree sign */ + { ISFUNC, rl_insert }, /* Plus-minus sign */ + { ISFUNC, rl_insert }, /* Superscript two */ + { ISFUNC, rl_insert }, /* Superscript three */ + { ISFUNC, rl_insert }, /* Acute accent */ + { ISFUNC, rl_insert }, /* Micro sign */ + { ISFUNC, rl_insert }, /* Pilcrow sign */ + { ISFUNC, rl_insert }, /* Middle dot */ + { ISFUNC, rl_insert }, /* Cedilla */ + { ISFUNC, rl_insert }, /* Superscript one */ + { ISFUNC, rl_insert }, /* Masculine ordinal indicator */ + { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */ + { ISFUNC, rl_insert }, /* Vulgar fraction one half */ + { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */ + { ISFUNC, rl_insert }, /* Inverted questionk mark */ + { ISFUNC, rl_insert }, /* Latin capital letter a with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter a with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin capital letter ae */ + { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin capital letter e with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter e with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter i with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter i with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter o with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Multiplication sign */ + { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin capital letter u with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter u with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */ + { ISFUNC, rl_insert }, /* Latin small letter a with grave */ + { ISFUNC, rl_insert }, /* Latin small letter a with acute */ + { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin small letter ae */ + { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin small letter e with grave */ + { ISFUNC, rl_insert }, /* Latin small letter e with acute */ + { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter i with grave */ + { ISFUNC, rl_insert }, /* Latin small letter i with acute */ + { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with grave */ + { ISFUNC, rl_insert }, /* Latin small letter o with acute */ + { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Division sign */ + { ISFUNC, rl_insert }, /* Latin small letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin small letter u with grave */ + { ISFUNC, rl_insert }, /* Latin small letter u with acute */ + { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter y with acute */ + { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */ + { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */ +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY emacs_meta_keymap = { + + /* Meta keys. Just like above, but the high bit is set. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-f */ + { ISFUNC, rl_abort }, /* Meta-Control-g */ + { ISFUNC, rl_backward_kill_word }, /* Meta-Control-h */ + { ISFUNC, rl_tab_insert }, /* Meta-Control-i */ + { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */ + { ISFUNC, rl_clear_display }, /* Meta-Control-l */ + { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-q */ + { ISFUNC, rl_revert_line }, /* Meta-Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-x */ + { ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-z */ + + { ISFUNC, rl_complete }, /* Meta-Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-\ */ + { ISFUNC, rl_backward_char_search }, /* Meta-Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_set_mark }, /* Meta-SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-" */ + { ISFUNC, rl_insert_comment }, /* Meta-# */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-$ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-% */ + { ISFUNC, rl_tilde_expand }, /* Meta-& */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-) */ + { ISFUNC, rl_insert_completions }, /* Meta-* */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-+ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-, */ + { ISFUNC, rl_digit_argument }, /* Meta-- */ + { ISFUNC, rl_yank_last_arg}, /* Meta-. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-/ */ + + /* Regular digits. */ + { ISFUNC, rl_digit_argument }, /* Meta-0 */ + { ISFUNC, rl_digit_argument }, /* Meta-1 */ + { ISFUNC, rl_digit_argument }, /* Meta-2 */ + { ISFUNC, rl_digit_argument }, /* Meta-3 */ + { ISFUNC, rl_digit_argument }, /* Meta-4 */ + { ISFUNC, rl_digit_argument }, /* Meta-5 */ + { ISFUNC, rl_digit_argument }, /* Meta-6 */ + { ISFUNC, rl_digit_argument }, /* Meta-7 */ + { ISFUNC, rl_digit_argument }, /* Meta-8 */ + { ISFUNC, rl_digit_argument }, /* Meta-9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-: */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-; */ + { ISFUNC, rl_beginning_of_history }, /* Meta-< */ + { ISFUNC, rl_possible_completions }, /* Meta-= */ + { ISFUNC, rl_end_of_history }, /* Meta-> */ + { ISFUNC, rl_possible_completions }, /* Meta-? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-@ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-A */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-B */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-C */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-D */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-E */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-F */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-G */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-H */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-I */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-J */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-K */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-L */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-M */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-N */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-O */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-P */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Q */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-R */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-S */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-T */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-U */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-V */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-W */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-X */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Y */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */ + { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-^ */ + { ISFUNC, rl_yank_last_arg }, /* Meta-_ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-a */ + { ISFUNC, rl_backward_word }, /* Meta-b */ + { ISFUNC, rl_capitalize_word }, /* Meta-c */ + { ISFUNC, rl_kill_word }, /* Meta-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-e */ + { ISFUNC, rl_forward_word }, /* Meta-f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-k */ + { ISFUNC, rl_downcase_word }, /* Meta-l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-m */ + { ISFUNC, rl_noninc_forward_search }, /* Meta-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */ + { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-q */ + { ISFUNC, rl_revert_line }, /* Meta-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-s */ + { ISFUNC, rl_transpose_words }, /* Meta-t */ + { ISFUNC, rl_upcase_word }, /* Meta-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-x */ + { ISFUNC, rl_yank_pop }, /* Meta-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-{ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-| */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-} */ + { ISFUNC, rl_tilde_expand }, /* Meta-~ */ + { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = { + + /* Control keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */ + { ISFUNC, rl_re_read_init_file }, /* Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */ + { ISFUNC, rl_undo_command }, /* Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */ + { ISFUNC, rl_exchange_point_and_mark }, /* Control-x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* # */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* % */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, rl_start_kbd_macro }, /* ( */ + { ISFUNC, rl_end_kbd_macro }, /* ) */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* * */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* + */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* , */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* - */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* . */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* / */ + + /* Regular digits. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 0 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 1 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 2 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 3 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 4 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 5 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 6 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 7 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 8 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* A */ + { ISFUNC, rl_do_lowercase_version }, /* B */ + { ISFUNC, rl_do_lowercase_version }, /* C */ + { ISFUNC, rl_do_lowercase_version }, /* D */ + { ISFUNC, rl_do_lowercase_version }, /* E */ + { ISFUNC, rl_do_lowercase_version }, /* F */ + { ISFUNC, rl_do_lowercase_version }, /* G */ + { ISFUNC, rl_do_lowercase_version }, /* H */ + { ISFUNC, rl_do_lowercase_version }, /* I */ + { ISFUNC, rl_do_lowercase_version }, /* J */ + { ISFUNC, rl_do_lowercase_version }, /* K */ + { ISFUNC, rl_do_lowercase_version }, /* L */ + { ISFUNC, rl_do_lowercase_version }, /* M */ + { ISFUNC, rl_do_lowercase_version }, /* N */ + { ISFUNC, rl_do_lowercase_version }, /* O */ + { ISFUNC, rl_do_lowercase_version }, /* P */ + { ISFUNC, rl_do_lowercase_version }, /* Q */ + { ISFUNC, rl_do_lowercase_version }, /* R */ + { ISFUNC, rl_do_lowercase_version }, /* S */ + { ISFUNC, rl_do_lowercase_version }, /* T */ + { ISFUNC, rl_do_lowercase_version }, /* U */ + { ISFUNC, rl_do_lowercase_version }, /* V */ + { ISFUNC, rl_do_lowercase_version }, /* W */ + { ISFUNC, rl_do_lowercase_version }, /* X */ + { ISFUNC, rl_do_lowercase_version }, /* Y */ + { ISFUNC, rl_do_lowercase_version }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* d */ + { ISFUNC, rl_call_last_kbd_macro }, /* e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */ + { ISFUNC, rl_backward_kill_line }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; diff --git a/utshell-0.5.0/lib/readline/examples/Inputrc b/utshell-0.5.0/lib/readline/examples/Inputrc new file mode 100644 index 00000000..a358bc47 --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/Inputrc @@ -0,0 +1,81 @@ +# My ~/.inputrc file is in -*- text -*- for easy editing with Emacs. +# +# Notice the various bindings which are conditionalized depending +# on which program is running, or what terminal is active. +# + +# Copyright (C) 1989-2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# In all programs, all terminals, make sure this is bound. +"\C-x\C-r": re-read-init-file + +# Hp terminals (and some others) have ugly default behaviour for C-h. +"\C-h": backward-delete-char +"\e\C-h": backward-kill-word +"\C-xd": dump-functions + +# In xterm windows, make the arrow keys do the right thing. +$if TERM=xterm +"\e[A": previous-history +"\e[B": next-history +"\e[C": forward-char +"\e[D": backward-char + +# alternate arrow key prefix +"\eOA": previous-history +"\eOB": next-history +"\eOC": forward-char +"\eOD": backward-char + +# Under Xterm in Bash, we bind local Function keys to do something useful. +$if Bash +"\e[11~": "Function Key 1" +"\e[12~": "Function Key 2" +"\e[13~": "Function Key 3" +"\e[14~": "Function Key 4" +"\e[15~": "Function Key 5" + +# I know the following escape sequence numbers are 1 greater than +# the function key. Don't ask me why, I didn't design the xterm terminal. +"\e[17~": "Function Key 6" +"\e[18~": "Function Key 7" +"\e[19~": "Function Key 8" +"\e[20~": "Function Key 9" +"\e[21~": "Function Key 10" +$endif +$endif + +# For Bash, all terminals, add some Bash specific hacks. +$if Bash +"\C-xv": show-bash-version +"\C-x\C-e": shell-expand-line + +# Here is one for editing my path. +"\C-xp": "$PATH\C-x\C-e\C-e\"\C-aPATH=\":\C-b" + +# Make C-x r read my mail in emacs. +# "\C-xr": "emacs -f rmail\C-j" +$endif + +# For FTP, different hacks: +$if Ftp +"\C-xg": "get \M-?" +"\C-xt": "put \M-?" +"\M-.": yank-last-arg +$endif + +" ": self-insert diff --git a/utshell-0.5.0/lib/readline/examples/Makefile b/utshell-0.5.0/lib/readline/examples/Makefile new file mode 100644 index 00000000..2df22407 --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/Makefile @@ -0,0 +1,44 @@ +# This is the Makefile for the examples subdirectory of readline. -*- text -*- +# +# Copyright (C) 1994 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +EXECUTABLES = fileman rltest rl +CFLAGS = -g -I../.. -I.. -DREADLINE_LIBRARY +LDFLAGS = -g -L.. + +.c.o: + $(CC) $(CFLAGS) -c $< + +all: $(EXECUTABLES) + + +rl: rl.o + $(CC) $(LDFLAGS) -o $@ rl.o -lreadline -ltermcap + +fileman: fileman.o + $(CC) $(LDFLAGS) -o $@ fileman.o -lreadline -ltermcap + +rltest: rltest.o + $(CC) $(LDFLAGS) -o $@ rltest.o -lreadline -ltermcap + +rlcat: rlcat.o + $(CC) $(LDFLAGS) -o $@ rlcat.o -lreadline -ltermcap + +fileman.o: fileman.c +rltest.o: rltest.c +rl.o: rl.c +rlcat.o: rlcat.c diff --git a/utshell-0.5.0/lib/readline/examples/excallback.c b/utshell-0.5.0/lib/readline/examples/excallback.c new file mode 100644 index 00000000..4206acfc --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/excallback.c @@ -0,0 +1,196 @@ +/* +From: Jeff Solomon +Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT) +To: chet@po.cwru.edu +Subject: new readline example +Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU> + +Chet, + +I've been using readline 4.0. Specifically, I've been using the perl +version Term::ReadLine::Gnu. It works great. + +Anyway, I've been playing around the alternate interface and I wanted +to contribute a little C program, callback.c, to you that you could +use as an example of the alternate interface in the /examples +directory of the readline distribution. + +My example shows how, using the alternate interface, you can +interactively change the prompt (which is very nice imo). Also, I +point out that you must roll your own terminal setting when using the +alternate interface because readline depreps (using your parlance) the +terminal while in the user callback. I try to demostrate what I mean +with an example. I've included the program below. + +To compile, I just put the program in the examples directory and made +the appropriate changes to the EXECUTABLES and OBJECTS line and added +an additional target 'callback'. + +I compiled on my Sun Solaris2.6 box using Sun's cc. + +Let me know what you think. + +Jeff +*/ +/* +Copyright (C) 1999 Jeff Solomon +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +#include +#include /* xxx - should make this more general */ + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif + +/* This little examples demonstrates the alternate interface to using readline. + * In the alternate interface, the user maintains control over program flow and + * only calls readline when STDIN is readable. Using the alternate interface, + * you can do anything else while still using readline (like talking to a + * network or another program) without blocking. + * + * Specifically, this program highlights two importants features of the + * alternate interface. The first is the ability to interactively change the + * prompt, which can't be done using the regular interface since rl_prompt is + * read-only. + * + * The second feature really highlights a subtle point when using the alternate + * interface. That is, readline will not alter the terminal when inside your + * callback handler. So let's so, your callback executes a user command that + * takes a non-trivial amount of time to complete (seconds). While your + * executing the command, the user continues to type keystrokes and expects them + * to be re-echoed on the new prompt when it returns. Unfortunately, the default + * terminal configuration doesn't do this. After the prompt returns, the user + * must hit one additional keystroke and then will see all of his previous + * keystrokes. To illustrate this, compile and run this program. Type "sleep" at + * the prompt and then type "bar" before the prompt returns (you have 3 + * seconds). Notice how "bar" is re-echoed on the prompt after the prompt + * returns? This is what you expect to happen. Now comment out the 4 lines below + * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do + * the same thing. When the prompt returns, you should not see "bar". Now type + * "f", see how "barf" magically appears? This behavior is un-expected and not + * desired. + */ + +void process_line(char *line); +int change_prompt(void); +char *get_prompt(void); + +int prompt = 1; +char prompt_buf[40], line_buf[256]; +tcflag_t old_lflag; +cc_t old_vtime; +struct termios term; + +int +main() +{ + fd_set fds; + + /* Adjust the terminal slightly before the handler is installed. Disable + * canonical mode processing and set the input character time flag to be + * non-blocking. + */ + if( tcgetattr(STDIN_FILENO, &term) < 0 ) { + perror("tcgetattr"); + exit(1); + } + old_lflag = term.c_lflag; + old_vtime = term.c_cc[VTIME]; + term.c_lflag &= ~ICANON; + term.c_cc[VTIME] = 1; + /* COMMENT LINE BELOW - see above */ + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + + rl_add_defun("change-prompt", change_prompt, CTRL('t')); + rl_callback_handler_install(get_prompt(), process_line); + + while(1) { + FD_ZERO(&fds); + FD_SET(fileno(stdin), &fds); + + if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) { + perror("select"); + exit(1); + } + + if( FD_ISSET(fileno(stdin), &fds) ) { + rl_callback_read_char(); + } + } +} + +void +process_line(char *line) +{ + if( line == NULL ) { + fprintf(stderr, "\n", line); + + /* reset the old terminal setting before exiting */ + term.c_lflag = old_lflag; + term.c_cc[VTIME] = old_vtime; + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + exit(0); + } + + if( strcmp(line, "sleep") == 0 ) { + sleep(3); + } else { + fprintf(stderr, "|%s|\n", line); + } + + free (line); +} + +int +change_prompt(void) +{ + /* toggle the prompt variable */ + prompt = !prompt; + + /* save away the current contents of the line */ + strcpy(line_buf, rl_line_buffer); + + /* install a new handler which will change the prompt and erase the current line */ + rl_callback_handler_install(get_prompt(), process_line); + + /* insert the old text on the new line */ + rl_insert_text(line_buf); + + /* redraw the current line - this is an undocumented function. It invokes the + * redraw-current-line command. + */ + rl_refresh_line(0, 0); +} + +char * +get_prompt(void) +{ + /* The prompts can even be different lengths! */ + sprintf(prompt_buf, "%s", + prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> "); + return prompt_buf; +} diff --git a/utshell-0.5.0/lib/readline/examples/fileman.c b/utshell-0.5.0/lib/readline/examples/fileman.c new file mode 100644 index 00000000..2a8b097a --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/fileman.c @@ -0,0 +1,506 @@ +/* fileman.c - file manager example for readline library. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library for + reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +/* fileman.c -- A tiny application which demonstrates how to use the + GNU Readline library. This application interactively allows users + to manipulate files and their modes. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#ifdef HAVE_SYS_FILE_H +# include +#endif +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#ifdef HAVE_STDLIB_H +# include +#endif + +#include + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern char *xmalloc PARAMS((size_t)); + +void initialize_readline PARAMS((void)); +void too_dangerous PARAMS((char *)); + +int execute_line PARAMS((char *)); +int valid_argument PARAMS((char *, char *)); + +/* The names of functions that actually do the manipulation. */ +int com_list PARAMS((char *)); +int com_view PARAMS((char *)); +int com_rename PARAMS((char *)); +int com_stat PARAMS((char *)); +int com_pwd PARAMS((char *)); +int com_delete PARAMS((char *)); +int com_help PARAMS((char *)); +int com_cd PARAMS((char *)); +int com_quit PARAMS((char *)); + +/* A structure which contains information on the commands this program + can understand. */ + +typedef struct { + char *name; /* User printable name of the function. */ + rl_icpfunc_t *func; /* Function to call to do the job. */ + char *doc; /* Documentation for this function. */ +} COMMAND; + +COMMAND commands[] = { + { "cd", com_cd, "Change to directory DIR" }, + { "delete", com_delete, "Delete FILE" }, + { "help", com_help, "Display this text" }, + { "?", com_help, "Synonym for `help'" }, + { "list", com_list, "List files in DIR" }, + { "ls", com_list, "Synonym for `list'" }, + { "pwd", com_pwd, "Print the current working directory" }, + { "quit", com_quit, "Quit using Fileman" }, + { "rename", com_rename, "Rename FILE to NEWNAME" }, + { "stat", com_stat, "Print out statistics on FILE" }, + { "view", com_view, "View the contents of FILE" }, + { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } +}; + +/* Forward declarations. */ +char *stripwhite (); +COMMAND *find_command (); + +/* The name of this program, as taken from argv[0]. */ +char *progname; + +/* When non-zero, this global means the user is done using this program. */ +int done; + +char * +dupstr (s) + char *s; +{ + char *r; + + r = xmalloc (strlen (s) + 1); + strcpy (r, s); + return (r); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *line, *s; + + progname = argv[0]; + + initialize_readline (); /* Bind our completer. */ + + /* Loop reading and executing lines until the user quits. */ + for ( ; done == 0; ) + { + line = readline ("FileMan: "); + + if (!line) + break; + + /* Remove leading and trailing whitespace from the line. + Then, if there is anything left, add it to the history list + and execute it. */ + s = stripwhite (line); + + if (*s) + { + add_history (s); + execute_line (s); + } + + free (line); + } + exit (0); +} + +/* Execute a command line. */ +int +execute_line (line) + char *line; +{ + register int i; + COMMAND *command; + char *word; + + /* Isolate the command word. */ + i = 0; + while (line[i] && whitespace (line[i])) + i++; + word = line + i; + + while (line[i] && !whitespace (line[i])) + i++; + + if (line[i]) + line[i++] = '\0'; + + command = find_command (word); + + if (!command) + { + fprintf (stderr, "%s: No such command for FileMan.\n", word); + return (-1); + } + + /* Get argument to command, if any. */ + while (whitespace (line[i])) + i++; + + word = line + i; + + /* Call the function. */ + return ((*(command->func)) (word)); +} + +/* Look up NAME as the name of a command, and return a pointer to that + command. Return a NULL pointer if NAME isn't a command name. */ +COMMAND * +find_command (name) + char *name; +{ + register int i; + + for (i = 0; commands[i].name; i++) + if (strcmp (name, commands[i].name) == 0) + return (&commands[i]); + + return ((COMMAND *)NULL); +} + +/* Strip whitespace from the start and end of STRING. Return a pointer + into STRING. */ +char * +stripwhite (string) + char *string; +{ + register char *s, *t; + + for (s = string; whitespace (*s); s++) + ; + + if (*s == 0) + return (s); + + t = s + strlen (s) - 1; + while (t > s && whitespace (*t)) + t--; + *++t = '\0'; + + return s; +} + +/* **************************************************************** */ +/* */ +/* Interface to Readline Completion */ +/* */ +/* **************************************************************** */ + +char *command_generator PARAMS((const char *, int)); +char **fileman_completion PARAMS((const char *, int, int)); + +/* Tell the GNU Readline library how to complete. We want to try to complete + on command names if this is the first word in the line, or on filenames + if not. */ +void +initialize_readline () +{ + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "FileMan"; + + /* Tell the completer that we want a crack first. */ + rl_attempted_completion_function = fileman_completion; +} + +/* Attempt to complete on the contents of TEXT. START and END bound the + region of rl_line_buffer that contains the word to complete. TEXT is + the word to complete. We can use the entire contents of rl_line_buffer + in case we want to do some simple parsing. Return the array of matches, + or NULL if there aren't any. */ +char ** +fileman_completion (text, start, end) + const char *text; + int start, end; +{ + char **matches; + + matches = (char **)NULL; + + /* If this word is at the start of the line, then it is a command + to complete. Otherwise it is the name of a file in the current + directory. */ + if (start == 0) + matches = rl_completion_matches (text, command_generator); + + return (matches); +} + +/* Generator function for command completion. STATE lets us know whether + to start from scratch; without any state (i.e. STATE == 0), then we + start at the top of the list. */ +char * +command_generator (text, state) + const char *text; + int state; +{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + /* Return the next name which partially matches from the command list. */ + while (name = commands[list_index].name) + { + list_index++; + + if (strncmp (name, text, len) == 0) + return (dupstr(name)); + } + + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +/* **************************************************************** */ +/* */ +/* FileMan Commands */ +/* */ +/* **************************************************************** */ + +/* String to pass to system (). This is for the LIST, VIEW and RENAME + commands. */ +static char syscom[1024]; + +/* List the file(s) named in arg. */ +int +com_list (arg) + char *arg; +{ + if (!arg) + arg = ""; + + sprintf (syscom, "ls -FClg %s", arg); + return (system (syscom)); +} + +int +com_view (arg) + char *arg; +{ + if (!valid_argument ("view", arg)) + return 1; + +#if defined (__MSDOS__) + /* more.com doesn't grok slashes in pathnames */ + sprintf (syscom, "less %s", arg); +#else + sprintf (syscom, "more %s", arg); +#endif + return (system (syscom)); +} + +int +com_rename (arg) + char *arg; +{ + too_dangerous ("rename"); + return (1); +} + +int +com_stat (arg) + char *arg; +{ + struct stat finfo; + + if (!valid_argument ("stat", arg)) + return (1); + + if (stat (arg, &finfo) == -1) + { + perror (arg); + return (1); + } + + printf ("Statistics for `%s':\n", arg); + + printf ("%s has %d link%s, and is %lu byte%s in length.\n", + arg, + finfo.st_nlink, + (finfo.st_nlink == 1) ? "" : "s", + (unsigned long)finfo.st_size, + (finfo.st_size == 1) ? "" : "s"); + printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); + printf (" Last access at: %s", ctime (&finfo.st_atime)); + printf (" Last modified at: %s", ctime (&finfo.st_mtime)); + return (0); +} + +int +com_delete (arg) + char *arg; +{ + too_dangerous ("delete"); + return (1); +} + +/* Print out help for ARG, or for all of the commands if ARG is + not present. */ +int +com_help (arg) + char *arg; +{ + register int i; + int printed = 0; + + for (i = 0; commands[i].name; i++) + { + if (!*arg || (strcmp (arg, commands[i].name) == 0)) + { + printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); + printed++; + } + } + + if (!printed) + { + printf ("No commands match `%s'. Possibilities are:\n", arg); + + for (i = 0; commands[i].name; i++) + { + /* Print in six columns. */ + if (printed == 6) + { + printed = 0; + printf ("\n"); + } + + printf ("%s\t", commands[i].name); + printed++; + } + + if (printed) + printf ("\n"); + } + return (0); +} + +/* Change to the directory ARG. */ +int +com_cd (arg) + char *arg; +{ + if (chdir (arg) == -1) + { + perror (arg); + return 1; + } + + com_pwd (""); + return (0); +} + +/* Print out the current working directory. */ +int +com_pwd (ignore) + char *ignore; +{ + char dir[1024], *s; + + s = getcwd (dir, sizeof(dir) - 1); + if (s == 0) + { + printf ("Error getting pwd: %s\n", dir); + return 1; + } + + printf ("Current directory is %s\n", dir); + return 0; +} + +/* The user wishes to quit using this program. Just set DONE non-zero. */ +int +com_quit (arg) + char *arg; +{ + done = 1; + return (0); +} + +/* Function which tells you that you can't do this. */ +void +too_dangerous (caller) + char *caller; +{ + fprintf (stderr, + "%s: Too dangerous for me to distribute. Write it yourself.\n", + caller); +} + +/* Return non-zero if ARG is a valid argument for CALLER, else print + an error message and return zero. */ +int +valid_argument (caller, arg) + char *caller, *arg; +{ + if (!arg || !*arg) + { + fprintf (stderr, "%s: Argument required.\n", caller); + return (0); + } + + return (1); +} diff --git a/utshell-0.5.0/lib/readline/examples/histexamp.c b/utshell-0.5.0/lib/readline/examples/histexamp.c new file mode 100644 index 00000000..3b43674f --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/histexamp.c @@ -0,0 +1,125 @@ +/* histexamp.c - history library example program. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library for + reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#include + +#ifdef READLINE_LIBRARY +# include "history.h" +#else +# include +#endif + +#include + +main (argc, argv) + int argc; + char **argv; +{ + char line[1024], *t; + int len, done; + + line[0] = 0; + done = 0; + + using_history (); + while (!done) + { + printf ("history$ "); + fflush (stdout); + t = fgets (line, sizeof (line) - 1, stdin); + if (t && *t) + { + len = strlen (t); + if (t[len - 1] == '\n') + t[len - 1] = '\0'; + } + + if (!t) + strcpy (line, "quit"); + + if (line[0]) + { + char *expansion; + int result; + + using_history (); + + result = history_expand (line, &expansion); + if (result) + fprintf (stderr, "%s\n", expansion); + + if (result < 0 || result == 2) + { + free (expansion); + continue; + } + + add_history (expansion); + strncpy (line, expansion, sizeof (line) - 1); + free (expansion); + } + + if (strcmp (line, "quit") == 0) + done = 1; + else if (strcmp (line, "save") == 0) + write_history ("history_file"); + else if (strcmp (line, "read") == 0) + read_history ("history_file"); + else if (strcmp (line, "list") == 0) + { + register HIST_ENTRY **the_list; + register int i; + time_t tt; + char timestr[128]; + + the_list = history_list (); + if (the_list) + for (i = 0; the_list[i]; i++) + { + tt = history_get_time (the_list[i]); + if (tt) + strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt)); + else + strcpy (timestr, "??"); + printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line); + } + } + else if (strncmp (line, "delete", 6) == 0) + { + int which; + if ((sscanf (line + 6, "%d", &which)) == 1) + { + HIST_ENTRY *entry = remove_history (which); + if (!entry) + fprintf (stderr, "No such entry %d\n", which); + else + { + free (entry->line); + free (entry); + } + } + else + { + fprintf (stderr, "non-numeric arg given to `delete'\n"); + } + } + } +} diff --git a/utshell-0.5.0/lib/readline/examples/manexamp.c b/utshell-0.5.0/lib/readline/examples/manexamp.c new file mode 100644 index 00000000..351c6285 --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/manexamp.c @@ -0,0 +1,111 @@ +/* manexamp.c -- The examples which appear in the documentation are here. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library for + reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#include +#include + +/* **************************************************************** */ +/* */ +/* How to Emulate gets () */ +/* */ +/* **************************************************************** */ + +/* A static variable for holding the line. */ +static char *line_read = (char *)NULL; + +/* Read a string, and return a pointer to it. Returns NULL on EOF. */ +char * +rl_gets () +{ + /* If the buffer has already been allocated, return the memory + to the free pool. */ + if (line_read) + { + free (line_read); + line_read = (char *)NULL; + } + + /* Get a line from the user. */ + line_read = readline (""); + + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) + add_history (line_read); + + return (line_read); +} + +/* **************************************************************** */ +/* */ +/* Writing a Function to be Called by Readline. */ +/* */ +/* **************************************************************** */ + +/* Invert the case of the COUNT following characters. */ +invert_case_line (count, key) + int count, key; +{ + register int start, end; + + start = rl_point; + + if (count < 0) + { + direction = -1; + count = -count; + } + else + direction = 1; + + /* Find the end of the range to modify. */ + end = start + (count * direction); + + /* Force it to be within range. */ + if (end > rl_end) + end = rl_end; + else if (end < 0) + end = -1; + + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + if (start == end) + return; + + /* Tell readline that we are modifying the line, so save the undo + information. */ + rl_modifying (start, end); + + for (; start != end; start += direction) + { + if (_rl_uppercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]); + else if (_rl_lowercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]); + } + + /* Move point to on top of the last character changed. */ + rl_point = end - direction; +} diff --git a/utshell-0.5.0/lib/readline/examples/rl-callbacktest.c b/utshell-0.5.0/lib/readline/examples/rl-callbacktest.c new file mode 100644 index 00000000..0f00e57c --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/rl-callbacktest.c @@ -0,0 +1,90 @@ +/* Standard include files. stdio.h is required. */ +#include +#include +#include + +/* Used for select(2) */ +#include +#include + +#include +#include + +/* Standard readline include files. */ +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int errno; + +static void cb_linehandler (char *); + +int running; +const char *prompt = "rltest$ "; + +/* Callback function called for each line when accept-line executed, EOF + seen, or EOF character read. This sets a flag and returns; it could + also call exit(3). */ +static void +cb_linehandler (char *line) +{ + /* Can use ^D (stty eof) or `exit' to exit. */ + if (line == NULL || strcmp (line, "exit") == 0) + { + if (line == 0) + printf ("\n"); + printf ("exit\n"); + /* This function needs to be called to reset the terminal settings, + and calling it from the line handler keeps one extra prompt from + being displayed. */ + rl_callback_handler_remove (); + + running = 0; + } + else + { + if (*line) + add_history (line); + printf ("input line: %s\n", line); + free (line); + } +} + +int +main (int c, char **v) +{ + fd_set fds; + int r; + + /* Install the line handler. */ + rl_callback_handler_install (prompt, cb_linehandler); + + /* Enter a simple event loop. This waits until something is available + to read on readline's input stream (defaults to standard input) and + calls the builtin character read callback to read it. It does not + have to modify the user's terminal settings. */ + running = 1; + while (running) + { + FD_ZERO (&fds); + FD_SET (fileno (rl_instream), &fds); + + r = select (FD_SETSIZE, &fds, NULL, NULL, NULL); + if (r < 0 && errno != EINTR) + { + perror ("rltest: select"); + rl_callback_handler_remove (); + break; + } + + if (FD_ISSET (fileno (rl_instream), &fds)) + rl_callback_read_char (); + } + + printf ("rltest: Event loop has exited\n"); + return 0; +} diff --git a/utshell-0.5.0/lib/readline/examples/rl.c b/utshell-0.5.0/lib/readline/examples/rl.c new file mode 100644 index 00000000..a5cf276c --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/rl.c @@ -0,0 +1,158 @@ +/* + * rl - command-line interface to read a line from the standard input + * (or another fd) using readline. + * + * usage: rl [-p prompt] [-u unit] [-d default] [-n nchars] + */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library for + reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#if defined (READLINE_LIBRARY) +# include "posixstat.h" +# include "readline.h" +# include "history.h" +#else +# include +# include +# include +#endif + +extern int optind; +extern char *optarg; + +#if !defined (strchr) && !defined (__STDC__) +extern char *strrchr(); +#endif + +static char *progname; +static char *deftext; + +static int +set_deftext () +{ + if (deftext) + { + rl_insert_text (deftext); + deftext = (char *)NULL; + rl_startup_hook = (rl_hook_func_t *)NULL; + } + return 0; +} + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n", + progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp, *prompt; + struct stat sb; + int opt, fd, nch; + FILE *ifp; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + /* defaults */ + prompt = "readline$ "; + fd = nch = 0; + deftext = (char *)0; + + while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF) + { + switch (opt) + { + case 'p': + prompt = optarg; + break; + case 'u': + fd = atoi(optarg); + if (fd < 0) + { + fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg); + exit (2); + } + break; + case 'd': + deftext = optarg; + break; + case 'n': + nch = atoi(optarg); + if (nch < 0) + { + fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg); + exit (2); + } + break; + default: + usage (); + exit (2); + } + } + + if (fd != 0) + { + if (fstat (fd, &sb) < 0) + { + fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd); + exit (1); + } + ifp = fdopen (fd, "r"); + rl_instream = ifp; + } + + if (deftext && *deftext) + rl_startup_hook = set_deftext; + + if (nch > 0) + rl_num_chars_to_read = nch; + + temp = readline (prompt); + + /* Test for EOF. */ + if (temp == 0) + exit (1); + + printf ("%s\n", temp); + exit (0); +} diff --git a/utshell-0.5.0/lib/readline/examples/rlcat.c b/utshell-0.5.0/lib/readline/examples/rlcat.c new file mode 100644 index 00000000..b4942413 --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/rlcat.c @@ -0,0 +1,179 @@ +/* + * rlcat - cat(1) using readline + * + * usage: rlcat + */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library for + reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include "posixstat.h" + +#include +#include +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#ifndef errno +extern int errno; +#endif + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int optind; +extern char *optarg; + +static int stdcat(); + +static char *progname; +static int vflag; + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp; + int opt, Vflag, Nflag; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + vflag = Vflag = Nflag = 0; + while ((opt = getopt(argc, argv, "vEVN")) != EOF) + { + switch (opt) + { + case 'v': + vflag = 1; + break; + case 'V': + Vflag = 1; + break; + case 'E': + Vflag = 0; + break; + case 'N': + Nflag = 1; + break; + default: + usage (); + exit (2); + } + } + + argc -= optind; + argv += optind; + + if (isatty(0) == 0 || argc || Nflag) + return stdcat(argc, argv); + + rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs"); + while (temp = readline ("")) + { + if (*temp) + add_history (temp); + printf ("%s\n", temp); + } + + return (ferror (stdout)); +} + +static int +fcopy(fp) + FILE *fp; +{ + int c; + char *x; + + while ((c = getc(fp)) != EOF) + { + if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0) + { + x = rl_untranslate_keyseq (c); + if (fputs (x, stdout) == EOF) + return 1; + } + else if (putchar (c) == EOF) + return 1; + } + return (ferror (stdout)); +} + +int +stdcat (argc, argv) + int argc; + char **argv; +{ + int i, fd, r; + char *s; + FILE *fp; + + if (argc == 0) + return (fcopy(stdin)); + + for (i = 0, r = 1; i < argc; i++) + { + if (*argv[i] == '-' && argv[i][1] == 0) + fp = stdin; + else + { + fp = fopen (argv[i], "r"); + if (fp == 0) + { + fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno)); + continue; + } + } + r = fcopy (fp); + if (fp != stdin) + fclose(fp); + } + return r; +} diff --git a/utshell-0.5.0/lib/readline/examples/rltest.c b/utshell-0.5.0/lib/readline/examples/rltest.c new file mode 100644 index 00000000..65abe87c --- /dev/null +++ b/utshell-0.5.0/lib/readline/examples/rltest.c @@ -0,0 +1,93 @@ +/* **************************************************************** */ +/* */ +/* Testing Readline */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library for + reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern HIST_ENTRY **history_list (); + +int +main () +{ + char *temp, *prompt; + int done; + + temp = (char *)NULL; + prompt = "readline$ "; + done = 0; + + while (!done) + { + temp = readline (prompt); + + /* Test for EOF. */ + if (!temp) + exit (1); + + /* If there is anything on the line, print it and remember it. */ + if (*temp) + { + fprintf (stderr, "%s\r\n", temp); + add_history (temp); + } + + /* Check for `command' that we handle. */ + if (strcmp (temp, "quit") == 0) + done = 1; + + if (strcmp (temp, "list") == 0) + { + HIST_ENTRY **list; + register int i; + + list = history_list (); + if (list) + { + for (i = 0; list[i]; i++) + fprintf (stderr, "%d: %s\r\n", i, list[i]->line); + } + } + free (temp); + } + exit (0); +} diff --git a/utshell-0.5.0/lib/readline/funmap.c b/utshell-0.5.0/lib/readline/funmap.c new file mode 100644 index 00000000..eca49a3e --- /dev/null +++ b/utshell-0.5.0/lib/readline/funmap.c @@ -0,0 +1,271 @@ +/* funmap.c -- attach names to functions. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if !defined (BUFSIZ) +#include +#endif /* BUFSIZ */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "rlconf.h" +#include "readline.h" + +#include "xmalloc.h" + +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +extern int _rl_qsort_string_compare PARAMS((char **, char **)); + +FUNMAP **funmap; +static int funmap_size; +static int funmap_entry; + +/* After initializing the function map, this is the index of the first + program specific function. */ +int funmap_program_specific_entry_start; + +static const FUNMAP default_funmap[] = { + { "abort", rl_abort }, + { "accept-line", rl_newline }, + { "arrow-key-prefix", rl_arrow_keys }, + { "backward-byte", rl_backward_byte }, + { "backward-char", rl_backward_char }, + { "backward-delete-char", rl_rubout }, + { "backward-kill-line", rl_backward_kill_line }, + { "backward-kill-word", rl_backward_kill_word }, + { "backward-word", rl_backward_word }, + { "beginning-of-history", rl_beginning_of_history }, + { "beginning-of-line", rl_beg_of_line }, + { "bracketed-paste-begin", rl_bracketed_paste_begin }, + { "call-last-kbd-macro", rl_call_last_kbd_macro }, + { "capitalize-word", rl_capitalize_word }, + { "character-search", rl_char_search }, + { "character-search-backward", rl_backward_char_search }, + { "clear-display", rl_clear_display }, + { "clear-screen", rl_clear_screen }, + { "complete", rl_complete }, + { "copy-backward-word", rl_copy_backward_word }, + { "copy-forward-word", rl_copy_forward_word }, + { "copy-region-as-kill", rl_copy_region_to_kill }, + { "delete-char", rl_delete }, + { "delete-char-or-list", rl_delete_or_show_completions }, + { "delete-horizontal-space", rl_delete_horizontal_space }, + { "digit-argument", rl_digit_argument }, + { "do-lowercase-version", rl_do_lowercase_version }, + { "downcase-word", rl_downcase_word }, + { "dump-functions", rl_dump_functions }, + { "dump-macros", rl_dump_macros }, + { "dump-variables", rl_dump_variables }, + { "emacs-editing-mode", rl_emacs_editing_mode }, + { "end-kbd-macro", rl_end_kbd_macro }, + { "end-of-history", rl_end_of_history }, + { "end-of-line", rl_end_of_line }, + { "exchange-point-and-mark", rl_exchange_point_and_mark }, + { "forward-backward-delete-char", rl_rubout_or_delete }, + { "forward-byte", rl_forward_byte }, + { "forward-char", rl_forward_char }, + { "forward-search-history", rl_forward_search_history }, + { "forward-word", rl_forward_word }, + { "history-search-backward", rl_history_search_backward }, + { "history-search-forward", rl_history_search_forward }, + { "history-substring-search-backward", rl_history_substr_search_backward }, + { "history-substring-search-forward", rl_history_substr_search_forward }, + { "insert-comment", rl_insert_comment }, + { "insert-completions", rl_insert_completions }, + { "kill-whole-line", rl_kill_full_line }, + { "kill-line", rl_kill_line }, + { "kill-region", rl_kill_region }, + { "kill-word", rl_kill_word }, + { "menu-complete", rl_menu_complete }, + { "menu-complete-backward", rl_backward_menu_complete }, + { "next-history", rl_get_next_history }, + { "next-screen-line", rl_next_screen_line }, + { "non-incremental-forward-search-history", rl_noninc_forward_search }, + { "non-incremental-reverse-search-history", rl_noninc_reverse_search }, + { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again }, + { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again }, + { "old-menu-complete", rl_old_menu_complete }, + { "operate-and-get-next", rl_operate_and_get_next }, + { "overwrite-mode", rl_overwrite_mode }, +#if defined (_WIN32) + { "paste-from-clipboard", rl_paste_from_clipboard }, +#endif + { "possible-completions", rl_possible_completions }, + { "previous-history", rl_get_previous_history }, + { "previous-screen-line", rl_previous_screen_line }, + { "print-last-kbd-macro", rl_print_last_kbd_macro }, + { "quoted-insert", rl_quoted_insert }, + { "re-read-init-file", rl_re_read_init_file }, + { "redraw-current-line", rl_refresh_line}, + { "reverse-search-history", rl_reverse_search_history }, + { "revert-line", rl_revert_line }, + { "self-insert", rl_insert }, + { "set-mark", rl_set_mark }, + { "skip-csi-sequence", rl_skip_csi_sequence }, + { "start-kbd-macro", rl_start_kbd_macro }, + { "tab-insert", rl_tab_insert }, + { "tilde-expand", rl_tilde_expand }, + { "transpose-chars", rl_transpose_chars }, + { "transpose-words", rl_transpose_words }, + { "tty-status", rl_tty_status }, + { "undo", rl_undo_command }, + { "universal-argument", rl_universal_argument }, + { "unix-filename-rubout", rl_unix_filename_rubout }, + { "unix-line-discard", rl_unix_line_discard }, + { "unix-word-rubout", rl_unix_word_rubout }, + { "upcase-word", rl_upcase_word }, + { "yank", rl_yank }, + { "yank-last-arg", rl_yank_last_arg }, + { "yank-nth-arg", rl_yank_nth_arg }, + { "yank-pop", rl_yank_pop }, + +#if defined (VI_MODE) + { "vi-append-eol", rl_vi_append_eol }, + { "vi-append-mode", rl_vi_append_mode }, + { "vi-arg-digit", rl_vi_arg_digit }, + { "vi-back-to-indent", rl_vi_back_to_indent }, + { "vi-backward-bigword", rl_vi_bWord }, + { "vi-backward-word", rl_vi_bword }, + { "vi-bWord", rl_vi_bWord }, + { "vi-bword", rl_vi_bword }, /* BEWARE: name matching is case insensitive */ + { "vi-change-case", rl_vi_change_case }, + { "vi-change-char", rl_vi_change_char }, + { "vi-change-to", rl_vi_change_to }, + { "vi-char-search", rl_vi_char_search }, + { "vi-column", rl_vi_column }, + { "vi-complete", rl_vi_complete }, + { "vi-delete", rl_vi_delete }, + { "vi-delete-to", rl_vi_delete_to }, + { "vi-eWord", rl_vi_eWord }, + { "vi-editing-mode", rl_vi_editing_mode }, + { "vi-end-bigword", rl_vi_eWord }, + { "vi-end-word", rl_vi_end_word }, + { "vi-eof-maybe", rl_vi_eof_maybe }, + { "vi-eword", rl_vi_eword }, /* BEWARE: name matching is case insensitive */ + { "vi-fWord", rl_vi_fWord }, + { "vi-fetch-history", rl_vi_fetch_history }, + { "vi-first-print", rl_vi_first_print }, + { "vi-forward-bigword", rl_vi_fWord }, + { "vi-forward-word", rl_vi_fword }, + { "vi-fword", rl_vi_fword }, /* BEWARE: name matching is case insensitive */ + { "vi-goto-mark", rl_vi_goto_mark }, + { "vi-insert-beg", rl_vi_insert_beg }, + { "vi-insertion-mode", rl_vi_insert_mode }, + { "vi-match", rl_vi_match }, + { "vi-movement-mode", rl_vi_movement_mode }, + { "vi-next-word", rl_vi_next_word }, + { "vi-overstrike", rl_vi_overstrike }, + { "vi-overstrike-delete", rl_vi_overstrike_delete }, + { "vi-prev-word", rl_vi_prev_word }, + { "vi-put", rl_vi_put }, + { "vi-redo", rl_vi_redo }, + { "vi-replace", rl_vi_replace }, + { "vi-rubout", rl_vi_rubout }, + { "vi-search", rl_vi_search }, + { "vi-search-again", rl_vi_search_again }, + { "vi-set-mark", rl_vi_set_mark }, + { "vi-subst", rl_vi_subst }, + { "vi-tilde-expand", rl_vi_tilde_expand }, + { "vi-unix-word-rubout", rl_vi_unix_word_rubout }, + { "vi-yank-arg", rl_vi_yank_arg }, + { "vi-yank-pop", rl_vi_yank_pop }, + { "vi-yank-to", rl_vi_yank_to }, +#endif /* VI_MODE */ + + {(char *)NULL, (rl_command_func_t *)NULL } +}; + +int +rl_add_funmap_entry (const char *name, rl_command_func_t *function) +{ + if (funmap_entry + 2 >= funmap_size) + { + funmap_size += 64; + funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *)); + } + + funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP)); + funmap[funmap_entry]->name = name; + funmap[funmap_entry]->function = function; + + funmap[++funmap_entry] = (FUNMAP *)NULL; + return funmap_entry; +} + +static int funmap_initialized; + +/* Make the funmap contain all of the default entries. */ +void +rl_initialize_funmap (void) +{ + register int i; + + if (funmap_initialized) + return; + + for (i = 0; default_funmap[i].name; i++) + rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function); + + funmap_initialized = 1; + funmap_program_specific_entry_start = i; +} + +/* Produce a NULL terminated array of known function names. The array + is sorted. The array itself is allocated, but not the strings inside. + You should free () the array when you done, but not the pointers. */ +const char ** +rl_funmap_names (void) +{ + const char **result; + int result_size, result_index; + + /* Make sure that the function map has been initialized. */ + rl_initialize_funmap (); + + for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++) + { + if (result_index + 2 > result_size) + { + result_size += 20; + result = (const char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index] = funmap[result_index]->name; + result[result_index + 1] = (char *)NULL; + } + + qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + return (result); +} diff --git a/utshell-0.5.0/lib/readline/histexpand.c b/utshell-0.5.0/lib/readline/histexpand.c new file mode 100644 index 00000000..b986dba0 --- /dev/null +++ b/utshell-0.5.0/lib/readline/histexpand.c @@ -0,0 +1,1695 @@ +/* histexpand.c -- history expansion. */ + +/* Copyright (C) 1989-2018 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifndef _MINIX +# include +# endif +# include +#endif + +#include "rlmbutil.h" + +#include "history.h" +#include "histlib.h" +#include "chardefs.h" + +#include "rlshell.h" +#include "xmalloc.h" + +#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>" +#define HISTORY_QUOTE_CHARACTERS "\"'`" +#define HISTORY_EVENT_DELIMITERS "^$*%-" + +#define slashify_in_quotes "\\`\"$" + +#define fielddelim(c) (whitespace(c) || (c) == '\n') + +typedef int _hist_search_func_t PARAMS((const char *, int)); + +static char error_pointer; + +static char *subst_lhs; +static char *subst_rhs; +static int subst_lhs_len; +static int subst_rhs_len; + +/* Characters that delimit history event specifications and separate event + specifications from word designators. Static for now */ +static char *history_event_delimiter_chars = HISTORY_EVENT_DELIMITERS; + +static char *get_history_word_specifier PARAMS((char *, char *, int *)); +static int history_tokenize_word PARAMS((const char *, int)); +static char **history_tokenize_internal PARAMS((const char *, int, int *)); +static char *history_substring PARAMS((const char *, int, int)); +static void freewords PARAMS((char **, int)); +static char *history_find_word PARAMS((char *, int)); + +static char *quote_breaks PARAMS((char *)); + +/* Variables exported by this file. */ +/* The character that represents the start of a history expansion + request. This is usually `!'. */ +char history_expansion_char = '!'; + +/* The character that invokes word substitution if found at the start of + a line. This is usually `^'. */ +char history_subst_char = '^'; + +/* During tokenization, if this character is seen as the first character + of a word, then it, and all subsequent characters up to a newline are + ignored. For a Bourne shell, this should be '#'. Bash special cases + the interactive comment character to not be a comment delimiter. */ +char history_comment_char = '\0'; + +/* The list of characters which inhibit the expansion of text if found + immediately following history_expansion_char. */ +char *history_no_expand_chars = " \t\n\r="; + +/* If set to a non-zero value, single quotes inhibit history expansion. + The default is 0. */ +int history_quotes_inhibit_expansion = 0; + +/* Used to split words by history_tokenize_internal. */ +char *history_word_delimiters = HISTORY_WORD_DELIMITERS; + +/* If set, this points to a function that is called to verify that a + particular history expansion should be performed. */ +rl_linebuf_func_t *history_inhibit_expansion_function; + +int history_quoting_state = 0; + +/* **************************************************************** */ +/* */ +/* History Expansion */ +/* */ +/* **************************************************************** */ + +/* Hairy history expansion on text, not tokens. This is of general + use, and thus belongs in this library. */ + +/* The last string searched for by a !?string? search. */ +static char *search_string; +/* The last string matched by a !?string? search. */ +static char *search_match; + +/* Return the event specified at TEXT + OFFSET modifying OFFSET to + point to after the event specifier. Just a pointer to the history + line is returned; NULL is returned in the event of a bad specifier. + You pass STRING with *INDEX equal to the history_expansion_char that + begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. + So you might call this function like: + line = get_history_event ("!echo:p", &index, 0); */ +char * +get_history_event (const char *string, int *caller_index, int delimiting_quote) +{ + register int i; + register char c; + HIST_ENTRY *entry; + int which, sign, local_index, substring_okay; + _hist_search_func_t *search_func; + char *temp; + + /* The event can be specified in a number of ways. + + !! the previous command + !n command line N + !-n current command-line minus N + !str the most recent command starting with STR + !?str[?] + the most recent command containing STR + + All values N are determined via HISTORY_BASE. */ + + i = *caller_index; + + if (string[i] != history_expansion_char) + return ((char *)NULL); + + /* Move on to the specification. */ + i++; + + sign = 1; + substring_okay = 0; + +#define RETURN_ENTRY(e, w) \ + return ((e = history_get (w)) ? e->line : (char *)NULL) + + /* Handle !! case. */ + if (string[i] == history_expansion_char) + { + i++; + which = history_base + (history_length - 1); + *caller_index = i; + RETURN_ENTRY (entry, which); + } + + /* Hack case of numeric line specification. */ + if (string[i] == '-' && _rl_digit_p (string[i+1])) + { + sign = -1; + i++; + } + + if (_rl_digit_p (string[i])) + { + /* Get the extent of the digits and compute the value. */ + for (which = 0; _rl_digit_p (string[i]); i++) + which = (which * 10) + _rl_digit_value (string[i]); + + *caller_index = i; + + if (sign < 0) + which = (history_length + history_base) - which; + + RETURN_ENTRY (entry, which); + } + + /* This must be something to search for. If the spec begins with + a '?', then the string may be anywhere on the line. Otherwise, + the string must be found at the start of a line. */ + if (string[i] == '?') + { + substring_okay++; + i++; + } + + /* Only a closing `?' or a newline delimit a substring search string. */ + for (local_index = i; c = string[i]; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); + /* These produce warnings because we're passing a const string to a + function that takes a non-const string. */ + _rl_adjust_point ((char *)string, i, &ps); + if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1) + { + i += v - 1; + continue; + } + } + +#endif /* HANDLE_MULTIBYTE */ + if ((!substring_okay && + (whitespace (c) || c == ':' || + (i > local_index && history_event_delimiter_chars && c == '-') || + (c != '-' && history_event_delimiter_chars && member (c, history_event_delimiter_chars)) || + (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) || + string[i] == delimiting_quote)) || + string[i] == '\n' || + (substring_okay && string[i] == '?')) + break; + } + + which = i - local_index; + temp = (char *)xmalloc (1 + which); + if (which) + strncpy (temp, string + local_index, which); + temp[which] = '\0'; + + if (substring_okay && string[i] == '?') + i++; + + *caller_index = i; + +#define FAIL_SEARCH() \ + do { \ + history_offset = history_length; xfree (temp) ; return (char *)NULL; \ + } while (0) + + /* If there is no search string, try to use the previous search string, + if one exists. If not, fail immediately. */ + if (*temp == '\0' && substring_okay) + { + if (search_string) + { + xfree (temp); + temp = savestring (search_string); + } + else + FAIL_SEARCH (); + } + + search_func = substring_okay ? history_search : history_search_prefix; + while (1) + { + local_index = (*search_func) (temp, -1); + + if (local_index < 0) + FAIL_SEARCH (); + + if (local_index == 0 || substring_okay) + { + entry = current_history (); + if (entry == 0) + FAIL_SEARCH (); + history_offset = history_length; + + /* If this was a substring search, then remember the + string that we matched for word substitution. */ + if (substring_okay) + { + FREE (search_string); + search_string = temp; + + FREE (search_match); + search_match = history_find_word (entry->line, local_index); + } + else + xfree (temp); + + return (entry->line); + } + + if (history_offset) + history_offset--; + else + FAIL_SEARCH (); + } +#undef FAIL_SEARCH +#undef RETURN_ENTRY +} + +/* Function for extracting single-quoted strings. Used for inhibiting + history expansion within single quotes. */ + +/* Extract the contents of STRING as if it is enclosed in single quotes. + SINDEX, when passed in, is the offset of the character immediately + following the opening single quote; on exit, SINDEX is left pointing + to the closing single quote. FLAGS currently used to allow backslash + to escape a single quote (e.g., for bash $'...'). */ +static void +hist_string_extract_single_quoted (char *string, int *sindex, int flags) +{ + register int i; + + for (i = *sindex; string[i] && string[i] != '\''; i++) + { + if ((flags & 1) && string[i] == '\\' && string[i+1]) + i++; + } + + *sindex = i; +} + +static char * +quote_breaks (char *s) +{ + register char *p, *r; + char *ret; + int len = 3; + + for (p = s; p && *p; p++, len++) + { + if (*p == '\'') + len += 3; + else if (whitespace (*p) || *p == '\n') + len += 2; + } + + r = ret = (char *)xmalloc (len); + *r++ = '\''; + for (p = s; p && *p; ) + { + if (*p == '\'') + { + *r++ = '\''; + *r++ = '\\'; + *r++ = '\''; + *r++ = '\''; + p++; + } + else if (whitespace (*p) || *p == '\n') + { + *r++ = '\''; + *r++ = *p++; + *r++ = '\''; + } + else + *r++ = *p++; + } + *r++ = '\''; + *r = '\0'; + return ret; +} + +static char * +hist_error(char *s, int start, int current, int errtype) +{ + char *temp; + const char *emsg; + int ll, elen; + + ll = current - start; + + switch (errtype) + { + case EVENT_NOT_FOUND: + emsg = "event not found"; + elen = 15; + break; + case BAD_WORD_SPEC: + emsg = "bad word specifier"; + elen = 18; + break; + case SUBST_FAILED: + emsg = "substitution failed"; + elen = 19; + break; + case BAD_MODIFIER: + emsg = "unrecognized history modifier"; + elen = 29; + break; + case NO_PREV_SUBST: + emsg = "no previous substitution"; + elen = 24; + break; + default: + emsg = "unknown expansion error"; + elen = 23; + break; + } + + temp = (char *)xmalloc (ll + elen + 3); + if (s[start]) + strncpy (temp, s + start, ll); + else + ll = 0; + temp[ll] = ':'; + temp[ll + 1] = ' '; + strcpy (temp + ll + 2, emsg); + return (temp); +} + +/* Get a history substitution string from STR starting at *IPTR + and return it. The length is returned in LENPTR. + + A backslash can quote the delimiter. If the string is the + empty string, the previous pattern is used. If there is + no previous pattern for the lhs, the last history search + string is used. + + If IS_RHS is 1, we ignore empty strings and set the pattern + to "" anyway. subst_lhs is not changed if the lhs is empty; + subst_rhs is allowed to be set to the empty string. */ + +static char * +get_subst_pattern (char *str, int *iptr, int delimiter, int is_rhs, int *lenptr) +{ + register int si, i, j, k; + char *s; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; +#endif + + s = (char *)NULL; + i = *iptr; + +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); + _rl_adjust_point (str, i, &ps); +#endif + + for (si = i; str[si] && str[si] != delimiter; si++) +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + if ((v = _rl_get_char_len (str + si, &ps)) > 1) + si += v - 1; + else if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + } + else +#endif /* HANDLE_MULTIBYTE */ + if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + + if (si > i || is_rhs) + { + s = (char *)xmalloc (si - i + 1); + for (j = 0, k = i; k < si; j++, k++) + { + /* Remove a backslash quoting the search string delimiter. */ + if (str[k] == '\\' && str[k + 1] == delimiter) + k++; + s[j] = str[k]; + } + s[j] = '\0'; + if (lenptr) + *lenptr = j; + } + + i = si; + if (str[i]) + i++; + *iptr = i; + + return s; +} + +static void +postproc_subst_rhs (void) +{ + char *new; + int i, j, new_size; + + new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len); + for (i = j = 0; i < subst_rhs_len; i++) + { + if (subst_rhs[i] == '&') + { + if (j + subst_lhs_len >= new_size) + new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len)); + strcpy (new + j, subst_lhs); + j += subst_lhs_len; + } + else + { + /* a single backslash protects the `&' from lhs interpolation */ + if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') + i++; + if (j >= new_size) + new = (char *)xrealloc (new, new_size *= 2); + new[j++] = subst_rhs[i]; + } + } + new[j] = '\0'; + xfree (subst_rhs); + subst_rhs = new; + subst_rhs_len = j; +} + +/* Expand the bulk of a history specifier starting at STRING[START]. + Returns 0 if everything is OK, -1 if an error occurred, and 1 + if the `p' modifier was supplied and the caller should just print + the returned string. Returns the new index into string in + *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ +/* need current line for !# */ +static int +history_expand_internal (char *string, int start, int qc, int *end_index_ptr, char **ret_string, char *current_line) +{ + int i, n, starting_index; + int substitute_globally, subst_bywords, want_quotes, print_only; + char *event, *temp, *result, *tstr, *t, c, *word_spec; + int result_len; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + result = (char *)xmalloc (result_len = 128); + + i = start; + + /* If it is followed by something that starts a word specifier, + then !! is implied as the event specifier. */ + + if (member (string[i + 1], ":$*%^")) + { + char fake_s[3]; + int fake_i = 0; + i++; + fake_s[0] = fake_s[1] = history_expansion_char; + fake_s[2] = '\0'; + event = get_history_event (fake_s, &fake_i, 0); + } + else if (string[i + 1] == '#') + { + i += 2; + event = current_line; + } + else + event = get_history_event (string, &i, qc); + + if (event == 0) + { + *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND); + xfree (result); + return (-1); + } + + /* If a word specifier is found, then do what that requires. */ + starting_index = i; + word_spec = get_history_word_specifier (string, event, &i); + + /* There is no such thing as a `malformed word specifier'. However, + it is possible for a specifier that has no match. In that case, + we complain. */ + if (word_spec == (char *)&error_pointer) + { + *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC); + xfree (result); + return (-1); + } + + /* If no word specifier, than the thing of interest was the event. */ + temp = word_spec ? savestring (word_spec) : savestring (event); + FREE (word_spec); + + /* Perhaps there are other modifiers involved. Do what they say. */ + want_quotes = substitute_globally = subst_bywords = print_only = 0; + starting_index = i; + + while (string[i] == ':') + { + c = string[i + 1]; + + if (c == 'g' || c == 'a') + { + substitute_globally = 1; + i++; + c = string[i + 1]; + } + else if (c == 'G') + { + subst_bywords = 1; + i++; + c = string[i + 1]; + } + + switch (c) + { + default: + *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER); + xfree (result); + xfree (temp); + return -1; + + case 'q': + want_quotes = 'q'; + break; + + case 'x': + want_quotes = 'x'; + break; + + /* :p means make this the last executed line. So we + return an error state after adding this line to the + history. */ + case 'p': + print_only = 1; + break; + + /* :t discards all but the last part of the pathname. */ + case 't': + tstr = strrchr (temp, '/'); + if (tstr) + { + tstr++; + t = savestring (tstr); + xfree (temp); + temp = t; + } + break; + + /* :h discards the last part of a pathname. */ + case 'h': + tstr = strrchr (temp, '/'); + if (tstr) + *tstr = '\0'; + break; + + /* :r discards the suffix. */ + case 'r': + tstr = strrchr (temp, '.'); + if (tstr) + *tstr = '\0'; + break; + + /* :e discards everything but the suffix. */ + case 'e': + tstr = strrchr (temp, '.'); + if (tstr) + { + t = savestring (tstr); + xfree (temp); + temp = t; + } + break; + + /* :s/this/that substitutes `that' for the first + occurrence of `this'. :gs/this/that substitutes `that' + for each occurrence of `this'. :& repeats the last + substitution. :g& repeats the last substitution + globally. */ + + case '&': + case 's': + { + char *new_event; + int delimiter, failed, si, l_temp, ws, we; + + if (c == 's') + { + if (i + 2 < (int)strlen (string)) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + _rl_adjust_point (string, i + 2, &ps); + if (_rl_get_char_len (string + i + 2, &ps) > 1) + delimiter = 0; + else + delimiter = string[i + 2]; + } + else +#endif /* HANDLE_MULTIBYTE */ + delimiter = string[i + 2]; + } + else + break; /* no search delimiter */ + + i += 3; + + t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len); + /* An empty substitution lhs with no previous substitution + uses the last search string as the lhs. */ + if (t) + { + FREE (subst_lhs); + subst_lhs = t; + } + else if (!subst_lhs) + { + if (search_string && *search_string) + { + subst_lhs = savestring (search_string); + subst_lhs_len = strlen (subst_lhs); + } + else + { + subst_lhs = (char *) NULL; + subst_lhs_len = 0; + } + } + + FREE (subst_rhs); + subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len); + + /* If `&' appears in the rhs, it's supposed to be replaced + with the lhs. */ + if (member ('&', subst_rhs)) + postproc_subst_rhs (); + } + else + i += 2; + + /* If there is no lhs, the substitution can't succeed. */ + if (subst_lhs_len == 0) + { + *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST); + xfree (result); + xfree (temp); + return -1; + } + + l_temp = strlen (temp); + /* Ignore impossible cases. */ + if (subst_lhs_len > l_temp) + { + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + xfree (result); + xfree (temp); + return (-1); + } + + /* Find the first occurrence of THIS in TEMP. */ + /* Substitute SUBST_RHS for SUBST_LHS in TEMP. There are three + cases to consider: + + 1. substitute_globally == subst_bywords == 0 + 2. substitute_globally == 1 && subst_bywords == 0 + 3. substitute_globally == 0 && subst_bywords == 1 + + In the first case, we substitute for the first occurrence only. + In the second case, we substitute for every occurrence. + In the third case, we tokenize into words and substitute the + first occurrence of each word. */ + + si = we = 0; + for (failed = 1; (si + subst_lhs_len) <= l_temp; si++) + { + /* First skip whitespace and find word boundaries if + we're past the end of the word boundary we found + the last time. */ + if (subst_bywords && si > we) + { + for (; temp[si] && fielddelim (temp[si]); si++) + ; + ws = si; + we = history_tokenize_word (temp, si); + } + + if (STREQN (temp+si, subst_lhs, subst_lhs_len)) + { + int len = subst_rhs_len - subst_lhs_len + l_temp; + new_event = (char *)xmalloc (1 + len); + strncpy (new_event, temp, si); + strncpy (new_event + si, subst_rhs, subst_rhs_len); + strncpy (new_event + si + subst_rhs_len, + temp + si + subst_lhs_len, + l_temp - (si + subst_lhs_len)); + new_event[len] = '\0'; + xfree (temp); + temp = new_event; + + failed = 0; + + if (substitute_globally) + { + /* Reported to fix a bug that causes it to skip every + other match when matching a single character. Was + si += subst_rhs_len previously. */ + si += subst_rhs_len - 1; + l_temp = strlen (temp); + substitute_globally++; + continue; + } + else if (subst_bywords) + { + si = we; + l_temp = strlen (temp); + continue; + } + else + break; + } + } + + if (substitute_globally > 1) + { + substitute_globally = 0; + continue; /* don't want to increment i */ + } + + if (failed == 0) + continue; /* don't want to increment i */ + + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + xfree (result); + xfree (temp); + return (-1); + } + } + i += 2; + } + /* Done with modifiers. */ + /* Believe it or not, we have to back the pointer up by one. */ + --i; + + if (want_quotes) + { + char *x; + + if (want_quotes == 'q') + x = sh_single_quote (temp); + else if (want_quotes == 'x') + x = quote_breaks (temp); + else + x = savestring (temp); + + xfree (temp); + temp = x; + } + + n = strlen (temp); + if (n >= result_len) + result = (char *)xrealloc (result, n + 2); + strcpy (result, temp); + xfree (temp); + + *end_index_ptr = i; + *ret_string = result; + return (print_only); +} + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + -1) If there was an error in expansion. + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + 2) If the `p' modifier was given and the caller should print the result + + If an error occurred in expansion, then OUTPUT contains a descriptive + error message. */ + +#define ADD_STRING(s) \ + do \ + { \ + int sl = strlen (s); \ + j += sl; \ + if (j >= result_len) \ + { \ + while (j >= result_len) \ + result_len += 128; \ + result = (char *)xrealloc (result, result_len); \ + } \ + strcpy (result + j - sl, s); \ + } \ + while (0) + +#define ADD_CHAR(c) \ + do \ + { \ + if (j >= result_len - 1) \ + result = (char *)xrealloc (result, result_len += 64); \ + result[j++] = c; \ + result[j] = '\0'; \ + } \ + while (0) + +int +history_expand (char *hstring, char **output) +{ + register int j; + int i, r, l, passc, cc, modified, eindex, only_printing, dquote, squote, flag; + char *string; + + /* The output string, and its length. */ + int result_len; + char *result; + +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; + mbstate_t ps; +#endif + + /* Used when adding the string. */ + char *temp; + + if (output == 0) + return 0; + + /* Setting the history expansion character to 0 inhibits all + history expansion. */ + if (history_expansion_char == 0) + { + *output = savestring (hstring); + return (0); + } + + /* Prepare the buffer for printing error messages. */ + result = (char *)xmalloc (result_len = 256); + result[0] = '\0'; + + only_printing = modified = 0; + l = strlen (hstring); + + /* Grovel the string. Only backslash and single quotes can quote the + history escape character. We also handle arg specifiers. */ + + /* Before we grovel forever, see if the history_expansion_char appears + anywhere within the text. */ + + /* The quick substitution character is a history expansion all right. That + is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact, + that is the substitution that we do. */ + if (hstring[0] == history_subst_char) + { + string = (char *)xmalloc (l + 5); + + string[0] = string[1] = history_expansion_char; + string[2] = ':'; + string[3] = 's'; + strcpy (string + 4, hstring); + l += 4; + } + else + { +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + string = hstring; + /* If not quick substitution, still maybe have to do expansion. */ + + /* `!' followed by one of the characters in history_no_expand_chars + is NOT an expansion. */ + dquote = history_quoting_state == '"'; + squote = history_quoting_state == '\''; + + /* If the calling application tells us we are already reading a + single-quoted string, consume the rest of the string right now + and then go on. */ + i = 0; + if (squote && history_quotes_inhibit_expansion) + { + hist_string_extract_single_quoted (string, &i, 0); + squote = 0; + if (string[i]) + i++; + } + + for ( ; string[i]; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + v = _rl_get_char_len (string + i, &ps); + if (v > 1) + { + i += v - 1; + continue; + } + } +#endif /* HANDLE_MULTIBYTE */ + + cc = string[i + 1]; + /* The history_comment_char, if set, appearing at the beginning + of a word signifies that the rest of the line should not have + history expansion performed on it. + Skip the rest of the line and break out of the loop. */ + if (history_comment_char && string[i] == history_comment_char && + dquote == 0 && + (i == 0 || member (string[i - 1], history_word_delimiters))) + { + while (string[i]) + i++; + break; + } + else if (string[i] == history_expansion_char) + { + if (cc == 0 || member (cc, history_no_expand_chars)) + continue; + /* DQUOTE won't be set unless history_quotes_inhibit_expansion + is set. The idea here is to treat double-quoted strings the + same as the word outside double quotes; in effect making the + double quote part of history_no_expand_chars when DQUOTE is + set. */ + else if (dquote && cc == '"') + continue; + /* If the calling application has set + history_inhibit_expansion_function to a function that checks + for special cases that should not be history expanded, + call the function and skip the expansion if it returns a + non-zero value. */ + else if (history_inhibit_expansion_function && + (*history_inhibit_expansion_function) (string, i)) + continue; + else + break; + } + /* Shell-like quoting: allow backslashes to quote double quotes + inside a double-quoted string. */ + else if (dquote && string[i] == '\\' && cc == '"') + i++; + /* More shell-like quoting: if we're paying attention to single + quotes and letting them quote the history expansion character, + then we need to pay attention to double quotes, because single + quotes are not special inside double-quoted strings. */ + else if (history_quotes_inhibit_expansion && string[i] == '"') + { + dquote = 1 - dquote; + } + else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'') + { + /* If this is bash, single quotes inhibit history expansion. */ + flag = (i > 0 && string[i - 1] == '$'); + i++; + hist_string_extract_single_quoted (string, &i, flag); + } + else if (history_quotes_inhibit_expansion && string[i] == '\\') + { + /* If this is bash, allow backslashes to quote single + quotes and the history expansion character. */ + if (cc == '\'' || cc == history_expansion_char) + i++; + } + + } + + if (string[i] != history_expansion_char) + { + xfree (result); + *output = savestring (string); + return (0); + } + } + + /* Extract and perform the substitution. */ + dquote = history_quoting_state == '"'; + squote = history_quoting_state == '\''; + + /* If the calling application tells us we are already reading a + single-quoted string, consume the rest of the string right now + and then go on. */ + i = j = 0; + if (squote && history_quotes_inhibit_expansion) + { + int c; + + hist_string_extract_single_quoted (string, &i, 0); + squote = 0; + for (c = 0; c < i; c++) + ADD_CHAR (string[c]); + if (string[i]) + { + ADD_CHAR (string[i]); + i++; + } + } + + for (passc = 0; i < l; i++) + { + int qc, tchar = string[i]; + + if (passc) + { + passc = 0; + ADD_CHAR (tchar); + continue; + } + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int k, c; + + c = tchar; + memset (mb, 0, sizeof (mb)); + for (k = 0; k < MB_LEN_MAX; k++) + { + mb[k] = (char)c; + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_get_char_len (mb, &ps) == -2) + c = string[++i]; + else + break; + } + if (strlen (mb) > 1) + { + ADD_STRING (mb); + continue; + } + } +#endif /* HANDLE_MULTIBYTE */ + + if (tchar == history_expansion_char) + tchar = -3; + else if (tchar == history_comment_char) + tchar = -2; + + switch (tchar) + { + default: + ADD_CHAR (string[i]); + break; + + case '\\': + passc++; + ADD_CHAR (tchar); + break; + + case '"': + dquote = 1 - dquote; + ADD_CHAR (tchar); + break; + + case '\'': + { + /* If history_quotes_inhibit_expansion is set, single quotes + inhibit history expansion, otherwise they are treated like + double quotes. */ + if (squote) + { + squote = 0; + ADD_CHAR (tchar); + } + else if (dquote == 0 && history_quotes_inhibit_expansion) + { + int quote, slen; + + flag = (i > 0 && string[i - 1] == '$'); + quote = i++; + hist_string_extract_single_quoted (string, &i, flag); + + slen = i - quote + 2; + temp = (char *)xmalloc (slen); + strncpy (temp, string + quote, slen); + temp[slen - 1] = '\0'; + ADD_STRING (temp); + xfree (temp); + } + else if (dquote == 0 && squote == 0 && history_quotes_inhibit_expansion == 0) + { + squote = 1; + ADD_CHAR (string[i]); + } + else + ADD_CHAR (string[i]); + break; + } + + case -2: /* history_comment_char */ + if ((dquote == 0 || history_quotes_inhibit_expansion == 0) && + (i == 0 || member (string[i - 1], history_word_delimiters))) + { + temp = (char *)xmalloc (l - i + 1); + strcpy (temp, string + i); + ADD_STRING (temp); + xfree (temp); + i = l; + } + else + ADD_CHAR (string[i]); + break; + + case -3: /* history_expansion_char */ + cc = string[i + 1]; + + /* If the history_expansion_char is followed by one of the + characters in history_no_expand_chars, then it is not a + candidate for expansion of any kind. */ + if (cc == 0 || member (cc, history_no_expand_chars) || + (dquote && cc == '"') || + (history_inhibit_expansion_function && (*history_inhibit_expansion_function) (string, i))) + { + ADD_CHAR (string[i]); + break; + } + +#if defined (NO_BANG_HASH_MODIFIERS) + /* There is something that is listed as a `word specifier' in csh + documentation which means `the expanded text to this point'. + That is not a word specifier, it is an event specifier. If we + don't want to allow modifiers with `!#', just stick the current + output line in again. */ + if (cc == '#') + { + if (result) + { + temp = (char *)xmalloc (1 + strlen (result)); + strcpy (temp, result); + ADD_STRING (temp); + xfree (temp); + } + i++; + break; + } +#endif + qc = squote ? '\'' : (dquote ? '"' : 0); + r = history_expand_internal (string, i, qc, &eindex, &temp, result); + if (r < 0) + { + *output = temp; + xfree (result); + if (string != hstring) + xfree (string); + return -1; + } + else + { + if (temp) + { + modified++; + if (*temp) + ADD_STRING (temp); + xfree (temp); + } + only_printing += r == 1; + i = eindex; + } + break; + } + } + + *output = result; + if (string != hstring) + xfree (string); + + if (only_printing) + { +#if 0 + add_history (result); +#endif + return (2); + } + + return (modified != 0); +} + +/* Return a consed string which is the word specified in SPEC, and found + in FROM. NULL is returned if there is no spec. The address of + ERROR_POINTER is returned if the word specified cannot be found. + CALLER_INDEX is the offset in SPEC to start looking; it is updated + to point to just after the last character parsed. */ +static char * +get_history_word_specifier (char *spec, char *from, int *caller_index) +{ + register int i = *caller_index; + int first, last; + int expecting_word_spec = 0; + char *result; + + /* The range of words to return doesn't exist yet. */ + first = last = 0; + result = (char *)NULL; + + /* If we found a colon, then this *must* be a word specification. If + it isn't, then it is an error. */ + if (spec[i] == ':') + { + i++; + expecting_word_spec++; + } + + /* Handle special cases first. */ + + /* `%' is the word last searched for. */ + if (spec[i] == '%') + { + *caller_index = i + 1; + return (search_match ? savestring (search_match) : savestring ("")); + } + + /* `*' matches all of the arguments, but not the command. */ + if (spec[i] == '*') + { + *caller_index = i + 1; + result = history_arg_extract (1, '$', from); + return (result ? result : savestring ("")); + } + + /* `$' is last arg. */ + if (spec[i] == '$') + { + *caller_index = i + 1; + return (history_arg_extract ('$', '$', from)); + } + + /* Try to get FIRST and LAST figured out. */ + + if (spec[i] == '-') + first = 0; + else if (spec[i] == '^') + { + first = 1; + i++; + } + else if (_rl_digit_p (spec[i]) && expecting_word_spec) + { + for (first = 0; _rl_digit_p (spec[i]); i++) + first = (first * 10) + _rl_digit_value (spec[i]); + } + else + return ((char *)NULL); /* no valid `first' for word specifier */ + + if (spec[i] == '^' || spec[i] == '*') + { + last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */ + i++; + } + else if (spec[i] != '-') + last = first; + else + { + i++; + + if (_rl_digit_p (spec[i])) + { + for (last = 0; _rl_digit_p (spec[i]); i++) + last = (last * 10) + _rl_digit_value (spec[i]); + } + else if (spec[i] == '$') + { + i++; + last = '$'; + } + else if (spec[i] == '^') + { + i++; + last = 1; + } +#if 0 + else if (!spec[i] || spec[i] == ':') + /* check against `:' because there could be a modifier separator */ +#else + else + /* csh seems to allow anything to terminate the word spec here, + leaving it as an abbreviation. */ +#endif + last = -1; /* x- abbreviates x-$ omitting word `$' */ + } + + *caller_index = i; + + if (last >= first || last == '$' || last < 0) + result = history_arg_extract (first, last, from); + + return (result ? result : (char *)&error_pointer); +} + +/* Extract the args specified, starting at FIRST, and ending at LAST. + The args are taken from STRING. If either FIRST or LAST is < 0, + then make that arg count from the right (subtract from the number of + tokens, so that FIRST = -1 means the next to last token on the line). + If LAST is `$' the last arg from STRING is used. */ +char * +history_arg_extract (int first, int last, const char *string) +{ + register int i, len; + char *result; + int size, offset; + char **list; + + /* XXX - think about making history_tokenize return a struct array, + each struct in array being a string and a length to avoid the + calls to strlen below. */ + if ((list = history_tokenize (string)) == NULL) + return ((char *)NULL); + + for (len = 0; list[len]; len++) + ; + + if (last < 0) + last = len + last - 1; + + if (first < 0) + first = len + first - 1; + + if (last == '$') + last = len - 1; + + if (first == '$') + first = len - 1; + + last++; + + if (first >= len || last > len || first < 0 || last < 0 || first > last) + result = ((char *)NULL); + else + { + for (size = 0, i = first; i < last; i++) + size += strlen (list[i]) + 1; + result = (char *)xmalloc (size + 1); + result[0] = '\0'; + + for (i = first, offset = 0; i < last; i++) + { + strcpy (result + offset, list[i]); + offset += strlen (list[i]); + if (i + 1 < last) + { + result[offset++] = ' '; + result[offset] = 0; + } + } + } + + for (i = 0; i < len; i++) + xfree (list[i]); + xfree (list); + + return (result); +} + +static int +history_tokenize_word (const char *string, int ind) +{ + register int i, j; + int delimiter, nestdelim, delimopen; + + i = ind; + delimiter = nestdelim = 0; + + if (member (string[i], "()\n")) /* XXX - included \n, but why? been here forever */ + { + i++; + return i; + } + + if (ISDIGIT (string[i])) + { + j = i; + while (string[j] && ISDIGIT (string[j])) + j++; + if (string[j] == 0) + return (j); + if (string[j] == '<' || string[j] == '>') + i = j; /* digit sequence is a file descriptor */ + else + { + i = j; + goto get_word; /* digit sequence is part of a word */ + } + } + + if (member (string[i], "<>;&|")) + { + int peek = string[i + 1]; + + if (peek == string[i]) + { + if (peek == '<' && string[i + 2] == '-') + i++; + else if (peek == '<' && string[i + 2] == '<') + i++; + i += 2; + return i; + } + else if (peek == '&' && (string[i] == '>' || string[i] == '<')) + { + j = i + 2; + while (string[j] && ISDIGIT (string[j])) /* file descriptor */ + j++; + if (string[j] =='-') /* <&[digits]-, >&[digits]- */ + j++; + return j; + } + else if ((peek == '>' && string[i] == '&') || (peek == '|' && string[i] == '>')) + { + i += 2; + return i; + } + /* XXX - process substitution -- separated out for later -- bash-4.2 */ + else if (peek == '(' && (string[i] == '>' || string[i] == '<')) /*)*/ + { + i += 2; + delimopen = '('; + delimiter = ')'; + nestdelim = 1; + goto get_word; + } + + i++; + return i; + } + +get_word: + /* Get word from string + i; */ + + if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS)) + delimiter = string[i++]; + + for (; string[i]; i++) + { + if (string[i] == '\\' && string[i + 1] == '\n') + { + i++; + continue; + } + + if (string[i] == '\\' && delimiter != '\'' && + (delimiter != '"' || member (string[i], slashify_in_quotes))) + { + i++; + continue; + } + + /* delimiter must be set and set to something other than a quote if + nestdelim is set, so these tests are safe. */ + if (nestdelim && string[i] == delimopen) + { + nestdelim++; + continue; + } + if (nestdelim && string[i] == delimiter) + { + nestdelim--; + if (nestdelim == 0) + delimiter = 0; + continue; + } + + if (delimiter && string[i] == delimiter) + { + delimiter = 0; + continue; + } + + /* Command and process substitution; shell extended globbing patterns */ + if (nestdelim == 0 && delimiter == 0 && member (string[i], "<>$!@?+*") && string[i+1] == '(') /*)*/ + { + i += 2; + delimopen = '('; + delimiter = ')'; + nestdelim = 1; + continue; + } + + if (delimiter == 0 && (member (string[i], history_word_delimiters))) + break; + + if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS)) + delimiter = string[i]; + } + + return i; +} + +static char * +history_substring (const char *string, int start, int end) +{ + register int len; + register char *result; + + len = end - start; + result = (char *)xmalloc (len + 1); + strncpy (result, string + start, len); + result[len] = '\0'; + return result; +} + +/* Parse STRING into tokens and return an array of strings. If WIND is + not -1 and INDP is not null, we also want the word surrounding index + WIND. The position in the returned array of strings is returned in + *INDP. */ +static char ** +history_tokenize_internal (const char *string, int wind, int *indp) +{ + char **result; + register int i, start, result_index, size; + + /* If we're searching for a string that's not part of a word (e.g., " "), + make sure we set *INDP to a reasonable value. */ + if (indp && wind != -1) + *indp = -1; + + /* Get a token, and stuff it into RESULT. The tokens are split + exactly where the shell would split them. */ + for (i = result_index = size = 0, result = (char **)NULL; string[i]; ) + { + /* Skip leading whitespace. */ + for (; string[i] && fielddelim (string[i]); i++) + ; + if (string[i] == 0 || string[i] == history_comment_char) + return (result); + + start = i; + + i = history_tokenize_word (string, start); + + /* If we have a non-whitespace delimiter character (which would not be + skipped by the loop above), use it and any adjacent delimiters to + make a separate field. Any adjacent white space will be skipped the + next time through the loop. */ + if (i == start && history_word_delimiters) + { + i++; + while (string[i] && member (string[i], history_word_delimiters)) + i++; + } + + /* If we are looking for the word in which the character at a + particular index falls, remember it. */ + if (indp && wind != -1 && wind >= start && wind < i) + *indp = result_index; + + if (result_index + 2 >= size) + result = (char **)xrealloc (result, ((size += 10) * sizeof (char *))); + + result[result_index++] = history_substring (string, start, i); + result[result_index] = (char *)NULL; + } + + return (result); +} + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +char ** +history_tokenize (const char *string) +{ + return (history_tokenize_internal (string, -1, (int *)NULL)); +} + +/* Free members of WORDS from START to an empty string */ +static void +freewords (char **words, int start) +{ + register int i; + + for (i = start; words[i]; i++) + xfree (words[i]); +} + +/* Find and return the word which contains the character at index IND + in the history line LINE. Used to save the word matched by the + last history !?string? search. */ +static char * +history_find_word (char *line, int ind) +{ + char **words, *s; + int i, wind; + + words = history_tokenize_internal (line, ind, &wind); + if (wind == -1 || words == 0) + { + if (words) + freewords (words, 0); + FREE (words); + return ((char *)NULL); + } + s = words[wind]; + for (i = 0; i < wind; i++) + xfree (words[i]); + freewords (words, wind + 1); + xfree (words); + return s; +} diff --git a/utshell-0.5.0/lib/readline/histfile.c b/utshell-0.5.0/lib/readline/histfile.c new file mode 100644 index 00000000..f0fa5ce1 --- /dev/null +++ b/utshell-0.5.0/lib/readline/histfile.c @@ -0,0 +1,835 @@ +/* histfile.c - functions to manipulate the history file. */ + +/* Copyright (C) 1989-2019 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +/* The goal is to make the implementation transparent, so that you + don't have to know what data types are used, just what functions + you can call. I think I have done that. */ + +#define READLINE_LIBRARY + +#if defined (__TANDEM) +# define _XOPEN_SOURCE_EXTENDED 1 +# include +# include +#endif + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include +#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif +#include "posixstat.h" +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#if defined (__EMX__) +# undef HAVE_MMAP +#endif + +#ifdef HISTORY_USE_MMAP +# include + +# ifdef MAP_FILE +# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE) +# define MAP_WFLAGS (MAP_FILE|MAP_SHARED) +# else +# define MAP_RFLAGS MAP_PRIVATE +# define MAP_WFLAGS MAP_SHARED +# endif + +# ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +# endif + +#endif /* HISTORY_USE_MMAP */ + +#if defined(_WIN32) +# define WIN32_LEAN_AND_MEAN +# include +#endif + +/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment + on win 95/98/nt), we want to open files with O_BINARY mode so that there + is no \n -> \r\n conversion performed. On other systems, we don't want to + mess around with O_BINARY at all, so we ensure that it's defined to 0. */ +#if defined (__EMX__) || defined (__CYGWIN__) +# ifndef O_BINARY +# define O_BINARY 0 +# endif +#else /* !__EMX__ && !__CYGWIN__ */ +# undef O_BINARY +# define O_BINARY 0 +#endif /* !__EMX__ && !__CYGWIN__ */ + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "history.h" +#include "histlib.h" + +#include "rlshell.h" +#include "xmalloc.h" + +#if !defined (PATH_MAX) +# define PATH_MAX 1024 /* default */ +#endif + +extern void _hs_append_history_line PARAMS((int, const char *)); + +/* history file version; currently unused */ +int history_file_version = 1; + +/* If non-zero, we write timestamps to the history file in history_do_write() */ +int history_write_timestamps = 0; + +/* If non-zero, we assume that a history file that starts with a timestamp + uses timestamp-delimited entries and can include multi-line history + entries. Used by read_history_range */ +int history_multiline_entries = 0; + +/* Immediately after a call to read_history() or read_history_range(), this + will return the number of lines just read from the history file in that + call. */ +int history_lines_read_from_file = 0; + +/* Immediately after a call to write_history() or history_do_write(), this + will return the number of lines just written to the history file in that + call. This also works with history_truncate_file. */ +int history_lines_written_to_file = 0; + +/* Does S look like the beginning of a history timestamp entry? Placeholder + for more extensive tests. */ +#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((unsigned char)(s)[1]) ) + +static char *history_backupfile PARAMS((const char *)); +static char *history_tempfile PARAMS((const char *)); +static int histfile_backup PARAMS((const char *, const char *)); +static int histfile_restore PARAMS((const char *, const char *)); +static int history_rename PARAMS((const char *, const char *)); + +/* Return the string that should be used in the place of this + filename. This only matters when you don't specify the + filename to read_history (), or write_history (). */ +static char * +history_filename (const char *filename) +{ + char *return_val; + const char *home; + int home_len; + + return_val = filename ? savestring (filename) : (char *)NULL; + + if (return_val) + return (return_val); + + home = sh_get_env_value ("HOME"); +#if defined (_WIN32) + if (home == 0) + home = sh_get_env_value ("APPDATA"); +#endif + + if (home == 0) + return (NULL); + else + home_len = strlen (home); + + return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ + strcpy (return_val, home); + return_val[home_len] = '/'; +#if defined (__MSDOS__) + strcpy (return_val + home_len + 1, "_history"); +#else + strcpy (return_val + home_len + 1, ".history"); +#endif + + return (return_val); +} + +static char * +history_backupfile (const char *filename) +{ + const char *fn; + char *ret, linkbuf[PATH_MAX+1]; + size_t len; + ssize_t n; + struct stat fs; + + fn = filename; +#if defined (HAVE_READLINK) + /* Follow symlink to avoid backing up symlink itself; call will fail if + not a symlink */ + if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0) + { + linkbuf[n] = '\0'; + fn = linkbuf; + } +#endif + + len = strlen (fn); + ret = xmalloc (len + 2); + strcpy (ret, fn); + ret[len] = '-'; + ret[len+1] = '\0'; + return ret; +} + +static char * +history_tempfile (const char *filename) +{ + const char *fn; + char *ret, linkbuf[PATH_MAX+1]; + size_t len; + ssize_t n; + struct stat fs; + int pid; + + fn = filename; +#if defined (HAVE_READLINK) + /* Follow symlink so tempfile created in the same directory as any symlinked + history file; call will fail if not a symlink */ + if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0) + { + linkbuf[n] = '\0'; + fn = linkbuf; + } +#endif + + len = strlen (fn); + ret = xmalloc (len + 11); + strcpy (ret, fn); + + pid = (int)getpid (); + + /* filename-PID.tmp */ + ret[len] = '-'; + ret[len+1] = (pid / 10000 % 10) + '0'; + ret[len+2] = (pid / 1000 % 10) + '0'; + ret[len+3] = (pid / 100 % 10) + '0'; + ret[len+4] = (pid / 10 % 10) + '0'; + ret[len+5] = (pid % 10) + '0'; + strcpy (ret + len + 6, ".tmp"); + + return ret; +} + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +int +read_history (const char *filename) +{ + return (read_history_range (filename, 0, -1)); +} + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +int +read_history_range (const char *filename, int from, int to) +{ + register char *line_start, *line_end, *p; + char *input, *buffer, *bufend, *last_ts; + int file, current_line, chars_read, has_timestamps, reset_comment_char; + struct stat finfo; + size_t file_size; +#if defined (EFBIG) + int overflow_errno = EFBIG; +#elif defined (EOVERFLOW) + int overflow_errno = EOVERFLOW; +#else + int overflow_errno = EIO; +#endif + + history_lines_read_from_file = 0; + + buffer = last_ts = (char *)NULL; + input = history_filename (filename); + file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1; + + if ((file < 0) || (fstat (file, &finfo) == -1)) + goto error_and_exit; + + if (S_ISREG (finfo.st_mode) == 0) + { +#ifdef EFTYPE + errno = EFTYPE; +#else + errno = EINVAL; +#endif + goto error_and_exit; + } + + file_size = (size_t)finfo.st_size; + + /* check for overflow on very large files */ + if (file_size != finfo.st_size || file_size + 1 < file_size) + { + errno = overflow_errno; + goto error_and_exit; + } + + if (file_size == 0) + { + free (input); + close (file); + return 0; /* don't waste time if we don't have to */ + } + +#ifdef HISTORY_USE_MMAP + /* We map read/write and private so we can change newlines to NULs without + affecting the underlying object. */ + buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0); + if ((void *)buffer == MAP_FAILED) + { + errno = overflow_errno; + goto error_and_exit; + } + chars_read = file_size; +#else + buffer = (char *)malloc (file_size + 1); + if (buffer == 0) + { + errno = overflow_errno; + goto error_and_exit; + } + + chars_read = read (file, buffer, file_size); +#endif + if (chars_read < 0) + { + error_and_exit: + if (errno != 0) + chars_read = errno; + else + chars_read = EIO; + if (file >= 0) + close (file); + + FREE (input); +#ifndef HISTORY_USE_MMAP + FREE (buffer); +#endif + + return (chars_read); + } + + close (file); + + /* Set TO to larger than end of file if negative. */ + if (to < 0) + to = chars_read; + + /* Start at beginning of file, work to end. */ + bufend = buffer + chars_read; + *bufend = '\0'; /* null-terminate buffer for timestamp checks */ + current_line = 0; + + /* Heuristic: the history comment character rarely changes, so assume we + have timestamps if the buffer starts with `#[:digit:]' and temporarily + set history_comment_char so timestamp parsing works right */ + reset_comment_char = 0; + if (history_comment_char == '\0' && buffer[0] == '#' && isdigit ((unsigned char)buffer[1])) + { + history_comment_char = '#'; + reset_comment_char = 1; + } + + has_timestamps = HIST_TIMESTAMP_START (buffer); + history_multiline_entries += has_timestamps && history_write_timestamps; + + /* Skip lines until we are at FROM. */ + if (has_timestamps) + last_ts = buffer; + for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++) + if (*line_end == '\n') + { + p = line_end + 1; + /* If we see something we think is a timestamp, continue with this + line. We should check more extensively here... */ + if (HIST_TIMESTAMP_START(p) == 0) + current_line++; + else + last_ts = p; + line_start = p; + /* If we are at the last line (current_line == from) but we have + timestamps (has_timestamps), then line_start points to the + text of the last command, and we need to skip to its end. */ + if (current_line >= from && has_timestamps) + { + for (line_end = p; line_end < bufend && *line_end != '\n'; line_end++) + ; + line_start = (*line_end == '\n') ? line_end + 1 : line_end; + } + } + + /* If there are lines left to gobble, then gobble them now. */ + for (line_end = line_start; line_end < bufend; line_end++) + if (*line_end == '\n') + { + /* Change to allow Windows-like \r\n end of line delimiter. */ + if (line_end > line_start && line_end[-1] == '\r') + line_end[-1] = '\0'; + else + *line_end = '\0'; + + if (*line_start) + { + if (HIST_TIMESTAMP_START(line_start) == 0) + { + if (last_ts == NULL && history_length > 0 && history_multiline_entries) + _hs_append_history_line (history_length - 1, line_start); + else + add_history (line_start); + if (last_ts) + { + add_history_time (last_ts); + last_ts = NULL; + } + } + else + { + last_ts = line_start; + current_line--; + } + } + + current_line++; + + if (current_line >= to) + break; + + line_start = line_end + 1; + } + + history_lines_read_from_file = current_line; + if (reset_comment_char) + history_comment_char = '\0'; + + FREE (input); +#ifndef HISTORY_USE_MMAP + FREE (buffer); +#else + munmap (buffer, file_size); +#endif + + return (0); +} + +/* We need a special version for WIN32 because Windows rename() refuses to + overwrite an existing file. */ +static int +history_rename (const char *old, const char *new) +{ +#if defined (_WIN32) + return (MoveFileEx (old, new, MOVEFILE_REPLACE_EXISTING) == 0 ? -1 : 0); +#else + return (rename (old, new)); +#endif +} + +/* Save FILENAME to BACK, handling case where FILENAME is a symlink + (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ +static int +histfile_backup (const char *filename, const char *back) +{ +#if defined (HAVE_READLINK) + char linkbuf[PATH_MAX+1]; + ssize_t n; + + /* Follow to target of symlink to avoid renaming symlink itself */ + if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0) + { + linkbuf[n] = '\0'; + return (history_rename (linkbuf, back)); + } +#endif + return (history_rename (filename, back)); +} + +/* Restore ORIG from BACKUP handling case where ORIG is a symlink + (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ +static int +histfile_restore (const char *backup, const char *orig) +{ +#if defined (HAVE_READLINK) + char linkbuf[PATH_MAX+1]; + ssize_t n; + + /* Follow to target of symlink to avoid renaming symlink itself */ + if ((n = readlink (orig, linkbuf, sizeof (linkbuf) - 1)) > 0) + { + linkbuf[n] = '\0'; + return (history_rename (backup, linkbuf)); + } +#endif + return (history_rename (backup, orig)); +} + +/* Should we call chown, based on whether finfo and nfinfo describe different + files with different owners? */ + +#define SHOULD_CHOWN(finfo, nfinfo) \ + (finfo.st_uid != nfinfo.st_uid || finfo.st_gid != nfinfo.st_gid) + +/* Truncate the history file FNAME, leaving only LINES trailing lines. + If FNAME is NULL, then use ~/.history. Writes a new file and renames + it to the original name. Returns 0 on success, errno on failure. */ +int +history_truncate_file (const char *fname, int lines) +{ + char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */ + int file, chars_read, rv, orig_lines, exists, r; + struct stat finfo, nfinfo; + size_t file_size; + + history_lines_written_to_file = 0; + + buffer = (char *)NULL; + filename = history_filename (fname); + tempname = 0; + file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1; + rv = exists = 0; + + /* Don't try to truncate non-regular files. */ + if (file == -1 || fstat (file, &finfo) == -1) + { + rv = errno; + if (file != -1) + close (file); + goto truncate_exit; + } + exists = 1; + + nfinfo.st_uid = finfo.st_uid; + nfinfo.st_gid = finfo.st_gid; + + if (S_ISREG (finfo.st_mode) == 0) + { + close (file); +#ifdef EFTYPE + rv = EFTYPE; +#else + rv = EINVAL; +#endif + goto truncate_exit; + } + + file_size = (size_t)finfo.st_size; + + /* check for overflow on very large files */ + if (file_size != finfo.st_size || file_size + 1 < file_size) + { + close (file); +#if defined (EFBIG) + rv = errno = EFBIG; +#elif defined (EOVERFLOW) + rv = errno = EOVERFLOW; +#else + rv = errno = EINVAL; +#endif + goto truncate_exit; + } + + buffer = (char *)malloc (file_size + 1); + if (buffer == 0) + { + rv = errno; + close (file); + goto truncate_exit; + } + + chars_read = read (file, buffer, file_size); + close (file); + + if (chars_read <= 0) + { + rv = (chars_read < 0) ? errno : 0; + goto truncate_exit; + } + + orig_lines = lines; + /* Count backwards from the end of buffer until we have passed + LINES lines. bp1 is set funny initially. But since bp[1] can't + be a comment character (since it's off the end) and *bp can't be + both a newline and the history comment character, it should be OK. */ + for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--) + { + if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0) + lines--; + bp1 = bp; + } + + /* If this is the first line, then the file contains exactly the + number of lines we want to truncate to, so we don't need to do + anything. It's the first line if we don't find a newline between + the current value of i and 0. Otherwise, write from the start of + this line until the end of the buffer. */ + for ( ; bp > buffer; bp--) + { + if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0) + { + bp++; + break; + } + bp1 = bp; + } + + /* Write only if there are more lines in the file than we want to + truncate to. */ + if (bp <= buffer) + { + rv = 0; + /* No-op if LINES == 0 at this point */ + history_lines_written_to_file = orig_lines - lines; + goto truncate_exit; + } + + tempname = history_tempfile (filename); + + if ((file = open (tempname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600)) != -1) + { + if (write (file, bp, chars_read - (bp - buffer)) < 0) + rv = errno; + + if (fstat (file, &nfinfo) < 0 && rv == 0) + rv = errno; + + if (close (file) < 0 && rv == 0) + rv = errno; + } + else + rv = errno; + + truncate_exit: + FREE (buffer); + + history_lines_written_to_file = orig_lines - lines; + + if (rv == 0 && filename && tempname) + rv = histfile_restore (tempname, filename); + + if (rv != 0) + { + rv = errno; + if (tempname) + unlink (tempname); + history_lines_written_to_file = 0; + } + +#if defined (HAVE_CHOWN) + /* Make sure the new filename is owned by the same user as the old. If one + user is running this, it's a no-op. If the shell is running after sudo + with a shared history file, we don't want to leave the history file + owned by root. */ + if (rv == 0 && exists && SHOULD_CHOWN (finfo, nfinfo)) + r = chown (filename, finfo.st_uid, finfo.st_gid); +#endif + + xfree (filename); + FREE (tempname); + + return rv; +} + +/* Workhorse function for writing history. Writes the last NELEMENT entries + from the history list to FILENAME. OVERWRITE is non-zero if you + wish to replace FILENAME with the entries. */ +static int +history_do_write (const char *filename, int nelements, int overwrite) +{ + register int i; + char *output, *tempname, *histname; + int file, mode, rv, exists; + struct stat finfo, nfinfo; +#ifdef HISTORY_USE_MMAP + size_t cursize; + + history_lines_written_to_file = 0; + + mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY; +#else + mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; +#endif + histname = history_filename (filename); + exists = histname ? (stat (histname, &finfo) == 0) : 0; + + tempname = (overwrite && exists && S_ISREG (finfo.st_mode)) ? history_tempfile (histname) : 0; + output = tempname ? tempname : histname; + + file = output ? open (output, mode, 0600) : -1; + rv = 0; + + if (file == -1) + { + rv = errno; + FREE (histname); + FREE (tempname); + return (rv); + } + +#ifdef HISTORY_USE_MMAP + cursize = overwrite ? 0 : lseek (file, 0, SEEK_END); +#endif + + if (nelements > history_length) + nelements = history_length; + + /* Build a buffer of all the lines to write, and write them in one syscall. + Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */ + { + HIST_ENTRY **the_history; /* local */ + register int j; + int buffer_size; + char *buffer; + + the_history = history_list (); + /* Calculate the total number of bytes to write. */ + for (buffer_size = 0, i = history_length - nelements; i < history_length; i++) + { + if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0]) + buffer_size += strlen (the_history[i]->timestamp) + 1; + buffer_size += strlen (the_history[i]->line) + 1; + } + + /* Allocate the buffer, and fill it. */ +#ifdef HISTORY_USE_MMAP + if (ftruncate (file, buffer_size+cursize) == -1) + goto mmap_error; + buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize); + if ((void *)buffer == MAP_FAILED) + { +mmap_error: + rv = errno; + close (file); + if (tempname) + unlink (tempname); + FREE (histname); + FREE (tempname); + return rv; + } +#else + buffer = (char *)malloc (buffer_size); + if (buffer == 0) + { + rv = errno; + close (file); + if (tempname) + unlink (tempname); + FREE (histname); + FREE (tempname); + return rv; + } +#endif + + for (j = 0, i = history_length - nelements; i < history_length; i++) + { + if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0]) + { + strcpy (buffer + j, the_history[i]->timestamp); + j += strlen (the_history[i]->timestamp); + buffer[j++] = '\n'; + } + strcpy (buffer + j, the_history[i]->line); + j += strlen (the_history[i]->line); + buffer[j++] = '\n'; + } + +#ifdef HISTORY_USE_MMAP + if (msync (buffer, buffer_size, MS_ASYNC) != 0 || munmap (buffer, buffer_size) != 0) + rv = errno; +#else + if (write (file, buffer, buffer_size) < 0) + rv = errno; + xfree (buffer); +#endif + } + + history_lines_written_to_file = nelements; + + if (close (file) < 0 && rv == 0) + rv = errno; + + if (rv == 0 && histname && tempname) + rv = histfile_restore (tempname, histname); + + if (rv != 0) + { + rv = errno; + if (tempname) + unlink (tempname); + history_lines_written_to_file = 0; + } + +#if defined (HAVE_CHOWN) + /* Make sure the new filename is owned by the same user as the old. If one + user is running this, it's a no-op. If the shell is running after sudo + with a shared history file, we don't want to leave the history file + owned by root. */ + if (rv == 0 && exists) + mode = chown (histname, finfo.st_uid, finfo.st_gid); +#endif + + FREE (histname); + FREE (tempname); + + return (rv); +} + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +int +append_history (int nelements, const char *filename) +{ + return (history_do_write (filename, nelements, HISTORY_APPEND)); +} + +/* Overwrite FILENAME with the current history. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history ().*/ +int +write_history (const char *filename) +{ + return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); +} diff --git a/utshell-0.5.0/lib/readline/histlib.h b/utshell-0.5.0/lib/readline/histlib.h new file mode 100644 index 00000000..9627b245 --- /dev/null +++ b/utshell-0.5.0/lib/readline/histlib.h @@ -0,0 +1,85 @@ +/* histlib.h -- internal definitions for the history library. */ + +/* Copyright (C) 1989-2009 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +#if !defined (_HISTLIB_H_) +#define _HISTLIB_H_ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((n) == 0) ? (1) \ + : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#ifndef savestring +#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) +#endif + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifndef _rl_digit_p +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') +#endif + +#ifndef _rl_digit_value +#define _rl_digit_value(c) ((c) - '0') +#endif + +#ifndef member +# if !defined (strchr) && !defined (__STDC__) +extern char *strchr (); +# endif /* !strchr && !__STDC__ */ +#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) +#endif + +#ifndef FREE +# define FREE(x) if (x) free (x) +#endif + +/* Possible history errors passed to hist_error. */ +#define EVENT_NOT_FOUND 0 +#define BAD_WORD_SPEC 1 +#define SUBST_FAILED 2 +#define BAD_MODIFIER 3 +#define NO_PREV_SUBST 4 + +/* Possible definitions for history starting point specification. */ +#define NON_ANCHORED_SEARCH 0 +#define ANCHORED_SEARCH 0x01 +#define PATTERN_SEARCH 0x02 + +/* Possible definitions for what style of writing the history file we want. */ +#define HISTORY_APPEND 0 +#define HISTORY_OVERWRITE 1 + +/* internal extern function declarations used by other parts of the library */ + +/* histsearch.c */ +extern int _hs_history_patsearch PARAMS((const char *, int, int)); + +#endif /* !_HISTLIB_H_ */ diff --git a/utshell-0.5.0/lib/readline/history.c b/utshell-0.5.0/lib/readline/history.c new file mode 100644 index 00000000..67158b14 --- /dev/null +++ b/utshell-0.5.0/lib/readline/history.c @@ -0,0 +1,607 @@ +/* history.c -- standalone history library */ + +/* Copyright (C) 1989-2017 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +/* The goal is to make the implementation transparent, so that you + don't have to know what data types are used, just what functions + you can call. I think I have done that. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include "history.h" +#include "histlib.h" + +#include "xmalloc.h" + +#if !defined (errno) +extern int errno; +#endif + +/* How big to make the_history when we first allocate it. */ +#define DEFAULT_HISTORY_INITIAL_SIZE 502 + +#define MAX_HISTORY_INITIAL_SIZE 8192 + +/* The number of slots to increase the_history by. */ +#define DEFAULT_HISTORY_GROW_SIZE 50 + +static char *hist_inittime PARAMS((void)); + +/* **************************************************************** */ +/* */ +/* History Functions */ +/* */ +/* **************************************************************** */ + +/* An array of HIST_ENTRY. This is where we store the history. */ +static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL; + +/* Non-zero means that we have enforced a limit on the amount of + history that we save. */ +static int history_stifled; + +/* The current number of slots allocated to the input_history. */ +static int history_size; + +/* If HISTORY_STIFLED is non-zero, then this is the maximum number of + entries to remember. */ +int history_max_entries; +int max_input_history; /* backwards compatibility */ + +/* The current location of the interactive history pointer. Just makes + life easier for outside callers. */ +int history_offset; + +/* The number of strings currently stored in the history list. */ +int history_length; + +/* The logical `base' of the history array. It defaults to 1. */ +int history_base = 1; + +/* Return the current HISTORY_STATE of the history. */ +HISTORY_STATE * +history_get_history_state (void) +{ + HISTORY_STATE *state; + + state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE)); + state->entries = the_history; + state->offset = history_offset; + state->length = history_length; + state->size = history_size; + state->flags = 0; + if (history_stifled) + state->flags |= HS_STIFLED; + + return (state); +} + +/* Set the state of the current history array to STATE. */ +void +history_set_history_state (HISTORY_STATE *state) +{ + the_history = state->entries; + history_offset = state->offset; + history_length = state->length; + history_size = state->size; + if (state->flags & HS_STIFLED) + history_stifled = 1; +} + +/* Begin a session in which the history functions might be used. This + initializes interactive variables. */ +void +using_history (void) +{ + history_offset = history_length; +} + +/* Return the number of bytes that the primary history entries are using. + This just adds up the lengths of the_history->lines and the associated + timestamps. */ +int +history_total_bytes (void) +{ + register int i, result; + + for (i = result = 0; the_history && the_history[i]; i++) + result += HISTENT_BYTES (the_history[i]); + + return (result); +} + +/* Returns the magic number which says what history element we are + looking at now. In this implementation, it returns history_offset. */ +int +where_history (void) +{ + return (history_offset); +} + +/* Make the current history item be the one at POS, an absolute index. + Returns zero if POS is out of range, else non-zero. */ +int +history_set_pos (int pos) +{ + if (pos > history_length || pos < 0 || !the_history) + return (0); + history_offset = pos; + return (1); +} + +/* Return the current history array. The caller has to be careful, since this + is the actual array of data, and could be bashed or made corrupt easily. + The array is terminated with a NULL pointer. */ +HIST_ENTRY ** +history_list (void) +{ + return (the_history); +} + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +HIST_ENTRY * +current_history (void) +{ + return ((history_offset == history_length) || the_history == 0) + ? (HIST_ENTRY *)NULL + : the_history[history_offset]; +} + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry then return + a NULL pointer. */ +HIST_ENTRY * +previous_history (void) +{ + return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL; +} + +/* Move history_offset forward to the next history entry, and return + a pointer to that entry. If there is no next entry then return a + NULL pointer. */ +HIST_ENTRY * +next_history (void) +{ + return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset]; +} + +/* Return the history entry which is logically at OFFSET in the history array. + OFFSET is relative to history_base. */ +HIST_ENTRY * +history_get (int offset) +{ + int local_index; + + local_index = offset - history_base; + return (local_index >= history_length || local_index < 0 || the_history == 0) + ? (HIST_ENTRY *)NULL + : the_history[local_index]; +} + +HIST_ENTRY * +alloc_history_entry (char *string, char *ts) +{ + HIST_ENTRY *temp; + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + + temp->line = string ? savestring (string) : string; + temp->data = (char *)NULL; + temp->timestamp = ts; + + return temp; +} + +time_t +history_get_time (HIST_ENTRY *hist) +{ + char *ts; + time_t t; + + if (hist == 0 || hist->timestamp == 0) + return 0; + ts = hist->timestamp; + if (ts[0] != history_comment_char) + return 0; + errno = 0; + t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */ + if (errno == ERANGE) + return (time_t)0; + return t; +} + +static char * +hist_inittime (void) +{ + time_t t; + char ts[64], *ret; + + t = (time_t) time ((time_t *)0); +#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */ + snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t); +#else + sprintf (ts, "X%lu", (unsigned long) t); +#endif + ret = savestring (ts); + ret[0] = history_comment_char; + + return ret; +} + +/* Place STRING at the end of the history list. The data field + is set to NULL. */ +void +add_history (const char *string) +{ + HIST_ENTRY *temp; + int new_length; + + if (history_stifled && (history_length == history_max_entries)) + { + register int i; + + /* If the history is stifled, and history_length is zero, + and it equals history_max_entries, we don't save items. */ + if (history_length == 0) + return; + + /* If there is something in the slot, then remove it. */ + if (the_history[0]) + (void) free_history_entry (the_history[0]); + + /* Copy the rest of the entries, moving down one slot. Copy includes + trailing NULL. */ + memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *)); + + new_length = history_length; + history_base++; + } + else + { + if (history_size == 0) + { + if (history_stifled && history_max_entries > 0) + history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE) + ? MAX_HISTORY_INITIAL_SIZE + : history_max_entries + 2; + else + history_size = DEFAULT_HISTORY_INITIAL_SIZE; + the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); + new_length = 1; + } + else + { + if (history_length == (history_size - 1)) + { + history_size += DEFAULT_HISTORY_GROW_SIZE; + the_history = (HIST_ENTRY **) + xrealloc (the_history, history_size * sizeof (HIST_ENTRY *)); + } + new_length = history_length + 1; + } + } + + temp = alloc_history_entry ((char *)string, hist_inittime ()); + + the_history[new_length] = (HIST_ENTRY *)NULL; + the_history[new_length - 1] = temp; + history_length = new_length; +} + +/* Change the time stamp of the most recent history entry to STRING. */ +void +add_history_time (const char *string) +{ + HIST_ENTRY *hs; + + if (string == 0 || history_length < 1) + return; + hs = the_history[history_length - 1]; + FREE (hs->timestamp); + hs->timestamp = savestring (string); +} + +/* Free HIST and return the data so the calling application can free it + if necessary and desired. */ +histdata_t +free_history_entry (HIST_ENTRY *hist) +{ + histdata_t x; + + if (hist == 0) + return ((histdata_t) 0); + FREE (hist->line); + FREE (hist->timestamp); + x = hist->data; + xfree (hist); + return (x); +} + +HIST_ENTRY * +copy_history_entry (HIST_ENTRY *hist) +{ + HIST_ENTRY *ret; + char *ts; + + if (hist == 0) + return hist; + + ret = alloc_history_entry (hist->line, (char *)NULL); + + ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp; + ret->timestamp = ts; + + ret->data = hist->data; + + return ret; +} + +/* Make the history entry at WHICH have LINE and DATA. This returns + the old entry so you can dispose of the data. In the case of an + invalid WHICH, a NULL pointer is returned. */ +HIST_ENTRY * +replace_history_entry (int which, const char *line, histdata_t data) +{ + HIST_ENTRY *temp, *old_value; + + if (which < 0 || which >= history_length) + return ((HIST_ENTRY *)NULL); + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + old_value = the_history[which]; + + temp->line = savestring (line); + temp->data = data; + temp->timestamp = savestring (old_value->timestamp); + the_history[which] = temp; + + return (old_value); +} + +/* Append LINE to the history line at offset WHICH, adding a newline to the + end of the current line first. This can be used to construct multi-line + history entries while reading lines from the history file. */ +void +_hs_append_history_line (int which, const char *line) +{ + HIST_ENTRY *hent; + size_t newlen, curlen, minlen; + char *newline; + + hent = the_history[which]; + curlen = strlen (hent->line); + minlen = curlen + strlen (line) + 2; /* min space needed */ + if (curlen > 256) /* XXX - for now */ + { + newlen = 512; /* now realloc in powers of 2 */ + /* we recalcluate every time; the operations are cheap */ + while (newlen < minlen) + newlen <<= 1; + } + else + newlen = minlen; + /* Assume that realloc returns the same pointer and doesn't try a new + alloc/copy if the new size is the same as the one last passed. */ + newline = realloc (hent->line, newlen); + if (newline) + { + hent->line = newline; + hent->line[curlen++] = '\n'; + strcpy (hent->line + curlen, line); + } +} + +/* Replace the DATA in the specified history entries, replacing OLD with + NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace + all of the history entries where entry->data == OLD; WHICH == -2 means + to replace the `newest' history entry where entry->data == OLD; and + WHICH >= 0 means to replace that particular history entry's data, as + long as it matches OLD. */ +void +_hs_replace_history_data (int which, histdata_t *old, histdata_t *new) +{ + HIST_ENTRY *entry; + register int i, last; + + if (which < -2 || which >= history_length || history_length == 0 || the_history == 0) + return; + + if (which >= 0) + { + entry = the_history[which]; + if (entry && entry->data == old) + entry->data = new; + return; + } + + last = -1; + for (i = 0; i < history_length; i++) + { + entry = the_history[i]; + if (entry == 0) + continue; + if (entry->data == old) + { + last = i; + if (which == -1) + entry->data = new; + } + } + if (which == -2 && last >= 0) + { + entry = the_history[last]; + entry->data = new; /* XXX - we don't check entry->old */ + } +} + +/* Remove history element WHICH from the history. The removed + element is returned to you so you can free the line, data, + and containing structure. */ +HIST_ENTRY * +remove_history (int which) +{ + HIST_ENTRY *return_value; + register int i; +#if 1 + int nentries; + HIST_ENTRY **start, **end; +#endif + + if (which < 0 || which >= history_length || history_length == 0 || the_history == 0) + return ((HIST_ENTRY *)NULL); + + return_value = the_history[which]; + +#if 1 + /* Copy the rest of the entries, moving down one slot. Copy includes + trailing NULL. */ + nentries = history_length - which; + start = the_history + which; + end = start + 1; + memmove (start, end, nentries * sizeof (HIST_ENTRY *)); +#else + for (i = which; i < history_length; i++) + the_history[i] = the_history[i + 1]; +#endif + + history_length--; + + return (return_value); +} + +HIST_ENTRY ** +remove_history_range (int first, int last) +{ + HIST_ENTRY **return_value; + register int i; + int nentries; + HIST_ENTRY **start, **end; + + if (the_history == 0 || history_length == 0) + return ((HIST_ENTRY **)NULL); + if (first < 0 || first >= history_length || last < 0 || last >= history_length) + return ((HIST_ENTRY **)NULL); + if (first > last) + return (HIST_ENTRY **)NULL; + + nentries = last - first + 1; + return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *)); + if (return_value == 0) + return return_value; + + /* Return all the deleted entries in a list */ + for (i = first ; i <= last; i++) + return_value[i - first] = the_history[i]; + return_value[i - first] = (HIST_ENTRY *)NULL; + + /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes + trailing NULL. */ + start = the_history + first; + end = the_history + last + 1; + memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *)); + + history_length -= nentries; + + return (return_value); +} + +/* Stifle the history list, remembering only MAX number of lines. */ +void +stifle_history (int max) +{ + register int i, j; + + if (max < 0) + max = 0; + + if (history_length > max) + { + /* This loses because we cannot free the data. */ + for (i = 0, j = history_length - max; i < j; i++) + free_history_entry (the_history[i]); + + history_base = i; + for (j = 0, i = history_length - max; j < max; i++, j++) + the_history[j] = the_history[i]; + the_history[j] = (HIST_ENTRY *)NULL; + history_length = j; + } + + history_stifled = 1; + max_input_history = history_max_entries = max; +} + +/* Stop stifling the history. This returns the previous maximum + number of history entries. The value is positive if the history + was stifled, negative if it wasn't. */ +int +unstifle_history (void) +{ + if (history_stifled) + { + history_stifled = 0; + return (history_max_entries); + } + else + return (-history_max_entries); +} + +int +history_is_stifled (void) +{ + return (history_stifled); +} + +void +clear_history (void) +{ + register int i; + + /* This loses because we cannot free the data. */ + for (i = 0; i < history_length; i++) + { + free_history_entry (the_history[i]); + the_history[i] = (HIST_ENTRY *)NULL; + } + + history_offset = history_length = 0; + history_base = 1; /* reset history base to default */ +} diff --git a/utshell-0.5.0/lib/readline/history.h b/utshell-0.5.0/lib/readline/history.h new file mode 100644 index 00000000..cc3de29a --- /dev/null +++ b/utshell-0.5.0/lib/readline/history.h @@ -0,0 +1,286 @@ +/* history.h -- the names of functions that you can call in history. */ + +/* Copyright (C) 1989-2015 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +#ifndef _HISTORY_H_ +#define _HISTORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include /* XXX - for history timestamp code */ + +#if defined READLINE_LIBRARY +# include "rlstdc.h" +# include "rltypedefs.h" +#else +# include +# include +#endif + +#ifdef __STDC__ +typedef void *histdata_t; +#else +typedef char *histdata_t; +#endif + +/* The structure used to store a history entry. */ +typedef struct _hist_entry { + char *line; + char *timestamp; /* char * rather than time_t for read/write */ + histdata_t data; +} HIST_ENTRY; + +/* Size of the history-library-managed space in history entry HS. */ +#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp)) + +/* A structure used to pass the current state of the history stuff around. */ +typedef struct _hist_state { + HIST_ENTRY **entries; /* Pointer to the entries themselves. */ + int offset; /* The location pointer within this array. */ + int length; /* Number of elements within this array. */ + int size; /* Number of slots allocated to this array. */ + int flags; +} HISTORY_STATE; + +/* Flag values for the `flags' member of HISTORY_STATE. */ +#define HS_STIFLED 0x01 + +/* Initialization and state management. */ + +/* Begin a session in which the history functions might be used. This + just initializes the interactive variables. */ +extern void using_history PARAMS((void)); + +/* Return the current HISTORY_STATE of the history. */ +extern HISTORY_STATE *history_get_history_state PARAMS((void)); + +/* Set the state of the current history array to STATE. */ +extern void history_set_history_state PARAMS((HISTORY_STATE *)); + +/* Manage the history list. */ + +/* Place STRING at the end of the history list. + The associated data field (if any) is set to NULL. */ +extern void add_history PARAMS((const char *)); + +/* Change the timestamp associated with the most recent history entry to + STRING. */ +extern void add_history_time PARAMS((const char *)); + +/* Remove an entry from the history list. WHICH is the magic number that + tells us which element to delete. The elements are numbered from 0. */ +extern HIST_ENTRY *remove_history PARAMS((int)); + +/* Remove a set of entries from the history list: FIRST to LAST, inclusive */ +extern HIST_ENTRY **remove_history_range PARAMS((int, int)); + +/* Allocate a history entry consisting of STRING and TIMESTAMP and return + a pointer to it. */ +extern HIST_ENTRY *alloc_history_entry PARAMS((char *, char *)); + +/* Copy the history entry H, but not the (opaque) data pointer */ +extern HIST_ENTRY *copy_history_entry PARAMS((HIST_ENTRY *)); + +/* Free the history entry H and return any application-specific data + associated with it. */ +extern histdata_t free_history_entry PARAMS((HIST_ENTRY *)); + +/* Make the history entry at WHICH have LINE and DATA. This returns + the old entry so you can dispose of the data. In the case of an + invalid WHICH, a NULL pointer is returned. */ +extern HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t)); + +/* Clear the history list and start over. */ +extern void clear_history PARAMS((void)); + +/* Stifle the history list, remembering only MAX number of entries. */ +extern void stifle_history PARAMS((int)); + +/* Stop stifling the history. This returns the previous amount the + history was stifled by. The value is positive if the history was + stifled, negative if it wasn't. */ +extern int unstifle_history PARAMS((void)); + +/* Return 1 if the history is stifled, 0 if it is not. */ +extern int history_is_stifled PARAMS((void)); + +/* Information about the history list. */ + +/* Return a NULL terminated array of HIST_ENTRY which is the current input + history. Element 0 of this list is the beginning of time. If there + is no history, return NULL. */ +extern HIST_ENTRY **history_list PARAMS((void)); + +/* Returns the number which says what history element we are now + looking at. */ +extern int where_history PARAMS((void)); + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +extern HIST_ENTRY *current_history PARAMS((void)); + +/* Return the history entry which is logically at OFFSET in the history + array. OFFSET is relative to history_base. */ +extern HIST_ENTRY *history_get PARAMS((int)); + +/* Return the timestamp associated with the HIST_ENTRY * passed as an + argument */ +extern time_t history_get_time PARAMS((HIST_ENTRY *)); + +/* Return the number of bytes that the primary history entries are using. + This just adds up the lengths of the_history->lines. */ +extern int history_total_bytes PARAMS((void)); + +/* Moving around the history list. */ + +/* Set the position in the history list to POS. */ +extern int history_set_pos PARAMS((int)); + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry, return + a NULL pointer. */ +extern HIST_ENTRY *previous_history PARAMS((void)); + +/* Move history_offset forward to the next item in the input_history, + and return the a pointer to that entry. If there is no next entry, + return a NULL pointer. */ +extern HIST_ENTRY *next_history PARAMS((void)); + +/* Searching the history list. */ + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, + else through subsequent. If the string is found, then + current_history () is the history entry, and the value of this function + is the offset in the line of that history entry that the string was + found in. Otherwise, nothing is changed, and a -1 is returned. */ +extern int history_search PARAMS((const char *, int)); + +/* Search the history for STRING, starting at history_offset. + The search is anchored: matching lines must begin with string. + DIRECTION is as in history_search(). */ +extern int history_search_prefix PARAMS((const char *, int)); + +/* Search for STRING in the history list, starting at POS, an + absolute index into the list. DIR, if negative, says to search + backwards from POS, else forwards. + Returns the absolute index of the history element where STRING + was found, or -1 otherwise. */ +extern int history_search_pos PARAMS((const char *, int, int)); + +/* Managing the history file. */ + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +extern int read_history PARAMS((const char *)); + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +extern int read_history_range PARAMS((const char *, int, int)); + +/* Write the current history to FILENAME. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history (). */ +extern int write_history PARAMS((const char *)); + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +extern int append_history PARAMS((int, const char *)); + +/* Truncate the history file, leaving only the last NLINES lines. */ +extern int history_truncate_file PARAMS((const char *, int)); + +/* History expansion. */ + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + -1) If there was an error in expansion. + 2) If the returned line should just be printed. + + If an error occurred in expansion, then OUTPUT contains a descriptive + error message. */ +extern int history_expand PARAMS((char *, char **)); + +/* Extract a string segment consisting of the FIRST through LAST + arguments present in STRING. Arguments are broken up as in + the shell. */ +extern char *history_arg_extract PARAMS((int, int, const char *)); + +/* Return the text of the history event beginning at the current + offset into STRING. Pass STRING with *INDEX equal to the + history_expansion_char that begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. */ +extern char *get_history_event PARAMS((const char *, int *, int)); + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +extern char **history_tokenize PARAMS((const char *)); + +/* Exported history variables. */ +extern int history_base; +extern int history_length; +extern int history_max_entries; +extern int history_offset; + +extern int history_lines_read_from_file; +extern int history_lines_written_to_file; + +extern char history_expansion_char; +extern char history_subst_char; +extern char *history_word_delimiters; +extern char history_comment_char; +extern char *history_no_expand_chars; +extern char *history_search_delimiter_chars; + +extern int history_quotes_inhibit_expansion; +extern int history_quoting_state; + +extern int history_write_timestamps; + +/* These two are undocumented; the second is reserved for future use */ +extern int history_multiline_entries; +extern int history_file_version; + +/* Backwards compatibility */ +extern int max_input_history; + +/* If set, this function is called to decide whether or not a particular + history expansion should be treated as a special case for the calling + application and not expanded. */ +extern rl_linebuf_func_t *history_inhibit_expansion_function; + +#ifdef __cplusplus +} +#endif + +#endif /* !_HISTORY_H_ */ diff --git a/utshell-0.5.0/lib/readline/histsearch.c b/utshell-0.5.0/lib/readline/histsearch.c new file mode 100644 index 00000000..7a426c96 --- /dev/null +++ b/utshell-0.5.0/lib/readline/histsearch.c @@ -0,0 +1,287 @@ +/* histsearch.c -- searching the history list. */ + +/* Copyright (C) 1989, 1992-2009,2017 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (HAVE_FNMATCH) +# include +#endif + +#include "history.h" +#include "histlib.h" +#include "xmalloc.h" + +/* The list of alternate characters that can delimit a history search + string. */ +char *history_search_delimiter_chars = (char *)NULL; + +static int history_search_internal PARAMS((const char *, int, int)); + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, else + through subsequent. If ANCHORED is non-zero, the string must + appear at the beginning of a history line, otherwise, the string + may appear anywhere in the line. If the string is found, then + current_history () is the history entry, and the value of this + function is the offset in the line of that history entry that the + string was found in. Otherwise, nothing is changed, and a -1 is + returned. */ + +static int +history_search_internal (const char *string, int direction, int flags) +{ + register int i, reverse; + register char *line; + register int line_index; + int string_len, anchored, patsearch; + HIST_ENTRY **the_history; /* local */ + + i = history_offset; + reverse = (direction < 0); + anchored = (flags & ANCHORED_SEARCH); +#if defined (HAVE_FNMATCH) + patsearch = (flags & PATTERN_SEARCH); +#else + patsearch = 0; +#endif + + /* Take care of trivial cases first. */ + if (string == 0 || *string == '\0') + return (-1); + + if (!history_length || ((i >= history_length) && !reverse)) + return (-1); + + if (reverse && (i >= history_length)) + i = history_length - 1; + +#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) + + the_history = history_list (); + string_len = strlen (string); + while (1) + { + /* Search each line in the history list for STRING. */ + + /* At limit for direction? */ + if ((reverse && i < 0) || (!reverse && i == history_length)) + return (-1); + + line = the_history[i]->line; + line_index = strlen (line); + + /* If STRING is longer than line, no match. */ + if (patsearch == 0 && (string_len > line_index)) + { + NEXT_LINE (); + continue; + } + + /* Handle anchored searches first. */ + if (anchored == ANCHORED_SEARCH) + { +#if defined (HAVE_FNMATCH) + if (patsearch) + { + if (fnmatch (string, line, 0) == 0) + { + history_offset = i; + return (0); + } + } + else +#endif + if (STREQN (string, line, string_len)) + { + history_offset = i; + return (0); + } + + NEXT_LINE (); + continue; + } + + /* Do substring search. */ + if (reverse) + { + line_index -= (patsearch == 0) ? string_len : 1; + + while (line_index >= 0) + { +#if defined (HAVE_FNMATCH) + if (patsearch) + { + if (fnmatch (string, line + line_index, 0) == 0) + { + history_offset = i; + return (line_index); + } + } + else +#endif + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index--; + } + } + else + { + register int limit; + + limit = line_index - string_len + 1; + line_index = 0; + + while (line_index < limit) + { +#if defined (HAVE_FNMATCH) + if (patsearch) + { + if (fnmatch (string, line + line_index, 0) == 0) + { + history_offset = i; + return (line_index); + } + } + else +#endif + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index++; + } + } + NEXT_LINE (); + } +} + +int +_hs_history_patsearch (const char *string, int direction, int flags) +{ + char *pat; + size_t len, start; + int ret, unescaped_backslash; + +#if defined (HAVE_FNMATCH) + /* Assume that the string passed does not have a leading `^' and any + anchored search request is captured in FLAGS */ + len = strlen (string); + ret = len - 1; + /* fnmatch is required to reject a pattern that ends with an unescaped + backslash */ + if (unescaped_backslash = (string[ret] == '\\')) + { + while (ret > 0 && string[--ret] == '\\') + unescaped_backslash = 1 - unescaped_backslash; + } + if (unescaped_backslash) + return -1; + pat = (char *)xmalloc (len + 3); + /* If the search string is not anchored, we'll be calling fnmatch (assuming + we have it). Prefix a `*' to the front of the search string so we search + anywhere in the line. */ + if ((flags & ANCHORED_SEARCH) == 0 && string[0] != '*') + { + pat[0] = '*'; + start = 1; + len++; + } + else + { + start = 0; + } + + /* Attempt to reduce the number of searches by tacking a `*' onto the end + of a pattern that doesn't have one. Assume a pattern that ends in a + backslash contains an even number of trailing backslashes; we check + above */ + strcpy (pat + start, string); + if (pat[len - 1] != '*') + { + pat[len] = '*'; /* XXX */ + pat[len+1] = '\0'; + } +#else + pat = string; +#endif + + ret = history_search_internal (pat, direction, flags|PATTERN_SEARCH); + + if (pat != string) + free (pat); + return ret; +} + +/* Do a non-anchored search for STRING through the history in DIRECTION. */ +int +history_search (const char *string, int direction) +{ + return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); +} + +/* Do an anchored search for string through the history in DIRECTION. */ +int +history_search_prefix (const char *string, int direction) +{ + return (history_search_internal (string, direction, ANCHORED_SEARCH)); +} + +/* Search for STRING in the history list. DIR is < 0 for searching + backwards. POS is an absolute index into the history list at + which point to begin searching. */ +int +history_search_pos (const char *string, int dir, int pos) +{ + int ret, old; + + old = where_history (); + history_set_pos (pos); + if (history_search (string, dir) == -1) + { + history_set_pos (old); + return (-1); + } + ret = where_history (); + history_set_pos (old); + return ret; +} diff --git a/utshell-0.5.0/lib/readline/input.c b/utshell-0.5.0/lib/readline/input.c new file mode 100644 index 00000000..61b0fde3 --- /dev/null +++ b/utshell-0.5.0/lib/readline/input.c @@ -0,0 +1,715 @@ +/* input.c -- character input functions for readline. */ + +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (__TANDEM) +# define _XOPEN_SOURCE_EXTENDED 1 +# define _TANDEM_SOURCE 1 +# include +#endif + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +#include "posixselect.h" + +#if defined (FIONREAD_IN_SYS_IOCTL) +# include +#endif + +#include +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +/* What kind of non-blocking I/O do we have? */ +#if !defined (O_NDELAY) && defined (O_NONBLOCK) +# define O_NDELAY O_NONBLOCK /* Posix style */ +#endif + +#if defined (HAVE_PSELECT) +extern sigset_t _rl_orig_sigset; +#endif + +/* Non-null means it is a pointer to a function to run while waiting for + character input. */ +rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; + +/* A function to call if a read(2) is interrupted by a signal. */ +rl_hook_func_t *rl_signal_event_hook = (rl_hook_func_t *)NULL; + +/* A function to replace _rl_input_available for applications using the + callback interface. */ +rl_hook_func_t *rl_input_available_hook = (rl_hook_func_t *)NULL; + +rl_getc_func_t *rl_getc_function = rl_getc; + +static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */ + +static int ibuffer_space PARAMS((void)); +static int rl_get_char PARAMS((int *)); +static int rl_gather_tyi PARAMS((void)); + +/* Windows isatty returns true for every character device, including the null + device, so we need to perform additional checks. */ +#if defined (_WIN32) && !defined (__CYGWIN__) +#include +#include +#define WIN32_LEAN_AND_MEAN 1 +#include + +int +win32_isatty (int fd) +{ + if (_isatty(fd)) + { + HANDLE h; + DWORD ignored; + + if ((h = (HANDLE) _get_osfhandle (fd)) == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return 0; + } + if (GetConsoleMode (h, &ignored) != 0) + return 1; + } + errno = ENOTTY; + return 0; +} + +#define isatty(x) win32_isatty(x) +#endif + +/* **************************************************************** */ +/* */ +/* Character Input Buffering */ +/* */ +/* **************************************************************** */ + +static int pop_index, push_index; +static unsigned char ibuffer[512]; +static int ibuffer_len = sizeof (ibuffer) - 1; + +#define any_typein (push_index != pop_index) + +int +_rl_any_typein (void) +{ + return any_typein; +} + +int +_rl_pushed_input_available (void) +{ + return (push_index != pop_index); +} + +/* Return the amount of space available in the buffer for stuffing + characters. */ +static int +ibuffer_space (void) +{ + if (pop_index > push_index) + return (pop_index - push_index - 1); + else + return (ibuffer_len - (push_index - pop_index)); +} + +/* Get a key from the buffer of characters to be read. + Return the key in KEY. + Result is non-zero if there was a key, or 0 if there wasn't. */ +static int +rl_get_char (int *key) +{ + if (push_index == pop_index) + return (0); + + *key = ibuffer[pop_index++]; +#if 0 + if (pop_index >= ibuffer_len) +#else + if (pop_index > ibuffer_len) +#endif + pop_index = 0; + + return (1); +} + +/* Stuff KEY into the *front* of the input buffer. + Returns non-zero if successful, zero if there is + no space left in the buffer. */ +int +_rl_unget_char (int key) +{ + if (ibuffer_space ()) + { + pop_index--; + if (pop_index < 0) + pop_index = ibuffer_len; + ibuffer[pop_index] = key; + return (1); + } + return (0); +} + +/* If a character is available to be read, then read it and stuff it into + IBUFFER. Otherwise, just return. Returns number of characters read + (0 if none available) and -1 on error (EIO). */ +static int +rl_gather_tyi (void) +{ + int tty; + register int tem, result; + int chars_avail, k; + char input; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif + + chars_avail = 0; + input = 0; + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout); + result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); + if (result <= 0) + return 0; /* Nothing to read. */ +#endif + + result = -1; + errno = 0; +#if defined (FIONREAD) + result = ioctl (tty, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; + if (result == -1) + chars_avail = 0; +#endif + +#if defined (O_NDELAY) + if (result == -1) + { + tem = fcntl (tty, F_GETFL, 0); + + fcntl (tty, F_SETFL, (tem | O_NDELAY)); + chars_avail = read (tty, &input, 1); + + fcntl (tty, F_SETFL, tem); + if (chars_avail == -1 && errno == EAGAIN) + return 0; + if (chars_avail == -1 && errno == EIO) + return -1; + if (chars_avail == 0) /* EOF */ + { + rl_stuff_char (EOF); + return (0); + } + } +#endif /* O_NDELAY */ + +#if defined (__MINGW32__) + /* Use getch/_kbhit to check for available console input, in the same way + that we read it normally. */ + chars_avail = isatty (tty) ? _kbhit () : 0; + result = 0; +#endif + + /* If there's nothing available, don't waste time trying to read + something. */ + if (chars_avail <= 0) + return 0; + + tem = ibuffer_space (); + + if (chars_avail > tem) + chars_avail = tem; + + /* One cannot read all of the available input. I can only read a single + character at a time, or else programs which require input can be + thwarted. If the buffer is larger than one character, I lose. + Damn! */ + if (tem < ibuffer_len) + chars_avail = 0; + + if (result != -1) + { + while (chars_avail--) + { + RL_CHECK_SIGNALS (); + k = (*rl_getc_function) (rl_instream); + if (rl_stuff_char (k) == 0) + break; /* some problem; no more room */ + if (k == NEWLINE || k == RETURN) + break; + } + } + else + { + if (chars_avail) + rl_stuff_char (input); + } + + return 1; +} + +int +rl_set_keyboard_input_timeout (int u) +{ + int o; + + o = _keyboard_input_timeout; + if (u >= 0) + _keyboard_input_timeout = u; + return (o); +} + +/* Is there input available to be read on the readline input file + descriptor? Only works if the system has select(2) or FIONREAD. + Uses the value of _keyboard_input_timeout as the timeout; if another + readline function wants to specify a timeout and not leave it up to + the user, it should use _rl_input_queued(timeout_value_in_microseconds) + instead. */ +int +_rl_input_available (void) +{ +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif +#if !defined (HAVE_SELECT) && defined(FIONREAD) + int chars_avail; +#endif + int tty; + + if (rl_input_available_hook) + return (*rl_input_available_hook) (); + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout); + return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); +#else + +#if defined (FIONREAD) + if (ioctl (tty, FIONREAD, &chars_avail) == 0) + return (chars_avail); +#endif + +#endif + +#if defined (__MINGW32__) + if (isatty (tty)) + return (_kbhit ()); +#endif + + return 0; +} + +int +_rl_nchars_available () +{ + int chars_avail, fd, result; + + chars_avail = 0; + +#if defined (FIONREAD) + fd = fileno (rl_instream); + errno = 0; + result = ioctl (fd, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; +#endif + + return chars_avail; +} + +int +_rl_input_queued (int t) +{ + int old_timeout, r; + + old_timeout = rl_set_keyboard_input_timeout (t); + r = _rl_input_available (); + rl_set_keyboard_input_timeout (old_timeout); + return r; +} + +void +_rl_insert_typein (int c) +{ + int key, t, i; + char *string; + + i = key = 0; + string = (char *)xmalloc (ibuffer_len + 1); + string[i++] = (char) c; + + while ((t = rl_get_char (&key)) && + _rl_keymap[key].type == ISFUNC && + _rl_keymap[key].function == rl_insert) + string[i++] = key; + + if (t) + _rl_unget_char (key); + + string[i] = '\0'; + rl_insert_text (string); + xfree (string); +} + +/* Add KEY to the buffer of characters to be read. Returns 1 if the + character was stuffed correctly; 0 otherwise. */ +int +rl_stuff_char (int key) +{ + if (ibuffer_space () == 0) + return 0; + + if (key == EOF) + { + key = NEWLINE; + rl_pending_input = EOF; + RL_SETSTATE (RL_STATE_INPUTPENDING); + } + ibuffer[push_index++] = key; +#if 0 + if (push_index >= ibuffer_len) +#else + if (push_index > ibuffer_len) +#endif + push_index = 0; + + return 1; +} + +/* Make C be the next command to be executed. */ +int +rl_execute_next (int c) +{ + rl_pending_input = c; + RL_SETSTATE (RL_STATE_INPUTPENDING); + return 0; +} + +/* Clear any pending input pushed with rl_execute_next() */ +int +rl_clear_pending_input (void) +{ + rl_pending_input = 0; + RL_UNSETSTATE (RL_STATE_INPUTPENDING); + return 0; +} + +/* **************************************************************** */ +/* */ +/* Character Input */ +/* */ +/* **************************************************************** */ + +/* Read a key, including pending input. */ +int +rl_read_key (void) +{ + int c, r; + + if (rl_pending_input) + { + c = rl_pending_input; /* XXX - cast to unsigned char if > 0? */ + rl_clear_pending_input (); + } + else + { + /* If input is coming from a macro, then use that. */ + if (c = _rl_next_macro_key ()) + return ((unsigned char)c); + + /* If the user has an event function, then call it periodically. */ + if (rl_event_hook) + { + while (rl_event_hook) + { + if (rl_get_char (&c) != 0) + break; + + if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */ + { + rl_done = 1; + return (errno == EIO ? (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF) : '\n'); + } + else if (r > 0) /* read something */ + continue; + + RL_CHECK_SIGNALS (); + if (rl_done) /* XXX - experimental */ + return ('\n'); + (*rl_event_hook) (); + } + } + else + { + if (rl_get_char (&c) == 0) + c = (*rl_getc_function) (rl_instream); +/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d\r\n", _rl_caught_signal); */ + RL_CHECK_SIGNALS (); + } + } + + return (c); +} + +int +rl_getc (FILE *stream) +{ + int result; + unsigned char c; +#if defined (HAVE_PSELECT) + sigset_t empty_set; + fd_set readfds; +#endif + + while (1) + { + RL_CHECK_SIGNALS (); + + /* We know at this point that _rl_caught_signal == 0 */ + +#if defined (__MINGW32__) + if (isatty (fileno (stream))) + return (_getch ()); /* "There is no error return." */ +#endif + result = 0; +#if defined (HAVE_PSELECT) + FD_ZERO (&readfds); + FD_SET (fileno (stream), &readfds); +# if defined (HANDLE_SIGNALS) + result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &_rl_orig_sigset); +# else + sigemptyset (&empty_set); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set); + result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set); +# endif /* HANDLE_SIGNALS */ +#endif + if (result >= 0) + result = read (fileno (stream), &c, sizeof (unsigned char)); + + if (result == sizeof (unsigned char)) + return (c); + + /* If zero characters are returned, then the file that we are + reading from is empty! Return EOF in that case. */ + if (result == 0) + return (EOF); + +#if defined (__BEOS__) + if (errno == EINTR) + continue; +#endif + +#if defined (EWOULDBLOCK) +# define X_EWOULDBLOCK EWOULDBLOCK +#else +# define X_EWOULDBLOCK -99 +#endif + +#if defined (EAGAIN) +# define X_EAGAIN EAGAIN +#else +# define X_EAGAIN -99 +#endif + + if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) + { + if (sh_unset_nodelay_mode (fileno (stream)) < 0) + return (EOF); + continue; + } + +#undef X_EWOULDBLOCK +#undef X_EAGAIN + +/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */ + +handle_error: + /* If the error that we received was EINTR, then try again, + this is simply an interrupted system call to read (). We allow + the read to be interrupted if we caught SIGHUP, SIGTERM, or any + of the other signals readline treats specially. If the + application sets an event hook, call it for other signals. + Otherwise (not EINTR), some error occurred, also signifying EOF. */ + if (errno != EINTR) + return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); + /* fatal signals of interest */ +#if defined (SIGHUP) + else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM) +#else + else if (_rl_caught_signal == SIGTERM) +#endif + return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF); + /* keyboard-generated signals of interest */ +#if defined (SIGQUIT) + else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT) +#else + else if (_rl_caught_signal == SIGINT) +#endif + RL_CHECK_SIGNALS (); +#if defined (SIGTSTP) + else if (_rl_caught_signal == SIGTSTP) + RL_CHECK_SIGNALS (); +#endif + /* non-keyboard-generated signals of interest */ +#if defined (SIGWINCH) + else if (_rl_caught_signal == SIGWINCH) + RL_CHECK_SIGNALS (); +#endif /* SIGWINCH */ +#if defined (SIGALRM) + else if (_rl_caught_signal == SIGALRM +# if defined (SIGVTALRM) + || _rl_caught_signal == SIGVTALRM +# endif + ) + RL_CHECK_SIGNALS (); +#endif /* SIGALRM */ + + if (rl_signal_event_hook) + (*rl_signal_event_hook) (); + } +} + +#if defined (HANDLE_MULTIBYTE) +/* read multibyte char */ +int +_rl_read_mbchar (char *mbchar, int size) +{ + int mb_len, c; + size_t mbchar_bytes_length; + wchar_t wc; + mbstate_t ps, ps_back; + + memset(&ps, 0, sizeof (mbstate_t)); + memset(&ps_back, 0, sizeof (mbstate_t)); + + mb_len = 0; + while (mb_len < size) + { + c = (mb_len == 0) ? _rl_bracketed_read_key () : rl_read_key (); + + if (c < 0) + break; + + mbchar[mb_len++] = c; + + mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps); + if (mbchar_bytes_length == (size_t)(-1)) + break; /* invalid byte sequence for the current locale */ + else if (mbchar_bytes_length == (size_t)(-2)) + { + /* shorted bytes */ + ps = ps_back; + continue; + } + else if (mbchar_bytes_length == 0) + { + mbchar[0] = '\0'; /* null wide character */ + mb_len = 1; + break; + } + else if (mbchar_bytes_length > (size_t)(0)) + break; + } + + return mb_len; +} + +/* Read a multibyte-character string whose first character is FIRST into + the buffer MB of length MLEN. Returns the last character read, which + may be FIRST. Used by the search functions, among others. Very similar + to _rl_read_mbchar. */ +int +_rl_read_mbstring (int first, char *mb, int mlen) +{ + int i, c, n; + mbstate_t ps; + + c = first; + memset (mb, 0, mlen); + for (i = 0; c >= 0 && i < mlen; i++) + { + mb[i] = (char)c; + memset (&ps, 0, sizeof (mbstate_t)); + n = _rl_get_char_len (mb, &ps); + if (n == -2) + { + /* Read more for multibyte character */ + RL_SETSTATE (RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE (RL_STATE_MOREINPUT); + } + else + break; + } + return c; +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/utshell-0.5.0/lib/readline/isearch.c b/utshell-0.5.0/lib/readline/isearch.c new file mode 100644 index 00000000..080ba3cb --- /dev/null +++ b/utshell-0.5.0/lib/readline/isearch.c @@ -0,0 +1,890 @@ +/* isearch.c - incremental searching */ + +/* **************************************************************** */ +/* */ +/* I-Search and Searching */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif + +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Variables exported to other files in the readline library. */ +char *_rl_isearch_terminators = (char *)NULL; + +_rl_search_cxt *_rl_iscxt = 0; + +/* Variables imported from other files in the readline library. */ +extern HIST_ENTRY *_rl_saved_line_for_history; + +static int rl_search_history PARAMS((int, int)); + +static _rl_search_cxt *_rl_isearch_init PARAMS((int)); +static void _rl_isearch_fini PARAMS((_rl_search_cxt *)); + +/* Last line found by the current incremental search, so we don't `find' + identical lines many times in a row. Now part of isearch context. */ +/* static char *prev_line_found; */ + +/* Last search string and its length. */ +static char *last_isearch_string; +static int last_isearch_string_len; + +static char * const default_isearch_terminators = "\033\012"; + +_rl_search_cxt * +_rl_scxt_alloc (int type, int flags) +{ + _rl_search_cxt *cxt; + + cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt)); + + cxt->type = type; + cxt->sflags = flags; + + cxt->search_string = 0; + cxt->search_string_size = cxt->search_string_index = 0; + + cxt->lines = 0; + cxt->allocated_line = 0; + cxt->hlen = cxt->hindex = 0; + + cxt->save_point = rl_point; + cxt->save_mark = rl_mark; + cxt->save_line = where_history (); + cxt->last_found_line = cxt->save_line; + cxt->prev_line_found = 0; + + cxt->save_undo_list = 0; + + cxt->keymap = _rl_keymap; + cxt->okeymap = _rl_keymap; + + cxt->history_pos = 0; + cxt->direction = 0; + + cxt->prevc = cxt->lastc = 0; + + cxt->sline = 0; + cxt->sline_len = cxt->sline_index = 0; + + cxt->search_terminators = 0; + + return cxt; +} + +void +_rl_scxt_dispose (_rl_search_cxt *cxt, int flags) +{ + FREE (cxt->search_string); + FREE (cxt->allocated_line); + FREE (cxt->lines); + + xfree (cxt); +} + +/* Search backwards through the history looking for a string which is typed + interactively. Start with the current line. */ +int +rl_reverse_search_history (int sign, int key) +{ + return (rl_search_history (-sign, key)); +} + +/* Search forwards through the history looking for a string which is typed + interactively. Start with the current line. */ +int +rl_forward_search_history (int sign, int key) +{ + return (rl_search_history (sign, key)); +} + +/* Display the current state of the search in the echo-area. + SEARCH_STRING contains the string that is being searched for, + DIRECTION is zero for forward, or non-zero for reverse, + WHERE is the history list number of the current line. If it is + -1, then this line is the starting one. */ +static void +rl_display_search (char *search_string, int flags, int where) +{ + char *message; + int msglen, searchlen; + + searchlen = (search_string && *search_string) ? strlen (search_string) : 0; + + message = (char *)xmalloc (searchlen + 64); + msglen = 0; + +#if defined (NOTDEF) + if (where != -1) + { + sprintf (message, "[%d]", where + history_base); + msglen = strlen (message); + } +#endif /* NOTDEF */ + + message[msglen++] = '('; + + if (flags & SF_FAILED) + { + strcpy (message + msglen, "failed "); + msglen += 7; + } + + if (flags & SF_REVERSE) + { + strcpy (message + msglen, "reverse-"); + msglen += 8; + } + + strcpy (message + msglen, "i-search)`"); + msglen += 10; + + if (search_string && *search_string) + { + strcpy (message + msglen, search_string); + msglen += searchlen; + } + else + _rl_optimize_redisplay (); + + strcpy (message + msglen, "': "); + + rl_message ("%s", message); + xfree (message); + (*rl_redisplay_function) (); +} + +static _rl_search_cxt * +_rl_isearch_init (int direction) +{ + _rl_search_cxt *cxt; + register int i; + HIST_ENTRY **hlist; + + cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0); + if (direction < 0) + cxt->sflags |= SF_REVERSE; + + cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators + : default_isearch_terminators; + + /* Create an array of pointers to the lines that we want to search. */ + hlist = history_list (); + rl_maybe_replace_line (); + i = 0; + if (hlist) + for (i = 0; hlist[i]; i++); + + /* Allocate space for this many lines, +1 for the current input line, + and remember those lines. */ + cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *)); + for (i = 0; i < cxt->hlen; i++) + cxt->lines[i] = hlist[i]->line; + + if (_rl_saved_line_for_history) + cxt->lines[i] = _rl_saved_line_for_history->line; + else + { + /* Keep track of this so we can free it. */ + cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer)); + strcpy (cxt->allocated_line, &rl_line_buffer[0]); + cxt->lines[i] = cxt->allocated_line; + } + + cxt->hlen++; + + /* The line where we start the search. */ + cxt->history_pos = cxt->save_line; + + rl_save_prompt (); + + /* Initialize search parameters. */ + cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128); + cxt->search_string[cxt->search_string_index = 0] = '\0'; + + /* Normalize DIRECTION into 1 or -1. */ + cxt->direction = (direction >= 0) ? 1 : -1; + + cxt->sline = rl_line_buffer; + cxt->sline_len = strlen (cxt->sline); + cxt->sline_index = rl_point; + + _rl_iscxt = cxt; /* save globally */ + + /* experimental right now */ + _rl_init_executing_keyseq (); + + return cxt; +} + +static void +_rl_isearch_fini (_rl_search_cxt *cxt) +{ + /* First put back the original state. */ + rl_replace_line (cxt->lines[cxt->save_line], 0); + + rl_restore_prompt (); + + /* Save the search string for possible later use. */ + FREE (last_isearch_string); + last_isearch_string = cxt->search_string; + last_isearch_string_len = cxt->search_string_index; + cxt->search_string = 0; + + if (cxt->last_found_line < cxt->save_line) + rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0); + else + rl_get_next_history (cxt->last_found_line - cxt->save_line, 0); + + /* If the string was not found, put point at the end of the last matching + line. If last_found_line == orig_line, we didn't find any matching + history lines at all, so put point back in its original position. */ + if (cxt->sline_index < 0) + { + if (cxt->last_found_line == cxt->save_line) + cxt->sline_index = cxt->save_point; + else + cxt->sline_index = strlen (rl_line_buffer); + rl_mark = cxt->save_mark; + rl_deactivate_mark (); + } + + rl_point = cxt->sline_index; + /* Don't worry about where to put the mark here; rl_get_previous_history + and rl_get_next_history take care of it. + If we want to highlight the search string, this is where to set the + point and mark to do it. */ + _rl_fix_point (0); + rl_deactivate_mark (); + +/* _rl_optimize_redisplay (); */ + rl_clear_message (); +} + +/* XXX - we could use _rl_bracketed_read_mbstring () here. */ +int +_rl_search_getchar (_rl_search_cxt *cxt) +{ + int c; + + /* Read a key and decide how to proceed. */ + RL_SETSTATE(RL_STATE_MOREINPUT); + c = cxt->lastc = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + +#if defined (HANDLE_MULTIBYTE) + /* This ends up with C (and LASTC) being set to the last byte of the + multibyte character. In most cases c == lastc == mb[0] */ + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX); +#endif + + RL_CHECK_SIGNALS (); + return c; +} + +#define ENDSRCH_CHAR(c) \ + ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G'))) + +/* Process just-read character C according to isearch context CXT. Return + -1 if the caller should just free the context and return, 0 if we should + break out of the loop, and 1 if we should continue to read characters. */ +int +_rl_isearch_dispatch (_rl_search_cxt *cxt, int c) +{ + int n, wstart, wlen, limit, cval, incr; + char *paste; + size_t pastelen; + int j; + rl_command_func_t *f; + + f = (rl_command_func_t *)NULL; + + if (c < 0) + { + cxt->sflags |= SF_FAILED; + cxt->history_pos = cxt->last_found_line; + return -1; + } + + _rl_add_executing_keyseq (c); + + /* XXX - experimental code to allow users to bracketed-paste into the search + string even when ESC is one of the isearch-terminators. Not perfect yet. */ + if (_rl_enable_bracketed_paste && c == ESC && strchr (cxt->search_terminators, c) && (n = _rl_nchars_available ()) > (BRACK_PASTE_SLEN-1)) + { + j = _rl_read_bracketed_paste_prefix (c); + if (j == 1) + { + cxt->lastc = -7; /* bracketed paste, see below */ + goto opcode_dispatch; + } + else if (_rl_pushed_input_available ()) /* eat extra char we pushed back */ + c = cxt->lastc = rl_read_key (); + else + c = cxt->lastc; /* last ditch */ + } + + /* If we are moving into a new keymap, modify cxt->keymap and go on. + This can be a problem if c == ESC and we want to terminate the + incremental search, so we check */ + if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0) + { + /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued + takes microseconds, so multiply by 1000. If we don't get any + additional input and this keymap shadows another function, process + that key as if it was all we read. */ + if (_rl_keyseq_timeout > 0 && + RL_ISSTATE (RL_STATE_CALLBACK) == 0 && + RL_ISSTATE (RL_STATE_INPUTPENDING) == 0 && + _rl_pushed_input_available () == 0 && + ((Keymap)(cxt->keymap[c].function))[ANYOTHERKEY].function && + _rl_input_queued (_rl_keyseq_timeout*1000) == 0) + goto add_character; + + cxt->okeymap = cxt->keymap; + cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c); + cxt->sflags |= SF_CHGKMAP; + /* XXX - we should probably save this sequence, so we can do + something useful if this doesn't end up mapping to a command we + interpret here. Right now we just save the most recent character + that caused the index into a new keymap. */ + cxt->prevc = c; +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + if (cxt->mb[1] == 0) + { + cxt->pmb[0] = c; /* XXX should be == cxt->mb[0] */ + cxt->pmb[1] = '\0'; + } + else + memcpy (cxt->pmb, cxt->mb, sizeof (cxt->pmb)); + } +#endif + return 1; + } + +add_character: + + /* Translate the keys we do something with to opcodes. */ + if (c >= 0 && cxt->keymap[c].type == ISFUNC) + { + /* If we have a multibyte character, see if it's bound to something that + affects the search. */ +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && cxt->mb[1]) + f = rl_function_of_keyseq (cxt->mb, cxt->keymap, (int *)NULL); + else +#endif + { + f = cxt->keymap[c].function; + if (f == rl_do_lowercase_version) + f = cxt->keymap[_rl_to_lower (c)].function; + } + + if (f == rl_reverse_search_history) + cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2; + else if (f == rl_forward_search_history) + cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1; + else if (f == rl_rubout) + cxt->lastc = -3; + else if (c == CTRL ('G') || f == rl_abort) + cxt->lastc = -4; + else if (c == CTRL ('W') || f == rl_unix_word_rubout) /* XXX */ + cxt->lastc = -5; + else if (c == CTRL ('Y') || f == rl_yank) /* XXX */ + cxt->lastc = -6; + else if (f == rl_bracketed_paste_begin) + cxt->lastc = -7; + } + + /* If we changed the keymap earlier while translating a key sequence into + a command, restore it now that we've succeeded. */ + if (cxt->sflags & SF_CHGKMAP) + { + cxt->keymap = cxt->okeymap; + cxt->sflags &= ~SF_CHGKMAP; + /* If we indexed into a new keymap, but didn't map to a command that + affects the search (lastc > 0), and the character that mapped to a + new keymap would have ended the search (ENDSRCH_CHAR(cxt->prevc)), + handle that now as if the previous char would have ended the search + and we would have read the current character. */ + /* XXX - should we check cxt->mb? */ + if (cxt->lastc > 0 && ENDSRCH_CHAR (cxt->prevc)) + { + rl_stuff_char (cxt->lastc); + rl_execute_next (cxt->prevc); + /* XXX - do we insert everything in cxt->pmb? */ + return (0); + } + /* Otherwise, if the current character is mapped to self-insert or + nothing (i.e., not an editing command), and the previous character + was a keymap index, then we need to insert both the previous + character and the current character into the search string. */ + else if (cxt->lastc > 0 && cxt->prevc > 0 && + cxt->keymap[cxt->prevc].type == ISKMAP && + (f == 0 || f == rl_insert)) + { + /* Make lastc be the next character read */ + /* XXX - do we insert everything in cxt->mb? */ + rl_execute_next (cxt->lastc); + /* Dispatch on the previous character (insert into search string) */ + cxt->lastc = cxt->prevc; +#if defined (HANDLE_MULTIBYTE) + /* Have to overwrite cxt->mb here because dispatch uses it below */ + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + if (cxt->pmb[1] == 0) + { + cxt->mb[0] = cxt->lastc; /* == cxt->prevc */ + cxt->mb[1] = '\0'; + } + else + memcpy (cxt->mb, cxt->pmb, sizeof (cxt->mb)); + } +#endif + cxt->prevc = 0; + } + else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert) + { + _rl_term_executing_keyseq (); /* should this go in the caller? */ + + _rl_pending_command.map = cxt->keymap; + _rl_pending_command.count = 1; /* XXX */ + _rl_pending_command.key = cxt->lastc; + _rl_pending_command.func = f; + _rl_command_to_execute = &_rl_pending_command; + + return (0); + } + } + + /* The characters in isearch_terminators (set from the user-settable + variable isearch-terminators) are used to terminate the search but + not subsequently execute the character as a command. The default + value is "\033\012" (ESC and C-J). */ + if (cxt->lastc > 0 && strchr (cxt->search_terminators, cxt->lastc)) + { + /* ESC still terminates the search, but if there is pending + input or if input arrives within 0.1 seconds (on systems + with select(2)) it is used as a prefix character + with rl_execute_next. WATCH OUT FOR THIS! This is intended + to allow the arrow keys to be used like ^F and ^B are used + to terminate the search and execute the movement command. + XXX - since _rl_input_available depends on the application- + settable keyboard timeout value, this could alternatively + use _rl_input_queued(100000) */ + if (cxt->lastc == ESC && (_rl_pushed_input_available () || _rl_input_available ())) + rl_execute_next (ESC); + return (0); + } + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc)) + { + /* This sets rl_pending_input to LASTC; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (cxt->lastc); + return (0); + } + } + else +#endif + if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc)) + { + /* This sets rl_pending_input to LASTC; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (cxt->lastc); + return (0); + } + + _rl_init_executing_keyseq (); + +opcode_dispatch: + /* Now dispatch on the character. `Opcodes' affect the search string or + state. Other characters are added to the string. */ + switch (cxt->lastc) + { + /* search again */ + case -1: + if (cxt->search_string_index == 0) + { + if (last_isearch_string) + { + cxt->search_string_size = 64 + last_isearch_string_len; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + strcpy (cxt->search_string, last_isearch_string); + cxt->search_string_index = last_isearch_string_len; + rl_display_search (cxt->search_string, cxt->sflags, -1); + break; + } + /* XXX - restore keymap here? */ + return (1); + } + else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0) + cxt->sline_index--; + else if (cxt->sline_index != cxt->sline_len) + cxt->sline_index++; + else + rl_ding (); + break; + + /* switch directions */ + case -2: + cxt->direction = -cxt->direction; + if (cxt->direction < 0) + cxt->sflags |= SF_REVERSE; + else + cxt->sflags &= ~SF_REVERSE; + break; + + /* delete character from search string. */ + case -3: /* C-H, DEL */ + /* This is tricky. To do this right, we need to keep a + stack of search positions for the current search, with + sentinels marking the beginning and end. But this will + do until we have a real isearch-undo. */ + if (cxt->search_string_index == 0) + rl_ding (); + else if (MB_CUR_MAX == 1 || rl_byte_oriented) + cxt->search_string[--cxt->search_string_index] = '\0'; + else + { + wstart = _rl_find_prev_mbchar (cxt->search_string, cxt->search_string_index, MB_FIND_NONZERO); + if (wstart >= 0) + cxt->search_string[cxt->search_string_index = wstart] = '\0'; + else + cxt->search_string[cxt->search_string_index = 0] = '\0'; + } + + if (cxt->search_string_index == 0) + rl_ding (); + + break; + + case -4: /* C-G, abort */ + rl_replace_line (cxt->lines[cxt->save_line], 0); + rl_point = cxt->save_point; + rl_mark = cxt->save_mark; + rl_deactivate_mark (); + rl_restore_prompt(); + rl_clear_message (); + + _rl_fix_point (1); /* in case save_line and save_point are out of sync */ + return -1; + + case -5: /* C-W */ + /* skip over portion of line we already matched and yank word */ + wstart = rl_point + cxt->search_string_index; + if (wstart >= rl_end) + { + rl_ding (); + break; + } + + /* if not in a word, move to one. */ + cval = _rl_char_value (rl_line_buffer, wstart); + if (_rl_walphabetic (cval) == 0) + { + rl_ding (); + break; + } + n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);; + while (n < rl_end) + { + cval = _rl_char_value (rl_line_buffer, n); + if (_rl_walphabetic (cval) == 0) + break; + n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);; + } + wlen = n - wstart + 1; + if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size) + { + cxt->search_string_size += wlen + 1; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } + for (; wstart < n; wstart++) + cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart]; + cxt->search_string[cxt->search_string_index] = '\0'; + break; + + case -6: /* C-Y */ + /* skip over portion of line we already matched and yank rest */ + wstart = rl_point + cxt->search_string_index; + if (wstart >= rl_end) + { + rl_ding (); + break; + } + n = rl_end - wstart + 1; + if (cxt->search_string_index + n + 1 >= cxt->search_string_size) + { + cxt->search_string_size += n + 1; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } + for (n = wstart; n < rl_end; n++) + cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n]; + cxt->search_string[cxt->search_string_index] = '\0'; + break; + + case -7: /* bracketed paste */ + paste = _rl_bracketed_text (&pastelen); + if (paste == 0 || *paste == 0) + { + free (paste); + break; + } + if (_rl_enable_active_region) + rl_activate_mark (); + if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size) + { + cxt->search_string_size += pastelen + 2; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } + strcpy (cxt->search_string + cxt->search_string_index, paste); + cxt->search_string_index += pastelen; + free (paste); + break; + + /* Add character to search string and continue search. */ + default: +#if defined (HANDLE_MULTIBYTE) + wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb); +#else + wlen = 1; +#endif + if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size) + { + cxt->search_string_size += 128; /* 128 much greater than MB_CUR_MAX */ + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int j; + + if (cxt->mb[0] == 0 || cxt->mb[1] == 0) + cxt->search_string[cxt->search_string_index++] = cxt->mb[0]; + else + for (j = 0; j < wlen; ) + cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; + } + else +#endif + cxt->search_string[cxt->search_string_index++] = cxt->lastc; /* XXX - was c instead of lastc */ + cxt->search_string[cxt->search_string_index] = '\0'; + break; + } + + for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; ) + { + if (cxt->search_string_index == 0) + { + cxt->sflags |= SF_FAILED; + break; + } + + limit = cxt->sline_len - cxt->search_string_index + 1; + + /* Search the current line. */ + while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit)) + { + if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index)) + { + cxt->sflags |= SF_FOUND; + break; + } + else + cxt->sline_index += cxt->direction; + + if (cxt->sline_index < 0) + { + cxt->sline_index = 0; + break; + } + } + if (cxt->sflags & SF_FOUND) + break; + + /* Move to the next line, but skip new copies of the line + we just found and lines shorter than the string we're + searching for. */ + do + { + /* Move to the next line. */ + cxt->history_pos += cxt->direction; + + /* At limit for direction? */ + if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen)) + { + cxt->sflags |= SF_FAILED; + break; + } + + /* We will need these later. */ + cxt->sline = cxt->lines[cxt->history_pos]; + cxt->sline_len = strlen (cxt->sline); + } + while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) || + (cxt->search_string_index > cxt->sline_len)); + + if (cxt->sflags & SF_FAILED) + { + /* XXX - reset sline_index if < 0 */ + if (cxt->sline_index < 0) + cxt->sline_index = 0; + break; + } + + /* Now set up the line for searching... */ + cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0; + } + + /* reset the keymaps for the next time through the loop */ + cxt->keymap = cxt->okeymap = _rl_keymap; + + if (cxt->sflags & SF_FAILED) + { + /* We cannot find the search string. Ding the bell. */ + rl_ding (); + cxt->history_pos = cxt->last_found_line; + rl_deactivate_mark (); + rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); + return 1; + } + + /* We have found the search string. Just display it. But don't + actually move there in the history list until the user accepts + the location. */ + if (cxt->sflags & SF_FOUND) + { + cxt->prev_line_found = cxt->lines[cxt->history_pos]; + rl_replace_line (cxt->lines[cxt->history_pos], 0); + if (_rl_enable_active_region) + rl_activate_mark (); + rl_point = cxt->sline_index; + if (rl_mark_active_p () && cxt->search_string_index > 0) + rl_mark = rl_point + cxt->search_string_index; + cxt->last_found_line = cxt->history_pos; + rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos); + } + + return 1; +} + +int +_rl_isearch_cleanup (_rl_search_cxt *cxt, int r) +{ + if (r >= 0) + _rl_isearch_fini (cxt); + _rl_scxt_dispose (cxt, 0); + _rl_iscxt = 0; + + RL_UNSETSTATE(RL_STATE_ISEARCH); + + return (r != 0); +} + +/* Search through the history looking for an interactively typed string. + This is analogous to i-search. We start the search in the current line. + DIRECTION is which direction to search; >= 0 means forward, < 0 means + backwards. */ +static int +rl_search_history (int direction, int invoking_key) +{ + _rl_search_cxt *cxt; /* local for now, but saved globally */ + int c, r; + + RL_SETSTATE(RL_STATE_ISEARCH); + cxt = _rl_isearch_init (direction); + + rl_display_search (cxt->search_string, cxt->sflags, -1); + + /* If we are using the callback interface, all we do is set up here and + return. The key is that we leave RL_STATE_ISEARCH set. */ + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return (0); + + r = -1; + for (;;) + { + c = _rl_search_getchar (cxt); + /* We might want to handle EOF here (c == 0) */ + r = _rl_isearch_dispatch (cxt, cxt->lastc); + if (r <= 0) + break; + } + + /* The searching is over. The user may have found the string that she + was looking for, or else she may have exited a failing search. If + LINE_INDEX is -1, then that shows that the string searched for was + not found. We use this to determine where to place rl_point. */ + return (_rl_isearch_cleanup (cxt, r)); +} + +#if defined (READLINE_CALLBACKS) +/* Called from the callback functions when we are ready to read a key. The + callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH). + If _rl_isearch_dispatch finishes searching, this function is responsible + for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */ +int +_rl_isearch_callback (_rl_search_cxt *cxt) +{ + int c, r; + + c = _rl_search_getchar (cxt); + /* We might want to handle EOF here */ + r = _rl_isearch_dispatch (cxt, cxt->lastc); + + return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0; +} +#endif diff --git a/utshell-0.5.0/lib/readline/keymaps.c b/utshell-0.5.0/lib/readline/keymaps.c new file mode 100644 index 00000000..4ade30bc --- /dev/null +++ b/utshell-0.5.0/lib/readline/keymaps.c @@ -0,0 +1,174 @@ +/* keymaps.c -- Functions and keymaps for the GNU Readline library. */ + +/* Copyright (C) 1988,1989-2009,2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include /* for FILE * definition for readline.h */ + +#include "readline.h" +#include "rlconf.h" + +#include "emacs_keymap.c" + +#if defined (VI_MODE) +#include "vi_keymap.c" +#endif + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Functions for manipulating Keymaps. */ +/* */ +/* **************************************************************** */ + + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +Keymap +rl_make_bare_keymap (void) +{ + register int i; + Keymap keymap; + + keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY)); + for (i = 0; i < KEYMAP_SIZE; i++) + { + keymap[i].type = ISFUNC; + keymap[i].function = (rl_command_func_t *)NULL; + } + +#if 0 + for (i = 'A'; i < ('Z' + 1); i++) + { + keymap[i].type = ISFUNC; + keymap[i].function = rl_do_lowercase_version; + } +#endif + + return (keymap); +} + +/* A convenience function that returns 1 if there are no keys bound to + functions in KEYMAP */ +int +rl_empty_keymap (Keymap keymap) +{ + int i; + + for (i = 0; i < ANYOTHERKEY; i++) + { + if (keymap[i].type != ISFUNC || keymap[i].function) + return 0; + } + return 1; +} + +/* Return a new keymap which is a copy of MAP. Just copies pointers, does + not copy text of macros or descend into child keymaps. */ +Keymap +rl_copy_keymap (Keymap map) +{ + register int i; + Keymap temp; + + temp = rl_make_bare_keymap (); + for (i = 0; i < KEYMAP_SIZE; i++) + { + temp[i].type = map[i].type; + temp[i].function = map[i].function; + } + return (temp); +} + +/* Return a new keymap with the printing characters bound to rl_insert, + the uppercase Meta characters bound to run their lowercase equivalents, + and the Meta digits bound to produce numeric arguments. */ +Keymap +rl_make_keymap (void) +{ + register int i; + Keymap newmap; + + newmap = rl_make_bare_keymap (); + + /* All ASCII printing characters are self-inserting. */ + for (i = ' '; i < 127; i++) + newmap[i].function = rl_insert; + + newmap[TAB].function = rl_insert; + newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */ + newmap[CTRL('H')].function = rl_rubout; + +#if KEYMAP_SIZE > 128 + /* Printing characters in ISO Latin-1 and some 8-bit character sets. */ + for (i = 128; i < 256; i++) + newmap[i].function = rl_insert; +#endif /* KEYMAP_SIZE > 128 */ + + return (newmap); +} + +/* Free the storage associated with MAP. */ +void +rl_discard_keymap (Keymap map) +{ + int i; + + if (map == 0) + return; + + for (i = 0; i < KEYMAP_SIZE; i++) + { + switch (map[i].type) + { + case ISFUNC: + break; + + case ISKMAP: + rl_discard_keymap ((Keymap)map[i].function); + xfree ((char *)map[i].function); + break; + + case ISMACR: + xfree ((char *)map[i].function); + break; + } + } +} + +/* Convenience function that discards, then frees, MAP. */ +void +rl_free_keymap (Keymap map) +{ + rl_discard_keymap (map); + xfree ((char *)map); +} diff --git a/utshell-0.5.0/lib/readline/keymaps.h b/utshell-0.5.0/lib/readline/keymaps.h new file mode 100644 index 00000000..1fa853d8 --- /dev/null +++ b/utshell-0.5.0/lib/readline/keymaps.h @@ -0,0 +1,100 @@ +/* keymaps.h -- Manipulation of readline keymaps. */ + +/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#ifndef _KEYMAPS_H_ +#define _KEYMAPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "chardefs.h" +# include "rltypedefs.h" +#else +# include +# include +# include +#endif + +/* A keymap contains one entry for each key in the ASCII set. + Each entry consists of a type and a pointer. + FUNCTION is the address of a function to run, or the + address of a keymap to indirect through. + TYPE says which kind of thing FUNCTION is. */ +typedef struct _keymap_entry { + char type; + rl_command_func_t *function; +} KEYMAP_ENTRY; + +/* This must be large enough to hold bindings for all of the characters + in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x, + and so on) plus one for subsequence matching. */ +#define KEYMAP_SIZE 257 +#define ANYOTHERKEY KEYMAP_SIZE-1 + +typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; +typedef KEYMAP_ENTRY *Keymap; + +/* The values that TYPE can have in a keymap entry. */ +#define ISFUNC 0 +#define ISKMAP 1 +#define ISMACR 2 + +extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap; + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); + +/* Return a new keymap which is a copy of MAP. */ +extern Keymap rl_copy_keymap PARAMS((Keymap)); + +/* Return a new keymap with the printing characters bound to rl_insert, + the lowercase Meta characters bound to run their equivalents, and + the Meta digits bound to produce numeric arguments. */ +extern Keymap rl_make_keymap PARAMS((void)); + +/* Free the storage associated with a keymap. */ +extern void rl_discard_keymap PARAMS((Keymap)); + +/* These functions actually appear in bind.c */ + +/* Return the keymap corresponding to a given name. Names look like + `emacs' or `emacs-meta' or `vi-insert'. */ +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); + +/* Return the current keymap. */ +extern Keymap rl_get_keymap PARAMS((void)); + +/* Set the current keymap to MAP. */ +extern void rl_set_keymap PARAMS((Keymap)); + +/* Set the name of MAP to NAME */ +extern int rl_set_keymap_name PARAMS((const char *, Keymap)); + +#ifdef __cplusplus +} +#endif + +#endif /* _KEYMAPS_H_ */ diff --git a/utshell-0.5.0/lib/readline/kill.c b/utshell-0.5.0/lib/readline/kill.c new file mode 100644 index 00000000..50c3fdea --- /dev/null +++ b/utshell-0.5.0/lib/readline/kill.c @@ -0,0 +1,866 @@ +/* kill.c -- kill ring management. */ + +/* Copyright (C) 1994-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Killing Mechanism */ +/* */ +/* **************************************************************** */ + +/* What we assume for a max number of kills. */ +#define DEFAULT_MAX_KILLS 10 + +/* The real variable to look at to find out when to flush kills. */ +static int rl_max_kills = DEFAULT_MAX_KILLS; + +/* Where to store killed text. */ +static char **rl_kill_ring = (char **)NULL; + +/* Where we are in the kill ring. */ +static int rl_kill_index; + +/* How many slots we have in the kill ring. */ +static int rl_kill_ring_length; + +static int _rl_copy_to_kill_ring PARAMS((char *, int)); +static int region_kill_internal PARAMS((int)); +static int _rl_copy_word_as_kill PARAMS((int, int)); +static int rl_yank_nth_arg_internal PARAMS((int, int, int)); + +/* How to say that you only want to save a certain amount + of kill material. */ +int +rl_set_retained_kills (int num) +{ + return 0; +} + +/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary. + This uses TEXT directly, so the caller must not free it. If APPEND is + non-zero, and the last command was a kill, the text is appended to the + current kill ring slot, otherwise prepended. */ +static int +_rl_copy_to_kill_ring (char *text, int append) +{ + char *old, *new; + int slot; + + /* First, find the slot to work with. */ + if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0) + { + /* Get a new slot. */ + if (rl_kill_ring == 0) + { + /* If we don't have any defined, then make one. */ + rl_kill_ring = (char **) + xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); + rl_kill_ring[slot = 0] = (char *)NULL; + } + else + { + /* We have to add a new slot on the end, unless we have + exceeded the max limit for remembering kills. */ + slot = rl_kill_ring_length; + if (slot == rl_max_kills) + { + register int i; + xfree (rl_kill_ring[0]); + for (i = 0; i < slot; i++) + rl_kill_ring[i] = rl_kill_ring[i + 1]; + } + else + { + slot = rl_kill_ring_length += 1; + rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *)); + } + rl_kill_ring[--slot] = (char *)NULL; + } + } + else + slot = rl_kill_ring_length - 1; + + /* If the last command was a kill, prepend or append. */ + if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode) + { + old = rl_kill_ring[slot]; + new = (char *)xmalloc (1 + strlen (old) + strlen (text)); + + if (append) + { + strcpy (new, old); + strcat (new, text); + } + else + { + strcpy (new, text); + strcat (new, old); + } + xfree (old); + xfree (text); + rl_kill_ring[slot] = new; + } + else + rl_kill_ring[slot] = text; + + rl_kill_index = slot; + return 0; +} + +/* The way to kill something. This appends or prepends to the last + kill, if the last command was a kill command. if FROM is less + than TO, then the text is appended, otherwise prepended. If the + last command was not a kill command, then a new slot is made for + this kill. */ +int +rl_kill_text (int from, int to) +{ + char *text; + + /* Is there anything to kill? */ + if (from == to) + { + _rl_last_command_was_kill++; + return 0; + } + + text = rl_copy_text (from, to); + + /* Delete the copied text from the line. */ + rl_delete_text (from, to); + + _rl_copy_to_kill_ring (text, from < to); + + _rl_last_command_was_kill++; + return 0; +} + +/* Now REMEMBER! In order to do prepending or appending correctly, kill + commands always make rl_point's original position be the FROM argument, + and rl_point's extent be the TO argument. */ + +/* **************************************************************** */ +/* */ +/* Killing Commands */ +/* */ +/* **************************************************************** */ + +/* Delete the word at point, saving the text in the kill ring. */ +int +rl_kill_word (int count, int key) +{ + int orig_point; + + if (count < 0) + return (rl_backward_kill_word (-count, key)); + else + { + orig_point = rl_point; + rl_forward_word (count, key); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + rl_point = orig_point; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Rubout the word before point, placing it on the kill ring. */ +int +rl_backward_kill_word (int count, int key) +{ + int orig_point; + + if (count < 0) + return (rl_kill_word (-count, key)); + else + { + orig_point = rl_point; + rl_backward_word (count, key); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Kill from here to the end of the line. If DIRECTION is negative, kill + back to the line start instead. */ +int +rl_kill_line (int direction, int key) +{ + int orig_point; + + if (direction < 0) + return (rl_backward_kill_line (1, key)); + else + { + orig_point = rl_point; + rl_end_of_line (1, key); + if (orig_point != rl_point) + rl_kill_text (orig_point, rl_point); + rl_point = orig_point; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Kill backwards to the start of the line. If DIRECTION is negative, kill + forwards to the line end instead. */ +int +rl_backward_kill_line (int direction, int key) +{ + int orig_point; + + if (direction < 0) + return (rl_kill_line (1, key)); + else + { + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + rl_beg_of_line (1, key); + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + } + return 0; +} + +/* Kill the whole line, no matter where point is. */ +int +rl_kill_full_line (int count, int key) +{ + rl_begin_undo_group (); + rl_point = 0; + rl_kill_text (rl_point, rl_end); + rl_mark = 0; + rl_end_undo_group (); + return 0; +} + +/* The next two functions mimic unix line editing behaviour, except they + save the deleted text on the kill ring. This is safer than not saving + it, and since we have a ring, nobody should get screwed. */ + +/* This does what C-w does in Unix. We can't prevent people from + using behaviour that they expect. */ +int +rl_unix_word_rubout (int count, int key) +{ + int orig_point; + + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) + rl_point--; /* XXX - multibyte? */ + } + + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + + return 0; +} + +/* This deletes one filename component in a Unix pathname. That is, it + deletes backward to directory separator (`/') or whitespace. */ +int +rl_unix_filename_rubout (int count, int key) +{ + int orig_point, c; + + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + c = rl_line_buffer[rl_point - 1]; + while (rl_point && (whitespace (c) || c == '/')) + { + rl_point--; + c = rl_line_buffer[rl_point - 1]; + } + + while (rl_point && (whitespace (c) == 0) && c != '/') + { + rl_point--; /* XXX - multibyte? */ + c = rl_line_buffer[rl_point - 1]; + } + } + + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + + return 0; +} + +/* Here is C-u doing what Unix does. You don't *have* to use these + key-bindings. We have a choice of killing the entire line, or + killing from where we are to the start of the line. We choose the + latter, because if you are a Unix weenie, then you haven't backspaced + into the line at all, and if you aren't, then you know what you are + doing. */ +int +rl_unix_line_discard (int count, int key) +{ + if (rl_point == 0) + rl_ding (); + else + { + rl_kill_text (rl_point, 0); + rl_point = 0; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Copy the text in the `region' to the kill ring. If DELETE is non-zero, + delete the text from the line as well. */ +static int +region_kill_internal (int delete) +{ + char *text; + + if (rl_mark != rl_point) + { + text = rl_copy_text (rl_point, rl_mark); + if (delete) + rl_delete_text (rl_point, rl_mark); + _rl_copy_to_kill_ring (text, rl_point < rl_mark); + } + + _rl_fix_point (1); + _rl_last_command_was_kill++; + return 0; +} + +/* Copy the text in the region to the kill ring. */ +int +rl_copy_region_to_kill (int count, int key) +{ + return (region_kill_internal (0)); +} + +/* Kill the text between the point and mark. */ +int +rl_kill_region (int count, int key) +{ + int r, npoint; + + npoint = (rl_point < rl_mark) ? rl_point : rl_mark; + r = region_kill_internal (1); + rl_point = npoint; + _rl_fix_point (1); + return r; +} + +/* Copy COUNT words to the kill ring. DIR says which direction we look + to find the words. */ +static int +_rl_copy_word_as_kill (int count, int dir) +{ + int om, op, r; + + om = rl_mark; + op = rl_point; + + if (dir > 0) + rl_forward_word (count, 0); + else + rl_backward_word (count, 0); + + rl_mark = rl_point; + + if (dir > 0) + rl_backward_word (count, 0); + else + rl_forward_word (count, 0); + + r = region_kill_internal (0); + + rl_mark = om; + rl_point = op; + + return r; +} + +int +rl_copy_forward_word (int count, int key) +{ + if (count < 0) + return (rl_copy_backward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, 1)); +} + +int +rl_copy_backward_word (int count, int key) +{ + if (count < 0) + return (rl_copy_forward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, -1)); +} + +/* Yank back the last killed text. This ignores arguments. */ +int +rl_yank (int count, int key) +{ + if (rl_kill_ring == 0) + { + _rl_abort_internal (); + return 1; + } + + _rl_set_mark_at_pos (rl_point); + rl_insert_text (rl_kill_ring[rl_kill_index]); + return 0; +} + +/* If the last command was yank, or yank_pop, and the text just + before point is identical to the current kill item, then + delete that text from the line, rotate the index down, and + yank back some other text. */ +int +rl_yank_pop (int count, int key) +{ + int l, n; + + if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || + !rl_kill_ring) + { + _rl_abort_internal (); + return 1; + } + + l = strlen (rl_kill_ring[rl_kill_index]); + n = rl_point - l; + if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) + { + rl_delete_text (n, rl_point); + rl_point = n; + rl_kill_index--; + if (rl_kill_index < 0) + rl_kill_index = rl_kill_ring_length - 1; + rl_yank (1, 0); + return 0; + } + else + { + _rl_abort_internal (); + return 1; + } +} + +#if defined (VI_MODE) +int +rl_vi_yank_pop (int count, int key) +{ + int l, n; + + if (((rl_last_func != rl_vi_yank_pop) && (rl_last_func != rl_vi_put)) || + !rl_kill_ring) + { + _rl_abort_internal (); + return 1; + } + + l = strlen (rl_kill_ring[rl_kill_index]); + n = rl_point - l; + if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) + { + rl_delete_text (n, rl_point); + rl_point = n; + rl_kill_index--; + if (rl_kill_index < 0) + rl_kill_index = rl_kill_ring_length - 1; + rl_vi_put (1, 'p'); + return 0; + } + else + { + _rl_abort_internal (); + return 1; + } +} +#endif /* VI_MODE */ + +/* Yank the COUNTh argument from the previous history line, skipping + HISTORY_SKIP lines before looking for the `previous line'. */ +static int +rl_yank_nth_arg_internal (int count, int key, int history_skip) +{ + register HIST_ENTRY *entry; + char *arg; + int i, pos; + + pos = where_history (); + + if (history_skip) + { + for (i = 0; i < history_skip; i++) + entry = previous_history (); + } + + entry = previous_history (); + + history_set_pos (pos); + + if (entry == 0) + { + rl_ding (); + return 1; + } + + arg = history_arg_extract (count, count, entry->line); + if (!arg || !*arg) + { + rl_ding (); + FREE (arg); + return 1; + } + + rl_begin_undo_group (); + + _rl_set_mark_at_pos (rl_point); + +#if defined (VI_MODE) + /* Vi mode always inserts a space before yanking the argument, and it + inserts it right *after* rl_point. */ + if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) + { + rl_vi_append_mode (1, key); + rl_insert_text (" "); + } +#endif /* VI_MODE */ + + rl_insert_text (arg); + xfree (arg); + + rl_end_undo_group (); + return 0; +} + +/* Yank the COUNTth argument from the previous history line. */ +int +rl_yank_nth_arg (int count, int key) +{ + return (rl_yank_nth_arg_internal (count, key, 0)); +} + +/* Yank the last argument from the previous history line. This `knows' + how rl_yank_nth_arg treats a count of `$'. With an argument, this + behaves the same as rl_yank_nth_arg. */ +int +rl_yank_last_arg (int count, int key) +{ + static int history_skip = 0; + static int explicit_arg_p = 0; + static int count_passed = 1; + static int direction = 1; + static int undo_needed = 0; + int retval; + + if (rl_last_func != rl_yank_last_arg) + { + history_skip = 0; + explicit_arg_p = rl_explicit_arg; + count_passed = count; + direction = 1; + } + else + { + if (undo_needed) + rl_do_undo (); + if (count < 0) /* XXX - was < 1 */ + direction = -direction; + history_skip += direction; + if (history_skip < 0) + history_skip = 0; + } + + if (explicit_arg_p) + retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); + else + retval = rl_yank_nth_arg_internal ('$', key, history_skip); + + undo_needed = retval == 0; + return retval; +} + +/* Having read the special escape sequence denoting the beginning of a + `bracketed paste' sequence, read the rest of the pasted input until the + closing sequence and return the pasted text. */ +char * +_rl_bracketed_text (size_t *lenp) +{ + int c; + size_t len, cap; + char *buf; + + len = 0; + buf = xmalloc (cap = 64); + buf[0] = '\0'; + + RL_SETSTATE (RL_STATE_MOREINPUT); + while ((c = rl_read_key ()) >= 0) + { + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (c); + + if (c == '\r') /* XXX */ + c = '\n'; + + if (len == cap) + buf = xrealloc (buf, cap *= 2); + + buf[len++] = c; + if (len >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST && + STREQN (buf + len - BRACK_PASTE_SLEN, BRACK_PASTE_SUFF, BRACK_PASTE_SLEN)) + { + len -= BRACK_PASTE_SLEN; + break; + } + } + RL_UNSETSTATE (RL_STATE_MOREINPUT); + + if (c >= 0) + { + if (len == cap) + buf = xrealloc (buf, cap + 1); + buf[len] = '\0'; + } + + if (lenp) + *lenp = len; + return (buf); +} + +/* Having read the special escape sequence denoting the beginning of a + `bracketed paste' sequence, read the rest of the pasted input until the + closing sequence and insert the pasted text as a single unit without + interpretation. Temporarily highlight the inserted text. */ +int +rl_bracketed_paste_begin (int count, int key) +{ + int retval, c; + size_t len, cap; + char *buf; + + buf = _rl_bracketed_text (&len); + rl_mark = rl_point; + retval = rl_insert_text (buf) == len ? 0 : 1; + if (_rl_enable_active_region) + rl_activate_mark (); + + xfree (buf); + return (retval); +} + +int +_rl_read_bracketed_paste_prefix (int c) +{ + char pbuf[BRACK_PASTE_SLEN+1], *pbpref; + int key, ind, j; + + pbpref = BRACK_PASTE_PREF; /* XXX - debugging */ + if (c != pbpref[0]) + return (0); + pbuf[ind = 0] = c; + while (ind < BRACK_PASTE_SLEN-1 && + (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && + _rl_pushed_input_available () == 0 && + _rl_input_queued (0)) + { + key = rl_read_key (); /* XXX - for now */ + if (key < 0) + break; + pbuf[++ind] = key; + if (pbuf[ind] != pbpref[ind]) + break; + } + + if (ind < BRACK_PASTE_SLEN-1) /* read incomplete sequence */ + { + while (ind >= 0) + _rl_unget_char (pbuf[ind--]); + return (key < 0 ? key : 0); + } + return (key < 0 ? key : 1); +} + +/* Get a character from wherever we read input, handling input in bracketed + paste mode. If we don't have or use bracketed paste mode, this can be + used in place of rl_read_key(). */ +int +_rl_bracketed_read_key () +{ + int c, r; + char *pbuf; + size_t pblen; + + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (c < 0) + return -1; + + /* read pasted data with bracketed-paste mode enabled. */ + if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1) + { + pbuf = _rl_bracketed_text (&pblen); + if (pblen == 0) + { + xfree (pbuf); + return 0; /* XXX */ + } + c = (unsigned char)pbuf[0]; + if (pblen > 1) + { + while (--pblen > 0) + _rl_unget_char ((unsigned char)pbuf[pblen]); + } + xfree (pbuf); + } + + return c; +} + +/* Get a character from wherever we read input, handling input in bracketed + paste mode. If we don't have or use bracketed paste mode, this can be + used in place of rl_read_key(). */ +int +_rl_bracketed_read_mbstring (char *mb, int mlen) +{ + int c, r; + + c = _rl_bracketed_read_key (); + if (c < 0) + return -1; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + c = _rl_read_mbstring (c, mb, mlen); + else +#endif + mb[0] = c; + mb[mlen] = '\0'; /* just in case */ + + return c; +} + +/* A special paste command for Windows users. */ +#if defined (_WIN32) +#include + +int +rl_paste_from_clipboard (int count, int key) +{ + char *data, *ptr; + int len; + + if (OpenClipboard (NULL) == 0) + return (0); + + data = (char *)GetClipboardData (CF_TEXT); + if (data) + { + ptr = strchr (data, '\r'); + if (ptr) + { + len = ptr - data; + ptr = (char *)xmalloc (len + 1); + ptr[len] = '\0'; + strncpy (ptr, data, len); + } + else + ptr = data; + _rl_set_mark_at_pos (rl_point); + rl_insert_text (ptr); + if (ptr != data) + xfree (ptr); + CloseClipboard (); + } + return (0); +} +#endif /* _WIN32 */ diff --git a/utshell-0.5.0/lib/readline/macro.c b/utshell-0.5.0/lib/readline/macro.c new file mode 100644 index 00000000..92cc55c3 --- /dev/null +++ b/utshell-0.5.0/lib/readline/macro.c @@ -0,0 +1,332 @@ +/* macro.c -- keyboard macros for readline. */ + +/* Copyright (C) 1994-2009,2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#define MAX_MACRO_LEVEL 16 + +/* **************************************************************** */ +/* */ +/* Hacking Keyboard Macros */ +/* */ +/* **************************************************************** */ + +/* The currently executing macro string. If this is non-zero, + then it is a malloc ()'ed string where input is coming from. */ +char *rl_executing_macro = (char *)NULL; + +/* The offset in the above string to the next character to be read. */ +static int executing_macro_index; + +/* The current macro string being built. Characters get stuffed + in here by add_macro_char (). */ +static char *current_macro = (char *)NULL; + +/* The size of the buffer allocated to current_macro. */ +static int current_macro_size; + +/* The index at which characters are being added to current_macro. */ +static int current_macro_index; + +/* A structure used to save nested macro strings. + It is a linked list of string/index for each saved macro. */ +struct saved_macro { + struct saved_macro *next; + char *string; + int sindex; +}; + +/* The list of saved macros. */ +static struct saved_macro *macro_list = (struct saved_macro *)NULL; + +static int macro_level = 0; + +/* Set up to read subsequent input from STRING. + STRING is free ()'ed when we are done with it. */ +void +_rl_with_macro_input (char *string) +{ + if (macro_level > MAX_MACRO_LEVEL) + { + _rl_errmsg ("maximum macro execution nesting level exceeded"); + _rl_abort_internal (); + return; + } + +#if 0 + if (rl_executing_macro) /* XXX - later */ +#endif + _rl_push_executing_macro (); + rl_executing_macro = string; + executing_macro_index = 0; + RL_SETSTATE(RL_STATE_MACROINPUT); +} + +/* Return the next character available from a macro, or 0 if + there are no macro characters. */ +int +_rl_next_macro_key (void) +{ + int c; + + if (rl_executing_macro == 0) + return (0); + + if (rl_executing_macro[executing_macro_index] == 0) + { + _rl_pop_executing_macro (); + return (_rl_next_macro_key ()); + } + +#if defined (READLINE_CALLBACKS) + c = rl_executing_macro[executing_macro_index++]; + if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0) + _rl_pop_executing_macro (); + return c; +#else + /* XXX - consider doing the same as the callback code, just not testing + whether we're running in callback mode */ + return (rl_executing_macro[executing_macro_index++]); +#endif +} + +int +_rl_peek_macro_key (void) +{ + if (rl_executing_macro == 0) + return (0); + if (rl_executing_macro[executing_macro_index] == 0 && (macro_list == 0 || macro_list->string == 0)) + return (0); + if (rl_executing_macro[executing_macro_index] == 0 && macro_list && macro_list->string) + return (macro_list->string[0]); + return (rl_executing_macro[executing_macro_index]); +} + +int +_rl_prev_macro_key (void) +{ + if (rl_executing_macro == 0) + return (0); + + if (executing_macro_index == 0) + return (0); + + executing_macro_index--; + return (rl_executing_macro[executing_macro_index]); +} + +/* Save the currently executing macro on a stack of saved macros. */ +void +_rl_push_executing_macro (void) +{ + struct saved_macro *saver; + + saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); + saver->next = macro_list; + saver->sindex = executing_macro_index; + saver->string = rl_executing_macro; + + macro_list = saver; + + macro_level++; +} + +/* Discard the current macro, replacing it with the one + on the top of the stack of saved macros. */ +void +_rl_pop_executing_macro (void) +{ + struct saved_macro *macro; + + FREE (rl_executing_macro); + rl_executing_macro = (char *)NULL; + executing_macro_index = 0; + + if (macro_list) + { + macro = macro_list; + rl_executing_macro = macro_list->string; + executing_macro_index = macro_list->sindex; + macro_list = macro_list->next; + xfree (macro); + } + + macro_level--; + + if (rl_executing_macro == 0) + RL_UNSETSTATE(RL_STATE_MACROINPUT); +} + +/* Add a character to the macro being built. */ +void +_rl_add_macro_char (int c) +{ + if (current_macro_index + 1 >= current_macro_size) + { + if (current_macro == 0) + current_macro = (char *)xmalloc (current_macro_size = 25); + else + current_macro = (char *)xrealloc (current_macro, current_macro_size += 25); + } + + current_macro[current_macro_index++] = c; + current_macro[current_macro_index] = '\0'; +} + +void +_rl_kill_kbd_macro (void) +{ + if (current_macro) + { + xfree (current_macro); + current_macro = (char *) NULL; + } + current_macro_size = current_macro_index = 0; + + FREE (rl_executing_macro); + rl_executing_macro = (char *) NULL; + executing_macro_index = 0; + + RL_UNSETSTATE(RL_STATE_MACRODEF); +} + +/* Begin defining a keyboard macro. + Keystrokes are recorded as they are executed. + End the definition with rl_end_kbd_macro (). + If a numeric argument was explicitly typed, then append this + definition to the end of the existing macro, and start by + re-executing the existing macro. */ +int +rl_start_kbd_macro (int ignore1, int ignore2) +{ + if (RL_ISSTATE (RL_STATE_MACRODEF)) + { + _rl_abort_internal (); + return 1; + } + + if (rl_explicit_arg) + { + if (current_macro) + _rl_with_macro_input (savestring (current_macro)); + } + else + current_macro_index = 0; + + RL_SETSTATE(RL_STATE_MACRODEF); + return 0; +} + +/* Stop defining a keyboard macro. + A numeric argument says to execute the macro right now, + that many times, counting the definition as the first time. */ +int +rl_end_kbd_macro (int count, int ignore) +{ + if (RL_ISSTATE (RL_STATE_MACRODEF) == 0) + { + _rl_abort_internal (); + return 1; + } + + current_macro_index -= rl_key_sequence_length; + current_macro[current_macro_index] = '\0'; + + RL_UNSETSTATE(RL_STATE_MACRODEF); + + return (rl_call_last_kbd_macro (--count, 0)); +} + +/* Execute the most recently defined keyboard macro. + COUNT says how many times to execute it. */ +int +rl_call_last_kbd_macro (int count, int ignore) +{ + if (current_macro == 0) + _rl_abort_internal (); + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + { + rl_ding (); /* no recursive macros */ + current_macro[--current_macro_index] = '\0'; /* erase this char */ + return 0; + } + + while (count--) + _rl_with_macro_input (savestring (current_macro)); + return 0; +} + +int +rl_print_last_kbd_macro (int count, int ignore) +{ + char *m; + + if (current_macro == 0) + { + rl_ding (); + return 0; + } + m = _rl_untranslate_macro_value (current_macro, 1); + rl_crlf (); + printf ("%s", m); + fflush (stdout); + rl_crlf (); + FREE (m); + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +void +rl_push_macro_input (char *macro) +{ + _rl_with_macro_input (macro); +} diff --git a/utshell-0.5.0/lib/readline/mbutil.c b/utshell-0.5.0/lib/readline/mbutil.c new file mode 100644 index 00000000..dc62b4cc --- /dev/null +++ b/utshell-0.5.0/lib/readline/mbutil.c @@ -0,0 +1,524 @@ +/* mbutil.c -- readline multibyte character utility functions */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixjmp.h" + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Declared here so it can be shared between the readline and history + libraries. */ +#if defined (HANDLE_MULTIBYTE) +int rl_byte_oriented = 0; +#else +int rl_byte_oriented = 1; +#endif + +/* Ditto */ +int _rl_utf8locale = 0; + +/* **************************************************************** */ +/* */ +/* Multibyte Character Utility Functions */ +/* */ +/* **************************************************************** */ + +#if defined(HANDLE_MULTIBYTE) + +/* **************************************************************** */ +/* */ +/* UTF-8 specific Character Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Return the length in bytes of the possibly-multibyte character beginning + at S. Encoding is UTF-8. */ +static int +_rl_utf8_mblen (const char *s, size_t n) +{ + unsigned char c, c1, c2, c3; + + if (s == 0) + return (0); /* no shift states */ + if (n <= 0) + return (-1); + + c = (unsigned char)*s; + if (c < 0x80) + return (c != 0); + if (c >= 0xc2) + { + c1 = (unsigned char)s[1]; + if (c < 0xe0) + { + if (n == 1) + return -2; + if (n >= 2 && (c1 ^ 0x80) < 0x40) + return 2; + } + else if (c < 0xf0) + { + if (n == 1) + return -2; + if ((c1 ^ 0x80) < 0x40 + && (c >= 0xe1 || c1 >= 0xa0) + && (c != 0xed || c1 < 0xa0)) + { + if (n == 2) + return -2; + c2 = (unsigned char)s[2]; + if ((c2 ^ 0x80) < 0x40) + return 3; + } + } + else if (c < 0xf4) + { + if (n == 1) + return -2; + if (((c1 ^ 0x80) < 0x40) + && (c >= 0xf1 || c1 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c1 < 0x90))) + { + if (n == 2) + return -2; + c2 = (unsigned char)s[2]; + if ((c2 ^ 0x80) < 0x40) + { + if (n == 3) + return -2; + c3 = (unsigned char)s[3]; + if ((c3 ^ 0x80) < 0x40) + return 4; + } + } + } + } + /* invalid or incomplete multibyte character */ + return -1; +} + +static int +_rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_zero) +{ + size_t tmp, len; + mbstate_t ps; + int point; + wchar_t wc; + + tmp = 0; + + memset(&ps, 0, sizeof (mbstate_t)); + if (seed < 0) + seed = 0; + if (count <= 0) + return seed; + + point = seed + _rl_adjust_point (string, seed, &ps); + /* if _rl_adjust_point returns -1, the character or string is invalid. + treat as a byte. */ + if (point == seed - 1) /* invalid */ + return seed + 1; + + /* if this is true, means that seed was not pointing to a byte indicating + the beginning of a multibyte character. Correct the point and consume + one char. */ + if (seed < point) + count--; + + while (count > 0) + { + len = strlen (string + point); + if (len == 0) + break; + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string+point, len, &ps); + if (MB_INVALIDCH ((size_t)tmp)) + { + /* invalid bytes. assume a byte represents a character */ + point++; + count--; + /* reset states. */ + memset(&ps, 0, sizeof(mbstate_t)); + } + else if (MB_NULLWCH (tmp)) + break; /* found wide '\0' */ + else + { + /* valid bytes */ + point += tmp; + if (find_non_zero) + { + if (WCWIDTH (wc) == 0) + continue; + else + count--; + } + else + count--; + } + } + + if (find_non_zero) + { + tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); + while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && WCWIDTH (wc) == 0) + { + point += tmp; + tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); + } + } + + return point; +} + +static inline int +_rl_test_nonzero (char *string, int ind, int len) +{ + size_t tmp; + wchar_t wc; + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); + tmp = mbrtowc (&wc, string + ind, len - ind, &ps); + /* treat invalid multibyte sequences as non-zero-width */ + return (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp) || WCWIDTH (wc) > 0); +} + +/* experimental -- needs to handle zero-width characters better */ +static int +_rl_find_prev_utf8char (char *string, int seed, int find_non_zero) +{ + char *s; + unsigned char b; + int save, prev; + size_t len; + + if (find_non_zero) + len = RL_STRLEN (string); + + prev = seed - 1; + while (prev >= 0) + { + b = (unsigned char)string[prev]; + if (UTF8_SINGLEBYTE (b)) + return (prev); + + save = prev; + + /* Move back until we're not in the middle of a multibyte char */ + if (UTF8_MBCHAR (b)) + { + while (prev > 0 && (b = (unsigned char)string[--prev]) && UTF8_MBCHAR (b)) + ; + } + + if (UTF8_MBFIRSTCHAR (b)) + { + if (find_non_zero) + { + if (_rl_test_nonzero (string, prev, len)) + return (prev); + else /* valid but WCWIDTH (wc) == 0 */ + prev = prev - 1; + } + else + return (prev); + } + else + return (save); /* invalid utf-8 multibyte sequence */ + } + + return ((prev < 0) ? 0 : prev); +} + +/*static*/ int +_rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero) +{ + mbstate_t ps; + int prev, non_zero_prev, point, length; + size_t tmp; + wchar_t wc; + + if (_rl_utf8locale) + return (_rl_find_prev_utf8char (string, seed, find_non_zero)); + + memset(&ps, 0, sizeof(mbstate_t)); + length = strlen(string); + + if (seed < 0) + return 0; + else if (length < seed) + return length; + + prev = non_zero_prev = point = 0; + while (point < seed) + { + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string + point, length - point, &ps); + if (MB_INVALIDCH ((size_t)tmp)) + { + /* in this case, bytes are invalid or too short to compose + multibyte char, so assume that the first byte represents + a single character anyway. */ + tmp = 1; + /* clear the state of the byte sequence, because + in this case effect of mbstate is undefined */ + memset(&ps, 0, sizeof (mbstate_t)); + + /* Since we're assuming that this byte represents a single + non-zero-width character, don't forget about it. */ + prev = point; + } + else if (MB_NULLWCH (tmp)) + break; /* Found '\0' char. Can this happen? */ + else + { + if (find_non_zero) + { + if (WCWIDTH (wc) != 0) + prev = point; + } + else + prev = point; + } + + point += tmp; + } + + return prev; +} + +/* return the number of bytes parsed from the multibyte sequence starting + at src, if a non-L'\0' wide character was recognized. It returns 0, + if a L'\0' wide character was recognized. It returns (size_t)(-1), + if an invalid multibyte sequence was encountered. It returns (size_t)(-2) + if it couldn't parse a complete multibyte character. */ +int +_rl_get_char_len (char *src, mbstate_t *ps) +{ + size_t tmp, l; + int mb_cur_max; + + /* Look at no more than MB_CUR_MAX characters */ + l = (size_t)strlen (src); + if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src)) + tmp = (*src != 0) ? 1 : 0; + else + { + mb_cur_max = MB_CUR_MAX; + tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps); + } + if (tmp == (size_t)(-2)) + { + /* too short to compose multibyte char */ + if (ps) + memset (ps, 0, sizeof(mbstate_t)); + return -2; + } + else if (tmp == (size_t)(-1)) + { + /* invalid to compose multibyte char */ + /* initialize the conversion state */ + if (ps) + memset (ps, 0, sizeof(mbstate_t)); + return -1; + } + else if (tmp == (size_t)0) + return 0; + else + return (int)tmp; +} + +/* compare the specified two characters. If the characters matched, + return 1. Otherwise return 0. */ +int +_rl_compare_chars (char *buf1, int pos1, mbstate_t *ps1, char *buf2, int pos2, mbstate_t *ps2) +{ + int i, w1, w2; + + if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 || + (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 || + (w1 != w2) || + (buf1[pos1] != buf2[pos2])) + return 0; + + for (i = 1; i < w1; i++) + if (buf1[pos1+i] != buf2[pos2+i]) + return 0; + + return 1; +} + +/* adjust pointed byte and find mbstate of the point of string. + adjusted point will be point <= adjusted_point, and returns + differences of the byte(adjusted_point - point). + if point is invalid (point < 0 || more than string length), + it returns -1 */ +int +_rl_adjust_point (char *string, int point, mbstate_t *ps) +{ + size_t tmp; + int length, pos; + + tmp = 0; + pos = 0; + length = strlen(string); + if (point < 0) + return -1; + if (length < point) + return -1; + + while (pos < point) + { + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[pos])) + tmp = 1; + else + tmp = mbrlen (string + pos, length - pos, ps); + if (MB_INVALIDCH ((size_t)tmp)) + { + /* in this case, bytes are invalid or too short to compose + multibyte char, so assume that the first byte represents + a single character anyway. */ + pos++; + /* clear the state of the byte sequence, because + in this case effect of mbstate is undefined */ + if (ps) + memset (ps, 0, sizeof (mbstate_t)); + } + else if (MB_NULLWCH (tmp)) + pos++; + else + pos += tmp; + } + + return (pos - point); +} + +int +_rl_is_mbchar_matched (char *string, int seed, int end, char *mbchar, int length) +{ + int i; + + if ((end - seed) < length) + return 0; + + for (i = 0; i < length; i++) + if (string[seed + i] != mbchar[i]) + return 0; + return 1; +} + +wchar_t +_rl_char_value (char *buf, int ind) +{ + size_t tmp; + wchar_t wc; + mbstate_t ps; + int l; + + if (MB_LEN_MAX == 1 || rl_byte_oriented) + return ((wchar_t) buf[ind]); + if (_rl_utf8locale && UTF8_SINGLEBYTE(buf[ind])) + return ((wchar_t) buf[ind]); + l = strlen (buf); + if (ind >= l - 1) + return ((wchar_t) buf[ind]); + if (l < ind) /* Sanity check */ + l = strlen (buf+ind); + memset (&ps, 0, sizeof (mbstate_t)); + tmp = mbrtowc (&wc, buf + ind, l - ind, &ps); + if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) + return ((wchar_t) buf[ind]); + return wc; +} +#endif /* HANDLE_MULTIBYTE */ + +/* Find next `count' characters started byte point of the specified seed. + If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte + characters. */ +#undef _rl_find_next_mbchar +int +_rl_find_next_mbchar (char *string, int seed, int count, int flags) +{ +#if defined (HANDLE_MULTIBYTE) + return _rl_find_next_mbchar_internal (string, seed, count, flags); +#else + return (seed + count); +#endif +} + +/* Find previous character started byte point of the specified seed. + Returned point will be point <= seed. If flags is MB_FIND_NONZERO, + we look for non-zero-width multibyte characters. */ +#undef _rl_find_prev_mbchar +int +_rl_find_prev_mbchar (char *string, int seed, int flags) +{ +#if defined (HANDLE_MULTIBYTE) + return _rl_find_prev_mbchar_internal (string, seed, flags); +#else + return ((seed == 0) ? seed : seed - 1); +#endif +} diff --git a/utshell-0.5.0/lib/readline/misc.c b/utshell-0.5.0/lib/readline/misc.c new file mode 100644 index 00000000..3d9a674c --- /dev/null +++ b/utshell-0.5.0/lib/readline/misc.c @@ -0,0 +1,737 @@ +/* misc.c -- miscellaneous bindable readline functions. */ + +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +static int rl_digit_loop PARAMS((void)); +static void _rl_history_set_point PARAMS((void)); + +/* Forward declarations used in this file */ +void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +/* If non-zero, rl_get_previous_history and rl_get_next_history attempt + to preserve the value of rl_point from line to line. */ +int _rl_history_preserve_point = 0; + +_rl_arg_cxt _rl_argcxt; + +/* Saved target point for when _rl_history_preserve_point is set. Special + value of -1 means that point is at the end of the line. */ +int _rl_history_saved_point = -1; + +/* **************************************************************** */ +/* */ +/* Numeric Arguments */ +/* */ +/* **************************************************************** */ + +int +_rl_arg_overflow (void) +{ + if (rl_numeric_arg > 1000000) + { + _rl_argcxt = 0; + rl_explicit_arg = rl_numeric_arg = 0; + rl_ding (); + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return 1; + } + return 0; +} + +void +_rl_arg_init (void) +{ + rl_save_prompt (); + _rl_argcxt = 0; + RL_SETSTATE(RL_STATE_NUMERICARG); +} + +int +_rl_arg_getchar (void) +{ + int c; + + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + return c; +} + +/* Process C as part of the current numeric argument. Return -1 if the + argument should be aborted, 0 if we should not read any more chars, and + 1 if we should continue to read chars. */ +int +_rl_arg_dispatch (_rl_arg_cxt cxt, int c) +{ + int key, r; + + key = c; + + /* If we see a key bound to `universal-argument' after seeing digits, + it ends the argument but is otherwise ignored. */ + if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) + { + if ((cxt & NUM_SAWDIGITS) == 0) + { + rl_numeric_arg *= 4; + return 1; + } + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_argcxt |= NUM_READONE; + return 0; /* XXX */ + } + else + { + key = _rl_bracketed_read_key (); + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + if (key < 0) + return -1; + return (_rl_dispatch (key, _rl_keymap)); + } + } + + c = UNMETA (c); + + if (_rl_digit_p (c)) + { + r = _rl_digit_value (c); + rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r; + rl_explicit_arg = 1; + _rl_argcxt |= NUM_SAWDIGITS; + } + else if (c == '-' && rl_explicit_arg == 0) + { + rl_numeric_arg = 1; + _rl_argcxt |= NUM_SAWMINUS; + rl_arg_sign = -1; + } + else + { + /* Make M-- command equivalent to M--1 command. */ + if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0) + rl_explicit_arg = 1; + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + + r = _rl_dispatch (key, _rl_keymap); + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + /* At worst, this will cause an extra redisplay. Otherwise, + we have to wait until the next character comes in. */ + if (rl_done == 0) + (*rl_redisplay_function) (); + r = 0; + } + return r; + } + + return 1; +} + +/* Handle C-u style numeric args, as well as M--, and M-digits. */ +static int +rl_digit_loop (void) +{ + int c, r; + + while (1) + { + if (_rl_arg_overflow ()) + return 1; + + c = _rl_arg_getchar (); + + if (c < 0) + { + _rl_abort_internal (); + return -1; + } + + r = _rl_arg_dispatch (_rl_argcxt, c); + if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)) + break; + } + + return r; +} + +/* Create a default argument. */ +void +_rl_reset_argument (void) +{ + rl_numeric_arg = rl_arg_sign = 1; + rl_explicit_arg = 0; + _rl_argcxt = 0; +} + +/* Start a numeric argument with initial value KEY */ +int +rl_digit_argument (int ignore, int key) +{ + _rl_arg_init (); + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_arg_dispatch (_rl_argcxt, key); + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); + return 0; + } + else + { + rl_execute_next (key); + return (rl_digit_loop ()); + } +} + +/* C-u, universal argument. Multiply the current argument by 4. + Read a key. If the key has nothing to do with arguments, then + dispatch on it. If the key is the abort character then abort. */ +int +rl_universal_argument (int count, int key) +{ + _rl_arg_init (); + rl_numeric_arg *= 4; + + return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ()); +} + +int +_rl_arg_callback (_rl_arg_cxt cxt) +{ + int c, r; + + c = _rl_arg_getchar (); + if (c < 0) + return (1); /* EOF */ + + if (_rl_argcxt & NUM_READONE) + { + _rl_argcxt &= ~NUM_READONE; + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + rl_execute_next (c); + return 0; + } + + r = _rl_arg_dispatch (cxt, c); + if (r > 0) + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); + return (r != 1); +} + +/* What to do when you abort reading an argument. */ +int +rl_discard_argument (void) +{ + rl_ding (); + rl_clear_message (); + _rl_reset_argument (); + + return 0; +} + +/* **************************************************************** */ +/* */ +/* History Utilities */ +/* */ +/* **************************************************************** */ + +/* We already have a history library, and that is what we use to control + the history features of readline. This is our local interface to + the history mechanism. */ + +/* While we are editing the history, this is the saved + version of the original line. */ +HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL; + +/* Set the history pointer back to the last entry in the history. */ +void +_rl_start_using_history (void) +{ + using_history (); + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); + + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; +} + +/* Free the contents (and containing structure) of a HIST_ENTRY. */ +void +_rl_free_history_entry (HIST_ENTRY *entry) +{ + if (entry == 0) + return; + + FREE (entry->line); + FREE (entry->timestamp); + + xfree (entry); +} + +/* Perhaps put back the current line if it has changed. */ +int +rl_maybe_replace_line (void) +{ + HIST_ENTRY *temp; + + temp = current_history (); + /* If the current line has changed, save the changes. */ + if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) + { + temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); + xfree (temp->line); + FREE (temp->timestamp); + xfree (temp); + } + return 0; +} + +/* Restore the _rl_saved_line_for_history if there is one. */ +int +rl_maybe_unsave_line (void) +{ + if (_rl_saved_line_for_history) + { + /* Can't call with `1' because rl_undo_list might point to an undo + list from a history entry, as in rl_replace_from_history() below. */ + rl_replace_line (_rl_saved_line_for_history->line, 0); + rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data; + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + rl_point = rl_end; /* rl_replace_line sets rl_end */ + } + else + rl_ding (); + return 0; +} + +/* Save the current line in _rl_saved_line_for_history. */ +int +rl_maybe_save_line (void) +{ + if (_rl_saved_line_for_history == 0) + { + _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + _rl_saved_line_for_history->line = savestring (rl_line_buffer); + _rl_saved_line_for_history->timestamp = (char *)NULL; + _rl_saved_line_for_history->data = (char *)rl_undo_list; + } + + return 0; +} + +int +_rl_free_saved_history_line (void) +{ + if (_rl_saved_line_for_history) + { + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + } + return 0; +} + +static void +_rl_history_set_point (void) +{ + rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) + ? _rl_history_saved_point + : rl_end; + if (rl_point > rl_end) + rl_point = rl_end; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap) + rl_point = 0; +#endif /* VI_MODE */ + + if (rl_editing_mode == emacs_mode) + rl_mark = (rl_point == rl_end ? 0 : rl_end); +} + +void +rl_replace_from_history (HIST_ENTRY *entry, int flags) +{ + /* Can't call with `1' because rl_undo_list might point to an undo list + from a history entry, just like we're setting up here. */ + rl_replace_line (entry->line, 0); + rl_undo_list = (UNDO_LIST *)entry->data; + rl_point = rl_end; + rl_mark = 0; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + { + rl_point = 0; + rl_mark = rl_end; + } +#endif +} + +/* Process and free undo lists attached to each history entry prior to the + current entry, inclusive, reverting each line to its saved state. This + is destructive, and state about the current line is lost. This is not + intended to be called while actively editing, and the current line is + not assumed to have been added to the history list. */ +void +_rl_revert_previous_lines (void) +{ + int hpos; + HIST_ENTRY *entry; + UNDO_LIST *ul, *saved_undo_list; + char *lbuf; + + lbuf = savestring (rl_line_buffer); + saved_undo_list = rl_undo_list; + hpos = where_history (); + + entry = (hpos == history_length) ? previous_history () : current_history (); + while (entry) + { + if (ul = (UNDO_LIST *)entry->data) + { + if (ul == saved_undo_list) + saved_undo_list = 0; + /* Set up rl_line_buffer and other variables from history entry */ + rl_replace_from_history (entry, 0); /* entry->line is now current */ + entry->data = 0; /* entry->data is now current undo list */ + /* Undo all changes to this history entry */ + while (rl_undo_list) + rl_do_undo (); + /* And copy the reverted line back to the history entry, preserving + the timestamp. */ + FREE (entry->line); + entry->line = savestring (rl_line_buffer); + } + entry = previous_history (); + } + + /* Restore history state */ + rl_undo_list = saved_undo_list; /* may have been set to null */ + history_set_pos (hpos); + + /* reset the line buffer */ + rl_replace_line (lbuf, 0); + _rl_set_the_line (); + + /* and clean up */ + xfree (lbuf); +} + +/* Revert all lines in the history by making sure we are at the end of the + history before calling _rl_revert_previous_lines() */ +void +_rl_revert_all_lines (void) +{ + int pos; + + pos = where_history (); + using_history (); + _rl_revert_previous_lines (); + history_set_pos (pos); +} + +/* Free the history list, including private readline data and take care + of pointer aliases to history data. Resets rl_undo_list if it points + to an UNDO_LIST * saved as some history entry's data member. This + should not be called while editing is active. */ +void +rl_clear_history (void) +{ + HIST_ENTRY **hlist, *hent; + register int i; + UNDO_LIST *ul, *saved_undo_list; + + saved_undo_list = rl_undo_list; + hlist = history_list (); /* direct pointer, not copy */ + + for (i = 0; i < history_length; i++) + { + hent = hlist[i]; + if (ul = (UNDO_LIST *)hent->data) + { + if (ul == saved_undo_list) + saved_undo_list = 0; + _rl_free_undo_list (ul); + hent->data = 0; + } + _rl_free_history_entry (hent); + } + + history_offset = history_length = 0; + rl_undo_list = saved_undo_list; /* should be NULL */ +} + +/* **************************************************************** */ +/* */ +/* History Commands */ +/* */ +/* **************************************************************** */ + +/* Meta-< goes to the start of the history. */ +int +rl_beginning_of_history (int count, int key) +{ + return (rl_get_previous_history (1 + where_history (), key)); +} + +/* Meta-> goes to the end of the history. (The current line). */ +int +rl_end_of_history (int count, int key) +{ + rl_maybe_replace_line (); + using_history (); + rl_maybe_unsave_line (); + return 0; +} + +/* Move down to the next history line. */ +int +rl_get_next_history (int count, int key) +{ + HIST_ENTRY *temp; + + if (count < 0) + return (rl_get_previous_history (-count, key)); + + if (count == 0) + return 0; + + rl_maybe_replace_line (); + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + temp = (HIST_ENTRY *)NULL; + while (count) + { + temp = next_history (); + if (!temp) + break; + --count; + } + + if (temp == 0) + rl_maybe_unsave_line (); + else + { + rl_replace_from_history (temp, 0); + _rl_history_set_point (); + } + return 0; +} + +/* Get the previous item out of our interactive history, making it the current + line. If there is no previous history, just ding. */ +int +rl_get_previous_history (int count, int key) +{ + HIST_ENTRY *old_temp, *temp; + int had_saved_line; + + if (count < 0) + return (rl_get_next_history (-count, key)); + + if (count == 0 || history_list () == 0) + return 0; + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + /* If we don't have a line saved, then save this one. */ + had_saved_line = _rl_saved_line_for_history != 0; + rl_maybe_save_line (); + + /* If the current line has changed, save the changes. */ + rl_maybe_replace_line (); + + temp = old_temp = (HIST_ENTRY *)NULL; + while (count) + { + temp = previous_history (); + if (temp == 0) + break; + + old_temp = temp; + --count; + } + + /* If there was a large argument, and we moved back to the start of the + history, that is not an error. So use the last value found. */ + if (!temp && old_temp) + temp = old_temp; + + if (temp == 0) + { + if (had_saved_line == 0) + _rl_free_saved_history_line (); + rl_ding (); + } + else + { + rl_replace_from_history (temp, 0); + _rl_history_set_point (); + } + + return 0; +} + +/* The equivalent of the Korn shell C-o operate-and-get-next-history-line + editing command. */ + +/* This could stand to be global to the readline library */ +static rl_hook_func_t *_rl_saved_internal_startup_hook = 0; +static int saved_history_logical_offset = -1; + +#define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries) + +static int +set_saved_history () +{ + int absolute_offset, count; + + if (saved_history_logical_offset >= 0) + { + absolute_offset = saved_history_logical_offset - history_base; + count = where_history () - absolute_offset; + rl_get_previous_history (count, 0); + } + saved_history_logical_offset = -1; + _rl_internal_startup_hook = _rl_saved_internal_startup_hook; + + return (0); +} + +int +rl_operate_and_get_next (count, c) + int count, c; +{ + /* Accept the current line. */ + rl_newline (1, c); + + saved_history_logical_offset = rl_explicit_arg ? count : where_history () + history_base + 1; + + + _rl_saved_internal_startup_hook = _rl_internal_startup_hook; + _rl_internal_startup_hook = set_saved_history; + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Editing Modes */ +/* */ +/* **************************************************************** */ +/* How to toggle back and forth between editing modes. */ +int +rl_vi_editing_mode (int count, int key) +{ +#if defined (VI_MODE) + _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ + rl_editing_mode = vi_mode; + rl_vi_insert_mode (1, key); +#endif /* VI_MODE */ + + return 0; +} + +int +rl_emacs_editing_mode (int count, int key) +{ + rl_editing_mode = emacs_mode; + _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ + _rl_keymap = emacs_standard_keymap; + + if (_rl_show_mode_in_prompt) + _rl_reset_prompt (); + + return 0; +} + +/* Function for the rest of the library to use to set insert/overwrite mode. */ +void +_rl_set_insert_mode (int im, int force) +{ +#ifdef CURSOR_MODE + _rl_set_cursor (im, force); +#endif + + rl_insert_mode = im; +} + +/* Toggle overwrite mode. A positive explicit argument selects overwrite + mode. A negative or zero explicit argument selects insert mode. */ +int +rl_overwrite_mode (int count, int key) +{ + if (rl_explicit_arg == 0) + _rl_set_insert_mode (rl_insert_mode ^ 1, 0); + else if (count > 0) + _rl_set_insert_mode (RL_IM_OVERWRITE, 0); + else + _rl_set_insert_mode (RL_IM_INSERT, 0); + + return 0; +} diff --git a/utshell-0.5.0/lib/readline/nls.c b/utshell-0.5.0/lib/readline/nls.c new file mode 100644 index 00000000..d2f67e0d --- /dev/null +++ b/utshell-0.5.0/lib/readline/nls.c @@ -0,0 +1,290 @@ +/* nls.c -- skeletal internationalization code. */ + +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#if defined (HAVE_LANGINFO_CODESET) +# include +#endif + +#include + +#include "rldefs.h" +#include "readline.h" +#include "rlshell.h" +#include "rlprivate.h" + +static int utf8locale PARAMS((char *)); + +#if !defined (HAVE_SETLOCALE) +/* A list of legal values for the LANG or LC_CTYPE environment variables. + If a locale name in this list is the value for the LC_ALL, LC_CTYPE, + or LANG environment variable (using the first of those with a value), + readline eight-bit mode is enabled. */ +static char *legal_lang_values[] = +{ + "iso88591", + "iso88592", + "iso88593", + "iso88594", + "iso88595", + "iso88596", + "iso88597", + "iso88598", + "iso88599", + "iso885910", + "koi8r", + "utf8", + 0 +}; + +static char *normalize_codeset PARAMS((char *)); +#endif /* !HAVE_SETLOCALE */ + +static char *find_codeset PARAMS((char *, size_t *)); + +static char *_rl_get_locale_var PARAMS((const char *)); + +static char * +_rl_get_locale_var (const char *v) +{ + char *lspec; + + lspec = sh_get_env_value ("LC_ALL"); + if (lspec == 0 || *lspec == 0) + lspec = sh_get_env_value (v); + if (lspec == 0 || *lspec == 0) + lspec = sh_get_env_value ("LANG"); + + return lspec; +} + +static int +utf8locale (char *lspec) +{ + char *cp; + size_t len; + +#if HAVE_LANGINFO_CODESET + cp = nl_langinfo (CODESET); + return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8")); +#else + cp = find_codeset (lspec, &len); + + if (cp == 0 || len < 4 || len > 5) + return 0; + return ((len == 5) ? strncmp (cp, "UTF-8", len) == 0 : strncmp (cp, "utf8", 4) == 0); +#endif +} + +/* Query the right environment variables and call setlocale() to initialize + the C library locale settings. */ +char * +_rl_init_locale (void) +{ + char *ret, *lspec; + + /* Set the LC_CTYPE locale category from environment variables. */ + lspec = _rl_get_locale_var ("LC_CTYPE"); + /* Since _rl_get_locale_var queries the right environment variables, + we query the current locale settings with setlocale(), and, if + that doesn't return anything, we set lspec to the empty string to + force the subsequent call to setlocale() to define the `native' + environment. */ + if (lspec == 0 || *lspec == 0) + lspec = setlocale (LC_CTYPE, (char *)NULL); + if (lspec == 0) + lspec = ""; + ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */ + + _rl_utf8locale = (ret && *ret) ? utf8locale (ret) : 0; + + return ret; +} + +/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value + to decide the defaults for 8-bit character input and output. Returns + 1 if we set eight-bit mode. */ +int +_rl_init_eightbit (void) +{ +/* If we have setlocale(3), just check the current LC_CTYPE category + value, and go into eight-bit mode if it's not C or POSIX. */ +#if defined (HAVE_SETLOCALE) + char *lspec, *t; + + t = _rl_init_locale (); /* returns static pointer */ + + if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + return (1); + } + else + return (0); + +#else /* !HAVE_SETLOCALE */ + char *lspec, *t; + int i; + + /* We don't have setlocale. Finesse it. Check the environment for the + appropriate variables and set eight-bit mode if they have the right + values. */ + lspec = _rl_get_locale_var ("LC_CTYPE"); + + if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) + return (0); + for (i = 0; t && legal_lang_values[i]; i++) + if (STREQ (t, legal_lang_values[i])) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + break; + } + + _rl_utf8locale = *t ? STREQ (t, "utf8") : 0; + + xfree (t); + return (legal_lang_values[i] ? 1 : 0); +#endif /* !HAVE_SETLOCALE */ +} + +#if !defined (HAVE_SETLOCALE) +static char * +normalize_codeset (char *codeset) +{ + size_t namelen, i; + int len, all_digits; + char *wp, *retval; + + codeset = find_codeset (codeset, &namelen); + + if (codeset == 0) + return (codeset); + + all_digits = 1; + for (len = 0, i = 0; i < namelen; i++) + { + if (ISALNUM ((unsigned char)codeset[i])) + { + len++; + all_digits &= _rl_digit_p (codeset[i]); + } + } + + retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1); + if (retval == 0) + return ((char *)0); + + wp = retval; + /* Add `iso' to beginning of an all-digit codeset */ + if (all_digits) + { + *wp++ = 'i'; + *wp++ = 's'; + *wp++ = 'o'; + } + + for (i = 0; i < namelen; i++) + if (ISALPHA ((unsigned char)codeset[i])) + *wp++ = _rl_to_lower (codeset[i]); + else if (_rl_digit_p (codeset[i])) + *wp++ = codeset[i]; + *wp = '\0'; + + return retval; +} +#endif /* !HAVE_SETLOCALE */ + +/* Isolate codeset portion of locale specification. */ +static char * +find_codeset (char *name, size_t *lenp) +{ + char *cp, *language, *result; + + cp = language = name; + result = (char *)0; + + while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',') + cp++; + + /* This does not make sense: language has to be specified. As + an exception we allow the variable to contain only the codeset + name. Perhaps there are funny codeset names. */ + if (language == cp) + { + *lenp = strlen (language); + result = language; + } + else + { + /* Next is the territory. */ + if (*cp == '_') + do + ++cp; + while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_'); + + /* Now, finally, is the codeset. */ + result = cp; + if (*cp == '.') + do + ++cp; + while (*cp && *cp != '@'); + + if (cp - result > 2) + { + result++; + *lenp = cp - result; + } + else + { + *lenp = strlen (language); + result = language; + } + } + + return result; +} diff --git a/utshell-0.5.0/lib/readline/parens.c b/utshell-0.5.0/lib/readline/parens.c new file mode 100644 index 00000000..af479773 --- /dev/null +++ b/utshell-0.5.0/lib/readline/parens.c @@ -0,0 +1,180 @@ +/* parens.c -- implementation of matching parentheses feature. */ + +/* Copyright (C) 1987, 1989, 1992-2015, 2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (__TANDEM) +# include +#endif + +#include "rlconf.h" + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "posixselect.h" + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#include "readline.h" +#include "rlprivate.h" + +static int find_matching_open PARAMS((char *, int, int)); + +/* Non-zero means try to blink the matching open parenthesis when the + close parenthesis is inserted. */ +int rl_blink_matching_paren = 0; + +static int _paren_blink_usec = 500000; + +/* Change emacs_standard_keymap to have bindings for paren matching when + ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */ +void +_rl_enable_paren_matching (int on_or_off) +{ + if (on_or_off) + { + /* ([{ */ + rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap); + rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap); + rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap); + +#if defined (VI_MODE) + /* ([{ */ + rl_bind_key_in_map (')', rl_insert_close, vi_insertion_keymap); + rl_bind_key_in_map (']', rl_insert_close, vi_insertion_keymap); + rl_bind_key_in_map ('}', rl_insert_close, vi_insertion_keymap); +#endif + } + else + { + /* ([{ */ + rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap); + rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap); + rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap); + +#if defined (VI_MODE) + /* ([{ */ + rl_bind_key_in_map (')', rl_insert, vi_insertion_keymap); + rl_bind_key_in_map (']', rl_insert, vi_insertion_keymap); + rl_bind_key_in_map ('}', rl_insert, vi_insertion_keymap); +#endif + } +} + +int +rl_set_paren_blink_timeout (int u) +{ + int o; + + o = _paren_blink_usec; + if (u > 0) + _paren_blink_usec = u; + return (o); +} + +int +rl_insert_close (int count, int invoking_key) +{ + if (rl_explicit_arg || !rl_blink_matching_paren) + _rl_insert_char (count, invoking_key); + else + { +#if defined (HAVE_SELECT) + int orig_point, match_point, ready; + struct timeval timer; + fd_set readfds; + + _rl_insert_char (1, invoking_key); + (*rl_redisplay_function) (); + match_point = + find_matching_open (rl_line_buffer, rl_point - 2, invoking_key); + + /* Emacs might message or ring the bell here, but I don't. */ + if (match_point < 0) + return 1; + + FD_ZERO (&readfds); + FD_SET (fileno (rl_instream), &readfds); + USEC_TO_TIMEVAL (_paren_blink_usec, timer); + + orig_point = rl_point; + rl_point = match_point; + (*rl_redisplay_function) (); + ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); + rl_point = orig_point; +#else /* !HAVE_SELECT */ + _rl_insert_char (count, invoking_key); +#endif /* !HAVE_SELECT */ + } + return 0; +} + +static int +find_matching_open (char *string, int from, int closer) +{ + register int i; + int opener, level, delimiter; + + switch (closer) + { + case ']': opener = '['; break; + case '}': opener = '{'; break; + case ')': opener = '('; break; + default: + return (-1); + } + + level = 1; /* The closer passed in counts as 1. */ + delimiter = 0; /* Delimited state unknown. */ + + for (i = from; i > -1; i--) + { + if (delimiter && (string[i] == delimiter)) + delimiter = 0; + else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i])) + delimiter = string[i]; + else if (!delimiter && (string[i] == closer)) + level++; + else if (!delimiter && (string[i] == opener)) + level--; + + if (!level) + break; + } + return (i); +} diff --git a/utshell-0.5.0/lib/readline/parse-colors.c b/utshell-0.5.0/lib/readline/parse-colors.c new file mode 100644 index 00000000..05ec9bc3 --- /dev/null +++ b/utshell-0.5.0/lib/readline/parse-colors.c @@ -0,0 +1,440 @@ +/* `dir', `vdir' and `ls' directory listing programs for GNU. + + Modified by Chet Ramey for Readline. + + Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2017 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Richard Stallman and David MacKenzie. */ + +/* Color support by Peter Anvin and Dennis + Flaherty based on original patches by + Greg Lee . */ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +// strdup() / strcpy() +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +// abort() +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "rldefs.h" // STREQ, savestring +#include "readline.h" +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#include "colors.h" +#include "parse-colors.h" + +#if defined (COLOR_SUPPORT) + +static bool get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count); + +struct bin_str _rl_color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, // lc: Left of color sequence + { LEN_STR_PAIR ("m") }, // rc: Right of color sequence + { 0, NULL }, // ec: End color (replaces lc+no+rc) + { LEN_STR_PAIR ("0") }, // rs: Reset to ordinary colors + { 0, NULL }, // no: Normal + { 0, NULL }, // fi: File: default + { LEN_STR_PAIR ("01;34") }, // di: Directory: bright blue + { LEN_STR_PAIR ("01;36") }, // ln: Symlink: bright cyan + { LEN_STR_PAIR ("33") }, // pi: Pipe: yellow/brown + { LEN_STR_PAIR ("01;35") }, // so: Socket: bright magenta + { LEN_STR_PAIR ("01;33") }, // bd: Block device: bright yellow + { LEN_STR_PAIR ("01;33") }, // cd: Char device: bright yellow + { 0, NULL }, // mi: Missing file: undefined + { 0, NULL }, // or: Orphaned symlink: undefined + { LEN_STR_PAIR ("01;32") }, // ex: Executable: bright green + { LEN_STR_PAIR ("01;35") }, // do: Door: bright magenta + { LEN_STR_PAIR ("37;41") }, // su: setuid: white on red + { LEN_STR_PAIR ("30;43") }, // sg: setgid: black on yellow + { LEN_STR_PAIR ("37;44") }, // st: sticky: black on blue + { LEN_STR_PAIR ("34;42") }, // ow: other-writable: blue on green + { LEN_STR_PAIR ("30;42") }, // tw: ow w/ sticky: black on green + { LEN_STR_PAIR ("30;41") }, // ca: black on red + { 0, NULL }, // mh: disabled by default + { LEN_STR_PAIR ("\033[K") }, // cl: clear to end of line + }; + +/* Parse a string as part of the LS_COLORS variable; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count) { + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + /* should we ? */ + /* abort (); no, we should not */ + state = ST_ERROR; + break; + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} +#endif /* COLOR_SUPPORT */ + +void _rl_parse_colors(void) +{ +#if defined (COLOR_SUPPORT) + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int state; /* State of parser */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + COLOR_EXT_TYPE *ext; /* Extension we are working on */ + + p = sh_get_env_value ("LS_COLORS"); + if (p == 0 || *p == '\0') + { + _rl_color_ext_list = NULL; + return; + } + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + LS_COLORS string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = savestring (p); + + state = 1; + while (state > 0) + { + switch (state) + { + case 1: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = (COLOR_EXT_TYPE *)xmalloc (sizeof *ext); + ext->next = _rl_color_ext_list; + _rl_color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? 4 : -1); + break; + + case '\0': + state = 0; /* Done! */ + break; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = 2; + break; + } + break; + + case 2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = 3; + } + else + state = -1; /* Error */ + break; + + case 3: /* Equal sign after indicator label */ + state = -1; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + _rl_color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &_rl_color_indicator[ind_no].len) + ? 1 : -1); + break; + } + } + if (state == -1) + { + _rl_errmsg ("LS_COLORS: unrecognized prefix: %s", label); + /* recover from an unrecognized prefix */ + while (p && *p && *p != ':') + p++; + if (p && *p == ':') + state = 1; + else if (p && *p == 0) + state = 0; + } + } + break; + + case 4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? 1 : -1); + } + else + state = -1; + /* XXX - recover here as with an unrecognized prefix? */ + if (state == -1 && ext->ext.string) + _rl_errmsg ("LS_COLORS: syntax error: %s", ext->ext.string); + break; + } + } + + if (state < 0) + { + COLOR_EXT_TYPE *e; + COLOR_EXT_TYPE *e2; + + _rl_errmsg ("unparsable value for LS_COLORS environment variable"); + free (color_buf); + for (e = _rl_color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + _rl_color_ext_list = NULL; + _rl_colored_stats = 0; /* can't have colored stats without colors */ + } +#else /* !COLOR_SUPPORT */ + ; +#endif /* !COLOR_SUPPORT */ +} diff --git a/utshell-0.5.0/lib/readline/parse-colors.h b/utshell-0.5.0/lib/readline/parse-colors.h new file mode 100644 index 00000000..aef86f78 --- /dev/null +++ b/utshell-0.5.0/lib/readline/parse-colors.h @@ -0,0 +1,46 @@ +/* `dir', `vdir' and `ls' directory listing programs for GNU. + + Modified by Chet Ramey for Readline. + + Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Richard Stallman and David MacKenzie. */ + +/* Color support by Peter Anvin and Dennis + Flaherty based on original patches by + Greg Lee . */ + +#ifndef _PARSE_COLORS_H_ +#define _PARSE_COLORS_H_ + +#include "readline.h" + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +void _rl_parse_colors (void); + +static const char *const indicator_name[]= + { + "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", + "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st", + "ow", "tw", "ca", "mh", "cl", NULL + }; + +/* Buffer for color sequences */ +static char *color_buf; + +#endif /* !_PARSE_COLORS_H_ */ diff --git a/utshell-0.5.0/lib/readline/posixdir.h b/utshell-0.5.0/lib/readline/posixdir.h new file mode 100644 index 00000000..af5be801 --- /dev/null +++ b/utshell-0.5.0/lib/readline/posixdir.h @@ -0,0 +1,71 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991,2012 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of or . */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include +# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN) +# define D_NAMLEN(d) ((d)->d_namlen) +# else +# define D_NAMLEN(d) (strlen ((d)->d_name)) +# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */ +#else +# if defined (HAVE_SYS_NDIR_H) +# include +# endif +# if defined (HAVE_SYS_DIR_H) +# include +# endif +# if defined (HAVE_NDIR_H) +# include +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +/* The bash code fairly consistently uses d_fileno; make sure it's available */ +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO) +# define d_fileno d_ino +#endif + +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +#if !defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO) +# define REAL_DIR_ENTRY(dp) 1 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* _POSIX_SOURCE */ + +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (BROKEN_DIRENT_D_INO) +# define D_INO_AVAILABLE +#endif + +/* Signal the rest of the code that it can safely use dirent.d_fileno */ +#if defined (D_INO_AVAILABLE) || defined (HAVE_STRUCT_DIRENT_D_FILENO) +# define D_FILENO_AVAILABLE 1 +#endif + +#endif /* !_POSIXDIR_H_ */ diff --git a/utshell-0.5.0/lib/readline/posixjmp.h b/utshell-0.5.0/lib/readline/posixjmp.h new file mode 100644 index 00000000..9c7e99ed --- /dev/null +++ b/utshell-0.5.0/lib/readline/posixjmp.h @@ -0,0 +1,46 @@ +/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ + +/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXJMP_H_ +#define _POSIXJMP_H_ + +#include + +/* This *must* be included *after* config.h */ + +#if defined (HAVE_POSIX_SIGSETJMP) +# define procenv_t sigjmp_buf + +# define setjmp_nosigs(x) sigsetjmp((x), 0) +# define setjmp_sigs(x) sigsetjmp((x), 1) + +# define _rl_longjmp(x, n) siglongjmp((x), (n)) +# define sh_longjmp(x, n) siglongjmp((x), (n)) +#else +# define procenv_t jmp_buf + +# define setjmp_nosigs setjmp +# define setjmp_sigs setjmp + +# define _rl_longjmp(x, n) longjmp((x), (n)) +# define sh_longjmp(x, n) longjmp((x), (n)) +#endif + +#endif /* _POSIXJMP_H_ */ diff --git a/utshell-0.5.0/lib/readline/posixselect.h b/utshell-0.5.0/lib/readline/posixselect.h new file mode 100644 index 00000000..da6a1ace --- /dev/null +++ b/utshell-0.5.0/lib/readline/posixselect.h @@ -0,0 +1,47 @@ +/* posixselect.h -- wrapper for select(2) includes and definitions */ + +/* Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXSELECT_H_ +#define _POSIXSELECT_H_ + +#if defined (FD_SET) && !defined (HAVE_SELECT) +# define HAVE_SELECT 1 +#endif + +#if defined (HAVE_SELECT) +# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) +# include +# endif +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#ifndef USEC_PER_SEC +# define USEC_PER_SEC 1000000 +#endif + +#define USEC_TO_TIMEVAL(us, tv) \ +do { \ + (tv).tv_sec = (us) / USEC_PER_SEC; \ + (tv).tv_usec = (us) % USEC_PER_SEC; \ +} while (0) + +#endif /* _POSIXSELECT_H_ */ diff --git a/utshell-0.5.0/lib/readline/posixstat.h b/utshell-0.5.0/lib/readline/posixstat.h new file mode 100644 index 00000000..b6077860 --- /dev/null +++ b/utshell-0.5.0/lib/readline/posixstat.h @@ -0,0 +1,162 @@ +/* posixstat.h -- Posix stat(2) definitions for systems that + don't have them. */ + +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of . + It relies on the local sys/stat.h to work though. */ +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ + +#include + +#if defined (STAT_MACROS_BROKEN) +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISREG +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ + +/* Posix 1003.1 5.6.1.1 file types */ + +/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but + do not provide the S_IS* macros that Posix requires. */ + +#if defined (_S_IFMT) && !defined (S_IFMT) +#define S_IFMT _S_IFMT +#endif +#if defined (_S_IFIFO) && !defined (S_IFIFO) +#define S_IFIFO _S_IFIFO +#endif +#if defined (_S_IFCHR) && !defined (S_IFCHR) +#define S_IFCHR _S_IFCHR +#endif +#if defined (_S_IFDIR) && !defined (S_IFDIR) +#define S_IFDIR _S_IFDIR +#endif +#if defined (_S_IFBLK) && !defined (S_IFBLK) +#define S_IFBLK _S_IFBLK +#endif +#if defined (_S_IFREG) && !defined (S_IFREG) +#define S_IFREG _S_IFREG +#endif +#if defined (_S_IFLNK) && !defined (S_IFLNK) +#define S_IFLNK _S_IFLNK +#endif +#if defined (_S_IFSOCK) && !defined (S_IFSOCK) +#define S_IFSOCK _S_IFSOCK +#endif + +/* Test for each symbol individually and define the ones necessary (some + systems claiming Posix compatibility define some but not all). */ + +#if defined (S_IFBLK) && !defined (S_ISBLK) +#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ +#endif + +#if defined (S_IFCHR) && !defined (S_ISCHR) +#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ +#endif + +#if defined (S_IFDIR) && !defined (S_ISDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ +#endif + +#if defined (S_IFREG) && !defined (S_ISREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ +#endif + +#if defined (S_IFIFO) && !defined (S_ISFIFO) +#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ +#endif + +#if defined (S_IFLNK) && !defined (S_ISLNK) +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ +#endif + +#if defined (S_IFSOCK) && !defined (S_ISSOCK) +#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ +#endif + +/* + * POSIX 1003.1 5.6.1.2 File Modes + */ + +#if !defined (S_IRWXU) +# if !defined (S_IREAD) +# define S_IREAD 00400 +# define S_IWRITE 00200 +# define S_IEXEC 00100 +# endif /* S_IREAD */ + +# if !defined (S_IRUSR) +# define S_IRUSR S_IREAD /* read, owner */ +# define S_IWUSR S_IWRITE /* write, owner */ +# define S_IXUSR S_IEXEC /* execute, owner */ + +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ + +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IRUSR */ + +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#else /* !S_IRWXU */ + /* S_IRWXU is defined, but "group" and "other" bits might not be + (happens in certain versions of MinGW). */ +# if !defined (S_IRGRP) +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ +# endif /* !S_IRGRP */ + +# if !defined (S_IROTH) +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IROTH */ +# if !defined (S_IRWXG) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# endif +# if !defined (S_IRWXO) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +# endif +#endif /* !S_IRWXU */ + +/* These are non-standard, but are used in builtins.c$symbolic_umask() */ +#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#endif /* _POSIXSTAT_H_ */ diff --git a/utshell-0.5.0/lib/readline/readline.c b/utshell-0.5.0/lib/readline/readline.c new file mode 100644 index 00000000..c8726ff0 --- /dev/null +++ b/utshell-0.5.0/lib/readline/readline.c @@ -0,0 +1,1581 @@ +/* readline.c -- a general facility for reading lines of input + with emacs style editing and completion. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include "posixstat.h" +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include +#include "posixjmp.h" +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if defined (HAVE_DECL_AUDIT_USER_TTY) +# include +# include +# include +#endif + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (__EMX__) +# define INCL_DOSPROCESS +# include +#endif /* __EMX__ */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#ifndef RL_LIBRARY_VERSION +# define RL_LIBRARY_VERSION "8.0" +#endif + +#ifndef RL_READLINE_VERSION +# define RL_READLINE_VERSION 0x0800 +#endif + +extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +#if defined (COLOR_SUPPORT) +extern void _rl_parse_colors PARAMS((void)); /* XXX */ +#endif + + +/* Forward declarations used in this file. */ +static char *readline_internal PARAMS((void)); +static void readline_initialize_everything PARAMS((void)); + +static void bind_arrow_keys_internal PARAMS((Keymap)); +static void bind_arrow_keys PARAMS((void)); + +static void bind_bracketed_paste_prefix PARAMS((void)); + +static void readline_default_bindings PARAMS((void)); +static void reset_default_bindings PARAMS((void)); + +static int _rl_subseq_result PARAMS((int, Keymap, int, int)); +static int _rl_subseq_getchar PARAMS((int)); + +/* **************************************************************** */ +/* */ +/* Line editing input utility */ +/* */ +/* **************************************************************** */ + +const char *rl_library_version = RL_LIBRARY_VERSION; + +int rl_readline_version = RL_READLINE_VERSION; + +/* True if this is `real' readline as opposed to some stub substitute. */ +int rl_gnu_readline_p = 1; + +/* A pointer to the keymap that is currently in use. + By default, it is the standard emacs keymap. */ +Keymap _rl_keymap = emacs_standard_keymap; + +/* The current style of editing. */ +int rl_editing_mode = emacs_mode; + +/* The current insert mode: input (the default) or overwrite */ +int rl_insert_mode = RL_IM_DEFAULT; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +int rl_dispatching; + +/* Non-zero if the previous command was a kill command. */ +int _rl_last_command_was_kill = 0; + +/* The current value of the numeric argument specified by the user. */ +int rl_numeric_arg = 1; + +/* Non-zero if an argument was typed. */ +int rl_explicit_arg = 0; + +/* Temporary value used while generating the argument. */ +int rl_arg_sign = 1; + +/* Non-zero means we have been called at least once before. */ +static int rl_initialized; + +#if 0 +/* If non-zero, this program is running in an EMACS buffer. */ +static int running_in_emacs; +#endif + +/* Flags word encapsulating the current readline state. */ +unsigned long rl_readline_state = RL_STATE_NONE; + +/* The current offset in the current input line. */ +int rl_point; + +/* Mark in the current input line. */ +int rl_mark; + +/* Length of the current input line. */ +int rl_end; + +/* Make this non-zero to return the current input_line. */ +int rl_done; + +/* The last function executed by readline. */ +rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL; + +/* Top level environment for readline_internal (). */ +procenv_t _rl_top_level; + +/* The streams we interact with. */ +FILE *_rl_in_stream, *_rl_out_stream; + +/* The names of the streams that we do input and output to. */ +FILE *rl_instream = (FILE *)NULL; +FILE *rl_outstream = (FILE *)NULL; + +/* Non-zero means echo characters as they are read. Defaults to no echo; + set to 1 if there is a controlling terminal, we can get its attributes, + and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings + for the code that sets it. */ +int _rl_echoing_p = 0; + +/* Current prompt. */ +char *rl_prompt = (char *)NULL; +int rl_visible_prompt_length = 0; + +/* Set to non-zero by calling application if it has already printed rl_prompt + and does not want readline to do it the first time. */ +int rl_already_prompted = 0; + +/* The number of characters read in order to type this complete command. */ +int rl_key_sequence_length = 0; + +/* If non-zero, then this is the address of a function to call just + before readline_internal_setup () prints the first prompt. */ +rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL; + +/* Any readline function can set this and have it run just before the user's + rl_startup_hook. */ +rl_hook_func_t *_rl_internal_startup_hook = (rl_hook_func_t *)NULL; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL; + +/* What we use internally. You should always refer to RL_LINE_BUFFER. */ +static char *the_line; + +/* The character that can generate an EOF. Really read from + the terminal driver... just defaulted here. */ +int _rl_eof_char = CTRL ('D'); + +/* Non-zero makes this the next keystroke to read. */ +int rl_pending_input = 0; + +/* If non-zero when readline_internal returns, it means we found EOF */ +int _rl_eof_found = 0; + +/* Pointer to a useful terminal name. */ +const char *rl_terminal_name = (const char *)NULL; + +/* Non-zero means to always use horizontal scrolling in line display. */ +int _rl_horizontal_scroll_mode = 0; + +/* Non-zero means to display an asterisk at the starts of history lines + which have been modified. */ +int _rl_mark_modified_lines = 0; + +/* The style of `bell' notification preferred. This can be set to NO_BELL, + AUDIBLE_BELL, or VISIBLE_BELL. */ +int _rl_bell_preference = AUDIBLE_BELL; + +/* String inserted into the line by rl_insert_comment (). */ +char *_rl_comment_begin; + +/* Keymap holding the function currently being executed. */ +Keymap rl_executing_keymap; + +/* Keymap we're currently using to dispatch. */ +Keymap _rl_dispatching_keymap; + +/* Non-zero means to erase entire line, including prompt, on empty input lines. */ +int rl_erase_empty_line = 0; + +/* Non-zero means to read only this many characters rather than up to a + character bound to accept-line. */ +int rl_num_chars_to_read = 0; + +/* Line buffer and maintenance. */ +char *rl_line_buffer = (char *)NULL; +int rl_line_buffer_len = 0; + +/* Key sequence `contexts' */ +_rl_keyseq_cxt *_rl_kscxt = 0; + +int rl_executing_key; +char *rl_executing_keyseq = 0; +int _rl_executing_keyseq_size = 0; + +struct _rl_cmd _rl_pending_command; +struct _rl_cmd *_rl_command_to_execute = (struct _rl_cmd *)NULL; + +/* Timeout (specified in milliseconds) when reading characters making up an + ambiguous multiple-key sequence */ +int _rl_keyseq_timeout = 500; + +#define RESIZE_KEYSEQ_BUFFER() \ + do \ + { \ + if (rl_key_sequence_length + 2 >= _rl_executing_keyseq_size) \ + { \ + _rl_executing_keyseq_size += 16; \ + rl_executing_keyseq = xrealloc (rl_executing_keyseq, _rl_executing_keyseq_size); \ + } \ + } \ + while (0); + +/* Forward declarations used by the display, termcap, and history code. */ + +/* **************************************************************** */ +/* */ +/* `Forward' declarations */ +/* */ +/* **************************************************************** */ + +/* Non-zero means do not parse any lines other than comments and + parser directives. */ +unsigned char _rl_parsing_conditionalized_out = 0; + +/* Non-zero means to convert characters with the meta bit set to + escape-prefixed characters so we can indirect through + emacs_meta_keymap or vi_escape_keymap. */ +int _rl_convert_meta_chars_to_ascii = 1; + +/* Non-zero means to output characters with the meta bit set directly + rather than as a meta-prefixed escape sequence. */ +int _rl_output_meta_chars = 0; + +/* Non-zero means to look at the termios special characters and bind + them to equivalent readline functions at startup. */ +int _rl_bind_stty_chars = 1; + +/* Non-zero means to go through the history list at every newline (or + whenever rl_done is set and readline returns) and revert each line to + its initial state. */ +int _rl_revert_all_at_newline = 0; + +/* Non-zero means to honor the termios ECHOCTL bit and echo control + characters corresponding to keyboard-generated signals. */ +int _rl_echo_control_chars = 1; + +/* Non-zero means to prefix the displayed prompt with a character indicating + the editing mode: @ for emacs, : for vi-command, + for vi-insert. */ +int _rl_show_mode_in_prompt = 0; + +/* Non-zero means to attempt to put the terminal in `bracketed paste mode', + where it will prefix pasted text with an escape sequence and send + another to mark the end of the paste. */ +int _rl_enable_bracketed_paste = BRACKETED_PASTE_DEFAULT; +int _rl_enable_active_region = BRACKETED_PASTE_DEFAULT; + +/* **************************************************************** */ +/* */ +/* Top Level Functions */ +/* */ +/* **************************************************************** */ + +/* Non-zero means treat 0200 bit in terminal input as Meta bit. */ +int _rl_meta_flag = 0; /* Forward declaration */ + +/* Set up the prompt and expand it. Called from readline() and + rl_callback_handler_install (). */ +int +rl_set_prompt (const char *prompt) +{ + FREE (rl_prompt); + rl_prompt = prompt ? savestring (prompt) : (char *)NULL; + rl_display_prompt = rl_prompt ? rl_prompt : ""; + + rl_visible_prompt_length = rl_expand_prompt (rl_prompt); + return 0; +} + +#if defined (HAVE_DECL_AUDIT_USER_TTY) +/* Report STRING to the audit system. */ +static void +audit_tty (char *string) +{ + struct sockaddr_nl addr; + struct msghdr msg; + struct nlmsghdr nlm; + struct iovec iov[2]; + size_t size; + int fd; + + size = strlen (string) + 1; + fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); + if (fd < 0) + return; + nlm.nlmsg_len = NLMSG_LENGTH (size); + nlm.nlmsg_type = AUDIT_USER_TTY; + nlm.nlmsg_flags = NLM_F_REQUEST; + nlm.nlmsg_seq = 0; + nlm.nlmsg_pid = 0; + iov[0].iov_base = &nlm; + iov[0].iov_len = sizeof (nlm); + iov[1].iov_base = string; + iov[1].iov_len = size; + addr.nl_family = AF_NETLINK; + addr.nl_pad = 0; + addr.nl_pid = 0; + addr.nl_groups = 0; + msg.msg_name = &addr; + msg.msg_namelen = sizeof (addr); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + (void)sendmsg (fd, &msg, 0); + close (fd); +} +#endif + +/* Read a line of input. Prompt with PROMPT. An empty PROMPT means + none. A return value of NULL means that EOF was encountered. */ +char * +readline (const char *prompt) +{ + char *value; +#if 0 + int in_callback; +#endif + + /* If we are at EOF return a NULL string. */ + if (rl_pending_input == EOF) + { + rl_clear_pending_input (); + return ((char *)NULL); + } + +#if 0 + /* If readline() is called after installing a callback handler, temporarily + turn off the callback state to avoid ensuing messiness. Patch supplied + by the gdb folks. XXX -- disabled. This can be fooled and readline + left in a strange state by a poorly-timed longjmp. */ + if (in_callback = RL_ISSTATE (RL_STATE_CALLBACK)) + RL_UNSETSTATE (RL_STATE_CALLBACK); +#endif + + rl_set_prompt (prompt); + + rl_initialize (); + if (rl_prep_term_function) + (*rl_prep_term_function) (_rl_meta_flag); + +#if defined (HANDLE_SIGNALS) + rl_set_signals (); +#endif + + value = readline_internal (); + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); + +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + +#if 0 + if (in_callback) + RL_SETSTATE (RL_STATE_CALLBACK); +#endif + +#if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT) + if (value) + _rl_audit_tty (value); +#endif + + return (value); +} + +#if defined (READLINE_CALLBACKS) +# define STATIC_CALLBACK +#else +# define STATIC_CALLBACK static +#endif + +STATIC_CALLBACK void +readline_internal_setup (void) +{ + char *nprompt; + + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; + + /* Enable the meta key only for the duration of readline(), if this + terminal has one and the terminal has been initialized */ + if (_rl_enable_meta & RL_ISSTATE (RL_STATE_TERMPREPPED)) + _rl_enable_meta_key (); + + if (rl_startup_hook) + (*rl_startup_hook) (); + + if (_rl_internal_startup_hook) + (*_rl_internal_startup_hook) (); + + rl_deactivate_mark (); + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_vi_insertion_mode (1, 'i'); /* don't want to reset last */ + else +#endif /* VI_MODE */ + if (_rl_show_mode_in_prompt) + _rl_reset_prompt (); + + /* If we're not echoing, we still want to at least print a prompt, because + rl_redisplay will not do it for us. If the calling application has a + custom redisplay function, though, let that function handle it. */ + if (_rl_echoing_p == 0 && rl_redisplay_function == rl_redisplay) + { + if (rl_prompt && rl_already_prompted == 0) + { + nprompt = _rl_strip_prompt (rl_prompt); + fprintf (_rl_out_stream, "%s", nprompt); + fflush (_rl_out_stream); + xfree (nprompt); + } + } + else + { + if (rl_prompt && rl_already_prompted) + rl_on_new_line_with_prompt (); + else + rl_on_new_line (); + (*rl_redisplay_function) (); + } + + if (rl_pre_input_hook) + (*rl_pre_input_hook) (); + + RL_CHECK_SIGNALS (); +} + +STATIC_CALLBACK char * +readline_internal_teardown (int eof) +{ + char *temp; + HIST_ENTRY *entry; + + RL_CHECK_SIGNALS (); + + /* Restore the original of this history line, iff the line that we + are editing was originally in the history, AND the line has changed. */ + entry = current_history (); + + if (entry && rl_undo_list) + { + temp = savestring (the_line); + rl_revert_line (1, 0); + entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL); + _rl_free_history_entry (entry); + + strcpy (the_line, temp); + xfree (temp); + } + + if (_rl_revert_all_at_newline) + _rl_revert_all_lines (); + + /* At any rate, it is highly likely that this line has an undo list. Get + rid of it now. */ + if (rl_undo_list) + rl_free_undo_list (); + + /* Disable the meta key, if this terminal has one and we were told to use it. + The check whether or not we sent the enable string is in + _rl_disable_meta_key(); the flag is set in _rl_enable_meta_key */ + _rl_disable_meta_key (); + + /* Restore normal cursor, if available. */ + _rl_set_insert_mode (RL_IM_INSERT, 0); + + return (eof ? (char *)NULL : savestring (the_line)); +} + +void +_rl_internal_char_cleanup (void) +{ +#if defined (VI_MODE) + /* In vi mode, when you exit insert mode, the cursor moves back + over the previous character. We explicitly check for that here. */ + if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) + rl_vi_check (); +#endif /* VI_MODE */ + + if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + rl_newline (1, '\n'); + } + + if (rl_done == 0) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + } + + /* If the application writer has told us to erase the entire line if + the only character typed was something bound to rl_newline, do so. */ + if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline && + rl_point == 0 && rl_end == 0) + _rl_erase_entire_line (); +} + +STATIC_CALLBACK int +#if defined (READLINE_CALLBACKS) +readline_internal_char (void) +#else +readline_internal_charloop (void) +#endif +{ + static int lastc, eof_found; + int c, code, lk, r; + + lastc = EOF; + +#if !defined (READLINE_CALLBACKS) + eof_found = 0; + while (rl_done == 0) + { +#endif + lk = _rl_last_command_was_kill; + +#if defined (HAVE_POSIX_SIGSETJMP) + code = sigsetjmp (_rl_top_level, 0); +#else + code = setjmp (_rl_top_level); +#endif + + if (code) + { + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + /* If we get here, we're not being called from something dispatched + from _rl_callback_read_char(), which sets up its own value of + _rl_top_level (saving and restoring the old, of course), so + we can just return here. */ + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return (0); + } + + if (rl_pending_input == 0) + { + /* Then initialize the argument and number of keys read. */ + _rl_reset_argument (); + rl_executing_keyseq[rl_key_sequence_length = 0] = '\0'; + } + + RL_SETSTATE(RL_STATE_READCMD); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_READCMD); + + /* look at input.c:rl_getc() for the circumstances under which this will + be returned; punt immediately on read error without converting it to + a newline; assume that rl_read_key has already called the signal + handler. */ + if (c == READERR) + { +#if defined (READLINE_CALLBACKS) + RL_SETSTATE(RL_STATE_DONE); + return (rl_done = 1); +#else + eof_found = 1; + break; +#endif + } + + /* EOF typed to a non-blank line is ^D the first time, EOF the second + time in a row. This won't return any partial line read from the tty. + If we want to change this, to force any existing line to be returned + when read(2) reads EOF, for example, this is the place to change. */ + if (c == EOF && rl_end) + { + if (RL_SIG_RECEIVED ()) + { + RL_CHECK_SIGNALS (); + if (rl_signal_event_hook) + (*rl_signal_event_hook) (); /* XXX */ + } + + /* XXX - reading two consecutive EOFs returns EOF */ + if (RL_ISSTATE (RL_STATE_TERMPREPPED)) + { + if (lastc == _rl_eof_char || lastc == EOF) + rl_end = 0; + else + c = _rl_eof_char; + } + else + c = NEWLINE; + } + + /* The character _rl_eof_char typed to blank line, and not as the + previous character is interpreted as EOF. This doesn't work when + READLINE_CALLBACKS is defined, so hitting a series of ^Ds will + erase all the chars on the line and then return EOF. */ + if (((c == _rl_eof_char && lastc != c) || c == EOF) && rl_end == 0) + { +#if defined (READLINE_CALLBACKS) + RL_SETSTATE(RL_STATE_DONE); + return (rl_done = 1); +#else + eof_found = 1; + break; +#endif + } + + lastc = c; + r = _rl_dispatch ((unsigned char)c, _rl_keymap); + RL_CHECK_SIGNALS (); + + if (_rl_command_to_execute) + { + (*rl_redisplay_function) (); + + rl_executing_keymap = _rl_command_to_execute->map; + rl_executing_key = _rl_command_to_execute->key; + + rl_dispatching = 1; + RL_SETSTATE(RL_STATE_DISPATCHING); + r = (*(_rl_command_to_execute->func)) (_rl_command_to_execute->count, _rl_command_to_execute->key); + _rl_command_to_execute = 0; + RL_UNSETSTATE(RL_STATE_DISPATCHING); + rl_dispatching = 0; + + RL_CHECK_SIGNALS (); + } + + /* If there was no change in _rl_last_command_was_kill, then no kill + has taken place. Note that if input is pending we are reading + a prefix command, so nothing has changed yet. */ + if (rl_pending_input == 0 && lk == _rl_last_command_was_kill) + _rl_last_command_was_kill = 0; + + if (_rl_keep_mark_active) + _rl_keep_mark_active = 0; + else if (rl_mark_active_p ()) + rl_deactivate_mark (); + + _rl_internal_char_cleanup (); + +#if defined (READLINE_CALLBACKS) + return 0; +#else + } + + return (eof_found); +#endif +} + +#if defined (READLINE_CALLBACKS) +static int +readline_internal_charloop (void) +{ + int eof = 1; + + while (rl_done == 0) + eof = readline_internal_char (); + return (eof); +} +#endif /* READLINE_CALLBACKS */ + +/* Read a line of input from the global rl_instream, doing output on + the global rl_outstream. + If rl_prompt is non-null, then that is our prompt. */ +static char * +readline_internal (void) +{ + readline_internal_setup (); + _rl_eof_found = readline_internal_charloop (); + return (readline_internal_teardown (_rl_eof_found)); +} + +void +_rl_init_line_state (void) +{ + rl_point = rl_end = rl_mark = 0; + the_line = rl_line_buffer; + the_line[0] = 0; +} + +void +_rl_set_the_line (void) +{ + the_line = rl_line_buffer; +} + +#if defined (READLINE_CALLBACKS) +_rl_keyseq_cxt * +_rl_keyseq_cxt_alloc (void) +{ + _rl_keyseq_cxt *cxt; + + cxt = (_rl_keyseq_cxt *)xmalloc (sizeof (_rl_keyseq_cxt)); + + cxt->flags = cxt->subseq_arg = cxt->subseq_retval = 0; + + cxt->okey = 0; + cxt->ocxt = _rl_kscxt; + cxt->childval = 42; /* sentinel value */ + + return cxt; +} + +void +_rl_keyseq_cxt_dispose (_rl_keyseq_cxt *cxt) +{ + xfree (cxt); +} + +void +_rl_keyseq_chain_dispose (void) +{ + _rl_keyseq_cxt *cxt; + + while (_rl_kscxt) + { + cxt = _rl_kscxt; + _rl_kscxt = _rl_kscxt->ocxt; + _rl_keyseq_cxt_dispose (cxt); + } +} +#endif + +static int +_rl_subseq_getchar (int key) +{ + int k; + + if (key == ESC) + RL_SETSTATE(RL_STATE_METANEXT); + RL_SETSTATE(RL_STATE_MOREINPUT); + k = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (key == ESC) + RL_UNSETSTATE(RL_STATE_METANEXT); + + return k; +} + +#if defined (READLINE_CALLBACKS) +int +_rl_dispatch_callback (_rl_keyseq_cxt *cxt) +{ + int nkey, r; + + /* For now */ + /* The first time this context is used, we want to read input and dispatch + on it. When traversing the chain of contexts back `up', we want to use + the value from the next context down. We're simulating recursion using + a chain of contexts. */ + if ((cxt->flags & KSEQ_DISPATCHED) == 0) + { + nkey = _rl_subseq_getchar (cxt->okey); + if (nkey < 0) + { + _rl_abort_internal (); + return -1; + } + r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg); + cxt->flags |= KSEQ_DISPATCHED; + } + else + r = cxt->childval; + + /* For now */ + if (r != -3) /* don't do this if we indicate there will be other matches */ + r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ)); + + RL_CHECK_SIGNALS (); + /* We only treat values < 0 specially to simulate recursion. */ + if (r >= 0 || (r == -1 && (cxt->flags & KSEQ_SUBSEQ) == 0)) /* success! or failure! */ + { + _rl_keyseq_chain_dispose (); + RL_UNSETSTATE (RL_STATE_MULTIKEY); + return r; + } + + if (r != -3) /* magic value that says we added to the chain */ + _rl_kscxt = cxt->ocxt; + if (_rl_kscxt) + _rl_kscxt->childval = r; + if (r != -3) + _rl_keyseq_cxt_dispose (cxt); + + return r; +} +#endif /* READLINE_CALLBACKS */ + +/* Do the command associated with KEY in MAP. + If the associated command is really a keymap, then read + another key, and dispatch into that map. */ +int +_rl_dispatch (register int key, Keymap map) +{ + _rl_dispatching_keymap = map; + return _rl_dispatch_subseq (key, map, 0); +} + +int +_rl_dispatch_subseq (register int key, Keymap map, int got_subseq) +{ + int r, newkey; + char *macro; + rl_command_func_t *func; +#if defined (READLINE_CALLBACKS) + _rl_keyseq_cxt *cxt; +#endif + + if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) + { + if (map[ESC].type == ISKMAP) + { + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (ESC); + RESIZE_KEYSEQ_BUFFER (); + rl_executing_keyseq[rl_key_sequence_length++] = ESC; + map = FUNCTION_TO_KEYMAP (map, ESC); + key = UNMETA (key); + return (_rl_dispatch (key, map)); + } + else + rl_ding (); + return 0; + } + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (key); + + r = 0; + switch (map[key].type) + { + case ISFUNC: + func = map[key].function; + if (func) + { + /* Special case rl_do_lowercase_version (). */ + if (func == rl_do_lowercase_version) + /* Should we do anything special if key == ANYOTHERKEY? */ + return (_rl_dispatch (_rl_to_lower ((unsigned char)key), map)); + + rl_executing_keymap = map; + rl_executing_key = key; + + RESIZE_KEYSEQ_BUFFER(); + rl_executing_keyseq[rl_key_sequence_length++] = key; + rl_executing_keyseq[rl_key_sequence_length] = '\0'; + + rl_dispatching = 1; + RL_SETSTATE(RL_STATE_DISPATCHING); + r = (*func) (rl_numeric_arg * rl_arg_sign, key); + RL_UNSETSTATE(RL_STATE_DISPATCHING); + rl_dispatching = 0; + + /* If we have input pending, then the last command was a prefix + command. Don't change the state of rl_last_func. Otherwise, + remember the last command executed in this variable. */ +#if defined (VI_MODE) + if (rl_pending_input == 0 && map[key].function != rl_digit_argument && map[key].function != rl_vi_arg_digit) +#else + if (rl_pending_input == 0 && map[key].function != rl_digit_argument) +#endif + rl_last_func = map[key].function; + + RL_CHECK_SIGNALS (); + } + else if (map[ANYOTHERKEY].function) + { + /* OK, there's no function bound in this map, but there is a + shadow function that was overridden when the current keymap + was created. Return -2 to note that. */ + if (RL_ISSTATE (RL_STATE_MACROINPUT)) + _rl_prev_macro_key (); + else + _rl_unget_char (key); + if (rl_key_sequence_length > 0) + rl_executing_keyseq[--rl_key_sequence_length] = '\0'; + return -2; + } + else if (got_subseq) + { + /* Return -1 to note that we're in a subsequence, but we don't + have a matching key, nor was one overridden. This means + we need to back up the recursion chain and find the last + subsequence that is bound to a function. */ + if (RL_ISSTATE (RL_STATE_MACROINPUT)) + _rl_prev_macro_key (); + else + _rl_unget_char (key); + if (rl_key_sequence_length > 0) + rl_executing_keyseq[--rl_key_sequence_length] = '\0'; + return -1; + } + else + { +#if defined (READLINE_CALLBACKS) + RL_UNSETSTATE (RL_STATE_MULTIKEY); + _rl_keyseq_chain_dispose (); +#endif + _rl_abort_internal (); + return -1; + } + break; + + case ISKMAP: + if (map[key].function != 0) + { +#if defined (VI_MODE) + /* The only way this test will be true is if a subsequence has been + bound starting with ESC, generally the arrow keys. What we do is + check whether there's input in the queue, which there generally + will be if an arrow key has been pressed, and, if there's not, + just dispatch to (what we assume is) rl_vi_movement_mode right + away. This is essentially an input test with a zero timeout (by + default) or a timeout determined by the value of `keyseq-timeout' */ + /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued + takes microseconds, so multiply by 1000 */ + if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap && + (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && + _rl_pushed_input_available () == 0 && + _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0) + return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); + /* This is a very specific test. It can possibly be generalized in + the future, but for now it handles a specific case of ESC being + the last character in a keyboard macro. */ + if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap && + (RL_ISSTATE (RL_STATE_INPUTPENDING) == 0) && + (RL_ISSTATE (RL_STATE_MACROINPUT) && _rl_peek_macro_key () == 0) && + _rl_pushed_input_available () == 0 && + _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0) + return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); +#endif + + RESIZE_KEYSEQ_BUFFER (); + rl_executing_keyseq[rl_key_sequence_length++] = key; + _rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key); + + /* Allocate new context here. Use linked contexts (linked through + cxt->ocxt) to simulate recursion */ +#if defined (READLINE_CALLBACKS) +# if defined (VI_MODE) + /* If we're redoing a vi mode command and we know there is a shadowed + function corresponding to this key, just call it -- all the redoable + vi mode commands already have all the input they need, and rl_vi_redo + assumes that one call to rl_dispatch is sufficient to complete the + command. */ + if (_rl_vi_redoing && RL_ISSTATE (RL_STATE_CALLBACK) && + map[ANYOTHERKEY].function != 0) + return (_rl_subseq_result (-2, map, key, got_subseq)); +# endif + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + /* Return 0 only the first time, to indicate success to + _rl_callback_read_char. The rest of the time, we're called + from _rl_dispatch_callback, so we return -3 to indicate + special handling is necessary. */ + r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0; + cxt = _rl_keyseq_cxt_alloc (); + + if (got_subseq) + cxt->flags |= KSEQ_SUBSEQ; + cxt->okey = key; + cxt->oldmap = map; + cxt->dmap = _rl_dispatching_keymap; + cxt->subseq_arg = got_subseq || cxt->dmap[ANYOTHERKEY].function; + + RL_SETSTATE (RL_STATE_MULTIKEY); + _rl_kscxt = cxt; + + return r; /* don't indicate immediate success */ + } +#endif + + /* Tentative inter-character timeout for potential multi-key + sequences? If no input within timeout, abort sequence and + act as if we got non-matching input. */ + /* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued + takes microseconds, so multiply by 1000 */ + if (_rl_keyseq_timeout > 0 && + (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && + _rl_pushed_input_available () == 0 && + _rl_dispatching_keymap[ANYOTHERKEY].function && + _rl_input_queued (_rl_keyseq_timeout*1000) == 0) + { + if (rl_key_sequence_length > 0) + rl_executing_keyseq[--rl_key_sequence_length] = '\0'; + return (_rl_subseq_result (-2, map, key, got_subseq)); + } + + newkey = _rl_subseq_getchar (key); + if (newkey < 0) + { + _rl_abort_internal (); + return -1; + } + + r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq || map[ANYOTHERKEY].function); + return _rl_subseq_result (r, map, key, got_subseq); + } + else + { + _rl_abort_internal (); /* XXX */ + return -1; + } + break; + + case ISMACR: + if (map[key].function != 0) + { + rl_executing_keyseq[rl_key_sequence_length] = '\0'; + macro = savestring ((char *)map[key].function); + _rl_with_macro_input (macro); + return 0; + } + break; + } + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && + key != ANYOTHERKEY && + _rl_dispatching_keymap == vi_movement_keymap && + _rl_vi_textmod_command (key)) + _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); +#endif + + return (r); +} + +static int +_rl_subseq_result (int r, Keymap map, int key, int got_subseq) +{ + Keymap m; + int type, nt; + rl_command_func_t *func, *nf; + + if (r == -2) + /* We didn't match anything, and the keymap we're indexed into + shadowed a function previously bound to that prefix. Call + the function. The recursive call to _rl_dispatch_subseq has + already taken care of pushing any necessary input back onto + the input queue with _rl_unget_char. */ + { + m = _rl_dispatching_keymap; + type = m[ANYOTHERKEY].type; + func = m[ANYOTHERKEY].function; + if (type == ISFUNC && func == rl_do_lowercase_version) + r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map); + else if (type == ISFUNC) + { + /* If we shadowed a function, whatever it is, we somehow need a + keymap with map[key].func == shadowed-function. + Let's use this one. Then we can dispatch using the original + key, since there are commands (e.g., in vi mode) for which it + matters. */ + nt = m[key].type; + nf = m[key].function; + + m[key].type = type; + m[key].function = func; + /* Don't change _rl_dispatching_keymap, set it here */ + _rl_dispatching_keymap = map; /* previous map */ + r = _rl_dispatch_subseq (key, m, 0); + m[key].type = nt; + m[key].function = nf; + } + else + /* We probably shadowed a keymap, so keep going. */ + r = _rl_dispatch (ANYOTHERKEY, m); + } + else if (r < 0 && map[ANYOTHERKEY].function) + { + /* We didn't match (r is probably -1), so return something to + tell the caller that it should try ANYOTHERKEY for an + overridden function. */ + if (RL_ISSTATE (RL_STATE_MACROINPUT)) + _rl_prev_macro_key (); + else + _rl_unget_char (key); + if (rl_key_sequence_length > 0) + rl_executing_keyseq[--rl_key_sequence_length] = '\0'; + _rl_dispatching_keymap = map; + return -2; + } + else if (r < 0 && got_subseq) /* XXX */ + { + /* OK, back up the chain. */ + if (RL_ISSTATE (RL_STATE_MACROINPUT)) + _rl_prev_macro_key (); + else + _rl_unget_char (key); + if (rl_key_sequence_length > 0) + rl_executing_keyseq[--rl_key_sequence_length] = '\0'; + _rl_dispatching_keymap = map; + return -1; + } + + return r; +} + +/* **************************************************************** */ +/* */ +/* Initializations */ +/* */ +/* **************************************************************** */ + +/* Initialize readline (and terminal if not already). */ +int +rl_initialize (void) +{ + /* If we have never been called before, initialize the + terminal and data structures. */ + if (rl_initialized == 0) + { + RL_SETSTATE(RL_STATE_INITIALIZING); + readline_initialize_everything (); + RL_UNSETSTATE(RL_STATE_INITIALIZING); + rl_initialized++; + RL_SETSTATE(RL_STATE_INITIALIZED); + } + else + (void)_rl_init_locale (); /* check current locale */ + + /* Initialize the current line information. */ + _rl_init_line_state (); + + /* We aren't done yet. We haven't even gotten started yet! */ + rl_done = 0; + RL_UNSETSTATE(RL_STATE_DONE); + + /* Tell the history routines what is going on. */ + _rl_start_using_history (); + + /* Make the display buffer match the state of the line. */ + rl_reset_line_state (); + + /* No such function typed yet. */ + rl_last_func = (rl_command_func_t *)NULL; + + /* Parsing of key-bindings begins in an enabled state. */ + _rl_parsing_conditionalized_out = 0; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + _rl_vi_initialize_line (); +#endif + + /* Each line starts in insert mode (the default). */ + _rl_set_insert_mode (RL_IM_DEFAULT, 1); + + return 0; +} + +#if 0 +#if defined (__EMX__) +static void +_emx_build_environ (void) +{ + TIB *tibp; + PIB *pibp; + char *t, **tp; + int c; + + DosGetInfoBlocks (&tibp, &pibp); + t = pibp->pib_pchenv; + for (c = 1; *t; c++) + t += strlen (t) + 1; + tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *)); + t = pibp->pib_pchenv; + while (*t) + { + *tp++ = t; + t += strlen (t) + 1; + } + *tp = 0; +} +#endif /* __EMX__ */ +#endif + +/* Initialize the entire state of the world. */ +static void +readline_initialize_everything (void) +{ +#if 0 +#if defined (__EMX__) + if (environ == 0) + _emx_build_environ (); +#endif +#endif + +#if 0 + /* Find out if we are running in Emacs -- UNUSED. */ + running_in_emacs = sh_get_env_value ("EMACS") != (char *)0; +#endif + + /* Set up input and output if they are not already set up. */ + if (!rl_instream) + rl_instream = stdin; + + if (!rl_outstream) + rl_outstream = stdout; + + /* Bind _rl_in_stream and _rl_out_stream immediately. These values + may change, but they may also be used before readline_internal () + is called. */ + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; + + /* Allocate data structures. */ + if (rl_line_buffer == 0) + rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); + + /* Initialize the terminal interface. */ + if (rl_terminal_name == 0) + rl_terminal_name = sh_get_env_value ("TERM"); + _rl_init_terminal_io (rl_terminal_name); + + /* Bind tty characters to readline functions. */ + readline_default_bindings (); + + /* Initialize the function names. */ + rl_initialize_funmap (); + + /* Decide whether we should automatically go into eight-bit mode. */ + _rl_init_eightbit (); + + /* Read in the init file. */ + rl_read_init_file ((char *)NULL); + + /* XXX */ + if (_rl_horizontal_scroll_mode && _rl_term_autowrap) + { + _rl_screenwidth--; + _rl_screenchars -= _rl_screenheight; + } + + /* Override the effect of any `set keymap' assignments in the + inputrc file. */ + rl_set_keymap_from_edit_mode (); + + /* Try to bind a common arrow key prefix, if not already bound. */ + bind_arrow_keys (); + + /* Bind the bracketed paste prefix assuming that the user will enable + it on terminals that support it. */ + bind_bracketed_paste_prefix (); + + /* If the completion parser's default word break characters haven't + been set yet, then do so now. */ + if (rl_completer_word_break_characters == (char *)NULL) + rl_completer_word_break_characters = (char *)rl_basic_word_break_characters; + +#if defined (COLOR_SUPPORT) + if (_rl_colored_stats || _rl_colored_completion_prefix) + _rl_parse_colors (); +#endif + + rl_executing_keyseq = malloc (_rl_executing_keyseq_size = 16); + if (rl_executing_keyseq) + rl_executing_keyseq[rl_key_sequence_length = 0] = '\0'; +} + +/* If this system allows us to look at the values of the regular + input editing characters, then bind them to their readline + equivalents, iff the characters are not bound to keymaps. */ +static void +readline_default_bindings (void) +{ + if (_rl_bind_stty_chars) + rl_tty_set_default_bindings (_rl_keymap); +} + +/* Reset the default bindings for the terminal special characters we're + interested in back to rl_insert and read the new ones. */ +static void +reset_default_bindings (void) +{ + if (_rl_bind_stty_chars) + { + rl_tty_unset_default_bindings (_rl_keymap); + rl_tty_set_default_bindings (_rl_keymap); + } +} + +/* Bind some common arrow key sequences in MAP. */ +static void +bind_arrow_keys_internal (Keymap map) +{ + Keymap xkeymap; + + xkeymap = _rl_keymap; + _rl_keymap = map; + +#if defined (__MSDOS__) + rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char); + rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char); + rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history); +#endif + + rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char); + rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char); + rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line); + rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line); + + rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char); + rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char); + rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line); + rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line); + + /* Key bindings for control-arrow keys */ + rl_bind_keyseq_if_unbound ("\033[1;5C", rl_forward_word); + rl_bind_keyseq_if_unbound ("\033[1;5D", rl_backward_word); + rl_bind_keyseq_if_unbound ("\033[3;5~", rl_kill_word); + + /* Key bindings for alt-arrow keys */ + rl_bind_keyseq_if_unbound ("\033[1;3C", rl_forward_word); + rl_bind_keyseq_if_unbound ("\033[1;3D", rl_backward_word); + +#if defined (__MINGW32__) + rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\340M", rl_forward_char); + rl_bind_keyseq_if_unbound ("\340K", rl_backward_char); + rl_bind_keyseq_if_unbound ("\340G", rl_beg_of_line); + rl_bind_keyseq_if_unbound ("\340O", rl_end_of_line); + rl_bind_keyseq_if_unbound ("\340S", rl_delete); + rl_bind_keyseq_if_unbound ("\340R", rl_overwrite_mode); + + /* These may or may not work because of the embedded NUL. */ + rl_bind_keyseq_if_unbound ("\\000H", rl_get_previous_history); + rl_bind_keyseq_if_unbound ("\\000P", rl_get_next_history); + rl_bind_keyseq_if_unbound ("\\000M", rl_forward_char); + rl_bind_keyseq_if_unbound ("\\000K", rl_backward_char); + rl_bind_keyseq_if_unbound ("\\000G", rl_beg_of_line); + rl_bind_keyseq_if_unbound ("\\000O", rl_end_of_line); + rl_bind_keyseq_if_unbound ("\\000S", rl_delete); + rl_bind_keyseq_if_unbound ("\\000R", rl_overwrite_mode); +#endif + + _rl_keymap = xkeymap; +} + +/* Try and bind the common arrow key prefixes after giving termcap and + the inputrc file a chance to bind them and create `real' keymaps + for the arrow key prefix. */ +static void +bind_arrow_keys (void) +{ + bind_arrow_keys_internal (emacs_standard_keymap); + +#if defined (VI_MODE) + bind_arrow_keys_internal (vi_movement_keymap); + /* Unbind vi_movement_keymap[ESC] to allow users to repeatedly hit ESC + in vi command mode while still allowing the arrow keys to work. */ + if (vi_movement_keymap[ESC].type == ISKMAP) + rl_bind_keyseq_in_map ("\033", (rl_command_func_t *)NULL, vi_movement_keymap); + bind_arrow_keys_internal (vi_insertion_keymap); +#endif +} + +static void +bind_bracketed_paste_prefix (void) +{ + Keymap xkeymap; + + xkeymap = _rl_keymap; + + _rl_keymap = emacs_standard_keymap; + rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin); + +#if defined (VI_MODE) + _rl_keymap = vi_insertion_keymap; + rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin); + /* XXX - is there a reason to do this in the vi command keymap? */ +#endif + + _rl_keymap = xkeymap; +} + +/* **************************************************************** */ +/* */ +/* Saving and Restoring Readline's state */ +/* */ +/* **************************************************************** */ + +int +rl_save_state (struct readline_state *sp) +{ + if (sp == 0) + return -1; + + sp->point = rl_point; + sp->end = rl_end; + sp->mark = rl_mark; + sp->buffer = rl_line_buffer; + sp->buflen = rl_line_buffer_len; + sp->ul = rl_undo_list; + sp->prompt = rl_prompt; + + sp->rlstate = rl_readline_state; + sp->done = rl_done; + sp->kmap = _rl_keymap; + + sp->lastfunc = rl_last_func; + sp->insmode = rl_insert_mode; + sp->edmode = rl_editing_mode; + sp->kseq = rl_executing_keyseq; + sp->kseqlen = rl_key_sequence_length; + sp->inf = rl_instream; + sp->outf = rl_outstream; + sp->pendingin = rl_pending_input; + sp->macro = rl_executing_macro; + + sp->catchsigs = rl_catch_signals; + sp->catchsigwinch = rl_catch_sigwinch; + + sp->entryfunc = rl_completion_entry_function; + sp->menuentryfunc = rl_menu_completion_entry_function; + sp->ignorefunc = rl_ignore_some_completions_function; + sp->attemptfunc = rl_attempted_completion_function; + sp->wordbreakchars = rl_completer_word_break_characters; + + return (0); +} + +int +rl_restore_state (struct readline_state *sp) +{ + if (sp == 0) + return -1; + + rl_point = sp->point; + rl_end = sp->end; + rl_mark = sp->mark; + the_line = rl_line_buffer = sp->buffer; + rl_line_buffer_len = sp->buflen; + rl_undo_list = sp->ul; + rl_prompt = sp->prompt; + + rl_readline_state = sp->rlstate; + rl_done = sp->done; + _rl_keymap = sp->kmap; + + rl_last_func = sp->lastfunc; + rl_insert_mode = sp->insmode; + rl_editing_mode = sp->edmode; + rl_executing_keyseq = sp->kseq; + rl_key_sequence_length = sp->kseqlen; + rl_instream = sp->inf; + rl_outstream = sp->outf; + rl_pending_input = sp->pendingin; + rl_executing_macro = sp->macro; + + rl_catch_signals = sp->catchsigs; + rl_catch_sigwinch = sp->catchsigwinch; + + rl_completion_entry_function = sp->entryfunc; + rl_menu_completion_entry_function = sp->menuentryfunc; + rl_ignore_some_completions_function = sp->ignorefunc; + rl_attempted_completion_function = sp->attemptfunc; + rl_completer_word_break_characters = sp->wordbreakchars; + + rl_deactivate_mark (); + + return (0); +} + +/* Functions to manage the string that is the current key sequence. */ + +void +_rl_init_executing_keyseq (void) +{ + rl_executing_keyseq[rl_key_sequence_length = 0] = '\0'; +} + +void +_rl_term_executing_keyseq (void) +{ + rl_executing_keyseq[rl_key_sequence_length] = '\0'; +} + +void +_rl_end_executing_keyseq (void) +{ + if (rl_key_sequence_length > 0) + rl_executing_keyseq[--rl_key_sequence_length] = '\0'; +} + +void +_rl_add_executing_keyseq (int key) +{ + RESIZE_KEYSEQ_BUFFER (); + rl_executing_keyseq[rl_key_sequence_length++] = key; +} diff --git a/utshell-0.5.0/lib/readline/readline.h b/utshell-0.5.0/lib/readline/readline.h new file mode 100644 index 00000000..78fa39d0 --- /dev/null +++ b/utshell-0.5.0/lib/readline/readline.h @@ -0,0 +1,969 @@ +/* Readline.h -- the names of functions callable from within readline. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_READLINE_H_) +#define _READLINE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "rltypedefs.h" +# include "keymaps.h" +# include "tilde.h" +#else +# include +# include +# include +# include +#endif + +/* Hex-encoded Readline version number. */ +#define RL_READLINE_VERSION 0x0801 /* Readline 8.0 */ +#define RL_VERSION_MAJOR 8 +#define RL_VERSION_MINOR 1 + +/* Readline data structures. */ + +/* Maintaining the state of undo. We remember individual deletes and inserts + on a chain of things to do. */ + +/* The actions that undo knows how to undo. Notice that UNDO_DELETE means + to insert some text, and UNDO_INSERT means to delete some text. I.e., + the code tells undo what to undo, not how to undo it. */ +enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; + +/* What an element of THE_UNDO_LIST looks like. */ +typedef struct undo_list { + struct undo_list *next; + int start, end; /* Where the change took place. */ + char *text; /* The text to insert, if undoing a delete. */ + enum undo_code what; /* Delete, Insert, Begin, End. */ +} UNDO_LIST; + +/* The current undo list for RL_LINE_BUFFER. */ +extern UNDO_LIST *rl_undo_list; + +/* The data structure for mapping textual names to code addresses. */ +typedef struct _funmap { + const char *name; + rl_command_func_t *function; +} FUNMAP; + +extern FUNMAP **funmap; + +/* **************************************************************** */ +/* */ +/* Functions available to bind to key sequences */ +/* */ +/* **************************************************************** */ + +/* Bindable commands for numeric arguments. */ +extern int rl_digit_argument PARAMS((int, int)); +extern int rl_universal_argument PARAMS((int, int)); + +/* Bindable commands for moving the cursor. */ +extern int rl_forward_byte PARAMS((int, int)); +extern int rl_forward_char PARAMS((int, int)); +extern int rl_forward PARAMS((int, int)); +extern int rl_backward_byte PARAMS((int, int)); +extern int rl_backward_char PARAMS((int, int)); +extern int rl_backward PARAMS((int, int)); +extern int rl_beg_of_line PARAMS((int, int)); +extern int rl_end_of_line PARAMS((int, int)); +extern int rl_forward_word PARAMS((int, int)); +extern int rl_backward_word PARAMS((int, int)); +extern int rl_refresh_line PARAMS((int, int)); +extern int rl_clear_screen PARAMS((int, int)); +extern int rl_clear_display PARAMS((int, int)); +extern int rl_skip_csi_sequence PARAMS((int, int)); +extern int rl_arrow_keys PARAMS((int, int)); + +extern int rl_previous_screen_line PARAMS((int, int)); +extern int rl_next_screen_line PARAMS((int, int)); + +/* Bindable commands for inserting and deleting text. */ +extern int rl_insert PARAMS((int, int)); +extern int rl_quoted_insert PARAMS((int, int)); +extern int rl_tab_insert PARAMS((int, int)); +extern int rl_newline PARAMS((int, int)); +extern int rl_do_lowercase_version PARAMS((int, int)); +extern int rl_rubout PARAMS((int, int)); +extern int rl_delete PARAMS((int, int)); +extern int rl_rubout_or_delete PARAMS((int, int)); +extern int rl_delete_horizontal_space PARAMS((int, int)); +extern int rl_delete_or_show_completions PARAMS((int, int)); +extern int rl_insert_comment PARAMS((int, int)); + +/* Bindable commands for changing case. */ +extern int rl_upcase_word PARAMS((int, int)); +extern int rl_downcase_word PARAMS((int, int)); +extern int rl_capitalize_word PARAMS((int, int)); + +/* Bindable commands for transposing characters and words. */ +extern int rl_transpose_words PARAMS((int, int)); +extern int rl_transpose_chars PARAMS((int, int)); + +/* Bindable commands for searching within a line. */ +extern int rl_char_search PARAMS((int, int)); +extern int rl_backward_char_search PARAMS((int, int)); + +/* Bindable commands for readline's interface to the command history. */ +extern int rl_beginning_of_history PARAMS((int, int)); +extern int rl_end_of_history PARAMS((int, int)); +extern int rl_get_next_history PARAMS((int, int)); +extern int rl_get_previous_history PARAMS((int, int)); +extern int rl_operate_and_get_next PARAMS((int, int)); + +/* Bindable commands for managing the mark and region. */ +extern int rl_set_mark PARAMS((int, int)); +extern int rl_exchange_point_and_mark PARAMS((int, int)); + +/* Bindable commands to set the editing mode (emacs or vi). */ +extern int rl_vi_editing_mode PARAMS((int, int)); +extern int rl_emacs_editing_mode PARAMS((int, int)); + +/* Bindable commands to change the insert mode (insert or overwrite) */ +extern int rl_overwrite_mode PARAMS((int, int)); + +/* Bindable commands for managing key bindings. */ +extern int rl_re_read_init_file PARAMS((int, int)); +extern int rl_dump_functions PARAMS((int, int)); +extern int rl_dump_macros PARAMS((int, int)); +extern int rl_dump_variables PARAMS((int, int)); + +/* Bindable commands for word completion. */ +extern int rl_complete PARAMS((int, int)); +extern int rl_possible_completions PARAMS((int, int)); +extern int rl_insert_completions PARAMS((int, int)); +extern int rl_old_menu_complete PARAMS((int, int)); +extern int rl_menu_complete PARAMS((int, int)); +extern int rl_backward_menu_complete PARAMS((int, int)); + +/* Bindable commands for killing and yanking text, and managing the kill ring. */ +extern int rl_kill_word PARAMS((int, int)); +extern int rl_backward_kill_word PARAMS((int, int)); +extern int rl_kill_line PARAMS((int, int)); +extern int rl_backward_kill_line PARAMS((int, int)); +extern int rl_kill_full_line PARAMS((int, int)); +extern int rl_unix_word_rubout PARAMS((int, int)); +extern int rl_unix_filename_rubout PARAMS((int, int)); +extern int rl_unix_line_discard PARAMS((int, int)); +extern int rl_copy_region_to_kill PARAMS((int, int)); +extern int rl_kill_region PARAMS((int, int)); +extern int rl_copy_forward_word PARAMS((int, int)); +extern int rl_copy_backward_word PARAMS((int, int)); +extern int rl_yank PARAMS((int, int)); +extern int rl_yank_pop PARAMS((int, int)); +extern int rl_yank_nth_arg PARAMS((int, int)); +extern int rl_yank_last_arg PARAMS((int, int)); +extern int rl_bracketed_paste_begin PARAMS((int, int)); +/* Not available unless _WIN32 is defined. */ +#if defined (_WIN32) +extern int rl_paste_from_clipboard PARAMS((int, int)); +#endif + +/* Bindable commands for incremental searching. */ +extern int rl_reverse_search_history PARAMS((int, int)); +extern int rl_forward_search_history PARAMS((int, int)); + +/* Bindable keyboard macro commands. */ +extern int rl_start_kbd_macro PARAMS((int, int)); +extern int rl_end_kbd_macro PARAMS((int, int)); +extern int rl_call_last_kbd_macro PARAMS((int, int)); +extern int rl_print_last_kbd_macro PARAMS((int, int)); + +/* Bindable undo commands. */ +extern int rl_revert_line PARAMS((int, int)); +extern int rl_undo_command PARAMS((int, int)); + +/* Bindable tilde expansion commands. */ +extern int rl_tilde_expand PARAMS((int, int)); + +/* Bindable terminal control commands. */ +extern int rl_restart_output PARAMS((int, int)); +extern int rl_stop_output PARAMS((int, int)); + +/* Miscellaneous bindable commands. */ +extern int rl_abort PARAMS((int, int)); +extern int rl_tty_status PARAMS((int, int)); + +/* Bindable commands for incremental and non-incremental history searching. */ +extern int rl_history_search_forward PARAMS((int, int)); +extern int rl_history_search_backward PARAMS((int, int)); +extern int rl_history_substr_search_forward PARAMS((int, int)); +extern int rl_history_substr_search_backward PARAMS((int, int)); +extern int rl_noninc_forward_search PARAMS((int, int)); +extern int rl_noninc_reverse_search PARAMS((int, int)); +extern int rl_noninc_forward_search_again PARAMS((int, int)); +extern int rl_noninc_reverse_search_again PARAMS((int, int)); + +/* Bindable command used when inserting a matching close character. */ +extern int rl_insert_close PARAMS((int, int)); + +/* Not available unless READLINE_CALLBACKS is defined. */ +extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *)); +extern void rl_callback_read_char PARAMS((void)); +extern void rl_callback_handler_remove PARAMS((void)); +extern void rl_callback_sigcleanup PARAMS((void)); + +/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ +/* VI-mode bindable commands. */ +extern int rl_vi_redo PARAMS((int, int)); +extern int rl_vi_undo PARAMS((int, int)); +extern int rl_vi_yank_arg PARAMS((int, int)); +extern int rl_vi_fetch_history PARAMS((int, int)); +extern int rl_vi_search_again PARAMS((int, int)); +extern int rl_vi_search PARAMS((int, int)); +extern int rl_vi_complete PARAMS((int, int)); +extern int rl_vi_tilde_expand PARAMS((int, int)); +extern int rl_vi_prev_word PARAMS((int, int)); +extern int rl_vi_next_word PARAMS((int, int)); +extern int rl_vi_end_word PARAMS((int, int)); +extern int rl_vi_insert_beg PARAMS((int, int)); +extern int rl_vi_append_mode PARAMS((int, int)); +extern int rl_vi_append_eol PARAMS((int, int)); +extern int rl_vi_eof_maybe PARAMS((int, int)); +extern int rl_vi_insertion_mode PARAMS((int, int)); +extern int rl_vi_insert_mode PARAMS((int, int)); +extern int rl_vi_movement_mode PARAMS((int, int)); +extern int rl_vi_arg_digit PARAMS((int, int)); +extern int rl_vi_change_case PARAMS((int, int)); +extern int rl_vi_put PARAMS((int, int)); +extern int rl_vi_column PARAMS((int, int)); +extern int rl_vi_delete_to PARAMS((int, int)); +extern int rl_vi_change_to PARAMS((int, int)); +extern int rl_vi_yank_to PARAMS((int, int)); +extern int rl_vi_yank_pop PARAMS((int, int)); +extern int rl_vi_rubout PARAMS((int, int)); +extern int rl_vi_delete PARAMS((int, int)); +extern int rl_vi_back_to_indent PARAMS((int, int)); +extern int rl_vi_unix_word_rubout PARAMS((int, int)); +extern int rl_vi_first_print PARAMS((int, int)); +extern int rl_vi_char_search PARAMS((int, int)); +extern int rl_vi_match PARAMS((int, int)); +extern int rl_vi_change_char PARAMS((int, int)); +extern int rl_vi_subst PARAMS((int, int)); +extern int rl_vi_overstrike PARAMS((int, int)); +extern int rl_vi_overstrike_delete PARAMS((int, int)); +extern int rl_vi_replace PARAMS((int, int)); +extern int rl_vi_set_mark PARAMS((int, int)); +extern int rl_vi_goto_mark PARAMS((int, int)); + +/* VI-mode utility functions. */ +extern int rl_vi_check PARAMS((void)); +extern int rl_vi_domove PARAMS((int, int *)); +extern int rl_vi_bracktype PARAMS((int)); + +extern void rl_vi_start_inserting PARAMS((int, int, int)); + +/* VI-mode pseudo-bindable commands, used as utility functions. */ +extern int rl_vi_fWord PARAMS((int, int)); +extern int rl_vi_bWord PARAMS((int, int)); +extern int rl_vi_eWord PARAMS((int, int)); +extern int rl_vi_fword PARAMS((int, int)); +extern int rl_vi_bword PARAMS((int, int)); +extern int rl_vi_eword PARAMS((int, int)); + +/* **************************************************************** */ +/* */ +/* Well Published Functions */ +/* */ +/* **************************************************************** */ + +/* Readline functions. */ +/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ +extern char *readline PARAMS((const char *)); + +extern int rl_set_prompt PARAMS((const char *)); +extern int rl_expand_prompt PARAMS((char *)); + +extern int rl_initialize PARAMS((void)); + +/* Undocumented; unused by readline */ +extern int rl_discard_argument PARAMS((void)); + +/* Utility functions to bind keys to readline commands. */ +extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int)); +extern int rl_bind_key PARAMS((int, rl_command_func_t *)); +extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap)); +extern int rl_unbind_key PARAMS((int)); +extern int rl_unbind_key_in_map PARAMS((int, Keymap)); +extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *)); +extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap)); +extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap)); +extern int rl_unbind_command_in_map PARAMS((const char *, Keymap)); +extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *)); +extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); +extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *)); +extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); +extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap)); + +extern char *rl_variable_value PARAMS((const char *)); +extern int rl_variable_bind PARAMS((const char *, const char *)); + +/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */ +extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap)); + +/* Backwards compatibility, use rl_generic_bind instead. */ +extern int rl_macro_bind PARAMS((const char *, const char *, Keymap)); + +/* Undocumented in the texinfo manual; not really useful to programs. */ +extern int rl_translate_keyseq PARAMS((const char *, char *, int *)); +extern char *rl_untranslate_keyseq PARAMS((int)); + +extern rl_command_func_t *rl_named_function PARAMS((const char *)); +extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *)); +extern rl_command_func_t *rl_function_of_keyseq_len PARAMS((const char *, size_t, Keymap, int *)); + +extern void rl_list_funmap_names PARAMS((void)); +extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap)); +extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *)); + +extern void rl_function_dumper PARAMS((int)); +extern void rl_macro_dumper PARAMS((int)); +extern void rl_variable_dumper PARAMS((int)); + +extern int rl_read_init_file PARAMS((const char *)); +extern int rl_parse_and_bind PARAMS((char *)); + +/* Functions for manipulating keymaps. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); +extern int rl_empty_keymap PARAMS((Keymap)); +extern Keymap rl_copy_keymap PARAMS((Keymap)); +extern Keymap rl_make_keymap PARAMS((void)); +extern void rl_discard_keymap PARAMS((Keymap)); +extern void rl_free_keymap PARAMS((Keymap)); + +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); +extern char *rl_get_keymap_name PARAMS((Keymap)); +extern void rl_set_keymap PARAMS((Keymap)); +extern Keymap rl_get_keymap PARAMS((void)); + +extern int rl_set_keymap_name PARAMS((const char *, Keymap)); + +/* Undocumented; used internally only. */ +extern void rl_set_keymap_from_edit_mode PARAMS((void)); +extern char *rl_get_keymap_name_from_edit_mode PARAMS((void)); + +/* Functions for manipulating the funmap, which maps command names to functions. */ +extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *)); +extern const char **rl_funmap_names PARAMS((void)); +/* Undocumented, only used internally -- there is only one funmap, and this + function may be called only once. */ +extern void rl_initialize_funmap PARAMS((void)); + +/* Utility functions for managing keyboard macros. */ +extern void rl_push_macro_input PARAMS((char *)); + +/* Functions for undoing, from undo.c */ +extern void rl_add_undo PARAMS((enum undo_code, int, int, char *)); +extern void rl_free_undo_list PARAMS((void)); +extern int rl_do_undo PARAMS((void)); +extern int rl_begin_undo_group PARAMS((void)); +extern int rl_end_undo_group PARAMS((void)); +extern int rl_modifying PARAMS((int, int)); + +/* Functions for redisplay. */ +extern void rl_redisplay PARAMS((void)); +extern int rl_on_new_line PARAMS((void)); +extern int rl_on_new_line_with_prompt PARAMS((void)); +extern int rl_forced_update_display PARAMS((void)); +extern int rl_clear_visible_line PARAMS((void)); +extern int rl_clear_message PARAMS((void)); +extern int rl_reset_line_state PARAMS((void)); +extern int rl_crlf PARAMS((void)); + +/* Functions to manage the mark and region, especially the notion of an + active mark and an active region. */ +extern void rl_keep_mark_active PARAMS((void)); + +extern void rl_activate_mark PARAMS((void)); +extern void rl_deactivate_mark PARAMS((void)); +extern int rl_mark_active_p PARAMS((void)); + +#if defined (USE_VARARGS) && defined (PREFER_STDARG) +extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#else +extern int rl_message (); +#endif + +extern int rl_show_char PARAMS((int)); + +/* Undocumented in texinfo manual. */ +extern int rl_character_len PARAMS((int, int)); +extern void rl_redraw_prompt_last_line PARAMS((void)); + +/* Save and restore internal prompt redisplay information. */ +extern void rl_save_prompt PARAMS((void)); +extern void rl_restore_prompt PARAMS((void)); + +/* Modifying text. */ +extern void rl_replace_line PARAMS((const char *, int)); +extern int rl_insert_text PARAMS((const char *)); +extern int rl_delete_text PARAMS((int, int)); +extern int rl_kill_text PARAMS((int, int)); +extern char *rl_copy_text PARAMS((int, int)); + +/* Terminal and tty mode management. */ +extern void rl_prep_terminal PARAMS((int)); +extern void rl_deprep_terminal PARAMS((void)); +extern void rl_tty_set_default_bindings PARAMS((Keymap)); +extern void rl_tty_unset_default_bindings PARAMS((Keymap)); + +extern int rl_tty_set_echoing PARAMS((int)); +extern int rl_reset_terminal PARAMS((const char *)); +extern void rl_resize_terminal PARAMS((void)); +extern void rl_set_screen_size PARAMS((int, int)); +extern void rl_get_screen_size PARAMS((int *, int *)); +extern void rl_reset_screen_size PARAMS((void)); + +extern char *rl_get_termcap PARAMS((const char *)); + +/* Functions for character input. */ +extern int rl_stuff_char PARAMS((int)); +extern int rl_execute_next PARAMS((int)); +extern int rl_clear_pending_input PARAMS((void)); +extern int rl_read_key PARAMS((void)); +extern int rl_getc PARAMS((FILE *)); +extern int rl_set_keyboard_input_timeout PARAMS((int)); + +/* `Public' utility functions . */ +extern void rl_extend_line_buffer PARAMS((int)); +extern int rl_ding PARAMS((void)); +extern int rl_alphabetic PARAMS((int)); +extern void rl_free PARAMS((void *)); + +/* Readline signal handling, from signals.c */ +extern int rl_set_signals PARAMS((void)); +extern int rl_clear_signals PARAMS((void)); +extern void rl_cleanup_after_signal PARAMS((void)); +extern void rl_reset_after_signal PARAMS((void)); +extern void rl_free_line_state PARAMS((void)); + +extern int rl_pending_signal PARAMS((void)); +extern void rl_check_signals PARAMS((void)); + +extern void rl_echo_signal_char PARAMS((int)); + +extern int rl_set_paren_blink_timeout PARAMS((int)); + +/* History management functions. */ + +extern void rl_clear_history PARAMS((void)); + +/* Undocumented. */ +extern int rl_maybe_save_line PARAMS((void)); +extern int rl_maybe_unsave_line PARAMS((void)); +extern int rl_maybe_replace_line PARAMS((void)); + +/* Completion functions. */ +extern int rl_complete_internal PARAMS((int)); +extern void rl_display_match_list PARAMS((char **, int, int)); + +extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)); +extern char *rl_username_completion_function PARAMS((const char *, int)); +extern char *rl_filename_completion_function PARAMS((const char *, int)); + +extern int rl_completion_mode PARAMS((rl_command_func_t *)); + +#if 0 +/* Backwards compatibility (compat.c). These will go away sometime. */ +extern void free_undo_list PARAMS((void)); +extern int maybe_save_line PARAMS((void)); +extern int maybe_unsave_line PARAMS((void)); +extern int maybe_replace_line PARAMS((void)); + +extern int ding PARAMS((void)); +extern int alphabetic PARAMS((int)); +extern int crlf PARAMS((void)); + +extern char **completion_matches PARAMS((char *, rl_compentry_func_t *)); +extern char *username_completion_function PARAMS((const char *, int)); +extern char *filename_completion_function PARAMS((const char *, int)); +#endif + +/* **************************************************************** */ +/* */ +/* Well Published Variables */ +/* */ +/* **************************************************************** */ + +/* The version of this incarnation of the readline library. */ +extern const char *rl_library_version; /* e.g., "4.2" */ +extern int rl_readline_version; /* e.g., 0x0402 */ + +/* True if this is real GNU readline. */ +extern int rl_gnu_readline_p; + +/* Flags word encapsulating the current readline state. */ +extern unsigned long rl_readline_state; + +/* Says which editing mode readline is currently using. 1 means emacs mode; + 0 means vi mode. */ +extern int rl_editing_mode; + +/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means + overwrite mode. Reset to insert mode on each input line. */ +extern int rl_insert_mode; + +/* The name of the calling program. You should initialize this to + whatever was in argv[0]. It is used when parsing conditionals. */ +extern const char *rl_readline_name; + +/* The prompt readline uses. This is set from the argument to + readline (), and should not be assigned to directly. */ +extern char *rl_prompt; + +/* The prompt string that is actually displayed by rl_redisplay. Public so + applications can more easily supply their own redisplay functions. */ +extern char *rl_display_prompt; + +/* The line buffer that is in use. */ +extern char *rl_line_buffer; + +/* The location of point, and end. */ +extern int rl_point; +extern int rl_end; + +/* The mark, or saved cursor position. */ +extern int rl_mark; + +/* Flag to indicate that readline has finished with the current input + line and should return it. */ +extern int rl_done; + +/* If set to a character value, that will be the next keystroke read. */ +extern int rl_pending_input; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +extern int rl_dispatching; + +/* Non-zero if the user typed a numeric argument before executing the + current function. */ +extern int rl_explicit_arg; + +/* The current value of the numeric argument specified by the user. */ +extern int rl_numeric_arg; + +/* The address of the last command function Readline executed. */ +extern rl_command_func_t *rl_last_func; + +/* The name of the terminal to use. */ +extern const char *rl_terminal_name; + +/* The input and output streams. */ +extern FILE *rl_instream; +extern FILE *rl_outstream; + +/* If non-zero, Readline gives values of LINES and COLUMNS from the environment + greater precedence than values fetched from the kernel when computing the + screen dimensions. */ +extern int rl_prefer_env_winsize; + +/* If non-zero, then this is the address of a function to call just + before readline_internal () prints the first prompt. */ +extern rl_hook_func_t *rl_startup_hook; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +extern rl_hook_func_t *rl_pre_input_hook; + +/* The address of a function to call periodically while Readline is + awaiting character input, or NULL, for no event handling. */ +extern rl_hook_func_t *rl_event_hook; + +/* The address of a function to call if a read is interrupted by a signal. */ +extern rl_hook_func_t *rl_signal_event_hook; + +/* The address of a function to call if Readline needs to know whether or not + there is data available from the current input source. */ +extern rl_hook_func_t *rl_input_available_hook; + +/* The address of the function to call to fetch a character from the current + Readline input stream */ +extern rl_getc_func_t *rl_getc_function; + +extern rl_voidfunc_t *rl_redisplay_function; + +extern rl_vintfunc_t *rl_prep_term_function; +extern rl_voidfunc_t *rl_deprep_term_function; + +/* Dispatch variables. */ +extern Keymap rl_executing_keymap; +extern Keymap rl_binding_keymap; + +extern int rl_executing_key; +extern char *rl_executing_keyseq; +extern int rl_key_sequence_length; + +/* Display variables. */ +/* If non-zero, readline will erase the entire line, including any prompt, + if the only thing typed on an otherwise-blank line is something bound to + rl_newline. */ +extern int rl_erase_empty_line; + +/* If non-zero, the application has already printed the prompt (rl_prompt) + before calling readline, so readline should not output it the first time + redisplay is done. */ +extern int rl_already_prompted; + +/* A non-zero value means to read only this many characters rather than + up to a character bound to accept-line. */ +extern int rl_num_chars_to_read; + +/* The text of a currently-executing keyboard macro. */ +extern char *rl_executing_macro; + +/* Variables to control readline signal handling. */ +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +extern int rl_catch_signals; + +/* If non-zero, readline will install a signal handler for SIGWINCH + that also attempts to call any calling application's SIGWINCH signal + handler. Note that the terminal is not cleaned up before the + application's signal handler is called; use rl_cleanup_after_signal() + to do that. */ +extern int rl_catch_sigwinch; + +/* If non-zero, the readline SIGWINCH handler will modify LINES and + COLUMNS in the environment. */ +extern int rl_change_environment; + +/* Completion variables. */ +/* Pointer to the generator function for completion_matches (). + NULL means to use rl_filename_completion_function (), the default + filename completer. */ +extern rl_compentry_func_t *rl_completion_entry_function; + +/* Optional generator for menu completion. Default is + rl_completion_entry_function (rl_filename_completion_function). */ +extern rl_compentry_func_t *rl_menu_completion_entry_function; + +/* If rl_ignore_some_completions_function is non-NULL it is the address + of a function to call after all of the possible matches have been + generated, but before the actual completion is done to the input line. + The function is called with one argument; a NULL terminated array + of (char *). If your function removes any of the elements, they + must be free()'ed. */ +extern rl_compignore_func_t *rl_ignore_some_completions_function; + +/* Pointer to alternative function to create matches. + Function is called with TEXT, START, and END. + START and END are indices in RL_LINE_BUFFER saying what the boundaries + of TEXT are. + If this function exists and returns NULL then call the value of + rl_completion_entry_function to try to match, otherwise use the + array of strings returned. */ +extern rl_completion_func_t *rl_attempted_completion_function; + +/* The basic list of characters that signal a break between words for the + completer routine. The initial contents of this variable is what + breaks words in the shell, i.e. "n\"\\'`@$>". */ +extern const char *rl_basic_word_break_characters; + +/* The list of characters that signal a break between words for + rl_complete_internal. The default list is the contents of + rl_basic_word_break_characters. */ +extern /*const*/ char *rl_completer_word_break_characters; + +/* Hook function to allow an application to set the completion word + break characters before readline breaks up the line. Allows + position-dependent word break characters. */ +extern rl_cpvfunc_t *rl_completion_word_break_hook; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +extern const char *rl_completer_quote_characters; + +/* List of quote characters which cause a word break. */ +extern const char *rl_basic_quote_characters; + +/* List of characters that need to be quoted in filenames by the completer. */ +extern const char *rl_filename_quote_characters; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +extern const char *rl_special_prefixes; + +/* If non-zero, then this is the address of a function to call when + completing on a directory name. The function is called with + the address of a string (the current directory name) as an arg. It + changes what is displayed when the possible completions are printed + or inserted. The directory completion hook should perform + any necessary dequoting. This function should return 1 if it modifies + the directory name pointer passed as an argument. If the directory + completion hook returns 0, it should not modify the directory name + pointer passed as an argument. */ +extern rl_icppfunc_t *rl_directory_completion_hook; + +/* If non-zero, this is the address of a function to call when completing + a directory name. This function takes the address of the directory name + to be modified as an argument. Unlike rl_directory_completion_hook, it + only modifies the directory name used in opendir(2), not what is displayed + when the possible completions are printed or inserted. If set, it takes + precedence over rl_directory_completion_hook. The directory rewrite + hook should perform any necessary dequoting. This function has the same + return value properties as the directory_completion_hook. + + I'm not happy with how this works yet, so it's undocumented. I'm trying + it in bash to see how well it goes. */ +extern rl_icppfunc_t *rl_directory_rewrite_hook; + +/* If non-zero, this is the address of a function for the completer to call + before deciding which character to append to a completed name. It should + modify the directory name passed as an argument if appropriate, and return + non-zero if it modifies the name. This should not worry about dequoting + the filename; that has already happened by the time it gets here. */ +extern rl_icppfunc_t *rl_filename_stat_hook; + +/* If non-zero, this is the address of a function to call when reading + directory entries from the filesystem for completion and comparing + them to the partial word to be completed. The function should + either return its first argument (if no conversion takes place) or + newly-allocated memory. This can, for instance, convert filenames + between character sets for comparison against what's typed at the + keyboard. The returned value is what is added to the list of + matches. The second argument is the length of the filename to be + converted. */ +extern rl_dequote_func_t *rl_filename_rewrite_hook; + +/* Backwards compatibility with previous versions of readline. */ +#define rl_symbolic_link_hook rl_directory_completion_hook + +/* If non-zero, then this is the address of a function to call when + completing a word would normally display the list of possible matches. + This function is called instead of actually doing the display. + It takes three arguments: (char **matches, int num_matches, int max_length) + where MATCHES is the array of strings that matched, NUM_MATCHES is the + number of strings in that array, and MAX_LENGTH is the length of the + longest string in that array. */ +extern rl_compdisp_func_t *rl_completion_display_matches_hook; + +/* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ +extern int rl_filename_completion_desired; + +/* Non-zero means that the results of the matches are to be quoted using + double quotes (or an application-specific quoting mechanism) if the + filename contains any characters in rl_word_break_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ +extern int rl_filename_quoting_desired; + +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +extern rl_quote_func_t *rl_filename_quoting_function; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. */ +extern rl_dequote_func_t *rl_filename_dequoting_function; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +extern rl_linebuf_func_t *rl_char_is_quoted_p; + +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +extern int rl_attempted_completion_over; + +/* Set to a character describing the type of completion being attempted by + rl_complete_internal; available for use by application completion + functions. */ +extern int rl_completion_type; + +/* Set to the last key used to invoke one of the completion functions */ +extern int rl_completion_invoking_key; + +/* Up to this many items will be displayed in response to a + possible-completions call. After that, we ask the user if she + is sure she wants to see them all. The default value is 100. */ +extern int rl_completion_query_items; + +/* Character appended to completed words when at the end of the line. The + default is a space. Nothing is added if this is '\0'. */ +extern int rl_completion_append_character; + +/* If set to non-zero by an application completion function, + rl_completion_append_character will not be appended. */ +extern int rl_completion_suppress_append; + +/* Set to any quote character readline thinks it finds before any application + completion function is called. */ +extern int rl_completion_quote_character; + +/* Set to a non-zero value if readline found quoting anywhere in the word to + be completed; set before any application completion function is called. */ +extern int rl_completion_found_quote; + +/* If non-zero, the completion functions don't append any closing quote. + This is set to 0 by rl_complete_internal and may be changed by an + application-specific completion function. */ +extern int rl_completion_suppress_quote; + +/* If non-zero, readline will sort the completion matches. On by default. */ +extern int rl_sort_completion_matches; + +/* If non-zero, a slash will be appended to completed filenames that are + symbolic links to directory names, subject to the value of the + mark-directories variable (which is user-settable). This exists so + that application completion functions can override the user's preference + (set via the mark-symlinked-directories variable) if appropriate. + It's set to the value of _rl_complete_mark_symlink_dirs in + rl_complete_internal before any application-specific completion + function is called, so without that function doing anything, the user's + preferences are honored. */ +extern int rl_completion_mark_symlink_dirs; + +/* If non-zero, then disallow duplicates in the matches. */ +extern int rl_ignore_completion_duplicates; + +/* If this is non-zero, completion is (temporarily) inhibited, and the + completion character will be inserted as any other. */ +extern int rl_inhibit_completion; + +/* Applications can set this to non-zero to have readline's signal handlers + installed during the entire duration of reading a complete line, as in + readline-6.2. This should be used with care, because it can result in + readline receiving signals and not handling them until it's called again + via rl_callback_read_char, thereby stealing them from the application. + By default, signal handlers are only active while readline is active. */ +extern int rl_persistent_signal_handlers; + +/* Input error; can be returned by (*rl_getc_function) if readline is reading + a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */ +#define READERR (-2) + +/* Definitions available for use by readline clients. */ +#define RL_PROMPT_START_IGNORE '\001' +#define RL_PROMPT_END_IGNORE '\002' + +/* Possible values for do_replace argument to rl_filename_quoting_function, + called by rl_complete_internal. */ +#define NO_MATCH 0 +#define SINGLE_MATCH 1 +#define MULT_MATCH 2 + +/* Possible state values for rl_readline_state */ +#define RL_STATE_NONE 0x000000 /* no state; before first call */ + +#define RL_STATE_INITIALIZING 0x0000001 /* initializing */ +#define RL_STATE_INITIALIZED 0x0000002 /* initialization done */ +#define RL_STATE_TERMPREPPED 0x0000004 /* terminal is prepped */ +#define RL_STATE_READCMD 0x0000008 /* reading a command key */ +#define RL_STATE_METANEXT 0x0000010 /* reading input after ESC */ +#define RL_STATE_DISPATCHING 0x0000020 /* dispatching to a command */ +#define RL_STATE_MOREINPUT 0x0000040 /* reading more input in a command function */ +#define RL_STATE_ISEARCH 0x0000080 /* doing incremental search */ +#define RL_STATE_NSEARCH 0x0000100 /* doing non-inc search */ +#define RL_STATE_SEARCH 0x0000200 /* doing a history search */ +#define RL_STATE_NUMERICARG 0x0000400 /* reading numeric argument */ +#define RL_STATE_MACROINPUT 0x0000800 /* getting input from a macro */ +#define RL_STATE_MACRODEF 0x0001000 /* defining keyboard macro */ +#define RL_STATE_OVERWRITE 0x0002000 /* overwrite mode */ +#define RL_STATE_COMPLETING 0x0004000 /* doing completion */ +#define RL_STATE_SIGHANDLER 0x0008000 /* in readline sighandler */ +#define RL_STATE_UNDOING 0x0010000 /* doing an undo */ +#define RL_STATE_INPUTPENDING 0x0020000 /* rl_execute_next called */ +#define RL_STATE_TTYCSAVED 0x0040000 /* tty special chars saved */ +#define RL_STATE_CALLBACK 0x0080000 /* using the callback interface */ +#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */ +#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */ +#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */ +#define RL_STATE_CHARSEARCH 0x0800000 /* vi mode char search */ +#define RL_STATE_REDISPLAYING 0x1000000 /* updating terminal display */ + +#define RL_STATE_DONE 0x2000000 /* done; accepted line */ + +#define RL_SETSTATE(x) (rl_readline_state |= (x)) +#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) +#define RL_ISSTATE(x) (rl_readline_state & (x)) + +struct readline_state { + /* line state */ + int point; + int end; + int mark; + int buflen; + char *buffer; + UNDO_LIST *ul; + char *prompt; + + /* global state */ + int rlstate; + int done; + Keymap kmap; + + /* input state */ + rl_command_func_t *lastfunc; + int insmode; + int edmode; + char *kseq; + int kseqlen; + + int pendingin; + FILE *inf; + FILE *outf; + char *macro; + + /* signal state */ + int catchsigs; + int catchsigwinch; + + /* search state */ + + /* completion state */ + rl_compentry_func_t *entryfunc; + rl_compentry_func_t *menuentryfunc; + rl_compignore_func_t *ignorefunc; + rl_completion_func_t *attemptfunc; + char *wordbreakchars; + + /* options state */ + + /* hook state */ + + /* reserved for future expansion, so the struct size doesn't change */ + char reserved[64]; +}; + +extern int rl_save_state PARAMS((struct readline_state *)); +extern int rl_restore_state PARAMS((struct readline_state *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _READLINE_H_ */ diff --git a/utshell-0.5.0/lib/readline/rlconf.h b/utshell-0.5.0/lib/readline/rlconf.h new file mode 100644 index 00000000..b6d6a2f1 --- /dev/null +++ b/utshell-0.5.0/lib/readline/rlconf.h @@ -0,0 +1,79 @@ +/* rlconf.h -- readline configuration definitions */ + +/* Copyright (C) 1992-2015 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RLCONF_H_) +#define _RLCONF_H_ + +/* Define this if you want the vi-mode editing available. */ +#define VI_MODE + +/* Define this to get an indication of file type when listing completions. */ +#define VISIBLE_STATS + +/* Define this to get support for colors when listing completions and in + other places. */ +#define COLOR_SUPPORT + +/* This definition is needed by readline.c, rltty.c, and signals.c. */ +/* If on, then readline handles signals in a way that doesn't suck. */ +#define HANDLE_SIGNALS + +/* Ugly but working hack for binding prefix meta. */ +#define PREFIX_META_HACK + +/* The next-to-last-ditch effort file name for a user-specific init file. */ +#define DEFAULT_INPUTRC "~/.inputrc" + +/* The ultimate last-ditch filename for an init file -- system-wide. */ +#define SYS_INPUTRC "/etc/inputrc" + +/* If defined, expand tabs to spaces. */ +#define DISPLAY_TABS + +/* If defined, use the terminal escape sequence to move the cursor forward + over a character when updating the line rather than rewriting it. */ +/* #define HACK_TERMCAP_MOTION */ + +/* The string inserted by the `insert comment' command. */ +#define RL_COMMENT_BEGIN_DEFAULT "#" + +/* Define this if you want code that allows readline to be used in an + X `callback' style. */ +#define READLINE_CALLBACKS + +/* Define this if you want the cursor to indicate insert or overwrite mode. */ +/* #define CURSOR_MODE */ + +/* Define this if you want to enable code that talks to the Linux kernel + tty auditing system. */ +/* #define ENABLE_TTY_AUDIT_SUPPORT */ + +/* Defaults for the various editing mode indicators, inserted at the beginning + of the last (maybe only) line of the prompt if show-mode-in-prompt is on */ +#define RL_EMACS_MODESTR_DEFAULT "@" +#define RL_EMACS_MODESTR_DEFLEN 1 + +#define RL_VI_INS_MODESTR_DEFAULT "(ins)" +#define RL_VI_INS_MODESTR_DEFLEN 5 +#define RL_VI_CMD_MODESTR_DEFAULT "(cmd)" +#define RL_VI_CMD_MODESTR_DEFLEN 5 + +#endif /* _RLCONF_H_ */ diff --git a/utshell-0.5.0/lib/readline/rldefs.h b/utshell-0.5.0/lib/readline/rldefs.h new file mode 100644 index 00000000..dab1beba --- /dev/null +++ b/utshell-0.5.0/lib/readline/rldefs.h @@ -0,0 +1,166 @@ +/* rldefs.h -- an attempt to isolate some of the system-specific defines + for readline. This should be included after any files that define + system-specific constants like _POSIX_VERSION or USG. */ + +/* Copyright (C) 1987-2011 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RLDEFS_H_) +#define _RLDEFS_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include "rlstdc.h" + +#if defined (STRCOLL_BROKEN) +# undef HAVE_STRCOLL +#endif + +#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING) +# define TERMIOS_TTY_DRIVER +#else +# if defined (HAVE_TERMIO_H) +# define TERMIO_TTY_DRIVER +# else +# if !defined (__MINGW32__) +# define NEW_TTY_DRIVER +# else +# define NO_TTY_DRIVER +# endif +# endif +#endif + +/* Posix macro to check file in statbuf for directory-ness. + This requires that be included before this test. */ +#if defined (S_IFDIR) && !defined (S_ISDIR) +# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif + +/* Decide which flavor of the header file describing the C library + string functions to include and include it. */ + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#if defined (PREFER_STDARG) +# include +#else +# if defined (PREFER_VARARGS) +# include +# endif +#endif + +#if defined (HAVE_STRCASECMP) +#define _rl_stricmp strcasecmp +#define _rl_strnicmp strncasecmp +#else +extern int _rl_stricmp PARAMS((const char *, const char *)); +extern int _rl_strnicmp PARAMS((const char *, const char *, int)); +#endif + +#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE) +# define _rl_strpbrk(a,b) strpbrk((a),(b)) +#else +extern char *_rl_strpbrk PARAMS((const char *, const char *)); +#endif + +#if !defined (emacs_mode) +# define no_mode -1 +# define vi_mode 0 +# define emacs_mode 1 +#endif + +#if !defined (RL_IM_INSERT) +# define RL_IM_INSERT 1 +# define RL_IM_OVERWRITE 0 +# +# define RL_IM_DEFAULT RL_IM_INSERT +#endif + +/* If you cast map[key].function to type (Keymap) on a Cray, + the compiler takes the value of map[key].function and + divides it by 4 to convert between pointer types (pointers + to functions and pointers to structs are different sizes). + This is not what is wanted. */ +#if defined (CRAY) +# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function) +# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data)) +#else +# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function) +# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data) +#endif + +#ifndef savestring +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif + +/* Possible values for _rl_bell_preference. */ +#define NO_BELL 0 +#define AUDIBLE_BELL 1 +#define VISIBLE_BELL 2 + +/* Definitions used when searching the line for characters. */ +/* NOTE: it is necessary that opposite directions are inverses */ +#define FTO 1 /* forward to */ +#define BTO -1 /* backward to */ +#define FFIND 2 /* forward find */ +#define BFIND -2 /* backward find */ + +/* Possible values for the found_quote flags word used by the completion + functions. It says what kind of (shell-like) quoting we found anywhere + in the line. */ +#define RL_QF_SINGLE_QUOTE 0x01 +#define RL_QF_DOUBLE_QUOTE 0x02 +#define RL_QF_BACKSLASH 0x04 +#define RL_QF_OTHER_QUOTE 0x08 + +/* Default readline line buffer length. */ +#define DEFAULT_BUFFER_SIZE 256 + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((n) == 0) ? (1) \ + : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#if !defined (RL_STRLEN) +# define RL_STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0) +#endif + +#if !defined (FREE) +# define FREE(x) if (x) free (x) +#endif + +#if !defined (SWAP) +# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) +#endif + +/* CONFIGURATION SECTION */ +#include "rlconf.h" + +#endif /* !_RLDEFS_H_ */ diff --git a/utshell-0.5.0/lib/readline/rlmbutil.h b/utshell-0.5.0/lib/readline/rlmbutil.h new file mode 100644 index 00000000..4d3e9070 --- /dev/null +++ b/utshell-0.5.0/lib/readline/rlmbutil.h @@ -0,0 +1,213 @@ +/* rlmbutil.h -- utility functions for multibyte characters. */ + +/* Copyright (C) 2001-2015 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RL_MBUTIL_H_) +#define _RL_MBUTIL_H_ + +#include "rlstdc.h" + +/************************************************/ +/* check multibyte capability for I18N code */ +/************************************************/ + +/* For platforms which support the ISO C amendment 1 functionality we + support user defined character classes. */ + /* Solaris 2.5 has a bug: must be included before . */ +#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H) +# include +# include +# if defined (HAVE_ISWCTYPE) && \ + defined (HAVE_ISWLOWER) && \ + defined (HAVE_ISWUPPER) && \ + defined (HAVE_MBSRTOWCS) && \ + defined (HAVE_MBRTOWC) && \ + defined (HAVE_MBRLEN) && \ + defined (HAVE_TOWLOWER) && \ + defined (HAVE_TOWUPPER) && \ + defined (HAVE_WCHAR_T) && \ + defined (HAVE_WCWIDTH) + /* system is supposed to support XPG5 */ +# define HANDLE_MULTIBYTE 1 +# endif +#endif + +/* If we don't want multibyte chars even on a system that supports them, let + the configuring user turn multibyte support off. */ +#if defined (NO_MULTIBYTE_SUPPORT) +# undef HANDLE_MULTIBYTE +#endif + +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ +#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T) +# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0) +# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0) +# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0) +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +# define mbrlen(s, n, ps) (mbrlen) (s, n, 0) +# define mbstate_t int +#endif + +/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to + handle multibyte chars (some systems define MB_LEN_MAX as 1) */ +#ifdef HANDLE_MULTIBYTE +# include +# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16) +# undef MB_LEN_MAX +# endif +# if !defined (MB_LEN_MAX) +# define MB_LEN_MAX 16 +# endif +#endif + +/************************************************/ +/* end of multibyte capability checks for I18N */ +/************************************************/ + +/* + * Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar: + * + * MB_FIND_ANY find any multibyte character + * MB_FIND_NONZERO find a non-zero-width multibyte character + */ + +#define MB_FIND_ANY 0x00 +#define MB_FIND_NONZERO 0x01 + +extern int _rl_find_prev_mbchar PARAMS((char *, int, int)); +extern int _rl_find_next_mbchar PARAMS((char *, int, int, int)); + +#ifdef HANDLE_MULTIBYTE + +extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *)); +extern int _rl_get_char_len PARAMS((char *, mbstate_t *)); +extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *)); + +extern int _rl_read_mbchar PARAMS((char *, int)); +extern int _rl_read_mbstring PARAMS((int, char *, int)); + +extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); + +extern wchar_t _rl_char_value PARAMS((char *, int)); +extern int _rl_walphabetic PARAMS((wchar_t)); + +#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc)) +#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc)) + +#define MB_NEXTCHAR(b,s,c,f) \ + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \ + ? _rl_find_next_mbchar ((b), (s), (c), (f)) \ + : ((s) + (c))) +#define MB_PREVCHAR(b,s,f) \ + ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \ + ? _rl_find_prev_mbchar ((b), (s), (f)) \ + : ((s) - 1)) + +#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2) +#define MB_NULLWCH(x) ((x) == 0) + +/* Try and shortcut the printable ascii characters to cut down the number of + calls to a libc wcwidth() */ +static inline int +_rl_wcwidth (wc) + wchar_t wc; +{ + switch (wc) + { + case ' ': case '!': case '"': case '#': case '%': + case '&': case '\'': case '(': case ')': case '*': + case '+': case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': + case '?': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': + case 'Z': + case '[': case '\\': case ']': case '^': case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': + case 'z': case '{': case '|': case '}': case '~': + return 1; + default: + return wcwidth (wc); + } +} + +/* Unicode combining characters range from U+0300 to U+036F */ +#define UNICODE_COMBINING_CHAR(x) ((x) >= 768 && (x) <= 879) + +#if defined (WCWIDTH_BROKEN) +# define WCWIDTH(wc) ((_rl_utf8locale && UNICODE_COMBINING_CHAR(wc)) ? 0 : _rl_wcwidth(wc)) +#else +# define WCWIDTH(wc) _rl_wcwidth(wc) +#endif + +#if defined (WCWIDTH_BROKEN) +# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0 && iswcntrl(x) == 0) +#else +# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0) +#endif + +#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0) +#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0) +#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80) + +#else /* !HANDLE_MULTIBYTE */ + +#undef MB_LEN_MAX +#undef MB_CUR_MAX + +#define MB_LEN_MAX 1 +#define MB_CUR_MAX 1 + +#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1)) +#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2)) + +#define _rl_char_value(buf,ind) ((buf)[(ind)]) + +#define _rl_walphabetic(c) (rl_alphabetic (c)) + +#define _rl_to_wupper(c) (_rl_to_upper (c)) +#define _rl_to_wlower(c) (_rl_to_lower (c)) + +#define MB_NEXTCHAR(b,s,c,f) ((s) + (c)) +#define MB_PREVCHAR(b,s,f) ((s) - 1) + +#define MB_INVALIDCH(x) (0) +#define MB_NULLWCH(x) (0) + +#define UTF8_SINGLEBYTE(c) (1) + +#if !defined (HAVE_WCHAR_T) && !defined (wchar_t) +# define wchar_t int +#endif + +#endif /* !HANDLE_MULTIBYTE */ + +extern int rl_byte_oriented; + +#endif /* _RL_MBUTIL_H_ */ diff --git a/utshell-0.5.0/lib/readline/rlprivate.h b/utshell-0.5.0/lib/readline/rlprivate.h new file mode 100644 index 00000000..23ab2d8c --- /dev/null +++ b/utshell-0.5.0/lib/readline/rlprivate.h @@ -0,0 +1,605 @@ +/* rlprivate.h -- functions and variables global to the readline library, + but not intended for use by applications. */ + +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RL_PRIVATE_H_) +#define _RL_PRIVATE_H_ + +#include "rlconf.h" /* for VISIBLE_STATS */ +#include "rlstdc.h" +#include "posixjmp.h" /* defines procenv_t */ +#include "rlmbutil.h" /* for HANDLE_MULTIBYTE */ + +/************************************************************************* + * * + * Convenience definitions * + * * + *************************************************************************/ + +#define EMACS_MODE() (rl_editing_mode == emacs_mode) +#define VI_COMMAND_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap) +#define VI_INSERT_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_insertion_keymap) + +#define RL_CHECK_SIGNALS() \ + do { \ + if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \ + } while (0) + +#define RL_SIG_RECEIVED() (_rl_caught_signal != 0) +#define RL_SIGINT_RECEIVED() (_rl_caught_signal == SIGINT) +#define RL_SIGWINCH_RECEIVED() (_rl_caught_signal == SIGWINCH) + +#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) +#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) + +/************************************************************************* + * * + * Global structs undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ +/* search types */ +#define RL_SEARCH_ISEARCH 0x01 /* incremental search */ +#define RL_SEARCH_NSEARCH 0x02 /* non-incremental search */ +#define RL_SEARCH_CSEARCH 0x04 /* intra-line char search */ + +/* search flags */ +#define SF_REVERSE 0x01 +#define SF_FOUND 0x02 +#define SF_FAILED 0x04 +#define SF_CHGKMAP 0x08 +#define SF_PATTERN 0x10 +#define SF_NOCASE 0x20 /* unused so far */ + +typedef struct __rl_search_context +{ + int type; + int sflags; + + char *search_string; + int search_string_index; + int search_string_size; + + char **lines; + char *allocated_line; + int hlen; + int hindex; + + int save_point; + int save_mark; + int save_line; + int last_found_line; + char *prev_line_found; + + UNDO_LIST *save_undo_list; + + Keymap keymap; /* used when dispatching commands in search string */ + Keymap okeymap; /* original keymap */ + + int history_pos; + int direction; + + int prevc; + int lastc; +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; + char pmb[MB_LEN_MAX]; +#endif + + char *sline; + int sline_len; + int sline_index; + + char *search_terminators; +} _rl_search_cxt; + +struct _rl_cmd { + Keymap map; + int count; + int key; + rl_command_func_t *func; +}; +extern struct _rl_cmd _rl_pending_command; +extern struct _rl_cmd *_rl_command_to_execute; + +/* Callback data for reading numeric arguments */ +#define NUM_SAWMINUS 0x01 +#define NUM_SAWDIGITS 0x02 +#define NUM_READONE 0x04 + +typedef int _rl_arg_cxt; + +/* A context for reading key sequences longer than a single character when + using the callback interface. */ +#define KSEQ_DISPATCHED 0x01 +#define KSEQ_SUBSEQ 0x02 +#define KSEQ_RECURSIVE 0x04 + +typedef struct __rl_keyseq_context +{ + int flags; + int subseq_arg; + int subseq_retval; /* XXX */ + int okey; + + Keymap dmap; + Keymap oldmap; + + struct __rl_keyseq_context *ocxt; + int childval; +} _rl_keyseq_cxt; + +/* vi-mode commands that use result of motion command to define boundaries */ +#define VIM_DELETE 0x01 +#define VIM_CHANGE 0x02 +#define VIM_YANK 0x04 + +/* various states for vi-mode commands that use motion commands. reflects + RL_READLINE_STATE */ +#define VMSTATE_READ 0x01 +#define VMSTATE_NUMARG 0x02 + +typedef struct __rl_vimotion_context +{ + int op; + int state; + int flags; /* reserved */ + _rl_arg_cxt ncxt; + int numeric_arg; + int start, end; /* rl_point, rl_end */ + int key, motion; /* initial key, motion command */ +} _rl_vimotion_cxt; + +/* fill in more as needed */ +/* `Generic' callback data and functions */ +typedef struct __rl_callback_generic_arg +{ + int count; + int i1, i2; + /* add here as needed */ +} _rl_callback_generic_arg; + +typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *)); + +typedef void _rl_sigcleanup_func_t PARAMS((int, void *)); + +/************************************************************************* + * * + * Global functions undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ + +/************************************************************************* + * * + * Global variables undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ + +/* complete.c */ +extern int rl_complete_with_tilde_expansion; +#if defined (VISIBLE_STATS) +extern int rl_visible_stats; +#endif /* VISIBLE_STATS */ +#if defined (COLOR_SUPPORT) +extern int _rl_colored_stats; +extern int _rl_colored_completion_prefix; +#endif + +/* readline.c */ +extern int rl_line_buffer_len; +extern int rl_arg_sign; +extern int rl_visible_prompt_length; +extern int rl_byte_oriented; + +/* display.c */ +extern int rl_display_fixed; + +/* parens.c */ +extern int rl_blink_matching_paren; + +/************************************************************************* + * * + * Global functions and variables unused and undocumented * + * * + *************************************************************************/ + +/* kill.c */ +extern int rl_set_retained_kills PARAMS((int)); + +/* terminal.c */ +extern void _rl_set_screen_size PARAMS((int, int)); + +/* undo.c */ +extern int _rl_fix_last_undo_of_type PARAMS((int, int, int)); + +/* util.c */ +extern char *_rl_savestring PARAMS((const char *)); + +/************************************************************************* + * * + * Functions and variables private to the readline library * + * * + *************************************************************************/ + +/* NOTE: Functions and variables prefixed with `_rl_' are + pseudo-global: they are global so they can be shared + between files in the readline library, but are not intended + to be visible to readline callers. */ + +/************************************************************************* + * Undocumented private functions * + *************************************************************************/ + +#if defined(READLINE_CALLBACKS) + +/* readline.c */ +extern void readline_internal_setup PARAMS((void)); +extern char *readline_internal_teardown PARAMS((int)); +extern int readline_internal_char PARAMS((void)); + +extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void)); +extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *)); +extern void _rl_keyseq_chain_dispose PARAMS((void)); + +extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *)); + +/* callback.c */ +extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int)); +extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *)); + +#endif /* READLINE_CALLBACKS */ + +/* bind.c */ +extern char *_rl_untranslate_macro_value PARAMS((char *, int)); + +/* complete.c */ +extern void _rl_reset_completion_state PARAMS((void)); +extern char _rl_find_completion_word PARAMS((int *, int *)); +extern void _rl_free_match_list PARAMS((char **)); + +/* display.c */ +extern char *_rl_strip_prompt PARAMS((char *)); +extern void _rl_reset_prompt PARAMS((void)); +extern void _rl_move_vert PARAMS((int)); +extern void _rl_save_prompt PARAMS((void)); +extern void _rl_restore_prompt PARAMS((void)); +extern char *_rl_make_prompt_for_search PARAMS((int)); +extern void _rl_erase_at_end_of_line PARAMS((int)); +extern void _rl_clear_to_eol PARAMS((int)); +extern void _rl_clear_screen PARAMS((int)); +extern void _rl_update_final PARAMS((void)); +extern void _rl_optimize_redisplay PARAMS((void)); +extern void _rl_redisplay_after_sigwinch PARAMS((void)); +extern void _rl_clean_up_for_exit PARAMS((void)); +extern void _rl_erase_entire_line PARAMS((void)); +extern int _rl_current_display_line PARAMS((void)); +extern void _rl_refresh_line PARAMS((void)); + +/* input.c */ +extern int _rl_any_typein PARAMS((void)); +extern int _rl_input_available PARAMS((void)); +extern int _rl_nchars_available PARAMS((void)); +extern int _rl_input_queued PARAMS((int)); +extern void _rl_insert_typein PARAMS((int)); +extern int _rl_unget_char PARAMS((int)); +extern int _rl_pushed_input_available PARAMS((void)); + +/* isearch.c */ +extern _rl_search_cxt *_rl_scxt_alloc PARAMS((int, int)); +extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int)); + +extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int)); +extern int _rl_isearch_callback PARAMS((_rl_search_cxt *)); +extern int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); + +extern int _rl_search_getchar PARAMS((_rl_search_cxt *)); + +/* kill.c */ +#ifndef BRACKETED_PASTE_DEFAULT +# define BRACKETED_PASTE_DEFAULT 1 /* XXX - for now */ +#endif + +#define BRACK_PASTE_PREF "\033[200~" +#define BRACK_PASTE_SUFF "\033[201~" + +#define BRACK_PASTE_LAST '~' +#define BRACK_PASTE_SLEN 6 + +#define BRACK_PASTE_INIT "\033[?2004h" +#define BRACK_PASTE_FINI "\033[?2004l\r" + +extern int _rl_read_bracketed_paste_prefix PARAMS((int)); +extern char *_rl_bracketed_text PARAMS((size_t *)); +extern int _rl_bracketed_read_key PARAMS((void)); +extern int _rl_bracketed_read_mbstring PARAMS((char *, int)); + +/* macro.c */ +extern void _rl_with_macro_input PARAMS((char *)); +extern int _rl_peek_macro_key PARAMS((void)); +extern int _rl_next_macro_key PARAMS((void)); +extern int _rl_prev_macro_key PARAMS((void)); +extern void _rl_push_executing_macro PARAMS((void)); +extern void _rl_pop_executing_macro PARAMS((void)); +extern void _rl_add_macro_char PARAMS((int)); +extern void _rl_kill_kbd_macro PARAMS((void)); + +/* misc.c */ +extern int _rl_arg_overflow PARAMS((void)); +extern void _rl_arg_init PARAMS((void)); +extern int _rl_arg_getchar PARAMS((void)); +extern int _rl_arg_callback PARAMS((_rl_arg_cxt)); +extern void _rl_reset_argument PARAMS((void)); + +extern void _rl_start_using_history PARAMS((void)); +extern int _rl_free_saved_history_line PARAMS((void)); +extern void _rl_set_insert_mode PARAMS((int, int)); + +extern void _rl_revert_previous_lines PARAMS((void)); +extern void _rl_revert_all_lines PARAMS((void)); + +/* nls.c */ +extern char *_rl_init_locale PARAMS((void)); +extern int _rl_init_eightbit PARAMS((void)); + +/* parens.c */ +extern void _rl_enable_paren_matching PARAMS((int)); + +/* readline.c */ +extern void _rl_init_line_state PARAMS((void)); +extern void _rl_set_the_line PARAMS((void)); +extern int _rl_dispatch PARAMS((int, Keymap)); +extern int _rl_dispatch_subseq PARAMS((int, Keymap, int)); +extern void _rl_internal_char_cleanup PARAMS((void)); + +extern void _rl_init_executing_keyseq PARAMS((void)); +extern void _rl_term_executing_keyseq PARAMS((void)); +extern void _rl_end_executing_keyseq PARAMS((void)); +extern void _rl_add_executing_keyseq PARAMS((int)); + +/* rltty.c */ +extern int _rl_disable_tty_signals PARAMS((void)); +extern int _rl_restore_tty_signals PARAMS((void)); + +/* search.c */ +extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *)); +extern int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int)); + +/* signals.c */ +extern void _rl_signal_handler PARAMS((int)); + +extern void _rl_block_sigint PARAMS((void)); +extern void _rl_release_sigint PARAMS((void)); +extern void _rl_block_sigwinch PARAMS((void)); +extern void _rl_release_sigwinch PARAMS((void)); + +/* terminal.c */ +extern void _rl_get_screen_size PARAMS((int, int)); +extern void _rl_sigwinch_resize_terminal PARAMS((void)); +extern int _rl_init_terminal_io PARAMS((const char *)); +#ifdef _MINIX +extern void _rl_output_character_function PARAMS((int)); +#else +extern int _rl_output_character_function PARAMS((int)); +#endif +extern void _rl_cr PARAMS((void)); +extern void _rl_output_some_chars PARAMS((const char *, int)); +extern int _rl_backspace PARAMS((int)); +extern void _rl_enable_meta_key PARAMS((void)); +extern void _rl_disable_meta_key PARAMS((void)); +extern void _rl_control_keypad PARAMS((int)); +extern void _rl_set_cursor PARAMS((int, int)); +extern void _rl_standout_on PARAMS((void)); +extern void _rl_standout_off PARAMS((void)); + +/* text.c */ +extern void _rl_fix_point PARAMS((int)); +extern void _rl_fix_mark PARAMS((void)); +extern int _rl_replace_text PARAMS((const char *, int, int)); +extern int _rl_forward_char_internal PARAMS((int)); +extern int _rl_backward_char_internal PARAMS((int)); +extern int _rl_insert_char PARAMS((int, int)); +extern int _rl_overwrite_char PARAMS((int, int)); +extern int _rl_overwrite_rubout PARAMS((int, int)); +extern int _rl_rubout_char PARAMS((int, int)); +#if defined (HANDLE_MULTIBYTE) +extern int _rl_char_search_internal PARAMS((int, int, char *, int)); +#else +extern int _rl_char_search_internal PARAMS((int, int, int)); +#endif +extern int _rl_set_mark_at_pos PARAMS((int)); + +/* undo.c */ +extern UNDO_LIST *_rl_copy_undo_entry PARAMS((UNDO_LIST *)); +extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *)); +extern void _rl_free_undo_list PARAMS((UNDO_LIST *)); + +/* util.c */ +#if defined (USE_VARARGS) && defined (PREFER_STDARG) +extern void _rl_ttymsg (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +extern void _rl_errmsg (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +extern void _rl_trace (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#else +extern void _rl_ttymsg (); +extern void _rl_errmsg (); +extern void _rl_trace (); +#endif +extern void _rl_audit_tty PARAMS((char *)); + +extern int _rl_tropen PARAMS((void)); + +extern int _rl_abort_internal PARAMS((void)); +extern int _rl_null_function PARAMS((int, int)); +extern char *_rl_strindex PARAMS((const char *, const char *)); +extern int _rl_qsort_string_compare PARAMS((char **, char **)); +extern int (_rl_uppercase_p) PARAMS((int)); +extern int (_rl_lowercase_p) PARAMS((int)); +extern int (_rl_pure_alphabetic) PARAMS((int)); +extern int (_rl_digit_p) PARAMS((int)); +extern int (_rl_to_lower) PARAMS((int)); +extern int (_rl_to_upper) PARAMS((int)); +extern int (_rl_digit_value) PARAMS((int)); + +/* vi_mode.c */ +extern void _rl_vi_initialize_line PARAMS((void)); +extern void _rl_vi_reset_last PARAMS((void)); +extern void _rl_vi_set_last PARAMS((int, int, int)); +extern int _rl_vi_textmod_command PARAMS((int)); +extern int _rl_vi_motion_command PARAMS((int)); +extern void _rl_vi_done_inserting PARAMS((void)); +extern int _rl_vi_domove_callback PARAMS((_rl_vimotion_cxt *)); +extern int _rl_vi_domove_motion_cleanup PARAMS((int, _rl_vimotion_cxt *)); + +/************************************************************************* + * Undocumented private variables * + *************************************************************************/ + +/* bind.c */ +extern const char * const _rl_possible_control_prefixes[]; +extern const char * const _rl_possible_meta_prefixes[]; + +/* callback.c */ +extern _rl_callback_func_t *_rl_callback_func; +extern _rl_callback_generic_arg *_rl_callback_data; + +/* complete.c */ +extern int _rl_complete_show_all; +extern int _rl_complete_show_unmodified; +extern int _rl_complete_mark_directories; +extern int _rl_complete_mark_symlink_dirs; +extern int _rl_completion_prefix_display_length; +extern int _rl_completion_columns; +extern int _rl_print_completions_horizontally; +extern int _rl_completion_case_fold; +extern int _rl_completion_case_map; +extern int _rl_match_hidden_files; +extern int _rl_page_completions; +extern int _rl_skip_completed_text; +extern int _rl_menu_complete_prefix_first; + +/* display.c */ +extern int _rl_vis_botlin; +extern int _rl_last_c_pos; +extern int _rl_suppress_redisplay; +extern int _rl_want_redisplay; + +extern char *_rl_emacs_mode_str; +extern int _rl_emacs_modestr_len; +extern char *_rl_vi_ins_mode_str; +extern int _rl_vi_ins_modestr_len; +extern char *_rl_vi_cmd_mode_str; +extern int _rl_vi_cmd_modestr_len; + +/* isearch.c */ +extern char *_rl_isearch_terminators; + +extern _rl_search_cxt *_rl_iscxt; + +/* macro.c */ +extern char *_rl_executing_macro; + +/* misc.c */ +extern int _rl_history_preserve_point; +extern int _rl_history_saved_point; + +extern _rl_arg_cxt _rl_argcxt; + +/* nls.c */ +extern int _rl_utf8locale; + +/* readline.c */ +extern int _rl_echoing_p; +extern int _rl_horizontal_scroll_mode; +extern int _rl_mark_modified_lines; +extern int _rl_bell_preference; +extern int _rl_meta_flag; +extern int _rl_convert_meta_chars_to_ascii; +extern int _rl_output_meta_chars; +extern int _rl_bind_stty_chars; +extern int _rl_revert_all_at_newline; +extern int _rl_echo_control_chars; +extern int _rl_show_mode_in_prompt; +extern int _rl_enable_bracketed_paste; +extern int _rl_enable_active_region; +extern char *_rl_comment_begin; +extern unsigned char _rl_parsing_conditionalized_out; +extern Keymap _rl_keymap; +extern FILE *_rl_in_stream; +extern FILE *_rl_out_stream; +extern int _rl_last_command_was_kill; +extern int _rl_eof_char; +extern int _rl_eof_found; +extern procenv_t _rl_top_level; +extern _rl_keyseq_cxt *_rl_kscxt; +extern int _rl_keyseq_timeout; + +extern int _rl_executing_keyseq_size; + +extern rl_hook_func_t *_rl_internal_startup_hook; + +/* search.c */ +extern _rl_search_cxt *_rl_nscxt; + +/* signals.c */ +extern int volatile _rl_caught_signal; + +extern _rl_sigcleanup_func_t *_rl_sigcleanup; +extern void *_rl_sigcleanarg; + +extern int _rl_echoctl; + +extern int _rl_intr_char; +extern int _rl_quit_char; +extern int _rl_susp_char; + +/* terminal.c */ +extern int _rl_enable_keypad; +extern int _rl_enable_meta; +extern char *_rl_term_clreol; +extern char *_rl_term_clrpag; +extern char *_rl_term_clrscroll; +extern char *_rl_term_im; +extern char *_rl_term_ic; +extern char *_rl_term_ei; +extern char *_rl_term_DC; +extern char *_rl_term_up; +extern char *_rl_term_dc; +extern char *_rl_term_cr; +extern char *_rl_term_IC; +extern char *_rl_term_forward_char; +extern int _rl_screenheight; +extern int _rl_screenwidth; +extern int _rl_screenchars; +extern int _rl_terminal_can_insert; +extern int _rl_term_autowrap; + +/* text.c */ +extern int _rl_optimize_typeahead; +extern int _rl_keep_mark_active; + +/* undo.c */ +extern int _rl_doing_an_undo; +extern int _rl_undo_group_level; + +/* vi_mode.c */ +extern int _rl_vi_last_command; +extern int _rl_vi_redoing; +extern _rl_vimotion_cxt *_rl_vimvcxt; + +#endif /* _RL_PRIVATE_H_ */ diff --git a/utshell-0.5.0/lib/readline/rlshell.h b/utshell-0.5.0/lib/readline/rlshell.h new file mode 100644 index 00000000..3e17d8bc --- /dev/null +++ b/utshell-0.5.0/lib/readline/rlshell.h @@ -0,0 +1,33 @@ +/* rlshell.h -- utility functions normally provided by bash. */ + +/* Copyright (C) 1999-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RL_SHELL_H_) +#define _RL_SHELL_H_ + +#include "rlstdc.h" + +extern char *sh_single_quote PARAMS((char *)); +extern void sh_set_lines_and_columns PARAMS((int, int)); +extern char *sh_get_env_value PARAMS((const char *)); +extern char *sh_get_home_dir PARAMS((void)); +extern int sh_unset_nodelay_mode PARAMS((int)); + +#endif /* _RL_SHELL_H_ */ diff --git a/utshell-0.5.0/lib/readline/rlstdc.h b/utshell-0.5.0/lib/readline/rlstdc.h new file mode 100644 index 00000000..2aaa30ba --- /dev/null +++ b/utshell-0.5.0/lib/readline/rlstdc.h @@ -0,0 +1,57 @@ +/* stdc.h -- macros to make source compile on both ANSI C and K&R C compilers. */ + +/* Copyright (C) 1993-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RL_STDC_H_) +#define _RL_STDC_H_ + +/* Adapted from BSD /usr/include/sys/cdefs.h. */ + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(x) +# endif +#endif + +/* Moved from config.h.in because readline.h:rl_message depends on these + defines. */ +#if defined (__STDC__) && defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +#else +# if defined (HAVE_VARARGS_H) +# define PREFER_VARARGS +# define USE_VARARGS +# endif +#endif + +#endif /* !_RL_STDC_H_ */ diff --git a/utshell-0.5.0/lib/readline/rltty.c b/utshell-0.5.0/lib/readline/rltty.c new file mode 100644 index 00000000..d0cd5727 --- /dev/null +++ b/utshell-0.5.0/lib/readline/rltty.c @@ -0,0 +1,991 @@ +/* rltty.c -- functions to prepare and restore the terminal for readline's + use. */ + +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include "rldefs.h" + +#include "rltty.h" +#if defined (HAVE_SYS_IOCTL_H) +# include /* include for declaration of ioctl */ +#endif + +#include "readline.h" +#include "rlprivate.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal; +rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal; + +static void set_winsize PARAMS((int)); + +/* **************************************************************** */ +/* */ +/* Saving and Restoring the TTY */ +/* */ +/* **************************************************************** */ + +/* Non-zero means that the terminal is in a prepped state. There are several + flags that are OR'd in to denote whether or not we have sent various + init strings to the terminal. */ +#define TPX_PREPPED 0x01 +#define TPX_BRACKPASTE 0x02 +#define TPX_METAKEY 0x04 + +static int terminal_prepped; + +static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars; + +/* If non-zero, means that this process has called tcflow(fd, TCOOFF) + and output is suspended. */ +#if defined (__ksr1__) +static int ksrflow; +#endif + +/* Dummy call to force a backgrounded readline to stop before it tries + to get the tty settings. */ +static void +set_winsize (tty) + int tty; +{ +#if defined (TIOCGWINSZ) + struct winsize w; + + if (ioctl (tty, TIOCGWINSZ, &w) == 0) + (void) ioctl (tty, TIOCSWINSZ, &w); +#endif /* TIOCGWINSZ */ +} + +#if defined (NO_TTY_DRIVER) +/* Nothing */ +#elif defined (NEW_TTY_DRIVER) + +/* Values for the `flags' field of a struct bsdtty. This tells which + elements of the struct bsdtty have been fetched from the system and + are valid. */ +#define SGTTY_SET 0x01 +#define LFLAG_SET 0x02 +#define TCHARS_SET 0x04 +#define LTCHARS_SET 0x08 + +struct bsdtty { + struct sgttyb sgttyb; /* Basic BSD tty driver information. */ + int lflag; /* Local mode flags, like LPASS8. */ +#if defined (TIOCGETC) + struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */ +#endif +#if defined (TIOCGLTC) + struct ltchars ltchars; /* 4.2 BSD editing characters */ +#endif + int flags; /* Bitmap saying which parts of the struct are valid. */ +}; + +#define TIOTYPE struct bsdtty + +static TIOTYPE otio; + +static void save_tty_chars PARAMS((TIOTYPE *)); +static int _get_tty_settings PARAMS((int, TIOTYPE *)); +static int get_tty_settings PARAMS((int, TIOTYPE *)); +static int _set_tty_settings PARAMS((int, TIOTYPE *)); +static int set_tty_settings PARAMS((int, TIOTYPE *)); + +static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); + +static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *)); + +static void +save_tty_chars (TIOTYPE *tiop) +{ + _rl_last_tty_chars = _rl_tty_chars; + + if (tiop->flags & SGTTY_SET) + { + _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase; + _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill; + } + + if (tiop->flags & TCHARS_SET) + { + _rl_intr_char = _rl_tty_chars.t_intr = tiop->tchars.t_intrc; + _rl_quit_char = _rl_tty_chars.t_quit = tiop->tchars.t_quitc; + + _rl_tty_chars.t_start = tiop->tchars.t_startc; + _rl_tty_chars.t_stop = tiop->tchars.t_stopc; + _rl_tty_chars.t_eof = tiop->tchars.t_eofc; + _rl_tty_chars.t_eol = '\n'; + _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc; + } + + if (tiop->flags & LTCHARS_SET) + { + _rl_susp_char = _rl_tty_chars.t_susp = tiop->ltchars.t_suspc; + + _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc; + _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc; + _rl_tty_chars.t_flush = tiop->ltchars.t_flushc; + _rl_tty_chars.t_werase = tiop->ltchars.t_werasc; + _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc; + } + + _rl_tty_chars.t_status = -1; +} + +static int +get_tty_settings (int tty, TIOTYPE *tiop) +{ + set_winsize (tty); + + tiop->flags = tiop->lflag = 0; + + errno = 0; + if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0) + return -1; + tiop->flags |= SGTTY_SET; + +#if defined (TIOCLGET) + if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0) + tiop->flags |= LFLAG_SET; +#endif + +#if defined (TIOCGETC) + if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0) + tiop->flags |= TCHARS_SET; +#endif + +#if defined (TIOCGLTC) + if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0) + tiop->flags |= LTCHARS_SET; +#endif + + return 0; +} + +static int +set_tty_settings (int tty, TIOTYPE *tiop) +{ + if (tiop->flags & SGTTY_SET) + { + ioctl (tty, TIOCSETN, &(tiop->sgttyb)); + tiop->flags &= ~SGTTY_SET; + } + _rl_echoing_p = 1; + +#if defined (TIOCLSET) + if (tiop->flags & LFLAG_SET) + { + ioctl (tty, TIOCLSET, &(tiop->lflag)); + tiop->flags &= ~LFLAG_SET; + } +#endif + +#if defined (TIOCSETC) + if (tiop->flags & TCHARS_SET) + { + ioctl (tty, TIOCSETC, &(tiop->tchars)); + tiop->flags &= ~TCHARS_SET; + } +#endif + +#if defined (TIOCSLTC) + if (tiop->flags & LTCHARS_SET) + { + ioctl (tty, TIOCSLTC, &(tiop->ltchars)); + tiop->flags &= ~LTCHARS_SET; + } +#endif + + return 0; +} + +static void +prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop) +{ + _rl_echoing_p = (oldtio.sgttyb.sg_flags & ECHO); + _rl_echoctl = (oldtio.sgttyb.sg_flags & ECHOCTL); + + /* Copy the original settings to the structure we're going to use for + our settings. */ + tiop->sgttyb = oldtio.sgttyb; + tiop->lflag = oldtio.lflag; +#if defined (TIOCGETC) + tiop->tchars = oldtio.tchars; +#endif +#if defined (TIOCGLTC) + tiop->ltchars = oldtio.ltchars; +#endif + tiop->flags = oldtio.flags; + + /* First, the basic settings to put us into character-at-a-time, no-echo + input mode. */ + tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD); + tiop->sgttyb.sg_flags |= CBREAK; + + /* If this terminal doesn't care how the 8th bit is used, then we can + use it for the meta-key. If only one of even or odd parity is + specified, then the terminal is using parity, and we cannot. */ +#if !defined (ANYP) +# define ANYP (EVENP | ODDP) +#endif + if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) || + ((oldtio.sgttyb.sg_flags & ANYP) == 0)) + { + tiop->sgttyb.sg_flags |= ANYP; + + /* Hack on local mode flags if we can. */ +#if defined (TIOCLGET) +# if defined (LPASS8) + tiop->lflag |= LPASS8; +# endif /* LPASS8 */ +#endif /* TIOCLGET */ + } + +#if defined (TIOCGETC) +# if defined (USE_XON_XOFF) + /* Get rid of terminal output start and stop characters. */ + tiop->tchars.t_stopc = -1; /* C-s */ + tiop->tchars.t_startc = -1; /* C-q */ + + /* If there is an XON character, bind it to restart the output. */ + if (oldtio.tchars.t_startc != -1) + rl_bind_key (oldtio.tchars.t_startc, rl_restart_output); +# endif /* USE_XON_XOFF */ + + /* If there is an EOF char, bind _rl_eof_char to it. */ + if (oldtio.tchars.t_eofc != -1) + _rl_eof_char = oldtio.tchars.t_eofc; + +# if defined (NO_KILL_INTR) + /* Get rid of terminal-generated SIGQUIT and SIGINT. */ + tiop->tchars.t_quitc = -1; /* C-\ */ + tiop->tchars.t_intrc = -1; /* C-c */ +# endif /* NO_KILL_INTR */ +#endif /* TIOCGETC */ + +#if defined (TIOCGLTC) + /* Make the interrupt keys go away. Just enough to make people happy. */ + tiop->ltchars.t_dsuspc = -1; /* C-y */ + tiop->ltchars.t_lnextc = -1; /* C-v */ +#endif /* TIOCGLTC */ +} + +#else /* !defined (NEW_TTY_DRIVER) */ + +#if !defined (VMIN) +# define VMIN VEOF +#endif + +#if !defined (VTIME) +# define VTIME VEOL +#endif + +#if defined (TERMIOS_TTY_DRIVER) +# define TIOTYPE struct termios +# define DRAIN_OUTPUT(fd) tcdrain (fd) +# define GETATTR(tty, tiop) (tcgetattr (tty, tiop)) +# ifdef M_UNIX +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) +# else +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop)) +# endif /* !M_UNIX */ +#else +# define TIOTYPE struct termio +# define DRAIN_OUTPUT(fd) +# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop)) +# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop)) +#endif /* !TERMIOS_TTY_DRIVER */ + +static TIOTYPE otio; + +static void save_tty_chars PARAMS((TIOTYPE *)); +static int _get_tty_settings PARAMS((int, TIOTYPE *)); +static int get_tty_settings PARAMS((int, TIOTYPE *)); +static int _set_tty_settings PARAMS((int, TIOTYPE *)); +static int set_tty_settings PARAMS((int, TIOTYPE *)); + +static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); + +static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *)); +static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE)); + +#if defined (FLUSHO) +# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) +#else +# define OUTPUT_BEING_FLUSHED(tp) 0 +#endif + +static void +save_tty_chars (TIOTYPE *tiop) +{ + _rl_last_tty_chars = _rl_tty_chars; + + _rl_tty_chars.t_eof = tiop->c_cc[VEOF]; + _rl_tty_chars.t_eol = tiop->c_cc[VEOL]; +#ifdef VEOL2 + _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2]; +#endif + _rl_tty_chars.t_erase = tiop->c_cc[VERASE]; +#ifdef VWERASE + _rl_tty_chars.t_werase = tiop->c_cc[VWERASE]; +#endif + _rl_tty_chars.t_kill = tiop->c_cc[VKILL]; +#ifdef VREPRINT + _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT]; +#endif + _rl_intr_char = _rl_tty_chars.t_intr = tiop->c_cc[VINTR]; + _rl_quit_char = _rl_tty_chars.t_quit = tiop->c_cc[VQUIT]; +#ifdef VSUSP + _rl_susp_char = _rl_tty_chars.t_susp = tiop->c_cc[VSUSP]; +#endif +#ifdef VDSUSP + _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP]; +#endif +#ifdef VSTART + _rl_tty_chars.t_start = tiop->c_cc[VSTART]; +#endif +#ifdef VSTOP + _rl_tty_chars.t_stop = tiop->c_cc[VSTOP]; +#endif +#ifdef VLNEXT + _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT]; +#endif +#ifdef VDISCARD + _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD]; +#endif +#ifdef VSTATUS + _rl_tty_chars.t_status = tiop->c_cc[VSTATUS]; +#endif +} + +#if defined (_AIX) || defined (_AIX41) +/* Currently this is only used on AIX */ +static void +rltty_warning (char *msg) +{ + _rl_errmsg ("warning: %s", msg); +} +#endif + +#if defined (_AIX) +void +setopost (TIOTYPE *tp) +{ + if ((tp->c_oflag & OPOST) == 0) + { + _rl_errmsg ("warning: turning on OPOST for terminal\r"); + tp->c_oflag |= OPOST|ONLCR; + } +} +#endif + +static int +_get_tty_settings (int tty, TIOTYPE *tiop) +{ + int ioctl_ret; + + while (1) + { + ioctl_ret = GETATTR (tty, tiop); + if (ioctl_ret < 0) + { + if (errno != EINTR) + return -1; + else + continue; + } + if (OUTPUT_BEING_FLUSHED (tiop)) + { +#if defined (FLUSHO) + _rl_errmsg ("warning: turning off output flushing"); + tiop->c_lflag &= ~FLUSHO; + break; +#else + continue; +#endif + } + break; + } + + return 0; +} + +static int +get_tty_settings (int tty, TIOTYPE *tiop) +{ + set_winsize (tty); + + errno = 0; + if (_get_tty_settings (tty, tiop) < 0) + return -1; + +#if defined (_AIX) + setopost(tiop); +#endif + + return 0; +} + +static int +_set_tty_settings (int tty, TIOTYPE *tiop) +{ + while (SETATTR (tty, tiop) < 0) + { + if (errno != EINTR) + return -1; + errno = 0; + } + return 0; +} + +static int +set_tty_settings (int tty, TIOTYPE *tiop) +{ + if (_set_tty_settings (tty, tiop) < 0) + return -1; + +#if 0 + +#if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + if (ksrflow) + { + ksrflow = 0; + tcflow (tty, TCOON); + } +# else /* !ksr1 */ + tcflow (tty, TCOON); /* Simulate a ^Q. */ +# endif /* !ksr1 */ +#else + ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */ +#endif /* !TERMIOS_TTY_DRIVER */ + +#endif /* 0 */ + + return 0; +} + +static void +prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop) +{ + int sc; + Keymap kmap; + + _rl_echoing_p = (oldtio.c_lflag & ECHO); +#if defined (ECHOCTL) + _rl_echoctl = (oldtio.c_lflag & ECHOCTL); +#endif + + tiop->c_lflag &= ~(ICANON | ECHO); + + if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE) + _rl_eof_char = oldtio.c_cc[VEOF]; + +#if defined (USE_XON_XOFF) +#if defined (IXANY) + tiop->c_iflag &= ~(IXON | IXANY); +#else + /* `strict' Posix systems do not define IXANY. */ + tiop->c_iflag &= ~IXON; +#endif /* IXANY */ +#endif /* USE_XON_XOFF */ + + /* Only turn this off if we are using all 8 bits. */ + if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag) + tiop->c_iflag &= ~(ISTRIP | INPCK); + + /* Make sure we differentiate between CR and NL on input. */ + tiop->c_iflag &= ~(ICRNL | INLCR); + +#if !defined (HANDLE_SIGNALS) + tiop->c_lflag &= ~ISIG; +#else + tiop->c_lflag |= ISIG; +#endif + + tiop->c_cc[VMIN] = 1; + tiop->c_cc[VTIME] = 0; + +#if defined (FLUSHO) + if (OUTPUT_BEING_FLUSHED (tiop)) + { + tiop->c_lflag &= ~FLUSHO; + oldtio.c_lflag &= ~FLUSHO; + } +#endif + + /* Turn off characters that we need on Posix systems with job control, + just to be sure. This includes ^Y and ^V. This should not really + be necessary. */ +#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE) + +#if defined (VLNEXT) + tiop->c_cc[VLNEXT] = _POSIX_VDISABLE; +#endif + +#if defined (VDSUSP) + tiop->c_cc[VDSUSP] = _POSIX_VDISABLE; +#endif + + /* Conditionally disable some other tty special characters if there is a + key binding for them in the current keymap. Readline ordinarily doesn't + bind these characters, but an application or user might. */ +#if defined (VI_MODE) + kmap = (rl_editing_mode == vi_mode) ? vi_insertion_keymap : _rl_keymap; +#else + kmap = _rl_keymap; +#endif +#if defined (VDISCARD) + sc = tiop->c_cc[VDISCARD]; + if (sc != _POSIX_VDISABLE && kmap[(unsigned char)sc].type == ISFUNC) + tiop->c_cc[VDISCARD] = _POSIX_VDISABLE; +#endif /* VDISCARD */ + +#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ +} +#endif /* !NEW_TTY_DRIVER */ + +/* Put the terminal in CBREAK mode so that we can detect key presses. */ +#if defined (NO_TTY_DRIVER) +void +rl_prep_terminal (int meta_flag) +{ + _rl_echoing_p = 1; +} + +void +rl_deprep_terminal (void) +{ +} + +#else /* ! NO_TTY_DRIVER */ +void +rl_prep_terminal (int meta_flag) +{ + int tty, nprep; + TIOTYPE tio; + + if (terminal_prepped) + return; + + /* Try to keep this function from being INTerrupted. */ + _rl_block_sigint (); + + tty = rl_instream ? fileno (rl_instream) : fileno (stdin); + + if (get_tty_settings (tty, &tio) < 0) + { +#if defined (ENOTSUP) + /* MacOS X and Linux, at least, lie about the value of errno if + tcgetattr fails. */ + if (errno == ENOTTY || errno == EINVAL || errno == ENOTSUP) +#else + if (errno == ENOTTY || errno == EINVAL) +#endif + _rl_echoing_p = 1; /* XXX */ + + _rl_release_sigint (); + return; + } + + otio = tio; + + if (_rl_bind_stty_chars) + { +#if defined (VI_MODE) + /* If editing in vi mode, make sure we restore the bindings in the + insertion keymap no matter what keymap we ended up in. */ + if (rl_editing_mode == vi_mode) + rl_tty_unset_default_bindings (vi_insertion_keymap); + else +#endif + rl_tty_unset_default_bindings (_rl_keymap); + } + save_tty_chars (&otio); + RL_SETSTATE(RL_STATE_TTYCSAVED); + if (_rl_bind_stty_chars) + { +#if defined (VI_MODE) + /* If editing in vi mode, make sure we set the bindings in the + insertion keymap no matter what keymap we ended up in. */ + if (rl_editing_mode == vi_mode) + _rl_bind_tty_special_chars (vi_insertion_keymap, tio); + else +#endif + _rl_bind_tty_special_chars (_rl_keymap, tio); + } + + prepare_terminal_settings (meta_flag, otio, &tio); + + if (set_tty_settings (tty, &tio) < 0) + { + _rl_release_sigint (); + return; + } + + if (_rl_enable_keypad) + _rl_control_keypad (1); + + nprep = TPX_PREPPED; + + if (_rl_enable_bracketed_paste) + { + fprintf (rl_outstream, BRACK_PASTE_INIT); + nprep |= TPX_BRACKPASTE; + } + + fflush (rl_outstream); + terminal_prepped = nprep; + RL_SETSTATE(RL_STATE_TERMPREPPED); + + _rl_release_sigint (); +} + +/* Restore the terminal's normal settings and modes. */ +void +rl_deprep_terminal (void) +{ + int tty; + + if (terminal_prepped == 0) + return; + + /* Try to keep this function from being interrupted. */ + _rl_block_sigint (); + + tty = rl_instream ? fileno (rl_instream) : fileno (stdin); + + if (terminal_prepped & TPX_BRACKPASTE) + { + fprintf (rl_outstream, BRACK_PASTE_FINI); + if (_rl_eof_found) + fprintf (rl_outstream, "\n"); + } + + if (_rl_enable_keypad) + _rl_control_keypad (0); + + fflush (rl_outstream); + + if (set_tty_settings (tty, &otio) < 0) + { + _rl_release_sigint (); + return; + } + + terminal_prepped = 0; + RL_UNSETSTATE(RL_STATE_TERMPREPPED); + + _rl_release_sigint (); +} +#endif /* !NO_TTY_DRIVER */ + +/* Set readline's idea of whether or not it is echoing output to the terminal, + returning the old value. */ +int +rl_tty_set_echoing (int u) +{ + int o; + + o = _rl_echoing_p; + _rl_echoing_p = u; + return o; +} + +/* **************************************************************** */ +/* */ +/* Bogus Flow Control */ +/* */ +/* **************************************************************** */ + +int +rl_restart_output (int count, int key) +{ +#if defined (__MINGW32__) + return 0; +#else /* !__MING32__ */ + + int fildes = fileno (rl_outstream); +#if defined (TIOCSTART) +#if defined (apollo) + ioctl (&fildes, TIOCSTART, 0); +#else + ioctl (fildes, TIOCSTART, 0); +#endif /* apollo */ + +#else /* !TIOCSTART */ +# if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + if (ksrflow) + { + ksrflow = 0; + tcflow (fildes, TCOON); + } +# else /* !ksr1 */ + tcflow (fildes, TCOON); /* Simulate a ^Q. */ +# endif /* !ksr1 */ +# else /* !TERMIOS_TTY_DRIVER */ +# if defined (TCXONC) + ioctl (fildes, TCXONC, TCOON); +# endif /* TCXONC */ +# endif /* !TERMIOS_TTY_DRIVER */ +#endif /* !TIOCSTART */ + + return 0; +#endif /* !__MINGW32__ */ +} + +int +rl_stop_output (int count, int key) +{ +#if defined (__MINGW32__) + return 0; +#else + + int fildes = fileno (rl_instream); + +#if defined (TIOCSTOP) +# if defined (apollo) + ioctl (&fildes, TIOCSTOP, 0); +# else + ioctl (fildes, TIOCSTOP, 0); +# endif /* apollo */ +#else /* !TIOCSTOP */ +# if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + ksrflow = 1; +# endif /* ksr1 */ + tcflow (fildes, TCOOFF); +# else +# if defined (TCXONC) + ioctl (fildes, TCXONC, TCOON); +# endif /* TCXONC */ +# endif /* !TERMIOS_TTY_DRIVER */ +#endif /* !TIOCSTOP */ + + return 0; +#endif /* !__MINGW32__ */ +} + +/* **************************************************************** */ +/* */ +/* Default Key Bindings */ +/* */ +/* **************************************************************** */ + +#if !defined (NO_TTY_DRIVER) +#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func) +#endif + +#if defined (NO_TTY_DRIVER) + +#define SET_SPECIAL(sc, func) +#define RESET_SPECIAL(c) + +#elif defined (NEW_TTY_DRIVER) +static void +set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func) +{ + if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC) + kmap[(unsigned char)sc].function = func; +} + +#define RESET_SPECIAL(c) \ + if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) \ + kmap[(unsigned char)c].function = rl_insert; + +static void +_rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff) +{ + if (ttybuff.flags & SGTTY_SET) + { + SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout); + SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard); + } + +# if defined (TIOCGLTC) + if (ttybuff.flags & LTCHARS_SET) + { + SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout); + SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert); + } +# endif /* TIOCGLTC */ +} + +#else /* !NEW_TTY_DRIVER */ +static void +set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func) +{ + unsigned char uc; + + uc = tiop->c_cc[sc]; + if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) + kmap[uc].function = func; +} + +/* used later */ +#define RESET_SPECIAL(uc) \ + if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \ + kmap[uc].function = rl_insert; + +static void +_rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff) +{ + SET_SPECIAL (VERASE, rl_rubout); + SET_SPECIAL (VKILL, rl_unix_line_discard); + +# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) + SET_SPECIAL (VLNEXT, rl_quoted_insert); +# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ + +# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) +# if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + SET_SPECIAL (VWERASE, rl_vi_unix_word_rubout); + else +# endif + SET_SPECIAL (VWERASE, rl_unix_word_rubout); +# endif /* VWERASE && TERMIOS_TTY_DRIVER */ +} + +#endif /* !NEW_TTY_DRIVER */ + +/* Set the system's default editing characters to their readline equivalents + in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */ +void +rltty_set_default_bindings (Keymap kmap) +{ +#if !defined (NO_TTY_DRIVER) + TIOTYPE ttybuff; + int tty; + + tty = fileno (rl_instream); + + if (get_tty_settings (tty, &ttybuff) == 0) + _rl_bind_tty_special_chars (kmap, ttybuff); +#endif +} + +/* New public way to set the system default editing chars to their readline + equivalents. */ +void +rl_tty_set_default_bindings (Keymap kmap) +{ + rltty_set_default_bindings (kmap); +} + +/* Rebind all of the tty special chars that readline worries about back + to self-insert. Call this before saving the current terminal special + chars with save_tty_chars(). This only works on POSIX termios or termio + systems. */ +void +rl_tty_unset_default_bindings (Keymap kmap) +{ + /* Don't bother before we've saved the tty special chars at least once. */ + if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0) + return; + + RESET_SPECIAL (_rl_tty_chars.t_erase); + RESET_SPECIAL (_rl_tty_chars.t_kill); + +# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER) + RESET_SPECIAL (_rl_tty_chars.t_lnext); +# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ + +# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) + RESET_SPECIAL (_rl_tty_chars.t_werase); +# endif /* VWERASE && TERMIOS_TTY_DRIVER */ +} + +#if defined (HANDLE_SIGNALS) + +#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER) +int +_rl_disable_tty_signals (void) +{ + return 0; +} + +int +_rl_restore_tty_signals (void) +{ + return 0; +} +#else + +static TIOTYPE sigstty, nosigstty; +static int tty_sigs_disabled = 0; + +int +_rl_disable_tty_signals (void) +{ + if (tty_sigs_disabled) + return 0; + + if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0) + return -1; + + nosigstty = sigstty; + + nosigstty.c_lflag &= ~ISIG; + nosigstty.c_iflag &= ~IXON; + + if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0) + return (_set_tty_settings (fileno (rl_instream), &sigstty)); + + tty_sigs_disabled = 1; + return 0; +} + +int +_rl_restore_tty_signals (void) +{ + int r; + + if (tty_sigs_disabled == 0) + return 0; + + r = _set_tty_settings (fileno (rl_instream), &sigstty); + + if (r == 0) + tty_sigs_disabled = 0; + + return r; +} +#endif /* !NEW_TTY_DRIVER */ + +#endif /* HANDLE_SIGNALS */ diff --git a/utshell-0.5.0/lib/readline/rltty.h b/utshell-0.5.0/lib/readline/rltty.h new file mode 100644 index 00000000..5bcc946b --- /dev/null +++ b/utshell-0.5.0/lib/readline/rltty.h @@ -0,0 +1,80 @@ +/* rltty.h - tty driver-related definitions used by some library files. */ + +/* Copyright (C) 1995-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RLTTY_H_) +#define _RLTTY_H_ + +/* Posix systems use termios and the Posix signal functions. */ +#if defined (TERMIOS_TTY_DRIVER) +# include +#endif /* TERMIOS_TTY_DRIVER */ + +/* System V machines use termio. */ +#if defined (TERMIO_TTY_DRIVER) +# include +# if !defined (TCOON) +# define TCOON 1 +# endif +#endif /* TERMIO_TTY_DRIVER */ + +/* Other (BSD) machines use sgtty. */ +#if defined (NEW_TTY_DRIVER) +# include +#endif + +#include "rlwinsize.h" + +/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and + it is not already defined. It is used both to determine if a + special character is disabled and to disable certain special + characters. Posix systems should set to 0, USG systems to -1. */ +#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE) +# if defined (_SVR4_VDISABLE) +# define _POSIX_VDISABLE _SVR4_VDISABLE +# else +# if defined (_POSIX_VERSION) +# define _POSIX_VDISABLE 0 +# else /* !_POSIX_VERSION */ +# define _POSIX_VDISABLE -1 +# endif /* !_POSIX_VERSION */ +# endif /* !_SVR4_DISABLE */ +#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */ + +typedef struct _rl_tty_chars { + unsigned char t_eof; + unsigned char t_eol; + unsigned char t_eol2; + unsigned char t_erase; + unsigned char t_werase; + unsigned char t_kill; + unsigned char t_reprint; + unsigned char t_intr; + unsigned char t_quit; + unsigned char t_susp; + unsigned char t_dsusp; + unsigned char t_start; + unsigned char t_stop; + unsigned char t_lnext; + unsigned char t_flush; + unsigned char t_status; +} _RL_TTY_CHARS; + +#endif /* _RLTTY_H_ */ diff --git a/utshell-0.5.0/lib/readline/rltypedefs.h b/utshell-0.5.0/lib/readline/rltypedefs.h new file mode 100644 index 00000000..f9f5cd3a --- /dev/null +++ b/utshell-0.5.0/lib/readline/rltypedefs.h @@ -0,0 +1,100 @@ +/* rltypedefs.h -- Type declarations for readline functions. */ + +/* Copyright (C) 2000-2011 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#ifndef _RL_TYPEDEFS_H_ +#define _RL_TYPEDEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Old-style, attempt to mark as deprecated in some way people will notice. */ + +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF + +#if defined(__GNUC__) || defined(__clang__) +typedef int Function () __attribute__ ((deprecated)); +typedef void VFunction () __attribute__ ((deprecated)); +typedef char *CPFunction () __attribute__ ((deprecated)); +typedef char **CPPFunction () __attribute__ ((deprecated)); +#else +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); +typedef char **CPPFunction (); +#endif + +#endif /* _FUNCTION_DEF */ + +/* New style. */ + +#if !defined (_RL_FUNCTION_TYPEDEF) +# define _RL_FUNCTION_TYPEDEF + +/* Bindable functions */ +typedef int rl_command_func_t PARAMS((int, int)); + +/* Typedefs for the completion system */ +typedef char *rl_compentry_func_t PARAMS((const char *, int)); +typedef char **rl_completion_func_t PARAMS((const char *, int, int)); + +typedef char *rl_quote_func_t PARAMS((char *, int, char *)); +typedef char *rl_dequote_func_t PARAMS((char *, int)); + +typedef int rl_compignore_func_t PARAMS((char **)); + +typedef void rl_compdisp_func_t PARAMS((char **, int, int)); + +/* Type for input and pre-read hook functions like rl_event_hook */ +typedef int rl_hook_func_t PARAMS((void)); + +/* Input function type */ +typedef int rl_getc_func_t PARAMS((FILE *)); + +/* Generic function that takes a character buffer (which could be the readline + line buffer) and an index into it (which could be rl_point) and returns + an int. */ +typedef int rl_linebuf_func_t PARAMS((char *, int)); + +/* `Generic' function pointer typedefs */ +typedef int rl_intfunc_t PARAMS((int)); +#define rl_ivoidfunc_t rl_hook_func_t +typedef int rl_icpfunc_t PARAMS((char *)); +typedef int rl_icppfunc_t PARAMS((char **)); + +typedef void rl_voidfunc_t PARAMS((void)); +typedef void rl_vintfunc_t PARAMS((int)); +typedef void rl_vcpfunc_t PARAMS((char *)); +typedef void rl_vcppfunc_t PARAMS((char **)); + +typedef char *rl_cpvfunc_t PARAMS((void)); +typedef char *rl_cpifunc_t PARAMS((int)); +typedef char *rl_cpcpfunc_t PARAMS((char *)); +typedef char *rl_cpcppfunc_t PARAMS((char **)); + +#endif /* _RL_FUNCTION_TYPEDEF */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RL_TYPEDEFS_H_ */ diff --git a/utshell-0.5.0/lib/readline/rlwinsize.h b/utshell-0.5.0/lib/readline/rlwinsize.h new file mode 100644 index 00000000..d198fcf8 --- /dev/null +++ b/utshell-0.5.0/lib/readline/rlwinsize.h @@ -0,0 +1,58 @@ +/* rlwinsize.h -- an attempt to isolate some of the system-specific defines + for `struct winsize' and TIOCGWINSZ. */ + +/* Copyright (C) 1997-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RLWINSIZE_H_) +#define _RLWINSIZE_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */ + +#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) +# include +#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ + +#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# include +#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +/* Not in either of the standard places, look around. */ +#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# if defined (HAVE_SYS_STREAM_H) +# include +# endif /* HAVE_SYS_STREAM_H */ +# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */ +# include +# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */ +# endif /* HAVE_SYS_PTEM_H */ +# if defined (HAVE_SYS_PTE_H) /* ??? */ +# include +# endif /* HAVE_SYS_PTE_H */ +#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +#if defined (M_UNIX) && !defined (_SCO_DS) && !defined (tcflow) +# define tcflow(fd, action) ioctl(fd, TCXONC, action) +#endif + +#endif /* _RL_WINSIZE_H */ diff --git a/utshell-0.5.0/lib/readline/savestring.c b/utshell-0.5.0/lib/readline/savestring.c new file mode 100644 index 00000000..f4bb6aa1 --- /dev/null +++ b/utshell-0.5.0/lib/readline/savestring.c @@ -0,0 +1,40 @@ +/* savestring.c - function version of savestring for backwards compatibility */ + +/* Copyright (C) 1998,2003,2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#include +#ifdef HAVE_STRING_H +# include +#endif +#include "xmalloc.h" + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +char * +savestring (const char *s) +{ + char *ret; + + ret = (char *)xmalloc (strlen (s) + 1); + strcpy (ret, s); + return ret; +} diff --git a/utshell-0.5.0/lib/readline/search.c b/utshell-0.5.0/lib/readline/search.c new file mode 100644 index 00000000..38a29361 --- /dev/null +++ b/utshell-0.5.0/lib/readline/search.c @@ -0,0 +1,695 @@ +/* search.c - code for non-incremental searching in emacs and vi modes. */ + +/* Copyright (C) 1992-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif + +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" +#include "histlib.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#ifdef abs +# undef abs +#endif +#define abs(x) (((x) >= 0) ? (x) : -(x)) + +_rl_search_cxt *_rl_nscxt = 0; + +extern HIST_ENTRY *_rl_saved_line_for_history; + +/* Functions imported from the rest of the library. */ +extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +static char *noninc_search_string = (char *) NULL; +static int noninc_history_pos; + +static char *prev_line_found = (char *) NULL; + +static int rl_history_search_len; +static int rl_history_search_pos; +static int rl_history_search_flags; + +static char *history_search_string; +static int history_string_size; + +static void make_history_line_current PARAMS((HIST_ENTRY *)); +static int noninc_search_from_pos PARAMS((char *, int, int, int, int *)); +static int noninc_dosearch PARAMS((char *, int, int)); +static int noninc_search PARAMS((int, int)); +static int rl_history_search_internal PARAMS((int, int)); +static void rl_history_search_reinit PARAMS((int)); + +static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int)); +static void _rl_nsearch_abort PARAMS((_rl_search_cxt *)); +static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int)); + +/* Make the data from the history entry ENTRY be the contents of the + current line. This doesn't do anything with rl_point; the caller + must set it. */ +static void +make_history_line_current (HIST_ENTRY *entry) +{ + _rl_replace_text (entry->line, 0, rl_end); + _rl_fix_point (1); +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + /* POSIX.2 says that the `U' command doesn't affect the copy of any + command lines to the edit line. We're going to implement that by + making the undo list start after the matching line is copied to the + current editing buffer. */ + rl_free_undo_list (); +#endif + + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; +} + +/* Search the history list for STRING starting at absolute history position + POS. If STRING begins with `^', the search must match STRING at the + beginning of a history line, otherwise a full substring match is performed + for STRING. DIR < 0 means to search backwards through the history list, + DIR >= 0 means to search forward. */ +static int +noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp) +{ + int ret, old, sflags; + char *s; + + if (pos < 0) + return -1; + + old = where_history (); + if (history_set_pos (pos) == 0) + return -1; + + RL_SETSTATE(RL_STATE_SEARCH); + /* These functions return the match offset in the line; history_offset gives + the matching line in the history list */ + if (flags & SF_PATTERN) + { + s = string; + sflags = 0; /* Non-anchored search */ + if (*s == '^') + { + sflags |= ANCHORED_SEARCH; + s++; + } + ret = _hs_history_patsearch (s, dir, sflags); + } + else if (*string == '^') + ret = history_search_prefix (string + 1, dir); + else + ret = history_search (string, dir); + RL_UNSETSTATE(RL_STATE_SEARCH); + + if (ncp) + *ncp = ret; /* caller will catch -1 to indicate no-op */ + + if (ret != -1) + ret = where_history (); + + history_set_pos (old); + return (ret); +} + +/* Search for a line in the history containing STRING. If DIR is < 0, the + search is backwards through previous entries, else through subsequent + entries. Returns 1 if the search was successful, 0 otherwise. */ +static int +noninc_dosearch (char *string, int dir, int flags) +{ + int oldpos, pos, ind; + HIST_ENTRY *entry; + + if (string == 0 || *string == '\0' || noninc_history_pos < 0) + { + rl_ding (); + return 0; + } + + pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, &ind); + if (pos == -1) + { + /* Search failed, current history position unchanged. */ + rl_maybe_unsave_line (); + rl_clear_message (); + rl_point = 0; + rl_ding (); + return 0; + } + + noninc_history_pos = pos; + + oldpos = where_history (); + history_set_pos (noninc_history_pos); + entry = current_history (); /* will never be NULL after successful search */ + +#if defined (VI_MODE) + if (rl_editing_mode != vi_mode) +#endif + history_set_pos (oldpos); + + make_history_line_current (entry); + + if (_rl_enable_active_region && ((flags & SF_PATTERN) == 0) && ind > 0 && ind < rl_end) + { + rl_point = ind; + rl_mark = ind + strlen (string); + if (rl_mark > rl_end) + rl_mark = rl_end; /* can't happen? */ + rl_activate_mark (); + } + else + { + rl_point = 0; + rl_mark = rl_end; + } + + rl_clear_message (); + return 1; +} + +static _rl_search_cxt * +_rl_nsearch_init (int dir, int pchar) +{ + _rl_search_cxt *cxt; + char *p; + + cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0); + if (dir < 0) + cxt->sflags |= SF_REVERSE; /* not strictly needed */ +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/')) + cxt->sflags |= SF_PATTERN; +#endif + + cxt->direction = dir; + cxt->history_pos = cxt->save_line; + + rl_maybe_save_line (); + + /* Clear the undo list, since reading the search string should create its + own undo list, and the whole list will end up being freed when we + finish reading the search string. */ + rl_undo_list = 0; + + /* Use the line buffer to read the search string. */ + rl_line_buffer[0] = 0; + rl_end = rl_point = 0; + + p = _rl_make_prompt_for_search (pchar ? pchar : ':'); + rl_message ("%s", p); + xfree (p); + + RL_SETSTATE(RL_STATE_NSEARCH); + + _rl_nscxt = cxt; + + return cxt; +} + +int +_rl_nsearch_cleanup (_rl_search_cxt *cxt, int r) +{ + _rl_scxt_dispose (cxt, 0); + _rl_nscxt = 0; + + RL_UNSETSTATE(RL_STATE_NSEARCH); + + return (r != 1); +} + +static void +_rl_nsearch_abort (_rl_search_cxt *cxt) +{ + rl_maybe_unsave_line (); + rl_clear_message (); + rl_point = cxt->save_point; + rl_mark = cxt->save_mark; + _rl_fix_point (1); + rl_restore_prompt (); + + RL_UNSETSTATE (RL_STATE_NSEARCH); +} + +/* Process just-read character C according to search context CXT. Return -1 + if the caller should abort the search, 0 if we should break out of the + loop, and 1 if we should continue to read characters. */ +static int +_rl_nsearch_dispatch (_rl_search_cxt *cxt, int c) +{ + int n; + + if (c < 0) + c = CTRL ('C'); + + switch (c) + { + case CTRL('W'): + rl_unix_word_rubout (1, c); + break; + + case CTRL('U'): + rl_unix_line_discard (1, c); + break; + + case RETURN: + case NEWLINE: + return 0; + + case CTRL('H'): + case RUBOUT: + if (rl_point == 0) + { + _rl_nsearch_abort (cxt); + return -1; + } + _rl_rubout_char (1, c); + break; + + case CTRL('C'): + case CTRL('G'): + rl_ding (); + _rl_nsearch_abort (cxt); + return -1; + + case ESC: + /* XXX - experimental code to allow users to bracketed-paste into the + search string. Similar code is in isearch.c:_rl_isearch_dispatch(). + The difference here is that the bracketed paste sometimes doesn't + paste everything, so checking for the prefix and the suffix in the + input queue doesn't work well. We just have to check to see if the + number of chars in the input queue is enough for the bracketed paste + prefix and hope for the best. */ + if (_rl_enable_bracketed_paste && ((n = _rl_nchars_available ()) >= (BRACK_PASTE_SLEN-1))) + { + if (_rl_read_bracketed_paste_prefix (c) == 1) + rl_bracketed_paste_begin (1, c); + else + { + c = rl_read_key (); /* get the ESC that got pushed back */ + _rl_insert_char (1, c); + } + } + else + _rl_insert_char (1, c); + break; + + default: +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_insert_text (cxt->mb); + else +#endif + _rl_insert_char (1, c); + break; + } + + (*rl_redisplay_function) (); + rl_deactivate_mark (); + return 1; +} + +/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return + -1 if the search should be aborted, any other value means to clean up + using _rl_nsearch_cleanup (). Returns 1 if the search was successful, + 0 otherwise. */ +static int +_rl_nsearch_dosearch (_rl_search_cxt *cxt) +{ + rl_mark = cxt->save_mark; + + /* If rl_point == 0, we want to re-use the previous search string and + start from the saved history position. If there's no previous search + string, punt. */ + if (rl_point == 0) + { + if (noninc_search_string == 0) + { + rl_ding (); + rl_restore_prompt (); + RL_UNSETSTATE (RL_STATE_NSEARCH); + return -1; + } + } + else + { + /* We want to start the search from the current history position. */ + noninc_history_pos = cxt->save_line; + FREE (noninc_search_string); + noninc_search_string = savestring (rl_line_buffer); + + /* If we don't want the subsequent undo list generated by the search + matching a history line to include the contents of the search string, + we need to clear rl_line_buffer here. For now, we just clear the + undo list generated by reading the search string. (If the search + fails, the old undo list will be restored by rl_maybe_unsave_line.) */ + rl_free_undo_list (); + } + + rl_restore_prompt (); + return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN)); +} + +/* Search non-interactively through the history list. DIR < 0 means to + search backwards through the history of previous commands; otherwise + the search is for commands subsequent to the current position in the + history list. PCHAR is the character to use for prompting when reading + the search string; if not specified (0), it defaults to `:'. */ +static int +noninc_search (int dir, int pchar) +{ + _rl_search_cxt *cxt; + int c, r; + + cxt = _rl_nsearch_init (dir, pchar); + + if (RL_ISSTATE (RL_STATE_CALLBACK)) + return (0); + + /* Read the search string. */ + r = 0; + while (1) + { + c = _rl_search_getchar (cxt); + + if (c < 0) + { + _rl_nsearch_abort (cxt); + return 1; + } + + if (c == 0) + break; + + r = _rl_nsearch_dispatch (cxt, c); + if (r < 0) + return 1; + else if (r == 0) + break; + } + + r = _rl_nsearch_dosearch (cxt); + return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1)); +} + +/* Search forward through the history list for a string. If the vi-mode + code calls this, KEY will be `?'. */ +int +rl_noninc_forward_search (int count, int key) +{ + return noninc_search (1, (key == '?') ? '?' : 0); +} + +/* Reverse search the history list for a string. If the vi-mode code + calls this, KEY will be `/'. */ +int +rl_noninc_reverse_search (int count, int key) +{ + return noninc_search (-1, (key == '/') ? '/' : 0); +} + +/* Search forward through the history list for the last string searched + for. If there is no saved search string, abort. If the vi-mode code + calls this, KEY will be `N'. */ +int +rl_noninc_forward_search_again (int count, int key) +{ + int r; + + if (!noninc_search_string) + { + rl_ding (); + return (1); + } +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && key == 'N') + r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN); + else +#endif + r = noninc_dosearch (noninc_search_string, 1, 0); + return (r != 1); +} + +/* Reverse search in the history list for the last string searched + for. If there is no saved search string, abort. If the vi-mode code + calls this, KEY will be `n'. */ +int +rl_noninc_reverse_search_again (int count, int key) +{ + int r; + + if (!noninc_search_string) + { + rl_ding (); + return (1); + } +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && key == 'n') + r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN); + else +#endif + r = noninc_dosearch (noninc_search_string, -1, 0); + return (r != 1); +} + +#if defined (READLINE_CALLBACKS) +int +_rl_nsearch_callback (_rl_search_cxt *cxt) +{ + int c, r; + + c = _rl_search_getchar (cxt); + if (c <= 0) + { + if (c < 0) + _rl_nsearch_abort (cxt); + return 1; + } + r = _rl_nsearch_dispatch (cxt, c); + if (r != 0) + return 1; + + r = _rl_nsearch_dosearch (cxt); + return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1)); +} +#endif + +static int +rl_history_search_internal (int count, int dir) +{ + HIST_ENTRY *temp; + int ret, oldpos, newcol; + char *t; + + rl_maybe_save_line (); + temp = (HIST_ENTRY *)NULL; + + /* Search COUNT times through the history for a line matching + history_search_string. If history_search_string[0] == '^', the + line must match from the start; otherwise any substring can match. + When this loop finishes, TEMP, if non-null, is the history line to + copy into the line buffer. */ + while (count) + { + RL_CHECK_SIGNALS (); + ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol); + if (ret == -1) + break; + + /* Get the history entry we found. */ + rl_history_search_pos = ret; + oldpos = where_history (); + history_set_pos (rl_history_search_pos); + temp = current_history (); /* will never be NULL after successful search */ + history_set_pos (oldpos); + + /* Don't find multiple instances of the same line. */ + if (prev_line_found && STREQ (prev_line_found, temp->line)) + continue; + prev_line_found = temp->line; + count--; + } + + /* If we didn't find anything at all, return. */ + if (temp == 0) + { + rl_maybe_unsave_line (); + rl_ding (); + /* If you don't want the saved history line (last match) to show up + in the line buffer after the search fails, change the #if 0 to + #if 1 */ +#if 0 + if (rl_point > rl_history_search_len) + { + rl_point = rl_end = rl_history_search_len; + rl_line_buffer[rl_end] = '\0'; + rl_mark = 0; + } +#else + rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */ + rl_mark = rl_end; +#endif + return 1; + } + + /* Copy the line we found into the current line buffer. */ + make_history_line_current (temp); + + /* decide where to put rl_point -- need to change this for pattern search */ + if (rl_history_search_flags & ANCHORED_SEARCH) + rl_point = rl_history_search_len; /* easy case */ + else + { +#if 0 + t = strstr (rl_line_buffer, history_search_string); /* XXX */ + rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end; +#else + rl_point = (newcol >= 0) ? newcol : rl_end; +#endif + } + rl_mark = rl_end; + + return 0; +} + +static void +rl_history_search_reinit (int flags) +{ + int sind; + + rl_history_search_pos = where_history (); + rl_history_search_len = rl_point; + rl_history_search_flags = flags; + + prev_line_found = (char *)NULL; + if (rl_point) + { + /* Allocate enough space for anchored and non-anchored searches */ + if (rl_history_search_len >= history_string_size - 2) + { + history_string_size = rl_history_search_len + 2; + history_search_string = (char *)xrealloc (history_search_string, history_string_size); + } + sind = 0; + if (flags & ANCHORED_SEARCH) + history_search_string[sind++] = '^'; + strncpy (history_search_string + sind, rl_line_buffer, rl_point); + history_search_string[rl_point + sind] = '\0'; + } + _rl_free_saved_history_line (); +} + +/* Search forward in the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. The search is anchored to the beginning of the history line. */ +int +rl_history_search_forward (int count, int ignore) +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (ANCHORED_SEARCH); + + if (rl_history_search_len == 0) + return (rl_get_next_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); +} + +/* Search backward through the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. */ +int +rl_history_search_backward (int count, int ignore) +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (ANCHORED_SEARCH); + + if (rl_history_search_len == 0) + return (rl_get_previous_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); +} + +/* Search forward in the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. The search succeeds if the search string is present anywhere + in the history line. */ +int +rl_history_substr_search_forward (int count, int ignore) +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_substr_search_forward && + rl_last_func != rl_history_substr_search_backward) + rl_history_search_reinit (NON_ANCHORED_SEARCH); + + if (rl_history_search_len == 0) + return (rl_get_next_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); +} + +/* Search backward through the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. */ +int +rl_history_substr_search_backward (int count, int ignore) +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_substr_search_forward && + rl_last_func != rl_history_substr_search_backward) + rl_history_search_reinit (NON_ANCHORED_SEARCH); + + if (rl_history_search_len == 0) + return (rl_get_previous_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); +} diff --git a/utshell-0.5.0/lib/readline/shell.c b/utshell-0.5.0/lib/readline/shell.c new file mode 100644 index 00000000..7fe2e97c --- /dev/null +++ b/utshell-0.5.0/lib/readline/shell.c @@ -0,0 +1,214 @@ +/* shell.c -- readline utility functions that are normally provided by + bash when readline is linked as part of the shell. */ + +/* Copyright (C) 1997-2009,2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#if defined (HAVE_FCNTL_H) +#include +#endif +#if defined (HAVE_PWD_H) +#include +#endif + +#include + +#include "rlstdc.h" +#include "rlshell.h" +#include "rldefs.h" + +#include "xmalloc.h" + +#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid PARAMS((uid_t)); +#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */ + +#ifndef NULL +# define NULL 0 +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) + +/* All of these functions are resolved from bash if we are linking readline + as part of bash. */ + +/* Does shell-like quoting using single quotes. */ +char * +sh_single_quote (char *string) +{ + register int c; + char *result, *r, *s; + + result = (char *)xmalloc (3 + (4 * strlen (string))); + r = result; + *r++ = '\''; + + for (s = string; s && (c = *s); s++) + { + *r++ = c; + + if (c == '\'') + { + *r++ = '\\'; /* insert escaped single quote */ + *r++ = '\''; + *r++ = '\''; /* start new quoted string */ + } + } + + *r++ = '\''; + *r = '\0'; + + return (result); +} + +/* Set the environment variables LINES and COLUMNS to lines and cols, + respectively. */ +static char setenv_buf[INT_STRLEN_BOUND (int) + 1]; +static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1]; /* sizeof("LINES=") == 6 */ +static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1]; /* sizeof("COLUMNS=") == 8 */ + +void +sh_set_lines_and_columns (int lines, int cols) +{ +#if defined (HAVE_SETENV) + sprintf (setenv_buf, "%d", lines); + setenv ("LINES", setenv_buf, 1); + + sprintf (setenv_buf, "%d", cols); + setenv ("COLUMNS", setenv_buf, 1); +#else /* !HAVE_SETENV */ +# if defined (HAVE_PUTENV) + sprintf (putenv_buf1, "LINES=%d", lines); + putenv (putenv_buf1); + + sprintf (putenv_buf2, "COLUMNS=%d", cols); + putenv (putenv_buf2); +# endif /* HAVE_PUTENV */ +#endif /* !HAVE_SETENV */ +} + +char * +sh_get_env_value (const char *varname) +{ + return ((char *)getenv (varname)); +} + +char * +sh_get_home_dir (void) +{ + static char *home_dir = (char *)NULL; + struct passwd *entry; + + if (home_dir) + return (home_dir); + + home_dir = (char *)NULL; +#if defined (HAVE_GETPWUID) +# if defined (__TANDEM) + entry = getpwnam (getlogin ()); +# else + entry = getpwuid (getuid ()); +# endif + if (entry) + home_dir = savestring (entry->pw_dir); +#endif + +#if defined (HAVE_GETPWENT) + endpwent (); /* some systems need this */ +#endif + + return (home_dir); +} + +#if !defined (O_NDELAY) +# if defined (FNDELAY) +# define O_NDELAY FNDELAY +# endif +#endif + +int +sh_unset_nodelay_mode (int fd) +{ +#if defined (HAVE_FCNTL) + int flags, bflags; + + if ((flags = fcntl (fd, F_GETFL, 0)) < 0) + return -1; + + bflags = 0; + +#ifdef O_NONBLOCK + bflags |= O_NONBLOCK; +#endif + +#ifdef O_NDELAY + bflags |= O_NDELAY; +#endif + + if (flags & bflags) + { + flags &= ~bflags; + return (fcntl (fd, F_SETFL, flags)); + } +#endif + + return 0; +} diff --git a/utshell-0.5.0/lib/readline/signals.c b/utshell-0.5.0/lib/readline/signals.c new file mode 100644 index 00000000..f9174ab8 --- /dev/null +++ b/utshell-0.5.0/lib/readline/signals.c @@ -0,0 +1,779 @@ +/* signals.c -- signal handling support for readline. */ + +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include /* Just for NULL. Yuck. */ +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) +# include +#endif /* GWINSZ_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" + +#if defined (HANDLE_SIGNALS) + +#if !defined (RETSIGTYPE) +# if defined (VOID_SIGHANDLER) +# define RETSIGTYPE void +# else +# define RETSIGTYPE int +# endif /* !VOID_SIGHANDLER */ +#endif /* !RETSIGTYPE */ + +#if defined (VOID_SIGHANDLER) +# define SIGHANDLER_RETURN return +#else +# define SIGHANDLER_RETURN return (0) +#endif + +/* This typedef is equivalent to the one for Function; it allows us + to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */ +typedef RETSIGTYPE SigHandler (); + +#if defined (HAVE_POSIX_SIGNALS) +typedef struct sigaction sighandler_cxt; +# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh) +#else +typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt; +# define sigemptyset(m) +#endif /* !HAVE_POSIX_SIGNALS */ + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif + +static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); +static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); +static void rl_maybe_restore_sighandler PARAMS((int, sighandler_cxt *)); + +static RETSIGTYPE rl_signal_handler PARAMS((int)); +static RETSIGTYPE _rl_handle_signal PARAMS((int)); + +/* Exported variables for use by applications. */ + +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +int rl_catch_signals = 1; + +/* If non-zero, readline will install a signal handler for SIGWINCH. */ +#ifdef SIGWINCH +int rl_catch_sigwinch = 1; +#else +int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */ +#endif + +/* Private variables. */ +int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including everywhere */ + +/* If non-zero, print characters corresponding to received signals as long as + the user has indicated his desire to do so (_rl_echo_control_chars). */ +int _rl_echoctl = 0; + +int _rl_intr_char = 0; +int _rl_quit_char = 0; +int _rl_susp_char = 0; + +static int signals_set_flag; +static int sigwinch_set_flag; + +#if defined (HAVE_POSIX_SIGNALS) +sigset_t _rl_orig_sigset; +#endif /* !HAVE_POSIX_SIGNALS */ + +/* **************************************************************** */ +/* */ +/* Signal Handling */ +/* */ +/* **************************************************************** */ + +static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit; +#if defined (SIGTSTP) +static sighandler_cxt old_tstp, old_ttou, old_ttin; +#endif +#if defined (SIGWINCH) +static sighandler_cxt old_winch; +#endif + +_rl_sigcleanup_func_t *_rl_sigcleanup; +void *_rl_sigcleanarg; + +/* Readline signal handler functions. */ + +/* Called from RL_CHECK_SIGNALS() macro to run signal handling code. */ +RETSIGTYPE +_rl_signal_handler (int sig) +{ + _rl_caught_signal = 0; /* XXX */ + +#if defined (SIGWINCH) + if (sig == SIGWINCH) + { + RL_SETSTATE(RL_STATE_SIGHANDLER); + + rl_resize_terminal (); + /* XXX - experimental for now */ + /* Call a signal hook because though we called the original signal handler + in rl_sigwinch_handler below, we will not resend the signal to + ourselves. */ + if (rl_signal_event_hook) + (*rl_signal_event_hook) (); + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + } + else +#endif + _rl_handle_signal (sig); + + SIGHANDLER_RETURN; +} + +static RETSIGTYPE +rl_signal_handler (int sig) +{ + _rl_caught_signal = sig; + SIGHANDLER_RETURN; +} + +/* This is called to handle a signal when it is safe to do so (out of the + signal handler execution path). Called by _rl_signal_handler for all the + signals readline catches except SIGWINCH. */ +static RETSIGTYPE +_rl_handle_signal (int sig) +{ + int block_sig; + +#if defined (HAVE_POSIX_SIGNALS) + sigset_t set, oset; +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + long omask; +# else /* !HAVE_BSD_SIGNALS */ + sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + RL_SETSTATE(RL_STATE_SIGHANDLER); + +#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS) + /* Since the signal will not be blocked while we are in the signal + handler, ignore it until rl_clear_signals resets the catcher. */ +# if defined (SIGALRM) + if (sig == SIGINT || sig == SIGALRM) +# else + if (sig == SIGINT) +# endif + rl_set_sighandler (sig, SIG_IGN, &dummy_cxt); +#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ + + /* If there's a sig cleanup function registered, call it and `deregister' + the cleanup function to avoid multiple calls */ + if (_rl_sigcleanup) + { + (*_rl_sigcleanup) (sig, _rl_sigcleanarg); + _rl_sigcleanup = 0; + _rl_sigcleanarg = 0; + } + +#if defined (HAVE_POSIX_SIGNALS) + /* Get the current set of blocked signals. If we want to block a signal for + the duration of the cleanup functions, make sure to add it to SET and + set block_sig = 1 (see the SIGHUP case below). */ + block_sig = 0; /* sentinel to block signals with sigprocmask */ + sigemptyset (&set); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); +#endif + + switch (sig) + { + case SIGINT: + _rl_reset_completion_state (); + rl_free_line_state (); +#if defined (READLINE_CALLBACKS) + rl_callback_sigcleanup (); +#endif + + /* FALLTHROUGH */ + +#if defined (SIGTSTP) + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: +# if defined (HAVE_POSIX_SIGNALS) + /* Block SIGTTOU so we can restore the terminal settings to something + sane without stopping on SIGTTOU if we have been placed into the + background. Even trying to get the current terminal pgrp with + tcgetpgrp() will generate SIGTTOU, so we don't bother. We still do + this even if we've been stopped on SIGTTOU, since we handle signals + when we have returned from the signal handler and the signal is no + longer blocked. */ + sigaddset (&set, SIGTTOU); + block_sig = 1; +# endif +#endif /* SIGTSTP */ + /* Any signals that should be blocked during cleanup should go here. */ +#if defined (SIGHUP) + case SIGHUP: +# if defined (_AIX) + if (block_sig == 0) + { + sigaddset (&set, sig); + block_sig = 1; + } +# endif // _AIX +#endif + /* Signals that don't require blocking during cleanup should go here. */ + case SIGTERM: +#if defined (SIGALRM) + case SIGALRM: +#endif +#if defined (SIGQUIT) + case SIGQUIT: +#endif + + if (block_sig) + sigprocmask (SIG_BLOCK, &set, &oset); + + rl_echo_signal_char (sig); + rl_cleanup_after_signal (); + + /* At this point, the application's signal handler, if any, is the + current handler. */ + +#if defined (HAVE_POSIX_SIGNALS) + /* Unblock any signal(s) blocked above */ + if (block_sig) + sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL); +#endif + + /* We don't have to bother unblocking the signal because we are not + running in a signal handler context. */ +#if 0 +#if defined (HAVE_POSIX_SIGNALS) + /* Make sure this signal is not blocked when we resend it to the + calling application. */ + sigemptyset (&set); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); + sigdelset (&set, sig); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + omask = sigblock (0); +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ +#endif + +#if defined (__EMX__) + signal (sig, SIG_ACK); +#endif + +#if defined (HAVE_KILL) + kill (getpid (), sig); +#else + raise (sig); /* assume we have raise */ +#endif + + /* We don't need to modify the signal mask now that this is not run in + a signal handler context. */ +#if 0 + /* Let the signal that we just sent through if it is blocked. */ +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (omask & ~(sigmask (sig))); +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ +#endif + + rl_reset_after_signal (); + } + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + SIGHANDLER_RETURN; +} + +#if defined (SIGWINCH) +static RETSIGTYPE +rl_sigwinch_handler (int sig) +{ + SigHandler *oh; + +#if defined (MUST_REINSTALL_SIGHANDLERS) + sighandler_cxt dummy_winch; + + /* We don't want to change old_winch -- it holds the state of SIGWINCH + disposition set by the calling application. We need this state + because we call the application's SIGWINCH handler after updating + our own idea of the screen size. */ + rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch); +#endif + + RL_SETSTATE(RL_STATE_SIGHANDLER); + _rl_caught_signal = sig; + + /* If another sigwinch handler has been installed, call it. */ + oh = (SigHandler *)old_winch.sa_handler; + if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL) + (*oh) (sig); + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + SIGHANDLER_RETURN; +} +#endif /* SIGWINCH */ + +/* Functions to manage signal handling. */ + +#if !defined (HAVE_POSIX_SIGNALS) +static int +rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh) +{ + oh->sa_handler = signal (sig, nh->sa_handler); + return 0; +} +#endif /* !HAVE_POSIX_SIGNALS */ + +/* Set up a readline-specific signal handler, saving the old signal + information in OHANDLER. Return the old signal handler, like + signal(). */ +static SigHandler * +rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler) +{ + sighandler_cxt old_handler; +#if defined (HAVE_POSIX_SIGNALS) + struct sigaction act; + + act.sa_handler = handler; +# if defined (SIGWINCH) + act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0; +# else + act.sa_flags = 0; +# endif /* SIGWINCH */ + sigemptyset (&act.sa_mask); + sigemptyset (&ohandler->sa_mask); + sigaction (sig, &act, &old_handler); +#else + old_handler.sa_handler = (SigHandler *)signal (sig, handler); +#endif /* !HAVE_POSIX_SIGNALS */ + + /* XXX -- assume we have memcpy */ + /* If rl_set_signals is called twice in a row, don't set the old handler to + rl_signal_handler, because that would cause infinite recursion. */ + if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler) + memcpy (ohandler, &old_handler, sizeof (sighandler_cxt)); + + return (ohandler->sa_handler); +} + +/* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't + change disposition if OHANDLER indicates the signal was ignored. */ +static void +rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler) +{ + sighandler_cxt dummy; + SigHandler *oh; + + sigemptyset (&dummy.sa_mask); + dummy.sa_flags = 0; + oh = rl_set_sighandler (sig, handler, ohandler); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (sig, ohandler, &dummy); +} + +/* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the + signal was not being ignored. MUST only be called for signals whose + disposition was changed using rl_maybe_set_sighandler or for which the + SIG_IGN check was performed inline (e.g., SIGALRM below). */ +static void +rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler) +{ + sighandler_cxt dummy; + + sigemptyset (&dummy.sa_mask); + dummy.sa_flags = 0; + if (handler->sa_handler != SIG_IGN) + rl_sigaction (sig, handler, &dummy); +} + +int +rl_set_signals (void) +{ + sighandler_cxt dummy; + SigHandler *oh; +#if defined (HAVE_POSIX_SIGNALS) + static int sigmask_set = 0; + static sigset_t bset, oset; +#endif + +#if defined (HAVE_POSIX_SIGNALS) + if (rl_catch_signals && sigmask_set == 0) + { + sigemptyset (&bset); + + sigaddset (&bset, SIGINT); + sigaddset (&bset, SIGTERM); +#if defined (SIGHUP) + sigaddset (&bset, SIGHUP); +#endif +#if defined (SIGQUIT) + sigaddset (&bset, SIGQUIT); +#endif +#if defined (SIGALRM) + sigaddset (&bset, SIGALRM); +#endif +#if defined (SIGTSTP) + sigaddset (&bset, SIGTSTP); +#endif +#if defined (SIGTTIN) + sigaddset (&bset, SIGTTIN); +#endif +#if defined (SIGTTOU) + sigaddset (&bset, SIGTTOU); +#endif + sigmask_set = 1; + } +#endif /* HAVE_POSIX_SIGNALS */ + + if (rl_catch_signals && signals_set_flag == 0) + { +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset); +#endif + + rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); + rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); +#if defined (SIGHUP) + rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup); +#endif +#if defined (SIGQUIT) + rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit); +#endif + +#if defined (SIGALRM) + oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART) + /* If the application using readline has already installed a signal + handler with SA_RESTART, SIGALRM will cause reads to be restarted + automatically, so readline should just get out of the way. Since + we tested for SIG_IGN above, we can just test for SIG_DFL here. */ + if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART)) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#endif /* HAVE_POSIX_SIGNALS */ +#endif /* SIGALRM */ + +#if defined (SIGTSTP) + rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp); +#endif /* SIGTSTP */ + +#if defined (SIGTTOU) + rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou); +#endif /* SIGTTOU */ + +#if defined (SIGTTIN) + rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin); +#endif /* SIGTTIN */ + + signals_set_flag = 1; + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL); +#endif + } + else if (rl_catch_signals == 0) + { +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset); +#endif + } + +#if defined (SIGWINCH) + if (rl_catch_sigwinch && sigwinch_set_flag == 0) + { + rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch); + sigwinch_set_flag = 1; + } +#endif /* SIGWINCH */ + + return 0; +} + +int +rl_clear_signals (void) +{ + sighandler_cxt dummy; + + if (rl_catch_signals && signals_set_flag == 1) + { + /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler, + we should in theory not have to restore a handler where + old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler + does. Fewer system calls should reduce readline's per-line + overhead */ + rl_maybe_restore_sighandler (SIGINT, &old_int); + rl_maybe_restore_sighandler (SIGTERM, &old_term); +#if defined (SIGHUP) + rl_maybe_restore_sighandler (SIGHUP, &old_hup); +#endif +#if defined (SIGQUIT) + rl_maybe_restore_sighandler (SIGQUIT, &old_quit); +#endif +#if defined (SIGALRM) + rl_maybe_restore_sighandler (SIGALRM, &old_alrm); +#endif + +#if defined (SIGTSTP) + rl_maybe_restore_sighandler (SIGTSTP, &old_tstp); +#endif /* SIGTSTP */ + +#if defined (SIGTTOU) + rl_maybe_restore_sighandler (SIGTTOU, &old_ttou); +#endif /* SIGTTOU */ + +#if defined (SIGTTIN) + rl_maybe_restore_sighandler (SIGTTIN, &old_ttin); +#endif /* SIGTTIN */ + + signals_set_flag = 0; + } + +#if defined (SIGWINCH) + if (rl_catch_sigwinch && sigwinch_set_flag == 1) + { + sigemptyset (&dummy.sa_mask); + rl_sigaction (SIGWINCH, &old_winch, &dummy); + sigwinch_set_flag = 0; + } +#endif + + return 0; +} + +/* Clean up the terminal and readline state after catching a signal, before + resending it to the calling application. */ +void +rl_cleanup_after_signal (void) +{ + _rl_clean_up_for_exit (); + if (rl_deprep_term_function) + (*rl_deprep_term_function) (); + rl_clear_pending_input (); + rl_clear_signals (); +} + +/* Reset the terminal and readline state after a signal handler returns. */ +void +rl_reset_after_signal (void) +{ + if (rl_prep_term_function) + (*rl_prep_term_function) (_rl_meta_flag); + rl_set_signals (); +} + +/* Free up the readline variable line state for the current line (undo list, + any partial history entry, any keyboard macros in progress, and any + numeric arguments in process) after catching a signal, before calling + rl_cleanup_after_signal(). */ +void +rl_free_line_state (void) +{ + register HIST_ENTRY *entry; + + rl_free_undo_list (); + + entry = current_history (); + if (entry) + entry->data = (char *)NULL; + + _rl_kill_kbd_macro (); + rl_clear_message (); + _rl_reset_argument (); +} + +int +rl_pending_signal (void) +{ + return (_rl_caught_signal); +} + +void +rl_check_signals (void) +{ + RL_CHECK_SIGNALS (); +} +#endif /* HANDLE_SIGNALS */ + +/* **************************************************************** */ +/* */ +/* SIGINT Management */ +/* */ +/* **************************************************************** */ + +#if defined (HAVE_POSIX_SIGNALS) +static sigset_t sigint_set, sigint_oset; +static sigset_t sigwinch_set, sigwinch_oset; +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) +static int sigint_oldmask; +static int sigwinch_oldmask; +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +static int sigint_blocked; +static int sigwinch_blocked; + +/* Cause SIGINT to not be delivered until the corresponding call to + release_sigint(). */ +void +_rl_block_sigint (void) +{ + if (sigint_blocked) + return; + + sigint_blocked = 1; +} + +/* Allow SIGINT to be delivered. */ +void +_rl_release_sigint (void) +{ + if (sigint_blocked == 0) + return; + + sigint_blocked = 0; + RL_CHECK_SIGNALS (); +} + +/* Cause SIGWINCH to not be delivered until the corresponding call to + release_sigwinch(). */ +void +_rl_block_sigwinch (void) +{ + if (sigwinch_blocked) + return; + +#if defined (SIGWINCH) + +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&sigwinch_set); + sigemptyset (&sigwinch_oset); + sigaddset (&sigwinch_set, SIGWINCH); + sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigwinch_oldmask = sigblock (sigmask (SIGWINCH)); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sighold (SIGWINCH); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +#endif /* SIGWINCH */ + + sigwinch_blocked = 1; +} + +/* Allow SIGWINCH to be delivered. */ +void +_rl_release_sigwinch (void) +{ + if (sigwinch_blocked == 0) + return; + +#if defined (SIGWINCH) + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL); +#else +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (sigwinch_oldmask); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sigrelse (SIGWINCH); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +#endif /* SIGWINCH */ + + sigwinch_blocked = 0; +} + +/* **************************************************************** */ +/* */ +/* Echoing special control characters */ +/* */ +/* **************************************************************** */ +void +rl_echo_signal_char (int sig) +{ + char cstr[3]; + int cslen, c; + + if (_rl_echoctl == 0 || _rl_echo_control_chars == 0) + return; + + switch (sig) + { + case SIGINT: c = _rl_intr_char; break; +#if defined (SIGQUIT) + case SIGQUIT: c = _rl_quit_char; break; +#endif +#if defined (SIGTSTP) + case SIGTSTP: c = _rl_susp_char; break; +#endif + default: return; + } + + if (CTRL_CHAR (c) || c == RUBOUT) + { + cstr[0] = '^'; + cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?'; + cstr[cslen = 2] = '\0'; + } + else + { + cstr[0] = c; + cstr[cslen = 1] = '\0'; + } + + _rl_output_some_chars (cstr, cslen); +} diff --git a/utshell-0.5.0/lib/readline/tcap.h b/utshell-0.5.0/lib/readline/tcap.h new file mode 100644 index 00000000..859e6eed --- /dev/null +++ b/utshell-0.5.0/lib/readline/tcap.h @@ -0,0 +1,60 @@ +/* tcap.h -- termcap library functions and variables. */ + +/* Copyright (C) 1996-2015 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RLTCAP_H_) +#define _RLTCAP_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#if defined (HAVE_TERMCAP_H) +# if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES) +# include "rltty.h" +# endif +# include +#elif defined (HAVE_NCURSES_TERMCAP_H) +# include +#else + +/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. + Unfortunately, PC is a global variable used by the termcap library. */ +#ifdef PC +# undef PC +#endif + +extern char PC; +extern char *UP, *BC; + +extern short ospeed; + +extern int tgetent (); +extern int tgetflag (); +extern int tgetnum (); +extern char *tgetstr (); + +extern int tputs (); + +extern char *tgoto (); + +#endif /* HAVE_TERMCAP_H */ + +#endif /* !_RLTCAP_H_ */ diff --git a/utshell-0.5.0/lib/readline/terminal.c b/utshell-0.5.0/lib/readline/terminal.c new file mode 100644 index 00000000..05415dc4 --- /dev/null +++ b/utshell-0.5.0/lib/readline/terminal.c @@ -0,0 +1,845 @@ +/* terminal.c -- controlling the terminal with termcap. */ + +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include "posixstat.h" +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#ifdef __MSDOS__ +# include +#endif + +#include "rltty.h" +#if defined (HAVE_SYS_IOCTL_H) +# include /* include for declaration of ioctl */ +#endif +#include "tcap.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#if defined (__MINGW32__) +# include +# include + +static void _win_get_screensize PARAMS((int *, int *)); +#endif + +#if defined (__EMX__) +static void _emx_get_screensize PARAMS((int *, int *)); +#endif + +/* If the calling application sets this to a non-zero value, readline will + use the $LINES and $COLUMNS environment variables to set its idea of the + window size before interrogating the kernel. */ +int rl_prefer_env_winsize = 0; + +/* If this is non-zero, readline will set LINES and COLUMNS in the + environment when it handles SIGWINCH. */ +int rl_change_environment = 1; + +/* **************************************************************** */ +/* */ +/* Terminal and Termcap */ +/* */ +/* **************************************************************** */ + +#ifndef __MSDOS__ +static char *term_buffer = (char *)NULL; +static char *term_string_buffer = (char *)NULL; +#endif + +static int tcap_initialized; + +#if !defined (__linux__) && !defined (NCURSES_VERSION) +# if defined (__EMX__) || defined (NEED_EXTERN_PC) +extern +# endif /* __EMX__ || NEED_EXTERN_PC */ +char PC, *BC, *UP; +#endif /* !__linux__ && !NCURSES_VERSION */ + +/* Some strings to control terminal actions. These are output by tputs (). */ +char *_rl_term_clreol; +char *_rl_term_clrpag; +char *_rl_term_clrscroll; +char *_rl_term_cr; +char *_rl_term_backspace; +char *_rl_term_goto; +char *_rl_term_pc; + +/* Non-zero if we determine that the terminal can do character insertion. */ +int _rl_terminal_can_insert = 0; + +/* How to insert characters. */ +char *_rl_term_im; +char *_rl_term_ei; +char *_rl_term_ic; +char *_rl_term_ip; +char *_rl_term_IC; + +/* How to delete characters. */ +char *_rl_term_dc; +char *_rl_term_DC; + +/* How to move forward a char, non-destructively */ +char *_rl_term_forward_char; + +/* How to go up a line. */ +char *_rl_term_up; + +/* A visible bell; char if the terminal can be made to flash the screen. */ +static char *_rl_visible_bell; + +/* Non-zero means the terminal can auto-wrap lines. */ +int _rl_term_autowrap = -1; + +/* Non-zero means that this terminal has a meta key. */ +static int term_has_meta; + +/* The sequences to write to turn on and off the meta key, if this + terminal has one. */ +static char *_rl_term_mm; +static char *_rl_term_mo; + +/* The sequences to enter and exit standout mode. */ +static char *_rl_term_so; +static char *_rl_term_se; + +/* The key sequences output by the arrow keys, if this terminal has any. */ +static char *_rl_term_ku; +static char *_rl_term_kd; +static char *_rl_term_kr; +static char *_rl_term_kl; + +/* How to initialize and reset the arrow keys, if this terminal has any. */ +static char *_rl_term_ks; +static char *_rl_term_ke; + +/* The key sequences sent by the Home and End keys, if any. */ +static char *_rl_term_kh; +static char *_rl_term_kH; +static char *_rl_term_at7; /* @7 */ + +/* Delete key */ +static char *_rl_term_kD; + +/* Insert key */ +static char *_rl_term_kI; + +/* Cursor control */ +static char *_rl_term_vs; /* very visible */ +static char *_rl_term_ve; /* normal */ + +/* It's not clear how HPUX is so broken here. */ +#ifdef TGETENT_BROKEN +# define TGETENT_SUCCESS 0 +#else +# define TGETENT_SUCCESS 1 +#endif +#ifdef TGETFLAG_BROKEN +# define TGETFLAG_SUCCESS 0 +#else +# define TGETFLAG_SUCCESS 1 +#endif +#define TGETFLAG(cap) (tgetflag (cap) == TGETFLAG_SUCCESS) + +static void bind_termcap_arrow_keys PARAMS((Keymap)); + +/* Variables that hold the screen dimensions, used by the display code. */ +int _rl_screenwidth, _rl_screenheight, _rl_screenchars; + +/* Non-zero means the user wants to enable the keypad. */ +int _rl_enable_keypad; + +/* Non-zero means the user wants to enable a meta key. */ +int _rl_enable_meta = 1; + +#if defined (__EMX__) +static void +_emx_get_screensize (int *swp, int *shp) +{ + int sz[2]; + + _scrsize (sz); + + if (swp) + *swp = sz[0]; + if (shp) + *shp = sz[1]; +} +#endif + +#if defined (__MINGW32__) +static void +_win_get_screensize (int *swp, int *shp) +{ + HANDLE hConOut; + CONSOLE_SCREEN_BUFFER_INFO scr; + + hConOut = GetStdHandle (STD_OUTPUT_HANDLE); + if (hConOut != INVALID_HANDLE_VALUE) + { + if (GetConsoleScreenBufferInfo (hConOut, &scr)) + { + *swp = scr.dwSize.X; + *shp = scr.srWindow.Bottom - scr.srWindow.Top + 1; + } + } +} +#endif + +/* Get readline's idea of the screen size. TTY is a file descriptor open + to the terminal. If IGNORE_ENV is true, we do not pay attention to the + values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being + non-null serve to check whether or not we have initialized termcap. */ +void +_rl_get_screen_size (int tty, int ignore_env) +{ + char *ss; +#if defined (TIOCGWINSZ) + struct winsize window_size; +#endif /* TIOCGWINSZ */ + int wr, wc; + + wr = wc = -1; +#if defined (TIOCGWINSZ) + if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) + { + wc = (int) window_size.ws_col; + wr = (int) window_size.ws_row; + } +#endif /* TIOCGWINSZ */ + +#if defined (__EMX__) + _emx_get_screensize (&wc, &wr); +#elif defined (__MINGW32__) + _win_get_screensize (&wc, &wr); +#endif + + if (ignore_env || rl_prefer_env_winsize == 0) + { + _rl_screenwidth = wc; + _rl_screenheight = wr; + } + else + _rl_screenwidth = _rl_screenheight = -1; + + /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV + is unset. If we prefer the environment, check it first before + assigning the value returned by the kernel. */ + if (_rl_screenwidth <= 0) + { + if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS"))) + _rl_screenwidth = atoi (ss); + + if (_rl_screenwidth <= 0) + _rl_screenwidth = wc; + +#if defined (__DJGPP__) + if (_rl_screenwidth <= 0) + _rl_screenwidth = ScreenCols (); +#else + if (_rl_screenwidth <= 0 && term_string_buffer) + _rl_screenwidth = tgetnum ("co"); +#endif + } + + /* Environment variable LINES overrides setting of "li" if IGNORE_ENV + is unset. */ + if (_rl_screenheight <= 0) + { + if (ignore_env == 0 && (ss = sh_get_env_value ("LINES"))) + _rl_screenheight = atoi (ss); + + if (_rl_screenheight <= 0) + _rl_screenheight = wr; + +#if defined (__DJGPP__) + if (_rl_screenheight <= 0) + _rl_screenheight = ScreenRows (); +#else + if (_rl_screenheight <= 0 && term_string_buffer) + _rl_screenheight = tgetnum ("li"); +#endif + } + + /* If all else fails, default to 80x24 terminal. */ + if (_rl_screenwidth <= 1) + _rl_screenwidth = 80; + + if (_rl_screenheight <= 0) + _rl_screenheight = 24; + + /* If we're being compiled as part of bash, set the environment + variables $LINES and $COLUMNS to new values. Otherwise, just + do a pair of putenv () or setenv () calls. */ + if (rl_change_environment) + sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); + + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + + _rl_screenchars = _rl_screenwidth * _rl_screenheight; +} + +void +_rl_set_screen_size (int rows, int cols) +{ + if (_rl_term_autowrap == -1) + _rl_init_terminal_io (rl_terminal_name); + + if (rows > 0) + _rl_screenheight = rows; + if (cols > 0) + { + _rl_screenwidth = cols; + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + } + + if (rows > 0 || cols > 0) + _rl_screenchars = _rl_screenwidth * _rl_screenheight; +} + +void +rl_set_screen_size (int rows, int cols) +{ + _rl_set_screen_size (rows, cols); +} + +void +rl_get_screen_size (int *rows, int *cols) +{ + if (rows) + *rows = _rl_screenheight; + if (cols) + *cols = _rl_screenwidth; +} + +void +rl_reset_screen_size (void) +{ + _rl_get_screen_size (fileno (rl_instream), 0); +} + +void +_rl_sigwinch_resize_terminal (void) +{ + _rl_get_screen_size (fileno (rl_instream), 1); +} + +void +rl_resize_terminal (void) +{ + _rl_get_screen_size (fileno (rl_instream), 1); + if (_rl_echoing_p) + { + if (CUSTOM_REDISPLAY_FUNC ()) + rl_forced_update_display (); + else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0) + _rl_redisplay_after_sigwinch (); + } +} + +struct _tc_string { + const char * const tc_var; + char **tc_value; +}; + +/* This should be kept sorted, just in case we decide to change the + search algorithm to something smarter. */ +static const struct _tc_string tc_strings[] = +{ + { "@7", &_rl_term_at7 }, + { "DC", &_rl_term_DC }, + { "E3", &_rl_term_clrscroll }, + { "IC", &_rl_term_IC }, + { "ce", &_rl_term_clreol }, + { "cl", &_rl_term_clrpag }, + { "cr", &_rl_term_cr }, + { "dc", &_rl_term_dc }, + { "ei", &_rl_term_ei }, + { "ic", &_rl_term_ic }, + { "im", &_rl_term_im }, + { "kD", &_rl_term_kD }, /* delete */ + { "kH", &_rl_term_kH }, /* home down ?? */ + { "kI", &_rl_term_kI }, /* insert */ + { "kd", &_rl_term_kd }, + { "ke", &_rl_term_ke }, /* end keypad mode */ + { "kh", &_rl_term_kh }, /* home */ + { "kl", &_rl_term_kl }, + { "kr", &_rl_term_kr }, + { "ks", &_rl_term_ks }, /* start keypad mode */ + { "ku", &_rl_term_ku }, + { "le", &_rl_term_backspace }, + { "mm", &_rl_term_mm }, + { "mo", &_rl_term_mo }, + { "nd", &_rl_term_forward_char }, + { "pc", &_rl_term_pc }, + { "se", &_rl_term_se }, + { "so", &_rl_term_so }, + { "up", &_rl_term_up }, + { "vb", &_rl_visible_bell }, + { "vs", &_rl_term_vs }, + { "ve", &_rl_term_ve }, +}; + +#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) + +/* Read the desired terminal capability strings into BP. The capabilities + are described in the TC_STRINGS table. */ +static void +get_term_capabilities (char **bp) +{ +#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ + register int i; + + for (i = 0; i < NUM_TC_STRINGS; i++) + *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp); +#endif + tcap_initialized = 1; +} + +int +_rl_init_terminal_io (const char *terminal_name) +{ + const char *term; + char *buffer; + int tty, tgetent_ret, dumbterm; + + term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); + _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL; + tty = rl_instream ? fileno (rl_instream) : 0; + + if (term == 0) + term = "dumb"; + + dumbterm = STREQ (term, "dumb"); + +#ifdef __MSDOS__ + _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; + _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; + _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; + _rl_term_mm = _rl_term_mo = (char *)NULL; + _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; + _rl_term_cr = "\r"; + _rl_term_backspace = (char *)NULL; + _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; + _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; + _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; + _rl_term_so = _rl_term_se = (char *)NULL; +#if defined(HACK_TERMCAP_MOTION) + _rl_term_forward_char = (char *)NULL; +#endif + + _rl_get_screen_size (tty, 0); +#else /* !__MSDOS__ */ + /* I've separated this out for later work on not calling tgetent at all + if the calling application has supplied a custom redisplay function, + (and possibly if the application has supplied a custom input function). */ + if (CUSTOM_REDISPLAY_FUNC()) + { + tgetent_ret = -1; + } + else + { + if (term_string_buffer == 0) + term_string_buffer = (char *)xmalloc(2032); + + if (term_buffer == 0) + term_buffer = (char *)xmalloc(4080); + + buffer = term_string_buffer; + + tgetent_ret = tgetent (term_buffer, term); + } + + if (tgetent_ret != TGETENT_SUCCESS) + { + FREE (term_string_buffer); + FREE (term_buffer); + buffer = term_buffer = term_string_buffer = (char *)NULL; + + _rl_term_autowrap = 0; /* used by _rl_get_screen_size */ + + /* Allow calling application to set default height and width, using + rl_set_screen_size */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + { +#if defined (__EMX__) + _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); + _rl_screenwidth--; +#else /* !__EMX__ */ + _rl_get_screen_size (tty, 0); +#endif /* !__EMX__ */ + } + + /* Defaults. */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + { + _rl_screenwidth = 79; + _rl_screenheight = 24; + } + + /* Everything below here is used by the redisplay code (tputs). */ + _rl_screenchars = _rl_screenwidth * _rl_screenheight; + _rl_term_cr = "\r"; + _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; + _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; + _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; + _rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL; + _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL; + _rl_term_mm = _rl_term_mo = (char *)NULL; + _rl_term_ve = _rl_term_vs = (char *)NULL; + _rl_term_forward_char = (char *)NULL; + _rl_term_so = _rl_term_se = (char *)NULL; + _rl_terminal_can_insert = term_has_meta = 0; + + /* Assume generic unknown terminal can't handle the enable/disable + escape sequences */ + _rl_enable_bracketed_paste = 0; + + /* Reasonable defaults for tgoto(). Readline currently only uses + tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we + change that later... */ + PC = '\0'; + BC = _rl_term_backspace = "\b"; + UP = _rl_term_up; + + return 0; + } + + get_term_capabilities (&buffer); + + /* Set up the variables that the termcap library expects the application + to provide. */ + PC = _rl_term_pc ? *_rl_term_pc : 0; + BC = _rl_term_backspace; + UP = _rl_term_up; + + if (_rl_term_cr == 0) + _rl_term_cr = "\r"; + + _rl_term_autowrap = TGETFLAG ("am") && TGETFLAG ("xn"); + + /* Allow calling application to set default height and width, using + rl_set_screen_size */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + _rl_get_screen_size (tty, 0); + + /* "An application program can assume that the terminal can do + character insertion if *any one of* the capabilities `IC', + `im', `ic' or `ip' is provided." But we can't do anything if + only `ip' is provided, so... */ + _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic); + + /* Check to see if this terminal has a meta key and clear the capability + variables if there is none. */ + term_has_meta = TGETFLAG ("km"); + if (term_has_meta == 0) + _rl_term_mm = _rl_term_mo = (char *)NULL; +#endif /* !__MSDOS__ */ + + /* Attempt to find and bind the arrow keys. Do not override already + bound keys in an overzealous attempt, however. */ + + bind_termcap_arrow_keys (emacs_standard_keymap); + +#if defined (VI_MODE) + bind_termcap_arrow_keys (vi_movement_keymap); + bind_termcap_arrow_keys (vi_insertion_keymap); +#endif /* VI_MODE */ + + /* There's no way to determine whether or not a given terminal supports + bracketed paste mode, so we assume a terminal named "dumb" does not. */ + if (dumbterm) + _rl_enable_bracketed_paste = 0; + + return 0; +} + +/* Bind the arrow key sequences from the termcap description in MAP. */ +static void +bind_termcap_arrow_keys (Keymap map) +{ + Keymap xkeymap; + + xkeymap = _rl_keymap; + _rl_keymap = map; + + rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history); + rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history); + rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char); + rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char); + + rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ + rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ + + rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); + rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode); /* Insert */ + + _rl_keymap = xkeymap; +} + +char * +rl_get_termcap (const char *cap) +{ + register int i; + + if (tcap_initialized == 0) + return ((char *)NULL); + for (i = 0; i < NUM_TC_STRINGS; i++) + { + if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) + return *(tc_strings[i].tc_value); + } + return ((char *)NULL); +} + +/* Re-initialize the terminal considering that the TERM/TERMCAP variable + has changed. */ +int +rl_reset_terminal (const char *terminal_name) +{ + _rl_screenwidth = _rl_screenheight = 0; + _rl_init_terminal_io (terminal_name); + return 0; +} + +/* A function for the use of tputs () */ +#ifdef _MINIX +void +_rl_output_character_function (int c) +{ + putc (c, _rl_out_stream); +} +#else /* !_MINIX */ +int +_rl_output_character_function (int c) +{ + return putc (c, _rl_out_stream); +} +#endif /* !_MINIX */ + +/* Write COUNT characters from STRING to the output stream. */ +void +_rl_output_some_chars (const char *string, int count) +{ + fwrite (string, 1, count, _rl_out_stream); +} + +/* Move the cursor back. */ +int +_rl_backspace (int count) +{ + register int i; + +#ifndef __MSDOS__ + if (_rl_term_backspace) + for (i = 0; i < count; i++) + tputs (_rl_term_backspace, 1, _rl_output_character_function); + else +#endif + for (i = 0; i < count; i++) + putc ('\b', _rl_out_stream); + return 0; +} + +/* Move to the start of the next line. */ +int +rl_crlf (void) +{ +#if defined (NEW_TTY_DRIVER) || defined (__MINT__) + if (_rl_term_cr) + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif /* NEW_TTY_DRIVER || __MINT__ */ + putc ('\n', _rl_out_stream); + return 0; +} + +void +_rl_cr (void) +{ +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif +} + +/* Ring the terminal bell. */ +int +rl_ding (void) +{ + if (_rl_echoing_p) + { + switch (_rl_bell_preference) + { + case NO_BELL: + default: + break; + case VISIBLE_BELL: + if (_rl_visible_bell) + { +#ifdef __DJGPP__ + ScreenVisualBell (); +#else + tputs (_rl_visible_bell, 1, _rl_output_character_function); +#endif + break; + } + /* FALLTHROUGH */ + case AUDIBLE_BELL: + fprintf (stderr, "\007"); + fflush (stderr); + break; + } + return (0); + } + return (-1); +} + +/* **************************************************************** */ +/* */ +/* Entering and leaving terminal standout mode */ +/* */ +/* **************************************************************** */ + +void +_rl_standout_on (void) +{ +#ifndef __MSDOS__ + if (_rl_term_so && _rl_term_se) + tputs (_rl_term_so, 1, _rl_output_character_function); +#endif +} + +void +_rl_standout_off (void) +{ +#ifndef __MSDOS__ + if (_rl_term_so && _rl_term_se) + tputs (_rl_term_se, 1, _rl_output_character_function); +#endif +} + +/* **************************************************************** */ +/* */ +/* Controlling the Meta Key and Keypad */ +/* */ +/* **************************************************************** */ + +static int enabled_meta = 0; /* flag indicating we enabled meta mode */ + +void +_rl_enable_meta_key (void) +{ +#if !defined (__DJGPP__) + if (term_has_meta && _rl_term_mm) + { + tputs (_rl_term_mm, 1, _rl_output_character_function); + enabled_meta = 1; + } +#endif +} + +void +_rl_disable_meta_key (void) +{ +#if !defined (__DJGPP__) + if (term_has_meta && _rl_term_mo && enabled_meta) + { + tputs (_rl_term_mo, 1, _rl_output_character_function); + enabled_meta = 0; + } +#endif +} + +void +_rl_control_keypad (int on) +{ +#if !defined (__DJGPP__) + if (on && _rl_term_ks) + tputs (_rl_term_ks, 1, _rl_output_character_function); + else if (!on && _rl_term_ke) + tputs (_rl_term_ke, 1, _rl_output_character_function); +#endif +} + +/* **************************************************************** */ +/* */ +/* Controlling the Cursor */ +/* */ +/* **************************************************************** */ + +/* Set the cursor appropriately depending on IM, which is one of the + insert modes (insert or overwrite). Insert mode gets the normal + cursor. Overwrite mode gets a very visible cursor. Only does + anything if we have both capabilities. */ +void +_rl_set_cursor (int im, int force) +{ +#ifndef __MSDOS__ + if (_rl_term_ve && _rl_term_vs) + { + if (force || im != rl_insert_mode) + { + if (im == RL_IM_OVERWRITE) + tputs (_rl_term_vs, 1, _rl_output_character_function); + else + tputs (_rl_term_ve, 1, _rl_output_character_function); + } + } +#endif +} diff --git a/utshell-0.5.0/lib/readline/text.c b/utshell-0.5.0/lib/readline/text.c new file mode 100644 index 00000000..2567dea2 --- /dev/null +++ b/utshell-0.5.0/lib/readline/text.c @@ -0,0 +1,1880 @@ +/* text.c -- text handling commands for readline. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (__EMX__) +# define INCL_DOSPROCESS +# include +#endif /* __EMX__ */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +/* Forward declarations. */ +static int rl_change_case PARAMS((int, int)); +static int _rl_char_search PARAMS((int, int, int)); + +#if defined (READLINE_CALLBACKS) +static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *)); +static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *)); +#endif + +/* The largest chunk of text that can be inserted in one call to + rl_insert_text. Text blocks larger than this are divided. */ +#define TEXT_COUNT_MAX 1024 + +int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */ + +/* **************************************************************** */ +/* */ +/* Insert and Delete */ +/* */ +/* **************************************************************** */ + +/* Insert a string of text into the line at point. This is the only + way that you should do insertion. _rl_insert_char () calls this + function. Returns the number of characters inserted. */ +int +rl_insert_text (const char *string) +{ + register int i, l; + + l = (string && *string) ? strlen (string) : 0; + if (l == 0) + return 0; + + if (rl_end + l >= rl_line_buffer_len) + rl_extend_line_buffer (rl_end + l); + + for (i = rl_end; i >= rl_point; i--) + rl_line_buffer[i + l] = rl_line_buffer[i]; + strncpy (rl_line_buffer + rl_point, string, l); + + /* Remember how to undo this if we aren't undoing something. */ + if (_rl_doing_an_undo == 0) + { + /* If possible and desirable, concatenate the undos. */ + if ((l == 1) && + rl_undo_list && + (rl_undo_list->what == UNDO_INSERT) && + (rl_undo_list->end == rl_point) && + (rl_undo_list->end - rl_undo_list->start < 20)) + rl_undo_list->end++; + else + rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL); + } + rl_point += l; + rl_end += l; + rl_line_buffer[rl_end] = '\0'; + return l; +} + +/* Delete the string between FROM and TO. FROM is inclusive, TO is not. + Returns the number of characters deleted. */ +int +rl_delete_text (int from, int to) +{ + register char *text; + register int diff, i; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + /* fix boundaries */ + if (to > rl_end) + { + to = rl_end; + if (from > to) + from = to; + } + if (from < 0) + from = 0; + + text = rl_copy_text (from, to); + + /* Some versions of strncpy() can't handle overlapping arguments. */ + diff = to - from; + for (i = from; i < rl_end - diff; i++) + rl_line_buffer[i] = rl_line_buffer[i + diff]; + + /* Remember how to undo this delete. */ + if (_rl_doing_an_undo == 0) + rl_add_undo (UNDO_DELETE, from, to, text); + else + xfree (text); + + rl_end -= diff; + rl_line_buffer[rl_end] = '\0'; + _rl_fix_mark (); + return (diff); +} + +/* Fix up point so that it is within the line boundaries after killing + text. If FIX_MARK_TOO is non-zero, the mark is forced within line + boundaries also. */ + +#define _RL_FIX_POINT(x) \ + do { \ + if (x > rl_end) \ + x = rl_end; \ + else if (x < 0) \ + x = 0; \ + } while (0) + +void +_rl_fix_point (int fix_mark_too) +{ + _RL_FIX_POINT (rl_point); + if (fix_mark_too) + _RL_FIX_POINT (rl_mark); +} + +void +_rl_fix_mark (void) +{ + _RL_FIX_POINT (rl_mark); +} +#undef _RL_FIX_POINT + +/* Replace the contents of the line buffer between START and END with + TEXT. The operation is undoable. To replace the entire line in an + undoable mode, use _rl_replace_text(text, 0, rl_end); */ +int +_rl_replace_text (const char *text, int start, int end) +{ + int n; + + n = 0; + rl_begin_undo_group (); + if (start <= end) + rl_delete_text (start, end + 1); + rl_point = start; + if (*text) + n = rl_insert_text (text); + rl_end_undo_group (); + + return n; +} + +/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is + non-zero, we free the current undo list. */ +void +rl_replace_line (const char *text, int clear_undo) +{ + int len; + + len = strlen (text); + if (len >= rl_line_buffer_len) + rl_extend_line_buffer (len); + strcpy (rl_line_buffer, text); + rl_end = len; + + if (clear_undo) + rl_free_undo_list (); + + _rl_fix_point (1); +} + +/* **************************************************************** */ +/* */ +/* Readline character functions */ +/* */ +/* **************************************************************** */ + +/* This is not a gap editor, just a stupid line input routine. No hair + is involved in writing any of the functions, and none should be. */ + +/* Note that: + + rl_end is the place in the string that we would place '\0'; + i.e., it is always safe to place '\0' there. + + rl_point is the place in the string where the cursor is. Sometimes + this is the same as rl_end. + + Any command that is called interactively receives two arguments. + The first is a count: the numeric arg passed to this command. + The second is the key which invoked this command. +*/ + +/* **************************************************************** */ +/* */ +/* Movement Commands */ +/* */ +/* **************************************************************** */ + +/* Note that if you `optimize' the display for these functions, you cannot + use said functions in other functions which do not do optimizing display. + I.e., you will have to update the data base for rl_redisplay, and you + might as well let rl_redisplay do that job. */ + +/* Move forward COUNT bytes. */ +int +rl_forward_byte (int count, int key) +{ + if (count < 0) + return (rl_backward_byte (-count, key)); + + if (count > 0) + { + int end, lend; + + end = rl_point + count; +#if defined (VI_MODE) + lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end; +#else + lend = rl_end; +#endif + + if (end > lend) + { + rl_point = lend; + rl_ding (); + } + else + rl_point = end; + } + + if (rl_end < 0) + rl_end = 0; + + return 0; +} + +int +_rl_forward_char_internal (int count) +{ + int point; + +#if defined (HANDLE_MULTIBYTE) + point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + +#if defined (VI_MODE) + if (point >= rl_end && VI_COMMAND_MODE()) + point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO); +#endif + + if (rl_end < 0) + rl_end = 0; +#else + point = rl_point + count; +#endif + + if (point > rl_end) + point = rl_end; + return (point); +} + +int +_rl_backward_char_internal (int count) +{ + int point; + + point = rl_point; +#if defined (HANDLE_MULTIBYTE) + if (count > 0) + { + while (count > 0 && point > 0) + { + point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); + count--; + } + if (count > 0) + return 0; /* XXX - rl_ding() here? */ + } +#else + if (count > 0) + point -= count; +#endif + + if (point < 0) + point = 0; + return (point); +} + +#if defined (HANDLE_MULTIBYTE) +/* Move forward COUNT characters. */ +int +rl_forward_char (int count, int key) +{ + int point; + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + return (rl_forward_byte (count, key)); + + if (count < 0) + return (rl_backward_char (-count, key)); + + if (count > 0) + { + if (rl_point == rl_end && EMACS_MODE()) + { + rl_ding (); + return 0; + } + + point = _rl_forward_char_internal (count); + + if (rl_point == point) + rl_ding (); + + rl_point = point; + } + + return 0; +} +#else /* !HANDLE_MULTIBYTE */ +int +rl_forward_char (int count, int key) +{ + return (rl_forward_byte (count, key)); +} +#endif /* !HANDLE_MULTIBYTE */ + +/* Backwards compatibility. */ +int +rl_forward (int count, int key) +{ + return (rl_forward_char (count, key)); +} + +/* Move backward COUNT bytes. */ +int +rl_backward_byte (int count, int key) +{ + if (count < 0) + return (rl_forward_byte (-count, key)); + + if (count > 0) + { + if (rl_point < count) + { + rl_point = 0; + rl_ding (); + } + else + rl_point -= count; + } + + if (rl_point < 0) + rl_point = 0; + + return 0; +} + +#if defined (HANDLE_MULTIBYTE) +/* Move backward COUNT characters. */ +int +rl_backward_char (int count, int key) +{ + int point; + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + return (rl_backward_byte (count, key)); + + if (count < 0) + return (rl_forward_char (-count, key)); + + if (count > 0) + { + point = rl_point; + + while (count > 0 && point > 0) + { + point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); + count--; + } + if (count > 0) + { + rl_point = 0; + rl_ding (); + } + else + rl_point = point; + } + + return 0; +} +#else +int +rl_backward_char (int count, int key) +{ + return (rl_backward_byte (count, key)); +} +#endif + +/* Backwards compatibility. */ +int +rl_backward (int count, int key) +{ + return (rl_backward_char (count, key)); +} + +/* Move to the beginning of the line. */ +int +rl_beg_of_line (int count, int key) +{ + rl_point = 0; + return 0; +} + +/* Move to the end of the line. */ +int +rl_end_of_line (int count, int key) +{ + rl_point = rl_end; + return 0; +} + +/* Move forward a word. We do what Emacs does. Handles multibyte chars. */ +int +rl_forward_word (int count, int key) +{ + int c; + + if (count < 0) + return (rl_backward_word (-count, key)); + + while (count) + { + if (rl_point > rl_end) + rl_point = rl_end; + if (rl_point == rl_end) + return 0; + + /* If we are not in a word, move forward until we are in one. + Then, move forward until we hit a non-alphabetic character. */ + c = _rl_char_value (rl_line_buffer, rl_point); + + if (_rl_walphabetic (c) == 0) + { + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + while (rl_point < rl_end) + { + c = _rl_char_value (rl_line_buffer, rl_point); + if (_rl_walphabetic (c)) + break; + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + } + } + + if (rl_point > rl_end) + rl_point = rl_end; + if (rl_point == rl_end) + return 0; + + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + while (rl_point < rl_end) + { + c = _rl_char_value (rl_line_buffer, rl_point); + if (_rl_walphabetic (c) == 0) + break; + rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + } + + --count; + } + + return 0; +} + +/* Move backward a word. We do what Emacs does. Handles multibyte chars. */ +int +rl_backward_word (int count, int key) +{ + int c, p; + + if (count < 0) + return (rl_forward_word (-count, key)); + + while (count) + { + if (rl_point == 0) + return 0; + + /* Like rl_forward_word (), except that we look at the characters + just before point. */ + + p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + c = _rl_char_value (rl_line_buffer, p); + + if (_rl_walphabetic (c) == 0) + { + rl_point = p; + while (rl_point > 0) + { + p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + c = _rl_char_value (rl_line_buffer, p); + if (_rl_walphabetic (c)) + break; + rl_point = p; + } + } + + while (rl_point) + { + p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + c = _rl_char_value (rl_line_buffer, p); + if (_rl_walphabetic (c) == 0) + break; + else + rl_point = p; + } + + --count; + } + + return 0; +} + +/* Clear the current line. Numeric argument to C-l does this. */ +int +rl_refresh_line (int ignore1, int ignore2) +{ + _rl_refresh_line (); + rl_display_fixed = 1; + return 0; +} + +/* C-l typed to a line without quoting clears the screen, and then reprints + the prompt and the current input line. Given a numeric arg, redraw only + the current line. */ +int +rl_clear_screen (int count, int key) +{ + if (rl_explicit_arg) + { + rl_refresh_line (count, key); + return 0; + } + + _rl_clear_screen (0); /* calls termcap function to clear screen */ + rl_keep_mark_active (); + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +int +rl_clear_display (int count, int key) +{ + _rl_clear_screen (1); /* calls termcap function to clear screen and scrollback buffer */ + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +int +rl_previous_screen_line (int count, int key) +{ + int c; + + c = _rl_term_autowrap ? _rl_screenwidth : (_rl_screenwidth + 1); + return (rl_backward_char (c, key)); +} + +int +rl_next_screen_line (int count, int key) +{ + int c; + + c = _rl_term_autowrap ? _rl_screenwidth : (_rl_screenwidth + 1); + return (rl_forward_char (c, key)); +} + +int +rl_skip_csi_sequence (int count, int key) +{ + int ch; + + RL_SETSTATE (RL_STATE_MOREINPUT); + do + ch = rl_read_key (); + while (ch >= 0x20 && ch < 0x40); + RL_UNSETSTATE (RL_STATE_MOREINPUT); + + return (ch < 0); +} + +int +rl_arrow_keys (int count, int key) +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (ch < 0) + return (1); + + switch (_rl_to_upper (ch)) + { + case 'A': + rl_get_previous_history (count, ch); + break; + + case 'B': + rl_get_next_history (count, ch); + break; + + case 'C': + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_forward_char (count, ch); + else + rl_forward_byte (count, ch); + break; + + case 'D': + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_backward_char (count, ch); + else + rl_backward_byte (count, ch); + break; + + default: + rl_ding (); + } + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Text commands */ +/* */ +/* **************************************************************** */ + +#ifdef HANDLE_MULTIBYTE +static char pending_bytes[MB_LEN_MAX]; +static int pending_bytes_length = 0; +static mbstate_t ps = {0}; +#endif + +/* Insert the character C at the current location, moving point forward. + If C introduces a multibyte sequence, we read the whole sequence and + then insert the multibyte char into the line buffer. */ +int +_rl_insert_char (int count, int c) +{ + register int i; + char *string; +#ifdef HANDLE_MULTIBYTE + int string_size; + char incoming[MB_LEN_MAX + 1]; + int incoming_length = 0; + mbstate_t ps_back; + static int stored_count = 0; +#endif + + if (count <= 0) + return 0; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + incoming[0] = c; + incoming[1] = '\0'; + incoming_length = 1; + } + else if (_rl_utf8locale && (c & 0x80) == 0) + { + incoming[0] = c; + incoming[1] = '\0'; + incoming_length = 1; + } + else + { + wchar_t wc; + size_t ret; + + if (stored_count <= 0) + stored_count = count; + else + count = stored_count; + + ps_back = ps; + pending_bytes[pending_bytes_length++] = c; + ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps); + + if (ret == (size_t)-2) + { + /* Bytes too short to compose character, try to wait for next byte. + Restore the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + ps = ps_back; + return 1; + } + else if (ret == (size_t)-1) + { + /* Invalid byte sequence for the current locale. Treat first byte + as a single character. */ + incoming[0] = pending_bytes[0]; + incoming[1] = '\0'; + incoming_length = 1; + pending_bytes_length--; + memmove (pending_bytes, pending_bytes + 1, pending_bytes_length); + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (ret == (size_t)0) + { + incoming[0] = '\0'; + incoming_length = 0; + pending_bytes_length--; + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (ret == 1) + { + incoming[0] = pending_bytes[0]; + incoming[incoming_length = 1] = '\0'; + pending_bytes_length = 0; + } + else + { + /* We successfully read a single multibyte character. */ + memcpy (incoming, pending_bytes, pending_bytes_length); + incoming[pending_bytes_length] = '\0'; + incoming_length = pending_bytes_length; + pending_bytes_length = 0; + } + } +#endif /* HANDLE_MULTIBYTE */ + + /* If we can optimize, then do it. But don't let people crash + readline because of extra large arguments. */ + if (count > 1 && count <= TEXT_COUNT_MAX) + { +#if defined (HANDLE_MULTIBYTE) + string_size = count * incoming_length; + string = (char *)xmalloc (1 + string_size); + + i = 0; + while (i < string_size) + { + if (incoming_length == 1) + string[i++] = *incoming; + else + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } + } + incoming_length = 0; + stored_count = 0; +#else /* !HANDLE_MULTIBYTE */ + string = (char *)xmalloc (1 + count); + + for (i = 0; i < count; i++) + string[i] = c; +#endif /* !HANDLE_MULTIBYTE */ + + string[i] = '\0'; + rl_insert_text (string); + xfree (string); + + return 0; + } + + if (count > TEXT_COUNT_MAX) + { + int decreaser; +#if defined (HANDLE_MULTIBYTE) + string_size = incoming_length * TEXT_COUNT_MAX; + string = (char *)xmalloc (1 + string_size); + + i = 0; + while (i < string_size) + { + if (incoming_length == 1) + string[i++] = *incoming; + else + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } + } + + while (count) + { + decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count; + string[decreaser*incoming_length] = '\0'; + rl_insert_text (string); + count -= decreaser; + } + + xfree (string); + incoming_length = 0; + stored_count = 0; +#else /* !HANDLE_MULTIBYTE */ + char str[TEXT_COUNT_MAX+1]; + + for (i = 0; i < TEXT_COUNT_MAX; i++) + str[i] = c; + + while (count) + { + decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count); + str[decreaser] = '\0'; + rl_insert_text (str); + count -= decreaser; + } +#endif /* !HANDLE_MULTIBYTE */ + + return 0; + } + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + /* We are inserting a single character. + If there is pending input, then make a string of all of the + pending characters that are bound to rl_insert, and insert + them all. Don't do this if we're current reading input from + a macro. */ + if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available ()) + _rl_insert_typein (c); + else + { + /* Inserting a single character. */ + char str[2]; + + str[1] = '\0'; + str[0] = c; + rl_insert_text (str); + } + } +#if defined (HANDLE_MULTIBYTE) + else + { + rl_insert_text (incoming); + stored_count = 0; + } +#endif + + return 0; +} + +/* Overwrite the character at point (or next COUNT characters) with C. + If C introduces a multibyte character sequence, read the entire sequence + before starting the overwrite loop. */ +int +_rl_overwrite_char (int count, int c) +{ + int i; +#if defined (HANDLE_MULTIBYTE) + char mbkey[MB_LEN_MAX]; + int k; + + /* Read an entire multibyte character sequence to insert COUNT times. */ + if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) + k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); +#endif + + rl_begin_undo_group (); + + for (i = 0; i < count; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_insert_text (mbkey); + else +#endif + _rl_insert_char (1, c); + + if (rl_point < rl_end) + rl_delete (1, c); + } + + rl_end_undo_group (); + + return 0; +} + +int +rl_insert (int count, int c) +{ + int r, n, x; + + r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (count, c) : _rl_overwrite_char (count, c); + + /* XXX -- attempt to batch-insert pending input that maps to self-insert */ + x = 0; + n = (unsigned short)-2; + while (_rl_optimize_typeahead && + rl_num_chars_to_read == 0 && + (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && + _rl_pushed_input_available () == 0 && + _rl_input_queued (0) && + (n = rl_read_key ()) > 0 && + _rl_keymap[(unsigned char)n].type == ISFUNC && + _rl_keymap[(unsigned char)n].function == rl_insert) + { + r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (1, n) : _rl_overwrite_char (1, n); + /* _rl_insert_char keeps its own set of pending characters to compose a + complete multibyte character, and only returns 1 if it sees a character + that's part of a multibyte character but too short to complete one. We + can try to read another character in the hopes that we will get the + next one or just punt. Right now we try to read another character. + We don't want to call rl_insert_next if _rl_insert_char has already + stored the character in the pending_bytes array because that will + result in doubled input. */ + n = (unsigned short)-2; + x++; /* count of bytes of typeahead read, currently unused */ + if (r == 1) /* read partial multibyte character */ + continue; + if (rl_done || r != 0) + break; + } + + if (n != (unsigned short)-2) /* -2 = sentinel value for having inserted N */ + { + /* setting rl_pending_input inhibits setting rl_last_func so we do it + ourselves here */ + rl_last_func = rl_insert; + _rl_reset_argument (); + rl_executing_keyseq[rl_key_sequence_length = 0] = '\0'; + r = rl_execute_next (n); + } + + return r; +} + +/* Insert the next typed character verbatim. */ +static int +_rl_insert_next (int count) +{ + int c; + + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (c < 0) + return 1; + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (c); + +#if defined (HANDLE_SIGNALS) + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + _rl_restore_tty_signals (); +#endif + + return (_rl_insert_char (count, c)); +} + +#if defined (READLINE_CALLBACKS) +static int +_rl_insert_next_callback (_rl_callback_generic_arg *data) +{ + int count, r; + + count = data->count; + r = 0; + + if (count < 0) + { + data->count++; + r = _rl_insert_next (1); + _rl_want_redisplay = 1; + /* If we should keep going, leave the callback function installed */ + if (data->count < 0 && r == 0) + return r; + count = 0; /* data->count == 0 || r != 0; force break below */ + } + + /* Deregister function, let rl_callback_read_char deallocate data */ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + if (count == 0) + return r; + + return _rl_insert_next (count); +} +#endif + +int +rl_quoted_insert (int count, int key) +{ + /* Let's see...should the callback interface futz with signal handling? */ +#if defined (HANDLE_SIGNALS) + if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) + _rl_disable_tty_signals (); +#endif + +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_func = _rl_insert_next_callback; + return (0); + } +#endif + + /* A negative count means to quote the next -COUNT characters. */ + if (count < 0) + { + int r; + + do + r = _rl_insert_next (1); + while (r == 0 && ++count < 0); + return r; + } + + return _rl_insert_next (count); +} + +/* Insert a tab character. */ +int +rl_tab_insert (int count, int key) +{ + return (_rl_insert_char (count, '\t')); +} + +/* What to do when a NEWLINE is pressed. We accept the whole line. + KEY is the key that invoked this command. I guess it could have + meaning in the future. */ +int +rl_newline (int count, int key) +{ + if (rl_mark_active_p ()) + { + rl_deactivate_mark (); + (*rl_redisplay_function) (); + _rl_want_redisplay = 0; + } + + rl_done = 1; + + if (_rl_history_preserve_point) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + RL_SETSTATE(RL_STATE_DONE); + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + { + _rl_vi_done_inserting (); + if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */ + _rl_vi_reset_last (); + } +#endif /* VI_MODE */ + + /* If we've been asked to erase empty lines, suppress the final update, + since _rl_update_final calls rl_crlf(). */ + if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) + return 0; + + if (_rl_echoing_p) + _rl_update_final (); + return 0; +} + +/* What to do for some uppercase characters, like meta characters, + and some characters appearing in emacs_ctlx_keymap. This function + is just a stub, you bind keys to it and the code in _rl_dispatch () + is special cased. */ +int +rl_do_lowercase_version (int ignore1, int ignore2) +{ + return 0; +} + +/* This is different from what vi does, so the code's not shared. Emacs + rubout in overwrite mode has one oddity: it replaces a control + character that's displayed as two characters (^X) with two spaces. */ +int +_rl_overwrite_rubout (int count, int key) +{ + int opoint; + int i, l; + + if (rl_point == 0) + { + rl_ding (); + return 1; + } + + opoint = rl_point; + + /* L == number of spaces to insert */ + for (i = l = 0; i < count; i++) + { + rl_backward_char (1, key); + l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */ + } + + rl_begin_undo_group (); + + if (count > 1 || rl_explicit_arg) + rl_kill_text (opoint, rl_point); + else + rl_delete_text (opoint, rl_point); + + /* Emacs puts point at the beginning of the sequence of spaces. */ + if (rl_point < rl_end) + { + opoint = rl_point; + _rl_insert_char (l, ' '); + rl_point = opoint; + } + + rl_end_undo_group (); + + return 0; +} + +/* Rubout the character behind point. */ +int +rl_rubout (int count, int key) +{ + if (count < 0) + return (rl_delete (-count, key)); + + if (!rl_point) + { + rl_ding (); + return 1; + } + + if (rl_insert_mode == RL_IM_OVERWRITE) + return (_rl_overwrite_rubout (count, key)); + + return (_rl_rubout_char (count, key)); +} + +int +_rl_rubout_char (int count, int key) +{ + int orig_point; + unsigned char c; + + /* Duplicated code because this is called from other parts of the library. */ + if (count < 0) + return (rl_delete (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return 1; + } + + orig_point = rl_point; + if (count > 1 || rl_explicit_arg) + { + rl_backward_char (count, key); + rl_kill_text (orig_point, rl_point); + } + else if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + c = rl_line_buffer[--rl_point]; + rl_delete_text (rl_point, orig_point); + /* The erase-at-end-of-line hack is of questionable merit now. */ + if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos) + { + int l; + l = rl_character_len (c, rl_point); + _rl_erase_at_end_of_line (l); + } + } + else + { + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + rl_delete_text (rl_point, orig_point); + } + + return 0; +} + +/* Delete the character under the cursor. Given a numeric argument, + kill that many characters instead. */ +int +rl_delete (int count, int key) +{ + int xpoint; + + if (count < 0) + return (_rl_rubout_char (-count, key)); + + if (rl_point == rl_end) + { + rl_ding (); + return 1; + } + + if (count > 1 || rl_explicit_arg) + { + xpoint = rl_point; + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_forward_char (count, key); + else + rl_forward_byte (count, key); + + rl_kill_text (xpoint, rl_point); + rl_point = xpoint; + } + else + { + xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + rl_delete_text (rl_point, xpoint); + } + return 0; +} + +/* Delete the character under the cursor, unless the insertion + point is at the end of the line, in which case the character + behind the cursor is deleted. COUNT is obeyed and may be used + to delete forward or backward that many characters. */ +int +rl_rubout_or_delete (int count, int key) +{ + if (rl_end != 0 && rl_point == rl_end) + return (_rl_rubout_char (count, key)); + else + return (rl_delete (count, key)); +} + +/* Delete all spaces and tabs around point. */ +int +rl_delete_horizontal_space (int count, int ignore) +{ + int start; + + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + start = rl_point; + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + if (start != rl_point) + { + rl_delete_text (start, rl_point); + rl_point = start; + } + + if (rl_point < 0) + rl_point = 0; + + return 0; +} + +/* Like the tcsh editing function delete-char-or-list. The eof character + is caught before this is invoked, so this really does the same thing as + delete-char-or-list-or-eof, as long as it's bound to the eof character. */ +int +rl_delete_or_show_completions (int count, int key) +{ + if (rl_end != 0 && rl_point == rl_end) + return (rl_possible_completions (count, key)); + else + return (rl_delete (count, key)); +} + +#ifndef RL_COMMENT_BEGIN_DEFAULT +#define RL_COMMENT_BEGIN_DEFAULT "#" +#endif + +/* Turn the current line into a comment in shell history. + A K*rn shell style function. */ +int +rl_insert_comment (int count, int key) +{ + char *rl_comment_text; + int rl_comment_len; + + rl_beg_of_line (1, key); + rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT; + + if (rl_explicit_arg == 0) + rl_insert_text (rl_comment_text); + else + { + rl_comment_len = strlen (rl_comment_text); + if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len)) + rl_delete_text (rl_point, rl_point + rl_comment_len); + else + rl_insert_text (rl_comment_text); + } + + (*rl_redisplay_function) (); + rl_newline (1, '\n'); + + return (0); +} + +/* **************************************************************** */ +/* */ +/* Changing Case */ +/* */ +/* **************************************************************** */ + +/* The three kinds of things that we know how to do. */ +#define UpCase 1 +#define DownCase 2 +#define CapCase 3 + +/* Uppercase the word at point. */ +int +rl_upcase_word (int count, int key) +{ + return (rl_change_case (count, UpCase)); +} + +/* Lowercase the word at point. */ +int +rl_downcase_word (int count, int key) +{ + return (rl_change_case (count, DownCase)); +} + +/* Upcase the first letter, downcase the rest. */ +int +rl_capitalize_word (int count, int key) +{ + return (rl_change_case (count, CapCase)); +} + +/* The meaty function. + Change the case of COUNT words, performing OP on them. + OP is one of UpCase, DownCase, or CapCase. + If a negative argument is given, leave point where it started, + otherwise, leave it where it moves to. */ +static int +rl_change_case (int count, int op) +{ + int start, next, end; + int inword, nc, nop; + wchar_t c; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc, nwc; + char mb[MB_LEN_MAX+1]; + int mlen; + size_t m; + mbstate_t mps; +#endif + + start = rl_point; + rl_forward_word (count, 0); + end = rl_point; + + if (op != UpCase && op != DownCase && op != CapCase) + { + rl_ding (); + return 1; + } + + if (count < 0) + SWAP (start, end); + +#if defined (HANDLE_MULTIBYTE) + memset (&mps, 0, sizeof (mbstate_t)); +#endif + + /* We are going to modify some text, so let's prepare to undo it. */ + rl_modifying (start, end); + + inword = 0; + while (start < end) + { + c = _rl_char_value (rl_line_buffer, start); + /* This assumes that the upper and lower case versions are the same width. */ + next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO); + + if (_rl_walphabetic (c) == 0) + { + inword = 0; + start = next; + continue; + } + + if (op == CapCase) + { + nop = inword ? DownCase : UpCase; + inword = 1; + } + else + nop = op; + /* Can't check isascii here; some languages (e.g, Turkish) have + multibyte upper and lower case equivalents of single-byte ascii + characters */ + if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); + rl_line_buffer[start] = nc; + } +#if defined (HANDLE_MULTIBYTE) + else + { + m = mbrtowc (&wc, rl_line_buffer + start, end - start, &mps); + if (MB_INVALIDCH (m)) + wc = (wchar_t)rl_line_buffer[start]; + else if (MB_NULLWCH (m)) + wc = L'\0'; + nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); + if (nwc != wc) /* just skip unchanged characters */ + { + char *s, *e; + mbstate_t ts; + + memset (&ts, 0, sizeof (mbstate_t)); + mlen = wcrtomb (mb, nwc, &ts); + if (mlen < 0) + { + nwc = wc; + memset (&ts, 0, sizeof (mbstate_t)); + mlen = wcrtomb (mb, nwc, &ts); + if (mlen < 0) /* should not happen */ + strncpy (mb, rl_line_buffer + start, mlen = m); + } + if (mlen > 0) + mb[mlen] = '\0'; + /* what to do if m != mlen? adjust below */ + /* m == length of old char, mlen == length of new char */ + s = rl_line_buffer + start; + e = rl_line_buffer + rl_end; + if (m == mlen) + memcpy (s, mb, mlen); + else if (m > mlen) + { + memcpy (s, mb, mlen); + memmove (s + mlen, s + m, (e - s) - m); + next -= m - mlen; /* next char changes */ + end -= m - mlen; /* end of word changes */ + rl_end -= m - mlen; /* end of line changes */ + rl_line_buffer[rl_end] = 0; + } + else if (m < mlen) + { + rl_extend_line_buffer (rl_end + mlen + (e - s) - m + 2); + s = rl_line_buffer + start; /* have to redo this */ + e = rl_line_buffer + rl_end; + memmove (s + mlen, s + m, (e - s) - m); + memcpy (s, mb, mlen); + next += mlen - m; /* next char changes */ + end += mlen - m; /* end of word changes */ + rl_end += mlen - m; /* end of line changes */ + rl_line_buffer[rl_end] = 0; + } + } + } +#endif + + start = next; + } + + rl_point = end; + return 0; +} + +/* **************************************************************** */ +/* */ +/* Transposition */ +/* */ +/* **************************************************************** */ + +/* Transpose the words at point. If point is at the end of the line, + transpose the two words before point. */ +int +rl_transpose_words (int count, int key) +{ + char *word1, *word2; + int w1_beg, w1_end, w2_beg, w2_end; + int orig_point = rl_point; + + if (!count) + return 0; + + /* Find the two words. */ + rl_forward_word (count, key); + w2_end = rl_point; + rl_backward_word (1, key); + w2_beg = rl_point; + rl_backward_word (count, key); + w1_beg = rl_point; + rl_forward_word (1, key); + w1_end = rl_point; + + /* Do some check to make sure that there really are two words. */ + if ((w1_beg == w2_beg) || (w2_beg < w1_end)) + { + rl_ding (); + rl_point = orig_point; + return 1; + } + + /* Get the text of the words. */ + word1 = rl_copy_text (w1_beg, w1_end); + word2 = rl_copy_text (w2_beg, w2_end); + + /* We are about to do many insertions and deletions. Remember them + as one operation. */ + rl_begin_undo_group (); + + /* Do the stuff at word2 first, so that we don't have to worry + about word1 moving. */ + rl_point = w2_beg; + rl_delete_text (w2_beg, w2_end); + rl_insert_text (word1); + + rl_point = w1_beg; + rl_delete_text (w1_beg, w1_end); + rl_insert_text (word2); + + /* This is exactly correct since the text before this point has not + changed in length. */ + rl_point = w2_end; + + /* I think that does it. */ + rl_end_undo_group (); + xfree (word1); + xfree (word2); + + return 0; +} + +/* Transpose the characters at point. If point is at the end of the line, + then transpose the characters before point. */ +int +rl_transpose_chars (int count, int key) +{ +#if defined (HANDLE_MULTIBYTE) + char *dummy; + int i; +#else + char dummy[2]; +#endif + int char_length, prev_point; + + if (count == 0) + return 0; + + if (!rl_point || rl_end < 2) + { + rl_ding (); + return 1; + } + + rl_begin_undo_group (); + + if (rl_point == rl_end) + { + rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + count = 1; + } + + prev_point = rl_point; + rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO); + +#if defined (HANDLE_MULTIBYTE) + char_length = prev_point - rl_point; + dummy = (char *)xmalloc (char_length + 1); + for (i = 0; i < char_length; i++) + dummy[i] = rl_line_buffer[rl_point + i]; + dummy[i] = '\0'; +#else + dummy[0] = rl_line_buffer[rl_point]; + dummy[char_length = 1] = '\0'; +#endif + + rl_delete_text (rl_point, rl_point + char_length); + + rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + + _rl_fix_point (0); + rl_insert_text (dummy); + rl_end_undo_group (); + +#if defined (HANDLE_MULTIBYTE) + xfree (dummy); +#endif + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Character Searching */ +/* */ +/* **************************************************************** */ + +int +#if defined (HANDLE_MULTIBYTE) +_rl_char_search_internal (int count, int dir, char *smbchar, int len) +#else +_rl_char_search_internal (int count, int dir, int schar) +#endif +{ + int pos, inc; +#if defined (HANDLE_MULTIBYTE) + int prepos; +#endif + + if (dir == 0) + return 1; + + pos = rl_point; + inc = (dir < 0) ? -1 : 1; + while (count) + { + if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) + { + rl_ding (); + return 1; + } + +#if defined (HANDLE_MULTIBYTE) + pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) + : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); +#else + pos += inc; +#endif + do + { +#if defined (HANDLE_MULTIBYTE) + if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len)) +#else + if (rl_line_buffer[pos] == schar) +#endif + { + count--; + if (dir < 0) + rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) + : pos; + else + rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY) + : pos; + break; + } +#if defined (HANDLE_MULTIBYTE) + prepos = pos; +#endif + } +#if defined (HANDLE_MULTIBYTE) + while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos + : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos); +#else + while ((dir < 0) ? pos-- : ++pos < rl_end); +#endif + } + return (0); +} + +/* Search COUNT times for a character read from the current input stream. + FDIR is the direction to search if COUNT is non-negative; otherwise + the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE + that there are two separate versions of this function. */ +#if defined (HANDLE_MULTIBYTE) +static int +_rl_char_search (int count, int fdir, int bdir) +{ + char mbchar[MB_LEN_MAX]; + int mb_len; + + mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); + + if (mb_len <= 0) + return 1; + + if (count < 0) + return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); + else + return (_rl_char_search_internal (count, fdir, mbchar, mb_len)); +} +#else /* !HANDLE_MULTIBYTE */ +static int +_rl_char_search (int count, int fdir, int bdir) +{ + int c; + + c = _rl_bracketed_read_key (); + if (c < 0) + return 1; + + if (count < 0) + return (_rl_char_search_internal (-count, bdir, c)); + else + return (_rl_char_search_internal (count, fdir, c)); +} +#endif /* !HANDLE_MULTIBYTE */ + +#if defined (READLINE_CALLBACKS) +static int +_rl_char_search_callback (data) + _rl_callback_generic_arg *data; +{ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_char_search (data->count, data->i1, data->i2)); +} +#endif + +int +rl_char_search (int count, int key) +{ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_data->i1 = FFIND; + _rl_callback_data->i2 = BFIND; + _rl_callback_func = _rl_char_search_callback; + return (0); + } +#endif + + return (_rl_char_search (count, FFIND, BFIND)); +} + +int +rl_backward_char_search (int count, int key) +{ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_data->i1 = BFIND; + _rl_callback_data->i2 = FFIND; + _rl_callback_func = _rl_char_search_callback; + return (0); + } +#endif + + return (_rl_char_search (count, BFIND, FFIND)); +} + +/* **************************************************************** */ +/* */ +/* The Mark and the Region. */ +/* */ +/* **************************************************************** */ + +/* Set the mark at POSITION. */ +int +_rl_set_mark_at_pos (int position) +{ + if (position < 0 || position > rl_end) + return 1; + + rl_mark = position; + return 0; +} + +/* A bindable command to set the mark. */ +int +rl_set_mark (int count, int key) +{ + return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); +} + +/* Exchange the position of mark and point. */ +int +rl_exchange_point_and_mark (int count, int key) +{ + if (rl_mark > rl_end) + rl_mark = -1; + + if (rl_mark < 0) + { + rl_ding (); + rl_mark = 0; /* like _RL_FIX_POINT */ + return 1; + } + else + { + SWAP (rl_point, rl_mark); + rl_activate_mark (); + } + + return 0; +} + +/* Active mark support */ + +/* Is the region active? */ +static int mark_active = 0; + +/* Does the current command want the mark to remain active when it completes? */ +int _rl_keep_mark_active; + +void +rl_keep_mark_active (void) +{ + _rl_keep_mark_active++; +} + +void +rl_activate_mark (void) +{ + mark_active = 1; + rl_keep_mark_active (); +} + +void +rl_deactivate_mark (void) +{ + mark_active = 0; +} + +int +rl_mark_active_p (void) +{ + return (mark_active); +} diff --git a/utshell-0.5.0/lib/readline/tilde.c b/utshell-0.5.0/lib/readline/tilde.c new file mode 100644 index 00000000..d678a31a --- /dev/null +++ b/utshell-0.5.0/lib/readline/tilde.c @@ -0,0 +1,493 @@ +/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ + +/* Copyright (C) 1988-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#if defined (HAVE_PWD_H) +#include +#endif + +#include "tilde.h" + +#if defined (TEST) || defined (STATIC_MALLOC) +static void *xmalloc (), *xrealloc (); +#else +# include "xmalloc.h" +#endif /* TEST || STATIC_MALLOC */ + +#if !defined (HAVE_GETPW_DECLS) +# if defined (HAVE_GETPWUID) +extern struct passwd *getpwuid (uid_t); +# endif +# if defined (HAVE_GETPWNAM) +extern struct passwd *getpwnam (const char *); +# endif +#endif /* !HAVE_GETPW_DECLS */ + +#if !defined (savestring) +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif /* !savestring */ + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* If being compiled as part of bash, these will be satisfied from + variables.o. If being compiled as part of readline, they will + be satisfied from shell.o. */ +extern char *sh_get_home_dir (void); +extern char *sh_get_env_value (const char *); + +/* The default value of tilde_additional_prefixes. This is set to + whitespace preceding a tilde so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_prefixes[] = + { " ~", "\t~", (const char *)NULL }; + +/* The default value of tilde_additional_suffixes. This is set to + whitespace or newline so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_suffixes[] = + { " ", "\n", (const char *)NULL }; + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +char **tilde_additional_prefixes = (char **)default_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +char **tilde_additional_suffixes = (char **)default_suffixes; + +static int tilde_find_prefix (const char *, int *); +static int tilde_find_suffix (const char *); +static char *isolate_tilde_prefix (const char *, int *); +static char *glue_prefix_and_suffix (char *, const char *, int); + +/* Find the start of a tilde expansion in STRING, and return the index of + the tilde which starts the expansion. Place the length of the text + which identified this tilde starter in LEN, excluding the tilde itself. */ +static int +tilde_find_prefix (const char *string, int *len) +{ + register int i, j, string_len; + register char **prefixes; + + prefixes = tilde_additional_prefixes; + + string_len = strlen (string); + *len = 0; + + if (*string == '\0' || *string == '~') + return (0); + + if (prefixes) + { + for (i = 0; i < string_len; i++) + { + for (j = 0; prefixes[j]; j++) + { + if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) + { + *len = strlen (prefixes[j]) - 1; + return (i + *len); + } + } + } + } + return (string_len); +} + +/* Find the end of a tilde expansion in STRING, and return the index of + the character which ends the tilde definition. */ +static int +tilde_find_suffix (const char *string) +{ + register int i, j, string_len; + register char **suffixes; + + suffixes = tilde_additional_suffixes; + string_len = strlen (string); + + for (i = 0; i < string_len; i++) + { +#if defined (__MSDOS__) + if (string[i] == '/' || string[i] == '\\' /* || !string[i] */) +#else + if (string[i] == '/' /* || !string[i] */) +#endif + break; + + for (j = 0; suffixes && suffixes[j]; j++) + { + if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) + return (i); + } + } + return (i); +} + +/* Return a new string which is the result of tilde expanding STRING. */ +char * +tilde_expand (const char *string) +{ + char *result; + int result_size, result_index; + + result_index = result_size = 0; + if (result = strchr (string, '~')) + result = (char *)xmalloc (result_size = (strlen (string) + 16)); + else + result = (char *)xmalloc (result_size = (strlen (string) + 1)); + + /* Scan through STRING expanding tildes as we come to them. */ + while (1) + { + register int start, end; + char *tilde_word, *expansion; + int len; + + /* Make START point to the tilde which starts the expansion. */ + start = tilde_find_prefix (string, &len); + + /* Copy the skipped text into the result. */ + if ((result_index + start + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + + strncpy (result + result_index, string, start); + result_index += start; + + /* Advance STRING to the starting tilde. */ + string += start; + + /* Make END be the index of one after the last character of the + username. */ + end = tilde_find_suffix (string); + + /* If both START and END are zero, we are all done. */ + if (!start && !end) + break; + + /* Expand the entire tilde word, and copy it into RESULT. */ + tilde_word = (char *)xmalloc (1 + end); + strncpy (tilde_word, string, end); + tilde_word[end] = '\0'; + string += end; + + expansion = tilde_expand_word (tilde_word); + + if (expansion == 0) + expansion = tilde_word; + else + xfree (tilde_word); + + len = strlen (expansion); +#ifdef __CYGWIN__ + /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when + $HOME for `user' is /. On cygwin, // denotes a network drive. */ + if (len > 1 || *expansion != '/' || *string != '/') +#endif + { + if ((result_index + len + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + + strcpy (result + result_index, expansion); + result_index += len; + } + xfree (expansion); + } + + result[result_index] = '\0'; + + return (result); +} + +/* Take FNAME and return the tilde prefix we want expanded. If LENP is + non-null, the index of the end of the prefix into FNAME is returned in + the location it points to. */ +static char * +isolate_tilde_prefix (const char *fname, int *lenp) +{ + char *ret; + int i; + + ret = (char *)xmalloc (strlen (fname)); +#if defined (__MSDOS__) + for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++) +#else + for (i = 1; fname[i] && fname[i] != '/'; i++) +#endif + ret[i - 1] = fname[i]; + ret[i - 1] = '\0'; + if (lenp) + *lenp = i; + return ret; +} + +#if 0 +/* Public function to scan a string (FNAME) beginning with a tilde and find + the portion of the string that should be passed to the tilde expansion + function. Right now, it just calls tilde_find_suffix and allocates new + memory, but it can be expanded to do different things later. */ +char * +tilde_find_word (const char *fname, int flags, int *lenp) +{ + int x; + char *r; + + x = tilde_find_suffix (fname); + if (x == 0) + { + r = savestring (fname); + if (lenp) + *lenp = 0; + } + else + { + r = (char *)xmalloc (1 + x); + strncpy (r, fname, x); + r[x] = '\0'; + if (lenp) + *lenp = x; + } + + return r; +} +#endif + +/* Return a string that is PREFIX concatenated with SUFFIX starting at + SUFFIND. */ +static char * +glue_prefix_and_suffix (char *prefix, const char *suffix, int suffind) +{ + char *ret; + int plen, slen; + + plen = (prefix && *prefix) ? strlen (prefix) : 0; + slen = strlen (suffix + suffind); + ret = (char *)xmalloc (plen + slen + 1); + if (plen) + strcpy (ret, prefix); + strcpy (ret + plen, suffix + suffind); + return ret; +} + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. + This always returns a newly-allocated string, never static storage. */ +char * +tilde_expand_word (const char *filename) +{ + char *dirname, *expansion, *username; + int user_len; + struct passwd *user_entry; + + if (filename == 0) + return ((char *)NULL); + + if (*filename != '~') + return (savestring (filename)); + + /* A leading `~/' or a bare `~' is *always* translated to the value of + $HOME or the home directory of the current user, regardless of any + preexpansion hook. */ + if (filename[1] == '\0' || filename[1] == '/') + { + /* Prefix $HOME to the rest of the string. */ + expansion = sh_get_env_value ("HOME"); +#if defined (_WIN32) + if (expansion == 0) + expansion = sh_get_env_value ("APPDATA"); +#endif + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (expansion == 0) + expansion = sh_get_home_dir (); + + return (glue_prefix_and_suffix (expansion, filename, 1)); + } + + username = isolate_tilde_prefix (filename, &user_len); + + if (tilde_expansion_preexpansion_hook) + { + expansion = (*tilde_expansion_preexpansion_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + xfree (username); + xfree (expansion); + return (dirname); + } + } + + /* No preexpansion hook, or the preexpansion hook failed. Look in the + password database. */ + dirname = (char *)NULL; +#if defined (HAVE_GETPWNAM) + user_entry = getpwnam (username); +#else + user_entry = 0; +#endif + if (user_entry == 0) + { + /* If the calling program has a special syntax for expanding tildes, + and we couldn't find a standard expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + expansion = (*tilde_expansion_failure_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + xfree (expansion); + } + } + /* If we don't have a failure hook, or if the failure hook did not + expand the tilde, return a copy of what we were passed. */ + if (dirname == 0) + dirname = savestring (filename); + } +#if defined (HAVE_GETPWENT) + else + dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); +#endif + + xfree (username); +#if defined (HAVE_GETPWENT) + endpwent (); +#endif + return (dirname); +} + + +#if defined (TEST) +#undef NULL +#include + +main (int argc, char **argv) +{ + char *result, line[512]; + int done = 0; + + while (!done) + { + printf ("~expand: "); + fflush (stdout); + + if (!gets (line)) + strcpy (line, "done"); + + if ((strcmp (line, "done") == 0) || + (strcmp (line, "quit") == 0) || + (strcmp (line, "exit") == 0)) + { + done = 1; + break; + } + + result = tilde_expand (line); + printf (" --> %s\n", result); + free (result); + } + exit (0); +} + +static void memory_error_and_abort (void); + +static void * +xmalloc (size_t bytes) +{ + void *temp = (char *)malloc (bytes); + + if (!temp) + memory_error_and_abort (); + return (temp); +} + +static void * +xrealloc (void *pointer, int bytes) +{ + void *temp; + + if (!pointer) + temp = malloc (bytes); + else + temp = realloc (pointer, bytes); + + if (!temp) + memory_error_and_abort (); + + return (temp); +} + +static void +memory_error_and_abort (void) +{ + fprintf (stderr, "readline: out of virtual memory\n"); + abort (); +} + +/* + * Local variables: + * compile-command: "gcc -g -DTEST -o tilde tilde.c" + * end: + */ +#endif /* TEST */ diff --git a/utshell-0.5.0/lib/readline/tilde.h b/utshell-0.5.0/lib/readline/tilde.h new file mode 100644 index 00000000..e26dd047 --- /dev/null +++ b/utshell-0.5.0/lib/readline/tilde.h @@ -0,0 +1,80 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992-2009 Free Software Foundation, Inc. + + This file contains the Readline Library (Readline), a set of + routines for providing Emacs style line input to programs that ask + for it. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +/* Find the portion of the string beginning with ~ that should be expanded. */ +extern char *tilde_find_word PARAMS((const char *, int, int *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/utshell-0.5.0/lib/readline/undo.c b/utshell-0.5.0/lib/readline/undo.c new file mode 100644 index 00000000..14799911 --- /dev/null +++ b/utshell-0.5.0/lib/readline/undo.c @@ -0,0 +1,367 @@ +/* undo.c - manage list of changes to lines, offering opportunity to undo them */ + +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +extern void _hs_replace_history_data PARAMS((int, histdata_t *, histdata_t *)); + +extern HIST_ENTRY *_rl_saved_line_for_history; + +/* Non-zero tells rl_delete_text and rl_insert_text to not add to + the undo list. */ +int _rl_doing_an_undo = 0; + +/* How many unclosed undo groups we currently have. */ +int _rl_undo_group_level = 0; + +/* The current undo list for THE_LINE. */ +UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; + +/* **************************************************************** */ +/* */ +/* Undo, and Undoing */ +/* */ +/* **************************************************************** */ + +static UNDO_LIST * +alloc_undo_entry (enum undo_code what, int start, int end, char *text) +{ + UNDO_LIST *temp; + + temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); + temp->what = what; + temp->start = start; + temp->end = end; + temp->text = text; + + temp->next = (UNDO_LIST *)NULL; + return temp; +} + +/* Remember how to undo something. Concatenate some undos if that + seems right. */ +void +rl_add_undo (enum undo_code what, int start, int end, char *text) +{ + UNDO_LIST *temp; + + temp = alloc_undo_entry (what, start, end, text); + temp->next = rl_undo_list; + rl_undo_list = temp; +} + +/* Free an UNDO_LIST */ +void +_rl_free_undo_list (UNDO_LIST *ul) +{ + UNDO_LIST *release; + + while (ul) + { + release = ul; + ul = ul->next; + + if (release->what == UNDO_DELETE) + xfree (release->text); + + xfree (release); + } +} + +/* Free the existing undo list. */ +void +rl_free_undo_list (void) +{ + UNDO_LIST *release, *orig_list; + + orig_list = rl_undo_list; + _rl_free_undo_list (rl_undo_list); + rl_undo_list = (UNDO_LIST *)NULL; + _hs_replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL); +} + +UNDO_LIST * +_rl_copy_undo_entry (UNDO_LIST *entry) +{ + UNDO_LIST *new; + + new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL); + new->text = entry->text ? savestring (entry->text) : 0; + return new; +} + +UNDO_LIST * +_rl_copy_undo_list (UNDO_LIST *head) +{ + UNDO_LIST *list, *new, *roving, *c; + + if (head == 0) + return head; + + list = head; + new = 0; + while (list) + { + c = _rl_copy_undo_entry (list); + if (new == 0) + roving = new = c; + else + { + roving->next = c; + roving = roving->next; + } + list = list->next; + } + + roving->next = 0; + return new; +} + +/* Undo the next thing in the list. Return 0 if there + is nothing to undo, or non-zero if there was. */ +int +rl_do_undo (void) +{ + UNDO_LIST *release, *search; + int waiting_for_begin, start, end; + HIST_ENTRY *cur, *temp; + +#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) + + start = end = waiting_for_begin = 0; + do + { + if (rl_undo_list == 0) + return (0); + + _rl_doing_an_undo = 1; + RL_SETSTATE(RL_STATE_UNDOING); + + /* To better support vi-mode, a start or end value of -1 means + rl_point, and a value of -2 means rl_end. */ + if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT) + { + start = TRANS (rl_undo_list->start); + end = TRANS (rl_undo_list->end); + } + + switch (rl_undo_list->what) + { + /* Undoing deletes means inserting some text. */ + case UNDO_DELETE: + rl_point = start; + _rl_fix_point (1); + rl_insert_text (rl_undo_list->text); + xfree (rl_undo_list->text); + break; + + /* Undoing inserts means deleting some text. */ + case UNDO_INSERT: + rl_delete_text (start, end); + rl_point = start; + _rl_fix_point (1); + break; + + /* Undoing an END means undoing everything 'til we get to a BEGIN. */ + case UNDO_END: + waiting_for_begin++; + break; + + /* Undoing a BEGIN means that we are done with this group. */ + case UNDO_BEGIN: + if (waiting_for_begin) + waiting_for_begin--; + else + rl_ding (); + break; + } + + _rl_doing_an_undo = 0; + RL_UNSETSTATE(RL_STATE_UNDOING); + + release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + release->next = 0; /* XXX */ + + /* If we are editing a history entry, make sure the change is replicated + in the history entry's line */ + cur = current_history (); + if (cur && cur->data && (UNDO_LIST *)cur->data == release) + { + temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); + xfree (temp->line); + FREE (temp->timestamp); + xfree (temp); + } + + /* Make sure there aren't any history entries with that undo list */ + _hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list); + + /* And make sure this list isn't anywhere in the saved line for history */ + if (_rl_saved_line_for_history && _rl_saved_line_for_history->data) + { + /* Brute force; no finesse here */ + search = (UNDO_LIST *)_rl_saved_line_for_history->data; + if (search == release) + _rl_saved_line_for_history->data = rl_undo_list; + else + { + while (search->next) + { + if (search->next == release) + { + search->next = rl_undo_list; + break; + } + search = search->next; + } + } + } + + xfree (release); + } + while (waiting_for_begin); + + return (1); +} +#undef TRANS + +int +_rl_fix_last_undo_of_type (int type, int start, int end) +{ + UNDO_LIST *rl; + + for (rl = rl_undo_list; rl; rl = rl->next) + { + if (rl->what == type) + { + rl->start = start; + rl->end = end; + return 0; + } + } + return 1; +} + +/* Begin a group. Subsequent undos are undone as an atomic operation. */ +int +rl_begin_undo_group (void) +{ + rl_add_undo (UNDO_BEGIN, 0, 0, 0); + _rl_undo_group_level++; + return 0; +} + +/* End an undo group started with rl_begin_undo_group (). */ +int +rl_end_undo_group (void) +{ + rl_add_undo (UNDO_END, 0, 0, 0); + _rl_undo_group_level--; + return 0; +} + +/* Save an undo entry for the text from START to END. */ +int +rl_modifying (int start, int end) +{ + if (start > end) + { + SWAP (start, end); + } + + if (start != end) + { + char *temp = rl_copy_text (start, end); + rl_begin_undo_group (); + rl_add_undo (UNDO_DELETE, start, end, temp); + rl_add_undo (UNDO_INSERT, start, end, (char *)NULL); + rl_end_undo_group (); + } + return 0; +} + +/* Revert the current line to its previous state. */ +int +rl_revert_line (int count, int key) +{ + if (rl_undo_list == 0) + rl_ding (); + else + { + while (rl_undo_list) + rl_do_undo (); +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_point = rl_mark = 0; /* rl_end should be set correctly */ +#endif + } + + return 0; +} + +/* Do some undoing of things that were done. */ +int +rl_undo_command (int count, int key) +{ + if (count < 0) + return 0; /* Nothing to do. */ + + while (count) + { + if (rl_do_undo ()) + count--; + else + { + rl_ding (); + break; + } + } + return 0; +} diff --git a/utshell-0.5.0/lib/readline/util.c b/utshell-0.5.0/lib/readline/util.c new file mode 100644 index 00000000..1576b55d --- /dev/null +++ b/utshell-0.5.0/lib/readline/util.c @@ -0,0 +1,576 @@ +/* util.c -- readline utility functions */ + +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixjmp.h" + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "xmalloc.h" +#include "rlshell.h" + +/* **************************************************************** */ +/* */ +/* Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Return 0 if C is not a member of the class of characters that belong + in words, or 1 if it is. */ + +int _rl_allow_pathname_alphabetic_chars = 0; +static const char * const pathname_alphabetic_chars = "/-_=~.#$"; + +int +rl_alphabetic (int c) +{ + if (ALPHABETIC (c)) + return (1); + + return (_rl_allow_pathname_alphabetic_chars && + strchr (pathname_alphabetic_chars, c) != NULL); +} + +#if defined (HANDLE_MULTIBYTE) +int +_rl_walphabetic (wchar_t wc) +{ + int c; + + if (iswalnum (wc)) + return (1); + + c = wc & 0177; + return (_rl_allow_pathname_alphabetic_chars && + strchr (pathname_alphabetic_chars, c) != NULL); +} +#endif + +/* How to abort things. */ +int +_rl_abort_internal (void) +{ + rl_ding (); + rl_clear_message (); + _rl_reset_argument (); + rl_clear_pending_input (); + rl_deactivate_mark (); + + while (rl_executing_macro) + _rl_pop_executing_macro (); + _rl_kill_kbd_macro (); + + RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */ + + rl_last_func = (rl_command_func_t *)NULL; + + _rl_longjmp (_rl_top_level, 1); + return (0); +} + +int +rl_abort (int count, int key) +{ + return (_rl_abort_internal ()); +} + +int +_rl_null_function (int count, int key) +{ + return 0; +} + +int +rl_tty_status (int count, int key) +{ +#if defined (TIOCSTAT) + ioctl (1, TIOCSTAT, (char *)0); + rl_refresh_line (count, key); +#else + rl_ding (); +#endif + return 0; +} + +/* Return a copy of the string between FROM and TO. + FROM is inclusive, TO is not. */ +char * +rl_copy_text (int from, int to) +{ + register int length; + char *copy; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + length = to - from; + copy = (char *)xmalloc (1 + length); + strncpy (copy, rl_line_buffer + from, length); + copy[length] = '\0'; + return (copy); +} + +/* Increase the size of RL_LINE_BUFFER until it has enough space to hold + LEN characters. */ +void +rl_extend_line_buffer (int len) +{ + while (len >= rl_line_buffer_len) + { + rl_line_buffer_len += DEFAULT_BUFFER_SIZE; + rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); + } + + _rl_set_the_line (); +} + + +/* A function for simple tilde expansion. */ +int +rl_tilde_expand (int ignore, int key) +{ + register int start, end; + char *homedir, *temp; + int len; + + end = rl_point; + start = end - 1; + + if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') + { + homedir = tilde_expand ("~"); + _rl_replace_text (homedir, start, end); + xfree (homedir); + return (0); + } + else if (start >= 0 && rl_line_buffer[start] != '~') + { + for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--) + ; + start++; + } + else if (start < 0) + start = 0; + + end = start; + do + end++; + while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); + + if (whitespace (rl_line_buffer[end]) || end >= rl_end) + end--; + + /* If the first character of the current word is a tilde, perform + tilde expansion and insert the result. If not a tilde, do + nothing. */ + if (rl_line_buffer[start] == '~') + { + len = end - start + 1; + temp = (char *)xmalloc (len + 1); + strncpy (temp, rl_line_buffer + start, len); + temp[len] = '\0'; + homedir = tilde_expand (temp); + xfree (temp); + + _rl_replace_text (homedir, start, end); + xfree (homedir); + } + + return (0); +} + +#if defined (USE_VARARGS) +void +#if defined (PREFER_STDARG) +_rl_ttymsg (const char *format, ...) +#else +_rl_ttymsg (va_alist) + va_dcl +#endif +{ + va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + + fprintf (stderr, "readline: "); + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + fflush (stderr); + + va_end (args); + + rl_forced_update_display (); +} + +void +#if defined (PREFER_STDARG) +_rl_errmsg (const char *format, ...) +#else +_rl_errmsg (va_alist) + va_dcl +#endif +{ + va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + + fprintf (stderr, "readline: "); + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + fflush (stderr); + + va_end (args); +} + +#else /* !USE_VARARGS */ +void +_rl_ttymsg (format, arg1, arg2) + char *format; +{ + fprintf (stderr, "readline: "); + fprintf (stderr, format, arg1, arg2); + fprintf (stderr, "\n"); + + rl_forced_update_display (); +} + +void +_rl_errmsg (format, arg1, arg2) + char *format; +{ + fprintf (stderr, "readline: "); + fprintf (stderr, format, arg1, arg2); + fprintf (stderr, "\n"); +} +#endif /* !USE_VARARGS */ + +/* **************************************************************** */ +/* */ +/* String Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Determine if s2 occurs in s1. If so, return a pointer to the + match in s1. The compare is case insensitive. */ +char * +_rl_strindex (const char *s1, const char *s2) +{ + register int i, l, len; + + for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) + if (_rl_strnicmp (s1 + i, s2, l) == 0) + return ((char *) (s1 + i)); + return ((char *)NULL); +} + +#ifndef HAVE_STRPBRK +/* Find the first occurrence in STRING1 of any character from STRING2. + Return a pointer to the character in STRING1. */ +char * +_rl_strpbrk (const char *string1, const char *string2) +{ + register const char *scan; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + register int i, v; + + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + for (; *string1; string1++) + { + for (scan = string2; *scan; scan++) + { + if (*string1 == *scan) + return ((char *)string1); + } +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + v = _rl_get_char_len (string1, &ps); + if (v > 1) + string1 += v - 1; /* -1 to account for auto-increment in loop */ + } +#endif + } + return ((char *)NULL); +} +#endif + +#if !defined (HAVE_STRCASECMP) +/* Compare at most COUNT characters from string1 to string2. Case + doesn't matter (strncasecmp). */ +int +_rl_strnicmp (const char *string1, const char *string2, int count) +{ + register const char *s1; + register const char *s2; + register int d; + + if (count <= 0 || (string1 == string2)) + return 0; + + s1 = string1; + s2 = string2; + do + { + d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */ + if (d != 0) + return d; + if (*s1++ == '\0') + break; + s2++; + } + while (--count != 0); + + return (0); +} + +/* strcmp (), but caseless (strcasecmp). */ +int +_rl_stricmp (const char *string1, const char *string2) +{ + register const char *s1; + register const char *s2; + register int d; + + s1 = string1; + s2 = string2; + + if (s1 == s2) + return 0; + + while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0) + { + if (*s1++ == '\0') + return 0; + s2++; + } + + return (d); +} +#endif /* !HAVE_STRCASECMP */ + +/* Stupid comparison routine for qsort () ing strings. */ +int +_rl_qsort_string_compare (char **s1, char **s2) +{ +#if defined (HAVE_STRCOLL) + return (strcoll (*s1, *s2)); +#else + int result; + + result = **s1 - **s2; + if (result == 0) + result = strcmp (*s1, *s2); + + return result; +#endif +} + +/* Function equivalents for the macros defined in chardefs.h. */ +#define FUNCTION_FOR_MACRO(f) int (f) (int c) { return f (c); } + +FUNCTION_FOR_MACRO (_rl_digit_p) +FUNCTION_FOR_MACRO (_rl_digit_value) +FUNCTION_FOR_MACRO (_rl_lowercase_p) +FUNCTION_FOR_MACRO (_rl_pure_alphabetic) +FUNCTION_FOR_MACRO (_rl_to_lower) +FUNCTION_FOR_MACRO (_rl_to_upper) +FUNCTION_FOR_MACRO (_rl_uppercase_p) + +/* A convenience function, to force memory deallocation to be performed + by readline. DLLs on Windows apparently require this. */ +void +rl_free (void *mem) +{ + if (mem) + free (mem); +} + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +#undef _rl_savestring +char * +_rl_savestring (const char *s) +{ + return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); +} + +#if defined (DEBUG) +#if defined (USE_VARARGS) +static FILE *_rl_tracefp; + +void +#if defined (PREFER_STDARG) +_rl_trace (const char *format, ...) +#else +_rl_trace (va_alist) + va_dcl +#endif +{ + va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + + if (_rl_tracefp == 0) + _rl_tropen (); + vfprintf (_rl_tracefp, format, args); + fprintf (_rl_tracefp, "\n"); + fflush (_rl_tracefp); + + va_end (args); +} + +int +_rl_tropen (void) +{ + char fnbuf[128], *x; + + if (_rl_tracefp) + fclose (_rl_tracefp); +#if defined (_WIN32) && !defined (__CYGWIN__) + x = sh_get_env_value ("TEMP"); + if (x == 0) + x = "."; +#else + x = "/var/tmp"; +#endif + snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld", x, (long)getpid()); + unlink(fnbuf); + _rl_tracefp = fopen (fnbuf, "w+"); + return _rl_tracefp != 0; +} + +int +_rl_trclose (void) +{ + int r; + + r = fclose (_rl_tracefp); + _rl_tracefp = 0; + return r; +} + +void +_rl_settracefp (FILE *fp) +{ + _rl_tracefp = fp; +} +#endif +#endif /* DEBUG */ + + +#if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT) +#include +#include +#include +#include + +/* Report STRING to the audit system. */ +void +_rl_audit_tty (char *string) +{ + struct audit_message req; + struct sockaddr_nl addr; + size_t size; + int fd; + + fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_AUDIT); + if (fd < 0) + return; + size = strlen (string) + 1; + + if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH) + return; + + memset (&req, 0, sizeof(req)); + req.nlh.nlmsg_len = NLMSG_SPACE (size); + req.nlh.nlmsg_type = AUDIT_USER_TTY; + req.nlh.nlmsg_flags = NLM_F_REQUEST; + req.nlh.nlmsg_seq = 0; + if (size && string) + memcpy (NLMSG_DATA(&req.nlh), string, size); + memset (&addr, 0, sizeof(addr)); + + addr.nl_family = AF_NETLINK; + addr.nl_pid = 0; + addr.nl_groups = 0; + + sendto (fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr)); + close (fd); +} +#endif diff --git a/utshell-0.5.0/lib/readline/vi_keymap.c b/utshell-0.5.0/lib/readline/vi_keymap.c new file mode 100644 index 00000000..045258bd --- /dev/null +++ b/utshell-0.5.0/lib/readline/vi_keymap.c @@ -0,0 +1,875 @@ +/* vi_keymap.c -- the keymap for vi_mode in readline (). */ + +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (BUFSIZ) +#include +#endif /* !BUFSIZ */ + +#include "readline.h" + +#if 0 +extern KEYMAP_ENTRY_ARRAY vi_escape_keymap; +#endif + +/* The keymap arrays for handling vi mode. */ +KEYMAP_ENTRY_ARRAY vi_movement_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ + { ISFUNC, rl_emacs_editing_mode }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, rl_backward_char }, /* Control-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, rl_clear_screen }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_get_next_history }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, rl_get_previous_history }, /* Control-p */ + { ISFUNC, rl_quoted_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_vi_unix_word_rubout }, /* Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_forward_char }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, rl_insert_comment }, /* # */ + { ISFUNC, rl_end_of_line }, /* $ */ + { ISFUNC, rl_vi_match }, /* % */ + { ISFUNC, rl_vi_tilde_expand }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */ + { ISFUNC, rl_vi_complete }, /* * */ + { ISFUNC, rl_get_next_history}, /* + */ + { ISFUNC, rl_vi_char_search }, /* , */ + { ISFUNC, rl_get_previous_history }, /* - */ + { ISFUNC, rl_vi_redo }, /* . */ + { ISFUNC, rl_vi_search }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_beg_of_line }, /* 0 */ + { ISFUNC, rl_vi_arg_digit }, /* 1 */ + { ISFUNC, rl_vi_arg_digit }, /* 2 */ + { ISFUNC, rl_vi_arg_digit }, /* 3 */ + { ISFUNC, rl_vi_arg_digit }, /* 4 */ + { ISFUNC, rl_vi_arg_digit }, /* 5 */ + { ISFUNC, rl_vi_arg_digit }, /* 6 */ + { ISFUNC, rl_vi_arg_digit }, /* 7 */ + { ISFUNC, rl_vi_arg_digit }, /* 8 */ + { ISFUNC, rl_vi_arg_digit }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, rl_vi_char_search }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, rl_vi_complete }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, rl_vi_search }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_vi_append_eol }, /* A */ + { ISFUNC, rl_vi_prev_word}, /* B */ + { ISFUNC, rl_vi_change_to }, /* C */ + { ISFUNC, rl_vi_delete_to }, /* D */ + { ISFUNC, rl_vi_end_word }, /* E */ + { ISFUNC, rl_vi_char_search }, /* F */ + { ISFUNC, rl_vi_fetch_history }, /* G */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* H */ + { ISFUNC, rl_vi_insert_beg }, /* I */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* J */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* K */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* L */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* M */ + { ISFUNC, rl_vi_search_again }, /* N */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* O */ + { ISFUNC, rl_vi_put }, /* P */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Q */ + { ISFUNC, rl_vi_replace }, /* R */ + { ISFUNC, rl_vi_subst }, /* S */ + { ISFUNC, rl_vi_char_search }, /* T */ + { ISFUNC, rl_revert_line }, /* U */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* V */ + { ISFUNC, rl_vi_next_word }, /* W */ + { ISFUNC, rl_vi_rubout }, /* X */ + { ISFUNC, rl_vi_yank_to }, /* Y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */ + { ISFUNC, rl_vi_complete }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, rl_vi_first_print }, /* ^ */ + { ISFUNC, rl_vi_yank_arg }, /* _ */ + { ISFUNC, rl_vi_goto_mark }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_vi_append_mode }, /* a */ + { ISFUNC, rl_vi_prev_word }, /* b */ + { ISFUNC, rl_vi_change_to }, /* c */ + { ISFUNC, rl_vi_delete_to }, /* d */ + { ISFUNC, rl_vi_end_word }, /* e */ + { ISFUNC, rl_vi_char_search }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, rl_backward_char }, /* h */ + { ISFUNC, rl_vi_insert_mode }, /* i */ + { ISFUNC, rl_get_next_history }, /* j */ + { ISFUNC, rl_get_previous_history }, /* k */ + { ISFUNC, rl_forward_char }, /* l */ + { ISFUNC, rl_vi_set_mark }, /* m */ + { ISFUNC, rl_vi_search_again }, /* n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* o */ + { ISFUNC, rl_vi_put }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, rl_vi_change_char }, /* r */ + { ISFUNC, rl_vi_subst }, /* s */ + { ISFUNC, rl_vi_char_search }, /* t */ + { ISFUNC, rl_vi_undo }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, rl_vi_next_word }, /* w */ + { ISFUNC, rl_vi_delete }, /* x */ + { ISFUNC, rl_vi_yank_to }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, rl_vi_column }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, rl_vi_change_case }, /* ~ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, rl_insert }, /* Control-a */ + { ISFUNC, rl_insert }, /* Control-b */ + { ISFUNC, rl_insert }, /* Control-c */ + { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ + { ISFUNC, rl_insert }, /* Control-e */ + { ISFUNC, rl_insert }, /* Control-f */ + { ISFUNC, rl_insert }, /* Control-g */ + { ISFUNC, rl_rubout }, /* Control-h */ + { ISFUNC, rl_complete }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_insert }, /* Control-k */ + { ISFUNC, rl_insert }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_menu_complete}, /* Control-n */ + { ISFUNC, rl_insert }, /* Control-o */ + { ISFUNC, rl_backward_menu_complete }, /* Control-p */ + { ISFUNC, rl_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_vi_unix_word_rubout }, /* Control-w */ + { ISFUNC, rl_insert }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, rl_insert }, /* Control-z */ + + { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ + { ISFUNC, rl_insert }, /* Control-\ */ + { ISFUNC, rl_insert }, /* Control-] */ + { ISFUNC, rl_insert }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_insert }, /* SPACE */ + { ISFUNC, rl_insert }, /* ! */ + { ISFUNC, rl_insert }, /* " */ + { ISFUNC, rl_insert }, /* # */ + { ISFUNC, rl_insert }, /* $ */ + { ISFUNC, rl_insert }, /* % */ + { ISFUNC, rl_insert }, /* & */ + { ISFUNC, rl_insert }, /* ' */ + { ISFUNC, rl_insert }, /* ( */ + { ISFUNC, rl_insert }, /* ) */ + { ISFUNC, rl_insert }, /* * */ + { ISFUNC, rl_insert }, /* + */ + { ISFUNC, rl_insert }, /* , */ + { ISFUNC, rl_insert }, /* - */ + { ISFUNC, rl_insert }, /* . */ + { ISFUNC, rl_insert }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_insert }, /* 0 */ + { ISFUNC, rl_insert }, /* 1 */ + { ISFUNC, rl_insert }, /* 2 */ + { ISFUNC, rl_insert }, /* 3 */ + { ISFUNC, rl_insert }, /* 4 */ + { ISFUNC, rl_insert }, /* 5 */ + { ISFUNC, rl_insert }, /* 6 */ + { ISFUNC, rl_insert }, /* 7 */ + { ISFUNC, rl_insert }, /* 8 */ + { ISFUNC, rl_insert }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, rl_insert }, /* : */ + { ISFUNC, rl_insert }, /* ; */ + { ISFUNC, rl_insert }, /* < */ + { ISFUNC, rl_insert }, /* = */ + { ISFUNC, rl_insert }, /* > */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_insert }, /* A */ + { ISFUNC, rl_insert }, /* B */ + { ISFUNC, rl_insert }, /* C */ + { ISFUNC, rl_insert }, /* D */ + { ISFUNC, rl_insert }, /* E */ + { ISFUNC, rl_insert }, /* F */ + { ISFUNC, rl_insert }, /* G */ + { ISFUNC, rl_insert }, /* H */ + { ISFUNC, rl_insert }, /* I */ + { ISFUNC, rl_insert }, /* J */ + { ISFUNC, rl_insert }, /* K */ + { ISFUNC, rl_insert }, /* L */ + { ISFUNC, rl_insert }, /* M */ + { ISFUNC, rl_insert }, /* N */ + { ISFUNC, rl_insert }, /* O */ + { ISFUNC, rl_insert }, /* P */ + { ISFUNC, rl_insert }, /* Q */ + { ISFUNC, rl_insert }, /* R */ + { ISFUNC, rl_insert }, /* S */ + { ISFUNC, rl_insert }, /* T */ + { ISFUNC, rl_insert }, /* U */ + { ISFUNC, rl_insert }, /* V */ + { ISFUNC, rl_insert }, /* W */ + { ISFUNC, rl_insert }, /* X */ + { ISFUNC, rl_insert }, /* Y */ + { ISFUNC, rl_insert }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_insert }, /* [ */ + { ISFUNC, rl_insert }, /* \ */ + { ISFUNC, rl_insert }, /* ] */ + { ISFUNC, rl_insert }, /* ^ */ + { ISFUNC, rl_insert }, /* _ */ + { ISFUNC, rl_insert }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_insert }, /* a */ + { ISFUNC, rl_insert }, /* b */ + { ISFUNC, rl_insert }, /* c */ + { ISFUNC, rl_insert }, /* d */ + { ISFUNC, rl_insert }, /* e */ + { ISFUNC, rl_insert }, /* f */ + { ISFUNC, rl_insert }, /* g */ + { ISFUNC, rl_insert }, /* h */ + { ISFUNC, rl_insert }, /* i */ + { ISFUNC, rl_insert }, /* j */ + { ISFUNC, rl_insert }, /* k */ + { ISFUNC, rl_insert }, /* l */ + { ISFUNC, rl_insert }, /* m */ + { ISFUNC, rl_insert }, /* n */ + { ISFUNC, rl_insert }, /* o */ + { ISFUNC, rl_insert }, /* p */ + { ISFUNC, rl_insert }, /* q */ + { ISFUNC, rl_insert }, /* r */ + { ISFUNC, rl_insert }, /* s */ + { ISFUNC, rl_insert }, /* t */ + { ISFUNC, rl_insert }, /* u */ + { ISFUNC, rl_insert }, /* v */ + { ISFUNC, rl_insert }, /* w */ + { ISFUNC, rl_insert }, /* x */ + { ISFUNC, rl_insert }, /* y */ + { ISFUNC, rl_insert }, /* z */ + + /* Final punctuation. */ + { ISFUNC, rl_insert }, /* { */ + { ISFUNC, rl_insert }, /* | */ + { ISFUNC, rl_insert }, /* } */ + { ISFUNC, rl_insert }, /* ~ */ + { ISFUNC, rl_rubout }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Pure 8-bit characters (128 - 159). + These might be used in some + character sets. */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + + /* ISO Latin-1 characters (160 - 255) */ + { ISFUNC, rl_insert }, /* No-break space */ + { ISFUNC, rl_insert }, /* Inverted exclamation mark */ + { ISFUNC, rl_insert }, /* Cent sign */ + { ISFUNC, rl_insert }, /* Pound sign */ + { ISFUNC, rl_insert }, /* Currency sign */ + { ISFUNC, rl_insert }, /* Yen sign */ + { ISFUNC, rl_insert }, /* Broken bar */ + { ISFUNC, rl_insert }, /* Section sign */ + { ISFUNC, rl_insert }, /* Diaeresis */ + { ISFUNC, rl_insert }, /* Copyright sign */ + { ISFUNC, rl_insert }, /* Feminine ordinal indicator */ + { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Not sign */ + { ISFUNC, rl_insert }, /* Soft hyphen */ + { ISFUNC, rl_insert }, /* Registered sign */ + { ISFUNC, rl_insert }, /* Macron */ + { ISFUNC, rl_insert }, /* Degree sign */ + { ISFUNC, rl_insert }, /* Plus-minus sign */ + { ISFUNC, rl_insert }, /* Superscript two */ + { ISFUNC, rl_insert }, /* Superscript three */ + { ISFUNC, rl_insert }, /* Acute accent */ + { ISFUNC, rl_insert }, /* Micro sign */ + { ISFUNC, rl_insert }, /* Pilcrow sign */ + { ISFUNC, rl_insert }, /* Middle dot */ + { ISFUNC, rl_insert }, /* Cedilla */ + { ISFUNC, rl_insert }, /* Superscript one */ + { ISFUNC, rl_insert }, /* Masculine ordinal indicator */ + { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */ + { ISFUNC, rl_insert }, /* Vulgar fraction one half */ + { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */ + { ISFUNC, rl_insert }, /* Inverted questionk mark */ + { ISFUNC, rl_insert }, /* Latin capital letter a with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter a with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin capital letter ae */ + { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin capital letter e with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter e with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter i with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter i with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter o with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Multiplication sign */ + { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin capital letter u with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter u with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */ + { ISFUNC, rl_insert }, /* Latin small letter a with grave */ + { ISFUNC, rl_insert }, /* Latin small letter a with acute */ + { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin small letter ae */ + { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin small letter e with grave */ + { ISFUNC, rl_insert }, /* Latin small letter e with acute */ + { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter i with grave */ + { ISFUNC, rl_insert }, /* Latin small letter i with acute */ + { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with grave */ + { ISFUNC, rl_insert }, /* Latin small letter o with acute */ + { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Division sign */ + { ISFUNC, rl_insert }, /* Latin small letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin small letter u with grave */ + { ISFUNC, rl_insert }, /* Latin small letter u with acute */ + { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter y with acute */ + { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */ + { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */ +#endif /* KEYMAP_SIZE > 128 */ +}; + +/* Unused for the time being. */ +#if 0 +KEYMAP_ENTRY_ARRAY vi_escape_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */ + { ISFUNC, rl_tab_insert}, /* Control-i */ + { ISFUNC, rl_emacs_editing_mode}, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */ + { ISFUNC, rl_emacs_editing_mode}, /* Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + + { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* # */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* % */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* * */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* + */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* , */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* - */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* . */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_vi_arg_digit }, /* 0 */ + { ISFUNC, rl_vi_arg_digit }, /* 1 */ + { ISFUNC, rl_vi_arg_digit }, /* 2 */ + { ISFUNC, rl_vi_arg_digit }, /* 3 */ + { ISFUNC, rl_vi_arg_digit }, /* 4 */ + { ISFUNC, rl_vi_arg_digit }, /* 5 */ + { ISFUNC, rl_vi_arg_digit }, /* 6 */ + { ISFUNC, rl_vi_arg_digit }, /* 7 */ + { ISFUNC, rl_vi_arg_digit }, /* 8 */ + { ISFUNC, rl_vi_arg_digit }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* A */ + { ISFUNC, rl_do_lowercase_version }, /* B */ + { ISFUNC, rl_do_lowercase_version }, /* C */ + { ISFUNC, rl_do_lowercase_version }, /* D */ + { ISFUNC, rl_do_lowercase_version }, /* E */ + { ISFUNC, rl_do_lowercase_version }, /* F */ + { ISFUNC, rl_do_lowercase_version }, /* G */ + { ISFUNC, rl_do_lowercase_version }, /* H */ + { ISFUNC, rl_do_lowercase_version }, /* I */ + { ISFUNC, rl_do_lowercase_version }, /* J */ + { ISFUNC, rl_do_lowercase_version }, /* K */ + { ISFUNC, rl_do_lowercase_version }, /* L */ + { ISFUNC, rl_do_lowercase_version }, /* M */ + { ISFUNC, rl_do_lowercase_version }, /* N */ + { ISFUNC, rl_do_lowercase_version }, /* O */ + { ISFUNC, rl_do_lowercase_version }, /* P */ + { ISFUNC, rl_do_lowercase_version }, /* Q */ + { ISFUNC, rl_do_lowercase_version }, /* R */ + { ISFUNC, rl_do_lowercase_version }, /* S */ + { ISFUNC, rl_do_lowercase_version }, /* T */ + { ISFUNC, rl_do_lowercase_version }, /* U */ + { ISFUNC, rl_do_lowercase_version }, /* V */ + { ISFUNC, rl_do_lowercase_version }, /* W */ + { ISFUNC, rl_do_lowercase_version }, /* X */ + { ISFUNC, rl_do_lowercase_version }, /* Y */ + { ISFUNC, rl_do_lowercase_version }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_arrow_keys }, /* [ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* n */ + { ISFUNC, rl_arrow_keys }, /* o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */ + { ISFUNC, rl_backward_kill_word }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; +#endif diff --git a/utshell-0.5.0/lib/readline/vi_mode.c b/utshell-0.5.0/lib/readline/vi_mode.c new file mode 100644 index 00000000..742341e3 --- /dev/null +++ b/utshell-0.5.0/lib/readline/vi_mode.c @@ -0,0 +1,2408 @@ +/* vi_mode.c -- A vi emulation mode for Bash. + Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +/* **************************************************************** */ +/* */ +/* VI Emulation Mode */ +/* */ +/* **************************************************************** */ +#include "rlconf.h" + +#if defined (VI_MODE) + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +/* Some standard library routines. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#ifndef member +#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) +#endif + +/* Increment START to the next character in RL_LINE_BUFFER, handling multibyte chars */ +#if defined (HANDLE_MULTIBYTE) +#define INCREMENT_POS(start) \ + do { \ + if (MB_CUR_MAX == 1 || rl_byte_oriented) \ + start++; \ + else \ + start = _rl_find_next_mbchar (rl_line_buffer, start, 1, MB_FIND_ANY); \ + } while (0) +#else /* !HANDLE_MULTIBYTE */ +#define INCREMENT_POS(start) (start)++ +#endif /* !HANDLE_MULTIBYTE */ + +/* This is global so other parts of the code can check whether the last + command was a text modification command. */ +int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */ + +_rl_vimotion_cxt *_rl_vimvcxt = 0; + +/* Non-zero indicates we are redoing a vi-mode command with `.' */ +int _rl_vi_redoing; + +/* Non-zero means enter insertion mode. */ +static int _rl_vi_doing_insert; + +/* Command keys which do movement for xxx_to commands. */ +static const char * const vi_motion = " hl^$0ftFT;,%wbeWBE|`"; + +/* Keymap used for vi replace characters. Created dynamically since + rarely used. */ +static Keymap vi_replace_map; + +/* The number of characters inserted in the last replace operation. */ +static int vi_replace_count; + +/* If non-zero, we have text inserted after a c[motion] command that put + us implicitly into insert mode. Some people want this text to be + attached to the command so that it is `redoable' with `.'. */ +static int vi_continued_command; +static char *vi_insert_buffer; +static int vi_insert_buffer_size; + +static int _rl_vi_last_repeat = 1; +static int _rl_vi_last_arg_sign = 1; +static int _rl_vi_last_motion; +#if defined (HANDLE_MULTIBYTE) +static char _rl_vi_last_search_mbchar[MB_LEN_MAX]; +static int _rl_vi_last_search_mblen; +#else +static int _rl_vi_last_search_char; +#endif +static char _rl_vi_last_replacement[MB_LEN_MAX+1]; /* reserve for trailing NULL */ + +static int _rl_vi_last_key_before_insert; + +/* Text modification commands. These are the `redoable' commands. */ +static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; + +/* Arrays for the saved marks. */ +static int vi_mark_chars['z' - 'a' + 1]; + +static void _rl_vi_replace_insert PARAMS((int)); +static void _rl_vi_save_replace PARAMS((void)); +static void _rl_vi_stuff_insert PARAMS((int)); +static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); + +static void vi_save_insert_buffer PARAMS ((int, int)); + +static inline void _rl_vi_backup PARAMS((void)); + +static int _rl_vi_arg_dispatch PARAMS((int)); +static int rl_digit_loop1 PARAMS((void)); + +static int _rl_vi_set_mark PARAMS((void)); +static int _rl_vi_goto_mark PARAMS((void)); + +static inline int _rl_vi_advance_point PARAMS((void)); +static inline int _rl_vi_backup_point PARAMS((void)); + +static void _rl_vi_append_forward PARAMS((int)); + +static int _rl_vi_callback_getchar PARAMS((char *, int)); + +#if defined (READLINE_CALLBACKS) +static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *)); +static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *)); +static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *)); +static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *)); +#endif + +static int rl_domove_read_callback PARAMS((_rl_vimotion_cxt *)); +static int rl_domove_motion_callback PARAMS((_rl_vimotion_cxt *)); +static int rl_vi_domove_getchar PARAMS((_rl_vimotion_cxt *)); + +static int vi_change_dispatch PARAMS((_rl_vimotion_cxt *)); +static int vi_delete_dispatch PARAMS((_rl_vimotion_cxt *)); +static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *)); + +static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *)); + +void +_rl_vi_initialize_line (void) +{ + register int i, n; + + n = sizeof (vi_mark_chars) / sizeof (vi_mark_chars[0]); + for (i = 0; i < n; i++) + vi_mark_chars[i] = -1; + + RL_UNSETSTATE(RL_STATE_VICMDONCE); +} + +void +_rl_vi_reset_last (void) +{ + _rl_vi_last_command = 'i'; + _rl_vi_last_repeat = 1; + _rl_vi_last_arg_sign = 1; + _rl_vi_last_motion = 0; +} + +void +_rl_vi_set_last (int key, int repeat, int sign) +{ + _rl_vi_last_command = key; + _rl_vi_last_repeat = repeat; + _rl_vi_last_arg_sign = sign; +} + +/* A convenience function that calls _rl_vi_set_last to save the last command + information and enters insertion mode. */ +void +rl_vi_start_inserting (int key, int repeat, int sign) +{ + _rl_vi_set_last (key, repeat, sign); + rl_begin_undo_group (); /* ensure inserts aren't concatenated */ + rl_vi_insertion_mode (1, key); +} + +/* Is the command C a VI mode text modification command? */ +int +_rl_vi_textmod_command (int c) +{ + return (member (c, vi_textmod)); +} + +int +_rl_vi_motion_command (int c) +{ + return (member (c, vi_motion)); +} + +static void +_rl_vi_replace_insert (int count) +{ + int nchars; + + nchars = strlen (vi_insert_buffer); + + rl_begin_undo_group (); + while (count--) + /* nchars-1 to compensate for _rl_replace_text using `end+1' in call + to rl_delete_text */ + _rl_replace_text (vi_insert_buffer, rl_point, rl_point+nchars-1); + rl_end_undo_group (); +} + +static void +_rl_vi_stuff_insert (int count) +{ + rl_begin_undo_group (); + while (count--) + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); +} + +/* Bound to `.'. Called from command mode, so we know that we have to + redo a text modification command. The default for _rl_vi_last_command + puts you back into insert mode. */ +int +rl_vi_redo (int count, int c) +{ + int r; + + if (rl_explicit_arg == 0) + { + rl_numeric_arg = _rl_vi_last_repeat; + rl_arg_sign = _rl_vi_last_arg_sign; + } + + r = 0; + _rl_vi_redoing = 1; + /* If we're redoing an insert with `i', stuff in the inserted text + and do not go into insertion mode. */ + if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_stuff_insert (count); + /* And back up point over the last character inserted. */ + if (rl_point > 0) + _rl_vi_backup (); + } + else if (_rl_vi_last_command == 'R' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_replace_insert (count); + /* And back up point over the last character inserted. */ + if (rl_point > 0) + _rl_vi_backup (); + } + /* Ditto for redoing an insert with `I', but move to the beginning of the + line like the `I' command does. */ + else if (_rl_vi_last_command == 'I' && vi_insert_buffer && *vi_insert_buffer) + { + rl_beg_of_line (1, 'I'); + _rl_vi_stuff_insert (count); + if (rl_point > 0) + _rl_vi_backup (); + } + /* Ditto for redoing an insert with `a', but move forward a character first + like the `a' command does. */ + else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_append_forward ('a'); + _rl_vi_stuff_insert (count); + if (rl_point > 0) + _rl_vi_backup (); + } + /* Ditto for redoing an insert with `A', but move to the end of the line + like the `A' command does. */ + else if (_rl_vi_last_command == 'A' && vi_insert_buffer && *vi_insert_buffer) + { + rl_end_of_line (1, 'A'); + _rl_vi_stuff_insert (count); + if (rl_point > 0) + _rl_vi_backup (); + } + else if (_rl_vi_last_command == '.' && _rl_keymap == vi_movement_keymap) + { + rl_ding (); + r = 0; + } + else + r = _rl_dispatch (_rl_vi_last_command, _rl_keymap); + + _rl_vi_redoing = 0; + + return (r); +} + +/* A placeholder for further expansion. */ +int +rl_vi_undo (int count, int key) +{ + return (rl_undo_command (count, key)); +} + +/* Yank the nth arg from the previous line into this line at point. */ +int +rl_vi_yank_arg (int count, int key) +{ + /* Readline thinks that the first word on a line is the 0th, while vi + thinks the first word on a line is the 1st. Compensate. */ + if (rl_explicit_arg) + rl_yank_nth_arg (count - 1, key); + else + rl_yank_nth_arg ('$', key); + + return (0); +} + +/* With an argument, move back that many history lines, else move to the + beginning of history. */ +int +rl_vi_fetch_history (int count, int c) +{ + int wanted; + + /* Giving an argument of n means we want the nth command in the history + file. The command number is interpreted the same way that the bash + `history' command does it -- that is, giving an argument count of 450 + to this command would get the command listed as number 450 in the + output of `history'. */ + if (rl_explicit_arg) + { + wanted = history_base + where_history () - count; + if (wanted <= 0) + rl_beginning_of_history (0, 0); + else + rl_get_previous_history (wanted, c); + } + else + rl_beginning_of_history (count, 0); + return (0); +} + +/* Search again for the last thing searched for. */ +int +rl_vi_search_again (int count, int key) +{ + switch (key) + { + case 'n': + rl_noninc_reverse_search_again (count, key); + break; + + case 'N': + rl_noninc_forward_search_again (count, key); + break; + } + return (0); +} + +/* Do a vi style search. */ +int +rl_vi_search (int count, int key) +{ + switch (key) + { + case '?': + _rl_free_saved_history_line (); + rl_noninc_forward_search (count, key); + break; + + case '/': + _rl_free_saved_history_line (); + rl_noninc_reverse_search (count, key); + break; + + default: + rl_ding (); + break; + } + return (0); +} + +/* Completion, from vi's point of view. */ +int +rl_vi_complete (int ignore, int key) +{ + if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) + { + if (!whitespace (rl_line_buffer[rl_point + 1])) + rl_vi_end_word (1, 'E'); + _rl_vi_advance_point (); + } + + if (key == '*') + rl_complete_internal ('*'); /* Expansion and replacement. */ + else if (key == '=') + rl_complete_internal ('?'); /* List possible completions. */ + else if (key == '\\') + rl_complete_internal (TAB); /* Standard Readline completion. */ + else + rl_complete (0, key); + + if (key == '*' || key == '\\') + rl_vi_start_inserting (key, 1, rl_arg_sign); + + return (0); +} + +/* Tilde expansion for vi mode. */ +int +rl_vi_tilde_expand (int ignore, int key) +{ + rl_tilde_expand (0, key); + rl_vi_start_inserting (key, 1, rl_arg_sign); + return (0); +} + +/* Previous word in vi mode. */ +int +rl_vi_prev_word (int count, int key) +{ + if (count < 0) + return (rl_vi_next_word (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return (0); + } + + if (_rl_uppercase_p (key)) + rl_vi_bWord (count, key); + else + rl_vi_bword (count, key); + + return (0); +} + +/* Next word in vi mode. */ +int +rl_vi_next_word (int count, int key) +{ + if (count < 0) + return (rl_vi_prev_word (-count, key)); + + if (rl_point >= (rl_end - 1)) + { + rl_ding (); + return (0); + } + + if (_rl_uppercase_p (key)) + rl_vi_fWord (count, key); + else + rl_vi_fword (count, key); + return (0); +} + +static inline int +_rl_vi_advance_point (void) +{ + int point; + + point = rl_point; + if (rl_point < rl_end) +#if defined (HANDLE_MULTIBYTE) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + rl_point++; + else + { + point = rl_point; + rl_point = _rl_forward_char_internal (1); + if (point == rl_point || rl_point > rl_end) + rl_point = rl_end; + } + } +#else + rl_point++; +#endif + + return point; +} + +/* Move the cursor back one character. */ +static inline void +_rl_vi_backup (void) +{ + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + else + rl_point--; +} + +/* Move the point back one character, returning the starting value and not + doing anything at the beginning of the line */ +static inline int +_rl_vi_backup_point (void) +{ + int point; + + point = rl_point; + if (rl_point > 0) +#if defined (HANDLE_MULTIBYTE) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + rl_point--; + else + { + point = rl_point; + rl_point = _rl_backward_char_internal (1); + if (rl_point < 0) + rl_point = 0; /* XXX - not really necessary */ + } + } +#else + rl_point--; +#endif + return point; +} + +/* Move to the end of the ?next? word. */ +int +rl_vi_end_word (int count, int key) +{ + if (count < 0) + { + rl_ding (); + return 1; + } + + if (_rl_uppercase_p (key)) + rl_vi_eWord (count, key); + else + rl_vi_eword (count, key); + return (0); +} + +/* Move forward a word the way that 'W' does. */ +int +rl_vi_fWord (int count, int ignore) +{ + while (count-- && rl_point < (rl_end - 1)) + { + /* Skip until whitespace. */ + while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + _rl_vi_advance_point (); + + /* Now skip whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + _rl_vi_advance_point (); + } + return (0); +} + +int +rl_vi_bWord (int count, int ignore) +{ + while (count-- && rl_point > 0) + { + /* If we are at the start of a word, move back to whitespace so + we will go back to the start of the previous word. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + _rl_vi_backup_point (); + + if (rl_point > 0) + { + do + _rl_vi_backup_point (); + while (rl_point > 0 && !whitespace (rl_line_buffer[rl_point])); + if (rl_point > 0) /* hit whitespace */ + rl_point++; + + if (rl_point < 0) + rl_point = 0; + } + } + return (0); +} + +int +rl_vi_eWord (int count, int ignore) +{ + int opoint; + + while (count-- && rl_point < (rl_end - 1)) + { + if (whitespace (rl_line_buffer[rl_point]) == 0) + _rl_vi_advance_point (); + + /* Move to the next non-whitespace character (to the start of the + next word). */ + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + _rl_vi_advance_point (); + + if (rl_point && rl_point < rl_end) + { + opoint = rl_point; + + /* Skip whitespace. */ + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + opoint = _rl_vi_advance_point (); /* XXX - why? */ + + /* Skip until whitespace. */ + while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point])) + opoint = _rl_vi_advance_point (); + + /* Move back to the last character of the word. */ + rl_point = opoint; + } + } + return (0); +} + +int +rl_vi_fword (int count, int ignore) +{ + int opoint; + + while (count-- && rl_point < (rl_end - 1)) + { + /* Move to white space (really non-identifer). */ + if (_rl_isident (rl_line_buffer[rl_point])) + { + while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end) + _rl_vi_advance_point (); + } + else /* if (!whitespace (rl_line_buffer[rl_point])) */ + { + while (!_rl_isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + _rl_vi_advance_point (); + } + + opoint = rl_point; + + /* Move past whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + opoint = _rl_vi_advance_point (); + } + return (0); +} + +int +rl_vi_bword (int count, int ignore) +{ + int opoint; + + while (count-- && rl_point > 0) + { + int prev_is_ident, cur_is_ident; + + /* If we are at the start of a word, move back to whitespace + so we will go back to the start of the previous word. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + if (--rl_point == 0) + break; + + /* If this character and the previous character are `opposite', move + back so we don't get messed up by the rl_point++ down there in + the while loop. Without this code, words like `l;' screw up the + function. */ + cur_is_ident = _rl_isident (rl_line_buffer[rl_point]); + opoint = _rl_vi_backup_point (); + prev_is_ident = _rl_isident (rl_line_buffer[rl_point]); + if ((cur_is_ident && !prev_is_ident) || (!cur_is_ident && prev_is_ident)) + ; /* leave point alone, we backed it up one character */ + else + rl_point = opoint; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + _rl_vi_backup_point (); + + if (rl_point > 0) + { + opoint = rl_point; + if (_rl_isident (rl_line_buffer[rl_point])) + do + opoint = _rl_vi_backup_point (); + while (rl_point > 0 && _rl_isident (rl_line_buffer[rl_point])); + else + do + opoint = _rl_vi_backup_point (); + while (rl_point > 0 && !_rl_isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point])); + + if (rl_point > 0) + rl_point = opoint; + + if (rl_point < 0) + rl_point = 0; + } + } + return (0); +} + +int +rl_vi_eword (int count, int ignore) +{ + int opoint; + + while (count-- && rl_point < (rl_end - 1)) + { + if (whitespace (rl_line_buffer[rl_point]) == 0) + _rl_vi_advance_point (); + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + _rl_vi_advance_point (); + + opoint = rl_point; + if (rl_point < rl_end) + { + if (_rl_isident (rl_line_buffer[rl_point])) + do + { + opoint = _rl_vi_advance_point (); + } + while (rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point])); + else + do + { + opoint = _rl_vi_advance_point (); + } + while (rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point]) + && !whitespace (rl_line_buffer[rl_point])); + } + rl_point = opoint; + } + return (0); +} + +int +rl_vi_insert_beg (int count, int key) +{ + rl_beg_of_line (1, key); + rl_vi_insert_mode (1, key); + return (0); +} + +static void +_rl_vi_append_forward (int key) +{ + _rl_vi_advance_point (); +} + +int +rl_vi_append_mode (int count, int key) +{ + _rl_vi_append_forward (key); + rl_vi_start_inserting (key, 1, rl_arg_sign); + return (0); +} + +int +rl_vi_append_eol (int count, int key) +{ + rl_end_of_line (1, key); + rl_vi_append_mode (1, key); + return (0); +} + +/* What to do in the case of C-d. */ +int +rl_vi_eof_maybe (int count, int c) +{ + return (rl_newline (1, '\n')); +} + +/* Insertion mode stuff. */ + +/* Switching from one mode to the other really just involves + switching keymaps. */ +int +rl_vi_insertion_mode (int count, int key) +{ + _rl_keymap = vi_insertion_keymap; + _rl_vi_last_key_before_insert = key; + if (_rl_show_mode_in_prompt) + _rl_reset_prompt (); + return (0); +} + +int +rl_vi_insert_mode (int count, int key) +{ + rl_vi_start_inserting (key, 1, rl_arg_sign); + return (0); +} + +static void +vi_save_insert_buffer (int start, int len) +{ + /* Same code as _rl_vi_save_insert below */ + if (len >= vi_insert_buffer_size) + { + vi_insert_buffer_size += (len + 32) - (len % 32); + vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size); + } + strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); + vi_insert_buffer[len-1] = '\0'; +} + +static void +_rl_vi_save_replace (void) +{ + int len, start, end; + UNDO_LIST *up; + + up = rl_undo_list; + if (up == 0 || up->what != UNDO_END || vi_replace_count <= 0) + { + if (vi_insert_buffer_size >= 1) + vi_insert_buffer[0] = '\0'; + return; + } + /* Let's try it the quick and easy way for now. This should essentially + accommodate every UNDO_INSERT and save the inserted text to + vi_insert_buffer */ + end = rl_point; + start = end - vi_replace_count + 1; + len = vi_replace_count + 1; + + if (start < 0) + { + len = end + 1; + start = 0; + } + + vi_save_insert_buffer (start, len); +} + +static void +_rl_vi_save_insert (UNDO_LIST *up) +{ + int len, start, end; + + if (up == 0 || up->what != UNDO_INSERT) + { + if (vi_insert_buffer_size >= 1) + vi_insert_buffer[0] = '\0'; + return; + } + + start = up->start; + end = up->end; + len = end - start + 1; + + vi_save_insert_buffer (start, len); +} + +void +_rl_vi_done_inserting (void) +{ + if (_rl_vi_doing_insert) + { + /* The `c', `s', `S', and `R' commands set this. */ + rl_end_undo_group (); /* for the group in rl_vi_start_inserting */ + /* Now, the text between rl_undo_list->next->start and + rl_undo_list->next->end is what was inserted while in insert + mode. It gets copied to VI_INSERT_BUFFER because it depends + on absolute indices into the line which may change (though they + probably will not). */ + _rl_vi_doing_insert = 0; + if (_rl_vi_last_key_before_insert == 'R') + _rl_vi_save_replace (); /* Half the battle */ + else + _rl_vi_save_insert (rl_undo_list->next); + /* sanity check, should always be >= 1 here */ + if (_rl_undo_group_level > 0) + rl_end_undo_group (); /* for the group in the command (change or replace) */ + } + else + { + if (rl_undo_list && (_rl_vi_last_key_before_insert == 'i' || + _rl_vi_last_key_before_insert == 'a' || + _rl_vi_last_key_before_insert == 'I' || + _rl_vi_last_key_before_insert == 'A')) + _rl_vi_save_insert (rl_undo_list); + /* XXX - Other keys probably need to be checked. */ + else if (_rl_vi_last_key_before_insert == 'C') + rl_end_undo_group (); + } + + /* Sanity check, make sure all the undo groups are closed before we leave + insert mode */ + while (_rl_undo_group_level > 0) + rl_end_undo_group (); +} + +int +rl_vi_movement_mode (int count, int key) +{ + if (rl_point > 0) + rl_backward_char (1, key); + + _rl_keymap = vi_movement_keymap; + _rl_vi_done_inserting (); + + /* This is how POSIX.2 says `U' should behave -- everything up until the + first time you go into command mode should not be undone. */ + if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0) + rl_free_undo_list (); + + if (_rl_show_mode_in_prompt) + _rl_reset_prompt (); + + RL_SETSTATE (RL_STATE_VICMDONCE); + return (0); +} + +int +rl_vi_arg_digit (int count, int c) +{ + if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) + return (rl_beg_of_line (1, c)); + else + return (rl_digit_argument (count, c)); +} + +/* Change the case of the next COUNT characters. */ +#if defined (HANDLE_MULTIBYTE) +static int +_rl_vi_change_mbchar_case (int count) +{ + wchar_t wc; + char mb[MB_LEN_MAX+1]; + int mlen, p; + size_t m; + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0) + count--; + while (count-- && rl_point < rl_end) + { + m = mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps); + if (MB_INVALIDCH (m)) + wc = (wchar_t)rl_line_buffer[rl_point]; + else if (MB_NULLWCH (m)) + wc = L'\0'; + if (iswupper (wc)) + wc = towlower (wc); + else if (iswlower (wc)) + wc = towupper (wc); + else + { + /* Just skip over chars neither upper nor lower case */ + rl_forward_char (1, 0); + continue; + } + + /* Vi is kind of strange here. */ + if (wc) + { + p = rl_point; + mlen = wcrtomb (mb, wc, &ps); + if (mlen >= 0) + mb[mlen] = '\0'; + rl_begin_undo_group (); + rl_vi_delete (1, 0); + if (rl_point < p) /* Did we retreat at EOL? */ + _rl_vi_advance_point (); + rl_insert_text (mb); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward_char (1, 0); + } + + return 0; +} +#endif + +int +rl_vi_change_case (int count, int ignore) +{ + int c, p; + + /* Don't try this on an empty line. */ + if (rl_point >= rl_end) + return (0); + + c = 0; +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + return (_rl_vi_change_mbchar_case (count)); +#endif + + while (count-- && rl_point < rl_end) + { + if (_rl_uppercase_p (rl_line_buffer[rl_point])) + c = _rl_to_lower (rl_line_buffer[rl_point]); + else if (_rl_lowercase_p (rl_line_buffer[rl_point])) + c = _rl_to_upper (rl_line_buffer[rl_point]); + else + { + /* Just skip over characters neither upper nor lower case. */ + rl_forward_char (1, c); + continue; + } + + /* Vi is kind of strange here. */ + if (c) + { + p = rl_point; + rl_begin_undo_group (); + rl_vi_delete (1, c); + if (rl_point < p) /* Did we retreat at EOL? */ + rl_point++; + _rl_insert_char (1, c); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward_char (1, c); + } + return (0); +} + +int +rl_vi_put (int count, int key) +{ + if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) + rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); + + while (count--) + rl_yank (1, key); + + rl_backward_char (1, key); + return (0); +} + +/* Move the cursor back one character if you're at the end of the line */ +int +rl_vi_check (void) +{ + if (rl_point && rl_point == rl_end) + _rl_vi_backup (); + return (0); +} + +/* Move to the character position specified by COUNT */ +int +rl_vi_column (int count, int key) +{ + if (count > rl_end) + rl_end_of_line (1, key); + else + { + rl_point = 0; + rl_point = _rl_forward_char_internal (count - 1); + } + return (0); +} + +/* Process C as part of the current numeric argument. Return -1 if the + argument should be aborted, 0 if we should not read any more chars, and + 1 if we should continue to read chars. */ +static int +_rl_vi_arg_dispatch (int c) +{ + int key; + + key = c; + if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument) + { + rl_numeric_arg *= 4; + return 1; + } + + c = UNMETA (c); + + if (_rl_digit_p (c)) + { + if (rl_explicit_arg) + rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c); + else + rl_numeric_arg = _rl_digit_value (c); + rl_explicit_arg = 1; + return 1; /* keep going */ + } + else + { + rl_clear_message (); + rl_stuff_char (key); + return 0; /* done */ + } +} + +/* A simplified loop for vi. Don't dispatch key at end. + Don't recognize minus sign? + Should this do rl_save_prompt/rl_restore_prompt? */ +static int +rl_digit_loop1 (void) +{ + int c, r; + + while (1) + { + if (_rl_arg_overflow ()) + return 1; + + c = _rl_arg_getchar (); + + r = _rl_vi_arg_dispatch (c); + if (r <= 0) + break; + } + + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return (0); +} + +/* This set of functions is basically to handle the commands that take a + motion argument while in callback mode: read the command, read the motion + command modifier, find the extent of the text to affect, and dispatch the + command for execution. */ +static void +_rl_mvcxt_init (_rl_vimotion_cxt *m, int op, int key) +{ + m->op = op; + m->state = m->flags = 0; + m->ncxt = 0; + m->numeric_arg = -1; + m->start = rl_point; + m->end = rl_end; + m->key = key; + m->motion = -1; +} + +static _rl_vimotion_cxt * +_rl_mvcxt_alloc (int op, int key) +{ + _rl_vimotion_cxt *m; + + m = xmalloc (sizeof (_rl_vimotion_cxt)); + _rl_mvcxt_init (m, op, key); + return m; +} + +static void +_rl_mvcxt_dispose (_rl_vimotion_cxt *m) +{ + xfree (m); +} + +static int +rl_domove_motion_callback (_rl_vimotion_cxt *m) +{ + int c; + + _rl_vi_last_motion = c = m->motion; + + /* Append a blank character temporarily so that the motion routines + work right at the end of the line. Original value of rl_end is saved + as m->end. */ + rl_extend_line_buffer (rl_end + 1); + rl_line_buffer[rl_end++] = ' '; + rl_line_buffer[rl_end] = '\0'; + + _rl_dispatch (c, _rl_keymap); + +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + /* Messy case where char search can be vi motion command; see rest of + details in callback.c. vi_char_search and callback_char_search just + set and unset the CHARSEARCH state. This is where any vi motion + command that needs to set its own state should be handled, with any + corresponding code to manage that state in callback.c */ + if (RL_ISSTATE (RL_STATE_CHARSEARCH)) + return 0; + else + return (_rl_vi_domove_motion_cleanup (c, m)); + } +#endif + + return (_rl_vi_domove_motion_cleanup (c, m)); +} + +int +_rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m) +{ + int r; + + /* Remove the blank that we added in rl_domove_motion_callback. */ + rl_end = m->end; + rl_line_buffer[rl_end] = '\0'; + _rl_fix_point (0); + + /* No change in position means the command failed. */ + if (rl_mark == rl_point) + { + /* 'c' and 'C' enter insert mode after the delete even if the motion + didn't delete anything, as long as the motion command is valid. */ + if (_rl_to_upper (m->key) == 'C' && _rl_vi_motion_command (c)) + return (vidomove_dispatch (m)); + RL_UNSETSTATE (RL_STATE_VIMOTION); + return (-1); + } + + /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next + word. If we are not at the end of the line, and we are on a + non-whitespace character, move back one (presumably to whitespace). */ + if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && + !whitespace (rl_line_buffer[rl_point])) + rl_point--; /* XXX */ + + /* If cw or cW, back up to the end of a word, so the behaviour of ce + or cE is the actual result. Brute-force, no subtlety. */ + if (m->key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W')) + { + /* Don't move farther back than where we started. */ + while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + /* Posix.2 says that if cw or cW moves the cursor towards the end of + the line, the character under the cursor should be deleted. */ + if (rl_point == rl_mark) + _rl_vi_advance_point (); + else + { + /* Move past the end of the word so that the kill doesn't + remove the last letter of the previous word. Only do this + if we are not at the end of the line. */ + if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point])) + _rl_vi_advance_point (); + } + } + + if (rl_mark < rl_point) + SWAP (rl_point, rl_mark); + +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + (*rl_redisplay_function)(); /* make sure motion is displayed */ +#endif + + r = vidomove_dispatch (m); + + return (r); +} + +#define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG)) + +static int +rl_domove_read_callback (_rl_vimotion_cxt *m) +{ + int c, save; + + c = m->motion; + + if (member (c, vi_motion)) + { +#if defined (READLINE_CALLBACKS) + /* If we just read a vi-mode motion command numeric argument, turn off + the `reading numeric arg' state */ + if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG()) + RL_UNSETSTATE (RL_STATE_NUMERICARG); +#endif + /* Should do everything, including turning off RL_STATE_VIMOTION */ + return (rl_domove_motion_callback (m)); + } + else if (m->key == c && (m->key == 'd' || m->key == 'y' || m->key == 'c')) + { + rl_mark = rl_end; + rl_beg_of_line (1, c); + _rl_vi_last_motion = c; + RL_UNSETSTATE (RL_STATE_VIMOTION); + return (vidomove_dispatch (m)); + } +#if defined (READLINE_CALLBACKS) + /* XXX - these need to handle rl_universal_argument bindings */ + /* Reading vi motion char continuing numeric argument */ + else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG()) + { + return (_rl_vi_arg_dispatch (c)); + } + /* Readine vi motion char starting numeric argument */ + else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_VIMOTION) && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)) + { + RL_SETSTATE (RL_STATE_NUMERICARG); + return (_rl_vi_arg_dispatch (c)); + } +#endif + else if (_rl_digit_p (c)) + { + /* This code path taken when not in callback mode */ + save = rl_numeric_arg; + rl_numeric_arg = _rl_digit_value (c); + rl_explicit_arg = 1; + RL_SETSTATE (RL_STATE_NUMERICARG); + rl_digit_loop1 (); + rl_numeric_arg *= save; + c = rl_vi_domove_getchar (m); + if (c < 0) + { + m->motion = 0; + return -1; + } + m->motion = c; + return (rl_domove_motion_callback (m)); + } + else + { + RL_UNSETSTATE (RL_STATE_VIMOTION); + RL_UNSETSTATE (RL_STATE_NUMERICARG); + return (1); + } +} + +static int +rl_vi_domove_getchar (_rl_vimotion_cxt *m) +{ + return (_rl_bracketed_read_key ()); +} + +#if defined (READLINE_CALLBACKS) +int +_rl_vi_domove_callback (_rl_vimotion_cxt *m) +{ + int c, r; + + m->motion = c = rl_vi_domove_getchar (m); + if (c < 0) + return 1; /* EOF */ + r = rl_domove_read_callback (m); + + return ((r == 0) ? r : 1); /* normalize return values */ +} +#endif + +/* This code path is taken when not in callback mode. */ +int +rl_vi_domove (int x, int *ignore) +{ + int r; + _rl_vimotion_cxt *m; + + m = _rl_vimvcxt; + *ignore = m->motion = rl_vi_domove_getchar (m); + + if (m->motion < 0) + { + m->motion = 0; + return -1; + } + + return (rl_domove_read_callback (m)); +} + +static int +vi_delete_dispatch (_rl_vimotion_cxt *m) +{ + /* These are the motion commands that do not require adjusting the + mark. */ + if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) && + (rl_mark < rl_end)) + INCREMENT_POS (rl_mark); + + rl_kill_text (rl_point, rl_mark); + return (0); +} + +int +rl_vi_delete_to (int count, int key) +{ + int c, r; + + if (_rl_vimvcxt) + _rl_mvcxt_init (_rl_vimvcxt, VIM_DELETE, key); + else + _rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key); + + _rl_vimvcxt->start = rl_point; + + rl_mark = rl_point; + if (_rl_uppercase_p (key)) + { + _rl_vimvcxt->motion = '$'; + r = rl_domove_motion_callback (_rl_vimvcxt); + } + else if (_rl_vi_redoing && _rl_vi_last_motion != 'd') /* `dd' is special */ + { + _rl_vimvcxt->motion = _rl_vi_last_motion; + r = rl_domove_motion_callback (_rl_vimvcxt); + } + else if (_rl_vi_redoing) /* handle redoing `dd' here */ + { + _rl_vimvcxt->motion = _rl_vi_last_motion; + rl_mark = rl_end; + rl_beg_of_line (1, key); + RL_UNSETSTATE (RL_STATE_VIMOTION); + r = vidomove_dispatch (_rl_vimvcxt); + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + RL_SETSTATE (RL_STATE_VIMOTION); + return (0); + } +#endif + else + r = rl_vi_domove (key, &c); + + if (r < 0) + { + rl_ding (); + r = -1; + } + + _rl_mvcxt_dispose (_rl_vimvcxt); + _rl_vimvcxt = 0; + + return r; +} + +static int +vi_change_dispatch (_rl_vimotion_cxt *m) +{ + /* These are the motion commands that do not require adjusting the + mark. c[wW] are handled by special-case code in rl_vi_domove(), + and already leave the mark at the correct location. */ + if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) && + (rl_mark < rl_end)) + INCREMENT_POS (rl_mark); + + /* The cursor never moves with c[wW]. */ + if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start) + rl_point = m->start; + + if (_rl_vi_redoing) + { + if (vi_insert_buffer && *vi_insert_buffer) + rl_begin_undo_group (); + rl_delete_text (rl_point, rl_mark); + if (vi_insert_buffer && *vi_insert_buffer) + { + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); + } + } + else + { + rl_begin_undo_group (); /* to make the `u' command work */ + rl_kill_text (rl_point, rl_mark); + /* `C' does not save the text inserted for undoing or redoing. */ + if (_rl_uppercase_p (m->key) == 0) + _rl_vi_doing_insert = 1; + /* XXX -- TODO -- use m->numericarg? */ + rl_vi_start_inserting (m->key, rl_numeric_arg, rl_arg_sign); + } + + return (0); +} + +int +rl_vi_change_to (int count, int key) +{ + int c, r; + + if (_rl_vimvcxt) + _rl_mvcxt_init (_rl_vimvcxt, VIM_CHANGE, key); + else + _rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key); + _rl_vimvcxt->start = rl_point; + + rl_mark = rl_point; + if (_rl_uppercase_p (key)) + { + _rl_vimvcxt->motion = '$'; + r = rl_domove_motion_callback (_rl_vimvcxt); + } + else if (_rl_vi_redoing && _rl_vi_last_motion != 'c') /* `cc' is special */ + { + _rl_vimvcxt->motion = _rl_vi_last_motion; + r = rl_domove_motion_callback (_rl_vimvcxt); + } + else if (_rl_vi_redoing) /* handle redoing `cc' here */ + { + _rl_vimvcxt->motion = _rl_vi_last_motion; + rl_mark = rl_end; + rl_beg_of_line (1, key); + RL_UNSETSTATE (RL_STATE_VIMOTION); + r = vidomove_dispatch (_rl_vimvcxt); + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + RL_SETSTATE (RL_STATE_VIMOTION); + return (0); + } +#endif + else + r = rl_vi_domove (key, &c); + + if (r < 0) + { + rl_ding (); + r = -1; /* normalize return value */ + } + + _rl_mvcxt_dispose (_rl_vimvcxt); + _rl_vimvcxt = 0; + + return r; +} + +static int +vi_yank_dispatch (_rl_vimotion_cxt *m) +{ + /* These are the motion commands that do not require adjusting the + mark. */ + if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) && + (rl_mark < rl_end)) + INCREMENT_POS (rl_mark); + + rl_begin_undo_group (); + rl_kill_text (rl_point, rl_mark); + rl_end_undo_group (); + rl_do_undo (); + rl_point = m->start; + + _rl_fix_point (1); + + return (0); +} + +int +rl_vi_yank_to (int count, int key) +{ + int c, r; + + if (_rl_vimvcxt) + _rl_mvcxt_init (_rl_vimvcxt, VIM_YANK, key); + else + _rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key); + _rl_vimvcxt->start = rl_point; + + rl_mark = rl_point; + if (_rl_uppercase_p (key)) + { + _rl_vimvcxt->motion = '$'; + r = rl_domove_motion_callback (_rl_vimvcxt); + } + else if (_rl_vi_redoing && _rl_vi_last_motion != 'y') /* `yy' is special */ + { + _rl_vimvcxt->motion = _rl_vi_last_motion; + r = rl_domove_motion_callback (_rl_vimvcxt); + } + else if (_rl_vi_redoing) /* handle redoing `yy' here */ + { + _rl_vimvcxt->motion = _rl_vi_last_motion; + rl_mark = rl_end; + rl_beg_of_line (1, key); + RL_UNSETSTATE (RL_STATE_VIMOTION); + r = vidomove_dispatch (_rl_vimvcxt); + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + RL_SETSTATE (RL_STATE_VIMOTION); + return (0); + } +#endif + else + r = rl_vi_domove (key, &c); + + if (r < 0) + { + rl_ding (); + r = -1; + } + + _rl_mvcxt_dispose (_rl_vimvcxt); + _rl_vimvcxt = 0; + + return r; +} + +static int +vidomove_dispatch (_rl_vimotion_cxt *m) +{ + int r; + + switch (m->op) + { + case VIM_DELETE: + r = vi_delete_dispatch (m); + break; + case VIM_CHANGE: + r = vi_change_dispatch (m); + break; + case VIM_YANK: + r = vi_yank_dispatch (m); + break; + default: + _rl_errmsg ("vidomove_dispatch: unknown operator %d", m->op); + r = 1; + break; + } + + RL_UNSETSTATE (RL_STATE_VIMOTION); + return r; +} + +int +rl_vi_rubout (int count, int key) +{ + int opoint; + + if (count < 0) + return (rl_vi_delete (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return 1; + } + + opoint = rl_point; + if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_backward_char (count, key); + else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + else + rl_point -= count; + + if (rl_point < 0) + rl_point = 0; + + rl_kill_text (rl_point, opoint); + + return (0); +} + +int +rl_vi_delete (int count, int key) +{ + int end; + + if (count < 0) + return (rl_vi_rubout (-count, key)); + + if (rl_end == 0) + { + rl_ding (); + return 1; + } + + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + else + end = rl_point + count; + + if (end >= rl_end) + end = rl_end; + + rl_kill_text (rl_point, end); + + if (rl_point > 0 && rl_point == rl_end) + rl_backward_char (1, key); + + return (0); +} + +/* This does what Posix specifies vi-mode C-w to do: using whitespace and + punctuation characters as the word boundaries. */ + +#define vi_unix_word_boundary(c) (whitespace(c) || ispunct(c)) + +int +rl_vi_unix_word_rubout (int count, int key) +{ + int orig_point; + + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + /* This isn't quite what ksh93 does but it seems to match what the + Posix description of sh specifies, with a few accommodations + for sequences of whitespace characters between words and at + the end of the line. */ + + /* Skip over whitespace at the end of the line as a special case */ + if (rl_point > 0 && (rl_line_buffer[rl_point] == 0) && + whitespace (rl_line_buffer[rl_point - 1])) + while (--rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + ; + + /* If we're at the start of a word, move back to word boundary so we + move back to the `preceding' word */ + if (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) && + vi_unix_word_boundary (rl_line_buffer[rl_point - 1])) + rl_point--; + + /* If we are at a word boundary (whitespace/punct), move backward + past a sequence of word boundary characters. If we are at the + end of a word (non-word boundary), move back to a word boundary */ + if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point])) + while (rl_point && vi_unix_word_boundary (rl_line_buffer[rl_point - 1])) + rl_point--; + else if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) + while (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point - 1]) == 0)) + _rl_vi_backup_point (); + } + + rl_kill_text (orig_point, rl_point); + } + + return 0; +} + + +int +rl_vi_back_to_indent (int count, int key) +{ + rl_beg_of_line (1, key); + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + return (0); +} + +int +rl_vi_first_print (int count, int key) +{ + return (rl_vi_back_to_indent (1, key)); +} + +static int _rl_cs_dir, _rl_cs_orig_dir; + +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_char_search (_rl_callback_generic_arg *data) +{ + int c; +#if defined (HANDLE_MULTIBYTE) + c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); +#else + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); +#endif + + if (c <= 0) + { + RL_UNSETSTATE (RL_STATE_CHARSEARCH); + return -1; + } + +#if !defined (HANDLE_MULTIBYTE) + _rl_vi_last_search_char = c; +#endif + + _rl_callback_func = 0; + _rl_want_redisplay = 1; + RL_UNSETSTATE (RL_STATE_CHARSEARCH); + +#if defined (HANDLE_MULTIBYTE) + return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen)); +#else + return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char)); +#endif +} +#endif + +int +rl_vi_char_search (int count, int key) +{ + int c; +#if defined (HANDLE_MULTIBYTE) + static char *target; + static int tlen; +#else + static char target; +#endif + + if (key == ';' || key == ',') + { + if (_rl_cs_orig_dir == 0) + return 1; +#if defined (HANDLE_MULTIBYTE) + if (_rl_vi_last_search_mblen == 0) + return 1; +#else + if (_rl_vi_last_search_char == 0) + return 1; +#endif + _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir; + } + else + { + switch (key) + { + case 't': + _rl_cs_orig_dir = _rl_cs_dir = FTO; + break; + + case 'T': + _rl_cs_orig_dir = _rl_cs_dir = BTO; + break; + + case 'f': + _rl_cs_orig_dir = _rl_cs_dir = FFIND; + break; + + case 'F': + _rl_cs_orig_dir = _rl_cs_dir = BFIND; + break; + } + + if (_rl_vi_redoing) + { + /* set target and tlen below */ + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_data->i1 = _rl_cs_dir; + _rl_callback_data->i2 = key; + _rl_callback_func = _rl_vi_callback_char_search; + RL_SETSTATE (RL_STATE_CHARSEARCH); + return (0); + } +#endif + else + { +#if defined (HANDLE_MULTIBYTE) + c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX); + if (c <= 0) + return -1; + _rl_vi_last_search_mblen = c; +#else + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + if (c < 0) + return -1; + _rl_vi_last_search_char = c; +#endif + } + } + +#if defined (HANDLE_MULTIBYTE) + target = _rl_vi_last_search_mbchar; + tlen = _rl_vi_last_search_mblen; +#else + target = _rl_vi_last_search_char; +#endif + +#if defined (HANDLE_MULTIBYTE) + return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen)); +#else + return (_rl_char_search_internal (count, _rl_cs_dir, target)); +#endif +} + +/* Match brackets */ +int +rl_vi_match (int ignore, int key) +{ + int count = 1, brack, pos, tmp, pre; + + pos = rl_point; + if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) + { + pre = rl_point; + rl_forward_char (1, key); + if (pre == rl_point) + break; + } + } + else + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && + rl_point < rl_end - 1) + rl_forward_char (1, key); + + if (brack <= 0) + { + rl_point = pos; + rl_ding (); + return 1; + } + } + + pos = rl_point; + + if (brack < 0) + { + while (count) + { + tmp = pos; + if (MB_CUR_MAX == 1 || rl_byte_oriented) + pos--; + else + { + pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); + if (tmp == pos) + pos--; + } + if (pos >= 0) + { + int b = rl_vi_bracktype (rl_line_buffer[pos]); + if (b == -brack) + count--; + else if (b == brack) + count++; + } + else + { + rl_ding (); + return 1; + } + } + } + else + { /* brack > 0 */ + while (count) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + pos++; + else + pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY); + + if (pos < rl_end) + { + int b = rl_vi_bracktype (rl_line_buffer[pos]); + if (b == -brack) + count--; + else if (b == brack) + count++; + } + else + { + rl_ding (); + return 1; + } + } + } + rl_point = pos; + return (0); +} + +int +rl_vi_bracktype (int c) +{ + switch (c) + { + case '(': return 1; + case ')': return -1; + case '[': return 2; + case ']': return -2; + case '{': return 3; + case '}': return -3; + default: return 0; + } +} + +static int +_rl_vi_change_char (int count, int c, char *mb) +{ + int p; + + if (c == '\033' || c == CTRL ('C')) + return -1; + + rl_begin_undo_group (); + while (count-- && rl_point < rl_end) + { + p = rl_point; + rl_vi_delete (1, c); + if (rl_point < p) /* Did we retreat at EOL? */ + _rl_vi_append_forward (c); +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_insert_text (mb); + else +#endif + _rl_insert_char (1, c); + } + + /* The cursor shall be left on the last character changed. */ + rl_backward_char (1, c); + + rl_end_undo_group (); + + return (0); +} + +static int +_rl_vi_callback_getchar (char *mb, int mlen) +{ + return (_rl_bracketed_read_mbstring (mb, mlen)); +} + +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_change_char (_rl_callback_generic_arg *data) +{ + int c; + char mb[MB_LEN_MAX+1]; + + c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX); + else +#endif + _rl_vi_last_replacement[0] = c; + _rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* XXX */ + + if (c < 0) + return -1; + + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_vi_change_char (data->count, c, mb)); +} +#endif + +int +rl_vi_change_char (int count, int key) +{ + int c; + char mb[MB_LEN_MAX+1]; + + if (_rl_vi_redoing) + { + strncpy (mb, _rl_vi_last_replacement, MB_LEN_MAX); + c = (unsigned char)_rl_vi_last_replacement[0]; /* XXX */ + mb[MB_LEN_MAX] = '\0'; + } +#if defined (READLINE_CALLBACKS) + else if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = _rl_callback_data_alloc (count); + _rl_callback_func = _rl_vi_callback_change_char; + return (0); + } +#endif + else + { + c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); +#ifdef HANDLE_MULTIBYTE + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX); + else +#endif + _rl_vi_last_replacement[0] = c; + _rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* just in case */ + } + + if (c < 0) + return -1; + + return (_rl_vi_change_char (count, c, mb)); +} + +int +rl_vi_subst (int count, int key) +{ + /* If we are redoing, rl_vi_change_to will stuff the last motion char */ + if (_rl_vi_redoing == 0) + rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */ + + return (rl_vi_change_to (count, 'c')); +} + +int +rl_vi_overstrike (int count, int key) +{ + if (_rl_vi_doing_insert == 0) + { + _rl_vi_doing_insert = 1; + rl_begin_undo_group (); + } + + if (count > 0) + { + _rl_overwrite_char (count, key); + vi_replace_count += count; + } + + return (0); +} + +int +rl_vi_overstrike_delete (int count, int key) +{ + int i, s; + + for (i = 0; i < count; i++) + { + if (vi_replace_count == 0) + { + rl_ding (); + break; + } + s = rl_point; + + if (rl_do_undo ()) + vi_replace_count--; /* XXX */ + + if (rl_point == s) + rl_backward_char (1, key); + } + + if (vi_replace_count == 0 && _rl_vi_doing_insert) + { + rl_end_undo_group (); + rl_do_undo (); + _rl_vi_doing_insert = 0; + } + return (0); +} + +static int +rl_vi_overstrike_kill_line (int count, int key) +{ + int r, end; + + end = rl_end; + r = rl_unix_line_discard (count, key); + vi_replace_count -= end - rl_end; + return r; +} + +static int +rl_vi_overstrike_kill_word (int count, int key) +{ + int r, end; + + end = rl_end; + r = rl_vi_unix_word_rubout (count, key); + vi_replace_count -= end - rl_end; + return r; +} + +static int +rl_vi_overstrike_yank (int count, int key) +{ + int r, end; + + end = rl_end; + r = rl_yank (count, key); + vi_replace_count += rl_end - end; + return r; +} + +/* Read bracketed paste mode pasted text and insert it in overwrite mode */ +static int +rl_vi_overstrike_bracketed_paste (int count, int key) +{ + int r; + char *pbuf; + size_t pblen; + + pbuf = _rl_bracketed_text (&pblen); + if (pblen == 0) + { + xfree (pbuf); + return 0; + } + r = pblen; + while (--r >= 0) + _rl_unget_char ((unsigned char)pbuf[r]); + xfree (pbuf); + + while (_rl_pushed_input_available ()) + { + key = rl_read_key (); + r = rl_vi_overstrike (1, key); + } + + return r; +} + +int +rl_vi_replace (int count, int key) +{ + int i; + + vi_replace_count = 0; + + if (vi_replace_map == 0) + { + vi_replace_map = rl_make_bare_keymap (); + + for (i = 0; i < ' '; i++) + if (vi_insertion_keymap[i].type == ISFUNC) + vi_replace_map[i].function = vi_insertion_keymap[i].function; + + for (i = ' '; i < KEYMAP_SIZE; i++) + vi_replace_map[i].function = rl_vi_overstrike; + + vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; + + /* Make sure these are what we want. */ + vi_replace_map[ESC].function = rl_vi_movement_mode; + vi_replace_map[RETURN].function = rl_newline; + vi_replace_map[NEWLINE].function = rl_newline; + + /* If the normal vi insertion keymap has ^H bound to erase, do the + same here. Probably should remove the assignment to RUBOUT up + there, but I don't think it will make a difference in real life. */ + if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC && + vi_insertion_keymap[CTRL ('H')].function == rl_rubout) + vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; + + /* Same for ^U and unix-line-discard. */ + if (vi_insertion_keymap[CTRL ('U')].type == ISFUNC && + vi_insertion_keymap[CTRL ('U')].function == rl_unix_line_discard) + vi_replace_map[CTRL ('U')].function = rl_vi_overstrike_kill_line; + + /* And for ^W and unix-word-rubout. */ + if (vi_insertion_keymap[CTRL ('W')].type == ISFUNC && + vi_insertion_keymap[CTRL ('W')].function == rl_vi_unix_word_rubout) + vi_replace_map[CTRL ('W')].function = rl_vi_overstrike_kill_word; + + /* And finally for ^Y and yank. */ + if (vi_insertion_keymap[CTRL ('Y')].type == ISFUNC && + vi_insertion_keymap[CTRL ('Y')].function == rl_yank) + vi_replace_map[CTRL ('Y')].function = rl_vi_overstrike_yank; + + /* Make sure this is the value we need. */ + vi_replace_map[ANYOTHERKEY].type = ISFUNC; + vi_replace_map[ANYOTHERKEY].function = (rl_command_func_t *)NULL; + } + + rl_vi_start_inserting (key, 1, rl_arg_sign); + + _rl_vi_last_key_before_insert = 'R'; /* in case someone rebinds it */ + _rl_keymap = vi_replace_map; + + if (_rl_enable_bracketed_paste) + rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_vi_overstrike_bracketed_paste); + + return (0); +} + +#if 0 +/* Try to complete the word we are standing on or the word that ends with + the previous character. A space matches everything. Word delimiters are + space and ;. */ +int +rl_vi_possible_completions (void) +{ + int save_pos = rl_point; + + if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';') + { + while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' && + rl_line_buffer[rl_point] != ';') + _rl_vi_advance_point (); + } + else if (rl_line_buffer[rl_point - 1] == ';') + { + rl_ding (); + return (0); + } + + rl_possible_completions (); + rl_point = save_pos; + + return (0); +} +#endif + +/* Functions to save and restore marks. */ +static int +_rl_vi_set_mark (void) +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */ + { + rl_ding (); + return 1; + } + ch -= 'a'; + vi_mark_chars[ch] = rl_point; + return 0; +} + +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_set_mark (_rl_callback_generic_arg *data) +{ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_vi_set_mark ()); +} +#endif + +int +rl_vi_set_mark (int count, int key) +{ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = 0; + _rl_callback_func = _rl_vi_callback_set_mark; + return (0); + } +#endif + + return (_rl_vi_set_mark ()); +} + +static int +_rl_vi_goto_mark (void) +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (ch == '`') + { + rl_point = rl_mark; + _rl_fix_point (1); + return 0; + } + else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */ + { + rl_ding (); + return 1; + } + + ch -= 'a'; + if (vi_mark_chars[ch] == -1) + { + rl_ding (); + return 1; + } + rl_point = vi_mark_chars[ch]; + _rl_fix_point (1); + return 0; +} + +#if defined (READLINE_CALLBACKS) +static int +_rl_vi_callback_goto_mark (_rl_callback_generic_arg *data) +{ + _rl_callback_func = 0; + _rl_want_redisplay = 1; + + return (_rl_vi_goto_mark ()); +} +#endif + +int +rl_vi_goto_mark (int count, int key) +{ +#if defined (READLINE_CALLBACKS) + if (RL_ISSTATE (RL_STATE_CALLBACK)) + { + _rl_callback_data = 0; + _rl_callback_func = _rl_vi_callback_goto_mark; + return (0); + } +#endif + + return (_rl_vi_goto_mark ()); +} +#endif /* VI_MODE */ diff --git a/utshell-0.5.0/lib/readline/xfree.c b/utshell-0.5.0/lib/readline/xfree.c new file mode 100644 index 00000000..c199b29b --- /dev/null +++ b/utshell-0.5.0/lib/readline/xfree.c @@ -0,0 +1,49 @@ +/* xfree.c -- safe version of free that ignores attempts to free NUL */ + +/* Copyright (C) 1991-2010,2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Memory Deallocation. */ +/* */ +/* **************************************************************** */ + +/* Use this as the function to call when adding unwind protects so we + don't need to know what free() returns. */ +void +xfree (PTR_T string) +{ + if (string) + free (string); +} diff --git a/utshell-0.5.0/lib/readline/xmalloc.c b/utshell-0.5.0/lib/readline/xmalloc.c new file mode 100644 index 00000000..5d01d75e --- /dev/null +++ b/utshell-0.5.0/lib/readline/xmalloc.c @@ -0,0 +1,75 @@ +/* xmalloc.c -- safe versions of malloc and realloc */ + +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Memory Allocation and Deallocation. */ +/* */ +/* **************************************************************** */ + +static void +memory_error_and_abort (char *fname) +{ + fprintf (stderr, "%s: out of virtual memory\n", fname); + exit (2); +} + +/* Return a pointer to free()able block of memory large enough + to hold BYTES number of bytes. If the memory cannot be allocated, + print an error message and abort. */ +PTR_T +xmalloc (size_t bytes) +{ + PTR_T temp; + + temp = malloc (bytes); + if (temp == 0) + memory_error_and_abort ("xmalloc"); + return (temp); +} + +PTR_T +xrealloc (PTR_T pointer, size_t bytes) +{ + PTR_T temp; + + temp = pointer ? realloc (pointer, bytes) : malloc (bytes); + + if (temp == 0) + memory_error_and_abort ("xrealloc"); + return (temp); +} diff --git a/utshell-0.5.0/lib/readline/xmalloc.h b/utshell-0.5.0/lib/readline/xmalloc.h new file mode 100644 index 00000000..f40d7a59 --- /dev/null +++ b/utshell-0.5.0/lib/readline/xmalloc.h @@ -0,0 +1,45 @@ +/* xmalloc.h -- memory allocation that aborts on errors. */ + +/* Copyright (C) 1999-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_XMALLOC_H_) +#define _XMALLOC_H_ + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +#else +# include +#endif + +#ifndef PTR_T + +#ifdef __STDC__ +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* !PTR_T */ + +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); + +#endif /* _XMALLOC_H_ */ diff --git a/utshell-0.5.0/lib/sh/Makefile b/utshell-0.5.0/lib/sh/Makefile new file mode 100644 index 00000000..9ba3661b --- /dev/null +++ b/utshell-0.5.0/lib/sh/Makefile @@ -0,0 +1,641 @@ +# +# Makefile for the Bash library +# +# +# Copyright (C) 1998-2020 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PACKAGE = utshell +VERSION = 0.1-release + +PACKAGE_BUGREPORT = bug-utshell@gnu.org +PACKAGE_NAME = utshell +PACKAGE_STRING = utshell 0.1-release +PACKAGE_VERSION = 0.1-release + +srcdir = . + +topdir = ../ +topdiri = ../include +BUILD_DIR = ../include + +LIBBUILD = ${BUILD_DIR}/lib + +BASHINCDIR = ${topdir}/include + +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = +LIBINTL_H = + +datarootdir = ${prefix}/share + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CC = gcc +RANLIB = ranlib +AR = ar +ARFLAGS = cr +RM = rm -f +CP = cp +MV = mv + +SHELL = /bin/sh + +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security -fPIC +LOCAL_CFLAGS = ${DEBUG} +CPPFLAGS = +LDFLAGS = -L./lib/termcap -rdynamic + +PROFILE_FLAGS = + +DEFS = -DHAVE_CONFIG_H +LOCAL_DEFS = -DSHELL + +#INCLUDES = -I. -I../include -I$(topdir)/include -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC) +INCLUDES = -I. -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC) + +CCFLAGS = ${ADDON_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \ + $(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS) + +GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wstrict-prototypes -Wconversion \ + -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic + +.c.o: + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libsh.a + +# The C code source files for this library. +CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ + strcasecmp.c strerror.c strtod.c strtol.c strtoul.c \ + vprint.c itos.c rename.c zread.c zwrite.c shtty.c \ + inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \ + pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \ + shquote.c strtrans.c strcasestr.c snprintf.c mailstat.c \ + fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \ + strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \ + mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \ + wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \ + casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \ + strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c \ + utf8.c random.c gettimeofday.c + +# The header files for this library. +HSOURCES = + +# The object files contained in $(LIBRARY_NAME) +LIBOBJS = ${LIBOBJDIR}mbschr$U.o +OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ + itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.o \ + netconn.o netopen.o timeval.o makepath.o pathcanon.o \ + pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \ + strtrans.o snprintf.o mailstat.o fmtulong.o \ + fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \ + fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \ + input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \ + utf8.o random.o gettimeofday.o wcsnwidth.o ${LIBOBJS} + +SUPPORT = Makefile + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + +clean: + $(RM) $(OBJECTS) $(LIBRARY_NAME) + +realclean distclean maintainer-clean: clean + $(RM) Makefile + +mostlyclean: clean + +# Dependencies + +${BUILD_DIR}/version.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile + -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h ) + +#${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile +# -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h ) + +# rules for losing makes, like SunOS +casemod.o: casemod.c +clktck.o: clktck.c +clock.o: clock.c +eaccess.o: eaccess.c +dprintf.o: dprintf.c +fmtullong.o: fmtullong.c +fmtulong.o: fmtulong.c +fmtumax.o: fmtumax.c +fnxform.o: fnxform.c +fpurge.o: fpurge.c +getcwd.o: getcwd.c +getenv.o: getenv.c +gettimeofday.o: gettimeofday.c +inet_aton.o: inet_aton.c +input_avail.o: input_avail.c +itos.o: itos.c +mailstat.o: mailstat.c +makepath.o: makepath.c +mbscasecmp.o: mbscasecmp.c +mbschr.o: mbschr.c +mbscmp.o: mbscmp.c +memset.o: memset.c +mktime.o: mktime.c +netconn.o: netconn.c +netopen.o: netopen.c +oslib.o: oslib.c +pathcanon.o: pathcanon.c +pathphys.o: pathphys.c +random.o: random.c +rename.o: rename.c +setlinebuf.o: setlinebuf.c +shmatch.o: shmatch.c +shmbchar.o: shmbchar.c +shquote.o: shquote.c +shtty.o: shtty.c +snprintf.o: snprintf.c +spell.o: spell.c +strcasecmp.o: strcasecmp.c +strchrnul.o: strchrnul.c +strerror.o: strerror.c +strftime.o: strftime.c +strcasestr.o: strcasestr.c +stringlist.o: stringlist.c +stringvec.o: stringvec.c +strnlen.o: strnlen.c +strpbrk.o: strpbrk.c +strtod.o: strtod.c +strtoimax.o: strtoimax.c +strtol.o: strtol.c +strtoll.o: strtoll.c +strtoul.o: strtoul.c +strtoull.o: strtoull.c +strtoumax.o: strtoumax.c +strtrans.o: strtrans.c +times.o: times.c +timeval.o: timeval.c +tmpfile.o: tmpfile.c +uconvert.o: uconvert.c +ufuncs.o: ufuncs.c +unicode.o: unicode.c +utf8.o: utf8.c +vprint.o: vprint.c +wcsdup.o: wcsdup.c +wcsnwidth.o: wcsnwidth.c +wcswidth.o: wcswidth.c +winsize.o: winsize.c +zcatfd.o: zcatfd.c +zmapfd.o: zmapfd.c +zgetline.o: zgetline.c +zread.o: zread.c +zwrite.o: zwrite.c + +# dependencies for c files that include other c files +fmtullong.o: fmtulong.c +fmtumax.o: fmtulong.c +strtoll.o: strtol.c +strtoul.o: strtol.c +strtoull.o: strtol.c + +# all files in the library depend on config.h +casemod.o: ${BUILD_DIR}/config.h +clktck.o: ${BUILD_DIR}/config.h +clock.o: ${BUILD_DIR}/config.h +eaccess.o: ${BUILD_DIR}/config.h +dprintf.o: ${BUILD_DIR}/config.h +fmtullong.o: ${BUILD_DIR}/config.h +fmtulong.o: ${BUILD_DIR}/config.h +fmtumax.o: ${BUILD_DIR}/config.h +fnxform.o: ${BUILD_DIR}/config.h +fpurge.o: ${BUILD_DIR}/config.h +getcwd.o: ${BUILD_DIR}/config.h +getenv.o: ${BUILD_DIR}/config.h +gettimeofday.o: ${BUILD_DIR}/config.h +inet_aton.o: ${BUILD_DIR}/config.h +input_avail.o: ${BUILD_DIR}/config.h +itos.o: ${BUILD_DIR}/config.h +mailstat.o: ${BUILD_DIR}/config.h +makepath.o: ${BUILD_DIR}/config.h +mbscasecmp.o: ${BUILD_DIR}/config.h +mbschr.o: ${BUILD_DIR}/config.h +mbscmp.o: ${BUILD_DIR}/config.h +memset.o: ${BUILD_DIR}/config.h +mktime.o: ${BUILD_DIR}/config.h +netconn.o: ${BUILD_DIR}/config.h +netopen.o: ${BUILD_DIR}/config.h +oslib.o: ${BUILD_DIR}/config.h +pathcanon.o: ${BUILD_DIR}/config.h +pathphys.o: ${BUILD_DIR}/config.h +random.o: ${BUILD_DIR}/config.h +rename.o: ${BUILD_DIR}/config.h +setlinebuf.o: ${BUILD_DIR}/config.h +shmatch.o: ${BUILD_DIR}/config.h +shmbchar.o: ${BUILD_DIR}/config.h +shquote.o: ${BUILD_DIR}/config.h +shtty.o: ${BUILD_DIR}/config.h +snprintf.o: ${BUILD_DIR}/config.h +spell.o: ${BUILD_DIR}/config.h +strcasecmp.o: ${BUILD_DIR}/config.h +strchrnul.o: ${BUILD_DIR}/config.h +strerror.o: ${BUILD_DIR}/config.h +strftime.o: ${BUILD_DIR}/config.h +strcasestr.o: ${BUILD_DIR}/config.h +stringlist.o: ${BUILD_DIR}/config.h +stringvec.o: ${BUILD_DIR}/config.h +strnlen.o: ${BUILD_DIR}/config.h +strpbrk.o: ${BUILD_DIR}/config.h +strtod.o: ${BUILD_DIR}/config.h +strtoimax.o: ${BUILD_DIR}/config.h +strtol.o: ${BUILD_DIR}/config.h +strtoll.o: ${BUILD_DIR}/config.h +strtoul.o: ${BUILD_DIR}/config.h +strtoull.o: ${BUILD_DIR}/config.h +strtoumax.o: ${BUILD_DIR}/config.h +strtrans.o: ${BUILD_DIR}/config.h +times.o: ${BUILD_DIR}/config.h +timeval.o: ${BUILD_DIR}/config.h +tmpfile.o: ${BUILD_DIR}/config.h ${topdiri}/config-top.h +uconvert.o: ${BUILD_DIR}/config.h +ufuncs.o: ${BUILD_DIR}/config.h +unicode.o: ${BUILD_DIR}/config.h +utf8.o: ${BUILD_DIR}/config.h +vprint.o: ${BUILD_DIR}/config.h +wcsdup.o: ${BUILD_DIR}/config.h +wcsnwidth.o: ${BUILD_DIR}/config.h +wcswidth.o: ${BUILD_DIR}/config.h +winsize.o: ${BUILD_DIR}/config.h +zcatfd.o: ${BUILD_DIR}/config.h +zgetline.o: ${BUILD_DIR}/config.h +zmapfd.o: ${BUILD_DIR}/config.h +zread.o: ${BUILD_DIR}/config.h +zwrite.o: ${BUILD_DIR}/config.h + +clktck.o: ${topdiri}/bashtypes.h + +getcwd.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h +getcwd.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h +getcwd.o: ${BASHINCDIR}/memalloc.h ${BASHINCDIR}/ansi_stdlib.h + +getenv.o: ${topdir}/include/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +getenv.o: ${topdir}/include/shell.h ${topdir}/include/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +getenv.o: ${topdir}/include/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +getenv.o: ${topdir}/include/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +getenv.o: ${topdir}/include/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +getenv.o: ${topdir}/include/unwind_prot.h ${topdiri}/dispose_cmd.h +getenv.o: ${topdir}/include/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +getenv.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +#getenv.o: ${BUILD_DIR}/version.h + +inet_aton.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +inet_aton.o: ${BASHINCDIR}/stdc.h + +itos.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +itos.o: ${topdiri}/shell.h ${topdir}/include/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +itos.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +itos.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +itos.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +itos.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +itos.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +itos.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +#itos.o: ${BUILD_DIR}/version.h + +makepath.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +makepath.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +makepath.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +makepath.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +makepath.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +makepath.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +makepath.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +makepath.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +#makepath.o: ${BUILD_DIR}/version.h + +netconn.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +netconn.o: ${topdiri}/bashtypes.h + +netopen.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${topdiri}/xmalloc.h +netopen.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +netopen.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +netopen.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +netopen.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +netopen.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +netopen.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +netopen.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +netopen.o: ${topdiri}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +#netopen.o: ${BUILD_DIR}/version.h + +oslib.o: ${topdiri}/bashtypes.h ${topdiri}/bashansi.h ${BASHINCDIR}/maxpath.h +oslib.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +oslib.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +oslib.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +oslib.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +oslib.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +oslib.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +oslib.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +oslib.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +oslib.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +#oslib.o: ${BUILD_DIR}/version.h + +pathcanon.o: ${topdiri}/bashtypes.h ${topdiri}/bashansi.h ${BASHINCDIR}/maxpath.h +pathcanon.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +pathcanon.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +pathcanon.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +pathcanon.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +pathcanon.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +pathcanon.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +pathcanon.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +pathcanon.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +#pathcanon.o: ${BUILD_DIR}/version.h + +pathphys.o: ${topdiri}/bashtypes.h ${topdiri}/bashansi.h ${BASHINCDIR}/maxpath.h +pathphys.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +pathphys.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +pathphys.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +pathphys.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +pathphys.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +pathphys.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +pathphys.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +#pathphys.o: ${BUILD_DIR}/version.h + +random.o: ${topdiri}/bashtypes.h ${BASHINCDIR}/stdc.h +random.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +random.o: ${BASHINCDIR}/filecntl.h + +rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h +rename.o: ${BASHINCDIR}/posixstat.h + +setlinebuf.o: ${topdiri}/xmalloc.h ${topdiri}/bashansi.h +setlinebuf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/stdc.h + +eaccess.o: ${topdiri}/bashtypes.h +eaccess.o: ${BASHINCDIR}/posixstat.h +eaccess.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +eaccess.o: ${BASHINCDIR}/filecntl.h +eaccess.o: ${BASHINCDIR}/stdc.h +eaccess.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +eaccess.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +eaccess.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +eaccess.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +eaccess.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +eaccess.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +eaccess.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +#eaccess.o: ${BUILD_DIR}/version.h + +shmatch.o: ${BASHINCDIR}/stdc.h ${topdiri}/bashansi.h +shmatch.o: ${BASHINCDIR}/ansi_stdlib.h ${topdiri}/xmalloc.h +shmatch.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +shmatch.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +shmatch.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +shmatch.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +shmatch.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +shmatch.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +shmatch.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h + +shquote.o: ${BASHINCDIR}/stdc.h ${topdiri}/bashansi.h +shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdiri}/xmalloc.h +shquote.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h + +shtty.o: ${BASHINCDIR}/shtty.h +shtty.o: ${BASHINCDIR}/stdc.h + +snprintf.o: ${BASHINCDIR}/stdc.h ${topdiri}/bashansi.h ${topdiri}/xmalloc.h +snprintf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +snprintf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h +snprintf.o: ${BASHINCDIR}/typemax.h + +spell.o: ${topdiri}/bashtypes.h +spell.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h +spell.o: ${BASHINCDIR}/ansi_stdlib.h + +strcasecmp.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +strcasecmp.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +strerror.o: ${topdir}/bashtypes.h +strerror.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +strerror.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +strerror.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#strerror.o: ${BUILD_DIR}/version.h + +strcasestr.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +strcasestr.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +stringlist.o: ${topdiri}/bashansi.h +stringlist.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +stringlist.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +stringlist.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +stringlist.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +stringlist.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +stringlist.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +stringlist.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +#stringlist.o: ${BUILD_DIR}/version.h + +stringvec.o: ${topdiri}/bashansi.h ${BASHINCDIR}/chartypes.h +stringvec.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +stringvec.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +stringvec.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +stringvec.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +stringvec.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +stringvec.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +stringvec.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +#stringvec.o: ${BUILD_DIR}/version.h + +strnlen.o: ${BASHINCDIR}/stdc.h + +strpbrk.o: ${BASHINCDIR}/stdc.h + +strtod.o: ${topdir}/bashansi.h +strtod.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +strtoimax.o: ${BASHINCDIR}/stdc.h + +strtol.o: ${topdir}/bashansi.h +strtol.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtol.o: ${BASHINCDIR}/typemax.h + +strtoll.o: ${topdir}/bashansi.h +strtoll.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoll.o: ${BASHINCDIR}/typemax.h + +strtoul.o: ${topdir}/bashansi.h +strtoul.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoul.o: ${BASHINCDIR}/typemax.h + +strtoull.o: ${topdir}/bashansi.h +strtoull.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoull.o: ${BASHINCDIR}/typemax.h + +strtoumax.o: ${BASHINCDIR}/stdc.h + +strtrans.o: ${topdiri}/bashansi.h +strtrans.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtrans.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +strtrans.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +strtrans.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +strtrans.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +strtrans.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +strtrans.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +strtrans.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h +strtrans.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h +#strtrans.o: ${BUILD_DIR}/version.h + +times.o: ${BASHINCDIR}/systimes.h +times.o: ${BASHINCDIR}/posixtime.h + +timeval.o: ${BASHINCDIR}/posixtime.h +gettimeofday.o: ${BASHINCDIR}/posixtime.h + +tmpfile.o: ${topdiri}/bashtypes.h +tmpfile.o: ${BASHINCDIR}/chartypes.h +tmpfile.o: ${BASHINCDIR}/posixstat.h +tmpfile.o: ${BASHINCDIR}/filecntl.h +tmpfile.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +tmpfile.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +tmpfile.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +tmpfile.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +tmpfile.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +tmpfile.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +tmpfile.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h + +uconvert.o: ${topdiri}/bashtypes.h +uconvert.o: ${BASHINCDIR}/chartypes.h +uconvert.o: ${topdiri}/shell.h ${topdiri}/syntax.h ${topdiri}/bashjmp.h ${BASHINCDIR}/posixjmp.h +uconvert.o: ${topdiri}/command.h ${BASHINCDIR}/stdc.h ${topdiri}/error.h +uconvert.o: ${topdiri}/general.h ${topdiri}/bashtypes.h ${topdiri}/variables.h ${topdiri}/conftypes.h +uconvert.o: ${topdiri}/array.h ${topdiri}/hashlib.h ${topdiri}/quit.h +uconvert.o: ${topdiri}/unwind_prot.h ${topdiri}/dispose_cmd.h +uconvert.o: ${topdiri}/make_cmd.h ${topdiri}/subst.h ${topdiri}/sig.h +uconvert.o: ${BUILD_DIR}/pathnames.h ${topdiri}/externs.h + +ufuncs.o: ${topdiri}/bashtypes.h + +clock.o: ${BASHINCDIR}/posixtime.h + +mailstat.o: ${topdiri}/bashansi.h +mailstat.o: ${topdiri}/bashtypes.h +mailstat.o: ${BASHINCDIR}/ansi_stdlib.h +mailstat.o: ${BASHINCDIR}/posixstat.h +mailstat.o: ${BASHINCDIR}/posixdir.h +mailstat.o: ${BASHINCDIR}/maxpath.h + +fmtulong.o: ${topdiri}/bashansi.h +fmtulong.o: ${BASHINCDIR}/ansi_stdlib.h +fmtulong.o: ${BASHINCDIR}/chartypes.h +fmtulong.o: ${BASHINCDIR}/stdc.h +fmtulong.o: ${BASHINCDIR}/typemax.h +fmtulong.o: ${topdiri}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +fmtullong.o: ${topdiri}/bashansi.h +fmtullong.o: ${BASHINCDIR}/ansi_stdlib.h +fmtullong.o: ${BASHINCDIR}/chartypes.h +fmtullong.o: ${BASHINCDIR}/stdc.h +fmtullong.o: ${BASHINCDIR}/typemax.h +fmtullong.o: ${topdiri}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +fmtumax.o: ${topdiri}/bashansi.h +fmtumax.o: ${BASHINCDIR}/ansi_stdlib.h +fmtumax.o: ${BASHINCDIR}/chartypes.h +fmtumax.o: ${BASHINCDIR}/stdc.h +fmtumax.o: ${BASHINCDIR}/typemax.h +fmtumax.o: ${topdiri}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +wcsdup.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcsdup.o: ${BASHINCDIR}/stdc.h +wcsdup.o: ${topdiri}/xmalloc.h + +wcsnwidth.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcsnwidth.o: ${BASHINCDIR}/stdc.h + +wcswidth.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcswidth.o: ${BASHINCDIR}/stdc.h + +mbschr.o: ${topdiri}/bashansi.h +mbschr.o: ${BASHINCDIR}/ansi_stdlib.h +mbschr.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h + +zgetline.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +zgetline.o: ${BASHINCDIR}/stdc.h +zgetline.o: ${topdiri}/xmalloc.h +zgetline.o: ${topdiri}/bashtypes.h + +mbscasecmp.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mbscasecmp.o: ${BASHINCDIR}/stdc.h +mbscasecmp.o: ${topdiri}/xmalloc.h + +mbscmp.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mbscmp.o: ${BASHINCDIR}/stdc.h +mbscmp.o: ${topdiri}/xmalloc.h + +casemod.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +casemod.o: ${BASHINCDIR}/stdc.h +casemod.o: ${topdiri}/xmalloc.h +casemod.o: ${topdiri}/bashtypes.h +casemod.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h +casemod.o: ${topdiri}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +dprintf.o: ${BASHINCDIR}/stdc.h + +input_avail.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +input_avail.o: ${BASHINCDIR}/stdc.h +input_avail.o: ${topdiri}/xmalloc.h ${BASHINCDIR}/posixselect.h + +mktime.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mktime.o: ${BASHINCDIR}/stdc.h + +fnxform.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +fnxform.o: ${BASHINCDIR}/stdc.h +fnxform.o: ${topdiri}/bashtypes.h +fnxform.o: ${topdiri}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +shmbchar.o: ${BASHINCDIR}/shmbchar.h +shmbchar.o: ${BASHINCDIR}/shmbutil.h + +unicode.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +unicode.o: ${BASHINCDIR}/stdc.h +unicode.o: ${topdiri}/xmalloc.h + +utf8.o: ${topdiri}/bashansi.h +utf8.o: ${BASHINCDIR}/ansi_stdlib.h +utf8.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h + +winsize.o: ${BASHINCDIR}/stdc.h +winsize.o: ${topdiri}/xmalloc.h +winsize.o: ${topdiri}/bashtypes.h + +zmapfd.o: ${topdiri}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +zmapfd.o: ${BASHINCDIR}/stdc.h +zmapfd.o: ${topdiri}/command.h +zmapfd.o: ${topdiri}/general.h +zmapfd.o: ${topdiri}/bashtypes.h ${BASHINCDIR}/chartypes.h ${topdiri}/xmalloc.h diff --git a/utshell-0.5.0/lib/sh/Makefile.in b/utshell-0.5.0/lib/sh/Makefile.in new file mode 100644 index 00000000..98064de5 --- /dev/null +++ b/utshell-0.5.0/lib/sh/Makefile.in @@ -0,0 +1,639 @@ +# +# Makefile for the Bash library +# +# +# Copyright (C) 1998-2020 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + +srcdir = @srcdir@ +VPATH = @srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +LIBBUILD = ${BUILD_DIR}/lib + +BASHINCDIR = ${topdir}/include + +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = @INTL_INC@ +LIBINTL_H = @LIBINTL_H@ + +datarootdir = @datarootdir@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv + +SHELL = @MAKE_SHELL@ + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG} +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ + +PROFILE_FLAGS = @PROFILE_FLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC) + +CCFLAGS = ${ADDON_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \ + $(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS) + +GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wstrict-prototypes -Wconversion \ + -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic + +.c.o: + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libsh.a + +# The C code source files for this library. +CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ + strcasecmp.c strerror.c strtod.c strtol.c strtoul.c \ + vprint.c itos.c rename.c zread.c zwrite.c shtty.c \ + inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \ + pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \ + shquote.c strtrans.c strcasestr.c snprintf.c mailstat.c \ + fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \ + strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \ + mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \ + wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \ + casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \ + strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c \ + utf8.c random.c gettimeofday.c + +# The header files for this library. +HSOURCES = + +# The object files contained in $(LIBRARY_NAME) +LIBOBJS = @LIBOBJS@ +OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ + itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.o \ + netconn.o netopen.o timeval.o makepath.o pathcanon.o \ + pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \ + strtrans.o snprintf.o mailstat.o fmtulong.o \ + fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \ + fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \ + input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \ + utf8.o random.o gettimeofday.o wcsnwidth.o ${LIBOBJS} + +SUPPORT = Makefile + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + +clean: + $(RM) $(OBJECTS) $(LIBRARY_NAME) + +realclean distclean maintainer-clean: clean + $(RM) Makefile + +mostlyclean: clean + +# Dependencies + +${BUILD_DIR}/version.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile + -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} version.h ) + +${BUILD_DIR}/pathnames.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile + -( cd ${BUILD_DIR} && ${MAKE} ${MFLAGS} pathnames.h ) + +# rules for losing makes, like SunOS +casemod.o: casemod.c +clktck.o: clktck.c +clock.o: clock.c +eaccess.o: eaccess.c +dprintf.o: dprintf.c +fmtullong.o: fmtullong.c +fmtulong.o: fmtulong.c +fmtumax.o: fmtumax.c +fnxform.o: fnxform.c +fpurge.o: fpurge.c +getcwd.o: getcwd.c +getenv.o: getenv.c +gettimeofday.o: gettimeofday.c +inet_aton.o: inet_aton.c +input_avail.o: input_avail.c +itos.o: itos.c +mailstat.o: mailstat.c +makepath.o: makepath.c +mbscasecmp.o: mbscasecmp.c +mbschr.o: mbschr.c +mbscmp.o: mbscmp.c +memset.o: memset.c +mktime.o: mktime.c +netconn.o: netconn.c +netopen.o: netopen.c +oslib.o: oslib.c +pathcanon.o: pathcanon.c +pathphys.o: pathphys.c +random.o: random.c +rename.o: rename.c +setlinebuf.o: setlinebuf.c +shmatch.o: shmatch.c +shmbchar.o: shmbchar.c +shquote.o: shquote.c +shtty.o: shtty.c +snprintf.o: snprintf.c +spell.o: spell.c +strcasecmp.o: strcasecmp.c +strchrnul.o: strchrnul.c +strerror.o: strerror.c +strftime.o: strftime.c +strcasestr.o: strcasestr.c +stringlist.o: stringlist.c +stringvec.o: stringvec.c +strnlen.o: strnlen.c +strpbrk.o: strpbrk.c +strtod.o: strtod.c +strtoimax.o: strtoimax.c +strtol.o: strtol.c +strtoll.o: strtoll.c +strtoul.o: strtoul.c +strtoull.o: strtoull.c +strtoumax.o: strtoumax.c +strtrans.o: strtrans.c +times.o: times.c +timeval.o: timeval.c +tmpfile.o: tmpfile.c +uconvert.o: uconvert.c +ufuncs.o: ufuncs.c +unicode.o: unicode.c +utf8.o: utf8.c +vprint.o: vprint.c +wcsdup.o: wcsdup.c +wcsnwidth.o: wcsnwidth.c +wcswidth.o: wcswidth.c +winsize.o: winsize.c +zcatfd.o: zcatfd.c +zmapfd.o: zmapfd.c +zgetline.o: zgetline.c +zread.o: zread.c +zwrite.o: zwrite.c + +# dependencies for c files that include other c files +fmtullong.o: fmtulong.c +fmtumax.o: fmtulong.c +strtoll.o: strtol.c +strtoul.o: strtol.c +strtoull.o: strtol.c + +# all files in the library depend on config.h +casemod.o: ${BUILD_DIR}/config.h +clktck.o: ${BUILD_DIR}/config.h +clock.o: ${BUILD_DIR}/config.h +eaccess.o: ${BUILD_DIR}/config.h +dprintf.o: ${BUILD_DIR}/config.h +fmtullong.o: ${BUILD_DIR}/config.h +fmtulong.o: ${BUILD_DIR}/config.h +fmtumax.o: ${BUILD_DIR}/config.h +fnxform.o: ${BUILD_DIR}/config.h +fpurge.o: ${BUILD_DIR}/config.h +getcwd.o: ${BUILD_DIR}/config.h +getenv.o: ${BUILD_DIR}/config.h +gettimeofday.o: ${BUILD_DIR}/config.h +inet_aton.o: ${BUILD_DIR}/config.h +input_avail.o: ${BUILD_DIR}/config.h +itos.o: ${BUILD_DIR}/config.h +mailstat.o: ${BUILD_DIR}/config.h +makepath.o: ${BUILD_DIR}/config.h +mbscasecmp.o: ${BUILD_DIR}/config.h +mbschr.o: ${BUILD_DIR}/config.h +mbscmp.o: ${BUILD_DIR}/config.h +memset.o: ${BUILD_DIR}/config.h +mktime.o: ${BUILD_DIR}/config.h +netconn.o: ${BUILD_DIR}/config.h +netopen.o: ${BUILD_DIR}/config.h +oslib.o: ${BUILD_DIR}/config.h +pathcanon.o: ${BUILD_DIR}/config.h +pathphys.o: ${BUILD_DIR}/config.h +random.o: ${BUILD_DIR}/config.h +rename.o: ${BUILD_DIR}/config.h +setlinebuf.o: ${BUILD_DIR}/config.h +shmatch.o: ${BUILD_DIR}/config.h +shmbchar.o: ${BUILD_DIR}/config.h +shquote.o: ${BUILD_DIR}/config.h +shtty.o: ${BUILD_DIR}/config.h +snprintf.o: ${BUILD_DIR}/config.h +spell.o: ${BUILD_DIR}/config.h +strcasecmp.o: ${BUILD_DIR}/config.h +strchrnul.o: ${BUILD_DIR}/config.h +strerror.o: ${BUILD_DIR}/config.h +strftime.o: ${BUILD_DIR}/config.h +strcasestr.o: ${BUILD_DIR}/config.h +stringlist.o: ${BUILD_DIR}/config.h +stringvec.o: ${BUILD_DIR}/config.h +strnlen.o: ${BUILD_DIR}/config.h +strpbrk.o: ${BUILD_DIR}/config.h +strtod.o: ${BUILD_DIR}/config.h +strtoimax.o: ${BUILD_DIR}/config.h +strtol.o: ${BUILD_DIR}/config.h +strtoll.o: ${BUILD_DIR}/config.h +strtoul.o: ${BUILD_DIR}/config.h +strtoull.o: ${BUILD_DIR}/config.h +strtoumax.o: ${BUILD_DIR}/config.h +strtrans.o: ${BUILD_DIR}/config.h +times.o: ${BUILD_DIR}/config.h +timeval.o: ${BUILD_DIR}/config.h +tmpfile.o: ${BUILD_DIR}/config.h ${topdir}/config-top.h +uconvert.o: ${BUILD_DIR}/config.h +ufuncs.o: ${BUILD_DIR}/config.h +unicode.o: ${BUILD_DIR}/config.h +utf8.o: ${BUILD_DIR}/config.h +vprint.o: ${BUILD_DIR}/config.h +wcsdup.o: ${BUILD_DIR}/config.h +wcsnwidth.o: ${BUILD_DIR}/config.h +wcswidth.o: ${BUILD_DIR}/config.h +winsize.o: ${BUILD_DIR}/config.h +zcatfd.o: ${BUILD_DIR}/config.h +zgetline.o: ${BUILD_DIR}/config.h +zmapfd.o: ${BUILD_DIR}/config.h +zread.o: ${BUILD_DIR}/config.h +zwrite.o: ${BUILD_DIR}/config.h + +clktck.o: ${topdir}/bashtypes.h + +getcwd.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h +getcwd.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h +getcwd.o: ${BASHINCDIR}/memalloc.h ${BASHINCDIR}/ansi_stdlib.h + +getenv.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +getenv.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +getenv.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +getenv.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +getenv.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +getenv.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +getenv.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +getenv.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#getenv.o: ${BUILD_DIR}/version.h + +inet_aton.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +inet_aton.o: ${BASHINCDIR}/stdc.h + +itos.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +itos.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +itos.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +itos.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +itos.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +itos.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +itos.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +itos.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#itos.o: ${BUILD_DIR}/version.h + +makepath.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +makepath.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +makepath.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +makepath.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +makepath.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +makepath.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +makepath.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +makepath.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#makepath.o: ${BUILD_DIR}/version.h + +netconn.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +netconn.o: ${topdir}/bashtypes.h + +netopen.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h +netopen.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +netopen.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +netopen.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +netopen.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +netopen.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +netopen.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +netopen.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +#netopen.o: ${BUILD_DIR}/version.h + +oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h +oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +oslib.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +oslib.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +oslib.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +oslib.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +oslib.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +oslib.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +oslib.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +oslib.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +#oslib.o: ${BUILD_DIR}/version.h + +pathcanon.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h +pathcanon.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +pathcanon.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +pathcanon.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +pathcanon.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +pathcanon.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +pathcanon.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +pathcanon.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +pathcanon.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +#pathcanon.o: ${BUILD_DIR}/version.h + +pathphys.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h +pathphys.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +pathphys.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +pathphys.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +pathphys.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +pathphys.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +pathphys.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +pathphys.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +#pathphys.o: ${BUILD_DIR}/version.h + +random.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h +random.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +random.o: ${BASHINCDIR}/filecntl.h + +rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h +rename.o: ${BASHINCDIR}/posixstat.h + +setlinebuf.o: ${topdir}/xmalloc.h ${topdir}/bashansi.h +setlinebuf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/stdc.h + +eaccess.o: ${topdir}/bashtypes.h +eaccess.o: ${BASHINCDIR}/posixstat.h +eaccess.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +eaccess.o: ${BASHINCDIR}/filecntl.h +eaccess.o: ${BASHINCDIR}/stdc.h +eaccess.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +eaccess.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +eaccess.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +eaccess.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +eaccess.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +eaccess.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +eaccess.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#eaccess.o: ${BUILD_DIR}/version.h + +shmatch.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +shmatch.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h +shmatch.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +shmatch.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +shmatch.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +shmatch.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +shmatch.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +shmatch.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +shmatch.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h + +shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h +shquote.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h + +shtty.o: ${BASHINCDIR}/shtty.h +shtty.o: ${BASHINCDIR}/stdc.h + +snprintf.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h ${topdir}/xmalloc.h +snprintf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +snprintf.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h +snprintf.o: ${BASHINCDIR}/typemax.h + +spell.o: ${topdir}/bashtypes.h +spell.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h +spell.o: ${BASHINCDIR}/ansi_stdlib.h + +strcasecmp.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +strcasecmp.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +strerror.o: ${topdir}/bashtypes.h +strerror.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +strerror.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +strerror.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#strerror.o: ${BUILD_DIR}/version.h + +strcasestr.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +strcasestr.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +stringlist.o: ${topdir}/bashansi.h +stringlist.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +stringlist.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +stringlist.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +stringlist.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +stringlist.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +stringlist.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +stringlist.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#stringlist.o: ${BUILD_DIR}/version.h + +stringvec.o: ${topdir}/bashansi.h ${BASHINCDIR}/chartypes.h +stringvec.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +stringvec.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +stringvec.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +stringvec.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +stringvec.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +stringvec.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +stringvec.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +#stringvec.o: ${BUILD_DIR}/version.h + +strnlen.o: ${BASHINCDIR}/stdc.h + +strpbrk.o: ${BASHINCDIR}/stdc.h + +strtod.o: ${topdir}/bashansi.h +strtod.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +strtoimax.o: ${BASHINCDIR}/stdc.h + +strtol.o: ${topdir}/bashansi.h +strtol.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtol.o: ${BASHINCDIR}/typemax.h + +strtoll.o: ${topdir}/bashansi.h +strtoll.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoll.o: ${BASHINCDIR}/typemax.h + +strtoul.o: ${topdir}/bashansi.h +strtoul.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoul.o: ${BASHINCDIR}/typemax.h + +strtoull.o: ${topdir}/bashansi.h +strtoull.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoull.o: ${BASHINCDIR}/typemax.h + +strtoumax.o: ${BASHINCDIR}/stdc.h + +strtrans.o: ${topdir}/bashansi.h +strtrans.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtrans.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +strtrans.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +strtrans.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +strtrans.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +strtrans.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +strtrans.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +strtrans.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h +strtrans.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h +#strtrans.o: ${BUILD_DIR}/version.h + +times.o: ${BASHINCDIR}/systimes.h +times.o: ${BASHINCDIR}/posixtime.h + +timeval.o: ${BASHINCDIR}/posixtime.h +gettimeofday.o: ${BASHINCDIR}/posixtime.h + +tmpfile.o: ${topdir}/bashtypes.h +tmpfile.o: ${BASHINCDIR}/chartypes.h +tmpfile.o: ${BASHINCDIR}/posixstat.h +tmpfile.o: ${BASHINCDIR}/filecntl.h +tmpfile.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +tmpfile.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +tmpfile.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +tmpfile.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +tmpfile.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +tmpfile.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +tmpfile.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h + +uconvert.o: ${topdir}/bashtypes.h +uconvert.o: ${BASHINCDIR}/chartypes.h +uconvert.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +uconvert.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +uconvert.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +uconvert.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +uconvert.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +uconvert.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +uconvert.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h + +ufuncs.o: ${topdir}/bashtypes.h + +clock.o: ${BASHINCDIR}/posixtime.h + +mailstat.o: ${topdir}/bashansi.h +mailstat.o: ${topdir}/bashtypes.h +mailstat.o: ${BASHINCDIR}/ansi_stdlib.h +mailstat.o: ${BASHINCDIR}/posixstat.h +mailstat.o: ${BASHINCDIR}/posixdir.h +mailstat.o: ${BASHINCDIR}/maxpath.h + +fmtulong.o: ${topdir}/bashansi.h +fmtulong.o: ${BASHINCDIR}/ansi_stdlib.h +fmtulong.o: ${BASHINCDIR}/chartypes.h +fmtulong.o: ${BASHINCDIR}/stdc.h +fmtulong.o: ${BASHINCDIR}/typemax.h +fmtulong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +fmtullong.o: ${topdir}/bashansi.h +fmtullong.o: ${BASHINCDIR}/ansi_stdlib.h +fmtullong.o: ${BASHINCDIR}/chartypes.h +fmtullong.o: ${BASHINCDIR}/stdc.h +fmtullong.o: ${BASHINCDIR}/typemax.h +fmtullong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +fmtumax.o: ${topdir}/bashansi.h +fmtumax.o: ${BASHINCDIR}/ansi_stdlib.h +fmtumax.o: ${BASHINCDIR}/chartypes.h +fmtumax.o: ${BASHINCDIR}/stdc.h +fmtumax.o: ${BASHINCDIR}/typemax.h +fmtumax.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +wcsdup.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcsdup.o: ${BASHINCDIR}/stdc.h +wcsdup.o: ${topdir}/xmalloc.h + +wcsnwidth.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcsnwidth.o: ${BASHINCDIR}/stdc.h + +wcswidth.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcswidth.o: ${BASHINCDIR}/stdc.h + +mbschr.o: ${topdir}/bashansi.h +mbschr.o: ${BASHINCDIR}/ansi_stdlib.h +mbschr.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h + +zgetline.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +zgetline.o: ${BASHINCDIR}/stdc.h +zgetline.o: ${topdir}/xmalloc.h +zgetline.o: ${topdir}/bashtypes.h + +mbscasecmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mbscasecmp.o: ${BASHINCDIR}/stdc.h +mbscasecmp.o: ${topdir}/xmalloc.h + +mbscmp.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mbscmp.o: ${BASHINCDIR}/stdc.h +mbscmp.o: ${topdir}/xmalloc.h + +casemod.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +casemod.o: ${BASHINCDIR}/stdc.h +casemod.o: ${topdir}/xmalloc.h +casemod.o: ${topdir}/bashtypes.h +casemod.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h +casemod.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +dprintf.o: ${BASHINCDIR}/stdc.h + +input_avail.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +input_avail.o: ${BASHINCDIR}/stdc.h +input_avail.o: ${topdir}/xmalloc.h ${BASHINCDIR}/posixselect.h + +mktime.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mktime.o: ${BASHINCDIR}/stdc.h + +fnxform.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +fnxform.o: ${BASHINCDIR}/stdc.h +fnxform.o: ${topdir}/bashtypes.h +fnxform.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h + +shmbchar.o: ${BASHINCDIR}/shmbchar.h +shmbchar.o: ${BASHINCDIR}/shmbutil.h + +unicode.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +unicode.o: ${BASHINCDIR}/stdc.h +unicode.o: ${topdir}/xmalloc.h + +utf8.o: ${topdir}/bashansi.h +utf8.o: ${BASHINCDIR}/ansi_stdlib.h +utf8.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/shmbchar.h + +winsize.o: ${BASHINCDIR}/stdc.h +winsize.o: ${topdir}/xmalloc.h +winsize.o: ${topdir}/bashtypes.h + +zmapfd.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +zmapfd.o: ${BASHINCDIR}/stdc.h +zmapfd.o: ${topdir}/command.h +zmapfd.o: ${topdir}/general.h +zmapfd.o: ${topdir}/bashtypes.h ${BASHINCDIR}/chartypes.h ${topdir}/xmalloc.h diff --git a/utshell-0.5.0/lib/sh/casemod.c b/utshell-0.5.0/lib/sh/casemod.c new file mode 100644 index 00000000..703bad74 --- /dev/null +++ b/utshell-0.5.0/lib/sh/casemod.c @@ -0,0 +1,273 @@ +/* casemod.c -- functions to change case of strings */ + +/* Copyright (C) 2008-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "strmatch.h" + +#define _to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc)) +#define _to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc)) + +#if !defined (HANDLE_MULTIBYTE) +# define cval(s, i) ((s)[(i)]) +# define iswalnum(c) (isalnum(c)) +# define TOGGLE(x) (ISUPPER (x) ? tolower ((unsigned char)x) : (TOUPPER (x))) +#else +# define TOGGLE(x) (iswupper (x) ? towlower (x) : (_to_wupper(x))) +#endif + +/* These must agree with the defines in externs.h */ +#define CASE_NOOP 0x0000 +#define CASE_LOWER 0x0001 +#define CASE_UPPER 0x0002 +#define CASE_CAPITALIZE 0x0004 +#define CASE_UNCAP 0x0008 +#define CASE_TOGGLE 0x0010 +#define CASE_TOGGLEALL 0x0020 +#define CASE_UPFIRST 0x0040 +#define CASE_LOWFIRST 0x0080 + +#define CASE_USEWORDS 0x1000 /* modify behavior to act on words in passed string */ + +extern char *substring PARAMS((char *, int, int)); + +#ifndef UCHAR_MAX +# define UCHAR_MAX TYPE_MAXIMUM(unsigned char) +#endif + +#if defined (HANDLE_MULTIBYTE) +static wchar_t +cval (s, i) + char *s; + int i; +{ + size_t tmp; + wchar_t wc; + int l; + mbstate_t mps; + + if (MB_CUR_MAX == 1 || is_basic (s[i])) + return ((wchar_t)s[i]); + l = strlen (s); + if (i >= (l - 1)) + return ((wchar_t)s[i]); + memset (&mps, 0, sizeof (mbstate_t)); + tmp = mbrtowc (&wc, s + i, l - i, &mps); + if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) + return ((wchar_t)s[i]); + return wc; +} +#endif + +/* Modify the case of characters in STRING matching PAT based on the value of + FLAGS. If PAT is null, modify the case of each character */ +char * +sh_modcase (string, pat, flags) + const char *string; + char *pat; + int flags; +{ + int start, next, end, retind; + int inword, c, nc, nop, match, usewords; + char *ret, *s; + wchar_t wc; + int mb_cur_max; +#if defined (HANDLE_MULTIBYTE) + wchar_t nwc; + char mb[MB_LEN_MAX+1]; + int mlen; + size_t m; + mbstate_t state; +#endif + + if (string == 0 || *string == 0) + { + ret = (char *)xmalloc (1); + ret[0] = '\0'; + return ret; + } + +#if defined (HANDLE_MULTIBYTE) + memset (&state, 0, sizeof (mbstate_t)); +#endif + + start = 0; + end = strlen (string); + mb_cur_max = MB_CUR_MAX; + + ret = (char *)xmalloc (2*end + 1); + retind = 0; + + /* See if we are supposed to split on alphanumerics and operate on each word */ + usewords = (flags & CASE_USEWORDS); + flags &= ~CASE_USEWORDS; + + inword = 0; + while (start < end) + { + wc = cval ((char *)string, start); + + if (iswalnum (wc) == 0) + inword = 0; + + if (pat) + { + next = start; + ADVANCE_CHAR (string, end, next); + s = substring ((char *)string, start, next); + match = strmatch (pat, s, FNM_EXTMATCH) != FNM_NOMATCH; + free (s); + if (match == 0) + { + /* copy unmatched portion */ + memcpy (ret + retind, string + start, next - start); + retind += next - start; + start = next; + inword = 1; + continue; + } + } + + /* XXX - for now, the toggling operators work on the individual + words in the string, breaking on alphanumerics. Should I + leave the capitalization operators to do that also? */ + if (flags == CASE_CAPITALIZE) + { + if (usewords) + nop = inword ? CASE_LOWER : CASE_UPPER; + else + nop = (start > 0) ? CASE_LOWER : CASE_UPPER; + inword = 1; + } + else if (flags == CASE_UNCAP) + { + if (usewords) + nop = inword ? CASE_UPPER : CASE_LOWER; + else + nop = (start > 0) ? CASE_UPPER : CASE_LOWER; + inword = 1; + } + else if (flags == CASE_UPFIRST) + { + if (usewords) + nop = inword ? CASE_NOOP : CASE_UPPER; + else + nop = (start > 0) ? CASE_NOOP : CASE_UPPER; + inword = 1; + } + else if (flags == CASE_LOWFIRST) + { + if (usewords) + nop = inword ? CASE_NOOP : CASE_LOWER; + else + nop = (start > 0) ? CASE_NOOP : CASE_LOWER; + inword = 1; + } + else if (flags == CASE_TOGGLE) + { + nop = inword ? CASE_NOOP : CASE_TOGGLE; + inword = 1; + } + else + nop = flags; + + /* Can't short-circuit, some locales have multibyte upper and lower + case equivalents of single-byte ascii characters (e.g., Turkish) */ + if (mb_cur_max == 1) + { +singlebyte: + switch (nop) + { + default: + case CASE_NOOP: nc = wc; break; + case CASE_UPPER: nc = TOUPPER (wc); break; + case CASE_LOWER: nc = TOLOWER (wc); break; + case CASE_TOGGLEALL: + case CASE_TOGGLE: nc = TOGGLE (wc); break; + } + ret[retind++] = nc; + } +#if defined (HANDLE_MULTIBYTE) + else + { + m = mbrtowc (&wc, string + start, end - start, &state); + /* Have to go through wide case conversion even for single-byte + chars, to accommodate single-byte characters where the + corresponding upper or lower case equivalent is multibyte. */ + if (MB_INVALIDCH (m)) + { + wc = (unsigned char)string[start]; + goto singlebyte; + } + else if (MB_NULLWCH (m)) + wc = L'\0'; + switch (nop) + { + default: + case CASE_NOOP: nwc = wc; break; + case CASE_UPPER: nwc = _to_wupper (wc); break; + case CASE_LOWER: nwc = _to_wlower (wc); break; + case CASE_TOGGLEALL: + case CASE_TOGGLE: nwc = TOGGLE (wc); break; + } + + /* We don't have to convert `wide' characters that are in the + unsigned char range back to single-byte `multibyte' characters. */ + if ((int)nwc <= UCHAR_MAX && is_basic ((int)nwc)) + ret[retind++] = nwc; + else + { + mlen = wcrtomb (mb, nwc, &state); + if (mlen > 0) + mb[mlen] = '\0'; + /* Don't assume the same width */ + strncpy (ret + retind, mb, mlen); + retind += mlen; + } + } +#endif + + ADVANCE_CHAR (string, end, start); + } + + ret[retind] = '\0'; + return ret; +} diff --git a/utshell-0.5.0/lib/sh/clktck.c b/utshell-0.5.0/lib/sh/clktck.c new file mode 100644 index 00000000..8b9b5b32 --- /dev/null +++ b/utshell-0.5.0/lib/sh/clktck.c @@ -0,0 +1,61 @@ +/* clktck.c - get the value of CLK_TCK. */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#if defined (HAVE_SYS_PARAM_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK) +# if !defined (CLK_TCK) +# if defined (HZ) +# define CLK_TCK HZ +# else +# define CLK_TCK 60 +# endif +# endif /* !CLK_TCK */ +#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */ + +long +get_clk_tck () +{ + static long retval = 0; + + if (retval != 0) + return (retval); + +#if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK) + retval = sysconf (_SC_CLK_TCK); +#else /* !SYSCONF || !_SC_CLK_TCK */ + retval = CLK_TCK; +#endif /* !SYSCONF || !_SC_CLK_TCK */ + + return (retval); +} diff --git a/utshell-0.5.0/lib/sh/clock.c b/utshell-0.5.0/lib/sh/clock.c new file mode 100644 index 00000000..c6c52bf8 --- /dev/null +++ b/utshell-0.5.0/lib/sh/clock.c @@ -0,0 +1,87 @@ +/* clock.c - operations on struct tms and clock_t's */ + +/* Copyright (C) 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_TIMES) + +#include +#include + +#if defined (HAVE_SYS_TIMES_H) +# include +#endif + +#include +#include + +#include + +#ifndef locale_decpoint +extern int locale_decpoint PARAMS((void)); +#endif + +extern long get_clk_tck PARAMS((void)); + +void +clock_t_to_secs (t, sp, sfp) + clock_t t; + time_t *sp; + int *sfp; +{ + static long clk_tck = -1; + + if (clk_tck == -1) + clk_tck = get_clk_tck (); + + *sfp = t % clk_tck; + *sfp = (*sfp * 1000) / clk_tck; + + *sp = t / clk_tck; + + /* Sanity check */ + if (*sfp >= 1000) + { + *sp += 1; + *sfp -= 1000; + } +} + +/* Print the time defined by a clock_t (returned by the `times' and `time' + system calls) in a standard way to stdio stream FP. This is scaled in + terms of the value of CLK_TCK, which is what is returned by the + `times' call. */ +void +print_clock_t (fp, t) + FILE *fp; + clock_t t; +{ + time_t timestamp; + long minutes; + int seconds, seconds_fraction; + + clock_t_to_secs (t, ×tamp, &seconds_fraction); + + minutes = timestamp / 60; + seconds = timestamp % 60; + + fprintf (fp, "%ldm%d%c%03ds", minutes, seconds, locale_decpoint(), seconds_fraction); +} +#endif /* HAVE_TIMES */ diff --git a/utshell-0.5.0/lib/sh/dprintf.c b/utshell-0.5.0/lib/sh/dprintf.c new file mode 100644 index 00000000..b3b5d644 --- /dev/null +++ b/utshell-0.5.0/lib/sh/dprintf.c @@ -0,0 +1,70 @@ +/* dprintf -- printf to a file descriptor */ + +/* Copyright (C) 2008-2010 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include + +int +#if defined (PREFER_STDARG) +dprintf(int fd, const char *format, ...) +#else +dprintf(fd, format, va_alist) + int fd; + const char *format; + va_dcl +#endif +{ + FILE *fp; + int fd2, rc, r2; + va_list args; + + if ((fd2 = dup(fd)) < 0) + return -1; + fp = fdopen (fd2, "w"); + if (fp == 0) + { + close (fd2); + return -1; + } + + SH_VA_START (args, format); + rc = vfprintf (fp, format, args); + fflush (fp); + va_end (args); + + r2 = fclose (fp); /* check here */ + + return rc; +} diff --git a/utshell-0.5.0/lib/sh/eaccess.c b/utshell-0.5.0/lib/sh/eaccess.c new file mode 100644 index 00000000..c3043ec1 --- /dev/null +++ b/utshell-0.5.0/lib/sh/eaccess.c @@ -0,0 +1,244 @@ +/* eaccess.c - eaccess replacement for the shell, plus other access functions. */ + +/* Copyright (C) 2006-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "bashansi.h" + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H) +# include +#endif /* !_POSIX_VERSION */ +#include "posixstat.h" +#include "filecntl.h" + +#include "shell.h" + +#if !defined (R_OK) +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#define F_OK 0 +#endif /* R_OK */ + +static int path_is_devfd PARAMS((const char *)); +static int sh_stataccess PARAMS((const char *, int)); +#if HAVE_DECL_SETREGID +static int sh_euidaccess PARAMS((const char *, int)); +#endif + +static int +path_is_devfd (path) + const char *path; +{ + if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) + return 1; + else if (STREQN (path, "/dev/std", 8)) + { + if (STREQ (path+8, "in") || STREQ (path+8, "out") || STREQ (path+8, "err")) + return 1; + else + return 0; + } + else + return 0; +} + +/* A wrapper for stat () which disallows pathnames that are empty strings + and handles /dev/fd emulation on systems that don't have it. */ +int +sh_stat (path, finfo) + const char *path; + struct stat *finfo; +{ + static char *pbuf = 0; + + if (*path == '\0') + { + errno = ENOENT; + return (-1); + } + if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) + { + /* If stating /dev/fd/n doesn't produce the same results as fstat of + FD N, then define DEV_FD_STAT_BROKEN */ +#if !defined (HAVE_DEV_FD) || defined (DEV_FD_STAT_BROKEN) + intmax_t fd; + int r; + + if (legal_number (path + 8, &fd) && fd == (int)fd) + { + r = fstat ((int)fd, finfo); + if (r == 0 || errno != EBADF) + return (r); + } + errno = ENOENT; + return (-1); +#else + /* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a + trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx. + On most systems, with the notable exception of linux, this is + effectively a no-op. */ + pbuf = xrealloc (pbuf, sizeof (DEV_FD_PREFIX) + strlen (path + 8)); + strcpy (pbuf, DEV_FD_PREFIX); + strcat (pbuf, path + 8); + return (stat (pbuf, finfo)); +#endif /* !HAVE_DEV_FD */ + } +#if !defined (HAVE_DEV_STDIN) + else if (STREQN (path, "/dev/std", 8)) + { + if (STREQ (path+8, "in")) + return (fstat (0, finfo)); + else if (STREQ (path+8, "out")) + return (fstat (1, finfo)); + else if (STREQ (path+8, "err")) + return (fstat (2, finfo)); + else + return (stat (path, finfo)); + } +#endif /* !HAVE_DEV_STDIN */ + return (stat (path, finfo)); +} + +/* Do the same thing access(2) does, but use the effective uid and gid, + and don't make the mistake of telling root that any file is + executable. This version uses stat(2). */ +static int +sh_stataccess (path, mode) + const char *path; + int mode; +{ + struct stat st; + + if (sh_stat (path, &st) < 0) + return (-1); + + if (current_user.euid == 0) + { + /* Root can read or write any file. */ + if ((mode & X_OK) == 0) + return (0); + + /* Root can execute any file that has any one of the execute + bits set. */ + if (st.st_mode & S_IXUGO) + return (0); + } + + if (st.st_uid == current_user.euid) /* owner */ + mode <<= 6; + else if (group_member (st.st_gid)) + mode <<= 3; + + if (st.st_mode & mode) + return (0); + + errno = EACCES; + return (-1); +} + +#if HAVE_DECL_SETREGID +/* Version to call when uid != euid or gid != egid. We temporarily swap + the effective and real uid and gid as appropriate. */ +static int +sh_euidaccess (path, mode) + const char *path; + int mode; +{ + int r, e; + + if (current_user.uid != current_user.euid) + setreuid (current_user.euid, current_user.uid); + if (current_user.gid != current_user.egid) + setregid (current_user.egid, current_user.gid); + + r = access (path, mode); + e = errno; + + if (current_user.uid != current_user.euid) + setreuid (current_user.uid, current_user.euid); + if (current_user.gid != current_user.egid) + setregid (current_user.gid, current_user.egid); + + errno = e; + return r; +} +#endif + +int +sh_eaccess (path, mode) + const char *path; + int mode; +{ + int ret; + + if (path_is_devfd (path)) + return (sh_stataccess (path, mode)); + +#if (defined (HAVE_FACCESSAT) && defined (AT_EACCESS)) || defined (HAVE_EACCESS) +# if defined (HAVE_FACCESSAT) && defined (AT_EACCESS) + ret = faccessat (AT_FDCWD, path, mode, AT_EACCESS); +# else /* HAVE_EACCESS */ /* FreeBSD */ + ret = eaccess (path, mode); /* XXX -- not always correct for X_OK */ +# endif /* HAVE_EACCESS */ +# if defined (__FreeBSD__) || defined (SOLARIS) || defined (_AIX) + if (ret == 0 && current_user.euid == 0 && mode == X_OK) + return (sh_stataccess (path, mode)); +# endif /* __FreeBSD__ || SOLARIS || _AIX */ + return ret; +#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */ + return access (path, mode|EFF_ONLY_OK); +#else + if (mode == F_OK) + return (sh_stataccess (path, mode)); + +# if HAVE_DECL_SETREGID + if (current_user.uid != current_user.euid || current_user.gid != current_user.egid) + return (sh_euidaccess (path, mode)); +# endif + + if (current_user.uid == current_user.euid && current_user.gid == current_user.egid) + { + ret = access (path, mode); +#if defined (__FreeBSD__) || defined (SOLARIS) + if (ret == 0 && current_user.euid == 0 && mode == X_OK) + return (sh_stataccess (path, mode)); +#endif + return ret; + } + + return (sh_stataccess (path, mode)); +#endif +} diff --git a/utshell-0.5.0/lib/sh/fmtullong.c b/utshell-0.5.0/lib/sh/fmtullong.c new file mode 100644 index 00000000..97a1dc18 --- /dev/null +++ b/utshell-0.5.0/lib/sh/fmtullong.c @@ -0,0 +1,31 @@ +/* fmtullong.c - convert `long long int' to string */ + +/* Copyright (C) 2001-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#ifdef HAVE_LONG_LONG + +#define LONG long long +#define UNSIGNED_LONG unsigned long long +#define fmtulong fmtullong + +#include "fmtulong.c" + +#endif diff --git a/utshell-0.5.0/lib/sh/fmtulong.c b/utshell-0.5.0/lib/sh/fmtulong.c new file mode 100644 index 00000000..0ccc22b4 --- /dev/null +++ b/utshell-0.5.0/lib/sh/fmtulong.c @@ -0,0 +1,191 @@ +/* fmtulong.c -- Convert unsigned long int to string. */ + +/* Copyright (C) 1998-2011 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include +#ifdef HAVE_STDDEF_H +# include +#endif + +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#include +#include + +#include + +#include "stdc.h" + +#include + +#ifndef errno +extern int errno; +#endif + +#define x_digs "0123456789abcdef" +#define X_digs "0123456789ABCDEF" + +/* XXX -- assumes uppercase letters, lowercase letters, and digits are + contiguous */ +#define FMTCHAR(x) \ + ((x) < 10) ? (x) + '0' \ + : (((x) < 36) ? (x) - 10 + 'a' \ + : (((x) < 62) ? (x) - 36 + 'A' \ + : (((x) == 62) ? '@' : '_'))) + +#ifndef FL_PREFIX +# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ +# define FL_ADDBASE 0x02 /* add base# prefix to converted value */ +# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ +# define FL_UNSIGNED 0x08 /* don't add any sign */ +#endif + +#ifndef LONG +# define LONG long +# define UNSIGNED_LONG unsigned long +#endif + +/* `unsigned long' (or unsigned long long) to string conversion for a given + base. The caller passes the output buffer and the size. This should + check for buffer underflow, but currently does not. */ +char * +fmtulong (ui, base, buf, len, flags) + UNSIGNED_LONG ui; + int base; + char *buf; + size_t len; + int flags; +{ + char *p; + int sign; + LONG si; + + if (base == 0) + base = 10; + + if (base < 2 || base > 64) + { +#if 1 + /* XXX - truncation possible with long translation */ + strncpy (buf, _("invalid base"), len - 1); + buf[len-1] = '\0'; + errno = EINVAL; + return (p = buf); +#else + base = 10; +#endif + } + + sign = 0; + if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0) + { + ui = -ui; + sign = '-'; + } + + p = buf + len - 2; + p[1] = '\0'; + + /* handle common cases explicitly */ + switch (base) + { + case 10: + if (ui < 10) + { + *p-- = TOCHAR (ui); + break; + } + /* Favor signed arithmetic over unsigned arithmetic; it is faster on + many machines. */ + if ((LONG)ui < 0) + { + *p-- = TOCHAR (ui % 10); + si = ui / 10; + } + else + si = ui; + do + *p-- = TOCHAR (si % 10); + while (si /= 10); + break; + + case 8: + do + *p-- = TOCHAR (ui & 7); + while (ui >>= 3); + break; + + case 16: + do + *p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15]; + while (ui >>= 4); + break; + + case 2: + do + *p-- = TOCHAR (ui & 1); + while (ui >>= 1); + break; + + default: + do + *p-- = FMTCHAR (ui % base); + while (ui /= base); + break; + } + + if ((flags & FL_PREFIX) && (base == 8 || base == 16)) + { + if (base == 16) + { + *p-- = (flags & FL_HEXUPPER) ? 'X' : 'x'; + *p-- = '0'; + } + else if (p[1] != '0') + *p-- = '0'; + } + else if ((flags & FL_ADDBASE) && base != 10) + { + *p-- = '#'; + *p-- = TOCHAR (base % 10); + if (base > 10) + *p-- = TOCHAR (base / 10); + } + + if (sign) + *p-- = '-'; + + return (p + 1); +} diff --git a/utshell-0.5.0/lib/sh/fmtumax.c b/utshell-0.5.0/lib/sh/fmtumax.c new file mode 100644 index 00000000..f2786b5d --- /dev/null +++ b/utshell-0.5.0/lib/sh/fmtumax.c @@ -0,0 +1,27 @@ +/* fmtumax.c -- Convert uintmax_t to string. */ + +/* Copyright (C) 2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#define LONG intmax_t +#define UNSIGNED_LONG uintmax_t +#define fmtulong fmtumax + +#include "fmtulong.c" diff --git a/utshell-0.5.0/lib/sh/fnxform.c b/utshell-0.5.0/lib/sh/fnxform.c new file mode 100644 index 00000000..35d7e737 --- /dev/null +++ b/utshell-0.5.0/lib/sh/fnxform.c @@ -0,0 +1,199 @@ +/* fnxform - use iconv(3) to transform strings to and from "filename" format */ + +/* Copyright (C) 2009-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include +#if defined (HAVE_UNISTD_H) +# include +#endif +#include "bashansi.h" +#include +#include "bashtypes.h" + +#include "stdc.h" +#include "bashintl.h" +#include + +#if defined (HAVE_ICONV) +# include +#endif + +#if defined (HAVE_LOCALE_CHARSET) +extern const char *locale_charset PARAMS((void)); +#else +extern char *get_locale_var PARAMS((char *)); +#endif + +#if defined (HAVE_ICONV) +static iconv_t conv_fromfs = (iconv_t)-1; +static iconv_t conv_tofs = (iconv_t)-1; + +#define OUTLEN_MAX 4096 + +static char *outbuf = 0; +static size_t outlen = 0; + +static char *curencoding PARAMS((void)); +static void init_tofs PARAMS((void)); +static void init_fromfs PARAMS((void)); + +static char * +curencoding () +{ + char *loc; +#if defined (HAVE_LOCALE_CHARSET) + loc = (char *)locale_charset (); + return loc; +#else + char *dot, *mod; + + loc = get_locale_var ("LC_CTYPE"); + if (loc == 0 || *loc == 0) + return ""; + dot = strchr (loc, '.'); + if (dot == 0) + return loc; + mod = strchr (dot, '@'); + if (mod) + *mod = '\0'; + return ++dot; +#endif +} + +static void +init_tofs () +{ + char *cur; + + cur = curencoding (); + conv_tofs = iconv_open ("UTF-8-MAC", cur); +} + +static void +init_fromfs () +{ + char *cur; + + cur = curencoding (); + conv_fromfs = iconv_open (cur, "UTF-8-MAC"); +} + +char * +fnx_tofs (string, len) + char *string; + size_t len; +{ +#ifdef MACOSX + ICONV_CONST char *inbuf; + char *tempbuf; + size_t templen; + + if (conv_tofs == (iconv_t)-1) + init_tofs (); + if (conv_tofs == (iconv_t)-1) + return string; + + /* Free and reallocate outbuf if it's *too* big */ + if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8) + { + free (outbuf); + outbuf = 0; + outlen = 0; + } + + inbuf = string; + if (outbuf == 0 || outlen < len + 8) + { + outlen = len + 8; + outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1); + } + tempbuf = outbuf; + templen = outlen; + + iconv (conv_tofs, NULL, NULL, NULL, NULL); + + if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1) + return string; + + *tempbuf = '\0'; + return outbuf; +#else + return string; +#endif +} + +char * +fnx_fromfs (string, len) + char *string; + size_t len; +{ +#ifdef MACOSX + ICONV_CONST char *inbuf; + char *tempbuf; + size_t templen; + + if (conv_fromfs == (iconv_t)-1) + init_fromfs (); + if (conv_fromfs == (iconv_t)-1) + return string; + + /* Free and reallocate outbuf if it's *too* big */ + if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8) + { + free (outbuf); + outbuf = 0; + outlen = 0; + } + + inbuf = string; + if (outbuf == 0 || outlen < (len + 8)) + { + outlen = len + 8; + outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1); + } + tempbuf = outbuf; + templen = outlen; + + iconv (conv_fromfs, NULL, NULL, NULL, NULL); + + if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1) + return string; + + *tempbuf = '\0'; + return outbuf; +#else + return string; +#endif +} + +#else +char * +fnx_tofs (string) + char *string; +{ + return string; +} + +char * +fnx_fromfs (string) + char *string; +{ + return string; +} +#endif diff --git a/utshell-0.5.0/lib/sh/fpurge.c b/utshell-0.5.0/lib/sh/fpurge.c new file mode 100644 index 00000000..8cd4e368 --- /dev/null +++ b/utshell-0.5.0/lib/sh/fpurge.c @@ -0,0 +1,232 @@ +/* fpurge - Flushing buffers of a FILE stream. */ + +/* Copyright (C) 2007-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include "stdc.h" + +#include + +/* Specification. Same as in ../../externs.h. */ +#define NEED_FPURGE_DECL +#if HAVE_FPURGE +# define fpurge _bash_fpurge +#endif +extern int fpurge PARAMS((FILE *stream)); + +#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */ +# include +#endif +#include + +/* Inline contents of gnulib:stdio-impl.h */ + +/* Many stdio implementations have the same logic and therefore can share + the same implementation of stdio extension API, except that some fields + have different naming conventions, or their access requires some casts. */ + +/* BSD stdio derived implementations. */ + +#if defined __NetBSD__ /* NetBSD */ +/* Get __NetBSD_Version__. */ +# include +#endif + +#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ + +# if defined __DragonFly__ /* DragonFly */ + /* See . */ +# define fp_ ((struct { struct __FILE_public pub; \ + struct { unsigned char *_base; int _size; } _bf; \ + void *cookie; \ + void *_close; \ + void *_read; \ + void *_seek; \ + void *_write; \ + struct { unsigned char *_base; int _size; } _ub; \ + int _ur; \ + unsigned char _ubuf[3]; \ + unsigned char _nbuf[1]; \ + struct { unsigned char *_base; int _size; } _lb; \ + int _blksize; \ + fpos_t _offset; \ + /* More fields, not relevant here. */ \ + } *) fp) + /* See . */ +# define _p pub._p +# define _flags pub._flags +# define _r pub._r +# define _w pub._w +# else +# define fp_ fp +# endif + +# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ /* NetBSD >= 1.5ZA, OpenBSD */ + /* See + and */ + struct __sfileext + { + struct __sbuf _ub; /* ungetc buffer */ + /* More fields, not relevant here. */ + }; +# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub +# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, MacOS X, Cygwin */ +# define fp_ub fp_->_ub +# endif + +# define HASUB(fp) (fp_ub._base != NULL) + +#endif + +/* SystemV derived implementations. */ + +#if defined _IOERR + +# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ +# define fp_ ((struct { unsigned char *_ptr; \ + unsigned char *_base; \ + unsigned char *_end; \ + long _cnt; \ + int _file; \ + unsigned int _flag; \ + } *) fp) +# else +# define fp_ fp +# endif + +# if defined _SCO_DS /* OpenServer */ +# define _cnt __cnt +# define _ptr __ptr +# define _base __base +# define _flag __flag +# endif + +#endif + +int +fpurge (FILE *fp) +{ +#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */ + + __fpurge (fp); + /* The __fpurge function does not have a return value. */ + return 0; + +#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin 1.7 */ + + /* Call the system's fpurge function. */ +# undef fpurge +# if !HAVE_DECL_FPURGE + extern int fpurge (FILE *); +# endif + int result = fpurge (fp); +# if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ + if (result == 0) + /* Correct the invariants that fpurge broke. + on BSD systems says: + "The following always hold: if _flags & __SRD, _w is 0." + If this invariant is not fulfilled and the stream is read-write but + currently reading, subsequent putc or fputc calls will write directly + into the buffer, although they shouldn't be allowed to. */ + if ((fp_->_flags & __SRD) != 0) + fp_->_w = 0; +# endif + return result; + +#else + + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_IO_read_end = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_write_base; + /* Avoid memory leak when there is an active ungetc buffer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_IO_save_base = NULL; + } + return 0; +# elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ + fp_->_p = fp_->_bf._base; + fp_->_r = 0; + fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ + ? fp_->_bf._size + : 0); + /* Avoid memory leak when there is an active ungetc buffer. */ + if (fp_ub._base != NULL) + { + if (fp_ub._base != fp_->_ubuf) + free (fp_ub._base); + fp_ub._base = NULL; + } + return 0; +# elif defined __EMX__ /* emx+gcc */ + fp->_ptr = fp->_buffer; + fp->_rcount = 0; + fp->_wcount = 0; + fp->_ungetc_count = 0; + return 0; +# elif defined _IOERR || defined __TANDEM /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */ + fp->_ptr = fp->_base; + if (fp->_ptr != NULL) + fp->_cnt = 0; + return 0; +# elif defined __UCLIBC__ /* uClibc */ +# ifdef __STDIO_BUFFERS + if (fp->__modeflags & __FLAG_WRITING) + fp->__bufpos = fp->__bufstart; + else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) + fp->__bufpos = fp->__bufread; +# endif + return 0; +# elif defined __QNX__ /* QNX */ + fp->_Rback = fp->_Back + sizeof (fp->_Back); + fp->_Rsave = NULL; + if (fp->_Mode & 0x2000 /* _MWRITE */) + /* fp->_Buf <= fp->_Next <= fp->_Wend */ + fp->_Next = fp->_Buf; + else + /* fp->_Buf <= fp->_Next <= fp->_Rend */ + fp->_Rend = fp->_Next; + return 0; +# elif defined __MINT__ /* Atari FreeMiNT */ + if (fp->__pushed_back) + { + fp->__bufp = fp->__pushback_bufp; + fp->__pushed_back = 0; + } + /* Preserve the current file position. */ + if (fp->__target != -1) + fp->__target += fp->__bufp - fp->__buffer; + fp->__bufp = fp->__buffer; + /* Nothing in the buffer, next getc is nontrivial. */ + fp->__get_limit = fp->__bufp; + /* Nothing in the buffer, next putc is nontrivial. */ + fp->__put_limit = fp->__buffer; + return 0; +# else +# warning "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib." + return 0; +# endif + +#endif +} diff --git a/utshell-0.5.0/lib/sh/getcwd.c b/utshell-0.5.0/lib/sh/getcwd.c new file mode 100644 index 00000000..d7bd241b --- /dev/null +++ b/utshell-0.5.0/lib/sh/getcwd.c @@ -0,0 +1,356 @@ +/* getcwd.c -- get pathname of current directory */ + +/* Copyright (C) 1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_GETCWD) + +#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX) + #pragma alloca +#endif /* _AIX && RISC6000 && !__GNUC__ */ + +#if defined (__QNX__) +# undef HAVE_LSTAT +#endif + +#include +#include + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include +#include +#include + +#include + +#if !defined (D_FILENO_AVAILABLE) +# include "command.h" +# include "general.h" +# include "externs.h" +#endif + +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if !defined (HAVE_LSTAT) +# define lstat stat +#endif + +#if !defined (NULL) +# define NULL 0 +#endif + +/* If the d_fileno member of a struct dirent doesn't return anything useful, + we need to check inode number equivalence the hard way. Return 1 if + the inode corresponding to PATH/DIR is identical to THISINO. */ +#if !defined (D_FILENO_AVAILABLE) +static int +_path_checkino (dotp, name, thisino) + char *dotp; + char *name; + ino_t thisino; +{ + char *fullpath; + int r, e; + struct stat st; + + e = errno; + fullpath = sh_makepath (dotp, name, MP_RMDOT); + if (stat (fullpath, &st) < 0) + { + errno = e; + return 0; + } + free (fullpath); + errno = e; + return (st.st_ino == thisino); +} +#endif + +/* Get the pathname of the current working directory, + and put it in SIZE bytes of BUF. Returns NULL if the + directory couldn't be determined or SIZE was too small. + If successful, returns BUF. In GNU, if BUF is NULL, + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE <= 0, in which case it is as + big as necessary. */ +#if defined (__STDC__) +char * +getcwd (char *buf, size_t size) +#else /* !__STDC__ */ +char * +getcwd (buf, size) + char *buf; + size_t size; +#endif /* !__STDC__ */ +{ + static const char dots[] + = "../../../../../../../../../../../../../../../../../../../../../../../\ +../../../../../../../../../../../../../../../../../../../../../../../../../../\ +../../../../../../../../../../../../../../../../../../../../../../../../../.."; + const char *dotp, *dotlist; + size_t dotsize; + dev_t rootdev, thisdev; + ino_t rootino, thisino; + char path[PATH_MAX + 1]; + register char *pathp; + char *pathbuf; + size_t pathsize; + struct stat st; + int saved_errno; + + if (buf != NULL && size == 0) + { + errno = EINVAL; + return ((char *)NULL); + } + + pathsize = sizeof (path); + pathp = &path[pathsize]; + *--pathp = '\0'; + pathbuf = path; + + if (stat (".", &st) < 0) + return ((char *)NULL); + thisdev = st.st_dev; + thisino = st.st_ino; + + if (stat ("/", &st) < 0) + return ((char *)NULL); + rootdev = st.st_dev; + rootino = st.st_ino; + + saved_errno = 0; + + dotsize = sizeof (dots) - 1; + dotp = &dots[sizeof (dots)]; + dotlist = dots; + while (!(thisdev == rootdev && thisino == rootino)) + { + register DIR *dirstream; + register struct dirent *d; + dev_t dotdev; + ino_t dotino; + char mount_point; + int namlen; + + /* Look at the parent directory. */ + if (dotp == dotlist) + { + /* My, what a deep directory tree you have, Grandma. */ + char *new; + if (dotlist == dots) + { + new = (char *)malloc (dotsize * 2 + 1); + if (new == NULL) + goto lose; + memcpy (new, dots, dotsize); + } + else + { + new = (char *)realloc ((PTR_T) dotlist, dotsize * 2 + 1); + if (new == NULL) + goto lose; + } + memcpy (&new[dotsize], new, dotsize); + dotp = &new[dotsize]; + dotsize *= 2; + new[dotsize] = '\0'; + dotlist = new; + } + + dotp -= 3; + + /* Figure out if this directory is a mount point. */ + if (stat (dotp, &st) < 0) + goto lose; + dotdev = st.st_dev; + dotino = st.st_ino; + mount_point = dotdev != thisdev; + + /* Search for the last directory. */ + dirstream = opendir (dotp); + if (dirstream == NULL) + goto lose; + while ((d = readdir (dirstream)) != NULL) + { + if (d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; +#if defined (D_FILENO_AVAILABLE) + if (mount_point || d->d_fileno == thisino) +#else + if (mount_point || _path_checkino (dotp, d->d_name, thisino)) +#endif + { + char *name; + + namlen = D_NAMLEN(d); + name = (char *) + alloca (dotlist + dotsize - dotp + 1 + namlen + 1); + memcpy (name, dotp, dotlist + dotsize - dotp); + name[dotlist + dotsize - dotp] = '/'; + memcpy (&name[dotlist + dotsize - dotp + 1], + d->d_name, namlen + 1); + if (lstat (name, &st) < 0) + { +#if 0 + int save = errno; + (void) closedir (dirstream); + errno = save; + goto lose; +#else + saved_errno = errno; +#endif + } + if (st.st_dev == thisdev && st.st_ino == thisino) + break; + } + } + if (d == NULL) + { +#if 0 + int save = errno; +#else + int save = errno ? errno : saved_errno; +#endif + (void) closedir (dirstream); + errno = save; + goto lose; + } + else + { + size_t space; + + while ((space = pathp - pathbuf) <= namlen) + { + char *new; + + if (pathbuf == path) + { + new = (char *)malloc (pathsize * 2); + if (!new) + goto lose; + } + else + { + new = (char *)realloc ((PTR_T) pathbuf, (pathsize * 2)); + if (!new) + goto lose; + pathp = new + space; + } + (void) memcpy (new + pathsize + space, pathp, pathsize - space); + pathp = new + pathsize + space; + pathbuf = new; + pathsize *= 2; + } + + pathp -= namlen; + (void) memcpy (pathp, d->d_name, namlen); + *--pathp = '/'; + (void) closedir (dirstream); + } + + thisdev = dotdev; + thisino = dotino; + } + + if (pathp == &path[sizeof(path) - 1]) + *--pathp = '/'; + + if (dotlist != dots) + free ((PTR_T) dotlist); + + { + size_t len = pathbuf + pathsize - pathp; + if (buf == NULL && size <= 0) + size = len; + + if ((size_t) size < len) + { + errno = ERANGE; + goto lose2; + } + if (buf == NULL) + { + buf = (char *) malloc (size); + if (buf == NULL) + goto lose2; + } + + (void) memcpy((PTR_T) buf, (PTR_T) pathp, len); + } + + if (pathbuf != path) + free (pathbuf); + + return (buf); + + lose: + if ((dotlist != dots) && dotlist) + { + int e = errno; + free ((PTR_T) dotlist); + errno = e; + } + + lose2: + if ((pathbuf != path) && pathbuf) + { + int e = errno; + free ((PTR_T) pathbuf); + errno = e; + } + return ((char *)NULL); +} + +#if defined (TEST) +# include +main (argc, argv) + int argc; + char **argv; +{ + char b[PATH_MAX]; + + if (getcwd(b, sizeof(b))) + { + printf ("%s\n", b); + exit (0); + } + else + { + perror ("cwd: getcwd"); + exit (1); + } +} +#endif /* TEST */ +#endif /* !HAVE_GETCWD */ diff --git a/utshell-0.5.0/lib/sh/getenv.c b/utshell-0.5.0/lib/sh/getenv.c new file mode 100644 index 00000000..1e682aef --- /dev/null +++ b/utshell-0.5.0/lib/sh/getenv.c @@ -0,0 +1,233 @@ +/* getenv.c - get environment variable value from the shell's variable + list. */ + +/* Copyright (C) 1997-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (CAN_REDEFINE_GETENV) + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include +#include + +#ifndef errno +extern int errno; +#endif + +extern char **environ; + +/* We supply our own version of getenv () because we want library + routines to get the changed values of exported variables. */ + +/* The NeXT C library has getenv () defined and used in the same file. + This screws our scheme. However, Bash will run on the NeXT using + the C library getenv (), since right now the only environment variable + that we care about is HOME, and that is already defined. */ +static char *last_tempenv_value = (char *)NULL; + +char * +getenv (name) + const char *name; +{ + SHELL_VAR *var; + + if (name == 0 || *name == '\0') + return ((char *)NULL); + + var = find_tempenv_variable ((char *)name); + if (var) + { + FREE (last_tempenv_value); + + last_tempenv_value = value_cell (var) ? savestring (value_cell (var)) : (char *)NULL; + return (last_tempenv_value); + } + else if (shell_variables) + { + var = find_variable ((char *)name); + if (var && exported_p (var)) + return (value_cell (var)); + } + else if (environ) + { + register int i, len; + + /* In some cases, s5r3 invokes getenv() before main(); BSD systems + using gprof also exhibit this behavior. This means that + shell_variables will be 0 when this is invoked. We look up the + variable in the real environment in that case. */ + + for (i = 0, len = strlen (name); environ[i]; i++) + { + if ((STREQN (environ[i], name, len)) && (environ[i][len] == '=')) + return (environ[i] + len + 1); + } + } + + return ((char *)NULL); +} + +/* Some versions of Unix use _getenv instead. */ +char * +_getenv (name) + const char *name; +{ + return (getenv (name)); +} + +/* SUSv3 says argument is a `char *'; BSD implementations disagree */ +int +putenv (str) +#ifndef HAVE_STD_PUTENV + const char *str; +#else + char *str; +#endif +{ + SHELL_VAR *var; + char *name, *value; + int offset; + + if (str == 0 || *str == '\0') + { + errno = EINVAL; + return -1; + } + + offset = assignment (str, 0); + if (str[offset] != '=') + { + errno = EINVAL; + return -1; + } + name = savestring (str); + name[offset] = 0; + + value = name + offset + 1; + + /* XXX - should we worry about readonly here? */ + var = bind_variable (name, value, 0); + if (var == 0) + { + errno = EINVAL; + return -1; + } + + VUNSETATTR (var, att_invisible); + VSETATTR (var, att_exported); + + return 0; +} + +#if 0 +int +_putenv (name) +#ifndef HAVE_STD_PUTENV + const char *name; +#else + char *name; +#endif +{ + return putenv (name); +} +#endif + +int +setenv (name, value, rewrite) + const char *name; + const char *value; + int rewrite; +{ + SHELL_VAR *var; + char *v; + + if (name == 0 || *name == '\0' || strchr (name, '=') != 0) + { + errno = EINVAL; + return -1; + } + + var = 0; + v = (char *)value; /* some compilers need explicit cast */ + /* XXX - should we worry about readonly here? */ + if (rewrite == 0) + var = find_variable (name); + + if (var == 0) + var = bind_variable (name, v, 0); + + if (var == 0) + return -1; + + VUNSETATTR (var, att_invisible); + VSETATTR (var, att_exported); + + return 0; +} + +#if 0 +int +_setenv (name, value, rewrite) + const char *name; + const char *value; + int rewrite; +{ + return setenv (name, value, rewrite); +} +#endif + +/* SUSv3 says unsetenv returns int; existing implementations (BSD) disagree. */ + +#ifdef HAVE_STD_UNSETENV +#define UNSETENV_RETURN(N) return(N) +#define UNSETENV_RETTYPE int +#else +#define UNSETENV_RETURN(N) return +#define UNSETENV_RETTYPE void +#endif + +UNSETENV_RETTYPE +unsetenv (name) + const char *name; +{ + if (name == 0 || *name == '\0' || strchr (name, '=') != 0) + { + errno = EINVAL; + UNSETENV_RETURN(-1); + } + + /* XXX - should we just remove the export attribute here? */ +#if 1 + unbind_variable (name); +#else + SHELL_VAR *v; + + v = find_variable (name); + if (v) + VUNSETATTR (v, att_exported); +#endif + + UNSETENV_RETURN(0); +} +#endif /* CAN_REDEFINE_GETENV */ diff --git a/utshell-0.5.0/lib/sh/gettimeofday.c b/utshell-0.5.0/lib/sh/gettimeofday.c new file mode 100644 index 00000000..b654c154 --- /dev/null +++ b/utshell-0.5.0/lib/sh/gettimeofday.c @@ -0,0 +1,35 @@ +/* gettimeofday.c - gettimeofday replacement using time() */ + +/* Copyright (C) 2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#if !defined (HAVE_GETTIMEOFDAY) + +#include "posixtime.h" + +/* A version of gettimeofday that just sets tv_sec from time(3) */ +int +gettimeofday (struct timeval *tv, void *tz) +{ + tv->tv_sec = (time_t) time ((time_t *)0); + tv->tv_usec = 0; + return 0; +} +#endif diff --git a/utshell-0.5.0/lib/sh/inet_aton.c b/utshell-0.5.0/lib/sh/inet_aton.c new file mode 100644 index 00000000..e377178e --- /dev/null +++ b/utshell-0.5.0/lib/sh/inet_aton.c @@ -0,0 +1,214 @@ +/* inet_aton - convert string to numeric IP address */ + +/* Snagged from GNU C library, version 2.0.3. */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static char rcsid[] = "$Id: inet_addr.c,v 1.5 1996/08/14 03:48:37 drepper Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#if !defined (HAVE_INET_ATON) && defined (HAVE_NETWORK) && defined (HAVE_NETINET_IN_H) && defined (HAVE_ARPA_INET_H) + +#include +#if defined (HAVE_SYS_PARAM_H) +#include +#endif +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#ifndef INADDR_NONE +# define INADDR_NONE 0xffffffff +#endif + +/* these are compatibility routines, not needed on recent BSD releases */ + +#if 0 +/* Not used, not needed. */ +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +u_long +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} +#endif + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(cp, addr) + register const char *cp; + struct in_addr *addr; +{ + register u_bits32_t val; + register int base, n; + register unsigned char c; + u_int parts[4]; + register u_int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ +#if 0 + if (!isdigit(c)) +#else + if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && + c != '5' && c != '6' && c != '7' && c != '8' && c != '9') +#endif + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +#endif /* !HAVE_INET_ATON */ diff --git a/utshell-0.5.0/lib/sh/input_avail.c b/utshell-0.5.0/lib/sh/input_avail.c new file mode 100644 index 00000000..695165fd --- /dev/null +++ b/utshell-0.5.0/lib/sh/input_avail.c @@ -0,0 +1,165 @@ +/* input_avail.c -- check whether or not data is available for reading on a + specified file descriptor. */ + +/* Copyright (C) 2008,2009-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if defined (__TANDEM) +# include +#endif + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_PSELECT) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include "bashansi.h" + +#include "posixselect.h" + +#if defined (FIONREAD_IN_SYS_IOCTL) +# include +#endif + +#include +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if !defined (O_NDELAY) && defined (O_NONBLOCK) +# define O_NDELAY O_NONBLOCK /* Posix style */ +#endif + +/* Return >= 1 if select/FIONREAD indicates data available for reading on + file descriptor FD; 0 if no data available. Return -1 on error. */ +int +input_avail (fd) + int fd; +{ + int result, chars_avail; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif + + if (fd < 0) + return -1; + + chars_avail = 0; + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (fd, &readfds); + FD_SET (fd, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = 0; + result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); + return ((result <= 0) ? 0 : 1); +#endif + +#if defined (FIONREAD) + errno = 0; + result = ioctl (fd, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; + return (chars_avail); +#endif + + return 0; +} + +/* Wait until NCHARS are available for reading on file descriptor FD. + This can wait indefinitely. Return -1 on error. */ +int +nchars_avail (fd, nchars) + int fd; + int nchars; +{ + int result, chars_avail; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; +#endif +#if defined (HAVE_PSELECT) + sigset_t set, oset; +#endif + + if (fd < 0 || nchars < 0) + return -1; + if (nchars == 0) + return (input_avail (fd)); + + chars_avail = 0; + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (fd, &readfds); + FD_SET (fd, &exceptfds); +#endif +#if defined (HAVE_SELECT) || defined (HAVE_PSELECT) + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); +# ifdef SIGCHLD + sigaddset (&set, SIGCHLD); +# endif + sigemptyset (&oset); +#endif + + while (1) + { + result = 0; +#if defined (HAVE_PSELECT) + /* XXX - use pselect(2) to block SIGCHLD atomically */ + result = pselect (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timespec *)NULL, &set); +#elif defined (HAVE_SELECT) + sigprocmask (SIG_BLOCK, &set, &oset); + result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timeval *)NULL); + sigprocmask (SIG_BLOCK, &oset, (sigset_t *)NULL); +#endif + if (result < 0) + return -1; + +#if defined (FIONREAD) + errno = 0; + result = ioctl (fd, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; + if (chars_avail >= nchars) + break; +#else + break; +#endif + } + + return 0; +} diff --git a/utshell-0.5.0/lib/sh/itos.c b/utshell-0.5.0/lib/sh/itos.c new file mode 100644 index 00000000..cd36ef33 --- /dev/null +++ b/utshell-0.5.0/lib/sh/itos.c @@ -0,0 +1,84 @@ +/* itos.c -- Convert integer to string. */ + +/* Copyright (C) 1998-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include "shell.h" + +char * +inttostr (i, buf, len) + intmax_t i; + char *buf; + size_t len; +{ + return (fmtumax (i, 10, buf, len, 0)); +} + +/* Integer to string conversion. This conses the string; the + caller should free it. */ +char * +itos (i) + intmax_t i; +{ + char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1]; + + p = fmtumax (i, 10, lbuf, sizeof(lbuf), 0); + return (savestring (p)); +} + +/* Integer to string conversion. This conses the string using strdup; + caller should free it and be prepared to deal with NULL return. */ +char * +mitos (i) + intmax_t i; +{ + char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1]; + + p = fmtumax (i, 10, lbuf, sizeof(lbuf), 0); + return (strdup (p)); +} + +char * +uinttostr (i, buf, len) + uintmax_t i; + char *buf; + size_t len; +{ + return (fmtumax (i, 10, buf, len, FL_UNSIGNED)); +} + +/* Integer to string conversion. This conses the string; the + caller should free it. */ +char * +uitos (i) + uintmax_t i; +{ + char *p, lbuf[INT_STRLEN_BOUND(uintmax_t) + 1]; + + p = fmtumax (i, 10, lbuf, sizeof(lbuf), FL_UNSIGNED); + return (savestring (p)); +} diff --git a/utshell-0.5.0/lib/sh/mailstat.c b/utshell-0.5.0/lib/sh/mailstat.c new file mode 100644 index 00000000..bd5c25fb --- /dev/null +++ b/utshell-0.5.0/lib/sh/mailstat.c @@ -0,0 +1,159 @@ +/* mailstat.c -- stat a mailbox file, handling maildir-type mail directories */ + +/* Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#include + +#include +#include +#include +#include + +#if defined (HAVE_SYS_PARAM_H) +# include +#endif + +#include + +/* + * Stat a file. If it's a maildir, check all messages + * in the maildir and present the grand total as a file. + * The fields in the 'struct stat' are from the mail directory. + * The following fields are emulated: + * + * st_nlink always 1, unless st_blocks is not present, in which case it's + * the total number of messages + * st_size total number of bytes in all files + * st_blocks total number of messages, if present in struct stat + * st_atime access time of newest file in maildir + * st_mtime modify time of newest file in maildir + * st_mode S_IFDIR changed to S_IFREG + * + * This is good enough for most mail-checking applications. + */ + +int +mailstat(path, st) + const char *path; + struct stat *st; +{ + static struct stat st_new_last, st_ret_last; + struct stat st_ret, st_tmp; + DIR *dd; + struct dirent *fn; + char dir[PATH_MAX * 2], file[PATH_MAX * 2 + 1]; + int i, l; + time_t atime, mtime; + + atime = mtime = 0; + + /* First see if it's a directory. */ + if ((i = stat(path, st)) != 0 || S_ISDIR(st->st_mode) == 0) + return i; + + if (strlen(path) > sizeof(dir) - 5) + { +#ifdef ENAMETOOLONG + errno = ENAMETOOLONG; +#else + errno = EINVAL; +#endif + return -1; + } + + st_ret = *st; + st_ret.st_nlink = 1; + st_ret.st_size = 0; +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + st_ret.st_blocks = 0; +#else + st_ret.st_nlink = 0; +#endif + st_ret.st_mode &= ~S_IFDIR; + st_ret.st_mode |= S_IFREG; + + /* See if cur/ is present */ + sprintf(dir, "%s/cur", path); + if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) + return 0; + st_ret.st_atime = st_tmp.st_atime; + + /* See if tmp/ is present */ + sprintf(dir, "%s/tmp", path); + if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) + return 0; + st_ret.st_mtime = st_tmp.st_mtime; + + /* And new/ */ + sprintf(dir, "%s/new", path); + if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) + return 0; + st_ret.st_mtime = st_tmp.st_mtime; + + /* Optimization - if new/ didn't change, nothing else did. */ + if (st_tmp.st_dev == st_new_last.st_dev && + st_tmp.st_ino == st_new_last.st_ino && + st_tmp.st_atime == st_new_last.st_atime && + st_tmp.st_mtime == st_new_last.st_mtime) + { + *st = st_ret_last; + return 0; + } + st_new_last = st_tmp; + + /* Loop over new/ and cur/ */ + for (i = 0; i < 2; i++) + { + sprintf(dir, "%s/%s", path, i ? "cur" : "new"); + sprintf(file, "%s/", dir); + l = strlen(file); + if ((dd = opendir(dir)) == NULL) + return 0; + while ((fn = readdir(dd)) != NULL) + { + if (fn->d_name[0] == '.' || strlen(fn->d_name) + l >= sizeof(file)) + continue; + strcpy(file + l, fn->d_name); + if (stat(file, &st_tmp) != 0) + continue; + st_ret.st_size += st_tmp.st_size; +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + st_ret.st_blocks++; +#else + st_ret.st_nlink++; +#endif + if (st_tmp.st_atime != st_tmp.st_mtime && st_tmp.st_atime > atime) + atime = st_tmp.st_atime; + if (st_tmp.st_mtime > mtime) + mtime = st_tmp.st_mtime; + } + closedir(dd); + } + +/* if (atime) */ /* Set atime even if cur/ is empty */ + st_ret.st_atime = atime; + if (mtime) + st_ret.st_mtime = mtime; + + *st = st_ret_last = st_ret; + return 0; +} diff --git a/utshell-0.5.0/lib/sh/makepath.c b/utshell-0.5.0/lib/sh/makepath.c new file mode 100644 index 00000000..46c5f71f --- /dev/null +++ b/utshell-0.5.0/lib/sh/makepath.c @@ -0,0 +1,128 @@ +/* makepath.c - glue PATH and DIR together into a full pathname. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include "shell.h" + +#include + +#ifndef NULL +# define NULL 0 +#endif + +/* MAKE SURE THESE AGREE WITH ../../externs.h. */ + +#ifndef MP_DOTILDE +# define MP_DOTILDE 0x01 +# define MP_DOCWD 0x02 +# define MP_RMDOT 0x04 +# define MP_IGNDOT 0x08 +#endif + +extern char *get_working_directory PARAMS((char *)); + +static char *nullpath = ""; + +/* Take PATH, an element from, e.g., $CDPATH, and DIR, a directory name, + and paste them together into PATH/DIR. Tilde expansion is performed on + PATH if (flags & MP_DOTILDE) is non-zero. If PATH is NULL or the empty + string, it is converted to the current directory. A full pathname is + used if (flags & MP_DOCWD) is non-zero, otherwise `./' is used. If + (flags & MP_RMDOT) is non-zero, any `./' is removed from the beginning + of DIR. If (flags & MP_IGNDOT) is non-zero, a PATH that is "." or "./" + is ignored. */ + +#define MAKEDOT() \ + do { \ + xpath = (char *)xmalloc (2); \ + xpath[0] = '.'; \ + xpath[1] = '\0'; \ + pathlen = 1; \ + } while (0) + +char * +sh_makepath (path, dir, flags) + const char *path, *dir; + int flags; +{ + int dirlen, pathlen; + char *ret, *xpath, *xdir, *r, *s; + + if (path == 0 || *path == '\0') + { + if (flags & MP_DOCWD) + { + xpath = get_working_directory ("sh_makepath"); + if (xpath == 0) + { + ret = get_string_value ("PWD"); + if (ret) + xpath = savestring (ret); + } + if (xpath == 0) + MAKEDOT(); + else + pathlen = strlen (xpath); + } + else + MAKEDOT(); + } + else if ((flags & MP_IGNDOT) && path[0] == '.' && (path[1] == '\0' || + (path[1] == '/' && path[2] == '\0'))) + { + xpath = nullpath; + pathlen = 0; + } + else + { + xpath = ((flags & MP_DOTILDE) && *path == '~') ? bash_tilde_expand (path, 0) : (char *)path; + pathlen = strlen (xpath); + } + + xdir = (char *)dir; + dirlen = strlen (xdir); + if ((flags & MP_RMDOT) && dir[0] == '.' && dir[1] == '/') + { + xdir += 2; + dirlen -= 2; + } + + r = ret = (char *)xmalloc (2 + dirlen + pathlen); + s = xpath; + while (*s) + *r++ = *s++; + if (s > xpath && s[-1] != '/') + *r++ = '/'; + s = xdir; + while (*r++ = *s++) + ; + if (xpath != path && xpath != nullpath) + free (xpath); + return (ret); +} diff --git a/utshell-0.5.0/lib/sh/mbscasecmp.c b/utshell-0.5.0/lib/sh/mbscasecmp.c new file mode 100644 index 00000000..0ab95605 --- /dev/null +++ b/utshell-0.5.0/lib/sh/mbscasecmp.c @@ -0,0 +1,79 @@ +/* mbscasecmp - case-insensitive multibyte string comparison. */ + +/* Copyright (C) 2009-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_MBSCASECMP) && defined (HANDLE_MULTIBYTE) + +#include +#include +#include + +#include +#include + +/* Compare MBS1 and MBS2 without regard to case. */ +int +mbscasecmp (mbs1, mbs2) + const char *mbs1; + const char *mbs2; +{ + int len1, len2, mb_cur_max; + wchar_t c1, c2, l1, l2; + + len1 = len2 = 0; + /* Reset multibyte characters to their initial state. */ + (void) mblen ((char *) NULL, 0); + + mb_cur_max = MB_CUR_MAX; + do + { + len1 = mbtowc (&c1, mbs1, mb_cur_max); + len2 = mbtowc (&c2, mbs2, mb_cur_max); + + if (len1 == 0) + return len2 == 0 ? 0 : -1; + else if (len2 == 0) + return 1; + else if (len1 > 0 && len2 < 0) + return -1; + else if (len1 < 0 && len2 > 0) + return 1; + else if (len1 < 0 && len2 < 0) + { + len1 = strlen (mbs1); + len2 = strlen (mbs2); + return (len1 == len2 ? memcmp (mbs1, mbs2, len1) + : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1) + : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1))); + } + + l1 = towlower (c1); + l2 = towlower (c2); + + mbs1 += len1; + mbs2 += len2; + } + while (l1 == l2); + + return l1 - l2; +} + +#endif diff --git a/utshell-0.5.0/lib/sh/mbschr.c b/utshell-0.5.0/lib/sh/mbschr.c new file mode 100644 index 00000000..639962d4 --- /dev/null +++ b/utshell-0.5.0/lib/sh/mbschr.c @@ -0,0 +1,91 @@ +/* mbschr.c - strchr(3) that handles multibyte characters. */ + +/* Copyright (C) 2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#ifdef HAVE_STDLIB_H +# include +#endif + +#include "bashansi.h" +#include "shmbutil.h" + +extern int locale_mb_cur_max; +extern int locale_utf8locale; + +#undef mbschr + +extern char *utf8_mbschr (const char *, int); /* XXX */ + +/* In some locales, the non-first byte of some multibyte characters have + the same value as some ascii character. Faced with these strings, a + legacy strchr() might return the wrong value. */ + +char * +#if defined (PROTOTYPES) +mbschr (const char *s, int c) +#else +mbschr (s, c) + const char *s; + int c; +#endif +{ +#if HANDLE_MULTIBYTE + char *pos; + mbstate_t state; + size_t strlength, mblength; + + if (locale_utf8locale && c < 0x80) + return (utf8_mbschr (s, c)); /* XXX */ + + /* The locale encodings with said weird property are BIG5, BIG5-HKSCS, + GBK, GB18030, SHIFT_JIS, and JOHAB. They exhibit the problem only + when c >= 0x30. We can therefore use the faster bytewise search if + c <= 0x30. */ + if ((unsigned char)c >= '0' && locale_mb_cur_max > 1) + { + pos = (char *)s; + memset (&state, '\0', sizeof(mbstate_t)); + strlength = strlen (s); + + while (strlength > 0) + { + if (is_basic (*pos)) + mblength = 1; + else + { + mblength = mbrlen (pos, strlength, &state); + if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0) + mblength = 1; + } + + if (mblength == 1 && c == (unsigned char)*pos) + return pos; + + strlength -= mblength; + pos += mblength; + } + + return ((char *)NULL); + } + else +#endif + return (strchr (s, c)); +} diff --git a/utshell-0.5.0/lib/sh/mbscmp.c b/utshell-0.5.0/lib/sh/mbscmp.c new file mode 100644 index 00000000..c7c84435 --- /dev/null +++ b/utshell-0.5.0/lib/sh/mbscmp.c @@ -0,0 +1,77 @@ +/* mbscmp - multibyte string comparison. */ + +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_MBSCMP) && defined (HANDLE_MULTIBYTE) + +#include +#include +#include + +extern int locale_utf8locale; + +extern int utf8_mbscmp (const char *, const char *); + +/* Compare MBS1 and MBS2. */ +int +mbscmp (mbs1, mbs2) + const char *mbs1; + const char *mbs2; +{ + int len1, len2, mb_cur_max; + wchar_t c1, c2; + + len1 = len2 = 0; + /* Reset multibyte characters to their initial state. */ + (void) mblen ((char *) NULL, 0); + + mb_cur_max = MB_CUR_MAX; + do + { + len1 = mbtowc (&c1, mbs1, mb_cur_max); + len2 = mbtowc (&c2, mbs2, mb_cur_max); + + if (len1 == 0) + return len2 == 0 ? 0 : -1; + else if (len2 == 0) + return 1; + else if (len1 > 0 && len2 < 0) + return -1; + else if (len1 < 0 && len2 > 0) + return 1; + else if (len1 < 0 && len2 < 0) + { + len1 = strlen (mbs1); + len2 = strlen (mbs2); + return (len1 == len2 ? memcmp (mbs1, mbs2, len1) + : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1) + : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1))); + } + + mbs1 += len1; + mbs2 += len2; + } + while (c1 == c2); + + return c1 - c2; +} + +#endif diff --git a/utshell-0.5.0/lib/sh/memset.c b/utshell-0.5.0/lib/sh/memset.c new file mode 100644 index 00000000..4ebc4188 --- /dev/null +++ b/utshell-0.5.0/lib/sh/memset.c @@ -0,0 +1,29 @@ +/* memset.c -- set an area of memory to a given value */ + +/* Copyright (C) 1991-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +char * +memset (char *str, int c, unsigned int len) +{ + register char *st = str; + + while (len-- > 0) + *st++ = c; + return str; +} diff --git a/utshell-0.5.0/lib/sh/mktime.c b/utshell-0.5.0/lib/sh/mktime.c new file mode 100644 index 00000000..9ee675be --- /dev/null +++ b/utshell-0.5.0/lib/sh/mktime.c @@ -0,0 +1,438 @@ +/* mktime - convert struct tm to a time_t value */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + Contributed by Paul Eggert (eggert@twinsun.com). + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ +/* Define this to have a standalone program to test this implementation of + mktime. */ +/* #define DEBUG 1 */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# define HAVE_LOCALTIME_R 1 +# define STDC_HEADERS 1 +#endif + +/* Assume that leap seconds are possible, unless told otherwise. + If the host has a `zic' command with a `-L leapsecondfilename' option, + then it supports leap seconds; otherwise it probably doesn't. */ +#ifndef LEAP_SECONDS_POSSIBLE +#define LEAP_SECONDS_POSSIBLE 1 +#endif + +#ifndef VMS +#include /* Some systems define `time_t' here. */ +#endif +#include + +#if HAVE_LIMITS_H +#include +#endif + +#include "bashansi.h" + +#if DEBUG_MKTIME +#include +/* Make it work even if the system's libc has its own mktime routine. */ +#define mktime my_mktime +#endif /* DEBUG_MKTIME */ + +#ifndef PARAMS +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define PARAMS(args) args +#else +#define PARAMS(args) () +#endif /* GCC. */ +#endif /* Not PARAMS. */ + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#ifndef INT_MIN +#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1)) +#endif +#ifndef INT_MAX +#define INT_MAX (~0 - INT_MIN) +#endif + +/* True if the arithmetic type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* The maximum and minimum values for the integer type T. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ +#define TYPE_MINIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) 0 \ + : ~ TYPE_MAXIMUM (t))) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) + +#ifndef TIME_T_MIN +# define TIME_T_MIN TYPE_MINIMUM (time_t) +#endif +#ifndef TIME_T_MAX +# define TIME_T_MAX TYPE_MAXIMUM (time_t) +#endif + +#define TM_YEAR_BASE 1900 +#define EPOCH_YEAR 1970 + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* How many days come before each month (0-12). */ +const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; + +static time_t ydhms_tm_diff PARAMS ((int, int, int, int, int, const struct tm *)); +time_t __mktime_internal PARAMS ((struct tm *, + struct tm *(*) (const time_t *, struct tm *), + time_t *)); + + +static struct tm *my_localtime_r PARAMS ((const time_t *, struct tm *)); +static struct tm * +my_localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} + + +/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP), + measured in seconds, ignoring leap seconds. + YEAR uses the same numbering as TM->tm_year. + All values are in range, except possibly YEAR. + If overflow occurs, yield the low order bits of the correct answer. */ +static time_t +ydhms_tm_diff (year, yday, hour, min, sec, tp) + int year, yday, hour, min, sec; + const struct tm *tp; +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow. time_t overflow is OK, since + only the low order bits of the correct time_t answer are needed. + Don't convert to time_t until after all divisions are done, since + time_t might be unsigned. */ + int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3); + int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = a100 >> 2; + int b400 = b100 >> 2; + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + time_t years = year - (time_t) tp->tm_year; + time_t days = (365 * years + intervening_leap_days + + (yday - tp->tm_yday)); + return (60 * (60 * (24 * days + (hour - tp->tm_hour)) + + (min - tp->tm_min)) + + (sec - tp->tm_sec)); +} + + +static time_t localtime_offset; + +/* Convert *TP to a time_t value. */ +time_t +mktime (tp) + struct tm *tp; +{ +#ifdef _LIBC + /* POSIX.1 8.1.1 requires that whenever mktime() is called, the + time zone names contained in the external variable `tzname' shall + be set as if the tzset() function had been called. */ + __tzset (); +#endif + + return __mktime_internal (tp, my_localtime_r, &localtime_offset); +} + +/* Convert *TP to a time_t value, inverting + the monotonic and mostly-unit-linear conversion function CONVERT. + Use *OFFSET to keep track of a guess at the offset of the result, + compared to what the result would be for UTC without leap seconds. + If *OFFSET's guess is correct, only one CONVERT call is needed. */ +time_t +__mktime_internal (tp, convert, offset) + struct tm *tp; + struct tm *(*convert) PARAMS ((const time_t *, struct tm *)); + time_t *offset; +{ + time_t t, dt, t0; + struct tm tm; + + /* The maximum number of probes (calls to CONVERT) should be enough + to handle any combinations of time zone rule changes, solar time, + and leap seconds. Posix.1 prohibits leap seconds, but some hosts + have them anyway. */ + int remaining_probes = 4; + + /* Time requested. Copy it in case CONVERT modifies *TP; this can + occur if TP is localtime's returned value and CONVERT is localtime. */ + int sec = tp->tm_sec; + int min = tp->tm_min; + int hour = tp->tm_hour; + int mday = tp->tm_mday; + int mon = tp->tm_mon; + int year_requested = tp->tm_year; + int isdst = tp->tm_isdst; + + /* Ensure that mon is in range, and set year accordingly. */ + int mon_remainder = mon % 12; + int negative_mon_remainder = mon_remainder < 0; + int mon_years = mon / 12 - negative_mon_remainder; + int year = year_requested + mon_years; + + /* The other values need not be in range: + the remaining code handles minor overflows correctly, + assuming int and time_t arithmetic wraps around. + Major overflows are caught at the end. */ + + /* Calculate day of year from year, month, and day of month. + The result need not be in range. */ + int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)] + [mon_remainder + 12 * negative_mon_remainder]) + + mday - 1); + +#if LEAP_SECONDS_POSSIBLE + /* Handle out-of-range seconds specially, + since ydhms_tm_diff assumes every minute has 60 seconds. */ + int sec_requested = sec; + if (sec < 0) + sec = 0; + if (59 < sec) + sec = 59; +#endif + + /* Invert CONVERT by probing. First assume the same offset as last time. + Then repeatedly use the error to improve the guess. */ + + tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE; + tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm); + + for (t = t0 + *offset; + (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm))); + t += dt) + if (--remaining_probes == 0) + return -1; + + /* Check whether tm.tm_isdst has the requested value, if any. */ + if (0 <= isdst && 0 <= tm.tm_isdst) + { + int dst_diff = (isdst != 0) - (tm.tm_isdst != 0); + if (dst_diff) + { + /* Move two hours in the direction indicated by the disagreement, + probe some more, and switch to a new time if found. + The largest known fallback due to daylight savings is two hours: + once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */ + time_t ot = t - 2 * 60 * 60 * dst_diff; + while (--remaining_probes != 0) + { + struct tm otm; + if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec, + (*convert) (&ot, &otm)))) + { + t = ot; + tm = otm; + break; + } + if ((ot += dt) == t) + break; /* Avoid a redundant probe. */ + } + } + } + + *offset = t - t0; + +#if LEAP_SECONDS_POSSIBLE + if (sec_requested != tm.tm_sec) + { + /* Adjust time to reflect the tm_sec requested, not the normalized value. + Also, repair any damage from a false match due to a leap second. */ + t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60); + (*convert) (&t, &tm); + } +#endif + + if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) + { + /* time_t isn't large enough to rule out overflows in ydhms_tm_diff, + so check for major overflows. A gross check suffices, + since if t has overflowed, it is off by a multiple of + TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of + the difference that is bounded by a small value. */ + + double dyear = (double) year_requested + mon_years - tm.tm_year; + double dday = 366 * dyear + mday; + double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested; + + if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec)) + return -1; + } + + *tp = tm; + return t; +} + +#ifdef weak_alias +weak_alias (mktime, timelocal) +#endif + +#if DEBUG_MKTIME + +static int +not_equal_tm (a, b) + struct tm *a; + struct tm *b; +{ + return ((a->tm_sec ^ b->tm_sec) + | (a->tm_min ^ b->tm_min) + | (a->tm_hour ^ b->tm_hour) + | (a->tm_mday ^ b->tm_mday) + | (a->tm_mon ^ b->tm_mon) + | (a->tm_year ^ b->tm_year) + | (a->tm_mday ^ b->tm_mday) + | (a->tm_yday ^ b->tm_yday) + | (a->tm_isdst ^ b->tm_isdst)); +} + +static void +print_tm (tp) + struct tm *tp; +{ + printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d", + tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec, + tp->tm_yday, tp->tm_wday, tp->tm_isdst); +} + +static int +check_result (tk, tmk, tl, tml) + time_t tk; + struct tm tmk; + time_t tl; + struct tm tml; +{ + if (tk != tl || not_equal_tm (&tmk, &tml)) + { + printf ("mktime ("); + print_tm (&tmk); + printf (")\nyields ("); + print_tm (&tml); + printf (") == %ld, should be %ld\n", (long) tl, (long) tk); + return 1; + } + + return 0; +} + +int +main (argc, argv) + int argc; + char **argv; +{ + int status = 0; + struct tm tm, tmk, tml; + time_t tk, tl; + char trailer; + + if ((argc == 3 || argc == 4) + && (sscanf (argv[1], "%d-%d-%d%c", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) + == 3) + && (sscanf (argv[2], "%d:%d:%d%c", + &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer) + == 3)) + { + tm.tm_year -= TM_YEAR_BASE; + tm.tm_mon--; + tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); + tmk = tm; + tl = mktime (&tmk); + tml = *localtime (&tl); + printf ("mktime returns %ld == ", (long) tl); + print_tm (&tmk); + printf ("\n"); + status = check_result (tl, tmk, tl, tml); + } + else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0)) + { + time_t from = atol (argv[1]); + time_t by = atol (argv[2]); + time_t to = atol (argv[3]); + + if (argc == 4) + for (tl = from; tl <= to; tl += by) + { + tml = *localtime (&tl); + tmk = tml; + tk = mktime (&tmk); + status |= check_result (tk, tmk, tl, tml); + } + else + for (tl = from; tl <= to; tl += by) + { + /* Null benchmark. */ + tml = *localtime (&tl); + tmk = tml; + tk = tl; + status |= check_result (tk, tmk, tl, tml); + } + } + else + printf ("Usage:\ +\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\ +\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\ +\t%s FROM BY TO - # Do not test those values (for benchmark).\n", + argv[0], argv[0], argv[0]); + + return status; +} + +#endif /* DEBUG_MKTIME */ + +/* +Local Variables: +compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime" +End: +*/ diff --git a/utshell-0.5.0/lib/sh/netconn.c b/utshell-0.5.0/lib/sh/netconn.c new file mode 100644 index 00000000..e20f1042 --- /dev/null +++ b/utshell-0.5.0/lib/sh/netconn.c @@ -0,0 +1,82 @@ +/* netconn.c -- is a particular file descriptor a network connection?. */ + +/* Copyright (C) 2002-2005 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif +#include +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +/* The second and subsequent conditions must match those used to decide + whether or not to call getpeername() in isnetconn(). */ +#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2) +# include +#endif + +/* Is FD a socket or network connection? */ +int +isnetconn (fd) + int fd; +{ +#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2) && !defined (__BEOS__) + int rv; + socklen_t l; + struct sockaddr sa; + + l = sizeof(sa); + rv = getpeername(fd, &sa, &l); + /* Posix.2 says getpeername can return these errors. */ + return ((rv < 0 && (errno == ENOTSOCK || errno == ENOTCONN || errno == EINVAL || errno == EBADF)) ? 0 : 1); +#else /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */ +# if defined (SVR4) || defined (SVR4_2) + /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */ + struct stat sb; + + if (isatty (fd)) + return (0); + if (fstat (fd, &sb) < 0) + return (0); +# if defined (S_ISFIFO) + if (S_ISFIFO (sb.st_mode)) + return (0); +# endif /* S_ISFIFO */ + return (S_ISCHR (sb.st_mode)); +# else /* !SVR4 && !SVR4_2 */ +# if defined (S_ISSOCK) && !defined (__BEOS__) + struct stat sb; + + if (fstat (fd, &sb) < 0) + return (0); + return (S_ISSOCK (sb.st_mode)); +# else /* !S_ISSOCK || __BEOS__ */ + return (0); +# endif /* !S_ISSOCK || __BEOS__ */ +# endif /* !SVR4 && !SVR4_2 */ +#endif /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */ +} diff --git a/utshell-0.5.0/lib/sh/netopen.c b/utshell-0.5.0/lib/sh/netopen.c new file mode 100644 index 00000000..ee0baf66 --- /dev/null +++ b/utshell-0.5.0/lib/sh/netopen.c @@ -0,0 +1,351 @@ +/* + * netopen.c -- functions to make tcp/udp connections + * + * Chet Ramey + * chet@ins.CWRU.Edu + */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_NETWORK) + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#if defined (HAVE_SYS_SOCKET_H) +# include +#endif + +#if defined (HAVE_NETINET_IN_H) +# include +#endif + +#if defined (HAVE_NETDB_H) +# include +#endif + +#if defined (HAVE_ARPA_INET_H) +# include +#endif + +#include +#include + +#include + +#include +#include + +#ifndef errno +extern int errno; +#endif + +#if !defined (HAVE_INET_ATON) +extern int inet_aton PARAMS((const char *, struct in_addr *)); +#endif + +#ifndef HAVE_GETADDRINFO +static int _getaddr PARAMS((char *, struct in_addr *)); +static int _getserv PARAMS((char *, int, unsigned short *)); +static int _netopen4 PARAMS((char *, char *, int)); +#else /* HAVE_GETADDRINFO */ +static int _netopen6 PARAMS((char *, char *, int)); +#endif + +static int _netopen PARAMS((char *, char *, int)); + +#ifndef HAVE_GETADDRINFO +/* Stuff the internet address corresponding to HOST into AP, in network + byte order. Return 1 on success, 0 on failure. */ + +static int +_getaddr (host, ap) + char *host; + struct in_addr *ap; +{ + struct hostent *h; + int r; + + r = 0; + if (host[0] >= '0' && host[0] <= '9') + { + /* If the first character is a digit, guess that it's an + Internet address and return immediately if inet_aton succeeds. */ + r = inet_aton (host, ap); + if (r) + return r; + } +#if !defined (HAVE_GETHOSTBYNAME) + return 0; +#else + h = gethostbyname (host); + if (h && h->h_addr) + { + bcopy(h->h_addr, (char *)ap, h->h_length); + return 1; + } +#endif + return 0; + +} + +/* Return 1 if SERV is a valid port number and stuff the converted value into + PP in network byte order. */ +static int +_getserv (serv, proto, pp) + char *serv; + int proto; + unsigned short *pp; +{ + intmax_t l; + unsigned short s; + + if (legal_number (serv, &l)) + { + s = (unsigned short)(l & 0xFFFF); + if (s != l) + return (0); + s = htons (s); + if (pp) + *pp = s; + return 1; + } + else +#if defined (HAVE_GETSERVBYNAME) + { + struct servent *se; + + se = getservbyname (serv, (proto == 't') ? "tcp" : "udp"); + if (se == 0) + return 0; + if (pp) + *pp = se->s_port; /* ports returned in network byte order */ + return 1; + } +#else /* !HAVE_GETSERVBYNAME */ + return 0; +#endif /* !HAVE_GETSERVBYNAME */ +} + +/* + * Open a TCP or UDP connection to HOST on port SERV. Uses the + * traditional BSD mechanisms. Returns the connected socket or -1 on error. + */ +static int +_netopen4(host, serv, typ) + char *host, *serv; + int typ; +{ + struct in_addr ina; + struct sockaddr_in sin; + unsigned short p; + int s, e; + + if (_getaddr(host, &ina) == 0) + { + internal_error (_("%s: host unknown"), host); + errno = EINVAL; + return -1; + } + + if (_getserv(serv, typ, &p) == 0) + { + internal_error(_("%s: invalid service"), serv); + errno = EINVAL; + return -1; + } + + memset ((char *)&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = p; + sin.sin_addr = ina; + + s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0); + if (s < 0) + { + sys_error ("socket"); + return (-1); + } + + if (connect (s, (struct sockaddr *)&sin, sizeof (sin)) < 0) + { + e = errno; + sys_error("connect"); + close(s); + errno = e; + return (-1); + } + + return(s); +} +#endif /* ! HAVE_GETADDRINFO */ + +#ifdef HAVE_GETADDRINFO +/* + * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3) + * which provides support for IPv6. Returns the connected socket or -1 + * on error. + */ +static int +_netopen6 (host, serv, typ) + char *host, *serv; + int typ; +{ + int s, e; + struct addrinfo hints, *res, *res0; + int gerr; + + memset ((char *)&hints, 0, sizeof (hints)); + /* XXX -- if problems with IPv6, set to PF_INET for IPv4 only */ +#ifdef DEBUG /* PF_INET is the one that works for me */ + hints.ai_family = PF_INET; +#else + hints.ai_family = PF_UNSPEC; +#endif + hints.ai_socktype = (typ == 't') ? SOCK_STREAM : SOCK_DGRAM; + + gerr = getaddrinfo (host, serv, &hints, &res0); + if (gerr) + { + if (gerr == EAI_SERVICE) + internal_error ("%s: %s", serv, gai_strerror (gerr)); + else + internal_error ("%s: %s", host, gai_strerror (gerr)); + errno = EINVAL; + return -1; + } + + for (res = res0; res; res = res->ai_next) + { + if ((s = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) + { + if (res->ai_next) + continue; + sys_error ("socket"); + freeaddrinfo (res0); + return -1; + } + if (connect (s, res->ai_addr, res->ai_addrlen) < 0) + { + if (res->ai_next) + { + close (s); + continue; + } + e = errno; + sys_error ("connect"); + close (s); + freeaddrinfo (res0); + errno = e; + return -1; + } + freeaddrinfo (res0); + break; + } + return s; +} +#endif /* HAVE_GETADDRINFO */ + +/* + * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3) + * if available, falling back to the traditional BSD mechanisms otherwise. + * Returns the connected socket or -1 on error. + */ +static int +_netopen(host, serv, typ) + char *host, *serv; + int typ; +{ +#ifdef HAVE_GETADDRINFO + return (_netopen6 (host, serv, typ)); +#else + return (_netopen4 (host, serv, typ)); +#endif +} + +/* + * Open a TCP or UDP connection given a path like `/dev/tcp/host/port' to + * host `host' on port `port' and return the connected socket. + */ +int +netopen (path) + char *path; +{ + char *np, *s, *t; + int fd; + + np = (char *)xmalloc (strlen (path) + 1); + strcpy (np, path); + + s = np + 9; + t = strchr (s, '/'); + if (t == 0) + { + internal_error (_("%s: bad network path specification"), path); + free (np); + return -1; + } + *t++ = '\0'; + fd = _netopen (s, t, path[5]); + free (np); + + return fd; +} + +#if 0 +/* + * Open a TCP connection to host `host' on the port defined for service + * `serv' and return the connected socket. + */ +int +tcpopen (host, serv) + char *host, *serv; +{ + return (_netopen (host, serv, 't')); +} + +/* + * Open a UDP connection to host `host' on the port defined for service + * `serv' and return the connected socket. + */ +int +udpopen (host, serv) + char *host, *serv; +{ + return _netopen (host, serv, 'u'); +} +#endif + +#else /* !HAVE_NETWORK */ + +int +netopen (path) + char *path; +{ + internal_error (_("network operations not supported")); + return -1; +} + +#endif /* !HAVE_NETWORK */ diff --git a/utshell-0.5.0/lib/sh/oslib.c b/utshell-0.5.0/lib/sh/oslib.c new file mode 100644 index 00000000..65eb99d9 --- /dev/null +++ b/utshell-0.5.0/lib/sh/oslib.c @@ -0,0 +1,301 @@ +/* oslib.c - functions present only in some unix versions. */ + +/* Copyright (C) 1995,2010 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#if defined (HAVE_SYS_PARAM_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include +#include +#include + +#if !defined (HAVE_KILLPG) +# include +#endif + +#include +#include +#include + +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* Make the functions strchr and strrchr if they do not exist. */ +#if !defined (HAVE_STRCHR) +char * +strchr (string, c) + char *string; + int c; +{ + register char *s; + + for (s = string; s && *s; s++) + if (*s == c) + return (s); + + return ((char *) NULL); +} + +char * +strrchr (string, c) + char *string; + int c; +{ + register char *s, *t; + + for (s = string, t = (char *)NULL; s && *s; s++) + if (*s == c) + t = s; + return (t); +} +#endif /* !HAVE_STRCHR */ + +#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN) +/* Replacement for dup2 (), for those systems which either don't have it, + or supply one with broken behaviour. */ +int +dup2 (fd1, fd2) + int fd1, fd2; +{ + int saved_errno, r; + + /* If FD1 is not a valid file descriptor, then return immediately with + an error. */ + if (fcntl (fd1, F_GETFL, 0) == -1) + return (-1); + + if (fd2 < 0 || fd2 >= getdtablesize ()) + { + errno = EBADF; + return (-1); + } + + if (fd1 == fd2) + return (0); + + saved_errno = errno; + + (void) close (fd2); + r = fcntl (fd1, F_DUPFD, fd2); + + if (r >= 0) + errno = saved_errno; + else + if (errno == EINVAL) + errno = EBADF; + + /* Force the new file descriptor to remain open across exec () calls. */ + SET_OPEN_ON_EXEC (fd2); + return (r); +} +#endif /* !HAVE_DUP2 */ + +/* + * Return the total number of available file descriptors. + * + * On some systems, like 4.2BSD and its descendants, there is a system call + * that returns the size of the descriptor table: getdtablesize(). There are + * lots of ways to emulate this on non-BSD systems. + * + * On System V.3, this can be obtained via a call to ulimit: + * return (ulimit(4, 0L)); + * + * On other System V systems, NOFILE is defined in /usr/include/sys/param.h + * (this is what we assume below), so we can simply use it: + * return (NOFILE); + * + * On POSIX systems, there are specific functions for retrieving various + * configuration parameters: + * return (sysconf(_SC_OPEN_MAX)); + * + */ + +#if !defined (HAVE_GETDTABLESIZE) +int +getdtablesize () +{ +# if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) + return (sysconf(_SC_OPEN_MAX)); /* Posix systems use sysconf */ +# else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */ +# if defined (ULIMIT_MAXFDS) + return (ulimit (4, 0L)); /* System V.3 systems use ulimit(4, 0L) */ +# else /* !ULIMIT_MAXFDS */ +# if defined (NOFILE) /* Other systems use NOFILE */ + return (NOFILE); +# else /* !NOFILE */ + return (20); /* XXX - traditional value is 20 */ +# endif /* !NOFILE */ +# endif /* !ULIMIT_MAXFDS */ +# endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */ +} +#endif /* !HAVE_GETDTABLESIZE */ + +#if !defined (HAVE_BCOPY) +# if defined (bcopy) +# undef bcopy +# endif +void +bcopy (s,d,n) + char *d, *s; + int n; +{ + FASTCOPY (s, d, n); +} +#endif /* !HAVE_BCOPY */ + +#if !defined (HAVE_BZERO) +# if defined (bzero) +# undef bzero +# endif +void +bzero (s, n) + char *s; + int n; +{ + register int i; + register char *r; + + for (i = 0, r = s; i < n; i++) + *r++ = '\0'; +} +#endif + +#if !defined (HAVE_GETHOSTNAME) +# if defined (HAVE_UNAME) +# include +int +gethostname (name, namelen) + char *name; + int namelen; +{ + int i; + struct utsname ut; + + --namelen; + + uname (&ut); + i = strlen (ut.nodename) + 1; + strncpy (name, ut.nodename, i < namelen ? i : namelen); + name[namelen] = '\0'; + return (0); +} +# else /* !HAVE_UNAME */ +int +gethostname (name, namelen) + char *name; + int namelen; +{ + strncpy (name, "unknown", namelen); + name[namelen] = '\0'; + return 0; +} +# endif /* !HAVE_UNAME */ +#endif /* !HAVE_GETHOSTNAME */ + +#if !defined (HAVE_KILLPG) +int +killpg (pgrp, sig) + pid_t pgrp; + int sig; +{ + return (kill (-pgrp, sig)); +} +#endif /* !HAVE_KILLPG */ + +#if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION) +int +mkfifo (path, mode) + char *path; + int mode; +{ +#if defined (S_IFIFO) + return (mknod (path, (mode | S_IFIFO), 0)); +#else /* !S_IFIFO */ + return (-1); +#endif /* !S_IFIFO */ +} +#endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */ + +#define DEFAULT_MAXGROUPS 64 + +int +getmaxgroups () +{ + static int maxgroups = -1; + + if (maxgroups > 0) + return maxgroups; + +#if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX) + maxgroups = sysconf (_SC_NGROUPS_MAX); +#else +# if defined (NGROUPS_MAX) + maxgroups = NGROUPS_MAX; +# else /* !NGROUPS_MAX */ +# if defined (NGROUPS) + maxgroups = NGROUPS; +# else /* !NGROUPS */ + maxgroups = DEFAULT_MAXGROUPS; +# endif /* !NGROUPS */ +# endif /* !NGROUPS_MAX */ +#endif /* !HAVE_SYSCONF || !SC_NGROUPS_MAX */ + + if (maxgroups <= 0) + maxgroups = DEFAULT_MAXGROUPS; + + return maxgroups; +} + +long +getmaxchild () +{ + static long maxchild = -1L; + + if (maxchild > 0) + return maxchild; + +#if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX) + maxchild = sysconf (_SC_CHILD_MAX); +#else +# if defined (CHILD_MAX) + maxchild = CHILD_MAX; +# else +# if defined (MAXUPRC) + maxchild = MAXUPRC; +# endif /* MAXUPRC */ +# endif /* CHILD_MAX */ +#endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ + + return (maxchild); +} diff --git a/utshell-0.5.0/lib/sh/pathcanon.c b/utshell-0.5.0/lib/sh/pathcanon.c new file mode 100644 index 00000000..7d0df9f9 --- /dev/null +++ b/utshell-0.5.0/lib/sh/pathcanon.c @@ -0,0 +1,234 @@ +/* pathcanon.c -- canonicalize and manipulate pathnames. */ + +/* Copyright (C) 2000 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#if defined (HAVE_SYS_PARAM_H) +# include +#endif +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include +#include +#include +#include + +#include "shell.h" + +#if !defined (errno) +extern int errno; +#endif + +#if defined (__CYGWIN__) +#include + +static int +_is_cygdrive (path) + char *path; +{ + static char user[MAXPATHLEN]; + static char system[MAXPATHLEN]; + static int first_time = 1; + + /* If the path is the first part of a network path, treat it as + existing. */ + if (path[0] == '/' && path[1] == '/' && !strchr (path + 2, '/')) + return 1; + /* Otherwise check for /cygdrive prefix. */ + if (first_time) + { + char user_flags[MAXPATHLEN]; + char system_flags[MAXPATHLEN]; + /* Get the cygdrive info */ + cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, system_flags); + first_time = 0; + } + return !strcasecmp (path, user) || !strcasecmp (path, system); +} +#endif /* __CYGWIN__ */ + +/* Return 1 if PATH corresponds to a directory. A function for debugging. */ +static int +_path_isdir (path) + char *path; +{ + int l; + struct stat sb; + + /* This should leave errno set to the correct value. */ + errno = 0; + l = stat (path, &sb) == 0 && S_ISDIR (sb.st_mode); +#if defined (__CYGWIN__) + if (l == 0) + l = _is_cygdrive (path); +#endif + return l; +} + +/* Canonicalize PATH, and return a new path. The new path differs from PATH + in that: + Multiple `/'s are collapsed to a single `/'. + Leading `./'s and trailing `/.'s are removed. + Trailing `/'s are removed. + Non-leading `../'s and trailing `..'s are handled by removing + portions of the path. */ + +/* Look for ROOTEDPATH, PATHSEP, DIRSEP, and ISDIRSEP in ../../general.h */ + +#define DOUBLE_SLASH(p) ((p[0] == '/') && (p[1] == '/') && p[2] != '/') + +char * +sh_canonpath (path, flags) + char *path; + int flags; +{ + char stub_char; + char *result, *p, *q, *base, *dotdot; + int rooted, double_slash_path; + + /* The result cannot be larger than the input PATH. */ + result = (flags & PATH_NOALLOC) ? path : savestring (path); + + /* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any + leading `x:' (dos drive name). */ + if (rooted = ROOTEDPATH(path)) + { + stub_char = DIRSEP; +#if defined (__CYGWIN__) + base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 3 : result + 1; +#else + base = result + 1; +#endif + double_slash_path = DOUBLE_SLASH (path); + base += double_slash_path; + } + else + { + stub_char = '.'; +#if defined (__CYGWIN__) + base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 2 : result; +#else + base = result; +#endif + double_slash_path = 0; + } + + /* + * invariants: + * base points to the portion of the path we want to modify + * p points at beginning of path element we're considering. + * q points just past the last path element we wrote (no slash). + * dotdot points just past the point where .. cannot backtrack + * any further (no slash). + */ + p = q = dotdot = base; + + while (*p) + { + if (ISDIRSEP(p[0])) /* null element */ + p++; + else if(p[0] == '.' && PATHSEP(p[1])) /* . and ./ */ + p += 1; /* don't count the separator in case it is nul */ + else if (p[0] == '.' && p[1] == '.' && PATHSEP(p[2])) /* .. and ../ */ + { + p += 2; /* skip `..' */ + if (q > dotdot) /* can backtrack */ + { + if (flags & PATH_CHECKDOTDOT) + { + char c; + + /* Make sure what we have so far corresponds to a valid + path before we chop some of it off. */ + c = *q; + *q = '\0'; + if (_path_isdir (result) == 0) + { + if ((flags & PATH_NOALLOC) == 0) + free (result); + return ((char *)NULL); + } + *q = c; + } + + while (--q > dotdot && ISDIRSEP(*q) == 0) + ; + } + else if (rooted == 0) + { + /* /.. is / but ./../ is .. */ + if (q != base) + *q++ = DIRSEP; + *q++ = '.'; + *q++ = '.'; + dotdot = q; + } + } + else /* real path element */ + { + /* add separator if not at start of work portion of result */ + if (q != base) + *q++ = DIRSEP; + while (*p && (ISDIRSEP(*p) == 0)) + *q++ = *p++; + /* Check here for a valid directory with _path_isdir. */ + if (flags & PATH_CHECKEXISTS) + { + char c; + + /* Make sure what we have so far corresponds to a valid + path before we chop some of it off. */ + c = *q; + *q = '\0'; + if (_path_isdir (result) == 0) + { + if ((flags & PATH_NOALLOC) == 0) + free (result); + return ((char *)NULL); + } + *q = c; + } + } + } + + /* Empty string is really ``.'' or `/', depending on what we started with. */ + if (q == result) + *q++ = stub_char; + *q = '\0'; + + /* If the result starts with `//', but the original path does not, we + can turn the // into /. Because of how we set `base', this should never + be true, but it's a sanity check. */ + if (DOUBLE_SLASH(result) && double_slash_path == 0) + { + if (result[2] == '\0') /* short-circuit for bare `//' */ + result[1] = '\0'; + else + memmove (result, result + 1, strlen (result + 1) + 1); + } + + return (result); +} diff --git a/utshell-0.5.0/lib/sh/pathphys.c b/utshell-0.5.0/lib/sh/pathphys.c new file mode 100644 index 00000000..95b72f19 --- /dev/null +++ b/utshell-0.5.0/lib/sh/pathphys.c @@ -0,0 +1,296 @@ +/* pathphys.c -- return pathname with all symlinks expanded. */ + +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#if defined (HAVE_SYS_PARAM_H) +# include +#endif +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include +#include +#include +#include + +#include "shell.h" + +#if !defined (MAXSYMLINKS) +# define MAXSYMLINKS 32 +#endif + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern char *get_working_directory PARAMS((char *)); + +static int +_path_readlink (path, buf, bufsiz) + char *path; + char *buf; + int bufsiz; +{ +#ifdef HAVE_READLINK + return readlink (path, buf, bufsiz); +#else + errno = EINVAL; + return -1; +#endif +} + +/* Look for ROOTEDPATH, PATHSEP, DIRSEP, and ISDIRSEP in ../../general.h */ + +#define DOUBLE_SLASH(p) ((p[0] == '/') && (p[1] == '/') && p[2] != '/') + +/* + * Return PATH with all symlinks expanded in newly-allocated memory. + * This always gets an absolute pathname. + */ + +char * +sh_physpath (path, flags) + char *path; + int flags; +{ + char tbuf[PATH_MAX+1], linkbuf[PATH_MAX+1]; + char *result, *p, *q, *qsave, *qbase, *workpath; + int double_slash_path, linklen, nlink; + + linklen = strlen (path); + +#if 0 + /* First sanity check -- punt immediately if the name is too long. */ + if (linklen >= PATH_MAX) + return (savestring (path)); +#endif + + nlink = 0; + q = result = (char *)xmalloc (PATH_MAX + 1); + + /* Even if we get something longer than PATH_MAX, we might be able to + shorten it, so we try. */ + if (linklen >= PATH_MAX) + workpath = savestring (path); + else + { + workpath = (char *)xmalloc (PATH_MAX + 1); + strcpy (workpath, path); + } + + /* This always gets an absolute pathname. */ + + /* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any + leading `x:' (dos drive name). */ +#if defined (__CYGWIN__) + qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; +#else + qbase = workpath + 1; +#endif + double_slash_path = DOUBLE_SLASH (workpath); + qbase += double_slash_path; + + for (p = workpath; p < qbase; ) + *q++ = *p++; + qbase = q; + + /* + * invariants: + * qbase points to the portion of the result path we want to modify + * p points at beginning of path element we're considering. + * q points just past the last path element we wrote (no slash). + * + * XXX -- need to fix error checking for too-long pathnames + */ + + while (*p) + { + if (ISDIRSEP(p[0])) /* null element */ + p++; + else if(p[0] == '.' && PATHSEP(p[1])) /* . and ./ */ + p += 1; /* don't count the separator in case it is nul */ + else if (p[0] == '.' && p[1] == '.' && PATHSEP(p[2])) /* .. and ../ */ + { + p += 2; /* skip `..' */ + if (q > qbase) + { + while (--q > qbase && ISDIRSEP(*q) == 0) + ; + } + } + else /* real path element */ + { + /* add separator if not at start of work portion of result */ + qsave = q; + if (q != qbase) + *q++ = DIRSEP; + while (*p && (ISDIRSEP(*p) == 0)) + { + if (q - result >= PATH_MAX) + { +#ifdef ENAMETOOLONG + errno = ENAMETOOLONG; +#else + errno = EINVAL; +#endif + goto error; + } + + *q++ = *p++; + } + + *q = '\0'; + + linklen = _path_readlink (result, linkbuf, PATH_MAX); + if (linklen < 0) /* if errno == EINVAL, it's not a symlink */ + { + if (errno != EINVAL) + goto error; + continue; + } + + /* It's a symlink, and the value is in LINKBUF. */ + nlink++; + if (nlink > MAXSYMLINKS) + { +#ifdef ELOOP + errno = ELOOP; +#else + errno = EINVAL; +#endif +error: + free (result); + free (workpath); + return ((char *)NULL); + } + + linkbuf[linklen] = '\0'; + + /* If the new path length would overrun PATH_MAX, punt now. */ + if ((strlen (p) + linklen + 2) >= PATH_MAX) + { +#ifdef ENAMETOOLONG + errno = ENAMETOOLONG; +#else + errno = EINVAL; +#endif + goto error; + } + + /* Form the new pathname by copying the link value to a temporary + buffer and appending the rest of `workpath'. Reset p to point + to the start of the rest of the path. If the link value is an + absolute pathname, reset p, q, and qbase. If not, reset p + and q. */ + strcpy (tbuf, linkbuf); + tbuf[linklen] = '/'; + strcpy (tbuf + linklen, p); + strcpy (workpath, tbuf); + + if (ABSPATH(linkbuf)) + { + q = result; + /* Duplicating some code here... */ +#if defined (__CYGWIN__) + qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; +#else + qbase = workpath + 1; +#endif + double_slash_path = DOUBLE_SLASH (workpath); + qbase += double_slash_path; + + for (p = workpath; p < qbase; ) + *q++ = *p++; + qbase = q; + } + else + { + p = workpath; + q = qsave; + } + } + } + + *q = '\0'; + free (workpath); + + /* If the result starts with `//', but the original path does not, we + can turn the // into /. Because of how we set `qbase', this should never + be true, but it's a sanity check. */ + if (DOUBLE_SLASH(result) && double_slash_path == 0) + { + if (result[2] == '\0') /* short-circuit for bare `//' */ + result[1] = '\0'; + else + memmove (result, result + 1, strlen (result + 1) + 1); + } + + return (result); +} + +char * +sh_realpath (pathname, resolved) + const char *pathname; + char *resolved; +{ + char *tdir, *wd; + + if (pathname == 0 || *pathname == '\0') + { + errno = (pathname == 0) ? EINVAL : ENOENT; + return ((char *)NULL); + } + + if (ABSPATH (pathname) == 0) + { + wd = get_working_directory ("sh_realpath"); + if (wd == 0) + return ((char *)NULL); + tdir = sh_makepath (wd, (char *)pathname, 0); + free (wd); + } + else + tdir = savestring (pathname); + + wd = sh_physpath (tdir, 0); + free (tdir); + + if (resolved == 0) + return (wd); + + if (wd) + { + strncpy (resolved, wd, PATH_MAX - 1); + resolved[PATH_MAX - 1] = '\0'; + free (wd); + return resolved; + } + else + { + resolved[0] = '\0'; + return wd; + } +} diff --git a/utshell-0.5.0/lib/sh/random.c b/utshell-0.5.0/lib/sh/random.c new file mode 100644 index 00000000..1eaa71aa --- /dev/null +++ b/utshell-0.5.0/lib/sh/random.c @@ -0,0 +1,240 @@ +/* random.c -- Functions for managing 16-bit and 32-bit random numbers. */ + +/* Copyright (C) 2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include "bashtypes.h" + +#if defined (HAVE_SYS_RANDOM_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif +#include "filecntl.h" + +#include +#include "bashansi.h" + +#include "shell.h" + +extern time_t shell_start_time; + +extern int last_random_value; + +static u_bits32_t intrand32 PARAMS((u_bits32_t)); +static u_bits32_t genseed PARAMS((void)); + +static u_bits32_t brand32 PARAMS((void)); +static void sbrand32 PARAMS((u_bits32_t)); +static void perturb_rand32 PARAMS((void)); + +/* The random number seed. You can change this by setting RANDOM. */ +static u_bits32_t rseed = 1; + +/* Returns a 32-bit pseudo-random number. */ +static u_bits32_t +intrand32 (last) + u_bits32_t last; +{ + /* Minimal Standard generator from + "Random number generators: good ones are hard to find", + Park and Miller, Communications of the ACM, vol. 31, no. 10, + October 1988, p. 1195. Filtered through FreeBSD. + + x(n+1) = 16807 * x(n) mod (m). + + We split up the calculations to avoid overflow. + + h = last / q; l = x - h * q; t = a * l - h * r + m = 2147483647, a = 16807, q = 127773, r = 2836 + + There are lots of other combinations of constants to use; look at + https://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html#Other-random-number-generators */ + + bits32_t h, l, t; + u_bits32_t ret; + + /* Can't seed with 0. */ + ret = (last == 0) ? 123459876 : last; + h = ret / 127773; + l = ret - (127773 * h); + t = 16807 * l - 2836 * h; + ret = (t < 0) ? t + 0x7fffffff : t; + + return (ret); +} + +static u_bits32_t +genseed () +{ + struct timeval tv; + u_bits32_t iv; + + gettimeofday (&tv, NULL); + iv = (u_bits32_t)seedrand; /* let the compiler truncate */ + iv = tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ iv; + return (iv); +} + +#define BASH_RAND_MAX 32767 /* 0x7fff - 16 bits */ + +/* Returns a pseudo-random number between 0 and 32767. */ +int +brand () +{ + unsigned int ret; + + rseed = intrand32 (rseed); + if (shell_compatibility_level > 50) + ret = (rseed >> 16) ^ (rseed & 65535); + else + ret = rseed; + return (ret & BASH_RAND_MAX); +} + +/* Set the random number generator seed to SEED. */ +void +sbrand (seed) + unsigned long seed; +{ + rseed = seed; + last_random_value = 0; +} + +void +seedrand () +{ + u_bits32_t iv; + + iv = genseed (); + sbrand (iv); +} + +static u_bits32_t rseed32 = 1073741823; +static int last_rand32; + +static int urandfd = -1; + +#define BASH_RAND32_MAX 0x7fffffff /* 32 bits */ + +/* Returns a 32-bit pseudo-random number between 0 and 4294967295. */ +static u_bits32_t +brand32 () +{ + u_bits32_t ret; + + rseed32 = intrand32 (rseed32); + return (rseed32 & BASH_RAND32_MAX); +} + +static void +sbrand32 (seed) + u_bits32_t seed; +{ + last_rand32 = rseed32 = seed; +} + +void +seedrand32 () +{ + u_bits32_t iv; + + iv = genseed (); + sbrand32 (iv); +} + +static void +perturb_rand32 () +{ + rseed32 ^= genseed (); +} + +/* Force another attempt to open /dev/urandom on the next call to get_urandom32 */ +void +urandom_close () +{ + if (urandfd >= 0) + close (urandfd); + urandfd = -1; +} + +#if !defined (HAVE_GETRANDOM) +/* Imperfect emulation of getrandom(2). */ +#ifndef GRND_NONBLOCK +# define GRND_NONBLOCK 1 +# define GRND_RANDOM 2 +#endif + +static ssize_t +getrandom (buf, len, flags) + void *buf; + size_t len; + unsigned int flags; +{ + int oflags; + ssize_t r; + static int urand_unavail = 0; + +#if HAVE_GETENTROPY + r = getentropy (buf, len); + return (r == 0) ? len : -1; +#endif + + if (urandfd == -1 && urand_unavail == 0) + { + oflags = O_RDONLY; + if (flags & GRND_NONBLOCK) + oflags |= O_NONBLOCK; + urandfd = open ("/dev/urandom", oflags, 0); + if (urandfd >= 0) + SET_CLOSE_ON_EXEC (urandfd); + else + { + urand_unavail = 1; + return -1; + } + } + if (urandfd >= 0 && (r = read (urandfd, buf, len)) == len) + return (r); + return -1; +} +#endif + +u_bits32_t +get_urandom32 () +{ + u_bits32_t ret; + + if (getrandom ((void *)&ret, sizeof (ret), GRND_NONBLOCK) == sizeof (ret)) + return (last_rand32 = ret); + +#if defined (HAVE_ARC4RANDOM) + ret = arc4random (); +#else + if (subshell_environment) + perturb_rand32 (); + do + ret = brand32 (); + while (ret == last_rand32); +#endif + return (last_rand32 = ret); +} diff --git a/utshell-0.5.0/lib/sh/rename.c b/utshell-0.5.0/lib/sh/rename.c new file mode 100644 index 00000000..e410b5e8 --- /dev/null +++ b/utshell-0.5.0/lib/sh/rename.c @@ -0,0 +1,76 @@ +/* + * rename - rename a file + */ + +/* Copyright (C) 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_RENAME) + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif +#include + +#include + +#ifndef errno +extern int errno; +#endif + +int +rename (from, to) + const char *from, *to; +{ + struct stat fb, tb; + + if (stat (from, &fb) < 0) + return -1; + + if (stat (to, &tb) < 0) + { + if (errno != ENOENT) + return -1; + } + else + { + if (fb.st_dev == tb.st_dev && fb.st_ino == tb.st_ino) + return 0; /* same file */ + if (unlink (to) < 0 && errno != ENOENT) + return -1; + } + + if (link (from, to) < 0) + return (-1); + + if (unlink (from) < 0 && errno != ENOENT) + { + int e = errno; + unlink (to); + errno = e; + return (-1); + } + + return (0); +} +#endif /* !HAVE_RENAME */ diff --git a/utshell-0.5.0/lib/sh/setlinebuf.c b/utshell-0.5.0/lib/sh/setlinebuf.c new file mode 100644 index 00000000..6473ddfc --- /dev/null +++ b/utshell-0.5.0/lib/sh/setlinebuf.c @@ -0,0 +1,63 @@ +/* setlinebuf.c - line-buffer a stdio stream. */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#include + +#if defined (USING_BASH_MALLOC) +# define LBUF_BUFSIZE 1008 +#else +# define LBUF_BUFSIZE BUFSIZ +#endif + +/* Cause STREAM to buffer lines as opposed to characters or blocks. */ +int +sh_setlinebuf (stream) + FILE *stream; +{ + char *local_linebuf; + +#if !defined (HAVE_SETLINEBUF) && !defined (HAVE_SETVBUF) + return (0); +#endif + +#if defined (USING_BASH_MALLOC) + local_linebuf = (char *)xmalloc (LBUF_BUFSIZE); +#else + local_linebuf = (char *)NULL; +#endif + +#if defined (HAVE_SETVBUF) + +# if defined (SETVBUF_REVERSED) + return (setvbuf (stream, _IOLBF, local_linebuf, LBUF_BUFSIZE)); +# else /* !SETVBUF_REVERSED */ + return (setvbuf (stream, local_linebuf, _IOLBF, LBUF_BUFSIZE)); +# endif /* !SETVBUF_REVERSED */ +# else /* !HAVE_SETVBUF */ + + setlinebuf (stream); + return (0); + +#endif /* !HAVE_SETVBUF */ +} diff --git a/utshell-0.5.0/lib/sh/shmatch.c b/utshell-0.5.0/lib/sh/shmatch.c new file mode 100644 index 00000000..d6e7f904 --- /dev/null +++ b/utshell-0.5.0/lib/sh/shmatch.c @@ -0,0 +1,123 @@ +/* + * shmatch.c -- shell interface to posix regular expression matching. + */ + +/* Copyright (C) 2003-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined (HAVE_POSIX_REGEXP) + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "bashansi.h" + +#include +#include + +#include "shell.h" +#include "variables.h" +#include "externs.h" + +extern int glob_ignore_case, match_ignore_case; + +int +sh_regmatch (string, pattern, flags) + const char *string; + const char *pattern; + int flags; +{ + regex_t regex = { 0 }; + regmatch_t *matches; + int rflags; +#if defined (ARRAY_VARS) + SHELL_VAR *rematch; + ARRAY *amatch; + int subexp_ind; + char *subexp_str; + int subexp_len; +#endif + int result; + +#if defined (ARRAY_VARS) + rematch = (SHELL_VAR *)NULL; +#endif + + rflags = REG_EXTENDED; + if (match_ignore_case) + rflags |= REG_ICASE; +#if !defined (ARRAY_VARS) + rflags |= REG_NOSUB; +#endif + + if (regcomp (®ex, pattern, rflags)) + return 2; /* flag for printing a warning here. */ + +#if defined (ARRAY_VARS) + matches = (regmatch_t *)malloc (sizeof (regmatch_t) * (regex.re_nsub + 1)); +#else + matches = NULL; +#endif + + /* man regexec: NULL PMATCH ignored if NMATCH == 0 */ + if (regexec (®ex, string, matches ? regex.re_nsub + 1 : 0, matches, 0)) + result = EXECUTION_FAILURE; + else + result = EXECUTION_SUCCESS; /* match */ + +#if defined (ARRAY_VARS) + subexp_len = strlen (string) + 10; + subexp_str = malloc (subexp_len + 1); + + /* Store the parenthesized subexpressions in the array BASH_REMATCH. + Element 0 is the portion that matched the entire regexp. Element 1 + is the part that matched the first subexpression, and so on. */ + unbind_variable_noref ("BASH_REMATCH"); + rematch = make_new_array_variable ("BASH_REMATCH"); + amatch = array_cell (rematch); + + if (matches && (flags & SHMAT_SUBEXP) && result == EXECUTION_SUCCESS && subexp_str) + { + for (subexp_ind = 0; subexp_ind <= regex.re_nsub; subexp_ind++) + { + memset (subexp_str, 0, subexp_len); + strncpy (subexp_str, string + matches[subexp_ind].rm_so, + matches[subexp_ind].rm_eo - matches[subexp_ind].rm_so); + array_insert (amatch, subexp_ind, subexp_str); + } + } + +#if 0 + VSETATTR (rematch, att_readonly); +#endif + + free (subexp_str); + free (matches); +#endif /* ARRAY_VARS */ + + regfree (®ex); + + return result; +} + +#endif /* HAVE_POSIX_REGEXP */ diff --git a/utshell-0.5.0/lib/sh/shmbchar.c b/utshell-0.5.0/lib/sh/shmbchar.c new file mode 100644 index 00000000..f2f2582b --- /dev/null +++ b/utshell-0.5.0/lib/sh/shmbchar.c @@ -0,0 +1,137 @@ +/* Copyright (C) 2001, 2006, 2009, 2010, 2012, 2015-2018 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + +#include + +#if defined (HANDLE_MULTIBYTE) +#include +#include + +#include + +#include +#include + +#ifndef errno +extern int errno; +#endif + +#if IS_BASIC_ASCII + +/* Bit table of characters in the ISO C "basic character set". */ +const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] = +{ + 0x00001a00, /* '\t' '\v' '\f' */ + 0xffffffef, /* ' '...'#' '%'...'?' */ + 0xfffffffe, /* 'A'...'Z' '[' '\\' ']' '^' '_' */ + 0x7ffffffe /* 'a'...'z' '{' '|' '}' '~' */ + /* The remaining bits are 0. */ +}; + +#endif /* IS_BASIC_ASCII */ + +extern int locale_utf8locale; + +extern char *utf8_mbsmbchar (const char *); +extern int utf8_mblen (const char *, size_t); + +/* Count the number of characters in S, counting multi-byte characters as a + single character. */ +size_t +mbstrlen (s) + const char *s; +{ + size_t clen, nc; + mbstate_t mbs = { 0 }, mbsbak = { 0 }; + int f, mb_cur_max; + + nc = 0; + mb_cur_max = MB_CUR_MAX; + while (*s && (clen = (f = is_basic (*s)) ? 1 : mbrlen(s, mb_cur_max, &mbs)) != 0) + { + if (MB_INVALIDCH(clen)) + { + clen = 1; /* assume single byte */ + mbs = mbsbak; + } + + if (f == 0) + mbsbak = mbs; + + s += clen; + nc++; + } + return nc; +} + +/* Return pointer to first multibyte char in S, or NULL if none. */ +/* XXX - if we know that the locale is UTF-8, we can just check whether or + not any byte has the eighth bit turned on */ +char * +mbsmbchar (s) + const char *s; +{ + char *t; + size_t clen; + mbstate_t mbs = { 0 }; + int mb_cur_max; + + if (locale_utf8locale) + return (utf8_mbsmbchar (s)); /* XXX */ + + mb_cur_max = MB_CUR_MAX; + for (t = (char *)s; *t; t++) + { + if (is_basic (*t)) + continue; + + if (locale_utf8locale) /* not used if above code active */ + clen = utf8_mblen (t, mb_cur_max); + else + clen = mbrlen (t, mb_cur_max, &mbs); + + if (clen == 0) + return 0; + if (MB_INVALIDCH(clen)) + continue; + + if (clen > 1) + return t; + } + return 0; +} + +int +sh_mbsnlen(src, srclen, maxlen) + const char *src; + size_t srclen; + int maxlen; +{ + int count; + int sind; + DECLARE_MBSTATE; + + for (sind = count = 0; src[sind]; ) + { + count++; /* number of multibyte characters */ + ADVANCE_CHAR (src, srclen, sind); + if (sind > maxlen) + break; + } + + return count; +} +#endif diff --git a/utshell-0.5.0/lib/sh/shquote.c b/utshell-0.5.0/lib/sh/shquote.c new file mode 100644 index 00000000..e7208dae --- /dev/null +++ b/utshell-0.5.0/lib/sh/shquote.c @@ -0,0 +1,434 @@ +/* shquote - functions to quote and dequote strings */ + +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include + +#include "syntax.h" +#include + +#include "shmbchar.h" +#include "shmbutil.h" + +extern char *ansic_quote PARAMS((char *, int, int *)); +extern int ansic_shouldquote PARAMS((const char *)); + +/* Default set of characters that should be backslash-quoted in strings */ +static const char bstab[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, /* TAB, NL */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 1, 1, 1, 0, 1, 0, 1, 1, /* SPACE, !, DQUOTE, DOL, AMP, SQUOTE */ + 1, 1, 1, 0, 1, 0, 0, 0, /* LPAR, RPAR, STAR, COMMA */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 1, 1, /* SEMI, LESSTHAN, GREATERTHAN, QUEST */ + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, /* LBRACK, BS, RBRACK, CARAT */ + + 1, 0, 0, 0, 0, 0, 0, 0, /* BACKQ */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, /* LBRACE, BAR, RBRACE */ + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + +/* **************************************************************** */ +/* */ +/* Functions for quoting strings to be re-read as input */ +/* */ +/* **************************************************************** */ + +/* Return a new string which is the single-quoted version of STRING. + Used by alias and trap, among others. */ + +/* +char *sh_single_quote (string) + const char *string; +{ + register int c; + char *result, *r; + const char *s; + + result = (char *)xmalloc (3 + (4 * strlen (string))); + r = result; + + if (string[0] == '\'' && string[1] == 0) + { + *r++ = '\\'; + *r++ = '\''; + *r++ = 0; + return result; + } + + *r++ = '\''; + + for (s = string; s && (c = *s); s++) + { + *r++ = c; + + if (c == '\'') + { + *r++ = '\\'; + *r++ = '\''; + *r++ = '\''; + } + } + + *r++ = '\''; + *r = '\0'; + + return (result); +} +*/ + + +/* Quote STRING using double quotes. Return a new string. */ +char * +sh_double_quote (string) + const char *string; +{ + register unsigned char c; + int mb_cur_max; + char *result, *r; + size_t slen; + const char *s, *send; + DECLARE_MBSTATE; + + slen = strlen (string); + send = string + slen; + mb_cur_max = MB_CUR_MAX; + + result = (char *)xmalloc (3 + (2 * strlen (string))); + r = result; + *r++ = '"'; + + for (s = string; s && (c = *s); s++) + { + /* Backslash-newline disappears within double quotes, so don't add one. */ + if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n') + *r++ = '\\'; + +#if defined (HANDLE_MULTIBYTE) + if ((locale_utf8locale && (c & 0x80)) || + (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)) + { + COPY_CHAR_P (r, s, send); + s--; /* compensate for auto-increment in loop above */ + continue; + } +#endif + + /* Assume that the string will not be further expanded, so no need to + add CTLESC to protect CTLESC or CTLNUL. */ + *r++ = c; + } + + *r++ = '"'; + *r = '\0'; + + return (result); +} + +/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote + double quote characters in S with backslashes. */ +char * +sh_mkdoublequoted (s, slen, flags) + const char *s; + int slen, flags; +{ + char *r, *ret; + const char *send; + int rlen, mb_cur_max; + DECLARE_MBSTATE; + + send = s + slen; + mb_cur_max = flags ? MB_CUR_MAX : 1; + rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1; + ret = r = (char *)xmalloc (rlen); + + *r++ = '"'; + while (*s) + { + if (flags && *s == '"') + *r++ = '\\'; + +#if defined (HANDLE_MULTIBYTE) + if (flags && ((locale_utf8locale && (*s & 0x80)) || + (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (*s) == 0))) + { + COPY_CHAR_P (r, s, send); + continue; + } +#endif + *r++ = *s++; + } + *r++ = '"'; + *r = '\0'; + + return ret; +} + +/* Remove backslashes that are quoting characters that are special between + double quotes. Return a new string. XXX - should this handle CTLESC + and CTLNUL? */ +char * +sh_un_double_quote (string) + char *string; +{ + register int c, pass_next; + char *result, *r, *s; + + r = result = (char *)xmalloc (strlen (string) + 1); + + for (pass_next = 0, s = string; s && (c = *s); s++) + { + if (pass_next) + { + *r++ = c; + pass_next = 0; + continue; + } + if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE)) + { + pass_next = 1; + continue; + } + *r++ = c; + } + + *r = '\0'; + return result; +} + +/* Quote special characters in STRING using backslashes. Return a new + string. NOTE: if the string is to be further expanded, we need a + way to protect the CTLESC and CTLNUL characters. As I write this, + the current callers will never cause the string to be expanded without + going through the shell parser, which will protect the internal + quoting characters. TABLE, if set, points to a map of the ascii code + set with char needing to be backslash-quoted if table[char]==1. FLAGS, + if 1, causes tildes to be quoted as well. If FLAGS&2, backslash-quote + other shell blank characters. */ + +char * +sh_backslash_quote (string, table, flags) + char *string; + char *table; + int flags; +{ + int c, mb_cur_max; + size_t slen; + char *result, *r, *s, *backslash_table, *send; + DECLARE_MBSTATE; + + slen = strlen (string); + send = string + slen; + result = (char *)xmalloc (2 * slen + 1); + + backslash_table = table ? table : (char *)bstab; + mb_cur_max = MB_CUR_MAX; + + for (r = result, s = string; s && (c = *s); s++) + { +#if defined (HANDLE_MULTIBYTE) + /* XXX - isascii, even if is_basic(c) == 0 - works in most cases. */ + if (c >= 0 && c <= 127 && backslash_table[(unsigned char)c] == 1) + { + *r++ = '\\'; + *r++ = c; + continue; + } + if ((locale_utf8locale && (c & 0x80)) || + (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)) + { + COPY_CHAR_P (r, s, send); + s--; /* compensate for auto-increment in loop above */ + continue; + } +#endif + if (backslash_table[(unsigned char)c] == 1) + *r++ = '\\'; + else if (c == '#' && s == string) /* comment char */ + *r++ = '\\'; + else if ((flags&1) && c == '~' && (s == string || s[-1] == ':' || s[-1] == '=')) + /* Tildes are special at the start of a word or after a `:' or `=' + (technically unquoted, but it doesn't make a difference in practice) */ + *r++ = '\\'; + else if ((flags&2) && shellblank((unsigned char)c)) + *r++ = '\\'; + *r++ = c; + } + + *r = '\0'; + return (result); +} + +#if defined (PROMPT_STRING_DECODE) +/* Quote characters that get special treatment when in double quotes in STRING + using backslashes. Return a new string. */ +char * +sh_backslash_quote_for_double_quotes (string) + char *string; +{ + unsigned char c; + char *result, *r, *s, *send; + size_t slen; + int mb_cur_max; + DECLARE_MBSTATE; + + slen = strlen (string); + send = string + slen; + mb_cur_max = MB_CUR_MAX; + result = (char *)xmalloc (2 * slen + 1); + + for (r = result, s = string; s && (c = *s); s++) + { + /* Backslash-newline disappears within double quotes, so don't add one. */ + if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n') + *r++ = '\\'; + /* I should probably use the CSPECL flag for these in sh_syntaxtab[] */ + else if (c == CTLESC || c == CTLNUL) + *r++ = CTLESC; /* could be '\\'? */ + +#if defined (HANDLE_MULTIBYTE) + if ((locale_utf8locale && (c & 0x80)) || + (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)) + { + COPY_CHAR_P (r, s, send); + s--; /* compensate for auto-increment in loop above */ + continue; + } +#endif + + *r++ = c; + } + + *r = '\0'; + return (result); +} +#endif /* PROMPT_STRING_DECODE */ + +char * +sh_quote_reusable (s, flags) + char *s; + int flags; +{ + char *ret; + + if (s == 0) + return s; + else if (*s == 0) + { + ret = (char *)xmalloc (3); + ret[0] = ret[1] = '\''; + ret[2] = '\0'; + } + else if (ansic_shouldquote (s)) + ret = ansic_quote (s, 0, (int *)0); + else if (flags) + ret = sh_backslash_quote (s, 0, 1); + else + ret = sh_single_quote (s); + + return ret; +} + +int +sh_contains_shell_metas (string) + const char *string; +{ + const char *s; + + for (s = string; s && *s; s++) + { + switch (*s) + { + case ' ': case '\t': case '\n': /* IFS white space */ + case '\'': case '"': case '\\': /* quoting chars */ + case '|': case '&': case ';': /* shell metacharacters */ + case '(': case ')': case '<': case '>': + case '!': case '{': case '}': /* reserved words */ + case '*': case '[': case '?': case ']': /* globbing chars */ + case '^': + case '$': case '`': /* expansion chars */ + return (1); + case '~': /* tilde expansion */ + if (s == string || s[-1] == '=' || s[-1] == ':') + return (1); + break; + case '#': + if (s == string) /* comment char */ + return (1); + /* FALLTHROUGH */ + default: + break; + } + } + + return (0); +} + +int +sh_contains_quotes (string) + const char *string; +{ + const char *s; + + for (s = string; s && *s; s++) + { + if (*s == '\'' || *s == '"' || *s == '\\') + return 1; + } + return 0; +} diff --git a/utshell-0.5.0/lib/sh/shtty.c b/utshell-0.5.0/lib/sh/shtty.c new file mode 100644 index 00000000..0433f5e2 --- /dev/null +++ b/utshell-0.5.0/lib/sh/shtty.c @@ -0,0 +1,330 @@ +/* + * shtty.c -- abstract interface to the terminal, focusing on capabilities. + */ + +/* Copyright (C) 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include + +static TTYSTRUCT ttin, ttout; +static int ttsaved = 0; + +int +ttgetattr(fd, ttp) +int fd; +TTYSTRUCT *ttp; +{ +#ifdef TERMIOS_TTY_DRIVER + return tcgetattr(fd, ttp); +#else +# ifdef TERMIO_TTY_DRIVER + return ioctl(fd, TCGETA, ttp); +# else + return ioctl(fd, TIOCGETP, ttp); +# endif +#endif +} + +int +ttsetattr(fd, ttp) +int fd; +TTYSTRUCT *ttp; +{ +#ifdef TERMIOS_TTY_DRIVER + return tcsetattr(fd, TCSADRAIN, ttp); +#else +# ifdef TERMIO_TTY_DRIVER + return ioctl(fd, TCSETAW, ttp); +# else + return ioctl(fd, TIOCSETN, ttp); +# endif +#endif +} + +void +ttsave() +{ + if (ttsaved) + return; + ttgetattr (0, &ttin); + ttgetattr (1, &ttout); + ttsaved = 1; +} + +void +ttrestore() +{ + if (ttsaved == 0) + return; + ttsetattr (0, &ttin); + ttsetattr (1, &ttout); + ttsaved = 0; +} + +/* Retrieve the internally-saved attributes associated with tty fd FD. */ +TTYSTRUCT * +ttattr (fd) + int fd; +{ + if (ttsaved == 0) + return ((TTYSTRUCT *)0); + if (fd == 0) + return &ttin; + else if (fd == 1) + return &ttout; + else + return ((TTYSTRUCT *)0); +} + +/* + * Change attributes in ttp so that when it is installed using + * ttsetattr, the terminal will be in one-char-at-a-time mode. + */ +int +tt_setonechar(ttp) + TTYSTRUCT *ttp; +{ +#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) + + /* XXX - might not want this -- it disables erase and kill processing. */ + ttp->c_lflag &= ~ICANON; + + ttp->c_lflag |= ISIG; +# ifdef IEXTEN + ttp->c_lflag |= IEXTEN; +# endif + + ttp->c_iflag |= ICRNL; /* make sure we get CR->NL on input */ + ttp->c_iflag &= ~INLCR; /* but no NL->CR */ + +# ifdef OPOST + ttp->c_oflag |= OPOST; +# endif +# ifdef ONLCR + ttp->c_oflag |= ONLCR; +# endif +# ifdef OCRNL + ttp->c_oflag &= ~OCRNL; +# endif +# ifdef ONOCR + ttp->c_oflag &= ~ONOCR; +# endif +# ifdef ONLRET + ttp->c_oflag &= ~ONLRET; +# endif + + ttp->c_cc[VMIN] = 1; + ttp->c_cc[VTIME] = 0; + +#else + + ttp->sg_flags |= CBREAK; + +#endif + + return 0; +} + +/* Set the tty associated with FD and TTP into one-character-at-a-time mode */ +int +ttfd_onechar (fd, ttp) + int fd; + TTYSTRUCT *ttp; +{ + if (tt_setonechar(ttp) < 0) + return -1; + return (ttsetattr (fd, ttp)); +} + +/* Set the terminal into one-character-at-a-time mode */ +int +ttonechar () +{ + TTYSTRUCT tt; + + if (ttsaved == 0) + return -1; + tt = ttin; + return (ttfd_onechar (0, &tt)); +} + +/* + * Change attributes in ttp so that when it is installed using + * ttsetattr, the terminal will be in no-echo mode. + */ +int +tt_setnoecho(ttp) + TTYSTRUCT *ttp; +{ +#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) + ttp->c_lflag &= ~(ECHO|ECHOK|ECHONL); +#else + ttp->sg_flags &= ~ECHO; +#endif + + return 0; +} + +/* Set the tty associated with FD and TTP into no-echo mode */ +int +ttfd_noecho (fd, ttp) + int fd; + TTYSTRUCT *ttp; +{ + if (tt_setnoecho (ttp) < 0) + return -1; + return (ttsetattr (fd, ttp)); +} + +/* Set the terminal into no-echo mode */ +int +ttnoecho () +{ + TTYSTRUCT tt; + + if (ttsaved == 0) + return -1; + tt = ttin; + return (ttfd_noecho (0, &tt)); +} + +/* + * Change attributes in ttp so that when it is installed using + * ttsetattr, the terminal will be in eight-bit mode (pass8). + */ +int +tt_seteightbit (ttp) + TTYSTRUCT *ttp; +{ +#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) + ttp->c_iflag &= ~ISTRIP; + ttp->c_cflag |= CS8; + ttp->c_cflag &= ~PARENB; +#else + ttp->sg_flags |= ANYP; +#endif + + return 0; +} + +/* Set the tty associated with FD and TTP into eight-bit mode */ +int +ttfd_eightbit (fd, ttp) + int fd; + TTYSTRUCT *ttp; +{ + if (tt_seteightbit (ttp) < 0) + return -1; + return (ttsetattr (fd, ttp)); +} + +/* Set the terminal into eight-bit mode */ +int +tteightbit () +{ + TTYSTRUCT tt; + + if (ttsaved == 0) + return -1; + tt = ttin; + return (ttfd_eightbit (0, &tt)); +} + +/* + * Change attributes in ttp so that when it is installed using + * ttsetattr, the terminal will be in non-canonical input mode. + */ +int +tt_setnocanon (ttp) + TTYSTRUCT *ttp; +{ +#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) + ttp->c_lflag &= ~ICANON; +#endif + + return 0; +} + +/* Set the tty associated with FD and TTP into non-canonical mode */ +int +ttfd_nocanon (fd, ttp) + int fd; + TTYSTRUCT *ttp; +{ + if (tt_setnocanon (ttp) < 0) + return -1; + return (ttsetattr (fd, ttp)); +} + +/* Set the terminal into non-canonical mode */ +int +ttnocanon () +{ + TTYSTRUCT tt; + + if (ttsaved == 0) + return -1; + tt = ttin; + return (ttfd_nocanon (0, &tt)); +} + +/* + * Change attributes in ttp so that when it is installed using + * ttsetattr, the terminal will be in cbreak, no-echo mode. + */ +int +tt_setcbreak(ttp) + TTYSTRUCT *ttp; +{ + if (tt_setonechar (ttp) < 0) + return -1; + return (tt_setnoecho (ttp)); +} + +/* Set the tty associated with FD and TTP into cbreak (no-echo, + one-character-at-a-time) mode */ +int +ttfd_cbreak (fd, ttp) + int fd; + TTYSTRUCT *ttp; +{ + if (tt_setcbreak (ttp) < 0) + return -1; + return (ttsetattr (fd, ttp)); +} + +/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */ +int +ttcbreak () +{ + TTYSTRUCT tt; + + if (ttsaved == 0) + return -1; + tt = ttin; + return (ttfd_cbreak (0, &tt)); +} diff --git a/utshell-0.5.0/lib/sh/snprintf.c b/utshell-0.5.0/lib/sh/snprintf.c new file mode 100644 index 00000000..406a3a50 --- /dev/null +++ b/utshell-0.5.0/lib/sh/snprintf.c @@ -0,0 +1,2221 @@ +/* snprintf - formatted output to strings, with bounds checking and allocation */ + +/* + build a test version with + gcc -g -DDRIVER -I../.. -I../../include -o test-snprintf snprintf.c fmtu*long.o +*/ + +/* + Unix snprintf implementation. + derived from inetutils/libinetutils/snprintf.c Version 1.1 + + Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . + + Original (pre-bash) Revision History: + + 1.1: + * added changes from Miles Bader + * corrected a bug with %f + * added support for %#g + * added more comments :-) + 1.0: + * supporting must ANSI syntaxic_sugars + 0.0: + * support %s %c %d + + THANKS(for the patches and ideas): + Miles Bader + Cyrille Rustom + Jacek Slabocewiz + Mike Parker(mouse) + +*/ + +/* + * Currently doesn't handle (and bash/readline doesn't use): + * * *M$ width, precision specifications + * * %N$ numbered argument conversions + * * support for `F' is imperfect with ldfallback(), since underlying + * printf may not handle it -- should ideally have another autoconf test + */ + +#define FLOATING_POINT + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* GCC 4.2 on Snow Leopard doesn't like the snprintf prototype */ +#if defined(DEBUG) && !defined (MACOSX) +# undef HAVE_SNPRINTF +# undef HAVE_ASPRINTF + +# define HAVE_SNPRINTF 0 +# define HAVE_ASPRINTF 0 +#endif + +#if defined(DRIVER) && !defined(HAVE_CONFIG_H) +#define HAVE_LONG_LONG +#define HAVE_LONG_DOUBLE +#ifdef __linux__ +#define HAVE_PRINTF_A_FORMAT +#endif +#define HAVE_ISINF_IN_LIBC +#define HAVE_ISNAN_IN_LIBC +#define PREFER_STDARG +#define HAVE_STRINGIZE +#define HAVE_LIMITS_H +#define HAVE_STDDEF_H +#define HAVE_LOCALE_H +#define intmax_t long +#endif + +#if !HAVE_SNPRINTF || !HAVE_ASPRINTF + +#include + +#if defined(PREFER_STDARG) +# include +#else +# include +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif +#include +#ifdef HAVE_STDDEF_H +# include +#endif +#include + +#ifdef HAVE_STDINT_H +# include +#endif + +#ifdef FLOATING_POINT +# include /* for manifest constants */ +# include /* for sprintf */ +#endif + +#include + +#ifdef HAVE_LOCALE_H +# include +#endif + +#include "stdc.h" +#include + +#ifndef DRIVER +# include "shell.h" +#else +# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ +# define FL_ADDBASE 0x02 /* add base# prefix to converted value */ +# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ +# define FL_UNSIGNED 0x08 /* don't add any sign */ +extern char *fmtulong PARAMS((unsigned long int, int, char *, size_t, int)); +extern char *fmtullong PARAMS((unsigned long long int, int, char *, size_t, int)); +#endif + +#ifndef FREE +# define FREE(x) if (x) free (x) +#endif + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#ifndef INT_STRLEN_BOUND +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) +#endif + +/* conversion flags */ +#define PF_ALTFORM 0x00001 /* # */ +#define PF_HEXPREFIX 0x00002 /* 0[Xx] */ +#define PF_LADJUST 0x00004 /* - */ +#define PF_ZEROPAD 0x00008 /* 0 */ +#define PF_PLUS 0x00010 /* + */ +#define PF_SPACE 0x00020 /* ' ' */ +#define PF_THOUSANDS 0x00040 /* ' */ + +#define PF_DOT 0x00080 /* `.precision' */ +#define PF_STAR_P 0x00100 /* `*' after precision */ +#define PF_STAR_W 0x00200 /* `*' before or without precision */ + +/* length modifiers */ +#define PF_SIGNEDCHAR 0x00400 /* hh */ +#define PF_SHORTINT 0x00800 /* h */ +#define PF_LONGINT 0x01000 /* l */ +#define PF_LONGLONG 0x02000 /* ll */ +#define PF_LONGDBL 0x04000 /* L */ +#define PF_INTMAX_T 0x08000 /* j */ +#define PF_SIZE_T 0x10000 /* z */ +#define PF_PTRDIFF_T 0x20000 /* t */ + +#define PF_ALLOCBUF 0x40000 /* for asprintf, vasprintf */ + +#define PFM_SN 0x01 /* snprintf, vsnprintf */ +#define PFM_AS 0x02 /* asprintf, vasprintf */ + +#define ASBUFSIZE 128 + +#define x_digs "0123456789abcdef" +#define X_digs "0123456789ABCDEF" + +static char intbuf[INT_STRLEN_BOUND(unsigned long) + 1]; + +static int decpoint; +static int thoussep; +static char *grouping; + +/* + * For the FLOATING POINT FORMAT : + * the challenge was finding a way to + * manipulate the Real numbers without having + * to resort to mathematical function(it + * would require to link with -lm) and not + * going down to the bit pattern(not portable) + * + * so a number, a real is: + + real = integral + fraction + + integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0 + fraction = b(1)*10^-1 + b(2)*10^-2 + ... + + where: + 0 <= a(i) => 9 + 0 <= b(i) => 9 + + from then it was simple math + */ + +/* + * size of the buffer for the integral part + * and the fraction part + */ +#define MAX_INT 99 + 1 /* 1 for the null */ +#define MAX_FRACT 307 + 1 + +/* + * These functions use static buffers to store the results, + * and so are not reentrant + */ +#define itoa(n) fmtulong(n, 10, intbuf, sizeof(intbuf), 0); +#define dtoa(n, p, f) numtoa(n, 10, p, f) + +#define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;} + +#define GETARG(type) (va_arg(args, type)) + +/* Macros that do proper sign extension and handle length modifiers. Used + for the integer conversion specifiers. */ +#define GETSIGNED(p) \ + (((p)->flags & PF_LONGINT) \ + ? GETARG (long) \ + : (((p)->flags & PF_SHORTINT) ? (long)(short)GETARG (int) \ + : (long)GETARG (int))) + +#define GETUNSIGNED(p) \ + (((p)->flags & PF_LONGINT) \ + ? GETARG (unsigned long) \ + : (((p)->flags & PF_SHORTINT) ? (unsigned long)(unsigned short)GETARG (int) \ + : (unsigned long)GETARG (unsigned int))) + + +#ifdef HAVE_LONG_DOUBLE +#define GETLDOUBLE(p) GETARG (long double) +#endif +#define GETDOUBLE(p) GETARG (double) + +#define SET_SIZE_FLAGS(p, type) \ + if (sizeof (type) > sizeof (int)) \ + (p)->flags |= PF_LONGINT; \ + if (sizeof (type) > sizeof (long)) \ + (p)->flags |= PF_LONGLONG; + +/* this struct holds everything we need */ +struct DATA +{ + int length; + char *base; /* needed for [v]asprintf */ + char *holder; + int counter; + const char *pf; + +/* FLAGS */ + int flags; + int justify; + int width, precision; + char pad; +}; + +/* the floating point stuff */ +#ifdef FLOATING_POINT +static double pow_10 PARAMS((int)); +static int log_10 PARAMS((double)); +static double integral PARAMS((double, double *)); +static char *numtoa PARAMS((double, int, int, char **)); +#endif + +static void init_data PARAMS((struct DATA *, char *, size_t, const char *, int)); +static void init_conv_flag PARAMS((struct DATA *)); + +/* for the format */ +#ifdef FLOATING_POINT +static void floating PARAMS((struct DATA *, double)); +static void exponent PARAMS((struct DATA *, double)); +#endif +static void number PARAMS((struct DATA *, unsigned long, int)); +#ifdef HAVE_LONG_LONG +static void lnumber PARAMS((struct DATA *, unsigned long long, int)); +#endif +static void pointer PARAMS((struct DATA *, unsigned long)); +static void strings PARAMS((struct DATA *, char *)); + +#ifdef FLOATING_POINT +# define FALLBACK_FMTSIZE 32 +# define FALLBACK_BASE 4096 +# define LFALLBACK_BASE 5120 +# ifdef HAVE_LONG_DOUBLE +static void ldfallback PARAMS((struct DATA *, const char *, const char *, long double)); +# endif +static void dfallback PARAMS((struct DATA *, const char *, const char *, double)); +#endif + +static char *groupnum PARAMS((char *)); + +#if defined (HAVE_LONG_DOUBLE) +# define LONGDOUBLE long double +#else +# define LONGDOUBLE double +#endif + +#ifndef isnan + static inline int isnan_f (float x) { return x != x; } + static inline int isnan_d (double x) { return x != x; } + static inline int isnan_ld (LONGDOUBLE x) { return x != x; } + # define isnan(x) \ + (sizeof (x) == sizeof (LONGDOUBLE) ? isnan_ld (x) \ + : sizeof (x) == sizeof (double) ? isnan_d (x) \ + : isnan_f (x)) +#endif + +#ifndef isinf + static inline int isinf_f (float x) { return !isnan (x) && isnan (x - x); } + static inline int isinf_d (double x) { return !isnan (x) && isnan (x - x); } + static inline int isinf_ld (LONGDOUBLE x) { return !isnan (x) && isnan (x - x); } + # define isinf(x) \ + (sizeof (x) == sizeof (LONGDOUBLE) ? isinf_ld (x) \ + : sizeof (x) == sizeof (double) ? isinf_d (x) \ + : isinf_f (x)) +#endif + +#ifdef DRIVER +static void memory_error_and_abort (); +static void *xmalloc PARAMS((size_t)); +static void *xrealloc PARAMS((void *, size_t)); +static void xfree PARAMS((void *)); +#else +# include +#endif + +/* those are defines specific to snprintf to hopefully + * make the code clearer :-) + */ +#define RIGHT 1 +#define LEFT 0 +#define NOT_FOUND -1 +#define FOUND 1 +#define MAX_FIELD 15 + +/* round off to the precision */ +#define ROUND(d, p) \ + (d < 0.) ? \ + d - pow_10(-(p)->precision) * 0.5 : \ + d + pow_10(-(p)->precision) * 0.5 + +/* set default precision */ +#define DEF_PREC(p) \ + if ((p)->precision == NOT_FOUND) \ + (p)->precision = 6 + +/* put a char. increment the number of chars written even if we've exceeded + the vsnprintf/snprintf buffer size (for the return value) */ +#define PUT_CHAR(c, p) \ + do \ + { \ + if (((p)->flags & PF_ALLOCBUF) && ((p)->counter >= (p)->length - 1)) \ + { \ + (p)->length += ASBUFSIZE; \ + (p)->base = (char *)xrealloc((p)->base, (p)->length); \ + (p)->holder = (p)->base + (p)->counter; /* in case reallocated */ \ + } \ + if ((p)->counter < (p)->length) \ + *(p)->holder++ = (c); \ + (p)->counter++; \ + } \ + while (0) + +/* Output a string. P->WIDTH has already been adjusted for padding. */ +#define PUT_STRING(string, len, p) \ + do \ + { \ + PAD_RIGHT (p); \ + while ((len)-- > 0) \ + { \ + PUT_CHAR (*(string), (p)); \ + (string)++; \ + } \ + PAD_LEFT (p); \ + } \ + while (0) + +#define PUT_PLUS(d, p, zero) \ + if (((p)->flags & PF_PLUS) && (d) > zero) \ + PUT_CHAR('+', p) + +#define PUT_SPACE(d, p, zero) \ + if (((p)->flags & PF_SPACE) && (d) > zero) \ + PUT_CHAR(' ', p) + +/* pad right */ +#define PAD_RIGHT(p) \ + if ((p)->width > 0 && (p)->justify != LEFT) \ + for (; (p)->width > 0; (p)->width--) \ + PUT_CHAR((p)->pad, p) + +/* pad left */ +#define PAD_LEFT(p) \ + if ((p)->width > 0 && (p)->justify == LEFT) \ + for (; (p)->width > 0; (p)->width--) \ + PUT_CHAR((p)->pad, p) + +/* pad with zeros from decimal precision */ +#define PAD_ZERO(p) \ + if ((p)->precision > 0) \ + for (; (p)->precision > 0; (p)->precision--) \ + PUT_CHAR('0', p) + +/* if width and prec. in the args */ +#define STAR_ARGS(p) \ + do { \ + if ((p)->flags & PF_STAR_W) \ + { \ + (p)->width = GETARG (int); \ + if ((p)->width < 0) \ + { \ + (p)->flags |= PF_LADJUST; \ + (p)->justify = LEFT; \ + (p)->width = -(p)->width; \ + } \ + } \ + if ((p)->flags & PF_STAR_P) \ + { \ + (p)->precision = GETARG (int); \ + if ((p)->precision < 0) \ + { \ + (p)->flags &= ~PF_STAR_P; \ + (p)->precision = NOT_FOUND; \ + } \ + } \ + } while (0) + +#if defined (HAVE_LOCALE_H) && defined (HAVE_LOCALECONV) +# define GETLOCALEDATA(d, t, g) \ + do \ + { \ + struct lconv *lv; \ + if ((d) == 0) { \ + (d) = '.'; (t) = -1; (g) = 0; /* defaults */ \ + lv = localeconv(); \ + if (lv) \ + { \ + if (lv->decimal_point && lv->decimal_point[0]) \ + (d) = lv->decimal_point[0]; \ + if (lv->thousands_sep && lv->thousands_sep[0]) \ + (t) = lv->thousands_sep[0]; \ + (g) = lv->grouping ? lv->grouping : ""; \ + if (*(g) == '\0' || *(g) == CHAR_MAX || (t) == -1) (g) = 0; \ + } \ + } \ + } \ + while (0); +#else +# define GETLOCALEDATA(d, t, g) \ + ( (d) = '.', (t) = ',', g = "\003" ) +#endif + +#ifdef FLOATING_POINT +/* + * Find the nth power of 10 + */ +static double +pow_10(n) + int n; +{ + double P; + + /* handle common cases with fast switch statement. */ + switch (n) + { + case -3: return .001; + case -2: return .01; + case -1: return .1; + case 0: return 1.; + case 1: return 10.; + case 2: return 100.; + case 3: return 1000.; + } + + if (n < 0) + { + P = .0001; + for (n += 4; n < 0; n++) + P /= 10.; + } + else + { + P = 10000.; + for (n -= 4; n > 0; n--) + P *= 10.; + } + + return P; +} + +/* + * Find the integral part of the log in base 10 + * Note: this not a real log10() + I just need and approximation(integerpart) of x in: + 10^x ~= r + * log_10(200) = 2; + * log_10(250) = 2; + * + * NOTE: do not call this with r == 0 -- an infinite loop results. + */ +static int +log_10(r) + double r; +{ + int i = 0; + double result = 1.; + + if (r < 0.) + r = -r; + + if (r < 1.) + { + while (result >= r) + { + result /= 10.; + i++; + } + return (-i); + } + else + { + while (result <= r) + { + result *= 10.; + i++; + } + return (i - 1); + } +} + +/* + * This function return the fraction part of a double + * and set in ip the integral part. + * In many ways it resemble the modf() found on most Un*x + */ +static double +integral(real, ip) + double real; + double *ip; +{ + int j; + double i, s, p; + double real_integral = 0.; + + /* take care of the obvious */ + /* equal to zero ? */ + if (real == 0.) + { + *ip = 0.; + return (0.); + } + + /* negative number ? */ + if (real < 0.) + real = -real; + + /* a fraction ? */ + if ( real < 1.) + { + *ip = 0.; + return real; + } + + /* the real work :-) */ + for (j = log_10(real); j >= 0; j--) + { + p = pow_10(j); + s = (real - real_integral)/p; + i = 0.; + while (i + 1. <= s) + i++; + real_integral += i*p; + } + *ip = real_integral; + return (real - real_integral); +} + +#define PRECISION 1.e-6 +/* + * return an ascii representation of the integral part of the number + * and set fract to be an ascii representation of the fraction part + * the container for the fraction and the integral part or statically + * declare with fix size + */ +static char * +numtoa(number, base, precision, fract) + double number; + int base, precision; + char **fract; +{ + register int i, j; + double ip, fp; /* integer and fraction part */ + double fraction; + int digits, sign; + static char integral_part[MAX_INT]; + static char fraction_part[MAX_FRACT]; + int ch; + + /* taking care of the obvious case: 0.0 */ + if (number == 0.) + { + integral_part[0] = '0'; + integral_part[1] = '\0'; + /* The fractional part has to take the precision into account */ + for (ch = 0; ch < precision-1; ch++) + fraction_part[ch] = '0'; + fraction_part[ch] = '0'; + fraction_part[ch+1] = '\0'; + if (fract) + *fract = fraction_part; + return integral_part; + } + + /* -0 is tricky */ + sign = (number == -0.) ? '-' : ((number < 0.) ? '-' : '+'); + digits = MAX_INT - 1; + + /* for negative numbers */ + if (sign == '-') + { + number = -number; + digits--; /* sign consume one digit */ + } + + fraction = integral(number, &ip); + number = ip; + + /* do the integral part */ + if (ip == 0.) + { + integral_part[0] = '0'; + i = 1; + } + else + { + for ( i = 0; i < digits && number != 0.; ++i) + { + number /= base; + fp = integral(number, &ip); + ch = (int)((fp + PRECISION)*base); /* force to round */ + integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10; + if (! ISXDIGIT((unsigned char)integral_part[i])) + break; /* bail out overflow !! */ + number = ip; + } + } + + /* Oh No !! out of bound, ho well fill it up ! */ + if (number != 0.) + for (i = 0; i < digits; ++i) + integral_part[i] = '9'; + + /* put the sign ? */ + if (sign == '-') + integral_part[i++] = '-'; + + integral_part[i] = '\0'; + + /* reverse every thing */ + for ( i--, j = 0; j < i; j++, i--) + SWAP_INT(integral_part[i], integral_part[j]); + + /* the fractional part */ + for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--) + { + fraction_part[i] = (int)((fp + PRECISION)*10. + '0'); + if (! DIGIT(fraction_part[i])) /* underflow ? */ + break; + fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.); + } + fraction_part[i] = '\0'; + + if (fract != (char **)0) + *fract = fraction_part; + + return integral_part; +} +#endif + +/* for %d and friends, it puts in holder + * the representation with the right padding + */ +static void +number(p, d, base) + struct DATA *p; + unsigned long d; + int base; +{ + char *tmp, *t; + long sd; + int flags; + + /* An explicit precision turns off the zero-padding flag and sets the + pad character back to space. */ + if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) + { + p->flags &= ~PF_ZEROPAD; + p->pad = ' '; + } + + sd = d; /* signed for ' ' padding in base 10 */ + flags = 0; + flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; + if (*p->pf == 'X') + flags |= FL_HEXUPPER; + + tmp = fmtulong (d, base, intbuf, sizeof(intbuf), flags); + t = 0; + if ((p->flags & PF_THOUSANDS)) + { + GETLOCALEDATA(decpoint, thoussep, grouping); + if (grouping && (t = groupnum (tmp))) + tmp = t; + } + + /* need to add one for any `+', but we only add one in base 10 */ + p->width -= strlen(tmp) + (base == 10 && d > 0 && (p->flags & PF_PLUS)); + PAD_RIGHT(p); + + if ((p->flags & PF_DOT) && p->precision > 0) + { + p->precision -= strlen(tmp); + PAD_ZERO(p); + } + + switch (base) + { + case 10: + PUT_PLUS(sd, p, 0); + PUT_SPACE(sd, p, 0); + break; + case 8: + if (p->flags & PF_ALTFORM) + PUT_CHAR('0', p); + break; + case 16: + if (p->flags & PF_ALTFORM) + { + PUT_CHAR('0', p); + PUT_CHAR(*p->pf, p); + } + break; + } + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + PAD_LEFT(p); + FREE (t); +} + +#ifdef HAVE_LONG_LONG +/* + * identical to number() but works for `long long' + */ +static void +lnumber(p, d, base) + struct DATA *p; + unsigned long long d; + int base; +{ + char *tmp, *t; + long long sd; + int flags; + + /* An explicit precision turns off the zero-padding flag and sets the + pad character back to space. */ + if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) + { + p->flags &= ~PF_ZEROPAD; + p->pad = ' '; + } + + sd = d; /* signed for ' ' padding in base 10 */ + flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; + if (*p->pf == 'X') + flags |= FL_HEXUPPER; + + tmp = fmtullong (d, base, intbuf, sizeof(intbuf), flags); + t = 0; + if ((p->flags & PF_THOUSANDS)) + { + GETLOCALEDATA(decpoint, thoussep, grouping); + if (grouping && (t = groupnum (tmp))) + tmp = t; + } + + /* need to add one for any `+', but we only add one in base 10 */ + p->width -= strlen(tmp) + (base == 10 && d > 0 && (p->flags & PF_PLUS)); + PAD_RIGHT(p); + + if ((p->flags & PF_DOT) && p->precision > 0) + { + p->precision -= strlen(tmp); + PAD_ZERO(p); + } + + switch (base) + { + case 10: + PUT_PLUS(sd, p, 0); + PUT_SPACE(sd, p, 0); + break; + case 8: + if (p->flags & PF_ALTFORM) + PUT_CHAR('0', p); + break; + case 16: + if (p->flags & PF_ALTFORM) + { + PUT_CHAR('0', p); + PUT_CHAR(*p->pf, p); + } + break; + } + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + PAD_LEFT(p); + FREE (t); +} +#endif + +static void +pointer(p, d) + struct DATA *p; + unsigned long d; +{ + char *tmp; + + tmp = fmtulong(d, 16, intbuf, sizeof(intbuf), 0); + p->width -= strlen(tmp); + PAD_RIGHT(p); + + /* prefix '0x' for pointers */ + PUT_CHAR('0', p); + PUT_CHAR('x', p); + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + PAD_LEFT(p); +} + +/* %s strings */ +static void +strings(p, tmp) + struct DATA *p; + char *tmp; +{ + size_t len; + + len = strlen(tmp); + if (p->precision != NOT_FOUND) /* the smallest number */ + len = (len < p->precision ? len : p->precision); + p->width -= len; + + PUT_STRING (tmp, len, p); +} + +#if HANDLE_MULTIBYTE +/* %ls wide-character strings */ +static void +wstrings(p, tmp) + struct DATA *p; + wchar_t *tmp; +{ + size_t len; + mbstate_t mbs; + char *os; + const wchar_t *ws; + + memset (&mbs, '\0', sizeof (mbstate_t)); + ws = (const wchar_t *)tmp; + + os = (char *)NULL; + if (p->precision != NOT_FOUND) + { + os = (char *)xmalloc (p->precision + 1); + len = wcsrtombs (os, &ws, p->precision, &mbs); + } + else + { + len = wcsrtombs (NULL, &ws, 0, &mbs); + if (len != (size_t)-1) + { + memset (&mbs, '\0', sizeof (mbstate_t)); + os = (char *)xmalloc (len + 1); + (void)wcsrtombs (os, &ws, len + 1, &mbs); + } + } + if (len == (size_t)-1) + { + /* invalid multibyte sequence; bail now. */ + FREE (os); + return; + } + + p->width -= len; + PUT_STRING (os, len, p); + free (os); +} + +static void +wchars (p, wc) + struct DATA *p; + wint_t wc; +{ + char *lbuf, *l; + mbstate_t mbs; + size_t len; + + lbuf = (char *)malloc (MB_CUR_MAX+1); + if (lbuf == 0) + return; + memset (&mbs, '\0', sizeof (mbstate_t)); + len = wcrtomb (lbuf, wc, &mbs); + if (len == (size_t)-1) + /* conversion failed; bail now. */ + return; + p->width -= len; + l = lbuf; + PUT_STRING (l, len, p); + free (lbuf); +} +#endif /* HANDLE_MULTIBYTE */ + +#ifdef FLOATING_POINT + +/* Check for [+-]infinity and NaN. If MODE == 1, we check for Infinity, else + (mode == 2) we check for NaN. This does the necessary printing. Returns + 1 if Inf or Nan, 0 if not. */ +static int +chkinfnan(p, d, mode) + struct DATA *p; + double d; + int mode; /* == 1 for inf, == 2 for nan */ +{ + int i; + char *tmp; + char *big, *small; + + i = (mode == 1) ? isinf(d) : isnan(d); + if (i == 0) + return 0; + big = (mode == 1) ? "INF" : "NAN"; + small = (mode == 1) ? "inf" : "nan"; + + tmp = (*p->pf == 'F' || *p->pf == 'G' || *p->pf == 'E') ? big : small; + + if (i < 0) + PUT_CHAR('-', p); + + while (*tmp) + { + PUT_CHAR (*tmp, p); + tmp++; + } + + return 1; +} + +/* %f %F %g %G floating point representation */ +static void +floating(p, d) + struct DATA *p; + double d; +{ + char *tmp, *tmp2, *t; + int i; + + if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) + return; /* already printed nan or inf */ + + GETLOCALEDATA(decpoint, thoussep, grouping); + DEF_PREC(p); + d = ROUND(d, p); + tmp = dtoa(d, p->precision, &tmp2); + t = 0; + if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) + tmp = t; + + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) + { + /* smash the trailing zeros unless altform */ + for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) + tmp2[i] = '\0'; + if (tmp2[0] == '\0') + p->precision = 0; + } + + /* calculate the padding. 1 for the dot */ + p->width = p->width - + /* XXX - should this be d>0. && (p->flags & PF_PLUS) ? */ +#if 0 + ((d > 0. && p->justify == RIGHT) ? 1:0) - +#else + ((d > 0. && (p->flags & PF_PLUS)) ? 1:0) - +#endif + ((p->flags & PF_SPACE) ? 1:0) - + strlen(tmp) - p->precision - + ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */ + + if (p->pad == ' ') + { + PAD_RIGHT(p); + PUT_PLUS(d, p, 0.); + } + else + { + if (*tmp == '-') + PUT_CHAR(*tmp++, p); + PUT_PLUS(d, p, 0.); + PAD_RIGHT(p); + } + PUT_SPACE(d, p, 0.); + + while (*tmp) + { + PUT_CHAR(*tmp, p); /* the integral */ + tmp++; + } + FREE (t); + + if (p->precision != 0 || (p->flags & PF_ALTFORM)) + PUT_CHAR(decpoint, p); /* put the '.' */ + + for (; *tmp2; tmp2++) + PUT_CHAR(*tmp2, p); /* the fraction */ + + PAD_LEFT(p); +} + +/* %e %E %g %G exponent representation */ +static void +exponent(p, d) + struct DATA *p; + double d; +{ + char *tmp, *tmp2; + int j, i; + + if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) + return; /* already printed nan or inf */ + + GETLOCALEDATA(decpoint, thoussep, grouping); + DEF_PREC(p); + if (d == 0.) + j = 0; + else + { + j = log_10(d); + d = d / pow_10(j); /* get the Mantissa */ + d = ROUND(d, p); + } + tmp = dtoa(d, p->precision, &tmp2); + + /* 1 for unit, 1 for the '.', 1 for 'e|E', + * 1 for '+|-', 2 for 'exp' (but no `.' if precision == 0 */ + /* calculate how much padding need */ + p->width = p->width - + /* XXX - should this be d>0. && (p->flags & PF_PLUS) ? */ +#if 0 + ((d > 0. && p->justify == RIGHT) ? 1:0) - +#else + ((d > 0. && (p->flags & PF_PLUS)) ? 1:0) - +#endif + (p->precision != 0 || (p->flags & PF_ALTFORM)) - + ((p->flags & PF_SPACE) ? 1:0) - p->precision - 5; + + if (p->pad == ' ') + { + PAD_RIGHT(p); + PUT_PLUS(d, p, 0.); + } + else + { + if (*tmp == '-') + PUT_CHAR(*tmp++, p); + PUT_PLUS(d, p, 0.); + PAD_RIGHT(p); + } + PUT_SPACE(d, p, 0.); + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + if (p->precision != 0 || (p->flags & PF_ALTFORM)) + PUT_CHAR(decpoint, p); /* the '.' */ + + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) + /* smash the trailing zeros unless altform */ + for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) + tmp2[i] = '\0'; + + for (; *tmp2; tmp2++) + PUT_CHAR(*tmp2, p); /* the fraction */ + + /* the exponent put the 'e|E' */ + if (*p->pf == 'g' || *p->pf == 'e') + PUT_CHAR('e', p); + else + PUT_CHAR('E', p); + + /* the sign of the exp */ + if (j >= 0) + PUT_CHAR('+', p); + else + { + PUT_CHAR('-', p); + j = -j; + } + + tmp = itoa(j); + /* pad out to at least two spaces. pad with `0' if the exponent is a + single digit. */ + if (j <= 9) + PUT_CHAR('0', p); + + /* the exponent */ + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + PAD_LEFT(p); +} +#endif + +/* Return a new string with the digits in S grouped according to the locale's + grouping info and thousands separator. If no grouping should be performed, + this returns NULL; the caller needs to check for it. */ +static char * +groupnum (s) + char *s; +{ + char *se, *ret, *re, *g; + int len, slen; + + if (grouping == 0 || *grouping <= 0 || *grouping == CHAR_MAX) + return ((char *)NULL); + + /* find min grouping to size returned string */ + for (len = *grouping, g = grouping; *g; g++) + if (*g > 0 && *g < len) + len = *g; + + slen = strlen (s); + len = slen / len + 1; + ret = (char *)xmalloc (slen + len + 1); + re = ret + slen + len; + *re = '\0'; + + g = grouping; + se = s + slen; + len = *g; + + while (se > s) + { + *--re = *--se; + + /* handle `-' inserted by numtoa() and the fmtu* family here. */ + if (se > s && se[-1] == '-') + continue; + + /* begin new group. */ + if (--len == 0 && se > s) + { + *--re = thoussep; + len = *++g; /* was g++, but that uses first char twice (glibc bug, too) */ + if (*g == '\0') + len = *--g; /* use previous grouping */ + else if (*g == CHAR_MAX) + { + do + *--re = *--se; + while (se > s); + break; + } + } + } + + if (re > ret) +#ifdef HAVE_MEMMOVE + memmove (ret, re, strlen (re) + 1); +#else + strcpy (ret, re); +#endif + + return ret; +} + +/* initialize the conversion specifiers */ +static void +init_conv_flag (p) + struct DATA *p; +{ + p->flags &= PF_ALLOCBUF; /* preserve PF_ALLOCBUF flag */ + p->precision = p->width = NOT_FOUND; + p->justify = NOT_FOUND; + p->pad = ' '; +} + +static void +init_data (p, string, length, format, mode) + struct DATA *p; + char *string; + size_t length; + const char *format; + int mode; +{ + p->length = length - 1; /* leave room for '\0' */ + p->holder = p->base = string; + p->pf = format; + p->counter = 0; + p->flags = (mode == PFM_AS) ? PF_ALLOCBUF : 0; +} + +static int +#if defined (__STDC__) +vsnprintf_internal(struct DATA *data, char *string, size_t length, const char *format, va_list args) +#else +vsnprintf_internal(data, string, length, format, args) + struct DATA *data; + char *string; + size_t length; + const char *format; + va_list args; +#endif +{ + double d; /* temporary holder */ +#ifdef HAVE_LONG_DOUBLE + long double ld; /* for later */ +#endif + unsigned long ul; +#ifdef HAVE_LONG_LONG + unsigned long long ull; +#endif + int state, i, c, n; + char *s; +#if HANDLE_MULTIBYTE + wchar_t *ws; + wint_t wc; +#endif + const char *convstart; + int negprec; + + /* Sanity check, the string length must be >= 0. C99 actually says that + LENGTH can be zero here, in the case of snprintf/vsnprintf (it's never + 0 in the case of asprintf/vasprintf), and the return value is the number + of characters that would have been written. */ + if (length < 0) + return -1; + + if (format == 0) + return 0; + + /* Reset these for each call because the locale might have changed. */ + decpoint = thoussep = 0; + grouping = 0; + + negprec = 0; + for (; c = *(data->pf); data->pf++) + { + if (c != '%') + { + PUT_CHAR (c, data); + continue; + } + + convstart = data->pf; + init_conv_flag (data); /* initialise format flags */ + + state = 1; + for (state = 1; state && *data->pf; ) + { + c = *(++data->pf); + /* fmtend = data->pf */ +#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE) + if (data->flags & PF_LONGDBL) + { + switch (c) + { + case 'f': case 'F': + case 'e': case 'E': + case 'g': case 'G': +# ifdef HAVE_PRINTF_A_FORMAT + case 'a': case 'A': +# endif + STAR_ARGS (data); + ld = GETLDOUBLE (data); + ldfallback (data, convstart, data->pf, ld); + goto conv_break; + } + } +#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */ + + switch (c) + { + /* Parse format flags */ + case '\0': /* a NULL here ? ? bail out */ + *data->holder = '\0'; + return data->counter; + break; + case '#': + data->flags |= PF_ALTFORM; + continue; + case '*': + if (data->flags & PF_DOT) + data->flags |= PF_STAR_P; + else + data->flags |= PF_STAR_W; + continue; + case '-': + if ((data->flags & PF_DOT) == 0) + { + data->flags |= PF_LADJUST; + data->justify = LEFT; + } + else + negprec = 1; + continue; + case ' ': + if ((data->flags & PF_PLUS) == 0) + data->flags |= PF_SPACE; + continue; + case '+': + if ((data->flags & PF_DOT) == 0) + { + data->flags |= PF_PLUS; + if ((data->flags & PF_LADJUST) == 0) + data->justify = RIGHT; + } + continue; + case '\'': + data->flags |= PF_THOUSANDS; + continue; + + case '0': + /* If we're not specifying precision (in which case we've seen + a `.') and we're not performing left-adjustment (in which + case the `0' is ignored), a `0' is taken as the zero-padding + flag. */ + if ((data->flags & (PF_DOT|PF_LADJUST)) == 0) + { + data->flags |= PF_ZEROPAD; + data->pad = '0'; + continue; + } + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + n = 0; + do + { + n = n * 10 + TODIGIT(c); + c = *(++data->pf); + } + while (DIGIT(c)); + data->pf--; /* went too far */ + if (n < 0) + n = 0; + if (data->flags & PF_DOT) + data->precision = negprec ? NOT_FOUND : n; + else + data->width = n; + continue; + + /* optional precision */ + case '.': + data->flags |= PF_DOT; + data->precision = 0; + continue; + + /* length modifiers */ + case 'h': + data->flags |= (data->flags & PF_SHORTINT) ? PF_SIGNEDCHAR : PF_SHORTINT; + continue; + case 'l': + data->flags |= (data->flags & PF_LONGINT) ? PF_LONGLONG : PF_LONGINT; + continue; + case 'L': + data->flags |= PF_LONGDBL; + continue; + case 'q': + data->flags |= PF_LONGLONG; + continue; + case 'j': + data->flags |= PF_INTMAX_T; + SET_SIZE_FLAGS(data, intmax_t); + continue; + case 'z': + data->flags |= PF_SIZE_T; + SET_SIZE_FLAGS(data, size_t); + continue; + case 't': + data->flags |= PF_PTRDIFF_T; + SET_SIZE_FLAGS(data, ptrdiff_t); + continue; + + /* Conversion specifiers */ +#ifdef FLOATING_POINT + case 'f': /* float, double */ + case 'F': + STAR_ARGS(data); + d = GETDOUBLE(data); + floating(data, d); +conv_break: + state = 0; + break; + case 'g': + case 'G': + STAR_ARGS(data); + DEF_PREC(data); + d = GETDOUBLE(data); + i = (d != 0.) ? log_10(d) : -1; + /* + * for '%g|%G' ANSI: use f if exponent + * is in the range or [-4,p] exclusively + * else use %e|%E + */ + if (-4 < i && i < data->precision) + { + /* reset precision */ + data->precision -= i + 1; + floating(data, d); + } + else + { + /* reduce precision by 1 because of leading digit before + decimal point in e format, unless specified as 0. */ + if (data->precision > 0) + data->precision--; + exponent(data, d); + } + state = 0; + break; + case 'e': + case 'E': /* Exponent double */ + STAR_ARGS(data); + d = GETDOUBLE(data); + exponent(data, d); + state = 0; + break; +# ifdef HAVE_PRINTF_A_FORMAT + case 'a': + case 'A': + STAR_ARGS(data); + d = GETDOUBLE(data); + dfallback(data, convstart, data->pf, d); + state = 0; + break; +# endif /* HAVE_PRINTF_A_FORMAT */ +#endif /* FLOATING_POINT */ + case 'U': + data->flags |= PF_LONGINT; + /* FALLTHROUGH */ + case 'u': + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = GETARG (unsigned long long); + lnumber(data, ull, 10); + } + else +#endif + { + ul = GETUNSIGNED(data); + number(data, ul, 10); + } + state = 0; + break; + case 'D': + data->flags |= PF_LONGINT; + /* FALLTHROUGH */ + case 'd': /* decimal */ + case 'i': + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = GETARG (long long); + lnumber(data, ull, 10); + } + else +#endif + { + ul = GETSIGNED(data); + number(data, ul, 10); + } + state = 0; + break; + case 'o': /* octal */ + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = GETARG (unsigned long long); + lnumber(data, ull, 8); + } + else +#endif + { + ul = GETUNSIGNED(data); + number(data, ul, 8); + } + state = 0; + break; + case 'x': + case 'X': /* hexadecimal */ + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = GETARG (unsigned long long); + lnumber(data, ull, 16); + } + else +#endif + { + ul = GETUNSIGNED(data); + number(data, ul, 16); + } + state = 0; + break; + case 'p': + STAR_ARGS(data); + ul = (unsigned long)GETARG (void *); + pointer(data, ul); + state = 0; + break; +#if HANDLE_MULTIBYTE + case 'C': + data->flags |= PF_LONGINT; + /* FALLTHROUGH */ +#endif + case 'c': /* character */ + STAR_ARGS(data); +#if HANDLE_MULTIBYTE + if (data->flags & PF_LONGINT) + { + wc = GETARG (wint_t); + wchars (data, wc); + } + else +#endif + { + ul = GETARG (int); + PUT_CHAR(ul, data); + } + state = 0; + break; +#if HANDLE_MULTIBYTE + case 'S': + data->flags |= PF_LONGINT; + /* FALLTHROUGH */ +#endif + case 's': /* string */ + STAR_ARGS(data); +#if HANDLE_MULTIBYTE + if (data->flags & PF_LONGINT) + { + ws = GETARG (wchar_t *); + wstrings (data, ws); + } + else +#endif + { + s = GETARG (char *); + strings(data, s); + } + state = 0; + break; + case 'n': +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + *(GETARG (long long *)) = data->counter; + else +#endif + if (data->flags & PF_LONGINT) + *(GETARG (long *)) = data->counter; + else if (data->flags & PF_SHORTINT) + *(GETARG (short *)) = data->counter; + else + *(GETARG (int *)) = data->counter; + state = 0; + break; + case '%': /* nothing just % */ + PUT_CHAR('%', data); + state = 0; + break; + default: + /* is this an error ? maybe bail out */ + state = 0; + break; + } /* end switch */ + } /* end of `%' for loop */ + } /* end of format string for loop */ + + if (data->length >= 0) + *data->holder = '\0'; /* the end ye ! */ + + return data->counter; +} + +#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE) +/* + * Printing floating point numbers accurately is an art. I'm not good + * at it. Fall back to sprintf for long double formats. + */ +static void +ldfallback (data, fs, fe, ld) + struct DATA *data; + const char *fs, *fe; + long double ld; +{ + register char *x; + char fmtbuf[FALLBACK_FMTSIZE], *obuf; + int fl; + + fl = LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2; + obuf = (char *)xmalloc (fl); + fl = fe - fs + 1; + strncpy (fmtbuf, fs, fl); + fmtbuf[fl] = '\0'; + + if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P)) + sprintf (obuf, fmtbuf, data->width, data->precision, ld); + else if (data->flags & PF_STAR_W) + sprintf (obuf, fmtbuf, data->width, ld); + else if (data->flags & PF_STAR_P) + sprintf (obuf, fmtbuf, data->precision, ld); + else + sprintf (obuf, fmtbuf, ld); + + for (x = obuf; *x; x++) + PUT_CHAR (*x, data); + xfree (obuf); +} +#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */ + +#ifdef FLOATING_POINT +/* Used for %a, %A if the libc printf supports them. */ +static void +dfallback (data, fs, fe, d) + struct DATA *data; + const char *fs, *fe; + double d; +{ + register char *x; + char fmtbuf[FALLBACK_FMTSIZE], obuf[FALLBACK_BASE]; + int fl; + + fl = fe - fs + 1; + strncpy (fmtbuf, fs, fl); + fmtbuf[fl] = '\0'; + + if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P)) + sprintf (obuf, fmtbuf, data->width, data->precision, d); + else if (data->flags & PF_STAR_W) + sprintf (obuf, fmtbuf, data->width, d); + else if (data->flags & PF_STAR_P) + sprintf (obuf, fmtbuf, data->precision, d); + else + sprintf (obuf, fmtbuf, d); + + for (x = obuf; *x; x++) + PUT_CHAR (*x, data); +} +#endif /* FLOATING_POINT */ + +#if !HAVE_SNPRINTF + +int +#if defined (__STDC__) +vsnprintf(char *string, size_t length, const char *format, va_list args) +#else +vsnprintf(string, length, format, args) + char *string; + size_t length; + const char *format; + va_list args; +#endif +{ + struct DATA data; + + if (string == 0 && length != 0) + return 0; + init_data (&data, string, length, format, PFM_SN); + return (vsnprintf_internal(&data, string, length, format, args)); +} + +int +#if defined(PREFER_STDARG) +snprintf(char *string, size_t length, const char * format, ...) +#else +snprintf(string, length, format, va_alist) + char *string; + size_t length; + const char *format; + va_dcl +#endif +{ + struct DATA data; + int rval; + va_list args; + + SH_VA_START(args, format); + + if (string == 0 && length != 0) + return 0; + init_data (&data, string, length, format, PFM_SN); + rval = vsnprintf_internal (&data, string, length, format, args); + + va_end(args); + + return rval; +} + +#endif /* HAVE_SNPRINTF */ + +#if !HAVE_ASPRINTF + +int +#if defined (__STDC__) +vasprintf(char **stringp, const char *format, va_list args) +#else +vasprintf(stringp, format, args) + char **stringp; + const char *format; + va_list args; +#endif +{ + struct DATA data; + char *string; + int r; + + string = (char *)xmalloc(ASBUFSIZE); + init_data (&data, string, ASBUFSIZE, format, PFM_AS); + r = vsnprintf_internal(&data, string, ASBUFSIZE, format, args); + *stringp = data.base; /* not string in case reallocated */ + return r; +} + +int +#if defined(PREFER_STDARG) +asprintf(char **stringp, const char * format, ...) +#else +asprintf(stringp, format, va_alist) + char **stringp; + const char *format; + va_dcl +#endif +{ + int rval; + va_list args; + + SH_VA_START(args, format); + + rval = vasprintf (stringp, format, args); + + va_end(args); + + return rval; +} + +#endif /* !HAVE_ASPRINTF */ + +#endif /* !HAVE_SNPRINTF || !HAVE_ASPRINTF */ + +#ifdef DRIVER + +static void +memory_error_and_abort () +{ + write (2, "out of virtual memory\n", 22); + abort (); +} + +static void * +xmalloc(bytes) + size_t bytes; +{ + void *ret; + + ret = malloc(bytes); + if (ret == 0) + memory_error_and_abort (); + return ret; +} + +static void * +xrealloc (pointer, bytes) + void *pointer; + size_t bytes; +{ + void *ret; + + ret = pointer ? realloc(pointer, bytes) : malloc(bytes); + if (ret == 0) + memory_error_and_abort (); + return ret; +} + +static void +xfree(x) + void *x; +{ + if (x) + free (x); +} + +/* set of small tests for snprintf() */ +main() +{ + char holder[100]; + char *h; + int i, si, ai; + +#ifdef HAVE_LOCALE_H + setlocale(LC_ALL, ""); +#endif + +#if 1 + si = snprintf((char *)NULL, 0, "abcde\n"); + printf("snprintf returns %d with NULL first argument and size of 0\n", si); + si = snprintf(holder, 0, "abcde\n"); + printf("snprintf returns %d with non-NULL first argument and size of 0\n", si); + si = snprintf((char *)NULL, 16, "abcde\n"); + printf("snprintf returns %d with NULL first argument and non-zero size\n", si); + +/* + printf("Suite of test for snprintf:\n"); + printf("a_format\n"); + printf("printf() format\n"); + printf("snprintf() format\n\n"); +*/ +/* Checking the field widths */ + + printf("/%%ld %%ld/, 336, 336\n"); + snprintf(holder, sizeof holder, "/%ld %ld/\n", 336, 336); + asprintf(&h, "/%ld %ld/\n", 336, 336); + printf("/%ld %ld/\n", 336, 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%d/, 336\n"); + snprintf(holder, sizeof holder, "/%d/\n", 336); + asprintf(&h, "/%d/\n", 336); + printf("/%d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%2d/, 336\n"); + snprintf(holder, sizeof holder, "/%2d/\n", 336); + asprintf(&h, "/%2d/\n", 336); + printf("/%2d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%10d/, 336\n"); + snprintf(holder, sizeof holder, "/%10d/\n", 336); + asprintf(&h, "/%10d/\n", 336); + printf("/%10d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%-10d/, 336\n"); + snprintf(holder, sizeof holder, "/%-10d/\n", 336); + asprintf(&h, "/%-10d/\n", 336); + printf("/%-10d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + +/* floating points */ + + printf("/%%f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%f/\n", 1234.56); + asprintf(&h, "/%f/\n", 1234.56); + printf("/%f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%e/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%e/\n", 1234.56); + asprintf(&h, "/%e/\n", 1234.56); + printf("/%e/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%4.2f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56); + asprintf(&h, "/%4.2f/\n", 1234.56); + printf("/%4.2f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%3.1f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56); + asprintf(&h, "/%3.1f/\n", 1234.56); + printf("/%3.1f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%10.3f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56); + asprintf(&h, "/%10.3f/\n", 1234.56); + printf("/%10.3f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%10.3e/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56); + asprintf(&h, "/%10.3e/\n", 1234.56); + printf("/%10.3e/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%+4.2f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56); + asprintf(&h, "/%+4.2f/\n", 1234.56); + printf("/%+4.2f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%010.2f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56); + asprintf(&h, "/%010.2f/\n", 1234.56); + printf("/%010.2f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + +#define BLURB "Outstanding acting !" +/* strings precisions */ + + printf("/%%2s/, \"%s\"\n", BLURB); + snprintf(holder, sizeof holder, "/%2s/\n", BLURB); + asprintf(&h, "/%2s/\n", BLURB); + printf("/%2s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%22s/ %s\n", BLURB); + snprintf(holder, sizeof holder, "/%22s/\n", BLURB); + asprintf(&h, "/%22s/\n", BLURB); + printf("/%22s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%22.5s/ %s\n", BLURB); + snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB); + asprintf(&h, "/%22.5s/\n", BLURB); + printf("/%22.5s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%-22.5s/ %s\n", BLURB); + snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB); + asprintf(&h, "/%-22.5s/\n", BLURB); + printf("/%-22.5s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + +/* see some flags */ + + printf("%%x %%X %%#x, 31, 31, 31\n"); + snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31); + asprintf(&h, "%x %X %#x\n", 31, 31, 31); + printf("%x %X %#x\n", 31, 31, 31); + printf("%s", holder); + printf("%s\n", h); + + printf("**%%d**%% d**%% d**, 42, 42, -42\n"); + snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42); + asprintf(&h, "**%d**% d**% d**\n", 42, 42, -42); + printf("**%d**% d**% d**\n", 42, 42, -42); + printf("%s", holder); + printf("%s\n", h); + +/* other flags */ + + printf("/%%g/, 31.4\n"); + snprintf(holder, sizeof holder, "/%g/\n", 31.4); + asprintf(&h, "/%g/\n", 31.4); + printf("/%g/\n", 31.4); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.6g/, 31.4\n"); + snprintf(holder, sizeof holder, "/%.6g/\n", 31.4); + asprintf(&h, "/%.6g/\n", 31.4); + printf("/%.6g/\n", 31.4); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.1G/, 31.4\n"); + snprintf(holder, sizeof holder, "/%.1G/\n", 31.4); + asprintf(&h, "/%.1G/\n", 31.4); + printf("/%.1G/\n", 31.4); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.1G/, 3100000000.4\n"); + snprintf(holder, sizeof holder, "/%.1G/\n", 3100000000.4); + asprintf(&h, "/%.1G/\n", 3100000000.4); + printf("/%.1G/\n", 3100000000.4); + printf("%s", holder); + printf("%s\n", h); + + printf("abc%%n\n"); + printf("abc%n", &i); printf("%d\n", i); + snprintf(holder, sizeof holder, "abc%n", &i); + printf("%s", holder); printf("%d\n\n", i); + asprintf(&h, "abc%n", &i); + printf("%s", h); printf("%d\n\n", i); + + printf("%%*.*s --> 10.10\n"); + snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB); + asprintf(&h, "%*.*s\n", 10, 10, BLURB); + printf("%*.*s\n", 10, 10, BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("%%%%%%%%\n"); + snprintf(holder, sizeof holder, "%%%%\n"); + asprintf(&h, "%%%%\n"); + printf("%%%%\n"); + printf("%s", holder); + printf("%s\n", h); + +#define BIG "Hello this is a too big string for the buffer" +/* printf("A buffer to small of 10, trying to put this:\n");*/ + printf("<%%>, %s\n", BIG); + i = snprintf(holder, 10, "%s\n", BIG); + i = asprintf(&h, "%s", BIG); + printf("<%s>\n", BIG); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); + + printf ("<%%p> vsnprintf\n"); + i = snprintf(holder, 100, "%p", vsnprintf); + i = asprintf(&h, "%p", vsnprintf); + printf("<%p>\n", vsnprintf); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); + + printf ("<%%lu> LONG_MAX+1\n"); + i = snprintf(holder, 100, "%lu", (unsigned long)(LONG_MAX)+1); + i = asprintf(&h, "%lu", (unsigned long)(LONG_MAX)+1); + printf("<%lu>\n", (unsigned long)(LONG_MAX)+1); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); + +#ifdef HAVE_LONG_LONG + printf ("<%%llu> LLONG_MAX+1\n"); + i = snprintf(holder, 100, "%llu", (unsigned long long)(LLONG_MAX)+1); + i = asprintf(&h, "%llu", (unsigned long long)(LLONG_MAX)+1); + printf("<%llu>\n", (unsigned long long)(LLONG_MAX)+1); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); +#endif + +#ifdef HAVE_LONG_DOUBLE + printf ("<%%6.2LE> 42.42\n"); + i = snprintf(holder, 100, "%6.2LE", (long double)42.42); + i = asprintf(&h, "%6.2LE", (long double)42.42); + printf ("<%6.2LE>\n", (long double)42.42); + printf ("<%s>\n", holder); + printf ("<%s>\n\n", h); +#endif + +#ifdef HAVE_PRINTF_A_FORMAT + printf ("<%%6.2A> 42.42\n"); + i = snprintf(holder, 100, "%6.2A", 42.42); + i = asprintf(&h, "%6.2A", 42.42); + printf ("<%6.2A>\n", 42.42); + printf ("<%s>\n", holder); + printf ("<%s>\n\n", h); + + printf ("<%%6.2LA> 42.42\n"); + i = snprintf(holder, 100, "%6.2LA", (long double)42.42); + i = asprintf(&h, "%6.2LA", (long double)42.42); + printf ("<%6.2LA>\n", (long double)42.42); + printf ("<%s>\n", holder); + printf ("<%s>\n\n", h); +#endif + + printf ("<%%.10240f> DBL_MAX\n"); + si = snprintf(holder, 100, "%.10240f", DBL_MAX); + ai = asprintf(&h, "%.10240f", DBL_MAX); + printf ("<%.10240f>\n", DBL_MAX); + printf ("<%d> <%s>\n", si, holder); + printf ("<%d> <%s>\n\n", ai, h); + + printf ("<%%.10240Lf> LDBL_MAX\n"); + si = snprintf(holder, 100, "%.10240Lf", (long double)LDBL_MAX); + ai = asprintf(&h, "%.10240Lf", (long double)LDBL_MAX); + printf ("<%.10240Lf>\n", (long double)LDBL_MAX); + printf ("<%d> <%s>\n", si, holder); + printf ("<%d> <%s>\n\n", ai, h); + + /* huh? */ + printf("/%%g/, 421.2345\n"); + snprintf(holder, sizeof holder, "/%g/\n", 421.2345); + asprintf(&h, "/%g/\n", 421.2345); + printf("/%g/\n", 421.2345); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%g/, 4214.2345\n"); + snprintf(holder, sizeof holder, "/%g/\n", 4214.2345); + asprintf(&h, "/%g/\n", 4214.2345); + printf("/%g/\n", 4214.2345); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.5g/, 4214.2345\n"); + snprintf(holder, sizeof holder, "/%.5g/\n", 4214.2345); + asprintf(&h, "/%.5g/\n", 4214.2345); + printf("/%.5g/\n", 4214.2345); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.4g/, 4214.2345\n"); + snprintf(holder, sizeof holder, "/%.4g/\n", 4214.2345); + asprintf(&h, "/%.4g/\n", 4214.2345); + printf("/%.4g/\n", 4214.2345); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'ld %%'ld/, 12345, 1234567\n"); + snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 12345, 1234567); + asprintf(&h, "/%'ld %'ld/\n", 12345, 1234567); + printf("/%'ld %'ld/\n", 12345, 1234567); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'ld %%'ld/, 336, 3336\n"); + snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 336, 3336); + asprintf(&h, "/%'ld %'ld/\n", 336, 3336); + printf("/%'ld %'ld/\n", 336, 3336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'ld %%'ld/, -42786, -142786\n"); + snprintf(holder, sizeof holder, "/%'ld %'ld/\n", -42786, -142786); + asprintf(&h, "/%'ld %'ld/\n", -42786, -142786); + printf("/%'ld %'ld/\n", -42786, -142786); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'f %%'f/, 421.2345, 421234.56789\n"); + snprintf(holder, sizeof holder, "/%'f %'f/\n", 421.2345, 421234.56789); + asprintf(&h, "/%'f %'f/\n", 421.2345, 421234.56789); + printf("/%'f %'f/\n", 421.2345, 421234.56789); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'f %%'f/, -421.2345, -421234.56789\n"); + snprintf(holder, sizeof holder, "/%'f %'f/\n", -421.2345, -421234.56789); + asprintf(&h, "/%'f %'f/\n", -421.2345, -421234.56789); + printf("/%'f %'f/\n", -421.2345, -421234.56789); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'g %%'g/, 421.2345, 421234.56789\n"); + snprintf(holder, sizeof holder, "/%'g %'g/\n", 421.2345, 421234.56789); + asprintf(&h, "/%'g %'g/\n", 421.2345, 421234.56789); + printf("/%'g %'g/\n", 421.2345, 421234.56789); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%'g %%'g/, -421.2345, -421234.56789\n"); + snprintf(holder, sizeof holder, "/%'g %'g/\n", -421.2345, -421234.56789); + asprintf(&h, "/%'g %'g/\n", -421.2345, -421234.56789); + printf("/%'g %'g/\n", -421.2345, -421234.56789); + printf("%s", holder); + printf("%s\n", h); +#endif + + printf("/%%'g/, 4213455.8392\n"); + snprintf(holder, sizeof holder, "/%'g/\n", 4213455.8392); + asprintf(&h, "/%'g/\n", 4213455.8392); + printf("/%'g/\n", 4213455.8392); + printf("%s", holder); + printf("%s\n", h); + + exit (0); +} +#endif diff --git a/utshell-0.5.0/lib/sh/spell.c b/utshell-0.5.0/lib/sh/spell.c new file mode 100644 index 00000000..cdf465b2 --- /dev/null +++ b/utshell-0.5.0/lib/sh/spell.c @@ -0,0 +1,212 @@ +/* spell.c -- spelling correction for pathnames. */ + +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include +#include +#if defined (HAVE_SYS_PARAM_H) +#include +#endif + +#include + +#include +#include +#include + +static int mindist PARAMS((char *, char *, char *)); +static int spdist PARAMS((char *, char *)); + +/* + * `spname' and its helpers are inspired by the code in "The UNIX + * Programming Environment", Kernighan & Pike, Prentice-Hall 1984, + * pages 209 - 213. + */ + +/* + * `spname' -- return a correctly spelled filename + * + * int spname(char * oldname, char * newname) + * Returns: -1 if no reasonable match found + * 0 if exact match found + * 1 if corrected + * Stores corrected name in `newname'. + */ +int +spname(oldname, newname) + char *oldname; + char *newname; +{ + char *op, *np, *p; + char guess[PATH_MAX + 1], best[PATH_MAX + 1]; + + op = oldname; + np = newname; + for (;;) + { + while (*op == '/') /* Skip slashes */ + *np++ = *op++; + *np = '\0'; + + if (*op == '\0') /* Exact or corrected */ + { + /* `.' is rarely the right thing. */ + if (oldname[1] == '\0' && newname[1] == '\0' && + oldname[0] != '.' && newname[0] == '.') + return -1; + return strcmp(oldname, newname) != 0; + } + + /* Copy next component into guess */ + for (p = guess; *op != '/' && *op != '\0'; op++) + if (p < guess + PATH_MAX) + *p++ = *op; + *p = '\0'; + + if (mindist(newname, guess, best) >= 3) + return -1; /* Hopeless */ + + /* + * Add to end of newname + */ + for (p = best; *np = *p++; np++) + ; + } +} + +/* + * Search directory for a guess + */ +static int +mindist(dir, guess, best) + char *dir; + char *guess; + char *best; +{ + DIR *fd; + struct dirent *dp; + int dist, x; + + dist = 3; /* Worst distance */ + if (*dir == '\0') + dir = "."; + + if ((fd = opendir(dir)) == NULL) + return dist; + + while ((dp = readdir(fd)) != NULL) + { + /* + * Look for a better guess. If the new guess is as + * good as the current one, we take it. This way, + * any single character match will be a better match + * than ".". + */ + x = spdist(dp->d_name, guess); + if (x <= dist && x != 3) + { + strcpy(best, dp->d_name); + dist = x; + if (dist == 0) /* Exact match */ + break; + } + } + (void)closedir(fd); + + /* Don't return `.' */ + if (best[0] == '.' && best[1] == '\0') + dist = 3; + return dist; +} + +/* + * `spdist' -- return the "distance" between two names. + * + * int spname(char * oldname, char * newname) + * Returns: 0 if strings are identical + * 1 if two characters are transposed + * 2 if one character is wrong, added or deleted + * 3 otherwise + */ +static int +spdist(cur, new) + char *cur, *new; +{ + while (*cur == *new) + { + if (*cur == '\0') + return 0; /* Exact match */ + cur++; + new++; + } + + if (*cur) + { + if (*new) + { + if (cur[1] && new[1] && cur[0] == new[1] && cur[1] == new[0] && strcmp (cur + 2, new + 2) == 0) + return 1; /* Transposition */ + + if (strcmp (cur + 1, new + 1) == 0) + return 2; /* One character mismatch */ + } + + if (strcmp(&cur[1], &new[0]) == 0) + return 2; /* Extra character */ + } + + if (*new && strcmp(cur, new + 1) == 0) + return 2; /* Missing character */ + + return 3; +} + +char * +dirspell (dirname) + char *dirname; +{ + int n; + char *guess; + + n = (strlen (dirname) * 3 + 1) / 2 + 1; + guess = (char *)malloc (n); + if (guess == 0) + return 0; + + switch (spname (dirname, guess)) + { + case -1: + default: + free (guess); + return (char *)NULL; + case 0: + case 1: + return guess; + } +} diff --git a/utshell-0.5.0/lib/sh/strcasecmp.c b/utshell-0.5.0/lib/sh/strcasecmp.c new file mode 100644 index 00000000..70d0551a --- /dev/null +++ b/utshell-0.5.0/lib/sh/strcasecmp.c @@ -0,0 +1,84 @@ +/* strcasecmp.c - functions for case-insensitive string comparison. */ + +/* Copyright (C) 1995 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_STRCASECMP) + +#include +#include +#include + +/* Compare at most COUNT characters from string1 to string2. Case + doesn't matter. */ +int +strncasecmp (string1, string2, count) + const char *string1; + const char *string2; + size_t count; +{ + register const char *s1; + register const char *s2; + register int r; + + if (count <= 0 || (string1 == string2)) + return 0; + + s1 = string1; + s2 = string2; + do + { + if ((r = TOLOWER ((unsigned char) *s1) - TOLOWER ((unsigned char) *s2)) != 0) + return r; + if (*s1++ == '\0') + break; + s2++; + } + while (--count != 0); + + return (0); +} + +/* strcmp (), but caseless. */ +int +strcasecmp (string1, string2) + const char *string1; + const char *string2; +{ + register const char *s1; + register const char *s2; + register int r; + + s1 = string1; + s2 = string2; + + if (s1 == s2) + return (0); + + while ((r = TOLOWER ((unsigned char)*s1) - TOLOWER ((unsigned char)*s2)) == 0) + { + if (*s1++ == '\0') + return 0; + s2++; + } + + return (r); +} +#endif /* !HAVE_STRCASECMP */ diff --git a/utshell-0.5.0/lib/sh/strcasestr.c b/utshell-0.5.0/lib/sh/strcasestr.c new file mode 100644 index 00000000..c819b3eb --- /dev/null +++ b/utshell-0.5.0/lib/sh/strcasestr.c @@ -0,0 +1,46 @@ +/* strcasestr.c - Find if one string appears as a substring of another string, + without regard to case. */ + +/* Copyright (C) 2000 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#include + +#include + +/* Determine if s2 occurs in s1. If so, return a pointer to the + match in s1. The compare is case insensitive. This is a + case-insensitive strstr(3). */ +char * +strcasestr (s1, s2) + const char *s1; + const char *s2; +{ + register int i, l, len, c; + + c = TOLOWER ((unsigned char)s2[0]); + len = strlen (s1); + l = strlen (s2); + for (i = 0; (len - i) >= l; i++) + if ((TOLOWER ((unsigned char)s1[i]) == c) && (strncasecmp (s1 + i, s2, l) == 0)) + return ((char *)s1 + i); + return ((char *)0); +} diff --git a/utshell-0.5.0/lib/sh/strchrnul.c b/utshell-0.5.0/lib/sh/strchrnul.c new file mode 100644 index 00000000..00cb88c4 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strchrnul.c @@ -0,0 +1,35 @@ +/* Searching in a string. + Copyright (C) 2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include + +/* Specification. */ +#include + +/* Find the first occurrence of C in S or the final NUL byte. */ +char * +strchrnul (s, c_in) + const char *s; + int c_in; +{ + char c; + register char *s1; + + for (c = c_in, s1 = (char *)s; s1 && *s1 && *s1 != c; s1++) + ; + return (s1); +} diff --git a/utshell-0.5.0/lib/sh/strdup.c b/utshell-0.5.0/lib/sh/strdup.c new file mode 100644 index 00000000..90fa3532 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strdup.c @@ -0,0 +1,42 @@ +/* strdup - return a copy of a string in newly-allocated memory. */ + +/* Copyright (C) 2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + + +#include + +/* Get specification. */ +#include +#include + +/* Duplicate S, returning an identical malloc'd string. */ +char * +strdup (s) + const char *s; +{ + size_t len; + void *new; + + len = strlen (s) + 1; + if ((new = malloc (len)) == NULL) + return NULL; + + memcpy (new, s, len); + return ((char *)new); +} diff --git a/utshell-0.5.0/lib/sh/strerror.c b/utshell-0.5.0/lib/sh/strerror.c new file mode 100644 index 00000000..bf639263 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strerror.c @@ -0,0 +1,74 @@ +/* strerror.c - string corresponding to a particular value of errno. */ + +/* Copyright (C) 1995 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_STRERROR) + +#include +#if defined (HAVE_SYS_PARAM_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* Return a string corresponding to the error number E. From + the ANSI C spec. */ +#if defined (strerror) +# undef strerror +#endif + +static char *errbase = "Unknown system error "; + +char * +strerror (e) + int e; +{ + static char emsg[40]; +#if defined (HAVE_SYS_ERRLIST) + extern int sys_nerr; + extern char *sys_errlist[]; + + if (e > 0 && e < sys_nerr) + return (sys_errlist[e]); + else +#endif /* HAVE_SYS_ERRLIST */ + { + char *z; + + z = itos (e); + strcpy (emsg, errbase); + strcat (emsg, z); + free (z); + return (&emsg[0]); + } +} +#endif /* HAVE_STRERROR */ diff --git a/utshell-0.5.0/lib/sh/strftime.c b/utshell-0.5.0/lib/sh/strftime.c new file mode 100644 index 00000000..08ccb9a3 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strftime.c @@ -0,0 +1,1015 @@ +/* strftime - formatted time and date to a string */ +/* + * Modified slightly by Chet Ramey for inclusion in Bash + */ +/* + * strftime.c + * + * Public-domain implementation of ISO C library routine. + * + * If you can't do prototypes, get GCC. + * + * The C99 standard now specifies just about all of the formats + * that were additional in the earlier versions of this file. + * + * For extensions from SunOS, add SUNOS_EXT. + * For extensions from HP/UX, add HPUX_EXT. + * For VMS dates, add VMS_EXT. + * For complete POSIX semantics, add POSIX_SEMANTICS. + * + * The code for %c, %x, and %X follows the C99 specification for + * the "C" locale. + * + * This version ignores LOCALE information. + * It also doesn't worry about multi-byte characters. + * So there. + * + * Arnold Robbins + * January, February, March, 1991 + * Updated March, April 1992 + * Updated April, 1993 + * Updated February, 1994 + * Updated May, 1994 + * Updated January, 1995 + * Updated September, 1995 + * Updated January, 1996 + * Updated July, 1997 + * Updated October, 1999 + * Updated September, 2000 + * Updated December, 2001 + * Updated January, 2011 + * Updated April, 2012 + * + * Fixes from ado@elsie.nci.nih.gov, + * February 1991, May 1992 + * Fixes from Tor Lillqvist tml@tik.vtt.fi, + * May 1993 + * Further fixes from ado@elsie.nci.nih.gov, + * February 1994 + * %z code from chip@chinacat.unicom.com, + * Applied September 1995 + * %V code fixed (again) and %G, %g added, + * January 1996 + * %v code fixed, better configuration, + * July 1997 + * Moved to C99 specification. + * September 2000 + * Fixes from Tanaka Akira + * December 2001 + */ +#include + +#include +#include +#include +#include + +#if defined(TM_IN_SYS_TIME) +#include +#include +#endif + +#include +#include + +/* defaults: season to taste */ +#define SUNOS_EXT 1 /* stuff in SunOS strftime routine */ +#define VMS_EXT 1 /* include %v for VMS date format */ +#define HPUX_EXT 1 /* non-conflicting stuff in HP-UX date */ +#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */ +#define POSIX_2008 1 /* flag and fw for C, F, G, Y formats */ + +#undef strchr /* avoid AIX weirdness */ + +#if !defined (errno) +extern int errno; +#endif + +#if defined (SHELL) +extern char *get_string_value (const char *); +#endif + +extern void tzset(void); +static int weeknumber(const struct tm *timeptr, int firstweekday); +static int iso8601wknum(const struct tm *timeptr); + +#ifndef inline +#ifdef __GNUC__ +#define inline __inline__ +#else +#define inline /**/ +#endif +#endif + +#define range(low, item, hi) max(low, min(item, hi)) + +/* Whew! This stuff is a mess. */ +#if !defined(OS2) && !defined(MSDOS) && !defined(__CYGWIN__) && defined(HAVE_TZNAME) +extern char *tzname[2]; +extern int daylight; +#if defined(SOLARIS) || defined(mips) || defined (M_UNIX) +extern long int timezone, altzone; +#else +# if defined (HPUX) || defined(__hpux) +extern long int timezone; +# else +# if !defined(__CYGWIN__) +extern int timezone, altzone; +# endif +# endif +#endif +#endif + +#undef min /* just in case */ + +/* min --- return minimum of two numbers */ + +static inline int +min(int a, int b) +{ + return (a < b ? a : b); +} + +#undef max /* also, just in case */ + +/* max --- return maximum of two numbers */ + +static inline int +max(int a, int b) +{ + return (a > b ? a : b); +} + +#ifdef POSIX_2008 +/* iso_8601_2000_year --- format a year per ISO 8601:2000 as in 1003.1 */ + +static void +iso_8601_2000_year(char *buf, int year, size_t fw) +{ + int extra; + char sign = '\0'; + + if (year >= -9999 && year <= 9999) { + sprintf(buf, "%0*d", (int) fw, year); + return; + } + + /* now things get weird */ + if (year > 9999) { + sign = '+'; + } else { + sign = '-'; + year = -year; + } + + extra = year / 10000; + year %= 10000; + sprintf(buf, "%c_%04d_%d", sign, extra, year); +} +#endif /* POSIX_2008 */ + +/* strftime --- produce formatted time */ + +size_t +strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) +{ + char *endp = s + maxsize; + char *start = s; + auto char tbuf[100]; + long off; + int i, w, oerrno; + long y; + static short first = 1; +#ifdef POSIX_SEMANTICS + static char *savetz = NULL; + static int savetzlen = 0; + char *tz; +#endif /* POSIX_SEMANTICS */ +#ifndef HAVE_TM_ZONE +#ifndef HAVE_TM_NAME +#ifndef HAVE_TZNAME +#ifndef __CYGWIN__ + extern char *timezone(); + struct timeval tv; + struct timezone zone; +#endif /* __CYGWIN__ */ +#endif /* HAVE_TZNAME */ +#endif /* HAVE_TM_NAME */ +#endif /* HAVE_TM_ZONE */ +#ifdef POSIX_2008 + int pad; + size_t fw; + char flag; +#endif /* POSIX_2008 */ + + /* various tables, useful in North America */ + static const char *days_a[] = { + "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat", + }; + static const char *days_l[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", + }; + static const char *months_a[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; + static const char *months_l[] = { + "January", "February", "March", "April", + "May", "June", "July", "August", "September", + "October", "November", "December", + }; + static const char *ampm[] = { "AM", "PM", }; + + oerrno = errno; + + if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0) + return 0; + + /* quick check if we even need to bother */ + if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize) + return 0; + +#ifndef POSIX_SEMANTICS + if (first) { + tzset(); + first = 0; + } +#else /* POSIX_SEMANTICS */ +#if defined (SHELL) + tz = get_string_value ("TZ"); +#else + tz = getenv("TZ"); +#endif + if (first) { + if (tz != NULL) { + int tzlen = strlen(tz); + + savetz = (char *) malloc(tzlen + 1); + if (savetz != NULL) { + savetzlen = tzlen + 1; + strcpy(savetz, tz); + } + } + tzset(); + first = 0; + } + /* if we have a saved TZ, and it is different, recapture and reset */ + if (tz && savetz && (tz[0] != savetz[0] || strcmp(tz, savetz) != 0)) { + i = strlen(tz) + 1; + if (i > savetzlen) { + savetz = (char *) realloc(savetz, i); + if (savetz) { + savetzlen = i; + strcpy(savetz, tz); + } + } else + strcpy(savetz, tz); + tzset(); + } +#endif /* POSIX_SEMANTICS */ + + for (; *format && s < endp - 1; format++) { + tbuf[0] = '\0'; + if (*format != '%') { + *s++ = *format; + continue; + } +#ifdef POSIX_2008 + pad = '\0'; + fw = 0; + flag = '\0'; + switch (*++format) { + case '+': + flag = '+'; + /* fall through */ + case '0': + pad = '0'; + format++; + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + + default: + format--; + goto again; + } + for (; isdigit(*format); format++) { + fw = fw * 10 + (*format - '0'); + } + format--; +#endif /* POSIX_2008 */ + + again: + switch (*++format) { + case '\0': + *s++ = '%'; + goto out; + + case '%': + *s++ = '%'; + continue; + + case 'a': /* abbreviated weekday name */ + if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) + strcpy(tbuf, "?"); + else + strcpy(tbuf, days_a[timeptr->tm_wday]); + break; + + case 'A': /* full weekday name */ + if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) + strcpy(tbuf, "?"); + else + strcpy(tbuf, days_l[timeptr->tm_wday]); + break; + + case 'b': /* abbreviated month name */ + short_month: + if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) + strcpy(tbuf, "?"); + else + strcpy(tbuf, months_a[timeptr->tm_mon]); + break; + + case 'B': /* full month name */ + if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) + strcpy(tbuf, "?"); + else + strcpy(tbuf, months_l[timeptr->tm_mon]); + break; + + case 'c': /* appropriate date and time representation */ + /* + * This used to be: + * + * strftime(tbuf, sizeof tbuf, "%a %b %e %H:%M:%S %Y", timeptr); + * + * Now, per the ISO 1999 C standard, it this: + */ + strftime(tbuf, sizeof tbuf, "%A %B %d %T %Y", timeptr); + break; + + case 'C': +#ifdef POSIX_2008 + if (pad != '\0' && fw > 0) { + size_t min_fw = (flag ? 3 : 2); + + fw = max(fw, min_fw); + sprintf(tbuf, flag + ? "%+0*ld" + : "%0*ld", (int) fw, + (timeptr->tm_year + 1900L) / 100); + } else +#endif /* POSIX_2008 */ + century: + sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100); + break; + + case 'd': /* day of the month, 01 - 31 */ + i = range(1, timeptr->tm_mday, 31); + sprintf(tbuf, "%02d", i); + break; + + case 'D': /* date as %m/%d/%y */ + strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr); + break; + + case 'e': /* day of month, blank padded */ + sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31)); + break; + + case 'E': + /* POSIX (now C99) locale extensions, ignored for now */ + goto again; + + case 'F': /* ISO 8601 date representation */ + { +#ifdef POSIX_2008 + /* + * Field width for %F is for the whole thing. + * It must be at least 10. + */ + char m_d[10]; + strftime(m_d, sizeof m_d, "-%m-%d", timeptr); + size_t min_fw = 10; + + if (pad != '\0' && fw > 0) { + fw = max(fw, min_fw); + } else { + fw = min_fw; + } + + fw -= 6; /* -XX-XX at end are invariant */ + + iso_8601_2000_year(tbuf, timeptr->tm_year + 1900, fw); + strcat(tbuf, m_d); +#else + strftime(tbuf, sizeof tbuf, "%Y-%m-%d", timeptr); +#endif /* POSIX_2008 */ + } + break; + + case 'g': + case 'G': + /* + * Year of ISO week. + * + * If it's December but the ISO week number is one, + * that week is in next year. + * If it's January but the ISO week number is 52 or + * 53, that week is in last year. + * Otherwise, it's this year. + */ + w = iso8601wknum(timeptr); + if (timeptr->tm_mon == 11 && w == 1) + y = 1900L + timeptr->tm_year + 1; + else if (timeptr->tm_mon == 0 && w >= 52) + y = 1900L + timeptr->tm_year - 1; + else + y = 1900L + timeptr->tm_year; + + if (*format == 'G') { +#ifdef POSIX_2008 + if (pad != '\0' && fw > 0) { + size_t min_fw = 4; + + fw = max(fw, min_fw); + sprintf(tbuf, flag + ? "%+0*ld" + : "%0*ld", (int) fw, + y); + } else +#endif /* POSIX_2008 */ + sprintf(tbuf, "%ld", y); + } + else + sprintf(tbuf, "%02ld", y % 100); + break; + + case 'h': /* abbreviated month name */ + goto short_month; + + case 'H': /* hour, 24-hour clock, 00 - 23 */ + i = range(0, timeptr->tm_hour, 23); + sprintf(tbuf, "%02d", i); + break; + + case 'I': /* hour, 12-hour clock, 01 - 12 */ + i = range(0, timeptr->tm_hour, 23); + if (i == 0) + i = 12; + else if (i > 12) + i -= 12; + sprintf(tbuf, "%02d", i); + break; + + case 'j': /* day of the year, 001 - 366 */ + sprintf(tbuf, "%03d", timeptr->tm_yday + 1); + break; + + case 'm': /* month, 01 - 12 */ + i = range(0, timeptr->tm_mon, 11); + sprintf(tbuf, "%02d", i + 1); + break; + + case 'M': /* minute, 00 - 59 */ + i = range(0, timeptr->tm_min, 59); + sprintf(tbuf, "%02d", i); + break; + + case 'n': /* same as \n */ + tbuf[0] = '\n'; + tbuf[1] = '\0'; + break; + + case 'O': + /* POSIX (now C99) locale extensions, ignored for now */ + goto again; + + case 'p': /* am or pm based on 12-hour clock */ + i = range(0, timeptr->tm_hour, 23); + if (i < 12) + strcpy(tbuf, ampm[0]); + else + strcpy(tbuf, ampm[1]); + break; + + case 'r': /* time as %I:%M:%S %p */ + strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr); + break; + + case 'R': /* time as %H:%M */ + strftime(tbuf, sizeof tbuf, "%H:%M", timeptr); + break; + +#if defined(HAVE_MKTIME) + case 's': /* time as seconds since the Epoch */ + { + struct tm non_const_timeptr; + + non_const_timeptr = *timeptr; + sprintf(tbuf, "%ld", mktime(& non_const_timeptr)); + break; + } +#endif /* defined(HAVE_MKTIME) */ + + case 'S': /* second, 00 - 60 */ + i = range(0, timeptr->tm_sec, 60); + sprintf(tbuf, "%02d", i); + break; + + case 't': /* same as \t */ + tbuf[0] = '\t'; + tbuf[1] = '\0'; + break; + + case 'T': /* time as %H:%M:%S */ + the_time: + strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr); + break; + + case 'u': + /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */ + sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 : + timeptr->tm_wday); + break; + + case 'U': /* week of year, Sunday is first day of week */ + sprintf(tbuf, "%02d", weeknumber(timeptr, 0)); + break; + + case 'V': /* week of year according ISO 8601 */ + sprintf(tbuf, "%02d", iso8601wknum(timeptr)); + break; + + case 'w': /* weekday, Sunday == 0, 0 - 6 */ + i = range(0, timeptr->tm_wday, 6); + sprintf(tbuf, "%d", i); + break; + + case 'W': /* week of year, Monday is first day of week */ + sprintf(tbuf, "%02d", weeknumber(timeptr, 1)); + break; + + case 'x': /* appropriate date representation */ + strftime(tbuf, sizeof tbuf, "%A %B %d %Y", timeptr); + break; + + case 'X': /* appropriate time representation */ + goto the_time; + break; + + case 'y': /* year without a century, 00 - 99 */ + year: + i = timeptr->tm_year % 100; + sprintf(tbuf, "%02d", i); + break; + + case 'Y': /* year with century */ +#ifdef POSIX_2008 + if (pad != '\0' && fw > 0) { + size_t min_fw = 4; + + fw = max(fw, min_fw); + sprintf(tbuf, flag + ? "%+0*ld" + : "%0*ld", (int) fw, + 1900L + timeptr->tm_year); + } else +#endif /* POSIX_2008 */ + sprintf(tbuf, "%ld", 1900L + timeptr->tm_year); + break; + + /* + * From: Chip Rosenthal + * Date: Sun, 19 Mar 1995 00:33:29 -0600 (CST) + * + * Warning: the %z [code] is implemented by inspecting the + * timezone name conditional compile settings, and + * inferring a method to get timezone offsets. I've tried + * this code on a couple of machines, but I don't doubt + * there is some system out there that won't like it. + * Maybe the easiest thing to do would be to bracket this + * with an #ifdef that can turn it off. The %z feature + * would be an admittedly obscure one that most folks can + * live without, but it would be a great help to those of + * us that muck around with various message processors. + */ + case 'z': /* time zone offset east of GMT e.g. -0600 */ + if (timeptr->tm_isdst < 0) + break; +#ifdef HAVE_TM_NAME + /* + * Systems with tm_name probably have tm_tzadj as + * secs west of GMT. Convert to mins east of GMT. + */ + off = -timeptr->tm_tzadj / 60; +#else /* !HAVE_TM_NAME */ +#ifdef HAVE_TM_ZONE + /* + * Systems with tm_zone probably have tm_gmtoff as + * secs east of GMT. Convert to mins east of GMT. + */ + off = timeptr->tm_gmtoff / 60; +#else /* !HAVE_TM_ZONE */ +#if HAVE_TZNAME + /* + * Systems with tzname[] probably have timezone as + * secs west of GMT. Convert to mins east of GMT. + */ +# if defined(__hpux) || defined (HPUX) || defined(__CYGWIN__) + off = -timezone / 60; +# else + /* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */ + off = -(daylight ? altzone : timezone) / 60; +# endif +#else /* !HAVE_TZNAME */ + gettimeofday(& tv, & zone); + off = -zone.tz_minuteswest; +#endif /* !HAVE_TZNAME */ +#endif /* !HAVE_TM_ZONE */ +#endif /* !HAVE_TM_NAME */ + if (off < 0) { + tbuf[0] = '-'; + off = -off; + } else { + tbuf[0] = '+'; + } + sprintf(tbuf+1, "%02ld%02ld", off/60, off%60); + break; + + case 'Z': /* time zone name or abbreviation */ +#ifdef HAVE_TZNAME + i = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */ + strcpy(tbuf, tzname[i]); +#else +#ifdef HAVE_TM_ZONE + strcpy(tbuf, timeptr->tm_zone); +#else +#ifdef HAVE_TM_NAME + strcpy(tbuf, timeptr->tm_name); +#else + gettimeofday(& tv, & zone); + strcpy(tbuf, timezone(zone.tz_minuteswest, + timeptr->tm_isdst > 0)); +#endif /* HAVE_TM_NAME */ +#endif /* HAVE_TM_ZONE */ +#endif /* HAVE_TZNAME */ + break; + +#ifdef SUNOS_EXT + case 'k': /* hour, 24-hour clock, blank pad */ + sprintf(tbuf, "%2d", range(0, timeptr->tm_hour, 23)); + break; + + case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */ + i = range(0, timeptr->tm_hour, 23); + if (i == 0) + i = 12; + else if (i > 12) + i -= 12; + sprintf(tbuf, "%2d", i); + break; +#endif + +#ifdef HPUX_EXT + case 'N': /* Emperor/Era name */ + /* this is essentially the same as the century */ + goto century; /* %C */ + + case 'o': /* Emperor/Era year */ + goto year; /* %y */ +#endif /* HPUX_EXT */ + + +#ifdef VMS_EXT + case 'v': /* date as dd-bbb-YYYY */ + sprintf(tbuf, "%2d-%3.3s-%4ld", + range(1, timeptr->tm_mday, 31), + months_a[range(0, timeptr->tm_mon, 11)], + timeptr->tm_year + 1900L); + for (i = 3; i < 6; i++) + if (islower(tbuf[i])) + tbuf[i] = toupper(tbuf[i]); + break; +#endif + + default: + tbuf[0] = '%'; + tbuf[1] = *format; + tbuf[2] = '\0'; + break; + } + i = strlen(tbuf); + if (i) { + if (s + i < endp - 1) { + strcpy(s, tbuf); + s += i; + } else + return 0; + } + } +out: + if (s < endp && *format == '\0') { + *s = '\0'; + if (s == start) + errno = oerrno; + return (s - start); + } else + return 0; +} + +/* isleap --- is a year a leap year? */ + +static int +isleap(long year) +{ + return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); +} + + +/* iso8601wknum --- compute week number according to ISO 8601 */ + +static int +iso8601wknum(const struct tm *timeptr) +{ + /* + * From 1003.2: + * If the week (Monday to Sunday) containing January 1 + * has four or more days in the new year, then it is week 1; + * otherwise it is the highest numbered week of the previous + * year (52 or 53), and the next week is week 1. + * + * ADR: This means if Jan 1 was Monday through Thursday, + * it was week 1, otherwise week 52 or 53. + * + * XPG4 erroneously included POSIX.2 rationale text in the + * main body of the standard. Thus it requires week 53. + */ + + int weeknum, jan1day, diff; + + /* get week number, Monday as first day of the week */ + weeknum = weeknumber(timeptr, 1); + + /* + * With thanks and tip of the hatlo to tml@tik.vtt.fi + * + * What day of the week does January 1 fall on? + * We know that + * (timeptr->tm_yday - jan1.tm_yday) MOD 7 == + * (timeptr->tm_wday - jan1.tm_wday) MOD 7 + * and that + * jan1.tm_yday == 0 + * and that + * timeptr->tm_wday MOD 7 == timeptr->tm_wday + * from which it follows that. . . + */ + jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7); + if (jan1day < 0) + jan1day += 7; + + /* + * If Jan 1 was a Monday through Thursday, it was in + * week 1. Otherwise it was last year's highest week, which is + * this year's week 0. + * + * What does that mean? + * If Jan 1 was Monday, the week number is exactly right, it can + * never be 0. + * If it was Tuesday through Thursday, the weeknumber is one + * less than it should be, so we add one. + * Otherwise, Friday, Saturday or Sunday, the week number is + * OK, but if it is 0, it needs to be 52 or 53. + */ + switch (jan1day) { + case 1: /* Monday */ + break; + case 2: /* Tuesday */ + case 3: /* Wednesday */ + case 4: /* Thursday */ + weeknum++; + break; + case 5: /* Friday */ + case 6: /* Saturday */ + case 0: /* Sunday */ + if (weeknum == 0) { +#ifdef USE_BROKEN_XPG4 + /* XPG4 (as of March 1994) says 53 unconditionally */ + weeknum = 53; +#else + /* get week number of last week of last year */ + struct tm dec31ly; /* 12/31 last year */ + dec31ly = *timeptr; + dec31ly.tm_year--; + dec31ly.tm_mon = 11; + dec31ly.tm_mday = 31; + dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1; + dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900L); + weeknum = iso8601wknum(& dec31ly); +#endif + } + break; + } + + if (timeptr->tm_mon == 11) { + /* + * The last week of the year + * can be in week 1 of next year. + * Sigh. + * + * This can only happen if + * M T W + * 29 30 31 + * 30 31 + * 31 + */ + int wday, mday; + + wday = timeptr->tm_wday; + mday = timeptr->tm_mday; + if ( (wday == 1 && (mday >= 29 && mday <= 31)) + || (wday == 2 && (mday == 30 || mday == 31)) + || (wday == 3 && mday == 31)) + weeknum = 1; + } + + return weeknum; +} + +/* weeknumber --- figure how many weeks into the year */ + +/* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */ + +static int +weeknumber(const struct tm *timeptr, int firstweekday) +{ + int wday = timeptr->tm_wday; + int ret; + + if (firstweekday == 1) { + if (wday == 0) /* sunday */ + wday = 6; + else + wday--; + } + ret = ((timeptr->tm_yday + 7 - wday) / 7); + if (ret < 0) + ret = 0; + return ret; +} + +#if 0 +/* ADR --- I'm loathe to mess with ado's code ... */ + +Date: Wed, 24 Apr 91 20:54:08 MDT +From: Michal Jaegermann +To: arnold@audiofax.com + +Hi Arnold, +in a process of fixing of strftime() in libraries on Atari ST I grabbed +some pieces of code from your own strftime. When doing that it came +to mind that your weeknumber() function compiles a little bit nicer +in the following form: +/* + * firstweekday is 0 if starting in Sunday, non-zero if in Monday + */ +{ + return (timeptr->tm_yday - timeptr->tm_wday + + (firstweekday ? (timeptr->tm_wday ? 8 : 1) : 7)) / 7; +} +How nicer it depends on a compiler, of course, but always a tiny bit. + + Cheers, + Michal + ntomczak@vm.ucs.ualberta.ca +#endif + +#ifdef TEST_STRFTIME + +/* + * NAME: + * tst + * + * SYNOPSIS: + * tst + * + * DESCRIPTION: + * "tst" is a test driver for the function "strftime". + * + * OPTIONS: + * None. + * + * AUTHOR: + * Karl Vogel + * Control Data Systems, Inc. + * vogelke@c-17igp.wpafb.af.mil + * + * BUGS: + * None noticed yet. + * + * COMPILE: + * cc -o tst -DTEST_STRFTIME strftime.c + */ + +/* ADR: I reformatted this to my liking, and deleted some unneeded code. */ + +#ifndef NULL +#include +#endif +#include +#include + +#define MAXTIME 132 + +/* + * Array of time formats. + */ + +static char *array[] = +{ + "(%%A) full weekday name, var length (Sunday..Saturday) %A", + "(%%B) full month name, var length (January..December) %B", + "(%%C) Century %C", + "(%%D) date (%%m/%%d/%%y) %D", + "(%%E) Locale extensions (ignored) %E", + "(%%F) full month name, var length (January..December) %F", + "(%%H) hour (24-hour clock, 00..23) %H", + "(%%I) hour (12-hour clock, 01..12) %I", + "(%%M) minute (00..59) %M", + "(%%N) Emperor/Era Name %N", + "(%%O) Locale extensions (ignored) %O", + "(%%R) time, 24-hour (%%H:%%M) %R", + "(%%S) second (00..60) %S", + "(%%T) time, 24-hour (%%H:%%M:%%S) %T", + "(%%U) week of year, Sunday as first day of week (00..53) %U", + "(%%V) week of year according to ISO 8601 %V", + "(%%W) week of year, Monday as first day of week (00..53) %W", + "(%%X) appropriate locale time representation (%H:%M:%S) %X", + "(%%Y) year with century (1970...) %Y", + "(%%Z) timezone (EDT), or blank if timezone not determinable %Z", + "(%%a) locale's abbreviated weekday name (Sun..Sat) %a", + "(%%b) locale's abbreviated month name (Jan..Dec) %b", + "(%%c) full date (Sat Nov 4 12:02:33 1989)%n%t%t%t %c", + "(%%d) day of the month (01..31) %d", + "(%%e) day of the month, blank-padded ( 1..31) %e", + "(%%h) should be same as (%%b) %h", + "(%%j) day of the year (001..366) %j", + "(%%k) hour, 24-hour clock, blank pad ( 0..23) %k", + "(%%l) hour, 12-hour clock, blank pad ( 0..12) %l", + "(%%m) month (01..12) %m", + "(%%o) Emperor/Era Year %o", + "(%%p) locale's AM or PM based on 12-hour clock %p", + "(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r", + "(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u", + "(%%v) VMS date (dd-bbb-YYYY) %v", + "(%%w) day of week (0..6, Sunday == 0) %w", + "(%%x) appropriate locale date representation %x", + "(%%y) last two digits of year (00..99) %y", + "(%%z) timezone offset east of GMT as HHMM (e.g. -0500) %z", + (char *) NULL +}; + +/* main routine. */ + +int +main(argc, argv) +int argc; +char **argv; +{ + long time(); + + char *next; + char string[MAXTIME]; + + int k; + int length; + + struct tm *tm; + + long clock; + + /* Call the function. */ + + clock = time((long *) 0); + tm = localtime(&clock); + + for (k = 0; next = array[k]; k++) { + length = strftime(string, MAXTIME, next, tm); + printf("%s\n", string); + } + + exit(0); +} +#endif /* TEST_STRFTIME */ diff --git a/utshell-0.5.0/lib/sh/stringlist.c b/utshell-0.5.0/lib/sh/stringlist.c new file mode 100644 index 00000000..3f28b631 --- /dev/null +++ b/utshell-0.5.0/lib/sh/stringlist.c @@ -0,0 +1,297 @@ +/* stringlist.c - functions to handle a generic `list of strings' structure */ + +/* Copyright (C) 2000-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#include "shell.h" + +#ifdef STRDUP +# undef STRDUP +#endif +#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) + +/* Allocate a new STRINGLIST, with room for N strings. */ + +STRINGLIST * +strlist_create (n) + int n; +{ + STRINGLIST *ret; + register int i; + + ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST)); + if (n) + { + ret->list = strvec_create (n+1); + ret->list_size = n; + for (i = 0; i < n; i++) + ret->list[i] = (char *)NULL; + } + else + { + ret->list = (char **)NULL; + ret->list_size = 0; + } + ret->list_len = 0; + return ret; +} + +STRINGLIST * +strlist_resize (sl, n) + STRINGLIST *sl; + int n; +{ + register int i; + + if (sl == 0) + return (sl = strlist_create (n)); + + if (n > sl->list_size) + { + sl->list = strvec_resize (sl->list, n + 1); + for (i = sl->list_size; i <= n; i++) + sl->list[i] = (char *)NULL; + sl->list_size = n; + } + return sl; +} + +void +strlist_flush (sl) + STRINGLIST *sl; +{ + if (sl == 0 || sl->list == 0) + return; + strvec_flush (sl->list); + sl->list_len = 0; +} + +void +strlist_dispose (sl) + STRINGLIST *sl; +{ + if (sl == 0) + return; + if (sl->list) + strvec_dispose (sl->list); + free (sl); +} + +int +strlist_remove (sl, s) + STRINGLIST *sl; + char *s; +{ + int r; + + if (sl == 0 || sl->list == 0 || sl->list_len == 0) + return 0; + + r = strvec_remove (sl->list, s); + if (r) + sl->list_len--; + return r; +} + +STRINGLIST * +strlist_copy (sl) + STRINGLIST *sl; +{ + STRINGLIST *new; + register int i; + + if (sl == 0) + return ((STRINGLIST *)0); + new = strlist_create (sl->list_size); + /* I'd like to use strvec_copy, but that doesn't copy everything. */ + if (sl->list) + { + for (i = 0; i < sl->list_size; i++) + new->list[i] = STRDUP (sl->list[i]); + } + new->list_size = sl->list_size; + new->list_len = sl->list_len; + /* just being careful */ + if (new->list) + new->list[new->list_len] = (char *)NULL; + return new; +} + +/* Return a new STRINGLIST with everything from M1 and M2. */ + +STRINGLIST * +strlist_merge (m1, m2) + STRINGLIST *m1, *m2; +{ + STRINGLIST *sl; + int i, n, l1, l2; + + l1 = m1 ? m1->list_len : 0; + l2 = m2 ? m2->list_len : 0; + + sl = strlist_create (l1 + l2 + 1); + for (i = n = 0; i < l1; i++, n++) + sl->list[n] = STRDUP (m1->list[i]); + for (i = 0; i < l2; i++, n++) + sl->list[n] = STRDUP (m2->list[i]); + sl->list_len = n; + sl->list[n] = (char *)NULL; + return (sl); +} + +/* Make STRINGLIST M1 contain everything in M1 and M2. */ +STRINGLIST * +strlist_append (m1, m2) + STRINGLIST *m1, *m2; +{ + register int i, n, len1, len2; + + if (m1 == 0) + return (m2 ? strlist_copy (m2) : (STRINGLIST *)0); + + len1 = m1->list_len; + len2 = m2 ? m2->list_len : 0; + + if (len2) + { + m1 = strlist_resize (m1, len1 + len2 + 1); + for (i = 0, n = len1; i < len2; i++, n++) + m1->list[n] = STRDUP (m2->list[i]); + m1->list[n] = (char *)NULL; + m1->list_len = n; + } + + return m1; +} + +STRINGLIST * +strlist_prefix_suffix (sl, prefix, suffix) + STRINGLIST *sl; + char *prefix, *suffix; +{ + int plen, slen, tlen, llen, i; + char *t; + + if (sl == 0 || sl->list == 0 || sl->list_len == 0) + return sl; + + plen = STRLEN (prefix); + slen = STRLEN (suffix); + + if (plen == 0 && slen == 0) + return (sl); + + for (i = 0; i < sl->list_len; i++) + { + llen = STRLEN (sl->list[i]); + tlen = plen + llen + slen + 1; + t = (char *)xmalloc (tlen + 1); + if (plen) + strcpy (t, prefix); + strcpy (t + plen, sl->list[i]); + if (slen) + strcpy (t + plen + llen, suffix); + free (sl->list[i]); + sl->list[i] = t; + } + + return (sl); +} + +void +strlist_print (sl, prefix) + STRINGLIST *sl; + char *prefix; +{ + register int i; + + if (sl == 0) + return; + for (i = 0; i < sl->list_len; i++) + printf ("%s%s\n", prefix ? prefix : "", sl->list[i]); +} + +void +strlist_walk (sl, func) + STRINGLIST *sl; + sh_strlist_map_func_t *func; +{ + register int i; + + if (sl == 0) + return; + for (i = 0; i < sl->list_len; i++) + if ((*func)(sl->list[i]) < 0) + break; +} + +void +strlist_sort (sl) + STRINGLIST *sl; +{ + if (sl == 0 || sl->list_len == 0 || sl->list == 0) + return; + strvec_sort (sl->list, 0); +} + +STRINGLIST * +strlist_from_word_list (list, alloc, starting_index, ip) + WORD_LIST *list; + int alloc, starting_index, *ip; +{ + STRINGLIST *ret; + int slen, len; + + if (list == 0) + { + if (ip) + *ip = 0; + return ((STRINGLIST *)0); + } + slen = list_length (list); + ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST)); + ret->list = strvec_from_word_list (list, alloc, starting_index, &len); + ret->list_size = slen + starting_index; + ret->list_len = len; + if (ip) + *ip = len; + return ret; +} + +WORD_LIST * +strlist_to_word_list (sl, alloc, starting_index) + STRINGLIST *sl; + int alloc, starting_index; +{ + WORD_LIST *list; + + if (sl == 0 || sl->list == 0) + return ((WORD_LIST *)NULL); + + list = strvec_to_word_list (sl->list, alloc, starting_index); + return list; +} diff --git a/utshell-0.5.0/lib/sh/stringvec.c b/utshell-0.5.0/lib/sh/stringvec.c new file mode 100644 index 00000000..86000429 --- /dev/null +++ b/utshell-0.5.0/lib/sh/stringvec.c @@ -0,0 +1,272 @@ +/* stringvec.c - functions for managing arrays of strings. */ + +/* Copyright (C) 2000-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include +#include + +#include "shell.h" + +/* Allocate an array of strings with room for N members. */ +char ** +strvec_create (n) + int n; +{ + return ((char **)xmalloc ((n) * sizeof (char *))); +} + +/* Allocate an array of strings with room for N members. */ +char ** +strvec_mcreate (n) + int n; +{ + return ((char **)malloc ((n) * sizeof (char *))); +} + +char ** +strvec_resize (array, nsize) + char **array; + int nsize; +{ + return ((char **)xrealloc (array, nsize * sizeof (char *))); +} + +char ** +strvec_mresize (array, nsize) + char **array; + int nsize; +{ + return ((char **)realloc (array, nsize * sizeof (char *))); +} + +/* Return the length of ARRAY, a NULL terminated array of char *. */ +int +strvec_len (array) + char **array; +{ + register int i; + + for (i = 0; array[i]; i++); + return (i); +} + +/* Free the contents of ARRAY, a NULL terminated array of char *. */ +void +strvec_flush (array) + char **array; +{ + register int i; + + if (array == 0) + return; + + for (i = 0; array[i]; i++) + free (array[i]); +} + +void +strvec_dispose (array) + char **array; +{ + if (array == 0) + return; + + strvec_flush (array); + free (array); +} + +int +strvec_remove (array, name) + char **array, *name; +{ + register int i, j; + char *x; + + if (array == 0) + return 0; + + for (i = 0; array[i]; i++) + if (STREQ (name, array[i])) + { + x = array[i]; + for (j = i; array[j]; j++) + array[j] = array[j + 1]; + free (x); + return 1; + } + return 0; +} + +/* Find NAME in ARRAY. Return the index of NAME, or -1 if not present. + ARRAY should be NULL terminated. */ +int +strvec_search (array, name) + char **array, *name; +{ + int i; + + for (i = 0; array[i]; i++) + if (STREQ (name, array[i])) + return (i); + + return (-1); +} + +/* Allocate and return a new copy of ARRAY and its contents. */ +char ** +strvec_copy (array) + char **array; +{ + register int i; + int len; + char **ret; + + len = strvec_len (array); + + ret = (char **)xmalloc ((len + 1) * sizeof (char *)); + for (i = 0; array[i]; i++) + ret[i] = savestring (array[i]); + ret[i] = (char *)NULL; + + return (ret); +} + +/* Comparison routine for use by qsort that conforms to the new Posix + requirements (http://austingroupbugs.net/view.php?id=1070). + + Perform a bytewise comparison if *S1 and *S2 collate equally. */ +int +strvec_posixcmp (s1, s2) + register char **s1, **s2; +{ + int result; + +#if defined (HAVE_STRCOLL) + result = strcoll (*s1, *s2); + if (result != 0) + return result; +#endif + + if ((result = **s1 - **s2) == 0) + result = strcmp (*s1, *s2); + + return (result); +} + +/* Comparison routine for use with qsort() on arrays of strings. Uses + strcoll(3) if available, otherwise it uses strcmp(3). */ +int +strvec_strcmp (s1, s2) + register char **s1, **s2; +{ +#if defined (HAVE_STRCOLL) + return (strcoll (*s1, *s2)); +#else /* !HAVE_STRCOLL */ + int result; + + if ((result = **s1 - **s2) == 0) + result = strcmp (*s1, *s2); + + return (result); +#endif /* !HAVE_STRCOLL */ +} + +/* Sort ARRAY, a null terminated array of pointers to strings. */ +void +strvec_sort (array, posix) + char **array; + int posix; +{ + if (posix) + qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_posixcmp); + else + qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp); +} + +/* Cons up a new array of words. The words are taken from LIST, + which is a WORD_LIST *. If ALLOC is true, everything is malloc'ed, + so you should free everything in this array when you are done. + The array is NULL terminated. If IP is non-null, it gets the + number of words in the returned array. STARTING_INDEX says where + to start filling in the returned array; it can be used to reserve + space at the beginning of the array. */ + +char ** +strvec_from_word_list (list, alloc, starting_index, ip) + WORD_LIST *list; + int alloc, starting_index, *ip; +{ + int count; + char **array; + + count = list_length (list); + array = (char **)xmalloc ((1 + count + starting_index) * sizeof (char *)); + + for (count = 0; count < starting_index; count++) + array[count] = (char *)NULL; + for (count = starting_index; list; count++, list = list->next) + array[count] = alloc ? savestring (list->word->word) : list->word->word; + array[count] = (char *)NULL; + + if (ip) + *ip = count; + return (array); +} + +/* Convert an array of strings into the form used internally by the shell. + ALLOC means to allocate new storage for each WORD_DESC in the returned + list rather than copy the values in ARRAY. STARTING_INDEX says where + in ARRAY to begin. */ + +WORD_LIST * +strvec_to_word_list (array, alloc, starting_index) + char **array; + int alloc, starting_index; +{ + WORD_LIST *list; + WORD_DESC *w; + int i, count; + + if (array == 0 || array[0] == 0) + return (WORD_LIST *)NULL; + + for (count = 0; array[count]; count++) + ; + + for (i = starting_index, list = (WORD_LIST *)NULL; i < count; i++) + { + w = make_bare_word (alloc ? array[i] : ""); + if (alloc == 0) + { + free (w->word); + w->word = array[i]; + } + list = make_word_list (w, list); + } + return (REVERSE_LIST (list, WORD_LIST *)); +} diff --git a/utshell-0.5.0/lib/sh/strnlen.c b/utshell-0.5.0/lib/sh/strnlen.c new file mode 100644 index 00000000..10414d35 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strnlen.c @@ -0,0 +1,49 @@ +/* strnlen - return length of passed string, with length limit */ + +/* Copyright (C) 2004 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined (HAVE_STRNLEN) + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +/* Find the length of S, but scan at most MAXLEN characters. If no '\0' + terminator is found within the first MAXLEN characters, return MAXLEN. */ +size_t +strnlen (s, maxlen) + register const char *s; + size_t maxlen; +{ + register const char *e; + size_t n; + + for (e = s, n = 0; *e && n < maxlen; e++, n++) + ; + return n; +} +#endif diff --git a/utshell-0.5.0/lib/sh/strpbrk.c b/utshell-0.5.0/lib/sh/strpbrk.c new file mode 100644 index 00000000..8cce8308 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strpbrk.c @@ -0,0 +1,49 @@ +/* strpbrk.c - locate multiple characters in a string */ + +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined (HAVE_STRPBRK) + +#include + +/* Find the first occurrence in S of any character in ACCEPT. */ +char * +strpbrk (s, accept) + register const char *s; + register const char *accept; +{ + while (*s != '\0') + { + const char *a = accept; + while (*a != '\0') + if (*a++ == *s) + return (char *) s; + ++s; + } + + return 0; +} +#endif diff --git a/utshell-0.5.0/lib/sh/strstr.c b/utshell-0.5.0/lib/sh/strstr.c new file mode 100644 index 00000000..c43b05e3 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strstr.c @@ -0,0 +1,125 @@ +/* strstr - find a substring within a string */ + +/* Copyright (C) 1994, 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* + * My personal strstr() implementation that beats most other algorithms. + * Until someone tells me otherwise, I assume that this is the + * fastest implementation of strstr() in C. + * I deliberately chose not to comment it. You should have at least + * as much fun trying to understand it, as I had to write it :-). + * + * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ + +#if HAVE_CONFIG_H +# include +#endif + +#if defined _LIBC || defined HAVE_STRING_H +# include +#endif +#include + +typedef unsigned chartype; + +#undef strstr + +char * +strstr (const char *phaystack, const char *pneedle) +{ + register const unsigned char *haystack, *needle; + register chartype b, c; + + haystack = (const unsigned char *) phaystack; + needle = (const unsigned char *) pneedle; + + b = *needle; + if (b != '\0') + { + haystack--; /* possible ANSI violation */ + do + { + c = *++haystack; + if (c == '\0') + goto ret0; + } + while (c != b); + + c = *++needle; + if (c == '\0') + goto foundneedle; + ++needle; + goto jin; + + for (;;) + { + register chartype a; + register const unsigned char *rhaystack, *rneedle; + + do + { + a = *++haystack; + if (a == '\0') + goto ret0; + if (a == b) + break; + a = *++haystack; + if (a == '\0') + goto ret0; +shloop:; } + while (a != b); + +jin: a = *++haystack; + if (a == '\0') + goto ret0; + + if (a != c) + goto shloop; + + rhaystack = haystack-- + 1; + rneedle = needle; + a = *rneedle; + + if (*rhaystack == a) + do + { + if (a == '\0') + goto foundneedle; + ++rhaystack; + a = *++needle; + if (*rhaystack != a) + break; + if (a == '\0') + goto foundneedle; + ++rhaystack; + a = *++needle; + } + while (*rhaystack == a); + + needle = rneedle; /* took the register-poor approach */ + + if (a == '\0') + break; + } + } +foundneedle: + return (char*) haystack; +ret0: + return 0; +} diff --git a/utshell-0.5.0/lib/sh/strtod.c b/utshell-0.5.0/lib/sh/strtod.c new file mode 100644 index 00000000..55e11540 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtod.c @@ -0,0 +1,207 @@ +/* strtod.c - convert string to double-precision floating-point value. */ + +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if HAVE_CONFIG_H +# include +#endif + +#ifndef HAVE_STRTOD + +#include +#ifndef errno +extern int errno; +#endif + +#include +#include + +#if HAVE_FLOAT_H +# include +#else +# define DBL_MAX 1.7976931348623159e+308 +# define DBL_MIN 2.2250738585072010e-308 +#endif + +#include + +#ifndef NULL +# define NULL 0 +#endif + +#ifndef HUGE_VAL +# define HUGE_VAL HUGE +#endif + +#ifndef locale_decpoint +extern int locale_decpoint PARAMS((void)); +#endif + +/* Convert NPTR to a double. If ENDPTR is not NULL, a pointer to the + character after the last one used in the number is put in *ENDPTR. */ +double +strtod (nptr, endptr) + const char *nptr; + char **endptr; +{ + register const char *s; + short sign; + + /* The number so far. */ + double num; + + int radixchar; + int got_dot; /* Found a decimal point. */ + int got_digit; /* Seen any digits. */ + + /* The exponent of the number. */ + long int exponent; + + if (nptr == NULL) + { + errno = EINVAL; + goto noconv; + } + + s = nptr; + + /* Eat whitespace. */ + while (ISSPACE ((unsigned char)*s)) + ++s; + + /* Get the sign. */ + sign = *s == '-' ? -1 : 1; + if (*s == '-' || *s == '+') + ++s; + + radixchar = locale_decpoint (); + num = 0.0; + got_dot = 0; + got_digit = 0; + exponent = 0; + for (;; ++s) + { + if (DIGIT (*s)) + { + got_digit = 1; + + /* Make sure that multiplication by 10 will not overflow. */ + if (num > DBL_MAX * 0.1) + /* The value of the digit doesn't matter, since we have already + gotten as many digits as can be represented in a `double'. + This doesn't necessarily mean the result will overflow. + The exponent may reduce it to within range. + + We just need to record that there was another + digit so that we can multiply by 10 later. */ + ++exponent; + else + num = (num * 10.0) + (*s - '0'); + + /* Keep track of the number of digits after the decimal point. + If we just divided by 10 here, we would lose precision. */ + if (got_dot) + --exponent; + } + else if (!got_dot && *s == radixchar) + /* Record that we have found the decimal point. */ + got_dot = 1; + else + /* Any other character terminates the number. */ + break; + } + + if (!got_digit) + goto noconv; + + if (TOLOWER ((unsigned char)*s) == 'e') + { + /* Get the exponent specified after the `e' or `E'. */ + int save = errno; + char *end; + long int exp; + + errno = 0; + ++s; + exp = strtol (s, &end, 10); + if (errno == ERANGE) + { + /* The exponent overflowed a `long int'. It is probably a safe + assumption that an exponent that cannot be represented by + a `long int' exceeds the limits of a `double'. */ + if (endptr != NULL) + *endptr = end; + if (exp < 0) + goto underflow; + else + goto overflow; + } + else if (end == s) + /* There was no exponent. Reset END to point to + the 'e' or 'E', so *ENDPTR will be set there. */ + end = (char *) s - 1; + errno = save; + s = end; + exponent += exp; + } + + if (endptr != NULL) + *endptr = (char *) s; + + if (num == 0.0) + return 0.0; + + /* Multiply NUM by 10 to the EXPONENT power, + checking for overflow and underflow. */ + + if (exponent < 0) + { + if (num < DBL_MIN * pow (10.0, (double) -exponent)) + goto underflow; + } + else if (exponent > 0) + { + if (num > DBL_MAX * pow (10.0, (double) -exponent)) + goto overflow; + } + + num *= pow (10.0, (double) exponent); + + return num * sign; + +overflow: + /* Return an overflow error. */ + errno = ERANGE; + return HUGE_VAL * sign; + +underflow: + /* Return an underflow error. */ + if (endptr != NULL) + *endptr = (char *) nptr; + errno = ERANGE; + return 0.0; + +noconv: + /* There was no number. */ + if (endptr != NULL) + *endptr = (char *) nptr; + return 0.0; +} + +#endif /* !HAVE_STRTOD */ diff --git a/utshell-0.5.0/lib/sh/strtoimax.c b/utshell-0.5.0/lib/sh/strtoimax.c new file mode 100644 index 00000000..676e02ef --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtoimax.c @@ -0,0 +1,113 @@ +/* strtoimax - convert string representation of a number into an intmax_t value. */ + +/* Copyright 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Written by Paul Eggert. Modified by Chet Ramey for Bash. */ + +#if HAVE_CONFIG_H +# include +#endif + +#if HAVE_INTTYPES_H +# include +#endif + +#if HAVE_STDINT_H +# include +#endif + +#if HAVE_STDLIB_H +# include +#endif + +#include + +/* Verify a requirement at compile-time (unlike assert, which is runtime). */ +#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } + +#ifndef HAVE_DECL_STRTOL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOL +extern long strtol PARAMS((const char *, char **, int)); +#endif + +#ifndef HAVE_DECL_STRTOLL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG +extern long long strtoll PARAMS((const char *, char **, int)); +#endif + +#ifdef strtoimax +#undef strtoimax +#endif + +intmax_t +strtoimax (ptr, endptr, base) + const char *ptr; + char **endptr; + int base; +{ +#if HAVE_LONG_LONG + verify(size_is_that_of_long_or_long_long, + (sizeof (intmax_t) == sizeof (long) || + sizeof (intmax_t) == sizeof (long long))); + + if (sizeof (intmax_t) != sizeof (long)) + return (strtoll (ptr, endptr, base)); +#else + verify (size_is_that_of_long, sizeof (intmax_t) == sizeof (long)); +#endif + + return (strtol (ptr, endptr, base)); +} + +#ifdef TESTING +# include +int +main () +{ + char *p, *endptr; + intmax_t x; +#if HAVE_LONG_LONG + long long y; +#endif + long z; + + printf ("sizeof intmax_t: %d\n", sizeof (intmax_t)); + +#if HAVE_LONG_LONG + printf ("sizeof long long: %d\n", sizeof (long long)); +#endif + printf ("sizeof long: %d\n", sizeof (long)); + + x = strtoimax("42", &endptr, 10); +#if HAVE_LONG_LONG + y = strtoll("42", &endptr, 10); +#else + y = -1; +#endif + z = strtol("42", &endptr, 10); + + printf ("%lld %lld %ld\n", x, y, z); + + exit (0); +} +#endif diff --git a/utshell-0.5.0/lib/sh/strtol.c b/utshell-0.5.0/lib/sh/strtol.c new file mode 100644 index 00000000..8aa74788 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtol.c @@ -0,0 +1,259 @@ +/* strtol - convert string representation of a number into a long integer value. */ + +/* Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_STRTOL) + +#include +#include + +#ifndef errno +extern int errno; +#endif + +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif + +#include + +#include +#include + +#ifndef NULL +# define NULL 0 +#endif + +/* Nonzero if we are defining `strtoul' or `strtoull', operating on + unsigned integers. */ +#ifndef UNSIGNED +# define UNSIGNED 0 +# define INT LONG int +#else +# define INT unsigned LONG int +#endif + +#if UNSIGNED +# ifdef QUAD +# define strtol strtoull +# else +# define strtol strtoul +# endif +#else +# ifdef QUAD +# define strtol strtoll +# endif +#endif + +/* If QUAD is defined, we are defining `strtoll' or `strtoull', + operating on `long long ints. */ + +#ifdef QUAD +# define LONG long long +# define STRTOL_LONG_MIN LLONG_MIN +# define STRTOL_LONG_MAX LLONG_MAX +# define STRTOL_ULONG_MAX ULLONG_MAX +#else /* !QUAD */ +# define LONG long +# define STRTOL_LONG_MIN LONG_MIN +# define STRTOL_LONG_MAX LONG_MAX +# define STRTOL_ULONG_MAX ULONG_MAX +#endif + +/* Convert NPTR to an `unsigned long int' or `long int' in base BASE. + If BASE is 0 the base is determined by the presence of a leading + zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. + If BASE is < 2 or > 36, it is no longer reset to 10; EINVAL is returned. + If ENDPTR is not NULL, a pointer to the character after the last + one converted is stored in *ENDPTR. */ + +INT +strtol (nptr, endptr, base) + const char *nptr; + char **endptr; + int base; +{ + int negative; + register unsigned LONG int cutoff; + register unsigned int cutlim; + register unsigned LONG int i; + register const char *s; + register unsigned char c; + const char *save, *end; + int overflow; + + if (base < 0 || base == 1 || base > 36) + { + __set_errno (EINVAL); + return 0; + } + + save = s = nptr; + + /* Skip white space. */ + while (ISSPACE ((unsigned char)*s)) + ++s; + if (*s == '\0') + goto noconv; + + /* Check for a sign. */ + if (*s == '-' || *s == '+') + { + negative = (*s == '-'); + ++s; + } + else + negative = 0; + + /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ + if (*s == '0') + { + if ((base == 0 || base == 16) && TOUPPER ((unsigned char) s[1]) == 'X') + { + s += 2; + base = 16; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; + + /* Save the pointer so we can check later if anything happened. */ + save = s; + + end = NULL; + + cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base; + cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base; + + overflow = 0; + i = 0; + c = *s; + if (sizeof (long int) != sizeof (LONG int)) + { + unsigned long int j = 0; + unsigned long int jmax = ULONG_MAX / base; + + for (;c != '\0'; c = *++s) + { + if (s == end) + break; + if (DIGIT (c)) + c -= '0'; + else if (ISALPHA (c)) + c = TOUPPER (c) - 'A' + 10; + else + break; + + if ((int) c >= base) + break; + /* Note that we never can have an overflow. */ + else if (j >= jmax) + { + /* We have an overflow. Now use the long representation. */ + i = (unsigned LONG int) j; + goto use_long; + } + else + j = j * (unsigned long int) base + c; + } + + i = (unsigned LONG int) j; + } + else + for (;c != '\0'; c = *++s) + { + if (s == end) + break; + if (DIGIT (c)) + c -= '0'; + else if (ISALPHA (c)) + c = TOUPPER (c) - 'A' + 10; + else + break; + if ((int) c >= base) + break; + /* Check for overflow. */ + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + use_long: + i *= (unsigned LONG int) base; + i += c; + } + } + + /* Check if anything actually happened. */ + if (s == save) + goto noconv; + + /* Store in ENDPTR the address of one character + past the last character we converted. */ + if (endptr != NULL) + *endptr = (char *) s; + +#if !UNSIGNED + /* Check for a value that is within the range of + `unsigned LONG int', but outside the range of `LONG int'. */ + if (overflow == 0 + && i > (negative + ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1 + : (unsigned LONG int) STRTOL_LONG_MAX)) + overflow = 1; +#endif + + if (overflow) + { + __set_errno (ERANGE); +#if UNSIGNED + return STRTOL_ULONG_MAX; +#else + return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX; +#endif + } + + /* Return the result of the appropriate sign. */ + return negative ? -i : i; + +noconv: + /* We must handle a special case here: the base is 0 or 16 and the + first two characters are '0' and 'x', but the rest are no + hexadecimal digits. This is no error case. We return 0 and + ENDPTR points to the `x`. */ + if (endptr != NULL) + { + if (save - nptr >= 2 && TOUPPER ((unsigned char) save[-1]) == 'X' && save[-2] == '0') + *endptr = (char *) &save[-1]; + else + /* There was no number to convert. */ + *endptr = (char *) nptr; + } + + return 0L; +} + +#endif /* !HAVE_STRTOL */ diff --git a/utshell-0.5.0/lib/sh/strtoll.c b/utshell-0.5.0/lib/sh/strtoll.c new file mode 100644 index 00000000..f6060eef --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtoll.c @@ -0,0 +1,30 @@ +/* strtoll - convert string representation of a number into a long long value. */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_LONG_LONG) && !defined (HAVE_STRTOLL) + +#define QUAD 1 +#undef HAVE_STRTOL + +#include "strtol.c" + +#endif /* HAVE_LONG_LONG && !HAVE_STRTOLL */ diff --git a/utshell-0.5.0/lib/sh/strtoul.c b/utshell-0.5.0/lib/sh/strtoul.c new file mode 100644 index 00000000..cbaa4845 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtoul.c @@ -0,0 +1,30 @@ +/* strtoul - convert string representation of a number into an unsigned long value. */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#ifndef HAVE_STRTOUL + +#define UNSIGNED 1 +#undef HAVE_STRTOL + +#include + +#endif /* !HAVE_STRTOUL */ diff --git a/utshell-0.5.0/lib/sh/strtoull.c b/utshell-0.5.0/lib/sh/strtoull.c new file mode 100644 index 00000000..02ddebb9 --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtoull.c @@ -0,0 +1,31 @@ +/* strtoull - convert string representation of a number into an unsigned long long value. */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_LONG_LONG) && !defined (HAVE_STRTOULL) + +#define QUAD 1 +#define UNSIGNED 1 +#undef HAVE_STRTOL + +#include "strtol.c" + +#endif /* HAVE_LONG_LONG && !HAVE_STRTOULL */ diff --git a/utshell-0.5.0/lib/sh/strtoumax.c b/utshell-0.5.0/lib/sh/strtoumax.c new file mode 100644 index 00000000..0247e57b --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtoumax.c @@ -0,0 +1,113 @@ +/* strtoumax - convert string representation of a number into an uintmax_t value. */ + +/* Copyright 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Written by Paul Eggert. Modified by Chet Ramey for Bash. */ + +#if HAVE_CONFIG_H +# include +#endif + +#if HAVE_INTTYPES_H +# include +#endif + +#if HAVE_STDINT_H +# include +#endif + +#if HAVE_STDLIB_H +# include +#endif + +#include + +/* Verify a requirement at compile-time (unlike assert, which is runtime). */ +#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } + +#ifndef HAVE_DECL_STRTOUL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOUL +extern unsigned long strtoul PARAMS((const char *, char **, int)); +#endif + +#ifndef HAVE_DECL_STRTOULL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG +extern unsigned long long strtoull PARAMS((const char *, char **, int)); +#endif + +#ifdef strtoumax +#undef strtoumax +#endif + +uintmax_t +strtoumax (ptr, endptr, base) + const char *ptr; + char **endptr; + int base; +{ +#if HAVE_UNSIGNED_LONG_LONG + verify (size_is_that_of_unsigned_long_or_unsigned_long_long, + (sizeof (uintmax_t) == sizeof (unsigned long) || + sizeof (uintmax_t) == sizeof (unsigned long long))); + + if (sizeof (uintmax_t) != sizeof (unsigned long)) + return (strtoull (ptr, endptr, base)); +#else + verify (size_is_that_of_unsigned_long, sizeof (uintmax_t) == sizeof (unsigned long)); +#endif + + return (strtoul (ptr, endptr, base)); +} + +#ifdef TESTING +# include +int +main () +{ + char *p, *endptr; + uintmax_t x; +#if HAVE_UNSIGNED_LONG_LONG + unsigned long long y; +#endif + unsigned long z; + + printf ("sizeof uintmax_t: %d\n", sizeof (uintmax_t)); + +#if HAVE_UNSIGNED_LONG_LONG + printf ("sizeof unsigned long long: %d\n", sizeof (unsigned long long)); +#endif + printf ("sizeof unsigned long: %d\n", sizeof (unsigned long)); + + x = strtoumax("42", &endptr, 10); +#if HAVE_LONG_LONG + y = strtoull("42", &endptr, 10); +#else + y = 0; +#endif + z = strtoul("42", &endptr, 10); + + printf ("%llu %llu %lu\n", x, y, z); + + exit (0); +} +#endif diff --git a/utshell-0.5.0/lib/sh/strtrans.c b/utshell-0.5.0/lib/sh/strtrans.c new file mode 100644 index 00000000..b2b1acca --- /dev/null +++ b/utshell-0.5.0/lib/sh/strtrans.c @@ -0,0 +1,400 @@ +/* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */ + +/* Copyright (C) 2000-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include +#include + +#include "shell.h" + +#include "shmbchar.h" +#include "shmbutil.h" + +#ifdef ESC +#undef ESC +#endif +#define ESC '\033' /* ASCII */ + +/* Convert STRING by expanding the escape sequences specified by the + ANSI C standard. If SAWC is non-null, recognize `\c' and use that + as a string terminator. If we see \c, set *SAWC to 1 before + returning. LEN is the length of STRING. If (FLAGS&1) is non-zero, + that we're translating a string for `echo -e', and therefore should not + treat a single quote as a character that may be escaped with a backslash. + If (FLAGS&2) is non-zero, we're expanding for the parser and want to + quote CTLESC and CTLNUL with CTLESC. If (flags&4) is non-zero, we want + to remove the backslash before any unrecognized escape sequence. */ +char * +ansicstr (string, len, flags, sawc, rlen) + char *string; + int len, flags, *sawc, *rlen; +{ + int c, temp; + char *ret, *r, *s; + unsigned long v; + size_t clen; + int b, mb_cur_max; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc; +#endif + + if (string == 0 || *string == '\0') + return ((char *)NULL); + + mb_cur_max = MB_CUR_MAX; +#if defined (HANDLE_MULTIBYTE) + temp = 4*len + 4; + if (temp < 12) + temp = 12; /* ensure enough for eventual u32cesc */ + ret = (char *)xmalloc (temp); +#else + ret = (char *)xmalloc (2*len + 1); /* 2*len for possible CTLESC */ +#endif + for (r = ret, s = string; s && *s; ) + { + c = *s++; + if (c != '\\' || *s == '\0') + { + clen = 1; +#if defined (HANDLE_MULTIBYTE) + if ((locale_utf8locale && (c & 0x80)) || + (locale_utf8locale == 0 && mb_cur_max > 0 && is_basic (c) == 0)) + { + clen = mbrtowc (&wc, s - 1, mb_cur_max, 0); + if (MB_INVALIDCH (clen)) + clen = 1; + } +#endif + *r++ = c; + for (--clen; clen > 0; clen--) + *r++ = *s++; + } + else + { + switch (c = *s++) + { +#if defined (__STDC__) + case 'a': c = '\a'; break; + case 'v': c = '\v'; break; +#else + case 'a': c = (int) 0x07; break; + case 'v': c = (int) 0x0B; break; +#endif + case 'b': c = '\b'; break; + case 'e': case 'E': /* ESC -- non-ANSI */ + c = ESC; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': +#if 1 + if (flags & 1) + { + *r++ = '\\'; + break; + } + /*FALLTHROUGH*/ +#endif + case '0': + /* If (FLAGS & 1), we're translating a string for echo -e (or + the equivalent xpg_echo option), so we obey the SUSv3/ + POSIX-2001 requirement and accept 0-3 octal digits after + a leading `0'. */ + temp = 2 + ((flags & 1) && (c == '0')); + for (c -= '0'; ISOCTAL (*s) && temp--; s++) + c = (c * 8) + OCTVALUE (*s); + c &= 0xFF; + break; + case 'x': /* Hex digit -- non-ANSI */ + if ((flags & 2) && *s == '{') + { + flags |= 16; /* internal flag value */ + s++; + } + /* Consume at least two hex characters */ + for (temp = 2, c = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++) + c = (c * 16) + HEXVALUE (*s); + /* DGK says that after a `\x{' ksh93 consumes ISXDIGIT chars + until a non-xdigit or `}', so potentially more than two + chars are consumed. */ + if (flags & 16) + { + for ( ; ISXDIGIT ((unsigned char)*s); s++) + c = (c * 16) + HEXVALUE (*s); + flags &= ~16; + if (*s == '}') + s++; + } + /* \x followed by non-hex digits is passed through unchanged */ + else if (temp == 2) + { + *r++ = '\\'; + c = 'x'; + } + c &= 0xFF; + break; +#if defined (HANDLE_MULTIBYTE) + case 'u': + case 'U': + temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ + for (v = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++) + v = (v * 16) + HEXVALUE (*s); + if (temp == ((c == 'u') ? 4 : 8)) + { + *r++ = '\\'; /* c remains unchanged */ + break; + } + else if (v <= 0x7f) /* <= 0x7f translates directly */ + { + c = v; + break; + } + else + { + temp = u32cconv (v, r); + r += temp; + continue; + } +#endif + case '\\': + break; + case '\'': case '"': case '?': + if (flags & 1) + *r++ = '\\'; + break; + case 'c': + if (sawc) + { + *sawc = 1; + *r = '\0'; + if (rlen) + *rlen = r - ret; + return ret; + } + else if ((flags & 1) == 0 && *s == 0) + ; /* pass \c through */ + else if ((flags & 1) == 0 && (c = *s)) + { + s++; + if ((flags & 2) && c == '\\' && c == *s) + s++; /* Posix requires $'\c\\' do backslash escaping */ + c = TOCTRL(c); + break; + } + /*FALLTHROUGH*/ + default: + if ((flags & 4) == 0) + *r++ = '\\'; + break; + } + if ((flags & 2) && (c == CTLESC || c == CTLNUL)) + *r++ = CTLESC; + *r++ = c; + } + } + *r = '\0'; + if (rlen) + *rlen = r - ret; + return ret; +} + +/* Take a string STR, possibly containing non-printing characters, and turn it + into a $'...' ANSI-C style quoted string. Returns a new string. */ +char * +ansic_quote (str, flags, rlen) + char *str; + int flags, *rlen; +{ + char *r, *ret, *s; + int l, rsize; + unsigned char c; + size_t clen; + int b; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc; +#endif + + if (str == 0 || *str == 0) + return ((char *)0); + + l = strlen (str); + rsize = 4 * l + 4; + r = ret = (char *)xmalloc (rsize); + + *r++ = '$'; + *r++ = '\''; + + for (s = str; c = *s; s++) + { + b = l = 1; /* 1 == add backslash; 0 == no backslash */ + clen = 1; + + switch (c) + { + case ESC: c = 'E'; break; +#ifdef __STDC__ + case '\a': c = 'a'; break; + case '\v': c = 'v'; break; +#else + case 0x07: c = 'a'; break; + case 0x0b: c = 'v'; break; +#endif + + case '\b': c = 'b'; break; + case '\f': c = 'f'; break; + case '\n': c = 'n'; break; + case '\r': c = 'r'; break; + case '\t': c = 't'; break; + case '\\': + case '\'': + break; + default: +#if defined (HANDLE_MULTIBYTE) + b = is_basic (c); + /* XXX - clen comparison to 0 is dicey */ + if ((b == 0 && ((clen = mbrtowc (&wc, s, MB_CUR_MAX, 0)) < 0 || MB_INVALIDCH (clen) || iswprint (wc) == 0)) || + (b == 1 && ISPRINT (c) == 0)) +#else + if (ISPRINT (c) == 0) +#endif + { + *r++ = '\\'; + *r++ = TOCHAR ((c >> 6) & 07); + *r++ = TOCHAR ((c >> 3) & 07); + *r++ = TOCHAR (c & 07); + continue; + } + l = 0; + break; + } + if (b == 0 && clen == 0) + break; + + if (l) + *r++ = '\\'; + + if (clen == 1) + *r++ = c; + else + { + for (b = 0; b < (int)clen; b++) + *r++ = (unsigned char)s[b]; + s += clen - 1; /* -1 because of the increment above */ + } + } + + *r++ = '\''; + *r = '\0'; + if (rlen) + *rlen = r - ret; + return ret; +} + +#if defined (HANDLE_MULTIBYTE) +int +ansic_wshouldquote (string) + const char *string; +{ + const wchar_t *wcs; + wchar_t wcc; + wchar_t *wcstr = NULL; + size_t slen; + + slen = mbstowcs (wcstr, string, 0); + + if (slen == (size_t)-1) + return 1; + + wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1)); + mbstowcs (wcstr, string, slen + 1); + + for (wcs = wcstr; wcc = *wcs; wcs++) + if (iswprint(wcc) == 0) + { + free (wcstr); + return 1; + } + + free (wcstr); + return 0; +} +#endif + +/* return 1 if we need to quote with $'...' because of non-printing chars. */ +int +ansic_shouldquote (string) + const char *string; +{ + const char *s; + unsigned char c; + + if (string == 0) + return 0; + + for (s = string; c = *s; s++) + { +#if defined (HANDLE_MULTIBYTE) + if (is_basic (c) == 0) + return (ansic_wshouldquote (s)); +#endif + if (ISPRINT (c) == 0) + return 1; + } + + return 0; +} + +/* $'...' ANSI-C expand the portion of STRING between START and END and + return the result. The result cannot be longer than the input string. */ +char * +ansiexpand (string, start, end, lenp) + char *string; + int start, end, *lenp; +{ + char *temp, *t; + int len, tlen; + + temp = (char *)xmalloc (end - start + 1); + for (tlen = 0, len = start; len < end; ) + temp[tlen++] = string[len++]; + temp[tlen] = '\0'; + + if (*temp) + { + t = ansicstr (temp, tlen, 2, (int *)NULL, lenp); + free (temp); + return (t); + } + else + { + if (lenp) + *lenp = 0; + return (temp); + } +} diff --git a/utshell-0.5.0/lib/sh/times.c b/utshell-0.5.0/lib/sh/times.c new file mode 100644 index 00000000..2423078a --- /dev/null +++ b/utshell-0.5.0/lib/sh/times.c @@ -0,0 +1,77 @@ +/* times.c - times(3) library function */ + +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_TIMES) + +#include +#include +#include + +#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRUSAGE) +# include +#endif /* HAVE_SYS_RESOURCE_H && HAVE_GETRUSAGE */ + +extern long get_clk_tck PARAMS((void)); + +#define CONVTCK(r) (r.tv_sec * clk_tck + r.tv_usec / (1000000 / clk_tck)) + +clock_t +times(tms) + struct tms *tms; +{ + clock_t rv; + static long clk_tck = -1; + +#if defined (HAVE_GETRUSAGE) + struct timeval tv; + struct rusage ru; + + if (clk_tck == -1) + clk_tck = get_clk_tck(); + + if (getrusage(RUSAGE_SELF, &ru) < 0) + return ((clock_t)-1); + tms->tms_utime = CONVTCK(ru.ru_utime); + tms->tms_stime = CONVTCK(ru.ru_stime); + + if (getrusage(RUSAGE_CHILDREN, &ru) < 0) + return ((clock_t)-1); + tms->tms_cutime = CONVTCK(ru.ru_utime); + tms->tms_cstime = CONVTCK(ru.ru_stime); + + if (gettimeofday(&tv, NULL) < 0) + return ((clock_t)-1); + rv = (clock_t)(CONVTCK(tv)); +#else /* !HAVE_GETRUSAGE */ + if (clk_tck == -1) + clk_tck = get_clk_tck(); + + /* We can't do anything. */ + tms->tms_utime = tms->tms_stime = (clock_t)0; + tms->tms_cutime = tms->tms_cstime = (clock_t)0; + + rv = (clock_t)time((time_t *)0) * clk_tck; +# endif /* HAVE_GETRUSAGE */ + + return rv; +} +#endif /* !HAVE_TIMES */ diff --git a/utshell-0.5.0/lib/sh/timeval.c b/utshell-0.5.0/lib/sh/timeval.c new file mode 100644 index 00000000..f2ca7624 --- /dev/null +++ b/utshell-0.5.0/lib/sh/timeval.c @@ -0,0 +1,179 @@ +/* timeval.c - functions to perform operations on struct timevals */ + +/* Copyright (C) 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HAVE_TIMEVAL) + +#include +#include + +#include +#include + +#ifndef locale_decpoint +extern int locale_decpoint PARAMS((void)); +#endif + +#include + +struct timeval * +difftimeval (d, t1, t2) + struct timeval *d, *t1, *t2; +{ + d->tv_sec = t2->tv_sec - t1->tv_sec; + d->tv_usec = t2->tv_usec - t1->tv_usec; + if (d->tv_usec < 0) + { + d->tv_usec += 1000000; + d->tv_sec -= 1; + if (d->tv_sec < 0) /* ??? -- BSD/OS does this */ + { + d->tv_sec = 0; + d->tv_usec = 0; + } + } + return d; +} + +struct timeval * +addtimeval (d, t1, t2) + struct timeval *d, *t1, *t2; +{ + d->tv_sec = t1->tv_sec + t2->tv_sec; + d->tv_usec = t1->tv_usec + t2->tv_usec; + if (d->tv_usec >= 1000000) + { + d->tv_usec -= 1000000; + d->tv_sec += 1; + } + return d; +} + +struct timeval * +multimeval (d, m) + struct timeval *d; + int m; +{ + time_t t; + + t = d->tv_usec * m; + d->tv_sec = d->tv_sec * m + t / 1000000; + d->tv_usec = t % 1000000; + return d; +} + +struct timeval * +divtimeval (d, m) + struct timeval *d; + int m; +{ + time_t t; + + t = d->tv_sec; + d->tv_sec = t / m; + d->tv_usec = (d->tv_usec + 1000000 * (t % m)) / m; + return d; +} + +/* Do "cpu = ((user + sys) * 10000) / real;" with timevals. + Barely-tested code from Deven T. Corzine . */ +int +timeval_to_cpu (rt, ut, st) + struct timeval *rt, *ut, *st; /* real, user, sys */ +{ + struct timeval t1, t2; + register int i; + + addtimeval (&t1, ut, st); + t2.tv_sec = rt->tv_sec; + t2.tv_usec = rt->tv_usec; + + for (i = 0; i < 6; i++) + { + if ((t1.tv_sec > 99999999) || (t2.tv_sec > 99999999)) + break; + t1.tv_sec *= 10; + t1.tv_sec += t1.tv_usec / 100000; + t1.tv_usec *= 10; + t1.tv_usec %= 1000000; + t2.tv_sec *= 10; + t2.tv_sec += t2.tv_usec / 100000; + t2.tv_usec *= 10; + t2.tv_usec %= 1000000; + } + for (i = 0; i < 4; i++) + { + if (t1.tv_sec < 100000000) + t1.tv_sec *= 10; + else + t2.tv_sec /= 10; + } + + return ((t2.tv_sec == 0) ? 0 : t1.tv_sec / t2.tv_sec); +} + +/* Convert a pointer to a struct timeval to seconds and thousandths of a + second, returning the values in *SP and *SFP, respectively. This does + rounding on the fractional part, not just truncation to three places. */ +void +timeval_to_secs (tvp, sp, sfp) + struct timeval *tvp; + time_t *sp; + int *sfp; +{ + int rest; + + *sp = tvp->tv_sec; + + *sfp = tvp->tv_usec % 1000000; /* pretty much a no-op */ + rest = *sfp % 1000; + *sfp = (*sfp * 1000) / 1000000; + if (rest >= 500) + *sfp += 1; + + /* Sanity check */ + if (*sfp >= 1000) + { + *sp += 1; + *sfp -= 1000; + } +} + +/* Print the contents of a struct timeval * in a standard way to stdio + stream FP. */ +void +print_timeval (fp, tvp) + FILE *fp; + struct timeval *tvp; +{ + time_t timestamp; + long minutes; + int seconds, seconds_fraction; + + timeval_to_secs (tvp, ×tamp, &seconds_fraction); + + minutes = timestamp / 60; + seconds = timestamp % 60; + + fprintf (fp, "%ldm%d%c%03ds", minutes, seconds, locale_decpoint (), seconds_fraction); +} + +#endif /* HAVE_TIMEVAL */ diff --git a/utshell-0.5.0/lib/sh/tmpfile.c b/utshell-0.5.0/lib/sh/tmpfile.c new file mode 100644 index 00000000..ef8b067b --- /dev/null +++ b/utshell-0.5.0/lib/sh/tmpfile.c @@ -0,0 +1,311 @@ +/* + * tmpfile.c - functions to create and safely open temp files for the shell. + */ + +/* Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include +#include +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#include +#include + +#include + +#ifndef errno +extern int errno; +#endif + +#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL | O_BINARY) + +#define DEFAULT_TMPDIR "." /* bogus default, should be changed */ +#define DEFAULT_NAMEROOT "shtmp" + +/* Use ANSI-C rand() interface if random(3) is not available */ +#if !HAVE_RANDOM +#define random() rand() +#endif + +extern pid_t dollar_dollar_pid; + +static char *get_sys_tmpdir PARAMS((void)); +static char *get_tmpdir PARAMS((int)); + +static char *sys_tmpdir = (char *)NULL; +static int ntmpfiles; +static int tmpnamelen = -1; +static unsigned long filenum = 1L; + +static char * +get_sys_tmpdir () +{ + if (sys_tmpdir) + return sys_tmpdir; + +#ifdef P_tmpdir + sys_tmpdir = P_tmpdir; + if (file_iswdir (sys_tmpdir)) + return sys_tmpdir; +#endif + + sys_tmpdir = "/tmp"; + if (file_iswdir (sys_tmpdir)) + return sys_tmpdir; + + sys_tmpdir = "/var/tmp"; + if (file_iswdir (sys_tmpdir)) + return sys_tmpdir; + + sys_tmpdir = "/usr/tmp"; + if (file_iswdir (sys_tmpdir)) + return sys_tmpdir; + + sys_tmpdir = DEFAULT_TMPDIR; + + return sys_tmpdir; +} + +static char * +get_tmpdir (flags) + int flags; +{ + char *tdir; + + tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL; + if (tdir && (file_iswdir (tdir) == 0 || strlen (tdir) > PATH_MAX)) + tdir = 0; + + if (tdir == 0) + tdir = get_sys_tmpdir (); + +#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX) + if (tmpnamelen == -1) + tmpnamelen = pathconf (tdir, _PC_NAME_MAX); +#else + tmpnamelen = 0; +#endif + + return tdir; +} + +static void +sh_seedrand () +{ +#if HAVE_RANDOM + int d; + static int seeded = 0; + if (seeded == 0) + { + struct timeval tv; + + gettimeofday (&tv, NULL); + srandom (tv.tv_sec ^ tv.tv_usec ^ (getpid () << 16) ^ (uintptr_t)&d); + seeded = 1; + } +#endif +} + +char * +sh_mktmpname (nameroot, flags) + char *nameroot; + int flags; +{ + char *filename, *tdir, *lroot; + struct stat sb; + int r, tdlen; + static int seeded = 0; + + filename = (char *)xmalloc (PATH_MAX + 1); + tdir = get_tmpdir (flags); + tdlen = strlen (tdir); + + lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; + if (nameroot == 0) + flags &= ~MT_TEMPLATE; + + if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX) + flags &= ~MT_TEMPLATE; + +#ifdef USE_MKTEMP + if (flags & MT_TEMPLATE) + strcpy (filename, nameroot); + else + sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); + if (mktemp (filename) == 0) + { + free (filename); + filename = NULL; + } +#else /* !USE_MKTEMP */ + sh_seedrand (); + while (1) + { + filenum = (filenum << 1) ^ + (unsigned long) time ((time_t *)0) ^ + (unsigned long) dollar_dollar_pid ^ + (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); + sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); + if (tmpnamelen > 0 && tmpnamelen < 32) + filename[tdlen + 1 + tmpnamelen] = '\0'; +# ifdef HAVE_LSTAT + r = lstat (filename, &sb); +# else + r = stat (filename, &sb); +# endif + if (r < 0 && errno == ENOENT) + break; + } +#endif /* !USE_MKTEMP */ + + return filename; +} + +int +sh_mktmpfd (nameroot, flags, namep) + char *nameroot; + int flags; + char **namep; +{ + char *filename, *tdir, *lroot; + int fd, tdlen; + + filename = (char *)xmalloc (PATH_MAX + 1); + tdir = get_tmpdir (flags); + tdlen = strlen (tdir); + + lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; + if (nameroot == 0) + flags &= ~MT_TEMPLATE; + + if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX) + flags &= ~MT_TEMPLATE; + +#ifdef USE_MKSTEMP + if (flags & MT_TEMPLATE) + strcpy (filename, nameroot); + else + sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); + fd = mkstemp (filename); + if (fd < 0 || namep == 0) + { + free (filename); + filename = NULL; + } + if (namep) + *namep = filename; + return fd; +#else /* !USE_MKSTEMP */ + sh_seedrand (); + do + { + filenum = (filenum << 1) ^ + (unsigned long) time ((time_t *)0) ^ + (unsigned long) dollar_dollar_pid ^ + (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); + sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); + if (tmpnamelen > 0 && tmpnamelen < 32) + filename[tdlen + 1 + tmpnamelen] = '\0'; + fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600); + } + while (fd < 0 && errno == EEXIST); + + if (namep) + *namep = filename; + else + free (filename); + + return fd; +#endif /* !USE_MKSTEMP */ +} + +FILE * +sh_mktmpfp (nameroot, flags, namep) + char *nameroot; + int flags; + char **namep; +{ + int fd; + FILE *fp; + + fd = sh_mktmpfd (nameroot, flags, namep); + if (fd < 0) + return ((FILE *)NULL); + fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w"); + if (fp == 0) + close (fd); + return fp; +} + +char * +sh_mktmpdir (nameroot, flags) + char *nameroot; + int flags; +{ + char *filename, *tdir, *lroot, *dirname; + int fd, tdlen; + +#ifdef USE_MKDTEMP + filename = (char *)xmalloc (PATH_MAX + 1); + tdir = get_tmpdir (flags); + tdlen = strlen (tdir); + + lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; + if (nameroot == 0) + flags &= ~MT_TEMPLATE; + + if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX) + flags &= ~MT_TEMPLATE; + + if (flags & MT_TEMPLATE) + strcpy (filename, nameroot); + else + sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); + dirname = mkdtemp (filename); + if (dirname == 0) + { + free (filename); + filename = NULL; + } + return dirname; +#else /* !USE_MKDTEMP */ + filename = (char *)NULL; + do + { + filename = sh_mktmpname (nameroot, flags); + fd = mkdir (filename, 0700); + if (fd == 0) + break; + free (filename); + filename = (char *)NULL; + } + while (fd < 0 && errno == EEXIST); + + return (filename); +#endif /* !USE_MKDTEMP */ +} diff --git a/utshell-0.5.0/lib/sh/uconvert.c b/utshell-0.5.0/lib/sh/uconvert.c new file mode 100644 index 00000000..457552eb --- /dev/null +++ b/utshell-0.5.0/lib/sh/uconvert.c @@ -0,0 +1,124 @@ +/* uconvert - convert string representations of decimal numbers into whole + number/fractional value pairs. */ + +/* Copyright (C) 2008,2009,2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include "bashtypes.h" + +#include "posixtime.h" + +#if defined (HAVE_UNISTD_H) +#include +#endif + +#include +#include "chartypes.h" + +#include "shell.h" +#include "builtins.h" + +#define DECIMAL '.' /* XXX - should use locale */ + +#define RETURN(x) \ +do { \ + if (ip) *ip = ipart * mult; \ + if (up) *up = upart; \ + if (ep) *ep = p; \ + return (x); \ +} while (0) + +/* + * An incredibly simplistic floating point converter. + */ +static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 }; + +/* Take a decimal number int-part[.[micro-part]] and convert it to the whole + and fractional portions. The fractional portion is returned in + millionths (micro); callers are responsible for multiplying appropriately. + EP, if non-null, gets the address of the character where conversion stops. + Return 1 if value converted; 0 if invalid integer for either whole or + fractional parts. */ +int +uconvert(s, ip, up, ep) + char *s; + long *ip, *up; + char **ep; +{ + int n, mult; + long ipart, upart; + char *p; + + ipart = upart = 0; + mult = 1; + + if (s && (*s == '-' || *s == '+')) + { + mult = (*s == '-') ? -1 : 1; + p = s + 1; + } + else + p = s; + + for ( ; p && *p; p++) + { + if (*p == DECIMAL) /* decimal point */ + break; + if (DIGIT(*p) == 0) + RETURN(0); + ipart = (ipart * 10) + (*p - '0'); + } + + if (p == 0 || *p == 0) /* callers ensure p can never be 0; this is to shut up clang */ + RETURN(1); + + if (*p == DECIMAL) + p++; + + /* Look for up to six digits past a decimal point. */ + for (n = 0; n < 6 && p[n]; n++) + { + if (DIGIT(p[n]) == 0) + { + if (ep) + { + upart *= multiplier[n]; + p += n; /* To set EP */ + } + RETURN(0); + } + upart = (upart * 10) + (p[n] - '0'); + } + + /* Now convert to millionths */ + upart *= multiplier[n]; + + if (n == 6 && p[6] >= '5' && p[6] <= '9') + upart++; /* round up 1 */ + + if (ep) + { + p += n; + while (DIGIT(*p)) + p++; + } + + RETURN(1); +} diff --git a/utshell-0.5.0/lib/sh/ufuncs.c b/utshell-0.5.0/lib/sh/ufuncs.c new file mode 100644 index 00000000..4dc4853b --- /dev/null +++ b/utshell-0.5.0/lib/sh/ufuncs.c @@ -0,0 +1,140 @@ +/* ufuncs - sleep and alarm functions that understand fractional values */ + +/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include "bashtypes.h" + +#include "posixtime.h" + +#if defined (HAVE_UNISTD_H) +#include +#endif + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if defined (HAVE_SELECT) +# include "posixselect.h" +# include "quit.h" +# include "trap.h" +# include "stat-time.h" +#endif + +/* A version of `alarm' using setitimer if it's available. */ + +#if defined (HAVE_SETITIMER) +unsigned int +falarm(secs, usecs) + unsigned int secs, usecs; +{ + struct itimerval it, oit; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + it.it_value.tv_sec = secs; + it.it_value.tv_usec = usecs; + + if (setitimer(ITIMER_REAL, &it, &oit) < 0) + return (-1); /* XXX will be converted to unsigned */ + + /* Backwards compatibility with alarm(3) */ + if (oit.it_value.tv_usec) + oit.it_value.tv_sec++; + return (oit.it_value.tv_sec); +} +#else +int +falarm (secs, usecs) + unsigned int secs, usecs; +{ + if (secs == 0 && usecs == 0) + return (alarm (0)); + + if (secs == 0 || usecs >= 500000) + { + secs++; + usecs = 0; + } + return (alarm (secs)); +} +#endif /* !HAVE_SETITIMER */ + +/* A version of sleep using fractional seconds and select. I'd like to use + `usleep', but it's already taken */ + +#if defined (HAVE_TIMEVAL) && (defined (HAVE_SELECT) || defined (HAVE_PSELECT)) +int +fsleep(sec, usec) + unsigned int sec, usec; +{ + int e, r; + sigset_t blocked_sigs, prevmask; +#if defined (HAVE_PSELECT) + struct timespec ts; +#else + struct timeval tv; +#endif + + sigemptyset (&blocked_sigs); +# if defined (SIGCHLD) + sigaddset (&blocked_sigs, SIGCHLD); +# endif + +#if defined (HAVE_PSELECT) + ts.tv_sec = sec; + ts.tv_nsec = usec * 1000; +#else + sigemptyset (&prevmask); + tv.tv_sec = sec; + tv.tv_usec = usec; +#endif /* !HAVE_PSELECT */ + + do + { +#if defined (HAVE_PSELECT) + r = pselect(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &ts, &blocked_sigs); +#else + sigprocmask (SIG_SETMASK, &blocked_sigs, &prevmask); + r = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv); + sigprocmask (SIG_SETMASK, &prevmask, NULL); +#endif + e = errno; + if (r < 0 && errno == EINTR) + return -1; /* caller will handle */ + errno = e; + } + while (r < 0 && errno == EINTR); + + return r; +} +#else /* !HAVE_TIMEVAL || !HAVE_SELECT */ +int +fsleep(sec, usec) + long sec, usec; +{ + if (usec >= 500000) /* round */ + sec++; + return (sleep(sec)); +} +#endif /* !HAVE_TIMEVAL || !HAVE_SELECT */ diff --git a/utshell-0.5.0/lib/sh/unicode.c b/utshell-0.5.0/lib/sh/unicode.c new file mode 100644 index 00000000..d95d1e25 --- /dev/null +++ b/utshell-0.5.0/lib/sh/unicode.c @@ -0,0 +1,339 @@ +/* unicode.c - functions to convert unicode characters */ + +/* Copyright (C) 2010-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HANDLE_MULTIBYTE) + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#if HAVE_ICONV +# include +#endif + +#include + +#ifndef USHORT_MAX +# ifdef USHRT_MAX +# define USHORT_MAX USHRT_MAX +# else +# define USHORT_MAX ((unsigned short) ~(unsigned short)0) +# endif +#endif + +#if !defined (STREQ) +# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0) +#endif /* !STREQ */ + +#if defined (HAVE_LOCALE_CHARSET) +extern const char *locale_charset PARAMS((void)); +#else +extern char *get_locale_var PARAMS((char *)); +#endif + +extern int locale_utf8locale; + +static int u32init = 0; +static int utf8locale = 0; +#if defined (HAVE_ICONV) +static iconv_t localconv; +#endif + +#ifndef HAVE_LOCALE_CHARSET +static char charsetbuf[40]; + +static char * +stub_charset () +{ + char *locale, *s, *t; + + locale = get_locale_var ("LC_CTYPE"); + if (locale == 0 || *locale == 0) + { + strcpy (charsetbuf, "ASCII"); + return charsetbuf; + } + s = strrchr (locale, '.'); + if (s) + { + strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1); + charsetbuf[sizeof (charsetbuf) - 1] = '\0'; + t = strchr (charsetbuf, '@'); + if (t) + *t = 0; + return charsetbuf; + } + strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1); + charsetbuf[sizeof (charsetbuf) - 1] = '\0'; + return charsetbuf; +} +#endif + +void +u32reset () +{ +#if defined (HAVE_ICONV) + if (u32init && localconv != (iconv_t)-1) + { + iconv_close (localconv); + localconv = (iconv_t)-1; + } +#endif + u32init = 0; + utf8locale = 0; +} + +/* u32toascii ? */ +int +u32tochar (x, s) + unsigned long x; + char *s; +{ + int l; + + l = (x <= UCHAR_MAX) ? 1 : ((x <= USHORT_MAX) ? 2 : 4); + + if (x <= UCHAR_MAX) + s[0] = x & 0xFF; + else if (x <= USHORT_MAX) /* assume unsigned short = 16 bits */ + { + s[0] = (x >> 8) & 0xFF; + s[1] = x & 0xFF; + } + else + { + s[0] = (x >> 24) & 0xFF; + s[1] = (x >> 16) & 0xFF; + s[2] = (x >> 8) & 0xFF; + s[3] = x & 0xFF; + } + s[l] = '\0'; + return l; +} + +int +u32tocesc (wc, s) + u_bits32_t wc; + char *s; +{ + int l; + + if (wc < 0x10000) + l = sprintf (s, "\\u%04X", wc); + else + l = sprintf (s, "\\u%08X", wc); + return l; +} + +/* Convert unsigned 32-bit int to utf-8 character string */ +int +u32toutf8 (wc, s) + u_bits32_t wc; + char *s; +{ + int l; + + if (wc < 0x0080) + { + s[0] = (char)wc; + l = 1; + } + else if (wc < 0x0800) + { + s[0] = (wc >> 6) | 0xc0; + s[1] = (wc & 0x3f) | 0x80; + l = 2; + } + else if (wc < 0x10000) + { + /* Technically, we could return 0 here if 0xd800 <= wc <= 0x0dfff */ + s[0] = (wc >> 12) | 0xe0; + s[1] = ((wc >> 6) & 0x3f) | 0x80; + s[2] = (wc & 0x3f) | 0x80; + l = 3; + } + else if (wc < 0x200000) + { + s[0] = (wc >> 18) | 0xf0; + s[1] = ((wc >> 12) & 0x3f) | 0x80; + s[2] = ((wc >> 6) & 0x3f) | 0x80; + s[3] = (wc & 0x3f) | 0x80; + l = 4; + } + /* Strictly speaking, UTF-8 doesn't have characters longer than 4 bytes */ + else if (wc < 0x04000000) + { + s[0] = (wc >> 24) | 0xf8; + s[1] = ((wc >> 18) & 0x3f) | 0x80; + s[2] = ((wc >> 12) & 0x3f) | 0x80; + s[3] = ((wc >> 6) & 0x3f) | 0x80; + s[4] = (wc & 0x3f) | 0x80; + l = 5; + } + else if (wc < 0x080000000) + { + s[0] = (wc >> 30) | 0xfc; + s[1] = ((wc >> 24) & 0x3f) | 0x80; + s[2] = ((wc >> 18) & 0x3f) | 0x80; + s[3] = ((wc >> 12) & 0x3f) | 0x80; + s[4] = ((wc >> 6) & 0x3f) | 0x80; + s[5] = (wc & 0x3f) | 0x80; + l = 6; + } + else + l = 0; + + s[l] = '\0'; + return l; +} + +/* Convert a 32-bit unsigned int (unicode) to a UTF-16 string. Rarely used, + only if sizeof(wchar_t) == 2. */ +int +u32toutf16 (c, s) + u_bits32_t c; + wchar_t *s; +{ + int l; + + l = 0; + if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff)) + { + s[0] = (wchar_t) (c & 0xFFFF); + l = 1; + } + else if (c >= 0x10000 && c <= 0x010ffff) + { + c -= 0x010000; + s[0] = (wchar_t)((c >> 10) + 0xd800); + s[1] = (wchar_t)((c & 0x3ff) + 0xdc00); + l = 2; + } + s[l] = 0; + return l; +} + +/* convert a single unicode-32 character into a multibyte string and put the + result in S, which must be large enough (at least max(10,MB_LEN_MAX) bytes) */ +int +u32cconv (c, s) + unsigned long c; + char *s; +{ + wchar_t wc; + wchar_t ws[3]; + int n; +#if HAVE_ICONV + const char *charset; + char obuf[25], *optr; + size_t obytesleft; + const char *iptr; + size_t sn; +#endif + +#if __STDC_ISO_10646__ + wc = c; + if (sizeof (wchar_t) == 4 && c <= 0x7fffffff) + n = wctomb (s, wc); + else if (sizeof (wchar_t) == 2 && c <= 0x10ffff && u32toutf16 (c, ws)) + n = wcstombs (s, ws, MB_LEN_MAX); + else + n = -1; + if (n != -1) + return n; +#endif + +#if HAVE_ICONV + /* this is mostly from coreutils-8.5/lib/unicodeio.c */ + if (u32init == 0) + { + utf8locale = locale_utf8locale; + localconv = (iconv_t)-1; + if (utf8locale == 0) + { +#if HAVE_LOCALE_CHARSET + charset = locale_charset (); +#elif HAVE_NL_LANGINFO + charset = nl_langinfo (CODESET); +#else + charset = stub_charset (); +#endif + localconv = iconv_open (charset, "UTF-8"); + if (localconv == (iconv_t)-1) + /* We assume ASCII when presented with an unknown encoding. */ + localconv = iconv_open ("ASCII", "UTF-8"); + } + u32init = 1; + } + + /* NL_LANGINFO and locale_charset used when setting locale_utf8locale */ + + /* If we have a UTF-8 locale, convert to UTF-8 and return converted value. */ + n = u32toutf8 (c, s); + if (utf8locale) + return n; + + /* If the conversion is not supported, even the ASCII requested above, we + bail now. Currently we return the UTF-8 conversion. We could return + u32tocesc(). */ + if (localconv == (iconv_t)-1) + return n; + + optr = obuf; + obytesleft = sizeof (obuf); + iptr = s; + sn = n; + + iconv (localconv, NULL, NULL, NULL, NULL); + + if (iconv (localconv, (ICONV_CONST char **)&iptr, &sn, &optr, &obytesleft) == (size_t)-1) + { + /* You get ISO C99 escape sequences if iconv fails */ + n = u32tocesc (c, s); + return n; + } + + *optr = '\0'; + + /* number of chars to be copied is optr - obuf if we want to do bounds + checking */ + strcpy (s, obuf); + return (optr - obuf); +#endif /* HAVE_ICONV */ + + if (locale_utf8locale) + n = u32toutf8 (c, s); + else + n = u32tocesc (c, s); /* fallback is ISO C99 escape sequences */ + return n; +} +#else +void +u32reset () +{ +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/utshell-0.5.0/lib/sh/utf8.c b/utshell-0.5.0/lib/sh/utf8.c new file mode 100644 index 00000000..fed25226 --- /dev/null +++ b/utshell-0.5.0/lib/sh/utf8.c @@ -0,0 +1,196 @@ +/* utf8.c - UTF-8 character handling functions */ + +/* Copyright (C) 2018 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#ifdef HAVE_STDLIB_H +# include +#endif + +#include "bashansi.h" +#include "shmbutil.h" + +extern int locale_mb_cur_max; +extern int locale_utf8locale; + +#if defined (HANDLE_MULTIBYTE) + +char * +utf8_mbschr (s, c) + const char *s; + int c; +{ + return strchr (s, c); /* for now */ +} + +int +utf8_mbscmp (s1, s2) + const char *s1, *s2; +{ + /* Use the fact that the UTF-8 encoding preserves lexicographic order. */ + return strcmp (s1, s2); +} + +char * +utf8_mbsmbchar (str) + const char *str; +{ + register char *s; + + for (s = (char *)str; *s; s++) + if ((*s & 0xc0) == 0x80) + return s; + return (0); +} + +int +utf8_mbsnlen(src, srclen, maxlen) + const char *src; + size_t srclen; + int maxlen; +{ + register int sind, count; + + for (sind = count = 0; src[sind] && sind <= maxlen; sind++) + { + if ((src[sind] & 0xc0) != 0x80) + count++; + } + return (count); +} + +/* Adapted from GNU gnulib. Handles UTF-8 characters up to 4 bytes long */ +int +utf8_mblen (s, n) + const char *s; + size_t n; +{ + unsigned char c, c1, c2, c3; + + if (s == 0) + return (0); /* no shift states */ + if (n <= 0) + return (-1); + + c = (unsigned char)*s; + if (c < 0x80) + return (c != 0); + if (c >= 0xc2) + { + c1 = (unsigned char)s[1]; + if (c < 0xe0) + { + if (n == 1) + return -2; + + /* + * c c1 + * + * U+0080..U+07FF C2..DF 80..BF + */ + + if (n >= 2 && (c1 ^ 0x80) < 0x40) /* 0x80..0xbf */ + return 2; + } + else if (c < 0xf0) + { + if (n == 1) + return -2; + + /* + * c c1 c2 + * + * U+0800..U+0FFF E0 A0..BF 80..BF + * U+1000..U+CFFF E1..EC 80..BF 80..BF + * U+D000..U+D7FF ED 80..9F 80..BF + * U+E000..U+FFFF EE..EF 80..BF 80..BF + */ + + if ((c1 ^ 0x80) < 0x40 + && (c >= 0xe1 || c1 >= 0xa0) + && (c != 0xed || c1 < 0xa0)) + { + if (n == 2) + return -2; /* incomplete */ + + c2 = (unsigned char)s[2]; + if ((c2 ^ 0x80) < 0x40) + return 3; + } + } + else if (c <= 0xf4) + { + if (n == 1) + return -2; + + /* + * c c1 c2 c3 + * + * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF + * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF + * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF + */ + if (((c1 ^ 0x80) < 0x40) + && (c >= 0xf1 || c1 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c1 < 0x90))) + { + if (n == 2) + return -2; /* incomplete */ + + c2 = (unsigned char)s[2]; + if ((c2 ^ 0x80) < 0x40) + { + if (n == 3) + return -2; + + c3 = (unsigned char)s[3]; + if ((c3 ^ 0x80) < 0x40) + return 4; + } + } + } + } + /* invalid or incomplete multibyte character */ + return -1; +} + +/* We can optimize this if we know the locale is UTF-8, but needs to handle + malformed byte sequences. */ +size_t +utf8_mbstrlen(s) + const char *s; +{ + size_t clen, nc; + int mb_cur_max; + + nc = 0; + mb_cur_max = MB_CUR_MAX; + while (*s && (clen = (size_t)utf8_mblen(s, mb_cur_max)) != 0) + { + if (MB_INVALIDCH(clen)) + clen = 1; /* assume single byte */ + + s += clen; + nc++; + } + return nc; +} + +#endif diff --git a/utshell-0.5.0/lib/sh/vprint.c b/utshell-0.5.0/lib/sh/vprint.c new file mode 100644 index 00000000..567fba38 --- /dev/null +++ b/utshell-0.5.0/lib/sh/vprint.c @@ -0,0 +1,85 @@ +/* vprint.c -- v[fs]printf() for 4.[23] BSD systems. */ + +/* Copyright (C) 1987,1989 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (USE_VFPRINTF_EMULATION) + +#include + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *)0) +# else +# define NULL 0x0 +# endif /* __STDC__ */ +#endif /* !NULL */ + +/* + * Beware! Don't trust the value returned by either of these functions; it + * seems that pre-4.3-tahoe implementations of _doprnt () return the first + * argument, i.e. a char *. + */ +#include + +int +vfprintf (iop, fmt, ap) + FILE *iop; + char *fmt; + va_list ap; +{ + int len; + char localbuf[BUFSIZ]; + + if (iop->_flag & _IONBF) + { + iop->_flag &= ~_IONBF; + iop->_ptr = iop->_base = localbuf; + len = _doprnt (fmt, ap, iop); + (void) fflush (iop); + iop->_flag |= _IONBF; + iop->_base = NULL; + iop->_bufsiz = 0; + iop->_cnt = 0; + } + else + len = _doprnt (fmt, ap, iop); + return (ferror (iop) ? EOF : len); +} + +/* + * Ditto for vsprintf + */ +int +vsprintf (str, fmt, ap) + char *str, *fmt; + va_list ap; +{ + FILE f; + int len; + + f._flag = _IOWRT|_IOSTRG; + f._ptr = str; + f._cnt = 32767; + len = _doprnt (fmt, ap, &f); + *f._ptr = 0; + return (len); +} +#endif /* USE_VFPRINTF_EMULATION */ diff --git a/utshell-0.5.0/lib/sh/wcsdup.c b/utshell-0.5.0/lib/sh/wcsdup.c new file mode 100644 index 00000000..62a3c864 --- /dev/null +++ b/utshell-0.5.0/lib/sh/wcsdup.c @@ -0,0 +1,44 @@ +/* wcsdup.c - duplicate wide character string */ + +/* Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE) + +#include +#include +#include +#include + +wchar_t * +wcsdup (ws) + const wchar_t *ws; +{ + wchar_t *ret; + size_t len; + + len = wcslen (ws); + ret = xmalloc ((len + 1) * sizeof (wchar_t)); + if (ret == 0) + return ret; + + return (wcscpy (ret, ws)); +} +#endif /* !HAVE_WCSDUP && HANDLE_MULTIBYTE */ diff --git a/utshell-0.5.0/lib/sh/wcsnwidth.c b/utshell-0.5.0/lib/sh/wcsnwidth.c new file mode 100644 index 00000000..9c7e7cc5 --- /dev/null +++ b/utshell-0.5.0/lib/sh/wcsnwidth.c @@ -0,0 +1,56 @@ +/* wcsnwidth.c - compute display width of wide character string, up to max + specified width, return length. */ + +/* Copyright (C) 2012 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HANDLE_MULTIBYTE) + +#include +#include +#include + +/* Return the number of wide characters that will be displayed from wide string + PWCS. If the display width exceeds MAX, return the number of wide chars + from PWCS required to display MAX characters on the screen. */ +int +wcsnwidth(pwcs, n, max) + const wchar_t *pwcs; + size_t n, max; +{ + wchar_t wc, *ws; + int len, l; + + len = 0; + ws = (wchar_t *)pwcs; + while (n-- > 0 && (wc = *ws++) != L'\0') + { + l = wcwidth (wc); + if (l < 0) + return (-1); + else if (l == max - len) + return (ws - pwcs); + else if (l > max - len) + return (--ws - pwcs); + len += l; + } + return (ws - pwcs); +} +#endif diff --git a/utshell-0.5.0/lib/sh/wcswidth.c b/utshell-0.5.0/lib/sh/wcswidth.c new file mode 100644 index 00000000..1a30d9fc --- /dev/null +++ b/utshell-0.5.0/lib/sh/wcswidth.c @@ -0,0 +1,46 @@ +/* wcswidth.c - compute display width of wide character string */ + +/* Copyright (C) 2010 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#if defined (HANDLE_MULTIBYTE) && !defined (HAVE_WCSWIDTH) + +#include +#include +#include + +int +wcswidth(pwcs, n) + const wchar_t *pwcs; + size_t n; +{ + wchar_t wc; + int len, l; + + len = 0; + while (n-- > 0 && (wc = *pwcs++) != L'\0') + { + if ((l = wcwidth(wc)) < 0) + return (-1); + len += l; + } + return (len); +} +#endif diff --git a/utshell-0.5.0/lib/sh/winsize.c b/utshell-0.5.0/lib/sh/winsize.c new file mode 100644 index 00000000..861c7c89 --- /dev/null +++ b/utshell-0.5.0/lib/sh/winsize.c @@ -0,0 +1,98 @@ +/* winsize.c - handle window size changes and information. */ + +/* Copyright (C) 2005-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */ + +#if 0 +#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) +# include +#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ +#endif + +#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# include +#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +/* Not in either of the standard places, look around. */ +#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# if defined (HAVE_SYS_STREAM_H) +# include +# endif /* HAVE_SYS_STREAM_H */ +# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */ +# include +# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */ +# endif /* HAVE_SYS_PTEM_H */ +# if defined (HAVE_SYS_PTE_H) /* ??? */ +# include +# endif /* HAVE_SYS_PTE_H */ +#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +#include + +/* Return the fd from which we are actually getting input. */ +#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr) + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern int shell_tty; + +#if defined (READLINE) +extern void rl_set_screen_size PARAMS((int, int)); +#endif +extern void sh_set_lines_and_columns PARAMS((int, int)); + +void +get_new_window_size (from_sig, rp, cp) + int from_sig; + int *rp, *cp; +{ +#if defined (TIOCGWINSZ) + struct winsize win; + int tty; + + tty = input_tty (); + if (tty >= 0 && (ioctl (tty, TIOCGWINSZ, &win) == 0) && + win.ws_row > 0 && win.ws_col > 0) + { + sh_set_lines_and_columns (win.ws_row, win.ws_col); +#if defined (READLINE) + rl_set_screen_size (win.ws_row, win.ws_col); + if (rp) + *rp = win.ws_row; + if (cp) + *cp = win.ws_col; +#endif + } +#endif +} diff --git a/utshell-0.5.0/lib/sh/zcatfd.c b/utshell-0.5.0/lib/sh/zcatfd.c new file mode 100644 index 00000000..aa8199fd --- /dev/null +++ b/utshell-0.5.0/lib/sh/zcatfd.c @@ -0,0 +1,74 @@ +/* zcatfd - copy contents of file descriptor to another */ + +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#include + +#if !defined (errno) +extern int errno; +#endif + +#ifndef ZBUFSIZ +# define ZBUFSIZ 4096 +#endif + +extern ssize_t zread PARAMS((int, char *, size_t)); +extern int zwrite PARAMS((int, char *, ssize_t)); + +/* Dump contents of file descriptor FD to OFD. FN is the filename for + error messages (not used right now). */ +int +zcatfd (fd, ofd, fn) + int fd, ofd; + char *fn; +{ + ssize_t nr; + int rval; + char lbuf[ZBUFSIZ]; + + rval = 0; + while (1) + { + nr = zread (fd, lbuf, sizeof (lbuf)); + if (nr == 0) + break; + else if (nr < 0) + { + rval = -1; + break; + } + else if (zwrite (ofd, lbuf, nr) < 0) + { + rval = -1; + break; + } + } + + return rval; +} diff --git a/utshell-0.5.0/lib/sh/zgetline.c b/utshell-0.5.0/lib/sh/zgetline.c new file mode 100644 index 00000000..4f6d3eb4 --- /dev/null +++ b/utshell-0.5.0/lib/sh/zgetline.c @@ -0,0 +1,125 @@ +/* zgetline - read a line of input from a specified file descriptor and return + a pointer to a newly-allocated buffer containing the data. */ + +/* Copyright (C) 2008-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include "xmalloc.h" + +#if !defined (errno) +extern int errno; +#endif + +extern ssize_t zread PARAMS((int, char *, size_t)); +extern ssize_t zreadc PARAMS((int, char *)); +extern ssize_t zreadintr PARAMS((int, char *, size_t)); +extern ssize_t zreadcintr PARAMS((int, char *)); + +typedef ssize_t breadfunc_t PARAMS((int, char *, size_t)); +typedef ssize_t creadfunc_t PARAMS((int, char *)); + +/* Initial memory allocation for automatic growing buffer in zreadlinec */ +#define GET_LINE_INITIAL_ALLOCATION 16 + +/* Derived from GNU libc's getline. + The behavior is almost the same as getline. See man getline. + The differences are + (1) using file descriptor instead of FILE *; + (2) the order of arguments: the file descriptor comes first; + (3) the addition of a fourth argument, DELIM; sets the delimiter to + be something other than newline if desired. If setting DELIM, + the next argument should be 1; and + (4) the addition of a fifth argument, UNBUFFERED_READ; this argument + controls whether get_line uses buffering or not to get a byte data + from FD. get_line uses zreadc if UNBUFFERED_READ is zero; and + uses zread if UNBUFFERED_READ is non-zero. + + Returns number of bytes read or -1 on error. */ + +ssize_t +zgetline (fd, lineptr, n, delim, unbuffered_read) + int fd; + char **lineptr; + size_t *n; + int delim; + int unbuffered_read; +{ + int nr, retval; + char *line, c; + if (lineptr == 0 || n == 0 || (*lineptr == 0 && *n != 0)) + return -1; + + nr = 0; + line = *lineptr; + + while (1) + { + //retval = unbuffered_read ? zread (fd, &c, 1) : zreadc(fd, &c); + retval = unbuffered_read ? zreadc(fd, &c) : zreadc(fd, &c); //ä¿®å¤mapfile使用-d傿•°æ—¶æ‰§è¡Œå¤šä½™è¾“入问题 + + if (retval <= 0) + { + if (line && nr > 0) + line[nr] = '\0'; + break; + } + + if (nr + 2 >= *n) + { + size_t new_size; + + new_size = (*n == 0) ? GET_LINE_INITIAL_ALLOCATION : *n * 2; + line = (*n >= new_size) ? NULL : xrealloc (*lineptr, new_size); + + if (line) + { + *lineptr = line; + *n = new_size; + } + else + { + if (*n > 0) + { + (*lineptr)[*n - 1] = '\0'; + nr = *n - 2; + } + break; + } + } + + line[nr] = c; + nr++; + + if (c == delim) + { + line[nr] = '\0'; + break; + } + } + + return nr - 1; +} diff --git a/utshell-0.5.0/lib/sh/zmapfd.c b/utshell-0.5.0/lib/sh/zmapfd.c new file mode 100644 index 00000000..f9e9ed71 --- /dev/null +++ b/utshell-0.5.0/lib/sh/zmapfd.c @@ -0,0 +1,93 @@ +/* zmapfd - read contents of file descriptor into a newly-allocated buffer */ + +/* Copyright (C) 2006-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#include "bashansi.h" +#include "command.h" +#include "general.h" + +#if !defined (errno) +extern int errno; +#endif + +#ifndef ZBUFSIZ +# define ZBUFSIZ 4096 +#endif + +extern ssize_t zread PARAMS((int, char *, size_t)); + +/* Dump contents of file descriptor FD to *OSTR. FN is the filename for + error messages (not used right now). */ +int +zmapfd (fd, ostr, fn) + int fd; + char **ostr; + char *fn; +{ + ssize_t nr; + int rval; + char lbuf[ZBUFSIZ]; + char *result; + int rsize, rind; + + rval = 0; + result = (char *)xmalloc (rsize = ZBUFSIZ); + rind = 0; + + while (1) + { + nr = zread (fd, lbuf, sizeof (lbuf)); + if (nr == 0) + { + rval = rind; + break; + } + else if (nr < 0) + { + free (result); + if (ostr) + *ostr = (char *)NULL; + return -1; + } + + RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, ZBUFSIZ); + memcpy (result+rind, lbuf, nr); + rind += nr; + } + + RESIZE_MALLOCED_BUFFER (result, rind, 1, rsize, 128); + result[rind] = '\0'; + + if (ostr) + *ostr = result; + else + free (result); + + return rval; +} diff --git a/utshell-0.5.0/lib/sh/zread.c b/utshell-0.5.0/lib/sh/zread.c new file mode 100644 index 00000000..71a06a76 --- /dev/null +++ b/utshell-0.5.0/lib/sh/zread.c @@ -0,0 +1,224 @@ +/* zread - read data from file descriptor into buffer with retries */ + +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#if !defined (errno) +extern int errno; +#endif + +#ifndef SEEK_CUR +# define SEEK_CUR 1 +#endif + +#ifndef ZBUFSIZ +# define ZBUFSIZ 4096 +#endif + +extern int executing_builtin; + +extern void check_signals_and_traps (void); +extern void check_signals (void); +extern int signal_is_trapped (int); + +/* Read LEN bytes from FD into BUF. Retry the read on EINTR. Any other + error causes the loop to break. */ +ssize_t +zread (fd, buf, len) + int fd; + char *buf; + size_t len; +{ + ssize_t r; + + check_signals (); /* check for signals before a blocking read */ + while ((r = read (fd, buf, len)) < 0 && errno == EINTR) + { + int t; + t = errno; + /* XXX - bash-5.0 */ + /* We check executing_builtin and run traps here for backwards compatibility */ + if (executing_builtin) + check_signals_and_traps (); /* XXX - should it be check_signals()? */ + else + check_signals (); + errno = t; + } + + return r; +} + +/* Read LEN bytes from FD into BUF. Retry the read on EINTR, up to three + interrupts. Any other error causes the loop to break. */ + +#ifdef NUM_INTR +# undef NUM_INTR +#endif +#define NUM_INTR 3 + +ssize_t +zreadretry (fd, buf, len) + int fd; + char *buf; + size_t len; +{ + ssize_t r; + int nintr; + + for (nintr = 0; ; ) + { + r = read (fd, buf, len); + if (r >= 0) + return r; + if (r == -1 && errno == EINTR) + { + if (++nintr >= NUM_INTR) + return -1; + continue; + } + return r; + } +} + +/* Call read(2) and allow it to be interrupted. Just a stub for now. */ +ssize_t +zreadintr (fd, buf, len) + int fd; + char *buf; + size_t len; +{ + check_signals (); + return (read (fd, buf, len)); +} + +/* Read one character from FD and return it in CP. Return values are as + in read(2). This does some local buffering to avoid many one-character + calls to read(2), like those the `read' builtin performs. */ + +static char lbuf[ZBUFSIZ]; +static size_t lind, lused; + +ssize_t +zreadc (fd, cp) + int fd; + char *cp; +{ + ssize_t nr; + + if (lind == lused || lused == 0) + { + nr = zread (fd, lbuf, sizeof (lbuf)); + lind = 0; + if (nr <= 0) + { + lused = 0; + return nr; + } + lused = nr; + } + if (cp) + *cp = lbuf[lind++]; + return 1; +} + +/* Don't mix calls to zreadc and zreadcintr in the same function, since they + use the same local buffer. */ +ssize_t +zreadcintr (fd, cp) + int fd; + char *cp; +{ + ssize_t nr; + + if (lind == lused || lused == 0) + { + nr = zreadintr (fd, lbuf, sizeof (lbuf)); + lind = 0; + if (nr <= 0) + { + lused = 0; + return nr; + } + lused = nr; + } + if (cp) + *cp = lbuf[lind++]; + return 1; +} + +/* Like zreadc, but read a specified number of characters at a time. Used + for `read -N'. */ +ssize_t +zreadn (fd, cp, len) + int fd; + char *cp; + size_t len; +{ + ssize_t nr; + + if (lind == lused || lused == 0) + { + if (len > sizeof (lbuf)) + len = sizeof (lbuf); + nr = zread (fd, lbuf, len); + lind = 0; + if (nr <= 0) + { + lused = 0; + return nr; + } + lused = nr; + } + if (cp) + *cp = lbuf[lind++]; + return 1; +} + +void +zreset () +{ + lind = lused = 0; +} + +/* Sync the seek pointer for FD so that the kernel's idea of the last char + read is the last char returned by zreadc. */ +void +zsyncfd (fd) + int fd; +{ + off_t off, r; + + off = lused - lind; + r = 0; + if (off > 0) + r = lseek (fd, -off, SEEK_CUR); + + if (r != -1) + lused = lind = 0; +} diff --git a/utshell-0.5.0/lib/sh/zwrite.c b/utshell-0.5.0/lib/sh/zwrite.c new file mode 100644 index 00000000..3240f4f4 --- /dev/null +++ b/utshell-0.5.0/lib/sh/zwrite.c @@ -0,0 +1,64 @@ +/* zwrite - write contents of buffer to file descriptor, retrying on error */ + +/* Copyright (C) 1999-2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#if !defined (errno) +extern int errno; +#endif + +/* Write NB bytes from BUF to file descriptor FD, retrying the write if + it is interrupted. We retry three times if we get a zero-length + write. Any other signal causes this function to return prematurely. */ +int +zwrite (fd, buf, nb) + int fd; + char *buf; + size_t nb; +{ + int n, i, nt; + + for (n = nb, nt = 0;;) + { + i = write (fd, buf, n); + if (i > 0) + { + n -= i; + if (n <= 0) + return nb; + buf += i; + } + else if (i == 0) + { + if (++nt > 3) + return (nb - n); + } + else if (errno != EINTR) + return -1; + } +} diff --git a/utshell-0.5.0/lib/support/config.sub b/utshell-0.5.0/lib/support/config.sub new file mode 100755 index 00000000..a7bc2470 --- /dev/null +++ b/utshell-0.5.0/lib/support/config.sub @@ -0,0 +1,1828 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2016 Free Software Foundation, Inc. + +timestamp='2016-09-05' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | loongarch32 | loongarch64 \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | loongarch32-* | loongarch64-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + echo '33333333333333333333' + echo $os + os=`echo $os | sed 's/[^-]*-//'` + echo $os + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/utshell-0.5.0/lib/termcap/Makefile b/utshell-0.5.0/lib/termcap/Makefile new file mode 100644 index 00000000..7f8a9af6 --- /dev/null +++ b/utshell-0.5.0/lib/termcap/Makefile @@ -0,0 +1,91 @@ +## -*- text -*- #################################################### +# # +# Makefile for termcap replacement libbrary. # +# # +#################################################################### + +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = . + +topdir = ../.. +topdiri = ../include +BUILD_DIR = ../include + +libdir = ${exec_prefix}/lib + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CC = gcc +RANLIB = ranlib +AR = ar +ARFLAGS = cr +RM = rm -f +CP = cp +MV = mv + +SHELL = /bin/sh + +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security -fPIC +CPPFLAGS = +LDFLAGS = -L./lib/termcap + +DEFS = -DHAVE_CONFIG_H + +INCLUDES = -I. -I$(topdiri) -I$(srcdir) + +CCFLAGS = $(CFLAGS) $(DEFS) $(CPPFLAGS) ${INCLUDES} + +# Here is a rule for making .o files from .c files that doesn't force +# the type of the machine (like -sun3) into the flags. +.c.o: + $(CC) -c $(CCFLAGS) $< + +SOURCES = termcap.c tparam.c +OBJECTS = termcap.o tparam.o + +DOCUMENTATION = termcap.texinfo + +THINGS_TO_TAR = $(SOURCES) $(DOCUMENTATION) + +########################################################################## + +all: libtermcap.a + +libtermcap.a: $(OBJECTS) + $(RM) -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +install: + +clean: + $(RM) *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc + +mostlyclean: clean + +distclean maintainer-clean: clean + $(RM) Makefile + +$(DESTDIR)$(libdir)/libtermcap.a: libtermcap.a + ${INSTALL_DATA} -c -m 644 libtermcap.a $@ + -test -n "$(RANLIB)" && $(RANLIB) -t $@ + +termcap.o: $(BUILD_DIR)/config.h +tparam.o: $(BUILD_DIR)/config.h +version.o: $(BUILD_DIR)/config.h diff --git a/utshell-0.5.0/lib/termcap/Makefile.in b/utshell-0.5.0/lib/termcap/Makefile.in new file mode 100644 index 00000000..48c65e32 --- /dev/null +++ b/utshell-0.5.0/lib/termcap/Makefile.in @@ -0,0 +1,92 @@ +## -*- text -*- #################################################### +# # +# Makefile for termcap replacement libbrary. # +# # +#################################################################### + +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = @srcdir@ +VPATH = @srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +libdir = @libdir@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv + +SHELL = @MAKE_SHELL@ + +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + +DEFS = @DEFS@ + +#INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(srcdir) +INCLUDES = -I. -I../include/ -I$(topdir) -I$(topdir)/lib -I$(srcdir) + + +CCFLAGS = $(CFLAGS) $(DEFS) $(CPPFLAGS) ${INCLUDES} + +# Here is a rule for making .o files from .c files that doesn't force +# the type of the machine (like -sun3) into the flags. +.c.o: + $(CC) -c $(CCFLAGS) $< + +SOURCES = termcap.c tparam.c +OBJECTS = termcap.o tparam.o + +DOCUMENTATION = termcap.texinfo + +THINGS_TO_TAR = $(SOURCES) $(DOCUMENTATION) + +########################################################################## + +all: libtermcap.a + +libtermcap.a: $(OBJECTS) + $(RM) -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +install: + +clean: + $(RM) *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc + +mostlyclean: clean + +distclean maintainer-clean: clean + $(RM) Makefile + +$(DESTDIR)$(libdir)/libtermcap.a: libtermcap.a + ${INSTALL_DATA} -c -m 644 libtermcap.a $@ + -test -n "$(RANLIB)" && $(RANLIB) -t $@ + +termcap.o: $(BUILD_DIR)/config.h +tparam.o: $(BUILD_DIR)/config.h +version.o: $(BUILD_DIR)/config.h diff --git a/utshell-0.5.0/lib/termcap/ltcap.h b/utshell-0.5.0/lib/termcap/ltcap.h new file mode 100644 index 00000000..a97f0d8b --- /dev/null +++ b/utshell-0.5.0/lib/termcap/ltcap.h @@ -0,0 +1,30 @@ +/* ltcap.h - Local declarations for termcap library. */ + +/* Copyright (C) 1999-2009 Free Software Foundation, Inc. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _LTCAP_H_ +#define _LTCAP_H_ 1 + +#if !defined (__APPLE__) +# define __private_extern__ +#endif + +#ifndef MAX_TGETENT_BUFSIZ +# define MAX_TGETENT_BUFSIZ 2048 +#endif + +#endif /* _LTCAP_H_ */ diff --git a/utshell-0.5.0/lib/termcap/termcap.c b/utshell-0.5.0/lib/termcap/termcap.c new file mode 100644 index 00000000..ba3dab2c --- /dev/null +++ b/utshell-0.5.0/lib/termcap/termcap.c @@ -0,0 +1,817 @@ +/* termcap.c - Work-alike for termcap, plus extra features. */ + +/* Copyright (C) 1985, 1986, 1993,1994, 1995, 1998, 2001,2003,2005,2006,2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Emacs config.h may rename various library functions such as malloc. */ +#ifdef HAVE_CONFIG_H + +#include + +/* Get the O_* definitions for open et al. */ +#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDLIB_H +# include +#else +extern char *getenv (); +extern char *malloc (); +extern char *realloc (); +#endif + +#if defined (HAVE_STRING_H) +#include +#endif + +#if !defined (HAVE_BCOPY) && (defined (HAVE_STRING_H) || defined (STDC_HEADERS)) +# define bcopy(s, d, n) memcpy ((d), (s), (n)) +#endif + +#else /* not HAVE_CONFIG_H */ + +#ifdef STDC_HEADERS +#include +#include +#else +char *getenv (); +char *malloc (); +char *realloc (); +#endif + +/* Do this after the include, in case string.h prototypes bcopy. */ +#if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy) +#define bcopy(s, d, n) memcpy ((d), (s), (n)) +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef _POSIX_VERSION +#include +#endif + +#endif /* not HAVE_CONFIG_H */ + +#ifndef NULL +#define NULL (char *) 0 +#endif + +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif + +/* BUFSIZE is the initial size allocated for the buffer + for reading the termcap file. + It is not a limit. + Make it large normally for speed. + Make it variable when debugging, so can exercise + increasing the space dynamically. */ + +#ifndef BUFSIZE +#ifdef DEBUG +#define BUFSIZE bufsize + +int bufsize = 128; +#else +#define BUFSIZE 2048 +#endif +#endif + +#include "ltcap.h" + +#ifndef TERMCAP_FILE +#define TERMCAP_FILE "/etc/termcap" +#endif + +#ifndef emacs +static void +memory_out () +{ + write (2, "virtual memory exhausted\n", 25); + exit (1); +} + +static char * +xmalloc (size) + unsigned size; +{ + register char *tem = malloc (size); + + if (!tem) + memory_out (); + return tem; +} + +static char * +xrealloc (ptr, size) + char *ptr; + unsigned size; +{ + register char *tem = realloc (ptr, size); + + if (!tem) + memory_out (); + return tem; +} +#endif /* not emacs */ + +/* Looking up capabilities in the entry already found. */ + +/* The pointer to the data made by tgetent is left here + for tgetnum, tgetflag and tgetstr to find. */ +static char *term_entry; + +static char *tgetst1 (); + +/* Search entry BP for capability CAP. + Return a pointer to the capability (in BP) if found, + 0 if not found. */ + +static char * +find_capability (bp, cap) + register char *bp, *cap; +{ + for (; *bp; bp++) + if (bp[0] == ':' + && bp[1] == cap[0] + && bp[2] == cap[1]) + return &bp[4]; + return NULL; +} + +__private_extern__ +int +tgetnum (cap) + char *cap; +{ + register char *ptr = find_capability (term_entry, cap); + if (!ptr || ptr[-1] != '#') + return -1; + return atoi (ptr); +} + +__private_extern__ +int +tgetflag (cap) + char *cap; +{ + register char *ptr = find_capability (term_entry, cap); + return ptr && ptr[-1] == ':'; +} + +/* Look up a string-valued capability CAP. + If AREA is non-null, it points to a pointer to a block in which + to store the string. That pointer is advanced over the space used. + If AREA is null, space is allocated with `malloc'. */ + +__private_extern__ +char * +tgetstr (cap, area) + char *cap; + char **area; +{ + register char *ptr = find_capability (term_entry, cap); + if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~')) + return NULL; + return tgetst1 (ptr, area); +} + +/* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted, + gives meaning of character following \, or a space if no special meaning. + Eight characters per line within the string. */ + +static char esctab[] + = " \007\010 \033\014 \ + \012 \ + \015 \011 \013 \ + "; + +/* PTR points to a string value inside a termcap entry. + Copy that value, processing \ and ^ abbreviations, + into the block that *AREA points to, + or to newly allocated storage if AREA is NULL. + Return the address to which we copied the value, + or NULL if PTR is NULL. */ + +static char * +tgetst1 (ptr, area) + char *ptr; + char **area; +{ + register char *p, *r; + register int c; + register int size; + char *ret; + register int c1; + + if (!ptr) + return NULL; + + /* `ret' gets address of where to store the string. */ + if (!area) + { + /* Compute size of block needed (may overestimate). */ + p = ptr; + while ((c = *p++) && c != ':' && c != '\n') + ; + ret = (char *) xmalloc (p - ptr + 1); + } + else + ret = *area; + + /* Copy the string value, stopping at null or colon. + Also process ^ and \ abbreviations. */ + p = ptr; + r = ret; + while ((c = *p++) && c != ':' && c != '\n') + { + if (c == '^') + { + c = *p++; + if (c == '?') + c = 0177; + else + c &= 037; + } + else if (c == '\\') + { + c = *p++; + if (c >= '0' && c <= '7') + { + c -= '0'; + size = 0; + + while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7') + { + c *= 8; + c += c1 - '0'; + p++; + } + } + else if (c >= 0100 && c < 0200) + { + c1 = esctab[(c & ~040) - 0100]; + if (c1 != ' ') + c = c1; + } + } + *r++ = c; + } + *r = '\0'; + /* Update *AREA. */ + if (area) + *area = r + 1; + return ret; +} + +/* Outputting a string with padding. */ + +short ospeed; +/* If OSPEED is 0, we use this as the actual baud rate. */ +int tputs_baud_rate; +__private_extern__ char PC = '\0'; + +/* Actual baud rate if positive; + - baud rate / 100 if negative. */ + +static int speeds[] = + { +#ifdef VMS + 0, 50, 75, 110, 134, 150, -3, -6, -12, -18, + -20, -24, -36, -48, -72, -96, -192 +#else /* not VMS */ + 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, + -18, -24, -48, -96, -192, -288, -384, -576, -1152 +#endif /* not VMS */ + }; + +__private_extern__ +int +tputs (str, nlines, outfun) + register char *str; + int nlines; + register int (*outfun) (); +{ + register int padcount = 0; + register int speed; + +#ifdef emacs + extern baud_rate; + speed = baud_rate; + /* For quite high speeds, convert to the smaller + units to avoid overflow. */ + if (speed > 10000) + speed = - speed / 100; +#else + if (ospeed == 0) + speed = tputs_baud_rate; + else if (ospeed > 0 && ospeed < (sizeof speeds / sizeof speeds[0])) + speed = speeds[ospeed]; + else + speed = 0; +#endif + + if (!str) + return -1; + + while (*str >= '0' && *str <= '9') + { + padcount += *str++ - '0'; + padcount *= 10; + } + if (*str == '.') + { + str++; + padcount += *str++ - '0'; + } + if (*str == '*') + { + str++; + padcount *= nlines; + } + while (*str) + (*outfun) (*str++); + + /* PADCOUNT is now in units of tenths of msec. + SPEED is measured in characters per 10 seconds + or in characters per .1 seconds (if negative). + We use the smaller units for larger speeds to avoid overflow. */ + padcount *= speed; + padcount += 500; + padcount /= 1000; + if (speed < 0) + padcount = -padcount; + else + { + padcount += 50; + padcount /= 100; + } + + while (padcount-- > 0) + (*outfun) (PC); + + return 0; +} + +/* Finding the termcap entry in the termcap data base. */ + +struct buffer + { + char *beg; + int size; + char *ptr; + int ateof; + int full; + }; + +/* Forward declarations of static functions. */ + +static int scan_file (); +static char *gobble_line (); +static int compare_contin (); +static int name_match (); + +#ifdef VMS + +#include +#include +#include + +static int +valid_filename_p (fn) + char *fn; +{ + struct FAB fab = cc$rms_fab; + struct NAM nam = cc$rms_nam; + char esa[NAM$C_MAXRSS]; + + fab.fab$l_fna = fn; + fab.fab$b_fns = strlen(fn); + fab.fab$l_nam = &nam; + fab.fab$l_fop = FAB$M_NAM; + + nam.nam$l_esa = esa; + nam.nam$b_ess = sizeof esa; + + return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL; +} + +#else /* !VMS */ + +#ifdef MSDOS /* MW, May 1993 */ +static int +valid_filename_p (fn) + char *fn; +{ + return *fn == '\\' || *fn == '/' || + (*fn >= 'A' && *fn <= 'z' && fn[1] == ':'); +} +#else +#define valid_filename_p(fn) (*(fn) == '/') +#endif + +#endif /* !VMS */ + +/* Find the termcap entry data for terminal type NAME + and store it in the block that BP points to. + Record its address for future use. + + If BP is null, space is dynamically allocated. + + Return -1 if there is some difficulty accessing the data base + of terminal types, + 0 if the data base is accessible but the type NAME is not defined + in it, and some other value otherwise. */ + +__private_extern__ +int +tgetent (bp, name) + char *bp, *name; +{ + register char *termcap_name; + register int fd; + struct buffer buf; + register char *bp1; + char *bp2; + char *term; + int malloc_size = 0; + register int c; + char *tcenv; /* TERMCAP value, if it contains :tc=. */ + char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ + int filep; + +#ifdef INTERNAL_TERMINAL + /* For the internal terminal we don't want to read any termcap file, + so fake it. */ + if (!strcmp (name, "internal")) + { + term = INTERNAL_TERMINAL; + if (!bp) + { + malloc_size = 1 + strlen (term); + bp = (char *) xmalloc (malloc_size); + } + strcpy (bp, term); + goto ret; + } +#endif /* INTERNAL_TERMINAL */ + + /* For compatibility with programs like `less' that want to + put data in the termcap buffer themselves as a fallback. */ + if (bp) + term_entry = bp; + + termcap_name = getenv ("TERMCAP"); + if (termcap_name && *termcap_name == '\0') + termcap_name = NULL; +#if 0 +#if defined (MSDOS) && !defined (TEST) + if (termcap_name && (*termcap_name == '\\' + || *termcap_name == '/' + || termcap_name[1] == ':')) + dostounix_filename(termcap_name); +#endif +#endif + + filep = termcap_name && valid_filename_p (termcap_name); + + /* If termcap_name is non-null and starts with / (in the un*x case, that is), + it is a file name to use instead of /etc/termcap. + If it is non-null and does not start with /, + it is the entry itself, but only if + the name the caller requested matches the TERM variable. */ + + if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) + { + indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); + if (!indirect) + { + if (!bp) + bp = termcap_name; + else + strcpy (bp, termcap_name); + goto ret; + } + else + { /* It has tc=. Need to read /etc/termcap. */ + tcenv = termcap_name; + termcap_name = NULL; + } + } + + if (!termcap_name || !filep) + termcap_name = TERMCAP_FILE; + + /* Here we know we must search a file and termcap_name has its name. */ + +#ifdef MSDOS + fd = open (termcap_name, O_RDONLY|O_TEXT, 0); +#else + fd = open (termcap_name, O_RDONLY, 0); +#endif + if (fd < 0) + return -1; + + buf.size = BUFSIZE; + /* Add 1 to size to ensure room for terminating null. */ + buf.beg = (char *) xmalloc (buf.size + 1); + term = indirect ? indirect : name; + + if (!bp) + { + malloc_size = indirect ? strlen (tcenv) + 1 : buf.size; + bp = (char *) xmalloc (malloc_size); + } + bp1 = bp; + + if (indirect) + /* Copy the data from the environment variable. */ + { + strcpy (bp, tcenv); + bp1 += strlen (tcenv); + } + + while (term) + { + /* Scan the file, reading it via buf, till find start of main entry. */ + if (scan_file (term, fd, &buf) == 0) + { + close (fd); + free (buf.beg); + if (malloc_size) + free (bp); + return 0; + } + + /* Free old `term' if appropriate. */ + if (term != name) + free (term); + + /* If BP is malloc'd by us, make sure it is big enough. */ + if (malloc_size) + { + malloc_size = bp1 - bp + buf.size; + termcap_name = (char *) xrealloc (bp, malloc_size); + bp1 += termcap_name - bp; + bp = termcap_name; + } + + bp2 = bp1; + + /* Copy the line of the entry from buf into bp. */ + termcap_name = buf.ptr; + while ((*bp1++ = c = *termcap_name++) && c != '\n') + /* Drop out any \ newline sequence. */ + if (c == '\\' && *termcap_name == '\n') + { + bp1--; + termcap_name++; + } + *bp1 = '\0'; + + /* Does this entry refer to another terminal type's entry? + If something is found, copy it into heap and null-terminate it. */ + term = tgetst1 (find_capability (bp2, "tc"), (char **) 0); + } + + close (fd); + free (buf.beg); + + if (malloc_size) + bp = (char *) xrealloc (bp, bp1 - bp + 1); + + ret: + term_entry = bp; + return 1; +} + +/* Given file open on FD and buffer BUFP, + scan the file from the beginning until a line is found + that starts the entry for terminal type STR. + Return 1 if successful, with that line in BUFP, + or 0 if no entry is found in the file. */ + +static int +scan_file (str, fd, bufp) + char *str; + int fd; + register struct buffer *bufp; +{ + register char *end; + + bufp->ptr = bufp->beg; + bufp->full = 0; + bufp->ateof = 0; + *bufp->ptr = '\0'; + + lseek (fd, 0L, 0); + + while (!bufp->ateof) + { + /* Read a line into the buffer. */ + end = NULL; + do + { + /* if it is continued, append another line to it, + until a non-continued line ends. */ + end = gobble_line (fd, bufp, end); + } + while (!bufp->ateof && end[-2] == '\\'); + + if (*bufp->ptr != '#' + && name_match (bufp->ptr, str)) + return 1; + + /* Discard the line just processed. */ + bufp->ptr = end; + } + return 0; +} + +/* Return nonzero if NAME is one of the names specified + by termcap entry LINE. */ + +static int +name_match (line, name) + char *line, *name; +{ + register char *tem; + + if (!compare_contin (line, name)) + return 1; + /* This line starts an entry. Is it the right one? */ + for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++) + if (*tem == '|' && !compare_contin (tem + 1, name)) + return 1; + + return 0; +} + +static int +compare_contin (str1, str2) + register char *str1, *str2; +{ + register int c1, c2; + while (1) + { + c1 = *str1++; + c2 = *str2++; + while (c1 == '\\' && *str1 == '\n') + { + str1++; + while ((c1 = *str1++) == ' ' || c1 == '\t'); + } + if (c2 == '\0') + { + /* End of type being looked up. */ + if (c1 == '|' || c1 == ':') + /* If end of name in data base, we win. */ + return 0; + else + return 1; + } + else if (c1 != c2) + return 1; + } +} + +/* Make sure that the buffer <- BUFP contains a full line + of the file open on FD, starting at the place BUFP->ptr + points to. Can read more of the file, discard stuff before + BUFP->ptr, or make the buffer bigger. + + Return the pointer to after the newline ending the line, + or to the end of the file, if there is no newline to end it. + + Can also merge on continuation lines. If APPEND_END is + non-null, it points past the newline of a line that is + continued; we add another line onto it and regard the whole + thing as one line. The caller decides when a line is continued. */ + +static char * +gobble_line (fd, bufp, append_end) + int fd; + register struct buffer *bufp; + char *append_end; +{ + register char *end; + register int nread; + register char *buf = bufp->beg; + register char *tem; + + if (!append_end) + append_end = bufp->ptr; + + while (1) + { + end = append_end; + while (*end && *end != '\n') end++; + if (*end) + break; + if (bufp->ateof) + return buf + bufp->full; + if (bufp->ptr == buf) + { + if (bufp->full == bufp->size) + { + bufp->size *= 2; + /* Add 1 to size to ensure room for terminating null. */ + tem = (char *) xrealloc (buf, bufp->size + 1); + bufp->ptr = (bufp->ptr - buf) + tem; + append_end = (append_end - buf) + tem; + bufp->beg = buf = tem; + } + } + else + { + append_end -= bufp->ptr - buf; + bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf); + bufp->ptr = buf; + } + if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full))) + bufp->ateof = 1; + bufp->full += nread; + buf[bufp->full] = '\0'; + } + return end + 1; +} + +#ifdef TEST + +#ifdef NULL +#undef NULL +#endif + +#include + +main (argc, argv) + int argc; + char **argv; +{ + char *term; + char *buf; + + term = argv[1]; + printf ("TERM: %s\n", term); + + buf = (char *) tgetent (0, term); + if ((int) buf <= 0) + { + printf ("No entry.\n"); + return 0; + } + + printf ("Entry: %s\n", buf); + + tprint ("cm"); + tprint ("AL"); + + printf ("co: %d\n", tgetnum ("co")); + printf ("am: %d\n", tgetflag ("am")); +} + +tprint (cap) + char *cap; +{ + char *x = tgetstr (cap, 0); + register char *y; + + printf ("%s: ", cap); + if (x) + { + for (y = x; *y; y++) + if (*y <= ' ' || *y == 0177) + printf ("\\%0o", *y); + else + putchar (*y); + free (x); + } + else + printf ("none"); + putchar ('\n'); +} + +#endif /* TEST */ diff --git a/utshell-0.5.0/lib/termcap/termcap.h b/utshell-0.5.0/lib/termcap/termcap.h new file mode 100644 index 00000000..b0e3061f --- /dev/null +++ b/utshell-0.5.0/lib/termcap/termcap.h @@ -0,0 +1,63 @@ +/* termcap.h - public declarations for termcap library. */ + +/* Copyright (C) 1991, 1992, 1995, 2001, 2005, 2006, 2008,2009 Free Software Foundation, Inc. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _TERMCAP_H +#define _TERMCAP_H 1 + +#if __STDC__ + +extern int tgetent (char *buffer, const char *termtype); + +extern int tgetnum (const char *name); +extern int tgetflag (const char *name); +extern char *tgetstr (const char *name, char **area); + +extern char PC; +extern short ospeed; +extern int tputs (const char *string, int nlines, int (*outfun) (int)); + +extern char *tparam (const char *ctlstring, char *buffer, int size, ...); + +extern char *UP; +extern char *BC; + +extern char *tgoto (const char *cstring, int hpos, int vpos); + +#else /* not __STDC__ */ + +extern int tgetent (); + +extern int tgetnum (); +extern int tgetflag (); +extern char *tgetstr (); + +extern char PC; +extern short ospeed; + +extern void tputs (); + +extern char *tparam (); + +extern char *UP; +extern char *BC; + +extern char *tgoto (); + +#endif /* not __STDC__ */ + +#endif /* not _TERMCAP_H */ diff --git a/utshell-0.5.0/lib/termcap/test/a b/utshell-0.5.0/lib/termcap/test/a new file mode 100755 index 0000000000000000000000000000000000000000..499cf9813ccea70633037b99ebba8376316e5a4b GIT binary patch literal 16408 zcmeHOU2GKB6+XLbu=(+N4J5db$`cB$)5L=@iE)|$v;G~o%TFAfrfOlj_O9(s_s80u zZS1IOshpy$QYaFAKzRudc|fWn^{J&&n}Cd<4}Ea@Qq-mrji91!2#(aCDpJ^+aTcX1^?G%-pG?IuL9{#M70E7$fImA&v zACx5Qquk#8;lX|J3cdK!ef3h7uIHtNp z>q|mQecprz>8Sp9KY0D&nVCPnl=vtUx%B0=FP|C9d`MV1u=v2V4lOs-v8Mji)6=wS zb?gDhH$lVcftj*h0?Q(WRkD*s+sY*~c^FQN^z~cadbj=*)=uRLd9Jm{U6@B3!covT zB;MsMnKe|qjoVz>Z>SQ@oy3O}|8eOlPC{*lp^A-oCcgm%5eOm>L?DPj5P={9K?H&b z1Q7@#@cE5^Isajk`TDBcI|0m}T(ra0MRWdg(?V@P)u%qds_Kp#cy4Joutf4S)&Jvq zwOZYEd!+K-F|+c4Ie%m6@R5e_^C@H$E1xd=@{FIJx7(698l8$xh=F}`)?UbSjo`Yd8^-SwB2c1Tn{ zO;qj=DpRs5$b?3dJd)AOb-If(Qf= z2qF+fAc#N^fgl1w1cC?z5eOpi;1LMnTfpvaeE!`Ud4}Hc(tE+SrE2vo@?PXGBA-T1 zkL+7Mu2wIS9{F|TXOVaCOF??SN)&o!6hgDH(AM>hO{YVRF?tXA2p-q&RI87Z0aATi z=ba_lzK^!@u5mlcU3ko*PD2jS*if|X>n-bEZaNP8w>I8NKMf~dlX7M zMBwul0S({R5-suf(ejKVe7&m06W2Gh{1)TBz_NVjyp?77PI(KpPLCpDP8~JN2%QwdzEU#5o0DGC!_qarD4ugl73#)zGitm?+!s@(iFVCj*y(`gX zhk@2$sFLWHxP9q2J);ug$F_>3eSGVy#+w`7{g@;At-W#tzaTyzHoQudA~*||>*^zLqprRI zn(D+Wf~!T=g}adm{;MJD$E$CIdU227YLxl%+OGkbcdveJZGCw4xEkxkF#_vBtE+FW z?Yr>$iGo~TUVRJ5J_N5mR{M_Mt8WDpKV(yNsfsG*7saL-V>aCjyUTyMy zx!3+-0KVS5`pwvV!>v-~2wuJPeTSbSAa|GL8oG`e;N$AD#wpQ#Dh$nV+!yC4>woFf zKgxQ!?>Sxo_Fy68>JPO?G=xW}PJD8xr*`E&O14CEc!cW2`7G+|_5Xh3dQ@qud=;=J^WeeSFWqu%FoLAjo<(_U>wfz?}Ehb02Va7 ztNQ1Cqq0|xcuqS|A47ZpdT1v5@XG7riTn8Z2K({1`y%Q!Pm7K)h5FX;X6W#(L!0!l zeBCuLb{_RKUW3Q0{$s?t-{29$_0#L~bB650%`n635Jg4Li67R>f2O}cJ^As+;n!?W z-&ql<|2~ob7WLGBzx_$F57)UbO%&~tUB<7iCLonArl&F`J6*KwoHdax~_EEbb;*Fg)9C(y64K6vO4cIX)|k ztenj`XzSUjg8?cPtm$Mvl}&>+atN(bnY>jlrEw6;?bGnUN@cBLI$M}X+G+A;XC|zf z48pAOQiIc;85;ot$E6Dqq&e z%Ng8Wl}Uk4(sZ&k4SH%WkNzBP7oD2#r;DXbA@30^ti!%03BaY9tPQ#vh;FB6u}sSV z>k2A{dU~2CemaF%ksO4x0vv>t(Qz`DnZQ;H=nGG}YQS-Z0RbJ?Vh-1rx(xp36XmUV zso=fbA<0{0zoO)=T&--SO#DlDP_8I=$!}zTo`!X9lKY70c45JdmpteOJKQdY%>DQQ z)ZfM2Qree%sfiO{>A%_&iMEo*ira%&pj=w;l2>&w{<~~Q`8dT%@RIkwfI2c2yyRc6 zF<$a@G*Lu8+;j{D%9RB#dD<1mOMB9Pu@nA1#8d7qvgC7%jMum^fB#txuV8^k@3IE_&#k?-c4NCe%MglCRJUH6(d1aU`d&QYK!( z!;RM%uQ6UDBNwq6e`6f_IWjliV7$QwN#BGCPF%j>!%P197XLuWbCTF|SVV+#jF@Z+S~>pnKK$~&RtNE{0Ga#S|CJ9fd9$f8z&C!Gf3Ag#SfE^!mrE_bmVK{& zdy$3z0kN26)bNsrx9O-v5<5p)mPLOJD`@RV`;zC$zT!phzpO98$vplIv1B56$?KPP zq7q5$9BF0yf5!?p9t^`V?Q)pru-aML7k&q8+<3{`G{)breR22+7RZqksfG}C_i_TPlW#hz5T#r literal 0 HcmV?d00001 diff --git a/utshell-0.5.0/lib/termcap/test/libglob.a b/utshell-0.5.0/lib/termcap/test/libglob.a new file mode 100644 index 0000000000000000000000000000000000000000..3fdb1afd3eb80138a09abd7b4de818866d515628 GIT binary patch literal 332852 zcmeFa3v^V~^*?^^+_{stvAV7iv;tL2M&+v!_oj}kauYf>A-j$ay5quDkWRz)| z8or9PtrcotwqLcjwQ7B|R1vTb>#tU8Ypb-iLZn(n1?r3cXYX_NxpyAe_P^GDt^Zp8 z|16!m_dfgVz0ZD~bMH)s^6DiUm#&(WGpsE6HQa|P*#BNucEQLIn&ZkG%d+}fR-p0U z{%_w~Z}I<6G+1_q|AUiXx6J?F8EyqL|G#q0`m36jtl7Nex=l@+u3o*NY1#T%(~@<| z=!*ZWb?cdfs4G^lS-x(`+U1)pCT&;}i!I-{u4#kSylnY3&Ff>!n?PDc9MCu}woSopHl8+kc|3|;SK z)tT~X^r%ssM^(eej2q2NSLSS+T7PlCwvkrqWm}Uh4-=|ojosr>r!aYn)yL{>MQ{4Y zoj_aPD2ygP{TcB@6Mv0W9VM3dzAeMrYb#0yS?^fZL~E~Q#RgBbrdU>F_rA!(`%bZ`hHxn~9};WHf#v))GzpxxQmr#gt%m!{ILYI|mS!TxAsVMRC!fnh9`EWct=&BB^RHH&MSu(fsVO$w6*#LNPfQg-Hw((E!Zog zKR@CqgA$~QtXc%CrY7E+TJ?I>TXh{%ohU|1A`gSPCb6&9J_WS024Nuj@MuSE#T0_Z z)+dh6NPJM2IB@J7vJaM5)*J|C!Ev<}c6~c}Za*CO3>h;c{#K+d2YTug|5Vzsnv$rq z1}1b=hnYlXp#7I(CXXQ8ry0P)VkKNX!{)NKyARb zy3WP;iq5I=*JJ0A&@e6VbTsiov}4Uv;T4eqZL~s|J0aTov|37Z+@G8O8EwC@LZb)a zYU1fCMY`(v5I;xzV6c+s$4|!wRJ~>7vB@1%?Pz=T)6v8;(fH}+e?$|nF}dq^pBOnm zBgssqs8B@Vnu8?KI`*3tD~5`Fk%zOYPDDF;&_J}~GP`YG?84Tg<<-@jD=D^1gFB-3 z^QR9R{mA#oqg19(gH(&cJzz&3MoA=ob8H{Qd;2!qYVK3D56QWmWYS=DW%Fx#PA7B( zKnooEwVEGocZsbX#U2~kI%#NZg^v=6BcxV)ud02m9}bNbwtl!U()LwQfP-@l)qS*` zO|NYaOofEsf!=&nCMczt)%+r6Yzq!WO^99XbAxPB{I{`3N%%ZbTL?pv=0u&DB`gnuQb6dbgwXyT7iq)Q3;swQ!O;6j4cq}EfXn=eHNsZYE?^G;!Y z;+c9RW#J60CS0HRz2cKul!GNmotUfV@2^Z8O=>Kb(p!SoW>mz!R^Ps+qJ-s6jh|>P zMwLNy)xM)+kiUs%j{Ohy+x9?R$AU1-XgzgKP2~22t*0i#J2lw{Yj@sQ5n*9fzr`?m zYU{@^m?>x%b>sF&+P;V-sl0gXMu7E+6XFMI1LT`OfehNz_LU#=Oawjm(X&CUY5n-@ zSfFZOP2!S|Nqpk%s(tl|kB)v7H8C}@^5eua@qNwT?RtYtZHn+Ti>R!^Pmo0DPpmkXpoFcJQHcV21;rW zlVJR}k+x+(>JZoJlGdzl$b5nT5yJGy^@JT`Dm9rS)k7m~ zbS4l%XaLPWUD2s!>?9e7F_T3{;?3k~J@r0JjV~j@_N@Uc5}yz7*q2Pd!Cuj^D1ca0 zpA)(LscOo;?5B3l_U9gUD+jIm0Mag+2v(>Jr)CP@=0aNCxVIy1UxD@&ot%eJ6QIsY=3~mz<_O0bCrXkB$ZrrKvkNpRP&l=REu-hYS63tBuw4 zgwn2EAazE^l~zRB5&${&k+#PPL>r8>{QywcD7-D)8%7h_&}T1G)VFcm!u7U;B$ zf20M1el~1SIRxd9OS@0B^%=YCWy)Q)=VDT2NscrFo!pu#W&stB}F{GK= ze&D`XRP_xk{ExzMIyRE`ys1_Dq8<6L}xH%aJ~|02Wo7bc!gynKc3pVZ|CJWe^KEBJSxw+u;a!u9N!N_m#W&YK^I4soR$+kMB-Q* z%jON@k0Czf(iW_|IRnSVy!ylu7Df4q{@OJFDonn#ivfQ+p?`^ge$ zjWyzyBQ^`SIM~5ry=i^*?ZenU^2vC3p$=!@W0C~NDm$ZUy=o1Kco~OlUvs7SqrQC* z3-4I|GOW5n?tK=?IZkgMkI^Cz#)~nX*ww-bY9IS39WaprwNH6xMGYl>-g>AI9i_HC zCsO4i||cv(9Le7 z_WA99|0MC_FoqG&L`RT;w-UPx0q8#CopU4cFCjL*eJ>Kf8HArfg-T3)J9-UsJxMNM z_fXPN#J&ub(bln6?0*%x^*|Ao`?WpVIotK2>9!9jeVT7cBEEW(b1J?LGHctPr1jRE zI9L+9pq)+C!GHvoT$}h5H(Jp|yo5}+{2h2AZULmSc-^tA6LAty7-_o%rnmo?hfYM| z<1o~|n|u&$|1nLKa6{55Y$3deVlYM9!&9qHOszT{Js5un0~Et3Jm2;jDp&Ds_lKldS zmUlk|J`=E;o}`4K)QQC3r=aI8Ku^^Af_na(b32j8U6!TF)CeG%eC(L7dY_Mf`;mN2waU#pxk?(Z`qwW_zx;71

U9@XW-TvqMP6D`qzhCByHqKom1gh9-L*|D|X?EQyW{=zMCo& zwg`bXytX^AoObR46ZhPVv(2qL;r!Nph15S2Os_|~Mgu+aj>wFnDYC?9;^#AHqu7Tj zoT85an2{I;MkHZf;u3g-^H*`Vcc`Sq{TV`;_zhFF|GNrchssNYB@+J$r|;j;tGi}U zzd&D%PN24goIDuIctB#MFt<{2Th(UYCAUAGnSqZ>tV6pY94`L!g|&x;1;e- zZ79Q75rtGeHqpNIC39CT&VFQqOo5`RK=c8$eyqz`+(>{^M;(-up%cl`jNn~}g{8r5`E zhd{@nW~3WMw4M78n}`JAkhOPkw~D_`#egEPJF2lTWUUCAp5VJt?;Cx^&e4sY#QcAONm%Ti4sd&(l?OI`sos%^?y2yb6YhseoO_XYHop? z_Ol1G(-FOg&XMg8G z1_V&4wFSW`=PPar(^19hK4*Ve4L$olEn77=JZdY!^AtSw{q)5CV5F@B`vkbpiL||* z3)ARXU2WpHJf<*3`*fsjCpfuHYy&_KR7 z({pq>p>@TdA(oB{)I7B)E&pli4EcIx5#B%Okuo-y__uhEhC{KRID7d6B z60d-61XjCb`x~FM{zBh7Nnb{Y--lkZlutDJc@QNGj)-r3I>$U-2Xx*py4ev}r{lbSl_ma#v0*Xe|@^%FR6B5kMPFIrkz zefw~Jh)>gN+ZR^gu=+|YM>7W5s3kF+t^w#5*1#T*CpPf zqN>`5M^Nf{B%Xh>g;VipFc-J?l87yR~tRgVSZhEbp@3L9>Uk){ETFYw9N(m=*%}Lg19Ti zL0y&BZ;&%pc&uD&S-3;Srxw3Jo*!y{&wiPVsEl@udWI4tiU(Z7*_HGlemGkbp$cms zQIq%sass!{IbELz1@)QuLrq8B>DH&QXOB9B2j0>4QNKVFB%Z%bI~Y7f0_(?p7-{=0 zodf86hEFiGa6owQ8Hvxs{=;?q~^kB{Q8?DpBBJm#p zCHPa+_qR0s3E(diTSu++;nc*Z$12!QH63$5Y5mY?8MqzYpt&^Kdeo^+yt{pib53&v zpZ{&&5*QYH1r=YDc&>Kbhq1z%)=z`i>Po6aX4G_CY#J;TOxI|vgr2A386yhhTgXHz zkVyOu&~<06?|>cXPj5178^IQ8ADN9E3ZFu?K390O^lx-*Amr4ik@!AvR^jk=@Muuz zlrG;TnY>BGzlX~84hm9RN1)zopmm8X&T$v&aWW%oP(^hIFA0+cU7I1zoX?Mb^jC^7 zl~mWg7^sCU)wt!2w2go!RsQiI3dBO=r3!Sg(ry5|KExdA>u8|5S=L3SzTfo-&LGO~ z?4S4$S^=KVI(W1ju14s3f>76?iO)cq zaqq|e&N&xtA76)hrn0Phiz=~~JanPhR@&R zmL7X$Gd?KfRco}saZv8M2iC>D=g-Iu|JJ8P2TzmAzV=D2E9Bn_WZr~m8 z)O4&z>r&_OXo7d;_*qaWhY3^G1L-Wg3o>TlX&XKPt!sTI*s`3CNpTAl7-R;{E?%Jp7I_3m$zz|#eiGNN#`^d2llye1b*V#~mgsH6v zR1b@V+fW22;S6*HJZwBxiV+;|4^*Gid`Zpr7WvM3fZc6_}+MX9A*K zOEq{d_O@)Oq6dJJPmpXlj<%JjyAINGZ+)JlbSUe39uITmR?8ddM-#dp!Wb%{>laXf zRL5bet2g8c8$bTI3Z+adq`IF=WjzqZ!SyR4jzLT6`u~UrhFVtVB#X}Wc!fFgd8teP z=0J~vOa}MMy~g3=wqD;y5Gg-!w>Zbd-s zUPNRC7v&J$%K0+h=>Obtcylbr=I0(Rk@CWBe)h8f_!BiZl10iiQtYk-9JJUrw}^s^h$+XT>O0?s}vGtt2Zd5j**x` zrsaNwwQW(zjP5ZY+ZA$Y0rID0u9`=COaa?S_xs6wt}+x98ss_{l0!4{DV>teyW_{NchWU*6;F-gq$heeu+_*mUCG* z`t(D=OS%=o^Lg8I-R!#nu+MU{dJv3~AS>?!$R!a`Q*y&j93)Qb!o2M8VVRbfn>T=_ zv5dUD9v1-#OPTuJn7_Qocc7hj@PYw>NET{15~eCpq;f^-MkYim3TQyVBl2iL3LfKw zCotTd_)F}OiYV~i6;hr<^NUnN_#QxB z{b{SHw(fH4+-;=~gH%kq*ae;4hK9d@6ydquhUfpt=<9X?D_8ouO^p20=<7DA;BP=m z)SM~#6pm7b)Z|l~$`o=@Hm$cpAyZj&r9!6hQidz!(r)L%MPn7xP&fw26op*T<53_{ zg)C&GQ6Y;MS*4KA^`aGQv2rM6cLC%T2Q2=wSJt@&yxK_kn;40NsergwQvEU`QE8TD z`=tlI1dw^(72YBhzV3;FPe6)rQ{;el|2$I^-0s0eeK@!|H^D6?rLFji_Y_(iinVO}N@=%}ha2zxaZ=WHNQGhj4$vLI+qtDreRNYZ4 zhXm{vA-Xs8nbn_U@FM#5?M}lAF7?6vd~kmsT*eFKZ_s50sqvNe3#~$r?M+Kp?>55$ zes}mi$nP${hxk2<-^2W#&F?w=6tKypOF@-k(GX%=ai|D@9=snVd!QEQik5^5F81=L88N@&pO}5 zUr6-17=J@h`imZ)0tOwX|FY-B_&7kpzv>kS+^24ZRr>4V-x~6BC4F#ER4l(KS!v+s z`#fdf|I_O|1HVvmDa=y*FZH4?Mk)9YJwGt;pZYF_R}}r#K3_BNYbAdoZ}lbH%1Q%v zAz4~VSgB*PGc*=dSWu0*whEZSLUuuW1ZAwSEIV%^uoC!!T)@F7DgCgJ)~($4krJ$s zj~NLn>hdJF&r*)oE1YBJA4f!Kg=LtoV>sU~q%={&7947`u=%U5Or>Bzl|{-EaAp4OZ!R?K4<58xz<|m8F;1g;X4BdNgTzU6N(f6c+Bc z90g|`LT)5XGPQ!^g>j?c zy%K`8g7>-gXqg}QOYMXywTr+W2~UIu)v8ZAin0rIoe$U8g~M?SQS0BRR;;m2cJ_5R zNa*#)lyCABXS2d|LR_n`Vl}o|VLEDC6jrLnu2Wc8K06o>ArQg)NdBFGp)9+$FoUq%%{YQoG!2tWX|7boOX=Dr|LAd35 zF!U!b_RWBP-QUJymDkJ8Dhxv?PcN(JORzQI>gCs2WrMgqD6f|d=9^X3;L3&+&Igy; zG|MVE1f|gO6H!ohwnH#0C@ed-@G_&|ydDH=ZRh(^rEDl8c@Q%P9FcGV-r3r+VNM^w zEUdEptiq>&u(jnCz7t9LAfK@E!AjVG<_%W)kX|%HSzcbrh_bx=?8qUEP>rp`H4?r8 z@2s-?9ET_huIY0bZp>Ky@bX!Ogedj1{p#oVoK-%T5v_7w$z7PDRW9g#50Ek?U=dqc zsgT8toM)9S1_S+HPH(X44P(iLeKyc!qJL2s%IOxN{C;?wA>6Iv<_fX6g&pa-9| zuD>P6{=fQ*eG7l>re6d~h5Zt7YOKiTs&!PM8Zn%N$sp(O> zX9%cbs#B&4!jJkCQtxM*VMor#%GAi^{yDS!$ZS6{*JhWn7lxegtz^g*p38?cdCwq* zEb;MN<%fG+4&6%5QXhROKgLn?Wj^|HAH2c`uk^vIeDG=?{5cklh7@NW6NL|N{moJ9ln=UlSJ$Jar8YqLB`1@o=%MLGsCT!-5a?plPwKWrLi z-PKTLS%ZmWPYdReZSqpY=|SErg*b!&dqyzFFHDHV>BLKeyqhIYzbwcuP9^s7YgaNa z3l8!VD_5+u?8}1Z`)P`?A(Nh&L2moWdM?jQjF3y^bv6O^n{Ge>H@WsXM0o^99i{H` z!2!uU zgPf2usAhaW$ay40i>DMAo8JoN`fXNo-cA<8Q}X&)*106bc3qZuo`_sA)Uv(@8_u`q z1b02SEp)y;J8RdS+inj|DYufCo=s-5hkL{JM9Vs?hV3cIzNBIaRz(0sl< z)8$oq41HnNz03ed+`BF0jgY}l$p~Cz4HJV%s6mJ=<01`l32L4Fyp#MqGtdG#!$p>H zHpv-=5R;E?Op%|&G*>YNckNBJcEcG*c51^o(g>giz7HsF>}sp6q&%KTu>7&+ssB zoTlaXSGtk^MqDH4BQ>4kKU>e98QALM>KJEP(+!t5dnsmLt>_uGQgQFp^T^$^Q~T5& zHE36PGRdMxm`oYz(aB4{F|s^5@xNvGDTA*~ndJ_UuzMk-1T;}f3$AewDXsOU8#*m) ziKeG5jB4?^43ntm-(l$Fjg)5ofF4X;zyUMKvze3_bJmj&6jN|lXKGt=k@~u;nHiK1 z0~DPj=gFd_RqGkDG?S7v4WbY)3;$tXdk0TueOpHlhp3?6MMXUVKgD9%?>ZR{L+?68 z{(0(zblgcgAyHwy@9?L*N-Am%ThseasefxyTi6Fqh6Bn8C+Toixo-Jp%Rb>0`HvDK zH(h1fC!NUSScS9e!In{?YL*6?%c;cI;at)`d51UYLrG#hLUCVZx4D7rJ#OUG1^m-9btr#Blant z;I5NT$^1q&>_4~?d8;Bv zu6?5A_TX7I{W0(9J|inWV~zJ@(0>mkJ>k>uS^NM-UeKyXc;v@GeoIf-)rs6Ro7e%2 z7|&fa0*|B7F-(B4|8jWt!dj2*?a}zE%D-p(Eks|V*tj655omealjM;*cL^hB1f3Z? zeH6C;^^JQYuVUmG8KHHVrBFy;laZuqq%izTMzFPeb7-UxjUUTL+8I$q9+FNbt0pUQ z(lLeT^E4eN0pn?+8<~XMsF}8Y7SlHr6IY5iomTgF2HkIh{z3-&3DDoybgDd5+{Z~3 zM*{O;9Yr2Z+89l1H%1dvmB(c0fl26piq55_0`1KsA*)QYhfG7*lP7#djikBu zhnkKAF;=Fz_77(i`>7g$WU#IEU zViulgkO%z_8ovxZH*1!yzB(9;sSg^F)KW+Q-J70oU!GPmhcZZb8SkYnEW{c`A$x;{6?{$pr=4wE&jLchrIllM+Cg=yU41k4F1@T zkW_mP-IhF}7 z2tCM8&aOwd;iwIVZBt>AX+rFVR%>2k$Z~n9YPWaU-A>`@&FJyIq0#62kuo2mj?XU+^Pe_8}9#4aC&!WaR0Qk&^NreLCnlSbh=8w{nQ?C+GoKKq$FY zU1?g?`{)*`RpA@L{zp}+D}^%=vy)rZ7?L3`eRrO3=f4K(=ziP})ZplDe#G@5s%f0< zql_QrM<)A`IzKYok1X~htNcjJhfKg9oqJ_T8+s`$RjJ|8Z$PXk8#?7PcLaaaAeN;` zENbKS*EN;Y4Ti@PPg~DjOxMqhT=Z%Gt>-P6_?Vff+l47}n(ietKXlRpd{0nFH!)oc z_g_LGu=nwPWz*e$l#j|k=aAR&;LmweQt(r}M^B>+-_K9krcr|L=kxG1dRSUdvz-z(y9b`m@ocAe5y8_oSWe&G3@x>s((Y5h%W|B4JX^yB zWD`yxGw_}yZ@Et%!Ac%OERViG_8IazFibM7z^_#CId?(`VxlOtK7-H*OrVF8YRWTu z$}i0nP`oKXc*>=HX`+5zudnu9)G9}x=NlS7){k81N9ujZWsN{=>r(21@_N%qZG_Z@ z0~oUBG`v8U*`sNjGp|c2ujKU$4cK?lZQD-Pm^GQC{mD1N;P|6H%J}1c?t1hO^;q#>Cx>Sp0acPQh=Lz zdr(19u2ayrpqt%2tFRX`yQk$8jL)5rJ1)1b2wkqi%FUew4t&v0kGN{Y9c&RpNHc`- z$LA67;v0dz?A%->!3INiev-f(+pa4jdTu%94+DQ*Q4)W?pMNaI3yN%~z%MaEdPsNS zC?%RLn%tYdQ`SwB*nCCm&huT*q9QCL>@Bgl2vTTn4{z!Cer`GPs@Da)#*!c`n3PLO zJt@5_F|8E#^?|`Yaea-sFpCz7KX_%2vX!);etLo-^dG}&2KWULV_6S-NN?q>a+g^K zj#XF}5~;#Z!iSYPbvA*g}uqN!LHA=K(9wGL;?))J5|#v zL8B$I#hP|@j+u)u1*FzF&ci&9*h9P^}kQ~g%Zk}js8R26YhF43~Mc$BQDUW9H3`0+b` zcbKLZp+~11#UN1Jl#F^$tVf(-c#%{d`O={XR+7b+(MqY#8aQ4sd8Y9d2P;>F^YWn< z)%&^vNgT_Xl|+I~mW2<_d|V);y!Q4`gh%z&w&n;py{8&-EPP>4kUXRVy@D2=UhWZW zyrwd%Aj|vuSp{3Gsmv;f{1k|is-`8si=F$7owEg$$&h#_o@D>udf^eAZ=N6ak^SJ$ zwH<#o_B06ii1wRp%{s2Z4-Kh7T((2I3|zm`;9-v>;BiB05b!I=2zp`S0~%a}X0AyB ze!Gt%!72A{`>94=^AiObsRIIemupbM0@BTz)M2<91ia0VW<8|A7d+D28a%15Y=|IV zD>ViS_|1Mkg9Uk96JdyeclG!23GypV1mAH12l)89X{5wY6y$tOw5^7b8ob1iW(oK? zLuwH4YlbxIdm5x~)X@vF1k9$5l}WQoG&sm3ouk1Tk94sHFV$D}oFKP)e79?GkDpJF z?|6Iy{>YFT1pKoh%@Xj4Uz#9&2AVYpc%C6O2sp)%7794kkY)*ZlP2-91d$p>0F|ap z@0aTI{hq$U$pSv;&+H94Yb1-nM_(GH*H+06t06T}z@>P+ciRL114vqe6nns`G7a)- zU7+HPqNP?g(Im4aorxxJg~|4XvH`5{NCHaN#|cS5 zZv$AEz5&dU4d5M5mVn*LRHoQgqkw-fq=f=Xv5>9vb*V|Qz#Rfgu@KvLG@BF)*aVbf zAvS??Opz=UP%4Ai1ePj+v@>Kl$R_(0U{L>zH*_JK@J>wv$^p~1<_dU)se=Xqr8Ka4 z?A#{BG0N(M{oWnyY>GBGtdnV6cL zOq5)ltn-J7g4|??*V=m|`6Rs@3q(OAi+K7CIzJ?Lm{Sl*B<7S%`mLV9oPtO~FsDDj z1mj_yuUpD)_d|0=ZIn8G!khvd1w5olxYri3dxZ8kk6pld-l6fqZPWDDCVM@KOEv@9 z0buWg+eEN;m8?0}%NlPmBP7`!@NE)7TDCFUH?616V@Y1yYLXs)wbn@0CQUr3PxVBr z)Nq53CJFt5ra@eK7jKdb_tLp3HJvdrHJL$@#@pSvyGg){4C!(KHyKisfD&HYTAbQp zX-SgSTTNSRlKegDkpz@14q02R8?924)pwLB2gBg|HMrl977O?XO>(T3t$R*tL{2Yc zjI>p$3!(`uWdRkb#Q>6&g0xrLx?H-dZMtfcfUYJv)`o3+1d)~tX#z^Zk{#*Yx5-L* z=`@rBi9$6|x~OCw9dRUeq!$uR5=HtS(NZ&oXsKH{(NfcgXsNA`XsMl$XsL~mXsLaW zXp%3o*%D0>MtU33By7^fh$eB9enqqt7p9=D!lk}}`9KNqvdAW56>s(rSA|Eqg~U$xMFZ2HAw>G{*lP5$D`H7I=@ zdSpj^!{d@hzd|>BzaF7^n?OTqQbDM6l^taiQi}0x0j05EtGH{MAaVttfL|}8iTDt} zidi{@f$}|HFC)~lq#b3UWAT6x{!qr_q)hTw+7IqMC2b{TK}v5iv!%tnS#D$r_%BT| z1_?oW3-n5Rk^K;^NbfR>m1ytXx5xR)L477iT+(S4>fER1CGfST9vWoNllvB8lRZyv zT!LHWo4e32&DCsVq!!9SFJS<>7LF8!x_ym+PVLsW8rBIkCyRXy*6H`45iQ;U@cIH#Q z^xi`rD3I>&6a-02uh%XV@VLp;MsX|s4LrSY%Os#U8Rt?-F}eBk-3Rt8<9ReuzMKif#S`Ajd_NS`&E zC)W53`z-Joy?Z`qcF_g_b4(v-60pFKW(z1EwPDXmFYu;veTW@t4zmpcdPm+S0hbxB z*#df)DWNEQkv3RO4^2u ziK%gMQVAND#$4iSxdNA)h%8Qb|6)la`GAOORNOdTdxK~Ki_@qD2`t_tzEmF(Ew#xK zE!8DNOZ5rSQu{2?&fo+l_t2}A)#Df_py!C0>5iDWN@v#9Cc_#86yKoAQ{9juMycDU zcdL+U2(6`3+dI-ksX@RohIIKt4X)Eynkn!mk4?axhBQaO4nw*;b@3!DbzMZ0&&A{e zLZS(Lt0|PZ0^V*&X`ds~%uGR}U%jE1X!kjIvL14*YwV13)yzJct-nz|Q@|mH)F9wc zPw2Kif`}$4mwUh_eVRk^C^i4?UB2J&rgv*6pnTr}pRmdI8}{~6@*rM7x#e?wq__(F zGvn^L0`51YjBdPAd$mnp@hOsk&AQRyaJ#)l4`;kwsi`s%H}nDy(uIfx3Rta4^qrd7 zdjz9@j*(tq6i|NqN-+v1R)JB?$n<`tCW;wID*2a7792-lSrk&lMUNk0c#DZ zVWtKp9yC+CD#K-`rir6r&4-%wslI|FVV`am+aRF$0g*}7oMGqjTd+_I6Gw;ePoB`3 zT=1Xj@oYQ`ZMog1At8x7^Q>K8qM>1Ym>18A9m%6YrQal_m#7n5{FOXQ@ut7;*2aC$ z^N4_A917vo)>NCAxH2U~8M>Keoz_adq|VTyeya0||5+VO$QTZ23TrTfnh; z;mjw9=tmCRnU({Y3^@}m-N2b*phOsoA8Zjs3?&cE+#?vi)Xpz#c>+qjzErLko6{}#aIuDptkgV=%zG4;ZkDAJ?g1n!^D%e7uO3W(A z7kv3ObB|z>RLm;K=XBC30|dKCQ<+te-ASy1E!UaHtb#~7D5+|RY45si6zO~_F$L8i z-o3;l2`Ju#y3Q8y;ys>gJ6ptwQdZ0<3zHIJq7+Yuw}j4ro4i9KY9TfHiY6=I#fG$4 zz<|k*mbH7tGKnZY_+Go`t2$Pmxgd(U;(F#hCjK|(f-`*$Af~z+?lH$NGj=A5kB$gw zOv+Nqjy51Ewi&wEh$gTUSeCUpGHTGMiao#4On)+!xmduz8PXg9>EA1%mu)Q)Q0kDh zNPbA;C7QrzX^&&7fKrzT`r)mDOfYSEk$@K)QiFh(8q#6`B?F;AK*>Y1S|L1QrY{ok zpdl?5@K1)cNWixZX|aI!==z6V0VR>Jr3xr%1TFz5=)55>2`mYQ8vp?%*DzDSTlGxj zxPVgjm?+@=nv320vPL9X!6#sj&RZxDP|6Vt5Kt1DtQA-a6f;#`c<(`cqbXoLrh_iQ zrODDEvvq+HZJ)O84YRN&Pn1AGOQy)xKUG$Pg~^1BSKC(ojS5H~9+?mLMLN6Film>8 zx?~^xE}&!|)Cwrs2d@Yyd6$-mx0`%w5OB94Ef!GvD6RK8oo1Oc>=C7 zq$UAn+aY12w7(}Czc2pJa!dl{dA;EyEhA{ssX;)=A=oOZbB*C@5>T><49gHYU;jg9 z>6br(Li?3Id_Hdup$!85(~uSk=;c@Z<~NM2q*!=4U#POfafRy zy_GE#o5iXOcUIZ}omR4CeOI3wVC&8nLGCw)i3R~B`plOacP7dSLkwo3Gw>drhY3NK(s{JR|2gFFM2b+^C}$ z*VnMM!5V%xJ)8NgxcRqVf#ph?1eW-qPYbwKhnE&Du!PT3E)=iXH3=wJ(j#Rc5hbAl z%dr5u1-wON_|*aVi_Cr_xVCGWjE z#oepTfW_a1`EMgGbxFDf_Ojr!Yg7V9a|M?0Pz(h2;xgRC#a~ncOCzPZ;zIEU>G0OB zAS@Y2zyJ2&=c~`dTT?}9+-&-UOOJlY>(TFQ732x8M++#fKm&MZYpM^JD9I@|eoPeP zd)^KspmZYU6VKdWHq-_IrF}4;^bqkN6Em*Yx7t(s6rJatE(DZip@q@U!&a51#n&4d zuGcWhTZ@2FRk)wsmR1y=1UV3N(~Xna1(8z%K9Ad$mKD0W%SwHV%TybgI^SpYw;$-| z5tNSt|47p!=#cb_)NSE`72GIgKwOtkk4JA0;#;RYEM&^0(|Rq)y;=z0=?rUzDm@3sKt{^snrALEJ*6v+p+x&*_5af+!gtX(<=yclQ zJ^B)`-HVjrU(&1-U+E&k^DdovHK9|ARP#)VOlfG@_ zH3%rFi>C5%rXKh4R`IW-By);4CFz)$nr%!>b&##U>3NIpw{pdI%c&cU7(A-a9-&Di zhM?^&(pG(TY;O@eWK(9&G?gG+t8WT!)>jI@zzOe$A$6+GBSl77y?e*cstIr39sZeT zEZLCA7=e8OX=@Qg@}3w4mKwm4+suPf`u92M#YDO7_j#<%9ELxuv+!&Qtwfb{3oM1h zj7p>TuD1%0pdrt9itwL$P#!nR(?i^43Ye*dh$H<@9c3OQE)-DCuUNv%=0T$P8(m63 zakt;~@)!?n0!oz-o51B}(_AQzTO<^iDPX2R$bk}U0?G{w+bhUvb97iJ`>ccwQw5Z$ zWr`r!(gFp7`a>r#VyR6KkFKO2{>U`@nU84j36JzU4gSfH%(LPnhBW6b4N6?`JV3xx z9#{Hf*F`VrC zevW{{b)=Y20&}5vCQAQ0l2ZOJEy~sNgZRVBmOX;ynfT8XFh7Ygb>X%p0)-DAOJfRx z68ybx&~hvfS;v`C?zH5As?a4-<+-fT|KA{8Z!Wo~@wZv2_WQ?D*We%f&(?wR+}V<< zf{CfJnV2S&|Ekw>{uI-=W(g?q!2IX8rfNcO%%JD_%(q7rW_ktR)1ki5XloGg$A;7- zpwED##sK=4mg$8$5>OHZh92E2R^4ebwn;!q80J$_eDCsSfI+dSNn7Mto3`x{WSuc{ zmVmeU`9%HWM*S=Sed^P1Bk`9izQ0UivrJ)#LDXOb7JJYi1r&SW83DyKa0$4_EMU%F z4c===vjqIUALP=Lo33(+JXR0jFwy`Y?RX z9>MB06^sH(Q&o&cO9mjvn=GJz^6U(o7k>IrPpUAJ8!pq}Y>%X&q>KKRs3j}H*D3@Q zp|&+IX$m9h^X8;8>EEBnfcOF81)QPzGm1}lWk&ISl~eSOtj*F_L{7lJ8qzEQ-_#@( z5Wzn27zK3mloG`#Sa(fD#tGObiBT{))q>G)EWvV|z`ro5)rxUo7EmnvFYWvf)GKr1 zT6My#yg|Uf8`8pbaT$+^pVu??nwbrcYw#J5l|4BMh~ol*xz06wlT4@(d0 zYI#pzsR4$xv;rfwLBO7dbh&_XMavMdx8}mn2iSW?Xk?7OW;#jI2Pl~=`48us)oj8)42)MwIW(l}klT-}}_Ir;}z?k0q z6r*5wYbvTzz!~ay;PtODCfk;ZiLC`j-)sTJK-_f+DAth)v-b%0shPV_K(S6S3MK|Z zqJVx|Gw&Xr#p$-rOt*DWCR=A3TYqS5T_m7bN4Cz~BbXS7TMhyJw$9AB(^1o$rZtEi zl)3`98SQhwqe0O}Y^jPeWxe#}5 zQEvXHmUN|Y)hq$UL=<rp-Wg5hc?(Cws3Uy%p`de&q(El5yhR9@ZAf!PVWmg%dsSe`;v+ge3gjc0OVuYZLYG9$wXU~r4~EP6 z^A{14dX-$0^@J?^88JTh7F-sC5C6ZvP5rrokec9mK6904E9 zRuib?=45PnnFY)?0*uT>4{Gqo`bsiq?-5KiWq8DsS;b7FLfe?J+^LQm@T=_f`dD9? zF`{R6{DC#ar1Kho>iZ`RWw z;7LPj63{bnR=R-=muV|LXRK-P6s1CKTKZ0-r9nV(2l}pnqBvk}wo)|{O?)G(&e*c| zX;mUD+iJ1GV=KaA2dBkftQGz587mhGC{hrHREy9TH6G)o4>c)16JM7gK#h;s*b9yZ(cxFX$^aWdT3b zq%(Ig;q3G#3n-H_{gMIn3)?UB%mD5sex+fVO0@Ks=oBtIj7eoex$FCgH|2i9`jGz3 zmop{?{wYHp;U`SC&k^v1AEFwJv z=Lq#_#cnW{EIJ=}PR33a-`$ZZJlt|72gl67`a|8KO>Sj|^-wL#)o+Ey8B1@MXF~ zI}a+e^4C+ti$@6`sa|T{Lkyu+@d46S6}6H zn96@xpU>XWS2@I3I(ZBAReE#keCY#adSMm%Dn1^raVh@>jnC89EA>^4jY7vw8WzcCt<=`QY{vNw5@!^4Y0;UX%LK*(v=IgM37m`cc^b(RTb! zUsJ?e>-8@}9MIS2^;LcmUw--Td7b#fOO%8M^|eet@^92v`H_c5H7>v1@JEfyPl&&x z@q7CzdHeKLem_orW>J1R?mOj*@1}w3`gwg-nD?G)*O~OlPesVjS)D9XGHk6!?6_Uy zVu$>2k^EfML~V!I{f5M~K8;`9Z6_y3wTiN$gMk?V413 z|E%qopV>+Epiq8|8D;C+P|_6@sG?)^^g2Ap#030Iuauw0l{{af*PlAS zFZ>v=N^x$r?T-rb@y_4xwt)|8-n4Pp>UB%kG%s5|Y|GfuO`}Jhzh?Ei<}K&1T-Q8o z({-CH=2)}(s$naaE=}hcE0Y!986{n{I<{$8?79uhwZPA0Op;{{9cpw~E7z>QYUom0 z-=^4-*w9sY^3JrTHS5=Jkbz~(mao7NcIc+2wO0}2@+RWN`cu$Nv5n13V@(&=)lXI9 z9>lhSh?BX1(ACtmY4yrY%VQ!>3y7^=yL{7z2O|fOG*O5YO%gyUn16A7i9?uUfil$wpw&S4D ze%-p*k}V3>7Qh!vHf~&Uog%KnRHTSPu3fTm^^&XBEZ?M1W?Rv`j+{fXR(e&y?o<3Z2*|o zE{QE&1vb2@uWDYsCU*Ynb(09&tX+sXmTOzt$Qku=z8JJ!r>Ll>YloccZFj`=!GN3N z{A6484h)QN4qDY9VC<1?LtUrX%?a6!G{Xu6gCXaamhFZZ1Sxc>n-#LBxuHhDTij5{ zcI{sU10iScw)K4&;nnE!~Shb5kXCPuIw16yj4%`5n*x*A@n(aJ__p`wQVT0+?2_@H( z#csF9-K^!TvKufbG@n&Fq5t7)PBlo=-7tporZJcYFvq!|)3q15-JSX{))3m^_5d|9 z+3h~g?K92oK9t^_P<@e`4Z3^l1EHaSCb;f=H+zCxUd2;-hS&<$*Xia=c8jZ5IAx7) zA7|6+9EPvm&>5yUWQUx0a4CkUvT5!>TBvhnBfgFXfPSu&7tR=rC2R*4cAHxX{?Z+8 zexqC3=yrPyw0iO;u1_*yFq8I9WLX9aYDa$@mI$|C-jrh zf<10-$PSacoL<##J~9ko91?OGU6+~e=QTQ^dAww&TA`Rhqt&4WoFp`V)?+T5N&%4| zI)fTXBq*ChcF>_b`_tw_AY|9NZk5|@lbbyarcQSQPEPnfKv)%!(8Ij$0P+ws)=oou zg`6QP)c9K09!>a)9h@QVG&tgV$~>ot9FLj^O)r9DZ0E1`W3JOv(K_8Bw8lklDRIQy zA$KE-@`k$QPHd<B~5o@-ntdE$``ET zP=U~>ddzpT7PgiBlQ6-)piS< z!q?qw^q?$WHtKrK?^m~lS8$lZs_mg?IiZ^&Q)MF=vjUXsy!6RAFQ0OeN0-V(uuqOmnB=;!H!5Eqm;^dk)c@ZWKF*y6r6@V+bf%I6GpRJA&Az zxfMigbp!X)wUcP%8s}Q%hwc1m8{*p&+XOWhYR91v0yy36Ii6~LC1B9Q2qJus_X!|2 zQ_CioOk$T%UC@?P;1u7d@KCnS;a_e0OpL>s181+}wGd92LPm6v1hY*hThXCnbLcofv91@u`*g%(Mwv-*^O?$p>B@Z$<87L*SY;f4{e^LXMU2N@{nEa_EdVvTGkUM zJ>5x9v)fPWnMit|u$!CpcV__>>kOv)+=KLPP`;*cli#?K@8E8mHOb8$?`ADgLJ$yHR$C&=YCT3E>Gd&n&$ zuTj-I13HUP_|6ubU9N=Fw^X}jweEyQ^4KaYmy#&KFSNSxyeB6@s!t;bFWARPn`!2#O*5 z?hV*nu+EoScDQ4Smh0@^*63z`)g9}+ZQYG&Pa+wM?g6?b=4Owmo-!7+$!@<;4;-wo zUooPZjy? zmSD-)46;MvUfjj=4q+KPIr)R=Xq3u9Y-{T3WUo+dJ!@K0Glcy?+<(v^J&R$ruZ2Uu zK!#D$7h+@Xwj2!26g2dCwLN22f<=RqJ>-U7hDVNWMZkI&6(RPjl*0G3_q%txx#Q8H z+=5BrL*edpqIUZ2KoA3Ta?5wTEqLH#W<1jXZ+n3|4tfo|$>l}%CL9b4oKwirptG}O1s$o1+#pUy)WT3%?_wmo_;J|f>_=oMJDkuy zHZCjlKBogE9i9AfejgMrcl)Sn8kAf-;Xbgahg-B1I;ZP=o~TwE!jXa6N)Qp&$s25m zQMvAaP>y4oH>U1NQgE!yVG7VyDAOX8I`gVjC z7rJgf2OfrCaY*EAc02~ElRwR)Gnwy$9@>U2mQDd7^ts>@dM46ZVjtGWQ8yGW#%Pgy z)&x2!oV6V8+vSFxY@4eb_eEhiimD6aa9+AWR8QbbE~ldOt9b8$)3Ph!0u= z@6*0^c5MyE+yGpLBOt%i5hM_L9L*bXY71bV(=Fx>#;r|vl3dK)f^?n(#?oml9_oqx zf7o#$>ScE5Zhq&!7K%|n@HI9<`6P|Q2*F5azC&8h$b9A|Up=y|lUs`Il;gfD^ey%{ zeENlL;j;VN{;mSv?Dm>~!IhzE+(Pl~-AT%OzGr@H2lnl-lfW{v$P;bz*%i4B?jYy- zyQzMryKXVxk-DMgA`MK}jW?p!17Wbp4w=Tw7;QSm89F4qme>~Vd>q#|t;W#nbhLSF zYxPU9&`a}aJH_Tnc88q5*menu0CipL4!+2Z%yRRta{D{~+Dbj<7CZ^a#(g(}*bDiU z?+(5i#4P<9sBYbMLllIOSyvDxB}4L&DT|?AQN;;OS^#1r#ERmL2LuCOK6&Vu$?CW9~!^ z=>3%+ifpl8a(iBho`j=b&&yHl^VMxq{%vl-bwHmk?m=CEdc8X6s*RU4#NcSB_%RnJ zlvelrI=2UHdD98S^#N`@S)n_^!;tWU=niH6e4O}taenhjtCJtFpf_V1`3QR?ZDZIt z#-Ib-d<(aptkC_OEp9o|%_+FsEj!`%+yGHi_-?h>xp(X9z?{EeOGMk92CIViu`f`$ zWN0wT854xzsiGEWz6n!f-m^}8oXyA$pnF5>$E-p#**I}dswk`;PS zd(6q{bnzeZ!D@8h!yo*v*7 ziUTosHG1kp52u2EbbHXg-R1_1=et=wcwQd5B|ZPi3;mk=Q-qAc(;*(@tr?q)Qx+Zy z<*;>KcxX{^Z+%S7ol6H(zKf;72QbrCDYF9Tj~M0Bzne1stV7C*P`HXmvZ0y!csTTH zJbk1-Jdix_7`3nR`#`|)Y7_NbzK?Fi&DEC?id^T2RgEGHO=bts0kavNzzyGgw_t+X ze+Gu|jEQzy+F(d*ZzuaD7k803l3?rTffE_U0Ou!Ko&yH55jU-L&d2QoJsfoEcpZYF zOYj(cO%GwhIE#^B=eE!ebbGDmCH6$XIf)ymbHR=WbL5%;jy!ast{vzMIbTG&l63{R zAR!SZ3^=$8p!;8X!bOvym{EORtPWkVm%@EFQu!s^D54lfuqB~T_^i;5`*7~~7CJZL zbKN2Jyr9rI5{OahO+qo?Mn4Fl7~aBr%W)uf=r~4k;gvBRojXV2CcT>Y28 zj+YSk4_nYg%8A{16w88y(wErp{}*#_9v@Ya{r%t00%0*1g;88-HKRe65JgNBBn=(t zXrm~gID$>c0+B3C(oIlN1Kq8(F^Y~lj4R_dIODjDqT&XE;4W^sq2Ra-Z9s7Y6p-h0 zs!nx^L;CxCfAjqFyDv!J`@VHgojP^u)OI_;sUC(Oa%Xn$;n~M8&+d!3-6iL*sw3z= zMo-lyXZL;O2J(d(nizHMqDIM+vj>yFYWi_!cEOo?=^*no)R6HZ8W@pN(r7K~V3a%; zr#YhzQ~uHe32A8vaj{s-$VLOE-oIOyM^$j6l@anR@-T|{hu(?P5sYrm?yGK%KzVy- zAByF_F3~QKg>Z7J8YEAKd%*?!!sC!o1;X{&BalusHexc`S$D63~- zu2=$`bw+kK`hXwMSP%sWLnI;)oo6<|gD=DwgQ9CDx+Ro?&d$?-I)xc15W@JuXgia! z5(ur(2U8jZCki{{c4`7LTwh{Alqg08Fb!GeDs)PRqLYNX!f&<5KBHR-9;H?Jj;5jn zQI7qK0Hx!yANI-$bD06nrV} zX?KIoF;k;pOCIfcHG2?!oJyYQ-ibv!+~|6z3aNv}$h33`2yIs;O%XIXX+T67MoE1I~VMN^Q(Fg6SG>g=wE zV##fIc8@rM*I{2~7eGGRN>-O8c(@>-8c+s;@}WThr6h(J5gEGRrk)^bj6)t zQme|GJvmD5Po|y{Rj1*}3lK}c^>`kn!sp|`xOxa~_3)KBYNeuAmuPr$=Id8ra@QmC zLk}DXDJPkZZ$b8f9o5n&bN%I*$z`6H<9(2{$!r`>LqZthdR)yQLl4eAh$esMbeY_R zgvmbjkVX4+sAsA=?w$Gc70WTt%{*mtmjxGefy&ejFakW0>%X_&%0XdOSB1GL-M;{v zF{eM6eM;ufXr6sAhFtV=25km6(KZ{lCF^FFhij(S)YgPA3Ds83sj78C)&`^#iquD% zswz)(0=@}>&_v&;V5u{^y0&~qlhas5yKfcYhDIk;T~k|C-{4f#g_^2r!LVlvxig)a zk=db!`cT!}ny}M^JwBBwHbgnAs=2eV--zA3kP=2at>ts7DnoVUO|zUCHI*Se6>hAU zeTh>MYNT6EW2mNnb|hRL(s|c3)H~s-y4iTXDN-A5a++&uE0L%&GP|~>0wsfJ^+2e( zp|KJ>rYJNDIJ2QKJUvqFR5w;tk)-eclU24d0swl_(nJ~Ay8w#oY$eQ|4 zT~%FO1Bz8y^~Xp9cC5*0N|}(haXmIQkwrswHB8Y-v5+Y?r!TE?>Kj7X!LJITPN>ih zDveB4-GJR*st~GaN0&g`#Hd||&1k2-Y6kYpQPRe`ntIwfuc@npB%IY=VoYvX92@Ty zvrr|peI03{TF35hcxI>?hA}=t-c;{YL>g(gn{ua}@awfgKhS@^0}}_D1@DB5;DC>S^S*`a0>99GAZHPuaM28~VO3RQCCQ;!;%<&fhc=cWqC zBfkzcmp5rQCtaXeodYjuXuO0yi+qx@=2s4I8opGy1Z0FMDK&@l&py{53YJZnsCK>U zE74}CG^z&iWN0RgT?<3Q=V+r{wMFEH22tnWb%gT98BWuzn%PQjMMHhPZpKXwk;aND z)tH^ihUR)yJ$a|yg6Opfyc&>tLxDVUXGsBb*{yEL5jGC&D6*WTG z74H^IM`b(b&qU-fFCHLHR8`=O22_>a&yrd9`UL)RIU_c`f2WI07$1$f=l#mO*Yu!H`3qQ!%p&0xoWt-h?{P z;V?Y2v7tE>Zooei4#RbbT5uUW*{tjWk7=mHdn}HR+7~<@VN`joinkQBgb%Yfqmfjr z!p>}{Qvpt=E3a)XN7Yet}}> zm0Y}nQ=yYlqjfsULlFr+govrKYKVl%T}Z5HeJS6dcW_dH#A#FxgcnSdQ|sVDL87K9 zgcnxm4HtUXL@lHptIA>eN(XP@R8m}nDyZ6uh6sXQ zd1WOUHeO;uArb6JEkxL=>9ytcvjECfzl4M}wT_AbXf+6Uh(xKI?4y&&V@{VNgoQS~*|%Er{)QEAEeXu1v6cm}<$>1|-r*|QOM z$Opp>C=}jmnNG10MU3EuBlQN9qXLqHxU9TEg(7;d$f>NS?g=kKA^1`jq2?O+8BA0T zNh)qZ_4-I{E$YjeV7!>U3q1`)K&KjX`S>6or4G8f(m^n7tiel3Fa}j!c`X@4zZis8 zJ2$M{yHWRTrg13MP;QPx)TQhAin^r8UrF7cQ>h=SMAo4>RgF!QY(fnh3`GwWz=%{T zZ=lze=*=v+nTjXq4>>^8O%I_mIP**@jLMYSK1;(8>4VS1+ zDLhg8Y6`&{@hVlS>EO9a@-ICUadf*0!Rawxp{}u_3V+&R;>6N(&(e{50*{o?o>W~^ zC(>N8pGVLeT2%FOU~cs7<+bo`1W~kFG$*Y->Iy@eNNweGxa}-B!OSYe3vzZf@R}Z} zn1#33RLic%7zt$x!Pg`8_2fJe^d4xVb>*t%bi6~Rida!sJ{w&@ZLM_ys6Fe}gh3_sVa?^R5Y%m? zKEj#N*np8Lg&1-+s#QdjR0m1EsRnK)+LB991EN?+T?|znjleKUpdz9Fszy_)PXdaBb=R+vu4Mx&{p;Z;?v z0~?QkIkI7ZQSa1oTUG;mj!kMvsXReNB6}=J`qz~=&Qe1YYEgR1q2~ok=_+b^snJ=g z4r-MBOy{J8qk7e#CuABf#&D(yTkn9vr_dY2Iclib80f$?_Q|#*LXmbA2xb*?&`~us z)y%EE1lMRqn9!hN)T~F@1Z|J{A9cQOTY#gG7t4N+7G$;=(ER-^PS~auCF?6<&vr1gVL#Ck#dNp zipClY0pX$KD?E->nyQwB7J!~f51r6{6r*v82?tHixuyQHb4y20EG<=od)!L%f6P!jbx_5i_dl5iu)p zS&qrZ2)q(KXxLEipc&plXP@XDR6V|IH0)PfMROIN^Gpbo27@8Y7RbHID~IThlhvSt zCp|pqYer3Cpr>XwW;#T(Glv^OlkTK>SgM>PR9{t9*+e6En9`|-Q>)>a?sfHht z$C*X35vv-QilKd|9wHQ~)m>9~4to6x-S+nn0A@n32LZa)b@)+Dy`rHuQdjTH?TGt& z(v*t+RSjy2I-R;p%&akAqGI4}Y0MF*{_AxxA;;J28oK#AW@LgY!lW7<7TIGo{h;1h zb%u2)OEsQCHKD+|vQ(%jub73-PY*TqgwKvClti_D8t!ZN)XO&L<}jquQB7AreA<{y zDXUhJ(6TUw(?baUpxF^*U?idZvpf=RsK7dl8Hn+$lS`%sa~MBioZ>Xjrga&-L=N+! zr><2)L+Y(*Y^lN)LJf@>b%$aPn9vzwe2S<(yS%ZSI&?X}pfw!TbB&rb`pnXadKKWT zi4&-+Mia&o&Gg8O85G-8Pi!KS#ff@At_MU|cB0iM73DBw!djEAB{)<) zc@%nAbpN((sYDp;swFlxfTh_5kM6YOR3B(J*Yd_N>QheuLP(D(CNKS{0j!$7t6G`e zi1w_O68xnTMmq>P$cUub)v@&=^5;$MCtaqNb^;AQILFrTJX}W~rg+1-w2}K*iz8 zgzaf!fpG(^!ytb>U#e|@)wuBR%qBf(Z>UG-Y63mHdH*hr29^k(7y+f0;;QTC!owQs zs+&6I?__oIPl_o#Ow(DYhGUNhp;R5bNex&L9x#08IK`t{ReyDMDU3qOCAgmTCx~Cg_%Ampl_>N3}eW||h zV7}Prx%6DeGq;!L@Sa_B7U4S{^aVZhEmigF&&K91@m$_LH^<+@3E*Cl{z36zAe)w{GMKi|cdNXRf=k_Yi%^BNc0!~Kf z=A5C*I-Ap)-)yMLFIX+aEM`XEbE2|dNA_*YL|L!Rf)-bieWP8*=9XmK*j?%6v&=fS zM{s}W?@_it97|tZ9f%F=GRgfpQSXJ^lc<@jKQ^%&siIPrurvte({;| zX|M~Jn_t{BjqQ9b3_d18X>)a`V?{u-8CH&1`RZo0B)1gxDe`GrRHEVGz z)9JjHG9CV%*!!jD-{ZR7*EBVj4=%Ji zL@do(+WxyLoh++cQ*b4khu>zAS+RZArxda0ZJ2UmLCoyDs#>&mUQnlMFI_E$={-V> z&8eELd54*|U?DcOP1~_R(lOaVdDXX>Y5P~bFTmTtN+(nQWEEu=Md4y<<6{5in9epH zp)9mZZ5!+OLh}GRD9+G)VE0~qlo7;1{7C#ad_F-O#Oaqf82$!995Ve@jrU8x%i{fT zZsgE7hz^qD#ec)Qqy5n#^F7kyUfeh7Pqp~b7B5f3udujX-uo?Xmv^(pkFn(MNW%-c zYbO2e^no<|B8z)1`3sp-Hq>XB@@A4?94FxavG{NJ?<}5Y@zH7cwP|<{9{SSl-&=By zu=sHnFR?g{sf|7}EpFSPB@MsF;b7oo^5fvTyrgMr@z+Xqb$2UYjHdMMvL3>zfZ&ane{!$w(IwJi`(*x z((ut~cy$^cOT(YDxUK(2i~B7*{J@<2(2lEz@oy5Oda>mcTimwiWQz~BiS+YS#{ ze5jTF5$3X8e84;dX=zSm;{V}?-~tEfS&ILL4`VLV2d(tBKJ`|5`Xzcs&Sh45ThD8l zOFi$gxZUqOZgIPxT4l)}W99pi#qIgmcNX_r>3i@*k?b(a;`5o49qe*lYo)i#^(W@C zTzjqbw%uG3ibJMsNHfj19{+x31J zO`dU(eZ2T@(ho_)A7U=$%%{!ldO&eNt8e~UQ}pHuu@=6y&w4kP~q<{Tzd{1fKf98-KF zbFY%pA?FL`d4hk)JYVn}G9ZqD`XeR(J5E1D@E@5|45Y*8zk_*^#woswIn9aaFzNR) zFHy9En{_U~;9XfyYHM^DIX##MHBNDt`FO#5GoL8361^*lK&4Mpw zzD4k7nQs$(3G<%>pWR)9oq|thzFTnfXB8ZezG33YG)|u-cqQ{3!Dlk>DR?dOUVn%-k!u+5gTHJjUts1z*T~py1asA0qf7=JbAntsR!mgJOna>k^1M?QaH!+V1{w4E;f^TMi zt>8w_MS^eR^fw9q6Z6G_?__?v;JcYG5!}4$bg$r9yk5Ul@Eqn33f`0XBZBv0{>g&bl^wE>giPMtOPF{cK^Xqt94vS{CBQ-Nm(gL; zFJpa%2wu$P9U=H=o=2P^_$O?)^946AtX2ws2iyOTf_LF{_A3NW@V;iN;0t*F#>6pG zuC+XFxlg1Yr;G1ACU}U~yI&CeMb^i(cO(Cg+)zFe=?l4`d@cAc&i6;bhnq&jpGLlk zV+RPnhRb`H;JGQu>ZU+xY>vMQ1Jh- z|9mOua~*|6u>f;dW;1yo&A6NAPdByk5cAaC;dj_;i+2BzQm8(=Yh3 ze0`qaQ`m0P1;1Mt*QpnLA^Y2mZ`Of~J+I;V zGV3>nmvH)Tgq$)?Z`Nr{`sG}IX5Gc`0M}zK`;p;KaojWO9EO{}et5h{e*))g)*(## zE4e+66zQk)wOJ=H=}qT~a~e`kA|`L~hNll5;A>3^XFINAh1p5wrig1^N2 zn|Y^^e>J!3S48>~xu0DxxR3SxLhxx^f9CrFMt*?P?-A(_XMgL??ZBkp$@P1P;AI>q z^8`PE^(++J{H40n1z*JS&lLPN_QT17|G?#{68uLV|1=67xBG{A~8uHG-RY?mL2?!*T30!QW?n%wLW)_WX+d zVY^6A-wU8)x8P4|>|}6#8aXRCU5?<}xW3GI(4;?=)AteS|Hb{(VS-=B@x&|m?^w=p zf-mQC4HUeF?SG=+D>%Lt30}?Z=ybt1upRt@Kg03l48b2_ZvJAYvBPcLzRnZrf6x9o zMeu_;{dB?Ca(Qb6k5EQ9E)%?j+sk~xH?SS97W{Vh!#2VH%=Z72;B&aX{v!A!t&Ve- z;Meo@eS#mtdj3Q3|e)bXU?H*vi`C-{5ppQ{8vll}h{!Kbqw-V%HOx4ZR% z*KpkULhwtuzP1Uzn9KW{;O0H2?(C1oe|}>7A0qhu+>Y`DH~F3}`17o%>EDd}$C!si z`Zl(It>E`_x#kK!lJ$uTZuGoS@KMH31UG*Cpy0-C=DlU3|9{vI&HTgg!R!z33OU!Y z|NKYr67Jt~x!gw1mz@4E!Oeb6q2T}I`W+$oYOe1x!Q0snCkeiS$9v_1FJQgv1b>MA z_7cGl;`)sXzJcrU2Ehlgo_7dt)>-~8_!jn0vyM);$pogp)`;|#TrXxl+oUh&a{XJR ze~9gG)|E~ABy;@gV09RNHQVzb!Hqus1ULGa^;9Frw4-8?ely4Uaf0{Z@#=+wn|x~o zpTu@(7TlEUTERDR{oX3Lk-t=MBj2pInR1!$A*>eZU*R}u-iJ5oUt@pxTBJXS+xw4# zf6e}27JQ8yGp{>MprM+k1}@l3(*;&NRe_#^Bm^@6{}el<^U zlkYWxn|v1wZv6Rv!O!P7^SI!B*bc7CX||jEgQ3d_C9uEWu4Z&K2C0>qfyN+@Ibn`1>4J9~1m6 z_GdHhF!q_k`n)O9n|aO#!ME}Jpsy!v#N?^~o3fJFdr*1vl#yqXd6~>$ghqLCkLu z{1N9pAqS|v0c^*Ue0m#Bf+y+{#Sw*u${jb{8P?%kKiuH!#->$ zqvrrR!QmCWg`YRyw=(HZ;CNCb(*K$B^$R|q?KxiXf0%Y5_;${Brr`C=!-7A;*YgFx zk+0hXAI5V2BKSS*Z}$m)D3|w9!KZP#o)f$e$MaVNU(e-zU-04FAAK(PB95P11wV`R z|5fm_Io=(_5r8_RnI$XR`id1V4w{;{?HfV!KTfJg(i%sT16M zANx|l-(!1TE%?9LpZ_HISzIr732ye){vmiF+wn=kzvA||O7M&M`YplFV>^E$_zaeB z)^$w1e8k-BI~jgHkGu8?IiGR8_b}se*pW`3U~bkOjhqL#evcLD&G#(}1g~a0pCpym z=D!55*6KSi2wu zF~N;Ly&$+5H@+^o8Ha2V{AG?~KQkvY=5bl+qbq+8k@zVV@5S8I%Xe&tBdzquTImZc zKFs1pLQXNqbHCtEv;6Uv9BR5t*l%Wt^Z_34HCdcOJe%2R7Tl;b&*CK7j3*aboa8Ly z2d)+TG3GZ|oaFq0`V8!fKN#r}M!#YvylbQ8zjg5S&hQNc~z zc|!2R*q>Gl-o)203tq+79|)e$FF1c9cz5QTEKVv8;&!pc;#96me$ix`;O8;_+2SN; z3ft4e`56Dt669!oMdq-SJM&r zf#VdxXD}aOanh%R>wS#HN&c%O1jo4+C;3P6_nFTV{AZSbp~XqgTO6NfSe)dn&Kd=O2RaX8x++M{&767knu5or0fx3^KuS z0Q-xnU-N$3!4@Yy13a!f#^Pj$*ZBL)#|i!d^OFUi;l)EZiUl9%RoFS*;$*iaY`1eP zPWjF~TBn~Rc$m3qAI6`TGoLBao9`#rGdK2k`TBan&*JL`1pfzLuM)h9?Y~a&IQz+` zg5S>k2f<(D`g6HG89jgGcHUR;Oin*U@I5Sdgy0AB_4$JD@M=5%QE)HYGa>ki%gmvERNe_yFeXnH&2w^Z4~!!LMZAh1-)!|4-%v1#f3Q zPH;2stP=c6?l0nkn{m~Rf-mBFeAwbV6i^lLw8hC}rd~G+K90+|L+~hb6DLf0uVX%p z{nYR~n2#3xVdm#BH}zP;4MMV>q`ZX@b#Ys zPw@4_g5Ss2YXvvy-V;3PRqo(?EBHe8pDujg*ynNPUcnFH_%lNALCnu#PVI$U(9DCT ziuBWPkB%0v`bf=F=5Tw73Es#&VR5^^zS-i`9+z|azX<*i^E)k0a?CvU?-nOH!94uH z@sL-2r1Tuc{5iqDV7^lD7nrXTeDZOQI^GlfEao3sob=2v^GA!5p6_z{q~L3re`|4) zW9H+(TAbu8Ivzi8{N`03sq!vl?y_H)@x~9#dkemec|LOw#8Et7K|gSmiS&o$Yd%i! z-!VT|$l1bjLW1vNK1c97nVa9=V*K+lUT^uc$ae(idz;{=F<&C&)9>Y`<7vTHYwWB_ z!#4@}(^>wPf=^? z_|eS25d3uJnH*P){#DHT3vTu?hY23c)cKwzxcQ#gbmqoyucbzeqh6#pzxV$JD?Qa$ zpZ+SjbF<*v+5YznKJ5gZ{_ldH$NXW7lPV^DK4Wpp*E2xNc|q{^S`g@s(uzHIahJ|V+CKpJm2CZr!hz8JJjMN=POQMB=~d8M_8QXyvg(2GK-U(2T#)S z#|hrT{9KEZoWFCqF0weunSHXBGhOg%<})l#a?JabO%^9PTRDBR;2W9GvpC7QlPU%x|zb$r(pKaNJ>Wk`pXa*!ipAUgq~(oJ7px{hh}wPI68^Rm)i> zcs}!IEKYKEvz)aSCpkk-({f%D`~>FfEKYJB=5?427AHA3aQaPxU(Wn1i<2Dl{^Iu* zCpni7#}6Do3tq?kSBsOJ^Vxs8{9Zkl8gKkz1YZkY!rZku$!YGQ(;p%Dy|lQ3Bj4hr z=c}hH>nYK4CJNrpaxSnq$zk(5RTd{X zNBOjz8o>`{UT<-dW7e@RwK&OX9LCpn*S`acQ2n)zajlblwr z_j@f)a=fGQ1IJRqcaGBhpB5)MH)U)7w8crz>we9j6Z|RWFIt@B^kq43TAbwEQL5#< zBlvC1Kd?BtS}*SRH(8wId)Ys?Se)d)%5t^|zJmGB7AHCLdA!=4$MqgC%JLWX^FC>K zA#>Azm5#wfI8GLPB=ge+zlHfI!Ea(dmbuaA0ABZ=Dfk`SF0K~*QRaUYd?oXT1b>_P z>wbd7aoTiIl}{5pYDPWW$s$swnJZwlO6uf>5mZncIGDtes-D8cd+24%uf;g zL*`~)X!Kvr+%M8Uc7~Q85PT`~a|9oBrcOUe@MD?(fw}S9E$k;z!RK<^xK;2a%>O31 zc~5tx;N95&KM~yg9-$uvzl_^mkN&zGM$fC5A1nA#ycj%6@Bs4*1iys&6@r`ZH?<1B zhtuC9cu$@eJSTV`w�-4`BYS;G>xD5_~H2V@}xD4voyq1izhmqu>uQzftftT#pY5 zZr%@HBlu2Eze(@|sL|l~Rq(@@A2>kYH}!Zi^L)W?W?mxr-OMKo{vq=!!Oiy;FBkk5 zPJfNyzvp?)y@C&7{;c3d%-<8djQP)k&u4zXzN~dzemnEKEKd3xeg0u_lG87!>u@ou_dI4+uV<`C~$UIm>_6N>BB;g7taB;w1m@v+x7Q+kzj+e7(hO zIsdV^@&``eF8CtmKMDQ?^PPfkWZrv-){ELZ$v^UJeSL`FhcZ8cxv7_Gw!=`tFJ&GS z{2JyBg8!BI)q+36{87O_W&VobJDGnj_~|`$xw;kVPow`tPJgiAW}PjMxrv8Q_R`Ov zD7f*f3c>Hs(&^3mrIGU#IWLY|MfzL1X?{0zqvs}i5XaLZy^;Tp#ScWf5ZBjw!6z^` z>!7CIlgyJM{a4JtvpA_9?@HP@&JN~A&lc7*_e6c)l-Jnjc#9v1B!kB5bOQuGn)#`M zKgaxZ!T-hFZ*kJo{GQVB%#EJry{0BBJ?RrXN9)rp`032&S)AmX_ed97oaF4}^w$dh z4f7i;PI62?b%(`C&b{a22adlAehc%*1V3YfPQOg>QOws0{wVX;1b=|}I*XH@7m)#R zd@lHJ><>Q(zKi|&H;Yrb4w|UMI2kADPveKV%)45g@;#r&KfNtZa)O-x5Wxe?z06I$ zugli?onWQ!4Kz(-=QN9x{Hs{bNWm8{4+y@Rc~I~dnNJeDo%scVCz)Sl@!po6Gb~Pe z9z01GV3y#$n1=ov-zITJZkNUle=+^EHBB%6uJj<5xeiUu_n=OBbDQkD>b0q|aww zAb1J$v4U4IuNV9&=GO}T9`k<*-j&JHb6HXBTthhvT{4k2Tl{xOZ}d6I;v{FpWG(j;!B1vB+~Oq1=pV2+$yvhbgM#1Ad=m3ix!9f|D}8Us zS)|o*W?P)(Z(uoL!9Qevx!{Lgpasnr{9xwS2!0;(>jWRq{7)9Q^}OBUq~`;ieu?1s zFn>Vs-~XejfAeA}!DO)ok{wBLz<|FA>~)zot^~mpJ`A!M8BK zL-4bC9QBOgvzTuZd^Wf1pP8HZb_K`1gNk*z3^(ofD8Ws8tP$MAw}{{$XtBB)E}3 zPH-dt0>O>^TEUwr_~E!h@Q}t%tKgUOy4hWVU(IqJ72L>qUT`C49dqO7Etxvwb}K!_ zpXa$@)fzed95~ zPhQ1D}zpDcJQ^J2lT zX6|Qh?ADhGj^ivVJ(btIhk233sk|>u!w($O1z$CdsN>AAxGiV4#YxVVX_VS=!h&y} zrm(X>@Z-xhze@1mGrwMNlm1VFoAisB8#{Q}4i5>wk^Smz!AElXO@cqi>9-308uN@1 zx*YU4h0b3%K6FXLUBUmtak6(BeuUuL4$%2|)A0U+U(idZAC!ilEckrxPm9xVpWy3R z|I##koZ#l~UYwJLUm*CCEPtxtUAbJ9f>)6P;Fy_)&lbEkSEmoB;g<`33;W6ZH2fOD zmum6Ob!qr5f)Am_gyYsU{2sv{V}1UXhCeL$u0C4+ztZq$1b>6mzmSHn6?`uH=WA*B zyMlks_4`2@zEN=Ve#IAQc)Q?Fu>Rkr;X4F>($)6am4;`YuJ4=nem>V%SHb78ALa_4 z%kAr+H2iSE-{kRjzcl=K!LQ=|hyiK%P{A)}{fpA@62VVq{rzcpP;%C1d>TGk@Vz`P zosx!E3VsjIcV?#Hvjy+VaU-0D&lCI@j`J;P_(H)yI7s`)wQ2ZLo;Q$ta8pqayfdc5 zugC?L=jrQj((sJ2ou?ln_}*i6xb!jV^v0?=``oT= zsMzPays^A~Mis>CC(M<~OrzSG`YLl9`8k6t8tUq*>Y-eHL%3@2*s~@LY6_QE%wn-s zGegyl<#kos9RJThy^ugAH~wk_mhj2F#~7kNjsF^YI8JEDR$>5uF72f&(o2J09EadP z5e_#_UxGM}!++xJ{)E)=CFje-L4%EZrmhF#jAY8^H}mr*Kl6Z;N6WF4e}+lGpXT|^ zx)`au^7%sC>8$)O^B>|f@99waDfAnCO!+CyQ5L*ChckVc??cFP8FkF(xkzr#&9n6R zZl1oniQ}lbC)3jF6`ko{RG?FCtJP1E{-nFq{~|Cclb)DSK|djz`#XKLf7(CdMrY5@ znyH^Sv)nwXKV@1{uQUDgIgl*n$4P(cN~Qku!K6%jWZ5h96Z2*Lk@_jq&cmI~@?XdK zo98Ki>aS$}i@>BzAm?k&-|U|dqeG^>rxQl$s@Ks^yk~Wk{xm=3^LOG#XZkyL=#;kp zy^vPw|1cP(H0f}vj`+9wb0e>ZF;3}k^jMA?ojqTfrBis#gZycpGoP#Yd6CSC@$-_K z=M4XlpO@`_AwR!R+%V-g&%cY4&g?gY?dRnTss70n=6Tcp>9)uM1mDl-svrE212d(k zSSz2W;gyULK+fg^^z-KL*Ab(G)zKIDNyFF9o*#dwPWkUtN_`@qM~_uk913!P~^l<|5 z?cpAQ_}*}rB*8`MZw0Ta9_;pu(RG^pR4}SB*ivQ914>2I58k0u=NUO&=~G!KBjD-l z!$nqBb`84cj4X94!=q{_Lx15t!=oxF1y%IR$Wb5JIcMW(mD)4dLz2vKFrRpCCu=CN zo&wjh46`Afu)^-PB;y`V0)o1ECT0HUnbgfQ5g!w~dCtMdIp~IRh9W<$$I)r@pvScy z$Mn3!sEJR_j_riyb*{(F>Gj|dAAIu2o*n0h_jEi5dVZhVyGLg3;kgHT4(dw3!Z0Jx z>CxkKAk@XdPG;_@Jx2J@%KnPg527-c!I|6S(FI2ID}eevPtYa_i zp3{j$c*_5D!ypw#Bn$k3%WR~-`5lzM-O=X56VoV)gy zxL>JhfT;s?s%s z*w8^3{YT~wno%DqC@QF_uc(bwR^gYCn4nrgQk%k+l~vV)XR6qU-#ge%tAjh4d7kXd z-q~Hc;G@f5vwPsvGo#C|`?HKL(4%>Fc{p6vSf3J4CpGmm9K)+?%V#vD?hdYSnk$-A zaCZ>z@L+jusM)CI)Hc-5@J8yJYG%||ReC8PVy5C9U3iMOXz)pchj<6og(LM-)W(+(OSpclSRsJMGn}C)0hO zd?HiLP9&xDD&+5XBQrG;+4okaLnD&?k4!cC?u^^3I34#h9n&^D7@cJ*YwpW5H!Zy5 z-bkDtWZB2qnRB|EY=b(x0j^(rfo#eGFhds3vK-%y1qmsx>EbPD#xOhdNpMKMnusps^nvh99pl z)i~AW#_6h?zx!||*bv1v|2elUy(XO%5Qy#n(pZYG1$=C2(MEVz4ACr$sZ@BRz z;%er>=}l}i`Y?7X`9yLrbJE>z?=*d&!*H*CWAavnd2Zgz4|TKk~>jb#3} z&r|uNOp-H zXFhM@=S4E-4cQ>Y^CtZR{5)5;!Ol8fA}VqCHD9xPMYux zsp@x^9pB#9?bkw&1){4wf#@zbd|X-U(9hguT@s)AidIK92NU0Iru*>~kqs9nHc$0U z@lEwzv}#e|R_hACT-A5J?>yfm-^5_s49}zqf#{aL5PzkoG`81`k(~n3wHf}zuZ5qq zAMW<^qt9PDqozx z<%|C2d5WeCZt2T`R)1bjA}0`C-M6gGe?-QGTtZ)HRWPw>Z5K*LH!ZH@6z>QJvH=@aU`k3gIHNT^ETx=B(Y7Zt8pRo$^d zTfNA4exPk^mbNL|v-QfXKq4!zG!BzKLxzd2&Cw?9TfImbb8S}Z`Mb%caoF>ABnh?+ zy@SO25*wnh>&H>p_5J@3b}d$RZ5^5i+ggVGcvP$ZWO9kOeXX$UK~(?I-P)!;*S|Kg z(wMb1E03%fX!9@5u}l~M@6@(1R*V#OVBg`e?*W#5BPW$Cw5?dOa6dD4SP=HqcBd+U zeu3g0ZtO|8y}Qhfz2e3m#3`}pLpbqGEG>McwD6PC!gnSWt|%>BF(E((rk*!1)jrmG zN>Sn~TYkCFjjh4GIm26ind-)(IBoo6%P;dHJ^hJSx~+6$M?>NwWTWzry%H`76#o`^ zA&}Tc27oRtc*1G0&tL2vw z?$y0P$`TvgWy!L4xA>x8di-wb`^jH^+q-uWJ+KWYrhcQp&I_N4%t@P9lIw9tx07I7 z$b$mvykAfckXjDv6Sb54CkR}975=O9RQ|s6$0gQMb16%_;hX47>@M6p$)9**LLl*D zFtG;lD9}=zU*g`hHjtQ@*Q@ZIfafh0*8*g<*AV5)5^H>I{=ALRo&DUa$B=il{f;sY zRAem(c-HOR6o`M~-sI04;x5AvxckV+?_(<>M+aKNdA*=9>MEG{C7Adjkl4667u_BS zo`m2WY^}`eRn}JO8CSd`h*;J)kU+>ma0w>n<#_{cDGKAyD@tsRZrX+B9fUk@pmkne z&hmN4KA709^#oQ==9d+34|fX|f8k!ekkmu`$`2xWQ6Rb*5ggAUV*2xX`P`e<_`8Sm zhG@I`TL&Ay_zfl#55D>6izqVvPSu!7% zJmG(^Ysv2pS30azW@ddc6tHZR}!XK8G!8^2N|?wMyy^g}SAtW=)LR$fcd;BZs0I4@5<<9A2Fg~r9d3?F6MiEbpp#D6wZIjCxfP}GR7_5_R3P~7On zxJ=Bw(W;DrLMMXZeBR zx819bLL2iZUiK&6M5j`g`0ee@(XV?&KZmP-5Z&g%Q$3@bJV-rop+E0psz=mN&$70$ z9u%&hs`B_N;ls4=w>sPXlRchr4|Cai#NyJzFUgL*=46$+%Z@`i2cpyH;cL0lgKnuW z#@EqZBi-14Ft%~8djQ%-ccIsN3T_|WHN}mejS~t{-azrZyuOi>(1xc(29>pq@lfN3 zM?VkG&@F%dYAUSdsHQ(vVGb(v4X;PtrfM5#4h_xLb73NH=~p#{MLZ%uoFQ zI-Th5f=Esb4YNB$_!mO?AR3j|k75jLA8Yj5Gcr62V%*qc5L{OLDTW|ehjNz<2(*p% zKs3pR>Kk&9ElKRr0zuIK3Dx7R!l*Cu43b4wm&U(zV|S@`J_cRom&)XGvQdxK9&}>u z_o#N$a$0`meQJXkp~8#DB{l~V2t(Un7>VpRzqxboURe0BK-*=W!gqp+Z?#<$tEfAS zUxacLu1J<3kCgvHo*OU44ed5-DDW2f5spi!ocRbgfnefiYM{N^d(n6+`jQ7h!HrG8 z%(yi1i%|gGA>l+|kJVRCynb`ehLk*sic@(PRrkZW1R z2LHlJbRcb6hf^b(M(&vM#DHl?y^I&S%d!@u0Sc^BhyN@?OZ z$S8qB6_t2*y74lK38YcsR*Xd5_%b9`^Q)!s8F*aJV4@vy?X+OqEIsd9M84Fr7rsO# z^|L4PB~A_9jAtyX+(?QCVUKf2MiUw_?GpI&OfTpOnRfM*6J;WoPyRq@Rbgxl@$BK{yRnd-e z!Lxf}Aasbz2PNKMT)>UTaGPAPgfPnSb>f@EXa2;0f^9QBg)26X_z|HX@$dd0qoVvT z##dZ1Qkgh*2ig=Y+%vx2jdjDhk-RY_IralQ(^!Jav^cp51ZSwN#5aX2{E4sqi5;6i z`GIoy!QcPioQ1n^7z7rs(2DHXyj&&tzW+ybeOpXpsJ~0{y+{y%_UxmGY+J^aUbC?b`ITC!8ASwr^#KvSn)$UTl{1=n~G1y z&&FZU1{0pYmzDs=VPPq;u5d4PA5PiR_`y@K5@%f7T+eV+%Wxza4qvUrC#Lc4br<4< z-gWBhF6&zKBH}i#mruomT3rpQIpvq=ev^{{Qt8XunlmU2W+Z!~EmbeVSR@15 zhA<*n<1W~?gC>S+VG@K>H#Q0dSEA6lqft*K@rM|O9NlF{EKYU-=$Ox|P~v-@N;AFjEr^gi}k}3?4Esanw)}L9rDpU;nh9xe4s6yH!qM_ zySe{X)aevDM{9}h!qC1RF-|x7#D?d{M=4w+*Q3CTuui5PRCx2ZTc{ynM2`rMLeFbE z+Y{ZnH}RtDf7_Q>pZroO-vR;7THK{i*s2smjfjU@(!&5{iJ#j0cIZa~@YMm&PRxK48;!b3LK!TT$^8N9{&L+L z9hT}(M&nF*7-DzwA82N@ZkKo|zSWJbBIl!?IMP!OKHd043b4Y#N%XEQoI3Sk&{LNl^W zVh2y&VdBj#2sYH>$0J#=_1U}@sH&d3=qCb?=Pd+C-nQLt5BsDmM7s9%sJHl6+CW37 z6@P?tYFjyO{7syySob_t6mm!9m{Rjl><1`;`bYH)xllQU8~+$cjqj3wp|+^(iH*PfU0)BW%&$7hNSl4o6??KDt8Y@;{u#opu@>IkwRBV-#?1eMrlXww}GncB| z-1r}nQTxqGK5Sp&89t)9q0GH!Wm63<$7fI#wgoa`?}XnqAN1gZy10aCplR?6N3d*doJ;e!z$Hi?f1)RWYqp` zDqg~M;{)LFRQ_It+o{6#b8l@yH7F;~P8O<8NXsV^7Ezy2f{|Y!c@k(kNBlD7k^TuR(!SZ~)8MK^X2bk>=}-3Bhk&G(ZxfT4Fn zF|c@shJUGlVP)Q>fi~?XH6elPdX+2`<)KvEq zn-6&uG_q)*7vF(asJucAzTzvsM=gI&#l>i3hz_-F)8Jx=#46@ahZ~e7K21J?*vpy* z^QNH$?vn#^s#k997X1p1XCrlu>b4416nG}$0hJLZBovlf;CU<{tOdL!=G2%f-@{$ zzLd=0KYdn?yKFU0M_)?P1ayDpR&G6jq-{mR=uD3cy1B07CYynZwQ_4N-TYU_&3%mA zlWyM9adV$1Gco_J4PgS)?IlXqfMnEPn+`-(NOBFFfEK~fygx0)s$lGA3|f=_fiqK8 zj}In_f{EEVn2SFC9jcA`i{{@Y@4@*ZJtb6Axj*6B*K&G6q@7w379_Ef4K$9byBQ}u z3&tV~mal?|Z`4ZE=2_pWpr{viCLx(#?LidHFKZizDav*=f_vd;IPT^BSv zMXfFkUZ233+TNfok4dTBjR_EduKpR6NsX*K#uu<#78ZWzMrnIvE$&`1B1+pE)NbcB zMzOtd09K;>sr`*sSI28CGY!Z7M)M0;k-u;%ZFcGS6s7$Q8plL`!TtvAoV>vs99O*G z>iX5*M*Nk?YAO)z&$MDEp#8B9eOg^rvi7@pe9`LCoHw<<(cORA`8(a%+sFW$8@tu! z#vkGRC?D-^RO3|Zr=E-WqO`xUP^oi~8@m!GPyu@!dJiQzY~S>5{PzH~&w*6QLvg++ zO8Xlw&M+hhyi3g;dmC>j_b9jaD{*pv!;NjmT_~XUINrfUNBOYNk%dhIRmkL%N=gf~ zGW#6&fzUoj%AT~pIu2VDsr`*W+a+0Iha*~?kL`qCc!xu~5gF}uM0||CJGM8*l6U+U z+Z*50f-1&|{j&7R?Rjd5hE-cEIcJS4{*9LBt?do0)Be9~ZzNz23InO_jjYbLH`qUD ze?zar|Bw3{RWQZ>ZGXe3(xmn`P_WMSH%@{tz;9Ir{ulcj#+2{Dgj7cz`x{>DZ)Dl~ z8(76(Ps2|bdAAyRQULp3?r&uMSNj_ywNf4X8+zyHf49Gpp&ky8pl1-;|M&YFufQu| zivP|2M%I73zk$u3jT~yz?{C1$YJa0hDHPWG8{g^ujp+YnQM2h)+In1TKGr?MC;Qf7x&>vnqAYX= z`x6x6c`=|gah&QB6N90x?hgk*22vl>N$U1@&F%)CYk$LBwA-&Qpk3(qLCO;E)9WUI z`CDE_ZUKacjxCRAK{&PA^1wC%wmi1OZ?NSNNW7|dJngzpVq06k5+=Un{XelWK6EQ@o56v$Gqi{3B%AjD&C}65$+znJPSS59WapE z@)(K}_o`cy0oQz4_lt=+~JF~CD+LKLL#x4%LAXlj2Wdc|%`r!T~%Qo@aGgO2{z%d-M)Q*(ULy(4J}d@uGMcH*l7 zBubBH@)Iw0tN|X0r%M*1_?T_vwU5F3DfHaM>bck>kf(Mup2u3hzx6cC;j(PG+qz*s zWbbLbrFyqjc$w!ZN*8%it)wnX=IhQR%2yqP5a%|i=x=i_=qao+u44`XP6Me zbhMw5wf}y`G$@ZT<71UgFo>M91~Uch8`omL4^FBkR$f{Jz$)oaYCi+( zFKEDDxmQiVw+2%C85oseBUJBa{6Xnp?`P0v28M2WGvgE0EMY;a&a&dI?$th!{kAeD zLM3vN95?m=?nhHw8B1^le^-{eo}SeE7%`ku`qVzgpO7Ic5ig@u=H|KkG(96?9wSl(!EVbWLmiRUZLzVdOa#(Z^28#48X?IyL z?@U}y@nb#mrWJ|Tyf3@)J-9(z60~M;FojW!n&-m}N()ispGy;4{CIbZEKy3M^cl)Q z_UMfYFBWAUqUmaM&mcE86c78cF^o2PD4HPP)JRnAG(itF3C7Hvb}BBTr8~;*4V)zF z@I%k{Tf0PeVw<8TI`!yI>{C?0KE7vZHV$2)JF!T7AY05`HYM*&h^Cl571aPc`4eAp zv&4E7B={4*sfm2zJ1n;akrwMSLsSYFF^F{vYzVIQC3durEo~jFiuNVun|>?`_tb^O zUc=pxlUSuz4g8RUXZ(q+N=D&!k`TwMBx@sgXfu)B%5sn~n+s2*6j}*?HrGDP{vNgc zyR|ecx)bB~2Ptl~MRKA$r(l!v6E|J~X;i{9p%|1*tcvbLMgEftr`B0ioxJ15pTUE8 zyG(6rU_+zlN0&Q#`v_`cWzv*PQWq!{Wn3&g*_n{ew0t|xvfZi2BA?TPJGkNnc#V1`?$fI8XX+*e>-f7kO+EmgidSae;e0@A-ywiY3fVMQMTd%g2U_>* zYxW)X-E?>gD^|QnMb7VwUXe3GHw8DoOSQNwdSb(2iyPmHD+(gM)_Tke(VrTxLw~AI z6ED%)%4w*Y@F2AV%x^QARb##7px=5l9vi<6#*-D*3p>Sql4qfwReR;OK8UWVJuW9f z$wy%im_p67Oh@U)?uG45Fhjdb-lXaxh6hmRdYDI^PCGxTQ9v>uSBRqlw29WKImyEz znfg_zmHe{`8v6NEph~Pts@=i1Qlv-Ve#u?X3y~iF+Y|4|(0u=VTw2)`c3k4wV{xVA zBV6O9gZHuAM81GEiu0i@s(||D7eL9}9HQM=749WR<43Cgeb}vQxAa51gBO*7sBH(V zd~AN@eMrH61wv82T2%43<_FtmXSJQTmv%4wAFCCXO^9}uw&PGGK3X?$k{`n6sr+au zg*HO;z0GxyO<`;vwOe$_aAKH#Q``9-G(xidGs^ZQ2pM~l6!UzoW3tRz&$zZL;6-?U z1la@=d)f~q`$u2OO01*sM&E*HorK1CYUGWFm#Qp_#G2B># z60k|Xg+=4tKwFGz=ByA% zF+arS2X0ZuF_pS3u^PGr+G2T2h+;jHKIu>sGL;+BsL!DL@TRi1d3heDYgJZHQ&zn8 zzE5&$uUN82HR`of{Wx}av@qO=?)=S-(l)0dCMUdC<;JE#FvcL%*~CZUoEl@TKcP*6 z(G`~9u>b6HZ(i;1_HV46{u?tO^0Rrtw#)VFG&Du{(QS ziuv*5sAqw%73sK(^o`2bb^C#i>P6)jNxjrYPaY~fJ_3CWp7Ua(2l~PNAAuw__JY%; zc6yd5^OAwT!Da$YaO7@J!1aHMP<*DN#;@4!Sq|N3_|}&?GQ7{!8y!O5ROoW!^!+lt zcUgulvfaVrAKk0QVxf_|+DpsWlp)Pf@J8a7yU0S=yxRcJBX=!PW0i5mKe<=kgJfu{ zc?gS#Vh|Y~+uF2S?(^V42OOvO*E%I2&67hP>`d^GNU}2NzX`ISU z9;z2r403WkciaIjs~4g9_G~T9N#20aHZJj-+Pzi|u?p%XKLa%#3Fd6cYJ?tNYgQgj z;F71~Vo`$LScqSN0x6B%_-(W@JOL%w{Xpv|M2r#5v(+}v#jR)L&?`c1qjE6&dy^)S z-vtvdCTUNZ*N4<#$P3TY97Dkk-Cdcdk2(CJWjD)EN zW*y0sP%A1wWR5MJ!o6w)0?qtT1m1-$ou?7_e9_@FGN#{rz%45IFW|xz)D#>wcH4aJ zTgq#$UrDu!+E=&Kz>8yhArd67N970FbfCm2*DRA@*V>I;4OxN3)JDkp6W?Nc=Wd*g zSQE=?!Kd>S?Ft3k?o|$1jgYwnP?a5zhl6e7GqFlQ@w4KcHL*T)b41(t?2fCcZR4|| zE4ly#7IT8Bg-Du3Nwpw~{x72FrLF&my)OZ?qPp_0de!y%bvH}X&Auqmh`4mKs-S>? zifl?Z-H>htT9#&sEG^w2CfH3tqh^IfqfXFAcE*r|Ofrd4Cz_Z^OkyS`G3aO(63w{8 ziH^pYNlfzpoqO-^)_qmg4T8?h|NBzkN7p&$o_p>&=bpQrs#k16vT=4_wYMGz*I_M^ zVJ7A4;j`ziLwLoebP1&Xn95-M2CLPXIA!ksW9Q7?cYf=+=TV5U{+w)yEfW?sG5-1= zpb*~RT4rZWRZH?CwR3L5KvhpEUdMBR$n)6Q9{$1K{-&N@Jtt%8lAC^`pJ5Do?g!vh z{VT@;eUy9m*Fc-OJ9>^$g!jQfQqM8&0ANnPcm#utvVD&6VfQ)4JHe(RQt{4x{{l>O z`a#AO`a#A&7e2_C5B}$Vg$EhRFVFRriAA{29+QoaY(8T=4!4*PGQCPc-Cd#!XMmd4CTa;eK~HMky>&Ke&1B;n?#G^Lrx6 zAI-h#bv!JA@ZB%y85Aob_D{0T*cTn7|8ECj{2%6E>BSp3zg8B>+S#^T6Nh6cMa1)E zRz)rW%s97dx*(W=_>$?4QNtBo;tLtx$!=N)^DCHDF{3uhtZ!d9b-4HJFTShhgzJ6) z7UWDazuh?;&Xa4n`YZS0o)36M+p6{Jz4K2$W5x&|8#Zm-h`+7tR(LBntk`s=w`x=S zmJQzO^=sF+duz9>XkCZzl3d-g#cRbkO4_~Ft(#W0du^>NR<(FrTU$ZDdh?dm-geD@ z>EZ=m{lYn3eM6&nk^EcO;9YcSoj3D>`DmkMOS^~v9Bk!^Raa^Oa~eGPUgd(>-lmqT z)yE;1GgReFF1X0M@PhI9Hv#`9;@>3i(wXzU`ld^v#w_oGnYdr#)i0jqT~vR8H@AM0H@hCU ziQdI>o8T>y+jwtrz1OmR)rJ-L63qI|o8&t#S9(`%-Q4b=@Yc$fE!FZ77H{?D4I5S% z7@k;#FInn>6&r!Jt=P2MThY21-*Va9x~|3B(6Xkzx^=}CaII@;Ti@nwS-*B&A!S7y zzCE+P?Mkn8!`3z}O1_Y}!drI@By2Lb>W%o2PMfFyu3pi$&O>YKH?Q{AY~8Q{AJE*~ z>a}eUa@*z&>sN#G9W7fndz&}4cJy*% z_zXI9MZ0!F8>(+R_ z3tM*h)L4ttR{vx?J>|*eRE^CH!vrB~pM(>PnxG zSLzB)>c}NF2+p>}Zo%bZ*+h+c7vml;qfO$Ycp2@N_F2{jxE24TA6DU?^qpJ+OFT(D z%0DTWYaRYwgMU&-VBz0{e{u<*#H8R7%OYDYiASj~xYUtL>Py`%_$PIwE#Z?(_+(7P z>%0Rr))9WW$0Vb&1ZRgY+qN5I&J3^<4c}mwu2tFX5FwcgKa;^G0P!yVRS$7r8=n`&s0Q?$TFM z)|Kx>=d^iD_&4I8$Y!6r_J}`3Hv5(G#YgldK-D(;Ut~!?P$!m)9c)YbocwZU9I+on z2ihZTiT>OeoUE?87QG4_RD+r zL?f-YHb-^{T0Q0;-F??_g9}>fd9t9s3E05zR#meLO$+7Y{K0H=FB8HEQ z;Z-qwR17~QhL4Wnr^fIxG5oX`E@yN1I>SW(pBcktK5(x$ir2W60mt#NvGO=RE>=E1 zhEIs$6Jz+K7=Bg^KRbq>6T>IR@F_9;+!%gd44)dqr^WE;F z?iI(ExrKn29|doYm0uCV-+2^#N38tXqu?E}^3E83H1zNDf1!us^L-ru`}|+%ufNa# zh5q>a{9ovgzt8`L{`kK({}*ca=3_sv)89p0Ej|;+(1(_8lNtt|(g`+yX$I9kLabLey|&snEUB zPvMXJD^o3bf&RaJLLv3YWqX$V6o8ufv%QO@VT1GyOkjm%Pr{@`%#!v4=gohx+7?7lAnS*MXXO6yjQ%vDIcM&^}$32fUn za!JKbAUid3Y41CM?9#}>oc#P{w?^uEXK{?YQ6o(~??=fVja)vU4@z#+$kIVWf$Z1F zGNsM|jVv!|fp-sSq`9;j$lV&bLh1H^MpouVLcq6lmy{F_`cLo$`u}U{ojV95ya7!I z`oC@pKcrxFUJWuKN)dAE20B9IBZK5sa}D1*MBv^zi4R378$CoKM;-QZXY^8syxzIr zC?;uD1(+DE0!*s@9A$>B2j~VI08sHxAaAAqnthL(dQAtZw~8cnX6*4EMbYqkBe>__ z9ulFY^2?q!RH^jBb+{?Mo;D;C{Q%07zJ4cE6B`nFS@NPYD;qy84Dzd5?o3}j`dylSspQtXw=P&kdaua)eT?syu7d}=GlvLC2`e8H2`E1;g8NkW z68#iUpBe?LleIrRTm+FN@Rz>SkT0(oQZBKh!mwhfGR+{vauR1b9X1sw1xL_wsql`% zKjn&MeMYYsUeOn%NU}Pq>mKsIk^KzHlwb8<*WZET^-#fC^|x64&8fd7>Tjv~Tc-Z@ zP=9->zrA$$e3dHo@rD$^_$kZm1pXpyBNKXBqdY*q_#+UBn z)oM;Z{=V0dml`T$|DsF}>3Lq7I6IAaai-K2HVkj&c>cVMp72fmVVgXEen!n$l&CTy z{(?*oQ7qVdpp%3FnsBI7Q4?bDvMwb_8#i2s!&m{Yo0;@Yim94DJ1qr`wf}g<({Rtfi9ElXn%30 z1Apr>IE~r_%V&@((It>$(<~jRV+Fhi$W$X>n?t`9^eZ%79ENuNaUvdvWm{Kxt|QN( zh{u(49c9Q3>%OZi)59-BFS^K^i!aknVA+KW1`yWz*& zer91%w!ZgUW*wV3F6#=SQ$;0)pBjcbIzvo6H_MVz5TJH@YNxAAZBThh`CDcqXT=k@ z@sJsTX*P~ct`eD!prSucQ*Ul$s_}L_w&>V1(@91~-lEL59h^!+^jxyDqUCM~huiyt z%9ASIY@_UQ$7YVlK)vzla=ANW?|xXQ%)}_H+R4k`;W$7o_vm#Jy7A586Wf< z0BZG5oucaRxyaXD;Wso#%E@SWlHpc+W`A7NgcM$;3KyF}-(WV@xgCXEJ2jUo z#b!hep1KUUZ1W;Z3{k5=Bt^d*n|WCujC|pmfQ{uV`gk%yHk7Yq)V^~9wxzFR`pFh_ zf^0`$$qW*Bq8xiNuj*sZ#8ub>{vo5zauZi!@ArpHj~VFSi5ozF&G2jh{k4qV6Hb!O z&+NNa2@J@f2NF#D;)Xr|d&kU4k ziM#zlf=Eld{gV~AX)|1PonIc+xZYR$WnJTX-!b5Ne~_?EY(@Qd`$~V!b%U=g(8!H0 za+9xIa}KI`nZ+4@@;<1q`R?;e#Q-7|f_PIVZieusrYp>GDAg!OWU?$gO_R1mXLVvUC#M(wV`IV_@yJhgMtzF;g6lQ zSX}j}Q^$t)eQI#aK+U-C*5_PfSJkaEaq>=L2#-fOi{*6lYpM0Vq25X z)np0(bNh?4H2J)KQO&99L^U1OPgfl>eG{Ob!aE(-pRamsdKrJkj%@V(&156XuP$~8MULjoz zqvhT^cM0GbLdcw=O_w}@HfFT4QNyP?@EC2Fxa4$gnYiKfUP{IBBFhiWbTJ%Vp~iuq z)ftkBt;hgmRFZjO>v(~CN;YNUs#Ts}lF13b(%LW0RGu3`lu8SZ16gHxdh6-P|Dmsy zmGGEwHR?X1E!J)Q$nPz>Ox(D#&GUcatJbvCNBy3^f>4e8)K_^IjU4uS{0NF@p&BRr0F!P)K$-)F5OSVea{zIwLjsPi)hS3{-^x183IDgr~F<58UcHafDK9j9QYwEVFD&oz zsjl-)^D9jAvys1?fME4kY6F!8EBy+oH1TTCSNl2PnRqqYY4LMQ1jaJquhHTsVwnJ} zJ4Z!{aHyurb=0gOJ|I2Qa;t2Maryhou%t87qK2L>@JyyfB`+-rv5rhj0S#junU+El z*pO*)X+uRsmzfrq(`H(dL}Xf$L}XfA;)!Ki0-i^pZM5|qXY7|uODim?zSLo>p5-Fv zxX2kUGTcS_I*6Ub*-X`CPHEL@2dUWvq-Hz*oN83^zJQmS?AFC@J!QAFNS*r%5)tX< z4X1g?wA2lI%gkdl$8X-zGcD-`j-r9cv`j!o`7P={HgjAC7Mx|f&a|W($jFgQOCL<* zZ;^p)=C}+j%(NUsfMP{57gHb^WLjQ)>&#;_$8X+IGA-$y$MG$hmY)oN%Q}zE9G7(k z(b;XL#kDa#)ACjL`7H`i&Wa~)W4D(ACN?)iAA{krf4b%Pv|l1^7!HGhV}a%P zvVMETa2O06@39=n=S14v=T`_aMJw=XL1lxXy~zh{?cSLIjs^w;$G=&QAv!5!G%y%A zUa}nL6mS>}92MwDt;mHLm9sE14AynlNlf7NTLbv}{sM6(>*O+=Zn92N%&Xh1li17a z+&*U#jDDb{vQB5BV8lrL8A*l~15{0R>eO5a1fI~>qiVV_sV6mSN0}#SwjlF#81E41 zl*<$~?o8%MY}4d(HCbn#BJz3tqMB~zNjP-oNkIs?^HoOCWS*q`$)CW!=zP&NQ>%{C zQ>Lrf)CkJ|*_Jai^;1jf)P1OHXaqH0wdLm-O(Un8yv!_7$bUv>(B!R~X^`=(n#+|s z{&W4$h4!j{{NJi*(VwC4f9y*EuZ;%q_sMv1lMkDg>Geyu6+t#vYIC8 zthG_?wNCAIihQx8(%#-%n4?VE#ga+8GDe)PT(?2Dq|#ewp_0j@>6S0jEng)q!$-4q z!$=vQc3u&J_QdbJE-`?=@5j>K!%k84V=nS*2dNndBj&kc z$|z5LCPxrt3ai~Zh0@%1MzSsjhPsq^YmVMKc5My}lARl`$Mo3W&aOBSi8zX|+lT z5(rn7lBZ#>N{J<+q!W=wcvVSbysA{A#9*9zTzb8aF7WrgYZ{Dm6MEGJslI|FU_pAY zAaUrX6uUkVRY?MnSCu3Jd5x7_YvGl-&@X)j+py{joucYlD}x&kLAT zy@j$RMoeftud^Y zoWmnWv3uilcsF8MMTsS1&i&oZ-QGM|WqC!pyE%sB|3le`T5wd)cG#>jhyF93hP+x4RnungCt@874o5U z(cYKD0SMuPjt7L{Y0ZEa=viFQCQRM!tl4Eo?NcX1?Hio}TS=QLCr(~H3~;&BdBQ1( z)sa&uuMr0L66%cl6AJu#>mzwkEd7u>UuJHZzwxH;17hAHE{G!Iad`fS@_e}WAr(p9Ldiq$DmTCcamDRUL7~eQHaJB& zQ)i9TX>tk*>)61YgemF<@Je8+Ko2{;4*asovdgq!x#fpEU((#pk*$E&hMh>JRQ>ZC zBidUixgB1N-?2DUSDoY(qzlUA#$q%U%V-oey))hZkJe|^TWBKV`=?gQS>#QP1-rnr znXV5f-MpR9A@hKZ3z;2lT&Q1yaC#~1ivnkNjacv5xokvoF1r?+4LkbT+#LDU60hY3 z@b^_B{ZsvlQ&jyo7b$a=|C#|nYDVJEB3G6ch1bfeUFJeDZUf4>RU(U5mB{2(@Akae z_e>~zditB)*;Tjp~t$82**4&Ce3qCIRC6ulb z2vT>1$QdD$we3ofX}?OzBcj9-QPPP>BfP4lFa00)lWD@)jx2N zZ#szf;4==T>h~_<_oH}Be?44ekc*6Vk%{$wU{yWLzkB>G& zB1VGW5rJYHPF!tsN^Lo?-xJriTD0X=Ejsf$ite{S5*iNo9>8KOv!!UDvJG}NHM+%F zWLM^$>FSqZoBCJ6z~opz|ALrjyVi9i1z?d=SC#AYt`(A9p86dv_NDSVw_Iz`Y}Fl3 z$9rR+9jJ@suhvyg_#-cZexc*B>OVPr+I z5W1m7%!eRkqG8_QsCOUe^Hb=;zsk@t#>O!4gx^MpFx?n270~w^`n3+fRK7cfE^;18 zp$q@BDRklYu%Qqup`2}3_y?xYg@2r(BUx3zKPQDQKS^3^=;|mcyM?Hli0h21ol4(G zHBl+5g2aRTB!$-q1NNf)KfWD?8^S@Z6KnlhZ;-gVI~T~x3Hi>g#pXD~|k!c?uTw@`k2 z#cPHEUW1sb3!MTRLa+#jmkd*Fd)9F`m5S&F*-+&0#ag7X&gK@hc1IaQVcF zTGLcsi?7z|Q6BZ8bki%aMh)iJ6jp|VUz{%dRfZm)@6Su23x9nIU1H$M6uR*5HuU(E z`q7AP`;rqv&dsUl2_dsXe!Ly!^|a}8@tdbgBOoT2l!=WT7nOT zlAZ+uOMQQCrO?Ypp#E6!_oyu3@9FYSMtQGFKj`I3>@Dp`+vSn2_$pr|+L?-jW5pz= z!Se?RsZusbeT)3*Wl}NHt=|~14h`{jHU*%u0j9DtQdb^WC@+Jf(;$~5guzA7F)n>b zjeq_iqZAA=r`)v5NBMZw6{Fv?%l9$^_s&AWsVu(bw?Qh<->fS=Pk^ zBE!a&`HSJE@sTcbD~BtSC%7u$JmNYMn-sSnM15W9EVm2rN_!+W;yI_(b`xGqE%U{{ zQ_3(KpIhj6yeMp{W86g5r;+*5S{As#3G%RrRg%&$eCf~)e>aGfwy;`$|@)8XHBiaQSBiH zoDh*HXnjOViqe!rhUIIPb@4q0{DCFa66|xfuH}0TH3p2#T^w&iHj%9Pgca66FsfM} zuZh(pAs*Yhqg{`foa1lI9pi!ErjvAKL@&V|Cu@=(55&G@s9+@c$Z(gD*mH&oMuI<+ zWgnN8NGxlPT3{r&#gH_kuGIZsn)Z@4t$|>R)wrG@jS=|`d1Chu*KPP-JwY0y87*e) z0ArB>KVj|}{KtuezZbC)q|L%cn8rd{_ckJTW~|HD-l`*bn;~Iv?CB&z%S8P;Yv<35 zLli3!Ynx&vMpG0k5gMbV5~CT4^=O9Za+;I1<}4ye3w&=GLD!f?31h%WQ`mXM9$tdU zRu$z*pjD#yqCBzJhih#hfgmk~1pKsq($G8!G}ekHft_h5|5zOP13m zjA!_Ke zH4&sezPE&+Yg&^vjjDr@pld~wwSt2cj09kmuPJ|Y z9~7UYc?O!h@6{4yC;MJALHYq&+}25FFzmrckZu6q{!aRW)`5>8ty6qNXr0J2GuW@} zOxEQplTmi)?=R!a^^rLQFN&CY4SR3nKGGMJS3;j$B2U-j33DQDvF_73TDa#+$aBBX~*1qPX z-YHvT(R!w7|5|e|!+&v_8$N2>X}P}*&a+ttK*k%FpJN(XVD1GKATV~(7+R9?#^+-! z4*KVWqn0fmuFI*Q?_Exive8p}IyV@7-fixf)(En*&y=x==OFTJg`Dhvnd898Z1s>N^GKhj~zMWWUWf7tKv-Q zu8MPEy+5FK2uUO3tnkH+okwTGKsy$ugqhidnW+sHC)iS)k8gSySDkNNma=_`Go`sK zDGF-sPxv8~?Y3iJ!;BMmS5j7rPqPUVp;xlO;sjfYEZ^H<+;q^oD`haonbO>qCMsnx z#zh^IQZR5&!lP*oro`4UG+3PCg@h#El8VT_D|QHgD) zjL$TtgrlEzMyP*mx9Twnx*Y%g_yCD~GfJ)4k~5}?H?Oo_gY_u_AiZ+~a*INTAOWsdhs zZ6fpSnZK6cn-ULm!YC9@i7*juo1_<@Y( zmZgHQ{C|*gVNy8MN#x^(h{z=<|Fxf7QkU>o-MYFs{+9}#WhFKcWMgRgZrd_N;z?Ir zl(9#V<3`GgLo5Gk7z3}(&lAa7Rd@LLJ_fnjDpgPLR!dq+{pf+TRSoa)nhNB`t|G3u z;HMfk8jtr4$d)HmTpi9Kzon0pAm zgcnKV(u~AP@Yau9U?eE-iKTUUVl+ju5}`4gl^D%Xtc7ZKh0&Z-tvQPb(gHlHBIp{kC}E5| zF*A0t^UQ-WKTiU!62%u;8;9C%T1JqT>L+O9hvrG3u~sw*>`YsO1iIxIpSdMn(wKBf zGhM=XhR^qR5^??1nBu4AxSvq_#?CY!HCi9he(ZD!(sEUsNMvnd3!WYXNqd`UFYQ56 zhM;R&lQoU1gOQ-y(@oY24puM{q&3P4BD4m41lgU6kI2b(=2}9K4v-K#mS=8bOz2Os zL!g!*I~ivlg7gElxUG}Uc+t*p%L&pA;M?CxU(ha@-IA6N{DLLb6Qmu8JA&*K)c_IOE$MG* zxSO6|8rz<=HrAIL-?!ShX{Lpft%dajX(2{F1Bu;&1&bin#TriVr`Epaq~0kHeA9kc6X_ZH+02%pG;5Z1mKg&i5I8 zK5d=QM39|*q6w5mrbl<#o=u$du&<0UrR_(PTq*gCG^WHLOEM{ExIG|nk}YNHBfh8h zoc_9+3F8eE+nOB5DGm4@`}aIM5K=rCXG-^AoD16kJc`4{A+B1oRk$cE#T}QJ+9ye- zMAjb9mSSO?+8~}S#n@6@hBuiFQ?qqh%CRHPl;*OeD5#Z8si(3fpNu8hFcHOFpT?Bf zrDUy%YmJG}E7@Rif-SXwxI{l}-IWqyai%nP`Cgps7~4x3qj5pTTolGLp5~>F z=Qu0OKYFXFy_b}fGMe#I17l|79=o55*4%^+QYl%}IyS1AXj2yEZq~g!jXGU~5o?ky z-QRI82uqt3Q`nMohHtfHn<ju(>+W)o~FUi7^S%#MmXzf>EOY-tYD`(z4S zW(4E8UuT{O_wU%U5R4k$)|s-rQyke+XR0JqVzo*$A?>*zMLEYI2{reU&?4J|#!5** zaU$k%LTK?zeALZm_A^G@iEd`u1m&f7SDY&~K$1*}xzM*Ju{}gl+8UUYmFTCemBo#H z$^uZF!jzB{cYSCM-Mym2H^C-DQfd=f74Z>lb@_-~9q|#o*5xB|UBpL_*^N|pc^)+; zTT1MwF(qb8hxPHOK&2YZ-YfG^HMf5&4QGcKG?P8DxsJs-EBsOIl8qW*bu4q>f(_n^JOP zsWs9IZa*{_jdvf0kydHjURF>y6*C!G-JHQ z_!wh3Tb4u=;Yp@Yxu3|nmblH&6Pam=cxs7n$Ek}y?Zf0tu+bD@h9F2wFtZR`X}AIp zO&B(NY3#+N)t5#wiLCVlp6N@A!td?H-sgXk=@FGD<(DKp@WM$ffS&X1txgj+^S(z?| z6A8MN7pGRHHsz)V=0-h1@Vn;mx$ZJzKQUCaM)1i3MqZR_!PQ&WT6_FR`RXf_GU`E&cJWh?Mk4ZJIyWzrT)ZcI6O7_x1GFT?aQ= z8ygAkHYDi*!ciPF#(gMkbmA`}X-5pmyRZ@dt!-g^o-m_B_~;JCvCz6Rv^xXeV|{hm z2Mx%keD5;0bU5Pb&hby*U=>FU7SisOYTr>`;M3DWK0^YgbGJ~|tG z1R1f4kFiQ`t44@Kw%chXGOCNkq0rQ!MvbejS&QQ8W}q&${bs}#*H+l5?2{22RedTV zF-TsCNF07=*q&R&u~r|E;+@&WF3>Y0g_aI7?Qj~D03>{}m3}#O7#ooYQWw=DL^$%1 zpd)ynsjB#hM4faw1C)lKDnZT$q8#CtVBwC>iU|M*!zY!QZ-okm&$+FD&IiRsrx`jVJ(fZF0I8* zf*|XPHg%~}4l6%w8(u_^mEpBVjv-8-LZc3^9cxt;!o1Pu$XuHBU;f7=!K}KTWb^3WCHyAz{1q{ls+V}+{ zk%tWt&s-kr$l?r5!c$R8|7E~S&1ZI0OGG|zh&TZee8iG!37%u399#_igAs|~5A0Zg zhD3g3iO`S;?@ARS96fLjhs<6xkQ5)0TP(3XlPB^iOGMj54p?HVpC|H~C0^_2iTuqH z+cJ3~Gw`uCxsbQ=^F-!bA{rvnWQb6m;6GYERQ{epeq@PghREvPPBTPy7$Q3MC3I{i zPr~Wt4mXh-ED=f(IcSN{fXKs^2u>o8TH^Lhp2*-nYzUl0>Map6i5##*a1t3?!Rp{7 za*ie95KiPeOGI@dw;LkP+yuXENzDZRWUHbPBBLwWGUO52Wr^S<@&QXkd=UAIC4!Sk zQC}?+XDou{hJ@Me*$yJ_w?tGXa*HLl`*|WCwGwLyj_=1tmJuA@pQL7jrx}vUrV^PG z@e!mJy8BUbL&tI_h6%9XcwnVMwl5i9Hh@({LGj z)-Ei|xv<=67mVdxL!OC91pjPFwFF1oHDo!Lm3KxYg4bHo5`tWD)Yv1!bp*;1W>kDcI5UboGh=cJRD47@xq*)$ zr#8h$gi{;%2y${!d_-=s19mw}x9 z^&Mt${f1q4>yx2Z&nTN~7q2A*xdP#lPcp`qB*SS*N;v(oBN;hMl0mYB@xbXBRuW`f zq(1XQm%p)qaAKs|#6%PbOBo2!_IoKo-k}D=;CVYGF8zZ6dD?`}*ys1#zFf+_@2hSpMs6eluNCCCs{RbMf4-XHDUw=`u=+tT8)!3|erS8QwgSpqa-zco<Jg?T>e` zLpc+u>M33Nct=YAJ>HShGmm$qbi?CmOUC0JDGq+TBgLDKcci$ko1}qtSp?8|8|@sq zl%V6!BWeCT(vjlNBWeCTlIG7N9Vz}ilIG7NY5qKt=FcN({ydWA&m(F6Jd);Q$P0Z@v}Zi@sqxD zsNZkT`OA2EA7~Ehs7UZMOR6Qv(>q4cOC3Z$WBHanVn7a5NMl&>lOKU_+Xr+-Kz$g@AV2=eS7 zcemefpevn4fdHy~G6#9w?>1&Q5>jhH*=uCo41R$qFkZAyL5#(KkI1w)2cK6gv?tC&+07W)h5M5PP!yk*(NFaI_uR_FT&`j}{4X%;UUNohQNx0DK(& z9LpdP+-k>LGe;4lA6yJK{zrfyF^Cv3ATeG}H7O%lnGB9&?cbE%)g7JE$IqDVPU+)2 zqCWnH0lCybV}cjiKK?)4p)Z*jV22jt8zK`%wR$7jtxa~eUP_SNi}i_MN>6{o&X-FG za*E90LluOhfUq0*ZUQ3b;XgCK*~grId~x9n>+ZqAeNF+E5-Z%aM6qHYJ2qvU(30z8U3`5M zw)g_6GC^D-Z!}A#FcN;hrFC`^=29wrTuc9K`L=t6OYI_=Tb56m^6oO_ocdsHH=)gS z4qWk7P84|~*Y#$8yTRN`ysPj9p%L?3xFQxxwQ zrzqY(?olj0Oy#ZGj0vb{Ti7txkQmt5EHR!L!XRC5xEQS<#RC$gxH{bXn72hx%pT_f zO`d`|d{Rp2BbH1-BZiqPWSAhftuek`FFU)ZG% zmvL^@gvPxZqg^_L6D&`8!bh7JtU_ay(l()SVxw(Bqb-aup(XU^>chL(L%6FKCs@wA z7OJ?JNGUk46XCfXN1y+NXZZ{*l|mr$Kl0!{-m&Va#$M*isnjCEH8k+v&@+0D3g@KW z#pC$+089xpDAA6?$COqAa&)CZP_*|`soEJETl=Yk#c(znT zB0NB-^F0wBB^4(TPVegH4DpFwwH_a>(aF;Hl2iJ)lqr32a@&$}hF_eV(ig|4^t9Q- zy!#Ya6F76Moa2!iC&(!eC-!}v92%V46_H`gMO_i&5etdQc!fm9D`$LFIlg);VloO) zJsAb^gvG4UQ51m4D2Tcd#AG*unBpIArP&#^n0wBgjj|(2S#L`0sVPm&*UU!#K6B4u zlPgE8>_}3$`V^azk!fN)?|CEOWh|6N6Bxf zkz=)4tM@gNsQI={*fbDivfFw1$psFixOK#tH6LNm>$L3T>YrC!!1>#QX+3^*$yU1q?g5vk39TO-m<2K+!o`m_N*8<8F~;6oAV zumPVm_pG-~jo9BC{J$-0Z66aO{cWr)sWIThh&11TwGnBZ0XIgZG>81B8S+eOMvDh2 zJfn59cq}k83`bwuTPi+ZIpRGfCOw}onDE}sSmXQL(c31qP3A2VzIBJpGC{sn1l9P4 z&hN~Go~A8ab*GuHK5jF4O$51<8!Yc9++0-h=fUcZ_wKSCUJZWW+`lq$B=x-H+a{^= z$UUY<{>9v*9wCJ_p>`7E8ej0J!PcgfA>}w5<|x02?r;cF*T$;@{h{|Tk>Zi zNogsLNisoJ^0zHXHUwteR{6FTHREg2Xp$gblEzUh`4yUCTa#=l4S4>~jWc=g;x||S zVSN3Zxyu(8^yZrs#){oD$Bn^{p-g2SQScN(I&S>nlzw~FOi`!UcZ$KA6d7krJG%K^ zoU4o8jkDot>Cs#4qIabt<-Klf!P~lip2#TsUi4yuk*(m1x16=&_*!;~din!WZ?s(s zRQko+jqp82;{%cA1fR5|B?OG)vafoey*)lf}e8Q6I39>;P zstB?*X}cj$ENZ(U-eQC&+pc5VKeuf!CCCQxD`|pkP5)4hSk!i1)K($%DI=cE;gJ(T zHiyNKAe-y5piFA-Sf{N4a(mlu64TXN>P{*c$U}Q`eqnkd*}@wD(y)4x0IKWX)9BuM?R3nloch$~}Mt+v`X z5}aU3wFEz4NsYAeU_?sV*mxW^nuk=~SvlG2UrTVMA&C*dR?G$0$ohauR`*CVdua6Gi2 z3X`n;iwV-v_-eq8JP~>tgOlI}Qx$wg`MBG`N3Sy$6(9Xh$Erq%M26ZKfDVPcuKgL6 z{Mn56CDyD(adq)wh$3oxXT%oQR@kWQKSgX*^_vli@$ln_#IaUtyJ-;z*0~WW-g8}? zW$Z&=WhOh0vzSC0;lEf7E~f^)ZF83sq$a9Ah;WeO)I;!-rmEs25_Qq#j76G(ss!0< z-46rZZ9C0lkKdR(dYWKsm1e=2gek#AawiwIH- zcIpHv5l&BL9z-z3u>wA7M9`_5Oh=^GZAz)Tze|5XM&YXsB2?2z=RGPhb<~Ees~0CU zw}^7`vo!b}Kwhkll)dF~R?~U9^NC;~t;5E6NkuY6gJ}Fb;u_ z+tC6>B402>ycB;MzF$z3C*j+s0I~F_0mqEe_NbPK>@-Ad3JHGFl4=PSo8bd44znE* ziQqrjkp~Tl+-Zr>kO=Qe6(Ss~P?-bt;?a)EL~1RuJ(nkPg(aeGBKs||qbN^=chxqL z1D11JE>GlnOGI@duUaA+vdF1gPpBRk@B(v37NaOnWUeKmGLiRLA~=cM5)pHGBHxLK zMR_7Wv_!}x@>oR7<%yJ!p*PXcM1xF?h`BtGzeL2MJdu-6V|6q{WRxXdmCF+ucDln! z3gQut=`;K$Pig$iLFI>BL8ZMs7~Y&LqtlJ z;ItaYY9cc%5w;MSV~L$bc_LR@BARJ6$aYHvCz0KT2v-msK32Dl)B?e0EolkC|1u=J zinAk6BsY##mk_KpB*jN$q$NVXYJ;3(?siIipCRzB+)LzUD+1OK`M4!QE|L2U5%v&l z9#8kelSDpeh~Ojmpe5B4{Fz&o$X_hqQi9J;U=vV<$cvVUm>@E4qQgmKvLRyPCb-7s zBXW%;!V)4kTO!&f@+T{CDZvuEjoPszPh_wmV%JM>tjkAaiY1~EB9~es)FHy%2OO&{ z?ecHI3f(1FY5~`CZd+2et9Wq1HTnB?m0iwN_FlVsE+_bJmQ+iSTUf~Ag34tOB!avn zVt3?;M9buIf?O`uMw&>YS*Re7;08Nc@4dT&2-&}M?%iYgBf z;mAP)92}?H!BL+a2ldI2uV>WWU>ErM_yP~{$(U_UhFvowjLQQSY=Vq5rGGNQnv=oQ zoQ#|LWQa5;qoFyihmV(bvY7~ZfWaKi$cTD;DSJHX-lgo`uiNfj`dtG?J-(DZKHv8E zQiAMccMcg>~#2w*=54glG-Wz` zp@V_NIS}#)GMbcrM7X^IU&?g&LPyHn_d-X?ME62RO3Xdb!2o3JskT$*wHG=ViW8#^ zLCU=LLPs(_m!`~XFLb0#VlN~T1)QFEkK*+&rpxV-%-g%agNHGvr}uZHbnE^O_943i zcJJ@_q8aS;y&|S~eSezQ_osP%f0~2$cceIYe@BWp_jjbYZhxBVk~x;hWf7Eg->K0s zA?SGYK$=Gnqeq&fLO zSMlj?Ks6juh({FF3yDr)dHf#rSu7Q$b6Xq-%$BG$M?6b{JOw8~W(<|b|fVcf(GJg5OBqlAmB<#ffOZDAmEE9Kp-t8{ZVAoA53nbD#44QJjagw zeuFUI0X_?wjWe3?4afutJhHSkF(4gyG|@8_%WNH=qS$`X-VdkQYyR zKs(M^y`yBp4x8H;Wr;XK5#b7iMskUS2PAUB~!6XA0=%#tSz_{WGuu*BvG8VR0lNlOUMvZOkK+v`X&5iGd{S5 z5XN{+2`!#T%i!fjh7Iq+N0?bD;Ummbh49hM%npH8PMH4Ac&+7xUpIXueBurF;&-IP zVRD&OiE9=pC*n3HpqYC{Kpe9tnKAu?orP)%{@If1kJaDF5nM}m^Zvip1&mqke{?`> zXJCK$+||ZF=!Inr^ zs#z3Uc#&A-^9C-v8T{@kzD}y4$(53aGPIC3TDj5{+l6QubMsuuQ1kd>Y#C#V_csz_ z@g+ixjjs_xOD+`Af}R7zx)~+O{2pxt<6g7nJW?zNMaEjtR>rTJ%IY{0Y z`=;5SMO(Lq-y0Ig9X`qtA8sJcH-mzM38eVg=;mu4@-6rDi*duVo4iE8M95gXi5ZvY z{Lgcg@NwRK(9XN|Aj64O*y5|U(2^4>K7?UbW-i{?pv5OtaUmyH9soofPXLTOp>f(| zTnUY#!Qn6R2s2!idL~W9bd=EI0U~u7865P&7x%MWf@1|AG$WV?W2sB;?lc}18okWb zP1>b3{4cy9!l9ijxSF7XOnkYH+n4X_h9X&|CG&M0}A~ZjLYSipbfA=T)T^ z5gu5TM~QGwSDf+1UlHRol_JKcbw%VH&s~60i8BxHJPOM}EV=%VOIiOHC%51!NtwmT z^?z}E{g=s@dhlLK0CyKAnF(NS1CU}T7>z_c@Zw11f}@`FBu9;Knk9z=1riBz%cv^H zvxn)){TI@b`)}mARWgvEBLgW44-k{#0b(*dKxBACkpLn+%6rDocxaOGtnhxwc=LhCt8tO=*Vx2KG2ueb`@RwJ zv=x=|pqxz4Sf=_yg#?Q;b)o;yjf_ZELM!oHbn(eUy?rRLh!ZZ)BFK#}HSk|%!Uu`R zk@L*K10KkmvSWAHELk(biS}vA5`uitg2y%O_Qg`B(BM6G z94Bs&;?p)roSzwqDQfL^)CX_t5R9~`O=^>PZxR)g+N2Es%4)6A0CPt@ zS4Dx%xb}+-%V7IzEmohnDhQ%zMZ3_f28u{^CfTor!iDSWJ*jrwl)7_&Y}K<5qrcQdnxpO6^~oT2Do_30B>S|pz7}p?oLNKx+ zu_%drxz01PXPbMO*Xrelj~aKHq}xbj|CD*xMulwm64P!$A+2QG78L51-M>SPjA$?< zoRaY>4HKDF47gHUn7`bJUO25i&AcgdiG4|GIYGWZh1HvH2YuZx1F62NG_&OZJLfkM z~fZv!fEzXrv5WFHfjk{G{zzY zap?r<7Go++Pu*gD(Y&z!xVa;9Xsk<2oA^{@j2Wh+y)zPLL(ZAT@Sc>FG6g1?&|vb{ zX-PIbOJzg6XA{b&G+3O%l#t|mGfby3|Aa5Ch|f~LwDK<|y8qMMVZr{yPTcq6Y-uN@ zBo~AoIR;^=o7Z@YUAR{KN7ipy8}M#BkrxaRZp+AiDo zyerInzayIW34YR&>Ir_ylIjS4*^u-PHHm%QGIsOZU$%XnWo{t&SxZ_%kPX7O1lgLj z-H<01wcQZe8HbW>*Rk!-*|wJwWP|u10715iup#>Eq7GYlH^4#7`aKOTGhP^^1@zmf9=D{mRW$U6;g4ZwcjJaDy3~+%_yUE;_ znftmzb8NNO4c#x%q|n@NFn7ynfFBzAOXkk+T5sv88Ll>W{>On=^wRWk<@&zI+#CC7 z{E)fNsL*(;x$iXhN6g);G;++H|7-Yd{WYB*LBHGJ{A{3Sz7@FN-2Z6qrRKwv@h@5P z3#R;tHNUaT|Cds?7XAH=v5%jNe$n9kNOZ)hp{si9`*w4We+W9x&##)_Yy9?2b1yZ1 zJDPn*)Bi;yhySM?Kg7vT|HkzhYx;xzbs*Ls{Qnl{fBKW3r%lM~t10|aEBX1gRen77 zHuH77c>QU|SpPj;)aU;)%x{76L!gIx#9Pw%w@rKeLM82FKOBg~SzJnk`I6!~bLWQ} z`I*W%fBbW3hs>u|`1Po78T{YP{g>wcthvYKu^#XI#Mbu>Kfn2Ptn&C_lpaHMOFhlK zzqt=E_jYsNY3}?y4L|a7xB2V|KX3AFgU9u+8lfpu%zc`<&oTEn|IZBlSLXg3bKf#D z&Z%*JqT^9h{+PKxYwmoE!(Xb6HSZSi*BCkTXt?z>EpNCvfIn{To_T1)Cp3IG!`}}L z9H;B?8Q@NX^Pv5J!LJyv`5rQNzMaDdAxu>;4Z`;;_?YEZbKDs_Nz38S5j7V5<;#Do z$7tGile**k3v7>%MB?%zNg9ej26@Ez=HGngoclG*B z?al3gvHxvu-ng=@eMNf<2{E*-eaqHW?aj02F1Scnh#;jah}a!py-JX3wg(E@TfZ5F z()2ZL%`IEDY*^nWZKAAw{l*qkv~J@{qhkn0U|ZYQZ$KF^RM})CtlGR`L)$eQ+fX1T zwr^R#X{`~^z8a3#u+l+;Q&(sG zfdRUOm2*SCNpvm>u9}*i8D{#0S=944?ka-)C1|A*&QP= z&&whi?vmSK`6FKVT%i}Lf+sxdg__2&D(Qt9cww*c!iU5QPirsyV`qUED#hISbcFb! zJ-aaS!#wfBE7#_xDo^xF_XSw4dMFHn3g0+jYvh1!$^lP{2hb2a0Aqr8tO?7rKJ-D& ze=ORiy-Y{<|8N*gMUP&mddd&B>9zxxz=#uNiy0Cv^STPSS{*YJ|mVPhn zF;@74x9>4*3n~>~&)oDzp%2)l=-KRUAc>g!zD%?}Sd-VEI8X z%?*1_Z@dR;t%8e#)1gjja2duMESd`5Ylg$RY%uvSBn%CDK^EMGF&p&SCD2qMifLQg zA+ZS|T^W>M&}RJ_;JZzD-=A%STEUq)sq^pGVDt<`m*^hPjH?I-2LAx@#n~IfKH0`x z#nkYupTn4I!ycfXoLd|AcpK2B@MNGx2wT5N{_K%Ijqp^as$X~(igE~LKlpy3_}tT? zep_LaqbkCg!2wh`sUs|!m%Rc_-wCrv9LA6pML*MtTESlnC22)p4Yi^ZvOzD5DA+wO zoDlSCJQ!9kkPbjdiPlBg+}f;vxE)I6wnNr`70TL^lak=w;FMktv)6|c)cs!YK3B+_ zIjtg`7Q83x%YcQevtYn5cRYA%MOYrZ7xg7-P%g1p8qAPxdBCedSgt-8jt}}`_9_lG z%$q83<6%*D(>;}8FH=wA3(Af|rF#k$2rGiGWpj=55G}&804hriHmi^<%HAA~N7bV2 zZ&34KVNDE|^58otJuSEru{SRq9W2OUMx2)oDkOj#!(n1nFd^3{WB0DkdmuZQi(c&+ zoP#l)4Q68Y>8E3*EZci+n4ONWx*lOw`8ELaO?)j-_YfhXXGu*r_~lc;dA=!G7KSp^ zWd5EOf!BqDF^oYAw(N366;?gXRJV^>Y<>Vj%T<`e_+S_XbmQ zFH1;$XNPokW!Q6WScU;DGfI>6{k-hczK>eK`-TJ6{Yf=Djg*lblpVyh(?^N$!z%RP zN%Np!@MHgA*c;M(^rUp;z77m6nRAM=|6=Z6Mpt3+2riu$=7I^0_hb+H{yie!Zwywv zER{w}7f6+Fgu`&JJ{=C@S12C_C^yBl6^ds866r`O%2CnM)wb^f|F$Y z1%3A@zKOw{J>fYBjd?=-P*?@-bN-6SYnF)kKb zVRLX!u+gYi7yB4~V_pu!kL2!Y3{OTJ$)qQ% zlFWF!=B*J+ufy^Terzgsp~`g~d(?Ea6Qc?9<6p0ZGtu?eXBw3@LH1R3A8}B0X~Fs= z@siEvW~m7XfYKGgc@9EmuuORppiq8KSh_1jN0esUeZNs=am>J2dIzdO)-$;G+Qx85 z@UPO&VVNF3CX(m94Cr%VasSFes^8J+PkWe+&}LO*SbC@YEzaI5`eVBJKxbpvFL+r- zb#||=&?k6zCt42v7iV*}g(}@ZarTSCf_+i;-Lgg~i(kH0 zt+ji?!ND)Rd%^+ASN(T|1C)&5Ti!016WoclzR%ilK=3Q2O90D7<$lf3qKKz zpSmaPHx-q4X_xd9MVhF{hm~)8!o{NdG=-IAa~0s#FxJ)*z=MMxdqk6>?0(g=Mc97~ zM{}5F`=X)%AHsc)ban}bA1GzJLTs{%vY%Ia<(jdN(VTe?K%;8CE?N_Lvq{$tGv7*fp>5A@JXy@xxQk3VQ|H8^cpKg;UmO zaLR>XTPOX9^8wbR;w8Z6SE~N{Eo2A%&~dfWZ-XO2kZLiN<7A3FEHlmbJU@%Q8yNos&B+?sL#DvX z)I=wf8!Twg=5!d$ds=*UJ4}&LjNyyr7d1+PN(|s&;~G>7#y+GYro?|a92?x!;fLj) z3(q)+0ra1KZVyE77m;D*!(orvz?Mo^VVbI#2E&8-PlE(CZU}SrVcF6!*8u7aY?ct_ zGG7OGcjoqRAY7-G5j|=5-W66q4UQVjU%TPXHL@ukgRN|KXNZwA1_B1{3d?qfgWiP} zrYY;f?Ayc9CDJjmwNG^yQw52gczb@uSQM)(&Fd=XP_ zE;~>*)gk2M282bIV<9TT_<_irUi@IB-q`l~)zn>TU;8|~t;cgvzH6Y_VFW!91;yER znUBl%$YvgAjyj zT6`&XDT9MnMGnl06l80|lfYTLH5`TTIQ!{rrW%vd%OFjJq41C&+#=p^c45^O!7pI6 zoGv6@FoX~kP#5+~73_tNXk~X{P0t1g;W4okdp5m=4{@TDUM|IyB?5ZpBr>ale?eSj zus_9ex(2J)7co7+4?hcDR$~|a-@8$*!dP|1wY}=Y(wT=P;+!c-q zo|h2K1}kdR^dMqN=Y^-D(vaMcaI&6W)%j9}+cc#GhMiKgS4-Fv69guW{(DrzJz%GJ zS!P(>V_$%)gH`jefe$A)P2Ghpao^x}^r!UNF57E&0N1^i%|50^_|(I9ibI})a?)4Q zGWH4>$YnuqC?8x^0|U@;;Ag_wtZED_~?ut}Z1 z$}yqzl~I9x@XJ$m#XFFI&=o7B;_0pwB2(QG#n#}mr68H?W5I9=mg-F@Oh(s&5}a#X z(P2r0+5%#ig_-SSL<5eJhv6tV{|?E3z+{*ykuQfMv92Ei7o>%1M$A>HKs}6plEg+1 zV?uT{IfR%jL%o7mJn5?MBJk#h{STsG9Xj-@&N!2Ck!_a~QB`oCnqiP0s8lm&?vAj> ze00MpW5cqyJ%nTFyMvbziSYQLckV$NK&M*#k7f@*I|KqIPdT?^ui58D>BBzfq3LO1 z1zHF&&-(-I;D(4zXm<9zX*d>tc=+&|gW2GPwA6x3Qf_MDlz3`EPRpZ&3wZ@>9#mdo zVLY!Oc?XqO!0G#3w0HsHurRLx_s?sO@(Ml5VF%I)YY^NQ)YM=AJs_c6ErV*1q$03{ zVxE<_LI?E3O2b^jG@VO0Xm~DTE@7M6H4o7AEY@q()wzT{DwR<4|JZx)_^OKS|9hXD zoN!1;fdr{az@XF+iZm$+%>)C44hn=20z}eG0aS!YlL%|*USY#2VSG}$IzTww{WmG{JMcz(WIeb zF_q%USFIb+rBZMntr+a((d2(#G1zH_nRs5~p+V>S(27B7pi}TRUND$P*q^l7h}A6^ zFx}eFg28Ak7%U)x1{Vx=QpaJzfbW3*Z!H+quJ|7o3<8ZFZ*aYU=9BR21SqEqu#_#ev7o;sCX`@wCx=v9j{Ntq$;XQiGfGC+b!N z=!%6_1UOD?Apb8{1gLYC@TxFfYEl!M(mdMGs=#Ktt>+-4OTo~pKrPMM?y7(hh-LvY z%6}2x-{-RQ_IbPl7!~}@^k^fVfvzUrJaEcn5*cF@k~|eWi-S9&Lug%OwQ;O%2%AW2 zsI)FXZX{z^3E$lE<*Hp6c!dgceieP1dslyBvrNTTkXN@d_cL#r`x&|OKZ>E@{y-94 z8qnhuns;wE*BHFw$(JeS7L8BG;OD0No|DS|i1JTz`O$-@e4_sWA8z|!Tt*!ky6q39 zkW5k~%M4+eT65D)m-6;jVQ|=6_ypB7e=#j6&|Q0E)Mw4jx!B}fT5{wY_9yrXYc$|I=teHa|D|v55%Qz|U(15c=mM(+odu7Zg^3dZUa_F1sG%H>gUkZ_cXTsl zZq|6T8iH;%H}^rljp^ZkmKGW9je1nn0}Y+V!DbW+QU3S?{3Ni2{~8l8_Fg_1^{N^F z&Y-KFF)IRRoI`H8hU+k^uUSF9z_mB^d4Z-g0x5KHJc>lp&23c*MGz~#VRF*kMHka zrqizd0P@x~)2T8#_Z!pw3|;OnvYo}<#U^&Al@lI^{B%0=rK3M8*giC0Qory;`~5T_ zCIT&8}}?&EZHOZt@9pcDQQ}wGFO0Y!2PMI%^I=x=pRO=s-aeg|!Wu0k#;olka%B zffj9A`zu+1n{8LV{q)GotTRjxq#OzK-5%&2K@W2pUSBx#e_UTEGecnG6(?w-J?^7( zCW1~OXW4*aXdO`=7wLu|+^Pc=rz!Ony7T3mvKV?^M1etz3vp4gfhHOB;3$Sy76L=Q zJ<#xq0`)tUYeOqlv|hlg17<~GASF*;QHae8#HE`Rg=UXqMd50!C_HIwjEvexBR;Pv z><#oEJZLkm1^@R2g~qh5a2XkImVtts>y{O0IiZ|y{o~jm8wF-rp;DF=%mPI0cK?$R zkJpr3XU!Y7^nX-hsxq z1frLb;?-Dn2%Z;cOiOaB2+2*5eMS0kC3BRB}Mwl=Kt_yMz1YI zCGv7gwEqSg$r{rzLeG5o@qRpCpzx4HW71)Ig2Bs^JbzJaOrAkx-1M(186?^-M4qTEXvIB zk%?{nf2Y+wy4mK{0+Mx>3l7&?F392K0ve9EtHLiA+(eIGhbC91rjk3O{MYe%K@vYG z;yP%xyiu??Ko#>tAU+?>_-aNkLZ2d93eBOqe37{T@&`Kv8c!jy?CJKIgm3ITy6dNA zRa9;IE@JqJEsfD_x6>rd?|hs~eLOnQl&566&gRh}dLE^>-bZO#kDW^C`3CdN3D4J! z=*Elmjiw)7^7%>%7MFOr6$?tsE9X?r^9n2M+e=<<);M~1Dt}>ar8mE*bWUzrUS&mo zUPRY^tR{E~vX$@J=$w`6Wr8Na4gO0r(=yz+vA@`8$7e!t3_Ur;%hU*=*fa&0AL zB?WZAyqZNVn^T^bztFrd#_i&FuZ*F^dF2ZW$}7D5eAA9xerKzMl~Cnn{6Q7vnwP2y zOLB_~iu21Z@`}rf3QD}idGs>b;?nZD-tghMW5?wV&(4@Qk<-J+PMVNS_2rYr^p@O( zRi$JX`E-G;A(!6*ySTKZfMrKyos%_*y;oXQ$zEBMS5!DRH$T59ucCsFPt3^}KGL|P zB5#rP2;K=}zm`@}6;{}G0~uIcx~RYu$S<8+kiV$XE6yuo$ImS&DlGQqm6qoh7&nvW zs){PTqSBK2$>!rEPgg7~EaTpk-X{%tMFsTATyB0zPx6mfxKT;#=TC~mCl=2QBY}$7++IEr;eL2f|^3zLgEvPN*5P!KNeCI zrQQ?3ZcQaS~h9`>t&)IU#H8B+^h~yL=uwVGfz#RTN%KZ~Tdc#?QH> zB}Er`JrVm8QYv1$lFAbMxsn!*XgZm7u6GCxb^(QMkzC2tMhQ^SIO4 z@ARIZXB6~C^GQ}zWIKVB49m_KdoGu+D9g*I_RA2& z!)aMX)f|rlg9?@9%{|M@U1UZ#iFPVJIVWf21UgKv;7;aIq=8}83=;)QDno;n^Qx*D zC8_5_V+gsWpu8lnC^yvBx|7eCUBPFnec6-^FRLoacLJ1$SbmF^i_`0_G+59JwFNY2 zlOzQp4W9@#j54NuW(F|>GSyICSxOa9;EJ0}mvPa#1r_-`$yAk<@yYCtqGphqGq13m zyj5CWINzLGG}+j|C#{Z2COQh|7Et_F=8+l-ra9~eGtuyDVBXR_dR4jdVq>5&+eBKf9qdEHuRUjTAxHBDcQ7?i&JjM>>}kY$+3%(yoS{}OMl*SE zW}oC0l~fh;s6zu4`;PXxG{@voSXdF6CPJfwM4lH4E$$Z+7#>ZjOE|u10H;Be)Xyo( zE8#)aOwq91PWP3i#w}*jw*eDsp^2;fdNU(tS2G3E3~Z)#s+k8mw!3%^k8auHrqU@y z-EU@Zs*%Q2vctxh?HANf{lM26y}Tk^4ur-WD$Qdm&t&Ajs^SuFj=fY6XOn<&AGfn_ zA8u(?NmWI`++L;|_`=2vH+7d3^ea5WhYw8dG`Y0Gj;g8sy7%l#FP?X{S8U<_V9q~-!__mT)%re8`60VGx9M^J#e`H+p`pAs9PHO@gacL`~7DvZ* z8XlKCEUqPq42ug6iy3}0Fu%HGUKA%aUqIJY5mewx|FF2^4Uxm*I;{_kj7wV+l@Zr} zWup;sIT1UfC2Zh6U+<@Ot%*D*uG7lEIdN%|;yO)vJ}x=qB?_Nc$sMo71-*1Cy9s5D zA7{oTtYJT{^heB!j!Vdh3yzLiXcHr1{6QbPYd9ZXV_iq(*=L8Kge$eZzq()P52Ea?emVqrDpsv68vM`(pUi6ZKXf1x3;lmW*ng8{owoY)l_p% z5qlh5{)cvR4iMw5&O0_QpMDR@1z_)Q@V7%*PhCH{Mf_fzn+>J?o_HaIOv3N+30i;i z%lGTmA-{+3Dc9rpo_#%z@734i4S)aI@74dF@;+0xew^^+-02p zH@LR+2zZ*=pZwwXTAd6icZ~iT@-hzq4RQLCLW4YxcvI?Oxek#t|FkgjXN2LYVR&ES z%_yD|Fs_>UglrrhMt*!4UJ!;Ch2fQ9_?j@hJ)N)(`E6Yo`K!b5zY*v5)*`gbJVNc= z9!CB_$RCHi_~-dB@~?*B?}p*6!nEsX82N9)@E^nQ*f9EAgyG3yc&9MDM;P8W3?D?C z{Xd&06xzi9m_}PY;R9XD#!#F3M7CuI!F9+_*F1Zi!DZp+N=w_ZRY zEBS^rbbHRXZ=83RmFf1;T@aR>d%uV!OIgjVzldrU&Twxii$bB>RpRz;l@fd#=T>g- zlCdNax^-V%|7Mh1LJg&zy%V%1t93>?isg^cTDq*4aQV6$S9|{*vas%kx^9W8Zk6Vw zRc_oAhh}UFOD~1~e*epEGSf2W*-v;jrFr9Vo_|e2_)83FV|ku!e#aE}7DL)J|HERV zr#q!Z&q5j}c;jE3NTomFJYMp~dUz_3dFIA2e2e0u=dLjPG*(Po$WHj7OBg-{obBK_ zSM=`#*Y+QD^sxPM<@4__{4>Sn3hJvcJO%z{dwMzcj0ERm{A)L2=c{4lqwTL!8UMO^ z2H`?j>mQ6uLFPRj{TGDcm0|d0VR#fStyw?+>WA3h+~GVV3xCn!uKYoVyYgvptZvu1 zSW-%xu6LHhT|Kv=L$&l+$D71YBiwihmpF`5 zT;!W8F7mCx*-p3LGaT;vf2zY>J8yHiEB}bYUHM~SxG#wep^fc1i~b}YPIGu)hj(>& zKZlP5m-A&Q9pi1bBhPCiqW=qr4{-P?xb@KexE7rCcXZ@8IPwD>zSH5Ze_nTZA4h&A zZf&?;*Pf3Z?#jQ|f&^*P@?CL*q3s{$a97Wb4nLdpiGRLyxNCn5Zb?{we@DK%!(I8| zVff52d{G#FRT#cK3_lcx{~Ct3z^$V8Tc0p|d>CF5hVR66KIiTwLfUk_*E&3%j*Fe+yRdY9`56vRr{f}D2_8Yr@9;|$=lXfOOmWe(R&kNv0M2UrMbqa6M3I^1pVVTZf(NJJ_Xrj7l14*f~H&UCmd|GvXB9r-34 ze6+D1Hy+BsxnKB{68%+$J zl@1@|=)czCuKkZVe4ryA$Ab=S+^!t@lXl&U`(oxClEP1LhttN~z0Nm~KKL;I9dBd_ z%kd_BeU!}y?JmS?!J8<4EqH?Bo4}J4zZtxx;#5AlbPsU#OQsmPV zUyppc;x{9oqxg2@XDj|B@@0y@ihQ-=65q8BZ;3STwjwR|A4h(N;=d!mTXBh}{SIgS zosd85aQ2(Tjnu>SvV11wB+kVii4TcSk*|il#FfZP9LQeew?RIg0c|2L@1*4@o{9Wy z#U~+Orubass}<+x+Pu{&z6$xRieHQT4#n?4ez)QeA-`Yo7mz=!_&dlSSNsU_=0bz) zKG>~z8vM3j@iOqkif;u!uK0d%v$#X`ahB^1LQdYt5S|8}%!@&^37-v~ zrua7Sbj8Jv9K~BAKilCP5AvR2nc_R3zuMt!ztmUjaMtrGaCxPfvpoLH0Z+htDZ-1ulNDbKo~HO(@N~ubJx|_p6u%vOw&M4JmnqKg zfAUtX_~YQUithp6s`zW*I~0Ele7EB7gYQ@T6Y#@|9|J$G__yHlA{uAe|NOovZwb+M zFZ@^VWX1mkPg6V+*Jyqj((TXDi+eyiDpAPx0igyOzp?Gib z-HHzb->>*s@WYDBb@*|`OCayXob2bN;0cP?f+s8fH}EvY?*UI&{2A~Z#a{uRt+;#_ zs7&$yK)zb>@4;&o{|kJp;?3kbQ}JZE&Qx5k&-W{y4*A21j{>(|w%6?(=S=`GESc+h z=CUOqA@LuJJYO60COpw*y=3f#W4Sl9{vjO8QRdx6E+V`m%J)}#x+0&hI37EO)=NZB zKgi`Md46Yww`q14s&_c@vlY)meu3iSkS|kw67smr@i^Sug7HrL&AdJR1#$h^ln>G- zd@1JX<`#$espv=XE4LRRWh6U0^2tc^4v&{ZdLp4`5M-p@=BPJA@gI<%q4-0{i+@DV zSm=@KP~nTw-WsJxo-1ur`~>WLLh;wR;k50wyHL9xhrC>uNxi!e)E_JPx6x5@-6ZlO zVgGMR{wVTt{UY+?(XQsOOL#Q&cTl_#cJ@$w6ZFVBoalKH_Q-XF@Vj8o6s2c4=DB>u zFMzzP$A}*JuTn2n@=Fk0S1A4%@;4|h*JH9iC;HzE+KP87d08iUTJdinzfbW2@WVmH zWGap4Ez<4m&q0ei!_3ui^*6|DpKbq5m<(XQ6*(eM|fhM7-@$^0~;ru6QQo z-&MRT{CP<655YfCJO}n4Q(XS5=5G}DLC+70e~WhgsrZA42l{WG%qHzkf`7UwelPU& zRs0X=9j5qd^w(I;q31lsPeps@DZUT>ELZ#x#*M2KzXJRw#m`2&{;v3$ut)qMez+F( zKBMI2dTF2HO(8Gql-zu|#$b~^Qu4Eq|61|S(2u_{^{22UGqqy7$U8VRA)O(%c%aFfG@f)H4R>k*%Kc)Bq=$H3gIEz;|(8pY-L!FAwVFS}m8FS=dHi~d~>Kb7R={zTpjWB)Lh?O8{@JwdVOHHWkO zRup(saakWe;BeNn3i2O2ob~kKhR`PcBldIx|4GU32LDa*C&A_WWuiycZQ>9|!heQ* zqQl#h9m%*pNl{$Z)6Y`;3)nGC@h_1dr+6mnouN4Wtclr*!C8#^_g1`Txh@Qsb!KT7 ze~*~AI~@J&=X1dCQ(Ug+b}D`^@QUO zdbH~z#h<}>bgAO^g0FBm`$xu;D;>^p{s7|aYQ=8^zro?G=S%qKc8421=#RfEF7dJ5 z;jCvC+O^B!tY;bWPbyx9{Id>cJ;PA%YYt~UUAd!adsFci;0GMedM-u3eC%-66OVPn z&lLX)dVW;=Daik-_@m&_D91b2e<~)JIK|t5Cpw(%+=X$Yox@qrxsX3y@eJ^8;69RN z6+Q7jTi-BzqSA8=dZsG=AMn|V)Bh%Jwz-No0WVg(5BP9;uf&ev;yBfAv+o8Te4e2Y?S(ydQYB;<@1Re1V(6_09yJuH>%(pQ-p-@Og^w z1iwJ>2f!;7KLEa1@pr(Nf@^u{K1A_H!Ov0rFu06!(yo7j zPg3#$JgAwbxF38bxb}0olJ5ffMT&O>1HT$v>K%&yeNAzBzx};1{ClN; z5%mA8cqO4ZcuOUp3w|oN^so4{my%xt`M!#;0w1dQz2L(YzZ-l4xYV10ew6u2_+;>FmAr77 zucW$Hxy3;KdAV0@I#7E1^-m>YVc! z^2~Ol;z{7QDLw)GF2!@eA5eS=_=Acs0)JBRE#SKqzXkkd#a{w{P4O4N4=66b!}3qX zk3s(5;NoZT=l4oJp}Fx_O{*`j((o1 z<-Oiwhx2vp4Cud5@$EBHBV;jt4!i&H= zhT+4&C4L@*{!xlQ3_ecrw)~PcZ4(u54L(EhVc@eBPX{kld_H)w;sxM~6kiW6*D2Dj zE5KJO`3J!-S9~Y6EBSoz2+aQ?Uk2V%@kUrzIZN>ez|U9wYwjG{ zE>k=i@p&6Kx0g|G7N#v3^Q7?8E%tgTF3+2?75{@9Lfdr3zp>bxr+90uS5_$AHNqCC zR$ShLxn1$Au>QPL@jp=S>x$>&eEdLhS+72-_+qR-|DgDd(BB&KoA|95emGNcKibtt z@u|>1Msvu^d@lOi!~Xe7{(AVKQt{JeeO~c%vHpCO;_`jz?TY`2b?;r^+)Or6p7*`) z$n!XGJzl!}Q1P|kUn$;?3(@wi;yuBAnD^KZjIIO^D82&x6vbQOd}*!tDd4ArOS{^@ z|HH!YsY=gKIUf~28+^9XBkz-4;mEhAcD;hbYE8Yun_^#p-=kb`| zB(8o!|F&10Ofp;VFnp%s-BIsq#d|>i^@@xAw<#{|yq-;v&BjoXzGc(Y@Xt#clM^b3CPIKJ1^5d06Z`1BzrmXZ?IC zhTgAm*Bg{%8FxzYz1|b|pU*{7J>fCsQHXb}OEd%+&MVP+aEOw-t|W zZ{kcD zio@9+d9K>Q;jHHbsHO5QhH`~qC&JitN8iguPD9({B^~v!QWGS8~6u`-vxd|@z=nQD!vc=Tg6X+ z|DgDB@IMuA)!DW;0@ocf4zvJo1g`zoR>`MBK3VZW;GGq}7`(gUOTY(#OT8=5k5!7x z`*6#{@SBzXEzrMJ@ms*}R{RC<`xJi;{1L@J2Y+1gqu|dg-n@(T{~pB?!S^dZ2>czz z2ZDd7cpmsiisyoV1}=UUfBvTA*FgR+#aDp``Q)T6n*KO>A9xeR?*(rIF7=*`d3;J3 zK06G*ROx>U`Y%&_Kll}j{{$}A%h9m^2k;w|{Ha|@fVP_yZv%dZ;v>MfDLxE*r{W92 zA6C2&{AtB&!Jkw7O7K14+RulS{KJqxtoVcA#}q#V{*~hY1pgge>di&}_QQ3D@SDLi z!thz((l5Sl*8g)9{|oglRQwFcmnxnDzC`hC@TH2624AiCh2S-cmx5od`1Rn|D}F8b z7R8?ezg_Vsz_)>Ge?Fz;KZE?UiXR4lMe%;!t)E|4yf^rV;8L&rj^Zh}P86Qr$m&TB z!v}*)|CU03hT_HGqZPjve5~SEgUfZR=zkpid?mjNe6Hf3f-g|~6YvWak50Aitx`M) zzD)5R;42jG4t_bf_UFw?ehTE}_v)m*6Tt6Q^0naiDZU>3NmXwi`tf_ktHA#Z!`mcV ze~3M=Kz}>MUjpx>cw`S-zMJ9^;Abh`1$=Gvk!O%xvuo}hRpcq_%rz)w}Y1pExeZvgM2_;ujD6@MDMpW;t~rz`#m_z1;6 z0?z{XkvsT)MEp5R$p?E{f6Y-m3VfmBJ-|y9?+(5U+=qJKLq9&L`0${u_a#RUpUSls zd+#}%r}RnC|AFEYz>g??3HVXPF9QEo@jJnPP<#vcpNfAE9)a}$iMJErF^ae9Wg8Z+ zcnk2BiVp#AtN0-B_6~Rb*2UrMH~K$}&6cY89PoaMuLD0@@yo$SgZoHp1pO^QKdx4M zJ@{2&_;zsd+aBoOq4@LQk15^-4@jO;yc76Kisyj8qWDF{4d2X0}o=|PU7Ja@Ft4i1>Rio z+J4slR*GK;u{*6`R?N?l$tA41sJXif(ae1y9dxljg z_RDkCHj3xKpZyh==c*$WUj;iSC@#-ca}~c4@~ae==c*eOm*)|i6_@9#k7|y7c|mb` zuKK3p@?7;_ipz7=FBQK$U>gv3=E?pPo)(5rP+XqR<|;1FXNwgV{k38EKf>^L!tfu% z@D80$Zr2r&HlGSE=Wm(C-Z)2|$FUc2zE4#A3GjTyNA$Of<|{q~e6iv;fnTEdRp9Ft z?>NBfuT}hX@EgIUUC*OkyTWi;&z5mA8+zVU`ZK{lPvPd$IFJ9*FHIB|Kle~vzAv4vxIA~BuDJYu!aT)e zF}_tQJ}An1^eV+g&rOPpo^6V6MSRM-shk(mU#}>6vHx9%^EhxF;{Scc*MWbpcV*r^?stb z$o~e;VywCu>`%ZtobUwjzTjf#3G{op;=iI@^8a&*ydUv=y`!I1%!Zvi9X;G%Z^O?I zE4~l>X~l<~Z4G@+@qys`6n_Bx4aM&Ue;=I9V>=&!ou50L{T8&_uT6PW0@C z-`az-f4IHALAFFk#eai6sftg8d@sevfS;}So!~7(wxN`B68E5A+g zvEUDZ`$&xYv9__5e?!TS8e#d{iuVOSq_}^il|QWbUyzseW3hiIuaxgH}EcsUp&Ujrz)NX-cRux za;*H>iq8ihq4OmKi|>A=i_mUJ^B9-MNj%^Frj@^0@egNMF8`mS*#Ffm z%kNh5Pl5kK@m6_O{t?CBoo)FuiXYCm{CUM+0Do2SvH~l=U-7x%?<*ddXXQUs{5!~h zruh4i|6K8x!GBl${rOhE`OgR`DSoQ~Z;W+u;lmeN`B=sKfuExIN8qg$-vfR+xWw)D z1gk$y@tKI{ETt!+*vgMl{LdoGg0$@2>F=he`2wi<^pMDQOS?$-O4!@1sZkoWhp`os@oz=Pn@-j!%qs^U+BpQH3Ff}V2~ zF9*+2dY*?Kd9EV$%J(6Ql)UgOmHsE7|7yh_1HVb}!{A#K{}=cj;M$(YlzgDn`td2n z{ov0jJ)fezM-`XvXPyYdlki+Z`l}1{%l}I&yc2kPB|i?lqvB)0<++fwSL_+8~iFjq~vmhjV=12|dddzX7~P>Hnsw_5U@FJnNVHpt~K;`t!@I z{C$eg1b-xq{@r2tA*E**^c+_F5%8}SKMa0C@k8K0fr~$-y-o3)NBB?hLz^(XH@L*f zsTW#5^i#YI_(;V^f@dk70X`O7+cQ`3)0)|Os~qkp1njL)Ji&^4*E*a-XL3t>U~?G$ z1h}+!1?+rA@oMlF!sz*r;X^jcY+@I{X)@y2KYTnejNDyik}Pqpu^pIpL96a zdpqQJD_#TsBDl2cIO69m#e250{`t4!=YW5ycpmsKieC&Kh3A%1?=|3withkVR{St{ zcg6n%AEl{N%6_xd5V{Vmnl8~@vuhm0QhFbJAl8SxSTJC6rT(E?-h?n zdt>oDNBnuTnQiYG;1X{SR$AUg@dvLXHiB|q4#aDoTs(26B`Lp6l>{!~G_P2ZS^Ql!f z-(2xF;H|->zgj_0H^turAF1>VgPttK)4|6oJ%^xYw&H;%*3PAhcL3kz=;v`}H^#RY z9nRxSG3tF;@dEJImHs}^|E=P8fp;2U?Gpb~G`0B*aPjkN&_7b~m%&FXJ-0*8&5BP! zoIkAeoVLi;`58N;E|5-M5 zIQPqy(9>M;wcw{I{t;`_i?Dt-d|a>b8>*DBs>iEZz-injp2(c!M&ZgV*M zEgkZADLx4N0mUx{e^Buy;Lm|eKPH@F?eyb$i}2Ubziq+gyxRgj$%@|s-cjj!3wrt~ z{t@cUQF>m2o=J*72R>ct`3!pIEB;NAZP!}G<#z+8FR34f z{IiO`+`<+(s`&Y^Q=WH;KVvSk@&P!F7QmnC!pRnip%e@+zKx7`3mg6Q}Ny4_bWc?5^Lu_6dwfsgyPSEKco0A@VCIF zy?3^;`VTqsJg&~he00>|rxG8u)XIOUcpvZ|6u%w(7sYP^kHB+9@lW)nR)3V@5#TWn zckN7a_^G6#6!I+W6e4gSLftM=&GHp`TOq$i@teT6DgGV!cE!H}e*#?kQNHi}sp1c#fB#Ti`n}~)>krX$9P+)vC7!dY ztz19Fhk`G1csmy5$&hezxMTfsatU!&=X5 znTnqVK3?%z;FA?U4}6y5IW?Zy<|uwWBr4QOZOgFoboyWJ@{AY@1+-CXbinjy*PVt{_ zxAH$JejB)#VUNpswB+wLAF22>@L0u%+->FMy&=)l3%s?G{{;Lr#h(Q~Q}LPiTK!!W z9|=BK@jctEe1_sP!AC1TWT%xMt9UQ)sfvFLe!k+*fzJi^k=h9Q^L4iRFI0SFC(AE! z^l+RU#*Nu}hjW~yKWOD^6(0nCtHWJA_c)yOR73uL#g~9T2<{_Uwto`rd{6PXUe=yp z6~Cgl0*rQY@rTR(iR zcsua#6dwitlj0-5z2R1$=wApPsdyoHV{mD&*ngUmzZ&u#6t4w8Q|b8-e#>#>xnIf< zKQkT9{qj8Y%zd`YIKWhE(x#BIszf(LN{3peS zfO{jXK8d#i@JPk;!5f2X``anL5&fIya6eTQwAFco6$kdlI6Q)2ADpLC!|*b2v41`6 ztW^98@Jkin34WR44}h-$m-dQ1_bK@Ukl(5JJK&Ei{s;KeivI%sJh;>=?;(Ap_!{`f z8)-c#@^65j3C{lEIF}CS<8Y4i;k)>t=k-_oEbt7)KLa1B_&>qNf{Q(g-L3vu|2u|G2Gpz2d(>&t}CJLH;(y z%fate{2}lM6yFXm?;T4#w|v6d^Q4kb0DloY2Q{p@7t_b z{9@?2QSr6lI~Bhb{AtDS2H&Un9`K(Pm+#3WoMR0Z{~UpQC&lIaFryTYfj{#c&VERP z9~L^C{g46qHH!D?V+&lT_-oxPzfbY+z~56m683+ic-K^`rx7|x+M5S^+A7}c3@hJ9 z@zcSx6(4)1m7lA48Tf^YKLlQ*_`kt#Rs0+9#}r@N$=3U(;+w#aDL%Q2mG@;~Pdo0H z+2E}dZ`9Sw^;G;6@GQlD0$-rG{LWal;uF!2w<`W_immr4#pU-xe*x!lfXCH@##TOR zwB0l3arHRHfoR2#g2#hPJVbW1<$Ec<2)t17FFITK6-s~3la{YhJR5wS($lhwmH)RR z&+SS_yS{Wdx9fK3Ij;B?@Lv@F1pE)hKLC$E*VZq7*xAG8TY*PYmhGvAJzX5m_GCO| z?O3f@og67aJXF9IK-_;ui!ieCdhUh&7lCo8@Se3s(>2A`w&hu{kpk9yj+w^Z>+ z@Jfffe!JA+r;>`UkiSgv&fr%lo&$cR;$y*Y0hfL}h<-e%_=gw|e^WdG@~33m_KBX0 zz`Ht}$N834%sb2BJf8dw@;Qp%4ZcuwOc*N_zoMtD;C{u^A-@NlewE^@!EaVv z-beqZ;Oa0*_a`+q1TOqT(IE&j6Qxxd?Wq zIr8mD#SY9bgB;H1^-_|?wY)=Ar9Bnr{ob8zeJzEtY3x2oaw}IcM_*U>o z6n_Q$am8N(e_rv}7mS(S9>p7h?^k>#_&bVE2mes<8^J$P{2K7j9Paw<8;7&szJUC9 zihm0JyW)diwC(b8>|V~Je&F%o(vJ_J9|tJD8hpIs((el#{q3o$2ZOf0qAj})IDX$yQBhJU4a0s8mbF#H$ApN0NE!tlU& zTR+D$$J-*C^%{raO%?wUan(EwKTYwEA>TpqOVKZ#6|aDN_b~h{#a}^x4G6bkVjQMv}7`|Td3Fw#F zF#JZv;}Ji%gyDB8F26H*cNo4?@k-e9a2WoS;*%R$gPsk;Usk*i^uHE{zpMBQh@bbv z@Cm2c`ZjsmB$N|9@;f23HHR~9 zR$Sg6JFNJAz9^tA6X&1km-m#eRa~ya_ba{|^ShT?aZzz)-W=LjmfQUTNtG8A<)u~@ zEUENT=jK)Bd8ud2{BJ7c7!u29ctZ@_FTXCG!i&Qd>fD#!!oj3QG#)Ftx)=%`Yu3 zE-0aPmXuZ&q@FW&a`%eLy!?ewTd*K^UU^<|f%W|Vv(IEI&LM--D5NYMskFW!WD;_I z2<33$sWM#v_6K*_KJdbN!zjBjTeGUpV!5+Kh zle6AJ%CoL?#h2{2?cd+j9^m%#SS{vA`&Scdu>Og*+!DJBeI|!eHc?HxhU(A61=j*= zhFL@7rs(=_AqEjj)onkc{*N%f$q_BPi4HVW|Bg?rWc9VSB)30~{&f9!6Vp1m#QS&h zCp||F*u8veSzhMWjAh&2YfIF;X!r7|W%==VL-waFv1i0=6lD9kE4BSRA8MUkUX7T6PZ|YpDKO)Gy_^{zUrI^?yK2>m=m8i~7qr=$uW}{^1VaRBkh;`X;i);{~d(?a!?`rkLM~WFMj32x^C9J z_kLS&6UJY@9OWfPU7p>m$38;d>_=?*#Y#EMVG*kN$oOD zr&BC8_cEqtOv$SGF=KL8&1)HxCQr<)`7Lwhmz^?eCZz;3SHB#;>Om?uX5EnNn!k>+ zhRm85vua+*T>U}(s&6UV^Q+92OH+bgRlhH);`x20jQB?yt=b*G>IFJDXhv1Htd)Cw zd;B~@Wv%?uH>PGt=E@g+nJb@<%p6dZ60A(muKC93UA?>Nh3uM-vuloJ*Zi4T^KV<( zhMb7ZmB0EH6_N$(60{d#f+NBn^_sxl3DY1cFj+w8b({V zVEiK^y;Zv_9~m?we)W|ESO;t67=YFRpD(%}{-tn8CJVFKTbUdB+($yBby7-#b=^8j zWmDxX$^Oa$68MS*C>U)47G&d->q}>@%T7s-Uv(<=UslbYteRJkaRk(6u3MVYDZA#| z#}ka6uT8b8SU0Gjw? zk^XFSBayRZtQz8bz`uC9PCmOP*{II0>Ho#wZ5(rVQU6RzN$>dqoow7uj50ZuX8Mv- z37ksjkT9KRTw=>V&2E>IEUV_FF`d7z?(gGTaT3(t5s}U2~$RJ^jg*97(Is;?5_D^o(aHWi(_OrAF7-4Jl`5kwp|c zN8>NQG2}5ixv5M7sbj^-nVsLy-q2)IcFh~vHFOqPuT!^iXUDI;nhjr9l#)JX^;hw$ zW>Pg-EC2GvuWDwhrjsnY<`YwdBd;ofAHx}<0Hk{U-7FyAPY=|*)_k}x{S1qu48u_VLKjWJk9>KUOsjQ6$_m= ztY-<^Wc0G9Ob<*mO=gpGGUA^e>1EXT*fC!Gstd$1Ee0}qxNt!B!eN$-=$(X|P$GbF&Vfe%}vV_O8mOP%(S=uDUs#^JTdi>>|P*r2r z4K?FpW2)Hn@dcEi5an1-%dGj(xc!S9^wYYe6l2zin$N7Bn&*u#SKULZvIl$@e|dW< zo;~1;_{+Dk@&R8jo-uOuk;--k2_MP_yWFn$$}Mk3d zp%H5fD6}I}+>@71j`&s2QsF144%WTs4s`85r99PDbuD*#!pNR~Wp*t}X-Q`>%}(S4 zcXk@Fc5X`A7h6L9Gm@qlpY(6g_!ODa^Q-I)MJZ|78|LyEXilz9Uo^FTSp7leJ(<22 zxkVZ4+L;;io0@-#XaB0g#A#=-J>DcT_t+xpX6dg`Rqyru>Wj1#QGSRkD~q9Ox@wCv%JG{*ze2{j4^BmD{f z8cLc=S%0%c#x|W8&D@LTVS@i+2GED!^ZU&F9$?fY=#OpuG9_Z^&-2GO;>wUo3e2Z; zq_xf8+`CR1rMqhoF(u_ZP$rdcIrs%>U${07Rbu$ghe|4?S7&5V!#i85<#W_s-X zl&Q6u^IJsFoVm$nX0(c>%vPJ3Y0TMXGqV~OkYjh)Om1{{%Ivb4*~YfrHZv!fND5xC zT@ux()kh@fk1(MTAKXfrz$H|*-xs8$^tnI6T&DShW=Dr9g063M6D4f=hBlmz4{~Tg z2+_!sx)DO|(BV7p#fvK`7pY zQ8QK_yuuKhURRfH+`0*eXY^&HbuJZ2^a9gqXXF~UY0b!{Pcw2h-Oli64#itYz|`!s za?xAjHb|N1t#xIhZ*9tMFy*7~a%ApzWF9awNo;R)OP@7tHf8=GjbzvfQ5=)ehLKU$ zq*I-OCY|fjvEAd?J|h#GYSPVFv9Eu#cWKv{%G=G-0j6Xf z^Fcb@`K2osN#uHD6WEz0WNTSeP{NY(UjP{1vaEvHs3VSGtBUe`&v&=4*}ojvn#Fzh z_)OG_$~JSV=6Sw*eZkL3(!a5Kxs|%t*UYs>U|Scqs-il!` zr*o#gZ*t_ugUh1Y`zA#!rQCS`Vp?}RNi3c!AhC!=^yvz95M9eiS4aTb#z$1p;nPJV z1Bs_dR|=J~?KsWSf(r?TfZH^86cjEjJ;xpGH_KKKkTNF-L1dM@xLM^=&Ej#kjU4OABu$ zS5Ky*+&dg;lOh*+y;ABzjgMF1_;MWYol@6T_tWuEzj3Cn=o6INhN5)29SVlM#HqT- zjcb>i0Oz0>?@Mp*n-IZQ16 z&E9;Gj+*8lHRreWcgQ*HLOJUA@?FBe+JZQVf-~wo{V^TwM*g9KzBKN`jkWCB@#IhP zDx+z}+b5SOuq7htT<3m>qye+8P+*Z);k7jdk1unE9`4lTQn22U8{H#e+Ei!6H>8Vy zVTa6)2v*kx2y&#r_dw`tX-GJ-OnVxD+ z<{Qkp+=I^H8_g-4W+eV*&QzPe$;=-%eY2Ck#f%wsviH%o^4Q7aq`jn=g6U<~@?@!(d;4v=X`vpE;<4xS$hrvmosRuwkI~FULCTsquzA*- zz-M1w)Zol9Gh9e{W4d|hMoKuumOJMYhw%t-y0s34D#j*T8I`aT6%S1$MUls?=`WVY zb@#>dt&Z86dIKdHpBEoW$99Yj$;Wq$h^x!=j;K2lm*Q&@Iuh5(7az(bH1^e%iOY44 z#J6#@#f^84Bvkw2d0y-oml)%ZYZKSh*Q`+jO?nZhc>cJ7F=xjNh{;N%UP2r#Y_`ljMd;HfyS{XDU9~{vJ#ocw5RetNWMwpN%FC- ze1AF~m+14yxffeaTqDQYgk}%i)k^_15;zTApJL@JriMg=RTaK z!d*)#I2ciIeE?ya6X6iqwH8g8_t2+S2K=l(#bM zecohA-WEa=C3%&(eWp{;+jw-DWbOgbEO9f$e)OK<#WivHQHzUuL!`qPl=nUeexD9XE(uO_xgepaZZGv${P7S|#1$4zxe zl5YYQ~%A$&tUD3vpc!IaT?d5})^*T~`c7%64nN)Q(BG5L{$Z$=oF*_=%%`rC zq_iZ$>$ydmB6|{(q_mF38fx1%)F4AogqOBO(sJ5SXXv7w7qKToKAre9l655;=<$Y1 z=IpCiGN++B8)nrQsO*yvKC>oEGQ-|V@{qe}xnw2+@^~_Ni{w^MKWHy~7Dmh+a;?1;3GW`IpRx9w|KgDPJ;5(l; zNs{6ws^RD|$%vP@hDi;D_=p9)>Wq?P zU!X=br}j>vJ0Jo4q#O;*eZcM#d5*z;f{Y5C3ujct+?XHn=%k{^^FXKl*ywzD0W(wJiQv0x{kdmad%7nD;2?K2%Cx5;Q zMN*m+>av7RE@NC{yd#5%j1@jFG;GMEVaFGlEJU}Z4Go9&hZyMxsZ2Cen>H;M#WL|2 zDD#cfW}s9i^NxYKVep2*@1j$raePWkx^vy6cXS!uKAO!j?C7!v45K*(l8#|@lY(Q| z(R#NvyHrF-+ArgI1D8hjL4;IAFSGs^4?H4IExd`6+!sPK4j}mr z_I{7fV#(CmIZ^CfA&&7TY9G;MyqMk|b7|Q7NP3`*3ZDzvk|W(SEL2C%P9)!|LsCcc zP#yK6o;%rRBBU3zr`OdY$x$JcI~hsY^N1h~UQ<`IBts2v=$7j%bj5GjH*iw&lj`qq zSgNFZD5>$TP>r)}xSssk28YF4RDrmn<9~IDoSsHqS16?mQAzF&p^0xHIR<5@A0;UZ z$~-VkZs;llMP=6`q;--c-w2^ul9UQr>!dA`YZR(}k|d>i@|V;QZZFl*SSLwQOhd}H z<&qKABqvF!#mI%zFI<%Sya|#N)!dv34K!zhuE+|CM%g1QCF^xWifWSNYaujKDiz%% zB}r*d0~cm=o{*O>fSL=j=QH3Iq<3RafhPJ|g*v98a}NhSZzxKhi#-p_lCIM_MYOgE zX`Lb!^r%DgkX#f(Ig+evUj54$u9_}la2-P#^F)F6VjML~Y${=4+I-#&Ns2@K-csKd z$vj}iSngpYch@0lPMz&DBsr+gc1cRJXq1;^U32PP%W^GpCXTODCds;z^)8h7p_ZLA zY0cf)WW~loCiyM2%Y|?NGp^hb$Yq_}yU7G5!?V^`jq>vU8p;*a|F-;A445(}mB}cH zF;D81SyR_9ziXd{ax!LylfMRfWtHqEl@pct#GH`f_s$D=T_bUQ|Y3Z2X@EPZIG`Q$uxl&i5DcxeXPS zbLSS!OI^UDPHrwe$*at(EXb`SKmnq%^i|2K{L0)>S=l4)@w${Tj37k?X)G+IB#o98 z7ggjIl$RG3Rn<(-^T$3nsfgU%;Q3n3NdsMa2f^1)^pK{89es+CZZy z-@Iv*UJ!_i@&%gu6Kezh)Iem^(Lj*$jYbC=N39Jsp=2;BoA&-#Um(t3F`BaT1C9KR zea%TAG0-H76b(Klkm^N5Mnw7N_yT=7H9Fw8yGBuq0x_f{dPRT^Hys^_W#v)9=7A1O zM+ce|Qg)ivbv7mEpAv|sBau{TW3#U!!&~f4r9=Lwme=yZg{5?O)qQ~^I^NjdGgw(k zM)^x?191e{Jgy@cRTYS*Jr$cjC^7MrKpV<5do|GJ1ww;KBry=fwoeZwZd#-u=tDBm=8 z>R_-O zpB89Iur0ad+(1j#a&Dk8X-*{QPg)V>e`xt2swYW2P2M4m)D-sXICSDFI?BBV^@&Ek zFA)Dspk+4sGdMDl6mT_>xKpTJTkrR}gloSYZ8>Ug=>0Cu{b1iq~dDIN9Br3Sr zIE>oRVsn5z6E`SodKCR}#php0q>4-pG$q+U)D!H$MAI#+ms2>hGa{n4n7(dAf}D># zFA!Z$)F|L+{mwgJ4)~*11_FtuTm95TtI>be@)gueUo0bEoPutmc&A|SH>Vo?W#okE zfw(UI#MD5HzvGdB-%sz{UCn1iOq9P5m5TC@+0Nb6+O+27z-eYbpR6UT(*vrADtO&PfC3UDx>^Kbiz@U@zk$`h8XS9n*(j>WR2Qn4*8?@kwC1!v+1B4 zmv1&SGHNTyo)?H5X#1a(Kf$$??F}@W7ijHIqthTV>U%De>z~agkf!GhJ9n*2*-D>LeQ!9CNYjkZO`Z;p0e+ju@#9pc+IK&80 zy-hbGb&cAekNhli0!2m*CPl6N|5tnG0$o*g?frdn&Iut2Cjk@zQG-uJ3B(5v0Zkxi zh$sXI2B8fh2_%r0$q6s5rUWbzqS3ZWm4feUy|kjWRH?Oyt)ib*p%$%*;-h{dYPGet z+E(wJYt8@OD>LV)*E{a`?)b)CBRPAm-=1r(wdQ*4efHUV&r;G>Jb^US&=})(MN-eE zX4AZ9t;ZUamRd&xk!mVa?*e1$FfAyN<&x)RvrVP?Mn2+b8CktIH)mxTP36=Cm9RI&W}g?UPMWr>eRx_)fDI0bT;LL zXut3!Buwjbi28x_FP0fvq z=`{oNx`So(YJ_-gV}lhdZ{T+i(BY4ci$*{v_(1?ykw-5*sIG3V zZYk&Ex3{=DPOomDJY0!Ibrp+SsC+trQ^m{cE1H*9H@8r;=z!nA5~R7jv6<>oxwNIO zqNRq;EzDuMwxPVfy1ue$B>{7o=f<1165z9gRgLs&25M_#E9oWMv{Wp!^(-&1Y;2_} zGOTQ@s;*oX_v$O^_~j2Z6%AE&)#VFU#;d)$#)ic?=A(PV$UO4cW+ll~R*-!C!t%=2 zW~%%OZv`2Sc9W2M&SH&CO=xXmi&D2WE?U$=cl9o>G{Q#KG#7fx7u8aiG*VkC`HZNX zjOG@@eNXlpS<_fwJ#sm{rJ{ahb8Abyyn01-b7gHy^~lzEOHFlMU3t8^B|egSYvD+a zR@F9-TwK?<&{U|ox}wTfr^%eGnG>!Ck2}k&ZK$fPq%%Y_)VwOn+C;CnC@)`DQP*1S zad%N?k?{ysRjjP5U0f6Q=xrA{lk>*pjLkhgcT~=Z`gm(Y^~A;1)UMh}N>(&i)=Z?c z))Ax6$QiLXXT;wQojI>HBe#B`8D)V*c#4q$Y8z_f zbe2n#-pn&IK)HdYi@e&Z6A>YU&$$+e&#k*>NGdv?(xNa9ZxU;$(uQ)_mPY zz6|!(_@c2kN~5@rCZ`?ATqK{xd+}AKjeb@;R>}pNnwceod)Rh`KMVblL?hG8$K{m` zt@TuYDuYJ5EH6eOce4yyV++4Hwgnaj=UW3cRl1vO*kC8HS5B&G8$45OyAsiG;u%=k zSl3$LU~FnjAAJU|POS~p*Hw1N@zQAqjCbDT$!FyZD{XAC13!1nh`dwitI)|dX}(IB zM=>ZCS~b%Pt;h}?nb|9?i@qln5gTG8Jh}`)kx8-aYf>h~23{SW63gj~Oo_PWGYP*q z3166mpOS>vCgFThkL%wiLj@0XT$)6_Jqhnj!Z(V3+!BTdm~KlVzat6Xm4rW$ggd8P zxpKDQ9CX}6Rd6-ND?e}A^hpKN%BP=u?yM=Z%V!r%nl`1J4>5d5!Vv_A7di1U$NX;R zY*>PWLzA;`I%hdaPEc@SgQZxXqfvt?@U=@0JRkeh|3B%ORSs(yQee(&CpbU*$ALND z91i{>LkfJkhWCNL#*hLy@8j@+-S}LR-lvNH-B#!GaWbwr{{Z@j{&I)YO|w47I~-Y_ zZWi_VZb#nL^GXsvg)2^h^|*Gp(cyz>AL_F^2@lCq$$DJ74RE+y&!dy@gAV6+vY^~k zSTP0O@bL_MLlXWghr8{fJE~3K-EO;z9PY}uJKU}Rv2qQU^|-v=;k@>voW?$rX>DIPh+eel?G-QW_lVH1{b7 za9p>fd)-ao;Uy|e`eciZJUuGmhg^qqxhaxqg5p)ue+7!~ku-kZKz*(kj^A0pamNim zD8T`Ir0CydvCqFP^}+8nkUv}I&qGRnrN}?2_)Zze`xKul<-V@?_k{mRap?W0;x9_M z{E`C>sOP&4i5;F&dghD#9~8e% z+Vz&=I1~Ge;@=egm^`Qt?&Rtt{RaMw$PZS0mT=sx1o>@ZpEHzvjnosr#X-JR_=QRy zk08%ee7V@6R`Kb=@s2C#?<2fJ$=@#Z?^674!m&O;vyk6?_ zsNyGx9iCLYTKex9#j!p$|DjU< zgPy%2zeLI3DSVmYugmyZt@ue|x6O**C-uKu@eNY{?TQ~G<>H;-sOJww&(li&1>v|! z3-T|C+*?ZiVX1#u@)9w7eyaF&!hfy!Uxe>g{0-sgf3^?n|95Hc%S!$>;qNJ)CFAfz#WRF|>~L<^OQOfV zI>a9DxZDzvPZj&2J~*Eq;&9e;iOADKZ6-i|zwlEP|DEtWhqIm`V&{nt=laYRUZD6i z;U$XSFT7OoZNe{hIF~z4_+rK9ihXcT1;#DL{R)w1F>Vs>VfePvlOp;%lsxWXxXzI` z$5JWxPKUD{{w#X#R{R~|zfinP`ukUkUnm^!B1ionloRShA`jkM&cCx|KloJPrz_qi zyhu3g_Jou>SMm2`JXAZJ+xuIQuT>m+8XV4clUJAekA-0zrb&BNJMyeQA{_U$Kpr<* z-k{{q7WqxWVFx@w^RVK0xC}ldAiq!S^AATqkHg#OpF=O%4|!adIa)aEd6?K|xWlJ zIN9KEuIEc4k8y{7+#~$^jy&tB6g{^%ob_DH9~ACTe421Pbp`udY0ulPlBg|RTuRGSnM;x;jE{heEH5( zJSKd!aLgl|PtQ>t&k!tAe6ZBNUGZauU#s|38CO42obEz0;rEK)Ec{jBuxFPQ_dakq zw|9oL>m$XBg#SzNUkVR#W(w%Xp9xQOIGY~j4s+^oa{d@2gABp+JhNJ-fcot!i z;*W}ao8r@CJ-Jcw?+Cw7aa?zJQt{Wh0u=r(oHsmlE@nufx2zN3I1ZkoIF1)%6t`OF z9r21|9iFZ@*41jo3uXRZqWHT~K!@UCvBUQjUoG;tDvtGYo8ovF9_uCg3+>vg5iI-K>C*kb9CNE?A29uxU8#dio_ zr1(7kF^9qu#rZ8Q92$kA-*J6&jU&(X!T7(%;oPnv{38H`?3Ke?xJ6&;P$k_y>y56nlP@g#SzNzl(iBa$bOO0-mn;EmHqj z5-x{Ta~>t9(x!i9`SZuQf%I{;)R#9>6|*bHd|Kx6I>qt555LQ>EdS$r*VphF#ZIEE z@1;b}oWv^=-O6X(N!j%OXg^MDvK;zn8>4?HYC^tj@jXV8J?_2W-(q>{`XZ> zG2@_R7bIXTmzm3-J$=0B{PRdAQTxX(;M_reZa*JCb^9BMX`O_;2~z&eYNtwitCQq^ zc_eG07mlGoo9s~*|Nfh({xu712J{oxpAXeg2Yxj%t`m;K6gA=VF?QQ2$4S9{`Dh2< zSCT0IhKV*u4l>FX`LMl}IO4A8R>|)&j%(SU3rkUg+a$kzOM9>r?FYG!B8lwRw!lgh zi6GmLPdSkv_T&2KvN_8G@_=&{M2t>H%(bm)$OjqJWO4jPf8=!$;jeqia8GedceE(2urlt>dWp zqO2XSjn8T~4g|J0h7Q)#T~Ld1;Y%QIXMWqihU+5oJ#J-u9c9m2!wxDAj;9ayEt9qV zh`gO^$gd6mxL#V+IX#s3-juwTW=-ofzslylB=u{5XK34}5 zDj{pl7y_h;^07-3%5ta+^=bq6Hnl z7GF=~7A9Sy1s%W1+c{<2AN8EE&Q>}Ra8W)=xjk!~5irMQmYBxz#7xc9h>f!uXLf35Gu9(DMR z8=m|TJNc*N?ag~>TBrHCgZcmV(DuL6{GVDG`S!HX?#~Z^Q}4tFuMg4mFKFMz^FKmv z!}b(*JbS1&uMc|uuU{Ua>78a)wzVI}$FEN>?9AtB9ciaoJ-3}E^=0imr+-S_YUcFa z6lv!<{UJqY>~uU`*s*i%6Rp1~3_WY+bQ^JR{do~CpZawTwIg%=d1MCN<@C+>Xbnylru*R+-_wtiCN zAiFn$J!sk=P1Am`5xjtQ6m?EYTVEWJdHeXGU$)bve}E?a{YGTCBVyiKa=5fA zlRAZ`yQt`8$~1PK+!@K{36J%0eRp}Q>UmNn_9*Ijminxyy*4V*{POwnnV3L;sWv*RFt>3sPod4X>c?|ytHks*P72qQs0{o z9nZ5K?qAe7IaE0AouaJ5Lq#OFKWjTVOzU`*4og2eM3u3M$&pX^^Fu!(-*IK1AKD+- zhch4A9i+)44{md$>iuu{|Iq?((S@6cX_!5em&=VoQwwoMPRN{yhkN>43V*4;C3sKb zGgYJTg-Bl7r?mF)`MDPn4@fpKy7x3HD9t9um_)Wsj5P`S6Ix`PN#xi)XPLw>n;35r zqikY=NsP6Li6)V66Zs}#e*lXVn8XabXOc;j*+k(0ejVEan>hC{zTvONCd31hO^631 zn<&oU`zBY|#0C9QDbZ#V7iJwpiPbhSJ?#lfwA(~U)*mRb&L-ye$)`k@P0TyuO-gLE ziTQ*6M2VYi;v1$qciDt^K(Yz(fMgTm0m&v7ru~%^hzF!-uR$%;0pbBEJ*|NfQNDNd zOFbZ^UO#9A$h+m9iF4t6wFJRI%rv zIJ4kLMkZ4q>ru(Z#iLTM$Xv?RcVuWWEeHH?X}_vh60vZu0G>&0I{P zXU!?3n9qp$OtZzth6mjoJ0+naD!hflXe@95aUj2UZd3lH~^`;4D8%xYl2kfV2F91bSHiiUgeH`R1xb z_2;)(YtHgJ13i3w-2~PzZIaG7yjy1s7rD@;R5}13!!s!~pdZIWrPPNP&~Dp@-3RC8 zG8xGM6^UYSx>F?i;9M+4^5*~1;7l|u-<4|7nnE_iuymV*VcC-<8kTM|bNK$1pcsgOfNznd#{QcwI{5C=Rp9%K6`NvECSLCPmv)U85kWjLb$%`pQW*-`O zG%`=*3>;EUj-6yt?I|JUgWU$ZsPCxFy$%Tw|`O?ja3_FEMhYy$x zao*v0b;)%7d00m;eOym5F?fo}f-jnE_@e2{gREa9ban=NmJ?R*@L=h(=1G_mHv0hXL!D|bjCJc7mxg3cdH1gaAimszvU4ge4 z@?S!o->p9M8$eD*h}92u_0Xirpd*XxDkg9VbAsF29?n-z?CJO9q;7~h2ZPM4%ACOK z@#wv!h~n-?`$kfv@KuQfeI-32xRDmB=q=xf9-w8N1HCd6QQTH)Us8$`3M4^9gR*B^ zCBY}1&)E>N$K#$g@Y{uAL*6Wug&%kcA)0Q!!SU}R^y1!ZNgOX*l0)=FAI(4%)g>uJ zgPQlS8lA72pli%8_3UZ1IjAx;)B7zEMIoG1l=_=5Dh0Qb2Zou!Z$ad6M$o$dYAHS2 zGQVeA=6{t^Y}Mow&&USQj)3H!?jFj8n|MajdcuJQHli&)nu#bL=?iQORo({fm!gBKnyiDj;o(pGfuV7M5u6EJX>TN64zTy=rk;TH*O z^cRd(p)E*YWeRy0zasmw=FoeY5&e^!6$vavloe4}H0)6kFwQr`eg+}|Yf)xA+ym24 zxw@&gah77?yjkkRZ_0i~;xEZI{@fGCU&$(^E!W9ZIvS5dNo- z$mXy=)}W9#4^gZw+%6O0eX2HU*1_%QI zD>3h zUq}j3bQCuT@xbzP(4dq3+Rw?AC|*5H%Fv*AAcc7zv~f<4Hri7TA3rN+V|X5$PB{=| zhwvQC`2`YVii&;taRk-+$gfrjqNoTfDe(=t#IIHfqNs=! zL~4H^h^SkwBTQ2!*yFvDVKzbDczg5FkYH_7TdOvIU8M^W{nrHMbIQJG_~Q z{==6l;Y%nS2I3l?SAuAcAUbCXZ9(E>U#=9jVKy#mnWpqSX##rML}P_j`b{`9PdiW z=leA%(Q}c{G<(jJ*_bIq{9c@`X8`ByIRR$RlN^`;eAv^v(d}wMUp}keaQ7k9A-{@j%|y!HXI?QL{IV=0^-3^HUmr9cYVvx zKom<_*lW6C3ldnr2!^&GfpI}+!+Jb?$q6zvJSxTW86?)hUcN2o>Mjj=bJ2b1GD3Ls zMPS~!cvuj2BPnB~?jOzx@)wy6{Z8kvh@#)wx`<;-Vu)faaPtrkj5e>Q(Z0e7@)y^s{~QMBIc|ZslI--N)UyyxLV0h zc6D#@q70KjH8b5*W<5e^xgcy4o&SdT{%{W1(x|o|_&k-Ob{fbfZP|s3=7FS*y+Ysc zQoKva1pl-B04=VkH}5w#(fesB*atC8lwLOP`vanv$bJQXKdlYq9-zwl;-UB5H#WuT zMcmEo=7;7ozq|gw<_w76dr!J3P<4E#Kg-Sg^+&)x5S3(rt%Vou<^yN|y8vQ`D7_a& zLupIM8$@{31miLybbV?#BTjqSpGH=+*DcXhcIvQ}+%{z08$FSnJcMWRM;U#jrM}6Z zA^&5CfuSfpB#;srl*-9LCTc!RlJp!$`1nvXv?48MGkLsOu{Di-+T2B+Syray8jm0$ zc81a`^+5DE66Z2g7V*af_I;5~{#w|Z3p=pLB(FLnqM^&9{f0$zr$z_llH-q+Bc$$n!@nB_~ER$D2*>)Nn;{arE$Tzb?x7s#li7ZcD;9kW-;v zlrb%JN&jesedx4BBh$!1%hvwJcSt7r$RK|^C^~?1ujY^9 zsPV-?1&7CU?T#MBEIfU4v=2w9)Gmv-WJ~%6BoaPsAGzZoA0ZRCh8O=ioDnjWJB3Br z<;r#a$t_E9G`pBQjr2(!h5aY1{W0E8^_#!i%4ZcXGU*j@q`OQyeFwQZVLu;a_3ZDL z?c+S@lm{&KefB~Wu3N5EmyK#O%_B2Jt@X*>l+G3Ae47KiE%IxGS1Nn_ipgqxV*0%goI*Bx0-6 za-AW1BW0YxdA=}X7q@q18hKSA6VOOzUn}niBbm!cVJ%@(GJiz7qGM>&yNfGtdo(~&LpzFTnQqy^ZhrdFvX&Z3A?KW->J@Q5 zCXru}c)Yr~fgI}4A&(rdko%5Vl@0X1c5;5RthTwa0e)s&*BfxRQC|_StnpQt!D$J&BMbn3igCJYxOGP=VwysEM5GOr6!#+E7WpF5uP!jyoC}OH!PF~~WOv>|ZmV-%6AAUd{}SF$&pz?}(s^{K2RH$SA> zcLh{Vo`bkzRke%B^$E3?-(%m+HH+^z#Av35lf$6q>Ue8&135imXC8GeE9<@G##AQr z)L9GbDjJqL^b(;u9jkx{BIX{}w>&4G*WLB+J2n!%2f zmiHW^c;SD%v957>bu%}E$8AOP;%*LFtYfFZ48D4{N4Erz7r6iF=FQ6ZC*r|s3{11c z7})p1LWQ!WG2B?t41e;}g03?)gzE#>#Z5PdRK~xI_3$!v)(Sh!;I4*d7CHSIUNsXkjy9@7)&$D)k?+gL=(Lkfd~ca4=DOse z4x~SEzXR>Y@e@zFrW*2GM3lxC`!s9yXYW^WxI-uT=AL-kYM(pV#LT^#v>i_W9H!Af zzQ&pxSIO5+C;Q>q5H5)2Tp1~d4Qr2**PWCF>9Ju%3gCCAC?lm*p(%84TOsLdqkj(O z-rfsi*;l3%#|E~CQ!Y%8Wf#QKre>sEYGZ{N;p|W>?a{}Ic>k3tmsxy1>EXKWHd?yZ z^<`mG_zQBfx?ZFzMkTIMh#mcKT~C!S+U6$t^MksU_;sCbV?`O^VQyW&WpOd-nLv8t zqQ^W?kgQ(CREa{zhIomYv`KGR<$tGdATIAe@9T$d5Ka)n=FK`icO>`qW1h6>ks*ddAE5$jOR*EE%ZA;5}u!g^Bt3{KS#z0?s@;F z@SEwYHwV;*Z%ko%{FZ9QI`Aqtk_3*9#;Jq18;0?cz1iZh)UHPLO?#f^8 za96&=;ja959q!8Go$9>Xm47{n{Cf^}3o`B92rFZ>L}ZxlXO@y){d zILHC@zg2j?p#i^Bc%kBV3olaqC&H&GexL9eifn;b>XNT}Ii+%pE@cD|v*U19K z9~1d1#qkcq8pWR$`8vh-3U5+;pYXWiFA86w_zS`>Q~YJ&ZHm7oe2wDo2w$i8`@%OU z{%7G`ihnHpdy0Q5e52x@3E!kRT`Dl)X2tn&XAZa9jo**y!tYW%CVZ>n{e*8*e1P!# z6^Cz|2NXYAU;cqHlEc|W7aUagRieD!3A1J;+juRg#zC`%n6>kv!PsN*s)2WmRTpa%|6OLcO zz*h;UA1J!XUoJdT@zuh!6~~RAhbex$$PZK;H&fylKGX-k0C3(2e!b{9Ug^0}_%Ovc z3&(dI=($xm-a!iv-xX&lJ$H-zSjB%Le1hWl3C~x2yYNEAcL*<1{9)nK6yGI$hT@M2 zpRM?l!pjtYTKIg$_X@}P0_?L-c$JcWQFx8wF9@$w{AJ-yioYcs-zibB2WE9uvMv@qWT@R(yc)+Z7)y z{4T|h7QR*SV});19PePiU-980|A6AT!XHxnG~qiHA1(aXik~HXx8i3De@gL5!k<YhKbZ zh6gqUJZsOz3o`s<^J(Qd4??a)pr>8Z6BK_%zIPQUK2!L7#Xpt8mne>#hvJH(yl*Rx z<1v3P=YV=<$~?NsVxJF@`ry0;@;?!K{!Gc^d%-Tnk$y(;4@CdVia#&ugNmOk@*gYy zmeeOK;{^3=6rQcQDGP@OmHaB<_?`jz2_pA9C4Za9A5gqP z%6(69`0B$gjL_dp#%FJ_6F7X}9jW-$lE!&1Kyg z{QDx0n=c`cn_SzJ{OuyYLGg&xbED#ak$T>)_$EnjQ+%q(KcqOm|L#_Npp^SZ#qXB% zhl>AL^y3*Kw0F3)>j<$E_(PJ$^*!)%(R+fDA0*@CRK-t~a$TQ~JYTL8J!dI-_>?VB z{0EXQQv52Z|8&JyO1Z9&NG=!0^?6GEyP^l{6WWXOxf&%uQ}o9b|FP(4Qykw9;e#9c zab9(U$g^7RT3iQz(9x4d9Opg1R9uSnb~&8edztL`t;1Q*eBpZ(pDFxR#a|KrhT=~P z|4?z9fB#i+oX5jg9@~NIgX=SCGLFD;o#zO}v7W+b5#(pfyuj}ZuqS+^jTJrMc-g@` z#o=Sj_0`DsY?OY#RLP^fAF6t$$vD47@f}jndlf%HI{0UbA0_-z#kUB5T=DM+f6C!p z|1+ij&pVv$zg146@oX*Zxl#B5N1pZIaX0vOg#0zEi~=4X28Yixd~ajUdiqO!dP{vF zpCdo%^-;W^aC{Ggo+{A;J3-HrB0p5=c|bV6S3%E8>6bhue-jH(I8*WO2*>v%=vgb{ zeyStS?VVz@kPlMfTx~8AzpE{C z2B0osRFZ8b#o~L-Ha6GjPd92G7O8!=n$K$?`$M=zIl|0tRA1VH+=y^o(sLVI4 zPw1E1q+ecB^7y^BkIX;Fj}Sdr&rr`Cj!-zuk>}{Zn8CiU5%kxS(q9)U`7`BEJY&6zJDj8G{NpEu6^j2;PJF-RaMpwMYMsM5x=r+KQ2ch` zH#wa3V7{a|O;m_i zHaU8@T!c%NJoqh2{$x4tx+4kyvEnr%e{T}LL-7Yi z{^2D2F~xr`^6*W`ySZK9dzJilS?Bj9;jbu;`#D}u!sW1Ou3sU}w#()Z3g{P`^1Q1U zP|!TbPRh^)bVN&>?)Q`;t83_1 zYPy+Qtnl?WIh2)6=Jqvf%jXXY`Z+g@1G|@e$5Mn(P4WR`n>N`-4oH9SVTq%>25^w+ zZr)+ZT!y{b#~*7T=o1?ebv`|nVl4V~^N*&ytdqxu8&E##k9~3)hNPEAu|(~EyU>c{ z%c8{X=Tj^+3+-n!={9lBDw&_}$d(xgEz7Q+5|uw}h7tEh$#I;^=Tkvl{&ZqmC+ECS z^5MEOGY(qz8wnW8t(4>DpU_Z-6mI^=UqdWW`^#i%AV0UCyF$1B z+X-|M@-|Aw*X8_~83$cHUpGlq{yHfi&FAv@)L56_DLPS4N}8~0tlf^`LE{9JkL^a< z$8nwi-ibC-j@|g5$cODMv;}RmAi|14K_wSN1q_#Pa|5Arm4HYHVFRfliOB{~kwg;I z6{DcGYPEvZ{;C$MZ7ou&h$7x<6)#ol6|GhxqKH-ymHf_m=A7NxvopT*_5FYT|NrOn z4rJ$fzH^@Qoaa2}dFHY+vnLf*G*m7fot_^|TncPiD{cP_1`E$Tn%-y2R;GMWMbqN)hKfj7n>Jp_ zg=-_QsiL6*%hyHfv~lCL+0(R0xM5jkMSWf!HO8$CXAc{uY(MLqq2~-$sfFpy6H6y~ zbRC*tExI;Zi|3eX+VFqG(_>X~tky^Ctp&EHhFYK2L+$75f$bM`wjP<^G`gi(PY*?3 zYC1L0UkkN9qX+trwbt9u1A(;2m#s&FkHtAt$Z z(eyyuJe3$3Xqyg+Q1t22_AaQiWUHQnYb|B}DeGI0&X1g18a)tdU#(v=r!%m9wpQA{ zOm8_la)q}faQE(p+EDaZ>(K>GuLriw1~*Ohv>Y81DQW$ne<=F5{m-orY@e!^w$Jvo zU%ET`d~0Xw@&&COV@sodZ~bP>ir+?GZhil~!1m_=g({yb4s6LxYxyP^nE3Mk_1r+v zvaK0x>A1YJvlION^dw!Iy7t3}4;^0;Ey@kGKIOacqT>0*7b*XNfu7b+3R;h*2CiNU z<)D6}z5CJDj)K;20IdQPYTcF6-u>l{!Ju({=+E5P=$oPFk^Sj`{w*M*1-4{`T6d^+ zeiaJb{c_`Hp~3swSL&(*LTh(KMuS74WBsj1M@G`noolxp>+F0QEd43yE!?palA-7` z9kU=8Jqj)E_%m#Wx{Z#9Ah9nSJ}`dP^}y=3f>dWRa`x(N1tfJdbW(y zTfQ0DbYNs^Q%7LS3VrPG22ay_q39dnf|N+VmdlKjn{rgh;D{~!+Ax1UCz0#Dqe>gTW`h44Sk-Wf`5H=U;32;62SWoMb?;>4WRvH+p7^R?U0#t+H z3hPj!zOgZVXA6CE^x@MyO?$y5%Isc&En|(MQIV9Q)lC_NJ35AakM0c>mWZ{m^zoSfBXVbxnfd@a`_UhC{S;bfG`U-~8gy_EFC%*50_>(7& zdM6D2B)a?Xo{4KeT-mdI^3ZMl*Y2MlefEiO)K)XPd+@XEWu0qxtnOR7ZlLNEXn*T| zy*RMFC>QH!{kF5|^THjr2(Mb-KCN?N;fGbNN4o~D_Cw5s+Ex5aSeLt|;~0dL3Z(rn z#QM8W*+L?`6tKu27Y4|B%jI>;$n0^JO>Z8p$Q>nbQ8Xq!gqL6GhX zX;9l2^_8xRpi%FZMh~m9q3C;RU8)}pf%dG&G|EI*9gLj1n@0?osQEBu8Rb})Ov|~#9uv4L*LzS;6 z2-OzryVmX~sr-9!;N~ZapHAteb*zMbD#{PEZ8n6jK|v7aT~!i;`9_=*woHY2V_(~I zfwoy7AJ{StM}GujxCM*?XYSC!=CPw&~^Z8!BPG4{=HS} zCyY1{Xgd`e2$px0;3Q+|DXDy?RR4BjV2ii7<;cl_w)r4Z{Ac)p(G^=seO1 z@fn#iHF^l7My?3%Plpm7mF^yj?IubCckc+SNr%EEtxxK(byd@zn3gy8{aI;g+C}q4 zX|69cqBJ)cNe@B$eX8;6N^|>$*3Hk&!d|!!O##Co4nplS_5FUef5qwUNtp4!E@@v5 zyW(d{qPwq2g%E9f6Krn%26ksJLjuZ8(p$fo-}F*ZdedJ))Puyc{~3;-P^1%~Wo_)}EhicjWP`jGrI(mUzY~t%kgWTgd4aF?UQh|Z3K;>|(5UU!bREwLU zNiHn~lBGJkWN>G3`wBXmh&AkI;GK>Epfi4e7p=+d+wta6s~T*6q<1L#8SF)sB^{N@ zpDR;3PD4vTcu>bQKuI-sj06fT)RtE_M4BpUg3H3o>KZN$hF31FXljgv7pH6a;YejZ z9cpW{CeD~TzId8iW3eAxhQih<@K+0eSHs`W;SZ|ogy`=C%R9e@Pte{CrO8Omta~jgYv_3u5VWZ0U1Vnv|27s&;*YDxC&1y0xTX#oxnU`e677Vnk}1 z{$iH{u!>7%D4MIMh8^%Jx`|fAr8D8=OFvcbjjH1`4TY9~M^#PTG<9a6pP^^Y0TvhY zgOnE3uh4z30uL+-FVXa7JpV-M|Zch)?&I`l7c9>IH zsOi79YG%Ql%Av@*+x1gJZ?tOFzmB!%CaXQ!SXjTwla0zPtA9pTTQ2%3l`Mh)>4qoS z`o&gB<*ypMzm{44vRqV0TJRK8(|76#t~0xXI7fV zQ|<1}snqnpCDv_4@rzbreWqpeOHR6WC+h0k5RPd20uOYNwVe3A3VkbM%|CiyPnUl{ zvfm-wrv4}qJZ2*&S!Fcss(_|F5Ap-_*+x1{Hz)Ik4A`J)Ct^JCVkPwgPsT`?OZuG@ zn-L(>!=CZkGFIJrHgY14QeG^sw|LT5LYMbDX4};73w!1xTgK9vVKXh5W6un-VTFGm!1(BEi>eTTkJwH-YoOqn>8?oaI}tXTpxA zvkz=Ni6u6H#CcE^O09;^=^nT$5G(&%tGv14-sYQAK!w??tMfgCzZY$pSbMlgaGz~!%-Tr+58JGrm9pX1W^deH+>R}| z4BKmMv$bZcXpQFz)!-}8%2U^n|Mc(mZVSNHL3aY^cazPl+KDWK1uXNRF8|HgGL+^; zluGVvz1Wj&!0yVuf33*+!9InK&}YFeah2A0xi%oyvk7C->I!{;C$k2t`wzzAY>-D! zF1Ps)$0#r(UF~X5w6}}AG2fH^#*b`Q%7(4YUX0dehiH8PEcn{8EWX=~2lGE*b50r? z4odU_h*g--V*&ILNDQ|mxFQcssIl!|!1igR!OpSbI*U71d<-^6S?xm*kuinoS(iEf$=Dm24-lI(&FIw2zBaTkoYg%wjBGgVRfFfA- zbU22>s?R_b`rGQL&C;f6kHw6;B~#OesAIr)5)LNvRH=8nT*XCToe#$xdlL>M^5NKK zZ%_MiKtAl<-%mKOKzlU(g9MhZ_S^qVID*K>!?O<)#0u?ua~jwOyZjfE$H{ClP7<+< zwe!~SoJiAmBsgOx70~aP00$yN;42MHf5O2TPYP$?f!$LH?l{vvEwdREA6V~GIcGx+ zKQKcN<3bqYWb7Xj4g;r>rh}`s{qwkAF%q>1=0{PGdEH%J~6v$b#P_ zSg?eP-hrwucio%dF3XPl6YMxA*$(~woQa^}2kI}Zf-dBRj*A{h@3+!MV*@f*4M>`2 zM?#_DSWy3kb+&?gh!J?qe7hQfBb486@1r8u61>t9#E2WA{J2K72{mbYYv3GMovY4J z)>`edN-eiaVRTuND{PXNT9QRdMI8+}I7GobEczYTyx3$@01cP{0A>|^D9oPm*&X*B zCGkUxQL3f0^+HV>g?c>I*34sIz-Kd=jtM+@REy^Xk3XIn=<$!?Eva!KW2v4M6Ec3H zXN@)QG$NI80nZALznBY}_h!b@-b>@!y)AkmzTuk8m`2Z;o-VPBQK83+dmic<-%x8a z!c*nxqUl}rf&T0a!+(N*cCW5_7941La0VQEyoN|g*0_`^gun`m9VVdC| znQ^W;09ySkIDfXQ z>#BE49h-B@xZbF>mtBpg*CXS=t2uUE#CqrHV|vFcOwiHCZW+m+U^jqR-}G1uy6SKS zb)sIFJwx9*&Yaz=EMu-YM>VsbsTF2Zf&Ll#Y_KOdERIf!uF)Y73RTApxOR=Md2%+4 z11Fyh8#LSi11qK&&5Wxam;oib!LjivtOSm-QPy7nAgmweYNz)8-16CJJt#0vhkCU$ z$hRt#68tiR{Gzr{lk&*lc9u{6wzC5ApPd!P+NBK6m;-?_G-jugOsN0Nm^}FbN?@N4 zvt0GFalNsnXC+t(Ejrtwn5LZ*qg*+v8g6gA6{jQY`d~V=HyGwlds{WFC|*9n^ii>9 z!Js|0cS*LTdvu)Ywsn6ah zsjkgPMoDFlQwl6fHc8iJ$r{j0^CSH6gKdes0;1Bf0|PMfafqh431s2$|3Qi4a9G?9 zw=RiGz)*Fx^f(*pR>2Pz|L@On|L>H9InRB%{(+5R7IoS`SR#&l3C9CKfSa85o5@hu z9QNi($Hj)$%&<4QZ$ z<8ZX@DCbnQ6LUD!cM@}ADR30(OY+WfDztmvo_4&{;BbxNco1GC`QgQ>S;xy9Lf)yU zgBWyJa=<#3brf`NkyG*GW=WwBU8^T|ZSn;UhsGu8QucbaLymU;r`%aP`02-;3Od>5 z==|e{PAVadB zES}st?jQ$;I1Vv~%S*?DxSIIdLA!P7!kawUft1HfTB#p_91Kp@o-C9!0~p$Jhe44f z=3r@Z6CK ztv;Tz$^GiwKBUeEJ{QRX4)LaI4pI&%DWDx4;BfZhP|yJ-%{GoPF7a+n07!(?sFU;4q@(~E9oe~@fyJK6of-T!(kS2FxFvcB}q9SSUSxE zNi8^DLlWmMhhBufa-57Dg2!RZ9FG)SzD+(PbBsF&pE;nUIz_9jn?zvm84E*)gyW={ zv@=N4F40_W$8b;p4Nbn5_X8?2w1#Ha+dUlgJB%h%Ytqilb%@BMrkKza2gwYrUURkK z2RAwzm{hHU%?<@UhT(FYRg+N+taj$ z|0vupNe;IRZMny_KOLq$Lu*J@Vrc)V<_zsJ_b_s-Bl-B<2cfuJb2_jl-zBUZCoMOx zi;_tbne%-^38i8ghndT5pPV#PB{v%G#MSCkl7iG>*uXR`mg5vka!QgSXB+$|esB;>ZUQ>;lK-Y7aTk~r6AmcZBQB>O4%49YfrEN{hBvLn-kMg4PH2oQuBl#>w-m=?Q*AY5tu(x)t*$;&URl==1^`2;sHcp zy8!E5W_Asky+@lV-g%}EKniTghqo{olg*yE0u->aCt0g5x0}5orI&%Oiw}bWK=YNM zp|Es^+W~bzm##MruaU7COEl>wB)7qxf=1eUusX*~GcGHF?PH;BX&`>m8eh=NHclvl z4dI9h_M|_H_MnMIPoN-^2^Ja)i_ET*O)xgqyGNPMtxlh;8lDP*UhjplX*lF-l|x`t z*D0p&Tmbn{4jSn-GRw?fkV-cii_A=;OA!dpQ>6bIGaGZQpu(uvtBjR*LTkN7zcs2| zhPPC$P48T^Z?dVEt^sLdX#^U65@^huTm;R$F&i=gGj%GYN11tEzXh|g>}0cxQNG?6 zF+I=;9@yMNt-G3CaE&ed9k}nRX6X4Ipv5?>K@S+w<|1_1Jk$WL_8Q-5Iyes_Ag#ze zX)>Y#uak|V(SwuAK+T9e*l|w(H>`&`^PoJq);rns%$)+3Zv-hYBpo|JFPdy-Vw|A~OH({x z&7(SO?w+EQZeOhf%QBwSCvQVy>|6~sw3zx*?>)AE7yOsHHdyxOvi;eX{i+%0;x=W8{(#r`w{{2v9-9gtia_N?<{{I& z862`f4I0DyYvuOzo1l?DEi!wmI4%MwwV7E^O)re?DJq$Mo|!eq>^TB^(tsg}11Qy7 znr&vI++;HgtDXl4%t8fAv!U2zGrh!2!vJeCyW*>3q;h6 zhLgZrn1`(bU5eJ2xiDx>1=W5S(AX;*RBT}PVzj1uZ&YiTMg8l|zCcn&nSF0CPZ?zf za3&fBRzHCAdJ$~uk!PMf*@W@Z!-|h|ZT;p*{6h-Ecyfq+tqcXrOGqbFi z@M8Ewv|!{L_v#;FH^J0stOMmIsA?{QHY9gb1dK5PRZ5%BTL9g7`{m%Ho)|Qn6N3gN z-%ZhRriSRthPL~#S2klCZjZYl)$1$9Jw}~=2%WaAS>MpA+~$S$Wq3EPfoTyeN;h6u z1yetieb^{NyLPEy1wZf%sd@rChI?WP_Jo=K`#hLC{%GiV5f}nxYHmM${f0J*?(Hf- z)90H0E5ZCGj;V!JW>3(a1J!JX`QR^2{Iw8y;8ayk!X-t3cLx4XeZy3{8@= z;&hYgwetA69$KF5g&Eju+zoc%9G7PJ*T5_Y5mN=}_pwSyZ^j+e>sR26WV{8&qglUuw0u5t~K$P<=2*{ z26~M*&@aY)tDXhp_Mm03bIvw?0Ti58j?o6Q6dqNi8h2iCNI6RBdc-K(&<5|X(sek} ztA;lu!K$KRiB{JXscNd#!nN>9u)11!hZ>}`6%Ez!I$nGWSUJ3mx8YK)rZF78m|xr5 zxU{Yz62#YMEvu-hsjH-y`kwcb*}?IJ=LCo6otak<9I`CZR2v?(BwQPAsIG)8zKD1f z9Hb68dsuMDlHic@hX#jKO)D9%S??e#2SaQJt8mm=2#2c;L$z`+!LkkB7*wypp(3ZZ?quh8!Ibn z%d4tu!dPXbu0~tQEdv+8k#b}8lG^a%VCB*Zc!RO^8sc(QuX>MhqZVFS9nmTxb=B|@ zuB+0*jg^s#MVh@>+<=(6xChG{t1k;fOV#0Zb!|DgWLe#E=mBVLV+0(bUY86#7H(+J zEcYj9S;>vIEaaCiLt|>fwb-W0`b#x%UsbrlYIH*BTIC^S!jig0i)zB<%Da_y%itx< zVK^(Og@DnjnrdoduW?3|%j#8@U-OJ_ZDzac>Y>{Dip7<6O+YK^A-fp5aj{leQ`ZRR zElcZ`h4WWb)Gk?;-vIBOD-W*>H&j+PhV$X&&`ZNLHRX|TVq(c z@1z4S!2hIoM^{0Am&0TB6^p8Csw0H&p5OPYA1Wn1A7h&d&XyIAt;vxZO28u9Sq9efMu^Y#`%NoDdYTut}~1M1y^~C z{li;RC;01)J5$pA!vPih2Z0EPT8%4qz5Nr_r)Xbvs!GI%;dB)VWDNM{v>5b4K>IeV z*kjYfeTOoJre5o37l(I$Tk`cpRlhw8?B@hRaJ54Gms%;IJ4f>XSDZTDN2f z#E6Za#Lb5FQoaN@N#&CLZ^g2yothx6(ful>>L2?i>tdv-<=Y{p4eMnU30v^%K^!M? z!TxsQ%U$^8E_@B}ZV(X*=`snw%;Z`Z`3)q$o8);c|AKgsLY>F+uZXu0=eGde3%sj# zsFT#-B^|XqNIZq|ynbA9&S4B&%agD|`*+YLekv%KXl=rxNy9M z*~y;6F8r7aH=yB8dNN!%9}VPHYGQY3KdPa*DMuH8CTuy+6I_$zkkp?2-yS6r^NRx0j#LK@yItd^^YV>sddllgiZKhefNCyw!( z34eUEMpp`G)YA|CSWhK!T;VqS!{uR{d=T<1|Ei1p$uyp%o|}lD20C(WdVXW$xNl(n zOUVF~KgGuHCXV{CT`a%X#xY4*?PD8%mv}IqB(1yKWh8 z=Mcww?RH*n<97dFW#jgK{L-f19uHaRaeM6Y#WrrYzr@Dv{w%j~yPdzV@zbCx_WxgO z+^&D8jobB8_o^cq`_T!G9bB+jHvI9Ef?W~9!u)nC8$0q~z6Ko*i+TkvtdV2c7UBaT zjSKQ_DrJ3OY~#XuI%$VF(!w$RDd{N|{B4q-D)n|i;Vc{76DexVXz@^<<#dr_OHKlu72kR*b9RH zoAR#;zMSmeBluv-e?)5(!!bj{O*=-M?Z+R#!3Fp0xZnz7X(9aK(w#WVbH5I-$>&<4 z>hp9V|1|ac2%9{|5*9e$#!s>7St|6DQl8t5S&n%u)-2?YQ2utodyzel2!0XecL{zD z$-gFeU*d-Z|1-6L#{v885|ZytYv#QFK2PvLl%Gj!tcH@RhMx-gUsJuyZ9D*seRP@N zB(62vIL;gQ(}s06j(Tn(euLl}h;I~pKk>T-|0nT33O<$m_=w;o#2>S9w3E->UlM#5 z>3>`Bmxv!0Je%|npyL+q7w*SVf^&bA5a)i`frAW|i*54gx6P!#PH_B*DqJEqj_qPQ z`8)>gK|NoQ-EB5`N!U8iv&MHypA}!1yy+IxN4Q)@Jc?lTxHXPDmGbIyT!(_ z-cmZaxLxqc#5dWvUC(_sj(Q>_|A62P#Q#8??LUX?{Hx#_sa@|1zMkaw+4Q45yQy8@ z*f`qrORD#K!EYh%C4D^Jza^e7_`iw6+bGq-^3$+0VS(36s)hMv;(cx0Zs$N7M?3E$ z`N4v3BtDcl`|Tmh7un=dKVKi6YU8N?^zO<$ZMxtm5T7UbyTlg={yOm`f?q%fY8MOs z6XNwYZnyJN8%H~zBKa!>-$wi@!Oy~zdswa&{7m9E3BHK@YjT%Bcx}K;9nDeU-15T@(s&Jf}cqI6XMdIP9Z;mkVpONjqo@OOy+N$^*RZzIm_VtZZ^ z@)zJqDlD%GUP^qA(4&)ojtG7p@t(BidVfRxF@`v{7stgy6o6&6jpMj@nd+S@_;bW7 zh5qa4#ABIF9`$b`{i|&p^%v3!=o-O?5ML*F6Y(1azl8X0#JRm^(|mrnO&;ypOZGf$ z<7m%=q-U$(za{>J;QNX168vN0&)c}Y-dAlL>pi&-e8BRC;3pA(n>e@YTxyq({LOqV z@ovPqf3s-6f3l5Zy``l8RKX_^Kf}h+e%5oAjia7TBtJs%TZxY*&URi)c3vQOcQhE5 zO9Y=v{BoOqv}YQ%i{lQ(&>l^_v>$#T)+Ueq7};~1;6q9Nmx31%|CNo~>;0{bqyD)h z|DfP=h(Ao6{ZL8m+9UWuI&L^%<2b}mg+E*l+c>)5BpTPf$*-)xk@yI~FDE`-@cA^4 zRM|M9e5@3fdK<@jt4W^wlk2Ubc)dr+Pba${7kn=9Hw3RE{)OOg5r`27zqg*J|Q#?qJlX9+%%_(&T^J$#LFl8vLDpOgG# z!LK8JzKx@vr8KTDv~kpvOD9O>g8PUswsF++M`~BSjia7Pc+nS@h~VRhud{K~^IOvM zbK)Ftn@|ZXTW#{F|9aB%sNk!JKVjpjU!(KY7i=8$l=sJtaGoLf`NZE9d}vUKYaa-n zPW+(Ydrq?CzY_c@;vPC*=eT-dfFu)`69NV=#*V5BR@ShStP4JX~ zmVBPz$4GvZ;1wiaEcjI7lZkUbrc=DlvdQB-&&xs^SN(E|wPms37ZI^a{4AuLb;5&)GXyf*{{fCXC z9xv^v-VvO4UxmB${7=LS1^*-Q zbBJ@jHDu33n>_mGeH4IYnvma3{nBESN58#E`r8EGL)`j_dh5D9s(6F++#>Wde^BVr z2cb1EFACmC`X3ei6q4T|IQ;6YTAs0SZ0{7Z=N01YpM}J~vdLq6&nG=c1TP`(qa6zO z<3{3{g5OTO2XU@<3Dw)*CXeHBEd1e;Z{ujsTcqbq!QUWWBzTX(N{u#F@UFxs6K8ww zC3|Ms;k$-6H6UxM=wXnx|t4+;JW`Qd99-YNJ5@~4qyHH7<}d4}N6Q+oq0-1-gPc-*cc z{e6Wz^MQh&NcInQ;e~>qO!l1R!bb}}lk|^s;k0{H-{+F)ss_4jn#AewF^SV|Ajavi zP&c;=Xq?n3m+@^e9|+;h0hdxG0F4&25ip?;#ESPzrVOdaGnn@75p&iX>;M%3H}|) z^L+?x5A%&ep0DfPFF4Oj^1cEdk9;2u>*w#?KN5P*rt!ts`&pj(5h2gx&ZKfI&*P$t z;2aO|6Ow9S`M%_b0fKY?=DTpdZ-Vu3|Be&#+`p3re~s#$BX~N^tL1{TpKAo?`8gsu z`~QI8Ln!}m!N*fRjph|@7xS)y^L%)U3(ph$8qz=Bg->ze7rAi0-<$1Z{i|H$+g$iY z7ycW;`TOFhT=)xu|B>3e&xIcp{4XS*N%JDNi+Oj!`B%*HUHCbIbHC1T;qwIN=X{!6 z_!WW&s6Ds1@Qs4^Ci!hH{7J$2K8H74_A(F2YdYE4<_;)0Kl?%UKaK3T;UKjq5;A!L+J}+TAng315 z^L+^)yYSBi??L+I_q@#cIS#J356PcK`xD8B3VtTZ^M0P?na_5SuXEum1TQB28(jEp zg7g0RcY<>~@qUl(~g5{Za6P(XyPZgYx z-|$zyabZ21N&f^FUMe^rKU4_L#}CzlXH$DtyYQ<7=Qy}s@a3fEZo&EZgunmgc5y%L z5b}I{!uLV5JRet_Ko|0ux6=M`kP9ymoabl$K9u$F{5(;}^Lf(@7d}sLo3n5PNO^GQ#^c|PeUI9~@l-G!eiIL|YqUHBxydH$I$_-|+) zm@7E%SE^iit>ApU>rxkfrQkfDTrW6Z2m86;e7)-~7k;1MJfCb4oacw_g7fvI=Un*9 zg7bXB&q;6`^0+=KjPIX=4x&iBd1o}YlZ8!uU%PxI0wA63!<{_!QjdH?u^ z;2fVH3eNkxPX*_A`$llyf9Z6gp8K8mUw*+kK6?tz@y5@=upYjid6AIk{aUpPzeI43 zpVfkM{9GkC$IneJ{C2@Pu72af9~68A#m}RH^LTkmaE>4TUX}gB@$(NM&-W+u_opn+ z{4*gxlIF>8T)0l(53(MPPrnQADL7xx86Y^v^J#+f^}4fNIDe1H_Hg`{2zieG>4Nk8 zf05ukF2aKIxVXfHUn)3{m#YQm@p6OUJYIg`!ha<=j~9LpjQzmJQ7;O4KF;}v;Cx^E z`-1a){;A*`pI-^i#|fQ+^L{*)ZdPMEIez##Gv++ri-bHsrxX&L$LTb|c|6V+ocnjN z;2%=_*SqkQf`3QytuB0>;2b}<2+sY!QSj^Oyx@Kp{s+PDCi%x*_%niUCiz!g_*;VW zyv@(^aeqyt>pb3Wc=i=P|6>1l6P*3uM{xG%DT1?q@&spl_&Gnehp)%Z67u8exPqVO zWBHN9SGmaZ^L8xH`-@)-d5*(}h@*S)5Q)D}`je1n|2!u66grQ1)CgjMC7sTZ}^Rw(LzQ~`#MvJ9e^0^L|0lWVIYr2GzvKzdei-4Rho8q~d)Pk}^CS)RX_(dao~=B$UG zt7gvfr@F}V^V2NP-`AA7$n$f|EYIJ^tq}6;=QhFldywk{=l#)bg7bODU4rvAmq8d)h_%J!MR0Ig69#xP4J<_?{VRq1?S@{e!iUB zdkGy^{6om|{bL`x@J|KjdFHU-d|uNj`0Esh>Ga$-+r#H;-2~_JGJbxY<@q_}5kmeI zI^LK-ocH6q=sHe`kmq=qE;x^i`7V0+`FLs16+#c&bB*9!?|Q+xUVc8F_49SAM}$0I zr+U(bKQB0c|IN?SOZ{I8dDef-g?s5aZ`Q;5`8j*${2cx1F7o_*Jj?U-u318!uWOYH z&es!`2+r4?ngr+TPFD!d=hyt4J=??g8{aGB*`7ZN-WvlCmcIzj-)lVW!e11e?SD&f zw*Q}kv;F*BKHJZFeDqv0bG}cQpUY>?@*`d3`T2X6XFU}{p6%r4q*vn2|G|ZCbK%dp@RtPtobGJ2g&!6?jqW>4q35&NKg=@)uORte zf?rR(zu=D$=jY2=Kl?u<h=?cwLtr9F2F`QMTM?{ne57d%S# zKkCAt5}fUS#f85q_)Vn$BNu)^aBeR@PcPeh20eJfoa2AE3m+@^%jBOaE_|lodq{qP z;BOJH68xXUFA@AJ;+G134*93egi8z@MD7Wd*3qXeFhvS%(De=CH?&b=Quw_aE?!YPXp`c zarYA;Uqkxm3jSN-6@s&Veoq7I-=y}A@V*Km-$DE?7k;1Moh1LT3x8Db_s{@Xo_FD| z2+r@}dB=r+B=|Y>oXJ5KenjxGByZ4zg6tpW8G=tF`JOJkpWtOAe})SmCOE&}fZvC~ z_H0sK)3hZ*p8Ko8gi z{B6Oxzdm;1p9{|Z9~!hA&i;Ri{6Er#Pjul^1?T=M6TDNimW6`*sJ||D;f;d#BKg%W z{3^kRlKci2ew*O@{?&V2_-4UFr2i2Y{PN&a~k{)*uI{?d0`_(y`@Mfwj4&T)Q3 zaDJ}RI7w3r7RQifo+0=fq(8@n2Li6CpgcO9}CXUfgci_=gFgjk0JkeIXSW4 znfDN!-}4@H;e!O{`S2_kK1%Rw$ew8~yi9P8w`DH8NpOyn78ibv;5*2kn_T$qg7dt3 zzYG6^;QU^f$6WX>7yg>yJm0=8__t*L7lL;Z|3+}0pZ&Rs@o=KY%J&qU$ID5A^LQC7 zIFFZMF1$!^o^Q`{;pYp^<7>I#-0!Ph__Z$lM!~s%?{wk+M{wSs{=tQB6P)L(rv+!f zy(l>Q=S>&>f#B>Peoq^Q0d_6VKbZp)`l0k~$%1pd4R_&V1?T=P7o6YYw?uHBfB1cS91r|Hy`Kqrj<-#M zbG`QpKA+ml@6TiX{GPp+g#1jy^4FU#`~$%oNuJ-UC-wVJP4qwiE=6w_ev;t){xybYT@K}B!>7OIy?;yU&h5uA={#~AxF1$tXXGlN4 zZ;$P{jrebb{3hZLyYNQ^e}v@U5_}2qe+tg^ekM4#>ubT;{vLx9`-}CTC^+jMBsl9Y z5S;b%`}x>E{C>aLLY~{}waiiP$D>Dc6rtO(WA}5CSZu}md4BWJ7RjX^p7-eM?wEew z&jy7ap5MrwF?qiJGgip6KSM5jn&36mzh#26|LX;3f39@lErM?*{nrS-mG~yX`99=( z1?T&a9}=9uSKTT&KfkbBaQ@wpJ%aQ7RC@*AK>@N)@M)f=hnum> z`F;;RzGKe!d$b5We7^^uFS0z}@3Be9w~?Lq3eNX|JmkW+3eNXq>=2yq$9Pt7z8_<+ z;HRfyuWH&p!Sje86rAthI3hUTFTvk4;AZqE-~W(9e{M0D5BC8ixxG6mnUqlsjE!LS2R@AE(xRNxC#eUQ(YTotx&m^2ftIiEL;o5)z(GA zdFTCP_K?O%Mdih$C%m-0s-a?8*lPBV{tSW!bRqBWS>aepaQraO;smYnc8nDG8%ud! z)mK=lX}A#yFN$$#s~e>+eJ7W5xJBEjW({5jQ)^6M|ePfdFk zmBWJaIM>SZc(^273d7)ZqU4{K3tA10B}(+WI_u*f6zaXu+^y7Fn3yJh60=M~`dNwb4oagB9OOV;R$9@dG}4gGbbF6Ng$q z^=-qOYeVg4;ii4~@i;0~sj8~HK>s#m+WO)-CDG2}3reD27tbz<{=0ZqY2^pAXBNH{ zeFv0;LebLPg3{=O+?-NKWj!+?7xyh1taEXV&^IBvICoHq{#8|={{&4dX`f`4jCg9r zn6(F*s@6@&9n`*ZP$>GnsyDQDN2IPadZ;w|St$BUN$XRCN(X(POci6yPi=*8D~OIn}Sxt4#dJrMatsB%|(WC$4Z zIg|@U|IHeqx~BUIckJsp*4YWhSq&}@Y&lO4tpmGD+E;kmr@ghVcgxYKfvfS}vyk-z z4S_AMgetpl2I|xZVfeD{Vht zzw%qWcXoAQbkDX|r!LAm{7H1r6G!?#anw8b$@Xyt)vw?$#6lN_+RyV$jXqrxJyIHd zsU-Tu;8&qQ|F!$4#|oIL0EkYFzUZ*+;wKkxTT)e3HF#%qPppiG%4kpkH(LD$4M~tl zxl!LScxUU*f@}JBoc}#~tp%K*g<5N%lR>y+B*1ukF z`lc0((Zf$1?f=9lecMyATlWSA??xk|y*nOIlGeD=Log7Bw|-k5xc(=g5?cA&`|m#u zhJz>8z!Y#n%8cS`E;#nYUUTqH7)0lJphiRA8ERdXo1-$G4rGrO`<4a1g*z-f^B9XsUlKj__1~aeFWxF$_Dd zu-XA>eQNX|dZlA0AmxG)d#>?x#DRf{>3MR2?07 za3@%X<3p7k{ADz!V>sksP(uWFY=A11Tzg7Ckn5+m>_7ve$6$`@7z^8@dz8d&hmV28 zcL413FU+zzU{WxenOpeW1nA(DiG@2R;JjKAeIK%!FoBgFg-TkV%2DHgZD(XW77DFX zM?uk9xxUhN5Z{JJ>!s_UBP|}u&7|2sw9W@gvRR2WPZ#dkiD93#EU#{eG*#3DmxY(r zHC!4DuUuNu)EEgb7Kcnp<^C7AdjPL*rKrt57`O4?d5@Ji-FBww@u{nVMv7St=ewR1 zmGkII!sDTw4~xd2>Tr)wty1vh3{L>eA@HGVUf(!aTgCc&0yjX$>%;99I>|yxpONdw z4OV(+CMvSh=h)Kcsx(zbwx*36uj#A%VBs{F;H@QX_B2gz7BB^k=>tws))lI=7frvi zOFE!9QPUSjVGz9So4iDw;}ep9Ah!eTckur4*>T2231y8Vo`OH;k3|2#p= zD*E%T$?9(Dj@9wvuhjJ0vh2$Ipz9ai?B)D*fNoDf0W7cIk!BaO*e_EPltseJG<{=2 z1(w_7)5)Xf;i}#{%El?yn86(DdJC z+bz!imkKb{iGig)AN1q3vhIg%ThuepJ^3esQ3?<9)p9Xd(hKBs^x2-}8XT_DlBF!n z=F8hiN&h4MYf%5+Z2G%DVar&R{liB3u+o*F6f3#{K4)Qd5O}<8t=cwAZJTbc)~?X{ z+RR)JTk)0iSbDW84Q_}v0=ItPy7dm&`kl2kWy3?w-guq31vI8?xD_ajLF{-udC~N> z34u=M_7E=*L*#X-gowDxAy}_Yh-oW;uTF>@HDl}1)EcP6vtenh@p#oA3^BgcXM<NlvjO2PhTA zR*XYB7xS>_cc>9!W#H%CLB|{`YINwA#IDjy;-R&Lgy6c}$y_+)1dl(S8R+4AxA3aw zKo&BujLVoUdLUN7Q>$miGAUJ_E}Gs|AL!4{F#IR@yXxIivtT@Uav#C7ho}s9*g3jZ0qAFUSx}kR z-|iQPSGx`fZo39e8xSv_Q1i)o8g^x^Us(ozfp|_p00t%klu-*`AiIq6x;C4W_rS2j zB}IdIYNM4-{EQ8s*mX88t8243`6QLmwTqsm?zR&W3SGY~OUp_9YjdAqyKC>|>6v;xdP_w>p-Ec?eV{*FKju%q2fS?bkFf zpiEc8vO~c$C^Om)CsBr5t|Xm||DR$nlA`x$t!vZx4r#uF9S|q^CTU%p&Po2=wlw&K zN8j*V-|$m5a&wnbvu&FgMQ9V~<|M}%=;p}zB3S{WuV_<-7HPg&r;7QWUDIQ=##S*S zA8pFen)O&YhJ3GFf>OSbWMHyVMuVJ`GCV7`(Pk;%)j2U)DI@-&(F98wPIXdx0l{mM zl`{Hutema+g%otNX>D^GBmVWG1Y_ycB zHai*p#;F{`zr;4$dSVB`9yFKQlrlP%HYFHSKyY|+IYzUc%FQEK>9lbv!A4r!jA3+z zQ@J$+*Cv-^w9%=YoJAly4C<7`P1ePB+a-5va~VnTtY_Od@t#E2$~nn%i~(bBBWHNF z0Xa_c)S~1#!}AR6w>Zi33>4)g&o3awN&dk*rHyBnh15!r_9O&Fjg6e)XoaGj%%VPkqMSUPkfBBNjhx}wf})%(i5KN02a7V8GaM#R1t&Q; zlpJSnitFQKe4hgjNbG*~RZ%Ki%3YlwDE@)T-lP5MU8 z#D6kv0Vh9=#oaVc4vq!ShONzXdWt^N4m*OOcrm~JRwQ)I4a%dXb%I1xnSr?b%pK#G$b8z9BW zcxTU&oq^YSJ(}!nU5g#k@28%D;9lSSHDy?#f>I@%>Dv~m+8##_#&zG*%$X+$g8iI) zIwsesZ{*CYaXAhZ{uMzm>z?K-X^h)!y{Fk`m`cL^063+`mLIaVC1%Bj&CQ%?jae~` zllbMxfn25e4h04Ub)BJ=-5YdF35GbQ;T1SYUp z8(B)fg;HEz*OJGsen*nfv?NWMLG8<;wSy+y!eXg0vDuuAmvlH?&PY<9WP@eXUK((H z;j$Mlu&?6e07BMP1J3c+Dq#1cTqDxW498?icObMhTRmVfMpIGtR0mQ&$b8@Yge zom_ajQ(@=p9h%0)AB!12gOjYrqpi?5ZEwsBM|nMyXYyALKfCvAmee-oFRG3-Y8u@(Rf(#bYO5O~i}RMErX}G>U45jyvaTTv0K5fTYN{7m8{zKY z>e?k%x@b{TbxmYQb?so-&9T?tYvo;A~r%re+~qnX;n^h1gC$!3aoUbdMEX`i>$45;-+ z5WcM$YUyF-05H7sOs}<8n~nFuf&t!a(^q5$!ccAs}87P~8dY781BOyJ?%m5B+ z_)PV7SGiR05;I-p+tj+tY}4a4*65Q#k8YYpP@D1b>dDRq8flZ!#8GCBaaS`Wjd!&o zC^w4i9tC#afp+&qyRo68(eN_U^cqdN_Yjz3d@okIgp)#tvDAF`CyE1D{L{& zEXp=ByP7^YT#b7O*$VtIq?am%*les!`8B$n+*f z4_MT=WHah11L;l8MIgOb@qC1!Z;Eku^M~MQbmxtwYB%_kX)*gnN489Ppi!CMvo%1 zHu=VlwhZI<)WjS^5|3@`E;JwNo8Q6zw-j8Wjhd=+n9%FI+Wv&rlNHD#2+s!g>* zt_|;66*|}=3>|D`?`>vZNM_}M71x4)`WjzrMeEHT;6LT>eB;;6cY+r{tqH|c!_$0I zO!&^mgdR*&YA#f9)3waZL^}$o5~Ir+>|wZLA!R*8#(QQ@6fQG+mYLaQX72DcPxeu0@Xdh)jQA0FC_<;Fm@Pyw`p<1V8NUEM@2m;w$l9&IjLvke4{*R?Wi z1EyzTVtrW^Be|H` ztnjPOa4p=TQ&+34XsC{awYsJV-r~@>w5}l%#2ZGIRn*`!7x08caD3r8!Qpvl<`o2o zEQ>VNhDR+4*M=LaD!p}`?l(@Mr`)@?uKpjIm{=c*tV z1_Pk>0{ke%kD>T+rk207Zdo{g1w7QTEWZJ66efTu2V%5n5v|_TDVa(bY@9+{lVLE5X9c>+2e| zrTC%jOwia^eOZ|5EyT_y-^6y6U<>@$B1`HbbzpRrmD05H#*ZHv95lPG(Tae)bA}Y2 zzIbtXu$6_KV|TTSgx&OIGciT**?nG^g4S9y#5!&_5B{ubT1Qcw2}2UhGKG|nF!=g)yMk@x(CGa0w@Mt4N`=ZlH#=xTohsDt7++J)m zK$FvAXms>w+lY5pcx?KWuYlnlDaaH2Mdgg7CyL;ETG*!B>a{;}W5n)kCj~J*&UfP( z8h^1W<<)%@i4byzMn5zswiuean@CWU@0!FA7#e(0?XVcJD2s1ARV9=CiP*4iK#B`P z3J;JmCgm~?fD;e7aD1l7NgmJCoH$-EbK;9#_{A=~0eCm)VLrFvduT2t&L@N_-hnm4 zUsvr=Cr3T6*SPTbQL}C8wx)+d+q95ZI=(S;gZ@CzjKW zM9ri$4(1$Gl3!6ONe#QJr7d{>p!-6ZE7g_!?7yc=Q z_Guv7-zJ|z7Z#8QZJd9D9_>VxtRIqUL5_b5ZT8^?=EJByjuYnmMIDcP=0zmWvCVue zao#U5pFkY@0vF~7sr|gKU|ve{K_wlRpGG`a@DEAPAi>K>9>+f}tbac70t?4Do`~Wy z%v!}b`)9b|gGjze@EYP{1+OPQL2$J{1Qrr}CCQfxzKXaSG_Z}^)j}NSBV3rb5ihfF zj9)_>=P6uR{yO3d6^--t#1{+B_AeFuR+6s~{0`#vf^Q-o5j>OlO2PRV*j0j`LGjQc zIM1JLf@TZ91D)_U+?-2Y2;+q8DP5d6gUn736;CqN~ z7W{4E4+*}P_``yKNPMf{`-nd(_@~5o2!4?GQ-Xg*{8_<|5Pw1N?}+afoDYp&6P)MG zJ%amaK7Cv8OyYY5x9&04v=0UEPV)N%&msP);CyBFpx|RuEbx`!9M4AtA4K}U6MQ}& zn$mpFi_i>l7wk}=9_49szqLBY1$(IU#3-OtPcOgDc z@Uw|m2!1lJqKtzX7MgBk_%`^ol`9dMDlY9|zTp{8( z;2VEf|3Re%o>jN$!C2)w770$`+7cVbxZ*3|4K|K?_@u zy-Hfs_)AdMa}vq@Qplf3`Cr*M+8Lz$12&HKTtxZb3(hy8Zn1IHvyAfmtuouQk@zl~ zJnH`$<@t+dmS05u^@fn|N&F+hH_-&sA$UFUBZ5EcgUVs~PVj4qbG)EE*sd#47?w<` zpY1H6$t+9oiNyK7PuA1dQlkZh{92OF6}*}FFu}hh&hPqRdtM?w$|jHY^L~r(?qKiAlbDDk|h(qW)elMQpO+U}I$hX@#wyS`4 zK2HjM2JycN{rtt@-)-`!zW|lP@{x_B{-va+L+~o%pV_!w&tV%!J?$iqkC)@Z{kx7h zTqIHp`I=I7ClhkuKT z`D)^QXdR1N>c4@+S)R{RCfVe%y(6hzd_N5L`!M3?+vE}P{5#LaQP1@x&%dq1dafc~ zX_H5^7Y&1@*2YoK*CgK{_-Djd*f^p#(sLDYZtsaS|KDljl*DSaKM6fi(zC-RkFMnN z-#3K(L8S#ANwjgae;ysc@_mo&hYN`Bx5=aZe4OyLjia7hNdBncHxW;#^EuZ48gaki zyNPGpIM#a&{Nd8i#CPRV075;0uYLYvZWrM$$9M z#?hWXll)}C|496N8%I4ne=Z}=@xbTxzZdfNQ@_6`I3FK;Ecjuvlh3o+4=mr6;*NO@ z$@6(F+e296-wtMu*HUpQAw9^+1jYIMjOB9`h5fducL;Gl4q|(lUn=DJVXG@#_*H@r zL<3;CR&YMv-5~f@lK+_t|E1vStvR6oE*E~k;C#LNcP{)9!TG%6FD{(0+7F`dc)=LM zh5c{kz)ng?9wd%)2~Ew4@cAzD0+MSJ@;v|W{+8u=KL7FW7Q`0<9_I@Nt=A2@zFW}R z{Qs@j3I@TS*eBed>h~l;iR|-*7RmpVt$qJjR`Uxr6E- z&Vsa&c2_acv5<1|pN|ZhMi(T|f2dOWZw4??1rT^gEtPvp_)*GE1zD&1%SI?Q+EzRm zgazxzx@G-%>%Y_qNV}EF@p%$5T%;_{|B|6x2L+l}e1$7zSGkn`{AAP;KQFLy$#voN zA*c3dg{%@h?_m3Je=FO+4w$qFOZLyjPk51;wTgX8**js2WGMU~m0xV%xjD$*2F%I+ zv1ES^DuV^>$3uN-|NX$Qer_iu)slUhwLVh>HrvYUKY^H2`AKJ3<%8BL_Q~aVy&bl2 zIwk~(Dk^Vhn3l4y5))=>OR4-rLIJm*@r#gf@?RPGZy^by|GL8;muJ7CJ+f{rl0yd) weE!!97+#~5<>48Cq`3=_RzMxH7BjX*wjU2)<=ltjTgm?aySqqwK}>Z00OWs4i~s-t literal 0 HcmV?d00001 diff --git a/utshell-0.5.0/lib/termcap/test/main.c b/utshell-0.5.0/lib/termcap/test/main.c new file mode 100644 index 00000000..6381b3a4 --- /dev/null +++ b/utshell-0.5.0/lib/termcap/test/main.c @@ -0,0 +1,4 @@ +#include +void main() { + printf("22\n"); +} diff --git a/utshell-0.5.0/lib/termcap/tparam.c b/utshell-0.5.0/lib/termcap/tparam.c new file mode 100644 index 00000000..1705aa3c --- /dev/null +++ b/utshell-0.5.0/lib/termcap/tparam.c @@ -0,0 +1,345 @@ +/* tparam.c - merge parameters into a termcap entry string. */ + +/* Copyright (C) 1985, 1986, 1993,1994, 1995, 1998, 2001,2003,2005,2006,2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Emacs config.h may rename various library functions such as malloc. */ +#ifdef HAVE_CONFIG_H +#include +#include +#ifdef HAVE_STDLIB_H +# include +#else +extern char *getenv (); +extern char *malloc (); +extern char *realloc (); +#endif + +#if defined (HAVE_STRING_H) +#include +#endif + +#if !defined (HAVE_BCOPY) && (defined (HAVE_STRING_H) || defined (STDC_HEADERS)) +# define bcopy(s, d, n) memcpy ((d), (s), (n)) +#endif + +#else /* not HAVE_CONFIG_H */ + +#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) +#define bcopy(s, d, n) memcpy ((d), (s), (n)) +#endif + +#ifdef STDC_HEADERS +#include +#include +#else +char *malloc (); +char *realloc (); +#endif + +#endif /* not HAVE_CONFIG_H */ + +#include "ltcap.h" + +#ifndef NULL +#define NULL (char *) 0 +#endif + +#ifndef emacs +static void +memory_out () +{ + write (2, "virtual memory exhausted\n", 25); + exit (1); +} + +static char * +xmalloc (size) + unsigned size; +{ + register char *tem = malloc (size); + + if (!tem) + memory_out (); + return tem; +} + +static char * +xrealloc (ptr, size) + char *ptr; + unsigned size; +{ + register char *tem = realloc (ptr, size); + + if (!tem) + memory_out (); + return tem; +} +#endif /* not emacs */ + +/* Assuming STRING is the value of a termcap string entry + containing `%' constructs to expand parameters, + merge in parameter values and store result in block OUTSTRING points to. + LEN is the length of OUTSTRING. If more space is needed, + a block is allocated with `malloc'. + + The value returned is the address of the resulting string. + This may be OUTSTRING or may be the address of a block got with `malloc'. + In the latter case, the caller must free the block. + + The fourth and following args to tparam serve as the parameter values. */ + +static char *tparam1 (); + +/* VARARGS 2 */ +char * +tparam (string, outstring, len, arg0, arg1, arg2, arg3) + char *string; + char *outstring; + int len; + int arg0, arg1, arg2, arg3; +{ + int arg[4]; + + arg[0] = arg0; + arg[1] = arg1; + arg[2] = arg2; + arg[3] = arg3; + return tparam1 (string, outstring, len, NULL, NULL, arg); +} + +__private_extern__ char *BC; +__private_extern__ char *UP; + +static char tgoto_buf[50]; + +__private_extern__ +char * +tgoto (cm, hpos, vpos) + char *cm; + int hpos, vpos; +{ + int args[2]; + if (!cm) + return NULL; + args[0] = vpos; + args[1] = hpos; + return tparam1 (cm, tgoto_buf, 50, UP, BC, args); +} + +static char * +tparam1 (string, outstring, len, up, left, argp) + char *string; + char *outstring; + int len; + char *up, *left; + register int *argp; +{ + register int c; + register char *p = string; + register char *op = outstring; + char *outend; + int outlen = 0; + + register int tem; + int *old_argp = argp; + int doleft = 0; + int doup = 0; + + outend = outstring + len; + + while (1) + { + /* If the buffer might be too short, make it bigger. */ + if (op + 5 >= outend) + { + register char *new; + if (outlen == 0) + { + outlen = len + 40; + new = (char *) xmalloc (outlen); + outend += 40; + bcopy (outstring, new, op - outstring); + } + else + { + outend += outlen; + outlen *= 2; + new = (char *) xrealloc (outstring, outlen); + } + op += new - outstring; + outend += new - outstring; + outstring = new; + } + c = *p++; + if (!c) + break; + if (c == '%') + { + c = *p++; + tem = *argp; + switch (c) + { + case 'd': /* %d means output in decimal. */ + if (tem < 10) + goto onedigit; + if (tem < 100) + goto twodigit; + case '3': /* %3 means output in decimal, 3 digits. */ + if (tem > 999) + { + *op++ = tem / 1000 + '0'; + tem %= 1000; + } + *op++ = tem / 100 + '0'; + case '2': /* %2 means output in decimal, 2 digits. */ + twodigit: + tem %= 100; + *op++ = tem / 10 + '0'; + onedigit: + *op++ = tem % 10 + '0'; + argp++; + break; + + case 'C': + /* For c-100: print quotient of value by 96, if nonzero, + then do like %+. */ + if (tem >= 96) + { + *op++ = tem / 96; + tem %= 96; + } + case '+': /* %+x means add character code of char x. */ + tem += *p++; + case '.': /* %. means output as character. */ + if (left) + { + /* If want to forbid output of 0 and \n and \t, + and this is one of them, increment it. */ + while (tem == 0 || tem == '\n' || tem == '\t') + { + tem++; + if (argp == old_argp) + doup++, outend -= strlen (up); + else + doleft++, outend -= strlen (left); + } + } + *op++ = tem ? tem : 0200; + case 'f': /* %f means discard next arg. */ + argp++; + break; + + case 'b': /* %b means back up one arg (and re-use it). */ + argp--; + break; + + case 'r': /* %r means interchange following two args. */ + argp[0] = argp[1]; + argp[1] = tem; + old_argp++; + break; + + case '>': /* %>xy means if arg is > char code of x, */ + if (argp[0] > *p++) /* then add char code of y to the arg, */ + argp[0] += *p; /* and in any case don't output. */ + p++; /* Leave the arg to be output later. */ + break; + + case 'a': /* %a means arithmetic. */ + /* Next character says what operation. + Add or subtract either a constant or some other arg. */ + /* First following character is + to add or - to subtract + or = to assign. */ + /* Next following char is 'p' and an arg spec + (0100 plus position of that arg relative to this one) + or 'c' and a constant stored in a character. */ + tem = p[2] & 0177; + if (p[1] == 'p') + tem = argp[tem - 0100]; + if (p[0] == '-') + argp[0] -= tem; + else if (p[0] == '+') + argp[0] += tem; + else if (p[0] == '*') + argp[0] *= tem; + else if (p[0] == '/') + argp[0] /= tem; + else + argp[0] = tem; + + p += 3; + break; + + case 'i': /* %i means add one to arg, */ + argp[0] ++; /* and leave it to be output later. */ + argp[1] ++; /* Increment the following arg, too! */ + break; + + case '%': /* %% means output %; no arg. */ + goto ordinary; + + case 'n': /* %n means xor each of next two args with 140. */ + argp[0] ^= 0140; + argp[1] ^= 0140; + break; + + case 'm': /* %m means xor each of next two args with 177. */ + argp[0] ^= 0177; + argp[1] ^= 0177; + break; + + case 'B': /* %B means express arg as BCD char code. */ + argp[0] += 6 * (tem / 10); + break; + + case 'D': /* %D means weird Delta Data transformation. */ + argp[0] -= 2 * (tem % 16); + break; + } + } + else + /* Ordinary character in the argument string. */ + ordinary: + *op++ = c; + } + *op = 0; + while (doup-- > 0) + strcat (op, up); + while (doleft-- > 0) + strcat (op, left); + return outstring; +} + +#ifdef DEBUG + +main (argc, argv) + int argc; + char **argv; +{ + char buf[50]; + int args[3]; + args[0] = atoi (argv[2]); + args[1] = atoi (argv[3]); + args[2] = atoi (argv[4]); + tparam1 (argv[1], buf, "LEFT", "UP", args); + printf ("%s\n", buf); + return 0; +} + +#endif /* DEBUG */ diff --git a/utshell-0.5.0/lib/termcap/version.c b/utshell-0.5.0/lib/termcap/version.c new file mode 100644 index 00000000..cad57be6 --- /dev/null +++ b/utshell-0.5.0/lib/termcap/version.c @@ -0,0 +1,22 @@ +/* version.c - termcap library version information. */ + +/* Copyright (C) 1985-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Make the library identifiable with the RCS ident command. */ +static char *termcap_version_string = "\n$Version: GNU termcap 1.3 $\n"; diff --git a/utshell-0.5.0/lib/test/libtest.a b/utshell-0.5.0/lib/test/libtest.a new file mode 100644 index 0000000000000000000000000000000000000000..8844b67c660f34e3f3a4a8135cc887241c0bf0ce GIT binary patch literal 1692 zcmb_bOK;Oa5FW?SLP$|42vsVF?FCUmm!uRZ2&z1k$02H^wh>&A<0M9@NNQvosc_+j z)B{rf6PNxGq+Yorl^O3&*>0T+;EZg#s~ehIv=1_ufG%zx?wCf0EPl(?7v{Fnf$SNelU;#dXIaZ` z=1Bou{IcL;rYyK{HH*e9^E3GDid~qyQ`uEmKz_<#-+7L2_2kv|F2 zP5;9rFbBOAy8{*E2z>9#QogK{T*g6nQo&(jNnb`ull%ko3s}!$0mX&Acg`$osx z^-p!orV&dj-#^p4sATo8trK#esDBj8@yt^__TEUr2~7y03#NbOIu1LYIJL;(NL%--spEj{gJC1c06Z literal 0 HcmV?d00001 diff --git a/utshell-0.5.0/lib/test/libtest1.a b/utshell-0.5.0/lib/test/libtest1.a new file mode 100644 index 0000000000000000000000000000000000000000..7208cd2c622cf838e46cd43a1982f29c09a9e0a5 GIT binary patch literal 1692 zcmbtTOK;Oa5FW?SLP$|~iAv?Ly&zDjNuWSMQ01XK4pA$$jo^YDCou|;)W}|>!i5_W zNJ#llT>3|ldgYE(X1qJmcI#Z=vvz0Z+j;H7tIvaYFxtxB7pGA&Or@K%5D#V!y*vOo zI9`py@i_8jn8-4uvlq?M&fGDtnd$MyMp~)-NGqb3|I+9*a}K3ca9}Gfz&6XH9BTlT zRIR`g6rkJw_N)El1u@4oO<(^^TU!;>l^DP6tL_4TR=xgA-04P%*z_KHCGW|4d2Kih z?<$jm5!aOf=kqQ&hec;q@aKfcbFzR%fSH z?f5&*=3Zmp->=p>4Ie&yl*z1fx^~*#pA&_Gu1P0x$>4?N$=`S?0ABKGB7;6k87nzr zEe^+lC&NPt-Y}2>c>N>+FOHNkh$fTp0M`y88G5bl?s_7F!FzO|uyEwRiGxX~%l@|z zn1SAkeFGKb2z>6!QogK{T){zSQo&(jSszA8ll%ko3s~0tZIo2setCO(-4^6);vO25 z^Izl37)v=%-5uIo|0e1t?D|h}kvQHb`@YkPU_widXIVp@b<_2`X&Acg`%=f-{ZDnw zrV&djpFh*PsASz=TPNguqWhy*j%S|wv1=m*M>HXXZkYZV`ls!9;_SOa3XXN0eXjQY Qugr<>>81ioX26dB3l6}6eE + +void hello_test() { + printf("hello! test libtest.a\n"); +} diff --git a/utshell-0.5.0/lib/test/test.o b/utshell-0.5.0/lib/test/test.o new file mode 100644 index 0000000000000000000000000000000000000000..803c7890aadd66364b6de3ce98c38cbd22aaff40 GIT binary patch literal 1544 zcmb_bOKTKC5U$zL#K%T9DiVl?@gfFIlaPZkpzMQv9F_!Wj=-DvCt&w5E3Y^yD`psd%g9#alDp&|~H?fCu>0?p3~(8cPeioPc-^aF!eN>#}ItFFYxc z&%Yx0T&V~?-7KQH%HkZpc*j01T+2u1eQTfD*_nf_T+1d}o5NGqh5=>G2@z1(?(WrV z-EgnfI%pn-hqZdQ8PccEI^`O&bF>|&`+b?C%szmdxXVNMfPDb@)>9!;>6eL)`fT+y zwMnZ(CDcbw>0wRd~#sg4F8IRUbG6n>aSlQ>)S zKYRkNfw$szpvoK|_nt?2uK2L4Ja8vf9yV6YWo#Jo4qL1vFJQ&+PYv(ByaO}u8q~1y zf&_vlQ_t+c^4;9GM(^%_ zW;END7OvdC(EIEZ^{- + +void hello_test1() { + printf("hello! test libtest1.a\n"); +} diff --git a/utshell-0.5.0/lib/test/test1.o b/utshell-0.5.0/lib/test/test1.o new file mode 100644 index 0000000000000000000000000000000000000000..e8466fb5f9656af5d40b76132a9bbe629848599b GIT binary patch literal 1544 zcmbtT-Afxm5TDEWQEQa6wJ6w!^QBZYi=huyp(P*W;~^-hp-*yNl9gx^ujE!xU;0+4 zP{{w(7yl8#*S-sOCby&OdU>&P?9R+@=QlgMv-hK1ucRCYSRD8Q4<4fcSE&a(KQ!|& z18Hc~eqGmoe6{1vs-@DV_n{F+-n#fG*2Jf5Zl&Fp z%dtyjl(|@ebFl-?S;kpRPrevnLGKW!LGp&C!ffVesx&jPg#qM`5IV~k{Jl$Bb`wtu z;Nq7gE@ny+7siud%rZFwPp;U7i6`+>h`cuH9G)Gqw>UCSq5)P$;1IW=1;g(6Ll69F zeY;qw``eYuZh6n&D-`QxAHJWe=)Q7lJDu+KE|#?3lWt<#z&(vqyzx{3M0DO$K@+v= z$GXE-Uv>kbR(MK3a=GpgZ Rpa0be{(&wkpk#*F{C{pUXg>e| literal 0 HcmV?d00001 diff --git a/utshell-0.5.0/lib/tilde/Makefile b/utshell-0.5.0/lib/tilde/Makefile new file mode 100644 index 00000000..49e31563 --- /dev/null +++ b/utshell-0.5.0/lib/tilde/Makefile @@ -0,0 +1,124 @@ +## -*- text -*- #################################################### +# # +# Makefile for the GNU Tilde Library. # +# # +#################################################################### + +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = . + +topdir = ../.. +BUILD_DIR = /root/gerrit/utshell/utshell-0.5 + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CC = gcc +RANLIB = ranlib +AR = ar +ARFLAGS = cr +RM = rm +CP = cp +MV = mv + +SHELL = /bin/sh + +PROFILE_FLAGS = + +CFLAGS = -g -O2 -Wno-parentheses -Wno-format-security -fPIC +LOCAL_CFLAGS = +CPPFLAGS = +LDFLAGS = -L./lib/termcap -rdynamic + +DEFS = -DHAVE_CONFIG_H +LOCAL_DEFS = -DSHELL + +BASHINCDIR = ../include + +INCLUDES = -I. -I$(topdir) -I${BASHINCDIR} -I$(topdir)/lib + +CCFLAGS = ${ASAN_CFLAGS} $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) \ + ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS) + +.c.o: + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libtilde.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/tilde.c + +# The header files for this library. +HSOURCES = $(srcdir)/tilde.h + +OBJECTS = tilde.o + +# The texinfo files which document this library. +DOCSOURCE = doc/tilde.texi +DOCOBJECT = doc/tilde.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +###################################################################### + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +documentation: force + -(cd doc; $(MAKE) $(MFLAGS)) + +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + $(INSTALL_DATA) -c -m 644 $(LIBRARY_NAME) $(libdir)/$(LIBRARY_NAME) + -test -n "$(RANLIB)" && $(RANLIB) -t $(libdir)/$(LIBRARY_NAME) + +clean: + $(RM) -f $(OBJECTS) $(LIBRARY_NAME) + +realclean distclean maintainer-clean: clean + $(RM) -f Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +###################################################################### +# # +# Dependencies for the object files which make up this library. # +# # +###################################################################### + +tilde.o: tilde.h $(BASHINCDIR)/ansi_stdlib.h +#tilde.o: $(BUILD_DIR)/config.h + +# Rules for deficient makes, like SunOS and Solaris +tilde.o: tilde.c diff --git a/utshell-0.5.0/lib/tilde/Makefile.in b/utshell-0.5.0/lib/tilde/Makefile.in new file mode 100644 index 00000000..939e3f6d --- /dev/null +++ b/utshell-0.5.0/lib/tilde/Makefile.in @@ -0,0 +1,124 @@ +## -*- text -*- #################################################### +# # +# Makefile for the GNU Tilde Library. # +# # +#################################################################### + +# Copyright (C) 1996-2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +srcdir = @srcdir@ +VPATH = @srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm +CP = cp +MV = mv + +SHELL = @MAKE_SHELL@ + +PROFILE_FLAGS = @PROFILE_FLAGS@ + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +BASHINCDIR = ${topdir}/include + +INCLUDES = -I. -I../.. -I$(topdir) -I${BASHINCDIR} -I$(topdir)/lib + +CCFLAGS = ${ASAN_CFLAGS} $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) \ + ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS) + +.c.o: + $(CC) -c $(CCFLAGS) $< + +# The name of the library target. +LIBRARY_NAME = libtilde.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/tilde.c + +# The header files for this library. +HSOURCES = $(srcdir)/tilde.h + +OBJECTS = tilde.o + +# The texinfo files which document this library. +DOCSOURCE = doc/tilde.texi +DOCOBJECT = doc/tilde.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +SUPPORT = Makefile ChangeLog $(DOCSUPPORT) + +SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE) + +THINGS_TO_TAR = $(SOURCES) $(SUPPORT) + +###################################################################### + +all: $(LIBRARY_NAME) + +$(LIBRARY_NAME): $(OBJECTS) + $(RM) -f $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +documentation: force + -(cd doc; $(MAKE) $(MFLAGS)) + +force: + +# The rule for 'includes' is written funny so that the if statement +# always returns TRUE unless there really was an error installing the +# include files. +install: + $(INSTALL_DATA) -c -m 644 $(LIBRARY_NAME) $(libdir)/$(LIBRARY_NAME) + -test -n "$(RANLIB)" && $(RANLIB) -t $(libdir)/$(LIBRARY_NAME) + +clean: + $(RM) -f $(OBJECTS) $(LIBRARY_NAME) + +realclean distclean maintainer-clean: clean + $(RM) -f Makefile + +mostlyclean: clean + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +###################################################################### +# # +# Dependencies for the object files which make up this library. # +# # +###################################################################### + +tilde.o: tilde.h $(BASHINCDIR)/ansi_stdlib.h +tilde.o: $(BUILD_DIR)/config.h + +# Rules for deficient makes, like SunOS and Solaris +tilde.o: tilde.c diff --git a/utshell-0.5.0/lib/tilde/README b/utshell-0.5.0/lib/tilde/README new file mode 100644 index 00000000..a8772f35 --- /dev/null +++ b/utshell-0.5.0/lib/tilde/README @@ -0,0 +1,5 @@ +If you're building this separately from bash or the readline library, add +$(srcdir)/shell.c to the CSOURCES variable and shell.o to the OBJECTS +variable in Makefile.in. (Not that this is very useful without readline +or bash.) + diff --git a/utshell-0.5.0/lib/tilde/shell.c b/utshell-0.5.0/lib/tilde/shell.c new file mode 100644 index 00000000..9805a924 --- /dev/null +++ b/utshell-0.5.0/lib/tilde/shell.c @@ -0,0 +1,79 @@ +/* shell.c -- tilde utility functions that are normally provided by + bash when readline is linked as part of the shell. */ + +/* Copyright (C) 1998-2017 Free Software Foundation, Inc. + + This file is part of the GNU Tilde Library. + + The GNU Tilde Library is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + The GNU Tilde Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Tilde Library. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#include + +#if !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid (); +#endif /* !HAVE_GETPW_DECLS */ + +char * +get_env_value (char *varname) +{ + return ((char *)getenv (varname)); +} + +/* If we're not using $HOME, assume that the passwd file information won't + change while this shell instance is running. */ +char * +get_home_dir (void) +{ + static char *home_dir = (char *)NULL; + struct passwd *entry; + + if (home_dir) + return (home_dir); + +#if defined (HAVE_GETPWUID) + entry = getpwuid (getuid ()); + if (entry) + home_dir = savestring (entry->pw_dir); +#endif + +#if defined (HAVE_GETPWENT) + endpwent (); /* some systems need this */ +#endif + + return (home_dir); +} diff --git a/utshell-0.5.0/lib/tilde/tilde.c b/utshell-0.5.0/lib/tilde/tilde.c new file mode 100644 index 00000000..d678a31a --- /dev/null +++ b/utshell-0.5.0/lib/tilde/tilde.c @@ -0,0 +1,493 @@ +/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ + +/* Copyright (C) 1988-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#if defined (HAVE_PWD_H) +#include +#endif + +#include "tilde.h" + +#if defined (TEST) || defined (STATIC_MALLOC) +static void *xmalloc (), *xrealloc (); +#else +# include "xmalloc.h" +#endif /* TEST || STATIC_MALLOC */ + +#if !defined (HAVE_GETPW_DECLS) +# if defined (HAVE_GETPWUID) +extern struct passwd *getpwuid (uid_t); +# endif +# if defined (HAVE_GETPWNAM) +extern struct passwd *getpwnam (const char *); +# endif +#endif /* !HAVE_GETPW_DECLS */ + +#if !defined (savestring) +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif /* !savestring */ + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* If being compiled as part of bash, these will be satisfied from + variables.o. If being compiled as part of readline, they will + be satisfied from shell.o. */ +extern char *sh_get_home_dir (void); +extern char *sh_get_env_value (const char *); + +/* The default value of tilde_additional_prefixes. This is set to + whitespace preceding a tilde so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_prefixes[] = + { " ~", "\t~", (const char *)NULL }; + +/* The default value of tilde_additional_suffixes. This is set to + whitespace or newline so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_suffixes[] = + { " ", "\n", (const char *)NULL }; + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +char **tilde_additional_prefixes = (char **)default_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +char **tilde_additional_suffixes = (char **)default_suffixes; + +static int tilde_find_prefix (const char *, int *); +static int tilde_find_suffix (const char *); +static char *isolate_tilde_prefix (const char *, int *); +static char *glue_prefix_and_suffix (char *, const char *, int); + +/* Find the start of a tilde expansion in STRING, and return the index of + the tilde which starts the expansion. Place the length of the text + which identified this tilde starter in LEN, excluding the tilde itself. */ +static int +tilde_find_prefix (const char *string, int *len) +{ + register int i, j, string_len; + register char **prefixes; + + prefixes = tilde_additional_prefixes; + + string_len = strlen (string); + *len = 0; + + if (*string == '\0' || *string == '~') + return (0); + + if (prefixes) + { + for (i = 0; i < string_len; i++) + { + for (j = 0; prefixes[j]; j++) + { + if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) + { + *len = strlen (prefixes[j]) - 1; + return (i + *len); + } + } + } + } + return (string_len); +} + +/* Find the end of a tilde expansion in STRING, and return the index of + the character which ends the tilde definition. */ +static int +tilde_find_suffix (const char *string) +{ + register int i, j, string_len; + register char **suffixes; + + suffixes = tilde_additional_suffixes; + string_len = strlen (string); + + for (i = 0; i < string_len; i++) + { +#if defined (__MSDOS__) + if (string[i] == '/' || string[i] == '\\' /* || !string[i] */) +#else + if (string[i] == '/' /* || !string[i] */) +#endif + break; + + for (j = 0; suffixes && suffixes[j]; j++) + { + if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) + return (i); + } + } + return (i); +} + +/* Return a new string which is the result of tilde expanding STRING. */ +char * +tilde_expand (const char *string) +{ + char *result; + int result_size, result_index; + + result_index = result_size = 0; + if (result = strchr (string, '~')) + result = (char *)xmalloc (result_size = (strlen (string) + 16)); + else + result = (char *)xmalloc (result_size = (strlen (string) + 1)); + + /* Scan through STRING expanding tildes as we come to them. */ + while (1) + { + register int start, end; + char *tilde_word, *expansion; + int len; + + /* Make START point to the tilde which starts the expansion. */ + start = tilde_find_prefix (string, &len); + + /* Copy the skipped text into the result. */ + if ((result_index + start + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + + strncpy (result + result_index, string, start); + result_index += start; + + /* Advance STRING to the starting tilde. */ + string += start; + + /* Make END be the index of one after the last character of the + username. */ + end = tilde_find_suffix (string); + + /* If both START and END are zero, we are all done. */ + if (!start && !end) + break; + + /* Expand the entire tilde word, and copy it into RESULT. */ + tilde_word = (char *)xmalloc (1 + end); + strncpy (tilde_word, string, end); + tilde_word[end] = '\0'; + string += end; + + expansion = tilde_expand_word (tilde_word); + + if (expansion == 0) + expansion = tilde_word; + else + xfree (tilde_word); + + len = strlen (expansion); +#ifdef __CYGWIN__ + /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when + $HOME for `user' is /. On cygwin, // denotes a network drive. */ + if (len > 1 || *expansion != '/' || *string != '/') +#endif + { + if ((result_index + len + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + + strcpy (result + result_index, expansion); + result_index += len; + } + xfree (expansion); + } + + result[result_index] = '\0'; + + return (result); +} + +/* Take FNAME and return the tilde prefix we want expanded. If LENP is + non-null, the index of the end of the prefix into FNAME is returned in + the location it points to. */ +static char * +isolate_tilde_prefix (const char *fname, int *lenp) +{ + char *ret; + int i; + + ret = (char *)xmalloc (strlen (fname)); +#if defined (__MSDOS__) + for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++) +#else + for (i = 1; fname[i] && fname[i] != '/'; i++) +#endif + ret[i - 1] = fname[i]; + ret[i - 1] = '\0'; + if (lenp) + *lenp = i; + return ret; +} + +#if 0 +/* Public function to scan a string (FNAME) beginning with a tilde and find + the portion of the string that should be passed to the tilde expansion + function. Right now, it just calls tilde_find_suffix and allocates new + memory, but it can be expanded to do different things later. */ +char * +tilde_find_word (const char *fname, int flags, int *lenp) +{ + int x; + char *r; + + x = tilde_find_suffix (fname); + if (x == 0) + { + r = savestring (fname); + if (lenp) + *lenp = 0; + } + else + { + r = (char *)xmalloc (1 + x); + strncpy (r, fname, x); + r[x] = '\0'; + if (lenp) + *lenp = x; + } + + return r; +} +#endif + +/* Return a string that is PREFIX concatenated with SUFFIX starting at + SUFFIND. */ +static char * +glue_prefix_and_suffix (char *prefix, const char *suffix, int suffind) +{ + char *ret; + int plen, slen; + + plen = (prefix && *prefix) ? strlen (prefix) : 0; + slen = strlen (suffix + suffind); + ret = (char *)xmalloc (plen + slen + 1); + if (plen) + strcpy (ret, prefix); + strcpy (ret + plen, suffix + suffind); + return ret; +} + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. + This always returns a newly-allocated string, never static storage. */ +char * +tilde_expand_word (const char *filename) +{ + char *dirname, *expansion, *username; + int user_len; + struct passwd *user_entry; + + if (filename == 0) + return ((char *)NULL); + + if (*filename != '~') + return (savestring (filename)); + + /* A leading `~/' or a bare `~' is *always* translated to the value of + $HOME or the home directory of the current user, regardless of any + preexpansion hook. */ + if (filename[1] == '\0' || filename[1] == '/') + { + /* Prefix $HOME to the rest of the string. */ + expansion = sh_get_env_value ("HOME"); +#if defined (_WIN32) + if (expansion == 0) + expansion = sh_get_env_value ("APPDATA"); +#endif + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (expansion == 0) + expansion = sh_get_home_dir (); + + return (glue_prefix_and_suffix (expansion, filename, 1)); + } + + username = isolate_tilde_prefix (filename, &user_len); + + if (tilde_expansion_preexpansion_hook) + { + expansion = (*tilde_expansion_preexpansion_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + xfree (username); + xfree (expansion); + return (dirname); + } + } + + /* No preexpansion hook, or the preexpansion hook failed. Look in the + password database. */ + dirname = (char *)NULL; +#if defined (HAVE_GETPWNAM) + user_entry = getpwnam (username); +#else + user_entry = 0; +#endif + if (user_entry == 0) + { + /* If the calling program has a special syntax for expanding tildes, + and we couldn't find a standard expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + expansion = (*tilde_expansion_failure_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + xfree (expansion); + } + } + /* If we don't have a failure hook, or if the failure hook did not + expand the tilde, return a copy of what we were passed. */ + if (dirname == 0) + dirname = savestring (filename); + } +#if defined (HAVE_GETPWENT) + else + dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); +#endif + + xfree (username); +#if defined (HAVE_GETPWENT) + endpwent (); +#endif + return (dirname); +} + + +#if defined (TEST) +#undef NULL +#include + +main (int argc, char **argv) +{ + char *result, line[512]; + int done = 0; + + while (!done) + { + printf ("~expand: "); + fflush (stdout); + + if (!gets (line)) + strcpy (line, "done"); + + if ((strcmp (line, "done") == 0) || + (strcmp (line, "quit") == 0) || + (strcmp (line, "exit") == 0)) + { + done = 1; + break; + } + + result = tilde_expand (line); + printf (" --> %s\n", result); + free (result); + } + exit (0); +} + +static void memory_error_and_abort (void); + +static void * +xmalloc (size_t bytes) +{ + void *temp = (char *)malloc (bytes); + + if (!temp) + memory_error_and_abort (); + return (temp); +} + +static void * +xrealloc (void *pointer, int bytes) +{ + void *temp; + + if (!pointer) + temp = malloc (bytes); + else + temp = realloc (pointer, bytes); + + if (!temp) + memory_error_and_abort (); + + return (temp); +} + +static void +memory_error_and_abort (void) +{ + fprintf (stderr, "readline: out of virtual memory\n"); + abort (); +} + +/* + * Local variables: + * compile-command: "gcc -g -DTEST -o tilde tilde.c" + * end: + */ +#endif /* TEST */ diff --git a/utshell-0.5.0/lib/tilde/tilde.h b/utshell-0.5.0/lib/tilde/tilde.h new file mode 100644 index 00000000..e26dd047 --- /dev/null +++ b/utshell-0.5.0/lib/tilde/tilde.h @@ -0,0 +1,80 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992-2009 Free Software Foundation, Inc. + + This file contains the Readline Library (Readline), a set of + routines for providing Emacs style line input to programs that ask + for it. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +/* Find the portion of the string beginning with ~ that should be expanded. */ +extern char *tilde_find_word PARAMS((const char *, int, int *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/utshell-0.5.0/resources/en-US/message.ftl b/utshell-0.5.0/resources/en-US/message.ftl new file mode 100644 index 00000000..26c2a3c3 --- /dev/null +++ b/utshell-0.5.0/resources/en-US/message.ftl @@ -0,0 +1,1806 @@ +helplongdoc ={ +$cmdName -> +[command0] + Resume job in foreground. + + Equivalent to the JOB_SPEC argument to the 'fg' command. Resume a + stopped or background job. JOB_SPEC can specify either a job name + or a job number. Following JOB_SPEC with a '&' places the job in + the background, as if the job specification had been supplied as an + argument to 'bg'. + + Exit Status: + Returns the status of the resumed job. + +[command1] + Evaluate conditional expression. + + This is a synonym for the test builtin, but the last argument must + be a literal ']', to match the opening '['. +[command2] + Execute commands from a file in the current shell. + + Read and execute commands from FILENAME in the current shell. The + entries in $PATH are used to find the directory containing FILENAME. + If any ARGUMENTS are supplied, they become the positional parameters + when FILENAME is executed. + + Exit Status: + Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is + not a shell builtin. + +[command3] + Null command. + + No effect; the command does nothing. + + Exit Status: + Always succeeds. + +[command4] + Evaluate conditional expression. + + This is a synonym for the test builtin, but the last argument must + be a literal ']', to match the opening '['. + +[command5] + Execute conditional command. + + Returns a status of 0 or 1 depending on the evaluation of the + conditional + expression EXPRESSION. Expressions are composed of the same primaries + used + by the 'test' builtin, and may be combined using the following + operators: + + ( EXPRESSION ) Returns the value of EXPRESSION + ! EXPRESSION True if EXPRESSION is false; else false + EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false + EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false + + When the '==' and '!=' operators are used, the string to the right of + the operator is used as a pattern and pattern matching is performed. + When the '=~' operator is used, the string to the right of the operator + is matched as a regular expression. + + The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to + +[command6] + Arithmetic for loop. + + Equivalent to + (( EXP1 )) + while (( EXP2 )); do + COMMANDS + (( EXP3 )) + done + EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is + omitted, it behaves as if it evaluates to 1. + + Exit Status: + Returns the status of the last command executed. + +[command7] + Group commands as a unit. + + Run a set of commands in a group. This is one way to redirect an + entire set of commands. + + Exit Status: + Returns the status of the last command executed. + +[set] + Set or unset values of shell options and positional parameters. + + Change the value of shell attributes and positional parameters, or + display tmes and values of shell variables. + + Options: + -a Mark variables which are modified or created for export. + -b Notify of job termination immediately. + -e Exit immediately if a command exits with a non-zero status. + -f Disable file name generation (globbing). + -h Remember the location of commands as they are looked up. + -k All assignment arguments are placed in the environment for a + command, not just those that precede the command name. + -m Job control is enabled. + -n Read commands but do not execute them. + -o option-name + Set the variable corresponding to option-name: + allexport same as -a + braceexpand same as -B + emacs use an emacs-style line editing interface + errexit same as -e + errtrace same as -E + functrace same as -T + hashall same as -h + histexpand same as -H + history enable command history + ignoreeof the shell will not exit upon reading EOF + interactive-comments + allow comments to appear in interactive commands + keyword same as -k + monitor same as -m + noclobber same as -C + noexec same as -n + noglob same as -f + nolog currently accepted but ignored + notify same as -b + nounset same as -u + onecmd same as -t + physical same as -P + pipefail the return value of a pipeline is the status of + the last command to exit with a non-zero status, + or zero if no command exited with a non-zero status + posix change the behavior of bash where the default + operation differs from the Posix standard to + match the standard + privileged same as -p + verbose same as -v + vi use a vi-style line editing interface + xtrace same as -x + -p Turned on whenever the real and effective user ids do not match. + Disables processing of the $ENV file and importing of shell + functions. Turning this option off causes the effective uid and + gid to be set to the real uid and gid. + -t Exit after reading and executing one command. + -u Treat unset variables as an error when substituting. + -v Print shell input lines as they are read. + -x Print commands and their arguments as they are executed. + -B the shell will perform brace expansion + -C If set, disallow existing regular files to be overwritten + by redirection of output. + -E If set, the ERR trap is inherited by shell functions. + -H Enable ! style history substitution. This flag is on + by default when the shell is interactive. + -P If set, do not resolve symbolic links when executing commands + such as cd which change the current directory. + -T If set, the DEBUG and RETURN traps are inherited by shell functions. + -- Assign any remaining arguments to the positional parameters. + If there are no remaining arguments, the positional parameters + are unset. + - Assign any remaining arguments to the positional parameters. + The -x and -v options are turned off. + + Using + rather than - causes these flags to be turned off. + The flags can also be used upon invocation of the shell. + The current set of flags may be found in $-. + The remaining n ARGs are positional + parameters and are assigned, in order, to $1, $2, .. $n. If no + ARGs are given, all shell variables are printed. + + Exit Status: + Returns success unless an invalid option is given. +[read] + Read a line from the standard input and split it into fields. + + Reads a single line from the standard input, or from file descriptor FD + if the -u option is supplied. The line is split into fields as with + word splitting, and the first word is assigned to the first NAME, the + second word to the second NAME, and so on, with any leftover words + assigned to the last NAME. Only the characters found in $IFS are recognized + as word delimiters. + + If no NAMEs are supplied, the line read is stored in the REPLY + variable. + + Options: + -a array assign the words read to sequential indices of the array + variable ARRAY, starting at zero + -d delim continue until the first character of DELIM is read, rather + than newline + -e use Readline to obtain the line + -i text use TEXT as the initial text for Readline + -n nchars return after reading NCHARS characters rather than waiting + for a newline, but honor a delimiter if fewer than + NCHARS characters are read before the delimiter + -N nchars return only after reading exactly NCHARS characters, + unless + EOF is encountered or read times out, ignoring any + delimiter + -p prompt output the string PROMPT without a trailing newline before + attempting to read + -r do not allow backslashes to escape any characters + -s do not echo input coming from a terminal + -t timeout time out and return failure if a complete line of + input is not read within TIMEOUT seconds. The value of the + TMOUT variable is the default timeout. TIMEOUT may be a + fractional number. If TIMEOUT is 0, read returns + immediately, without trying to read any data, returning + success only if input is available on the specified + file descriptor. The exit status is greater than 128 + if the timeout is exceeded + -u fd read from file descriptor FD instead of the standard input + + Exit Status: + The return code is zero, unless end-of-file is encountered, read times + out (in which case it's greater than 128), a variable assignment error + occurs, or an invalid file descriptor is supplied as the argument to -u. + +[type] + Display information about command type. + + For each NAME, indicate how it would be interpreted if used as a + command name. + + Options: + -a display all locations containing an executable named NAME; + includes aliases, builtins, and functions, if and only if + the '-p' option is not also used + -f suppress shell function lookup + -P force a PATH search for each NAME, even if it is an alias, + builtin, or function, and returns the name of the disk file + that would be executed + -p returns either the name of the disk file that would be executed, + or nothing if 'type -t NAME' would not return 'file' + -t output a single word which is one of 'alias', 'keyword', + 'function', 'builtin', 'file' or '', if NAME is an alias, + shell reserved word, shell function, shell builtin, disk file, + or not found, respectively + + Arguments: + NAME Command name to be interpreted. + + Exit Status: + Returns success if all of the NAMEs are found; fails if any are not + found. + +[trap] + Trap signals and other events. + + Defines and activates handlers to be run when the shell receives + signals or other conditions. + + ARG is a command to be read and executed when the shell receives the + signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC + is supplied) or '-', each specified signal is reset to its original + value. If ARG is the null string each SIGNAL_SPEC is ignored by the + shell and by the commands it invokes. + + If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. + If a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. + If a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or + a script run by the . or source builtins finishes executing. A + SIGNAL_SPEC of ERR means to execute ARG each time a command's failure + would cause the shell to exit when the -e option is enabled. + + If no arguments are supplied, trap prints the list of commands + associated with each signal. + + Options: + -l print a list of signal names and their corresponding numbers + -p display the trap commands associated with each SIGNAL_SPEC + + Each SIGNAL_SPEC is either a signal name in or a signal + number. + Signal names are case insensitive and the SIG prefix is optional. A + signal may be sent to the shell with \kill -signal $$\. + + Exit Status: + Returns success unless a SIGSPEC is invalid or an invalid option is + given. + +[alias] + Define or display aliases. + + Without arguments, 'alias' prints the list of aliases in the reusable + form 'alias NAME=VALUE' on standard output. + + Otherwise, an alias is defined for each NAME whose VALUE is given. + A trailing space in VALUE causes the next word to be checked for + alias substitution when the alias is expanded. + + Options: + -p print all defined aliases in a reusable format + + Exit Status: + alias returns true unless a NAME is supplied for which no alias has + been defined. + +[unalias] + Remove each NAME from the list of defined aliases. + + Options: + -a remove all alias definitions + + Return success unless a NAME is not an existing alias. + +[break] + Exit for, while, or until loops. + + Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing + loops. + + Exit Status: + The exit status is 0 unless N is not greater than or equal to 1. + +[continue] + Resume for, while, or until loops. + + Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop. + If N is specified, resumes the Nth enclosing loop. + + Exit Status: + The exit status is 0 unless N is not greater than or equal to 1. + +[builtin] + Execute shell builtins. + + Execute SHELL-BUILTIN with arguments ARGs without performing command + lookup. This is useful when you wish to reimplement a shell builtin + as a shell function, but need to execute the builtin within the + function. + + Exit Status: + Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is + not a shell builtin. + +[caller] + Returns the context of the current subroutine call. + + Without EXPR, returns \$line $filename\. With EXPR, returns + \$line $subroutine $filename\; this extra information can be used to + provide a stack trace. + + The value of EXPR indicates how many call frames to go back before the + current one; the top frame is frame 0. + +[cd] + Change the shell working directory. + + Change the current directory to DIR. The default DIR is the value of + the HOME shell variable. + + The variable CDPATH defines the search path for the directory + containing DIR. Alternative directory names in CDPATH are + separated by a colon (:). + A null directory name is the same as the current directory. If DIR + begins with a slash (/), then CDPATH is not used. + + If the directory is not found, and the shell option 'cdable_vars' is + set,the word is assumed to be a variable name. If that variable has a + value,its value is used for DIR. + + Options: + -L force symbolic links to be followed: resolve symbolic + links in DIR after processing instances of '..' + -P use the physical directory structure without following + symbolic links: resolve symbolic links in DIR before + processing instances of '..' + -e if the -P option is supplied, and the current working + directory cannot be determined successfully, exit with + a non-zero status + -@ on systems that support it, present a file with extended + attributes as a directory containing the file attributes + + The default is to follow symbolic links, as if '-L' were specified. + '..' is processed by removing the immediately previous pathname + component back to a slash or the beginning of DIR. + + Exit Status: + Returns 0 if the directory is changed, and if $PWD is set successfully + when -P is used; non-zero otherwise. + +[pwd] + Print the name of the current working directory. + + Options: + -L print the value of $PWD if it names the current working + directory + -P print the physical directory, without any symbolic links + + By default, 'pwd' behaves as if '-L' were specified. + + Exit Status: + Returns 0 unless an invalid option is given or the current directory + cannot be read. + +[true] + Null command. + + No effect; the command does nothing. + + Exit Status: + Always succeeds. + +[shopt] + Set and unset shell options. + + Change the setting of each shell option OPTNAME. Without any option + arguments, list each supplied OPTNAME, or all shell options if no + OPTNAMEs are given, with an indication of whether or not each is set. + + Options: + -o restrict OPTNAMEs to those defined for use with 'set -o' + -p print each shell option with an indication of its status + -q suppress output + -s enable (set) each OPTNAME + -u disable (unset) each OPTNAME + + Exit Status: + Returns success if OPTNAME is enabled; fails if an invalid option is + given or OPTNAME is disabled. + +[false] + Return an unsuccessful result. + + Exit Status: + Always fails. + +[command] + Execute a simple command or display information about commands. + + Runs COMMAND with ARGS suppressing shell function lookup, or display + information about the specified COMMANDs. Can be used to invoke + commands on disk when a function with the same name exists. + + Options: + -p use a default value for PATH that is guaranteed to find all of + the standard utilities + -v print a description of COMMAND similar to the 'type' builtin + -V print a more verbose description of each COMMAND + + Exit Status: + Returns exit status of COMMAND, or failure if COMMAND is not found. + +[echo] + Write arguments to the standard output. + + Display the ARGs, separated by a single space character and followed by + a newline, on the standard output. + + Options: + -n do not append a newline + -e enable interpretation of the following backslash escapes + -E explicitly suppress interpretation of backslash escapes + + 'echo' interprets the following backslash-escaped characters: + \\a alert (bell) + \\b backspace + \\c suppress further output + \\e escape character + \\E escape character + \\f form feed + \ new line + \\r carriage return + \ horizontal tab + \\v vertical tab + \\\\ backslash + \\0nnn the character whose ASCII code is NNN (octal). NNN can be + 0 to 3 octal digits + \\xHH the eight-bit character whose value is HH (hexadecimal). HH + can be one or two hex digits + \\uHHHH the Unicode character whose value is the hexadecimal value + HHHH. + HHHH can be one to four hex digits. + \\UHHHHHHHH the Unicode character whose value is the hexadecimal + value + HHHHHHHH. HHHHHHHH can be one to eight hex digits. + + Exit Status: + Returns success unless a write error occurs. + +[enable] + Enable and disable shell builtins. + + Enables and disables builtin shell commands. Disabling allows you to + execute a disk command which has the same name as a shell builtin + without using a full pathname. + + Options: + -a print a list of builtins showing whether or not each is enabled + -n disable each NAME or display a list of disabled builtins + -p print the list of builtins in a reusable format + -s print only the names of Posix 'special' builtins + + Options controlling dynamic loading: + -f Load builtin NAME from shared object FILENAME + -d Remove a builtin loaded with -f + + Without options, each NAME is enabled. + + To use the 'test' found in $PATH instead of the shell builtin + version, type 'enable -n test'. + + Exit Status: + Returns success unless NAME is not a shell builtin or an error occurs. + +[getopts] + Parse option arguments. + + Getopts is used by shell procedures to parse positional parameters + as options. + + OPTSTRING contains the option letters to be recognized; if a letter + is followed by a colon, the option is expected to have an argument, + which should be separated from it by white space. + + Each time it is invoked, getopts will place the next option in the + shell variable $name, initializing name if it does not exist, and + the index of the next argument to be processed into the shell + variable OPTIND. OPTIND is initialized to 1 each time the shell or + a shell script is invoked. When an option requires an argument, + getopts places that argument into the shell variable OPTARG. + + getopts reports errors in one of two ways. If the first character + of OPTSTRING is a colon, getopts uses silent error reporting. In + this mode, no error messages are printed. If an invalid option is + seen, getopts places the option character found into OPTARG. If a + required argument is not found, getopts places a ':' into NAME and + sets OPTARG to the option character found. If getopts is not in + silent mode, and an invalid option is seen, getopts places '?' into + NAME and unsets OPTARG. If a required argument is not found, a '?' + is placed in NAME, OPTARG is unset, and a diagnostic message is + printed. + + If the shell variable OPTERR has the value 0, getopts disables the + printing of error messages, even if the first character of + OPTSTRING is not a colon. OPTERR has the value 1 by default. + + Getopts normally parses the positional parameters, but if arguments + are supplied as ARG values, they are parsed instead. + + Exit Status: + Returns success if an option is found; fails if the end of options is + encountered or an error occurs. + +[exec] + Replace the shell with the given command. + + Execute COMMAND, replacing this shell with the specified program. + ARGUMENTS become the arguments to COMMAND. If COMMAND is not + specified, + any redirections take effect in the current shell. + + Options: + -a name pass NAME as the zeroth argument to COMMAND + -c execute COMMAND with an empty environment + -l place a dash in the zeroth argument to COMMAND + + If the command cannot be executed, a non-interactive shell exits, + unless + the shell option 'execfail' is set. + + Exit Status: + Returns success unless COMMAND is not found or a redirection error + occurs. + +[exit] + Exit the shell. + + Exits the shell with a status of N. If N is omitted, the exit status + is that of the last command executed. + +[logout] + Exit a login shell. + + Exits a login shell with exit status N. Returns an error if not + executed in a login shell. + +[fc] + Display or execute commands from the history list. + + fc is used to list or edit and re-execute commands from the history + list. + FIRST and LAST can be numbers specifying the range, or FIRST can be a + string, which means the most recent command beginning with that + string. + + Options: + -e ENAME select which editor to use. Default is FCEDIT, then + EDITOR, + then vi + -l list lines instead of editing + -n omit line numbers when listing + -r reverse the order of the lines (newest listed first) + + With the 'fc -s [pat=rep ...] [command]' format, COMMAND is + re-executed after the substitution OLD=NEW is performed. + + A useful alias to use with this is r='fc -s', so that typing 'r cc' + runs the last command beginning with 'cc' and typing 'r' re-executes + the last command. + + Exit Status: + Returns success or status of executed command; non-zero if an error + occurs. + +[fg] + Resume job in foreground. + + Equivalent to the JOB_SPEC argument to the 'fg' command. Resume a + stopped or background job. JOB_SPEC can specify either a job name + or a job number. Following JOB_SPEC with a '&' places the job in + the background, as if the job specification had been supplied as an + argument to 'bg'. + + Exit Status: + Returns the status of the resumed job. + +[bg] + Move jobs to the background. + + Place the jobs identified by each JOB_SPEC in the background, as if + they had been started with '&'. If JOB_SPEC is not present, the shell's + notion of the current job is used. + + Exit Status: + Returns success unless job control is not enabled or an error occurs. + +[hash] + Remember or display program locations. + + Determine and remember the full pathname of each command NAME. If + no arguments are given, information about remembered commands is + displayed. + + Options: + -d forget the remembered location of each NAME + -l display in a format that may be reused as input + -p pathname use PATHNAME as the full pathname of NAME + -r forget all remembered locations + -t print the remembered location of each NAME, preceding + each location with the corresponding NAME if multiple + NAMEs are given + Arguments: + NAME Each NAME is searched for in $PATH and added to the list + of remembered commands. + + Exit Status: + Returns success unless NAME is not found or an invalid option is given. + + +[help] + Display information about builtin commands. + + Displays brief summaries of builtin commands. If PATTERN is + specified, gives detailed help on all commands matching PATTERN, + otherwise the list of help topics is printed. + + Options: + -d output short description for each topic + -m display usage in pseudo-manpage format + -s output only a short usage synopsis for each topic matching + PATTERN + + Arguments: + PATTERN Pattern specifying a help topic + + Exit Status: + Returns success unless PATTERN is not found or an invalid option is + given. + +[history] + Display or manipulate the history list. + + Display the history list with line numbers, prefixing each modified + entry with a '*'. An argument of N lists only the last N entries. + + Options: + -c clear the history list by deleting all of the entries + -d offset delete the history entry at position OFFSET. Negative + offsets count back from the end of the history list + + -a append history lines from this session to the history file + -n read all history lines not already read from the history file + and append them to the history list + -r read the history file and append the contents to the history + list + -w write the current history to the history file + + -p perform history expansion on each ARG and display the result + without storing it in the history list + -s append the ARGs to the history list as a single entry + + If FILENAME is given, it is used as the history file. Otherwise, + if HISTFILE has a value, that is used, else ~/.bash_history. + + If the HISTTIMEFORMAT variable is set and not null, its value is used + as a format string for strftime(3) to print the time stamp associated + with each displayed history entry. No time stamps are printed + otherwise. + + Exit Status: + Returns success unless an invalid option is given or an error occurs. + +[jobs] + Display status of jobs. + + Lists the active jobs. JOBSPEC restricts output to that job. + Without options, the status of all active jobs is displayed. + + Options: + -l lists process IDs in addition to the normal information + -n lists only processes that have changed status since the last + notification + -p lists process IDs only + -r restrict output to running jobs + -s restrict output to stopped jobs + + If -x is supplied, COMMAND is run after all job specifications that + appear in ARGS have been replaced with the process ID of that job's + process group leader. + + Exit Status: + Returns success unless an invalid option is given or an error occurs. + If -x is used, returns the exit status of COMMAND. + +[disown] + Remove jobs from current shell. + + Removes each JOBSPEC argument from the table of active jobs. Without + any JOBSPECs, the shell uses its notion of the current job. + + Options: + -a remove all jobs if JOBSPEC is not supplied + -h mark each JOBSPEC so that SIGHUP is not sent to the job if the + shell receives a SIGHUP + -r remove only running jobs + + Exit Status: + Returns success unless an invalid option or JOBSPEC is given. + +[kill] + Send a signal to a job. + + Send the processes identified by PID or JOBSPEC the signal named by + SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then + SIGTERM is assumed. + + Options: + -s sig SIG is a signal name + -n sig SIG is a signal number + -l list the signal names; if arguments follow '-l' they are + assumed to be signal numbers for which names should be listed + -L synonym for -l + + Kill is a shell builtin for two reasons: it allows job IDs to be used + instead of process IDs, and allows processes to be killed if the limit + on processes that you can create is reached. + + Exit Status: + Returns success unless an invalid option is given or an error occurs. + +[let] + Evaluate arithmetic expressions. + + Evaluate each ARG as an arithmetic expression. Evaluation is done in + fixed-width integers with no check for overflow, though division by 0 + is trapped and flagged as an error. The following list of operators is + grouped into levels of equal-precedence operators. The levels are + listed in order of decreasing precedence. + + id++, id-- variable post-increment, post-decrement + ++id, --id variable pre-increment, pre-decrement + -, + unary minus, plus + !, ~ logical and bitwise negation + '**' exponentiation + '*', /, % multiplication, division, remainder + +, - addition, subtraction + <<, >> left and right bitwise shifts + <=, >=, <, > comparison + ==, != equality, inequality + & bitwise AND + ^ tbitwise XOR + | bitwise OR + && logical AND + || logical OR + expr ? expr : expr + conditional operator + =, *=, /=, %=, + +=, -=, <<=, >>=, + &=, ^=, |= assignment + + Shell variables are allowed as operands. The name of the variable + is replaced by its value (coerced to a fixed-width integer) within + an expression. The variable need not have its integer attribute + turned on to be used in an expression. + + Operators are evaluated in order of precedence. Sub-expressions in + parentheses are evaluated first and may override the precedence + rules above. + + Exit Status: + If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise. + +[shift] + Shift positional parameters. + + Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is + not given, it is assumed to be 1. + + Exit Status: + Returns success unless N is negative or greater than $#. + +[suspend] + Suspend shell execution. + + Suspend the execution of this shell until it receives a SIGCONT signal. + Unless forced, login shells cannot be suspended. + + Options: + -f force the suspend, even if the shell is a login shell + + Exit Status: + Returns success unless job control is not enabled or an error occurs. + +[test] + Evaluate conditional expression. + + Exits with a status of 0 (true) or 1 (false) depending on + the evaluation of EXPR. Expressions may be unary or binary. Unary + expressions are often used to examine the status of a file. There + are string operators and numeric comparison operators as well. + + The behavior of test depends on the number of arguments. Read the + bash manual page for the complete specification. + + File operators: + + -a FILE True if file exists. + -b FILE True if file is block special. + -c FILE True if file is character special. + -d FILE True if file is a directory. + -e FILE True if file exists. + -f FILE True if file exists and is a regular file. + -g FILE True if file is set-group-id. + -h FILE True if file is a symbolic link. + -L FILE True if file is a symbolic link. + -k FILE True if file has its 'sticky' bit set. + -p FILE True if file is a named pipe. + -r FILE True if file is readable by you. + -s FILE True if file exists and is not empty. + -S FILE True if file is a socket. + -t FD True if FD is opened on a terminal. + -u FILE True if the file is set-user-id. + -w FILE True if the file is writable by you. + -x FILE True if the file is executable by you. + -O FILE True if the file is effectively owned by you. + -G FILE True if the file is effectively owned by your group. + -N FILE True if the file has been modified since it was last + read. + + FILE1 -nt FILE2 True if file1 is newer than file2 (according to + modification date). + + FILE1 -ot FILE2 True if file1 is older than file2. + + FILE1 -ef FILE2 True if file1 is a hard link to file2. + + String operators: + + -z STRING True if string is empty. + + -n STRING + STRING True if string is not empty. + + STRING1 = STRING2 + True if the strings are equal. + STRING1 != STRING2 + True if the strings are not equal. + STRING1 < STRING2 + True if STRING1 sorts before STRING2 + lexicographically. + STRING1 > STRING2 + True if STRING1 sorts after STRING2 lexicographically. + + Other operators: + + -o OPTION True if the shell option OPTION is enabled. + -v VAR True if the shell variable VAR is set. + -R VAR True if the shell variable VAR is set and is a name + reference. + ! EXPR True if expr is false. + EXPR1 -a EXPR2 True if both expr1 AND expr2 are true. + EXPR1 -o EXPR2 True if either expr1 OR expr2 is true. + + arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne, + -lt, -le, -gt, or -ge. + + Arithmetic binary operators return true if ARG1 is equal, not-equal, + less-than, less-than-or-equal, greater-than, or greater-than-or-equal + than ARG2. + + Exit Status: + Returns success if EXPR evaluates to true; fails if EXPR evaluates to + false or an invalid argument is given. + +[eval] + Execute arguments as a shell command. + + Combine ARGs into a single string, use the result as input to the shell, + and execute the resulting commands. + + Exit Status: + Returns exit status of command or success if command is null. + + +[times] + Display process times. + + Prints the accumulated user and system times for the shell and all of + its child processes. + + Exit Status: + Always succeeds. + +[ulimit] + Modify shell resource limits. + + Provides control over the resources available to the shell and + processes + it creates, on systems that allow such control. + + Options: + -S use the 'soft' resource limit + -H use the 'hard' resource limit + -a all current limits are reported + -b the socket buffer size + -c the maximum size of core files created + -d the maximum size of a process's data segment + -e the maximum scheduling priority ('nice') + -f the maximum size of files written by the shell and its children + -i the maximum number of pending signals + -k the maximum number of kqueues allocated for this process + -l the maximum size a process may lock into memory + -m the maximum resident set size + -n the maximum number of open file descriptors + -p the pipe buffer size + -q the maximum number of bytes in POSIX message queues + -r the maximum real-time scheduling priority + -s the maximum stack size + -t the maximum amount of cpu time in seconds + -u the maximum number of user processes + -v the size of virtual memory + -x the maximum number of file locks + -P the maximum number of pseudoterminals + -R the maximum time a real-time process can run before blocking + -T the maximum number of threads + + Not all options are available on all platforms. + + If LIMIT is given, it is the new value of the specified resource; the + special LIMIT values 'soft', 'hard', and 'unlimited' stand for the + current soft limit, the current hard limit, and no limit, respectively. + Otherwise, the current value of the specified resource is printed. If + no option is given, then -f is assumed. + + Values are in 1024-byte increments, except for -t, which is in seconds, + -p, which is in increments of 512 bytes, and -u, which is an unscaled + number of processes. + + Exit Status: + Returns success unless an invalid option is supplied or an error occurs. + +[umask] + Display or set file mode mask. + + Sets the user file-creation mask to MODE. If MODE is omitted, prints + the current value of the mask. + + If MODE begins with a digit, it is interpreted as an octal number; + otherwise it is a symbolic mode string like that accepted by chmod(1). + + Options: + -p if MODE is omitted, output in a form that may be reused as input + -S makes the output symbolic; otherwise an octal number is output + + Exit Status: + Returns success unless MODE is invalid or an invalid option is given. + +[return] + Return from a shell function. + + Causes a function or sourced script to exit with the return value + specified by N. If N is omitted, the return status is that of the + last command executed within the function or script. + + Exit Status: + Returns N, or failure if the shell is not executing a function or script. + +[wait] + Wait for job completion and return exit status. + + Waits for each process identified by an ID, which may be a process ID or + a job specification, and reports its termination status. If ID is not + given, waits for all currently active child processes, and the return + status is zero. If ID is a job specification, waits for all processes + in that job's pipeline. + + If the -n option is supplied, waits for a single job from the list of IDs, + or, if no IDs are supplied, for the next job to complete and returns its + exit status. + + If the -p option is supplied, the process or job identifier of the job + for which the exit status is returned is assigned to the variable VAR + named by the option argument. The variable will be unset initially, + before any assignment. This is useful only when the -n option is supplied. + + If the -f option is supplied, and job control is enabled, waits for the + specified ID to terminate, instead of waiting for it to change status. + + Exit Status: + Returns the status of the last ID; fails if ID is invalid or an invalid + option is given, or if -n is supplied and the shell has no unwaited-for + children. + +[for] + Execute commands for each member in a list. + + The 'for' loop executes a sequence of commands for each member in a + list of items. If 'in WORDS ...;' is not present, then 'in \$@\' is + assumed. For each element in WORDS, NAME is set to that element, and + the COMMANDS are executed. + + Exit Status: + Returns the status of the last command executed. + +[select] + Select words from a list and execute commands. + + The WORDS are expanded, generating a list of words. The + set of expanded words is printed on the standard error, each + preceded by a number. If 'in WORDS' is not present, 'in \$@\' + is assumed. The PS3 prompt is then displayed and a line read + from the standard input. If the line consists of the number + corresponding to one of the displayed words, then NAME is set + to that word. If the line is empty, WORDS and the prompt are + redisplayed. If EOF is read, the command completes. Any other + value read causes NAME to be set to null. The line read is saved + in the variable REPLY. COMMANDS are executed after each selection + until a break command is executed. + + Exit Status: + Returns the status of the last command executed. + +[time] + Report time consumed by pipeline's execution. + + Execute PIPELINE and print a summary of the real time, user CPU time, + and system CPU time spent executing PIPELINE when it terminates. + + Options: + -p print the timing summary in the portable Posix format + + The value of the TIMEFORMAT variable is used as the output format. + + Exit Status: + The return status is the return status of PIPELINE. + +[case] + Execute commands based on pattern matching. + + Selectively execute COMMANDS based upon WORD matching PATTERN. The + '|' is used to separate multiple patterns. + + Exit Status: + Returns the status of the last command executed. + +[if] + Execute commands based on conditional. + + The 'if COMMANDS' list is executed. If its exit status is zero, then + the + 'then COMMANDS' list is executed. Otherwise, each 'elif COMMANDS' list + is + executed in turn, and if its exit status is zero, the corresponding + 'then COMMANDS' list is executed and the if command completes. + Otherwise, + the 'else COMMANDS' list is executed, if present. The exit status of + the + entire construct is the exit status of the last command executed, or + zero + if no condition tested true. + + Exit Status: + Returns the status of the last command executed. + +[while] + Execute commands as long as a test succeeds. + + Expand and execute COMMANDS as long as the final command in the + 'while' COMMANDS has an exit status of zero. + + Exit Status: + Returns the status of the last command executed. + +[until] + Execute commands as long as a test does not succeed. + + Expand and execute COMMANDS as long as the final command in the + 'until' COMMANDS has an exit status which is not zero. + + Exit Status: + Returns the status of the last command executed. + +[coproc] + Create a coprocess named NAME. + + Execute COMMAND asynchronously, with the standard output and standard + input of the command connected via a pipe to file descriptors assigned + to indices 0 and 1 of an array variable NAME in the executing shell. + The default NAME is \COPROC\. + + Exit Status: + The coproc command returns an exit status of 0. + +[variables] + Common shell variable names and usage. + + BASH_VERSION Version information for this Bash. + CDPATH A colon-separated list of directories to search + for directories given as arguments to 'cd'. + GLOBIGNORE A colon-separated list of patterns describing filenames to + be ignored by pathname expansion. + HISTFILE The name of the file where your command history is stored. + HISTFILESIZE The maximum number of lines this file can contain. + HISTSIZE The maximum number of history lines that a running + shell can access. + HOME The complete pathname to your login directory. + HOSTNAME The name of the current host. + HOSTTYPE The type of CPU this version of Bash is running under. + IGNOREEOF Controls the action of the shell on receipt of an EOF + character as the sole input. If set, then the value + of it is the number of EOF characters that can be seen + in a row on an empty line before the shell will exit + (default 10). When unset, EOF signifies the end of input. + MACHTYPE A string describing the current system Bash is running on. + MAILCHECK How often, in seconds, Bash checks for new mail. + MAILPATH A colon-separated list of filenames which Bash checks + for new mail. + OSTYPE The version of Unix this version of Bash is running on. + PATH A colon-separated list of directories to search when + looking for commands. + PROMPT_COMMAND A command to be executed before the printing of each + primary prompt. + PS1 The primary prompt string. + PS2 The secondary prompt string. + PWD The full pathname of the current directory. + SHELLOPTS A colon-separated list of enabled shell options. + TERM The name of the current terminal type. + TIMEFORMAT The output format for timing statistics displayed by the + 'time' reserved word. + auto_resume Non-null means a command word appearing on a line by + itself is first looked for in the list of currently + stopped jobs. If found there, that job is foregrounded. + A value of 'exact' means that the command word must + exactly match a command in the list of stopped jobs. A + value of 'substring' means that the command word must + match a substring of the job. Any other value means that + the command must be a prefix of a stopped job. + histchars Characters controlling history expansion and quick + substitution. The first character is the history + substitution character, usually '!'. The second is + the 'quick substitution' character, usually '^'. The + third is the 'history comment' character, usually '#'. + HISTIGNORE A colon-separated list of patterns used to decide which + commands should be saved on the history list. + +[pushd] + Add directories to stack. + + Adds a directory to the top of the directory stack, or rotates + the stack, making the new top of the stack the current working + directory. With no arguments, exchanges the top two directories. + + Options: + -n Suppresses the normal change of directory when adding + directories to the stack, so only the stack is manipulated. + + Arguments: + +N Rotates the stack so that the Nth directory (counting + from the left of the list shown by 'dirs', starting with + zero) is at the top. + + -N Rotates the stack so that the Nth directory (counting + from the right of the list shown by 'dirs', starting with + zero) is at the top. + + dir Adds DIR to the directory stack at the top, making it the + new current working directory. + + The 'dirs' builtin displays the directory stack. + + Exit Status: + Returns success unless an invalid argument is supplied or the directory + change fails. + +[popd] + Removes entries from the directory stack. With no arguments, removes + the top directory from the stack, and changes to the new top directory. + + Options: + -n Suppresses the normal change of directory when removing + directories from the stack, so only the stack is manipulated. + + Arguments: + +N Removes the Nth entry counting from the left of the list + shown by 'dirs', starting with zero. For example: 'popd +0' + removes the first directory, 'popd +1' the second. + + -N Removes the Nth entry counting from the right of the list + shown by 'dirs', starting with zero. For example: 'popd -0' + removes the last directory, 'popd -1' the next to last. + + The 'dirs' builtin displays the directory stack. + the stack, making the new top of the stack the current working + directory. With no arguments, exchanges the top two directories. + +[dirs] + Display the list of currently remembered directories. Directories + find their way onto the list with the 'pushd' command; you can get + back up through the list with the 'popd' command. + + Options: + -c clear the directory stack by deleting all of the elements + -l do not print tilde-prefixed versions of directories relative + to your home directory + -p print the directory stack with one entry per line + -v print the directory stack with one entry per line prefixed + with its position in the stack + + Arguments: + +N Displays the Nth entry counting from the left of the list shown + by dirs when invoked without options, starting with zero. + + -N Displays the Nth entry counting from the right of the list shown + by dirs when invoked without options, starting with zero. + +[printf] + Formats and prints ARGUMENTS under control of the FORMAT. + + Options: + -v var assign the output to shell variable VAR rather than + display it on the standard output + + FORMAT is a character string which contains three types of objects: + plain + characters, which are simply copied to standard output; character + escape + sequences, which are converted and copied to the standard output; and + format specifications, each of which causes printing of the next + successive + argument. + + In addition to the standard format specifications described in + printf(1), + printf interprets: + + %b expand backslash escape sequences in the corresponding argument + %q quote the argument in a way that can be reused as shell input + %(fmt)T output the date-time string resulting from using FMT as a + format + string for strftime(3) + + The format is re-used as necessary to consume all of the arguments. If + there are fewer arguments than the format requires, extra format + specifications behave as if a zero value or null string, as + appropriate, + had been supplied. + + Exit Status: + Returns success unless an invalid option is given or a write or + assignment + error occurs. + +[complete] + Specify how arguments are to be completed by Readline. + + For each NAME, specify how arguments are to be completed. If no + options are supplied, existing completion specifications are printed + in a way that allows them to be reused as input. + + Options: + -p print existing completion specifications in a reusable format + -r remove a completion specification for each NAME, or, if no + NAMEs are supplied, all completion specifications + -D apply the completions and actions as the default for commands + without any specific completion defined + -E apply the completions and actions to \empty\ commands -- + completion attempted on a blank line + -I apply the completions and actions to the initial (usually the + command) word + + When completion is attempted, the actions are applied in the order the + uppercase-letter options are listed above. If multiple options are + supplied, + the -D option takes precedence over -E, and both take precedence over - + I. + + Exit Status: + Returns success unless an invalid option is supplied or an error occurs. + +[compgen] + Display possible completions depending on the options. + + Intended to be used from within a shell function generating possible + completions. If the optional WORD argument is supplied, matches + against WORD are generated. + + Exit Status: + Returns success unless an invalid option is supplied or an error occurs. + +[compopt] + Modify or display completion options. + + Modify the completion options for each NAME, or, if no NAMEs are + supplied, + the completion currently being executed. If no OPTIONs are given, + print the completion options for each NAME or the current completion + specification. + + Options: + -o option Set completion option OPTION for each NAME + -D Change options for the \default\ command completion + -E Change options for the \empty\ command completion + -I Change options for completion on the initial word + + Using '+o' instead of '-o' turns off the specified option. + + Arguments: + + Each NAME refers to a command for which a completion specification must + have previously been defined using the 'complete' builtin. If no NAMEs + are supplied, compopt must be called by a function currently generating + completions, and the options for that currently-executing completion + generator are modified. + + Exit Status: + Returns success unless an invalid option is supplied or NAME does not + have a completion specification defined. + +[mapfile] + Read lines from the standard input into an indexed array variable. + + Read lines from the standard input into the indexed array variable + ARRAY, or from file descriptor FD if the -u option is supplied. The variable + MAPFILE is the default ARRAY. + + Options: + -d delim Use DELIM to terminate lines, instead of newline + -n count Copy at most COUNT lines. If COUNT is 0, all lines are + copied + -O origin Begin assigning to ARRAY at index ORIGIN. The default + index is 0 + -s count Discard the first COUNT lines read + -t Remove a trailing DELIM from each line read (default newline) + -u fd Read lines from file descriptor FD instead of the standard + input + -C callback Evaluate CALLBACK each time QUANTUM lines are read + -c quantum Specify the number of lines read between each call to + CALLBACK + + Arguments: + ARRAY Array variable name to use for file data + + If -C is supplied without -c, the default quantum is 5000. When + CALLBACK is evaluated, it is supplied the index of the next array + element to be assigned and the line to be assigned to that element + as additional arguments. + + If not supplied with an explicit origin, mapfile will clear ARRAY + before assigning to it. + + Exit Status: + Returns success unless an invalid option is given or ARRAY is readonly + or not an indexed array. + +[readarray] + Read lines from a file into an array variable. + + A synonym for 'mapfile'. + +[unset] + Unset values and attributes of shell variables and functions. + + For each NAME, remove the corresponding variable or function. + + Options: + -f treat each NAME as a shell function + -v treat each NAME as a shell variable + -n treat each NAME as a name reference and unset the variable itself + rather than the variable it references + + Without options, unset first tries to unset a variable, and if that + fails, + tries to unset a function. + + Some variables cannot be unset; also see 'readonly'. + + Exit Status: + Returns success unless an invalid option is given or a NAME is read-only. + +[local] + Define local variables. + + Create a local variable called NAME, and give it VALUE. OPTION can + be any option accepted by `declare'. + + Local variables can only be used within a function; they are visible + only to the function where they are defined and its children. + + Exit Status: + Returns success unless an invalid option is supplied, a variable + assignment error occurs, or the shell is not executing a function. + +[export] + Set export attribute for shell variables. + + Marks each NAME for automatic export to the environment of subsequently + executed commands. If VALUE is supplied, assign VALUE before + exporting. + + Options: + -f refer to shell functions + -n remove the export property from each NAME + -p display a list of all exported variables and functions + + An argument of '--' disables further option processing. + + Exit Status: + Returns success unless an invalid option is given or NAME is invalid. + +[readonly] + Mark shell variables as unchangeable. + + Mark each NAME as read-only; the values of these NAMEs may not be + changed by subsequent assignment. If VALUE is supplied, assign VALUE + before marking as read-only. + + Options: + -a refer to indexed array variables + -A refer to associative array variables + -f refer to shell functions + -p display a list of all readonly variables or functions, + depending on whether or not the -f option is given + + An argument of '--' disables further option processing. + + Exit Status: + Returns success unless an invalid option is given or NAME is invalid. + +[declare] + Set variable values and attributes. + + Declare variables and give them attributes. If no NAMEs are given, + display the attributes and values of all variables. + + Options: + -f\trestrict action or display to function names and definitions + -F\trestrict display to function names only (plus line number and + \t\tsource file when debugging) + -g\tcreate global variables when used in a shell function; otherwise + \t\tignored + -I\tif creating a local variable, inherit the attributes and value + \t\tof a variable with the same name at a previous scope + -p\tdisplay the attributes and value of each NAME + + Options which set attributes: + -a\tto make NAMEs indexed arrays (if supported) + -A\tto make NAMEs associative arrays (if supported) + -i\tto make NAMEs have the 'integer' attribute + -l\tto convert the value of each NAME to lower case on assignment + -n\tmake NAME a reference to the variable named by its value + -r to make NAMEs readonly + -t to make NAMEs have the 'trace' attribute + -u to convert the value of each NAME to upper case on assignment + -x to make NAMEs export + + Using '+' instead of '-' turns off the given attribute. + + Variables with the integer attribute have arithmetic evaluation (see + the 'let' command) performed when the variable is assigned a value. + + When used in a function, 'declare' makes NAMEs local, as with the + 'local' + command. The '-g' option suppresses this behavior. + + Exit Status: + Returns success unless an invalid option is supplied or a variable + assignment error occurs. + +[function] + Define shell function. + + Create a shell function named NAME. When invoked as a simple command, + NAME runs COMMANDs in the calling shell's context. When NAME is + invoked, + the arguments are passed to the function as $1...$n, and the function's + name is in $FUNCNAME. + + Exit Status: + Returns success unless NAME is readonly. + +[typeset] + Set variable values and attributes. + + A synonym for 'declare'. See 'help declare'. + +[source] + Execute commands from a file in the current shell. + + Read and execute commands from FILENAME in the current shell. The + entries in $PATH are used to find the directory containing FILENAME. + If any ARGUMENTS are supplied, they become the positional parameters + when FILENAME is executed. + + Exit Status: + Returns the status of the last command executed in FILENAME; fails if + FILENAME cannot be read. + +[bind] + Set Readline key bindings and variables. + + Bind a key sequence to a Readline function or a macro, or set a + Readline variable. The non-option argument syntax is equivalent to + that found in ~/.inputrc, but must be passed as a single argument: + e.g., bind '\\\C-x\\C-r\: re-read-init-file'. + + Options: + -m keymap Use KEYMAP as the keymap for the duration of this + command. Acceptable keymap names are emacs, + emacs-standard, emacs-meta, emacs-ctlx, vi, vi- + move, + vi-command, and vi-insert. + -l List names of functions. + -P List function names and bindings. + -p List functions and bindings in a form that can be + reused as input. + -S List key sequences that invoke macros and their + values + -s List key sequences that invoke macros and their + values + in a form that can be reused as input. + -V List variable names and values + -v List variable names and values in a form that can + be reused as input. + -q function-name Query about which keys invoke the named function. + -u function-name Unbind all keys which are bound to the named + function. + -r keyseq Remove the binding for KEYSEQ. + -f filename Read key bindings from FILENAME. + -x keyseq:shell-command Cause SHELL-COMMAND to be executed when + KEYSEQ is entered. + -X List key sequences bound with -x and associated + commands + in a form that can be reused as input. + + Exit Status: + bind returns 0 unless an unrecognized option is given or an error occurs. + +[test] + Evaluate arithmetic expressions. + + Evaluate each ARG as an arithmetic expression. Evaluation is done in + fixed-width integers with no check for overflow, though division by 0 + is trapped and flagged as an error. The following list of operators is + grouped into levels of equal-precedence operators. The levels are + listed + in order of decreasing precedence. + + + id++, id-- variable post-increment, post-decrement + ++id, --id variable pre-increment, pre-decrement + -, + unary minus, plus + !, ~ logical and bitwise negation + '**' exponentiation + '*', /, % multiplication, division, remainder + +, - addition, subtraction + <<, >> left and right bitwise shifts + <=, >=, <, > comparison + ==, != equality, inequality + & bitwise AND + ^ tbitwise XOR + | bitwise OR + && logical AND + || logical OR + expr ? expr : expr + conditional operator + =, *=, /=, %=, + +=, -=, <<=, >>=, + &=, ^=, |= assignment + + + Shell variables are allowed as operands. The name of the variable + is replaced by its value (coerced to a fixed-width integer) within + an expression. The variable need not have its integer attribute + turned on to be used in an expression. + + Operators are evaluated in order of precedence. Sub-expressions in + parentheses are evaluated first and may override the precedence + rules above. + + Exit Status: + If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise. + +*[other] show other command help info. + } + +helpname = { +$cmdName -> +[command0] {" % - Resume job in foreground."} +[command1] {"(( - Evaluate conditional expression. "} +[command2] {". - Execute commands from a file in the current shell. "} +[command3] {": - Null command."} +[command4] {"[ - Evaluate conditional expression."} +[command5] {"[[ - Execute conditional command. "} +[command6] {"for (( - Arithmetic for loop."} +[command7] Group commands as a unit. +[set] set - Set or unset values of shell options and positional parameters. +[read] read - Read a line from the standard input and split it into fields. +[type] type - Display information about command type. +[trap] trap - Trap signals and other events. +[alias] alias - Define or display aliases. +[unalias] unalias - Remove each NAME from the list of defined aliases. +[break] break - Exit for, while, or until loops. +[continue] continue - Resume for, while, or until loops. +[builtin] builtin - Execute shell builtins. +[caller] caller - Returns the context of the current subroutine call. +[cd] cd - Change the shell working directory. +[pwd] pwd - Print the name of the current working directory. +[true] true - Null command. +[shopt] shopt - Set and unset shell options. +[false] false - Return an unsuccessful result. +[command] command - Execute a simple command or display information about commands. +[echo] echo - Write arguments to the standard output. +[enable] enable - Enable and disable shell builtins. +[getopts] getopts - Parse option arguments. +[exec] exec - Replace the shell with the given command. +[exit] exit - Exit the shell. +[logout] logout - Exit a login shell. +[fc] fc - Display or execute commands from the history list. +[fg] fg - Resume job in foreground. +[bg] bg - Move jobs to the background. +[hash] hash - Remember or display program locations. +[help] help - Display information about builtin commands. +[history] history - Display or manipulate the history list. +[jobs] jobs - Display status of jobs. +[disown] discow - Remove jobs from current shell. +[kill] kill - Send a signal to a job. +[let] let - Evaluate arithmetic expressions. +[shift] shift - Shift positional parameters. +[suspend] suspend - Suspend shell execution. +[eval] eval - Evaluate conditional expression. +[times] times - Display process times. +[ulimit] limit - Modify shell resource limits. +[umask] umask - Display or set file mode mask. +[return] return - Wait for job completion and return exit status. +[wait] wait -Wait for process completion and return exit status. +[for] for - Execute commands for each member in a list. +[select] select - Select words from a list and execute commands. +[time] time - Report time consumed by pipeline's execution. +[case] case - Execute commands based on pattern matching. +[if] if - Execute commands based on conditional. +[while] while - Execute commands as long as a test succeeds. +[until] until - Execute commands as long as a test does not succeed. +[coproc] corproc - Create a coprocess named NAME. +[variables] variables - Common shell variable names and usage. +[pushd] pushd - Add directories to stack. +[popd] popd - Removes entries from the directory stack. +[dirs] dirs - Display the list of currently remembered directories. +[printf] printf - Formats and prints ARGUMENTS under control of the FORMAT. +[complete] complete - Specify how arguments are to be completed by Readline. +[compgen] compgen - Display possible completions depending on the options. +[compopt] compopt - Modify or display completion options. +[mapfile] mapfile - Read lines from the standard input into an indexed array variable. +[unset] unset - Unset values and attributes of shell variables and functions. +[readarray] readarry - Read lines from a file into an array variable. +[local] local -Remember or display program locations.。 +[export] export - Set export attribute for shell variables. +[readonly] readonly - Mark shell variables as unchangeable. +[function] function - Define shell function. +[typeset] typeset - Set variable values and attributes. +[source] source - Execute commands from a file in the current shell. +[bind] bind - Set Readline key bindings and variables.。 +[test] test - Evaluate arithmetic expressions. +[declare] declare - Set variable values and attributes. +*[other] show other command help info.. +} + +helpsynopsis = { +$cmdName -> +[command0] {"job_spec [&]"} +[command1] {"(( expression ))"} +[command2] {". filename [arguments]"} +[command3] {":"} +[command4] {"[ ... ]"} +[command5] {"[[ expression ]]"} +[command6] {"for (( exp1; exp2; exp33 )); do COMMANDS ; done"} +[command7] {"{ COMMAND ; }"} +[set] {"set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]"} +[read] {"read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]"} +[type] {"type [-afptP] name [name ...]"} +[trap] {"trap [-lp] [[arg] signal_spec ...]"} +[alias] {"alias [-p] [name[=value] ... ]"} +[unalias] {"unalias [-a] name [name ...]"} +[break] {"break [n]"} +[continue] {"continue [n]"} +[builtin] {"unalias [-a] name [name ...]"} +[caller] {"caller [expr] "} +[cd] {"cd [-L|[-P [-e]] [-@]] [dir]"} +[pwd] {"pwd [-LP]"} +[true] {"true"} +[shopt] {"shopt [-pqsu] [-o] [optname ...]"} +[false] {"false"} +[command] {"command [-pVv] command [arg ...]"} +[echo] {"echo [-neE] [arg ...]"} +[enable] {"enable [-a] [-dnps] [-f filename] [name ...] "} +[getopts] {"getopts optstring name [arg ...]"} +[exec] {"exec [-cl] [-a name] [command [argument ...]] [redirection ...] "} +[exit] {"exit [n]"} +[logout] {"logout [n]"} +[fc] {"fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]"} +[fg] {"fg [job_spec] "} +[bg] {"bg [job_spec ...]"} +[hash] {"hash [-lr] [-p pathname] [-dt] [name ...]"} +[help] {"help [-dms] [pattren ...]"} +[history] {"history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"} +[jobs] {"jobs [-lnprs] [jobspec ...] or jobs -x command [args]"} +[disown] {"disown [-h] [-ar] [jobspec ... | pid ...]"} +[kill] {"kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"} +[let] {"let arg [arg ...]"} +[shift] {"shift [n]"} +[suspend] {"suspend [-f]"} +[eval] {"eval [arg ...]"} +[times] {"times"} +[ulimit] {"ulimit [-SHabcdefiklmnpqrstuvxPT] [ulimit]"} +[umask] {"umask [-p] [-S] [pattern]"} +[return] {"return [n]"} +[wait] {"wait [-fn] [-p var] [id ...]"} +[for] {"for NAME [in WORDS ... ] ; do COMMANDS; done"} +[select] {"select NAME [in WORDS ... ;] do COMMANDS; done"} +[time] {"time [-p] pipeline"} +[case] {"case WORD in [pattern [| pattern]...) COMMANDS ;;]... esac"} +[if] {"if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi"} +[while] {"while COMMANDS; do COMMANDS; done"} +[until] {"until COMMANDS; do COMMANDS; done"} +[coproc] {"coproc [NAME] COMMANDS [redirections]"} +[variables] {"variables - variables - Names and meanings of some shell variables"} +[pushd] {"pushd [-n] [+N | -N | dir]"} +[popd] {"popd [-n] [+N | -N]"} +[dirs] {"dirs [-clpv] [+N] [-N]"} +[printf] {"printf [-v var] format [arguments]"} +[complete] {"complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]"} +[compgen] {"compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"} +[compopt] {"compopt [-o|+o option] [-DEI] [name ...]"} +[mapfile] {"mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]]"} +[unset] {"unset [-f] [-v] [-n] [NAME ...]"} +[readarray] {"readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"} +[local] {"local [option] name[=value] ... "} +[export] {"export [-fn] [name[=value] ...] or export -p"} +[readonly] {"readonly [-aAf] [name[=value] ...] or readonly -p"} +[function] {"function NAME { COMMANDS ; } 或 name () { COMMANDS ; } "} +[typeset] {"typeset [-aAfFgiIlnrtux] [-p] name[=value] ..."} +[source] {"source filename [arguments]"} +[bind] {"bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command] "} +[test] {"test [expr]"} +[declare] {"declare [-aAfFgilnrtux] [-p] [name[=value] ...]"} +*[other] {"show other command help info.."} +} + +information = These shell commands are defined internally. Type 'help' to see this list. + Type 'help name' to find out more about the function 'name'. + Use 'info bash' to find out more about the shell in general. + Use 'man -k' or 'info' to find out more about commands not in this list. + A star (*) next to a name means that the command is disabled. + +helperr = "no help topics match {$name} .Try 'help help' or 'man -k {$name}' or info {$name}" + +is = {$str1} is {$str2} +special = {$str1} is a special shell builtin +hashd = {$str1} is hashed {$str2} +isfunction = {$str1} is a function +iskeyword = {$str1} is a shell keyword +isalias = {$str1} is aliased to {$str2} +isbuiltin = {$str1} is a shell builtin +killargerr = {$str1} : arguments must be process or job IDs +letwarn = utshell : let : expression expected +bindvia = {$str1} can be invoked via +bindnokeys = {$str1} is not bound to any keys. +unknowdfunction = {$str1} : unknown function name +unbindfaild = {$str1} : cannot unbind +invaildmap = {$str1} : invalid keymap name +logout = logout +nologinsh = not login shell: use 'exit' +stoppedjobs = There are stopped jobs. +runjobs = There are running jobs. diff --git a/utshell-0.5.0/resources/zh-CN/message.ftl b/utshell-0.5.0/resources/zh-CN/message.ftl new file mode 100644 index 00000000..aaff61e3 --- /dev/null +++ b/utshell-0.5.0/resources/zh-CN/message.ftl @@ -0,0 +1,1640 @@ +helplongdoc ={ +$cmdName -> +[command0] + 在å‰å°ç»§ç»­ä»»åŠ¡ + 对于 JOB_SPEC 傿•°æ¥è¯´å’Œ `fg' 命令等åŒã€‚继续一个 + åœæ­¢çš„æˆ–者åŽå°ä»»åŠ¡ã€‚JOB_SPEC å¯ä»¥æŒ‡å®šä¸€ä¸ªä»»åŠ¡ + å字或任务å·ã€‚在 JOB_SPEC åŽåŠ ä¸Šä¸€ä¸ª `&' 将会把 + 任务放至åŽå°ï¼Œå°±åƒä»»åŠ¡å£°æ˜Žè¢«ä½œä¸º `bg' å‘½ä»¤çš„å‚æ•° + 执行一样。 + + 退出状æ€ï¼š + 返回被继续的任务的状æ€ã€‚ + +[command1] + 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚ + 是内建命令 test çš„åŒä¹‰è¯ï¼Œä½†æ˜¯æœ€åŽä¸€ä¸ªå‚数必须是 + 字符 `]',以匹é…èµ·å§‹çš„ `['。 + +[command2] + åœ¨å½“å‰ shell 中执行一个文件中的命令。 + + åœ¨å½“å‰ shell 中读å–并执行 FILENAME 文件中的命令。$PATH å˜é‡ä¸­çš„ + æ¡ç›®è¢«ç”¨äºŽå¯»æ‰¾åŒ…å« FILENAME 文件的目录。如果æä¾›äº†ä»»ä½•çš„ ARGUMENTS + 傿•°ï¼Œåˆ™å®ƒä»¬å°†æˆä¸º FILENAME 文件执行时的ä½ç½®å‚数。 + + 退出状æ€ï¼š + 返回 FILENAME 文件中最åŽä¸€ä¸ªå‘½ä»¤çš„状æ€ï¼›å¦‚æžœ FILENAME 文件ä¸å¯è¯»åˆ™å¤±è´¥ã€‚ + +[command3] + 空的命令。 + 没有效果; 此命令ä¸åšä»»ä½•æ“作。 + + 退出状æ€ï¼š + 总是æˆåŠŸã€‚ + +[command4] + 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚ + + 是内建命令 test çš„åŒä¹‰è¯ï¼Œä½†æ˜¯æœ€åŽä¸€ä¸ªå‚数必须是 + 字符 `]',以匹é…èµ·å§‹çš„ `['。 + +[command5] + 执行æ¡ä»¶å‘½ä»¤ã€‚ + + æ ¹æ®æ¡ä»¶è¡¨è¾¾å¼ EXPRESSION 的估值返回状æ€0或1ã€‚è¡¨è¾¾å¼æŒ‰ç…§ + `test' å†…å»ºçš„ç›¸åŒæ¡ä»¶ç»„æˆï¼Œæˆ–者å¯ä»¥æœ‰ä¸‹åˆ—æ“作符连接而æˆï¼š + + ( EXPRESSION ) 返回 EXPRESSION 表达å¼çš„值 + ! EXPRESSION 如果 EXPRESSION表达å¼ä¸ºå‡åˆ™ä¸ºçœŸï¼Œå¦åˆ™ä¸ºå‡ + EXPR1 && EXPR2 如果 EXPR1 å’Œ EXPR2 表达å¼å‡ä¸ºçœŸåˆ™ä¸ºçœŸï¼Œå¦åˆ™ä¸ºå‡ + EXPR1 || EXPR2 如果 EXPR1 å’Œ EXPR2 表达å¼ä¸­æœ‰ä¸€ä¸ªä¸ºçœŸåˆ™ä¸ºçœŸï¼Œå¦åˆ™ä¸º + å‡ + + 当使用 `==' å’Œ `!=' æ“作符时,æ“作符å³è¾¹çš„字符串被用作模å¼å¹¶ä¸”执行一个 + 匹é…。当使用 `=~' æ“作符时,æ“作符å³è¾¹çš„å­—ç¬¦ä¸²è¢«å½“ä½œæ­£åˆ™è¡¨è¾¾å¼æ¥è¿›è¡Œ + 匹é…。 + + æ“作符 && å’Œ || å°†ä¸å¯¹ EXPR2 表达å¼è¿›è¡Œä¼°å€¼ï¼Œå¦‚æžœ EXPR1 表达å¼è¶³å¤Ÿç¡®å®š + 整个表达å¼çš„值。 + + 退出状æ€ï¼š + æ ¹æ® EXPRESSION 的值为0或1。 + +[command6] + 算术 for 循环。 + + 等价于 + (( EXP1 )) + while (( EXP2 )); do + 命令们 + (( EXP3 )) + done + EXP1ã€EXP2 å’Œ EXP3 都是算术表达å¼ã€‚如果çœç•¥ä»»ä½•表达å¼ï¼Œ + 则等åŒäºŽä½¿ç”¨äº†ä¼°å€¼ä¸º1的表达å¼ã€‚ + + 退出状æ€ï¼š + è¿”å›žæœ€åŽæ‰§è¡Œçš„命令的状æ€ã€‚ + +[command7] + 将命令组åˆä¸ºä¸€ä¸ªå•元。 + + è¿è¡Œç»„中的命令集åˆã€‚è¿™æ˜¯å¯¹æ•´ä¸ªå‘½ä»¤é›†åˆ + åšé‡å®šå‘的方法之一。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[set] + è®¾å®šæˆ–å–æ¶ˆè®¾å®š shell 选项和ä½ç½®å‚æ•°çš„ + + æ”¹å˜ shell 选项和ä½ç½®å‚数的值,或者显示 shell å˜é‡çš„ + å称和值。 + + 选项: + -a 标记修改的或者创建的å˜é‡ä¸ºå¯¼å‡ºã€‚ + -b ç«‹å³é€šå‘Šä»»åŠ¡ç»ˆç»“ã€‚ + -e 如果一个命令以éžé›¶çжæ€é€€å‡ºï¼Œåˆ™ç«‹å³é€€å‡ºã€‚ + -f ç¦ç”¨æ–‡ä»¶å生æˆ(模å¼åŒ¹é…)。 + -h 当查询命令时记ä½å®ƒä»¬çš„ä½ç½® + -k æ‰€æœ‰çš„èµ‹å€¼å‚æ•°è¢«æ”¾åœ¨å‘½ä»¤çš„环境中,而ä¸ä»…仅是 + 命令å称之å‰çš„傿•°ã€‚ + -m å¯ç”¨ä»»åŠ¡æŽ§åˆ¶ã€‚ + -n 读å–命令但䏿‰§è¡Œ + -o 选项å + 设定与选项å对应的å˜é‡ï¼š + allexport 与 -a ç›¸åŒ + braceexpand 与 -B ç›¸åŒ + emacs 使用 emacs é£Žæ ¼çš„è¡Œç¼–è¾‘ç•Œé¢ + errexit 与 -e ç›¸åŒ + errtrace 与 -E ç›¸åŒ + functrace 与 -T ç›¸åŒ + hashall 与 -h ç›¸åŒ + histexpand 与 -H ç›¸åŒ + history å¯ç”¨å‘½ä»¤åŽ†å² + ignoreeof shell è¯»å–æ–‡ä»¶ç»“æŸç¬¦æ—¶ä¸ä¼šé€€å‡º + interactive-comments + å…许在交互å¼å‘½ä»¤ä¸­æ˜¾ç¤ºæ³¨é‡Š + keyword 与 -k ç›¸åŒ + monitor 与 -m ç›¸åŒ + noclobber 与 -C ç›¸åŒ + noexec 与 -n ç›¸åŒ + noglob 与 -f ç›¸åŒ + nolog ç›®å‰å¯æŽ¥å—但是被忽略 + notify 与 -b ç›¸åŒ + nounset 与 -u ç›¸åŒ + onecmd 与 -t ç›¸åŒ + physical 与 -P ç›¸åŒ + pipefail 管é“的返回值是最åŽä¸€ä¸ªéžé›¶è¿”回值的命令的返回结果, + 或者当所有命令都返回零是也为零。 + posix 改å˜é»˜è®¤æ—¶å’Œ Posix 标准ä¸åŒçš„ bash 行为 + ä»¥åŒ¹é…æ ‡å‡† + privileged 与 -p ç›¸åŒ + verbose 与 -v ç›¸åŒ + vi 使用 vi é£Žæ ¼çš„è¡Œç¼–è¾‘ç•Œé¢ + xtrace 与 -x ç›¸åŒ + -p 无论何时当真实的有效的用户身份ä¸åŒ¹é…时打开。 + ç¦ç”¨å¯¹ $ENV 文件的处ç†ä»¥åŠå¯¼å…¥ shell 函数。 + 关闭此选项会导致有效的用户编å·å’Œç»„ç¼–å·è®¾å®š + 为真实的用户编å·å’Œç»„ç¼–å· + -t 读å–并执行一个命令之åŽé€€å‡ºã€‚ + -u æ›¿æ¢æ—¶å°†ä¸ºè®¾å®šçš„å˜é‡å½“作错误对待。 + -v è¯»å– shell 输入行时将它们打å°ã€‚ + -x 执行命令时打å°å®ƒä»¬ä»¥åŠå‚数。 + -B shell å°†æ‰§è¡ŒèŠ±æ‹¬å·æ‰©å±•。 + -C 设定之åŽç¦æ­¢ä»¥é‡å®šå‘输出的方å¼è¦†ç›–常 + 规文件。 + -E è®¾å®šä¹‹åŽ ERR 陷阱会被 shell 函数继承。 + -H å¯ç”¨ ! é£Žæ ¼çš„åŽ†å²æ›¿æ¢ã€‚当 shell 是交互å¼çš„ + 时候这个标识ä½é»˜è®¤æ‰“开。 + -P 设定之åŽç±»ä¼¼ cd 的会改å˜å½“å‰ç›®å½•çš„å‘½ä»¤ä¸ + 追踪符å·é“¾æŽ¥ã€‚ + -T è®¾å®šä¹‹åŽ DEBUG 陷阱会被 shell 函数继承。 + -- ä»»ä½•å‰©ä½™çš„å‚æ•°ä¼šè¢«èµ‹å€¼ç»™ä½ç½®å‚数。如果没 + æœ‰å‰©ä½™çš„å‚æ•°ï¼Œä½ç½®å‚æ•°ä¸ä¼šè¢«è®¾ç½®ã€‚ + - ä»»ä½•å‰©ä½™çš„å‚æ•°ä¼šè¢«èµ‹å€¼ç»™ä½ç½®å‚数。 + -x å’Œ -v 选项已关闭。 + + 使用 + è€Œä¸æ˜¯ - 会使标志ä½è¢«å…³é—­ã€‚标志ä½ä¹Ÿå¯ä»¥åœ¨ + shell 被å¯åŠ¨æ—¶ä½¿ç”¨ã€‚å½“å‰çš„æ ‡å¿—ä½è®¾å®šå¯ä»¥åœ¨ $- å˜ + é‡ä¸­æ‰¾åˆ°ã€‚剩余的 ARG 傿•°æ˜¯ä½ç½®å‚数并且是按照 + $1, $2, .. $n 的顺åºè¢«èµ‹å€¼çš„。如果没有给定 ARG + 傿•°ï¼Œåˆ™æ‰“å°æ‰€æœ‰çš„ shell å˜é‡ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„傿•°ã€‚ +[read] + 从标准输入读å–一行并将其分为ä¸åŒçš„域。 + + 从标准输入读å–å•独的一行,或者如果使用了 -u 选项,从文件æè¿°ç¬¦ FD 中读 + å–。 + 该行被分割æˆåŸŸï¼Œå¦‚åŒè¯è¯­åˆ†å‰²ä¸€æ ·ï¼Œå¹¶ä¸”第一个è¯è¢«èµ‹å€¼ç»™ç¬¬ä¸€ä¸ª NAME å˜é‡ï¼Œ + 第二 + 个è¯è¢«èµ‹å€¼ç»™ç¬¬äºŒä¸ª NAME å˜é‡ï¼Œå¦‚此继续,直到剩下所有的è¯è¢«èµ‹å€¼ç»™æœ€åŽä¸€ä¸ª + NAME + å˜é‡ã€‚åªæœ‰ $IFS å˜é‡ä¸­çš„字符被认作是è¯è¯­åˆ†éš”符。 + + 如果没有æä¾› NAME å˜é‡ï¼Œåˆ™è¯»å–的行被存放在 REPLY å˜é‡ä¸­ã€‚ + + 选项: + -a array å°†è¯è¯­èµ‹å€¼ç»™ ARRAY 数组å˜é‡çš„åºåˆ—下标æˆå‘˜ï¼Œä»Žé›¶å¼€å§‹ + -d delim æŒç»­è¯»å–直到读入 DELIM å˜é‡ä¸­çš„ç¬¬ä¸€ä¸ªå­—ç¬¦ï¼Œè€Œä¸æ˜¯æ¢è¡Œç¬¦ + -e 使用 Readline 获å–行 + -i text 使用 TEXT 文本作为 Readline çš„åˆå§‹æ–‡å­— + -n nchars è¯»å– nchars 个字符之åŽè¿”å›žï¼Œè€Œä¸æ˜¯ç­‰åˆ°è¯»å–æ¢è¡Œç¬¦ã€‚ + 但是分隔符ä»ç„¶æœ‰æ•ˆï¼Œå¦‚æžœé‡åˆ°åˆ†éš”符之å‰è¯»å–了ä¸è¶³ nchars 个字符。 + -N nchars 在准确读å–了 nchars 个字符之åŽè¿”回,除éžé‡åˆ°æ–‡ä»¶ç»“æŸç¬¦æˆ–者读 + 超时,任何的分隔符都被忽略 + -p prompt 在å°è¯•读å–之å‰è¾“出 PROMPT æç¤ºç¬¦å¹¶ä¸”ä¸å¸¦æ¢è¡Œç¬¦ + -r ä¸å…è®¸åæ–œæ è½¬ä¹‰ä»»ä½•字符 + -s ä¸å›žæ˜¾ç»ˆç«¯çš„任何输入 + -t timeout 如果在 TIMEOUT 秒内没有读å–一个完整的行则超时并且返回失 + 败。TMOUT å˜é‡çš„值是默认的超时时间。TIMEOUT å¯ä»¥æ˜¯å°æ•°ã€‚ + 如果 TIMEOUT 是 0,那么仅当在指定的文件æè¿°ç¬¦ä¸Šè¾“入有效的时候, + read æ‰è¿”回æˆåŠŸï¼›å¦åˆ™å®ƒå°†ç«‹åˆ»è¿”回而ä¸å°è¯•读å–任何数æ®ã€‚ + 如果超过了超时时间,则返回状æ€ç å¤§äºŽ 128 + -u fd 从文件æè¿°ç¬¦ FD 中读å–ï¼Œè€Œä¸æ˜¯æ ‡å‡†è¾“å…¥ + + 退出状æ€ï¼š + 返回ç ä¸ºé›¶ï¼Œé™¤éžé‡åˆ°äº†æ–‡ä»¶ç»“æŸç¬¦ã€è¯»è¶…时(且返回ç ä¸å¤§äºŽ128)〠+ 出现了å˜é‡èµ‹å€¼é”™è¯¯æˆ–者无效的文件æè¿°ç¬¦ä½œä¸ºå‚数传递给了 -u 选项。 + +[type] + 显示命令类型的信æ¯ã€‚ + + 对于æ¯ä¸€ä¸ª NAME å称,指示如果作为命令它将如何被解释。 + + 选项: + -a 显示所有包å«å称为 NAME çš„å¯æ‰§è¡Œæ–‡ä»¶çš„ä½ç½®ï¼› + 包括别åã€å†…建和函数。仅当 `-p' 选项没有使用时 + -f 抑制 shell 函数查询 + -P 为æ¯ä¸ª NAME å称惊醒 PATH 路径æœç´¢ï¼Œå³ä½¿å®ƒæ˜¯åˆ«å〠+ 内建或函数,并且返回将被执行的ç£ç›˜ä¸Šæ–‡ä»¶çš„å称。 + -p 返回将被执行的ç£ç›˜ä¸Šæ–‡ä»¶çš„å称,或者当 `type -t NAME' + ä¸è¿”回 `file' 时,ä¸è¿”回任何值。 + -t 返回下列è¯ä¸­çš„任何一个 `alias'ã€`keyword'〠+ `function'ã€`builtin'ã€`file' 或者 `',相应地如果 NAME 是 + 一个别åã€shell ä¿ç•™å­—ã€shell 函数ã€shell 内建〠+ ç£ç›˜æ–‡ä»¶æˆ–没有找到。 + + 傿•°ï¼š + NAME å°†è¦è§£æžçš„命令。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称为åªè¯»ã€‚ + +[trap] + 对信å·å’Œå…¶ä»–事件设陷阱。 + + 定义一个处ç†å™¨ï¼Œåœ¨ shell 接收到信å·å’Œå…¶ä»–æ¡ä»¶ä¸‹æ‰§è¡Œã€‚ + + ARG 傿•°æ˜¯å½“ shell 接收到 SIGNAL_SPEC ä¿¡å·æ—¶è¯»å–和执行的命令。 + 如果没有指定 ARG 傿•° (并且åªç»™å‡ºä¸€ä¸ª SIGNAL_SPEC ä¿¡å·) 或者 + ARG 傿•°ä¸º + `-',æ¯ä¸€ä¸ªæŒ‡å®šçš„傿•°ä¼šè¢«é‡ç½®ä¸ºåŽŸå§‹å€¼ã€‚å¦‚æžœ ARG 傿•°æ˜¯ä¸€ä¸ªç©ºä¸²ï¼Œåˆ™æ¯ä¸€ + 个 + SIGNAL_SPEC ä¿¡å·ä¼šè¢« shell 和它å¯åŠ¨çš„å‘½ä»¤å¿½ç•¥ã€‚ + + 如果一个 SIGNAL_SPEC ä¿¡å·æ˜¯ EXIT (0) ,则 ARG 命令会在 shell 退出时被 + 执行。如果一个 SIGNAL_SPEC ä¿¡å·æ˜¯ DEBUG,则 ARG命令会在æ¯ä¸€ä¸ªç®€å•命 + 令之剿‰§è¡Œã€‚ + + å¦‚æžœä¸æä¾›å‚æ•°ï¼Œtrap 打å°åˆ—表显示æ¯ä¸€ä¸ªä¸Žæ¯ä¸€ä¸ªä¿¡å·ç›¸å…³è”的命令。 + + 选项: + -l 打å°ä¸€ä¸ªä¿¡å·å称和它们对应的编å·çš„列表 + -p 打å°ä¸Žæ¯ä¸ª SIGNAL_SPEC ä¿¡å·ç›¸å…³è”的陷阱命令 + + æ¯ä¸€ä¸ª SIGNAL_SPEC ä¿¡å·å¯ä»¥æ˜¯ 中的信å·å称或者信å·ç¼–å·ã€‚ + ä¿¡å·å称大å°å†™æ•感且å¯ä»¥ä½¿ç”¨ SIG å‰ç¼€ã€‚ä¿¡å·å¯ç”¨ \kill -ä¿¡å· $$\ + å‘é€ç»™ shell。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 SIGSPEC。 + +[alias] + 定义或显示别å。 + + ä¸å¸¦å‚数时,`alias' 以å¯é‡ç”¨çš„æ ¼å¼ + `alias åç§°=值'在标准输出设备上打å°åˆ«å列表。 + + å¦åˆ™ï¼Œå¯¹äºŽæ¯ä¸ªç»™å®šå€¼çš„å称定义一个别å。 + 值末尾的空格会使下一个è¯è¢«æ£€æµ‹ä½œä¸ºåˆ«å替æ¢å±•开。 + + 选项: + -p 以å¯é‡ç”¨çš„æ ¼å¼æ‰“å°æ‰€æœ‰çš„已定义的别å + + 退出状æ€ï¼š + 除éžä¸€ä¸ªæ²¡æœ‰å®šä¹‰çš„åå­—è¢«ä½œä¸ºå‚æ•°æä¾›ï¼Œå¦åˆ™ alias + 返回值为真。 + +[unalias] + 从别å定义列表中删除æ¯ä¸€ä¸ªâ€œåå­—â€ã€‚ + + 选项: + -a 删除所有的别å定义 + + 返回æˆåŠŸï¼Œé™¤éžâ€œåå­—â€ä¸æ˜¯ä¸€ä¸ªå·²å­˜åœ¨çš„别å。 + +[break] + 退出 forã€while 或 until 循环 + + 退出一个 FORã€WHILE 或 UNTIL 循环。如果指定了N,则跳出Né‡ + 循环 + + 退出状æ€ï¼š + 退出状æ€ä¸º0é™¤éž N ä¸å¤§äºŽæˆ–等于 1。 + +[continue] + ç»§ç»­ forã€while 或 until 循环。 + + ç»§ç»­å½“å‰ FORã€WHILE 或 UNTIL 循环的下一步。 + 如果指定了 N, 则继续当å‰çš„第 N é‡å¾ªçŽ¯ã€‚ + + 退出状æ€ï¼š + 退出状æ€ä¸º 0 é™¤éž N ä¸å¤§äºŽæˆ–等于1。 + +[builtin] + 执行 shell 内建。 + + 另傿•° ARGs 执行 SHELL-BUILTIN 内建,并且ä¸åšå‘½ä»¤æŸ¥è¯¢ + 在希望以 shell å‡½æ•°çš„å½¢å¼æ¥é‡æ–°å®žçް shell 内建, + 并且希望在函数之内执行该 shell 内建的情况下有用处。 + + 退出状æ€ï¼š + 以 SHELL-BUILTIN 内建的退出状æ€ä¸ºå‡†ï¼Œæˆ–者如果 SHELL-BUILTIN 䏿˜¯ä¸€ä¸ª + shell 内建时为å‡ã€‚ + +[caller] + 返回当å‰å­è°ƒç”¨çš„上下文。 + + ä¸å¸¦æœ‰ EXPR 时,返回 $line $filename。带有 EXPR 时,返回 + $line $subroutine $filename;这个é¢å¤–的信æ¯å¯ä»¥è¢«ç”¨äºŽæä¾› + 栈追踪。 + + EXPR 的值 显示了到当å‰è°ƒç”¨å¸§éœ€è¦å›žåŽ»å¤šå°‘ä¸ªè°ƒç”¨å¸§ï¼›é¡¶éƒ¨å¸§ + 是第 0 帧。 + + 退出状æ€ï¼š + é™¤éž shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ª shell 函数或者 EXPR 无效,å¦åˆ™è¿”回结 + 果为0。 + +[cd] + æ”¹å˜ shell 工作目录。 + + 改å˜å½“å‰ç›®å½•至 DIR 目录。默认的 DIR 目录是 shell å˜é‡ HOME + 的值。 + + å˜é‡ CDPATH å®šä¹‰äº†å«æœ‰ DIR 的目录的æœç´¢è·¯å¾„,其中ä¸åŒçš„目录åç§°ç”±å†’å· (:) + 分隔。 + 一个空的目录å称表示当å‰ç›®å½•。如果è¦åˆ‡æ¢åˆ°çš„ DIR ç”±æ–œæ  (/) 开头,则 + CDPATH + ä¸ä¼šç”¨ä¸Šå˜é‡ã€‚ + + 如果路径找ä¸åˆ°ï¼Œå¹¶ä¸” shell 选项 `cdable_vars' è¢«è®¾å®šï¼Œåˆ™å‚æ•°è¯è¢«å‡å®šä¸ºä¸€ + 个 + å˜é‡å。如果该å˜é‡æœ‰å€¼ï¼Œåˆ™å®ƒçš„值被当作 DIR 目录。 + + 选项: + -L 强制跟éšç¬¦å·é“¾æŽ¥: åœ¨å¤„ç† `..' 之åŽè§£æž DIR 中的符å·é“¾æŽ¥ã€‚ + -P 使用物ç†ç›®å½•结构而ä¸è·Ÿéšç¬¦å·é“¾æŽ¥: åœ¨å¤„ç† `..' 之å‰è§£æž DIR 中的符 + å·é“¾æŽ¥ã€‚ + -e 如果使用了 -P 傿•°ï¼Œä½†ä¸èƒ½æˆåŠŸç¡®å®šå½“å‰å·¥ä½œç›®å½•时,返回éžé›¶çš„返回 + 值。 + -@ åœ¨æ”¯æŒæ‹“展属性的系统上,将一个有这些属性的文件当作有文件属性的目 + 录。 + + 默认情况下跟éšç¬¦å·é“¾æŽ¥ï¼Œå¦‚åŒæŒ‡å®š `-L'。 + `..' 使用移除å‘å‰ç›¸é‚»ç›®å½•åæˆå‘˜ç›´åˆ° DIR 开始或一个斜æ çš„æ–¹å¼å¤„ç†ã€‚ + + 退出状æ€ï¼š + 如果目录改å˜ï¼Œæˆ–在使用 -P 选项时 $PWD 修改æˆåŠŸæ—¶è¿”å›ž 0,å¦åˆ™éžé›¶ã€‚ + +[pwd] + 打å°å½“å‰å·¥ä½œç›®å½•çš„å字。 + + 选项: + -L æ‰“å° $PWD å˜é‡çš„值,如果它包å«äº†å½“å‰çš„工作目录 + -P 打å°å½“å‰çš„物ç†è·¯å¾„,ä¸å¸¦æœ‰ä»»ä½•的符å·é“¾æŽ¥ + + 默认情况下,`pwd' 的行为和带 `-L' 选项一致 + + 退出状æ€ï¼š + 除éžä½¿ç”¨äº†æ— æ•ˆé€‰é¡¹æˆ–者当å‰ç›®å½•ä¸å¯è¯»ï¼Œå¦åˆ™è¿”回状æ€ä¸º0。 + +[true] + 空的命令。 + + 没有效果; 此命令ä¸åšä»»ä½•æ“作。 + + 退出状æ€ï¼š + 总是æˆåŠŸã€‚ + +[shopt] + è®¾å®šå’Œå–æ¶ˆè®¾å®š shell 选项。 + + æ”¹å˜æ¯ä¸ª shell 选项 OPTNAME 的设定。ä¸å¸¦å‚数时, + 列出æ¯ä¸ªæä¾›çš„ OPTNAME,å¦åˆ™åˆ—出所有 shell 选项; + åŒæ—¶æ ‡æ³¨æ¯ä¸€ä¸ªé€‰é¡¹æ˜¯å¦è¢«è®¾å®šã€‚ + + 选项: + -o é™åˆ¶ OPTNAME 为定义用于`set -o' 的选项 + -p æ‰“å°æ¯ä¸ª shell 选项并标注它的状æ€ã€‚ + -q 抑制输出 + -s å¯ç”¨(设定)æ¯ä¸ª OPTNAME 选项 + -u ç¦ç”¨(å–æ¶ˆè®¾å®š)æ¯ä¸ª OPTNAME 选项 + + 退出状æ€ï¼š + 如果 OPTNAME 选项被å¯ç”¨åˆ™è¿”回æˆåŠŸï¼›å¦‚æžœæ˜¯ + 无效的选项或 OPTNAME 被ç¦ç”¨åˆ™å¤±è´¥ã€‚ + +[false] + è¿”å›žä¸€ä¸ªä¸æˆåŠŸçš„ç»“æžœã€‚ + + 退出状æ€ï¼š + 总是失败。 + +[command] + 执行一个简å•命令或者显示命令的相关信æ¯ã€‚ + + 带 ARGS 傿•°è¿è¡Œ COMMAND 命令且抑制 shell 函数查询,或显示 + 指定的 COMMAND 命令的信æ¯ã€‚å¯ä»¥åœ¨å­˜åœ¨ç›¸åŒå称的函数定义的 + 情况下用于å¯åЍç£ç›˜ä¸Šçš„命令。 + + 选项: + -p 使用 PATH å˜é‡çš„ä¸€ä¸ªé»˜è®¤å€¼ä»¥ç¡®ä¿æ‰€æœ‰çš„æ ‡å‡†å·¥å…·éƒ½èƒ½è¢«æ‰¾åˆ°ã€‚ + -v æ‰“å° COMMAND 命令的æè¿°ï¼Œå’Œ `type' 内建相似 + -V æ‰“å°æ¯ä¸ª COMMAND 命令的详细æè¿° + + é€€å‡ºçŠ¶æ€ + 返回 COMMAND 命令的返回状æ€ï¼Œæˆ–者当找ä¸åˆ° COMMAND 命令时失败。 + +[echo] + 将傿•°å†™åˆ°æ ‡å‡†è¾“出。 + + 在标准输出上,显示用空格分割的 ARG 傿•°åŽè·Ÿä¸€ä¸ªæ¢è¡Œã€‚ + + 选项: + -n ä¸è¦è¿½åŠ æ¢è¡Œ + -e å¯ç”¨ä¸‹åˆ—åæ–œæ è½¬ä¹‰çš„解释 + -E 显å¼åœ°æŠ‘åˆ¶å¯¹äºŽåæ–œæ è½¬ä¹‰çš„解释 + + `echo' å¯¹ä¸‹åˆ—åæ–œæ å­—符进行转义: + \a 警告(å“铃) + \\b 退格 + \\c 抑制更多的输出 + \\e 转义字符 + \\f æ¢é¡µå­—符 + \\tæ¢è¡Œ + \\r\t回车 + \\t\t横å‘制表符 + \\v\t纵å‘制表符 + \\\\\tåæ–œæ  + \\0nnn 以 NNN(八进制)为 ASCII ç çš„字符。NNN å¯ä»¥æ˜¯ 0 到 3 个八进制 + ä½ + \\xHH 以 HH(å六进制)为值的八比特字符。HH å¯ä»¥æ˜¯ä¸€ä¸ªæˆ–两个å六进制 + ä½ + \\uHHHH 以 HHHH(å六进制)为值的 Unicode 字符。HHHH å¯ä»¥æ˜¯ä¸€ä¸ªåˆ° + 四个å六进制ä½ã€‚ + \\UHHHHHHHH 以 HHHHHHHH(å六进制)为值的 Unicode 字符。 + HHHHHHHH å¯ä»¥æ˜¯ä¸€åˆ°å…«ä¸ªå六进制ä½ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžæœ‰å†™é”™è¯¯å‘生。 + + 写傿•°è‡³æ ‡å‡†è¾“出设备。 + + 在标准输出设备上显示 ARGs 傿•°å’Œä¸€ä¸ªæ¢è¡Œã€‚ + + 选项: + -n ä¸é™„加æ¢è¡Œ + + 退出状æ€ï¼š + 除éžå†™é”™è¯¯å‘生,å¦åˆ™è¿”回æˆåŠŸã€‚ + +[enable] + å¯ç”¨å’Œç¦ç”¨ shell 内建。 + + å¯ç”¨å’Œç¦ç”¨ shell 的内建命令。ç¦ç”¨ä½¿æ‚¨èƒ½å¤Ÿæ‰§è¡Œä¸€ä¸ªå’Œå†…建 + 命令åŒåçš„ç£ç›˜ä¸Šçš„命令,而无须使用完整的路径å。 + + + 选项: + -a 打å°ä¸€ä¸ªå†…建的列表,并显示其中æ¯ä¸€ä¸ªæ˜¯å¦å¯ç”¨ + -n ç¦ç”¨æ¯ä¸€ä¸ª NAME 内建或者显示一个被ç¦ç”¨çš„内建的列表 + -p 以å¯é‡ç”¨çš„æ ¼å¼æ‰“å°ä¸€ä¸ªå†…建的列表 + -s 仅打å°Posix `special' 内建的åç§° + + 控制动æ€åŠ è½½çš„é€‰é¡¹ï¼š + -f 从共享对象 FILENAME 文件中加载 NAME 内建 + -d 删除以 -f 选项加载的内建 + + ä¸å¸¦é€‰é¡¹æ—¶ï¼Œæ¯ä¸€ä¸ª NAME 内建都被å¯ç”¨ã€‚ + + 如果è¦ä½¿ç”¨ $PATH 中找到的 `test' è€Œä¸æ˜¯ shell 内建的版本, + 输入 `enable -n test'。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éž NAME 䏿˜¯ä¸€ä¸ª shell 内建或者有错误å‘生。 + +[getopts] + è§£æžé€‰é¡¹å‚数。 + + getopts 被 shell 过程用于解æžå¯å®šä½çš„傿•°ä½œä¸ºé€‰é¡¹ã€‚ + + + OPTSTRING 字符串包å«å¾…识别的选项字æ¯ï¼›å¦‚果一个字æ¯åŽé¢è·Ÿ + ç€åˆ†å·ï¼Œåˆ™è¯¥é€‰é¡¹éœ€è¦ä¸€ä¸ªå‚æ•°ï¼Œè€Œè¯¥å‚æ•°åº”用空格与选项分开。 + + + æ¯æ¬¡å¯åŠ¨æ—¶ï¼Œgetopts 会将下一个选项放到 shell å˜é‡ $name + 中,如果 name å˜é‡ä¸å­˜åœ¨åˆ™å…ˆå°†å…¶åˆå§‹åŒ–,而下一个待处 + ç†çš„傿•°åºå·æ”¾å…¥ shell å˜é‡ OPTIND 中。OPTIND å˜é‡åœ¨æ¯ + 次 shell 或者 shell 脚本å¯åŠ¨æ—¶éƒ½è¢«åˆå§‹åŒ–为1ã€‚å½“ä¸€ä¸ªé€‰é¡¹è¦ + æ±‚æœ‰ä¸€ä¸ªå‚æ•°æ—¶ï¼Œgetopts 将傿•°æ”¾å…¥ shell å˜é‡ OPTARG + 中。 + + getopts æœ‰ä¸¤ç§æŠ¥å‘Šé”™è¯¯çš„æ–¹æ³•ã€‚å¦‚æžœ OPTSTRING å˜é‡çš„第 + 一个字符是冒å·ï¼Œgetopts ä½¿ç”¨æ²‰é»˜é”™è¯¯æŠ¥å‘Šã€‚åœ¨è¿™ç§æ¨¡å¼ + 下,ä¸ä¼šæ‰“å°é”™è¯¯æ¶ˆæ¯ã€‚如果看到了一个无效的选项, + getopts 将找到的选项字符放至 OPTARG å˜é‡ä¸­ã€‚如果一个必 + 须的选项没有找到,getopts 放一个 ':' 到 NAME å˜é‡ä¸­å¹¶ä¸”设 + ç½® OPTARG å˜é‡ä¸ºæ‰¾åˆ°çš„选项字符。如果 getopts ä¸åœ¨æ²‰é»˜æ¨¡ + å¼ä¸­ï¼Œå¹¶ä¸”é‡åˆ°äº†ä¸€ä¸ªæ— æ•ˆçš„选项,getopts 放置一个 '?' 到 NAME + å˜é‡ä¸­å¹¶ä¸”å–æ¶ˆè®¾å®š OPTARGå˜é‡ã€‚如果必须的选项没有找到, + 一个'?'会被放入 NAMEå˜é‡ä¸­ï¼ŒOPTARG å°†è¢«å–æ¶ˆè®¾å®šï¼Œå¹¶ä¸”会 + 打å°ä¸€ä¸ªè¯Šæ–­ä¿¡æ¯ã€‚ + + 如果 shell å˜é‡ OPTERR 的值为0,getopts ç¦ç”¨ + 错误信æ¯çš„æ‰“å°ï¼Œå³ä½¿ OPTSTRING å˜é‡çš„ç¬¬ä¸€ä¸ªå­—ç¬¦ä¸æ˜¯ä¸€ + 个冒å·ã€‚OPTERR 的默认值为1. + + getopts 通常解æžå¯å®šä½çš„傿•°($0 - $9),ä¸è¿‡å¦‚æžœæä¾›äº† + æ›´å¤šçš„å‚æ•°ï¼Œå®ƒä»¬å而会被解æžã€‚ + + 退出状æ€ï¼š + 如果一个选项被找到则返回æˆåŠŸï¼›å¦‚æžœé‡åˆ°äº†é€‰é¡¹çš„结尾或者 + 有错误å‘生则返回失败。 + +[exec] + ä½¿ç”¨æŒ‡å®šå‘½ä»¤æ›¿æ¢ shell。 + + 执行 COMMAND å‘½ä»¤ï¼Œä»¥æŒ‡å®šçš„ç¨‹åºæ›¿æ¢è¿™ä¸ª shell。 + ARGUMENTS 傿•°æˆä¸º COMMANDå‘½ä»¤çš„å‚æ•°ã€‚如果 + 没有指定COMMAND 命令,则任何的é‡å®šå‘åœ¨å½“å‰ shell 中生效。 + + 选项: + -a åç§° 作为第0ä¸ªå‚æ•°ä¼ é€’ç»™ COMMAND 命令 + -c 在一个空环境中执行 COMMAND 命令 + -l 在COMMAND 命令的第0ä¸ªå‚æ•°ä¸­åŠ ä¸€ä¸ªçŸ­çº¿ + + 如果命令ä¸èƒ½è¢«æ‰§è¡Œï¼Œåˆ™é€€å‡ºä¸€ä¸ªéžäº¤äº’å¼çš„ shellï¼Œé™¤éž + shell 选项`execfail' å·²ç»è®¾å®šã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éž COMMAND 命令没有找到或者出现一个é‡å®šå‘错误。 + +[exit] + 退出shell。 + + ä»¥çŠ¶æ€ N 退出 shell。 如果 N 被çœç•¥ï¼Œåˆ™é€€å‡ºçŠ¶æ€ + 为最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的退出状æ€ã€‚ + +[logout] + 退出一个登录 shell. + + ä»¥çŠ¶æ€ N 退出一个登录 shell。如果ä¸åœ¨ç™»å½• shell 中执行,则 + 返回一个错误。 + +[fc] + 从历å²åˆ—表中显示或者执行命令。 + + fc 被用于从历å²åˆ—è¡¨ä¸­åˆ—å‡ºæˆ–è€…é‡æ–°ç¼–辑并执行命令。 + FIRST å’Œ LAST å˜é‡å¯ä»¥æ˜¯æ•°å­—用于指定范围,或者 FIRST å¯ä»¥æ˜¯ + 字符串,æ„味ç€ä»¥è¿™ä¸ªå­—符串打头的最近的一个命令。 + + + 选项: + -e ENAME 选择使用哪个编辑器。默认的是 FCEDIT, ç„¶åŽæ˜¯ EDITOR, + ç„¶åŽæ˜¯ vi + -l 列出行而ä¸ç¼–辑 + -n 列举时çœç•¥è¡Œå· + -r å转行的顺åº(最新行在å‰) + + 用 `fc -s [模å¼=æ›¿æ¢ ...] [命令]' 的格å¼ï¼ŒCOMMAND 命令会在 OLD=NEW + 替æ¢ä¹‹åŽè¢«é‡æ–°æ‰§è¡Œã€‚ + + r='fc -s' 是一个有用的别å,这样的è¯è¾“å…¥ `r cc'会执行最åŽä¸€ä¸ªä»¥ `cc' + 开头的命令,输入 `r'ä¼šé‡æ–°æ‰§è¡Œæœ€åŽä¸€ä¸ªå‘½ä»¤ã€‚ + + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œæˆ–è€…æ‰§è¡Œçš„å‘½ä»¤çš„çŠ¶æ€ï¼›å¦‚果错误å‘生则返回éžé›¶ã€‚ + +[fg] + 将任务移至å‰å°ã€‚ + + 将以 JOB_SPEC 标识的任务放至å‰å°ï¼Œä½¿å…¶æˆä¸º + 当å‰ä»»åŠ¡ã€‚å¦‚æžœ JOB_SPEC ä¸å­˜åœ¨ï¼Œshell 观念中的当å‰ä»»åŠ¡ + 将被使用。 + + 退出状æ€ï¼š + 放至å‰å°çš„命令状æ€ï¼Œæˆ–者当错误å‘生时为失败。 + +[bg] + 移动任务至åŽå°ã€‚ + + å°† JOB_SPEC 标识的任务放至åŽå°ï¼Œå°±åƒå®ƒä»¬ + 是带 `&' å¯åŠ¨çš„ä¸€æ ·ã€‚å¦‚æžœ JOB_SPEC ä¸å­˜åœ¨ï¼Œshell 观念中的 + 当å‰ä»»åŠ¡å°†ä¼šè¢«ä½¿ç”¨ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžä»»åŠ¡ç®¡ç†æ²¡æœ‰å¯ç”¨æˆ–者错误å‘生。 + +[hash] + è®°ä½æˆ–显示程åºä½ç½®ã€‚ + + ç¡®å®šå¹¶è®°ä½æ¯ä¸€ä¸ªç»™å®š NAME å称的命令的完整路径。 + å¦‚æžœä¸æä¾›å‚æ•°ï¼Œåˆ™æ˜¾ç¤ºå·²ç»è®°ä½çš„命令的信æ¯ã€‚ + + 选项: + -d 忘记æ¯ä¸€ä¸ªå·²ç»è®°ä½çš„ NAME çš„ä½ç½® + -l 以å¯ä½œä¸ºè¾“å…¥é‡ç”¨çš„æ ¼å¼æ˜¾ç¤º + -p pathname 使用 pathname 路径作为 NAME 命令的全路径 + -r 忘记所有记ä½çš„ä½ç½® + -t 打å°è®°ä½çš„æ¯ä¸€ä¸ª NAME åç§°çš„ä½ç½®ï¼Œå¦‚果指定了多个 + NAME å称,则æ¯ä¸ªä½ç½®å‰é¢ä¼šåŠ ä¸Šç›¸åº”çš„ NAME åç§° + + 傿•°ï¼š + NAME æ¯ä¸ª NAME å称会在 $PATH 路径å˜é‡ä¸­è¢«æœç´¢ï¼Œå¹¶ä¸”添加到记ä½çš„命 + 令 + 列表中。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éž NAME 命令没有找到或者使用了无效的选项。 + +[help] + 显示内建命令的相关信æ¯ã€‚ + + 显示内建命令的简略信æ¯ã€‚如果指定了 PATTERN 模å¼ï¼Œ + ç»™å‡ºæ‰€æœ‰åŒ¹é… PATTERN 模å¼çš„命令的详细帮助,å¦åˆ™æ‰“ + å°ä¸€ä¸ªå¸®åŠ©ä¸»é¢˜åˆ—è¡¨ + + 选项: + -d 输出æ¯ä¸ªä¸»é¢˜çš„简短æè¿° + -m 以伪 man æ‰‹å†Œçš„æ ¼å¼æ˜¾ç¤ºä½¿ç”¨æ–¹æ³• + -s 为æ¯ä¸€ä¸ªåŒ¹é… PATTERN 模å¼çš„主题仅显示一个用法 + 简介 + + 傿•°ï¼š + PATTERN æŒ‡å®šå¸®åŠ©ä¸»é¢˜çš„æ¨¡å¼ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžæœªæ‰¾åˆ° PATTERN æ¨¡å¼æ²¡æœ‰æ‰¾åˆ°æˆ–者使用了无效选项。 + +[history] + 显示或æ“纵历å²åˆ—表。 + + å¸¦è¡Œå·æ˜¾ç¤ºåކå²åˆ—表,将æ¯ä¸ªè¢«ä¿®æ”¹çš„æ¡ç›®åŠ ä¸Š `*' å‰ç¼€ã€‚ + 傿•° N 会仅列出最åŽçš„ N 个æ¡ç›®ã€‚ + + 选项: + -c 删除所有æ¡ç›®ä»Žè€Œæ¸…空历å²åˆ—表。 + -d åç§»é‡ ä»ŽæŒ‡å®šä½ç½®åˆ é™¤åކå²åˆ—表。负åç§»é‡å°†ä»Žåކ岿¡ç›®æœ«å°¾ + 开始计数 + + -a 将当å‰ä¼šè¯çš„历å²è¡Œè¿½åŠ åˆ°åŽ†å²æ–‡ä»¶ä¸­ + -n ä»ŽåŽ†å²æ–‡ä»¶ä¸­è¯»å–所有未被读å–的行 + 并且将它们附加到历å²åˆ—表 + -r 读å–åŽ†å²æ–‡ä»¶å¹¶å°†å†…容追加到历å²åˆ—表中 + -w 将当å‰åކå²å†™å…¥åˆ°åކ岿–‡ä»¶ä¸­ + + -p 对æ¯ä¸€ä¸ª ARG 傿•°å±•开历å²å¹¶æ˜¾ç¤ºç»“果,而ä¸å­˜å‚¨åˆ°åކå²åˆ—表中 + -s 以啿¡è®°å½•追加 ARG 到历å²åˆ—表中 + + 如果给定了 FILENAME 文件åï¼Œåˆ™å®ƒå°†è¢«ä½œä¸ºåŽ†å²æ–‡ä»¶ã€‚å¦åˆ™ + 如果 $HISTFILE å˜é‡æœ‰å€¼çš„è¯ä½¿ç”¨ä¹‹ï¼Œä¸ç„¶ä½¿ç”¨ ~/.utshell_history 文件。 + + 如果 $HISTTIMEFORMAT å˜é‡è¢«è®¾å®šå¹¶ä¸”ä¸ä¸ºç©ºï¼Œå®ƒçš„值会被用于 + strftime(3) 的格å¼å­—ç¬¦ä¸²æ¥æ‰“å°ä¸Žæ¯ä¸€ä¸ªæ˜¾ç¤ºçš„åŽ†å²æ¡ç›®æƒ³å…³è”çš„ + 时间戳,å¦åˆ™ä¸æ‰“å°æ—¶é—´æˆ³ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者å‘生错误。 + +[jobs] + 显示任务状æ€ã€‚ + + 列出活动的任务。JOBSPEC é™åˆ¶ä»…输出指定的任务。 + ä¸å¸¦é€‰é¡¹æ—¶ï¼Œæ‰€æœ‰æ´»åŠ¨ä»»åŠ¡çš„çŠ¶æ€éƒ½ä¼šæ˜¾ç¤ºã€‚ + + 选项: + -l 在正常信æ¯åŸºç¡€ä¸Šåˆ—å‡ºè¿›ç¨‹å· + -n ä»…åˆ—å‡ºä¸Šæ¬¡é€šå‘Šä¹‹åŽæ”¹å˜äº†çжæ€çš„进程 + -p ä»…åˆ—å‡ºè¿›ç¨‹å· + -r é™åˆ¶ä»…输出è¿è¡Œä¸­çš„任务 + -s é™åˆ¶ä»…è¾“å‡ºåœæ­¢çš„任务 + + 如果使用了 -x 选项,ARG 傿•°ä¸­çš„æ‰€æœ‰ä»»åŠ¡å£°æ˜Žä¼šè¢«æ›¿æ¢ä¸ºè¯¥ä»»åŠ¡ + 的进程组头领的进程å·ï¼Œç„¶åŽæ‰§è¡Œ COMMAND 命令。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者有错误å‘生。 + 如果使用 -x 选项,则返回 COMMAND 命令的退出状æ€ã€‚ + +[disown] + ä»Žå½“å‰ shell 中删除任务。 + + 从活动任务表中删除æ¯ä¸€ä¸ª JOBSPEC 傿•°ã€‚ä¸å¸¦ä»»ä½• + JOBSPEC 傿•°æ—¶ï¼Œshell 使用观念中的当å‰ä»»åŠ¡ã€‚ + + 选项: + -a å¦‚æžœä¸æä¾› JOBSPEC 傿•°ï¼Œåˆ™åˆ é™¤æ‰€æœ‰ä»»åŠ¡ + -h 标识æ¯ä¸ª JOBSPEC 任务,从而当 shell 接收到 SIGHUP + ä¿¡å·æ—¶ä¸å‘é€ SIGHUP 给指定任务 + -r 仅删除è¿è¡Œä¸­çš„任务 + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 JOBSPEC 声明。 + +[kill] + å‘一个任务å‘é€ä¸€ä¸ªä¿¡å·ã€‚ + + å‘以 PID è¿›ç¨‹å·æˆ–者 JOBSPEC 任务声明指定的进程å‘é€ä¸€ä¸ªä»¥ + SIGSPEC ä¿¡å·å£°æ˜Žæˆ– SIGNUM ä¿¡å·ç¼–å·å‘½å的信å·ã€‚如果没有指定 + SIGSPEC 或 SIGNUM,那么å‡å®šå‘é€ SIGTERM ä¿¡å·ã€‚ + + 选项: + -s sig SIG 是信å·åç§° + -n sig SIG 是信å·ç¼–å· + -l 列出信å·åç§°ï¼›å¦‚æžœå‚æ•°åŽè·Ÿ `-l'则被å‡è®¾ä¸ºä¿¡å·ç¼–å·ï¼Œ + 而相应的信å·å称会被列出 + + Kill æˆä¸º shell 内建有两个ç†ç”±ï¼šå®ƒå…许使用任务编å·è€Œä¸æ˜¯è¿›ç¨‹å·ï¼Œ + 并且在å¯ä»¥åˆ›å»ºçš„进程数上é™è¾¾åˆ°æ˜¯å…è®¸è¿›ç¨‹è¢«æ€æ­»ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者有错误å‘生。 + +[let] + 估值算术表达å¼ã€‚ + + å°†æ¯ä¸ª ARG å‚èµ›ä½œä¸ºç®—æœ¯è¡¨è¾¾å¼æ¥ä¼°å€¼ã€‚估值的计算以定宽的整 + 数完æˆï¼Œä¸å¸¦æº¢å‡ºæ£€æµ‹ï¼Œä¸è¿‡é™¤ 0 是被置陷阱的并且会报一个错 + 误。下列æ“作符被按照相åŒçš„算术优先级组åˆã€‚åˆ—è¡¨çš„é¡ºåºæŒ‰ç…§ + 优先级从高至低。 + + id++, id-- å˜é‡åŽç½®åŠ ï¼ŒåŽç½®å‡ + ++id, --id å˜é‡å‰ç½®åŠ ï¼Œå‰ç½®å‡ + -, + ä¸€å…ƒå‡æ³•,一元加法 + !, ~ 逻辑和ä½å–å + '**' 指数 + '*', /, '%' 乘法,除法,å–余数 + +, - 增加,å‡å°‘ + <<, >> å‘左和å‘峿Œ‰ä½ç§»ä½ + <=, >=, <, > 比较 + ==, != 等于,ä¸ç­‰äºŽ + & 按ä½ä¸Ž + ^ 按ä½å¼‚或 + | æŒ‰ä½æˆ– + && 逻辑与 + || 逻辑或 + expr ? expr : expr + æ¡ä»¶æ“作符 + =, *=, /=, %=, + +=, -=, <<=, >>=, + &=, ^=, |= 赋值 + + Shell å˜é‡å…许作为æ“作数。表达å¼ä¸­çš„å˜é‡çš„å称会被å–代以值 + (强制转æ¢ä¸ºå®šå®½çš„æ•´æ•°)。表达å¼ä¸­çš„å˜é‡ä¸éœ€è¦æ‰“开整数属性。 + + æ“作符按照优先级进行估值。括å·ä¸­çš„å­è¡¨è¾¾å¼å°†è¢«å…ˆä¼°å€¼ï¼Œå¹¶å¯å–ä»£ä¸Šè¿°è¡¨è¾¾å¼ + 规则。 + + 退出状æ€ï¼š + 如果最åŽä¸€ä¸ª ARG 傿•°ä¼°å€¼ä¸º 0,则 let 返回 1ï¼› å¦åˆ™ let 返回 0。 + +[shift] + ç§»ä½ä½ç½®å‚数。 + + é‡å‘½åä½ç½®å‚æ•° $N+1ã€$N+2 ... 到 $1ã€$2 ... 如果没有给定 N, + 则å‡è®¾ä¸º1. + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éž N 为负或者大于 $#。 + 返回 N,或者如果 shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ªå‡½æ•°æˆ–引用脚本时,失败。 + +[suspend] + 挂起 shell 执行。 + + 挂起 shell 的执行直到收到 SIGCONT ä¿¡å·ã€‚ + 登录 shell ä¸å¯ä»¥è¢«æŒ‚起,除éžå¼ºåˆ¶æ‰§è¡Œã€‚ + + 选项: + -f 强制挂起,å³ä½¿æ˜¯ç™»å½• shell。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžæ²¡æœ‰å¯ç”¨ä»»åŠ¡æŽ§åˆ¶æˆ–è€…æœ‰é”™è¯¯å‘生。 + +[test] + 对æ¡ä»¶è¡¨è¾¾å¼è¿›è¡Œä¼°å€¼ã€‚ + + æ ¹æ® EXPR 表达å¼çš„ä¼°å€¼ä»¥çŠ¶æ€ 0 (真) 或 1 (伪) 退出。 + 表达å¼å¯ä»¥æ˜¯ä¸€å…ƒæˆ–者二元的。一元表达å¼é€šå¸¸ç”¨äºŽæ£€æµ‹ + 文件状æ€ã€‚åŒæ—¶è¿˜æœ‰å­—符串æ“作符和数字比较æ“作符。 + + 文件æ“作符: + + -a 文件 如果文件存在则为真。 + -b 文件 如果文件为å—特殊文件则为真。 + -c 文件 如果文件为字符特殊文件则为真。 + -d 文件 如果文件为目录则为真。 + -e 文件 如果文件存在则为真。 + -f 文件 如果文件存在且为常规文件则为真。 + -g 文件 如果文件的组属性设置打开则为真。 + -h 文件 如果文件为符å·é“¾æŽ¥åˆ™ä¸ºçœŸã€‚ + -L 文件 如果文件为符å·é“¾æŽ¥åˆ™ä¸ºçœŸã€‚ + -k 文件 如果文件的粘滞 (sticky) ä½è®¾å®šåˆ™ä¸ºçœŸã€‚ + -p 文件 如果文件为命å管é“则为真。 + -r 文件 如果文件对于您是å¯è¯»çš„则为真。 + -s 文件 如果文件存在且ä¸ä¸ºç©ºåˆ™ä¸ºçœŸã€‚ + -S 文件 如果文件是套接字则为真。 + -t 文件æè¿°ç¬¦ 如果文件æè¿°ç¬¦åœ¨ä¸€ä¸ªç»ˆç«¯ä¸Šæ‰“开则为真。 + -u 文件 如果文件的用户数行设置打开则为真。 + -w 文件 如果文件对您是å¯å†™çš„则为真 + -x 文件 å¦‚æžœæ–‡ä»¶å¯¹æ‚¨æ˜¯å¯æ‰§è¡Œçš„则为真。 + -O 文件 如果文件是被您所有的则为真。 + -G 文件 如果文件被您的组所有则为真。 + -N 文件 如果文件上次被读å–之åŽä¿®æ”¹è¿‡åˆ™ä¸ºçœŸã€‚ + + FILE1 -nt FILE2 如果 file1 文件新于 file2 文件则为真(æ ¹æ® + 修改日期)。 + + FILE1 -ot FILE2 如果 file1 文件旧于 file2 文件则为真。 + + FILE1 -ef FILE2 如果 file1 文件是 file2 文件的硬链接则为真。 + + 字符串æ“作符 + + -z 字符串 如果字符串为空则为真。 + + -n 字符串 + 字符串 如果字符串ä¸ä¸ºç©ºåˆ™ä¸ºçœŸã€‚ + + STRING1 = STRING2 + 如果 string1 å’Œ string2 字符串相åŒåˆ™ä¸ºçœŸã€‚ + STRING1 != STRING2 + 如果 string1 å’Œ string2 字符串ä¸ç›¸åŒåˆ™ä¸ºçœŸã€‚ + STRING1 < STRING2 + å¦‚æžœæŒ‰å­—å…¸æŽ’åº string1 在 string2 串之å‰åˆ™ä¸ºçœŸã€‚ + STRING1 > STRING2 + å¦‚æžœæŒ‰å­—å…¸æŽ’åº string1 在 string2 串之å‰åˆ™ä¸ºçœŸã€‚ + + å…¶ä»–æ“作符: + + -o 选项 如果指定 shell 选项å¯ç”¨åˆ™ä¸ºçœŸã€‚ + -v VAR 如果指定 Shell å˜é‡ VAR 已赋值则为真。 + -R VAR 如果指定 Shell å˜é‡ VAR 已赋值且为å称引用则为真。 + ! EXPR å¦‚æžœè¡¨è¾¾å¼ expr 为å‡åˆ™ä¸ºçœŸã€‚ + EXPR1 -a EXPR2 如果 expr1 å’Œ expr2 都为真则为真。 + EXPR1 -o EXPR2 如果 expr1 å’Œ expr2 有一个为真则为真。 + + arg1 OP arg2 算术测试。OPæ“作符å¯ä»¥æ˜¯ -eqã€-ne〠+ -ltã€-leã€-gtã€æˆ– -ge 中的一个。 + + 二元算术æ“作返回真,如果 ARG1 傿•°ç­‰äºŽã€ä¸ç­‰äºŽã€ + å°äºŽã€å°äºŽç­‰äºŽã€å¤§äºŽã€æˆ–者大于等于 ARG2 傿•°ã€‚ + + 退出状æ€ï¼š + 如果 EXPR 表达å¼ä¼°å€¼ä¸ºçœŸåˆ™è¿”回æˆåŠŸï¼›å¦‚æžœ EXPR 表达å¼ä¼°å€¼ + ä¸ºå‡æˆ–è€…ä½¿ç”¨äº†æ— æ•ˆçš„å‚æ•°åˆ™è¿”回失败。 + +[eval] + 将傿•°ä½œä¸º shell 命令执行。 + + å°† ARGs åˆæˆä¸€ä¸ªå­—符串,用结果作为 shell 的输入, + 并且执行得到的命令。 + + 退出状æ€ï¼š + 以命令的状æ€é€€å‡ºï¼Œæˆ–者在命令为空的情况下返回æˆåŠŸã€‚ + +[times] + 显示进程时间 + + æ‰“å° shell åŠå…¶æ‰€æœ‰å­è¿›ç¨‹çš„累计用户空间和 + 系统空间执行时间。 + + é€€å‡ºçŠ¶æ€ + 总是æˆåŠŸã€‚ + +[ulimit] + 修改 shell 资æºé™åˆ¶ã€‚ + + 在å…许此类控制的系统上,æä¾›å¯¹äºŽ shell åŠå…¶åˆ›å»ºçš„进程所å¯ç”¨çš„ + 资æºçš„æŽ§åˆ¶ã€‚ + + 选项: + -S 使用软 (`soft') 资æºé™åˆ¶ + -H 使用硬 (`hard') 资æºé™åˆ¶ + -a 所有当å‰é™åˆ¶éƒ½è¢«æŠ¥å‘Š + -b 套接字缓存尺寸 + -c 创建的核文件的最大尺寸 + -d 一个进程的数æ®åŒºçš„æœ€å¤§å°ºå¯¸ + -e 最高的调度优先级 (`nice') + -f 有 shell åŠå…¶å­è¿›ç¨‹å¯ä»¥å†™çš„æœ€å¤§æ–‡ä»¶å°ºå¯¸ + -i 最多的å¯ä»¥æŒ‚èµ·çš„ä¿¡å·æ•° + -k 分é…给此进程的最大 kqueue æ•°é‡ + -l 一个进程å¯ä»¥é”定的最大内存尺寸 + -m 最大的内存进驻尺寸 + -n 最多的打开的文件æè¿°ç¬¦ä¸ªæ•° + -p 管é“缓冲区尺寸 + -q POSIX ä¿¡æ¯é˜Ÿåˆ—的最大字节数 + -r 实时调度的最大优先级 + -s 最大栈尺寸 + -t 最大的CPU时间,以秒为å•ä½ + -u 最大用户进程数 + -v 虚拟内存尺寸 + -x æœ€å¤§çš„æ–‡ä»¶é”æ•°é‡ + -P æœ€å¤§ä¼ªç»ˆç«¯æ•°é‡ + -T æœ€å¤§çº¿ç¨‹æ•°é‡ + + å¹¶éžæ‰€æœ‰é€‰é¡¹åœ¨æ‰€æœ‰ç³»ç»Ÿä¸Šå¯ç”¨ã€‚ + + 如果æä¾›äº† LIMIT å˜é‡ï¼Œåˆ™å®ƒä¸ºæŒ‡å®šèµ„æºçš„æ–°çš„值;特别的 LIMIT 值为 + `soft'ã€`hard'å’Œ`unlimited',分别表示当å‰çš„软é™åˆ¶ï¼Œç¡¬é™åˆ¶å’Œæ— é™åˆ¶ã€‚ + å¦åˆ™æ‰“å°æŒ‡å®šèµ„æºçš„当å‰é™åˆ¶å€¼ï¼Œä¸å¸¦é€‰é¡¹åˆ™å‡å®šä¸º -f + + å–值都是 1024 字节为å•ä½ï¼Œé™¤äº† -t 以秒为å•ä½ï¼Œ-p 以 512 字节递增, + -u 为无范围的进程数é‡ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者错误å‘生。 + +[umask] + æ˜¾ç¤ºæˆ–è®¾å®šæ–‡ä»¶æ¨¡å¼æŽ©ç ã€‚ + + 设定用户文件创建掩ç ä¸º MODE 模å¼ã€‚如果çœç•¥äº† MODE,则 + 打å°å½“剿ީç çš„值。 + + 如果 MODE 模å¼ä»¥æ•°å­—开头,则被当作八进制数解æžï¼›å¦åˆ™æ˜¯ä¸€ä¸ª + chmod(1) å¯æŽ¥æ”¶çš„ç¬¦å·æ¨¡å¼ä¸²ã€‚ + + 选项: + -p 如果çœç•¥ MODE 模å¼ï¼Œä»¥å¯é‡ç”¨ä¸ºè¾“入的格å¼è¾“å…¥ + -S 以符å·å½¢å¼è¾“出,å¦åˆ™ä»¥å…«è¿›åˆ¶æ•°æ ¼å¼è¾“出 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„ MODE æ¨¡å¼æˆ–者选项。 + +[wait] + 等待任务完æˆå¹¶è¿”回退出状æ€ã€‚ + + 等待以 ID ç¼–å·è¯†åˆ«çš„进程,其中 ID å¯ä»¥æ˜¯è¿›ç¨‹ç¼–å·æˆ–者任务声明, + 并报告它的终止状æ€ã€‚如果 ID æ²¡æœ‰ç»™å‡ºï¼Œåˆ™ç­‰å¾…æ‰€æœ‰çš„å½“å‰æ´»è·ƒå­ + 进程,并且返回状æ€ä¸ºé›¶ã€‚如果 ID 是任务声明,等待任务管é“中的 + 所有进程。 + + 若给定了 -n 选项,等待下一个任务完æˆå¹¶è¿”回其状æ€ã€‚ + + 若给定了 -f 选项,且已å¯ç”¨äº†ä»»åŠ¡æŽ§åˆ¶ï¼Œåˆ™ç­‰å¾…æŒ‡å®šçš„ ID 终止 + 而éžç­‰å¾…它改å˜çжæ€ã€‚ + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ª ID 进程的状æ€ï¼›å¦‚果使用了无效的 ID 或者选项则失败。 + +[return] + 从一个 shell 函数返回。 + + 使一个函数或者被引用的脚本以指定的返回值 N 退出。 + 如果 N 被çœç•¥ï¼Œåˆ™è¿”回状æ€å°±æ˜¯ + 函数或脚本中的最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + + 退出状æ€ï¼š + 返回 N,或者如果 shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ªå‡½æ•°æˆ–引用脚本时,失败。 + +[for] + 为列表中的æ¯ä¸ªæˆå‘˜æ‰§è¡Œå‘½ä»¤ã€‚ + + “forâ€å¾ªçŽ¯ä¸ºåˆ—è¡¨ä¸­çš„æ¯ä¸ªæˆå‘˜æ‰§è¡Œä¸€ç³»åˆ—的命令。如果没有 + “in <è¯è¯­> ...;â€åˆ™å‡å®šä½¿ç”¨â€œin \$@\â€ã€‚对于 <è¯è¯­> ä¸­çš„æ¯ + 个元素,<åç§°> å˜é‡è¢«è®¾å®šä¸ºè¯¥å…ƒç´ åŽæ‰§è¡Œ <命令>。 + + 退出状æ€ï¼š + è¿”å›žæœ€åŽæ‰§è¡Œçš„命令的状æ€ã€‚ + +[select] + 从列表中选å–è¯å¹¶ä¸”执行命令。 + + <è¯è¯­...> 被展开,生æˆä¸€ä¸ªè¯çš„列表。展开的è¯é›†åˆè¢«æ‰“å° + 在标准错误输出设备上,æ¯ä¸ªä»¥ä¸€ä¸ªæ•°å­—åšå‰ç¼€ã€‚如果没有 `in WORDS' + 则å‡å®šä½¿ç”¨`in \$@\'。PS3æç¤ºç¬¦ä¼šè¢«æ˜¾ç¤ºå¹¶ä¸”从标准输入读入一行 + 如果该行由被显示的è¯å¯¹åº”的数字组æˆï¼Œåˆ™ NAME å˜é‡è¢«è®¾å®šä¸ºç›¸åº” + çš„è¯ã€‚如果行为空,则 WORDS å˜é‡å’Œæç¤ºç¬¦è¢«é‡æ–°æ˜¾ç¤ºã€‚如果读å–了 + 文件结æŸç¬¦ï¼Œåˆ™å‘½ä»¤å®Œæˆã€‚读入任何其他的值会导致 NAME å˜é‡è¢«è®¾å®š + 为空。读入的行被存放在å˜é‡ REPLY 中。COMMANDS å‘½ä»¤åœ¨æ¯æ¬¡é€‰æ‹© + ä¹‹åŽæ‰§è¡Œç›´åˆ°æ‰§è¡Œä¸€ä¸ª break 命令。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[time] + æŠ¥å‘Šç®¡é“æ‰§è¡Œçš„æ¶ˆè€—时间。 + + 执行 PIPELINE å¹¶ä¸”æ‰“å° PIPELINE 终结时实际时间ã€ç”¨æˆ· CPU 时间和系统 + CPU 时间的总结。 + + 选项: + -p 用å¯è¿ç§»çš„ POSIX æ ¼å¼æ‰“å°ç”¨æ—¶æ€»ç»“。 + + TIMEFORMAT å˜é‡çš„值被作为输出格å¼ã€‚ + + 退出状æ€ï¼š + 返回状æ€å³PIPELINE 的返回状æ€ã€‚ + +[case] + 基于模å¼åŒ¹é…æ¥æ‰§è¡Œå‘½ä»¤ã€‚ + + 基于 PATTERN 模å¼åŒ¹é…çš„è¯ WORD,有选择的执行 COMMANDS 命令。 + |' 用于分隔多个模å¼ã€‚ + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[if] + æ ¹æ®æ¡ä»¶æ‰§è¡Œå‘½ä»¤ã€‚ + + `if COMMANDS'列表被执行。如果退出状æ€ä¸ºé›¶ï¼Œåˆ™æ‰§è¡Œ`then COMMANDS' + 列表。å¦åˆ™æŒ‰é¡ºåºæ‰§è¡Œæ¯ä¸ª `elif COMMANDS'列表,并且如果它的退出状æ€ä¸º + 零,则执行对应的 `then COMMANDS' 列表并且 if 命令终止。å¦åˆ™å¦‚果存在的 + 情况下,执行 `else COMMANDS'åˆ—è¡¨ã€‚æ•´ä¸ªç»“æž„çš„é€€å‡ºçŠ¶æ€æ˜¯æœ€åŽä¸€ä¸ªæ‰§è¡Œ + 的命令的状æ€ï¼Œæˆ–者如果没有æ¡ä»¶æµ‹è¯•为真的è¯ï¼Œä¸ºé›¶ã€‚ + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[while] + åªè¦æµ‹è¯•æˆåŠŸå³æ‰§è¡Œå‘½ä»¤ã€‚ + + åªè¦åœ¨ `while' COMMANDS 中的最终命令返回结果为0,则 + 展开并执行 COMMANDS 命令。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[until] + 当测试ä¸åŒè¿‡æ—¶æ‰§è¡Œå‘½ä»¤ã€‚ + + `until' COMMANDS 命令的最终命令返回状æ€ä¸ä¸º 0 时, + 展开并执行 COMMANDS 命令。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[coproc] + 创建一个以 NAME 为å的副进程。 + + 异步执行 COMMANDS 命令,在执行 shell 中的数组å˜é‡ NAME + çš„ 0 å·å’Œ 1 å·å…ƒç´ ä½œä¸ºæ–‡ä»¶æè¿°ç¬¦ï¼Œä»¥ä¸€ä¸ªç®¡é“连接命令 + 分别作为命令的标准输出和输入设备。 + 默认的 NAME 是 \COPROC\。 + + 退出状æ€ï¼š + å‰¯è¿›ç¨‹ä¼šè¿”å›žé€€å‡ºçŠ¶æ€ 0。 + +[variables] + 常用 shell å˜é‡å称和使用。 + + BASH_VERSION å½“å‰ Bash 的版本信æ¯ã€‚ + CDPATH 用于 `cd' 命令傿•°æœç´¢çš„分å·åˆ†éš”的目录列表 + GLOBIGNORE 路径扩展时忽略的文件ååŒ¹é…æ¨¡å¼åˆ—表, + 以分å·åˆ†éš”。 + HISTFILE 您的命令历å²å­˜æ”¾çš„æ–‡ä»¶å称。 + HISTFILESIZE åŽ†å²æ–‡ä»¶æœ€å¤šå¯ä»¥ä¿å­˜çš„行数。 + HISTSIZE 一个è¿è¡Œçš„ shell 最多å¯ä»¥è®¿é—®çš„历å²å‘½ä»¤è¡Œæ•°ã€‚ + HOME 您的登录目录的完整路径。 + HOSTNAME 当å‰ä¸»æœºçš„主机å。 + HOSTTYPE 当å‰ç‰ˆæœ¬çš„ BASH 在其之上è¿è¡Œçš„ CPU 类型。 + IGNOREEOF 控制 shell 收到文件结æŸç¬¦ä½œä¸ºå•一输入åŽçš„ + 动作。如果设定这个å˜é‡ï¼Œåˆ™å®ƒçš„值是 shell 退出之å‰åœ¨ + 一个空行上å¯ä»¥è¿žç»­çœ‹åˆ°çš„æ–‡ä»¶ç»“æŸç¬¦æ•°é‡(默认为10)。 + 未设定时,文件结æŸç¬¦æ ‡å¿—ç€è¾“入的结æŸã€‚ + MACHTYPE æè¿°å½“å‰è¿è¡Œ Bash 的系统的字符串。 + MAILCHECK Bash 检测新邮件的频率,以秒为å•ä½ã€‚ + MAILPATH Bash 从中检测新邮件的文件列表,以分å·åˆ†éš”。 + OSTYPE è¿è¡Œ Bash çš„ Unix 版本。 + PATH 当寻找命令时æœç´¢çš„目录列表,以冒å·åˆ†éš”。 + PROMPT_COMMAND æ‰“å°æ¯ä¸€ä¸ªä¸»æç¤ºç¬¦ä¹‹å‰æ‰§è¡Œçš„命 + 令。 + PS1 主æç¤ºç¬¦å­—符串。 + PS2 从æç¤ºç¬¦å­—符串。 + PWD 当å‰ç›®å½•的完整路径。 + SHELLOPTS å·²å¯ç”¨çš„ shell 选项列表,以冒å·åˆ†éš”。 + TERM 当å‰ç»ˆç«¯ç±»åž‹çš„å称。 + TIMEFORMAT 以关键则 `time' 显示的时间统计信æ¯çš„输出 + æ ¼å¼ã€‚ + auto_resume éžç©ºæ—¶ï¼Œä¸€ä¸ªå•独的命令è¯ä¼šé¦–å…ˆè¢«åœ¨å½“å‰ + åœæ­¢çš„任务列表中æœç´¢ã€‚如果找到则该任务被置于å‰å°ã€‚ + 如果值为 `exact' 则æ„味ç€å‘½ä»¤è¯å¿…须精确匹é…åœæ­¢ä»»åŠ¡ + 列表中的命令。如果值为 `substring' 则æ„味ç€å‘½ä»¤è¯å¿… + 须匹é…任务的一个å­å­—符串。任何其他的值æ„味ç€å‘½ä»¤è¯ + å¿…é¡»æ˜¯åœæ­¢ä»»åŠ¡çš„ä¸€ä¸ªå‰ç¼€ã€‚ + histchars 控制历å²å±•开和快速替æ¢çš„字符。第一个字符是 + åŽ†å²æ›¿æ¢å­—符,通常是 `!'。第二个字符是快速替æ¢å­—符, + 通常是 `^'ã€‚ç¬¬ä¸‰ä¸ªæ˜¯åŽ†å²æ³¨é‡Šå­—符,通常是 `#'。 + HISTIGNORE ç”¨äºŽå†³å®šå“ªäº›å‘½ä»¤è¢«å­˜å…¥åŽ†å²æ–‡ä»¶çš„æ¨¡å¼ + 列表,以冒å·åˆ†éš”。 + +[pushd] + 将目录添加到栈中。 + + å°†ç›®å½•æ·»åŠ åˆ°ç›®å½•æ ˆé¡¶ï¼Œæˆ–ç€æ—‹è½¬æ ˆç›´åˆ°å½“å‰å·¥ä½œç›®å½•æˆä¸º + 新的栈顶。ä¸å¸¦å‚æ•°æ—¶ï¼Œäº¤æ¢æ ˆé¡¶çš„两个目录。 + + 选项: + -n 抑制添加目录至栈时通常的改å˜ç›®å½•æ“作,从而仅对栈 + 进行æ“作。 + + 傿•°ï¼š + +N 旋转栈从而第 N 个目录 (`dirs' 显示的列表中左起,从零开始) + 将移动到栈顶。 + + -N 旋转栈从而第 N 个目录 (`dirs' 显示的列表中å³èµ·ï¼Œä»Žé›¶å¼€å§‹) + 将移动到栈顶。 + + dir å°† DIR 目录添加到栈顶,并且使其æˆä¸ºå½“å‰å·¥ä½œç›®å½•。 + + `dirs' 内建显示目录栈。 + + 退出状æ€ï¼š + +[popd] + 从栈中删除目录。 + + 从目录栈中删除æ¡ç›®ã€‚ä¸å¸¦å‚数时,删除栈顶目录,并改å˜è‡³æ–°çš„æ ˆ + 顶目录。 + + 选项: + -n æŠ‘åˆ¶ä»Žæ ˆä¸­åˆ é™¤ç›®å½•æ—¶é€šå¸¸çš„ç›®å½•å˜æ¢æ“作,从而仅对栈 + 进行æ“作。 + + 傿•°ï¼š + +N 删除第 N 个目录 (`dirs' 显示的目录列表中左起,从零开始)。 + 例如:`popd +0' 删除第一个目录,`popd +1' 删除第二个。 + + -N 删除第 N 个目录 (`dirs' 显示的目录列表中å³èµ·ï¼Œä»Žé›¶å¼€å§‹)。 + 例如:`popd -0' 删除最åŽä¸€ä¸ªç›®å½•,,`popd -1' 删除倒数第二个。 + + `dirs' 内建显示目录栈。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„傿•°æˆ–è€…ç›®å½•å˜æ¢å¤±è´¥ã€‚ + +[dirs] + 显示目录栈。 + + 显示当å‰è®°ä½çš„目录列表。通过 `pushd' 命令å¯ä»¥å°†ç›®å½•存入列表 + 中;`popd' 命令å¯ç”¨äºŽé历弹出列表。 + + 选项: + -c 删除所有元素以清空目录栈 + -l 䏿‰“å°ä¸Žä¸»ç›®å½•相关的波浪å·å‰ç¼€çš„目录 + -p æ¯è¡Œä¸€ä¸ªæ¡ç›®æ‰“å°ç›®å½•æ ˆ + -v æ¯è¡Œä¸€ä¸ªæ¡ç›®ï¼Œä»¥æ ˆä¸­ä½ç½®ä¸ºå‰ç¼€æ‰“å°ç›®å½•æ ˆ + + 傿•°ï¼š + +N 显示 dirs ä¸å¸¦é€‰é¡¹å¯åŠ¨æ—¶æ˜¾ç¤ºçš„ç›®å½•åˆ—è¡¨å·¦èµ·ä¸­ç¬¬ + N 个目录,从零开始。 + + -N 显示 dirs ä¸å¸¦é€‰é¡¹å¯åŠ¨æ—¶æ˜¾ç¤ºçš„ç›®å½•åˆ—è¡¨å³èµ·ä¸­ç¬¬ + N 个目录,从零开始。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者å‘生错误。 + +[printf] + 在 FORMAT 的控制下格å¼åŒ–å¹¶æ‰“å° ARGUMENTS 傿•°ã€‚ + + 选项: + -v var 将输出赋值给 shell å˜é‡ VAR è€Œä¸æ˜¾ç¤ºåœ¨æ ‡å‡†è¾“出上 + + FORMAT 是包å«ä¸‰ç§å¯¹è±¡çš„字符串:简å•地被拷è´åˆ°æ ‡å‡†è¾“出的普通字符; + è¢«å˜æ¢ä¹‹åŽæ‹·è´åˆ°æ ‡å‡†è¾“å…¥çš„è½¬ä¹‰å­—ç¬¦ï¼›ä»¥åŠæ¯ä¸ªéƒ½ä¼šå½±å“åˆ°ä¸‹ä¸ªå‚æ•°çš„æ‰“å°çš„æ ¼ + å¼åŒ–声明。 + + 在 printf(1) 中æè¿°çš„æ ‡å‡†æŽ§åˆ¶å£°æ˜Žä¹‹å¤–,printf è§£æžï¼š + + %b æ‰©å±•å¯¹åº”å‚æ•°ä¸­çš„åæ–œæ è½¬ä¹‰åºåˆ— + %q 以å¯ä½œä¸º shell 输入的格å¼å¼•ç”¨å‚æ•° + %(fmt)T 以 FMT 为供给 strftime(3) 的格å¼è¾“出日期时间字符串 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者写或赋值错误å‘生。 + +[complete] + 指定 Readline å¦‚ä½•è¡¥å…¨å‚æ•°ã€‚ + + 声明对于æ¯ä¸€ä¸ª NAME åç§°å¦‚ä½•è¡¥å…¨å‚æ•°ã€‚如果ä¸å¸¦é€‰é¡¹ï¼Œ + 现有的补全声明会以å¯ä»¥é‡ç”¨ä¸ºè¾“å…¥çš„æ ¼å¼æ‰“å°å‡ºæ¥ã€‚ + + 选项: + -p 以å¯é‡ç”¨çš„æ ¼å¼æ‰“å°çŽ°æœ‰çš„è¡¥å…¨å£°æ˜Žã€‚ + -r 对于æ¯ä¸ª NAME å称删除补全声明,或者如果没有æä¾› NAME + å称,删除所有的补全声明。 + -D 对于没有补全声明定义的命令,设定默认的补全动作 + -E 对于 \empty\ 命令设定补全动作,—— 对于空行的补全。 + -I 将补全和动作应用在首å•è¯ï¼ˆé€šå¸¸æ˜¯æ‰€ç»™å‘½ä»¤ï¼‰ä¸Š + + å°è¯•补全时,按照上述大写字æ¯é€‰é¡¹çš„顺åºè¿›è¡ŒåŠ¨ä½œã€‚ + 如果给出了多个选项,-D 选项优先级高于 -E 选项,且 + 这两个选项优先级å‡é«˜äºŽ -I。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者错误å‘生。 + +[compgen] + 便®é€‰é¡¹æ˜¾ç¤ºå¯èƒ½çš„补全。 + + æ„图在能产生å¯èƒ½çš„补全的 shell 函数内部使用。 + 如果æä¾›äº†å¯é€‰çš„ WORD 傿•°ï¼Œåˆ™äº§ç”ŸæŒ‰ç…§ WORD + 进行的匹é…。 + + 退出状æ€ï¼š + 除éžä½¿ç”¨äº†æ— æ•ˆé€‰é¡¹æˆ–者错误å‘生,å¦åˆ™è¿”回æˆåŠŸã€‚ + +[compopt] + 修改或显示补全选项。 + + 修改æ¯ä¸ª NAME å称的补全选项,或如果没有æä¾› NAME å称,执行当å‰çš„è¡¥ + 全。 + 如果ä¸å¸¦é€‰é¡¹ï¼Œæ‰“å°æ¯ä¸ª NAME å称的补全选项或当å‰çš„补全声明。 + + 选项: + -o option 为æ¯ä¸ª NAME å称设定补全选项 option + -D 为 \default\ 命令补全改å˜é€‰é¡¹ + -E 为 \empty\ 命令补全改å˜é€‰é¡¹ + -I 为首å•è¯çš„补全改å˜é€‰é¡¹ + + 使用 `+o' è€Œä¸æ˜¯ `-o' å¯ä»¥å…³é—­æŒ‡å®šçš„选项。 + + 傿•°ï¼š + + æ¯ä¸ª NAME å称都对应一个之å‰ä»¥é€šè¿‡ `complete' 内建定义了的补全声明的 + å‘½ä»¤ã€‚å¦‚æžœä¸æä¾› NAME å称,当å‰ç”Ÿæˆè¡¥å…¨çš„函数必须调用 compopt, + 并䏔当剿‰§è¡Œçš„补全生æˆå™¨é€‰é¡¹ä¼šè¢«ä¿®æ”¹ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称没有定义补全声明。 + +[mapfile] + 从标准输入读å–行到下标数组å˜é‡ä¸­ã€‚ + + 从标准输入读å–行到下标数组å˜é‡ ARRAY 中,或者如果使用了 -u 选项, + 从文件æè¿°ç¬¦ FD 中读å–。MAPFILE å˜é‡æ˜¯é»˜è®¤çš„ ARRAY å˜é‡ã€‚ + + 选项: + -d delim 使用 DELIM è€Œéžæ¢è¡Œç¬¦æ–­è¡Œ + -n count æœ€å¤šæ‹·è´ COUNT 行,如果 COUNT 为 0ï¼Œåˆ™æ‹·è´æ‰€æœ‰è¡Œã€‚ + -O origin 从下标 ORIGIN 开始 赋值给 ARRAY å˜é‡ã€‚默认下标是0. + -s count 丢弃最先读å–çš„ COUNT 行。 + -t 从读å–çš„æ¯è¡Œæœ«å°¾åˆ é™¤ä¸€ä¸ªæ¢è¡Œç¬¦ã€‚ + -u fd 从文件æè¿°ç¬¦ FD 中读å–è¡Œè€Œä¸æ˜¯æ ‡å‡†è¾“入。 + -C callback æ¯ QUANTUM 次读行之åŽå¯¹ CALLBACK 回调进行估值。 + -c quantum å®šä¹‰æ¯æ¬¡è°ƒç”¨ CALLBACK 回调之间读å–的行数。 + + 傿•°ï¼š + ARRAY 存储数æ®ä½¿ç”¨çš„æ•°ç»„å˜é‡ + + 如果使用了 -C 而没有 -c,默认的é‡å­æ˜¯5000。当对 CALLBACK 估值时, + 下一个将被赋值的数组元素的下标作为é¢å¤–傿•°è¢«ä¼ é€’。 + + å¦‚æžœæ²¡æœ‰æ˜¾å¼æŒ‡å®šèµ·å§‹ä¸‹æ ‡ï¼Œmapfile å°†åœ¨èµ‹å€¼å‰æ¸…空 ARRAY å˜é‡ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项,或者 ARRAY å˜é‡åªè¯»æˆ–䏿˜¯ä¸‹æ ‡æ•°ç»„。 + +[readarray] + 从一个文件中读å–行到数组å˜é‡ä¸­ã€‚ + 一个 `mapfile'çš„åŒä¹‰è¯ã€‚ + +[unset] + å–æ¶ˆè®¾å®š shell å˜é‡å’Œå‡½æ•°çš„值和属性。 + 对æ¯ä¸€ä¸ª NAME å称,删除对应的å˜é‡æˆ–函数。 + + 选项: + -f å°†æ¯ä¸ª NAME 视为函数 + -v å°†æ¯ä¸ª NAME 视为å˜é‡ + -n å°†æ¯ä¸ª NAME 视为å称引用,åªå–消其本身而éžå…¶æŒ‡å‘çš„å˜é‡ + + ä¸å¸¦é€‰é¡¹æ—¶ï¼Œunset 首先å°è¯•å–æ¶ˆè®¾å®šä¸€ä¸ªå˜é‡ï¼Œå¦‚果失败,å†å°è¯•å–æ¶ˆè®¾å®šä¸€ä¸ª + 函数。 + + æŸäº›å˜é‡ä¸å¯ä»¥è¢«å–消设定;å‚è§ `readonly'。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称为åªè¯»ã€‚ + +[local] + 定义本地å˜é‡ã€‚ + + 创建一个以 NAME 为åç§°çš„å˜é‡ï¼Œå¹¶ä¸”å°† VALUE 赋值给它。 + OPTION 选项å¯ä»¥æ˜¯ä»»ä½•能被 `declare' 接å—的选项。 + + 本地å˜é‡åªèƒ½åœ¨å‡½æ•°å†…部被使用,它们åªèƒ½åœ¨å®šä¹‰å®ƒä»¬çš„函数内 + 部以åŠå­å‡½æ•°ä¸­å¯è§ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项ã€å‘生了赋值错误或者 shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ªå‡½æ•°ã€‚ + +[export] + 为 shell å˜é‡è®¾å®šå¯¼å‡ºå±žæ€§ã€‚ + + 标记æ¯ä¸ª NAME å称为自动导出到åŽç»­å‘½ä»¤æ‰§è¡Œçš„环境。如果æä¾›äº† VALUE + 则导出å‰å°† VALUE 作为赋值。 + + 选项: + -f 指 shell 函数 + -n 删除æ¯ä¸ª NAME å称的导出属性 + -p 显示所有导出的å˜é‡å’Œå‡½æ•°çš„列表 + + `--' çš„å‚æ•°ç¦ç”¨è¿›ä¸€æ­¥çš„选项处ç†ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称。 + +[readonly] + 标记 shell å˜é‡ä¸ºä¸å¯æ”¹å˜ã€‚ + + 标记æ¯ä¸€ä¸ª NAME å称为åªè¯»ï¼›è¿™äº› NAME å˜é‡çš„值将ä¸å¯ä»¥è¢«åŽç»­çš„赋值 + æ“作所改å˜ã€‚如果æä¾›äº† VALUE,则在标记为åªè¯»ä¹‹å‰å°† VALUE 值赋给å˜é‡ã€‚ + + 选项: + -a 指下标数组å˜é‡ + -A æŒ‡å…³è”æ•°ç»„æ ‡é‡ + -f 指 shell 函数 + -p 显示åªè¯»å˜é‡æˆ–函数列表,å–å†³äºŽæ˜¯å¦æä¾›äº† -f 选项 + + `--' çš„å‚æ•°ç¦ç”¨è¿›ä¸€æ­¥çš„选项处ç†ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称。 + +[declare] + 设定å˜é‡å€¼å’Œå±žæ€§ã€‚ + + 声明å˜é‡å¹¶ä¸”赋予它们属性。如果没有给定å称, + 则显示所有å˜é‡çš„属性和值。 + + 选项: + -f é™åˆ¶åŠ¨ä½œæˆ–æ˜¾ç¤ºä¸ºä»…å‡½æ•°å称和定义 + -F é™åˆ¶ä»…显示函数åç§° (以åŠè°ƒè¯•时显示行å·å’Œæºæ–‡ä»¶å) + -g 当用于 shell 函数内时创建全局å˜é‡; å¦åˆ™å¿½ç•¥ + -p 显示æ¯ä¸ª NAME å˜é‡çš„属性和值 + + 设定属性的选项: + -a 使 NAME æˆä¸ºä¸‹æ ‡æ•°ç»„ (如果支æŒ) + -A 使 NAME æˆä¸ºå…³è”数组 (如果支æŒ) + -i 使 NAME 带有 `integer' (æ•´æ•°)属性 + -l å°† NAME 在赋值时转为å°å†™ + -n 使 NAME æˆä¸ºæŒ‡å‘一个以其值为åç§°çš„å˜é‡çš„引用 + -r å°† NAME å˜ä¸ºåªè¯» + -t 使 NAME 带有 `trace' (追踪)属性 + -u å°†æ¯ä¸ª NAME 在赋值时转为大写 + -x å°† NAME 导出 + + 用 `+' 代替 `-' 会关闭指定选项。 + + 带有整数属性的å˜é‡åœ¨èµ‹å€¼æ—¶å°†ä½¿ç”¨ç®—术估值(è§ + `let' 命令) + + 在函数中使用时,`declare' 使 NAME æˆä¸ºæœ¬åœ°å˜é‡ï¼Œå’Œ `local' + 命令一致。`-g' 选项抑制此行为。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžæä¾›äº†æ— æ•ˆé€‰é¡¹æˆ–è€…å‘生å˜é‡èµ‹å€¼é”™è¯¯ + +[function] + 定义 shell 函数。 + + 创建一个以 NAME 为åçš„ shell 函数。当作为一个简å•的命令å¯ç”¨æ—¶ï¼Œ + NAME 函数执行调用 shell 的上下文中的 COMMANDs 命令。当 NAME + 被å¯ç”¨æ—¶ï¼Œå‚数作为 $1...$n 被传递给函数,函数的å字储存在å˜é‡ + $FUNCNAME 中。 + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éž NAME 为åªè¯»ã€‚ + +[typeset] + 设置å˜é‡çš„值和属性。 + + `declare' 的等价形å¼ã€‚å‚è§ `help declare'。 + +[source] + åœ¨å½“å‰ shell 中执行一个文件中的命令。 + + åœ¨å½“å‰ shell 中读å–并执行 FILENAME 文件中的命令。$PATH å˜é‡ä¸­çš„ + æ¡ç›®è¢«ç”¨äºŽå¯»æ‰¾åŒ…å« FILENAME 文件的目录。如果æä¾›äº†ä»»ä½•çš„ ARGUMENTS + 傿•°ï¼Œåˆ™å®ƒä»¬å°†æˆä¸º FILENAME 文件执行时的ä½ç½®å‚数。 + + 退出状æ€ï¼š + 返回 FILENAME 文件中最åŽä¸€ä¸ªå‘½ä»¤çš„状æ€ï¼›å¦‚æžœ FILENAME 文件ä¸å¯è¯»åˆ™å¤±è´¥ã€‚ + +[bind] + 设定 Readline 键绑定和å˜é‡ã€‚ + + 绑定一个键åºåˆ—到一个 Readline 函数或者å®ï¼Œæˆ–者设定一个 + Readline å˜é‡ã€‚éžé€‰é¡¹å‚数的语法和 ~/.inputrc 文件中的等 + åŒï¼Œä½†æ˜¯å¿…é¡»ä½œä¸ºä¸€ä¸ªå‚æ•°è¢«ä¼ é€’, + 例如,bind '\\\C-x\\C-r\: re-read-init-file'. + + 选项: + -m 键映射 在此命令执行过程中使用指定的键映射。 + å¯è¢«æŽ¥å—的键映射å字有 emacsã€emacs-standardã€emacs- + meta〠+ emacs-ctlxã€viã€vi-moveã€vi-commandã€å’Œ vi-insert。 + -l 列出函数å称。 + -P 列出函数å称和绑定。 + -p 以å¯ä»¥é‡æ–°ç”¨ä½œè¾“入的格å¼åˆ—出函数å称和绑定。 + -S 列出å¯ä»¥å¯åЍå®çš„é”®åºåˆ—以åŠå®ƒä»¬çš„值 + -s 以å¯ä»¥é‡æ–°ç”¨ä½œè¾“入的格å¼åˆ—出å¯ä»¥å¯åЍå®çš„键以åŠå®ƒä»¬çš„ + 值。 + -V 列出å˜é‡åæˆå’Œå®ƒä»¬çš„值 + -v 以å¯ä»¥é‡æ–°ç”¨ä½œè¾“入的格å¼åˆ—出å˜é‡çš„å称和它们的值 + -q å‡½æ•°å æŸ¥è¯¢æŒ‡å®šçš„函数å¯ä»¥ç”±å“ªäº›é”®å¯åŠ¨ã€‚ + -u 函数å å绑定所有绑定至指定函数的键。 + -r é”®åºåˆ— å–æ¶ˆæŒ‡å®šé”®åºåˆ—的绑定。 + -f 文件å 从指定文件中读å–键绑定。 + -x é”®åºåˆ—:shell命令\t当指定的键åºåˆ—被输入时,执行指定的 shell 命令。 + -X 以å¯è¢«é‡ç”¨çš„å½¢å¼åˆ—出用 -x 绑定的键åºåˆ—和命令。 + + 退出状æ€ï¼š + 除éžä½¿ç”¨äº†æ— æ³•辨认的选项或者错误å‘生,å¦åˆ™è¿”回0. + +[test] + 估值算术表达å¼ã€‚ + + å°†æ¯ä¸ª ARG å‚èµ›ä½œä¸ºç®—æœ¯è¡¨è¾¾å¼æ¥ä¼°å€¼ã€‚估值的计算以定宽的整 + 数完æˆï¼Œä¸å¸¦æº¢å‡ºæ£€æµ‹ï¼Œä¸è¿‡é™¤ 0 是被置陷阱的并且会报一个错 + 误。下列æ“作符被按照相åŒçš„算术优先级组åˆã€‚åˆ—è¡¨çš„é¡ºåºæŒ‰ç…§ + 优先级从高至低。 + + + id++, id-- å˜é‡åŽç½®åŠ ï¼ŒåŽç½®å‡ + ++id, --id å˜é‡å‰ç½®åŠ ï¼Œå‰ç½®å‡ + -, + ä¸€å…ƒå‡æ³•,一元加法 + !, ~ 逻辑和ä½å–å + '**' 指数 + '*', /, % 乘法,除法,å–余数 + +, - 增加,å‡å°‘ + <<, >> å‘左和å‘峿Œ‰ä½ç§»ä½ + <=, >=, <, > 比较 + ==, != 等于,ä¸ç­‰äºŽ + & 按ä½ä¸Ž + ^ 按ä½å¼‚或 + | æŒ‰ä½æˆ– + && 逻辑与 + || 逻辑或 + expr ? expr : expr + æ¡ä»¶æ“作符 + =, *=, /=, %=, + +=, -=, <<=, >>=, + &=, ^=, |= 赋值 + + + Shell å˜é‡å…许作为æ“作数。表达å¼ä¸­çš„å˜é‡çš„å称会被å–代以值 + (强制转æ¢ä¸ºå®šå®½çš„æ•´æ•°)。表达å¼ä¸­çš„å˜é‡ä¸éœ€è¦æ‰“开整数属性。 + + æ“作符按照优先级进行估值。括å·ä¸­çš„å­è¡¨è¾¾å¼å°†è¢«å…ˆä¼°å€¼ï¼Œå¹¶å¯å–ä»£ä¸Šè¿°è¡¨è¾¾å¼ + 规则。 + + 退出状æ€ï¼š + 如果最åŽä¸€ä¸ª ARG 傿•°ä¼°å€¼ä¸º 0,则 let 返回 1ï¼› å¦åˆ™ let 返回 0。 + +*[other] æ˜¾ç¤ºå…¶ä»–å‘½ä»¤å¸®åŠ©ä¿¡æ¯ . +} + +helpname = { +$cmdName -> +[command0] {" % - 在å‰å°ç»§ç»­ä»»åŠ¡"} +[command1] {"(( - 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚"} +[command2] {". 文件å [傿•°]"} +[command3] {":"} +[command4] {"[ 傿•°... ]"} +[command5] {"[[ è¡¨è¾¾å¼ ]]"} +[command6] {"for (( - 算术 for 循环。"} +[command7] 将命令组åˆä¸ºä¸€ä¸ªå•元。 +[set] set - è®¾å®šæˆ–å–æ¶ˆè®¾å®š shell 选项和ä½ç½®å‚æ•°çš„ +[read] read - 从标准输入读å–一行并将其分为ä¸åŒçš„域。 +[type] type - 显示命令类型的信æ¯ã€‚ +[trap] trap - 对信å·å’Œå…¶ä»–事件设陷阱。 +[alias] alias - 定义或显示别å。 +[unalias] unalias - 从别å定义列表中删除æ¯ä¸€ä¸ªâ€œåå­—â€ã€‚ +[break] break - 退出 forã€while 或 until 循环 +[continue] continue - ç»§ç»­ forã€while 或 until 循环。 +[builtin] builtin - 执行 shell 内建。 +[caller] caller - 返回当å‰å­è°ƒç”¨çš„上下文。 +[cd] cd - æ”¹å˜ shell 工作目录。 +[pwd] pwd - 打å°å½“å‰å·¥ä½œç›®å½•çš„å字。 +[true] true - 空的命令。 +[shopt] shopt - è®¾å®šå’Œå–æ¶ˆè®¾å®š shell 选项。 +[false] false - è¿”å›žä¸€ä¸ªä¸æˆåŠŸçš„ç»“æžœã€‚ +[command] command - 执行一个简å•命令或者显示命令的相关信æ¯ã€‚ +[echo] echo - 将傿•°å†™åˆ°æ ‡å‡†è¾“出。 +[enable] enable - å¯ç”¨å’Œç¦ç”¨ shell 内建。 +[getopts] getopts - è§£æžé€‰é¡¹å‚数。 +[exec] exec - ä½¿ç”¨æŒ‡å®šå‘½ä»¤æ›¿æ¢ shell。 +[exit] exit - 退出shell。 +[logout] logout - 退出一个登录 shell. +[fc] fc - 从历å²åˆ—表中显示或者执行命令。 +[fg] fg - 将任务移至å‰å°ã€‚ +[bg] bg - 移动任务至åŽå°ã€‚ +[hash] hash - è®°ä½æˆ–显示程åºä½ç½®ã€‚ +[help] help - 显示内建命令的相关信æ¯ã€‚ +[history] history - 显示或æ“纵历å²åˆ—表。 +[jobs] jobs - 显示任务状æ€ã€‚ +[disown] discow - ä»Žå½“å‰ shell 中删除任务。 +[kill] kill - å‘一个任务å‘é€ä¸€ä¸ªä¿¡å·ã€‚ +[let] let - 估值算术表达å¼ã€‚ +[shift] shift - ç§»ä½ä½ç½®å‚数。 +[suspend] suspend - 挂起 shell 执行。 +[eval] eval - 对æ¡ä»¶è¡¨è¾¾å¼è¿›è¡Œä¼°å€¼ã€‚ +[times] times - 显示进程时间 +[ulimit] limit - 修改 shell 资æºé™åˆ¶ã€‚ +[umask] umask - æ˜¾ç¤ºæˆ–è®¾å®šæ–‡ä»¶æ¨¡å¼æŽ©ç ã€‚ +[return] return - 等待任务完æˆå¹¶è¿”回退出状æ€ã€‚ +[wait] wait - 等待进程完æˆå¹¶ä¸”返回退出状æ€ã€‚ +[for] for - 为列表中的æ¯ä¸ªæˆå‘˜æ‰§è¡Œå‘½ä»¤ã€‚ +[select] select - 从列表中选å–è¯å¹¶ä¸”执行命令。 +[time] time - æŠ¥å‘Šç®¡é“æ‰§è¡Œçš„æ¶ˆè€—时间。 +[case] case - 基于模å¼åŒ¹é…æ¥æ‰§è¡Œå‘½ä»¤ã€‚ +[if] if - æ ¹æ®æ¡ä»¶æ‰§è¡Œå‘½ä»¤ã€‚ +[while] while - åªè¦æµ‹è¯•æˆåŠŸå³æ‰§è¡Œå‘½ä»¤ã€‚ +[until] until -当测试ä¸åŒè¿‡æ—¶æ‰§è¡Œå‘½ä»¤ +[coproc] corproc - 创建一个以 NAME 为å的副进程。 +[variables] variables - 常用 shell å˜é‡å称和使用。 +[pushd] pushd - 将目录添加到栈中。 +[popd] popd - 从栈中删除目录。 +[dirs] dirs - 显示目录栈。 +[printf] printf -在 FORMAT 的控制下格å¼åŒ–å¹¶æ‰“å° ARGUMENTS 傿•°ã€‚ +[complete] complete - 指定 Readline å¦‚ä½•è¡¥å…¨å‚æ•°ã€‚ +[compgen] compgen - 便®é€‰é¡¹æ˜¾ç¤ºå¯èƒ½çš„补全。 +[compopt] compopt - 修改或显示补全选项。 +[mapfile] mapfile - 从标准输入读å–行到下标数组å˜é‡ä¸­ã€‚ +[unset] unset - å–æ¶ˆè®¾å®š shell å˜é‡å’Œå‡½æ•°çš„值和属性。 +[readarray] readarry - 从一个文件中读å–行到数组å˜é‡ä¸­ã€‚ +[local] local -è®°ä½æˆ–显示程åºä½ç½®ã€‚ +[export] export -为 shell å˜é‡è®¾å®šå¯¼å‡ºå±žæ€§ã€‚ +[readonly] readonly - 标记 shell å˜é‡ä¸ºä¸å¯æ”¹å˜ã€‚ +[function] function - 定义 shell 函数。 +[typeset] typeset - 设置å˜é‡çš„值和属性。 +[source] source - åœ¨å½“å‰ shell 中执行一个文件中的命令。 +[bind] bind - 设定 Readline 键绑定和å˜é‡ã€‚ +[test] test - 估值算术表达å¼ã€‚ +[declare] declare - 设置å˜é‡çš„值和属性。 +*[other] æ˜¾ç¤ºå…¶ä»–å‘½ä»¤å¸®åŠ©ä¿¡æ¯ . +} + +helpsynopsis = { +$cmdName -> +[command0] {"job_spec [&]"} +[command1] {"(( - "} +[command2] {". - åœ¨å½“å‰ shell 中执行一个文件中的命令。"} +[command3] {": - 空的命令。"} +[command4] {"[ - 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚"} +[command5] {"[[ ... ]] - 执行æ¡ä»¶å‘½ä»¤ã€‚"} +[command6] {"for (( 表达å¼1; 表达å¼2; 表达å¼3 )); do 命令 ; done"} +[command7] {"{ 命令 ; }"} +[set] {"set [--abefhkmnptuvxBCHP][-o 选项å][--][傿•° ...]"} +[read] {"read [-ers] [-a 数组] [-d 分隔符] [-i 缓冲区文字] [-n 读å–字符数] [-N 读å–字符数] [-p æç¤ºç¬¦] [-t è¶…æ—¶] [-u 文件æè¿°ç¬¦] [åç§° ...]"} +[type] {"type [-afptP] åç§° [åç§° ...]"} +[trap] {"trap: trap [-lp] [[傿•°] ä¿¡å·å£°æ˜Ž ...]"} +[alias] {"alias [-p] [åç§°[=值] ... ]"} +[unalias] {"unalias [-a] åç§° [åç§° ...] "} +[break] {"break [n]"} +[continue] {"continue [n]"} +[builtin] {"builtin [shell 内建 [傿•° ...]] "} +[caller] {"caller [表达å¼] "} +[cd] {"cd [-L|[-P [-e]] [-@]] [目录]"} +[pwd] {"pwd [-LP]"} +[true] {"true"} +[shopt] {"shopt [-pqsu] [-o] [选项å ...]"} +[false] {"false"} +[command] {"command [-pVv] 命令 [傿•° ...]"} +[echo] {"echo [-neE] [傿•° ...]"} +[enable] {"enable [-a] [-dnps] [-f 文件å] [åç§° ...] "} +[getopts] {"getopts 选项字符串 åç§° [傿•°]"} +[exec] {"exec [-cl] [-a åç§°] [命令 [傿•° ...]] [é‡å®šå‘ ...] "} +[exit] {"exit [n]"} +[logout] {"logout [n]"} +[fc] {"fc [-e 编辑器å] [-lnr] [èµ·å§‹] [终结] 或 fc -s [模å¼=替æ¢ä¸²] [命令]"} +[fg] {"fg [任务声明] "} +[bg] {"bg [任务声明 ...]"} +[hash] {"hash [-lr] [-p 路径å] [-dt] [åç§° ...]"} +[help] {"help [-dms] [æ¨¡å¼ ...]"} +[history] {"history [-c] [-d åç§»é‡] [n] 或 history -anrw [文件å] 或 history -ps 傿•° [傿•°...]"} +[jobs] {"jobs [-lnprs] [任务声明 ...] 或 jobs -x 命令 [傿•°]"} +[disown] {"disown [-h] [-ar] [任务声明 ... | pid ...]"} +[kill] {"kill [-s ä¿¡å·å£°æ˜Ž | -n ä¿¡å·ç¼–å· | -ä¿¡å·å£°æ˜Ž] è¿›ç¨‹å· | 任务声明 ... 或 kill -l [ä¿¡å·å£°æ˜Ž]"} +[let] {"let 傿•° [傿•° ...]"} +[shift] {"shift [n]"} +[suspend] {"suspend [-f]"} +[eval] {"eval [傿•° ...]"} +[times] {"times"} +[ulimit] {"ulimit [-SHabcdefiklmnpqrstuvxPT] [é™åˆ¶]"} +[umask] {"umask [-p] [-S] [模å¼]"} +[return] {"return [n]"} +[wait] {"wait [-fn] [ç¼–å· ...]"} +[for] {"for åç§° [in è¯è¯­ ... ] ; do 命令; done"} +[select] {"select NAME [in è¯è¯­ ... ;] do 命令; done"} +[time] {"time [-p] 管é“"} +[case] {"case è¯ in [æ¨¡å¼ [| 模å¼]...) 命令 ;;]... esac"} +[if] {"if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi"} +[while] {"while 命令; do 命令; done"} +[until] {"until 命令; do 命令; done"} +[coproc] {"coproc [åç§°] 命令 [é‡å®šå‘]"} +[variables] {"variables - 一些 shell å˜é‡çš„åç§°å’Œå«ä¹‰"} +[pushd] {"pushd [-n] [+N | -N | 目录]"} +[popd] {"popd [-n] [+N | -N]"} +[dirs] {"dirs [-clpv] [+N] [-N]"} +[printf] {"printf [-v var] æ ¼å¼ [傿•°]"} +[complete] {"complete [-abcdefgjksuv] [-pr] [-DEI] [-o 选项] [-A 动作] [-G 全局模å¼] [-W è¯è¯­åˆ—表] [-F 函数] [-C 命令] [-X 过滤模å¼] [-P å‰ç¼€] [-S åŽç¼€] [åç§° ...]"} +[compgen] {"compgen [-abcdefgjksuv] [-o 选项] [-A 动作] [-G 全局模å¼] [-W è¯è¯­åˆ—表] [-F 函数] [-C 命令] [-X 过滤模å¼] [-P å‰ç¼€] [-S åŽç¼€] [è¯è¯­]"} +[compopt] {"compopt [-o|+o 选项] [-DEI] [åç§° ...]"} +[mapfile] {"mapfile [-d 分隔符] [-n 计数] [-O èµ·å§‹åºå·] [-s 计数] [-t] [-u fd] [-C 回调] [-c é‡å­] [数组]"} +[unset] {"unset [-f] [-v] [-n] [åç§° ...]"} +[readarray] {"readarray [-d 定界符] [-n 计数] [-O èµ·å§‹åºå·] [-s 计数] [-t] [-u fd] [-C 回调] [-c é‡å­] [数组]"} +[local] {"local [option] åç§°[=值] ... "} +[export] {"export [-fn] [åç§°[=值] ...] 或 export -p"} +[readonly] {"readonly [-aAf] [åç§°[=值] ...] 或 readonly -p"} +[function] {"function åç§° { 命令 ; } 或 name () { 命令 ; } "} +[typeset] {"typeset [-aAfFgilnrtux] [-p] åç§°[=值] ..."} +[source] {"source 文件å [傿•°]"} +[bind] {"bind [-lpvsPSVX] [-m 键映射] [-f 文件å] [-q åç§°] [-u åç§°] [-r é”®åºåˆ—] [-x é”®åºåˆ—:shell-命令] [é”®åºåˆ—:readline-函数 或 readline-命令] "} +[test] {"test [表达å¼]"} +[declare] {"declare [-aAfFgilnrtux] [-p] [åç§°[=值] ...]"} +*[other] æ˜¾ç¤ºå…¶ä»–å‘½ä»¤å¸®åŠ©ä¿¡æ¯ . +} + +information = 这些 shell 命令是内部定义的。请输入 `help' 以获å–一个列表。 + 输入 `help åç§°' 以得到有关函数`åç§°'的更多信æ¯ã€‚ + 使用 `info bash' æ¥èŽ·å¾—å…³äºŽ shell 的更多一般性信æ¯ã€‚ + 使用 `man -k' 或 `info' æ¥èŽ·å–ä¸åœ¨åˆ—表中的命令的更多信æ¯ã€‚ + +helperr = 没有与{$name}匹é…的帮助主题。å°è¯•使用"help help"ã€"man -k {$name} 或 "info {$name}"。 + +is = {$str1} 是 {$str2} +special = {$str1} 是特殊 shell 内建 +hashd = {$str1} 已被录入哈希表 +isfunction = {$str1}是函数 +iskeyword = {$str1} 是 shell 关键字 +isalias = {$str1} 是 {$str2} 的别å +isbuiltin = {$str1} 是 shell 内建 +killargerr = {$str1} : 傿•°å¿…须是进程或任务 ID +letwarn = utshell : let : 需è¦è¡¨è¾¾å¼ +bindvia = {$str1} å¯ä»¥è¢«è°ƒç”¨ï¼Œ 通过 +bindnokeys = {$str1}未与任何键绑定。 +unknowdfunction = {$str1} : 未知函数å +unbindfaild = {$str1} : 无法解除绑定 +invaildmap = {$str1} : 无效的键映射å +logout = 注销 +nologinsh = 䏿˜¯ç™»å½• shell: 使用 'exit' +stoppedjobs = æœ‰åœæ­¢çš„任务 +runjobs = 有è¿è¡Œä¸­çš„任务 diff --git a/utshell-0.5.0/resources/zh-HK/message.ftl b/utshell-0.5.0/resources/zh-HK/message.ftl new file mode 100644 index 00000000..bf75e84c --- /dev/null +++ b/utshell-0.5.0/resources/zh-HK/message.ftl @@ -0,0 +1,1638 @@ +helplongdoc ={ +$cmdName -> +[command0] + 在å‰å°ç»§ç»­ä»»åŠ¡ + 对于 JOB_SPEC 傿•°æ¥è¯´å’Œ `fg' 命令等åŒã€‚继续一个 + åœæ­¢çš„æˆ–者åŽå°ä»»åŠ¡ã€‚JOB_SPEC å¯ä»¥æŒ‡å®šä¸€ä¸ªä»»åŠ¡ + å字或任务å·ã€‚在 JOB_SPEC åŽåŠ ä¸Šä¸€ä¸ª `&' 将会把 + 任务放至åŽå°ï¼Œå°±åƒä»»åŠ¡å£°æ˜Žè¢«ä½œä¸º `bg' å‘½ä»¤çš„å‚æ•° + 执行一样。 + + 退出状æ€ï¼š + 返回被继续的任务的状æ€ã€‚ + +[command1] + 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚ + 是内建命令 test çš„åŒä¹‰è¯ï¼Œä½†æ˜¯æœ€åŽä¸€ä¸ªå‚数必须是 + 字符 `]',以匹é…èµ·å§‹çš„ `['。 + +[command2] + åœ¨å½“å‰ shell 中执行一个文件中的命令。 + + åœ¨å½“å‰ shell 中读å–并执行 FILENAME 文件中的命令。$PATH å˜é‡ä¸­çš„ + æ¡ç›®è¢«ç”¨äºŽå¯»æ‰¾åŒ…å« FILENAME 文件的目录。如果æä¾›äº†ä»»ä½•çš„ ARGUMENTS + 傿•°ï¼Œåˆ™å®ƒä»¬å°†æˆä¸º FILENAME 文件执行时的ä½ç½®å‚数。 + + 退出状æ€ï¼š + 返回 FILENAME 文件中最åŽä¸€ä¸ªå‘½ä»¤çš„状æ€ï¼›å¦‚æžœ FILENAME 文件ä¸å¯è¯»åˆ™å¤±è´¥ã€‚ + +[command3] + 空的命令。 + 没有效果; 此命令ä¸åšä»»ä½•æ“作。 + + 退出状æ€ï¼š + 总是æˆåŠŸã€‚ + +[command4] + 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚ + + 是内建命令 test çš„åŒä¹‰è¯ï¼Œä½†æ˜¯æœ€åŽä¸€ä¸ªå‚数必须是 + 字符 `]',以匹é…èµ·å§‹çš„ `['。 + +[command5] + 执行æ¡ä»¶å‘½ä»¤ã€‚ + + æ ¹æ®æ¡ä»¶è¡¨è¾¾å¼ EXPRESSION 的估值返回状æ€0或1ã€‚è¡¨è¾¾å¼æŒ‰ç…§ + `test' å†…å»ºçš„ç›¸åŒæ¡ä»¶ç»„æˆï¼Œæˆ–者å¯ä»¥æœ‰ä¸‹åˆ—æ“作符连接而æˆï¼š + + ( EXPRESSION ) 返回 EXPRESSION 表达å¼çš„值 + ! EXPRESSION 如果 EXPRESSION表达å¼ä¸ºå‡åˆ™ä¸ºçœŸï¼Œå¦åˆ™ä¸ºå‡ + EXPR1 && EXPR2 如果 EXPR1 å’Œ EXPR2 表达å¼å‡ä¸ºçœŸåˆ™ä¸ºçœŸï¼Œå¦åˆ™ä¸ºå‡ + EXPR1 || EXPR2 如果 EXPR1 å’Œ EXPR2 表达å¼ä¸­æœ‰ä¸€ä¸ªä¸ºçœŸåˆ™ä¸ºçœŸï¼Œå¦åˆ™ä¸º + å‡ + + 当使用 `==' å’Œ `!=' æ“作符时,æ“作符å³è¾¹çš„字符串被用作模å¼å¹¶ä¸”执行一个 + 匹é…。当使用 `=~' æ“作符时,æ“作符å³è¾¹çš„å­—ç¬¦ä¸²è¢«å½“ä½œæ­£åˆ™è¡¨è¾¾å¼æ¥è¿›è¡Œ + 匹é…。 + + æ“作符 && å’Œ || å°†ä¸å¯¹ EXPR2 表达å¼è¿›è¡Œä¼°å€¼ï¼Œå¦‚æžœ EXPR1 表达å¼è¶³å¤Ÿç¡®å®š + 整个表达å¼çš„值。 + + 退出状æ€ï¼š + æ ¹æ® EXPRESSION 的值为0或1。 + +[command6] + 算术 for 循环。 + + 等价于 + (( EXP1 )) + while (( EXP2 )); do + 命令们 + (( EXP3 )) + done + EXP1ã€EXP2 å’Œ EXP3 都是算术表达å¼ã€‚如果çœç•¥ä»»ä½•表达å¼ï¼Œ + 则等åŒäºŽä½¿ç”¨äº†ä¼°å€¼ä¸º1的表达å¼ã€‚ + + 退出状æ€ï¼š + è¿”å›žæœ€åŽæ‰§è¡Œçš„命令的状æ€ã€‚ + +[command7] + 将命令组åˆä¸ºä¸€ä¸ªå•元。 + + è¿è¡Œç»„中的命令集åˆã€‚è¿™æ˜¯å¯¹æ•´ä¸ªå‘½ä»¤é›†åˆ + åšé‡å®šå‘的方法之一。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[set] + è®¾å®šæˆ–å–æ¶ˆè®¾å®š shell 选项和ä½ç½®å‚æ•°çš„ + + æ”¹å˜ shell 选项和ä½ç½®å‚数的值,或者显示 shell å˜é‡çš„ + å称和值。 + + 选项: + -a 标记修改的或者创建的å˜é‡ä¸ºå¯¼å‡ºã€‚ + -b ç«‹å³é€šå‘Šä»»åŠ¡ç»ˆç»“ã€‚ + -e 如果一个命令以éžé›¶çжæ€é€€å‡ºï¼Œåˆ™ç«‹å³é€€å‡ºã€‚ + -f ç¦ç”¨æ–‡ä»¶å生æˆ(模å¼åŒ¹é…)。 + -h 当查询命令时记ä½å®ƒä»¬çš„ä½ç½® + -k æ‰€æœ‰çš„èµ‹å€¼å‚æ•°è¢«æ”¾åœ¨å‘½ä»¤çš„环境中,而ä¸ä»…仅是 + 命令å称之å‰çš„傿•°ã€‚ + -m å¯ç”¨ä»»åŠ¡æŽ§åˆ¶ã€‚ + -n 读å–命令但䏿‰§è¡Œ + -o 选项å + 设定与选项å对应的å˜é‡ï¼š + allexport 与 -a ç›¸åŒ + braceexpand 与 -B ç›¸åŒ + emacs 使用 emacs é£Žæ ¼çš„è¡Œç¼–è¾‘ç•Œé¢ + errexit 与 -e ç›¸åŒ + errtrace 与 -E ç›¸åŒ + functrace 与 -T ç›¸åŒ + hashall 与 -h ç›¸åŒ + histexpand 与 -H ç›¸åŒ + history å¯ç”¨å‘½ä»¤åŽ†å² + ignoreeof shell è¯»å–æ–‡ä»¶ç»“æŸç¬¦æ—¶ä¸ä¼šé€€å‡º + interactive-comments + å…许在交互å¼å‘½ä»¤ä¸­æ˜¾ç¤ºæ³¨é‡Š + keyword 与 -k ç›¸åŒ + monitor 与 -m ç›¸åŒ + noclobber 与 -C ç›¸åŒ + noexec 与 -n ç›¸åŒ + noglob 与 -f ç›¸åŒ + nolog ç›®å‰å¯æŽ¥å—但是被忽略 + notify 与 -b ç›¸åŒ + nounset 与 -u ç›¸åŒ + onecmd 与 -t ç›¸åŒ + physical 与 -P ç›¸åŒ + pipefail 管é“的返回值是最åŽä¸€ä¸ªéžé›¶è¿”回值的命令的返回结果, + 或者当所有命令都返回零是也为零。 + posix 改å˜é»˜è®¤æ—¶å’Œ Posix 标准ä¸åŒçš„ bash 行为 + ä»¥åŒ¹é…æ ‡å‡† + privileged 与 -p ç›¸åŒ + verbose 与 -v ç›¸åŒ + vi 使用 vi é£Žæ ¼çš„è¡Œç¼–è¾‘ç•Œé¢ + xtrace 与 -x ç›¸åŒ + -p 无论何时当真实的有效的用户身份ä¸åŒ¹é…时打开。 + ç¦ç”¨å¯¹ $ENV 文件的处ç†ä»¥åŠå¯¼å…¥ shell 函数。 + 关闭此选项会导致有效的用户编å·å’Œç»„ç¼–å·è®¾å®š + 为真实的用户编å·å’Œç»„ç¼–å· + -t 读å–并执行一个命令之åŽé€€å‡ºã€‚ + -u æ›¿æ¢æ—¶å°†ä¸ºè®¾å®šçš„å˜é‡å½“作错误对待。 + -v è¯»å– shell 输入行时将它们打å°ã€‚ + -x 执行命令时打å°å®ƒä»¬ä»¥åŠå‚数。 + -B shell å°†æ‰§è¡ŒèŠ±æ‹¬å·æ‰©å±•。 + -C 设定之åŽç¦æ­¢ä»¥é‡å®šå‘输出的方å¼è¦†ç›–常 + 规文件。 + -E è®¾å®šä¹‹åŽ ERR 陷阱会被 shell 函数继承。 + -H å¯ç”¨ ! é£Žæ ¼çš„åŽ†å²æ›¿æ¢ã€‚当 shell 是交互å¼çš„ + 时候这个标识ä½é»˜è®¤æ‰“开。 + -P 设定之åŽç±»ä¼¼ cd 的会改å˜å½“å‰ç›®å½•çš„å‘½ä»¤ä¸ + 追踪符å·é“¾æŽ¥ã€‚ + -T è®¾å®šä¹‹åŽ DEBUG 陷阱会被 shell 函数继承。 + -- ä»»ä½•å‰©ä½™çš„å‚æ•°ä¼šè¢«èµ‹å€¼ç»™ä½ç½®å‚数。如果没 + æœ‰å‰©ä½™çš„å‚æ•°ï¼Œä½ç½®å‚æ•°ä¸ä¼šè¢«è®¾ç½®ã€‚ + - ä»»ä½•å‰©ä½™çš„å‚æ•°ä¼šè¢«èµ‹å€¼ç»™ä½ç½®å‚数。 + -x å’Œ -v 选项已关闭。 + + 使用 + è€Œä¸æ˜¯ - 会使标志ä½è¢«å…³é—­ã€‚标志ä½ä¹Ÿå¯ä»¥åœ¨ + shell 被å¯åŠ¨æ—¶ä½¿ç”¨ã€‚å½“å‰çš„æ ‡å¿—ä½è®¾å®šå¯ä»¥åœ¨ $- å˜ + é‡ä¸­æ‰¾åˆ°ã€‚剩余的 ARG 傿•°æ˜¯ä½ç½®å‚数并且是按照 + $1, $2, .. $n 的顺åºè¢«èµ‹å€¼çš„。如果没有给定 ARG + 傿•°ï¼Œåˆ™æ‰“å°æ‰€æœ‰çš„ shell å˜é‡ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„傿•°ã€‚ +[read] + 从标准输入读å–一行并将其分为ä¸åŒçš„域。 + + 从标准输入读å–å•独的一行,或者如果使用了 -u 选项,从文件æè¿°ç¬¦ FD 中读 + å–。 + 该行被分割æˆåŸŸï¼Œå¦‚åŒè¯è¯­åˆ†å‰²ä¸€æ ·ï¼Œå¹¶ä¸”第一个è¯è¢«èµ‹å€¼ç»™ç¬¬ä¸€ä¸ª NAME å˜é‡ï¼Œ + 第二 + 个è¯è¢«èµ‹å€¼ç»™ç¬¬äºŒä¸ª NAME å˜é‡ï¼Œå¦‚此继续,直到剩下所有的è¯è¢«èµ‹å€¼ç»™æœ€åŽä¸€ä¸ª + NAME + å˜é‡ã€‚åªæœ‰ $IFS å˜é‡ä¸­çš„字符被认作是è¯è¯­åˆ†éš”符。 + + 如果没有æä¾› NAME å˜é‡ï¼Œåˆ™è¯»å–的行被存放在 REPLY å˜é‡ä¸­ã€‚ + + 选项: + -a array å°†è¯è¯­èµ‹å€¼ç»™ ARRAY 数组å˜é‡çš„åºåˆ—下标æˆå‘˜ï¼Œä»Žé›¶å¼€å§‹ + -d delim æŒç»­è¯»å–直到读入 DELIM å˜é‡ä¸­çš„ç¬¬ä¸€ä¸ªå­—ç¬¦ï¼Œè€Œä¸æ˜¯æ¢è¡Œç¬¦ + -e 使用 Readline 获å–行 + -i text 使用 TEXT 文本作为 Readline çš„åˆå§‹æ–‡å­— + -n nchars è¯»å– nchars 个字符之åŽè¿”å›žï¼Œè€Œä¸æ˜¯ç­‰åˆ°è¯»å–æ¢è¡Œç¬¦ã€‚ + 但是分隔符ä»ç„¶æœ‰æ•ˆï¼Œå¦‚æžœé‡åˆ°åˆ†éš”符之å‰è¯»å–了ä¸è¶³ nchars 个字符。 + -N nchars 在准确读å–了 nchars 个字符之åŽè¿”回,除éžé‡åˆ°æ–‡ä»¶ç»“æŸç¬¦æˆ–者读 + 超时,任何的分隔符都被忽略 + -p prompt 在å°è¯•读å–之å‰è¾“出 PROMPT æç¤ºç¬¦å¹¶ä¸”ä¸å¸¦æ¢è¡Œç¬¦ + -r ä¸å…è®¸åæ–œæ è½¬ä¹‰ä»»ä½•字符 + -s ä¸å›žæ˜¾ç»ˆç«¯çš„任何输入 + -t timeout 如果在 TIMEOUT 秒内没有读å–一个完整的行则超时并且返回失 + 败。TMOUT å˜é‡çš„值是默认的超时时间。TIMEOUT å¯ä»¥æ˜¯å°æ•°ã€‚ + 如果 TIMEOUT 是 0,那么仅当在指定的文件æè¿°ç¬¦ä¸Šè¾“入有效的时候, + read æ‰è¿”回æˆåŠŸï¼›å¦åˆ™å®ƒå°†ç«‹åˆ»è¿”回而ä¸å°è¯•读å–任何数æ®ã€‚ + 如果超过了超时时间,则返回状æ€ç å¤§äºŽ 128 + -u fd 从文件æè¿°ç¬¦ FD 中读å–ï¼Œè€Œä¸æ˜¯æ ‡å‡†è¾“å…¥ + + 退出状æ€ï¼š + 返回ç ä¸ºé›¶ï¼Œé™¤éžé‡åˆ°äº†æ–‡ä»¶ç»“æŸç¬¦ã€è¯»è¶…时(且返回ç ä¸å¤§äºŽ128)〠+ 出现了å˜é‡èµ‹å€¼é”™è¯¯æˆ–者无效的文件æè¿°ç¬¦ä½œä¸ºå‚数传递给了 -u 选项。 + +[type] + 显示命令类型的信æ¯ã€‚ + + 对于æ¯ä¸€ä¸ª NAME å称,指示如果作为命令它将如何被解释。 + + 选项: + -a 显示所有包å«å称为 NAME çš„å¯æ‰§è¡Œæ–‡ä»¶çš„ä½ç½®ï¼› + 包括别åã€å†…建和函数。仅当 `-p' 选项没有使用时 + -f 抑制 shell 函数查询 + -P 为æ¯ä¸ª NAME å称惊醒 PATH 路径æœç´¢ï¼Œå³ä½¿å®ƒæ˜¯åˆ«å〠+ 内建或函数,并且返回将被执行的ç£ç›˜ä¸Šæ–‡ä»¶çš„å称。 + -p 返回将被执行的ç£ç›˜ä¸Šæ–‡ä»¶çš„å称,或者当 `type -t NAME' + ä¸è¿”回 `file' 时,ä¸è¿”回任何值。 + -t 返回下列è¯ä¸­çš„任何一个 `alias'ã€`keyword'〠+ `function'ã€`builtin'ã€`file' 或者 `',相应地如果 NAME 是 + 一个别åã€shell ä¿ç•™å­—ã€shell 函数ã€shell 内建〠+ ç£ç›˜æ–‡ä»¶æˆ–没有找到。 + + 傿•°ï¼š + NAME å°†è¦è§£æžçš„命令。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称为åªè¯»ã€‚ + +[trap] + 对信å·å’Œå…¶ä»–事件设陷阱。 + + 定义一个处ç†å™¨ï¼Œåœ¨ shell 接收到信å·å’Œå…¶ä»–æ¡ä»¶ä¸‹æ‰§è¡Œã€‚ + + ARG 傿•°æ˜¯å½“ shell 接收到 SIGNAL_SPEC ä¿¡å·æ—¶è¯»å–和执行的命令。 + 如果没有指定 ARG 傿•° (并且åªç»™å‡ºä¸€ä¸ª SIGNAL_SPEC ä¿¡å·) 或者 + ARG 傿•°ä¸º + `-',æ¯ä¸€ä¸ªæŒ‡å®šçš„傿•°ä¼šè¢«é‡ç½®ä¸ºåŽŸå§‹å€¼ã€‚å¦‚æžœ ARG 傿•°æ˜¯ä¸€ä¸ªç©ºä¸²ï¼Œåˆ™æ¯ä¸€ + 个 + SIGNAL_SPEC ä¿¡å·ä¼šè¢« shell 和它å¯åŠ¨çš„å‘½ä»¤å¿½ç•¥ã€‚ + + 如果一个 SIGNAL_SPEC ä¿¡å·æ˜¯ EXIT (0) ,则 ARG 命令会在 shell 退出时被 + 执行。如果一个 SIGNAL_SPEC ä¿¡å·æ˜¯ DEBUG,则 ARG命令会在æ¯ä¸€ä¸ªç®€å•命 + 令之剿‰§è¡Œã€‚ + + å¦‚æžœä¸æä¾›å‚æ•°ï¼Œtrap 打å°åˆ—表显示æ¯ä¸€ä¸ªä¸Žæ¯ä¸€ä¸ªä¿¡å·ç›¸å…³è”的命令。 + + 选项: + -l 打å°ä¸€ä¸ªä¿¡å·å称和它们对应的编å·çš„列表 + -p 打å°ä¸Žæ¯ä¸ª SIGNAL_SPEC ä¿¡å·ç›¸å…³è”的陷阱命令 + + æ¯ä¸€ä¸ª SIGNAL_SPEC ä¿¡å·å¯ä»¥æ˜¯ 中的信å·å称或者信å·ç¼–å·ã€‚ + ä¿¡å·å称大å°å†™æ•感且å¯ä»¥ä½¿ç”¨ SIG å‰ç¼€ã€‚ä¿¡å·å¯ç”¨ \kill -ä¿¡å· $$\ + å‘é€ç»™ shell。 + + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 SIGSPEC。 + +[alias] + 定义或显示别å。 + + ä¸å¸¦å‚数时,`alias' 以å¯é‡ç”¨çš„æ ¼å¼ + `alias åç§°=值'在标准输出设备上打å°åˆ«å列表。 + + å¦åˆ™ï¼Œå¯¹äºŽæ¯ä¸ªç»™å®šå€¼çš„å称定义一个别å。 + 值末尾的空格会使下一个è¯è¢«æ£€æµ‹ä½œä¸ºåˆ«å替æ¢å±•开。 + + 选项: + -p 以å¯é‡ç”¨çš„æ ¼å¼æ‰“å°æ‰€æœ‰çš„已定义的别å + + 退出状æ€ï¼š + 除éžä¸€ä¸ªæ²¡æœ‰å®šä¹‰çš„åå­—è¢«ä½œä¸ºå‚æ•°æä¾›ï¼Œå¦åˆ™ alias + 返回值为真。 + +[unalias] + 从别å定义列表中删除æ¯ä¸€ä¸ªâ€œåå­—â€ã€‚ + + 选项: + -a 删除所有的别å定义 + + 返回æˆåŠŸï¼Œé™¤éžâ€œåå­—â€ä¸æ˜¯ä¸€ä¸ªå·²å­˜åœ¨çš„别å。 + +[break] + 退出 forã€while 或 until 循环 + + 退出一个 FORã€WHILE 或 UNTIL 循环。如果指定了N,则跳出Né‡ + 循环 + + 退出状æ€ï¼š + 退出状æ€ä¸º0é™¤éž N ä¸å¤§äºŽæˆ–等于 1。 + +[continue] + ç»§ç»­ forã€while 或 until 循环。 + + ç»§ç»­å½“å‰ FORã€WHILE 或 UNTIL 循环的下一步。 + 如果指定了 N, 则继续当å‰çš„第 N é‡å¾ªçŽ¯ã€‚ + + 退出状æ€ï¼š + 退出状æ€ä¸º 0 é™¤éž N ä¸å¤§äºŽæˆ–等于1。 + +[builtin] + 执行 shell 内建。 + + 另傿•° ARGs 执行 SHELL-BUILTIN 内建,并且ä¸åšå‘½ä»¤æŸ¥è¯¢ + 在希望以 shell å‡½æ•°çš„å½¢å¼æ¥é‡æ–°å®žçް shell 内建, + 并且希望在函数之内执行该 shell 内建的情况下有用处。 + + 退出状æ€ï¼š + 以 SHELL-BUILTIN 内建的退出状æ€ä¸ºå‡†ï¼Œæˆ–者如果 SHELL-BUILTIN 䏿˜¯ä¸€ä¸ª + shell 内建时为å‡ã€‚ + +[caller] + 返回当å‰å­è°ƒç”¨çš„上下文。 + + ä¸å¸¦æœ‰ EXPR 时,返回 $line $filename。带有 EXPR 时,返回 + $line $subroutine $filename;这个é¢å¤–的信æ¯å¯ä»¥è¢«ç”¨äºŽæä¾› + 栈追踪。 + + EXPR 的值 显示了到当å‰è°ƒç”¨å¸§éœ€è¦å›žåŽ»å¤šå°‘ä¸ªè°ƒç”¨å¸§ï¼›é¡¶éƒ¨å¸§ + 是第 0 帧。 + + 退出状æ€ï¼š + é™¤éž shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ª shell 函数或者 EXPR 无效,å¦åˆ™è¿”回结 + 果为0。 + +[cd] + æ”¹å˜ shell 工作目录。 + + 改å˜å½“å‰ç›®å½•至 DIR 目录。默认的 DIR 目录是 shell å˜é‡ HOME + 的值。 + + å˜é‡ CDPATH å®šä¹‰äº†å«æœ‰ DIR 的目录的æœç´¢è·¯å¾„,其中ä¸åŒçš„目录åç§°ç”±å†’å· (:) + 分隔。 + 一个空的目录å称表示当å‰ç›®å½•。如果è¦åˆ‡æ¢åˆ°çš„ DIR ç”±æ–œæ  (/) 开头,则 + CDPATH + ä¸ä¼šç”¨ä¸Šå˜é‡ã€‚ + + 如果路径找ä¸åˆ°ï¼Œå¹¶ä¸” shell 选项 `cdable_vars' è¢«è®¾å®šï¼Œåˆ™å‚æ•°è¯è¢«å‡å®šä¸ºä¸€ + 个 + å˜é‡å。如果该å˜é‡æœ‰å€¼ï¼Œåˆ™å®ƒçš„值被当作 DIR 目录。 + + 选项: + -L 强制跟éšç¬¦å·é“¾æŽ¥: åœ¨å¤„ç† `..' 之åŽè§£æž DIR 中的符å·é“¾æŽ¥ã€‚ + -P 使用物ç†ç›®å½•结构而ä¸è·Ÿéšç¬¦å·é“¾æŽ¥: åœ¨å¤„ç† `..' 之å‰è§£æž DIR 中的符 + å·é“¾æŽ¥ã€‚ + -e 如果使用了 -P 傿•°ï¼Œä½†ä¸èƒ½æˆåŠŸç¡®å®šå½“å‰å·¥ä½œç›®å½•时,返回éžé›¶çš„返回 + 值。 + -@ åœ¨æ”¯æŒæ‹“展属性的系统上,将一个有这些属性的文件当作有文件属性的目 + 录。 + + 默认情况下跟éšç¬¦å·é“¾æŽ¥ï¼Œå¦‚åŒæŒ‡å®š `-L'。 + `..' 使用移除å‘å‰ç›¸é‚»ç›®å½•åæˆå‘˜ç›´åˆ° DIR 开始或一个斜æ çš„æ–¹å¼å¤„ç†ã€‚ + + 退出状æ€ï¼š + 如果目录改å˜ï¼Œæˆ–在使用 -P 选项时 $PWD 修改æˆåŠŸæ—¶è¿”å›ž 0,å¦åˆ™éžé›¶ã€‚ + +[pwd] + 打å°å½“å‰å·¥ä½œç›®å½•çš„å字。 + + 选项: + -L æ‰“å° $PWD å˜é‡çš„值,如果它包å«äº†å½“å‰çš„工作目录 + -P 打å°å½“å‰çš„物ç†è·¯å¾„,ä¸å¸¦æœ‰ä»»ä½•的符å·é“¾æŽ¥ + + 默认情况下,`pwd' 的行为和带 `-L' 选项一致 + + 退出状æ€ï¼š + 除éžä½¿ç”¨äº†æ— æ•ˆé€‰é¡¹æˆ–者当å‰ç›®å½•ä¸å¯è¯»ï¼Œå¦åˆ™è¿”回状æ€ä¸º0。 + +[true] + 空的命令。 + + 没有效果; 此命令ä¸åšä»»ä½•æ“作。 + + 退出状æ€ï¼š + 总是æˆåŠŸã€‚ + +[shopt] + è®¾å®šå’Œå–æ¶ˆè®¾å®š shell 选项。 + + æ”¹å˜æ¯ä¸ª shell 选项 OPTNAME 的设定。ä¸å¸¦å‚数时, + 列出æ¯ä¸ªæä¾›çš„ OPTNAME,å¦åˆ™åˆ—出所有 shell 选项; + åŒæ—¶æ ‡æ³¨æ¯ä¸€ä¸ªé€‰é¡¹æ˜¯å¦è¢«è®¾å®šã€‚ + + 选项: + -o é™åˆ¶ OPTNAME 为定义用于`set -o' 的选项 + -p æ‰“å°æ¯ä¸ª shell 选项并标注它的状æ€ã€‚ + -q 抑制输出 + -s å¯ç”¨(设定)æ¯ä¸ª OPTNAME 选项 + -u ç¦ç”¨(å–æ¶ˆè®¾å®š)æ¯ä¸ª OPTNAME 选项 + + 退出状æ€ï¼š + 如果 OPTNAME 选项被å¯ç”¨åˆ™è¿”回æˆåŠŸï¼›å¦‚æžœæ˜¯ + 无效的选项或 OPTNAME 被ç¦ç”¨åˆ™å¤±è´¥ã€‚ + +[false] + è¿”å›žä¸€ä¸ªä¸æˆåŠŸçš„ç»“æžœã€‚ + + 退出状æ€ï¼š + 总是失败。 + +[command] + 执行一个简å•命令或者显示命令的相关信æ¯ã€‚ + + 带 ARGS 傿•°è¿è¡Œ COMMAND 命令且抑制 shell 函数查询,或显示 + 指定的 COMMAND 命令的信æ¯ã€‚å¯ä»¥åœ¨å­˜åœ¨ç›¸åŒå称的函数定义的 + 情况下用于å¯åЍç£ç›˜ä¸Šçš„命令。 + + 选项: + -p 使用 PATH å˜é‡çš„ä¸€ä¸ªé»˜è®¤å€¼ä»¥ç¡®ä¿æ‰€æœ‰çš„æ ‡å‡†å·¥å…·éƒ½èƒ½è¢«æ‰¾åˆ°ã€‚ + -v æ‰“å° COMMAND 命令的æè¿°ï¼Œå’Œ `type' 内建相似 + -V æ‰“å°æ¯ä¸ª COMMAND 命令的详细æè¿° + + é€€å‡ºçŠ¶æ€ + 返回 COMMAND 命令的返回状æ€ï¼Œæˆ–者当找ä¸åˆ° COMMAND 命令时失败。 + +[echo] + 将傿•°å†™åˆ°æ ‡å‡†è¾“出。 + + 在标准输出上,显示用空格分割的 ARG 傿•°åŽè·Ÿä¸€ä¸ªæ¢è¡Œã€‚ + + 选项: + -n ä¸è¦è¿½åŠ æ¢è¡Œ + -e å¯ç”¨ä¸‹åˆ—åæ–œæ è½¬ä¹‰çš„解释 + -E 显å¼åœ°æŠ‘åˆ¶å¯¹äºŽåæ–œæ è½¬ä¹‰çš„解释 + + `echo' å¯¹ä¸‹åˆ—åæ–œæ å­—符进行转义: + \a 警告(å“铃) + \\b 退格 + \\c 抑制更多的输出 + \\e 转义字符 + \\f æ¢é¡µå­—符 + \\tæ¢è¡Œ + \\r\t回车 + \\t\t横å‘制表符 + \\v\t纵å‘制表符 + \\\\\tåæ–œæ  + \\0nnn 以 NNN(八进制)为 ASCII ç çš„字符。NNN å¯ä»¥æ˜¯ 0 到 3 个八进制 + ä½ + \\xHH 以 HH(å六进制)为值的八比特字符。HH å¯ä»¥æ˜¯ä¸€ä¸ªæˆ–两个å六进制 + ä½ + \\uHHHH 以 HHHH(å六进制)为值的 Unicode 字符。HHHH å¯ä»¥æ˜¯ä¸€ä¸ªåˆ° + 四个å六进制ä½ã€‚ + \\UHHHHHHHH 以 HHHHHHHH(å六进制)为值的 Unicode 字符。 + HHHHHHHH å¯ä»¥æ˜¯ä¸€åˆ°å…«ä¸ªå六进制ä½ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžæœ‰å†™é”™è¯¯å‘生。 + + 写傿•°è‡³æ ‡å‡†è¾“出设备。 + + 在标准输出设备上显示 ARGs 傿•°å’Œä¸€ä¸ªæ¢è¡Œã€‚ + + 选项: + -n ä¸é™„加æ¢è¡Œ + + 退出状æ€ï¼š + 除éžå†™é”™è¯¯å‘生,å¦åˆ™è¿”回æˆåŠŸã€‚ + +[enable] + å¯ç”¨å’Œç¦ç”¨ shell 内建。 + + å¯ç”¨å’Œç¦ç”¨ shell 的内建命令。ç¦ç”¨ä½¿æ‚¨èƒ½å¤Ÿæ‰§è¡Œä¸€ä¸ªå’Œå†…建 + 命令åŒåçš„ç£ç›˜ä¸Šçš„命令,而无须使用完整的路径å。 + + + 选项: + -a 打å°ä¸€ä¸ªå†…建的列表,并显示其中æ¯ä¸€ä¸ªæ˜¯å¦å¯ç”¨ + -n ç¦ç”¨æ¯ä¸€ä¸ª NAME 内建或者显示一个被ç¦ç”¨çš„内建的列表 + -p 以å¯é‡ç”¨çš„æ ¼å¼æ‰“å°ä¸€ä¸ªå†…建的列表 + -s 仅打å°Posix `special' 内建的åç§° + + 控制动æ€åŠ è½½çš„é€‰é¡¹ï¼š + -f 从共享对象 FILENAME 文件中加载 NAME 内建 + -d 删除以 -f 选项加载的内建 + + ä¸å¸¦é€‰é¡¹æ—¶ï¼Œæ¯ä¸€ä¸ª NAME 内建都被å¯ç”¨ã€‚ + + 如果è¦ä½¿ç”¨ $PATH 中找到的 `test' è€Œä¸æ˜¯ shell 内建的版本, + 输入 `enable -n test'。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éž NAME 䏿˜¯ä¸€ä¸ª shell 内建或者有错误å‘生。 + +[getopts] + è§£æžé€‰é¡¹å‚数。 + + getopts 被 shell 过程用于解æžå¯å®šä½çš„傿•°ä½œä¸ºé€‰é¡¹ã€‚ + + + OPTSTRING 字符串包å«å¾…识别的选项字æ¯ï¼›å¦‚果一个字æ¯åŽé¢è·Ÿ + ç€åˆ†å·ï¼Œåˆ™è¯¥é€‰é¡¹éœ€è¦ä¸€ä¸ªå‚æ•°ï¼Œè€Œè¯¥å‚æ•°åº”用空格与选项分开。 + + + æ¯æ¬¡å¯åŠ¨æ—¶ï¼Œgetopts 会将下一个选项放到 shell å˜é‡ $name + 中,如果 name å˜é‡ä¸å­˜åœ¨åˆ™å…ˆå°†å…¶åˆå§‹åŒ–,而下一个待处 + ç†çš„傿•°åºå·æ”¾å…¥ shell å˜é‡ OPTIND 中。OPTIND å˜é‡åœ¨æ¯ + 次 shell 或者 shell 脚本å¯åŠ¨æ—¶éƒ½è¢«åˆå§‹åŒ–为1ã€‚å½“ä¸€ä¸ªé€‰é¡¹è¦ + æ±‚æœ‰ä¸€ä¸ªå‚æ•°æ—¶ï¼Œgetopts 将傿•°æ”¾å…¥ shell å˜é‡ OPTARG + 中。 + + getopts æœ‰ä¸¤ç§æŠ¥å‘Šé”™è¯¯çš„æ–¹æ³•ã€‚å¦‚æžœ OPTSTRING å˜é‡çš„第 + 一个字符是冒å·ï¼Œgetopts ä½¿ç”¨æ²‰é»˜é”™è¯¯æŠ¥å‘Šã€‚åœ¨è¿™ç§æ¨¡å¼ + 下,ä¸ä¼šæ‰“å°é”™è¯¯æ¶ˆæ¯ã€‚如果看到了一个无效的选项, + getopts 将找到的选项字符放至 OPTARG å˜é‡ä¸­ã€‚如果一个必 + 须的选项没有找到,getopts 放一个 ':' 到 NAME å˜é‡ä¸­å¹¶ä¸”设 + ç½® OPTARG å˜é‡ä¸ºæ‰¾åˆ°çš„选项字符。如果 getopts ä¸åœ¨æ²‰é»˜æ¨¡ + å¼ä¸­ï¼Œå¹¶ä¸”é‡åˆ°äº†ä¸€ä¸ªæ— æ•ˆçš„选项,getopts 放置一个 '?' 到 NAME + å˜é‡ä¸­å¹¶ä¸”å–æ¶ˆè®¾å®š OPTARGå˜é‡ã€‚如果必须的选项没有找到, + 一个'?'会被放入 NAMEå˜é‡ä¸­ï¼ŒOPTARG å°†è¢«å–æ¶ˆè®¾å®šï¼Œå¹¶ä¸”会 + 打å°ä¸€ä¸ªè¯Šæ–­ä¿¡æ¯ã€‚ + + 如果 shell å˜é‡ OPTERR 的值为0,getopts ç¦ç”¨ + 错误信æ¯çš„æ‰“å°ï¼Œå³ä½¿ OPTSTRING å˜é‡çš„ç¬¬ä¸€ä¸ªå­—ç¬¦ä¸æ˜¯ä¸€ + 个冒å·ã€‚OPTERR 的默认值为1. + + getopts 通常解æžå¯å®šä½çš„傿•°($0 - $9),ä¸è¿‡å¦‚æžœæä¾›äº† + æ›´å¤šçš„å‚æ•°ï¼Œå®ƒä»¬å而会被解æžã€‚ + + 退出状æ€ï¼š + 如果一个选项被找到则返回æˆåŠŸï¼›å¦‚æžœé‡åˆ°äº†é€‰é¡¹çš„结尾或者 + 有错误å‘生则返回失败。 + +[exec] + ä½¿ç”¨æŒ‡å®šå‘½ä»¤æ›¿æ¢ shell。 + + 执行 COMMAND å‘½ä»¤ï¼Œä»¥æŒ‡å®šçš„ç¨‹åºæ›¿æ¢è¿™ä¸ª shell。 + ARGUMENTS 傿•°æˆä¸º COMMANDå‘½ä»¤çš„å‚æ•°ã€‚如果 + 没有指定COMMAND 命令,则任何的é‡å®šå‘åœ¨å½“å‰ shell 中生效。 + + 选项: + -a åç§° 作为第0ä¸ªå‚æ•°ä¼ é€’ç»™ COMMAND 命令 + -c 在一个空环境中执行 COMMAND 命令 + -l 在COMMAND 命令的第0ä¸ªå‚æ•°ä¸­åŠ ä¸€ä¸ªçŸ­çº¿ + + 如果命令ä¸èƒ½è¢«æ‰§è¡Œï¼Œåˆ™é€€å‡ºä¸€ä¸ªéžäº¤äº’å¼çš„ shellï¼Œé™¤éž + shell 选项`execfail' å·²ç»è®¾å®šã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éž COMMAND 命令没有找到或者出现一个é‡å®šå‘错误。 + +[exit] + 退出shell。 + + ä»¥çŠ¶æ€ N 退出 shell。 如果 N 被çœç•¥ï¼Œåˆ™é€€å‡ºçŠ¶æ€ + 为最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的退出状æ€ã€‚ + +[logout] + 退出一个登录 shell. + + ä»¥çŠ¶æ€ N 退出一个登录 shell。如果ä¸åœ¨ç™»å½• shell 中执行,则 + 返回一个错误。 + +[fc] + 从历å²åˆ—表中显示或者执行命令。 + + fc 被用于从历å²åˆ—è¡¨ä¸­åˆ—å‡ºæˆ–è€…é‡æ–°ç¼–辑并执行命令。 + FIRST å’Œ LAST å˜é‡å¯ä»¥æ˜¯æ•°å­—用于指定范围,或者 FIRST å¯ä»¥æ˜¯ + 字符串,æ„味ç€ä»¥è¿™ä¸ªå­—符串打头的最近的一个命令。 + + + 选项: + -e ENAME 选择使用哪个编辑器。默认的是 FCEDIT, ç„¶åŽæ˜¯ EDITOR, + ç„¶åŽæ˜¯ vi + -l 列出行而ä¸ç¼–辑 + -n 列举时çœç•¥è¡Œå· + -r å转行的顺åº(最新行在å‰) + + 用 `fc -s [模å¼=æ›¿æ¢ ...] [命令]' 的格å¼ï¼ŒCOMMAND 命令会在 OLD=NEW + 替æ¢ä¹‹åŽè¢«é‡æ–°æ‰§è¡Œã€‚ + + r='fc -s' 是一个有用的别å,这样的è¯è¾“å…¥ `r cc'会执行最åŽä¸€ä¸ªä»¥ `cc' + 开头的命令,输入 `r'ä¼šé‡æ–°æ‰§è¡Œæœ€åŽä¸€ä¸ªå‘½ä»¤ã€‚ + + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œæˆ–è€…æ‰§è¡Œçš„å‘½ä»¤çš„çŠ¶æ€ï¼›å¦‚果错误å‘生则返回éžé›¶ã€‚ + +[fg] + 将任务移至å‰å°ã€‚ + + 将以 JOB_SPEC 标识的任务放至å‰å°ï¼Œä½¿å…¶æˆä¸º + 当å‰ä»»åŠ¡ã€‚å¦‚æžœ JOB_SPEC ä¸å­˜åœ¨ï¼Œshell 观念中的当å‰ä»»åŠ¡ + 将被使用。 + + 退出状æ€ï¼š + 放至å‰å°çš„命令状æ€ï¼Œæˆ–者当错误å‘生时为失败。 + +[bg] + 移动任务至åŽå°ã€‚ + + å°† JOB_SPEC 标识的任务放至åŽå°ï¼Œå°±åƒå®ƒä»¬ + 是带 `&' å¯åŠ¨çš„ä¸€æ ·ã€‚å¦‚æžœ JOB_SPEC ä¸å­˜åœ¨ï¼Œshell 观念中的 + 当å‰ä»»åŠ¡å°†ä¼šè¢«ä½¿ç”¨ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžä»»åŠ¡ç®¡ç†æ²¡æœ‰å¯ç”¨æˆ–者错误å‘生。 + +[hash] + è®°ä½æˆ–显示程åºä½ç½®ã€‚ + + ç¡®å®šå¹¶è®°ä½æ¯ä¸€ä¸ªç»™å®š NAME å称的命令的完整路径。 + å¦‚æžœä¸æä¾›å‚æ•°ï¼Œåˆ™æ˜¾ç¤ºå·²ç»è®°ä½çš„命令的信æ¯ã€‚ + + 选项: + -d 忘记æ¯ä¸€ä¸ªå·²ç»è®°ä½çš„ NAME çš„ä½ç½® + -l 以å¯ä½œä¸ºè¾“å…¥é‡ç”¨çš„æ ¼å¼æ˜¾ç¤º + -p pathname 使用 pathname 路径作为 NAME 命令的全路径 + -r 忘记所有记ä½çš„ä½ç½® + -t 打å°è®°ä½çš„æ¯ä¸€ä¸ª NAME åç§°çš„ä½ç½®ï¼Œå¦‚果指定了多个 + NAME å称,则æ¯ä¸ªä½ç½®å‰é¢ä¼šåŠ ä¸Šç›¸åº”çš„ NAME åç§° + + 傿•°ï¼š + NAME æ¯ä¸ª NAME å称会在 $PATH 路径å˜é‡ä¸­è¢«æœç´¢ï¼Œå¹¶ä¸”添加到记ä½çš„命 + 令 + 列表中。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éž NAME 命令没有找到或者使用了无效的选项。 + +[help] + 显示内建命令的相关信æ¯ã€‚ + + 显示内建命令的简略信æ¯ã€‚如果指定了 PATTERN 模å¼ï¼Œ + ç»™å‡ºæ‰€æœ‰åŒ¹é… PATTERN 模å¼çš„命令的详细帮助,å¦åˆ™æ‰“ + å°ä¸€ä¸ªå¸®åŠ©ä¸»é¢˜åˆ—è¡¨ + + 选项: + -d 输出æ¯ä¸ªä¸»é¢˜çš„简短æè¿° + -m 以伪 man æ‰‹å†Œçš„æ ¼å¼æ˜¾ç¤ºä½¿ç”¨æ–¹æ³• + -s 为æ¯ä¸€ä¸ªåŒ¹é… PATTERN 模å¼çš„主题仅显示一个用法 + 简介 + + 傿•°ï¼š + PATTERN æŒ‡å®šå¸®åŠ©ä¸»é¢˜çš„æ¨¡å¼ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžæœªæ‰¾åˆ° PATTERN æ¨¡å¼æ²¡æœ‰æ‰¾åˆ°æˆ–者使用了无效选项。 + +[history] + 显示或æ“纵历å²åˆ—表。 + + å¸¦è¡Œå·æ˜¾ç¤ºåކå²åˆ—表,将æ¯ä¸ªè¢«ä¿®æ”¹çš„æ¡ç›®åŠ ä¸Š `*' å‰ç¼€ã€‚ + 傿•° N 会仅列出最åŽçš„ N 个æ¡ç›®ã€‚ + + 选项: + -c 删除所有æ¡ç›®ä»Žè€Œæ¸…空历å²åˆ—表。 + -d åç§»é‡ ä»ŽæŒ‡å®šä½ç½®åˆ é™¤åކå²åˆ—表。负åç§»é‡å°†ä»Žåކ岿¡ç›®æœ«å°¾ + 开始计数 + + -a 将当å‰ä¼šè¯çš„历å²è¡Œè¿½åŠ åˆ°åŽ†å²æ–‡ä»¶ä¸­ + -n ä»ŽåŽ†å²æ–‡ä»¶ä¸­è¯»å–所有未被读å–的行 + 并且将它们附加到历å²åˆ—表 + -r 读å–åŽ†å²æ–‡ä»¶å¹¶å°†å†…容追加到历å²åˆ—表中 + -w 将当å‰åކå²å†™å…¥åˆ°åކ岿–‡ä»¶ä¸­ + + -p 对æ¯ä¸€ä¸ª ARG 傿•°å±•开历å²å¹¶æ˜¾ç¤ºç»“果,而ä¸å­˜å‚¨åˆ°åކå²åˆ—表中 + -s 以啿¡è®°å½•追加 ARG 到历å²åˆ—表中 + + 如果给定了 FILENAME 文件åï¼Œåˆ™å®ƒå°†è¢«ä½œä¸ºåŽ†å²æ–‡ä»¶ã€‚å¦åˆ™ + 如果 $HISTFILE å˜é‡æœ‰å€¼çš„è¯ä½¿ç”¨ä¹‹ï¼Œä¸ç„¶ä½¿ç”¨ ~/.utshell_history 文件。 + + 如果 $HISTTIMEFORMAT å˜é‡è¢«è®¾å®šå¹¶ä¸”ä¸ä¸ºç©ºï¼Œå®ƒçš„值会被用于 + strftime(3) 的格å¼å­—ç¬¦ä¸²æ¥æ‰“å°ä¸Žæ¯ä¸€ä¸ªæ˜¾ç¤ºçš„åŽ†å²æ¡ç›®æƒ³å…³è”çš„ + 时间戳,å¦åˆ™ä¸æ‰“å°æ—¶é—´æˆ³ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者å‘生错误。 + +[jobs] + 显示任务状æ€ã€‚ + + 列出活动的任务。JOBSPEC é™åˆ¶ä»…输出指定的任务。 + ä¸å¸¦é€‰é¡¹æ—¶ï¼Œæ‰€æœ‰æ´»åŠ¨ä»»åŠ¡çš„çŠ¶æ€éƒ½ä¼šæ˜¾ç¤ºã€‚ + + 选项: + -l 在正常信æ¯åŸºç¡€ä¸Šåˆ—å‡ºè¿›ç¨‹å· + -n ä»…åˆ—å‡ºä¸Šæ¬¡é€šå‘Šä¹‹åŽæ”¹å˜äº†çжæ€çš„进程 + -p ä»…åˆ—å‡ºè¿›ç¨‹å· + -r é™åˆ¶ä»…输出è¿è¡Œä¸­çš„任务 + -s é™åˆ¶ä»…è¾“å‡ºåœæ­¢çš„任务 + + 如果使用了 -x 选项,ARG 傿•°ä¸­çš„æ‰€æœ‰ä»»åŠ¡å£°æ˜Žä¼šè¢«æ›¿æ¢ä¸ºè¯¥ä»»åŠ¡ + 的进程组头领的进程å·ï¼Œç„¶åŽæ‰§è¡Œ COMMAND 命令。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者有错误å‘生。 + 如果使用 -x 选项,则返回 COMMAND 命令的退出状æ€ã€‚ + +[disown] + ä»Žå½“å‰ shell 中删除任务。 + + 从活动任务表中删除æ¯ä¸€ä¸ª JOBSPEC 傿•°ã€‚ä¸å¸¦ä»»ä½• + JOBSPEC 傿•°æ—¶ï¼Œshell 使用观念中的当å‰ä»»åŠ¡ã€‚ + + 选项: + -a å¦‚æžœä¸æä¾› JOBSPEC 傿•°ï¼Œåˆ™åˆ é™¤æ‰€æœ‰ä»»åŠ¡ + -h 标识æ¯ä¸ª JOBSPEC 任务,从而当 shell 接收到 SIGHUP + ä¿¡å·æ—¶ä¸å‘é€ SIGHUP 给指定任务 + -r 仅删除è¿è¡Œä¸­çš„任务 + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 JOBSPEC 声明。 + +[kill] + å‘一个任务å‘é€ä¸€ä¸ªä¿¡å·ã€‚ + + å‘以 PID è¿›ç¨‹å·æˆ–者 JOBSPEC 任务声明指定的进程å‘é€ä¸€ä¸ªä»¥ + SIGSPEC ä¿¡å·å£°æ˜Žæˆ– SIGNUM ä¿¡å·ç¼–å·å‘½å的信å·ã€‚如果没有指定 + SIGSPEC 或 SIGNUM,那么å‡å®šå‘é€ SIGTERM ä¿¡å·ã€‚ + + 选项: + -s sig SIG 是信å·åç§° + -n sig SIG 是信å·ç¼–å· + -l 列出信å·åç§°ï¼›å¦‚æžœå‚æ•°åŽè·Ÿ `-l'则被å‡è®¾ä¸ºä¿¡å·ç¼–å·ï¼Œ + 而相应的信å·å称会被列出 + + Kill æˆä¸º shell 内建有两个ç†ç”±ï¼šå®ƒå…许使用任务编å·è€Œä¸æ˜¯è¿›ç¨‹å·ï¼Œ + 并且在å¯ä»¥åˆ›å»ºçš„进程数上é™è¾¾åˆ°æ˜¯å…è®¸è¿›ç¨‹è¢«æ€æ­»ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者有错误å‘生。 + +[let] + 估值算术表达å¼ã€‚ + + å°†æ¯ä¸ª ARG å‚èµ›ä½œä¸ºç®—æœ¯è¡¨è¾¾å¼æ¥ä¼°å€¼ã€‚估值的计算以定宽的整 + 数完æˆï¼Œä¸å¸¦æº¢å‡ºæ£€æµ‹ï¼Œä¸è¿‡é™¤ 0 是被置陷阱的并且会报一个错 + 误。下列æ“作符被按照相åŒçš„算术优先级组åˆã€‚åˆ—è¡¨çš„é¡ºåºæŒ‰ç…§ + 优先级从高至低。 + + id++, id-- å˜é‡åŽç½®åŠ ï¼ŒåŽç½®å‡ + ++id, --id å˜é‡å‰ç½®åŠ ï¼Œå‰ç½®å‡ + -, + ä¸€å…ƒå‡æ³•,一元加法 + !, ~ 逻辑和ä½å–å + '**' 指数 + '*', /, '%' 乘法,除法,å–余数 + +, - 增加,å‡å°‘ + <<, >> å‘左和å‘峿Œ‰ä½ç§»ä½ + <=, >=, <, > 比较 + ==, != 等于,ä¸ç­‰äºŽ + & 按ä½ä¸Ž + ^ 按ä½å¼‚或 + | æŒ‰ä½æˆ– + && 逻辑与 + || 逻辑或 + expr ? expr : expr + æ¡ä»¶æ“作符 + =, *=, /=, %=, + +=, -=, <<=, >>=, + &=, ^=, |= 赋值 + + Shell å˜é‡å…许作为æ“作数。表达å¼ä¸­çš„å˜é‡çš„å称会被å–代以值 + (强制转æ¢ä¸ºå®šå®½çš„æ•´æ•°)。表达å¼ä¸­çš„å˜é‡ä¸éœ€è¦æ‰“开整数属性。 + + æ“作符按照优先级进行估值。括å·ä¸­çš„å­è¡¨è¾¾å¼å°†è¢«å…ˆä¼°å€¼ï¼Œå¹¶å¯å–ä»£ä¸Šè¿°è¡¨è¾¾å¼ + 规则。 + + 退出状æ€ï¼š + 如果最åŽä¸€ä¸ª ARG 傿•°ä¼°å€¼ä¸º 0,则 let 返回 1ï¼› å¦åˆ™ let 返回 0。 + +[shift] + ç§»ä½ä½ç½®å‚数。 + + é‡å‘½åä½ç½®å‚æ•° $N+1ã€$N+2 ... 到 $1ã€$2 ... 如果没有给定 N, + 则å‡è®¾ä¸º1. + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éž N 为负或者大于 $#。 + 返回 N,或者如果 shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ªå‡½æ•°æˆ–引用脚本时,失败。 + +[suspend] + 挂起 shell 执行。 + + 挂起 shell 的执行直到收到 SIGCONT ä¿¡å·ã€‚ + 登录 shell ä¸å¯ä»¥è¢«æŒ‚起,除éžå¼ºåˆ¶æ‰§è¡Œã€‚ + + 选项: + -f 强制挂起,å³ä½¿æ˜¯ç™»å½• shell。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžæ²¡æœ‰å¯ç”¨ä»»åŠ¡æŽ§åˆ¶æˆ–è€…æœ‰é”™è¯¯å‘生。 + +[test] + 对æ¡ä»¶è¡¨è¾¾å¼è¿›è¡Œä¼°å€¼ã€‚ + + æ ¹æ® EXPR 表达å¼çš„ä¼°å€¼ä»¥çŠ¶æ€ 0 (真) 或 1 (伪) 退出。 + 表达å¼å¯ä»¥æ˜¯ä¸€å…ƒæˆ–者二元的。一元表达å¼é€šå¸¸ç”¨äºŽæ£€æµ‹ + 文件状æ€ã€‚åŒæ—¶è¿˜æœ‰å­—符串æ“作符和数字比较æ“作符。 + + 文件æ“作符: + + -a 文件 如果文件存在则为真。 + -b 文件 如果文件为å—特殊文件则为真。 + -c 文件 如果文件为字符特殊文件则为真。 + -d 文件 如果文件为目录则为真。 + -e 文件 如果文件存在则为真。 + -f 文件 如果文件存在且为常规文件则为真。 + -g 文件 如果文件的组属性设置打开则为真。 + -h 文件 如果文件为符å·é“¾æŽ¥åˆ™ä¸ºçœŸã€‚ + -L 文件 如果文件为符å·é“¾æŽ¥åˆ™ä¸ºçœŸã€‚ + -k 文件 如果文件的粘滞 (sticky) ä½è®¾å®šåˆ™ä¸ºçœŸã€‚ + -p 文件 如果文件为命å管é“则为真。 + -r 文件 如果文件对于您是å¯è¯»çš„则为真。 + -s 文件 如果文件存在且ä¸ä¸ºç©ºåˆ™ä¸ºçœŸã€‚ + -S 文件 如果文件是套接字则为真。 + -t 文件æè¿°ç¬¦ 如果文件æè¿°ç¬¦åœ¨ä¸€ä¸ªç»ˆç«¯ä¸Šæ‰“开则为真。 + -u 文件 如果文件的用户数行设置打开则为真。 + -w 文件 如果文件对您是å¯å†™çš„则为真 + -x 文件 å¦‚æžœæ–‡ä»¶å¯¹æ‚¨æ˜¯å¯æ‰§è¡Œçš„则为真。 + -O 文件 如果文件是被您所有的则为真。 + -G 文件 如果文件被您的组所有则为真。 + -N 文件 如果文件上次被读å–之åŽä¿®æ”¹è¿‡åˆ™ä¸ºçœŸã€‚ + + FILE1 -nt FILE2 如果 file1 文件新于 file2 文件则为真(æ ¹æ® + 修改日期)。 + + FILE1 -ot FILE2 如果 file1 文件旧于 file2 文件则为真。 + + FILE1 -ef FILE2 如果 file1 文件是 file2 文件的硬链接则为真。 + + 字符串æ“作符 + + -z 字符串 如果字符串为空则为真。 + + -n 字符串 + 字符串 如果字符串ä¸ä¸ºç©ºåˆ™ä¸ºçœŸã€‚ + + STRING1 = STRING2 + 如果 string1 å’Œ string2 字符串相åŒåˆ™ä¸ºçœŸã€‚ + STRING1 != STRING2 + 如果 string1 å’Œ string2 字符串ä¸ç›¸åŒåˆ™ä¸ºçœŸã€‚ + STRING1 < STRING2 + å¦‚æžœæŒ‰å­—å…¸æŽ’åº string1 在 string2 串之å‰åˆ™ä¸ºçœŸã€‚ + STRING1 > STRING2 + å¦‚æžœæŒ‰å­—å…¸æŽ’åº string1 在 string2 串之å‰åˆ™ä¸ºçœŸã€‚ + + å…¶ä»–æ“作符: + + -o 选项 如果指定 shell 选项å¯ç”¨åˆ™ä¸ºçœŸã€‚ + -v VAR 如果指定 Shell å˜é‡ VAR 已赋值则为真。 + -R VAR 如果指定 Shell å˜é‡ VAR 已赋值且为å称引用则为真。 + ! EXPR å¦‚æžœè¡¨è¾¾å¼ expr 为å‡åˆ™ä¸ºçœŸã€‚ + EXPR1 -a EXPR2 如果 expr1 å’Œ expr2 都为真则为真。 + EXPR1 -o EXPR2 如果 expr1 å’Œ expr2 有一个为真则为真。 + + arg1 OP arg2 算术测试。OPæ“作符å¯ä»¥æ˜¯ -eqã€-ne〠+ -ltã€-leã€-gtã€æˆ– -ge 中的一个。 + + 二元算术æ“作返回真,如果 ARG1 傿•°ç­‰äºŽã€ä¸ç­‰äºŽã€ + å°äºŽã€å°äºŽç­‰äºŽã€å¤§äºŽã€æˆ–者大于等于 ARG2 傿•°ã€‚ + + 退出状æ€ï¼š + 如果 EXPR 表达å¼ä¼°å€¼ä¸ºçœŸåˆ™è¿”回æˆåŠŸï¼›å¦‚æžœ EXPR 表达å¼ä¼°å€¼ + ä¸ºå‡æˆ–è€…ä½¿ç”¨äº†æ— æ•ˆçš„å‚æ•°åˆ™è¿”回失败。 + +[eval] + 将傿•°ä½œä¸º shell 命令执行。 + + å°† ARGs åˆæˆä¸€ä¸ªå­—符串,用结果作为 shell 的输入, + 并且执行得到的命令。 + + 退出状æ€ï¼š + 以命令的状æ€é€€å‡ºï¼Œæˆ–者在命令为空的情况下返回æˆåŠŸã€‚ + +[times] + 显示进程时间 + + æ‰“å° shell åŠå…¶æ‰€æœ‰å­è¿›ç¨‹çš„累计用户空间和 + 系统空间执行时间。 + + é€€å‡ºçŠ¶æ€ + 总是æˆåŠŸã€‚ + +[ulimit] + 修改 shell 资æºé™åˆ¶ã€‚ + + 在å…许此类控制的系统上,æä¾›å¯¹äºŽ shell åŠå…¶åˆ›å»ºçš„进程所å¯ç”¨çš„ + 资æºçš„æŽ§åˆ¶ã€‚ + + 选项: + -S 使用软 (`soft') 资æºé™åˆ¶ + -H 使用硬 (`hard') 资æºé™åˆ¶ + -a 所有当å‰é™åˆ¶éƒ½è¢«æŠ¥å‘Š + -b 套接字缓存尺寸 + -c 创建的核文件的最大尺寸 + -d 一个进程的数æ®åŒºçš„æœ€å¤§å°ºå¯¸ + -e 最高的调度优先级 (`nice') + -f 有 shell åŠå…¶å­è¿›ç¨‹å¯ä»¥å†™çš„æœ€å¤§æ–‡ä»¶å°ºå¯¸ + -i 最多的å¯ä»¥æŒ‚èµ·çš„ä¿¡å·æ•° + -k 分é…给此进程的最大 kqueue æ•°é‡ + -l 一个进程å¯ä»¥é”定的最大内存尺寸 + -m 最大的内存进驻尺寸 + -n 最多的打开的文件æè¿°ç¬¦ä¸ªæ•° + -p 管é“缓冲区尺寸 + -q POSIX ä¿¡æ¯é˜Ÿåˆ—的最大字节数 + -r 实时调度的最大优先级 + -s 最大栈尺寸 + -t 最大的CPU时间,以秒为å•ä½ + -u 最大用户进程数 + -v 虚拟内存尺寸 + -x æœ€å¤§çš„æ–‡ä»¶é”æ•°é‡ + -P æœ€å¤§ä¼ªç»ˆç«¯æ•°é‡ + -T æœ€å¤§çº¿ç¨‹æ•°é‡ + + å¹¶éžæ‰€æœ‰é€‰é¡¹åœ¨æ‰€æœ‰ç³»ç»Ÿä¸Šå¯ç”¨ã€‚ + + 如果æä¾›äº† LIMIT å˜é‡ï¼Œåˆ™å®ƒä¸ºæŒ‡å®šèµ„æºçš„æ–°çš„值;特别的 LIMIT 值为 + `soft'ã€`hard'å’Œ`unlimited',分别表示当å‰çš„软é™åˆ¶ï¼Œç¡¬é™åˆ¶å’Œæ— é™åˆ¶ã€‚ + å¦åˆ™æ‰“å°æŒ‡å®šèµ„æºçš„当å‰é™åˆ¶å€¼ï¼Œä¸å¸¦é€‰é¡¹åˆ™å‡å®šä¸º -f + + å–值都是 1024 字节为å•ä½ï¼Œé™¤äº† -t 以秒为å•ä½ï¼Œ-p 以 512 字节递增, + -u 为无范围的进程数é‡ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者错误å‘生。 + +[umask] + æ˜¾ç¤ºæˆ–è®¾å®šæ–‡ä»¶æ¨¡å¼æŽ©ç ã€‚ + + 设定用户文件创建掩ç ä¸º MODE 模å¼ã€‚如果çœç•¥äº† MODE,则 + 打å°å½“剿ީç çš„值。 + + 如果 MODE 模å¼ä»¥æ•°å­—开头,则被当作八进制数解æžï¼›å¦åˆ™æ˜¯ä¸€ä¸ª + chmod(1) å¯æŽ¥æ”¶çš„ç¬¦å·æ¨¡å¼ä¸²ã€‚ + + 选项: + -p 如果çœç•¥ MODE 模å¼ï¼Œä»¥å¯é‡ç”¨ä¸ºè¾“入的格å¼è¾“å…¥ + -S 以符å·å½¢å¼è¾“出,å¦åˆ™ä»¥å…«è¿›åˆ¶æ•°æ ¼å¼è¾“出 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„ MODE æ¨¡å¼æˆ–者选项。 + +[wait] + 等待任务完æˆå¹¶è¿”回退出状æ€ã€‚ + + 等待以 ID ç¼–å·è¯†åˆ«çš„进程,其中 ID å¯ä»¥æ˜¯è¿›ç¨‹ç¼–å·æˆ–者任务声明, + 并报告它的终止状æ€ã€‚如果 ID æ²¡æœ‰ç»™å‡ºï¼Œåˆ™ç­‰å¾…æ‰€æœ‰çš„å½“å‰æ´»è·ƒå­ + 进程,并且返回状æ€ä¸ºé›¶ã€‚如果 ID 是任务声明,等待任务管é“中的 + 所有进程。 + + 若给定了 -n 选项,等待下一个任务完æˆå¹¶è¿”回其状æ€ã€‚ + + 若给定了 -f 选项,且已å¯ç”¨äº†ä»»åŠ¡æŽ§åˆ¶ï¼Œåˆ™ç­‰å¾…æŒ‡å®šçš„ ID 终止 + 而éžç­‰å¾…它改å˜çжæ€ã€‚ + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ª ID 进程的状æ€ï¼›å¦‚果使用了无效的 ID 或者选项则失败。 + +[return] + 从一个 shell 函数返回。 + + 使一个函数或者被引用的脚本以指定的返回值 N 退出。 + 如果 N 被çœç•¥ï¼Œåˆ™è¿”回状æ€å°±æ˜¯ + 函数或脚本中的最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + + 退出状æ€ï¼š + 返回 N,或者如果 shell ä¸åœ¨æ‰§è¡Œä¸€ä¸ªå‡½æ•°æˆ–引用脚本时,失败。 + +[for] + 为列表中的æ¯ä¸ªæˆå‘˜æ‰§è¡Œå‘½ä»¤ã€‚ + + “forâ€å¾ªçŽ¯ä¸ºåˆ—è¡¨ä¸­çš„æ¯ä¸ªæˆå‘˜æ‰§è¡Œä¸€ç³»åˆ—的命令。如果没有 + “in <è¯è¯­> ...;â€åˆ™å‡å®šä½¿ç”¨â€œin \$@\â€ã€‚对于 <è¯è¯­> ä¸­çš„æ¯ + 个元素,<åç§°> å˜é‡è¢«è®¾å®šä¸ºè¯¥å…ƒç´ åŽæ‰§è¡Œ <命令>。 + + 退出状æ€ï¼š + è¿”å›žæœ€åŽæ‰§è¡Œçš„命令的状æ€ã€‚ + +[select] + 从列表中选å–è¯å¹¶ä¸”执行命令。 + + <è¯è¯­...> 被展开,生æˆä¸€ä¸ªè¯çš„列表。展开的è¯é›†åˆè¢«æ‰“å° + 在标准错误输出设备上,æ¯ä¸ªä»¥ä¸€ä¸ªæ•°å­—åšå‰ç¼€ã€‚如果没有 `in WORDS' + 则å‡å®šä½¿ç”¨`in \$@\'。PS3æç¤ºç¬¦ä¼šè¢«æ˜¾ç¤ºå¹¶ä¸”从标准输入读入一行 + 如果该行由被显示的è¯å¯¹åº”的数字组æˆï¼Œåˆ™ NAME å˜é‡è¢«è®¾å®šä¸ºç›¸åº” + çš„è¯ã€‚如果行为空,则 WORDS å˜é‡å’Œæç¤ºç¬¦è¢«é‡æ–°æ˜¾ç¤ºã€‚如果读å–了 + 文件结æŸç¬¦ï¼Œåˆ™å‘½ä»¤å®Œæˆã€‚读入任何其他的值会导致 NAME å˜é‡è¢«è®¾å®š + 为空。读入的行被存放在å˜é‡ REPLY 中。COMMANDS å‘½ä»¤åœ¨æ¯æ¬¡é€‰æ‹© + ä¹‹åŽæ‰§è¡Œç›´åˆ°æ‰§è¡Œä¸€ä¸ª break 命令。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[time] + æŠ¥å‘Šç®¡é“æ‰§è¡Œçš„æ¶ˆè€—时间。 + + 执行 PIPELINE å¹¶ä¸”æ‰“å° PIPELINE 终结时实际时间ã€ç”¨æˆ· CPU 时间和系统 + CPU 时间的总结。 + + 选项: + -p 用å¯è¿ç§»çš„ POSIX æ ¼å¼æ‰“å°ç”¨æ—¶æ€»ç»“。 + + TIMEFORMAT å˜é‡çš„值被作为输出格å¼ã€‚ + + 退出状æ€ï¼š + 返回状æ€å³PIPELINE 的返回状æ€ã€‚ + +[case] + 基于模å¼åŒ¹é…æ¥æ‰§è¡Œå‘½ä»¤ã€‚ + + 基于 PATTERN 模å¼åŒ¹é…çš„è¯ WORD,有选择的执行 COMMANDS 命令。 + |' 用于分隔多个模å¼ã€‚ + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[if] + æ ¹æ®æ¡ä»¶æ‰§è¡Œå‘½ä»¤ã€‚ + + `if COMMANDS'列表被执行。如果退出状æ€ä¸ºé›¶ï¼Œåˆ™æ‰§è¡Œ`then COMMANDS' + 列表。å¦åˆ™æŒ‰é¡ºåºæ‰§è¡Œæ¯ä¸ª `elif COMMANDS'列表,并且如果它的退出状æ€ä¸º + 零,则执行对应的 `then COMMANDS' 列表并且 if 命令终止。å¦åˆ™å¦‚果存在的 + 情况下,执行 `else COMMANDS'åˆ—è¡¨ã€‚æ•´ä¸ªç»“æž„çš„é€€å‡ºçŠ¶æ€æ˜¯æœ€åŽä¸€ä¸ªæ‰§è¡Œ + 的命令的状æ€ï¼Œæˆ–者如果没有æ¡ä»¶æµ‹è¯•为真的è¯ï¼Œä¸ºé›¶ã€‚ + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[while] + åªè¦æµ‹è¯•æˆåŠŸå³æ‰§è¡Œå‘½ä»¤ã€‚ + + åªè¦åœ¨ `while' COMMANDS 中的最终命令返回结果为0,则 + 展开并执行 COMMANDS 命令。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[until] + 当测试ä¸åŒè¿‡æ—¶æ‰§è¡Œå‘½ä»¤ã€‚ + + `until' COMMANDS 命令的最终命令返回状æ€ä¸ä¸º 0 时, + 展开并执行 COMMANDS 命令。 + + 退出状æ€ï¼š + 返回最åŽä¸€ä¸ªæ‰§è¡Œçš„命令的状æ€ã€‚ + +[coproc] + 创建一个以 NAME 为å的副进程。 + + 异步执行 COMMANDS 命令,在执行 shell 中的数组å˜é‡ NAME + çš„ 0 å·å’Œ 1 å·å…ƒç´ ä½œä¸ºæ–‡ä»¶æè¿°ç¬¦ï¼Œä»¥ä¸€ä¸ªç®¡é“连接命令 + 分别作为命令的标准输出和输入设备。 + 默认的 NAME 是 \COPROC\。 + + 退出状æ€ï¼š + å‰¯è¿›ç¨‹ä¼šè¿”å›žé€€å‡ºçŠ¶æ€ 0。 + +[variables] + 常用 shell å˜é‡å称和使用。 + + BASH_VERSION å½“å‰ Bash 的版本信æ¯ã€‚ + CDPATH 用于 `cd' 命令傿•°æœç´¢çš„分å·åˆ†éš”的目录列表 + GLOBIGNORE 路径扩展时忽略的文件ååŒ¹é…æ¨¡å¼åˆ—表, + 以分å·åˆ†éš”。 + HISTFILE 您的命令历å²å­˜æ”¾çš„æ–‡ä»¶å称。 + HISTFILESIZE åŽ†å²æ–‡ä»¶æœ€å¤šå¯ä»¥ä¿å­˜çš„行数。 + HISTSIZE 一个è¿è¡Œçš„ shell 最多å¯ä»¥è®¿é—®çš„历å²å‘½ä»¤è¡Œæ•°ã€‚ + HOME 您的登录目录的完整路径。 + HOSTNAME 当å‰ä¸»æœºçš„主机å。 + HOSTTYPE 当å‰ç‰ˆæœ¬çš„ BASH 在其之上è¿è¡Œçš„ CPU 类型。 + IGNOREEOF 控制 shell 收到文件结æŸç¬¦ä½œä¸ºå•一输入åŽçš„ + 动作。如果设定这个å˜é‡ï¼Œåˆ™å®ƒçš„值是 shell 退出之å‰åœ¨ + 一个空行上å¯ä»¥è¿žç»­çœ‹åˆ°çš„æ–‡ä»¶ç»“æŸç¬¦æ•°é‡(默认为10)。 + 未设定时,文件结æŸç¬¦æ ‡å¿—ç€è¾“入的结æŸã€‚ + MACHTYPE æè¿°å½“å‰è¿è¡Œ Bash 的系统的字符串。 + MAILCHECK Bash 检测新邮件的频率,以秒为å•ä½ã€‚ + MAILPATH Bash 从中检测新邮件的文件列表,以分å·åˆ†éš”。 + OSTYPE è¿è¡Œ Bash çš„ Unix 版本。 + PATH 当寻找命令时æœç´¢çš„目录列表,以冒å·åˆ†éš”。 + PROMPT_COMMAND æ‰“å°æ¯ä¸€ä¸ªä¸»æç¤ºç¬¦ä¹‹å‰æ‰§è¡Œçš„命 + 令。 + PS1 主æç¤ºç¬¦å­—符串。 + PS2 从æç¤ºç¬¦å­—符串。 + PWD 当å‰ç›®å½•的完整路径。 + SHELLOPTS å·²å¯ç”¨çš„ shell 选项列表,以冒å·åˆ†éš”。 + TERM 当å‰ç»ˆç«¯ç±»åž‹çš„å称。 + TIMEFORMAT 以关键则 `time' 显示的时间统计信æ¯çš„输出 + æ ¼å¼ã€‚ + auto_resume éžç©ºæ—¶ï¼Œä¸€ä¸ªå•独的命令è¯ä¼šé¦–å…ˆè¢«åœ¨å½“å‰ + åœæ­¢çš„任务列表中æœç´¢ã€‚如果找到则该任务被置于å‰å°ã€‚ + 如果值为 `exact' 则æ„味ç€å‘½ä»¤è¯å¿…须精确匹é…åœæ­¢ä»»åŠ¡ + 列表中的命令。如果值为 `substring' 则æ„味ç€å‘½ä»¤è¯å¿… + 须匹é…任务的一个å­å­—符串。任何其他的值æ„味ç€å‘½ä»¤è¯ + å¿…é¡»æ˜¯åœæ­¢ä»»åŠ¡çš„ä¸€ä¸ªå‰ç¼€ã€‚ + histchars 控制历å²å±•开和快速替æ¢çš„字符。第一个字符是 + åŽ†å²æ›¿æ¢å­—符,通常是 `!'。第二个字符是快速替æ¢å­—符, + 通常是 `^'ã€‚ç¬¬ä¸‰ä¸ªæ˜¯åŽ†å²æ³¨é‡Šå­—符,通常是 `#'。 + HISTIGNORE ç”¨äºŽå†³å®šå“ªäº›å‘½ä»¤è¢«å­˜å…¥åŽ†å²æ–‡ä»¶çš„æ¨¡å¼ + 列表,以冒å·åˆ†éš”。 + +[pushd] + 将目录添加到栈中。 + + å°†ç›®å½•æ·»åŠ åˆ°ç›®å½•æ ˆé¡¶ï¼Œæˆ–ç€æ—‹è½¬æ ˆç›´åˆ°å½“å‰å·¥ä½œç›®å½•æˆä¸º + 新的栈顶。ä¸å¸¦å‚æ•°æ—¶ï¼Œäº¤æ¢æ ˆé¡¶çš„两个目录。 + + 选项: + -n 抑制添加目录至栈时通常的改å˜ç›®å½•æ“作,从而仅对栈 + 进行æ“作。 + + 傿•°ï¼š + +N 旋转栈从而第 N 个目录 (`dirs' 显示的列表中左起,从零开始) + 将移动到栈顶。 + + -N 旋转栈从而第 N 个目录 (`dirs' 显示的列表中å³èµ·ï¼Œä»Žé›¶å¼€å§‹) + 将移动到栈顶。 + + dir å°† DIR 目录添加到栈顶,并且使其æˆä¸ºå½“å‰å·¥ä½œç›®å½•。 + + `dirs' 内建显示目录栈。 + + 退出状æ€ï¼š + +[popd] + 从栈中删除目录。 + + 从目录栈中删除æ¡ç›®ã€‚ä¸å¸¦å‚数时,删除栈顶目录,并改å˜è‡³æ–°çš„æ ˆ + 顶目录。 + + 选项: + -n æŠ‘åˆ¶ä»Žæ ˆä¸­åˆ é™¤ç›®å½•æ—¶é€šå¸¸çš„ç›®å½•å˜æ¢æ“作,从而仅对栈 + 进行æ“作。 + + 傿•°ï¼š + +N 删除第 N 个目录 (`dirs' 显示的目录列表中左起,从零开始)。 + 例如:`popd +0' 删除第一个目录,`popd +1' 删除第二个。 + + -N 删除第 N 个目录 (`dirs' 显示的目录列表中å³èµ·ï¼Œä»Žé›¶å¼€å§‹)。 + 例如:`popd -0' 删除最åŽä¸€ä¸ªç›®å½•,,`popd -1' 删除倒数第二个。 + + `dirs' 内建显示目录栈。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„傿•°æˆ–è€…ç›®å½•å˜æ¢å¤±è´¥ã€‚ + +[dirs] + 显示目录栈。 + + 显示当å‰è®°ä½çš„目录列表。通过 `pushd' 命令å¯ä»¥å°†ç›®å½•存入列表 + 中;`popd' 命令å¯ç”¨äºŽé历弹出列表。 + + 选项: + -c 删除所有元素以清空目录栈 + -l 䏿‰“å°ä¸Žä¸»ç›®å½•相关的波浪å·å‰ç¼€çš„目录 + -p æ¯è¡Œä¸€ä¸ªæ¡ç›®æ‰“å°ç›®å½•æ ˆ + -v æ¯è¡Œä¸€ä¸ªæ¡ç›®ï¼Œä»¥æ ˆä¸­ä½ç½®ä¸ºå‰ç¼€æ‰“å°ç›®å½•æ ˆ + + 傿•°ï¼š + +N 显示 dirs ä¸å¸¦é€‰é¡¹å¯åŠ¨æ—¶æ˜¾ç¤ºçš„ç›®å½•åˆ—è¡¨å·¦èµ·ä¸­ç¬¬ + N 个目录,从零开始。 + + -N 显示 dirs ä¸å¸¦é€‰é¡¹å¯åŠ¨æ—¶æ˜¾ç¤ºçš„ç›®å½•åˆ—è¡¨å³èµ·ä¸­ç¬¬ + N 个目录,从零开始。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者å‘生错误。 + +[printf] + 在 FORMAT 的控制下格å¼åŒ–å¹¶æ‰“å° ARGUMENTS 傿•°ã€‚ + + 选项: + -v var 将输出赋值给 shell å˜é‡ VAR è€Œä¸æ˜¾ç¤ºåœ¨æ ‡å‡†è¾“出上 + + FORMAT 是包å«ä¸‰ç§å¯¹è±¡çš„字符串:简å•地被拷è´åˆ°æ ‡å‡†è¾“出的普通字符; + è¢«å˜æ¢ä¹‹åŽæ‹·è´åˆ°æ ‡å‡†è¾“å…¥çš„è½¬ä¹‰å­—ç¬¦ï¼›ä»¥åŠæ¯ä¸ªéƒ½ä¼šå½±å“åˆ°ä¸‹ä¸ªå‚æ•°çš„æ‰“å°çš„æ ¼ + å¼åŒ–声明。 + + 在 printf(1) 中æè¿°çš„æ ‡å‡†æŽ§åˆ¶å£°æ˜Žä¹‹å¤–,printf è§£æžï¼š + + %b æ‰©å±•å¯¹åº”å‚æ•°ä¸­çš„åæ–œæ è½¬ä¹‰åºåˆ— + %q 以å¯ä½œä¸º shell 输入的格å¼å¼•ç”¨å‚æ•° + %(fmt)T 以 FMT 为供给 strftime(3) 的格å¼è¾“出日期时间字符串 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者写或赋值错误å‘生。 + +[complete] + 指定 Readline å¦‚ä½•è¡¥å…¨å‚æ•°ã€‚ + + 声明对于æ¯ä¸€ä¸ª NAME åç§°å¦‚ä½•è¡¥å…¨å‚æ•°ã€‚如果ä¸å¸¦é€‰é¡¹ï¼Œ + 现有的补全声明会以å¯ä»¥é‡ç”¨ä¸ºè¾“å…¥çš„æ ¼å¼æ‰“å°å‡ºæ¥ã€‚ + + 选项: + -p 以å¯é‡ç”¨çš„æ ¼å¼æ‰“å°çŽ°æœ‰çš„è¡¥å…¨å£°æ˜Žã€‚ + -r 对于æ¯ä¸ª NAME å称删除补全声明,或者如果没有æä¾› NAME + å称,删除所有的补全声明。 + -D 对于没有补全声明定义的命令,设定默认的补全动作 + -E 对于 \empty\ 命令设定补全动作,—— 对于空行的补全。 + -I 将补全和动作应用在首å•è¯ï¼ˆé€šå¸¸æ˜¯æ‰€ç»™å‘½ä»¤ï¼‰ä¸Š + + å°è¯•补全时,按照上述大写字æ¯é€‰é¡¹çš„顺åºè¿›è¡ŒåŠ¨ä½œã€‚ + 如果给出了多个选项,-D 选项优先级高于 -E 选项,且 + 这两个选项优先级å‡é«˜äºŽ -I。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者错误å‘生。 + +[compgen] + 便®é€‰é¡¹æ˜¾ç¤ºå¯èƒ½çš„补全。 + + æ„图在能产生å¯èƒ½çš„补全的 shell 函数内部使用。 + 如果æä¾›äº†å¯é€‰çš„ WORD 傿•°ï¼Œåˆ™äº§ç”ŸæŒ‰ç…§ WORD + 进行的匹é…。 + + 退出状æ€ï¼š + 除éžä½¿ç”¨äº†æ— æ•ˆé€‰é¡¹æˆ–者错误å‘生,å¦åˆ™è¿”回æˆåŠŸã€‚ + +[compopt] + 修改或显示补全选项。 + + 修改æ¯ä¸ª NAME å称的补全选项,或如果没有æä¾› NAME å称,执行当å‰çš„è¡¥ + 全。 + 如果ä¸å¸¦é€‰é¡¹ï¼Œæ‰“å°æ¯ä¸ª NAME å称的补全选项或当å‰çš„补全声明。 + + 选项: + -o option 为æ¯ä¸ª NAME å称设定补全选项 option + -D 为 \default\ 命令补全改å˜é€‰é¡¹ + -E 为 \empty\ 命令补全改å˜é€‰é¡¹ + -I 为首å•è¯çš„补全改å˜é€‰é¡¹ + + 使用 `+o' è€Œä¸æ˜¯ `-o' å¯ä»¥å…³é—­æŒ‡å®šçš„选项。 + + 傿•°ï¼š + + æ¯ä¸ª NAME å称都对应一个之å‰ä»¥é€šè¿‡ `complete' 内建定义了的补全声明的 + å‘½ä»¤ã€‚å¦‚æžœä¸æä¾› NAME å称,当å‰ç”Ÿæˆè¡¥å…¨çš„函数必须调用 compopt, + 并䏔当剿‰§è¡Œçš„补全生æˆå™¨é€‰é¡¹ä¼šè¢«ä¿®æ”¹ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称没有定义补全声明。 + +[mapfile] + 从标准输入读å–行到下标数组å˜é‡ä¸­ã€‚ + + 从标准输入读å–行到下标数组å˜é‡ ARRAY 中,或者如果使用了 -u 选项, + 从文件æè¿°ç¬¦ FD 中读å–。MAPFILE å˜é‡æ˜¯é»˜è®¤çš„ ARRAY å˜é‡ã€‚ + + 选项: + -d delim 使用 DELIM è€Œéžæ¢è¡Œç¬¦æ–­è¡Œ + -n count æœ€å¤šæ‹·è´ COUNT 行,如果 COUNT 为 0ï¼Œåˆ™æ‹·è´æ‰€æœ‰è¡Œã€‚ + -O origin 从下标 ORIGIN 开始 赋值给 ARRAY å˜é‡ã€‚默认下标是0. + -s count 丢弃最先读å–çš„ COUNT 行。 + -t 从读å–çš„æ¯è¡Œæœ«å°¾åˆ é™¤ä¸€ä¸ªæ¢è¡Œç¬¦ã€‚ + -u fd 从文件æè¿°ç¬¦ FD 中读å–è¡Œè€Œä¸æ˜¯æ ‡å‡†è¾“入。 + -C callback æ¯ QUANTUM 次读行之åŽå¯¹ CALLBACK 回调进行估值。 + -c quantum å®šä¹‰æ¯æ¬¡è°ƒç”¨ CALLBACK 回调之间读å–的行数。 + + 傿•°ï¼š + ARRAY 存储数æ®ä½¿ç”¨çš„æ•°ç»„å˜é‡ + + 如果使用了 -C 而没有 -c,默认的é‡å­æ˜¯5000。当对 CALLBACK 估值时, + 下一个将被赋值的数组元素的下标作为é¢å¤–傿•°è¢«ä¼ é€’。 + + å¦‚æžœæ²¡æœ‰æ˜¾å¼æŒ‡å®šèµ·å§‹ä¸‹æ ‡ï¼Œmapfile å°†åœ¨èµ‹å€¼å‰æ¸…空 ARRAY å˜é‡ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项,或者 ARRAY å˜é‡åªè¯»æˆ–䏿˜¯ä¸‹æ ‡æ•°ç»„。 + +[readarray] + 从一个文件中读å–行到数组å˜é‡ä¸­ã€‚ + 一个 `mapfile'çš„åŒä¹‰è¯ã€‚ + +[unset] + å–æ¶ˆè®¾å®š shell å˜é‡å’Œå‡½æ•°çš„值和属性。 + 对æ¯ä¸€ä¸ª NAME å称,删除对应的å˜é‡æˆ–函数。 + + 选项: + -f å°†æ¯ä¸ª NAME 视为函数 + -v å°†æ¯ä¸ª NAME 视为å˜é‡ + -n å°†æ¯ä¸ª NAME 视为å称引用,åªå–消其本身而éžå…¶æŒ‡å‘çš„å˜é‡ + + ä¸å¸¦é€‰é¡¹æ—¶ï¼Œunset 首先å°è¯•å–æ¶ˆè®¾å®šä¸€ä¸ªå˜é‡ï¼Œå¦‚果失败,å†å°è¯•å–æ¶ˆè®¾å®šä¸€ä¸ª + 函数。 + + æŸäº›å˜é‡ä¸å¯ä»¥è¢«å–消设定;å‚è§ `readonly'。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称为åªè¯»ã€‚ + +[local] + 定義本機變數。 + + 建立一個以 <å稱> 為å稱的變數,並且將 VALUE 指派給它。 + OPTION é¸é …å¯ä»¥æ˜¯ä»»ä½•能被「declareã€æŽ¥å—çš„é¸é …。 + + 本機變數åªèƒ½åœ¨å‡½æ•¸å…§éƒ¨è¢«ä½¿ç”¨ï¼Œå®ƒå€‘åªèƒ½åœ¨å®šç¾©å®ƒå€‘的函數內 + 部以åŠå­å‡½æ•¸ä¸­å¯è¦‹ã€‚ + + 退出狀態: + 回傳æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†ç„¡æ•ˆçš„é¸é …ã€ç™¼ç”Ÿäº†æŒ‡æ´¾éŒ¯èª¤æˆ–者 shell ä¸åœ¨åŸ·è¡Œä¸€å€‹å‡½æ•¸ã€‚ + +[export] + 为 shell å˜é‡è®¾å®šå¯¼å‡ºå±žæ€§ã€‚ + + 标记æ¯ä¸ª NAME å称为自动导出到åŽç»­å‘½ä»¤æ‰§è¡Œçš„环境。如果æä¾›äº† VALUE + 则导出å‰å°† VALUE 作为赋值。 + + 选项: + -f 指 shell 函数 + -n 删除æ¯ä¸ª NAME å称的导出属性 + -p 显示所有导出的å˜é‡å’Œå‡½æ•°çš„列表 + + `--' çš„å‚æ•°ç¦ç”¨è¿›ä¸€æ­¥çš„选项处ç†ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称。 + +[readonly] + 标记 shell å˜é‡ä¸ºä¸å¯æ”¹å˜ã€‚ + + 标记æ¯ä¸€ä¸ª NAME å称为åªè¯»ï¼›è¿™äº› NAME å˜é‡çš„值将ä¸å¯ä»¥è¢«åŽç»­çš„赋值 + æ“作所改å˜ã€‚如果æä¾›äº† VALUE,则在标记为åªè¯»ä¹‹å‰å°† VALUE 值赋给å˜é‡ã€‚ + + 选项: + -a 指下标数组å˜é‡ + -A æŒ‡å…³è”æ•°ç»„æ ‡é‡ + -f 指 shell 函数 + -p 显示åªè¯»å˜é‡æˆ–函数列表,å–å†³äºŽæ˜¯å¦æä¾›äº† -f 选项 + + `--' çš„å‚æ•°ç¦ç”¨è¿›ä¸€æ­¥çš„选项处ç†ã€‚ + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžä½¿ç”¨äº†æ— æ•ˆçš„选项或者 NAME å称。 + +[declare] + 设定å˜é‡å€¼å’Œå±žæ€§ã€‚ + + 声明å˜é‡å¹¶ä¸”赋予它们属性。如果没有给定å称, + 则显示所有å˜é‡çš„属性和值。 + + 选项: + -f é™åˆ¶åŠ¨ä½œæˆ–æ˜¾ç¤ºä¸ºä»…å‡½æ•°å称和定义 + -F é™åˆ¶ä»…显示函数åç§° (以åŠè°ƒè¯•时显示行å·å’Œæºæ–‡ä»¶å) + -g 当用于 shell 函数内时创建全局å˜é‡; å¦åˆ™å¿½ç•¥ + -p 显示æ¯ä¸ª NAME å˜é‡çš„属性和值 + + 设定属性的选项: + -a 使 NAME æˆä¸ºä¸‹æ ‡æ•°ç»„ (如果支æŒ) + -A 使 NAME æˆä¸ºå…³è”数组 (如果支æŒ) + -i 使 NAME 带有 `integer' (æ•´æ•°)属性 + -l å°† NAME 在赋值时转为å°å†™ + -n 使 NAME æˆä¸ºæŒ‡å‘一个以其值为åç§°çš„å˜é‡çš„引用 + -r å°† NAME å˜ä¸ºåªè¯» + -t 使 NAME 带有 `trace' (追踪)属性 + -u å°†æ¯ä¸ª NAME 在赋值时转为大写 + -x å°† NAME 导出 + + 用 `+' 代替 `-' 会关闭指定选项。 + + 带有整数属性的å˜é‡åœ¨èµ‹å€¼æ—¶å°†ä½¿ç”¨ç®—术估值(è§ + `let' 命令) + + 在函数中使用时,`declare' 使 NAME æˆä¸ºæœ¬åœ°å˜é‡ï¼Œå’Œ `local' + 命令一致。`-g' 选项抑制此行为。 + + 退出状æ€ï¼š + 返回æˆåŠŸï¼Œé™¤éžæä¾›äº†æ— æ•ˆé€‰é¡¹æˆ–è€…å‘生å˜é‡èµ‹å€¼é”™è¯¯ + +[function] + 定义 shell 函数。 + + 创建一个以 NAME 为åçš„ shell 函数。当作为一个简å•的命令å¯ç”¨æ—¶ï¼Œ + NAME 函数执行调用 shell 的上下文中的 COMMANDs 命令。当 NAME + 被å¯ç”¨æ—¶ï¼Œå‚数作为 $1...$n 被传递给函数,函数的å字储存在å˜é‡ + $FUNCNAME 中。 + + 退出状æ€ï¼š + 返回æˆåŠŸé™¤éž NAME 为åªè¯»ã€‚ + +[typeset] + 设置å˜é‡çš„值和属性。 + + `declare' 的等价形å¼ã€‚å‚è§ `help declare'。 + +[source] + åœ¨å½“å‰ shell 中执行一个文件中的命令。 + + åœ¨å½“å‰ shell 中读å–并执行 FILENAME 文件中的命令。$PATH å˜é‡ä¸­çš„ + æ¡ç›®è¢«ç”¨äºŽå¯»æ‰¾åŒ…å« FILENAME 文件的目录。如果æä¾›äº†ä»»ä½•çš„ ARGUMENTS + 傿•°ï¼Œåˆ™å®ƒä»¬å°†æˆä¸º FILENAME 文件执行时的ä½ç½®å‚数。 + + 退出状æ€ï¼š + 返回 FILENAME 文件中最åŽä¸€ä¸ªå‘½ä»¤çš„状æ€ï¼›å¦‚æžœ FILENAME 文件ä¸å¯è¯»åˆ™å¤±è´¥ã€‚ + +[bind] + 设定 Readline 键绑定和å˜é‡ã€‚ + + 绑定一个键åºåˆ—到一个 Readline 函数或者å®ï¼Œæˆ–者设定一个 + Readline å˜é‡ã€‚éžé€‰é¡¹å‚数的语法和 ~/.inputrc 文件中的等 + åŒï¼Œä½†æ˜¯å¿…é¡»ä½œä¸ºä¸€ä¸ªå‚æ•°è¢«ä¼ é€’, + 例如,bind '\\\C-x\\C-r\: re-read-init-file'. + + 选项: + -m 键映射 在此命令执行过程中使用指定的键映射。 + å¯è¢«æŽ¥å—的键映射å字有 emacsã€emacs-standardã€emacs- + meta〠+ emacs-ctlxã€viã€vi-moveã€vi-commandã€å’Œ vi-insert。 + -l 列出函数å称。 + -P 列出函数å称和绑定。 + -p 以å¯ä»¥é‡æ–°ç”¨ä½œè¾“入的格å¼åˆ—出函数å称和绑定。 + -S 列出å¯ä»¥å¯åЍå®çš„é”®åºåˆ—以åŠå®ƒä»¬çš„值 + -s 以å¯ä»¥é‡æ–°ç”¨ä½œè¾“入的格å¼åˆ—出å¯ä»¥å¯åЍå®çš„键以åŠå®ƒä»¬çš„ + 值。 + -V 列出å˜é‡åæˆå’Œå®ƒä»¬çš„值 + -v 以å¯ä»¥é‡æ–°ç”¨ä½œè¾“入的格å¼åˆ—出å˜é‡çš„å称和它们的值 + -q å‡½æ•°å æŸ¥è¯¢æŒ‡å®šçš„函数å¯ä»¥ç”±å“ªäº›é”®å¯åŠ¨ã€‚ + -u 函数å å绑定所有绑定至指定函数的键。 + -r é”®åºåˆ— å–æ¶ˆæŒ‡å®šé”®åºåˆ—的绑定。 + -f 文件å 从指定文件中读å–键绑定。 + -x é”®åºåˆ—:shell命令\t当指定的键åºåˆ—被输入时,执行指定的 shell 命令。 + -X 以å¯è¢«é‡ç”¨çš„å½¢å¼åˆ—出用 -x 绑定的键åºåˆ—和命令。 + + 退出状æ€ï¼š + 除éžä½¿ç”¨äº†æ— æ³•辨认的选项或者错误å‘生,å¦åˆ™è¿”回0. + +[test] + 估值算术表达å¼ã€‚ + + å°†æ¯ä¸ª ARG å‚èµ›ä½œä¸ºç®—æœ¯è¡¨è¾¾å¼æ¥ä¼°å€¼ã€‚估值的计算以定宽的整 + 数完æˆï¼Œä¸å¸¦æº¢å‡ºæ£€æµ‹ï¼Œä¸è¿‡é™¤ 0 是被置陷阱的并且会报一个错 + 误。下列æ“作符被按照相åŒçš„算术优先级组åˆã€‚åˆ—è¡¨çš„é¡ºåºæŒ‰ç…§ + 优先级从高至低。 + + + id++, id-- å˜é‡åŽç½®åŠ ï¼ŒåŽç½®å‡ + ++id, --id å˜é‡å‰ç½®åŠ ï¼Œå‰ç½®å‡ + -, + ä¸€å…ƒå‡æ³•,一元加法 + !, ~ 逻辑和ä½å–å + '**' 指数 + '*', /, % 乘法,除法,å–余数 + +, - 增加,å‡å°‘ + <<, >> å‘左和å‘峿Œ‰ä½ç§»ä½ + <=, >=, <, > 比较 + ==, != 等于,ä¸ç­‰äºŽ + & 按ä½ä¸Ž + ^ 按ä½å¼‚或 + | æŒ‰ä½æˆ– + && 逻辑与 + || 逻辑或 + expr ? expr : expr + æ¡ä»¶æ“作符 + =, *=, /=, %=, + +=, -=, <<=, >>=, + &=, ^=, |= 赋值 + + + Shell å˜é‡å…许作为æ“作数。表达å¼ä¸­çš„å˜é‡çš„å称会被å–代以值 + (强制转æ¢ä¸ºå®šå®½çš„æ•´æ•°)。表达å¼ä¸­çš„å˜é‡ä¸éœ€è¦æ‰“开整数属性。 + + æ“作符按照优先级进行估值。括å·ä¸­çš„å­è¡¨è¾¾å¼å°†è¢«å…ˆä¼°å€¼ï¼Œå¹¶å¯å–ä»£ä¸Šè¿°è¡¨è¾¾å¼ + 规则。 + + 退出状æ€ï¼š + 如果最åŽä¸€ä¸ª ARG 傿•°ä¼°å€¼ä¸º 0,则 let 返回 1ï¼› å¦åˆ™ let 返回 0。 + +*[other] æ˜¾ç¤ºå…¶ä»–å‘½ä»¤å¸®åŠ©ä¿¡æ¯ . +} + +helpname = { +$cmdName -> +[command0] {" % - 在å‰å°ç»§ç»­ä»»åŠ¡"} +[command1] {"(( - 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚"} +[command2] {". 文件å [傿•°]"} +[command3] {":"} +[command4] {"[ 傿•°... ]"} +[command5] {"[[ è¡¨è¾¾å¼ ]]"} +[command6] {"for (( - 算术 for 循环。"} +[command7] 将命令组åˆä¸ºä¸€ä¸ªå•元。 +[set] set - è®¾å®šæˆ–å–æ¶ˆè®¾å®š shell 选项和ä½ç½®å‚æ•°çš„ +[read] read - 从标准输入读å–一行并将其分为ä¸åŒçš„域。 +[type] type - 显示命令类型的信æ¯ã€‚ +[trap] trap - 对信å·å’Œå…¶ä»–事件设陷阱。 +[alias] alias - 定义或显示别å。 +[unalias] unalias - 从别å定义列表中删除æ¯ä¸€ä¸ªâ€œåå­—â€ã€‚ +[break] break - 退出 forã€while 或 until 循环 +[continue] continue - ç»§ç»­ forã€while 或 until 循环。 +[builtin] builtin - 执行 shell 内建。 +[caller] caller - 返回当å‰å­è°ƒç”¨çš„上下文。 +[cd] cd - æ”¹å˜ shell 工作目录。 +[pwd] pwd - 打å°å½“å‰å·¥ä½œç›®å½•çš„å字。 +[true] true - 空的命令。 +[shopt] shopt - è®¾å®šå’Œå–æ¶ˆè®¾å®š shell 选项。 +[false] false - è¿”å›žä¸€ä¸ªä¸æˆåŠŸçš„ç»“æžœã€‚ +[command] command - 执行一个简å•命令或者显示命令的相关信æ¯ã€‚ +[echo] echo - 将傿•°å†™åˆ°æ ‡å‡†è¾“出。 +[enable] enable - å¯ç”¨å’Œç¦ç”¨ shell 内建。 +[getopts] getopts - è§£æžé€‰é¡¹å‚数。 +[exec] exec - ä½¿ç”¨æŒ‡å®šå‘½ä»¤æ›¿æ¢ shell。 +[exit] exit - 退出shell。 +[logout] logout - 退出一个登录 shell. +[fc] fc - 从历å²åˆ—表中显示或者执行命令。 +[fg] fg - 将任务移至å‰å°ã€‚ +[bg] bg - 移动任务至åŽå°ã€‚ +[hash] hash - è®°ä½æˆ–显示程åºä½ç½®ã€‚ +[help] help - 显示内建命令的相关信æ¯ã€‚ +[history] history - 显示或æ“纵历å²åˆ—表。 +[jobs] jobs - 显示任务状æ€ã€‚ +[disown] discow - ä»Žå½“å‰ shell 中删除任务。 +[kill] kill - å‘一个任务å‘é€ä¸€ä¸ªä¿¡å·ã€‚ +[let] let - 估值算术表达å¼ã€‚ +[shift] shift - ç§»ä½ä½ç½®å‚数。 +[suspend] suspend - 挂起 shell 执行。 +[eval] eval - 对æ¡ä»¶è¡¨è¾¾å¼è¿›è¡Œä¼°å€¼ã€‚ +[times] times - 显示进程时间 +[ulimit] limit - 修改 shell 资æºé™åˆ¶ã€‚ +[umask] umask - æ˜¾ç¤ºæˆ–è®¾å®šæ–‡ä»¶æ¨¡å¼æŽ©ç ã€‚ +[return] return - 等待任务完æˆå¹¶è¿”回退出状æ€ã€‚ +[wait] wait - 等待进程完æˆå¹¶ä¸”返回退出状æ€ã€‚ +[for] for - 为列表中的æ¯ä¸ªæˆå‘˜æ‰§è¡Œå‘½ä»¤ã€‚ +[select] select - 从列表中选å–è¯å¹¶ä¸”执行命令。 +[time] time - æŠ¥å‘Šç®¡é“æ‰§è¡Œçš„æ¶ˆè€—时间。 +[case] case - 基于模å¼åŒ¹é…æ¥æ‰§è¡Œå‘½ä»¤ã€‚ +[if] if - æ ¹æ®æ¡ä»¶æ‰§è¡Œå‘½ä»¤ã€‚ +[while] while - åªè¦æµ‹è¯•æˆåŠŸå³æ‰§è¡Œå‘½ä»¤ã€‚ +[until] until -当测试ä¸åŒè¿‡æ—¶æ‰§è¡Œå‘½ä»¤ +[coproc] corproc - 创建一个以 NAME 为å的副进程。 +[variables] variables - 常用 shell å˜é‡å称和使用。 +[pushd] pushd - 将目录添加到栈中。 +[popd] popd - 从栈中删除目录。 +[dirs] dirs - 显示目录栈。 +[printf] printf -在 FORMAT 的控制下格å¼åŒ–å¹¶æ‰“å° ARGUMENTS 傿•°ã€‚ +[complete] complete - 指定 Readline å¦‚ä½•è¡¥å…¨å‚æ•°ã€‚ +[compgen] compgen - 便®é€‰é¡¹æ˜¾ç¤ºå¯èƒ½çš„补全。 +[compopt] compopt - 修改或显示补全选项。 +[mapfile] mapfile - 从标准输入读å–行到下标数组å˜é‡ä¸­ã€‚ +[unset] unset - å–æ¶ˆè®¾å®š shell å˜é‡å’Œå‡½æ•°çš„值和属性。 +[readarray] readarry - 从一个文件中读å–行到数组å˜é‡ä¸­ã€‚ +[local] local -è®°ä½æˆ–显示程åºä½ç½®ã€‚ +[export] export -为 shell å˜é‡è®¾å®šå¯¼å‡ºå±žæ€§ã€‚ +[readonly] readonly - 标记 shell å˜é‡ä¸ºä¸å¯æ”¹å˜ã€‚ +[function] function - 定义 shell 函数。 +[typeset] typeset - 设置å˜é‡çš„值和属性。 +[source] source - åœ¨å½“å‰ shell 中执行一个文件中的命令。 +[bind] bind - 设定 Readline 键绑定和å˜é‡ã€‚ +[test] test - 估值算术表达å¼ã€‚ +[declare] declare - 设置å˜é‡çš„值和属性。 +*[other] æ˜¾ç¤ºå…¶ä»–å‘½ä»¤å¸®åŠ©ä¿¡æ¯ . +} + +helpsynopsis = { +$cmdName -> +[command0] {"job_spec [&]"} +[command1] {"(( - "} +[command2] {". - åœ¨å½“å‰ shell 中执行一个文件中的命令。"} +[command3] {": - 空的命令。"} +[command4] {"[ - 估值æ¡ä»¶è¡¨è¾¾å¼ã€‚"} +[command5] {"[[ ... ]] - 执行æ¡ä»¶å‘½ä»¤ã€‚"} +[command6] {"for (( 表达å¼1; 表达å¼2; 表达å¼3 )); do 命令 ; done"} +[command7] {"{ 命令 ; }"} +[set] {"set [--abefhkmnptuvxBCHP][-o 选项å][--][傿•° ...]"} +[read] {"read [-ers] [-a 数组] [-d 分隔符] [-i 缓冲区文字] [-n 读å–字符数] [-N 读å–字符数] [-p æç¤ºç¬¦] [-t è¶…æ—¶] [-u 文件æè¿°ç¬¦] [åç§° ...]"} +[type] {"type [-afptP] åç§° [åç§° ...]"} +[trap] {"trap: trap [-lp] [[傿•°] ä¿¡å·å£°æ˜Ž ...]"} +[alias] {"alias [-p] [åç§°[=值] ... ]"} +[unalias] {"unalias [-a] åç§° [åç§° ...] "} +[break] {"break [n]"} +[continue] {"continue [n]"} +[builtin] {"builtin [shell 内建 [傿•° ...]] "} +[caller] {"caller [表达å¼] "} +[cd] {"cd [-L|[-P [-e]] [-@]] [目录]"} +[pwd] {"pwd [-LP]"} +[true] {"true"} +[shopt] {"shopt [-pqsu] [-o] [选项å ...]"} +[false] {"false"} +[command] {"command [-pVv] 命令 [傿•° ...]"} +[echo] {"echo [-neE] [傿•° ...]"} +[enable] {"enable [-a] [-dnps] [-f 文件å] [åç§° ...] "} +[getopts] {"getopts 选项字符串 åç§° [傿•°]"} +[exec] {"exec [-cl] [-a åç§°] [命令 [傿•° ...]] [é‡å®šå‘ ...] "} +[exit] {"exit [n]"} +[logout] {"logout [n]"} +[fc] {"fc [-e 编辑器å] [-lnr] [èµ·å§‹] [终结] 或 fc -s [模å¼=替æ¢ä¸²] [命令]"} +[fg] {"fg [任务声明] "} +[bg] {"bg [任务声明 ...]"} +[hash] {"hash [-lr] [-p 路径å] [-dt] [åç§° ...]"} +[help] {"help [-dms] [æ¨¡å¼ ...]"} +[history] {"history [-c] [-d åç§»é‡] [n] 或 history -anrw [文件å] 或 history -ps 傿•° [傿•°...]"} +[jobs] {"jobs [-lnprs] [任务声明 ...] 或 jobs -x 命令 [傿•°]"} +[disown] {"disown [-h] [-ar] [任务声明 ... | pid ...]"} +[kill] {"kill [-s ä¿¡å·å£°æ˜Ž | -n ä¿¡å·ç¼–å· | -ä¿¡å·å£°æ˜Ž] è¿›ç¨‹å· | 任务声明 ... 或 kill -l [ä¿¡å·å£°æ˜Ž]"} +[let] {"let 傿•° [傿•° ...]"} +[shift] {"shift [n]"} +[suspend] {"suspend [-f]"} +[eval] {"eval [傿•° ...]"} +[times] {"times"} +[ulimit] {"ulimit [-SHabcdefiklmnpqrstuvxPT] [é™åˆ¶]"} +[umask] {"umask [-p] [-S] [模å¼]"} +[return] {"return [n]"} +[wait] {"wait [-fn] [ç¼–å· ...]"} +[for] {"for åç§° [in è¯è¯­ ... ] ; do 命令; done"} +[select] {"select NAME [in è¯è¯­ ... ;] do 命令; done"} +[time] {"time [-p] 管é“"} +[case] {"case è¯ in [æ¨¡å¼ [| 模å¼]...) 命令 ;;]... esac"} +[if] {"if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi"} +[while] {"while 命令; do 命令; done"} +[until] {"until 命令; do 命令; done"} +[coproc] {"coproc [åç§°] 命令 [é‡å®šå‘]"} +[variables] {"variables - 一些 shell å˜é‡çš„åç§°å’Œå«ä¹‰"} +[pushd] {"pushd [-n] [+N | -N | 目录]"} +[popd] {"popd [-n] [+N | -N]"} +[dirs] {"dirs [-clpv] [+N] [-N]"} +[printf] {"printf [-v var] æ ¼å¼ [傿•°]"} +[complete] {"complete [-abcdefgjksuv] [-pr] [-DEI] [-o 选项] [-A 动作] [-G 全局模å¼] [-W è¯è¯­åˆ—表] [-F 函数] [-C 命令] [-X 过滤模å¼] [-P å‰ç¼€] [-S åŽç¼€] [åç§° ...]"} +[compgen] {"compgen [-abcdefgjksuv] [-o 选项] [-A 动作] [-G 全局模å¼] [-W è¯è¯­åˆ—表] [-F 函数] [-C 命令] [-X 过滤模å¼] [-P å‰ç¼€] [-S åŽç¼€] [è¯è¯­]"} +[compopt] {"compopt [-o|+o 选项] [-DEI] [åç§° ...]"} +[mapfile] {"mapfile [-d 分隔符] [-n 计数] [-O èµ·å§‹åºå·] [-s 计数] [-t] [-u fd] [-C 回调] [-c é‡å­] [数组]"} +[unset] {"unset [-f] [-v] [-n] [åç§° ...]"} +[readarray] {"readarray [-d 定界符] [-n 计数] [-O èµ·å§‹åºå·] [-s 计数] [-t] [-u fd] [-C 回调] [-c é‡å­] [数组]"} +[local] {"local [option] åç§°[=值] ... "} +[export] {"export [-fn] [åç§°[=值] ...] 或 export -p"} +[readonly] {"readonly [-aAf] [åç§°[=值] ...] 或 readonly -p"} +[function] {"function åç§° { 命令 ; } 或 name () { 命令 ; } "} +[typeset] {"typeset [-aAfFgilnrtux] [-p] åç§°[=值] ..."} +[source] {"source 文件å [傿•°]"} +[bind] {"bind [-lpvsPSVX] [-m 键映射] [-f 文件å] [-q åç§°] [-u åç§°] [-r é”®åºåˆ—] [-x é”®åºåˆ—:shell-命令] [é”®åºåˆ—:readline-函数 或 readline-命令] "} +[test] {"test [表达å¼]"} +[declare] {"declare [-aAfFgilnrtux] [-p] [åç§°[=值] ...]"} +*[other] æ˜¾ç¤ºå…¶ä»–å‘½ä»¤å¸®åŠ©ä¿¡æ¯ . +} + +information = 这些 shell 命令是内部定义的。请输入 `help' 以获å–一个列表。 + 输入 `help åç§°' 以得到有关函数`åç§°'的更多信æ¯ã€‚ + 使用 `info bash' æ¥èŽ·å¾—å…³äºŽ shell 的更多一般性信æ¯ã€‚ + 使用 `man -k' 或 `info' æ¥èŽ·å–ä¸åœ¨åˆ—表中的命令的更多信æ¯ã€‚ + +helperr = 没有与{$name}匹é…的帮助主题。å°è¯•使用"help help"ã€"man -k {$name} 或 "info {$name}"。 + +is = {$str1} 是 {$str2} +special = {$str1} 是特殊 shell 内建 +hashd = {$str1} 已被录入哈希表 +isfunction = {$str1}是函数 +iskeyword = {$str1} 是 shell 关键字 +isalias = {$str1} 是 {$str2} 的别å +isbuiltin = {$str1} 是 shell 内建 +killargerr = {$str1} : 傿•°å¿…须是进程或任务 ID +letwarn = utshell : let : 需è¦è¡¨è¾¾å¼ +bindvia = å¯ä»¥è¢«è°ƒç”¨ï¼Œ 通过 {$str1} +bindnokeys = {$str1}未与任何键绑定。 +unknowdfunction = {$str1} : 未知函数å +unbindfaild = {$str1} : 无法解除绑定 +invaildmap = {$str1} : 无效的键映射å +logout = 注销 +stoppedjobs = æœ‰åœæ­¢çš„任务 +runjobs = 有è¿è¡Œä¸­çš„任务 diff --git a/utshell-0.5.0/src/1.sh b/utshell-0.5.0/src/1.sh new file mode 100644 index 00000000..9d5d4836 --- /dev/null +++ b/utshell-0.5.0/src/1.sh @@ -0,0 +1,6 @@ +#!/bin/bash +while read line +do + sed -i '1i use crate::src_common::*; ' ${line} +# sed -i 's/use crate::src_common::\*;//g' $line +done < 1.txt diff --git a/utshell-0.5.0/src/1.txt b/utshell-0.5.0/src/1.txt new file mode 100644 index 00000000..4b2b3718 --- /dev/null +++ b/utshell-0.5.0/src/1.txt @@ -0,0 +1,50 @@ +builtins/mapfile.rs +builtins/colon.rs +builtins/exit.rs +builtins/cd.rs +builtins/signal.rs +builtins/let_1.rs +builtins/kill.rs +builtins/common.rs +builtins/fg_bg.rs +builtins/return_1.rs +builtins/type_1.rs +builtins/eval.rs +builtins/wait.rs +builtins/alias.rs +builtins/shopt.rs +builtins/declare.rs +builtins/getopt.rs +builtins/test.rs +builtins/time.rs +builtins/break_1.rs +builtins/suspend.rs +builtins/builtin.rs +builtins/exec_cmd.rs +builtins/umask.rs +builtins/caller.rs +builtins/bind.rs +builtins/evalstring.rs +builtins/bashgetopt.rs +builtins/echo.rs +builtins/printf.rs +builtins/hash.rs +builtins/complete.rs +builtins/command.rs +builtins/setattr.rs +builtins/fc.rs +builtins/shift.rs +builtins/trap.rs +builtins/jobs.rs +builtins/source.rs +builtins/pushd.rs +builtins/enable.rs +builtins/read.rs +builtins/getopts.rs +builtins/history.rs +builtins/ulimit.rs +builtins/evalfile.rs +builtins/exec.rs +builtins/help.rs +builtins/cmd.rs +builtins/set.rs diff --git a/utshell-0.5.0/src/README.txt b/utshell-0.5.0/src/README.txt new file mode 100644 index 00000000..ff0e266f --- /dev/null +++ b/utshell-0.5.0/src/README.txt @@ -0,0 +1,57 @@ +一ã€ç¬¬ä¸€è½®ä¿®æ”¹ +1ã€goto çš„matchå½¢å¼ çœ‹çœ‹æ˜¯å¦èƒ½æ”¹æˆloopå½¢å¼ï¼Œmatchå½¢å¼ä¸ä¸€å®šæ˜¯ä¸å¯ä»¥ï¼Œèƒ½å¦æŠŠæ•°å­—改æˆå­—符 +2ã€æœ‰äº›å®è¢«å†™æˆäº†å‡½æ•°ï¼Œè¿™éƒ¨åˆ†æ˜¯å¦éœ€è¦ä¿®æ”¹ï¼ˆfc.rs) +3ã€signal.rs比较特殊,目å‰è¿˜ä¸æ¸…楚作用是什么,wait.rs中使用 +4ã€builtins䏋颿œ‰å‡ ä¸ªæ–‡ä»¶åå’Œrust关键字é‡å,如何修改 +5ã€expr.rs中的sh_free? +6ã€main.rs中的main函数修改 +7ã€y_tab 没有引用rbash,ä¸ç”¨ä¿®æ”¹ï¼Ÿ + +8ã€r_instruction_r_output_direction: r_instruction = 0;中的r_instruction_r_output_direction去掉r_instruction_å‰ç¼€ + + + + +二ã€ç¬¬äºŒè½®ä¿®æ”¹ç‰¹å¾ +1ã€ç±»åž‹ä¸åŒ¹é…,对于函数指针有多余的“Optionâ€æè¿° + + +三ã€åº“å’Œé‡æž„函数出现函数é‡å¤å®šä¹‰é—®é¢˜åˆ†æž +出现é‡å¤å®šä¹‰çš„函数,å‡ä¸Žreadline/shell.c中é‡å¤ + +1ã€sh_set_lines_and_columns函数 + 1)函数分别定义在:variables.rså’Œreadline/shell.c中 + 2)variables中的该函数没有找到调用的地方 + 3)readline/shell.c中的该函数åªåœ¨readline文件中使用到了 + 4)建议:将variables中的函数改为å¦å¤–一个åå­— + +  //bgz:bash里é¢ï¼Œä¸æ˜¯åŒä¸€ä¸ªå‡½æ•°ã€‚é‡å‘½åsrc/variables.rs下的sh_set_lines_and_columns函数,rename sh_set_line_and_columns as sh_set_line_and_columns_out; + +2ã€sh_get_env_value函数 + 1)函数实现ä¸åŒ,函数分别定义在:variables.rså’Œreadline/shell.c中 + 2)在variables中有如下注释:“/* This is present for use by the tilde and readline libraries. */,ç»è¿‡æŸ¥æ‰¾å‘现 + tildeå’Œreadline库使用的是readline/shell.c中的函数 + + //bgz:将文件src/variables.rs文件中相应函数é‡å‘½å为sh_get_env_value_rename(); + +3ã€sh_get_home_dir + + //bgz:variables.rså’Œshell.cä¸­ç»æŸ¥çœ‹ï¼Œåº”该是一样的(c中使用ifdefine较多)ï¼Œå¤„ç†æ–¹å¼ï¼šæ³¨é‡Šrs文件中此函数,并于开头处添加对c.a的调用(æ„为调用c.a中的åŒå函数)ï¼› + +4ã€sh_single_quote + 1)函数分别定义在:sh/shquote.cå’Œreadline/shell.c中 + 2)函数逻辑看ç€å·®ä¸å¤šï¼Œè¿˜æ²¡ä»”细看 + 3)除sh/shquote.c中使用的函数是本文件中的,其他ä½ç½®è°ƒç”¨çš„都是readline/shell.c中的该函数 + 4)建议:如果函数逻辑相åŒï¼Œåˆ™åœ¨sh/shquote.c中的函数å‰é¢åŠ static + + //bgz:注释shquote.c中sh_single_quote函数,æ›´æ–°c.a 。 + +5ã€sh_unset_nodelay_mode + + //bgz:å¤„ç†æ–¹å¼åŒ3。 + +6ã€src_common.rså’Œsrc/bin/utshellversion.rs中关于shell_nameå˜é‡é‡å¤å®šä¹‰ï¼Œæˆ‘å°†utshellversion.rs中å˜é‡å‰é¢çš„pub去除,错误消除; + + //bgz:å°†src/bin/utshellversion.rs中å˜é‡shell_nameé‡å‘½å为shell_name_rename。 + + diff --git a/utshell-0.5.0/src/alias.rs b/utshell-0.5.0/src/alias.rs new file mode 100644 index 00000000..3896dd61 --- /dev/null +++ b/utshell-0.5.0/src/alias.rs @@ -0,0 +1,495 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::hashlib::{ + hash_create, hash_dispose, hash_flush, hash_insert, hash_remove, hash_search, +}; +use crate::pcomplete::{it_aliases, set_itemlist_dirty}; +#[allow(dead_code)] +use crate::src_common::*; +use crate::y_tab::clear_string_list_expander; +#[no_mangle] +pub fn initialize_aliases() { + unsafe { + if aliases.is_null() { + aliases = hash_create(64 as libc::c_int); + } + } +} +#[no_mangle] +pub fn find_alias(name: *mut libc::c_char) -> *mut alias_t { + let al: *mut BUCKET_CONTENTS; + unsafe { + if aliases.is_null() { + return 0 as *mut libc::c_void as *mut alias_t; + } + al = hash_search(name, aliases, 0 as libc::c_int); + return if !al.is_null() { + (*al).data as *mut alias_t + } else { + 0 as *mut libc::c_void as *mut alias_t + }; + } +} +#[no_mangle] +pub fn get_alias_value(name: *mut libc::c_char) -> *mut libc::c_char { + let alias: *mut alias_t; + if unsafe { aliases.is_null() } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + alias = find_alias(name); + return if !alias.is_null() { + unsafe { (*alias).value } + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; +} +#[no_mangle] +pub fn add_alias(name: *mut libc::c_char, value: *mut libc::c_char) { + let elt: *mut BUCKET_CONTENTS; + let mut temp: *mut alias_t; + let n: libc::c_int; + unsafe { + if aliases.is_null() { + initialize_aliases(); + temp = 0 as *mut libc::c_void as *mut alias_t; + } else { + temp = find_alias(name); + } + if !temp.is_null() { + libc::free((*temp).value as *mut libc::c_void); + (*temp).value = savestring!(value); + + (*temp).flags = + ((*temp).flags as libc::c_int & !(AL_EXPANDNEXT as libc::c_int)) as libc::c_char; + if *value.offset(0 as libc::c_int as isize) != 0 { + n = *value.offset((libc::strlen(value) + 1) as isize) as libc::c_int; + if n == ' ' as i32 || n == '\t' as i32 { + (*temp).flags = ((*temp).flags as libc::c_int | AL_EXPANDNEXT as libc::c_int) + as libc::c_char; + } + } + } else { + temp = libc::malloc(::core::mem::size_of::()) as *mut alias_t; + (*temp).name = savestring!(name); + (*temp).value = savestring!(value); + (*temp).flags = 0 as libc::c_int as libc::c_char; + if *value.offset(0 as libc::c_int as isize) != 0 { + n = *value.offset((libc::strlen(value) - 1) as isize) as libc::c_int; + if n == ' ' as i32 || n == '\t' as i32 { + (*temp).flags = ((*temp).flags as libc::c_int | AL_EXPANDNEXT as libc::c_int) + as libc::c_char; + } + } + elt = hash_insert(savestring!(name), aliases, HASH_NOSRCH as libc::c_int); + (*elt).data = temp as *mut libc::c_void; + set_itemlist_dirty(&mut it_aliases); + }; + } +} +fn free_alias_data(data: *mut libc::c_void) { + let a: *mut alias_t; + a = data as *mut alias_t; + unsafe { + if (*a).flags as libc::c_int & 0x2 as libc::c_int != 0 { + clear_string_list_expander(a); + } + libc::free((*a).value as *mut libc::c_void); + libc::free((*a).name as *mut libc::c_void); + libc::free(data); + } +} +#[no_mangle] +pub(crate) fn remove_alias(name: *mut libc::c_char) -> libc::c_int { + let elt: *mut BUCKET_CONTENTS; + unsafe { + if aliases.is_null() { + return -(1 as libc::c_int); + } + elt = hash_remove(name, aliases, 0 as libc::c_int); + if !elt.is_null() { + free_alias_data((*elt).data); + libc::free((*elt).key as *mut libc::c_void); + libc::free(elt as *mut libc::c_void); + set_itemlist_dirty(&mut it_aliases); + return (*aliases).nentries; + } + } + return -(1 as libc::c_int); +} +#[no_mangle] +pub fn delete_all_aliases() { + unsafe { + if aliases.is_null() { + return; + } + hash_flush( + aliases, + Some(free_alias_data), /* + Some( ::core::mem::transmute::< + unsafe extern "C" fn(*mut libc::c_void) -> (), + sh_free_func_t + >(free_alias_data) + ) + + ::core::mem::transmute::< + Option:: ()>, + Option::, + >( + Some( + ::core::mem::transmute::< + unsafe extern "C" fn(*mut libc::c_void) -> (), + unsafe extern "C" fn() -> (), + >(free_alias_data), + ), + ), + */ + ); + hash_dispose(aliases); + aliases = 0 as *mut libc::c_void as *mut HASH_TABLE; + set_itemlist_dirty(&mut it_aliases); + } +} +fn map_over_aliases(function: Option) -> *mut *mut alias_t { + let mut i: libc::c_int; + let mut tlist: *mut BUCKET_CONTENTS; + let mut alias: *mut alias_t; + let list: *mut *mut alias_t; + let mut list_index: libc::c_int; + unsafe { + i = if !aliases.is_null() { + (*aliases).nentries + } else { + 0 as libc::c_int + }; + } + if i == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut *mut alias_t; + } + unsafe { + list = libc::malloc( + ((i + 1 as libc::c_int) as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::<*mut alias_t>() as libc::c_ulong) + as usize, + ) as *mut *mut alias_t; + } + list_index = 0 as libc::c_int; + i = list_index; + unsafe { + while i < (*aliases).nbuckets { + tlist = if !aliases.is_null() && i < (*aliases).nbuckets { + *((*aliases).bucket_array).offset(i as isize) + } else { + 0 as *mut libc::c_void as *mut BUCKET_CONTENTS + }; + while !tlist.is_null() { + alias = (*tlist).data as *mut alias_t; + if function.is_none() + || (Some(function.expect("non-null function pointer"))) + .expect("non-null function pointer")(alias) + != 0 + { + *list.offset(list_index as isize) = alias; + list_index = list_index + 1; + *list.offset(list_index as isize) = 0 as *mut libc::c_void as *mut alias_t; + } + tlist = (*tlist).next; + } + i += 1; + } + } + return list; +} +fn sort_aliases(array: *mut *mut alias_t) { + unsafe { + qsort( + array as *mut libc::c_void, + strvec_len(array as *mut *mut libc::c_char) as libc::size_t, + ::core::mem::size_of::<*mut alias_t>() as usize, + ::core::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(qsort_alias_compare)), + ); + } +} +fn qsort_alias_compare(as1: *mut *mut alias_t, as2: *mut *mut alias_t) -> libc::c_int { + let mut result: libc::c_int; + unsafe { + result = *((**as1).name).offset(0 as libc::c_int as isize) as libc::c_int + - *((**as2).name).offset(0 as libc::c_int as isize) as libc::c_int; + if result == 0 as libc::c_int { + result = libc::strcmp((**as1).name, (**as2).name); + } + } + return result; +} +#[no_mangle] +pub fn all_aliases() -> *mut *mut alias_t { + unsafe { + let list: *mut *mut alias_t; + + if aliases.is_null() + || (if !aliases.is_null() { + (*aliases).nentries + } else { + 0 as libc::c_int + }) == 0 as libc::c_int + { + return 0 as *mut libc::c_void as *mut *mut alias_t; + } + list = map_over_aliases(::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void)); + if !list.is_null() { + sort_aliases(list); + } + return list; + } +} +#[no_mangle] +pub fn alias_expand_word(s: *mut libc::c_char) -> *mut libc::c_char { + let r: *mut alias_t; + r = find_alias(s); + return if !r.is_null() { + unsafe { savestring!((*r).value) } + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; +} +static mut command_word: libc::c_int = 0; +fn skipquotes(string: *mut libc::c_char, start: libc::c_int) -> libc::c_int { + let mut i: libc::c_int; + unsafe { + let delimiter: libc::c_int = *string.offset(start as isize) as libc::c_int; + + i = start + 1 as libc::c_int; + while *string.offset(i as isize) != 0 { + if *string.offset(i as isize) as libc::c_int == '\\' as i32 { + i += 1; + + if *string.offset(i as isize) as libc::c_int == 0 as libc::c_int { + break; + } + } else if *string.offset(i as isize) as libc::c_int == delimiter { + return i; + } + i += 1; + } + } + return i; +} +fn skipws(string: *mut libc::c_char, _start: libc::c_int) -> libc::c_int { + let mut i: libc::c_int; + let mut pass_next: libc::c_int; + let mut backslash_quoted_word: libc::c_int; + let mut peekc: libc::c_uchar; + unsafe { + pass_next = 0 as libc::c_int; + backslash_quoted_word = 0; + i = 0; + while *string.offset(i as isize) != 0 { + if pass_next != 0 { + pass_next = 0 as libc::c_int; + } else if *string.offset(i as isize) as libc::c_int == ' ' as i32 + || *string.offset(i as isize) as libc::c_int == '\t' as i32 + { + backslash_quoted_word = 0 as libc::c_int; + } else if *string.offset(i as isize) as libc::c_int == '\\' as i32 { + peekc = *string.offset((i + 1 as libc::c_int) as isize) as libc::c_uchar; + if peekc as libc::c_int == 0 as libc::c_int { + break; + } + if 1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(peekc as libc::c_int as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + { + backslash_quoted_word += 1; + } else { + pass_next += 1; + } + } else if *string.offset(i as isize) as libc::c_int == '\'' as i32 + || *string.offset(i as isize) as libc::c_int == '"' as i32 + { + i = skipquotes(string, i); + if *string.offset(i as isize) as libc::c_int == '\0' as i32 { + break; + } + peekc = *string.offset((i + 1 as libc::c_int) as isize) as libc::c_uchar; + if 1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(peekc as libc::c_int as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + { + backslash_quoted_word += 1; + } + } else if !(backslash_quoted_word != 0) { + if !(if *string.offset(i as isize) as libc::c_int != 0 { + (mbschr( + b"\r\n;|&(\0" as *const u8 as *const libc::c_char, + *string.offset(i as isize) as libc::c_int, + ) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + } != 0) + { + break; + } + command_word += 1; + } + i += 1; + } + } + return i; +} +fn rd_token(string: *mut libc::c_char, start: libc::c_int) -> libc::c_int { + let mut i: libc::c_int; + unsafe { + i = start; + while *string.offset(i as isize) as libc::c_int != 0 + && !(*string.offset(i as isize) as libc::c_int == ' ' as i32 + || *string.offset(i as isize) as libc::c_int == '\t' as i32 + || (if *string.offset(i as isize) as libc::c_int != 0 { + unsafe { + (mbschr( + b" \t\n\r;|&()\0" as *const u8 as *const libc::c_char, + *string.offset(i as isize) as libc::c_int, + ) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } + } else { + 0 as libc::c_int + }) != 0) + { + if *string.offset(i as isize) as libc::c_int == '\\' as i32 { + i += 1; + + if *string.offset(i as isize) as libc::c_int == 0 as libc::c_int { + break; + } + } else if *string.offset(i as isize) as libc::c_int == '\'' as i32 + || *string.offset(i as isize) as libc::c_int == '"' as i32 + { + i = skipquotes(string, i); + if *string.offset(i as isize) as libc::c_int == '\0' as i32 { + break; + } + } + i += 1; + } + } + return i; +} +#[no_mangle] +pub fn alias_expand(string: *mut libc::c_char) -> *mut libc::c_char { + let mut i: libc::c_int; + let mut j: libc::c_int; + let mut start: libc::c_int; + let mut line: *mut libc::c_char; + let token: *mut libc::c_char; + let mut line_len: libc::c_int; + let mut tl: libc::c_int; + let mut real_start: libc::c_int; + let mut expand_next: libc::c_int; + let mut expand_this_token: libc::c_int; + let mut alias: *mut alias_t = 0 as *mut alias_t; + unsafe { + line_len = (libc::strlen(string) + 1) as libc::c_int; + line = libc::malloc(line_len as usize) as *mut libc::c_char; + token = libc::malloc(line_len as usize) as *mut libc::c_char; + + i = 0 as libc::c_int; + *line.offset(0 as libc::c_int as isize) = i as libc::c_char; + expand_next = 0 as libc::c_int; + command_word = 1 as libc::c_int; + loop { + *token.offset(0 as libc::c_int as isize) = 0 as libc::c_int as libc::c_char; + start = i; + i = skipws(string, start); + + if start == i && *string.offset(i as isize) as libc::c_int == '\0' as i32 { + libc::free(token as *mut libc::c_void); + return line; + } + j = libc::strlen(line) as libc::c_int; + tl = i - start; + RESIZE_MALLOCED_BUFFER!(line, j, (tl + 1), line_len, (tl + 50)); + libc::strncpy( + line.offset(j as isize), + string.offset(start as isize), + tl as usize, + ); + *line.offset((j + tl) as isize) = '\0' as i32 as libc::c_char; + real_start = i; + command_word = (command_word != 0 + || (if *string.offset(i as isize) as libc::c_int != 0 { + (mbschr( + b"\r\n;|&(\0" as *const u8 as *const libc::c_char, + *string.offset(i as isize) as libc::c_int, + ) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0) as libc::c_int; + expand_this_token = (command_word != 0 || expand_next != 0) as libc::c_int; + expand_next = 0 as libc::c_int; + + start = i; + i = rd_token(string, start); + tl = i - start; + if tl == 0 as libc::c_int && *string.offset(i as isize) as libc::c_int != '\0' as i32 { + tl = 1 as libc::c_int; + i += 1; + } + + libc::strncpy(token, string.offset(start as isize), tl as usize); + *token.offset(tl as isize) = '\0' as i32 as libc::c_char; + if !(mbschr(token, '\\' as i32)).is_null() { + expand_this_token = 0 as libc::c_int; + } + if *token.offset(0 as libc::c_int as isize) as libc::c_int != 0 + && (expand_this_token != 0 || alias_expand_all != 0) + && { + alias = find_alias(token); + !alias.is_null() + } + { + let v: *mut libc::c_char; + let vlen: libc::c_int; + let llen: libc::c_int; + v = (*alias).value; + vlen = libc::strlen(v) as libc::c_int; + llen = libc::strlen(line) as libc::c_int; + RESIZE_MALLOCED_BUFFER!(line, llen, (vlen + 3), line_len, (vlen + 50)); + libc::strcpy(line.offset(llen as isize), v); + if expand_this_token != 0 + && vlen != 0 + && (*v.offset((vlen - 1 as libc::c_int) as isize) as libc::c_int == ' ' as i32 + || *v.offset((vlen - 1 as libc::c_int) as isize) as libc::c_int + == '\t' as i32) + || alias_expand_all != 0 + { + expand_next = 1 as libc::c_int; + } + } else { + let llen_0: libc::c_int; + let tlen: libc::c_int; + llen_0 = libc::strlen(line) as libc::c_int; + tlen = i - real_start; + RESIZE_MALLOCED_BUFFER!(line, llen_0, (tlen + 1), line_len, (llen_0 + tlen + 50)); + libc::strncpy( + line.offset(llen_0 as isize), + string.offset(real_start as isize), + tlen as usize, + ); + *line.offset((llen_0 + tlen) as isize) = '\0' as i32 as libc::c_char; + } + command_word = 0 as libc::c_int; + } + } +} diff --git a/utshell-0.5.0/src/array.rs b/utshell-0.5.0/src/array.rs new file mode 100644 index 00000000..d0d7e699 --- /dev/null +++ b/utshell-0.5.0/src/array.rs @@ -0,0 +1,1021 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::dispose_cmd::dispose_words; +use crate::make_cmd::{make_bare_word, make_word_list}; +use crate::src_common::*; +use crate::subst::{ + dequote_escapes, dequote_string, pat_subst, quote_escapes, quote_string, remove_quoted_nulls, + string_list_pos_params, +}; + +#[no_mangle] +pub fn array_create() -> *mut ARRAY { + let mut r: *mut ARRAY = 0 as *mut ARRAY; + let mut head: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + r = libc::malloc(std::mem::size_of::() as usize) as *mut ARRAY; + (*r).type_0 = array_indexed; + (*r).max_index = -(1 as libc::c_int) as arrayind_t; + (*r).num_elements = 0 as libc::c_int; + (*r).lastref = 0 as *mut ARRAY_ELEMENT; + head = array_create_element( + -(1 as libc::c_int) as arrayind_t, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + (*head).next = head; + (*head).prev = (*head).next; + (*r).head = head; + } + return r; +} +#[no_mangle] +pub fn array_flush(mut a: *mut ARRAY) { + let mut r: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut r1: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + if a.is_null() { + return; + } + unsafe { + r = element_forw!((*a).head); + while r != (*a).head { + r1 = element_forw!(r); + array_dispose_element(r); + r = r1; + } + (*(*a).head).prev = (*a).head; + (*(*a).head).next = (*(*a).head).prev; + (*a).max_index = -(1 as libc::c_int) as arrayind_t; + (*a).num_elements = 0 as libc::c_int; + (*a).lastref = 0 as *mut array_element; + } +} +#[no_mangle] +pub fn array_dispose(mut a: *mut ARRAY) { + if a.is_null() { + return; + } + array_flush(a); + unsafe { + array_dispose_element((*a).head); + } + (a as *mut libc::c_void); +} +#[no_mangle] +pub fn array_copy(mut a: *mut ARRAY) -> *mut ARRAY { + let mut a1: *mut ARRAY = 0 as *mut ARRAY; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut new: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + if a.is_null() { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a1 = array_create(); + unsafe { + (*a1).type_0 = (*a).type_0; + (*a1).max_index = (*a).max_index; + (*a1).num_elements = (*a).num_elements; + ae = element_forw!((*a).head); + while ae != (*a).head { + new = array_create_element(element_index!(ae), element_value!(ae)); + ADD_BEFORE!((*a1).head, new); + if ae == LASTREF!(a) { + SET_LASTREF!(a1, new); + } + ae = element_forw!(ae); + } + } + return a1; +} +#[no_mangle] +pub fn array_slice( + mut array: *mut ARRAY, + mut s: *mut ARRAY_ELEMENT, + mut e: *mut ARRAY_ELEMENT, +) -> *mut ARRAY { + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut p: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut n: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut i: libc::c_int = 0; + let mut mi: arrayind_t = 0; + unsafe { + a = array_create(); + (*a).type_0 = (*array).type_0; + mi = 0 as libc::c_int as arrayind_t; + p = s; + i = 0 as libc::c_int; + while p != e { + n = array_create_element(element_index!(p), element_value!(p)); + ADD_BEFORE!((*a).head, n); + mi = element_index!(n); + p = element_forw!(p); + i += 1; + } + (*a).num_elements = i; + (*a).max_index = mi; + } + return a; +} +#[no_mangle] +pub fn array_walk( + mut a: *mut ARRAY, + mut func: Option, + mut udata: *mut libc::c_void, +) { + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + if a.is_null() || array_empty!(a) { + return; + } + ae = element_forw!((*a).head); + while ae != (*a).head { + if (Some(func.expect("non-null function pointer"))).expect("non-null function pointer")( + ae, udata, + ) < 0 as libc::c_int + { + return; + } + ae = element_forw!(ae); + } + } +} +#[no_mangle] +pub fn array_shift( + mut a: *mut ARRAY, + mut n: libc::c_int, + mut flags: libc::c_int, +) -> *mut ARRAY_ELEMENT { + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut ret: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut i: libc::c_int = 0; + unsafe { + if a.is_null() || array_empty!(a) || n <= 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + } + INVALIDATE_LASTREF!(a); + + i = 0 as libc::c_int; + ae = element_forw!((*a).head); + ret = ae; + while ae != (*a).head && i < n { + ae = element_forw!(ae); + i += 1; + } + if ae == (*a).head { + if flags & AS_DISPOSE as libc::c_int != 0 { + array_flush(a); + return 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + } + ae = ret; + while element_forw!(ae) != (*a).head { + ae = element_forw!(ae); + } + element_forw!(ae) = 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + (*(*a).head).prev = (*a).head; + (*(*a).head).next = (*(*a).head).prev; + (*a).max_index = -(1 as libc::c_int) as arrayind_t; + (*a).num_elements = 0 as libc::c_int; + return ret; + } + (*(*ae).prev).next = 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + (*(*a).head).next = ae; + (*ae).prev = (*a).head; + while ae != (*a).head { + element_index!(ae) -= n as libc::c_long; + ae = element_forw!(ae); + } + (*a).num_elements -= n; + (*a).max_index = element_index!((*(*a).head).prev); + if flags & AS_DISPOSE as libc::c_int != 0 { + ae = ret; + while !ae.is_null() { + ret = element_forw!(ae); + array_dispose_element(ae); + ae = ret; + } + return 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + } + } + return ret; +} +#[no_mangle] +pub fn array_rshift( + mut a: *mut ARRAY, + mut n: libc::c_int, + mut s: *mut libc::c_char, +) -> libc::c_int { + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut new: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + if a.is_null() || array_empty!(a) && s.is_null() { + return 0 as libc::c_int; + } else if n <= 0 as libc::c_int { + return (*a).num_elements; + } + ae = element_forw!((*a).head); + if !s.is_null() { + new = array_create_element(0 as libc::c_int as arrayind_t, s); + ADD_BEFORE!(ae, new); + (*a).num_elements += 1; + if array_num_elements!(a) == 1 as libc::c_int { + (*a).max_index = 0 as libc::c_int as arrayind_t; + return 1 as libc::c_int; + } + } + while ae != (*a).head { + element_index!(ae) += n as libc::c_long; + ae = element_forw!(ae); + } + (*a).max_index = (*(*(*a).head).prev).ind; + INVALIDATE_LASTREF!(a); + return (*a).num_elements; + } +} +#[no_mangle] +pub fn array_unshift_element(mut a: *mut ARRAY) -> *mut ARRAY_ELEMENT { + return array_shift(a, 1 as libc::c_int, 0 as libc::c_int); +} +#[no_mangle] +pub fn array_shift_element(mut a: *mut ARRAY, mut v: *mut libc::c_char) -> libc::c_int { + return array_rshift(a, 1 as libc::c_int, v); +} +#[no_mangle] +pub fn array_quote(mut array: *mut ARRAY) -> *mut ARRAY { + let mut a: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if array.is_null() || array_head!(array).is_null() || array_empty!(array) { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = element_forw!((*array).head); + while a != (*array).head { + t = quote_string((*a).value); + if !((*a).value).is_null() { + libc::free((*a).value as *mut libc::c_void); + } + (*a).value = 0 as *mut libc::c_char; + (*a).value = t; + a = element_forw!(a); + } + } + return array; +} +#[no_mangle] +pub fn array_quote_escapes(mut array: *mut ARRAY) -> *mut ARRAY { + let mut a: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if array.is_null() || array_head!(array).is_null() || array_empty!(array) { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = element_forw!((*array).head); + while a != (*array).head { + t = quote_escapes((*a).value); + if !((*a).value).is_null() { + libc::free((*a).value as *mut libc::c_void); + } + (*a).value = 0 as *mut libc::c_char; + (*a).value = t; + a = element_forw!(a); + } + } + return array; +} +#[no_mangle] +pub fn array_dequote(mut array: *mut ARRAY) -> *mut ARRAY { + let mut a: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if array.is_null() || array_head!(array).is_null() || array_empty!(array) { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = element_forw!((*array).head); + while a != (*array).head { + t = dequote_string((*a).value); + if !((*a).value).is_null() { + libc::free((*a).value as *mut libc::c_void); + } + (*a).value = 0 as *mut libc::c_char; + (*a).value = t; + a = element_forw!(a); + } + } + return array; +} +#[no_mangle] +pub fn array_dequote_escapes(mut array: *mut ARRAY) -> *mut ARRAY { + let mut a: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if array.is_null() || array_head!(array).is_null() || array_empty!(array) { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = element_forw!((*array).head); + while a != (*array).head { + t = dequote_escapes((*a).value); + if !((*a).value).is_null() { + libc::free((*a).value as *mut libc::c_void); + } + (*a).value = 0 as *mut libc::c_char; + (*a).value = t; + a = element_forw!(a); + } + } + return array; +} +#[no_mangle] +pub fn array_remove_quoted_nulls(mut array: *mut ARRAY) -> *mut ARRAY { + let mut a: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + if array.is_null() || array_head!(array).is_null() || array_empty!(array) { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = element_forw!((*array).head); + while a != (*array).head { + (*a).value = remove_quoted_nulls((*a).value); + a = element_forw!(a); + } + } + return array; +} +#[no_mangle] +pub fn array_subrange( + mut a: *mut ARRAY, + mut start: arrayind_t, + mut nelem: arrayind_t, + mut starsub: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, +) -> *mut libc::c_char { + let mut a2: *mut ARRAY = 0 as *mut ARRAY; + let mut h: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut p: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut i: arrayind_t = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + unsafe { + p = if !a.is_null() { + array_head!(a) + } else { + 0 as *mut array_element + }; + if p.is_null() || array_empty!(a) || start > array_max_index!(a) { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + p = element_forw!(p); + while p != array_head!(a) && start > element_index!(p) { + p = element_forw!(p); + } + if p == (*a).head { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + i = 0 as libc::c_int as arrayind_t; + h = p; + while p != (*a).head && i < nelem { + i += 1; + p = element_forw!(p); + } + } + a2 = array_slice(a, h, p); + wl = array_to_word_list(a2); + array_dispose(a2); + if wl.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + t = string_list_pos_params( + if starsub != 0 { '*' as i32 } else { '@' as i32 }, + wl, + quoted, + pflags, + ); + dispose_words(wl); + return t; +} +#[no_mangle] +pub fn array_patsub( + mut a: *mut ARRAY, + mut pat: *mut libc::c_char, + mut rep: *mut libc::c_char, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pchar: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + if unsafe { a.is_null() || array_head!(a).is_null() || array_empty!(a) } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + wl = array_to_word_list(a); + if wl.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + save = wl; + unsafe { + while !wl.is_null() { + t = pat_subst((*(*wl).word).word, pat, rep, mflags); + if !((*(*wl).word).word).is_null() { + libc::free((*(*wl).word).word as *mut libc::c_void); + } + (*(*wl).word).word = 0 as *mut libc::c_char; + (*(*wl).word).word = t; + wl = (*wl).next; + } + } + pchar = if mflags & MATCH_STARSUB as libc::c_int == MATCH_STARSUB as libc::c_int { + '*' as i32 + } else { + '@' as i32 + }; + qflags = if mflags & MATCH_QUOTED as libc::c_int == MATCH_QUOTED as libc::c_int { + 0x1 as libc::c_int + } else { + 0 as libc::c_int + }; + pflags = if mflags & MATCH_ASSIGNRHS as libc::c_int != 0 { + PF_ASSIGNRHS as libc::c_int + } else { + 0 as libc::c_int + }; + t = string_list_pos_params(pchar, save, qflags, pflags); + dispose_words(save); + return t; +} +#[no_mangle] +pub fn array_modcase( + mut a: *mut ARRAY, + mut pat: *mut libc::c_char, + mut modop: libc::c_int, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pchar: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + if unsafe { a.is_null() || array_head!(a).is_null() || array_empty!(a) } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + wl = array_to_word_list(a); + if wl.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + save = wl; + unsafe { + while !wl.is_null() { + t = sh_modcase((*(*wl).word).word, pat, modop); + if !((*(*wl).word).word).is_null() { + libc::free((*(*wl).word).word as *mut libc::c_void); + } + (*(*wl).word).word = 0 as *mut libc::c_char; + (*(*wl).word).word = t; + wl = (*wl).next; + } + } + pchar = if mflags & MATCH_STARSUB as libc::c_int == MATCH_STARSUB as libc::c_int { + '*' as i32 + } else { + '@' as i32 + }; + qflags = if mflags & MATCH_QUOTED as libc::c_int == MATCH_QUOTED as libc::c_int { + Q_DOUBLE_QUOTES as libc::c_int + } else { + 0 as libc::c_int + }; + pflags = if mflags & MATCH_ASSIGNRHS as libc::c_int != 0 { + PF_ASSIGNRHS as libc::c_int + } else { + 0 as libc::c_int + }; + t = string_list_pos_params(pchar, save, qflags, pflags); + dispose_words(save); + return t; +} +#[no_mangle] +pub fn array_create_element( + mut indx: arrayind_t, + mut value: *mut libc::c_char, +) -> *mut ARRAY_ELEMENT { + let mut r: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + r = libc::malloc(std::mem::size_of::() as usize) as *mut ARRAY_ELEMENT; + (*r).ind = indx; + (*r).value = if !value.is_null() { + savestring!(value) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + (*r).prev = 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + (*r).next = (*r).prev; + } + return r; +} +#[no_mangle] +pub fn array_dispose_element(mut ae: *mut ARRAY_ELEMENT) { + unsafe { + if !ae.is_null() { + if !((*ae).value).is_null() { + libc::free((*ae).value as *mut libc::c_void); + } + (*ae).value = 0 as *mut libc::c_char; + libc::free(ae as *mut libc::c_void); + } + } +} +#[no_mangle] +pub fn array_insert(mut a: *mut ARRAY, mut i: arrayind_t, mut v: *mut libc::c_char) -> libc::c_int { + let mut new: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut start: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut startind: arrayind_t = 0; + let mut direction: libc::c_int = 0; + if a.is_null() { + return -(1 as libc::c_int); + } + unsafe { + new = array_create_element(i, v); + if i > array_max_index!(a) { + ADD_BEFORE!((*a).head, new); + (*a).max_index = i; + (*a).num_elements += 1; + SET_LASTREF!(a, new); + return 0 as libc::c_int; + } else if i < array_first_index!(a) { + ADD_AFTER!((*a).head, new); + (*a).num_elements += 1; + SET_LASTREF!(a, new); + return 0 as libc::c_int; + } + start = LASTREF!(a); + startind = element_index!(start); + if i < startind / 2 as libc::c_int as libc::c_long { + start = element_forw!((*a).head); + startind = element_index!(start); + direction = 1 as libc::c_int; + } else if i >= startind { + direction = 1 as libc::c_int; + } else { + direction = -(1 as libc::c_int); + } + ae = start; + while ae != (*a).head { + if element_index!(ae) == i { + libc::free(element_value!(ae) as *mut libc::c_void); + (*ae).value = (*new).value; + (*new).value = 0 as *mut libc::c_char; + array_dispose_element(new); + SET_LASTREF!(a, ae); + return 0 as libc::c_int; + } else if direction == 1 as libc::c_int && (*ae).ind > i { + ADD_BEFORE!(ae, new); + (*a).num_elements += 1; + SET_LASTREF!(a, new); + return 0 as libc::c_int; + } else if direction == -(1 as libc::c_int) && (*ae).ind < i { + ADD_AFTER!(ae, new); + (*a).num_elements += 1; + (*a).lastref = new; + SET_LASTREF!(a, new); + return 0 as libc::c_int; + } + ae = if direction == 1 as libc::c_int { + element_forw!(ae) + } else { + element_back!(ae) + }; + } + array_dispose_element(new); + INVALIDATE_LASTREF!(a); + } + return -(1 as libc::c_int); +} +#[no_mangle] +pub fn array_remove(mut a: *mut ARRAY, mut i: arrayind_t) -> *mut ARRAY_ELEMENT { + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut start: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut startind: arrayind_t = 0; + let mut direction: libc::c_int = 0; + unsafe { + if a.is_null() || array_empty!(a) { + return 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + } + if i > array_max_index!(a) || i < array_first_index!(a) { + return 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; + } + start = LASTREF!(a); + startind = element_index!(start); + if i < startind / 2 as libc::c_int as libc::c_long { + start = element_forw!((*a).head); + startind = element_index!(start); + direction = 1 as libc::c_int; + } else if i >= startind { + direction = 1 as libc::c_int; + } else { + direction = -(1 as libc::c_int); + } + ae = start; + while ae != (*a).head { + if element_index!(ae) == i { + (*(*ae).next).prev = (*ae).prev; + (*(*ae).prev).next = (*ae).next; + (*a).num_elements -= 1; + (*a).num_elements; + if i == array_max_index!(a) { + (*a).max_index = element_index!((*ae).prev); + } + if (*ae).next != (*a).head { + SET_LASTREF!(a, (*ae).next); + } else if (*ae).prev != (*a).head { + SET_LASTREF!(a, (*ae).prev); + } else { + INVALIDATE_LASTREF!(a); + } + return ae; + } + ae = if direction == 1 as libc::c_int { + element_forw!(ae) + } else { + element_back!(ae) + }; + if direction == 1 as libc::c_int && element_index!(ae) > i { + break; + } + if direction == -(1 as libc::c_int) && element_index!(ae) < i { + break; + } + } + } + return 0 as *mut libc::c_void as *mut ARRAY_ELEMENT; +} +#[no_mangle] +pub fn array_reference(mut a: *mut ARRAY, mut i: arrayind_t) -> *mut libc::c_char { + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut start: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut startind: arrayind_t = 0; + let mut direction: libc::c_int = 0; + unsafe { + if a.is_null() || array_empty!(a) { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if i > array_max_index!(a) || i < array_first_index!(a) { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + start = LASTREF!(a); + startind = element_index!(start); + if i < startind / 2 as libc::c_int as libc::c_long { + start = element_forw!((*a).head); + startind = element_index!(start); + direction = 1 as libc::c_int; + } else if i >= startind { + direction = 1 as libc::c_int; + } else { + direction = -(1 as libc::c_int); + } + ae = start; + while ae != (*a).head { + if element_index!(ae) == i { + SET_LASTREF!(a, ae); + return element_value!(ae); + } + ae = if direction == 1 as libc::c_int { + element_forw!(ae) + } else { + element_back!(ae) + }; + if direction == 1 as libc::c_int && (*ae).ind > i { + start = ae; + break; + } else { + if !(direction == -(1 as libc::c_int) && (*ae).ind < i) { + continue; + } + start = ae; + break; + } + } + SET_LASTREF!(a, start); + } + return 0 as *mut libc::c_void as *mut libc::c_char; +} +#[no_mangle] +pub fn array_to_word_list(mut a: *mut ARRAY) -> *mut WORD_LIST { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + if a.is_null() || (*a).num_elements == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + list = 0 as *mut libc::c_void as *mut WORD_LIST; + ae = element_forw!((*a).head); + while ae != (*a).head { + list = make_word_list(make_bare_word(element_value!(ae)), list); + ae = element_forw!(ae); + } + return REVERSE_LIST!(list, *mut WORD_LIST); + } +} +#[no_mangle] +pub fn array_assign_list(mut array: *mut ARRAY, mut list: *mut WORD_LIST) -> *mut ARRAY { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut i: arrayind_t = 0; + l = list; + i = 0 as libc::c_int as arrayind_t; + unsafe { + while !l.is_null() { + array_insert(array, i, (*(*l).word).word); + l = (*l).next; + } + } + return array; +} +#[no_mangle] +pub fn array_from_word_list(mut list: *mut WORD_LIST) -> *mut ARRAY { + let mut a: *mut ARRAY = 0 as *mut ARRAY; + if list.is_null() { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = array_create(); + return array_assign_list(a, list); +} +#[no_mangle] +pub fn array_keys_to_word_list(mut a: *mut ARRAY) -> *mut WORD_LIST { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if a.is_null() || array_empty!(a) { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + list = 0 as *mut libc::c_void as *mut WORD_LIST; + + ae = element_forw!((*a).head); + while ae != (*a).head { + t = itos(element_index!(ae)); + list = make_word_list(make_bare_word(t), list); + libc::free(t as *mut libc::c_void); + element_forw!(ae); + } + return REVERSE_LIST!(list, *mut WORD_LIST); + } +} +#[no_mangle] +pub fn array_to_argv(mut a: *mut ARRAY, mut countp: *mut libc::c_int) -> *mut *mut libc::c_char { + let mut ret: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + if a.is_null() || array_empty!(a) { + if !countp.is_null() { + *countp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + ret = strvec_create(array_num_elements!(a) + 1 as libc::c_int); + i = 0 as libc::c_int; + ae = element_forw!((*a).head); + while ae != (*a).head { + t = element_value!(ae); + if !t.is_null() { + *ret.offset(i as isize) = savestring!(t); + i = i + 1; + } + ae = element_forw!(ae); + } + *ret.offset(i as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + if !countp.is_null() { + *countp = i; + } + } + return ret; +} +fn array_to_string_internal( + mut start: *mut ARRAY_ELEMENT, + mut end: *mut ARRAY_ELEMENT, + mut sep: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut slen: libc::c_int = 0; + let mut rsize: libc::c_int = 0; + let mut rlen: libc::c_int = 0; + let mut reg: libc::c_int = 0; + if start == end { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + slen = unsafe { libc::strlen(sep) as libc::c_int }; + result = 0 as *mut libc::c_char; + rlen = 0 as libc::c_int; + rsize = rlen; + ae = start; + unsafe { + while ae != end { + if rsize == 0 as libc::c_int { + rsize = 64 as libc::c_int; + result = libc::malloc(rsize as usize) as *mut libc::c_char; + } + if !element_value!(ae).is_null() { + t = if quoted != 0 { + quote_string(element_value!(ae)) + } else { + element_value!(ae) + }; + reg = libc::strlen(t) as libc::c_int; + + RESIZE_MALLOCED_BUFFER!( + result, + rlen, + (reg + slen + 2 as libc::c_int), + rsize, + rsize + ); + + libc::strcpy(result.offset(rlen as isize), t); + rlen += reg; + if quoted != 0 { + libc::free(t as *mut libc::c_void); + } + if element_forw!(ae) != end { + libc::strcpy(result.offset(rlen as isize), sep); + rlen += slen; + } + } + ae = element_forw!(ae); + } + } + if !result.is_null() { + unsafe { + *result.offset(rlen as isize) = '\0' as i32 as libc::c_char; + } + } + return result; +} +#[no_mangle] +pub fn array_to_kvpair(mut a: *mut ARRAY, mut quoted: libc::c_int) -> *mut libc::c_char { + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut valstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut is: *mut libc::c_char = 0 as *mut libc::c_char; + let mut indstr: [libc::c_char; 22] = [0; 22]; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut rsize: libc::c_int = 0; + let mut rlen: libc::c_int = 0; + let mut elen: libc::c_int = 0; + unsafe { + if a.is_null() || array_empty!(a) { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + rsize = 128 as libc::c_int; + result = libc::malloc(rsize as usize) as *mut libc::c_char; + rlen = 0 as libc::c_int; + *result.offset(rlen as isize) = '\0' as i32 as libc::c_char; + ae = element_forw!((*a).head); + while ae != (*a).head { + is = inttostr( + (*ae).ind, + indstr.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; 22]>() as usize as u64, + ); + valstr = if !element_value!(ae).is_null() { + if ansic_shouldquote(element_value!(ae)) != 0 { + ansic_quote(element_value!(ae), 0 as libc::c_int, 0 as *mut libc::c_int) + } else { + sh_double_quote(element_value!(ae)) + } + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + elen = (STRLEN!(is) + 8 + STRLEN!(valstr)) as libc::c_int; + RESIZE_MALLOCED_BUFFER!(result, rlen, (elen + 1), rsize, rsize); + + libc::strcpy(result.offset(rlen as isize), is); + rlen += STRLEN!(is) as libc::c_int; + *result.offset(rlen as isize) = ' ' as i32 as libc::c_char; + rlen = rlen + 1; + if !valstr.is_null() { + libc::strcpy(result.offset(rlen as isize), valstr); + rlen += STRLEN!(valstr) as libc::c_int; + } else { + libc::strcpy( + result.offset(rlen as isize), + b"\"\"\0" as *const u8 as *const libc::c_char, + ); + rlen += 2 as libc::c_int; + } + if element_forw!(ae) != (*a).head { + *result.offset(rlen as isize) = ' ' as i32 as libc::c_char; + rlen = rlen + 1; + } + if !valstr.is_null() { + libc::free(valstr as *mut libc::c_void); + } + valstr = 0 as *mut libc::c_char; + ae = element_forw!(ae); + } + + RESIZE_MALLOCED_BUFFER!(result, rlen, 1, rsize, 8); + *result.offset(rlen as isize) = '\0' as i32 as libc::c_char; + + if quoted != 0 { + valstr = sh_single_quote(result); + libc::free(result as *mut libc::c_void); + result = valstr; + } + } + return result; +} +#[no_mangle] +pub fn array_to_assign(mut a: *mut ARRAY, mut quoted: libc::c_int) -> *mut libc::c_char { + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut valstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut is: *mut libc::c_char = 0 as *mut libc::c_char; + let mut indstr: [libc::c_char; 22] = [0; 22]; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut rsize: libc::c_int = 0; + let mut rlen: libc::c_int = 0; + let mut elen: libc::c_int = 0; + unsafe { + if a.is_null() || array_empty!(a) { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + rsize = 128 as libc::c_int; + result = libc::malloc(rsize as usize) as *mut libc::c_char; + *result.offset(0 as libc::c_int as isize) = '(' as i32 as libc::c_char; + rlen = 1 as libc::c_int; + ae = element_forw!((*a).head); + + while ae != (*a).head { + is = inttostr( + element_index!(ae), + indstr.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; 22]>() as usize as u64, + ); + valstr = if !element_value!(ae).is_null() { + if ansic_shouldquote(element_value!(ae)) != 0 { + ansic_quote(element_value!(ae), 0 as libc::c_int, 0 as *mut libc::c_int) + } else { + sh_double_quote(element_value!(ae)) + } + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + elen = (STRLEN!(is) + 8 + STRLEN!(valstr)) as libc::c_int; + RESIZE_MALLOCED_BUFFER!(result, rlen, (elen + 1), rsize, rsize); + *result.offset(rlen as isize) = '[' as i32 as libc::c_char; + rlen = rlen + 1; + libc::strcpy(result.offset(rlen as isize), is); + rlen += STRLEN!(is) as libc::c_int; + + *result.offset(rlen as isize) = ']' as i32 as libc::c_char; + rlen = rlen + 1; + *result.offset(rlen as isize) = '=' as i32 as libc::c_char; + rlen = rlen + 1; + if !valstr.is_null() { + libc::strcpy(result.offset(rlen as isize), valstr); + rlen += STRLEN!(valstr) as libc::c_int; + } + if element_forw!(ae) != (*a).head { + *result.offset(rlen as isize) = ' ' as i32 as libc::c_char; + rlen = rlen + 1; + } + if !valstr.is_null() { + libc::free(valstr as *mut libc::c_void); + } + valstr = 0 as *mut libc::c_char; + ae = (*ae).next; + } + RESIZE_MALLOCED_BUFFER!(result, rlen, 1, rsize, 8); + + *result.offset(rlen as isize) = ')' as i32 as libc::c_char; + rlen = rlen + 1; + *result.offset(rlen as isize) = '\0' as i32 as libc::c_char; + if quoted != 0 { + valstr = sh_single_quote(result); + libc::free(result as *mut libc::c_void); + result = valstr; + } + } + return result; +} +#[no_mangle] +pub fn array_to_string( + mut a: *mut ARRAY, + mut sep: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + if a.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + if array_empty!(a) { + return savestring!(b"\0" as *const u8 as *const libc::c_char); + } + return array_to_string_internal(element_forw!((*a).head), (*a).head, sep, quoted); + } +} diff --git a/utshell-0.5.0/src/arrayfunc.rs b/utshell-0.5.0/src/arrayfunc.rs new file mode 100644 index 00000000..051eaf1d --- /dev/null +++ b/utshell-0.5.0/src/arrayfunc.rs @@ -0,0 +1,1958 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::array::{ + array_create, array_dispose_element, array_flush, array_insert, array_keys_to_word_list, + array_reference, array_remove, array_to_assign, array_to_word_list, +}; +use crate::assoc::{ + assoc_dispose, assoc_insert, assoc_keys_to_word_list, assoc_reference, assoc_remove, + assoc_to_assign, assoc_to_word_list, +}; +use crate::builtins::common::sh_invalidid; +use crate::dispose_cmd::dispose_words; +use crate::error::err_badarraysub; +use crate::expr::evalexp; +use crate::general::legal_identifier; +use crate::make_cmd::{make_word, make_word_list}; +use crate::pathexp::glob_char_p; +use crate::sig::{jump_to_top_level, top_level_cleanup}; +use crate::src_common::*; +use crate::stringlib::substring; +use crate::subst::expand_assignment_string_to_string; +use crate::subst::{ + expand_arith_string, expand_words_no_vars, extract_array_assignment_list, quote_string, + skipsubscript, string_list_dollar_at, string_list_dollar_star, string_list_pos_params, +}; +use crate::variables::{ + dispose_variable, find_shell_variable, find_variable, find_variable_last_nameref, + find_variable_nameref_for_create, make_new_array_variable, make_new_assoc_variable, + make_variable_value, unbind_variable, +}; +use crate::y_tab::parse_string_to_word_list; + +#[inline] +fn mbrlen(mut __s: *const libc::c_char, mut __n: size_t, mut __ps: *mut mbstate_t) -> size_t { + unsafe { + return if !__ps.is_null() { + mbrtowc(0 as *mut wchar_t, __s, __n, __ps) + } else { + __mbrlen(__s, __n, 0 as *mut mbstate_t) + }; + } +} +#[inline] +fn is_basic(mut c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} +#[no_mangle] +pub fn convert_var_to_array(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut oldval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut array: *mut ARRAY = 0 as *mut ARRAY; + unsafe { + oldval = value_cell!(var); + array = array_create(); + if !oldval.is_null() { + array_insert(array, 0 as libc::c_int as arrayind_t, oldval); + } + FREE!(value_cell!(var)); + var_setarray!(var, array); + + /* these aren't valid anymore */ + (*var).dynamic_value = ::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + (*var).assign_func = ::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + + INVALIDATE_EXPORTSTR!(var); + + if exported_p!(var) != 0 { + array_needs_making += 1; + array_needs_making; + } + + VSETATTR!(var, att_array); + if !oldval.is_null() { + VUNSETATTR!(var, att_invisible); + } + + /* Make sure it's not marked as an associative array any more */ + VUNSETATTR!(var, att_assoc); + + /* Since namerefs can't be array variables, turn off nameref attribute */ + VUNSETATTR!(var, att_nameref); + } + return var; +} + +/* Convert a shell variable to an array variable. The original value is +saved as array[0]. */ +#[no_mangle] +pub fn convert_var_to_assoc(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut oldval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut hash: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + unsafe { + oldval = value_cell!(var); + hash = assoc_create!(0); + if !oldval.is_null() { + assoc_insert( + hash, + savestring!(b"0\0" as *const u8 as *const libc::c_char), + oldval, + ); + } + + FREE!(value_cell!(var)); + var_setassoc!(var, hash); + + /* these aren't valid anymore */ + (*var).dynamic_value = ::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + (*var).assign_func = ::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + + INVALIDATE_EXPORTSTR!(var); + + if exported_p!(var) != 0 { + array_needs_making += 1; + array_needs_making; + } + + VSETATTR!(var, att_assoc); + if !oldval.is_null() { + VUNSETATTR!(var, att_invisible); + } + + /* Make sure it's not marked as an indexed array any more */ + VUNSETATTR!(var, att_array); + + /* Since namerefs can't be array variables, turn off nameref attribute */ + VUNSETATTR!(var, att_nameref); + } + return var; +} + +#[no_mangle] +pub fn make_array_variable_value( + mut entry: *mut SHELL_VAR, + mut ind: arrayind_t, + mut key: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut dentry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut newval: *mut libc::c_char = 0 as *mut libc::c_char; + + /* If we're appending, we need the old value of the array reference, so + fake out make_variable_value with a dummy SHELL_VAR */ + unsafe { + if flags & ASS_APPEND as libc::c_int != 0 { + dentry = libc::malloc(::core::mem::size_of::() as libc::c_ulong as usize) + as *mut SHELL_VAR; + (*dentry).name = savestring!((*entry).name); + if assoc_p!(entry) != 0 { + newval = assoc_reference(assoc_cell!(entry), key); + } else { + newval = array_reference(array_cell!(entry), ind); + } + if !newval.is_null() { + (*dentry).value = savestring!(newval); + } else { + (*dentry).value = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *((*dentry).value).offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + (*dentry).exportstr = 0 as *mut libc::c_char; + (*dentry).attributes = (*entry).attributes + & !(att_array as libc::c_int + | att_assoc as libc::c_int + | att_exported as libc::c_int); + /* Leave the rest of the members uninitialized; the code doesn't look + at them. */ + newval = make_variable_value(dentry, value, flags); + dispose_variable(dentry); + } else { + newval = make_variable_value(entry, value, flags); + } + } + return newval; +} + +/* Assign HASH[KEY]=VALUE according to FLAGS. ENTRY is an associative array +variable; HASH is the hash table to assign into. HASH may or may not be +the hash table associated with ENTRY; if it's not, the caller takes care +of it. +XXX - make sure that any dynamic associative array variables recreate the +hash table on each assignment. BASH_CMDS and BASH_ALIASES already do this */ +fn bind_assoc_var_internal( + mut entry: *mut SHELL_VAR, + mut hash: *mut HASH_TABLE, + mut key: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut newval: *mut libc::c_char = 0 as *mut libc::c_char; + + /* Use the existing array contents to expand the value */ + newval = make_array_variable_value(entry, 0 as libc::c_int as arrayind_t, key, value, flags); + unsafe { + if ((*entry).assign_func).is_some() { + (Some(((*entry).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + entry, + newval, + 0 as libc::c_int as arrayind_t, + key, + ); + } else { + assoc_insert(hash, key, newval); + } + + FREE!(newval); + + VUNSETATTR!(entry, att_invisible); /* no longer invisible */ + } + /* check mark_modified_variables if we ever want to export array vars */ + return entry; +} + +/* Perform ENTRY[IND]=VALUE or ENTRY[KEY]=VALUE. This is not called for every +assignment to an associative array; see assign_compound_array_list below. */ +fn bind_array_var_internal( + mut entry: *mut SHELL_VAR, + mut ind: arrayind_t, + mut key: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut newval: *mut libc::c_char = 0 as *mut libc::c_char; + + newval = make_array_variable_value(entry, ind, key, value, flags); + unsafe { + if ((*entry).assign_func).is_some() { + (Some(((*entry).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")(entry, newval, ind, key); + } else if assoc_p!(entry) != 0 { + assoc_insert(assoc_cell!(entry), key, newval); + } else { + array_insert(array_cell!(entry), ind, newval); + } + FREE!(newval); + + VUNSETATTR!(entry, att_invisible); /* no longer invisible */ + } + /* check mark_modified_variables if we ever want to export array vars */ + return entry; +} + +/* Perform an array assignment name[ind]=value. If NAME already exists and +is not an array, and IND is 0, perform name=value instead. If NAME exists +and is not an array, and IND is not 0, convert it into an array with the +existing value as name[0]. + +If NAME does not exist, just create an array variable, no matter what +IND's value may be. */ +#[no_mangle] +pub fn bind_array_variable( + mut name: *mut libc::c_char, + mut ind: arrayind_t, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + entry = find_shell_variable(name); + + if entry.is_null() { + /* Is NAME a nameref variable that points to an unset variable? */ + entry = find_variable_nameref_for_create(name, 0 as libc::c_int); + if entry == INVALID_NAMEREF_VALUE!() { + return 0 as *mut SHELL_VAR; + } + if !entry.is_null() && nameref_p!(entry) != 0 { + entry = make_new_array_variable(nameref_cell!(entry)); + } + } + if entry.is_null() { + entry = make_new_array_variable(name); + } else if readonly_p!(entry) != 0 && flags & ASS_FORCE as libc::c_int == 0 as libc::c_int + || noassign_p!(entry) != 0 + { + if readonly_p!(entry) != 0 { + err_readonly(name); + } + return entry; + } else if array_p!(entry) == 0 as libc::c_int { + entry = convert_var_to_array(entry); + } + } + /* ENTRY is an array variable, and ARRAY points to the value. */ + return bind_array_var_internal(entry, ind, 0 as *mut libc::c_char, value, flags); +} + +#[no_mangle] +pub fn bind_array_element( + mut entry: *mut SHELL_VAR, + mut ind: arrayind_t, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + return bind_array_var_internal(entry, ind, 0 as *mut libc::c_char, value, flags); +} + +#[no_mangle] +pub fn bind_assoc_variable( + mut entry: *mut SHELL_VAR, + mut name: *mut libc::c_char, + mut key: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + unsafe { + if readonly_p!(entry) != 0 && flags & ASS_FORCE as libc::c_int == 0 as libc::c_int + || noassign_p!(entry) != 0 + { + if readonly_p!(entry) != 0 { + err_readonly(name); + } + return entry; + } + + return bind_assoc_var_internal(entry, assoc_cell!(entry), key, value, flags); + } +} + +/* Parse NAME, a lhs of an assignment statement of the form v[s], and +assign VALUE to that array element by calling bind_array_variable(). +Flags are ASS_ assignment flags */ +#[no_mangle] +pub fn assign_array_element( + mut name: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut sub: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sublen: libc::c_int = 0; + let mut isassoc: libc::c_int = 0; + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + vname = array_variable_name( + name, + (flags & ASS_NOEXPAND as libc::c_int != 0 as libc::c_int) as libc::c_int, + &mut sub, + &mut sublen, + ); + + if vname.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + + entry = find_variable(vname); + unsafe { + isassoc = (!entry.is_null() && assoc_p!(entry) != 0) as libc::c_int; + + if (isassoc == 0 as libc::c_int || flags & ASS_NOEXPAND as libc::c_int == 0 as libc::c_int) + && (ALL_ELEMENT_SUB!(sub.offset(0 as libc::c_int as isize) as libc::c_int) + && *sub.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32) + || sublen <= 1 as libc::c_int + { + libc::free(vname as *mut libc::c_void); + err_badarraysub(name); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + + entry = assign_array_element_internal(entry, name, vname, sub, sublen, value, flags); + + libc::free(vname as *mut libc::c_void); + } + return entry; +} + +fn assign_array_element_internal( + mut entry: *mut SHELL_VAR, + mut name: *mut libc::c_char, /* only used for error messages */ + mut vname: *mut libc::c_char, + mut sub: *mut libc::c_char, + mut sublen: libc::c_int, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut akey: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ind: arrayind_t = 0; + unsafe { + if !entry.is_null() && assoc_p!(entry) as libc::c_int != 0 { + *sub.offset((sublen - 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + if flags & ASS_NOEXPAND as libc::c_int == 0 as libc::c_int { + akey = expand_assignment_string_to_string(sub, 0 as libc::c_int); + } else { + akey = savestring!(sub); + } + *sub.offset((sublen - 1 as libc::c_int) as isize) = ']' as i32 as libc::c_char; + if akey.is_null() || *akey as libc::c_int == 0 as libc::c_int { + err_badarraysub(name); + FREE!(akey); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + entry = bind_assoc_variable(entry, vname, akey, value, flags); + } else { + ind = array_expand_index(entry, sub, sublen, 0 as libc::c_int); + /* negative subscripts to indexed arrays count back from end */ + if !entry.is_null() && ind < 0 as libc::c_int as libc::c_long { + ind = (if array_p!(entry) != 0 { + array_max_index!(array_cell!(entry)) + } else { + 0 as libc::c_int as libc::c_long + }) + 1 as libc::c_int as libc::c_long + + ind; + } + + if ind < 0 as libc::c_int as libc::c_long { + err_badarraysub(name); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + entry = bind_array_variable(vname, ind, value, flags); + } + } + return entry; +} + +/* Find the array variable corresponding to NAME. If there is no variable, +create a new array variable. If the variable exists but is not an array, +convert it to an indexed array. If FLAGS&1 is non-zero, an existing +variable is checked for the readonly or noassign attribute in preparation +for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we +create an associative array. */ +#[no_mangle] +pub fn find_or_make_array_variable( + mut name: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + var = find_variable(name); + unsafe { + if var.is_null() { + /* See if we have a nameref pointing to a variable that hasn't been + created yet. */ + var = find_variable_last_nameref(name, 1 as libc::c_int); + if !var.is_null() && nameref_p!(var) != 0 && invisible_p!(var) != 0 { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"%s: removing nameref attribute\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + VUNSETATTR!(var, att_nameref); + } + if !var.is_null() && nameref_p!(var) != 0 { + if valid_nameref_value(nameref_cell!(var), 2 as libc::c_int) == 0 as libc::c_int { + sh_invalidid(nameref_cell!(var)); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + var = if flags & 2 as libc::c_int != 0 { + make_new_assoc_variable(nameref_cell!(var)) + } else { + make_new_array_variable(nameref_cell!(var)) + }; + } + } + + if var.is_null() { + var = if flags & 2 as libc::c_int != 0 { + make_new_assoc_variable(name) + } else { + make_new_array_variable(name) + }; + } else if flags & 1 as libc::c_int != 0 && (readonly_p!(var) != 0 || noassign_p!(var) != 0) + { + if readonly_p!(var) != 0 { + err_readonly(name); + } + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } else if flags & 2 as libc::c_int != 0 && array_p!(var) != 0 { + set_exit_status(EXECUTION_FAILURE as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot convert indexed to associative array\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } else if array_p!(var) == 0 as libc::c_int && assoc_p!(var) == 0 as libc::c_int { + var = convert_var_to_array(var); + } + } + return var; +} + +/* Perform a compound assignment statement for array NAME, where VALUE is +the text between the parens: NAME=( VALUE ) */ +#[no_mangle] +pub fn assign_array_from_string( + mut name: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut vflags: libc::c_int = 0; + + vflags = 1 as libc::c_int; + if flags & ASS_MKASSOC as libc::c_int != 0 { + vflags |= 2 as libc::c_int; + } + + var = find_or_make_array_variable(name, vflags); + if var.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + + return assign_array_var_from_string(var, value, flags); +} + +/* Sequentially assign the indices of indexed array variable VAR from the +words in LIST. */ +#[no_mangle] +pub fn assign_array_var_from_word_list( + mut var: *mut SHELL_VAR, + mut list: *mut WORD_LIST, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut i: arrayind_t = 0; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut a: *mut ARRAY = 0 as *mut ARRAY; + unsafe { + a = array_cell!(var); + i = if flags & ASS_APPEND as libc::c_int != 0 { + array_max_index!(a) + 1 as libc::c_int as libc::c_long + } else { + 0 as libc::c_int as libc::c_long + }; + + l = list; + while !l.is_null() { + bind_array_var_internal( + var, + i, + 0 as *mut libc::c_char, + (*(*l).word).word, + flags & !(ASS_APPEND as libc::c_int), + ); + l = (*l).next; + i += 1; + i; + } + + VUNSETATTR!(var, att_invisible); /* no longer invisible */ + } + return var; +} + +#[no_mangle] +pub fn expand_compound_array_assignment( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut WORD_LIST { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut nlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ni: libc::c_int = 0; + + /* This condition is true when invoked from the declare builtin with a + command like + declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")' */ + if unsafe { *value as libc::c_int == '(' as i32 } { + ni = 1 as libc::c_int; + val = extract_array_assignment_list(value, &mut ni); + if val.is_null() { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + } else { + val = value; + } + + /* Expand the value string into a list of words, performing all the + shell expansions including pathname generation and word splitting. */ + /* First we split the string on whitespace, using the shell parser + (ksh93 seems to do this). */ + list = parse_string_to_word_list( + val, + 1 as libc::c_int, + b"array assign\0" as *const u8 as *const libc::c_char, + ); + + /* Note that we defer expansion of the assignment statements for associative + arrays here, so we don't have to scan the subscript and find the ending + bracket twice. See the caller below. */ + unsafe { + if !var.is_null() && assoc_p!(var) != 0 { + if val != value { + libc::free(val as *mut libc::c_void); + } + return list; + } + } + /* If we're using [subscript]=value, we need to quote each [ and ] to + prevent unwanted filename expansion. This doesn't need to be done + for associative array expansion, since that uses a different expansion + function (see assign_compound_array_list below). */ + if !list.is_null() { + quote_array_assignment_chars(list); + } + + /* Now that we've split it, perform the shell expansions on each + word in the list. */ + nlist = if !list.is_null() { + expand_words_no_vars(list) + } else { + 0 as *mut libc::c_void as *mut WORD_LIST + }; + + dispose_words(list); + + if val != value { + unsafe { + libc::free(val as *mut libc::c_void); + } + } + + return nlist; +} + +fn assign_assoc_from_kvlist( + mut var: *mut SHELL_VAR, + mut nlist: *mut WORD_LIST, + mut h: *mut HASH_TABLE, + mut flags: libc::c_int, +) { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut akey: *mut libc::c_char = 0 as *mut libc::c_char; + let mut aval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut k: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + let mut free_aval: libc::c_int = 0; + + list = nlist; + while !list.is_null() { + unsafe { + free_aval = 0 as libc::c_int; + + k = (*(*list).word).word; + v = if !((*list).next).is_null() { + (*(*(*list).next).word).word + } else { + 0 as *mut libc::c_char + }; + + if !((*list).next).is_null() { + list = (*list).next; + } + + akey = expand_assignment_string_to_string(k, 0 as libc::c_int); + aval = expand_assignment_string_to_string(v, 0 as libc::c_int); + + if akey.is_null() || *akey as libc::c_int == 0 as libc::c_int { + err_badarraysub(k); + FREE!(akey); + } else { + if aval.is_null() { + aval = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *aval.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; /* like do_assignment_internal */ + free_aval = 1 as libc::c_int; + } + + bind_assoc_var_internal(var, h, akey, aval, flags); + if free_aval != 0 { + libc::free(aval as *mut libc::c_void); + } + } + list = (*list).next; + } + } +} + +/* Return non-zero if L appears to be a key-value pair associative array +compound assignment. */ +#[no_mangle] +pub fn kvpair_assignment_p(mut l: *mut WORD_LIST) -> libc::c_int { + unsafe { + return (!l.is_null() + && (*(*l).word).flags & W_ASSIGNMENT == 0 as libc::c_int + && *((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int != '[' as i32) + as libc::c_int; + } +} + +#[no_mangle] +pub fn expand_and_quote_kvpair_word(mut w: *mut libc::c_char) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + + t = if !w.is_null() { + expand_assignment_string_to_string(w, 0 as libc::c_int) + } else { + 0 as *mut libc::c_char + }; + unsafe { + r = sh_single_quote(if !t.is_null() { + t as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }); + libc::free(t as *mut libc::c_void); + } + return r; +} + +/* Callers ensure that VAR is not NULL. Associative array assignments have not +been expanded when this is called, or have been expanded once and single- +quoted, so we don't have to scan through an unquoted expanded subscript to +find the ending bracket; indexed array assignments have been expanded and +possibly single-quoted to prevent further expansion. + +If this is an associative array, we perform the assignments into NHASH and +set NHASH to be the value of VAR after processing the assignments in NLIST */ +#[no_mangle] +pub fn assign_compound_array_list( + mut var: *mut SHELL_VAR, + mut nlist: *mut WORD_LIST, + mut flags: libc::c_int, +) { + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut nhash: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut savecmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: libc::c_int = 0; + let mut iflags: libc::c_int = 0; + let mut free_val: libc::c_int = 0; + let mut ind: arrayind_t = 0; + let mut last_ind: arrayind_t = 0; + let mut akey: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + a = if !var.is_null() && array_p!(var) != 0 { + array_cell!(var) + } else { + 0 as *mut ARRAY + }; + h = if !var.is_null() && assoc_p!(var) != 0 { + assoc_cell!(var) + } else { + 0 as *mut HASH_TABLE + }; + nhash = h; + + akey = 0 as *mut libc::c_char; + ind = 0 as libc::c_int as arrayind_t; + + /* Now that we are ready to assign values to the array, kill the existing + value. */ + if flags & ASS_APPEND as libc::c_int == 0 as libc::c_int { + if !a.is_null() && array_p!(var) != 0 { + array_flush(a); + } else if !h.is_null() && assoc_p!(var) != 0 { + nhash = assoc_create!((*h).nbuckets); + } + } + + last_ind = if !a.is_null() && flags & ASS_APPEND as libc::c_int != 0 { + array_max_index!(a) + 1 as libc::c_int as libc::c_long + } else { + 0 as libc::c_int as libc::c_long + }; + + if assoc_p!(var) != 0 && kvpair_assignment_p(nlist) != 0 { + iflags = flags & !(ASS_APPEND as libc::c_int); + assign_assoc_from_kvlist(var, nlist, nhash, iflags); + if !nhash.is_null() && nhash != h { + h = assoc_cell!(var); + var_setassoc!(var, nhash); + assoc_dispose(h); + } + return; + } + + list = nlist; + loop { + if list.is_null() { + break; + } + /* Don't allow var+=(values) to make assignments in VALUES append to + existing values by default. */ + iflags = flags & !(ASS_APPEND as libc::c_int); + w = (*(*list).word).word; + /* We have a word of the form [ind]=value */ + if (*(*list).word).flags & W_ASSIGNMENT != 0 + && *w.offset(0 as libc::c_int as isize) as libc::c_int == '[' as i32 + { + /* Don't have to handle embedded quotes specially any more, since + associative array subscripts have not been expanded yet (see + above). */ + len = skipsubscript(w, 0 as libc::c_int, 0 as libc::c_int); + + /* XXX - changes for `+=' */ + if *w.offset(len as isize) as libc::c_int != ']' as i32 + || *w.offset((len + 1 as libc::c_int) as isize) as libc::c_int != '=' as i32 + && (*w.offset((len + 1 as libc::c_int) as isize) as libc::c_int + != '+' as i32 + || *w.offset((len + 2 as libc::c_int) as isize) as libc::c_int + != '=' as i32) + { + if assoc_p!(var) != 0 { + err_badarraysub(w); + list = (*list).next; + continue; + } + nval = make_variable_value(var, w, flags); + if ((*var).assign_func).is_some() { + (Some(((*var).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + var, + nval, + last_ind, + 0 as *mut libc::c_char, + ); + } else { + array_insert(a, last_ind, nval); + } + FREE!(nval); + last_ind += 1; + last_ind; + list = (*list).next; + continue; + } + + if len == 1 as libc::c_int { + err_badarraysub(w); + list = (*list).next; + continue; + } + + if ALL_ELEMENT_SUB!(*w.offset(1 as libc::c_int as isize) as libc::c_int) + && len == 2 as libc::c_int + { + set_exit_status(EXECUTION_FAILURE as libc::c_int); + if assoc_p!(var) != 0 { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid associative array key\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + w, + ); + } else { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot assign to non-numeric index\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + w, + ); + } + list = (*list).next; + continue; + } + + if array_p!(var) != 0 { + ind = array_expand_index( + var, + w.offset(1 as libc::c_int as isize), + len, + 0 as libc::c_int, + ); + /* negative subscripts to indexed arrays count back from end */ + if ind < 0 as libc::c_int as libc::c_long { + ind = array_max_index!(array_cell!(var)) + + 1 as libc::c_int as libc::c_long + + ind; + } + if ind < 0 as libc::c_int as libc::c_long { + err_badarraysub(w); + list = (*list).next; + continue; + } + + last_ind = ind; + } else if assoc_p!(var) != 0 { + /* This is not performed above, see expand_compound_array_assignment */ + *w.offset(len as isize) = '\0' as i32 as libc::c_char; /*[*/ + akey = expand_assignment_string_to_string( + w.offset(1 as libc::c_int as isize), + 0 as libc::c_int, + ); + *w.offset(len as isize) = ']' as i32 as libc::c_char; + /* And we need to expand the value also, see below */ + if akey.is_null() || *akey as libc::c_int == 0 as libc::c_int { + err_badarraysub(w); + FREE!(akey); + list = (*list).next; + continue; + } + } + + /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */ + if *w.offset((len + 1 as libc::c_int) as isize) as libc::c_int == '+' as i32 + && *w.offset((len + 2 as libc::c_int) as isize) as libc::c_int == '=' as i32 + { + iflags |= ASS_APPEND as libc::c_int; + val = w.offset(len as isize).offset(3 as libc::c_int as isize); + } else { + val = w.offset(len as isize).offset(2 as libc::c_int as isize); + } + } else if assoc_p!(var) != 0 { + set_exit_status(EXECUTION_FAILURE as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: %s: must use subscript when assigning associative array\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + (*var).name, + w, + ); + list = (*list).next; + continue; + } else { + /* No [ind]=value, just a stray `=' */ + ind = last_ind; + val = w; + } + free_val = 0 as libc::c_int; + /* See above; we need to expand the value here */ + if assoc_p!(var) != 0 { + val = expand_assignment_string_to_string(val, 0 as libc::c_int); + if val.is_null() { + val = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *val.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + free_val = 1 as libc::c_int; + } + savecmd = this_command_name; + if integer_p!(var) != 0 { + this_command_name = 0 as *mut libc::c_void as *mut libc::c_char; + } + if assoc_p!(var) != 0 { + bind_assoc_var_internal(var, nhash, akey, val, iflags); + } else { + bind_array_var_internal(var, ind, akey, val, iflags); + } + last_ind += 1; + last_ind; + this_command_name = savecmd; + + if free_val != 0 { + libc::free(val as *mut libc::c_void); + } + + list = (*list).next; + } + + if assoc_p!(var) != 0 && !nhash.is_null() && nhash != h { + h = assoc_cell!(var); + var_setassoc!(var, nhash); + assoc_dispose(h); + } + } +} + +/* Perform a compound array assignment: VAR->name=( VALUE ). The +VALUE has already had the parentheses stripped. */ +#[no_mangle] +pub fn assign_array_var_from_string( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut nlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + + if value.is_null() { + return var; + } + + nlist = expand_compound_array_assignment(var, value, flags); + assign_compound_array_list(var, nlist, flags); + + if !nlist.is_null() { + dispose_words(nlist); + } + + if !var.is_null() { + unsafe { + VUNSETATTR!(var, att_invisible); + } /* no longer invisible */ + } + + return var; +} + +/* Quote globbing chars and characters in $IFS before the `=' in an assignment +statement (usually a compound array assignment) to protect them from +unwanted filename expansion or word splitting. */ +fn quote_assign(mut string: *const libc::c_char) -> *mut libc::c_char { + let mut slen: size_t = 0; + let mut saw_eq: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut subs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *const libc::c_char = 0 as *const libc::c_char; + let mut send: *const libc::c_char = 0 as *const libc::c_char; + let mut ss: libc::c_int = 0; + let mut se: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + ::core::mem::size_of::() as libc::c_ulong as usize, + ); + + slen = libc::strlen(string) as u64; + send = string.offset(slen as isize); + + temp = libc::malloc( + slen.wrapping_mul(2 as libc::c_int as libc::c_ulong) + .wrapping_add(1 as libc::c_int as libc::c_ulong) as usize, + ) as *mut libc::c_char; + t = temp; + saw_eq = 0 as libc::c_int; + s = string; + while *s != 0 { + if *s as libc::c_int == '=' as i32 { + saw_eq = 1 as libc::c_int; + } + /* looks like a subscript */ + if saw_eq == 0 as libc::c_int && *s as libc::c_int == '[' as i32 { + ss = s.offset_from(string) as libc::c_long as libc::c_int; + se = skipsubscript(string, ss, 0 as libc::c_int); + subs = substring(s, ss, se); + let fresh0 = t; + t = t.offset(1); + *fresh0 = '\\' as i32 as libc::c_char; + libc::strcpy(t, subs); + t = t.offset((se - ss) as isize); + let fresh1 = t; + t = t.offset(1); + *fresh1 = '\\' as i32 as libc::c_char; + let fresh2 = t; + t = t.offset(1); + *fresh2 = ']' as i32 as libc::c_char; + s = s.offset((se + 1 as libc::c_int) as isize); + libc::free(subs as *mut libc::c_void); + } + if saw_eq == 0 as libc::c_int && (glob_char_p(s) != 0 || isifs!(*s) != 0 as libc::c_int) + { + let fresh3 = t; + t = t.offset(1); + *fresh3 = '\\' as i32 as libc::c_char; + } + + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*s); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = (*s as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen(s, send.offset_from(s) as libc::c_long as size_t, &mut state); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh4 = s; + s = s.offset(1); + let fresh5 = t; + t = t.offset(1); + *fresh5 = *fresh4; + _k += 1; + _k; + } + } else { + let fresh6 = s; + s = s.offset(1); + let fresh7 = t; + t = t.offset(1); + *fresh7 = *fresh6; + } + } + *t = '\0' as i32 as libc::c_char; + } + return temp; +} + +/* Take a word W of the form [IND]=VALUE and transform it to ['IND']='VALUE' +to prevent further expansion. This is called for compound assignments to +indexed arrays. W has already undergone word expansions. If W has no [IND]=, +just single-quote and return it. */ +fn quote_compound_array_word( + mut w: *mut libc::c_char, + mut type_0: libc::c_int, +) -> *mut libc::c_char { + let mut nword: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sub: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ind: libc::c_int = 0; + let mut wlen: libc::c_int = 0; + let mut i: libc::c_int = 0; + unsafe { + //LBRACK RBRACK + if *w.offset(0 as libc::c_int as isize) as libc::c_int != LBRACK!() as i32 { + return sh_single_quote(w); + } + ind = skipsubscript(w, 0 as libc::c_int, 0 as libc::c_int); + if *w.offset(ind as isize) as libc::c_int != RBRACK!() as i32 { + return sh_single_quote(w); + } + + wlen = libc::strlen(w) as libc::c_int; + *w.offset(ind as isize) = '\0' as i32 as libc::c_char; + sub = sh_single_quote(w.offset(1 as libc::c_int as isize)); + *w.offset(ind as isize) = RBRACK!() as i32 as libc::c_char; + + nword = libc::malloc((wlen * 4 as libc::c_int + 5 as libc::c_int) as usize) + as *mut libc::c_char; /* wlen*4 is max single quoted length */ + *nword.offset(0 as libc::c_int as isize) = LBRACK!() as i32 as libc::c_char; + i = STRLEN!(sub); + libc::memcpy( + nword.offset(1 as libc::c_int as isize) as *mut libc::c_void, + sub as *const libc::c_void, + i as libc::c_ulong as usize, + ); + + i += 1; + i; /* accommodate the opening LBRACK */ + let fresh8 = ind; + ind = ind + 1; + let fresh9 = i; + i = i + 1; + *nword.offset(fresh9 as isize) = *w.offset(fresh8 as isize); /* RBRACK */ + if *w.offset(ind as isize) as libc::c_int == '+' as i32 { + let fresh10 = ind; + ind = ind + 1; + let fresh11 = i; + i = i + 1; + *nword.offset(fresh11 as isize) = *w.offset(fresh10 as isize); + } + let fresh12 = ind; + ind = ind + 1; + let fresh13 = i; + i = i + 1; + *nword.offset(fresh13 as isize) = *w.offset(fresh12 as isize); + value = sh_single_quote(w.offset(ind as isize)); + libc::strcpy(nword.offset(i as isize), value); + } + return nword; +} + +/* Expand the key and value in W, which is of the form [KEY]=VALUE, and +reconstruct W with the expanded and single-quoted version: +['expanded-key']='expanded-value'. If there is no [KEY]=, single-quote the +word and return it. Very similar to previous function, but does not assume +W has already been expanded, and expands the KEY and VALUE separately. +Used for compound assignments to associative arrays that are arguments to +declaration builtins (declare -A a=( list )). */ +#[no_mangle] +pub fn expand_and_quote_assoc_word( + mut w: *mut libc::c_char, + mut type_0: libc::c_int, +) -> *mut libc::c_char { + let mut nword: *mut libc::c_char = 0 as *mut libc::c_char; + let mut key: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ind: libc::c_int = 0; + let mut wlen: libc::c_int = 0; + let mut i: libc::c_int = 0; + unsafe { + if *w.offset(0 as libc::c_int as isize) as libc::c_int != LBRACK!() as i32 { + return sh_single_quote(w); + } + ind = skipsubscript(w, 0 as libc::c_int, 0 as libc::c_int); + if *w.offset(ind as isize) as libc::c_int != RBRACK!() as i32 { + return sh_single_quote(w); + } + + *w.offset(ind as isize) = '\0' as i32 as libc::c_char; + t = expand_assignment_string_to_string( + w.offset(1 as libc::c_int as isize), + 0 as libc::c_int, + ); + *w.offset(ind as isize) = RBRACK!() as i32 as libc::c_char; + + key = sh_single_quote(if !t.is_null() { + t as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }); + libc::free(t as *mut libc::c_void); + + wlen = STRLEN!(key); + nword = libc::malloc((wlen + 5 as libc::c_int) as usize) as *mut libc::c_char; + *nword.offset(0 as libc::c_int as isize) = LBRACK!() as i32 as libc::c_char; + libc::memcpy( + nword.offset(1 as libc::c_int as isize) as *mut libc::c_void, + key as *const libc::c_void, + wlen as libc::c_ulong as usize, + ); + + i = wlen + 1 as libc::c_int; /* accommodate the opening LBRACK */ + + let fresh14 = ind; /* RBRACK */ + ind = ind + 1; + let fresh15 = i; + i = i + 1; + *nword.offset(fresh15 as isize) = *w.offset(fresh14 as isize); + if *w.offset(ind as isize) as libc::c_int == '+' as i32 { + let fresh16 = ind; + ind = ind + 1; + let fresh17 = i; + i = i + 1; + *nword.offset(fresh17 as isize) = *w.offset(fresh16 as isize); + } + let fresh18 = ind; + ind = ind + 1; + let fresh19 = i; + i = i + 1; + *nword.offset(fresh19 as isize) = *w.offset(fresh18 as isize); + + t = expand_assignment_string_to_string(w.offset(ind as isize), 0 as libc::c_int); + + value = sh_single_quote(if !t.is_null() { + t as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }); + libc::free(t as *mut libc::c_void); + nword = libc::realloc( + nword as *mut libc::c_void, + ((wlen + 5 as libc::c_int) as libc::c_ulong) + .wrapping_add(STRLEN!(value) as libc::c_ulong) as usize, + ) as *mut libc::c_char; + libc::strcpy(nword.offset(i as isize), value); + + libc::free(key as *mut libc::c_void); + libc::free(value as *mut libc::c_void); + } + return nword; +} + +/* For each word in a compound array assignment, if the word looks like +[ind]=value, single-quote ind and value, but leave the brackets and +the = sign (and any `+') alone. If it's not an assignment, just single- +quote the word. This is used for indexed arrays. */ +#[no_mangle] +pub fn quote_compound_array_list(mut list: *mut WORD_LIST, mut type_0: libc::c_int) { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + + l = list; + unsafe { + while !l.is_null() { + if !(((*l).word).is_null() || ((*(*l).word).word).is_null()) { + if (*(*l).word).flags & W_ASSIGNMENT == 0 as libc::c_int { + t = sh_single_quote((*(*l).word).word); + } else { + t = quote_compound_array_word((*(*l).word).word, type_0); + } + libc::free((*(*l).word).word as *mut libc::c_void); + (*(*l).word).word = t; + } + l = (*l).next; + } + } +} + +/* For each word in a compound array assignment, if the word looks like +[ind]=value, quote globbing chars and characters in $IFS before the `='. */ +fn quote_array_assignment_chars(mut list: *mut WORD_LIST) { + let mut nword: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + + l = list; + unsafe { + while !l.is_null() { + if ((*l).word).is_null() + || ((*(*l).word).word).is_null() + || *((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == '\0' as i32 + { + l = (*l).next; + continue; /* should not happen, but just in case... */ + } + /* Don't bother if it hasn't been recognized as an assignment or + doesn't look like [ind]=value */ + if (*(*l).word).flags & W_ASSIGNMENT == 0 as libc::c_int { + l = (*l).next; + continue; + } + /* ] */ + if *((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int != '[' as i32 + || (mbschr((*(*l).word).word, '=' as i32)).is_null() + { + l = (*l).next; + continue; + } + nword = quote_assign((*(*l).word).word); + libc::free((*(*l).word).word as *mut libc::c_void); + (*(*l).word).word = nword; + (*(*l).word).flags |= W_NOGLOB as libc::c_int; /* XXX - W_NOSPLIT also? */ + + l = (*l).next; + } + } +} + +/* skipsubscript moved to subst.c to use private functions. 2009/02/24. */ + +/* This function is called with SUB pointing to just after the beginning +`[' of an array subscript and removes the array element to which SUB +expands from array VAR. A subscript of `*' or `@' unsets the array. */ +/* If FLAGS&1 we don't expand the subscript; we just use it as-is. */ +#[no_mangle] +pub fn unbind_array_element( + mut var: *mut SHELL_VAR, + mut sub: *mut libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + let mut len: libc::c_int = 0; + let mut ind: arrayind_t = 0; + let mut akey: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + unsafe { + len = skipsubscript( + sub, + 0 as libc::c_int, + (flags & 1 as libc::c_int != 0 || !var.is_null() && assoc_p!(var) != 0) as libc::c_int, + ); /* XXX */ + + if *sub.offset(len as isize) as libc::c_int != ']' as i32 || len == 0 as libc::c_int { + builtin_error( + b"%s[%s: %s\0" as *const u8 as *const libc::c_char, + (*var).name, + sub, + dcgettext( + 0 as *const libc::c_char, + bash_badsub_errmsg, + 5 as libc::c_int, + ), + ); + return -(1 as libc::c_int); + } + *sub.offset(len as isize) = '\0' as i32 as libc::c_char; + + if ALL_ELEMENT_SUB!(*sub.offset(0 as libc::c_int as isize) as libc::c_int) + && *sub.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + if array_p!(var) != 0 || assoc_p!(var) != 0 { + unbind_variable((*var).name); /* XXX -- {array,assoc}_flush ? */ + return 0 as libc::c_int; + } else { + return -(2 as libc::c_int); /* don't allow this to unset scalar variables */ + } + } + + if assoc_p!(var) != 0 { + akey = if flags & 1 as libc::c_int != 0 { + sub + } else { + expand_assignment_string_to_string(sub, 0 as libc::c_int) + }; + if akey.is_null() || *akey as libc::c_int == 0 as libc::c_int { + builtin_error( + b"[%s]: %s\0" as *const u8 as *const libc::c_char, + sub, + dcgettext( + 0 as *const libc::c_char, + bash_badsub_errmsg, + 5 as libc::c_int, + ), + ); + FREE!(akey); + return -(1 as libc::c_int); + } + + assoc_remove(assoc_cell!(var), akey); + if akey != sub { + libc::free(akey as *mut libc::c_void); + } + } else if array_p!(var) != 0 { + ind = array_expand_index(var, sub, len + 1 as libc::c_int, 0 as libc::c_int); + /* negative subscripts to indexed arrays count back from end */ + if ind < 0 as libc::c_int as libc::c_long { + ind = array_max_index!(array_cell!(var)) + 1 as libc::c_int as libc::c_long + ind; + } + if ind < 0 as libc::c_int as libc::c_long { + builtin_error( + b"[%s]: %s\0" as *const u8 as *const libc::c_char, + sub, + dcgettext( + 0 as *const libc::c_char, + bash_badsub_errmsg, + 5 as libc::c_int, + ), + ); + return -(1 as libc::c_int); + } + ae = array_remove((*var).value as *mut ARRAY, ind); + if !ae.is_null() { + array_dispose_element(ae); + } + } else { + /* array_p (var) == 0 && assoc_p (var) == 0 */ + akey = this_command_name; + ind = array_expand_index(var, sub, len + 1 as libc::c_int, 0 as libc::c_int); + this_command_name = akey; + if ind == 0 as libc::c_int as libc::c_long { + unbind_variable((*var).name); + return 0 as libc::c_int; + } else { + return -(2 as libc::c_int); /* any subscript other than 0 is invalid with scalar variables */ + } + } + } + return 0 as libc::c_int; +} + +/* Format and output an array assignment in compound form VAR=(VALUES), +suitable for re-use as input. */ +#[no_mangle] +pub fn print_array_assignment(mut var: *mut SHELL_VAR, mut quoted: libc::c_int) { + let mut vstr: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + vstr = array_to_assign(array_cell!(var), quoted); + + if vstr.is_null() { + libc::printf( + b"%s=%s\n\0" as *const u8 as *const libc::c_char, + (*var).name, + if quoted != 0 { + b"'()'\0" as *const u8 as *const libc::c_char + } else { + b"()\0" as *const u8 as *const libc::c_char + }, + ); + } else { + libc::printf( + b"%s=%s\n\0" as *const u8 as *const libc::c_char, + (*var).name, + vstr, + ); + libc::free(vstr as *mut libc::c_void); + }; + } +} + +/* Format and output an associative array assignment in compound form +VAR=(VALUES), suitable for re-use as input. */ +#[no_mangle] +pub fn print_assoc_assignment(mut var: *mut SHELL_VAR, mut quoted: libc::c_int) { + let mut vstr: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + vstr = assoc_to_assign(assoc_cell!(var), quoted); + + if vstr.is_null() { + libc::printf( + b"%s=%s\n\0" as *const u8 as *const libc::c_char, + (*var).name, + if quoted != 0 { + b"'()'\0" as *const u8 as *const libc::c_char + } else { + b"()\0" as *const u8 as *const libc::c_char + }, + ); + } else { + libc::printf( + b"%s=%s\n\0" as *const u8 as *const libc::c_char, + (*var).name, + vstr, + ); + libc::free(vstr as *mut libc::c_void); + }; + } +} + +/***********************************************************************/ +/* */ +/* Utility functions to manage arrays and their contents for expansion */ +/* */ +/***********************************************************************/ + +/* Return 1 if NAME is a properly-formed array reference v[sub]. */ + +/* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */ +#[no_mangle] +pub fn valid_array_reference(mut name: *const libc::c_char, mut flags: libc::c_int) -> libc::c_int { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut isassoc: libc::c_int = 0; + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + t = unsafe { mbschr(name, '[' as i32) }; /* ] */ + isassoc = 0 as libc::c_int; + if !t.is_null() { + unsafe { + *t = '\0' as i32 as libc::c_char; + r = legal_identifier(name); + + if flags & VA_NOEXPAND as libc::c_int != 0 { + /* Don't waste a lookup if we don't need one */ + entry = find_variable(name); + isassoc = (!entry.is_null() && assoc_p!(entry) != 0) as libc::c_int; + } + *t = '[' as i32 as libc::c_char; + if r == 0 as libc::c_int { + return 0 as libc::c_int; + } + + if isassoc != 0 + && flags & (VA_NOEXPAND as libc::c_int | VA_ONEWORD as libc::c_int) + == VA_NOEXPAND as libc::c_int | VA_ONEWORD as libc::c_int + { + len = (libc::strlen(t)).wrapping_sub(1 as libc::c_int as libc::c_ulong as usize) + as libc::c_int; + } else if isassoc != 0 { + len = skipsubscript(t, 0 as libc::c_int, flags & VA_NOEXPAND as libc::c_int); + /* VA_NOEXPAND must be 1 */ + } else { + /* Check for a properly-terminated non-null subscript. */ + len = skipsubscript(t, 0 as libc::c_int, 0 as libc::c_int); /* arithmetic expression */ + } + + if *t.offset(len as isize) as libc::c_int != ']' as i32 + || len == 1 as libc::c_int + || *t.offset((len + 1 as libc::c_int) as isize) as libc::c_int != '\0' as i32 + { + return 0 as libc::c_int; + } + /* This allows blank subscripts */ + return 1 as libc::c_int; + } + } + return 0 as libc::c_int; +} + +/* Expand the array index beginning at S and extending LEN characters. */ +#[no_mangle] +pub fn array_expand_index( + mut var: *mut SHELL_VAR, + mut s: *mut libc::c_char, + mut len: libc::c_int, + mut flags: libc::c_int, +) -> arrayind_t { + let mut exp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut savecmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut expok: libc::c_int = 0; + let mut val: arrayind_t = 0; + unsafe { + exp = libc::malloc(len as usize) as *mut libc::c_char; + libc::strncpy(exp, s, (len - 1 as libc::c_int) as libc::c_ulong as usize); + *exp.offset((len - 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + + t = expand_arith_string( + exp, + Q_DOUBLE_QUOTES as libc::c_int | Q_ARITH as libc::c_int | Q_ARRAYSUB as libc::c_int, + ); /* XXX - Q_ARRAYSUB for future use */ + savecmd = this_command_name; + this_command_name = 0 as *mut libc::c_void as *mut libc::c_char; + val = evalexp(t, EXP_EXPANDED as libc::c_int, &mut expok); /* XXX - was 0 but we expanded exp already */ + this_command_name = savecmd; + if t != exp { + libc::free(t as *mut libc::c_void); + } + libc::free(exp as *mut libc::c_void); + if expok == 0 as libc::c_int { + set_exit_status(EXECUTION_FAILURE as libc::c_int); + if no_longjmp_on_fatal_error != 0 { + return 0 as libc::c_int as arrayind_t; + } + top_level_cleanup(); + jump_to_top_level(DISCARD as libc::c_int); + } + } + return val; +} + +/* Return the name of the variable specified by S without any subscript. +If SUBP is non-null, return a pointer to the start of the subscript +in *SUBP. If LENP is non-null, the length of the subscript is returned +in *LENP. This returns newly-allocated memory. */ +#[no_mangle] +pub fn array_variable_name( + mut s: *const libc::c_char, + mut flags: libc::c_int, + mut subp: *mut *mut libc::c_char, + mut lenp: *mut libc::c_int, +) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ind: libc::c_int = 0; + let mut ni: libc::c_int = 0; + unsafe { + t = mbschr(s, '[' as i32); + if t.is_null() { + if !subp.is_null() { + *subp = t; + } + if !lenp.is_null() { + *lenp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut libc::c_char; + } + ind = t.offset_from(s) as libc::c_long as libc::c_int; + ni = skipsubscript(s, ind, flags); /* XXX - was 0 not flags */ + if ni <= ind + 1 as libc::c_int || *s.offset(ni as isize) as libc::c_int != ']' as i32 { + err_badarraysub(s); + if !subp.is_null() { + *subp = t; + } + if !lenp.is_null() { + *lenp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + *t = '\0' as i32 as libc::c_char; + ret = savestring!(s); + let fresh20 = t; + t = t.offset(1); + *fresh20 = '[' as i32 as libc::c_char; /* ] */ + + if !subp.is_null() { + *subp = t; + } + if !lenp.is_null() { + *lenp = ni - ind; + } + } + return ret; +} + +/* Return the variable specified by S without any subscript. If SUBP is +non-null, return a pointer to the start of the subscript in *SUBP. +If LENP is non-null, the length of the subscript is returned in *LENP. */ +#[no_mangle] +pub fn array_variable_part( + mut s: *const libc::c_char, + mut flags: libc::c_int, + mut subp: *mut *mut libc::c_char, + mut lenp: *mut libc::c_int, +) -> *mut SHELL_VAR { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + t = array_variable_name(s, flags, subp, lenp); + + if t.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + var = find_variable(t); /* XXX - handle namerefs here? */ + + libc::free(t as *mut libc::c_void); + return var; /* now return invisible variables; caller must handle */ + } +} + +/* Return a string containing the elements in the array and subscript +described by S. If the subscript is * or @, obeys quoting rules akin +to the expansion of $* and $@ including double quoting. If RTYPE +is non-null it gets 1 if the array reference is name[*], 2 if the +reference is name[@], and 0 otherwise. */ +fn array_value_internal( + mut s: *const libc::c_char, + mut quoted: libc::c_int, + mut flags: libc::c_int, + mut rtype: *mut libc::c_int, + mut indp: *mut arrayind_t, +) -> *mut libc::c_char { + let mut len: libc::c_int = 0; + let mut ind: arrayind_t = 0; + let mut akey: *mut libc::c_char = 0 as *mut libc::c_char; + let mut retval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + var = array_variable_part( + s, + if flags & 0x20 as libc::c_int != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }, + &mut t, + &mut len, + ); /* XXX */ + + /* Expand the index, even if the variable doesn't exist, in case side + effects are needed, like ${w[i++]} where w is unset. */ + if len == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut libc::c_char; /* error message already printed */ + } + + /* [ */ + akey = 0 as *mut libc::c_char; + unsafe { + if ALL_ELEMENT_SUB!(*t.offset(0 as libc::c_int as isize) as libc::c_int) + && *t.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + if !rtype.is_null() { + *rtype = if *t.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 { + 1 as libc::c_int + } else { + 2 as libc::c_int + }; + } + if flags & AV_ALLOWALL as libc::c_int == 0 as libc::c_int { + err_badarraysub(s); + return 0 as *mut libc::c_void as *mut libc::c_char; + } else if var.is_null() || value_cell!(var).is_null() { + /* XXX - check for invisible_p(var) ? */ + return 0 as *mut libc::c_void as *mut libc::c_char; + } else if invisible_p!(var) != 0 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } else if array_p!(var) == 0 as libc::c_int && assoc_p!(var) == 0 as libc::c_int { + l = make_word_list( + make_word(value_cell!(var)), + 0 as *mut libc::c_void as *mut WORD_LIST, + ); + } else if assoc_p!(var) != 0 { + l = assoc_to_word_list(assoc_cell!(var)); + if l.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + } else { + l = array_to_word_list(array_cell!(var)); + if l.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + } + + /* Caller of array_value takes care of inspecting rtype and duplicating + retval if rtype == 0, so this is not a memory leak */ + if *t.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + && quoted & (Q_HERE_DOCUMENT as libc::c_int | Q_DOUBLE_QUOTES as libc::c_int) != 0 + { + temp = string_list_dollar_star( + l, + quoted, + if flags & AV_ASSIGNRHS as libc::c_int != 0 { + PF_ASSIGNRHS as libc::c_int + } else { + 0 as libc::c_int + }, + ); + retval = quote_string(temp); + libc::free(temp as *mut libc::c_void); + } else { + /* ${name[@]} or unquoted ${name[*]} */ + retval = string_list_dollar_at( + l, + quoted, + if flags & AV_ASSIGNRHS as libc::c_int != 0 { + PF_ASSIGNRHS as libc::c_int + } else { + 0 as libc::c_int + }, + ); + } + + dispose_words(l); + } else { + if !rtype.is_null() { + *rtype = 0 as libc::c_int; + } + if var.is_null() || array_p!(var) != 0 || assoc_p!(var) == 0 as libc::c_int { + if flags & AV_USEIND as libc::c_int == 0 as libc::c_int || indp.is_null() { + ind = array_expand_index(var, t, len, flags); + if ind < 0 as libc::c_int as libc::c_long { + /* negative subscripts to indexed arrays count back from end */ + if !var.is_null() && array_p!(var) != 0 { + ind = array_max_index!(array_cell!(var)) + + 1 as libc::c_int as libc::c_long + + ind; + } + if ind < 0 as libc::c_int as libc::c_long { + INDEX_ERROR!(var, t, s); + } + } + if !indp.is_null() { + *indp = ind; + } + } else if !indp.is_null() { + ind = *indp; + } + } else if assoc_p!(var) != 0 { + *t.offset((len - 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + if flags & AV_NOEXPAND as libc::c_int == 0 as libc::c_int { + akey = expand_assignment_string_to_string(t, 0 as libc::c_int); + /* [ */ + } else { + akey = savestring!(t); + } + *t.offset((len - 1 as libc::c_int) as isize) = ']' as i32 as libc::c_char; + if akey.is_null() || *akey as libc::c_int == 0 as libc::c_int { + FREE!(akey); + INDEX_ERROR!(var, t, s); + } + } + + /* XXX - check invisible_p(var) ? */ + if var.is_null() || value_cell!(var).is_null() { + FREE!(akey); + return 0 as *mut libc::c_void as *mut libc::c_char; + } else if invisible_p!(var) != 0 { + FREE!(akey); + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + if array_p!(var) == 0 as libc::c_int && assoc_p!(var) == 0 as libc::c_int { + return if ind == 0 as libc::c_int as libc::c_long { + value_cell!(var) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } else if assoc_p!(var) != 0 { + retval = assoc_reference(assoc_cell!(var), akey); + libc::free(akey as *mut libc::c_void); + } else { + retval = array_reference(array_cell!(var), ind); + } + } + } + return retval; +} + +/* Return a string containing the elements described by the array and +subscript contained in S, obeying quoting for subscripts * and @. */ +#[no_mangle] +pub fn array_value( + mut s: *const libc::c_char, + mut quoted: libc::c_int, + mut flags: libc::c_int, + mut rtype: *mut libc::c_int, + mut indp: *mut arrayind_t, +) -> *mut libc::c_char { + return array_value_internal(s, quoted, flags | AV_ALLOWALL as libc::c_int, rtype, indp); +} + +/* Return the value of the array indexing expression S as a single string. +If (FLAGS & AV_ALLOWALL) is 0, do not allow `@' and `*' subscripts. This +is used by other parts of the shell such as the arithmetic expression +evaluator in expr.c. */ +#[no_mangle] +pub fn get_array_value( + mut s: *const libc::c_char, + mut flags: libc::c_int, + mut rtype: *mut libc::c_int, + mut indp: *mut arrayind_t, +) -> *mut libc::c_char { + return array_value_internal(s, 0 as libc::c_int, flags, rtype, indp); +} + +#[no_mangle] +pub fn array_keys( + mut s: *mut libc::c_char, + mut quoted: libc::c_int, + mut pflags: libc::c_int, +) -> *mut libc::c_char { + let mut len: libc::c_int = 0; + let mut retval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + var = array_variable_part(s, 0 as libc::c_int, &mut t, &mut len); + + /* [ */ + if var.is_null() + || ALL_ELEMENT_SUB!(*t.offset(0 as libc::c_int as isize) as libc::c_int) as libc::c_int + == 0 as libc::c_int + || *t.offset(1 as libc::c_int as isize) as libc::c_int != ']' as i32 + { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + if var_isset!(var) as libc::c_int == 0 as libc::c_int || invisible_p!(var) != 0 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + if array_p!(var) == 0 as libc::c_int && assoc_p!(var) == 0 as libc::c_int { + l = make_word_list( + make_word(b"0\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ); + } else if assoc_p!(var) != 0 { + l = assoc_keys_to_word_list(assoc_cell!(var)); + } else { + l = array_keys_to_word_list(array_cell!(var)); + } + if l.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + retval = string_list_pos_params( + *t.offset(0 as libc::c_int as isize) as libc::c_int, + l, + quoted, + pflags, + ); + } + dispose_words(l); + return retval; +} diff --git a/utshell-0.5.0/src/assoc.rs b/utshell-0.5.0/src/assoc.rs new file mode 100644 index 00000000..72bd8237 --- /dev/null +++ b/utshell-0.5.0/src/assoc.rs @@ -0,0 +1,685 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::dispose_cmd::dispose_words; +use crate::hashlib::{hash_dispose, hash_flush, hash_remove, hash_search}; +use crate::make_cmd::{make_bare_word, make_word_list}; +use crate::src_common::*; +use crate::subst::{ + dequote_escapes, dequote_string, pat_subst, quote_escapes, quote_string, remove_quoted_nulls, + string_list_internal, string_list_pos_params, +}; + +#[no_mangle] +pub fn assoc_dispose(mut hash: *mut HASH_TABLE) { + unsafe { + if !hash.is_null() { + hash_flush(hash, None); + hash_dispose(hash); + } + } +} + +#[no_mangle] +pub fn assoc_flush(mut hash: *mut HASH_TABLE) { + hash_flush(hash, None); +} + +#[no_mangle] +pub fn assoc_insert( + mut hash: *mut HASH_TABLE, + mut key: *mut libc::c_char, + mut value: *mut libc::c_char, +) -> libc::c_int { + let mut b: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + b = hash_search(key, hash, 0x2 as libc::c_int); + if b.is_null() { + return -(1 as libc::c_int); + } + unsafe { + if (*b).key != key { + libc::free(key as *mut libc::c_void); + } + if !((*b).data).is_null() { + libc::free((*b).data); + } + (*b).data = 0 as *mut libc::c_void; + (*b).data = (if !value.is_null() { + savestring!(value) + } else { + 0 as *mut libc::c_char + }) as *mut libc::c_void; + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn assoc_remove(mut hash: *mut HASH_TABLE, mut string: *mut libc::c_char) { + let mut b: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + b = hash_remove(string, hash, 0 as libc::c_int); + unsafe { + if !b.is_null() { + libc::free((*b).data as *mut libc::c_char as *mut libc::c_void); + libc::free((*b).key as *mut libc::c_void); + libc::free(b as *mut libc::c_void); + } + } +} + +#[no_mangle] +pub fn assoc_reference( + mut hash: *mut HASH_TABLE, + mut string: *mut libc::c_char, +) -> *mut libc::c_char { + let mut b: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + if hash.is_null() { + return 0 as *mut libc::c_char; + } + b = hash_search(string, hash, 0 as libc::c_int); + unsafe { + return if !b.is_null() { + (*b).data as *mut libc::c_char + } else { + 0 as *mut libc::c_char + }; + } +} +#[no_mangle] +pub fn assoc_quote(mut h: *mut HASH_TABLE) -> *mut HASH_TABLE { + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if h.is_null() || assoc_empty!(h) { + return 0 as *mut libc::c_void as *mut HASH_TABLE; + } + i = 0 as libc::c_int; + + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + t = quote_string((*tlist).data as *mut libc::c_char); + if !((*tlist).data).is_null() { + libc::free((*tlist).data); + } + (*tlist).data = 0 as *mut libc::c_void; + (*tlist).data = t as *mut libc::c_void; + tlist = (*tlist).next; + } + i += 1; + i; + } + } + return h; +} + +#[no_mangle] +pub fn assoc_quote_escapes(mut h: *mut HASH_TABLE) -> *mut HASH_TABLE { + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if h.is_null() || assoc_empty!(h) { + return 0 as *mut libc::c_void as *mut HASH_TABLE; + } + i = 0 as libc::c_int; + + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + t = quote_escapes((*tlist).data as *mut libc::c_char); + if !((*tlist).data).is_null() { + libc::free((*tlist).data); + } + (*tlist).data = 0 as *mut libc::c_void; + (*tlist).data = t as *mut libc::c_void; + tlist = (*tlist).next; + } + i += 1; + i; + } + } + return h; +} + +#[no_mangle] +pub fn assoc_dequote(mut h: *mut HASH_TABLE) -> *mut HASH_TABLE { + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if h.is_null() || assoc_empty!(h) { + return 0 as *mut libc::c_void as *mut HASH_TABLE; + } + i = 0 as libc::c_int; + + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + t = dequote_string((*tlist).data as *mut libc::c_char); + if !((*tlist).data).is_null() { + libc::free((*tlist).data); + } + (*tlist).data = 0 as *mut libc::c_void; + (*tlist).data = t as *mut libc::c_void; + tlist = (*tlist).next; + } + i += 1; + i; + } + } + return h; +} + +#[no_mangle] +pub fn assoc_dequote_escapes(mut h: *mut HASH_TABLE) -> *mut HASH_TABLE { + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if h.is_null() || assoc_empty!(h) { + return 0 as *mut libc::c_void as *mut HASH_TABLE; + } + i = 0 as libc::c_int; + + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + t = dequote_escapes((*tlist).data as *mut libc::c_char); + if !((*tlist).data).is_null() { + libc::free((*tlist).data); + } + (*tlist).data = 0 as *mut libc::c_void; + (*tlist).data = t as *mut libc::c_void; + tlist = (*tlist).next; + } + i += 1; + i; + } + } + return h; +} + +#[no_mangle] +pub fn assoc_remove_quoted_nulls(mut h: *mut HASH_TABLE) -> *mut HASH_TABLE { + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if h.is_null() || assoc_empty!(h) { + return 0 as *mut libc::c_void as *mut HASH_TABLE; + } + i = 0 as libc::c_int; + + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + t = remove_quoted_nulls((*tlist).data as *mut libc::c_char); + (*tlist).data = t as *mut libc::c_void; + tlist = (*tlist).next; + } + i += 1; + i; + } + } + return h; +} + +#[no_mangle] +pub fn assoc_subrange( + mut hash: *mut HASH_TABLE, + mut start: arrayind_t, + mut nelem: arrayind_t, + mut starsub: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, +) -> *mut libc::c_char { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut h: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + if unsafe { assoc_empty!(hash) } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + l = assoc_to_word_list(hash); + save = l; + + if save.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + i = 1 as libc::c_int; + + while !l.is_null() && (i as libc::c_long) < start { + l = unsafe { (*l).next }; + i += 1; + i; + } + if l.is_null() { + dispose_words(save); + return 0 as *mut libc::c_void as *mut libc::c_char; + } + j = 0 as libc::c_int; + t = l; + h = t; + while !l.is_null() && (j as libc::c_long) < nelem { + t = l; + l = unsafe { (*l).next }; + j += 1; + j; + } + unsafe { + (*t).next = 0 as *mut libc::c_void as *mut WORD_LIST; + } + ret = string_list_pos_params( + if starsub != 0 { '*' as i32 } else { '@' as i32 }, + h, + quoted, + pflags, + ); + if t != l { + unsafe { + (*t).next = l; + } + } + dispose_words(save); + return ret; +} + +#[no_mangle] +pub fn assoc_patsub( + mut h: *mut HASH_TABLE, + mut pat: *mut libc::c_char, + mut rep: *mut libc::c_char, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pchar: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + if h.is_null() || unsafe { assoc_empty!(h) } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + wl = assoc_to_word_list(h); + if wl.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + save = wl; + unsafe { + while !wl.is_null() { + t = pat_subst((*(*wl).word).word, pat, rep, mflags); + if !((*(*wl).word).word).is_null() { + libc::free((*(*wl).word).word as *mut libc::c_void); + } + (*(*wl).word).word = 0 as *mut libc::c_char; + (*(*wl).word).word = t; + wl = (*wl).next; + } + } + pchar = if mflags & MATCH_STARSUB as libc::c_int == MATCH_STARSUB as libc::c_int { + '*' as i32 + } else { + '@' as i32 + }; + qflags = if mflags & MATCH_QUOTED as libc::c_int == MATCH_QUOTED as libc::c_int { + Q_DOUBLE_QUOTES as libc::c_int + } else { + 0 as libc::c_int + }; + pflags = if mflags & MATCH_ASSIGNRHS as libc::c_int == MATCH_ASSIGNRHS as libc::c_int { + PF_ASSIGNRHS as libc::c_int + } else { + 0 as libc::c_int + }; + t = string_list_pos_params(pchar, save, qflags, pflags); + dispose_words(save); + return t; +} + +#[no_mangle] +pub fn assoc_modcase( + mut h: *mut HASH_TABLE, + mut pat: *mut libc::c_char, + mut modop: libc::c_int, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pchar: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + if unsafe { h.is_null() || (*h).nentries == 0 as libc::c_int } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + wl = assoc_to_word_list(h); + if wl.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + save = wl; + unsafe { + while !wl.is_null() { + t = sh_modcase((*(*wl).word).word, pat, modop); + if !((*(*wl).word).word).is_null() { + libc::free((*(*wl).word).word as *mut libc::c_void); + } + (*(*wl).word).word = 0 as *mut libc::c_char; + (*(*wl).word).word = t; + wl = (*wl).next; + } + } + pchar = if mflags & MATCH_STARSUB as libc::c_int == MATCH_STARSUB as libc::c_int { + '*' as i32 + } else { + '@' as i32 + }; + qflags = if mflags & MATCH_QUOTED as libc::c_int == MATCH_QUOTED as libc::c_int { + Q_DOUBLE_QUOTES as libc::c_int + } else { + 0 as libc::c_int + }; + pflags = if mflags & MATCH_ASSIGNRHS as libc::c_int == MATCH_ASSIGNRHS as libc::c_int { + PF_ASSIGNRHS as libc::c_int + } else { + 0 as libc::c_int + }; + t = string_list_pos_params(pchar, save, qflags, pflags); + dispose_words(save); + return t; +} + +#[no_mangle] +pub fn assoc_to_kvpair(mut hash: *mut HASH_TABLE, mut quoted: libc::c_int) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut istr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + let mut rsize: libc::c_int = 0; + let mut rlen: libc::c_int = 0; + let mut elen: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + + unsafe { + if hash.is_null() || assoc_empty!(hash) { + return 0 as *mut libc::c_char; + } + rsize = 128 as libc::c_int; + ret = libc::malloc(rsize as size_t as usize) as *mut libc::c_char; + rlen = 0 as libc::c_int; + *ret.offset(rlen as isize) = '\0' as i32 as libc::c_char; + i = 0 as libc::c_int; + while i < (*hash).nbuckets { + tlist = hash_items!(i, hash); + while !tlist.is_null() { + if ansic_shouldquote((*tlist).key) != 0 { + istr = ansic_quote((*tlist).key, 0 as libc::c_int, 0 as *mut libc::c_int); + } else if sh_contains_shell_metas((*tlist).key) != 0 { + istr = sh_double_quote((*tlist).key); + } else if ALL_ELEMENT_SUB!(*((*tlist).key) as i32) + && *((*tlist).key).offset(1 as libc::c_int as isize) as libc::c_int + == '\0' as i32 + { + istr = sh_double_quote((*tlist).key); + } else { + istr = (*tlist).key; + } + vstr = if !((*tlist).data).is_null() { + if ansic_shouldquote((*tlist).data as *mut libc::c_char) != 0 { + ansic_quote( + (*tlist).data as *mut libc::c_char, + 0 as libc::c_int, + 0 as *mut libc::c_int, + ) + } else { + sh_double_quote((*tlist).data as *mut libc::c_char) + } + } else { + 0 as *mut libc::c_char + }; + elen = STRLEN!(istr) + 4 as libc::c_int + STRLEN!(vstr); + RESIZE_MALLOCED_BUFFER!(ret, rlen, (elen + 1), rsize, rsize); + libc::strcpy(ret.offset(rlen as isize), istr); + rlen += STRLEN!(istr); + *ret.offset(rlen as isize) = ' ' as i32 as libc::c_char; + rlen += 1; + if !vstr.is_null() { + libc::strcpy(ret.offset(rlen as isize), vstr); + rlen += STRLEN!(vstr); + } else { + libc::strcpy( + ret.offset(rlen as isize), + b"\"\"\0" as *const u8 as *const libc::c_char, + ); + rlen += 2 as libc::c_int; + } + *ret.offset(rlen as isize) = ' ' as i32 as libc::c_char; + rlen += 1; + + if istr != (*tlist).key { + if !istr.is_null() { + libc::free(istr as *mut libc::c_void); + } + istr = 0 as *mut libc::c_char; + } + if !vstr.is_null() { + libc::free(vstr as *mut libc::c_void); + } + vstr = 0 as *mut libc::c_char; + tlist = (*tlist).next; + } + i += 1; + i; + } + + RESIZE_MALLOCED_BUFFER!(ret, rlen, 1 as libc::c_int, rsize, 8 as libc::c_int); + *ret.offset(rlen as isize) = '\0' as i32 as libc::c_char; + + if quoted != 0 { + vstr = sh_single_quote(ret); + libc::free(ret as *mut libc::c_void); + ret = vstr; + } + } + return ret; +} + +#[no_mangle] +pub fn assoc_to_assign(mut hash: *mut HASH_TABLE, mut quoted: libc::c_int) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut istr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + let mut rsize: libc::c_int = 0; + let mut rlen: libc::c_int = 0; + let mut elen: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + if hash.is_null() || assoc_empty!(hash) { + return 0 as *mut libc::c_char; + } + rsize = 128 as libc::c_int; + ret = libc::malloc(rsize as size_t as usize) as *mut libc::c_char; + *ret.offset(0 as libc::c_int as isize) = '(' as i32 as libc::c_char; + rlen = 1 as libc::c_int; + + i = 0 as libc::c_int; + + while i < (*hash).nbuckets { + tlist = hash_items!(i, hash); + while !tlist.is_null() { + if ansic_shouldquote((*tlist).key) != 0 { + istr = ansic_quote((*tlist).key, 0 as libc::c_int, 0 as *mut libc::c_int); + } else if sh_contains_shell_metas((*tlist).key) != 0 { + istr = sh_double_quote((*tlist).key); + } else if ALL_ELEMENT_SUB!(*((*tlist).key) as i32) + && *((*tlist).key).offset(1 as libc::c_int as isize) as libc::c_int + == '\0' as i32 + { + istr = sh_double_quote((*tlist).key); + } else { + istr = (*tlist).key; + } + vstr = if !((*tlist).data).is_null() { + if ansic_shouldquote((*tlist).data as *mut libc::c_char) != 0 { + ansic_quote( + (*tlist).data as *mut libc::c_char, + 0 as libc::c_int, + 0 as *mut libc::c_int, + ) + } else { + sh_double_quote((*tlist).data as *mut libc::c_char) + } + } else { + 0 as *mut libc::c_char + }; + elen = STRLEN!(istr) + 8 as libc::c_int + STRLEN!(vstr); + RESIZE_MALLOCED_BUFFER!(ret, rlen, (elen + 1), rsize, rsize); + *ret.offset(rlen as isize) = '[' as i32 as libc::c_char; + rlen += 1; + libc::strcpy(ret.offset(rlen as isize), istr); + rlen += STRLEN!(istr); + + *ret.offset(rlen as isize) = ']' as i32 as libc::c_char; + rlen += 1; + + *ret.offset(rlen as isize) = '=' as i32 as libc::c_char; + rlen += 1; + if !vstr.is_null() { + libc::strcpy(ret.offset(rlen as isize), vstr); + rlen += STRLEN!(istr); + } + + *ret.offset(rlen as isize) = ' ' as i32 as libc::c_char; + rlen += 1; + + if istr != (*tlist).key { + if !istr.is_null() { + libc::free(istr as *mut libc::c_void); + } + istr = 0 as *mut libc::c_char; + } + if !vstr.is_null() { + libc::free(vstr as *mut libc::c_void); + } + vstr = 0 as *mut libc::c_char; + tlist = (*tlist).next; + } + i += 1; + i; + } + RESIZE_MALLOCED_BUFFER!(ret, rlen, 1 as libc::c_int, rsize, 8 as libc::c_int); + *ret.offset(rlen as isize) = ')' as i32 as libc::c_char; + rlen = rlen + 1; + *ret.offset(rlen as isize) = '\0' as i32 as libc::c_char; + if quoted != 0 { + vstr = sh_single_quote(ret); + libc::free(ret as *mut libc::c_void); + ret = vstr; + } + } + return ret; +} + +fn assoc_to_word_list_internal(mut h: *mut HASH_TABLE, mut t: libc::c_int) -> *mut WORD_LIST { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut w: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if h.is_null() || assoc_empty!(h) { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + list = 0 as *mut libc::c_void as *mut WORD_LIST; + i = 0 as libc::c_int; + + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + w = if t == 0 as libc::c_int { + (*tlist).data as *mut libc::c_char + } else { + (*tlist).key + }; + list = make_word_list(make_bare_word(w), list); + tlist = (*tlist).next; + } + i += 1; + i; + } + return REVERSE_LIST!(list, *mut WORD_LIST); + } +} + +#[no_mangle] +pub fn assoc_to_word_list(mut h: *mut HASH_TABLE) -> *mut WORD_LIST { + return assoc_to_word_list_internal(h, 0 as libc::c_int); +} + +#[no_mangle] +pub fn assoc_keys_to_word_list(mut h: *mut HASH_TABLE) -> *mut WORD_LIST { + return assoc_to_word_list_internal(h, 1 as libc::c_int); +} + +#[no_mangle] +pub fn assoc_to_string( + mut h: *mut HASH_TABLE, + mut sep: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut i: libc::c_int = 0; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut w: *mut libc::c_char = 0 as *mut libc::c_char; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + + if h.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + if assoc_empty!(h) { + return savestring!(b"\0" as *const u8 as *const libc::c_char); + } + + result = 0 as *mut libc::c_char; + list = 0 as *mut WORD_LIST; + l = list; + i = 0 as libc::c_int; + while i < (*h).nbuckets { + tlist = hash_items!(i, h); + while !tlist.is_null() { + w = (*tlist).data as *mut libc::c_char; + if !w.is_null() { + t = if quoted != 0 { + quote_string(w) + } else { + savestring!(w) + }; + list = make_word_list(make_bare_word(t), list); + if !t.is_null() { + libc::free(t as *mut libc::c_void); + } + t = 0 as *mut libc::c_char; + } + tlist = (*tlist).next; + } + i += 1; + i; + } + l = REVERSE_LIST!(list, *mut WORD_LIST); + result = if !l.is_null() { + string_list_internal(l, sep) + } else { + savestring!(b"\0" as *const u8 as *const libc::c_char) + }; + dispose_words(l); + } + return result; +} diff --git a/utshell-0.5.0/src/bashhist.rs b/utshell-0.5.0/src/bashhist.rs new file mode 100644 index 00000000..ca9ba02b --- /dev/null +++ b/utshell-0.5.0/src/bashhist.rs @@ -0,0 +1,822 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::bashline::bash_re_edit; +use crate::general::file_exists; +use crate::pathexp::setup_ignore_patterns; +use crate::src_common::*; +use crate::stringlib::strcreplace; +use crate::subst::{skip_to_delim, skip_to_histexp}; +use crate::variables::{ + get_string_value, set_if_not, sv_histchars, sv_histignore, sv_history_control, sv_histsize, +}; +use crate::y_tab::{ + bash_input, current_command_line_count, dstack, history_delimiting_chars, parser_state, +}; +use std::ffi::CStr; + +#[inline] +fn stat( + mut __path: *const libc::c_char, + mut __statbuf: *mut crate::src_common::stat, +) -> libc::c_int { + unsafe { + return __xstat(1 as libc::c_int, __path, __statbuf); + } +} + + +fn member(c: i32, s: *const libc::c_char) -> bool { + if c != 0 { + return unsafe { mbschr(s, c) as libc::c_char != 0 as libc::c_char }; + } else { + return false; + } +} + +static mut histignore: ignorevar = unsafe { + { + let mut init = ignorevar { + varname: b"HISTIGNORE\0" as *const u8 as *mut libc::c_char, + ignores: 0 as *mut ign, + num_ignores: 0 as libc::c_int, + last_ignoreval: 0 as *const libc::c_char as *mut libc::c_char, + item_func: Some(::std::mem::transmute::< + fn(*mut ign) -> libc::c_int, + sh_iv_item_func_t, + >(histignore_item_func)), + }; + init + } +}; + +fn bash_history_inhibit_expansion( + mut string: *mut libc::c_char, + mut i: libc::c_int, +) -> libc::c_int { + let mut t: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut hx: [libc::c_char; 2] = [0; 2]; + hx[0 as usize] = unsafe { history_expansion_char }; + hx[1 as usize] = '\u{0}' as i32 as libc::c_char; + unsafe { + if i > 0 as libc::c_int + && *string.offset((i - 1) as isize) as libc::c_int == '[' as i32 + && member( + ']' as i32, + string.offset(i as isize).offset(1 as libc::c_int as isize), + ) + { + return 1; + } else if i > 1 as libc::c_int + && *string.offset((i - 1 as libc::c_int) as isize) as libc::c_int == '{' as i32 + && *string.offset((i - 2 as libc::c_int) as isize) as libc::c_int == '$' as i32 + && member( + '}' as i32, + string.offset(i as isize).offset(1 as libc::c_int as isize), + ) + { + return 1; + } else if i > 1 as libc::c_int + && *string.offset((i - 1 as libc::c_int) as isize) as libc::c_int == '$' as i32 + && *string.offset(i as isize) as libc::c_int == '!' as i32 + { + return 1; + } else if extended_glob != 0 + && i > 1 as libc::c_int + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + && member( + ')' as i32, + string.offset(i as isize).offset(2 as libc::c_int as isize), + ) + { + return 1; + } + + si = 0; + if history_quoting_state == '\'' as i32 { + si = skip_to_delim( + string, + 0, + b"'\0" as *const u8 as *mut libc::c_char, + SD_NOJMP as libc::c_int | SD_HISTEXP as libc::c_int, + ); + if *string.offset(si as isize) == 0 || si >= i { + return 1; + } + si += 1; + } + } + t = skip_to_histexp( + string, + si, + hx.as_mut_ptr(), + SD_NOJMP as libc::c_int | SD_HISTEXP as libc::c_int, + ); + if t > 0 { + while t < i { + t = skip_to_histexp( + string, + t + 1 as libc::c_int, + hx.as_mut_ptr(), + SD_NOJMP as libc::c_int | SD_HISTEXP as libc::c_int, + ); + if t <= 0 { + return 0; + } + } + return (t > i) as libc::c_int; + } else { + return 0; + }; +} + +#[no_mangle] +pub fn bash_initialize_history() { + unsafe { + history_quotes_inhibit_expansion = 1; + history_search_delimiter_chars = + b";&()|<>\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + + history_inhibit_expansion_function = std::mem::transmute::< + fn(*mut libc::c_char, libc::c_int) -> libc::c_int, + Option, + >(bash_history_inhibit_expansion); + + sv_histchars(b"histchars\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } +} + +#[no_mangle] +pub fn bash_history_reinit(mut interact: libc::c_int) { + unsafe { + history_expansion = if interact == 0 { + histexp_flag + } else { + HISTEXPAND_DEFAULT as libc::c_int + }; + + history_expansion_inhibited = if interact == 0 { 1 - histexp_flag } else { 0 }; + history_inhibit_expansion_function = std::mem::transmute::< + fn(*mut libc::c_char, libc::c_int) -> libc::c_int, + Option, + >(bash_history_inhibit_expansion); + remember_on_history = enable_history_list; + } +} + +#[no_mangle] +pub fn bash_history_disable() { + unsafe { + remember_on_history = 0; + history_expansion_inhibited = 1; + } +} + +#[no_mangle] +pub fn bash_history_enable() { + unsafe { + remember_on_history = 1; + enable_history_list = 1; + history_expansion_inhibited = 0; + history_inhibit_expansion_function = std::mem::transmute::< + fn(*mut libc::c_char, libc::c_int) -> libc::c_int, + Option, + >(bash_history_inhibit_expansion); + sv_history_control(b"HISTCONTROL\0" as *const u8 as *mut libc::c_char); + sv_histignore(b"HISTIGNORE\0" as *const u8 as *mut libc::c_char); + } +} + +#[no_mangle] +pub fn load_history() { + let mut hf: *mut libc::c_char; + unsafe { + set_if_not( + b"HISTSIZE\0" as *const u8 as *mut libc::c_char, + HISTSIZE_DEFAULT!(), + ); + sv_histsize(b"HISTSIZE\0" as *const u8 as *mut libc::c_char); + + set_if_not( + b"HISTFILESIZE\0" as *const u8 as *mut libc::c_char, + get_string_value(b"HISTSIZE\0" as *const u8 as *mut libc::c_char), + ); + sv_histsize(b"HISTFILESIZE\0" as *const u8 as *mut libc::c_char); + + hf = get_string_value(b"HISTFILE\0" as *const u8 as *mut libc::c_char); + + if !hf.is_null() && *hf as libc::c_int != 0 && file_exists(hf) != 0 { + read_history(hf); + history_lines_in_file = history_lines_read_from_file; + using_history(); + } + } +} + +#[no_mangle] +pub fn bash_clear_history() { + unsafe { + clear_history(); + history_lines_this_session = 0; + } +} + +#[no_mangle] +pub fn bash_delete_histent(mut i: libc::c_int) -> libc::c_int { + let mut discard: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + unsafe { + discard = remove_history(i); + if !discard.is_null() { + free_history_entry(discard); + history_lines_this_session -= 1; + } + } + return (discard != 0 as *mut HIST_ENTRY) as libc::c_int; +} + +#[no_mangle] +pub fn bash_delete_history_range(mut first: libc::c_int, mut last: libc::c_int) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut discard_list: *mut *mut HIST_ENTRY = 0 as *mut *mut HIST_ENTRY; + unsafe { + discard_list = remove_history_range(first, last); + i = 0 as libc::c_int; + while !discard_list.is_null() && !(*discard_list.offset(i as isize)).is_null() { + free_history_entry(*discard_list.offset(i as isize)); + i += 1; + } + history_lines_this_session -= i; + } + return 1 as libc::c_int; +} + +#[no_mangle] +pub fn bash_delete_last_history() -> libc::c_int { + let mut i: libc::c_int = 0; + let mut hlist: *mut *mut HIST_ENTRY = 0 as *mut *mut HIST_ENTRY; + let mut histent: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + let mut r: libc::c_int = 0; + unsafe { + hlist = history_list(); + if hlist.is_null() { + return 0; + } + + i = 0; + while !(*hlist.offset(i as isize)).is_null() { + i += 1; + } + + i -= 1; + histent = history_get(history_base + i); + if histent.is_null() { + return 0; + } + + r = bash_delete_histent(i); + if where_history() > history_length { + history_set_pos(history_length); + } + } + return r; +} + +#[no_mangle] +pub fn maybe_append_history(mut filename: *mut libc::c_char) -> libc::c_int { + let mut fd: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut histlen: libc::c_int = 0; + let mut buf: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + result = EXECUTION_SUCCESS as i32; + unsafe { + if history_lines_this_session > 0 { + if stat(filename, &mut buf) == -1 && errno!() == ENOENT!() { + fd = libc::open( + filename, + O_WRONLY as i32 | O_CREAT as i32, + 0o600 as libc::c_int, + ); + if fd < 0 as libc::c_int { + builtin_error( + b"%s: cannot create: %s\0" as *const u8 as *const libc::c_char, + filename, + libc::strerror(errno!()), + ); + return 1 as libc::c_int; + } + libc::close(fd); + } + histlen = where_history(); + if histlen > 0 && history_lines_this_session > histlen { + history_lines_this_session = histlen; + } + result = append_history(history_lines_this_session, filename); + history_lines_in_file += history_lines_this_session; + history_lines_this_session = 0; + } else { + history_lines_this_session = 0; + } + } + return result; +} + +#[no_mangle] +pub fn maybe_save_shell_history() -> libc::c_int { + let mut result: libc::c_int = 0; + let mut hf: *mut libc::c_char = 0 as *mut libc::c_char; + result = 0; + unsafe { + if history_lines_this_session > 0 { + hf = get_string_value(b"HISTFILE\0" as *const u8 as *const libc::c_char); + if !hf.is_null() && *hf as libc::c_int != 0 { + if file_exists(hf) == 0 { + let mut file: libc::c_int = 0; + file = libc::open( + hf, + O_CREAT as libc::c_int | O_TRUNC as libc::c_int | O_WRONLY as libc::c_int, + 0o600 as libc::c_int, + ); + if file != -1 { + libc::close(file); + } + } + using_history(); + if history_lines_this_session <= where_history() || force_append_history != 0 { + result = append_history(history_lines_this_session, hf); + history_lines_in_file += history_lines_this_session; + } else { + result = write_history(hf); + history_lines_in_file = history_lines_written_to_file; + } + history_lines_this_session = 0; + sv_histsize(b"HISTFILESIZE\0" as *const u8 as *mut libc::c_char); + } + } + } + return result; +} + +fn re_edit(mut text: *mut libc::c_char) { + unsafe { + if bash_input.type_0 as libc::c_uint == st_stdin as libc::c_int as libc::c_uint { + bash_re_edit(text); + } + } +} + +fn history_expansion_p(mut line: *mut libc::c_char) -> libc::c_int { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + s = line; + unsafe { + while *s != 0 { + if *s as libc::c_int == history_expansion_char as libc::c_int + || *s as libc::c_int == history_subst_char as libc::c_int + { + return 1; + } + s = s.offset(1); + } + } + return 0; +} + +#[no_mangle] +pub fn pre_process_line( + mut line: *mut libc::c_char, + mut print_changes: libc::c_int, + mut addit: libc::c_int, +) -> *mut libc::c_char { + let mut history_value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut return_value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut expanded: libc::c_int = 0; + return_value = line; + expanded = 0; + unsafe { + if history_expansion_inhibited == 0 + && history_expansion != 0 + && history_expansion_p(line) != 0 + { + let mut old_len: libc::c_int = 0; + old_len = history_length; + if history_length > 0 + && command_oriented_history != 0 + && current_command_first_line_saved != 0 + && current_command_line_count > 1 + { + history_length -= 1; + } + expanded = history_expand(line, &mut history_value); + if history_length >= 0 + && command_oriented_history != 0 + && current_command_first_line_saved != 0 + && current_command_line_count > 1 + { + history_length = old_len; + } + if expanded != 0 { + if print_changes != 0 { + if expanded < 0 { + internal_error(b"%s\0" as *const u8 as *const libc::c_char, history_value); + } else if hist_verify == 0 || expanded == 2 { + println!("{}", CStr::from_ptr(history_value).to_str().unwrap()) + } + } + if expanded < 0 || expanded == 2 { + if expanded == 2 as libc::c_int + && rl_dispatching == 0 + && *history_value as libc::c_int != 0 + { + maybe_add_history(history_value); + } + libc::free(history_value as *mut libc::c_void); + if history_reediting != 0 && expanded < 0 && rl_done != 0 { + re_edit(line); + } + return 0 as *mut libc::c_char; + } + if hist_verify != 0 && expanded == 1 { + re_edit(history_value); + libc::free(history_value as *mut libc::c_void); + return 0 as *mut libc::c_char; + } + } + expanded = 1; + return_value = history_value; + } + if addit != 0 && remember_on_history != 0 && *return_value as libc::c_int != 0 { + maybe_add_history(return_value); + } + } + return return_value; +} + +fn shell_comment(mut line: *mut libc::c_char) -> libc::c_int { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut n: libc::c_int = 0; + if line.is_null() { + return 0; + } + unsafe { + p = line; + while !p.is_null() && *p as libc::c_int != 0 && whitespace!(*p) { + p = p.offset(1); + } + if !p.is_null() && *p as libc::c_int == '#' as i32 { + return 1; + } + n = skip_to_delim( + line, + p.offset_from(line) as libc::c_int, + b"#\0" as *const u8 as *mut libc::c_char, + SD_NOJMP as libc::c_int + | SD_GLOB as libc::c_int + | SD_EXTGLOB as libc::c_int + | SD_COMPLETE as libc::c_int, + ); + return if *line.offset(n as isize) as libc::c_int == '#' as i32 { + 2 + } else { + 0 + }; + } +} + +fn check_history_control(mut line: *mut libc::c_char) -> libc::c_int { + let mut temp: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + let mut r: libc::c_int = 0; + unsafe { + if history_control == 0 { + return 1; + } + if history_control & HC_IGNSPACE as libc::c_int != 0 && *line as libc::c_int == ' ' as i32 { + return 0; + } + if history_control & HC_IGNDUPS as libc::c_int != 0 { + using_history(); + temp = previous_history(); + r = (temp.is_null() || STREQ!((*temp).line, line) == false) as libc::c_int; + using_history(); + if r == 0 { + return r; + } + } + } + return 1; +} + +fn hc_erasedups(mut line: *mut libc::c_char) { + let mut temp: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + let mut r: libc::c_int = 0; + unsafe { + using_history(); + loop { + temp = previous_history(); + if temp.is_null() { + break; + } + if STREQ!((*temp).line, line) { + r = where_history(); + temp = remove_history(r); + if !temp.is_null() { + free_history_entry(temp); + } + } + } + using_history(); + } +} + +#[no_mangle] +pub fn maybe_add_history(mut line: *mut libc::c_char) { + let mut is_comment: libc::c_int = 0; + unsafe { + hist_last_line_added = 0; + is_comment = if parser_state & PST_HEREDOC as libc::c_int != 0 { + 0 + } else { + shell_comment(line) + }; + if current_command_line_count > 1 { + if current_command_first_line_saved != 0 + && (parser_state & PST_HEREDOC as libc::c_int != 0 + || literal_history != 0 + || dstack.delimiter_depth != 0 + || is_comment != 1) + { + bash_add_history(line); + } + current_command_line_comment = if is_comment != 0 { + current_command_line_count + } else { + -(2 as libc::c_int) + }; + return; + } + current_command_line_comment = if is_comment != 0 { + current_command_line_count + } else { + -(2 as libc::c_int) + }; + current_command_first_line_saved = check_add_history(line, 0); + } +} + +#[no_mangle] +pub fn check_add_history(mut line: *mut libc::c_char, mut force: libc::c_int) -> libc::c_int { + unsafe { + if check_history_control(line) != 0 && history_should_ignore(line) == 0 { + if history_control & HC_ERASEDUPS as libc::c_int != 0 { + hc_erasedups(line); + } + if force != 0 { + really_add_history(line); + using_history(); + } else { + bash_add_history(line); + } + return 1; + } + } + return 0; +} + +#[no_mangle] +pub fn bash_add_history(mut line: *mut libc::c_char) { + let mut add_it: libc::c_int = 0; + let mut offset: libc::c_int = 0; + let mut curlen: libc::c_int = 0; + let mut is_comment: libc::c_int = 0; + let mut current: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + let mut old: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + let mut chars_to_add: *mut libc::c_char = 0 as *mut libc::c_char; + let mut new_line: *mut libc::c_char = 0 as *mut libc::c_char; + + add_it = 1; + unsafe { + if command_oriented_history != 0 && current_command_line_count > 1 { + is_comment = if parser_state & PST_HEREDOC as libc::c_int != 0 { + 0 + } else { + shell_comment(line) + }; + if parser_state & PST_HEREDOC as libc::c_int != 0 + && current_command_line_count > 2 + && *line.offset(((libc::strlen(line)) - 1) as isize) as libc::c_int == '\n' as i32 + { + chars_to_add = b"\0" as *const u8 as *mut libc::c_char; + } else if current_command_line_count == current_command_line_comment + 1 { + chars_to_add = b"\n\0" as *const u8 as *mut libc::c_char; + } else if literal_history != 0 { + chars_to_add = b"\n\0" as *const u8 as *mut libc::c_char; + } else { + chars_to_add = history_delimiting_chars(line); + } + using_history(); + current = previous_history(); + current_command_line_comment = if is_comment != 0 { + current_command_line_count + } else { + -(2 as libc::c_int) + }; + if !current.is_null() { + curlen = libc::strlen((*current).line) as libc::c_int; + if dstack.delimiter_depth == 0 + && *((*current).line).offset((curlen - 1) as isize) as libc::c_int + == '\\' as i32 + && *((*current).line).offset((curlen - 2) as isize) as libc::c_int + != '\\' as i32 + { + *((*current).line).offset((curlen - 1) as isize) = + '\u{0}' as i32 as libc::c_char; + curlen -= 1; + chars_to_add = b"\0" as *const u8 as *mut libc::c_char; + } + if dstack.delimiter_depth == 0 + && *((*current).line).offset((curlen - 1) as isize) as libc::c_int + == '\n' as i32 + && *chars_to_add as libc::c_int == ';' as i32 + { + chars_to_add = chars_to_add.offset(1); + } + + new_line = libc::malloc( + (1 + curlen + libc::strlen(line) as i32 + libc::strlen(chars_to_add) as i32) + as usize, + ) as *mut libc::c_char; + libc::sprintf( + new_line, + b"%s%s%s\0" as *const u8 as *const libc::c_char, + (*current).line, + chars_to_add, + line, + ); + offset = where_history(); + old = replace_history_entry(offset, new_line, (*current).data); + + libc::free(new_line as *mut libc::c_void); + if !old.is_null() { + free_history_entry(old); + } + add_it = 0 as libc::c_int; + } + } + if add_it != 0 + && history_is_stifled() != 0 + && history_length == 0 as libc::c_int + && history_length == history_max_entries + { + add_it = 0 as libc::c_int; + } + if add_it != 0 { + really_add_history(line); + } + using_history(); + } +} + +fn really_add_history(mut line: *mut libc::c_char) { + unsafe { + hist_last_line_added = 1; + hist_last_line_pushed = 0; + add_history(line); + history_lines_this_session += 1; + } +} + +#[no_mangle] +pub fn history_number() -> libc::c_int { + unsafe { + using_history(); + return if remember_on_history != 0 || enable_history_list != 0 { + history_base + where_history() + } else { + 1 + }; + } +} + +fn should_expand(mut s: *mut libc::c_char) -> libc::c_int { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + p = s; + unsafe { + while !p.is_null() && *p as libc::c_int != 0 { + if *p as libc::c_int == '\\' as i32 { + p = p.offset(1); + } else if *p as libc::c_int == '&' as i32 { + return 1 as libc::c_int; + } + p = p.offset(1); + } + } + return 0; +} + +fn histignore_item_func(mut ign: *mut ign) -> libc::c_int { + unsafe { + if should_expand((*ign).val) != 0 { + (*ign).flags |= HIGN_EXPAND!(); + } + } + return 0; +} + +#[no_mangle] +pub fn setup_history_ignore(mut varname: *mut libc::c_char) { + unsafe { + setup_ignore_patterns(&mut histignore); + } +} + +fn last_history_entry() -> *mut HIST_ENTRY { + let mut he: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + unsafe { + using_history(); + he = previous_history(); + using_history(); + } + return he; +} + +#[no_mangle] +pub fn last_history_line() -> *mut libc::c_char { + let mut he: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + + he = last_history_entry(); + if he.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + return unsafe { (*he).line }; +} + +fn expand_histignore_pattern(mut pat: *mut libc::c_char) -> *mut libc::c_char { + let mut phe: *mut HIST_ENTRY = 0 as *mut HIST_ENTRY; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + + phe = last_history_entry(); + unsafe { + if phe.is_null() { + return savestring!(pat); + } + ret = strcreplace(pat, '&' as i32, (*phe).line, 1); + } + return ret; +} + +fn history_should_ignore(mut line: *mut libc::c_char) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut match_0: libc::c_int = 0; + let mut npat: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if histignore.num_ignores == 0 { + return 0; + } + match_0 = 0; + i = match_0; + while i < histignore.num_ignores { + if (*(histignore.ignores).offset(i as isize)).flags & HIGN_EXPAND!() != 0 { + npat = expand_histignore_pattern((*(histignore.ignores).offset(i as isize)).val); + } else { + npat = (*(histignore.ignores).offset(i as isize)).val; + } + match_0 = (strmatch(npat, line, FNMATCH_EXTFLAG!()) != FNM_NOMATCH!() as libc::c_int) + as libc::c_int; + + if (*(histignore.ignores).offset(i as isize)).flags & HIGN_EXPAND!() != 0 { + libc::free(npat as *mut libc::c_void); + } + if match_0 != 0 { + break; + } + i += 1; + } + } + return match_0; +} diff --git a/utshell-0.5.0/src/bashline.rs b/utshell-0.5.0/src/bashline.rs new file mode 100644 index 00000000..7860b509 --- /dev/null +++ b/utshell-0.5.0/src/bashline.rs @@ -0,0 +1,4825 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::alias::{alias_expand, all_aliases, get_alias_value}; +use crate::bashhist::{bash_add_history, pre_process_line}; +use crate::bracecomp::bash_brace_completion; +use crate::builtins::common::get_working_directory; +use crate::builtins::read::read_builtin; +use crate::builtins::read::sigalrm_seen; +use crate::dispose_cmd::{dispose_word, dispose_words}; +use crate::findcmd::{executable_file, executable_or_directory, search_for_command}; +use crate::make_cmd::alloc_word_desc; +use crate::pathexp::{setup_ignore_patterns, shell_glob_filename}; +use crate::pcomplete::prog_completion_enabled; +use crate::pcomplib::{progcomp_search, progcomp_size}; +use crate::readline::putc; +use crate::readline::*; +use crate::sig::throw_to_top_level; +use crate::src_common::{self, *}; +use crate::stringlib::substring; +use crate::subst::{ + char_is_quoted, expand_prompt_string, expand_word, skip_to_delim, string_list, unclosed_pair, +}; +use crate::syntax::sh_syntaxtab; +use crate::trap::first_pending_trap; +use crate::variables::{ + all_variables_matching_prefix, all_visible_functions, bind_int_variable, bind_variable, + check_unbind_variable, find_variable, get_string_value, +}; +use crate::version::show_shell_version; +use crate::y_tab::{ + current_command_line_count, current_prompt_string, parser_in_command_position, ps1_prompt, + reset_readahead_token, restore_parser_state, save_parser_state, saved_command_line_count, + word_token_alist, +}; +use std::convert::TryInto; + +extern "C" { + static mut stdin: *mut FILE; +} +#[inline] +fn lstat( + mut __path: *const libc::c_char, + mut __statbuf: *mut crate::src_common::stat, +) -> libc::c_int { + unsafe { + return __lxstat(1 as libc::c_int, __path, __statbuf); + } +} +#[macro_export] +macro_rules! BACKUP_CHAR { + ($_str:expr, $_strsize:expr, $_i:expr,$state:expr) => { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = __mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _x: libc::c_int = 0; + let mut _p: libc::c_int = 0; + _p = 0 as libc::c_int; + _x = _p; + while _x < $_i { + state_bak = $state; + mblength = mbrlen( + $_str.offset(_x as isize), + $_strsize.wrapping_sub(_x as libc::c_ulong), + &mut $state, + ) as u64; + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + $state = state_bak; + _x += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + _x += 1; + } else { + _p = _x; + _x = (_x as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } + $_i = _p; + } else { + $_i -= 1; + } + }; +} +#[no_mangle] +pub fn posix_readline_initialize(mut on_or_off: libc::c_int) { + static mut kseq: [libc::c_char; 2] = [CTRL!('I' as i32) as libc::c_char, 0 as libc::c_char]; + unsafe { + if on_or_off != 0 { + rl_variable_bind( + b"comment-begin\0" as *const u8 as *const libc::c_char, + b"#\0" as *const u8 as *const libc::c_char, + ); + } + if on_or_off != 0 { + vi_tab_binding = rl_function_of_keyseq( + kseq.as_mut_ptr(), + vi_insertion_keymap.as_mut_ptr(), + 0 as *mut libc::c_void as *mut libc::c_int, + ); + rl_bind_key_in_map( + CTRL!('I' as i32) as libc::c_int, + Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_insert)), + vi_insertion_keymap.as_mut_ptr(), + ); + } else if rl_function_of_keyseq( + kseq.as_mut_ptr(), + vi_insertion_keymap.as_mut_ptr(), + 0 as *mut c_void as *mut libc::c_int, + ) == Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_insert)) + { + rl_bind_key_in_map( + CTRL!('I' as i32) as libc::c_int, + vi_tab_binding, + vi_insertion_keymap.as_mut_ptr(), + ); + } + } +} + +#[no_mangle] +pub fn reset_completer_word_break_chars() { + unsafe { + rl_completer_word_break_characters = if perform_hostname_completion != 0 { + savestring!(bash_completer_word_break_characters) + } else { + savestring!(bash_nohostname_word_break_characters) + }; + } +} + +#[no_mangle] +pub fn enable_hostname_completion(mut on_or_off: libc::c_int) -> libc::c_int { + let mut old_value: libc::c_int = 0; + let mut at: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nv: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nval: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + old_value = perform_hostname_completion; + + if on_or_off != 0 { + perform_hostname_completion = 1 as libc::c_int; + rl_special_prefixes = b"$@\0" as *const u8 as *const libc::c_char; + } else { + perform_hostname_completion = 0 as libc::c_int; + rl_special_prefixes = b"$\0" as *const u8 as *const libc::c_char; + } + if bash_readline_initialized == 0 as libc::c_int + && (rl_completer_word_break_characters.is_null() + || rl_completer_word_break_characters + == rl_basic_word_break_characters as *mut libc::c_char) + { + if on_or_off != 0 { + rl_completer_word_break_characters = + savestring!(bash_completer_word_break_characters); + } else { + rl_completer_word_break_characters = + savestring!(bash_nohostname_word_break_characters); + } + } else { + at = libc::strchr(rl_completer_word_break_characters, '@' as i32); + if at.is_null() && on_or_off == 0 as libc::c_int + || !at.is_null() && on_or_off != 0 as libc::c_int + { + return old_value; + } + nval = libc::malloc( + ((libc::strlen(rl_completer_word_break_characters)) + 1 + on_or_off as usize) + as usize, + ) as *mut libc::c_char; + + if on_or_off == 0 as libc::c_int { + nv = nval; + at = rl_completer_word_break_characters; + while *at != 0 { + if *at as libc::c_int != '@' as i32 { + let fresh0 = at; + at = at.offset(1); + let fresh1 = nv; + nv = nv.offset(1); + *fresh1 = *fresh0; + } else { + at = at.offset(1); + } + } + *nv = '\u{0}' as i32 as libc::c_char; + } else { + *nval.offset(0 as libc::c_int as isize) = '@' as i32 as libc::c_char; + libc::strcpy( + nval.offset(1 as libc::c_int as isize), + rl_completer_word_break_characters, + ); + } + libc::free(rl_completer_word_break_characters as *mut c_void); + rl_completer_word_break_characters = nval; + } + } + return old_value; +} + +#[no_mangle] +pub fn initialize_readline() { + let mut func: Option = None; + let mut kseq: [libc::c_char; 2] = [0; 2]; + unsafe { + if bash_readline_initialized != 0 { + return; + } + rl_terminal_name = get_string_value(b"TERM\0" as *const u8 as *const libc::c_char); + rl_instream = stdin; + rl_outstream = stderr; + + rl_readline_name = b"Bash\0" as *const u8 as *const libc::c_char; + + rl_add_defun( + b"shell-expand-line\0" as *const u8 as *const libc::c_char, + Some(shell_expand_line), + -(1 as libc::c_int), + ); + rl_add_defun( + b"history-expand-line\0" as *const u8 as *const libc::c_char, + Some(history_expand_line), + -(1 as libc::c_int), + ); + rl_add_defun( + b"magic-space\0" as *const u8 as *const libc::c_char, + Some(tcsh_magic_space), + -(1 as libc::c_int), + ); + rl_add_defun( + b"shell-forward-word\0" as *const u8 as *const libc::c_char, + Some(bash_forward_shellword), + -(1 as libc::c_int), + ); + rl_add_defun( + b"shell-backward-word\0" as *const u8 as *const libc::c_char, + Some(bash_backward_shellword), + -(1 as libc::c_int), + ); + rl_add_defun( + b"shell-kill-word\0" as *const u8 as *const libc::c_char, + Some(bash_kill_shellword), + -(1 as libc::c_int), + ); + rl_add_defun( + b"shell-backward-kill-word\0" as *const u8 as *const libc::c_char, + Some(bash_backward_kill_shellword), + -(1 as libc::c_int), + ); + rl_add_defun( + b"shell-transpose-words\0" as *const u8 as *const libc::c_char, + Some(bash_transpose_shellwords), + -(1 as libc::c_int), + ); + rl_add_defun( + b"alias-expand-line\0" as *const u8 as *const libc::c_char, + Some(alias_expand_line), + -(1 as libc::c_int), + ); + rl_add_defun( + b"history-and-alias-expand-line\0" as *const u8 as *const libc::c_char, + Some(history_and_alias_expand_line), + -(1 as libc::c_int), + ); + rl_add_defun( + b"insert-last-argument\0" as *const u8 as *const libc::c_char, + Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_yank_last_arg)), + -(1 as libc::c_int), + ); + rl_add_defun( + b"display-shell-version\0" as *const u8 as *const libc::c_char, + Some(display_shell_version), + -(1 as libc::c_int), + ); + rl_add_defun( + b"edit-and-execute-command\0" as *const u8 as *const libc::c_char, + Some(emacs_edit_and_execute_command), + -(1 as libc::c_int), + ); + rl_add_defun( + b"complete-into-braces\0" as *const u8 as *const libc::c_char, + Some(bash_brace_completion), + -(1 as libc::c_int), + ); + rl_add_defun( + b"complete-filename\0" as *const u8 as *const libc::c_char, + Some(bash_complete_filename), + -(1 as libc::c_int), + ); + rl_add_defun( + b"possible-filename-completions\0" as *const u8 as *const libc::c_char, + Some(bash_possible_filename_completions), + -(1 as libc::c_int), + ); + rl_add_defun( + b"complete-username\0" as *const u8 as *const libc::c_char, + Some(bash_complete_username), + -(1 as libc::c_int), + ); + rl_add_defun( + b"possible-username-completions\0" as *const u8 as *const libc::c_char, + Some(bash_possible_username_completions), + -(1 as libc::c_int), + ); + rl_add_defun( + b"complete-hostname\0" as *const u8 as *const libc::c_char, + Some(bash_complete_hostname), + -(1 as libc::c_int), + ); + rl_add_defun( + b"possible-hostname-completions\0" as *const u8 as *const libc::c_char, + Some(bash_possible_hostname_completions), + -(1 as libc::c_int), + ); + rl_add_defun( + b"complete-variable\0" as *const u8 as *const libc::c_char, + Some(bash_complete_variable), + -(1 as libc::c_int), + ); + rl_add_defun( + b"possible-variable-completions\0" as *const u8 as *const libc::c_char, + Some(bash_possible_variable_completions), + -(1 as libc::c_int), + ); + rl_add_defun( + b"complete-command\0" as *const u8 as *const libc::c_char, + Some(bash_complete_command), + -(1 as libc::c_int), + ); + rl_add_defun( + b"possible-command-completions\0" as *const u8 as *const libc::c_char, + Some(bash_possible_command_completions), + -(1 as libc::c_int), + ); + rl_add_defun( + b"glob-complete-word\0" as *const u8 as *const libc::c_char, + Some(bash_glob_complete_word), + -(1 as libc::c_int), + ); + rl_add_defun( + b"glob-expand-word\0" as *const u8 as *const libc::c_char, + Some(bash_glob_expand_word), + -(1 as libc::c_int), + ); + rl_add_defun( + b"glob-list-expansions\0" as *const u8 as *const libc::c_char, + Some(bash_glob_list_expansions), + -(1 as libc::c_int), + ); + rl_add_defun( + b"dynamic-complete-history\0" as *const u8 as *const libc::c_char, + Some(dynamic_complete_history), + -(1 as libc::c_int), + ); + rl_add_defun( + b"dabbrev-expand\0" as *const u8 as *const libc::c_char, + Some(bash_dabbrev_expand), + -(1 as libc::c_int), + ); + if rl_readline_state & 0x2 as libc::c_int as libc::c_ulong + == 0 as libc::c_int as libc::c_ulong + { + rl_initialize(); + } + rl_bind_key_if_unbound_in_map( + 'E' as i32 & 0x1f as libc::c_int, + Some(shell_expand_line), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '^' as i32, + Some(history_expand_line), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'V' as i32 & 0x1f as libc::c_int, + Some(display_shell_version), + emacs_ctlx_keymap.as_mut_ptr(), + ); + kseq[0 as usize] = CTRL!('J' as i32) as libc::c_char; + kseq[1 as usize] = '\u{0}' as i32 as libc::c_char; + func = rl_function_of_keyseq( + kseq.as_mut_ptr(), + emacs_meta_keymap.as_mut_ptr(), + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if func + == Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_vi_editing_mode)) + { + rl_unbind_key_in_map( + CTRL!('J' as i32) as libc::c_int, + emacs_meta_keymap.as_mut_ptr(), + ); + } + kseq[0 as usize] = CTRL!('M' as i32) as libc::c_char; + func = rl_function_of_keyseq( + kseq.as_mut_ptr(), + emacs_meta_keymap.as_mut_ptr(), + 0 as *mut c_void as *mut libc::c_int, + ); + if func + == Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_vi_editing_mode)) + { + rl_unbind_key_in_map( + CTRL!('M' as i32) as libc::c_int, + emacs_meta_keymap.as_mut_ptr(), + ); + } + kseq[0 as usize] = CTRL!('E' as i32) as libc::c_char; + func = rl_function_of_keyseq( + kseq.as_mut_ptr(), + vi_movement_keymap.as_mut_ptr(), + 0 as *mut c_void as *mut libc::c_int, + ); + if func + == Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_emacs_editing_mode)) + { + rl_unbind_key_in_map( + CTRL!('E' as i32) as libc::c_int, + vi_movement_keymap.as_mut_ptr(), + ); + } + rl_bind_key_if_unbound_in_map( + '{' as i32, + Some(bash_brace_completion), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '/' as i32, + Some(bash_complete_filename), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '/' as i32, + Some(bash_possible_filename_completions), + emacs_ctlx_keymap.as_mut_ptr(), + ); + kseq[0 as libc::c_int as usize] = '~' as i32 as libc::c_char; + kseq[1 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + func = rl_function_of_keyseq( + kseq.as_mut_ptr(), + emacs_meta_keymap.as_mut_ptr(), + 0 as *mut c_void as *mut libc::c_int, + ); + if func.is_none() + || func + == Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_tilde_expand)) + { + rl_bind_keyseq_in_map( + kseq.as_mut_ptr(), + Some(bash_complete_username), + emacs_meta_keymap.as_mut_ptr(), + ); + } + rl_bind_key_if_unbound_in_map( + '~' as i32, + Some(bash_possible_username_completions), + emacs_ctlx_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '@' as i32, + Some(bash_complete_hostname), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '@' as i32, + Some(bash_possible_hostname_completions), + emacs_ctlx_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '$' as i32, + Some(bash_complete_variable), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '$' as i32, + Some(bash_possible_variable_completions), + emacs_ctlx_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '!' as i32, + Some(bash_complete_command), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '!' as i32, + Some(bash_possible_command_completions), + emacs_ctlx_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'g' as i32, + Some(bash_glob_complete_word), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '*' as i32, + Some(bash_glob_expand_word), + emacs_ctlx_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'g' as i32, + Some(bash_glob_list_expansions), + emacs_ctlx_keymap.as_mut_ptr(), + ); + kseq[0 as libc::c_int as usize] = '\t' as i32 as libc::c_char; + kseq[1 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + func = rl_function_of_keyseq( + kseq.as_mut_ptr(), + emacs_meta_keymap.as_mut_ptr(), + 0 as *mut c_void as *mut libc::c_int, + ); + if func.is_none() + || func + == Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_tab_insert)) + { + rl_bind_key_in_map( + '\t' as i32, + Some(dynamic_complete_history), + emacs_meta_keymap.as_mut_ptr(), + ); + } + rl_attempted_completion_function = Some(attempt_shell_completion); + set_directory_hook(); + rl_filename_rewrite_hook = Some(bash_filename_rewrite_hook); + rl_filename_stat_hook = Some(bash_filename_stat_hook); + rl_ignore_some_completions_function = Some(filename_completion_ignore); + rl_bind_key_if_unbound_in_map( + 'E' as i32 & 0x1f as libc::c_int, + Some(emacs_edit_and_execute_command), + emacs_ctlx_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'v' as i32, + Some(vi_edit_and_execute_command), + vi_movement_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + '@' as i32, + Some(posix_edit_macros), + vi_movement_keymap.as_mut_ptr(), + ); + rl_bind_key_in_map( + '\\' as i32, + Some(bash_vi_complete), + vi_movement_keymap.as_mut_ptr(), + ); + rl_bind_key_in_map( + '*' as i32, + Some(bash_vi_complete), + vi_movement_keymap.as_mut_ptr(), + ); + rl_bind_key_in_map( + '=' as i32, + Some(bash_vi_complete), + vi_movement_keymap.as_mut_ptr(), + ); + rl_completer_quote_characters = b"'\"\0" as *const u8 as *const libc::c_char; + enable_hostname_completion(perform_hostname_completion); + rl_filename_quote_characters = default_filename_quote_characters; + set_filename_bstab(rl_filename_quote_characters); + rl_filename_quoting_function = Some(bash_quote_filename); + rl_filename_dequoting_function = Some(bash_dequote_filename); + rl_char_is_quoted_p = Some(char_is_quoted); + rl_bind_key_if_unbound_in_map( + 'B' as i32 & 0x1f as libc::c_int, + Some(bash_backward_shellword), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'D' as i32 & 0x1f as libc::c_int, + Some(bash_kill_shellword), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'F' as i32 & 0x1f as libc::c_int, + Some(bash_forward_shellword), + emacs_meta_keymap.as_mut_ptr(), + ); + rl_bind_key_if_unbound_in_map( + 'T' as i32 & 0x1f as libc::c_int, + Some(bash_transpose_shellwords), + emacs_meta_keymap.as_mut_ptr(), + ); + bash_readline_initialized = 1 as libc::c_int; + } +} + +#[no_mangle] +pub fn bashline_reinitialize() { + unsafe { + bash_readline_initialized = 0; + } +} +#[no_mangle] +pub fn bashline_set_event_hook() { + unsafe { + rl_signal_event_hook = Some(bash_event_hook); + } +} +#[no_mangle] +pub fn bashline_reset_event_hook() { + unsafe { + rl_signal_event_hook = None; + } +} + +#[no_mangle] +pub fn bashline_reset() { + unsafe { + tilde_initialize(); + rl_attempted_completion_function = Some(attempt_shell_completion); + rl_completion_entry_function = None; + rl_ignore_some_completions_function = Some(filename_completion_ignore); + rl_filename_quote_characters = default_filename_quote_characters; + set_filename_bstab(rl_filename_quote_characters); + + set_directory_hook(); + rl_filename_stat_hook = Some(bash_filename_stat_hook); + + bashline_reset_event_hook(); + + rl_sort_completion_matches = 1 as libc::c_int; + } +} + +static mut push_to_readline: *mut libc::c_char = 0 as *mut libc::c_char; + +fn bash_push_line() -> libc::c_int { + unsafe { + if !push_to_readline.is_null() { + rl_insert_text(push_to_readline); + libc::free(push_to_readline as *mut c_void); + push_to_readline = 0 as *mut libc::c_char; + rl_startup_hook = old_rl_startup_hook; + } + } + return 0; +} + +#[no_mangle] +pub fn bash_re_edit(mut line: *mut libc::c_char) -> libc::c_int { + unsafe { + FREE!(push_to_readline); + + push_to_readline = savestring!(line); + old_rl_startup_hook = rl_startup_hook; + rl_startup_hook = Some(bash_push_line); + } + return 0; +} + +fn display_shell_version(mut count: libc::c_int, mut c: libc::c_int) -> libc::c_int { + unsafe { + rl_crlf(); + show_shell_version(0); + putc('\r' as i32, rl_outstream); + fflush(rl_outstream); + rl_on_new_line(); + rl_redisplay(); + } + return 0; +} + +static mut hostname_list: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + +static mut hostname_list_size: libc::c_int = 0; + +static mut hostname_list_length: libc::c_int = 0; + +#[no_mangle] +pub static mut hostname_list_initialized: libc::c_int = 0; +fn initialize_hostname_list() { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + + temp = get_string_value(b"HOSTFILE\0" as *const u8 as *const libc::c_char); + if temp.is_null() { + temp = get_string_value(b"hostname_completion_file\0" as *const u8 as *const libc::c_char); + } + if temp.is_null() { + temp = b"/etc/hosts\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + + snarf_hosts_from_file(temp); + unsafe { + if !hostname_list.is_null() { + hostname_list_initialized += 1; + } + } +} + +fn add_host_name(mut name: *mut libc::c_char) { + unsafe { + if hostname_list_length + 2 > hostname_list_size { + hostname_list_size = hostname_list_size + 32 - hostname_list_size % 32; + hostname_list = strvec_resize(hostname_list, hostname_list_size); + } + //有å¯èƒ½å­˜åœ¨é”™è¯¯çš„地方 + *hostname_list.offset(hostname_list_length as isize) = savestring!(name); + hostname_list_length = hostname_list_length + 1; + *hostname_list.offset(hostname_list_length as isize) = 0 as *mut libc::c_char; + } +} + +fn snarf_hosts_from_file(mut filename: *mut libc::c_char) { + let mut file: *mut FILE = 0 as *mut FILE; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut buffer: [libc::c_char; 256] = [0; 256]; + let mut name: [libc::c_char; 256] = [0; 256]; + let mut i: libc::c_int = 0; + let mut start: libc::c_int = 0; + unsafe { + file = libc::fopen(filename, b"r\0" as *const u8 as *const libc::c_char); + if file.is_null() { + return; + } + + loop { + temp = libc::fgets(buffer.as_mut_ptr(), 255 as libc::c_int, file); + if temp.is_null() { + break; + } + + i = 0; + while buffer[i as usize] as libc::c_int != 0 && cr_whitespace!(buffer[i as usize]) { + i += 1; + } + + if buffer[i as usize] as libc::c_int == '\u{0}' as i32 + || buffer[i as usize] as libc::c_int == '#' as i32 + { + continue; + } + + if libc::strncmp( + buffer.as_mut_ptr().offset(i as isize), + b"$include \0" as *const u8 as *const libc::c_char, + (9 as libc::c_int as libc::c_ulong).try_into().unwrap(), + ) == 0 + { + let mut incfile: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + incfile = buffer.as_mut_ptr().offset(i as isize).offset(9 as isize); + while *incfile as libc::c_int != 0 && whitespace!(*incfile) { + incfile = incfile.offset(1); + } + + t = incfile; + while *t as libc::c_int != 0 && cr_whitespace!(*t as libc::c_int) == false { + t = t.offset(1); + } + *t = '\u{0}' as i32 as libc::c_char; + snarf_hosts_from_file(incfile); + } else { + if DIGIT![i as usize] { + while buffer[i as usize] as libc::c_int != 0 + && cr_whitespace!(buffer[i as usize]) == false + { + i += 1; + } + } + + while buffer[i as usize] != 0 { + while cr_whitespace!(buffer[i as usize]) { + i += 1; + } + if buffer[i as usize] as libc::c_int == '\u{0}' as i32 + || buffer[i as usize] as libc::c_int == '#' as i32 + { + break; + } + start = i; + while buffer[i as usize] as libc::c_int != 0 + && cr_whitespace!(buffer[i as usize]) == false + { + i += 1; + } + + if i == start { + continue; + } + + libc::strncpy( + name.as_mut_ptr(), + buffer.as_mut_ptr().offset(start as isize), + ((i - start) as libc::c_ulong).try_into().unwrap(), + ); + name[(i - start) as usize] = '\u{0}' as i32 as libc::c_char; + add_host_name(name.as_mut_ptr()); + } + } + } + libc::fclose(file); + } +} + +#[no_mangle] +pub fn get_hostname_list() -> *mut *mut libc::c_char { + unsafe { + if hostname_list_initialized == 0 as libc::c_int { + initialize_hostname_list(); + } + return hostname_list; + } +} + +#[no_mangle] +pub fn clear_hostname_list() { + let mut i: libc::c_int = 0; + unsafe { + if hostname_list_initialized == 0 as libc::c_int { + return; + } + i = 0; + while i < hostname_list_length { + libc::free(*hostname_list.offset(i as isize) as *mut c_void); + i += 1; + } + hostname_list_initialized = 0; + hostname_list_length = hostname_list_initialized; + } +} + +fn hostnames_matching(mut text: *mut libc::c_char) -> *mut *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut nmatch: libc::c_int = 0; + let mut rsize: libc::c_int = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + unsafe { + if hostname_list_initialized == 0 { + initialize_hostname_list(); + } + + if hostname_list_initialized == 0 { + return 0 as *mut *mut libc::c_char; + } + + if *text as libc::c_int == '\u{0}' as i32 { + result = strvec_create(1 + hostname_list_length); + i = 0; + while i < hostname_list_length { + *result.offset(i as isize) = *hostname_list.offset(i as isize); + i += 1; + } + *result.offset(i as isize) = 0 as *mut libc::c_char; + return result; + } + + len = libc::strlen(text) as libc::c_int; + result = 0 as *mut *mut libc::c_char; + + rsize = 0 as libc::c_int; + nmatch = rsize; + i = nmatch; + while i < hostname_list_length { + if STREQN!(text, *hostname_list.offset(i as isize), len as usize) as i32 == 0 { + continue; + } + + if nmatch >= rsize - 1 { + rsize = rsize + 16 - rsize % 16; + result = strvec_resize(result, rsize); + } + + *result.offset(nmatch as isize) = *hostname_list.offset(i as isize); + nmatch = nmatch + 1; + + i += 1; + } + + if nmatch != 0 { + *result.offset(nmatch as isize) = 0 as *mut libc::c_char; + } + } + return result; +} + +fn edit_and_execute_command( + mut count: libc::c_int, + mut c: libc::c_int, + mut editing_mode: libc::c_int, + mut edit_command: *mut libc::c_char, +) -> libc::c_int { + let mut command: *mut libc::c_char = 0 as *mut libc::c_char; + let mut metaval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + let mut rrs: libc::c_int = 0; + let mut metaflag: libc::c_int = 0; + let mut ps: sh_parser_state_t = sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + unsafe { + rrs = rl_readline_state as libc::c_int; + saved_command_line_count = current_command_line_count; + + rl_newline(1, c); + + if rl_explicit_arg != 0 { + command = libc::malloc((libc::strlen(edit_command)).wrapping_add(8 as usize) as usize) + as *mut libc::c_char; + sprintf( + command, + b"%s %d\0" as *const u8 as *const libc::c_char, + edit_command, + count, + ); + } else { + using_history(); + current_command_line_count += 1; + bash_add_history(rl_line_buffer); + current_command_line_count = 0 as libc::c_int; + bash_add_history(b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + history_lines_this_session += 1; + using_history(); + command = savestring!(edit_command); + } + + metaval = rl_variable_value(b"input-meta\0" as *const u8 as *const libc::c_char); + metaflag = RL_BOOLEAN_VARIABLE_VALUE!(metaval) as libc::c_int; + + if rl_deprep_term_function.is_some() { + (Some(rl_deprep_term_function.expect("non-null function pointer"))) + .expect("non-null function pointer")(); + } + rl_clear_signals(); + save_parser_state(&mut ps); + r = parse_and_execute( + command, + if editing_mode == 0 as libc::c_int { + b"v\0" as *const u8 as *const libc::c_char + } else { + b"C-xC-e\0" as *const u8 as *const libc::c_char + }, + SEVAL_NOHIST as libc::c_int, + ); + restore_parser_state(&mut ps); + + reset_readahead_token(); + + if rl_prep_term_function.is_some() { + (Some(rl_prep_term_function.expect("non-null function pointer"))) + .expect("non-null function pointer")(metaflag); + } + rl_set_signals(); + + current_command_line_count = saved_command_line_count; + + *rl_line_buffer.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + rl_end = 0 as libc::c_int; + rl_point = rl_end; + rl_done = 0 as libc::c_int; + rl_readline_state = rrs as libc::c_ulong; + + if editing_mode == 0 { + rl_vi_insertion_mode(1 as libc::c_int, c); + } + rl_forced_update_display(); + } + return r; +} + +fn vi_edit_and_execute_command(mut count: libc::c_int, mut c: libc::c_int) -> libc::c_int { + if unsafe { posixly_correct != 0 } { + return edit_and_execute_command(count, c, 0 as libc::c_int, POSIX_VI_EDIT_COMMAND!()); + } else { + return edit_and_execute_command(count, c, 0 as libc::c_int, VI_EDIT_COMMAND!()); + }; +} + +fn emacs_edit_and_execute_command(mut count: libc::c_int, mut c: libc::c_int) -> libc::c_int { + return edit_and_execute_command(count, c, EMACS_EDITING_MODE!(), EMACS_EDIT_COMMAND!()); +} + +fn posix_edit_macros(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut c: libc::c_int = 0; + let mut alias_name: [libc::c_char; 3] = [0; 3]; + let mut alias_value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut macro_0: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + c = rl_read_key(); + alias_name[0 as usize] = '_' as i32 as libc::c_char; + alias_name[1 as usize] = c as libc::c_char; + alias_name[2 as usize] = '\u{0}' as i32 as libc::c_char; + + alias_value = get_alias_value(alias_name.as_mut_ptr()); + if !alias_value.is_null() && *alias_value as libc::c_int != 0 { + macro_0 = savestring!(alias_value); + rl_push_macro_input(macro_0); + } + } + return 0; +} + +fn is_basic(mut c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} + +fn bash_forward_shellword(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut slen: size_t = 0; + let mut c: libc::c_int = 0; + let mut p: libc::c_int = 0; + let mut state: mbstate_t = __mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + DECLARE_MBSTATE!(state); + + if count < 0 { + return bash_backward_shellword(-count, key); + } + + p = rl_point; + slen = rl_end as size_t; + + while count != 0 { + if p == rl_end { + rl_point = rl_end; + return 0; + } + + if char_is_quoted(rl_line_buffer, p) != 0 + && p > 0 + && *rl_line_buffer.offset((p - 1) as isize) as libc::c_int != '\\' as i32 + { + loop { + ADVANCE_CHAR!(rl_line_buffer, slen, p, state); + if !(p < rl_end && char_is_quoted(rl_line_buffer, p) != 0) { + break; + } + } + count -= 1; + } else { + while p < rl_end + && { + c = *rl_line_buffer.offset(p as isize) as libc::c_int; + c != 0 + } + && WORDDELIM!(c) + { + let optu8: u8 = c as u8; + let optChar: char = char::from(optu8); + match optChar { + '\\' => { + if p < rl_end && *rl_line_buffer.offset(p as isize) as libc::c_int != 0 + { + ADVANCE_CHAR!(rl_line_buffer, slen, p, state); + } + } + '\'' => { + p += 1; + p = skip_to_delim( + rl_line_buffer, + p, + b"'\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + } + '"' => { + p += 1; + p = skip_to_delim( + rl_line_buffer, + p, + b"\"\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + } + _ => { + ADVANCE_CHAR!(rl_line_buffer, slen, p, state); + + continue; + } + } + if p < rl_end { + p += 1; + } + } + + if *rl_line_buffer.offset(p as isize) as libc::c_int == 0 || p == rl_end { + rl_point = rl_end; + rl_ding(); + return 0; + } + + while p < rl_end + && { + c = *rl_line_buffer.offset(p as isize) as libc::c_int; + c != 0 + } + && WORDDELIM!(c) == false + { + let optu8: u8 = c as u8; + let optChar: char = char::from(optu8); + match optChar { + '\\' => { + if p < rl_end && *rl_line_buffer.offset(p as isize) as libc::c_int != 0 + { + ADVANCE_CHAR!(rl_line_buffer, slen, p, state); + } + } + '\'' => { + p += 1; + p = skip_to_delim( + rl_line_buffer, + p, + b"'\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + } + '"' => { + p += 1; + p = skip_to_delim( + rl_line_buffer, + p, + b"\"\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + } + _ => { + ADVANCE_CHAR!(rl_line_buffer, slen, p, state); + continue; + } + } + if p < rl_end { + p += 1; + } + } + if p == rl_end + || *rl_line_buffer.offset(p as isize) as libc::c_int == 0 as libc::c_int + { + rl_point = rl_end; + return 0; + } + count -= 1; + } + } + rl_point = p; + } + return 0; +} + +fn bash_backward_shellword(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut slen: size_t = 0; + let mut c: libc::c_int = 0; + let mut p: libc::c_int = 0; + let mut prev_p: libc::c_int = 0; + let mut state: mbstate_t = __mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut c_void, + '\u{0}' as i32, + (::std::mem::size_of::() as libc::c_ulong) as usize, + ); + if count < 0 { + return bash_forward_shellword(-count, key); + } + p = rl_point; + slen = rl_end as size_t; + + while count != 0 { + if p == 0 { + rl_point = 0; + return 0; + } + + BACKUP_CHAR!(rl_line_buffer, slen, p, state); + while p > 0 { + c = *rl_line_buffer.offset(p as isize) as libc::c_int; + if WORDDELIM!(c) == false || char_is_quoted(rl_line_buffer, p) != 0 { + break; + } + BACKUP_CHAR!(rl_line_buffer, slen, p, state); + } + + if p == 0 { + rl_point = 0; + return 0; + } + + prev_p = p; + while p > 0 { + c = *rl_line_buffer.offset(p as isize) as libc::c_int; + if WORDDELIM!(c) && char_is_quoted(rl_line_buffer, p) == 0 as libc::c_int { + p = prev_p; + break; + } else { + prev_p = p; + BACKUP_CHAR!(rl_line_buffer, slen, p, state); + } + } + count -= 1; + } + rl_point = p; + } + return 0; +} + +fn bash_kill_shellword(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut p: libc::c_int = 0; + + if count < 0 { + return bash_backward_kill_shellword(-count, key); + } + unsafe { + p = rl_point; + bash_forward_shellword(count, key); + + if rl_point != p { + rl_kill_text(p, rl_point); + } + + rl_point = p; + if rl_editing_mode == 1 { + rl_mark = rl_point; + } + } + return 0; +} + +fn bash_backward_kill_shellword(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut p: libc::c_int = 0; + + if count < 0 as libc::c_int { + return bash_kill_shellword(-count, key); + } + unsafe { + p = rl_point; + bash_backward_shellword(count, key); + + if rl_point != p { + rl_kill_text(p, rl_point); + } + if rl_editing_mode == 1 as libc::c_int { + rl_mark = rl_point; + } + } + return 0 as libc::c_int; +} + +fn bash_transpose_shellwords(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut word1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut word2: *mut libc::c_char = 0 as *mut libc::c_char; + let mut w1_beg: libc::c_int = 0; + let mut w1_end: libc::c_int = 0; + let mut w2_beg: libc::c_int = 0; + let mut w2_end: libc::c_int = 0; + unsafe { + let mut orig_point: libc::c_int = rl_point; + + if count == 0 as libc::c_int { + return 0 as libc::c_int; + } + + bash_forward_shellword(count, key); + w2_end = rl_point; + bash_backward_shellword(1, key); + w2_beg = rl_point; + bash_backward_shellword(count, key); + w1_beg = rl_point; + bash_forward_shellword(1, key); + w1_end = rl_point; + + if w1_beg == w2_beg || w2_beg < w1_end { + rl_ding(); + rl_point = orig_point; + return 1; + } + + word1 = rl_copy_text(w1_beg, w1_end); + word2 = rl_copy_text(w2_beg, w2_end); + + rl_begin_undo_group(); + + rl_point = w2_beg; + rl_delete_text(w2_beg, w2_end); + rl_insert_text(word1); + + rl_point = w1_beg; + rl_delete_text(w1_beg, w1_end); + rl_insert_text(word2); + + rl_point = w2_end; + + rl_end_undo_group(); + libc::free(word1 as *mut c_void); + libc::free(word2 as *mut c_void); + } + return 0; +} + +fn check_redir(mut ti: libc::c_int) -> libc::c_int { + let mut this_char: libc::c_int = 0; + let mut prev_char: libc::c_int = 0; + unsafe { + this_char = *rl_line_buffer.offset(ti as isize) as libc::c_int; + prev_char = if ti > 0 as libc::c_int { + *rl_line_buffer.offset((ti - 1 as libc::c_int) as isize) as libc::c_int + } else { + 0 as libc::c_int + }; + + if this_char == '&' as i32 && (prev_char == '<' as i32 || prev_char == '>' as i32) + || this_char == '|' as i32 && prev_char == '>' as i32 + { + return 1 as libc::c_int; + } else { + if this_char == '{' as i32 && prev_char == '$' as i32 { + return 1 as libc::c_int; + } else { + if char_is_quoted(rl_line_buffer, ti) != 0 { + return 1 as libc::c_int; + } + } + } + } + return 0 as libc::c_int; +} + +fn find_cmd_start(mut start: libc::c_int) -> libc::c_int { + let mut s: libc::c_int = 0; + let mut os: libc::c_int = 0; + let mut ns: libc::c_int = 0; + os = 0 as libc::c_int; + unsafe { + loop { + s = skip_to_delim( + rl_line_buffer, + os, + b";|&{(`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int | 0x100 as libc::c_int, + ); + if !(s <= start && *rl_line_buffer.offset(s as isize) as libc::c_int != 0) { + break; + } + if s > 0 as libc::c_int + && *rl_line_buffer.offset(s as isize) as libc::c_int == '|' as i32 + && *rl_line_buffer.offset((s - 1 as libc::c_int) as isize) as libc::c_int + == '>' as i32 + { + ns = skip_to_delim( + rl_line_buffer, + s + 1 as libc::c_int, + b";|&{(`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int | 0x100 as libc::c_int, + ); + if ns > start + || *rl_line_buffer.offset(ns as isize) as libc::c_int == 0 as libc::c_int + { + return os; + } + os = ns + 1 as libc::c_int; + } else { + if s >= os && *rl_line_buffer.offset(s as isize) as libc::c_int == '{' as i32 { + let mut pc: libc::c_int = 0; + let mut nc: libc::c_int = 0; + pc = if s > os { s - 1 as libc::c_int } else { os }; + while pc > os + && (*rl_line_buffer.offset(pc as isize) as libc::c_int == ' ' as i32 + || *rl_line_buffer.offset(pc as isize) as libc::c_int == '\t' as i32) + { + pc -= 1; + } + nc = *rl_line_buffer.offset((s + 1 as libc::c_int) as isize) as libc::c_int; + if pc > os + && (*rl_line_buffer.offset((s - 1 as libc::c_int) as isize) as libc::c_int + == '{' as i32 + || (libc::strchr( + b";|&{(`\0" as *const u8 as *const libc::c_char, + *rl_line_buffer.offset(pc as isize) as libc::c_int, + )) + .is_null()) + || *sh_syntaxtab + .as_mut_ptr() + .offset(nc as libc::c_uchar as isize) + & 0x2 as libc::c_int + == 0 as libc::c_int + { + ns = skip_to_delim( + rl_line_buffer, + s + 1 as libc::c_int, + b";|&{(`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int | 0x100 as libc::c_int, + ); + if ns > start + || *rl_line_buffer.offset(ns as isize) as libc::c_int + == 0 as libc::c_int + { + return os; + } + os = ns + 1 as libc::c_int; + continue; + } + } + os = s + 1 as libc::c_int; + } + } + } + return os; +} + +fn find_cmd_end(mut end: libc::c_int) -> libc::c_int { + let mut e: libc::c_int = 0; + + e = unsafe { + skip_to_delim( + rl_line_buffer, + end, + COMMAND_SEPARATORS!(), + SD_NOJMP as libc::c_int | SD_COMPLETE as libc::c_int, + ) + }; + return e; +} +fn find_cmd_name( + mut start: libc::c_int, + mut sp: *mut libc::c_int, + mut ep: *mut libc::c_int, +) -> *mut libc::c_char { + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: libc::c_int = 0; + let mut e: libc::c_int = 0; + unsafe { + s = start; + while whitespace!(*rl_line_buffer.offset(s as isize)) { + s += 1; + } + e = skip_to_delim( + rl_line_buffer, + s, + b"()<>;&| \t\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int | 0x100 as libc::c_int, + ); + name = substring(rl_line_buffer, s, e); + if !sp.is_null() { + *sp = s; + } + if !ep.is_null() { + *ep = e; + } + } + return name; +} + +static mut prog_complete_matches: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; + +fn prog_complete_return( + mut text: *const libc::c_char, + mut matchnum: libc::c_int, +) -> *mut libc::c_char { + static mut ind: libc::c_int = 0; + unsafe { + if matchnum == 0 as libc::c_int { + ind = 0 as libc::c_int; + } + + if prog_complete_matches.is_null() + || (*prog_complete_matches.offset(ind as isize)).is_null() + { + return 0 as *mut c_void as *mut libc::c_char; + } + let fresh10 = ind; + ind = ind + 1; + return *prog_complete_matches.offset(fresh10 as isize); + } +} + +fn invalid_completion(mut text: *const libc::c_char, mut ind: libc::c_int) -> libc::c_int { + let mut pind: libc::c_int = 0; + unsafe { + if ind > 0 as libc::c_int + && *rl_line_buffer.offset(ind as isize) as libc::c_int == '(' as i32 + && member!( + rl_line_buffer.offset((ind - 1 as libc::c_int) as isize), + b"$<>\0" as *const u8 as *const libc::c_char + ) + { + return 0 as libc::c_int; + } + pind = ind - 1 as libc::c_int; + while pind > 0 as libc::c_int && whitespace!(*rl_line_buffer.offset(pind as isize)) { + pind -= 1; + } + if ind >= 0 + && pind <= 0 + && *rl_line_buffer.offset(ind as isize) as libc::c_int == '(' as i32 + { + return 0; + } + if ind > 0 + && *rl_line_buffer.offset(ind as isize) as libc::c_int == '(' as i32 + && member!(rl_line_buffer.offset(pind as isize), COMMAND_SEPARATORS!()) + { + return 1 as libc::c_int; + } + } + return 0 as libc::c_int; +} + +fn attempt_shell_completion( + mut text: *const libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, +) -> *mut *mut libc::c_char { + let mut in_command_position: libc::c_int = 0; + let mut ti: libc::c_int = 0; + let mut qc: libc::c_int = 0; + let mut dflags: libc::c_int = 0; + let mut matches: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut command_separator_chars: *mut libc::c_char = 0 as *mut libc::c_char; + let mut have_progcomps: libc::c_int = 0; + let mut was_assignment: libc::c_int = 0; + let mut iw_compspec: *mut COMPSPEC = 0 as *mut COMPSPEC; + unsafe { + command_separator_chars = COMMAND_SEPARATORS!(); + matches = 0 as *mut *mut libc::c_char; + + rl_ignore_some_completions_function = Some(filename_completion_ignore); + + rl_filename_quote_characters = default_filename_quote_characters; + set_filename_bstab(rl_filename_quote_characters); + + set_directory_hook(); + rl_filename_stat_hook = Some(bash_filename_stat_hook); + rl_sort_completion_matches = 1; + + ti = start - 1 as libc::c_int; + qc = -(1 as libc::c_int); + + while ti > -(1 as libc::c_int) && whitespace!(rl_line_buffer.offset(ti as isize)) { + ti -= 1; + } + + if ti >= 0 + && (*rl_line_buffer.offset(ti as isize) as libc::c_int == '"' as i32 + || *rl_line_buffer.offset(ti as isize) as libc::c_int == '\'' as i32) + { + qc = *rl_line_buffer.offset(ti as isize) as libc::c_int; + ti -= 1; + while ti > -(1 as libc::c_int) && whitespace!(rl_line_buffer.offset(ti as isize)) { + ti -= 1; + } + } + + in_command_position = 0; + if ti < 0 { + if current_prompt_string == ps1_prompt { + in_command_position += 1; + } else if parser_in_command_position() != 0 { + in_command_position += 1; + } + } else if member!(rl_line_buffer.offset(ti as isize), command_separator_chars) { + in_command_position += 1; + if check_redir(ti) == 1 as libc::c_int { + in_command_position = 0 as libc::c_int; + } + } + + if in_command_position != 0 && invalid_completion(text, ti) != 0 { + rl_attempted_completion_over = 1; + return 0 as *mut *mut libc::c_char; + } + + if in_command_position != 0 + && ti >= 0 + && *rl_line_buffer.offset(ti as isize) as libc::c_int == '`' as i32 + && *text as libc::c_int != '`' as i32 + && unclosed_pair( + rl_line_buffer, + end, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 as libc::c_int + { + in_command_position = 0; + } + if *text as libc::c_int == '`' as i32 + && rl_completion_quote_character != '\'' as i32 + && (in_command_position != 0 + || unclosed_pair( + rl_line_buffer, + start, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) != 0 + && unclosed_pair( + rl_line_buffer, + end, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) != 0) + { + matches = rl_completion_matches(text, Some(command_subst_completion_function)); + } + have_progcomps = + (prog_completion_enabled != 0 && progcomp_size() > 0 as libc::c_int) as libc::c_int; + iw_compspec = progcomp_search(INITIALWORD!()); + if matches.is_null() + && (in_command_position == 0 + || *text.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + || in_command_position != 0 && !iw_compspec.is_null()) + && current_prompt_string == ps1_prompt + { + let mut s: libc::c_int = 0; + let mut e: libc::c_int = 0; + let mut s1: libc::c_int = 0; + let mut e1: libc::c_int = 0; + let mut os: libc::c_int = 0; + let mut foundcs: libc::c_int = 0; + let mut n: *mut libc::c_char = 0 as *mut libc::c_char; + + if !prog_complete_matches.is_null() { + libc::free(prog_complete_matches as *mut c_void); + } + prog_complete_matches = 0 as *mut *mut libc::c_char; + + os = start; + n = 0 as *mut libc::c_char; + was_assignment = 0 as libc::c_int; + s = find_cmd_start(os); + e = find_cmd_end(end); + + loop { + if s > rl_end { + s = e1; + s1 = s; + break; + } else if was_assignment != 0 && s > rl_point { + s = e1; + s1 = s; + break; + } + + FREE!(n); + n = find_cmd_name(s, &mut s1, &mut e1); + s = e1 + 1; + was_assignment = assignment(n, 0 as libc::c_int); + if !(was_assignment != 0) { + break; + } + } + + s = s1; + if start == 0 + && end == 0 + && e != 0 + && *text.offset(0 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + foundcs = 0; + } else if start == end && start == s1 && e != 0 && e1 > end { + foundcs = 0; + } else if e == 0 + && e == s + && *text.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + && have_progcomps != 0 + { + prog_complete_matches = + programmable_completions(EMPTYCMD!(), text, s, e, &mut foundcs); + } else if start == end + && *text.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + && s1 > start + && whitespace!(rl_line_buffer.offset(start as isize)) + { + foundcs = 0; + } else if e > s + && was_assignment == 0 as libc::c_int + && e1 == end + && *rl_line_buffer.offset(e as isize) as libc::c_int == 0 as libc::c_int + && whitespace!(rl_line_buffer.offset((e - 1 as libc::c_int) as isize)) + { + foundcs = 0; + in_command_position = (s == start && STREQ!(n, text)) as i32; + } else if e > s && was_assignment == 0 && have_progcomps != 0 { + prog_complete_matches = programmable_completions(n, text, s, e, &mut foundcs); + + in_command_position = + (s == start && (!iw_compspec.is_null() || STREQ!(n, text))) as libc::c_int; + if !iw_compspec.is_null() && in_command_position != 0 { + foundcs = 0; + } + } else if s >= e + && *n.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + && *text.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + && start > 0 + && was_assignment == 0 + && member!( + rl_line_buffer.offset((start - 1 as libc::c_int).try_into().unwrap()), + COMMAND_SEPARATORS!() + ) + { + foundcs = 0 as libc::c_int; + in_command_position = 1 as libc::c_int; + } else if s >= e + && *n.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + && *text.offset(0 as isize) as libc::c_int == '\u{0}' as i32 + && start > 0 as libc::c_int + { + foundcs = 0; + in_command_position += was_assignment; + } else if s == start && e == end && STREQ!(n, text) && start > 0 as libc::c_int { + foundcs = 0; + in_command_position = 1; + } else { + foundcs = 0; + } + if in_command_position != 0 + && have_progcomps != 0 + && foundcs == 0 as libc::c_int + && !iw_compspec.is_null() + { + prog_complete_matches = + programmable_completions(INITIALWORD!(), text, s, e, &mut foundcs); + } + + FREE!(n); + + if foundcs != 0 { + pcomp_set_readline_variables(foundcs, 1 as libc::c_int); + matches = rl_completion_matches(text, Some(prog_complete_return)); + if foundcs & COPT_DEFAULT as libc::c_int == 0 { + rl_attempted_completion_over = 1; + } + if !matches.is_null() || foundcs & COPT_BASHDEFAULT as libc::c_int == 0 { + return matches; + } + } + } + if matches.is_null() { + dflags = 0; + if in_command_position != 0 { + dflags |= DEFCOMP_CMDPOS!(); + } + matches = bash_default_completion(text, start, end, qc, dflags); + } + } + return matches; +} + +#[no_mangle] +pub fn bash_default_completion( + mut text: *const libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, + mut qc: libc::c_int, + mut compflags: libc::c_int, +) -> *mut *mut libc::c_char { + let mut matches: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + matches = 0 as *mut c_void as *mut *mut libc::c_char; + unsafe { + if *text as libc::c_int == '$' as i32 { + if qc != '\'' as i32 && *text.offset(1 as isize) as libc::c_int == '(' as i32 { + matches = rl_completion_matches(text, Some(command_subst_completion_function)); + } else { + matches = rl_completion_matches(text, Some(variable_completion_function)); + if !matches.is_null() + && !(*matches.offset(0 as isize)).is_null() + && (*matches.offset(1 as isize)).is_null() + { + t = savestring!(*matches.offset(0 as libc::c_int as isize)); + bash_filename_stat_hook(&mut t); + if file_isdir(t) != 0 { + rl_completion_append_character = '/' as i32; + } + libc::free(t as *mut c_void); + } + } + } + if matches.is_null() + && *text as libc::c_int == '~' as i32 + && (mbschr(text, '/' as i32)).is_null() + { + rl_completion_matches( + text, + Some(std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_username_completion_function)), + ); + } + + if matches.is_null() + && perform_hostname_completion != 0 + && *text as libc::c_int == '@' as i32 + { + matches = rl_completion_matches( + text, + Some( + hostname_completion_function + as fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + ), + ); + } + + if matches.is_null() && compflags & DEFCOMP_CMDPOS!() != 0 { + if no_empty_command_completion != 0 + && end == start + && *text.offset(0 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + matches = 0 as *mut *mut libc::c_char; + rl_ignore_some_completions_function = Some(bash_ignore_everything); + } else { + dot_in_path = 0; + matches = rl_completion_matches(text, Some(command_word_completion_function)); + if matches.is_null() { + rl_ignore_some_completions_function = Some(bash_ignore_filenames); + } else if (*matches.offset(1 as libc::c_int as isize)).is_null() + && CMD_IS_DIR!(*matches.offset(0 as isize)) + && dot_in_path == 0 + { + rl_completion_suppress_append = 1; + rl_filename_completion_desired = 0; + } else if !(*matches.offset(0 as isize)).is_null() + && !(*matches.offset(1 as isize)).is_null() + && STREQ!(*matches.offset(0 as isize), *matches.offset(1 as isize)) + && CMD_IS_DIR!(*matches.offset(0 as isize)) + { + rl_completion_suppress_append = 1 as libc::c_int; + rl_filename_completion_desired = 0 as libc::c_int; + } + } + } + if matches.is_null() && completion_glob_pattern(text as *mut libc::c_char) != 0 { + matches = rl_completion_matches(text, Some(glob_complete_word)); + + if !matches.is_null() + && !(*matches.offset(1 as isize)).is_null() + && rl_completion_type == '\t' as i32 + { + strvec_dispose(matches); + matches = 0 as *mut *mut libc::c_char; + } else if !matches.is_null() + && !(*matches.offset(1 as libc::c_int as isize)).is_null() + && rl_completion_type == '!' as i32 + { + rl_completion_suppress_append = 1 as libc::c_int; + rl_filename_completion_desired = 0 as libc::c_int; + } + } + } + return matches; +} + +fn bash_command_name_stat_hook(mut name: *mut *mut libc::c_char) -> libc::c_int { + let mut cname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if absolute_program(*name) != 0 { + return bash_filename_stat_hook(name); + } + cname = *name; + result = search_for_command(cname, 0 as libc::c_int); + if !result.is_null() { + *name = result; + return 1; + } + } + return 0; +} + +fn executable_completion( + mut filename: *const libc::c_char, + mut searching_path: libc::c_int, +) -> libc::c_int { + let mut f: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + unsafe { + f = savestring!(filename); + + bash_directory_completion_hook(&mut f); + + r = if searching_path != 0 { + executable_file(f) + } else { + executable_or_directory(f) + }; + libc::free(f as *mut c_void); + } + return r; +} + +// #[macro_export] +// macro_rules! TAB { +// () => { +// '\t' as i32 +// }; +// } + +#[no_mangle] +pub fn command_word_completion_function( + mut hint_text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + let mut match_0: libc::c_int = 0; + let mut freetemp: libc::c_int = 0; + let mut current_block: u64; + static mut hint: *mut libc::c_char = 0 as *mut libc::c_char; + static mut path: *mut libc::c_char = 0 as *mut libc::c_char; + static mut val: *mut libc::c_char = 0 as *mut libc::c_char; + static mut filename_hint: *mut libc::c_char = 0 as *mut c_void as *mut libc::c_char; + static mut fnhint: *mut libc::c_char = 0 as *mut libc::c_char; + static mut dequoted_hint: *mut libc::c_char = 0 as *mut c_void as *mut libc::c_char; + static mut directory_part: *mut libc::c_char = 0 as *mut c_void as *mut libc::c_char; + static mut glob_matches: *mut *mut libc::c_char = 0 as *mut c_void as *mut *mut libc::c_char; + static mut path_index: libc::c_int = 0; + static mut hint_len: libc::c_int = 0; + static mut istate: libc::c_int = 0; + static mut igncase: libc::c_int = 0; + static mut mapping_over: libc::c_int = 0; + static mut local_index: libc::c_int = 0; + static mut searching_path: libc::c_int = 0; + static mut hint_is_dir: libc::c_int = 0; + static mut old_glob_ignore_case: libc::c_int = 0; + static mut globpat: libc::c_int = 0; + static mut varlist: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + static mut alias_list: *mut *mut alias_t = 0 as *mut *mut alias_t; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut cval: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if state == 0 { + rl_filename_stat_hook = Some(bash_command_name_stat_hook); + + if !dequoted_hint.is_null() && dequoted_hint != hint { + libc::free(dequoted_hint as *mut c_void); + } + if !hint.is_null() { + libc::free(hint as *mut c_void); + } + + searching_path = 0; + mapping_over = searching_path; + hint_is_dir = CMD_IS_DIR!(hint_text) as i32; + val = 0 as *mut libc::c_char; + + temp = + rl_variable_value(b"completion-ignore-case\0" as *const u8 as *const libc::c_char); + igncase = RL_BOOLEAN_VARIABLE_VALUE!(temp) as libc::c_int; + + if !glob_matches.is_null() { + libc::free(glob_matches as *mut c_void); + glob_matches = 0 as *mut *mut libc::c_char; + } + + globpat = completion_glob_pattern(hint_text as *mut libc::c_char); + + if globpat != 0 || absolute_program(hint_text) != 0 { + if *hint_text as libc::c_int == '~' as i32 { + hint = bash_tilde_expand(hint_text, 0); + directory_part = savestring!(hint_text); + temp = libc::strchr(directory_part, '/' as i32); + + if !temp.is_null() { + *temp = 0 as libc::c_char; + } else { + libc::free(directory_part as *mut c_void); + directory_part = 0 as *mut libc::c_char; + } + } else if dircomplete_expand != 0 { + hint = savestring!(hint_text); + bash_directory_completion_hook(&mut hint); + } else { + hint = savestring!(hint_text); + } + + dequoted_hint = hint; + + if rl_completion_found_quote != 0 && rl_completion_quote_character == 0 { + dequoted_hint = bash_dequote_filename(hint, 0); + libc::free(hint as *mut c_void); + hint = dequoted_hint; + } + hint_len = libc::strlen(hint) as libc::c_int; + + if !filename_hint.is_null() { + libc::free(filename_hint as *mut c_void); + } + + filename_hint = savestring!(hint); + fnhint = filename_hint; + + istate = 0; + + if globpat != 0 { + mapping_over = 5; + current_block = 6770491532623035343; //globword + } else { + if dircomplete_expand != 0 && path_dot_or_dotdot(filename_hint) != 0 { + dircomplete_expand = 0 as libc::c_int; + set_directory_hook(); + dircomplete_expand = 1 as libc::c_int; + } + mapping_over = 4 as libc::c_int; + current_block = 14702977349412626834; //inner + } + } else { + hint = savestring!(hint_text); + dequoted_hint = hint; + hint_len = libc::strlen(hint) as libc::c_int; + + if rl_completion_found_quote != 0 + && rl_completion_quote_character == 0 as libc::c_int + { + dequoted_hint = bash_dequote_filename(hint, 0 as libc::c_int); + } + + path = get_string_value(b"PATH\0" as *const u8 as *const libc::c_char); + dot_in_path = 0 as libc::c_int; + path_index = dot_in_path; + local_index = 0 as libc::c_int; + + if !varlist.is_null() { + libc::free(varlist as *mut c_void); + } + + varlist = all_visible_functions(); + if !alias_list.is_null() { + libc::free(alias_list as *mut c_void); + } + + alias_list = all_aliases(); + current_block = 1874315696050160458; //Normal + } + } else { + current_block = 1874315696050160458; //Normal + } + + match current_block { + 1874315696050160458 => { + //Normal + let mut current_block_92: u64; + match mapping_over { + 0 => { + while !alias_list.is_null() + && !(*alias_list.offset(local_index as isize)).is_null() + { + let mut alias: *mut libc::c_char = 0 as *mut libc::c_char; + + alias = (**alias_list.offset(local_index as isize)).name; + local_index = local_index + 1; + + if igncase == 0 && STREQN!(alias, hint, hint_len) != 0 { + return savestring!(alias); + } else { + if igncase != 0 + && strncasecmp(alias, hint, hint_len as usize) + == 0 as libc::c_int + { + return savestring!(alias); + } + } + } + local_index = 0; + mapping_over += 1; + + current_block_92 = 12999253957288907134; + } + 1 => { + current_block_92 = 12999253957288907134; + } + 2 => { + current_block_92 = 12548522231677580853; + } + 3 => { + current_block_92 = 5440753863019323004; + } + _ => { + current_block_92 = 5706507068631705000; + } + } + match current_block_92 { + 12999253957288907134 => { + while !((*word_token_alist.as_mut_ptr().offset(local_index as isize)).word) + .is_null() + { + let mut reserved_word: *mut libc::c_char = 0 as *mut libc::c_char; + + reserved_word = + (*word_token_alist.as_mut_ptr().offset(local_index as isize)).word; + local_index = local_index + 1; + + if STREQN!(reserved_word, hint, hint_len) != 0 { + return savestring!(reserved_word); + } + } + local_index = 0 as libc::c_int; + mapping_over += 1; + current_block_92 = 12548522231677580853; + } + _ => {} + } + + match current_block_92 { + 12548522231677580853 => { + while !varlist.is_null() + && !(*varlist.offset(local_index as isize)).is_null() + { + let mut varname: *mut libc::c_char = 0 as *mut libc::c_char; + + varname = (**varlist.offset(local_index as isize)).name; + local_index = local_index + 1; + + if igncase == 0 && STREQN!(varname, hint, hint_len) != 0 { + return savestring!(varname); + } else { + if igncase != 0 + && strncasecmp(varname, hint, hint_len as usize) == 0 + { + return savestring!(varname); + } + } + } + local_index = 0 as libc::c_int; + mapping_over += 1; + current_block_92 = 5440753863019323004; + } + _ => {} + } + match current_block_92 { + 5440753863019323004 => { + while local_index < num_shell_builtins { + if !(((*shell_builtins.offset(local_index as isize)).function) + .is_none() + || (*shell_builtins.offset(local_index as isize)).flags + & BUILTIN_ENABLED as libc::c_int + == 0 as libc::c_int) + { + if STREQN!( + (*shell_builtins.offset(local_index as isize)).name, + hint, + hint_len + ) != 0 + { + let mut i: libc::c_int = local_index; + local_index = local_index + 1; + + return savestring!((*shell_builtins.offset(i as isize)).name); + } + } + + local_index += 1; + } + local_index = 0 as libc::c_int; + mapping_over += 1; + } + _ => {} + } + current_block = 6770491532623035343; + } + _ => {} + } + match current_block { + 6770491532623035343 => { + if globpat != 0 { + if state == 0 as libc::c_int { + glob_ignore_case = igncase; + glob_matches = shell_glob_filename(hint, 0 as libc::c_int); + glob_ignore_case = old_glob_ignore_case; + + if glob_matches == &mut glob_error_return as *mut *mut libc::c_char + || glob_matches.is_null() + { + glob_matches = 0 as *mut *mut libc::c_char; + return 0 as *mut libc::c_char; + } + + local_index = 0; + + if !(*glob_matches.offset(1 as libc::c_int as isize)).is_null() + && rl_completion_type == TAB!() + { + return 0 as *mut libc::c_char; + } + } + + loop { + val = *glob_matches.offset(local_index as isize); + local_index = local_index + 1; + if val.is_null() { + break; + } + if executable_or_directory(val) != 0 { + if *hint_text as libc::c_int == '~' as i32 && !directory_part.is_null() + { + temp = maybe_restore_tilde(val, directory_part); + libc::free(val as *mut c_void); + val = temp; + } + return val; + } + libc::free(val as *mut c_void); + } + glob_ignore_case = old_glob_ignore_case; + return 0 as *mut libc::c_char; + } + + if hint_is_dir != 0 { + hint_is_dir = 0; + return savestring!(hint_text); + } + current_block = 14531478163722833811; + } + _ => {} + } + + loop { + match current_block { + 14702977349412626834 => { + val = rl_filename_completion_function(fnhint, istate); + if mapping_over == 4 as libc::c_int && dircomplete_expand != 0 { + set_directory_hook(); + } + + istate = 1; + + if val.is_null() { + if absolute_program(hint) != 0 { + return 0 as *mut libc::c_char; + } + current_block = 14531478163722833811; + } else { + match_0 = 0; + freetemp = 0; + if absolute_program(hint) != 0 { + if igncase == 0 { + match_0 = (libc::strncmp(val, hint, hint_len as usize) == 0) + as libc::c_int; + } else { + match_0 = + (strncasecmp(val, hint, hint_len as usize) == 0) as libc::c_int; + } + if *hint_text as libc::c_int == '~' as i32 { + temp = maybe_restore_tilde(val, directory_part); + } else { + temp = savestring!(val); + } + freetemp = 1; + } else { + temp = strrchr(val, '/' as i32); + if !temp.is_null() { + temp = temp.offset(1); + if igncase == 0 { + match_0 = (libc::strncmp(temp, hint, hint_len as usize) == 0) + as libc::c_int; + freetemp = match_0; + } else { + match_0 = (strncasecmp(temp, hint, hint_len as usize) + == 0 as libc::c_int) + as libc::c_int; + freetemp = match_0; + } + if match_0 != 0 { + temp = savestring!(temp); + } + } else { + match_0 = 0 as libc::c_int; + freetemp = match_0; + } + } + cval = val; + if match_0 != 0 + && executable_completion( + (if searching_path != 0 { val } else { cval }), + searching_path, + ) != 0 + { + break; + } + if freetemp != 0 { + libc::free(temp as *mut c_void); + } + if cval != val { + libc::free(cval as *mut c_void); + } + libc::free(val as *mut c_void); + current_block = 14702977349412626834; + } + } + _ => { + istate = (val != 0 as *mut libc::c_char) as libc::c_int; + + if istate == 0 { + let mut current_path: *mut libc::c_char = 0 as *mut libc::c_char; + + if path.is_null() + || *path.offset(path_index as isize) as libc::c_int == 0 + || { + current_path = extract_colon_unit(path, &mut path_index); + current_path.is_null() + } + { + return 0 as *mut c_void as *mut libc::c_char; + } + searching_path = 1; + if *current_path as libc::c_int == 0 as libc::c_int { + libc::free(current_path as *mut c_void); + current_path = savestring!(b".\0" as *const u8 as *const libc::c_char); + } + if *current_path as libc::c_int == '~' as i32 { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + t = bash_tilde_expand(current_path, 0 as libc::c_int); + libc::free(current_path as *mut c_void); + current_path = t; + } + + if *current_path.offset(0 as isize) as libc::c_int == '.' as i32 + && *current_path.offset(1 as isize) as libc::c_int == '\u{0}' as i32 + { + dot_in_path = 1; + } + if !fnhint.is_null() && fnhint != filename_hint { + libc::free(fnhint as *mut c_void); + } + if !filename_hint.is_null() { + libc::free(filename_hint as *mut c_void); + } + filename_hint = sh_makepath(current_path, hint, 0); + if !(strpbrk( + filename_hint, + b"\"'\\\0" as *const u8 as *const libc::c_char, + )) + .is_null() + { + fnhint = sh_backslash_quote( + filename_hint, + filename_bstab.as_mut_ptr(), + 0 as libc::c_int, + ); + } else { + fnhint = filename_hint; + } + libc::free(current_path as *mut c_void); + } + current_block = 14702977349412626834; + } + } + } + if cval != val { + libc::free(cval as *mut c_void); + } + libc::free(val as *mut c_void); + val = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + return temp; +} + +fn command_subst_completion_function( + mut text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + static mut matches: *mut *mut libc::c_char = + 0 as *const c_void as *mut c_void as *mut *mut libc::c_char; + static mut orig_start: *const libc::c_char = 0 as *const libc::c_char; + static mut filename_text: *mut libc::c_char = + 0 as *const c_void as *mut c_void as *mut libc::c_char; + static mut cmd_index: libc::c_int = 0; + static mut start_len: libc::c_int = 0; + unsafe { + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + + if state == 0 as libc::c_int { + if !filename_text.is_null() { + libc::free(filename_text as *mut c_void); + } + orig_start = text; + if *text as libc::c_int == '`' as i32 { + text = text.offset(1); + } else if *text as libc::c_int == '$' as i32 + && *text.offset(1 as libc::c_int as isize) as libc::c_int == '(' as i32 + { + text = text.offset(2 as libc::c_int as isize); + } + + rl_completion_suppress_quote = 1 as libc::c_int; + start_len = text.offset_from(orig_start) as libc::c_long as libc::c_int; + filename_text = savestring!(text); + if !matches.is_null() { + libc::free(matches as *mut c_void); + } + + value = filename_text + .offset(libc::strlen(filename_text) as isize) + .offset(-(1 as libc::c_int as isize)); + while value > filename_text { + if whitespace!(*value) || member!(value, COMMAND_SEPARATORS!()) { + break; + } + value = value.offset(-1); + } + + if value <= filename_text { + matches = + rl_completion_matches(filename_text, Some(command_word_completion_function)); + } else { + value = value.offset(1); + start_len = (start_len as libc::c_long + + value.offset_from(filename_text) as libc::c_long) + as libc::c_int; + if whitespace!(value.offset(-(1 as libc::c_int) as isize)) { + matches = rl_completion_matches( + value, + Some(std::mem::transmute::< + unsafe extern "C" fn( + *const libc::c_char, + libc::c_int, + ) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_filename_completion_function)), + ); + } else { + matches = rl_completion_matches(value, Some(command_word_completion_function)); + } + } + + cmd_index = (!matches.is_null() + && !(*matches.offset(0 as isize)).is_null() + && !(*matches.offset(1 as isize)).is_null()) as libc::c_int; + + if !matches.is_null() + && !(*matches.offset(0 as isize)).is_null() + && (*matches.offset(1 as libc::c_int as isize)).is_null() + && test_for_directory(*matches.offset(0 as isize)) != 0 + { + rl_completion_append_character = '/' as i32; + } else { + rl_completion_suppress_append = 1 as libc::c_int; + } + } + + if matches.is_null() || (*matches.offset(cmd_index as isize)).is_null() { + rl_filename_quoting_desired = 0; + return 0 as *mut libc::c_char; + } else { + value = libc::malloc( + (1 + start_len + strlen(*matches.offset(cmd_index as isize)) as i32) as usize, + ) as *mut libc::c_char; + if start_len == 1 { + *value.offset(0 as isize) = *orig_start; + } else { + libc::strncpy( + value, + orig_start, + (start_len as libc::c_ulong).try_into().unwrap(), + ); + } + + libc::strcpy( + value.offset(start_len as isize), + *matches.offset(cmd_index as isize), + ); + + cmd_index += 1; + return value; + }; + } +} + +fn variable_completion_function( + mut text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + static mut varlist: *mut *mut libc::c_char = + 0 as *const c_void as *mut c_void as *mut *mut libc::c_char; + static mut varlist_index: libc::c_int = 0; + static mut varname: *mut libc::c_char = 0 as *const c_void as *mut c_void as *mut libc::c_char; + static mut first_char: libc::c_int = 0; + static mut first_char_loc: libc::c_int = 0; + unsafe { + if state == 0 { + if !varname.is_null() { + libc::free(varname as *mut c_void); + } + + first_char_loc = 0 as libc::c_int; + first_char = *text.offset(0 as isize) as libc::c_int; + + if first_char == '$' as i32 { + first_char_loc += 1; + } + + if *text.offset(first_char_loc as isize) as libc::c_int == '{' as i32 { + first_char_loc += 1; + } + varname = savestring!(text.offset(first_char_loc as isize)); + + if !varlist.is_null() { + strvec_dispose(varlist); + } + + varlist = all_variables_matching_prefix(varname); + varlist_index = 0; + } + + if varlist.is_null() || (*varlist.offset(varlist_index as isize)).is_null() { + return 0 as *mut libc::c_char; + } else { + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + value = libc::malloc( + (4 + libc::strlen(*varlist.offset(varlist_index as isize))) + .try_into() + .unwrap(), + ) as *mut libc::c_char; + + if first_char_loc != 0 { + *value.offset(0 as isize) = first_char as libc::c_char; + if first_char_loc == 2 { + *value.offset(1 as isize) = '{' as i32 as libc::c_char; + } + } + + libc::strcpy( + value.offset(first_char_loc as isize), + *varlist.offset(varlist_index as isize), + ); + if first_char_loc == 2 as libc::c_int { + strcat(value, b"}\0" as *const u8 as *const libc::c_char); + } + + varlist_index += 1; + return value; + }; + } +} + +fn hostname_completion_function( + mut text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + static mut list: *mut *mut libc::c_char = + 0 as *const c_void as *mut c_void as *mut *mut libc::c_char; + static mut list_index: libc::c_int = 0 as libc::c_int; + static mut first_char: libc::c_int = 0; + static mut first_char_loc: libc::c_int = 0; + unsafe { + if state == 0 { + FREE!(list); + + list = 0 as *mut *mut libc::c_char; + + first_char_loc = 0; + first_char = *text as libc::c_int; + + if first_char == '@' as i32 { + first_char_loc += 1; + } + + list = hostnames_matching((text as *mut libc::c_char).offset(first_char_loc as isize)); + list_index = 0 as libc::c_int; + } + + if !list.is_null() && !(*list.offset(list_index as isize)).is_null() { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + t = libc::malloc( + (2 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(*list.offset(list_index as isize))) + as usize, + ) as *mut libc::c_char; + + *t = first_char as libc::c_char; + libc::strcpy( + t.offset(first_char_loc as isize), + *list.offset(list_index as isize), + ); + list_index += 1; + return t; + } + } + return 0 as *mut libc::c_char; +} + +#[no_mangle] +pub fn bash_servicename_completion_function( + mut text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + static mut sname: *mut libc::c_char = 0 as *const c_void as *mut c_void as *mut libc::c_char; + static mut srvent: *mut servent = 0 as *const servent as *mut servent; + static mut snamelen: libc::c_int = 0; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut alist: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut aentry: *mut libc::c_char = 0 as *mut libc::c_char; + let mut afound: libc::c_int = 0; + unsafe { + if state == 0 as libc::c_int { + FREE!(sname); + + sname = savestring!(text); + snamelen = libc::strlen(sname) as libc::c_int; + setservent(0 as libc::c_int); + } + + loop { + srvent = getservent(); + if srvent.is_null() { + break; + } + + afound = 0; + if snamelen == 0 || STREQN!(sname, (*srvent).s_name, snamelen) != 0 { + break; + } + + alist = (*srvent).s_aliases; + while !(*alist).is_null() { + aentry = *alist; + if STREQN!(sname, aentry, snamelen) != 0 { + afound = 1; + break; + } else { + alist = alist.offset(1); + } + } + if afound != 0 { + break; + } + } + + if srvent.is_null() { + endservent(); + return 0 as *mut libc::c_char; + } + value = if afound != 0 { + savestring!(aentry) + } else { + savestring!((*srvent).s_name) + }; + } + return value; +} + +#[no_mangle] +pub fn bash_groupname_completion_function( + mut text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + static mut gname: *mut libc::c_char = 0 as *const c_void as *mut c_void as *mut libc::c_char; + static mut grent: *mut group = 0 as *const group as *mut group; + static mut gnamelen: libc::c_int = 0; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if state == 0 { + FREE!(gname); + + gname = savestring!(text); + gnamelen = libc::strlen(gname) as libc::c_int; + + setgrent(); + } + + loop { + grent = getgrent(); + if grent.is_null() { + break; + } + if gnamelen == 0 || STREQN!(gname, (*grent).gr_name, gnamelen) != 0 { + break; + } + } + if grent.is_null() { + endgrent(); + return 0 as *mut c_void as *mut libc::c_char; + } + value = savestring!((*grent).gr_name); + } + return value; +} + +fn history_expand_line_internal(mut line: *mut libc::c_char) -> *mut libc::c_char { + let mut new_line: *mut libc::c_char = 0 as *mut libc::c_char; + let mut old_verify: libc::c_int = 0; + unsafe { + old_verify = hist_verify; + hist_verify = 0 as libc::c_int; + new_line = pre_process_line(line, 0 as libc::c_int, 0 as libc::c_int); + hist_verify = old_verify; + + return if new_line == line { + savestring!(line) + } else { + new_line + }; + } +} +fn cleanup_expansion_error() { + let mut to_free: *mut libc::c_char = 0 as *mut libc::c_char; + let mut old_verify: libc::c_int = 0; + unsafe { + old_verify = hist_verify; + hist_verify = 0 as libc::c_int; + + fprintf(rl_outstream, b"\r\n\0" as *const u8 as *const libc::c_char); + to_free = pre_process_line(rl_line_buffer, 1, 0); + + hist_verify = old_verify; + + if to_free != rl_line_buffer { + FREE!(to_free); + } + putc('\r' as i32, rl_outstream); + rl_forced_update_display(); + } +} + +fn maybe_make_readline_line(mut new_line: *mut libc::c_char) { + unsafe { + if !new_line.is_null() && libc::strcmp(new_line, rl_line_buffer) != 0 as libc::c_int { + rl_point = rl_end; + rl_add_undo(UNDO_BEGIN!(), 0, 0, 0 as *mut libc::c_char); + rl_delete_text(0 as libc::c_int, rl_point); + rl_mark = 0 as libc::c_int; + rl_end = rl_mark; + rl_point = rl_end; + rl_insert_text(new_line); + rl_add_undo(UNDO_END!(), 0, 0, 0 as *mut libc::c_char); + } + } +} + +fn set_up_new_line(mut new_line: *mut libc::c_char) { + let mut old_point: libc::c_int = 0; + let mut at_end: libc::c_int = 0; + unsafe { + old_point = rl_point; + at_end = (rl_point == rl_end) as libc::c_int; + + maybe_make_readline_line(new_line); + libc::free(new_line as *mut c_void); + + if at_end != 0 { + rl_point = rl_end; + } else if old_point < rl_end { + rl_point = old_point; + if !whitespace!(*rl_line_buffer.offset(rl_point as isize)) { + rl_forward_word(1 as libc::c_int, 0 as libc::c_int); + } + } + } +} + +fn alias_expand_line(mut count: libc::c_int, mut ignore: libc::c_int) -> libc::c_int { + let mut new_line: *mut libc::c_char = 0 as *mut libc::c_char; + new_line = unsafe { alias_expand(rl_line_buffer) }; + if !new_line.is_null() { + set_up_new_line(new_line); + return 0; + } else { + cleanup_expansion_error(); + return 1; + }; +} + +fn history_expand_line(mut count: libc::c_int, mut ignore: libc::c_int) -> libc::c_int { + let mut new_line: *mut libc::c_char = 0 as *mut libc::c_char; + + new_line = unsafe { history_expand_line_internal(rl_line_buffer) }; + + if !new_line.is_null() { + set_up_new_line(new_line); + return 0; + } else { + cleanup_expansion_error(); + return 1; + }; +} + +fn tcsh_magic_space(mut count: libc::c_int, mut ignore: libc::c_int) -> libc::c_int { + let mut dist_from_end: libc::c_int = 0; + let mut old_point: libc::c_int = 0; + unsafe { + old_point = rl_point; + dist_from_end = rl_end - rl_point; + + if history_expand_line(count, ignore) == 0 { + rl_point = if old_point == 0 { + old_point + } else { + rl_end - dist_from_end + }; + rl_insert(1, ' ' as i32); + return 0; + } else { + return 1; + }; + } +} + +fn history_and_alias_expand_line(mut count: libc::c_int, mut ignore: libc::c_int) -> libc::c_int { + let mut new_line: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + new_line = 0 as *mut libc::c_char; + new_line = history_expand_line_internal(rl_line_buffer); + + if !new_line.is_null() { + let mut alias_line: *mut libc::c_char = 0 as *mut libc::c_char; + alias_line = alias_expand(new_line); + libc::free(new_line as *mut c_void); + new_line = alias_line; + } + } + if !new_line.is_null() { + set_up_new_line(new_line); + return 0; + } else { + cleanup_expansion_error(); + return 1; + }; +} + +fn shell_expand_line(mut count: libc::c_int, mut ignore: libc::c_int) -> libc::c_int { + let mut new_line: *mut libc::c_char = 0 as *mut libc::c_char; + let mut expanded_string: *mut WordList = 0 as *mut WordList; + let mut w: *mut WordDesc = 0 as *mut WordDesc; + unsafe { + new_line = 0 as *mut libc::c_char; + new_line = history_expand_line_internal(rl_line_buffer); + + if !new_line.is_null() { + let mut alias_line: *mut libc::c_char = 0 as *mut libc::c_char; + alias_line = alias_expand(new_line); + libc::free(new_line as *mut c_void); + new_line = alias_line; + } + if !new_line.is_null() { + let mut old_point: libc::c_int = rl_point; + let mut at_end: libc::c_int = (rl_point == rl_end) as libc::c_int; + + maybe_make_readline_line(new_line); + libc::free(new_line as *mut c_void); + + w = alloc_word_desc(); + let ref mut fresh16 = (*w).word; + (*w).word = savestring!(rl_line_buffer); + (*w).flags = if rl_explicit_arg != 0 { + (W_NOPROCSUB as libc::c_int) | (W_NOCOMSUB as libc::c_int) + } else { + 0 + }; + + expanded_string = expand_word( + w, + if rl_explicit_arg != 0 { + Q_HERE_DOCUMENT!() + } else { + 0 as libc::c_int + }, + ); + dispose_word(w); + + if expanded_string.is_null() { + new_line = libc::malloc(1 as usize) as *mut libc::c_char; + *new_line.offset(0 as isize) = '\u{0}' as i32 as libc::c_char; + } else { + new_line = string_list(expanded_string); + dispose_words(expanded_string); + } + + maybe_make_readline_line(new_line); + libc::free(new_line as *mut c_void); + + if at_end != 0 { + rl_point = rl_end; + } else if old_point < rl_end { + rl_point = old_point; + if !whitespace!(*rl_line_buffer.offset(rl_point as isize)) { + rl_forward_word(1, 0); + } + } + return 0; + } else { + cleanup_expansion_error(); + return 1; + }; + } +} + +static mut fignore: ignorevar = { + let mut init = ignorevar { + varname: b"FIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ignores: 0 as *const ign as *mut ign, + num_ignores: 0, + last_ignoreval: 0 as *mut libc::c_char, + item_func: None, + }; + init +}; + +fn _ignore_completion_names( + mut names: *mut *mut libc::c_char, + mut name_func: Option, +) { + let mut newnames: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut idx: libc::c_int = 0; + let mut nidx: libc::c_int = 0; + let mut oldnames: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut oidx: libc::c_int = 0; + unsafe { + if (*names.offset(1 as isize)).is_null() { + if force_fignore != 0 { + if (Some(name_func.expect("non-null function pointer"))) + .expect("non-null function pointer")( + *names.offset(0 as libc::c_int as isize) + ) == 0 as libc::c_int + //å¯èƒ½ä¼šå‡ºçŽ°é—®é¢˜ + { + libc::free(*names.offset(0 as libc::c_int as isize) as *mut c_void); + let ref mut fresh17 = *names.offset(0 as isize); + *names.offset(0 as isize) = 0 as *mut libc::c_char; + } + } + return; + } + + nidx = 1; + while !(*names.offset(nidx as isize)).is_null() { + nidx += 1; + } + + newnames = strvec_create(nidx + 1); + + if force_fignore == 0 { + oldnames = strvec_create(nidx - 1); + oidx = 0; + } + + *newnames.offset(0 as isize) = *names.offset(0 as isize); + nidx = 1; + idx = nidx; + while !(*names.offset(idx as isize)).is_null() { + if (Some(name_func.expect("non-null function pointer"))) + .expect("non-null function pointer")(*names.offset(idx as isize)) + != 0 + { + *(*newnames).offset(nidx as isize) = *(*names).offset(idx as isize); + nidx = nidx + 1; + } else if force_fignore == 0 { + *(*oldnames).offset(oidx as isize) = *(*names).offset(idx as isize); + oidx = oidx + 1; + } else { + libc::free(*names.offset(idx as isize) as *mut c_void); + } + idx += 1; + } + + *newnames.offset(nidx as isize) = 0 as *mut libc::c_char; + + if nidx == 1 { + if force_fignore != 0 { + libc::free(*names.offset(0 as isize) as *mut c_void); + *names.offset(0 as isize) = 0 as *mut libc::c_char; + } else { + libc::free(oldnames as *mut c_void); + } + libc::free(newnames as *mut c_void); + return; + } + + if force_fignore == 0 { + while oidx != 0 { + oidx -= 1; + libc::free(*oldnames.offset(oidx as isize) as *mut c_void); + } + libc::free(oldnames as *mut c_void); + } + + if nidx == 2 { + libc::free(*names.offset(0 as isize) as *mut c_void); + *names.offset(0 as isize) = *newnames.offset(1 as isize); + *names.offset(1 as isize) = 0 as *mut libc::c_char; + libc::free(newnames as *mut c_void); + return; + } + + nidx = 1; + while !(*newnames.offset(nidx as isize)).is_null() { + *names.offset(nidx as isize) = *newnames.offset(nidx as isize); + nidx += 1; + } + + *names.offset(nidx as isize) = 0 as *mut libc::c_char; + libc::free(newnames as *mut c_void); + } +} + +fn name_is_acceptable(mut name: *const libc::c_char) -> libc::c_int { + let mut p: *mut ign = 0 as *mut ign; + let mut nlen: libc::c_int = 0; + unsafe { + nlen = libc::strlen(name) as libc::c_int; + p = fignore.ignores; + while !((*p).val).is_null() { + if nlen > (*p).len + && (*p).len > 0 + && (*((*p).val).offset(0 as isize) as libc::c_int + == *(&*name.offset((nlen - (*p).len) as isize) as *const libc::c_char) + .offset(0 as isize) as libc::c_int + && libc::strcmp((*p).val, &*name.offset((nlen - (*p).len) as isize)) + == 0 as libc::c_int) + { + return 0; + } + p = p.offset(1); + } + } + return 1 as libc::c_int; +} + +fn filename_completion_ignore(mut names: *mut *mut libc::c_char) -> libc::c_int { + unsafe { + setup_ignore_patterns(&mut fignore); + + if fignore.num_ignores == 0 { + return 0; + } + } + _ignore_completion_names(names, Some(name_is_acceptable)); + return 0; +} + +fn test_for_directory(mut name: *const libc::c_char) -> libc::c_int { + let mut fn_0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + unsafe { + fn_0 = bash_tilde_expand(name, 0); + r = file_isdir(fn_0); + libc::free(fn_0 as *mut c_void); + } + return r; +} + +fn test_for_canon_directory(mut name: *const libc::c_char) -> libc::c_int { + let mut fn_0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + unsafe { + fn_0 = if *name as libc::c_int == '~' as i32 { + bash_tilde_expand(name, 0) + } else { + savestring!(name) + }; + bash_filename_stat_hook(&mut fn_0); + r = file_isdir(fn_0); + libc::free(fn_0 as *mut c_void); + } + return r; +} + +fn bash_ignore_filenames(mut names: *mut *mut libc::c_char) -> libc::c_int { + _ignore_completion_names(names, Some(test_for_directory)); + return 0; +} + +fn bash_progcomp_ignore_filenames(mut names: *mut *mut libc::c_char) -> libc::c_int { + _ignore_completion_names(names, Some(test_for_canon_directory)); + return 0; +} + +fn return_zero(mut name: *const libc::c_char) -> libc::c_int { + return 0; +} + +fn bash_ignore_everything(mut names: *mut *mut libc::c_char) -> libc::c_int { + _ignore_completion_names(names, Some(return_zero)); + return 0; +} + +fn restore_tilde( + mut val: *mut libc::c_char, + mut directory_part: *mut libc::c_char, +) -> *mut libc::c_char { + let mut l: libc::c_int = 0; + let mut vl: libc::c_int = 0; + let mut dl2: libc::c_int = 0; + let mut xl: libc::c_int = 0; + let mut dh2: *mut libc::c_char = 0 as *mut libc::c_char; + let mut expdir: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + vl = libc::strlen(val) as libc::c_int; + dh2 = if !directory_part.is_null() { + bash_dequote_filename(directory_part, 0) + } else { + 0 as *mut libc::c_char + }; + bash_directory_expansion(&mut dh2); + dl2 = libc::strlen(dh2) as libc::c_int; + + expdir = bash_tilde_expand(directory_part, 0); + xl = libc::strlen(expdir) as libc::c_int; + if *directory_part as libc::c_int == '~' as i32 && STREQ!(directory_part, expdir) { + v = mbschr(val, '/' as i32); + vl = STRLEN!(v) as libc::c_int; + ret = libc::malloc(((xl + vl + 2 as libc::c_int) as size_t).try_into().unwrap()) + as *mut libc::c_char; + libc::strcpy(ret, directory_part); + if !v.is_null() && *v as libc::c_int != 0 { + libc::strcpy(ret.offset(xl as isize), v); + } + + libc::free(dh2 as *mut c_void); + libc::free(expdir as *mut c_void); + return ret; + } + + libc::free(expdir as *mut c_void); + + l = vl - xl + 1; + if l <= 0 { + libc::free(dh2 as *mut c_void); + return savestring!(val); + } + + ret = libc::malloc(((dl2 + 2 as libc::c_int + l) as size_t).try_into().unwrap()) + as *mut libc::c_char; + libc::strcpy(ret, dh2); + libc::strcpy(ret.offset(dl2 as isize), val.offset(xl as isize)); + + libc::free(dh2 as *mut c_void); + } + return ret; +} + +fn maybe_restore_tilde( + mut val: *mut libc::c_char, + mut directory_part: *mut libc::c_char, +) -> *mut libc::c_char { + let mut save: rl_icppfunc_t = None; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + save = if unsafe { dircomplete_expand == 0 as libc::c_int } { + save_directory_hook() + } else { + None + }; + ret = restore_tilde(val, directory_part); + if save.is_some() { + restore_directory_hook(save); + } + return ret; +} + +fn bash_directory_expansion(mut dirname: *mut *mut libc::c_char) { + let mut d: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nd: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + d = savestring!(*dirname); + if rl_directory_rewrite_hook.is_some() + && (rl_directory_rewrite_hook.expect("non-null function pointer"))(&mut d) != 0 + { + libc::free(*dirname as *mut c_void); + *dirname = d; + } else if rl_directory_completion_hook.is_some() + && (rl_directory_completion_hook.expect("non-null function pointer"))(&mut d) != 0 + { + libc::free(*dirname as *mut c_void); + *dirname = d; + } else if rl_completion_found_quote != 0 { + nd = bash_dequote_filename(d, rl_completion_quote_character); + libc::free(*dirname as *mut c_void); + libc::free(d as *mut c_void); + *dirname = nd; + } + } +} + +fn bash_filename_rewrite_hook( + mut fname: *mut libc::c_char, + mut fnlen: libc::c_int, +) -> *mut libc::c_char { + let mut conv: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + conv = fnx_fromfs(fname, fnlen as size_t); + if conv != fname { + conv = savestring!(conv); + } + } + return conv; +} + +#[no_mangle] +pub fn set_directory_hook() { + unsafe { + if dircomplete_expand != 0 { + rl_directory_completion_hook = + Some(bash_directory_completion_hook as fn(*mut *mut libc::c_char) -> libc::c_int); + rl_directory_rewrite_hook = None; + } else { + rl_directory_rewrite_hook = + Some(bash_directory_completion_hook as fn(*mut *mut libc::c_char) -> libc::c_int); + rl_directory_completion_hook = None; + }; + } +} + +fn save_directory_hook() -> rl_icppfunc_t { + let mut ret: rl_icppfunc_t = None; + unsafe { + if dircomplete_expand != 0 { + ret = rl_directory_completion_hook; + rl_directory_completion_hook = + ::std::mem::transmute::<*mut c_void, rl_icppfunc_t>(0 as *mut c_void); + } else { + ret = rl_directory_rewrite_hook; + rl_directory_rewrite_hook = + ::std::mem::transmute::<*mut c_void, rl_icppfunc_t>(0 as *mut c_void); + } + } + return ret; +} + +fn restore_directory_hook(mut hookf: rl_icppfunc_t) { + unsafe { + if dircomplete_expand != 0 { + rl_directory_completion_hook = hookf; + } else { + rl_directory_rewrite_hook = hookf; + }; + } +} + +fn directory_exists( + mut dirname: *const libc::c_char, + mut should_dequote: libc::c_int, +) -> libc::c_int { + let mut new_dirname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut dirlen: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut sb: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + unsafe { + new_dirname = if should_dequote != 0 { + bash_dequote_filename(dirname as *mut libc::c_char, rl_completion_quote_character) + } else { + savestring!(dirname) + }; + + dirlen = STRLEN!(new_dirname); + if *new_dirname.offset((dirlen - 1 as libc::c_int) as isize) as libc::c_int == '/' as i32 { + *new_dirname.offset((dirlen - 1 as libc::c_int) as isize) = + '\u{0}' as i32 as libc::c_char; + } + r = (lstat(new_dirname, &mut sb) == 0) as libc::c_int; + libc::free(new_dirname as *mut c_void); + } + return r; +} + +fn bash_filename_stat_hook(mut dirname: *mut *mut libc::c_char) -> libc::c_int { + let mut local_dirname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut new_dirname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut should_expand_dirname: libc::c_int = 0; + let mut return_value: libc::c_int = 0; + let mut global_nounset: libc::c_int = 0; + let mut wl: *mut WordList = 0 as *mut WordList; + unsafe { + local_dirname = *dirname; + return_value = 0; + should_expand_dirname = return_value; + t = mbschr(local_dirname, '$' as i32); + if !t.is_null() { + should_expand_dirname = '$' as i32; + } else { + t = mbschr(local_dirname, '`' as i32); + if !t.is_null() { + should_expand_dirname = '`' as i32; + } + } + if should_expand_dirname != 0 && directory_exists(local_dirname, 0 as libc::c_int) != 0 { + should_expand_dirname = 0 as libc::c_int; + } + + if should_expand_dirname != 0 { + new_dirname = savestring!(local_dirname); + + global_nounset = unbound_vars_is_error; + unbound_vars_is_error = 0 as libc::c_int; + wl = expand_prompt_string( + new_dirname, + 0 as libc::c_int, + W_NOCOMSUB as libc::c_int | W_NOPROCSUB as libc::c_int | W_COMPLETE as libc::c_int, + ); + unbound_vars_is_error = global_nounset; + if !wl.is_null() { + libc::free(new_dirname as *mut c_void); + new_dirname = string_list(wl); + + if !new_dirname.is_null() && *new_dirname as libc::c_int != 0 { + libc::free(local_dirname as *mut c_void); + *dirname = new_dirname; + local_dirname = *dirname; + return_value = (STREQ!(local_dirname, *dirname) as libc::c_int + == 0 as libc::c_int) as libc::c_int; + } else { + libc::free(new_dirname as *mut c_void); + } + dispose_words(wl); + } else { + libc::free(new_dirname as *mut c_void); + } + } + + if no_symbolic_links == 0 as libc::c_int + && (*local_dirname.offset(0 as isize) as libc::c_int != '.' as i32 + || *local_dirname.offset(1 as isize) as libc::c_int != 0) + { + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp2: *mut libc::c_char = 0 as *mut libc::c_char; + t = get_working_directory( + b"symlink-hook\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + temp1 = make_absolute(local_dirname, t); + libc::free(t as *mut c_void); + temp2 = sh_canonpath(temp1, 0x1 as libc::c_int | 0x2 as libc::c_int); + + if temp2.is_null() { + libc::free(temp1 as *mut c_void); + return return_value; + } + libc::free(local_dirname as *mut c_void); + *dirname = temp2; + libc::free(temp1 as *mut c_void); + } + } + return return_value; +} + +fn bash_directory_completion_hook(mut dirname: *mut *mut libc::c_char) -> libc::c_int { + let mut local_dirname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut new_dirname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut return_value: libc::c_int = 0; + let mut should_expand_dirname: libc::c_int = 0; + let mut nextch: libc::c_int = 0; + let mut closer: libc::c_int = 0; + let mut wl: *mut WordList = 0 as *mut WordList; + unsafe { + closer = 0; + nextch = closer; + should_expand_dirname = nextch; + return_value = should_expand_dirname; + + local_dirname = *dirname; + + t = mbschr(local_dirname, '$' as i32); + if !t.is_null() { + should_expand_dirname = '$' as i32; + nextch = *t.offset(1 as isize) as libc::c_int; + + if nextch == '(' as i32 { + closer = ')' as i32; + } else if nextch == '{' as i32 { + closer = '}' as i32; + } else { + nextch = 0 as libc::c_int; + } + + if closer != 0 { + let mut p: libc::c_int = 0; + let mut delims: [libc::c_char; 2] = [0; 2]; + + delims[0 as usize] = closer as libc::c_char; + delims[1 as usize] = 0 as libc::c_char; + p = skip_to_delim( + t, + 1, + delims.as_mut_ptr(), + SD_NOJMP as libc::c_int | SD_COMPLETE as libc::c_int, + ); + if *t.offset(p as isize) as libc::c_int != closer { + should_expand_dirname = 0 as libc::c_int; + } + } + } else if *local_dirname.offset(0 as isize) as libc::c_int == '~' as i32 { + should_expand_dirname = '~' as i32; + } else { + t = mbschr(local_dirname, '`' as i32); + if !t.is_null() + && unclosed_pair( + local_dirname, + libc::strlen(local_dirname) as libc::c_int, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 as libc::c_int + { + should_expand_dirname = '`' as i32; + } + } + + if should_expand_dirname != 0 && directory_exists(local_dirname, 1 as libc::c_int) != 0 { + should_expand_dirname = 0 as libc::c_int; + } + if should_expand_dirname != 0 { + new_dirname = savestring!(local_dirname); + wl = expand_prompt_string( + new_dirname, + 0 as libc::c_int, + W_NOCOMSUB as libc::c_int | W_NOPROCSUB as libc::c_int | W_COMPLETE as libc::c_int, + ); + + if !wl.is_null() { + *dirname = string_list(wl); + return_value = (STREQ!(local_dirname, *dirname) as libc::c_int == 0 as libc::c_int) + as libc::c_int; + libc::free(local_dirname as *mut c_void); + libc::free(new_dirname as *mut c_void); + dispose_words(wl); + local_dirname = *dirname; + + if !rl_filename_quote_characters.is_null() + && *rl_filename_quote_characters as libc::c_int != 0 + { + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut c: libc::c_int = 0; + i = libc::strlen(default_filename_quote_characters) as libc::c_int; + custom_filename_quote_characters = xrealloc( + custom_filename_quote_characters as *mut c_void, + (i + 1 as libc::c_int) as usize, + ) as *mut libc::c_char; + + j = 0; + i = j; + loop { + c = *default_filename_quote_characters.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if !(c == should_expand_dirname || c == nextch || c == closer) { + let fresh29 = j; + j = j + 1; + *custom_filename_quote_characters.offset(fresh29 as isize) = + c as libc::c_char; + } + i += 1; + } + *custom_filename_quote_characters.offset(j as isize) = + '\u{0}' as i32 as libc::c_char; + rl_filename_quote_characters = custom_filename_quote_characters; + set_filename_bstab(rl_filename_quote_characters); + } + } else { + libc::free(new_dirname as *mut c_void); + libc::free(local_dirname as *mut c_void); + *dirname = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + **dirname = '\u{0}' as i32 as libc::c_char; + return 1 as libc::c_int; + } + } else { + new_dirname = bash_dequote_filename(local_dirname, rl_completion_quote_character); + return_value = ((STREQ!(local_dirname, new_dirname)) as libc::c_int == 0 as libc::c_int) + as libc::c_int; + libc::free(local_dirname as *mut c_void); + *dirname = new_dirname; + local_dirname = *dirname; + } + + if no_symbolic_links == 0 + && (*local_dirname.offset(0 as isize) as libc::c_int != '.' as i32 + || *local_dirname.offset(1 as isize) as libc::c_int != 0) + { + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp2: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len1: libc::c_int = 0; + let mut len2: libc::c_int = 0; + t = get_working_directory( + b"symlink-hook\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + temp1 = make_absolute(local_dirname, t); + libc::free(t as *mut c_void); + temp2 = sh_canonpath( + temp1, + PATH_CHECKDOTDOT!() as libc::c_int | PATH_CHECKEXISTS!() as libc::c_int, + ); + + if temp2.is_null() && dircomplete_spelling != 0 && dircomplete_expand != 0 { + temp2 = dirspell(temp1); + if !temp2.is_null() { + libc::free(temp1 as *mut c_void); + temp1 = temp2; + temp2 = sh_canonpath( + temp1, + PATH_CHECKDOTDOT!() as libc::c_int | PATH_CHECKEXISTS!() as libc::c_int, + ); + return_value |= (temp2 != 0 as *mut libc::c_char) as libc::c_int; + } + } + if temp2.is_null() { + libc::free(temp1 as *mut c_void); + return return_value; + } + len1 = libc::strlen(temp1) as libc::c_int; + if *temp1.offset((len1 - 1) as isize) as libc::c_int == '/' as i32 { + len2 = libc::strlen(temp2) as libc::c_int; + if len2 > 2 as libc::c_int { + temp2 = xrealloc(temp2 as *mut c_void, (len2 + 2 as libc::c_int) as usize) + as *mut libc::c_char; + *temp2.offset(len2 as isize) = '/' as i32 as libc::c_char; + *temp2.offset((len2 + 1) as isize) = '\u{0}' as i32 as libc::c_char; + } + } + if dircomplete_expand_relpath != 0 + || *local_dirname.offset(0 as isize) as libc::c_int != '/' as i32 + && *local_dirname.offset(0 as isize) as libc::c_int != '.' as i32 + && STREQ!(temp1, temp2) as libc::c_int == 0 as libc::c_int + { + return_value |= (STREQ!(local_dirname, temp2) as libc::c_int == 0 as libc::c_int) + as libc::c_int; + } + libc::free(local_dirname as *mut c_void); + *dirname = temp2; + libc::free(temp1 as *mut c_void); + } + } + return return_value; +} + +static mut history_completion_array: *mut *mut libc::c_char = + 0 as *const c_void as *mut c_void as *mut *mut libc::c_char; +static mut harry_size: libc::c_int = 0; +static mut harry_len: libc::c_int = 0; + +fn build_history_completion_array() { + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut hlist: *mut *mut HIST_ENTRY = 0 as *mut *mut HIST_ENTRY; + let mut tokens: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + unsafe { + if harry_size != 0 { + strvec_dispose(history_completion_array); + history_completion_array = 0 as *mut c_void as *mut *mut libc::c_char; + harry_size = 0 as libc::c_int; + harry_len = 0 as libc::c_int; + } + hlist = history_list(); + if !hlist.is_null() { + i = 0 as libc::c_int; + while !(*hlist.offset(i as isize)).is_null() { + i += 1; + } + i -= 1; + while i >= 0 as libc::c_int { + tokens = history_tokenize((**hlist.offset(i as isize)).line); + j = 0 as libc::c_int; + while !tokens.is_null() && !(*tokens.offset(j as isize)).is_null() { + if harry_len + 2 as libc::c_int > harry_size { + harry_size += 10 as libc::c_int; + history_completion_array = + strvec_resize(history_completion_array, harry_size); + } + + *history_completion_array.offset(harry_len as isize) = + *tokens.offset(j as isize); + harry_len = harry_len + 1; + *history_completion_array.offset(harry_len as isize) = 0 as *mut libc::c_char; + + j += 1; + } + libc::free(tokens as *mut c_void); + i -= 1; + } + + if dabbrev_expand_active == 0 { + qsort( + history_completion_array as *mut c_void, + harry_len as usize, + ::std::mem::size_of::<*mut libc::c_char>() as usize, + ::std::mem::transmute::< + unsafe extern "C" fn(*mut *mut libc::c_char, *mut *mut libc::c_char) -> i32, + Option i32>, + >(strvec_strcmp), + ); + } + } + } +} + +fn history_completion_generator( + mut hint_text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + static mut local_index: libc::c_int = 0; + static mut len: libc::c_int = 0; + static mut text: *const libc::c_char = 0 as *const libc::c_char; + unsafe { + if state == 0 { + if dabbrev_expand_active != 0 { + rl_completion_suppress_append = 1; + } + local_index = 0; + build_history_completion_array(); + text = hint_text; + len = libc::strlen(text) as libc::c_int; + } + + while !history_completion_array.is_null() + && !(*history_completion_array.offset(local_index as isize)).is_null() + { + let local_index_temp = local_index; //local_index_temp 临时å˜é‡ + local_index = local_index + 1; + if libc::strncmp( + text, + *history_completion_array.offset(local_index_temp as isize), + len as usize, + ) == 0 as libc::c_int + { + return savestring!(*history_completion_array.offset((local_index - 1) as isize)); + } + } + } + return 0 as *mut libc::c_char; +} + +fn dynamic_complete_history(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut r: libc::c_int = 0; + let mut orig_func: Option = None; + let mut orig_attempt_func: Option = None; + let mut orig_ignore_func: Option = None; + unsafe { + orig_func = rl_completion_entry_function; + orig_attempt_func = rl_attempted_completion_function; + orig_ignore_func = rl_ignore_some_completions_function; + + rl_completion_entry_function = Some(history_completion_generator); + rl_attempted_completion_function = None; + rl_ignore_some_completions_function = Some(filename_completion_ignore); + + if rl_last_func + == ::std::mem::transmute:: libc::c_int>, Option>( + Some(::std::mem::transmute::< + fn(libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(dynamic_complete_history)), + ) + { + r = rl_complete_internal('?' as i32); + } else { + r = rl_complete_internal('\t' as i32); + } + + rl_completion_entry_function = orig_func; + rl_attempted_completion_function = orig_attempt_func; + rl_ignore_some_completions_function = orig_ignore_func; + } + return r; +} + +fn bash_dabbrev_expand(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut r: libc::c_int = 0; + let mut orig_suppress: libc::c_int = 0; + let mut orig_sort: libc::c_int = 0; + let mut orig_func: Option = None; + let mut orig_attempt_func: Option = None; + let mut orig_ignore_func: Option = None; + unsafe { + orig_func = rl_menu_completion_entry_function; + orig_attempt_func = rl_attempted_completion_function; + orig_ignore_func = rl_ignore_some_completions_function; + orig_suppress = rl_completion_suppress_append; + orig_sort = rl_sort_completion_matches; + + rl_menu_completion_entry_function = Some(history_completion_generator); + rl_attempted_completion_function = None; + rl_ignore_some_completions_function = Some(filename_completion_ignore); + rl_filename_completion_desired = 0 as libc::c_int; + rl_completion_suppress_append = 1 as libc::c_int; + rl_sort_completion_matches = 0 as libc::c_int; + + dabbrev_expand_active = 1 as libc::c_int; + if rl_last_func + == ::std::mem::transmute:: libc::c_int>, Option>( + Some(::std::mem::transmute::< + fn(libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(bash_dabbrev_expand)), + ) + { + rl_last_func = Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_menu_complete)); + } + + r = rl_menu_complete(count, key); + dabbrev_expand_active = 0 as libc::c_int; + rl_last_func = ::std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(::std::mem::transmute::< + fn(libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(bash_dabbrev_expand))); + rl_menu_completion_entry_function = orig_func; + rl_attempted_completion_function = orig_attempt_func; + rl_ignore_some_completions_function = orig_ignore_func; + rl_completion_suppress_append = orig_suppress; + rl_sort_completion_matches = orig_sort; + } + return r; +} + +fn bash_complete_username(mut ignore: libc::c_int, mut ignore2: libc::c_int) -> libc::c_int { + unsafe { + return bash_complete_username_internal(rl_completion_mode(::core::mem::transmute::< + Option libc::c_int>, + Option, + >(Some( + ::core::mem::transmute::< + fn(libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(bash_complete_username), + )))); + } +} + +fn bash_possible_username_completions( + mut ignore: libc::c_int, + mut ignore2: libc::c_int, +) -> libc::c_int { + return bash_complete_username_internal('?' as i32); +} + +fn bash_complete_username_internal(mut what_to_do: libc::c_int) -> libc::c_int { + return bash_specific_completion( + what_to_do, + Some(unsafe { + std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_username_completion_function) + }), + ); +} + +fn bash_complete_filename(mut ignore: libc::c_int, mut ignore2: libc::c_int) -> libc::c_int { + unsafe { + return bash_complete_filename_internal(rl_completion_mode(::std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some( + ::std::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + bash_complete_filename, + ), + )))); + } +} + +fn bash_possible_filename_completions( + mut ignore: libc::c_int, + mut ignore2: libc::c_int, +) -> libc::c_int { + return bash_complete_filename_internal('?' as i32); +} + +fn bash_complete_filename_internal(mut what_to_do: libc::c_int) -> libc::c_int { + let mut orig_func: Option = None; + let mut orig_attempt_func: Option = None; + let mut orig_dir_func: rl_icppfunc_t = None; + let mut orig_ignore_func: Option = None; + let mut orig_rl_completer_word_break_characters: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + unsafe { + orig_func = rl_completion_entry_function; + orig_attempt_func = rl_attempted_completion_function; + orig_ignore_func = rl_ignore_some_completions_function; + orig_rl_completer_word_break_characters = rl_completer_word_break_characters; + orig_dir_func = save_directory_hook(); + rl_completion_entry_function = Some(std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_filename_completion_function)); + + rl_completion_entry_function = Some(std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_filename_completion_function)); + rl_attempted_completion_function = None; + rl_ignore_some_completions_function = Some(filename_completion_ignore); + rl_completer_word_break_characters = + b" \t\n\"'\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + + r = rl_complete_internal(what_to_do); + rl_completion_entry_function = orig_func; + rl_attempted_completion_function = orig_attempt_func; + rl_ignore_some_completions_function = orig_ignore_func; + rl_completer_word_break_characters = orig_rl_completer_word_break_characters; + restore_directory_hook(orig_dir_func); + } + return r; +} + +fn bash_complete_hostname(mut ignore: libc::c_int, mut ignore2: libc::c_int) -> libc::c_int { + unsafe { + return bash_complete_hostname_internal(rl_completion_mode(::std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some( + ::std::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + bash_complete_hostname, + ), + )))); + } +} + +fn bash_possible_hostname_completions( + mut ignore: libc::c_int, + mut ignore2: libc::c_int, +) -> libc::c_int { + return bash_complete_hostname_internal('?' as i32); +} + +fn bash_complete_variable(mut ignore: libc::c_int, mut ignore2: libc::c_int) -> libc::c_int { + unsafe { + return bash_complete_variable_internal(rl_completion_mode(::std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some( + ::std::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + bash_complete_variable, + ), + )))); + } +} + +fn bash_possible_variable_completions( + mut ignore: libc::c_int, + mut ignore2: libc::c_int, +) -> libc::c_int { + return bash_complete_variable_internal('?' as i32); +} + +fn bash_complete_command(mut ignore: libc::c_int, mut ignore2: libc::c_int) -> libc::c_int { + unsafe { + return bash_complete_command_internal(rl_completion_mode(::std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some( + ::std::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + bash_complete_command, + ), + )))); + } +} + +fn bash_possible_command_completions( + mut ignore: libc::c_int, + mut ignore2: libc::c_int, +) -> libc::c_int { + return bash_complete_command_internal('?' as i32); +} + +fn bash_complete_hostname_internal(mut what_to_do: libc::c_int) -> libc::c_int { + return bash_specific_completion(what_to_do, Some(hostname_completion_function)); +} + +fn bash_complete_variable_internal(mut what_to_do: libc::c_int) -> libc::c_int { + return bash_specific_completion(what_to_do, Some(variable_completion_function)); +} + +fn bash_complete_command_internal(mut what_to_do: libc::c_int) -> libc::c_int { + return bash_specific_completion(what_to_do, Some(command_word_completion_function)); +} + +fn completion_glob_pattern(mut string: *mut libc::c_char) -> libc::c_int { + unsafe { + return (glob_pattern_p(string) == 1 as libc::c_int) as libc::c_int; + } +} + +static mut globtext: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +static mut globorig: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; + +fn glob_complete_word(mut text: *const libc::c_char, mut state: libc::c_int) -> *mut libc::c_char { + static mut matches: *mut *mut libc::c_char = + 0 as *const c_void as *mut c_void as *mut *mut libc::c_char; + static mut ind: libc::c_int = 0; + let mut glen: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ttext: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if state == 0 { + rl_filename_completion_desired = 1; + if !matches.is_null() { + FREE!(matches); + } + if globorig != globtext { + FREE!(globorig); + } + FREE!(globtext); + + ttext = bash_tilde_expand(text, 0); + if rl_explicit_arg != 0 { + globorig = savestring!(ttext); + glen = libc::strlen(ttext) as libc::c_int; + globtext = libc::malloc((glen + 2 as libc::c_int) as usize) as *mut libc::c_char; + libc::strcpy(globtext, ttext); + *globtext.offset(glen as isize) = '*' as i32 as libc::c_char; + *globtext.offset((glen + 1 as libc::c_int) as isize) = + '\u{0}' as i32 as libc::c_char; + } else { + globorig = savestring!(ttext); + globtext = globorig; + } + if ttext != text as *mut libc::c_char { + libc::free(ttext as *mut c_void); + } + matches = shell_glob_filename(globtext, 0); + if GLOB_FAILED!(matches) { + matches = 0 as *mut *mut libc::c_char; + } + ind = 0; + } + + ret = if !matches.is_null() { + *matches.offset(ind as isize) + } else { + 0 as *mut libc::c_char + }; + ind += 1; + } + return ret; +} + +fn bash_glob_completion_internal(mut what_to_do: libc::c_int) -> libc::c_int { + return bash_specific_completion(what_to_do, Some(glob_complete_word)); +} + +fn bash_glob_quote_filename( + mut s: *mut libc::c_char, + mut rtype: libc::c_int, + mut qcp: *mut libc::c_char, +) -> *mut libc::c_char { + unsafe { + if !globorig.is_null() + && !qcp.is_null() + && *qcp as libc::c_int == '\u{0}' as i32 + && STREQ!(s, globorig) + { + return savestring!(s); + } else { + return bash_quote_filename(s, rtype, qcp); + }; + } +} + +fn bash_glob_complete_word(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut r: libc::c_int = 0; + let mut orig_quoting_function: Option = None; + unsafe { + if rl_editing_mode == EMACS_EDITING_MODE!() { + rl_explicit_arg = 1; + } + orig_quoting_function = rl_filename_quoting_function; + rl_filename_quoting_function = Some(bash_glob_quote_filename); + + r = bash_glob_completion_internal(rl_completion_mode(Some(bash_glob_complete_word))); + + rl_filename_quoting_function = orig_quoting_function; + } + return r; +} + +fn bash_glob_expand_word(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + return bash_glob_completion_internal('*' as i32); +} + +fn bash_glob_list_expansions(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + return bash_glob_completion_internal('?' as i32); +} + +fn bash_specific_completion( + mut what_to_do: libc::c_int, + mut generator: Option, +) -> libc::c_int { + let mut orig_func: Option = None; + let mut orig_attempt_func: Option = None; + let mut orig_ignore_func: Option = None; + let mut r: libc::c_int = 0; + unsafe { + orig_func = rl_completion_entry_function; + orig_attempt_func = rl_attempted_completion_function; + orig_ignore_func = rl_ignore_some_completions_function; + rl_completion_entry_function = generator; + rl_attempted_completion_function = None; + rl_ignore_some_completions_function = orig_ignore_func; + r = rl_complete_internal(what_to_do); + rl_completion_entry_function = orig_func; + rl_attempted_completion_function = orig_attempt_func; + rl_ignore_some_completions_function = orig_ignore_func; + } + return r; +} + +fn bash_vi_complete(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut p: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if rl_point < rl_end && !whitespace!(*rl_line_buffer.offset(rl_point as isize)) { + if !whitespace!(*rl_line_buffer.offset((rl_point + 1) as isize)) { + rl_vi_end_word(1, 'E' as i32); + } + rl_point += 1; + } + + t = 0 as *mut libc::c_char; + if rl_point > 0 { + p = rl_point; + rl_vi_bWord(1, 'B' as i32); + r = rl_point; + rl_point = p; + p = r; + t = substring(rl_line_buffer, p, rl_point); + } + + if !t.is_null() && completion_glob_pattern(t) == 0 { + rl_explicit_arg = 1; + } + FREE!(t); + + if key == '*' as i32 { + r = bash_glob_expand_word(count, key); + } else if key == '=' as i32 { + r = bash_glob_list_expansions(count, key); + } else if key == '\\' as i32 { + r = bash_glob_complete_word(count, key); + } else { + r = rl_complete(0, key); + } + if key == '*' as i32 || key == '\\' as i32 { + rl_vi_start_inserting(key, 1, 1); + } + } + return r; +} + +fn bash_dequote_filename( + mut text: *mut libc::c_char, + mut quote_char: libc::c_int, +) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: libc::c_int = 0; + let mut quoted: libc::c_int = 0; + unsafe { + l = libc::strlen(text) as libc::c_int; + ret = libc::malloc((l + 1 as libc::c_int) as usize) as *mut libc::c_char; + + quoted = quote_char; + p = text; + r = ret; + while !p.is_null() && *p as libc::c_int != 0 { + if *p as libc::c_int == '\\' as i32 { + if quoted == '\'' as i32 { + *r = *p; + r = r.offset(1); + } else if quoted == '"' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*p.offset(1 as libc::c_int as isize) as libc::c_uchar as isize) + & CBSDQUOTE!() + == 0 + { + *r = *p; + r = r.offset(1); + } + + p = p.offset(1); + *r = *p; + r = r.offset(1); + + if *p == '\u{0}' as libc::c_char { + return ret; + } + } else if quoted != 0 && *p as libc::c_int == quoted { + quoted = 0; + } else if quoted == 0 + && (*p as libc::c_int == '\'' as i32 || *p as libc::c_int == '"' as i32) + { + quoted = *p as libc::c_int; + } else { + *r = *p; + r = r.offset(1); + } + + p = p.offset(1); + } + *r = '\u{0}' as i32 as libc::c_char; + } + return ret; +} + +fn quote_word_break_chars(mut text: *mut libc::c_char) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: libc::c_int = 0; + unsafe { + l = libc::strlen(text) as libc::c_int; + ret = libc::malloc( + ((2 as libc::c_int * l + 1 as libc::c_int) as size_t) + .try_into() + .unwrap(), + ) as *mut libc::c_char; + + s = text; + r = ret; + while *s != 0 { + if *s as libc::c_int == '\\' as i32 { + *r = '\\' as i32 as libc::c_char; + r = r.offset(1); + + s = s.offset(1); + *r = *s; + r = r.offset(1); + + if *s as libc::c_int == '\u{0}' as i32 { + break; + } + } else { + if !(mbschr(rl_completer_word_break_characters, *s as libc::c_int)).is_null() { + *r = '\\' as i32 as libc::c_char; + r = r.offset(1); + } + if s == text && *s as libc::c_int == '~' as i32 && file_exists(text) != 0 { + *r = '\\' as i32 as libc::c_char; + r = r.offset(1); + } + *r = *s; + r = r.offset(1); + } + s = s.offset(1); + } + *r = '\u{0}' as i32 as libc::c_char; + } + return ret; +} + +fn set_filename_bstab(mut string: *const libc::c_char) { + unsafe { + let mut s: *const libc::c_char = 0 as *const libc::c_char; + memset( + filename_bstab.as_mut_ptr() as *mut c_void, + 0 as libc::c_int, + ::std::mem::size_of::<[libc::c_char; 256]>() as usize, + ); + s = string; + while !s.is_null() && *s as libc::c_int != 0 { + filename_bstab[*s as libc::c_uchar as usize] = 1 as libc::c_int as libc::c_char; + s = s.offset(1); + } + } +} + +fn bash_quote_filename( + mut s: *mut libc::c_char, + mut rtype: libc::c_int, + mut qcp: *mut libc::c_char, +) -> *mut libc::c_char { + let mut rtext: *mut libc::c_char = 0 as *mut libc::c_char; + let mut mtext: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rlen: libc::c_int = 0; + let mut cs: libc::c_int = 0; + + rtext = 0 as *mut libc::c_char; + unsafe { + cs = completion_quoting_style; + + if *qcp as libc::c_int == '\u{0}' as i32 + && cs == COMPLETE_BSQUOTE!() + && !(mbschr(s, '\n' as i32)).is_null() + { + cs = COMPLETE_SQUOTE!(); + } else if *qcp as libc::c_int == '"' as i32 { + cs = COMPLETE_DQUOTE!(); + } else if *qcp as libc::c_int == '\'' as i32 { + cs = COMPLETE_SQUOTE!(); + } else if *qcp as libc::c_int == '\u{0}' as i32 + && history_expansion != 0 + && cs == COMPLETE_DQUOTE!() + && history_expansion_inhibited == 0 + && !(mbschr(s, '!' as i32)).is_null() + { + cs = COMPLETE_BSQUOTE!(); + } + if *qcp as libc::c_int == '"' as i32 + && history_expansion != 0 + && cs == COMPLETE_DQUOTE!() + && history_expansion_inhibited == 0 + && !(mbschr(s, '!' as i32)).is_null() + { + cs = COMPLETE_BSQUOTE!(); + *qcp = '\u{0}' as i32 as libc::c_char; + } + + mtext = s; + if *mtext.offset(0 as libc::c_int as isize) as libc::c_int == '~' as i32 + && rtype == SINGLE_MATCH as libc::c_int + && cs != COMPLETE_BSQUOTE!() + { + mtext = bash_tilde_expand(s, 0); + } + match cs { + COMPLETE_DQUOTE!() => { + rtext = sh_double_quote(mtext); + } + COMPLETE_SQUOTE!() => { + rtext = sh_single_quote(mtext); + } + COMPLETE_BSQUOTE!() => { + rtext = sh_backslash_quote( + mtext, + if complete_fullquote != 0 { + 0 as *mut libc::c_char + } else { + filename_bstab.as_mut_ptr() + }, + 0 as libc::c_int, + ); + } + _ => {} + } + + if mtext != s { + libc::free(mtext as *mut c_void); + } + + if !rtext.is_null() && cs == COMPLETE_BSQUOTE!() { + mtext = quote_word_break_chars(rtext); + libc::free(rtext as *mut c_void); + rtext = mtext; + } + + if !rtext.is_null() { + rlen = libc::strlen(rtext) as libc::c_int; + ret = libc::malloc((rlen + 1 as libc::c_int) as usize) as *mut libc::c_char; + libc::strcpy(ret, rtext); + } else { + rlen = 1; + ret = libc::malloc(rlen as usize) as *mut libc::c_char; + *ret.offset(0 as isize) = '\u{0}' as i32 as libc::c_char; + } + + if rtype == MULT_MATCH as libc::c_int && cs != COMPLETE_BSQUOTE!() { + *ret.offset((rlen - 1 as libc::c_int) as isize) = '\u{0}' as i32 as libc::c_char; + } + libc::free(rtext as *mut c_void); + } + return ret; +} + +static mut emacs_std_cmd_xmap: Keymap = 0 as *const KEYMAP_ENTRY as *mut KEYMAP_ENTRY; +static mut vi_insert_cmd_xmap: Keymap = 0 as *const KEYMAP_ENTRY as *mut KEYMAP_ENTRY; +static mut vi_movement_cmd_xmap: Keymap = 0 as *const KEYMAP_ENTRY as *mut KEYMAP_ENTRY; + +fn putx(c: libc::c_int) -> libc::c_int { + let mut x: libc::c_int = 0; + unsafe { + x = putc(c, rl_outstream); + } + return x; +} + +fn readline_get_char_offset(mut ind: libc::c_int) -> libc::c_int { + let mut r: libc::c_int = 0; + let mut old_ch: libc::c_int = 0; + + r = ind; + unsafe { + if locale_mb_cur_max > 1 { + old_ch = *rl_line_buffer.offset(ind as isize) as libc::c_int; + *rl_line_buffer.offset(ind as isize) = '\u{0}' as i32 as libc::c_char; + r = MB_STRLEN!(rl_line_buffer); + *rl_line_buffer.offset(ind as isize) = old_ch as libc::c_char; + } + } + return r; +} + +fn readline_set_char_offset(mut ind: libc::c_int, mut varp: *mut libc::c_int) { + let mut i: libc::c_int = 0; + i = ind; + unsafe { + if i > 0 as libc::c_int && locale_mb_cur_max > 1 as libc::c_int { + i = _rl_find_next_mbchar(rl_line_buffer, 0 as libc::c_int, i, 0 as libc::c_int); + } + if i != *varp { + if i > rl_end { + i = rl_end; + } else if i < 0 as libc::c_int { + i = 0 as libc::c_int; + } + *varp = i; + } + } +} + +#[no_mangle] +pub fn bash_execute_unix_command(mut count: libc::c_int, mut key: libc::c_int) -> libc::c_int { + let mut type_0: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut mi: intmax_t = 0; + let mut ps: sh_parser_state_t = sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + let mut cmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ce: *mut libc::c_char = 0 as *mut libc::c_char; + let mut old_ch: libc::c_char = 0; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut ibuf: [libc::c_char; 12] = [0; 12]; + let mut cmd_xmap: Keymap = 0 as *mut KEYMAP_ENTRY; + unsafe { + cmd_xmap = get_cmd_xmap_from_keymap(rl_get_keymap()); + cmd = ::std::mem::transmute::, *mut libc::c_char>( + rl_function_of_keyseq_len( + rl_executing_keyseq, + rl_key_sequence_length as size_t, + cmd_xmap, + &mut type_0, + ), + ); + + if type_0 == ISKMAP as libc::c_int && { + type_0 = (*(cmd as Keymap).offset(ANYOTHERKEY as isize)).Type as libc::c_int; + type_0 == ISMACR as libc::c_int + } { + cmd = ::core::mem::transmute::, *mut libc::c_char>( + (*(cmd as Keymap).offset(ANYOTHERKEY as isize)).function, + ); + } + + if cmd.is_null() || type_0 != ISMACR as libc::c_int { + rl_crlf(); + internal_error( + b"bash_execute_unix_command: cannot find keymap for command\0" as *const u8 + as *const libc::c_char, + ); + rl_forced_update_display(); + return 1 as libc::c_int; + } + + ce = rl_get_termcap(b"ce\0" as *const u8 as *const libc::c_char); + if !ce.is_null() { + rl_clear_visible_line(); + fflush(rl_outstream); + } else { + rl_crlf(); + } + + v = bind_variable( + b"READLINE_LINE\0" as *const u8 as *const libc::c_char, + rl_line_buffer, + 0 as libc::c_int, + ); + + if !v.is_null() { + VSETATTR_1!(v, att_exported as i32); + } + + i = readline_get_char_offset(rl_point); + value = inttostr( + i as intmax_t, + ibuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong, + ); + v = bind_int_variable( + b"READLINE_POINT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + 0, + ); + + if !v.is_null() { + VSETATTR_1!(v, att_exported as i32); + } + + i = readline_get_char_offset(rl_mark); + value = inttostr( + i as intmax_t, + ibuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong, + ); + v = bind_int_variable( + b"READLINE_MARK\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + 0, + ); + + if !v.is_null() { + VSETATTR!(v, att_exported as i32); + } + array_needs_making = 1; + + save_parser_state(&mut ps); + rl_clear_signals(); + r = parse_and_execute( + savestring!(cmd), + b"bash_execute_unix_command\0" as *const u8 as *const libc::c_char, + SEVAL_NOHIST as libc::c_int, + ); + rl_set_signals(); + restore_parser_state(&mut ps); + + v = find_variable(b"READLINE_LINE\0" as *const u8 as *const libc::c_char); + maybe_make_readline_line(if !v.is_null() { + value_cell!(v) + } else { + 0 as *mut libc::c_char + }); + + v = find_variable(b"READLINE_POINT\0" as *const u8 as *const libc::c_char); + if !v.is_null() && legal_number(value_cell!(v), &mut mi) != 0 { + readline_set_char_offset(mi as libc::c_int, &mut rl_point); + } + v = find_variable(b"READLINE_MARK\0" as *const u8 as *const libc::c_char); + if !v.is_null() && legal_number(value_cell!(v), &mut mi) != 0 { + readline_set_char_offset(mi as libc::c_int, &mut rl_mark); + } + + check_unbind_variable(b"READLINE_LINE\0" as *const u8 as *const libc::c_char); + check_unbind_variable(b"READLINE_POINT\0" as *const u8 as *const libc::c_char); + check_unbind_variable(b"READLINE_MARK\0" as *const u8 as *const libc::c_char); + array_needs_making = 1; + + if !ce.is_null() && r != 124 { + rl_redraw_prompt_last_line(); + } else { + rl_forced_update_display(); + } + return 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn print_unix_command_map() -> libc::c_int { + let mut save: Keymap = 0 as *mut KEYMAP_ENTRY; + let mut cmd_xmap: Keymap = 0 as *mut KEYMAP_ENTRY; + unsafe { + save = rl_get_keymap(); + cmd_xmap = get_cmd_xmap_from_keymap(save); + rl_set_keymap(cmd_xmap); + rl_macro_dumper(1 as libc::c_int); + rl_set_keymap(save); + } + return 0 as libc::c_int; +} + +fn init_unix_command_map() { + unsafe { + emacs_std_cmd_xmap = rl_make_bare_keymap(); + + (*emacs_std_cmd_xmap.offset(CTRL!('X' as i32) as isize)).Type = + ISKMAP as libc::c_int as libc::c_char; + let ref mut fresh43 = (*emacs_std_cmd_xmap.offset(CTRL!('X' as i32) as isize)).function; + (*emacs_std_cmd_xmap.offset(CTRL!('X' as i32) as isize)).function = + ::std::mem::transmute::>(rl_make_bare_keymap()); + + (*emacs_std_cmd_xmap.offset(ESC!() as isize)).Type = ISKMAP as libc::c_int as libc::c_char; + (*emacs_std_cmd_xmap.offset(ESC!() as isize)).function = + ::std::mem::transmute::>(rl_make_bare_keymap()); + + vi_insert_cmd_xmap = rl_make_bare_keymap(); + vi_movement_cmd_xmap = rl_make_bare_keymap(); + } +} + +fn get_cmd_xmap_from_keymap(mut kmap: Keymap) -> Keymap { + unsafe { + if emacs_std_cmd_xmap.is_null() { + init_unix_command_map(); + } + + if kmap == emacs_standard_keymap.as_mut_ptr() { + return emacs_std_cmd_xmap; + } else if kmap == emacs_meta_keymap.as_mut_ptr() { + return ::core::mem::transmute::, Keymap>( + (*emacs_std_cmd_xmap.offset(('[' as i32 & 0x1f as libc::c_int) as isize)).function, + ); + } else if kmap == emacs_ctlx_keymap.as_mut_ptr() { + return ::core::mem::transmute::, Keymap>( + (*emacs_std_cmd_xmap.offset(('X' as i32 & 0x1f as libc::c_int) as isize)).function, + ); + } else if kmap == vi_insertion_keymap.as_mut_ptr() { + return vi_insert_cmd_xmap; + } else if kmap == vi_movement_keymap.as_mut_ptr() { + return vi_movement_cmd_xmap; + } else { + return 0 as *mut c_void as Keymap; + }; + } +} + +fn isolate_sequence( + mut string: *mut libc::c_char, + mut ind: libc::c_int, + mut need_dquote: libc::c_int, + mut startp: *mut libc::c_int, +) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut passc: libc::c_int = 0; + let mut delim: libc::c_int = 0; + + i = ind; + unsafe { + while *string.offset(i as isize) as libc::c_int != 0 + && whitespace!(*string.offset(i as isize)) + { + i += 1; + } + + if need_dquote != 0 && *string.offset(i as isize) as libc::c_int != '"' as i32 { + builtin_error( + b"%s: first non-whitespace character is not `\"'\0" as *const u8 + as *const libc::c_char, + string, + ); + return -(1 as libc::c_int); + } + + delim = if *string.offset(i as isize) as libc::c_int == '"' as i32 + || *string.offset(i as isize) as libc::c_int == '\'' as i32 + { + *string.offset(i as isize) as libc::c_int + } else { + 0 as libc::c_int + }; + + if !startp.is_null() { + *startp = if delim != 0 { + i += 1; + i + } else { + i + }; + } + + passc = 0 as libc::c_int; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if passc != 0 { + passc = 0 as libc::c_int; + } else if c == '\\' as i32 { + passc += 1; + } else if c == delim { + break; + } + i += 1; + } + if delim != 0 && *string.offset(i as isize) as libc::c_int != delim { + builtin_error( + b"no closing `%c' in %s\0" as *const u8 as *const libc::c_char, + delim, + string, + ); + return -(1 as libc::c_int); + } + return i; + } +} + +#[no_mangle] +pub fn bind_keyseq_to_unix_command(mut line: *mut libc::c_char) -> libc::c_int { + let mut kmap: Keymap = 0 as *mut KEYMAP_ENTRY; + let mut cmd_xmap: Keymap = 0 as *mut KEYMAP_ENTRY; + let mut kseq: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + let mut kstart: libc::c_int = 0; + unsafe { + kmap = rl_get_keymap(); + + i = isolate_sequence(line, 0 as libc::c_int, 1 as libc::c_int, &mut kstart); + if i < 0 { + return -(1 as libc::c_int); + } + + kseq = substring(line, kstart, i); + + while *line.offset(i as isize) as libc::c_int != 0 + && *line.offset(i as isize) as libc::c_int != ':' as i32 + { + i += 1; + } + if *line.offset(i as isize) as libc::c_int != ':' as i32 { + builtin_error( + b"%s: missing colon separator\0" as *const u8 as *const libc::c_char, + line, + ); + FREE!(kseq); + return -(1 as libc::c_int); + } + + i = isolate_sequence(line, i + 1 as libc::c_int, 0 as libc::c_int, &mut kstart); + if i < 0 { + FREE!(kseq); + return -(1 as libc::c_int); + } + + value = substring(line, kstart, i); + cmd_xmap = get_cmd_xmap_from_keymap(kmap); + rl_generic_bind(ISMACR as libc::c_int, kseq, value, cmd_xmap); + + rl_bind_keyseq_in_map( + kseq, + ::std::mem::transmute:: libc::c_int>, Option>(Some( + ::std::mem::transmute::< + fn(libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(bash_execute_unix_command), + )), + kmap, + ); + libc::free(kseq as *mut c_void); + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn unbind_unix_command(mut kseq: *mut libc::c_char) -> libc::c_int { + let mut cmd_xmap: Keymap = 0 as *mut KEYMAP_ENTRY; + unsafe { + cmd_xmap = get_cmd_xmap_from_keymap(rl_get_keymap()); + if rl_bind_keyseq_in_map( + kseq, + ::std::mem::transmute::<*mut c_void, Option>(0 as *mut c_void), + cmd_xmap, + ) != 0 as libc::c_int + { + builtin_error( + b"`%s': cannot unbind in command keymap\0" as *const u8 as *const libc::c_char, + kseq, + ); + return 0 as libc::c_int; + } + + return 1 as libc::c_int; + } +} + +#[no_mangle] +pub fn bash_directory_completion_matches(mut text: *const libc::c_char) -> *mut *mut libc::c_char { + let mut m1: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut dfn: *mut libc::c_char = 0 as *mut libc::c_char; + let mut qc: libc::c_int = 0; + unsafe { + qc = if rl_dispatching != 0 { + rl_completion_quote_character + } else { + 0 as libc::c_int + }; + if rl_dispatching != 0 && rl_completion_found_quote == 0 { + dfn = bash_dequote_filename(text as *mut libc::c_char, qc); + } else { + dfn = text as *mut libc::c_char; + } + m1 = rl_completion_matches( + dfn, + Some(std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_filename_completion_function)), + ); + + if dfn != text as *mut libc::c_char { + libc::free(dfn as *mut c_void); + } + + if m1.is_null() || (*m1.offset(0 as libc::c_int as isize)).is_null() { + return m1; + } + bash_progcomp_ignore_filenames(m1); + return m1; + } +} + +#[no_mangle] +pub fn bash_dequote_text(mut text: *const libc::c_char) -> *mut libc::c_char { + let mut dtxt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut qc: libc::c_int = 0; + unsafe { + qc = if *text.offset(0 as isize) as libc::c_int == '"' as i32 + || *text.offset(0 as isize) as libc::c_int == '\'' as i32 + { + *text.offset(0 as isize) as libc::c_int + } else { + 0 + }; + dtxt = bash_dequote_filename(text as *mut libc::c_char, qc); + } + return dtxt; +} + +fn bash_event_hook() -> libc::c_int { + let mut sig: libc::c_int = 0; + unsafe { + if sigterm_received != 0 { + return 0; + } + sig = 0; + if terminating_signal != 0 { + sig = terminating_signal; + } else if interrupt_state != 0 { + sig = SIGINT as libc::c_int; + } else if sigalrm_seen != 0 { + sig = SIGALRM as libc::c_int; + } else { + sig = first_pending_trap(); + } + if terminating_signal != 0 || interrupt_state != 0 || sigalrm_seen != 0 { + rl_cleanup_after_signal(); + } + bashline_reset_event_hook(); + if posixly_correct != 0 && this_shell_builtin == Some(read_builtin) && sig == 2 { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 128 as libc::c_int | SIGINT as libc::c_int, + ); + throw_to_top_level(); + } + check_signals_and_traps(); + } + return 0; +} diff --git a/utshell-0.5.0/src/bin/utshell.rs b/utshell-0.5.0/src/bin/utshell.rs new file mode 100644 index 00000000..b4fa560f --- /dev/null +++ b/utshell-0.5.0/src/bin/utshell.rs @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] + +use builtins::utshell::r_main; + +fn main() { + r_main(); +} diff --git a/utshell-0.5.0/src/bin/utshellversion.rs b/utshell-0.5.0/src/bin/utshellversion.rs new file mode 100644 index 00000000..25f20a61 --- /dev/null +++ b/utshell-0.5.0/src/bin/utshellversion.rs @@ -0,0 +1,186 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] + +use builtins::version::{dist_version, patch_level, shell_version_string, show_shell_version}; +use libc::FILE; + +extern "C" { + static mut stderr: *mut FILE; + fn fprintf(_: *mut FILE, _: *const libc::c_char, _: ...) -> libc::c_int; + fn printf(_: *const libc::c_char, _: ...) -> libc::c_int; + static mut optind: libc::c_int; + fn getopt( + ___argc: libc::c_int, + ___argv: *const *mut libc::c_char, + __shortopts: *const libc::c_char, + ) -> libc::c_int; + fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char; + fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; + fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; + fn exit(_: libc::c_int) -> !; +} + +pub const EOF: libc::c_int = -1; +pub const RFLAG: libc::c_int = 0x0001; +pub const VFLAG: libc::c_int = 0x0002; +pub const MFLAG: libc::c_int = 0x0004; +pub const PFLAG: libc::c_int = 0x0008; +pub const SFLAG: libc::c_int = 0x0010; +pub const LFLAG: libc::c_int = 0x0020; +pub const XFLAG: libc::c_int = 0x0040; + +pub type size_t = libc::c_ulong; +pub type __off64_t = libc::c_long; +pub type __off_t = libc::c_long; + +#[macro_export] +macro_rules! MACHTYPE { + () => { + (b"x86_64-pc-linux-gnu\0" as *const u8 as *const libc::c_char) + }; +} + +#[no_mangle] +static mut shell_name_rename: *mut libc::c_char = + b"utshell\0" as *const u8 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut progname: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +unsafe extern "C" fn usage() { + fprintf( + stderr, + b"%s: usage: %s [-hrvpmlsx]\n\0" as *const u8 as *const libc::c_char, + progname, + progname, + ); +} +unsafe fn main_0(mut argc: libc::c_int, mut argv: *mut *mut libc::c_char) -> libc::c_int { + let mut opt: libc::c_int = 0; + let mut oflags: libc::c_int = 0; + let mut dv: [libc::c_char; 128] = [0; 128]; + let mut rv: *mut libc::c_char = 0 as *mut libc::c_char; + + progname = strrchr(*argv.offset(0 as libc::c_int as isize), '/' as i32); + if !progname.is_null() { + progname = progname.offset(1); + } else { + progname = *argv.offset(0 as libc::c_int as isize); + } + + oflags = 0 as libc::c_int; + loop { + opt = getopt( + argc, + argv, + b"hrvmpslx\0" as *const u8 as *const libc::c_char, + ); + if !(opt != EOF) { + break; + } + match opt as u8 as char { + 'h' => { + usage(); + exit(0 as libc::c_int); + } + 'r' => { + oflags |= RFLAG; /* release */ + } + 'v' => { + oflags |= VFLAG; /* version */ + } + 'm' => { + oflags |= MFLAG; /* machtype */ + } + 'p' => { + oflags |= PFLAG; /* patchlevel */ + } + 's' => { + oflags |= SFLAG; /* short version string */ + } + 'l' => { + oflags |= LFLAG; /* long version string */ + } + 'x' => { + oflags |= XFLAG; /* extended version information */ + } + _ => { + usage(); + exit(2 as libc::c_int); + } + } + } + argc -= optind; + argv = argv.offset(optind as isize); + + if argc > 0 as libc::c_int { + usage(); + exit(2 as libc::c_int); + } + + /* default behavior */ + if oflags == 0 as libc::c_int { + oflags = SFLAG; + } + if oflags & (RFLAG | VFLAG) != 0 { + strcpy(dv.as_mut_ptr(), dist_version); + rv = strchr(dv.as_mut_ptr(), '.' as i32); + if !rv.is_null() { + let fresh0 = rv; + rv = rv.offset(1); + *fresh0 = '\0' as i32 as libc::c_char; + } else { + rv = b"00\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + } + if oflags & RFLAG != 0 { + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + dv.as_mut_ptr(), + ); + } else if oflags & VFLAG != 0 { + printf(b"%s\n\0" as *const u8 as *const libc::c_char, rv); + } else if oflags & MFLAG != 0 { + printf(b"%s\n\0" as *const u8 as *const libc::c_char, MACHTYPE!()); + } else if oflags & PFLAG != 0 { + printf(b"%d\n\0" as *const u8 as *const libc::c_char, patch_level); + } else if oflags & SFLAG != 0 { + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + shell_version_string(), + ); + } else if oflags & LFLAG != 0 { + show_shell_version(0 as libc::c_int); + } else if oflags & XFLAG != 0 { + show_shell_version(1 as libc::c_int); + } + exit(0 as libc::c_int); +} + +pub fn main() { + let mut args: Vec<*mut libc::c_char> = Vec::new(); + for arg in ::std::env::args() { + args.push( + (::std::ffi::CString::new(arg)) + .expect("Failed to convert argument into CString.") + .into_raw(), + ); + } + args.push(::core::ptr::null_mut()); + unsafe { + ::std::process::exit(main_0( + (args.len() - 1) as libc::c_int, + args.as_mut_ptr() as *mut *mut libc::c_char, + ) as i32) + } +} diff --git a/utshell-0.5.0/src/brace.rs b/utshell-0.5.0/src/brace.rs new file mode 100644 index 00000000..a2bb230d --- /dev/null +++ b/utshell-0.5.0/src/brace.rs @@ -0,0 +1,828 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::general::legal_number; +use crate::sig::{termsig_handler, throw_to_top_level}; +use crate::src_common::*; +use crate::stringlib::substring; +use crate::subst::extract_command_subst; + +/* å®ADVANCE_CHAR在src_common中有定义,这里是其中的一个å˜å½¢ */ +#[macro_export] +macro_rules! ADVANCE_CHAR_1 { + ($str:expr, $strsize:expr, $i:expr) => { + $i += 1; + }; +} + +//errno 的一个å˜å½¢ +static mut errno: libc::c_int = 0 as libc::c_int; + +#[inline] +fn strtoimax( + mut nptr: *const libc::c_char, + mut endptr: *mut *mut libc::c_char, + mut base: libc::c_int, +) -> intmax_t { + unsafe { + return __strtol_internal(nptr, endptr, base, 0 as libc::c_int); + } +} + +fn STREQN(a: *const libc::c_char, b: *const libc::c_char, n: i32) -> bool { + if n == 0 { + return true; + } else { + return unsafe { *a == *b && libc::strncmp(a, b, n as libc::size_t) == 0 }; + } +} + +#[inline] +fn is_basic(mut c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} +static mut brace_arg_separator: libc::c_int = ',' as i32; + +#[no_mangle] +pub fn brace_expand(mut text: *mut libc::c_char) -> *mut *mut libc::c_char { + let mut start: libc::c_int = 0; + let mut tlen: size_t = 0; + let mut preamble: *mut libc::c_char = 0 as *mut libc::c_char; + let mut postamble: *mut libc::c_char = 0 as *mut libc::c_char; + let mut amble: *mut libc::c_char = 0 as *mut libc::c_char; + let mut alen: size_t = 0; + let mut tack: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut c1: libc::c_int = 0; + + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + std::mem::size_of::() as usize, + ); + + tlen = libc::strlen(text) as u64; + i = 0 as libc::c_int; + + loop { + c = brace_gobbler(text, tlen, &mut i, '{' as i32); + c1 = c; + if c != 0 { + j = i + 1 as libc::c_int; + start = j; + c = brace_gobbler(text, tlen, &mut j, '}' as i32); + if c == 0 as libc::c_int { + i += 1; + c = c1; + continue; + } else { + c = c1; + break; + } + } else { + break; + } + } + preamble = libc::malloc((i + 1 as libc::c_int) as size_t as usize) as *mut libc::c_char; + + if i > 0 as libc::c_int { + libc::strncpy(preamble, text, i as usize); + } + + *preamble.offset(i as isize) = '\0' as i32 as libc::c_char; + + result = libc::malloc( + ((2 as libc::c_int as size_t) * (std::mem::size_of::<*mut libc::c_char>() as size_t)) + as usize, + ) as *mut *mut libc::c_char; + + *result.offset(0 as libc::c_int as isize) = preamble; + *result.offset(1 as libc::c_int as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + + if c != '{' as i32 { + return result; + } + + i += 1; + start = i; + + c = brace_gobbler(text, tlen, &mut i, '}' as i32); + if c == 0 as libc::c_int { + libc::free(preamble as *mut libc::c_void); + *result.offset(0 as libc::c_int as isize) = savestring!(text); + return result; + } + amble = substring(text, start, i); + alen = (i - start) as size_t; + + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + std::mem::size_of::() as size_t as usize, + ); + j = 0 as libc::c_int; + + loop { + if *amble.offset(j as isize) == 0 { + break; + } + if *amble.offset(j as isize) as libc::c_int == '\\' as i32 { + j += 1; + ADVANCE_CHAR_1!(amble, alen, j); + continue; + } + if *amble.offset(j as isize) as libc::c_int == brace_arg_separator { + break; + } + ADVANCE_CHAR_1!(amble, alen, j); + } + loop { + if *amble.offset(j as isize) as libc::c_int == 0 as libc::c_int { + tack = expand_seqterm(amble, alen); + if tack.is_null() { + break; + } else if !text.offset((i + 1) as isize).is_null() { + tack = strvec_create(2 as libc::c_int); + *tack = savestring!(text.offset((start - 1) as isize) as *mut libc::c_char); + *(*tack.offset((i - start + 2) as isize)) = '\0' as i32 as libc::c_char; + *tack.offset(1 as isize) = 0 as *mut libc::c_char; + break; + } else { + libc::free(amble as *mut libc::c_void); + libc::free(preamble as *mut libc::c_void); + *result.offset(0 as libc::c_int as isize) = libc::strcpy( + libc::malloc((1 as libc::c_int as usize).wrapping_add(libc::strlen(text))) + as *mut libc::c_char, + text, + ); + return result; + } + } + tack = expand_amble(amble, alen, 0); + break; + } + result = array_concat(result, tack); + libc::free(amble as *mut libc::c_void); + if tack != result { + strvec_dispose(tack); + } + postamble = text.offset(i as isize).offset(1 as libc::c_int as isize); + if !postamble.is_null() && *postamble as libc::c_int != 0 { + tack = brace_expand(postamble); + result = array_concat(result, tack); + if tack != result { + strvec_dispose(tack); + } + } + } + return result; +} + +fn expand_amble( + mut text: *mut libc::c_char, + mut tlen: size_t, + mut flags: libc::c_int, +) -> *mut *mut libc::c_char { + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut partial: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut tresult: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut tem: *mut libc::c_char = 0 as *mut libc::c_char; + let mut start: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + std::mem::size_of::() as usize, + ); + + result = 0 as *mut libc::c_void as *mut *mut libc::c_char; + i = 0 as libc::c_int; + start = i; + c = 1 as libc::c_int; + while c != 0 { + c = brace_gobbler(text, tlen, &mut i, brace_arg_separator); + tem = substring(text, start, i); + partial = brace_expand(tem); + if result.is_null() { + result = partial; + } else { + let mut lr: libc::c_int = 0; + let mut lp: libc::c_int = 0; + let mut j: libc::c_int = 0; + lr = strvec_len(result); + lp = strvec_len(partial); + tresult = strvec_mresize(result, lp + lr + 1 as libc::c_int); + if tresult.is_null() { + internal_error( + b"brace expansion: cannot allocate memory for %s\0" as *const u8 + as *mut libc::c_char, + tem, + ); + libc::free(tem as *mut libc::c_void); + strvec_dispose(partial); + strvec_dispose(result); + result = 0 as *mut libc::c_void as *mut *mut libc::c_char; + return result; + } else { + result = tresult; + } + j = 0 as libc::c_int; + while j < lp { + *result.offset((lr + j) as isize) = *partial.offset(j as isize); + j += 1; + j; + } + *result.offset((lr + j) as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + libc::free(partial as *mut libc::c_void); + } + libc::free(tem as *mut libc::c_void); + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*text.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *text.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*text.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + text.offset(i as isize), + tlen.wrapping_sub(i as usize as u64), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + i; + } else if mblength == 0 as libc::c_int as usize as u64 { + i += 1; + i; + } else { + i = (i as usize).wrapping_add(mblength as usize) as libc::c_int as libc::c_int; + } + } else { + i += 1; + i; + } + start = i; + } + } + return result; +} + +fn mkseq( + mut start: intmax_t, + mut end: intmax_t, + mut incr: intmax_t, + mut type_0: libc::c_int, + mut width: libc::c_int, +) -> *mut *mut libc::c_char { + let mut n: intmax_t = 0; + let mut prevn: intmax_t = 0; + let mut i: libc::c_int = 0; + let mut nelem: libc::c_int = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + if incr == 0 as libc::c_int as libc::c_long { + incr = 1 as libc::c_int as intmax_t; + } + + if start > end && incr > 0 as libc::c_int as libc::c_long { + incr = -incr; + } else if start < end && incr < 0 as libc::c_int as libc::c_long { + if incr == INTMAX_MIN!() { + return 0 as *mut *mut libc::c_void as *mut *mut libc::c_char; + } + incr = -incr; + } + if SUBOVERFLOW!(end, start, INTMAX_MIN!() + 3, INTMAX_MAX!() - 2) { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + prevn = sh_imaxabs!(end - start); + + if INT_MAX!() == INTMAX_MAX!() && ADDOVERFLOW!(prevn, 2, INT_MIN!(), INT_MAX!()) { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } else if ADDOVERFLOW!((prevn / sh_imaxabs!(incr)), 1, INTMAX_MIN!(), INTMAX_MAX!()) { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + if (prevn / sh_imaxabs!(incr)) > INT_MAX!() - 3 as libc::c_int as libc::c_long { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + nelem = (prevn / sh_imaxabs!(incr)) as libc::c_int + 1 as libc::c_int; + unsafe { + result = strvec_mcreate(nelem + 1); + + if result.is_null() { + internal_error( + b"brace expansion: failed to allocate memory for %u elements\0" as *const u8 + as *const libc::c_char, + nelem as libc::c_uint, + ); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + i = 0 as libc::c_int; + n = start; + loop { + if interrupt_state != 0 as libc::c_int { + *result.offset(i as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + strvec_dispose(result); + result = 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + if type_0 == ST_INT!() { + t = itos(n); + *result.offset(i as isize) = t; + i += 1; + } else if type_0 == ST_ZINT!() { + let mut len: libc::c_int = 0; + let mut arg: libc::c_int = 0; + arg = n as libc::c_int; + len = asprintf( + &mut t as *mut *mut libc::c_char, + b"%0*d\0" as *const u8 as *const libc::c_char, + width, + arg, + ); + *result.offset(i as isize) = t; + i += 1; + } else { + t = libc::malloc(2 as libc::c_int as usize) as *mut libc::c_char; + if !t.is_null() { + *t.offset(0 as libc::c_int as isize) = n as libc::c_char; + *t.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + *result.offset(i as isize) = t; + i = i + 1; + } + if t.is_null() { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lbuf: [libc::c_char; INT_STRLEN_BOUND!(intmax_t) + 1 as usize] = + [0; INT_STRLEN_BOUND!(intmax_t) + 1 as usize]; + p = inttostr( + n, + lbuf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; INT_STRLEN_BOUND!(intmax_t) + 1 as usize]>() + as usize as u64, + ); + internal_error( + b"brace expansion: failed to allocate memory for '%s'\0" as *const u8 + as *const libc::c_char, + p, + ); + strvec_dispose(result); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + if ADDOVERFLOW!(n, incr, INTMAX_MIN!(), INTMAX_MAX!()) { + break; + } + n += incr; + if incr < 0 as libc::c_int as libc::c_long && n < end + || incr > 0 as libc::c_int as libc::c_long && n > end + { + break; + } + } + *result.offset(i as isize) = 0 as *mut libc::c_char; + } + return (result); +} + +fn expand_seqterm(mut text: *mut libc::c_char, mut tlen: size_t) -> *mut *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lhs_t: libc::c_int = 0; + let mut rhs_t: libc::c_int = 0; + let mut lhs_l: libc::c_int = 0; + let mut rhs_l: libc::c_int = 0; + let mut width: libc::c_int = 0; + let mut lhs_v: intmax_t = 0; + let mut rhs_v: intmax_t = 0; + let mut incr: intmax_t = 0; + let mut tl: intmax_t = 0; + let mut tr: intmax_t = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut ep: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oep: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + t = libc::strstr(text, b"..\0" as *const u8 as *const libc::c_char); + + if t.is_null() { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + lhs_l = t.offset_from(text) as libc::c_long as libc::c_int; + + lhs = substring(text, 0 as libc::c_int, lhs_l); + rhs = substring( + text, + (lhs_l + std::mem::size_of::<[libc::c_char; 3]> as libc::c_int - 1 as libc::c_int), + tlen as libc::c_int, + ); + if *lhs.offset(0 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + || *rhs.offset(0 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + libc::free(lhs as *mut libc::c_void); + libc::free(rhs as *mut libc::c_void); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + lhs_t = if legal_number(lhs, &mut tl) != 0 { + ST_INT!() + } else if ISALPHA!(*lhs) + && *lhs.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + ST_CHAR!() as libc::c_int + } else { + ST_BAD!() as libc::c_int + }; + + ep = 0 as *mut libc::c_char; + + if ISDIGIT!(*rhs) + || ((*rhs as libc::c_int == '+' as libc::c_int + || *rhs as libc::c_int == '-' as libc::c_int) + && ISDIGIT!(*rhs.offset(1 as isize))) + { + rhs_t = ST_INT!() as libc::c_int; + errno = 0 as libc::c_int; + tr = strtoimax(rhs, &mut ep, 10 as libc::c_int); + if errno == ERANGE!() + || !ep.is_null() + && *ep as libc::c_int != 0 as libc::c_int + && *ep as libc::c_int != '.' as i32 + { + rhs_t = ST_BAD!() as libc::c_int; + } + } else if ISALPHA!(*rhs) && *rhs.offset(1 as isize) == 0 + || *rhs.offset(1 as isize) as libc::c_int == '.' as libc::c_int + { + rhs_t = ST_CHAR!(); + ep = rhs.offset(1 as libc::c_int as isize); + } else { + rhs_t = ST_BAD!(); + ep = 0 as *mut libc::c_char; + } + incr = 1 as libc::c_int as intmax_t; + if rhs_t != ST_BAD!() { + oep = ep; + errno = 0 as libc::c_int; + + if !ep.is_null() + && *ep as libc::c_int == '.' as i32 + && *ep.offset(1 as libc::c_int as isize) as libc::c_int == '.' as i32 + && *ep.offset(2 as libc::c_int as isize) as libc::c_int != 0 + { + incr = strtoimax( + ep.offset(2 as libc::c_int as isize), + &mut ep, + 10 as libc::c_int, + ); + } + if *ep as libc::c_int != 0 as libc::c_int || errno == ERANGE!() { + rhs_t = ST_BAD!(); + } + tlen = (tlen as usize).wrapping_sub(ep.offset_from(oep) as libc::c_long as usize) + as size_t as size_t; + } + + if lhs_t != rhs_t || lhs_t == ST_BAD!() as libc::c_int || rhs_t == ST_BAD!() as libc::c_int + { + libc::free(lhs as *mut libc::c_void); + libc::free(rhs as *mut libc::c_void); + + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + if lhs_t == ST_CHAR!() as libc::c_int { + lhs_v = *lhs.offset(0 as libc::c_int as isize) as libc::c_uchar as intmax_t; + rhs_v = *rhs.offset(0 as libc::c_int as isize) as libc::c_uchar as intmax_t; + width = 1 as libc::c_int; + } else { + lhs_v = tl; + rhs_v = tr; + rhs_l = tlen as libc::c_int + - lhs_l as libc::c_int + - std::mem::size_of::<[libc::c_char; 3]>() as libc::c_int + + 1 as libc::c_int; + + width = 0; + if lhs_l > 1 as libc::c_int + && *lhs.offset(0 as libc::c_int as isize) as libc::c_int == '0' as i32 + { + width = lhs_l; + lhs_t = ST_ZINT!(); + } + if lhs_l > 2 as libc::c_int + && *lhs.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *lhs.offset(1 as libc::c_int as isize) as libc::c_int == '0' as i32 + { + width = lhs_l; + lhs_t = ST_ZINT!(); + } + if rhs_l > 1 as libc::c_int + && *rhs.offset(0 as libc::c_int as isize) as libc::c_int == '0' as i32 + && width < rhs_l + { + width = rhs_l; + lhs_t = ST_ZINT!(); + } + if rhs_l > 2 as libc::c_int + && *rhs.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *rhs.offset(1 as libc::c_int as isize) as libc::c_int == '0' as i32 + && width < rhs_l + { + width = rhs_l; + lhs_t = ST_ZINT!(); + } + if width < lhs_l && lhs_t == ST_ZINT!() { + width = lhs_l; + } + if width < rhs_l && lhs_t == ST_ZINT!() { + width = rhs_l; + } + } + result = mkseq(lhs_v, rhs_v, incr, lhs_t, width); + + libc::free(lhs as *mut libc::c_void); + libc::free(rhs as *mut libc::c_void); + } + return result; +} + +fn brace_gobbler( + mut text: *mut libc::c_char, + mut tlen: size_t, + mut indx: *mut libc::c_int, + mut satisfy: libc::c_int, +) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut quoted: libc::c_int = 0; + let mut level: libc::c_int = 0; + let mut commas: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut Flag = false; + + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + std::mem::size_of::() as usize, + ); + + pass_next = 0 as libc::c_int; + quoted = pass_next; + level = quoted; + commas = if satisfy == '}' as i32 { + 0 as libc::c_int + } else { + 1 as libc::c_int + }; + + i = *indx; + + 'outer: loop { + Flag = false; + c = *text.offset(i as isize) as libc::c_int; + if (c == 0) { + break 'outer; + } + if pass_next != 0 { + pass_next = 0 as libc::c_int; + ADVANCE_CHAR_1!(text, tlen, i); + continue 'outer; + } + if c == '\\' as i32 && (quoted == 0 || quoted == '"' as i32 || quoted == '`' as i32) { + pass_next = 1; + i += 1; + continue 'outer; + } + if c == '$' as i32 + && *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '{' as i32 + && quoted != '\'' as i32 + { + pass_next = 1 as libc::c_int; + i += 1; + if quoted == 0 as libc::c_int { + level += 1; + } + continue 'outer; + } + 'inner: loop { + if quoted != 0 { + if c == quoted { + quoted = 0 as libc::c_int; + } + if quoted == '"' as i32 + && c == '$' as i32 + && *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '(' as i32 + { + Flag = true; + break 'inner; + } + ADVANCE_CHAR_1!(text, tlen, i); + continue 'outer; + } + if c == '"' as libc::c_int || c == '\'' as libc::c_int || c == '`' as libc::c_int { + quoted = c; + i += 1; + continue 'outer; + } else if (c == '$' as libc::c_int + || c == '<' as libc::c_int + || c == '>' as libc::c_int) + && *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '(' as libc::c_int + /* ) */ + { + si = i + 2 as libc::c_int; + t = extract_command_subst(text, &mut si, 0 as libc::c_int); + i = si; + libc::free(t as *mut libc::c_void); + i += 1; + continue 'outer; + } + break 'inner; + } + + if Flag { + si = i + 2 as libc::c_int; + t = extract_command_subst(text, &mut si, 0 as libc::c_int); + i = si; + libc::free(t as *mut libc::c_void); + i += 1; + continue 'outer; + } + + if (c == satisfy + && level == 0 as libc::c_int + && quoted == 0 as libc::c_int + && commas > 0 as libc::c_int) + { + /* We ignore an open brace surrounded by whitespace, and also + an open brace followed immediately by a close brace preceded + by whitespace. */ + if c == '{' as libc::c_int + && ((i == 0 + || brace_whitespace!(*text.offset((i - 1 as libc::c_int) as isize))) + && (brace_whitespace!(*text.offset((i + 1 as libc::c_int) as isize)) + || *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '}' as i32)) + { + i += 1; + continue 'outer; + } + break 'outer; + } + + if c == '{' as i32 { + level += 1; + } else if c == '}' as i32 && level != 0 { + level -= 1; + } else if satisfy == '}' as i32 && c == brace_arg_separator && level == 0 as libc::c_int + { + commas += 1; + } else if satisfy == '}' as i32 + && STREQN( + text.offset(i as libc::c_int as isize), + BRACE_SEQ_SPECIFIER!(), + 2, + ) + && *text.offset((i + 2 as libc::c_int) as isize) as libc::c_int != satisfy + && level == 0 as libc::c_int + { + commas += 1; + } + ADVANCE_CHAR_1!(text, tlen, i); + } + + *indx = i; + } + return c; +} +fn array_concat( + mut arr1: *mut *mut libc::c_char, + mut arr2: *mut *mut libc::c_char, +) -> *mut *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut len1: libc::c_int = 0; + let mut len2: libc::c_int = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + + if arr1.is_null() { + return arr2; + } + + if arr2.is_null() { + return arr1; + } + unsafe { + if !(*arr1.offset(0 as libc::c_int as isize)).is_null() + && *(*arr1.offset(0 as libc::c_int as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int + && (*arr1.offset(1 as libc::c_int as isize)).is_null() + { + strvec_dispose(arr1); + return arr2; + } + if !(*arr2.offset(0 as libc::c_int as isize)).is_null() + && *(*arr2.offset(0 as libc::c_int as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int + && (*arr2.offset(1 as libc::c_int as isize)).is_null() + { + return arr1; + } + + len1 = strvec_len(arr1); + len2 = strvec_len(arr2); + result = libc::malloc( + ((1 as libc::c_int + len1 * len2) as usize) + .wrapping_mul(std::mem::size_of::<*mut libc::c_char>() as usize), + ) as *mut *mut libc::c_char; + if result.is_null() { + return result; + } + + len = 0 as libc::c_int; + i = 0 as libc::c_int; + + while i < len1 { + let mut strlen_1: libc::c_int = libc::strlen(*arr1.offset(i as isize)) as libc::c_int; + j = 0 as libc::c_int; + while j < len2 { + *result.offset(len as isize) = libc::malloc( + (1 as libc::c_int + + strlen_1 + + libc::strlen(*arr2.offset(j as isize)) as libc::c_int) + as size_t as usize, + ) as *mut libc::c_char; + + libc::strcpy(*result.offset(len as isize), *arr1.offset(i as isize)); + libc::strcpy( + (*result.offset(len as isize)).offset(strlen_1 as isize), + *arr2.offset(j as isize), + ); + len += 1; + j += 1; + } + libc::free(*arr1.offset(i as isize) as *mut libc::c_void); + i += 1 + } + libc::free(arr1 as *mut libc::c_void); + *result.offset(len as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + } + return result; +} diff --git a/utshell-0.5.0/src/bracecomp.rs b/utshell-0.5.0/src/bracecomp.rs new file mode 100644 index 00000000..851a0e64 --- /dev/null +++ b/utshell-0.5.0/src/bracecomp.rs @@ -0,0 +1,211 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +fn string_gcd(mut s1: *mut libc::c_char, mut s2: *mut libc::c_char) -> libc::c_int { + let mut i: libc::c_int = 0; + if s1.is_null() || s2.is_null() { + return 0 as libc::c_int; + } + unsafe { + i = 0 as libc::c_int; + while *s1 as libc::c_int != 0 && *s2 as libc::c_int != 0 { + if *s1 as libc::c_int != *s2 as libc::c_int { + break; + } + s1 = s1.offset(1); + s2 = s2.offset(1); + i += 1; + } + } + return i; +} + +fn really_munge_braces( + mut array: *mut *mut libc::c_char, + mut real_start: libc::c_int, + mut real_end: libc::c_int, + mut gcd_zero: libc::c_int, +) -> *mut libc::c_char { + let mut start: libc::c_int = 0; + let mut end: libc::c_int = 0; + let mut gcd: libc::c_int = 0; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut subterm: *mut libc::c_char = 0 as *mut libc::c_char; + let mut x: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result_size: libc::c_int = 0; + let mut flag: libc::c_int = 0; + let mut tlen: libc::c_int = 0; + flag = 0 as libc::c_int; + unsafe { + if real_start == real_end { + x = if !(*array.offset(real_start as isize)).is_null() { + sh_backslash_quote( + (*array.offset(real_start as isize)).offset(gcd_zero as isize), + 0 as *const libc::c_char, + 0 as libc::c_int, + ) + } else { + sh_backslash_quote(*array, 0 as *const libc::c_char, 0 as libc::c_int) + }; + return x; + } + result_size = 16 as libc::c_int; + result = libc::malloc(result_size as usize) as *mut libc::c_char; + *result = '\0' as i32 as libc::c_char; + start = real_start; + while start < real_end { + gcd = libc::strlen(*array.offset(start as isize)) as libc::c_int; + end = start + 1 as libc::c_int; + while end < real_end { + let mut temp: libc::c_int = 0; + temp = string_gcd(*array.offset(start as isize), *array.offset(end as isize)); + if temp <= gcd_zero { + break; + } + gcd = temp; + end += 1; + } + end -= 1; + if gcd_zero == 0 as libc::c_int + && start == real_start + && end != real_end - 1 as libc::c_int + { + result_size += 1 as libc::c_int; + result = libc::realloc(result as *mut libc::c_void, result_size as usize) + as *mut libc::c_char; + *result.offset(0 as libc::c_int as isize) = '{' as i32 as libc::c_char; + *result.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + flag += 1; + flag; + } + if start == end { + x = savestring!((*array.offset(start as isize)).offset(gcd_zero as isize)); + subterm = sh_backslash_quote(x, 0 as *const libc::c_char, 0 as libc::c_int); + libc::free(x as *mut libc::c_void); + } else { + tlen = gcd - gcd_zero; + x = libc::malloc((tlen + 1 as libc::c_int) as usize) as *mut libc::c_char; + libc::strncpy( + x, + (*array.offset(start as isize)).offset(gcd_zero as isize), + tlen as usize, + ); + *x.offset(tlen as isize) = '\0' as i32 as libc::c_char; + subterm = sh_backslash_quote(x, 0 as *const libc::c_char, 0 as libc::c_int); + libc::free(x as *mut libc::c_void); + result_size += libc::strlen(subterm) as libc::c_int + 1 as libc::c_int; + result = libc::realloc(result as *mut libc::c_void, result_size as usize) + as *mut libc::c_char; + strcat(result, subterm); + libc::free(subterm as *mut libc::c_void); + strcat(result, b"{\0" as *const u8 as *const libc::c_char); + subterm = really_munge_braces(array, start, end + 1 as libc::c_int, gcd); + *subterm.offset((libc::strlen(subterm) + 1 as libc::c_ulong as usize) as isize) = + '}' as i32 as libc::c_char; + } + result_size += libc::strlen(subterm) as libc::c_int + 1 as libc::c_int; + result = libc::realloc(result as *mut libc::c_void, result_size as usize) + as *mut libc::c_char; + strcat(result, subterm); + strcat(result, b",\0" as *const u8 as *const libc::c_char); + libc::free(subterm as *mut libc::c_void); + start = end + 1 as libc::c_int; + } + if gcd_zero == 0 as libc::c_int { + *result.offset((libc::strlen(result) - 1 as libc::c_ulong as usize) as isize) = + (if flag != 0 { '}' as i32 } else { '\0' as i32 }) as libc::c_char; + } + } + return result; +} + +fn _strcompare(mut s1: *mut *mut libc::c_char, mut s2: *mut *mut libc::c_char) -> libc::c_int { + unsafe { + let mut result: libc::c_int = 0; + result = **s1 as libc::c_int - **s2 as libc::c_int; + if result == 0 as libc::c_int { + result = strcmp(*s1, *s2); + } + return result; + } +} + +fn hack_braces_completion(mut names: *mut *mut libc::c_char) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + i = strvec_len(names); + if __ctype_get_mb_cur_max() > 1 as usize && i > 2 as libc::c_int { + qsort( + names.offset(1 as libc::c_int as isize) as *mut libc::c_void, + (i - 1 as libc::c_int) as usize, + std::mem::size_of::<*mut libc::c_char>() as usize, + std::mem::transmute:: libc::c_int>, Option>(Some( + std::mem::transmute::< + fn(*mut *mut libc::c_char, *mut *mut libc::c_char) -> libc::c_int, + fn() -> libc::c_int, + >(_strcompare), + )), + ); + } + temp = really_munge_braces(names, 1 as libc::c_int, i, 0 as libc::c_int); + i = 0 as libc::c_int; + while !(*names.offset(i as isize)).is_null() { + libc::free(*names.offset(i as isize) as *mut libc::c_void); + let ref mut fresh0 = *names.offset(i as isize); + *fresh0 = 0 as *mut libc::c_char; + i += 1; + i; + } + let ref mut fresh1 = *names.offset(0 as libc::c_int as isize); + *fresh1 = temp; + } + return 0 as libc::c_int; +} +#[no_mangle] +pub fn bash_brace_completion(mut count: libc::c_int, mut ignore: libc::c_int) -> libc::c_int { + let mut orig_ignore_func: Option = None; + let mut orig_entry_func: Option = None; + let mut orig_quoting_func: Option = None; + let mut orig_attempt_func: Option = None; + let mut orig_quoting_desired: libc::c_int = 0; + let mut r: libc::c_int = 0; + unsafe { + orig_ignore_func = rl_ignore_some_completions_function; + orig_attempt_func = rl_attempted_completion_function; + orig_entry_func = rl_completion_entry_function; + orig_quoting_func = rl_filename_quoting_function; + orig_quoting_desired = rl_filename_quoting_desired; + rl_completion_entry_function = Some(std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + >(rl_filename_completion_function)); + rl_attempted_completion_function = ::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + rl_ignore_some_completions_function = ::core::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(::core::mem::transmute::< + fn(*mut *mut libc::c_char) -> libc::c_int, + fn() -> libc::c_int, + >(hack_braces_completion))); + rl_filename_quoting_function = ::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + rl_filename_quoting_desired = 0 as libc::c_int; + r = rl_complete_internal('\t' as i32); + rl_ignore_some_completions_function = orig_ignore_func; + rl_attempted_completion_function = orig_attempt_func; + rl_completion_entry_function = orig_entry_func; + rl_filename_quoting_function = orig_quoting_func; + rl_filename_quoting_desired = orig_quoting_desired; + } + return r; +} diff --git a/utshell-0.5.0/src/builtins/alias.rs b/utshell-0.5.0/src/builtins/alias.rs new file mode 100644 index 00000000..b1bfdf76 --- /dev/null +++ b/utshell-0.5.0/src/builtins/alias.rs @@ -0,0 +1,322 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use std::ffi::CStr; +use std::ffi::CString; + +use crate::alias::{add_alias, all_aliases, delete_all_aliases, find_alias, remove_alias}; +use crate::findcmd::find_user_command; +use crate::general::legal_alias_name; +use crate::src_common::*; +use crate::variables::find_function; + +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + common::{builtin_usage, find_shell_builtin, sh_chkwrite, sh_notfound}, + help::builtin_help, +}; + +/* Hack the alias command in a Korn shell way. */ +#[no_mangle] +pub fn alias_builtin(mut list: *mut WordList) -> libc::c_int { + let mut any_failed; + let mut offset; + let mut pflag; + let mut dflags; + let alias_list: *mut *mut AliasT; + let mut t: *mut AliasT; + let mut name: *mut libc::c_char; + let mut value: *mut libc::c_char; + + dflags = if unsafe { posixly_correct != 0 } { + 0 as libc::c_int + } else { + 0x1 as libc::c_int + }; + pflag = 0 as libc::c_int; + reset_internal_getopt(); + loop { + offset = internal_getopt( + list, + b"p\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if !(offset != -(1 as libc::c_int)) { + break; + } + match offset as u8 { + b'p' => { + pflag = 1; + dflags |= AL_REUSABLE; + } + _ => { + if offset == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + } + unsafe { + list = loptend; + if list.is_null() || pflag != 0 { + if aliases.is_null() { + return EXECUTION_SUCCESS!(); + } + alias_list = all_aliases(); + if alias_list.is_null() { + return EXECUTION_SUCCESS!(); + } + offset = 0; + while !(*alias_list.offset(offset as isize)).is_null() { + print_alias(*alias_list.offset(offset as isize), dflags); + offset += 1; + } + libc::free(alias_list as *mut libc::c_void); + if list.is_null() { + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + } + any_failed = 0; + while !list.is_null() { + name = (*(*list).word).word; + offset = 0; + while *name.offset(offset as isize) as libc::c_int != 0 + && *name.offset(offset as isize) as libc::c_int != '=' as i32 + { + offset += 1; + } + if offset != 0 && *name.offset(offset as isize) as libc::c_int == '=' as i32 { + *name.offset(offset as isize) = '\u{0}' as i32 as libc::c_char; + value = name + .offset(offset as isize) + .offset(1 as libc::c_int as isize); + if legal_alias_name(name, 0) == 0 { + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"`%s': invalid alias name\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + any_failed += 1; + } else { + let slice = CStr::from_ptr(value); + let r_str = slice.to_str().unwrap().to_owned(); + let new_str = CString::new(r_str).unwrap(); + if legal_alias_rust(name, new_str.as_ptr() as *mut libc::c_char) == 0 { + add_alias(name, value); + } + } + } else { + t = find_alias(name); + if !t.is_null() { + print_alias(t, dflags); + } else { + sh_notfound(name); + any_failed += 1; + } + } + list = (*list).next; + } + } + return if any_failed != 0 { + EXECUTION_FAILURE!() + } else { + EXECUTION_SUCCESS!() + }; +} + +#[no_mangle] +pub fn unalias_builtin(mut list: *mut WordList) -> libc::c_int { + let mut alias: *mut AliasT; + let mut opt: libc::c_int; + let mut aflag: libc::c_int; + aflag = 0 as libc::c_int; + reset_internal_getopt(); + loop { + opt = internal_getopt( + list, + b"a\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if !(opt != -(1 as libc::c_int)) { + break; + } + match opt as u8 { + b'a' => { + aflag = 1 as libc::c_int; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + } + unsafe { + list = loptend; + if aflag != 0 { + delete_all_aliases(); + return 0; + } + if list.is_null() { + builtin_usage(); + return EX_USAGE!(); + } + aflag = 0 as libc::c_int; + while !list.is_null() { + alias = find_alias((*(*list).word).word); + if !alias.is_null() { + remove_alias((*alias).name); + } else { + sh_notfound((*(*list).word).word); + aflag += 1; + } + list = (*list).next; + } + } + return if aflag != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; +} + +fn print_alias(alias: *mut AliasT, flags: libc::c_int) { + let value: *mut libc::c_char; + unsafe { + value = sh_single_quote((*alias).value); + if flags & 0x1 as libc::c_int != 0 { + print!("alias "); + //printf( + // b"alias %s\0" as *const u8 as *const libc::c_char, + if !((*alias).name).is_null() + && *((*alias).name).offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + { + // b"-- \0" as *const u8 as *const libc::c_char + print!("-- "); + } else { + // b"\0" as *const u8 as *const libc::c_char + print!(" "); + } + //); + } + println!( + "{}={}", + CStr::from_ptr((*alias).name).to_string_lossy().into_owned(), + CStr::from_ptr(value).to_string_lossy().into_owned() + ); + libc::free(value as *mut libc::c_void); + } +} + +//增加alias安全策略逻辑 +fn legal_alias_rust(name: *mut libc::c_char, value: *mut libc::c_char) -> libc::c_int { + let name_w: *mut libc::c_char; + let value_w: *mut libc::c_char; + let new_value: *mut libc::c_char; + let mut new_value_2: *mut libc::c_char; + let mut _shell_bui: *mut libc::c_char; + let mut t: *mut AliasT; + let dflags; + dflags = if unsafe { posixly_correct != 0 } { + 0 as libc::c_int + } else { + 0x1 as libc::c_int + }; + unsafe { + if libc::strstr( + value, + CString::new(";").unwrap().as_ptr() as *mut libc::c_char, + ) != std::ptr::null_mut() + { + println!("; is not allow in alias"); + return 1; + } + t = find_alias(name); + if !t.is_null() { + println!( + "{} is already in alias", + CStr::from_ptr(name).to_string_lossy().into_owned() + ); + print_alias(t, dflags); + return 1; + } + name_w = find_user_command(name); + new_value = sh_single_quote(value); + // 按照空格区分 + new_value_2 = libc::strtok( + value, + CString::new(" ").unwrap().as_ptr() as *mut libc::c_char, + ); + t = find_alias(new_value_2); + while t != std::ptr::null_mut() { + new_value_2 = libc::strtok( + (*t).value, + CString::new(" ").unwrap().as_ptr() as *mut libc::c_char, + ); + if libc::strcmp((*t).name, new_value_2) == 0 { + break; + } + t = find_alias(new_value_2); + } + } + let arr: [*mut libc::c_char; 7] = [ + CString::new("exec").unwrap().into_raw() as *mut libc::c_char, + CString::new("eval").unwrap().into_raw() as *mut libc::c_char, + CString::new("builtin").unwrap().into_raw() as *mut libc::c_char, + CString::new("command").unwrap().into_raw() as *mut libc::c_char, + CString::new("function").unwrap().into_raw() as *mut libc::c_char, + CString::new("source").unwrap().into_raw() as *mut libc::c_char, + CString::new(".").unwrap().into_raw() as *mut libc::c_char, + ]; + + for index in 0..7 { + unsafe { + if libc::strcmp(new_value_2, arr[index]) == 0 { + println!( + "command {} will raise an unsafe operation", + CStr::from_ptr(arr[index]).to_string_lossy().into_owned() + ); + return 1; + } + } + } + unsafe { + value_w = find_user_command(new_value_2); + if name_w != std::ptr::null_mut() { + if value_w != std::ptr::null_mut() && libc::strcmp(name_w, value_w) == 0 { + return 0; + } else { + println!("The name and value point to different executable files"); + return 1; + } + } else { + if find_shell_builtin(name) != None { + println!( + "name {} is shell builtin", + CStr::from_ptr(name).to_string_lossy().into_owned() + ); + return 1; + } else if find_function(name) != std::ptr::null_mut() { + println!( + "name {} is function", + CStr::from_ptr(name).to_string_lossy().into_owned() + ); + return 1; + } + } + } + return 0; +} diff --git a/utshell-0.5.0/src/builtins/bashgetopt.rs b/utshell-0.5.0/src/builtins/bashgetopt.rs new file mode 100644 index 00000000..cb2ba0c2 --- /dev/null +++ b/utshell-0.5.0/src/builtins/bashgetopt.rs @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::general::legal_number; +use crate::src_common::*; + +use crate::builtins::common::{sh_invalidopt, sh_needarg, sh_neednumarg}; + +static mut sp: libc::c_int = 0; +static mut lhead: *mut WordList = 0 as *const libc::c_void as *mut libc::c_void as *mut WordList; + +#[no_mangle] +pub fn internal_getopt(mut list: *mut WordList, mut opts: *mut libc::c_char) -> libc::c_int { + let mut c: libc::c_int = 0; + let mut cp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut plus: libc::c_int = 0; + static mut errstr: [libc::c_char; 3] = [ + '-' as i32 as libc::c_char, + '\u{0}' as i32 as libc::c_char, + '\u{0}' as i32 as libc::c_char, + ]; + unsafe { + plus = (*opts as libc::c_int == '+' as i32) as libc::c_int; + if plus != 0 { + opts = opts.offset(1); + } + if list.is_null() { + list_optarg = 0 as *mut libc::c_void as *mut libc::c_char; + loptend = 0 as *mut libc::c_void as *mut WordList; + return -(1 as libc::c_int); + } + if list != lhead || lhead.is_null() { + sp = 1 as libc::c_int; + lhead = list; + lcurrent = lhead; + loptend = 0 as *mut libc::c_void as *mut WordList; + } + if sp == 1 as libc::c_int { + if lcurrent.is_null() + || (*(*(*lcurrent).word).word as libc::c_int != '-' as i32 + && (plus == 0 || *(*(*lcurrent).word).word as libc::c_int != '+' as i32) + || *((*(*lcurrent).word).word).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + lhead = 0 as *mut libc::c_void as *mut WordList; + loptend = lcurrent; + return -(1 as libc::c_int); + } else { + if *((*(*lcurrent).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == (*::std::mem::transmute::<&[u8; 7], &[libc::c_char; 7]>(b"--help\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp( + (*(*lcurrent).word).word, + b"--help\0" as *const u8 as *const libc::c_char, + ) == 0 as libc::c_int + { + lhead = 0 as *mut libc::c_void as *mut WordList; + loptend = lcurrent; + return -(99 as libc::c_int); + } else { + if *((*(*lcurrent).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && *((*(*lcurrent).word).word).offset(1 as libc::c_int as isize) + as libc::c_int + == '-' as i32 + && *((*(*lcurrent).word).word).offset(2 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int + { + lhead = 0 as *mut libc::c_void as *mut WordList; + loptend = (*lcurrent).next; + return -(1 as libc::c_int); + } + } + } + list_opttype = + *((*(*lcurrent).word).word).offset(0 as libc::c_int as isize) as libc::c_int; + errstr[0 as libc::c_int as usize] = list_opttype as libc::c_char; + } + c = *((*(*lcurrent).word).word).offset(sp as isize) as libc::c_int; + list_optopt = c; + if c == ':' as i32 || { + cp = strchr(opts, c); + cp.is_null() + } { + errstr[1 as libc::c_int as usize] = c as libc::c_char; + sh_invalidopt(errstr.as_mut_ptr()); + sp += 1; + if *((*(*lcurrent).word).word).offset(sp as isize) as libc::c_int == '\u{0}' as i32 { + lcurrent = (*lcurrent).next; + sp = 1 as libc::c_int; + } + list_optarg = 0 as *mut libc::c_char; + if !lcurrent.is_null() { + loptend = (*lcurrent).next; + } + return '?' as i32; + } + cp = cp.offset(1); + if *cp as libc::c_int == ':' as i32 || *cp as libc::c_int == ';' as i32 { + if *((*(*lcurrent).word).word).offset((sp + 1 as libc::c_int) as isize) != 0 { + list_optarg = ((*(*lcurrent).word).word) + .offset(sp as isize) + .offset(1 as libc::c_int as isize); + lcurrent = (*lcurrent).next; + } else if !((*lcurrent).next).is_null() + && (*cp as libc::c_int == ':' as i32 + || (*(*(*(*lcurrent).next).word).word as libc::c_int != '-' as i32 + && (plus == 0 + || *(*(*(*lcurrent).next).word).word as libc::c_int != '+' as i32) + || *((*(*(*lcurrent).next).word).word).offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32)) + { + lcurrent = (*lcurrent).next; + list_optarg = (*(*lcurrent).word).word; + lcurrent = (*lcurrent).next; + } else if *cp as libc::c_int == ';' as i32 { + list_optarg = 0 as *mut libc::c_void as *mut libc::c_char; + lcurrent = (*lcurrent).next; + } else { + errstr[1 as libc::c_int as usize] = c as libc::c_char; + sh_needarg(errstr.as_mut_ptr()); + sp = 1 as libc::c_int; + list_optarg = 0 as *mut libc::c_void as *mut libc::c_char; + return '?' as i32; + } + sp = 1 as libc::c_int; + } else if *cp as libc::c_int == '#' as i32 { + if *((*(*lcurrent).word).word).offset((sp + 1 as libc::c_int) as isize) != 0 { + if *((*(*lcurrent).word).word).offset((sp + 1 as libc::c_int) as isize) + as libc::c_int + >= '0' as i32 + && *((*(*lcurrent).word).word).offset((sp + 1 as libc::c_int) as isize) + as libc::c_int + <= '9' as i32 + { + list_optarg = ((*(*lcurrent).word).word) + .offset(sp as isize) + .offset(1 as libc::c_int as isize); + lcurrent = (*lcurrent).next; + } else { + list_optarg = 0 as *mut libc::c_void as *mut libc::c_char; + } + } else if !((*lcurrent).next).is_null() + && legal_number((*(*(*lcurrent).next).word).word, 0 as *mut intmax_t) != 0 + { + lcurrent = (*lcurrent).next; + list_optarg = (*(*lcurrent).word).word; + lcurrent = (*lcurrent).next; + } else { + errstr[1 as libc::c_int as usize] = c as libc::c_char; + sh_neednumarg(errstr.as_mut_ptr()); + sp = 1 as libc::c_int; + list_optarg = 0 as *mut libc::c_void as *mut libc::c_char; + return '?' as i32; + } + } else { + sp += 1; + if *((*(*lcurrent).word).word).offset(sp as isize) as libc::c_int == '\u{0}' as i32 { + sp = 1 as libc::c_int; + lcurrent = (*lcurrent).next; + } + list_optarg = 0 as *mut libc::c_void as *mut libc::c_char; + } + return c; + } +} +#[no_mangle] +pub fn reset_internal_getopt() { + unsafe { + loptend = 0 as *mut libc::c_void as *mut WordList; + lcurrent = loptend; + lhead = lcurrent; + sp = 1 as libc::c_int; + } +} diff --git a/utshell-0.5.0/src/builtins/bind.rs b/utshell-0.5.0/src/builtins/bind.rs new file mode 100644 index 00000000..809a7ec2 --- /dev/null +++ b/utshell-0.5.0/src/builtins/bind.rs @@ -0,0 +1,418 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::bashgetopt::{internal_getopt, reset_internal_getopt}; +use super::common::{builtin_usage, err_translate_fn, sh_chkwrite, translate_fn}; +use super::help::builtin_help; +use crate::bashline::initialize_readline; +use crate::bashline::{ + bash_execute_unix_command, bind_keyseq_to_unix_command, print_unix_command_map, + unbind_unix_command, +}; +use crate::general::printable_filename; +use crate::src_common::*; +use crate::unwind_prot::{begin_unwind_frame, run_unwind_frame, unwind_protect_mem}; + +#[no_mangle] +pub fn bind_builtin(mut list: *mut WordList) -> i32 { + let mut return_code: i32; + let mut kmap: Keymap; + let mut saved_keymap: Keymap; + let mut flags: i32; + let mut opt: i32; + let mut initfile: *mut libc::c_char; + let mut map_name: *mut libc::c_char; + let mut fun_name: *mut libc::c_char; + let mut unbind_name: *mut libc::c_char; + let mut remove_seq: *mut libc::c_char; + let mut cmd_seq: *mut libc::c_char; + let t: *mut libc::c_char; + + unsafe { + if no_line_editing != 0 { + builtin_warning(dcgettext( + 0 as *const libc::c_char, + CString::new("line editing not enabled").unwrap().as_ptr() as *const libc::c_char, + 5 as libc::c_int, + )); + } + + kmap = std::ptr::null_mut(); + saved_keymap = std::ptr::null_mut(); + flags = 0; + initfile = std::ptr::null_mut(); + map_name = std::ptr::null_mut(); + fun_name = std::ptr::null_mut(); + unbind_name = std::ptr::null_mut(); + remove_seq = std::ptr::null_mut(); + cmd_seq = std::ptr::null_mut(); + + return_code = EXECUTION_SUCCESS!(); + + if bash_readline_initialized == 0 { + initialize_readline(); + } + let bind_str = CString::new("bind_builtin").unwrap(); + + begin_unwind_frame(bind_str.as_ptr() as *mut libc::c_char); + + unwind_protect_mem( + &mut rl_outstream as *mut *mut FILE as *mut libc::c_char, + ::std::mem::size_of::<*mut libc::FILE>() as libc::c_ulong as libc::c_int, + ); + + rl_outstream = stdout; + reset_internal_getopt(); + + let c_str = CString::new("lvpVPsSXf:q:u:m:r:x:").unwrap(); + let c_ptr = c_str.as_ptr() as *mut libc::c_char; + opt = internal_getopt(list, c_ptr); + while opt != -1 { + let optu8 = opt as u8; + let opt_char = char::from(optu8); + match opt_char { + 'l' => flags |= LFLAG!(), + 'v' => flags |= VFLAG!(), + 'p' => flags |= PFLAG!(), + 'f' => { + flags |= FFLAG!(); + initfile = list_optarg; + } + 'm' => { + flags |= MFLAG!(); + map_name = list_optarg; + } + 'q' => { + flags |= QFLAG!(); + fun_name = list_optarg; + } + 'u' => { + flags |= UFLAG!(); + unbind_name = list_optarg; + } + 'r' => { + flags |= RFLAG!(); + remove_seq = list_optarg; + } + 'V' => flags |= VVFLAG!(), + 'P' => flags |= PPFLAG!(), + 's' => flags |= SFLAG!(), + 'S' => flags |= SSFLAG!(), + 'x' => { + flags |= XFLAG!(); + cmd_seq = list_optarg; + } + 'X' => flags |= XXFLAG!(), + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + + return_code = EX_USAGE!(); + if !saved_keymap.is_null() { + rl_set_keymap(saved_keymap); + } + run_unwind_frame(bind_str.as_ptr() as *mut libc::c_char); + if return_code < 0 { + return_code = EXECUTION_FAILURE!(); + } + return sh_chkwrite(return_code); + } + } + opt = internal_getopt(list, c_ptr); + } + + list = loptend; + + /* First, see if we need to install a special keymap for this + command. Then start on the arguments. */ + + if (flags & MFLAG!()) != 0 && !map_name.is_null() { + kmap = rl_get_keymap_by_name(map_name); + if kmap.is_null() { + let names = String::from("invaildmap"); + err_translate_fn(&names, map_name); + println!(); + return_code = EXECUTION_FAILURE!(); + if !saved_keymap.is_null() { + rl_set_keymap(saved_keymap); + } + run_unwind_frame(bind_str.as_ptr() as *mut libc::c_char); + if return_code < 0 { + return_code = EXECUTION_FAILURE!(); + } + return sh_chkwrite(return_code); + } + } + + if !kmap.is_null() { + saved_keymap = rl_get_keymap(); + rl_set_keymap(kmap); + } + + /* XXX - we need to add exclusive use tests here. It doesn't make sense + to use some of these options together. */ + /* Now hack the option arguments */ + if flags & LFLAG!() != 0 { + rl_list_funmap_names(); + } + if flags & PFLAG!() != 0 { + rl_function_dumper(1); + } + if flags & PPFLAG!() != 0 { + rl_function_dumper(0); + } + if flags & SFLAG!() != 0 { + rl_macro_dumper(1); + } + if flags & SSFLAG!() != 0 { + rl_macro_dumper(0); + } + if flags & VFLAG!() != 0 { + rl_variable_dumper(1); + } + if flags & VVFLAG!() != 0 { + rl_variable_dumper(0); + } + + if (flags & FFLAG!()) != 0 && !initfile.is_null() { + if rl_read_init_file(initfile) != 0 { + t = printable_filename(initfile, 0); + let c_str = CString::new("%s: cannot read: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + + builtin_error(c_ptr, t, strerror(nix::errno::errno())); + if t != initfile { + free(t as *mut c_void); + } + return_code = EXECUTION_FAILURE!(); + if !saved_keymap.is_null() { + rl_set_keymap(saved_keymap); + } + run_unwind_frame(bind_str.as_ptr() as *mut libc::c_char); + if return_code < 0 { + return_code = EXECUTION_FAILURE!(); + } + return sh_chkwrite(return_code); + } + } + + if (flags & QFLAG!()) != 0 && !fun_name.is_null() { + return_code = query_bindings(fun_name); + } + + if (flags & UFLAG!()) != 0 && !unbind_name.is_null() { + return_code = unbind_command(unbind_name); + } + + if (flags & RFLAG!()) != 0 && !remove_seq.is_null() { + opt = unbind_keyseq(remove_seq); + return_code = opt; + if !saved_keymap.is_null() { + rl_set_keymap(saved_keymap); + } + run_unwind_frame(bind_str.as_ptr() as *mut libc::c_char); + if return_code < 0 { + return_code = EXECUTION_FAILURE!(); + } + return sh_chkwrite(return_code); + } + + if flags & XFLAG!() != 0 { + return_code = bind_keyseq_to_unix_command(cmd_seq); + } + + if flags & XXFLAG!() != 0 { + return_code = print_unix_command_map(); + } + + /* Process the rest of the arguments as binding specifications. */ + while !list.is_null() { + let olen: i32; + let nlen: i32; + let mut d: i32; + let mut i: i32; + let obindings: *mut *mut libc::c_char; + let nbindings: *mut *mut libc::c_char; + + obindings = rl_invoking_keyseqs(bash_execute_unix_command as *mut rl_command_func_t); + if !obindings.is_null() { + olen = strvec_len(obindings); + } else { + olen = 0; + } + + rl_parse_and_bind((*(*list).word).word); + + nbindings = rl_invoking_keyseqs(bash_execute_unix_command as *mut rl_command_func_t); + if !nbindings.is_null() { + nlen = strvec_len(nbindings); + } else { + nlen = 0; + } + + if nlen < olen { + d = olen - nlen; + i = 0; + let mut t: *mut libc::c_char; + while i < olen && d > 0 { + t = *((obindings as usize + (i * 8) as usize) as *mut *mut libc::c_char) + as *mut libc::c_char; + if nlen == 0 || strvec_search(nbindings, t) >= 0 { + unbind_unix_command(t); + d = d - 1; + } + i += 1; + } + } + + strvec_dispose(obindings); + strvec_dispose(nbindings); + + list = (*list).next; + } + + if !saved_keymap.is_null() { + rl_set_keymap(saved_keymap); + } + run_unwind_frame(bind_str.as_ptr() as *mut libc::c_char); + + if return_code < 0 { + return_code = EXECUTION_FAILURE!(); + } + + return sh_chkwrite(return_code); + } //unsafe +} + +#[no_mangle] +fn query_bindings(name: *mut libc::c_char) -> i32 { + let function: *mut rl_command_func_t; + let keyseqs: *mut *mut libc::c_char; + let mut j: i32; + // let mut name_str:String; + + unsafe { + function = rl_named_function(name); + if function.is_null() { + let names = String::from("unknowdfunction"); + err_translate_fn(&names, name); + println!(); + return EXECUTION_FAILURE!(); + } + + keyseqs = rl_invoking_keyseqs(function); + + if keyseqs.is_null() { + let names = String::from("bindnokeys"); + err_translate_fn(&names, name); + println!(); + return EXECUTION_FAILURE!(); + } + let names = String::from("bindvia"); + translate_fn(&names, name); + j = 0; + let mut t: *mut libc::c_char; + t = *keyseqs; + while j < 5 && !t.is_null() { + let c: String; + if !(*((keyseqs as usize + ((j + 1) * 8) as usize) as *mut *mut libc::c_char) + as *mut libc::c_char) + .is_null() + { + c = String::from(","); + } else { + c = String::from(".\n"); + } + let c_cstr = CStr::from_ptr(t); + let c_str = c_cstr.to_str().unwrap(); + print!("\"{}\"{}", c_str, c); + j += 1; + t = *((keyseqs as usize + (j * 8) as usize) as *mut *mut libc::c_char) + as *mut libc::c_char; + } + if !(*((keyseqs as usize + (j * 8) as usize) as *mut *mut libc::c_char) + as *mut libc::c_char) + .is_null() + { + print!("...\n"); + } + strvec_dispose(keyseqs); + return EXECUTION_SUCCESS!(); + } +} + +#[no_mangle] +fn unbind_command(name: *mut libc::c_char) -> i32 { + let function: *mut rl_command_func_t; + + unsafe { + function = rl_named_function(name); + if function.is_null() { + let names = String::from("unknowdfunction"); + err_translate_fn(&names, name); + println!(); + return EXECUTION_FAILURE!(); + } + + rl_unbind_function_in_map(function, rl_get_keymap()); + return EXECUTION_SUCCESS!(); + } +} + +#[no_mangle] +fn unbind_keyseq(seq: *mut libc::c_char) -> i32 { + let kseq: *mut libc::c_char; + let mut kslen: i32 = 0; + let mut type1: i32 = 0; + let mut f: Option = None; + unsafe { + kseq = malloc((2 * strlen(seq) as usize) + 1) as *mut libc::c_char; + if rl_translate_keyseq(seq, kseq, &mut kslen) != 0 { + free(kseq as *mut c_void); + let names = String::from("unbindfaild"); + err_translate_fn(&names, seq); + println!(); + return EXECUTION_FAILURE!(); + } + //å¯èƒ½å­˜åœ¨é”™è¯¯ + f = rl_function_of_keyseq_len(kseq, kslen as size_t, 0 as Keymap, &mut type1); + if f.is_none() { + free(kseq as *mut c_void); + return EXECUTION_SUCCESS!(); + } + + if type1 == ISKMAP!() { + //䏿¸…楚这个æ¡ä»¶æ˜¯å¦‚何触å‘的,所以下é¢è¯­å¥å¯èƒ½å­˜åœ¨é—®é¢˜ + // f = (*(f as Keymap).offset(ANYOTHERKEY!() as isize)).function ; + f = (*(::std::mem::transmute::, Keymap>(f)) + .offset(ANYOTHERKEY!() as isize)) + .function; + } + + /* I wish this didn't have to translate the key sequence again, but readline + doesn't have a binding function that takes a translated key sequence as + an argument. */ + if rl_bind_keyseq(seq, std::ptr::null_mut() as *mut rl_command_func_t) != 0 { + free(kseq as *mut c_void); + let names = String::from("unbindfaild"); + err_translate_fn(&names, seq); + println!(); + return EXECUTION_FAILURE!(); + } + + if f == Some(bash_execute_unix_command as rl_command_func_t) { + unbind_unix_command(seq); + } + free(kseq as *mut c_void); + return EXECUTION_SUCCESS!(); + } +} diff --git a/utshell-0.5.0/src/builtins/break_1.rs b/utshell-0.5.0/src/builtins/break_1.rs new file mode 100644 index 00000000..73e8226e --- /dev/null +++ b/utshell-0.5.0/src/builtins/break_1.rs @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::common::{get_numeric_arg, sh_erange}; +use super::help::builtin_help; +use crate::src_common::*; + +fn checkhelp(l: *mut WordList) -> i32 { + unsafe { + let tmp = CString::new("--help").unwrap(); + if l != std::ptr::null_mut() + && (*l).word != std::ptr::null_mut() + && libc::strcmp((*((*l).word)).word, tmp.as_ptr()) == 0 + { + builtin_help(); + } + return EX_USAGE!(); + } +} + +/* Set up to break x levels, where x defaults to 1, but can be specified +as the first argument. */ +#[no_mangle] +pub fn break_builtin(list: *mut WordList) -> i32 { + let mut newbreak: intmax_t = 1 as intmax_t; + unsafe { + // checkhelp(list); + CHECK_HELPOPT!(list); + if check_loop_level() == 0 { + return EXECUTION_SUCCESS!(); + } + get_numeric_arg(list, 1, &mut newbreak as *mut intmax_t); + + if newbreak <= 0 { + let tmp = CString::new("loop count ").unwrap(); + sh_erange((*(*list).word).word, tmp.as_ptr() as *mut libc::c_char); + //set_breaking (get_loop_level()); + breaking = loop_level; + return EXECUTION_FAILURE!(); + } + + if newbreak > loop_level as libc::c_long { + newbreak = loop_level as i64; + } + breaking = newbreak as i32; + } + return EXECUTION_SUCCESS!(); +} + +/* Set up to continue x levels, where x defaults to 1, but can be specified +as the first argument. */ +#[no_mangle] +pub fn continue_builtin(list: *mut WordList) -> i32 { + let mut newcont: intmax_t = 0 as intmax_t; + unsafe { + CHECK_HELPOPT!(list); + // checkhelp(list); + } + if check_loop_level() == 0 { + return EXECUTION_SUCCESS!(); + } + + get_numeric_arg(list, 1, &mut newcont as *mut intmax_t); + + unsafe { + if newcont <= 0 { + let tmp = CString::new("loop count ").unwrap(); + sh_erange((*(*list).word).word, tmp.as_ptr() as *mut libc::c_char); + //set_breaking(get_loop_level()); + breaking = loop_level; + return EXECUTION_FAILURE!(); + } + if newcont > loop_level.into() { + newcont = loop_level as i64; + } + continuing = newcont as i32; + //set_continuing(newcont as i32); + } + return EXECUTION_SUCCESS!(); +} + +/* Return non-zero if a break or continue command would be okay. +Print an error message if break or continue is meaningless here. */ +#[no_mangle] +pub fn check_loop_level() -> i32 { + unsafe { + if loop_level == 0 && posixly_correct == 0 { + builtin_error( + b"only meaningful in a `for`, `while`, or until `loop` \0" as *const u8 + as *const libc::c_char, + ); + return 0; + } + loop_level + } +} diff --git a/utshell-0.5.0/src/builtins/builtin.rs b/utshell-0.5.0/src/builtins/builtin.rs new file mode 100644 index 00000000..d160d64e --- /dev/null +++ b/utshell-0.5.0/src/builtins/builtin.rs @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::common::{find_shell_builtin, no_options, sh_notbuiltin}; +use crate::src_common::*; + +#[no_mangle] +pub fn builtin_builtin(mut list: *mut WordList) -> i32 { + unsafe { + let mut function: Option = None; + let mut command: *mut libc::c_char = 0 as *mut libc::c_char; + if no_options(list) != 0 { + return 258 as libc::c_int; + } + list = loptend; + if list.is_null() { + return 0 as libc::c_int; + } + command = (*(*list).word).word; + function = find_shell_builtin(command); + if function.is_none() { + sh_notbuiltin(command); + return 1 as libc::c_int; + } else { + this_command_name = command; + this_shell_builtin = function; + list = (*list).next; + return (Some(function.expect("non-null function pointer"))) + .expect("non-null function pointer")(list); + }; + } +} diff --git a/utshell-0.5.0/src/builtins/builtins.rs b/utshell-0.5.0/src/builtins/builtins.rs new file mode 100644 index 00000000..b1a525b3 --- /dev/null +++ b/utshell-0.5.0/src/builtins/builtins.rs @@ -0,0 +1,1480 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +use super::alias::{alias_builtin, unalias_builtin}; +use super::bind::bind_builtin; +use super::break_1::{break_builtin, continue_builtin}; +use super::builtin::builtin_builtin; +use super::caller::caller_builtin; +use super::cd::{cd_builtin, pwd_builtin}; +use super::colon::{colon_builtin, false_builtin}; +use super::command::command_builtin; +use super::complete::{compgen_builtin, complete_builtin, compopt_builtin}; +use super::declare::{declare_builtin, local_builtin}; +use super::echo::echo_builtin; +use super::enable::enable_builtin; +use super::eval::eval_builtin; +use super::exec::exec_builtin; +use super::exit::{exit_builtin, logout_builtin}; +use super::fc::fc_builtin; +use super::fg_bg::{bg_builtin, fg_builtin}; +use super::getopts::getopts_builtin; +use super::hash::hash_builtin; +use super::help::help_builtin; +use super::history::history_builtin; +use super::jobs::disown_builtin; +use super::jobs::jobs_builtin; +use super::kill::kill_builtin; +use super::let_1::let_builtin; +use super::mapfile::mapfile_builtin; +use super::printf::printf_builtin; +use super::pushd::{dirs_builtin, popd_builtin, pushd_builtin}; +use super::read::read_builtin; +use super::return_1::return_builtin; +use super::set::{set_builtin, unset_builtin}; +use super::setattr::{export_builtin, readonly_builtin}; +use super::shift::shift_builtin; +use super::shopt::shopt_builtin; +use super::source::source_builtin; +use super::suspend::suspend_builtin; +use super::test::test_builtin; +use super::times::times_builtin; +use super::trap::trap_builtin; +use super::type_1::type_builtin; +use super::ulimit::ulimit_builtin; +use super::umask::umask_builtin; +use super::wait::wait_builtin; + +#[no_mangle] +pub static mut static_shell_builtins: [builtin; 77] = unsafe { + [ + { + let mut init = builtin { + name: b"alias\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(alias_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x10 as libc::c_int + | 0x20 as libc::c_int, + long_doc: alias_doc.as_ptr(), + short_doc: b"alias [-p] [name[=value] ... ]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"unalias\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(unalias_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: unalias_doc.as_ptr(), + short_doc: b"unalias [-a] name [name ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"bind\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some( + bind_builtin as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: bind_doc.as_ptr(), + short_doc: b"bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"break\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(break_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: break_doc.as_ptr(), + short_doc: b"break [n]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"continue\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(continue_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: continue_doc.as_ptr(), + short_doc: b"continue [n]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"builtin\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(builtin_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: builtin_doc.as_ptr(), + short_doc: b"builtin [shell-builtin [arg ...]]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"caller\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(caller_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: caller_doc.as_ptr(), + short_doc: b"caller [expr]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"cd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(cd_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: cd_doc.as_ptr(), + short_doc: b"cd [-L|[-P [-e]] [-@]] [dir]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"pwd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(pwd_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: pwd_doc.as_ptr(), + short_doc: b"pwd [-LP]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b":\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(colon_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: colon_doc.as_ptr(), + short_doc: b":\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"true\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(colon_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: true_doc.as_ptr(), + short_doc: b"true\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"false\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(false_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: false_doc.as_ptr(), + short_doc: b"false\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"command\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(command_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x20 as libc::c_int + | 0x80 as libc::c_int, + long_doc: command_doc.as_ptr(), + short_doc: b"command [-pVv] command [arg ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"declare\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(declare_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x10 as libc::c_int + | 0x40 as libc::c_int, + long_doc: declare_doc.as_ptr(), + short_doc: b"declare [-aAfFgiIlnrtux] [-p] [name[=value] ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"typeset\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(declare_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x10 as libc::c_int + | 0x40 as libc::c_int, + long_doc: typeset_doc.as_ptr(), + short_doc: b"typeset [-aAfFgiIlnrtux] [-p] name[=value] ...\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"local\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(local_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x10 as libc::c_int + | 0x40 as libc::c_int, + long_doc: local_doc.as_ptr(), + short_doc: b"local [option] name[=value] ...\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"echo\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(echo_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: echo_doc.as_ptr(), + short_doc: b"echo [-neE] [arg ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"enable\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(enable_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: enable_doc.as_ptr(), + short_doc: b"enable [-a] [-dnps] [-f filename] [name ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"eval\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(eval_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: eval_doc.as_ptr(), + short_doc: b"eval [arg ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"getopts\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(getopts_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: getopts_doc.as_ptr(), + short_doc: b"getopts optstring name [arg ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"exec\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(exec_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x8 as libc::c_int + | 0x80 as libc::c_int, + long_doc: exec_doc.as_ptr(), + short_doc: b"exec [-cl] [-a name] [command [argument ...]] [redirection ...]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"exit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(exit_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: exit_doc.as_ptr(), + short_doc: b"exit [n]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"logout\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(logout_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: logout_doc.as_ptr(), + short_doc: b"logout [n]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"fc\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(fc_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: fc_doc.as_ptr(), + short_doc: b"fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"fg\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(fg_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: fg_doc.as_ptr(), + short_doc: b"fg [job_spec]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"bg\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(bg_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: bg_doc.as_ptr(), + short_doc: b"bg [job_spec ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"hash\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(hash_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: hash_doc.as_ptr(), + short_doc: b"hash [-lr] [-p pathname] [-dt] [name ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"help\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(help_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: help_doc.as_ptr(), + short_doc: b"help [-dms] [pattern ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"history\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + function: Some( + history_builtin + as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: history_doc.as_ptr(), + short_doc: b"history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"jobs\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(jobs_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: jobs_doc.as_ptr(), + short_doc: b"jobs [-lnprs] [jobspec ...] or jobs -x command [args]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"disown\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(disown_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: disown_doc.as_ptr(), + short_doc: b"disown [-h] [-ar] [jobspec ... | pid ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"kill\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some( + kill_builtin as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: kill_doc.as_ptr(), + short_doc: b"kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"let\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(let_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: let_doc.as_ptr(), + short_doc: b"let arg [arg ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"read\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some( + read_builtin as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: read_doc.as_ptr(), + short_doc: b"read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"return\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(return_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: return_doc.as_ptr(), + short_doc: b"return [n]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"set\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(set_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: set_doc.as_ptr(), + short_doc: b"set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"unset\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(unset_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: unset_doc.as_ptr(), + short_doc: b"unset [-f] [-v] [-n] [name ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"export\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(export_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x8 as libc::c_int + | 0x10 as libc::c_int, + long_doc: export_doc.as_ptr(), + short_doc: b"export [-fn] [name[=value] ...] or export -p\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"readonly\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(readonly_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x8 as libc::c_int + | 0x10 as libc::c_int, + long_doc: readonly_doc.as_ptr(), + short_doc: b"readonly [-aAf] [name[=value] ...] or readonly -p\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"shift\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(shift_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: shift_doc.as_ptr(), + short_doc: b"shift [n]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"source\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(source_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x8 as libc::c_int + | 0x80 as libc::c_int, + long_doc: source_doc.as_ptr(), + short_doc: b"source filename [arguments]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b".\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(source_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int + | 0x4 as libc::c_int + | 0x8 as libc::c_int + | 0x80 as libc::c_int, + long_doc: dot_doc.as_ptr(), + short_doc: b". filename [arguments]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"suspend\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(suspend_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: suspend_doc.as_ptr(), + short_doc: b"suspend [-f]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"test\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(test_builtin), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: test_doc.as_ptr(), + short_doc: b"test [expr]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(test_builtin), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: test_bracket_doc.as_ptr(), + short_doc: b"[ arg... ]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"times\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(times_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: times_doc.as_ptr(), + short_doc: b"times\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(trap_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + long_doc: trap_doc.as_ptr(), + short_doc: b"trap [-lp] [[arg] signal_spec ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"type\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(type_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: type_doc.as_ptr(), + short_doc: b"type [-afptP] name [name ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"ulimit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(ulimit_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: ulimit_doc.as_ptr(), + short_doc: b"ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"umask\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(umask_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: umask_doc.as_ptr(), + short_doc: b"umask [-p] [-S] [mode]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"wait\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(wait_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int | 0x20 as libc::c_int, + long_doc: wait_doc.as_ptr(), + short_doc: b"wait [-fn] [-p var] [id ...]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"for\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: for_doc.as_ptr(), + short_doc: b"for NAME [in WORDS ... ] ; do COMMANDS; done\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"for ((\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: arith_for_doc.as_ptr(), + short_doc: b"for (( exp1; exp2; exp3 )); do COMMANDS; done\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"select\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: select_doc.as_ptr(), + short_doc: b"select NAME [in WORDS ... ;] do COMMANDS; done\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"time\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: time_doc.as_ptr(), + short_doc: b"time [-p] pipeline\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"case\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: case_doc.as_ptr(), + short_doc: b"case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"if\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: if_doc.as_ptr(), + short_doc: b"if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"while\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: while_doc.as_ptr(), + short_doc: b"while COMMANDS; do COMMANDS; done\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"until\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: until_doc.as_ptr(), + short_doc: b"until COMMANDS; do COMMANDS; done\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"coproc\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: coproc_doc.as_ptr(), + short_doc: b"coproc [NAME] command [redirections]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"function\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: function_doc.as_ptr(), + short_doc: b"function name { COMMANDS ; } or name () { COMMANDS ; }\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"{ ... }\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: grouping_braces_doc.as_ptr(), + short_doc: b"{ COMMANDS ; }\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"%\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: fg_percent_doc.as_ptr(), + short_doc: b"job_spec [&]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"(( ... ))\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: arith_doc.as_ptr(), + short_doc: b"(( expression ))\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"[[ ... ]]\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: conditional_doc.as_ptr(), + short_doc: b"[[ expression ]]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"variables\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: variable_help_doc.as_ptr(), + short_doc: b"variables - Names and meanings of some shell variables\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"pushd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(pushd_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: pushd_doc.as_ptr(), + short_doc: b"pushd [-n] [+N | -N | dir]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"popd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(popd_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: popd_doc.as_ptr(), + short_doc: b"popd [-n] [+N | -N]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"dirs\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(dirs_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: dirs_doc.as_ptr(), + short_doc: b"dirs [-clpv] [+N] [-N]\0" as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"shopt\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(shopt_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: shopt_doc.as_ptr(), + short_doc: b"shopt [-pqsu] [-o] [optname ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"printf\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(printf_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: printf_doc.as_ptr(), + short_doc: b"printf [-v var] format [arguments]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"complete\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + function: Some( + complete_builtin + as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: complete_doc.as_ptr(), + short_doc: b"complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"compgen\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + function: Some( + compgen_builtin + as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: compgen_doc.as_ptr(), + short_doc: b"compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"compopt\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(compopt_builtin as fn(*mut WORD_LIST) -> libc::c_int), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: compopt_doc.as_ptr(), + short_doc: b"compopt [-o|+o option] [-DEI] [name ...]\0" as *const u8 + as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"mapfile\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + function: Some( + mapfile_builtin + as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: mapfile_doc.as_ptr(), + short_doc: b"mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: b"readarray\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + function: Some( + mapfile_builtin + as fn(*mut WORD_LIST) -> libc::c_int, + ), + flags: 0x1 as libc::c_int | 0x4 as libc::c_int, + long_doc: readarray_doc.as_ptr(), + short_doc: b"readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]\0" + as *const u8 as *const libc::c_char, + handle: 0 as *const libc::c_void as *mut libc::c_void + as *mut libc::c_char, + }; + init + }, + { + let mut init = builtin { + name: 0 as *const libc::c_char as *mut libc::c_char, + function: None, + flags: 0 as libc::c_int, + long_doc: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + short_doc: 0 as *const libc::c_char as *mut libc::c_char, + handle: 0 as *const libc::c_char as *mut libc::c_char, + }; + init + }, + ] +}; +#[no_mangle] +pub static mut shell_builtins: *mut builtin = unsafe { static_shell_builtins.as_ptr() as *mut _ }; +#[no_mangle] +pub static mut current_builtin: *mut builtin = 0 as *const builtin as *mut builtin; +#[no_mangle] +pub static mut num_shell_builtins: libc::c_int = + (::std::mem::size_of::<[builtin; 77]>() as libc::c_ulong) + .wrapping_div(::std::mem::size_of::() as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) as libc::c_int; +// pub static mut num_shell_builtins: libc::c_int = 0; + +#[no_mangle] +pub static mut alias_doc: [*mut libc::c_char; 2] = [ + b"Define or display aliases.\n \n Without arguments, `alias' prints the list of aliases in the reusable\n form `alias NAME=VALUE' on standard output.\n \n Otherwise, an alias is defined for each NAME whose VALUE is given.\n A trailing space in VALUE causes the next word to be checked for\n alias substitution when the alias is expanded.\n \n Options:\n -p\tprint all defined aliases in a reusable format\n \n Exit Status:\n alias returns true unless a NAME is supplied for which no alias has been\n defined.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut unalias_doc: [*mut libc::c_char; 2] = [ + b"Remove each NAME from the list of defined aliases.\n \n Options:\n -a\tremove all alias definitions\n \n Return success unless a NAME is not an existing alias.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut bind_doc: [*mut libc::c_char; 2] = [ + b"Set Readline key bindings and variables.\n \n Bind a key sequence to a Readline function or a macro, or set a\n Readline variable. The non-option argument syntax is equivalent to\n that found in ~/.inputrc, but must be passed as a single argument:\n e.g., bind '\"\\C-x\\C-r\": re-read-init-file'.\n \n Options:\n -m keymap Use KEYMAP as the keymap for the duration of this\n command. Acceptable keymap names are emacs,\n emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,\n vi-command, and vi-insert.\n -l List names of functions.\n -P List function names and bindings.\n -p List functions and bindings in a form that can be\n reused as input.\n -S List key sequences that invoke macros and their values\n -s List key sequences that invoke macros and their values\n in a form that can be reused as input.\n -V List variable names and values\n -v List variable names and values in a form that can\n be reused as input.\n -q function-name Query about which keys invoke the named function.\n -u function-name Unbind all keys which are bound to the named function.\n -r keyseq Remove the binding for KEYSEQ.\n -f filename Read key bindings from FILENAME.\n -x keyseq:shell-command\tCause SHELL-COMMAND to be executed when\n \t\t\t\tKEYSEQ is entered.\n -X List key sequences bound with -x and associated commands\n in a form that can be reused as input.\n \n Exit Status:\n bind returns 0 unless an unrecognized option is given or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut break_doc: [*mut libc::c_char; 2] = [ + b"Exit for, while, or until loops.\n \n Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing\n loops.\n \n Exit Status:\n The exit status is 0 unless N is not greater than or equal to 1.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut continue_doc: [*mut libc::c_char; 2] = [ + b"Resume for, while, or until loops.\n \n Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.\n If N is specified, resumes the Nth enclosing loop.\n \n Exit Status:\n The exit status is 0 unless N is not greater than or equal to 1.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut builtin_doc: [*mut libc::c_char; 2] = [ + b"Execute shell builtins.\n \n Execute SHELL-BUILTIN with arguments ARGs without performing command\n lookup. This is useful when you wish to reimplement a shell builtin\n as a shell function, but need to execute the builtin within the function.\n \n Exit Status:\n Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is\n not a shell builtin.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut caller_doc: [*mut libc::c_char; 2] = [ + b"Return the context of the current subroutine call.\n \n Without EXPR, returns \"$line $filename\". With EXPR, returns\n \"$line $subroutine $filename\"; this extra information can be used to\n provide a stack trace.\n \n The value of EXPR indicates how many call frames to go back before the\n current one; the top frame is frame 0.\n \n Exit Status:\n Returns 0 unless the shell is not executing a shell function or EXPR\n is invalid.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut cd_doc: [*mut libc::c_char; 2] = [ + b"Change the shell working directory.\n \n Change the current directory to DIR. The default DIR is the value of the\n HOME shell variable.\n \n The variable CDPATH defines the search path for the directory containing\n DIR. Alternative directory names in CDPATH are separated by a colon (:).\n A null directory name is the same as the current directory. If DIR begins\n with a slash (/), then CDPATH is not used.\n \n If the directory is not found, and the shell option `cdable_vars' is set,\n the word is assumed to be a variable name. If that variable has a value,\n its value is used for DIR.\n \n Options:\n -L\tforce symbolic links to be followed: resolve symbolic\n \t\tlinks in DIR after processing instances of `..'\n -P\tuse the physical directory structure without following\n \t\tsymbolic links: resolve symbolic links in DIR before\n \t\tprocessing instances of `..'\n -e\tif the -P option is supplied, and the current working\n \t\tdirectory cannot be determined successfully, exit with\n \t\ta non-zero status\n -@\ton systems that support it, present a file with extended\n \t\tattributes as a directory containing the file attributes\n \n The default is to follow symbolic links, as if `-L' were specified.\n `..' is processed by removing the immediately previous pathname component\n back to a slash or the beginning of DIR.\n \n Exit Status:\n Returns 0 if the directory is changed, and if $PWD is set successfully when\n -P is used; non-zero otherwise.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut pwd_doc: [*mut libc::c_char; 2] = [ + b"Print the name of the current working directory.\n \n Options:\n -L\tprint the value of $PWD if it names the current working\n \t\tdirectory\n -P\tprint the physical directory, without any symbolic links\n \n By default, `pwd' behaves as if `-L' were specified.\n \n Exit Status:\n Returns 0 unless an invalid option is given or the current directory\n cannot be read.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut colon_doc: [*mut libc::c_char; 2] = [ + b"Null command.\n \n No effect; the command does nothing.\n \n Exit Status:\n Always succeeds.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut true_doc: [*mut libc::c_char; 2] = [ + b"Return a successful result.\n \n Exit Status:\n Always succeeds.\0" as *const u8 + as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut false_doc: [*mut libc::c_char; 2] = [ + b"Return an unsuccessful result.\n \n Exit Status:\n Always fails.\0" as *const u8 + as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut command_doc: [*mut libc::c_char; 2] = [ + b"Execute a simple command or display information about commands.\n \n Runs COMMAND with ARGS suppressing shell function lookup, or display\n information about the specified COMMANDs. Can be used to invoke commands\n on disk when a function with the same name exists.\n \n Options:\n -p use a default value for PATH that is guaranteed to find all of\n the standard utilities\n -v print a description of COMMAND similar to the `type' builtin\n -V print a more verbose description of each COMMAND\n \n Exit Status:\n Returns exit status of COMMAND, or failure if COMMAND is not found.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut declare_doc: [*mut libc::c_char; 2] = [ + b"Set variable values and attributes.\n \n Declare variables and give them attributes. If no NAMEs are given,\n display the attributes and values of all variables.\n \n Options:\n -f\trestrict action or display to function names and definitions\n -F\trestrict display to function names only (plus line number and\n \t\tsource file when debugging)\n -g\tcreate global variables when used in a shell function; otherwise\n \t\tignored\n -I\tif creating a local variable, inherit the attributes and value\n \t\tof a variable with the same name at a previous scope\n -p\tdisplay the attributes and value of each NAME\n \n Options which set attributes:\n -a\tto make NAMEs indexed arrays (if supported)\n -A\tto make NAMEs associative arrays (if supported)\n -i\tto make NAMEs have the `integer' attribute\n -l\tto convert the value of each NAME to lower case on assignment\n -n\tmake NAME a reference to the variable named by its value\n -r\tto make NAMEs readonly\n -t\tto make NAMEs have the `trace' attribute\n -u\tto convert the value of each NAME to upper case on assignment\n -x\tto make NAMEs export\n \n Using `+' instead of `-' turns off the given attribute.\n \n Variables with the integer attribute have arithmetic evaluation (see\n the `let' command) performed when the variable is assigned a value.\n \n When used in a function, `declare' makes NAMEs local, as with the `local'\n command. The `-g' option suppresses this behavior.\n \n Exit Status:\n Returns success unless an invalid option is supplied or a variable\n assignment error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut typeset_doc: [*mut libc::c_char; 2] = [ + b"Set variable values and attributes.\n \n A synonym for `declare'. See `help declare'.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut local_doc: [*mut libc::c_char; 2] = [ + b"Define local variables.\n \n Create a local variable called NAME, and give it VALUE. OPTION can\n be any option accepted by `declare'.\n \n Local variables can only be used within a function; they are visible\n only to the function where they are defined and its children.\n \n Exit Status:\n Returns success unless an invalid option is supplied, a variable\n assignment error occurs, or the shell is not executing a function.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut echo_doc: [*mut libc::c_char; 2] = [ + b"Write arguments to the standard output.\n \n Display the ARGs, separated by a single space character and followed by a\n newline, on the standard output.\n \n Options:\n -n\tdo not append a newline\n -e\tenable interpretation of the following backslash escapes\n -E\texplicitly suppress interpretation of backslash escapes\n \n `echo' interprets the following backslash-escaped characters:\n \\a\talert (bell)\n \\b\tbackspace\n \\c\tsuppress further output\n \\e\tescape character\n \\E\tescape character\n \\f\tform feed\n \\n\tnew line\n \\r\tcarriage return\n \\t\thorizontal tab\n \\v\tvertical tab\n \\\\\tbackslash\n \\0nnn\tthe character whose ASCII code is NNN (octal). NNN can be\n \t\t0 to 3 octal digits\n \\xHH\tthe eight-bit character whose value is HH (hexadecimal). HH\n \t\tcan be one or two hex digits\n \\uHHHH\tthe Unicode character whose value is the hexadecimal value HHHH.\n \t\tHHHH can be one to four hex digits.\n \\UHHHHHHHH the Unicode character whose value is the hexadecimal value\n \t\tHHHHHHHH. HHHHHHHH can be one to eight hex digits.\n \n Exit Status:\n Returns success unless a write error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut enable_doc: [*mut libc::c_char; 2] = [ + b"Enable and disable shell builtins.\n \n Enables and disables builtin shell commands. Disabling allows you to\n execute a disk command which has the same name as a shell builtin\n without using a full pathname.\n \n Options:\n -a\tprint a list of builtins showing whether or not each is enabled\n -n\tdisable each NAME or display a list of disabled builtins\n -p\tprint the list of builtins in a reusable format\n -s\tprint only the names of Posix `special' builtins\n \n Options controlling dynamic loading:\n -f\tLoad builtin NAME from shared object FILENAME\n -d\tRemove a builtin loaded with -f\n \n Without options, each NAME is enabled.\n \n To use the `test' found in $PATH instead of the shell builtin\n version, type `enable -n test'.\n \n Exit Status:\n Returns success unless NAME is not a shell builtin or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut eval_doc: [*mut libc::c_char; 2] = [ + b"Execute arguments as a shell command.\n \n Combine ARGs into a single string, use the result as input to the shell,\n and execute the resulting commands.\n \n Exit Status:\n Returns exit status of command or success if command is null.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut getopts_doc: [*mut libc::c_char; 2] = [ + b"Parse option arguments.\n \n Getopts is used by shell procedures to parse positional parameters\n as options.\n \n OPTSTRING contains the option letters to be recognized; if a letter\n is followed by a colon, the option is expected to have an argument,\n which should be separated from it by white space.\n \n Each time it is invoked, getopts will place the next option in the\n shell variable $name, initializing name if it does not exist, and\n the index of the next argument to be processed into the shell\n variable OPTIND. OPTIND is initialized to 1 each time the shell or\n a shell script is invoked. When an option requires an argument,\n getopts places that argument into the shell variable OPTARG.\n \n getopts reports errors in one of two ways. If the first character\n of OPTSTRING is a colon, getopts uses silent error reporting. In\n this mode, no error messages are printed. If an invalid option is\n seen, getopts places the option character found into OPTARG. If a\n required argument is not found, getopts places a ':' into NAME and\n sets OPTARG to the option character found. If getopts is not in\n silent mode, and an invalid option is seen, getopts places '?' into\n NAME and unsets OPTARG. If a required argument is not found, a '?'\n is placed in NAME, OPTARG is unset, and a diagnostic message is\n printed.\n \n If the shell variable OPTERR has the value 0, getopts disables the\n printing of error messages, even if the first character of\n OPTSTRING is not a colon. OPTERR has the value 1 by default.\n \n Getopts normally parses the positional parameters, but if arguments\n are supplied as ARG values, they are parsed instead.\n \n Exit Status:\n Returns success if an option is found; fails if the end of options is\n encountered or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut exec_doc: [*mut libc::c_char; 2] = [ + b"Replace the shell with the given command.\n \n Execute COMMAND, replacing this shell with the specified program.\n ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,\n any redirections take effect in the current shell.\n \n Options:\n -a name\tpass NAME as the zeroth argument to COMMAND\n -c\texecute COMMAND with an empty environment\n -l\tplace a dash in the zeroth argument to COMMAND\n \n If the command cannot be executed, a non-interactive shell exits, unless\n the shell option `execfail' is set.\n \n Exit Status:\n Returns success unless COMMAND is not found or a redirection error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut exit_doc: [*mut libc::c_char; 2] = [ + b"Exit the shell.\n \n Exits the shell with a status of N. If N is omitted, the exit status\n is that of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut logout_doc: [*mut libc::c_char; 2] = [ + b"Exit a login shell.\n \n Exits a login shell with exit status N. Returns an error if not executed\n in a login shell.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut fc_doc: [*mut libc::c_char; 2] = [ + b"Display or execute commands from the history list.\n \n fc is used to list or edit and re-execute commands from the history list.\n FIRST and LAST can be numbers specifying the range, or FIRST can be a\n string, which means the most recent command beginning with that\n string.\n \n Options:\n -e ENAME\tselect which editor to use. Default is FCEDIT, then EDITOR,\n \t\tthen vi\n -l \tlist lines instead of editing\n -n\tomit line numbers when listing\n -r\treverse the order of the lines (newest listed first)\n \n With the `fc -s [pat=rep ...] [command]' format, COMMAND is\n re-executed after the substitution OLD=NEW is performed.\n \n A useful alias to use with this is r='fc -s', so that typing `r cc'\n runs the last command beginning with `cc' and typing `r' re-executes\n the last command.\n \n Exit Status:\n Returns success or status of executed command; non-zero if an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut fg_doc: [*mut libc::c_char; 2] = [ + b"Move job to the foreground.\n \n Place the job identified by JOB_SPEC in the foreground, making it the\n current job. If JOB_SPEC is not present, the shell's notion of the\n current job is used.\n \n Exit Status:\n Status of command placed in foreground, or failure if an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut bg_doc: [*mut libc::c_char; 2] = [ + b"Move jobs to the background.\n \n Place the jobs identified by each JOB_SPEC in the background, as if they\n had been started with `&'. If JOB_SPEC is not present, the shell's notion\n of the current job is used.\n \n Exit Status:\n Returns success unless job control is not enabled or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut hash_doc: [*mut libc::c_char; 2] = [ + b"Remember or display program locations.\n \n Determine and remember the full pathname of each command NAME. If\n no arguments are given, information about remembered commands is displayed.\n \n Options:\n -d\tforget the remembered location of each NAME\n -l\tdisplay in a format that may be reused as input\n -p pathname\tuse PATHNAME as the full pathname of NAME\n -r\tforget all remembered locations\n -t\tprint the remembered location of each NAME, preceding\n \t\teach location with the corresponding NAME if multiple\n \t\tNAMEs are given\n Arguments:\n NAME\tEach NAME is searched for in $PATH and added to the list\n \t\tof remembered commands.\n \n Exit Status:\n Returns success unless NAME is not found or an invalid option is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut help_doc: [*mut libc::c_char; 2] = [ + b"Display information about builtin commands.\n \n Displays brief summaries of builtin commands. If PATTERN is\n specified, gives detailed help on all commands matching PATTERN,\n otherwise the list of help topics is printed.\n \n Options:\n -d\toutput short description for each topic\n -m\tdisplay usage in pseudo-manpage format\n -s\toutput only a short usage synopsis for each topic matching\n \t\tPATTERN\n \n Arguments:\n PATTERN\tPattern specifying a help topic\n \n Exit Status:\n Returns success unless PATTERN is not found or an invalid option is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut history_doc: [*mut libc::c_char; 2] = [ + b"Display or manipulate the history list.\n \n Display the history list with line numbers, prefixing each modified\n entry with a `*'. An argument of N lists only the last N entries.\n \n Options:\n -c\tclear the history list by deleting all of the entries\n -d offset\tdelete the history entry at position OFFSET. Negative\n \t\toffsets count back from the end of the history list\n \n -a\tappend history lines from this session to the history file\n -n\tread all history lines not already read from the history file\n \t\tand append them to the history list\n -r\tread the history file and append the contents to the history\n \t\tlist\n -w\twrite the current history to the history file\n \n -p\tperform history expansion on each ARG and display the result\n \t\twithout storing it in the history list\n -s\tappend the ARGs to the history list as a single entry\n \n If FILENAME is given, it is used as the history file. Otherwise,\n if HISTFILE has a value, that is used, else ~/.utshell_history.\n \n If the HISTTIMEFORMAT variable is set and not null, its value is used\n as a format string for strftime(3) to print the time stamp associated\n with each displayed history entry. No time stamps are printed otherwise.\n \n Exit Status:\n Returns success unless an invalid option is given or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut jobs_doc: [*mut libc::c_char; 2] = [ + b"Display status of jobs.\n \n Lists the active jobs. JOBSPEC restricts output to that job.\n Without options, the status of all active jobs is displayed.\n \n Options:\n -l\tlists process IDs in addition to the normal information\n -n\tlists only processes that have changed status since the last\n \t\tnotification\n -p\tlists process IDs only\n -r\trestrict output to running jobs\n -s\trestrict output to stopped jobs\n \n If -x is supplied, COMMAND is run after all job specifications that\n appear in ARGS have been replaced with the process ID of that job's\n process group leader.\n \n Exit Status:\n Returns success unless an invalid option is given or an error occurs.\n If -x is used, returns the exit status of COMMAND.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut disown_doc: [*mut libc::c_char; 2] = [ + b"Remove jobs from current shell.\n \n Removes each JOBSPEC argument from the table of active jobs. Without\n any JOBSPECs, the shell uses its notion of the current job.\n \n Options:\n -a\tremove all jobs if JOBSPEC is not supplied\n -h\tmark each JOBSPEC so that SIGHUP is not sent to the job if the\n \t\tshell receives a SIGHUP\n -r\tremove only running jobs\n \n Exit Status:\n Returns success unless an invalid option or JOBSPEC is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut kill_doc: [*mut libc::c_char; 2] = [ + b"Send a signal to a job.\n \n Send the processes identified by PID or JOBSPEC the signal named by\n SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then\n SIGTERM is assumed.\n \n Options:\n -s sig\tSIG is a signal name\n -n sig\tSIG is a signal number\n -l\tlist the signal names; if arguments follow `-l' they are\n \t\tassumed to be signal numbers for which names should be listed\n -L\tsynonym for -l\n \n Kill is a shell builtin for two reasons: it allows job IDs to be used\n instead of process IDs, and allows processes to be killed if the limit\n on processes that you can create is reached.\n \n Exit Status:\n Returns success unless an invalid option is given or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut let_doc: [*mut libc::c_char; 2] = [ + b"Evaluate arithmetic expressions.\n \n Evaluate each ARG as an arithmetic expression. Evaluation is done in\n fixed-width integers with no check for overflow, though division by 0\n is trapped and flagged as an error. The following list of operators is\n grouped into levels of equal-precedence operators. The levels are listed\n in order of decreasing precedence.\n \n \tid++, id--\tvariable post-increment, post-decrement\n \t++id, --id\tvariable pre-increment, pre-decrement\n \t-, +\t\tunary minus, plus\n \t!, ~\t\tlogical and bitwise negation\n \t**\t\texponentiation\n \t*, /, %\t\tmultiplication, division, remainder\n \t+, -\t\taddition, subtraction\n \t<<, >>\t\tleft and right bitwise shifts\n \t<=, >=, <, >\tcomparison\n \t==, !=\t\tequality, inequality\n \t&\t\tbitwise AND\n \t^\t\tbitwise XOR\n \t|\t\tbitwise OR\n \t&&\t\tlogical AND\n \t||\t\tlogical OR\n \texpr ? expr : expr\n \t\t\tconditional operator\n \t=, *=, /=, %=,\n \t+=, -=, <<=, >>=,\n \t&=, ^=, |=\tassignment\n \n Shell variables are allowed as operands. The name of the variable\n is replaced by its value (coerced to a fixed-width integer) within\n an expression. The variable need not have its integer attribute\n turned on to be used in an expression.\n \n Operators are evaluated in order of precedence. Sub-expressions in\n parentheses are evaluated first and may override the precedence\n rules above.\n \n Exit Status:\n If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut read_doc: [*mut libc::c_char; 2] = [ + b"Read a line from the standard input and split it into fields.\n \n Reads a single line from the standard input, or from file descriptor FD\n if the -u option is supplied. The line is split into fields as with word\n splitting, and the first word is assigned to the first NAME, the second\n word to the second NAME, and so on, with any leftover words assigned to\n the last NAME. Only the characters found in $IFS are recognized as word\n delimiters.\n \n If no NAMEs are supplied, the line read is stored in the REPLY variable.\n \n Options:\n -a array\tassign the words read to sequential indices of the array\n \t\tvariable ARRAY, starting at zero\n -d delim\tcontinue until the first character of DELIM is read, rather\n \t\tthan newline\n -e\tuse Readline to obtain the line\n -i text\tuse TEXT as the initial text for Readline\n -n nchars\treturn after reading NCHARS characters rather than waiting\n \t\tfor a newline, but honor a delimiter if fewer than\n \t\tNCHARS characters are read before the delimiter\n -N nchars\treturn only after reading exactly NCHARS characters, unless\n \t\tEOF is encountered or read times out, ignoring any\n \t\tdelimiter\n -p prompt\toutput the string PROMPT without a trailing newline before\n \t\tattempting to read\n -r\tdo not allow backslashes to escape any characters\n -s\tdo not echo input coming from a terminal\n -t timeout\ttime out and return failure if a complete line of\n \t\tinput is not read within TIMEOUT seconds. The value of the\n \t\tTMOUT variable is the default timeout. TIMEOUT may be a\n \t\tfractional number. If TIMEOUT is 0, read returns\n \t\timmediately, without trying to read any data, returning\n \t\tsuccess only if input is available on the specified\n \t\tfile descriptor. The exit status is greater than 128\n \t\tif the timeout is exceeded\n -u fd\tread from file descriptor FD instead of the standard input\n \n Exit Status:\n The return code is zero, unless end-of-file is encountered, read times out\n (in which case it's greater than 128), a variable assignment error occurs,\n or an invalid file descriptor is supplied as the argument to -u.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut return_doc: [*mut libc::c_char; 2] = [ + b"Return from a shell function.\n \n Causes a function or sourced script to exit with the return value\n specified by N. If N is omitted, the return status is that of the\n last command executed within the function or script.\n \n Exit Status:\n Returns N, or failure if the shell is not executing a function or script.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut set_doc: [*mut libc::c_char; 2] = [ + b"Set or unset values of shell options and positional parameters.\n \n Change the value of shell attributes and positional parameters, or\n display the names and values of shell variables.\n \n Options:\n -a Mark variables which are modified or created for export.\n -b Notify of job termination immediately.\n -e Exit immediately if a command exits with a non-zero status.\n -f Disable file name generation (globbing).\n -h Remember the location of commands as they are looked up.\n -k All assignment arguments are placed in the environment for a\n command, not just those that precede the command name.\n -m Job control is enabled.\n -n Read commands but do not execute them.\n -o option-name\n Set the variable corresponding to option-name:\n allexport same as -a\n braceexpand same as -B\n emacs use an emacs-style line editing interface\n errexit same as -e\n errtrace same as -E\n functrace same as -T\n hashall same as -h\n histexpand same as -H\n history enable command history\n ignoreeof the shell will not exit upon reading EOF\n interactive-comments\n allow comments to appear in interactive commands\n keyword same as -k\n monitor same as -m\n noclobber same as -C\n noexec same as -n\n noglob same as -f\n nolog currently accepted but ignored\n notify same as -b\n nounset same as -u\n onecmd same as -t\n physical same as -P\n pipefail the return value of a pipeline is the status of\n the last command to exit with a non-zero status,\n or zero if no command exited with a non-zero status\n posix change the behavior of bash where the default\n operation differs from the Posix standard to\n match the standard\n privileged same as -p\n verbose same as -v\n vi use a vi-style line editing interface\n xtrace same as -x\n -p Turned on whenever the real and effective user ids do not match.\n Disables processing of the $ENV file and importing of shell\n functions. Turning this option off causes the effective uid and\n gid to be set to the real uid and gid.\n -t Exit after reading and executing one command.\n -u Treat unset variables as an error when substituting.\n -v Print shell input lines as they are read.\n -x Print commands and their arguments as they are executed.\n -B the shell will perform brace expansion\n -C If set, disallow existing regular files to be overwritten\n by redirection of output.\n -E If set, the ERR trap is inherited by shell functions.\n -H Enable ! style history substitution. This flag is on\n by default when the shell is interactive.\n -P If set, do not resolve symbolic links when executing commands\n such as cd which change the current directory.\n -T If set, the DEBUG and RETURN traps are inherited by shell functions.\n -- Assign any remaining arguments to the positional parameters.\n If there are no remaining arguments, the positional parameters\n are unset.\n - Assign any remaining arguments to the positional parameters.\n The -x and -v options are turned off.\n \n Using + rather than - causes these flags to be turned off. The\n flags can also be used upon invocation of the shell. The current\n set of flags may be found in $-. The remaining n ARGs are positional\n parameters and are assigned, in order, to $1, $2, .. $n. If no\n ARGs are given, all shell variables are printed.\n \n Exit Status:\n Returns success unless an invalid option is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut unset_doc: [*mut libc::c_char; 2] = [ + b"Unset values and attributes of shell variables and functions.\n \n For each NAME, remove the corresponding variable or function.\n \n Options:\n -f\ttreat each NAME as a shell function\n -v\ttreat each NAME as a shell variable\n -n\ttreat each NAME as a name reference and unset the variable itself\n \t\trather than the variable it references\n \n Without options, unset first tries to unset a variable, and if that fails,\n tries to unset a function.\n \n Some variables cannot be unset; also see `readonly'.\n \n Exit Status:\n Returns success unless an invalid option is given or a NAME is read-only.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut export_doc: [*mut libc::c_char; 2] = [ + b"Set export attribute for shell variables.\n \n Marks each NAME for automatic export to the environment of subsequently\n executed commands. If VALUE is supplied, assign VALUE before exporting.\n \n Options:\n -f\trefer to shell functions\n -n\tremove the export property from each NAME\n -p\tdisplay a list of all exported variables and functions\n \n An argument of `--' disables further option processing.\n \n Exit Status:\n Returns success unless an invalid option is given or NAME is invalid.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut readonly_doc: [*mut libc::c_char; 2] = [ + b"Mark shell variables as unchangeable.\n \n Mark each NAME as read-only; the values of these NAMEs may not be\n changed by subsequent assignment. If VALUE is supplied, assign VALUE\n before marking as read-only.\n \n Options:\n -a\trefer to indexed array variables\n -A\trefer to associative array variables\n -f\trefer to shell functions\n -p\tdisplay a list of all readonly variables or functions,\n \t\tdepending on whether or not the -f option is given\n \n An argument of `--' disables further option processing.\n \n Exit Status:\n Returns success unless an invalid option is given or NAME is invalid.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut shift_doc: [*mut libc::c_char; 2] = [ + b"Shift positional parameters.\n \n Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is\n not given, it is assumed to be 1.\n \n Exit Status:\n Returns success unless N is negative or greater than $#.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut source_doc: [*mut libc::c_char; 2] = [ + b"Execute commands from a file in the current shell.\n \n Read and execute commands from FILENAME in the current shell. The\n entries in $PATH are used to find the directory containing FILENAME.\n If any ARGUMENTS are supplied, they become the positional parameters\n when FILENAME is executed.\n \n Exit Status:\n Returns the status of the last command executed in FILENAME; fails if\n FILENAME cannot be read.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut dot_doc: [*mut libc::c_char; 2] = [ + b"Execute commands from a file in the current shell.\n \n Read and execute commands from FILENAME in the current shell. The\n entries in $PATH are used to find the directory containing FILENAME.\n If any ARGUMENTS are supplied, they become the positional parameters\n when FILENAME is executed.\n \n Exit Status:\n Returns the status of the last command executed in FILENAME; fails if\n FILENAME cannot be read.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut suspend_doc: [*mut libc::c_char; 2] = [ + b"Suspend shell execution.\n \n Suspend the execution of this shell until it receives a SIGCONT signal.\n Unless forced, login shells cannot be suspended.\n \n Options:\n -f\tforce the suspend, even if the shell is a login shell\n \n Exit Status:\n Returns success unless job control is not enabled or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut test_doc: [*mut libc::c_char; 2] = [ + b"Evaluate conditional expression.\n \n Exits with a status of 0 (true) or 1 (false) depending on\n the evaluation of EXPR. Expressions may be unary or binary. Unary\n expressions are often used to examine the status of a file. There\n are string operators and numeric comparison operators as well.\n \n The behavior of test depends on the number of arguments. Read the\n bash manual page for the complete specification.\n \n File operators:\n \n -a FILE True if file exists.\n -b FILE True if file is block special.\n -c FILE True if file is character special.\n -d FILE True if file is a directory.\n -e FILE True if file exists.\n -f FILE True if file exists and is a regular file.\n -g FILE True if file is set-group-id.\n -h FILE True if file is a symbolic link.\n -L FILE True if file is a symbolic link.\n -k FILE True if file has its `sticky' bit set.\n -p FILE True if file is a named pipe.\n -r FILE True if file is readable by you.\n -s FILE True if file exists and is not empty.\n -S FILE True if file is a socket.\n -t FD True if FD is opened on a terminal.\n -u FILE True if the file is set-user-id.\n -w FILE True if the file is writable by you.\n -x FILE True if the file is executable by you.\n -O FILE True if the file is effectively owned by you.\n -G FILE True if the file is effectively owned by your group.\n -N FILE True if the file has been modified since it was last read.\n \n FILE1 -nt FILE2 True if file1 is newer than file2 (according to\n modification date).\n \n FILE1 -ot FILE2 True if file1 is older than file2.\n \n FILE1 -ef FILE2 True if file1 is a hard link to file2.\n \n String operators:\n \n -z STRING True if string is empty.\n \n -n STRING\n STRING True if string is not empty.\n \n STRING1 = STRING2\n True if the strings are equal.\n STRING1 != STRING2\n True if the strings are not equal.\n STRING1 < STRING2\n True if STRING1 sorts before STRING2 lexicographically.\n STRING1 > STRING2\n True if STRING1 sorts after STRING2 lexicographically.\n \n Other operators:\n \n -o OPTION True if the shell option OPTION is enabled.\n -v VAR True if the shell variable VAR is set.\n -R VAR True if the shell variable VAR is set and is a name\n reference.\n ! EXPR True if expr is false.\n EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.\n EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.\n \n arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,\n -lt, -le, -gt, or -ge.\n \n Arithmetic binary operators return true if ARG1 is equal, not-equal,\n less-than, less-than-or-equal, greater-than, or greater-than-or-equal\n than ARG2.\n \n Exit Status:\n Returns success if EXPR evaluates to true; fails if EXPR evaluates to\n false or an invalid argument is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut test_bracket_doc: [*mut libc::c_char; 2] = [ + b"Evaluate conditional expression.\n \n This is a synonym for the \"test\" builtin, but the last argument must\n be a literal `]', to match the opening `['.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut times_doc: [*mut libc::c_char; 2] = [ + b"Display process times.\n \n Prints the accumulated user and system times for the shell and all of its\n child processes.\n \n Exit Status:\n Always succeeds.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut trap_doc: [*mut libc::c_char; 2] = [ + b"Trap signals and other events.\n \n Defines and activates handlers to be run when the shell receives signals\n or other conditions.\n \n ARG is a command to be read and executed when the shell receives the\n signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC\n is supplied) or `-', each specified signal is reset to its original\n value. If ARG is the null string each SIGNAL_SPEC is ignored by the\n shell and by the commands it invokes.\n \n If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If\n a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If\n a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a\n script run by the . or source builtins finishes executing. A SIGNAL_SPEC\n of ERR means to execute ARG each time a command's failure would cause the\n shell to exit when the -e option is enabled.\n \n If no arguments are supplied, trap prints the list of commands associated\n with each signal.\n \n Options:\n -l\tprint a list of signal names and their corresponding numbers\n -p\tdisplay the trap commands associated with each SIGNAL_SPEC\n \n Each SIGNAL_SPEC is either a signal name in or a signal number.\n Signal names are case insensitive and the SIG prefix is optional. A\n signal may be sent to the shell with \"kill -signal $$\".\n \n Exit Status:\n Returns success unless a SIGSPEC is invalid or an invalid option is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut type_doc: [*mut libc::c_char; 2] = [ + b"Display information about command type.\n \n For each NAME, indicate how it would be interpreted if used as a\n command name.\n \n Options:\n -a\tdisplay all locations containing an executable named NAME;\n \t\tincludes aliases, builtins, and functions, if and only if\n \t\tthe `-p' option is not also used\n -f\tsuppress shell function lookup\n -P\tforce a PATH search for each NAME, even if it is an alias,\n \t\tbuiltin, or function, and returns the name of the disk file\n \t\tthat would be executed\n -p\treturns either the name of the disk file that would be executed,\n \t\tor nothing if `type -t NAME' would not return `file'\n -t\toutput a single word which is one of `alias', `keyword',\n \t\t`function', `builtin', `file' or `', if NAME is an alias,\n \t\tshell reserved word, shell function, shell builtin, disk file,\n \t\tor not found, respectively\n \n Arguments:\n NAME\tCommand name to be interpreted.\n \n Exit Status:\n Returns success if all of the NAMEs are found; fails if any are not found.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut ulimit_doc: [*mut libc::c_char; 2] = [ + b"Modify shell resource limits.\n \n Provides control over the resources available to the shell and processes\n it creates, on systems that allow such control.\n \n Options:\n -S\tuse the `soft' resource limit\n -H\tuse the `hard' resource limit\n -a\tall current limits are reported\n -b\tthe socket buffer size\n -c\tthe maximum size of core files created\n -d\tthe maximum size of a process's data segment\n -e\tthe maximum scheduling priority (`nice')\n -f\tthe maximum size of files written by the shell and its children\n -i\tthe maximum number of pending signals\n -k\tthe maximum number of kqueues allocated for this process\n -l\tthe maximum size a process may lock into memory\n -m\tthe maximum resident set size\n -n\tthe maximum number of open file descriptors\n -p\tthe pipe buffer size\n -q\tthe maximum number of bytes in POSIX message queues\n -r\tthe maximum real-time scheduling priority\n -s\tthe maximum stack size\n -t\tthe maximum amount of cpu time in seconds\n -u\tthe maximum number of user processes\n -v\tthe size of virtual memory\n -x\tthe maximum number of file locks\n -P\tthe maximum number of pseudoterminals\n -R\tthe maximum time a real-time process can run before blocking\n -T\tthe maximum number of threads\n \n Not all options are available on all platforms.\n \n If LIMIT is given, it is the new value of the specified resource; the\n special LIMIT values `soft', `hard', and `unlimited' stand for the\n current soft limit, the current hard limit, and no limit, respectively.\n Otherwise, the current value of the specified resource is printed. If\n no option is given, then -f is assumed.\n \n Values are in 1024-byte increments, except for -t, which is in seconds,\n -p, which is in increments of 512 bytes, and -u, which is an unscaled\n number of processes.\n \n Exit Status:\n Returns success unless an invalid option is supplied or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut umask_doc: [*mut libc::c_char; 2] = [ + b"Display or set file mode mask.\n \n Sets the user file-creation mask to MODE. If MODE is omitted, prints\n the current value of the mask.\n \n If MODE begins with a digit, it is interpreted as an octal number;\n otherwise it is a symbolic mode string like that accepted by chmod(1).\n \n Options:\n -p\tif MODE is omitted, output in a form that may be reused as input\n -S\tmakes the output symbolic; otherwise an octal number is output\n \n Exit Status:\n Returns success unless MODE is invalid or an invalid option is given.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut wait_doc: [*mut libc::c_char; 2] = [ + b"Wait for job completion and return exit status.\n \n Waits for each process identified by an ID, which may be a process ID or a\n job specification, and reports its termination status. If ID is not\n given, waits for all currently active child processes, and the return\n status is zero. If ID is a job specification, waits for all processes\n in that job's pipeline.\n \n If the -n option is supplied, waits for a single job from the list of IDs,\n or, if no IDs are supplied, for the next job to complete and returns its\n exit status.\n \n If the -p option is supplied, the process or job identifier of the job\n for which the exit status is returned is assigned to the variable VAR\n named by the option argument. The variable will be unset initially, before\n any assignment. This is useful only when the -n option is supplied.\n \n If the -f option is supplied, and job control is enabled, waits for the\n specified ID to terminate, instead of waiting for it to change status.\n \n Exit Status:\n Returns the status of the last ID; fails if ID is invalid or an invalid\n option is given, or if -n is supplied and the shell has no unwaited-for\n children.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut for_doc: [*mut libc::c_char; 2] = [ + b"Execute commands for each member in a list.\n \n The `for' loop executes a sequence of commands for each member in a\n list of items. If `in WORDS ...;' is not present, then `in \"$@\"' is\n assumed. For each element in WORDS, NAME is set to that element, and\n the COMMANDS are executed.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut arith_for_doc: [*mut libc::c_char; 2] = [ + b"Arithmetic for loop.\n \n Equivalent to\n \t(( EXP1 ))\n \twhile (( EXP2 )); do\n \t\tCOMMANDS\n \t\t(( EXP3 ))\n \tdone\n EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is\n omitted, it behaves as if it evaluates to 1.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut select_doc: [*mut libc::c_char; 2] = [ + b"Select words from a list and execute commands.\n \n The WORDS are expanded, generating a list of words. The\n set of expanded words is printed on the standard error, each\n preceded by a number. If `in WORDS' is not present, `in \"$@\"'\n is assumed. The PS3 prompt is then displayed and a line read\n from the standard input. If the line consists of the number\n corresponding to one of the displayed words, then NAME is set\n to that word. If the line is empty, WORDS and the prompt are\n redisplayed. If EOF is read, the command completes. Any other\n value read causes NAME to be set to null. The line read is saved\n in the variable REPLY. COMMANDS are executed after each selection\n until a break command is executed.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut time_doc: [*mut libc::c_char; 2] = [ + b"Report time consumed by pipeline's execution.\n \n Execute PIPELINE and print a summary of the real time, user CPU time,\n and system CPU time spent executing PIPELINE when it terminates.\n \n Options:\n -p\tprint the timing summary in the portable Posix format\n \n The value of the TIMEFORMAT variable is used as the output format.\n \n Exit Status:\n The return status is the return status of PIPELINE.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut case_doc: [*mut libc::c_char; 2] = [ + b"Execute commands based on pattern matching.\n \n Selectively execute COMMANDS based upon WORD matching PATTERN. The\n `|' is used to separate multiple patterns.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut if_doc: [*mut libc::c_char; 2] = [ + b"Execute commands based on conditional.\n \n The `if COMMANDS' list is executed. If its exit status is zero, then the\n `then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is\n executed in turn, and if its exit status is zero, the corresponding\n `then COMMANDS' list is executed and the if command completes. Otherwise,\n the `else COMMANDS' list is executed, if present. The exit status of the\n entire construct is the exit status of the last command executed, or zero\n if no condition tested true.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut while_doc: [*mut libc::c_char; 2] = [ + b"Execute commands as long as a test succeeds.\n \n Expand and execute COMMANDS as long as the final command in the\n `while' COMMANDS has an exit status of zero.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut until_doc: [*mut libc::c_char; 2] = [ + b"Execute commands as long as a test does not succeed.\n \n Expand and execute COMMANDS as long as the final command in the\n `until' COMMANDS has an exit status which is not zero.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut coproc_doc: [*mut libc::c_char; 2] = [ + b"Create a coprocess named NAME.\n \n Execute COMMAND asynchronously, with the standard output and standard\n input of the command connected via a pipe to file descriptors assigned\n to indices 0 and 1 of an array variable NAME in the executing shell.\n The default NAME is \"COPROC\".\n \n Exit Status:\n The coproc command returns an exit status of 0.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut function_doc: [*mut libc::c_char; 2] = [ + b"Define shell function.\n \n Create a shell function named NAME. When invoked as a simple command,\n NAME runs COMMANDs in the calling shell's context. When NAME is invoked,\n the arguments are passed to the function as $1...$n, and the function's\n name is in $FUNCNAME.\n \n Exit Status:\n Returns success unless NAME is readonly.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut grouping_braces_doc: [*mut libc::c_char; 2] = [ + b"Group commands as a unit.\n \n Run a set of commands in a group. This is one way to redirect an\n entire set of commands.\n \n Exit Status:\n Returns the status of the last command executed.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut fg_percent_doc: [*mut libc::c_char; 2] = [ + b"Resume job in foreground.\n \n Equivalent to the JOB_SPEC argument to the `fg' command. Resume a\n stopped or background job. JOB_SPEC can specify either a job name\n or a job number. Following JOB_SPEC with a `&' places the job in\n the background, as if the job specification had been supplied as an\n argument to `bg'.\n \n Exit Status:\n Returns the status of the resumed job.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut arith_doc: [*mut libc::c_char; 2] = [ + b"Evaluate arithmetic expression.\n \n The EXPRESSION is evaluated according to the rules for arithmetic\n evaluation. Equivalent to `let \"EXPRESSION\"'.\n \n Exit Status:\n Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut conditional_doc: [*mut libc::c_char; 2] = [ + b"Execute conditional command.\n \n Returns a status of 0 or 1 depending on the evaluation of the conditional\n expression EXPRESSION. Expressions are composed of the same primaries used\n by the `test' builtin, and may be combined using the following operators:\n \n ( EXPRESSION )\tReturns the value of EXPRESSION\n ! EXPRESSION\t\tTrue if EXPRESSION is false; else false\n EXPR1 && EXPR2\tTrue if both EXPR1 and EXPR2 are true; else false\n EXPR1 || EXPR2\tTrue if either EXPR1 or EXPR2 is true; else false\n \n When the `==' and `!=' operators are used, the string to the right of\n the operator is used as a pattern and pattern matching is performed.\n When the `=~' operator is used, the string to the right of the operator\n is matched as a regular expression.\n \n The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to\n determine the expression's value.\n \n Exit Status:\n 0 or 1 depending on value of EXPRESSION.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut variable_help_doc: [*mut libc::c_char; 2] = [ + b"Common shell variable names and usage.\n \n BASH_VERSION\tVersion information for this Bash.\n CDPATH\tA colon-separated list of directories to search\n \t\tfor directories given as arguments to `cd'.\n GLOBIGNORE\tA colon-separated list of patterns describing filenames to\n \t\tbe ignored by pathname expansion.\n HISTFILE\tThe name of the file where your command history is stored.\n HISTFILESIZE\tThe maximum number of lines this file can contain.\n HISTSIZE\tThe maximum number of history lines that a running\n \t\tshell can access.\n HOME\tThe complete pathname to your login directory.\n HOSTNAME\tThe name of the current host.\n HOSTTYPE\tThe type of CPU this version of Bash is running under.\n IGNOREEOF\tControls the action of the shell on receipt of an EOF\n \t\tcharacter as the sole input. If set, then the value\n \t\tof it is the number of EOF characters that can be seen\n \t\tin a row on an empty line before the shell will exit\n \t\t(default 10). When unset, EOF signifies the end of input.\n MACHTYPE\tA string describing the current system Bash is running on.\n MAILCHECK\tHow often, in seconds, Bash checks for new mail.\n MAILPATH\tA colon-separated list of filenames which Bash checks\n \t\tfor new mail.\n OSTYPE\tThe version of Unix this version of Bash is running on.\n PATH\tA colon-separated list of directories to search when\n \t\tlooking for commands.\n PROMPT_COMMAND\tA command to be executed before the printing of each\n \t\tprimary prompt.\n PS1\t\tThe primary prompt string.\n PS2\t\tThe secondary prompt string.\n PWD\t\tThe full pathname of the current directory.\n SHELLOPTS\tA colon-separated list of enabled shell options.\n TERM\tThe name of the current terminal type.\n TIMEFORMAT\tThe output format for timing statistics displayed by the\n \t\t`time' reserved word.\n auto_resume\tNon-null means a command word appearing on a line by\n \t\titself is first looked for in the list of currently\n \t\tstopped jobs. If found there, that job is foregrounded.\n \t\tA value of `exact' means that the command word must\n \t\texactly match a command in the list of stopped jobs. A\n \t\tvalue of `substring' means that the command word must\n \t\tmatch a substring of the job. Any other value means that\n \t\tthe command must be a prefix of a stopped job.\n histchars\tCharacters controlling history expansion and quick\n \t\tsubstitution. The first character is the history\n \t\tsubstitution character, usually `!'. The second is\n \t\tthe `quick substitution' character, usually `^'. The\n \t\tthird is the `history comment' character, usually `#'.\n HISTIGNORE\tA colon-separated list of patterns used to decide which\n \t\tcommands should be saved on the history list.\n\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut pushd_doc: [*mut libc::c_char; 2] = [ + b"Add directories to stack.\n \n Adds a directory to the top of the directory stack, or rotates\n the stack, making the new top of the stack the current working\n directory. With no arguments, exchanges the top two directories.\n \n Options:\n -n\tSuppresses the normal change of directory when adding\n \t\tdirectories to the stack, so only the stack is manipulated.\n \n Arguments:\n +N\tRotates the stack so that the Nth directory (counting\n \t\tfrom the left of the list shown by `dirs', starting with\n \t\tzero) is at the top.\n \n -N\tRotates the stack so that the Nth directory (counting\n \t\tfrom the right of the list shown by `dirs', starting with\n \t\tzero) is at the top.\n \n dir\tAdds DIR to the directory stack at the top, making it the\n \t\tnew current working directory.\n \n The `dirs' builtin displays the directory stack.\n \n Exit Status:\n Returns success unless an invalid argument is supplied or the directory\n change fails.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut popd_doc: [*mut libc::c_char; 2] = [ + b"Remove directories from stack.\n \n Removes entries from the directory stack. With no arguments, removes\n the top directory from the stack, and changes to the new top directory.\n \n Options:\n -n\tSuppresses the normal change of directory when removing\n \t\tdirectories from the stack, so only the stack is manipulated.\n \n Arguments:\n +N\tRemoves the Nth entry counting from the left of the list\n \t\tshown by `dirs', starting with zero. For example: `popd +0'\n \t\tremoves the first directory, `popd +1' the second.\n \n -N\tRemoves the Nth entry counting from the right of the list\n \t\tshown by `dirs', starting with zero. For example: `popd -0'\n \t\tremoves the last directory, `popd -1' the next to last.\n \n The `dirs' builtin displays the directory stack.\n \n Exit Status:\n Returns success unless an invalid argument is supplied or the directory\n change fails.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut dirs_doc: [*mut libc::c_char; 2] = [ + b"Display directory stack.\n \n Display the list of currently remembered directories. Directories\n find their way onto the list with the `pushd' command; you can get\n back up through the list with the `popd' command.\n \n Options:\n -c\tclear the directory stack by deleting all of the elements\n -l\tdo not print tilde-prefixed versions of directories relative\n \t\tto your home directory\n -p\tprint the directory stack with one entry per line\n -v\tprint the directory stack with one entry per line prefixed\n \t\twith its position in the stack\n \n Arguments:\n +N\tDisplays the Nth entry counting from the left of the list\n \t\tshown by dirs when invoked without options, starting with\n \t\tzero.\n \n -N\tDisplays the Nth entry counting from the right of the list\n \t\tshown by dirs when invoked without options, starting with\n \t\tzero.\n \n Exit Status:\n Returns success unless an invalid option is supplied or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut shopt_doc: [*mut libc::c_char; 2] = [ + b"Set and unset shell options.\n \n Change the setting of each shell option OPTNAME. Without any option\n arguments, list each supplied OPTNAME, or all shell options if no\n OPTNAMEs are given, with an indication of whether or not each is set.\n \n Options:\n -o\trestrict OPTNAMEs to those defined for use with `set -o'\n -p\tprint each shell option with an indication of its status\n -q\tsuppress output\n -s\tenable (set) each OPTNAME\n -u\tdisable (unset) each OPTNAME\n \n Exit Status:\n Returns success if OPTNAME is enabled; fails if an invalid option is\n given or OPTNAME is disabled.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut printf_doc: [*mut libc::c_char; 2] = [ + b"Formats and prints ARGUMENTS under control of the FORMAT.\n \n Options:\n -v var\tassign the output to shell variable VAR rather than\n \t\tdisplay it on the standard output\n \n FORMAT is a character string which contains three types of objects: plain\n characters, which are simply copied to standard output; character escape\n sequences, which are converted and copied to the standard output; and\n format specifications, each of which causes printing of the next successive\n argument.\n \n In addition to the standard format specifications described in printf(1),\n printf interprets:\n \n %b\texpand backslash escape sequences in the corresponding argument\n %q\tquote the argument in a way that can be reused as shell input\n %(fmt)T\toutput the date-time string resulting from using FMT as a format\n \t string for strftime(3)\n \n The format is re-used as necessary to consume all of the arguments. If\n there are fewer arguments than the format requires, extra format\n specifications behave as if a zero value or null string, as appropriate,\n had been supplied.\n \n Exit Status:\n Returns success unless an invalid option is given or a write or assignment\n error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut complete_doc: [*mut libc::c_char; 2] = [ + b"Specify how arguments are to be completed by Readline.\n \n For each NAME, specify how arguments are to be completed. If no options\n are supplied, existing completion specifications are printed in a way that\n allows them to be reused as input.\n \n Options:\n -p\tprint existing completion specifications in a reusable format\n -r\tremove a completion specification for each NAME, or, if no\n \t\tNAMEs are supplied, all completion specifications\n -D\tapply the completions and actions as the default for commands\n \t\twithout any specific completion defined\n -E\tapply the completions and actions to \"empty\" commands --\n \t\tcompletion attempted on a blank line\n -I\tapply the completions and actions to the initial (usually the\n \t\tcommand) word\n \n When completion is attempted, the actions are applied in the order the\n uppercase-letter options are listed above. If multiple options are supplied,\n the -D option takes precedence over -E, and both take precedence over -I.\n \n Exit Status:\n Returns success unless an invalid option is supplied or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut compgen_doc: [*mut libc::c_char; 2] = [ + b"Display possible completions depending on the options.\n \n Intended to be used from within a shell function generating possible\n completions. If the optional WORD argument is supplied, matches against\n WORD are generated.\n \n Exit Status:\n Returns success unless an invalid option is supplied or an error occurs.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut compopt_doc: [*mut libc::c_char; 2] = [ + b"Modify or display completion options.\n \n Modify the completion options for each NAME, or, if no NAMEs are supplied,\n the completion currently being executed. If no OPTIONs are given, print\n the completion options for each NAME or the current completion specification.\n \n Options:\n \t-o option\tSet completion option OPTION for each NAME\n \t-D\t\tChange options for the \"default\" command completion\n \t-E\t\tChange options for the \"empty\" command completion\n \t-I\t\tChange options for completion on the initial word\n \n Using `+o' instead of `-o' turns off the specified option.\n \n Arguments:\n \n Each NAME refers to a command for which a completion specification must\n have previously been defined using the `complete' builtin. If no NAMEs\n are supplied, compopt must be called by a function currently generating\n completions, and the options for that currently-executing completion\n generator are modified.\n \n Exit Status:\n Returns success unless an invalid option is supplied or NAME does not\n have a completion specification defined.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut mapfile_doc: [*mut libc::c_char; 2] = [ + b"Read lines from the standard input into an indexed array variable.\n \n Read lines from the standard input into the indexed array variable ARRAY, or\n from file descriptor FD if the -u option is supplied. The variable MAPFILE\n is the default ARRAY.\n \n Options:\n -d delim\tUse DELIM to terminate lines, instead of newline\n -n count\tCopy at most COUNT lines. If COUNT is 0, all lines are copied\n -O origin\tBegin assigning to ARRAY at index ORIGIN. The default index is 0\n -s count\tDiscard the first COUNT lines read\n -t\tRemove a trailing DELIM from each line read (default newline)\n -u fd\tRead lines from file descriptor FD instead of the standard input\n -C callback\tEvaluate CALLBACK each time QUANTUM lines are read\n -c quantum\tSpecify the number of lines read between each call to\n \t\t\tCALLBACK\n \n Arguments:\n ARRAY\tArray variable name to use for file data\n \n If -C is supplied without -c, the default quantum is 5000. When\n CALLBACK is evaluated, it is supplied the index of the next array\n element to be assigned and the line to be assigned to that element\n as additional arguments.\n \n If not supplied with an explicit origin, mapfile will clear ARRAY before\n assigning to it.\n \n Exit Status:\n Returns success unless an invalid option is given or ARRAY is readonly or\n not an indexed array.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +#[no_mangle] +pub static mut readarray_doc: [*mut libc::c_char; 2] = [ + b"Read lines from a file into an array variable.\n \n A synonym for `mapfile'.\0" + as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, +]; +fn run_static_initializers() { + unsafe { + num_shell_builtins = (::std::mem::size_of::<[builtin; 77]>() as libc::c_ulong) + .wrapping_div(::std::mem::size_of::() as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + as libc::c_int + }; +} diff --git a/utshell-0.5.0/src/builtins/caller.rs b/utshell-0.5.0/src/builtins/caller.rs new file mode 100644 index 00000000..c331b8a5 --- /dev/null +++ b/utshell-0.5.0/src/builtins/caller.rs @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::common::{builtin_usage, sh_invalidnum}; +use crate::array::array_reference; +use crate::builtins::common::no_options; +use crate::general::legal_number; +use crate::src_common::*; +use crate::GET_ARRAY_FROM_VAR; + +fn array_empty(a: *mut ARRAY) -> bool { + if unsafe { (*a).num_elements == 0 } { + return true; + } else { + return false; + } +} + +#[no_mangle] +pub fn caller_builtin(mut list: *mut WordList) -> i32 { + let funcname_v: *mut SHELL_VAR; + let bash_source_v: *mut SHELL_VAR; + let bash_lineno_v: *mut SHELL_VAR; + let funcname_a: *mut ARRAY; + let bash_source_a: *mut ARRAY; + let bash_lineno_a: *mut ARRAY; + let funcname_s: *mut libc::c_char; + let mut source_s: *mut libc::c_char; + let mut lineno_s: *mut libc::c_char; + let mut num: intmax_t = 0; + + let mut c_str: CString; + + unsafe { + CHECK_HELPOPT!(list); + + let c_str1 = CString::new("FUNCNAME").unwrap(); + let c_ptr1 = c_str1.as_ptr(); + GET_ARRAY_FROM_VAR!(c_ptr1, funcname_v, funcname_a); + + let c_str1 = CString::new("BASH_SOURCE").unwrap(); + let c_ptr1 = c_str1.as_ptr(); + GET_ARRAY_FROM_VAR!(c_ptr1, bash_source_v, bash_source_a); + + let c_str1 = CString::new("BASH_LINENO").unwrap(); + let c_ptr1 = c_str1.as_ptr(); + GET_ARRAY_FROM_VAR!(c_ptr1, bash_lineno_v, bash_lineno_a); + + if bash_lineno_a.is_null() || array_empty(bash_lineno_a) { + return EXECUTION_FAILURE!(); + } + + if bash_source_a.is_null() || array_empty(bash_source_a) { + return EXECUTION_FAILURE!(); + } + + if no_options(list) != 0 { + return EX_USAGE!(); + } + + list = loptend; /* skip over possible `--' */ + /* If there is no argument list, then give short form: line filename. */ + if list.is_null() { + lineno_s = array_reference(bash_lineno_a, 0); + source_s = array_reference(bash_source_a, 1); + + if !lineno_s.is_null() { + lineno_s = lineno_s; + } else { + c_str = CString::new("NULL").unwrap(); + lineno_s = c_str.as_ptr() as *mut libc::c_char; + } + + if !source_s.is_null() { + source_s = source_s; + } else { + c_str = CString::new("NULL").unwrap(); + source_s = c_str.as_ptr() as *mut libc::c_char; + } + let lineno_s_str = CStr::from_ptr(lineno_s).to_str().unwrap().to_owned(); + let source_s_str = CStr::from_ptr(source_s).to_str().unwrap().to_owned(); + println!("{} {}", lineno_s_str, source_s_str); + + return EXECUTION_SUCCESS!(); + } + + if funcname_a.is_null() || array_empty(funcname_a) { + return EXECUTION_FAILURE!(); + } + if legal_number((*(*list).word).word, &mut num) != 0 { + lineno_s = array_reference(bash_lineno_a, num); + source_s = array_reference(bash_source_a, num + 1); + funcname_s = array_reference(funcname_a, num + 1); + + if lineno_s == PT_NULL as *mut libc::c_char + || source_s == PT_NULL as *mut libc::c_char + || funcname_s == PT_NULL as *mut libc::c_char + { + return EXECUTION_FAILURE!(); + } + let lineno_s_str = CStr::from_ptr(lineno_s).to_str().unwrap().to_owned(); + let funcname_s_str = CStr::from_ptr(funcname_s).to_str().unwrap().to_owned(); + let source_s_str = CStr::from_ptr(source_s).to_str().unwrap().to_owned(); + println!("{} {} {}", lineno_s_str, funcname_s_str, source_s_str); + } else { + sh_invalidnum((*(*list).word).word); + builtin_usage(); + return EX_USAGE!(); + } + + return EXECUTION_SUCCESS!(); + } +} diff --git a/utshell-0.5.0/src/builtins/cd.rs b/utshell-0.5.0/src/builtins/cd.rs new file mode 100644 index 00000000..45684525 --- /dev/null +++ b/utshell-0.5.0/src/builtins/cd.rs @@ -0,0 +1,564 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::help::builtin_help; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_usage, get_working_directory, set_working_directory, sh_chkwrite, sh_restricted, + the_current_working_directory, +}; +use crate::general::{ + absolute_pathname, extract_colon_unit, make_absolute, printable_filename, same_file, +}; +use crate::src_common::*; +use crate::variables::{bind_variable, get_string_value, update_export_env_inplace}; + +#[no_mangle] +pub static mut cdspelling: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut cdable_vars: libc::c_int = 0; +static mut eflag: libc::c_int = 0; +static mut xattrflag: libc::c_int = 0; +static mut xattrfd: libc::c_int = -(1 as libc::c_int); + +/* How to bring a job into the foreground. */ +#[no_mangle] +pub fn setpwd(dirname: *mut libc::c_char) -> i32 { + let old_anm: i32; + let tvar: *mut SHELL_VAR; + unsafe { + old_anm = array_needs_making; + + let c_str_pwd = CString::new("PWD").unwrap(); + if dirname == std::ptr::null_mut() { + tvar = bind_variable( + c_str_pwd.as_ptr(), + CString::new("").unwrap().as_ptr() as *mut libc::c_char, + 0, + ); + } else { + tvar = bind_variable(c_str_pwd.as_ptr(), dirname, 0); + } + + if tvar != std::ptr::null_mut() && readonly_p!(tvar) != 0 { + return EXECUTION_FAILURE!(); + } + + if tvar != std::ptr::null_mut() + && old_anm == 0 + && array_needs_making != 0 + && exported_p!(tvar) != 0 + { + if dirname == std::ptr::null_mut() { + update_export_env_inplace( + c_str_pwd.as_ptr() as *mut libc::c_char, + 4, + CString::new("").unwrap().as_ptr() as *mut libc::c_char, + ); + } else { + update_export_env_inplace(c_str_pwd.as_ptr() as *mut libc::c_char, 4, dirname); + } + array_needs_making = 0; + } + return EXECUTION_SUCCESS!(); + } +} + +#[no_mangle] +pub fn bindpwd(no_symlinks: i32) -> i32 { + let mut dirname: *mut libc::c_char; + let pwdvar: *mut libc::c_char; + let old_anm: i32; + let mut r: i32; + let mut canon_failed: i32; + let tvar: *mut SHELL_VAR; + unsafe { + r = sh_chkwrite(EXECUTION_SUCCESS!()); + if the_current_working_directory != std::ptr::null_mut() { + if no_symlinks != 0 { + dirname = sh_physpath(the_current_working_directory, 0); + } else { + dirname = the_current_working_directory; + } + } else { + let c_str_cd = CString::new("cd").unwrap(); + dirname = get_working_directory(c_str_cd.as_ptr() as *mut libc::c_char); + } + + /* If canonicalization fails, reset dirname to the_current_working_directory */ + canon_failed = 0; + if dirname == std::ptr::null_mut() { + canon_failed = 1; + dirname = the_current_working_directory; + } + + old_anm = array_needs_making; + let c_str_pwd = CString::new("PWD").unwrap(); + pwdvar = get_string_value(c_str_pwd.as_ptr()); + + tvar = bind_variable(CString::new("OLDPWD").unwrap().as_ptr(), pwdvar, 0); + if tvar != std::ptr::null_mut() && readonly_p!(tvar) != 0 { + r = EXECUTION_FAILURE!(); + } + + if old_anm == 0 && array_needs_making != 0 && exported_p!(tvar) != 0 { + update_export_env_inplace( + CString::new("OLDPWD").unwrap().as_ptr() as *mut libc::c_char, + 7, + pwdvar, + ); + array_needs_making = 0; + } + + if setpwd(dirname) == EXECUTION_FAILURE!() { + r = EXECUTION_FAILURE!(); + } + + if canon_failed != 0 && eflag != 0 { + r = EXECUTION_FAILURE!(); + } + + if dirname != std::ptr::null_mut() && dirname != the_current_working_directory { + libc::free(dirname as *mut libc::c_void); + } + return r; + } +} + +/* Call get_working_directory to reset the value of +the_current_working_directory () */ +#[no_mangle] +pub fn resetpwd(caller: *mut libc::c_char) -> *mut libc::c_char { + let tdir: *mut libc::c_char; + unsafe { + libc::free(the_current_working_directory as *mut libc::c_void); + the_current_working_directory = 0 as *mut libc::c_char; + tdir = get_working_directory(caller); + return tdir; + } +} + +#[no_mangle] +pub fn cdxattr(dir: *mut libc::c_char, ndirp: *mut libc::c_char) -> i32 { + return -1; +} + +#[no_mangle] +pub fn resetxattr() { + unsafe { + xattrfd = -1; /* not strictly necessary */ + } +} + +#[no_mangle] +pub fn cd_builtin(mut list: *mut WordList) -> i32 { + let mut dirname: *mut libc::c_char = std::ptr::null_mut(); + let cdpath: *mut libc::c_char; + let mut path: *mut libc::c_char; + let mut temp: *mut libc::c_char; + let mut path_index: i32; + let mut no_symlinks: i32; + let mut opt: i32; + let mut lflag: i32; + let e: i32; + + unsafe { + if restricted != 0 { + sh_restricted(0 as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + + eflag = 0; + no_symlinks = no_symbolic_links; + xattrflag = 0; + reset_internal_getopt(); + + let c_str_elp = CString::new("eLP").unwrap(); // from a &str, creates a new allocation + opt = internal_getopt(list, c_str_elp.as_ptr() as *mut libc::c_char); + while opt != -1 { + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'P' => { + no_symlinks = 1; + } + 'L' => { + no_symlinks = 0; + } + 'e' => { + eflag = 1; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + opt = internal_getopt(list, c_str_elp.as_ptr() as *mut libc::c_char); + } + + // list = loptend; //åŽåŠ çš„ + + if cdable_vars != 0 { + lflag = LCD_DOVARS!(); + } else { + lflag = 0; + } + + if interactive != 0 && cdspelling != 0 { + lflag = lflag | LCD_DOSPELL!(); + } else { + lflag = lflag | 0; + } + + if eflag != 0 && no_symlinks == 0 { + eflag = 0; + } + + if loptend == std::ptr::null_mut() { + /* `cd' without arguments is equivalent to `cd $HOME' */ + dirname = get_string_value(CString::new("HOME").unwrap().as_ptr()); + + if dirname == std::ptr::null_mut() { + builtin_error(CString::new("HOME not set").unwrap().as_ptr()); + return EXECUTION_FAILURE!(); + } + lflag = 0; + } else if (*loptend).next != std::ptr::null_mut() { + builtin_error(CString::new("too many arguments").unwrap().as_ptr()); + return EXECUTION_FAILURE!(); + } else if char::from((*(*(*loptend).word).word) as u8) == '-' + && char::from(*((((*(*loptend).word).word) as usize + 1) as *mut libc::c_char) as u8) + == '\0' + { + /* This is `cd -', equivalent to `cd $OLDPWD' */ + dirname = get_string_value(CString::new("OLDPWD").unwrap().as_ptr()); + if dirname == std::ptr::null_mut() { + builtin_error(CString::new("OLDPWD not set").unwrap().as_ptr()); + return EXECUTION_FAILURE!(); + } + lflag = LCD_PRINTPATH!(); /* According to SUSv3 */ + } else if absolute_pathname((*(*loptend).word).word) != 0 { + dirname = (*(*loptend).word).word; + } else if privileged_mode == 0 + && get_string_value(CString::new("CDPATH").unwrap().as_ptr()) != std::ptr::null_mut() + { + cdpath = get_string_value(CString::new("CDPATH").unwrap().as_ptr()); + dirname = (*(*loptend).word).word; + + /* Find directory in $CDPATH. */ + path_index = 0; + path = extract_colon_unit(cdpath, &mut path_index); + + while path != std::ptr::null_mut() { + /* OPT is 1 if the path element is non-empty */ + opt = (char::from(*path as u8) != '\0') as i32; + temp = sh_makepath(path, dirname, MP_DOTILDE!()); + libc::free(path as *mut c_void); + + if change_to_directory(temp, no_symlinks, xattrflag) != 0 { + /* POSIX.2 says that if a nonempty directory from CDPATH + is used to find the directory to change to, the new + directory name is echoed to stdout, whether or not + the shell is interactive. */ + if opt != 0 { + if no_symlinks != 0 { + path = temp; + } else { + path = the_current_working_directory; + } + + if path != std::ptr::null_mut() { + libc::printf( + CString::new("%s\n").unwrap().as_ptr() as *const libc::c_char, + path, + ); + } + } + + libc::free(temp as *mut c_void); + return bindpwd(no_symlinks); + } else { + libc::free(temp as *mut c_void); + } + + path = extract_colon_unit(cdpath, &mut path_index); + } + } else { + dirname = (*(*loptend).word).word; + } + + /* When we get here, DIRNAME is the directory to change to. If we + chdir successfully, just return. */ + if 0 != change_to_directory(dirname, no_symlinks, xattrflag) { + if (lflag & LCD_PRINTPATH!()) != 0 { + libc::printf( + CString::new("%s\n").unwrap().as_ptr() as *const libc::c_char, + dirname, + ); + } + return bindpwd(no_symlinks); + } + + /* If the user requests it, then perhaps this is the name of + a shell variable, whose value contains the directory to + change to. */ + if (lflag & LCD_DOVARS!()) != 0 { + temp = get_string_value(dirname); + if temp != std::ptr::null_mut() + && change_to_directory(temp, no_symlinks, xattrflag) != 0 + { + libc::printf( + CString::new("%s\n").unwrap().as_ptr() as *const libc::c_char, + temp, + ); + return bindpwd(no_symlinks); + } + } + + /* If the user requests it, try to find a directory name similar in + spelling to the one requested, in case the user made a simple + typo. This is similar to the UNIX 8th and 9th Edition shells. */ + if (lflag & LCD_DOSPELL!()) != 0 { + temp = dirspell(dirname); + if temp != std::ptr::null_mut() + && change_to_directory(temp, no_symlinks, xattrflag) != 0 + { + println!("{:?}", temp); + libc::free(temp as *mut c_void); + return bindpwd(no_symlinks); + } else { + libc::free(temp as *mut c_void); + } + } + + e = errno!(); + temp = printable_filename(dirname, 0); + builtin_error( + CString::new("%s: %s").unwrap().as_ptr(), + temp, + libc::strerror(e), + ); + + if temp != dirname { + libc::free(temp as *mut c_void); + } + return EXECUTION_FAILURE!(); + } +} + +#[no_mangle] +pub fn pwd_builtin(list: *mut WordList) -> i32 { + let mut directory: *mut libc::c_char; + let mut opt: i32; + let mut pflag: i32; + unsafe { + verbatim_pwd = no_symbolic_links; + pflag = 0; + reset_internal_getopt(); + let c_str_lp = CString::new("LP").unwrap(); // from a &str, creates a new allocation + opt = internal_getopt(list, c_str_lp.as_ptr() as *mut libc::c_char); + while opt != -1 { + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'P' => { + verbatim_pwd = 1; + pflag = 1; + } + 'L' => { + verbatim_pwd = 0; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + opt = internal_getopt(list, c_str_lp.as_ptr() as *mut libc::c_char); + } + if the_current_working_directory != std::ptr::null_mut() { + if verbatim_pwd != 0 { + directory = sh_physpath(the_current_working_directory, 0); + } else { + directory = the_current_working_directory; + } + } else { + directory = + get_working_directory(CString::new("pwd").unwrap().as_ptr() as *mut libc::c_char); + } + + /* Try again using getcwd() if canonicalization fails (for instance, if + the file system has changed state underneath bash). */ + if (the_current_working_directory != std::ptr::null_mut() + && directory == std::ptr::null_mut()) + || (posixly_correct != 0 + && same_file( + CString::new(".").unwrap().as_ptr(), + the_current_working_directory, + std::ptr::null_mut(), + std::ptr::null_mut(), + ) == 0) + { + if directory != std::ptr::null_mut() && directory != the_current_working_directory { + libc::free(directory as *mut c_void); + } + directory = resetpwd(CString::new("pwd").unwrap().as_ptr() as *mut libc::c_char); + } + + if directory != std::ptr::null_mut() { + opt = EXECUTION_SUCCESS!(); + libc::printf( + CString::new("%s\n").unwrap().as_ptr() as *const libc::c_char, + directory, + ); + /* This is dumb but posix-mandated. */ + if posixly_correct != 0 && pflag != 0 { + opt = setpwd(directory); + } + + if directory != the_current_working_directory { + libc::free(directory as *mut c_void); + } + return sh_chkwrite(opt); + } else { + return EXECUTION_FAILURE!(); + } + } +} + +/* Do the work of changing to the directory NEWDIR. Handle symbolic +link following, etc. This function *must* return with +the_current_working_directory either set to NULL (in which case +getcwd() will eventually be called), or set to a string corresponding +to the working directory. Return 1 on success, 0 on failure. */ +#[no_mangle] +pub fn change_to_directory(newdir: *mut libc::c_char, nolinks: i32, xattr: i32) -> i32 { + unsafe { + let mut t: *mut libc::c_char; + let mut tdir: *mut libc::c_char; + let mut ndir: *mut libc::c_char; + let err: i32; + let mut canon_failed: i32; + let mut r: i32; + let ndlen: i32; + + tdir = std::ptr::null_mut(); + + if the_current_working_directory == std::ptr::null_mut() { + t = get_working_directory(CString::new("chdir").unwrap().as_ptr() as *mut libc::c_char); + libc::free(t as *mut c_void); + } + + t = make_absolute(newdir, the_current_working_directory); + + /* TDIR is either the canonicalized absolute pathname of NEWDIR + (nolinks == 0) or the absolute physical pathname of NEWDIR + (nolinks != 0). */ + if nolinks != 0 { + tdir = sh_physpath(t, 0); + } else { + tdir = sh_canonpath(t, PATH_CHECKDOTDOT!() | PATH_CHECKEXISTS!()); + } + + ndlen = libc::strlen(newdir) as i32; + + /* Use the canonicalized version of NEWDIR, or, if canonicalization + failed, use the non-canonical form. */ + canon_failed = 0; + if tdir != std::ptr::null_mut() && *tdir != 0 { + libc::free(t as *mut c_void); + } else { + libc::free(tdir as *mut c_void); + tdir = t; + canon_failed = 1; + } + + /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath + returns NULL (because it checks the path, it will return NULL if the + resolved path doesn't exist), fail immediately. */ + if posixly_correct != 0 + && nolinks == 0 + && canon_failed != 0 + && (errno!() != libc::ENAMETOOLONG || ndlen > libc::PATH_MAX) + { + if errno!() != libc::ENOENT && errno!() != libc::ENAMETOOLONG { + errno!() = libc::ENOTDIR; + } + libc::free(tdir as *mut c_void); + return 0; + } + + { + if nolinks != 0 { + r = libc::chdir(newdir); + } else { + r = libc::chdir(tdir); + } + + if r >= 0 { + resetxattr(); + } + } + + /* If the chdir succeeds, update the_current_working_directory. */ + if r == 0 { + /* If canonicalization failed, but the chdir succeeded, reset the + shell's idea of the_current_working_directory. */ + if canon_failed != 0 { + t = resetpwd(CString::new("cd").unwrap().as_ptr() as *mut libc::c_char); + if t == std::ptr::null_mut() { + set_working_directory(tdir); + } else { + libc::free(t as *mut c_void); + } + } else { + set_working_directory(tdir); + } + + libc::free(tdir as *mut c_void); + return 1; + } + + /* We failed to change to the appropriate directory name. If we tried + what the user passed (nolinks != 0), punt now. */ + if nolinks != 0 { + libc::free(tdir as *mut c_void); + return 0; + } + + err = errno!(); + + /* We're not in physical mode (nolinks == 0), but we failed to change to + the canonicalized directory name (TDIR). Try what the user passed + verbatim. If we succeed, reinitialize the_current_working_directory. + POSIX requires that we just fail here, so we do in posix mode. */ + if posixly_correct == 0 && libc::chdir(newdir) == 0 { + t = resetpwd(CString::new("cd").unwrap().as_ptr() as *mut libc::c_char); + if t == std::ptr::null_mut() { + set_working_directory(tdir); + } else { + libc::free(t as *mut c_void); + } + r = 1; + } else { + errno!() = err; + r = 0; + } + + libc::free(tdir as *mut c_void); + return r; + } +} diff --git a/utshell-0.5.0/src/builtins/cmd.rs b/utshell-0.5.0/src/builtins/cmd.rs new file mode 100644 index 00000000..a091fc39 --- /dev/null +++ b/utshell-0.5.0/src/builtins/cmd.rs @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use std::collections::HashMap; +use std::sync::Mutex; + +use lazy_static::lazy_static; + +pub struct Cmd { + name: String, + enable: bool, +} +impl Cmd { + pub fn build_cmd(name: String, enable: bool) -> Cmd { + Cmd { name, enable } + } + + pub fn set_enable(&mut self, is_enable: bool) -> &Cmd { + self.enable = is_enable; + self + } + pub fn get_enable(&self) -> bool { + return self.enable; + } +} + +lazy_static! { + static ref CMD: Mutex>> = Mutex::new(HashMap::new()); +} +fn init_cmd_table() {} + +pub fn insert_empty_cmd(cmd: String) -> bool { + let it = Cmd::build_cmd(String::from(&cmd[..]), true); + let mut cmd_table = CMD.lock().unwrap(); + cmd_table.insert(String::from(&cmd[..]), Box::new(it)); + return true; +} +pub fn insert_cmd(cmd: &str, item: Box) -> Option> { + let mut cmd_table = CMD.lock().unwrap(); + cmd_table.insert(String::from(cmd), item) +} + +pub fn get_cmd_enable(cmd: String) -> Result { + let cmd_table = CMD.lock().unwrap(); + let item = cmd_table.get(&cmd); + match item { + Some(c) => { + println!("name:{}, is {}!", cmd, c.enable); + + return Ok(c.enable); + } + None => { + return Err(cmd + " not found"); + } + } +} + +pub fn set_cmd_enable(cmd: String, is_enable: bool) -> bool { + let mut a = CMD.lock().unwrap(); + let v = a.get_mut(&cmd); + match v { + Some(c) => { + c.enable = is_enable; + } + None => { + return false; + } + } + return true; +} diff --git a/utshell-0.5.0/src/builtins/colon.rs b/utshell-0.5.0/src/builtins/colon.rs new file mode 100644 index 00000000..0e0da77b --- /dev/null +++ b/utshell-0.5.0/src/builtins/colon.rs @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::src_common::*; + +#[no_mangle] +pub fn colon_builtin(_ignore: *mut WordList) -> i32 { + 0 +} + +#[no_mangle] +pub fn false_builtin(_ignore: *mut WordList) -> i32 { + 1 +} diff --git a/utshell-0.5.0/src/builtins/command.rs b/utshell-0.5.0/src/builtins/command.rs new file mode 100644 index 00000000..4011afac --- /dev/null +++ b/utshell-0.5.0/src/builtins/command.rs @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::common::{builtin_usage, sh_notfound, sh_restricted}; +use super::help::builtin_help; +use super::type_1::describe_command; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::copycmd::copy_word_list; +use crate::execute_cmd::execute_command; +use crate::make_cmd::make_bare_simple_command; +use crate::src_common::*; +use crate::unwind_prot::{begin_unwind_frame, run_unwind_frame}; + +#[no_mangle] +pub fn command_builtin(mut list: *mut WordList) -> libc::c_int { + let mut result: libc::c_int = 0; + let mut verbose: libc::c_int = 0; + let mut use_standard_path: libc::c_int = 0; + let mut opt: libc::c_int = 0; + let mut command: *mut COMMAND = 0 as *mut COMMAND; + use_standard_path = 0 as libc::c_int; + verbose = use_standard_path; + + reset_internal_getopt(); + let adnpsf = CString::new("pvV").expect("CString::new failed"); + loop { + opt = internal_getopt(list, adnpsf.as_ptr() as *mut libc::c_char); + if !(opt != -1) { + break; + } + let opt_char = opt as u8 as char; + match opt_char { + 'p' => { + use_standard_path = CDESC_STDPATH!(); + } + 'V' => { + verbose = CDESC_SHORTDESC!() | CDESC_ABSPATH!(); + } + 'v' => { + verbose = CDESC_REUSABLE!(); // ditto + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + } + unsafe { + list = loptend; + if list.is_null() { + return EXECUTION_SUCCESS!(); + } + if use_standard_path != 0 && restricted != 0 { + sh_restricted(b"-p\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + if verbose != 0 { + let mut found: libc::c_int = 0; + let mut any_found: libc::c_int = 0; + any_found = 0 as libc::c_int; + while !list.is_null() { + found = describe_command((*(*list).word).word, verbose | use_standard_path); + if found == 0 as libc::c_int && verbose != CDESC_REUSABLE!() { + sh_notfound((*(*list).word).word); + } + any_found += found; + list = (*list).next; + } + return if any_found != 0 { + EXECUTION_SUCCESS!() + } else { + EXECUTION_FAILURE!() + }; + } + begin_unwind_frame(const_command_builtin); + command = make_bare_simple_command(); + + (*(*command).value.Simple).words = copy_word_list(list); + + (*(*command).value.Simple).redirects = 0 as *mut libc::c_void as *mut REDIRECT; + + (*command).flags |= CMD_NO_FUNCTIONS + | CMD_INHIBIT_EXPANSION + | CMD_COMMAND_BUILTIN + | (if use_standard_path != 0 { + CMD_STDPATH + } else { + 0 as libc::c_int + }); + (*(*command).value.Simple).flags |= CMD_NO_FUNCTIONS + | CMD_INHIBIT_EXPANSION + | CMD_COMMAND_BUILTIN + | (if use_standard_path != 0 { + CMD_STDPATH + } else { + 0 as libc::c_int + }); + /*add_unwind_protect( + ::std::mem::transmute::< + Option:: ()>, + *mut libc::c_char, + >(Some(dispose_command as unsafe extern "C" fn(*mut COMMAND) -> ())), + command, + );*/ + result = execute_command(command); + run_unwind_frame( + b"command_builtin\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + return result; + } +} diff --git a/utshell-0.5.0/src/builtins/common.rs b/utshell-0.5.0/src/builtins/common.rs new file mode 100644 index 00000000..1b54af1d --- /dev/null +++ b/utshell-0.5.0/src/builtins/common.rs @@ -0,0 +1,1192 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::arrayfunc::{assign_array_element, valid_array_reference}; +use crate::copycmd::copy_word_list; +use crate::dispose_cmd::dispose_words; +use crate::error::get_name_for_error; +use crate::execute_cmd::executing_line_number; +use crate::general::{all_digits, legal_number}; +use crate::list::list_length; +use crate::sig::{jump_to_top_level, termsig_handler, throw_to_top_level, top_level_cleanup}; +use crate::src_common::*; +use crate::subst::invalidate_cached_quoted_dollar_at; +use crate::trap::{decode_signal, signal_name}; +use crate::variables::{bind_variable, find_variable, unbind_variable}; + +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + builtins::{current_builtin, num_shell_builtins, shell_builtins}, + help::builtin_help, + kill::kill_builtin, + return_1::return_builtin, + set::set_builtin, +}; + +fn ISOPTION(s: *const libc::c_char, c: libc::c_char) -> bool { + unsafe { + return *s == '-' as libc::c_char && *s.offset(1) == c && *s.offset(2) != 0; + } +} + +/* **************************************************************** */ +/* */ +/* Error reporting, usage, and option processing */ +/* */ +/* **************************************************************** */ + +/* This is a lot like report_error (), but it is for shell builtins +instead of shell control structures, and it won't ever exit the +shell. */ + +#[no_mangle] +fn builtin_error_prolog() { + let name: *mut libc::c_char; + + unsafe { + name = get_name_for_error(); + eprint!("{}: ", CStr::from_ptr(name).to_str().unwrap()); + + if interactive_shell == 0 { + eprint!("line {}: ", executing_line_number()) + } + + if !this_command_name.is_null() && *this_command_name != 0 { + eprint!("{}: ", CStr::from_ptr(this_command_name).to_str().unwrap()); + } + } +} + +/* Print a usage summary for the currently-executing builtin command. */ +#[no_mangle] +pub fn builtin_usage() { + unsafe { + if !this_command_name.is_null() && *this_command_name != 0 { + eprint!( + "{}: usage: ", + CStr::from_ptr(this_command_name).to_str().unwrap() + ); + eprintln!( + "{}", + CStr::from_ptr((*current_builtin).short_doc) + .to_str() + .unwrap() + ); + } + } +} + +/* Return if LIST is NULL else barf and jump to top_level. Used by some +builtins that do not accept arguments. */ +#[no_mangle] +pub fn no_args(list: *mut WordList) { + unsafe { + if !list.is_null() { + let c_str = CString::new("too many arguments").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + top_level_cleanup(); + jump_to_top_level(DISCARD!()); + } + } +} + +/* Check that no options were given to the currently-executing builtin, +and return 0 if there were options. */ +#[no_mangle] +pub fn no_options(list: *mut WordList) -> i32 { + let opt: i32; + + reset_internal_getopt(); + let c_str = CString::new("").unwrap(); + let c_ptr = c_str.as_ptr(); + opt = internal_getopt(list, c_ptr as *mut libc::c_char); + if opt != -1 { + if opt == GETOPT_HELP!() { + builtin_help(); + return 2; + } + builtin_usage(); + return 1; + } + return 0; +} + +#[no_mangle] +pub fn sh_needarg(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: option requires an argument").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_neednumarg(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: numeric argument requited").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_notfound(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: not found").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +/* Function called when one of the builtin commands detects an invalid +option. */ +#[no_mangle] +pub fn sh_invalidopt(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: invalid option").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_invalidoptname(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: invalid option name").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_invalidid(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("`%s': not a valid identifier").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_invalidnum(s: *mut libc::c_char) { + unsafe { + // let msg:*mut libc::c_char; + let mut msg = String::new(); + let mut mag_ptr: *const libc::c_char = std::ptr::null_mut(); + + if *s == b'0' as libc::c_char && isdigit(*s.offset(1) as libc::c_int) != 0 { + msg.push_str("invalid octal number"); + mag_ptr = msg.as_ptr() as *mut libc::c_char; + } else if *s == b'0' as libc::c_char && *s.offset(1) == b'x' as libc::c_char { + msg.push_str("invalid hex number"); + mag_ptr = msg.as_ptr() as *mut libc::c_char; + } else { + msg.push_str("invalid number"); + mag_ptr = msg.as_ptr() as *mut libc::c_char; + } + + let c_str = CString::new("%s: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s, mag_ptr); + } +} + +#[no_mangle] +pub fn sh_invalidsig(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: invalid signal specification").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_badpid(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("`%s': not a pid or valid job spec").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_readonly(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: readonly variable").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_erange(s: *mut libc::c_char, desc: *mut libc::c_char) { + unsafe { + if !s.is_null() { + let c_str = CString::new("%s: %s out of range").unwrap(); + let c_ptr = c_str.as_ptr(); + if !desc.is_null() { + builtin_error(c_ptr, s, desc); + } else { + let desc_str = CString::new("argument").unwrap(); + let desc_ptr = desc_str.as_ptr(); + builtin_error(c_ptr, s, desc_ptr); + } + } else { + let c_str = CString::new("%s out of range").unwrap(); + let c_ptr = c_str.as_ptr(); + let desc_str = CString::new("argument").unwrap(); + let desc_ptr = desc_str.as_ptr(); + builtin_error(c_ptr, desc_ptr) + } + } +} + +#[no_mangle] +pub fn sh_badjob(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: no job control").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_nojobs(s: *mut libc::c_char) { + unsafe { + if !s.is_null() { + let c_str = CString::new("%s: no job control").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } else { + let c_str = CString::new("no job control").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + } + } +} + +#[no_mangle] +pub fn sh_restricted(s: *mut libc::c_char) { + unsafe { + if !s.is_null() { + let c_str = CString::new("%s: restricted").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } else { + let c_str = CString::new("restricted").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + } + } +} + +#[no_mangle] +pub fn sh_notbuiltin(s: *mut libc::c_char) { + unsafe { + let c_str = CString::new("%s: not a shell builtin").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, s); + } +} + +#[no_mangle] +pub fn sh_wrerror() { + unsafe { + let c_str = CString::new("write error: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, strerror(*__errno_location())); + } +} + +#[no_mangle] +pub fn sh_ttyerror(set: i32) { + unsafe { + if set != 0 { + let c_str = CString::new("error setting terminal attributes: %s").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr, strerror(*__errno_location())); + } else { + let c_str = CString::new("error getting terminal attributes: %s").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr, strerror(*__errno_location())); + } + } +} + +#[no_mangle] +pub fn sh_chkwrite(s: i32) -> i32 { + unsafe { + QUIT!(); + fflush(stdout); + QUIT!(); + + if ferror(stdout) != 0 { + sh_wrerror(); + fpurge(stdout); + libc::clearerr(stdout); + return EXECUTION_FAILURE!(); + } + return s; + } +} + +/* **************************************************************** */ +/* */ +/* Shell positional parameter manipulation */ +/* */ +/* **************************************************************** */ + +/* Convert a WordList into a C-style argv. Return the number of elements +in the list in *IP, if IP is non-null. A convenience function for +loadable builtins; also used by `test'. */ +#[no_mangle] +pub fn make_builtin_argv(list: *mut WordList, ip: *mut i32) -> *mut *mut libc::c_char { + let argv: *mut *mut libc::c_char; + unsafe { + argv = strvec_from_word_list(list, 0, 1, ip); + *argv.offset(0) = this_command_name; + return argv; + } +} + +/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is +non-zero, then discard whatever the existing arguments are, else +only discard the ones that are to be replaced. Set POSPARAM_COUNT +to the number of args assigned (length of LIST). */ +#[no_mangle] +pub fn remember_args(mut list: *mut WordList, destructive: i32) { + let mut i: i32; + + unsafe { + posparam_count = 0; + i = 1; + while i < 10 { + if (destructive != 0 || list != std::ptr::null_mut()) + && *dollar_vars.as_ptr().offset(i as isize) != std::ptr::null_mut() + { + free(*dollar_vars.as_ptr().offset(i as isize) as *mut c_void); + *dollar_vars.as_mut_ptr().offset(i as isize) = std::ptr::null_mut(); + } + + if !list.is_null() { + posparam_count = i; + *dollar_vars.as_mut_ptr().offset(posparam_count as isize) = + savestring!((*(*list).word).word); + list = (*list).next; + } + i += 1; + } + + /* If arguments remain, assign them to REST_OF_ARGS. + Note that copy_word_list (NULL) returns NULL, and + that dispose_words (NULL) does nothing. */ + if destructive != 0 || !list.is_null() { + dispose_words(rest_of_args); + rest_of_args = copy_word_list(list); + posparam_count += list_length(list as *mut GENERIC_LIST); //there is may be problems + } + + if destructive != 0 { + set_dollar_vars_changed(); + } + invalidate_cached_quoted_dollar_at(); + } +} + +#[no_mangle] +pub fn shift_args(mut times: i32) { + let mut temp: *mut WordList; + // let mut count:i32; + + unsafe { + if times <= 0 { + return; + } + loop { + let fresh3 = times; + times = times - 1; + if !(fresh3 > 0 as libc::c_int) { + break; + } + if *dollar_vars.as_ptr().offset(1) != std::ptr::null_mut() { + free(*dollar_vars.as_ptr().offset(1) as *mut c_void); + } + for count in 1..9 { + *dollar_vars.as_mut_ptr().offset(count) = *dollar_vars.as_ptr().offset(count + 1) + } + if !rest_of_args.is_null() { + temp = rest_of_args; + *dollar_vars.as_mut_ptr().offset(9) = savestring!((*(*temp).word).word); + rest_of_args = (*rest_of_args).next; + (*temp).next = std::ptr::null_mut(); + dispose_words(temp); + } else { + *dollar_vars.as_mut_ptr().offset(9) = std::ptr::null_mut(); + } + posparam_count -= 1; + } + } +} + +#[no_mangle] +pub fn number_of_args() -> i32 { + unsafe { + return posparam_count; + } +} + +static mut changed_dollar_vars: i32 = 0; + +/* Have the dollar variables been reset to new values since we last +checked? */ + +#[no_mangle] +pub fn dollar_vars_changed() -> i32 { + unsafe { + return changed_dollar_vars; + } +} + +#[no_mangle] +pub fn set_dollar_vars_unchanged() { + unsafe { + changed_dollar_vars = 0; + } +} + +#[no_mangle] +pub fn set_dollar_vars_changed() { + unsafe { + if variable_context != 0 { + changed_dollar_vars |= ARGS_FUNC!(); + } else if this_shell_builtin == Some(set_builtin) { + //there may be problems + changed_dollar_vars |= ARGS_SETBLTIN!(); + } else { + changed_dollar_vars |= ARGS_INVOC!(); + } + } +} + +/* **************************************************************** */ +/* */ +/* Validating numeric input and arguments */ +/* */ +/* **************************************************************** */ + +/* Read a numeric arg for this_command_name, the name of the shell builtin +that wants it. LIST is the word list that the arg is to come from. +Accept only the numeric argument; report an error if other arguments +follow. If FATAL is 1, call throw_to_top_level, which exits the +shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the +current command; if FATAL is 0, return an indication of an invalid +number by setting *NUMOK == 0 and return -1. */ +#[no_mangle] +pub fn get_numeric_arg(mut list: *mut WordList, fatal: i32, count: *mut intmax_t) -> i32 { + let arg: *mut libc::c_char; + unsafe { + if !count.is_null() { + *count = 1; + } + + if !list.is_null() + && !(*list).word.is_null() + && ISOPTION((*(*list).word).word, b'-' as libc::c_char) + { + list = (*list).next; + } + + if !list.is_null() { + arg = (*(*list).word).word; + if arg.is_null() || legal_number(arg, count) == 0 { + if !(*(*list).word).word.is_null() { + sh_neednumarg((*(*list).word).word); + } else { + sh_neednumarg(String::from("`'").as_ptr() as *mut libc::c_char); + } + + if fatal == 0 { + return 0; + } else if fatal == 1 { + /* fatal == 1; abort */ + throw_to_top_level(); + } else { + /* fatal == 2; discard current command */ + top_level_cleanup(); + jump_to_top_level(DISCARD!()); + } + } + no_args((*list).next); + } + return 1; + } +} + +/* Get an eight-bit status value from LIST */ +#[no_mangle] +pub fn get_exitstat(mut list: *mut WordList) -> i32 { + let status: i32; + let mut sval: intmax_t = 0; + let arg: *mut libc::c_char; + + unsafe { + if !list.is_null() + && !(*list).word.is_null() + && ISOPTION((*(*list).word).word, b'-' as libc::c_char) + { + list = (*list).next; + } + + if list.is_null() { + /* If we're not running the DEBUG trap, the return builtin, when not + given any arguments, uses the value of $? before the trap ran. If + given an argument, return uses it. This means that the trap can't + change $?. The DEBUG trap gets to change $?, though, since that is + part of its reason for existing, and because the extended debug mode + does things with the return value. */ + if this_shell_builtin == Some(return_builtin) + && running_trap > 0 + && running_trap != DEBUG_TRAP!() + 1 + { + return trap_saved_exit_value; + } + return last_command_exit_value; + } + + arg = (*(*list).word).word; + if arg.is_null() || legal_number(arg, &mut sval) == 0 { + if !(*(*list).word).word.is_null() { + sh_neednumarg((*(*list).word).word); + } else { + sh_neednumarg(String::from("`'").as_ptr() as *mut libc::c_char); + } + + return EX_BADUSAGE!(); + } + + no_args((*list).next); + + status = (sval & 255) as i32; + return status; + } +} + +/* Return the octal number parsed from STRING, or -1 to indicate +that the string contained a bad number. */ +#[no_mangle] +pub fn read_octal(mut string: *mut libc::c_char) -> i32 { + let mut result: i32 = 0; + let mut digits: i32 = 0; + + unsafe { + while *string != 0 && ISOCTAL!(*string) { + digits += 1; + result = (result * 8) + (*string - b'0' as libc::c_char) as i32; + string = (string as usize + 1) as *mut libc::c_char; + if result > 0o7777 { + return -1; + } + } + + if digits == 0 || *string != 0 { + result = -1; + } + + return result; + } +} + +/* **************************************************************** */ +/* */ +/* Manipulating the current working directory */ +/* */ +/* **************************************************************** */ + +/* Return a consed string which is the current working directory. +FOR_WHOM is the name of the caller for error printing. */ + +pub static mut the_current_working_directory: *mut libc::c_char = std::ptr::null_mut(); + +#[no_mangle] +pub fn get_working_directory(for_whom: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + if no_symbolic_links != 0 { + FREE!(the_current_working_directory as *mut c_void); + the_current_working_directory = std::ptr::null_mut(); + } + + if the_current_working_directory.is_null() { + the_current_working_directory = getcwd(0 as *mut libc::c_char, 0); + + if the_current_working_directory.is_null() { + let strerror_str = CStr::from_ptr(strerror(errno())); + let strerror_string = strerror_str.to_str().unwrap().to_owned(); + let bash_getcwd_errstr = String::from("getcwd: cannot access parent directories"); + if !for_whom.is_null() && *for_whom != 0 { + let for_whom_str = CStr::from_ptr(for_whom); + let for_whom_string = for_whom_str.to_str().unwrap().to_owned(); + eprintln!( + "{}: error retrieving current directory: {}: {}", + for_whom_string, bash_getcwd_errstr, strerror_string + ); + } else { + let for_whom_str = CStr::from_ptr(get_name_for_error()); + let for_whom_string = for_whom_str.to_str().unwrap().to_owned(); + eprintln!( + "{}: error retrieving current directory: {}: {}", + for_whom_string, bash_getcwd_errstr, strerror_string + ); + } + return std::ptr::null_mut(); + } + } + return savestring!(the_current_working_directory); + } +} + +#[no_mangle] +pub fn set_working_directory(name: *mut libc::c_char) { + unsafe { + FREE!(the_current_working_directory as *mut c_void); + the_current_working_directory = savestring!(name); + } +} + +/* **************************************************************** */ +/* */ +/* Job control support functions */ +/* */ +/* **************************************************************** */ +#[no_mangle] +pub fn get_job_by_name(name: *const libc::c_char, flags: i32) -> i32 { + let mut i: i32; + let wl: i32; + let mut cl: i32; + let mut match_0: i32; + let mut job: i32; + let mut p: *mut PROCESS; + let mut j: *mut JOB; + + unsafe { + job = NO_JOB!(); + wl = strlen(name) as i32; + + i = js.j_jobslots - 1; + while i >= 0 { + j = get_job_by_jid!(i); + if j.is_null() || (flags & JM_STOPPED!() != 0 && J_JOBSTATE!(j) != JSTOPPED) { + continue; + } + + p = (*j).pipe; + + loop { + if (flags & JM_EXACT!()) != 0 { + cl = strlen((*p).command) as i32; + match_0 = STREQN!((*p).command, name, cl as usize); + } else if (flags & JM_SUBSTRING!()) != 0 { + match_0 = (strcasestr((*p).command, name) != 0 as *mut libc::c_char) as i32; + } else { + match_0 = STREQN!((*p).command, name, wl as usize); + } + + if match_0 == 0 { + p = (*p).next; + continue; + } else if flags & JM_FIRSTMATCH!() != 0 { + return i; + } else if job != NO_JOB!() { + if this_shell_builtin.is_some() { + let c_str = CString::new("%s: ambiguous job spece").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr, name); + } else { + let c_str = CString::new("%s: ambiguous job spece").unwrap(); + let c_str_ptr = c_str.as_ptr(); + internal_error(c_str_ptr, name) + } + return DUP_JOB!(); + } else { + job = i; + } + + if p == (*j).pipe { + break; + } + } + + i -= 1; + } + return job; + } +} + +/* Return the job spec found in LIST. */ +#[no_mangle] +pub fn get_job_spec(list: *mut WordList) -> i32 { + let mut word: *mut libc::c_char; + let job: i32; + let mut jflags: i32; + + unsafe { + if list.is_null() { + return js.j_current; + } + + word = (*(*list).word).word; + + if *word.offset(0) == '\0' as libc::c_char { + return NO_JOB!(); + } + + if *word.offset(0) == '%' as libc::c_char { + word = word.offset(1); + } + + if DIGIT!(*word) && all_digits(word) != 0 { + job = atoi(word); + if job < 0 || job > js.j_jobslots { + return NO_JOB!(); + } else { + return job - 1; + } + } + + jflags = 0; + let opt = word.offset(0) as u8; + let opt_char = char::from(opt); + match opt_char { + '\0' | '%' | '+' => return js.j_current, + '-' => return js.j_previous, + '?' => { + jflags |= JM_SUBSTRING!(); + word = word.offset(1); + } + _ => {} + } + return get_job_by_name(word, jflags); + } +} + +/* + * NOTE: `kill' calls this function with forcecols == 0 + */ +pub fn display_signal_list(mut list: *mut WordList, forcecols: i32) -> i32 { + let mut _i: i32; + let mut column: i32; + let mut name: *mut libc::c_char; + let mut result: i32; + let mut signum: i32; + let mut dflags: i32; + let mut lsignum: intmax_t = 0; + + unsafe { + result = EXECUTION_SUCCESS!(); + if list.is_null() { + column = 0; + for i in 1..65 { + name = signal_name(i); + if STREQN!( + name, + String::from("SIGJUNK").as_ptr() as *mut libc::c_char, + 7 + ) != 0 + || STREQN!( + name, + String::from("Unknown").as_ptr() as *mut libc::c_char, + 7 + ) != 0 + { + continue; + } + + if posixly_correct != 0 && forcecols == 0 { + /* This is for the kill builtin. POSIX.2 says the signal names + are displayed without the `SIG' prefix. */ + if STREQN!(name, String::from("SIG").as_ptr() as *mut libc::c_char, 3) != 0 { + name = name.offset(3); + } + if i == NSIG!() - 1 { + print!("{}", CStr::from_ptr(name).to_str().unwrap().to_owned()); + } else { + print!("{} ", CStr::from_ptr(name).to_str().unwrap().to_owned()); + } + } else { + print!( + "{:>2}{} {}", + i, + ")", + CStr::from_ptr(name).to_str().unwrap().to_owned() + ); + + column += 1; + if column < 5 { + print! {"\t"}; + } else { + print!("\n"); + column = 0; + } + } + } + + if posixly_correct != 0 && forcecols != 0 || column != 0 { + print!("\n"); + } + return result; + } //if list.is_null() + + /* List individual signal names or numbers. */ + while !list.is_null() { + if legal_number((*(*list).word).word, &mut lsignum) != 0 { + /* This is specified by Posix.2 so that exit statuses can be + mapped into signal numbers. */ + if lsignum > 128 { + lsignum -= 128; + } + if lsignum < 0 || lsignum >= NSIG!() { + sh_invalidsig((*(*list).word).word); + result = EXECUTION_FAILURE!(); + list = (*list).next; + continue; + } + + signum = lsignum as i32; + name = signal_name(signum); + if STREQN!( + name, + String::from("SIGJUNK").as_ptr() as *mut libc::c_char, + 7 + ) != 0 + || STREQN!( + name, + String::from("Unknow").as_ptr() as *mut libc::c_char, + 7 + ) != 0 + { + list = (*list).next; + continue; + } + /* POSIX.2 says that `kill -l signum' prints the signal name without + the `SIG' prefix. */ + if this_shell_builtin == Some(kill_builtin) && signum > 0 { + // name = name.offset(3); + println!( + "{}", + CStr::from_ptr(name.offset(3)).to_str().unwrap().to_owned() + ); + } else { + println!("{}", CStr::from_ptr(name).to_str().unwrap().to_owned()); + } + } else { + dflags = DSIG_NOCASE!(); + if posixly_correct == 0 || this_shell_builtin != Some(kill_builtin) { + dflags |= DSIG_SIGPREFIX!(); + } + signum = decode_signal((*(*list).word).word, dflags); + if signum == NO_SIG!() { + sh_invalidsig((*(*list).word).word); + result = EXECUTION_FAILURE!(); + list = (*list).next; + continue; + } + println!("{}", signum); + } + list = (*list).next; + } //while + return result; + } +} + +/* **************************************************************** */ +/* */ +/* Finding builtin commands and their functions */ +/* */ +/* **************************************************************** */ + +/* Perform a binary search and return the address of the builtin function +whose name is NAME. If the function couldn't be found, or the builtin +is disabled or has no function associated with it, return NULL. +Return the address of the builtin. +DISABLED_OKAY means find it even if the builtin is disabled. */ + +fn print_builtin_name() { + let hi: i32; + let lo: i32; + let _mid: i32 = 0; + let mut _j: i32; + + unsafe { + hi = num_shell_builtins - 1; + lo = 0; + + while lo <= hi { + //printf(b" builtin command name is :%s\n", (*shell_builtins.offset(mid as isize)).name); + } + } +} + +#[no_mangle] +pub fn builtin_address_internal(name: *mut libc::c_char, disabled_okay: i32) -> *mut builtin { + let mut hi: i32; + let mut lo: i32; + let mut mid: i32 = 0; + let mut j: i32; + + unsafe { + hi = num_shell_builtins - 1; + lo = 0; + + while lo <= hi { + mid = (lo + hi) / 2; + + j = (*((*shell_builtins.offset(mid as isize)).name).offset(0) - *name.offset(0)) as i32; + + if j == 0 { + j = strcmp((*shell_builtins.offset(mid as isize)).name, name); + } + + if j == 0 { + /* It must have a function pointer. It must be enabled, or we + must have explicitly allowed disabled functions to be found, + and it must not have been deleted. */ + if ((*shell_builtins.offset(mid as isize)).function).is_some() + && (*shell_builtins.offset(mid as isize)).flags & BUILTIN_DELETED!() == 0 + && (*shell_builtins.offset(mid as isize)).flags & BUILTIN_ENABLED!() != 0 //应该是 !=0 + || disabled_okay != 0 + { + return &mut *shell_builtins.offset(mid as isize); + } else { + return 0 as *mut builtin; + } + } + + if j > 0 { + hi = mid - 1; + } else { + lo = mid + 1; + } + } + + return 0 as *mut builtin; + } +} + +/* Return the pointer to the function implementing builtin command NAME. */ +pub fn find_shell_builtin(name: *mut libc::c_char) -> Option { + unsafe { + current_builtin = builtin_address_internal(name, 0); + if !current_builtin.is_null() { + return (*current_builtin).function; + } else { + return None; + } + } +} + +/* Return the address of builtin with NAME, whether it is enabled or not. */ +pub fn builtin_address(name: *mut libc::c_char) -> Option { + unsafe { + current_builtin = builtin_address_internal(name, 1); + if !current_builtin.is_null() { + return (*current_builtin).function; + } else { + return None; + } + } +} + +/* Return the function implementing the builtin NAME, but only if it is a +POSIX.2 special builtin. */ +#[no_mangle] +pub fn find_special_builtin(name: *mut libc::c_char) -> Option { + unsafe { + current_builtin = builtin_address_internal(name, 0); + + if !current_builtin.is_null() && (*current_builtin).flags & SPECIAL_BUILTIN!() != 0 { + return (*current_builtin).function; + } else { + return None; + } + } +} + +#[no_mangle] +fn shell_builtin_compare(sbp1: *mut builtin, sbp2: *mut builtin) -> i32 { + let mut result: i32; + + unsafe { + result = (*((*sbp1).name).offset(0) - *((*sbp2).name).offset(0)) as i32; + if result == 0 { + result = strcmp((*sbp1).name, (*sbp2).name); + } + return result; + } +} + +/* Sort the table of shell builtins so that the binary search will work +in find_shell_builtin. */ +#[no_mangle] +pub fn initialize_shell_builtins() { + unsafe { + qsort( + shell_builtins as *mut c_void, + num_shell_builtins as usize, + size_of::(), + std::mem::transmute:: libc::c_int>, Option>(Some( + std::mem::transmute::< + fn(*mut builtin, *mut builtin) -> libc::c_int, + fn() -> libc::c_int, + >(shell_builtin_compare), + )), + ); + } +} + +/* **************************************************************** */ +/* */ +/* Variable assignments during builtin commands */ +/* */ +/* **************************************************************** */ +#[no_mangle] +pub fn builtin_bind_variable( + name: *mut libc::c_char, + value: *mut libc::c_char, + flags: i32, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR; + + unsafe { + let opt: i32; + if assoc_expand_once != 0 { + opt = VA_NOEXPAND!() | VA_ONEWORD!(); + } else { + opt = 0; + } + + if valid_array_reference(name, opt) == 0 { + v = bind_variable(name, value, flags); + } else { + v = assign_array_element( + name, + value, + flags + | (if assoc_expand_once != 0 { + ASS_NOEXPAND!() + } else { + 0 + }), + ); + } + + if !v.is_null() && readonly_p!(v) == 0 && noassign_p!(v) == 0 { + VUNSETATTR!(v, att_invisible!()); + } + return v; + } +} + +/* Like check_unbind_variable, but for use by builtins (only matters for +error messages). */ +pub fn builtin_unbind_variable(vname: *const libc::c_char) -> i32 { + let v: *mut SHELL_VAR; + + unsafe { + v = find_variable(vname); + if !v.is_null() && readonly_p!(v) != 0 { + let c_str = CString::new("%s: cannot unset: readonly %s").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr, vname, "variable"); + return -2; + } else if !v.is_null() && non_unsettable_p!(v) != 0 { + let c_str = CString::new("%s: cannot unset").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr, vname); + return -2; + } + + return unbind_variable(vname); + } +} + +pub fn get_local_str() -> Vec { + let language: String; + match var("LANG") { + Ok(v) => language = v, + Err(e) => { + language = String::from("en-US"); + println!("err is {e:?}") + } + } + // println!("now language is {:?}",language); + //parse() ç”¨äºŽç±»åž‹è½¬æ¢ + let v: Vec<_> = language.split('.').collect(); + let langid: LanguageIdentifier = v[0].parse().expect("wrong language"); + let locales = vec![langid.into()]; + return locales; +} + +pub fn savestring(x: *const libc::c_char) -> *mut libc::c_char { + unsafe { + let len = 1 + libc::strlen(x); + let str1: *mut libc::c_char = libc::malloc(len) as *mut libc::c_char; + libc::memset(str1 as *mut libc::c_void, 0, len); + return libc::strcpy(str1 as *mut libc::c_char, x); + } +} + +pub fn err_translate_fn(command: &String, args1: *mut libc::c_char) { + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + unsafe { + if args1 != std::ptr::null_mut() { + args.set( + "str1", + format!("{:?}", CStr::from_ptr(args1).to_str().unwrap()), + ); + } + } + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message(command).unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + if args1 != std::ptr::null_mut() { + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + eprint!("{msg1}"); + } else { + let msg1 = bundle.format_pattern(&pattern, None, &mut errors); + eprint!("{msg1}"); + } +} + +pub fn translate_fn(command: &String, args1: *mut libc::c_char) { + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + unsafe { + if args1 != std::ptr::null_mut() { + args.set( + "str1", + format!("{:?}", CStr::from_ptr(args1).to_str().unwrap()), + ); + } + } + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message(command).unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + if args1 != std::ptr::null_mut() { + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + print!("{msg1}"); + } else { + let msg1 = bundle.format_pattern(&pattern, None, &mut errors); + print!("{msg1}"); + } +} diff --git a/utshell-0.5.0/src/builtins/complete.rs b/utshell-0.5.0/src/builtins/complete.rs new file mode 100644 index 00000000..677da0a9 --- /dev/null +++ b/utshell-0.5.0/src/builtins/complete.rs @@ -0,0 +1,1090 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::help::builtin_help; +use crate::bashline::bash_default_completion; +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + common::{builtin_usage, sh_chkwrite, sh_invalidid, sh_invalidopt, sh_invalidoptname}, +}; +use crate::dispose_cmd::dispose_words; +use crate::general::check_identifier; +use crate::make_cmd::{make_bare_word, make_word_list}; +use crate::pcomplete::{ + completions_to_stringlist, gen_compspec_completions, pcomp_curcmd, pcomp_curcs, pcomp_ind, + pcomp_line, pcomp_set_compspec_options, pcomp_set_readline_variables, +}; +use crate::pcomplib::{ + compspec_create, compspec_dispose, progcomp_flush, progcomp_insert, progcomp_remove, + progcomp_search, progcomp_walk, +}; +use crate::src_common::*; + +extern "C" { + static mut rl_readline_state: libc::c_ulong; + fn rl_filename_completion_function(text: *const libc::c_char, state: i32) -> *mut libc::c_char; + fn rl_completion_matches( + text: *const libc::c_char, + entry_function: unsafe extern "C" fn( + text: *const libc::c_char, + state: i32, + ) -> *mut libc::c_char, + ) -> *mut *mut libc::c_char; + fn strlist_print(strlist: *mut STRINGLIST, text: *mut libc::c_char); +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _compacts { + actname: *const libc::c_char, + actflag: libc::c_ulong, + actopt: libc::c_int, +} + +pub struct CompactsArray { + compactsArr: [_compacts; 25usize], +} + +impl CompactsArray { + pub fn new() -> CompactsArray { + CompactsArray { + compactsArr: [ + _compacts { + actname: b"alias\0".as_ptr() as *const libc::c_char, + actflag: CA_ALIAS!(), + actopt: 'a' as libc::c_int, + }, + _compacts { + actname: b"arrayvar\0".as_ptr() as *const libc::c_char, + actflag: CA_ARRAYVAR!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"binding\0".as_ptr() as *const libc::c_char, + actflag: CA_BINDING!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"builtin\0".as_ptr() as *const libc::c_char, + actflag: CA_BUILTIN!(), + actopt: 'b' as libc::c_int, + }, + _compacts { + actname: b"command\0".as_ptr() as *const libc::c_char, + actflag: CA_COMMAND!(), + actopt: 'c' as libc::c_int, + }, + _compacts { + actname: b"directory\0".as_ptr() as *const libc::c_char, + actflag: CA_DIRECTORY!(), + actopt: 'd' as libc::c_int, + }, + _compacts { + actname: b"disabled\0".as_ptr() as *const libc::c_char, + actflag: CA_DISABLED!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"enabled\0".as_ptr() as *const libc::c_char, + actflag: CA_ENABLED!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"export\0".as_ptr() as *const libc::c_char, + actflag: CA_EXPORT!(), + actopt: 'e' as libc::c_int, + }, + _compacts { + actname: b"file\0".as_ptr() as *const libc::c_char, + actflag: CA_FILE!(), + actopt: 'f' as libc::c_int, + }, + _compacts { + actname: b"function\0".as_ptr() as *const libc::c_char, + actflag: CA_FUNCTION!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"helptopic\0".as_ptr() as *const libc::c_char, + actflag: CA_HELPTOPIC!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"hostname\0".as_ptr() as *const libc::c_char, + actflag: CA_HOSTNAME!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"group\0".as_ptr() as *const libc::c_char, + actflag: CA_GROUP!(), + actopt: 'g' as libc::c_int, + }, + _compacts { + actname: b"job\0".as_ptr() as *const libc::c_char, + actflag: CA_JOB!(), + actopt: 'j' as libc::c_int, + }, + _compacts { + actname: b"keyword\0".as_ptr() as *const libc::c_char, + actflag: CA_KEYWORD!(), + actopt: 'k' as libc::c_int, + }, + _compacts { + actname: b"running\0".as_ptr() as *const libc::c_char, + actflag: CA_RUNNING!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"service\0".as_ptr() as *const libc::c_char, + actflag: CA_SERVICE!(), + actopt: 's' as libc::c_int, + }, + _compacts { + actname: b"setopt\0".as_ptr() as *const libc::c_char, + actflag: CA_SETOPT!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"shopt\0".as_ptr() as *const libc::c_char, + actflag: CA_SHOPT!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"signal\0".as_ptr() as *const libc::c_char, + actflag: CA_SIGNAL!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"stopped\0".as_ptr() as *const libc::c_char, + actflag: CA_STOPPED!(), + actopt: 0 as libc::c_int, + }, + _compacts { + actname: b"user\0".as_ptr() as *const libc::c_char, + actflag: CA_USER!(), + actopt: 'u' as libc::c_int, + }, + _compacts { + actname: b"variable\0".as_ptr() as *const libc::c_char, + actflag: CA_VARIABLE!(), + actopt: 'v' as libc::c_int, + }, + _compacts { + actname: std::ptr::null_mut(), + actflag: 0, + actopt: 0 as libc::c_int, + }, + ], + } + } +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _compopt { + optname: *const libc::c_char, + optflag: libc::c_ulong, +} + +pub struct CompoptArray { + compoptArr: [_compopt; 9usize], +} + +impl CompoptArray { + pub fn new() -> CompoptArray { + CompoptArray { + compoptArr: [ + _compopt { + optname: "bashdefault\0".as_ptr() as *const libc::c_char, + optflag: COPT_BASHDEFAULT!(), + }, + _compopt { + optname: "default\0".as_ptr() as *const libc::c_char, + optflag: COPT_DEFAULT!(), + }, + _compopt { + optname: "dirnames\0".as_ptr() as *const libc::c_char, + optflag: COPT_DIRNAMES!(), + }, + _compopt { + optname: "filenames\0".as_ptr() as *const libc::c_char, + optflag: COPT_FILENAMES!(), + }, + _compopt { + optname: "noquote\0".as_ptr() as *const libc::c_char, + optflag: COPT_NOQUOTE!(), + }, + _compopt { + optname: "nosort\0".as_ptr() as *const libc::c_char, + optflag: COPT_NOSORT!(), + }, + _compopt { + optname: "nospace\0".as_ptr() as *const libc::c_char, + optflag: COPT_NOSPACE!(), + }, + _compopt { + optname: "plusdirs\0".as_ptr() as *const libc::c_char, + optflag: COPT_PLUSDIRS!(), + }, + _compopt { + optname: std::ptr::null_mut(), + optflag: 0, + }, + ], + } + } +} + +pub static mut Garg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Warg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Parg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Sarg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Xarg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Farg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Carg: *mut libc::c_char = std::ptr::null_mut(); + +fn STRDUP(x: *const libc::c_char) -> *mut libc::c_char { + if x != std::ptr::null_mut() { + unsafe { + return savestring!(x); + } + } else { + return std::ptr::null_mut(); + } +} + +fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + unsafe { + return *a == *b && libc::strcmp(a, b) == 0; + } +} + +fn shell_break_chars() -> *const libc::c_char { + return b"()<>;&| \t\n\0".as_ptr() as *const libc::c_char; +} + +fn EMPTYCMD() -> *const libc::c_char { + return b"_EmptycmD_\0".as_ptr() as *const libc::c_char; +} + +fn DEFAULTCMD() -> *const libc::c_char { + return b"_DefaultCmD_\0".as_ptr() as *const libc::c_char; +} + +fn INITIALWORD() -> *const libc::c_char { + return b"_InitialWorD_\0".as_ptr() as *const libc::c_char; +} + +fn RL_ISSTATE(x: libc::c_ulong) -> libc::c_ulong { + unsafe { + return rl_readline_state & x; + } +} + +#[no_mangle] +pub fn find_compact(name: *mut libc::c_char) -> i32 { + let mut i: i32 = 0; + unsafe { + let compacts: CompactsArray = CompactsArray::new(); + while compacts.compactsArr[i as usize].actname != std::ptr::null_mut() { + let tmp = CStr::from_ptr(compacts.compactsArr[i as usize].actname); + if STREQ(name, compacts.compactsArr[i as usize].actname) { + return i; + } + i += 1; + } + return -1; + } +} + +#[no_mangle] +pub fn find_compopt(name: *mut libc::c_char) -> i32 { + let mut i: i32 = 0; + let compopts: CompoptArray = CompoptArray::new(); + + while compopts.compoptArr[i as usize].optname != std::ptr::null_mut() { + if STREQ(name, compopts.compoptArr[i as usize].optname) { + return i; + } + i += 1; + } + return -1; +} + +#[no_mangle] +pub fn build_actions( + mut list: *mut WordList, + flagp: *mut _optflags, + actp: *mut libc::c_ulong, + optp: *mut libc::c_ulong, +) -> i32 { + let mut opt: i32; + let mut ind: i32; + let mut opt_given: i32 = 0; + let mut acts: libc::c_ulong = 0; + let mut copts: libc::c_ulong = 0; + let mut w: WordDesc = WordDesc { + word: std::ptr::null_mut(), + flags: 0, + }; + + unsafe { + reset_internal_getopt(); + opt = internal_getopt( + list, + CString::new("abcdefgjko:prsuvA:G:W:P:S:X:F:C:DEI") + .unwrap() + .as_ptr() as *mut libc::c_char, + ); + while opt != -1 { + opt_given = 1; + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'r' => { + if flagp != std::ptr::null_mut() { + (*flagp).rflag = 1; + } else { + sh_invalidopt(CString::new("-r").unwrap().as_ptr() as *mut libc::c_char); + builtin_usage(); + return EX_USAGE!(); + } + } + 'p' => { + if flagp != std::ptr::null_mut() { + (*flagp).pflag = 1; + } else { + sh_invalidopt(CString::new("-p").unwrap().as_ptr() as *mut libc::c_char); + builtin_usage(); + return EX_USAGE!(); + } + } + 'a' => { + acts |= CA_ALIAS!(); + } + 'b' => { + acts |= CA_BUILTIN!(); + } + 'c' => { + acts |= CA_COMMAND!(); + } + 'd' => { + acts |= CA_DIRECTORY!(); + } + 'e' => { + acts |= CA_EXPORT!(); + } + 'f' => { + acts |= CA_FILE!(); + } + 'g' => { + acts |= CA_GROUP!(); + } + 'j' => { + acts |= CA_GROUP!(); + } + 'k' => { + acts |= CA_KEYWORD!(); + } + 's' => { + acts |= CA_SERVICE!(); + } + 'u' => { + acts |= CA_USER!(); + } + 'v' => { + acts |= CA_VARIABLE!(); + } + 'o' => { + ind = find_compopt(list_optarg); + if ind < 0 { + sh_invalidoptname(list_optarg); + return EX_USAGE!(); + } + let compopts: CompoptArray = CompoptArray::new(); + copts |= compopts.compoptArr[ind as usize].optflag; + } + 'A' => { + ind = find_compact(list_optarg); + if ind < 0 { + builtin_error( + CString::new("%s: invalid action name").unwrap().as_ptr(), + list_optarg, + ); + return EX_USAGE!(); + } + let compacts: CompactsArray = CompactsArray::new(); + acts |= compacts.compactsArr[ind as usize].actflag; + } + 'C' => { + Carg = list_optarg; + } + 'D' => { + if flagp != std::ptr::null_mut() { + (*flagp).Dflag = 1; + } else { + sh_invalidopt(CString::new("-D").unwrap().as_ptr() as *mut libc::c_char); + builtin_usage(); + return EX_USAGE!(); + } + } + 'E' => { + if flagp != std::ptr::null_mut() { + (*flagp).Eflag = 1; + } else { + sh_invalidopt(CString::new("-E").unwrap().as_ptr() as *mut libc::c_char); + builtin_usage(); + return EX_USAGE!(); + } + } + 'I' => { + if flagp != std::ptr::null_mut() { + (*flagp).Iflag = 1; + } else { + sh_invalidopt(CString::new("-I").unwrap().as_ptr() as *mut libc::c_char); + builtin_usage(); + return EX_USAGE!(); + } + } + 'F' => { + w.word = list_optarg; + Farg = list_optarg; + w.flags = 0; + if check_identifier(&mut w, posixly_correct) == 0 + || libc::strpbrk(Farg, shell_break_chars()) != std::ptr::null_mut() + { + sh_invalidid(Farg); + return EX_USAGE!(); + } + } + 'G' => { + Garg = list_optarg; + } + 'P' => { + Parg = list_optarg; + } + 'S' => { + Sarg = list_optarg; + } + 'W' => { + Warg = list_optarg; + } + 'X' => { + Xarg = list_optarg; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + opt = internal_getopt( + list, + CString::new("abcdefgjko:prsuvA:G:W:P:S:X:F:C:DEI") + .unwrap() + .as_ptr() as *mut libc::c_char, + ); + } + *actp = acts; + *optp = copts; + list = loptend.clone(); + if opt_given != 0 { + return EXECUTION_SUCCESS!(); + } else { + return EXECUTION_FAILURE!(); + } + } +} + +/* Add, remove, and display completion specifiers. */ +#[no_mangle] +pub fn complete_builtin(listt: *mut WordList) -> i32 { + let mut opt_given: i32 = 0; + let mut rval: i32; + let mut acts: libc::c_ulong = 0; + let mut copts: libc::c_ulong = 0; + let mut cs: *mut COMPSPEC; + let mut oflags: _optflags = _optflags { + pflag: 0, + rflag: 0, + Dflag: 0, + Eflag: 0, + Iflag: 0, + }; + let mut l: *mut WordList; + let mut wl: *mut WordList; + + unsafe { + let mut list: *mut WordList = listt.clone(); + if list == std::ptr::null_mut() { + print_all_completions(); + return EXECUTION_SUCCESS!(); + } + + oflags.pflag = 0; + oflags.rflag = 0; + oflags.Dflag = 0; + oflags.Eflag = 0; + oflags.Iflag = 0; + + Garg = std::ptr::null_mut(); + Warg = std::ptr::null_mut(); + Parg = std::ptr::null_mut(); + Sarg = std::ptr::null_mut(); + Xarg = std::ptr::null_mut(); + Farg = std::ptr::null_mut(); + Carg = std::ptr::null_mut(); + + cs = std::ptr::null_mut(); + + /* Build the actions from the arguments. Also sets the [A-Z]arg variables + as a side effect if they are supplied as options. */ + rval = build_actions(list, &mut oflags, &mut acts, &mut copts); + if rval == EX_USAGE!() { + return rval; + } + + opt_given = (rval != EXECUTION_FAILURE!()) as i32; + + list = loptend.clone(); + + if oflags.Dflag != 0 { + wl = make_word_list(make_bare_word(DEFAULTCMD()), std::ptr::null_mut()); + } else if oflags.Eflag != 0 { + wl = make_word_list(make_bare_word(EMPTYCMD()), std::ptr::null_mut()); + } else if oflags.Iflag != 0 { + wl = make_word_list(make_bare_word(INITIALWORD()), std::ptr::null_mut()); + } else { + wl = std::ptr::null_mut(); + } + + /* -p overrides everything else */ + if oflags.pflag != 0 || (list == std::ptr::null_mut() && opt_given == 0) { + if wl != std::ptr::null_mut() { + rval = print_cmd_completions(wl); + dispose_words(wl); + return rval; + } else if list == std::ptr::null_mut() { + //给了P,ä½†æ²¡ç»™å‚æ•°ï¼Œç›´æŽ¥æ‰“å°å…¨éƒ¨å¹¶é€€å‡º + print_all_completions(); + return EXECUTION_SUCCESS!(); + } + return print_cmd_completions(list); + } + + /* next, -r overrides everything else. */ + if oflags.rflag != 0 { + if wl != std::ptr::null_mut() { + rval = remove_cmd_completions(wl); + dispose_words(wl); + return rval; + } else if list == std::ptr::null_mut() { + progcomp_flush(); + return EXECUTION_SUCCESS!(); + } + return remove_cmd_completions(list); + } + + if wl == std::ptr::null_mut() && list == std::ptr::null_mut() && opt_given != 0 { + builtin_usage(); + return EX_USAGE!(); + } + + /* If we get here, we need to build a compspec and add it for each + remaining argument. */ + cs = compspec_create(); + (*cs).actions = acts; + (*cs).options = copts; + + (*cs).globpat = STRDUP(Garg); + (*cs).words = STRDUP(Warg); + (*cs).prefix = STRDUP(Parg); + (*cs).suffix = STRDUP(Sarg); + (*cs).funcname = STRDUP(Farg); + (*cs).command = STRDUP(Carg); + (*cs).filterpat = STRDUP(Xarg); + + rval = EXECUTION_SUCCESS!(); + + if wl != std::ptr::null_mut() { + l = wl.clone(); + } else { + l = list.clone(); + } + + while l != std::ptr::null_mut() { + /* Add CS as the compspec for the specified commands. */ + if progcomp_insert((*(*l).word).word, cs) == 0 { + rval = EXECUTION_FAILURE!(); + } + l = (*l).next; + } + + dispose_words(wl); + return rval; + } +} + +#[no_mangle] +pub fn remove_cmd_completions(list: *mut WordList) -> i32 { + let mut l: *mut WordList; + let mut ret: i32; + unsafe { + ret = EXECUTION_SUCCESS!(); + l = list.clone(); + while l != std::ptr::null_mut() { + if progcomp_remove((*(*l).word).word) == 0 { + builtin_error( + CString::new("%s: no completion specification") + .unwrap() + .as_ptr(), + (*(*l).word).word, + ); + ret = EXECUTION_FAILURE!(); + } + l = (*l).next; + } + return ret; + } +} + +#[no_mangle] +pub fn print_compoptions(copts: libc::c_ulong, full: i32) { + unsafe { + let compopts: CompoptArray = CompoptArray::new(); + for i in 0..compopts.compoptArr.len() { + if (copts & compopts.compoptArr[i].optflag) != 0 { + libc::printf( + CString::new("-o %s ").unwrap().as_ptr(), + compopts.compoptArr[i].optname, + ); + } else if full != 0 { + libc::printf( + CString::new("+o %s ").unwrap().as_ptr(), + compopts.compoptArr[i].optname, + ); + } + } + } +} + +#[no_mangle] +pub fn print_compactions(acts: libc::c_ulong) { + unsafe { + let compacts: CompactsArray = CompactsArray::new(); + for i in 0..compacts.compactsArr.len() { + if compacts.compactsArr[i].actopt != 0 && (acts & compacts.compactsArr[i].actflag) != 0 + { + libc::printf( + CString::new("-%c ").unwrap().as_ptr(), + compacts.compactsArr[i].actopt, + ); + } + } + + for i in 0..compacts.compactsArr.len() { + if compacts.compactsArr[i].actopt == 0 && (acts & compacts.compactsArr[i].actflag) != 0 + { + libc::printf( + CString::new("-A %s ").unwrap().as_ptr(), + compacts.compactsArr[i].actname, + ); + } + } + } +} + +#[no_mangle] +pub fn print_arg(arg: *const libc::c_char, flag: *const libc::c_char, quote: i32) { + let x: *mut libc::c_char; + unsafe { + if arg != std::ptr::null_mut() { + if quote != 0 { + // å¤åˆ¶arg 增加å•引å·è¿”ç»™x + x = sh_single_quote(arg as *mut libc::c_char); + } else { + x = arg as *mut libc::c_char; + } + libc::printf(CString::new("%s %s ").unwrap().as_ptr(), flag, x); + if x != arg as *mut libc::c_char { + libc::free(x as *mut c_void); + } + } + } +} + +#[no_mangle] +pub fn print_cmd_name(cmd: *const libc::c_char) { + unsafe { + if STREQ(cmd, DEFAULTCMD()) { + libc::printf(CString::new("-D").unwrap().as_ptr()); + } else if STREQ(cmd, EMPTYCMD()) { + libc::printf(CString::new("-E").unwrap().as_ptr()); + } else if STREQ(cmd, INITIALWORD()) { + libc::printf(CString::new("-I").unwrap().as_ptr()); + } else if *cmd == 0 { + /* XXX - can this happen? */ + libc::printf(CString::new("''").unwrap().as_ptr()); + } else { + libc::printf(CString::new("%s").unwrap().as_ptr(), cmd); + } + } +} + +#[no_mangle] +pub fn print_one_completion(cmd: *mut libc::c_char, cs: *mut COMPSPEC) -> i32 { + unsafe { + libc::printf(CString::new("complete ").unwrap().as_ptr()); + + print_compoptions((*cs).options, 0); + print_compactions((*cs).actions); + + /* now the rest of the arguments */ + + /* arguments that require quoting */ + print_arg((*cs).globpat, CString::new("-G").unwrap().as_ptr(), 1); + print_arg((*cs).words, CString::new("-W").unwrap().as_ptr(), 1); + print_arg((*cs).prefix, CString::new("-P").unwrap().as_ptr(), 1); + print_arg((*cs).suffix, CString::new("-S").unwrap().as_ptr(), 1); + print_arg((*cs).filterpat, CString::new("-X").unwrap().as_ptr(), 1); + + print_arg((*cs).command, CString::new("-C").unwrap().as_ptr(), 1); + + /* simple arguments that don't require quoting */ + print_arg((*cs).funcname, CString::new("-F").unwrap().as_ptr(), 0); + + print_cmd_name(cmd); + libc::printf(CString::new("\n").unwrap().as_ptr()); + + return 0; + } +} + +#[no_mangle] +pub fn print_compopts(cmd: *mut libc::c_char, cs: *mut COMPSPEC, full: i32) { + unsafe { + libc::printf(CString::new("compopt ").unwrap().as_ptr()); + + print_compoptions((*cs).options, full); + print_cmd_name(cmd); + + libc::printf(CString::new("\n").unwrap().as_ptr()); + } +} + +#[no_mangle] +pub fn print_compitem(item: *mut BUCKET_CONTENTS) -> i32 { + let cs: *mut COMPSPEC; + let cmd: *mut libc::c_char; + unsafe { + cmd = (*item).key; + cs = (*item).data as *mut COMPSPEC; + } + + return print_one_completion(cmd, cs); +} + +#[no_mangle] +pub fn print_all_completions() { + progcomp_walk(Some(print_compitem)); +} + +#[no_mangle] +pub fn print_cmd_completions(list: *mut WordList) -> i32 { + let mut l: *mut WordList; + let mut cs: *mut COMPSPEC; + let mut ret: i32; + + unsafe { + ret = EXECUTION_SUCCESS!(); + l = list.clone(); + while l != std::ptr::null_mut() { + cs = progcomp_search((*(*l).word).word); + if cs != std::ptr::null_mut() { + print_one_completion((*(*l).word).word, cs); + } else { + builtin_error( + CString::new("%s: no completion specification") + .unwrap() + .as_ptr(), + (*(*l).word).word, + ); + ret = EXECUTION_FAILURE!(); + } + l = (*l).next; + } + return sh_chkwrite(ret); + } +} + +#[no_mangle] +pub fn compgen_builtin(listt: *mut WordList) -> i32 { + let mut rval: i32; + let mut acts: libc::c_ulong = 0; + let mut copts: libc::c_ulong = 0; + let mut cs: *mut COMPSPEC; + let mut sl: *mut STRINGLIST; + let word: *mut libc::c_char; + let mut matches: *mut *mut libc::c_char; + let old_line: *mut libc::c_char; + let old_ind: i32; + unsafe { + let mut list: *mut WordList = listt.clone(); + if list == std::ptr::null_mut() { + return EXECUTION_SUCCESS!(); + } + + Garg = std::ptr::null_mut(); + Warg = std::ptr::null_mut(); + Parg = std::ptr::null_mut(); + Sarg = std::ptr::null_mut(); + Xarg = std::ptr::null_mut(); + Farg = std::ptr::null_mut(); + Carg = std::ptr::null_mut(); + + cs = std::ptr::null_mut(); + + /* Build the actions from the arguments. Also sets the [A-Z]arg variables + as a side effect if they are supplied as options. */ + rval = build_actions(list, std::ptr::null_mut(), &mut acts, &mut copts); + if rval == EX_USAGE!() { + return rval; + } + + if rval == EXECUTION_FAILURE!() { + return EXECUTION_SUCCESS!(); + } + + list = loptend.clone(); + + let wordtmp = CString::new("").unwrap(); + if list != std::ptr::null_mut() && (*list).word != std::ptr::null_mut() { + word = (*((*list).word)).word; + } else { + word = wordtmp.as_ptr() as *mut libc::c_char; + } + + if Farg != std::ptr::null_mut() { + builtin_error( + CString::new("warning: -F option may not work as you expect") + .unwrap() + .as_ptr(), + ); + } + + if Carg != std::ptr::null_mut() { + builtin_error( + CString::new("warning: -C option may not work as you expect") + .unwrap() + .as_ptr(), + ); + } + + /* If we get here, we need to build a compspec and evaluate it. */ + cs = compspec_create(); + (*cs).actions = acts; + (*cs).options = copts; + (*cs).refcount = 1; + + (*cs).globpat = STRDUP(Garg); + (*cs).words = STRDUP(Warg); + (*cs).prefix = STRDUP(Parg); + (*cs).suffix = STRDUP(Sarg); + (*cs).funcname = STRDUP(Farg); + (*cs).command = STRDUP(Carg); + (*cs).filterpat = STRDUP(Xarg); + + rval = EXECUTION_FAILURE!(); + + /* probably don't have to save these, just being safe */ + old_line = pcomp_line; + old_ind = pcomp_ind; + pcomp_line = std::ptr::null_mut(); + pcomp_ind = 0; + let compgenStr = CString::new("compgen").unwrap(); + sl = gen_compspec_completions(cs, compgenStr.as_ptr(), word, 0, 0, std::ptr::null_mut()); + pcomp_line = old_line; + pcomp_ind = old_ind; + + /* If the compspec wants the bash default completions, temporarily + turn off programmable completion and call the bash completion code. */ + if (sl == std::ptr::null_mut() || (*sl).list_len == 0) && (copts & COPT_BASHDEFAULT!()) != 0 + { + matches = bash_default_completion(word, 0, 0, 0, 0); + sl = completions_to_stringlist(matches); + strvec_dispose(matches); + } + + /* This isn't perfect, but it's the best we can do, given what readline + exports from its set of completion utility functions. */ + if (sl == std::ptr::null_mut() || (*sl).list_len == 0) && (copts & COPT_DEFAULT!()) != 0 { + matches = rl_completion_matches(word, rl_filename_completion_function); + strlist_dispose(sl); + sl = completions_to_stringlist(matches); + strvec_dispose(matches); + } + + if sl != std::ptr::null_mut() { + if (*sl).list != std::ptr::null_mut() && (*sl).list_len != 0 { + rval = EXECUTION_SUCCESS!(); + strlist_print(sl, std::ptr::null_mut()); + } + strlist_dispose(sl); + } + + compspec_dispose(cs); + return rval; + } +} + +#[no_mangle] +pub fn compopt_builtin(listt: *mut WordList) -> i32 { + let mut opts_on: i32 = 0; + let mut opts_off: i32 = 0; + let mut opts: *mut i32; + let mut opt: i32; + let mut oind: i32; + let mut ret: i32; + let mut Dflag: i32 = 0; + let mut Eflag: i32 = 0; + let mut Iflag: i32 = 0; + let mut l: *mut WordList; + let mut wl: *mut WordList; + let mut cs: *mut COMPSPEC; + + ret = EXECUTION_SUCCESS!(); + unsafe { + let mut list: *mut WordList = listt.clone(); + reset_internal_getopt(); + + opt = internal_getopt( + list, + CString::new("+o:DEI").unwrap().as_ptr() as *mut libc::c_char, + ); + + while opt != -1 { + if list_opttype == '-' as i32 { + opts = &mut opts_on; + } else { + opts = &mut opts_off; + } + + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + + match optChar { + 'o' => { + oind = find_compopt(list_optarg); + if oind < 0 { + sh_invalidoptname(list_optarg); + return EX_USAGE!(); + } + let compopts: CompoptArray = CompoptArray::new(); + *opts |= compopts.compoptArr[oind as usize].optflag as i32; + } + 'D' => { + Dflag = 1; + } + 'E' => { + Eflag = 1; + } + 'I' => { + Iflag = 1; + } + _ => { + builtin_usage(); + return EX_USAGE!(); + } + } + opt = internal_getopt( + list, + CString::new("+o:DEI").unwrap().as_ptr() as *mut libc::c_char, + ); + } + + list = loptend.clone(); + + if Dflag != 0 { + wl = make_word_list(make_bare_word(DEFAULTCMD()), std::ptr::null_mut()); + } else if Eflag != 0 { + wl = make_word_list(make_bare_word(EMPTYCMD()), std::ptr::null_mut()); + } else if Iflag != 0 { + wl = make_word_list(make_bare_word(INITIALWORD()), std::ptr::null_mut()); + } else { + wl = std::ptr::null_mut(); + } + + if list == std::ptr::null_mut() && wl == std::ptr::null_mut() { + if RL_ISSTATE(RL_STATE_COMPLETING!()) == 0 || pcomp_curcs == std::ptr::null_mut() { + builtin_error( + CString::new("not currently executing completion function") + .unwrap() + .as_ptr(), + ); + return EXECUTION_FAILURE!(); + } + cs = pcomp_curcs.clone(); + + if opts_on == 0 && opts_off == 0 { + print_compopts(pcomp_curcmd as *mut libc::c_char, cs, 1); + return sh_chkwrite(ret); + } + + /* Set the compspec options */ + pcomp_set_compspec_options(cs, opts_on, 1); + pcomp_set_compspec_options(cs, opts_off, 0); + + /* And change the readline variables the options control */ + pcomp_set_readline_variables(opts_on, 1); + pcomp_set_readline_variables(opts_off, 0); + + return ret; + } + + if wl != std::ptr::null_mut() { + l = wl.clone(); + } else { + l = list.clone(); + } + + while l != std::ptr::null_mut() { + cs = progcomp_search((*((*list).word)).word); + if cs == std::ptr::null_mut() { + builtin_error( + CString::new("%s: no completion specification") + .unwrap() + .as_ptr(), + (*((*list).word)).word, + ); + ret = EXECUTION_FAILURE!(); + l = (*l).next; + continue; + } + if opts_on == 0 && opts_off == 0 { + print_compopts((*((*list).word)).word, cs, 1); + l = (*l).next; + continue; /* XXX -- fill in later */ + } + + /* Set the compspec options */ + pcomp_set_compspec_options(cs, opts_on, 1); + pcomp_set_compspec_options(cs, opts_off, 0); + l = (*l).next; + } + + if wl != std::ptr::null_mut() { + dispose_words(wl); + } + + return ret; + } +} diff --git a/utshell-0.5.0/src/builtins/declare.rs b/utshell-0.5.0/src/builtins/declare.rs new file mode 100644 index 00000000..b293eedf --- /dev/null +++ b/utshell-0.5.0/src/builtins/declare.rs @@ -0,0 +1,1279 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::arrayfunc::{ + assign_array_element, assign_array_var_from_string, bind_array_variable, bind_assoc_variable, + convert_var_to_array, convert_var_to_assoc, valid_array_reference, +}; +use crate::general::{assignment, check_selfref, legal_identifier}; +use crate::print_cmd::named_function_string; +use crate::src_common::*; +use crate::variables::{ + bind_global_variable, bind_variable, bind_variable_value, delete_var, find_function, + find_function_def, find_global_variable, find_global_variable_last_nameref, + find_global_variable_noref, find_tempenv_variable, find_variable, find_variable_last_nameref, + find_variable_noref, make_local_array_variable, make_local_assoc_variable, make_local_variable, + make_new_array_variable, make_new_assoc_variable, nameref_transform_name, + stupidly_hack_special_variables, +}; +use crate::version::shell_compatibility_level; + +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + common::{builtin_usage, sh_chkwrite, sh_invalidid, sh_invalidopt, sh_notfound, sh_readonly}, + help::builtin_help, + set::{get_current_options, set_builtin}, + setattr::{ + set_or_show_attributes, show_all_var_attributes, show_func_attributes, + show_local_var_attributes, show_localname_attributes, show_name_attributes, + }, +}; + +#[no_mangle] +pub fn declare_builtin(list: *mut WordList) -> i32 { + return declare_internal(list, 0); +} + +fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + unsafe { + return *a == *b && libc::strcmp(a, b) == 0; + } +} + +#[no_mangle] +pub fn local_builtin(list: *mut WordList) -> i32 { + unsafe { + /* Catch a straight `local --help' before checking function context */ + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && STREQ( + (*(*list).word).word, + CString::new("--help").unwrap().as_ptr(), + ) + { + builtin_help(); + return EX_USAGE!(); + } + + if variable_context != 0 { + return declare_internal(list, 1); + } else { + builtin_error( + CString::new("can only be used in a function") + .unwrap() + .as_ptr(), + ); + return EXECUTION_FAILURE!(); + } + } +} + +fn local_p(varr: *mut SHELL_VAR) -> i32 { + unsafe { + return (*varr).attributes & att_local!(); + } +} + +#[no_mangle] +pub fn declare_find_variable( + name: *const libc::c_char, + mkglobal: i32, + chklocal: i32, +) -> *mut SHELL_VAR { + let varr: *mut SHELL_VAR; + unsafe { + if mkglobal == 0 { + return find_variable(name); + } else if chklocal != 0 { + varr = find_variable(name); + if varr != std::ptr::null_mut() + && local_p(varr) != 0 + && (*varr).context == variable_context + { + return varr; + } + + return find_global_variable(name); + } else { + return find_global_variable(name); + } + } +} + +fn DECLARE_OPTS() -> CString { + return CString::new("+acfgilnprtuxAFGI").unwrap(); +} + +fn value_cell(var: *mut SHELL_VAR) -> *mut libc::c_char { + unsafe { + return (*var).value; + } +} + +fn var_setvalue(var: *mut SHELL_VAR, str1: *mut libc::c_char) { + unsafe { + (*var).value = str1; + } +} + +fn VSETATTR(var: *mut SHELL_VAR, attr: i32) { + unsafe { + (*var).attributes |= attr; + } +} + +fn readonly_p(var: *mut SHELL_VAR) -> i32 { + unsafe { + return (*var).attributes & att_readonly!(); + } +} + +fn nameref_p(var: *mut SHELL_VAR) -> i32 { + unsafe { + return (*var).attributes & att_nameref!(); + } +} + +fn nameref_cell(var: *mut SHELL_VAR) -> *mut libc::c_char { + unsafe { + return (*var).value; /* so it can change later */ + } +} + +fn function_cell(var: *mut SHELL_VAR) -> *mut COMMAND { + unsafe { + return (*var).value as *mut COMMAND; + } +} + +fn VUNSETATTR(var: *mut SHELL_VAR, attr: i32) { + unsafe { + (*var).attributes &= !attr; + } +} + +fn array_p(var: *mut SHELL_VAR) -> i32 { + unsafe { + return (*var).attributes & att_array!(); + } +} + +fn assoc_p(var: *mut SHELL_VAR) -> i32 { + unsafe { + return (*var).attributes & att_assoc!(); + } +} + +fn var_isset(var: *mut SHELL_VAR) -> bool { + unsafe { + return (*var).value != std::ptr::null_mut(); + } +} + +fn tempvar_p(var: *mut SHELL_VAR) -> i32 { + unsafe { + return (*var).attributes & att_tempvar!(); + } +} + +fn noassign_p(var: *mut SHELL_VAR) -> i32 { + unsafe { + return (*var).attributes & att_noassign!(); + } +} + +#[no_mangle] +pub fn declare_internal(mut list: *mut WordList, local_var: i32) -> i32 { + let mut flags_on: i32 = 0; + let mut flags_off: i32 = 0; + let mut flags: *mut i32; + let mut any_failed: i32 = 0; + let mut assign_error: i32 = 0; + let mut pflag: i32 = 0; + let mut nodefs: i32 = 0; + let mut opt: i32; + let mut onref: i32; + let mut offref: i32; + let mut mkglobal: i32 = 0; + let mut chklocal: i32 = 0; + let mut inherit_flag: i32 = 0; + + let mut t: *mut libc::c_char; + let mut subscript_start: *mut libc::c_char; + let mut var: *mut SHELL_VAR; + let mut refvar: *mut SHELL_VAR; + let mut v: *mut SHELL_VAR; + + let mut shell_fn: *mut function_def; + + refvar = std::ptr::null_mut(); + unsafe { + reset_internal_getopt(); + let tmp = DECLARE_OPTS(); + opt = internal_getopt(list, tmp.as_ptr() as *mut libc::c_char); + while opt != -1 { + if list_opttype == '+' as i32 { + flags = &mut flags_off; + } else { + flags = &mut flags_on; + } + + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + + /* If you add options here, see whether or not they need to be added to + the loop in subst.c:shell_expand_word_list() */ + match optChar { + 'a' => { + *flags |= att_array!(); + } + 'A' => { + *flags |= att_assoc!(); + } + 'p' => { + pflag += 1; + } + 'F' => { + nodefs += 1; + *flags |= att_function!(); + } + 'f' => { + *flags |= att_function!(); + } + 'G' => { + if flags == &mut flags_on { + chklocal = 1; + } + } + 'g' => { + if flags == &mut flags_on { + mkglobal = 1; + } + } + 'i' => { + *flags |= att_integer!(); + } + 'n' => { + *flags |= att_nameref!(); + } + 'r' => { + *flags |= att_readonly!(); + } + 't' => { + *flags |= att_trace!(); + } + 'x' => { + *flags |= att_exported!(); + array_needs_making = 1; + } + 'c' => { + *flags |= att_capcase!(); + if flags == &mut flags_on { + flags_off |= att_uppercase!() | att_lowercase!(); + } + } + 'l' => { + *flags |= att_lowercase!(); + if flags == &mut flags_on { + flags_off |= att_capcase!() | att_uppercase!(); + } + } + 'u' => { + *flags |= att_uppercase!(); + if flags == &mut flags_on { + flags_off |= att_capcase!() | att_lowercase!(); + } + } + 'I' => { + inherit_flag = MKLOC_INHERIT!(); + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + opt = internal_getopt(list, tmp.as_ptr() as *mut libc::c_char); + } + list = loptend; + /* If there are no more arguments left, then we just want to show + some variables. */ + if list == std::ptr::null_mut() { + /* declare -[aAfFirtx] */ + /* Show local variables defined at this context level if this is + the `local' builtin. */ + if local_var != 0 { + show_local_var_attributes(0, nodefs); /* XXX - fix up args later */ + } else if pflag != 0 && (flags_on == 0 || flags_on == att_function!()) { + let mut ret = 0; + if flags_on == 0 { + ret = 1; + } + show_all_var_attributes(ret, nodefs); + } else if flags_on == 0 { + return set_builtin(std::ptr::null_mut()); + } else { + set_or_show_attributes(std::ptr::null_mut(), flags_on, nodefs); + } + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + + if pflag != 0 { + /* declare -p [-aAfFirtx] name [name...] */ + any_failed = 0; + while list != std::ptr::null_mut() { + if (flags_on & att_function!()) != 0 { + pflag = show_func_attributes((*(*list).word).word, nodefs); + } else if local_var != 0 { + pflag = show_localname_attributes((*(*list).word).word, nodefs); + } else { + pflag = show_name_attributes((*(*list).word).word, nodefs); + } + if pflag != 0 { + sh_notfound((*(*list).word).word); + any_failed += 1; + } + list = (*list).next; + } + + if any_failed != 0 { + return EXECUTION_FAILURE!(); + } else { + return EXECUTION_SUCCESS!(); + } + } + let tmpValue = CString::new("").unwrap(); + + /* There are arguments left, so we are making variables. */ + 'outter: while list != std::ptr::null_mut() { + /* declare [-aAfFirx] name [name ...] */ + let mut value: *mut libc::c_char; + let mut name: *mut libc::c_char; + let mut oldname: *mut libc::c_char; + let mut offset: i32; + let mut aflags: i32; + let wflags: i32; + let mut created_var: i32; + let mut namelen: i32; + let assoc_noexpand: bool; + + let mut making_array_special: i32; + let mut compound_array_assign: i32; + let mut simple_array_assign: i32; + let mut var_exists: i32; + let mut array_exists: i32; + let mut creating_array: i32; + let mut array_subscript_assignment: bool; + + name = savestring!((*(*list).word).word); + wflags = (*(*list).word).flags; + + assoc_noexpand = assoc_expand_once != 0 && (wflags & (1 << 2)) != 0; + // 分出= + if assoc_noexpand { + offset = assignment(name, 2); + } else { + offset = assignment(name, 0); + } + + aflags = 0; + created_var = 0; + + if local_var != 0 + && variable_context != 0 + && STREQ(name, CString::new("-").unwrap().as_ptr()) + { + var = make_local_variable(CString::new("-").unwrap().as_ptr(), 0); + if value_cell(var) != std::ptr::null_mut() { + libc::free(value_cell(var) as *mut c_void); /* just in case */ + } + value = get_current_options(); + var_setvalue(var, value); + VSETATTR(var, att_invisible!()); + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + if offset != 0 { + /* declare [-aAfFirx] name=value */ + *name.offset(offset as isize) = '\0' as libc::c_char; + value = name.offset((offset + 1) as isize); + if *(name.offset((offset - 1) as isize)) == '+' as libc::c_char { + aflags |= ASS_APPEND!(); + *(name.offset((offset - 1) as isize)) = '\0' as libc::c_char; + } + } else { + value = tmpValue.as_ptr() as *mut libc::c_char; + } + /* Do some lexical error checking on the LHS and RHS of the assignment + that is specific to nameref variables. */ + if (flags_on & att_nameref!()) != 0 { + if valid_array_reference(name, 0) != 0 { + builtin_error( + CString::new("%s: reference variable cannot be an array") + .unwrap() + .as_ptr(), + name, + ); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } else if check_selfref(name, value, 0) != 0 { + /* disallow self references at global scope, warn at function scope */ + if variable_context == 0 { + builtin_error( + CString::new("%s: nameref variable self references not allowed") + .unwrap() + .as_ptr(), + name, + ); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } else { + builtin_warning( + CString::new("%s: circular name reference") + .unwrap() + .as_ptr(), + name, + ); + } + } + + if value != std::ptr::null_mut() + && (*value) != 0 + && (aflags & ASS_APPEND!()) == 0 + && valid_nameref_value(value, 1) == 0 + { + builtin_error( + CString::new("`nvalid %s': ivariable name for name reference") + .unwrap() + .as_ptr(), + value, + ); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + } + //restart_new_var_name: + 'inner: loop { + var_exists = 0; + array_exists = 0; + creating_array = 0; + compound_array_assign = 0; + simple_array_assign = 0; + array_subscript_assignment = false; + subscript_start = std::ptr::null_mut(); + t = libc::strchr(name, '[' as libc::c_int); + if t != std::ptr::null_mut() && (flags_on & att_function!()) == 0 { + /* ] */ + /* If offset != 0 we have already validated any array reference + because assignment() calls skipsubscript() */ + if offset == 0 && valid_array_reference(name, 0) == 0 { + sh_invalidid(name); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + subscript_start = t; + *t = '\0' as libc::c_char; + making_array_special = 1; /* XXX - should this check offset? */ + array_subscript_assignment = offset != 0; + } else { + making_array_special = 0; + } + /* If we're in posix mode or not looking for a shell function (since + shell function names don't have to be valid identifiers when the + shell's not in posix mode), check whether or not the argument is a + valid, well-formed shell identifier. */ + if (posixly_correct != 0 || (flags_on & att_function!()) == 0) + && legal_identifier(name) == 0 + { + sh_invalidid(name); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + /* If VARIABLE_CONTEXT has a non-zero value, then we are executing + inside of a function. This means we should make local variables, + not global ones. */ + + /* XXX - this has consequences when we're making a local copy of a + variable that was in the temporary environment. Watch out + for this. */ + refvar = std::ptr::null_mut(); + if variable_context != 0 && mkglobal == 0 && ((flags_on & att_function!()) == 0) { + let newname: *mut libc::c_char; + + /* check name for validity here? */ + var = find_variable(name); + if var == std::ptr::null_mut() { + newname = nameref_transform_name(name, ASS_MKLOCAL!()); + } else if (flags_on & att_nameref!()) == 0 && (flags_off & att_nameref!()) == 0 + { + /* Ok, we're following namerefs here, so let's make sure that if + we followed one, it was at the same context (see below for + more details). */ + refvar = find_variable_last_nameref(name, 1); + if refvar != std::ptr::null_mut() && (*refvar).context != variable_context { + newname = name; + } else { + newname = (*var).name; + } + refvar = std::ptr::null_mut(); + } else { + newname = name; /* dealing with nameref attribute */ + } + // 至此,find_variable 返回var 没有被更新 + /* Pass 1 as second argument to make_local_{assoc,array}_variable + return an existing {array,assoc} variable to be flagged as an + error below. */ + if (flags_on & att_assoc!()) != 0 { + var = make_local_assoc_variable(newname, MKLOC_ARRAYOK!() | inherit_flag); + } else if (flags_on & att_array!()) != 0 || making_array_special != 0 { + var = make_local_array_variable(newname, MKLOC_ASSOCOK!() | inherit_flag); + } else if offset == 0 && (flags_on & att_nameref!()) != 0 { + /* First look for refvar at current scope */ + refvar = find_variable_last_nameref(name, 1); + /* VARIABLE_CONTEXT != 0, so we are attempting to create or modify + the attributes for a local variable at the same scope. If we've + used a reference from a previous context to resolve VAR, we + want to throw REFVAR and VAR away and create a new local var. */ + if refvar != std::ptr::null_mut() && (*refvar).context != variable_context { + refvar = std::ptr::null_mut(); + var = make_local_variable(name, inherit_flag); + } else if refvar != std::ptr::null_mut() + && (*refvar).context == variable_context + { + var = refvar; + } else if var == std::ptr::null_mut() + || (*refvar).context != variable_context + { + /* Maybe we just want to create a new local variable */ + var = make_local_variable(name, inherit_flag); + } + /* otherwise we have a var at the right context */ + } else { + /* XXX - check name for validity here with valid_nameref_value */ + if flags_on & att_nameref!() != 0 { + var = make_local_variable(name, inherit_flag); + } else { + var = make_local_variable(newname, inherit_flag); /* sets att_invisible for new vars */ + } + } + + if var == std::ptr::null_mut() { + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + if var != std::ptr::null_mut() + && nameref_p(var) != 0 + && readonly_p(var) != 0 + && nameref_cell(var) != std::ptr::null_mut() + && (flags_off & att_nameref!()) != 0 + { + sh_readonly(name); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + } else { + var = std::ptr::null_mut(); + } + /* If we are declaring a function, then complain about it in some way. + We don't let people make functions by saying `typeset -f foo=bar'. */ + + /* There should be a way, however, to let people look at a particular + function definition by saying `typeset -f foo'. */ + + if (flags_on & att_function!()) != 0 { + if offset != 0 { + /* declare -f [-rix] foo=bar */ + builtin_error( + CString::new("cannot use `-f' to make functions") + .unwrap() + .as_ptr(), + ); + libc::free(name as *mut c_void); + return EXECUTION_FAILURE!(); + } else { + /* declare -f [-rx] name [name...] */ + var = find_function(name); + if var != std::ptr::null_mut() { + if readonly_p(var) != 0 && (flags_off & att_readonly!()) != 0 { + builtin_error( + CString::new("%s: readonly function").unwrap().as_ptr(), + name, + ); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } else if (flags_on & (att_array!() | att_assoc!())) != 0 { + if (flags_on & att_array!()) != 0 { + sh_invalidopt( + CString::new("-a").unwrap().as_ptr() as *mut libc::c_char + ); + } else { + sh_invalidopt( + CString::new("-A").unwrap().as_ptr() as *mut libc::c_char + ); + } + + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + /* declare -[Ff] name [name...] */ + if flags_on == att_function!() && flags_off == 0 { + if nodefs != 0 && debugging_mode != 0 { + shell_fn = find_function_def((*var).name); + if shell_fn != std::ptr::null_mut() { + println!( + "{} {} {}", + CStr::from_ptr((*var).name).to_str().unwrap(), + (*shell_fn).line, + CStr::from_ptr((*shell_fn).source_file) + .to_str() + .unwrap() + ); + } else { + println!( + "{}", + CStr::from_ptr((*var).name).to_str().unwrap() + ); + } + } else { + if nodefs != 0 { + t = (*var).name; + } else { + t = named_function_string( + name, + function_cell(var), + FUNC_MULTILINE!() | FUNC_EXTERNAL!(), + ); + } + println!("{}", CStr::from_ptr(t).to_str().unwrap()); + any_failed = sh_chkwrite(any_failed); + } + } else { + /* declare -[fF] -[rx] name [name...] */ + VSETATTR(var, flags_on); + flags_off &= !att_function!(); /* makes no sense */ + VUNSETATTR(var, flags_off); + } + } else { + any_failed += 1; + } + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + } else { + /* declare -[aAinrx] name [name...] */ + /* Non-null if we just created or fetched a local variable. */ + + /* Here's what ksh93 seems to do as of the 2012 version: if we are + using declare -n to modify the value of an existing nameref + variable, don't follow the nameref chain at all and just search + for a nameref at the current context. If we have a nameref, + modify its value (changing which variable #define ASS_NAMEREF 0x0010 /* assigning to nameref variable */it references). */ + if var == std::ptr::null_mut() && (flags_on & att_nameref!()) != 0 { + /* See if we are trying to modify an existing nameref variable, + but don't follow the nameref chain. */ + if mkglobal != 0 { + var = find_global_variable_noref(name); + } else { + var = find_variable_noref(name); + } + + if var != std::ptr::null_mut() && nameref_p(var) == 0 { + var = std::ptr::null_mut(); + } + } else if var == std::ptr::null_mut() && (flags_off & att_nameref!()) != 0 { + /* However, if we're turning off the nameref attribute on an existing + nameref variable, we first follow the nameref chain to the end, + modify the value of the variable this nameref variable references + if there is an assignment statement argument, + *CHANGING ITS VALUE AS A SIDE EFFECT*, then turn off the nameref + flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */ + /* See if we are trying to modify an existing nameref variable */ + if mkglobal != 0 { + refvar = find_global_variable_last_nameref(name, 0); + } else { + refvar = find_variable_last_nameref(name, 0); + } + + if refvar != std::ptr::null_mut() && nameref_p(refvar) == 0 { + refvar = std::ptr::null_mut(); + } + /* If the nameref is readonly but doesn't have a value, ksh93 + allows the nameref attribute to be removed. If it's readonly + and has a value, even if the value doesn't reference an + existing variable, we disallow the modification */ + if refvar != std::ptr::null_mut() + && nameref_cell(refvar) != std::ptr::null_mut() + && readonly_p(refvar) != 0 + { + sh_readonly(name); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + /* If all we're doing is turning off the nameref attribute, don't + bother with VAR at all, whether it exists or not. Just turn it + off and go on. */ + if refvar != std::ptr::null_mut() + && flags_on == 0 + && offset == 0 + && (flags_off & !att_nameref!()) == 0 + { + VUNSETATTR(refvar, att_nameref!()); + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + if refvar != std::ptr::null_mut() { + /* XXX - use declare_find_variable here? */ + if mkglobal != 0 { + var = find_global_variable(nameref_cell(refvar)); + } else { + var = find_variable(nameref_cell(refvar)); + } + } + } else if var == std::ptr::null_mut() + && offset != 0 + && array_subscript_assignment + { + /* If we have an array assignment to a nameref, remove the nameref + attribute and go on. */ + if mkglobal != 0 { + var = find_global_variable_noref(name); + } else { + var = find_variable_noref(name); + } + + if var != std::ptr::null_mut() && nameref_p(var) != 0 { + internal_warning( + CString::new("%s: removing nameref attribute") + .unwrap() + .as_ptr(), + name, + ); + libc::free(value_cell(var) as *mut c_void); /* XXX - bash-4.3 compat */ + var_setvalue(var, std::ptr::null_mut()); + VUNSETATTR(var, att_nameref!()); + } + } + + /* See if we are trying to set flags or value (or create) for an + existing nameref that points to a non-existent variable: e.g., + declare -n foo=bar + unset foo # unsets bar + declare -i foo + foo=4+4 + declare -p foo */ + if var == std::ptr::null_mut() + && (mkglobal != 0 || flags_on != 0 || flags_off != 0 || offset != 0) + { + if mkglobal != 0 { + refvar = find_global_variable_last_nameref(name, 0); + } else { + refvar = find_variable_last_nameref(name, 0); + } + + if refvar != std::ptr::null_mut() && nameref_p(refvar) == 0 { + refvar = std::ptr::null_mut(); + } + + if refvar != std::ptr::null_mut() { + /* XXX - use declare_find_variable here? */ + if mkglobal != 0 { + var = find_global_variable(nameref_cell(refvar)); + } else { + var = find_variable(nameref_cell(refvar)); + } + } + + if refvar != std::ptr::null_mut() && var == std::ptr::null_mut() { + oldname = name; /* need to free this */ + namelen = libc::strlen(nameref_cell(refvar)) as i32; + + if subscript_start != std::ptr::null_mut() { + *subscript_start = '[' as libc::c_char; /*]*/ + namelen += libc::strlen(subscript_start) as i32; + } + + name = + libc::malloc(namelen as libc::size_t + 2 + libc::strlen(value) + 1) + as *mut libc::c_char; + libc::strcpy(name, nameref_cell(refvar)); + + if subscript_start != std::ptr::null_mut() { + libc::strcpy( + name.offset(libc::strlen(nameref_cell(refvar)) as isize), + subscript_start, + ); + } + + /* We are committed to using the new name, so reset */ + if offset != 0 { + /* Rebuild assignment and restore offset and value */ + if (aflags & ASS_APPEND!()) != 0 { + *(name.offset(namelen as isize) as *mut libc::c_char) = + '+' as libc::c_char; + + namelen += 1; + } + *(name.offset(namelen as isize) as *mut libc::c_char) = + '=' as libc::c_char; + // *((name as usize + namelen as usize) as * mut libc::c_char) = '=' as libc::c_char; + namelen += 1; + + if value != std::ptr::null_mut() && (*value) != 0 { + libc::strcpy(name.offset(namelen as isize), value); + } else { + *(name.offset(namelen as isize) as *mut libc::c_char) = + '\0' as libc::c_char; + } + + offset = assignment(name, 0); + /* if offset was valid previously, but the substituting + of the nameref value results in an invalid assignment, + throw an invalid identifier error */ + if offset == 0 { + libc::free(oldname as *mut c_void); + sh_invalidid(name); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + *(name.offset(offset as isize)) = '\0' as libc::c_char; + + value = name.offset(namelen as isize); + } + libc::free(oldname as *mut c_void); + + /* OK, let's turn off the nameref attribute. + Now everything else applies to VAR. */ + if (flags_off & att_nameref!()) != 0 { + VUNSETATTR(refvar, att_nameref!()); + } + + //goto restart_new_var_name; + continue 'inner; + /* NOTREACHED */ + } + } + if var == std::ptr::null_mut() { + var = declare_find_variable(name, mkglobal, chklocal); + } + + var_exists = (var != std::ptr::null_mut()) as i32; + array_exists = (var != std::ptr::null_mut() + && (array_p(var) != 0 || assoc_p(var) != 0)) + as i32; + creating_array = flags_on & (att_array!() | att_assoc!()); + + if var == std::ptr::null_mut() { + if (flags_on & att_assoc!()) != 0 { + var = make_new_assoc_variable(name); + if var != std::ptr::null_mut() && offset == 0 { + VSETATTR(var, att_invisible!()); + } + } else if (flags_on & att_array!()) != 0 || making_array_special != 0 { + var = make_new_array_variable(name); + if var != std::ptr::null_mut() && offset == 0 { + VSETATTR(var, att_invisible!()); + } + } else { + if mkglobal != 0 { + var = + bind_global_variable(name, std::ptr::null_mut(), ASS_FORCE!()); + } else { + var = bind_variable(name, std::ptr::null_mut(), ASS_FORCE!()); + } + if var != std::ptr::null_mut() && offset == 0 { + VSETATTR(var, att_invisible!()); + } + } + + if var == std::ptr::null_mut() { + /* Has to appear in brackets */ + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + created_var = 1; + } else if (array_p(var) != 0 || assoc_p(var) != 0) + && (flags_on & att_nameref!()) != 0 + { + /* Can't take an existing array variable and make it a nameref */ + builtin_error( + CString::new("%s: reference variable cannot be an array") + .unwrap() + .as_ptr(), + name, + ); + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } else if nameref_p(var) != 0 + && (flags_on & att_nameref!()) == 0 + && (flags_off & att_nameref!()) == 0 + && offset != 0 + && valid_nameref_value(value, 1) == 0 + { + builtin_error( + CString::new("`%s': invalid variable name for name reference") + .unwrap() + .as_ptr(), + value, + ); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } else if (flags_on & att_nameref!()) != 0 { + /* Check of offset is to allow an assignment to a nameref var as + part of the declare word to override existing value */ + if nameref_p(var) == 0 + && var_isset(var) + && offset == 0 + && valid_nameref_value(value_cell(var), 0) == 0 + { + builtin_error( + CString::new("`%s': invalid variable name for name reference") + .unwrap() + .as_ptr(), + value_cell(var), + ); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + if readonly_p(var) != 0 { + sh_readonly(name); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + /* ksh93 compat: turning on nameref attribute turns off -ilu */ + VUNSETATTR( + var, + att_integer!() | att_uppercase!() | att_lowercase!() | att_capcase!(), + ); + } + + /* Cannot use declare +r to turn off readonly attribute. */ + if readonly_p(var) != 0 && (flags_off & att_readonly!()) != 0 { + sh_readonly((*var).name); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + /* Cannot use declare to assign value to readonly or noassign + variable. */ + if (readonly_p(var) != 0 || noassign_p(var) != 0) && offset != 0 { + if readonly_p(var) != 0 { + sh_readonly(name); + } + assign_error += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + /* make declare a[2]=foo as similar to a[2]=foo as possible if + a is already an array or assoc variable. */ + if array_subscript_assignment && array_exists != 0 && creating_array == 0 { + simple_array_assign = 1; + } else if (making_array_special != 0 + || creating_array != 0 + || array_exists != 0) + && offset != 0 + { + let vlen: i32; + vlen = libc::strlen(value) as i32; + /*itrace("declare_builtin: name = %s value = %s flags = %d", name, value, wflags);*/ + if shell_compatibility_level > 43 + && (wflags & W_COMPASSIGN!()) == 0 + && *value == '(' as libc::c_char + && *(value.offset((vlen - 1) as isize) as *mut libc::c_char) + == ')' as libc::c_char + { + /* The warning is only printed when using compound assignment + to an array variable that doesn't already exist. We use + creating_array to allow things like + declare -a foo$bar='(abc)' to work. */ + if array_exists == 0 && creating_array == 0 { + internal_warning( + CString::new("%s: quoted compound array assignment deprecated") + .unwrap() + .as_ptr(), + (*(*list).word).word, + ); + } + compound_array_assign = + (array_exists != 0 || creating_array != 0) as i32; + simple_array_assign = making_array_special; + } else if *value == '(' as libc::c_char + && *(value.offset((vlen - 1) as isize) as *mut libc::c_char) + == ')' as libc::c_char + && (shell_compatibility_level < 44 || (wflags & W_COMPASSIGN!()) != 0) + { + compound_array_assign = 1; + } else { + simple_array_assign = 1; + } + } + + /* Cannot use declare +a name or declare +A name to remove an + array variable. */ + if ((flags_off & att_array!()) != 0 && array_p(var) != 0) + || ((flags_off & att_assoc!()) != 0 && assoc_p(var) != 0) + { + builtin_error( + CString::new("%s: cannot destroy array variables in this way") + .unwrap() + .as_ptr(), + name, + ); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + if (flags_on & att_array!()) != 0 && assoc_p(var) != 0 { + builtin_error( + CString::new("%s: cannot convert associative to indexed array") + .unwrap() + .as_ptr(), + name, + ); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + if (flags_on & att_assoc!()) != 0 && array_p(var) != 0 { + builtin_error( + CString::new("%s: cannot convert indexed to associative array") + .unwrap() + .as_ptr(), + name, + ); + any_failed += 1; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + + /* declare -A name[[n]] makes name an associative array variable. */ + if (flags_on & att_assoc!()) != 0 { + if assoc_p(var) == 0 { + var = convert_var_to_assoc(var); + } + } else if (making_array_special != 0 || (flags_on & att_array!()) != 0) + && array_p(var) == 0 + && assoc_p(var) == 0 + { + /* declare -a name[[n]] or declare name[n] makes name an indexed + array variable. */ + var = convert_var_to_array(var); + } + + /* XXX - we note that we are turning on nameref attribute and defer + setting it until the assignment has been made so we don't do an + inadvertent nameref lookup. Might have to do the same thing for + flags_off&att_nameref. */ + /* XXX - ksh93 makes it an error to set a readonly nameref variable + using a single typeset command. */ + onref = flags_on & att_nameref!(); + flags_on &= !att_nameref!(); + + if array_p(var) != 0 + || assoc_p(var) != 0 + || (offset != 0 && compound_array_assign != 0) + || simple_array_assign != 0 + { + onref = 0; /* array variables may not be namerefs */ + } + /* ksh93 seems to do this */ + offref = flags_off & att_nameref!(); + flags_off &= !att_nameref!(); + + VSETATTR(var, flags_on); + VUNSETATTR(var, flags_off); + + if offset != 0 && compound_array_assign != 0 { + assign_array_var_from_string(var, value, aflags | ASS_FORCE!()); + } else if simple_array_assign != 0 && subscript_start != std::ptr::null_mut() { + let mut local_aflags: i32; + /* declare [-aA] name[N]=value */ + *subscript_start = '[' as libc::c_char; /* ] */ + /* XXX - problem here with appending */ + local_aflags = aflags & ASS_APPEND!(); + if assoc_noexpand { + local_aflags |= ASS_NOEXPAND!(); + } else { + local_aflags |= 0; + } + + var = assign_array_element(name, value, local_aflags); /* XXX - not aflags */ + *subscript_start = '\0' as libc::c_char; + if var == std::ptr::null_mut() { + /* some kind of assignment error */ + assign_error += 1; + flags_on |= onref; + flags_off |= offref; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + } else if simple_array_assign != 0 { + /* let bind_{array,assoc}_variable take care of this. */ + if assoc_p(var) != 0 { + bind_assoc_variable( + var, + name, + savestring!(CString::new("0").unwrap().as_ptr()), + value, + aflags | ASS_FORCE!(), + ); + } else { + bind_array_variable(name, 0, value, aflags | ASS_FORCE!()); + } + } else if offset != 0 { + /* XXX - no ASS_FORCE here */ + /* bind_variable_value duplicates the essential internals of bind_variable() */ + if onref != 0 || nameref_p(var) != 0 { + aflags |= ASS_NAMEREF!(); + } + + v = bind_variable_value(var, value, aflags); + if v == std::ptr::null_mut() && (onref != 0 || nameref_p(var) != 0) { + if valid_nameref_value(value, 1) == 0 { + sh_invalidid(value); + } + + assign_error += 1; + /* XXX - unset this variable? or leave it as normal var? */ + if created_var != 0 { + if mkglobal != 0 { + delete_var((*var).name, global_variables); + } else { + delete_var((*var).name, shell_variables); + } + } + + flags_on |= onref; /* undo change from above */ + flags_off |= offref; + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + } + + /* If we found this variable in the temporary environment, as with + `var=value declare -x var', make sure it is treated identically + to `var=value export var'. Do the same for `declare -r' and + `readonly'. Preserve the attributes, except for att_tempvar. */ + /* XXX -- should this create a variable in the global scope, or + modify the local variable flags? ksh93 has it modify the + global scope. + Need to handle case like in set_var_attribute where a temporary + variable is in the same table as the function local vars. */ + if (flags_on & (att_exported!() | att_readonly!()) != 0) && tempvar_p(var) != 0 + { + let mut tv: *mut SHELL_VAR; + let mut tvalue: *mut libc::c_char = std::ptr::null_mut(); + + tv = find_tempenv_variable((*var).name); + if tv != std::ptr::null_mut() { + if var_isset(var) { + tvalue = savestring!(value_cell(var)); + } else { + tvalue = savestring!(CString::new("").unwrap().as_ptr()); + } + tv = bind_variable((*var).name, tvalue, 0); + + if tv != std::ptr::null_mut() { + (*tv).attributes |= (*var).attributes & !att_tempvar!(); + if (*tv).context > 0 { + VSETATTR(tv, att_propagate!()); + } + } + libc::free(tvalue as *mut c_void); + } + VSETATTR(var, att_propagate!()); + } + } + + /* Turn on nameref attribute we deferred above. */ + /* XXX - should we turn on the noassign attribute for consistency with + ksh93 when we turn on the nameref attribute? */ + VSETATTR(var, onref); + flags_on |= onref; + VUNSETATTR(var, offref); + flags_off |= offref; + /* Yuck. ksh93 compatibility. XXX - need to investigate more but + definitely happens when turning off nameref attribute on nameref + (see comments above). Under no circumstances allow this to turn + off readonly attribute on readonly nameref variable. */ + if refvar != std::ptr::null_mut() { + if (flags_off & att_readonly!()) != 0 { + flags_off &= !att_readonly!(); + } + VUNSETATTR(refvar, flags_off); + } + stupidly_hack_special_variables(name); + libc::free(name as *mut c_void); + list = (*list).next; + continue 'outter; + } + } + if assign_error != 0 { + return EX_BADASSIGN!(); + } else { + if any_failed == 0 { + return EXECUTION_SUCCESS!(); + } else { + return EXECUTION_FAILURE!(); + } + } + } +} diff --git a/utshell-0.5.0/src/builtins/echo.rs b/utshell-0.5.0/src/builtins/echo.rs new file mode 100644 index 00000000..ee63082d --- /dev/null +++ b/utshell-0.5.0/src/builtins/echo.rs @@ -0,0 +1,156 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::builtins::common::sh_chkwrite; +use crate::readline::clearerr; +use crate::src_common::*; + +/* System V machines already have a /bin/sh with a v9 behaviour. We +give Bash the identical behaviour for these machines so that the +existing system shells won't barf. Regrettably, the SUS v2 has +standardized the Sys V echo behavior. This variable is external +so that we can have a `shopt' variable to control it at runtime. */ + +pub static mut xpg_echo: i32 = 0; // 也有å¯èƒ½æ˜¯1 + +/* Print the words in LIST to standard output. If the first word is +`-n', then don't print a trailing newline. We also support the +echo syntax from Version 9 Unix systems. */ + +#[no_mangle] +pub fn echo_builtin(mut list: *mut WordList) -> i32 { + let mut display_return: i32; + let mut do_v9: i32; + let mut i: i32; + let mut len: i32; + let mut temp: *mut libc::c_char = std::ptr::null_mut(); + let mut s: *mut libc::c_char; + + unsafe { + do_v9 = xpg_echo; + display_return = 1; + + // if posixly_correct!=0 && xpg_echo!=0{ //xpg_echo=0,所以这个å¯èƒ½ä¸ç”¨ç¿»è¯‘ + + // } + if !list.is_null() + && (*list).word != std::ptr::null_mut() + && (*(*list).word).word != std::ptr::null_mut() + { + temp = (*(*list).word).word; + } + while !list.is_null() && *temp == '-' as libc::c_char { + /* If it appears that we are handling options, then make sure that + all of the options specified are actually valid. Otherwise, the + string should just be echoed. */ + + temp = (temp as usize + 1) as *mut libc::c_char; + let mut t = temp; + i = 0; + + while *temp as i32 != 0 { + let s = *temp as i32; + let su8 = s as u8; + let s_opt = char::from(su8); + + if strchr(VALID_ECHO_OPTIONS!(), s_opt as libc::c_int).is_null() { + break; + } + + temp = (temp as usize + 1) as *mut libc::c_char; + i += 1; + } + // + /* echo - and echo - both mean to just echo the arguments. */ + if *t == 0 || *((t as usize + i as usize) as *mut libc::c_char) != 0 { + break; + } + + /* All of the options in TEMP are valid options to ECHO. + Handle them. */ + while !t.is_null() { + let optu8 = *t as u8; + let opt_char = char::from(optu8); + + match opt_char { + 'n' => { + display_return = 0; + } + 'e' => { + do_v9 = 1; + } + 'E' => { + do_v9 = 0; + } + _ => break, + } + t = (t as usize + 1) as *mut libc::c_char; + } + + list = (*list).next; + if !(*(*list).word).word.is_null() { + temp = (*(*list).word).word; + } + } + + clearerr(stdout); /* clear error before writing and testing success */ + + while list != std::ptr::null_mut() { + i = 0; + len = 0; + + if do_v9 != 0 { + temp = ansicstr( + (*(*list).word).word, + STRLEN!((*(*list).word).word), + 1, + &mut i, + &mut len, + ); + } else { + temp = (*(*list).word).word; + } + + if temp != std::ptr::null_mut() { + if do_v9 != 0 { + s = temp; + + for _ in 0..len { + putchar(*s as libc::c_int); + s = (s as usize + 1) as *mut libc::c_char; + } + } else { + fprintf(stdout, temp); + } + } + + QUIT!(); + if do_v9 != 0 && temp != std::ptr::null_mut() { + free(temp as *mut c_void); + } + + list = (*list).next; + if i != 0 { + display_return = 0; + break; + } + + if list != std::ptr::null_mut() { + putchar(' ' as i32); + QUIT!(); + } + } //while + + if display_return != 0 { + putchar('\n' as i32); + } + + return sh_chkwrite(EXECUTION_SUCCESS!()); + } //unsafe +} diff --git a/utshell-0.5.0/src/builtins/enable.rs b/utshell-0.5.0/src/builtins/enable.rs new file mode 100644 index 00000000..82475c51 --- /dev/null +++ b/utshell-0.5.0/src/builtins/enable.rs @@ -0,0 +1,543 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::findcmd::find_in_path; +use crate::general::{absolute_program, printable_filename}; +use crate::pcomplete::{it_builtins, it_disabled, it_enabled, set_itemlist_dirty}; +use crate::src_common::*; +use crate::variables::get_string_value; + +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + builtins::{num_shell_builtins, shell_builtins, static_shell_builtins}, + cmd::{insert_empty_cmd, set_cmd_enable}, + common::{ + builtin_address_internal, builtin_usage, initialize_shell_builtins, sh_notbuiltin, + sh_restricted, + }, + help::builtin_help, +}; + +#[no_mangle] +pub fn enable_builtin(mut list: *mut WordList) -> i32 { + let mut result: i32 = 0; + let mut flags: i32 = 0; + let mut opt: i32 = 0; + let mut filter: i32 = 0; + let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; + reset_internal_getopt(); + let adnpsf = CString::new("adnpsf").expect("CString::new failed"); + loop { + opt = internal_getopt(list, adnpsf.as_ptr() as *mut libc::c_char); + if !(opt != -1) { + break; + } + let opt_char = opt as u8 as char; + match opt_char { + 'a' => { + flags |= AFLAG; + } + 'n' => { + flags |= NFLAG; + } + 'p' => { + flags |= PFLAG; + } + 's' => { + flags |= SFLAG; + } + 'f' => { + flags |= FFLAG; + filename = unsafe { list_optarg }; + } + 'd' => { + flags |= DFLAG; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + } + unsafe { + list = loptend; + } + // 如果是严格模å¼ï¼Œå°±ç›´æŽ¥è¿”回EXECUTION_FAILURE,命令结æŸã€‚ + if unsafe { restricted != 0 && flags & (FFLAG | DFLAG) != 0 } { + sh_restricted(0 as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + + // é…ç½®filter,通过flagå’ŒPFLAG,åŽè€…表示打å°ï¼Œ + // 如果命令传入ä¸å¸¦é€‰é¡¹ï¼Œæˆ–者带-P + // 则打å°enableå’Œdisable的集åˆï¼› + // å¦åˆ™åˆ¤æ–­æ˜¯å¦å¸¦-N + // 带则打å°DISABLED的,ä¸å¸¦â€”N则打å°ENABLEDçš„ + if list.is_null() || flags & PFLAG != 0 { + filter = if flags & AFLAG != 0 { + ENABLED | DISABLED + } else if flags & NFLAG != 0 { + DISABLED + } else { + ENABLED + }; + + if flags & SFLAG != 0 { + filter |= SPECIAL; + } + + list_some_builtins(filter); + } else if flags & FFLAG != 0 { + // 如果ä¸å¸¦-Næˆ–è€…å‚æ•°ä¸ä¸ºç©º,那么判断-F.(bashæºæ–‡ä»¶ä¸­åˆ¤æ–­HAVE_DLSYM,HAVE_DLOPEN两个å®å­˜åœ¨) + // -FåŽé¢éœ€è¦åŠ æ–‡ä»¶å,载入so,作为内建命令 + + //判断是ENABLED还是DISABLED + filter = if flags & NFLAG != 0 { + DISABLED + } else { + ENABLED + }; + + // 判断是å¦è®¾ç½®SPECIALæ ‡å¿—ä½ + if flags & SFLAG != 0 { + filter |= SPECIAL; + } + + //载入so + result = dyn_load_builtin(list, filter, filename); + + // 设置完æˆï¼Œbashæºä»£ç ä¸­åˆ¤æ–­PROGRAMMABLE_COMPLETION + unsafe { + set_itemlist_dirty(&mut it_builtins); + } + } else if flags & DFLAG != 0 { + // å¦åˆ™åˆ¤æ–­-D,-Då«ä¹‰æ˜¯åˆ é™¤ä»¥ -f 选项加载的内建 + while !list.is_null() { + opt = unsafe { dyn_unload_builtin((*(*list).word).word) }; + if opt == EXECUTION_FAILURE!() { + result = EXECUTION_FAILURE!(); + } + unsafe { + list = (*list).next; + } + } + unsafe { + set_itemlist_dirty(&mut it_builtins); + } + } else { + // ä¸å¸¦-N -F -D,且选项ä¸ä¸ºç©ºçš„å…¶ä»– + while !list.is_null() { + unsafe { + opt = enable_shell_command((*(*list).word).word, flags & NFLAG); + if opt == EXECUTION_FAILURE!() { + sh_notbuiltin((*(*list).word).word); + result = EXECUTION_FAILURE!(); + } + list = (*list).next; + } + } + } + return result; +} + +//ä»…ä»…-p的时候会调用,打å°ï¼Œfilter决定是enable,disable +fn list_some_builtins(mut filter: libc::c_int) { + let mut i: i32 = 0; + unsafe { + while i < num_shell_builtins { + let tmpIter = *shell_builtins.offset(i as isize); + if !(tmpIter.function.is_none() || tmpIter.flags & BUILTIN_DELETED != 0) { + if !(filter & SPECIAL != 0 + && (*shell_builtins.offset(i as isize)).flags & SPECIAL_BUILTIN == 0) + { + if filter & ENABLED != 0 + && (*shell_builtins.offset(i as isize)).flags & BUILTIN_ENABLED != 0 + { + let name = CStr::from_ptr((*shell_builtins.offset(i as isize)).name); + println!("enable {}", name.to_str().expect("name cannot trans")); + } else if filter & DISABLED != 0 + && (*shell_builtins.offset(i as isize)).flags & BUILTIN_ENABLED + == 0 as libc::c_int + { + let name = CStr::from_ptr((*shell_builtins.offset(i as isize)).name); + println!("enable -n {}", name.to_str().expect("name cannot trans")); + } + } + } + i += 1; + } + } +} +fn enable_shell_command(mut name: *mut libc::c_char, mut disable_p: libc::c_int) -> libc::c_int { + let mut b: *mut builtin = 0 as *mut builtin; + b = builtin_address_internal(name, 1); + if b.is_null() { + return EXECUTION_FAILURE!(); + } + unsafe { + if disable_p != 0 { + (*b).flags &= !(BUILTIN_ENABLED); + if !set_cmd_enable(CStr::from_ptr(name).to_string_lossy().into_owned(), false) { + insert_empty_cmd(CStr::from_ptr(name).to_string_lossy().into_owned()); + set_cmd_enable(CStr::from_ptr(name).to_string_lossy().into_owned(), false); + //get_cmd_enable(CStr::from_ptr(name).to_string_lossy().into_owned()); + } + } else if restricted != 0 && (*b).flags & BUILTIN_ENABLED == 0 { + sh_restricted(0 as *mut libc::c_void as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } else { + (*b).flags |= BUILTIN_ENABLED; + if !set_cmd_enable(CStr::from_ptr(name).to_string_lossy().into_owned(), true) { + insert_empty_cmd(CStr::from_ptr(name).to_string_lossy().into_owned()); + set_cmd_enable(CStr::from_ptr(name).to_string_lossy().into_owned(), true); + } + } + set_itemlist_dirty(&mut it_enabled); + set_itemlist_dirty(&mut it_disabled); + return EXECUTION_SUCCESS!(); + } +} +fn dyn_load_builtin( + mut list: *mut WordList, + mut flags: libc::c_int, + mut filename: *mut libc::c_char, +) -> libc::c_int { + unsafe { + let mut l: *mut WordList = 0 as *mut WordList; + let mut handle: *mut libc::c_void = 0 as *mut libc::c_void; + let mut total: libc::c_int = 0; + let mut size: libc::c_int = 0; + let mut new: libc::c_int = 0; + let mut replaced: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut struct_name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut funcname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut loadfunc: sh_load_func_t = None; + let mut new_builtins: *mut *mut builtin = 0 as *mut *mut builtin; + let mut b: *mut builtin = 0 as *mut builtin; + let mut new_shell_builtins: *mut builtin = 0 as *mut builtin; + let mut old_builtin: *mut builtin = 0 as *mut builtin; + let mut loadables_path: *mut libc::c_char = 0 as *mut libc::c_char; + let mut load_path: *mut libc::c_char = 0 as *mut libc::c_char; + if list.is_null() { + return 1 as libc::c_int; + } + handle = 0 as *mut libc::c_void; + if absolute_program(filename) == 0 as libc::c_int { + loadables_path = + get_string_value(b"BASH_LOADABLES_PATH\0" as *const u8 as *const libc::c_char); + if !loadables_path.is_null() { + load_path = find_in_path( + filename, + loadables_path, + 0x20 as libc::c_int | 0x4 as libc::c_int, + ); + if !load_path.is_null() { + handle = dlopen(load_path, 0x1 as libc::c_int); + free(load_path as *mut libc::c_void); + } + } + } + if handle.is_null() { + handle = dlopen(filename, 0x1 as libc::c_int); + } + if handle.is_null() { + name = printable_filename(filename, 0 as libc::c_int); + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot open shared object %s: %s\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + dlerror(), + ); + if name != filename { + free(name as *mut libc::c_void); + } + return 1 as libc::c_int; + } + new = 0 as libc::c_int; + l = list; + while !l.is_null() { + l = (*l).next; + new += 1; + } + new_builtins = libc::malloc( + (new as usize).wrapping_mul(::std::mem::size_of::<*mut builtin>() as usize), + ) as *mut *mut builtin; + let mut current_block_57: u64; + new = 0 as libc::c_int; + replaced = new; + while !list.is_null() { + name = (*(*list).word).word; + size = strlen(name) as libc::c_int; + struct_name = libc::malloc((size + 8 as libc::c_int) as usize) as *mut libc::c_char; + strcpy(struct_name, name); + strcpy( + struct_name.offset(size as isize), + b"_struct\0" as *const u8 as *const libc::c_char, + ); + old_builtin = builtin_address_internal(name, 1 as libc::c_int); + b = dlsym(handle, struct_name) as *mut builtin; + if b.is_null() { + name = printable_filename(filename, 0 as libc::c_int); + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot find %s in shared object %s: %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + struct_name, + name, + dlerror(), + ); + if name != filename { + free(name as *mut libc::c_void); + } + free(struct_name as *mut libc::c_void); + } else { + funcname = libc::realloc( + struct_name as *mut libc::c_void, + (size as usize) + .wrapping_add(::std::mem::size_of::<[libc::c_char; 14]>() as usize) + .wrapping_add(1 as libc::c_int as usize), + ) as *mut libc::c_char; + strcpy(funcname, name); + strcpy( + funcname.offset(size as isize), + b"_builtin_load\0" as *const u8 as *const libc::c_char, + ); + loadfunc = ::std::mem::transmute::<*mut libc::c_void, sh_load_func_t>(dlsym( + handle, funcname, + )); + if loadfunc.is_some() { + if !old_builtin.is_null() + && (*old_builtin).flags & 0x4 as libc::c_int == 0 as libc::c_int + { + builtin_warning( + dcgettext( + 0 as *const libc::c_char, + b"%s: dynamic builtin already loaded\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + } + r = (Some(loadfunc.expect("non-null function pointer"))) + .expect("non-null function pointer")(name); + if r == 0 as libc::c_int { + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"load function for %s returns failure (%d): not loaded\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + r, + ); + free(funcname as *mut libc::c_void); + current_block_57 = 15345278821338558188; + } else { + current_block_57 = 7990025728955927862; + } + } else { + current_block_57 = 7990025728955927862; + } + match current_block_57 { + 15345278821338558188 => {} + _ => { + free(funcname as *mut libc::c_void); + (*b).flags &= !(0x4 as libc::c_int); + if flags & 4 as libc::c_int != 0 { + (*b).flags |= 0x8 as libc::c_int; + } + let ref mut fresh0 = (*b).handle; + *fresh0 = handle as *mut libc::c_char; + if !old_builtin.is_null() { + replaced += 1; + libc::memcpy( + old_builtin as *mut libc::c_char as *mut libc::c_void, + b as *mut libc::c_char as *const libc::c_void, + ::std::mem::size_of::() as libc::c_ulong as libc::size_t, + ); + } else { + let fresh1 = new; + new = new + 1; + let ref mut fresh2 = *new_builtins.offset(fresh1 as isize); + *fresh2 = b; + } + } + } + } + list = (*list).next; + } + if replaced == 0 as libc::c_int && new == 0 as libc::c_int { + free(new_builtins as *mut libc::c_void); + dlclose(handle); + return 1 as libc::c_int; + } + if new != 0 { + total = num_shell_builtins + new; + size = ((total + 1 as libc::c_int) as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as libc::c_int; + new_shell_builtins = libc::malloc(size as usize) as *mut builtin; + libc::memcpy( + new_shell_builtins as *mut libc::c_char as *mut libc::c_void, + shell_builtins as *mut libc::c_char as *const libc::c_void, + (num_shell_builtins as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as libc::size_t, + ); + replaced = 0 as libc::c_int; + while replaced < new { + libc::memcpy( + &mut *new_shell_builtins.offset((num_shell_builtins + replaced) as isize) + as *mut builtin as *mut libc::c_char + as *mut libc::c_void, + *new_builtins.offset(replaced as isize) as *mut libc::c_char + as *const libc::c_void, + ::std::mem::size_of::() as libc::c_ulong as libc::size_t, + ); + replaced += 1; + } + let ref mut fresh3 = (*new_shell_builtins.offset(total as isize)).name; + *fresh3 = 0 as *mut libc::c_char; + let ref mut fresh4 = (*new_shell_builtins.offset(total as isize)).function; + *fresh4 = None; + (*new_shell_builtins.offset(total as isize)).flags = 0 as libc::c_int; + if shell_builtins != static_shell_builtins.as_mut_ptr() { + free(shell_builtins as *mut libc::c_void); + } + shell_builtins = new_shell_builtins; + num_shell_builtins = total; + initialize_shell_builtins(); + } + free(new_builtins as *mut libc::c_void); + return 0 as libc::c_int; + } +} +fn delete_builtin(mut b: *mut builtin) { + let mut ind: libc::c_int = 0; + let mut size: libc::c_int = 0; + let mut new_shell_builtins: *mut builtin = 0 as *mut builtin; + unsafe { + ind = b.offset_from(shell_builtins) as libc::c_long as libc::c_int; + size = (num_shell_builtins as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as libc::c_int; + new_shell_builtins = libc::malloc(size as usize) as *mut builtin; + if ind != 0 { + libc::memcpy( + new_shell_builtins as *mut libc::c_char as *mut libc::c_void, + shell_builtins as *mut libc::c_char as *const libc::c_void, + (ind as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as libc::size_t, + ); + } + libc::memcpy( + &mut *new_shell_builtins.offset(ind as isize) as *mut builtin as *mut libc::c_char + as *mut libc::c_void, + &mut *shell_builtins.offset((ind + 1 as libc::c_int) as isize) as *mut builtin + as *mut libc::c_char as *const libc::c_void, + ((num_shell_builtins - ind) as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as libc::size_t, + ); + if shell_builtins != static_shell_builtins.as_mut_ptr() { + free(shell_builtins as *mut libc::c_void); + } + num_shell_builtins -= 1; + shell_builtins = new_shell_builtins; + } +} +fn local_dlclose(mut handle: *mut libc::c_void) -> libc::c_int { + unsafe { + return dlclose(handle); + } +} +fn dyn_unload_builtin(mut name: *mut libc::c_char) -> libc::c_int { + let mut b: *mut builtin = 0 as *mut builtin; + let mut handle: *mut libc::c_void = 0 as *mut libc::c_void; + let mut funcname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut unloadfunc: sh_unload_func_t = None; + let mut ref_0: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut size: libc::c_int = 0; + b = builtin_address_internal(name, 1 as libc::c_int); + if b.is_null() { + sh_notbuiltin(name); + return 1 as libc::c_int; + } + unsafe { + if (*b).flags & 0x4 as libc::c_int != 0 { + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: not dynamically loaded\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + return 1 as libc::c_int; + } + handle = (*b).handle as *mut libc::c_void; + i = 0 as libc::c_int; + ref_0 = i; + while i < num_shell_builtins { + if (*shell_builtins.offset(i as isize)).handle == (*b).handle { + ref_0 += 1; + } + i += 1; + } + size = strlen(name) as libc::c_int; + funcname = libc::malloc( + (size as usize) + .wrapping_add(::std::mem::size_of::<[libc::c_char; 16]>() as usize) + .wrapping_add(1 as libc::c_int as usize), + ) as *mut libc::c_char; + strcpy(funcname, name); + strcpy( + funcname.offset(size as isize), + b"_builtin_unload\0" as *const u8 as *const libc::c_char, + ); + unloadfunc = + ::std::mem::transmute::<*mut libc::c_void, sh_unload_func_t>(dlsym(handle, funcname)); + if unloadfunc.is_some() { + (Some(unloadfunc.expect("non-null function pointer"))) + .expect("no-null function pointer")(name); + } + free(funcname as *mut libc::c_void); + if ref_0 == 1 as libc::c_int && local_dlclose(handle) != 0 as libc::c_int { + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot delete: %s\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + dlerror(), + ); + return 1 as libc::c_int; + } + delete_builtin(b); + return 0 as libc::c_int; + } +} diff --git a/utshell-0.5.0/src/builtins/eval.rs b/utshell-0.5.0/src/builtins/eval.rs new file mode 100644 index 00000000..4ab4cc84 --- /dev/null +++ b/utshell-0.5.0/src/builtins/eval.rs @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use std::ffi::CString; + +use crate::src_common::*; +use crate::subst::string_list; + +use crate::builtins::{common::no_options, evalstring::evalstring}; + +#[no_mangle] +pub fn eval_builtin(mut list: *mut WordList) -> i32 { + if no_options(list) != 0 { + return EX_USAGE!(); + } + + list = unsafe { loptend }; + + if !list.is_null() { + let c_str = CString::new("eval").unwrap(); + let c_ptr = c_str.as_ptr(); + return unsafe { evalstring(string_list(list), c_ptr, SEVAL_NOHIST!()) }; + } else { + return EXECUTION_SUCCESS!(); + } +} diff --git a/utshell-0.5.0/src/builtins/evalfile.rs b/utshell-0.5.0/src/builtins/evalfile.rs new file mode 100644 index 00000000..2146f443 --- /dev/null +++ b/utshell-0.5.0/src/builtins/evalfile.rs @@ -0,0 +1,552 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use libc::{__errno_location, close, free, malloc, memmove, open, read, strlen}; + +use crate::array::{array_dispose_element, array_rshift, array_shift}; +use crate::builtins::evalstring::{parse_and_execute, parse_and_execute_cleanup}; +use crate::error::file_error; +use crate::execute_cmd::{executing_line_number, restore_funcarray_state}; +use crate::general::{bash_tilde_expand, check_binary_file}; +use crate::sig::jump_to_top_level; +use crate::src_common::*; +use crate::stringlib::xbcopy; +use crate::trap::run_return_trap; +use crate::unwind_prot::{ + add_unwind_protect, begin_unwind_frame, run_unwind_frame, unwind_protect_mem, +}; +use crate::variables::{find_variable, init_bash_argv, pop_args}; +use crate::version::shell_compatibility_level; +use crate::y_tab::{current_token, push_token}; + +#[inline] +fn fstat(mut __fd: libc::c_int, mut __statbuf: *mut crate::src_common::stat) -> libc::c_int { + return unsafe { __fxstat(1 as libc::c_int, __fd, __statbuf) }; +} +#[no_mangle] +pub static mut sourcelevel: libc::c_int = 0 as libc::c_int; +fn evalfile(mut filename: *const libc::c_char, mut flags: libc::c_int) -> libc::c_int { + unsafe { + let mut old_interactive: libc::c_int = 0; + let mut old_return_catch: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, + }; 1]; + let mut return_val: libc::c_int = 0; + let mut fd: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut nnull: libc::c_int = 0; + let mut nr: ssize_t = 0; + let mut string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut file_size: size_t = 0; + let mut errfunc: sh_vmsg_func_t = None; + let mut funcname_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_source_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_lineno_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut funcname_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_source_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_lineno_a: *mut ARRAY = 0 as *mut ARRAY; + let mut fa: *mut func_array_state = 0 as *mut func_array_state; + let mut bash_argv_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_argc_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_argv_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_argc_a: *mut ARRAY = 0 as *mut ARRAY; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tt: [libc::c_char; 2] = [0; 2]; + funcname_v = find_variable(b"FUNCNAME\0" as *const u8 as *const libc::c_char); + funcname_a = if !funcname_v.is_null() + && (*funcname_v).attributes & FEVAL_UNWINDPROT!() as libc::c_int != 0 + { + (*funcname_v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + bash_source_v = find_variable(b"BASH_SOURCE\0" as *const u8 as *const libc::c_char); + bash_source_a = if !bash_source_v.is_null() + && (*bash_source_v).attributes & FEVAL_UNWINDPROT!() as libc::c_int != 0 + { + (*bash_source_v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + bash_lineno_v = find_variable(b"BASH_LINENO\0" as *const u8 as *const libc::c_char); + bash_lineno_a = if !bash_lineno_v.is_null() + && (*bash_lineno_v).attributes & FEVAL_UNWINDPROT!() as libc::c_int != 0 + { + (*bash_lineno_v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + bash_argv_v = find_variable(b"BASH_ARGV\0" as *const u8 as *const libc::c_char); + bash_argv_a = if !bash_argv_v.is_null() + && (*bash_argv_v).attributes & FEVAL_UNWINDPROT!() as libc::c_int != 0 + { + (*bash_argv_v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + bash_argc_v = find_variable(b"BASH_ARGC\0" as *const u8 as *const libc::c_char); + bash_argc_a = if !bash_argc_v.is_null() + && (*bash_argc_v).attributes & FEVAL_UNWINDPROT!() as libc::c_int != 0 + { + (*bash_argc_v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + + fd = open(filename, 0 as libc::c_int); + if fd < 0 as libc::c_int || fstat(fd, &mut finfo) == -(1 as libc::c_int) { + i = *__errno_location(); + if fd >= 0 as libc::c_int { + close(fd); + } + *__errno_location() = i; + if flags & FEVAL_ENOENTOK!() as libc::c_int == 0 as libc::c_int + || *__errno_location() != 2 as libc::c_int + { + file_error(filename); + } + if flags & FEVAL_LONGJMP!() as libc::c_int != 0 { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + jump_to_top_level(3 as libc::c_int); + } + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 1 as libc::c_int + } else if *__errno_location() == 2 as libc::c_int + && flags & FEVAL_ENOENTOK!() as libc::c_int != 0 as libc::c_int + { + 0 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } else { + errfunc = if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + Some(builtin_error) + } else { + Some(internal_error) + }; + if finfo.st_mode & __S_IFMT!() as libc::c_int as libc::c_uint + == __S_IFDIR!() as libc::c_int as libc::c_uint + { + (Some(errfunc.expect("non-null function pointer"))) + .expect("non-null function pointer")( + dcgettext( + 0 as *const libc::c_char, + b"%s: is a directory\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + close(fd); + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 1 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } else { + if flags & FEVAL_REGFILE!() as libc::c_int != 0 + && (finfo.st_mode & __S_IFMT!() as libc::c_int as libc::c_uint + == __S_IFREG!() as libc::c_int as libc::c_uint) + as libc::c_int + == 0 as libc::c_int + { + (Some(errfunc.expect("non-null function pointer"))) + .expect("non-null function pointer")( + dcgettext( + 0 as *const libc::c_char, + b"%s: not a regular file\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + close(fd); + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 1 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } + } + file_size = finfo.st_size as size_t; + if file_size != finfo.st_size as libc::c_ulong + || file_size.wrapping_add(1 as libc::c_int as libc::c_ulong) < file_size + { + (Some(errfunc.expect("non-null function pointer"))) + .expect("non-null function pointer")( + dcgettext( + 0 as *const libc::c_char, + b"%s: file is too large\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + close(fd); + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 1 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } + if finfo.st_mode & __S_IFMT!() as libc::c_int as libc::c_uint + == __S_IFREG!() as libc::c_int as libc::c_uint + && file_size <= SSIZE_MAX!() as libc::c_long as libc::c_ulong + { + string = malloc((1 as libc::c_int as libc::c_ulong).wrapping_add(file_size) as usize) + as *mut libc::c_char; + nr = read(fd, string as *mut libc::c_void, file_size as usize) as ssize_t; + if nr >= 0 as libc::c_int as libc::c_long { + *string.offset(nr as isize) = '\u{0}' as i32 as libc::c_char; + } + } else { + nr = zmapfd(fd, &mut string, 0 as *mut libc::c_char) as ssize_t; + } + return_val = *__errno_location(); + close(fd); + *__errno_location() = return_val; + if nr < 0 as libc::c_int as libc::c_long { + free(string as *mut libc::c_void); + if flags & FEVAL_ENOENTOK!() as libc::c_int == 0 as libc::c_int + || *__errno_location() != 2 as libc::c_int + { + file_error(filename); + } + if flags & FEVAL_LONGJMP!() as libc::c_int != 0 { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + jump_to_top_level(3 as libc::c_int); + } + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 1 as libc::c_int + } else if *__errno_location() == 2 as libc::c_int + && flags & FEVAL_ENOENTOK!() as libc::c_int != 0 as libc::c_int + { + 0 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } else { + if nr == 0 as libc::c_int as libc::c_long { + free(string as *mut libc::c_void); + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 0 as libc::c_int + } else { + 1 as libc::c_int + }; + } + if flags & FEVAL_CHECKBINARY!() as libc::c_int != 0 + && check_binary_file( + string, + (if nr > 80 as libc::c_int as libc::c_long { + 80 as libc::c_int as libc::c_long + } else { + nr + }) as libc::c_int, + ) != 0 + { + free(string as *mut libc::c_void); + (Some(errfunc.expect("non-null function pointer"))) + .expect("non-null function pointer")( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot execute binary file\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 126 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } + i = strlen(string) as libc::c_int; + if (i as libc::c_long) < nr { + i = 0 as libc::c_int; + nnull = i; + while (i as libc::c_long) < nr { + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + memmove( + string.offset(i as isize) as *mut libc::c_void, + string.offset(i as isize).offset(1 as libc::c_int as isize) + as *const libc::c_void, + ((nr - i as libc::c_long) as usize), + ); + nr -= 1; + if flags & FEVAL_BUILTIN!() as libc::c_int != 0 && { + nnull += 1; + nnull > 256 as libc::c_int + } { + free(string as *mut libc::c_void); + (Some(errfunc.expect("non-null function pointer"))) + .expect("non-null function pointer")( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot execute binary file\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + 126 as libc::c_int + } else { + -(1 as libc::c_int) + }; + } + } + i += 1; + } + } + if flags & FEVAL_UNWINDPROT!() as libc::c_int != 0 { + begin_unwind_frame( + b"evalfile\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + unwind_protect_mem( + &mut return_catch_flag as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut return_catch as *mut sigjmp_buf as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + if flags & FEVAL_NONINT!() as libc::c_int != 0 { + unwind_protect_mem( + &mut interactive as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + } + unwind_protect_mem( + &mut sourcelevel as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + } else { + xbcopy( + return_catch.as_mut_ptr() as *mut libc::c_char, + old_return_catch.as_mut_ptr() as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + if flags & FEVAL_NONINT!() as libc::c_int != 0 { + ::std::ptr::write_volatile( + &mut old_interactive as *mut libc::c_int, + interactive, + ); + } + } + if flags & FEVAL_NONINT!() as libc::c_int != 0 { + interactive = 0 as libc::c_int; + } + return_catch_flag += 1; + sourcelevel += 1; + array_rshift( + bash_source_a, + 1 as libc::c_int, + filename as *mut libc::c_char, + ); + t = itos(executing_line_number() as intmax_t); + array_rshift(bash_lineno_a, 1 as libc::c_int, t); + free(t as *mut libc::c_void); + array_rshift( + funcname_a, + 1 as libc::c_int, + b"source\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + fa = malloc((::std::mem::size_of::() as usize)) + as *mut func_array_state; + let ref mut fresh0 = (*fa).source_a; + *fresh0 = bash_source_a; + let ref mut fresh1 = (*fa).source_v; + *fresh1 = bash_source_v; + let ref mut fresh2 = (*fa).lineno_a; + *fresh2 = bash_lineno_a; + let ref mut fresh3 = (*fa).lineno_v; + *fresh3 = bash_lineno_v; + let ref mut fresh4 = (*fa).funcname_a; + *fresh4 = funcname_a; + let ref mut fresh5 = (*fa).funcname_v; + *fresh5 = funcname_v; + // let rfs: Option = Some(restore_funcarray_state); + if flags & FEVAL_UNWINDPROT!() as libc::c_int != 0 { + add_unwind_protect( + std::mem::transmute:: (), Option>( + restore_funcarray_state, + ), + fa as *mut libc::c_char, + ); + } + if flags & FEVAL_NOPUSHARGS!() as libc::c_int == 0 as libc::c_int { + if shell_compatibility_level <= 44 as libc::c_int { + init_bash_argv(); + } + array_rshift(bash_argv_a, 1 as libc::c_int, filename as *mut libc::c_char); + tt[0 as libc::c_int as usize] = '1' as i32 as libc::c_char; + tt[1 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + array_rshift(bash_argc_a, 1 as libc::c_int, tt.as_mut_ptr()); + // let pa: Functions = Functions { pop_args }; + if flags & FEVAL_UNWINDPROT!() as libc::c_int != 0 { + add_unwind_protect( + std::mem::transmute::>(pop_args), + 0 as *mut libc::c_char, + ); + } + } + pflags = FEVAL_LONGJMP!() as libc::c_int; + pflags |= if flags & FEVAL_HISTORY!() as libc::c_int != 0 { + 0 as libc::c_int + } else { + FEVAL_UNWINDPROT!() as libc::c_int + }; + if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + result = 0 as libc::c_int; + } + return_val = __sigsetjmp(return_catch.as_mut_ptr(), 0 as libc::c_int); //问题 + if return_val != 0 { + parse_and_execute_cleanup(-(1 as libc::c_int)); + result = return_catch_value; + } else { + result = parse_and_execute(string, filename, pflags); + } + if flags & FEVAL_UNWINDPROT!() as libc::c_int != 0 { + run_unwind_frame( + b"evalfile\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else { + if flags & FEVAL_NONINT!() as libc::c_int != 0 { + interactive = old_interactive; + } + restore_funcarray_state(fa); + if flags & FEVAL_NOPUSHARGS!() as libc::c_int == 0 as libc::c_int { + array_dispose_element(array_shift( + bash_argc_a, + 1 as libc::c_int, + 0 as libc::c_int, + )); + array_dispose_element(array_shift( + bash_argv_a, + 1 as libc::c_int, + 0 as libc::c_int, + )); + } + return_catch_flag -= 1; + sourcelevel -= 1; + xbcopy( + old_return_catch.as_mut_ptr() as *mut libc::c_char, + return_catch.as_mut_ptr() as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + } + if current_token == yacc_EOF!() as libc::c_int { + push_token('\n' as i32); + } + return if flags & FEVAL_BUILTIN!() as libc::c_int != 0 { + result + } else { + 1 as libc::c_int + }; + } + } + } +} +#[no_mangle] +pub fn maybe_execute_file( + mut fname: *const libc::c_char, + mut force_noninteractive: libc::c_int, +) -> libc::c_int { + unsafe { + let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: libc::c_int = 0; + let mut flags: libc::c_int = 0; + filename = bash_tilde_expand(fname, 0 as libc::c_int); + flags = FEVAL_ENOENTOK!() as libc::c_int; + if force_noninteractive != 0 { + flags |= FEVAL_NONINT!() as libc::c_int; + } + result = evalfile(filename, flags); + free(filename as *mut libc::c_void); + return result; + } +} +#[no_mangle] +pub fn force_execute_file( + mut fname: *const libc::c_char, + mut force_noninteractive: libc::c_int, +) -> libc::c_int { + unsafe { + let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: libc::c_int = 0; + let mut flags: libc::c_int = 0; + filename = bash_tilde_expand(fname, 0 as libc::c_int); + flags = 0 as libc::c_int; + if force_noninteractive != 0 { + flags |= FEVAL_NONINT!() as libc::c_int; + } + result = evalfile(filename, flags); + free(filename as *mut libc::c_void); + return result; + } +} +#[no_mangle] +pub fn fc_execute_file(mut filename: *const libc::c_char) -> libc::c_int { + let mut flags: libc::c_int = 0; + flags = FEVAL_ENOENTOK!() as libc::c_int + | FEVAL_HISTORY!() as libc::c_int + | FEVAL_REGFILE!() as libc::c_int + | FEVAL_BUILTIN!() as libc::c_int; + return evalfile(filename, flags); +} +#[no_mangle] +pub fn source_file(mut filename: *const libc::c_char, mut sflags: libc::c_int) -> libc::c_int { + let mut flags: libc::c_int = 0; + let mut rval: libc::c_int = 0; + flags = FEVAL_BUILTIN!() as libc::c_int + | FEVAL_UNWINDPROT!() as libc::c_int + | FEVAL_NONINT!() as libc::c_int; + if sflags != 0 { + flags |= FEVAL_NOPUSHARGS!() as libc::c_int; + } + if unsafe { + posixly_correct != 0 + && interactive_shell == 0 as libc::c_int + && executing_command_builtin == 0 as libc::c_int + } { + flags |= FEVAL_LONGJMP!() as libc::c_int; + } + rval = evalfile(filename, flags); + run_return_trap(); + return rval; +} diff --git a/utshell-0.5.0/src/builtins/evalstring.rs b/utshell-0.5.0/src/builtins/evalstring.rs new file mode 100644 index 00000000..0ac9e0f2 --- /dev/null +++ b/utshell-0.5.0/src/builtins/evalstring.rs @@ -0,0 +1,894 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use libc::{close, free, malloc, open, strcmp, strcpy, strlen}; + +use crate::bashhist::bash_history_disable; +use crate::builtins::{eval::eval_builtin, source::source_builtin}; +use crate::dispose_cmd::dispose_command; +use crate::error::{command_error, file_error}; +use crate::eval::parse_command; +use crate::execute_cmd::{dispose_fd_bitmap, execute_command_internal, new_fd_bitmap}; +use crate::jobs::unfreeze_jobs_list; +use crate::readline::siglongjmp; +use crate::redir::{redirection_error, redirection_expand}; +use crate::sig::{jump_to_top_level, throw_to_top_level, top_level_cleanup}; +use crate::src_common::*; +use crate::trap::{any_signals_trapped, run_trap_cleanup, signal_is_trapped}; +use crate::unwind_prot::{ + add_unwind_protect, begin_unwind_frame, discard_unwind_frame, have_unwind_protects, + run_unwind_frame, unwind_protect_mem, +}; +use crate::variables::set_pipestatus_from_exit; +use crate::y_tab::{ + bash_input, clear_shell_input_line, current_token, get_current_prompt_level, line_number, + parser_expanding_alias, parser_remaining_input, parser_restore_alias, parser_save_alias, + pop_stream, push_stream, reset_parser, set_current_prompt_level, shell_eof_token, + with_input_from_string, +}; + +extern "C" { + fn sigprocmask( + __how: ::std::os::raw::c_int, + __set: *const sigset_t, + __oset: *mut sigset_t, + ) -> ::std::os::raw::c_int; + fn sigemptyset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} + +#[no_mangle] +pub static mut parse_and_execute_level: libc::c_int = 0 as libc::c_int; +fn set_history_remembering() { + unsafe { + remember_on_history = enable_history_list; + } +} +fn restore_lastcom(mut x: *mut libc::c_char) { + unsafe { + if !the_printed_command_except_trap.is_null() { + free(the_printed_command_except_trap as *mut libc::c_void); + } + the_printed_command_except_trap = x; + } +} +#[no_mangle] +pub fn should_suppress_fork(mut command: *mut COMMAND) -> libc::c_int { + unsafe { + return (startup_state == 2 as libc::c_int + && parse_and_execute_level == 1 as libc::c_int + && running_trap == 0 as libc::c_int + && *bash_input.location.string as libc::c_int == '\u{0}' as i32 + && parser_expanding_alias() == 0 as libc::c_int + && (*command).type_0 as libc::c_uint == cm_simple as libc::c_int as libc::c_uint + && signal_is_trapped(0 as libc::c_int) == 0 as libc::c_int + && signal_is_trapped(64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int) + == 0 as libc::c_int + && any_signals_trapped() < 0 as libc::c_int + && ((*command).redirects).is_null() + && ((*(*command).value.Simple).redirects).is_null() + && (*command).flags & CMD_TIME_PIPELINE!() as libc::c_int == 0 as libc::c_int + && (*command).flags & CMD_INVERT_RETURN!() as libc::c_int == 0 as libc::c_int) + as libc::c_int; + } +} +#[no_mangle] +pub fn can_optimize_connection(mut command: *mut COMMAND) -> libc::c_int { + unsafe { + return (*bash_input.location.string as libc::c_int == '\u{0}' as i32 + && parser_expanding_alias() == 0 as libc::c_int + && ((*(*command).value.Connection).connector == AND_AND!() as libc::c_int + || (*(*command).value.Connection).connector == OR_OR!() as libc::c_int + || (*(*command).value.Connection).connector == ';' as i32) + && (*(*(*command).value.Connection).second).type_0 as libc::c_uint + == cm_simple as libc::c_int as libc::c_uint) as libc::c_int; + } +} +#[no_mangle] +pub fn optimize_fork(mut command: *mut COMMAND) { + unsafe { + if (*command).type_0 as libc::c_uint == cm_connection as libc::c_int as libc::c_uint + && ((*(*command).value.Connection).connector == AND_AND!() as libc::c_int + || (*(*command).value.Connection).connector == OR_OR!() as libc::c_int + || (*(*command).value.Connection).connector == ';' as i32) + && (*(*(*command).value.Connection).second).flags & CMD_TRY_OPTIMIZING!() as libc::c_int + != 0 + && should_suppress_fork((*(*command).value.Connection).second) != 0 + { + (*(*(*command).value.Connection).second).flags |= CMD_NO_FORK!() as libc::c_int; + (*(*(*(*command).value.Connection).second).value.Simple).flags |= + CMD_NO_FORK!() as libc::c_int; + } + } +} +#[no_mangle] +pub fn optimize_subshell_command(mut command: *mut COMMAND) { + unsafe { + if running_trap == 0 as libc::c_int + && (*command).type_0 as libc::c_uint == cm_simple as libc::c_int as libc::c_uint + && signal_is_trapped(0 as libc::c_int) == 0 as libc::c_int + && signal_is_trapped(64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int) + == 0 as libc::c_int + && any_signals_trapped() < 0 as libc::c_int + && ((*command).redirects).is_null() + && ((*(*command).value.Simple).redirects).is_null() + && (*command).flags & CMD_TIME_PIPELINE!() as libc::c_int == 0 as libc::c_int + && (*command).flags & CMD_INVERT_RETURN!() as libc::c_int == 0 as libc::c_int + { + (*command).flags |= CMD_NO_FORK!() as libc::c_int; + (*(*command).value.Simple).flags |= CMD_NO_FORK!() as libc::c_int; + } else if (*command).type_0 as libc::c_uint == cm_connection as libc::c_int as libc::c_uint + && ((*(*command).value.Connection).connector == AND_AND!() as libc::c_int + || (*(*command).value.Connection).connector == OR_OR!() as libc::c_int) + { + optimize_subshell_command((*(*command).value.Connection).second); + } + } +} +#[no_mangle] +pub fn optimize_shell_function(mut command: *mut COMMAND) { + let mut fc: *mut COMMAND = 0 as *mut COMMAND; + unsafe { + fc = if (*command).type_0 as libc::c_uint == cm_group as libc::c_int as libc::c_uint { + (*(*command).value.Group).command + } else { + command + }; + if (*fc).type_0 as libc::c_uint == cm_simple as libc::c_int as libc::c_uint + && should_suppress_fork(fc) != 0 + { + (*fc).flags |= CMD_NO_FORK!() as libc::c_int; + (*(*fc).value.Simple).flags |= CMD_NO_FORK!() as libc::c_int; + } else if (*fc).type_0 as libc::c_uint == cm_connection as libc::c_int as libc::c_uint + && can_optimize_connection(fc) != 0 + && should_suppress_fork((*(*fc).value.Connection).second) != 0 + { + (*(*(*fc).value.Connection).second).flags |= CMD_NO_FORK!() as libc::c_int; + (*(*(*(*fc).value.Connection).second).value.Simple).flags |= + CMD_NO_FORK!() as libc::c_int; + } + } +} +#[no_mangle] +pub fn parse_and_execute_cleanup(mut old_running_trap: libc::c_int) { + unsafe { + if running_trap > 0 as libc::c_int { + if running_trap != old_running_trap { + run_trap_cleanup(running_trap - 1 as libc::c_int); + } + unfreeze_jobs_list(); + } + if have_unwind_protects() != 0 { + run_unwind_frame( + b"parse_and_execute top\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else { + parse_and_execute_level = 0 as libc::c_int; + }; + } +} +fn parse_prologue( + mut string: *mut libc::c_char, + mut flags: libc::c_int, + mut tag: *mut libc::c_char, +) { + let mut orig_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lastcom: *mut libc::c_char = 0 as *mut libc::c_char; + let mut x: libc::c_int = 0; + orig_string = string; + unsafe { + begin_unwind_frame(tag); + unwind_protect_mem( + &mut parse_and_execute_level as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut top_level as *mut sigjmp_buf as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut indirection_level as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut line_number as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut line_number_for_err_trap as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut loop_level as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut executing_list as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut comsub_ignore_return as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + if flags & (SEVAL_NONINT!() as libc::c_int | SEVAL_INTERACT!() as libc::c_int) != 0 { + unwind_protect_mem( + &mut interactive as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + } + if parse_and_execute_level == 0 as libc::c_int { + // let shr: Functions = Functions { + // set_history_remembering, + // }; + // add_unwind_protect(set_history_remembering, 0 as *mut libc::c_void as *mut libc::c_char); + add_unwind_protect( + std::mem::transmute::>(set_history_remembering), + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } else { + unwind_protect_mem( + &mut remember_on_history as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + } + unwind_protect_mem( + &mut history_expansion_inhibited as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + if interactive_shell != 0 { + x = get_current_prompt_level(); + // let scpl: Functions = Functions { + // set_current_prompt_level, + // }; + // add_unwind_protect(scpl, x); + add_unwind_protect( + std::mem::transmute::>( + set_current_prompt_level, + ), + x as *mut libc::c_char, + ); + } + if !the_printed_command_except_trap.is_null() { + lastcom = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(the_printed_command_except_trap) as u64) + as usize, + ) as *mut libc::c_char, + the_printed_command_except_trap, + ); + // let rl: Functions = Functions { restore_lastcom }; + // add_unwind_protect(rl, lastcom); + add_unwind_protect( + std::mem::transmute::>(restore_lastcom), + lastcom, + ); + } + // let ps: Functions = Functions { pop_stream }; + // add_unwind_protect(ps, 0 as *mut libc::c_void as *mut libc::c_char); + add_unwind_protect( + std::mem::transmute::>(pop_stream), + 0 as *mut libc::c_void as *mut libc::c_char, + ); + if parser_expanding_alias() != 0 { + // let pra: Functions = Functions { + // parser_restore_alias, + // }; + // add_unwind_protect(pra, 0 as *mut libc::c_void as *mut libc::c_char); + add_unwind_protect( + std::mem::transmute::>(parser_restore_alias), + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + if !orig_string.is_null() && flags & CMD_IGNORE_RETURN!() as libc::c_int == 0 as libc::c_int + { + // let xf: Functions = Functions { free }; + // add_unwind_protect(xf, orig_string); + add_unwind_protect( + std::mem::transmute::>(free), + orig_string, + ); + } + if flags & (SEVAL_NONINT!() as libc::c_int | SEVAL_INTERACT!() as libc::c_int) != 0 { + interactive = if flags & SEVAL_NONINT!() as libc::c_int != 0 { + 0 as libc::c_int + } else { + 1 as libc::c_int + }; + } + if flags & CMD_INVERT_RETURN!() as libc::c_int != 0 { + bash_history_disable(); + } + if flags & SEVAL_NOHISTEXP!() as libc::c_int != 0 { + history_expansion_inhibited = 1 as libc::c_int; + } + } +} +#[no_mangle] +pub fn parse_and_execute( + mut string: *mut libc::c_char, + mut from_file: *const libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + let mut code: libc::c_int = 0; + let mut lreset: libc::c_int = 0; + let mut should_jump_to_top_level: libc::c_int = 0; + let mut last_result: libc::c_int = 0; + let mut command: *mut COMMAND = 0 as *mut COMMAND; + let mut pe_sigmask: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + parse_prologue( + string, + flags, + b"parse_and_execute top\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + parse_and_execute_level += 1; + lreset = flags & SEVAL_RESETLINE!() as libc::c_int; + sigemptyset(&mut pe_sigmask as *mut sigset_t as *mut sigset_t); + sigprocmask( + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut sigset_t, + &mut pe_sigmask as *mut sigset_t as *mut sigset_t, + ); + push_stream(lreset); + if parser_expanding_alias() != 0 { + parser_save_alias(); + } + if lreset == 0 as libc::c_int { + line_number -= 1; + } + indirection_level += 1; + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 0 as libc::c_int, + ); + code = ::std::ptr::read_volatile::( + &should_jump_to_top_level as *const libc::c_int, + ); + ::std::ptr::write_volatile(&mut last_result as *mut libc::c_int, 0 as libc::c_int); + if current_token == 304 as libc::c_int { + current_token = '\n' as i32; + } + with_input_from_string(string, from_file); + clear_shell_input_line(); + while *bash_input.location.string as libc::c_int != 0 || parser_expanding_alias() != 0 { + ::std::ptr::write_volatile( + &mut command as *mut *mut COMMAND, + 0 as *mut libc::c_void as *mut COMMAND, + ); + if interrupt_state != 0 { + ::std::ptr::write_volatile(&mut last_result as *mut libc::c_int, 1 as libc::c_int); + break; + } else { + code = __sigsetjmp(top_level.as_mut_ptr(), 0 as libc::c_int); + if code != 0 { + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 0 as libc::c_int, + ); + match code { + 4 => { + if exit_immediately_on_error != 0 && variable_context != 0 { + discard_unwind_frame( + b"pe_dispose\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + variable_context = 0 as libc::c_int; + } + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 1 as libc::c_int, + ); + run_unwind_frame( + b"parse_and_execute top\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if interrupt_state != 0 && parse_and_execute_level == 0 as libc::c_int { + interactive = interactive_shell; + throw_to_top_level(); + } + if should_jump_to_top_level != 0 { + jump_to_top_level(code); + } + return last_result; + } + 1 | 3 => { + if !command.is_null() { + run_unwind_frame( + b"pe_dispose\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + } + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 1 as libc::c_int, + ); + run_unwind_frame( + b"parse_and_execute top\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if interrupt_state != 0 && parse_and_execute_level == 0 as libc::c_int { + interactive = interactive_shell; + throw_to_top_level(); + } + if should_jump_to_top_level != 0 { + jump_to_top_level(code); + } + return last_result; + } + 2 => { + if !command.is_null() { + run_unwind_frame( + b"pe_dispose\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + } + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + ::std::ptr::write_volatile( + &mut last_result as *mut libc::c_int, + ::std::ptr::read_volatile::( + &last_command_exit_value as *const libc::c_int, + ), + ); + set_pipestatus_from_exit(last_command_exit_value); + if subshell_environment != 0 { + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 1 as libc::c_int, + ); + run_unwind_frame( + b"parse_and_execute top\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if interrupt_state != 0 + && parse_and_execute_level == 0 as libc::c_int + { + interactive = interactive_shell; + throw_to_top_level(); + } + if should_jump_to_top_level != 0 { + jump_to_top_level(code); + } + return last_result; + } else { + sigprocmask( + 2 as libc::c_int, + &mut pe_sigmask as *mut sigset_t as *mut sigset_t, + 0 as *mut libc::c_void as *mut sigset_t, + ); + continue; + } + } + _ => { + command_error( + b"parse_and_execute\0" as *const u8 as *const libc::c_char, + 3 as libc::c_int, + code, + 0 as libc::c_int, + ); + } + } + } + if parse_command() == 0 as libc::c_int { + if flags & SEVAL_PARSEONLY!() as libc::c_int != 0 + || interactive_shell == 0 as libc::c_int && read_but_dont_execute != 0 + { + ::std::ptr::write_volatile( + &mut last_result as *mut libc::c_int, + 0 as libc::c_int, + ); + dispose_command(global_command); + global_command = 0 as *mut libc::c_void as *mut COMMAND; + } else { + ::std::ptr::write_volatile( + &mut command as *mut *mut COMMAND, + global_command, + ); + if (::std::ptr::read_volatile::<*mut COMMAND>( + &command as *const *mut COMMAND, + )) + .is_null() + { + continue; + } + let mut bitmap: *mut fd_bitmap = 0 as *mut fd_bitmap; + if flags & CMD_TIME_PIPELINE!() as libc::c_int != 0 { + let mut x: *mut libc::c_char = 0 as *mut libc::c_char; + if (*command).type_0 as libc::c_uint + != cm_function_def as libc::c_int as libc::c_uint + || { + x = parser_remaining_input(); + !x.is_null() && *x as libc::c_int != 0 + } + || (*from_file.offset(0 as libc::c_int as isize) as libc::c_int + == *((*(*(*command).value.Function_def).name).word) + .offset(0 as libc::c_int as isize) + as libc::c_int + && strcmp( + from_file, + (*(*(*command).value.Function_def).name).word, + ) == 0 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"%s: ignoring function definition attempt\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + from_file, + ); + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 0 as libc::c_int, + ); + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 2 as libc::c_int, + ); + ::std::ptr::write_volatile( + &mut last_result as *mut libc::c_int, + ::std::ptr::read_volatile::( + &last_command_exit_value as *const libc::c_int, + ), + ); + set_pipestatus_from_exit(last_command_exit_value); + reset_parser(); + break; + } + } + bitmap = new_fd_bitmap(32 as libc::c_int); + begin_unwind_frame( + b"pe_dispose\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + // let dfb: Functions = Functions { dispose_fd_bitmap }; + // add_unwind_protect(dfb, bitmap); + // let dc: Functions = Functions { dispose_command }; + // add_unwind_protect(dc, command); + add_unwind_protect( + std::mem::transmute::>( + dispose_fd_bitmap, + ), + bitmap as *mut libc::c_char, + ); + add_unwind_protect( + std::mem::transmute::>( + dispose_command, + ), + command as *mut libc::c_char, + ); + global_command = 0 as *mut libc::c_void as *mut COMMAND; + if subshell_environment & CMD_INVERT_RETURN!() as libc::c_int != 0 + && comsub_ignore_return != 0 + { + (*command).flags |= CMD_IGNORE_RETURN!() as libc::c_int; + } + if should_suppress_fork(command) != 0 { + (*command).flags |= CMD_NO_FORK!() as libc::c_int; + (*(*command).value.Simple).flags |= CMD_NO_FORK!() as libc::c_int; + } else if (*command).type_0 as libc::c_uint + == cm_connection as libc::c_int as libc::c_uint + && can_optimize_connection(command) != 0 + { + (*(*(*command).value.Connection).second).flags |= + CMD_TRY_OPTIMIZING!() as libc::c_int; + (*(*(*(*command).value.Connection).second).value.Simple).flags |= + CMD_TRY_OPTIMIZING!() as libc::c_int; + } + if startup_state == 2 as libc::c_int + && subshell_environment & CMD_INVERT_RETURN!() as libc::c_int != 0 + && *bash_input.location.string as libc::c_int == '\u{0}' as i32 + && (*command).type_0 as libc::c_uint + == cm_simple as libc::c_int as libc::c_uint + && ((*command).redirects).is_null() + && (*command).flags & CMD_TIME_PIPELINE!() as libc::c_int + == 0 as libc::c_int + && ((*(*command).value.Simple).words).is_null() + && !((*(*command).value.Simple).redirects).is_null() + && ((*(*(*command).value.Simple).redirects).next).is_null() + && (*(*(*command).value.Simple).redirects).instruction as libc::c_uint + == r_input_direction as libc::c_int as libc::c_uint + && (*(*(*command).value.Simple).redirects).redirector.dest + == 0 as libc::c_int + { + let mut r: libc::c_int = 0; + r = cat_file((*(*command).value.Simple).redirects); + ::std::ptr::write_volatile( + &mut last_result as *mut libc::c_int, + if r < 0 as libc::c_int { + 1 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + } else { + ::std::ptr::write_volatile( + //问题 + &mut last_result as *mut libc::c_int, + execute_command_internal( + command, + 0 as libc::c_int, + -(1 as libc::c_int), + -(1 as libc::c_int), + bitmap, + ), + ); + } + dispose_command(command); + dispose_fd_bitmap(bitmap); + discard_unwind_frame( + b"pe_dispose\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if !(flags & SEVAL_ONECMD!() as libc::c_int != 0) { + continue; + } + reset_parser(); + break; + } + } else { + ::std::ptr::write_volatile( + &mut last_result as *mut libc::c_int, + 2 as libc::c_int, + ); + if interactive_shell == 0 as libc::c_int + && this_shell_builtin.is_some() + && (this_shell_builtin == Some(source_builtin) + || this_shell_builtin == Some(eval_builtin)) + && last_command_exit_value == 257 as libc::c_int + && posixly_correct != 0 + && executing_command_builtin == 0 as libc::c_int + { + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 1 as libc::c_int, + ); + code = 4 as libc::c_int; + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 2 as libc::c_int, + ); + } + break; + } + } + } + run_unwind_frame( + b"parse_and_execute top\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if interrupt_state != 0 && parse_and_execute_level == 0 as libc::c_int { + interactive = interactive_shell; + throw_to_top_level(); + } + if should_jump_to_top_level != 0 { + jump_to_top_level(code); + } + return last_result; + } +} +#[no_mangle] +pub fn parse_string( + mut string: *mut libc::c_char, + mut from_file: *const libc::c_char, + mut flags: libc::c_int, + mut endp: *mut *mut libc::c_char, +) -> libc::c_int { + let mut code: libc::c_int = 0; + let mut nc: libc::c_int = 0; + let mut should_jump_to_top_level: libc::c_int = 0; + let mut command: *mut COMMAND = 0 as *mut COMMAND; + let mut oglobal: *mut COMMAND = 0 as *mut COMMAND; + let mut ostring: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ps_sigmask: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + parse_prologue( + string, + flags, + b"parse_string top\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + sigemptyset(&mut ps_sigmask as *mut sigset_t as *mut sigset_t); + sigprocmask( + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut sigset_t, + &mut ps_sigmask as *mut sigset_t as *mut sigset_t, + ); + push_stream(0 as libc::c_int); + if parser_expanding_alias() != 0 { + parser_save_alias(); + } + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 0 as libc::c_int, + ); + code = ::std::ptr::read_volatile::( + &should_jump_to_top_level as *const libc::c_int, + ); + oglobal = global_command; + ostring = string; + with_input_from_string(string, from_file); + while *bash_input.location.string != 0 { + ::std::ptr::write_volatile( + &mut command as *mut *mut COMMAND, + 0 as *mut libc::c_void as *mut COMMAND, + ); + code = __sigsetjmp(top_level.as_mut_ptr(), 0 as libc::c_int); + if code != 0 { + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 0 as libc::c_int, + ); + match code { + 1 | 4 | 3 | 2 => { + if !command.is_null() { + dispose_command(command); + } + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 1 as libc::c_int, + ); + global_command = oglobal; + nc = (bash_input.location.string).offset_from(ostring) as libc::c_long + as libc::c_int; + if !endp.is_null() { + *endp = bash_input.location.string; + } + run_unwind_frame( + b"parse_string top\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + if should_jump_to_top_level != 0 { + if parse_and_execute_level == 0 as libc::c_int { + top_level_cleanup(); + } + if code == 2 as libc::c_int { + return -(2 as libc::c_int); + } + jump_to_top_level(code); + } + return nc; + } + _ => { + sigprocmask( + 2 as libc::c_int, + &mut ps_sigmask as *mut sigset_t as *mut sigset_t, + 0 as *mut libc::c_void as *mut sigset_t, + ); + command_error( + b"parse_string\0" as *const u8 as *const libc::c_char, + 3 as libc::c_int, + code, + 0 as libc::c_int, + ); + } + } + } + if parse_command() == 0 as libc::c_int { + dispose_command(global_command); + global_command = 0 as *mut libc::c_void as *mut COMMAND; + if current_token == 304 as libc::c_int || current_token == shell_eof_token { + break; + } + } else { + if flags & CMD_NO_FORK!() as libc::c_int == 0 as libc::c_int { + ::std::ptr::write_volatile( + &mut should_jump_to_top_level as *mut libc::c_int, + 1 as libc::c_int, + ); + code = 2 as libc::c_int; + } else { + reset_parser(); + } + break; + } + } + global_command = oglobal; + nc = (bash_input.location.string).offset_from(ostring) as libc::c_long as libc::c_int; + if !endp.is_null() { + *endp = bash_input.location.string; + } + run_unwind_frame( + b"parse_string top\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if should_jump_to_top_level != 0 { + if parse_and_execute_level == 0 as libc::c_int { + top_level_cleanup(); + } + if code == 2 as libc::c_int { + return -(2 as libc::c_int); + } + jump_to_top_level(code); + } + return nc; + } +} +fn cat_file(mut r: *mut REDIRECT) -> libc::c_int { + let mut fn_0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut fd: libc::c_int = 0; + let mut rval: libc::c_int = 0; + unsafe { + if (*r).instruction as libc::c_uint != r_input_direction as libc::c_int as libc::c_uint { + return -(1 as libc::c_int); + } + if posixly_correct != 0 && interactive_shell == 0 { + disallow_filename_globbing += 1; + } + fn_0 = redirection_expand((*r).redirectee.filename); + if posixly_correct != 0 && interactive_shell == 0 { + disallow_filename_globbing -= 1; + } + if fn_0.is_null() { + redirection_error(r, -(1 as libc::c_int), fn_0); + return -(1 as libc::c_int); + } + fd = open(fn_0, 0 as libc::c_int); + if fd < 0 as libc::c_int { + file_error(fn_0); + free(fn_0 as *mut libc::c_void); + return -(1 as libc::c_int); + } + rval = zcatfd(fd, 1 as libc::c_int, fn_0); + free(fn_0 as *mut libc::c_void); + close(fd); + return rval; + } +} +#[no_mangle] +pub fn evalstring( + mut string: *mut libc::c_char, + mut from_file: *const libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + let mut r: libc::c_int = 0; + let mut rflag: libc::c_int = 0; + let mut rcatch: libc::c_int = 0; + let mut was_trap: libc::c_int = 0; + unsafe { + ::std::ptr::write_volatile(&mut was_trap as *mut libc::c_int, running_trap); + ::std::ptr::write_volatile(&mut rcatch as *mut libc::c_int, 0 as libc::c_int); + ::std::ptr::write_volatile(&mut rflag as *mut libc::c_int, return_catch_flag); + if rflag != 0 { + begin_unwind_frame( + b"evalstring\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + unwind_protect_mem( + &mut return_catch_flag as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut return_catch as *mut sigjmp_buf as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + return_catch_flag += 1; + ::std::ptr::write_volatile( + &mut rcatch as *mut libc::c_int, + __sigsetjmp(return_catch.as_mut_ptr(), 0 as libc::c_int), + ); + } + if rcatch != 0 { + parse_and_execute_cleanup(was_trap); + ::std::ptr::write_volatile(&mut r as *mut libc::c_int, return_catch_value); + } else { + ::std::ptr::write_volatile( + &mut r as *mut libc::c_int, + parse_and_execute(string, from_file, flags), + ); + } + if rflag != 0 { + run_unwind_frame( + b"evalstring\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if rcatch != 0 && return_catch_flag != 0 { + return_catch_value = r; + siglongjmp(return_catch.as_mut_ptr(), 1 as libc::c_int); + } + } + return r; + } +} diff --git a/utshell-0.5.0/src/builtins/exec.rs b/utshell-0.5.0/src/builtins/exec.rs new file mode 100644 index 00000000..af80eda7 --- /dev/null +++ b/utshell-0.5.0/src/builtins/exec.rs @@ -0,0 +1,239 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::bashhist::maybe_save_shell_history; +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + common::{builtin_usage, sh_notfound, sh_restricted}, + help::builtin_help, +}; +use crate::dispose_cmd::dispose_redirects; +use crate::error::file_error; +use crate::execute_cmd::shell_execve; +use crate::findcmd::{executable_file, search_for_command}; +use crate::general::{absolute_program, file_isdir, full_pathname}; +use crate::input::sync_buffered_stream; +use crate::jobs::{default_tty_job_signals, end_job_control, restart_job_control}; +use crate::sig::initialize_signals; +use crate::src_common::*; +use crate::trap::{initialize_traps, restore_original_signals}; +use crate::utshell::exit_shell; +use crate::variables::{adjust_shell_level, maybe_make_export_env}; + +/* If the user wants this to look like a login shell, then +prepend a `-' onto NAME and return the new name. */ +#[no_mangle] +fn mkdashname(name: *mut libc::c_char) -> *mut libc::c_char { + let ret: *mut libc::c_char; + + unsafe { + ret = malloc(2 + strlen(name) as usize) as *mut libc::c_char; + *ret.offset(0) = '-' as libc::c_char; + strcpy(ret.offset(1), name); + return ret; + } +} + +#[no_mangle] +pub fn exec_builtin(mut list: *mut WordList) -> i32 { + let mut exit_value; + let mut cleanenv: i32 = 0; + let mut login: i32 = 0; + let mut opt: i32; + let mut orig_job_control: i32 = 0; + let mut argv0: *mut libc::c_char = std::ptr::null_mut() as *mut libc::c_char; + let mut command: *mut libc::c_char; + let mut args: *mut *mut libc::c_char; + let mut env: *mut *mut libc::c_char; + let newname: *mut libc::c_char; + let com2: *mut libc::c_char; + + unsafe { + exec_argv0 = std::ptr::null_mut() as *mut libc::c_char; + + reset_internal_getopt(); + + loop { + let c_str = CString::new("cla:").unwrap(); + opt = internal_getopt(list, c_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let optu8 = opt as u8; + let opt_char = char::from(optu8); + match opt_char { + 'c' => cleanenv = 1, + 'l' => login = 1, + 'a' => argv0 = list_optarg, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + + opt = internal_getopt(list, c_str.as_ptr() as *mut libc::c_char); + } + + list = loptend; + + /* First, let the redirections remain. */ + dispose_redirects(redirection_undo_list); + redirection_undo_list = std::ptr::null_mut() as *mut REDIRECT; + + if list.is_null() { + return EXECUTION_SUCCESS!(); + } + + if restricted != 0 { + //é™åˆ¶æ€§shell + // sh_restricted(std::ptr::null_mut() as *mut libc::c_char); + sh_restricted(std::ptr::null_mut() as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + + args = strvec_from_word_list(list, 1, 0, 0 as *mut libc::c_int); //è¿™ä¸ªæŒ‡é’ˆè¿™æ ·å†™ä¸æ¸…楚å¯ä¸å¯ä»¥ + env = 0 as *mut *mut libc::c_char; + + /* A command with a slash anywhere in its name is not looked up in $PATH. */ + if absolute_program(*args.offset(0)) != 0 { + //命令给的ç»å¯¹è·¯å¾„,或者执行脚本 + command = (*args).offset(0); + } else { + //execåŽç›´æŽ¥ç»™å‘½ä»¤ + command = search_for_command(*args.offset(0), 1); + } + + if command.is_null() { + if file_isdir(*args.offset(0)) != 0 { + let c_str = CString::new("%s: cannot execute: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, *args.offset(0), strerror(errno())); + exit_value = EX_NOEXEC; + } else { + sh_notfound(*args.offset(0)); + exit_value = EX_NOTFOUND; + } + //goto failed_exec; + break; + } + + com2 = full_pathname(command); + if !com2.is_null() { + if command != *args.offset(0) { + free(command as *mut c_void); + } + command = com2; + } + + if !argv0.is_null() { + //exec有-a傿•° + free(*args.offset(0) as *mut c_void); + if login != 0 { + *args.offset(0) = mkdashname(argv0); + } else { + *args.offset(0) = savestring!(argv0); + } + exec_argv0 = savestring!(*args.offset(0)); + } else if login != 0 { + newname = mkdashname(*args.offset(0)); + free(*args.offset(0) as *mut c_void); + *args.offset(0) = newname; + } + + /* Decrement SHLVL by 1 so a new shell started here has the same value, + preserving the appearance. After we do that, we need to change the + exported environment to include the new value. If we've already forked + and are in a subshell, we don't want to decrement the shell level, + since we are `increasing' the level */ + + if cleanenv == 0 && (subshell_environment & SUBSHELL_PAREN!() == 0) { + adjust_shell_level(-1); + } + + if cleanenv != 0 { + env = strvec_create(1); + *env.offset(0) = 0 as *mut libc::c_char; + } else { + maybe_make_export_env(); + env = export_env; + } + + if interactive_shell != 0 && subshell_environment == 0 { + maybe_save_shell_history(); + } + + restore_original_signals(); + + orig_job_control = job_control; + if subshell_environment == 0 { + end_job_control(); + } + if interactive != 0 || job_control != 0 { + default_tty_job_signals(); + } + + if default_buffered_input >= 0 { + sync_buffered_stream(default_buffered_input); + } + + exit_value = shell_execve(command, args, env); + + /* We have to set this to NULL because shell_execve has called realloc() + to stuff more items at the front of the array, which may have caused + the memory to be freed by realloc(). We don't want to free it twice. */ + + args = std::ptr::null_mut() as *mut *mut libc::c_char; + + if cleanenv == 0 { + adjust_shell_level(1); + } + + if exit_value == EX_NOTFOUND { + //goto failed_exec; + break; + } else if executable_file(command) == 0 { + let c_str = CString::new("%s: cannot execute: %s").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr, command, strerror(errno())); + exit_value = EX_NOEXEC; + } else { + file_error(command); + } + + //跳出loopå¾ªçŽ¯ï¼Œåªæ‰§è¡Œä¸€æ¬¡loop + break; + } + + //fialed_exec + FREE!(command as *mut c_void); + + if subshell_environment != 0 || interactive == 0 && no_exit_on_failed_exec == 0 { + exit_shell(exit_value); + } + + if !args.is_null() { + strvec_dispose(args); + } + + if !env.is_null() && env != export_env { + strvec_dispose(env); + } + + initialize_traps(); + initialize_signals(1); + + if orig_job_control != 0 { + restart_job_control(); + } + + return exit_value; + } +} diff --git a/utshell-0.5.0/src/builtins/exec_cmd.rs b/utshell-0.5.0/src/builtins/exec_cmd.rs new file mode 100644 index 00000000..7477bcee --- /dev/null +++ b/utshell-0.5.0/src/builtins/exec_cmd.rs @@ -0,0 +1,953 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::builtins::alias::{alias_builtin, unalias_builtin}; +use crate::builtins::bind::bind_builtin; +use crate::builtins::break_1::{break_builtin, continue_builtin}; +use crate::builtins::builtin::builtin_builtin; +use crate::builtins::caller::caller_builtin; +use crate::builtins::cd::{cd_builtin, pwd_builtin}; +use crate::builtins::colon::{colon_builtin, false_builtin}; +use crate::builtins::command::command_builtin; +use crate::builtins::complete::{compgen_builtin, complete_builtin, compopt_builtin}; +use crate::builtins::declare::{declare_builtin, local_builtin}; +use crate::builtins::echo::echo_builtin; +use crate::builtins::enable::enable_builtin; +use crate::builtins::eval::eval_builtin; +use crate::builtins::exec::exec_builtin; +use crate::builtins::exit::{exit_builtin, logout_builtin}; +use crate::builtins::fc::fc_builtin; +use crate::builtins::fg_bg::{bg_builtin, fg_builtin}; +use crate::builtins::getopts::getopts_builtin; +use crate::builtins::hash::hash_builtin; +use crate::builtins::help::help_builtin; +use crate::builtins::history::history_builtin; +use crate::builtins::jobs::disown_builtin; +use crate::builtins::jobs::jobs_builtin; +use crate::builtins::kill::kill_builtin; +use crate::builtins::let_1::let_builtin; +use crate::builtins::mapfile::mapfile_builtin; +use crate::builtins::printf::printf_builtin; +use crate::builtins::pushd::{dirs_builtin, popd_builtin, pushd_builtin}; +use crate::builtins::read::read_builtin; +use crate::builtins::return_1::return_builtin; +use crate::builtins::set::{set_builtin, unset_builtin}; +use crate::builtins::setattr::{export_builtin, readonly_builtin}; +use crate::builtins::shift::shift_builtin; +use crate::builtins::shopt::shopt_builtin; +use crate::builtins::source::source_builtin; +use crate::builtins::suspend::suspend_builtin; +use crate::builtins::test::test_builtin; +use crate::builtins::times::times_builtin; +use crate::builtins::trap::trap_builtin; +use crate::builtins::type_1::type_builtin; +use crate::builtins::ulimit::ulimit_builtin; +use crate::builtins::umask::umask_builtin; +use crate::builtins::wait::wait_builtin; +use crate::src_common::*; + +enum CMDType { + AliasCmd, + UnAliasCmd, + BindCmd, + BreakCmd, + ContinueCmd, + BuiltinCmd, + CallerCmd, + CdCmd, + PwdCmd, + ColonCmd, + FalseCmd, + CommandCmd, + CommonCmd, + CompleteCmd, + CompoptCmd, + CompgenCmd, + DeclareCmd, + LocalCmd, + EchoCmd, + EnableCmd, + EvalCmd, + ExecCmd, + ExitCmd, + LogoutCmd, + FcCmd, + FgCmd, + BgCmd, + GetoptsCmd, + HashCmd, + HelpCmd, + HistoryCmd, + JobsCmd, + KillCmd, + LetCmd, + MapfileCmd, + PrintfCmd, + PushdCmd, + DirsCmd, + PopdCmd, + ReadCmd, + ReservedCmd, + ReturnCmd, + SetattrCmd, + ExportCmd, + ReadonlyCmd, + SetCmd, + UnSetCmd, + ShiftCmd, + ShoptCmd, + SourceCmd, + SuspendCmd, + TestCmd, + TimesCmd, + TrapCmd, + TypeCmd, + UlimitCmd, + UmaskCmd, + WaitCmd, + DisownCmd, +} + +struct AliasComand; +impl CommandExec for AliasComand { + fn excute(&self, list: *mut WordList) -> i32 { + alias_builtin(list) + } +} +struct UnAliasComand; +impl CommandExec for UnAliasComand { + fn excute(&self, list: *mut WordList) -> i32 { + unalias_builtin(list) + } +} + +struct BindComand; +impl CommandExec for BindComand { + fn excute(&self, list: *mut WordList) -> i32 { + bind_builtin(list) + } +} +struct BreakComand; +impl CommandExec for BreakComand { + fn excute(&self, list: *mut WordList) -> i32 { + break_builtin(list) + } +} +struct ContinueComand; +impl CommandExec for ContinueComand { + fn excute(&self, list: *mut WordList) -> i32 { + continue_builtin(list) + } +} +struct BuiltinComand; +impl CommandExec for BuiltinComand { + fn excute(&self, list: *mut WordList) -> i32 { + builtin_builtin(list) + } +} +struct CallerComand; +impl CommandExec for CallerComand { + fn excute(&self, list: *mut WordList) -> i32 { + caller_builtin(list) + } +} +struct CdComand; +impl CommandExec for CdComand { + fn excute(&self, list: *mut WordList) -> i32 { + cd_builtin(list) + } +} + +struct PwdComand; +impl CommandExec for PwdComand { + fn excute(&self, list: *mut WordList) -> i32 { + pwd_builtin(list) + } +} +struct ColonComand; +impl CommandExec for ColonComand { + fn excute(&self, list: *mut WordList) -> i32 { + colon_builtin(list) + // 0 + } +} +struct FalseComand; +impl CommandExec for FalseComand { + fn excute(&self, list: *mut WordList) -> i32 { + false_builtin(list) + // 0 + } +} +struct CommandComand; +impl CommandExec for CommandComand { + fn excute(&self, list: *mut WordList) -> i32 { + command_builtin(list) + } +} +struct CommonComand; +impl CommandExec for CommonComand { + fn excute(&self, _list: *mut WordList) -> i32 { + 0 + } +} +struct CompleteComand; +impl CommandExec for CompleteComand { + fn excute(&self, list: *mut WordList) -> i32 { + complete_builtin(list) + } +} + +struct CompgenCommand; +impl CommandExec for CompgenCommand { + fn excute(&self, list: *mut WordList) -> i32 { + compgen_builtin(list) + } +} + +struct CompoptCommand; +impl CommandExec for CompoptCommand { + fn excute(&self, list: *mut WordList) -> i32 { + compopt_builtin(list) + } +} +struct DeclareComand; +impl CommandExec for DeclareComand { + fn excute(&self, list: *mut WordList) -> i32 { + declare_builtin(list) + } +} +struct LocalComand; +impl CommandExec for LocalComand { + fn excute(&self, list: *mut WordList) -> i32 { + local_builtin(list) + } +} + +struct EchoComand; +impl CommandExec for EchoComand { + fn excute(&self, list: *mut WordList) -> i32 { + echo_builtin(list) + } +} +struct EnableComand; +impl CommandExec for EnableComand { + fn excute(&self, list: *mut WordList) -> i32 { + enable_builtin(list) + } +} +struct EvalComand; +impl CommandExec for EvalComand { + fn excute(&self, list: *mut WordList) -> i32 { + eval_builtin(list) + } +} +struct ExecComand; +impl CommandExec for ExecComand { + fn excute(&self, list: *mut WordList) -> i32 { + exec_builtin(list) + } +} +struct ExitComand; +impl CommandExec for ExitComand { + fn excute(&self, list: *mut WordList) -> i32 { + exit_builtin(list) + } +} + +struct LogoutCommand; +impl CommandExec for LogoutCommand { + fn excute(&self, list: *mut WordList) -> i32 { + logout_builtin(list) + } +} +struct FcComand; +impl CommandExec for FcComand { + fn excute(&self, list: *mut WordList) -> i32 { + fc_builtin(list) + } +} +struct FgComand; +impl CommandExec for FgComand { + fn excute(&self, list: *mut WordList) -> i32 { + fg_builtin(list) + } +} +struct BgComand; +impl CommandExec for BgComand { + fn excute(&self, list: *mut WordList) -> i32 { + bg_builtin(list) + } +} +struct GetoptsComand; +impl CommandExec for GetoptsComand { + fn excute(&self, list: *mut WordList) -> i32 { + getopts_builtin(list) + } +} +struct HashComand; +impl CommandExec for HashComand { + fn excute(&self, list: *mut WordList) -> i32 { + hash_builtin(list) + } +} +struct HelpComand; +impl CommandExec for HelpComand { + fn excute(&self, list: *mut WordList) -> i32 { + help_builtin(list) + } +} +struct HistoryComand; +impl CommandExec for HistoryComand { + fn excute(&self, list: *mut WordList) -> i32 { + history_builtin(list) + } +} +struct JobsComand; +impl CommandExec for JobsComand { + fn excute(&self, list: *mut WordList) -> i32 { + jobs_builtin(list) + } +} +struct KillComand; +impl CommandExec for KillComand { + fn excute(&self, list: *mut WordList) -> i32 { + kill_builtin(list) + } +} +struct LetComand; +impl CommandExec for LetComand { + fn excute(&self, list: *mut WordList) -> i32 { + let_builtin(list) + } +} +struct MapfileComand; +impl CommandExec for MapfileComand { + fn excute(&self, list: *mut WordList) -> i32 { + mapfile_builtin(list) + } +} +struct PrintfComand; +impl CommandExec for PrintfComand { + fn excute(&self, list: *mut WordList) -> i32 { + printf_builtin(list) + } +} +struct PushdCommand; +impl CommandExec for PushdCommand { + fn excute(&self, list: *mut WordList) -> i32 { + pushd_builtin(list) + } +} + +struct PopdComand; +impl CommandExec for PopdComand { + fn excute(&self, list: *mut WordList) -> i32 { + popd_builtin(list) + } +} +struct DirsCommand; +impl CommandExec for DirsCommand { + fn excute(&self, list: *mut WordList) -> i32 { + dirs_builtin(list) + } +} +struct ReadComand; +impl CommandExec for ReadComand { + fn excute(&self, list: *mut WordList) -> i32 { + read_builtin(list) + } +} +struct ReservedComand; +impl CommandExec for ReservedComand { + fn excute(&self, _list: *mut WordList) -> i32 { + // reserve_builtin(list) + 0 + } +} +struct ReturnComand; +impl CommandExec for ReturnComand { + fn excute(&self, list: *mut WordList) -> i32 { + return_builtin(list) + } +} +struct SetattrComand; +impl CommandExec for SetattrComand { + fn excute(&self, _list: *mut WordList) -> i32 { + //setattbuiltin(list); + /*unkown enter which func */ + 0 + } +} +struct ExportComand; +impl CommandExec for ExportComand { + fn excute(&self, list: *mut WordList) -> i32 { + export_builtin(list) + } +} + +struct ReadonlyComand; +impl CommandExec for ReadonlyComand { + fn excute(&self, list: *mut WordList) -> i32 { + readonly_builtin(list) + } +} + +struct SetComand; +impl CommandExec for SetComand { + fn excute(&self, list: *mut WordList) -> i32 { + set_builtin(list) + } +} + +struct UnSetComand; +impl CommandExec for UnSetComand { + fn excute(&self, list: *mut WordList) -> i32 { + unset_builtin(list) + } +} +struct ShiftComand; +impl CommandExec for ShiftComand { + fn excute(&self, list: *mut WordList) -> i32 { + shift_builtin(list) + } +} +struct ShoptComand; +impl CommandExec for ShoptComand { + fn excute(&self, list: *mut WordList) -> i32 { + shopt_builtin(list) + } +} +struct SourceComand; +impl CommandExec for SourceComand { + fn excute(&self, list: *mut WordList) -> i32 { + source_builtin(list) + } +} +struct SuspendComand; +impl CommandExec for SuspendComand { + fn excute(&self, list: *mut WordList) -> i32 { + suspend_builtin(list) + } +} +struct TestComand; +impl CommandExec for TestComand { + fn excute(&self, list: *mut WordList) -> i32 { + test_builtin(list) + } +} +struct TimesComand; +impl CommandExec for TimesComand { + fn excute(&self, list: *mut WordList) -> i32 { + times_builtin(list) + } +} +struct TrapComand; +impl CommandExec for TrapComand { + fn excute(&self, list: *mut WordList) -> i32 { + trap_builtin(list) + } +} +struct TypeComand; +impl CommandExec for TypeComand { + fn excute(&self, list: *mut WordList) -> i32 { + type_builtin(list) + } +} +struct UlimitComand; +impl CommandExec for UlimitComand { + fn excute(&self, list: *mut WordList) -> i32 { + ulimit_builtin(list) + } +} +struct UmaskComand; +impl CommandExec for UmaskComand { + fn excute(&self, list: *mut WordList) -> i32 { + umask_builtin(list) + } +} +struct WaitComand; +impl CommandExec for WaitComand { + fn excute(&self, list: *mut WordList) -> i32 { + wait_builtin(list) + } +} + +struct DisownCommand; +impl CommandExec for DisownCommand { + fn excute(&self, list: *mut WordList) -> i32 { + disown_builtin(list) + } +} + +// å®šä¹‰æŽ¥å£ +pub trait CommandExec { + fn excute(&self, list: *mut WordList) -> i32; +} + +// å·¥åŽ‚æ¨¡å¼ +trait Factory { + fn make_product(&self, product_type: CMDType) -> Box; +} + +struct SimpleFactory; +impl SimpleFactory { + fn new() -> Self { + Self + } +} + +impl Factory for SimpleFactory { + fn make_product(&self, cmd_type: CMDType) -> Box { + match cmd_type { + CMDType::AliasCmd => Box::new(AliasComand {}), + CMDType::UnAliasCmd => Box::new(UnAliasComand {}), + CMDType::BindCmd => Box::new(BindComand {}), + CMDType::BreakCmd => Box::new(BreakComand {}), + CMDType::ContinueCmd => Box::new(ContinueComand {}), + CMDType::BuiltinCmd => Box::new(BuiltinComand {}), + CMDType::CallerCmd => Box::new(CallerComand {}), + CMDType::CdCmd => Box::new(CdComand {}), + CMDType::PwdCmd => Box::new(PwdComand {}), + CMDType::ColonCmd => Box::new(ColonComand {}), + CMDType::FalseCmd => Box::new(FalseComand {}), + CMDType::CommandCmd => Box::new(CommandComand {}), + CMDType::CommonCmd => Box::new(CommonComand {}), + CMDType::CompleteCmd => Box::new(CompleteComand {}), + CMDType::CompoptCmd => Box::new(CompoptCommand {}), + CMDType::CompgenCmd => Box::new(CompgenCommand {}), + CMDType::DeclareCmd => Box::new(DeclareComand {}), + CMDType::LocalCmd => Box::new(LocalComand {}), + CMDType::EchoCmd => Box::new(EchoComand {}), + CMDType::EnableCmd => Box::new(EnableComand {}), + CMDType::EvalCmd => Box::new(EvalComand {}), + CMDType::ExecCmd => Box::new(ExecComand {}), + CMDType::ExitCmd => Box::new(ExitComand {}), + CMDType::LogoutCmd => Box::new(LogoutCommand {}), + CMDType::FcCmd => Box::new(FcComand {}), + CMDType::FgCmd => Box::new(FgComand {}), + CMDType::BgCmd => Box::new(BgComand {}), + CMDType::GetoptsCmd => Box::new(GetoptsComand {}), + CMDType::HashCmd => Box::new(HashComand {}), + CMDType::HelpCmd => Box::new(HelpComand {}), + CMDType::HistoryCmd => Box::new(HistoryComand {}), + CMDType::JobsCmd => Box::new(JobsComand {}), + CMDType::KillCmd => Box::new(KillComand {}), + CMDType::LetCmd => Box::new(LetComand {}), + CMDType::MapfileCmd => Box::new(MapfileComand {}), + CMDType::PrintfCmd => Box::new(PrintfComand {}), + CMDType::PushdCmd => Box::new(PushdCommand {}), + CMDType::DirsCmd => Box::new(DirsCommand {}), + CMDType::PopdCmd => Box::new(PopdComand {}), + CMDType::ReadCmd => Box::new(ReadComand {}), + CMDType::ReservedCmd => Box::new(ReservedComand {}), + CMDType::ReturnCmd => Box::new(ReturnComand {}), + CMDType::SetattrCmd => Box::new(SetattrComand {}), + CMDType::ExportCmd => Box::new(ExportComand {}), + CMDType::ReadonlyCmd => Box::new(ReadonlyComand {}), + CMDType::SetCmd => Box::new(SetComand {}), + CMDType::UnSetCmd => Box::new(UnSetComand {}), + CMDType::ShiftCmd => Box::new(ShiftComand {}), + CMDType::ShoptCmd => Box::new(ShoptComand {}), + CMDType::SourceCmd => Box::new(SourceComand {}), + CMDType::SuspendCmd => Box::new(SuspendComand {}), + CMDType::TestCmd => Box::new(TestComand {}), + CMDType::TimesCmd => Box::new(TimesComand {}), + CMDType::TrapCmd => Box::new(TrapComand {}), + CMDType::TypeCmd => Box::new(TypeComand {}), + CMDType::UlimitCmd => Box::new(UlimitComand {}), + CMDType::UmaskCmd => Box::new(UmaskComand {}), + CMDType::WaitCmd => Box::new(WaitComand {}), + CMDType::DisownCmd => Box::new(DisownCommand {}), + } + } +} + +unsafe fn get_cmd_type(command: *mut libc::c_char) -> CMDType { + let mut types = CMDType::HelpCmd; + if libc::strcmp( + command, + b"alias\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::AliasCmd; + } + if libc::strcmp( + command, + b"unalias\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::UnAliasCmd; + } else if libc::strcmp( + command, + b"bind\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::BindCmd; + } else if libc::strcmp( + command, + b"break\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::BreakCmd; + } else if libc::strcmp( + command, + b"continue\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ContinueCmd; + } else if libc::strcmp( + command, + b"builtin\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::BuiltinCmd; + } else if libc::strcmp( + command, + b"caller\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CallerCmd; + } else if libc::strcmp( + command, + b"cd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CdCmd; + } else if libc::strcmp( + command, + b"pwd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::PwdCmd; + } else if libc::strcmp( + command, + b":\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + || libc::strcmp( + command, + b"true\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ColonCmd; + } else if libc::strcmp( + command, + b"false\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::FalseCmd; + } else if libc::strcmp( + command, + b"command\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CommandCmd; + } else if libc::strcmp( + command, + b"common\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CommonCmd; + } else if libc::strcmp( + command, + b"complete\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CompleteCmd; + } else if libc::strcmp( + command, + b"compopt\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CompoptCmd; + } else if libc::strcmp( + command, + b"compgen\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::CompgenCmd; + } else if libc::strcmp( + command, + b"declare\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + || libc::strcmp( + command, + b"typeset\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::DeclareCmd; + } else if libc::strcmp( + command, + b"local\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::LocalCmd; + } else if libc::strcmp( + command, + b"echo\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::EchoCmd; + } else if libc::strcmp( + command, + b"enable\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::EnableCmd; + } else if libc::strcmp( + command, + b"eval\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::EvalCmd; + } else if libc::strcmp( + command, + b"exec\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ExecCmd; + } else if libc::strcmp( + command, + b"exit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ExitCmd; + } else if libc::strcmp( + command, + b"logout\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::LogoutCmd; + } else if libc::strcmp( + command, + b"fc\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::FcCmd; + } else if libc::strcmp( + command, + b"fg\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::FgCmd; + } else if libc::strcmp( + command, + b"bg\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::BgCmd; + } else if libc::strcmp( + command, + b"getopts\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::GetoptsCmd; + } else if libc::strcmp( + command, + b"hash\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::HashCmd; + } else if libc::strcmp( + command, + b"help\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::HelpCmd; + } else if libc::strcmp( + command, + b"history\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::HistoryCmd; + } else if libc::strcmp( + command, + b"jobs\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::JobsCmd; + } else if libc::strcmp( + command, + b"kill\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::KillCmd; + } else if libc::strcmp( + command, + b"mapfile\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + || libc::strcmp( + command, + b"readarray\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::MapfileCmd; + } else if libc::strcmp( + command, + b"printf\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::PrintfCmd; + } else if libc::strcmp( + command, + b"pushd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::PushdCmd; + } else if libc::strcmp( + command, + b"dirs\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::DirsCmd; + } else if libc::strcmp( + command, + b"popd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::PopdCmd; + } else if libc::strcmp( + command, + b"read\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ReadCmd; + } else if libc::strcmp( + command, + b"let\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::LetCmd; + } else if libc::strcmp( + command, + b"return\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ReturnCmd; + } else if libc::strcmp( + command, + b"set\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::SetCmd; + } else if libc::strcmp( + command, + b"unset\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::UnSetCmd; + } else if libc::strcmp( + command, + b"setattr\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::SetattrCmd; + } else if libc::strcmp( + command, + b"readonly\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ReadonlyCmd; + } else if libc::strcmp( + command, + b"export\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ExportCmd; + } else if libc::strcmp( + command, + b"shift\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ShiftCmd; + } else if libc::strcmp( + command, + b"shopt\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::ShoptCmd; + } else if libc::strcmp( + command, + b"source\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + || libc::strcmp( + command, + b".\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::SourceCmd; + } else if libc::strcmp( + command, + b"suspend\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::SuspendCmd; + } else if libc::strcmp( + command, + b"test\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + || libc::strcmp( + command, + b"[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::TestCmd; + } else if libc::strcmp( + command, + b"times\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::TimesCmd; + } else if libc::strcmp( + command, + b"trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::TrapCmd; + } else if libc::strcmp( + command, + b"type\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::TypeCmd; + } else if libc::strcmp( + command, + b"ulimit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::UlimitCmd; + } else if libc::strcmp( + command, + b"umask\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::UmaskCmd; + } else if libc::strcmp( + command, + b"wait\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::WaitCmd; + } else if libc::strcmp( + command, + b"disown\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) == 0 + { + types = CMDType::DisownCmd; + } + + types +} + +#[no_mangle] +pub extern "C" fn exec_cmd(command: *mut libc::c_char, list: *mut WordList) -> i32 { + let commandType = unsafe { get_cmd_type(command) }; + let factory = SimpleFactory::new(); + let cmdCall = factory.make_product(commandType); + cmdCall.excute(list) +} diff --git a/utshell-0.5.0/src/builtins/exit.rs b/utshell-0.5.0/src/builtins/exit.rs new file mode 100644 index 00000000..540a340d --- /dev/null +++ b/utshell-0.5.0/src/builtins/exit.rs @@ -0,0 +1,154 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::builtins::{ + common::{err_translate_fn, get_exitstat}, + evalfile::maybe_execute_file, + help::builtin_help, + jobs::jobs_builtin, +}; +use crate::jobs::list_all_jobs; +use crate::sig::jump_to_top_level; +use crate::src_common::*; + +unsafe fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + return *a == *b && libc::strcmp(a, b) == 0; +} + +static mut sourced_logout: i32 = 0; + +#[no_mangle] +pub fn exit_builtin(list: *mut WordList) -> i32 { + unsafe { + let c_str = CString::new("--help").unwrap(); + let c_ptr = c_str.as_ptr(); + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && STREQ((*(*list).word).word, c_ptr) + { + builtin_help(); + return EX_USAGE; + } + + if interactive != 0 { + if login_shell != 0 { + let names = String::from("logout"); + err_translate_fn(&names, std::ptr::null_mut()); + println!(); + } else { + eprintln!("exit"); + } + } + return exit_or_logout(list); + } +} + +#[no_mangle] +pub fn logout_builtin(list: *mut WordList) -> i32 { + unsafe { + let c_str = CString::new("--help").unwrap(); + let c_ptr = c_str.as_ptr(); + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && STREQ((*(*list).word).word, c_ptr) + { + builtin_help(); + return EX_USAGE; + } + + if login_shell == 0 { + let names = String::from("logout"); + err_translate_fn(&names, std::ptr::null_mut()); + println!(); + let c_str = CString::new("not login shell: use `exit'").unwrap(); + let c_ptr = c_str.as_ptr(); + builtin_error(c_ptr); + + return EXECUTION_FAILURE!(); + } else { + return exit_or_logout(list); + } + } +} + +pub fn exit_or_logout(list: *mut WordList) -> i32 { + let exit_value: i32; + let exit_immediate_okay: i32; + let mut stopmsg: i32; + + unsafe { + exit_immediate_okay = (interactive == 0 + || last_shell_builtin == Some(exit_builtin) + || last_shell_builtin == Some(logout_builtin) + || last_shell_builtin == Some(jobs_builtin)) as i32; + + /* Check for stopped jobs if thw user wants to.*/ + if exit_immediate_okay == 0 { + stopmsg = 0; + for i in 0..js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() && STOPPED!(i) { + stopmsg = JSTOPPED as i32; + break; + } else if (check_jobs_at_exit != 0) + && (stopmsg == 0) + && !(*jobs.offset(i as isize)).is_null() + && RUNNING!(i) + { + stopmsg = JRUNNING as i32; + break; + } + } + + if stopmsg == JSTOPPED as i32 { + let names = String::from("stoppedjobs"); + err_translate_fn(&names, std::ptr::null_mut()); + eprintln!(); + } else if stopmsg == JRUNNING as i32 { + let names = String::from("runjobs"); + err_translate_fn(&names, std::ptr::null_mut()); + eprintln!(); + } + + if stopmsg == check_jobs_at_exit { + list_all_jobs(JLIST_STANDARD!()) + } + + if stopmsg != 0 { + last_shell_builtin = Some(exit_builtin); + this_shell_builtin = last_shell_builtin; + return EXECUTION_FAILURE!(); + } + } + + if (running_trap == 1) && (list == std::ptr::null_mut()) { + exit_value = trap_saved_exit_value; + } else { + exit_value = get_exitstat(list); + } + + bash_logout(); + last_command_exit_value = exit_value; + + jump_to_top_level(EXITPROG!()); + + 0 + } +} + +pub fn bash_logout() { + unsafe { + if login_shell != 0 && sourced_logout == 0 && subshell_environment == 0 { + sourced_logout = sourced_logout + 1; + let c_str = CString::new("~/.utshell_logout").unwrap(); + let c_ptr = c_str.as_ptr(); + maybe_execute_file(c_ptr, 1); + maybe_execute_file(SYS_BASH_LOGOOUT!(), 1); + } + } +} diff --git a/utshell-0.5.0/src/builtins/fc.rs b/utshell-0.5.0/src/builtins/fc.rs new file mode 100644 index 00000000..bf354dfd --- /dev/null +++ b/utshell-0.5.0/src/builtins/fc.rs @@ -0,0 +1,884 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use crate::bashhist::{bash_delete_last_history, maybe_add_history}; +use crate::builtins::evalfile::fc_execute_file; +use crate::builtins::{ + bashgetopt::{internal_getopt, reset_internal_getopt}, + common::{builtin_usage, sh_chkwrite, sh_erange, sh_wrerror}, + help::builtin_help, +}; +use crate::general::legal_number; +use crate::list::list_reverse; +use crate::readline::xfree; +use crate::sig::{termsig_handler, throw_to_top_level}; +use crate::src_common::*; +use crate::stringlib::strsub; +use crate::unwind_prot::{add_unwind_protect, unwind_protect_mem}; + +#[no_mangle] +pub fn set_verbose_flag() { + unsafe { + echo_input_at_read = verbose_flag; + } +} + +#[no_mangle] +pub fn fc_number(list: *mut WordList) -> i32 { + let mut s: *mut libc::c_char; + unsafe { + if list.is_null() { + return 0; + } + s = (*(*list).word).word; + if *s as libc::c_int == '-' as i32 { + s = s.offset(1); + } + let res = legal_number(s, std::ptr::null_mut()); + return res; + } +} + +fn REVERSE_LIST(list: *mut GENERIC_LIST) -> *mut REPL { + unsafe { + if list != std::ptr::null_mut() && (*list).next != std::ptr::null_mut() { + list_reverse(list) as *mut REPL + } else { + list as *mut REPL + } + } +} + +fn printToStderr(str: *mut libc::c_char) -> std::io::Result<()> { + let stderr_1 = std::io::stderr(); + let mut handle = stderr_1.lock(); + unsafe { + handle.write_all(std::ffi::CStr::from_ptr(str).to_bytes())?; + Ok(()) + } +} + +fn printToStdout(str: *mut libc::c_char) -> std::io::Result<()> { + let stdouts = std::io::stdout(); + let mut handle = stdouts.lock(); + unsafe { + handle.write_all(std::ffi::CStr::from_ptr(str).to_bytes())?; + Ok(()) + } +} + +fn printToStdoutflush() -> std::io::Result<()> { + let stdouts = std::io::stdout(); + let mut handle = stdouts.lock(); + handle.flush()?; + Ok(()) +} + +fn QUIT() { + unsafe { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + + if interrupt_state != 0 { + throw_to_top_level(); + } + } +} + +fn STREQN(a: *const libc::c_char, b: *const libc::c_char, n: i32) -> bool { + if n == 0 { + return true; + } else { + return unsafe { *a == *b && libc::strncmp(a, b, n as libc::size_t) == 0 }; + } +} + +#[no_mangle] +pub fn fc_builtin(mut list: *mut WordList) -> i32 { + let mut i: i32; + let mut sep: *mut libc::c_char; + let mut numbering: i32; + let mut reverse: i32; + let mut listing: i32; + let mut execute: i32; + let mut histbeg: i32; + let mut histend: i32; + let mut last_hist: i32; + let mut retval: i32; + let mut opt: i32; + let rh: i32; + let mut real_last: i32; + let stream: *mut libc::FILE; + let mut rlist: *mut REPL; + let mut rl: *mut REPL; + let mut ename: *mut libc::c_char; + let mut command: *mut libc::c_char; + let newcom: *mut libc::c_char; + let fcedit: std::ffi::CString; + let hlist: *mut *mut HIST_ENTRY; + let mut fnc: *mut libc::c_char = std::ptr::null_mut(); + + numbering = 1; + reverse = 0; + listing = 0; + execute = 0; + ename = std::ptr::null_mut(); + unsafe { + reset_internal_getopt(); + lcurrent = list; + + loptend = lcurrent; + while fc_number(loptend) == 0 { + opt = internal_getopt( + list, + CString::new(":e:lnrs").unwrap().as_ptr() as *mut libc::c_char, + ); + if opt != -1 { + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'n' => numbering = 0, + 'l' => listing = HN_LISTING!(), + 'r' => reverse = 1, + 's' => execute = 1, + 'e' => ename = list_optarg, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE!(); + } + builtin_usage(); + return EX_USAGE!(); + } + } + } else { + break; + } + loptend = lcurrent; + } + + list = loptend; + + if ename != std::ptr::null_mut() + && char::from(*ename as u8) == '-' + && char::from(*((ename as usize + 4) as *mut libc::c_char) as u8) == '\0' + { + execute = 1; + } + + if execute != 0 { + rlist = std::ptr::null_mut(); + + let mut ret: bool = loptend != std::ptr::null_mut(); + sep = libc::strchr((*(*list).word).word, char::from('=') as libc::c_int); + ret = ret && sep != std::ptr::null_mut(); + while ret { + sep = (sep as usize + 4) as *mut libc::c_char; + *sep = char::from('\0') as libc::c_char; + rl = libc::malloc(std::mem::size_of::<&REPL>()) as *mut REPL; + (*rl).next = std::ptr::null_mut(); + (*rl).pat = savestring!((*(*list).word).word); + (*rl).rep = savestring!(sep); + + if rlist == std::ptr::null_mut() { + rlist = rl; + } else { + (*rl).next = rlist; + rlist = rl; + } + list = (*list).next; + } + + rlist = REVERSE_LIST(rlist as *mut GENERIC_LIST); + hlist = history_list(); + if list != std::ptr::null_mut() { + command = fc_gethist((*(*list).word).word, hlist, 0); + } else { + command = fc_gethist(std::ptr::null_mut(), hlist, 0); + } + + if command == std::ptr::null_mut() { + builtin_error(CString::new("no command found").unwrap().as_ptr()); + if rlist != std::ptr::null_mut() { + rl = rlist; + while rl != std::ptr::null_mut() { + let r: *mut REPL; + r = (*rl).next; + if (*rl).pat != std::ptr::null_mut() { + libc::free((*rl).pat as *mut c_void); + } + + if (*rl).rep != std::ptr::null_mut() { + libc::free((*rl).rep as *mut c_void); + } + + libc::free(rl as *mut c_void); + rl = r; + } + } + return EXECUTION_FAILURE!(); + } + + if rlist != std::ptr::null_mut() { + newcom = fc_dosubs(command, rlist); + libc::free(command as *mut c_void); + rl = rlist; + while rl != std::ptr::null_mut() { + let r: *mut REPL; + r = (*rl).next; + if (*rl).pat != std::ptr::null_mut() { + libc::free((*rl).pat as *mut c_void); + } + + if (*rl).rep != std::ptr::null_mut() { + libc::free((*rl).rep as *mut c_void); + } + + libc::free(rl as *mut c_void); + rl = r; + } + command = newcom; + } + printToStderr(command); + fc_replhist(command); + return parse_and_execute( + command, + CString::new("fc").unwrap().as_ptr(), + SEVAL_NOHIST!(), + ); + } + + hlist = history_list(); + + if hlist == std::ptr::null_mut() { + return EXECUTION_SUCCESS!(); + } + i = 0; + + while !(*hlist.offset(i as isize)).is_null() { + i += 1; + } + + rh = (remember_on_history != 0 + || ((subshell_environment & SUBSHELL_COMSUB!()) != 0 && enable_history_list != 0)) + as i32; + last_hist = i - rh - hist_last_line_added; + + real_last = i; + while (*hlist.offset(real_last as isize)).is_null() && real_last > 0 { + real_last -= 1; + } + + if i == last_hist && (*hlist.offset(last_hist as isize)).is_null() { + while last_hist >= 0 && (*hlist.offset(last_hist as isize)).is_null() { + last_hist -= 1; + } + } + + if last_hist < 0 { + last_hist = 0; + } + + if !(list.is_null()) { + histbeg = fc_gethnum((*(*list).word).word, hlist, listing | HN_FIRST!()); + list = (*list).next; + + if list != std::ptr::null_mut() { + histend = fc_gethnum((*(*list).word).word, hlist, listing); + } else if histbeg == real_last { + histend = if listing != 0 { real_last } else { histbeg }; + } else { + histend = if listing != 0 { last_hist } else { histbeg } + } + } else { + if listing != 0 { + histend = last_hist; + histbeg = histend - 16 + 1; + if histbeg < 0 { + histbeg = 0; + } + } else { + histbeg = last_hist; + histend = last_hist; + } + } + + if histbeg == HIST_INVALID!() || histend == HIST_INVALID!() { + sh_erange( + std::ptr::null_mut(), + CString::new("history specification").unwrap().as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE!(); + } else if histbeg == HIST_ERANGE!() || histend == HIST_ERANGE!() { + sh_erange( + std::ptr::null_mut(), + CString::new("history specification").unwrap().as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE!(); + } else if histbeg == HIST_NOTFOUND!() || histend == HIST_NOTFOUND!() { + builtin_error(CString::new("no command found").unwrap().as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + + if histbeg < 0 { + histbeg = 0; + } + + if histend < 0 { + histend = 0; + } + + if listing == 0 && hist_last_line_added != 0 { + bash_delete_last_history(); + + if histbeg == histend + && histend == last_hist + && *((hlist as usize + (8 * last_hist) as usize) as *mut *mut HIST_ENTRY) + == std::ptr::null_mut() + { + histend -= 1; + last_hist = histend; + histbeg = histend; + } + + if *((hlist as usize + (8 * last_hist) as usize) as *mut *mut HIST_ENTRY) + == std::ptr::null_mut() + { + last_hist -= 1; + } + + if histend >= last_hist { + histend = last_hist; + } else if histbeg >= last_hist { + histbeg = last_hist; + } + } + + if histbeg == HIST_INVALID!() || histend == HIST_INVALID!() { + sh_erange( + std::ptr::null_mut(), + CString::new("history specification").unwrap().as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE!(); + } else if histbeg == HIST_ERANGE!() || histend == HIST_ERANGE!() { + sh_erange( + std::ptr::null_mut(), + CString::new("history specification").unwrap().as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE!(); + } else if histbeg == HIST_NOTFOUND!() || histend == HIST_NOTFOUND!() { + builtin_error(CString::new("no command found").unwrap().as_ptr()); + return EXECUTION_FAILURE!(); + } + + if histbeg < 0 { + histbeg = 0; + } + + if histend < 0 { + histend = 0; + } + + if histend < histbeg { + i = histend; + histend = histbeg; + histbeg = i; + reverse = 1; + } + + if listing != 0 { + stream = std::ptr::null_mut(); + } else { + numbering = 0; + stream = sh_mktmpfp( + CString::new("bash-fc").unwrap().as_ptr() as *mut libc::c_char, + MT_USERANDOM!() | MT_USETMPDIR!(), + &mut fnc, + ); + + if stream == std::ptr::null_mut() { + if fnc != std::ptr::null_mut() { + builtin_error( + CString::new("%s: cannot open temp file: %s") + .unwrap() + .as_ptr(), + fnc, + strerror(errno!()), + ); + } else { + builtin_error( + CString::new("%s: cannot open temp file: %s") + .unwrap() + .as_ptr(), + CString::new("").unwrap().as_ptr(), + strerror(errno!()), + ); + } + + libc::free(fnc as *mut c_void); + return EXECUTION_FAILURE!(); + } + } + + if reverse != 0 { + i = histend; + } else { + i = histbeg; + } + + let mut ret: bool = reverse != 0; + + if ret { + ret = i >= histbeg; + } else { + ret = i <= histend; + } + + while ret { + QUIT(); + if numbering != 0 { + if stream != std::ptr::null_mut() { + libc::fprintf( + stream, + CString::new("%d").unwrap().as_ptr(), + i + history_base, + ); + } else { + let diff = i + history_base; + printToStdout( + CString::new(diff.to_string()).unwrap().as_ptr() as *mut libc::c_char + ); + } + } + + if listing != 0 { + if posixly_correct != 0 { + if stream != std::ptr::null_mut() { + libc::fputs(CString::new("\t").unwrap().as_ptr(), stream); + } else { + printToStdout(CString::new("\t").unwrap().as_ptr() as *mut libc::c_char); + } + } else { + let mut ch: char; + if (**((hlist as usize + (8 * i) as usize) as *mut *mut HIST_ENTRY)).data + != std::ptr::null_mut() + { + ch = '*'; + } else { + ch = ' '; + } + + if stream != std::ptr::null_mut() { + libc::fprintf(stream, CString::new("\t%c").unwrap().as_ptr(), &mut ch); + } else { + let mut th = vec!['\t' as libc::c_char]; + th.push(ch as libc::c_char); + th.push(0); + printToStdout(th.as_ptr() as *mut libc::c_char); + } + } + } + + if stream != std::ptr::null_mut() { + libc::fprintf( + stream, + CString::new("%s\n").unwrap().as_ptr(), + (**((hlist as usize + (i * 8) as usize) as *mut *mut HIST_ENTRY)).line, + ); + } else { + printToStdout( + (**((hlist as usize + (i * 8) as usize) as *mut *mut HIST_ENTRY)).line, + ); + printToStdout(CString::new("\n").unwrap().as_ptr() as *mut libc::c_char); + } + + ret = reverse != 0; + if ret { + i -= 1; + } else { + i += 1; + } + + if ret { + ret = i >= histbeg; + } else { + ret = i <= histend; + } + } + + if listing != 0 { + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + + if stream != std::ptr::null_mut() { + libc::fflush(stream); + if libc::ferror(stream) != 0 { + sh_wrerror(); + libc::fclose(stream); + libc::free(fnc as *mut c_void); + return EXECUTION_FAILURE!(); + } + libc::fclose(stream); + } else { + if printToStdoutflush().is_err() { + sh_wrerror(); + libc::free(fnc as *mut c_void); + return EXECUTION_FAILURE!(); + } + } + + /* Now edit the file of commands. */ + if ename != std::ptr::null_mut() { + command = + libc::malloc(libc::strlen(ename) + libc::strlen(fnc) + 2) as *mut libc::c_char; + libc::sprintf(command, CString::new("").unwrap().as_ptr()); + libc::strcpy(command, ename); + libc::strcat(command, CString::new(" ").unwrap().as_ptr()); + libc::strcat(command, fnc); + } else { + if posixly_correct != 0 { + fcedit = CString::new("${FCEDIT:-${EDITOR:-ed}}").unwrap(); + } else { + fcedit = CString::new("${FCEDIT:-${EDITOR:-vi}}").unwrap(); + } + + command = + libc::malloc(3 + libc::strlen(fcedit.as_ptr()) as libc::size_t + libc::strlen(fnc)) + as *mut libc::c_char; + libc::sprintf(command, CString::new("").unwrap().as_ptr()); + libc::strcpy(command, fcedit.as_ptr()); + libc::strcat(command, CString::new(" ").unwrap().as_ptr()); + libc::strcat(command, fnc); + } + + retval = parse_and_execute( + command, + CString::new("fc").unwrap().as_ptr(), + SEVAL_NOHIST!(), + ); + if retval != EXECUTION_SUCCESS!() { + unlink(fnc); + libc::free(fnc as *mut c_void); + return EXECUTION_FAILURE!(); + } + + /* Make sure parse_and_execute doesn't turn this off, even though a + call to parse_and_execute farther up the function call stack (e.g., + if this is called by vi_edit_and_execute_command) may have already + called bash_history_disable. */ + remember_on_history = 1; + + /* Turn on the `v' flag while fc_execute_file runs so the commands + will be echoed as they are read by the parser. */ + //begin_unwind_frame (CString::new ("fc builtin").unwrap().as_ptr() as * mut libc::c_char); + // let xf: Functions = Functions { f_xfree: xfree }; + // let uk: Functions = Functions { f_unlink: unlink }; + // let r_flag: Functions = Functions { + // f_set_verbose: set_verbose_flag, + // }; + // add_unwind_protect(xf, fnc); + // add_unwind_protect(uk, fnc); + add_unwind_protect( + std::mem::transmute::< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + Option, + >(xfree), + fnc, + ); + add_unwind_protect( + std::mem::transmute:: libc::c_int, Option>(unlink), + fnc, + ); + add_unwind_protect( + std::mem::transmute::>(set_verbose_flag), + std::ptr::null_mut(), + ); + unwind_protect_mem( + (&mut (suppress_debug_trap_verbose as libc::c_char)) as *mut libc::c_char, + 4, + ); + echo_input_at_read = 1; + suppress_debug_trap_verbose = 1; + + retval = fc_execute_file(fnc); + //run_unwind_frame (CString::new ("fc builtin").unwrap().as_ptr() as * mut libc::c_char); + + return retval; + } +} + +#[no_mangle] +pub fn fc_gethist( + command: *mut libc::c_char, + hlist: *mut *mut HIST_ENTRY, + mode: i32, +) -> *mut libc::c_char { + let i: i32; + + if hlist == std::ptr::null_mut() { + return std::ptr::null_mut(); + } + + i = fc_gethnum(command, hlist, mode); + unsafe { + if i >= 0 { + return savestring!( + (*(*((hlist as usize + (8 * i) as usize) as *mut *mut HIST_ENTRY))).line + ); + } else { + return std::ptr::null_mut(); + } + } +} + +#[no_mangle] +pub fn fc_gethnum(command: *mut libc::c_char, hlist: *mut *mut HIST_ENTRY, mode: i32) -> i32 { + let mut sign: i32; + let mut n: i32; + let clen: i32; + let rh: i32; + let mut i: i32 = 0; + let mut j: i32; + let mut last_hist: i32; + let mut real_last: i32; + let listing: i32; + + let mut s: *mut libc::c_char; + + unsafe { + listing = mode & HN_LISTING!(); + sign = 1; + /* Count history elements. */ + while !(*hlist.offset(i as isize)).is_null() { + i += 1; + } + /* With the Bash implementation of history, the current command line + ("fc blah..." and so on) is already part of the history list by + the time we get to this point. This just skips over that command + and makes the last command that this deals with be the last command + the user entered before the fc. We need to check whether the + line was actually added (HISTIGNORE may have caused it to not be), + so we check hist_last_line_added. This needs to agree with the + calculation of last_hist in fc_builtin above. */ + /* Even though command substitution through parse_and_execute turns off + remember_on_history, command substitution in a shell when set -o history + has been enabled (interactive or not) should use it in the last_hist + calculation as if it were on. */ + rh = (remember_on_history != 0 + || ((subshell_environment & SUBSHELL_COMSUB!()) != 0 && enable_history_list != 0)) + as i32; + last_hist = i - rh - hist_last_line_added; + + if i == last_hist && (*hlist.offset(last_hist as isize)).is_null() { + while last_hist >= 0 && (*hlist.offset(last_hist as isize)).is_null() { + last_hist -= 1; + } + } + + if last_hist < 0 { + return -1; + } + + real_last = i; + i = last_hist; + + /* No specification defaults to most recent command. */ + if command == std::ptr::null_mut() { + return i; + } + + /* back up from the end to the last non-null history entry */ + while (*hlist.offset(real_last as isize)).is_null() && real_last > 0 { + real_last -= 1; + } + + /* Otherwise, there is a specification. It can be a number relative to + the current position, or an absolute history number. */ + s = command; + + /* Handle possible leading minus sign. */ + if s != std::ptr::null_mut() && (char::from(*s as u8) == '-') { + sign = -1; + s = s.offset(1) + } + + if s != std::ptr::null_mut() && DIGIT!(*s) { + n = libc::atoi(s); + n *= sign; + + /* We want to return something that is an offset to HISTORY_BASE. */ + /* If the value is negative or zero, then it is an offset from + the current history item. */ + /* We don't use HN_FIRST here, so we don't return different values + depending on whether we're looking for the first or last in a + pair of range arguments, but nobody else does, either. */ + if n < 0 { + n += i + 1; + if n < 0 { + return 0; + } else { + return n; + } + } else if n == 0 { + if sign == -1 { + if listing != 0 { + return real_last; + } else { + return HIST_INVALID!(); + } + } else { + return i; + } + } else { + /* If we're out of range (greater than I (last history entry) or + less than HISTORY_BASE, we want to return different values + based on whether or not we are looking for the first or last + value in a desired range of history entries. */ + n -= history_base; + if n < 0 { + if mode & HN_FIRST!() != 0 { + return 0; + } else { + return i; + } + } else if n >= i { + if mode & HN_FIRST!() != 0 { + return 0; + } else { + return i; + } + } else { + return n; + } + } + } + + clen = libc::strlen(command as *const libc::c_char) as i32; + j = i; + while j >= 0 { + if STREQN(command, (*(*hlist.offset(j as isize))).line, clen) { + //if STREQN (command, (*(*((hlist as usize + (8*j) as usize ) as * mut * mut HIST_ENTRY))).line, clen) { + return j; + } + j -= 1; + } + return HIST_NOTFOUND!(); + } +} + +#[no_mangle] +pub fn fc_dosubs(command: *mut libc::c_char, subs: *mut REPL) -> *mut libc::c_char { + let mut new: *mut libc::c_char; + let mut t: *mut libc::c_char; + let mut r: *mut REPL; + unsafe { + new = savestring!(command); + while subs != std::ptr::null_mut() { + r = subs; + t = strsub(new, (*r).pat, (*r).rep, 1); + r = (*r).next; + libc::free(new as *mut c_void); + new = t; + } + return new; + } +} + +#[no_mangle] +pub fn fc_replhist(command: *mut libc::c_char) { + let n: i32; + unsafe { + if command == std::ptr::null_mut() || char::from(*command as u8) == '\0' { + return; + } + + n = libc::strlen(command as *const libc::c_char) as i32; + if char::from(*((command as usize + 4 * (n - 1) as usize) as *mut libc::c_char) as u8) + == '\n' + { + *((command as usize + 4 * (n - 1) as usize) as *mut libc::c_char) = 0 as libc::c_char; + } + + if command != std::ptr::null_mut() && (*command) != 0 { + bash_delete_last_history(); + maybe_add_history(command); + } + } +} + +#[no_mangle] +pub fn fc_addhist(line: *mut libc::c_char) { + let n: i32; + unsafe { + if line == std::ptr::null_mut() || *line == 0 { + return; + } + + n = libc::strlen(line) as i32; + + if *((line as usize + (n - 1) as usize) as *mut libc::c_char) == '\n' as libc::c_char { + *((line as usize + (n - 1) as usize) as *mut libc::c_char) = '\0' as libc::c_char; + } + + if line != std::ptr::null_mut() && *line != 0 { + maybe_add_history(line); + } + } +} + +#[no_mangle] +pub fn fc_readline(stream: *mut libc::FILE) -> *mut libc::c_char { + let mut c: i32; + let mut line_len: i32 = 0; + let mut lindex: i32 = 0; + let mut line: *mut libc::c_char = std::ptr::null_mut(); + unsafe { + c = libc::fgetc(stream); + while c != libc::EOF { + if (lindex + 2) >= line_len { + line_len += 128; + line = libc::malloc(line_len as libc::size_t) as *mut libc::c_char; + } + + if c == '\n' as i32 { + *((line as usize + (4 * lindex) as usize) as *mut libc::c_char) = + '\n' as libc::c_char; + lindex += 1; + *((line as usize + (4 * lindex) as usize) as *mut libc::c_char) = + '\0' as libc::c_char; + lindex += 1; + return line; + } else { + *((line as usize + (4 * lindex) as usize) as *mut libc::c_char) = c as libc::c_char; + lindex += 1; + } + + c = libc::fgetc(stream); + } + + if lindex == 0 { + if line != std::ptr::null_mut() { + libc::free(line as *mut c_void); + } + return std::ptr::null_mut(); + } + + if lindex + 2 >= line_len { + line = libc::malloc((lindex + 3) as libc::size_t) as *mut libc::c_char; + } + + *((line as usize + (4 * lindex) as usize) as *mut libc::c_char) = '\n' as libc::c_char; + lindex += 1; + *((line as usize + (4 * lindex) as usize) as *mut libc::c_char) = '\0' as libc::c_char; + lindex += 1; + + return line; + } +} diff --git a/utshell-0.5.0/src/builtins/fg_bg.rs b/utshell-0.5.0/src/builtins/fg_bg.rs new file mode 100644 index 00000000..d7d5fd5e --- /dev/null +++ b/utshell-0.5.0/src/builtins/fg_bg.rs @@ -0,0 +1,161 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use std::{ffi::CString, ops::Add}; + +use crate::builtins::common::{get_job_spec, no_options, sh_badjob, sh_nojobs}; +use crate::jobs::start_job; +use crate::src_common::*; + +/* How to bring a job into the foreground. */ +#[no_mangle] +pub fn fg_builtin(list: *mut WordList) -> i32 { + let fg_bit: i32; + unsafe { + CHECK_HELPOPT!(list); + + if job_control == 0 { + sh_nojobs(0 as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + + if no_options(list) != 0 { + return EX_USAGE!(); + } + + /* If the last arg on the line is '&', then start this job in the + background. Else, fg the job. */ + + if loptend == std::ptr::null_mut() { + return fg_bg(loptend, 1); + } else { + let mut t: WordList = *loptend; + while t.next != std::ptr::null_mut() { + t = *(t.next); + } + let cstr: &std::ffi::CStr = std::ffi::CStr::from_ptr((*(t.word)).word); + let mut isfg: bool = char::from(cstr.to_bytes()[0]) == '&'; + isfg = isfg && char::from(cstr.to_bytes()[1]) == '\0'; + isfg = isfg == false; + if isfg { + fg_bit = 1; + } else { + fg_bit = 0; + } + return fg_bg(loptend, fg_bit); + } + } +} + +/* How to put a job into the background. */ +#[no_mangle] +pub fn bg_builtin(list: *mut WordList) -> i32 { + let mut r: i32; + unsafe { + CHECK_HELPOPT!(list); + + if job_control == 0 { + sh_nojobs(0 as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + + if no_options(list) != 0 { + return EX_USAGE!(); + } + + /* This relies on the fact that fg_bg() takes a WordList *, but only acts + on the first member (if any) of that list. */ + r = EXECUTION_SUCCESS!(); + + if fg_bg(loptend, 0) == EXECUTION_FAILURE!() { + r = EXECUTION_FAILURE!(); + } + + if loptend != std::ptr::null_mut() { + let mut t: WordList = *loptend; + while t.next != std::ptr::null_mut() { + if fg_bg(&mut t, 0) == EXECUTION_FAILURE!() { + r = EXECUTION_FAILURE!(); + } + t = *(t.next); + } + return r; + } else { + return r; + } + } +} + +/* How to put a job into the foreground/background. */ +#[no_mangle] +pub fn fg_bg(list: *mut WordList, foreground: i32) -> i32 { + let mut set: nix::sys::signal::SigSet = nix::sys::signal::SigSet::empty(); + let mut oset: nix::sys::signal::SigSet = nix::sys::signal::SigSet::empty(); + let job: i32; + let status: i32; + let mut old_async_pid: i32 = 0; + let j: *mut JOB; + + unsafe { + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + job = get_job_spec(list); + + if INVALID_JOB!(job) { + if job != DUP_JOB!() { + if list != std::ptr::null_mut() { + sh_badjob((*(*list).word).word); + } else { + let c_str_current = CString::new("current").unwrap(); // from a &str, creates a new allocation + sh_badjob(c_str_current.as_ptr() as *mut libc::c_char); + } + } + + UNBLOCK_CHILD_1!(Some(&oset)); + return EXECUTION_FAILURE!(); + } + + j = get_job_by_jid!(job); + /* Or if j->pgrp == shell_pgrp. */ + if !IS_JOBCONTROL!(job) { + let jobNum: i32 = job + 1; + builtin_error( + String::from("job ") + .add(&jobNum.to_string()) + .add(&String::from("started without job control").to_string()) + .as_ptr() as *const libc::c_char, + ); + UNBLOCK_CHILD_1!(Some(&oset)); + return EXECUTION_FAILURE!(); + } + + if foreground == 0 { + old_async_pid = i32::from(last_asynchronous_pid); + last_asynchronous_pid = i32::from((*j).pgrp); /* As per Posix.2 5.4.2 */ + } + + status = start_job(job, foreground); + + if status >= 0 { + /* win: */ + UNBLOCK_CHILD_1!(Some(&oset)); + if foreground != 0 { + return status; + } else { + return EXECUTION_SUCCESS!(); + } + } else { + if foreground == 0 { + last_asynchronous_pid = i32::from(old_async_pid); + } + + UNBLOCK_CHILD_1!(Some(&oset)); + return EXECUTION_FAILURE!(); + } + } +} diff --git a/utshell-0.5.0/src/builtins/getopt.rs b/utshell-0.5.0/src/builtins/getopt.rs new file mode 100644 index 00000000..2fa2f514 --- /dev/null +++ b/utshell-0.5.0/src/builtins/getopt.rs @@ -0,0 +1,157 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +#[no_mangle] +pub fn sh_getopt( + mut argc: libc::c_int, + mut argv: *const *mut libc::c_char, + mut optstring: *const libc::c_char, +) -> libc::c_int { + let mut c: libc::c_char = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + sh_optarg = 0 as *mut libc::c_char; + if sh_optind >= argc || sh_optind < 0 as libc::c_int { + sh_optind = argc; + return -(1 as libc::c_int); + } + if sh_optind == 0 as libc::c_int { + sh_optind = 1 as libc::c_int; + nextchar = 0 as *mut libc::c_void as *mut libc::c_char; + } + if nextchar.is_null() || *nextchar as libc::c_int == '\u{0}' as i32 { + if sh_optind >= argc { + return -(1 as libc::c_int); + } + temp = *argv.offset(sh_optind as isize); + if *temp.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *temp.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + sh_optind += 1; + return -(1 as libc::c_int); + } + if *temp.offset(0 as libc::c_int as isize) as libc::c_int != '-' as i32 + || *temp.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return -(1 as libc::c_int); + } + sh_curopt = sh_optind; + nextchar = (*argv.offset(sh_curopt as isize)).offset(1 as libc::c_int as isize); + sh_charindex = 1 as libc::c_int; + } + let fresh0 = nextchar; + nextchar = nextchar.offset(1); + c = *fresh0; + sh_charindex += 1; + temp = strchr(optstring, c as libc::c_int); + sh_optopt = c as libc::c_int; + if nextchar.is_null() || *nextchar as libc::c_int == '\u{0}' as i32 { + sh_optind += 1; + nextchar = 0 as *mut libc::c_void as *mut libc::c_char; + } + sh_badopt = (temp.is_null() || c as libc::c_int == ':' as i32) as libc::c_int; + if sh_badopt != 0 { + if sh_opterr != 0 { + fprintf( + stderr, + dcgettext( + 0 as *const libc::c_char, + b"%s: illegal option -- %c\n\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + *argv.offset(0 as libc::c_int as isize), + c as libc::c_int, + ); + } + return '?' as i32; + } + if *temp.offset(1 as libc::c_int as isize) as libc::c_int == ':' as i32 { + if !nextchar.is_null() && *nextchar as libc::c_int != 0 { + sh_optarg = nextchar; + sh_optind += 1; + } else if sh_optind == argc { + if sh_opterr != 0 { + fprintf( + stderr, + dcgettext( + 0 as *const libc::c_char, + b"%s: option requires an argument -- %c\n\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + *argv.offset(0 as libc::c_int as isize), + c as libc::c_int, + ); + } + sh_optopt = c as libc::c_int; + sh_optarg = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + c = (if *optstring.offset(0 as libc::c_int as isize) as libc::c_int == ':' as i32 { + ':' as i32 + } else { + '?' as i32 + }) as libc::c_char; + } else { + let fresh1 = sh_optind; + sh_optind = sh_optind + 1; + sh_optarg = *argv.offset(fresh1 as isize); + } + nextchar = 0 as *mut libc::c_void as *mut libc::c_char; + } + } + return c as libc::c_int; +} +#[no_mangle] +pub fn sh_getopt_restore_state(mut argv: *mut *mut libc::c_char) { + unsafe { + if !nextchar.is_null() { + nextchar = (*argv.offset(sh_curopt as isize)).offset(sh_charindex as isize); + } + } +} +#[no_mangle] +pub fn sh_getopt_alloc_istate() -> *mut sh_getopt_state_t { + unsafe { + let mut ret: *mut sh_getopt_state_t = 0 as *mut sh_getopt_state_t; + ret = + malloc((::std::mem::size_of::() as usize)) as *mut sh_getopt_state_t; + return ret; + } +} +#[no_mangle] +pub fn sh_getopt_dispose_istate(mut gs: *mut sh_getopt_state_t) { + unsafe { + free(gs as *mut libc::c_void); + } +} +#[no_mangle] +pub fn sh_getopt_save_istate() -> *mut sh_getopt_state_t { + unsafe { + let mut ret: *mut sh_getopt_state_t = 0 as *mut sh_getopt_state_t; + ret = sh_getopt_alloc_istate(); + let ref mut fresh2 = (*ret).gs_optarg; + *fresh2 = sh_optarg; + (*ret).gs_optind = sh_optind; + (*ret).gs_curopt = sh_curopt; + let ref mut fresh3 = (*ret).gs_nextchar; + *fresh3 = nextchar; + (*ret).gs_charindex = sh_charindex; + (*ret).gs_flags = 0 as libc::c_int; + return ret; + } +} +#[no_mangle] +pub fn sh_getopt_restore_istate(mut state: *mut sh_getopt_state_t) { + unsafe { + sh_optarg = (*state).gs_optarg; + sh_optind = (*state).gs_optind; + sh_curopt = (*state).gs_curopt; + nextchar = (*state).gs_nextchar; + sh_charindex = (*state).gs_charindex; + sh_getopt_dispose_istate(state); + } +} diff --git a/utshell-0.5.0/src/builtins/getopts.rs b/utshell-0.5.0/src/builtins/getopts.rs new file mode 100644 index 00000000..0c69d04a --- /dev/null +++ b/utshell-0.5.0/src/builtins/getopts.rs @@ -0,0 +1,289 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +use super::help::builtin_help; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, make_builtin_argv, number_of_args, sh_invalidid}; +use crate::builtins::getopt::{sh_getopt, sh_getopt_restore_state}; +use crate::general::legal_identifier; +use crate::src_common::*; +use crate::variables::{bind_variable, unbind_variable_noref}; + +/* getopts_reset is magic code for when OPTIND is reset. N is the +value that has just been assigned to OPTIND. */ +#[no_mangle] +pub fn getopts_reset(newind: i32) { + unsafe { + sh_optind = newind; + sh_badopt = 0; + } +} + +#[no_mangle] +pub fn getopts_unbind_variable(name: *mut libc::c_char) -> i32 { + return unbind_variable_noref(name); +} + +fn readonly_p(va: *mut SHELL_VAR) -> i32 { + unsafe { + return (*va).attributes & att_readonly!(); + } +} + +fn noassign_p(va: *mut SHELL_VAR) -> i32 { + unsafe { + return (*va).attributes & att_noassign!(); + } +} + +#[no_mangle] +pub fn getopts_bind_variable(name: *mut libc::c_char, value: *mut libc::c_char) -> i32 { + let v: *mut SHELL_VAR; + unsafe { + if legal_identifier(name) != 0 { + v = bind_variable(name, value, 0); + if v != std::ptr::null_mut() && (readonly_p(v) != 0 || noassign_p(v) != 0) { + return EX_MISCERROR!(); + } + + if v != std::ptr::null_mut() { + return EXECUTION_SUCCESS!(); + } else { + return EXECUTION_FAILURE!(); + } + } else { + sh_invalidid(name); + return EXECUTION_FAILURE!(); + } + } +} + +#[no_mangle] +pub fn dogetopts(argc: i32, argv: *mut *mut libc::c_char) -> i32 { + let mut ret: i32; + let special_error: i32; + let mut old_opterr: i32 = 0; + let mut i: i32; + let n: i32; + + let mut strval: [libc::c_char; 2] = [0; 2]; + let mut numval: [libc::c_char; 16] = [0; 16]; + let mut optstr: *mut libc::c_char; /* list of options */ + let name: *mut libc::c_char; /* variable to get flag val */ + let t: *mut libc::c_char; + unsafe { + let mut argcc: i32 = argc; + let mut argvv: *mut *mut libc::c_char = argv; + if argcc < 3 { + builtin_usage(); + return EX_USAGE; + } + + /* argv[0] is "getopts". */ + optstr = *(argvv.offset(1)); + name = *(argvv.offset(2)); + argcc -= 2; + argvv = argvv.offset(2); + + if *optstr == ':' as libc::c_char { + special_error = 1; + } else { + special_error = 0; + } + + if special_error != 0 { + old_opterr = sh_opterr; + optstr = optstr.offset(1); + sh_opterr = 0; /* suppress diagnostic messages */ + } + + if argcc > 1 { + sh_getopt_restore_state(&mut (*argvv)); + t = *argvv; + *argvv = dollar_vars[0]; + ret = sh_getopt(argcc, argvv, optstr); + *argvv = t; + } else if rest_of_args == std::ptr::null_mut() { + i = 0; + while i < 10 && dollar_vars[i as usize] != std::ptr::null_mut() { + i += 1; + } + + sh_getopt_restore_state(&mut (dollar_vars[0] as *mut libc::c_char)); + ret = sh_getopt(i, &dollar_vars[0], optstr); + } else { + let mut words: *mut WordList; + let v: *mut *mut libc::c_char; + + i = number_of_args() + 1; /* +1 for $0 */ + v = strvec_create(i + 1); + i = 0; + while i < 10 && dollar_vars[i as usize] != std::ptr::null_mut() { + *(v.offset(i as isize)) = dollar_vars[i as usize]; + i += 1; + } + + words = rest_of_args; + while words != std::ptr::null_mut() { + *(v.offset(i as isize)) = (*(*words).word).word; + words = (*words).next; + i += 1; + } + + *(v.offset(i as isize)) = std::ptr::null_mut(); + sh_getopt_restore_state(&mut (*v)); + ret = sh_getopt(i, v, optstr); + libc::free(v as *mut c_void); + } + + if special_error != 0 { + sh_opterr = old_opterr.clone(); + } + + /* Set the OPTIND variable in any case, to handle "--" skipping. It's + highly unlikely that 14 digits will be too few. */ + if sh_optind < 10 { + numval[14] = sh_optind as libc::c_char + '0' as libc::c_char; + numval[15] = '\0' as libc::c_char; + i = 14; + } else { + i = 15; + numval[15] = '\0' as libc::c_char; + n = sh_optind; + + i -= 1; + numval[i as usize] = (n % 10) as libc::c_char + '0' as libc::c_char; + while n / 10 != 0 { + i -= 1; + numval[i as usize] = (n % 10) as libc::c_char + '0' as libc::c_char; + } + } + bind_variable( + CString::new("OPTIND").unwrap().as_ptr(), + &mut numval[i as usize], + 0, + ); + /* If an error occurred, decide which one it is and set the return + code appropriately. In all cases, the option character in error + is in OPTOPT. If an invalid option was encountered, OPTARG is + NULL. If a required option argument was missing, OPTARG points + to a NULL string (that is, sh_optarg[0] == 0). */ + if ret == '?' as i32 { + if sh_optarg == std::ptr::null_mut() { + ret = G_INVALID_OPT!(); + } else if *sh_optarg == '\0' as libc::c_char { + ret = G_ARG_MISSING!(); + } + } + + if ret == G_EOF!() { + getopts_unbind_variable(CString::new("OPTARG").unwrap().as_ptr() as *mut libc::c_char); + getopts_bind_variable( + name, + CString::new("?").unwrap().as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE!(); + } + + if ret == G_INVALID_OPT!() { + /* Invalid option encountered. */ + ret = getopts_bind_variable( + name, + CString::new("?").unwrap().as_ptr() as *mut libc::c_char, + ); + + if special_error != 0 { + strval[0] = sh_optopt as libc::c_char; + strval[1] = '\0' as libc::c_char; + bind_variable( + CString::new("OPTARG").unwrap().as_ptr() as *mut libc::c_char, + &mut strval[0], + 0, + ); + } else { + getopts_unbind_variable( + CString::new("OPTARG").unwrap().as_ptr() as *mut libc::c_char + ); + } + return ret; + } + + if ret == G_ARG_MISSING!() { + /* Required argument missing. */ + if special_error != 0 { + ret = getopts_bind_variable( + name, + CString::new(":").unwrap().as_ptr() as *mut libc::c_char, + ); + + strval[0] = sh_optopt as libc::c_char; + strval[1] = '\0' as libc::c_char; + bind_variable( + CString::new("OPTARG").unwrap().as_ptr() as *mut libc::c_char, + &mut strval[0], + 0, + ); + } else { + ret = getopts_bind_variable( + name, + CString::new("?").unwrap().as_ptr() as *mut libc::c_char, + ); + getopts_unbind_variable( + CString::new("OPTARG").unwrap().as_ptr() as *mut libc::c_char + ); + } + return ret; + } + + bind_variable( + CString::new("OPTARG").unwrap().as_ptr() as *mut libc::c_char, + sh_optarg, + 0, + ); + + strval[0] = ret as libc::c_char; + strval[1] = '\0' as libc::c_char; + return getopts_bind_variable(name, &mut strval[0]); + } +} + +#[no_mangle] +pub fn getopts_builtin(list: *mut WordList) -> i32 { + unsafe { + let av: *mut *mut libc::c_char; + let mut ac: i32 = 0; + let mut ret: i32; + + if list == std::ptr::null_mut() { + builtin_usage(); + return EX_USAGE; + } + + reset_internal_getopt(); + ret = internal_getopt( + list, + CString::new("").unwrap().as_ptr() as *mut libc::c_char, + ); + if ret != -1 { + if ret == GETOPT_HELP!() { + builtin_help(); + } else { + builtin_usage(); + } + + return EX_USAGE; + } + let llist: *mut WordList = loptend.clone(); + av = make_builtin_argv(llist, &mut ac); + ret = dogetopts(ac, av); + libc::free(av as *mut c_void); + + return ret; + } +} diff --git a/utshell-0.5.0/src/builtins/hash.rs b/utshell-0.5.0/src/builtins/hash.rs new file mode 100644 index 00000000..3f48d131 --- /dev/null +++ b/utshell-0.5.0/src/builtins/hash.rs @@ -0,0 +1,346 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::alias::all_aliases; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_usage, find_shell_builtin, sh_needarg, sh_notfound, sh_restricted, +}; +use crate::findcmd::{executable_file, find_user_command, is_directory}; +use crate::general::{absolute_program, printable_filename}; +use crate::hashcmd::{phash_flush, phash_insert, phash_remove, phash_search}; +use crate::hashlib::hash_walk; +use crate::src_common::*; +use crate::variables::find_function; +use crate::version::shell_compatibility_level; + +static mut common_inode: libc::c_int = 0; + +/* Print statistics on the current state of hashed commands. If LIST is +not empty, then rehash (or hash in the first place) the specified +commands. */ +#[no_mangle] +pub fn hash_builtin(mut list: *mut WordList) -> i32 { + let mut expunge_hash_table: i32; + let mut list_targets: i32; + let mut list_portably: i32; + let mut delete: i32; + let mut opt: i32; + let mut w: *mut libc::c_char; + let mut pathname: *mut libc::c_char; + unsafe { + if hashing_enabled == 0 { + let c_str = CString::new("hashing disabled").unwrap(); + let c_str_ptr = c_str.as_ptr(); + builtin_error(c_str_ptr); + return EXECUTION_FAILURE!(); + } + expunge_hash_table = 0; + list_targets = 0; + list_portably = 0; + delete = 0; + pathname = std::ptr::null_mut(); + reset_internal_getopt(); + let opts = CString::new("dlp:rt").unwrap(); + opt = internal_getopt(list, opts.as_ptr() as *mut libc::c_char); + while opt != -1 { + let optu8 = opt as u8; + let opt_char = char::from(optu8); + match opt_char { + 'd' => delete = 1, + 'l' => list_portably = 1, + 'p' => pathname = list_optarg, + 'r' => expunge_hash_table = 1, + 't' => list_targets = 1, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opts.as_ptr() as *mut libc::c_char); + } + list = loptend; + /* hash -t requires at least one argument. */ + if list == std::ptr::null_mut() && (delete != 0 || list_targets != 0) { + let temp: CString; + let temp_ptr: *mut libc::c_char; + if delete != 0 { + temp = CString::new("-d").unwrap(); + temp_ptr = temp.as_ptr() as *mut libc::c_char; + sh_needarg(temp_ptr); + } else { + temp = CString::new("-t").unwrap(); + temp_ptr = temp.as_ptr() as *mut libc::c_char; + sh_needarg(temp_ptr); + } + return EXECUTION_FAILURE!(); + } + + /* We want hash -r to be silent, but hash -- to print hashing info, so + we test expunge_hash_table. */ + if list == std::ptr::null_mut() && expunge_hash_table == 0 { + opt = print_hashed_commands(list_portably); + if opt == 0 + && posixly_correct == 0 + && (list_portably == 0 || shell_compatibility_level <= 50) + { + let s_cstr = CStr::from_ptr(this_command_name); + let s_str = s_cstr.to_str().unwrap(); + let s_string = s_str.to_owned(); + println!("{}:hash table empty", s_string); + } + return EXECUTION_SUCCESS!(); + } + if expunge_hash_table != 0 { + phash_flush(); + } + /* If someone runs `hash -r -t xyz' he will be disappointed. */ + if list_targets != 0 { + return list_hashed_filename_targets(list, list_portably); + } + if restricted != 0 && pathname != std::ptr::null_mut() { + if strchr(pathname, '/' as libc::c_int) != std::ptr::null_mut() { + sh_restricted(pathname); + return EXECUTION_FAILURE!(); + } + /* If we are changing the hash table in a restricted shell, make sure the + target pathname can be found using a $PATH search. */ + w = find_user_command(pathname); + if w == std::ptr::null_mut() || *w == 0 || executable_file(w) == 0 { + sh_notfound(pathname); + free(w as *mut c_void); + return EXECUTION_FAILURE!(); + } + free(w as *mut c_void); + } + opt = EXECUTION_SUCCESS!(); + while list != std::ptr::null_mut() { + /* Add, remove or rehash the specified commands. */ + w = (*(*list).word).word; + if absolute_program(w as *const libc::c_char) != 0 { + continue; + } else if pathname != std::ptr::null_mut() { + if is_directory(pathname) != 0 { + let c_err = CString::new("%s:%s").unwrap(); + let c_err_ptr = c_err.as_ptr(); + builtin_error(c_err_ptr, pathname, strerror(EISDIR)); + opt = EXECUTION_SUCCESS!(); + } else { + if legal_hash_rust(w, pathname) == 0 { + phash_insert(w, pathname, 0, 0); + } + } + } else if delete != 0 { + if phash_remove(w) != 0 { + sh_notfound(w); + opt = EXECUTION_FAILURE!(); + } + } else if add_hashed_command(w, 0) != 0 { + opt = EXECUTION_FAILURE!(); + } + list = (*list).next; + } + std::io::stdout().flush(); + return opt; + } //unsafe +} +fn add_hashed_command(w: *mut libc::c_char, quiet: i32) -> i32 { + let mut rv: i32; + let full_path: *mut libc::c_char; + rv = 0; + unsafe { + if find_function(w).is_null() && find_shell_builtin(w).is_none() { + // if find_function(w).is_null() && r_find_shell_builtin(w).is_null(){ + phash_remove(w); + full_path = find_user_command(w); + if full_path != std::ptr::null_mut() && executable_file(full_path) != 0 { + phash_insert(w, full_path, dot_found_in_search, 0) + } else { + if quiet == 0 { + sh_notfound(w); + } + rv += 1; + } + FREE!(full_path); + } + return rv; + } //unsafe +} +fn print_hash_info(item: *mut BUCKET_CONTENTS) -> i32 { + unsafe { + let path_string = CStr::from_ptr((*pathdata!(item)).path).to_str().unwrap(); + println!("{:04}\t{}", (*item).times_found, path_string); + } //unsafe + 0 +} +#[no_mangle] +fn print_portable_hash_info(item: *mut BUCKET_CONTENTS) -> i32 { + let fp: *mut libc::c_char; + let f: *mut libc::c_char; + unsafe { + fp = printable_filename((*pathdata!(item)).path, 1); + f = printable_filename((*item).key, 1); + let fp_string = CStr::from_ptr(fp).to_str().unwrap(); + let f_string = CStr::from_ptr(f).to_str().unwrap(); + println!("builtin hash -p {} {}", fp_string, f_string); + if fp != (*pathdata!(item)).path { + free(fp as *mut c_void); + } + if f != (*item).key { + free(f as *mut c_void); + } + return 0; + } //unsafe +} +#[no_mangle] +fn print_hashed_commands(fmt: i32) -> i32 { + unsafe { + if hashed_filenames.is_null() || hash_entries(hashed_filenames) == 0 { + return 0; + } + if fmt == 0 { + println!("hits\tcommand"); + } + let fmt_t: hash_wfunc; + if fmt != 0 { + fmt_t = print_portable_hash_info; + } else { + fmt_t = print_hash_info; + } + hash_walk(hashed_filenames, Some(fmt_t)); + return 1; + } +} +#[no_mangle] +fn list_hashed_filename_targets(list: *mut WordList, fmt: i32) -> i32 { + let mut all_found: i32; + let multiple: i32; + let mut target: *mut libc::c_char; + let mut l: *mut WordList; + all_found = 1; + + unsafe { + if !(*list).next.is_null() { + multiple = 1; + } else { + multiple = 0; + } + l = list; + while !l.is_null() { + target = phash_search((*(*l).word).word); + if target.is_null() { + all_found = 0; + sh_notfound((*(*l).word).word); + continue; + } + if fmt != 0 { + let target_string = CStr::from_ptr(target).to_str().unwrap(); + let c_str = CStr::from_ptr((*(*l).word).word).to_str().unwrap(); + println!("builtin hash -p {} {}", target_string, c_str) + } else { + if multiple != 0 { + let c_str = CStr::from_ptr((*(*l).word).word).to_str().unwrap(); + print!("{}\t", c_str); + } + let target_str = CStr::from_ptr(target).to_str().unwrap(); + println!("{}", target_str); + } + free(target as *mut c_void); + l = (*l).next; + } + + if all_found != 0 { + return EXECUTION_SUCCESS!(); + } else { + return EXECUTION_FAILURE!(); + } + } +} +fn legal_hash_rust(name: *mut libc::c_char, value: *mut libc::c_char) -> libc::c_int { + let alias_list: *mut *mut AliasT = all_aliases(); + let mut t: *mut AliasT; + let mut offset; + let name_w: *mut libc::c_char; + let target: *mut libc::c_char; + offset = 0; + if !alias_list.is_null() { + unsafe { + t = *alias_list.offset(offset as isize); + while !t.is_null() { + if !(*t).name.is_null() { + if libc::strcmp(name, (*t).name) == 0 { + println!("Prohibit setting existing variables that is already in alias"); + println!( + "{} = {}", + CStr::from_ptr((*t).name).to_string_lossy().into_owned(), + CStr::from_ptr((*t).value).to_string_lossy().into_owned() + ); + return 1; + } + } + offset += 1; + t = *alias_list.offset(offset as isize); + } + } + } + // if find_shell_builtin(name) != std::ptr::null_mut() { + unsafe { + if find_shell_builtin(name).is_some() { + //䏿˜¯ç©º + println!( + "Prohibit setting existing variables {} is a shell builtin", + CStr::from_ptr(name).to_string_lossy().into_owned() + ); + return 1; + } else if find_function(name) != std::ptr::null_mut() { + println!( + "Prohibit setting existing variables {} is a function", + CStr::from_ptr(name).to_string_lossy().into_owned() + ); + return 1; + } + } + name_w = find_user_command(name); + if name_w != std::ptr::null_mut() { + unsafe { + file_inode( + CStr::from_ptr(name_w).to_str().unwrap(), + CStr::from_ptr(value).to_str().unwrap(), + ); + if common_inode == 1 { + return 1; + } + } + } + target = phash_search(name); + unsafe { + if target != std::ptr::null_mut() { + println!( + "{} is already in hash", + CStr::from_ptr(name).to_string_lossy().into_owned() + ); + return 1; + } + } + return 0; +} + +fn file_inode(pathname: &str, pathname2: &str) -> std::io::Result<()> { + let meta = std::fs::metadata(pathname)?; + let meta2 = std::fs::metadata(pathname2)?; + unsafe { + common_inode = 0; + if meta.st_ino() != meta2.st_ino() { + println!("The name and value point to different executable files"); + common_inode = 1; + } + Ok(()) + } +} diff --git a/utshell-0.5.0/src/builtins/help.rs b/utshell-0.5.0/src/builtins/help.rs new file mode 100644 index 00000000..88cbf18a --- /dev/null +++ b/utshell-0.5.0/src/builtins/help.rs @@ -0,0 +1,500 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::builtins::current_builtin; +use crate::builtins::common::{builtin_address_internal, builtin_usage, get_local_str}; +use crate::general::default_columns; +use crate::sig::{termsig_handler, throw_to_top_level}; +use crate::src_common::*; +use crate::version::{bash_copyright, bash_license, show_shell_version}; + +pub enum Option { + None, + Some(T), +} +extern "C" { + fn __ctype_get_mb_cur_max() -> size_t; + fn xstrmatch( + string1: *mut libc::c_char, + string2: *mut libc::c_char, + i: libc::c_char, + ) -> libc::c_char; +} + +#[no_mangle] +pub fn help_builtin(mut list: *mut WordList) -> i32 { + // let mut i:i32; + let mut plen: usize; + let mut _match_found: i32; + let mut sflag: i32 = 0; + let mut dflag: i32 = 0; + let mut mflag: i32 = 0; + let mut m: bool; + let _pass: i32 = 0; + let mut _this_found: i32; + let mut _pattern: *mut libc::c_char; + let mut _name: *mut libc::c_char; + let _l: *mut WordList = list; + let mut i: i32; + + reset_internal_getopt(); + + let c_str_dms = CString::new("dms").unwrap(); // from a &str, creates a new allocation + + i = internal_getopt(list, c_str_dms.as_ptr() as *mut libc::c_char); + + while i != -1 { + let optu8: u8 = i as u8; + let optChar: char = char::from(optu8); + match optChar { + 'd' => { + dflag = 1; + } + 'm' => { + mflag = 1; + } + 's' => { + sflag = 1; + } + _ => { + if i == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + + i = internal_getopt(list, c_str_dms.as_ptr() as *mut libc::c_char); + } + + if list == std::ptr::null_mut() { + unsafe { + show_shell_version(0); + } + + show_builtin_command_help(); + return EXECUTION_SUCCESS!(); + } + + unsafe { + let mut pattern = 0; + pattern = glob_pattern_p((*(*list).word).word); + if pattern == 1 { + println!("Shell commands matching keyword, Shell commands matching keyword"); + if list != std::ptr::null_mut() && (*list).next != std::ptr::null_mut() { + println!("Shell commands matching keywords"); + } else { + println!("Shell commands matching keyword"); + } + println!("{:?} ,", list); + } + // let mut loptendt=*list; + + let mut match_found = 0; + let mut pattern: *mut libc::c_char = 0 as *mut libc::c_char; + while list != std::ptr::null_mut() { + pattern = (*(*list).word).word; + plen = libc::strlen(pattern); + let mut this_found = 0; + let mut v: Vec<*mut libc::c_char> = Vec::new(); + for val in 0..=75 { + //let nname = &shell_builtins[val].name; + let builtin1 = &(*((shell_builtins as usize + (val * BUILTIN_SIZEOF!()) as usize) + as *mut builtin)); + if builtin1.name != std::ptr::null_mut() { + v.push(builtin1.name); + } + } + for val in 1..3 { + //for &mut namee in &mut v { + for i in 0..v.len() { + QUIT(); + /* First val: look for exact string or pattern matches. + Second val: look for prefix matches like bash-4.2 */ + if val == 1 { + m = (libc::strcmp(pattern, v[i]) == 0) + || (strmatch(pattern, v[i], FNMATCH_EXTFLAG!() as libc::c_char) != FNM_NOMATCH!()); + //FNMATCH_EXTFLAG C çš„å®å¹¶ä¸æ˜¯0ï¼Œé‡æž„åŽä¸ºå•¥æ˜¯0了呢? + } else { + m = libc::strncmp(pattern, v[i], plen) == 0; + } + if m { + this_found = 1; + match_found = match_found + 1; + if dflag == 1 { + show_desc(i as i32); + continue; + } else if mflag == 1 { + show_manpage(v[i], i as i32); + continue; + } + let builtin1 = &(*((shell_builtins as usize + + (i * BUILTIN_SIZEOF!()) as usize) + as *mut builtin)); + print!("{:?}:", CStr::from_ptr(builtin1.name)); + show_helpsynopsis(i as i32); + if sflag == 0 { + show_longdoc(i as i32); + } + } + } + if val == 1 && this_found == 1 { + break; + } + } + if (*list).next != std::ptr::null_mut() { + list = (*list).next; + } else { + break; + } + } + if match_found == 0 { + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + let _s1 = String::from("command"); + args.set("name", format!("{:?}", CStr::from_ptr(pattern))); + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message("helperr").unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!("utshell: help: {}", msg1); + return EXECUTION_FAILURE!(); + } + } + + std::io::stdout().flush(); + + return EXECUTION_SUCCESS!(); +} + +#[no_mangle] +pub fn help_null_builtin(_list: *mut WordList) -> i32 { + unsafe { + show_shell_version(0); + } + show_builtin_command_help(); + return EXECUTION_SUCCESS!(); +} + +fn QUIT() { + unsafe { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + + if interrupt_state != 0 { + throw_to_top_level(); + } + } +} + +pub fn builtin_help() { + // print all command usage + let mut ind: i32 = 5; + let d: i32; + unsafe { + current_builtin = builtin_address_internal(this_command_name, 0); + if current_builtin == 0 as *mut builtin { + return; + } + + d = (current_builtin as usize - shell_builtins as usize) as i32; + } + ind = d / BUILTIN_SIZEOF!(); + unsafe { + print!("{}:", CStr::from_ptr(this_command_name).to_str().unwrap()); + } + show_helpsynopsis(ind); + show_longdoc(ind); +} + +fn open_helpfile(name: *mut libc::c_char) -> i32 { + let fd: i32; + unsafe { + fd = open(name, 0); + } + if fd == -1 { + return -1; + } else { + fd + } +} + +fn show_longdoc(i: i32) { + let builtin1 = unsafe { + &(*((shell_builtins as usize + (i * BUILTIN_SIZEOF!()) as usize) as *mut builtin)) + }; + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + let c_str: &CStr = unsafe { CStr::from_ptr(builtin1.name) }; + let s1 = String::from("command"); + match i { + 0 | 1 | 2 | 3 | 4 | 5 => { + args.set("cmdName", format!("{}{}", s1, i)); + } + 33 => args.set("cmdName", format!("{}{}", s1, 6)), + 75 => args.set("cmdName", format!("{}{}", s1, 7)), + _ => { + let msg: &str = c_str.to_str().unwrap(); + args.set("cmdName", msg); + } + } + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message("helplongdoc").unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!(" {}", msg1); +} + +fn show_helpsynopsis(i: i32) { + let builtin1 = unsafe { + &(*((shell_builtins as usize + (i * BUILTIN_SIZEOF!()) as usize) as *mut builtin)) + }; + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + let c_str: &CStr = unsafe { CStr::from_ptr(builtin1.name) }; + let s1 = String::from("command"); + match i { + 0 | 1 | 2 | 3 | 4 | 5 => { + args.set("cmdName", format!("{}{}", s1, i)); + } + 33 => args.set("cmdName", format!("{}{}", s1, 6)), + 75 => args.set("cmdName", format!("{}{}", s1, 7)), + _ => { + let msg: &str = c_str.to_str().unwrap(); + args.set("cmdName", msg); + } + } + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message("helpsynopsis").unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!(" {}", msg1); +} + +fn show_desc(i: i32) { + let builtin1 = unsafe { + &(*((shell_builtins as usize + (i * BUILTIN_SIZEOF!()) as usize) as *mut builtin)) + }; + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + let c_str: &CStr = unsafe { CStr::from_ptr(builtin1.name) }; + let s1 = String::from("command"); + match i { + 0 | 1 | 2 | 3 | 4 | 5 => { + args.set("cmdName", format!("{}{}", s1, i)); + } + 33 => args.set("cmdName", format!("{}{}", s1, 6)), + 75 => args.set("cmdName", format!("{}{}", s1, 7)), + _ => { + let msg: &str = c_str.to_str().unwrap(); + args.set("cmdName", msg); + } + } + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message("helpname").unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!(" {}", msg1); +} + +fn show_manpage(_name: *mut libc::c_char, i: i32) { + /* NAME */ + println!("NAME\n"); + show_desc(i); + + /* SYNOPSIS */ + println!("SYNOPSIS\n"); + show_helpsynopsis(i); + println!("DESCRIPTION\n"); + show_longdoc(i); + /* SEE ALSO */ + println!("SEE ALSO\n"); + println!(" utshell(1) {} \n\n", " "); + + /* IMPLEMENTATION */ + println!("IMPLEMENTATION\n"); + println!(" "); + unsafe { + show_shell_version(0); + } + println!(" "); + unsafe { + println!("{:?}", CStr::from_ptr(bash_copyright)); + } + println!(" "); + unsafe { + println!("{:?}", CStr::from_ptr(bash_license)); + } +} + +#[no_mangle] +pub fn dispcolumn( + i: i32, + buf: *mut libc::c_char, + _bufsize: libc::c_int, + width: usize, + height: i32, +) { + let mut _j: i32; + let dispcols: usize; + let mut helpdoc: *mut libc::c_char; + /* first column */ + let mut builtin1 = unsafe { + &(*((shell_builtins as usize + (i * BUILTIN_SIZEOF!()) as usize) as *mut builtin)) + }; + helpdoc = builtin1.short_doc as *mut libc::c_char; + unsafe { + libc::strncpy( + (buf as usize + 4 as usize) as *mut libc::c_char, + helpdoc, + width - 2, + ); + *((buf as usize + (width - 2) as usize) as *mut libc::c_char) = '>' as libc::c_char; + *((buf as usize + (width - 1) as usize) as *mut libc::c_char) = '\0' as libc::c_char; + } + /* indicate truncation */ + println!("{:?}", buf); + unsafe { + if ((i << 1) >= num_shell_builtins) || (i + height >= num_shell_builtins) { + println!("\n"); + return; + } + } + dispcols = unsafe { libc::strlen(buf) }; + /* two spaces */ + for _j in dispcols..width { + std::io::stdout().write(b" "); + } + /* second column */ + builtin1 = unsafe { + &(*((shell_builtins as usize + (((i + height) * BUILTIN_SIZEOF!()) as usize)) + as *mut builtin)) + }; + helpdoc = builtin1.short_doc as *mut libc::c_char; + unsafe { + if builtin1.flags != 0 && BUILTIN_ENABLED!() == 1 { + //修改过,原为if builtin1.flags && BUILTIN_ENABLED!() == 1 + *((buf as usize) as *mut libc::c_char) = ' ' as libc::c_char; + } else { + *((buf as usize) as *mut libc::c_char) = '*' as libc::c_char; + } + libc::strncpy( + (buf as usize + 4 as usize) as *mut libc::c_char, + helpdoc, + width - 3, + ); + *((buf as usize + (width - 3) as usize) as *mut libc::c_char) = '>' as libc::c_char; + *((buf as usize + (width - 2) as usize) as *mut libc::c_char) = '\0' as libc::c_char; + } + println!("{:?}\n", buf); +} + +pub fn wdispcolumn(i: i32, _buf: *mut libc::c_char, _bufsize: i32, _width: i32, _height: i32) { + let mut _j: i32; + show_helpsynopsis(i); +} + +fn show_builtin_command_help() { + // println!("enter show_builtin_command_help"); + let mut _i: i32; + let mut _j: i32; + let height: i32 = 76; + let mut width: usize; + let mut _t: *mut libc::c_char; + let mut blurb: [libc::c_char; 128] = ['0' as libc::c_char; 128]; + + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message("information").unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + let msg1 = bundle.format_pattern(&pattern, None, &mut errors); + println!("{}\n", msg1); + //println!("{}",("These shell commands are defined internally. Type `help' to see this list.\n Type `help name' to find out more about the function `name'.\n Use `info bash' to find out more about the shell in general.\n Use `man -k' or `info' to find out more about commands not in this list.\n A star (*) next to a name means that the command is disabled.\n")); + + let ref2: &mut libc::c_char = &mut blurb[0]; + + unsafe { + width = default_columns() as usize; + } + width /= 2; + if width > (std::mem::size_of::() * 128) { + width = std::mem::size_of::() * 128; + } + + if width <= 3 { + width = 40; + } + for i in 0..height { + QUIT(); + + unsafe { + if __ctype_get_mb_cur_max() > 1 { + let ptr2: *mut libc::c_char = ref2 as *mut libc::c_char; + wdispcolumn(i, ptr2, 128, width as i32, height); + } + } + } +} +//#endif /* HELP_BUILTIN */ +fn strmatch( + pattern: *mut libc::c_char, + string: *mut libc::c_char, + flags: libc::c_char, +) -> libc::c_char { + if ((string as usize) as *mut libc::c_char != std::ptr::null_mut()) + || ((pattern as usize) as *mut libc::c_char != std::ptr::null_mut()) + { + return FNM_NOMATCH!(); + } + return unsafe { xstrmatch(pattern, string, flags) }; +} + +struct Thing { + pointer_to_self: *mut Thing, +} + +fn xmalloc(size: usize) -> *mut c_void { + let ret: *mut c_void; + unsafe { + ret = libc::malloc(size); + } + // if (ret == 0) { + // println!("man2html: out of memory"); + // // fprintf(stderr, "man2html: out of memory"); + // (1) + // } + ret +} + +/* +fn wcswidth(pwcs : *mut libc::wchar_t , n : i32) -> i32{ + let mut wc : libc::wchar_t; + let mut len : i32 = 0; + let mut l : i32; + + while n-1 > 0 && *(pwcs as usize + 1 as usize) != '\0' as libc::wchar_t{ + wc = *(pwcs += 1); + if wcwidth(wc) < 0 { + return -1; + } + len += l; + } + len +} +*/ diff --git a/utshell-0.5.0/src/builtins/history.rs b/utshell-0.5.0/src/builtins/history.rs new file mode 100644 index 00000000..597d9f25 --- /dev/null +++ b/utshell-0.5.0/src/builtins/history.rs @@ -0,0 +1,412 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::bashhist::{bash_clear_history, bash_delete_history_range, maybe_append_history}; +use crate::bashhist::{bash_delete_histent, bash_delete_last_history, check_add_history}; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_usage, get_numeric_arg, sh_chkwrite, sh_erange, sh_restricted, +}; +use crate::general::legal_number; +use crate::readline::{history_get_time, read_history_range}; +use crate::sig::{termsig_handler, throw_to_top_level}; +use crate::src_common::*; +use crate::subst::string_list; +use crate::variables::get_string_value; +use crate::y_tab::current_command_line_count; + +#[no_mangle] +pub fn history_builtin(mut list: *mut WordList) -> i32 { + let mut flags: libc::c_int = 0; + let mut opt: libc::c_int; + let mut result: libc::c_int; + + let filename: *mut libc::c_char; + let mut delete_arg: *mut libc::c_char = PT_NULL as *mut libc::c_char; + let mut range: *mut libc::c_char; + + let mut delete_offset: libc::c_long = 0; + + unsafe { + reset_internal_getopt(); + let opt_str = CString::new("acd:npsrw").unwrap(); + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'a' => flags |= AFLAG, + 'c' => flags |= CFLAG, + 'n' => flags |= NFLAG, + 'r' => flags |= RFLAG, + 'w' => flags |= WFLAG, + 's' => flags |= SFLAG_H, + 'd' => { + flags |= DFLAG_H; + delete_arg = list_optarg; + } + 'p' => flags |= PFLAG_H, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + } + list = loptend; + + opt = flags & (AFLAG | RFLAG | WFLAG | NFLAG); + if opt != 0 && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG { + let c_err = CString::new("cannot use more than one of -anrw").unwrap(); + builtin_error(c_err.as_ptr()); + return EXECUTION_FAILURE; + } + + if (flags & CFLAG) != 0 { + bash_clear_history(); + if list.is_null() { + return EXECUTION_SUCCESS; + } + } + + if (flags & SFLAG_H) != 0 { + if !list.is_null() { + push_history(list); + } + return EXECUTION_SUCCESS; + } else if (flags & PFLAG_H) != 0 { + if !list.is_null() { + return expand_and_print_history(list); + } + return sh_chkwrite(EXECUTION_SUCCESS); + } else if (flags & DFLAG_H) != 0 { + let c_tmp = if *delete_arg == b'-' as libc::c_char { + delete_arg.offset(1 as isize) as *mut libc::c_char + } else { + delete_arg + }; + range = libc::strchr(c_tmp, b'-' as libc::c_int); + if !range.is_null() { + let mut delete_start: libc::c_long = 0; + let mut delete_end: libc::c_long = 0; + + *range = b'\0' as libc::c_char; + range = (range as usize + 1) as *mut libc::c_char; + if legal_number(delete_arg, std::mem::transmute(&delete_start)) == 0 + || legal_number(range, std::mem::transmute(&delete_end)) == 0 + { + *((range as usize - 1) as *mut libc::c_char) = b'-' as libc::c_char; + sh_erange( + delete_arg, + "history position\0".as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE; + } + if *delete_arg == b'-' as libc::c_char && delete_start < 0 { + delete_start += history_length as libc::c_long; + if delete_start < history_base as libc::c_long { + sh_erange( + delete_arg, + "history position\0".as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE; + } + } else if delete_start > 0 { + delete_start -= history_base as libc::c_long; + } + if delete_start < 0 || delete_start >= history_length as libc::c_long { + sh_erange( + delete_arg, + "history position\0".as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE; + } + if *range == b'-' as libc::c_char && delete_end < 0 { + delete_end += history_length as libc::c_long; + if delete_end < history_base as libc::c_long { + sh_erange(range, "history position\0".as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE; + } + } else if delete_end > 0 { + delete_end -= history_base as libc::c_long; + } + + if delete_end < 0 || delete_end >= history_length as libc::c_long { + sh_erange(range, "history position\0".as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE; + } + result = bash_delete_history_range( + delete_start as libc::c_int, + delete_end as libc::c_int, + ); + if where_history() > history_length { + history_set_pos(history_length); + } + + return if result != 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; + } else if (flags & DFLAG_H) != 0 { + if legal_number(delete_arg, &mut delete_offset) == 0 { + sh_erange( + delete_arg, + "history position\0".as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE; + } + + if *delete_arg == b'-' as libc::c_char && delete_offset < 0 { + let ind = history_length + delete_offset as libc::c_int; + if ind < history_base { + sh_erange( + delete_arg, + "history position\0".as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE; + } + opt = ind + history_base; + } else if delete_offset < history_base as libc::c_long + || (delete_offset >= (history_base + history_length) as libc::c_long) + { + sh_erange( + delete_arg, + "history position\0".as_ptr() as *mut libc::c_char, + ); + return EXECUTION_FAILURE; + } else { + opt = delete_offset as libc::c_int; + } + result = bash_delete_histent(opt - history_base); + if where_history() > history_length { + history_set_pos(history_length); + } + return if result != 0 { + EXECUTION_FAILURE + } else { + EXECUTION_SUCCESS + }; + } + } else if (flags & (AFLAG | RFLAG | NFLAG | WFLAG | CFLAG)) == 0 { + result = display_history(list); + return sh_chkwrite(result); + } + + filename = if !list.is_null() { + (*((*list).word)).word + } else { + get_string_value("HISTFILE\0".as_ptr() as *mut libc::c_char) + }; + result = EXECUTION_SUCCESS; + + if restricted != 0 && !(libc::strchr(filename, b'/' as libc::c_int).is_null()) { + sh_restricted(filename); + return EXECUTION_FAILURE; + } + if (flags & AFLAG) != 0 { + result = maybe_append_history(filename); + } else if (flags & WFLAG) != 0 { + result = write_history(filename); + } else if (flags & RFLAG) != 0 { + result = read_history(filename); + history_lines_in_file = history_lines_read_from_file; + } else if (flags & NFLAG) != 0 { + let old_history_lines = history_lines_in_file; + let obase = history_base; + + using_history(); + result = read_history_range(filename, history_lines_in_file, -1); + using_history(); + + history_lines_in_file = history_lines_read_from_file; + if force_append_history == 0 { + history_lines_this_session += + history_lines_in_file - old_history_lines + history_base - obase; + } + } + } + + return if result != 0 { + EXECUTION_FAILURE + } else { + EXECUTION_SUCCESS + }; +} + +fn histtime(hlist: *mut HIST_ENTRY, histtimefmt: *const libc::c_char) -> *mut libc::c_char { + unsafe { + static mut timestr: [libc::c_char; 128] = [0; 128]; + + let t = history_get_time(hlist); + let tm = if t != 0 { + libc::localtime(&t) + } else { + PT_NULL as *mut libc::tm + }; + if t != 0 && !tm.is_null() { + strftime( + std::mem::transmute(×tr), + std::mem::size_of_val(×tr), + histtimefmt, + tm, + ); + } else if !(*hlist).timestamp.is_null() && (*(*hlist).timestamp) != 0 { + let c_str = CString::new("%s: invalid timestamp").unwrap(); + libc::snprintf( + std::mem::transmute(×tr), + std::mem::size_of_val(×tr), + c_str.as_ptr(), + if *((*hlist).timestamp) == b'#' as libc::c_char { + ((*hlist).timestamp as usize + 1) as *mut libc::c_char + } else { + (*hlist).timestamp + }, + ); + } else { + libc::strcpy( + std::mem::transmute(×tr), + b"??\0".as_ptr() as *const libc::c_char, + ); + } + + return timestr.as_mut_ptr(); + } +} + +fn quit() { + unsafe { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + } +} +fn display_history(list: *mut WordList) -> libc::c_int { + let mut limit: libc::c_long = 0; + let histtimefmt: *mut libc::c_char; + let mut timestr: *mut libc::c_char; + + if !list.is_null() { + if get_numeric_arg(list, 0, &mut limit) == 0 { + return EXECUTION_FAILURE; + } + if limit < 0 { + limit = -limit; + } + } else { + limit = -1; + } + let hlist = unsafe { history_list() }; + + if !hlist.is_null() { + let mut i: libc::c_long = 0; + unsafe { + while !(*hlist.offset(i as isize)).is_null() { + i += 1; + } + } + i = if 0 <= limit && limit < i { + i - limit + } else { + 0 + }; + unsafe { + histtimefmt = get_string_value(b"HISTTIMEFORMAT\0" as *const u8 as *const libc::c_char); + + while !(*hlist.offset(i as isize)).is_null() { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + timestr = if !histtimefmt.is_null() && *histtimefmt as libc::c_int != 0 { + histtime(*hlist.offset(i as isize), histtimefmt) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + printf( + b"%5d%c %s%s\n\0" as *const u8 as *const libc::c_char, + i + history_base as libc::c_long, + if !((**hlist.offset(i as isize)).data).is_null() { + '*' as i32 + } else { + ' ' as i32 + }, + if !timestr.is_null() && *timestr as libc::c_int != 0 { + timestr + } else { + b"\0" as *const u8 as *const libc::c_char + }, + (**hlist.offset(i as isize)).line, + ); + i += 1; + } + } + } + return EXECUTION_SUCCESS; +} + +fn push_history(list: *mut WordList) { + unsafe { + if remember_on_history != 0 + && hist_last_line_pushed == 0 + && (hist_last_line_added != 0 + || (current_command_line_count > 0 + && current_command_first_line_saved != 0 + && command_oriented_history != 0)) + && bash_delete_last_history() == 0 + { + return; + } + + let s = string_list(list); + check_add_history(s, 1); + + hist_last_line_pushed = 1; + libc::free(s as *mut c_void); + } +} + +fn expand_and_print_history(mut list: *mut WordList) -> libc::c_int { + unsafe { + let s: *mut libc::c_char = PT_NULL as *mut libc::c_char; + let mut result: libc::c_int; + + if hist_last_line_pushed == 0 + && hist_last_line_added != 0 + && bash_delete_last_history() == 0 + { + return EXECUTION_FAILURE; + } + result = EXECUTION_SUCCESS; + while !list.is_null() { + let r = history_expand((*((*list).word)).word, std::mem::transmute(&s)); + if r < 0 { + let c_err = CString::new("%s: history expansion failed").unwrap(); + builtin_error(c_err.as_ptr(), (*((*list).word)).word); + result = EXECUTION_FAILURE; + } else { + println!("{}", CStr::from_ptr(s).to_str().unwrap()); + //println!("{}",String::from(CStr::from_ptr(s).to_str().unwrap())); + //std::io::stdout().lock().write_all(CStr::from_ptr(s).to_bytes()).unwrap(); + //libc::putchar(b'\n' as libc::c_int); + } + if !s.is_null() { + libc::free(s as *mut c_void); + } + list = (*list).next; + } + std::io::stdout().lock().flush().unwrap(); + return result; + } +} diff --git a/utshell-0.5.0/src/builtins/jobs.rs b/utshell-0.5.0/src/builtins/jobs.rs new file mode 100644 index 00000000..503c8f61 --- /dev/null +++ b/utshell-0.5.0/src/builtins/jobs.rs @@ -0,0 +1,278 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, get_job_spec, sh_badjob}; +use crate::copycmd::copy_word_list; +use crate::dispose_cmd::dispose_command; +use crate::execute_cmd::execute_command; +use crate::general::legal_number; +use crate::jobs::{ + delete_all_jobs, delete_job, get_job_by_pid, list_all_jobs, list_one_job, list_running_jobs, + list_stopped_jobs, nohup_all_jobs, nohup_job, +}; +use crate::make_cmd::make_bare_simple_command; +use crate::src_common::*; +use crate::unwind_prot::{add_unwind_protect, begin_unwind_frame, discard_unwind_frame}; + +#[no_mangle] +pub fn execute_list_with_replacements(list: *mut WordList) -> i32 { + unsafe { + let mut l: *mut WordList = list; + let mut job: i32; + let result: i32; + let command: *mut COMMAND; + + /* First do the replacement of job specifications with pids. */ + while l != std::ptr::null_mut() { + let lchar: char = char::from((*(*(*l).word).word) as u8); + if lchar == '%' + /* we have a winner */ + { + job = get_job_spec(l); + /* A bad job spec is not really a job spec! Pass it through. */ + if INVALID_JOB!(job) { + continue; + } + + libc::free((*(*l).word).word as *mut libc::c_void); + (*(*(*l).word).word) = (*get_job_by_jid!(job)).pgrp as libc::c_char; + } + l = (*l).next; + } + + let c_str_jobs_builtin = CString::new("jobs_builtin").unwrap(); + /* Next make a new simple command and execute it. */ + begin_unwind_frame(c_str_jobs_builtin.as_ptr() as *mut libc::c_char); + + command = make_bare_simple_command(); + (*((*command).value.Simple)).words = copy_word_list(list); + (*((*command).value.Simple)).redirects = std::ptr::null_mut(); + (*command).flags |= CMD_INHIBIT_EXPANSION!(); + (*((*command).value.Simple)).flags |= CMD_INHIBIT_EXPANSION!(); + + add_unwind_protect( + std::mem::transmute::>(dispose_command), + command as *mut libc::c_char, + ); + result = execute_command(command); + dispose_command(command); + discard_unwind_frame(c_str_jobs_builtin.as_ptr() as *mut libc::c_char); + return result; + } +} + +#[no_mangle] +pub fn jobs_builtin(mut list: *mut WordList) -> i32 { + let mut form: i32; + let mut execute: i32 = 0; + let mut state: i32; + let mut opt: i32; + let mut any_failed: i32 = 0; + let mut job: i32; + + let mut set: nix::sys::signal::SigSet = nix::sys::signal::SigSet::empty(); + let mut oset: nix::sys::signal::SigSet = nix::sys::signal::SigSet::empty(); + // let mut set: sigset_t = sigset_t { __val: [0; 16] }; + // let mut oset: sigset_t = sigset_t { __val: [0; 16] }; + + form = JLIST_STANDARD!(); + state = JSTATE_ANY!(); + + unsafe { + reset_internal_getopt(); + + let c_str_lpnxrs = CString::new("lpnxrs").unwrap(); // from a &str, creates a new allocation + + opt = internal_getopt(list, c_str_lpnxrs.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_har: char = opt as u8 as char; + match opt_har { + 'l' => { + form = JLIST_LONG!(); + } + 'p' => { + form = JLIST_PID_ONLY!(); + } + 'n' => { + form = JLIST_CHANGED_ONLY!(); + } + 'x' => { + if form != JLIST_STANDARD!() { + let c_str_err = CString::new("no other options allowed with `-x'").unwrap(); // from a &str, creates a new allocation + builtin_error(c_str_err.as_ptr()); + return EXECUTION_FAILURE!(); + } + execute += 1; + } + 'r' => { + state = JSTATE_RUNNING!(); + } + 's' => { + state = JSTATE_STOPPED!(); + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, c_str_lpnxrs.as_ptr() as *mut libc::c_char); + } + + list = loptend; + + if execute != 0 { + return execute_list_with_replacements(loptend); + } + + if loptend == std::ptr::null_mut() { + if state == JSTATE_ANY!() { + list_all_jobs(form); + } else if state == JSTATE_RUNNING!() { + list_running_jobs(form); + } else if state == JSTATE_STOPPED!() { + list_stopped_jobs(form); + } + return EXECUTION_SUCCESS!(); + } + + while list != std::ptr::null_mut() { + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + job = get_job_spec(list); + + if (job == NO_JOB!()) + || jobs == std::ptr::null_mut() + || get_job_by_jid!(job) == std::ptr::null_mut() + { + sh_badjob((*((*list).word)).word); + any_failed += 1; + } else if job != DUP_JOB!() { + list_one_job(0 as *mut JOB, form, 0, job); + } + + UNBLOCK_CHILD_1!(Some(&oset)); + + list = (*list).next; + } + if any_failed != 0 { + return EXECUTION_FAILURE!(); + } else { + return EXECUTION_SUCCESS!(); + } + } +} + +#[no_mangle] +pub fn disown_builtin(list: *mut WordList) -> libc::c_int { + let mut opt: i32; + let mut job: i32 = 0; + let mut retval: i32; + let mut nohup_only: i32 = 0; + let mut running_jobs: i32 = 0; + let mut all_jobs: i32 = 0; + + let mut set: nix::sys::signal::SigSet = nix::sys::signal::SigSet::empty(); + let mut oset: nix::sys::signal::SigSet = nix::sys::signal::SigSet::empty(); + // let mut set: sigset_t = sigset_t { __val: [0; 16] }; + // let mut oset: sigset_t = sigset_t { __val: [0; 16] }; + let mut pid_value: libc::c_long = 0; + unsafe { + reset_internal_getopt(); + let c_str_ahr = CString::new("ahr").unwrap(); // from a &str, creates a new allocation + opt = internal_getopt(list, c_str_ahr.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = opt as u8 as char; + match opt_char { + 'a' => { + all_jobs = 1; + } + 'h' => { + nohup_only = 1; + } + 'r' => { + running_jobs = 1; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, c_str_ahr.as_ptr() as *mut libc::c_char); + } + + retval = EXECUTION_SUCCESS!(); + + /* `disown -a' or `disown -r' */ + if loptend == std::ptr::null_mut() && (all_jobs != 0 || running_jobs != 0) { + if nohup_only != 0 { + nohup_all_jobs(running_jobs); + } else { + delete_all_jobs(running_jobs); + } + return EXECUTION_SUCCESS!(); + } + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + if loptend != std::ptr::null_mut() + && legal_number((*(*loptend).word).word, &mut pid_value) != 0 + && pid_value == pid_value + { + job = get_job_by_pid(pid_value as i32, 0, 0 as *mut *mut PROCESS); + } else { + job = get_job_spec(loptend); + } + if (job == NO_JOB!()) || (jobs == std::ptr::null_mut()) || (INVALID_JOB!(job)) { + if loptend != std::ptr::null_mut() { + sh_badjob((*(*loptend).word).word); + } else { + sh_badjob(CString::new("current").unwrap().as_ptr() as *mut libc::c_char); + } + retval = EXECUTION_FAILURE!(); + } else if nohup_only != 0 { + nohup_job(job); + } else { + delete_job(job, 1); + } + + UNBLOCK_CHILD_1!(Some(&oset)); + + if loptend != std::ptr::null_mut() { + let mut loptendt = *loptend; + while loptendt.next != std::ptr::null_mut() { + loptendt = *loptendt.next; + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + if legal_number((*loptendt.word).word, &mut pid_value) != 0 + && pid_value == pid_value + { + job = get_job_by_pid(pid_value as i32, 0, 0 as *mut *mut PROCESS); + } else { + get_job_spec(&mut loptendt); + } + if job == NO_JOB!() || jobs != std::ptr::null_mut() || INVALID_JOB!(job) { + sh_badjob((*loptendt.word).word); + retval = EXECUTION_FAILURE!(); + } else if nohup_only != 0 { + nohup_job(job); + } else { + delete_job(job, 1); + } + UNBLOCK_CHILD_1!(Some(&oset)); + } + } + return retval; + } +} + +fn cmd_name() -> *const u8 { + return b"jobs" as *const u8; +} diff --git a/utshell-0.5.0/src/builtins/kill.rs b/utshell-0.5.0/src/builtins/kill.rs new file mode 100644 index 00000000..6b87e5b0 --- /dev/null +++ b/utshell-0.5.0/src/builtins/kill.rs @@ -0,0 +1,252 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::common::{ + builtin_usage, display_signal_list, err_translate_fn, get_job_spec, sh_badjob, sh_badpid, + sh_invalidsig, sh_needarg, +}; +use crate::general::legal_number; +use crate::jobs::kill_pid; +use crate::src_common::*; +use crate::trap::decode_signal; + +#[no_mangle] +pub fn kill_builtin(mut list: *mut WordList) -> i32 { + unsafe { + let mut word: *mut libc::c_char; + let mut pid: libc::pid_t; + let mut pid_value: libc::c_long = 0; + + if list.is_null() { + builtin_usage(); + return EX_USAGE; + } + + if !list.is_null() + && !(*list).word.is_null() + && libc::strcmp( + (*((*list).word)).word, + "--help\0".as_ptr() as *const libc::c_char, + ) == 0 + { + builtin_help(); + return EX_USAGE; + } + + let mut any_succeeded: libc::c_int = 0; + let mut listing: libc::c_int = 0; + let mut saw_signal: libc::c_int = 0; + let mut sig = libc::SIGTERM; + let mut sigspec = "TERM\0".as_ptr() as *mut libc::c_char; + + let dflags = DSIG_NOCASE + | if posixly_correct == 0 { + DSIG_SIGPREFIX + } else { + 0 + }; + while !list.is_null() { + word = (*((*list).word)).word; + if is_option(word, b'l') || is_option(word, b'L') { + listing += 1; + list = (*list).next; + } else if is_option(word, b's') || is_option(word, b'n') { + list = (*list).next; + if !list.is_null() { + sigspec = (*((*list).word)).word; + if *sigspec == b'0' as libc::c_char + && *((sigspec as usize + 1) as *mut libc::c_char) == b'\0' as libc::c_char + { + sig = 0; + } else { + sig = decode_signal(sigspec, dflags); + } + list = (*list).next; + saw_signal += 1; + } else { + sh_needarg(word); + return EXECUTION_FAILURE; + } + } else if *word == b'-' as libc::c_char + && *((word as usize + 1) as *mut libc::c_char) == b's' as libc::c_char + && libc::isalpha(*((word as usize + 2) as *mut libc::c_char) as libc::c_int) != 0 + { + sigspec = (word as usize + 2) as *mut libc::c_char; + if *sigspec == b'0' as libc::c_char + && *((sigspec as usize + 1) as *mut libc::c_char) == b'\0' as libc::c_char + { + sig = 0; + } else { + sig = decode_signal(sigspec, dflags); + } + list = (*list).next; + saw_signal += 1; + } else if *word == b'-' as libc::c_char + && *((word as usize + 1) as *mut libc::c_char) == b'n' as libc::c_char + && libc::isdigit(*((word as usize + 2) as *mut libc::c_char) as libc::c_int) != 0 + { + sigspec = (word as usize + 2) as *mut libc::c_char; + if *sigspec == b'0' as libc::c_char + && *((sigspec as usize + 1) as *mut libc::c_char) == b'\0' as libc::c_char + { + sig = 0; + } else { + sig = decode_signal(sigspec, dflags); + } + list = (*list).next; + saw_signal += 1; + } else if is_option(word, b'-') { + list = (*list).next; + break; + } else if is_option(word, b'?') { + builtin_usage(); + return EX_USAGE; + } else if *word == b'-' as libc::c_char && saw_signal == 0 { + sigspec = (word as usize + 1) as *mut libc::c_char; + sig = decode_signal(sigspec, dflags); + saw_signal += 1; + list = (*list).next; + } else { + break; + } + } + + if listing != 0 { + return display_signal_list(list, 0); + } + + if sig == NO_SIG { + sh_invalidsig(sigspec); + return EXECUTION_FAILURE; + } + + if list.is_null() { + builtin_usage(); + return EX_USAGE; + } + + while !list.is_null() { + word = (*((*list).word)).word; + + if *word == b'-' as libc::c_char { + word = (word as usize + 1) as *mut libc::c_char; + } + + if *word != 0 + && legal_number((*((*list).word)).word, std::mem::transmute(&pid_value)) != 0 + && (pid_value == (pid_value as libc::c_int) as libc::c_long) + { + pid = pid_value as libc::pid_t; + + if kill_pid(pid, sig, (pid < -1) as libc::c_int) < 0 { + if *(libc::__errno_location()) == EINVAL { + sh_invalidsig(sigspec); + } else { + kill_error(pid, *(libc::__errno_location())); + } + list = (*list).next; + continue; + } else { + any_succeeded += 1; + } + } else if *((*((*list).word)).word) != 0 + && *((*((*list).word)).word) != b'%' as libc::c_char + { + eprint!("utshell : kill :"); + let names = String::from("killargerr"); + err_translate_fn(&names, (*((*list).word)).word); + println!(); + list = (*list).next; + continue; + } else if *word != 0 { + let set: libc::sigset_t = std::mem::zeroed(); + let oset: libc::sigset_t = std::mem::zeroed(); + let j: *mut JOB; + + libc::sigemptyset(std::mem::transmute(&set)); + libc::sigaddset(std::mem::transmute(&set), libc::SIGCHLD); + libc::sigemptyset(std::mem::transmute(&oset)); + libc::sigprocmask( + libc::SIG_BLOCK, + std::mem::transmute(&set), + std::mem::transmute(&oset), + ); + + let job = get_job_spec(list); + + if job < 0 + || job > js.j_jobslots + || ((jobs as usize + job as usize * 8) as *mut JOB).is_null() + { + if job != DUP_JOB { + sh_badjob((*((*list).word)).word); + } + libc::sigprocmask( + libc::SIG_SETMASK, + std::mem::transmute(&oset), + PT_NULL as *mut libc::sigset_t, + ); + list = (*list).next; + continue; + } + + j = (jobs as usize + job as usize * 8) as *mut JOB; + if (*j).flags & J_JOBCONTROL != 0 { + pid = (*j).pgrp; + } else { + pid = (*((*j).pipe)).pid; + } + + libc::sigprocmask( + libc::SIG_SETMASK, + std::mem::transmute(&oset), + PT_NULL as *mut libc::sigset_t, + ); + + if kill_pid(pid, sig, 1) < 0 { + if *(libc::__errno_location()) == EINVAL { + sh_invalidsig(sigspec); + } else { + kill_error(pid, *(libc::__errno_location())); + } + list = (*list).next; + continue; + } else { + any_succeeded += 1; + } + } else { + sh_badpid((*((*list).word)).word); + list = (*list).next; + continue; + } + list = (*list).next; + } + + return if any_succeeded != 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; + } +} + +fn is_option(s: *mut libc::c_char, c: u8) -> bool { + unsafe { + let str = CStr::from_ptr(s).to_bytes_with_nul(); + return str[0] == b'-' && str[1] == c && str[2] == 0; + } +} + +fn kill_error(pid: libc::pid_t, e: libc::c_int) { + unsafe { + let mut x = libc::strerror(e); + if x.is_null() { + x = "Unknown error".as_ptr() as *mut libc::c_char; + } + + builtin_error(b"(%ld) - %s\0" as *const u8 as *const libc::c_char, pid, x); + } +} diff --git a/utshell-0.5.0/src/builtins/let_1.rs b/utshell-0.5.0/src/builtins/let_1.rs new file mode 100644 index 00000000..ce65ada9 --- /dev/null +++ b/utshell-0.5.0/src/builtins/let_1.rs @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::common::err_translate_fn; +use crate::expr::evalexp; +use crate::src_common::*; +use crate::subst::string_list; + +#[no_mangle] +pub fn let_builtin(mut list: *mut WordList) -> i32 { + unsafe { + let mut ret: libc::c_long = 0; + let expok: libc::c_int = 0; + + if !list.is_null() + && !(*list).word.is_null() + && libc::strcmp( + (*((*list).word)).word, + "--help\0".as_ptr() as *const libc::c_char, + ) == 0 + { + builtin_help(); + return EX_USAGE; + } + + if !list.is_null() && !(*list).word.is_null() && is_option((*((*list).word)).word, b'-') { + list = (*list).next; + } + + if list.is_null() { + let names = String::from("letwarn"); + err_translate_fn(&names, std::ptr::null_mut()); + println!(); + return EXECUTION_FAILURE; + } + + while !list.is_null() { + ret = evalexp( + (*((*list).word)).word, + EXP_EXPANDED, + std::mem::transmute(&expok), + ); + if expok == 0 { + return EXECUTION_FAILURE; + } + list = (*list).next; + } + + return if ret == 0 { + EXECUTION_FAILURE + } else { + EXECUTION_SUCCESS + }; + } +} + +#[no_mangle] +pub fn exp_builtin(list: *mut WordList) -> i32 { + unsafe { + let expok: libc::c_int = 0; + + if list.is_null() { + let names = String::from("letwarn"); + err_translate_fn(&names, std::ptr::null_mut()); + println!(); + return EXECUTION_FAILURE; + } + + let exp = string_list(list); + let ret = evalexp(exp, EXP_EXPANDED, std::mem::transmute(&expok)); + libc::free(exp as *mut c_void); + return if ret == 0 || expok == 0 { + EXECUTION_FAILURE + } else { + EXECUTION_SUCCESS + }; + } +} + +fn is_option(s: *mut libc::c_char, c: u8) -> bool { + unsafe { + let str = CStr::from_ptr(s).to_bytes_with_nul(); + return str[0] == b'-' && str[1] == c && str[2] != 0; + } +} diff --git a/utshell-0.5.0/src/builtins/mapfile.rs b/utshell-0.5.0/src/builtins/mapfile.rs new file mode 100644 index 00000000..6c8d4656 --- /dev/null +++ b/utshell-0.5.0/src/builtins/mapfile.rs @@ -0,0 +1,313 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::array::array_flush; +use crate::arrayfunc::{bind_array_element, find_or_make_array_variable}; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, sh_invalidid}; +use crate::builtins::evalstring::evalstring; +use crate::general::{legal_identifier, legal_number, sh_validfd}; +use crate::src_common::*; + +pub const DEFAULT_QUANTUM: libc::c_long = 5000; +pub const MAPF_CLEARARRAY: libc::c_int = 0x01; +pub const MAPF_CHOP: libc::c_int = 0x02; + +static mut delim: libc::c_int = 0; + +#[no_mangle] +pub fn mapfile_builtin(mut list: *mut WordList) -> i32 { + let mut opt: libc::c_int; + let mut code: libc::c_int; + let mut fd: libc::c_int = 0; + let mut flags: libc::c_int = MAPF_CLEARARRAY; + let intval: libc::c_long = 0; + let mut lines: libc::c_long = 0; + let mut origin: libc::c_long = 0; + let mut nskip: libc::c_long = 0; + let mut callback_quantum: libc::c_long = DEFAULT_QUANTUM; + + let array_name: *mut libc::c_char; + let mut callback: *mut libc::c_char = PT_NULL as *mut libc::c_char; + + unsafe { + delim = b'\n' as libc::c_int; + + reset_internal_getopt(); + let opt_str = CString::new("d:u:n:O:tC:c:s:").unwrap(); + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'd' => delim = *list_optarg as libc::c_int, + 'u' => { + code = legal_number(list_optarg, std::mem::transmute(&intval)); + if code == 0 || intval < 0 || intval != (intval as libc::c_int) as libc::c_long + { + builtin_error( + "%s: invalid file descriptor specification\0".as_ptr() + as *const libc::c_char, + list_optarg, + ); + return EXECUTION_FAILURE; + } else { + fd = intval as libc::c_int; + } + if sh_validfd(fd) == 0 { + builtin_error( + "%d: invalid file descriptor: %s\0".as_ptr() as *const libc::c_char, + fd, + libc::strerror(*libc::__errno_location()), + ); + return EXECUTION_FAILURE; + } + } + 'n' => { + code = legal_number(list_optarg, std::mem::transmute(&intval)); + if code == 0 || intval < 0 || intval != (intval as libc::c_uint) as libc::c_long + { + builtin_error( + "%s: invalid line count\0".as_ptr() as *const libc::c_char, + list_optarg, + ); + return EXECUTION_FAILURE; + } else { + lines = intval; + } + } + 'O' => { + code = legal_number(list_optarg, std::mem::transmute(&intval)); + if code == 0 || intval < 0 || intval != (intval as libc::c_uint) as libc::c_long + { + builtin_error( + "%s: invalid array origin\0".as_ptr() as *const libc::c_char, + list_optarg, + ); + return EXECUTION_FAILURE; + } else { + origin = intval; + } + flags &= (MAPF_CLEARARRAY as libc::c_uint ^ 0xffffffff) as libc::c_int; + } + 't' => flags |= MAPF_CHOP, + 'C' => callback = list_optarg, + 'c' => { + code = legal_number(list_optarg, std::mem::transmute(&intval)); + if code == 0 || intval < 0 || intval != (intval as libc::c_uint) as libc::c_long + { + builtin_error( + "%s: invalid callback quantum\0".as_ptr() as *const libc::c_char, + list_optarg, + ); + return EXECUTION_FAILURE; + } else { + callback_quantum = intval; + } + } + 's' => { + code = legal_number(list_optarg, std::mem::transmute(&intval)); + if code == 0 || intval < 0 || intval != (intval as libc::c_uint) as libc::c_long + { + builtin_error( + "%s: invalid line count\0".as_ptr() as *const libc::c_char, + list_optarg, + ); + return EXECUTION_FAILURE; + } else { + nskip = intval; + } + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + } + list = loptend; + + if list.is_null() { + array_name = "MAPFILE".as_ptr() as *mut libc::c_char; + } else if (*list).word.is_null() || (*(*list).word).word.is_null() { + builtin_error("internal error: getting variable name\0".as_ptr() as *const libc::c_char); + return EXECUTION_FAILURE; + } else if *(*(*list).word).word == b'\0' as libc::c_char { + builtin_error("empty array variable name\0".as_ptr() as *const libc::c_char); + return EX_USAGE; + } else { + array_name = (*(*list).word).word; + } + if legal_identifier(array_name) == 0 { + sh_invalidid(array_name); + return EXECUTION_FAILURE; + } + + return mapfile( + fd, + lines, + origin, + nskip, + callback_quantum, + callback, + array_name, + delim, + flags, + ); + } +} + +fn run_callback( + callback: *const libc::c_char, + curindex: libc::c_uint, + curline: *mut libc::c_char, +) -> libc::c_int { + unsafe { + let qline = sh_single_quote(curline); + let execlen = libc::strlen(callback) + libc::strlen(qline) + 10 + 3; + let execstr = libc::malloc(execlen); + + let flags = SEVAL_NOHIST; + + libc::snprintf( + execstr as *mut libc::c_char, + execlen, + "%s %d %s\0".as_ptr() as *const libc::c_char, + callback, + curindex, + qline, + ); + libc::free(qline as *mut c_void); + return evalstring( + execstr as *mut libc::c_char, + PT_NULL as *const libc::c_char, + flags, + ); + } +} + +fn do_chop(line: *mut libc::c_char, d: libc::c_uchar) { + unsafe { + let length = libc::strlen(line); + if length != 0 && *((line as usize + length - 1) as *mut libc::c_char) == d as libc::c_char + { + *((line as usize + length - 1) as *mut libc::c_char) = b'\0' as libc::c_char; + } + } +} + +fn mapfile( + fd: libc::c_int, + line_count_goal: libc::c_long, + origin: libc::c_long, + nskip: libc::c_long, + callback_quantum: libc::c_long, + callback: *mut libc::c_char, + array_name: *mut libc::c_char, + dlm: libc::c_int, + flags: libc::c_int, +) -> libc::c_int { + let mut line: *mut libc::c_char = PT_NULL as *mut libc::c_char; + let mut line_length: size_t = 0; + let mut unbuffered_read: libc::c_int; + unsafe { + let entry = find_or_make_array_variable(array_name, 1); + // let entry_test = *entry; + // println!("entry:{:#?}",entry_test); + + if entry.is_null() + || ((*entry).attributes & att_readonly) != 0 + || ((*entry).attributes & att_noassign) != 0 + { + if !entry.is_null() && ((*entry).attributes & att_readonly) != 0 { + err_readonly(array_name); + } + + return EXECUTION_FAILURE; + } else if ((*entry).attributes & att_array) == 0 { + builtin_error( + "%s: not an indexed array\0".as_ptr() as *const libc::c_char, + array_name, + ); + return EXECUTION_FAILURE; + } else if ((*entry).attributes & att_array) != 0 { + (*entry).attributes &= (att_invisible as libc::c_uint ^ 0xffffffff) as libc::c_int; + } + + if (flags & MAPF_CLEARARRAY) != 0 { + array_flush(std::mem::transmute((*entry).value)); + } + unbuffered_read = ((libc::lseek(fd, 0, SEEK_CUR) < 0) + && (*libc::__errno_location() == ESPIPE)) as libc::c_int; + + if dlm != b'\n' as libc::c_int { + unbuffered_read = 1; + } + zreset(); + + let mut line_count: libc::c_uint = 0; + while (line_count as libc::c_long) < nskip { + if zgetline( + fd, + std::mem::transmute(&line), + std::mem::transmute(&line_length), + dlm, + unbuffered_read, + ) < 0 + { + break; + } + line_count += 1; + } + + line = PT_NULL as *mut libc::c_char; + line_length = 0; + let mut array_index: libc::c_uint = origin as libc::c_uint; + line_count = 1; + while zgetline( + fd, + std::mem::transmute(&line), + std::mem::transmute(&line_length), + dlm, + unbuffered_read, + ) != -1 + { + if (flags & MAPF_CHOP) != 0 { + do_chop(line, dlm as libc::c_uchar); + } + + if !callback.is_null() + && line_count != 0 + && (line_count as libc::c_long % callback_quantum) == 0 + { + run_callback(callback, array_index, line); + + if unbuffered_read == 0 { + zsyncfd(fd); + } + } + + bind_array_element(entry, array_index as libc::c_long, line, 0); + + line_count += 1; + if line_count_goal != 0 && (line_count as libc::c_long) > line_count_goal { + break; + } + + array_index += 1; + } + + libc::free(line as *mut c_void); + + if unbuffered_read == 0 { + zsyncfd(fd); + } + } + return EXECUTION_SUCCESS; +} diff --git a/utshell-0.5.0/src/builtins/printf.rs b/utshell-0.5.0/src/builtins/printf.rs new file mode 100644 index 00000000..6970b242 --- /dev/null +++ b/utshell-0.5.0/src/builtins/printf.rs @@ -0,0 +1,1573 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::arrayfunc::valid_array_reference; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_bind_variable, builtin_usage, sh_invalidid, sh_invalidnum, sh_wrerror, +}; +use crate::general::legal_identifier; +use crate::sig::{termsig_handler, throw_to_top_level}; +use crate::src_common::*; +use crate::variables::{bind_var_to_int, stupidly_hack_special_variables, sv_tz}; + +extern "C" { + pub fn mbtowc(pwc: *mut libc::wchar_t, s: *const libc::c_char, n: size_t) -> size_t; + pub fn u32cconv(c: libc::c_ulong, s: *mut libc::c_char) -> libc::c_int; +} + +unsafe fn QUIT() { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + + if interrupt_state != 0 { + throw_to_top_level(); + } +} + +unsafe fn PC(c: u8) { + let mut b: [libc::c_char; 2] = [0; 2]; + tw += 1; + b[0] = c as libc::c_char; + if vflag != 0 { + vbadd(b.as_ptr() as *mut libc::c_char, 1); + } else { + libc::putchar(c as libc::c_int); + } + QUIT(); +} + +static mut conversion_error: libc::c_int = 0; +static mut conv_buf: *mut libc::c_char = PT_NULL as *mut libc::c_char; +static mut conv_bufsize: size_t = 0; +static mut vbuf: *mut libc::c_char = PT_NULL as *mut libc::c_char; +static mut vname: *mut libc::c_char = PT_NULL as *mut libc::c_char; +static mut vflag: libc::c_int = 0; +static mut vbsize: size_t = 0; +static mut vblen: libc::c_int = 0; + +static mut retval: libc::c_int = 0; +static mut tw: libc::c_long = 0; + +static mut garglist: *mut WordList = PT_NULL as *mut WordList; +static mut orig_arglist: *mut WordList = PT_NULL as *mut WordList; + +#[no_mangle] +pub fn printf_builtin(mut list: *mut WordList) -> i32 { + let mut ch: libc::c_int; + let mut fieldwidth: libc::c_int; + let mut have_fieldwidth: libc::c_int; + let mut precision: libc::c_int; + let mut have_precision: libc::c_int; + let mut arrayflags: libc::c_int; + + let mut fmt; + let mut start; + let mut modstart; + let mut convch; + let mut thisch; + let mut nextch; + unsafe { + let PRETURN = |out_val: libc::c_int| { + QUIT(); + if vflag != 0 { + let v = builtin_bind_variable(vname, vbuf, 0); + stupidly_hack_special_variables(vname); + if v.is_null() + || ((*v).attributes & att_readonly) != 0 + || ((*v).attributes & att_noassign) != 0 + { + return EXECUTION_FAILURE; + } + } + if conv_bufsize > 4096 { + libc::free(conv_buf as *mut c_void); + conv_bufsize = 0; + conv_buf = PT_NULL as *mut libc::c_char; + } + + if vbsize > 4096 { + libc::free(vbuf as *mut c_void); + vbsize = 0; + vbuf = PT_NULL as *mut libc::c_char; + } else if !vbuf.is_null() { + *vbuf = 0; + } + + if libc::ferror(stdout) == 0 { + libc::fflush(stdout); + } + QUIT(); + if libc::ferror(stdout) != 0 { + sh_wrerror(); + libc::clearerr(stdout); + return EXECUTION_FAILURE; + } + + return out_val; + }; + + vflag = 0; + reset_internal_getopt(); + let opt_str = CString::new("v:").unwrap(); + let mut opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'v' => { + vname = list_optarg; + arrayflags = if assoc_expand_once != 0 { + VA_NOEXPAND | VA_ONEWORD + } else { + 0 + }; + if legal_identifier(vname) != 0 || valid_array_reference(vname, arrayflags) != 0 + { + vflag = 1; + if vbsize == 0 { + vbsize = 16; + vbuf = malloc(16) as *mut libc::c_char; + } + vblen = 0; + if !vbuf.is_null() { + *vbuf = 0; + } + } else { + sh_invalidid(vname); + return EX_USAGE; + } + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + } + list = loptend; + + if list.is_null() { + builtin_usage(); + return EX_USAGE; + } + + if vflag != 0 + && !((*(*list).word).word.is_null()) + && *(*(*list).word).word == b'\0' as libc::c_char + { + let v = builtin_bind_variable(vname, "\0".as_ptr() as *mut libc::c_char, 0); + stupidly_hack_special_variables(vname); + return if v.is_null() + || ((*v).attributes & att_readonly) != 0 + || ((*v).attributes & att_noassign) != 0 + { + EXECUTION_FAILURE + } else { + EXECUTION_SUCCESS + }; + } + + if (*(*list).word).word.is_null() || *(*(*list).word).word == b'\0' as libc::c_char { + return EXECUTION_SUCCESS; + } + + let format = (*(*list).word).word; + tw = 0; + + garglist = (*list).next; + orig_arglist = (*list).next; + + if format.is_null() || *format == 0 { + return EXECUTION_SUCCESS; + } + + 'outer: loop { + tw = 0; + fmt = format; + + while *fmt != 0 { + precision = 0; + fieldwidth = 0; + have_fieldwidth = 0; + have_precision = 0; + + if *fmt == b'\\' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + + let mbch: [libc::c_char; 25] = [0; 25]; + let mblen: libc::c_int = 0; + fmt = (fmt as usize + + tescape( + fmt, + mbch.as_ptr() as *mut libc::c_char, + std::mem::transmute(&mblen), + PT_NULL as *mut libc::c_int, + ) as usize) as *mut libc::c_char; + let mut mbind = 0; + + while mbind < mblen { + PC(mbch[mbind as usize] as u8); + mbind += 1; + } + fmt = (fmt as usize - 1) as *mut libc::c_char; + + fmt = (fmt as usize + 1) as *mut libc::c_char; + continue; + } + + if *fmt != b'%' as libc::c_char { + PC(*fmt as u8); + + fmt = (fmt as usize + 1) as *mut libc::c_char; + continue; + } + + start = fmt; + fmt = (fmt as usize + 1) as *mut libc::c_char; + if *fmt == b'%' as libc::c_char { + PC(b'%'); + + fmt = (fmt as usize + 1) as *mut libc::c_char; + continue; + } + + while *fmt != 0 + && !(strchr( + "#'-+ 0\0".as_ptr() as *const libc::c_char, + *fmt as libc::c_int, + ) + .is_null()) + { + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + + if *fmt == b'*' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + have_fieldwidth = 1; + fieldwidth = getint(); + } else { + while IS_DIGITAL!(*fmt) { + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + } + + if *fmt == b'.' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + if *fmt == b'*' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + have_precision = 1; + precision = getint(); + } else { + if *fmt == b'-' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + while IS_DIGITAL!(*fmt) { + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + } + } + + modstart = fmt; + while *fmt != 0 + && !(strchr( + "hjlLtz\0".as_ptr() as *const libc::c_char, + *fmt as libc::c_int, + ) + .is_null()) + { + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + + if *fmt == 0 { + builtin_error( + "`%s': missing format character\0".as_ptr() as *const libc::c_char, + start, + ); + return PRETURN(EXECUTION_FAILURE); + } + + convch = *fmt; + thisch = *modstart; + nextch = *((modstart as usize + 1) as *mut libc::c_char); + *modstart = convch; + *((modstart as usize + 1) as *mut libc::c_char) = b'\0' as libc::c_char; + + QUIT(); + let format_type = convch as u8; + match format_type { + b'c' => { + let p = getchr(); + let f = start; + libc::clearerr(stdout); + let PF = || { + let nw: libc::c_int; + if vflag == 0 { + if have_fieldwidth != 0 && have_precision != 0 { + nw = libc::printf(f, fieldwidth, precision, p); + } else if have_fieldwidth != 0 { + nw = libc::printf(f, fieldwidth, p); + } else if have_precision != 0 { + nw = libc::printf(f, precision, p); + } else { + nw = libc::printf(f, p); + } + } else { + let vbsnprintf2 = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf1 = |x: libc::c_int| { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + if have_fieldwidth != 0 && have_precision != 0 { + nw = vbsnprintf2(); + } else if have_fieldwidth != 0 { + nw = vbsnprintf1(fieldwidth); + } else if have_precision != 0 { + nw = vbsnprintf1(precision); + } else { + nw = vbsnprintf(); + } + } + tw += nw as libc::c_long; + }; + PF(); + QUIT(); + if libc::ferror(stdout) != 0 { + sh_wrerror(); + libc::clearerr(stdout); + return EXECUTION_FAILURE; + } + } + b's' => { + let p = getstr(); + let f = start; + libc::clearerr(stdout); + let PF = || { + let nw: libc::c_int; + if vflag == 0 { + if have_fieldwidth != 0 && have_precision != 0 { + nw = libc::printf(f, fieldwidth, precision, p); + } else if have_fieldwidth != 0 { + nw = libc::printf(f, fieldwidth, p); + } else if have_precision != 0 { + nw = libc::printf(f, precision, p); + } else { + nw = libc::printf(f, p); + } + } else { + let vbsnprintf2 = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf1 = |x: libc::c_int| { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + if have_fieldwidth != 0 && have_precision != 0 { + nw = vbsnprintf2(); + } else if have_fieldwidth != 0 { + nw = vbsnprintf1(fieldwidth); + } else if have_precision != 0 { + nw = vbsnprintf1(precision); + } else { + nw = vbsnprintf(); + } + } + tw += nw as libc::c_long; + }; + PF(); + QUIT(); + if libc::ferror(stdout) != 0 { + sh_wrerror(); + libc::clearerr(stdout); + return EXECUTION_FAILURE; + } + } + b'(' => { + *((modstart as usize + 1) as *mut libc::c_char) = nextch; + let timefmt = malloc(libc::strlen(fmt) + 3) as *mut libc::c_char; + fmt = (fmt as usize + 1) as *mut libc::c_char; + let mut t = timefmt; + let mut n = 1; + while *fmt != 0 { + if *fmt == b'(' as libc::c_char { + n += 1; + } else if *fmt == b')' as libc::c_char { + n -= 1; + } + if n == 0 { + break; + } + *t = *fmt; + t = (t as usize + 1) as *mut libc::c_char; + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + *t = b'\0' as libc::c_char; + fmt = (fmt as usize + 1) as *mut libc::c_char; + if *fmt != b'T' as libc::c_char { + builtin_warning( + "`%c': invalid time format specification\0".as_ptr() + as *const libc::c_char, + *fmt as libc::c_int, + ); + fmt = start; + libc::free(timefmt as *mut c_void); + PC(*fmt as u8); + + fmt = (fmt as usize + 1) as *mut libc::c_char; + continue; + } + if *timefmt == b'\0' as libc::c_char { + *timefmt = b'%' as libc::c_char; + *((timefmt as usize + 1) as *mut libc::c_char) = b'X' as libc::c_char; + *((timefmt as usize + 2) as *mut libc::c_char) = b'\0' as libc::c_char; + } + + let arg = if !garglist.is_null() { getintmax() } else { -1 }; + let mut secs: libc::time_t; + if arg == -1 { + secs = libc::time(0 as *mut libc::time_t); + } else if arg == -2 { + secs = shell_start_time; + } else { + secs = arg; + } + + sv_tz("TZ\0".as_ptr() as *mut libc::c_char); + let mut tm = libc::localtime(std::mem::transmute(&secs)); + if tm.is_null() { + secs = 0; + tm = libc::localtime(std::mem::transmute(&secs)); + } + let mut timebuf: [libc::c_char; 128] = [0; 128]; + let mut n: libc::c_int = if !tm.is_null() { + strftime(timebuf.as_ptr() as *mut libc::c_char, 128, timefmt, tm) + as libc::c_int + } else { + 0 + }; + libc::free(timefmt as *mut c_void); + if n == 0 { + timebuf[0] = b'\0' as libc::c_char; + } else { + timebuf[127] = b'\0' as libc::c_char; + } + + *modstart = b's' as libc::c_char; + *((modstart as usize + 1) as *mut libc::c_char) = b'\0' as libc::c_char; + n = printstr( + start, + timebuf.as_ptr() as *mut libc::c_char, + libc::strlen(timebuf.as_ptr()) as libc::c_int, + fieldwidth, + precision, + ); + if n < 0 { + if libc::ferror(stdout) == 0 { + sh_wrerror(); + libc::clearerr(stdout); + } + return PRETURN(EXECUTION_FAILURE); + } + } + b'n' => { + let var = getstr(); + if !var.is_null() && *var != 0 { + if legal_identifier(var) != 0 { + bind_var_to_int(var, tw); + } else { + sh_invalidid(var); + return PRETURN(EXECUTION_FAILURE); + } + } + } + b'b' => { + let rlen: libc::c_int = 0; + let mut r: libc::c_int = 0; + ch = 0; + let p = getstr(); + let xp = bexpand( + p, + libc::strlen(p) as libc::c_int, + std::mem::transmute(&ch), + std::mem::transmute(&rlen), + ); + if !xp.is_null() { + r = printstr(start, xp, rlen, fieldwidth, precision); + if r < 0 { + if libc::ferror(stdout) == 0 { + sh_wrerror(); + libc::clearerr(stdout); + } + retval = EXECUTION_FAILURE; + } + libc::free(xp as *mut c_void); + } + if ch != 0 || r < 0 { + return PRETURN(retval); + } + } + b'q' => { + let mut r: libc::c_int = 0; + let xp: *mut libc::c_char; + let p = getstr(); + if !p.is_null() && *p == 0 { + xp = savestring!(b"''\0".as_ptr() as *mut libc::c_char); + //xp = savestring(b"''\0".as_ptr() as *const libc::c_char); + } else if ansic_shouldquote(p) != 0 { + xp = ansic_quote(p, 0, PT_NULL as *mut libc::c_int); + } else { + xp = sh_backslash_quote(p, PT_NULL as *mut libc::c_char, 3); + } + if !xp.is_null() { + r = printstr( + start, + xp, + libc::strlen(xp) as libc::c_int, + fieldwidth, + precision, + ); + if r < 0 { + if libc::ferror(stdout) == 0 { + sh_wrerror(); + libc::clearerr(stdout); + } + libc::free(xp as *mut c_void); + } + } + if r < 0 { + return PRETURN(EXECUTION_FAILURE); + } + } + b'd' | b'i' => { + let f = mklong(start, "l\0".as_ptr() as *mut libc::c_char, 1); + let p = getintmax(); + libc::clearerr(stdout); + let PF = || { + let nw: libc::c_int; + if vflag == 0 { + if have_fieldwidth != 0 && have_precision != 0 { + nw = libc::printf(f, fieldwidth, precision, p); + } else if have_fieldwidth != 0 { + nw = libc::printf(f, fieldwidth, p); + } else if have_precision != 0 { + nw = libc::printf(f, precision, p); + } else { + nw = libc::printf(f, p); + } + } else { + let vbsnprintf2 = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf1 = |x: libc::c_int| { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + if have_fieldwidth != 0 && have_precision != 0 { + nw = vbsnprintf2(); + } else if have_fieldwidth != 0 { + nw = vbsnprintf1(fieldwidth); + } else if have_precision != 0 { + nw = vbsnprintf1(precision); + } else { + nw = vbsnprintf(); + } + } + tw += nw as libc::c_long; + }; + PF(); + QUIT(); + if libc::ferror(stdout) != 0 { + sh_wrerror(); + libc::clearerr(stdout); + return EXECUTION_FAILURE; + } + } + b'o' | b'u' | b'x' | b'X' => { + let f = mklong(start, "l\0".as_ptr() as *mut libc::c_char, 1); + let p = getuintmax(); + libc::clearerr(stdout); + let PF = || { + let nw: libc::c_int; + if vflag == 0 { + if have_fieldwidth != 0 && have_precision != 0 { + nw = libc::printf(f, fieldwidth, precision, p); + } else if have_fieldwidth != 0 { + nw = libc::printf(f, fieldwidth, p); + } else if have_precision != 0 { + nw = libc::printf(f, precision, p); + } else { + nw = libc::printf(f, p); + } + } else { + let vbsnprintf2 = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf1 = |x: libc::c_int| { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + if have_fieldwidth != 0 && have_precision != 0 { + nw = vbsnprintf2(); + } else if have_fieldwidth != 0 { + nw = vbsnprintf1(fieldwidth); + } else if have_precision != 0 { + nw = vbsnprintf1(precision); + } else { + nw = vbsnprintf(); + } + } + tw += nw as libc::c_long; + }; + PF(); + QUIT(); + if libc::ferror(stdout) != 0 { + sh_wrerror(); + libc::clearerr(stdout); + return EXECUTION_FAILURE; + } + } + b'e' | b'E' | b'f' | b'F' | b'g' | b'G' | b'a' | b'A' => { + let p = getfloatmax(); + let f = mklong(start, "l\0".as_ptr() as *mut libc::c_char, 1); + libc::clearerr(stdout); + let PF = || { + let nw: libc::c_int; + if vflag == 0 { + if have_fieldwidth != 0 && have_precision != 0 { + nw = libc::printf(f, fieldwidth, precision, p); + } else if have_fieldwidth != 0 { + nw = libc::printf(f, fieldwidth, p); + } else if have_precision != 0 { + nw = libc::printf(f, precision, p); + } else { + nw = libc::printf(f, p); + } + } else { + let vbsnprintf2 = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + have_fieldwidth, + have_precision, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf1 = |x: libc::c_int| { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + x, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + let vbsnprintf = || { + let mut blen: libc::c_int; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen > vbsize { + vbsize = ((nlen as size_t + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) + as *mut libc::c_char; + blen = libc::snprintf( + (vbuf as usize + vblen as usize) as *mut libc::c_char, + (vbsize - vblen as size_t) as usize, + f, + p, + ); + } + vblen += blen; + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = + b'0' as libc::c_char; + blen + }; + if have_fieldwidth != 0 && have_precision != 0 { + nw = vbsnprintf2(); + } else if have_fieldwidth != 0 { + nw = vbsnprintf1(fieldwidth); + } else if have_precision != 0 { + nw = vbsnprintf1(precision); + } else { + nw = vbsnprintf(); + } + } + tw += nw as libc::c_long; + }; + PF(); + QUIT(); + if libc::ferror(stdout) != 0 { + sh_wrerror(); + libc::clearerr(stdout); + return EXECUTION_FAILURE; + } + } + _ => { + builtin_error( + "`%c': invalid format character\0".as_ptr() as *const libc::c_char, + convch as libc::c_int, + ); + return PRETURN(EXECUTION_FAILURE); + } + } + + *modstart = thisch; + *((modstart as usize + 1) as *mut libc::c_char) = nextch; + + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + + if libc::ferror(stdout) != 0 { + return PRETURN(EXECUTION_FAILURE); + } + + if !garglist.is_null() && garglist != (*list).next { + continue 'outer; + } else { + break 'outer; + } + } + + if conversion_error != 0 { + retval = EXECUTION_FAILURE; + } + + return PRETURN(retval); + } +} + +fn hexvalue(c: u8) -> libc::c_int { + return (if (c) >= b'a' && (c) <= b'f' { + (c) - b'a' + 10 + } else if (c) >= b'A' && (c) <= b'F' { + (c) - b'A' + 10 + } else { + (c) - b'0' + }) as i32; +} + +fn printstr( + mut fmt: *mut libc::c_char, + mut string: *mut libc::c_char, + len: libc::c_int, + fieldwidth: libc::c_int, + precision: libc::c_int, +) -> libc::c_int { + unsafe { + if string.is_null() { + string = "\0".as_ptr() as *mut libc::c_char; + } + + if *fmt == b'%' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + + let mut ljust: libc::c_int = 0; + let mut fw: libc::c_int = 0; + let mut mfw: libc::c_long = 0; + let mut pr: libc::c_int = -1; + let mut mpr: libc::c_long = -1; + + while !(strchr( + "#'-+ 0\0".as_ptr() as *const libc::c_char, + *fmt as libc::c_int, + ) + .is_null()) + { + if *fmt == b'-' as libc::c_char { + ljust = 1; + } + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + + if *fmt == b'*' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + fw = fieldwidth; + if fw < 0 { + fw = -fw; + ljust = 1; + } + } else if IS_DIGITAL!(*fmt) { + mfw = (*fmt - b'0' as libc::c_char) as libc::c_long; + fmt = (fmt as usize + 1) as *mut libc::c_char; + while IS_DIGITAL!(*fmt) { + mfw = mfw * 10 + (*fmt - b'0' as libc::c_char) as libc::c_long; + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + fw = if mfw < 0 || mfw > (libc::INT_MAX as libc::c_long) { + libc::INT_MAX + } else { + mfw as libc::c_int + }; + } + + if *fmt == b'.' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + if *fmt == b'*' as libc::c_char { + fmt = (fmt as usize + 1) as *mut libc::c_char; + pr = precision; + } else if IS_DIGITAL!(*fmt) { + mpr = (*fmt - b'0' as libc::c_char) as libc::c_long; + fmt = (fmt as usize + 1) as *mut libc::c_char; + while IS_DIGITAL!(*fmt) { + mpr = mpr * 10 + (*fmt - b'0' as libc::c_char) as libc::c_long; + fmt = (fmt as usize + 1) as *mut libc::c_char; + } + pr = if mpr < 0 || mpr > (libc::INT_MAX as libc::c_long) { + libc::INT_MAX + } else { + mpr as libc::c_int + }; + } else { + pr = 0; + } + } + + let nc = if pr >= 0 && pr <= len { pr } else { len }; + let mut padlen = fw - nc; + if padlen < 0 { + padlen = 0; + } + if ljust != 0 { + padlen = -padlen; + } + + while padlen > 0 { + PC(b' '); + padlen -= 1; + } + + for i in 0..nc { + PC(*((string as usize + i as usize) as *mut libc::c_char) as u8); + } + + return 0; + } +} + +fn tescape( + estart: *mut libc::c_char, + cp: *mut libc::c_char, + lenp: *mut libc::c_int, + sawc: *mut libc::c_int, +) -> libc::c_int { + let mut p: *mut libc::c_char = estart; + let mut evalue: libc::c_int; + let mut temp: libc::c_int; + let mut uvalue: libc::c_ulong; + unsafe { + if !lenp.is_null() { + *lenp = 1; + } + + let c = *p as u8; + p = (p as usize + 1) as *mut libc::c_char; + match c { + b'a' => *cp = 7, + b'b' => *cp = 8, + b'e' | b'E' => *cp = 27, + b'f' => *cp = 12, + b'n' => *cp = 10, + b'r' => *cp = 13, + b't' => *cp = 9, + b'v' => *cp = 11, + b'0'..=b'7' => { + evalue = (c - b'0') as libc::c_int; + temp = 2 + (evalue == 0 && !sawc.is_null()) as libc::c_int; + while *p >= b'0' as libc::c_char && *p <= b'7' as libc::c_char && temp != 0 { + temp -= 1; + evalue = (evalue * 8) + (*p - b'0' as libc::c_char) as libc::c_int; + p = (p as usize + 1) as *mut libc::c_char; + } + + *cp = (evalue & 0xff) as libc::c_char; + } + b'x' => { + temp = 2; + evalue = 0; + while libc::isdigit(*p as libc::c_int) != 0 && temp != 0 { + temp -= 1; + evalue = (evalue * 16) + hexvalue(*p as u8); + p = (p as usize + 1) as *mut libc::c_char; + } + + if p as usize == (estart as usize + 1) { + builtin_error("missing hex digit for \\x\0".as_ptr() as *const libc::c_char); + *cp = b'\\' as libc::c_char; + return 0; + } + *cp = (evalue & 0xff) as libc::c_char; + } + b'u' | b'U' => { + temp = if c == b'u' { 4 } else { 8 }; + uvalue = 0; + while libc::isdigit(*p as libc::c_int) != 0 && temp != 0 { + temp -= 1; + uvalue = (uvalue * 16) + hexvalue(*p as u8) as libc::c_ulong; + p = (p as usize + 1) as *mut libc::c_char; + } + + if p as usize == (estart as usize + 1) { + builtin_error( + "missing unicode digit for \\%c\0".as_ptr() as *const libc::c_char, + c as libc::c_int, + ); + *cp = b'\\' as libc::c_char; + return 0; + } + if uvalue <= 0x7f { + *cp = uvalue as libc::c_char; + } else { + temp = u32cconv(uvalue, cp); + *((cp as usize + temp as usize) as *mut libc::c_char) = b'\0' as libc::c_char; + if !lenp.is_null() { + *lenp = temp; + } + } + } + b'\\' => *cp = c as libc::c_char, + b'\'' | b'"' | b'?' => { + if sawc.is_null() { + *cp = c as libc::c_char; + } else { + *cp = b'\\' as libc::c_char; + return 0; + } + } + b'c' => { + if sawc.is_null() { + *sawc = 1; + } else { + *cp = b'\\' as libc::c_char; + return 0; + } + } + _ => { + *cp = b'\\' as libc::c_char; + return 0; + } + } + } + return (p as usize - estart as usize) as libc::c_int; +} + +fn bexpand( + string: *mut libc::c_char, + len: libc::c_int, + sawc: *mut libc::c_int, + lenp: *mut libc::c_int, +) -> *mut libc::c_char { + let mut mbch: [libc::c_char; 25]; + let mblen: libc::c_int = 0; + + let ret: *mut libc::c_char; + let mut r: *mut libc::c_char; + let mut s: *mut libc::c_char; + let mut c: libc::c_char; + unsafe { + if string.is_null() || len == 0 { + if !sawc.is_null() { + *sawc = 0; + } + if !lenp.is_null() { + *lenp = 0; + } + ret = malloc(1) as *mut libc::c_char; + *ret = b'\0' as libc::c_char; + return ret; + } + + ret = malloc((len + 1) as usize) as *mut libc::c_char; + r = ret; + s = string; + while !s.is_null() && *s != 0 { + c = *s as libc::c_char; + s = (s as usize + 1) as *mut libc::c_char; + if c != b'\\' as libc::c_char || *s == b'\0' as libc::c_char { + *r = c; + r = (r as usize + 1) as *mut libc::c_char; + continue; + } + + let temp: libc::c_int = 0; + mbch = [0; 25]; + let n = tescape( + s, + mbch.as_mut_ptr() as *mut libc::c_char, + std::mem::transmute(&mblen), + std::mem::transmute(&temp), + ); + s = (s as usize + n as usize) as *mut libc::c_char; + + if temp != 0 { + if !sawc.is_null() { + *sawc = 1; + } + break; + } + + for mbind in 0..mblen { + *r = mbch[mbind as usize]; + r = (r as usize + 1) as *mut libc::c_char; + } + } + + *r = b'\0' as libc::c_char; + if !lenp.is_null() { + *lenp = (r as usize - ret as usize) as libc::c_int; + } + } + return ret; +} + +fn vbadd(buf: *mut libc::c_char, blen: libc::c_int) -> *mut libc::c_char { + unsafe { + let nlen: size_t = vblen as size_t + blen as size_t + 1; + if nlen >= vbsize { + vbsize = ((nlen + 63) >> 6) << 6; + vbuf = realloc(vbuf as *mut c_void, vbsize as usize) as *mut libc::c_char; + } + + if blen == 1 { + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = *buf; + vblen += 1; + } else if blen > 1 { + libc::memcpy( + (vbuf as usize + vblen as usize) as *mut c_void, + buf as *mut c_void, + blen as usize, + ); + vblen += blen; + } + *((vbuf as usize + vblen as usize) as *mut libc::c_char) = b'\0' as libc::c_char; + + return vbuf; + } +} + +fn printf_erange(s: *mut libc::c_char) { + unsafe { + builtin_error( + "warning: %s: %s\0".as_ptr() as *const libc::c_char, + s, + libc::strerror(libc::ERANGE), + ); + } +} + +fn mklong(str: *mut libc::c_char, modifiers: *mut libc::c_char, mlen: size_t) -> *mut libc::c_char { + unsafe { + let slen = libc::strlen(str); + let len = slen + mlen as usize + 1; + + if len as size_t > conv_bufsize { + conv_bufsize = (((len + 1023) >> 10) << 10) as size_t; + conv_buf = + libc::realloc(conv_buf as *mut c_void, conv_bufsize as usize) as *mut libc::c_char; + } + + libc::memcpy(conv_buf as *mut c_void, str as *mut c_void, slen - 1); + libc::memcpy( + (conv_buf as usize + slen - 1) as *mut c_void, + modifiers as *mut c_void, + mlen as usize, + ); + + *((conv_buf as usize + len - 2) as *mut libc::c_char) = + *((str as usize + slen - 1) as *mut libc::c_char); + *((conv_buf as usize + len - 1) as *mut libc::c_char) = b'\0' as libc::c_char; + + return conv_buf; + } +} + +fn getchr() -> libc::c_int { + unsafe { + if garglist.is_null() { + return b'\0' as libc::c_int; + } + + let ret = *(*(*garglist).word).word as libc::c_int; + garglist = (*garglist).next; + return ret; + } +} + +fn getstr() -> *mut libc::c_char { + unsafe { + if garglist.is_null() { + return "\0".as_ptr() as *mut libc::c_char; + } + + let ret = (*(*garglist).word).word; + garglist = (*garglist).next; + return ret; + } +} + +fn getint() -> libc::c_int { + let mut ret = getintmax(); + unsafe { + if garglist.is_null() { + return ret as libc::c_int; + } + if ret > libc::INT_MAX as libc::c_long { + printf_erange((*(*garglist).word).word); + ret = libc::INT_MAX as libc::c_long; + } else if ret < libc::INT_MIN as libc::c_long { + printf_erange((*(*garglist).word).word); + ret = libc::INT_MIN as libc::c_long; + } + } + return ret as libc::c_int; +} + +fn getintmax() -> libc::c_long { + unsafe { + if garglist.is_null() { + return 0; + } + + if *(*(*garglist).word).word == b'\'' as libc::c_char + || *(*(*garglist).word).word == b'"' as libc::c_char + { + return asciicode(); + } + + let ep: *mut libc::c_char = PT_NULL as *mut libc::c_char; + *libc::__errno_location() = 0; + let ret = libc::strtol((*(*garglist).word).word, std::mem::transmute(&ep), 0); + if *ep != 0 { + sh_invalidnum((*(*garglist).word).word); + conversion_error = 1; + } else if *libc::__errno_location() == libc::ERANGE { + printf_erange((*(*garglist).word).word); + } + garglist = (*garglist).next; + return ret; + } +} + +fn getuintmax() -> libc::c_ulong { + unsafe { + if garglist.is_null() { + return 0; + } + + if *(*(*garglist).word).word == b'\'' as libc::c_char + || *(*(*garglist).word).word == b'"' as libc::c_char + { + return asciicode() as libc::c_ulong; + } + + *libc::__errno_location() = 0; + let ep: *mut libc::c_char = PT_NULL as *mut libc::c_char; + let ret = libc::strtoul((*(*garglist).word).word, std::mem::transmute(&ep), 0); + if *ep != 0 { + sh_invalidnum((*(*garglist).word).word); + conversion_error = 1; + } else if *libc::__errno_location() == libc::ERANGE { + printf_erange((*(*garglist).word).word); + } + garglist = (*garglist).next; + return ret; + } +} + +fn getfloatmax() -> f64 { + let ep: *mut libc::c_char = PT_NULL as *mut libc::c_char; + unsafe { + if garglist.is_null() { + return 0.0; + } + + if *(*(*garglist).word).word == b'\'' as libc::c_char + || *(*(*garglist).word).word == b'\"' as libc::c_char + { + return asciicode() as f64; + } + + *libc::__errno_location() = 0; + let ret = libc::strtod((*(*garglist).word).word, std::mem::transmute(&ep)); + if *ep != 0 { + sh_invalidnum((*(*garglist).word).word); + conversion_error = 1; + } else if *libc::__errno_location() == libc::ERANGE { + printf_erange((*(*garglist).word).word); + } + + garglist = (*garglist).next; + + return ret; + } +} + +fn asciicode() -> libc::c_long { + unsafe { + let ch: libc::c_long; + //let state: mbstate_t = std::mem::zeroed(); + let slen = libc::strlen((*(*garglist).word).word); + let wc: libc::wchar_t = 0; + let mblength = mbtowc( + std::mem::transmute(&wc), + ((*(*garglist).word).word as usize + 1) as *mut libc::c_char, + slen as size_t, + ); + if mblength > 0 { + ch = wc as libc::c_long; + } else { + ch = *(((*(*garglist).word).word as usize + 1) as *mut libc::c_char) as libc::c_long; + } + + garglist = (*garglist).next; + + return ch; + } +} diff --git a/utshell-0.5.0/src/builtins/pushd.rs b/utshell-0.5.0/src/builtins/pushd.rs new file mode 100644 index 00000000..afb510e9 --- /dev/null +++ b/utshell-0.5.0/src/builtins/pushd.rs @@ -0,0 +1,831 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::cd::cd_builtin; +use crate::builtins::common::{ + builtin_usage, get_working_directory, sh_chkwrite, sh_erange, sh_invalidnum, sh_invalidopt, +}; +use crate::dispose_cmd::dispose_words; +use crate::general::{legal_number, polite_directory_format}; +use crate::make_cmd::{make_word, make_word_list}; +use crate::src_common::*; +use crate::variables::get_string_value; + +fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + unsafe { + return *a == *b && libc::strcmp(a, b) == 0; + } +} + +fn ISHELP(s: *const libc::c_char) -> bool { + return STREQ(s, CString::new("--help").unwrap().as_ptr()); +} + +fn ISOPTION(s: *const libc::c_char, c: libc::c_char) -> bool { + unsafe { + return *s == '-' as libc::c_char && *(s.offset(1)) == c && *(s.offset(2)) == 0; + } +} + +#[no_mangle] +pub fn pushd_builtin(listt: *mut WordList) -> i32 { + let orig_list: *mut WordList; + let mut temp: *mut libc::c_char; + let current_directory: *mut libc::c_char; + let mut top: *mut libc::c_char; + let mut j: i32; + let mut flags: i32; + let skipopt: i32; + let mut num: libc::c_long = 0; + let mut direction: libc::c_char; + + unsafe { + let mut list: *mut WordList = listt.clone(); + orig_list = list.clone(); + + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && ISHELP((*((*list).word)).word) + { + builtin_help(); + return EX_USAGE; + } + + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && ISOPTION((*((*list).word)).word, '-' as libc::c_char) + { + list = (*list).next; + skipopt = 1; + } else { + skipopt = 0; + } + + /* If there is no argument list then switch current and + top of list. */ + if list == std::ptr::null_mut() { + if directory_list_offset == 0 { + builtin_error(CString::new("no other directory").unwrap().as_ptr()); + return EXECUTION_FAILURE!(); + } + + current_directory = + get_working_directory(CString::new("pushd").unwrap().as_ptr() as *mut libc::c_char); + if current_directory == std::ptr::null_mut() { + return EXECUTION_FAILURE!(); + } + + j = directory_list_offset - 1; + temp = *((pushd_directory_list as usize + (j * 8) as usize) as *mut *mut libc::c_char); + *((pushd_directory_list as usize + (j * 8) as usize) as *mut *mut libc::c_char) = + current_directory; + j = change_to_temp(temp); + libc::free(temp as *mut c_void); + return j; + } + + flags = 0; + + while skipopt == 0 && list != std::ptr::null_mut() { + if ISOPTION((*((*list).word)).word, 'n' as libc::c_char) { + flags |= NOCD!(); + } else if ISOPTION((*((*list).word)).word, '-' as libc::c_char) { + list = (*list).next; + break; + } else if *((*((*list).word)).word) == '-' as libc::c_char + && *(((*((*list).word)).word as usize + 1) as *mut libc::c_char) + == '\0' as libc::c_char + { + /* Let `pushd -' work like it used to. */ + break; + } else { + direction = *((*((*list).word)).word); + if direction == '+' as libc::c_char || direction == '-' as libc::c_char { + if legal_number( + ((*((*list).word)).word as usize + 1) as *mut libc::c_char, + &mut num, + ) == 0 + { + sh_invalidnum((*((*list).word)).word); + builtin_usage(); + return EX_USAGE; + } + + if direction == '-' as libc::c_char { + num = directory_list_offset as libc::c_long - num; + } + + if num > directory_list_offset as libc::c_long || num < 0 { + pushd_error(directory_list_offset, (*((*list).word)).word); + return EXECUTION_FAILURE!(); + } + flags |= ROTATE!(); + } else if *((*((*list).word)).word) == '-' as libc::c_char { + sh_invalidopt((*((*list).word)).word); + builtin_usage(); + return EX_USAGE; + } else { + break; + } + } + list = (*list).next; + } + + if (flags & ROTATE!()) != 0 { + /* Rotate the stack num times. Remember, the current + directory acts like it is part of the stack. */ + temp = + get_working_directory(CString::new("pushd").unwrap().as_ptr() as *mut libc::c_char); + + if num == 0 { + if (flags & NOCD!()) == 0 { + j = change_to_temp(temp); + } else { + j = EXECUTION_SUCCESS!(); + } + + libc::free(temp as *mut c_void); + return j; + } + + { + top = *((pushd_directory_list as usize + ((directory_list_offset - 1) * 8) as usize) + as *mut *mut libc::c_char); + j = directory_list_offset - 2; + + while j > -1 { + *((pushd_directory_list as usize + ((j + 1) * 8) as usize) + as *mut *mut libc::c_char) = *((pushd_directory_list as usize + + (j * 8) as usize) + as *mut *mut libc::c_char); + j -= 1; + } + + *((pushd_directory_list as usize + ((j + 1) * 8) as usize) + as *mut *mut libc::c_char) = temp; + + temp = top; + num -= 1; + } + + while num != 0 { + top = *((pushd_directory_list as usize + ((directory_list_offset - 1) * 8) as usize) + as *mut *mut libc::c_char); + j = directory_list_offset - 2; + + while j > -1 { + *((pushd_directory_list as usize + ((j + 1) * 8) as usize) + as *mut *mut libc::c_char) = *((pushd_directory_list as usize + + (j * 8) as usize) + as *mut *mut libc::c_char); + j -= 1; + } + + *((pushd_directory_list as usize + ((j + 1) * 8) as usize) + as *mut *mut libc::c_char) = temp; + + temp = top; + num -= 1; + } + + if (flags & NOCD!()) == 0 { + j = change_to_temp(temp); + } else { + j = EXECUTION_SUCCESS!(); + } + + libc::free(temp as *mut c_void); + return j; + } + + if list == std::ptr::null_mut() { + return EXECUTION_SUCCESS!(); + } + + /* Change to the directory in list->word->word. Save the current + directory on the top of the stack. */ + current_directory = + get_working_directory(CString::new("pushd").unwrap().as_ptr() as *mut libc::c_char); + if current_directory == std::ptr::null_mut() { + return EXECUTION_FAILURE!(); + } + + if (flags & NOCD!()) == 0 { + if skipopt != 0 { + j = cd_builtin(orig_list); + } else { + j = cd_builtin(list); + } + } else { + j = EXECUTION_SUCCESS!(); + } + + if j == EXECUTION_SUCCESS!() { + if (flags & NOCD!()) != 0 { + add_dirstack_element(savestring!((*((*list).word)).word)); + } else { + add_dirstack_element(current_directory); + } + + dirs_builtin(std::ptr::null_mut()); + if (flags & NOCD!()) != 0 { + libc::free(current_directory as *mut c_void); + } + return EXECUTION_SUCCESS!(); + } else { + libc::free(current_directory as *mut c_void); + return EXECUTION_FAILURE!(); + } + } +} + +/* Pop the directory stack, and then change to the new top of the stack. +If LIST is non-null it should consist of a word +N or -N, which says +what element to delete from the stack. The default is the top one. */ +#[no_mangle] +pub fn popd_builtin(listt: *mut WordList) -> i32 { + let mut i: i32; + let mut which: libc::c_long; + let mut flags: i32; + let mut direction: libc::c_char; + let mut which_word: *mut libc::c_char; + + unsafe { + let mut list: *mut WordList = listt.clone(); + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && ISHELP((*((*list).word)).word) + { + builtin_help(); + return EX_USAGE; + } + + which_word = std::ptr::null_mut(); + flags = 0; + which = 0; + direction = '+' as libc::c_char; + while list != std::ptr::null_mut() { + if ISOPTION((*((*list).word)).word, 'n' as libc::c_char) { + flags |= NOCD!(); + } else if ISOPTION((*((*list).word)).word, '-' as libc::c_char) { + list = (*list).next; + break; + } else { + direction = *((*((*list).word)).word); + if direction == '+' as libc::c_char || direction == '-' as libc::c_char { + if legal_number( + ((*((*list).word)).word as usize + 1) as *mut libc::c_char, + &mut which, + ) == 0 + { + sh_invalidnum((*((*list).word)).word); + builtin_usage(); + return EX_USAGE; + } + which_word = (*((*list).word)).word; + } else if *((*((*list).word)).word) == '-' as libc::c_char { + sh_invalidopt((*((*list).word)).word); + builtin_usage(); + return EX_USAGE; + } else if (*((*list).word)).word != std::ptr::null_mut() { + builtin_error( + CString::new("%s: invalid argument").unwrap().as_ptr() as *mut libc::c_char, + (*((*list).word)).word, + ); + builtin_usage(); + return EX_USAGE; + } else { + break; + } + } + list = (*list).next; + } + + if which > directory_list_offset as libc::c_long + || (which < -directory_list_offset as libc::c_long) + || (directory_list_offset == 0 && which == 0) + { + if which_word != std::ptr::null_mut() { + pushd_error(directory_list_offset, which_word); + } else { + pushd_error( + directory_list_offset, + CString::new("").unwrap().as_ptr() as *mut libc::c_char, + ); + } + return EXECUTION_FAILURE!(); + } + + /* Handle case of no specification, or top of stack specification. */ + if (direction == '+' as libc::c_char && which == 0) + || (direction == '-' as libc::c_char && which == directory_list_offset as libc::c_long) + { + if (flags & NOCD!()) == 0 { + i = cd_to_string( + *((pushd_directory_list as usize + ((directory_list_offset - 1) * 8) as usize) + as *mut *mut libc::c_char), + ); + } else { + i = EXECUTION_SUCCESS!(); + } + + if i != EXECUTION_SUCCESS!() { + return i; + } + + directory_list_offset -= 1; + + libc::free( + (*((pushd_directory_list as usize + (directory_list_offset * 8) as usize) + as *mut *mut libc::c_char)) as *mut c_void, + ); + } else { + /* Since an offset other than the top directory was specified, + remove that directory from the list and shift the remainder + of the list into place. */ + if direction == '+' as libc::c_char { + i = directory_list_offset - which as i32; + } else { + i = which as i32; + } + + if i < 0 || i > directory_list_offset { + if which_word != std::ptr::null_mut() { + pushd_error(directory_list_offset, which_word); + } else { + pushd_error( + directory_list_offset, + CString::new("").unwrap().as_ptr() as *mut libc::c_char, + ); + } + + return EXECUTION_FAILURE!(); + } + libc::free( + (*((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char)) + as *mut c_void, + ); + directory_list_offset -= 1; + + /* Shift the remainder of the list into place. */ + while i < directory_list_offset { + *((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char) = + *((pushd_directory_list as usize + ((i + 1) * 8) as usize) + as *mut *mut libc::c_char); + i += 1; + } + } + + dirs_builtin(std::ptr::null_mut()); + return EXECUTION_SUCCESS!(); + } +} + +/* Print the current list of directories on the directory stack. */ +#[no_mangle] +pub fn dirs_builtin(listt: *mut WordList) -> i32 { + let mut flags: i32 = 0; + let mut desired_index: i32 = -1; + let mut index_flag: i32 = 0; + let mut vflag: i32 = 0; + let mut i: libc::c_long = 0; + let mut temp: *mut libc::c_char; + let mut w: *mut libc::c_char = CString::new("").unwrap().as_ptr() as *mut libc::c_char; + + unsafe { + let mut list: *mut WordList = listt.clone(); + if list != std::ptr::null_mut() + && (*list).word != std::ptr::null_mut() + && ISHELP((*((*list).word)).word) + { + builtin_help(); + return EX_USAGE; + } + + while list != std::ptr::null_mut() { + if ISOPTION((*((*list).word)).word, 'l' as libc::c_char) { + flags |= LONGFORM!(); + } else if ISOPTION((*((*list).word)).word, 'c' as libc::c_char) { + flags |= CLEARSTAK!(); + } else if ISOPTION((*((*list).word)).word, 'v' as libc::c_char) { + vflag |= 2; + } else if ISOPTION((*((*list).word)).word, 'p' as libc::c_char) { + vflag |= 1; + } else if ISOPTION((*((*list).word)).word, '-' as libc::c_char) { + list = (*list).next; + break; + } else if *((*((*list).word)).word) == '+' as libc::c_char + || *((*((*list).word)).word) == '-' as libc::c_char + { + let sign: i32; + w = (*(*list).word).word.offset(1); + if legal_number(w, &mut i) == 0 { + sh_invalidnum((*((*list).word)).word); + builtin_usage(); + return EX_USAGE; + } + + if *((*(*list).word).word) == '+' as libc::c_char { + sign = 1; + } else { + sign = -1; + } + + desired_index = get_dirstack_index(i, sign, &mut index_flag); + } else { + sh_invalidopt((*((*list).word)).word); + builtin_usage(); + return EX_USAGE; + } + list = (*list).next + } + + if (flags & CLEARSTAK!()) != 0 { + clear_directory_stack(); + return EXECUTION_SUCCESS!(); + } + + if index_flag != 0 && (desired_index < 0 || desired_index > directory_list_offset) { + pushd_error(directory_list_offset, w); + return EXECUTION_FAILURE!(); + } + + /* The first directory printed is always the current working directory. */ + if index_flag == 0 || (index_flag == 1 && desired_index == 0) { + temp = + get_working_directory(CString::new("dirs").unwrap().as_ptr() as *mut libc::c_char); + if temp == std::ptr::null_mut() { + temp = + savestring!(CString::new("").unwrap().as_ptr() + as *mut libc::c_char); + } + + if (vflag & 2) != 0 { + if (flags & LONGFORM!()) != 0 { + libc::printf(CString::new("%2d %s").unwrap().as_ptr(), 0, temp); + } else { + libc::printf( + CString::new("%2d %s").unwrap().as_ptr(), + 0, + polite_directory_format(temp), + ); + } + } else { + if (flags & LONGFORM!()) != 0 { + libc::printf(CString::new("%s").unwrap().as_ptr(), temp); + } else { + libc::printf( + CString::new("%s").unwrap().as_ptr(), + polite_directory_format(temp), + ); + } + } + + libc::free(temp as *mut c_void); + if index_flag != 0 { + libc::putchar('\n' as libc::c_int); + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + } + + /* Now print the requested directory stack entries. */ + if index_flag != 0 { + if (vflag & 2) != 0 { + if (flags & LONGFORM!()) != 0 { + libc::printf( + CString::new("%2d %s").unwrap().as_ptr(), + directory_list_offset - desired_index, + *((pushd_directory_list as usize + (desired_index * 8) as usize) + as *mut *mut libc::c_char), + ); + } else { + libc::printf( + CString::new("%2d %s").unwrap().as_ptr(), + directory_list_offset - desired_index, + polite_directory_format( + *((pushd_directory_list as usize + (desired_index * 8) as usize) + as *mut *mut libc::c_char), + ), + ); + } + } else { + if (flags & LONGFORM!()) != 0 { + libc::printf( + CString::new("%s").unwrap().as_ptr(), + *((pushd_directory_list as usize + (desired_index * 8) as usize) + as *mut *mut libc::c_char), + ); + } else { + libc::printf( + CString::new("%s").unwrap().as_ptr(), + polite_directory_format( + *((pushd_directory_list as usize + (desired_index * 8) as usize) + as *mut *mut libc::c_char), + ), + ); + } + } + } else { + i = (directory_list_offset - 1) as libc::c_long; + while i >= 0 { + if vflag >= 2 { + if (flags & LONGFORM!()) != 0 { + libc::printf( + CString::new("\n%2d %s").unwrap().as_ptr(), + directory_list_offset - i as i32, + *((pushd_directory_list as usize + (i * 8) as usize) + as *mut *mut libc::c_char), + ); + } else { + libc::printf( + CString::new("\n%2d %s").unwrap().as_ptr(), + directory_list_offset - i as i32, + polite_directory_format( + *((pushd_directory_list as usize + (i * 8) as usize) + as *mut *mut libc::c_char), + ), + ); + } + } else { + if (flags & LONGFORM!()) != 0 { + if (vflag & 1) != 0 { + libc::printf( + CString::new("%s%s").unwrap().as_ptr(), + CString::new("\n").unwrap().as_ptr() as *mut libc::c_char, + *((pushd_directory_list as usize + (i * 8) as usize) + as *mut *mut libc::c_char), + ); + } else { + libc::printf( + CString::new("%s%s").unwrap().as_ptr(), + CString::new(" ").unwrap().as_ptr() as *mut libc::c_char, + *((pushd_directory_list as usize + (i * 8) as usize) + as *mut *mut libc::c_char), + ); + } + } else { + if (vflag & 1) != 0 { + libc::printf( + CString::new("%s%s").unwrap().as_ptr(), + CString::new("\n").unwrap().as_ptr() as *mut libc::c_char, + polite_directory_format( + *((pushd_directory_list as usize + (i * 8) as usize) + as *mut *mut libc::c_char), + ), + ); + } else { + libc::printf( + CString::new("%s%s").unwrap().as_ptr(), + CString::new(" ").unwrap().as_ptr() as *mut libc::c_char, + polite_directory_format( + *((pushd_directory_list as usize + (i * 8) as usize) + as *mut *mut libc::c_char), + ), + ); + } + } + } + i -= 1; + } + } + + libc::putchar('\n' as libc::c_int); + return sh_chkwrite(EXECUTION_SUCCESS!()); + } +} + +#[no_mangle] +pub fn pushd_error(offset: i32, arg: *mut libc::c_char) { + unsafe { + if offset == 0 { + builtin_error(CString::new("directory stack empty").unwrap().as_ptr()); + } else { + sh_erange( + arg, + CString::new("directory stack index").unwrap().as_ptr() as *mut libc::c_char, + ); + } + } +} + +#[no_mangle] +pub fn clear_directory_stack() { + let mut i: i32 = 0; + unsafe { + while i < directory_list_offset { + libc::free( + *((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char) + as *mut c_void, + ); + i += 1; + } + + directory_list_offset = 0; + } +} + +/* Switch to the directory in NAME. This uses the cd_builtin to do the work, +so if the result is EXECUTION_FAILURE then an error message has already +been printed. */ +#[no_mangle] +pub fn cd_to_string(name: *mut libc::c_char) -> i32 { + unsafe { + let tlist: *mut WordList; + let dir: *mut WordList; + let result: i32; + + dir = make_word_list(make_word(name), std::ptr::null_mut()); + tlist = make_word_list(make_word(CString::new("--").unwrap().as_ptr()), dir); + result = cd_builtin(tlist); + dispose_words(tlist); + return result; + } +} + +#[no_mangle] +pub fn change_to_temp(temp: *mut libc::c_char) -> i32 { + let tt: i32; + + if temp != std::ptr::null_mut() { + tt = cd_to_string(temp); + } else { + tt = EXECUTION_FAILURE!(); + } + + if tt == EXECUTION_SUCCESS!() { + dirs_builtin(std::ptr::null_mut()); + } + + return tt; +} + +#[no_mangle] +pub fn add_dirstack_element(dir: *mut libc::c_char) { + unsafe { + if directory_list_offset == directory_list_size { + directory_list_size += 10; + pushd_directory_list = strvec_resize(pushd_directory_list, directory_list_size); + } + + *((pushd_directory_list as usize + (directory_list_offset * 8) as usize) + as *mut *mut libc::c_char) = dir; + directory_list_offset += 1; + } +} + +#[no_mangle] +pub fn get_dirstack_index(ind: libc::c_long, sign: i32, indexp: *mut i32) -> i32 { + unsafe { + if indexp != std::ptr::null_mut() { + if sign > 0 { + *indexp = 1; + } else { + *indexp = 2; + } + } + /* dirs +0 prints the current working directory. */ + /* dirs -0 prints last element in directory stack */ + if ind == 0 && sign > 0 { + return 0; + } else if ind == directory_list_offset as libc::c_long { + if indexp != std::ptr::null_mut() { + if sign > 0 { + *indexp = 2; + } else { + *indexp = 1; + } + } + return 0; + } else if ind >= 0 && ind <= directory_list_offset as libc::c_long { + if sign > 0 { + return directory_list_offset - ind as i32; + } else { + return ind as i32; + } + } else { + return -1; + } + } +} + +/* Used by the tilde expansion code. */ +#[no_mangle] +pub fn get_dirstack_from_string(strt: *mut libc::c_char) -> *mut libc::c_char { + let ind: i32; + let mut sign: i32; + let mut index_flag: i32; + let mut i: libc::c_long = 0; + + sign = 1; + let mut str1 = strt.clone(); + unsafe { + if *str1 == '-' as libc::c_char || *str1 == '+' as libc::c_char { + if *str1 == '-' as libc::c_char { + sign = -1; + } else { + sign = 1; + } + str1 = (str1 as usize + 1) as *mut libc::c_char; + } + + if legal_number(str1, &mut i) == 0 { + return std::ptr::null_mut(); + } + + index_flag = 0; + ind = get_dirstack_index(i, sign, &mut index_flag); + if index_flag != 0 && (ind < 0 || ind > directory_list_offset) { + return std::ptr::null_mut(); + } + + if index_flag == 0 || (index_flag == 1 && ind == 0) { + return get_string_value(CString::new("PWD").unwrap().as_ptr()); + } else { + return *((pushd_directory_list as usize + (ind * 8) as usize) + as *mut *mut libc::c_char); + } + } +} + +#[no_mangle] +pub fn get_dirstack_element(ind: libc::c_long, sign: i32) -> *mut libc::c_char { + let i: i32; + unsafe { + i = get_dirstack_index(ind, sign, std::ptr::null_mut()); + if i < 0 || i > directory_list_offset { + return std::ptr::null_mut(); + } else { + return *((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char); + } + } +} + +#[no_mangle] +pub fn set_dirstack_element(ind: libc::c_long, sign: i32, value: *mut libc::c_char) { + let i: i32; + unsafe { + i = get_dirstack_index(ind, sign, std::ptr::null_mut()); + if ind == 0 || i < 0 || i > directory_list_offset { + return; + } + libc::free( + (*((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char)) + as *mut c_void, + ); + *((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char) = + savestring!(value); + } +} + +#[no_mangle] +pub fn get_directory_stack(flags: i32) -> *mut WordList { + let mut i: i32; + let mut ret: *mut WordList; + let mut d: *mut libc::c_char; + let t: *mut libc::c_char; + unsafe { + ret = std::ptr::null_mut(); + i = 0; + while i < directory_list_offset { + if (flags & 1) != 0 { + d = polite_directory_format( + *((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char), + ); + } else { + d = *((pushd_directory_list as usize + (i * 8) as usize) as *mut *mut libc::c_char) + } + ret = make_word_list(make_word(d), ret); + i += 1; + } + /* Now the current directory. */ + d = get_working_directory(CString::new("dirstack").unwrap().as_ptr() as *mut libc::c_char); + i = 0; /* sentinel to decide whether or not to free d */ + if d == std::ptr::null_mut() { + d = CString::new(".").unwrap().as_ptr() as *mut libc::c_char; + } else { + if (flags & 1) != 0 { + t = polite_directory_format(d); + } else { + t = d; + } + /* polite_directory_format sometimes returns its argument unchanged. + If it does not, we can free d right away. If it does, we need to + mark d to be deleted later. */ + if t != d { + libc::free(d as *mut c_void); + d = t; + } else { + /* t == d, so d is what we want */ + i = 1; + } + } + ret = make_word_list(make_word(d), ret); + if i != 0 { + libc::free(d as *mut c_void); + } + return ret; /* was (REVERSE_LIST (ret, (WordList *)); */ + } +} diff --git a/utshell-0.5.0/src/builtins/read.rs b/utshell-0.5.0/src/builtins/read.rs new file mode 100644 index 00000000..78901869 --- /dev/null +++ b/utshell-0.5.0/src/builtins/read.rs @@ -0,0 +1,1245 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::array::array_flush; +use crate::arrayfunc::{ + assign_array_var_from_word_list, find_or_make_array_variable, valid_array_reference, +}; +use crate::bashline::{bashline_reset_event_hook, bashline_set_event_hook, initialize_readline}; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_bind_variable, builtin_usage, sh_invalidid, sh_invalidnum, sh_ttyerror, +}; +use crate::dispose_cmd::dispose_words; +use crate::general::{legal_identifier, legal_number, sh_validfd}; +use crate::input::{fd_is_bash_input, sync_buffered_stream}; +use crate::readline::{rl_insert, rl_newline}; +use crate::sig::{ + initialize_terminating_signals, set_signal_handler, termsig_handler, throw_to_top_level, +}; +use crate::src_common::*; +use crate::subst::{ + dequote_list, dequote_string, get_word_from_string, getifs, list_string, + strip_trailing_ifs_whitespace, word_list_remove_quoted_nulls, +}; +use crate::trap::check_signals; +use crate::unwind_prot::{ + add_unwind_protect, begin_unwind_frame, discard_unwind_frame, remove_unwind_protect, + run_unwind_frame, unwind_protect_mem, +}; +use crate::variables::{bind_variable, get_string_value, stupidly_hack_special_variables}; + +static mut old_alrm: Option = None; +static mut reading: libc::c_int = 0; +static mut tty_modified: libc::c_int = 0; +static mut delim: libc::c_char = b'\n' as libc::c_char; + +static mut termsave: tty_save = tty_save { + fd: 0, + attrs: libc::termios { + c_iflag: (0), + c_oflag: (0), + c_cflag: (0), + c_lflag: (0), + c_line: (0), + c_cc: [0; 32], + c_ispeed: (0), + c_ospeed: (0), + }, +}; + +pub static mut sigalrm_seen: libc::c_int = 0; +static mut interactive: libc::c_int = 0; +static mut default_buffered_input: libc::c_int = -1; + +#[no_mangle] +pub fn read_builtin(mut list: *mut WordList) -> i32 { + let mut varname: *mut libc::c_char = libc::PT_NULL as *mut libc::c_char; + let mut size: libc::c_int = 0; + let mut nr: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut saw_escape: libc::c_int = 0; + let mut eof: libc::c_int; + let mut opt: libc::c_int; + let mut retval: libc::c_int; + let mut code: libc::c_int; + let mut print_ps2: libc::c_int; + let mut nflag: libc::c_int = 0; + + let mut i: libc::c_int = 0; + + let mut input_is_tty: libc::c_int = 0; + let mut input_is_pipe: libc::c_int = 0; + let mut unbuffered_read: libc::c_int = 0; + let mut skip_ctlesc: libc::c_int; + let mut skip_ctlnul: libc::c_int; + + let mut raw: libc::c_int = 0; + let mut edit: libc::c_int = 0; + let mut nchars: libc::c_int = 0; + let mut silent: libc::c_int = 0; + let mut have_timeout: libc::c_int = 0; + let mut ignore_delim: libc::c_int = 0; + let mut fd: libc::c_int = 0; + + let mut lastsig: libc::c_int = 0; + let t_errno: libc::c_int; + + let mut _mb_cur_max: libc::c_int; + + let mut tmsec: libc::c_uint = 0; + let mut tmusec: libc::c_uint = 0; + + let mut ival: libc::c_long = 0; + let mut uval: libc::c_long = 0; + let mut intval: libc::c_long = 0; + + let mut c: libc::c_char = 0; + + let mut input_string: *mut libc::c_char; + let mut orig_input_string: *mut libc::c_char; + let ifs_chars_null = CString::new("").unwrap(); + let mut ifs_chars: *mut libc::c_char; + let mut prompt: *mut libc::c_char = PT_NULL as *mut libc::c_char; + let mut arrayname: *mut libc::c_char = PT_NULL as *mut libc::c_char; + + let mut e: *mut libc::c_char; + let t: *mut libc::c_char; + let t1: *mut libc::c_char; + let mut ps2: *mut libc::c_char; + let mut tofree: *mut libc::c_char; + + let mut tsb: libc::stat; + + let mut var: *mut SHELL_VAR = PT_NULL as *mut SHELL_VAR; + + let mut ttattrs: libc::termios; + let mut ttset: libc::termios; + unsafe { + ttattrs = std::mem::zeroed(); + ttset = std::mem::zeroed(); + } + + let alist: *mut WordList; + + let vflags: libc::c_int; + let mut rlbuf: *mut libc::c_char = null_mut(); + let mut itext: *mut libc::c_char = null_mut(); + + let mut rlind: libc::c_int = 0; + + let mut save_instream: *mut libc::FILE; + + let mut mb_cur_max: libc::c_int = 1; + + unsafe { + // if termsave.is_none() { + // let tmp: tty_save = std::mem::zeroed(); + // termsave = Some(tmp); + // } + // ptermsave = std::mem::transmute(&termsave.unwrap()); + + reset_internal_getopt(); + let opt_str = CString::new("ersa:d:i:n:p:t:u:N:").unwrap(); + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'r' => raw = 1, + 'p' => prompt = list_optarg, + 's' => silent = 1, + 'e' => edit = 1, + 'i' => itext = list_optarg, + 'a' => arrayname = list_optarg, + 't' => { + code = uconvert( + list_optarg, + &mut ival, + &mut uval, + PT_NULL as *mut *mut libc::c_char, + ); + if code == 0 || ival < 0 || uval < 0 { + let c_err = CString::new("%s: invalid timeout specification").unwrap(); + builtin_error(c_err.as_ptr(), list_optarg); + return EXECUTION_FAILURE; + } else { + have_timeout = 1; + tmsec = ival as libc::c_uint; + tmusec = uval as libc::c_uint; + } + } + 'N' | 'n' => { + if opt_char == 'N' { + ignore_delim = 1; + delim = 255 as u8 as libc::c_char; + } + nflag = 1; + code = legal_number(list_optarg, &mut intval); + if code == 0 || intval < 0 || intval != (intval as libc::c_int) as libc::c_long + { + sh_invalidnum(list_optarg); + return EXECUTION_FAILURE; + } else { + nchars = intval as libc::c_int; + } + } + 'u' => { + code = legal_number(list_optarg, &mut intval); + if code == 0 || intval < 0 || intval != (intval as libc::c_int) as libc::c_long + { + let c_err = + CString::new("%s: invalid file descriptor specification").unwrap(); + builtin_error(c_err.as_ptr(), list_optarg); + return EXECUTION_FAILURE; + } else { + fd = intval as libc::c_int; + } + if sh_validfd(fd) == 0 { + let c_err = CString::new("%d: invalid file descriptor: %s").unwrap(); + builtin_error(c_err.as_ptr(), fd, libc::strerror(nix::errno::errno())); + return EXECUTION_FAILURE; + } + } + 'd' => { + delim = *list_optarg; + } + + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + } + + list = loptend; + + //-t + if have_timeout != 0 && tmsec == 0 && tmusec == 0 { + return if input_avail(fd) != 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; + } + + vflags = if assoc_expand_once != 0 { + (VA_NOEXPAND | VA_ONEWORD) as libc::c_int + } else { + 0 + }; + if !list.is_null() + && legal_identifier((*(*list).word).word) == 0 + && valid_array_reference((*(*list).word).word, vflags) == 0 + { + // sh_invalidid((*(*list).word).word); + sh_invalidid((*(*list).word).word); + return EXECUTION_FAILURE; + } + + //忽略界定符 + if ignore_delim != 0 { + //-N ignore_delim = 1 + delim = 255 as u8 as libc::c_char; + } + + ifs_chars = getifs(); //ifs_chars is "\n" + if ifs_chars.is_null() { + ifs_chars = ifs_chars_null.as_ptr() as *mut libc::c_char; + } + + if ignore_delim != 0 { + ifs_chars = ifs_chars_null.as_ptr() as *mut libc::c_char; + } + + skip_ctlesc = 0; + skip_ctlnul = 0; + e = ifs_chars; + + loop { + if *e == 0 { + break; + } + skip_ctlesc |= (*e == 1) as libc::c_int; + skip_ctlnul |= (*e == 117) as libc::c_int; + e = ((e as usize) + 1) as *mut libc::c_char; + } + + input_string = malloc(112) as *mut libc::c_char; + *input_string = b'\0' as libc::c_char; + + 'out_assig_vars: loop { + if nflag == 1 && nchars == 0 { + let mut gc: libc::c_int = 0; + retval = libc::read(fd, &mut gc as *mut i32 as *mut c_void, 0) as libc::c_int; + retval = if retval >= 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; + + break 'out_assig_vars; + } + + //设置TMOUTåŽï¼ŒTMOUTæ˜¯é»˜è®¤è¯»å–æ—¶é—´ + let str_val = CString::new("TMOUT").unwrap(); + e = get_string_value(str_val.as_ptr()); + if have_timeout == 0 && !e.is_null() { + code = uconvert(e, &mut ival, &mut uval, 0 as *mut *mut libc::c_char); + if code == 0 || ival < 0 || uval < 0 { + tmsec = 0; + tmusec = 0; + } else { + tmsec = ival as libc::c_uint; + tmusec = uval as libc::c_uint; + } + } + + let frame_name = CString::new("r_read_builtin").unwrap(); //有没有å¯èƒ½æ˜¯r_read_builtin? + begin_unwind_frame(frame_name.as_ptr() as *mut libc::c_char); + + if interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input(fd) != 0 { + sync_buffered_stream(default_buffered_input); + } + + input_is_tty = libc::isatty(fd); + if input_is_tty == 0 { + input_is_pipe = (libc::lseek(fd, 0, libc::SEEK_CUR) < 0 + && (errno() == libc::ESPIPE)) as libc::c_int; + } + + //如果设置 -p,-e,-sä½†è¾“å…¥ä¸æ˜¯ç»ˆç«¯ï¼Œå¿½ç•¥ + if (!prompt.is_null() || edit != 0 || silent != 0) && input_is_tty == 0 { + itext = PT_NULL as *mut libc::c_char; + edit = 0; + silent = 0; + } + + if edit != 0 { + add_unwind_protect( + std::mem::transmute::>(free), + rlbuf, + ); + } + + tsb = std::mem::zeroed(); + if tmsec > 0 || tmusec > 0 { + if (libc::fstat(fd, &mut tsb as *mut libc::stat) < 0) + || ((tsb.st_mode & __S_IFMT) == __S_IFREG) + { + tmsec = 0; + tmusec = 0; + } + } + + if tmsec > 0 || tmusec > 0 { + code = __sigsetjmp(&mut alrmbuf as *mut __jmp_buf_tag, 0); + if code != 0 { + sigalrm_seen = 0; + orig_input_string = PT_NULL as *mut libc::c_char; + *input_string.offset(i as isize) = b'\0' as libc::c_char; + if i == 0 { + t = libc::malloc(1) as *mut libc::c_char; + *t = b'\0' as libc::c_char; + } else { + t = libc::strcpy( + malloc((libc::strlen(input_string) + 1) as usize) as *mut libc::c_char, + input_string, + ); + } + run_unwind_frame(frame_name.as_ptr() as *mut libc::c_char); + input_string = t; + retval = 128 + libc::SIGALRM; + break 'out_assig_vars; + } + + if interactive_shell == 0 { + initialize_terminating_signals(); + } + + old_alrm = set_signal_handler( + libc::SIGALRM, + std::mem::transmute::>(sigalrm), + ); + add_unwind_protect( + std::mem::transmute::>(reset_alarm), + 0 as *mut libc::c_void as *mut libc::c_char, + ); + + if edit != 0 { + add_unwind_protect( + std::mem::transmute::>( + reset_attempted_completion_function, + ), + 0 as *mut libc::c_void as *mut libc::c_char, + ); + add_unwind_protect( + std::mem::transmute::>(bashline_reset_event_hook), + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + falarm(tmsec, tmusec); + } + + if nchars > 0 || delim != b'\n' as libc::c_char { + //-d -n + if edit != 0 { + if nchars > 0 { + unwind_protect_mem( + &mut rl_num_chars_to_read as *mut libc::c_int as *mut libc::c_char, + std::mem::size_of_val(&rl_num_chars_to_read) as libc::c_int, + ); + rl_num_chars_to_read = nchars; + } + + if delim != b'\n' as libc::c_char { + set_eol_delim(delim as libc::c_int); + add_unwind_protect( + std::mem::transmute::>( + reset_eol_delim, + ), + PT_NULL as *mut libc::c_char, + ); + } + } else if input_is_tty != 0 { + //-d -n + // termsave.unwrap().fd = fd; + termsave.fd = fd; + ttgetattr(fd, &mut ttattrs as *mut libc::termios); + // termsave.unwrap().attrs = ttattrs; + termsave.attrs = ttattrs; + + ttset = ttattrs; + if silent != 0 { + i = ttfd_cbreak(fd, std::mem::transmute(&ttset)); + } else { + i = ttfd_onechar(fd, std::mem::transmute(&ttset)); + } + + if i < 0 { + sh_ttyerror(1); + } + tty_modified = 1; + // add_unwind_protect(ttyrestore as *mut c_void, ptermsave); + add_unwind_protect( + std::mem::transmute::>(ttyrestore), + &mut termsave as *mut tty_save as *mut libc::c_char, + ); + if interactive_shell == 0 { + initialize_terminating_signals(); + } + } + } else if silent != 0 { + //-s + // termsave.unwrap().fd = fd; + termsave.fd = fd; + ttgetattr(fd, &mut ttattrs as *mut libc::termios); + // termsave.unwrap().attrs = ttattrs; + termsave.attrs = ttattrs; + + ttset = ttattrs; + i = ttfd_noecho(fd, std::mem::transmute(&ttset)); + if i < 0 { + sh_ttyerror(1); + } + + tty_modified = 1; + // add_unwind_protect(ttyrestore as *mut c_void, ptermsave); + // add_unwind_protect(ttyrestore as *mut c_void, &mut termsave); + add_unwind_protect( + std::mem::transmute::>(ttyrestore), + &mut termsave as *mut tty_save as *mut libc::c_char, + ); + if interactive_shell == 0 { + initialize_terminating_signals(); + } + } + + save_instream = std::mem::zeroed(); + if edit != 0 && fd != 0 { + if bash_readline_initialized == 0 { + initialize_readline(); + } + + unwind_protect_mem( + std::mem::transmute(rl_instream), + std::mem::size_of_val(&rl_instream) as libc::c_int, + ); + save_instream = rl_instream; + rl_instream = libc::fdopen(fd, "r".as_ptr() as *const libc::c_char); + } + + add_unwind_protect( + std::mem::transmute::>(free), + input_string, + ); + check_alrm(); + if nchars > 0 && input_is_tty == 0 && ignore_delim != 0 { + unbuffered_read = 2; + } else if nchars > 0 || delim != b'\n' as libc::c_char || input_is_pipe != 0 { + unbuffered_read = 1; + } + + if !prompt.is_null() && edit == 0 { + //-p no -e + // eprintln!("{}", CStr::from_ptr(prompt).to_str().unwrap()); + eprint!("{}", CStr::from_ptr(prompt).to_str().unwrap()); + } + + ps2 = PT_NULL as *mut libc::c_char; + print_ps2 = 0; + eof = 0; + retval = 0; + 'get_input_string: loop { + if sigalrm_seen != 0 { + siglongjmp(std::mem::transmute(&alrmbuf), 1); + } + + if edit != 0 { + //没有设置-e edit等于0 + if !rlbuf.is_null() + && *((rlbuf as usize + rlind as usize) as *mut libc::c_char) == 0 + && delim != 0 + { + libc::free(rlbuf as *mut c_void); + rlbuf = PT_NULL as *mut libc::c_char; + } + if rlbuf.is_null() { + reading = 1; + rlbuf = if prompt.is_null() { + // edit_line("".as_ptr() as *mut libc::c_char, itext)} + // let c_str = b'\0'; // b'\0'代表的是空字符串,和String::from("")䏿˜¯åŒä¸€ä¸ªä¸œè¥¿ã€‚ + edit_line(b'\0' as *mut libc::c_char, itext) // b'\0'代表的是空字符串,和String::from("")䏿˜¯åŒä¸€ä¸ªä¸œè¥¿ã€‚ + } else { + edit_line(prompt, itext) + }; + reading = 0; + rlind = 0; + } + if rlbuf.is_null() { + eof = 1; + break 'get_input_string; + } + c = *((rlbuf as usize + rlind as usize) as *mut libc::c_char); + rlind += 1; + } else { + if print_ps2 != 0 { + if ps2.is_null() { + ps2 = get_string_value("PS2".as_ptr() as *const libc::c_char); + } + eprintln!("{}", CStr::from_ptr(prompt).to_str().unwrap()); + print_ps2 = 0; + } + + reading = 1; + check_alrm(); + *(libc::__errno_location()) = 0; + if unbuffered_read == 2 { + retval = if posixly_correct != 0 { + zreadintr(fd, &mut c as *mut libc::c_char, 1) as libc::c_int + } else { + zreadn(fd, &mut c as *mut libc::c_char, (nchars - nr) as size_t) + as libc::c_int + }; + } else if unbuffered_read != 0 { + retval = if posixly_correct != 0 { + zreadintr(fd, &mut c as *mut libc::c_char, 1) as libc::c_int + } else { + zread(fd, &mut c as *mut libc::c_char, 1) as libc::c_int + }; + } else { + retval = if posixly_correct != 0 { + zreadcintr(fd, &mut c as *mut libc::c_char) as libc::c_int + } else { + //-a -t + zreadc(fd, &mut c as *mut libc::c_char) as libc::c_int + }; + } + reading = 0; + + if retval <= 0 { + let t = *libc::__errno_location(); + if retval < 0 && *libc::__errno_location() == libc::EINTR { + check_signals(); + //lastsig = LASTSIG(); + if terminating_signal != 0 { + lastsig = terminating_signal; + } else { + lastsig = if interrupt_state != 0 { + libc::SIGINT + } else { + 0 + }; + } + + if lastsig == 0 { + lastsig = trapped_signal_received; + } + } else { + lastsig = 0; + } + if terminating_signal != 0 && tty_modified != 0 { + // ttyrestore(); + ttyrestore(&mut termsave); + } + check_alrm(); + eof = 1; + *libc::__errno_location() = t; + break 'get_input_string; + } + + quit(); + } + + if retval <= 0 { + check_alrm(); + } + + if mb_cur_max <= 4 { + mb_cur_max = 4; + } + if i + mb_cur_max >= size { + size += 128; + let t: *mut libc::c_char = + realloc(input_string as *mut c_void, size as usize) as *mut libc::c_char; + if t != input_string { + input_string = t; + remove_unwind_protect(); + add_unwind_protect( + std::mem::transmute::>(free), + input_string, + ); + } + } + 'out_add_char: loop { + if pass_next != 0 { + pass_next = 0; + if c == b'\n' as libc::c_char { + if skip_ctlesc == 0 && i > 0 { + i -= 1; + } + if interactive != 0 && input_is_tty != 0 && raw == 0 { + print_ps2 = 1; + } + } else { + break 'out_add_char; + } + continue 'get_input_string; + } + + if c == b'\\' as libc::c_char && raw == 0 { + pass_next += 1; + if skip_ctlesc == 0 { + saw_escape += 1; + *((input_string as usize + i as usize) as *mut libc::c_char) = + CTLESC as libc::c_char; + i += 1; + } + + continue 'get_input_string; + } + + if ignore_delim == 0 && c == delim { + //-a + break 'get_input_string; + } + + if c == b'\0' as libc::c_char && delim != b'\0' as libc::c_char { + continue 'get_input_string; + } + + if (skip_ctlesc == 0 && c == CTLESC as libc::c_char) + || (skip_ctlnul == 0 && c == CTLNUL as libc::c_char) + { + saw_escape += 1; + *((input_string as usize + i as usize) as *mut libc::c_char) = + CTLESC as libc::c_char; + i += 1; + } + break 'out_add_char; + } //out_add_char + + *((input_string as usize + i as usize) as *mut libc::c_char) = c; + i += 1; + check_alrm(); + + if mb_cur_max > 1 && is_basic(c) == 0 { + *((input_string as usize + i as usize) as *mut libc::c_char) = + b'\0' as libc::c_char; + + if edit != 0 { + let clen = mbrlen( + (rlbuf as usize + rlind as usize - 1) as *const libc::c_char, + mb_cur_max as size_t, + std::mem::transmute(&PT_NULL), + ); + if clen > 1 { + libc::memcpy( + (input_string as usize + i as usize) as *mut c_void, + (rlbuf as usize + rlind as usize) as *mut c_void, + (clen - 1) as usize, + ); + i += clen as libc::c_int - 1; + rlind += clen as libc::c_int - 1; + } + } else if locale_utf8locale == 0 || ((c as u8 & 0x80) != 0) { + i += read_mbchar(fd, input_string, i, c as libc::c_int, unbuffered_read); + } + } + nr += 1; + if nchars > 0 && nr >= nchars { + break 'get_input_string; + } + } //get_input_string + + *((input_string as usize + i as usize) as *mut libc::c_char) = b'\0' as libc::c_char; + check_alrm(); + + if edit != 0 { + libc::free(rlbuf as *mut c_void); + } + + if retval < 0 { + t_errno = *libc::__errno_location(); + if *libc::__errno_location() != EINTR { + let c_err = CString::new("read error: %d: %s").unwrap(); + builtin_error( + c_err.as_ptr(), + fd, + libc::strerror(*libc::__errno_location()), + ); + } + + run_unwind_frame(frame_name.as_ptr() as *mut libc::c_char); + return if t_errno != EINTR { + EXECUTION_FAILURE + } else { + 128 + lastsig + }; + } + + if tmsec > 0 || tmusec > 0 { + reset_alarm(); + } + + if nchars > 0 || delim != b'\n' as libc::c_char { + if edit != 0 { + if nchars > 0 { + rl_num_chars_to_read = 0; + } + if delim != b'\n' as libc::c_char { + reset_eol_delim(0 as *mut libc::c_char); + } + } else if input_is_tty != 0 { + // ttyrestore(); + ttyrestore(&mut termsave); + } + } else if silent != 0 { + // ttyrestore(); + ttyrestore(&mut termsave); + } + + // if unbuffered_read != 0 { + if unbuffered_read == 0 { + zsyncfd(fd); + } + + if !save_instream.is_null() { + rl_instream = save_instream; + } + + discard_unwind_frame(frame_name.as_ptr() as *mut libc::c_char); + + retval = if eof != 0 { + EXECUTION_FAILURE + } else { + EXECUTION_SUCCESS + }; + + break 'out_assig_vars; + } //out_assig_vars + + if !arrayname.is_null() { + //å’Œ-a有关 + if legal_identifier(arrayname) == 0 { + //标签ä¸ç¬¦åˆè§„范 + // sh_invalidid(arrayname); + sh_invalidid(arrayname); + libc::free(input_string as *mut c_void); + return EXECUTION_FAILURE; + } + + var = find_or_make_array_variable(arrayname, 1); + if var.is_null() { + libc::free(input_string as *mut c_void); + return EXECUTION_FAILURE; /* readonly or noassign */ + } + if ((*var).attributes & 0x0000040) != 0 { + let c_err = + CString::new("%s: cannot convert associative to indexed array").unwrap(); + builtin_error(c_err.as_ptr(), arrayname); + libc::free(input_string as *mut c_void); + return EXECUTION_FAILURE; /* existing associative array */ + } else if ((*var).attributes & 0x0001000) != 0 { + (*var).attributes &= ((*var).attributes as u32 ^ 0xffffffff as u32) as i32; + } + + array_flush(std::mem::transmute((*var).value)); + + alist = list_string(input_string, ifs_chars, 0); + if !alist.is_null() { + if saw_escape != 0 { + dequote_list(alist); + } else { + word_list_remove_quoted_nulls(alist); + } + assign_array_var_from_word_list(var, alist, 0); + dispose_words(alist); + } + + libc::free(input_string as *mut c_void); + + return retval; + } + + if list.is_null() { + //å’Œ-d相关 -n 0å¯ä»¥é€€å‡ºï¼Œæœ‰æ˜¾ç¤º + if saw_escape != 0 { + let t = dequote_string(input_string); + var = bind_variable(b"REPLY\0" as *const u8 as *const libc::c_char, t, 0); + libc::free(t as *mut c_void); + } else { + var = bind_variable( + b"REPLY\0" as *const u8 as *const libc::c_char, + input_string, + 0, + ); + } + let cond = var.is_null() + || ((*var).attributes & 0x0000002) != 0 + || ((*var).attributes & 0x0004000) != 0; + if cond { + retval = EXECUTION_FAILURE; + } else { + (*var).attributes &= ((*var).attributes as u32 ^ 0xffffffff as u32) as i32; + } + + libc::free(input_string as *mut c_void); + return retval; + } + + orig_input_string = input_string; + + let mut t = input_string; + while !ifs_chars.is_null() + && *ifs_chars != 0 + && (*t == b' ' as libc::c_char + || *t == b'\t' as libc::c_char + || *t == b'\n' as libc::c_char) + && (ifs_cmap[*t as usize] != 0) + { + t = (t as usize + 1) as *mut libc::c_char; + } + input_string = t; + + while !(*list).next.is_null() { + varname = (*((*list).word)).word; + + if legal_identifier(varname) == 0 && valid_array_reference(varname, vflags) == 0 { + // sh_invalidid(varname); + sh_invalidid(varname); + libc::free(orig_input_string as *mut c_void); + return EXECUTION_FAILURE; + } + + if *input_string != 0 { + t = get_word_from_string( + std::mem::transmute(&input_string), + ifs_chars, + std::mem::transmute(&e), + ); + if !t.is_null() { + *e = b'\0' as libc::c_char; + } + + if !t.is_null() && saw_escape != 0 { + let t1 = dequote_string(t); + var = bind_read_variable(varname, t1); + libc::free(t1 as *mut c_void); + } else { + var = bind_read_variable( + varname, + if !t.is_null() { + t + } else { + "".as_ptr() as *mut libc::c_char + }, + ); + } + } else { + t = PT_NULL as *mut libc::c_char; + var = bind_read_variable(varname, "".as_ptr() as *mut libc::c_char); + } + + if !t.is_null() { + libc::free(t as *mut c_void); + } + + if var.is_null() { + libc::free(orig_input_string as *mut c_void); + return EXECUTION_FAILURE; + } + + stupidly_hack_special_variables(varname); + (*var).attributes &= ((*var).attributes as u32 ^ 0xffffffff as u32) as i32; + + list = (*list).next; + } + + if legal_identifier((*((*list).word)).word) == 0 + && valid_array_reference((*((*list).word)).word, vflags) == 0 + { + // sh_invalidid((*((*list).word)).word); + sh_invalidid((*((*list).word)).word); + libc::free(orig_input_string as *mut c_void); + return EXECUTION_FAILURE; + } + + tofree = PT_NULL as *mut libc::c_char; + if *input_string != 0 { + t1 = input_string; + t = get_word_from_string( + std::mem::transmute(&input_string), + ifs_chars, + std::mem::transmute(&e), + ); + if *input_string == 0 { + input_string = t; + tofree = input_string; + } else { + input_string = strip_trailing_ifs_whitespace(t1, ifs_chars, saw_escape); + tofree = t; + } + } + + if saw_escape != 0 && !input_string.is_null() && *input_string != 0 { + t = dequote_string(input_string); + var = bind_read_variable((*((*list).word)).word, t); + libc::free(t as *mut c_void); + } else { + var = bind_read_variable( + (*((*list).word)).word, + if !input_string.is_null() { + input_string + } else { + "".as_ptr() as *mut libc::c_char + }, + ); + } + + if !var.is_null() { + stupidly_hack_special_variables((*((*list).word)).word); + (*var).attributes &= ((*var).attributes as u32 ^ 0xffffffff as u32) as i32; + } else { + retval = EXECUTION_FAILURE; + } + + if !tofree.is_null() { + libc::free(tofree as *mut c_void); + } + libc::free(orig_input_string as *mut c_void); + return retval; + } //unsafe +} + +/* ---------------------------------------------------------------------------------- */ + +// pub fn is_basic(c: i8) -> u32 { +// let is_basic_table :[c_uint; 8] = [ 0x00001a00, 0xffffffef, 0xfffffffe, 0x7ffffffe, 0,0,0,0]; + +// let index = (c >> 5) as usize; +// return (is_basic_table[index] >> (c & 31) ) & 1; +// } + +#[inline] +fn is_basic(c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} + +pub fn bind_read_variable(name: *mut libc::c_char, value: *mut libc::c_char) -> *mut SHELL_VAR { + let v: *mut SHELL_VAR; + unsafe { + // v = builtin_bind_variable(name, value, 0); + v = builtin_bind_variable(name, value, 0); + + if v.is_null() { + return v; + } else { + if ((*v).attributes & 0x0000002) != 0 || ((*v).attributes & 0x0004000) != 0 { + return PT_NULL as *mut SHELL_VAR; + } else { + return v; + } + } + } +} + +fn read_mbchar( + fd: libc::c_int, + string: *mut libc::c_char, + ind: libc::c_int, + ch: libc::c_int, + unbuffered: libc::c_int, +) -> libc::c_int { + let mut i: size_t = 1; + let mut r: ssize_t; + let c: libc::c_char = 0; + let mut ret: ssize_t; + + unsafe { + let mut mbchar: [libc::c_char; MB_LEN_MAX as usize + 1] = std::mem::zeroed(); + let mut ps: mbstate_t = std::mem::zeroed(); + let mut ps_back: mbstate_t = std::mem::zeroed(); + let wc: libc::wchar_t = std::mem::zeroed(); + + 'out: loop { + mbchar[0] = ch as libc::c_char; + for _n in 0..=MB_LEN_MAX { + ps_back = ps; + ret = mbrtowc( + std::mem::transmute(&wc), + std::mem::transmute(&mbchar), + i, + std::mem::transmute(&ps), + ) as ssize_t; + if ret == -2 { + ps = ps_back; + + /* We don't want to be interrupted during a multibyte char read */ + if unbuffered == 2 { + r = zreadn(fd, std::mem::transmute(&c), 1) as ssize_t; + } else if unbuffered != 0 { + r = zread(fd, std::mem::transmute(&c), 1) as ssize_t; + } else { + r = zreadc(fd, std::mem::transmute(&c)) as ssize_t; + } + if r <= 0 { + break 'out; + } + mbchar[i as usize] = c; + i += 1; + continue; + } else if ret == -1 || ret == 0 || ret > 0 { + break; + } + } + break 'out; + } + if i > 1 { + r = 1; + while r < i as ssize_t { + *((string as usize + ind as usize + r as usize - 1) as *mut libc::c_char) = + mbchar[r as usize]; + + r += 1; + } + } + return (i - 1) as libc::c_int; + } +} + +fn quit() { + unsafe { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + + if interrupt_state != 0 { + throw_to_top_level(); + } + } +} + +fn check_alrm() { + unsafe { + if sigalrm_seen != 0 { + siglongjmp(std::mem::transmute(&alrmbuf), 1); + // siglongjmp (&mut alrmbuf as *mut __jmp_buf_tag, 1); + } + } +} + +// static mut old_attempted_completion_function: usize = 0; +static mut old_attempted_completion_function: Option = None; +pub fn reset_attempted_completion_function(_cp: *mut libc::c_char) { + unsafe { + if rl_attempted_completion_function.is_none() && old_attempted_completion_function.is_some() + { + rl_attempted_completion_function = + std::mem::transmute(old_attempted_completion_function); + } + } +} + +static mut old_startup_hook: usize = 0; +static mut deftext: *mut libc::c_char = PT_NULL as *mut libc::c_char; + +fn set_itext() -> libc::c_int { + let mut r1 = 0; + let mut r2 = 0; + + unsafe { + if old_startup_hook != 0 { + let fp: rl_hook_func_t = std::mem::transmute(old_startup_hook); + r1 = fp(); + } + if !deftext.is_null() { + r2 = rl_insert_text(deftext as *const libc::c_char); + deftext = PT_NULL as *mut libc::c_char; + rl_startup_hook = std::mem::transmute(old_startup_hook); + old_startup_hook = std::mem::transmute(0 as usize); + } + } + return (r1 != 0 || r2 != 0) as libc::c_int; +} + +fn edit_line(p: *mut libc::c_char, itext: *mut libc::c_char) -> *mut libc::c_char { + let mut len: i32; + unsafe { + if bash_readline_initialized == 0 { + initialize_readline(); + } + + old_attempted_completion_function = std::mem::transmute(rl_attempted_completion_function); + rl_attempted_completion_function = std::mem::transmute(0 as usize); + bashline_set_event_hook(); + if !itext.is_null() { + old_startup_hook = std::mem::transmute(rl_startup_hook); + rl_startup_hook = std::mem::transmute(set_itext as usize); + deftext = itext; + } + + let mut ret = readline(p); + + rl_attempted_completion_function = std::mem::transmute(old_attempted_completion_function); + old_attempted_completion_function = std::mem::transmute(0 as usize); + bashline_reset_event_hook(); + + if ret.is_null() { + return ret; + } + + len = libc::strlen(ret) as i32; + ret = realloc(ret as *mut c_void, (len + 2) as usize) as *mut libc::c_char; + *ret.offset(len as isize) = delim; + len += 1; + *ret.offset(len as isize) = b'\0' as libc::c_char; + return ret; + } +} + +fn sigalrm(_s: libc::c_int) { + unsafe { + sigalrm_seen = 1; + } +} + +fn reset_alarm() { + unsafe { + falarm(0, 0); + set_signal_handler(libc::SIGALRM, old_alrm); + } +} + +fn ttyrestore(ttp: *mut tty_save) { + unsafe { + ttsetattr((*ttp).fd, &mut (*ttp).attrs); + tty_modified = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn read_tty_cleanup() { + unsafe { + if tty_modified != 0 { + ttyrestore(&mut termsave); + } + } +} + +#[no_mangle] +pub fn read_tty_modified() -> libc::c_int { + unsafe { + return tty_modified; + } +} + +static mut old_delim_ctype: libc::c_int = 0; +// static mut old_delim_func: usize = 0; +static mut old_delim_func: Option = None; +static mut old_newline_ctype: libc::c_int = 0; +// static mut old_newline_func: usize = 0; +static mut old_newline_func: Option = None; + +static mut delim_char: u8 = 0; + +fn set_eol_delim(c: libc::c_int) { + let cmap: Keymap; + unsafe { + if bash_readline_initialized == 0 { + initialize_readline(); + } + + // let cmap = rl_get_keymap(); + cmap = rl_get_keymap(); + + old_newline_ctype = (*cmap.offset((b'M' as i32 & 0x1f) as isize)).Type as libc::c_int; + old_newline_func = (*cmap.offset((b'M' as i32 & 0x1f) as isize)).function; + old_delim_ctype = (*cmap.offset(c as isize)).Type as libc::c_int; + old_delim_func = (*cmap.offset(c as isize)).function; + + /* Change newline to self-insert */ + (*cmap.offset((b'M' as i32 & 0x1f) as isize)).Type = ISFUNC as libc::c_char; + (*cmap.offset((b'M' as i32 & 0x1f) as isize)).function = Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + rl_command_func_t, + >(rl_insert)); + + /* Bind the delimiter character to accept-line. */ + (*cmap.offset(c as isize)).Type = ISFUNC as libc::c_char; + (*cmap.offset(c as isize)).function = Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + rl_command_func_t, + >(rl_newline)); + + delim_char = c as u8; + } +} + +fn reset_eol_delim(_cp: *mut libc::c_char) { + unsafe { + let cmap = rl_get_keymap(); + let n = std::mem::size_of_val(&*cmap); + let ret_pos = (b'M' & 0x1f) as usize * n; + let delim_pos = (delim_char & 0x1f) as usize * n; + + (*((cmap as usize + ret_pos) as Keymap)).Type = old_newline_ctype as libc::c_char; + (*((cmap as usize + ret_pos) as Keymap)).function = std::mem::transmute(old_newline_func); + + (*((cmap as usize + delim_pos) as Keymap)).Type = old_delim_ctype as libc::c_char; + (*((cmap as usize + delim_pos) as Keymap)).function = std::mem::transmute(old_delim_func); + } +} diff --git a/utshell-0.5.0/src/builtins/return_1.rs b/utshell-0.5.0/src/builtins/return_1.rs new file mode 100644 index 00000000..032498c8 --- /dev/null +++ b/utshell-0.5.0/src/builtins/return_1.rs @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::common::get_exitstat; +use crate::src_common::*; + +extern "C" { + pub fn siglongjmp(__env: *mut __jmp_buf_tag, __val: libc::c_int); +} + +#[no_mangle] +pub fn return_builtin(list: *mut WordList) -> i32 { + unsafe { + if !list.is_null() + && !(*list).word.is_null() + && libc::strcmp( + (*((*list).word)).word, + "--help\0".as_ptr() as *const libc::c_char, + ) == 0 + { + builtin_help(); + return EX_USAGE; + } + + return_catch_value = get_exitstat(list); + if return_catch_flag != 0 { + siglongjmp(std::mem::transmute(&return_catch), 1); + } else { + builtin_error( + "can only `return' from a function or sourced script\0".as_ptr() + as *const libc::c_char, + ); + return EX_USAGE; + } + } + return EXECUTION_SUCCESS; +} diff --git a/utshell-0.5.0/src/builtins/set.rs b/utshell-0.5.0/src/builtins/set.rs new file mode 100644 index 00000000..a8b1121b --- /dev/null +++ b/utshell-0.5.0/src/builtins/set.rs @@ -0,0 +1,1290 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::arrayfunc::{array_variable_part, unbind_array_element, valid_array_reference}; +use crate::bashhist::{bash_history_disable, bash_history_enable, load_history}; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_usage, remember_args, sh_chkwrite, sh_invalidid, sh_invalidopt, sh_invalidoptname, +}; +use crate::flags::{change_flag, find_flag}; +use crate::general::{extract_colon_unit, get_posix_options, legal_identifier, num_posix_options}; +use crate::src_common::*; +use crate::variables::{ + all_shell_functions, all_shell_variables, bind_variable, find_function, find_variable, + find_variable_last_nameref, print_func_list, print_var_list, stupidly_hack_special_variables, + sv_ignoreeof, sv_strict_posix, unbind_func, unbind_nameref, unbind_variable, + unbind_variable_noref, +}; +use crate::y_tab::{ignoreeof, with_input_from_stdin, with_input_from_stream}; +use std::io::stdin; + +pub type setopt_get_func_t = fn(*mut libc::c_char) -> libc::c_int; +pub type setopt_set_func_t = fn(libc::c_int, *mut libc::c_char) -> libc::c_int; + +#[no_mangle] +pub static mut o_options: [opp; 28] = unsafe { + [ + { + opp { + name: b"allexport\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'a' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"braceexpand\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'B' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"emacs\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: Some(set_edit_mode), + get_func: Some(get_edit_mode), + } + }, + { + opp { + name: b"errexit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'e' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"errtrace\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'E' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"functrace\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'T' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"hashall\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'h' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"histexpand\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'H' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"history\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + // variable : 0 as *const libc::c_void + // as *mut libc::c_void + // as *mut i32, + variable: &enable_history_list as *const i32 as *mut i32, + set_func: Some(bash_set_history), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"ignoreeof\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + /*variable : 0 as *const libc::c_void + as *mut libc::c_void + as *mut i32, */ + variable: &ignoreeof as *const i32 as *mut i32, + set_func: Some(set_ignoreeof), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"interactive-comments\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + letter: b'\0' as i32, + /*variable : 0 as *const libc::c_void + as *mut libc::c_void + as *mut i32, */ + variable: &interactive_comments as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"keyword\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'k' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"monitor\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'm' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"noclobber\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'C' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"noexec\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'n' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"noglob\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'f' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"nolog\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + /*variable : 0 as *const libc::c_void + as *mut libc::c_void + as *mut i32, */ + variable: &dont_save_function_defs as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"notify\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'b' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"nounset\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'u' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"onecmd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b't' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"physical\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'P' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"pipefail\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + /*variable : 0 as *const libc::c_void + as *mut libc::c_void + as *mut i32, */ + variable: &pipefail_opt as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"posix\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + /*variable : 0 as *const libc::c_void + as *mut libc::c_void + as *mut i32, */ + variable: &posixly_correct as *const libc::c_int as *mut libc::c_int, + set_func: Some(set_posix_mode), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"privileged\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'p' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"verbose\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'v' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: b"vi\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'\0' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: Some(set_edit_mode), //set_edit_mode as *mut setopt_set_func_t ,// unsafe {&mut set_edit_mode}, + get_func: Some(get_edit_mode), + } + }, + { + opp { + name: b"xtrace\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + letter: b'x' as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + { + opp { + name: std::ptr::null_mut(), + letter: 0 as i32, + variable: 0 as *const libc::c_void as *mut libc::c_void as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + get_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + } + }, + ] +}; + +extern "C" { + fn rl_variable_bind(_: *const libc::c_char, _: *const libc::c_char) -> i32; + static mut rl_editing_mode: i32; +} + +static mut on: *const libc::c_char = b"on\0" as *const u8 as *const libc::c_char; +static mut off: *const libc::c_char = b"off\0" as *const u8 as *const libc::c_char; +static mut previous_option_value: i32 = 0; +// pub type SHELL_VAR = variable; +// pub type arrayind_t = i64; + +fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + return unsafe { (*a == *b) && (libc::strcmp(a, b) == 0) }; +} + +fn find_minus_o_option(name: *mut libc::c_char) -> i32 { + let mut i: i32 = 0; + unsafe { + for j in 0..N_O_OPTIONS!() - 1 { + i = j as i32; + let _ooo = o_options[j]; + + if STREQ(name, o_options[j as usize].name) { + return i; + } + } + -1 + } +} + +#[no_mangle] +pub fn minus_o_option_value(name: *mut libc::c_char) -> i32 { + let mut i: i32 = 0; + let on_or_off: *mut i32 = 0 as *mut i32; + + i = find_minus_o_option(name); + if i < 0 { + return -1; + } + let options = unsafe { o_options[i as usize] }; + if options.letter != 0 { + if on_or_off == FLAG_UNKNOWN!() { + return -1; + } + return unsafe { *on_or_off }; + } else { + unsafe { GET_BINARY_O_OPTION_VALUE!(i, name) } + } +} + +fn print_minus_o_option(name: *mut libc::c_char, value: i32, pflag: i32) { + unsafe { + if pflag == 0 { + if value > 0 { + println!("{:?} {:?}", CStr::from_ptr(name), CStr::from_ptr(on)); + } else { + println!("{:?} {:?}", CStr::from_ptr(name), CStr::from_ptr(off)); + } + } else { + if value > 0 { + println!("set -o {:?}", CStr::from_ptr(name)); + } else { + println!("set +o {:?}", CStr::from_ptr(name)); + } + } + } +} + +#[no_mangle] +pub fn list_minus_o_opts(mode: i32, reusable: i32) { + let mut i: i32 = 0; + let mut on_or_off: *mut i32 = 0 as *mut i32; + let mut value: i32 = 0; + unsafe { + for j in 0..N_O_OPTIONS!() - 1 { + i = j as i32; + if o_options[j as usize].letter != 0 { + value = 0; + on_or_off = find_flag(o_options[i as usize].letter); + if on_or_off == FLAG_UNKNOWN!() { + on_or_off = &mut value; + } + if mode == -1 || mode == *on_or_off { + print_minus_o_option(o_options[i as usize].name, *on_or_off, reusable); + } + } else { + value = GET_BINARY_O_OPTION_VALUE!(i, o_options[i as usize].name); + if mode == -1 || mode == value { + print_minus_o_option(o_options[i as usize].name, value, reusable); + } + } + } + } +} + +pub fn get_minus_o_opts() -> *mut *mut libc::c_char { + let mut ret = 0 as *mut *mut libc::c_char; + let mut i: i32 = 0; + ret = unsafe { strvec_create(N_O_OPTIONS!() as i32 + 1) }; + for j in 0..N_O_OPTIONS!() { + i = j as i32; + unsafe { + if o_options[i as usize].name != std::ptr::null_mut() { + *ret.offset(i as isize) = o_options[i as usize].name; + //*ret.as_ptr().offset(i as isize) = o_options[i as usize].name ; + } + } + } + unsafe { *ret.offset(i as isize) = o_options[i as usize].name }; + // *ret.as_ptr().offset(27 as usize) = std::ptr::null_mut(); + ret +} + +pub fn get_current_options() -> *mut libc::c_char { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: i32 = 0; + let mut posixopts: i32 = 0; + posixopts = unsafe { num_posix_options() }; /* shopts modified by posix mode */ + /* Make the buffer big enough to hold the set -o options and the shopt + options modified by posix mode. */ + temp = unsafe { malloc((1 + N_O_OPTIONS!() as i32 + posixopts) as usize) as *mut libc::c_char }; + for t in 0..N_O_OPTIONS!() { + i = t as i32; + if unsafe { o_options[t as usize].letter != 0 } { + unsafe { + *(temp.offset(t as isize)) = + *(find_flag(o_options[t as usize].letter)) as libc::c_char + }; + } else { + unsafe { + *(temp.offset(t as isize)) = + GET_BINARY_O_OPTION_VALUE!(t, o_options[i as usize].name) as libc::c_char; + } + } + } + /* Add the shell options that are modified by posix mode to the end of the + bitmap. They will be handled in set_current_options() */ + unsafe { + get_posix_options(temp.offset(i as isize)); + *(temp.offset((i + posixopts) as isize)) = b'\0' as libc::c_char; + } + return temp; +} + +pub fn set_current_options(bitmap: *const libc::c_char) { + let mut i: i32; + let mut v: i32; + let mut cv: i32; + let mut on_or_off: *mut i32; + + if bitmap == std::ptr::null_mut() { + return; + } + + for t in 0..N_O_OPTIONS!() { + i = t as i32; + unsafe { + if bitmap.offset(i as isize) != std::ptr::null_mut() { + v = FLAG_ON!(); + } else { + v = FLAG_OFF!(); + } + } + if unsafe { o_options[t as usize].letter != 0 } { + on_or_off = unsafe { find_flag(o_options[i as usize].letter) }; + if on_or_off != std::ptr::null_mut() { + cv = FLAG_ON!(); + } else { + cv = FLAG_OFF!(); + } + if v != cv { + unsafe { + change_flag(o_options[i as usize].letter, v); + } + } else { + unsafe { cv = GET_BINARY_O_OPTION_VALUE!(i, o_options[i as usize].name) }; + if cv > 0 { + cv = FLAG_ON!(); + } else { + cv = FLAG_OFF!(); + } + if v != cv { + unsafe { + SET_BINARY_O_OPTION_VALUE!(i, v, o_options[i as usize].name); + } + } + } + } + } +} + +fn set_ignoreeof(on_or_off: i32, _option_name: *mut libc::c_char) -> i32 { + on_or_off == FLAG_ON!(); + unsafe { + ignoreeof = on_or_off; + unbind_variable_noref(b"ignoreeof\0" as *const u8 as *const libc::c_char); + if ignoreeof != 0 { + bind_variable( + b"IGNOREEOF\0" as *const u8 as *const libc::c_char, + b"10\0" as *const u8 as *mut libc::c_char, + 0, + ); + } else { + unbind_variable_noref(b"IGNOREEOF\0" as *const u8 as *const libc::c_char); + } + sv_ignoreeof(b"IGNOREEOF\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + return 0; +} + +fn set_posix_mode(on_or_off: i32, _option_name: *mut libc::c_char) -> i32 { + unsafe { + if (on_or_off == FLAG_ON!() && posixly_correct != 0) + || (on_or_off == FLAG_OFF!() && posixly_correct == 0) + { + return 0; + } + on_or_off == FLAG_ON!(); + posixly_correct = on_or_off; + + if posixly_correct != 0 { + unbind_variable_noref(b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char); + } else { + bind_variable( + b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char, + b"y\0" as *const u8 as *mut libc::c_char, + 0, + ); + } + sv_strict_posix(b"POSIXLY_CORRECT\0" as *const u8 as *mut libc::c_char); + } + return 0; +} + +fn set_edit_mode(on_or_off: i32, option_name: *mut libc::c_char) -> i32 { + unsafe { + let isemacs: i32; + + if on_or_off == FLAG_ON!() { + rl_variable_bind( + b"editing-mode\0" as *const u8 as *const libc::c_char, + option_name, + ); + if interactive > 0 { + with_input_from_stdin(); + } + + no_line_editing = 0; + } else { + if rl_editing_mode == 1 { + isemacs = 1; + } else { + isemacs = 0; + } + if isemacs != 0 && *option_name == b'e' as libc::c_char + || (isemacs == 0 && *option_name == b'v' as libc::c_char) + { + if interactive > 0 { + with_input_from_stream( + stdin as *mut libc::FILE, + b"stdin\0" as *const u8 as *const libc::c_char, + ); + } + } + } + + return 1 - no_line_editing; + } +} + +fn get_edit_mode(name: *mut libc::c_char) -> i32 { + unsafe { + if *name == b'e' as libc::c_char { + if no_line_editing == 0 && rl_editing_mode == 1 { + return 1; + } else { + return 0; + } + } else { + if no_line_editing == 0 && rl_editing_mode == 0 { + return 1; + } else { + return 0; + } + } + } +} + +fn bash_set_history(on_or_off: i32, _option_name: *mut libc::c_char) -> i32 { + unsafe { + if on_or_off == FLAG_ON!() { + enable_history_list = 1; + bash_history_enable(); + if history_lines_this_session == 0 { + load_history(); + } + } else { + enable_history_list = 0; + bash_history_disable(); + } + return 1 - enable_history_list; + } +} + +#[no_mangle] +pub fn set_minus_o_option(on_or_off: i32, option_name: *mut libc::c_char) -> i32 { + let i: i32; + + i = find_minus_o_option(option_name); + + if i < 0 { + sh_invalidoptname(option_name); + return EX_USAGE; + } + unsafe { + if o_options[i as usize].letter == 0 { + previous_option_value = GET_BINARY_O_OPTION_VALUE!(i, o_options[i as usize].name); + SET_BINARY_O_OPTION_VALUE!(i, on_or_off, option_name); + return EXECUTION_SUCCESS!(); + } else { + previous_option_value = change_flag(o_options[i as usize].letter, on_or_off); + if previous_option_value == FLAG_ERROR!() { + sh_invalidoptname(option_name); + return EXECUTION_FAILURE!(); + } else { + return EXECUTION_SUCCESS!(); + } + } + } +} + +fn print_all_shell_variables() { + let mut vars = 0 as *mut *mut SHELL_VAR; + unsafe { + vars = all_shell_variables(); + if vars != std::ptr::null_mut() { + print_var_list(vars); + libc::free(vars as *mut libc::c_void); + } + /* POSIX.2 does not allow function names and definitions to be output when + `set' is invoked without options (PASC Interp #202). */ + if posixly_correct == 0 { + vars = all_shell_functions(); + if vars != std::ptr::null_mut() { + print_func_list(vars); + libc::free(vars as *mut libc::c_void); + } + } + } +} + +#[no_mangle] +pub fn set_shellopts() { + let value: *mut libc::c_char; + let mut tflag: [libc::c_char; N_O_OPTIONS!()] = [0 as libc::c_char; N_O_OPTIONS!()]; + let mut vsize: i32 = 0; + let mut i: i32 = 0; + let mut vptr: i32; + let mut ip: *mut i32; + let exported: i32; + + let mut v: *mut SHELL_VAR; + unsafe { + for j in 0..N_O_OPTIONS!() { + i = j as i32; + if o_options[i as usize].name != std::ptr::null_mut() { + tflag[i as usize] = 0; + if o_options[i as usize].letter != 0 { + ip = find_flag(o_options[i as usize].letter); + if ip != std::ptr::null_mut() && *ip != 0 { + vsize = vsize + strlen(o_options[i as usize].name) as u64 as u32 as i32 + 1; + tflag[i as usize] = 1; + } + } else if GET_BINARY_O_OPTION_VALUE!(i, o_options[i as usize].name) != 0 { + vsize = vsize + strlen(o_options[i as usize].name) as i32 + 1; + tflag[i as usize] = 1; + } + } + } + value = malloc((vsize + 1) as u32 as usize) as *mut libc::c_char; + vptr = 0; + + for j in 0..N_O_OPTIONS!() { + i = j as i32; + if o_options[i as usize].name != std::ptr::null_mut() { + if tflag[i as usize] != 0 as libc::c_char { + libc::strcpy(value.offset(vptr as isize), o_options[i as usize].name); + vptr = vptr + strlen(o_options[i as usize].name) as u64 as i64 as i32; + + *value.offset(vptr as isize) = b':' as libc::c_char; + vptr = vptr + 1; + } + } + } + + if vptr > 0 { + vptr = vptr - 1; + } + *value.offset(vptr as isize) = b'\0' as libc::c_char; + + v = find_variable(b"SHELLOPTS\0" as *const u8 as *mut libc::c_char); + + /* Turn off the read-only attribute so we can bind the new value, and + note whether or not the variable was exported. */ + if v != std::ptr::null_mut() { + VUNSETATTR!(v, att_readonly!()); + exported = exported_p!(v); + } else { + exported = 0; + } + v = bind_variable(b"SHELLOPTS\0" as *const u8 as *mut libc::c_char, value, 0); + /* Turn the read-only attribute back on, and turn off the export attribute + if it was set implicitly by mark_modified_vars and SHELLOPTS was not + exported before we bound the new value. */ + + VSETATTR_1!(v, att_readonly!()); + + if mark_modified_vars != 0 && exported != 0 && exported_p!(v) != 0 { + VUNSETATTR!(v, att_exported!()); + } + libc::free(value as *mut libc::c_void); + } +} + +fn parse_shellopts(value: *mut libc::c_char) { + let mut vname: *mut libc::c_char; + let mut vptr: i32 = 0; + loop { + vname = unsafe { extract_colon_unit(value, &mut vptr) }; + if vname != std::ptr::null_mut() { + break; + } + set_minus_o_option(FLAG_ON!(), vname); + unsafe { + libc::free(vname as *mut libc::c_void); + } + } +} + +pub fn initialize_shell_options(no_shellopts: i32) { + let temp: *mut libc::c_char; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + if no_shellopts == 0 { + var = find_variable(b"SHELLOPTS\0" as *const u8 as *const libc::c_char); + /* set up any shell options we may have inherited. */ + unsafe { + if !var.is_null() && imported_p!(var) != 0 { + if assoc_p!(var) != 0 || array_p!(var) != 0 { + temp = std::ptr::null_mut(); + } else { + temp = savestring!(value_cell!(var)); + } + + if temp != std::ptr::null_mut() { + parse_shellopts(temp); + libc::free(temp as *mut libc::c_void); + } + } + } + } + + /* Set up the $SHELLOPTS variable. */ + set_shellopts(); +} + +#[no_mangle] +pub fn reset_shell_options() { + unsafe { + pipefail_opt = 0; + ignoreeof = 0; + posixly_correct = 0; + dont_save_function_defs = 0; + enable_history_list = 1; + remember_on_history = enable_history_list; + } +} + +#[no_mangle] +pub fn set_builtin(mut list: *mut WordList) -> i32 { + let mut on_or_off: i32; + let mut flag_name: i32 = 0; + let mut force_assignment: i32; + let mut opts_changed: i32; + let mut rv: i32; + let mut r: i32; + let mut arg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: [libc::c_char; 3] = [0 as libc::c_char; 3]; + let mut opt: i32; + let _flag: bool = false; + if list.is_null() { + print_all_shell_variables(); + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + rv = EXECUTION_SUCCESS!(); + unsafe { + reset_internal_getopt(); + opt = internal_getopt(list, optflags.as_mut_ptr()); + } + while opt != -1 { + let optu8: u8 = flag_name as u8; + let optChar: char = char::from(optu8); + + match optChar { + 'i' => { + s[0] = unsafe { list_opttype as libc::c_char }; + s[1] = b'i' as u8 as libc::c_char; + s[2] = b'\0' as u8 as libc::c_char; + + sh_invalidopt(s.as_ptr() as *mut libc::c_char); + builtin_usage(); + + return EX_USAGE; + } + '?' => { + builtin_usage(); + + if unsafe { list_optopt } == b'?' as libc::c_int { + return EXECUTION_SUCCESS!(); + } else { + return EX_USAGE; + } + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + } + } + // opt = unsafe {internal_getopt(list, optflags.as_ptr() as *mut libc::c_char)}; + opt = unsafe { internal_getopt(list, optflags.as_mut_ptr()) }; + } + opts_changed = 0; + force_assignment = opts_changed; + while list != std::ptr::null_mut() { + if unsafe { (*(*list).word).word != std::ptr::null_mut() } { + arg = unsafe { (*(*list).word).word }; + //if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2]))) + if unsafe { + (*arg == b'-' as u8 as libc::c_char) + && (arg.offset(1 as isize) == std::ptr::null_mut() + || (*(arg.offset(1 as isize)) == b'-' as u8 as libc::c_char + && arg.offset(2 as isize) != std::ptr::null_mut())) + } { + //println!("*arg == b'-' && arg[1] && arg[1]== b'-'"); + unsafe { + list = (*list).next; + /* `set --' unsets the positional parameters. */ + if *arg.offset(1 as isize) == b'-' as u8 as libc::c_char { + //println!("arg[1]== b'-'"); + force_assignment = 1; + } + /* Until told differently, the old shell behaviour of + `set - [arg ...]' being equivalent to `set +xv [arg ...]' + stands. Posix.2 says the behaviour is marked as obsolescent. */ + else { + //println!("else ........."); + change_flag('x' as i32, b'+' as i32); + change_flag('v' as i32, b'+' as i32); + opts_changed = 1; + } + } + } + on_or_off = unsafe { *arg as i32 }; + if on_or_off != 0 && (on_or_off == '-' as i32 || on_or_off == '+' as i32) { + unsafe { + arg = arg.offset(1 as isize); + } + flag_name = unsafe { *arg as i32 }; + + while flag_name != 0 { + let optu8: u8 = flag_name as u8; + let optChar: char = char::from(optu8); + + if optChar == '?' { + builtin_usage(); + + return EXECUTION_SUCCESS!(); + } else if optChar == 'o' { + /* -+o option-name */ + + let mut option_name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut opt: *mut WordList = 0 as *mut WordList; + unsafe { + opt = (*list).next; + } + if opt == std::ptr::null_mut() { + if on_or_off == '+' as i32 { + list_minus_o_opts(-1, 1); + } else { + list_minus_o_opts(-1, 0); + } + + rv = sh_chkwrite(rv); + unsafe { + arg = arg.offset(1 as isize); + } + flag_name = unsafe { *arg as i32 }; + + continue; + } + + unsafe { + if !(*opt).word.is_null() { + option_name = (*(*opt).word).word; + } + } + + if option_name == std::ptr::null_mut() + || unsafe { + *option_name == '\u{0}' as libc::c_char + || *option_name == '-' as libc::c_char + || *option_name == '+' as libc::c_char + } + { + //on_or_off == '+' as i32; + + if on_or_off == '+' as i32 { + list_minus_o_opts(-1, 1); + } else { + list_minus_o_opts(-1, 0); + } + + unsafe { + arg = arg.offset(1 as isize); + } + flag_name = unsafe { *arg as i32 }; + + continue; + } + unsafe { + list = (*list).next; /* Skip over option name. */ + } + opts_changed = 1; + r = set_minus_o_option(on_or_off, option_name); + if r != EXECUTION_SUCCESS!() { + set_shellopts(); + return r; + } + } else if unsafe { change_flag(flag_name, on_or_off) == FLAG_ERROR!() } { + s[0] = on_or_off as libc::c_char; + s[1] = flag_name as libc::c_char; + s[2] = '\0' as i32 as libc::c_char; + + sh_invalidopt(s.as_ptr() as *mut libc::c_char); + builtin_usage(); + set_shellopts(); + + return EXECUTION_FAILURE!(); + } + opts_changed = 1; + unsafe { + arg = arg.offset(1 as isize); + } + + flag_name = 0; + //flag_name = unsafe{*arg as i32}; + } + } else { + break; + } + + unsafe { + list = (*list).next; + } + } + } + + if list != std::ptr::null_mut() || force_assignment != 0 { + remember_args(list, 1 as i32); + } + + if opts_changed != 0 { + set_shellopts(); + } + return rv; +} + +#[no_mangle] +pub fn unset_builtin(mut list: *mut WordList) -> i32 { + let mut unset_function: i32 = 0; + let mut unset_variable: i32 = 0; + let mut unset_array: i32 = 0; + let mut opt: i32 = 0; + let mut nameref: i32 = 0; + let mut any_failed: i32 = 0; + let mut global_unset_func: i32 = 0; + let mut global_unset_var: i32 = 0; + let mut vflags: i32 = 0; + let mut valid_id: i32 = 0; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tname: *mut libc::c_char = 0 as *mut libc::c_char; + + let c_str_fnv = CString::new("fnv").unwrap(); + unsafe { + reset_internal_getopt(); + opt = internal_getopt(list, c_str_fnv.as_ptr() as *mut libc::c_char); + + while opt != -1 { + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'f' => { + global_unset_func = 1; + } + 'v' => { + global_unset_var = 0; + } + 'n' => { + nameref = 1; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, c_str_fnv.as_ptr() as *mut libc::c_char); + } + //println!("unset func={}, unset val=%{}", global_unset_func, global_unset_var); + + list = loptend; + + if global_unset_func != 0 && global_unset_var != 0 { + builtin_error( + b"cannot simultaneously unset a function and a variable \0" as *const u8 + as *const libc::c_char, + ); + return EXECUTION_FAILURE!(); + } else if unset_function != 0 && nameref != 0 { + nameref = 0; + } + + if assoc_expand_once != 0 { + vflags = VA_NOEXPAND!() | VA_ONEWORD!(); + } else { + vflags = 0; + } + while !list.is_null() { + let mut var: *mut SHELL_VAR; + let mut tem: i32 = 0; + + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + name = (*(*list).word).word; + unset_function = global_unset_func; + unset_variable = global_unset_var; + unset_array = 0; + + if !unset_function == 0 && nameref == 0 && valid_array_reference(name, vflags) != 0 { + t = libc::strchr(name, '[' as i32); + *t.offset(1 as isize) = b'\0' as i32 as libc::c_char; + unset_array = unset_array + 1; + } + + valid_id = legal_identifier(name); + + if global_unset_func == 0 && global_unset_var == 0 && valid_id == 0 { + unset_array = 0; + unset_variable = unset_array; + unset_function = 1; + } + + if unset_function == 0 && valid_id == 0 { + sh_invalidid(name); + any_failed = any_failed + 1; + list = (*list).next; + } + + if unset_function != 0 { + var = find_function(name); + } else { + if nameref != 0 { + var = find_variable_last_nameref(name, 0); + } else { + var = find_variable(name); + } + } + + if var != std::ptr::null_mut() && unset_function == 0 && non_unsettable_p!(var) != 0 { + builtin_error( + b"%s: cannot unset \0" as *const u8 as *const libc::c_char, + name, + ); + any_failed = any_failed + 1; + list = (*list).next; + } + + if var != std::ptr::null_mut() + && unset_function == 0 + && nameref == 0 + && STREQ(name, name_cell!(var)) + { + name = name_cell!(var); + } + + if var == std::ptr::null_mut() + && nameref == 0 + && unset_variable == 0 + && unset_function == 0 + { + var = find_function(name); + if var != std::ptr::null_mut() { + unset_function = 1; + } + } + + if var != std::ptr::null_mut() && readonly_p!(var) != 0 { + if unset_function != 0 { + builtin_error( + b"%s: cannot unset: readonly %s \0 " as *const u8 as *mut libc::c_char, + (*var).name, + b"function\0" as *const u8 as *mut libc::c_char, + ); + } else { + builtin_error( + b"%s: cannot unset: readonly %s \0" as *const u8 as *mut libc::c_char, + (*var).name, + b"variable\0" as *const u8 as *mut libc::c_char, + ); + } + any_failed = any_failed + 1; + list = (*list).next; + } + // #if defined (ARRAY_VARS) + if var != std::ptr::null_mut() && unset_array != 0 { + /* Let unbind_array_element decide what to do with non-array vars */ + tem = unbind_array_element(var, t, vflags); /* XXX new third arg */ + if tem == -2 && array_p!(var) == 0 && assoc_p!(var) == 0 { + builtin_error( + b"%s: not an array variable\0" as *const u8 as *const libc::c_char, + (*var).name, + ); + any_failed = any_failed + 1; + list = (*list).next; + } else if tem < 0 { + any_failed = any_failed + 1; + } + } else { + if var == std::ptr::null_mut() && nameref == 0 && unset_function == 0 { + var = find_variable_last_nameref(name, 0); + if var != std::ptr::null_mut() && nameref_p!(var) != 0 { + if valid_array_reference(nameref_cell!(var), 0) != 0 { + tname = savestring!(nameref_cell!(var)); + var = array_variable_part(tname, 0, &mut t, &mut 0); + if var != std::ptr::null_mut() { + tem = unbind_array_element(var, t, vflags); /* XXX new third arg */ + } + libc::free(tname as *mut libc::c_void); + } else { + tem = unbind_variable(nameref_cell!(var)); + } + } else { + tem = unbind_variable(name); + } + } else { + if unset_function != 0 { + tem = unbind_func(name); + } else if nameref != 0 { + tem = unbind_nameref(name); + } else { + tem = unbind_variable(name); + } + } + } + + if tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0 { + tem = unbind_func(name); + } + name = (*(*list).word).word; + + if unset_function == 0 { + stupidly_hack_special_variables(name); + } + list = (*list).next; + } + + if any_failed != 0 { + return EXECUTION_FAILURE!(); + } else { + return EXECUTION_SUCCESS!(); + } + } +} diff --git a/utshell-0.5.0/src/builtins/setattr.rs b/utshell-0.5.0/src/builtins/setattr.rs new file mode 100644 index 00000000..04b9b163 --- /dev/null +++ b/utshell-0.5.0/src/builtins/setattr.rs @@ -0,0 +1,735 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::array::array_to_assign; +use crate::arrayfunc::print_array_assignment; +use crate::arrayfunc::print_assoc_assignment; +use crate::assoc::assoc_to_assign; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, sh_chkwrite, sh_invalidid}; +use crate::builtins::declare::declare_builtin; +use crate::dispose_cmd::dispose_word; +use crate::general::legal_identifier; +use crate::general::{assignment, exportable_function_name}; +use crate::make_cmd::{make_word, make_word_list}; +use crate::print_cmd::named_function_string; +use crate::src_common::*; +use crate::subst::do_assignment_no_expand; +use crate::variables::{ + all_local_variables, all_shell_functions, all_shell_variables, bind_variable, find_function, + find_global_variable, find_tempenv_variable, find_variable, find_variable_nameref_for_create, + find_variable_noref, find_variable_notempenv, stupidly_hack_special_variables, +}; +use crate::version::shell_compatibility_level; + +#[no_mangle] +pub fn export_builtin(list: *mut WordList) -> libc::c_int { + return set_or_show_attributes(list, att_exported, 0); +} + +#[no_mangle] +pub fn readonly_builtin(list: *mut WordList) -> libc::c_int { + return set_or_show_attributes(list, att_readonly, 0); +} + +#[no_mangle] +pub fn set_or_show_attributes( + mut list: *mut WordList, + mut attribute: libc::c_int, + nodefs: libc::c_int, +) -> libc::c_int { + let mut assign_error: libc::c_int = 0; + let mut any_failed: libc::c_int = 0; + let mut undo: libc::c_int = 0; + let mut functions_only: bool = false; + let mut arrays_only: libc::c_int = 0; + let mut assoc_only: libc::c_int = 0; + let mut name: *mut libc::c_char; + let mut var: *mut SHELL_VAR; + let mut assign: libc::c_int; + let mut aflags: libc::c_int; + let mut tlist: *mut WordList; + let mut nlist: *mut WordList; + let mut w: *mut WordDesc; + + reset_internal_getopt(); + let opt_str = std::ffi::CString::new("aAfnp").unwrap(); + let mut opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'n' => undo = 1, + 'f' => functions_only = true, + 'a' => arrays_only = 1, + 'A' => assoc_only = 1, + 'p' => break, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + } + unsafe { + list = loptend; + } + + if !list.is_null() { + if attribute & att_exported != 0 { + unsafe { + array_needs_making = 1; + } + } + if undo != 0 && (attribute & att_readonly) != 0 { + attribute &= !att_readonly; + } + unsafe { + while !list.is_null() { + name = (*(*list).word).word; + + if functions_only { + var = find_function(name); + if var.is_null() { + builtin_error("%s: not a function\0".as_ptr() as *const libc::c_char, name); + any_failed += 1; + } else if (attribute & att_exported) != 0 + && undo == 0 + && exportable_function_name(name) == 0 + { + builtin_error("%s: cannot export\0".as_ptr() as *const libc::c_char, name); + any_failed += 1; + } else { + if undo == 0 { + (*var).attributes |= attribute; + } else { + (*var).attributes &= !attribute; + } + } + list = (*list).next; + continue; + } + assign = assignment(name, 0); + aflags = 0; + if assign != 0 { + *(name.offset(assign as isize)) = b'\0' as libc::c_char; + + if *(name.offset((assign - 1) as isize)) == b'+' as libc::c_char { + aflags |= ASS_APPEND; + + *(name.offset((assign - 1) as isize)) = b'\0' as libc::c_char; + } + } + + if legal_identifier(name) == 0 { + sh_invalidid(name); + if assign != 0 { + assign_error += 1; + } else { + any_failed += 1; + } + list = (*list).next; + continue; + } + + if assign != 0 { + *(name.offset(assign as isize)) = b'=' as libc::c_char; + + if (aflags & ASS_APPEND) != 0 { + *(name.offset((assign - 1) as isize)) = b'+' as libc::c_char; + } + + if arrays_only != 0 || assoc_only != 0 { + tlist = (*list).next; + (*list).next = PT_NULL as *mut WordList; + + let mut optw: [u8; 8] = [0; 8]; + optw[0] = b'-'; + optw[1] = b'g'; + let mut opti = 2; + if (attribute & att_readonly) != 0 { + optw[opti] = b'r'; + opti += 1; + } + if (attribute & att_exported) != 0 { + optw[opti] = b'x'; + opti += 1; + } + if (attribute & arrays_only) != 0 { + optw[opti] = b'a'; + opti += 1; + } else { + optw[opti] = b'A'; + opti += 1; + } + + w = make_word(optw.as_ptr() as *const libc::c_char); + nlist = make_word_list(w, list); + + opt = declare_builtin(nlist); + if opt != EXECUTION_SUCCESS { + assign_error += 1; + } + (*list).next = tlist; + dispose_word(w); + libc::free(nlist as *mut c_void); + } else if do_assignment_no_expand(name) == 0 { + assign_error += 1; + } + + *(name.offset(assign as isize)) = b'\0' as libc::c_char; + + if (aflags & ASS_APPEND) != 0 { + *(name.offset((assign - 1) as isize)) = b'\0' as libc::c_char; + } + } + + set_var_attribute(name, attribute, undo); + if assign != 0 { + *(name.offset(assign as isize)) = b'=' as libc::c_char; + + // *((name as usize + assign as usize) as *mut libc::c_char) = b'=' as libc::c_char; + if (aflags & ASS_APPEND) != 0 { + *(name.offset((assign - 1) as isize)) = b'+' as libc::c_char; + } + } + list = (*list).next; + } + } + } else { + let variable_list: *mut *mut SHELL_VAR; + if (attribute & att_function) != 0 || functions_only { + variable_list = all_shell_functions(); + + if attribute != att_function { + attribute &= !att_function; + } + } else { + variable_list = all_shell_variables(); + } + + if (attribute & att_array) != 0 { + arrays_only += 1; + if attribute != att_array { + attribute &= !att_array; + } + } else if (attribute & att_assoc) != 0 { + assoc_only += 1; + if attribute != att_assoc { + attribute &= !att_assoc; + } + } + unsafe { + if !variable_list.is_null() { + let mut i = 0; + loop { + var = *(variable_list.offset(i)) as *mut SHELL_VAR; + + if var.is_null() { + break; + } + + if arrays_only != 0 && (((*var).attributes & att_array) == 0) { + i += 1; + continue; + } else if assoc_only != 0 && (((*var).attributes & att_assoc) == 0) { + i += 1; + continue; + } + + if ((*var).attributes & (att_invisible | att_exported)) + == (att_invisible | att_exported) + { + i += 1; + continue; + } + + if ((*var).attributes & attribute) != 0 { + let pattr = (this_shell_builtin == Some(readonly_builtin)) + || (this_shell_builtin == Some(export_builtin)); + if pattr { + show_var_attributes(var, 1, nodefs); + } else { + show_var_attributes(var, 0, nodefs); + } + any_failed = sh_chkwrite(any_failed); + if any_failed != 0 { + break; + } + } + i += 1; + } + libc::free(variable_list as *mut c_void); + } + } + } + + return if assign_error != 0 { + EX_BADASSIGN + } else if any_failed == 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; +} + +#[no_mangle] +pub fn show_all_var_attributes(v: libc::c_int, nodefs: libc::c_int) -> libc::c_int { + let mut i = 0; + let mut any_failed = 0; + let mut var: *mut SHELL_VAR; + let variable_list: *mut *mut SHELL_VAR; + + variable_list = if v != 0 { + all_shell_variables() + } else { + all_shell_functions() + }; + + if variable_list.is_null() { + return EXECUTION_SUCCESS; + } + + loop { + unsafe { + var = *(variable_list.offset(i)); + } + if var.is_null() { + break; + } + let pattr = unsafe { + (this_shell_builtin == Some(readonly_builtin)) + || (this_shell_builtin == Some(export_builtin)) + }; + if pattr { + show_var_attributes(var, 1, nodefs); + } else { + show_var_attributes(var, 0, nodefs); + } + any_failed = sh_chkwrite(any_failed); + if any_failed != 0 { + break; + } + i += 1; + } + + unsafe { + libc::free(variable_list as *mut c_void); + } + + return if any_failed == 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; +} + +#[no_mangle] +pub fn show_local_var_attributes(_v: libc::c_int, nodefs: libc::c_int) -> libc::c_int { + let mut i = 0; + let mut any_failed = 0; + let mut var: *mut SHELL_VAR; + let variable_list: *mut *mut SHELL_VAR; + unsafe { + variable_list = all_local_variables(0); + if variable_list.is_null() { + return EXECUTION_SUCCESS; + } + + loop { + var = variable_list.offset(i) as *mut SHELL_VAR; + if var.is_null() { + break; + } + + let pattr = (this_shell_builtin == Some(readonly_builtin)) + || (this_shell_builtin == Some(export_builtin)); + if pattr { + show_var_attributes(var, 1, nodefs); + } else { + show_var_attributes(var, 0, nodefs); + } + any_failed = sh_chkwrite(any_failed); + if any_failed != 0 { + break; + } + + i += 1; + } + + libc::free(variable_list as *mut c_void); + } + return if any_failed == 0 { + EXECUTION_SUCCESS + } else { + EXECUTION_FAILURE + }; +} + +#[no_mangle] +pub fn show_var_attributes( + var: *mut SHELL_VAR, + pattr: libc::c_int, + mut nodefs: libc::c_int, +) -> libc::c_int { + let mut flags = [0; 16]; + let i = var_attribute_string(var, pattr, flags.as_mut_ptr()); + unsafe { + if ((*var).attributes & att_function) != 0 + && nodefs == 0 + && (pattr == 0 || posixly_correct == 0) + { + println!( + "{}", + CStr::from_ptr(named_function_string( + (*var).name, + (*var).value as *mut COMMAND, + FUNC_MULTILINE | FUNC_EXTERNAL + )) + .to_str() + .unwrap() + ); + nodefs += 1; + if pattr == 0 && i == 1 && flags[0] == b'f' as libc::c_char { + return 0; + } + } + + if pattr == 0 as libc::c_int || posixly_correct == 0 as libc::c_int { + printf( + b"declare -%s \0" as *const u8 as *const libc::c_char, + if i != 0 { + flags.as_mut_ptr() + } else { + b"-\0" as *const u8 as *const libc::c_char + }, + ); + } else if i != 0 { + printf( + b"%s -%s \0" as *const u8 as *const libc::c_char, + this_command_name, + flags.as_mut_ptr(), + ); + } else { + printf( + b"%s \0" as *const u8 as *const libc::c_char, + this_command_name, + ); + } + + if ((*var).attributes & att_invisible) != 0 + && (((*var).attributes & att_array) != 0 || ((*var).attributes & att_assoc) != 0) + { + printf(b"%s\n\0" as *const u8 as *const libc::c_char, (*var).name); + } else if ((*var).attributes & att_array) != 0 { + print_array_assignment(var, 0); + } else if ((*var).attributes & att_assoc) != 0 { + print_assoc_assignment(var, 0); + } else if nodefs != 0 + || (((*var).attributes & att_function) != 0 && pattr != 0 && posixly_correct != 0) + { + printf(b"%s\n\0" as *const u8 as *const libc::c_char, (*var).name); + } else if ((*var).attributes & att_function) != 0 { + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + named_function_string( + (*var).name, + (*var).value as *mut COMMAND, + 0x1 as libc::c_int | 0x2 as libc::c_int, + ), + ); + } else if ((*var).attributes & att_invisible) != 0 || (*var).value == std::ptr::null_mut() { + printf(b"%s\n\0" as *const u8 as *const libc::c_char, (*var).name); + } else { + let x = sh_double_quote(value_cell(var)); + printf( + b"%s=%s\n\0" as *const u8 as *const libc::c_char, + (*var).name, + x, + ); + + libc::free(x as *mut c_void); + } + } + return 0; +} + +fn value_cell(var: *mut SHELL_VAR) -> *mut libc::c_char { + return unsafe { (*var).value }; +} + +fn array_cell(var: *mut SHELL_VAR) -> *mut ARRAY { + return unsafe { (*var).value as *mut ARRAY }; +} + +fn assoc_cell(var: *mut SHELL_VAR) -> *mut HASH_TABLE { + return unsafe { (*var).value as *mut HASH_TABLE }; +} + +#[no_mangle] +pub fn show_name_attributes(name: *mut libc::c_char, nodefs: libc::c_int) -> libc::c_int { + let var = find_variable_noref(name); + if !var.is_null() { + let pattr = unsafe { + (this_shell_builtin == Some(readonly_builtin)) + || (this_shell_builtin == Some(export_builtin)) + }; + if pattr { + show_var_attributes(var, 1, nodefs); + } else { + show_var_attributes(var, 0, nodefs); + } + return 0; + } else { + return 1; + } +} + +#[no_mangle] +pub fn show_localname_attributes(name: *mut libc::c_char, nodefs: libc::c_int) -> libc::c_int { + let var = find_variable_noref(name); + let cond = unsafe { + var.is_null() && ((*var).attributes & att_local) != 0 && (*var).context == variable_context + }; + if cond { + let pattr = unsafe { + (this_shell_builtin == Some(readonly_builtin)) + || (this_shell_builtin == Some(export_builtin)) + }; + if pattr { + show_var_attributes(var, 1, nodefs); + } else { + show_var_attributes(var, 0, nodefs); + } + return 0; + } else { + return 1; + } +} + +#[no_mangle] +pub fn show_func_attributes(name: *mut libc::c_char, nodefs: libc::c_int) -> libc::c_int { + let var = find_function(name); + if !var.is_null() { + let pattr = unsafe { + (this_shell_builtin == Some(readonly_builtin)) + || (this_shell_builtin == Some(export_builtin)) + }; + if pattr { + show_var_attributes(var, 1, nodefs); + } else { + show_var_attributes(var, 0, nodefs); + } + return 0; + } else { + return 1; + } +} + +#[no_mangle] +pub fn set_var_attribute(name: *mut libc::c_char, attribute: libc::c_int, undo: libc::c_int) { + let mut var: *mut SHELL_VAR; + let tvalue: *mut libc::c_char; + unsafe { + if undo != 0 { + var = find_variable(name); + } else { + let tv = find_tempenv_variable(name); + if !tv.is_null() && ((*tv).attributes & att_tempvar) != 0 { + tvalue = if !(*tv).value.is_null() { + libc::strdup((*tv).value) + } else { + "\0".as_ptr() as *mut libc::c_char + }; + + var = bind_variable((*tv).name, tvalue, 0); + if var.is_null() { + libc::free(tvalue as *mut c_void); + return; + } + (*var).attributes |= (*tv).attributes & (!att_tempvar); + if posixly_correct != 0 || shell_compatibility_level <= 44 { + if (*var).context == 0 && (attribute & att_readonly) != 0 { + let v = find_global_variable((*tv).name); + if v as usize != var as usize { + (*tv).attributes |= att_propagate; + } + } else { + (*tv).attributes |= att_propagate; + } + + if (*var).context != 0 { + (*var).attributes |= att_propagate; + } + } + if undo == 0 { + (*tv).attributes |= attribute; + } else { + (*tv).attributes &= !attribute; + } + + stupidly_hack_special_variables((*tv).name); + libc::free(tvalue as *mut c_void); + } else { + var = find_variable_notempenv(name); + if var.is_null() { + let refvar = find_variable_nameref_for_create(name, 0); + if cmp_two( + std::mem::transmute(refvar), + std::mem::transmute(&nameref_invalid_value), + ) { + return; + } + } + if var.is_null() { + var = bind_variable(name, PT_NULL as *mut libc::c_char, 0); + if !var.is_null() { + (*var).attributes |= att_invisible; + } + } else if (*var).context != 0 { + (*var).attributes |= att_propagate; + } + } + } + + if !var.is_null() { + if undo == 0 { + (*var).attributes |= attribute; + } else { + (*var).attributes &= !attribute; + } + } + + if !var.is_null() + && (((*var).attributes & att_exported) != 0 || (attribute & att_exported) != 0) + { + array_needs_making += 1; + } + } +} + +#[no_mangle] +pub fn var_attribute_string( + var: *mut SHELL_VAR, + pattr: libc::c_int, + flags: *mut libc::c_char, +) -> libc::c_int { + let mut i = 0; + unsafe { + if pattr == 0 || posixly_correct == 0 { + if ((*var).attributes & att_array) != 0 { + *(flags.offset(i as isize)) = b'a' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_assoc) != 0 { + *(flags.offset(i as isize)) = b'A' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_function) != 0 { + *(flags.offset(i as isize)) = b'f' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_integer) != 0 { + *(flags.offset(i as isize)) = b'i' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_nameref) != 0 { + *(flags.offset(i as isize)) = b'n' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_readonly) != 0 { + *(flags.offset(i as isize)) = b'r' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_trace) != 0 { + *(flags.offset(i as isize)) = b't' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_exported) != 0 { + *(flags.offset(i as isize)) = b'x' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_capcase) != 0 { + *(flags.offset(i as isize)) = b'c' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_lowercase) != 0 { + *(flags.offset(i as isize)) = b'l' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_uppercase) != 0 { + *(flags.offset(i as isize)) = b'u' as libc::c_char; + i += 1; + } + } else { + if ((*var).attributes & att_array) != 0 { + *(flags.offset(i as isize)) = b'a' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_assoc) != 0 { + *(flags.offset(i as isize)) = b'A' as libc::c_char; + i += 1; + } + if ((*var).attributes & att_function) != 0 { + *(flags.offset(i as isize)) = b'f' as libc::c_char; + i += 1; + } + } + + *(flags.offset(i as isize)) = b'\0' as libc::c_char; + } + return i; +} + +fn cmp_two(a: usize, b: usize) -> bool { + return a == b; +} +/* +#[no_mangle] +pub fn print_array_assignment(var: *mut SHELL_VAR, quote: libc::c_int) { + let vstr = array_to_assign(array_cell(var) as *mut ARRAY, quote); + + if vstr == std::ptr::null_mut() { + if quote != 0 { + println!("{}=\'()\'", CStr::from_ptr((*var).name).to_str().unwrap()); + } else { + println!("{}=()", CStr::from_ptr((*var).name).to_str().unwrap()); + } + } else { + println!( + "{}={}", + CStr::from_ptr((*var).name).to_str().unwrap(), + CStr::from_ptr(vstr).to_str().unwrap() + ); + libc::free(vstr as *mut c_void); + } +} +*/ + +/* +#[no_mangle] +pub fn print_assoc_assignment(var: *mut SHELL_VAR, quote: libc::c_int) { + let vstr = assoc_to_assign(assoc_cell(var) as *mut HASH_TABLE, quote); + + if vstr == std::ptr::null_mut() { + if quote != 0 { + println!("{}=\'()\'", CStr::from_ptr((*var).name).to_str().unwrap()); + } else { + println!("{}=()", CStr::from_ptr((*var).name).to_str().unwrap()); + } + } else { + println!( + "{}={}", + CStr::from_ptr((*var).name).to_str().unwrap(), + CStr::from_ptr(vstr).to_str().unwrap() + ); + libc::free(vstr as *mut c_void); + } +} +*/ diff --git a/utshell-0.5.0/src/builtins/shift.rs b/utshell-0.5.0/src/builtins/shift.rs new file mode 100644 index 00000000..12a78601 --- /dev/null +++ b/utshell-0.5.0/src/builtins/shift.rs @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::common::{ + builtin_usage, get_numeric_arg, number_of_args, sh_erange, shift_args, +}; +use crate::builtins::help::builtin_help; +use crate::src_common::*; +use crate::subst::invalidate_cached_quoted_dollar_at; +use crate::variables::clear_dollar_vars; + +pub static print_shift_error: libc::c_int = 0; + +#[no_mangle] +pub fn shift_builtin(list: *mut WordList) -> i32 { + unsafe { + if !list.is_null() + && !(*list).word.is_null() + && libc::strcmp( + (*((*list).word)).word, + "--help\0".as_ptr() as *const libc::c_char, + ) == 0 + { + builtin_help(); + return EX_USAGE; + } + + let times: intmax_t = 0; + if get_numeric_arg(list, 0, std::mem::transmute(×)) == 0 { + return EXECUTION_FAILURE; + } + + if times == 0 { + return EXECUTION_SUCCESS; + } else if times < 0 { + let s = if list.is_null() { + PT_NULL as *mut libc::c_char + } else { + (*(*list).word).word + }; + sh_erange(s, "shift count\0".as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE; + } + + let nargs = number_of_args(); + if times > nargs.into() { + if print_shift_error != 0 { + let s = if list.is_null() { + PT_NULL as *mut libc::c_char + } else { + (*(*list).word).word + }; + sh_erange(s, "shift count\0".as_ptr() as *mut libc::c_char); + } + return EXECUTION_FAILURE; + } else if times == nargs.into() { + clear_dollar_vars(); + } else { + shift_args(times as i32); + } + + invalidate_cached_quoted_dollar_at(); + } + return EXECUTION_SUCCESS; +} diff --git a/utshell-0.5.0/src/builtins/shopt.rs b/utshell-0.5.0/src/builtins/shopt.rs new file mode 100644 index 00000000..cc0a0482 --- /dev/null +++ b/utshell-0.5.0/src/builtins/shopt.rs @@ -0,0 +1,1239 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::bashline::{enable_hostname_completion, set_directory_hook}; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::cd::{cdable_vars, cdspelling}; +use crate::builtins::common::{builtin_usage, sh_chkwrite, sh_invalidoptname}; +use crate::builtins::echo::xpg_echo; +use crate::builtins::set::{ + list_minus_o_opts, minus_o_option_value, set_minus_o_option, set_shellopts, +}; +use crate::builtins::source::source_uses_path; +use crate::dispose_cmd::dispose_words; +use crate::error::gnu_error_format; +use crate::general::extract_colon_unit; +use crate::make_cmd::{make_word, make_word_list}; +use crate::pcomplete::progcomp_alias; +use crate::src_common::*; +use crate::variables::find_variable; +use crate::variables::{bind_variable, init_bash_argv}; +use crate::version::shell_compatibility_level; +use crate::y_tab::{expand_aliases, extended_quote, promptvars}; + +extern "C" { + fn shell_is_restricted(_: *mut libc::c_char) -> i32; + static mut no_exit_on_failed_exec: i32; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct RShoptVars { + pub name: *mut libc::c_char, + pub value: *mut i32, + pub set_func: Option, +} +pub type ShoptSetFuncT = fn(*mut libc::c_char, i32) -> i32; + +static mut SHOPT_LOGIN_SHELL: i32 = 0; +static mut SHOPT_COMPAT31: i32 = 0; +static mut SHOPT_COMPAT32: i32 = 0; +static mut SHOPT_COMPAT40: i32 = 0; +static mut SHOPT_COMPAT41: i32 = 0; +static mut SHOPT_COMPAT42: i32 = 0; +static mut SHOPT_COMPAT43: i32 = 0; +static mut SHOPT_COMPAT44: i32 = 0; +static mut SHOPT_VARS: [RShoptVars; 54] = unsafe { + [ + { + let init = RShoptVars { + name: b"autocd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &autocd as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"assoc_expand_once\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + value: &assoc_expand_once as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"cdable_vars\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &cdable_vars as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"cdspell\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &cdspelling as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"checkhash\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &check_hashed_filenames as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"checkjobs\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &check_jobs_at_exit as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"checkwinsize\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &check_window_size as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"cmdhist\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &command_oriented_history as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"compat31\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT31 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"compat32\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT32 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"compat40\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT40 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"compat41\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT41 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"compat42\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT42 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"compat43\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT43 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"compat44\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_COMPAT44 as *const i32 as *mut libc::c_int, + set_func: Some(set_compatibility_level as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"complete_fullquote\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + value: &complete_fullquote as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"direxpand\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &dircomplete_expand as *const i32 as *mut libc::c_int, + set_func: Some(shopt_set_complete_direxpand as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"dirspell\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &dircomplete_spelling as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"dotglob\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &glob_dot_filenames as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"execfail\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &no_exit_on_failed_exec as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"expand_aliases\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &expand_aliases as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"extdebug\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &debugging_mode as *const i32 as *mut libc::c_int, + set_func: Some(shopt_set_debug_mode as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"extglob\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &extended_glob as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"extquote\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &extended_quote as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"failglob\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &fail_glob_expansion as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"force_fignore\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &force_fignore as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"globasciiranges\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &glob_asciirange as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"globstar\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &glob_star as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"gnu_errfmt\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &gnu_error_format as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"histappend\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &force_append_history as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"histreedit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &history_reediting as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"histverify\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &hist_verify as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"hostcomplete\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &perform_hostname_completion as *const i32 as *mut i32, + set_func: Some( + shopt_enable_hostname_completion as fn(*mut libc::c_char, i32) -> i32, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"huponexit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &hup_on_exit as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"inherit_errexit\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &inherit_errexit as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"interactive_comments\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + value: &interactive_comments as *const i32 as *mut libc::c_int, + set_func: Some(set_shellopts_after_change as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"lastpipe\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &lastpipe_opt as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"lithist\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &literal_history as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"localvar_inherit\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + value: &localvar_inherit as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"localvar_unset\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &localvar_unset as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"login_shell\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &SHOPT_LOGIN_SHELL as *const i32 as *mut i32, + set_func: Some(set_login_shell as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"mailwarn\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &mail_warning as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"no_empty_cmd_completion\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + value: &no_empty_command_completion as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"nocaseglob\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &glob_ignore_case as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"nocasematch\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &match_ignore_case as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"nullglob\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &allow_null_glob_expansion as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"progcomp\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &prog_completion_enabled as *const i32 as *mut i32, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"progcomp_alias\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &progcomp_alias as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"promptvars\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &promptvars as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"restricted_shell\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + value: &restricted_shell as *const i32 as *mut libc::c_int, + set_func: Some(set_restricted_shell as fn(*mut libc::c_char, i32) -> i32), + }; + init + }, + { + let init = RShoptVars { + name: b"shift_verbose\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &print_shift_error as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"sourcepath\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &source_uses_path as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: b"xpg_echo\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value: &xpg_echo as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + { + let init = RShoptVars { + name: 0 as *const libc::c_char as *mut libc::c_char, + value: 0 as *const i32 as *mut libc::c_int, + set_func: ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ), + }; + init + }, + ] +}; + +static SFLAG: i32 = 0x01; +static UFLAG: i32 = 0x02; +static QFLAG: i32 = 0x04; +static OFLAG: i32 = 0x08; +static PFLAG: i32 = 0x10; +static SETOPT: i32 = 1; +static UNSETOPT: i32 = 0; + +static mut ON: *const libc::c_char = b"on\0" as *const u8 as *const libc::c_char; +static mut OFF: *const libc::c_char = b"off\0" as *const u8 as *const libc::c_char; +#[no_mangle] +pub fn shopt_builtin(mut list: *mut WordList) -> i32 { + let mut opt: i32; + let mut flags: i32 = 0; + let mut rval: i32 = 0; + + reset_internal_getopt(); + let psuoq = CString::new("psuoq").expect("CString::new failed"); + loop { + opt = internal_getopt(list, psuoq.as_ptr() as *mut libc::c_char); + if !(opt != -(1 as i32)) { + break; + } + let opt_char = opt as u8 as char; + match opt_char { + 's' => { + flags |= SFLAG; + } + 'u' => flags |= UFLAG, + 'q' => { + flags |= QFLAG; + } + 'o' => { + flags |= OFLAG; + } + 'p' => { + flags |= PFLAG; + } + + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + } + list = unsafe { loptend }; + if flags & (SFLAG | UFLAG) == SFLAG | UFLAG { + unsafe { + builtin_error(dcgettext( + 0 as *const libc::c_char, + b"cannot set and unset shell options simultaneously\0" as *const u8 + as *const libc::c_char, + 5 as i32, + )) + }; + return EXECUTION_FAILURE!(); + } + + rval = EXECUTION_SUCCESS; + if (flags & OFLAG != 0) && ((flags & (SFLAG | UFLAG)) == 0) + // shopt -o + { + //设置了o-flag,并没设s或u-flag + rval = list_shopt_o_options(list, flags); + } else if !list.is_null() && flags & OFLAG != 0 { + //设置-o了 //shopt -so args , shopt -u args + rval = set_shopt_o_options( + if flags & SFLAG != 0 { + '-' as i32 /*on*/ + } else { + '+' as i32 /*off*/ + }, + list, + flags & QFLAG, //æ˜¯å¦æ²‰é»˜? + ); + } else if flags & OFLAG != 0 { + // shopt -so + rval = list_some_o_options(if flags & SFLAG != 0 { 1 } else { 0 }, flags); + } else if !list.is_null() && flags & (SFLAG | UFLAG) != 0 { + // shopt -s/u args + rval = toggle_shopts(if flags & SFLAG != 0 { 1 } else { 0 }, list, flags & QFLAG); + } else if flags & (SFLAG | UFLAG) == 0 { + // shopt [args] + //println!("shopt ===list all "); + rval = list_shopts(list, flags); + } else { + // shopt -su + rval = list_some_shopts(if flags & SFLAG != 0 { SETOPT } else { UNSETOPT }, flags); + } + return rval; +} + +//把环境å˜é‡ç½®0 +#[no_mangle] +pub fn reset_shopt_options() { + unsafe { + cdspelling = 0; + cdable_vars = 0; + autocd = 0; + check_hashed_filenames = 0; + check_window_size = 1; + glob_dot_filenames = 0; + allow_null_glob_expansion = glob_dot_filenames; + no_exit_on_failed_exec = 0; + expand_aliases = 0; + extended_quote = 1; + fail_glob_expansion = 0; + glob_asciirange = 1; + glob_star = 0; + gnu_error_format = 0; + hup_on_exit = 0; + inherit_errexit = 0; + interactive_comments = 1; + lastpipe_opt = 0; + localvar_unset = 0; + localvar_inherit = localvar_unset; + mail_warning = 0; + match_ignore_case = 0; + glob_ignore_case = match_ignore_case; + print_shift_error = 0; + promptvars = 1; + source_uses_path = promptvars; + check_jobs_at_exit = 0; + extended_glob = 0; + assoc_expand_once = 0; + literal_history = 0; + force_append_history = 0; + command_oriented_history = 1; + complete_fullquote = 1; + force_fignore = 1; + history_reediting = 0; + hist_verify = history_reediting; + perform_hostname_completion = 1; + dircomplete_expand = 0; + dircomplete_spelling = 0; + no_empty_command_completion = 0; + prog_completion_enabled = 1; + progcomp_alias = 0; + xpg_echo = 0; + SHOPT_LOGIN_SHELL = login_shell; + } +} + +fn find_shopt(name: *mut libc::c_char) -> i32 { + let mut i = 0; + for item in unsafe { SHOPT_VARS } { + i += 1; + if item.name.is_null() { + return -1; + } + if unsafe { strcmp(name, SHOPT_VARS[i as usize].name) } == 0 { + return i; + } + } + return -1; +} + +fn shopt_error(s: *mut libc::c_char) { + unsafe { + builtin_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid shell option name\0" as *const u8 as *const libc::c_char, + 5 as i32, + ), + s, + ) + }; +} + +fn toggle_shopts(mode: i32, list: *mut WordList, _quiet: i32) -> i32 { + let mut l: *mut WordList; + let mut ind: i32; + let mut rval: i32; + let v: *mut ShellVar; + l = list; + rval = EXECUTION_SUCCESS!(); + while !l.is_null() { + unsafe { + ind = find_shopt((*(*l).word).word); + if ind < 0 { + shopt_error((*(*l).word).word); + rval = EXECUTION_FAILURE!(); + } else { + *SHOPT_VARS[ind as usize].value = mode; + if (SHOPT_VARS[ind as usize].set_func).is_some() { + SHOPT_VARS[ind as usize].set_func.expect("")( + SHOPT_VARS[ind as usize].name, + mode, + ); + /* + (Some( + ((*SHOPT_VARS.as_mut_ptr().offset(ind as isize)).set_func) + .expect("non-null function pointer"), + )) + .expect( + "non-null function pointer", + )(SHOPT_VARS[ind as usize].name, mode); + */ + } + } + l = (*l).next; + } + } + + v = find_variable(b"BASHOPTS\0" as *const u8 as *const libc::c_char); + + if !v.is_null() { + set_bashopts(); + } + return rval; +} +fn print_shopt(name: *mut libc::c_char, val: i32, flags: i32) { + let msg: CString = CString::new("shopt %s %s\n").expect("CString new faild"); + let s: CString = CString::new("-s").expect("CString new faild"); + let u: CString = CString::new("-u").expect("CString new faild"); + let optfmt: CString = CString::new("%-15s\t%s\n").expect("CString new faild"); + if flags & PFLAG != 0 { + unsafe { + printf( + msg.as_ptr(), + if val != 0 { s.as_ptr() } else { u.as_ptr() }, + name, + ) + }; + } else { + unsafe { printf(optfmt.as_ptr(), name, if val != 0 { ON } else { OFF }) }; + }; +} + +fn list_shopts(mut list: *mut WORD_LIST, mut flags: libc::c_int) -> libc::c_int { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut i: libc::c_int = 0; + let mut val: libc::c_int = 0; + let mut rval: libc::c_int = 0; + + if list.is_null() { + i = 0 as libc::c_int; + unsafe { + while !(SHOPT_VARS[i as usize].name).is_null() { + val = *SHOPT_VARS[i as usize].value; + if flags & QFLAG as libc::c_int == 0 as libc::c_int { + print_shopt(SHOPT_VARS[i as usize].name, val, flags); + } + i += 1; + } + } + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + + l = list; + rval = EXECUTION_SUCCESS!(); + while !l.is_null() { + unsafe { + i = find_shopt((*(*l).word).word); + if i < 0 as libc::c_int { + shopt_error((*(*l).word).word); + rval = EXECUTION_FAILURE!(); + } else { + val = *SHOPT_VARS[i as usize].value; + if val == 0 as libc::c_int { + rval = EXECUTION_FAILURE!(); + } + if flags & QFLAG as libc::c_int == 0 as libc::c_int { + print_shopt((*(*l).word).word, val, flags); + } + } + l = (*l).next; + } + } + return sh_chkwrite(rval); +} + +fn list_some_shopts(mode: i32, flags: i32) -> i32 { + unsafe { + for item in SHOPT_VARS { + if ((flags & QFLAG) == 0) && item.value != std::ptr::null_mut() && mode == *item.value { + print_shopt(item.name, *item.value, flags); + } + } + return sh_chkwrite(EXECUTION_SUCCESS!()); + } +} + +fn list_shopt_o_options(list: *mut WordList, flags: i32) -> i32 { + let mut l: *mut WordList = 0 as *mut WordList; + let mut val: i32 = 0; + let mut rval: i32 = EXECUTION_SUCCESS!(); + if list.is_null() { + if flags & QFLAG == 0 { + list_minus_o_opts(-1, flags & PFLAG); + } + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + l = list; + unsafe { + while !l.is_null() { + val = minus_o_option_value((*(*l).word).word); + if val == -1 { + sh_invalidoptname((*(*l).word).word); + rval = EXECUTION_FAILURE!(); + } else { + if val == 0 { + rval = EXECUTION_FAILURE!(); + } + if flags & QFLAG == 0 { + if flags & PFLAG != 0 { + printf( + b"set %co %s\n\0" as *const u8 as *const libc::c_char, + if val != 0 { '-' as i32 } else { '+' as i32 }, + (*(*l).word).word, + ); + println!( + "set {:?}o %{:?}", + if val != 0 { b'-' } else { b'+' }, + (*(*l).word).word + ) + } else { + printf( + b"%-15s\t%s\n\0" as *const u8 as *const libc::c_char, + (*(*l).word).word, + if val != 0 { ON } else { OFF }, + ); + } + } + } + l = (*l).next; + } + } + return sh_chkwrite(rval); +} + +fn list_some_o_options(mode: i32, flags: i32) -> i32 { + if flags & QFLAG == 0 { + list_minus_o_opts(mode, flags & PFLAG); + } + return sh_chkwrite(EXECUTION_SUCCESS!()); +} +fn set_shopt_o_options(mode: i32, list: *mut WordList, _quiet: i32) -> i32 { + //let mut l: *mut WordList =0 as *mut WordList; + let mut l: *mut WordList; + let mut rval: i32; + l = list; + rval = EXECUTION_SUCCESS!(); + while !l.is_null() { + unsafe { + if set_minus_o_option(mode, (*(*l).word).word) == 1 as i32 { + rval = 1 as i32; + } + l = (*l).next; + } + } + set_shellopts(); + return rval; +} +fn set_shellopts_after_change(_option_name: *mut libc::c_char, _mode: i32) -> i32 { + set_shellopts(); + return 0; +} +fn shopt_set_debug_mode(_option_name: *mut libc::c_char, _mode: i32) -> i32 { + unsafe { + function_trace_mode = debugging_mode; + error_trace_mode = function_trace_mode; + set_shellopts(); + if debugging_mode != 0 { + init_bash_argv(); + } + return 0; + } +} +fn shopt_enable_hostname_completion(_option_name: *mut libc::c_char, mode: i32) -> i32 { + return enable_hostname_completion(mode); +} +fn set_compatibility_level(option_name: *mut libc::c_char, mode: i32) -> i32 { + let mut ind: i32 = 0; + let mut rhs: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if mode != 0 { + SHOPT_COMPAT32 = 0 as i32; + SHOPT_COMPAT31 = SHOPT_COMPAT32; + SHOPT_COMPAT43 = 0 as i32; + SHOPT_COMPAT42 = SHOPT_COMPAT43; + SHOPT_COMPAT41 = SHOPT_COMPAT42; + SHOPT_COMPAT40 = SHOPT_COMPAT41; + SHOPT_COMPAT44 = 0 as i32; + ind = find_shopt(option_name); + *SHOPT_VARS[ind as usize].value = mode; + } + if SHOPT_COMPAT31 != 0 { + shell_compatibility_level = 31 as i32; + } else if SHOPT_COMPAT32 != 0 { + shell_compatibility_level = 32 as i32; + } else if SHOPT_COMPAT40 != 0 { + shell_compatibility_level = 40 as i32; + } else if SHOPT_COMPAT41 != 0 { + shell_compatibility_level = 41 as i32; + } else if SHOPT_COMPAT42 != 0 { + shell_compatibility_level = 42 as i32; + } else if SHOPT_COMPAT43 != 0 { + shell_compatibility_level = 43 as i32; + } else if SHOPT_COMPAT44 != 0 { + shell_compatibility_level = 44 as i32; + } else { + shell_compatibility_level = 51 as i32; + } + rhs = itos(shell_compatibility_level as intmax_t); + bind_variable( + b"BASH_COMPAT\0" as *const u8 as *const libc::c_char, + rhs, + 0 as i32, + ); + free(rhs as *mut libc::c_void); + } + return 0; +} +#[no_mangle] +pub fn set_compatibility_opts() { + unsafe { + SHOPT_COMPAT32 = 0; + SHOPT_COMPAT31 = 0; + SHOPT_COMPAT43 = 0; + SHOPT_COMPAT42 = 0; + SHOPT_COMPAT41 = 0; + SHOPT_COMPAT40 = 0; + SHOPT_COMPAT44 = 0; + match shell_compatibility_level { + 44 => { + SHOPT_COMPAT44 = 1; + } + 43 => { + SHOPT_COMPAT43 = 1; + } + 42 => { + SHOPT_COMPAT42 = 1; + } + 41 => { + SHOPT_COMPAT41 = 1; + } + 40 => { + SHOPT_COMPAT40 = 1; + } + 32 => { + SHOPT_COMPAT32 = 1; + } + 31 => { + SHOPT_COMPAT31 = 1; + } + _ => {} + }; + } +} +fn shopt_set_complete_direxpand(_option_name: *mut libc::c_char, _mode: i32) -> i32 { + set_directory_hook(); + return 0; +} +fn set_restricted_shell(_option_name: *mut libc::c_char, _mode: i32) -> i32 { + static mut SAVE_RESTRICTED: i32 = -1; + unsafe { + if SAVE_RESTRICTED == -1 { + SAVE_RESTRICTED = shell_is_restricted(shell_name); + } + restricted_shell = SAVE_RESTRICTED; + } + return 0; +} +#[no_mangle] +pub fn set_login_shell(_option_name: *mut libc::c_char, _mode: i32) -> i32 { + unsafe { + SHOPT_LOGIN_SHELL = if login_shell != 0 { 1 } else { 0 }; + return 0; + } +} +#[no_mangle] +pub fn get_shopt_options() -> *mut *mut libc::c_char { + unsafe { + let mut ret: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut n: i32 = 0; + let mut i: i32 = 0; + n = (::std::mem::size_of::<[RShoptVars; 54]>() as libc::c_ulong) + .wrapping_div(::std::mem::size_of::() as libc::c_ulong) as i32; + + ret = strvec_create(n + 1 as i32); + i = 0 as i32; + while !(SHOPT_VARS[i as usize].name).is_null() { + let ref mut fresh0 = *ret.offset(i as isize); + *fresh0 = strcpy( + malloc( + (1 as i32 as libc::c_ulong) + .wrapping_add(strlen(SHOPT_VARS[i as usize].name) as u64) + as usize, + ) as *mut libc::c_char, + SHOPT_VARS[i as usize].name, + ); + i += 1; + } + let ref mut fresh1 = *ret.offset(i as isize); + *fresh1 = 0 as *mut libc::c_void as *mut libc::c_char; + return ret; + } +} + +#[no_mangle] +pub fn shopt_setopt(name: *mut libc::c_char, mode: i32) -> i32 { + unsafe { + let wl: *mut WordList; + let r: i32; + + wl = make_word_list(make_word(name), std::ptr::null_mut()); + //wl = make_word_list(make_word(name), 0 as *mut libc::c_void as *mut WordList); + r = toggle_shopts(mode, wl, 0); + dispose_words(wl); + return r; + } +} +#[no_mangle] +pub fn shopt_listopt(name: *mut libc::c_char, reusable: i32) -> i32 { + let mut i: i32 = 0; + if name.is_null() { + return list_shopts( + // 0 as *mut libc::c_void as *mut WordList, + std::ptr::null_mut(), + if reusable != 0 { PFLAG } else { 0 }, + ); + } + i = find_shopt(name); + if i < 0 { + shopt_error(name); + return 1; + } + print_shopt( + name, + unsafe { *SHOPT_VARS[i as usize].value }, + if reusable != 0 { PFLAG } else { 0 }, + ); + return sh_chkwrite(EXECUTION_SUCCESS!()); +} +#[no_mangle] +pub fn set_bashopts() { + let value: *mut libc::c_char; + let mut tflag: [libc::c_char; 54] = [0; 54]; + let mut vsize: i32; + let mut i: i32; + let mut vptr: i32; + /* + let mut ip: *mut i32; + */ + let exported: i32; + let mut v: *mut ShellVar; + unsafe { + i = 0; + vsize = 0; + while !(SHOPT_VARS[i as usize].name).is_null() { + tflag[i as usize] = 0 as libc::c_char; + if *SHOPT_VARS[i as usize].value != 0 { + vsize += strlen(SHOPT_VARS[i as usize].name) as i32; + vsize += 1; + /* + vsize = (vsize as libc::c_ulong) + .wrapping_add( + (strlen(SHOPT_VARS[i as usize].name)) + .wrapping_add(1 as i32 as libc::c_ulong), + ) as i32 as libc::c_int; + */ + tflag[i as usize] = 1 as libc::c_char; + } + i += 1; + } + value = libc::malloc((vsize + 1) as usize) as *mut libc::c_char; + vptr = 0; + i = 0; + while !(SHOPT_VARS[i as usize].name).is_null() { + if tflag[i as usize] != 0 { + strcpy(value.offset(vptr as isize), SHOPT_VARS[i as usize].name); + vptr = (vptr as libc::c_ulong) + .wrapping_add(strlen(SHOPT_VARS[i as usize].name) as u64) + as i32 as i32; + let fresh2 = vptr; + vptr = vptr + 1; + *value.offset(fresh2 as isize) = ':' as i32 as libc::c_char; + } + i += 1; + } + //printf(b"the values=%s" as *const u8 as *const libc::c_char, value); + if vptr != 0 { + vptr -= 1; + } + *value.offset(vptr as isize) = '\u{0}' as i32 as libc::c_char; + v = find_variable(b"BASHOPTS\0" as *const u8 as *const libc::c_char); + if !v.is_null() { + (*v).attributes &= !(0x2 as i32); + exported = (*v).attributes & 0x1 as i32; + } else { + exported = 0; + } + v = bind_variable(b"BASHOPTS\0" as *const u8 as *const libc::c_char, value, 0); + (*v).attributes |= 0x2; + if mark_modified_vars != 0 && exported == 0 as i32 && (*v).attributes & 0x1 != 0 { + (*v).attributes &= !(0x1); + } + libc::free(value as *mut libc::c_void); + } +} +#[no_mangle] +pub fn parse_bashopts(value: *mut libc::c_char) { + let mut vname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vptr: i32 = 0; + let mut ind: i32 = 0; + vptr = 0 as i32; + unsafe { + loop { + vname = extract_colon_unit(value, &mut vptr); + if vname.is_null() { + break; + } + ind = find_shopt(vname); + if ind >= 0 as i32 { + *SHOPT_VARS[ind as usize].value = 1 as i32; + if (SHOPT_VARS[ind as usize].set_func).is_some() { + (Some( + ((*SHOPT_VARS.as_mut_ptr().offset(ind as isize)).set_func) + .expect("non-null function pointer"), + )) + .expect("non-null function pointer")( + SHOPT_VARS[ind as usize].name, 1 as i32 + ); + } + } + free(vname as *mut libc::c_void); + } + } +} +#[no_mangle] +pub fn initialize_bashopts(no_bashopts: i32) { + unsafe { + let temp: *mut libc::c_char; + let var: *mut ShellVar; + if no_bashopts == 0 { + var = find_variable(b"BASHOPTS\0" as *const u8 as *const libc::c_char); + if !var.is_null() && (*var).attributes & att_imported as i32 != 0 { + temp = if (*var).attributes & att_array != 0 + || (*var).attributes & att_assoc as i32 != 0 + { + std::ptr::null_mut() + } else { + strcpy( + malloc( + (1 as libc::c_ulong).wrapping_add(strlen((*var).value) as u64) as usize, + ) as *mut libc::c_char, + (*var).value, + ) + }; + if !temp.is_null() { + parse_bashopts(temp); + free(temp as *mut libc::c_void); + } + } + } + set_bashopts(); + } +} diff --git a/utshell-0.5.0/src/builtins/signal.rs b/utshell-0.5.0/src/builtins/signal.rs new file mode 100644 index 00000000..b4b0afa5 --- /dev/null +++ b/utshell-0.5.0/src/builtins/signal.rs @@ -0,0 +1,874 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +//# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + +//# SPDX-License-Identifier: GPL-3.0-or-later + +/* automatically generated by rust-bindgen */ +use crate::src_common::*; +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: u32 = 201706; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 28; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __HAVE_GENERIC_SELECTION: u32 = 1; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const _BITS_SIGNUM_H: u32 = 1; +pub const _BITS_SIGNUM_GENERIC_H: u32 = 1; +pub const SIGINT: u32 = 2; +pub const SIGILL: u32 = 4; +pub const SIGABRT: u32 = 6; +pub const SIGFPE: u32 = 8; +pub const SIGSEGV: u32 = 11; +pub const SIGTERM: u32 = 15; +pub const SIGHUP: u32 = 1; +pub const SIGQUIT: u32 = 3; +pub const SIGTRAP: u32 = 5; +pub const SIGKILL: u32 = 9; +pub const SIGBUS: u32 = 10; +pub const SIGSYS: u32 = 12; +pub const SIGPIPE: u32 = 13; +pub const SIGALRM: u32 = 14; +pub const SIGURG: u32 = 16; +pub const SIGSTOP: u32 = 17; +pub const SIGTSTP: u32 = 18; +pub const SIGCONT: u32 = 19; +pub const SIGCHLD: u32 = 20; +pub const SIGTTIN: u32 = 21; +pub const SIGTTOU: u32 = 22; +pub const SIGPOLL: u32 = 23; +pub const SIGXCPU: u32 = 24; +pub const SIGXFSZ: u32 = 25; +pub const SIGVTALRM: u32 = 26; +pub const SIGPROF: u32 = 27; +pub const SIGUSR1: u32 = 30; +pub const SIGUSR2: u32 = 31; +pub const SIGWINCH: u32 = 28; +pub const SIGIO: u32 = 23; +pub const SIGIOT: u32 = 6; +pub const SIGCLD: u32 = 20; +pub const __SIGRTMIN: u32 = 32; +pub const __SIGRTMAX: u32 = 32; +pub const _NSIG: u32 = 33; +pub const SIGSTKFLT: u32 = 16; +pub const SIGPWR: u32 = 30; +pub const __sig_atomic_t_defined: u32 = 1; +pub const __sigset_t_defined: u32 = 1; +pub const _STRUCT_TIMESPEC: u32 = 1; +pub const __siginfo_t_defined: u32 = 1; +pub const __SI_MAX_SIZE: u32 = 128; +pub const _BITS_SIGINFO_ARCH_H: u32 = 1; +pub const __SI_ERRNO_THEN_CODE: u32 = 1; +pub const __SI_HAVE_SIGSYS: u32 = 1; +pub const _BITS_SIGINFO_CONSTS_H: u32 = 1; +pub const __SI_ASYNCIO_AFTER_SIGIO: u32 = 1; +pub const __sigevent_t_defined: u32 = 1; +pub const __SIGEV_MAX_SIZE: u32 = 64; +pub const __have_pthread_attr_t: u32 = 1; +pub const _BITS_SIGEVENT_CONSTS_H: u32 = 1; +pub const NSIG: u32 = 33; +pub const _BITS_SIGACTION_H: u32 = 1; +pub const SA_NOCLDSTOP: u32 = 1; +pub const SA_NOCLDWAIT: u32 = 2; +pub const SA_SIGINFO: u32 = 4; +pub const SA_ONSTACK: u32 = 134217728; +pub const SA_RESTART: u32 = 268435456; +pub const SA_NODEFER: u32 = 1073741824; +pub const SA_RESETHAND: u32 = 2147483648; +pub const SA_INTERRUPT: u32 = 536870912; +pub const SA_NOMASK: u32 = 1073741824; +pub const SA_ONESHOT: u32 = 2147483648; +pub const SA_STACK: u32 = 134217728; +pub const SIG_BLOCK: u32 = 0; +pub const SIG_UNBLOCK: u32 = 1; +pub const SIG_SETMASK: u32 = 2; +pub const _BITS_SIGCONTEXT_H: u32 = 1; +pub const FP_XSTATE_MAGIC1: u32 = 1179670611; +pub const FP_XSTATE_MAGIC2: u32 = 1179670597; +pub const __stack_t_defined: u32 = 1; +pub const _SYS_UCONTEXT_H: u32 = 1; +pub const __NGREG: u32 = 23; +pub const NGREG: u32 = 23; +pub const _BITS_SIGSTACK_H: u32 = 1; +pub const MINSIGSTKSZ: u32 = 2048; +pub const SIGSTKSZ: u32 = 8192; +pub const _BITS_SS_FLAGS_H: u32 = 1; +pub const __sigstack_defined: u32 = 1; +pub const _BITS_PTHREADTYPES_COMMON_H: u32 = 1; +pub const _THREAD_SHARED_TYPES_H: u32 = 1; +pub const _BITS_PTHREADTYPES_ARCH_H: u32 = 1; +pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40; +pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56; +pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_COND_T: u32 = 48; +pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4; +pub const __PTHREAD_MUTEX_LOCK_ELISION: u32 = 1; +pub const __PTHREAD_MUTEX_NUSERS_AFTER_KIND: u32 = 0; +pub const __PTHREAD_MUTEX_USE_UNION: u32 = 0; +pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1; +pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; +pub const _BITS_SIGTHREAD_H: u32 = 1; +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __intmax_t = ::std::os::raw::c_long; +pub type __uintmax_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type __sig_atomic_t = ::std::os::raw::c_int; +pub type sig_atomic_t = __sig_atomic_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sigset_t { + pub __val: [::std::os::raw::c_ulong; 16usize], +} +pub type sigset_t = __sigset_t; +pub type pid_t = __pid_t; +pub type uid_t = __uid_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigval { + pub sival_int: ::std::os::raw::c_int, + pub sival_ptr: *mut ::std::os::raw::c_void, + _bindgen_union_align: u64, +} +pub type __sigval_t = sigval; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t { + pub si_signo: ::std::os::raw::c_int, + pub si_errno: ::std::os::raw::c_int, + pub si_code: ::std::os::raw::c_int, + pub __pad0: ::std::os::raw::c_int, + pub _sifields: siginfo_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1 { + pub _pad: [::std::os::raw::c_int; 28usize], + pub _kill: siginfo_t__bindgen_ty_1__bindgen_ty_1, + pub _timer: siginfo_t__bindgen_ty_1__bindgen_ty_2, + pub _rt: siginfo_t__bindgen_ty_1__bindgen_ty_3, + pub _sigchld: siginfo_t__bindgen_ty_1__bindgen_ty_4, + pub _sigfault: siginfo_t__bindgen_ty_1__bindgen_ty_5, + pub _sigpoll: siginfo_t__bindgen_ty_1__bindgen_ty_6, + pub _sigsys: siginfo_t__bindgen_ty_1__bindgen_ty_7, + _bindgen_union_align: [u64; 14usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_2 { + pub si_tid: ::std::os::raw::c_int, + pub si_overrun: ::std::os::raw::c_int, + pub si_sigval: __sigval_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_3 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_sigval: __sigval_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_4 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_status: ::std::os::raw::c_int, + pub si_utime: __clock_t, + pub si_stime: __clock_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_5 { + pub si_addr: *mut ::std::os::raw::c_void, + pub si_addr_lsb: ::std::os::raw::c_short, + pub _bounds: siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1 { + pub _addr_bnd: siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, + pub _pkey: __uint32_t, + _bindgen_union_align: [u64; 2usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1 { + pub _lower: *mut ::std::os::raw::c_void, + pub _upper: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_6 { + pub si_band: ::std::os::raw::c_long, + pub si_fd: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_7 { + pub _call_addr: *mut ::std::os::raw::c_void, + pub _syscall: ::std::os::raw::c_int, + pub _arch: ::std::os::raw::c_uint, +} +pub const SI_ASYNCNL: _bindgen_ty_1 = -60; +pub const SI_TKILL: _bindgen_ty_1 = -6; +pub const SI_SIGIO: _bindgen_ty_1 = -5; +pub const SI_ASYNCIO: _bindgen_ty_1 = -4; +pub const SI_MESGQ: _bindgen_ty_1 = -3; +pub const SI_TIMER: _bindgen_ty_1 = -2; +pub const SI_QUEUE: _bindgen_ty_1 = -1; +pub const SI_USER: _bindgen_ty_1 = 0; +pub const SI_KERNEL: _bindgen_ty_1 = 128; +pub type _bindgen_ty_1 = i32; +pub const ILL_ILLOPC: _bindgen_ty_2 = 1; +pub const ILL_ILLOPN: _bindgen_ty_2 = 2; +pub const ILL_ILLADR: _bindgen_ty_2 = 3; +pub const ILL_ILLTRP: _bindgen_ty_2 = 4; +pub const ILL_PRVOPC: _bindgen_ty_2 = 5; +pub const ILL_PRVREG: _bindgen_ty_2 = 6; +pub const ILL_COPROC: _bindgen_ty_2 = 7; +pub const ILL_BADSTK: _bindgen_ty_2 = 8; +pub type _bindgen_ty_2 = u32; +pub const FPE_INTDIV: _bindgen_ty_3 = 1; +pub const FPE_INTOVF: _bindgen_ty_3 = 2; +pub const FPE_FLTDIV: _bindgen_ty_3 = 3; +pub const FPE_FLTOVF: _bindgen_ty_3 = 4; +pub const FPE_FLTUND: _bindgen_ty_3 = 5; +pub const FPE_FLTRES: _bindgen_ty_3 = 6; +pub const FPE_FLTINV: _bindgen_ty_3 = 7; +pub const FPE_FLTSUB: _bindgen_ty_3 = 8; +pub type _bindgen_ty_3 = u32; +pub const SEGV_MAPERR: _bindgen_ty_4 = 1; +pub const SEGV_ACCERR: _bindgen_ty_4 = 2; +pub const SEGV_BNDERR: _bindgen_ty_4 = 3; +pub const SEGV_PKUERR: _bindgen_ty_4 = 4; +pub type _bindgen_ty_4 = u32; +pub const BUS_ADRALN: _bindgen_ty_5 = 1; +pub const BUS_ADRERR: _bindgen_ty_5 = 2; +pub const BUS_OBJERR: _bindgen_ty_5 = 3; +pub const BUS_MCEERR_AR: _bindgen_ty_5 = 4; +pub const BUS_MCEERR_AO: _bindgen_ty_5 = 5; +pub type _bindgen_ty_5 = u32; +pub const CLD_EXITED: _bindgen_ty_6 = 1; +pub const CLD_KILLED: _bindgen_ty_6 = 2; +pub const CLD_DUMPED: _bindgen_ty_6 = 3; +pub const CLD_TRAPPED: _bindgen_ty_6 = 4; +pub const CLD_STOPPED: _bindgen_ty_6 = 5; +pub const CLD_CONTINUED: _bindgen_ty_6 = 6; +pub type _bindgen_ty_6 = u32; +pub const POLL_IN: _bindgen_ty_7 = 1; +pub const POLL_OUT: _bindgen_ty_7 = 2; +pub const POLL_MSG: _bindgen_ty_7 = 3; +pub const POLL_ERR: _bindgen_ty_7 = 4; +pub const POLL_PRI: _bindgen_ty_7 = 5; +pub const POLL_HUP: _bindgen_ty_7 = 6; +pub type _bindgen_ty_7 = u32; +pub type sigval_t = __sigval_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigevent { + pub sigev_value: __sigval_t, + pub sigev_signo: ::std::os::raw::c_int, + pub sigev_notify: ::std::os::raw::c_int, + pub _sigev_un: sigevent__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigevent__bindgen_ty_1 { + pub _pad: [::std::os::raw::c_int; 12usize], + pub _tid: __pid_t, + pub _sigev_thread: sigevent__bindgen_ty_1__bindgen_ty_1, + _bindgen_union_align: [u64; 6usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigevent__bindgen_ty_1__bindgen_ty_1 { + pub _function: ::std::option::Option, + pub _attribute: *mut pthread_attr_t, +} +pub type sigevent_t = sigevent; +pub const SIGEV_SIGNAL: _bindgen_ty_8 = 0; +pub const SIGEV_NONE: _bindgen_ty_8 = 1; +pub const SIGEV_THREAD: _bindgen_ty_8 = 2; +pub const SIGEV_THREAD_ID: _bindgen_ty_8 = 4; +pub type _bindgen_ty_8 = u32; +pub type __sighandler_t = ::std::option::Option; +extern "C" { + pub fn __sysv_signal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) + -> __sighandler_t; +} +extern "C" { + pub fn signal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) -> __sighandler_t; +} +extern "C" { + pub fn kill(__pid: __pid_t, __sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn killpg(__pgrp: __pid_t, __sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn raise(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ssignal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) -> __sighandler_t; +} +extern "C" { + pub fn gsignal(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn psignal(__sig: ::std::os::raw::c_int, __s: *const ::std::os::raw::c_char); +} +extern "C" { + pub fn psiginfo(__pinfo: *const siginfo_t, __s: *const ::std::os::raw::c_char); +} +extern "C" { + pub fn sigblock(__mask: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigsetmask(__mask: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn siggetmask() -> ::std::os::raw::c_int; +} +pub type sig_t = __sighandler_t; +extern "C" { + pub fn sigemptyset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigfillset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigaddset(__set: *mut sigset_t, __signo: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigdelset(__set: *mut sigset_t, __signo: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigismember( + __set: *const sigset_t, + __signo: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigaction { + pub __sigaction_handler: sigaction__bindgen_ty_1, + pub sa_mask: __sigset_t, + pub sa_flags: ::std::os::raw::c_int, + pub sa_restorer: ::std::option::Option, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigaction__bindgen_ty_1 { + pub sa_handler: __sighandler_t, + pub sa_sigaction: ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: *mut siginfo_t, + arg3: *mut ::std::os::raw::c_void, + ), + >, + _bindgen_union_align: u64, +} +extern "C" { + pub fn sigprocmask( + __how: ::std::os::raw::c_int, + __set: *const sigset_t, + __oset: *mut sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigsuspend(__set: *const sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigaction( + __sig: ::std::os::raw::c_int, + __act: *const sigaction, + __oact: *mut sigaction, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigpending(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigwait( + __set: *const sigset_t, + __sig: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigwaitinfo(__set: *const sigset_t, __info: *mut siginfo_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigtimedwait( + __set: *const sigset_t, + __info: *mut siginfo_t, + __timeout: *const timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigqueue( + __pid: __pid_t, + __sig: ::std::os::raw::c_int, + __val: sigval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_sys_siglist"] + pub static mut _sys_siglist: [*const ::std::os::raw::c_char; 65usize]; +} +extern "C" { + #[link_name = "\u{1}sys_siglist"] + pub static mut sys_siglist: [*const ::std::os::raw::c_char; 65usize]; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpx_sw_bytes { + pub magic1: __uint32_t, + pub extended_size: __uint32_t, + pub xstate_bv: __uint64_t, + pub xstate_size: __uint32_t, + pub __glibc_reserved1: [__uint32_t; 7usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpreg { + pub significand: [::std::os::raw::c_ushort; 4usize], + pub exponent: ::std::os::raw::c_ushort, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpxreg { + pub significand: [::std::os::raw::c_ushort; 4usize], + pub exponent: ::std::os::raw::c_ushort, + pub __glibc_reserved1: [::std::os::raw::c_ushort; 3usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _xmmreg { + pub element: [__uint32_t; 4usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpstate { + pub cwd: __uint16_t, + pub swd: __uint16_t, + pub ftw: __uint16_t, + pub fop: __uint16_t, + pub rip: __uint64_t, + pub rdp: __uint64_t, + pub mxcsr: __uint32_t, + pub mxcr_mask: __uint32_t, + pub _st: [_fpxreg; 8usize], + pub _xmm: [_xmmreg; 16usize], + pub __glibc_reserved1: [__uint32_t; 24usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigcontext { + pub r8: __uint64_t, + pub r9: __uint64_t, + pub r10: __uint64_t, + pub r11: __uint64_t, + pub r12: __uint64_t, + pub r13: __uint64_t, + pub r14: __uint64_t, + pub r15: __uint64_t, + pub rdi: __uint64_t, + pub rsi: __uint64_t, + pub rbp: __uint64_t, + pub rbx: __uint64_t, + pub rdx: __uint64_t, + pub rax: __uint64_t, + pub rcx: __uint64_t, + pub rsp: __uint64_t, + pub rip: __uint64_t, + pub eflags: __uint64_t, + pub cs: ::std::os::raw::c_ushort, + pub gs: ::std::os::raw::c_ushort, + pub fs: ::std::os::raw::c_ushort, + pub __pad0: ::std::os::raw::c_ushort, + pub err: __uint64_t, + pub trapno: __uint64_t, + pub oldmask: __uint64_t, + pub cr2: __uint64_t, + pub __bindgen_anon_1: sigcontext__bindgen_ty_1, + pub __reserved1: [__uint64_t; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigcontext__bindgen_ty_1 { + pub fpstate: *mut _fpstate, + pub __fpstate_word: __uint64_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _xsave_hdr { + pub xstate_bv: __uint64_t, + pub __glibc_reserved1: [__uint64_t; 2usize], + pub __glibc_reserved2: [__uint64_t; 5usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _ymmh_state { + pub ymmh_space: [__uint32_t; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _xstate { + pub fpstate: _fpstate, + pub xstate_hdr: _xsave_hdr, + pub ymmh: _ymmh_state, +} +extern "C" { + pub fn sigreturn(__scp: *mut sigcontext) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct stack_t { + pub ss_sp: *mut ::std::os::raw::c_void, + pub ss_flags: ::std::os::raw::c_int, + pub ss_size: usize, +} +pub type greg_t = ::std::os::raw::c_longlong; +pub type gregset_t = [greg_t; 23usize]; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _libc_fpxreg { + pub significand: [::std::os::raw::c_ushort; 4usize], + pub exponent: ::std::os::raw::c_ushort, + pub __glibc_reserved1: [::std::os::raw::c_ushort; 3usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _libc_xmmreg { + pub element: [__uint32_t; 4usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _libc_fpstate { + pub cwd: __uint16_t, + pub swd: __uint16_t, + pub ftw: __uint16_t, + pub fop: __uint16_t, + pub rip: __uint64_t, + pub rdp: __uint64_t, + pub mxcsr: __uint32_t, + pub mxcr_mask: __uint32_t, + pub _st: [_libc_fpxreg; 8usize], + pub _xmm: [_libc_xmmreg; 16usize], + pub __glibc_reserved1: [__uint32_t; 24usize], +} +pub type fpregset_t = *mut _libc_fpstate; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mcontext_t { + pub gregs: gregset_t, + pub fpregs: fpregset_t, + pub __reserved1: [::std::os::raw::c_ulonglong; 8usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ucontext_t { + pub uc_flags: ::std::os::raw::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: sigset_t, + pub __fpregs_mem: _libc_fpstate, + pub __ssp: [::std::os::raw::c_ulonglong; 4usize], +} +extern "C" { + pub fn siginterrupt( + __sig: ::std::os::raw::c_int, + __interrupt: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +pub const SS_ONSTACK: _bindgen_ty_9 = 1; +pub const SS_DISABLE: _bindgen_ty_9 = 2; +pub type _bindgen_ty_9 = u32; +extern "C" { + pub fn sigaltstack(__ss: *const stack_t, __oss: *mut stack_t) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigstack { + pub ss_sp: *mut ::std::os::raw::c_void, + pub ss_onstack: ::std::os::raw::c_int, +} +extern "C" { + pub fn sigstack(__ss: *mut sigstack, __oss: *mut sigstack) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_rwlock_arch_t { + pub __readers: ::std::os::raw::c_uint, + pub __writers: ::std::os::raw::c_uint, + pub __wrphase_futex: ::std::os::raw::c_uint, + pub __writers_futex: ::std::os::raw::c_uint, + pub __pad3: ::std::os::raw::c_uint, + pub __pad4: ::std::os::raw::c_uint, + pub __cur_writer: ::std::os::raw::c_int, + pub __shared: ::std::os::raw::c_int, + pub __rwelision: ::std::os::raw::c_schar, + pub __pad1: [::std::os::raw::c_uchar; 7usize], + pub __pad2: ::std::os::raw::c_ulong, + pub __flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_internal_list { + pub __prev: *mut __pthread_internal_list, + pub __next: *mut __pthread_internal_list, +} +pub type __pthread_list_t = __pthread_internal_list; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_mutex_s { + pub __lock: ::std::os::raw::c_int, + pub __count: ::std::os::raw::c_uint, + pub __owner: ::std::os::raw::c_int, + pub __nusers: ::std::os::raw::c_uint, + pub __kind: ::std::os::raw::c_int, + pub __spins: ::std::os::raw::c_short, + pub __elision: ::std::os::raw::c_short, + pub __list: __pthread_list_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __pthread_cond_s { + pub __bindgen_anon_1: __pthread_cond_s__bindgen_ty_1, + pub __bindgen_anon_2: __pthread_cond_s__bindgen_ty_2, + pub __g_refs: [::std::os::raw::c_uint; 2usize], + pub __g_size: [::std::os::raw::c_uint; 2usize], + pub __g1_orig_size: ::std::os::raw::c_uint, + pub __wrefs: ::std::os::raw::c_uint, + pub __g_signals: [::std::os::raw::c_uint; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __pthread_cond_s__bindgen_ty_1 { + pub __wseq: ::std::os::raw::c_ulonglong, + pub __wseq32: __pthread_cond_s__bindgen_ty_1__bindgen_ty_1, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_cond_s__bindgen_ty_1__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __pthread_cond_s__bindgen_ty_2 { + pub __g1_start: ::std::os::raw::c_ulonglong, + pub __g1_start32: __pthread_cond_s__bindgen_ty_2__bindgen_ty_1, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_cond_s__bindgen_ty_2__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +pub type pthread_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutexattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_condattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +pub type pthread_key_t = ::std::os::raw::c_uint; +pub type pthread_once_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_attr_t { + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 7usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutex_t { + pub __data: __pthread_mutex_s, + pub __size: [::std::os::raw::c_char; 40usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 5usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_cond_t { + pub __data: __pthread_cond_s, + pub __size: [::std::os::raw::c_char; 48usize], + pub __align: ::std::os::raw::c_longlong, + _bindgen_union_align: [u64; 6usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlock_t { + pub __data: __pthread_rwlock_arch_t, + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 7usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlockattr_t { + pub __size: [::std::os::raw::c_char; 8usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: u64, +} +pub type pthread_spinlock_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrier_t { + pub __size: [::std::os::raw::c_char; 32usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 4usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrierattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +extern "C" { + pub fn pthread_sigmask( + __how: ::std::os::raw::c_int, + __newmask: *const __sigset_t, + __oldmask: *mut __sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pthread_kill( + __threadid: pthread_t, + __signo: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __libc_current_sigrtmin() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __libc_current_sigrtmax() -> ::std::os::raw::c_int; +} diff --git a/utshell-0.5.0/src/builtins/source.rs b/utshell-0.5.0/src/builtins/source.rs new file mode 100644 index 00000000..47f7db31 --- /dev/null +++ b/utshell-0.5.0/src/builtins/source.rs @@ -0,0 +1,185 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::common::{ + builtin_usage, dollar_vars_changed, no_options, remember_args, set_dollar_vars_unchanged, + sh_restricted, +}; +use crate::builtins::evalfile::source_file; +use crate::findcmd::find_path_file; +use crate::general::{absolute_pathname, printable_filename}; +use crate::sig::jump_to_top_level; +use crate::src_common::*; +use crate::subst::invalidate_cached_quoted_dollar_at; +use crate::trap::{ + maybe_set_debug_trap, restore_default_signal, signal_is_ignored, signal_is_trapped, +}; +use crate::unwind_prot::{add_unwind_protect, begin_unwind_frame, run_unwind_frame}; +use crate::variables::{ + dispose_saved_dollar_vars, init_bash_argv, pop_args, pop_dollar_vars, push_args, + push_dollar_vars, +}; +use crate::version::shell_compatibility_level; + +pub union Functions { + f_xfree: fn(str1: *mut c_void), + f_maybe_pop_dollar_vars: fn(), + f_maybe_set_debug_trap: fn(*mut libc::c_char), +} + +#[no_mangle] +pub static mut source_uses_path: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut source_searches_cwd: libc::c_int = 1 as libc::c_int; + +#[no_mangle] +pub fn maybe_pop_dollar_vars() { + unsafe { + if variable_context == 0 && (dollar_vars_changed() & ARGS_SETBLTIN!()) != 0 { + dispose_saved_dollar_vars(); + } else { + pop_dollar_vars(); + } + if debugging_mode != 0 { + pop_args(); /* restore BASH_ARGC and BASH_ARGV */ + } + + set_dollar_vars_unchanged(); + invalidate_cached_quoted_dollar_at(); /* just invalidate to be safe */ + } +} + +fn TRAP_STRING(s: i32) -> *mut libc::c_char { + unsafe { + if signal_is_trapped(s) != 0 && signal_is_ignored(s) == 0 { + return trap_list[s as usize]; + } else { + return std::ptr::null_mut(); + } + } +} + +unsafe fn DEBUG_TRAP() -> i32 { + return libc::SIGRTMAX() + 1; +} + +#[no_mangle] +pub fn source_builtin(list: *mut WordList) -> i32 { + unsafe { + let result: i32; + let mut filename: *mut libc::c_char; + let mut debug_trap: *mut libc::c_char; + let x: *mut libc::c_char; + + if no_options(list) != 0 { + return EX_USAGE; + } + + let llist: *mut WordList = loptend.clone(); + + if list == std::ptr::null_mut() { + builtin_error( + b"filename argument required\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + builtin_usage(); + return EX_USAGE; + } + + if restricted != 0 + && libc::strchr((*(*llist).word).word, '/' as libc::c_int) != std::ptr::null_mut() + { + sh_restricted((*(*llist).word).word); + return EXECUTION_FAILURE!(); + } + + filename = std::ptr::null_mut(); + /* XXX -- should this be absolute_pathname? */ + if posixly_correct != 0 + && libc::strchr((*(*llist).word).word, '/' as libc::c_int) != std::ptr::null_mut() + { + filename = savestring!((*(*llist).word).word); + } else if absolute_pathname((*(*llist).word).word) != 0 { + filename = savestring!((*(*llist).word).word); + } else if source_uses_path != 0 { + filename = find_path_file((*(*llist).word).word); + } + + if filename == std::ptr::null_mut() { + if source_searches_cwd == 0 { + x = printable_filename((*(*llist).word).word, 0); + builtin_error(CString::new("%s: file not found").unwrap().as_ptr(), x); + if x != (*(*llist).word).word { + libc::free(x as *mut c_void); + } + + if posixly_correct != 0 && interactive_shell == 0 && executing_command_builtin == 0 + { + last_command_exit_value = EXECUTION_FAILURE!(); + jump_to_top_level(EXITPROG!()); + } + return EXECUTION_FAILURE!(); + } else { + filename = savestring!((*(*llist).word).word); + } + } + + begin_unwind_frame(b"source\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + + add_unwind_protect( + std::mem::transmute::>(free), + filename, + ); + + if (*list).next != std::ptr::null_mut() { + push_dollar_vars(); + + add_unwind_protect( + std::mem::transmute::>(maybe_pop_dollar_vars), + std::ptr::null_mut(), + ); + if debugging_mode != 0 || shell_compatibility_level <= 44 { + init_bash_argv(); /* Initialize BASH_ARGV and BASH_ARGC */ + } + + remember_args((*list).next, 1); + if debugging_mode != 0 { + push_args((*list).next); /* Update BASH_ARGV and BASH_ARGC */ + } + } + set_dollar_vars_unchanged(); + + /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded) + is set. XXX - should sourced files inherit the RETURN trap? Functions + don't. */ + debug_trap = TRAP_STRING(DEBUG_TRAP()); + if debug_trap != std::ptr::null_mut() && function_trace_mode == 0 { + debug_trap = savestring!(debug_trap); + + add_unwind_protect( + std::mem::transmute::>(free), + debug_trap, + ); + + add_unwind_protect( + std::mem::transmute::>( + maybe_set_debug_trap, + ), + debug_trap, + ); + + restore_default_signal(DEBUG_TRAP()); + } + + result = source_file( + filename, + (list != std::ptr::null_mut() && (*list).next != std::ptr::null_mut()) as i32, + ); + + run_unwind_frame(b"source\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + + return result; + } +} diff --git a/utshell-0.5.0/src/builtins/suspend.rs b/utshell-0.5.0/src/builtins/suspend.rs new file mode 100644 index 00000000..1f6c7249 --- /dev/null +++ b/utshell-0.5.0/src/builtins/suspend.rs @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, no_args, sh_nojobs}; +use crate::sig::set_signal_handler; +use crate::src_common::*; + +#[no_mangle] +pub fn suspend_builtin(mut list: *mut WordList) -> i32 { + let mut opt: libc::c_int; + let mut force: libc::c_int = 0; + + unsafe { + reset_internal_getopt(); + let opt_str = "f\0".as_ptr() as *mut libc::c_char; + opt = internal_getopt(list, opt_str); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'f' => force += 1, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + + opt = internal_getopt(list, opt_str); + } + list = loptend; + if job_control == 0 { + sh_nojobs("cannot suspend\0".as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE; + } + if force == 0 { + no_args(list); + if login_shell != 0 { + builtin_error("cannot suspend a login shell\0".as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE; + } + } + + old_cont = set_signal_handler( + libc::SIGCONT, + std::mem::transmute(suspend_continue as usize), + ); + killpg(shell_pgrp, libc::SIGSTOP); + } + return EXECUTION_SUCCESS; +} + +fn suspend_continue(sig: libc::c_int) { + unsafe { + set_signal_handler(libc::SIGCONT, old_cont); + } +} diff --git a/utshell-0.5.0/src/builtins/test.rs b/utshell-0.5.0/src/builtins/test.rs new file mode 100644 index 00000000..eaa48d91 --- /dev/null +++ b/utshell-0.5.0/src/builtins/test.rs @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::common::make_builtin_argv; +use crate::src_common::*; +use crate::test::test_command; + +#[no_mangle] +pub fn test_builtin(list: *mut WordList) -> i32 { + let result: libc::c_int; + let argc: libc::c_int = 0; + unsafe { + if list.is_null() { + if *this_command_name == b'[' as libc::c_char + && *((this_command_name as usize + 1) as *mut libc::c_char) == 0 + { + builtin_error("missing `]'\0".as_ptr() as *mut libc::c_char); + return EX_BADUSAGE; + } + return EXECUTION_FAILURE; + } + let argv = make_builtin_argv(list, std::mem::transmute(&argc)); + + result = test_command(argc, argv); + libc::free(argv as *mut c_void); + } + return result; +} diff --git a/utshell-0.5.0/src/builtins/times.rs b/utshell-0.5.0/src/builtins/times.rs new file mode 100644 index 00000000..7c86927b --- /dev/null +++ b/utshell-0.5.0/src/builtins/times.rs @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::common::{no_options, sh_chkwrite}; +use crate::src_common::*; + +extern "C" { + pub fn print_timeval(fp: *mut libc::FILE, tvp: *mut libc::timeval); +} + +#[no_mangle] +pub fn times_builtin(list: *mut WordList) -> i32 { + if no_options(list) != 0 { + return EX_USAGE; + } + unsafe { + let curr: libc::rusage = std::mem::zeroed(); + let kids: libc::rusage = std::mem::zeroed(); + libc::putchar(b'\n' as libc::c_int); + + libc::getrusage(libc::RUSAGE_SELF, std::mem::transmute(&curr)); + libc::getrusage(libc::RUSAGE_CHILDREN, std::mem::transmute(&kids)); + + print_timeval(stdout, std::mem::transmute(&curr.ru_utime)); + libc::putchar(b' ' as libc::c_int); + print_timeval(stdout, std::mem::transmute(&curr.ru_stime)); + libc::putchar(b'\n' as libc::c_int); + + print_timeval(stdout, std::mem::transmute(&kids.ru_utime)); + libc::putchar(b' ' as libc::c_int); + print_timeval(stdout, std::mem::transmute(&kids.ru_stime)); + libc::putchar(b'\n' as libc::c_int); + } + return sh_chkwrite(EXECUTION_SUCCESS); +} diff --git a/utshell-0.5.0/src/builtins/trap.rs b/utshell-0.5.0/src/builtins/trap.rs new file mode 100644 index 00000000..e7a2b3ce --- /dev/null +++ b/utshell-0.5.0/src/builtins/trap.rs @@ -0,0 +1,261 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use super::help::builtin_help; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, display_signal_list, sh_chkwrite, sh_invalidsig}; +use crate::builtins::evalfile::sourcelevel; +use crate::general::all_digits; +use crate::sig::{ + initialize_terminating_signals, set_signal_handler, sigint_sighandler, termsig_sighandler, +}; +use crate::src_common::*; +use crate::trap::{ + decode_signal, free_trap_strings, get_all_original_signals, ignore_signal, + restore_default_signal, set_signal, signal_is_hard_ignored, signal_name, +}; + +extern "C" { + pub static parse_and_execute_level: libc::c_int; +} + +#[no_mangle] +pub fn trap_builtin(mut list: *mut WordList) -> i32 { + let mut list_signal_names: libc::c_int = 0; + let mut display: libc::c_int = 0; + let mut result: libc::c_int = EXECUTION_SUCCESS; + + reset_internal_getopt(); + let opt_str = CString::new("lp").unwrap(); + let mut opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + while opt != -1 { + let opt_char: char = char::from(opt as u8); + match opt_char { + 'l' => list_signal_names += 1, + 'p' => display += 1, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, opt_str.as_ptr() as *mut libc::c_char); + } + unsafe { + list = loptend; + } + + opt = DSIG_NOCASE | DSIG_SIGPREFIX; + unsafe { + if list_signal_names != 0 { + return sh_chkwrite(display_signal_list(PT_NULL as *mut WordList, 1)); + } else if display != 0 || list.is_null() { + initialize_terminating_signals(); + get_all_original_signals(); + return sh_chkwrite(display_traps( + list, + (display != 0 && posixly_correct != 0) as libc::c_int, + )); + } else { + let mut operation = SET; + let first_arg = (*(*list).word).word; + let first_signal = !first_arg.is_null() + && *first_arg != 0 + && all_digits(first_arg) != 0 + && decode_signal(first_arg, opt) != NO_SIG; + if first_signal { + operation = REVERT; + } else if posixly_correct == 0 + && !first_arg.is_null() + && *first_arg != 0 + && (*first_arg != b'-' as libc::c_char + || *((first_arg as usize + 1) as *mut libc::c_char) != 0) + && decode_signal(first_arg, opt) != NO_SIG + && (*list).next.is_null() + { + operation = REVERT; + } else { + list = (*list).next; + if list.is_null() { + builtin_usage(); + return EX_USAGE; + } else if *first_arg == b'\0' as libc::c_char { + operation = IGNORE; + } else if *first_arg == b'-' as libc::c_char + && *((first_arg as usize + 1) as *mut libc::c_char) == 0 + { + operation = REVERT; + } + } + + if subshell_environment & SUBSHELL_RESETTRAP as i32 != 0 { + free_trap_strings(); + subshell_environment &= !(SUBSHELL_RESETTRAP as i32); + } + + let mut sig: libc::c_int; + while !list.is_null() { + sig = decode_signal((*(*list).word).word, opt); + if sig == NO_SIG { + sh_invalidsig((*(*list).word).word); + result = EXECUTION_FAILURE; + } else { + match operation { + SET => set_signal(sig, first_arg), + IGNORE => ignore_signal(sig), + REVERT => { + restore_default_signal(sig); + match sig { + libc::SIGINT => { + if interactive != 0 { + set_signal_handler( + libc::SIGINT, + //sigint_sighandler as *mut SigHandler, + Some(sigint_sighandler as fn(libc::c_int) -> ()), + ); + } else if interactive_shell != 0 + && (sourcelevel != 0 + || running_trap != 0 + || parse_and_execute_level != 0) + { + set_signal_handler( + libc::SIGINT, + //sigint_sighandler as *mut SigHandler, + Some(sigint_sighandler as fn(libc::c_int) -> ()), + ); + } else { + set_signal_handler( + libc::SIGINT, + //termsig_sighandler as *mut SigHandler, + Some(termsig_sighandler as fn(libc::c_int) -> ()), + ); + } + } + libc::SIGQUIT => { + set_signal_handler(libc::SIGQUIT, std::mem::transmute(1_usize)); + } + libc::SIGTERM | libc::SIGTTIN | libc::SIGTTOU | libc::SIGTSTP => { + if interactive != 0 { + set_signal_handler(sig, std::mem::transmute(1_usize)); + } + } + _ => (), + } + break; + } + _ => (), + } + } + + list = (*list).next; + } + } + } + return result; +} + +fn showtrap(i: libc::c_int, show_default: libc::c_int) { + let t: *mut libc::c_char; + let p = unsafe { trap_list[i as usize] }; + if (p == libc::SIG_DFL as *mut libc::c_char) && unsafe { signal_is_hard_ignored(i) } == 0 { + if show_default != 0 { + t = "-\0".as_ptr() as *mut libc::c_char; + } else { + return; + } + } else if unsafe { signal_is_hard_ignored(i) } != 0 { + t = PT_NULL as *mut libc::c_char; + } else { + t = if p == libc::SIG_IGN as *mut libc::c_char { + PT_NULL as *mut libc::c_char + } else { + unsafe { sh_single_quote(p) } + } + } + unsafe { + let sn = signal_name(i); + if libc::strncmp(sn, "SIGJUNK\0".as_ptr() as *const libc::c_char, 7) == 0 + || libc::strncmp(sn, "unknown\0".as_ptr() as *const libc::c_char, 7) == 0 + { + libc::printf( + "trap -- %s %d\n\0".as_ptr() as *const libc::c_char, + if t.is_null() { + "''\0".as_ptr() as *mut libc::c_char + } else { + t + }, + i, + ); + } else if posixly_correct != 0 { + if libc::strncmp(sn, "SIG\0".as_ptr() as *const libc::c_char, 3) == 0 { + libc::printf( + "trap -- %s %s\n\0".as_ptr() as *const libc::c_char, + if t.is_null() { + "''\0".as_ptr() as *mut libc::c_char + } else { + t + }, + (sn as usize + 3) as *mut libc::c_char, + ); + } else { + libc::printf( + "trap -- %s %s\n\0".as_ptr() as *const libc::c_char, + if t.is_null() { + "''\0".as_ptr() as *mut libc::c_char + } else { + t + }, + sn, + ); + } + } else { + libc::printf( + "trap -- %s %s\n\0".as_ptr() as *const libc::c_char, + if t.is_null() { + "''\0".as_ptr() as *mut libc::c_char + } else { + t + }, + sn, + ); + } + + if show_default == 0 { + if !t.is_null() { + libc::free(t as *mut c_void); + } + } + } +} + +fn display_traps(mut list: *mut WordList, show_all: libc::c_int) -> libc::c_int { + if list.is_null() { + for i in 0..BASH_NSIG { + showtrap(i as i32, show_all); + } + return EXECUTION_SUCCESS; + } + + let mut result = EXECUTION_SUCCESS; + let mut i: libc::c_int; + while !list.is_null() { + unsafe { + i = decode_signal((*(*list).word).word, DSIG_NOCASE | DSIG_SIGPREFIX); + if i == NO_SIG { + sh_invalidsig((*(*list).word).word); + result = EXECUTION_FAILURE; + } else { + showtrap(i, show_all); + } + + list = (*list).next; + } + } + + return result; +} diff --git a/utshell-0.5.0/src/builtins/type_1.rs b/utshell-0.5.0/src/builtins/type_1.rs new file mode 100644 index 00000000..b885f2d4 --- /dev/null +++ b/utshell-0.5.0/src/builtins/type_1.rs @@ -0,0 +1,443 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use fluent_bundle::FluentArgs; +use fluent_resmgr::resource_manager::ResourceManager; + +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_usage, find_shell_builtin, find_special_builtin, get_local_str, sh_chkwrite, + sh_notfound, +}; +use crate::builtins::help::builtin_help; +use crate::findcmd::{file_status, find_in_path, find_user_command, user_command_matches}; +use crate::general::{absolute_program, conf_standard_path}; +use crate::hashcmd::phash_search; +use crate::print_cmd::named_function_string; +use crate::src_common::*; +use crate::variables::find_function; +use crate::y_tab::find_reserved_word; + +fn function_cell(var: *mut SHELL_VAR) -> *mut COMMAND { + return (unsafe { *var }).value as *mut COMMAND; +} + +#[no_mangle] +pub fn type_builtin(mut list: *mut WordList) -> i32 { + //println!("rtype is run"); + let mut dflags: i32; + let mut any_failed: i32 = 0; + let _opt: i32 = 0; + let mut this: *mut WordList; + + dflags = CDESC_SHORTDESC!(); /* default */ + unsafe { + this = list; + while this != std::ptr::null_mut() && char::from((*(*(*this).word).word) as u8) == '-' { + let flag = (((*(*this).word).word) as usize + 1) as *mut libc::c_char; + let c_str_type = CString::new("type").unwrap(); + let c_str_type1 = CString::new("-type").unwrap(); + let c_str_path = CString::new("path").unwrap(); + let c_str_path1 = CString::new("-path").unwrap(); + let c_str_all = CString::new("all").unwrap(); + let c_str_all1 = CString::new("-all").unwrap(); + if STREQ!(flag, c_str_type.as_ptr() as *mut libc::c_char) + || STREQ!(flag, c_str_type1.as_ptr() as *mut libc::c_char) + { + *((*(*this).word).word).offset(1) = 't' as libc::c_char; + *((*(*this).word).word).offset(2) = '\0' as libc::c_char; + } else if STREQ!(flag, c_str_path.as_ptr() as *mut libc::c_char) + || STREQ!(flag, c_str_path1.as_ptr() as *mut libc::c_char) + { + *((*(*this).word).word).offset(1) = 'p' as libc::c_char; + *((*(*this).word).word).offset(2) = '\0' as libc::c_char; + } else if STREQ!(flag, c_str_all.as_ptr() as *mut libc::c_char) + || STREQ!(flag, c_str_all1.as_ptr() as *mut libc::c_char) + { + *((*(*this).word).word).offset(1) = 'a' as libc::c_char; + *((*(*this).word).word).offset(2) = '\0' as libc::c_char; + } + + if (*this).next != std::ptr::null_mut() { + this = (*this).next; + } else { + break; + } + } + } + reset_internal_getopt(); + + let c_str_afptP = CString::new("afptP").unwrap(); + let mut opt = internal_getopt(list, c_str_afptP.as_ptr() as *mut libc::c_char); + while opt != -1 { + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'a' => { + dflags = dflags | CDESC_ALL!(); + } + 'f' => { + dflags = dflags | CDESC_NOFUNCS!(); + } + 'p' => { + dflags = dflags | CDESC_PATH_ONLY!(); + dflags = dflags & !(CDESC_TYPE!() | CDESC_SHORTDESC!()); + } + 't' => { + dflags = dflags | CDESC_TYPE!(); + dflags = dflags & !(CDESC_PATH_ONLY!() | CDESC_SHORTDESC!()); + } + 'P' => { + dflags = dflags | CDESC_PATH_ONLY!() | CDESC_FORCE_PATH!(); + dflags = dflags & !(CDESC_TYPE!() | CDESC_SHORTDESC!()); + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE; + } + + builtin_usage(); + return EX_USAGE; + } + } + opt = internal_getopt(list, c_str_afptP.as_ptr() as *mut libc::c_char); + } + unsafe { + list = loptend; + } + while list != std::ptr::null_mut() { + let found: i32; + unsafe { + found = describe_command((*(*list).word).word, dflags); + } + if found == 0 && (dflags & (CDESC_PATH_ONLY!() | CDESC_TYPE!())) == 0 { + unsafe { + sh_notfound((*(*list).word).word); + } + } + any_failed = found + any_failed; + let _ = any_failed == 0; + // (any_failed += found) == 0; + unsafe { + list = (*list).next; + } + } + if any_failed == 0 { + EXECUTION_SUCCESS!(); + } else { + EXECUTION_FAILURE!(); + } + return sh_chkwrite(opt); +} + +pub fn describe_command(command: *mut libc::c_char, dflags: i32) -> i32 { + let mut found: i32 = 0; + let mut _i: i32; + let mut found_file: i32 = 0; + let mut f: i32; + let all: i32; + let mut full_path: *mut libc::c_char; + let mut x: *mut libc::c_char; + let mut pathlist: *mut libc::c_char; + let _func: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + // let mut alias : *mut alias_t; + + if (dflags & CDESC_ALL!()) != 0 { + all = 1; + } else { + all = 0; + } + + full_path = std::ptr::null_mut(); + + /* + // #if defined (ALIAS) + alias = find_alias(command); + if (((dflags & CDESC_FORCE_PATH!()) == 0) && expand_aliases!=0 && alias != std::ptr::null_mut()) + { + if (dflags & CDESC_TYPE!()) != 0{ + unsafe { + libc::puts("alias" as *const libc::c_char ); + } + } + else if (dflags & CDESC_SHORTDESC!()) != 0 { + unsafe{ + println!("{:?} is aliased to {:?}\n",CStr::from_ptr(command), CStr::from_ptr(alias.value)); + } + } + else if dflags & CDESC_REUSABLE!(){ + unsafe { + x = sh_single_quote((*alias).value); + println!("alias {:?} = {:?}",CStr::from_ptr(command),CStr::from_ptr(x)); + libc::free(x); + } + } + found = 1; + + if all == 0 { + return 1; + } + } + */ + /* Command is a shell reserved word? */ + if ((dflags & CDESC_FORCE_PATH!()) == 0) && find_reserved_word(command) >= 0 { + if dflags & CDESC_TYPE!() != 0 { + unsafe { + let c_str_keyword = CString::new("keyword").unwrap(); + libc::puts(c_str_keyword.as_ptr()); + } + } else if dflags & CDESC_SHORTDESC!() != 0 { + let name = String::from("iskeyword"); + translation_fn(&name, command, std::ptr::null_mut()); + } else if dflags & CDESC_REUSABLE!() != 0 { + unsafe { + println!("{}", CStr::from_ptr(command).to_str().unwrap()); + } + } + + found = 1; + if all == 0 { + return 1; + } + } + + /* Command is a function? */ + if (dflags & (CDESC_FORCE_PATH!() | CDESC_NOFUNCS!()) == 0) + && find_function(command) != std::ptr::null_mut() + { + if dflags & CDESC_TYPE!() != 0 { + unsafe { + let c_str_function = CString::new("function").unwrap(); + libc::puts(c_str_function.as_ptr()); + } + } else if dflags & CDESC_SHORTDESC!() != 0 { + let result: *mut libc::c_char; + unsafe { + let name = String::from("isfunction"); + translation_fn(&name, command, std::ptr::null_mut()); + result = named_function_string( + command, + function_cell(find_function(command)), + FUNC_MULTILINE!() | FUNC_EXTERNAL!(), + ); + println!("{}", CStr::from_ptr(result).to_str().unwrap()); + } + } else if dflags & CDESC_REUSABLE!() != 0 { + unsafe { + println!("{}", CStr::from_ptr(command).to_str().unwrap()); + } + } + + found = 1; + + if all == 0 { + return 1; + } + } + + /* Command is a builtin? */ + if ((dflags & CDESC_FORCE_PATH!()) == 0) +// && unsafe { find_shell_builtin(command) } != std::ptr::null_mut() + && find_shell_builtin(command).is_some() + { + if dflags & CDESC_TYPE!() != 0 { + unsafe { + let c_str_builtin = CString::new("builtin").unwrap(); + libc::puts(c_str_builtin.as_ptr()); + } + } else if dflags & CDESC_SHORTDESC!() != 0 { + if unsafe { posixly_correct } != 0 +// && unsafe { find_special_builtin(command) } != std::ptr::null_mut() + && find_special_builtin(command).is_some() + { + let name = String::from("special"); + translation_fn(&name, command, std::ptr::null_mut()); + } else { + let name = String::from("isbuiltin"); + translation_fn(&name, command, std::ptr::null_mut()); + } + } else if dflags & CDESC_REUSABLE!() != 0 { + unsafe { + println!("{}", CStr::from_ptr(command).to_str().unwrap()); + } + } + + found = 1; + if all == 0 { + return 1; + } + } + + /* Command is a disk file? */ + /* If the command name given is already an absolute command, just + check to see if it is executable. */ + if unsafe { absolute_program(command) } != 0 { + f = unsafe { file_status(command) }; + if f & FS_EXECABLE!() != 0 { + if dflags & CDESC_TYPE!() != 0 { + unsafe { + let c_str_file = CString::new("file").unwrap(); + libc::puts(c_str_file.as_ptr()); + } + } + } else if dflags & CDESC_SHORTDESC!() != 0 { + let name = String::from("is"); + translation_fn(&name, command, command); + } else if dflags & (CDESC_REUSABLE!() | CDESC_PATH_ONLY!()) != 0 { + unsafe { + println!("{}", CStr::from_ptr(command).to_str().unwrap()); + } + + /* There's no use looking in the hash table or in $PATH, + because they're not consulted when an absolute program + name is supplied. */ + return 1; + } + } + + /* If the user isn't doing "-a", then we might care about + whether the file is present in our hash table. */ + if all == 0 || (dflags & CDESC_FORCE_PATH!() != 0) { + full_path = phash_search(command); + if full_path != std::ptr::null_mut() { + if dflags & CDESC_TYPE!() != 0 { + unsafe { + let c_str_file = CString::new("file").unwrap(); + libc::puts(c_str_file.as_ptr()); + } + } else if dflags & CDESC_SHORTDESC!() != 0 { + let name = String::from("hashed"); + translation_fn(&name, command, full_path); + } else if (dflags & (CDESC_REUSABLE!() | CDESC_PATH_ONLY!())) != 0 { + unsafe { + println!("{}", CStr::from_ptr(full_path).to_str().unwrap()); + } + } + unsafe { + libc::free(full_path as *mut c_void); + } + return 1; + } + } + + /* Now search through $PATH. */ + #[warn(while_true)] + loop { + if dflags & CDESC_STDPATH!() != 0 { + /* command -p, all cannot be non-zero */ + unsafe { + pathlist = conf_standard_path(); + full_path = find_in_path(command, pathlist, FS_EXEC_PREFERRED!() | FS_NODIRS!()); + libc::free(pathlist as *mut c_void); + } + /* Will only go through this once, since all == 0 if STDPATH set */ + } else if all == 0 { + full_path = find_user_command(command); + } else { + unsafe { + full_path = user_command_matches(command, FS_EXEC_ONLY!(), found_file); + /* XXX - should that be FS_EXEC_PREFERRED? */ + } + } + if full_path == std::ptr::null_mut() { + // return 0; + break; + } + + /* If we found the command as itself by looking through $PATH, it + probably doesn't exist. Check whether or not the command is an + executable file. If it's not, don't report a match. This is + the default posix mode behavior */ + if (unsafe { STREQ!(full_path, command) } || unsafe { posixly_correct } != 0) { + unsafe { + f = file_status(full_path); + } + if f & FS_EXECABLE!() == 0 { + unsafe { + libc::free(full_path as *mut c_void); + full_path = std::ptr::null_mut(); + } + if all == 0 { + break; + } + } else if unsafe { ABSPATH!(full_path) } { + } + /* placeholder; don't need to do anything yet */ + else if dflags & (CDESC_REUSABLE!() | CDESC_PATH_ONLY!() | CDESC_SHORTDESC!()) != 0 { + if MP_DOCWD!() != 0 | (dflags & CDESC_ABSPATH!()) { + f = MP_RMDOT!(); + } else { + f = 0; + } + unsafe { + x = sh_makepath(std::ptr::null_mut(), full_path, f); + libc::free(full_path as *mut c_void); + } + + full_path = x; + } + } + /* If we require a full path and don't have one, make one */ + else if ((dflags & CDESC_ABSPATH!()) != 0) && unsafe { ABSPATH!(full_path) } == false { + unsafe { + x = sh_makepath(std::ptr::null_mut(), full_path, MP_DOCWD!() | MP_RMDOT!()); + libc::free(full_path as *mut c_void); + } + full_path = x; + } + found_file += 1; + found = 1; + if dflags & CDESC_TYPE!() != 0 { + unsafe { + let c_str_file = CString::new("file").unwrap(); + libc::puts(c_str_file.as_ptr()); + } + } else if dflags & CDESC_SHORTDESC!() != 0 { + let name = String::from("is"); + translation_fn(&name, command, full_path); + } else if dflags & (CDESC_REUSABLE!() | CDESC_PATH_ONLY!()) != 0 { + unsafe { + println!("{}", CStr::from_ptr(full_path).to_str().unwrap()); + } + } + + unsafe { + libc::free(full_path as *mut c_void); + } + full_path = std::ptr::null_mut(); + if all == 0 { + break; + } + } + found +} + +fn translation_fn(command: &String, args1: *mut libc::c_char, args2: *mut libc::c_char) { + let mgr = ResourceManager::new("/usr/share/utshell/resources/{locale}/{res_id}".into()); + let resources = vec!["message.ftl".into()]; + let mut args = FluentArgs::new(); + if args1 != std::ptr::null_mut() { + args.set("str1", unsafe { + format!("{}", CStr::from_ptr(args1).to_str().unwrap()) + }); + } + if args2 != std::ptr::null_mut() { + args.set("str2", unsafe { + format!("{}", CStr::from_ptr(args2).to_str().unwrap()) + }); + } + let bundle = mgr.get_bundle(get_local_str(), resources); + let value = bundle.get_message(command).unwrap(); + let pattern = value.value().expect("partern err"); + let mut errors = vec![]; + if args1 != std::ptr::null_mut() { + let msg1 = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!("{}", msg1.replace("\"", "")); + } else { + let msg1 = bundle.format_pattern(&pattern, None, &mut errors); + println!("{}", msg1.replace("\"", "")); + } +} diff --git a/utshell-0.5.0/src/builtins/ulimit.rs b/utshell-0.5.0/src/builtins/ulimit.rs new file mode 100644 index 00000000..d8ef2bf3 --- /dev/null +++ b/utshell-0.5.0/src/builtins/ulimit.rs @@ -0,0 +1,788 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, sh_chkwrite, sh_erange, sh_invalidnum}; +use crate::builtins::help::builtin_help; +use crate::general::{all_digits, string_to_rlimtype}; +use crate::src_common::*; +use std::ffi::{CStr, CString}; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct RESOURCE_LIMITS { + pub option: i32, /* The ulimit option for this limit. */ + pub parameter: i32, /* Parameter to pass to get_limit (). */ + pub block_factor: i32, /* Blocking factor for specific limit. */ + pub description: *const libc::c_char, /* Descriptive string to output. */ + pub units: *const libc::c_char, /* scale */ +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _cmd { + pub cmd: i32, + pub arg: *mut libc::c_char, +} +pub type ULCMD = _cmd; +pub type RLIMTYPE = i64; +pub type RESOURCE_LIMITS_T = RESOURCE_LIMITS; +static mut cmdlistsz: i32 = 0; +const limits: [RESOURCE_LIMITS_T; 18] = [ + { + RESOURCE_LIMITS { + option: 'R' as i32, + parameter: __RLIMIT_RTTIME as i32, + block_factor: 1 as i32, + description: b"real-time non-blocking time\0" as *const u8 as *const libc::c_char, + units: b"microseconds\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'c' as i32, + parameter: RLIMIT_CORE as i32, + block_factor: -(2 as i32), + description: b"core file size\0" as *const u8 as *const libc::c_char, + units: b"blocks\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'd' as i32, + parameter: RLIMIT_DATA as i32, + block_factor: 1024 as i32, + description: b"data seg size\0" as *const u8 as *const libc::c_char, + units: b"kbytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'e' as i32, + parameter: __RLIMIT_NICE as i32, + block_factor: 1 as i32, + description: b"scheduling priority\0" as *const u8 as *const libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'f' as i32, + parameter: RLIMIT_FSIZE as i32, + block_factor: -(2 as i32), + description: b"file size\0" as *const u8 as *const libc::c_char, + units: b"blocks\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'i' as i32, + parameter: __RLIMIT_SIGPENDING as i32, + block_factor: 1 as i32, + description: b"pending signals\0" as *const u8 as *const libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'l' as i32, + parameter: __RLIMIT_MEMLOCK as i32, + block_factor: 1024 as i32, + description: b"max locked memory\0" as *const u8 as *const libc::c_char, + units: b"kbytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'm' as i32, + parameter: __RLIMIT_RSS as i32, + block_factor: 1024 as i32, + description: b"max memory size\0" as *const u8 as *const libc::c_char, + units: b"kbytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'n' as i32, + parameter: RLIMIT_NOFILE as i32, + block_factor: 1 as i32, + description: b"open files\0" as *const u8 as *const libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'p' as i32, + parameter: 257 as i32, + block_factor: 512 as i32, + description: b"pipe size\0" as *const u8 as *const libc::c_char, + units: b"512 bytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'q' as i32, + parameter: __RLIMIT_MSGQUEUE as i32, + block_factor: 1 as i32, + description: b"POSIX message queues\0" as *const u8 as *const libc::c_char, + units: b"bytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'r' as i32, + parameter: __RLIMIT_RTPRIO as i32, + block_factor: 1 as i32, + description: b"real-time priority\0" as *const u8 as *const libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 's' as i32, + parameter: RLIMIT_STACK as i32, + block_factor: 1024 as i32, + description: b"stack size\0" as *const u8 as *const libc::c_char, + units: b"kbytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 't' as i32, + parameter: RLIMIT_CPU as i32, + block_factor: 1 as i32, + description: b"cpu time\0" as *const u8 as *const libc::c_char, + units: b"seconds\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'u' as i32, + parameter: __RLIMIT_NPROC as i32, + block_factor: 1 as i32, + description: b"max user processes\0" as *const u8 as *const libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'v' as i32, + parameter: RLIMIT_AS as i32, + block_factor: 1024 as i32, + description: b"virtual memory\0" as *const u8 as *const libc::c_char, + units: b"kbytes\0" as *const u8 as *const libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: 'x' as i32, + parameter: __RLIMIT_LOCKS as i32, + block_factor: 1 as i32, + description: b"file locks\0" as *const u8 as *const libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, + { + RESOURCE_LIMITS { + option: -1, + parameter: -1, + block_factor: -1, + description: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + units: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + } + }, +]; + +extern "C" { + fn getdtablesize() -> libc::c_int; + fn strerror(_: i32) -> *mut libc::c_char; + fn getrlimit(__resource: __rlimit_resource_t, __rlimits: *mut rlimit) -> i32; + fn setrlimit(__resource: __rlimit_resource_t, __rlimits: *const rlimit) -> i32; +} + +static mut optstring: [libc::c_char; 4 + 2 * NCMDS!() as usize] = [0; 4 + 2 * NCMDS!() as usize]; +static mut cmdlist: *mut ULCMD = 0 as *const ULCMD as *mut ULCMD; +static mut ncmd: i32 = 0; + +fn _findlim(opt: i32) -> i32 { + // let mut register : i32; + //let i : i32 = 0; + + for i in 0..17 { + if limits[i].option > 0 { + if limits[i].option == opt { + return i as i32; + } + } + } + -1 +} + +#[no_mangle] +pub fn ulimit_builtin(mut list: *mut WordList) -> i32 { + let mut s: *mut libc::c_char; + let c: i32; + let mut limind: i32; + let mut mode: i32 = 0; + let mut opt: i32 = 0; + let mut all_limits: i32 = 0; + unsafe { + if optstring[0] == 0 { + s = optstring.as_mut_ptr(); + s = s.offset(0); + *s = 'a' as libc::c_char; + s = s.offset(1); + *s = 'S' as libc::c_char; + s = s.offset(1); + *s = 'H' as libc::c_char; + s = s.offset(1); + c = 0; + for i in 0..17 { + if limits[i].option > 0 { + *s = limits[i].option as libc::c_char; + s = s.offset(1); + *s = ';' as libc::c_char; + s = s.offset(1); + } + } + *s = '\0' as libc::c_char; + } + } + + if unsafe { cmdlistsz } == 0 { + unsafe { cmdlistsz = 16 }; + unsafe { + cmdlist = libc::malloc( + (cmdlistsz as u64 as usize) + * (std::mem::size_of::() as libc::c_ulong) as usize, + ) as *mut ULCMD; + } + } + unsafe { ncmd = 0 }; + reset_internal_getopt(); + opt = internal_getopt(list, unsafe { optstring.as_ptr() } as *mut libc::c_char); + while opt != -1 { + let optu8: u8 = opt as u8; + let optChar: char = char::from(optu8); + match optChar { + 'a' => { + all_limits = all_limits + 1; + } + 'S' => { + mode = mode | LIMIT_SOFT!(); + } + 'H' => { + mode = mode | LIMIT_HARD!(); + } + '?' => { + builtin_usage(); + return EX_USAGE as libc::c_int; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE as libc::c_int; + } + if unsafe { ncmd } >= unsafe { cmdlistsz } { + unsafe { cmdlistsz = cmdlistsz * 2 }; + unsafe { + cmdlist = libc::realloc( + cmdlist as *mut libc::c_void, + ((cmdlistsz as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong)) + as usize, + //(cmdlistsz as u64) * std::mem::size_of::() as usize, + ) as *mut ULCMD + }; + } + unsafe { + (*cmdlist.offset(ncmd as isize)).cmd = opt; + let fresh5 = ncmd; + //ncmd = ncmd + 1; + let ref mut fresh6 = (*cmdlist.offset(fresh5 as isize)).arg; + *fresh6 = list_optarg; + // let mut cmm =&mut (*((cmdlist as usize + + // (ncmd as usize)*std::mem::size_of::())as *mut ULCMD) as ULCMD); + // cmm.cmd = opt; + // cmm.arg = list_optarg; + // (*((cmdlist as usize + (ncmd as usize)*std::mem::size_of::()) + // as *mut ULCMD) as ULCMD).cmd = opt ; + // (*((cmdlist as usize + (ncmd as usize) * std::mem::size_of::()) + // as *mut ULCMD) as ULCMD).arg = list_optarg; + ncmd = ncmd + 1; + } + } + } + opt = internal_getopt(list, unsafe { optstring.as_ptr() } as *mut libc::c_char); + } + + // as *mut ULCMD) as ULCMD).cmd ); + list = unsafe { loptend }; + + if all_limits != 0 { + if mode == 0 { + print_all_limits(LIMIT_SOFT!()); + } else { + print_all_limits(mode); + } + return sh_chkwrite(EXECUTION_SUCCESS!()); + } + + if unsafe { ncmd } == 0 { + unsafe { + (*cmdlist.offset(ncmd as isize)).cmd = 'f' as i32; + // let mut cmm = *((cmdlist as usize + (ncmd as usize )*std::mem::size_of::())as *mut ULCMD) as ULCMD; + // cmm.cmd = 'f' as i32; + } + /* `ulimit something' is same as `ulimit -f something' */ + if !list.is_null() { + unsafe { + (*cmdlist.offset(ncmd as isize)).arg = (*(*list).word).word; + // let mut cmm = *((cmdlist as usize + (ncmd as usize )*std::mem::size_of::())as *mut ULCMD) as ULCMD; + // cmm.arg = (*(*list).word).word; + ncmd = ncmd + 1; + } + } else { + unsafe { + (*cmdlist.offset(ncmd as isize)).arg = std::ptr::null_mut(); + // let mut cmm = *((cmdlist as usize + (ncmd as usize )*std::mem::size_of::())as *mut ULCMD) as ULCMD; + // cmm.arg = std::ptr::null_mut(); + ncmd = ncmd + 1; + } + } + if !list.is_null() { + list = (unsafe { *list }).next; + } + } + + for d in 0..unsafe { ncmd } { + //as *mut ULCMD) as ULCMD).cmd); + let cmm = unsafe { + *((cmdlist as usize + (d as usize) * std::mem::size_of::()) as *mut ULCMD) + } as ULCMD; + let _dmd = cmm.cmd; + + limind = unsafe { _findlim((*cmdlist.offset(d as isize)).cmd) }; + if limind == -1 { + unsafe { + builtin_error( + b"%s: bad command : %s\0" as *const u8 as *const libc::c_char, + (*cmdlist.offset(d as isize)).cmd, + strerror(errno!()) as *const libc::c_char, + ); + } + return EX_USAGE as libc::c_int; + } + } + unsafe { + for d in 0..ncmd { + let dmd = (*cmdlist.offset(d as isize)).cmd; + let drg = (*cmdlist.offset(d as isize)).arg; + // let dmd = (*((cmdlist as usize + (d as usize )*std::mem::size_of::()) + // as *mut ULCMD) as ULCMD).cmd; + // let drg = (*((cmdlist as usize + (d as usize )*std::mem::size_of::()) + // as *mut ULCMD) as ULCMD).arg; + if (ulimit_internal(dmd, drg, mode, d - 1)) == EXECUTION_FAILURE!() { + return EXECUTION_FAILURE!(); + } + } + } + return EXECUTION_SUCCESS!(); +} + +fn ulimit_internal(cmd: i32, cmdarg: *mut libc::c_char, mut mode: i32, multiple: i32) -> i32 { + let opt: i32; + let limind: i32; + let setting: i32; + let block_factor: i32; + let mut soft_limit: RLIMTYPE = 0; + let mut hard_limit: RLIMTYPE = 0; + let mut real_limit: RLIMTYPE = 0; + let limit: RLIMTYPE; + + if cmdarg != std::ptr::null_mut() { + setting = 1; + } else { + setting = 0; + } + limind = _findlim(cmd); + if mode == 0 { + if setting != 0 { + mode = LIMIT_HARD!() | LIMIT_SOFT!(); + } else { + mode = LIMIT_SOFT!(); + } + } + opt = get_limit(limind, &mut soft_limit, &mut hard_limit); + + if opt < 0 { + unsafe { + builtin_error( + b"%s: cannot get limit : %s\0" as *const u8 as *const libc::c_char, + limits[limind as usize].description, + strerror(errno!()) as *const libc::c_char, + ); + } + + return EXECUTION_FAILURE!(); + } + + if setting == 0 { + if (mode & LIMIT_SOFT!()) != 0 { + printone(limind, soft_limit, multiple); + } else { + printone(limind, hard_limit, multiple); + } + return EXECUTION_SUCCESS!(); + } + + let c_str_hard = CString::new("hard").unwrap(); + let c_str_soft = CString::new("soft").unwrap(); + let c_str_unlimited = CString::new("unlimited").unwrap(); + unsafe { + if STREQ!(cmdarg, c_str_hard.as_ptr() as *mut libc::c_char) { + real_limit = hard_limit; + } else if STREQ!(cmdarg, c_str_soft.as_ptr() as *mut libc::c_char) { + real_limit = soft_limit; + } else if STREQ!(cmdarg, c_str_unlimited.as_ptr() as *mut libc::c_char) { + real_limit = RLIM_INFINITY!(); + } else if all_digits(cmdarg) != 0 { + limit = string_to_rlimtype(cmdarg) as i64; + block_factor = BLOCKSIZE!(limits[limind as usize].block_factor); + real_limit = limit * block_factor as i64; + + if (real_limit / block_factor as i64) != limit { + let c_str_limit = CString::new("limit").unwrap(); + sh_erange(cmdarg, c_str_limit.as_ptr() as *mut libc::c_char); + return EXECUTION_FAILURE!(); + } + } else { + sh_invalidnum(cmdarg); + return EXECUTION_FAILURE!(); + } + } + if set_limit(limind, real_limit, mode) < 0 { + unsafe { + builtin_error( + b"%s: cannot modify limit : %s\0" as *const u8 as *const libc::c_char, + limits[limind as usize].description, + strerror(errno!()) as *const libc::c_char, + ) + }; + return EXECUTION_FAILURE!(); + } + return EXECUTION_SUCCESS!(); +} + +fn get_limit(ind: i32, softlim: *mut RLIMTYPE, hardlim: *mut RLIMTYPE) -> i32 { + let mut value: RLIMTYPE = 0; + let mut limit: rlimit = rlimit { + rlim_cur: 1, + rlim_max: 1, + }; + + if limits[ind as usize].parameter >= 256 { + match limits[ind as usize].parameter { + RLIMIT_FILESIZE!() => { + if filesize(((&mut value) as *mut i64) as *mut u64) < 0 { + return -1; + } + } + RLIMIT_PIPESIZE!() => { + if pipesize(((&mut value) as *mut i64) as *mut u64) < 0 { + return -1; + } + } + RLIMIT_OPENFILES!() => { + value = unsafe { getdtablesize() } as RLIMTYPE; + } + RLIMIT_VIRTMEM!() => { + return getmaxvm(softlim, hardlim as *mut libc::c_char); + } + RLIMIT_MAXUPROC!() => { + if getmaxuprc((value as usize) as *mut u64) < 0 { + return -1; + } + } + _ => unsafe { + errno!() = libc::EINVAL; + }, + } + unsafe { + *softlim = value; + *hardlim = value; + } + return 0; + } else { + unsafe { + let ii = getrlimit( + limits[ind as u32 as usize].parameter as __rlimit_resource_t, + &mut limit, + ); + if ii < 0 { + return -1; + } + } + unsafe { + // limit.rlim_max as i64); + *softlim = limit.rlim_cur as i64; + *hardlim = limit.rlim_max as i64; + } + return 0; + } +} + +fn set_limit(ind: i32, newlim: RLIMTYPE, mode: i32) -> i32 { + let mut limit: rlimit = rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + let mut val: RLIMTYPE = 0; + + if limits[ind as usize].parameter >= 256 { + match limits[ind as usize].parameter { + RLIMIT_FILESIZE!() => { + unsafe { + errno!() = libc::EINVAL; + } + return -1; + } + RLIMIT_OPENFILES!() + | RLIMIT_PIPESIZE!() + | RLIMIT_VIRTMEM!() + | RLIMIT_MAXUPROC!() + | _ => { + unsafe { + errno!() = libc::EINVAL; + } + return -1; + } + } + } else { + if unsafe { + getrlimit( + limits[ind as usize].parameter as __rlimit_resource_t, + &mut limit, + ) + } < 0 + { + return -1; + } + let b = unsafe { current_user.euid } != 0 + && newlim == RLIM_INFINITY!() + && (mode & LIMIT_HARD!()) == 0 + && limit.rlim_cur <= limit.rlim_max; + if b { + val = limit.rlim_max as i64; + } else { + val = newlim; + } + if mode & LIMIT_SOFT!() != 0 { + limit.rlim_cur = val as u64; + } + if mode & LIMIT_HARD!() != 0 { + limit.rlim_max = val as u64; + } + return unsafe { + setrlimit( + limits[ind as usize].parameter as __rlimit_resource_t, + &mut limit, + ) + }; + } +} + +fn getmaxvm(softlim: *mut RLIMTYPE, hardlim: *mut libc::c_char) -> i32 { + let mut datalim: rlimit = rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + let mut stacklim: rlimit = rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + + if unsafe { getrlimit(RLIMIT_DATA, &mut datalim) } < 0 { + return -1; + } + if unsafe { getrlimit(RLIMIT_STACK, &mut stacklim) } < 0 { + return -1; + } + unsafe { + *softlim = + (datalim.rlim_cur as i64 / 1024 as i64) + (stacklim.rlim_cur as i64 / 1024 as i64) + }; + unsafe { + *hardlim = ((datalim.rlim_max as i64) / 1024 as i64) as libc::c_char + + (stacklim.rlim_max as i64 / 1024 as i64) as libc::c_char + }; + return 0; +} + +fn filesize(_valuep: *mut rlim_t) -> i32 { + unsafe { + errno!() = libc::EINVAL; + } + return -1; +} + +fn pipesize(valuep: *mut rlim_t) -> i32 { + unsafe { *((valuep as usize) as *mut rlim_t) = PIPE_BUF!() as rlim_t }; + return 0; +} + +fn getmaxuprc(valuep: *mut rlim_t) -> i32 { + let mut maxchild: i64 = 0; + maxchild = unsafe { getmaxchild() }; + if maxchild < 0 as i32 as libc::c_long { + unsafe { + errno!() = libc::EINVAL; + } + return -1; + } else { + unsafe { + *valuep = maxchild as rlim_t; + } + return 0; + }; +} + +fn print_all_limits(mut mode: i32) { + let mut i: i32; + let mut softlim: RLIMTYPE = 0; + let mut hardlim: RLIMTYPE = 0; + + if mode == 0 { + mode = mode | LIMIT_SOFT!(); + } + i = 0; + while limits[i as usize].option > 0 { + if get_limit(i, &mut softlim, &mut hardlim) == 0 { + if mode & LIMIT_SOFT!() != 0 { + printone(i, softlim, 1); + } else { + printone(i, hardlim, 1); + } + } else if unsafe { errno!() != libc::EINVAL } { + unsafe { + builtin_error( + b"%s: cannot get limit : %s\0" as *const u8 as *const libc::c_char, + limits[i as usize].description, + strerror(errno!()) as *const libc::c_char, + ); + } + } + i = i + 1; + } +} + +fn printone(limind: i32, curlim: RLIMTYPE, pdesc: i32) { + let mut unitstr: [libc::c_char; 64] = [0; 64]; + let factor: i32; + + factor = BLOCKSIZE!(limits[limind as usize].block_factor); + if pdesc > 0 { + if !limits[limind as usize].units.is_null() { + unsafe { + libc::sprintf( + unitstr.as_mut_ptr(), + b"(%s, -%c) \0" as *const u8 as *const libc::c_char, + limits[limind as usize].units, + limits[limind as usize].option, + ); + } + } else { + unsafe { + libc::sprintf( + unitstr.as_mut_ptr(), + b"(-%c) \0" as *const u8 as *const libc::c_char, + limits[limind as usize].option, + ); + } + } + print!( + "{:<20} {:>20}", + unsafe { + CStr::from_ptr(limits[limind as usize].description) + .to_str() + .unwrap() + }, + unsafe { CStr::from_ptr(unitstr.as_mut_ptr()).to_str().unwrap() } + ); + } + if curlim == RLIM_INFINITY!() { + let c_str_unlimited = b"unlimited" as *const u8 as *const libc::c_char; + println!("{}", unsafe { + CStr::from_ptr(c_str_unlimited).to_str().unwrap() + }); + } else if curlim == RLIM_SAVED_MAX!() { + //println!("hard"); + let c_str_hard = b"hard" as *const u8 as *const libc::c_char; + println!("{}", unsafe { + CStr::from_ptr(c_str_hard).to_str().unwrap() + }); + } else if curlim == RLIM_SAVED_CUR!() { + //println!("soft"); + let c_str_soft = b"soft" as *const u8 as *const libc::c_char; + println!("{}", unsafe { + CStr::from_ptr(c_str_soft).to_str().unwrap() + }); + } else { + print_rlimtype((curlim / factor as i64) as u64, 1); + } +} + +/* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which + causes all limits to be set as high as possible depending on mode (like + csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits + were set successfully, and 1 if at least one limit could not be set. + + To raise all soft limits to their corresponding hard limits, use + ulimit -S -a unlimited + To attempt to raise all hard limits to infinity (superuser-only), use + ulimit -H -a unlimited + To attempt to raise all soft and hard limits to infinity, use + ulimit -a unlimited +*/ + +fn print_rlimtype(num: u64, nl: i32) { + if nl > 0 { + println!("{num}"); + } else { + print!("{num}"); + } +} + +fn set_all_limits(mut mode: i32, newlim: RLIMTYPE) -> i32 { + let mut i: i32; + let mut retval: i32 = 0; + + if newlim != RLIM_INFINITY!() { + unsafe { + errno!() = libc::EINVAL; + } + return -1; + } + + if mode == 0 { + mode = LIMIT_SOFT!() | LIMIT_HARD!(); + } + retval = 0; + i = 0; + + while limits[i as usize].option > 0 { + if set_limit(i, newlim, mode) < 0 { + unsafe { + builtin_error( + b"%s: cannot modify limit : %s\0" as *const u8 as *const libc::c_char, + limits[i as usize].description, + strerror(errno!()) as *const libc::c_char, + ); + } + retval = 1; + i = i + 1; + } + } + return retval; +} diff --git a/utshell-0.5.0/src/builtins/umask.rs b/utshell-0.5.0/src/builtins/umask.rs new file mode 100644 index 00000000..bf80e56d --- /dev/null +++ b/utshell-0.5.0/src/builtins/umask.rs @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{builtin_usage, read_octal, sh_chkwrite, sh_erange}; +use crate::builtins::help::builtin_help; +use std::ffi::CString; + +//C库 +extern "C" { + fn umask(__mask: __mode_t) -> __mode_t; +} + +//有å¯èƒ½é”™è¯¯ +fn member(c: *mut libc::c_char, s: *mut libc::c_char) -> bool { + if c != std::ptr::null_mut() { + let c = c as libc::c_int; + let ptr = unsafe { libc::strchr(s, c) }; + if ptr != std::ptr::null_mut() { + true + } else { + false + } + } else { + false + } +} + +// +#[no_mangle] +/* Set or display the mask used by the system when creating files. Flag +of -S means display the umask in a symbolic mode. */ + +pub fn umask_builtin(mut list: *mut WordList) -> i32 { + let mut print_symbolically: i32; + let mut opt: i32; + let umask_value: i32; + let mut pflag: i32; + let umask_arg: mode_t!(); + + print_symbolically = 0; + pflag = 0; + reset_internal_getopt(); + + let c_str_sp = CString::new("Sp").unwrap(); + opt = internal_getopt(list, c_str_sp.as_ptr() as *mut libc::c_char); + while opt != -1 { + let optu8 = opt as u8; + let opt_char = char::from(optu8); + match opt_char { + 'S' => { + print_symbolically = print_symbolically + 1; + } + 'p' => { + pflag = pflag + 1; + } + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE as libc::c_int; + } + builtin_usage(); + return EX_USAGE as libc::c_int; + } + } + + opt = internal_getopt(list, c_str_sp.as_ptr() as *mut libc::c_char); + } + + list = unsafe { loptend }; + if list != std::ptr::null_mut() { + if unsafe { DIGIT!(*(*(*list).word).word) } != false { + umask_value = read_octal((unsafe { *(*list).word }).word); + /* Note that other shells just let you set the umask to zero + by specifying a number out of range. This is a problem + with those shells. We don't change the umask if the input + is lousy. */ + if umask_value == -1 { + let c_str = CString::new("octal number").unwrap(); + let c_char_str: *mut libc::c_char = c_str.into_raw(); + sh_erange((unsafe { *(*list).word }).word, c_char_str); + return EXECUTION_FAILURE!(); + } + } else { + umask_value = symbolic_umask(list); + if umask_value == -1 { + return EXECUTION_FAILURE!(); + } + } + umask_arg = umask_value as u32; + unsafe { umask(umask_arg as __mode_t) }; + if print_symbolically != 0 { + print_symbolic_umask(umask_arg); + } + } else { + /* Display the UMASK for this user. */ + umask_arg = unsafe { umask(0o22 as libc::c_uint) }; + unsafe { umask(umask_arg as __mode_t) }; + if pflag != 0 { + if print_symbolically != 0 { + println!("umask -S"); + } else { + print!("umask ") + } + } + /* + if pflag != 0{ + if print_symbolically != 0{ + println!("umask \" -S\" "); + } + else{ + println!("umask \"\" ") + } + } + */ + if print_symbolically != 0 { + print_symbolic_umask(umask_arg); + } else { + println!("{:04o}", umask_arg); + } + } + return sh_chkwrite(EXECUTION_SUCCESS!()); +} + +#[no_mangle] +/* Print the umask in a symbolic form. In the output, a letter is +printed if the corresponding bit is clear in the umask. */ + +fn print_symbolic_umask(um: mode_t!()) { + /* u=rwx,g=rwx,o=rwx */ + let mut ubits = String::new(); + let mut gbits = String::new(); + let mut obits = String::new(); + + if um & S_IRUSR!() == 0 { + ubits.push('r'); + } + if um & S_IWUSR!() == 0 { + ubits.push('w'); + } + if um & S_IXUSR!() == 0 { + ubits.push('x'); + } + + if um & S_IRGRP!() == 0 { + gbits.push('r'); + } + if um & S_IWGRP!() == 0 { + gbits.push('w'); + } + if um & S_IXGRP!() == 0 { + gbits.push('x'); + } + + if um & S_IROTH!() == 0 { + obits.push('r'); + } + if um & S_IWOTH!() == 0 { + obits.push('w'); + } + if um & S_IXOTH!() == 0 { + obits.push('x'); + } + + println! {"u={},g={},o={}",ubits,gbits,obits}; +} + +#[no_mangle] +fn parse_symbolic_mode(mode: *mut libc::c_char, initial_bits: i32) -> i32 { + let mut who: i32; + let mut op: i32; + let mut perm: i32; + let mut bits: i32; + let mut c: i32; + let mut s: *mut libc::c_char; + + s = mode; + bits = initial_bits; + + loop { + who = 0; + op = 0; + perm = 0; + + /* Parse the `who' portion of the symbolic mode clause. */ + let c_str = CString::new("agou").unwrap(); + while member(s, c_str.as_ptr() as *mut libc::c_char) { + c = unsafe { *s } as libc::c_int; + s = (s as usize + 1) as *mut libc::c_char; + let optu8 = c as u8; + let opt_char = char::from(optu8); + match opt_char { + 'u' => { + who |= S_IRWXU!(); + continue; + } + 'g' => { + who |= S_IRWXG!(); + continue; + } + 'o' => { + who |= S_IRWXO!(); + continue; + } + 'a' => { + who |= S_IRWXU!() | S_IRWXG!() | S_IRWXO!(); + continue; + } + _ => {} + } + } + + /* The operation is now sitting in *s. */ + op = unsafe { *s } as libc::c_int; + // *s = *s + 1; + s = (s as usize + 1) as *mut libc::c_char; + let opu8 = op as u8; + let op_str = char::from(opu8); + match op_str { + '+' | '-' | '=' => {} + _ => { + println!("{}:invalid symbolic mode operator", op_str); + return -1; + } + } + + /* Parse out the `perm' section of the symbolic mode clause. */ + let c_rwx_str = CString::new("rwx").unwrap(); + while member(s, c_rwx_str.as_ptr() as *mut libc::c_char) { + c = s as libc::c_int; + //*s = *s + 1; + s = (s as usize + 1) as *mut libc::c_char; + let optu8 = c as u8; + let op_str = char::from(optu8); + + match op_str { + 'r' => perm |= S_IRUGO!(), + 'w' => perm |= S_IWUGO!(), + 'x' => perm |= S_IXUGO!(), + _ => {} + } + } + + /* Now perform the operation or return an error for a + bad permission string. */ + if unsafe { *s } != 0 || unsafe { *s } == ',' as libc::c_char { + if who != 0 { + perm &= who; + } + + match op_str { + '+' => bits |= perm, + '-' => bits &= !perm, + '=' => { + if who == 0 { + who = S_IRWXU!() | S_IRWXG!() | S_IRWXO!(); + bits &= !who; + bits |= perm; + } + } + /* No other values are possible. */ + _ => {} + } + if unsafe { *s } == '\0' as libc::c_char { + break; + } else { + //*s = *s + 1; + s = (s as usize + 1) as *mut libc::c_char; + } + } else { + println!("{}:invalid symbolic mode character", unsafe { *s } + as libc::c_char); + return -1; + } + } //loop + return bits; +} + +#[no_mangle] +/* Set the umask from a symbolic mode string similar to that accepted +by chmod. If the -S argument is given, then print the umask in a +symbolic form. */ + +fn symbolic_umask(list: *mut WordList) -> i32 { + let mut um: i32; + let bits: i32; + + /* Get the initial umask. Don't change it yet. */ + um = unsafe { umask(0o22 as libc::c_uint) } as i32; + unsafe { umask(um as __mode_t) }; + + /* All work is done with the complement of the umask -- it's + more intuitive and easier to deal with. It is complemented + again before being returned. */ + bits = parse_symbolic_mode((unsafe { *(*list).word }).word, !um & 0777); + if bits == -1 { + return -1; + } + + um = !bits & 0o777; + return um; +} diff --git a/utshell-0.5.0/src/builtins/wait.rs b/utshell-0.5.0/src/builtins/wait.rs new file mode 100644 index 00000000..eb9fbe15 --- /dev/null +++ b/utshell-0.5.0/src/builtins/wait.rs @@ -0,0 +1,310 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::arrayfunc::valid_array_reference; +use crate::builtins::bashgetopt::{internal_getopt, reset_internal_getopt}; +use crate::builtins::common::{ + builtin_unbind_variable, builtin_usage, get_job_spec, sh_badjob, sh_invalidid, +}; +use crate::builtins::help::builtin_help; +use crate::general::{legal_identifier, legal_number}; +use crate::jobs::{ + get_job_by_pid, wait_for_any_job, wait_for_background_pids, wait_for_job, wait_for_single_pid, + wait_sigint_cleanup, +}; +use crate::src_common::*; +use crate::trap::{first_pending_trap, next_pending_trap}; +use crate::variables::bind_var_to_int; +use nix::sys::signal::SigSet; + +include!("./signal.rs"); + +#[macro_export] +macro_rules! WAIT_RETURN { + ($s:expr) => {{ + wait_signal_received = 0; + wait_intr_flag = 0; + $s + }}; +} + +#[no_mangle] +pub fn wait_builtin(mut list: *mut WordList) -> i32 { + let mut status: i32; + let code: i32; + let mut opt: i32; + let mut nflag: i32; + let mut wflags: i32; + let mut vname: *mut libc::c_char; + let pidvar: *mut SHELL_VAR; + let mut pstat: procstat = procstat { pid: 0, status: 0 }; + + unsafe { + // USE_VAR(list); + nflag = 0; + wflags = 0; + vname = std::ptr::null_mut(); + pidvar = std::ptr::null_mut(); + + reset_internal_getopt(); + let c_fnp = std::ffi::CString::new("fnp:").unwrap(); + + loop { + opt = internal_getopt(list, c_fnp.as_ptr() as *mut libc::c_char); + if opt == -1 { + break; + } + let optu8 = opt as u8; + let opt_char = char::from(optu8); + + match opt_char { + 'n' => nflag = 1, + 'f' => wflags |= JWAIT_FORCE!(), + 'p' => vname = list_optarg, + _ => { + if opt == -99 { + builtin_help(); + return EX_USAGE as libc::c_int; + } + builtin_usage(); + return EX_USAGE as libc::c_int; + } + } + } + + list = loptend; + /* Sanity-check variable name if -p supplied. */ + if vname != std::ptr::null_mut() { + //这里有个æ¡ä»¶ç¼–译,确定是å¦éœ€è¦ + let arrayflags: i32; + if assoc_expand_once != 0 { + arrayflags = VA_NOEXPAND!() | VA_ONEWORD!(); + } else { + arrayflags = 0; + } + + if legal_identifier(vname) == 0 && valid_array_reference(vname, arrayflags) == 0 { + sh_invalidid(vname); + return WAIT_RETURN!(EXECUTION_FAILURE!()); + } + + if builtin_unbind_variable(vname) == -2 { + return WAIT_RETURN!(EXECUTION_FAILURE!()); + } + } + /* POSIX.2 says: When the shell is waiting (by means of the wait utility) + for asynchronous commands to complete, the reception of a signal for + which a trap has been set shall cause the wait utility to return + immediately with an exit status greater than 128, after which the trap + associated with the signal shall be taken. + + We handle SIGINT here; it's the only one that needs to be treated + specially (I think), since it's handled specially in {no,}jobs.c. */ + + wait_intr_flag = 1; + + code = __sigsetjmp(wait_intr_buf.as_mut_ptr(), 1); //*mut [__jmp_buf_tag; 1] + + if code != 0 { + last_command_exit_signal = wait_signal_received; + status = 128 + wait_signal_received; + wait_sigint_cleanup(); + return WAIT_RETURN!(status); + } + + opt = first_pending_trap(); + + //#if define (SIGCHLD) + + /* We special case SIGCHLD when not in posix mode because we don't break + out of the wait even when the signal is trapped; we run the trap after + the wait completes. See how it's handled in jobs.c:waitchld(). */ + + if opt == (SIGCHLD as i32) && posixly_correct == 0 { + opt = next_pending_trap(opt + 1); + } + if opt != -1 { + last_command_exit_signal = opt; + wait_signal_received = opt; + status = opt + 128; + return WAIT_RETURN!(status); + } + + //if define JB_CONTROL + /* We support jobs or pids. + wait [pid-or-job ...] */ + if nflag != 0 { + if list != std::ptr::null_mut() { + opt = set_waitlist(list); + if opt == 0 { + return WAIT_RETURN!(127); + } + wflags |= JWAIT_WAITING!(); + } + + status = wait_for_any_job(wflags, &mut pstat); + if vname != std::ptr::null_mut() && status >= 0 { + bind_var_to_int(vname, pstat.pid as intmax_t); + } + + if status < 0 { + status = 127; + } + if list != std::ptr::null_mut() { + unset_waitlist(); + } + return WAIT_RETURN!(status); + } + //endif + + /* But wait without any arguments means to wait for all of the shell's + currently active background processes. */ + if list == std::ptr::null_mut() { + wait_for_background_pids(&mut pstat); + if vname != std::ptr::null_mut() { + bind_var_to_int(vname, pstat.pid as intmax_t); + } + return WAIT_RETURN!(EXECUTION_SUCCESS!()); + // WAIT_RETURN!() + } + + status = EXECUTION_SUCCESS!(); + while list != std::ptr::null_mut() { + let pid: pid_t; + let w: *mut libc::c_char; + let mut pid_value: intmax_t = 0; + + w = (*(*list).word).word; + if DIGIT!(*w) { + if legal_number(w, &mut pid_value) != 0 && pid_value == (pid_value as pid_t) as i64 + { + pid = pid_value as pid_t; + status = wait_for_single_pid(pid, wflags | JWAIT_PEROOR!()); + pstat.pid = pid; + pstat.status = status as libc::c_short; + } else { + sh_badjob(w); + pstat.pid = NO_PID!(); + pstat.status = 127; + return WAIT_RETURN!(EXECUTION_FAILURE!()); + } + } + //if defined (JOB_CONTROL) + //else if w != std::ptr::null_mut() && (w as u8)as char == '%' { + else if *w != 0 && *w == '%' as libc::c_char { + /* Must be a job spec. Check it out. */ + let job: i32; + let mut set: SigSet = SigSet::empty(); + let mut oset: SigSet = SigSet::empty(); + + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + job = get_job_spec(list); + + if INVALID_JOB!(job) == true { + if job != DUP_JOB!() { + sh_badjob((*(*list).word).word); + } + UNBLOCK_CHILD_1!(Some(&mut oset)); + status = 127; /* As per Posix.2, section 4.70.2 */ + pstat.pid = NO_PID!(); + pstat.status = status as libc::c_short; + list = (*list).next; + continue; + } + + /* Job spec used. Wait for the last pid in the pipeline. */ + UNBLOCK_CHILD_1!(Some(&mut oset)); + status = wait_for_job(job, wflags, &mut pstat) + } else { + sh_badjob(w); + pstat.pid = NO_PID!(); + pstat.status = 127; + status = EXECUTION_FAILURE!(); + } + + /* Don't waste time with a longjmp. */ + if wait_signal_received != 0 { + last_command_exit_signal = wait_signal_received; + status = 128 + wait_signal_received; + wait_sigint_cleanup(); + return WAIT_RETURN!(status); + } + + list = (*list).next; + } + + return WAIT_RETURN!(status); + } //unsafe +} + +#[no_mangle] +fn set_waitlist(list: *mut WordList) -> i32 { + let mut set: SigSet = SigSet::empty(); + let mut oset: SigSet = SigSet::empty(); + let mut job: i32; + let mut _r: i32; + let mut njob: i32; + let mut pid: intmax_t = 0; + let mut l: *mut WordList; + + unsafe { + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + njob = 0; + + l = list; + while l != std::ptr::null_mut() { + //å¦‚ä½•æ¢æˆfor + job = NO_JOB!(); + + if l != std::ptr::null_mut() + && legal_number((*(*l).word).word, &mut pid) != 0 + && pid == (pid as pid_t) as i64 + { + job = get_job_by_pid(pid as pid_t, 0, std::ptr::null_mut()); + } else { + get_job_spec(l); + } + + if job == NO_JOB!() || jobs == std::ptr::null_mut() || INVALID_JOB!(job) { + sh_badjob((*(*l).word).word); + continue; + } + + /* We don't check yet to see if one of the desired jobs has already + terminated, but we could. We wait until wait_for_any_job(). This + has the advantage of validating all the arguments. */ + if (*get_job_by_jid!(job)).flags & J_WAITING!() == 0 { + njob = njob + 1; + (*get_job_by_jid!(job)).flags |= J_WAITING!(); + } + + l = (*l).next; + } + UNBLOCK_CHILD_1!(Some(&mut oset)); + + return njob; + } //unsafe +} + +/* Clean up after a call to wait -n jobs */ +#[no_mangle] +fn unset_waitlist() { + // let mut i:i32; + let mut set: SigSet = SigSet::empty(); + let mut oset: SigSet = SigSet::empty(); + + unsafe { + BLOCK_CHILD_1!(Some(&mut set), Some(&mut oset)); + for i in 0..js.j_jobslots { + if get_job_by_jid!(i) != std::ptr::null_mut() + && (*get_job_by_jid!(i)).flags & J_WAITING!() != 0 + { + (*get_job_by_jid!(i)).flags &= !J_WAITING!(); + } + } + + UNBLOCK_CHILD_1!(Some(&mut oset)); + } +} diff --git a/utshell-0.5.0/src/copycmd.rs b/utshell-0.5.0/src/copycmd.rs new file mode 100644 index 00000000..0263b726 --- /dev/null +++ b/utshell-0.5.0/src/copycmd.rs @@ -0,0 +1,394 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::list::list_reverse; +use crate::make_cmd::{make_bare_word, make_word_list}; +use crate::src_common::*; + +#[no_mangle] +pub fn copy_word(w: *mut WordDesc) -> *mut WordDesc { + unsafe { + let new_word: *mut WordDesc = make_bare_word((*w).word); + (*new_word).flags = (*w).flags; + + return new_word; + } +} + +#[no_mangle] +pub fn copy_word_list(mut list: *mut WordList) -> *mut WordList { + let mut new_list: *mut WordList; + let mut tl: *mut WordList = 0 as *mut WordList; + new_list = tl; + unsafe { + while !list.is_null() { + if new_list.is_null() { + tl = make_word_list(copy_word((*list).word), new_list); + new_list = tl; + } else { + (*tl).next = make_word_list( + copy_word((*list).word), + 0 as *mut libc::c_void as *mut WordList, + ); + tl = (*tl).next; + } + list = (*list).next; + } + } + return new_list; +} + +fn copy_case_clause(clause: *mut PATTERN_LIST) -> *mut PATTERN_LIST { + unsafe { + let new_clause: *mut PATTERN_LIST = + malloc(::core::mem::size_of::() as usize) as *mut PATTERN_LIST; + (*new_clause).patterns = copy_word_list((*clause).patterns); + (*new_clause).action = copy_command((*clause).action); + (*new_clause).flags = (*clause).flags; + + return new_clause; + } +} + +fn copy_case_clauses(mut clauses: *mut PATTERN_LIST) -> *mut PATTERN_LIST { + let mut new_list: *mut PATTERN_LIST = 0 as *mut PATTERN_LIST; + let mut new_clause: *mut PATTERN_LIST; + unsafe { + while !clauses.is_null() { + new_clause = copy_case_clause(clauses); + (*new_clause).next = new_list; + new_list = new_clause; + clauses = (*clauses).next; + } + return if !new_list.is_null() && !((*new_list).next).is_null() { + list_reverse(new_list as *mut GENERIC_LIST) as *mut PATTERN_LIST + } else { + new_list + }; + } +} + +#[no_mangle] +pub fn copy_redirect(redirect: *mut REDIRECT) -> *mut REDIRECT { + unsafe { + let new_redirect: *mut REDIRECT = + malloc(::core::mem::size_of::() as usize) as *mut REDIRECT; + *new_redirect = *redirect; + if (*redirect).rflags & 0x1 as libc::c_int != 0 { + (*new_redirect).redirector.filename = copy_word((*redirect).redirector.filename); + } + + match (*redirect).instruction as libc::c_uint { + r_reading_until | r_deblank_reading_until => { + (*new_redirect).here_doc_eof = if !((*redirect).here_doc_eof).is_null() { + savestring!((*redirect).here_doc_eof) as *mut libc::c_char + } else { + 0 as *mut libc::c_char + }; + (*new_redirect).redirectee.filename = copy_word((*redirect).redirectee.filename); + } + r_reading_string + | r_appending_to + | r_output_direction + | r_input_direction + | r_inputa_direction + | r_err_and_out + | r_append_err_and_out + | r_input_output + | r_output_force + | r_duplicating_input_word + | r_duplicating_output_word + | r_move_input_word + | r_move_output_word => { + (*new_redirect).redirectee.filename = copy_word((*redirect).redirectee.filename); + } + r_duplicating_input | r_duplicating_output | r_move_input | r_move_output + | r_close_this | _ => {} + } + return new_redirect; + } +} + +#[no_mangle] +pub fn copy_redirects(mut list: *mut REDIRECT) -> *mut REDIRECT { + let mut new_list: *mut REDIRECT; + let mut temp: *mut REDIRECT; + new_list = 0 as *mut libc::c_void as *mut REDIRECT; + unsafe { + while !list.is_null() { + temp = copy_redirect(list); + (*temp).next = new_list; + new_list = temp; + list = (*list).next; + } + return if !new_list.is_null() && !((*new_list).next).is_null() { + list_reverse(new_list as *mut GENERIC_LIST) as *mut REDIRECT + } else { + new_list + }; + } +} + +fn copy_for_command(com: *mut FOR_COM) -> *mut FOR_COM { + unsafe { + let new_for: *mut FOR_COM = + malloc(::core::mem::size_of::() as usize) as *mut FOR_COM; + (*new_for).flags = (*com).flags; + (*new_for).line = (*com).line; + (*new_for).name = copy_word((*com).name); + (*new_for).map_list = copy_word_list((*com).map_list); + (*new_for).action = copy_command((*com).action); + + return new_for; + } +} + +fn copy_arith_for_command(com: *mut ARITH_FOR_COM) -> *mut ARITH_FOR_COM { + unsafe { + let new_arith_for: *mut ARITH_FOR_COM = + malloc(::core::mem::size_of::() as usize) as *mut ARITH_FOR_COM; + (*new_arith_for).flags = (*com).flags; + (*new_arith_for).line = (*com).line; + (*new_arith_for).init = copy_word_list((*com).init); + (*new_arith_for).test = copy_word_list((*com).test); + (*new_arith_for).step = copy_word_list((*com).step); + (*new_arith_for).action = copy_command((*com).action); + return new_arith_for; + } +} + +fn copy_group_command(com: *mut GROUP_COM) -> *mut GROUP_COM { + unsafe { + let new_group: *mut GROUP_COM = + malloc(::core::mem::size_of::() as usize) as *mut GROUP_COM; + (*new_group).command = copy_command((*com).command); + + return new_group; + } +} + +fn copy_subshell_command(com: *mut SUBSHELL_COM) -> *mut SUBSHELL_COM { + unsafe { + let new_subshell: *mut SUBSHELL_COM = + malloc(::core::mem::size_of::() as usize) as *mut SUBSHELL_COM; + (*new_subshell).command = copy_command((*com).command); + (*new_subshell).flags = (*com).flags; + (*new_subshell).line = (*com).line; + + return new_subshell; + } +} +fn copy_coproc_command(com: *mut COPROC_COM) -> *mut COPROC_COM { + unsafe { + let new_coproc: *mut COPROC_COM = + malloc(::core::mem::size_of::() as usize) as *mut COPROC_COM; + (*new_coproc).name = savestring!((*com).name); + (*new_coproc).command = copy_command((*com).command); + (*new_coproc).flags = (*com).flags; + + return new_coproc; + } +} + +fn copy_case_command(com: *mut CASE_COM) -> *mut CASE_COM { + unsafe { + let new_case: *mut CASE_COM = + malloc(::core::mem::size_of::() as usize) as *mut CASE_COM; + (*new_case).flags = (*com).flags; + (*new_case).line = (*com).line; + (*new_case).word = copy_word((*com).word); + (*new_case).clauses = copy_case_clauses((*com).clauses); + + return new_case; + } +} + +fn copy_while_command(com: *mut WHILE_COM) -> *mut WHILE_COM { + unsafe { + let new_while: *mut WHILE_COM = + malloc(::core::mem::size_of::() as usize) as *mut WHILE_COM; + (*new_while).flags = (*com).flags; + (*new_while).test = copy_command((*com).test); + (*new_while).action = copy_command((*com).action); + + return new_while; + } +} + +fn copy_if_command(com: *mut IF_COM) -> *mut IF_COM { + unsafe { + let new_if: *mut IF_COM = malloc(::core::mem::size_of::() as usize) as *mut IF_COM; + (*new_if).flags = (*com).flags; + (*new_if).test = copy_command((*com).test); + (*new_if).true_case = copy_command((*com).true_case); + (*new_if).false_case = if !((*com).false_case).is_null() { + copy_command((*com).false_case) + } else { + (*com).false_case + }; + + return new_if; + } +} + +fn copy_arith_command(com: *mut ARITH_COM) -> *mut ARITH_COM { + unsafe { + let new_arith: *mut ARITH_COM = + libc::malloc(::core::mem::size_of::() as libc::c_ulong as usize) + as *mut ARITH_COM; + (*new_arith).flags = (*com).flags; + (*new_arith).exp = copy_word_list((*com).exp); + (*new_arith).line = (*com).line; + return new_arith; + } +} +fn copy_cond_command(com: *mut COND_COM) -> *mut COND_COM { + unsafe { + let new_cond: *mut COND_COM = + malloc(::core::mem::size_of::() as usize) as *mut COND_COM; + (*new_cond).flags = (*com).flags; + (*new_cond).line = (*com).line; + (*new_cond).type_0 = (*com).type_0; + (*new_cond).op = if !((*com).op).is_null() { + copy_word((*com).op) + } else { + (*com).op + }; + (*new_cond).left = if !((*com).left).is_null() { + copy_cond_command((*com).left) + } else { + 0 as *mut libc::c_void as *mut COND_COM + }; + (*new_cond).right = if !((*com).right).is_null() { + copy_cond_command((*com).right) + } else { + 0 as *mut libc::c_void as *mut COND_COM + }; + return new_cond; + } +} + +fn copy_simple_command(com: *mut SIMPLE_COM) -> *mut SIMPLE_COM { + unsafe { + let new_simple: *mut SIMPLE_COM = + malloc(::core::mem::size_of::() as usize) as *mut SIMPLE_COM; + (*new_simple).flags = (*com).flags; + (*new_simple).words = copy_word_list((*com).words); + (*new_simple).redirects = if !((*com).redirects).is_null() { + copy_redirects((*com).redirects) + } else { + 0 as *mut libc::c_void as *mut REDIRECT + }; + (*new_simple).line = (*com).line; + return new_simple; + } +} + +#[no_mangle] +pub fn copy_function_def_contents( + old: *mut FUNCTION_DEF, + new_def: *mut FUNCTION_DEF, +) -> *mut FUNCTION_DEF { + unsafe { + (*new_def).name = copy_word((*old).name); + (*new_def).command = if !((*old).command).is_null() { + copy_command((*old).command) + } else { + (*old).command + }; + (*new_def).flags = (*old).flags; + (*new_def).line = (*old).line; + (*new_def).source_file = if !((*old).source_file).is_null() { + savestring!((*old).source_file) + } else { + (*old).source_file + }; + return new_def; + } +} + +#[no_mangle] +pub fn copy_function_def(com: *mut FUNCTION_DEF) -> *mut FUNCTION_DEF { + unsafe { + let mut new_def: *mut FUNCTION_DEF = + malloc(::core::mem::size_of::() as usize) as *mut FUNCTION_DEF; + new_def = copy_function_def_contents(com, new_def); + return new_def; + } +} + +#[no_mangle] +pub fn copy_command(command: *mut COMMAND) -> *mut COMMAND { + unsafe { + let new_command: *mut COMMAND; + if command.is_null() { + return command; + } + new_command = malloc(::core::mem::size_of::() as usize) as *mut COMMAND; + libc::memcpy( + new_command as *mut libc::c_char as *mut libc::c_void, + command as *mut libc::c_char as *const libc::c_void, + ::core::mem::size_of::() as libc::c_ulong as libc::size_t, + ); + (*new_command).flags = (*command).flags; + (*new_command).line = (*command).line; + if !((*command).redirects).is_null() { + (*new_command).redirects = copy_redirects((*command).redirects); + } + match (*command).type_0 as libc::c_uint { + cm_for => { + (*new_command).value.For = copy_for_command((*command).value.For); + } + cm_arith_for => { + (*new_command).value.ArithFor = copy_arith_for_command((*command).value.ArithFor); + } + cm_select => { + (*new_command).value.Select = + copy_for_command((*command).value.Select as *mut FOR_COM) as *mut SELECT_COM; + } + cm_group => { + (*new_command).value.Group = copy_group_command((*command).value.Group); + } + cm_subshell => { + (*new_command).value.Subshell = copy_subshell_command((*command).value.Subshell); + } + cm_coproc => { + (*new_command).value.Coproc = copy_coproc_command((*command).value.Coproc); + } + cm_case => { + (*new_command).value.Case = copy_case_command((*command).value.Case); + } + cm_until | cm_while => { + (*new_command).value.While = copy_while_command((*command).value.While); + } + cm_if => { + (*new_command).value.If = copy_if_command((*command).value.If); + } + cm_arith => { + (*new_command).value.Arith = copy_arith_command((*command).value.Arith); + } + cm_cond => { + (*new_command).value.Cond = copy_cond_command((*command).value.Cond); + } + cm_simple => { + (*new_command).value.Simple = copy_simple_command((*command).value.Simple); + } + cm_connection => { + let new_connection: *mut CONNECTION = + malloc(::core::mem::size_of::() as usize) as *mut CONNECTION; + (*new_connection).connector = (*(*command).value.Connection).connector; + (*new_connection).first = copy_command((*(*command).value.Connection).first); + (*new_connection).second = copy_command((*(*command).value.Connection).second); + (*new_command).value.Connection = new_connection; + } + cm_function_def => { + (*new_command).value.Function_def = + copy_function_def((*command).value.Function_def); + } + _ => {} + } + return new_command; + } +} diff --git a/utshell-0.5.0/src/dispose_cmd.rs b/utshell-0.5.0/src/dispose_cmd.rs new file mode 100644 index 00000000..36f42f88 --- /dev/null +++ b/utshell-0.5.0/src/dispose_cmd.rs @@ -0,0 +1,234 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::error::command_error; +use crate::src_common::*; + +#[no_mangle] +pub fn dispose_command(command: *mut COMMAND) { + if command.is_null() { + return; + } + unsafe { + if !((*command).redirects).is_null() { + dispose_redirects((*command).redirects); + } + match (*command).type_0 { + command_type_cm_for | command_type_cm_select => { + let mut c: *mut FOR_COM = 0 as *mut FOR_COM; + if (*command).type_0 == command_type_cm_select { + c = (*command).value.Select as *mut FOR_COM; + } else { + c = (*command).value.For; + } + dispose_word((*c).name); + dispose_words((*c).map_list); + dispose_command((*c).action); + free(c as *mut libc::c_void); + } + command_type_cm_arith_for => { + let mut c_0: *mut ARITH_FOR_COM = 0 as *mut ARITH_FOR_COM; + c_0 = (*command).value.ArithFor; + dispose_words((*c_0).init); + dispose_words((*c_0).test); + dispose_words((*c_0).step); + dispose_command((*c_0).action); + free(c_0 as *mut libc::c_void); + } + command_type_cm_group => { + dispose_command((*(*command).value.Group).command); + free((*command).value.Group as *mut libc::c_void); + } + command_type_cm_subshell => { + dispose_command((*(*command).value.Subshell).command); + free((*command).value.Subshell as *mut libc::c_void); + } + command_type_cm_coproc => { + free((*(*command).value.Coproc).name as *mut libc::c_void); + dispose_command((*(*command).value.Coproc).command); + free((*command).value.Coproc as *mut libc::c_void); + } + command_type_cm_case => { + let mut c_1: *mut CASE_COM = 0 as *mut CASE_COM; + let mut t: *mut PATTERN_LIST = 0 as *mut PATTERN_LIST; + let mut p: *mut PATTERN_LIST = 0 as *mut PATTERN_LIST; + c_1 = (*command).value.Case; + dispose_word((*c_1).word); + p = (*c_1).clauses; + while !p.is_null() { + dispose_words((*p).patterns); + dispose_command((*p).action); + t = p; + p = (*p).next; + free(t as *mut libc::c_void); + } + free(c_1 as *mut libc::c_void); + } + command_type_cm_until | command_type_cm_while => { + let mut c_2: *mut WHILE_COM = 0 as *mut WHILE_COM; + c_2 = (*command).value.While; + dispose_command((*c_2).test); + dispose_command((*c_2).action); + free(c_2 as *mut libc::c_void); + } + command_type_cm_if => { + let mut c_3: *mut IF_COM = 0 as *mut IF_COM; + c_3 = (*command).value.If; + dispose_command((*c_3).test); + dispose_command((*c_3).true_case); + dispose_command((*c_3).false_case); + free(c_3 as *mut libc::c_void); + } + command_type_cm_simple => { + let mut c_4: *mut SIMPLE_COM = 0 as *mut SIMPLE_COM; + c_4 = (*command).value.Simple; + dispose_words((*c_4).words); + dispose_redirects((*c_4).redirects); + free(c_4 as *mut libc::c_void); + } + command_type_cm_connection => { + let mut c_5: *mut CONNECTION = 0 as *mut CONNECTION; + c_5 = (*command).value.Connection; + dispose_command((*c_5).first); + dispose_command((*c_5).second); + free(c_5 as *mut libc::c_void); + } + command_type_cm_arith => { + let mut c_6: *mut ARITH_COM = 0 as *mut ARITH_COM; + c_6 = (*command).value.Arith; + dispose_words((*c_6).exp); + free(c_6 as *mut libc::c_void); + } + command_type_cm_cond => { + let mut c_7: *mut COND_COM = 0 as *mut COND_COM; + c_7 = (*command).value.Cond; + dispose_cond_node(c_7); + } + command_type_cm_function_def => { + let mut c_8: *mut FUNCTION_DEF = 0 as *mut FUNCTION_DEF; + c_8 = (*command).value.Function_def; + dispose_function_def(c_8); + } + _ => { + command_error( + b"dispose_command\0" as *const u8 as *const libc::c_char, + CMDERR_BADTYPE as libc::c_int, + (*command).type_0 as libc::c_int, + 0, + ); + } + } + free(command as *mut libc::c_void); + } +} + +#[no_mangle] +pub fn dispose_cond_node(cond: *mut COND_COM) { + unsafe { + if !cond.is_null() { + if !((*cond).left).is_null() { + dispose_cond_node((*cond).left); + } + if !((*cond).right).is_null() { + dispose_cond_node((*cond).right); + } + if !((*cond).op).is_null() { + dispose_word((*cond).op); + } + free(cond as *mut libc::c_void); + } + } +} + +#[no_mangle] +pub fn dispose_function_def_contents(c: *mut FUNCTION_DEF) { + unsafe { + dispose_word((*c).name); + dispose_command((*c).command); + FREE!((*c).source_file); + } +} + +#[no_mangle] +pub fn dispose_function_def(c: *mut FUNCTION_DEF) { + dispose_function_def_contents(c); + unsafe { + free(c as *mut libc::c_void); + } +} + +#[no_mangle] +pub fn dispose_word(w: *mut WordDesc) { + unsafe { + FREE!((*w).word); + // ocache_free!(wdcache, WordDesc, w); + (*w).word = 0 as *mut libc::c_char; + free(w as *mut c_void); + } +} + +#[no_mangle] +pub fn dispose_word_desc(w: *mut WordDesc) { + unsafe { + (*w).word = 0 as *mut libc::c_char; + // ocache_free!(wdcache, WordDesc, w); + free(w as *mut c_void); + } +} + +#[no_mangle] +pub fn dispose_words(mut list: *mut WordList) { + let mut t: *mut WordList = 0 as *mut WordList; + while !list.is_null() { + unsafe { + t = list; + list = (*list).next; + dispose_word((*t).word); + + // ocache_free!(wlcache, WordList, t); + free(t as *mut c_void); + } + } +} + +#[no_mangle] +pub fn dispose_redirects(mut list: *mut REDIRECT) { + let mut t: *mut REDIRECT = 0 as *mut REDIRECT; + unsafe { + while !list.is_null() { + t = list; + list = (*list).next; + + if (*t).rflags & REDIR_VARASSIGN as libc::c_int != 0 { + dispose_word((*t).redirector.filename); + } + + match (*t).instruction { + r_instruction_r_reading_until | r_instruction_r_deblank_reading_until => { + free((*t).here_doc_eof as *mut libc::c_void); + dispose_word((*t).redirectee.filename); + } + r_instruction_r_reading_string + | r_instruction_r_output_direction + | r_instruction_r_input_direction + | r_instruction_r_inputa_direction + | r_instruction_r_appending_to + | r_instruction_r_err_and_out + | r_instruction_r_append_err_and_out + | r_instruction_r_input_output + | r_instruction_r_output_force + | r_instruction_r_duplicating_input_word + | r_instruction_r_duplicating_output_word + | r_instruction_r_move_input_word + | r_instruction_r_move_output_word => { + dispose_word((*t).redirectee.filename); + } + _ => {} + } + + free(t as *mut libc::c_void); + } + } +} diff --git a/utshell-0.5.0/src/error.rs b/utshell-0.5.0/src/error.rs new file mode 100644 index 00000000..c84f596e --- /dev/null +++ b/utshell-0.5.0/src/error.rs @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::array::array_reference; +use crate::execute_cmd::executing_line_number; +use crate::general::base_pathname; +use crate::src_common::*; +use crate::variables::find_variable; +use std::convert::TryInto; +#[no_mangle] +pub static mut gnu_error_format: libc::c_int = 0 as libc::c_int; + +//该文件中有多个å¯å˜é¤å‡½æ•°ï¼Œåœ¨variables/error.c中实现 +#[no_mangle] +pub fn get_name_for_error() -> *mut libc::c_char { + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut bash_source_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_source_a: *mut ARRAY = 0 as *mut ARRAY; + name = 0 as *mut libc::c_void as *mut libc::c_char; + unsafe { + if interactive_shell == 0 as libc::c_int { + bash_source_v = find_variable(b"BASH_SOURCE\0" as *const u8 as *const libc::c_char); + if !bash_source_v.is_null() + && (*bash_source_v).attributes & 0x4 as libc::c_int != 0 + && { + bash_source_a = (*bash_source_v).value as *mut ARRAY; + !bash_source_a.is_null() + } + { + name = array_reference(bash_source_a, 0 as libc::c_int as arrayind_t); + } + if name.is_null() || *name as libc::c_int == '\u{0}' as i32 { + name = *dollar_vars.as_mut_ptr().offset(0 as libc::c_int as isize); + } + } + if name.is_null() && !shell_name.is_null() && *shell_name as libc::c_int != 0 { + name = base_pathname(shell_name); + } + } + if name.is_null() { + name = b"bash\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + return name; +} + +#[no_mangle] +pub fn file_error(mut filename: *const libc::c_char) { + unsafe { + report_error( + b"%s: %s\0" as *const u8 as *const libc::c_char, + filename, + strerror(*__errno_location()), + ); + } +} + +static mut cmd_error_table: [*const libc::c_char; 5] = [ + b"unknown command error\0" as *const u8 as *const libc::c_char, + b"bad command type\0" as *const u8 as *const libc::c_char, + b"bad connector\0" as *const u8 as *const libc::c_char, + b"bad jump\0" as *const u8 as *const libc::c_char, + 0 as *const libc::c_char, +]; + +#[no_mangle] +pub fn command_error( + mut func: *const libc::c_char, + mut code: libc::c_int, + mut e: libc::c_int, + mut flags: libc::c_int, +) { + if code > CMDERR_LAST.try_into().unwrap() { + code = CMDERR_DEFAULT as i32; + } + unsafe { + programming_error( + b"%s: %s: %d\0" as *const u8 as *const libc::c_char, + func, + dcgettext( + 0 as *const libc::c_char, + cmd_error_table[code as usize], + 5 as libc::c_int, + ), + e, + ); + } +} + +#[no_mangle] +pub fn command_errstr(mut code: libc::c_int) -> *mut libc::c_char { + if code > CMDERR_LAST.try_into().unwrap() { + code = CMDERR_DEFAULT as i32; + } + unsafe { + return dcgettext( + 0 as *const libc::c_char, + cmd_error_table[code as usize], + 5 as libc::c_int, + ); + } +} + +#[no_mangle] +pub fn err_badarraysub(mut s: *const libc::c_char) { + unsafe { + report_error( + b"%s: %s\0" as *const u8 as *const libc::c_char, + s, + dcgettext( + 0 as *const libc::c_char, + bash_badsub_errmsg, + 5 as libc::c_int, + ), + ); + } +} + +#[no_mangle] +pub fn err_unboundvar(mut s: *const libc::c_char) { + unsafe { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: unbound variable\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + s, + ); + } +} + +#[no_mangle] +pub fn err_readonly(mut s: *const libc::c_char) { + unsafe { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: readonly variable\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + s, + ); + } +} diff --git a/utshell-0.5.0/src/eval.rs b/utshell-0.5.0/src/eval.rs new file mode 100644 index 00000000..0d22407d --- /dev/null +++ b/utshell-0.5.0/src/eval.rs @@ -0,0 +1,362 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::array::array_to_argv; +use crate::builtins::common::get_working_directory; +use crate::builtins::exit::bash_logout; +use crate::dispose_cmd::dispose_command; +use crate::error::command_error; +use crate::execute_cmd::execute_command; +use crate::print_cmd::make_command_string; +use crate::sig::restore_sigmask; +use crate::sig::{jump_to_top_level, sigint_sighandler}; +use crate::src_common::*; +use crate::subst::unlink_fifo_list; +use crate::trap::{run_pending_traps, signal_is_ignored, signal_is_trapped}; +use crate::variables::{dispose_used_env_vars, find_variable, get_string_value}; +use crate::y_tab::{ + bash_input, current_command_line_count, decode_prompt_string, execute_variable_command, + gather_here_documents, need_here_doc, parser_expanding_alias, parser_will_prompt, ps0_prompt, + reset_readahead_token, set_current_prompt_level, yyparse, EOF_Reached, +}; +#[no_mangle] +pub fn reader_loop() -> libc::c_int { + let mut flag: bool = false; + let mut our_indirection_level: libc::c_int = 0; + let mut current_command: *mut COMMAND = 0 as *mut COMMAND; + + current_command = 0 as *mut c_void as *mut COMMAND; + unsafe { + indirection_level += 1; + our_indirection_level = indirection_level; + + if just_one_command != 0 { + reset_readahead_token(); + } + while EOF_Reached == 0 { + let mut code: libc::c_int = 0; + + code = setjmp_nosigs!(top_level.as_mut_ptr()); + + unlink_fifo_list(); + + if interactive_shell != 0 + && signal_is_ignored(SIGINT as libc::c_int) == 0 + && signal_is_trapped(SIGINT as libc::c_int) == 0 + { + set_signal_handler( + SIGINT as libc::c_int, + sigint_sighandler as *mut SigHandler, //å¯èƒ½å­˜åœ¨é—®é¢˜ + ); + } + + loop { + if code != NOT_JUMPED as libc::c_int { + indirection_level = our_indirection_level; + + match code as u32 { + FORCE_EOF!() | ERREXIT!() | EXITPROG!() => { + current_command = 0 as *mut c_void as *mut COMMAND; + + if exit_immediately_on_error != 0 { + variable_context = 0; + } + EOF_Reached = EOF as i32; + flag = true; + break; + } + DISCARD!() => { + if last_command_exit_value == 0 { + set_exit_status(EXECUTION_FAILURE as libc::c_int); + } + if subshell_environment != 0 { + current_command = 0 as *mut c_void as *mut COMMAND; + EOF_Reached = EOF as i32; + flag = true; + break; + } + + if !current_command.is_null() { + dispose_command(current_command); + current_command = 0 as *mut c_void as *mut COMMAND; + } + restore_sigmask(); + } + _ => { + command_error( + b"reader_loop\0" as *const u8 as *const libc::c_char, + 3 as libc::c_int, + code, + 0 as libc::c_int, + ); + } + } + } + + executing = 0; + if !temporary_env.is_null() { + dispose_used_env_vars(); + } + + if read_command() == 0 { + if interactive_shell == 0 && (read_but_dont_execute != 0 && rpm_requires == 0) { + set_exit_status(EXECUTION_SUCCESS as i32); + dispose_command(global_command); + global_command = 0 as *mut COMMAND; + } else { + current_command = global_command; + if !current_command.is_null() { + global_command = 0 as *mut COMMAND; + + if interactive != 0 && !ps0_prompt.is_null() { + let mut ps0_string: *mut libc::c_char = 0 as *mut libc::c_char; + + ps0_string = decode_prompt_string(ps0_prompt); + if !ps0_string.is_null() && *ps0_string as libc::c_int != 0 { + fprintf( + stderr, + b"%s\0" as *const u8 as *const libc::c_char, + ps0_string, + ); + fflush(stderr); + } + + free(ps0_string as *mut c_void); + } + current_command_number += 1; + + executing = 1; + stdin_redir = 0; + + execute_command(current_command); + flag = true; + break; + } + } + } else { + if interactive == 0 { + EOF_Reached = EOF; + } + } + break; //跳出loop循环 + } + + if flag == true { + flag = false; + QUIT!(); + + if !current_command.is_null() { + dispose_command(current_command); + current_command = 0 as *mut COMMAND; + } + } + + if just_one_command != 0 { + EOF_Reached = EOF; + } + } + + indirection_level -= 1; + return last_command_exit_value; + } +} + +#[no_mangle] +pub fn pretty_print_loop() -> libc::c_int { + let mut current_command: *mut COMMAND = 0 as *mut COMMAND; + let mut command_to_print: *mut libc::c_char = 0 as *mut libc::c_char; + let mut code: libc::c_int = 0; + let mut global_posix_mode: libc::c_int = 0; + let mut last_was_newline: libc::c_int = 0; + unsafe { + global_posix_mode = posixly_correct; + last_was_newline = 0; + while EOF_Reached == 0 { + code = setjmp_nosigs!(top_level.as_mut_ptr()); + if code != 0 { + return EXECUTION_FAILURE as libc::c_int; + } + if read_command() == 0 { + current_command = global_command; + global_command = 0 as *mut COMMAND; + posixly_correct = 1; + if !current_command.is_null() && { + command_to_print = make_command_string(current_command); + !command_to_print.is_null() + } { + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + command_to_print, + ); + last_was_newline = 0; + } else if last_was_newline == 0 { + printf(b"\n\0" as *const u8 as *const libc::c_char); + last_was_newline = 1; + } + posixly_correct = global_posix_mode; + dispose_command(current_command); + } else { + return 1; + } + } + } + return 0; +} + +fn alrm_catcher(mut i: libc::c_int) { + let mut msg: *mut libc::c_char = 0 as *mut libc::c_char; + msg = b"\x07timed out waiting for input: auto-logout\n\0" as *const u8 as *mut libc::c_char; + unsafe { + write(1 as libc::c_int, msg as *const c_void, strlen(msg) as usize); + bash_logout(); + jump_to_top_level(EXITPROG as libc::c_int); + } +} +fn send_pwd_to_eterm() { + let mut pwd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut f: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + f = 0 as *mut libc::c_char; + pwd = get_string_value(b"PWD\0" as *const u8 as *const libc::c_char); + if pwd.is_null() { + pwd = get_working_directory( + b"eterm\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + f = pwd; + } + + fprintf( + stderr, + b"\x1A/%s\n\0" as *const u8 as *const libc::c_char, + pwd, + ); + free(f as *mut c_void); + } +} + +#[no_mangle] +pub fn execute_array_command(mut a: *mut ARRAY, mut v: *mut c_void) -> libc::c_int { + let mut tag: *mut libc::c_char = 0 as *mut libc::c_char; + let mut argv: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut argc: libc::c_int = 0; + let mut i: libc::c_int = 0; + unsafe { + tag = v as *mut libc::c_char; + argc = 0; + argv = array_to_argv(a, &mut argc); + i = 0; + while i < argc { + if !(*argv.offset(i as isize)).is_null() + && *(*argv.offset(i as isize)).offset(0) as libc::c_int != 0 + { + execute_variable_command(*argv.offset(i as isize), tag); + } + i += 1; + } + strvec_dispose(argv); + } + return 0; +} + +fn execute_prompt_command() { + let mut command_to_execute: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pcv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut pcmds: *mut ARRAY = 0 as *mut ARRAY; + + pcv = find_variable(b"PROMPT_COMMAND\0" as *const u8 as *const libc::c_char); + unsafe { + if pcv.is_null() || var_isset!(pcv) as libc::c_int == 0 || invisible_p!(pcv) != 0 { + return; + } + if array_p!(pcv) != 0 { + pcmds = array_cell!(pcv); + if !pcmds.is_null() && array_num_elements!(pcmds) > 0 { + execute_array_command( + pcmds, + b"PROMPT_COMMAND\0" as *const u8 as *const libc::c_char as *mut c_void, + ); + } + return; + } else { + if assoc_p!(pcv) != 0 { + return; + } + } + command_to_execute = value_cell!(pcv); + if !command_to_execute.is_null() && *command_to_execute as libc::c_int != 0 { + execute_variable_command( + command_to_execute, + b"PROMPT_COMMAND\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + } +} + +#[no_mangle] +pub fn parse_command() -> libc::c_int { + let mut r: libc::c_int = 0; + unsafe { + need_here_doc = 0; + run_pending_traps(); + + if interactive != 0 + && bash_input.type_0 as libc::c_uint != st_string + && parser_expanding_alias() == 0 + { + if no_line_editing != 0 + || bash_input.type_0 as libc::c_uint == st_stdin && parser_will_prompt() != 0 + { + execute_prompt_command(); + } + if running_under_emacs == 2 { + send_pwd_to_eterm(); + } + } + current_command_line_count = 0; + r = yyparse(); + if need_here_doc != 0 { + gather_here_documents(); + } + } + return r; +} +#[no_mangle] +pub fn read_command() -> libc::c_int { + let mut tmout_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut tmout_len: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut old_alrm: *mut SigHandler = 0 as *mut SigHandler; + + set_current_prompt_level(1); + unsafe { + global_command = 0 as *mut COMMAND; + tmout_var = 0 as *mut SHELL_VAR; + tmout_len = 0; + old_alrm = 0 as *mut SigHandler; + + if interactive != 0 { + tmout_var = find_variable(b"TMOUT\0" as *const u8 as *const libc::c_char); + + if !tmout_var.is_null() && !((*tmout_var).value).is_null() { + tmout_len = atoi((*tmout_var).value); + if tmout_len > 0 { + old_alrm = + set_signal_handler(SIGALRM as libc::c_int, alrm_catcher as *mut SigHandler); + alarm(tmout_len as libc::c_uint); + } + } + } + + QUIT!(); + + current_command_line_count = 0; + result = parse_command(); + if interactive != 0 && !tmout_var.is_null() && tmout_len > 0 { + alarm(0); + set_signal_handler(SIGALRM as libc::c_int, old_alrm); + } + } + return result; +} diff --git a/utshell-0.5.0/src/execute_cmd.rs b/utshell-0.5.0/src/execute_cmd.rs new file mode 100644 index 00000000..42805229 --- /dev/null +++ b/utshell-0.5.0/src/execute_cmd.rs @@ -0,0 +1,5571 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +use crate::alias::delete_all_aliases; +use crate::arrayfunc::{bind_array_variable, convert_var_to_array}; +use crate::builtins::command::command_builtin; +use crate::builtins::common::{ + builtin_address, builtin_address_internal, find_shell_builtin, find_special_builtin, + get_job_by_name, remember_args, sh_invalidid, +}; +use crate::builtins::eval::eval_builtin; +use crate::builtins::exec::exec_builtin; +use crate::builtins::exec_cmd::exec_cmd; +use crate::builtins::fc::fc_builtin; +use crate::builtins::jobs::jobs_builtin; +use crate::builtins::mapfile::mapfile_builtin; +use crate::builtins::read::read_builtin; +use crate::builtins::return_1::return_builtin; +use crate::builtins::set::{reset_shell_options, unset_builtin}; +use crate::builtins::shopt::reset_shopt_options; +use crate::builtins::source::source_builtin; +use crate::copycmd::{copy_command, copy_word_list}; +use crate::dispose_cmd::{dispose_command, dispose_redirects, dispose_words}; +use crate::error::{command_error, file_error}; +use crate::expr::evalexp; +use crate::findcmd::{executable_file, search_for_command}; +use crate::flags::{change_flag, reset_shell_flags}; +use crate::general::{ + check_binary_file, check_identifier, default_columns, file_isdir, legal_identifier, + legal_number, move_to_high_fd, printable_filename, sh_openpipe, +}; +use crate::input::fd_is_bash_input; +use crate::jobs::{ + append_process, freeze_jobs_list, init_job_stats, job_exit_status, kill_current_pipeline, + make_child, set_jobs_list_frozen, set_sigchld_handler, start_job, stop_pipeline, + terminate_current_pipeline, wait_for, wait_for_single_pid, without_job_control, BLOCK_CHILD, + UNBLOCK_CHILD, +}; +use crate::list::list_length; +use crate::local::locale_decpoint; +use crate::make_cmd::{make_word, make_word_list}; +use crate::pathexp::quote_string_for_globbing; +use crate::print_cmd::{ + print_arith_command, print_case_command_head, print_cond_command, print_for_command_head, + print_select_command_head, print_simple_command, xtrace_print_arith_cmd, + xtrace_print_case_command_head, xtrace_print_cond_term, xtrace_print_for_command_head, + xtrace_print_select_command_head, xtrace_print_word_list, +}; +use crate::readline::clearerr; +use crate::redir::{do_redirections, stdin_redirects}; +use crate::sig::{ + jump_to_top_level, reset_terminating_signals, set_signal_handler, throw_to_top_level, +}; +use crate::stringlib::{substring, xbcopy}; +use crate::subst::{ + clear_fifo_list, close_new_fifos, cond_expand_word, copy_fifo_list, dequote_escapes, + dequote_string, expand_arith_string, expand_string_unsplit_to_string, expand_word_leave_quoted, + expand_words, expand_words_no_vars, fifos_pending, num_fifos, setifs, string_list, + unlink_fifo_list, +}; +use crate::test::{binary_test, unary_test}; +use crate::trap::{ + clear_pending_traps, get_original_signal, maybe_set_debug_trap, maybe_set_error_trap, + maybe_set_return_trap, reset_signal_handlers, restore_default_signal, restore_original_signals, + run_debug_trap, run_error_trap, run_exit_trap, run_pending_traps, run_return_trap, + run_trap_cleanup, set_error_trap, set_sigint_handler, signal_in_progress, signal_is_ignored, + signal_is_trapped, +}; +use crate::unwind_prot::{ + add_unwind_protect, begin_unwind_frame, clear_unwind_protect_list, discard_unwind_frame, + run_unwind_frame, unwind_protect_mem, unwind_protect_tag_on_stack, +}; +use crate::variables::{ + adjust_shell_level, bind_variable, bind_variable_value, check_unbind_variable, + dispose_used_env_vars, find_function, find_function_def, find_variable, + find_variable_last_nameref, find_variable_nameref_for_create, get_string_value, init_bash_argv, + make_funcname_visible, make_new_array_variable, maybe_make_export_env, merge_temporary_env, + pop_args, pop_context, pop_scope, push_args, push_context, push_scope, + put_command_name_into_env, set_pipestatus_from_exit, stupidly_hack_special_variables, + unbind_variable_noref, +}; +use crate::version::shell_compatibility_level; +use crate::y_tab::{expand_aliases, line_number, reset_parser}; + +/* Functions to allocate and deallocate the structures used to pass +information from the shell to its children about file descriptors +to close. */ +#[no_mangle] +pub fn new_fd_bitmap(mut size: libc::c_int) -> *mut fd_bitmap { + let mut ret: *mut fd_bitmap = 0 as *mut fd_bitmap; + unsafe { + ret = malloc(size_of::() as usize) as *mut fd_bitmap; + + (*ret).size = size; + + if size != 0 { + (*ret).bitmap = malloc(size as usize) as *mut libc::c_char; + memset( + (*ret).bitmap as *mut libc::c_void, + '\u{0}' as i32, + size as usize, + ); + } else { + (*ret).bitmap = 0 as *mut libc::c_char; + } + } + return ret; +} + +#[no_mangle] +pub fn dispose_fd_bitmap(mut fdbp: *mut fd_bitmap) { + unsafe { + FREE!((*fdbp).bitmap); + free(fdbp as *mut c_void); + } +} + +#[no_mangle] +pub fn close_fd_bitmap(mut fdbp: *mut fd_bitmap) { + let mut i: libc::c_int = 0; + + if !fdbp.is_null() { + i = 0; + unsafe { + while i < (*fdbp).size { + if *((*fdbp).bitmap).offset(i as isize) != 0 { + close(i); + *((*fdbp).bitmap).offset(i as isize) = 0 as libc::c_char; + } + i += 1; + } + } + } +} + +#[no_mangle] +pub fn executing_line_number() -> libc::c_int { + unsafe { + if executing != 0 + && showing_function_line == 0 + && (variable_context == 0 || interactive_shell == 0) + && !currently_executing_command.is_null() + { + if (*currently_executing_command).type_0 as libc::c_uint + == command_type_cm_cond as libc::c_uint + { + return (*(*currently_executing_command).value.Cond).line; + } + if (*currently_executing_command).type_0 as libc::c_uint + == command_type_cm_arith as libc::c_uint + { + return (*(*currently_executing_command).value.Arith).line; + } + if (*currently_executing_command).type_0 as libc::c_uint + == command_type_cm_arith_for as libc::c_uint + { + return (*(*currently_executing_command).value.ArithFor).line; + } + return line_number; + } else { + return line_number; + }; + } +} + +#[no_mangle] +pub fn execute_command(mut command: *mut COMMAND) -> libc::c_int { + let mut bitmap: *mut fd_bitmap = 0 as *mut fd_bitmap; + let mut result: libc::c_int = 0; + unsafe { + current_fds_to_close = 0 as *mut fd_bitmap; + bitmap = new_fd_bitmap(FD_BITMAP_DEFAULT_SIZE!()); + begin_unwind_frame(b"execute-command\0" as *const u8 as *mut libc::c_char); + add_unwind_protect( + ::std::mem::transmute:: (), Option>(dispose_fd_bitmap), + bitmap as *mut libc::c_char, + ); + + //执行内部命令 + result = execute_command_internal(command, 0, NO_PIPE, NO_PIPE, bitmap); + + dispose_fd_bitmap(bitmap); + discard_unwind_frame(b"execute-command\0" as *const u8 as *mut libc::c_char); + + if variable_context == 0 && executing_list == 0 { + unlink_fifo_list(); + } + + QUIT!(); + } + return result; +} + +fn shell_control_structure(mut type_0: command_type) -> libc::c_int { + match type_0 as libc::c_uint { + command_type_cm_arith_for + | command_type_cm_select + | command_type_cm_arith + | command_type_cm_cond + | command_type_cm_case + | command_type_cm_while + | command_type_cm_until + | command_type_cm_if + | command_type_cm_for + | command_type_cm_group + | command_type_cm_function_def => return 1 as libc::c_int, + + _ => return 0 as libc::c_int, + }; +} + +fn cleanup_redirects(mut list: *mut REDIRECT) { + unsafe { + do_redirections(list, RX_ACTIVE as libc::c_int); + dispose_redirects(list); + } +} + +#[no_mangle] +pub fn undo_partial_redirects() { + unsafe { + if !redirection_undo_list.is_null() { + cleanup_redirects(redirection_undo_list); + redirection_undo_list = 0 as *mut REDIRECT; + } + } +} + +#[no_mangle] +pub fn dispose_exec_redirects() { + unsafe { + if !exec_redirection_undo_list.is_null() { + dispose_redirects(exec_redirection_undo_list); + exec_redirection_undo_list = 0 as *mut REDIRECT; + } + } +} + +#[no_mangle] +pub fn dispose_partial_redirects() { + unsafe { + if !redirection_undo_list.is_null() { + dispose_redirects(redirection_undo_list); + redirection_undo_list = 0 as *mut REDIRECT; + } + } +} + +fn restore_signal_mask(mut set: *mut sigset_t) -> libc::c_int { + unsafe { + return sigprocmask(SIG_SETMASK as libc::c_int, set, 0 as *mut sigset_t); + } +} + +#[no_mangle] +pub fn async_redirect_stdin() { + let mut fd: libc::c_int = 0; + unsafe { + fd = open( + b"/dev/null\0" as *const u8 as *const libc::c_char, + O_RDONLY as libc::c_int, + ); + if fd > 0 { + dup2(fd, 0); + close(fd); + } else if fd < 0 { + internal_error( + b"cannot redirect standard input from /dev/null: %s\0" as *const u8 + as *mut libc::c_char, + strerror(errno!()), + ); + } + } +} + +/* Execute the command passed in COMMAND, perhaps doing it asynchronously. +COMMAND is exactly what read_command () places into GLOBAL_COMMAND. +ASYNCHRONOUS, if non-zero, says to do this command in the background. +PIPE_IN and PIPE_OUT are file descriptors saying where input comes +from and where it goes. They can have the value of NO_PIPE, which means +I/O is stdin/stdout. +FDS_TO_CLOSE is a list of file descriptors to close once the child has +been forked. This list often contains the unusable sides of pipes, etc. + +EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible +return values. Executing a command with nothing in it returns +EXECUTION_SUCCESS. */ +#[no_mangle] +pub fn execute_command_internal( + mut command: *mut COMMAND, + mut asynchronous: libc::c_int, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + unsafe { + let mut exec_result: libc::c_int = 0; + let mut user_subshell: libc::c_int = 0; + let mut invert: libc::c_int = 0; + let mut ignore_return: libc::c_int = 0; + let mut was_error_trap: libc::c_int = 0; + let mut fork_flags: libc::c_int = 0; + let mut my_undo_list: *mut REDIRECT = 0 as *mut REDIRECT; + let mut exec_undo_list: *mut REDIRECT = 0 as *mut REDIRECT; + let mut tcmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut save_line_number: libc::c_int = 0; + let mut ofifo: libc::c_int = 0; + let mut nfifo: libc::c_int = 0; + let mut osize: libc::c_int = 0; + let mut saved_fifo: libc::c_int = 0; + let mut ofifo_list: *mut libc::c_void = 0 as *mut libc::c_void; + + if breaking != 0 || continuing != 0 { + return last_command_exit_value; + } + if command.is_null() || read_but_dont_execute != 0 && rpm_requires == 0 { + return EXECUTION_SUCCESS as i32; + } + if rpm_requires != 0 && (*command).type_0 == command_type_cm_function_def { + last_command_exit_value = execute_intern_function( + (*(*command).value.Function_def).name, + (*command).value.Function_def, + ); + return last_command_exit_value; + } + if read_but_dont_execute != 0 { + return EXECUTION_SUCCESS as libc::c_int; + } + + QUIT!(); + run_pending_traps(); + + currently_executing_command = command; + + invert = ((*command).flags & CMD_INVERT_RETURN as libc::c_int != 0) as libc::c_int; + + if exit_immediately_on_error != 0 && invert != 0 { + (*command).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + exec_result = EXECUTION_SUCCESS as libc::c_int; + + if (*command).type_0 == command_type_cm_subshell + && (*command).flags & CMD_NO_FORK as libc::c_int != 0 + { + return execute_in_subshell(command, asynchronous, pipe_in, pipe_out, fds_to_close); + } + if (*command).type_0 == command_type_cm_coproc { + last_command_exit_value = execute_coproc(command, pipe_in, pipe_out, fds_to_close); + return last_command_exit_value; + } + + user_subshell = ((*command).type_0 == command_type_cm_subshell + || (*command).flags & CMD_WANT_SUBSHELL as libc::c_int != 0) + as libc::c_int; + + if (*command).type_0 == command_type_cm_subshell + || (*command).flags + & (CMD_WANT_SUBSHELL as libc::c_int | CMD_FORCE_SUBSHELL as libc::c_int) + != 0 + || shell_control_structure((*command).type_0 as libc::c_uint) != 0 + && (pipe_out != NO_PIPE || pipe_in != NO_PIPE || asynchronous != 0) + { + let mut paren_pid: pid_t = 0; + let mut s: libc::c_int = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + + save_line_number = line_number; + if (*command).type_0 == command_type_cm_subshell { + line_number = (*(*command).value.Subshell).line; + line_number_for_err_trap = line_number; + } + + tcmd = make_command_string(command); + fork_flags = if asynchronous != 0 { + FORK_ASYNC as libc::c_int + } else { + 0 + }; + p = savestring!(tcmd); + paren_pid = make_child(p, fork_flags); + + if user_subshell != 0 + && signal_is_trapped(ERROR_TRAP as libc::c_int) != 0 + && signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 + && running_trap == 0 + { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command); + } + + if paren_pid == 0 { + FREE!(p); + s = (user_subshell == 0 + && (*command).type_0 == command_type_cm_group + && pipe_in == NO_PIPE + && pipe_out == NO_PIPE + && asynchronous != 0) as libc::c_int; + + s += (user_subshell == 0 + && (*command).type_0 == command_type_cm_group + && (pipe_in != NO_PIPE || pipe_out != NO_PIPE) + && asynchronous == 0) as libc::c_int; + + last_command_exit_value = + execute_in_subshell(command, asynchronous, pipe_in, pipe_out, fds_to_close); + if s != 0 { + subshell_exit(last_command_exit_value); + } else { + sh_exit(last_command_exit_value); + } + } else { + close_pipes(pipe_in, pipe_out); + + if variable_context == 0 { + unlink_fifo_list(); + } + + if pipe_out != NO_PIPE { + return EXECUTION_SUCCESS as libc::c_int; + } + + stop_pipeline(asynchronous, 0 as *mut COMMAND); + + line_number = save_line_number; + + if asynchronous == 0 { + was_error_trap = (signal_is_trapped(ERROR_TRAP as libc::c_int) != 0 + && signal_is_ignored(ERROR_TRAP as libc::c_int) == 0) + as libc::c_int; + invert = + ((*command).flags & CMD_INVERT_RETURN as libc::c_int != 0) as libc::c_int; + ignore_return = + ((*command).flags & CMD_IGNORE_RETURN as libc::c_int != 0) as libc::c_int; + + exec_result = wait_for(paren_pid, 0); + + if invert != 0 { + exec_result = if exec_result == EXECUTION_SUCCESS as libc::c_int { + EXECUTION_FAILURE as libc::c_int + } else { + EXECUTION_SUCCESS as libc::c_int + }; + } + + last_command_exit_value = exec_result; + if user_subshell != 0 + && was_error_trap != 0 + && ignore_return == 0 + && invert == 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + save_line_number = line_number; + line_number = line_number_for_err_trap; + run_error_trap(); + line_number = save_line_number; + } + + if user_subshell != 0 + && ignore_return == 0 + && invert == 0 + && exit_immediately_on_error != 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + run_pending_traps(); + jump_to_top_level(ERREXIT as libc::c_int); + } + return last_command_exit_value; + } else { + DESCRIBE_PID!(paren_pid); + + run_pending_traps(); + + last_command_exit_value = 0; + return EXECUTION_SUCCESS as libc::c_int; + } + } + } + if (*command).flags & CMD_TIME_PIPELINE as libc::c_int != 0 { + if asynchronous != 0 { + (*command).flags |= CMD_FORCE_SUBSHELL as libc::c_int; + exec_result = execute_command_internal(command, 1, pipe_in, pipe_out, fds_to_close); + } else { + exec_result = time_command(command, asynchronous, pipe_in, pipe_out, fds_to_close); + currently_executing_command = 0 as *mut COMMAND; + } + return exec_result; + } + if shell_control_structure((*command).type_0) != 0 && !((*command).redirects).is_null() { + stdin_redir = stdin_redirects((*command).redirects); + } + + if variable_context != 0 || executing_list != 0 { + ofifo = num_fifos(); + ofifo_list = copy_fifo_list(&mut osize as *mut libc::c_int); + begin_unwind_frame(b"internal_fifos\0" as *const u8 as *mut libc::c_char); + if !ofifo_list.is_null() { + add_unwind_protect( + ::std::mem::transmute::< + unsafe extern "C" fn(*mut c_void) -> (), + Option, + >(libc::free), + ofifo_list as *mut libc::c_char, + ); + } + saved_fifo = 1; + } else { + saved_fifo = 0; + } + + was_error_trap = (signal_is_trapped(ERROR_TRAP as libc::c_int) != 0 + && signal_is_ignored(ERROR_TRAP as libc::c_int) == 0) + as libc::c_int; + ignore_return = ((*command).flags & CMD_IGNORE_RETURN as libc::c_int != 0) as libc::c_int; + + if do_redirections( + (*command).redirects, + RX_ACTIVE as libc::c_int | RX_UNDOABLE as libc::c_int, + ) != 0 + { + undo_partial_redirects(); + dispose_exec_redirects(); + if saved_fifo != 0 { + free(ofifo_list as *mut c_void); + discard_unwind_frame(b"internal_fifos\0" as *const u8 as *mut libc::c_char); + } + + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + if ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE { + if was_error_trap != 0 { + save_line_number = line_number; + line_number = line_number_for_err_trap; + run_error_trap(); + line_number = save_line_number; + } + if exit_immediately_on_error != 0 { + run_pending_traps(); + jump_to_top_level(ERREXIT as libc::c_int); + } + } + return last_command_exit_value; + } + + my_undo_list = redirection_undo_list; + redirection_undo_list = 0 as *mut REDIRECT; + + exec_undo_list = exec_redirection_undo_list; + exec_redirection_undo_list = 0 as *mut REDIRECT; + + if !my_undo_list.is_null() || !exec_undo_list.is_null() { + begin_unwind_frame(b"loop_redirections\0" as *const u8 as *mut libc::c_char); + } + if !my_undo_list.is_null() { + add_unwind_protect( + std::mem::transmute:: (), Option>(cleanup_redirects), + my_undo_list as *mut libc::c_char, + ); + } + if !exec_undo_list.is_null() { + add_unwind_protect( + transmute:: (), Option>(dispose_redirects), + exec_undo_list as *mut libc::c_char, + ); + } + + QUIT!(); + + match (*command).type_0 { + command_type_cm_simple => { + save_line_number = line_number; + was_error_trap = (signal_is_trapped(ERROR_TRAP as libc::c_int) != 0 + && signal_is_ignored(ERROR_TRAP as libc::c_int) == 0) + as libc::c_int; + + if ignore_return != 0 && !((*command).value.Simple).is_null() { + (*(*command).value.Simple).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + if (*command).flags & CMD_STDIN_REDIR as libc::c_int != 0 { + (*(*command).value.Simple).flags |= CMD_STDIN_REDIR as libc::c_int; + } + + line_number = (*(*command).value.Simple).line; + line_number_for_err_trap = line_number; + exec_result = execute_simple_command( + (*command).value.Simple, + pipe_in, + pipe_out, + asynchronous, + fds_to_close, + ); + line_number = save_line_number; + + dispose_used_env_vars(); + + if already_making_children != 0 && pipe_out == NO_PIPE { + stop_pipeline(asynchronous, 0 as *mut COMMAND); + if asynchronous != 0 { + DESCRIBE_PID!(last_made_pid); + exec_result = EXECUTION_SUCCESS as libc::c_int; + invert = 0; + } else if last_made_pid != NO_PID!() { + exec_result = wait_for(last_made_pid, 0 as libc::c_int); + } + } + + if was_error_trap != 0 + && ignore_return == 0 + && invert == 0 + && pipe_in == NO_PIPE + && pipe_out == NO_PIPE + && (*(*command).value.Simple).flags & CMD_COMMAND_BUILTIN as libc::c_int == 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + last_command_exit_value = exec_result; + line_number = line_number_for_err_trap; + run_error_trap(); + line_number = save_line_number; + } + + if ignore_return == 0 + && invert == 0 + && (posixly_correct != 0 && interactive == 0 && special_builtin_failed != 0 + || exit_immediately_on_error != 0 + && pipe_in == NO_PIPE + && pipe_out == NO_PIPE + && exec_result != EXECUTION_SUCCESS as libc::c_int) + { + last_command_exit_value = exec_result; + run_pending_traps(); + if exit_immediately_on_error != 0 + && signal_is_trapped(0) != 0 + && unwind_protect_tag_on_stack( + b"saved-redirects\0" as *const u8 as *const libc::c_char, + ) != 0 + { + run_unwind_frame(b"saved-redirects\0" as *const u8 as *mut libc::c_char); + } + jump_to_top_level(4 as libc::c_int); + } + } + command_type_cm_for => { + if ignore_return != 0 { + (*(*command).value.For).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_for_command((*command).value.For); + } + command_type_cm_arith_for => { + if ignore_return != 0 { + (*(*command).value.ArithFor).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_arith_for_command((*command).value.ArithFor); + } + command_type_cm_select => { + if ignore_return != 0 { + (*(*command).value.Select).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_select_command((*command).value.Select); + } + command_type_cm_case => { + if ignore_return != 0 { + (*(*command).value.Case).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_case_command((*command).value.Case); + } + command_type_cm_while => { + if ignore_return != 0 { + (*(*command).value.While).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_while_command((*command).value.While); + } + command_type_cm_until => { + if ignore_return != 0 { + (*(*command).value.While).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_until_command((*command).value.While); + } + command_type_cm_if => { + if ignore_return != 0 { + (*(*command).value.If).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_if_command((*command).value.If); + } + command_type_cm_group => { + if asynchronous != 0 { + (*command).flags |= CMD_FORCE_SUBSHELL as libc::c_int; + exec_result = + execute_command_internal(command, 1, pipe_in, pipe_out, fds_to_close); + } else { + if ignore_return != 0 && !((*(*command).value.Group).command).is_null() { + (*(*(*command).value.Group).command).flags |= + CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_command_internal( + (*(*command).value.Group).command, + asynchronous, + pipe_in, + pipe_out, + fds_to_close, + ); + } + } + command_type_cm_connection => { + exec_result = + execute_connection(command, asynchronous, pipe_in, pipe_out, fds_to_close); + if asynchronous != 0 { + invert = 0; + } + } + command_type_cm_arith | command_type_cm_cond | command_type_cm_function_def => { + was_error_trap = (signal_is_trapped(ERROR_TRAP as libc::c_int) != 0 + && signal_is_ignored(ERROR_TRAP as libc::c_int) == 0) + as libc::c_int; + if ignore_return != 0 && (*command).type_0 == command_type_cm_arith { + (*(*command).value.Arith).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + if ignore_return != 0 && (*command).type_0 == command_type_cm_cond { + (*(*command).value.Cond).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + ::core::ptr::write_volatile(&mut save_line_number as *mut libc::c_int, line_number); + line_number_for_err_trap = ::core::ptr::read_volatile::( + &save_line_number as *const libc::c_int, + ); + + if (*command).type_0 == command_type_cm_arith { + exec_result = execute_arith_command((*command).value.Arith); + } else if (*command).type_0 == command_type_cm_cond { + exec_result = execute_cond_command((*command).value.Cond); + } else if (*command).type_0 == command_type_cm_function_def { + exec_result = execute_intern_function( + (*(*command).value.Function_def).name, + (*command).value.Function_def, + ); + } + line_number = save_line_number; + if was_error_trap != 0 + && ignore_return == 0 + && invert == 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + last_command_exit_value = exec_result; + save_line_number = line_number; + line_number = line_number_for_err_trap; + run_error_trap(); + line_number = save_line_number; + } + if ignore_return == 0 + && invert == 0 + && exit_immediately_on_error != 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + last_command_exit_value = exec_result; + run_pending_traps(); + jump_to_top_level(ERREXIT as libc::c_int); + } + } + _ => { + command_error( + b"execute_command\0" as *const u8 as *const libc::c_char, + CMDERR_BADTYPE as libc::c_int, + (*command).type_0 as libc::c_int, + 0, + ); + } + } + if !my_undo_list.is_null() { + cleanup_redirects(my_undo_list); + } + if !exec_undo_list.is_null() { + dispose_redirects(exec_undo_list); + } + if !my_undo_list.is_null() || !exec_undo_list.is_null() { + discard_unwind_frame(b"loop_redirections\0" as *const u8 as *mut libc::c_char); + } + + if saved_fifo != 0 { + nfifo = num_fifos(); + if nfifo > ofifo { + close_new_fifos(ofifo_list as *mut libc::c_void, osize); + } + free(ofifo_list as *mut c_void); + discard_unwind_frame(b"internal_fifos\0" as *const u8 as *mut libc::c_char); + } + + if invert != 0 { + exec_result = if exec_result == EXECUTION_SUCCESS as libc::c_int { + EXECUTION_FAILURE as libc::c_int + } else { + EXECUTION_SUCCESS as libc::c_int + }; + } + match (*command).type_0 { + command_type_cm_arith | command_type_cm_cond => { + set_pipestatus_from_exit(exec_result); + } + _ => {} + } + last_command_exit_value = exec_result; + run_pending_traps(); + currently_executing_command = 0 as *mut COMMAND; + return last_command_exit_value; + } +} + +static mut precs: [libc::c_int; 4] = [ + 0 as libc::c_int, + 100 as libc::c_int, + 10 as libc::c_int, + 1 as libc::c_int, +]; + +fn mkfmt( + mut buf: *mut libc::c_char, + mut prec: libc::c_int, + mut lng: libc::c_int, + mut sec: time_t, + mut sec_fraction: libc::c_int, +) -> libc::c_int { + let mut min: time_t = 0; + let mut abuf: [libc::c_char; 22] = [0; 22]; + let mut ind: libc::c_int = 0; + let mut aind: libc::c_int = 0; + unsafe { + ind = 0; + abuf[((size_of::<[libc::c_char; 22]>()) - 1)] = '\u{0}' as libc::c_char; + + if lng != 0 { + min = sec / 60 as libc::c_long; + sec %= 60 as libc::c_long; + aind = (size_of::<[libc::c_char; 22]>() - 2) as libc::c_int; + loop { + //有å¯èƒ½aindçš„å€¼ä¸æ­£ç¡® + abuf[aind as usize] = (min % 10 + '0' as libc::c_long) as libc::c_char; + aind = aind - 1; + min /= 10 as libc::c_long; + if !(min != 0) { + break; + } + } + aind += 1; + while abuf[aind as usize] != 0 { + //有å¯èƒ½ind,aindçš„å€¼ä¸æ­£ç¡® + *buf.offset(ind as isize) = abuf[aind as usize]; + aind = aind + 1; + ind = ind + 1; + } + *buf.offset(ind as isize) = 'm' as libc::c_char; + ind = ind + 1; + } + + aind = (size_of::<[libc::c_char; 22]>() - 2) as libc::c_int; + loop { + abuf[aind as usize] = ((sec % 10) + '0' as libc::c_long) as libc::c_char; + aind = aind - 1; + sec /= 10; + if !(sec != 0) { + break; + } + } + aind += 1; + while abuf[aind as usize] != 0 { + *buf.offset(ind as isize) = abuf[aind as usize]; + aind = aind + 1; + ind = ind + 1; + } + + if prec != 0 { + *buf.offset(ind as isize) = locale_decpoint() as libc::c_char; + ind = ind + 1; + aind = 1; + while aind <= prec { + *buf.offset(ind as isize) = + (sec_fraction / precs[aind as usize] + '0' as i32) as libc::c_char; + ind = ind + 1; + sec_fraction %= precs[aind as usize]; + aind += 1; + } + } + + if lng != 0 { + *buf.offset(ind as isize) = 's' as libc::c_char; + ind = ind + 1; + } + *buf.offset(ind as isize) = '\u{0}' as libc::c_char; + } + return ind; +} + +fn print_formatted_time( + mut fp: *mut FILE, + mut format: *mut libc::c_char, + mut rs: time_t, + mut rsf: libc::c_int, + mut us: time_t, + mut usf: libc::c_int, + mut ss: time_t, + mut ssf: libc::c_int, + mut cpu: libc::c_int, +) { + let mut prec: libc::c_int = 0; + let mut lng: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut str: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ts: [libc::c_char; 30] = [0; 30]; + let mut sum: time_t = 0; + let mut sum_frac: libc::c_int = 0; + let mut sindex: libc::c_int = 0; + let mut ssize: libc::c_int = 0; + unsafe { + len = strlen(format) as libc::c_int; + ssize = (len + 64) - (len % 64); + str = malloc(ssize as usize) as *mut libc::c_char; + sindex = 0; + + s = format; + while *s != 0 { + if *s as libc::c_int != '%' as i32 + || *s.offset(1 as isize) as libc::c_int == '\u{0}' as i32 + { + RESIZE_MALLOCED_BUFFER!(str, sindex, 1, ssize, 64); + *str.offset(sindex as isize) = *s; + sindex = sindex + 1; + } else if *s.offset(1 as isize) as libc::c_int == '%' as i32 { + s = s.offset(1); + RESIZE_MALLOCED_BUFFER!(str, sindex, 1, ssize, 64); + *str.offset(sindex as isize) = *s; + sindex = sindex + 1; + } else if *s.offset(1 as isize) as libc::c_int == 'P' as i32 { + s = s.offset(1); + sum = (cpu / 100) as time_t; + sum_frac = cpu % 100 * 10; + len = mkfmt(ts.as_mut_ptr(), 2, 0, sum, sum_frac); + RESIZE_MALLOCED_BUFFER!(str, sindex, len, ssize, 64); + strcpy(str.offset(sindex as isize), ts.as_mut_ptr()); + sindex += len; + } else { + prec = 3; + lng = 0; + s = s.offset(1); + if DIGIT!(*s) { + prec = *s as libc::c_int - '0' as i32; + s = s.offset(1); + if prec > 3 { + prec = 3; + } + } + if *s as libc::c_int == 'l' as i32 { + lng = 1; + s = s.offset(1); + } + if *s as libc::c_int == 'R' as i32 || *s as libc::c_int == 'E' as i32 { + len = mkfmt(ts.as_mut_ptr(), prec, lng, rs, rsf); + } else if *s as libc::c_int == 'U' as i32 { + len = mkfmt(ts.as_mut_ptr(), prec, lng, us, usf); + } else if *s as libc::c_int == 'S' as i32 { + len = mkfmt(ts.as_mut_ptr(), prec, lng, ss, ssf); + } else { + internal_error( + b"TIMEFORMAT: `%c': invalid format character\0" as *const u8 + as *mut libc::c_char, + *s as libc::c_int, + ); + free(str as *mut c_void); + return; + } + + RESIZE_MALLOCED_BUFFER!(str, sindex, len, ssize, 64); + strcpy(str.offset(sindex as isize), ts.as_mut_ptr()); + sindex += len; + } + s = s.offset(1); + } + *str.offset(sindex as isize) = '\u{0}' as libc::c_char; + fprintf(fp, b"%s\n\0" as *const u8 as *const libc::c_char, str); + fflush(fp); + free(str as *mut c_void); + } +} + +fn time_command( + mut command: *mut COMMAND, + mut asynchronous: libc::c_int, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + let mut rv: libc::c_int = 0; + let mut posix_time: libc::c_int = 0; + let mut old_flags: libc::c_int = 0; + let mut nullcmd: libc::c_int = 0; + let mut code: libc::c_int = 0; + let mut rs: time_t = 0; + let mut us: time_t = 0; + let mut ss: time_t = 0; + let mut rsf: libc::c_int = 0; + let mut usf: libc::c_int = 0; + let mut ssf: libc::c_int = 0; + let mut cpu: libc::c_int = 0; + let mut time_format: *mut libc::c_char = 0 as *mut libc::c_char; + let mut save_top_level: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, + }; 1]; + let mut real: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + let mut user: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + let mut sys: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + let mut before: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + let mut after: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + let mut dtz: crate::src_common::timezone = crate::src_common::timezone { + tz_minuteswest: 0, + tz_dsttime: 0, + }; + let mut selfb: crate::src_common::rusage = crate::src_common::rusage { + ru_utime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + ru_stime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + __bindgen_anon_1: rusage__bindgen_ty_1 { ru_maxrss: 0 }, + __bindgen_anon_2: rusage__bindgen_ty_2 { ru_ixrss: 0 }, + __bindgen_anon_3: rusage__bindgen_ty_3 { ru_idrss: 0 }, + __bindgen_anon_4: rusage__bindgen_ty_4 { ru_isrss: 0 }, + __bindgen_anon_5: rusage__bindgen_ty_5 { ru_minflt: 0 }, + __bindgen_anon_6: rusage__bindgen_ty_6 { ru_majflt: 0 }, + __bindgen_anon_7: rusage__bindgen_ty_7 { ru_nswap: 0 }, + __bindgen_anon_8: rusage__bindgen_ty_8 { ru_inblock: 0 }, + __bindgen_anon_9: rusage__bindgen_ty_9 { ru_oublock: 0 }, + __bindgen_anon_10: rusage__bindgen_ty_10 { ru_msgsnd: 0 }, + __bindgen_anon_11: rusage__bindgen_ty_11 { ru_msgrcv: 0 }, + __bindgen_anon_12: rusage__bindgen_ty_12 { ru_nsignals: 0 }, + __bindgen_anon_13: rusage__bindgen_ty_13 { ru_nvcsw: 0 }, + __bindgen_anon_14: rusage__bindgen_ty_14 { ru_nivcsw: 0 }, + }; + let mut selfa: crate::src_common::rusage = crate::src_common::rusage { + ru_utime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + ru_stime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + __bindgen_anon_1: rusage__bindgen_ty_1 { ru_maxrss: 0 }, + __bindgen_anon_2: rusage__bindgen_ty_2 { ru_ixrss: 0 }, + __bindgen_anon_3: rusage__bindgen_ty_3 { ru_idrss: 0 }, + __bindgen_anon_4: rusage__bindgen_ty_4 { ru_isrss: 0 }, + __bindgen_anon_5: rusage__bindgen_ty_5 { ru_minflt: 0 }, + __bindgen_anon_6: rusage__bindgen_ty_6 { ru_majflt: 0 }, + __bindgen_anon_7: rusage__bindgen_ty_7 { ru_nswap: 0 }, + __bindgen_anon_8: rusage__bindgen_ty_8 { ru_inblock: 0 }, + __bindgen_anon_9: rusage__bindgen_ty_9 { ru_oublock: 0 }, + __bindgen_anon_10: rusage__bindgen_ty_10 { ru_msgsnd: 0 }, + __bindgen_anon_11: rusage__bindgen_ty_11 { ru_msgrcv: 0 }, + __bindgen_anon_12: rusage__bindgen_ty_12 { ru_nsignals: 0 }, + __bindgen_anon_13: rusage__bindgen_ty_13 { ru_nvcsw: 0 }, + __bindgen_anon_14: rusage__bindgen_ty_14 { ru_nivcsw: 0 }, + }; + let mut kidsb: crate::src_common::rusage = crate::src_common::rusage { + ru_utime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + ru_stime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + __bindgen_anon_1: rusage__bindgen_ty_1 { ru_maxrss: 0 }, + __bindgen_anon_2: rusage__bindgen_ty_2 { ru_ixrss: 0 }, + __bindgen_anon_3: rusage__bindgen_ty_3 { ru_idrss: 0 }, + __bindgen_anon_4: rusage__bindgen_ty_4 { ru_isrss: 0 }, + __bindgen_anon_5: rusage__bindgen_ty_5 { ru_minflt: 0 }, + __bindgen_anon_6: rusage__bindgen_ty_6 { ru_majflt: 0 }, + __bindgen_anon_7: rusage__bindgen_ty_7 { ru_nswap: 0 }, + __bindgen_anon_8: rusage__bindgen_ty_8 { ru_inblock: 0 }, + __bindgen_anon_9: rusage__bindgen_ty_9 { ru_oublock: 0 }, + __bindgen_anon_10: rusage__bindgen_ty_10 { ru_msgsnd: 0 }, + __bindgen_anon_11: rusage__bindgen_ty_11 { ru_msgrcv: 0 }, + __bindgen_anon_12: rusage__bindgen_ty_12 { ru_nsignals: 0 }, + __bindgen_anon_13: rusage__bindgen_ty_13 { ru_nvcsw: 0 }, + __bindgen_anon_14: rusage__bindgen_ty_14 { ru_nivcsw: 0 }, + }; + let mut kidsa: crate::src_common::rusage = crate::src_common::rusage { + ru_utime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + ru_stime: crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }, + __bindgen_anon_1: rusage__bindgen_ty_1 { ru_maxrss: 0 }, + __bindgen_anon_2: rusage__bindgen_ty_2 { ru_ixrss: 0 }, + __bindgen_anon_3: rusage__bindgen_ty_3 { ru_idrss: 0 }, + __bindgen_anon_4: rusage__bindgen_ty_4 { ru_isrss: 0 }, + __bindgen_anon_5: rusage__bindgen_ty_5 { ru_minflt: 0 }, + __bindgen_anon_6: rusage__bindgen_ty_6 { ru_majflt: 0 }, + __bindgen_anon_7: rusage__bindgen_ty_7 { ru_nswap: 0 }, + __bindgen_anon_8: rusage__bindgen_ty_8 { ru_inblock: 0 }, + __bindgen_anon_9: rusage__bindgen_ty_9 { ru_oublock: 0 }, + __bindgen_anon_10: rusage__bindgen_ty_10 { ru_msgsnd: 0 }, + __bindgen_anon_11: rusage__bindgen_ty_11 { ru_msgrcv: 0 }, + __bindgen_anon_12: rusage__bindgen_ty_12 { ru_nsignals: 0 }, + __bindgen_anon_13: rusage__bindgen_ty_13 { ru_nvcsw: 0 }, + __bindgen_anon_14: rusage__bindgen_ty_14 { ru_nivcsw: 0 }, + }; + unsafe { + gettimeofday(&mut before, &mut dtz); + getrusage(RUSAGE_SELF, &mut selfb); + getrusage(RUSAGE_CHILDREN, &mut kidsb); + + posix_time = (!command.is_null() && (*command).flags & CMD_TIME_POSIX as libc::c_int != 0) + as libc::c_int; + nullcmd = (command.is_null() + || (*command).type_0 == command_type_cm_simple + && ((*(*command).value.Simple).words).is_null() + && ((*(*command).value.Simple).redirects).is_null()) + as libc::c_int; + if posixly_correct != 0 && nullcmd != 0 { + kidsb.ru_stime.tv_sec = 0 as __time_t; + selfb.ru_stime.tv_sec = kidsb.ru_stime.tv_sec; + kidsb.ru_utime.tv_sec = selfb.ru_stime.tv_sec; + selfb.ru_utime.tv_sec = kidsb.ru_utime.tv_sec; + kidsb.ru_stime.tv_usec = 0 as __suseconds_t; + selfb.ru_stime.tv_usec = kidsb.ru_stime.tv_usec; + kidsb.ru_utime.tv_usec = selfb.ru_stime.tv_usec; + selfb.ru_utime.tv_usec = kidsb.ru_utime.tv_usec; + before = shellstart; + } + + old_flags = (*command).flags; + COPY_PROCENV!(top_level, save_top_level); + (*command).flags &= !(CMD_TIME_PIPELINE as libc::c_int | CMD_TIME_POSIX as libc::c_int); + code = setjmp_nosigs!(top_level.as_mut_ptr()); + if code == NOT_JUMPED as libc::c_int { + rv = execute_command_internal(command, asynchronous, pipe_in, pipe_out, fds_to_close); + (*command).flags = old_flags; + } + COPY_PROCENV!(save_top_level, top_level); + + ss = 0 as time_t; + us = ss; + rs = us; + cpu = 0; + ssf = cpu; + usf = ssf; + rsf = usf; + + gettimeofday(&mut after, &mut dtz); + + getrusage(RUSAGE_SELF, &mut selfa); + getrusage(RUSAGE_CHILDREN, &mut kidsa); + + difftimeval(&mut real, &mut before, &mut after); + timeval_to_secs(&mut real, &mut rs, &mut rsf); + + addtimeval( + &mut user, + difftimeval(&mut after, &mut selfb.ru_utime, &mut selfa.ru_utime), + difftimeval(&mut before, &mut kidsb.ru_utime, &mut kidsa.ru_utime), + ); + timeval_to_secs(&mut user, &mut us, &mut usf); + + addtimeval( + &mut sys, + difftimeval(&mut after, &mut selfb.ru_stime, &mut selfa.ru_stime), + difftimeval(&mut before, &mut kidsb.ru_stime, &mut kidsa.ru_stime), + ); + timeval_to_secs(&mut sys, &mut ss, &mut ssf); + + cpu = timeval_to_cpu(&mut real, &mut user, &mut sys); + + if posix_time != 0 { + time_format = POSIX_TIMEFORMAT!(); + } else { + time_format = get_string_value(b"TIMEFORMAT\0" as *const u8 as *const libc::c_char); + if time_format.is_null() { + if posixly_correct != 0 && nullcmd != 0 { + time_format = b"user\t%2lU\nsys\t%2lS\0" as *const u8 as *mut libc::c_char; + } else { + time_format = BASH_TIMEFORMAT!(); + } + } + } + if !time_format.is_null() && *time_format as libc::c_int != 0 { + print_formatted_time(stderr, time_format, rs, rsf, us, usf, ss, ssf, cpu); + } + if code != 0 { + siglongjmp(top_level.as_mut_ptr(), code); + } + } + return rv; +} + +fn execute_in_subshell( + mut command: *mut COMMAND, + mut asynchronous: libc::c_int, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + let mut user_subshell: libc::c_int = 0; + let mut user_coproc: libc::c_int = 0; + let mut invert: libc::c_int = 0; + let mut return_code: libc::c_int = 0; + let mut function_value: libc::c_int = 0; + let mut should_redir_stdin: libc::c_int = 0; + let mut ois: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut tcom: *mut COMMAND = 0 as *mut COMMAND; + unsafe { + subshell_level += 1; + should_redir_stdin = (asynchronous != 0 + && (*command).flags & CMD_STDIN_REDIR as libc::c_int != 0 + && pipe_in == NO_PIPE + && stdin_redirects((*command).redirects) == 0) + as libc::c_int; + + invert = (((*command).flags & CMD_INVERT_RETURN as libc::c_int) != 0) as libc::c_int; + user_subshell = ((*command).type_0 == command_type_cm_subshell + || ((*command).flags & CMD_WANT_SUBSHELL as libc::c_int) != 0) + as libc::c_int; + user_coproc = ((*command).type_0 == command_type_cm_coproc) as libc::c_int; + (*command).flags &= !(CMD_FORCE_SUBSHELL as libc::c_int + | CMD_WANT_SUBSHELL as libc::c_int + | CMD_INVERT_RETURN as libc::c_int); + + if asynchronous != 0 { + original_pgrp = -1; + + ois = interactive_shell; + interactive_shell = 0; + + if ois != interactive_shell { + expand_aliases = 0; + } + } + + interactive = 0; + login_shell = interactive; + + if shell_compatibility_level > 44 { + loop_level = 0; + } + + if user_subshell != 0 { + subshell_environment = SUBSHELL_PAREN as libc::c_int; + if asynchronous != 0 { + subshell_environment |= SUBSHELL_ASYNC as libc::c_int; + } + } else { + subshell_environment = 0; + if asynchronous != 0 { + subshell_environment |= SUBSHELL_ASYNC as libc::c_int; + } + if pipe_in != NO_PIPE || pipe_out != NO_PIPE { + subshell_environment |= SUBSHELL_PIPE as libc::c_int; + } + if user_coproc != 0 { + subshell_environment |= SUBSHELL_COPROC as libc::c_int; + } + } + QUIT!(); + CHECK_TERMSIG!(); + + reset_terminating_signals(); + clear_pending_traps(); + reset_signal_handlers(); + subshell_environment |= SUBSHELL_RESETTRAP as libc::c_int; + + if running_trap > 0 { + run_trap_cleanup(running_trap - 1 as libc::c_int); + running_trap = 0; + } + + if asynchronous != 0 { + setup_async_signals(); + asynchronous = 0; + } else { + set_sigint_handler(); + } + + set_sigchld_handler(); + + without_job_control(); + + if !fds_to_close.is_null() { + close_fd_bitmap(fds_to_close); + } + + do_piping(pipe_in, pipe_out); + + coproc_closeall(); + + clear_fifo_list(); + + if user_subshell != 0 { + stdin_redir = + (stdin_redirects((*command).redirects) != 0 || pipe_in != NO_PIPE) as libc::c_int; + } else if shell_control_structure((*command).type_0 as libc::c_uint) != 0 + && pipe_in != NO_PIPE + { + stdin_redir = 1; + } + + if should_redir_stdin != 0 && stdin_redir == 0 { + async_redirect_stdin(); + } + + default_buffered_input = -1; + + if !((*command).redirects).is_null() { + if do_redirections((*command).redirects, RX_ACTIVE as libc::c_int) != 0 { + exit(if invert != 0 { + EXECUTION_SUCCESS as libc::c_int + } else { + EXECUTION_FAILURE as libc::c_int + }); + } + dispose_redirects((*command).redirects); + (*command).redirects = 0 as *mut REDIRECT; + } + + if (*command).type_0 == command_type_cm_subshell { + tcom = (*(*command).value.Subshell).command as *mut COMMAND; + } else if user_coproc != 0 { + tcom = (*(*command).value.Coproc).command as *mut COMMAND; + } else { + tcom = command as *mut COMMAND; + } + + if (*command).flags & CMD_TIME_PIPELINE as libc::c_int != 0 { + (*tcom).flags = CMD_TIME_PIPELINE as libc::c_int; + } + if (*command).flags & CMD_TIME_POSIX as libc::c_int != 0 { + (*tcom).flags = CMD_TIME_POSIX as libc::c_int; + } + + if (*command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 + && tcom != command as *mut COMMAND + { + (*tcom).flags = CMD_IGNORE_RETURN as libc::c_int; + } + + if (user_subshell != 0 || user_coproc != 0) + && ((*tcom).type_0 == command_type_cm_simple + || (*tcom).type_0 == command_type_cm_subshell) + && (*tcom).flags & CMD_TIME_PIPELINE as libc::c_int == 0 + && (*tcom).flags & CMD_INVERT_RETURN as libc::c_int == 0 + { + (*tcom).flags = CMD_NO_FORK as libc::c_int; + if (*tcom).type_0 == command_type_cm_simple { + (*(*tcom).value.Simple).flags |= CMD_NO_FORK as libc::c_int; + } + } + + invert = ((*tcom).flags & CMD_INVERT_RETURN as libc::c_int != 0) as libc::c_int; + (*tcom).flags &= !CMD_INVERT_RETURN as libc::c_int; + + result = setjmp_nosigs!(top_level.as_mut_ptr()); + + function_value = 0; + if return_catch_flag != 0 { + function_value = setjmp_nosigs!(return_catch.as_mut_ptr()); + } + + if result == EXITPROG as libc::c_int { + invert = 0; + return_code = last_command_exit_value; + } else if result != 0 { + return_code = if last_command_exit_value == EXECUTION_SUCCESS as libc::c_int { + EXECUTION_FAILURE as libc::c_int + } else { + last_command_exit_value + }; + } else if function_value != 0 { + return_code = return_catch_value; + } else { + return_code = execute_command_internal( + tcom as *mut COMMAND, + asynchronous, + NO_PIPE, + NO_PIPE, + fds_to_close, + ); + } + if invert != 0 { + return_code = if return_code == EXECUTION_SUCCESS as libc::c_int { + EXECUTION_FAILURE as libc::c_int + } else { + EXECUTION_SUCCESS as libc::c_int + }; + } + if user_subshell != 0 && signal_is_trapped(0) != 0 { + last_command_exit_value = return_code; + return_code = run_exit_trap(); + } + } + return return_code; +} + +#[no_mangle] +pub fn getcoprocbypid(mut pid: pid_t) -> *mut coproc { + unsafe { + return if pid == sh_coproc.c_pid { + &mut sh_coproc + } else { + 0 as *mut Coproc + }; + } +} + +pub fn cpe_alloc(cp: *mut Coproc) -> *mut cpelement { + let mut cpe: *mut cpelement; + unsafe { + cpe = malloc(size_of::() as usize) as *mut cpelement; + (*cpe).coproc = cp; + (*cpe).next = 0 as *mut cpelement; + } + return cpe; +} + +pub fn cpe_dispose(cpe: *mut cpelement) { + unsafe { + free(cpe as *mut c_void); + } +} + +pub fn cpe_add(cp: *mut Coproc) -> *mut cpelement { + let mut cpe: *mut cpelement; + + cpe = cpe_alloc(cp); + unsafe { + if coproc_list.head == 0 as *mut cpelement { + coproc_list.tail = cpe; + coproc_list.head = cpe; + coproc_list.ncoproc = 0 + } else { + (*coproc_list.tail).next = cpe; + coproc_list.tail = cpe; + } + coproc_list.ncoproc += 1; + } + return cpe; +} + +pub fn cpl_delete(pid: pid_t) -> *mut cpelement { + let mut prev: *mut cpelement; + let mut p: *mut cpelement; + unsafe { + p = coproc_list.head; + prev = coproc_list.head; + while !p.is_null() { + if (*(*p).coproc).c_pid == pid { + (*prev).next = (*p).next; + break; + } + prev = p; + p = (*p).next; + } + + if p == 0 as *mut cpelement { + return 0 as *mut cpelement; + } + + if p == coproc_list.head { + coproc_list.head = (*coproc_list.head).next; + } else if p == coproc_list.tail { + coproc_list.tail = prev; + } + + coproc_list.ncoproc -= 1; + if coproc_list.ncoproc == 0 { + coproc_list.head = 0 as *mut cpelement; + coproc_list.tail = 0 as *mut cpelement; + } else if coproc_list.ncoproc == 1 { + coproc_list.tail = coproc_list.head; + } + } + return p; +} + +pub fn cpl_reap() { + let mut p: *mut cpelement; + let mut next: *mut cpelement; + let mut nh: *mut cpelement; + let mut nt: *mut cpelement; + + nh = 0 as *mut cpelement; + nt = 0 as *mut cpelement; + next = 0 as *mut cpelement; + unsafe { + p = coproc_list.head; + while !p.is_null() { + next = (*p).next; + + if ((*(*p).coproc).c_flags & COPROC_DEAD as libc::c_int) != 0 { + coproc_list.ncoproc -= 0; + coproc_dispose((*p).coproc); + cpe_dispose(p); + } else if nh.is_null() { + nh = p; + nt = p; + } + p = next; + } + + if coproc_list.ncoproc == 0 { + coproc_list.head = 0 as *mut cpelement; + coproc_list.tail = 0 as *mut cpelement; + } else { + if !nt.is_null() { + (*nt).next = 0 as *mut cpelement; + } + + coproc_list.head = nh; + coproc_list.tail = nt; + if coproc_list.ncoproc == 1 { + coproc_list.tail = coproc_list.head; /* just to make sure */ + } + } + } +} + +pub fn cpl_flush() { + let mut cpe: *mut cpelement; + let mut p: *mut cpelement; + unsafe { + cpe = coproc_list.head; + while !cpe.is_null() { + p = cpe; + cpe = (*cpe).next; + + coproc_dispose((*p).coproc); + cpe_dispose(p); + } + + coproc_list.head = 0 as *mut cpelement; + coproc_list.tail = 0 as *mut cpelement; + coproc_list.ncoproc = 0; + } +} + +pub fn cpl_closeall() { + let mut cpe: *mut cpelement; + unsafe { + cpe = coproc_list.head; + while !cpe.is_null() { + coproc_close((*cpe).coproc); + + cpe = (*cpe).next; + } + } +} + +pub fn cpl_fdchk(fd: libc::c_int) { + let mut cpe: *mut cpelement; + unsafe { + cpe = coproc_list.head; + while !cpe.is_null() { + coproc_checkfd((*cpe).coproc, fd); + + cpe = (*cpe).next; + } + } +} + +pub fn cpl_search(pid: pid_t) -> *mut cpelement { + let mut cpe: *mut cpelement; + unsafe { + cpe = coproc_list.head; + while !cpe.is_null() { + if (*(*cpe).coproc).c_pid == pid { + return cpe; + } + cpe = (*cpe).next; + } + } + return 0 as *mut cpelement; +} + +pub fn cpl_searchbyname(name: *mut libc::c_char) -> *mut cpelement { + let mut cp: *mut cpelement; + unsafe { + cp = coproc_list.head; + while !cp.is_null() { + if STREQ!((*(*cp).coproc).c_name, name) { + return cp; + } + cp = (*cp).next; + } + } + return 0 as *mut cpelement; +} + +pub fn cpl_firstactive() -> pid_t { + let mut cpe: *mut cpelement; + unsafe { + cpe = coproc_list.head; + while !cpe.is_null() { + if (*(*cpe).coproc).c_flags & COPROC_DEAD as libc::c_int == 0 { + return (*(*cpe).coproc).c_pid; + } + cpe = (*cpe).next; + } + } + return NO_PID!() as pid_t; +} + +#[no_mangle] +pub fn getcoprocbyname(mut name: *const libc::c_char) -> *mut coproc { + unsafe { + return if !(sh_coproc.c_name).is_null() && STREQ!(sh_coproc.c_name, name) { + &mut sh_coproc + } else { + 0 as *mut Coproc + }; + } +} + +#[no_mangle] +pub fn coproc_init(mut cp: *mut coproc) { + unsafe { + (*cp).c_name = 0 as *mut libc::c_char; + (*cp).c_pid = NO_PID!(); + (*cp).c_wfd = -1; + (*cp).c_rfd = -1; + (*cp).c_wsave = -1; + (*cp).c_rsave = -1; + (*cp).c_lock = 0; + (*cp).c_status = 0; + (*cp).c_flags = 0; + } +} + +#[no_mangle] +pub fn coproc_alloc(mut name: *mut libc::c_char, mut pid: pid_t) -> *mut coproc { + let mut cp: *mut coproc = 0 as *mut coproc; + unsafe { + cp = &mut sh_coproc; + + coproc_init(cp); + (*cp).c_lock = 2; + + (*cp).c_pid = pid; + (*cp).c_name = savestring!(name); + + (*cp).c_lock = 0; + } + return cp; +} + +pub fn coproc_free(cp: *mut coproc) { + unsafe { + free(cp as *mut c_void); + } +} + +#[no_mangle] +pub fn coproc_dispose(mut cp: *mut coproc) { + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if cp.is_null() { + return; + } + unsafe { + BLOCK_SIGNAL!(SIGCHLD, set, oset); + (*cp).c_lock = 3; + coproc_unsetvars(cp); + FREE!((*cp).c_name); + coproc_close(cp); + + coproc_init(cp); + (*cp).c_lock = 0; + UNBLOCK_SIGNAL!(oset); + } +} + +#[no_mangle] +pub fn coproc_flush() { + unsafe { + coproc_dispose(&mut sh_coproc); + } +} + +#[no_mangle] +pub fn coproc_close(mut cp: *mut coproc) { + unsafe { + if (*cp).c_rfd >= 0 { + close((*cp).c_rfd); + (*cp).c_rfd = -1; + } + if (*cp).c_wfd >= 0 { + close((*cp).c_wfd); + (*cp).c_wfd = -1; + } + let ref mut fresh27 = (*cp).c_wsave; + (*cp).c_wsave = -1; + (*cp).c_rsave = -1; + } +} + +#[no_mangle] +pub fn coproc_closeall() { + unsafe { + coproc_close(&mut sh_coproc); + } +} + +#[no_mangle] +pub fn coproc_reap() { + let mut cp: *mut coproc = 0 as *mut coproc; + unsafe { + cp = &mut sh_coproc; + if !cp.is_null() && (*cp).c_flags & COPROC_DEAD as libc::c_int != 0 { + coproc_dispose(cp); + } + } +} + +#[no_mangle] +pub fn coproc_rclose(mut cp: *mut coproc, mut fd: libc::c_int) { + unsafe { + if (*cp).c_rfd >= 0 && (*cp).c_rfd == fd { + close((*cp).c_rfd); + (*cp).c_rfd = -1; + } + } +} + +#[no_mangle] +pub fn coproc_wclose(mut cp: *mut coproc, mut fd: libc::c_int) { + unsafe { + if (*cp).c_wfd >= 0 && (*cp).c_wfd == fd { + close((*cp).c_wfd); + (*cp).c_wfd = -1; + } + } +} + +#[no_mangle] +pub fn coproc_checkfd(mut cp: *mut coproc, mut fd: libc::c_int) { + let mut update: libc::c_int = 0; + unsafe { + update = 0; + if (*cp).c_rfd >= 0 && (*cp).c_rfd == fd { + let ref mut fresh28 = (*cp).c_rfd; + (*cp).c_rfd = -1; + update = -1; + } + if (*cp).c_wfd >= 0 && (*cp).c_wfd == fd { + let ref mut fresh29 = (*cp).c_wfd; + (*cp).c_wfd = -1; + update = -1; + } + if update != 0 { + coproc_setvars(cp); + } + } +} + +#[no_mangle] +pub fn coproc_fdchk(mut fd: libc::c_int) { + unsafe { + coproc_checkfd(&mut sh_coproc, fd); + } +} + +#[no_mangle] +pub fn coproc_fdclose(mut cp: *mut coproc, mut fd: libc::c_int) { + coproc_rclose(cp, fd); + coproc_wclose(cp, fd); + coproc_setvars(cp); +} + +#[no_mangle] +pub fn coproc_fdsave(mut cp: *mut coproc) { + unsafe { + (*cp).c_rsave = (*cp).c_rfd; + (*cp).c_wsave = (*cp).c_wfd; + } +} + +#[no_mangle] +pub fn coproc_fdrestore(mut cp: *mut coproc) { + unsafe { + (*cp).c_rfd = (*cp).c_rsave; + (*cp).c_wfd = (*cp).c_wsave; + } +} + +fn coproc_setstatus(mut cp: *mut coproc, mut status: libc::c_int) { + unsafe { + (*cp).c_lock = 4; + (*cp).c_status = status; + (*cp).c_flags |= COPROC_DEAD as libc::c_int; + (*cp).c_flags &= !(COPROC_RUNNING as libc::c_int); + (*cp).c_lock = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn coproc_pidchk(mut pid: pid_t, mut status: libc::c_int) { + let mut cp: *mut coproc = 0 as *mut coproc; + + cp = getcoprocbypid(pid); + if !cp.is_null() { + coproc_setstatus(cp, status); + } +} + +#[no_mangle] +pub fn coproc_active() -> pid_t { + unsafe { + return if sh_coproc.c_flags & COPROC_DEAD as libc::c_int != 0 { + NO_PID!() + } else { + sh_coproc.c_pid + }; + } +} + +#[no_mangle] +pub fn coproc_setvars(mut cp: *mut coproc) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut namevar: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: libc::c_int = 0; + let mut w: WordDesc = WordDesc { + word: 0 as *mut libc::c_char, + flags: 0, + }; + let mut ind: arrayind_t = 0; + unsafe { + if ((*cp).c_name).is_null() { + return; + } + + w.word = (*cp).c_name; + w.flags = 0; + if check_identifier(&mut w, 1) == 0 { + return; + } + + l = strlen((*cp).c_name) as libc::c_int; + namevar = malloc((l + 16) as usize) as *mut libc::c_char; + + v = find_variable((*cp).c_name); + + if v.is_null() { + v = find_variable_nameref_for_create((*cp).c_name, 1); + if v == INVALID_NAMEREF_VALUE!() { + free(namevar as *mut c_void); + return; + } + if !v.is_null() && nameref_p!(v) != 0 { + free((*cp).c_name as *mut c_void); + let ref mut fresh30 = (*cp).c_name; + (*cp).c_name = savestring!(nameref_cell!(v)); + v = make_new_array_variable((*cp).c_name); + } + } + + if !v.is_null() && (readonly_p!(v) != 0 || noassign_p!(v) != 0) { + if readonly_p!(v) != 0 { + err_readonly((*cp).c_name); + } + free(namevar as *mut c_void); + return; + } + if v.is_null() { + v = make_new_array_variable((*cp).c_name); + } + if array_p!(v) == 0 { + v = convert_var_to_array(v); + } + + t = itos((*cp).c_rfd as intmax_t); + ind = 0 as arrayind_t; + v = bind_array_variable((*cp).c_name, ind, t, 0); + free(t as *mut c_void); + + t = itos((*cp).c_wfd as intmax_t); + ind = 1 as arrayind_t; + v = bind_array_variable((*cp).c_name, ind, t, 0 as libc::c_int); + free(t as *mut c_void); + + sprintf( + namevar, + b"%s_PID\0" as *const u8 as *const libc::c_char, + (*cp).c_name, + ); + t = itos((*cp).c_pid as intmax_t); + v = bind_variable(namevar, t, 0 as libc::c_int); + free(t as *mut c_void); + + free(namevar as *mut c_void); + } +} + +#[no_mangle] +pub fn coproc_unsetvars(mut cp: *mut coproc) { + let mut l: libc::c_int = 0; + let mut namevar: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if ((*cp).c_name).is_null() { + return; + } + l = strlen((*cp).c_name) as libc::c_int; + + namevar = malloc((l + 16) as usize) as *mut libc::c_char; + + sprintf( + namevar, + b"%s_PID\0" as *const u8 as *const libc::c_char, + (*cp).c_name, + ); + unbind_variable_noref(namevar); + + check_unbind_variable((*cp).c_name); + + free(namevar as *mut c_void); + } +} + +fn execute_coproc( + mut command: *mut COMMAND, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + let mut rpipe: [libc::c_int; 2] = [0; 2]; + let mut wpipe: [libc::c_int; 2] = [0; 2]; + let mut estat: libc::c_int = 0; + let mut invert: libc::c_int = 0; + let mut coproc_pid: pid_t = 0; + let mut cp: *mut Coproc = 0 as *mut Coproc; + let mut tcmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + if sh_coproc.c_pid != NO_PID!() && (sh_coproc.c_rfd >= 0 || sh_coproc.c_wfd >= 0) { + internal_warning( + b"execute_coproc: coproc [%d:%s] still exists\0" as *const u8 as *mut libc::c_char, + sh_coproc.c_pid, + sh_coproc.c_name, + ); + } + coproc_init(&mut sh_coproc); + + invert = ((*command).flags & CMD_INVERT_RETURN as libc::c_int != 0) as libc::c_int; + + name = expand_string_unsplit_to_string((*(*command).value.Coproc).name, 0); + + if legal_identifier(name) == 0 { + internal_error( + b"`%s': not a valid identifier\0" as *const u8 as *const libc::c_char, + name, + ); + return if invert != 0 { 0 } else { 1 }; + } else { + free((*(*command).value.Coproc).name as *mut c_void); + (*(*command).value.Coproc).name = name; + } + + command_string_index = 0; + tcmd = make_command_string(command); + + sh_openpipe(&mut rpipe as *mut [libc::c_int; 2] as *mut libc::c_int); + sh_openpipe(&mut wpipe as *mut [libc::c_int; 2] as *mut libc::c_int); + + BLOCK_SIGNAL!(SIGCHLD, set, oset); + + p = savestring!(tcmd); + coproc_pid = make_child(p, FORK_ASYNC as libc::c_int); + + if coproc_pid == 0 { + close(rpipe[0 as libc::c_int as usize]); + close(wpipe[1 as libc::c_int as usize]); + + FREE!(p); + + UNBLOCK_SIGNAL!(oset); + estat = execute_in_subshell(command, 1, wpipe[0], rpipe[1], fds_to_close); + fflush(stdout); + fflush(stderr); + + exit(estat); + } + + close(rpipe[1]); + close(wpipe[0]); + + cp = coproc_alloc((*(*command).value.Coproc).name, coproc_pid); + (*cp).c_rfd = rpipe[0]; + (*cp).c_wfd = wpipe[1]; + + (*cp).c_flags |= COPROC_RUNNING as libc::c_int; + + fcntl((*cp).c_rfd, 2 as libc::c_int, 1 as libc::c_int); + fcntl((*cp).c_wfd, 2 as libc::c_int, 1 as libc::c_int); + coproc_setvars(cp); + + UNBLOCK_SIGNAL!(oset); + + close_pipes(pipe_in, pipe_out); + + unlink_fifo_list(); + + stop_pipeline(1, 0 as *mut libc::c_void as *mut COMMAND); + DESCRIBE_PID!(coproc_pid); + run_pending_traps(); + + return if invert != 0 { 1 } else { 0 }; + } +} + +fn restore_stdin(mut s: libc::c_int) { + unsafe { + dup2(s, 0); + close(s); + } +} +fn lastpipe_cleanup(mut s: libc::c_int) { + unsafe { + set_jobs_list_frozen(s); + } +} + +fn execute_pipeline( + mut command: *mut COMMAND, + mut asynchronous: libc::c_int, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + let mut prev: libc::c_int = 0; + let mut fildes: [libc::c_int; 2] = [0; 2]; + let mut new_bitmap_size: libc::c_int = 0; + let mut dummyfd: libc::c_int = 0; + let mut ignore_return: libc::c_int = 0; + let mut exec_result: libc::c_int = 0; + let mut lstdin: libc::c_int = 0; + let mut lastpipe_flag: libc::c_int = 0; + let mut lastpipe_jid: libc::c_int = 0; + let mut old_frozen: libc::c_int = 0; + let mut cmd: *mut COMMAND = 0 as *mut COMMAND; + let mut fd_bitmap: *mut fd_bitmap = 0 as *mut fd_bitmap; + let mut lastpid: pid_t = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + BLOCK_CHILD(&mut set, &mut oset); + ignore_return = ((*command).flags & CMD_IGNORE_RETURN as libc::c_int != 0) as libc::c_int; + + prev = pipe_in; + cmd = command; + + while !cmd.is_null() + && (*cmd).type_0 == command_type_cm_connection + && !((*cmd).value.Connection).is_null() + && (*(*cmd).value.Connection).connector == '|' as i32 + { + if pipe(fildes.as_mut_ptr()) < 0 { + sys_error(b"pipe error\0" as *const u8 as *const libc::c_char); + + terminate_current_pipeline(); + kill_current_pipeline(); + + UNBLOCK_CHILD(&mut oset); + + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + + throw_to_top_level(); + return 1; + } + + new_bitmap_size = if fildes[0] < (*fds_to_close).size { + (*fds_to_close).size + } else { + fildes[0] + 8 + }; + + fd_bitmap = new_fd_bitmap(new_bitmap_size); + + xbcopy( + (*fds_to_close).bitmap, + (*fd_bitmap).bitmap, + (*fds_to_close).size, + ); + + *((*fd_bitmap).bitmap).offset(fildes[0] as isize) = 1; + + begin_unwind_frame(b"pipe-file-descriptors\0" as *const u8 as *mut libc::c_char); + + add_unwind_protect( + transmute:: (), Option>(dispose_fd_bitmap), + fd_bitmap as *mut libc::c_char, + ); + + add_unwind_protect( + transmute:: (), Option>(close_fd_bitmap), + fd_bitmap as *mut libc::c_char, + ); + if prev >= 0 { + add_unwind_protect( + transmute::< + unsafe extern "C" fn(__fd: libc::c_int) -> libc::c_int, + Option, + >(close), + prev as *mut libc::c_char, + ); + } + dummyfd = fildes[1]; + add_unwind_protect( + transmute:: libc::c_int, Option>( + close, + ), + dummyfd as *mut libc::c_char, + ); + + add_unwind_protect( + transmute:: libc::c_int, Option>( + restore_signal_mask, + ), + transmute::<*mut sigset_t, *mut libc::c_char>(&mut oset), //这个ä½ç½®å¯èƒ½ä¼šå­˜åœ¨é—®é¢˜ + ); + + if ignore_return != 0 && !((*(*cmd).value.Connection).first).is_null() { + (*(*(*cmd).value.Connection).first).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + execute_command_internal( + (*(*cmd).value.Connection).first, + asynchronous, + prev, + fildes[1], + fd_bitmap, + ); + + if prev >= 0 { + close(prev); + } + + prev = fildes[0]; + close(fildes[1]); + + dispose_fd_bitmap(fd_bitmap); + discard_unwind_frame(b"pipe-file-descriptors\0" as *const u8 as *mut libc::c_char); + + cmd = (*(*cmd).value.Connection).second; + } + + lastpid = last_made_pid; + if ignore_return != 0 && !cmd.is_null() { + (*cmd).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + lastpipe_flag = 0; + + begin_unwind_frame(b"lastpipe-exec\0" as *const u8 as *mut libc::c_char); + lstdin = -1; + + if lastpipe_opt != 0 + && job_control == 0 + && asynchronous == 0 + && pipe_out == NO_PIPE + && prev > 0 + { + lstdin = move_to_high_fd(0, 1, -1); + if lstdin > 0 { + do_piping(prev, pipe_out); + prev = NO_PIPE; + add_unwind_protect( + transmute:: (), Option>(restore_stdin), + lstdin as *mut libc::c_char, + ); + lastpipe_flag = 1; + old_frozen = freeze_jobs_list(); + lastpipe_jid = + stop_pipeline(0 as libc::c_int, 0 as *mut libc::c_void as *mut COMMAND); + add_unwind_protect( + transmute:: (), Option>(lastpipe_cleanup), + old_frozen as *mut libc::c_char, + ); + UNBLOCK_CHILD(&mut oset); + } + if !cmd.is_null() { + (*cmd).flags |= CMD_LASTPIPE as libc::c_int; + } + } + + if prev >= 0 { + add_unwind_protect( + transmute:: libc::c_int, Option>( + close, + ), + prev as *mut libc::c_char, + ); + } + + exec_result = execute_command_internal(cmd, asynchronous, prev, pipe_out, fds_to_close); + + if lstdin > 0 { + restore_stdin(lstdin); + } + + if prev >= 0 { + close(prev); + } + + UNBLOCK_CHILD(&mut oset); + + QUIT!(); + + if lastpipe_flag != 0 { + if (lastpipe_jid < 0 as libc::c_int + || lastpipe_jid >= js.j_jobslots + || (*jobs.offset(lastpipe_jid as isize)).is_null()) as libc::c_int + == 0 as libc::c_int + { + append_process( + savestring!(the_printed_command_except_trap), + dollar_dollar_pid, + exec_result, + lastpipe_jid, + ); + lstdin = wait_for(lastpid, 0); + } else { + lstdin = wait_for_single_pid(lastpid, 0); + } + if (lastpipe_jid < 0 + || lastpipe_jid >= js.j_jobslots + || (*jobs.offset(lastpipe_jid as isize)).is_null()) as libc::c_int + == 0 as libc::c_int + { + exec_result = job_exit_status(lastpipe_jid); + } else if pipefail_opt != 0 { + exec_result = exec_result | lstdin; + } + set_jobs_list_frozen(old_frozen); + } + discard_unwind_frame(b"lastpipe-exec\0" as *const u8 as *mut libc::c_char); + } + return exec_result; +} + +const FLAG_AND: i32 = '&' as i32; +const FLAG_SEMICOLON: i32 = ';' as i32; +const FLAG_OR: i32 = '|' as i32; +const FLAG_OR_OR: i32 = OR_OR as i32; +const FLAG_AND_AND: i32 = AND_AND as i32; + +fn execute_connection( + mut command: *mut COMMAND, + mut asynchronous: libc::c_int, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + let mut tc: *mut COMMAND = 0 as *mut COMMAND; + let mut second: *mut COMMAND = 0 as *mut COMMAND; + let mut ignore_return: libc::c_int = 0; + let mut exec_result: libc::c_int = 0; + let mut was_error_trap: libc::c_int = 0; + let mut invert: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + unsafe { + ignore_return = ((*command).flags & CMD_IGNORE_RETURN as libc::c_int != 0) as libc::c_int; + + match (*(*command).value.Connection).connector { + FLAG_AND => { + tc = (*(*command).value.Connection).first; + if tc.is_null() { + return EXECUTION_SUCCESS as libc::c_int; + } + + if ignore_return != 0 { + (*tc).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + (*tc).flags |= CMD_AMPERSAND as libc::c_int; + + if (subshell_environment != 0 || job_control == 0) && stdin_redir == 0 { + (*tc).flags |= CMD_STDIN_REDIR as libc::c_int; + } + exec_result = execute_command_internal(tc, 1, pipe_in, pipe_out, fds_to_close); + QUIT!(); + + if (*tc).flags & CMD_STDIN_REDIR as libc::c_int != 0 { + (*tc).flags &= !(CMD_STDIN_REDIR as libc::c_int); + } + + second = (*(*command).value.Connection).second; + if !second.is_null() { + if ignore_return != 0 { + (*second).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_command_internal( + second, + asynchronous, + pipe_in, + pipe_out, + fds_to_close, + ); + } + } + FLAG_SEMICOLON => { + if ignore_return != 0 { + if !((*(*command).value.Connection).first).is_null() { + (*(*(*command).value.Connection).first).flags |= + CMD_IGNORE_RETURN as libc::c_int; + } + if !((*(*command).value.Connection).second).is_null() { + (*(*(*command).value.Connection).second).flags |= + CMD_IGNORE_RETURN as libc::c_int; + } + } + executing_list += 1; + QUIT!(); + + execute_command((*(*command).value.Connection).first); + + QUIT!(); + optimize_fork(command); + exec_result = execute_command_internal( + (*(*command).value.Connection).second, + asynchronous, + pipe_in, + pipe_out, + fds_to_close, + ); + executing_list -= 1; + } + FLAG_OR => { + was_error_trap = (signal_is_trapped(ERROR_TRAP as libc::c_int) != 0 + && signal_is_ignored(ERROR_TRAP as libc::c_int) == 0) + as libc::c_int; + invert = ((*command).flags & CMD_INVERT_RETURN as libc::c_int != 0) as libc::c_int; + ignore_return = + ((*command).flags & CMD_IGNORE_RETURN as libc::c_int != 0) as libc::c_int; + + line_number_for_err_trap = line_number; + exec_result = + execute_pipeline(command, asynchronous, pipe_in, pipe_out, fds_to_close); + + if asynchronous != 0 { + exec_result = EXECUTION_SUCCESS as libc::c_int; + invert = 0 as libc::c_int; + } + + if was_error_trap != 0 + && ignore_return == 0 + && invert == 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + last_command_exit_value = exec_result; + save_line_number = line_number; + line_number = line_number_for_err_trap; + run_error_trap(); + line_number = save_line_number; + } + + if ignore_return == 0 + && invert == 0 + && exit_immediately_on_error != 0 + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + last_command_exit_value = exec_result; + run_pending_traps(); + jump_to_top_level(ERREXIT as libc::c_int); + } + } + FLAG_AND_AND | FLAG_OR_OR => { + if asynchronous != 0 { + (*command).flags |= CMD_FORCE_SUBSHELL as libc::c_int; + exec_result = + execute_command_internal(command, 1, pipe_in, pipe_out, fds_to_close); + } else { + executing_list += 1; + if !((*(*command).value.Connection).first).is_null() { + (*(*(*command).value.Connection).first).flags |= + CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_command((*(*command).value.Connection).first); + + QUIT!(); + + if (*(*command).value.Connection).connector == AND_AND as libc::c_int + && exec_result == EXECUTION_SUCCESS as libc::c_int + || (*(*command).value.Connection).connector == OR_OR as libc::c_int + && exec_result != EXECUTION_SUCCESS as libc::c_int + { + optimize_fork(command); + + second = (*(*command).value.Connection).second; + if ignore_return != 0 && !second.is_null() { + (*second).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + exec_result = execute_command(second); + } + executing_list -= 1; + } + } + _ => { + command_error( + b"execute_connection\0" as *const u8 as *const libc::c_char, + CMDERR_BADCONN as libc::c_int, + (*(*command).value.Connection).connector, + 0, + ); + jump_to_top_level(EXECUTION_FAILURE as libc::c_int); + } + } + } + return exec_result; +} + +fn execute_for_command(mut for_command: *mut FOR_COM) -> libc::c_int { + let mut releaser: *mut WordList = 0 as *mut WordList; + let mut list: *mut WordList = 0 as *mut WordList; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut identifier: *mut libc::c_char = 0 as *mut libc::c_char; + let mut retval: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + unsafe { + save_line_number = line_number; + if check_identifier((*for_command).name, 1) == 0 { + if posixly_correct != 0 && interactive_shell == 0 && rpm_requires == 0 { + last_command_exit_value = EX_BADUSAGE as libc::c_int; + jump_to_top_level(ERREXIT as libc::c_int); + } + return EXECUTION_FAILURE as libc::c_int; + } + + loop_level += 1; + identifier = (*(*for_command).name).word; + + line_number = (*for_command).line; + releaser = expand_words_no_vars((*for_command).map_list); + list = releaser; + + begin_unwind_frame(b"for\0" as *const u8 as *mut libc::c_char); + add_unwind_protect( + transmute::>(dispose_words), + releaser as *mut libc::c_char, + ); + + if (*for_command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 { + (*(*for_command).action).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + retval = EXECUTION_SUCCESS as libc::c_int; + while !list.is_null() { + QUIT!(); + + line_number = (*for_command).line; + + command_string_index = 0; + print_for_command_head(for_command); + + if echo_command_at_execute != 0 { + xtrace_print_for_command_head(for_command); + } + + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command); + } + + retval = run_debug_trap(); + + if !(debugging_mode != 0 && retval != EXECUTION_SUCCESS as libc::c_int) { + this_command_name = 0 as *mut libc::c_char; + + v = find_variable_last_nameref(identifier, 1); + if !v.is_null() && nameref_p!(v) != 0 { + if valid_nameref_value((*(*list).word).word, 1) == 0 { + sh_invalidid((*(*list).word).word); + v = 0 as *mut SHELL_VAR; + } else if readonly_p!(v) != 0 { + err_readonly(name_cell!(v)); + } else { + v = bind_variable_value( + v, + (*(*list).word).word, + ASS_NAMEREF as libc::c_int, + ); + } + } else { + v = bind_variable(identifier, (*(*list).word).word, 0); + } + if v.is_null() || readonly_p!(v) != 0 || noassign_p!(v) != 0 { + line_number = save_line_number; + if !v.is_null() + && readonly_p!(v) != 0 + && interactive_shell == 0 + && posixly_correct != 0 + { + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + jump_to_top_level(FORCE_EOF as libc::c_int); + } else { + dispose_words(releaser); + discard_unwind_frame(b"for\0" as *const u8 as *mut libc::c_char); + loop_level -= 1; + return EXECUTION_FAILURE as libc::c_int; + } + } + + if ifsname!(identifier) { + setifs(v); + } else { + stupidly_hack_special_variables(identifier); + } + retval = execute_command((*for_command).action); + REAP!(); + QUIT!(); + + if breaking != 0 { + breaking -= 1; + break; + } else if continuing != 0 { + continuing -= 1; + if continuing != 0 { + break; + } + } + } + + list = (*list).next; + } + + loop_level -= 1; + line_number = save_line_number; + + dispose_words(releaser); + discard_unwind_frame(b"for\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + return retval; +} + +fn eval_arith_for_expr(mut l: *mut WordList, mut okp: *mut libc::c_int) -> intmax_t { + let mut new: *mut WordList = 0 as *mut WordList; + let mut expresult: intmax_t = 0; + let mut r: libc::c_int = 0; + + new = expand_words_no_vars(l); + unsafe { + if !new.is_null() { + if echo_command_at_execute != 0 { + xtrace_print_arith_cmd(new); + } + + this_command_name = b"((\0" as *const u8 as *mut libc::c_char; + + command_string_index = 0; + print_arith_command(new); + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command); + } + + r = run_debug_trap(); + if debugging_mode == 0 || r == EXECUTION_SUCCESS as libc::c_int { + expresult = evalexp((*(*new).word).word, EXP_EXPANDED as libc::c_int, okp); + } else { + expresult = 0 as intmax_t; + if !okp.is_null() { + *okp = 1; + } + } + + dispose_words(new); + } else { + expresult = 0 as intmax_t; + if !okp.is_null() { + *okp = 1; + } + } + } + return expresult; +} + +fn execute_arith_for_command(mut arith_for_command: *mut ARITH_FOR_COM) -> libc::c_int { + let mut expresult: intmax_t = 0; + let mut expok: libc::c_int = 0; + let mut body_status: libc::c_int = 0; + let mut arith_lineno: libc::c_int = 0; + let mut save_lineno: libc::c_int = 0; + + body_status = EXECUTION_SUCCESS as libc::c_int; + unsafe { + loop_level += 1; + save_lineno = line_number; + + if (*arith_for_command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 { + (*(*arith_for_command).action).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + this_command_name = b"((\0" as *const u8 as *mut libc::c_char; + + arith_lineno = (*arith_for_command).line; + line_number = arith_lineno; + if variable_context != 0 && interactive_shell != 0 && sourcelevel == 0 { + line_number -= function_line_number - 1; + if line_number <= 0 { + line_number = 1; + } + } + expresult = eval_arith_for_expr((*arith_for_command).init, &mut expok); + if expok == 0 { + line_number = save_lineno; + return EXECUTION_FAILURE as libc::c_int; + } + + loop { + line_number = arith_lineno; + expresult = eval_arith_for_expr((*arith_for_command).test, &mut expok); + line_number = save_lineno; + + if expok == 0 { + body_status = EXECUTION_FAILURE as libc::c_int; + break; + } else { + REAP!(); + if expresult == 0 { + break; + } + + QUIT!(); + body_status = execute_command((*arith_for_command).action); + QUIT!(); + + if breaking != 0 { + breaking -= 1; + break; + } else { + if continuing != 0 { + continuing -= 1; + if continuing != 0 { + break; + } + } + + line_number = arith_lineno; + expresult = eval_arith_for_expr((*arith_for_command).step, &mut expok); + line_number = save_lineno; + + if !(expok == 0) { + continue; + } + body_status = 1; + break; + } + } + } + loop_level -= 1; + line_number = save_lineno; + } + return body_status; +} + +static mut COLS: libc::c_int = 0; +static mut tabsize: libc::c_int = 0; + +fn displen(mut s: *const libc::c_char) -> libc::c_int { + let mut wcstr: *mut wchar_t = 0 as *mut wchar_t; + let mut slen: size_t = 0; + let mut wclen: libc::c_int = 0; + unsafe { + wcstr = 0 as *mut wchar_t; + slen = mbstowcs(wcstr, s, 0 as usize) as size_t; + if slen == -(1 as libc::c_int) as libc::c_ulong { + slen = 0 as size_t; + } + + wcstr = malloc((size_of::() * (slen + 1) as usize) as usize) as *mut wchar_t; + mbstowcs(wcstr, s, (slen + 1) as usize); + wclen = wcswidth(wcstr, slen as usize); + free(wcstr as *mut c_void); + + return (if wclen < 0 { STRLEN!(s) } else { wclen }) as libc::c_int; + } +} + +fn print_index_and_element( + mut len: libc::c_int, + mut ind: libc::c_int, + mut list: *mut WordList, +) -> libc::c_int { + let mut l: *mut WordList = 0 as *mut WordList; + let mut i: libc::c_int = 0; + + if list.is_null() { + return 0; + } + + i = ind; + l = list; + unsafe { + while !l.is_null() && { + i -= 1; + i != 0 + } { + l = (*l).next; + } + if l.is_null() { + return 0; + } + fprintf( + stderr, + b"%*d%s%s\0" as *const u8 as *const libc::c_char, + len, + ind, + b") \0" as *const u8 as *const libc::c_char, + (*(*l).word).word, + ); + return displen((*(*l).word).word); + } +} + +fn indent(mut from: libc::c_int, mut to: libc::c_int) { + unsafe { + while from < to { + if to / tabsize > from / tabsize { + putc('\t' as i32, stderr); + from += tabsize - from % tabsize; + } else { + putc(' ' as i32, stderr); + from += 1; + } + } + } +} + +fn print_select_list( + mut list: *mut WordList, + mut list_len: libc::c_int, + mut max_elem_len: libc::c_int, + mut indices_len: libc::c_int, +) { + let mut ind: libc::c_int = 0; + let mut row: libc::c_int = 0; + let mut elem_len: libc::c_int = 0; + let mut pos: libc::c_int = 0; + let mut cols: libc::c_int = 0; + let mut rows: libc::c_int = 0; + let mut first_column_indices_len: libc::c_int = 0; + let mut other_indices_len: libc::c_int = 0; + + if list.is_null() { + unsafe { + putc('\n' as i32, stderr); + } + return; + } + + cols = if max_elem_len != 0 { + unsafe { COLS / max_elem_len } + } else { + 1 + }; + if cols == 0 { + cols = 1; + } + + rows = if list_len != 0 { + list_len / cols + (list_len % cols != 0) as libc::c_int + } else { + 1 + }; + cols = if list_len != 0 { + list_len / rows + (list_len % rows != 0) as libc::c_int + } else { + 1 + }; + if rows == 1 { + rows = cols; + cols = 1; + } + + first_column_indices_len = NUMBER_LEN!(rows); + other_indices_len = indices_len; + + row = 0; + while row < rows { + ind = row; + pos = 0; + loop { + indices_len = if pos == 0 { + first_column_indices_len + } else { + other_indices_len + }; + elem_len = print_index_and_element(indices_len, ind + 1, list); + elem_len += indices_len + RP_SPACE_LEN!(); + ind += rows; + if ind >= list_len { + break; + } + indent(pos + elem_len, pos + max_elem_len); + pos += max_elem_len; + } + unsafe { + putc('\n' as i32, stderr); + } + + row += 1; + } +} + +fn select_query( + mut list: *mut WordList, + mut list_len: libc::c_int, + mut prompt: *mut libc::c_char, + mut print_menu: libc::c_int, +) -> *mut libc::c_char { + let mut max_elem_len: libc::c_int = 0; + let mut indices_len: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut oe: libc::c_int = 0; + let mut reply: intmax_t = 0; + let mut l: *mut WordList = 0 as *mut WordList; + let mut repl_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + COLS = default_columns(); + + tabsize = 8; + max_elem_len = 0; + l = list; + while !l.is_null() { + len = displen((*(*l).word).word); + if len > max_elem_len { + max_elem_len = len; + } + l = (*l).next; + } + indices_len = NUMBER_LEN!(list_len); + max_elem_len += indices_len + RP_SPACE_LEN!() + 2; + + loop { + if print_menu != 0 { + print_select_list(list, list_len, max_elem_len, indices_len); + } + fprintf(stderr, b"%s\0" as *const u8 as *const libc::c_char, prompt); + fflush(stderr); + QUIT!(); + + oe = executing_builtin; + executing_builtin = 1; + r = read_builtin(0 as *mut WordList); + executing_builtin = oe; + if r != EXECUTION_SUCCESS as libc::c_int { + putchar('\n' as i32); + return 0 as *mut libc::c_char; + } + repl_string = get_string_value(b"REPLY\0" as *const u8 as *const libc::c_char); + if repl_string.is_null() { + return 0 as *mut libc::c_char; + } + if *repl_string as libc::c_int == 0 { + print_menu = 1; + } else { + if legal_number(repl_string, &mut reply) == 0 { + return b"\0" as *const u8 as *mut libc::c_char; + } + if reply < 1 || reply > list_len as libc::c_long { + return b"\0" as *const u8 as *mut libc::c_char; + } + l = list; + while !l.is_null() && { + reply -= 1; + reply != 0 + } { + l = (*l).next; + } + return (*(*l).word).word; + } + } + } +} + +fn execute_select_command(mut select_command: *mut SELECT_COM) -> libc::c_int { + let mut releaser: *mut WordList = 0 as *mut WordList; + let mut list: *mut WordList = 0 as *mut WordList; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut identifier: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ps3_prompt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut selection: *mut libc::c_char = 0 as *mut libc::c_char; + let mut retval: libc::c_int = 0; + let mut list_len: libc::c_int = 0; + let mut show_menu: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + unsafe { + if check_identifier((*select_command).name, 1) == 0 { + return EXECUTION_FAILURE as libc::c_int; + } + save_line_number = line_number; + line_number = (*select_command).line; + + command_string_index = 0; + print_select_command_head(select_command); + + if echo_command_at_execute != 0 { + xtrace_print_select_command_head(select_command); + } + + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command); + } + + retval = run_debug_trap(); + if debugging_mode != 0 && retval != EXECUTION_SUCCESS as libc::c_int { + return EXECUTION_SUCCESS as libc::c_int; + } + + loop_level += 1; + identifier = (*(*select_command).name).word; + + releaser = expand_words_no_vars((*select_command).map_list); + list = releaser; + list_len = list_length(list as *mut GENERIC_LIST); + if list.is_null() || list_len == 0 { + if !list.is_null() { + dispose_words(list); + } + line_number = save_line_number; + return EXECUTION_SUCCESS as libc::c_int; + } + + begin_unwind_frame(b"select\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + add_unwind_protect( + transmute::>(dispose_words), + releaser as *mut libc::c_char, + ); + + if (*select_command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 { + (*(*select_command).action).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + retval = EXECUTION_SUCCESS as libc::c_int; + show_menu = 1 as libc::c_int; + + loop { + line_number = (*select_command).line; + ps3_prompt = get_string_value(b"PS3\0" as *const u8 as *const libc::c_char); + if ps3_prompt.is_null() { + ps3_prompt = b"#? \0" as *const u8 as *mut libc::c_char; + } + + QUIT!(); + selection = select_query(list, list_len, ps3_prompt, show_menu); + QUIT!(); + if selection.is_null() { + retval = EXECUTION_FAILURE as libc::c_int; + break; + } else { + v = bind_variable(identifier, selection, 0); + if v.is_null() || readonly_p!(v) != 0 || noassign_p!(v) != 0 { + if !v.is_null() + && readonly_p!(v) != 0 + && interactive_shell == 0 + && posixly_correct != 0 + { + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + jump_to_top_level(FORCE_EOF as libc::c_int); + } else { + dispose_words(releaser); + discard_unwind_frame(b"select\0" as *const u8 as *mut libc::c_char); + loop_level -= 1; + line_number = save_line_number; + return EXECUTION_FAILURE as libc::c_int; + } + } + + stupidly_hack_special_variables(identifier); + + retval = execute_command((*select_command).action); + + REAP!(); + QUIT!(); + + if breaking != 0 { + breaking -= 1; + break; + } else { + if continuing != 0 { + continuing -= 1; + if continuing != 0 { + break; + } + } + + show_menu = 0; + selection = get_string_value(b"REPLY\0" as *const u8 as *const libc::c_char); + if !selection.is_null() && *selection as libc::c_int == '\u{0}' as i32 { + show_menu = 1; + } + } + } + } + + loop_level -= 1; + line_number = save_line_number; + + dispose_words(releaser); + discard_unwind_frame(b"select\0" as *const u8 as *mut libc::c_char); + } + return retval; +} + +fn execute_case_command(mut case_command: *mut CASE_COM) -> libc::c_int { + let mut list: *mut WordList = 0 as *mut WordList; + let mut wlist: *mut WordList = 0 as *mut WordList; + let mut es: *mut WordList = 0 as *mut WordList; + let mut clauses: *mut PATTERN_LIST = 0 as *mut PATTERN_LIST; + let mut word: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pattern: *mut libc::c_char = 0 as *mut libc::c_char; + let mut retval: libc::c_int = 0; + let mut match_0: libc::c_int = 0; + let mut ignore_return: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + unsafe { + save_line_number = line_number; + line_number = (*case_command).line; + + command_string_index = 0 as libc::c_int; + print_case_command_head(case_command); + + if echo_command_at_execute != 0 { + xtrace_print_case_command_head(case_command); + } + + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command); + } + + retval = run_debug_trap(); + if debugging_mode != 0 && retval != EXECUTION_SUCCESS as libc::c_int { + line_number = save_line_number; + return EXECUTION_SUCCESS as libc::c_int; + } + wlist = expand_word_leave_quoted((*case_command).word, 0); + + if !wlist.is_null() { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + t = string_list(wlist); + word = dequote_string(t); + free(t as *mut c_void); + } else { + word = savestring!(b"\0" as *const u8 as *mut libc::c_char); + } + dispose_words(wlist); + + retval = EXECUTION_SUCCESS as libc::c_int; + ignore_return = (*case_command).flags & CMD_IGNORE_RETURN as libc::c_int; + + begin_unwind_frame(b"case\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + add_unwind_protect( + transmute::>( + free, + ), + word, + ); + + clauses = (*case_command).clauses; + 's_150: while !clauses.is_null() { + QUIT!(); + list = (*clauses).patterns; + while !list.is_null() { + es = expand_word_leave_quoted((*list).word, 0); + + if !es.is_null() + && !((*es).word).is_null() + && !((*(*es).word).word).is_null() + && *(*(*es).word).word as libc::c_int != 0 + { + qflags = QGLOB_CVTNULL as libc::c_int; + qflags |= QGLOB_CTLESC as libc::c_int; + pattern = quote_string_for_globbing((*(*es).word).word, qflags); + } else { + pattern = malloc(1 as usize) as *mut libc::c_char; + *pattern.offset(0 as isize) = '\u{0}' as i32 as libc::c_char; + } + match_0 = (strmatch(pattern, word, FNMATCH_EXTFLAG!() | FNMATCH_IGNCASE!()) + != FNM_NOMATCH!()) as libc::c_int; + free(pattern as *mut c_void); + + dispose_words(es); + if match_0 != 0 { + loop { + if !((*clauses).action).is_null() && ignore_return != 0 { + (*(*clauses).action).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + retval = execute_command((*clauses).action); + if !((*clauses).flags & CASEPAT_FALLTHROUGH as libc::c_int != 0 && { + clauses = (*clauses).next; + !clauses.is_null() + }) { + break; + } + } + if clauses.is_null() || (*clauses).flags & CASEPAT_TESTNEXT as libc::c_int == 0 + { + break 's_150; + } else { + break; + } + } else { + QUIT!(); + list = (*list).next; + } + } + clauses = (*clauses).next; + } + free(word as *mut c_void); + discard_unwind_frame(b"case\0" as *const u8 as *mut libc::c_char); + line_number = save_line_number; + } + return retval; +} + +// #[macro_export] +// macro_rules! CMD_WHILE { +// () => { +// 0 +// }; +// } + +fn execute_while_command(mut while_command: *mut WHILE_COM) -> libc::c_int { + return execute_while_or_until(while_command, CMD_WHILE!()); +} + +// #[macro_export] +// macro_rules! CMD_UNTIL { +// () => { +// 1 +// }; +// } + +fn execute_until_command(mut while_command: *mut WHILE_COM) -> libc::c_int { + return execute_while_or_until(while_command, CMD_UNTIL!()); +} + +fn execute_while_or_until( + mut while_command: *mut WHILE_COM, + mut type_0: libc::c_int, +) -> libc::c_int { + let mut return_value: libc::c_int = 0; + let mut body_status: libc::c_int = 0; + unsafe { + body_status = EXECUTION_SUCCESS as libc::c_int; + loop_level += 1; + (*(*while_command).test).flags |= CMD_IGNORE_RETURN as libc::c_int; + if (*while_command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 { + (*(*while_command).action).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + loop { + return_value = execute_command((*while_command).test); + REAP!(); + + if type_0 == CMD_WHILE!() && return_value != EXECUTION_SUCCESS as libc::c_int { + if breaking != 0 { + breaking -= 1; + } + if continuing != 0 { + continuing -= 1; + } + break; + } else if type_0 == CMD_UNTIL!() && return_value == EXECUTION_SUCCESS as libc::c_int { + if breaking != 0 { + breaking -= 1; + } + if continuing != 0 { + continuing -= 1; + } + break; + } else { + QUIT!(); + body_status = execute_command((*while_command).action); + QUIT!(); + + if breaking != 0 { + breaking -= 1; + break; + } else { + if !(continuing != 0) { + continue; + } + continuing -= 1; + if continuing != 0 { + break; + } + } + } + } + loop_level -= 1; + } + return body_status; +} + +fn execute_if_command(mut if_command: *mut IF_COM) -> libc::c_int { + let mut return_value: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + unsafe { + save_line_number = line_number; + (*(*if_command).test).flags |= CMD_IGNORE_RETURN as libc::c_int; + return_value = execute_command((*if_command).test); + line_number = save_line_number; + + if return_value == EXECUTION_SUCCESS as libc::c_int { + QUIT!(); + + if !((*if_command).true_case).is_null() + && (*if_command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 + { + (*(*if_command).true_case).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + return execute_command((*if_command).true_case); + } else { + QUIT!(); + + if !((*if_command).false_case).is_null() + && (*if_command).flags & CMD_IGNORE_RETURN as libc::c_int != 0 + { + (*(*if_command).false_case).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + return execute_command((*if_command).false_case); + }; + } +} + +fn execute_arith_command(mut arith_command: *mut ARITH_COM) -> libc::c_int { + let mut expok: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + let mut retval: libc::c_int = 0; + let mut expresult: intmax_t = 0; + let mut new: *mut WordList = 0 as *mut WordList; + let mut exp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + expresult = 0 as intmax_t; + unsafe { + save_line_number = line_number; + this_command_name = b"((\0" as *const u8 as *mut libc::c_char; + line_number = (*arith_command).line; + line_number_for_err_trap = line_number; + + if variable_context != 0 && interactive_shell != 0 && sourcelevel == 0 { + line_number -= function_line_number - 1; + if line_number <= 0 { + line_number = 1; + } + } + + command_string_index = 0; + print_arith_command((*arith_command).exp); + + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command); + } + + retval = run_debug_trap(); + if debugging_mode != 0 && retval != EXECUTION_SUCCESS as libc::c_int { + line_number = save_line_number; + return EXECUTION_SUCCESS as libc::c_int; + } + + t = 0 as *mut libc::c_char; + new = (*arith_command).exp; + if !((*new).next).is_null() { + t = string_list(new); + exp = t; + } else { + exp = (*(*new).word).word; + } + + exp = expand_arith_string(exp, Q_DOUBLE_QUOTES as libc::c_int | Q_ARITH as libc::c_int); + + if echo_command_at_execute != 0 { + new = make_word_list( + make_word(if !exp.is_null() { + exp + } else { + b"\0" as *const u8 as *const libc::c_char + }), + 0 as *mut WordList, + ); + xtrace_print_arith_cmd(new); + dispose_words(new); + } + + if !exp.is_null() { + expresult = evalexp(exp, EXP_EXPANDED as libc::c_int, &mut expok); + line_number = save_line_number; + free(exp as *mut c_void); + } else { + expresult = 0 as intmax_t; + expok = 1; + } + FREE!(t); + + if expok == 0 { + return EXECUTION_FAILURE as libc::c_int; + } + return if expresult == 0 { + EXECUTION_FAILURE as libc::c_int + } else { + EXECUTION_SUCCESS as libc::c_int + }; + } +} + +static mut nullstr: *mut libc::c_char = b"\0" as *const u8 as *mut libc::c_char; + +fn execute_cond_node(mut cond: *mut COND_COM) -> libc::c_int { + let mut result: libc::c_int = 0; + let mut invert: libc::c_int = 0; + let mut patmatch: libc::c_int = 0; + let mut rmatch: libc::c_int = 0; + let mut mflags: libc::c_int = 0; + let mut ignore: libc::c_int = 0; + let mut arg1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut arg2: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + invert = (*cond).flags & CMD_INVERT_RETURN as libc::c_int; + ignore = (*cond).flags & CMD_IGNORE_RETURN as libc::c_int; + if ignore != 0 { + if !((*cond).left).is_null() { + (*(*cond).left).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + if !((*cond).right).is_null() { + (*(*cond).right).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + } + + if (*cond).type_0 == COND_EXPR as libc::c_int { + result = execute_cond_node((*cond).left); + } else if (*cond).type_0 == COND_OR as libc::c_int { + result = execute_cond_node((*cond).left); + if result != EXECUTION_SUCCESS as libc::c_int { + result = execute_cond_node((*cond).right); + } + } else if (*cond).type_0 == COND_AND as libc::c_int { + result = execute_cond_node((*cond).left); + if result == EXECUTION_SUCCESS as libc::c_int { + result = execute_cond_node((*cond).right); + } + } else if (*cond).type_0 == COND_UNARY as libc::c_int { + if ignore != 0 { + comsub_ignore_return += 1; + } + arg1 = cond_expand_word((*(*cond).left).op, 0); + if ignore != 0 { + comsub_ignore_return -= 1; + } + if arg1.is_null() { + arg1 = nullstr; + } + if echo_command_at_execute != 0 { + xtrace_print_cond_term( + (*cond).type_0, + invert, + (*cond).op, + arg1, + 0 as *mut libc::c_char, + ); + } + result = if unary_test((*(*cond).op).word, arg1) != 0 { + EXECUTION_SUCCESS as libc::c_int + } else { + EXECUTION_FAILURE as libc::c_int + }; + if arg1 != nullstr { + free(arg1 as *mut c_void); + } + } else if (*cond).type_0 == COND_BINARY as libc::c_int { + rmatch = 0; + patmatch = (*((*(*cond).op).word).offset(1 as isize) as libc::c_int == '=' as i32 + && *((*(*cond).op).word).offset(2 as isize) as libc::c_int == '\u{0}' as i32 + && (*((*(*cond).op).word).offset(0 as isize) as libc::c_int == '!' as i32 + || *((*(*cond).op).word).offset(0 as isize) as libc::c_int == '=' as i32) + || *((*(*cond).op).word).offset(0 as isize) as libc::c_int == '=' as i32 + && *((*(*cond).op).word).offset(1 as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int; + rmatch = (*((*(*cond).op).word).offset(0 as isize) as libc::c_int == '=' as i32 + && *((*(*cond).op).word).offset(1 as isize) as libc::c_int == '~' as i32 + && *((*(*cond).op).word).offset(2 as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int; + + if ignore != 0 { + comsub_ignore_return += 1; + } + arg1 = cond_expand_word((*(*cond).left).op, 0); + if ignore != 0 { + comsub_ignore_return -= 1; + } + if arg1.is_null() { + arg1 = nullstr; + } + if ignore != 0 { + comsub_ignore_return += 1; + } + arg2 = cond_expand_word( + (*(*cond).right).op, + if rmatch != 0 && shell_compatibility_level > 31 { + 2 + } else if patmatch != 0 { + 1 + } else { + 0 + }, + ); + if ignore != 0 { + comsub_ignore_return -= 1; + } + if arg2.is_null() { + arg2 = nullstr; + } + + if echo_command_at_execute != 0 { + xtrace_print_cond_term((*cond).type_0, invert, (*cond).op, arg1, arg2); + } + + if rmatch != 0 { + mflags = SHMAT_PWARN as libc::c_int; + mflags |= SHMAT_SUBEXP as libc::c_int; + result = sh_regmatch(arg1, arg2, mflags); + } else { + let mut oe: libc::c_int = 0; + + oe = extended_glob; + extended_glob = 1; + result = if binary_test( + (*(*cond).op).word, + arg1, + arg2, + TEST_PATMATCH as libc::c_int + | TEST_ARITHEXP as libc::c_int + | TEST_LOCALE as libc::c_int, + ) != 0 + { + EXECUTION_SUCCESS as libc::c_int + } else { + EXECUTION_FAILURE as libc::c_int + }; + extended_glob = oe; + } + if arg1 != nullstr { + free(arg1 as *mut c_void); + } + if arg2 != nullstr { + free(arg2 as *mut c_void); + } + } else { + command_error( + b"execute_cond_node\0" as *const u8 as *const libc::c_char, + CMDERR_BADTYPE as libc::c_int, + (*cond).type_0, + 0, + ); + jump_to_top_level(DISCARD as libc::c_int); + result = EXECUTION_FAILURE as libc::c_int; + } + if invert != 0 { + result = if result == EXECUTION_FAILURE as libc::c_int { + EXECUTION_FAILURE as libc::c_int + } else { + EXECUTION_SUCCESS as libc::c_int + }; + } + } + return result; +} + +fn execute_cond_command(mut cond_command: *mut COND_COM) -> libc::c_int { + let mut retval: libc::c_int = 0; + let mut save_line_number: libc::c_int = 0; + unsafe { + save_line_number = line_number; + this_command_name = b"[[\0" as *const u8 as *mut libc::c_char; + line_number = (*cond_command).line; + line_number_for_err_trap = line_number; + if variable_context != 0 && interactive_shell != 0 && sourcelevel == 0 { + line_number -= function_line_number - 1; + if line_number <= 0 { + line_number = 1; + } + } + + command_string_index = 0; + print_cond_command(cond_command); + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + FREE!(the_printed_command_except_trap); + the_printed_command_except_trap = savestring!(the_printed_command) + } + + retval = run_debug_trap(); + if debugging_mode != 0 && retval != EXECUTION_SUCCESS as libc::c_int { + line_number = save_line_number; + return EXECUTION_SUCCESS as libc::c_int; + } + retval = execute_cond_node(cond_command); + last_command_exit_value = retval; + line_number = save_line_number; + } + return retval; +} + +fn bind_lastarg(mut arg: *mut libc::c_char) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + if arg.is_null() { + arg = b"\0" as *const u8 as *mut libc::c_char; + } + var = bind_variable(b"_\0" as *const u8 as *const libc::c_char, arg, 0); + + if !var.is_null() { + unsafe { + VUNSETATTR!(var, att_exported); + } + } +} + +fn execute_null_command( + mut redirects: *mut REDIRECT, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut async_0: libc::c_int, +) -> libc::c_int { + let mut r: libc::c_int = 0; + let mut forcefork: libc::c_int = 0; + let mut fork_flags: libc::c_int = 0; + let mut rd: *mut REDIRECT = 0 as *mut REDIRECT; + + forcefork = 0; + rd = redirects; + unsafe { + while !rd.is_null() { + forcefork += (*rd).rflags & REDIR_VARASSIGN as libc::c_int; + forcefork += ((*rd).redirector.dest == 0 + || fd_is_bash_input((*rd).redirector.dest) != 0 + && INPUT_REDIRECT!((*rd).instruction) + || TRANSLATE_REDIRECT!((*rd).instruction) + || (*rd).instruction == r_instruction_r_close_this) + as libc::c_int; + rd = (*rd).next; + } + + if forcefork != 0 || pipe_in != NO_PIPE || pipe_out != NO_PIPE || async_0 != 0 { + fork_flags = if async_0 != 0 { + FORK_ASYNC as libc::c_int + } else { + 0 + }; + if make_child(0 as *mut libc::c_char, fork_flags) == 0 { + restore_original_signals(); + do_piping(pipe_in, pipe_out); + coproc_closeall(); + + interactive = 0; + + subshell_environment = 0; + if async_0 != 0 { + subshell_environment |= SUBSHELL_ASYNC as libc::c_int; + } + if pipe_in != NO_PIPE || pipe_out != NO_PIPE { + subshell_environment |= SUBSHELL_PIPE as libc::c_int; + } + if do_redirections(redirects, RX_ACTIVE as libc::c_int) == 0 { + exit(EXECUTION_SUCCESS as libc::c_int); + } else { + exit(EXECUTION_FAILURE as libc::c_int); + } + } else { + close_pipes(pipe_in, pipe_out); + if pipe_out == NO_PIPE { + unlink_fifo_list(); + } + return EXECUTION_SUCCESS as libc::c_int; + } + } else { + r = do_redirections( + redirects, + RX_ACTIVE as libc::c_int | RX_UNDOABLE as libc::c_int, + ); + cleanup_redirects(redirection_undo_list); + redirection_undo_list = 0 as *mut REDIRECT; + + if r != 0 { + return EXECUTION_FAILURE as libc::c_int; + } else if last_command_subst_pid != NO_PID!() { + return last_command_exit_value; + } else { + return EXECUTION_SUCCESS as libc::c_int; + } + }; + } + return 0; +} + +fn fix_assignment_words(mut words: *mut WordList) { + let mut w: *mut WordList = 0 as *mut WordList; + let mut wcmd: *mut WordList = 0 as *mut WordList; + let mut b: *mut builtin = 0 as *mut builtin; + let mut assoc: libc::c_int = 0; + let mut global: libc::c_int = 0; + let mut array: libc::c_int = 0; + let mut integer: libc::c_int = 0; + + if words.is_null() { + return; + } + + b = 0 as *mut builtin; + integer = 0; + array = integer; + global = array; + assoc = global; + + wcmd = words; + wcmd = words; + unsafe { + while !wcmd.is_null() { + if (*(*wcmd).word).flags & W_ASSIGNMENT as libc::c_int == 0 { + break; + } + wcmd = (*wcmd).next; + } + + while posixly_correct != 0 + && !wcmd.is_null() + && !((*wcmd).word).is_null() + && !((*(*wcmd).word).word).is_null() + && STREQ!( + (*(*wcmd).word).word, + b"command\0" as *const u8 as *const libc::c_char + ) + { + wcmd = (*wcmd).next; + } + + w = wcmd; + while !w.is_null() { + if (*(*w).word).flags & W_ASSIGNMENT as libc::c_int != 0 { + if b.is_null() { + b = builtin_address_internal((*(*wcmd).word).word, 0); + if b.is_null() || (*b).flags & ASSIGNMENT_BUILTIN as libc::c_int == 0 { + return; + } else { + if !b.is_null() && (*b).flags & ASSIGNMENT_BUILTIN as libc::c_int != 0 { + (*(*wcmd).word).flags |= W_ASSNBLTIN as libc::c_int; + } + } + } + (*(*w).word).flags |= (W_NOSPLIT as libc::c_int) + | (W_NOGLOB as libc::c_int) + | (W_TILDEEXP as libc::c_int) + | (W_ASSIGNARG as libc::c_int); + if assoc != 0 { + (*(*w).word).flags |= W_ASSIGNASSOC as libc::c_int; + } + if array != 0 { + (*(*w).word).flags |= W_ASSIGNARRAY as libc::c_int; + } + if global != 0 { + (*(*w).word).flags |= W_ASSNGLOBAL as libc::c_int; + } + + if !b.is_null() + && (*b).flags + & (ASSIGNMENT_BUILTIN as libc::c_int | LOCALVAR_BUILTIN as libc::c_int) + == ASSIGNMENT_BUILTIN as libc::c_int + { + (*(*w).word).flags |= W_ASSNGLOBAL as libc::c_int | W_CHKLOCAL as libc::c_int; + } else if !b.is_null() + && (*b).flags & ASSIGNMENT_BUILTIN as libc::c_int != 0 + && (*b).flags & LOCALVAR_BUILTIN as libc::c_int != 0 + && variable_context != 0 + { + (*(*w).word).flags |= W_FORCELOCAL as libc::c_int; + } + } else if *((*(*w).word).word).offset(0 as isize) as libc::c_int == '-' as i32 + && !(strpbrk( + ((*(*w).word).word).offset(1 as isize), + b"Aag\0" as *const u8 as *const libc::c_char, + )) + .is_null() + { + if b.is_null() { + b = builtin_address_internal((*(*wcmd).word).word, 0); + if b.is_null() || (*b).flags & ASSIGNMENT_BUILTIN as libc::c_int == 0 { + return; + } else { + if !b.is_null() && (*b).flags & ASSIGNMENT_BUILTIN as libc::c_int != 0 { + (*(*wcmd).word).flags |= W_ASSNBLTIN as libc::c_int; + } + } + } + if (*(*wcmd).word).flags & W_ASSNBLTIN as libc::c_int != 0 + && !(strchr(((*(*w).word).word).offset(1 as isize), 'A' as i32)).is_null() + { + assoc = 1; + } else if (*(*wcmd).word).flags & W_ASSNBLTIN as libc::c_int != 0 + && !(strchr( + ((*(*w).word).word).offset(1 as libc::c_int as isize), + 'a' as i32, + )) + .is_null() + { + array = 1; + } + if (*(*wcmd).word).flags & W_ASSNBLTIN as libc::c_int != 0 + && !(strchr(((*(*w).word).word).offset(1 as isize), 'g' as i32)).is_null() + { + global = 1; + } + } + w = (*w).next; + } + } +} + +// #[macro_export] +// macro_rules! ISOPTION { +// ($s:expr, $c:expr) => { +// (*$s.offset(0 as isize) as libc::c_int == '-' as i32 +// && *$s.offset(1 as isize) as libc::c_int == $c as i32 +// && *$s.offset(2 as isize) == 0) +// }; +// } + +fn check_command_builtin(mut words: *mut WordList, mut typep: *mut libc::c_int) -> *mut WordList { + let mut type_0: libc::c_int = 0; + let mut w: *mut WordList = 0 as *mut WordList; + + #[macro_export] + macro_rules! RETURN_NOT_COMMAND { + () => { + if !typep.is_null() { + *typep = 0; + } + return words; + }; + } + unsafe { + w = (*words).next; + type_0 = 1; + + if !w.is_null() && ISOPTION!((*(*w).word).word, 'p') { + if restricted != 0 { + RETURN_NOT_COMMAND!(); + } + w = (*w).next; + type_0 = 2; + } + if !w.is_null() && ISOPTION!((*(*w).word).word, '-') { + w = (*w).next; + } else if !w.is_null() + && *((*(*w).word).word).offset(0 as isize) as libc::c_int == '-' as i32 + { + RETURN_NOT_COMMAND!(); + } + if w.is_null() || ((*(*w).word).word).is_null() { + RETURN_NOT_COMMAND!(); + } + + if !typep.is_null() { + *typep = type_0; + } + } + return w; +} + +fn is_dirname(mut pathname: *mut libc::c_char) -> libc::c_int { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: libc::c_int = 0; + unsafe { + temp = search_for_command(pathname, 0); + ret = if !temp.is_null() { + file_isdir(temp) + } else { + file_isdir(pathname) + }; + free(temp as *mut c_void); + } + return ret; +} + +fn execute_simple_command( + mut simple_command: *mut SIMPLE_COM, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut async_0: libc::c_int, + mut fds_to_close: *mut fd_bitmap, +) -> libc::c_int { + unsafe { + let mut current_block: u64; + let mut words: *mut WordList = 0 as *mut WordList; + let mut lastword: *mut WordList = 0 as *mut WordList; + let mut command_line: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lastarg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut first_word_quoted: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut builtin_is_special: libc::c_int = 0; + let mut already_forked: libc::c_int = 0; + let mut dofork: libc::c_int = 0; + let mut fork_flags: libc::c_int = 0; + let mut cmdflags: libc::c_int = 0; + let mut old_last_async_pid: pid_t = 0; + let mut builtin: Option = None; + let mut func: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut old_builtin: libc::c_int = 0; + let mut old_command_builtin: libc::c_int = 0; + + result = EXECUTION_SUCCESS as libc::c_int; + builtin_is_special = 0; + special_builtin_failed = builtin_is_special; + command_line = 0 as *mut libc::c_char; + + QUIT!(); + + if variable_context != 0 && interactive_shell != 0 && sourcelevel == 0 { + line_number -= function_line_number - 1; + if line_number <= 0 { + line_number = 1; + } + } + + command_string_index = 0; + print_simple_command(simple_command); + + if signal_in_progress(DEBUG_TRAP as libc::c_int) == 0 && running_trap == 0 { + if !the_printed_command_except_trap.is_null() { + FREE!(the_printed_command_except_trap); + } + the_printed_command_except_trap = if !the_printed_command.is_null() { + savestring!(the_printed_command) + } else { + 0 as *mut libc::c_char + }; + } + + result = run_debug_trap(); + + if debugging_mode != 0 && result != EXECUTION_SUCCESS as libc::c_int { + return EXECUTION_SUCCESS as libc::c_int; + } + + cmdflags = (*simple_command).flags; + + first_word_quoted = if !((*simple_command).words).is_null() { + (*(*(*simple_command).words).word).flags & W_QUOTED as libc::c_int + } else { + 0 + }; + + last_command_subst_pid = NO_PID!(); + old_last_async_pid = last_asynchronous_pid; + + already_forked = 0; + + dofork = (pipe_in != NO_PIPE as libc::c_int + || pipe_out != NO_PIPE as libc::c_int + || async_0 != 0) as libc::c_int; + + if dofork != 0 + && pipe_in == NO_PIPE as libc::c_int + && pipe_out == NO_PIPE as libc::c_int + && !((*simple_command).words).is_null() + && !((*(*simple_command).words).word).is_null() + && !((*(*(*simple_command).words).word).word).is_null() + && *((*(*(*simple_command).words).word).word).offset(0 as isize) as libc::c_int + == '%' as i32 + { + dofork = 0; + } + + if dofork != 0 { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + + maybe_make_export_env(); + + fork_flags = if async_0 != 0 { + FORK_ASYNC as libc::c_int + } else { + 0 + }; + p = savestring!(the_printed_command_except_trap); + if make_child(p, fork_flags) == 0 { + already_forked = 1; + cmdflags |= CMD_NO_FORK as libc::c_int; + + subshell_environment = SUBSHELL_FORK as libc::c_int; + if pipe_in != NO_PIPE as libc::c_int || pipe_out != NO_PIPE as libc::c_int { + subshell_environment |= SUBSHELL_PIPE as libc::c_int; + } + if async_0 != 0 { + subshell_environment |= SUBSHELL_ASYNC as libc::c_int; + } + + if !fds_to_close.is_null() { + close_fd_bitmap(fds_to_close); + } + + stdin_redir |= (pipe_in != NO_PIPE as libc::c_int) as libc::c_int; + + do_piping(pipe_in, pipe_out); + pipe_out = NO_PIPE as libc::c_int; + pipe_in = pipe_out; + + coproc_closeall(); + last_asynchronous_pid = old_last_async_pid; + + if async_0 != 0 { + subshell_level += 1; + } + FREE!(p); + } else { + if pipe_out != NO_PIPE as libc::c_int { + result = last_command_exit_value; + } + close_pipes(pipe_in, pipe_out); + command_line = 0 as *mut libc::c_char; + return result; + } + } + + QUIT!(); + + if cmdflags & CMD_INHIBIT_EXPANSION as libc::c_int == 0 { + current_fds_to_close = fds_to_close; + fix_assignment_words((*simple_command).words); + + if cmdflags & CMD_IGNORE_RETURN as libc::c_int != 0 { + comsub_ignore_return += 1; + } + + words = expand_words((*simple_command).words); + if cmdflags & CMD_IGNORE_RETURN as libc::c_int != 0 { + comsub_ignore_return -= 1; + } + current_fds_to_close = 0 as *mut fd_bitmap; + } else { + words = copy_word_list((*simple_command).words); + } + + if words.is_null() { + this_command_name = 0 as *mut libc::c_char; + result = execute_null_command( + (*simple_command).redirects, + pipe_in, + pipe_out, + if already_forked != 0 { 0 } else { async_0 }, + ); + + if already_forked != 0 { + sh_exit(result); + } else { + bind_lastarg(0 as *mut libc::c_char); + set_pipestatus_from_exit(result); + return result; + } + } + + lastarg = 0 as *mut libc::c_char; + begin_unwind_frame(b"simple-command\0" as *const u8 as *mut libc::c_char); + + if echo_command_at_execute != 0 && cmdflags & CMD_COMMAND_BUILTIN as libc::c_int == 0 { + xtrace_print_word_list(words, 1); + } + + builtin = None; + + func = 0 as *mut SHELL_VAR; + + if cmdflags & CMD_NO_FUNCTIONS as libc::c_int == 0 { + if posixly_correct != 0 { + builtin = find_special_builtin((*(*words).word).word); + if builtin.is_some() { + builtin_is_special = 1; + } + } + if builtin.is_none() { + func = find_function((*(*words).word).word); + } + } + + if posixly_correct != 0 + && builtin_is_special != 0 + && interactive_shell == 0 + && tempenv_assign_error != 0 + { + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + jump_to_top_level(ERREXIT as libc::c_int); + } + tempenv_assign_error = 0; + old_command_builtin = -1; + + if builtin.is_none() && func.is_null() { + let mut disposer: *mut WordList = 0 as *mut WordList; + let mut l: *mut WordList = 0 as *mut WordList; + let mut cmdtype: libc::c_int = 0; + + builtin = find_shell_builtin((*(*words).word).word); + + while builtin == Some(command_builtin) { + disposer = words; + cmdtype = 0; + words = check_command_builtin(words, &mut cmdtype); + if !(cmdtype > 0) { + break; + } + l = disposer; + while (*l).next != words { + l = (*l).next; + } + + (*l).next = 0 as *mut WordList; + dispose_words(disposer); + cmdflags |= CMD_COMMAND_BUILTIN as libc::c_int | CMD_NO_FUNCTIONS as libc::c_int; + if cmdtype == 2 { + cmdflags |= CMD_STDPATH as libc::c_int; + } + builtin = find_shell_builtin((*(*words).word).word); + } + if cmdflags & CMD_COMMAND_BUILTIN as libc::c_int != 0 { + old_command_builtin = executing_command_builtin; + unwind_protect_mem( + &mut executing_command_builtin as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + executing_command_builtin |= 1; + } + builtin = None; + } + add_unwind_protect( + transmute::>(dispose_words), + words as *mut libc::c_char, + ); + + QUIT!(); + + lastword = words; + while !((*lastword).next).is_null() { + lastword = (*lastword).next; + } + + lastarg = (*(*lastword).word).word; + + if *((*(*words).word).word).offset(0 as isize) as libc::c_int == '%' as i32 + && already_forked == 0 + { + this_command_name = (if async_0 != 0 { + b"bg\0" as *const u8 as *const libc::c_char + } else { + b"fg\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + + last_shell_builtin = this_shell_builtin; + this_shell_builtin = builtin_address(this_command_name); + result = (Some(this_shell_builtin.expect("non-null function pointer"))) + .expect("non-null function pointer")(words); + } else { + if job_control != 0 + && already_forked == 0 + && async_0 == 0 + && first_word_quoted == 0 + && ((*words).next).is_null() + && *((*(*words).word).word).offset(0 as isize) as libc::c_int != 0 + && ((*simple_command).redirects).is_null() + && pipe_in == NO_PIPE as libc::c_int + && pipe_out == NO_PIPE as libc::c_int + && { + temp = get_string_value(b"auto_resume\0" as *const u8 as *const libc::c_char); + !temp.is_null() + } + { + let mut job: libc::c_int = 0; + let mut jflags: libc::c_int = 0; + let mut started_status: libc::c_int = 0; + + jflags = JM_STOPPED as libc::c_int | JM_FIRSTMATCH as libc::c_int; + if STREQ!(temp, b"exact" as *const u8 as *mut libc::c_char) { + jflags |= JM_EXACT as libc::c_int; + } else if STREQ!(temp, b"substring" as *const u8 as *mut libc::c_char) { + jflags |= JM_SUBSTRING as libc::c_int; + } else { + jflags |= JM_PREFIX as libc::c_int; + } + job = get_job_by_name((*(*words).word).word, jflags); + if job != NO_JOB { + run_unwind_frame(b"simple-command\0" as *const u8 as *mut libc::c_char); + this_command_name = b"fg\0" as *const u8 as *mut libc::c_char; + last_shell_builtin = this_shell_builtin; + this_shell_builtin = builtin_address(b"fg\0" as *const u8 as *mut libc::c_char); + + started_status = start_job(job, 1); + return if started_status < 0 { + EXECUTION_FAILURE as libc::c_int + } else { + started_status + }; + } + } + loop { + this_command_name = (*(*words).word).word; + + QUIT!(); + + if func.is_null() && builtin.is_none() { + builtin = find_shell_builtin(this_command_name); + } + + last_shell_builtin = this_shell_builtin; + this_shell_builtin = builtin; + + if builtin.is_some() || !func.is_null() { + if builtin.is_some() { + old_builtin = executing_builtin; + unwind_protect_mem( + &mut executing_builtin as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + if old_command_builtin == -1 { + old_command_builtin = executing_command_builtin; + unwind_protect_mem( + &mut executing_command_builtin as *mut libc::c_int + as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong + as libc::c_int, + ); + } + } + if already_forked != 0 { + reset_signal_handlers(); + subshell_environment |= SUBSHELL_RESETTRAP as libc::c_int; + if async_0 != 0 { + if cmdflags & CMD_STDIN_REDIR as libc::c_int != 0 + && pipe_in == NO_PIPE + && stdin_redirects((*simple_command).redirects) == 0 + { + async_redirect_stdin(); + } + setup_async_signals(); + } + if async_0 == 0 { + subshell_level += 1; + } + execute_subshell_builtin_or_function( + words, + (*simple_command).redirects, + builtin, + func, + pipe_in, + pipe_out, + async_0, + fds_to_close, + cmdflags, + ); + subshell_level -= 1; + } else { + result = execute_builtin_or_function( + words, + builtin, + func, + (*simple_command).redirects, + fds_to_close, + cmdflags, + ); + if builtin.is_some() { + current_block = 2525024825076287515; + break; + } else { + current_block = 2149547614657787525; + break; + } + } + } + if !(autocd != 0 + && interactive != 0 + && !((*words).word).is_null() + && is_dirname((*(*words).word).word) != 0) + { + current_block = 5373862753408874748; + break; + } + words = make_word_list( + make_word(b"--\0" as *const u8 as *const libc::c_char), + words, + ); + words = make_word_list( + make_word(b"cd\0" as *const u8 as *const libc::c_char), + words, + ); + xtrace_print_word_list(words, 0 as libc::c_int); + func = find_function(b"cd\0" as *const u8 as *const libc::c_char); + } + match current_block { + 2525024825076287515 => { + if result > EX_SHERRBASE as libc::c_int { + match result { + EX_REDIRFAIL!() | EX_BADASSIGN!() | EX_EXPFAIL!() => { + if posixly_correct != 0 + && builtin_is_special != 0 + && interactive_shell == 0 + { + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + jump_to_top_level(ERREXIT as libc::c_int); + } + current_block = 5872168878400681860; + } + EX_DISKFALLBACK!() => { + executing_builtin = old_builtin; + executing_command_builtin = old_command_builtin; + builtin = None; + current_block = 5373862753408874748; + } + _ => { + current_block = 5872168878400681860; + } + } + match current_block { + 5373862753408874748 => {} + _ => { + result = builtin_status(result); + if builtin_is_special != 0 { + special_builtin_failed = 1 as libc::c_int; + } + current_block = 8487579351791723214; + } + } + } else { + current_block = 8487579351791723214; + } + match current_block { + 5373862753408874748 => {} + _ => { + if posixly_correct != 0 + && builtin_is_special != 0 + && !temporary_env.is_null() + { + merge_temporary_env(); + } + current_block = 11272946706888692785; + } + } + } + 2149547614657787525 => { + if result == EX_USAGE as libc::c_int { + result = EX_BADUSAGE as libc::c_int; + } else if result > EX_SHERRBASE as libc::c_int { + result = builtin_status(result); + } + current_block = 11272946706888692785; + } + _ => {} + } + match current_block { + 11272946706888692785 => { + set_pipestatus_from_exit(result); + } + _ => { + if command_line.is_null() { + command_line = savestring!(if !the_printed_command_except_trap.is_null() { + the_printed_command_except_trap + } else { + b"\0" as *const u8 as *const libc::c_char + }); + } + if already_forked == 0 as libc::c_int + && cmdflags & 0x40 as libc::c_int != 0 + && fifos_pending() > 0 as libc::c_int + { + cmdflags &= !(0x40 as libc::c_int); + } + result = execute_disk_command( + words, + (*simple_command).redirects, + command_line, + pipe_in, + pipe_out, + async_0, + fds_to_close, + cmdflags, + ); + } + } + } + bind_lastarg(lastarg); + FREE!(command_line); + dispose_words(words); + if builtin.is_some() { + executing_builtin = old_builtin; + executing_command_builtin = old_command_builtin; + } + discard_unwind_frame(b"simple-command\0" as *const u8 as *mut libc::c_char); + this_command_name = 0 as *mut libc::c_char; + + return result; + } +} + +fn builtin_status(mut result: libc::c_int) -> libc::c_int { + let mut r: libc::c_int = 0; + + match result as libc::c_uint { + EX_USAGE!() | EX_BADSYNTAX => { + r = EX_BADUSAGE as libc::c_int; + } + EX_REDIRFAIL | EX_BADASSIGN!() | EX_EXPFAIL => { + r = EXECUTION_FAILURE as libc::c_int; + } + _ => { + r = if result > EX_SHERRBASE as libc::c_int { + EXECUTION_FAILURE as libc::c_int + } else { + 0 as libc::c_int + }; + } + } + return r; +} + +#[macro_export] +macro_rules! unwind_protect_int { + ($var:expr) => { + unwind_protect_mem( + &mut $var as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + }; +} + +fn execute_builtin( + mut builtin: Option, + // mut builtin: sh_builtin_func_t, + mut words: *mut WordList, + mut flags: libc::c_int, + mut subshell: libc::c_int, +) -> libc::c_int { + unsafe { + let mut result: libc::c_int = 0; + let mut eval_unwind: libc::c_int = 0; + let mut ignexit_flag: libc::c_int = 0; + let mut isbltinenv: libc::c_int = 0; + let mut should_keep: libc::c_int = 0; + let mut error_trap: *mut libc::c_char = 0 as *mut libc::c_char; + + error_trap = 0 as *mut libc::c_char; + should_keep = 0 as libc::c_int; + + if subshell == 0 + && flags & CMD_IGNORE_RETURN as libc::c_int != 0 + && (builtin == Some(eval_builtin) + || flags & 0x800 as libc::c_int != 0 + || builtin == Some(source_builtin)) + { + begin_unwind_frame( + b"eval_builtin\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + unwind_protect_mem( + &mut exit_immediately_on_error as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut builtin_ignoring_errexit as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + error_trap = TRAP_STRING!(ERROR_TRAP as libc::c_int); + if !error_trap.is_null() { + error_trap = savestring!(error_trap); + add_unwind_protect( + transmute::< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + Option, + >(libc::free), + error_trap, + ); + add_unwind_protect( + transmute::>( + set_error_trap, + ), + error_trap, + ); + restore_default_signal(ERROR_TRAP as libc::c_int); + } + exit_immediately_on_error = 0; + ignexit_flag = builtin_ignoring_errexit; + builtin_ignoring_errexit = 1; + eval_unwind = 1; + } else { + eval_unwind = 0; + } + + isbltinenv = (builtin == Some(source_builtin) + || builtin == Some(eval_builtin) + || builtin == Some(unset_builtin) + || builtin == Some(mapfile_builtin)) as libc::c_int; + should_keep = (isbltinenv != 0 && builtin != Some(mapfile_builtin)) as libc::c_int; + if builtin == Some(fc_builtin) || builtin == Some(read_builtin) { + isbltinenv = 1; + should_keep = 0; + } + + if isbltinenv != 0 { + if subshell == 0 { + begin_unwind_frame( + b"builtin_env\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + if !temporary_env.is_null() { + push_scope(VC_BLTNENV as libc::c_int, temporary_env); + if flags & CMD_COMMAND_BUILTIN as libc::c_int != 0 { + should_keep = 0; + } + if subshell == 0 { + add_unwind_protect( + transmute::>(pop_scope), + if should_keep != 0 { + b"1\0" as *const u8 as *mut libc::c_char + } else { + 0 as *mut libc::c_char + }, + ); + } + temporary_env = 0 as *mut HASH_TABLE; + } + } + + if subshell == 0 && builtin == Some(eval_builtin) { + if evalnest_max > 0 && evalnest >= evalnest_max { + internal_error( + b"eval: maximum eval nesting level exceeded (%d)\0" as *const u8 + as *mut libc::c_char, + evalnest, + ); + evalnest = 0; + jump_to_top_level(DISCARD as libc::c_int); + } + unwind_protect_int!(evalnest); + evalnest += 1; + } else if subshell == 0 && builtin == Some(source_builtin) { + if sourcenest_max > 0 && sourcenest >= sourcenest_max { + internal_error( + b"%s: maximum source nesting level exceeded (%d)\0" as *const u8 + as *mut libc::c_char, + this_command_name, + sourcenest, + ); + sourcenest = 0; + jump_to_top_level(DISCARD as libc::c_int); + } + unwind_protect_int!(sourcenest); + sourcenest += 1; + } + + if posixly_correct != 0 + && subshell == 0 + && builtin == Some(return_builtin) + && flags & 0x800 as libc::c_int == 0 as libc::c_int + && !temporary_env.is_null() + { + begin_unwind_frame(b"return_temp_env\0" as *const u8 as *mut libc::c_char); + add_unwind_protect( + transmute::>(merge_temporary_env), + 0 as *mut libc::c_char, + ); + } + + executing_builtin += 1; + executing_command_builtin |= (builtin == Some(command_builtin)) as libc::c_int; + + result = exec_cmd((*(*words).word).word, (*words).next); + + if posixly_correct != 0 + && subshell == 0 + && builtin == Some(return_builtin) + && !temporary_env.is_null() + { + discard_unwind_frame(b"return_temp_env\0" as *const u8 as *mut libc::c_char); + } + if subshell == 0 && isbltinenv != 0 { + run_unwind_frame(b"builtin_env\0" as *const u8 as *mut libc::c_char); + } + if eval_unwind != 0 { + builtin_ignoring_errexit = ignexit_flag; + exit_immediately_on_error = if builtin_ignoring_errexit != 0 { + 0 + } else { + errexit_flag + }; + if !error_trap.is_null() { + set_error_trap(error_trap); + free(error_trap as *mut c_void); + } + discard_unwind_frame(b"eval_builtin\0" as *const u8 as *mut libc::c_char); + } + return result; + } +} + +fn maybe_restore_getopt_state(mut gs: *mut sh_getopt_state_t) { + unsafe { + if (*gs).gs_flags & 1 != 0 { + sh_getopt_restore_istate(gs); + } else { + free(gs as *mut c_void); + }; + } +} + +#[no_mangle] +pub fn restore_funcarray_state(mut fa: *mut func_array_state) { + let mut nfv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut funcname_a: *mut ARRAY = 0 as *mut ARRAY; + unsafe { + array_pop!((*fa).source_a); + array_pop!((*fa).lineno_a); + + GET_ARRAY_FROM_VAR!( + b"FUNCNAME\0" as *const u8 as *const libc::c_char, + nfv, + funcname_a + ); + if nfv == (*fa).funcname_v { + array_pop!(funcname_a); + } + free(fa as *mut c_void); + } +} + +fn execute_function( + mut var: *mut SHELL_VAR, + mut words: *mut WordList, + mut flags: libc::c_int, + mut fds_to_close: *mut fd_bitmap, + mut async_0: libc::c_int, + mut subshell: libc::c_int, +) -> libc::c_int { + let mut return_val: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut tc: *mut COMMAND = 0 as *mut COMMAND; + let mut fc: *mut COMMAND = 0 as *mut COMMAND; + let mut save_current: *mut COMMAND = 0 as *mut COMMAND; + let mut debug_trap: *mut libc::c_char = 0 as *mut libc::c_char; + let mut error_trap: *mut libc::c_char = 0 as *mut libc::c_char; + let mut return_trap: *mut libc::c_char = 0 as *mut libc::c_char; + let mut funcname_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_source_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_lineno_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut funcname_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_source_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_lineno_a: *mut ARRAY = 0 as *mut ARRAY; + let mut fa: *mut func_array_state = 0 as *mut func_array_state; + let mut shell_fn: *mut FUNCTION_DEF = 0 as *mut FUNCTION_DEF; + let mut sfile: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut gs: *mut sh_getopt_state_t = 0 as *mut sh_getopt_state_t; + let mut gv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + // USE_VAR!(fc); + + if funcnest_max > 0 && funcnest >= funcnest_max { + internal_error( + b"%s: maximum function nesting level exceeded (%d)\0" as *const u8 + as *mut libc::c_char, + (*var).name, + funcnest, + ); + funcnest = 0; + jump_to_top_level(DISCARD as libc::c_int); + } + + GET_ARRAY_FROM_VAR!( + b"FUNCNAME\0" as *const u8 as *const libc::c_char, + funcname_v, + funcname_a + ); + GET_ARRAY_FROM_VAR!( + b"BASH_SOURCE\0" as *const u8 as *const libc::c_char, + bash_source_v, + bash_source_a + ); + GET_ARRAY_FROM_VAR!( + b"BASH_LINENO\0" as *const u8 as *const libc::c_char, + bash_lineno_v, + bash_lineno_a + ); + + tc = copy_command((*var).value as *mut COMMAND); + if !tc.is_null() && flags & CMD_IGNORE_RETURN as libc::c_int != 0 { + (*tc).flags |= CMD_IGNORE_RETURN as libc::c_int; + } + + if !tc.is_null() + && flags & CMD_NO_FORK as libc::c_int != 0 + && subshell_environment & SUBSHELL_COMSUB as libc::c_int != 0 + { + optimize_shell_function(tc); + } + + gs = sh_getopt_save_istate(); + if subshell == 0 { + begin_unwind_frame(b"function_calling\0" as *const u8 as *mut libc::c_char); + push_context((*var).name, subshell, temporary_env); + + add_unwind_protect( + transmute:: (), Option>( + maybe_restore_getopt_state, + ), + gs as *mut libc::c_char, + ); + add_unwind_protect( + transmute::>(pop_context), + 0 as *mut libc::c_char, + ); + unwind_protect_int!(line_number); + unwind_protect_int!(line_number_for_err_trap); + unwind_protect_int!(function_line_number); + unwind_protect_int!(return_catch_flag); + + unwind_protect_mem( + &mut return_catch as *mut sigjmp_buf as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + + add_unwind_protect( + transmute::>(dispose_command), + tc as *mut libc::c_char, + ); + unwind_protect_mem( + &mut this_shell_function as *mut *mut SHELL_VAR as *mut libc::c_char, + ::std::mem::size_of::<*mut SHELL_VAR>() as libc::c_ulong as libc::c_int, + ); + unwind_protect_int!(funcnest); + unwind_protect_int!(loop_level); + } else { + push_context((*var).name, subshell, temporary_env); + } + + temporary_env = 0 as *mut HASH_TABLE; + + this_shell_function = var; + make_funcname_visible(1); + + debug_trap = TRAP_STRING!((64 + 1) as libc::c_int); + error_trap = TRAP_STRING!(((64 + 1) + 1) as libc::c_int); + return_trap = TRAP_STRING!(((64 + 1) + 2) as libc::c_int); + + if !debug_trap.is_null() && (trace_p!(var) == 0 && function_trace_mode == 0) { + if subshell == 0 { + debug_trap = savestring!(debug_trap); + add_unwind_protect( + transmute::< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + Option, + >(libc::free), + debug_trap, + ); + add_unwind_protect( + transmute::>( + maybe_set_debug_trap, + ), + debug_trap, + ); + } + restore_default_signal((64 + 1) as libc::c_int); + } + + if !error_trap.is_null() && error_trace_mode == 0 { + if subshell == 0 { + error_trap = savestring!(error_trap); + add_unwind_protect( + transmute::< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + Option, + >(libc::free), + error_trap, + ); + add_unwind_protect( + transmute::>( + maybe_set_error_trap, + ), + error_trap, + ); + } + restore_default_signal(((64 + 1) + 1) as libc::c_int); + } + + if !return_trap.is_null() + && (signal_in_progress(DEBUG_TRAP as libc::c_int) != 0 + || trace_p!(var) == 0 && function_trace_mode == 0) + { + if subshell == 0 { + return_trap = savestring!(return_trap); + add_unwind_protect( + transmute::< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + Option, + >(libc::free), + return_trap, + ); + add_unwind_protect( + transmute::>( + maybe_set_return_trap, + ), + return_trap, + ); + } + restore_default_signal(((64 + 1) + 2) as libc::c_int); + } + + funcnest += 1; + + shell_fn = find_function_def((*this_shell_function).name); + sfile = (if !shell_fn.is_null() { + (*shell_fn).source_file + } else { + b"\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + array_push!(funcname_a, (*this_shell_function).name); + array_push!(bash_source_a, sfile); + t = itos(executing_line_number() as intmax_t); + array_push!(bash_lineno_a, t); + free(t as *mut c_void); + + fa = libc::malloc(size_of::()) as *mut func_array_state; + (*fa).source_a = bash_source_a as *mut ARRAY; + (*fa).source_v = bash_source_v; + (*fa).lineno_a = bash_lineno_a as *mut ARRAY; + (*fa).lineno_v = bash_lineno_v; + (*fa).funcname_a = funcname_a; + (*fa).funcname_v = funcname_v; + + if subshell == 0 as libc::c_int { + add_unwind_protect( + transmute:: (), Option>( + restore_funcarray_state, + ), + fa as *mut libc::c_char, + ); + } + + if debugging_mode != 0 || shell_compatibility_level <= 44 { + init_bash_argv(); + } + + remember_args((*words).next, 1); + + if debugging_mode != 0 { + push_args((*words).next); + if subshell == 0 { + add_unwind_protect( + transmute::>(pop_args), + 0 as *mut libc::c_char, + ); + } + } + + function_line_number = (*tc).line; + line_number = function_line_number; + + if subshell != 0 { + stop_pipeline(async_0, 0 as *mut COMMAND); + } + if shell_compatibility_level > 43 { + loop_level = 0; + } + + fc = tc; + + from_return_trap = 0; + + return_catch_flag += 1; + return_val = setjmp_nosigs!(return_catch.as_mut_ptr()); + + if return_val != 0 { + result = return_catch_value; + save_current = currently_executing_command; + if from_return_trap == 0 { + run_return_trap(); + } + currently_executing_command = save_current; + } else { + showing_function_line = 1; + save_current = currently_executing_command; + result = run_debug_trap(); + if debugging_mode == 0 || result == EXECUTION_SUCCESS as libc::c_int { + showing_function_line = 0; + currently_executing_command = save_current; + result = execute_command_internal(fc, 0, NO_PIPE, NO_PIPE, fds_to_close); + + save_current = currently_executing_command; + run_return_trap(); + currently_executing_command = save_current; + } + + showing_function_line = 0; + } + gv = find_variable(b"OPTIND\0" as *const u8 as *const libc::c_char); + if !gv.is_null() && (*gv).context == variable_context { + (*gs).gs_flags |= 1; + } + + if subshell == 0 { + run_unwind_frame( + b"function_calling\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else { + restore_funcarray_state(fa); + if debugging_mode != 0 { + pop_args(); + } + } + if variable_context == 0 || this_shell_function.is_null() { + make_funcname_visible(0); + unlink_fifo_list(); + } + } + return result; +} + +#[no_mangle] +pub fn execute_shell_function(mut var: *mut SHELL_VAR, mut words: *mut WordList) -> libc::c_int { + let mut ret: libc::c_int = 0; + let mut bitmap: *mut fd_bitmap = 0 as *mut fd_bitmap; + unsafe { + bitmap = new_fd_bitmap(FD_BITMAP_DEFAULT_SIZE!()); + begin_unwind_frame(b"execute-shell-function\0" as *const u8 as *mut libc::c_char); + add_unwind_protect( + transmute::>(dispose_fd_bitmap), + bitmap as *mut libc::c_char, + ); + + ret = execute_function(var, words, 0, bitmap, 0, 0); + + dispose_fd_bitmap(bitmap); + discard_unwind_frame( + b"execute-shell-function\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + return ret; +} + +fn execute_subshell_builtin_or_function( + mut words: *mut WordList, + mut redirects: *mut REDIRECT, + mut builtin: Option, + mut var: *mut SHELL_VAR, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut async_0: libc::c_int, + mut fds_to_close: *mut fd_bitmap, + mut flags: libc::c_int, +) { + let mut result: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut funcvalue: libc::c_int = 0; + let mut jobs_hack: libc::c_int = 0; + unsafe { + jobs_hack = (builtin == Some(jobs_builtin) + && (subshell_environment & 0x1 as libc::c_int == 0 as libc::c_int + || pipe_out != -(1 as libc::c_int))) as libc::c_int; + interactive = 0 as libc::c_int; + login_shell = interactive; + if builtin == Some(eval_builtin) { + evalnest = 0 as libc::c_int; + } else if builtin == Some(source_builtin) { + sourcenest = 0; + } + if async_0 != 0 { + subshell_environment |= SUBSHELL_ASYNC as libc::c_int; + } + if pipe_in != NO_PIPE || pipe_out != NO_PIPE { + subshell_environment |= SUBSHELL_PIPE as libc::c_int; + } + + maybe_make_export_env(); + + if jobs_hack != 0 { + kill_current_pipeline(); + } else { + without_job_control(); + } + + set_sigchld_handler(); + + set_sigint_handler(); + + if !fds_to_close.is_null() { + close_fd_bitmap(fds_to_close); + } + + do_piping(pipe_in, pipe_out); + + if do_redirections(redirects, RX_ACTIVE as libc::c_int) != 0 { + exit(EXECUTION_FAILURE as libc::c_int); + } + if builtin.is_some() { + result = setjmp_nosigs!(top_level.as_mut_ptr()); + funcvalue = 0; + if return_catch_flag != 0 && builtin == Some(return_builtin) { + funcvalue = setjmp_nosigs!(return_catch.as_mut_ptr()); + } + + if result == EXITPROG as libc::c_int { + subshell_exit(last_command_exit_value); + } else if result != 0 { + subshell_exit(EXECUTION_FAILURE as libc::c_int); + } else if funcvalue != 0 { + subshell_exit(return_catch_value); + } else { + r = execute_builtin(builtin, words, flags, 1); + fflush(stdout); + if r == EX_USAGE as libc::c_int { + r = EX_BADUSAGE as libc::c_int; + } else if r == EX_DISKFALLBACK as libc::c_int { + let mut command_line: *mut libc::c_char = 0 as *mut libc::c_char; + savestring!(if !the_printed_command_except_trap.is_null() { + the_printed_command_except_trap + } else { + b"\0" as *const u8 as *mut libc::c_char + }); + r = execute_disk_command( + words, + 0 as *mut REDIRECT, + command_line, + -1, + -1, + async_0, + 0 as *mut fd_bitmap, + flags | CMD_NO_FORK as libc::c_int, + ); + } + subshell_exit(r); + } + } else { + r = execute_function(var, words, flags, fds_to_close, async_0, 1); + fflush(stdout); + subshell_exit(r); + }; + } +} + +fn execute_builtin_or_function( + mut words: *mut WordList, + mut builtin: Option, + mut var: *mut SHELL_VAR, + mut redirects: *mut REDIRECT, + mut fds_to_close: *mut fd_bitmap, + mut flags: libc::c_int, +) -> libc::c_int { + let mut result: libc::c_int = 0; + let mut saved_undo_list: *mut REDIRECT = 0 as *mut REDIRECT; + let mut ofifo: libc::c_int = 0; + let mut nfifo: libc::c_int = 0; + let mut osize: libc::c_int = 0; + let mut ofifo_list: *mut libc::c_void = 0 as *mut libc::c_void; + unsafe { + begin_unwind_frame(b"saved_fifos\0" as *const u8 as *mut libc::c_char); + ofifo = num_fifos(); + ofifo_list = copy_fifo_list(&mut osize); + if !ofifo_list.is_null() { + add_unwind_protect( + transmute::< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void), + Option, + >(libc::free), + ofifo_list as *mut libc::c_char, + ); + } + + if do_redirections( + redirects, + RX_ACTIVE as libc::c_int | RX_UNDOABLE as libc::c_int, + ) != 0 + { + undo_partial_redirects(); + dispose_exec_redirects(); + free(ofifo_list as *mut c_void); + return EX_REDIRFAIL as libc::c_int; + } + saved_undo_list = redirection_undo_list; + if builtin == Some(exec_builtin) { + dispose_redirects(saved_undo_list); + saved_undo_list = exec_redirection_undo_list; + exec_redirection_undo_list = 0 as *mut REDIRECT; + } else { + dispose_exec_redirects(); + } + + if !saved_undo_list.is_null() { + begin_unwind_frame(b"saved-redirects\0" as *const u8 as *mut libc::c_char); + add_unwind_protect( + transmute:: (), Option>(cleanup_redirects), + saved_undo_list as *mut libc::c_char, + ); + } + + redirection_undo_list = 0 as *mut REDIRECT; + + if builtin.is_some() { + //tab键出现问题的地方 + result = execute_builtin(builtin, words, flags, 0); + } else { + result = execute_function(var, words, flags, fds_to_close, 0, 0); + } + + fflush(stdout); + fpurge(stdout); + if ferror(stdout) != 0 { + clearerr(stdout); + } + if builtin == Some(command_builtin) && this_shell_builtin == Some(exec_builtin) { + let mut discard: libc::c_int = 0; + + discard = 0; + if !saved_undo_list.is_null() { + dispose_redirects(saved_undo_list); + discard = 1; + } + redirection_undo_list = exec_redirection_undo_list; + exec_redirection_undo_list = 0 as *mut REDIRECT; + saved_undo_list = exec_redirection_undo_list; + if discard != 0 { + discard_unwind_frame(b"saved-redirects\0" as *const u8 as *mut libc::c_char); + } + } + if !saved_undo_list.is_null() { + redirection_undo_list = saved_undo_list; + discard_unwind_frame(b"saved-redirects\0" as *const u8 as *mut libc::c_char); + } + + undo_partial_redirects(); + + nfifo = num_fifos(); + if nfifo > ofifo { + close_new_fifos(ofifo_list, osize); + } + if !ofifo_list.is_null() { + free(ofifo_list as *mut c_void); + } + discard_unwind_frame( + b"saved_fifos\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + return result; +} + +#[no_mangle] +pub fn setup_async_signals() { + unsafe { + if job_control == 0 { + get_original_signal(SIGINT as libc::c_int); + set_signal_handler(SIGINT as libc::c_int, SIG_IGN!()); + get_original_signal(SIGQUIT as libc::c_int); + set_signal_handler(SIGQUIT as libc::c_int, SIG_IGN!()); + } + } +} + +// #[macro_export] +// macro_rules! NOTFOUND_HOOK { +// () => { +// b"command_not_found_handle\0" as *const u8 as *const libc::c_char +// }; +// } + +fn execute_disk_command( + mut words: *mut WordList, + mut redirects: *mut REDIRECT, + mut command_line: *mut libc::c_char, + mut pipe_in: libc::c_int, + mut pipe_out: libc::c_int, + mut async_0: libc::c_int, + mut fds_to_close: *mut fd_bitmap, + mut cmdflags: libc::c_int, +) -> libc::c_int { + let mut pathname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut command: *mut libc::c_char = 0 as *mut libc::c_char; + let mut args: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nofork: libc::c_int = 0; + let mut stdpath: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut fork_flags: libc::c_int = 0; + let mut pid: pid_t = 0; + let mut hookf: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut wl: *mut WordList = 0 as *mut WordList; + unsafe { + // stdpath = cmdflags & 0x4000 as libc::c_int; + nofork = cmdflags & CMD_NO_FORK as libc::c_int; + pathname = (*(*words).word).word; + + p = 0 as *mut libc::c_char; + result = EXECUTION_SUCCESS as libc::c_int; + command = 0 as *mut libc::c_char; + if restricted != 0 && !(mbschr(pathname, '/' as i32)).is_null() { + internal_error( + b"%s: restricted: cannot specify `/' in command names\0" as *const u8 + as *mut libc::c_char, + pathname, + ); + last_command_exit_value = EXECUTION_FAILURE as libc::c_int; + result = last_command_exit_value; + + if nofork != 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE { + exit(last_command_exit_value); + } + } else { + command = search_for_command( + pathname, + CMDSRCH_HASH as libc::c_int + | (if stdpath != 0 { + CMDSRCH_STDPATH as libc::c_int + } else { + 0 + }), + ); + QUIT!(); + + if !command.is_null() { + if nofork != 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE { + adjust_shell_level(-1); + } + maybe_make_export_env(); + put_command_name_into_env(command); + } + + if nofork != 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE { + pid = 0; + } else { + fork_flags = if async_0 != 0 { + FORK_ASYNC as libc::c_int + } else { + 0 + }; + p = savestring!(command_line); + pid = make_child(p, fork_flags); + } + + if pid == 0 { + let mut old_interactive: libc::c_int = 0; + + reset_terminating_signals(); + restore_original_signals(); + + FREE!(p); + + if async_0 != 0 { + if cmdflags & CMD_STDIN_REDIR as libc::c_int != 0 + && pipe_in == NO_PIPE + && stdin_redirects(redirects) == 0 + { + async_redirect_stdin(); + } + setup_async_signals(); + } + + if !fds_to_close.is_null() { + close_fd_bitmap(fds_to_close); + } + + do_piping(pipe_in, pipe_out); + + old_interactive = interactive; + + if async_0 != 0 { + interactive = 0; + } + + subshell_environment |= SUBSHELL_FORK as libc::c_int; + + if !redirects.is_null() && do_redirections(redirects, RX_ACTIVE as libc::c_int) != 0 + { + unlink_fifo_list(); + exit(EXECUTION_FAILURE as libc::c_int); + } + + if async_0 != 0 { + interactive = old_interactive; + } + + if command.is_null() { + hookf = find_function(NOTFOUND_HOOK!()); + if hookf.is_null() { + pathname = printable_filename(pathname, 0); + internal_error( + b"%s: command not found\0" as *const u8 as *mut libc::c_char, + pathname as *mut libc::c_char, + ); + exit(127 as libc::c_int); + } + + without_job_control(); + + set_sigchld_handler(); + + wl = make_word_list(make_word(NOTFOUND_HOOK!()), words); + exit(execute_shell_function(hookf, wl)); + } + args = strvec_from_word_list(words, 0, 0, 0 as *mut libc::c_int); + exit(shell_execve(command, args, export_env)); + } + } + QUIT!(); + + close_pipes(pipe_in, pipe_out); + FREE!(command); + } + return result; +} + +fn getinterp( + mut sample: *mut libc::c_char, + mut sample_len: libc::c_int, + mut endp: *mut libc::c_int, +) -> *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut execname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut start: libc::c_int = 0; + unsafe { + #[macro_export] + macro_rules! STRINGCHAR { + ($ind:expr) => { + $ind < sample_len + && !whitespace!(sample.offset($ind as isize)) + && $ind as libc::c_int != '\n' as i32 + }; + } + + i = 2; + while i < sample_len && whitespace!(*sample.offset(i as isize)) { + i += 1; + } + start = i; + while STRINGCHAR!(i) { + i += 1; + } + execname = substring(sample, start, i); + if !endp.is_null() { + *endp = i; + } + } + return execname; +} + +fn initialize_subshell() { + unsafe { + delete_all_aliases(); + history_lines_this_session = 0; + + without_job_control(); + + set_sigchld_handler(); + init_job_stats(); + + reset_shell_flags(); + reset_shell_options(); + reset_shopt_options(); + + if vc_isbltnenv!(shell_variables) { + shell_variables = (*shell_variables).down; + } + + clear_unwind_protect_list(0); + parse_and_execute_level = 0; + sourcenest = 0; + evalnest = sourcenest; + funcnest = evalnest; + return_catch_flag = funcnest; + variable_context = return_catch_flag; + + executing_list = 0; + if interactive_shell == 0 { + unset_bash_input(0); + } + } +} + +#[no_mangle] +pub fn shell_execve( + mut command: *mut libc::c_char, + mut args: *mut *mut libc::c_char, + mut env: *mut *mut libc::c_char, +) -> libc::c_int { + let mut larray: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut fd: libc::c_int = 0; + let mut sample: [libc::c_char; 128] = [0; 128]; + let mut sample_len: libc::c_int = 0; + unsafe { + //缺少SETOSTYPE(0); 语å¥ï¼Œå› ä¸ºæ‰¾åˆ°å®å®šä¹‰çš„地方å‘现是没有展开的 + execve( + command, + args as *const *const libc::c_char, + env as *const *const libc::c_char, + ); + i = errno!(); + CHECK_TERMSIG!(); + + if i != ENOEXEC!() { + last_command_exit_value = if i == ENOENT!() as libc::c_int { + EX_NOTFOUND as libc::c_int + } else { + EX_NOEXEC as libc::c_int + }; + if file_isdir(command) != 0 { + internal_error( + b"%s: %s\0" as *const u8 as *mut libc::c_char, + command as *mut libc::c_char, + strerror(EISDIR!()), + ); + } else if executable_file(command) == 0 { + errno!() = i; + file_error(command); + } else if i == E2BIG!() || i == ENOMEM!() { + errno!() = i; + file_error(command); + } else { + let mut fd_0: libc::c_int = open(command, O_RDONLY as libc::c_int); + + if fd_0 >= 0 { + sample_len = read( + fd_0, + sample.as_mut_ptr() as *mut libc::c_void, + ::std::mem::size_of::<[libc::c_char; 128]>() as usize, + ) as libc::c_int; + } else { + sample_len = -1; + } + + READ_SAMPLE_BUF!(command, sample, sample_len); //有å¯èƒ½å­˜åœ¨é—®é¢˜ï¼Œå¦‚果存在问题就ä¸ç”¨å®äº† + if sample_len > 0 { + sample[(sample_len - 1) as usize] = '\u{0}' as i32 as libc::c_char; + } + if sample_len > 2 + && sample[0] as libc::c_int == '#' as i32 + && sample[1] as libc::c_int == '!' as i32 + { + let mut interp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ilen: libc::c_int = 0; + + close(fd_0); + interp = getinterp(sample.as_mut_ptr(), sample_len, 0 as *mut libc::c_int); + ilen = strlen(interp) as libc::c_int; + errno!() = i; + if *interp.offset((ilen - 1) as isize) as libc::c_int == '\r' as i32 { + interp = realloc(interp as *mut c_void, (ilen + 2) as usize) + as *mut libc::c_char; + *interp.offset((ilen - 1 as libc::c_int) as isize) = + '^' as i32 as libc::c_char; + *interp.offset(ilen as isize) = 'M' as i32 as libc::c_char; + *interp.offset((ilen + 1 as libc::c_int) as isize) = + '\u{0}' as i32 as libc::c_char; + } + sys_error( + b"%s: %s: bad interpreter\0" as *const u8 as *mut libc::c_char, + command, + if !interp.is_null() { + interp + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + FREE!(interp); + return EX_NOEXEC as libc::c_int; + } + + if fd_0 >= 0 { + close(fd_0); + } + errno!() = i; + file_error(command); + } + return last_command_exit_value; + } + + READ_SAMPLE_BUF!(command, sample, sample_len); + + if sample_len == 0 { + return EXECUTION_SUCCESS as libc::c_int; + } + + if sample_len > 0 { + if check_binary_file(sample.as_mut_ptr(), sample_len) != 0 { + internal_error( + b"%s: cannot execute binary file: %s\0" as *const u8 as *mut libc::c_char, + command, + strerror(i), + ); + errno!() = i; + return EX_BINARY_FILE as libc::c_int; + } + } + + reset_parser(); + initialize_subshell(); + + set_sigint_handler(); + + larray = strvec_len(args) + 1; + args = strvec_resize(args, larray + 1); + + i = larray - 1; + while i != 0 { + *args.offset(i as isize) = *args.offset((i - 1) as isize); + i -= 1; + } + + *args.offset(0 as isize) = shell_name; + *args.offset(1 as isize) = command; + *args.offset(larray as isize) = 0 as *mut libc::c_char; + + if *(*args.offset(0 as isize)).offset(0 as isize) as libc::c_int == '-' as i32 { + *args.offset(0 as isize) = *args.offset(1); + } + if restricted != 0 { + change_flag('r' as i32, '+' as i32); + } + + if !subshell_argv.is_null() { + i = 1; + while i < subshell_argc { + free(subshell_argv.offset(i as isize) as *mut c_void); + i += 1; + } + free(subshell_argv as *mut c_void); + } + dispose_command(currently_executing_command); + currently_executing_command = 0 as *mut libc::c_void as *mut COMMAND; + + subshell_argc = larray; + subshell_argv = args; + subshell_envp = env; + + unbind_args(); + + clear_fifo_list(); + + siglongjmp(subshell_top_level.as_mut_ptr(), 1); + } + return 0; //这个地方c是没有返回值的,如果ä¸åŠ ä¼šæŠ¥é”™ï¼Œä¸æ¸…楚加0 æ˜¯å¦æ­£ç¡® +} + +fn execute_intern_function(mut name: *mut WordDesc, mut funcdef: *mut FUNCTION_DEF) -> libc::c_int { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if check_identifier(name, posixly_correct) == 0 { + if posixly_correct != 0 && interactive_shell == 0 { + last_command_exit_value = EX_BADUSAGE as libc::c_int; + jump_to_top_level(ERREXIT as libc::c_int); + } + return EXECUTION_FAILURE as libc::c_int; + } + + if !(strchr((*name).word, CTLESC!())).is_null() { + t = dequote_escapes((*name).word); + free((*name).word as *mut c_void); + (*name).word = t; + } + + if posixly_correct != 0 && (find_special_builtin((*name).word)).is_some() { + internal_error( + b"`%s': is a special builtin\0" as *const u8 as *mut libc::c_char, + (*name).word, + ); + last_command_exit_value = EX_BADUSAGE as libc::c_int; + jump_to_top_level(if interactive_shell != 0 { + DISCARD as libc::c_int + } else { + ERREXIT as libc::c_int + }); + } + + var = find_function((*name).word); + if !var.is_null() && (readonly_p!(var) != 0 || noassign_p!(var) != 0) { + if readonly_p!(var) != 0 { + internal_error( + b"%s: readonly function\0" as *const u8 as *mut libc::c_char, + (*var).name, + ); + } + return EXECUTION_FAILURE as libc::c_int; + } + bind_function_def((*name).word, funcdef, 1); + bind_function((*name).word, (*funcdef).command); + } + return EXECUTION_SUCCESS as libc::c_int; +} + +fn close_pipes(mut in_0: libc::c_int, mut out: libc::c_int) { + unsafe { + if in_0 >= 0 { + close(in_0); + } + if out >= 0 { + close(out); + } + } +} + +fn dup_error(mut oldd: libc::c_int, mut newd: libc::c_int) { + unsafe { + sys_error( + b"cannot duplicate fd %d to fd %d\0" as *const u8 as *mut libc::c_char, + oldd, + newd, + ); + } +} + +fn do_piping(mut pipe_in: libc::c_int, mut pipe_out: libc::c_int) { + unsafe { + if pipe_in != NO_PIPE { + if dup2(pipe_in, 0) < 0 { + dup_error(pipe_in, 0); + } + if pipe_in > 0 { + close(pipe_in); + } + } + if pipe_out != NO_PIPE { + if pipe_out != REDIRECT_BOTH as libc::c_int { + if dup2(pipe_out, 1) < 0 { + dup_error(pipe_out, 1); + } + if pipe_out == 0 || pipe_out > 1 { + close(pipe_out); + } + } else if dup2(1, 2) < 0 { + dup_error(1, 2); + } + } + } +} diff --git a/utshell-0.5.0/src/expr.rs b/utshell-0.5.0/src/expr.rs new file mode 100644 index 00000000..60bbe06e --- /dev/null +++ b/utshell-0.5.0/src/expr.rs @@ -0,0 +1,1587 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::arrayfunc::{array_variable_name, array_variable_part, get_array_value}; +use crate::error::err_unboundvar; +use crate::general::legal_identifier; +use crate::sig::{jump_to_top_level, top_level_cleanup}; +use crate::src_common::*; +use crate::subst::skipsubscript; +use crate::variables::{ + bind_int_variable, find_variable, find_variable_last_nameref, get_variable_value, + stupidly_hack_special_variables, +}; + +static mut assigntok: libc::c_int = 0; +static mut expression: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +static mut expr_depth: libc::c_int = 0; +static mut tokstr: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +static mut evalbuf: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, +}; 1]; +static mut noeval: libc::c_int = 0; +static mut already_expanded: libc::c_int = 0; +static mut expr_stack: *mut *mut EXPR_CONTEXT = + 0 as *const *mut EXPR_CONTEXT as *mut *mut EXPR_CONTEXT; +static mut lasttok: libc::c_int = 0; +static mut curtok: libc::c_int = 0; +static mut tp: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +static mut tokval: intmax_t = 0; +static mut expr_stack_size: libc::c_int = 0; +static mut lasttp: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +static mut lastlval: lvalue = { + let mut init = lvalue { + tokstr: 0 as *const libc::c_char as *mut libc::c_char, + tokval: 0 as libc::c_int as intmax_t, + tokvar: 0 as *const SHELL_VAR as *mut SHELL_VAR, + ind: -(1 as libc::c_int) as intmax_t, + }; + init +}; + +static mut curlval: lvalue = { + let mut init = lvalue { + tokstr: 0 as *const libc::c_char as *mut libc::c_char, + tokval: 0 as libc::c_int as intmax_t, + tokvar: 0 as *const SHELL_VAR as *mut SHELL_VAR, + ind: -(1 as libc::c_int) as intmax_t, + }; + init +}; + +#[no_mangle] +fn expr_bind_variable(mut lhs: *mut libc::c_char, mut rhs: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut aflags: libc::c_int = 0; + unsafe { + if lhs.is_null() || *lhs as libc::c_int == 0 as libc::c_int { + return; + } + aflags = if assoc_expand_once != 0 && already_expanded != 0 { + ASS_NOEXPAND as libc::c_int + } else { + 0 as libc::c_int + }; + v = bind_int_variable(lhs, rhs, aflags); + if !v.is_null() + && ((*v).attributes & 0x2 as libc::c_int != 0 + || (*v).attributes & 0x4000 as libc::c_int != 0) + { + siglongjmp(evalbuf.as_mut_ptr(), 1 as libc::c_int); + } + stupidly_hack_special_variables(lhs); + } +} + +#[no_mangle] +fn expr_streval( + mut tok: *mut libc::c_char, + mut e: libc::c_int, + mut lvalue: *mut lvalue, +) -> intmax_t { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tval: intmax_t = 0; + let mut initial_depth: libc::c_int = 0; + let mut ind: arrayind_t = 0; + let mut tflag: libc::c_int = 0; + let mut aflag: libc::c_int = 0; + unsafe { + if noeval != 0 { + return 0 as libc::c_int as intmax_t; + } + initial_depth = expr_depth; + tflag = (assoc_expand_once != 0 && already_expanded != 0) as libc::c_int; + aflag = if tflag != 0 { + AV_NOEXPAND as libc::c_int + } else { + 0 as libc::c_int + }; + v = if e == ']' as i32 { + array_variable_part( + tok, + tflag, + 0 as *mut *mut libc::c_char, + 0 as *mut libc::c_int, + ) + } else { + find_variable(tok) + }; + if v.is_null() && e != ']' as i32 { + v = find_variable_last_nameref(tok, 0 as libc::c_int); + } + if (v.is_null() || (*v).attributes & 0x1000 as libc::c_int != 0) + && unbound_vars_is_error != 0 + { + value = if e == ']' as i32 { + array_variable_name( + tok, + tflag, + 0 as *mut *mut libc::c_char, + 0 as *mut libc::c_int, + ) + } else { + tok + }; + set_exit_status(EXECUTION_FAILURE as libc::c_int); + err_unboundvar(value); + if e == ']' as i32 { + if !value.is_null() { + libc::free(value as *mut libc::c_void); + } + } + if no_longjmp_on_fatal_error != 0 && interactive_shell != 0 { + siglongjmp(evalbuf.as_mut_ptr(), 1 as libc::c_int); + } + if interactive_shell != 0 { + expr_unwind(); + top_level_cleanup(); + jump_to_top_level(DISCARD as libc::c_int); + } else { + jump_to_top_level(FORCE_EOF as libc::c_int); + } + } + ind = -(1 as libc::c_int) as arrayind_t; + value = if e == ']' as i32 { + get_array_value( + tok, + aflag, + 0 as *mut libc::c_void as *mut libc::c_int, + &mut ind, + ) + } else { + get_variable_value(v) + }; + if expr_depth < initial_depth { + if no_longjmp_on_fatal_error != 0 && interactive_shell != 0 { + siglongjmp(evalbuf.as_mut_ptr(), 1 as libc::c_int); + } + return 0 as libc::c_int as intmax_t; + } + tval = if !value.is_null() && *value as libc::c_int != 0 { + subexpr(value) + } else { + 0 as libc::c_int as libc::c_long + }; + if !lvalue.is_null() { + let ref mut fresh9 = (*lvalue).tokstr; + *fresh9 = tok; + (*lvalue).tokval = tval; + let ref mut fresh10 = (*lvalue).tokvar; + *fresh10 = v; + (*lvalue).ind = ind; + } + } + return tval; +} + +#[no_mangle] +fn init_lvalue(mut lv: *mut lvalue) { + unsafe { + let ref mut fresh6 = (*lv).tokstr; + *fresh6 = 0 as *mut libc::c_char; + let ref mut fresh7 = (*lv).tokvar; + *fresh7 = 0 as *mut SHELL_VAR; + let ref mut fresh8 = (*lv).ind; + *fresh8 = -(1 as libc::c_int) as intmax_t; + (*lv).tokval = *fresh8; + } +} + +#[no_mangle] +fn expr_bind_array_element( + mut tok: *mut libc::c_char, + mut ind: arrayind_t, + mut rhs: *mut libc::c_char, +) { + let mut lhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut llen: size_t = 0; + let mut ibuf: [libc::c_char; 22] = [0; 22]; + let mut istr: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + istr = fmtumax( + ind as uintmax_t, + 10 as libc::c_int, + ibuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 22]>() as usize, + 0 as libc::c_int, + ); + vname = array_variable_name( + tok, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut *mut libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + llen = (strlen(vname)) + .wrapping_add(::std::mem::size_of::<[libc::c_char; 22]>() as libc::c_ulong) + .wrapping_add(3 as libc::c_ulong); + + lhs = libc::malloc(llen as usize) as *mut libc::c_char; + sprintf( + lhs, + b"%s[%s]\0" as *const u8 as *const libc::c_char, + vname, + istr, + ); + expr_bind_variable(lhs, rhs); + libc::free(vname as *mut libc::c_void); + libc::free(lhs as *mut libc::c_void); + } +} + +#[no_mangle] +fn ipow(mut base: intmax_t, mut exp: intmax_t) -> intmax_t { + let mut result: intmax_t = 0; + result = 1 as libc::c_int as intmax_t; + while exp != 0 { + if exp & 1 as libc::c_int as libc::c_long != 0 { + result *= base; + } + exp >>= 1 as libc::c_int; + base *= base; + } + return result; +} + +#[no_mangle] +fn exp1() -> intmax_t { + unsafe { + let mut val: intmax_t = 0; + if curtok == '!' as i32 { + readtok(); + val = (exp1() == 0) as libc::c_int as intmax_t; + lasttok = 6 as libc::c_int; + } else if curtok == '~' as i32 { + readtok(); + val = !exp1(); + lasttok = 6 as libc::c_int; + } else if curtok == '-' as i32 { + readtok(); + val = -exp1(); + lasttok = 6 as libc::c_int; + } else if curtok == '+' as i32 { + readtok(); + val = exp1(); + lasttok = 6 as libc::c_int; + } else { + val = exp0(); + } + return val; + } +} + +#[no_mangle] +fn exp0() -> intmax_t { + let mut val: intmax_t = 0 as libc::c_int as intmax_t; + let mut v2: intmax_t = 0; + let mut vincdec: *mut libc::c_char = 0 as *mut libc::c_char; + let mut stok: libc::c_int = 0; + let mut ec: EXPR_CONTEXT = EXPR_CONTEXT { + curtok: 0, + lasttok: 0, + expression: 0 as *mut libc::c_char, + tp: 0 as *mut libc::c_char, + lasttp: 0 as *mut libc::c_char, + tokval: 0, + tokstr: 0 as *mut libc::c_char, + noeval: 0, + lval: lvalue { + tokstr: 0 as *mut libc::c_char, + tokval: 0, + tokvar: 0 as *mut SHELL_VAR, + ind: 0, + }, + }; + unsafe { + if curtok == PREINC as libc::c_int || curtok == PREDEC as libc::c_int { + lasttok = curtok; + stok = lasttok; + readtok(); + if curtok != STR as libc::c_int { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"identifier expected after pre-increment or pre-decrement\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } + v2 = tokval + + (if stok == PREINC as libc::c_int { + 1 as libc::c_int + } else { + -(1 as libc::c_int) + }) as libc::c_long; + vincdec = itos(v2); + if noeval == 0 as libc::c_int { + if curlval.ind != -(1 as libc::c_int) as libc::c_long { + expr_bind_array_element(curlval.tokstr, curlval.ind, vincdec); + } else if !tokstr.is_null() { + expr_bind_variable(tokstr, vincdec); + } + } + libc::free(vincdec as *mut libc::c_void); + val = v2; + curtok = NUM as libc::c_int; + readtok(); + } else if curtok == '(' as i32 { + readtok(); + val = expcomma(); + if curtok != ')' as i32 { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"missing `)'\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + readtok(); + } else if curtok == NUM as libc::c_int || curtok == STR as libc::c_int { + val = tokval; + if curtok == STR as libc::c_int { + ec.curtok = curtok; + ec.lasttok = lasttok; + ec.tp = tp; + ec.lasttp = lasttp; + ec.tokval = tokval; + ec.tokstr = tokstr; + ec.noeval = noeval; + ec.lval = curlval; + tokstr = 0 as *mut libc::c_void as *mut libc::c_char; + noeval = 1 as libc::c_int; + readtok(); + stok = curtok; + if stok == POSTINC as libc::c_int || stok == POSTDEC as libc::c_int { + tokstr = ec.tokstr; + noeval = ec.noeval; + curlval = ec.lval; + lasttok = 5 as libc::c_int; + v2 = val + + (if stok == POSTINC as libc::c_int { + 1 as libc::c_int + } else { + -(1 as libc::c_int) + }) as libc::c_long; + vincdec = itos(v2); + if noeval == 0 as libc::c_int { + if curlval.ind != -(1 as libc::c_int) as libc::c_long { + expr_bind_array_element(curlval.tokstr, curlval.ind, vincdec); + } else { + expr_bind_variable(tokstr, vincdec); + } + } + libc::free(vincdec as *mut libc::c_void); + curtok = 6 as libc::c_int; + } else { + if stok == 5 as libc::c_int { + if !tokstr.is_null() { + libc::free(tokstr as *mut libc::c_void); + } + } + curtok = ec.curtok; + lasttok = ec.lasttok; + tp = ec.tp; + lasttp = ec.lasttp; + tokval = ec.tokval; + tokstr = ec.tokstr; + noeval = ec.noeval; + curlval = ec.lval; + } + } + readtok(); + } else { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"syntax error: operand expected\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + } + return val; +} + +#[no_mangle] +fn exppower() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + let mut c: intmax_t = 0; + val1 = exp1(); + unsafe { + while curtok == POWER as libc::c_int { + readtok(); + val2 = exppower(); + lasttok = NUM as libc::c_int; + if val2 == 0 as libc::c_int as libc::c_long { + return 1 as libc::c_int as intmax_t; + } + if val2 < 0 as libc::c_int as libc::c_long { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"exponent less than 0\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + val1 = ipow(val1, val2); + } + } + return val1; +} + +#[no_mangle] +fn expmuldiv() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + let mut idiv: imaxdiv_t = imaxdiv_t { quot: 0, rem: 0 }; + val1 = exppower(); + unsafe { + while curtok == '*' as i32 || curtok == '/' as i32 || curtok == '%' as i32 { + let mut op: libc::c_int = curtok; + let mut stp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sltp: *mut libc::c_char = 0 as *mut libc::c_char; + stp = tp; + readtok(); + val2 = exppower(); + if (op == '/' as i32 || op == '%' as i32) && val2 == 0 as libc::c_int as libc::c_long { + if noeval == 0 as libc::c_int { + sltp = lasttp; + lasttp = stp; + while !lasttp.is_null() + && *lasttp as libc::c_int != 0 + && (*lasttp as libc::c_int == ' ' as i32 + || *lasttp as libc::c_int == '\t' as i32) + { + lasttp = lasttp.offset(1); + } + evalerror(dcgettext( + 0 as *const libc::c_char, + b"division by 0\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + lasttp = sltp; + } else { + val2 = 1 as libc::c_int as intmax_t; + } + } else if op == '%' as i32 + && val1 == -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long + && val2 == -(1 as libc::c_int) as libc::c_long + { + val1 = 0 as libc::c_int as intmax_t; + continue; + } else if op == '/' as i32 + && val1 == -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long + && val2 == -(1 as libc::c_int) as libc::c_long + { + val2 = 1 as libc::c_int as intmax_t; + } + if op == '*' as i32 { + val1 *= val2; + } else if op == '/' as i32 || op == '%' as i32 { + idiv = imaxdiv(val1, val2); + val1 = if op == '/' as i32 { + idiv.quot + } else { + idiv.rem + }; + } + lasttok = 6 as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn exp3() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = expmuldiv(); + unsafe { + while curtok == '+' as i32 || curtok == '-' as i32 { + let mut op: libc::c_int = curtok; + readtok(); + val2 = expmuldiv(); + if op == '+' as i32 { + val1 += val2; + } else if op == '-' as i32 { + val1 -= val2; + } + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn expshift() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = exp3(); + unsafe { + while curtok == LSH as libc::c_int || curtok == RSH as libc::c_int { + let mut op: libc::c_int = curtok; + readtok(); + val2 = exp3(); + if op == LSH as libc::c_int { + val1 = val1 << val2; + } else { + val1 = val1 >> val2; + } + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn exp4() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = expshift(); + unsafe { + while curtok == LEQ as libc::c_int + || curtok == GEQ as libc::c_int + || curtok == '<' as i32 + || curtok == '>' as i32 + { + let mut op: libc::c_int = curtok; + readtok(); + val2 = expshift(); + if op == LEQ as libc::c_int { + val1 = (val1 <= val2) as libc::c_int as intmax_t; + } else if op == GEQ as libc::c_int { + val1 = (val1 >= val2) as libc::c_int as intmax_t; + } else if op == '<' as i32 { + val1 = (val1 < val2) as libc::c_int as intmax_t; + } else { + val1 = (val1 > val2) as libc::c_int as intmax_t; + } + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn exp5() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = exp4(); + unsafe { + while curtok == EQEQ as libc::c_int || curtok == NEQ as libc::c_int { + let mut op: libc::c_int = curtok; + readtok(); + val2 = exp4(); + if op == EQEQ as libc::c_int { + val1 = (val1 == val2) as libc::c_int as intmax_t; + } else if op == NEQ as libc::c_int { + val1 = (val1 != val2) as libc::c_int as intmax_t; + } + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn expband() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = exp5(); + unsafe { + while curtok == '&' as i32 { + readtok(); + val2 = exp5(); + val1 = val1 & val2; + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn expbxor() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = expband(); + unsafe { + while curtok == '^' as i32 { + readtok(); + val2 = expband(); + val1 = val1 ^ val2; + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn expbor() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + val1 = expbxor(); + unsafe { + while curtok == '|' as i32 { + readtok(); + val2 = expbxor(); + val1 = val1 | val2; + lasttok = NUM as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn expland() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + let mut set_noeval: libc::c_int = 0; + val1 = expbor(); + unsafe { + while curtok == LAND as libc::c_int { + set_noeval = 0 as libc::c_int; + if val1 == 0 as libc::c_int as libc::c_long { + set_noeval = 1 as libc::c_int; + noeval += 1; + } + readtok(); + val2 = expbor(); + if set_noeval != 0 { + noeval -= 1; + } + val1 = (val1 != 0 && val2 != 0) as libc::c_int as intmax_t; + lasttok = LAND as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn explor() -> intmax_t { + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + let mut set_noeval: libc::c_int = 0; + val1 = expland(); + unsafe { + while curtok == LOR as libc::c_int { + set_noeval = 0 as libc::c_int; + if val1 != 0 as libc::c_int as libc::c_long { + noeval += 1; + set_noeval = 1 as libc::c_int; + } + readtok(); + val2 = expland(); + if set_noeval != 0 { + noeval -= 1; + } + val1 = (val1 != 0 || val2 != 0) as libc::c_int as intmax_t; + lasttok = LOR as libc::c_int; + } + } + return val1; +} + +#[no_mangle] +fn expcond() -> intmax_t { + let mut cval: intmax_t = 0; + let mut val1: intmax_t = 0; + let mut val2: intmax_t = 0; + let mut rval: intmax_t = 0; + let mut set_noeval: libc::c_int = 0; + set_noeval = 0 as libc::c_int; + cval = explor(); + rval = cval; + unsafe { + if curtok == '?' as i32 { + if cval == 0 as libc::c_int as libc::c_long { + set_noeval = 1 as libc::c_int; + noeval += 1; + } + readtok(); + if curtok == 0 as libc::c_int || curtok == ':' as i32 { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"expression expected\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + val1 = expcomma(); + if set_noeval != 0 { + noeval -= 1; + } + if curtok != ':' as i32 { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"`:' expected for conditional expression\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } + set_noeval = 0 as libc::c_int; + if cval != 0 { + set_noeval = 1 as libc::c_int; + noeval += 1; + } + readtok(); + if curtok == 0 as libc::c_int { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"expression expected\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + val2 = expcond(); + if set_noeval != 0 { + noeval -= 1; + } + rval = if cval != 0 { val1 } else { val2 }; + lasttok = COND as libc::c_int; + } + } + return rval; +} + +#[no_mangle] +fn expassign() -> intmax_t { + let mut value: intmax_t = 0; + let mut lhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lind: arrayind_t = 0; + let mut idiv: imaxdiv_t = imaxdiv_t { quot: 0, rem: 0 }; + value = expcond(); + unsafe { + if curtok == '=' as i32 || curtok == 11 as libc::c_int { + let mut special: libc::c_int = 0; + let mut op: libc::c_int = 0; + let mut lvalue: intmax_t = 0; + special = (curtok == 11 as libc::c_int) as libc::c_int; + if lasttok != 5 as libc::c_int { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"attempted assignment to non-variable\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + if special != 0 { + op = assigntok; + lvalue = value; + } + if tokstr.is_null() { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"syntax error in variable assignment\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + lhs = strcpy( + libc::malloc((1 as libc::c_ulong).wrapping_add(strlen(tokstr)) as usize) + as *mut libc::c_char, + tokstr, + ); + lind = curlval.ind; + readtok(); + value = expassign(); + if special != 0 { + if (op == '/' as i32 || op == '%' as i32) + && value == 0 as libc::c_int as libc::c_long + { + if noeval == 0 as libc::c_int { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"division by 0\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } else { + value = 1 as libc::c_int as intmax_t; + } + } + match op { + 42 => { + // '*' + lvalue *= value; + } + 47 | 37 => { + // '/' | '%' + if lvalue + == -(9223372036854775807 as libc::c_long) + - 1 as libc::c_int as libc::c_long + && value == -(1 as libc::c_int) as libc::c_long + { + lvalue = if op == '/' as i32 { + -(9223372036854775807 as libc::c_long) + - 1 as libc::c_int as libc::c_long + } else { + 0 as libc::c_int as libc::c_long + }; + } else { + idiv = imaxdiv(lvalue, value); + lvalue = if op == '/' as i32 { + idiv.quot + } else { + idiv.rem + }; + } + } + 43 => { + // '+' + lvalue += value; + } + 45 => { + // '-' + lvalue -= value; + } + LSH => { + lvalue <<= value; + } + RSH => { + lvalue >>= value; + } + 38 => { + // '&' + lvalue &= value; + } + 124 => { + // '|' + lvalue |= value; + } + 94 => { + // '^' + lvalue ^= value; + } + _ => { + libc::free(lhs as *mut libc::c_void); + evalerror(dcgettext( + 0 as *const libc::c_char, + b"bug: bad expassign token\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + } + value = lvalue; + } + rhs = itos(value); + if noeval == 0 as libc::c_int { + if lind != -(1 as libc::c_int) as libc::c_long { + expr_bind_array_element(lhs, lind, rhs); + } else { + expr_bind_variable(lhs, rhs); + } + } + if !(curlval.tokstr).is_null() && curlval.tokstr == tokstr { + init_lvalue(&mut curlval); + } + libc::free(rhs as *mut libc::c_void); + libc::free(lhs as *mut libc::c_void); + if !tokstr.is_null() { + libc::free(tokstr as *mut libc::c_void); + } + tokstr = 0 as *mut libc::c_void as *mut libc::c_char; + } + } + return value; +} + +#[no_mangle] +fn expcomma() -> intmax_t { + let mut value: intmax_t = 0; + value = expassign(); + while unsafe { curtok == ',' as i32 } { + readtok(); + value = expassign(); + } + return value; +} + +#[no_mangle] +fn strlong(mut num: *mut libc::c_char) -> intmax_t { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut c: libc::c_uchar = 0; + let mut base: libc::c_int = 0; + let mut foundbase: libc::c_int = 0; + let mut val: intmax_t = 0; + s = num; + base = 10 as libc::c_int; + foundbase = 0 as libc::c_int; + unsafe { + if *s as libc::c_int == '0' as i32 { + s = s.offset(1); + if *s as libc::c_int == '\u{0}' as i32 { + return 0 as libc::c_int as intmax_t; + } + if *s as libc::c_int == 'x' as i32 || *s as libc::c_int == 'X' as i32 { + base = 16 as libc::c_int; + s = s.offset(1); + } else { + base = 8 as libc::c_int; + } + foundbase += 1; + } + val = 0 as libc::c_int as intmax_t; + let fresh14 = s; + s = s.offset(1); + c = *fresh14 as libc::c_uchar; + while c != 0 { + if c as libc::c_int == '#' as i32 { + if foundbase != 0 { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"invalid number\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + if val < 2 as libc::c_int as libc::c_long || val > 64 as libc::c_int as libc::c_long + { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"invalid arithmetic base\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + base = val as libc::c_int; + val = 0 as libc::c_int as intmax_t; + foundbase += 1; + if (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*s as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISalnum as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *s as libc::c_int == '_' as i32 + || *s as libc::c_int == '@' as i32) as libc::c_int + == 0 as libc::c_int + { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"invalid integer constant\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + } else { + if !(1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(c as libc::c_int as isize) as libc::c_int + & _ISalnum as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || c as libc::c_int == '_' as i32 + || c as libc::c_int == '@' as i32) + { + break; + } + if c as libc::c_int >= '0' as i32 && c as libc::c_int <= '9' as i32 { + c = (c as libc::c_int - '0' as i32) as libc::c_uchar; + } else if c as libc::c_int >= 'a' as i32 && c as libc::c_int <= 'z' as i32 { + c = (c as libc::c_int - ('a' as i32 - 10 as libc::c_int)) as libc::c_uchar; + } else if c as libc::c_int >= 'A' as i32 && c as libc::c_int <= 'Z' as i32 { + c = (c as libc::c_int + - ('A' as i32 + - (if base <= 36 as libc::c_int { + 10 as libc::c_int + } else { + 36 as libc::c_int + }))) as libc::c_uchar; + } else if c as libc::c_int == '@' as i32 { + c = 62 as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == '_' as i32 { + c = 63 as libc::c_int as libc::c_uchar; + } + if c as libc::c_int >= base { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"value too great for base\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + val = val * base as libc::c_long + c as libc::c_long; + } + let fresh15 = s; + s = s.offset(1); + c = *fresh15 as libc::c_uchar; + } + } + return val; +} + +#[no_mangle] +fn expr_skipsubscript(mut vp: *mut libc::c_char, mut cp: *mut libc::c_char) -> libc::c_int { + let mut flags: libc::c_int = 0; + let mut isassoc: libc::c_int = 0; + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + isassoc = 0 as libc::c_int; + entry = 0 as *mut SHELL_VAR; + unsafe { + if assoc_expand_once & already_expanded != 0 { + *cp = '\u{0}' as i32 as libc::c_char; + isassoc = (legal_identifier(vp) != 0 + && { + entry = find_variable(vp); + !entry.is_null() + } + && (*entry).attributes & 0x40 as libc::c_int != 0) + as libc::c_int; + *cp = '[' as i32 as libc::c_char; + } + flags = if isassoc != 0 && assoc_expand_once != 0 && already_expanded != 0 { + 0x1 as libc::c_int + } else { + 0 as libc::c_int + }; + } + return skipsubscript(cp, 0 as libc::c_int, flags); +} + +#[no_mangle] +fn evalerror(mut msg: *const libc::c_char) { + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + name = this_command_name; + t = expression; + while !t.is_null() && (*t as libc::c_int == ' ' as i32 || *t as libc::c_int == '\t' as i32) + { + t = t.offset(1); + } + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s%s%s: %s (error token is \"%s\")\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + if !name.is_null() { + name + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !name.is_null() { + b": \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + if !t.is_null() { + t + } else { + b"\0" as *const u8 as *const libc::c_char + }, + msg, + if !lasttp.is_null() && *lasttp as libc::c_int != 0 { + lasttp + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + + siglongjmp(evalbuf.as_mut_ptr(), 1 as libc::c_int); + } +} + +#[no_mangle] +fn pushexp() { + let mut context: *mut EXPR_CONTEXT = 0 as *mut EXPR_CONTEXT; + unsafe { + if expr_depth >= MAX_EXPR_RECURSION_LEVEL as libc::c_int { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"expression recursion level exceeded\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + if expr_depth >= expr_stack_size { + expr_stack_size += EXPR_STACK_GROW_SIZE as libc::c_int; + expr_stack = libc::realloc( + expr_stack as *mut libc::c_void, + (expr_stack_size as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::<*mut EXPR_CONTEXT>() as libc::c_ulong) + as usize, + ) as *mut *mut EXPR_CONTEXT; + } + context = libc::malloc(::std::mem::size_of::() as usize) as *mut EXPR_CONTEXT; + let ref mut fresh0 = (*context).expression; + *fresh0 = expression; + (*context).curtok = curtok; + (*context).lasttok = lasttok; + let ref mut fresh1 = (*context).tp; + *fresh1 = tp; + let ref mut fresh2 = (*context).lasttp; + *fresh2 = lasttp; + (*context).tokval = tokval; + let ref mut fresh3 = (*context).tokstr; + *fresh3 = tokstr; + (*context).noeval = noeval; + (*context).lval = curlval; + let fresh4 = expr_depth; + expr_depth = expr_depth + 1; + let ref mut fresh5 = *expr_stack.offset(fresh4 as isize); + *fresh5 = context; + } +} + +#[no_mangle] +fn popexp() { + let mut context: *mut EXPR_CONTEXT = 0 as *mut EXPR_CONTEXT; + unsafe { + if expr_depth <= 0 as libc::c_int { + lasttp = 0 as *mut libc::c_char; + expression = lasttp; + evalerror(dcgettext( + 0 as *const libc::c_char, + b"recursion stack underflow\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + expr_depth -= 1; + context = *expr_stack.offset(expr_depth as isize); + expression = (*context).expression; + curtok = (*context).curtok; + lasttok = (*context).lasttok; + tp = (*context).tp; + lasttp = (*context).lasttp; + tokval = (*context).tokval; + tokstr = (*context).tokstr; + noeval = (*context).noeval; + curlval = (*context).lval; + libc::free(context as *mut libc::c_void); + } +} + +#[no_mangle] +fn _is_arithop(mut c: libc::c_int) -> libc::c_int { + match c as u8 as char { + '=' | '>' | '<' | '+' | '-' | '*' | '/' | '%' | '!' | '(' | ')' | '&' | '|' | '^' | '~' => { + return 1 as libc::c_int; + } + '?' | ':' | ',' => return 1 as libc::c_int, + _ => return 0 as libc::c_int, + }; +} + +#[no_mangle] +fn _is_multiop(mut c: libc::c_int) -> libc::c_int { + match c { + EQEQ | NEQ | LEQ | GEQ | LAND | LOR | LSH | RSH | OP_ASSIGN | COND | POWER | PREINC + | PREDEC | POSTINC | POSTDEC => { + return 1 as libc::c_int; + } + _ => return 0 as libc::c_int, + }; +} + +#[no_mangle] +fn readtok() { + let mut cp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut xp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut c: libc::c_uchar = 0; + let mut c1: libc::c_uchar = 0; + let mut e: libc::c_int = 0; + let mut lval: lvalue = lvalue { + tokstr: 0 as *mut libc::c_char, + tokval: 0, + tokvar: 0 as *mut SHELL_VAR, + ind: 0, + }; + unsafe { + cp = tp; + e = 0 as libc::c_int; + c = e as libc::c_uchar; + while !cp.is_null() + && { + c = *cp as libc::c_uchar; + c as libc::c_int != 0 + } + && (c as libc::c_int == ' ' as i32 + || c as libc::c_int == '\t' as i32 + || c as libc::c_int == '\n' as i32) + { + cp = cp.offset(1); + } + if c != 0 { + cp = cp.offset(1); + } + if c as libc::c_int == '\u{0}' as i32 { + lasttok = curtok; + curtok = 0 as libc::c_int; + tp = cp; + return; + } + tp = cp.offset(-(1 as libc::c_int as isize)); + lasttp = tp; + if 1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(c as libc::c_int as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || c as libc::c_int == '_' as i32 + { + let mut savecp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ec: EXPR_CONTEXT = EXPR_CONTEXT { + curtok: 0, + lasttok: 0, + expression: 0 as *mut libc::c_char, + tp: 0 as *mut libc::c_char, + lasttp: 0 as *mut libc::c_char, + tokval: 0, + tokstr: 0 as *mut libc::c_char, + noeval: 0, + lval: lvalue { + tokstr: 0 as *mut libc::c_char, + tokval: 0, + tokvar: 0 as *mut SHELL_VAR, + ind: 0, + }, + }; + let mut peektok: libc::c_int = 0; + while 1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(c as libc::c_int as isize) as libc::c_int + & _ISalnum as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || c as libc::c_int == '_' as i32 + { + let fresh11 = cp; + cp = cp.offset(1); + c = *fresh11 as libc::c_uchar; + } + cp = cp.offset(-1); + c = *cp as libc::c_uchar; + if c as libc::c_int == '[' as i32 { + e = expr_skipsubscript(tp, cp); + if *cp.offset(e as isize) as libc::c_int == ']' as i32 { + cp = cp.offset((e + 1 as libc::c_int) as isize); + c = *cp as libc::c_uchar; + e = ']' as i32; + } else { + evalerror(bash_badsub_errmsg); + } + } + *cp = '\u{0}' as i32 as libc::c_char; + if !(curlval.tokstr).is_null() && curlval.tokstr == tokstr { + init_lvalue(&mut curlval); + } + if !tokstr.is_null() { + libc::free(tokstr as *mut libc::c_void); + } + tokstr = strcpy( + libc::malloc((1 as libc::c_ulong).wrapping_add(strlen(tp)) as usize) + as *mut libc::c_char, + tp, + ); + *cp = c as libc::c_char; + ec.curtok = curtok; + ec.lasttok = lasttok; + ec.tp = tp; + ec.lasttp = lasttp; + ec.tokval = tokval; + ec.tokstr = tokstr; + ec.noeval = noeval; + ec.lval = curlval; + tokstr = 0 as *mut libc::c_void as *mut libc::c_char; + savecp = cp; + tp = savecp; + noeval = 1 as libc::c_int; + curtok = STR as libc::c_int; + readtok(); + peektok = curtok; + if peektok == STR as libc::c_int { + if !tokstr.is_null() { + libc::free(tokstr as *mut libc::c_void); + } + } + curtok = ec.curtok; + lasttok = ec.lasttok; + tp = ec.tp; + lasttp = ec.lasttp; + tokval = ec.tokval; + tokstr = ec.tokstr; + noeval = ec.noeval; + curlval = ec.lval; + cp = savecp; + if lasttok == PREINC as libc::c_int + || lasttok == PREDEC as libc::c_int + || peektok != '=' as i32 + { + lastlval = curlval; + tokval = expr_streval(tokstr, e, &mut curlval); + } else { + tokval = 0 as libc::c_int as intmax_t; + } + lasttok = curtok; + curtok = STR as libc::c_int; + } else if c as libc::c_int >= '0' as i32 && c as libc::c_int <= '9' as i32 { + while 1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(c as libc::c_int as isize) as libc::c_int + & _ISalnum as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || c as libc::c_int == '#' as i32 + || c as libc::c_int == '@' as i32 + || c as libc::c_int == '_' as i32 + { + let fresh12 = cp; + cp = cp.offset(1); + c = *fresh12 as libc::c_uchar; + } + cp = cp.offset(-1); + c = *cp as libc::c_uchar; + *cp = '\u{0}' as i32 as libc::c_char; + tokval = strlong(tp); + *cp = c as libc::c_char; + lasttok = curtok; + curtok = NUM as libc::c_int; + } else { + let fresh13 = cp; + cp = cp.offset(1); + c1 = *fresh13 as libc::c_uchar; + if c as libc::c_int == EQ as i32 && c1 as libc::c_int == EQ as i32 { + c = EQEQ as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == NOT as i32 && c1 as libc::c_int == EQ as i32 { + c = NEQ as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == GT as i32 && c1 as libc::c_int == EQ as i32 { + c = GEQ as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == LT as i32 && c1 as libc::c_int == EQ as i32 { + c = LEQ as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == LT as i32 && c1 as libc::c_int == LT as i32 { + if *cp as libc::c_int == '=' as i32 { + assigntok = LSH as libc::c_int; + c = OP_ASSIGN as libc::c_int as libc::c_uchar; + cp = cp.offset(1); + } else { + c = LSH as libc::c_int as libc::c_uchar; + } + } else if c as libc::c_int == '>' as i32 && c1 as libc::c_int == '>' as i32 { + if *cp as libc::c_int == '=' as i32 { + assigntok = 10 as libc::c_int; + c = 11 as libc::c_int as libc::c_uchar; + cp = cp.offset(1); + } else { + c = 10 as libc::c_int as libc::c_uchar; + } + } else if c as libc::c_int == BAND as i32 && c1 as libc::c_int == BAND as i32 { + c = LAND as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == BOR as i32 && c1 as libc::c_int == BOR as i32 { + c = LOR as libc::c_int as libc::c_uchar; + } else if c as libc::c_int == '*' as i32 && c1 as libc::c_int == '*' as i32 { + c = POWER as libc::c_int as libc::c_uchar; + } else if (c as libc::c_int == '-' as i32 || c as libc::c_int == '+' as i32) + && c1 as libc::c_int == c as libc::c_int + && curtok == 5 as libc::c_int + { + c = (if c as libc::c_int == '-' as i32 { + 17 as libc::c_int + } else { + 16 as libc::c_int + }) as libc::c_uchar; + } else if (c as libc::c_int == '-' as i32 || c as libc::c_int == '+' as i32) + && c1 as libc::c_int == c as libc::c_int + && curtok == NUM as libc::c_int + && (lasttok == PREINC as libc::c_int || lasttok == PREDEC as libc::c_int) + { + if c as libc::c_int == '-' as i32 { + evalerror( + b"--: assignment requires lvalue\0" as *const u8 as *const libc::c_char, + ); + } else { + evalerror( + b"++: assignment requires lvalue\0" as *const u8 as *const libc::c_char, + ); + } + } else if (c as libc::c_int == '-' as i32 || c as libc::c_int == '+' as i32) + && c1 as libc::c_int == c as libc::c_int + { + xp = cp; + while !xp.is_null() + && *xp as libc::c_int != 0 + && (*xp as libc::c_int == ' ' as i32 + || *xp as libc::c_int == '\t' as i32 + || *xp as libc::c_int == '\n' as i32) + { + xp = xp.offset(1); + } + if 1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*xp as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *xp as libc::c_uchar as libc::c_int == '_' as i32 + { + c = (if c as libc::c_int == '-' as i32 { + PREDEC as libc::c_int + } else { + PREINC as libc::c_int + }) as libc::c_uchar; + } else { + cp = cp.offset(-1); + } + } else if c1 as libc::c_int == EQ as i32 + && (if c as libc::c_int != 0 { + (mbschr( + b"*/%+-&^|\0" as *const u8 as *const libc::c_char, + c as libc::c_int, + ) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + assigntok = c as libc::c_int; + c = OP_ASSIGN as libc::c_int as libc::c_uchar; + } else if _is_arithop(c as libc::c_int) == 0 as libc::c_int { + cp = cp.offset(-1); + if curtok == 0 as libc::c_int + || _is_arithop(curtok) != 0 + || _is_multiop(curtok) != 0 + { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"syntax error: operand expected\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } else { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"syntax error: invalid arithmetic operator\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } + } else { + cp = cp.offset(-1); + } + lasttok = curtok; + curtok = c as libc::c_int; + } + tp = cp; + } +} + +#[no_mangle] +fn subexpr(mut expr: *mut libc::c_char) -> intmax_t { + let mut val: intmax_t = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + p = expr; + unsafe { + while !p.is_null() + && *p as libc::c_int != 0 + && (*p as libc::c_int == ' ' as i32 + || *p as libc::c_int == '\t' as i32 + || *p as libc::c_int == '\n' as i32) + { + p = p.offset(1); + } + if p.is_null() || *p as libc::c_int == '\u{0}' as i32 { + return 0 as libc::c_int as intmax_t; + } + pushexp(); + expression = strcpy( + libc::malloc((1 as libc::c_ulong).wrapping_add(strlen(expr)) as usize) + as *mut libc::c_char, + expr, + ); + tp = expression; + lasttok = 0 as libc::c_int; + curtok = lasttok; + tokstr = 0 as *mut libc::c_void as *mut libc::c_char; + tokval = 0 as libc::c_int as intmax_t; + init_lvalue(&mut curlval); + lastlval = curlval; + readtok(); + val = expcomma(); + if curtok != 0 as libc::c_int { + evalerror(dcgettext( + 0 as *const libc::c_char, + b"syntax error in expression\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + if !tokstr.is_null() { + libc::free(tokstr as *mut libc::c_void); + } + if !expression.is_null() { + libc::free(expression as *mut libc::c_void); + } + popexp(); + } + return val; +} + +#[no_mangle] +fn expr_unwind() { + unsafe { + loop { + expr_depth -= 1; + if !(expr_depth > 0 as libc::c_int) { + break; + } + if !((**expr_stack.offset(expr_depth as isize)).tokstr).is_null() { + libc::free((**expr_stack.offset(expr_depth as isize)).tokstr as *mut libc::c_void); + } + if !((**expr_stack.offset(expr_depth as isize)).expression).is_null() { + libc::free( + (**expr_stack.offset(expr_depth as isize)).expression as *mut libc::c_void, + ); + } + libc::free(*expr_stack.offset(expr_depth as isize) as *mut libc::c_void); + } + if expr_depth == 0 as libc::c_int { + libc::free(*expr_stack.offset(expr_depth as isize) as *mut libc::c_void); + } + noeval = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn evalexp( + mut expr: *mut libc::c_char, + mut flags: libc::c_int, + mut validp: *mut libc::c_int, +) -> intmax_t { + let mut val: intmax_t = 0; + let mut c: libc::c_int = 0; + let mut oevalbuf: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, + }; 1]; + unsafe { + val = 0 as libc::c_int as intmax_t; + + noeval = 0 as libc::c_int; + already_expanded = flags & EXP_EXPANDED as libc::c_int; + + libc::memcpy( + oevalbuf.as_mut_ptr() as *mut libc::c_void, + evalbuf.as_mut_ptr() as *const libc::c_void, + ::std::mem::size_of::() as libc::c_ulong as libc::size_t, + ); + c = __sigsetjmp(evalbuf.as_mut_ptr(), 0 as libc::c_int); + + if c != 0 { + if !tokstr.is_null() { + libc::free(tokstr as *mut libc::c_void); + } + if !expression.is_null() { + libc::free(expression as *mut libc::c_void); + } + expression = 0 as *mut libc::c_void as *mut libc::c_char; + tokstr = expression; + expr_unwind(); + expr_depth = 0 as libc::c_int; + libc::memcpy( + evalbuf.as_mut_ptr() as *mut libc::c_void, + oevalbuf.as_mut_ptr() as *const libc::c_void, + ::std::mem::size_of::() as libc::c_ulong as libc::size_t, + ); + if !validp.is_null() { + *validp = 0 as libc::c_int; + } + return 0 as libc::c_int as intmax_t; + } + + val = subexpr(expr); + + if !validp.is_null() { + *validp = 1 as libc::c_int; + } + + libc::memcpy( + evalbuf.as_mut_ptr() as *mut libc::c_void, + oevalbuf.as_mut_ptr() as *const libc::c_void, + ::std::mem::size_of::() as libc::c_ulong as libc::size_t, + ); + + return val; + } +} diff --git a/utshell-0.5.0/src/findcmd.rs b/utshell-0.5.0/src/findcmd.rs new file mode 100644 index 00000000..233a31ba --- /dev/null +++ b/utshell-0.5.0/src/findcmd.rs @@ -0,0 +1,586 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::general::{absolute_program, bash_tilde_expand, conf_standard_path, extract_colon_unit}; +use crate::hashcmd::{phash_insert, phash_remove, phash_search}; +use crate::pathexp::setup_ignore_patterns; +use crate::src_common::*; +use crate::variables::{find_variable_tempenv, get_string_value}; + +#[inline] +fn stat( + mut __path: *const libc::c_char, + mut __statbuf: *mut crate::src_common::stat, +) -> libc::c_int { + unsafe { + return __xstat(1 as libc::c_int, __path, __statbuf); + } +} + +static mut file_to_lose_on: *mut libc::c_char = 0 as *mut libc::c_char; +static mut execignore: ignorevar = { + let init = ignorevar { + varname: b"EXECIGNORE\0" as *const u8 as *mut libc::c_char, + ignores: 0 as *mut ign, + num_ignores: 0, + last_ignoreval: 0 as *mut libc::c_char, + item_func: None, + }; + init +}; + +#[no_mangle] +pub fn setup_exec_ignore(_varname: *mut libc::c_char) { + unsafe { + setup_ignore_patterns(&mut execignore); + } +} + +fn exec_name_should_ignore(name: *const libc::c_char) -> libc::c_int { + let mut p: *mut ign = 0 as *mut ign; + unsafe { + p = execignore.ignores; + while !p.is_null() && !((*p).val).is_null() { + if strmatch( + (*p).val, + name as *mut libc::c_char, + FNMATCH_EXTFLAG!() | FNM_CASEFOLD!(), + ) != FNM_NOMATCH!() + { + return 1; + } + + p = p.offset(1); + } + } + return 0; +} + +#[no_mangle] +pub fn file_status(name: *const libc::c_char) -> libc::c_int { + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut r: libc::c_int = 0; + + if stat(name, &mut finfo) < 0 { + return 0; + } + + if S_ISDIR!(finfo.st_mode) { + return FS_EXISTS as libc::c_int | FS_DIRECTORY as libc::c_int; + } + r = FS_EXISTS as libc::c_int; + unsafe { + if exec_name_should_ignore(name) == 0 && eaccess(name, X_OK as libc::c_int) == 0 { + r |= FS_EXECABLE as libc::c_int; + } + if eaccess(name, R_OK as libc::c_int) == 0 { + r |= FS_READABLE as libc::c_int; + } + } + return r; +} + +#[no_mangle] +pub fn executable_file(file: *const libc::c_char) -> libc::c_int { + let mut s: libc::c_int = 0; + + s = file_status(file); + if s & FS_DIRECTORY as libc::c_int != 0 { + unsafe { + errno!() = EISDIR!(); + } + } + return (s & FS_EXECABLE as libc::c_int != 0 + && s & FS_DIRECTORY as libc::c_int == 0 as libc::c_int) as libc::c_int; +} + +#[no_mangle] +pub fn is_directory(file: *const libc::c_char) -> libc::c_int { + return file_status(file) & FS_DIRECTORY as libc::c_int; +} + +#[no_mangle] +pub fn executable_or_directory(file: *const libc::c_char) -> libc::c_int { + let mut s: libc::c_int = 0; + + s = file_status(file); + return (s & FS_EXECABLE as libc::c_int != 0 || s & FS_DIRECTORY as libc::c_int != 0) + as libc::c_int; +} + +#[no_mangle] +pub fn find_user_command(name: *const libc::c_char) -> *mut libc::c_char { + unsafe { + return find_user_command_internal( + name, + FS_EXEC_PREFERRED as libc::c_int | FS_NODIRS as libc::c_int, + ); + } +} +#[no_mangle] +pub fn find_path_file(name: *const libc::c_char) -> *mut libc::c_char { + return find_user_command_internal(name, FS_READABLE as libc::c_int); +} + +fn _find_user_command_internal(name: *const libc::c_char, flags: libc::c_int) -> *mut libc::c_char { + let mut path_list: *mut libc::c_char = 0 as *mut libc::c_char; + let mut cmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + var = find_variable_tempenv(b"PATH\0" as *const u8 as *const libc::c_char); + unsafe { + if !var.is_null() { + path_list = value_cell!(var); + } else { + path_list = 0 as *mut libc::c_char; + } + + if path_list.is_null() || *path_list as libc::c_int == '\u{0}' as i32 { + return savestring!(name); + } + } + cmd = find_user_command_in_path(name, path_list, flags); + return cmd; +} +fn find_user_command_internal(name: *const libc::c_char, flags: libc::c_int) -> *mut libc::c_char { + return _find_user_command_internal(name, flags); +} + +fn get_next_path_element( + path_list: *mut libc::c_char, + path_index_pointer: *mut libc::c_int, +) -> *mut libc::c_char { + let mut path: *mut libc::c_char = 0 as *mut libc::c_char; + + path = extract_colon_unit(path_list, path_index_pointer); + if path.is_null() { + return path; + } + unsafe { + if *path as libc::c_int == '\u{0}' as i32 { + free(path as *mut libc::c_void); + path = savestring!(b".\0" as *const u8 as *const libc::c_char); + } + } + return path; +} + +#[no_mangle] +pub fn search_for_command(pathname: *const libc::c_char, flags: libc::c_int) -> *mut libc::c_char { + let mut hashed_file: *mut libc::c_char = 0 as *mut libc::c_char; + let mut command: *mut libc::c_char = 0 as *mut libc::c_char; + let mut path_list: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp_path: libc::c_int = 0; + let mut st: libc::c_int = 0; + let mut path: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + command = 0 as *mut libc::c_char; + hashed_file = command; + + path = find_variable_tempenv(b"PATH\0" as *const u8 as *const libc::c_char); + unsafe { + temp_path = (!path.is_null() && tempvar_p!(path) != 0) as libc::c_int; + + if temp_path == 0 && absolute_program(pathname) == 0 { + hashed_file = phash_search(pathname); + } + if !hashed_file.is_null() && (posixly_correct != 0 || check_hashed_filenames != 0) { + st = file_status(hashed_file); + if st & (FS_EXISTS as libc::c_int | FS_EXECABLE as libc::c_int) + != FS_EXISTS as libc::c_int | FS_EXECABLE as libc::c_int + { + phash_remove(pathname); + free(hashed_file as *mut libc::c_void); + hashed_file = 0 as *mut libc::c_char; + } + } + + if !hashed_file.is_null() { + command = hashed_file; + } else if absolute_program(pathname) != 0 { + command = savestring!(pathname); + } else { + if flags & CMDSRCH_STDPATH as libc::c_int != 0 { + path_list = conf_standard_path(); + } else if temp_path != 0 || !path.is_null() { + path_list = (*path).value; + } else { + path_list = 0 as *mut libc::c_char; + } + command = find_user_command_in_path( + pathname, + path_list, + FS_EXEC_PREFERRED as libc::c_int | FS_NODIRS as libc::c_int, + ); + + if !command.is_null() + && hashing_enabled != 0 + && temp_path == 0 + && flags & CMDSRCH_HASH as libc::c_int != 0 + { + if STREQ!(command, pathname) { + st = file_status(command); + if st & FS_EXECABLE as libc::c_int != 0 { + phash_insert( + pathname as *mut libc::c_char, + command, + dot_found_in_search, + 1, + ); + } + } else if posixly_correct != 0 { + st = file_status(command); + if st & FS_EXECABLE as libc::c_int != 0 { + phash_insert( + pathname as *mut libc::c_char, + command, + dot_found_in_search, + 1, + ); + } + } else { + phash_insert( + pathname as *mut libc::c_char, + command, + dot_found_in_search, + 1, + ); + } + } + if flags & CMDSRCH_STDPATH as libc::c_int != 0 { + free(path_list as *mut libc::c_void); + } + } + } + return command; +} + +#[no_mangle] +pub fn user_command_matches( + name: *const libc::c_char, + flags: libc::c_int, + state: libc::c_int, +) -> *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut path_index: libc::c_int = 0; + let mut name_len: libc::c_int = 0; + let mut path_list: *mut libc::c_char = 0 as *mut libc::c_char; + let mut path_element: *mut libc::c_char = 0 as *mut libc::c_char; + let mut match_0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut dotinfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + static mut match_list: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; + static mut match_list_size: libc::c_int = 0 as libc::c_int; + static mut match_index: libc::c_int = 0 as libc::c_int; + unsafe { + if state == 0 { + if match_list.is_null() { + match_list_size = 5; + match_list = strvec_create(match_list_size); + } + i = 0; + while i < match_list_size { + *match_list.offset(i as isize) = 0 as *mut libc::c_char; + i += 1; + } + + match_index = 0; + if absolute_program(name) != 0 { + *match_list.offset(0 as isize) = find_absolute_program(name, flags); + *match_list.offset(1 as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + path_list = 0 as *mut libc::c_char; + } else { + name_len = strlen(name) as libc::c_int; + file_to_lose_on = 0 as *mut libc::c_char; + dot_found_in_search = 0; + if stat(b".\0" as *const u8 as *const libc::c_char, &mut dotinfo) < 0 { + dotinfo.st_ino = 0 as __ino_t; + dotinfo.st_dev = dotinfo.st_ino; + } + path_list = get_string_value(b"PATH\0" as *const u8 as *const libc::c_char); + path_index = 0; + } + + while !path_list.is_null() && *path_list.offset(path_index as isize) as libc::c_int != 0 + { + path_element = get_next_path_element(path_list, &mut path_index); + if path_element.is_null() { + break; + } + match_0 = find_in_path_element(name, path_element, flags, name_len, &mut dotinfo); + + free(path_element as *mut libc::c_void); + + if match_0.is_null() { + continue; + } + + if match_index + 1 == match_list_size { + match_list_size += 10; + match_list = strvec_resize(match_list, match_list_size + 1); + } + + let fresh3 = match_index; + match_index = match_index + 1; + let ref mut fresh4 = *match_list.offset(fresh3 as isize); + *fresh4 = match_0; + let ref mut fresh5 = *match_list.offset(match_index as isize); + *fresh5 = 0 as *mut libc::c_void as *mut libc::c_char; + FREE!(file_to_lose_on); + file_to_lose_on = 0 as *mut libc::c_void as *mut libc::c_char; + } + match_index = 0; + } + + match_0 = *match_list.offset(match_index as isize); + + if !match_0.is_null() { + match_index += 1; + } + } + return match_0; +} + +fn find_absolute_program(name: *const libc::c_char, flags: libc::c_int) -> *mut libc::c_char { + let mut st: libc::c_int = 0; + + st = file_status(name); + + if st & FS_EXISTS as libc::c_int == 0 { + return 0 as *mut libc::c_char; + } + + if flags & FS_EXISTS as libc::c_int != 0 + || flags & FS_EXEC_ONLY as libc::c_int != 0 && st & FS_EXECABLE as libc::c_int != 0 + { + unsafe { + return savestring!(name); + } + } + return 0 as *mut libc::c_char; +} + +fn find_in_path_element( + name: *const libc::c_char, + path: *mut libc::c_char, + flags: libc::c_int, + _name_len: libc::c_int, + dotinfop: *mut crate::src_common::stat, +) -> *mut libc::c_char { + let mut status: libc::c_int = 0; + let mut full_path: *mut libc::c_char = 0 as *mut libc::c_char; + let mut xpath: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + xpath = if posixly_correct == 0 && *path as libc::c_int == '~' as i32 { + bash_tilde_expand(path, 0) + } else { + path + }; + + if dot_found_in_search == 0 && *xpath as libc::c_int == '.' as i32 { + dot_found_in_search = same_file( + b".\0" as *const u8 as *const libc::c_char, + xpath, + dotinfop, + 0 as *mut libc::c_void as *mut crate::src_common::stat, + ); + } + + full_path = sh_makepath(xpath, name, 0); + + status = file_status(full_path); + + if xpath != path { + free(xpath as *mut libc::c_void); + } + + if status & FS_EXISTS as libc::c_int == 0 { + free(full_path as *mut libc::c_void); + return 0 as *mut libc::c_char; + } + + if flags & FS_EXISTS as libc::c_int != 0 { + return full_path; + } + + if flags & FS_READABLE as libc::c_int != 0 && status & FS_READABLE as libc::c_int != 0 { + return full_path; + } + + if status & FS_EXECABLE as libc::c_int != 0 + && flags & (FS_EXEC_ONLY as libc::c_int | FS_EXEC_PREFERRED as libc::c_int) != 0 + && (flags & FS_NODIRS as libc::c_int == 0 as libc::c_int + || status & FS_DIRECTORY as libc::c_int == 0 as libc::c_int) + { + FREE!(file_to_lose_on); + file_to_lose_on = 0 as *mut libc::c_char; + return full_path; + } + + if flags & FS_EXEC_PREFERRED as libc::c_int != 0 + && file_to_lose_on.is_null() + && exec_name_should_ignore(full_path) == 0 + { + file_to_lose_on = savestring!(full_path); + } + + if flags & (FS_EXEC_ONLY as libc::c_int | FS_EXEC_PREFERRED as libc::c_int) != 0 + || flags & FS_NODIRS as libc::c_int != 0 && status & FS_DIRECTORY as libc::c_int != 0 + || flags & FS_READABLE as libc::c_int != 0 && status & FS_READABLE as libc::c_int == 0 + { + free(full_path as *mut libc::c_void); + return 0 as *mut libc::c_char; + } else { + return full_path; + }; + } +} + +fn find_user_command_in_path( + name: *const libc::c_char, + path_list: *mut libc::c_char, + flags: libc::c_int, +) -> *mut libc::c_char { + let mut full_path: *mut libc::c_char = 0 as *mut libc::c_char; + let mut path: *mut libc::c_char = 0 as *mut libc::c_char; + let mut path_index: libc::c_int = 0; + let mut name_len: libc::c_int = 0; + let mut dotinfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + unsafe { + dot_found_in_search = 0; + + if absolute_program(name) != 0 { + full_path = find_absolute_program(name, flags); + return full_path; + } + + if path_list.is_null() || *path_list as libc::c_int == '\u{0}' as i32 { + return savestring!(name); + } + + file_to_lose_on = 0 as *mut libc::c_char; + name_len = strlen(name) as libc::c_int; + if stat(b".\0" as *const u8 as *const libc::c_char, &mut dotinfo) < 0 as libc::c_int { + dotinfo.st_ino = 0 as libc::c_int as __ino_t; + dotinfo.st_dev = dotinfo.st_ino; + } + path_index = 0; + + while *path_list.offset(path_index as isize) != 0 { + QUIT!(); + + path = get_next_path_element(path_list, &mut path_index); + if path.is_null() { + break; + } + + full_path = find_in_path_element(name, path, flags, name_len, &mut dotinfo); + free(path as *mut libc::c_void); + + if !full_path.is_null() && is_directory(full_path) != 0 { + free(full_path as *mut libc::c_void); + continue; + } + if !full_path.is_null() { + FREE!(file_to_lose_on); + return full_path; + } + } + + if !file_to_lose_on.is_null() + && flags & FS_NODIRS as libc::c_int != 0 + && is_directory(file_to_lose_on) != 0 + { + free(file_to_lose_on as *mut libc::c_void); + file_to_lose_on = 0 as *mut libc::c_char; + } + + return file_to_lose_on; + } +} + +#[no_mangle] +pub fn find_in_path( + name: *const libc::c_char, + path_list: *mut libc::c_char, + flags: libc::c_int, +) -> *mut libc::c_char { + return find_user_command_in_path(name, path_list, flags); +} diff --git a/utshell-0.5.0/src/flags.rs b/utshell-0.5.0/src/flags.rs new file mode 100644 index 00000000..c074dafb --- /dev/null +++ b/utshell-0.5.0/src/flags.rs @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::bashhist::bash_initialize_history; +use crate::jobs::set_job_control; +use crate::src_common::*; +use crate::utshell::{disable_priv_mode, maybe_make_restricted}; + +#[no_mangle] +pub fn find_flag(name: libc::c_int) -> *mut libc::c_int { + let mut i: libc::c_int = 0; + unsafe { + while shell_flags[i as usize].name != 0 { + if shell_flags[i as usize].name as libc::c_int == name { + return shell_flags[i as usize].value; + } + i += 1; + } + } + return FLAG_UNKNOWN as *mut libc::c_int; +} +#[no_mangle] +pub fn change_flag(flag: libc::c_int, on_or_off: libc::c_int) -> libc::c_int { + let value: *mut libc::c_int; + let old_value: libc::c_int; + unsafe { + if restricted != 0 && flag == b'r' as i32 && on_or_off == FLAG_OFF as i32 { + return FLAG_ERROR; + } + value = find_flag(flag); + if value as *const libc::c_int == FLAG_UNKNOWN as *const libc::c_int + || on_or_off != FLAG_ON as i32 && on_or_off != FLAG_OFF as i32 + { + return FLAG_ERROR; + } + old_value = *value; + *value = if on_or_off == FLAG_ON as i32 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + match flag as u8 { + b'H' => { + history_expansion = histexp_flag; + if on_or_off == '-' as i32 { + bash_initialize_history(); + } + } + b'm' => { + set_job_control((on_or_off == '-' as i32) as libc::c_int); + } + b'e' => { + if builtin_ignoring_errexit == 0 as libc::c_int { + exit_immediately_on_error = errexit_flag; + } + } + b'n' => { + if interactive_shell != 0 { + read_but_dont_execute = 0 as libc::c_int; + } + } + b'p' => { + if on_or_off == '+' as i32 { + disable_priv_mode(); + } + } + b'r' => { + if on_or_off == '-' as i32 && shell_initialized != 0 { + maybe_make_restricted(shell_name); + } + } + b'v' => { + echo_input_at_read = verbose_flag; + } + _ => {} + } + } + return old_value; +} + +#[no_mangle] +pub fn which_set_flags() -> *mut libc::c_char { + let temp: *mut libc::c_char; + let mut i: libc::c_int; + let mut string_index: libc::c_int; + unsafe { + temp = libc::malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(::core::mem::size_of::<[flags_alist; 22]>() as libc::c_ulong) + .wrapping_add(read_from_stdin as libc::c_ulong) + .wrapping_add(want_pending_command as libc::c_ulong) as usize, + ) as *mut libc::c_char; + string_index = 0 as libc::c_int; + i = string_index; + while shell_flags[i as usize].name != 0 { + if *shell_flags[i as usize].value != 0 { + let fresh0 = string_index; + string_index = string_index + 1; + *temp.offset(fresh0 as isize) = shell_flags[i as usize].name; + } + i += 1; + } + if want_pending_command != 0 { + let fresh1 = string_index; + string_index = string_index + 1; + *temp.offset(fresh1 as isize) = 'c' as i32 as libc::c_char; + } + if read_from_stdin != 0 { + let fresh2 = string_index; + string_index = string_index + 1; + *temp.offset(fresh2 as isize) = 's' as i32 as libc::c_char; + } + *temp.offset(string_index as isize) = '\0' as i32 as libc::c_char; + } + return temp; +} + +#[no_mangle] +pub fn get_current_flags() -> *mut libc::c_char { + let temp: *mut libc::c_char; + let mut i: libc::c_int; + unsafe { + temp = libc::malloc(1 + ::core::mem::size_of::<[flags_alist; 22]>()) as *mut libc::c_char; + i = 0 as libc::c_int; + while shell_flags[i as usize].name != 0 { + *temp.offset(i as isize) = *shell_flags[i as usize].value as libc::c_char; + i += 1; + } + *temp.offset(i as isize) = '\0' as i32 as libc::c_char; + } + return temp; +} + +#[no_mangle] +pub fn set_current_flags(bitmap: *const libc::c_char) { + let mut i: libc::c_int = 0; + if bitmap.is_null() { + return; + } + unsafe { + while shell_flags[i as usize].name != 0 { + *shell_flags[i as usize].value = *bitmap.offset(i as isize) as libc::c_int; + i += 1; + } + } +} + +#[no_mangle] +pub fn reset_shell_flags() { + unsafe { + disallow_filename_globbing = 0 as libc::c_int; + mark_modified_vars = 0 as libc::c_int; + just_one_command = 0 as libc::c_int; + read_but_dont_execute = 0 as libc::c_int; + place_keywords_in_env = 0 as libc::c_int; + unbound_vars_is_error = 0 as libc::c_int; + noclobber = 0 as libc::c_int; + forced_interactive = 0 as libc::c_int; + jobs_m_flag = 0 as libc::c_int; + echo_command_at_execute = 0 as libc::c_int; + no_symbolic_links = 0 as libc::c_int; + pipefail_opt = 0 as libc::c_int; + privileged_mode = 0 as libc::c_int; + function_trace_mode = 0 as libc::c_int; + error_trace_mode = 0 as libc::c_int; + errexit_flag = 0 as libc::c_int; + exit_immediately_on_error = 0 as libc::c_int; + verbose_flag = 0 as libc::c_int; + echo_input_at_read = 0 as libc::c_int; + interactive_comments = 1 as libc::c_int; + hashing_enabled = 1 as libc::c_int; + asynchronous_notification = 0 as libc::c_int; + histexp_flag = 0 as libc::c_int; + brace_expansion = 1 as libc::c_int; + restricted = 0 as libc::c_int; + } +} +#[no_mangle] +pub fn initialize_flags() { + let mut i: libc::c_int = 0; + unsafe { + while shell_flags[i as usize].name != 0 { + optflags[(i + 1 as libc::c_int) as usize] = shell_flags[i as usize].name; + i += 1; + } + i += 1; + optflags[i as usize] = 'o' as i32 as libc::c_char; + i += 1; + optflags[i as usize] = ';' as i32 as libc::c_char; + optflags[(i + 1 as libc::c_int) as usize] = '\0' as i32 as libc::c_char; + } +} diff --git a/utshell-0.5.0/src/general.rs b/utshell-0.5.0/src/general.rs new file mode 100644 index 00000000..c08135f4 --- /dev/null +++ b/utshell-0.5.0/src/general.rs @@ -0,0 +1,1808 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::arrayfunc::{array_variable_name, valid_array_reference}; +use crate::builtins::{ + pushd::get_dirstack_from_string, + source::{source_searches_cwd, source_uses_path}, +}; +use crate::readline::*; +use crate::src_common::*; +use crate::stringlib::substring; +use crate::subst::skipsubscript; +use crate::variables::get_string_value; +use crate::y_tab::expand_aliases; + +//add by bgz +#[link(name = "history")] +#[link(name = "readline")] +extern "C" { + pub fn sh_unset_nodelay_mode(_: libc::c_int) -> libc::c_int; +} +//end of bgz + +#[macro_export] +macro_rules! legal_variable_starter { + ($c: expr) => { + (ISALPHA!($c) || ($c as i32 == '_' as i32)) + }; +} +#[macro_export] +macro_rules! legal_variable_char { + ($c: expr) => { + (ISALNUM!($c) || ($c as i32 == '_' as i32)) + }; +} +#[macro_export] +macro_rules! ISALNUM { + ($c:expr) => { + IN_CTYPE_DOMAIN!($c) != false && isalnum!($c) != 0 as libc::c_int + }; +} +#[macro_export] +macro_rules! isalnum { + ($c:expr) => { + __isctype_f!($c, _ISalnum) + }; +} + +#[inline] +fn strtoimax( + mut nptr: *const libc::c_char, + mut endptr: *mut *mut libc::c_char, + mut base: libc::c_int, +) -> intmax_t { + unsafe { + return __strtol_internal(nptr, endptr, base, 0 as libc::c_int); + } +} + +#[inline] +fn stat( + mut __path: *const libc::c_char, + mut __statbuf: *mut crate::src_common::stat, +) -> libc::c_int { + unsafe { + return __xstat(1 as libc::c_int, __path, __statbuf); + } +} + +#[inline] +fn atoi(mut __nptr: *const libc::c_char) -> libc::c_int { + unsafe { + return strtol( + __nptr, + 0 as *mut libc::c_void as *mut *mut libc::c_char, + 10 as libc::c_int, + ) as libc::c_int; + } +} + +/* A standard error message to use when getcwd() returns NULL. */ +#[no_mangle] +pub static mut bash_getcwd_errstr: *const libc::c_char = + b"getcwd: cannot access parent directories\0" as *const u8 as *const libc::c_char; + +/* Do whatever is necessary to initialize `Posix mode'. This currently + modifies the following variables which are controlled via shopt: + interactive_comments + source_uses_path + expand_aliases + inherit_errexit + print_shift_error + posixglob + + and the following variables which cannot be user-modified: + + source_searches_cwd + +If we add to the first list, we need to change the table and functions +below */ +static mut posix_vars: [C2RustUnnamed_1; 6] = unsafe { + [ + { + let mut init = C2RustUnnamed_1 { + posix_mode_var: &interactive_comments as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = C2RustUnnamed_1 { + posix_mode_var: &source_uses_path as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = C2RustUnnamed_1 { + posix_mode_var: &expand_aliases as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = C2RustUnnamed_1 { + posix_mode_var: &inherit_errexit as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = C2RustUnnamed_1 { + posix_mode_var: &print_shift_error as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = C2RustUnnamed_1 { + posix_mode_var: 0 as *const libc::c_int as *mut libc::c_int, + }; + init + }, + ] +}; + +static mut saved_posix_vars: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; + +#[no_mangle] +pub fn posix_initialize(mut on: libc::c_int) { + /* Things that should be turned on when posix mode is enabled. */ + unsafe { + if on != 0 as libc::c_int { + expand_aliases = 1 as libc::c_int; + source_uses_path = expand_aliases; + interactive_comments = source_uses_path; + inherit_errexit = 1 as libc::c_int; + source_searches_cwd = 0 as libc::c_int; + print_shift_error = 1 as libc::c_int; + + /* Things that should be turned on when posix mode is disabled. */ + } else if !saved_posix_vars.is_null() { + set_posix_options(saved_posix_vars); + libc::free(saved_posix_vars as *mut libc::c_void); + saved_posix_vars = 0 as *mut libc::c_char; + } else { + /* on == 0, restore a default set of settings */ + source_searches_cwd = 1 as libc::c_int; + expand_aliases = interactive_shell; + print_shift_error = 0 as libc::c_int; + }; + } +} + +#[no_mangle] +pub fn num_posix_options() -> libc::c_int { + return (::core::mem::size_of::<[C2RustUnnamed_1; 6]>() as libc::c_ulong) + .wrapping_div(::core::mem::size_of::() as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) as libc::c_int; +} + +#[no_mangle] +pub fn get_posix_options(mut bitmap: *mut libc::c_char) -> *mut libc::c_char { + let mut i: libc::c_int = 0; + unsafe { + if bitmap.is_null() { + bitmap = libc::malloc(num_posix_options() as usize) as *mut libc::c_char; + /* no trailing NULL */ + } + i = 0 as libc::c_int; + while !(posix_vars[i as usize].posix_mode_var).is_null() { + *bitmap.offset(i as isize) = *posix_vars[i as usize].posix_mode_var as libc::c_char; + i += 1; + i; + } + } + return bitmap; +} + +#[no_mangle] +pub fn save_posix_options() { + unsafe { + saved_posix_vars = get_posix_options(saved_posix_vars); + } +} + +#[no_mangle] +pub fn set_posix_options(mut bitmap: *const libc::c_char) { + let mut i: libc::c_int = 0; + + i = 0 as libc::c_int; + unsafe { + while !(posix_vars[i as usize].posix_mode_var).is_null() { + *posix_vars[i as usize].posix_mode_var = *bitmap.offset(i as isize) as libc::c_int; + i += 1; + i; + } + } +} + +/* **************************************************************** */ +/* */ +/* Functions to convert to and from and display non-standard types */ +/* */ +/* **************************************************************** */ +#[no_mangle] +pub fn string_to_rlimtype(mut s: *mut libc::c_char) -> rlim_t { + let mut ret: rlim_t = 0 as rlim_t; + let mut neg: libc::c_int = 0; + unsafe { + while !s.is_null() && *s as libc::c_int != 0 && whitespace!(*s) { + s = s.offset(1); + s; + } + if !s.is_null() && (*s as libc::c_int == '-' as i32 || *s as libc::c_int == '+' as i32) { + neg = (*s as libc::c_int == '-' as i32) as libc::c_int; + s = s.offset(1); + s; + } + while !s.is_null() && *s as libc::c_int != 0 && DIGIT!(*s) { + ret = ret + .wrapping_mul(10 as libc::c_int as libc::c_ulong) + .wrapping_add((TODIGIT!(*s)) as libc::c_ulong); + s = s.offset(1); + s; + } + return if neg != 0 { ret.wrapping_neg() } else { ret }; + } +} + +#[no_mangle] +pub fn print_rlimtype(mut n: rlim_t, mut addnl: libc::c_int) { + let mut s: [libc::c_char; 21] = [0; 21]; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + p = s + .as_mut_ptr() + .offset(::core::mem::size_of::<[libc::c_char; 21]>() as libc::c_ulong as isize); + p = p.offset(-1); + *p = '\0' as i32 as libc::c_char; + + if n < 0 as libc::c_int as libc::c_ulong { + loop { + p = p.offset(-1); + *p = ('0' as i32 as libc::c_ulong) + .wrapping_sub(n.wrapping_rem(10 as libc::c_int as libc::c_ulong)) + as libc::c_char; + n = (n as libc::c_ulong).wrapping_div(10 as libc::c_int as libc::c_ulong) as rlim_t + as rlim_t; + if !(n != 0 as libc::c_int as libc::c_ulong) { + break; + } + } + p = p.offset(-1); + *p = '-' as i32 as libc::c_char; + } else { + loop { + p = p.offset(-1); + *p = ('0' as i32 as libc::c_ulong) + .wrapping_add(n.wrapping_rem(10 as libc::c_int as libc::c_ulong)) + as libc::c_char; + n = (n as libc::c_ulong).wrapping_div(10 as libc::c_int as libc::c_ulong) as rlim_t + as rlim_t; + if !(n != 0 as libc::c_int as libc::c_ulong) { + break; + } + } + } + + printf( + b"%s%s\0" as *const u8 as *const libc::c_char, + p, + if addnl != 0 { + b"\n\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + } +} + +/* **************************************************************** */ +/* */ +/* Input Validation Functions */ +/* */ +/* **************************************************************** */ + +/* Return non-zero if all of the characters in STRING are digits. */ +#[no_mangle] +pub fn all_digits(mut string: *const libc::c_char) -> libc::c_int { + let mut s: *const libc::c_char = 0 as *const libc::c_char; + + s = string; + unsafe { + while *s != 0 { + if DIGIT!(*s) as libc::c_int == 0 { + return 0; + } + s = s.offset(1); + s; + } + } + return 1; +} + +/* Return non-zero if the characters pointed to by STRING constitute a +valid number. Stuff the converted number into RESULT if RESULT is +not null. */ +#[no_mangle] +pub fn legal_number(mut string: *const libc::c_char, mut result: *mut intmax_t) -> libc::c_int { + let mut value: intmax_t = 0; + let mut ep: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if !result.is_null() { + *result = 0 as intmax_t; + } + + if string.is_null() { + return 0; + } + + *__errno_location() = 0; + value = strtoimax(string, &mut ep, 10); + if *__errno_location() != 0 || ep == string as *mut libc::c_char { + return 0; /* errno is set on overflow or underflow */ + } + + /* Skip any trailing whitespace, since strtoimax does not. */ + while *ep as libc::c_int == ' ' as i32 || *ep as libc::c_int == '\t' as i32 { + ep = ep.offset(1); + ep; + } + + /* If *string is not '\0' but *ep is '\0' on return, the entire string + is valid. */ + if *string as libc::c_int != 0 && *ep as libc::c_int == '\0' as i32 { + if !result.is_null() { + *result = value; + } + /* The SunOS4 implementation of strtol() will happily ignore + overflow conditions, so this cannot do overflow correctly + on those systems. */ + return 1; + } + + return 0; + } +} + +/* Return 1 if this token is a legal shell `identifier'; that is, it consists +solely of letters, digits, and underscores, and does not begin with a +digit. */ +#[no_mangle] +pub fn legal_identifier(mut name: *const libc::c_char) -> libc::c_int { + let mut s: *const libc::c_char = 0 as *const libc::c_char; + let mut c: libc::c_uchar = 0; + unsafe { + if name.is_null() + || { + c = *name as libc::c_uchar; + c == 0 + } + || legal_variable_starter!(c) as libc::c_int == 0 as libc::c_int + { + return 0; + } + + s = name.offset(1 as isize); + loop { + c = *s as libc::c_uchar; + if !(c as libc::c_int != 0 as libc::c_int) { + break; + } + if legal_variable_char!(c) as libc::c_int == 0 as libc::c_int { + return 0 as libc::c_int; + } + s = s.offset(1); + s; + } + return 1; + } +} + +/* Return 1 if NAME is a valid value that can be assigned to a nameref +variable. FLAGS can be 2, in which case the name is going to be used +to create a variable. Other values are currently unused, but could +be used to allow values to be stored and indirectly referenced, but +not used in assignments. */ +#[no_mangle] +pub fn valid_nameref_value(mut name: *const libc::c_char, mut flags: libc::c_int) -> libc::c_int { + unsafe { + if name.is_null() || *name as libc::c_int == 0 as libc::c_int { + return 0; + } + + /* valid identifier */ + if legal_identifier(name) != 0 + || flags != 2 as libc::c_int && valid_array_reference(name, 0 as libc::c_int) != 0 + { + return 1; + } + return 0; + } +} + +#[no_mangle] +pub fn check_selfref( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if STREQ!(name, value) { + return 1; + } + + if valid_array_reference(value, 0 as libc::c_int) != 0 { + t = array_variable_name( + value, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut *mut libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if !t.is_null() && STREQ!(name, t) { + libc::free(t as *mut libc::c_void); + return 1; + } + libc::free(t as *mut libc::c_void); + } + } + return 0; /* not a self reference */ +} + +/* Make sure that WORD is a valid shell identifier, i.e. +does not contain a dollar sign, nor is quoted in any way. +If CHECK_WORD is non-zero, +the word is checked to ensure that it consists of only letters, +digits, and underscores, and does not consist of all digits. */ +#[no_mangle] +pub fn check_identifier(mut word: *mut WORD_DESC, mut check_word: libc::c_int) -> libc::c_int { + /* XXX - HASDOLLAR? */ + unsafe { + if (*word).flags & (W_HASDOLLAR | W_QUOTED) != 0 { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"`%s': not a valid identifier\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + (*word).word, + ); + return 0; + } else if check_word != 0 + && (all_digits((*word).word) != 0 || legal_identifier((*word).word) == 0 as libc::c_int) + { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"`%s': not a valid identifier\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + (*word).word, + ); + return 0; + } else { + return 1; + }; + } +} + +/* Return 1 if STRING is a function name that the shell will import from +the environment. Currently we reject attempts to import shell functions +containing slashes, beginning with newlines or containing blanks. In +Posix mode, we require that STRING be a valid shell identifier. Not +used yet. */ +#[no_mangle] +pub fn importable_function_name(mut string: *const libc::c_char, mut len: size_t) -> libc::c_int { + if absolute_program(string) != 0 { + /* don't allow slash */ + return 0; + } + unsafe { + if *string as libc::c_int == '\n' as i32 { + /* can't start with a newline */ + return 0; + } + if shellblank!(*string as libc::c_uchar as isize) != 0 + || shellblank!(len.wrapping_sub(1 as libc::c_ulong) as isize) != 0 + { + return 0; + } + return if posixly_correct != 0 { + legal_identifier(string) + } else { + 1 + }; + } +} + +#[no_mangle] +pub fn exportable_function_name(mut string: *const libc::c_char) -> libc::c_int { + if absolute_program(string) != 0 { + return 0; + } + if unsafe { !(mbschr(string, '=' as i32)).is_null() } { + return 0; + } + return 1; +} + +/* Return 1 if STRING comprises a valid alias name. The shell accepts +essentially all characters except those which must be quoted to the +parser (which disqualifies them from alias expansion anyway) and `/'. */ +#[no_mangle] +pub fn legal_alias_name(mut string: *const libc::c_char, mut flags: libc::c_int) -> libc::c_int { + let mut s: *const libc::c_char = 0 as *const libc::c_char; + s = string; + unsafe { + while *s != 0 { + if shellbreak!(*s as libc::c_uchar as isize) != 0 + || shellxquote!(*s as libc::c_uchar as isize) != 0 + || shellexp!(*s as libc::c_int) + || *s as libc::c_int == '/' as i32 + { + return 0; + } + s = s.offset(1); + s; + } + } + return 1; +} + +/* Returns non-zero if STRING is an assignment statement. The returned value +is the index of the `=' sign. If FLAGS&1 we are expecting a compound assignment +and require an array subscript before the `=' to denote an assignment +statement. */ +#[no_mangle] +pub fn assignment(mut string: *const libc::c_char, mut flags: libc::c_int) -> libc::c_int { + let mut c: libc::c_uchar = 0; + let mut newi: libc::c_int = 0; + let mut indx: libc::c_int = 0; + unsafe { + indx = 0; + c = *string.offset(indx as isize) as libc::c_uchar; + + /* If parser_state includes PST_COMPASSIGN, FLAGS will include 1, so we are + parsing the contents of a compound assignment. If parser_state includes + PST_REPARSE, we are in the middle of an assignment statement and breaking + the words between the parens into words and assignment statements, but + we don't need to check for that right now. Within a compound assignment, + the subscript is required to make the word an assignment statement. If + we don't have a subscript, even if the word is a valid assignment + statement otherwise, we don't want to treat it as one. */ + + if flags & 1 != 0 && c as libc::c_int != '[' as i32 { + return 0; + } else if flags & 1 == 0 && legal_variable_starter!(c) as libc::c_int == 0 as libc::c_int { + return 0; + } + + loop { + c = *string.offset(indx as isize) as libc::c_uchar; + if !(c != 0) { + break; + } + /* The following is safe. Note that '=' at the start of a word + is not an assignment statement. */ + if c as libc::c_int == '=' as i32 { + return indx; + } + + if c as libc::c_int == '[' as i32 { + newi = skipsubscript(string, indx, if flags & 2 != 0 { 1 } else { 0 }); + /* XXX - why not check for blank subscripts here, if we do in + valid_array_reference? */ + let fresh0 = newi; + newi = newi + 1; + if *string.offset(fresh0 as isize) as libc::c_int != ']' as i32 { + return 0 as libc::c_int; + } + if *string.offset(newi as isize) as libc::c_int == '+' as i32 + && *string.offset((newi + 1 as libc::c_int) as isize) as libc::c_int + == '=' as i32 + { + return newi + 1 as libc::c_int; + } + return if *string.offset(newi as isize) as libc::c_int == '=' as i32 { + newi + } else { + 0 as libc::c_int + }; + } + + /* Check for `+=' */ + if c as libc::c_int == '+' as i32 + && *string.offset((indx + 1 as libc::c_int) as isize) as libc::c_int == '=' as i32 + { + return indx + 1 as libc::c_int; + } + + /* Variable names in assignment statements may contain only letters, + digits, and `_'. */ + if legal_variable_char!(c) as libc::c_int == 0 as libc::c_int { + return 0; + } + indx += 1; + indx; + } + return 0; + } +} + +#[no_mangle] +pub fn line_isblank(mut line: *const libc::c_char) -> libc::c_int { + let mut i: libc::c_int = 0; + + if line.is_null() { + return 0; /* XXX */ + } + + i = 0; + unsafe { + while *line.offset(i as isize) != 0 { + if isblank!(*line.offset(i as isize) as libc::c_uchar as libc::c_int as isize) + == 0 as libc::c_int + { + break; + } + i += 1; + i; + } + return (*line.offset(i as isize) as libc::c_int == '\0' as i32) as libc::c_int; + } +} + +/* Make sure no-delay mode is not set on file descriptor FD. */ + +/* Just a wrapper for the define in include/filecntl.h */ +#[no_mangle] +pub fn sh_setclexec(mut fd: libc::c_int) -> libc::c_int { + unsafe { + return SET_CLOSE_ON_EXEC!(fd); + } +} + +/* Return 1 if file descriptor FD is valid; 0 otherwise. */ +#[no_mangle] +pub fn sh_validfd(mut fd: libc::c_int) -> libc::c_int { + unsafe { + return (fcntl(fd, F_GETFD, 0) >= 0) as libc::c_int; + } +} + +#[no_mangle] +pub fn fd_ispipe(mut fd: libc::c_int) -> libc::c_int { + unsafe { + *__errno_location() = 0; + return (lseek(fd, 0 as libc::c_long, SEEK_CUR) < 0 as libc::c_int as libc::c_long + && *__errno_location() == ESPIPE) as libc::c_int; + } +} + +#[no_mangle] +pub fn check_dev_tty() { + let mut tty_fd: libc::c_int = 0; + let mut tty: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + tty_fd = open( + b"/dev/tty\0" as *const u8 as *const libc::c_char, + O_RDWR | O_NONBLOCK, + ); + + if tty_fd < 0 as libc::c_int { + tty = ttyname(fileno(stdin)); + if tty.is_null() { + return; + } + tty_fd = open(tty, O_RDWR | O_NONBLOCK); + } + if tty_fd >= 0 as libc::c_int { + close(tty_fd); + } + } +} + +/* Return 1 if PATH1 and PATH2 are the same file. This is kind of +expensive. If non-NULL STP1 and STP2 point to stat structures +corresponding to PATH1 and PATH2, respectively. */ +#[no_mangle] +pub fn same_file( + mut path1: *const libc::c_char, + mut path2: *const libc::c_char, + mut stp1: *mut crate::src_common::stat, + mut stp2: *mut crate::src_common::stat, +) -> libc::c_int { + let mut st1: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut st2: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + if stp1.is_null() { + if stat(path1, &mut st1) != 0 as libc::c_int { + return 0 as libc::c_int; + } + stp1 = &mut st1; + } + + if stp2.is_null() { + if stat(path2, &mut st2) != 0 as libc::c_int { + return 0 as libc::c_int; + } + stp2 = &mut st2; + } + + return unsafe { + ((*stp1).st_dev == (*stp2).st_dev && (*stp1).st_ino == (*stp2).st_ino) as libc::c_int + }; +} + +/* Move FD to a number close to the maximum number of file descriptors +allowed in the shell process, to avoid the user stepping on it with +redirection and causing us extra work. If CHECK_NEW is non-zero, +we check whether or not the file descriptors are in use before +duplicating FD onto them. MAXFD says where to start checking the +file descriptors. If it's less than 20, we get the maximum value +available from getdtablesize(2). */ +#[no_mangle] +pub fn move_to_high_fd( + mut fd: libc::c_int, + mut check_new: libc::c_int, + mut maxfd: libc::c_int, +) -> libc::c_int { + let mut script_fd: libc::c_int = 0; + let mut nfds: libc::c_int = 0; + let mut ignore: libc::c_int = 0; + unsafe { + if maxfd < 20 as libc::c_int { + nfds = getdtablesize(); + if nfds <= 0 as libc::c_int { + nfds = 20 as libc::c_int; + } + if nfds > HIGH_FD_MAX { + nfds = HIGH_FD_MAX; /* reasonable maximum */ + } + } else { + nfds = maxfd; + } + + nfds -= 1; + nfds; + while check_new != 0 && nfds > 3 as libc::c_int { + if fcntl(nfds, F_GETFD, &mut ignore as *mut libc::c_int) == -(1 as libc::c_int) { + break; + } + nfds -= 1; + nfds; + } + + if nfds > 3 as libc::c_int && fd != nfds && { + script_fd = dup2(fd, nfds); + script_fd != -(1 as libc::c_int) + } { + /* don't close stderr */ + if check_new == 0 as libc::c_int || fd != fileno(stderr) { + close(fd); + } + return script_fd; + } + } + /* OK, we didn't find one less than our artificial maximum; return the + original file descriptor. */ + return fd; +} + +/* Return non-zero if the characters from SAMPLE are not all valid +characters to be found in the first line of a shell script. We +check up to the first newline, or SAMPLE_LEN, whichever comes first. +All of the characters must be printable or whitespace. */ +#[no_mangle] +pub fn check_binary_file( + mut sample: *const libc::c_char, + mut sample_len: libc::c_int, +) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut c: libc::c_uchar = 0; + unsafe { + while i < sample_len { + c = *sample.offset(i as isize) as libc::c_uchar; + if c as libc::c_int == '\n' as i32 { + return 0 as libc::c_int; + } + if c as libc::c_int == '\0' as i32 { + return 1 as libc::c_int; + } + i += 1; + i; + } + + return 0 as libc::c_int; + } +} + +/* **************************************************************** */ +/* */ +/* Functions to manipulate pipes */ +/* */ +/* **************************************************************** */ +#[no_mangle] +pub fn sh_openpipe(mut pv: *mut libc::c_int) -> libc::c_int { + let mut r: libc::c_int = 0; + unsafe { + r = pipe(pv); + if r < 0 { + return r; + } + + *pv.offset(0 as isize) = move_to_high_fd(*pv.offset(0 as isize), 1, 64); + *pv.offset(1 as isize) = move_to_high_fd(*pv.offset(1 as isize), 1, 64); + } + return 0; +} + +#[no_mangle] +pub fn sh_closepipe(mut pv: *mut libc::c_int) -> libc::c_int { + unsafe { + if *pv.offset(0 as isize) >= 0 as libc::c_int { + close(*pv.offset(0 as isize)); + } + + if *pv.offset(1 as isize) >= 0 as libc::c_int { + close(*pv.offset(1 as isize)); + } + + let ref mut fresh1 = *pv.offset(1 as isize); + *fresh1 = -(1 as libc::c_int); + *pv.offset(0 as isize) = *fresh1; + } + return 0; +} + +/* **************************************************************** */ +/* */ +/* Functions to inspect pathnames */ +/* */ +/* **************************************************************** */ +#[no_mangle] +pub fn file_exists(mut fn_0: *const libc::c_char) -> libc::c_int { + let mut sb: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + + return (stat(fn_0, &mut sb) == 0 as libc::c_int) as libc::c_int; +} + +#[no_mangle] +pub fn file_isdir(mut fn_0: *const libc::c_char) -> libc::c_int { + let mut sb: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + + return (stat(fn_0, &mut sb) == 0 && S_ISDIR!(sb.st_mode)) as libc::c_int; +} + +#[no_mangle] +pub fn file_iswdir(mut fn_0: *const libc::c_char) -> libc::c_int { + unsafe { + return (file_isdir(fn_0) != 0 && sh_eaccess(fn_0, W_OK) == 0 as libc::c_int) + as libc::c_int; + } +} + +/* Return 1 if STRING is "." or "..", optionally followed by a directory +separator */ +#[no_mangle] +pub fn path_dot_or_dotdot(mut string: *const libc::c_char) -> libc::c_int { + unsafe { + if string.is_null() + || *string as libc::c_int == '\0' as i32 + || *string as libc::c_int != '.' as i32 + { + return 0 as libc::c_int; + } + + /* string[0] == '.' */ + if PATHSEP!(*string.offset(1 as isize) as libc::c_int) + || *string.offset(1 as isize) as libc::c_int == '.' as i32 + && PATHSEP!(*string.offset(2 as isize) as libc::c_int) + { + return 1; + } + + return 0; + } +} + +/* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd' +to decide whether or not to look up a directory name in $CDPATH. */ +#[no_mangle] +pub fn absolute_pathname(mut string: *const libc::c_char) -> libc::c_int { + unsafe { + if string.is_null() || *string as libc::c_int == '\0' as i32 { + return 0; + } + + if ABSPATH!(string) { + return 1; + } + + /* . and ./ */ + if *string.offset(0 as libc::c_int as isize) as libc::c_int == '.' as i32 + && PATHSEP!(*string.offset(1 as libc::c_int as isize) as libc::c_int) + { + return 1; + } + + /* .. and ../ */ + if *string.offset(0 as libc::c_int as isize) as libc::c_int == '.' as i32 + && *string.offset(1 as libc::c_int as isize) as libc::c_int == '.' as i32 + && PATHSEP!(*string.offset(2 as libc::c_int as isize) as libc::c_int) + { + return 1; + } + + return 0; + } +} + +/* Return 1 if STRING is an absolute program name; it is absolute if it +contains any slashes. This is used to decide whether or not to look +up through $PATH. */ +#[no_mangle] +pub fn absolute_program(mut string: *const libc::c_char) -> libc::c_int { + unsafe { + return (mbschr(string, '/' as i32) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int; + } +} + +/* **************************************************************** */ +/* */ +/* Functions to manipulate pathnames */ +/* */ +/* **************************************************************** */ + +/* Turn STRING (a pathname) into an absolute pathname, assuming that +DOT_PATH contains the symbolic location of `.'. This always +returns a new string, even if STRING was an absolute pathname to +begin with. */ +#[no_mangle] +pub fn make_absolute( + mut string: *const libc::c_char, + mut dot_path: *const libc::c_char, +) -> *mut libc::c_char { + unsafe { + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + + if dot_path.is_null() || ABSPATH!(string) { + result = savestring!(string); + } else { + result = sh_makepath(dot_path, string, 0 as libc::c_int); + } + + return result; + } +} + +/* Return the `basename' of the pathname in STRING (the stuff after the +last '/'). If STRING is `/', just return it. */ +#[no_mangle] +pub fn base_pathname(mut string: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + + if *string.offset(0 as libc::c_int as isize) as libc::c_int == '/' as i32 + && *string.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + return string; + } + + p = strrchr(string, '/' as i32); + return if !p.is_null() { + p = p.offset(1); + p + } else { + string + }; + } +} + +/* Return the full pathname of FILE. Easy. Filenames that begin +with a '/' are returned as themselves. Other filenames have +the current working directory prepended. A new string is +returned in either case. */ +#[no_mangle] +pub fn full_pathname(mut file: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + + file = if *file as libc::c_int == '~' as i32 { + bash_tilde_expand(file, 0 as libc::c_int) + } else { + savestring!(file) + }; + + if ABSPATH!(file) { + return file; + } + + ret = sh_makepath( + 0 as *mut libc::c_void as *mut libc::c_char, + file, + MP_DOCWD | MP_RMDOT, + ); + libc::free(file as *mut libc::c_void); + + return ret; + } +} + +/* A slightly related function. Get the prettiest name of this +directory possible. */ +static mut tdir: [libc::c_char; PATH_MAX as usize] = [0; PATH_MAX as usize]; + +/* Return a pretty pathname. If the first part of the pathname is +the same as $HOME, then replace that with `~'. */ +#[no_mangle] +pub fn polite_directory_format(mut name: *mut libc::c_char) -> *mut libc::c_char { + let mut home: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: libc::c_int = 0; + unsafe { + home = get_string_value(b"HOME\0" as *const u8 as *const libc::c_char); + l = (if !home.is_null() { strlen(home) } else { 0 }) as libc::c_int; + if l > 1 as libc::c_int + && strncmp(home, name, l as usize) == 0 as libc::c_int + && (*name.offset(l as isize) == 0 + || *name.offset(l as isize) as libc::c_int == '/' as i32) + { + strncpy( + tdir.as_mut_ptr().offset(1 as isize), + name.offset(l as isize), + (::core::mem::size_of::<[libc::c_char; 4096]>() as usize).wrapping_sub(2 as usize), + ); + tdir[0 as usize] = '~' as i32 as libc::c_char; + tdir[(::core::mem::size_of::<[libc::c_char; 4096]>() as libc::c_ulong) + .wrapping_sub(1 as libc::c_ulong) as usize] = '\0' as i32 as libc::c_char; + return tdir.as_mut_ptr(); + } else { + return name; + }; + } +} + +/* Trim NAME. If NAME begins with `~/', skip over tilde prefix. Trim to +keep any tilde prefix and PROMPT_DIRTRIM trailing directory components +and replace the intervening characters with `...' */ +#[no_mangle] +pub fn trim_pathname(mut name: *mut libc::c_char, mut maxlen: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut nlen: libc::c_int = 0; + let mut ndirs: libc::c_int = 0; + let mut nskip: intmax_t = 0; + let mut nbeg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nend: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ntail: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + + if name.is_null() || { + nlen = strlen(name) as libc::c_int; + nlen == 0 as libc::c_int + } { + return name; + } + nend = name.offset(nlen as isize); + + v = get_string_value(b"PROMPT_DIRTRIM\0" as *const u8 as *const libc::c_char); + if v.is_null() || *v as libc::c_int == 0 as libc::c_int { + return name; + } + if legal_number(v, &mut nskip) == 0 as libc::c_int + || nskip <= 0 as libc::c_int as libc::c_long + { + return name; + } + + /* Skip over tilde prefix */ + nbeg = name; + if *name.offset(0 as libc::c_int as isize) as libc::c_int == '~' as i32 { + nbeg = name; + while *nbeg != 0 { + if *nbeg as libc::c_int == '/' as i32 { + nbeg = nbeg.offset(1); + nbeg; + break; + } else { + nbeg = nbeg.offset(1); + nbeg; + } + } + } + if *nbeg as libc::c_int == 0 as libc::c_int { + return name; + } + + ndirs = 0 as libc::c_int; + ntail = nbeg; + while *ntail != 0 { + if *ntail as libc::c_int == '/' as i32 { + ndirs += 1; + ndirs; + } + ntail = ntail.offset(1); + ntail; + } + if (ndirs as libc::c_long) < nskip { + return name; + } + + ntail = if *nend as libc::c_int == '/' as i32 { + nend + } else { + nend.offset(-(1 as libc::c_int as isize)) + }; + while ntail > nbeg { + if *ntail as libc::c_int == '/' as i32 { + nskip -= 1; + nskip; + } + if nskip == 0 as libc::c_int as libc::c_long { + break; + } + ntail = ntail.offset(-1); + ntail; + } + if ntail == nbeg { + return name; + } + + /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */ + nlen = ntail.offset_from(nbeg) as libc::c_long as libc::c_int; + if nlen <= 3 as libc::c_int { + return name; + } + + let fresh2 = nbeg; + nbeg = nbeg.offset(1); + *fresh2 = '.' as i32 as libc::c_char; + let fresh3 = nbeg; + nbeg = nbeg.offset(1); + *fresh3 = '.' as i32 as libc::c_char; + let fresh4 = nbeg; + nbeg = nbeg.offset(1); + *fresh4 = '.' as i32 as libc::c_char; + + nlen = nend.offset_from(ntail) as libc::c_long as libc::c_int; + memmove( + nbeg as *mut libc::c_void, + ntail as *const libc::c_void, + nlen as usize, + ); + *nbeg.offset(nlen as isize) = '\0' as i32 as libc::c_char; + + return name; + } +} + +/* Return a printable representation of FN without special characters. The +caller is responsible for freeing memory if this returns something other +than its argument. If FLAGS is non-zero, we are printing for portable +re-input and should single-quote filenames appropriately. */ +#[no_mangle] +pub fn printable_filename( + mut fn_0: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut newf: *mut libc::c_char = 0 as *mut libc::c_char; + + if ansic_shouldquote(fn_0) != 0 { + newf = ansic_quote(fn_0, 0 as libc::c_int, 0 as *mut libc::c_int); + } else if flags != 0 && sh_contains_shell_metas(fn_0) != 0 { + newf = sh_single_quote(fn_0); + } else { + newf = fn_0; + } + + return newf; + } +} + +/* Given a string containing units of information separated by colons, +return the next one pointed to by (P_INDEX), or NULL if there are no more. +Advance (P_INDEX) to the character after the colon. */ +#[no_mangle] +pub fn extract_colon_unit( + mut string: *mut libc::c_char, + mut p_index: *mut libc::c_int, +) -> *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut start: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + + if string.is_null() { + return string; + } + unsafe { + len = strlen(string) as libc::c_int; + if *p_index >= len { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + i = *p_index; + + /* Each call to this routine leaves the index pointing at a colon if + there is more to the path. If I is > 0, then increment past the + `:'. If I is 0, then the path has a leading colon. Trailing colons + are handled OK by the `else' part of the if statement; an empty + string is returned in that case. */ + if i != 0 && *string.offset(i as isize) as libc::c_int == ':' as i32 { + i += 1; + i; + } + + start = i; + while *string.offset(i as isize) as libc::c_int != 0 + && *string.offset(i as isize) as libc::c_int != ':' as i32 + { + i += 1; + i; + } + + *p_index = i; + + if i == start { + if *string.offset(i as isize) != 0 { + *p_index += 1; + *p_index; + } + /* Return "" in the case of a trailing `:'. */ + value = libc::malloc(1 as usize) as *mut libc::c_char; + *value.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } else { + value = substring(string, start, i); + } + } + return value; +} + +static mut bash_tilde_prefixes: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; +static mut bash_tilde_prefixes2: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; +static mut bash_tilde_suffixes: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; +static mut bash_tilde_suffixes2: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; + +/* If tilde_expand hasn't been able to expand the text, perhaps it +is a special shell expansion. This function is installed as the +tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+. +If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the +directory stack. */ +fn bash_special_tilde_expansions(mut text: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + + result = 0 as *mut libc::c_void as *mut libc::c_char; + if *text.offset(0 as libc::c_int as isize) as libc::c_int == '+' as i32 + && *text.offset(1 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + result = get_string_value(b"PWD\0" as *const u8 as *const libc::c_char); + } else if *text.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *text.offset(1 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + result = get_string_value(b"OLDPWD\0" as *const u8 as *const libc::c_char); + } else if DIGIT!(*text) + || (*text as libc::c_int == '+' as i32 || *text as libc::c_int == '-' as i32) + && DIGIT!(*text.offset(1 as libc::c_int as isize)) + { + result = get_dirstack_from_string(text); + } + + return if !result.is_null() { + savestring!(result) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } +} + +/* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as +well as handling special tilde prefixes; `:~" and `=~' are indications +that we should do tilde expansion. */ +#[no_mangle] +pub fn tilde_initialize() { + unsafe { + static mut times_called: libc::c_int = 0 as libc::c_int; + + /* Tell the tilde expander that we want a crack first. */ + tilde_expansion_preexpansion_hook = + ::core::mem::transmute:: *mut libc::c_char>, Option>( + Some(::core::mem::transmute::< + fn(*mut libc::c_char) -> *mut libc::c_char, + fn() -> *mut libc::c_char, + >(bash_special_tilde_expansions)), + ); + + /* Tell the tilde expander about special strings which start a tilde + expansion, and the special strings that end one. Only do this once. + tilde_initialize () is called from within bashline_reinitialize (). */ + let fresh5 = times_called; + times_called = times_called + 1; + if fresh5 == 0 as libc::c_int { + bash_tilde_prefixes = strvec_create(3 as libc::c_int); + let ref mut fresh6 = *bash_tilde_prefixes.offset(0 as libc::c_int as isize); + *fresh6 = b"=~\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + let ref mut fresh7 = *bash_tilde_prefixes.offset(1 as libc::c_int as isize); + *fresh7 = b":~\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + let ref mut fresh8 = *bash_tilde_prefixes.offset(2 as libc::c_int as isize); + *fresh8 = 0 as *mut libc::c_void as *mut libc::c_char; + + bash_tilde_prefixes2 = strvec_create(2 as libc::c_int); + let ref mut fresh9 = *bash_tilde_prefixes2.offset(0 as libc::c_int as isize); + *fresh9 = b":~\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + let ref mut fresh10 = *bash_tilde_prefixes2.offset(1 as libc::c_int as isize); + *fresh10 = 0 as *mut libc::c_void as *mut libc::c_char; + + tilde_additional_prefixes = bash_tilde_prefixes; + + bash_tilde_suffixes = strvec_create(3 as libc::c_int); + let ref mut fresh11 = *bash_tilde_suffixes.offset(0 as libc::c_int as isize); + *fresh11 = b":\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + let ref mut fresh12 = *bash_tilde_suffixes.offset(1 as libc::c_int as isize); + *fresh12 = b"=~\0" as *const u8 as *const libc::c_char as *mut libc::c_char; /* XXX - ?? */ + let ref mut fresh13 = *bash_tilde_suffixes.offset(2 as libc::c_int as isize); + *fresh13 = 0 as *mut libc::c_void as *mut libc::c_char; + + tilde_additional_suffixes = bash_tilde_suffixes; + + bash_tilde_suffixes2 = strvec_create(2 as libc::c_int); + let ref mut fresh14 = *bash_tilde_suffixes2.offset(0 as libc::c_int as isize); + *fresh14 = b":\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + let ref mut fresh15 = *bash_tilde_suffixes2.offset(1 as libc::c_int as isize); + *fresh15 = 0 as *mut libc::c_void as *mut libc::c_char; + } + } +} + +fn unquoted_tilde_word(mut s: *const libc::c_char) -> libc::c_int { + let mut r: *const libc::c_char = 0 as *const libc::c_char; + r = s; + unsafe { + while TILDE_END!(*r as libc::c_int) as libc::c_int == 0 as libc::c_int { + match *r as u8 as char { + '\\' | '\'' | '"' => return 0, + _ => {} + } + r = r.offset(1); + r; + } + } + return 1; +} + +/* Find the end of the tilde-prefix starting at S, and return the tilde +prefix in newly-allocated memory. Return the length of the string in +*LENP. FLAGS tells whether or not we're in an assignment context -- +if so, `:' delimits the end of the tilde prefix as well. */ +#[no_mangle] +pub fn bash_tilde_find_word( + mut s: *const libc::c_char, + mut flags: libc::c_int, + mut lenp: *mut libc::c_int, +) -> *mut libc::c_char { + let mut r: *const libc::c_char = 0 as *const libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: libc::c_int = 0; + + r = s; + unsafe { + while *r as libc::c_int != 0 && *r as libc::c_int != '/' as i32 { + /* Short-circuit immediately if we see a quote character. Even though + POSIX says that `the first unquoted slash' (or `:') terminates the + tilde-prefix, in practice, any quoted portion of the tilde prefix + will cause it to not be expanded. */ + if *r as libc::c_int == '\\' as i32 + || *r as libc::c_int == '\'' as i32 + || *r as libc::c_int == '"' as i32 + { + ret = savestring!(s); + if !lenp.is_null() { + *lenp = 0 as libc::c_int; + } + return ret; + } else { + if flags != 0 && *r as libc::c_int == ':' as i32 { + break; + } + r = r.offset(1); + r; + } + } + l = r.offset_from(s) as libc::c_long as libc::c_int; + ret = libc::malloc((l + 1 as libc::c_int) as usize) as *mut libc::c_char; + strncpy(ret, s, l as usize); + *ret.offset(l as isize) = '\0' as i32 as libc::c_char; + if !lenp.is_null() { + *lenp = l; + } + } + return ret; +} + +/* Tilde-expand S by running it through the tilde expansion library. +ASSIGN_P is 1 if this is a variable assignment, so the alternate +tilde prefixes should be enabled (`=~' and `:~', see above). If +ASSIGN_P is 2, we are expanding the rhs of an assignment statement, +so `=~' is not valid. */ +#[no_mangle] +pub fn bash_tilde_expand( + mut s: *const libc::c_char, + mut assign_p: libc::c_int, +) -> *mut libc::c_char { + let mut r: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + tilde_additional_prefixes = if assign_p == 0 as libc::c_int { + 0 as *mut *mut libc::c_char + } else if assign_p == 2 as libc::c_int { + bash_tilde_prefixes2 + } else { + bash_tilde_prefixes + }; + if assign_p == 2 as libc::c_int { + tilde_additional_suffixes = bash_tilde_suffixes2; + } + + r = if *s as libc::c_int == '~' as i32 { + unquoted_tilde_word(s) + } else { + 1 as libc::c_int + }; + ret = if r != 0 { + tilde_expand(s) + } else { + savestring!(s) + }; + + QUIT!(); + } + return ret; +} + +/* **************************************************************** */ +/* */ +/* Functions to manipulate and search the group list */ +/* */ +/* **************************************************************** */ + +static mut ngroups: libc::c_int = 0; +static mut maxgroups: libc::c_int = 0; + +/* The set of groups that this user is a member of. */ +static mut group_array: *mut gid_t = 0 as *const libc::c_void as *mut libc::c_void as *mut gid_t; + +fn initialize_group_array() { + let mut i: libc::c_int = 0; + unsafe { + if maxgroups == 0 as libc::c_int { + maxgroups = getmaxgroups(); + } + + ngroups = 0 as libc::c_int; + group_array = libc::realloc( + group_array as *mut libc::c_void, + ((maxgroups as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::() as libc::c_ulong)) + as usize, + ) as *mut gid_t; + + ngroups = getgroups(maxgroups, group_array); + + /* If getgroups returns nothing, or the OS does not support getgroups(), + make sure the groups array includes at least the current gid. */ + if ngroups == 0 as libc::c_int { + *group_array.offset(0 as libc::c_int as isize) = current_user.gid; + ngroups = 1 as libc::c_int; + } + + /* If the primary group is not in the groups array, add it as group_array[0] + and shuffle everything else up 1, if there's room. */ + i = 0 as libc::c_int; + while i < ngroups { + if current_user.gid == *group_array.offset(i as isize) { + break; + } + i += 1; + i; + } + if i == ngroups && ngroups < maxgroups { + i = ngroups; + while i > 0 as libc::c_int { + *group_array.offset(i as isize) = + *group_array.offset((i - 1 as libc::c_int) as isize); + i -= 1; + i; + } + *group_array.offset(0 as libc::c_int as isize) = current_user.gid; + ngroups += 1; + ngroups; + } + if *group_array.offset(0 as libc::c_int as isize) != current_user.gid { + i = 0 as libc::c_int; + while i < ngroups { + if *group_array.offset(i as isize) == current_user.gid { + break; + } + i += 1; + i; + } + if i < ngroups { + *group_array.offset(i as isize) = *group_array.offset(0 as libc::c_int as isize); + *group_array.offset(0 as libc::c_int as isize) = current_user.gid; + } + } + } +} + +/* Return non-zero if GID is one that we have in our groups list. */ +#[no_mangle] +pub fn group_member(mut gid: gid_t) -> libc::c_int { + let mut i: libc::c_int = 0; + unsafe { + /* Short-circuit if possible, maybe saving a call to getgroups(). */ + if gid == current_user.gid || gid == current_user.egid { + return 1 as libc::c_int; + } + if ngroups == 0 as libc::c_int { + initialize_group_array(); + } + + /* In case of error, the user loses. */ + if ngroups <= 0 as libc::c_int { + return 0 as libc::c_int; + } + + /* Search through the list looking for GID. */ + i = 0 as libc::c_int; + while i < ngroups { + if gid == *group_array.offset(i as isize) { + return 1 as libc::c_int; + } + i += 1; + i; + } + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn get_group_list(mut ngp: *mut libc::c_int) -> *mut *mut libc::c_char { + static mut group_vector: *mut *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut *mut libc::c_char; + let mut i: libc::c_int = 0; + unsafe { + if !group_vector.is_null() { + if !ngp.is_null() { + *ngp = ngroups; + } + return group_vector; + } + + if ngroups == 0 as libc::c_int { + initialize_group_array(); + } + + if ngroups <= 0 as libc::c_int { + if !ngp.is_null() { + *ngp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + group_vector = strvec_create(ngroups); + i = 0 as libc::c_int; + while i < ngroups { + let ref mut fresh16 = *group_vector.offset(i as isize); + *fresh16 = itos(*group_array.offset(i as isize) as intmax_t); + i += 1; + i; + } + + if !ngp.is_null() { + *ngp = ngroups; + } + return group_vector; + } +} + +#[no_mangle] +pub fn get_group_array(mut ngp: *mut libc::c_int) -> *mut libc::c_int { + let mut i: libc::c_int = 0; + static mut group_iarray: *mut libc::c_int = + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_int; + unsafe { + if !group_iarray.is_null() { + if !ngp.is_null() { + *ngp = ngroups; + } + return group_iarray; + } + + if ngroups == 0 as libc::c_int { + initialize_group_array(); + } + + if ngroups <= 0 as libc::c_int { + if !ngp.is_null() { + *ngp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut libc::c_int; + } + + group_iarray = libc::malloc( + (ngroups as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::() as libc::c_ulong) + as usize, + ) as *mut libc::c_int; + i = 0 as libc::c_int; + while i < ngroups { + *group_iarray.offset(i as isize) = *group_array.offset(i as isize) as libc::c_int; + i += 1; + i; + } + + if !ngp.is_null() { + *ngp = ngroups; + } + return group_iarray; + } +} + +/* **************************************************************** */ +/* */ +/* Miscellaneous functions */ +/* */ +/* **************************************************************** */ + +/* Return a value for PATH that is guaranteed to find all of the standard +utilities. This uses Posix.2 configuration variables, if present. It +uses a value defined in config.h as a last resort. */ +#[no_mangle] +pub fn conf_standard_path() -> *mut libc::c_char { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: size_t = 0; + unsafe { + len = confstr( + _CS_PATH, + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int as usize, + ) as size_t; + if len > 0 as libc::c_int as libc::c_ulong { + p = libc::malloc(len.wrapping_add(2 as libc::c_int as libc::c_ulong) as usize) + as *mut libc::c_char; + confstr(_CS_PATH, p, len as usize); + return p; + } else { + return savestring!(STANDARD_UTILS_PATH!()); + }; + } +} +#[no_mangle] +pub fn default_columns() -> libc::c_int { + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + let mut c: libc::c_int = 0; + unsafe { + c = -(1 as libc::c_int); + v = get_string_value(b"COLUMNS\0" as *const u8 as *const libc::c_char); + if !v.is_null() && *v as libc::c_int != 0 { + c = atoi(v); + if c > 0 as libc::c_int { + return c; + } + } + + if check_window_size != 0 { + get_new_window_size(0 as libc::c_int, 0 as *mut libc::c_int, &mut c); + } + + return if c > 0 as libc::c_int { + c + } else { + 80 as libc::c_int + }; + } +} diff --git a/utshell-0.5.0/src/hashcmd.rs b/utshell-0.5.0/src/hashcmd.rs new file mode 100644 index 00000000..db882572 --- /dev/null +++ b/utshell-0.5.0/src/hashcmd.rs @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::findcmd::executable_file; +use crate::general::same_file; +use crate::hashlib::{hash_create, hash_flush, hash_insert, hash_remove, hash_search}; +use crate::src_common::*; + +#[no_mangle] +pub fn phash_create() { + unsafe { + if hashed_filenames.is_null() { + hashed_filenames = hash_create(FILENAME_HASH_BUCKETS as libc::c_int); + } + } +} + +fn phash_freedata(mut data: *mut c_void) { + unsafe { + free((*(data as *mut PATH_DATA)).path as *mut c_void); + free(data); + } +} + +#[no_mangle] +pub fn phash_flush() { + unsafe { + if !hashed_filenames.is_null() { + hash_flush(hashed_filenames, Some(phash_freedata)); + } + } +} + +#[no_mangle] +pub fn phash_remove(mut filename: *const libc::c_char) -> libc::c_int { + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + if hashing_enabled == 0 || hashed_filenames.is_null() { + return 0 as libc::c_int; + } + + item = hash_remove(filename, hashed_filenames, 0); + if !item.is_null() { + if !((*item).data).is_null() { + phash_freedata((*item).data); + } + free((*item).key as *mut c_void); + free(item as *mut c_void); + return 0; + } + return 1; + } +} + +#[no_mangle] +pub fn phash_insert( + mut filename: *mut libc::c_char, + mut full_path: *mut libc::c_char, + mut check_dot: libc::c_int, + mut found: libc::c_int, +) { + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + if hashing_enabled == 0 { + return; + } + + if hashed_filenames.is_null() { + phash_create(); + } + + item = hash_insert(filename, hashed_filenames, 0); + if !((*item).data).is_null() { + free((*((*item).data as *mut PATH_DATA)).path as *mut c_void); + } else { + (*item).key = savestring!(filename); + (*item).data = libc::malloc(::std::mem::size_of::() as usize); + } + + (*((*item).data as *mut PATH_DATA)).path = savestring!(full_path); + (*((*item).data as *mut PATH_DATA)).flags = 0; + if check_dot != 0 { + (*((*item).data as *mut PATH_DATA)).flags |= HASH_CHKDOT as libc::c_int; + } + if *full_path as libc::c_int != '/' as i32 { + (*((*item).data as *mut PATH_DATA)).flags |= HASH_RELPATH as libc::c_int; + } + (*item).times_found = found; + } +} + +#[no_mangle] +pub fn phash_search(mut filename: *const libc::c_char) -> *mut libc::c_char { + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut path: *mut libc::c_char = 0 as *mut libc::c_char; + let mut dotted_filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tail: *mut libc::c_char = 0 as *mut libc::c_char; + let mut same: libc::c_int = 0; + unsafe { + if hashing_enabled == 0 || hashed_filenames.is_null() { + return 0 as *mut libc::c_char; + } + + item = hash_search(filename, hashed_filenames, 0); + + if item.is_null() { + return 0 as *mut libc::c_char; + } + path = (*((*item).data as *mut PATH_DATA)).path; + if (*((*item).data as *mut PATH_DATA)).flags + & (HASH_CHKDOT as libc::c_int | HASH_RELPATH as libc::c_int) + != 0 + { + tail = if (*((*item).data as *mut PATH_DATA)).flags & HASH_RELPATH as libc::c_int != 0 { + path + } else { + filename as *mut libc::c_char + }; + if *tail.offset(0 as libc::c_int as isize) as libc::c_int != '.' as i32 + || *tail.offset(1 as libc::c_int as isize) as libc::c_int != '/' as i32 + { + dotted_filename = libc::malloc( + (3 as libc::c_int as libc::c_ulong).wrapping_add(strlen(tail)) as usize, + ) as *mut libc::c_char; + *dotted_filename.offset(0 as isize) = '.' as i32 as libc::c_char; + *dotted_filename.offset(1 as isize) = '/' as i32 as libc::c_char; + strcpy(dotted_filename.offset(2 as libc::c_int as isize), tail); + } else { + dotted_filename = savestring!(tail); + } + if executable_file(dotted_filename) != 0 { + return dotted_filename; + } + free(dotted_filename as *mut c_void); + + if *path as libc::c_int == '.' as i32 { + same = 0 as libc::c_int; + tail = strrchr(path, '/' as i32); + if !tail.is_null() { + *tail = '\u{0}' as i32 as libc::c_char; + same = same_file( + b".\0" as *const u8 as *const libc::c_char, + path, + 0 as *mut c_void as *mut crate::src_common::stat, + 0 as *mut c_void as *mut crate::src_common::stat, + ); + *tail = '/' as i32 as libc::c_char; + } + return if same != 0 { + 0 as *mut c_void as *mut libc::c_char + } else { + savestring!(path) + }; + } + } + return savestring!(path); + } +} diff --git a/utshell-0.5.0/src/hashlib.rs b/utshell-0.5.0/src/hashlib.rs new file mode 100644 index 00000000..e207d6d1 --- /dev/null +++ b/utshell-0.5.0/src/hashlib.rs @@ -0,0 +1,411 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +#[no_mangle] +pub fn hash_create(mut buckets: libc::c_int) -> *mut HASH_TABLE { + unsafe { + let mut new_table: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut i: libc::c_int = 0; + + new_table = malloc(::std::mem::size_of::() as usize) as *mut HASH_TABLE; + if buckets == 0 { + buckets = DEFAULT_HASH_BUCKETS as libc::c_int; + } + + (*new_table).bucket_array = malloc( + (buckets as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::<*mut BUCKET_CONTENTS>() as libc::c_ulong) + as usize, + ) as *mut *mut BUCKET_CONTENTS; + (*new_table).nbuckets = buckets; + (*new_table).nentries = 0; + + i = 0; + while i < buckets { + *((*new_table).bucket_array).offset(i as isize) = 0 as *mut BUCKET_CONTENTS; + + i += 1; + } + return new_table; + } +} + +#[no_mangle] +pub fn hash_size(mut table: *mut HASH_TABLE) -> libc::c_int { + unsafe { + return HASH_ENTRIES!(table); + } +} + +fn copy_bucket_array( + mut ba: *mut BUCKET_CONTENTS, + mut cpdata: Option, +) -> *mut BUCKET_CONTENTS { + unsafe { + let mut new_bucket: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut n: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut e: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + + if ba.is_null() { + return 0 as *mut BUCKET_CONTENTS; + } + + n = 0 as *mut BUCKET_CONTENTS; + e = ba; + while !e.is_null() { + if n.is_null() { + new_bucket = malloc(::std::mem::size_of::() as usize) + as *mut BUCKET_CONTENTS; + n = new_bucket; + } else { + (*n).next = malloc(::std::mem::size_of::() as usize) + as *mut BUCKET_CONTENTS; + n = (*n).next; + } + + (*n).key = savestring!((*e).key); + (*n).data = (if !((*e).data).is_null() { + if cpdata.is_some() { + (cpdata.expect("non-null function pointer"))((*e).data as *mut libc::c_char) + } else { + savestring!((*e).data as *const libc::c_char) + } + } else { + 0 as *mut libc::c_char + }) as *mut c_void; + + (*n).khash = (*e).khash; + (*n).times_found = (*e).times_found; + (*n).next = 0 as *mut c_void as *mut BUCKET_CONTENTS; + + e = (*e).next; + } + return new_bucket; + } +} + +fn hash_rehash(mut table: *mut HASH_TABLE, mut nsize: libc::c_int) { + let mut osize: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut old_bucket_array: *mut *mut BUCKET_CONTENTS = 0 as *mut *mut BUCKET_CONTENTS; + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut next: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + if table.is_null() || nsize == (*table).nbuckets { + return; + } + + osize = (*table).nbuckets; + old_bucket_array = (*table).bucket_array; + + (*table).nbuckets = nsize; + (*table).bucket_array = malloc( + ((*table).nbuckets as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::<*mut BUCKET_CONTENTS>() as u64) + as usize, + ) as *mut *mut BUCKET_CONTENTS; + + i = 0; + while i < (*table).nbuckets { + *((*table).bucket_array).offset(i as isize) = 0 as *mut BUCKET_CONTENTS; + i += 1; + } + + j = 0; + while j < osize { + item = *old_bucket_array.offset(j as isize); + while !item.is_null() { + next = (*item).next; + i = ((*item).khash & ((*table).nbuckets - 1 as libc::c_int) as libc::c_uint) + as libc::c_int; + (*item).next = *((*table).bucket_array).offset(i as isize); + *((*table).bucket_array).offset(i as isize) = item; + + item = next; + } + j += 1; + } + + free(old_bucket_array as *mut c_void); + } +} + +fn hash_grow(mut table: *mut HASH_TABLE) { + let mut nsize: libc::c_int = 0; + unsafe { + nsize = (*table).nbuckets * HASH_REHASH_MULTIPLIER!(); + if nsize > 0 { + hash_rehash(table, nsize); + } + } +} + +fn hash_shrink(mut table: *mut HASH_TABLE) { + let mut nsize: libc::c_int = 0; + unsafe { + nsize = (*table).nbuckets / HASH_REHASH_MULTIPLIER!(); + hash_rehash(table, nsize); + } +} + +#[no_mangle] +pub fn hash_copy( + mut table: *mut HASH_TABLE, + mut cpdata: Option, +) -> *mut HASH_TABLE { + let mut new_table: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut i: libc::c_int = 0; + unsafe { + if table.is_null() { + return 0 as *mut HASH_TABLE; + } + new_table = hash_create((*table).nbuckets); + + i = 0; + while i < (*table).nbuckets { + *((*new_table).bucket_array).offset(i as isize) = + copy_bucket_array(*((*table).bucket_array).offset(i as isize), cpdata); + i += 1; + } + + (*new_table).nentries = (*table).nentries; + } + return new_table; +} + +#[no_mangle] +pub fn hash_string(mut s: *const libc::c_char) -> libc::c_uint { + unsafe { + let mut i: libc::c_uint = 0; + + i = FNV_OFFSET!(); + while *s != 0 { + i = i.wrapping_add( + (i << 1 as libc::c_int) + .wrapping_add(i << 4 as libc::c_int) + .wrapping_add(i << 7 as libc::c_int) + .wrapping_add(i << 8 as libc::c_int) + .wrapping_add(i << 24 as libc::c_int), + ); + i ^= *s as libc::c_uint; + s = s.offset(1); + } + return i; + } +} + +#[no_mangle] +pub fn hash_bucket(mut string: *const libc::c_char, mut table: *mut HASH_TABLE) -> libc::c_int { + let mut h: libc::c_uint = 0; + unsafe { + return HASH_BUCKET!(string, table, h) as i32; + } +} + +#[no_mangle] +pub fn hash_search( + mut string: *const libc::c_char, + mut table: *mut HASH_TABLE, + mut flags: libc::c_int, +) -> *mut BUCKET_CONTENTS { + let mut list: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut bucket: libc::c_int = 0; + let mut hv: libc::c_uint = 0; + unsafe { + if table.is_null() + || flags & HASH_CREATE as libc::c_int == 0 as libc::c_int + && HASH_ENTRIES!(table) == 0 as libc::c_int + { + return 0 as *mut BUCKET_CONTENTS; + } + + bucket = HASH_BUCKET!(string, table, hv) as i32; + + list = if !((*table).bucket_array).is_null() { + *((*table).bucket_array).offset(bucket as isize) + } else { + 0 as *mut BUCKET_CONTENTS + }; + while !list.is_null() { + if hv == (*list).khash && STREQ!((*list).key, string) { + (*list).times_found += 1; + return list; + } + list = (*list).next; + } + + if flags & HASH_CREATE as libc::c_int != 0 { + if HASH_SHOULDGROW!(table) { + hash_grow(table); + hv = hash_string(string); + bucket = HASH_BUCKET!(string, table, hv) as i32; + } + list = + malloc(::std::mem::size_of::() as usize) as *mut BUCKET_CONTENTS; + (*list).next = *((*table).bucket_array).offset(bucket as isize); + *((*table).bucket_array).offset(bucket as isize) = list; + + (*list).data = 0 as *mut c_void; + (*list).key = string as *mut libc::c_char; + (*list).khash = hv; + (*list).times_found = 0 as libc::c_int; + + (*table).nentries += 1; + return list; + } + } + return 0 as *mut BUCKET_CONTENTS; +} + +#[no_mangle] +pub fn hash_remove( + mut string: *const libc::c_char, + mut table: *mut HASH_TABLE, + mut flags: libc::c_int, +) -> *mut BUCKET_CONTENTS { + let mut bucket: libc::c_int = 0; + let mut prev: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut temp: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut hv: libc::c_uint = 0; + unsafe { + if table.is_null() || HASH_ENTRIES!(table) == 0 as libc::c_int { + return 0 as *mut BUCKET_CONTENTS; + } + + bucket = HASH_BUCKET!(string, table, hv) as i32; + prev = 0 as *mut c_void as *mut BUCKET_CONTENTS; + + temp = *((*table).bucket_array).offset(bucket as isize); + while !temp.is_null() { + if hv == (*temp).khash && STREQ!((*temp).key, string) { + if !prev.is_null() { + (*prev).next = (*temp).next; + } else { + *((*table).bucket_array).offset(bucket as isize) = (*temp).next; + } + (*table).nentries -= 1; + return temp; + } + prev = temp; + temp = (*temp).next; + } + } + return 0 as *mut c_void as *mut BUCKET_CONTENTS; +} + +#[no_mangle] +pub fn hash_insert( + mut string: *mut libc::c_char, + mut table: *mut HASH_TABLE, + mut flags: libc::c_int, +) -> *mut BUCKET_CONTENTS { + unsafe { + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut bucket: libc::c_int = 0; + let mut hv: libc::c_uint = 0; + + if table.is_null() { + table = hash_create(0 as libc::c_int); + } + item = if flags & 0x1 as libc::c_int != 0 { + 0 as *mut c_void as *mut BUCKET_CONTENTS + } else { + hash_search(string, table, 0 as libc::c_int) + }; + if item.is_null() { + if HASH_SHOULDGROW!(table) { + hash_grow(table); + } + + bucket = HASH_BUCKET!(string, table, hv) as i32; + item = + malloc(::std::mem::size_of::() as usize) as *mut BUCKET_CONTENTS; + + (*item).next = *((*table).bucket_array).offset(bucket as isize); + *((*table).bucket_array).offset(bucket as isize) = item; + + (*item).data = 0 as *mut c_void; + (*item).key = string; + (*item).khash = hv; + (*item).times_found = 0 as libc::c_int; + + (*table).nentries += 1; + } + + return item; + } +} + +#[no_mangle] +pub fn hash_flush(mut table: *mut HASH_TABLE, mut free_data: sh_free_func_t) { + let mut i: libc::c_int = 0; + let mut bucket: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + if table.is_null() || HASH_ENTRIES!(table) == 0 as libc::c_int { + return; + } + + i = 0; + while i < (*table).nbuckets { + bucket = *((*table).bucket_array).offset(i as isize); + while !bucket.is_null() { + item = bucket; + bucket = (*bucket).next; + + if free_data.is_some() { + (Some(free_data.expect("non-null function pointer"))) + .expect("non-null function pointer")((*item).data); + } else { + free((*item).data); + } + free((*item).key as *mut c_void); + free(item as *mut c_void); + } + + *((*table).bucket_array).offset(i as isize) = 0 as *mut BUCKET_CONTENTS; + i += 1; + } + (*table).nentries = 0; + } +} + +#[no_mangle] +pub fn hash_dispose(mut table: *mut HASH_TABLE) { + unsafe { + free((*table).bucket_array as *mut c_void); + free(table as *mut c_void); + } +} + +#[no_mangle] +pub fn hash_walk(mut table: *mut HASH_TABLE, mut func: Option) { + let mut i: libc::c_int = 0; + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + if table.is_null() || HASH_ENTRIES!(table) == 0 as libc::c_int { + return; + } + i = 0 as libc::c_int; + + while i < (*table).nbuckets { + item = hash_items!(i, table); + + while !item.is_null() { + if (Some(func.expect("non-null function pointer"))) + .expect("non-null function pointer")(item) + < 0 as libc::c_int + { + return; + } + item = (*item).next; + } + i += 1; + } + } +} diff --git a/utshell-0.5.0/src/input.rs b/utshell-0.5.0/src/input.rs new file mode 100644 index 00000000..c99d36c8 --- /dev/null +++ b/utshell-0.5.0/src/input.rs @@ -0,0 +1,660 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::general::sh_unset_nodelay_mode; +use crate::src_common::*; +use crate::stringlib::xbcopy; +use crate::trap::run_pending_traps; +use crate::y_tab::{bash_input, init_yy_io, return_EOF}; + +#[inline] +fn fstat(mut __fd: libc::c_int, mut __statbuf: *mut crate::src_common::stat) -> libc::c_int { + unsafe { + return __fxstat( + 1 as libc::c_int, + __fd, + __statbuf as *mut crate::src_common::stat, + ); + } +} + +/* Functions to handle reading input on systems that don't restart read(2) +if a signal is received. */ + +static mut localbuf: [libc::c_char; 1024] = [0; 1024]; +static mut local_index: libc::c_int = 0 as libc::c_int; +static mut local_bufused: libc::c_int = 0 as libc::c_int; + +/* Posix and USG systems do not guarantee to restart read () if it is +interrupted by a signal. We do the read ourselves, and restart it +if it returns EINTR. */ +#[no_mangle] +pub fn getc_with_restart(mut stream: *mut FILE) -> libc::c_int { + unsafe { + let mut uc: libc::c_uchar = 0; + + CHECK_TERMSIG!(); + + /* Try local buffering to reduce the number of read(2) calls. */ + if local_index == local_bufused || local_bufused == 0 as libc::c_int { + loop { + QUIT!(); + run_pending_traps(); + + local_bufused = read( + fileno(stream), + localbuf.as_mut_ptr() as *mut libc::c_void, + ::core::mem::size_of::<[libc::c_char; 1024]>() as usize, + ) as libc::c_int; + if local_bufused > 0 as libc::c_int { + break; + } + if local_bufused == 0 as libc::c_int { + local_index = 0 as libc::c_int; + return EOF; + } else if *__errno_location() == X_EAGAIN || *__errno_location() == X_EWOULDBLOCK { + if sh_unset_nodelay_mode(fileno(stream)) < 0 as libc::c_int { + sys_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot reset nodelay mode for fd %d\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + fileno(stream), + ); + local_bufused = 0 as libc::c_int; + local_index = local_bufused; + return EOF; + } + } else if *__errno_location() != EINTR { + local_bufused = 0 as libc::c_int; + local_index = local_bufused; + return EOF; + } else if interrupt_state != 0 || terminating_signal != 0 { + /* QUIT; */ + local_bufused = 0 as libc::c_int; + local_index = local_bufused; + } + } + local_index = 0 as libc::c_int; + } + let fresh0 = local_index; + local_index = local_index + 1; + uc = localbuf[fresh0 as usize] as libc::c_uchar; + return uc as libc::c_int; + } +} + +#[no_mangle] +pub fn ungetc_with_restart(mut c: libc::c_int, mut stream: *mut FILE) -> libc::c_int { + unsafe { + if local_index == 0 as libc::c_int || c == EOF { + return EOF; + } + local_index -= 1; + localbuf[local_index as usize] = c as libc::c_char; + return c; + } +} + +#[no_mangle] +pub static mut bash_input_fd_changed: libc::c_int = 0; + +/* This provides a way to map from a file descriptor to the buffer +associated with that file descriptor, rather than just the other +way around. This is needed so that buffers are managed properly +in constructs like 3<&4. buffers[x]->b_fd == x -- that is how the +correspondence is maintained. */ +static mut buffers: *mut *mut BUFFERED_STREAM = + 0 as *const libc::c_void as *mut libc::c_void as *mut *mut BUFFERED_STREAM; +static mut nbuffers: libc::c_int = 0; + +/* Make sure `buffers' has at least N elements. */ +fn allocate_buffers(mut n: libc::c_int) { + let mut i: libc::c_int = 0; + let mut orig_nbuffers: libc::c_int = 0; + unsafe { + orig_nbuffers = nbuffers; + nbuffers = n + 20 as libc::c_int; + buffers = libc::realloc( + buffers as *mut libc::c_void, + (nbuffers as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::<*mut BUFFERED_STREAM>() as libc::c_ulong) + as usize, + ) as *mut *mut BUFFERED_STREAM; + + /* Zero out the new buffers. */ + i = orig_nbuffers; + while i < nbuffers { + let ref mut fresh1 = *buffers.offset(i as isize); + *fresh1 = 0 as *mut libc::c_void as *mut BUFFERED_STREAM; + i += 1; + i; + } + } +} + +/* Construct and return a BUFFERED_STREAM corresponding to file descriptor +FD, using BUFFER. */ +fn make_buffered_stream( + mut fd: libc::c_int, + mut buffer: *mut libc::c_char, + mut bufsize: size_t, +) -> *mut BUFFERED_STREAM { + unsafe { + let mut bp: *mut BUFFERED_STREAM = 0 as *mut BUFFERED_STREAM; + bp = libc::malloc(::core::mem::size_of::() as libc::c_ulong as usize) + as *mut BUFFERED_STREAM; + ALLOCATE_BUFFERS!(fd); + let ref mut fresh2 = *buffers.offset(fd as isize); + *fresh2 = bp; + (*bp).b_fd = fd; + (*bp).b_buffer = buffer; + (*bp).b_size = bufsize; + (*bp).b_flag = 0 as libc::c_int; + (*bp).b_inputp = (*bp).b_flag as size_t; + (*bp).b_used = (*bp).b_inputp; + if bufsize == 1 as libc::c_int as libc::c_ulong { + (*bp).b_flag |= B_UNBUFF; + } + if O_TEXT != 0 && fcntl(fd, F_GETFL) & O_TEXT != 0 as libc::c_int { + (*bp).b_flag |= B_TEXT; + } + return bp; + } +} + +/* Allocate a new BUFFERED_STREAM, copy BP to it, and return the new copy. */ +fn copy_buffered_stream(mut bp: *mut BUFFERED_STREAM) -> *mut BUFFERED_STREAM { + unsafe { + let mut nbp: *mut BUFFERED_STREAM = 0 as *mut BUFFERED_STREAM; + + if bp.is_null() { + return 0 as *mut libc::c_void as *mut BUFFERED_STREAM; + } + + nbp = libc::malloc(::core::mem::size_of::() as libc::c_ulong as usize) + as *mut BUFFERED_STREAM; + xbcopy( + bp as *mut libc::c_char, + nbp as *mut libc::c_char, + ::core::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + return nbp; + } +} + +#[no_mangle] +pub fn set_bash_input_fd(mut fd: libc::c_int) -> libc::c_int { + unsafe { + if bash_input.type_0 as libc::c_uint == st_bstream as libc::c_int as libc::c_uint { + bash_input.location.buffered_fd = fd; + } else if interactive_shell == 0 as libc::c_int { + default_buffered_input = fd; + } + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn fd_is_bash_input(mut fd: libc::c_int) -> libc::c_int { + unsafe { + if bash_input.type_0 as libc::c_uint == st_bstream as libc::c_int as libc::c_uint + && bash_input.location.buffered_fd == fd + { + return 1 as libc::c_int; + } else if interactive_shell == 0 as libc::c_int && default_buffered_input == fd { + return 1 as libc::c_int; + } + return 0 as libc::c_int; + } +} + +/* Save the buffered stream corresponding to file descriptor FD (which bash +is using to read input) to a buffered stream associated with NEW_FD. If +NEW_FD is -1, a new file descriptor is allocated with fcntl. The new +file descriptor is returned on success, -1 on error. */ +#[no_mangle] +pub fn save_bash_input(mut fd: libc::c_int, mut new_fd: libc::c_int) -> libc::c_int { + unsafe { + let mut nfd: libc::c_int = 0; + + /* Sync the stream so we can re-read from the new file descriptor. We + might be able to avoid this by copying the buffered stream verbatim + to the new file descriptor. */ + if !(*buffers.offset(fd as isize)).is_null() { + sync_buffered_stream(fd); + } + + /* Now take care of duplicating the file descriptor that bash is + using for input, so we can reinitialize it later. */ + nfd = if new_fd == -(1 as libc::c_int) { + fcntl(fd, 0 as libc::c_int, 10 as libc::c_int) + } else { + new_fd + }; + if nfd == -(1 as libc::c_int) { + if fcntl(fd, 1 as libc::c_int, 0 as libc::c_int) == 0 as libc::c_int { + sys_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot allocate new file descriptor for bash input from fd %d\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + fd, + ); + } + return -(1 as libc::c_int); + } + + if nfd < nbuffers && !(*buffers.offset(nfd as isize)).is_null() { + /* What's this? A stray buffer without an associated open file + descriptor? Free up the buffer and report the error. */ + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"save_bash_input: buffer already exists for new fd %d\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + nfd, + ); + if (**buffers.offset(nfd as isize)).b_flag & B_SHAREDBUF as libc::c_int != 0 { + let ref mut fresh3 = (**buffers.offset(nfd as isize)).b_buffer; + *fresh3 = 0 as *mut libc::c_void as *mut libc::c_char; + } + free_buffered_stream(*buffers.offset(nfd as isize)); + } + + /* Reinitialize bash_input.location. */ + if bash_input.type_0 as libc::c_uint == st_bstream as libc::c_int as libc::c_uint { + bash_input.location.buffered_fd = nfd; + fd_to_buffered_stream(nfd); + close_buffered_fd(fd); /* XXX */ + } else { + /* If the current input type is not a buffered stream, but the shell + is not interactive and therefore using a buffered stream to read + input (e.g. with an `eval exec 3>output' inside a script), note + that the input fd has been changed. pop_stream() looks at this + value and adjusts the input fd to the new value of + default_buffered_input accordingly. */ + bash_input_fd_changed += 1; + bash_input_fd_changed; + } + if default_buffered_input == fd { + default_buffered_input = nfd; + } + + SET_CLOSE_ON_EXEC!(nfd); + return nfd; + } +} + +/* Check that file descriptor FD is not the one that bash is currently +using to read input from a script. FD is about to be duplicated onto, +which means that the kernel will close it for us. If FD is the bash +input file descriptor, we need to seek backwards in the script (if +possible and necessary -- scripts read from stdin are still unbuffered), +allocate a new file descriptor to use for bash input, and re-initialize +the buffered stream. Make sure the file descriptor used to save bash +input is set close-on-exec. Returns 0 on success, -1 on failure. This +works only if fd is > 0 -- if fd == 0 and bash is reading input from +fd 0, sync_buffered_stream is used instead, to cooperate with input +redirection (look at redir.c:add_undo_redirect()). */ +#[no_mangle] +pub fn check_bash_input(mut fd: libc::c_int) -> libc::c_int { + if fd_is_bash_input(fd) != 0 { + if fd > 0 as libc::c_int { + return if save_bash_input(fd, -(1 as libc::c_int)) == -(1 as libc::c_int) { + -(1 as libc::c_int) + } else { + 0 as libc::c_int + }; + } else if fd == 0 as libc::c_int { + return if sync_buffered_stream(fd) == -(1 as libc::c_int) { + -(1 as libc::c_int) + } else { + 0 as libc::c_int + }; + } + } + return 0 as libc::c_int; +} + +/* This is the buffered stream analogue of dup2(fd1, fd2). The +BUFFERED_STREAM corresponding to fd2 is deallocated, if one exists. +BUFFERS[fd1] is copied to BUFFERS[fd2]. This is called by the +redirect code for constructs like 4<&0 and 3 libc::c_int { + let mut is_bash_input: libc::c_int = 0; + let mut m: libc::c_int = 0; + unsafe { + if fd1 == fd2 { + return 0 as libc::c_int; + } + + m = max!(fd1, fd2); + ALLOCATE_BUFFERS!(m); + + /* If FD2 is the file descriptor bash is currently using for shell input, + we need to do some extra work to make sure that the buffered stream + actually exists (it might not if fd1 was not active, and the copy + didn't actually do anything). */ + is_bash_input = (bash_input.type_0 as libc::c_uint + == st_bstream as libc::c_int as libc::c_uint + && bash_input.location.buffered_fd == fd2) as libc::c_int; + + if !(*buffers.offset(fd2 as isize)).is_null() { + /* If the two objects share the same b_buffer, don't free it. */ + if !(*buffers.offset(fd1 as isize)).is_null() + && !((**buffers.offset(fd1 as isize)).b_buffer).is_null() + && (**buffers.offset(fd1 as isize)).b_buffer + == (**buffers.offset(fd2 as isize)).b_buffer + { + let ref mut fresh4 = *buffers.offset(fd2 as isize); + *fresh4 = 0 as *mut libc::c_void as *mut BUFFERED_STREAM; + /* If this buffer is shared with another fd, don't free the buffer */ + } else if (**buffers.offset(fd2 as isize)).b_flag & B_SHAREDBUF as libc::c_int != 0 { + let ref mut fresh5 = (**buffers.offset(fd2 as isize)).b_buffer; + *fresh5 = 0 as *mut libc::c_void as *mut libc::c_char; + free_buffered_stream(*buffers.offset(fd2 as isize)); + } else { + free_buffered_stream(*buffers.offset(fd2 as isize)); + } + } + let ref mut fresh6 = *buffers.offset(fd2 as isize); + *fresh6 = copy_buffered_stream(*buffers.offset(fd1 as isize)); + if !(*buffers.offset(fd2 as isize)).is_null() { + (**buffers.offset(fd2 as isize)).b_fd = fd2; + } + if is_bash_input != 0 { + if (*buffers.offset(fd2 as isize)).is_null() { + fd_to_buffered_stream(fd2); + } + (**buffers.offset(fd2 as isize)).b_flag |= B_WASBASHINPUT as libc::c_int; + } + if fd_is_bash_input(fd1) != 0 + || !(*buffers.offset(fd1 as isize)).is_null() + && (**buffers.offset(fd1 as isize)).b_flag & B_SHAREDBUF as libc::c_int != 0 + { + (**buffers.offset(fd2 as isize)).b_flag |= B_SHAREDBUF as libc::c_int; + } + + return fd2; + } +} + +/* Take FD, a file descriptor, and create and return a buffered stream +corresponding to it. If something is wrong and the file descriptor +is invalid, return a NULL stream. */ +#[no_mangle] +pub fn fd_to_buffered_stream(mut fd: libc::c_int) -> *mut BUFFERED_STREAM { + let mut buffer: *mut libc::c_char = 0 as *mut libc::c_char; + let mut size: size_t = 0; + let mut sb: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + unsafe { + if fstat(fd, &mut sb) < 0 as libc::c_int { + close(fd); + return 0 as *mut libc::c_void as *mut BUFFERED_STREAM; + } + + size = (if fd_is_seekable!(fd) { + min!(sb.st_size, MAX_INPUT_BUFFER_SIZE as libc::c_long) + } else { + 1 as libc::c_int as libc::c_long + }) as size_t; + if size == 0 as libc::c_int as libc::c_ulong { + size = 1 as libc::c_int as size_t; + } + buffer = libc::malloc(size as usize) as *mut libc::c_char; + + return make_buffered_stream(fd, buffer, size); + } +} + +/* Return a buffered stream corresponding to FILE, a file name. */ +#[no_mangle] +pub fn open_buffered_stream(mut file: *mut libc::c_char) -> *mut BUFFERED_STREAM { + let mut fd: libc::c_int = 0; + unsafe { + fd = open(file, O_RDONLY); + return if fd >= 0 as libc::c_int { + fd_to_buffered_stream(fd) + } else { + 0 as *mut libc::c_void as *mut BUFFERED_STREAM + }; + } +} + +/* Deallocate a buffered stream and free up its resources. Make sure we +zero out the slot in BUFFERS that points to BP. */ +#[no_mangle] +pub fn free_buffered_stream(mut bp: *mut BUFFERED_STREAM) { + let mut n: libc::c_int = 0; + + if bp.is_null() { + return; + } + unsafe { + n = (*bp).b_fd; + if !((*bp).b_buffer).is_null() { + libc::free((*bp).b_buffer as *mut libc::c_void); + } + libc::free(bp as *mut libc::c_void); + let ref mut fresh7 = *buffers.offset(n as isize); + *fresh7 = 0 as *mut libc::c_void as *mut BUFFERED_STREAM; + } +} + +/* Close the file descriptor associated with BP, a buffered stream, and free +up the stream. Return the status of closing BP's file descriptor. */ +#[no_mangle] +pub fn close_buffered_stream(mut bp: *mut BUFFERED_STREAM) -> libc::c_int { + let mut fd: libc::c_int = 0; + + if bp.is_null() { + return 0 as libc::c_int; + } + unsafe { + fd = (*bp).b_fd; + if (*bp).b_flag & B_SHAREDBUF as libc::c_int != 0 { + (*bp).b_buffer = 0 as *mut libc::c_void as *mut libc::c_char; + } + free_buffered_stream(bp); + return close(fd); + } +} + +/* Deallocate the buffered stream associated with file descriptor FD, and +close FD. Return the status of the close on FD. */ +#[no_mangle] +pub fn close_buffered_fd(mut fd: libc::c_int) -> libc::c_int { + unsafe { + if fd < 0 as libc::c_int { + *__errno_location() = EBADF; + return -(1 as libc::c_int); + } + if fd >= nbuffers || buffers.is_null() || (*buffers.offset(fd as isize)).is_null() { + return close(fd); + } + return close_buffered_stream(*buffers.offset(fd as isize)); + } +} + +/* Make the BUFFERED_STREAM associated with buffers[FD] be BP, and return +the old BUFFERED_STREAM. */ +#[no_mangle] +pub fn set_buffered_stream( + mut fd: libc::c_int, + mut bp: *mut BUFFERED_STREAM, +) -> *mut BUFFERED_STREAM { + unsafe { + let mut ret: *mut BUFFERED_STREAM = 0 as *mut BUFFERED_STREAM; + + ret = *buffers.offset(fd as isize); + let ref mut fresh8 = *buffers.offset(fd as isize); + *fresh8 = bp; + return ret; + } +} + +/* Read a buffer full of characters from BP, a buffered stream. */ +fn b_fill_buffer(mut bp: *mut BUFFERED_STREAM) -> libc::c_int { + let mut nr: ssize_t = 0; + let mut o: off_t = 0; + unsafe { + CHECK_TERMSIG!(); + /* In an environment where text and binary files are treated differently, + compensate for lseek() on text files returning an offset different from + the count of characters read() returns. Text-mode streams have to be + treated as unbuffered. */ + if (*bp).b_flag & (B_TEXT | B_UNBUFF) == B_TEXT { + o = lseek((*bp).b_fd, 0 as __off_t, SEEK_CUR); + nr = zread((*bp).b_fd, (*bp).b_buffer, (*bp).b_size); + if nr > 0 as libc::c_long && nr < lseek((*bp).b_fd, 0 as __off_t, 1) - o { + lseek((*bp).b_fd, o, SEEK_SET as libc::c_int); + (*bp).b_flag |= B_UNBUFF; + (*bp).b_size = 1 as size_t; + nr = zread((*bp).b_fd, (*bp).b_buffer, (*bp).b_size); + } + } else { + nr = zread((*bp).b_fd, (*bp).b_buffer, (*bp).b_size); + } + if nr <= 0 as libc::c_long { + (*bp).b_inputp = 0 as size_t; + (*bp).b_used = (*bp).b_inputp; + *((*bp).b_buffer).offset(0 as isize) = 0 as libc::c_char; + if nr == 0 as libc::c_long { + (*bp).b_flag |= B_EOF as libc::c_int; + } else { + (*bp).b_flag |= B_ERROR as libc::c_int; + } + return EOF; + } + + (*bp).b_used = nr as size_t; + (*bp).b_inputp = 0 as size_t; + let fresh9 = (*bp).b_inputp; + (*bp).b_inputp = ((*bp).b_inputp).wrapping_add(1); + return *((*bp).b_buffer).offset(fresh9 as isize) as libc::c_int & 0xff as libc::c_int; + } +} + +/* Push C back onto buffered stream BP. */ +fn bufstream_ungetc(mut c: libc::c_int, mut bp: *mut BUFFERED_STREAM) -> libc::c_int { + unsafe { + if c == EOF || bp.is_null() || (*bp).b_inputp == 0 as libc::c_int as libc::c_ulong { + return EOF; + } + + (*bp).b_inputp = ((*bp).b_inputp).wrapping_sub(1); + *((*bp).b_buffer).offset((*bp).b_inputp as isize) = c as libc::c_char; + return c; + } +} + +/* Seek backwards on file BFD to synchronize what we've read so far +with the underlying file pointer. */ +#[no_mangle] +pub fn sync_buffered_stream(mut bfd: libc::c_int) -> libc::c_int { + let mut bp: *mut BUFFERED_STREAM = 0 as *mut BUFFERED_STREAM; + let mut chars_left: off_t = 0; + unsafe { + if buffers.is_null() || { + bp = *buffers.offset(bfd as isize); + bp.is_null() + } { + return -(1 as libc::c_int); + } + + chars_left = ((*bp).b_used).wrapping_sub((*bp).b_inputp) as off_t; + if chars_left != 0 { + lseek((*bp).b_fd, -chars_left, SEEK_CUR); + } + (*bp).b_inputp = 0 as size_t; + (*bp).b_used = (*bp).b_inputp; + } + return 0; +} + +#[no_mangle] +pub fn buffered_getchar() -> libc::c_int { + unsafe { + CHECK_TERMSIG!(); + + if bash_input.location.buffered_fd < 0 as libc::c_int + || (*buffers.offset(bash_input.location.buffered_fd as isize)).is_null() + { + return EOF; + } + + return bufstream_getc!(**buffers.offset(bash_input.location.buffered_fd as isize)); + } +} + +#[no_mangle] +pub fn buffered_ungetchar(mut c: libc::c_int) -> libc::c_int { + unsafe { + return bufstream_ungetc(c, *buffers.offset(bash_input.location.buffered_fd as isize)); + } +} + +/* Make input come from file descriptor BFD through a buffered stream. */ +#[no_mangle] +pub fn with_input_from_buffered_stream(mut bfd: libc::c_int, mut name: *mut libc::c_char) { + let mut location: crate::y_tab::INPUT_STREAM = crate::y_tab::INPUT_STREAM { + file: 0 as *const FILE as *mut FILE, + }; + let mut bp: *mut BUFFERED_STREAM = 0 as *mut BUFFERED_STREAM; + + location.buffered_fd = bfd; + /* Make sure the buffered stream exists. */ + bp = fd_to_buffered_stream(bfd); + init_yy_io( + if bp.is_null() { + Some(return_EOF as fn() -> libc::c_int) + } else { + Some(buffered_getchar as fn() -> libc::c_int) + }, + unsafe { + ::core::mem::transmute:: libc::c_int>, Option>(Some( + ::core::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + buffered_ungetchar, + ), + )) + }, + st_bstream, + name, + location, + ); +} diff --git a/utshell-0.5.0/src/jobs.rs b/utshell-0.5.0/src/jobs.rs new file mode 100644 index 00000000..d2ebd913 --- /dev/null +++ b/utshell-0.5.0/src/jobs.rs @@ -0,0 +1,4489 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::builtins::{ + common::{get_working_directory, the_current_working_directory}, + evalfile::sourcelevel, + wait::wait_builtin, +}; +use crate::dispose_cmd::dispose_command; +use crate::error::get_name_for_error; +use crate::execute_cmd::{coproc_pidchk, coproc_reap}; +use crate::flags::change_flag; +use crate::general::{move_to_high_fd, polite_directory_format, sh_closepipe}; +use crate::input::sync_buffered_stream; +use crate::list::list_reverse; +use crate::readline::rl_readline_state; +use crate::sig::{ + restore_sigmask, set_signal_handler, sigint_sighandler, termsig_handler, throw_to_top_level, +}; +use crate::src_common::*; +use crate::subst::{find_procsub_child, set_procsub_status}; +use crate::trap::{ + get_original_signal, initialize_traps, maybe_call_trap_handler, maybe_set_sigchld_trap, + queue_sigchld_trap, set_impossible_sigchld_trap, set_original_signal, signal_in_progress, + signal_is_hard_ignored, signal_is_trapped, signal_name, +}; +use crate::trap::{trap_handler, trap_to_sighandler}; +use crate::unwind_prot::{ + add_unwind_protect, begin_unwind_frame, run_unwind_frame, unwind_protect_mem, +}; +use crate::utshell::unset_bash_input; +use crate::variables::{get_string_value, set_pipestatus_array}; +use crate::version::shell_compatibility_level; +use crate::y_tab::line_number; +use std::convert::TryInto; + +#[no_mangle] +pub fn UNQUEUE_SIGCHLD(os: libc::c_int) { + unsafe { + queue_sigchld -= 1; + if queue_sigchld == 0 && os != sigchld { + queue_sigchld = 1; + waitchld(-1, 0); + queue_sigchld = 0; + } + } +} + +#[no_mangle] +pub fn PSTOPPED(p: *mut PROCESS) -> libc::c_int { + unsafe { + if (*p).status & 0xff == 0x7f { + return 1; + } else { + return 0; + } + } +} + +#[no_mangle] +pub fn BLOCK_CHILD(nvar: *mut sigset_t, ovar: *mut sigset_t) { + unsafe { + sigemptyset(nvar); + sigaddset(nvar, SIGCHLD as libc::c_int); + sigemptyset(ovar); + sigprocmask(SIG_BLOCK as libc::c_int, nvar, ovar); + } +} + +#[no_mangle] +pub fn UNBLOCK_CHILD(over: *const sigset_t) { + unsafe { + sigprocmask( + SIG_SETMASK as libc::c_int, + over, + 0 as *mut c_void as *mut sigset_t, + ); + } +} + +/* å‡½æ•°éƒ¨åˆ†é‡æž„ */ +#[no_mangle] +pub fn init_job_stats() { + unsafe { + js = zerojs; + } +} + +fn current_working_directory() -> *mut libc::c_char { + unsafe { + let mut dir: *mut libc::c_char; + let mut d: [libc::c_char; PATH_MAX as usize] = [0; PATH_MAX as usize]; + + dir = get_string_value(b"PWD\0" as *const u8 as *const libc::c_char); + + if dir.is_null() && !the_current_working_directory.is_null() && no_symbolic_links != 0 { + dir = the_current_working_directory; + } + + if dir.is_null() { + dir = getcwd( + d.as_mut_ptr(), + (::std::mem::size_of::<[libc::c_char; 4096]>() as libc::c_ulong) + .try_into() + .unwrap(), + ); + if !dir.is_null() { + dir = d.as_mut_ptr(); + } + } + + if dir.is_null() { + return b"\0" as *const u8 as *mut libc::c_char; + } else { + return dir; + } + } +} + +fn job_working_directory() -> *mut libc::c_char { + unsafe { + let mut dir: *mut libc::c_char; + + dir = get_string_value(b"PWD\0" as *const u8 as *const libc::c_char); + dir = get_working_directory(b"job-working-directory\0" as *const u8 as *mut libc::c_char); + if !dir.is_null() { + return savestring!(dir); + } + + return savestring!(b"\0" as *const u8 as *const libc::c_char); + } +} + +#[no_mangle] +pub fn making_children() { + unsafe { + if already_making_children != 0 { + return; + } + + already_making_children = 1; + start_pipeline(); + } +} + +#[no_mangle] +pub fn stop_making_children() { + unsafe { + already_making_children = 0; + } +} + +#[no_mangle] +pub fn cleanup_the_pipeline() { + unsafe { + let mut disposer: *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + disposer = the_pipeline; + the_pipeline = 0 as *mut PROCESS; + UNBLOCK_CHILD(&mut oset); + + if !disposer.is_null() { + discard_pipeline(disposer); + } + } +} + +#[no_mangle] +pub fn discard_last_procsub_child() { + let mut disposer: *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + BLOCK_CHILD(&mut set, &mut oset); + disposer = last_procsub_child; + last_procsub_child = 0 as *mut PROCESS; + UNBLOCK_CHILD(&mut oset); + + if !disposer.is_null() { + discard_pipeline(disposer); + } + } +} + +fn alloc_pipeline_saver() -> *mut pipeline_saver { + unsafe { + let mut ret: *mut pipeline_saver; + + ret = malloc(::std::mem::size_of::() as usize) as *mut pipeline_saver; + + (*ret).pipeline = 0 as *mut process; + (*ret).next = 0 as *mut pipeline_saver; + + return ret; + } +} + +#[no_mangle] +pub fn save_pipeline(clear: libc::c_int) { + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut saver: *mut pipeline_saver; + unsafe { + BLOCK_CHILD(&mut set, &mut oset); + saver = alloc_pipeline_saver(); + (*saver).pipeline = the_pipeline; + (*saver).next = saved_pipeline; + saved_pipeline = saver; + + if clear != 0 { + the_pipeline = 0 as *mut PROCESS; + } + saved_already_making_children = already_making_children; + UNBLOCK_CHILD(&mut oset); + } +} + +#[no_mangle] +pub fn restore_pipeline(discard: libc::c_int) -> *mut PROCESS { + unsafe { + let mut old_pipeline: *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut saver: *mut pipeline_saver; + + BLOCK_CHILD(&mut set, &mut oset); + old_pipeline = the_pipeline; + the_pipeline = (*saved_pipeline).pipeline; + saver = saved_pipeline; + saved_pipeline = (*saved_pipeline).next; + free(saver as *mut c_void); + already_making_children = saved_already_making_children; + UNBLOCK_CHILD(&mut oset); + + if discard != 0 && !old_pipeline.is_null() { + discard_pipeline(old_pipeline); + return 0 as *mut PROCESS; + } + return old_pipeline; + } +} + +#[no_mangle] +pub fn start_pipeline() { + unsafe { + if !the_pipeline.is_null() { + cleanup_the_pipeline(); + if pipeline_pgrp != shell_pgrp { + pipeline_pgrp = 0 as pid_t; + } + sh_closepipe(pgrp_pipe.as_mut_ptr()); + } + + if job_control != 0 { + if libc::pipe(pgrp_pipe.as_mut_ptr()) == -1 { + sys_error(b"start_pipeline: pgrp pipe\0" as *const u8 as *const libc::c_char); + } + } + } +} + +#[no_mangle] +pub fn stop_pipeline(mut async_0: libc::c_int, mut deferred: *mut COMMAND) -> libc::c_int { + unsafe { + let mut i: libc::c_int; + let mut j: libc::c_int; + let mut newjob: *mut JOB; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + sh_closepipe(pgrp_pipe.as_mut_ptr()); + cleanup_dead_jobs(); + + if js.j_jobslots == 0 { + js.j_jobslots = JOB_SLOTS as libc::c_int; + jobs = + malloc((js.j_jobslots * (std::mem::size_of::<*mut JOB>() as libc::c_int)) as usize) + as *mut *mut JOB; + + i = 0 as libc::c_int; + while i < js.j_jobslots { + (*jobs.offset(i as isize)) = std::ptr::null_mut(); + + i += 1; + } + js.j_njobs = 0 as libc::c_int; + js.j_lastj = js.j_njobs; + js.j_firstj = js.j_lastj; + } + + if interactive != 0 { + i = js.j_jobslots; + while i != 0 { + let temp = i - 1; + if !(*jobs.offset(temp as isize)).is_null() { + break; + } + i -= 1; + } + } else { + if js.j_lastj != 0 { + i = js.j_lastj + 1; + } else { + i = js.j_lastj; + } + while i < js.j_jobslots { + if (*jobs.offset(i as isize)).is_null() { + break; + } + i += 1; + } + } + + if (interactive_shell == 0 || subshell_environment != 0) + && i == js.j_jobslots + && js.j_jobslots >= MAX_JOBS_IN_ARRAY as i32 + { + i = compact_jobs_list(0 as libc::c_int); + } + + if i == js.j_jobslots { + js.j_jobslots += JOB_SLOTS as i32; + jobs = realloc( + jobs as *mut c_void, + (js.j_jobslots * std::mem::size_of::<*mut JOB>() as libc::c_int) as usize, + ) as *mut *mut JOB; + + j = i; + while j < js.j_jobslots { + (*jobs.offset(j as isize)) = 0 as *mut JOB; + j += 1; + } + } + + if !the_pipeline.is_null() { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut any_running: libc::c_int = 0; + let mut any_stopped: libc::c_int = 0; + let mut n: libc::c_int = 0; + + newjob = malloc(std::mem::size_of::() as libc::c_int as usize) as *mut JOB; + + n = 1 as libc::c_int; + p = the_pipeline; + while (*p).next != the_pipeline { + n += 1; + p = (*p).next; + } + + (*p).next = 0 as *mut PROCESS; + if !the_pipeline.is_null() && !((*the_pipeline).next).is_null() { + (*newjob).pipe = list_reverse(the_pipeline as *mut GENERIC_LIST) as *mut PROCESS + } else { + (*newjob).pipe = the_pipeline; + }; + + p = (*newjob).pipe; + while !((*p).next).is_null() { + p = (*p).next; + } + + (*p).next = (*newjob).pipe; + + the_pipeline = 0 as *mut PROCESS; + (*newjob).pgrp = pipeline_pgrp; + + if pipeline_pgrp != shell_pgrp { + pipeline_pgrp = 0; + } + + (*newjob).flags = 0; + + if pipefail_opt != 0 { + (*newjob).flags |= J_PIPEFAIL as i32; + } + + if job_control != 0 { + (*newjob).flags |= J_JOBCONTROL as i32; + } + + p = (*newjob).pipe; + any_running = 0; + any_stopped = 0; + + loop { + any_running |= PRUNNING!(p) as libc::c_int; + any_stopped |= PSTOPPED(p); + p = (*p).next; + if !(p != (*newjob).pipe) { + break; + } + } + + (*newjob).state = (if any_running != 0 { + JRUNNING as libc::c_int + } else if any_stopped != 0 { + JSTOPPED as libc::c_int + } else { + JDEAD as libc::c_int + }) as JOB_STATE; + + (*newjob).wd = job_working_directory(); + (*newjob).deferred = deferred; + + (*newjob).j_cleanup = + ::std::mem::transmute::<*mut libc::c_void, sh_vptrfunc_t>(0 as *mut libc::c_void); + (*newjob).cleanarg = 0 as *mut c_void; + + *jobs.offset(i as isize) = newjob; + + if (*newjob).state == JDEAD as libc::c_int && (*newjob).flags & 0x1 as libc::c_int != 0 + { + setjstatus(i); + } + if (*newjob).state == JDEAD as libc::c_int { + js.c_reaped += n; + js.j_ndead += 1; + } + js.c_injobs += n; + js.j_lastj = i; + js.j_njobs += 1; + } else { + newjob = 0 as *mut JOB; + } + + if !newjob.is_null() { + js.j_lastmade = newjob; + } + + if async_0 != 0 { + if !newjob.is_null() { + (*newjob).flags &= !J_FOREGROUND as libc::c_int; + (*newjob).flags |= J_ASYNC as libc::c_int; + js.j_lastasync = newjob; + } + reset_current(); + } else { + if !newjob.is_null() { + (*newjob).flags |= J_FOREGROUND as libc::c_int; + + if job_control != 0 + && (*newjob).pgrp != 0 + && (subshell_environment & SUBSHELL_ASYNC as libc::c_int) == 0 + && running_in_background == 0 + { + maybe_give_terminal_to(shell_pgrp, (*newjob).pgrp, 0); + } + } + } + + stop_making_children(); + UNBLOCK_CHILD(&mut oset); + return if !newjob.is_null() { i } else { js.j_current }; + } +} + +#[no_mangle] +fn bgp_resize() { + let mut nsize: ps_index_t = 0; + let mut nsize_cur: ps_index_t = 0; + let mut nsize_max: ps_index_t = 0; + let mut psi: ps_index_t = 0; + unsafe { + if bgpids.nalloc == 0 { + psi = 0 as libc::c_int; + while psi < r_pidstat_table_SZ as libc::c_int { + r_pidstat_table[psi as usize] = NO_PIDSTAT; + psi += 1; + } + nsize = BGPIDS_TABLE_SZ as ps_index_t; + bgpids.head = 0; + } else { + nsize = bgpids.nalloc; + } + + nsize_max = TYPE_MAXIMUM!(ps_index_t); + nsize_cur = js.c_childmax as ps_index_t; + + if nsize_cur < 0 { + nsize_cur = MAX_CHILD_MAX as libc::c_int; + } + + while nsize > 0 && nsize < nsize_cur { + nsize <<= 1; + } + + if nsize > nsize_max || nsize <= 0 { + nsize = nsize_max; + } + + if nsize > MAX_CHILD_MAX as libc::c_int { + nsize_max = MAX_CHILD_MAX as libc::c_int; + nsize = nsize_max; + } + + if bgpids.nalloc < nsize_cur && bgpids.nalloc < nsize_max { + bgpids.storage = realloc( + bgpids.storage as *mut c_void, + (nsize * std::mem::size_of::() as libc::c_int) as usize, + ) as *mut pidstat; + psi = bgpids.nalloc; + while psi < nsize { + (*(bgpids.storage).offset(psi as isize)).pid = -(1 as libc::c_int); + psi += 1; + } + bgpids.nalloc = nsize; + } else if bgpids.head >= bgpids.nalloc { + bgpids.head = 0 as libc::c_int; + } + } +} + +#[no_mangle] +fn bgp_getindex() -> ps_index_t { + unsafe { + if bgpids.nalloc < js.c_childmax as ps_index_t || bgpids.head >= bgpids.nalloc { + bgp_resize(); + } + pshash_delindex(bgpids.head); + bgpids.head += 1; + return bgpids.head; + } +} + +#[no_mangle] +fn pshash_getbucket(pid: pid_t) -> *mut ps_index_t { + let mut hash: libc::c_ulong = 0; + hash = (pid as libc::c_ulong).wrapping_mul(0x9e370001 as libc::c_ulong); + unsafe { + return &mut *r_pidstat_table + .as_mut_ptr() + .offset((hash % r_pidstat_table_SZ as u64) as isize) as *mut ps_index_t; + } +} + +#[no_mangle] +fn bgp_add(mut pid: pid_t, mut status: libc::c_int) -> *mut pidstat { + unsafe { + let mut bucket: *mut ps_index_t = 0 as *mut ps_index_t; + let mut psi: ps_index_t = 0; + let mut ps: *mut pidstat = 0 as *mut pidstat; + bucket = pshash_getbucket(pid); + psi = bgp_getindex(); + if psi == *bucket { + (*(bgpids.storage).offset(psi as isize)).pid = -1; + psi = bgp_getindex(); + } + ps = &mut *(bgpids.storage).offset(psi as isize) as *mut pidstat; + (*ps).pid = pid; + (*ps).status = status as libc::c_short; + (*ps).bucket_next = *bucket; + (*ps).bucket_prev = -1; + bgpids.npid += 1; + if (*ps).bucket_next != -1 { + (*(bgpids.storage).offset((*ps).bucket_next as isize)).bucket_prev = psi; + } + *bucket = psi; + return ps; + } +} + +#[no_mangle] +fn pshash_delindex(mut psi: ps_index_t) { + let mut ps: *mut pidstat = 0 as *mut pidstat; + let mut bucket: *mut ps_index_t = 0 as *mut ps_index_t; + unsafe { + ps = &mut *(bgpids.storage).offset(psi as isize) as *mut pidstat; + if (*ps).pid == NO_PID { + return; + } + if (*ps).bucket_next != NO_PIDSTAT { + (*(bgpids.storage).offset((*ps).bucket_next as isize)).bucket_prev = (*ps).bucket_prev; + } + if (*ps).bucket_prev != NO_PIDSTAT { + (*(bgpids.storage).offset((*ps).bucket_prev as isize)).bucket_next = (*ps).bucket_next; + } else { + bucket = pshash_getbucket((*ps).pid); + *bucket = (*ps).bucket_next; + } + (*ps).pid = NO_PID; + (*ps).bucket_next = NO_PIDSTAT; + (*ps).bucket_prev = NO_PIDSTAT; + } +} + +fn bgp_delete(mut pid: pid_t) -> libc::c_int { + unsafe { + let mut psi: ps_index_t = 0; + let mut orig_psi: ps_index_t = 0; + + if (bgpids.storage).is_null() || bgpids.nalloc == 0 || bgpids.npid == 0 { + return 0; + } + + psi = *pshash_getbucket(pid); + orig_psi = psi; + while psi != NO_PIDSTAT { + if (*(bgpids.storage).offset(psi as isize)).pid == pid { + break; + } + if orig_psi == (*(bgpids.storage).offset(psi as isize)).bucket_next { + internal_warning( + b"bgp_delete: LOOP: psi (%d) == storage[psi].bucket_next\0" as *const u8 + as *const libc::c_char, + psi, + ); + return 0 as libc::c_int; + } + psi = (*(bgpids.storage).offset(psi as isize)).bucket_next; + } + if psi == NO_PIDSTAT { + return 0; + } + pshash_delindex(psi); + bgpids.npid -= 1; + return 1; + } +} + +fn bgp_clear() { + unsafe { + if (bgpids.storage).is_null() || bgpids.nalloc == 0 { + return; + } + libc::free(bgpids.storage as *mut c_void); + + bgpids.storage = 0 as *mut pidstat; + bgpids.nalloc = 0; + bgpids.head = 0; + bgpids.npid = 0; + } +} + +fn bgp_search(mut pid: pid_t) -> libc::c_int { + unsafe { + let mut psi: ps_index_t = 0; + let mut orig_psi: ps_index_t = 0; + if (bgpids.storage).is_null() || bgpids.nalloc == 0 || bgpids.npid == 0 { + return -1; + } + + psi = *pshash_getbucket(pid); + orig_psi = psi; + while psi != NO_PIDSTAT { + if (*(bgpids.storage).offset(psi as isize)).pid == pid { + return (*(bgpids.storage).offset(psi as isize)).status as libc::c_int; + } + if orig_psi == (*(bgpids.storage).offset(psi as isize)).bucket_next { + internal_warning( + b"bgp_search: LOOP: psi (%d) == storage[psi].bucket_next\0" as *const u8 + as *const libc::c_char, + psi, + ); + return -1; + } + psi = (*(bgpids.storage).offset(psi as isize)).bucket_next; + } + return -1; + } +} + +#[no_mangle] +pub fn save_proc_status(mut pid: pid_t, mut status: libc::c_int) { + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + BLOCK_CHILD(&mut set, &mut oset); + bgp_add(pid, status); + UNBLOCK_CHILD(&mut oset); + } +} + +fn procsub_free(mut p: *mut PROCESS) { + unsafe { + if !((*p).command).is_null() { + free(((*p).command) as *mut c_void); + } + free(p as *mut c_void); + } +} + +#[no_mangle] +pub fn procsub_add(mut p: *mut PROCESS) -> *mut PROCESS { + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + BLOCK_CHILD(&mut set, &mut oset); + if (procsubs.head).is_null() { + procsubs.end = p; + procsubs.head = procsubs.end; + procsubs.nproc = 0; + } else { + (*procsubs.end).next = p; + procsubs.end = p; + } + procsubs.nproc += 1; + UNBLOCK_CHILD(&mut oset); + + return p; + } +} + +#[no_mangle] +pub fn procsub_search(mut pid: pid_t) -> *mut PROCESS { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + p = procsubs.head; + while !p.is_null() { + if (*p).pid == pid { + break; + } + p = (*p).next; + } + UNBLOCK_CHILD(&mut oset); + return p; + } +} + +#[no_mangle] +pub fn procsub_delete(mut pid: pid_t) -> *mut PROCESS { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut prev: *mut PROCESS = 0 as *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + prev = procsubs.head; + p = prev; + while !p.is_null() { + if (*p).pid == pid { + (*prev).next = (*p).next; + break; + } else { + prev = p; + p = (*p).next; + } + } + if p.is_null() { + UNBLOCK_CHILD(&mut oset); + return p; + } + if p == procsubs.head { + procsubs.head = (*procsubs.head).next; + } else if p == procsubs.end { + procsubs.end = prev; + } + procsubs.nproc -= 1; + if procsubs.nproc == 0 { + procsubs.end = 0 as *mut PROCESS; + procsubs.head = procsubs.end; + } else if procsubs.nproc == 1 { + procsubs.end = procsubs.head; + } + bgp_add((*p).pid, process_exit_status((*p).status)); + UNBLOCK_CHILD(&mut oset); + return p; + } +} + +#[no_mangle] +pub fn procsub_waitpid(mut pid: pid_t) -> libc::c_int { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut r: libc::c_int = 0; + + p = procsub_search(pid); + if p.is_null() { + return -1; + } + if (*p).running == PS_DONE as i32 { + return (*p).status; + } + r = wait_for((*p).pid, 0); + return r; + } +} + +#[no_mangle] +pub fn procsub_waitall() { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut r: libc::c_int = 0; + + p = procsubs.head; + while !p.is_null() { + if !((*p).running == PS_DONE as i32) { + r = wait_for((*p).pid, 0); + } + p = (*p).next; + } + } +} + +#[no_mangle] +pub fn procsub_clear() { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut ps: *mut PROCESS = 0 as *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + ps = procsubs.head; + while !ps.is_null() { + p = ps; + ps = (*ps).next; + procsub_free(p); + } + procsubs.end = 0 as *mut PROCESS; + procsubs.head = procsubs.end; + procsubs.nproc = 0 as libc::c_int; + UNBLOCK_CHILD(&mut oset); + } +} + +#[no_mangle] +pub fn procsub_prune() { + unsafe { + let mut ohead: *mut PROCESS = 0 as *mut PROCESS; + let mut oend: *mut PROCESS = 0 as *mut PROCESS; + let mut ps: *mut PROCESS = 0 as *mut PROCESS; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut onproc: libc::c_int = 0; + + if procsubs.nproc == 0 { + return; + } + ohead = procsubs.head; + oend = procsubs.end; + onproc = procsubs.nproc; + + procsubs.end = 0 as *mut PROCESS; + procsubs.head = procsubs.end; + procsubs.nproc = 0 as libc::c_int; + + p = ohead; + while !p.is_null() { + ps = (*p).next; + (*p).next = 0 as *mut process; + if (*p).running == 0 as libc::c_int { + bgp_add((*p).pid, process_exit_status((*p).status)); + procsub_free(p); + } else { + procsub_add(p); + } + p = ps; + } + } +} + +fn reset_job_indices() { + unsafe { + let mut old: libc::c_int = 0; + + if (*jobs.offset(js.j_firstj as isize)).is_null() { + js.j_firstj = js.j_firstj + 1; + old = js.j_firstj; + if old >= js.j_jobslots { + old = js.j_jobslots - 1; + } + while js.j_firstj != old { + if js.j_firstj >= js.j_jobslots { + js.j_firstj = 0; + } + if !(*jobs.offset(js.j_firstj as isize)).is_null() || js.j_firstj == old { + break; + } + js.j_firstj += 1; + } + if js.j_firstj == old { + js.j_njobs = 0; + js.j_lastj = js.j_njobs; + js.j_firstj = js.j_lastj; + } + } + if (*jobs.offset(js.j_lastj as isize)).is_null() { + js.j_lastj = js.j_lastj - 1; + old = js.j_lastj; + if old < 0 { + old = 0; + } + while js.j_lastj != old { + if js.j_lastj < 0 { + js.j_lastj = js.j_jobslots - 1; + } + if !(*jobs.offset(js.j_lastj as isize)).is_null() || js.j_lastj == old { + break; + } + js.j_lastj -= 1; + } + if js.j_lastj == old { + js.j_njobs = 0 as libc::c_int; + js.j_lastj = js.j_njobs; + js.j_firstj = js.j_lastj; + } + } + } +} + +fn cleanup_dead_jobs() { + unsafe { + let mut i: libc::c_int = 0; + let mut os: libc::c_int = 0; + let mut discard: *mut PROCESS = 0 as *mut PROCESS; + + if js.j_jobslots == 0 || jobs_list_frozen != 0 { + return; + } + QUEUE_SIGCHLD!(os); + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() && DEADJOB!(i) && IS_NOTIFIED!(i) { + delete_job(i, 0 as libc::c_int); + } + i += 1; + } + procsub_prune(); + last_procsub_child = 0 as *mut c_void as *mut PROCESS; + coproc_reap(); + UNQUEUE_SIGCHLD(os) + } +} + +fn processes_in_job(mut job: libc::c_int) -> libc::c_int { + unsafe { + let mut nproc: libc::c_int = 0; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + + nproc = 0 as libc::c_int; + p = (**jobs.offset(job as isize)).pipe; + loop { + p = (*p).next; + nproc += 1; + if !(p != (**jobs.offset(job as isize)).pipe) { + break; + } + } + return nproc; + } +} + +fn delete_old_job(mut pid: pid_t) { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut job: libc::c_int = 0; + + job = find_job(pid, 0, &mut p); + if job != NO_JOB { + if JOBSTATE!(job) == JDEAD { + delete_job(job, 2 as libc::c_int); + } else if !p.is_null() { + (*p).pid = 0; + } + } + } +} + +fn realloc_jobs_list() { + unsafe { + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut nsize: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut ncur: libc::c_int = 0; + let mut nprev: libc::c_int = 0; + let mut nlist: *mut *mut JOB = 0 as *mut *mut JOB; + + nprev = NO_JOB; + ncur = nprev; + nsize = (js.j_njobs + JOB_SLOTS as libc::c_int - 1) / JOB_SLOTS as libc::c_int; + nsize *= JOB_SLOTS as libc::c_int; + i = js.j_njobs % JOB_SLOTS as libc::c_int; + if i == 0 || i > (JOB_SLOTS as libc::c_int >> 1) { + nsize += JOB_SLOTS as libc::c_int; + } + BLOCK_CHILD(&mut set, &mut oset); + nlist = if js.j_jobslots == nsize { + jobs + } else { + malloc((nsize * std::mem::size_of::() as libc::c_int) as usize) as *mut *mut JOB + }; + + js.j_ndead = 0; + js.c_reaped = js.j_ndead; + j = 0; + i = j; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() { + if i == js.j_current { + ncur = j; + } + if i == js.j_previous { + nprev = j; + } + + *nlist.offset(j as isize) = *jobs.offset(i as isize); + j = j + 1; // + if (**jobs.offset(i as isize)).state as libc::c_int == JDEAD as libc::c_int { + js.j_ndead += 1; + js.c_reaped += processes_in_job(i); + } + } + i += 1; + } + + js.j_firstj = 0; + js.j_lastj = if j > 0 { j - 1 } else { 0 }; + js.j_njobs = j; + + js.j_jobslots = nsize; + + while j < nsize { + *nlist.offset(j as isize) = 0 as *mut JOB; + j += 1; + } + + if jobs != nlist { + libc::free(jobs as *mut c_void); + jobs = nlist; + } + + if ncur != NO_JOB { + js.j_current = ncur; + } + + if nprev != NO_JOB { + js.j_previous = nprev; + } + if js.j_current == NO_JOB + || js.j_previous == NO_JOB + || js.j_current > js.j_lastj + || js.j_previous > js.j_lastj + { + reset_current(); + } + UNBLOCK_CHILD(&mut oset); + } +} + +fn compact_jobs_list(mut flags: libc::c_int) -> libc::c_int { + unsafe { + if js.j_jobslots == 0 || jobs_list_frozen != 0 { + return js.j_jobslots; + } + reap_dead_jobs(); + realloc_jobs_list(); + return if js.j_lastj != 0 || !(*jobs.offset(js.j_lastj as isize)).is_null() { + js.j_lastj + 1 + } else { + 0 + }; + } +} + +#[no_mangle] +pub fn delete_job(mut job_index: libc::c_int, mut dflags: libc::c_int) { + unsafe { + let mut temp: *mut JOB = 0 as *mut JOB; + let mut proc_0: *mut PROCESS = 0 as *mut PROCESS; + let mut ndel: libc::c_int = 0; + + if js.j_jobslots == 0 || jobs_list_frozen != 0 { + return; + } + if dflags & DEL_WARNSTOPPED as libc::c_int != 0 + && subshell_environment == 0 + && STOPPED!(job_index) + { + internal_warning( + b"deleting stopped job %d with process group %ld\0" as *const u8 + as *const libc::c_char, + job_index + 1, + (**jobs.offset(job_index as isize)).pgrp as libc::c_long, + ); + } + temp = *jobs.offset(job_index as isize); + if temp.is_null() { + return; + } + + if dflags & DEL_NOBGPID as libc::c_int == 0 as libc::c_int + && (*temp).flags & (J_ASYNC as libc::c_int | J_FOREGROUND as libc::c_int) + == J_ASYNC as libc::c_int + { + proc_0 = find_last_proc(job_index, 0); + if !proc_0.is_null() { + bgp_add((*proc_0).pid, process_exit_status((*proc_0).status)); + } + } + + *jobs.offset(job_index as isize) = 0 as *mut JOB; + if temp == js.j_lastmade { + js.j_lastmade = 0 as *mut JOB; + } else if temp == js.j_lastasync { + js.j_lastasync = 0 as *mut JOB; + } + + libc::free((*temp).wd as *mut c_void); + ndel = discard_pipeline((*temp).pipe); + + js.c_injobs -= ndel; + if (*temp).state == JDEAD as libc::c_int { + js.c_reaped -= ndel; + js.j_ndead -= 1; + if js.c_reaped < 0 { + js.c_reaped = 0; + } + } + if !((*temp).deferred).is_null() { + dispose_command((*temp).deferred); + } + + libc::free(temp as *mut c_void); + + js.j_njobs -= 1; + if js.j_njobs == 0 { + js.j_lastj = 0; + js.j_firstj = js.j_lastj; + } else if (*jobs.offset(js.j_firstj as isize)).is_null() + || (*jobs.offset(js.j_lastj as isize)).is_null() + { + reset_job_indices(); + } + if job_index == js.j_current || job_index == js.j_previous { + reset_current(); + } + } +} + +#[no_mangle] +pub fn nohup_job(mut job_index: libc::c_int) { + unsafe { + let mut temp: *mut JOB = 0 as *mut JOB; + + if js.j_jobslots == 0 { + return; + } + temp = *jobs.offset(job_index as isize); + if !temp.is_null() { + (*temp).flags |= J_NOHUP as libc::c_int; + } + } +} + +#[no_mangle] +pub fn discard_pipeline(mut chain: *mut PROCESS) -> libc::c_int { + unsafe { + let mut this: *mut PROCESS = 0 as *mut PROCESS; + let mut next: *mut PROCESS = 0 as *mut PROCESS; + let mut n: libc::c_int = 0; + + this = chain; + n = 0; + loop { + next = (*this).next; + if !((*this).command).is_null() { + libc::free((*this).command as *mut c_void); + } + libc::free(this as *mut c_void); + n += 1; + this = next; + if !(this != chain) { + break; + } + } + return n; + } +} + +fn add_process(mut name: *mut libc::c_char, mut pid: pid_t) { + unsafe { + let mut t: *mut PROCESS = 0 as *mut PROCESS; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + + t = malloc(::std::mem::size_of::() as usize) as *mut PROCESS; + (*t).next = the_pipeline; + (*t).pid = pid; + (*t).status = 0; + (*t).running = PS_RUNNING as libc::c_int; + (*t).command = name; + the_pipeline = t; + + if ((*t).next).is_null() { + (*t).next = t; + } else { + p = (*t).next; + while (*p).next != (*t).next { + p = (*p).next; + } + (*p).next = t; + }; + } +} + +#[no_mangle] +pub fn append_process( + mut name: *mut libc::c_char, + mut pid: pid_t, + mut status: libc::c_int, + mut jid: libc::c_int, +) { + unsafe { + let mut t: *mut PROCESS = 0 as *mut PROCESS; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + + t = malloc(::std::mem::size_of::() as usize) as *mut PROCESS; + (*t).next = 0 as *mut c_void as *mut PROCESS; + (*t).pid = pid; + (*t).status = (status & 0xff as libc::c_int) << WEXITSTATUS_OFFSET as libc::c_int; + (*t).running = PS_DONE as libc::c_int; + (*t).command = name; + + js.c_reaped += 1; + p = (**jobs.offset(jid as isize)).pipe; + while (*p).next != (**jobs.offset(jid as isize)).pipe { + p = (*p).next; + } + + (*p).next = t; + (*t).next = (**jobs.offset(jid as isize)).pipe; + } +} + +fn map_over_jobs( + mut func: Option, + mut arg1: libc::c_int, + mut arg2: libc::c_int, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + if js.j_jobslots == 0 { + return 0; + } + BLOCK_CHILD(&mut set, &mut oset); + result = 0; + i = result; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() { + result = (Some(func.expect("non-null function pointer"))) + .expect("non-null function pointer")( + *jobs.offset(i as isize), arg1, arg2, i + ); + if result != 0 { + break; + } + } + i += 1; + } + UNBLOCK_CHILD(&mut oset); + return result; + } +} + +#[no_mangle] +pub fn terminate_current_pipeline() { + unsafe { + if pipeline_pgrp != 0 && pipeline_pgrp != shell_pgrp { + killpg(pipeline_pgrp, SIGTERM as libc::c_int); + killpg(pipeline_pgrp, SIGCONT as libc::c_int); + } + } +} + +#[no_mangle] +pub fn terminate_stopped_jobs() { + unsafe { + let mut i: libc::c_int = 0; + i = 0 as libc::c_int; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() && STOPPED!(i) { + killpg((**jobs.offset(i as isize)).pgrp, SIGTERM as libc::c_int); + killpg((**jobs.offset(i as isize)).pgrp, SIGCONT as libc::c_int); + } + i += 1; + } + } +} + +#[no_mangle] +pub fn hangup_all_jobs() { + unsafe { + let mut i: libc::c_int = 0; + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() { + if !((**jobs.offset(i as isize)).flags & J_NOHUP as libc::c_int != 0) { + continue; + } + killpg((**jobs.offset(i as isize)).pgrp, SIGHUP as libc::c_int); + if STOPPED!(i) { + killpg((**jobs.offset(i as isize)).pgrp, SIGCONT as libc::c_int); + } + } + i += 1; + } + } +} + +#[no_mangle] +pub fn kill_current_pipeline() { + stop_making_children(); + start_pipeline(); +} + +fn find_pid_in_pipeline( + mut pid: pid_t, + mut pipeline: *mut PROCESS, + mut alive_only: libc::c_int, +) -> *mut PROCESS { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + p = pipeline; + loop { + if (*p).pid == pid && (alive_only == 0 && PRECYCLED!(p) == 0 || PALIVE!(p)) { + return p; + } + p = (*p).next; + if !(p != pipeline) { + break; + } + } + return 0 as *mut PROCESS; + } +} + +fn find_pipeline( + mut pid: pid_t, + mut alive_only: libc::c_int, + mut jobp: *mut libc::c_int, +) -> *mut PROCESS { + unsafe { + let mut job: libc::c_int = 0; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut save: *mut pipeline_saver = 0 as *mut pipeline_saver; + p = 0 as *mut libc::c_void as *mut PROCESS; + if !jobp.is_null() { + *jobp = -(1 as libc::c_int); + } + if !the_pipeline.is_null() && { + p = find_pid_in_pipeline(pid, the_pipeline, alive_only); + !p.is_null() + } { + return p; + } + save = saved_pipeline; + while !save.is_null() { + if !((*save).pipeline).is_null() && { + p = find_pid_in_pipeline(pid, (*save).pipeline, alive_only); + !p.is_null() + } { + return p; + } + save = (*save).next; + } + if procsubs.nproc > 0 as libc::c_int + && { + p = procsub_search(pid); + !p.is_null() + } + && (alive_only == 0 as libc::c_int && 0 as libc::c_int == 0 as libc::c_int + || ((*p).running == 1 as libc::c_int + || (*p).status & 0xff as libc::c_int == 0x7f as libc::c_int)) + { + return p; + } + job = find_job(pid, alive_only, &mut p); + if !jobp.is_null() { + *jobp = job; + } + return if job == -(1 as libc::c_int) { + 0 as *mut libc::c_void as *mut PROCESS + } else { + (**jobs.offset(job as isize)).pipe + }; + } +} + +fn find_process( + mut pid: pid_t, + mut alive_only: libc::c_int, + mut jobp: *mut libc::c_int, +) -> *mut PROCESS { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + p = find_pipeline(pid, alive_only, jobp); + while !p.is_null() && (*p).pid != pid { + p = (*p).next; + } + return p; + } +} + +fn find_job( + mut pid: pid_t, + mut alive_only: libc::c_int, + mut procp: *mut *mut PROCESS, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + i = 0 as libc::c_int; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() { + p = (**jobs.offset(i as isize)).pipe; + loop { + if (*p).pid == pid + && (alive_only == 0 as libc::c_int && 0 as libc::c_int == 0 as libc::c_int + || ((*p).running == 1 as libc::c_int + || (*p).status & 0xff as libc::c_int == 0x7f as libc::c_int)) + { + if !procp.is_null() { + *procp = p; + } + return i; + } + p = (*p).next; + if !(p != (**jobs.offset(i as isize)).pipe) { + break; + } + } + } + i += 1; + } + return -(1 as libc::c_int); + } +} + +#[no_mangle] +pub fn get_job_by_pid( + mut pid: pid_t, + mut block: libc::c_int, + mut procp: *mut *mut PROCESS, +) -> libc::c_int { + unsafe { + let mut job: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if block != 0 { + BLOCK_CHILD(&mut set, &mut oset); + } + job = find_job(pid, 0 as libc::c_int, procp); + if block != 0 { + UNBLOCK_CHILD(&mut oset); + } + return job; + } +} + +#[no_mangle] +pub fn describe_pid(mut pid: pid_t) { + unsafe { + let mut job: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + job = find_job(pid, 0, 0 as *mut *mut PROCESS); + + if job != NO_JOB { + libc::fprintf( + stderr, + b"[%d] %ld\n\0" as *const u8 as *const libc::c_char, + job + 1 as libc::c_int, + pid as libc::c_long, + ); + } else { + programming_error( + b"describe_pid: %ld: no such pid\0" as *const u8 as *const libc::c_char, + pid as libc::c_long, + ); + } + UNBLOCK_CHILD(&mut oset); + } +} + +fn j_strsignal(mut s: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut x: *mut libc::c_char = 0 as *mut libc::c_char; + x = strsignal(s); + if x.is_null() { + x = retcode_name_buffer.as_mut_ptr(); + libc::snprintf( + x, + ::std::mem::size_of::<[libc::c_char; 64]>() as usize, + b"Signal %d\0" as *const u8 as *const libc::c_char, + s, + ); + } + return x; + } +} + +fn printable_job_status( + mut j: libc::c_int, + mut p: *mut PROCESS, + mut format: libc::c_int, +) -> *mut libc::c_char { + unsafe { + static mut temp: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; + let mut es: libc::c_int = 0; + temp = b"Done\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + + if STOPPED!(j) && format == 0 { + if posixly_correct == 0 as libc::c_int || p.is_null() || (WIFSTOPPED!((*p).status)) { + temp = b"Stopped\0" as *const u8 as *mut libc::c_char; + } else { + temp = retcode_name_buffer.as_mut_ptr(); + libc::snprintf( + temp, + ::std::mem::size_of::<[libc::c_char; 64]>() as usize, + b"Stopped(%s)\0" as *const u8 as *const libc::c_char, + signal_name(WSTOPSIG!((*p).status)), + ); + } + } else if RUNNING!(j) { + temp = b"Running\0" as *const u8 as *mut libc::c_char; + } else { + if WIFSTOPPED!((*p).status) { + temp = j_strsignal(WSTOPSIG!((*p).status)); + } else if WIFSIGNALED!((*p).status) { + temp = j_strsignal(WTERMSIG!((*p).status)); + } else if WIFEXITED!((*p).status) { + temp = retcode_name_buffer.as_mut_ptr(); + es = WEXITSTATUS!((*p).status); + if es == 0 { + libc::strncpy( + temp, + b"Done\0" as *const u8 as *mut libc::c_char, + std::mem::size_of::<[libc::c_char; 64]>() - 1, + ); + *temp.offset( + (::std::mem::size_of::<[libc::c_char; 64]>() as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + as isize, + ) = '\u{0}' as i32 as libc::c_char; + } else if posixly_correct != 0 { + libc::snprintf( + temp, + ::std::mem::size_of::<[libc::c_char; 64]>() as usize, + b"Done(%d)\0" as *const u8 as *const libc::c_char, + es, + ); + } else { + libc::snprintf( + temp, + ::std::mem::size_of::<[libc::c_char; 64]>() as usize, + b"Exit(%d)\0" as *const u8 as *const libc::c_char, + es, + ); + } + } else { + temp = b"Unknown status\0" as *const u8 as *mut libc::c_char; + } + } + + return temp; + } +} + +fn print_pipeline( + mut p: *mut PROCESS, + mut job_index: libc::c_int, + mut format: libc::c_int, + mut stream: *mut libc::FILE, +) { + unsafe { + let mut first: *mut PROCESS = 0 as *mut PROCESS; + let mut last: *mut PROCESS = 0 as *mut PROCESS; + let mut show: *mut PROCESS = 0 as *mut PROCESS; + let mut es: libc::c_int = 0; + let mut name_padding: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + + if p.is_null() { + return; + } + + last = p; + first = last; + while (*last).next != first { + last = (*last).next; + } + + loop { + if p != first { + libc::fprintf( + stream, + if format != 0 { + b" \0" as *const u8 as *const libc::c_char + } else { + b" |\0" as *const u8 as *const libc::c_char + }, + ); + } + if format != 0 { + libc::fprintf( + stream, + b"%5ld\0" as *const u8 as *const libc::c_char, + (*p).pid as libc::c_long, + ); + } + libc::fprintf(stream, b" \0" as *const u8 as *const libc::c_char); + + if format > -1 && job_index >= 0 { + show = if format != 0 { p } else { last }; + temp = printable_job_status(job_index, show, format); + + if p != first { + if format != 0 { + if (*show).running == (*first).running + && WSTATUS!((*show).status) == WSTATUS!((*first).status) + { + temp = b"\0" as *const u8 as *mut libc::c_char; + } + } else { + temp = 0 as *mut libc::c_char; + } + } + + if !temp.is_null() { + libc::fprintf(stream, b"%s\0" as *const u8 as *const libc::c_char, temp); + es = STRLEN!(temp) as libc::c_int; + + if es == 0 { + es = 2; + } + name_padding = LONGEST_SIGNAL_DESC as libc::c_int - es; + libc::fprintf( + stream, + b"%*s\0" as *const u8 as *const libc::c_char, + name_padding, + b"\0" as *const u8 as *const libc::c_char, + ); + if (WIFSTOPPED!((*show).status)) as libc::c_int == 0 + && (WIFCONTINUED!((*show).status)) as libc::c_int == 0 + && WIFCORED!((*show).status) as libc::c_int != 0 + { + libc::fprintf( + stream, + b"(core dumped) \0" as *const u8 as *const libc::c_char, + ); + } + } + } + if p != first && format != 0 { + libc::fprintf(stream, b"| \0" as *const u8 as *const libc::c_char); + } + if !((*p).command).is_null() { + fprintf( + stream, + b"%s\0" as *const u8 as *const libc::c_char, + (*p).command, + ); + } + if p == last && job_index >= 0 { + temp = current_working_directory(); + if RUNNING!(job_index) && IS_FOREGROUND!(job_index) as libc::c_int == 0 { + fprintf(stream, b" &\0" as *const u8 as *const libc::c_char); + } + if libc::strcmp(temp, (**jobs.offset(job_index as isize)).wd) != 0 as libc::c_int { + fprintf( + stream, + b" (wd: %s)\0" as *const u8 as *const libc::c_char, + polite_directory_format((**jobs.offset(job_index as isize)).wd), + ); + } + } + if format != 0 || p == last { + if asynchronous_notification != 0 && interactive != 0 { + libc::fputc('\r' as i32, stream); + } + fprintf(stream, b"\n\0" as *const u8 as *const libc::c_char); + } + if p == last { + break; + } + p = (*p).next; + } + libc::fflush(stream); + } +} + +fn pretty_print_job( + mut job_index: libc::c_int, + mut format: libc::c_int, + mut stream: *mut libc::FILE, +) { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + + if format == JLIST_PID_ONLY as libc::c_int { + fprintf( + stream, + b"%ld\n\0" as *const u8 as *const libc::c_char, + (*(**jobs.offset(job_index as isize)).pipe).pid as libc::c_long, + ); + return; + } + if format == JLIST_CHANGED_ONLY as libc::c_int { + if IS_NOTIFIED!(job_index) { + return; + } + format = JLIST_STANDARD as libc::c_int; + } + if format != JLIST_NONINTERACTIVE as libc::c_int { + fprintf( + stream, + b"[%d]%c \0" as *const u8 as *const libc::c_char, + job_index + 1 as libc::c_int, + if job_index == js.j_current { + '+' as i32 + } else if job_index == js.j_previous { + '-' as i32 + } else { + ' ' as i32 + }, + ); + } + if format == JLIST_NONINTERACTIVE as libc::c_int { + format = JLIST_LONG as libc::c_int; + } + p = (**jobs.offset(job_index as isize)).pipe; + print_pipeline(p, job_index, format, stream); + (**jobs.offset(job_index as isize)).flags |= J_NOTIFIED as libc::c_int; + } +} + +fn print_job( + mut job: *mut JOB, + mut format: libc::c_int, + mut state: libc::c_int, + mut job_index: libc::c_int, +) -> libc::c_int { + unsafe { + if state == -(1 as libc::c_int) + || state as JOB_STATE as libc::c_int == (*job).state as libc::c_int + { + pretty_print_job(job_index, format, stdout); + } + return 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn list_one_job( + mut job: *mut JOB, + mut format: libc::c_int, + mut ignore: libc::c_int, + mut job_index: libc::c_int, +) { + unsafe { + pretty_print_job(job_index, format, stdout); + cleanup_dead_jobs(); + } +} + +#[no_mangle] +pub fn list_stopped_jobs(mut format: libc::c_int) { + unsafe { + cleanup_dead_jobs(); + map_over_jobs( + ::std::mem::transmute:: libc::c_int>, Option>(Some( + ::std::mem::transmute::< + fn(*mut JOB, libc::c_int, libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(print_job), + )), + format, + JSTOPPED as libc::c_int, + ); + } +} + +#[no_mangle] +pub fn list_running_jobs(mut format: libc::c_int) { + cleanup_dead_jobs(); + unsafe { + map_over_jobs( + ::std::mem::transmute:: libc::c_int>, Option>(Some( + ::std::mem::transmute::< + fn(*mut JOB, libc::c_int, libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(print_job), + )), + format, + JRUNNING as libc::c_int, + ); + } +} + +#[no_mangle] +pub fn list_all_jobs(mut format: libc::c_int) { + cleanup_dead_jobs(); + unsafe { + map_over_jobs( + ::std::mem::transmute:: libc::c_int>, Option>(Some( + ::std::mem::transmute::< + fn(*mut JOB, libc::c_int, libc::c_int, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(print_job), + )), + format, + -(1 as libc::c_int), + ); + } +} + +#[no_mangle] +pub fn make_child(mut command: *mut libc::c_char, mut flags: libc::c_int) -> pid_t { + unsafe { + let mut async_p: libc::c_int = 0; + let mut forksleep: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut termset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut chldset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset_copy: sigset_t = __sigset_t { __val: [0; 16] }; + let mut pid: pid_t = 0; + //let mut oterm: *mut SigHandler = 0 as *mut SigHandler; + let mut oterm: Option = None; + sigemptyset(&mut oset_copy); + sigprocmask( + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut sigset_t, + &mut oset_copy, + ); + sigaddset(&mut oset_copy, 15 as libc::c_int); + sigemptyset(&mut set); + sigaddset(&mut set, 17 as libc::c_int); + sigaddset(&mut set, 2 as libc::c_int); + sigaddset(&mut set, 15 as libc::c_int); + sigemptyset(&mut oset); + sigprocmask(0 as libc::c_int, &mut set, &mut oset); + if interactive_shell != 0 { + oterm = set_signal_handler(15 as libc::c_int, None); + } + making_children(); + async_p = flags & 1 as libc::c_int; + forksleep = 1 as libc::c_int; + if default_buffered_input != -(1 as libc::c_int) + && (async_p == 0 || default_buffered_input > 0 as libc::c_int) + { + sync_buffered_stream(default_buffered_input); + } + loop { + pid = fork(); + if !(pid < 0 as libc::c_int + && *__errno_location() == 11 as libc::c_int + && forksleep < 16 as libc::c_int) + { + break; + } + sigprocmask( + 2 as libc::c_int, + &mut oset_copy, + 0 as *mut libc::c_void as *mut sigset_t, + ); + waitchld(-(1 as libc::c_int), 0 as libc::c_int); + *__errno_location() = 11 as libc::c_int; + sys_error(b"fork: retry\0" as *const u8 as *const libc::c_char); + if sleep(forksleep as libc::c_uint) != 0 as libc::c_int as libc::c_uint { + break; + } + forksleep <<= 1 as libc::c_int; + if interrupt_state != 0 { + break; + } + sigprocmask( + 2 as libc::c_int, + &mut set, + 0 as *mut libc::c_void as *mut sigset_t, + ); + } + if pid != 0 as libc::c_int { + if interactive_shell != 0 { + set_signal_handler(15 as libc::c_int, oterm); + } + } + if pid < 0 as libc::c_int { + sys_error(b"fork\0" as *const u8 as *const libc::c_char); + terminate_current_pipeline(); + if !the_pipeline.is_null() { + kill_current_pipeline(); + } + set_exit_status(126 as libc::c_int); + throw_to_top_level(); + } + if pid == 0 as libc::c_int { + let mut mypid: pid_t = 0; + mypid = getpid(); + unset_bash_input(0 as libc::c_int); + ::std::ptr::write_volatile(&mut interrupt_state as *mut sig_atomic_t, 0 as libc::c_int); + restore_sigmask(); + if job_control != 0 { + if pipeline_pgrp == 0 as libc::c_int { + pipeline_pgrp = mypid; + } + if pipeline_pgrp == shell_pgrp { + ignore_tty_job_signals(); + } else { + default_tty_job_signals(); + } + if setpgid(mypid, pipeline_pgrp) < 0 as libc::c_int { + sys_error( + dcgettext( + 0 as *const libc::c_char, + b"child setpgid (%ld to %ld)\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + mypid as libc::c_long, + pipeline_pgrp as libc::c_long, + ); + } + if flags & 4 as libc::c_int == 0 as libc::c_int + && async_p == 0 as libc::c_int + && pipeline_pgrp != shell_pgrp + && subshell_environment & (0x1 as libc::c_int | 0x10 as libc::c_int) + == 0 as libc::c_int + && running_in_background == 0 as libc::c_int + { + give_terminal_to(pipeline_pgrp, 0 as libc::c_int); + } + if pipeline_pgrp == mypid { + pipe_read(pgrp_pipe.as_mut_ptr()); + } + } else { + if pipeline_pgrp == 0 as libc::c_int { + pipeline_pgrp = shell_pgrp; + } + default_tty_job_signals(); + } + sh_closepipe(pgrp_pipe.as_mut_ptr()); + } else { + if job_control != 0 { + if pipeline_pgrp == 0 as libc::c_int { + pipeline_pgrp = pid; + } + setpgid(pid, pipeline_pgrp); + } else if pipeline_pgrp == 0 as libc::c_int { + pipeline_pgrp = shell_pgrp; + } + add_process(command, pid); + if async_p != 0 { + ::std::ptr::write_volatile(&mut last_asynchronous_pid as *mut pid_t, pid); + } + delete_old_job(pid); + bgp_delete(pid); + ::std::ptr::write_volatile(&mut last_made_pid as *mut pid_t, pid); + js.c_totforked += 1; + js.c_living += 1; + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + } + return pid; + } +} + +#[no_mangle] +pub fn ignore_tty_job_signals() { + unsafe { + set_signal_handler(SIGTSTP as libc::c_int, SIG_IGN!()); + set_signal_handler(SIGTTIN as libc::c_int, SIG_IGN!()); + set_signal_handler(SIGTTOU as libc::c_int, SIG_IGN!()); + } +} + +#[no_mangle] +pub fn default_tty_job_signals() { + unsafe { + if signal_is_trapped(SIGTSTP as libc::c_int) == 0 + && signal_is_hard_ignored(SIGTSTP as libc::c_int) != 0 + { + set_signal_handler(SIGTSTP as libc::c_int, SIG_IGN!()); + } else { + set_signal_handler(SIGTSTP as libc::c_int, None); + } + if signal_is_trapped(SIGTTIN as libc::c_int) == 0 + && signal_is_hard_ignored(SIGTTIN as libc::c_int) != 0 + { + set_signal_handler(SIGTTIN as libc::c_int, SIG_IGN!()); + } else { + set_signal_handler(SIGTTIN as libc::c_int, None); + } + if signal_is_trapped(SIGTTOU as libc::c_int) == 0 + && signal_is_hard_ignored(SIGTTOU as libc::c_int) != 0 + { + set_signal_handler(SIGTTOU as libc::c_int, SIG_IGN!()); + } else { + set_signal_handler(SIGTTOU as libc::c_int, None); + }; + } +} + +#[no_mangle] +pub fn get_original_tty_job_signals() { + static mut fetched: libc::c_int = 0 as libc::c_int; + unsafe { + if fetched == 0 as libc::c_int { + if interactive_shell != 0 { + set_original_signal(SIGTSTP as libc::c_int, None); + set_original_signal(SIGTTIN as libc::c_int, None); + set_original_signal(SIGTTOU as libc::c_int, None); + } else { + get_original_signal(SIGTSTP as libc::c_int); + get_original_signal(SIGTTIN as libc::c_int); + get_original_signal(SIGTTOU as libc::c_int); + } + fetched = 1; + } + } +} + +static mut shell_tty_info: libc::termios = libc::termios { + c_iflag: 0, + c_oflag: 0, + c_cflag: 0, + c_lflag: 0, + c_line: 0, + c_cc: [0; 32], + c_ispeed: 0, + c_ospeed: 0, +}; + +#[no_mangle] +pub fn get_tty_state() -> libc::c_int { + let mut tty: libc::c_int = 0; + unsafe { + tty = input_tty!(); + if tty != -1 { + if libc::tcgetattr(tty, &mut shell_tty_info) < 0 { + return -(1 as libc::c_int); + } + if check_window_size != 0 { + get_new_window_size( + 0 as libc::c_int, + 0 as *mut libc::c_int, + 0 as *mut libc::c_int, + ); + } + } + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn set_tty_state() -> libc::c_int { + let mut tty: libc::c_int = 0; + unsafe { + tty = input_tty!(); + if tty != -1 { + if libc::tcsetattr(tty, 1 as libc::c_int, &mut shell_tty_info) < 0 as libc::c_int { + if interactive != 0 { + sys_error( + b"[%ld: %d (%d)] tcsetattr\0" as *const u8 as *const libc::c_char, + getpid() as libc::c_long, + shell_level, + tty, + ); + } + return -1; + } + } + return 0; + } +} + +fn find_last_proc(mut job: libc::c_int, mut block: libc::c_int) -> *mut PROCESS { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if block != 0 { + BLOCK_CHILD(&mut set, &mut oset); + } + p = (**jobs.offset(job as isize)).pipe; + while !p.is_null() && (*p).next != (**jobs.offset(job as isize)).pipe { + p = (*p).next; + } + if block != 0 { + UNBLOCK_CHILD(&mut oset); + } + return p; + } +} + +fn find_last_pid(mut job: libc::c_int, mut block: libc::c_int) -> pid_t { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + p = find_last_proc(job, block); + return (*p).pid; + } +} + +#[no_mangle] +pub fn wait_for_single_pid(mut pid: pid_t, mut flags: libc::c_int) -> libc::c_int { + unsafe { + let mut child: *mut PROCESS = 0 as *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut r: libc::c_int = 0; + let mut job: libc::c_int = 0; + let mut alive: libc::c_int = 0; + + BLOCK_CHILD(&mut set, &mut oset); + child = find_pipeline(pid, 0, 0 as *mut libc::c_int); + UNBLOCK_CHILD(&mut oset); + + if child.is_null() { + r = bgp_search(pid); + if r >= 0 { + return r; + } + } + if child.is_null() { + if flags & JWAIT_PERROR as libc::c_int != 0 { + internal_error( + b"wait: pid %ld is not a child of this shell\0" as *const u8 + as *const libc::c_char, + pid as libc::c_long, + ); + } + return 127; + } + alive = 0; + loop { + r = wait_for(pid, 0); + if flags & JWAIT_FORCE as libc::c_int == 0 { + break; + } + + BLOCK_CHILD(&mut set, &mut oset); + alive = PALIVE!(child) as libc::c_int; + UNBLOCK_CHILD(&mut oset); + + if !(alive != 0) { + break; + } + } + + BLOCK_CHILD(&mut set, &mut oset); + job = find_job(pid, 0, 0 as *mut *mut PROCESS); + if job != NO_JOB && !(*jobs.offset(job as isize)).is_null() && DEADJOB!(job) { + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + } + UNBLOCK_CHILD(&mut oset); + + if posixly_correct != 0 { + cleanup_dead_jobs(); + bgp_delete(pid); + } + + CHECK_WAIT_INTR!(); + + return r; + } +} + +#[no_mangle] +pub fn wait_for_background_pids(mut ps: *mut procstat) { + let mut i: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut any_stopped: libc::c_int = 0; + let mut check_async: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut pid: pid_t = 0; + + any_stopped = 0; + check_async = 1; + unsafe { + loop { + BLOCK_CHILD(&mut set, &mut set); + + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() && STOPPED!(i) { + builtin_warning( + b"job %d[%d] stopped\0" as *const u8 as *const libc::c_char, + i + 1, + find_last_pid(i, 0), + ); + any_stopped = 1; + } + if !(*jobs.offset(i as isize)).is_null() && RUNNING!(i) && IS_FOREGROUND!(i) { + break; + } + i += 1; + } + if i == js.j_jobslots { + UNBLOCK_CHILD(&mut oset); + break; + } + + pid = find_last_pid(i, 0); + UNBLOCK_CHILD(&mut oset); + QUIT!(); + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + *__errno_location() = 0; + r = wait_for_single_pid(pid, JWAIT_PERROR as libc::c_int); + if !ps.is_null() { + (*ps).pid = pid; + (*ps).status = (if r < 0 as libc::c_int { + 127 as libc::c_int + } else { + r + }) as libc::c_short; + } + if r == -1 && *__errno_location() == ECHILD as libc::c_int { + check_async = 0; + mark_all_jobs_as_dead(); + } + } + procsub_waitall(); + mark_dead_jobs_as_notified(1); + cleanup_dead_jobs(); + bgp_clear(); + } +} + +static mut wait_sigint_received: libc::c_int = 0; +static mut child_caught_sigint: libc::c_int = 0; + +#[no_mangle] +pub fn wait_sigint_cleanup() { + unsafe { + queue_sigchld = 0; + waiting_for_child = 0; + } +} + +#[macro_export] +macro_rules! INVALID_SIGNAL_HANDLER { + () => { + ::std::mem::transmute:: ()>, Option>(Some( + ::std::mem::transmute:: (), fn() -> ()>(wait_for_background_pids), + )) + }; +} + +static mut old_sigint_handler: Option = unsafe { INVALID_SIGNAL_HANDLER!() }; + +fn restore_sigint_handler() { + unsafe { + if old_sigint_handler != INVALID_SIGNAL_HANDLER!() { + set_signal_handler(SIGINT as libc::c_int, old_sigint_handler); + old_sigint_handler = INVALID_SIGNAL_HANDLER!(); + waiting_for_child = 0; + } + } +} + +fn wait_sigint_handler(mut sig: libc::c_int) { + unsafe { + let mut sigint_handler: Option = None; + + if this_shell_builtin.is_some() && this_shell_builtin == Some(wait_builtin) { + set_exit_status(128 + SIGINT as libc::c_int); + restore_sigint_handler(); + if this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + && signal_is_trapped(SIGINT as libc::c_int) != 0 + && { + // sigint_handler = Some(trap_to_sighandler(SIGINT as libc::c_int)); + // sigint_handler == Some(Some(trap_handler as unsafe extern "C" fn(c_int) -> ())) + sigint_handler = trap_to_sighandler(SIGINT as libc::c_int); + sigint_handler == Some(trap_handler) + } + { + trap_handler(SIGINT as libc::c_int); + wait_signal_received = SIGINT as libc::c_int; + if wait_intr_flag != 0 { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1); + } else { + return; + } + } else { + kill(getpid(), SIGINT as libc::c_int); + } + } + if waiting_for_child != 0 { + wait_sigint_received = 1; + } else { + set_exit_status(128 + SIGINT as libc::c_int); + restore_sigint_handler(); + kill(getpid(), SIGINT as libc::c_int); + }; + } +} + +fn process_exit_signal(mut status: WAIT) -> libc::c_int { + if libc::WIFSIGNALED(status) { + return libc::WTERMSIG(status); + } else { + return 0; + } +} +fn process_exit_status(mut status: WAIT) -> libc::c_int { + unsafe { + if WIFSIGNALED!(status) { + return 128 + WTERMSIG!(status); + } else if WIFSTOPPED!(status) as libc::c_int == 0 { + return WEXITSTATUS!(status); + } else { + return 0; + } + } +} + +fn job_signal_status(mut job: libc::c_int) -> WAIT { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut s: WAIT = 0; + + p = (**jobs.offset(job as isize)).pipe; + loop { + s = (*p).status; + if WIFSIGNALED!(s) || WIFSTOPPED!(s) { + break; + } + p = (*p).next; + if !(p != (**jobs.offset(job as isize)).pipe) { + break; + } + } + return s; + } +} + +fn raw_job_exit_status(mut job: libc::c_int) -> WAIT { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut fail: libc::c_int = 0; + let mut ret: WAIT = 0; + + if (**jobs.offset(job as isize)).flags & J_PIPEFAIL as libc::c_int != 0 { + fail = 0; + p = (**jobs.offset(job as isize)).pipe; + loop { + if WSTATUS!((*p).status) != 0 { + fail = WSTATUS!((*p).status); + } + p = (*p).next; + if !(p != (**jobs.offset(job as isize)).pipe) { + break; + } + } + WSTATUS!(ret) = fail; + return ret; + } + p = (**jobs.offset(job as isize)).pipe; + while (*p).next != (**jobs.offset(job as isize)).pipe { + p = (*p).next; + } + return (*p).status; + } +} + +#[no_mangle] +pub fn job_exit_status(mut job: libc::c_int) -> libc::c_int { + return process_exit_status(raw_job_exit_status(job)); +} +#[no_mangle] +pub fn job_exit_signal(mut job: libc::c_int) -> libc::c_int { + return process_exit_signal(raw_job_exit_status(job)); +} + +#[no_mangle] +pub fn wait_for(mut pid: pid_t, mut flags: libc::c_int) -> libc::c_int { + unsafe { + let mut current_block: u64; + let mut job: libc::c_int = 0; + let mut termination_state: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut s: WAIT = 0; + let mut child: *mut PROCESS = 0 as *mut PROCESS; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + child = 0 as *mut PROCESS; + sigemptyset(&mut set); + sigaddset(&mut set, 17 as libc::c_int); + sigemptyset(&mut oset); + sigprocmask(0 as libc::c_int, &mut set, &mut oset); + child_caught_sigint = 0 as libc::c_int; + wait_sigint_received = child_caught_sigint; + if job_control == 0 as libc::c_int || subshell_environment & 0x4 as libc::c_int != 0 { + //let mut temp_sigint_handler: *mut SigHandler; + let mut temp_sigint_handler: Option = None; + temp_sigint_handler = set_signal_handler( + SIGINT as libc::c_int, + //wait_sigint_handler as *mut Option, + ::core::mem::transmute:: ()>, Option>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + wait_sigint_handler, + ), + )), + ); + if !(temp_sigint_handler + == ::core::mem::transmute:: ()>, Option>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + wait_sigint_handler, + ), + ))) + { + old_sigint_handler = temp_sigint_handler; + } + waiting_for_child = 0; + if old_sigint_handler + == ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ) + { + set_signal_handler(2 as libc::c_int, old_sigint_handler); + } + } + termination_state = last_command_exit_value; + if interactive != 0 && job_control == 0 as libc::c_int { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + } + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if wait_intr_flag != 0 + && wait_signal_received != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + job = -(1 as libc::c_int); + loop { + if pid != -(1 as libc::c_int) { + child = find_pipeline( + pid, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if child.is_null() { + give_terminal_to(shell_pgrp, 0 as libc::c_int); + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"wait_for: No record of process %ld\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + pid as libc::c_long, + ); + restore_sigint_handler(); + termination_state = 127 as libc::c_int; + return termination_state; + } + } + if job == -(1 as libc::c_int) && pid != -(1 as libc::c_int) { + job = find_job(pid, 0 as libc::c_int, 0 as *mut *mut PROCESS); + } + if pid == -(1 as libc::c_int) + || (*child).running == 1 as libc::c_int + || job != -(1 as libc::c_int) + && (**jobs.offset(job as isize)).state as libc::c_int == JRUNNING as libc::c_int + { + let mut old_waiting: libc::c_int = 0; + queue_sigchld = 1 as libc::c_int; + old_waiting = waiting_for_child; + waiting_for_child = 1 as libc::c_int; + if wait_intr_flag != 0 + && wait_signal_received != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + r = waitchld(pid, 1 as libc::c_int); + waiting_for_child = old_waiting; + queue_sigchld = 0 as libc::c_int; + if r == -(1 as libc::c_int) + && *__errno_location() == 10 as libc::c_int + && this_shell_builtin == Some(wait_builtin) + { + termination_state = -(1 as libc::c_int); + restore_sigint_handler(); + current_block = 6718615339517147058; + break; + } else if r == -(1 as libc::c_int) && *__errno_location() == 10 as libc::c_int { + if !child.is_null() { + (*child).running = 0 as libc::c_int; + (*child).status = 0 as libc::c_int; + } + js.c_living = 0 as libc::c_int; + if job != -(1 as libc::c_int) { + (**jobs.offset(job as isize)).state = JDEAD; + js.c_reaped += 1; + js.j_ndead += 1; + } + if pid == -(1 as libc::c_int) { + termination_state = -(1 as libc::c_int); + current_block = 7072655752890836508; + break; + } + } + } + if interactive != 0 && job_control == 0 as libc::c_int { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + } + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if wait_intr_flag != 0 + && wait_signal_received != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + if pid == -(1 as libc::c_int) { + restore_sigint_handler(); + current_block = 6718615339517147058; + break; + } else if !((*child).running == 1 as libc::c_int + || job != -(1 as libc::c_int) + && (**jobs.offset(job as isize)).state as libc::c_int + == JRUNNING as libc::c_int) + { + current_block = 7072655752890836508; + break; + } + } + match current_block { + 7072655752890836508 => { + restore_sigint_handler(); + termination_state = if job != -(1 as libc::c_int) { + job_exit_status(job) + } else if !child.is_null() { + process_exit_status((*child).status) + } else { + 0 as libc::c_int + }; + last_command_exit_signal = if job != -(1 as libc::c_int) { + job_exit_signal(job) + } else if !child.is_null() { + process_exit_signal((*child).status) + } else { + 0 as libc::c_int + }; + if job != -(1 as libc::c_int) + && (**jobs.offset(job as isize)).state as libc::c_int == JSTOPPED as libc::c_int + || !child.is_null() + && (*child).status & 0xff as libc::c_int == 0x7f as libc::c_int + { + termination_state = 128 as libc::c_int + + (((*child).status & 0xff00 as libc::c_int) >> 8 as libc::c_int); + } + if job == -(1 as libc::c_int) + || (**jobs.offset(job as isize)).flags & 0x4 as libc::c_int != 0 as libc::c_int + { + if flags & (1 as libc::c_int) << 8 as libc::c_int == 0 as libc::c_int + && running_in_background == 0 as libc::c_int + && subshell_environment & (0x1 as libc::c_int | 0x10 as libc::c_int) + == 0 as libc::c_int + { + give_terminal_to(shell_pgrp, 0 as libc::c_int); + } + } + if job != -(1 as libc::c_int) { + if interactive_shell != 0 && subshell_environment == 0 as libc::c_int { + s = job_signal_status(job); + if ((s & 0x7f as libc::c_int) + 1 as libc::c_int) as libc::c_schar + as libc::c_int + >> 1 as libc::c_int + > 0 as libc::c_int + || s & 0xff as libc::c_int == 0x7f as libc::c_int + { + set_tty_state(); + if check_window_size != 0 + && (job == js.j_current + || (**jobs.offset(job as isize)).flags & 0x1 as libc::c_int + != 0 as libc::c_int) + { + get_new_window_size( + 0 as libc::c_int, + 0 as *mut libc::c_int, + 0 as *mut libc::c_int, + ); + } + } else if rl_readline_state & 0x4000 as libc::c_int as libc::c_ulong + == 0 as libc::c_int as libc::c_ulong + { + get_tty_state(); + } + if job_control != 0 + && (**jobs.offset(job as isize)).flags & 0x4 as libc::c_int + != 0 as libc::c_int + && (**jobs.offset(job as isize)).flags & 0x1 as libc::c_int + != 0 as libc::c_int + && ((s & 0x7f as libc::c_int) + 1 as libc::c_int) as libc::c_schar + as libc::c_int + >> 1 as libc::c_int + > 0 as libc::c_int + && s & 0x7f as libc::c_int == 2 as libc::c_int + { + if signal_is_trapped(2 as libc::c_int) == 0 as libc::c_int + && (loop_level != 0 + || shell_compatibility_level > 32 as libc::c_int + && executing_list != 0) + { + ::std::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + ::std::ptr::read_volatile::( + &interrupt_state as *const sig_atomic_t, + ) + 1, + ); + } else if signal_is_trapped(2 as libc::c_int) != 0 && loop_level != 0 { + ::std::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + ::std::ptr::read_volatile::( + &interrupt_state as *const sig_atomic_t, + ) + 1, + ); + } else if interactive_shell != 0 + && signal_is_trapped(2 as libc::c_int) == 0 as libc::c_int + && sourcelevel != 0 + { + ::std::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + ::std::ptr::read_volatile::( + &interrupt_state as *const sig_atomic_t, + ) + 1, + ); + } else { + putchar('\n' as i32); + libc::fflush(stdout); + } + } + } else if subshell_environment & (0x4 as libc::c_int | 0x10 as libc::c_int) != 0 + && wait_sigint_received != 0 + { + if child_caught_sigint == 0 as libc::c_int + && signal_is_trapped(2 as libc::c_int) == 0 as libc::c_int + { + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + old_sigint_handler = set_signal_handler(2 as libc::c_int, None); + if old_sigint_handler == SIG_IGN!() { + restore_sigint_handler(); + } else { + kill(getpid(), 2 as libc::c_int); + } + } + } else if interactive_shell == 0 as libc::c_int + && subshell_environment == 0 as libc::c_int + && (**jobs.offset(job as isize)).flags & 0x1 as libc::c_int + != 0 as libc::c_int + { + s = job_signal_status(job); + if job_control != 0 + && (**jobs.offset(job as isize)).flags & 0x4 as libc::c_int + != 0 as libc::c_int + && ((s & 0x7f as libc::c_int) + 1 as libc::c_int) as libc::c_schar + as libc::c_int + >> 1 as libc::c_int + > 0 as libc::c_int + && s & 0x7f as libc::c_int == 2 as libc::c_int + { + ::std::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + ::std::ptr::read_volatile::( + &interrupt_state as *const sig_atomic_t, + ) + 1, + ); + } + if check_window_size != 0 { + get_new_window_size( + 0 as libc::c_int, + 0 as *mut libc::c_int, + 0 as *mut libc::c_int, + ); + } + } + if (**jobs.offset(job as isize)).state as libc::c_int == JDEAD as libc::c_int + && (**jobs.offset(job as isize)).flags & 0x1 as libc::c_int + != 0 as libc::c_int + { + setjstatus(job); + } + notify_and_cleanup(); + } + } + _ => {} + } + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + return termination_state; + } +} + +#[no_mangle] +pub fn wait_for_job( + mut job: libc::c_int, + mut flags: libc::c_int, + mut ps: *mut procstat, +) -> libc::c_int { + unsafe { + let mut pid: pid_t = 0; + let mut r: libc::c_int = 0; + let mut state: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + state = JOBSTATE!(job); + if state == JSTOPPED as libc::c_int { + internal_warning( + b"wait_for_job: job %d is stopped\0" as *const u8 as *const libc::c_char, + job + 1 as libc::c_int, + ); + } + + pid = find_last_pid(job, 0); + UNBLOCK_CHILD(&mut oset); + + loop { + r = wait_for(pid, 0); + if r == -1 && errno!() == ECHILD { + mark_all_jobs_as_dead(); + } + + CHECK_WAIT_INTR!(); + + if flags & JWAIT_FORCE as libc::c_int == 0 { + break; + } + BLOCK_CHILD(&mut set, &mut oset); + state = if job != NO_JOB && !(*jobs.offset(job as isize)).is_null() { + JOBSTATE!(job) + } else { + JDEAD as libc::c_int + }; + UNBLOCK_CHILD(&mut oset); + if !(state != JDEAD as libc::c_int) { + break; + } + } + + BLOCK_CHILD(&mut set, &mut oset); + if job != NO_JOB && !(*jobs.offset(job as isize)).is_null() && DEADJOB!(job) { + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + } + UNBLOCK_CHILD(&mut oset); + if !ps.is_null() { + (*ps).pid = pid; + (*ps).status = (if r < 0 { 127 } else { r }) as libc::c_short; + } + return r; + } +} + +#[no_mangle] +pub fn wait_for_any_job(mut flags: libc::c_int, mut ps: *mut procstat) -> libc::c_int { + unsafe { + let mut current_block: u64; + let mut pid: pid_t = 0; + let mut i: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if jobs_list_frozen != 0 { + return -1; + } + + BLOCK_CHILD(&mut set, &mut oset); + i = 0 as libc::c_int; + loop { + if i < js.j_jobslots { + if !(flags & JWAIT_WAITING as libc::c_int != 0 + && !(*jobs.offset(i as isize)).is_null() + && IS_WAITING!(i) as libc::c_int == 0) + { + if !(*jobs.offset(i as isize)).is_null() + && DEADJOB!(i) + && IS_NOTIFIED!(i) as libc::c_int == 0 + { + current_block = 2729223887955387488; + break; + } + } + i += 1; + } else { + UNBLOCK_CHILD(&mut oset); + current_block = 7172762164747879670; + break; + } + } + 'c_22951: loop { + match current_block { + 2729223887955387488 => { + r = job_exit_status(i); + break; + } + _ => { + BLOCK_CHILD(&mut set, &mut oset); + i = 0 as libc::c_int; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() + && RUNNING!(i) + && IS_FOREGROUND!(i) as libc::c_int == 0 + { + break; + } + i += 1; + } + if i == js.j_jobslots { + UNBLOCK_CHILD(&mut oset); + return -1; + } + UNBLOCK_CHILD(&mut oset); + + QUIT!(); + CHECK_TERMSIG!(); + CHECK_WAIT_INTR!(); + + errno!() = 0; + r = wait_for(ANY_PID, 0); + if r == -1 && errno!() == ECHILD { + mark_all_jobs_as_dead(); + } + BLOCK_CHILD(&mut set, &mut oset); + + i = 0 as libc::c_int; + while i < js.j_jobslots { + if !(flags & JWAIT_WAITING as libc::c_int != 0 + && !(*jobs.offset(i as isize)).is_null() + && IS_WAITING!(i) as libc::c_int == 0) + { + if !(*jobs.offset(i as isize)).is_null() && DEADJOB!(i) { + current_block = 2729223887955387488; + continue 'c_22951; + } + } + i += 1; + } + UNBLOCK_CHILD(&mut oset); + current_block = 7172762164747879670; + } + } + } + pid = find_last_pid(i, 0); + if !ps.is_null() { + (*ps).pid = pid; + (*ps).status = r as libc::c_short; + } + notify_of_job_status(); + delete_job(i, 0); + coproc_reap(); + UNBLOCK_CHILD(&mut oset); + return r; + } +} + +#[no_mangle] +pub fn notify_and_cleanup() { + unsafe { + if jobs_list_frozen != 0 { + return; + } + if interactive != 0 || interactive_shell == 0 || sourcelevel != 0 { + notify_of_job_status(); + } + cleanup_dead_jobs(); + } +} + +#[no_mangle] +pub fn reap_dead_jobs() { + mark_dead_jobs_as_notified(0); + cleanup_dead_jobs(); +} + +fn most_recent_job_in_state(mut job: libc::c_int, mut state: JOB_STATE) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + sigemptyset(&mut set); + sigaddset(&mut set, 17 as libc::c_int); + sigemptyset(&mut oset); + sigprocmask(0 as libc::c_int, &mut set, &mut oset); + result = -(1 as libc::c_int); + i = job - 1 as libc::c_int; + while i >= 0 as libc::c_int { + if !(*jobs.offset(i as isize)).is_null() + && (**jobs.offset(i as isize)).state as libc::c_int == state as libc::c_int + { + result = i; + break; + } else { + i -= 1; + } + } + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + return result; + } +} + +fn job_last_stopped(mut job: libc::c_int) -> libc::c_int { + return most_recent_job_in_state(job, JSTOPPED as libc::c_int); +} + +fn job_last_running(mut job: libc::c_int) -> libc::c_int { + return most_recent_job_in_state(job, JRUNNING as libc::c_int); +} + +fn set_current_job(mut job: libc::c_int) { + let mut candidate: libc::c_int = 0; + unsafe { + if js.j_current != job { + js.j_previous = js.j_current; + js.j_current = job; + } + + if js.j_previous != js.j_current + && js.j_previous != NO_JOB + && !(*jobs.offset(js.j_previous as isize)).is_null() + && (**jobs.offset(js.j_previous as isize)).state as libc::c_int + == JSTOPPED as libc::c_int + { + return; + } + candidate = NO_JOB; + if (**jobs.offset(js.j_current as isize)).state as libc::c_int == JSTOPPED as libc::c_int { + candidate = job_last_stopped(js.j_current); + if candidate != NO_JOB { + js.j_previous = candidate; + return; + } + } + candidate = if (**jobs.offset(js.j_current as isize)).state as libc::c_int + == JRUNNING as libc::c_int + { + job_last_running(js.j_current) + } else { + job_last_running(js.j_jobslots) + }; + if candidate != NO_JOB { + js.j_previous = candidate; + return; + } + js.j_previous = js.j_current; + } +} + +fn reset_current() { + let mut candidate: libc::c_int = 0; + unsafe { + if js.j_jobslots != 0 + && js.j_current != NO_JOB + && !(*jobs.offset(js.j_current as isize)).is_null() + && STOPPED!(js.j_current) + { + candidate = js.j_current; + } else { + candidate = NO_JOB; + + if js.j_previous != NO_JOB + && !(*jobs.offset(js.j_previous as isize)).is_null() + && STOPPED!(js.j_previous) + { + candidate = js.j_previous; + } + if candidate == NO_JOB { + candidate = job_last_stopped(js.j_jobslots); + } + if candidate == NO_JOB { + candidate = job_last_running(js.j_jobslots); + } + } + if candidate != NO_JOB { + set_current_job(candidate); + } else { + js.j_previous = NO_JOB; + js.j_current = js.j_previous; + }; + } +} + +fn set_job_running(mut job: libc::c_int) { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + unsafe { + p = (**jobs.offset(job as isize)).pipe; + loop { + if WIFSTOPPED!((*p).status) { + (*p).running = PS_RUNNING as libc::c_int; + } + p = (*p).next; + if !(p != (**jobs.offset(job as isize)).pipe) { + break; + } + } + JOBSTATE!(job) = JRUNNING; + } +} + +#[no_mangle] +pub fn start_job(mut job: libc::c_int, mut foreground: libc::c_int) -> libc::c_int { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut already_running: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut wd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + static mut save_stty: libc::termios = libc::termios { + c_iflag: 0, + c_oflag: 0, + c_cflag: 0, + c_lflag: 0, + c_line: 0, + c_cc: [0; 32], + c_ispeed: 0, + c_ospeed: 0, + }; + unsafe { + BLOCK_CHILD(&mut set, &mut oset); + if subshell_environment & SUBSHELL_COMSUB as libc::c_int != 0 && pipeline_pgrp == shell_pgrp + { + internal_error( + b"%s: no current jobs\0" as *const u8 as *const libc::c_char, + this_command_name, + ); + UNBLOCK_CHILD(&mut oset); + return -1; + } + if DEADJOB!(job) { + internal_error( + b"%s: job has terminated\0" as *const u8 as *const libc::c_char, + this_command_name, + ); + UNBLOCK_CHILD(&mut oset); + return -1; + } + already_running = RUNNING!(job) as libc::c_int; + + if foreground == 0 && already_running != 0 { + internal_error( + b"%s: job %d already in background\0" as *const u8 as *const libc::c_char, + this_command_name, + job + 1 as libc::c_int, + ); + UNBLOCK_CHILD(&mut oset); + return 0; + } + + wd = current_working_directory(); + + (**jobs.offset(job as isize)).flags &= !(J_NOTIFIED as libc::c_int); + + if foreground != 0 { + set_current_job(job); + (**jobs.offset(job as isize)).flags |= J_FOREGROUND as libc::c_int; + } + + p = (**jobs.offset(job as isize)).pipe; + + if foreground == 0 { + if posixly_correct == 0 as libc::c_int { + s = (if job == js.j_current { + b"+ \0" as *const u8 as *const libc::c_char + } else if job == js.j_previous { + b"- \0" as *const u8 as *const libc::c_char + } else { + b" \0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + } else { + s = b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + print!( + "[{}]{}", + job + 1 as libc::c_int, + CStr::from_ptr(s).to_str().unwrap() + ); + } + loop { + print!( + "{}{}", + if !((*p).command).is_null() { + let str1 = (*p).command; + CStr::from_ptr(str1).to_str().unwrap() + } else { + let str1 = b"\0" as *const u8 as *const libc::c_char; + CStr::from_ptr(str1).to_str().unwrap() + }, + if (*p).next != (**jobs.offset(job as isize)).pipe { + let str1 = b" | \0" as *const u8 as *const libc::c_char; + CStr::from_ptr(str1).to_str().unwrap() + } else { + let str1 = b"\0" as *const u8 as *const libc::c_char; + CStr::from_ptr(str1).to_str().unwrap() + }, + ); + p = (*p).next; + if !(p != (**jobs.offset(job as isize)).pipe) { + break; + } + } + if foreground == 0 { + print!(" &"); + } + if strcmp(wd, (**jobs.offset(job as isize)).wd) != 0 { + let str1 = polite_directory_format((**jobs.offset(job as isize)).wd); + print!(" (wd:{})", CStr::from_ptr(str1).to_str().unwrap()); + } + print!("\n"); + + if already_running == 0 { + set_job_running(job); + } + if foreground != 0 { + get_tty_state(); + save_stty = shell_tty_info; + if IS_JOBCONTROL!(job) { + give_terminal_to((**jobs.offset(job as isize)).pgrp, 0); + } + } else { + (**jobs.offset(job as isize)).flags &= !(J_FOREGROUND as libc::c_int); + } + if already_running == 0 { + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + killpg((**jobs.offset(job as isize)).pgrp, 18 as libc::c_int); + } + if foreground != 0 { + let mut pid: pid_t = 0; + let mut st: libc::c_int = 0; + + pid = find_last_pid(job, 0 as libc::c_int); + UNBLOCK_CHILD(&mut oset); + st = wait_for(pid, 0); + shell_tty_info = save_stty; + set_tty_state(); + return st; + } else { + reset_current(); + UNBLOCK_CHILD(&mut set); + return 0 as libc::c_int; + }; + } +} + +#[no_mangle] +pub fn kill_pid(mut pid: pid_t, mut sig: libc::c_int, mut group: libc::c_int) -> libc::c_int { + unsafe { + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut job: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut negative: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if pid < -1 { + pid = -pid; + negative = 1; + group = negative; + } else { + negative = 0; + } + result = 0; + if group != 0 { + BLOCK_CHILD(&mut set, &mut oset); + p = find_pipeline(pid, 0, &mut job); + + if job != NO_JOB { + (**jobs.offset(job as isize)).flags &= !(J_NOTIFIED as libc::c_int); + if negative != 0 && (**jobs.offset(job as isize)).pgrp == shell_pgrp { + result = killpg(pid, sig); + } else if (**jobs.offset(job as isize)).pgrp == shell_pgrp { + p = (**jobs.offset(job as isize)).pipe; + loop { + if !(PALIVE!(p) as libc::c_int == 0) { + kill((*p).pid, sig); + if PEXITED!(p) + && (sig == SIGTERM as libc::c_int || sig == SIGHUP as libc::c_int) + { + kill((*p).pid, SIGCONT as libc::c_int); + } + p = (*p).next; + } + if !(p != (**jobs.offset(job as isize)).pipe) { + break; + } + } + } else { + result = killpg((**jobs.offset(job as isize)).pgrp, sig); + if !p.is_null() + && STOPPED!(job) + && (sig == SIGTERM as libc::c_int || sig == SIGHUP as libc::c_int) + { + killpg((**jobs.offset(job as isize)).pgrp, SIGCONT as libc::c_int); + } + if !p.is_null() && STOPPED!(job) && sig == SIGCONT as libc::c_int { + set_job_running(job); + (**jobs.offset(job as isize)).flags &= !(J_FOREGROUND as libc::c_int); + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + } + } + } else { + result = killpg(pid, sig); + } + UNBLOCK_CHILD(&mut oset); + } else { + result = kill(pid, sig); + } + return result; + } +} + +fn sigchld_handler(mut sig: libc::c_int) { + let mut n: libc::c_int = 0; + let mut oerrno: libc::c_int = 0; + unsafe { + oerrno = errno!(); + sigchld += 1; + n = 0; + if queue_sigchld == 0 { + n = waitchld(-1, 0); + } + errno!() = oerrno; + } + return; +} +fn waitchld(mut wpid: pid_t, mut block: libc::c_int) -> libc::c_int { + unsafe { + let mut status: WAIT = 0; + let mut child: *mut PROCESS = 0 as *mut PROCESS; + let mut pid: pid_t = 0; + let mut ind: libc::c_int = 0; + let mut call_set_current: libc::c_int = 0; + let mut last_stopped_job: libc::c_int = 0; + let mut job: libc::c_int = 0; + let mut children_exited: libc::c_int = 0; + let mut waitpid_flags: libc::c_int = 0; + static mut wcontinued: libc::c_int = 8 as libc::c_int; + children_exited = 0 as libc::c_int; + call_set_current = children_exited; + last_stopped_job = -(1 as libc::c_int); + loop { + waitpid_flags = if job_control != 0 && subshell_environment == 0 as libc::c_int { + 2 as libc::c_int | wcontinued + } else { + 0 as libc::c_int + }; + if sigchld != 0 || block == 0 as libc::c_int { + waitpid_flags |= 1 as libc::c_int; + } + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if wait_intr_flag != 0 + && wait_signal_received != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + if block == 1 as libc::c_int + && queue_sigchld == 0 as libc::c_int + && waitpid_flags & 1 as libc::c_int == 0 as libc::c_int + { + internal_warning(dcgettext( + 0 as *const libc::c_char, + b"waitchld: turning on WNOHANG to avoid indefinite block\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + waitpid_flags |= 1 as libc::c_int; + } + pid = waitpid(-(1 as libc::c_int), &mut status, waitpid_flags); + if wcontinued != 0 && pid < 0 as libc::c_int && *__errno_location() == 22 as libc::c_int + { + wcontinued = 0 as libc::c_int; + } else { + if sigchld > 0 as libc::c_int && waitpid_flags & 1 as libc::c_int != 0 { + sigchld -= 1; + } + if pid < 0 as libc::c_int && *__errno_location() == 10 as libc::c_int { + if !(children_exited == 0 as libc::c_int) { + break; + } + return -(1 as libc::c_int); + } else { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if wait_intr_flag != 0 + && wait_signal_received != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + if pid < 0 as libc::c_int + && *__errno_location() == 4 as libc::c_int + && wait_sigint_received != 0 + { + child_caught_sigint = 1 as libc::c_int; + } + if !(pid <= 0 as libc::c_int) { + if wait_sigint_received != 0 + && ((((status & 0x7f as libc::c_int) + 1 as libc::c_int) + as libc::c_schar as libc::c_int + >> 1 as libc::c_int + > 0 as libc::c_int) as libc::c_int + == 0 as libc::c_int + || status & 0x7f as libc::c_int != 2 as libc::c_int) + { + child_caught_sigint = 1 as libc::c_int; + } + if ((status & 0x7f as libc::c_int) + 1 as libc::c_int) as libc::c_schar + as libc::c_int + >> 1 as libc::c_int + > 0 as libc::c_int + && status & 0x7f as libc::c_int == 2 as libc::c_int + { + child_caught_sigint = 0 as libc::c_int; + } + if (status == 0xffff as libc::c_int) as libc::c_int == 0 as libc::c_int { + children_exited += 1; + js.c_living -= 1; + } + child = find_process(pid, 1 as libc::c_int, &mut job); + coproc_pidchk(pid, status); + ind = find_procsub_child(pid); + if ind >= 0 as libc::c_int { + set_procsub_status(ind, pid, status); + } + if child.is_null() { + if status & 0x7f as libc::c_int == 0 as libc::c_int + || ((status & 0x7f as libc::c_int) + 1 as libc::c_int) + as libc::c_schar + as libc::c_int + >> 1 as libc::c_int + > 0 as libc::c_int + { + js.c_reaped += 1; + } + } else { + (*child).status = status; + (*child).running = if status == 0xffff as libc::c_int { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + if (*child).running == 0 as libc::c_int { + js.c_totreaped += 1; + if job != -(1 as libc::c_int) { + js.c_reaped += 1; + } + } + if !(job == -(1 as libc::c_int)) { + call_set_current += set_job_status_and_cleanup(job); + if (**jobs.offset(job as isize)).state as libc::c_int + == JSTOPPED as libc::c_int + { + last_stopped_job = job; + } else if (**jobs.offset(job as isize)).state as libc::c_int + == JDEAD as libc::c_int + && last_stopped_job == job + { + last_stopped_job = -(1 as libc::c_int); + } + } + } + } + } + } + if !((sigchld != 0 || block == 0 as libc::c_int) && pid > 0 as libc::c_int) { + break; + } + } + if call_set_current != 0 { + if last_stopped_job != -(1 as libc::c_int) { + set_current_job(last_stopped_job); + } else { + reset_current(); + } + } + if children_exited != 0 + && (signal_is_trapped(17 as libc::c_int) != 0 + || *trap_list.as_mut_ptr().offset(17 as libc::c_int as isize) + == ::std::mem::transmute::<*mut SigHandler, *mut libc::c_char>( + ::std::mem::transmute:: (), *mut SigHandler>(initialize_traps), + )) + && *trap_list.as_mut_ptr().offset(17 as libc::c_int as isize) + != ::std::mem::transmute::<__sighandler_t, *mut libc::c_char>( + ::std::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ), + ) + { + if posixly_correct != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == Some(wait_builtin) + { + queue_sigchld_trap(children_exited); + wait_signal_received = 17 as libc::c_int; + if sigchld == 0 as libc::c_int && wait_intr_flag != 0 { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + } else if sigchld != 0 { + queue_sigchld_trap(children_exited); + } else if signal_in_progress(17 as libc::c_int) != 0 { + queue_sigchld_trap(children_exited); + } else if *trap_list.as_mut_ptr().offset(17 as libc::c_int as isize) + == ::std::mem::transmute::<*mut SigHandler, *mut libc::c_char>( + ::std::mem::transmute:: (), *mut SigHandler>(initialize_traps), + ) + { + queue_sigchld_trap(children_exited); + } else if running_trap != 0 { + queue_sigchld_trap(children_exited); + } else if this_shell_builtin == Some(wait_builtin) { + run_sigchld_trap(children_exited); + } else { + queue_sigchld_trap(children_exited); + } + } + if asynchronous_notification != 0 + && interactive != 0 + && executing_builtin == 0 as libc::c_int + { + notify_of_job_status(); + } + return children_exited; + } +} + +fn set_job_status_and_cleanup(mut job: libc::c_int) -> libc::c_int { + unsafe { + let mut child: *mut PROCESS = 0 as *mut PROCESS; + let mut tstatus: libc::c_int = 0; + let mut job_state: libc::c_int = 0; + let mut any_stopped: libc::c_int = 0; + let mut any_tstped: libc::c_int = 0; + let mut call_set_current: libc::c_int = 0; + let mut temp_handler: Option; + + child = (**jobs.offset(job as isize)).pipe; + (**jobs.offset(job as isize)).flags &= !(J_NOTIFIED as libc::c_int); + + call_set_current = 0; + + any_tstped = 0; + any_stopped = any_tstped; + job_state = any_stopped; + loop { + job_state |= PRUNNING!(child) as libc::c_int; + if PSTOPPED(child) != 0 { + any_stopped = 1; + any_tstped |= (job_control != 0 + && WSTOPSIG!((*child).status) == SIGTSTP as libc::c_int) + as libc::c_int; + } + child = (*child).next; + if !(child != (**jobs.offset(job as isize)).pipe) { + break; + } + } + + if job_state != 0 && JOBSTATE!(job) != JSTOPPED as libc::c_int { + return 0; + } + + if any_stopped != 0 { + (**jobs.offset(job as isize)).state = JSTOPPED; + (**jobs.offset(job as isize)).flags &= !(J_FOREGROUND as libc::c_int); + call_set_current += 1; + + if any_tstped != 0 && loop_level != 0 { + breaking = loop_level; + } + } else if job_state != 0 { + (**jobs.offset(job as isize)).state = JRUNNING; + call_set_current += 1; + } else { + (**jobs.offset(job as isize)).state = JDEAD; + js.j_ndead += 1; + + if ((**jobs.offset(job as isize)).j_cleanup).is_some() { + (Some( + ((**jobs.offset(job as isize)).j_cleanup).expect("non-null function pointer"), + )) + .expect("non-null function pointer")( + (**jobs.offset(job as isize)).cleanarg + ); + + (**jobs.offset(job as isize)).j_cleanup = ::std::mem::transmute::< + *mut libc::c_void, + sh_vptrfunc_t, + >(0 as *mut libc::c_void); + } + } + if JOBSTATE!(job) == JDEAD as libc::c_int { + if wait_sigint_received != 0 + && interactive_shell == 0 + && child_caught_sigint != 0 + && IS_FOREGROUND!(job) + && signal_is_trapped(SIGINT as libc::c_int) != 0 + { + let mut old_frozen: libc::c_int = 0; + wait_sigint_received = 0; + last_command_exit_value = process_exit_status((*child).status); + + old_frozen = jobs_list_frozen; + jobs_list_frozen = 1; + tstatus = maybe_call_trap_handler(SIGINT as libc::c_int); + jobs_list_frozen = old_frozen; + } else if wait_sigint_received != 0 + && child_caught_sigint == 0 + && IS_FOREGROUND!(job) + && IS_JOBCONTROL!(job) as libc::c_int == 0 + { + let mut old_frozen_0: libc::c_int = 0; + + wait_sigint_received = 0; + + if signal_is_trapped(SIGINT as libc::c_int) != 0 { + last_command_exit_value = process_exit_status((*child).status); + } + old_frozen_0 = jobs_list_frozen; + jobs_list_frozen = 1; + tstatus = maybe_call_trap_handler(SIGINT as libc::c_int); + jobs_list_frozen = old_frozen_0; + if tstatus == 0 && old_sigint_handler != INVALID_SIGNAL_HANDLER!() { + temp_handler = old_sigint_handler; + if temp_handler == Some(trap_handler) + && signal_is_trapped(SIGINT as libc::c_int) == 0 + { + //temp_handler = &mut trap_to_sighandler(SIGINT as libc::c_int); + temp_handler = trap_to_sighandler(2 as libc::c_int); + } + println!("161616161616"); + restore_sigint_handler(); + if !temp_handler.is_none() { + termsig_handler(SIGINT as libc::c_int); + } else if temp_handler != SIG_IGN!() { + //è¿™é‡Œæ˜¯å‡½æ•°å›žè°ƒä¼ å…¥å‚æ•° + //(*temp_handler).unwrap()(SIGINT as libc::c_int); + (Some(temp_handler.expect("non-null function pointer"))) + .expect("non-null function pointer")( + 2 as libc::c_int + ); + } + } + } + } + return call_set_current; + } +} + +fn setjstatus(mut j: libc::c_int) { + unsafe { + let mut i: libc::c_int = 0; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + + i = 1; + p = (**jobs.offset(j as isize)).pipe; + while (*p).next != (**jobs.offset(j as isize)).pipe { + p = (*p).next; + i += 1; + } + i += 1; + if statsize < i { + pstatuses = + libc::realloc(pstatuses as *mut c_void, (i * 4) as usize) as *mut libc::c_int; //i * sizeof (int) + statsize = i; + } + i = 0 as libc::c_int; + p = (**jobs.offset(j as isize)).pipe; + loop { + *pstatuses.offset(i as isize) = process_exit_status((*p).status); + i = i + 1; + p = (*p).next; + if !(p != (**jobs.offset(j as isize)).pipe) { + break; + } + } + + *pstatuses.offset(i as isize) = -1; + set_pipestatus_array(pstatuses, i); + } +} + +#[no_mangle] +pub fn run_sigchld_trap(mut nchild: libc::c_int) { + unsafe { + let mut trap_command: *mut libc::c_char; + let mut i: libc::c_int = 0; + trap_command = savestring!(*trap_list + .as_mut_ptr() + .offset(SIGCHLD as libc::c_int as isize)); + + begin_unwind_frame(b"SIGCHLD trap\0" as *const u8 as *mut libc::c_char); + + unwind_protect_mem( + &mut last_command_exit_value as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut last_command_exit_signal as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut last_made_pid as *mut pid_t as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut jobs_list_frozen as *mut libc::c_int as *mut libc::c_char, + ::std::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut the_pipeline as *mut *mut PROCESS as *mut libc::c_char, + ::std::mem::size_of::<*mut PROCESS>() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut subst_assign_varlist as *mut *mut WordList as *mut libc::c_char, + ::std::mem::size_of::<*mut WordList>() as libc::c_ulong as libc::c_int, + ); + // unsafe { + // unwind_protect_mem( + // &mut this_shell_builtin as *const sh_builtin_func_t as *mut libc::c_char, + // ::std::mem::size_of::>() as libc::c_ulong as libc::c_int, + // ); + // } + unwind_protect_mem( + &mut this_shell_builtin as *mut Option as *mut libc::c_char, + ::core::mem::size_of::>() as libc::c_ulong as libc::c_int, + ); + unwind_protect_mem( + &mut temporary_env as *mut *mut HASH_TABLE as *mut libc::c_char, + ::std::mem::size_of::<*mut HASH_TABLE>() as libc::c_ulong as libc::c_int, + ); + + extern "C" { + pub fn xfree(arg1: *mut ::std::os::raw::c_void); + } + + add_unwind_protect( + std::mem::transmute::>(free), + trap_command, + ); + add_unwind_protect( + std::mem::transmute::>(maybe_set_sigchld_trap), + trap_command, + ); + + subst_assign_varlist = 0 as *mut WordList; + the_pipeline = 0 as *mut PROCESS; + temporary_env = 0 as *mut HASH_TABLE; + + running_trap = SIGCHLD as libc::c_int + 1; + + set_impossible_sigchld_trap(); + jobs_list_frozen = 1; + i = 0; + while i < nchild { + parse_and_execute( + savestring!(trap_command), + b"trap\0" as *const u8 as *const libc::c_char, + SEVAL_NOHIST | SEVAL_RESETLINE, + ); + i += 1; + } + run_unwind_frame( + b"SIGCHLD trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + running_trap = 0 as libc::c_int; + } +} + +fn notify_of_job_status() { + unsafe { + let mut job: libc::c_int = 0; + let mut termsig: libc::c_int = 0; + let mut dir: *mut libc::c_char = 0 as *mut libc::c_char; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut s: WAIT = 0; + + if jobs.is_null() || js.j_jobslots == 0 { + return; + } + if old_ttou.is_some() { + sigemptyset(&mut set); + sigaddset(&mut set, SIGCHLD as libc::c_int); + sigaddset(&mut set, SIGTTOU as libc::c_int); + sigemptyset(&mut oset); + sigprocmask(SIG_BLOCK as libc::c_int, &mut set, &mut oset); + } else { + queue_sigchld += 1; + } + job = 0; + dir = 0 as *mut libc::c_char; + while job < js.j_jobslots { + if !(*jobs.offset(job as isize)).is_null() && IS_NOTIFIED!(job) as libc::c_int == 0 { + s = raw_job_exit_status(job); + termsig = WTERMSIG!(s); + + if !(startup_state == 0 + && WIFSIGNALED!(s) as libc::c_int == 0 + && (DEADJOB!(job) && IS_FOREGROUND!(job) as libc::c_int == 0 || STOPPED!(job))) + { + if job_control == 0 && interactive_shell != 0 + || startup_state == 2 + && subshell_environment & SUBSHELL_COMSUB as libc::c_int != 0 + || startup_state == 2 + && posixly_correct != 0 + && subshell_environment & SUBSHELL_COMSUB as libc::c_int + == 0 as libc::c_int + { + if (DEADJOB!(job) + && (interactive_shell != 0 + || find_last_pid(job, 0) != last_asynchronous_pid)) + { + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + } + } else { + match (**jobs.offset(job as isize)).state as libc::c_int { + JDEAD => { + if interactive_shell == 0 + && termsig != 0 + && WIFSIGNALED!(s) + && termsig != SIGINT as libc::c_int + && termsig != SIGTERM as libc::c_int + && signal_is_trapped(termsig) == 0 + { + fprintf( + stderr, + b"%s: line %d: \0" as *const u8 as *const libc::c_char, + get_name_for_error(), + if line_number == 0 { 1 } else { line_number }, + ); + pretty_print_job( + job, + JLIST_NONINTERACTIVE as libc::c_int, + stderr, + ); + } else if IS_FOREGROUND!(job) { + if termsig != 0 + && WIFSIGNALED!(s) + && termsig != SIGINT as libc::c_int + && termsig != SIGPIPE as libc::c_int + { + fprintf( + stderr, + b"%s\0" as *const u8 as *const libc::c_char, + j_strsignal(termsig), + ); + if WIFCORED!(s) { + fprintf( + stderr, + b" (core dumped)\0" as *const u8 + as *const libc::c_char, + ); + } + fprintf( + stderr, + b"\n\0" as *const u8 as *const libc::c_char, + ); + } + } else if job_control != 0 { + if dir.is_null() { + dir = current_working_directory(); + } + pretty_print_job(job, JLIST_STANDARD as libc::c_int, stderr); + if !dir.is_null() + && strcmp(dir, (**jobs.offset(job as isize)).wd) != 0 + { + fprintf( + stderr, + b"(wd now: %s)\n\0" as *const u8 as *const libc::c_char, + polite_directory_format(dir), + ); + } + } + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + } + JSTOPPED => { + fprintf(stderr, b"\n\0" as *const u8 as *const libc::c_char); + if dir.is_null() { + dir = current_working_directory(); + } + pretty_print_job(job, JLIST_STANDARD as libc::c_int, stderr); + if !dir.is_null() + && strcmp(dir, (**jobs.offset(job as isize)).wd) != 0 + { + fprintf( + stderr, + b"(wd now: %s)\n\0" as *const u8 as *const libc::c_char, + polite_directory_format(dir), + ); + } + (**jobs.offset(job as isize)).flags |= J_NOTIFIED as libc::c_int; + } + JRUNNING | JMIXED => {} + _ => { + programming_error( + b"notify_of_job_status\0" as *const u8 as *const libc::c_char, + ); + } + } + } + } + } + job += 1; + } + if old_ttou.is_some() { + sigprocmask( + SIG_SETMASK as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + } else { + queue_sigchld -= 1; + }; + } +} + +#[no_mangle] +pub fn initialize_job_control(mut force: libc::c_int) -> libc::c_int { + unsafe { + let mut current_block: u64; + let mut t: pid_t = 0; + let mut t_errno: libc::c_int = 0; + let mut tty_sigs: libc::c_int = 0; + + t_errno = -(1 as libc::c_int); + shell_pgrp = getpgid(0); + + if shell_pgrp == -(1 as libc::c_int) { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"initialize_job_control: getpgrp failed\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + exit(1 as libc::c_int); + } + + if interactive == 0 as libc::c_int && force == 0 as libc::c_int { + job_control = 0 as libc::c_int; + original_pgrp = -(1 as libc::c_int); + shell_tty = fileno(stderr); + terminal_pgrp = tcgetpgrp(shell_tty); + } else { + shell_tty = -(1 as libc::c_int); + if forced_interactive != 0 && isatty(fileno(stderr)) == 0 as libc::c_int { + shell_tty = open( + b"/dev/tty\0" as *const u8 as *const libc::c_char, + 0o2 as libc::c_int | 0o4000 as libc::c_int, + ); + } + if shell_tty == -(1 as libc::c_int) { + shell_tty = dup(fileno(stderr)); + } + if shell_tty != -(1 as libc::c_int) { + shell_tty = move_to_high_fd(shell_tty, 1 as libc::c_int, -(1 as libc::c_int)); + } + if shell_pgrp == 0 as libc::c_int { + shell_pgrp = getpid(); + setpgid(0 as libc::c_int, shell_pgrp); + if shell_tty != -(1 as libc::c_int) { + tcsetpgrp(shell_tty, shell_pgrp); + } + } + tty_sigs = 0 as libc::c_int; + loop { + terminal_pgrp = tcgetpgrp(shell_tty); + if !(terminal_pgrp != -(1 as libc::c_int)) { + current_block = 5529461102203738653; + break; + } + if !(shell_pgrp != terminal_pgrp) { + current_block = 5529461102203738653; + break; + } + //let mut ottin: *mut SigHandler; + let mut ottin: Option = None; + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + ottin = set_signal_handler(21 as libc::c_int, None); + kill(0 as libc::c_int, 21 as libc::c_int); + set_signal_handler(21 as libc::c_int, ottin); + let fresh35 = tty_sigs; + tty_sigs = tty_sigs + 1; + if !(fresh35 > 16 as libc::c_int) { + continue; + } + sys_error(dcgettext( + 0 as *const libc::c_char, + b"initialize_job_control: no job control in background\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + job_control = 0 as libc::c_int; + original_pgrp = terminal_pgrp; + current_block = 16073591882049499585; + break; + } + match current_block { + 16073591882049499585 => {} + _ => { + if terminal_pgrp == -(1 as libc::c_int) { + t_errno = *__errno_location(); + } + if set_new_line_discipline(shell_tty) < 0 as libc::c_int { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"initialize_job_control: line discipline\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + job_control = 0 as libc::c_int; + } else { + original_pgrp = shell_pgrp; + shell_pgrp = getpid(); + if original_pgrp != shell_pgrp + && setpgid(0 as libc::c_int, shell_pgrp) < 0 as libc::c_int + { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"initialize_job_control: setpgid\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + shell_pgrp = original_pgrp; + } + job_control = 1 as libc::c_int; + if shell_pgrp != original_pgrp && shell_pgrp != terminal_pgrp { + if give_terminal_to(shell_pgrp, 0 as libc::c_int) < 0 as libc::c_int { + t_errno = *__errno_location(); + setpgid(0 as libc::c_int, original_pgrp); + shell_pgrp = original_pgrp; + *__errno_location() = t_errno; + sys_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot set terminal process group (%d)\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + shell_pgrp, + ); + job_control = 0 as libc::c_int; + } + } + if job_control != 0 && { + t = tcgetpgrp(shell_tty); + t == -(1 as libc::c_int) || t != shell_pgrp + } { + if t_errno != -(1 as libc::c_int) { + *__errno_location() = t_errno; + } + sys_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot set terminal process group (%d)\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + t, + ); + job_control = 0 as libc::c_int; + } + } + if job_control == 0 as libc::c_int { + internal_error(dcgettext( + 0 as *const libc::c_char, + b"no job control in this shell\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + } + } + } + } + running_in_background = (terminal_pgrp != shell_pgrp) as libc::c_int; + if shell_tty != fileno(stderr) { + fcntl(shell_tty, 2 as libc::c_int, 1 as libc::c_int); + } + set_signal_handler( + 17 as libc::c_int, + //sigchld_handler as *mut Option, + std::mem::transmute(sigchld_handler as usize), + ); + change_flag( + 'm' as i32, + if job_control != 0 { + '-' as i32 + } else { + '+' as i32 + }, + ); + if interactive != 0 { + get_tty_state(); + } + set_maxchild(0 as libc::c_int); + return job_control; + } +} + +fn set_new_line_discipline(mut tty: libc::c_int) -> libc::c_int { + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn initialize_job_signals() { + unsafe { + if interactive != 0 { + set_signal_handler( + 2 as libc::c_int, + std::mem::transmute(sigint_sighandler as usize), + ); + set_signal_handler(SIGTSTP as libc::c_int, SIG_IGN!()); + set_signal_handler(SIGTTOU as libc::c_int, SIG_IGN!()); + set_signal_handler(SIGTTIN as libc::c_int, SIG_IGN!()); + } else if job_control != 0 { + old_tstp = set_signal_handler(SIGTSTP as libc::c_int, Some(sigstop_sighandler)); + old_ttin = set_signal_handler(SIGTTIN as libc::c_int, Some(sigstop_sighandler)); + old_ttou = set_signal_handler(SIGTTOU as libc::c_int, Some(sigstop_sighandler)); + } + } +} + +fn sigcont_sighandler(mut sig: libc::c_int) { + unsafe { + initialize_job_signals(); + set_signal_handler(SIGCONT as libc::c_int, old_cont); + kill(getpid(), SIGCONT as libc::c_int); + } +} +fn sigstop_sighandler(mut sig: libc::c_int) { + unsafe { + set_signal_handler(SIGTSTP as libc::c_int, old_tstp); + set_signal_handler(SIGTTOU as libc::c_int, old_ttou); + set_signal_handler(SIGTTIN as libc::c_int, old_ttin); + old_cont = set_signal_handler( + SIGCONT as libc::c_int, + ::core::mem::transmute:: ()>, Option>(Some( + ::core::mem::transmute:: (), fn() -> ()>(sigcont_sighandler), + )), + ); + give_terminal_to(shell_pgrp, 0); + kill(getpid(), sig); + } +} + +#[no_mangle] +pub fn give_terminal_to(mut pgrp: pid_t, mut force: libc::c_int) -> libc::c_int { + unsafe { + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + let mut r: libc::c_int = 0; + let mut e: libc::c_int = 0; + + if job_control != 0 || force != 0 { + sigemptyset(&mut set); + sigaddset(&mut set, SIGTTOU as libc::c_int); + sigaddset(&mut set, SIGTTIN as libc::c_int); + sigaddset(&mut set, SIGTSTP as libc::c_int); + sigaddset(&mut set, SIGCHLD as libc::c_int); + sigemptyset(&mut oset); + sigprocmask(SIG_BLOCK as libc::c_int, &mut set, &mut oset); + + if tcsetpgrp(shell_tty, pgrp) < 0 { + r = -1; + e = errno!(); + } else { + terminal_pgrp = pgrp; + } + sigprocmask(SIG_SETMASK as libc::c_int, &mut oset, 0 as *mut sigset_t); + } + if r == -1 { + errno!() = e; + } + return r; + } +} + +fn maybe_give_terminal_to( + mut opgrp: pid_t, + mut npgrp: pid_t, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut tpgrp: libc::c_int = 0; + + tpgrp = tcgetpgrp(shell_tty); + if tpgrp < 0 && errno!() == ENOTTY { + return -1; + } + if tpgrp == npgrp { + terminal_pgrp = npgrp; + return 0; + } else if tpgrp != opgrp { + return -1; + } else { + return give_terminal_to(npgrp, flags); + }; + } +} + +#[no_mangle] +pub fn delete_all_jobs(mut running_only: libc::c_int) { + unsafe { + let mut i: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + if js.j_jobslots != 0 { + js.j_previous = NO_JOB; + js.j_current = js.j_previous; + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() + && (running_only == 0 || running_only != 0 && RUNNING!(i)) + { + delete_job( + i, + DEL_WARNSTOPPED as libc::c_int | DEL_NOBGPID as libc::c_int, + ); + } + i += 1; + } + if running_only == 0 { + libc::free(jobs as *mut c_void); + + js.j_jobslots = 0; + js.j_njobs = 0; + js.j_lastj = js.j_njobs; + js.j_firstj = js.j_lastj; + } + } + if running_only == 0 { + bgp_clear(); + } + UNBLOCK_CHILD(&mut oset); + } +} + +#[no_mangle] +pub fn nohup_all_jobs(mut running_only: libc::c_int) { + unsafe { + let mut i: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + if js.j_jobslots != 0 { + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() + && (running_only == 0 || running_only != 0 && RUNNING!(i)) + { + nohup_job(i); + } + i += 1; + } + } + UNBLOCK_CHILD(&mut oset); + } +} + +#[no_mangle] +pub fn count_all_jobs() -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + BLOCK_CHILD(&mut set, &mut oset); + n = 0; + i = n; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() + && DEADJOB!(i) as libc::c_int == 0 as libc::c_int + { + n += 1; + } + i += 1; + } + UNBLOCK_CHILD(&mut oset); + return n; + } +} + +fn mark_all_jobs_as_dead() { + unsafe { + let mut i: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if js.j_jobslots == 0 { + return; + } + BLOCK_CHILD(&mut set, &mut oset); + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() { + (**jobs.offset(i as isize)).state = JDEAD; + js.j_ndead += 1; + } + i += 1; + } + UNBLOCK_CHILD(&mut oset); + } +} + +fn mark_dead_jobs_as_notified(mut force: libc::c_int) { + unsafe { + let mut i: libc::c_int = 0; + let mut ndead: libc::c_int = 0; + let mut ndeadproc: libc::c_int = 0; + let mut set: sigset_t = __sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = __sigset_t { __val: [0; 16] }; + + if js.j_jobslots == 0 { + return; + } + BLOCK_CHILD(&mut set, &mut oset); + if force != 0 { + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() + && DEADJOB!(i) + && (interactive_shell != 0 + || find_last_pid(i, 0 as libc::c_int) != last_asynchronous_pid) + { + (**jobs.offset(i as isize)).flags |= J_NOTIFIED as libc::c_int; + } + i += 1; + } + UNBLOCK_CHILD(&mut oset); + return; + } + ndeadproc = 0; + ndead = ndeadproc; + i = ndead; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() && DEADJOB!(i) { + ndead += 1; + ndeadproc += processes_in_job(i); + } + i += 1; + } + if js.c_childmax < 0 { + set_maxchild(0); + } + if ndeadproc as libc::c_long <= js.c_childmax { + UNBLOCK_CHILD(&mut oset); + return; + } + i = 0; + while i < js.j_jobslots { + if !(*jobs.offset(i as isize)).is_null() + && DEADJOB!(i) + && (interactive_shell != 0 + || find_last_pid(i, 0 as libc::c_int) != last_asynchronous_pid) + { + ndeadproc -= processes_in_job(i); + if ndeadproc as libc::c_long <= js.c_childmax { + break; + } + (**jobs.offset(i as isize)).flags |= J_NOTIFIED as libc::c_int; + } + i += 1; + } + UNBLOCK_CHILD(&mut oset); + } +} + +#[no_mangle] +pub fn freeze_jobs_list() -> libc::c_int { + unsafe { + let mut o: libc::c_int = 0; + + o = jobs_list_frozen; + jobs_list_frozen = 1; + return o; + } +} + +#[no_mangle] +pub fn unfreeze_jobs_list() { + unsafe { + jobs_list_frozen = 0; + } +} + +#[no_mangle] +pub fn set_jobs_list_frozen(mut s: libc::c_int) { + unsafe { + jobs_list_frozen = s; + } +} + +#[no_mangle] +pub fn set_job_control(mut arg: libc::c_int) -> libc::c_int { + unsafe { + let mut old: libc::c_int = 0; + + old = job_control; + job_control = arg; + + if terminal_pgrp == NO_PID as libc::c_int { + terminal_pgrp = tcgetpgrp(shell_tty); + } + if job_control != old && job_control != 0 { + shell_pgrp = getpgid(0); + } + running_in_background = (terminal_pgrp != shell_pgrp) as libc::c_int; + + if job_control != old && job_control != 0 { + pipeline_pgrp = 0; + } + return old; + } +} + +#[no_mangle] +pub fn without_job_control() { + unsafe { + stop_making_children(); + start_pipeline(); + sh_closepipe(pgrp_pipe.as_mut_ptr()); + delete_all_jobs(0); + set_job_control(0); + } +} +#[no_mangle] +pub fn end_job_control() { + unsafe { + if job_control != 0 { + terminate_stopped_jobs(); + } + if original_pgrp >= 0 as libc::c_int && terminal_pgrp != original_pgrp { + give_terminal_to(original_pgrp, 1); + } + if original_pgrp >= 0 && setpgid(0, original_pgrp) == 0 { + shell_pgrp = original_pgrp; + } + } +} +#[no_mangle] +pub fn restart_job_control() { + unsafe { + if shell_tty != -1 { + libc::close(shell_tty); + } + } + initialize_job_control(0); +} + +#[no_mangle] +pub fn set_maxchild(mut nchild: libc::c_int) { + static mut lmaxchild: libc::c_int = -1; + unsafe { + if lmaxchild < 0 { + errno!() = 0; + lmaxchild = getmaxchild() as libc::c_int; + if lmaxchild < 0 && *__errno_location() == 0 { + lmaxchild = MAX_CHILD_MAX as libc::c_int; + } + } + if lmaxchild < 0 { + lmaxchild = DEFAULT_CHILD_MAX as libc::c_int; + } + if nchild < lmaxchild { + nchild = lmaxchild; + } else if nchild > MAX_CHILD_MAX as libc::c_int { + nchild = MAX_CHILD_MAX as libc::c_int; + } + js.c_childmax = nchild as libc::c_long; + } +} + +#[no_mangle] +pub fn set_sigchld_handler() { + unsafe { + set_signal_handler( + SIGCHLD as libc::c_int, + ::core::mem::transmute:: ()>, Option>(Some( + ::core::mem::transmute:: (), fn() -> ()>(sigchld_handler), + )), + ); + } +} + +fn pipe_read(mut pp: *mut libc::c_int) { + let mut ch: libc::c_char = 0; + unsafe { + if *pp.offset(1 as isize) >= 0 { + libc::close(*pp.offset(1 as libc::c_int as isize)); + *pp.offset(1 as isize) = -(1 as libc::c_int); + } + if *pp.offset(0 as libc::c_int as isize) >= 0 { + while libc::read( + *pp.offset(0 as libc::c_int as isize), + &mut ch as *mut libc::c_char as *mut libc::c_void, + 1, + ) == -1 + && errno!() == EINTR as libc::c_int + {} + } + } +} + +#[no_mangle] +pub fn close_pgrp_pipe() { + unsafe { + sh_closepipe(pgrp_pipe.as_mut_ptr()); + } +} + +#[no_mangle] +pub fn save_pgrp_pipe(mut p: *mut libc::c_int, mut clear: libc::c_int) { + unsafe { + *p.offset(0 as libc::c_int as isize) = pgrp_pipe[0 as libc::c_int as usize]; + *p.offset(1 as libc::c_int as isize) = pgrp_pipe[1 as libc::c_int as usize]; + if clear != 0 { + pgrp_pipe[1] = -1; + pgrp_pipe[0] = pgrp_pipe[1]; + } + } +} +#[no_mangle] +pub fn restore_pgrp_pipe(mut p: *mut libc::c_int) { + unsafe { + pgrp_pipe[0] = *p.offset(0); + pgrp_pipe[1] = *p.offset(1 as libc::c_int as isize); + } +} diff --git a/utshell-0.5.0/src/lib.rs b/utshell-0.5.0/src/lib.rs new file mode 100644 index 00000000..3efe91c4 --- /dev/null +++ b/utshell-0.5.0/src/lib.rs @@ -0,0 +1,106 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +extern crate lazy_static; +#[warn(unused_unsafe)] +#[macro_use] + +pub mod src_common; +pub mod alias; +pub mod array; +pub mod arrayfunc; +pub mod assoc; +pub mod bashhist; +pub mod bashline; +pub mod brace; +pub mod bracecomp; +pub mod copycmd; +pub mod dispose_cmd; +pub mod error; +pub mod eval; +pub mod execute_cmd; +pub mod expr; +pub mod findcmd; +pub mod flags; +pub mod general; +pub mod hashcmd; +pub mod hashlib; +pub mod input; +pub mod jobs; +pub mod list; +pub mod local; +pub mod mailcheck; +pub mod make_cmd; +pub mod pathexp; +pub mod pcomplete; +pub mod pcomplib; +pub mod print_cmd; +pub mod readline; +pub mod redir; +pub mod sig; +pub mod stringlib; +pub mod subst; +pub mod syntax; +pub mod test; +pub mod trap; +pub mod unwind_prot; +pub mod utshell; +pub mod variables; +pub mod version; +pub mod y_tab; + +pub mod builtins { + pub mod alias; + pub mod bashgetopt; + pub mod bind; + pub mod break_1; + pub mod builtin; + pub mod builtins; + pub mod caller; + pub mod cd; + pub mod cmd; + pub mod colon; + pub mod command; + pub mod common; + pub mod complete; + pub mod declare; + pub mod echo; + pub mod enable; + pub mod eval; + pub mod evalfile; + pub mod evalstring; + pub mod exec; + pub mod exec_cmd; + pub mod exit; + pub mod fc; + pub mod fg_bg; + pub mod getopt; + pub mod getopts; + pub mod hash; + pub mod help; + pub mod history; + pub mod jobs; + pub mod kill; + pub mod let_1; + pub mod mapfile; + pub mod printf; + pub mod pushd; + pub mod read; + pub mod return_1; + pub mod set; + pub mod setattr; + pub mod shift; + pub mod shopt; + pub mod signal; + pub mod source; + pub mod suspend; + pub mod test; + pub mod times; + pub mod trap; + pub mod type_1; + pub mod ulimit; + pub mod umask; + pub mod wait; +} diff --git a/utshell-0.5.0/src/list.rs b/utshell-0.5.0/src/list.rs new file mode 100644 index 00000000..f70fc695 --- /dev/null +++ b/utshell-0.5.0/src/list.rs @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; + +#[no_mangle] +pub fn list_reverse(mut list: *mut GENERIC_LIST) -> *mut GENERIC_LIST { + unsafe { + let mut next: *mut GENERIC_LIST; + let mut prev: *mut GENERIC_LIST; + prev = 0 as *mut libc::c_void as *mut GENERIC_LIST; + + while !list.is_null() { + next = (*list).next; + (*list).next = prev; + prev = list; + list = next; + } + return prev; + } +} +#[no_mangle] +pub fn list_length(mut list: *mut GENERIC_LIST) -> libc::c_int { + let mut i: libc::c_int = 0; + + while !list.is_null() { + list = unsafe { (*list).next }; + i += 1; + } + return i; +} +#[no_mangle] +pub fn list_append(head: *mut GENERIC_LIST, tail: *mut GENERIC_LIST) -> *mut GENERIC_LIST { + let mut t_head: *mut GENERIC_LIST; + if head.is_null() { + return tail; + } + t_head = head; + unsafe { + while !((*t_head).next).is_null() { + t_head = (*t_head).next; + } + (*t_head).next = tail; + } + return head; +} diff --git a/utshell-0.5.0/src/local.rs b/utshell-0.5.0/src/local.rs new file mode 100644 index 00000000..74487757 --- /dev/null +++ b/utshell-0.5.0/src/local.rs @@ -0,0 +1,630 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common; +use crate::src_common::*; +use crate::variables::maybe_make_export_env; +use crate::y_tab::yy_input_name; + +#[no_mangle] +pub fn set_default_locale() { + unsafe { + default_locale = setlocale(LC_ALL, b"\0" as *const u8 as *const libc::c_char); + bindtextdomain(STR_PACKAGE, STR_LOCALEDIR); + textdomain(STR_PACKAGE); + locale_mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + locale_utf8locale = locale_isutf8(default_locale); + locale_shiftstates = mblen(0 as *mut libc::c_void as *mut libc::c_char, 0); + } +} + +#[no_mangle] +pub fn set_default_locale_vars() { + let mut val: *mut libc::c_char; + unsafe { + val = get_string_value(STR_LC_CTYPE); + if val.is_null() && !lc_all.is_null() && *lc_all as libc::c_int != 0 { + setlocale(0 as libc::c_int, lc_all); + locale_setblanks(); + locale_mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + locale_utf8locale = locale_isutf8(lc_all); + locale_shiftstates = mblen(0 as *mut libc::c_void as *mut libc::c_char, 0); + u32reset(); + } + val = get_string_value(STR_LC_COLLATE); + if val.is_null() && !lc_all.is_null() && *lc_all as libc::c_int != 0 { + setlocale(3 as libc::c_int, lc_all); + } + val = get_string_value(STR_LC_MESSAGES); + if val.is_null() && !lc_all.is_null() && *lc_all as libc::c_int != 0 { + setlocale(5 as libc::c_int, lc_all); + } + val = get_string_value(STR_LC_NUMERIC); + if val.is_null() && !lc_all.is_null() && *lc_all as libc::c_int != 0 { + setlocale(1 as libc::c_int, lc_all); + } + val = get_string_value(STR_LC_TIME); + if val.is_null() && !lc_all.is_null() && *lc_all as libc::c_int != 0 { + setlocale(2 as libc::c_int, lc_all); + } + val = get_string_value(STR_TEXTDOMAIN); + if !val.is_null() && *val as libc::c_int != 0 { + if !default_domain.is_null() { + free(default_domain as *mut libc::c_void); + } + default_domain = 0 as *mut libc::c_char; + default_domain = savestring!(val); + if !default_dir.is_null() && *default_dir as libc::c_int != 0 { + bindtextdomain(default_domain, default_dir); + } + } + val = get_string_value(STR_TEXTDOMAINDIR); + if !val.is_null() && *val as libc::c_int != 0 { + if !default_dir.is_null() { + free(default_dir as *mut libc::c_void); + } + default_dir = 0 as *mut libc::c_char; + default_dir = savestring!(val); + if !default_domain.is_null() && *default_domain as libc::c_int != 0 { + bindtextdomain(default_domain, default_dir); + } + } + } +} + +#[no_mangle] +pub fn set_locale_var(var: *mut libc::c_char, value: *mut libc::c_char) -> libc::c_int { + let r: libc::c_int; + let mut x: *mut libc::c_char; + x = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + unsafe { + *__errno_location() = 0 as libc::c_int; + if *var.offset(0 as libc::c_int as isize) as libc::c_int == 'T' as i32 + && *var.offset(10 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + if !default_domain.is_null() { + free(default_domain as *mut libc::c_void); + } + default_domain = 0 as *mut libc::c_char; + default_domain = if !value.is_null() { + savestring!(value) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !default_dir.is_null() && *default_dir as libc::c_int != 0 { + bindtextdomain(default_domain, default_dir); + } + return 1 as libc::c_int; + } else if *var.offset(0 as libc::c_int as isize) as libc::c_int == 'T' as i32 { + if !default_dir.is_null() { + free(default_dir as *mut libc::c_void); + } + default_dir = 0 as *mut libc::c_char; + default_dir = if !value.is_null() { + savestring!(value) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !default_domain.is_null() && *default_domain as libc::c_int != 0 { + bindtextdomain(default_domain, default_dir); + } + return 1 as libc::c_int; + } else if *var.offset(3 as libc::c_int as isize) as libc::c_int == 'A' as i32 { + if !lc_all.is_null() { + free(lc_all as *mut libc::c_void); + } + lc_all = 0 as *mut libc::c_char; + if !value.is_null() { + lc_all = savestring!(value); + } else { + lc_all = malloc(1 as libc::c_int as libc::size_t) as *mut libc::c_char; + *lc_all.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + r = if *lc_all as libc::c_int != 0 { + x = setlocale(6 as libc::c_int, lc_all); + (x != 0 as *mut libc::c_char) as libc::c_int + } else { + reset_locale_vars() + }; + if x.is_null() { + if *__errno_location() == 0 as libc::c_int { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"setlocale: LC_ALL: cannot change locale (%s)\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + lc_all, + ); + } else { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"setlocale: LC_ALL: cannot change locale (%s): %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + lc_all, + strerror(*__errno_location()), + ); + } + } + locale_setblanks(); + locale_mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + if *lc_all as libc::c_int != 0 && !x.is_null() { + locale_utf8locale = locale_isutf8(lc_all); + } + locale_shiftstates = mblen(0 as *mut libc::c_void as *mut libc::c_char, 0); + u32reset(); + return r; + } else if *var.offset(3 as libc::c_int as isize) as libc::c_int == 'C' as i32 + && *var.offset(4 as libc::c_int as isize) as libc::c_int == 'T' as i32 + { + /* LC_CTYPE */ + if lc_all.is_null() || *lc_all as libc::c_int == '\0' as i32 { + x = setlocale( + 0 as libc::c_int, + get_locale_var( + STR_LC_CTYPE as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + locale_setblanks(); + locale_mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + if !x.is_null() { + locale_utf8locale = locale_isutf8(x); + } + locale_shiftstates = mblen( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int as size_t, + ); + u32reset(); + } + } else if *var.offset(3 as libc::c_int as isize) as libc::c_int == 'C' as i32 + && *var.offset(4 as libc::c_int as isize) as libc::c_int == 'O' as i32 + { + /* LC_COLLATE */ + if lc_all.is_null() || *lc_all as libc::c_int == '\0' as i32 { + x = setlocale( + 3 as libc::c_int, + get_locale_var( + b"LC_COLLATE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + } + } else if *var.offset(3 as libc::c_int as isize) as libc::c_int == 'M' as i32 + && *var.offset(4 as libc::c_int as isize) as libc::c_int == 'E' as i32 + { + /* LC_MESSAGES */ + if lc_all.is_null() || *lc_all as libc::c_int == '\0' as i32 { + x = setlocale( + 5 as libc::c_int, + get_locale_var( + b"LC_MESSAGES\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + } + } else if *var.offset(3 as libc::c_int as isize) as libc::c_int == 'N' as i32 + && *var.offset(4 as libc::c_int as isize) as libc::c_int == 'U' as i32 + { + /* LC_NUMERIC */ + if lc_all.is_null() || *lc_all as libc::c_int == '\0' as i32 { + x = setlocale( + 1 as libc::c_int, + get_locale_var( + b"LC_NUMERIC\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + } + } else if *var.offset(3 as libc::c_int as isize) as libc::c_int == 'T' as i32 + && *var.offset(4 as libc::c_int as isize) as libc::c_int == 'I' as i32 + { + /* LC_TIME */ + + if lc_all.is_null() || *lc_all as libc::c_int == '\0' as i32 { + x = setlocale( + 2 as libc::c_int, + get_locale_var( + b"LC_TIME\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + } + } + if x.is_null() { + if *__errno_location() == 0 as libc::c_int { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"setlocale: %s: cannot change locale (%s)\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + var, + get_locale_var(var), + ); + } else { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"setlocale: %s: cannot change locale (%s): %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + var, + get_locale_var(var), + strerror(*__errno_location()), + ); + } + } + } + return (x != 0 as *mut libc::c_char) as libc::c_int; +} +#[no_mangle] +pub fn set_lang(mut _var: *mut libc::c_char, value: *mut libc::c_char) -> libc::c_int { + unsafe { + if !lang.is_null() { + free(lang as *mut libc::c_void); + } + lang = 0 as *mut libc::c_char; + if !value.is_null() { + lang = savestring!(value); + } else { + lang = malloc(1 as libc::c_int as libc::size_t) as *mut libc::c_char; + *lang.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + return if lc_all.is_null() || *lc_all as libc::c_int == 0 as libc::c_int { + reset_locale_vars() + } else { + 0 as libc::c_int + }; + } +} +#[no_mangle] +pub fn set_default_lang() { + let mut v: *mut libc::c_char; + unsafe { + v = get_string_value(b"LC_ALL\0" as *const u8 as *const libc::c_char); + set_locale_var( + b"LC_ALL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + v, + ); + v = get_string_value(b"LANG\0" as *const u8 as *const libc::c_char); + set_lang( + b"LANG\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + v, + ); + } +} +#[no_mangle] +pub fn get_locale_var(var: *mut libc::c_char) -> *mut libc::c_char { + let mut locale: *mut libc::c_char; + unsafe { + locale = lc_all; + if locale.is_null() || *locale as libc::c_int == 0 as libc::c_int { + locale = get_string_value(var); + } + if locale.is_null() || *locale as libc::c_int == 0 as libc::c_int { + locale = lang; + } + if locale.is_null() || *locale as libc::c_int == 0 as libc::c_int { + locale = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + } + return locale; +} +fn reset_locale_vars() -> libc::c_int { + let x: *mut libc::c_char; + unsafe { + if lang.is_null() || *lang as libc::c_int == '\0' as i32 { + maybe_make_export_env(); + } + if (setlocale( + 6 as libc::c_int, + if !lang.is_null() { + lang as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + )) + .is_null() + { + return 0 as libc::c_int; + } + // x = 0 as *mut libc::c_char; + x = setlocale( + 0 as libc::c_int, + get_locale_var(b"LC_CTYPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char), + ); + setlocale( + 3 as libc::c_int, + get_locale_var( + b"LC_COLLATE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + setlocale( + 5 as libc::c_int, + get_locale_var( + b"LC_MESSAGES\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + setlocale( + 1 as libc::c_int, + get_locale_var( + b"LC_NUMERIC\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ), + ); + setlocale( + 2 as libc::c_int, + get_locale_var(b"LC_TIME\0" as *const u8 as *const libc::c_char as *mut libc::c_char), + ); + locale_setblanks(); + locale_mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + if !x.is_null() { + locale_utf8locale = locale_isutf8(x); + } + locale_shiftstates = mblen(0 as *mut libc::c_void as *mut libc::c_char, 0); + u32reset(); + } + return 1 as libc::c_int; +} + +#[no_mangle] +pub fn localetrans( + string: *mut libc::c_char, + len: libc::c_int, + lenp: *mut libc::c_int, +) -> *mut libc::c_char { + let locale: *mut libc::c_char; + let t: *mut libc::c_char; + let translated: *mut libc::c_char; + let tlen: libc::c_int; + unsafe { + if string.is_null() || *string as libc::c_int == 0 as libc::c_int { + if !lenp.is_null() { + *lenp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut libc::c_char; + } + locale = get_locale_var( + b"LC_MESSAGES\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if locale.is_null() + || *locale.offset(0 as libc::c_int as isize) as libc::c_int == '\0' as i32 + || *locale.offset(0 as libc::c_int as isize) as libc::c_int == 'C' as i32 + && *locale.offset(1 as libc::c_int as isize) as libc::c_int == '\0' as i32 + || *locale.offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 6], &[libc::c_char; 6]>(b"POSIX\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp(locale, b"POSIX\0" as *const u8 as *const libc::c_char) + == 0 as libc::c_int + { + t = malloc((len + 1 as libc::c_int) as libc::size_t) as *mut libc::c_char; + strcpy(t, string); + if !lenp.is_null() { + *lenp = len; + } + return t; + } + if !default_domain.is_null() && *default_domain as libc::c_int != 0 { + translated = dcgettext(default_domain, string, 5 as libc::c_int); + } else { + translated = string; + } + if translated == string { + t = malloc((len + 1 as libc::c_int) as libc::size_t) as *mut libc::c_char; + strcpy(t, string); + if !lenp.is_null() { + *lenp = len; + } + } else { + tlen = strlen(translated) as libc::c_int; + t = malloc((tlen + 1 as libc::c_int) as libc::size_t) as *mut libc::c_char; + strcpy(t, translated); + if !lenp.is_null() { + *lenp = tlen; + } + } + } + return t; +} + +#[no_mangle] +pub fn mk_msgstr(string: *mut libc::c_char, foundnlp: *mut libc::c_int) -> *mut libc::c_char { + let mut c: libc::c_int = 0; + let mut len: libc::c_int; + let result: *mut libc::c_char; + let mut r: *mut libc::c_char; + let mut s: *mut libc::c_char; + len = 0 as libc::c_int; + s = string; + unsafe { + while !s.is_null() && *s as libc::c_int != 0 { + len += 1; + if *s as libc::c_int == '"' as i32 || *s as libc::c_int == '\\' as i32 { + len += 1; + } else if *s as libc::c_int == '\n' as i32 { + len += 5 as libc::c_int; + } + s = s.offset(1); + } + result = malloc((len + 3 as libc::c_int) as libc::size_t) as *mut libc::c_char; + r = result; + let fresh0 = r; + r = r.offset(1); + *fresh0 = '"' as i32 as libc::c_char; + s = string; + while !s.is_null() && { + c = *s as libc::c_int; + c != 0 + } { + if c == '\n' as i32 { + let fresh1 = r; + r = r.offset(1); + *fresh1 = '\\' as i32 as libc::c_char; + let fresh2 = r; + r = r.offset(1); + *fresh2 = 'n' as i32 as libc::c_char; + let fresh3 = r; + r = r.offset(1); + *fresh3 = '"' as i32 as libc::c_char; + let fresh4 = r; + r = r.offset(1); + *fresh4 = '\n' as i32 as libc::c_char; + let fresh5 = r; + r = r.offset(1); + *fresh5 = '"' as i32 as libc::c_char; + if !foundnlp.is_null() { + *foundnlp = 1 as libc::c_int; + } + } else { + if c == '"' as i32 || c == '\\' as i32 { + let fresh6 = r; + r = r.offset(1); + *fresh6 = '\\' as i32 as libc::c_char; + } + let fresh7 = r; + r = r.offset(1); + *fresh7 = c as libc::c_char; + } + s = s.offset(1); + } + let fresh8 = r; + r = r.offset(1); + *fresh8 = '"' as i32 as libc::c_char; + let fresh9 = r; + r = r.offset(1); + *fresh9 = '\0' as i32 as libc::c_char; + } + return result; +} + +#[no_mangle] +pub fn localeexpand( + string: *mut libc::c_char, + start: libc::c_int, + end: libc::c_int, + lineno: libc::c_int, + lenp: *mut libc::c_int, +) -> *mut libc::c_char { + let mut len: libc::c_int; + let mut tlen: libc::c_int; + let mut foundnl: libc::c_int; + let temp: *mut libc::c_char; + let t: *mut libc::c_char; + let t2: *mut libc::c_char; + unsafe { + temp = malloc((end - start + 1 as libc::c_int) as libc::size_t) as *mut libc::c_char; + tlen = 0 as libc::c_int; + len = start; + while len < end { + let fresh10 = len; + len = len + 1; + let fresh11 = tlen; + tlen = tlen + 1; + *temp.offset(fresh11 as isize) = *string.offset(fresh10 as isize); + } + *temp.offset(tlen as isize) = '\0' as i32 as libc::c_char; + if dump_translatable_strings != 0 { + if dump_po_strings != 0 { + foundnl = 0 as libc::c_int; + t = mk_msgstr(temp, &mut foundnl); + t2 = (if foundnl != 0 { + b"\"\"\n\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + printf( + b"#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n\0" as *const u8 as *const libc::c_char, + yy_input_name(), + lineno, + t2, + t, + ); + free(t as *mut libc::c_void); + } else { + printf(b"\"%s\"\n\0" as *const u8 as *const libc::c_char, temp); + } + if !lenp.is_null() { + *lenp = tlen; + } + return temp; + } else if *temp != 0 { + t = localetrans(temp, tlen, &mut len); + free(temp as *mut libc::c_void); + if !lenp.is_null() { + *lenp = len; + } + return t; + } else { + if !lenp.is_null() { + *lenp = 0 as libc::c_int; + } + return temp; + }; + } +} + +fn locale_setblanks() { + let mut x: libc::c_int; + x = 0 as libc::c_int; + unsafe { + while x < sh_syntabsiz { + if *(*__ctype_b_loc()).offset(x as libc::c_uchar as libc::c_int as isize) as libc::c_int + & _ISblank as libc::c_int as libc::c_ushort as libc::c_int + != 0 + { + *sh_syntaxtab.as_mut_ptr().offset(x as isize) |= + 0x2 as libc::c_int | 0x2000 as libc::c_int; + } else if if x != 0 { + (mbschr(b"()<>;&| \t\n\0" as *const u8 as *const libc::c_char, x) + != 0 as *mut libc::c_void as *mut libc::c_char) as libc::c_int + } else { + 0 as libc::c_int + } != 0 + { + *sh_syntaxtab.as_mut_ptr().offset(x as isize) |= 0x2 as libc::c_int; + *sh_syntaxtab.as_mut_ptr().offset(x as isize) &= !(0x2000 as libc::c_int); + } else { + *sh_syntaxtab.as_mut_ptr().offset(x as isize) &= + !(0x2 as libc::c_int | 0x2000 as libc::c_int); + } + x += 1; + } + } +} + +fn locale_isutf8(mut _lspec: *mut libc::c_char) -> libc::c_int { + let cp: *mut libc::c_char; + let mut _encoding: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + cp = nl_langinfo(libc::CODESET as libc::c_int); + return (*cp.offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 6], &[libc::c_char; 6]>(b"UTF-8\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp(cp, b"UTF-8\0" as *const u8 as *const libc::c_char) == 0 as libc::c_int + || *cp.offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"utf8\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp(cp, b"utf8\0" as *const u8 as *const libc::c_char) == 0 as libc::c_int) + as libc::c_int; + } +} + +#[no_mangle] +pub fn locale_decpoint() -> libc::c_int { + let lv: *mut lconv; + //let lv: *const lconv; + unsafe { + lv = localeconv() as *mut src_common::lconv; + return if !lv.is_null() + && !((*lv).decimal_point).is_null() + && *((*lv).decimal_point).offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + *((*lv).decimal_point).offset(0 as libc::c_int as isize) as libc::c_int + } else { + '.' as i32 + }; + } +} diff --git a/utshell-0.5.0/src/mailcheck.rs b/utshell-0.5.0/src/mailcheck.rs new file mode 100644 index 00000000..ad22a383 --- /dev/null +++ b/utshell-0.5.0/src/mailcheck.rs @@ -0,0 +1,534 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::general::{extract_colon_unit, full_pathname, legal_number}; +use crate::src_common::*; +use crate::subst::expand_string_to_string; +use crate::variables::{bind_variable, unbind_variable}; + +#[no_mangle] +pub fn time_to_check_mail() -> libc::c_int { + let mut seconds: intmax_t = 0; + let temp: *mut libc::c_char; + let now: time_t; + unsafe { + temp = get_string_value(b"MAILCHECK\0" as *const u8 as *const libc::c_char); + if temp.is_null() + || legal_number(temp, &mut seconds) == 0 as libc::c_int + || seconds < 0 as libc::c_int as intmax_t + { + return 0 as libc::c_int; + } + now = time(0 as *mut time_t); + return (seconds == 0 as libc::c_int as intmax_t || now - last_time_mail_checked >= seconds) + as libc::c_int; + } +} + +#[no_mangle] +pub fn reset_mail_timer() { + unsafe { + last_time_mail_checked = time(0 as *mut time_t); + } +} + +fn find_mail_file(file: *mut libc::c_char) -> libc::c_int { + let mut i: libc::c_int; + i = 0 as libc::c_int; + unsafe { + while i < mailfiles_count { + if *((**mailfiles.offset(i as isize)).name).offset(0 as libc::c_int as isize) + as libc::c_int + == *file.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp((**mailfiles.offset(i as isize)).name, file) == 0 as libc::c_int + { + return i; + } + i += 1; + } + } + return -(1 as libc::c_int); +} + +fn init_mail_file(i: libc::c_int) { + unsafe { + let ref mut fresh0 = (**mailfiles.offset(i as isize)).mod_time; + *fresh0 = if last_time_mail_checked != 0 { + last_time_mail_checked + } else { + shell_start_time + }; + (**mailfiles.offset(i as isize)).access_time = *fresh0; + (**mailfiles.offset(i as isize)).file_size = 0 as libc::c_int as off_t; + (**mailfiles.offset(i as isize)).flags = 0 as libc::c_int; + } +} + +fn update_mail_file(i: libc::c_int) { + let file: *mut libc::c_char; + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + unsafe { + file = (**mailfiles.offset(i as isize)).name; + if mailstat(file, &mut finfo) == 0 as libc::c_int { + UPDATE_MAIL_FILE!(i, finfo); + } else { + RESET_MAIL_FILE!(i); + }; + } +} + +fn add_mail_file(file: *mut libc::c_char, msg: *mut libc::c_char) -> libc::c_int { + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let filename: *mut libc::c_char; + let mut i: libc::c_int; + filename = full_pathname(file); + i = find_mail_file(filename); + unsafe { + if i >= 0 as libc::c_int { + if mailstat(filename, &mut finfo) == 0 as libc::c_int { + UPDATE_MAIL_FILE!(i, finfo); + } + free(filename as *mut libc::c_void); + return i; + } + let fresh2 = mailfiles_count; + mailfiles_count = mailfiles_count + 1; + i = fresh2; + mailfiles = libc::realloc( + mailfiles as *mut libc::c_void, + (mailfiles_count as libc::size_t) + .wrapping_mul(::core::mem::size_of::<*mut FILEINFO>() as libc::size_t), + ) as *mut *mut FILEINFO; + let ref mut fresh3 = *mailfiles.offset(i as isize); + *fresh3 = alloc_mail_file(filename, msg); + init_mail_file(i); + } + return i; +} + +#[no_mangle] +pub fn reset_mail_files() { + unsafe { + let mut i: libc::c_int; + i = 0 as libc::c_int; + while i < mailfiles_count { + RESET_MAIL_FILE!(i); + i += 1; + } + } +} + +fn alloc_mail_file(filename: *mut libc::c_char, msg: *mut libc::c_char) -> *mut FILEINFO { + unsafe { + let mf: *mut FILEINFO; + mf = libc::malloc(::core::mem::size_of::() as libc::size_t) as *mut FILEINFO; + (*mf).name = filename; + (*mf).msg = if !msg.is_null() { + strcpy( + libc::malloc( + (1 as libc::c_int as libc::size_t).wrapping_add(strlen(msg) as libc::size_t), + ) as *mut libc::c_char, + msg, + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + (*mf).flags = 0 as libc::c_int; + return mf; + } +} + +fn dispose_mail_file(mf: *mut FILEINFO) { + unsafe { + free((*mf).name as *mut libc::c_void); + if !((*mf).msg).is_null() { + free((*mf).msg as *mut libc::c_void); + } + (*mf).msg = 0 as *mut libc::c_char; + free(mf as *mut libc::c_void); + } +} + +#[no_mangle] +pub fn free_mail_files() { + let mut i: libc::c_int; + i = 0 as libc::c_int; + unsafe { + while i < mailfiles_count { + dispose_mail_file(*mailfiles.offset(i as isize)); + i += 1; + } + if !mailfiles.is_null() { + free(mailfiles as *mut libc::c_void); + } + mailfiles_count = 0 as libc::c_int; + mailfiles = 0 as *mut libc::c_void as *mut *mut FILEINFO; + } +} + +#[no_mangle] +pub fn init_mail_dates() { + unsafe { + if mailfiles.is_null() { + remember_mail_dates(); + } + } +} + +fn file_mod_date_changed(i: libc::c_int) -> libc::c_int { + let mtime_0: time_t; + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + unsafe { + let file: *mut libc::c_char; + file = (**mailfiles.offset(i as isize)).name; + mtime_0 = (**mailfiles.offset(i as isize)).mod_time; + if mailstat(file, &mut finfo) != 0 as libc::c_int { + return 0 as libc::c_int; + } + if finfo.st_size > 0 as libc::c_int as libc::c_long { + return (mtime_0 < finfo.st_mtim.tv_sec) as libc::c_int; + } + if finfo.st_size == 0 as libc::c_int as libc::c_long + && (**mailfiles.offset(i as isize)).file_size > 0 as libc::c_int as off_t + { + UPDATE_MAIL_FILE!(i, finfo); + } + } + return 0 as libc::c_int; +} + +fn file_access_date_changed(i: libc::c_int) -> libc::c_int { + let atime_0: time_t; + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let file: *mut libc::c_char; + unsafe { + file = (**mailfiles.offset(i as isize)).name; + atime_0 = (**mailfiles.offset(i as isize)).access_time; + if mailstat(file, &mut finfo) != 0 as libc::c_int { + return 0 as libc::c_int; + } + if finfo.st_size > 0 as libc::c_int as libc::c_long { + return (atime_0 < finfo.st_atim.tv_sec) as libc::c_int; + } + } + return 0 as libc::c_int; +} + +fn file_has_grown(i: libc::c_int) -> libc::c_int { + let size: off_t; + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + unsafe { + let file: *mut libc::c_char; + file = (**mailfiles.offset(i as isize)).name; + size = (**mailfiles.offset(i as isize)).file_size; + return (mailstat(file, &mut finfo) == 0 as libc::c_int && finfo.st_size > size) + as libc::c_int; + } +} + +fn parse_mailpath_spec(str: *mut libc::c_char) -> *mut libc::c_char { + let mut s: *mut libc::c_char; + let mut pass_next: libc::c_int; + s = str; + unsafe { + pass_next = 0 as libc::c_int; + while !s.is_null() && *s as libc::c_int != 0 { + if pass_next != 0 { + pass_next = 0 as libc::c_int; + } else if *s as libc::c_int == '\\' as i32 { + pass_next += 1; + } else if *s as libc::c_int == '?' as i32 || *s as libc::c_int == '%' as i32 { + return s; + } + s = s.offset(1); + } + } + return 0 as *mut libc::c_void as *mut libc::c_char; +} + +#[no_mangle] +pub fn make_default_mailpath() -> *mut libc::c_char { + unsafe { + let mp: *mut libc::c_char; + get_current_user_info(); + mp = libc::malloc( + (2 as libc::c_int as usize) + .wrapping_add(strlen(DEFAULT_MAIL_DIRECTORY) as usize) + .wrapping_add(strlen(current_user.user_name) as usize), + ) as *mut libc::c_char; + strcpy(mp, DEFAULT_MAIL_DIRECTORY); + *mp.offset((strlen(DEFAULT_MAIL_DIRECTORY)).wrapping_sub(1) as isize) = + '/' as i32 as libc::c_char; + strcpy( + mp.offset(strlen(DEFAULT_MAIL_DIRECTORY) as libc::c_ulong as isize), + current_user.user_name, + ); + return mp; + } +} + +#[no_mangle] +pub fn remember_mail_dates() { + let mut mailpaths: *mut libc::c_char; + let mut mailfile: *mut libc::c_char; + let mut mp: *mut libc::c_char; + let mut i: libc::c_int = 0 as libc::c_int; + unsafe { + mailpaths = get_string_value(b"MAILPATH\0" as *const u8 as *const libc::c_char); + if mailpaths.is_null() && { + mailpaths = get_string_value(b"MAIL\0" as *const u8 as *const libc::c_char); + !mailpaths.is_null() + } { + add_mail_file(mailpaths, 0 as *mut libc::c_void as *mut libc::c_char); + return; + } + if mailpaths.is_null() { + mailpaths = make_default_mailpath(); + if !mailpaths.is_null() { + add_mail_file(mailpaths, 0 as *mut libc::c_void as *mut libc::c_char); + free(mailpaths as *mut libc::c_void); + } + return; + } + loop { + mailfile = extract_colon_unit(mailpaths, &mut i); + if mailfile.is_null() { + break; + } + mp = parse_mailpath_spec(mailfile); + if !mp.is_null() && *mp as libc::c_int != 0 { + let fresh5 = mp; + mp = mp.offset(1); + *fresh5 = '\0' as i32 as libc::c_char; + } + add_mail_file(mailfile, mp); + free(mailfile as *mut libc::c_void); + } + } +} + +#[no_mangle] +pub fn check_mail() { + let mut current_mail_file: *mut libc::c_char; + let mut message: *mut libc::c_char; + let mut i: libc::c_int; + let mut use_user_notification: libc::c_int; + let mut dollar_underscore: *mut libc::c_char; + let mut temp: *mut libc::c_char; + unsafe { + dollar_underscore = get_string_value(b"_\0" as *const u8 as *const libc::c_char); + if !dollar_underscore.is_null() { + dollar_underscore = strcpy( + libc::malloc( + (1 as libc::c_int as usize).wrapping_add(strlen(dollar_underscore) as usize), + ) as *mut libc::c_char, + dollar_underscore, + ); + } + let mut _current_block_20: u64; + i = 0 as libc::c_int; + while i < mailfiles_count { + current_mail_file = (**mailfiles.offset(i as isize)).name; + if !(*current_mail_file as libc::c_int == '\0' as i32) { + if file_mod_date_changed(i) != 0 { + let file_is_bigger: libc::c_int; + use_user_notification = ((**mailfiles.offset(i as isize)).msg + != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int; + message = if !((**mailfiles.offset(i as isize)).msg).is_null() { + (**mailfiles.offset(i as isize)).msg + } else { + dcgettext( + 0 as *const libc::c_char, + b"You have mail in $_\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ) + }; + bind_variable( + b"_\0" as *const u8 as *const libc::c_char, + current_mail_file, + 0 as libc::c_int, + ); + file_is_bigger = file_has_grown(i); + update_mail_file(i); + if (**mailfiles.offset(i as isize)).access_time + >= (**mailfiles.offset(i as isize)).mod_time + && file_is_bigger == 0 + { + i += 1; + continue; + } else { + if use_user_notification == 0 as libc::c_int + && (**mailfiles.offset(i as isize)).access_time + < (**mailfiles.offset(i as isize)).mod_time + && file_is_bigger != 0 + { + message = dcgettext( + 0 as *const libc::c_char, + b"You have new mail in $_\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ); + } + temp = expand_string_to_string(message, 0x1 as libc::c_int); + if !temp.is_null() { + puts(temp); + free(temp as *mut libc::c_void); + } else { + putc('\n' as i32, stdout); + } + } + if mail_warning != 0 && file_access_date_changed(i) != 0 { + update_mail_file(i); + printf( + dcgettext( + 0 as *const libc::c_char, + b"The mail in %s has been read\n\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + current_mail_file, + ); + } + } + } + i += 1; + } + if !dollar_underscore.is_null() { + bind_variable( + b"_\0" as *const u8 as *const libc::c_char, + dollar_underscore, + 0 as libc::c_int, + ); + free(dollar_underscore as *mut libc::c_void); + } else { + unbind_variable(b"_\0" as *const u8 as *const libc::c_char); + }; + } +} diff --git a/utshell-0.5.0/src/make_cmd.rs b/utshell-0.5.0/src/make_cmd.rs new file mode 100644 index 00000000..ed501d02 --- /dev/null +++ b/utshell-0.5.0/src/make_cmd.rs @@ -0,0 +1,907 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::array::array_reference; +use crate::builtins::common::builtin_address_internal; +use crate::dispose_cmd::{dispose_word, dispose_words}; +use crate::error::command_error; +use crate::general::{all_digits, assignment, legal_number}; +use crate::list::list_reverse; +use crate::src_common::*; +use crate::stringlib::substring; +use crate::subst::{skip_to_delim, string_quote_removal}; +use crate::variables::{bind_function_def, find_function}; +use crate::y_tab::{line_number, parser_state, read_secondary_line}; + +#[no_mangle] +pub fn cmd_init() { + unsafe { + ocache_create!(wdcache, WordDesc, WDCACHESIZE!()); + ocache_create!(wlcache, WordList, WLCACHESIZE!()); + } +} + +#[no_mangle] +pub fn alloc_word_desc() -> *mut WordDesc { + let mut temp: *mut WordDesc = 0 as *mut WordDesc; + unsafe { + ocache_alloc!(wdcache, WordDesc, temp); + (*temp).flags = 0; + (*temp).word = 0 as *mut libc::c_char; + } + return temp; +} + +#[no_mangle] +pub fn make_bare_word(mut string: *const libc::c_char) -> *mut WordDesc { + let mut temp: *mut WordDesc = 0 as *mut WordDesc; + temp = alloc_word_desc(); + unsafe { + if *string != 0 { + (*temp).word = savestring!(string); + } else { + (*temp).word = malloc(1) as *mut libc::c_char; + *((*temp).word).offset(0 as isize) = '\u{0}' as i32 as libc::c_char; + } + } + return temp; +} + +#[inline] +fn is_basic(mut c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} + +#[no_mangle] +pub fn make_word_flags(mut w: *mut WordDesc, mut string: *const libc::c_char) -> *mut WordDesc { + let mut i: libc::c_int = 0; + let mut slen: size_t = 0; + // DECLARE_MBSTATE!(); + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + std::mem::size_of::() as usize, + ); + + i = 0; + slen = strlen(string) as size_t; + while (i as libc::c_ulong) < slen { + let opt = *string.offset(i as isize); + let opt_char = char::from(opt as u8); + + match opt_char { + '$' => { + (*w).flags |= W_HASDOLLAR as libc::c_int; + } + '\'' | '`' | '"' => { + (*w).flags |= W_QUOTED as libc::c_int; + } + '\\' | _ => {} + } + ADVANCE_CHAR!(string, slen, i, state); + } + + return w; + } +} + +#[no_mangle] +pub fn make_word(mut string: *const libc::c_char) -> *mut WordDesc { + unsafe { + let mut temp: *mut WordDesc = 0 as *mut WordDesc; + temp = make_bare_word(string); + return make_word_flags(temp, string); + } +} + +#[no_mangle] +pub fn make_word_from_token(mut token: libc::c_int) -> *mut WordDesc { + let mut tokenizer: [libc::c_char; 2] = [0; 2]; + + tokenizer[0 as usize] = token as libc::c_char; + tokenizer[1 as usize] = '\u{0}' as i32 as libc::c_char; + return make_word(tokenizer.as_mut_ptr()); +} + +#[no_mangle] +pub fn make_word_list(mut word: *mut WordDesc, mut wlink: *mut WordList) -> *mut WordList { + let mut temp: *mut WordList = 0 as *mut WordList; + unsafe { + ocache_alloc!(wlcache, WordList, temp); + + (*temp).word = word; + (*temp).next = wlink; + } + return temp; +} + +#[no_mangle] +pub fn make_command(mut type_0: command_type, mut pointer: *mut SIMPLE_COM) -> *mut COMMAND { + let mut temp: *mut COMMAND = 0 as *mut COMMAND; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut COMMAND; + (*temp).type_0 = type_0; + (*temp).value.Simple = pointer; + (*temp).flags = 0; + (*(*temp).value.Simple).flags = 0; + (*temp).redirects = 0 as *mut REDIRECT; + } + return temp; +} + +#[no_mangle] +pub fn command_connect( + mut com1: *mut COMMAND, + mut com2: *mut COMMAND, + mut connector: libc::c_int, +) -> *mut COMMAND { + let mut temp: *mut CONNECTION = 0 as *mut CONNECTION; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut CONNECTION; + (*temp).connector = connector; + (*temp).first = com1; + (*temp).second = com2; + } + return make_command(command_type_cm_connection, temp as *mut SIMPLE_COM); +} + +fn make_for_or_select( + mut type_0: command_type, + mut name: *mut WordDesc, + mut map_list: *mut WordList, + mut action: *mut COMMAND, + mut lineno: libc::c_int, +) -> *mut COMMAND { + let mut temp: *mut FOR_COM = 0 as *mut FOR_COM; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut FOR_COM; + (*temp).flags = 0; + (*temp).name = name; + (*temp).line = lineno; + (*temp).map_list = map_list; + (*temp).action = action; + } + return make_command(type_0 as libc::c_uint, temp as *mut SIMPLE_COM); +} + +#[no_mangle] +pub fn make_for_command( + mut name: *mut WordDesc, + mut map_list: *mut WordList, + mut action: *mut COMMAND, + mut lineno: libc::c_int, +) -> *mut COMMAND { + return make_for_or_select(command_type_cm_for, name, map_list, action, lineno); +} +#[no_mangle] +pub fn make_select_command( + mut name: *mut WordDesc, + mut map_list: *mut WordList, + mut action: *mut COMMAND, + mut lineno: libc::c_int, +) -> *mut COMMAND { + return make_for_or_select(command_type_cm_select, name, map_list, action, lineno); +} + +fn make_arith_for_expr(mut s: *mut libc::c_char) -> *mut WordList { + let mut result: *mut WordList = 0 as *mut WordList; + let mut wd: *mut WordDesc = 0 as *mut WordDesc; + unsafe { + if s.is_null() || *s as libc::c_int == '\u{0}' as i32 { + return 0 as *mut WordList; + } + wd = make_word(s); + (*wd).flags |= W_NOGLOB!() | W_NOSPLIT!() | W_QUOTED!() | W_DQUOTE!(); + (*wd).flags |= W_NOPROCSUB!(); + result = make_word_list(wd, 0 as *mut WordList); + } + return result; +} + +#[no_mangle] +pub fn make_arith_for_command( + mut exprs: *mut WordList, + mut action: *mut COMMAND, + mut lineno: libc::c_int, +) -> *mut COMMAND { + let mut temp: *mut ARITH_FOR_COM = 0 as *mut ARITH_FOR_COM; + let mut init: *mut WordList = 0 as *mut WordList; + let mut test: *mut WordList = 0 as *mut WordList; + let mut step: *mut WordList = 0 as *mut WordList; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut start: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nsemi: libc::c_int = 0; + let mut i: libc::c_int = 0; + + step = 0 as *mut WordList; + test = step; + init = test; + unsafe { + s = (*(*exprs).word).word; + t = s; + start = t; + nsemi = 0; + loop { + while whitespace!(*s) { + s = s.offset(1); + } + start = s; + i = skip_to_delim( + start, + 0, + b";\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + SD_NOJMP as libc::c_int | SD_NOPROCSUB as libc::c_int, + ); + s = start.offset(i as isize); + + t = if i > 0 as libc::c_int { + substring(start, 0, i) + } else { + 0 as *mut libc::c_char + }; + + nsemi += 1; + match nsemi { + 1 => { + init = make_arith_for_expr(t); + } + 2 => { + test = make_arith_for_expr(t); + } + 3 => { + step = make_arith_for_expr(t); + } + _ => {} + } + FREE!(t); + if *s as libc::c_int == '\u{0}' as i32 { + break; + } + s = s.offset(1); + } + if nsemi != 3 { + if nsemi < 3 { + parser_error( + lineno, + b"syntax error: arithmetic expression required\0" as *const u8 + as *mut libc::c_char, + ); + } else { + parser_error( + lineno, + b"syntax error: `;' unexpected\0" as *const u8 as *const libc::c_char, + ); + } + parser_error( + lineno, + b"syntax error: `((%s))'\0" as *const u8 as *const libc::c_char, + (*(*exprs).word).word, + ); + free(init as *mut c_void); + free(test as *mut c_void); + free(step as *mut c_void); + set_exit_status(2); + return 0 as *mut COMMAND; + } + + temp = malloc(std::mem::size_of::() as usize) as *mut ARITH_FOR_COM; + (*temp).flags = 0; + (*temp).line = lineno; + (*temp).init = if !init.is_null() { + init + } else { + make_arith_for_expr(b"1\0" as *const u8 as *const libc::c_char as *mut libc::c_char) + }; + (*temp).test = if !test.is_null() { + test + } else { + make_arith_for_expr(b"1\0" as *const u8 as *const libc::c_char as *mut libc::c_char) + }; + (*temp).step = if !step.is_null() { + step + } else { + make_arith_for_expr(b"1\0" as *const u8 as *const libc::c_char as *mut libc::c_char) + }; + (*temp).action = action; + dispose_words(exprs); + } + return make_command(command_type_cm_arith_for, temp as *mut SIMPLE_COM); +} + +#[no_mangle] +pub fn make_group_command(mut command: *mut COMMAND) -> *mut COMMAND { + unsafe { + let mut temp: *mut GROUP_COM = 0 as *mut GROUP_COM; + temp = malloc(std::mem::size_of::() as usize) as *mut GROUP_COM; + + (*temp).command = command; + + return make_command(command_type_cm_group, temp as *mut SIMPLE_COM); + } +} + +#[no_mangle] +pub fn make_case_command( + mut word: *mut WordDesc, + mut clauses: *mut PATTERN_LIST, + mut lineno: libc::c_int, +) -> *mut COMMAND { + let mut temp: *mut CASE_COM = 0 as *mut CASE_COM; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut CASE_COM; + (*temp).flags = 0; + (*temp).line = lineno; + (*temp).word = word; + (*temp).clauses = REVERSE_LIST!(clauses, *mut PATTERN_LIST); + } + return make_command(command_type_cm_case, temp as *mut SIMPLE_COM); +} + +#[no_mangle] +pub fn make_pattern_list( + mut patterns: *mut WordList, + mut action: *mut COMMAND, +) -> *mut PATTERN_LIST { + let mut temp: *mut PATTERN_LIST = 0 as *mut PATTERN_LIST; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut PATTERN_LIST; + (*temp).patterns = REVERSE_LIST!(patterns, *mut WordList); + (*temp).action = action; + (*temp).next = 0 as *mut pattern_list; + (*temp).flags = 0; + } + return temp; +} + +#[no_mangle] +pub fn make_if_command( + mut test: *mut COMMAND, + mut true_case: *mut COMMAND, + mut false_case: *mut COMMAND, +) -> *mut COMMAND { + let mut temp: *mut IF_COM = 0 as *mut IF_COM; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut IF_COM; + (*temp).flags = 0; + (*temp).test = test; + (*temp).true_case = true_case; + (*temp).false_case = false_case; + } + return make_command(command_type_cm_if, temp as *mut SIMPLE_COM); +} + +fn make_until_or_while( + mut which: command_type, + mut test: *mut COMMAND, + mut action: *mut COMMAND, +) -> *mut COMMAND { + let mut temp: *mut WHILE_COM = 0 as *mut WHILE_COM; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut WHILE_COM; + (*temp).flags = 0 as libc::c_int; + (*temp).test = test; + (*temp).action = action; + } + return make_command(which as libc::c_uint, temp as *mut SIMPLE_COM); +} + +#[no_mangle] +pub fn make_while_command(mut test: *mut COMMAND, mut action: *mut COMMAND) -> *mut COMMAND { + return make_until_or_while(command_type_cm_while, test, action); +} + +#[no_mangle] +pub fn make_until_command(mut test: *mut COMMAND, mut action: *mut COMMAND) -> *mut COMMAND { + return make_until_or_while(command_type_cm_until, test, action); +} + +#[no_mangle] +pub fn make_arith_command(mut exp: *mut WordList) -> *mut COMMAND { + let mut command: *mut COMMAND = 0 as *mut COMMAND; + let mut temp: *mut ARITH_COM = 0 as *mut ARITH_COM; + unsafe { + command = malloc(std::mem::size_of::() as usize) as *mut COMMAND; + temp = malloc(std::mem::size_of::() as usize) as *mut ARITH_COM; + (*command).value.Arith = temp; + (*temp).flags = 0; + (*temp).line = line_number; + (*temp).exp = exp; + (*command).type_0 = command_type_cm_arith; + (*command).redirects = 0 as *mut libc::c_void as *mut REDIRECT; + (*command).flags = 0; + } + return command; +} + +#[no_mangle] +pub fn make_cond_node( + mut type_0: libc::c_int, + mut op: *mut WordDesc, + mut left: *mut cond_com, + mut right: *mut cond_com, +) -> *mut COND_COM { + let mut temp: *mut COND_COM = 0 as *mut COND_COM; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut COND_COM; + (*temp).flags = 0; + (*temp).line = line_number; + (*temp).type_0 = type_0; + (*temp).op = op; + (*temp).left = left; + (*temp).right = right; + } + return temp; +} + +#[no_mangle] +pub fn make_cond_command(mut cond_node: *mut COND_COM) -> *mut COMMAND { + let mut command: *mut COMMAND = 0 as *mut COMMAND; + unsafe { + command = malloc(std::mem::size_of::() as usize) as *mut COMMAND; + (*command).value.Cond = cond_node; + (*command).type_0 = command_type_cm_cond; + (*command).redirects = 0 as *mut REDIRECT; + (*command).flags = 0; + (*command).line = if !cond_node.is_null() { + (*cond_node).line + } else { + 0 + }; + } + return command; +} + +#[no_mangle] +pub fn make_bare_simple_command() -> *mut COMMAND { + let mut command: *mut COMMAND = 0 as *mut COMMAND; + let mut temp: *mut SIMPLE_COM = 0 as *mut SIMPLE_COM; + unsafe { + command = malloc(std::mem::size_of::() as usize) as *mut COMMAND; + temp = malloc(std::mem::size_of::() as usize) as *mut SIMPLE_COM; + (*command).value.Simple = temp; + + (*temp).flags = 0; + (*temp).line = line_number; + (*temp).words = 0 as *mut WordList; + (*temp).redirects = 0 as *mut REDIRECT; + + (*command).type_0 = command_type_cm_simple; + (*command).redirects = 0 as *mut REDIRECT; + (*command).flags = 0; + } + return command; +} + +#[no_mangle] +pub fn make_simple_command(mut element: ELEMENT, mut command: *mut COMMAND) -> *mut COMMAND { + unsafe { + if command.is_null() { + command = make_bare_simple_command(); + parser_state |= PST_REDIRLIST as libc::c_int; + } + if !(element.word).is_null() { + (*(*command).value.Simple).words = + make_word_list(element.word, (*(*command).value.Simple).words); + parser_state &= !(PST_REDIRLIST as libc::c_int); + } else if !(element.redirect).is_null() { + let mut r: *mut REDIRECT = element.redirect; + while !((*r).next).is_null() { + r = (*r).next; + } + (*r).next = (*(*command).value.Simple).redirects; + (*(*command).value.Simple).redirects = element.redirect; + } + return command; + } +} + +#[no_mangle] +pub fn make_here_document(mut temp: *mut REDIRECT, mut lineno: libc::c_int) { + let mut current_block: u64; + let mut kill_leading: libc::c_int = 0; + let mut redir_len: libc::c_int = 0; + let mut redir_word: *mut libc::c_char = 0 as *mut libc::c_char; + let mut document: *mut libc::c_char = 0 as *mut libc::c_char; + let mut full_line: *mut libc::c_char = 0 as *mut libc::c_char; + let mut document_index: libc::c_int = 0; + let mut document_size: libc::c_int = 0; + let mut delim_unquoted: libc::c_int = 0; + unsafe { + if (*temp).instruction != r_instruction_r_deblank_reading_until + && (*temp).instruction != r_instruction_r_reading_until + { + internal_error( + b"make_here_document: bad instruction type %d\0" as *const u8 + as *const libc::c_char, + (*temp).instruction as libc::c_uint, + ); + return; + } + kill_leading = + ((*temp).instruction == r_instruction_r_deblank_reading_until) as libc::c_int; + + document = 0 as *mut libc::c_char; + document_size = 0; + document_index = document_size; + + redir_word = string_quote_removal((*(*temp).redirectee.filename).word, 0); + + 'lable1: loop { + if !redir_word.is_null() { + redir_len = strlen(redir_word) as libc::c_int; + } else { + (*temp).here_doc_eof = malloc(1 as usize) as *mut libc::c_char; + *(*temp).here_doc_eof.offset(0) = '\u{0}' as i32 as libc::c_char; + break 'lable1; + } + + free((*(*temp).redirector.filename).word as *mut c_void); + (*temp).here_doc_eof = redir_word; + + delim_unquoted = (((*(*temp).redirector.filename).flags & W_QUOTED as libc::c_int) == 0) + as libc::c_int; + + full_line = read_secondary_line(delim_unquoted); + while !full_line.is_null() { + let mut line: *mut libc::c_char; + let mut len: i32; + + here_doc_first_line = 0; + line = full_line; + line_number += 1; + + if echo_input_at_read != 0 { + fprintf(stderr, b"%s\0" as *const u8 as *const libc::c_char, line); + } + if kill_leading != 0 && *line as libc::c_int != 0 { + if STREQN!(line, redir_word, redir_len as usize) != 0 + && *line.offset(redir_len as isize) as libc::c_int == '\n' as i32 + { + break 'lable1; + } + while *line as libc::c_int == '\t' as i32 { + line = line.offset(1); + } + } + + if *line as libc::c_int == 0 { + continue; + } + + if STREQN!(line, redir_word, redir_len as usize) != 0 + && *line.offset(redir_len as isize) as libc::c_int == '\n' as i32 + { + break 'lable1; + } + + len = strlen(line) as libc::c_int; + if len + document_index >= document_size { + document_size = if document_size != 0 { + 2 * (document_size + len) + } else { + len + 2 + }; + document = realloc(document as *mut libc::c_void, document_size as usize) + as *mut libc::c_char; + } + + FASTCOPY!(line, document.offset(document_index as isize), len); + document_index += len; + + full_line = read_secondary_line(delim_unquoted); + } + + if !full_line.is_null() { + internal_warning( + b"here-document at line %d delimited by end-of-file (wanted `%s')\0" + as *const u8 as *const libc::c_char, + lineno, + redir_word, + ); + } + + break 'lable1; + } + + if !document.is_null() { + *document.offset(document_index as isize) = '\u{0}' as libc::c_char; + } else { + document = malloc(1) as *mut libc::c_char; + *document.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } + + (*(*temp).redirectee.filename).word = document; + here_doc_first_line = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn make_redirection( + mut source: REDIRECTEE, + mut instruction: r_instruction, + mut dest_and_filename: REDIRECTEE, + mut flags: libc::c_int, +) -> *mut REDIRECT { + unsafe { + let mut temp: *mut REDIRECT = 0 as *mut REDIRECT; + let mut w: *mut WordDesc = 0 as *mut WordDesc; + let mut wlen: libc::c_int = 0; + let mut lfd: intmax_t = 0; + + temp = malloc(std::mem::size_of::() as usize) as *mut REDIRECT; + + (*temp).redirector = source; + (*temp).redirectee = dest_and_filename; + (*temp).here_doc_eof = 0 as *mut libc::c_char; + (*temp).instruction = instruction; + (*temp).flags = 0; + (*temp).rflags = flags; + let ref mut fresh47 = (*temp).next; + (*temp).next = 0 as *mut REDIRECT; + + match instruction as u32 { + r_instruction_r_output_direction + | r_instruction_r_output_force + | r_instruction_r_err_and_out => { + (*temp).flags = + O_TRUNC as libc::c_int | O_WRONLY as libc::c_int | O_CREAT as libc::c_int; + } + + r_instruction_r_appending_to | r_instruction_r_append_err_and_out => { + (*temp).flags = + O_APPEND as libc::c_int | O_WRONLY as libc::c_int | O_CREAT as libc::c_int; + } + + r_instruction_r_input_direction | r_instruction_r_inputa_direction => { + (*temp).flags = O_RDONLY as libc::c_int; + } + + r_input_output => { + (*temp).flags = O_RDWR as libc::c_int | O_CREAT as libc::c_int; + } + + r_instruction_r_deblank_reading_until + | r_instruction_r_reading_until + | r_instruction_r_reading_string + | r_instruction_r_close_this + | r_instruction_r_duplicating_input + | r_instruction_r_duplicating_output => {} + + r_instruction_r_move_input + | r_instruction_r_move_output + | r_instruction_r_move_input_word + | r_instruction_r_move_output_word => {} + + r_instruction_r_duplicating_input_word | r_instruction_r_duplicating_output_word => { + w = dest_and_filename.filename; + wlen = (strlen((*w).word) - 1) as libc::c_int; + if *((*w).word).offset(wlen as isize) as libc::c_int == '-' as i32 { + *((*w).word).offset(wlen as isize) = '\u{0}' as i32 as libc::c_char; + if all_digits((*w).word) != 0 + && legal_number((*w).word, &mut lfd) != 0 + && lfd == lfd as libc::c_long + { + dispose_word(w); + (*temp).instruction = + (if instruction == r_instruction_r_duplicating_input_word { + r_instruction_r_move_input as libc::c_int + } else { + r_instruction_r_move_output as libc::c_int + }) as r_instruction; + (*temp).redirectee.dest = lfd as libc::c_int; + } else { + (*temp).instruction = + (if instruction == r_instruction_r_duplicating_input_word { + r_instruction_r_move_input_word as libc::c_int + } else { + r_instruction_r_move_output_word as libc::c_int + }) as r_instruction; + } + } + } + + _ => { + programming_error( + b"make_redirection: redirection instruction `%d' out of range\0" as *const u8 + as *const libc::c_char, + instruction as libc::c_uint, + ); + abort(); + } + } + + return temp; + } +} + +#[no_mangle] +pub fn make_function_def( + mut name: *mut WordDesc, + mut command: *mut COMMAND, + mut lineno: libc::c_int, + mut lstart: libc::c_int, +) -> *mut COMMAND { + let mut temp: *mut FUNCTION_DEF = 0 as *mut FUNCTION_DEF; + let mut bash_source_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_source_a: *mut ARRAY = 0 as *mut ARRAY; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut FUNCTION_DEF; + (*temp).command = command; + let ref mut fresh49 = (*temp).name; + (*temp).name = name; + (*temp).line = lineno; + (*temp).flags = 0; + (*command).line = lstart; + + (*temp).source_file = 0 as *mut libc::c_char; + GET_ARRAY_FROM_VAR!( + b"BASH_SOURCE\0" as *const u8 as *const libc::c_char, + bash_source_v, + bash_source_a + ); + if !bash_source_a.is_null() && array_num_elements!(bash_source_a) > 0 { + (*temp).source_file = array_reference(bash_source_a, 0 as arrayind_t); + } + if ((*temp).source_file).is_null() { + (*temp).source_file = (if shell_initialized != 0 { + b"main\0" as *const u8 as *const libc::c_char + } else { + b"environment\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + } + + bind_function_def((*name).word, temp, 0); + let ref mut fresh53 = (*temp).source_file; + (*temp).source_file = if !((*temp).source_file).is_null() { + savestring!((*temp).source_file) + } else { + 0 as *mut libc::c_char + }; + } + return make_command(command_type_cm_function_def, temp as *mut SIMPLE_COM); +} + +#[no_mangle] +pub fn make_subshell_command(mut command: *mut COMMAND) -> *mut COMMAND { + unsafe { + let mut temp: *mut SUBSHELL_COM = 0 as *mut SUBSHELL_COM; + temp = malloc(std::mem::size_of::() as usize) as *mut SUBSHELL_COM; + + (*temp).command = command; + (*temp).flags = 0x1; + (*temp).line = line_number; + return make_command(command_type_cm_subshell, temp as *mut SIMPLE_COM); + } +} + +#[no_mangle] +pub fn make_coproc_command(mut name: *mut libc::c_char, mut command: *mut COMMAND) -> *mut COMMAND { + let mut temp: *mut COPROC_COM = 0 as *mut COPROC_COM; + unsafe { + temp = malloc(std::mem::size_of::() as usize) as *mut COPROC_COM; + let ref mut fresh55 = (*temp).name; + (*temp).name = savestring!(name); + let ref mut fresh56 = (*temp).command; + (*temp).command = command; + (*temp).flags = CMD_WANT_SUBSHELL as libc::c_int | CMD_COPROC_SUBSHELL as libc::c_int; + } + return make_command(command_type_cm_coproc, temp as *mut SIMPLE_COM); +} + +fn output_requirement(mut deptype: *const libc::c_char, mut filename: *mut libc::c_char) { + unsafe { + static mut alphabet_set: *mut libc::c_char = + b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\0" as *const u8 + as *const libc::c_char as *mut libc::c_char; + if !(strchr(filename, '$' as i32)).is_null() + || *filename.offset(0 as libc::c_int as isize) as libc::c_int != '/' as i32 + && !(strchr(filename, '/' as i32)).is_null() + { + return; + } + if !(strpbrk(filename, alphabet_set)).is_null() { + printf( + b"%s(%s)\n\0" as *const u8 as *const libc::c_char, + deptype, + filename, + ); + } + } +} + +#[no_mangle] +pub fn clean_simple_command(mut command: *mut COMMAND) -> *mut COMMAND { + unsafe { + if (*command).type_0 != command_type_cm_simple { + command_error( + b"clean_simple_command\0" as *const u8 as *const libc::c_char, + CMDERR_BADTYPE as libc::c_int, + (*command).type_0 as libc::c_int, + 0, + ); + } else { + (*(*command).value.Simple).words = + REVERSE_LIST!((*(*command).value.Simple).words, *mut WordList); + (*(*command).value.Simple).redirects = + REVERSE_LIST!((*(*command).value.Simple).redirects, *mut REDIRECT); + } + + if rpm_requires != 0 && !((*(*command).value.Simple).words).is_null() { + let mut cmd0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut cmd1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut b: *mut builtin = 0 as *mut builtin; + + cmd0 = (*(*(*(*command).value.Simple).words).word).word; + b = builtin_address_internal(cmd0, 0); + cmd1 = 0 as *mut libc::c_char; + if !((*(*(*command).value.Simple).words).next).is_null() { + cmd1 = (*(*(*(*(*command).value.Simple).words).next).word).word; + } + + if !b.is_null() { + if (*b).flags & REQUIRES_BUILTIN as libc::c_int != 0 && !cmd1.is_null() { + output_requirement(b"executable\0" as *const u8 as *const libc::c_char, cmd1); + } + } else if assignment(cmd0, 0 as libc::c_int) == 0 { + output_requirement( + if !(find_function(cmd0)).is_null() { + b"function\0" as *const u8 as *const libc::c_char + } else { + b"executable\0" as *const u8 as *const libc::c_char + }, + cmd0, + ); + } + } + parser_state &= !(PST_REDIRLIST as libc::c_int); + return command; + } +} + +#[no_mangle] +pub fn connect_async_list( + mut command: *mut COMMAND, + mut command2: *mut COMMAND, + mut connector: libc::c_int, +) -> *mut COMMAND { + let mut t: *mut COMMAND = 0 as *mut COMMAND; + let mut t1: *mut COMMAND = 0 as *mut COMMAND; + let mut t2: *mut COMMAND = 0 as *mut COMMAND; + unsafe { + t1 = command; + t = (*(*command).value.Connection).second; + + if t.is_null() + || (*command).flags & CMD_WANT_SUBSHELL as libc::c_int != 0 + || (*(*command).value.Connection).connector != ';' as i32 + { + t = command_connect(command, command2, connector); + return t; + } + + while (*t).flags & CMD_WANT_SUBSHELL as libc::c_int == 0 as libc::c_int + && (*t).type_0 == command_type_cm_connection + && (*(*t).value.Connection).connector == ';' as i32 + { + t1 = t; + t = (*(*t).value.Connection).second; + } + t2 = command_connect(t, command2, connector); + (*(*t1).value.Connection).second = t2; + return command; + } +} diff --git a/utshell-0.5.0/src/nojobs.rs b/utshell-0.5.0/src/nojobs.rs new file mode 100644 index 00000000..edd86954 --- /dev/null +++ b/utshell-0.5.0/src/nojobs.rs @@ -0,0 +1,347 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +use std::mem::size_of; + +use libc::{c_char, c_int, c_long, c_void, WEXITSTATUS, WIFSIGNALED, WIFSTOPPED, WTERMSIG}; +use r_bash::*; + +#[macro_export] +macro_rules! DEFAULT_CHILD_MAX { + () => { + 4096 + }; +} + +#[macro_export] +macro_rules! killpg { + ($pg:expr,$sig:expr) => { + kill(-($pg), ($sig)) + }; +} + +#[macro_export] +macro_rules! WAITPID { + ($pid:expr,$statusp:expr, $options:expr) => { + waitpid($pid, $statusp, $options) + }; +} + +#[macro_export] +macro_rules! input_tty { + () => { + if shell_tty != -1 { + shell_tty + } else { + fileno(stderr) + } + }; +} + +#[macro_export] +macro_rules! NO_PID { + () => { + -1 as pid_t + }; +} + +#[no_mangle] +pub static mut last_made_pid: pid_t = NO_PID!(); +#[no_mangle] +pub static mut last_asynchronous_pid: pid_t = NO_PID!(); +#[no_mangle] +pub static mut queue_sigchld: libc::c_int = 0; +#[no_mangle] +pub static mut waiting_for_child: libc::c_int = 0; +#[no_mangle] +pub static mut already_making_children: libc::c_int = 0; +#[no_mangle] +pub static mut shell_tty: libc::c_int = -1; +#[no_mangle] +pub static mut check_window_size: libc::c_int = CHECKWINSIZE_DEFAULT as libc::c_int; +#[no_mangle] +pub static mut job_control: libc::c_int = 0; +#[no_mangle] +pub static mut running_in_background: libc::c_int = 0; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct proc_status { + pid: pid_t, + status: libc::c_int, + flags: libc::c_int, +} + +#[macro_export] +macro_rules! PROC_RUNNING { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! PROC_NOTIFIED { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! PROC_ASYNC { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! PROC_SIGNALED { + () => { + 0x10 + }; +} + +#[macro_export] +macro_rules! PROC_BAD { + () => { + -1 + }; +} + +#[macro_export] +macro_rules! PROC_STILL_ALIVE { + () => { + -2 + }; +} + +#[no_mangle] +pub static mut pid_list: *mut proc_status = 0 as *mut proc_status; + +#[no_mangle] +pub static mut pid_list_size: libc::c_int = 0; +#[no_mangle] +pub static mut wait_sigint_received: libc::c_int = 0; +#[no_mangle] +pub static mut child_max: linc::c_long = -1; + +unsafe extern "C" fn alloc_pid_list() { + let mut i: libc::c_int; + let mut old: libc::c_int = pid_list_size; + + pid_list_size += 10; + pid_list = libc::realloc( + pid_list as *mut c_void, + (pid_list_size * size_of::() as libc::c_int) as usize, + ) as *mut proc_status; + + i = old; + while i < pid_list_size { + (*pid_list.offset(i as isize)).pid = NO_PID!(); + (*pid_list.offset(i as isize)).flags = 0; + (*pid_list.offset(i as isize)).status = 0; + i += 1; + } +} + +unsafe extern "C" fn find_proc_slot(pid: pid_t) -> libc::c_int { + let mut i: libc::c_int; + + i = 0; + while i < pid_list_size { + if (*pid_list.offset(i as isize)).pid == NO_PID!() + || (*pid_list.offset(i as isize)).pid == pid + { + return i; + } + i += 1; + } + + if i == pid_list_size { + alloc_pid_list(); + } + + return i; +} + +unsafe extern "C" fn find_index_by_pid(pid: pid_t) -> libc::c_int { + let mut i: libc::c_int; + + i = find_index_by_pid(pid); + if i == NO_PID!() { + return PROC_BAD!(); + } + + if (*pid_list.offset(i as isize)).flags & PROC_RUNNING!() != 0 { + return PROC_STILL_ALIVE!(); + } + + return (*pid_list.offset(i as isize)).status; +} + +unsafe extern "C" fn process_exit_status(status: WAIT) -> libc::c_int { + if WIFSIGNALED(status) { + return (128 + WTERMSIG(status)); + } else { + return WEXITSTATUS(status); + } +} + +unsafe extern "C" fn find_termsig_by_pid(pid: pid_t) -> libc::c_int { + let mut i: libc::c_int; + + i = find_index_by_pid(pid); + + if i == NO_PID!() { + return 0; + } + + if (*pid_list.offset(i as isize)).flags & PROC_RUNNING!() != 0 { + return 0; + } + + return get_termsig((*pid_list.offset(i as isize)).status as WAIT); +} + +unsafe extern "C" fn get_termsig(status: WAIT) -> libc::c_int { + if WIFSTOPPED(status) as libc::c_int == 0 && WIFSIGNALED(status) { + return WTERMSIG(status); + } else { + return 0; + } +} + +#[macro_export] +macro_rules! WSTATUS { + ($t:expr) => { + $t + }; +} + +unsafe extern "C" fn set_pid_status(pid: pid_t, status: WAIT) { + let mut slot: libc::c_int; + + coproc_pidchk(pid, status); + + slot = find_procsub_child(pid); + if slot >= 0 { + set_procsub_status(slot, pid, WSTATUS!(status)) + } + + slot = find_index_by_pid(pid); + if slot == NO_PID!() { + return; + } + + (*pid_list.offset(slot as isize)).status = process_exit_status(status); + (*pid_list.offset(slot as isize)).flags &= !PROC_SIGNALED!(); + + if WIFSIGNALED(status) { + (*pid_list.offset(slot as isize)).flags |= PROC_SIGNALED!(); + } + + if (*pid_list.offset(slot as isize)).flags & PROC_ASYNC!() == 0 { + (*pid_list.offset(slot as isize)).flags |= PROC_NOTIFIED!(); + } +} + +unsafe extern "C" fn set_pid_flags(pid: pid_t, flags: libc::c_int) { + let mut slot: libc::c_int; + + slot = find_index_by_pid(pid); + if slot == NO_PID!() { + return; + } + + (*pid_list.offset(slot as isize)).flags |= flags; +} + +unsafe extern "C" fn unset_pid_flags(pid: pid_t, flags: libc::c_int) { + let mut slot: libc::c_int; + + slot = find_index_by_pid(pid); + if slot == NO_PID!() { + return; + } + + (*pid_list.offset(slot as isize)).flags &= !flags; +} + +unsafe extern "C" fn get_pid_flags(pid: pid_t) -> libc::c_int { + let mut slot: libc::c_int; + slot = find_index_by_pid(pid); + if slot == NO_PID!() { + return 0; + } + return (*pid_list.offset(slot as isize)).flags; +} + +unsafe extern "C" fn add_pid(pid: pid_t, async_: libc::c_int) { + let mut slot: libc::c_int; + + slot = find_proc_slot(pid); + + (*pid_list.offset(slot as isize)).pid = pid; + (*pid_list.offset(slot as isize)).status = -1; + (*pid_list.offset(slot as isize)).flags = PROC_RUNNING!(); + + if async_ != 0 { + (*pid_list.offset(slot as isize)).flags |= PROC_ASYNC!(); + } +} + +unsafe extern "C" fn mark_dead_jobs_as_notified(force: libc::c_int) { + let mut i: libc::c_int; + let mut ndead: libc::c_int; + + i = 0; + ndead = 0; + while force == 0 && i < pid_list_size { + if (*pid_list.offset(i as isize)).pid == NO_PID!() { + continue; + } + + if (*pid_list.offset(i as isize)).flags & PROC_RUNNING!() == 0 + && (*pid_list.offset(i as isize)).flags & PROC_ASYNC!() != 0 + { + ndead += 1; + } + + i += 1; + } + + if child_max < 0 { + child_max = getmaxchild(); + } + if child_max < 0 { + child_max = DEFAULT_CHILD_MAX!(); + } + + if force == 0 && ndead <= child_max as libc::c_int { + return; + } + + i = 0; + while i < pid_list_size { + if (*pid_list.offset(i as isize)).pid == NO_PID!() { + continue; + } + if (*pid_list.offset(i as isize)).flags & PROC_RUNNING!() == 0 + && (*pid_list.offset(i as isize)).pid != last_asynchronous_pid + { + (*pid_list.offset(i as isize)).flags |= PROC_NOTIFIED!(); + + ndead -= 1; + if force == 0 + && (*pid_list.offset(i as isize)).flags & PROC_ASYNC!() != 0 + && ndead <= child_max as libc::c_int + { + break; + } + } + + i += 1; + } +} diff --git a/utshell-0.5.0/src/pathexp.rs b/utshell-0.5.0/src/pathexp.rs new file mode 100644 index 00000000..47a576f3 --- /dev/null +++ b/utshell-0.5.0/src/pathexp.rs @@ -0,0 +1,857 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +use crate::stringlib::substring; +use crate::subst::skip_to_delim; +use crate::variables::get_string_value; +use std::convert::TryInto; + +extern "C" { + fn strvec_sort(_: *mut *mut libc::c_char, _: libc::c_int); + static mut noglob_dot_filenames: libc::c_int; + fn glob_filename(_: *mut libc::c_char, _: libc::c_int) -> *mut *mut libc::c_char; +} + +#[inline] +fn is_basic(mut c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} + +#[no_mangle] +pub fn unquoted_glob_pattern_p(mut string: *mut libc::c_char) -> libc::c_int { + let mut c: libc::c_int = 0; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + let mut open: libc::c_int = 0; + let mut bsquote: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ); + bsquote = 0 as libc::c_int; + open = bsquote; + send = string.offset(libc::strlen(string) as isize); + loop { + let fresh0 = string; + string = string.offset(1); + c = *fresh0 as libc::c_int; + if !(c != 0) { + break; + } + match c { + // '?' | '*' + 63 | 42 => return 1 as libc::c_int, + // '[' + 91 => { + open += 1; + continue; + } + // ']' + 93 => { + if open != 0 { + return 1 as libc::c_int; + } + continue; + } + // '/' + 47 => { + if open != 0 { + open = 0 as libc::c_int; + } + if *string as libc::c_int == '(' as i32 { + return 1 as libc::c_int; + } + continue; + } + // '+' | '@' | '!' + 43 | 64 | 33 => { + if *string as libc::c_int == '(' as i32 { + return 1 as libc::c_int; + } + continue; + } + // '\\' + 92 => { + if *string as libc::c_int != '\u{0}' as i32 + && *string as libc::c_int != '/' as i32 + { + bsquote = 1 as libc::c_int; + string = string.offset(1); + continue; + } else if open != 0 && *string as libc::c_int == '/' as i32 { + string = string.offset(1); + continue; + } else if *string as libc::c_int == 0 as libc::c_int { + return 0 as libc::c_int; + } + let fresh1 = string; + string = string.offset(1); + if *fresh1 as libc::c_int == '\u{0}' as i32 { + return 0 as libc::c_int; + } + } + 1 => { + let fresh1 = string; + string = string.offset(1); + if *fresh1 as libc::c_int == '\u{0}' as i32 { + return 0 as libc::c_int; + } + } + _ => {} + } + + string = string.offset(-1); + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = + (*string as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string, + send.offset_from(string) as libc::c_long as size_t, + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + string = string.offset( + (if mblength < 1 as libc::c_int as libc::c_ulong { + 0 as libc::c_int as libc::c_ulong + } else { + mblength.wrapping_sub(1 as libc::c_int as libc::c_ulong) + }) as isize, + ); + } + } + string = string.offset(1); + } + } + return 0 as libc::c_int; +} +#[inline] +fn ere_char(mut c: libc::c_int) -> libc::c_int { + match c as u8 as char { + '.' | '[' | '\\' | '(' | ')' | '*' | '+' | '?' | '{' | '|' | '^' | '$' => { + return 1 as libc::c_int; + } + _ => return 0 as libc::c_int, + }; +} +#[no_mangle] +pub fn glob_char_p(mut s: *const libc::c_char) -> libc::c_int { + unsafe { + match *s as libc::c_int as u8 as char { + '*' | '[' | ']' | '?' | '\\' => return 1 as libc::c_int, + '+' | '@' | '!' => { + if *s.offset(1 as libc::c_int as isize) as libc::c_int == '(' as i32 { + return 1 as libc::c_int; + } + } + _ => {} + } + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn quote_string_for_globbing( + mut pathname: *const libc::c_char, + mut qflags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut cclass: libc::c_int = 0; + let mut collsym: libc::c_int = 0; + let mut equiv: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut last_was_backslash: libc::c_int = 0; + let mut savei: libc::c_int = 0; + let mut savej: libc::c_int = 0; + + temp = libc::malloc( + (2 as libc::c_int as libc::c_ulong) + .wrapping_mul(libc::strlen(pathname) as u64) + .wrapping_add(1 as libc::c_int as libc::c_ulong) as usize, + ) as *mut libc::c_char; + + if qflags & QGLOB_CVTNULL as libc::c_int != 0 + && (*pathname.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *pathname.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + { + *temp.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + return temp; + } + + last_was_backslash = 0 as libc::c_int; + equiv = last_was_backslash; + collsym = equiv; + cclass = collsym; + j = 0 as libc::c_int; + i = j; + + while *pathname.offset(i as isize) != 0 { + if *pathname.offset(i as isize) as libc::c_int == CTLESC as i32 + && *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '\u{0}' as i32 + { + let fresh2 = i; + i = i + 1; + let fresh3 = j; + j = j + 1; + *temp.offset(fresh3 as isize) = *pathname.offset(fresh2 as isize); + break; + } else if qflags & (QGLOB_REGEXP as libc::c_int | QGLOB_CTLESC as libc::c_int) != 0 + && *pathname.offset(i as isize) as libc::c_int == CTLESC as i32 + && (*pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == CTLESC as i32 + || *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == CTLNUL as i32) + { + i += 1; + let fresh4 = j; + j = j + 1; + *temp.offset(fresh4 as isize) = *pathname.offset(i as isize); + i += 1; + continue; + } else if *pathname.offset(i as isize) as libc::c_int == CTLESC as i32 { + //convert_to_backslash + if qflags & QGLOB_FILENAME as libc::c_int != 0 + && *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '/' as i32 + { + i += 1; + continue; + } + if *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int != CTLESC as i32 + && qflags & QGLOB_REGEXP as libc::c_int != 0 + && ere_char(*pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int) + == 0 as libc::c_int + { + i += 1; + continue; + } + let fresh41 = j; + j = j + 1; + *temp.offset(fresh41 as isize) = '\\' as i32 as libc::c_char; + i += 1; + if *pathname.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } + } else if qflags & QGLOB_REGEXP as libc::c_int != 0 + && (i == 0 as libc::c_int + || *pathname.offset((i - 1 as libc::c_int) as isize) as libc::c_int + != '\u{1}' as i32) + && *pathname.offset(i as isize) as libc::c_int == '[' as i32 + { + let fresh6 = i; + i = i + 1; + let fresh7 = j; + j = j + 1; + *temp.offset(fresh7 as isize) = *pathname.offset(fresh6 as isize); + savej = j; + savei = i; + let fresh8 = i; + i = i + 1; + c = *pathname.offset(fresh8 as isize) as libc::c_int; + if c == '^' as i32 { + let fresh9 = j; + j = j + 1; + *temp.offset(fresh9 as isize) = c as libc::c_char; + let fresh10 = i; + i = i + 1; + c = *pathname.offset(fresh10 as isize) as libc::c_int; + } + if c == ']' as i32 { + let fresh11 = j; + j = j + 1; + *temp.offset(fresh11 as isize) = c as libc::c_char; + let fresh12 = i; + i = i + 1; + c = *pathname.offset(fresh12 as isize) as libc::c_int; + } + + loop { + if c == 0 as libc::c_int { + *temp.offset(j as isize) = '\0' as i32 as libc::c_char; + return temp; + } else if c == '\u{1}' as i32 { + if *pathname.offset(i as isize) as libc::c_int == 0 as libc::c_int { + *temp.offset(j as isize) = '\0' as i32 as libc::c_char; + return temp; + } + let fresh13 = i; + i = i + 1; + let fresh14 = j; + j = j + 1; + *temp.offset(fresh14 as isize) = *pathname.offset(fresh13 as isize); + } else if c == '[' as i32 + && *pathname.offset(i as isize) as libc::c_int == ':' as i32 + { + let fresh15 = j; + j = j + 1; + *temp.offset(fresh15 as isize) = c as libc::c_char; + let fresh16 = i; + i = i + 1; + let fresh17 = j; + j = j + 1; + *temp.offset(fresh17 as isize) = *pathname.offset(fresh16 as isize); + cclass = 1 as libc::c_int; + } else if cclass != 0 + && c == ':' as i32 + && *pathname.offset(i as isize) as libc::c_int == ']' as i32 + { + let fresh18 = j; + j = j + 1; + *temp.offset(fresh18 as isize) = c as libc::c_char; + let fresh19 = i; + i = i + 1; + let fresh20 = j; + j = j + 1; + *temp.offset(fresh20 as isize) = *pathname.offset(fresh19 as isize); + cclass = 0 as libc::c_int; + } else if c == '[' as i32 + && *pathname.offset(i as isize) as libc::c_int == '=' as i32 + { + let fresh21 = j; + j = j + 1; + *temp.offset(fresh21 as isize) = c as libc::c_char; + let fresh22 = i; + i = i + 1; + let fresh23 = j; + j = j + 1; + *temp.offset(fresh23 as isize) = *pathname.offset(fresh22 as isize); + if *pathname.offset(i as isize) as libc::c_int == ']' as i32 { + let fresh24 = i; + i = i + 1; + let fresh25 = j; + j = j + 1; + *temp.offset(fresh25 as isize) = *pathname.offset(fresh24 as isize); + } + equiv = 1 as libc::c_int; + } else if equiv != 0 + && c == '=' as i32 + && *pathname.offset(i as isize) as libc::c_int == ']' as i32 + { + let fresh26 = j; + j = j + 1; + *temp.offset(fresh26 as isize) = c as libc::c_char; + let fresh27 = i; + i = i + 1; + let fresh28 = j; + j = j + 1; + *temp.offset(fresh28 as isize) = *pathname.offset(fresh27 as isize); + equiv = 0 as libc::c_int; + } else if c == '[' as i32 + && *pathname.offset(i as isize) as libc::c_int == '.' as i32 + { + let fresh29 = j; + j = j + 1; + *temp.offset(fresh29 as isize) = c as libc::c_char; + let fresh30 = i; + i = i + 1; + let fresh31 = j; + j = j + 1; + *temp.offset(fresh31 as isize) = *pathname.offset(fresh30 as isize); + if *pathname.offset(i as isize) as libc::c_int == ']' as i32 { + let fresh32 = i; + i = i + 1; + let fresh33 = j; + j = j + 1; + *temp.offset(fresh33 as isize) = *pathname.offset(fresh32 as isize); + } + collsym = 1 as libc::c_int; + } else if collsym != 0 + && c == '.' as i32 + && *pathname.offset(i as isize) as libc::c_int == ']' as i32 + { + let fresh34 = j; + j = j + 1; + *temp.offset(fresh34 as isize) = c as libc::c_char; + let fresh35 = i; + i = i + 1; + let fresh36 = j; + j = j + 1; + *temp.offset(fresh36 as isize) = *pathname.offset(fresh35 as isize); + collsym = 0 as libc::c_int; + } else { + let fresh37 = j; + j = j + 1; + *temp.offset(fresh37 as isize) = c as libc::c_char; + } + let fresh38 = i; + i = i + 1; + c = *pathname.offset(fresh38 as isize) as libc::c_int; + if !(c != ']' as i32 && c != 0 as libc::c_int) { + break; + } + } + + if c == 0 as libc::c_int { + i = savei - 1 as libc::c_int; + j = savej; + i += 1; + continue; + } + let fresh39 = j; + j = j + 1; + *temp.offset(fresh39 as isize) = c as libc::c_char; + i -= 1; + i += 1; + continue; + } else if *pathname.offset(i as isize) as libc::c_int == '\\' as i32 + && qflags & QGLOB_REGEXP as libc::c_int == 0 as libc::c_int + { + let fresh40 = j; + j = j + 1; + *temp.offset(fresh40 as isize) = '\\' as i32 as libc::c_char; + i += 1; + if *pathname.offset(i as isize) as libc::c_int == '\0' as i32 { + break; + } + if qflags & QGLOB_CTLESC as libc::c_int != 0 + && *pathname.offset(i as isize) as libc::c_int == CTLESC as i32 + && (*pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == CTLESC as i32 + || *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == CTLNUL as i32) + { + i += 1; + } else if qflags & QGLOB_CTLESC as libc::c_int != 0 + && *pathname.offset(i as isize) as libc::c_int == CTLESC as i32 + { + //goto convert_to_backslash + if qflags & QGLOB_FILENAME as libc::c_int != 0 + && *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '/' as i32 + { + i += 1; + continue; + } + if *pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int + != CTLESC as i32 + && qflags & QGLOB_REGEXP as libc::c_int != 0 + && ere_char(*pathname.offset((i + 1 as libc::c_int) as isize) as libc::c_int) + == 0 as libc::c_int + { + i += 1; + continue; + } + let fresh41 = j; + j = j + 1; + *temp.offset(fresh41 as isize) = '\\' as i32 as libc::c_char; + i += 1; + if *pathname.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } + } else if *pathname.offset(i as isize) as libc::c_int == '\\' as i32 + && qflags & QGLOB_REGEXP as libc::c_int != 0 + { + last_was_backslash = 1 as libc::c_int; + } + } + let fresh41 = j; + j = j + 1; + *temp.offset(fresh41 as isize) = *pathname.offset(i as isize); + i += 1; + } + + *temp.offset(j as isize) = '\u{0}' as i32 as libc::c_char; + return temp; + } +} + +#[no_mangle] +pub fn quote_globbing_chars(mut string: *const libc::c_char) -> *mut libc::c_char { + unsafe { + let mut slen: size_t = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *const libc::c_char = 0 as *const libc::c_char; + let mut send: *const libc::c_char = 0 as *const libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as libc::c_ulong as usize, + ); + slen = libc::strlen(string) as u64; + send = string.offset(slen as isize); + temp = libc::malloc( + slen.wrapping_mul(2 as libc::c_int as libc::c_ulong) + .wrapping_add(1 as libc::c_int as libc::c_ulong) as usize, + ) as *mut libc::c_char; + t = temp; + s = string; + while *s != 0 { + if glob_char_p(s) != 0 { + let fresh42 = t; + t = t.offset(1); + *fresh42 = '\\' as i32 as libc::c_char; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*s); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = (*s as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen(s, send.offset_from(s) as libc::c_long as size_t, &mut state); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh43 = s; + s = s.offset(1); + let fresh44 = t; + t = t.offset(1); + *fresh44 = *fresh43; + _k += 1; + } + } else { + let fresh45 = s; + s = s.offset(1); + let fresh46 = t; + t = t.offset(1); + *fresh46 = *fresh45; + } + } + *t = '\u{0}' as i32 as libc::c_char; + return temp; + } +} +#[no_mangle] +pub fn shell_glob_filename( + mut pathname: *const libc::c_char, + mut qflags: libc::c_int, +) -> *mut *mut libc::c_char { + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut results: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut gflags: libc::c_int = 0; + let mut quoted_pattern: libc::c_int = 0; + noglob_dot_filenames = (glob_dot_filenames == 0 as libc::c_int) as libc::c_int; + temp = quote_string_for_globbing(pathname, 0x2 as libc::c_int | qflags); + gflags = if glob_star != 0 { + 0x400 as libc::c_int + } else { + 0 as libc::c_int + }; + results = glob_filename(temp, gflags); + libc::free(temp as *mut libc::c_void); + if !results.is_null() + && (results == &mut glob_error_return as *mut *mut libc::c_char) as libc::c_int + == 0 as libc::c_int + { + if should_ignore_glob_matches() != 0 { + ignore_glob_matches(results); + } + if !results.is_null() && !(*results.offset(0 as libc::c_int as isize)).is_null() { + strvec_sort(results, 1 as libc::c_int); + } else { + if !results.is_null() { + libc::free(results as *mut libc::c_void); + } + results = &mut glob_error_return as *mut *mut libc::c_char; + } + } + return results; + } +} +static mut globignore: ignorevar = { + let mut init = ignorevar { + varname: b"GLOBIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ignores: 0 as *const ign as *mut ign, + num_ignores: 0 as libc::c_int, + last_ignoreval: 0 as *const libc::c_char as *mut libc::c_char, + item_func: None, + }; + init +}; +#[no_mangle] +pub fn setup_glob_ignore(mut name: *mut libc::c_char) { + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + v = get_string_value(name); + setup_ignore_patterns(&mut globignore); + if globignore.num_ignores != 0 { + glob_dot_filenames = 1 as libc::c_int; + } else if v.is_null() { + glob_dot_filenames = 0 as libc::c_int; + } + } +} +#[no_mangle] +pub fn should_ignore_glob_matches() -> libc::c_int { + unsafe { + return globignore.num_ignores; + } +} +fn glob_name_is_acceptable(mut name: *const libc::c_char) -> libc::c_int { + let mut p: *mut ign = 0 as *mut ign; + let mut n: *mut libc::c_char = 0 as *mut libc::c_char; + let mut flags: libc::c_int = 0; + unsafe { + n = libc::strrchr(name, '/' as i32); + if n.is_null() || *n.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int { + n = name as *mut libc::c_char; + } else { + n = n.offset(1); + } + if *n.offset(0 as libc::c_int as isize) as libc::c_int == '.' as i32 + && (*n.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *n.offset(1 as libc::c_int as isize) as libc::c_int == '.' as i32 + && *n.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + { + return 0 as libc::c_int; + } + flags = (1 as libc::c_int) << 0 as libc::c_int + | (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) + | (if glob_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }); + p = globignore.ignores; + while !((*p).val).is_null() { + if strmatch((*p).val, name as *mut libc::c_char, flags) != 1 as libc::c_int { + return 0 as libc::c_int; + } + p = p.offset(1); + } + } + return 1 as libc::c_int; +} +fn ignore_globbed_names( + mut names: *mut *mut libc::c_char, + mut name_func: Option, +) { + unsafe { + let mut newnames: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut n: libc::c_int = 0; + let mut i: libc::c_int = 0; + i = 0 as libc::c_int; + while !(*names.offset(i as isize)).is_null() { + i += 1; + } + + newnames = strvec_create(i + 1 as libc::c_int); + i = 0 as libc::c_int; + n = i; + while !(*names.offset(i as isize)).is_null() { + if (Some(name_func.expect("non-null function pointer"))) + .expect("non-null function pointer")(*names.offset(i as isize)) + != 0 + { + let fresh47 = n; + n = n + 1; + let ref mut fresh48 = *newnames.offset(fresh47 as isize); + *fresh48 = *names.offset(i as isize); + } else { + libc::free(*names.offset(i as isize) as *mut libc::c_void); + } + i += 1; + } + let ref mut fresh49 = *newnames.offset(n as isize); + *fresh49 = 0 as *mut libc::c_void as *mut libc::c_char; + if n == 0 as libc::c_int { + let ref mut fresh50 = *names.offset(0 as libc::c_int as isize); + *fresh50 = 0 as *mut libc::c_void as *mut libc::c_char; + libc::free(newnames as *mut libc::c_void); + return; + } + n = 0 as libc::c_int; + while !(*newnames.offset(n as isize)).is_null() { + let ref mut fresh51 = *names.offset(n as isize); + *fresh51 = *newnames.offset(n as isize); + n += 1; + } + let ref mut fresh52 = *names.offset(n as isize); + *fresh52 = 0 as *mut libc::c_void as *mut libc::c_char; + libc::free(newnames as *mut libc::c_void); + } +} +#[no_mangle] +pub fn ignore_glob_matches(mut names: *mut *mut libc::c_char) { + unsafe { + if globignore.num_ignores == 0 as libc::c_int { + return; + } + ignore_globbed_names( + names, + ::std::mem::transmute:: libc::c_int>, Option>(Some( + ::std::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + glob_name_is_acceptable, + ), + )), + ); + } +} +fn split_ignorespec(mut s: *mut libc::c_char, mut ip: *mut libc::c_int) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut n: libc::c_int = 0; + let mut i: libc::c_int = 0; + if s.is_null() { + return 0 as *mut libc::c_char; + } + unsafe { + i = *ip; + if *s.offset(i as isize) as libc::c_int == 0 as libc::c_int { + return 0 as *mut libc::c_char; + } + n = skip_to_delim( + s, + i, + b":\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + SD_NOJMP as libc::c_int | SD_EXTGLOB as libc::c_int | SD_GLOB as libc::c_int, + ); + t = substring(s, i, n); + if *s.offset(n as isize) as libc::c_int == ':' as i32 { + n += 1; + } + *ip = n; + } + return t; +} +#[no_mangle] +pub fn setup_ignore_patterns(mut ivp: *mut ignorevar) { + let mut numitems: libc::c_int = 0; + let mut maxitems: libc::c_int = 0; + let mut ptr: libc::c_int = 0; + let mut colon_bit: *mut libc::c_char = 0 as *mut libc::c_char; + let mut this_ignoreval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut ign = 0 as *mut ign; + unsafe { + this_ignoreval = get_string_value((*ivp).varname); + if !this_ignoreval.is_null() + && !((*ivp).last_ignoreval).is_null() + && (*this_ignoreval.offset(0 as libc::c_int as isize) as libc::c_int + == *((*ivp).last_ignoreval).offset(0 as libc::c_int as isize) as libc::c_int + && libc::strcmp(this_ignoreval, (*ivp).last_ignoreval) == 0 as libc::c_int) + || this_ignoreval.is_null() && ((*ivp).last_ignoreval).is_null() + { + return; + } + (*ivp).num_ignores = 0 as libc::c_int; + if !((*ivp).ignores).is_null() { + p = (*ivp).ignores; + while !((*p).val).is_null() { + libc::free((*p).val as *mut libc::c_void); + p = p.offset(1); + } + libc::free((*ivp).ignores as *mut libc::c_void); + let ref mut fresh53 = (*ivp).ignores; + *fresh53 = 0 as *mut libc::c_void as *mut ign; + } + if !((*ivp).last_ignoreval).is_null() { + libc::free((*ivp).last_ignoreval as *mut libc::c_void); + let ref mut fresh54 = (*ivp).last_ignoreval; + *fresh54 = 0 as *mut libc::c_void as *mut libc::c_char; + } + if this_ignoreval.is_null() || *this_ignoreval as libc::c_int == '\u{0}' as i32 { + return; + } + let ref mut fresh55 = (*ivp).last_ignoreval; + *fresh55 = libc::strcpy( + libc::malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(libc::strlen(this_ignoreval) as u64) as usize, + ) as *mut libc::c_char, + this_ignoreval, + ); + ptr = 0 as libc::c_int; + maxitems = ptr; + numitems = maxitems; + loop { + colon_bit = split_ignorespec(this_ignoreval, &mut ptr); + if colon_bit.is_null() { + break; + } + if numitems + 1 as libc::c_int >= maxitems { + maxitems += 10 as libc::c_int; + let ref mut fresh56 = (*ivp).ignores; + *fresh56 = libc::realloc( + (*ivp).ignores as *mut libc::c_void, + (maxitems as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as usize, + ) as *mut ign; + } + let ref mut fresh57 = (*((*ivp).ignores).offset(numitems as isize)).val; + *fresh57 = colon_bit; + (*((*ivp).ignores).offset(numitems as isize)).len = + libc::strlen(colon_bit) as libc::c_int; + (*((*ivp).ignores).offset(numitems as isize)).flags = 0 as libc::c_int; + if ((*ivp).item_func).is_some() { + (Some(((*ivp).item_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + &mut *((*ivp).ignores).offset(numitems as isize), + ); + } + numitems += 1; + } + let ref mut fresh58 = (*((*ivp).ignores).offset(numitems as isize)).val; + *fresh58 = 0 as *mut libc::c_void as *mut libc::c_char; + (*ivp).num_ignores = numitems; + } +} diff --git a/utshell-0.5.0/src/pcomplete.rs b/utshell-0.5.0/src/pcomplete.rs new file mode 100644 index 00000000..5b2cb240 --- /dev/null +++ b/utshell-0.5.0/src/pcomplete.rs @@ -0,0 +1,2278 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +use crate::unwind_prot::begin_unwind_frame; +use std::convert::TryInto; + +use crate::unwind_prot::add_unwind_protect; + +use crate::alias::{all_aliases, find_alias}; +use crate::array::array_to_argv; +use crate::arrayfunc::{assign_array_var_from_word_list, convert_var_to_array}; +use crate::bashline::{ + bash_dequote_text, bash_directory_completion_matches, bash_groupname_completion_function, + bash_servicename_completion_function, command_word_completion_function, get_hostname_list, +}; +use crate::builtins::{complete::compgen_builtin, set::get_minus_o_opts, shopt::get_shopt_options}; +use crate::copycmd::copy_word; +use crate::dispose_cmd::{dispose_word_desc, dispose_words}; +use crate::execute_cmd::execute_shell_function; +use crate::list::list_length; +use crate::make_cmd::{make_bare_word, make_word, make_word_list}; +use crate::pathexp::shell_glob_filename; +use crate::pcomplib::{compspec_copy, compspec_create, compspec_dispose, progcomp_search}; +use crate::readline::{ + rl_completer_word_break_characters, rl_completion_found_quote, rl_completion_invoking_key, + rl_completion_mark_symlink_dirs, rl_completion_matches, rl_completion_quote_character, + rl_completion_suppress_append, rl_completion_type, rl_ding, rl_filename_completion_desired, + rl_filename_dequoting_function, rl_funmap_names, rl_line_buffer, rl_on_new_line, rl_point, + rl_readline_state, rl_sort_completion_matches, rl_username_completion_function, +}; +use crate::stringlib::{strcreplace, substring}; +use crate::subst::{command_substitute, expand_words_shellexp, skip_to_delim, split_at_delims}; +use crate::unwind_prot::discard_unwind_frame; +use crate::variables::{ + all_array_variables, all_exported_variables, all_visible_functions, all_visible_variables, + bind_int_variable, bind_variable, find_function, find_variable_noref, make_new_array_variable, + unbind_variable_noref, +}; +use crate::y_tab::{restore_parser_state, save_parser_state, word_token_alist}; + +pub union Functions { + restore_parser_state: unsafe extern "C" fn(*mut sh_parser_state_t) -> (), + dispose_words: unsafe extern "C" fn(*mut WORD_LIST) -> (), + unbind_compfunc_variables: unsafe extern "C" fn(libc::c_int) -> (), +} + +pub type SVFUNC = fn() -> *mut *mut SHELL_VAR; + +pub type rl_dequote_func_t = fn(*mut libc::c_char, libc::c_int) -> *mut libc::c_char; + +#[no_mangle] +pub static mut prog_completion_enabled: libc::c_int = 1; + +#[no_mangle] +pub static mut progcomp_alias: libc::c_int = 0 as libc::c_int; + +#[no_mangle] +pub static mut it_aliases: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_aliases), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; + +#[no_mangle] +pub static mut it_arrayvars: ITEMLIST = { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_arrayvars), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_bindings: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_bindings), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_builtins: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_builtins), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_disabled: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_disabled), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_enabled: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_enabled), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_exports: ITEMLIST = { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_exported), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_functions: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_functions), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_helptopics: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_helptopics), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_hostnames: ITEMLIST = { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_hostnames), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_jobs: ITEMLIST = { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_jobs), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_keywords: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_keywords), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_running: ITEMLIST = { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_running), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_setopts: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_setopts), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_shopts: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_shopts), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_signals: ITEMLIST = { + { + let mut init = _list_of_items { + flags: 0 as libc::c_int, + list_getter: Some(it_init_signals), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } +}; +#[no_mangle] +pub static mut it_stopped: ITEMLIST = { + unsafe { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_stopped), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } + } +}; +#[no_mangle] +pub static mut it_variables: ITEMLIST = { + unsafe { + { + let mut init = _list_of_items { + flags: LIST_DYNAMIC as libc::c_int, + list_getter: Some(it_init_variables), + slist: 0 as *const STRINGLIST as *mut STRINGLIST, + genlist: 0 as *const STRINGLIST as *mut STRINGLIST, + genindex: 0, + }; + init + } + } +}; +#[no_mangle] +pub static mut pcomp_curcs: *mut COMPSPEC = 0 as *const COMPSPEC as *mut COMPSPEC; +#[no_mangle] +pub static mut pcomp_curcmd: *const libc::c_char = 0 as *const libc::c_char; +#[no_mangle] +pub static mut pcomp_curtxt: *const libc::c_char = 0 as *const libc::c_char; +#[no_mangle] +pub static mut pcomp_line: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut pcomp_ind: libc::c_int = 0; +#[no_mangle] +pub fn set_itemlist_dirty(mut it: *mut ITEMLIST) { + unsafe { + (*it).flags |= LIST_DIRTY as libc::c_int; + } +} +#[no_mangle] +pub fn initialize_itemlist(mut itp: *mut ITEMLIST) { + unsafe { + (Some(((*itp).list_getter).expect("non-null function pointer"))) + .expect("non-null function pointer")(itp); + (*itp).flags |= LIST_INITIALIZED as libc::c_int; + (*itp).flags &= !(LIST_DIRTY as libc::c_int); + } +} +#[no_mangle] +pub fn clean_itemlist(mut itp: *mut ITEMLIST) { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + sl = (*itp).slist; + if !sl.is_null() { + if (*itp).flags & (0x20 as libc::c_int | 0x10 as libc::c_int) == 0 as libc::c_int { + strvec_flush((*sl).list); + } + if (*itp).flags & 0x10 as libc::c_int == 0 as libc::c_int { + free((*sl).list as *mut libc::c_void); + } + free(sl as *mut libc::c_void); + } + let ref mut fresh0 = (*itp).slist; + *fresh0 = 0 as *mut libc::c_void as *mut STRINGLIST; + (*itp).flags &= !(0x10 as libc::c_int + | 0x20 as libc::c_int + | LIST_INITIALIZED as libc::c_int + | LIST_DIRTY as libc::c_int); + } +} +#[no_mangle] +fn shouldexp_filterpat(mut s: *mut libc::c_char) -> libc::c_int { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + p = s; + unsafe { + while !p.is_null() && *p as libc::c_int != 0 { + if *p as libc::c_int == '\\' as i32 { + p = p.offset(1); + } else if *p as libc::c_int == '&' as i32 { + return 1 as libc::c_int; + } + p = p.offset(1); + } + } + return 0 as libc::c_int; +} +#[no_mangle] +fn preproc_filterpat( + mut pat: *mut libc::c_char, + mut text: *const libc::c_char, +) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + ret = strcreplace(pat, '&' as i32, text, 1 as libc::c_int); + return ret; + } +} +#[no_mangle] +pub fn filter_stringlist( + mut sl: *mut STRINGLIST, + mut filterpat: *mut libc::c_char, + mut text: *const libc::c_char, +) -> *mut STRINGLIST { + unsafe { + let mut i: libc::c_int = 0; + let mut m: libc::c_int = 0; + let mut not: libc::c_int = 0; + let mut ret: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut npat: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + if sl.is_null() || ((*sl).list).is_null() || (*sl).list_len == 0 as libc::c_int { + return sl; + } + npat = if shouldexp_filterpat(filterpat) != 0 { + preproc_filterpat(filterpat, text) + } else { + filterpat + }; + not = (*npat.offset(0 as libc::c_int as isize) as libc::c_int == '!' as i32 + && (extended_glob == 0 as libc::c_int + || *npat.offset(1 as libc::c_int as isize) as libc::c_int != '(' as i32)) + as libc::c_int; + t = if not != 0 { + npat.offset(1 as libc::c_int as isize) + } else { + npat + }; + ret = strlist_create((*sl).list_size); + i = 0 as libc::c_int; + while i < (*sl).list_len { + m = strmatch( + t, + *((*sl).list).offset(i as isize), + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ); + if not != 0 && m == 1 as libc::c_int || not == 0 as libc::c_int && m != 1 as libc::c_int + { + free(*((*sl).list).offset(i as isize) as *mut libc::c_void); + } else { + let ref mut fresh1 = (*ret).list_len; + let fresh2 = *fresh1; + *fresh1 = *fresh1 + 1; + let ref mut fresh3 = *((*ret).list).offset(fresh2 as isize); + *fresh3 = *((*sl).list).offset(i as isize); + } + i += 1; + } + let ref mut fresh4 = *((*ret).list).offset((*ret).list_len as isize); + *fresh4 = 0 as *mut libc::c_void as *mut libc::c_char; + if npat != filterpat { + free(npat as *mut libc::c_void); + } + return ret; + } +} +#[no_mangle] +pub fn completions_to_stringlist(mut matches: *mut *mut libc::c_char) -> *mut STRINGLIST { + unsafe { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut mlen: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + mlen = if matches.is_null() { + 0 as libc::c_int + } else { + strvec_len(matches) + }; + sl = strlist_create(mlen + 1 as libc::c_int); + if matches.is_null() || (*matches.offset(0 as libc::c_int as isize)).is_null() { + return sl; + } + if (*matches.offset(1 as libc::c_int as isize)).is_null() { + let ref mut fresh5 = *((*sl).list).offset(0 as libc::c_int as isize); + *fresh5 = if !(*matches.offset(0 as libc::c_int as isize)).is_null() { + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(*matches.offset(0 as libc::c_int as isize)) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + *matches.offset(0 as libc::c_int as isize), + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + let ref mut fresh6 = (*sl).list_len; + *fresh6 = 1 as libc::c_int; + let ref mut fresh7 = *((*sl).list).offset(*fresh6 as isize); + *fresh7 = 0 as *mut libc::c_void as *mut libc::c_char; + return sl; + } + i = 1 as libc::c_int; + n = 0 as libc::c_int; + while i < mlen { + let ref mut fresh8 = *((*sl).list).offset(n as isize); + *fresh8 = if !(*matches.offset(i as isize)).is_null() { + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(*matches.offset(i as isize)) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + *matches.offset(i as isize), + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + i += 1; + n += 1; + } + (*sl).list_len = n; + let ref mut fresh9 = *((*sl).list).offset(n as isize); + *fresh9 = 0 as *mut libc::c_void as *mut libc::c_char; + return sl; + } +} +#[no_mangle] +fn it_init_aliases(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut alias_list: *mut *mut alias_t = 0 as *mut *mut alias_t; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + alias_list = all_aliases(); + if alias_list.is_null() { + let ref mut fresh10 = (*itp).slist; + *fresh10 = 0 as *mut libc::c_void as *mut STRINGLIST; + return 0 as libc::c_int; + } + n = 0 as libc::c_int; + while !(*alias_list.offset(n as isize)).is_null() { + n += 1; + } + sl = strlist_create(n + 1 as libc::c_int); + i = 0 as libc::c_int; + while i < n { + let ref mut fresh11 = *((*sl).list).offset(i as isize); + *fresh11 = if !((**alias_list.offset(i as isize)).name).is_null() { + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((**alias_list.offset(i as isize)).name) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + (**alias_list.offset(i as isize)).name, + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + i += 1; + } + let ref mut fresh12 = *((*sl).list).offset(n as isize); + *fresh12 = 0 as *mut libc::c_void as *mut libc::c_char; + let ref mut fresh13 = (*sl).list_len; + *fresh13 = n; + (*sl).list_size = *fresh13; + let ref mut fresh14 = (*itp).slist; + *fresh14 = sl; + free(alias_list as *mut libc::c_void); + } + return 1 as libc::c_int; +} +#[no_mangle] +fn init_itemlist_from_varlist(mut itp: *mut ITEMLIST, mut svfunc: Option) { + let mut vlist: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + unsafe { + vlist = ::std::mem::transmute::<_, fn() -> *mut *mut SHELL_VAR>( + (Some(svfunc.expect("non-null function pointer"))).expect("non-null function pointer"), + )(); + if vlist.is_null() { + let ref mut fresh15 = (*itp).slist; + *fresh15 = 0 as *mut libc::c_void as *mut STRINGLIST; + return; + } + n = 0 as libc::c_int; + while !(*vlist.offset(n as isize)).is_null() { + n += 1; + } + sl = strlist_create(n + 1 as libc::c_int); + i = 0 as libc::c_int; + while i < n { + let ref mut fresh16 = *((*sl).list).offset(i as isize); + *fresh16 = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((**vlist.offset(i as isize)).name) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + (**vlist.offset(i as isize)).name, + ); + i += 1; + } + let ref mut fresh17 = (*sl).list_len; + *fresh17 = n; + let ref mut fresh18 = *((*sl).list).offset(*fresh17 as isize); + *fresh18 = 0 as *mut libc::c_void as *mut libc::c_char; + let ref mut fresh19 = (*itp).slist; + *fresh19 = sl; + } +} +#[no_mangle] +fn it_init_arrayvars(mut itp: *mut ITEMLIST) -> libc::c_int { + unsafe { + init_itemlist_from_varlist( + itp, + ::std::mem::transmute:: *mut *mut SHELL_VAR>, Option>(Some( + all_array_variables, + )), + ); + } + return 1 as libc::c_int; +} +#[no_mangle] +fn it_init_bindings(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut blist: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + blist = rl_funmap_names() as *mut *mut libc::c_char; + sl = strlist_create(0 as libc::c_int); + let ref mut fresh20 = (*sl).list; + *fresh20 = blist; + (*sl).list_size = 0 as libc::c_int; + (*sl).list_len = strvec_len((*sl).list); + (*itp).flags |= 0x20 as libc::c_int; + let ref mut fresh21 = (*itp).slist; + *fresh21 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_builtins(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + unsafe { + sl = strlist_create(num_shell_builtins); + n = 0 as libc::c_int; + i = n; + while i < num_shell_builtins { + if ((*shell_builtins.offset(i as isize)).function).is_some() { + let fresh22 = n; + n = n + 1; + let ref mut fresh23 = *((*sl).list).offset(fresh22 as isize); + *fresh23 = (*shell_builtins.offset(i as isize)).name; + } + i += 1; + } + let ref mut fresh24 = (*sl).list_len; + *fresh24 = n; + let ref mut fresh25 = *((*sl).list).offset(*fresh24 as isize); + *fresh25 = 0 as *mut libc::c_void as *mut libc::c_char; + (*itp).flags |= 0x20 as libc::c_int; + let ref mut fresh26 = (*itp).slist; + *fresh26 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_enabled(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + unsafe { + sl = strlist_create(num_shell_builtins); + n = 0 as libc::c_int; + i = n; + while i < num_shell_builtins { + if ((*shell_builtins.offset(i as isize)).function).is_some() + && (*shell_builtins.offset(i as isize)).flags & LIST_DYNAMIC as libc::c_int != 0 + { + let fresh27 = n; + n = n + 1; + let ref mut fresh28 = *((*sl).list).offset(fresh27 as isize); + *fresh28 = (*shell_builtins.offset(i as isize)).name; + } + i += 1; + } + let ref mut fresh29 = (*sl).list_len; + *fresh29 = n; + let ref mut fresh30 = *((*sl).list).offset(*fresh29 as isize); + *fresh30 = 0 as *mut libc::c_void as *mut libc::c_char; + (*itp).flags |= 0x20 as libc::c_int; + let ref mut fresh31 = (*itp).slist; + *fresh31 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_disabled(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + unsafe { + sl = strlist_create(num_shell_builtins); + n = 0 as libc::c_int; + i = n; + while i < num_shell_builtins { + if ((*shell_builtins.offset(i as isize)).function).is_some() + && (*shell_builtins.offset(i as isize)).flags & LIST_DYNAMIC as libc::c_int + == 0 as libc::c_int + { + let fresh32 = n; + n = n + 1; + let ref mut fresh33 = *((*sl).list).offset(fresh32 as isize); + *fresh33 = (*shell_builtins.offset(i as isize)).name; + } + i += 1; + } + let ref mut fresh34 = (*sl).list_len; + *fresh34 = n; + let ref mut fresh35 = *((*sl).list).offset(*fresh34 as isize); + *fresh35 = 0 as *mut libc::c_void as *mut libc::c_char; + (*itp).flags |= 0x20 as libc::c_int; + let ref mut fresh36 = (*itp).slist; + *fresh36 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_exported(mut itp: *mut ITEMLIST) -> libc::c_int { + unsafe { + init_itemlist_from_varlist( + itp, + ::std::mem::transmute:: *mut *mut SHELL_VAR>, Option>(Some( + all_exported_variables, + )), + ); + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_functions(mut itp: *mut ITEMLIST) -> libc::c_int { + unsafe { + init_itemlist_from_varlist( + itp, + ::std::mem::transmute:: *mut *mut SHELL_VAR>, Option>(Some( + all_visible_functions, + )), + ); + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_helptopics(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + unsafe { + sl = strlist_create(num_shell_builtins); + n = 0 as libc::c_int; + i = n; + while i < num_shell_builtins { + let fresh37 = n; + n = n + 1; + let ref mut fresh38 = *((*sl).list).offset(fresh37 as isize); + *fresh38 = (*shell_builtins.offset(i as isize)).name; + i += 1; + } + let ref mut fresh39 = (*sl).list_len; + *fresh39 = n; + let ref mut fresh40 = *((*sl).list).offset(*fresh39 as isize); + *fresh40 = 0 as *mut libc::c_void as *mut libc::c_char; + (*itp).flags |= 0x20 as libc::c_int; + let ref mut fresh41 = (*itp).slist; + *fresh41 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_hostnames(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + sl = strlist_create(0 as libc::c_int); + let ref mut fresh42 = (*sl).list; + *fresh42 = get_hostname_list(); + (*sl).list_len = if !((*sl).list).is_null() { + strvec_len((*sl).list) + } else { + 0 as libc::c_int + }; + (*sl).list_size = (*sl).list_len; + let ref mut fresh43 = (*itp).slist; + *fresh43 = sl; + (*itp).flags |= 0x20 as libc::c_int | 0x10 as libc::c_int; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_joblist(mut itp: *mut ITEMLIST, mut jstate: libc::c_int) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut p: *mut PROCESS = 0 as *mut PROCESS; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut j: *mut JOB = 0 as *mut JOB; + let mut ws: JOB_STATE = 0 as JOB_STATE; + ws = JNONE; + if jstate == 0 as libc::c_int { + ws = JRUNNING; + } else if jstate == 1 as libc::c_int { + ws = JSTOPPED; + } + unsafe { + sl = strlist_create(js.j_jobslots); + i = js.j_jobslots - 1 as libc::c_int; + while i >= 0 as libc::c_int { + j = *jobs.offset(i as isize); + if !j.is_null() { + p = (*j).pipe; + if jstate == -(1 as libc::c_int) + || (**jobs.offset(i as isize)).state as libc::c_int == ws as libc::c_int + { + s = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*p).command) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + (*p).command, + ); + t = strpbrk(s, b" \t\n\0" as *const u8 as *const libc::c_char); + if !t.is_null() { + *t = '\u{0}' as i32 as libc::c_char; + } + let ref mut fresh44 = (*sl).list_len; + let fresh45 = *fresh44; + *fresh44 = *fresh44 + 1; + let ref mut fresh46 = *((*sl).list).offset(fresh45 as isize); + *fresh46 = s; + } + } + i -= 1; + } + let ref mut fresh47 = (*itp).slist; + *fresh47 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_jobs(mut itp: *mut ITEMLIST) -> libc::c_int { + return it_init_joblist(itp, -(1 as libc::c_int)); +} +#[no_mangle] +fn it_init_running(mut itp: *mut ITEMLIST) -> libc::c_int { + return it_init_joblist(itp, 0 as libc::c_int); +} +#[no_mangle] +fn it_init_stopped(mut itp: *mut ITEMLIST) -> libc::c_int { + return it_init_joblist(itp, 1 as libc::c_int); +} +#[no_mangle] +fn it_init_keywords(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + n = 0 as libc::c_int; + unsafe { + while !((*word_token_alist.as_mut_ptr().offset(n as isize)).word).is_null() { + n += 1; + } + sl = strlist_create(n); + i = 0 as libc::c_int; + while i < n { + let ref mut fresh48 = *((*sl).list).offset(i as isize); + *fresh48 = (*word_token_alist.as_mut_ptr().offset(i as isize)).word; + i += 1; + } + let ref mut fresh49 = (*sl).list_len; + *fresh49 = i; + let ref mut fresh50 = *((*sl).list).offset(*fresh49 as isize); + *fresh50 = 0 as *mut libc::c_void as *mut libc::c_char; + (*itp).flags |= 0x20 as libc::c_int; + let ref mut fresh51 = (*itp).slist; + *fresh51 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_signals(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + sl = strlist_create(0 as libc::c_int); + let ref mut fresh52 = (*sl).list; + *fresh52 = signal_names.as_mut_ptr(); + (*sl).list_len = strvec_len((*sl).list); + (*itp).flags |= 0x10 as libc::c_int; + let ref mut fresh53 = (*itp).slist; + *fresh53 = sl; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_variables(mut itp: *mut ITEMLIST) -> libc::c_int { + unsafe { + init_itemlist_from_varlist( + itp, + ::std::mem::transmute:: *mut *mut SHELL_VAR>, Option>(Some( + all_visible_variables, + )), + ); + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_setopts(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + sl = strlist_create(0 as libc::c_int); + let ref mut fresh54 = (*sl).list; + *fresh54 = get_minus_o_opts(); + (*sl).list_len = strvec_len((*sl).list); + let ref mut fresh55 = (*itp).slist; + *fresh55 = sl; + (*itp).flags |= 0x20 as libc::c_int; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn it_init_shopts(mut itp: *mut ITEMLIST) -> libc::c_int { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + unsafe { + sl = strlist_create(0 as libc::c_int); + let ref mut fresh56 = (*sl).list; + *fresh56 = get_shopt_options(); + (*sl).list_len = strvec_len((*sl).list); + let ref mut fresh57 = (*itp).slist; + *fresh57 = sl; + (*itp).flags |= 0x20 as libc::c_int; + } + return 0 as libc::c_int; +} +#[no_mangle] +fn gen_matches_from_itemlist( + mut itp: *mut ITEMLIST, + mut text: *const libc::c_char, +) -> *mut STRINGLIST { + let mut ret: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut tlen: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut n: libc::c_int = 0; + let mut ntxt: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if (*itp).flags & (LIST_DIRTY as libc::c_int | LIST_DYNAMIC as libc::c_int) != 0 + || (*itp).flags & LIST_INITIALIZED as libc::c_int == 0 as libc::c_int + { + if (*itp).flags & (LIST_DIRTY as libc::c_int | LIST_DYNAMIC as libc::c_int) != 0 { + clean_itemlist(itp); + } + if (*itp).flags & LIST_INITIALIZED as libc::c_int == 0 as libc::c_int { + initialize_itemlist(itp); + } + } + if ((*itp).slist).is_null() { + return 0 as *mut libc::c_void as *mut STRINGLIST; + } + ret = strlist_create((*(*itp).slist).list_len + 1 as libc::c_int); + sl = (*itp).slist; + ntxt = bash_dequote_text(text); + tlen = (if !ntxt.is_null() && *ntxt.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *ntxt.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *ntxt.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(ntxt) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + n = 0 as libc::c_int; + i = n; + while i < (*sl).list_len { + if tlen == 0 as libc::c_int + || (if tlen == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*(*((*sl).list).offset(i as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + == *ntxt.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp( + *((*sl).list).offset(i as isize), + ntxt, + (tlen as libc::c_ulong).try_into().unwrap(), + ) == 0 as libc::c_int) as libc::c_int + }) != 0 + { + let fresh58 = n; + n = n + 1; + let ref mut fresh59 = *((*ret).list).offset(fresh58 as isize); + *fresh59 = if !(*((*sl).list).offset(i as isize)).is_null() { + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(*((*sl).list).offset(i as isize)) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + *((*sl).list).offset(i as isize), + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + i += 1; + } + let ref mut fresh60 = (*ret).list_len; + *fresh60 = n; + let ref mut fresh61 = *((*ret).list).offset(*fresh60 as isize); + *fresh61 = 0 as *mut libc::c_void as *mut libc::c_char; + if !ntxt.is_null() { + free(ntxt as *mut libc::c_void); + } + } + return ret; +} +#[no_mangle] +fn pcomp_filename_completion_function( + mut text: *const libc::c_char, + mut state: libc::c_int, +) -> *mut libc::c_char { + unsafe { + static mut dfn: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; + let mut iscompgen: libc::c_int = 0; + let mut iscompleting: libc::c_int = 0; + if state == 0 as libc::c_int { + if !dfn.is_null() { + free(dfn as *mut libc::c_void); + } + iscompgen = (this_shell_builtin == Some(compgen_builtin)) as libc::c_int; + iscompleting = + (rl_readline_state & 0x4000 as libc::c_int as libc::c_ulong) as libc::c_int; + if iscompgen != 0 + && iscompleting == 0 as libc::c_int + && rl_completion_found_quote == 0 as libc::c_int + && rl_filename_dequoting_function.is_some() + { + dfn = (Some(rl_filename_dequoting_function.expect("non-null function pointer"))) + .expect("non-null function pointer")( + text as *mut libc::c_char, + rl_completion_quote_character, + ); + } else if iscompgen != 0 + && iscompleting != 0 + && !pcomp_curtxt.is_null() + && *pcomp_curtxt as libc::c_int == 0 as libc::c_int + && !text.is_null() + && (*text as libc::c_int == '\'' as i32 || *text as libc::c_int == '"' as i32) + && *text.offset(1 as libc::c_int as isize) as libc::c_int + == *text.offset(0 as libc::c_int as isize) as libc::c_int + && *text.offset(2 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + && rl_filename_dequoting_function.is_some() + { + dfn = (Some(rl_filename_dequoting_function.expect("non-null function pointer"))) + .expect("non-null function pointer")( + text as *mut libc::c_char, + rl_completion_quote_character, + ); + } else if iscompgen != 0 + && iscompleting != 0 + && rl_filename_dequoting_function.is_some() + && !pcomp_curtxt.is_null() + && !text.is_null() + && (*pcomp_curtxt.offset(0 as libc::c_int as isize) as libc::c_int + == *text.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp(pcomp_curtxt, text) == 0 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + && variable_context != 0 + && sh_contains_quotes(text) != 0 + { + dfn = (Some(rl_filename_dequoting_function.expect("non-null function pointer"))) + .expect("non-null function pointer")( + text as *mut libc::c_char, + rl_completion_quote_character, + ); + } else { + dfn = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(text) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + text, + ); + } + } + return rl_filename_completion_function(dfn, state); + } +} +#[no_mangle] +fn gen_action_completions(mut cs: *mut COMPSPEC, mut text: *const libc::c_char) -> *mut STRINGLIST { + unsafe { + let mut ret: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut tmatches: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut cmatches: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut flags: libc::c_ulong = 0; + let mut t: libc::c_int = 0; + tmatches = 0 as *mut libc::c_void as *mut STRINGLIST; + ret = tmatches; + + flags = (*cs).actions; + if flags & ((1 as libc::c_int) << 0 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_aliases, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 1 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_arrayvars, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 2 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_bindings, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 3 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_builtins, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 6 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_disabled, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 7 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_enabled, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 8 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_exports, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 10 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_functions, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 12 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_helptopics, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 13 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_hostnames, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 14 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_jobs, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 15 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_keywords, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 16 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_running, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 18 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_setopts, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 19 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_shopts, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 20 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_signals, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 21 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_stopped, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 23 as libc::c_int) as libc::c_ulong != 0 { + tmatches = gen_matches_from_itemlist(&mut it_variables, text); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if flags & ((1 as libc::c_int) << 4 as libc::c_int) as libc::c_ulong != 0 { + cmatches = rl_completion_matches(text, Some(command_word_completion_function)); + tmatches = completions_to_stringlist(cmatches); + ret = strlist_append(ret, tmatches); + strvec_dispose(cmatches); + strlist_dispose(tmatches); + } + if flags & ((1 as libc::c_int) << 9 as libc::c_int) as libc::c_ulong != 0 { + cmatches = rl_completion_matches( + text, + ::std::mem::transmute::< + Option *mut libc::c_char>, + Option, + >(Some(::std::mem::transmute::< + fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn() -> *mut libc::c_char, + >(pcomp_filename_completion_function))), + ); + tmatches = completions_to_stringlist(cmatches); + ret = strlist_append(ret, tmatches); + strvec_dispose(cmatches); + strlist_dispose(tmatches); + } + if flags & ((1 as libc::c_int) << 22 as libc::c_int) as libc::c_ulong != 0 { + cmatches = rl_completion_matches( + text, + Some(std::mem::transmute::< + unsafe extern "C" fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char, + fn( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char, + >(rl_username_completion_function)), + ); + tmatches = completions_to_stringlist(cmatches); + ret = strlist_append(ret, tmatches); + strvec_dispose(cmatches); + strlist_dispose(tmatches); + } + if flags & ((1 as libc::c_int) << 11 as libc::c_int) as libc::c_ulong != 0 { + cmatches = rl_completion_matches(text, Some(bash_groupname_completion_function)); + tmatches = completions_to_stringlist(cmatches); + ret = strlist_append(ret, tmatches); + strvec_dispose(cmatches); + strlist_dispose(tmatches); + } + if flags & ((1 as libc::c_int) << 17 as libc::c_int) as libc::c_ulong != 0 { + cmatches = rl_completion_matches(text, Some(bash_servicename_completion_function)); + tmatches = completions_to_stringlist(cmatches); + ret = strlist_append(ret, tmatches); + strvec_dispose(cmatches); + strlist_dispose(tmatches); + } + if flags & ((1 as libc::c_int) << 5 as libc::c_int) as libc::c_ulong != 0 { + t = rl_filename_completion_desired; + rl_completion_mark_symlink_dirs = 1 as libc::c_int; + cmatches = bash_directory_completion_matches(text); + if t == 0 as libc::c_int + && cmatches.is_null() + && rl_filename_completion_desired == 1 as libc::c_int + { + rl_filename_completion_desired = 0 as libc::c_int; + } + tmatches = completions_to_stringlist(cmatches); + ret = strlist_append(ret, tmatches); + strvec_dispose(cmatches); + strlist_dispose(tmatches); + } + return ret; + } +} +#[no_mangle] +pub fn gen_globpat_matches( + mut cs: *mut COMPSPEC, + mut text: *const libc::c_char, +) -> *mut STRINGLIST { + unsafe { + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + sl = strlist_create(0 as libc::c_int); + let ref mut fresh62 = (*sl).list; + *fresh62 = shell_glob_filename((*cs).globpat, 0 as libc::c_int); + if (*sl).list == &mut glob_error_return as *mut *mut libc::c_char { + let ref mut fresh63 = (*sl).list; + *fresh63 = 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + if !((*sl).list).is_null() { + let ref mut fresh64 = (*sl).list_size; + *fresh64 = strvec_len((*sl).list); + (*sl).list_len = *fresh64; + } + return sl; + } +} +#[no_mangle] +fn gen_wordlist_matches(mut cs: *mut COMPSPEC, mut text: *const libc::c_char) -> *mut STRINGLIST { + unsafe { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut l2: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut nw: libc::c_int = 0; + let mut tlen: libc::c_int = 0; + let mut ntxt: *mut libc::c_char = 0 as *mut libc::c_char; + if ((*cs).words).is_null() + || *((*cs).words).offset(0 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return 0 as *mut libc::c_void as *mut STRINGLIST; + } + l = split_at_delims( + (*cs).words, + strlen((*cs).words) as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_char, + -(1 as libc::c_int), + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if l.is_null() { + return 0 as *mut libc::c_void as *mut STRINGLIST; + } + l2 = expand_words_shellexp(l); + dispose_words(l); + nw = list_length(l2 as *mut GENERIC_LIST); + sl = strlist_create(nw + 1 as libc::c_int); + ntxt = bash_dequote_text(text); + tlen = (if !ntxt.is_null() && *ntxt.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *ntxt.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *ntxt.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(ntxt) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + nw = 0 as libc::c_int; + l = l2; + while !l.is_null() { + if tlen == 0 as libc::c_int + || (if tlen == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == *ntxt.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp( + (*(*l).word).word, + ntxt, + (tlen as libc::c_ulong).try_into().unwrap(), + ) == 0 as libc::c_int) as libc::c_int + }) != 0 + { + let fresh65 = nw; + nw = nw + 1; + let ref mut fresh66 = *((*sl).list).offset(fresh65 as isize); + *fresh66 = if !((*(*l).word).word).is_null() { + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*(*l).word).word) as u64) + .try_into() + .unwrap(), + ) as *mut libc::c_char, + (*(*l).word).word, + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + l = (*l).next; + } + let ref mut fresh67 = (*sl).list_len; + *fresh67 = nw; + let ref mut fresh68 = *((*sl).list).offset(*fresh67 as isize); + *fresh68 = 0 as *mut libc::c_void as *mut libc::c_char; + dispose_words(l2); + if !ntxt.is_null() { + free(ntxt as *mut libc::c_void); + } + return sl; + } +} +#[no_mangle] +fn bind_comp_words(mut lwords: *mut WORD_LIST) -> *mut SHELL_VAR { + unsafe { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable_noref(b"COMP_WORDS\0" as *const u8 as *const libc::c_char); + if v.is_null() { + v = make_new_array_variable( + b"COMP_WORDS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + if (*v).attributes & att_nameref as libc::c_int != 0 { + (*v).attributes &= !(att_nameref as libc::c_int); + } + if (*v).attributes & LIST_INITIALIZED as libc::c_int == 0 as libc::c_int { + v = convert_var_to_array(v); + } + v = assign_array_var_from_word_list(v, lwords, 0 as libc::c_int); + (*v).attributes &= !(0x1000 as libc::c_int); + return v; + } +} +#[no_mangle] +fn bind_compfunc_variables( + mut line: *mut libc::c_char, + mut ind: libc::c_int, + mut lwords: *mut WORD_LIST, + mut cw: libc::c_int, + mut exported: libc::c_int, +) { + let mut ibuf: [libc::c_char; 12] = [0; 12]; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut llen: size_t = 0; + let mut c: libc::c_int = 0; + v = bind_variable( + b"COMP_LINE\0" as *const u8 as *const libc::c_char, + line, + 0 as libc::c_int, + ); + unsafe { + if !v.is_null() && exported != 0 { + (*v).attributes |= LIST_DYNAMIC as libc::c_int; + } + c = *line.offset(ind as isize) as libc::c_int; + *line.offset(ind as isize) = '\u{0}' as i32 as libc::c_char; + llen = if __ctype_get_mb_cur_max() > (1 as libc::c_int as libc::c_ulong).try_into().unwrap() + { + if !line.is_null() && *line.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *line.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + mbstrlen(line).try_into().unwrap() + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + } + } else if !line.is_null() && *line.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *line.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *line.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(line) as libc::c_ulong + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + *line.offset(ind as isize) = c as libc::c_char; + value = inttostr( + llen as intmax_t, + ibuf.as_mut_ptr(), + (::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong) + .try_into() + .unwrap(), + ); + v = bind_int_variable( + b"COMP_POINT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + 0 as libc::c_int, + ); + if !v.is_null() && exported != 0 { + (*v).attributes |= LIST_DYNAMIC as libc::c_int; + } + value = inttostr( + rl_completion_type as intmax_t, + ibuf.as_mut_ptr(), + (::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong) + .try_into() + .unwrap(), + ); + v = bind_int_variable( + b"COMP_TYPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + 0 as libc::c_int, + ); + if !v.is_null() && exported != 0 { + (*v).attributes |= LIST_DYNAMIC as libc::c_int; + } + value = inttostr( + rl_completion_invoking_key as intmax_t, + ibuf.as_mut_ptr(), + (::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong) + .try_into() + .unwrap(), + ); + v = bind_int_variable( + b"COMP_KEY\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + 0 as libc::c_int, + ); + if !v.is_null() && exported != 0 { + (*v).attributes |= LIST_DYNAMIC as libc::c_int; + } + if exported == 0 as libc::c_int { + v = bind_comp_words(lwords); + value = inttostr( + cw as intmax_t, + ibuf.as_mut_ptr(), + (::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong) + .try_into() + .unwrap(), + ); + bind_int_variable( + b"COMP_CWORD\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + 0 as libc::c_int, + ); + } else { + array_needs_making = 1 as libc::c_int; + }; + } +} +#[no_mangle] +fn unbind_compfunc_variables(mut exported: libc::c_int) { + unbind_variable_noref(b"COMP_LINE\0" as *const u8 as *const libc::c_char); + unbind_variable_noref(b"COMP_POINT\0" as *const u8 as *const libc::c_char); + unbind_variable_noref(b"COMP_TYPE\0" as *const u8 as *const libc::c_char); + unbind_variable_noref(b"COMP_KEY\0" as *const u8 as *const libc::c_char); + unbind_variable_noref(b"COMP_WORDS\0" as *const u8 as *const libc::c_char); + unbind_variable_noref(b"COMP_CWORD\0" as *const u8 as *const libc::c_char); + unsafe { + if exported != 0 { + array_needs_making = 1 as libc::c_int; + } + } +} +#[no_mangle] +fn build_arg_list( + mut cmd: *mut libc::c_char, + mut cname: *const libc::c_char, + mut text: *const libc::c_char, + mut lwords: *mut WORD_LIST, + mut ind: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut ret: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut cl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut i: libc::c_int = 0; + ret = 0 as *mut libc::c_void as *mut WORD_LIST; + w = make_word(cmd); + ret = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + w = make_word(cname); + let ref mut fresh69 = (*ret).next; + *fresh69 = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + cl = *fresh69; + w = make_word(text); + let ref mut fresh70 = (*cl).next; + *fresh70 = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + cl = (*cl).next; + l = lwords; + i = 1 as libc::c_int; + while !l.is_null() && i < ind - 1 as libc::c_int { + l = (*l).next; + i += 1; + } + w = if !l.is_null() && !((*l).word).is_null() { + copy_word((*l).word) + } else { + make_word(b"\0" as *const u8 as *const libc::c_char) + }; + let ref mut fresh71 = (*cl).next; + *fresh71 = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + return ret; + } +} +#[no_mangle] +fn gen_shell_function_matches( + mut cs: *mut COMPSPEC, + mut cmd: *const libc::c_char, + mut text: *const libc::c_char, + mut line: *mut libc::c_char, + mut ind: libc::c_int, + mut lwords: *mut WORD_LIST, + mut nw: libc::c_int, + mut cw: libc::c_int, + mut foundp: *mut libc::c_int, +) -> *mut STRINGLIST { + unsafe { + let mut funcname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut f: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut cmdlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut fval: libc::c_int = 0; + let mut found: libc::c_int = 0; + let mut ps: sh_parser_state_t = sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + let mut pps: *mut sh_parser_state_t = 0 as *mut sh_parser_state_t; + let mut a: *mut ARRAY = 0 as *mut ARRAY; + found = 0 as libc::c_int; + if !foundp.is_null() { + *foundp = found; + } + funcname = (*cs).funcname; + f = find_function(funcname); + if f.is_null() { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"completion: function `%s' not found\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + funcname, + ); + rl_ding(); + rl_on_new_line(); + return 0 as *mut libc::c_void as *mut STRINGLIST; + } + bind_compfunc_variables(line, ind, lwords, cw - 1 as libc::c_int, 0 as libc::c_int); + cmdlist = build_arg_list(funcname, cmd, text, lwords, cw); + pps = &mut ps; + save_parser_state(pps); + begin_unwind_frame( + b"gen-shell-function-matches\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + add_unwind_protect( + std::mem::transmute::>(restore_parser_state), + pps as *mut libc::c_char, + ); + add_unwind_protect( + std::mem::transmute::>(dispose_words), + cmdlist as *mut libc::c_char, + ); + add_unwind_protect( + std::mem::transmute::>(unbind_compfunc_variables), + 0 as *mut libc::c_char, + ); + fval = execute_shell_function(f, cmdlist); + discard_unwind_frame( + b"gen-shell-function-matches\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + ); + restore_parser_state(pps); + found = (fval != EX_NOTFOUND as libc::c_int) as libc::c_int; + if fval == EX_RETRYFAIL as libc::c_int { + found |= ((1 as libc::c_int) << 8 as libc::c_int) << 1 as libc::c_int; + } + if !foundp.is_null() { + *foundp = found; + } + dispose_words(cmdlist); + unbind_compfunc_variables(0 as libc::c_int); + v = find_variable(b"COMPREPLY\0" as *const u8 as *const libc::c_char); + if v.is_null() { + return 0 as *mut libc::c_void as *mut STRINGLIST; + } + if (*v).attributes & LIST_INITIALIZED as libc::c_int == 0 as libc::c_int + && (*v).attributes & att_assoc as libc::c_int == 0 as libc::c_int + { + v = convert_var_to_array(v); + } + (*v).attributes &= !(0x1000 as libc::c_int); + a = (*v).value as *mut ARRAY; + if found == 0 as libc::c_int + || found & ((1 as libc::c_int) << 8 as libc::c_int) << 1 as libc::c_int != 0 + || a.is_null() + || (*v).attributes & LIST_INITIALIZED as libc::c_int == 0 as libc::c_int + || (*a).num_elements == 0 as libc::c_int + { + sl = 0 as *mut libc::c_void as *mut STRINGLIST; + } else { + sl = strlist_create(0 as libc::c_int); + let ref mut fresh72 = (*sl).list; + *fresh72 = array_to_argv(a, 0 as *mut libc::c_int); + let ref mut fresh73 = (*sl).list_size; + *fresh73 = (*a).num_elements; + (*sl).list_len = *fresh73; + } + unbind_variable_noref(b"COMPREPLY\0" as *const u8 as *const libc::c_char); + return sl; + } +} +#[no_mangle] +fn gen_command_matches( + mut cs: *mut COMPSPEC, + mut cmd: *const libc::c_char, + mut text: *const libc::c_char, + mut line: *mut libc::c_char, + mut ind: libc::c_int, + mut lwords: *mut WORD_LIST, + mut nw: libc::c_int, + mut cw: libc::c_int, +) -> *mut STRINGLIST { + unsafe { + let mut csbuf: *mut libc::c_char = 0 as *mut libc::c_char; + let mut cscmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut cmdlen: libc::c_int = 0; + let mut cmdsize: libc::c_int = 0; + let mut n: libc::c_int = 0; + let mut ws: libc::c_int = 0; + let mut we: libc::c_int = 0; + let mut cmdlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut cl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tw: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut sl: *mut STRINGLIST = 0 as *mut STRINGLIST; + bind_compfunc_variables(line, ind, lwords, cw, 1 as libc::c_int); + cmdlist = build_arg_list((*cs).command, cmd, text, lwords, cw); + n = strlen((*cs).command) as libc::c_int; + cmdsize = n + 1 as libc::c_int; + cl = (*cmdlist).next; + while !cl.is_null() { + cmdsize = (cmdsize as libc::c_ulong).wrapping_add( + (if !((*(*cl).word).word).is_null() + && *((*(*cl).word).word).offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + (if *((*(*cl).word).word).offset(1 as libc::c_int as isize) as libc::c_int != 0 + { + (if *((*(*cl).word).word).offset(2 as libc::c_int as isize) as libc::c_int + != 0 + { + strlen((*(*cl).word).word) + } else { + 2 as libc::c_int as libc::c_ulong + }) + } else { + 1 as libc::c_int as libc::c_ulong + }) + } else { + 0 as libc::c_int as libc::c_ulong + }) + .wrapping_add(3 as libc::c_int as libc::c_ulong), + ) as libc::c_int as libc::c_int; + cl = (*cl).next; + } + cmdsize += 2 as libc::c_int; + cscmd = malloc(((cmdsize + 1 as libc::c_int) as size_t).try_into().unwrap()) + as *mut libc::c_char; + strcpy(cscmd, (*cs).command); + cmdlen = n; + let fresh74 = cmdlen; + cmdlen = cmdlen + 1; + *cscmd.offset(fresh74 as isize) = ' ' as i32 as libc::c_char; + cl = (*cmdlist).next; + while !cl.is_null() { + t = sh_single_quote(if !((*(*cl).word).word).is_null() { + (*(*cl).word).word + } else { + b"\0" as *const u8 as *const libc::c_char + }); + n = strlen(t) as libc::c_int; + if cmdlen + (n + 2 as libc::c_int) >= cmdsize { + while cmdlen + (n + 2 as libc::c_int) >= cmdsize { + cmdsize += 64 as libc::c_int; + } + cscmd = realloc( + cscmd as *mut libc::c_void, + (cmdsize as size_t).try_into().unwrap(), + ) as *mut libc::c_char; + } + strcpy(cscmd.offset(cmdlen as isize), t); + cmdlen += n; + if !((*cl).next).is_null() { + let fresh75 = cmdlen; + cmdlen = cmdlen + 1; + *cscmd.offset(fresh75 as isize) = ' ' as i32 as libc::c_char; + } + free(t as *mut libc::c_void); + cl = (*cl).next; + } + *cscmd.offset(cmdlen as isize) = '\u{0}' as i32 as libc::c_char; + tw = command_substitute(cscmd, 0 as libc::c_int, 0 as libc::c_int); + csbuf = if !tw.is_null() { + (*tw).word + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !tw.is_null() { + dispose_word_desc(tw); + } + dispose_words(cmdlist); + free(cscmd as *mut libc::c_void); + unbind_compfunc_variables(1 as libc::c_int); + if csbuf.is_null() || *csbuf as libc::c_int == '\u{0}' as i32 { + if !csbuf.is_null() { + free(csbuf as *mut libc::c_void); + } + return 0 as *mut libc::c_void as *mut STRINGLIST; + } + sl = strlist_create(16 as libc::c_int); + ws = 0 as libc::c_int; + while *csbuf.offset(ws as isize) != 0 { + we = ws; + while *csbuf.offset(we as isize) as libc::c_int != 0 + && *csbuf.offset(we as isize) as libc::c_int != '\n' as i32 + { + if *csbuf.offset(we as isize) as libc::c_int == '\\' as i32 + && *csbuf.offset((we + 1 as libc::c_int) as isize) as libc::c_int == '\n' as i32 + { + we += 1; + } + we += 1; + } + t = substring(csbuf, ws, we); + if (*sl).list_len >= (*sl).list_size - 1 as libc::c_int { + strlist_resize(sl, (*sl).list_size + 16 as libc::c_int); + } + let ref mut fresh76 = (*sl).list_len; + let fresh77 = *fresh76; + *fresh76 = *fresh76 + 1; + let ref mut fresh78 = *((*sl).list).offset(fresh77 as isize); + *fresh78 = t; + while *csbuf.offset(we as isize) as libc::c_int == '\n' as i32 { + we += 1; + } + ws = we; + } + let ref mut fresh79 = *((*sl).list).offset((*sl).list_len as isize); + *fresh79 = 0 as *mut libc::c_void as *mut libc::c_char; + free(csbuf as *mut libc::c_void); + return sl; + } +} +#[no_mangle] +fn command_line_to_word_list( + mut line: *mut libc::c_char, + mut llen: libc::c_int, + mut sentinel: libc::c_int, + mut nwp: *mut libc::c_int, + mut cwp: *mut libc::c_int, +) -> *mut WORD_LIST { + let mut ret: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut delims: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + delims = rl_completer_word_break_characters; + } + ret = split_at_delims( + line, + llen, + delims, + sentinel, + LIST_INITIALIZED as libc::c_int | 0x100 as libc::c_int, + nwp, + cwp, + ); + return ret; +} +#[no_mangle] +pub fn gen_compspec_completions( + mut cs: *mut COMPSPEC, + mut cmd: *const libc::c_char, + mut word: *const libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, + mut foundp: *mut libc::c_int, +) -> *mut STRINGLIST { + unsafe { + let mut ret: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut tmatches: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut line: *mut libc::c_char = 0 as *mut libc::c_char; + let mut llen: libc::c_int = 0; + let mut nw: libc::c_int = 0; + let mut cw: libc::c_int = 0; + let mut found: libc::c_int = 0; + let mut foundf: libc::c_int = 0; + let mut lwords: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut lw: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut tcs: *mut COMPSPEC = 0 as *mut COMPSPEC; + found = 1 as libc::c_int; + ret = gen_action_completions(cs, word); + if !((*cs).globpat).is_null() { + tmatches = gen_globpat_matches(cs, word); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + rl_filename_completion_desired = 1 as libc::c_int; + } + } + if !((*cs).words).is_null() { + tmatches = gen_wordlist_matches(cs, word); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + lwords = 0 as *mut libc::c_void as *mut WORD_LIST; + line = 0 as *mut libc::c_void as *mut libc::c_char; + if !((*cs).command).is_null() || !((*cs).funcname).is_null() { + line = substring(pcomp_line, start, end); + llen = end - start; + lwords = command_line_to_word_list(line, llen, pcomp_ind - start, &mut nw, &mut cw); + if !lwords.is_null() + && !((*lwords).word).is_null() + && *cmd.offset(0 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + && *((*(*lwords).word).word).offset(0 as libc::c_int as isize) as libc::c_int + != 0 as libc::c_int + { + lw = make_bare_word(cmd); + lwords = make_word_list(lw, lwords); + nw += 1; + cw += 1; + } + } + if !((*cs).funcname).is_null() { + foundf = 0 as libc::c_int; + tmatches = gen_shell_function_matches( + cs, + cmd, + word, + line, + pcomp_ind - start, + lwords, + nw, + cw, + &mut foundf, + ); + if foundf != 0 as libc::c_int { + found = foundf; + } + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if !((*cs).command).is_null() { + tmatches = gen_command_matches(cs, cmd, word, line, pcomp_ind - start, lwords, nw, cw); + if !tmatches.is_null() { + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + } + } + if !((*cs).command).is_null() || !((*cs).funcname).is_null() { + if !lwords.is_null() { + dispose_words(lwords); + } + if !line.is_null() { + free(line as *mut libc::c_void); + } + } + if !foundp.is_null() { + *foundp = found; + } + if found == 0 as libc::c_int + || found & ((1 as libc::c_int) << 8 as libc::c_int) << 1 as libc::c_int != 0 + { + strlist_dispose(ret); + return 0 as *mut STRINGLIST; + } + if !((*cs).filterpat).is_null() { + tmatches = filter_stringlist(ret, (*cs).filterpat, word); + if !ret.is_null() && ret != tmatches { + if !((*ret).list).is_null() { + free((*ret).list as *mut libc::c_void); + } + free(ret as *mut libc::c_void); + } + ret = tmatches; + } + if !((*cs).prefix).is_null() || !((*cs).suffix).is_null() { + ret = strlist_prefix_suffix(ret, (*cs).prefix, (*cs).suffix); + } + if (ret.is_null() || (*ret).list_len == 0 as libc::c_int) + && (*cs).options & ((1 as libc::c_int) << 3 as libc::c_int) as libc::c_ulong != 0 + { + tcs = compspec_create(); + (*tcs).actions = ((1 as libc::c_int) << 5 as libc::c_int) as libc::c_ulong; + if !ret.is_null() { + free(ret as *mut libc::c_void); + } + ret = gen_action_completions(tcs, word); + compspec_dispose(tcs); + } else if (*cs).options & ((1 as libc::c_int) << 7 as libc::c_int) as libc::c_ulong != 0 { + tcs = compspec_create(); + (*tcs).actions = ((1 as libc::c_int) << 5 as libc::c_int) as libc::c_ulong; + tmatches = gen_action_completions(tcs, word); + ret = strlist_append(ret, tmatches); + strlist_dispose(tmatches); + compspec_dispose(tcs); + } + return ret; + } +} +#[no_mangle] +pub fn pcomp_set_readline_variables(mut flags: libc::c_int, mut nval: libc::c_int) { + unsafe { + if flags & (1 as libc::c_int) << 2 as libc::c_int != 0 { + rl_filename_completion_desired = nval; + } + if flags & (1 as libc::c_int) << 5 as libc::c_int != 0 { + rl_completion_suppress_append = nval; + } + if flags & (1 as libc::c_int) << 4 as libc::c_int != 0 { + rl_filename_quoting_desired = 1 as libc::c_int - nval; + } + if flags & (1 as libc::c_int) << 8 as libc::c_int != 0 { + rl_sort_completion_matches = 1 as libc::c_int - nval; + } + } +} +#[no_mangle] +pub fn pcomp_set_compspec_options( + mut cs: *mut COMPSPEC, + mut flags: libc::c_int, + mut set_or_unset: libc::c_int, +) { + unsafe { + if cs.is_null() && { + cs = pcomp_curcs; + cs.is_null() + } { + return; + } + if set_or_unset != 0 { + (*cs).options |= flags as libc::c_ulong; + } else { + (*cs).options &= !flags as libc::c_ulong; + }; + } +} +#[no_mangle] +fn gen_progcomp_completions( + mut ocmd: *const libc::c_char, + mut cmd: *const libc::c_char, + mut word: *const libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, + mut foundp: *mut libc::c_int, + mut retryp: *mut libc::c_int, + mut lastcs: *mut *mut COMPSPEC, +) -> *mut STRINGLIST { + unsafe { + let mut cs: *mut COMPSPEC = 0 as *mut COMPSPEC; + let mut oldcs: *mut COMPSPEC = 0 as *mut COMPSPEC; + let mut oldcmd: *const libc::c_char = 0 as *const libc::c_char; + let mut oldtxt: *const libc::c_char = 0 as *const libc::c_char; + let mut ret: *mut STRINGLIST = 0 as *mut STRINGLIST; + cs = progcomp_search(ocmd); + if cs.is_null() || cs == *lastcs { + return 0 as *mut STRINGLIST; + } + if !(*lastcs).is_null() { + compspec_dispose(*lastcs); + } + let ref mut fresh80 = (*cs).refcount; + *fresh80 += 1; + *lastcs = cs; + cs = compspec_copy(cs); + oldcs = pcomp_curcs; + oldcmd = pcomp_curcmd; + oldtxt = pcomp_curtxt; + pcomp_curcs = cs; + pcomp_curcmd = cmd; + pcomp_curtxt = word; + ret = gen_compspec_completions(cs, cmd, word, start, end, foundp); + pcomp_curcs = oldcs; + pcomp_curcmd = oldcmd; + pcomp_curtxt = oldtxt; + if !retryp.is_null() { + *retryp = (!foundp.is_null() + && *foundp & ((1 as libc::c_int) << 8 as libc::c_int) << 1 as libc::c_int != 0) + as libc::c_int; + } + if !foundp.is_null() { + *foundp &= !(((1 as libc::c_int) << 8 as libc::c_int) << 1 as libc::c_int); + *foundp = (*foundp as libc::c_ulong | (*cs).options) as libc::c_int; + } + compspec_dispose(cs); + return ret; + } +} +#[no_mangle] +pub fn programmable_completions( + mut cmd: *const libc::c_char, + mut word: *const libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, + mut foundp: *mut libc::c_int, +) -> *mut *mut libc::c_char { + unsafe { + let mut lastcs: *mut COMPSPEC = 0 as *mut COMPSPEC; + let mut ret: *mut STRINGLIST = 0 as *mut STRINGLIST; + let mut rmatches: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut found: libc::c_int = 0; + let mut retry: libc::c_int = 0; + let mut count: libc::c_int = 0; + let mut ocmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oend: libc::c_int = 0; + let mut al: *mut alias_t = 0 as *mut alias_t; + lastcs = 0 as *mut COMPSPEC; + count = 0 as libc::c_int; + found = count; + pcomp_line = rl_line_buffer; + pcomp_ind = rl_point; + ocmd = cmd as *mut libc::c_char; + oend = end; + loop { + retry = 0 as libc::c_int; + ret = gen_progcomp_completions( + ocmd, + ocmd, + word, + start, + oend, + &mut found, + &mut retry, + &mut lastcs, + ); + if found == 0 as libc::c_int { + t = strrchr(ocmd, '/' as i32); + if !t.is_null() && { + t = t.offset(1); + *t as libc::c_int != 0 + } { + ret = gen_progcomp_completions( + t, + ocmd, + word, + start, + oend, + &mut found, + &mut retry, + &mut lastcs, + ); + } + } + if found == 0 as libc::c_int { + ret = gen_progcomp_completions( + b"_DefaultCmD_\0" as *const u8 as *const libc::c_char, + ocmd, + word, + start, + oend, + &mut found, + &mut retry, + &mut lastcs, + ); + } + if found == 0 as libc::c_int && retry == 0 as libc::c_int && progcomp_alias != 0 && { + al = find_alias(ocmd); + !al.is_null() + } { + let mut ncmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nline: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ntxt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ind: libc::c_int = 0; + let mut lendiff: libc::c_int = 0; + let mut nlen: size_t = 0; + let mut olen: size_t = 0; + let mut llen: size_t = 0; + ntxt = (*al).value; + nlen = strlen(ntxt) as size_t; + if nlen == 0 as libc::c_int as libc::c_ulong { + break; + } + olen = strlen(ocmd) as size_t; + lendiff = nlen.wrapping_sub(olen) as libc::c_int; + llen = strlen(pcomp_line) as size_t; + nline = malloc( + llen.wrapping_add(lendiff as libc::c_ulong) + .wrapping_add(1 as libc::c_int as libc::c_ulong) + .try_into() + .unwrap(), + ) as *mut libc::c_char; + if start > 0 as libc::c_int { + strncpy( + nline, + pcomp_line, + (start as libc::c_ulong).try_into().unwrap(), + ); + } + strncpy(nline.offset(start as isize), ntxt, nlen.try_into().unwrap()); + strcpy( + nline.offset(start as isize).offset(nlen as isize), + pcomp_line.offset(start as isize).offset(olen as isize), + ); + ind = skip_to_delim( + ntxt, + 0 as libc::c_int, + b"()<>;&| \t\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + LIST_DYNAMIC as libc::c_int | 0x100 as libc::c_int, + ); + if ind > 0 as libc::c_int { + ncmd = substring(ntxt, 0 as libc::c_int, ind); + pcomp_ind += lendiff; + oend += lendiff; + if ocmd != cmd as *mut libc::c_char { + free(ocmd as *mut libc::c_void); + } + if pcomp_line != rl_line_buffer { + free(pcomp_line as *mut libc::c_void); + } + ocmd = ncmd; + pcomp_line = nline; + retry = 1 as libc::c_int; + } else { + free(nline as *mut libc::c_void); + break; + } + } + count += 1; + if count > 32 as libc::c_int { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"programmable_completion: %s: possible retry loop\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + cmd, + ); + break; + } else if !(retry != 0) { + break; + } + } + if pcomp_line != rl_line_buffer { + free(pcomp_line as *mut libc::c_void); + } + if ocmd != cmd as *mut libc::c_char { + free(ocmd as *mut libc::c_void); + } + if !ret.is_null() { + rmatches = (*ret).list; + free(ret as *mut libc::c_void); + } else { + rmatches = 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + if !foundp.is_null() { + *foundp = found; + } + if !lastcs.is_null() { + compspec_dispose(lastcs); + } + pcomp_line = rl_line_buffer; + pcomp_ind = rl_point; + return rmatches; + } +} diff --git a/utshell-0.5.0/src/pcomplib.rs b/utshell-0.5.0/src/pcomplib.rs new file mode 100644 index 00000000..feeaf30c --- /dev/null +++ b/utshell-0.5.0/src/pcomplib.rs @@ -0,0 +1,214 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::hashlib::{ + hash_create, hash_dispose, hash_flush, hash_insert, hash_remove, hash_search, hash_walk, +}; +use crate::src_common::*; + +#[no_mangle] +pub fn compspec_create() -> *mut COMPSPEC { + unsafe { + let ret: *mut COMPSPEC = + libc::malloc(::core::mem::size_of::() as usize) as *mut COMPSPEC; + (*ret).refcount = 0 as libc::c_int; + (*ret).actions = 0 as libc::c_int as libc::c_ulong; + (*ret).options = 0 as libc::c_int as libc::c_ulong; + (*ret).globpat = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).words = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).prefix = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).suffix = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).funcname = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).command = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).lcommand = 0 as *mut libc::c_void as *mut libc::c_char; + (*ret).filterpat = 0 as *mut libc::c_void as *mut libc::c_char; + return ret; + } +} + +#[no_mangle] +pub fn compspec_dispose(cs: *mut COMPSPEC) { + unsafe { + (*cs).refcount -= 1; + if (*cs).refcount == 0 as libc::c_int { + if !((*cs).globpat).is_null() { + libc::free((*cs).globpat as *mut libc::c_void); + } + if !((*cs).words).is_null() { + libc::free((*cs).words as *mut libc::c_void); + } + if !((*cs).prefix).is_null() { + libc::free((*cs).prefix as *mut libc::c_void); + } + if !((*cs).suffix).is_null() { + libc::free((*cs).suffix as *mut libc::c_void); + } + if !((*cs).funcname).is_null() { + libc::free((*cs).funcname as *mut libc::c_void); + } + if !((*cs).command).is_null() { + libc::free((*cs).command as *mut libc::c_void); + } + if !((*cs).lcommand).is_null() { + libc::free((*cs).lcommand as *mut libc::c_void); + } + if !((*cs).filterpat).is_null() { + libc::free((*cs).filterpat as *mut libc::c_void); + } + libc::free(cs as *mut libc::c_void); + } + } +} + +#[no_mangle] +pub fn compspec_copy(cs: *mut COMPSPEC) -> *mut COMPSPEC { + unsafe { + let new: *mut COMPSPEC = + libc::malloc(::core::mem::size_of::() as usize) as *mut COMPSPEC; + (*new).refcount = 1 as libc::c_int; + (*new).actions = (*cs).actions; + (*new).options = (*cs).options; + (*new).globpat = STRDUP!((*cs).globpat); + (*new).words = STRDUP!((*cs).words); + (*new).prefix = STRDUP!((*cs).prefix); + (*new).suffix = STRDUP!((*cs).suffix); + (*new).funcname = STRDUP!((*cs).funcname); + (*new).command = STRDUP!((*cs).command); + (*new).lcommand = STRDUP!((*cs).lcommand); + (*new).filterpat = STRDUP!((*cs).filterpat); + return new; + } +} +// pub const COMPLETE_HASH_BUCKETS: libc::c_int = 256; + +#[no_mangle] +pub fn progcomp_create() { + unsafe { + if prog_completes.is_null() { + prog_completes = hash_create(COMPLETE_HASH_BUCKETS); + } + } +} + +#[no_mangle] +pub fn progcomp_size() -> libc::c_int { + unsafe { + return if !prog_completes.is_null() { + (*prog_completes).nentries + } else { + 0 as libc::c_int + }; + } +} + +fn free_progcomp(data: *mut libc::c_void) { + let cs: *mut COMPSPEC = data as *mut COMPSPEC; + compspec_dispose(cs); +} + +#[no_mangle] +pub fn progcomp_flush() { + unsafe { + if !prog_completes.is_null() { + hash_flush(prog_completes, Some(free_progcomp)); + } + } +} + +#[no_mangle] +pub fn progcomp_dispose() { + unsafe { + if !prog_completes.is_null() { + hash_dispose(prog_completes); + } + prog_completes = 0 as *mut libc::c_void as *mut HASH_TABLE; + } +} + +#[no_mangle] +pub fn progcomp_remove(cmd: *mut libc::c_char) -> libc::c_int { + unsafe { + let item: *mut BUCKET_CONTENTS; + if prog_completes.is_null() { + return 1 as libc::c_int; + } + item = hash_remove(cmd, prog_completes, 0 as libc::c_int); + if !item.is_null() { + if !((*item).data).is_null() { + free_progcomp((*item).data); + } + libc::free((*item).key as *mut libc::c_void); + libc::free(item as *mut libc::c_void); + return 1 as libc::c_int; + } + return 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn progcomp_insert(cmd: *mut libc::c_char, cs: *mut COMPSPEC) -> libc::c_int { + unsafe { + let item: *mut BUCKET_CONTENTS; + if cs.is_null() { + programming_error( + dcgettext( + 0 as *const libc::c_char, + b"progcomp_insert: %s: NULL COMPSPEC\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + cmd, + ); + } + if prog_completes.is_null() { + progcomp_create(); + } + (*cs).refcount += 1; + item = hash_insert(cmd, prog_completes, 0 as libc::c_int); + if !((*item).data).is_null() { + free_progcomp((*item).data); + } else { + (*item).key = libc::strcpy( + libc::malloc((1 + libc::strlen(cmd)) as usize) as *mut libc::c_char, + cmd, + ); + } + (*item).data = cs as *mut libc::c_void; + return 1 as libc::c_int; + } +} + +#[no_mangle] +pub fn progcomp_search(cmd: *const libc::c_char) -> *mut COMPSPEC { + unsafe { + let item: *mut BUCKET_CONTENTS; + let cs: *mut COMPSPEC; + if prog_completes.is_null() { + return 0 as *mut libc::c_void as *mut COMPSPEC; + } + item = hash_search(cmd, prog_completes, 0 as libc::c_int); + if item.is_null() { + return 0 as *mut libc::c_void as *mut COMPSPEC; + } + cs = (*item).data as *mut COMPSPEC; + return cs; + } +} + +#[no_mangle] +pub fn progcomp_walk(pfunc: Option) { + unsafe { + if prog_completes.is_null() + || pfunc.is_none() + || (if !prog_completes.is_null() { + (*prog_completes).nentries + } else { + 0 as libc::c_int + }) == 0 as libc::c_int + { + return; + } + hash_walk(prog_completes, pfunc); + } +} diff --git a/utshell-0.5.0/src/print_cmd.rs b/utshell-0.5.0/src/print_cmd.rs new file mode 100644 index 00000000..ee6b8e33 --- /dev/null +++ b/utshell-0.5.0/src/print_cmd.rs @@ -0,0 +1,1677 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::copycmd::copy_command; +use crate::copycmd::copy_redirect; +use crate::dispose_cmd::{dispose_command, dispose_redirects}; +use crate::error::command_error; +use crate::flags::change_flag; +use crate::general::sh_validfd; +use crate::src_common::*; +use crate::subst::remove_quoted_escapes; +use crate::unwind_prot::{add_unwind_protect, remove_unwind_protect}; +use crate::y_tab::{decode_prompt_string, find_reserved_word}; +use std::convert::TryInto; + +extern "C" { + fn cprintf(_: *const libc::c_char, ...); +} + +#[no_mangle] +pub fn print_command(command: *mut COMMAND) { + let _str: *mut libc::c_char; + unsafe { + command_string_index = 0; + print!( + "{}", + CStr::from_ptr(make_command_string(command)) + .to_str() + .unwrap() + ); + } +} + +#[no_mangle] +pub fn make_command_string(command: *mut COMMAND) -> *mut libc::c_char { + unsafe { + command_string_index = 0; + was_heredoc = 0; + deferred_heredocs = 0 as *mut REDIRECT; + make_command_string_internal(command); + return the_printed_command; + } +} + +#[no_mangle] +fn make_command_string_internal(command: *mut COMMAND) { + let mut s: [libc::c_char; 3] = [0; 3]; + unsafe { + if command.is_null() { + cprintf(b"\0" as *const u8 as *const libc::c_char); + } else { + if skip_this_indent != 0 { + skip_this_indent = skip_this_indent - 1; + } else { + indent(indentation); + } + + if (*command).flags != 0 && CMD_TIME_PIPELINE != 0 { + cprintf(b"time \0" as *const u8 as *const libc::c_char); + if (*command).flags != 0 && CMD_TIME_POSIX != 0 { + cprintf(b"-p \0" as *const u8 as *const libc::c_char); + } + } + + if (*command).flags != 0 && CMD_INVERT_RETURN != 0 { + cprintf(b"! \0" as *const u8 as *const libc::c_char); + } + // (*command).type_ = 11; + match (*command).type_0 as libc::c_uint { + command_type_cm_for => print_for_command((*command).value.For), + command_type_cm_arith_for => print_arith_for_command((*command).value.ArithFor), + command_type_cm_select => print_select_command((*command).value.Select), + command_type_cm_case => print_case_command((*command).value.Case), + command_type_cm_while => print_while_command((*command).value.While), + command_type_cm_until => print_until_command((*command).value.While), + command_type_cm_if => print_if_command((*command).value.If), + command_type_cm_arith => print_arith_command((*(*command).value.Arith).exp), + command_type_cm_cond => print_cond_command((*command).value.Cond), + command_type_cm_simple => print_simple_command((*command).value.Simple), + command_type_cm_connection => { + skip_this_indent = skip_this_indent + 1; + printing_connection = printing_connection + 1; + make_command_string_internal((*(*command).value.Connection).first); + let _str_1 = b'&' as i32; + let _str_1 = b'|' as i32; + let _str_3 = b';' as i32; + match (*(*command).value.Connection).connector { + 38 | 124 => { + let c: libc::c_char = + (*(*command).value.Connection).connector as libc::c_char; + s[0] = ' ' as i32 as libc::c_char; + s[1] = c; + s[2] = '\u{0}' as i32 as libc::c_char; + + print_deferred_heredocs(s.as_mut_ptr()); + + if c as libc::c_int != '&' as i32 + || !((*(*command).value.Connection).second.is_null()) + { + cprintf(b" \0" as *const u8 as *const libc::c_char); + skip_this_indent = skip_this_indent + 1; + } + } + AND_AND => { + print_deferred_heredocs(b" && \0" as *const u8 as *const libc::c_char); + if !(*(*command).value.Connection).second.is_null() { + skip_this_indent = skip_this_indent + 1; + } + } + OR_OR => { + print_deferred_heredocs(b" || \0" as *const u8 as *const libc::c_char); + if !(*(*command).value.Connection).second.is_null() { + skip_this_indent = skip_this_indent + 1; + } + } + // str_3 => { + 59 => { + if deferred_heredocs.is_null() { + if was_heredoc == 0 { + cprintf(b";\0" as *const u8 as *const libc::c_char); + } else { + was_heredoc = 0; + } + } else { + print_deferred_heredocs(if inside_function_def != 0 { + b"\0" as *const u8 as *const libc::c_char + } else { + b";\0" as *const u8 as *const libc::c_char + }) + } + + if inside_function_def != 0 { + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + } else { + cprintf(b" \0" as *const u8 as *const libc::c_char); + if !(*(*command).value.Connection).second.is_null() { + skip_this_indent = skip_this_indent + 1; + } + } + } + _ => { + cprintf( + b"print_command:bas connector %s \0" as *const u8 + as *const libc::c_char, + (*(*command).value.Connection).connector, + ); + } + } + + make_command_string_internal((*(*command).value.Connection).second); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + printing_connection = printing_connection - 1; + } + + command_type_cm_function_def => print_function_def((*command).value.Function_def), + command_type_cm_group => print_group_command((*command).value.Group), + command_type_cm_subshell => { + cprintf(b"( \0" as *const u8 as *const libc::c_char); + skip_this_indent = skip_this_indent + 1; + make_command_string_internal((*(*command).value.Subshell).command); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + cprintf(b" )\0" as *const u8 as *const libc::c_char); + } + command_type_cm_coproc => { + cprintf( + b"coproc %s \0" as *const u8 as *const libc::c_char, + (*(*command).value.Coproc).name, + ); + skip_this_indent += 1; + make_command_string_internal((*(*command).value.Coproc).command); + } + _ => { + // let c_str = CString::new("print_command").unwrap(); + // let c_str_ptr = c_str.as_ptr(); + command_error( + b"print_command\0" as *const u8 as *const libc::c_char, + CMDERR_BADTYPE as i32, + (*command).type_0 as i32, + 0 as i32, + ); + } + } + + if !(*command).redirects.is_null() { + cprintf(b" \0" as *const u8 as *const libc::c_char); + print_redirection_list((*command).redirects); + } + } + } +} + +#[no_mangle] +pub fn print_word_list(list: *mut WordList, separator: *mut libc::c_char) { + let mut w: *mut WordList; + // let mut str:*mut libc::c_char; + w = list; + unsafe { + while !w.is_null() { + if !(*w).word.is_null() { + print!( + "{}{}", + CStr::from_ptr((*(*w).word).word).to_str().unwrap(), + CStr::from_ptr(separator).to_str().unwrap() + ); + } else { + print!("{}", CStr::from_ptr((*(*w).word).word).to_str().unwrap()); + } + + w = (*w).next; + } + } +} + +#[no_mangle] +pub fn xtrace_set(fd: libc::c_int, fp: *mut FILE) { + unsafe { + if fd >= 0 && sh_validfd(fd) == 0 { + internal_error( + b"xtrace_set: %d: invalid file descriptor\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + fd, + ); + return; + } + + if fp.is_null() { + internal_error(b"xtrace_set: NULL file pointer\0" as *const u8 as *const libc::c_char); + return; + } + + if fd >= 0 && fileno(fp) != fd { + internal_warning( + b"xtrace fd (%d) != fileno xtrace fp (%d)\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + fd, + fileno(fp), + ); + } + + xtrace_fd = fd; + xtrace_fp = fp; + } +} + +#[no_mangle] +pub fn xtrace_init() { + unsafe { + xtrace_set(-1, stderr); + } +} + +#[no_mangle] +pub fn xtrace_reset() { + unsafe { + if xtrace_fd >= 0 && !xtrace_fp.is_null() { + libc::fflush(xtrace_fp); + libc::fclose(xtrace_fp); + } else if xtrace_fd >= 0 { + libc::close(xtrace_fd); + } + + xtrace_fd = -1; + xtrace_fp = stderr; + } +} + +#[no_mangle] +pub fn xtrace_fdchk(fd: libc::c_int) { + unsafe { + if fd == xtrace_fd { + xtrace_reset(); + } + } +} + +#[no_mangle] +pub fn indirection_level_string() -> *mut libc::c_char { + let mut i: libc::c_int; + let mut j: libc::c_int; + let mut ps4: *mut libc::c_char; + let mut ps4_firstc: [libc::c_char; MB_LEN_MAX + 1] = [0; MB_LEN_MAX + 1]; + let ps4_firstc_len: libc::c_int; + let ps4_len: libc::c_int; + let ineed: libc::c_int; + let old: libc::c_int; + unsafe { + ps4 = get_string_value(b"PS4\0" as *const u8 as *const libc::c_char); + + if indirection_string.is_null() { + indirection_stringsiz = 100; + indirection_string = libc::malloc(100) as *mut libc::c_char; + } + *indirection_string.offset(0 as isize) = '\u{0}' as i32 as libc::c_char; + + if ps4.is_null() || *ps4 as libc::c_int == '\u{0}' as i32 { + return indirection_string; + } + + old = change_flag('x' as i32, FLAG_OFF as i32); + ps4 = decode_prompt_string(ps4); + if old != 0 { + change_flag('x' as i32, FLAG_ON.into()); + } + + if ps4.is_null() || *ps4 as libc::c_int == '\u{0}' as i32 { + return indirection_string; + } + + ps4_len = strnlen(ps4 as *const libc::c_char, MB_CUR_MAX) as libc::c_int; + + ps4_firstc_len = MBLEN(ps4, ps4_len as size_t); + if ps4_firstc_len == 1 || ps4_firstc_len == 0 || ps4_firstc_len < 0 { + ps4_firstc[0] = *ps4.offset(0 as isize); + ps4_firstc[1] = '\u{0}' as i32 as libc::c_char; + } else { + libc::memcpy( + ps4_firstc.as_mut_ptr() as *mut c_void, + ps4 as *const c_void, + ps4_firstc_len as usize, + ); + } + + ineed = ((ps4_firstc_len * indirection_level) as libc::c_ulong) + .wrapping_add(libc::strlen(ps4).try_into().unwrap()) as libc::c_int; + if ineed > indirection_stringsiz - 1 { + indirection_stringsiz = ineed + 1; + indirection_string = libc::realloc( + indirection_string as *mut c_void, + indirection_stringsiz as usize, + ) as *mut libc::c_char; + } + + i = 0; + j = 0; + while j < indirection_level && (i < indirection_stringsiz - 1) { + if ps4_firstc_len == 1 { + *indirection_string.offset(i as isize) = ps4_firstc[0]; + } else { + libc::memcpy( + indirection_string.offset(i as isize) as *mut c_void, + ps4_firstc.as_mut_ptr() as *const c_void, + ps4_firstc_len as usize, + ); + } + + i += ps4_firstc_len; + j += 1; + } + + j = ps4_firstc_len; + while *ps4 as libc::c_int != 0 + && *ps4.offset(j as isize) != 0 + && (i < indirection_stringsiz - 1) + { + *indirection_string.offset(i as isize) = *ps4.offset(j as isize); + + i += 1; + j += 1; + } + + *indirection_string.offset(i as isize) = '\u{0}' as i32 as libc::c_char; + libc::free(ps4 as *mut libc::c_void); + return indirection_string; + } +} + +#[no_mangle] +pub fn xtrace_print_assignment( + name: *mut libc::c_char, + value: *mut libc::c_char, + assign_list: libc::c_int, + xflags: libc::c_int, +) { + let nval: *mut libc::c_char; + unsafe { + CHECK_XTRACE_FP!(); + if xflags != 0 { + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + } + + if *value as libc::c_int == '\u{0}' as i32 || assign_list != 0 { + nval = value; + } else if sh_contains_shell_metas(value) != 0 { + nval = sh_single_quote(value); + } else if ansic_shouldquote(value) != 0 { + nval = ansic_quote(value, 0, 0 as *mut libc::c_int); + } else { + nval = value; + } + + if assign_list != 0 { + fprintf( + xtrace_fp, + CString::new("%s=(%s)\n").unwrap().as_ptr(), + name, + nval, + ); + } else { + fprintf( + xtrace_fp, + CString::new("%s=%s\n").unwrap().as_ptr(), + name, + nval, + ); + } + + if nval != value { + if !nval.is_null() { + libc::free(nval as *mut c_void); + } + } + + libc::fflush(xtrace_fp); + } +} + +#[no_mangle] +pub fn xtrace_print_word_list(list: *mut WordList, xtflags: libc::c_int) { + let mut w: *mut WordList; + let mut t: *mut libc::c_char; + let mut x: *mut libc::c_char; + unsafe { + CHECK_XTRACE_FP!(); + + if (xtflags & 1) != 0 { + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + } + + w = list; + while !w.is_null() { + t = (*(*w).word).word; + if t.is_null() || *t as libc::c_int == '\u{0}' as i32 { + fprintf( + xtrace_fp, + CString::new("''%s").unwrap().as_ptr(), + if !((*w).next).is_null() { + b" \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + } else if (xtflags & 2) != 0 { + fprintf( + xtrace_fp, + CString::new("%s%s").unwrap().as_ptr(), + t, + if !((*w).next).is_null() { + b" \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + } else if sh_contains_shell_metas(t) != 0 { + x = sh_single_quote(t); + fprintf( + xtrace_fp, + CString::new("%s%s").unwrap().as_ptr(), + x, + if !((*w).next).is_null() { + b" \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + libc::free(x as *mut c_void); + } else if ansic_shouldquote(t) != 0 { + x = ansic_quote(t, 0, 0 as *mut libc::c_int); + fprintf( + xtrace_fp, + CString::new("%s%s").unwrap().as_ptr(), + x, + if !((*w).next).is_null() { + b" \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + libc::free(x as *mut c_void); + } else { + fprintf( + xtrace_fp, + CString::new("%s%s").unwrap().as_ptr(), + t, + if !((*w).next).is_null() { + b" \0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + } + w = (*w).next; + } + + fprintf(xtrace_fp, CString::new("\n").unwrap().as_ptr()); + libc::fflush(xtrace_fp); + } +} + +#[no_mangle] +pub fn command_print_word_list(list: *mut WordList, separator: *mut libc::c_char) { + let mut w: *mut WordList; + w = list; + unsafe { + while !w.is_null() { + if !(*w).next.is_null() { + cprintf( + b"%s%s\0" as *const u8 as *const libc::c_char, + (*(*w).word).word, + separator, + ); + } else { + cprintf( + b"%s\0" as *const u8 as *const libc::c_char, + (*(*w).word).word, + ); + } + + if !(*w).next.is_null() {} + + w = (*w).next; + } + } +} + +// 有个cprintf函数 +#[no_mangle] +pub fn print_for_command_head(for_command: *mut FOR_COM) { + unsafe { + cprintf( + b"for %s in \0" as *const u8 as *const libc::c_char, + (*(*for_command).name).word, + ); + command_print_word_list( + (*for_command).map_list, + b" \0" as *const u8 as *mut libc::c_char, + ); + } +} + +#[no_mangle] +pub fn xtrace_print_for_command_head(for_command: *mut FOR_COM) { + unsafe { + CHECK_XTRACE_FP!(); + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + fprintf( + xtrace_fp, + CString::new("for %s in ").unwrap().as_ptr(), + (*(*for_command).name).word, + ); + xtrace_print_word_list((*for_command).map_list, 2); + } +} + +#[no_mangle] +pub fn print_for_command(for_command: *mut FOR_COM) { + unsafe { + print_for_command_head(for_command); + cprintf(b";\0" as *const u8 as *const libc::c_char); + newline(b"do\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + + indentation += indentation_amount; + make_command_string_internal((*for_command).action); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *mut libc::c_char); + semicolon(); + indentation -= indentation_amount; + } + newline(b"done\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn print_arith_for_command(arith_for_command: *mut ARITH_FOR_COM) { + unsafe { + cprintf(b"for ((\0" as *const u8 as *const libc::c_char); + command_print_word_list( + (*arith_for_command).init, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + cprintf(b"; \0" as *const u8 as *const libc::c_char); + command_print_word_list( + (*arith_for_command).test, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + cprintf(b"; \0" as *const u8 as *const libc::c_char); + command_print_word_list( + (*arith_for_command).step, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + cprintf(b"))\0" as *const u8 as *const libc::c_char); + newline(b"do\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + + indentation += indentation_amount; + make_command_string_internal((*arith_for_command).action); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + semicolon(); + indentation -= indentation_amount; + newline(b"done\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } +} + +#[no_mangle] +pub fn print_select_command_head(select_command: *mut SELECT_COM) { + unsafe { + cprintf( + b"select %s in \0" as *const u8 as *const libc::c_char, + (*(*select_command).name).word, + ); + command_print_word_list( + (*select_command).map_list, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } +} + +#[no_mangle] +pub fn xtrace_print_select_command_head(select_command: *mut SELECT_COM) { + unsafe { + CHECK_XTRACE_FP!(); + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + fprintf( + xtrace_fp, + CString::new("select %s in ").unwrap().as_ptr(), + (*(*select_command).name).word, + ); + xtrace_print_word_list((*select_command).map_list, 2); + } +} + +#[no_mangle] +pub fn print_select_command(select_command: *mut SELECT_COM) { + print_select_command_head(select_command); + unsafe { + cprintf(b";\0" as *const u8 as *const libc::c_char); + newline(b"do\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + indentation += indentation_amount; + make_command_string_internal((*select_command).action); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + semicolon(); + indentation -= indentation_amount; + } + newline(b"done\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn print_group_command(group_command: *mut GROUP_COM) { + unsafe { + group_command_nesting += 1; + cprintf(b"{{ \0" as *const u8 as *const libc::c_char); + if inside_function_def == 0 { + skip_this_indent += 1; + } else { + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + indentation += indentation_amount; + } + + make_command_string_internal((*group_command).command); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + + if inside_function_def != 0 { + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + indentation -= indentation_amount; + indent(indentation); + } else { + semicolon(); + cprintf(b" \0" as *const u8 as *const libc::c_char); + } + cprintf(b"}\0" as *const u8 as *const libc::c_char); + group_command_nesting -= 1; + } +} + +#[no_mangle] +pub fn print_case_command_head(case_command: *mut CASE_COM) { + unsafe { + cprintf( + b"case %s in \0" as *const u8 as *const libc::c_char, + (*(*case_command).word).word, + ); + } +} + +#[no_mangle] +pub fn xtrace_print_case_command_head(case_command: *mut CASE_COM) { + unsafe { + CHECK_XTRACE_FP!(); + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + fprintf( + xtrace_fp, + CString::new("case %s in\n").unwrap().as_ptr(), + (*(*case_command).word).word, + ); + } +} + +#[no_mangle] +pub fn print_case_command(case_command: *mut CASE_COM) { + print_case_command_head(case_command); + unsafe { + if !(*case_command).clauses.is_null() { + print_case_clauses((*case_command).clauses); + } + } + newline(b"esac\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn print_case_clauses(mut clauses: *mut PATTERN_LIST) { + unsafe { + indentation += indentation_amount; + while !clauses.is_null() { + newline(b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + command_print_word_list( + (*clauses).patterns, + CString::new(" | ").unwrap().as_ptr() as *mut libc::c_char, + ); + + cprintf(b")\n\0" as *const u8 as *const libc::c_char); + indentation += indentation_amount; + make_command_string_internal((*clauses).action); + indentation -= indentation_amount; + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + if (*clauses).flags & CASEPAT_FALLTHROUGH as i32 != 0 { + newline(b";&\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } else if (*clauses).flags & CASEPAT_TESTNEXT as i32 != 0 { + newline(b";;&\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } else { + newline(b";;\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + clauses = (*clauses).next; + } + indentation -= indentation_amount; + } +} + +#[no_mangle] +pub fn print_while_command(while_command: *mut WHILE_COM) { + print_until_or_while( + while_command, + CString::new("while").unwrap().as_ptr() as *mut libc::c_char, + ); +} + +#[no_mangle] +pub fn print_until_command(while_command: *mut WHILE_COM) { + print_until_or_while( + while_command, + CString::new("until").unwrap().as_ptr() as *mut libc::c_char, + ); +} + +#[no_mangle] +pub fn print_until_or_while(while_command: *mut WHILE_COM, which: *mut libc::c_char) { + unsafe { + cprintf(b"%s\0" as *const u8 as *const libc::c_char, which); + skip_this_indent += 1; + make_command_string_internal((*while_command).test); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + semicolon(); + cprintf(b"do\n\0" as *const u8 as *const libc::c_char); + indentation += indentation_amount; + make_command_string_internal((*while_command).action); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + indentation -= indentation_amount; + } + semicolon(); + newline(b"done\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn print_if_command(if_command: *mut IF_COM) { + unsafe { + cprintf(b"if \0" as *const u8 as *const libc::c_char); + skip_this_indent += 1; + make_command_string_internal((*if_command).test); + semicolon(); + cprintf(b" then\n\0" as *const u8 as *const libc::c_char); + indentation += indentation_amount; + make_command_string_internal((*if_command).true_case); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + indentation -= indentation_amount; + + if !(*if_command).false_case.is_null() { + semicolon(); + newline(b"else\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + indentation += indentation_amount; + make_command_string_internal((*if_command).false_case); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + indentation -= indentation_amount; + } + } + semicolon(); + newline(b"fi\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn print_arith_command(arith_cmd_list: *mut WordList) { + unsafe { + cprintf(b"((\0" as *const u8 as *const libc::c_char); + command_print_word_list( + arith_cmd_list, + CString::new(" ").unwrap().as_ptr() as *mut libc::c_char, + ); + cprintf(b"))\0" as *const u8 as *const libc::c_char); + } +} + +#[no_mangle] +pub fn print_cond_node(cond: *mut COND_COM) { + unsafe { + if (*cond).flags & CMD_INVERT_RETURN as i32 != 0 { + cprintf(b"! \0" as *const u8 as *const libc::c_char); + } + + if (*cond).type_0 == COND_EXPR as i32 { + cprintf(b"( \0" as *const u8 as *const libc::c_char); + print_cond_node((*cond).left); + cprintf(b" )\0" as *const u8 as *const libc::c_char); + } else if (*cond).type_0 == COND_AND as i32 { + print_cond_node((*cond).left); + cprintf(b" && \0" as *const u8 as *const libc::c_char); + print_cond_node((*cond).right); + } else if (*cond).type_0 == COND_OR as i32 { + print_cond_node((*cond).left); + cprintf(b" || \0" as *const u8 as *const libc::c_char); + print_cond_node((*cond).right); + } else if (*cond).type_0 == COND_UNARY as i32 { + cprintf((*(*cond).op).word); + cprintf(b" \0" as *const u8 as *const libc::c_char); + print_cond_node((*cond).left); + } else if (*cond).type_0 == COND_BINARY as i32 { + print_cond_node((*cond).left); + cprintf(b" \0" as *const u8 as *const libc::c_char); + cprintf((*(*cond).op).word); + cprintf(b" \0" as *const u8 as *const libc::c_char); + print_cond_node((*cond).right); + } else if (*cond).type_0 == COND_TERM as i32 { + cprintf( + b"%s\0" as *const u8 as *const libc::c_char, + (*(*cond).op).word, + ); + } + } +} + +#[no_mangle] +pub fn print_cond_command(cond: *mut COND_COM) { + unsafe { + cprintf(b"[[ \0" as *const u8 as *const libc::c_char); + print_cond_node(cond); + cprintf(b" ]]\0" as *const u8 as *const libc::c_char); + } +} + +//ifdef debug中没有内容 +#[no_mangle] +pub fn xtrace_print_cond_term( + type_0: libc::c_int, + invert: libc::c_int, + op: *mut WordDesc, + arg1: *mut libc::c_char, + arg2: *mut libc::c_char, +) { + unsafe { + CHECK_XTRACE_FP!(); + command_string_index = 0; + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + fprintf(xtrace_fp, CString::new("[[ ").unwrap().as_ptr()); + + if invert != 0 { + fprintf(xtrace_fp, CString::new("! ").unwrap().as_ptr()); + } + + if type_0 == COND_UNARY as i32 { + let str: *mut libc::c_char; + if !arg1.is_null() && *arg1 as libc::c_int != 0 { + str = arg1; + } else { + str = CString::new("''").unwrap().as_ptr() as *mut libc::c_char; + } + fprintf(xtrace_fp, CString::new("%s ").unwrap().as_ptr(), (*op).word); + fprintf(xtrace_fp, CString::new("%s ").unwrap().as_ptr(), str); + } else if type_0 == COND_BINARY as i32 { + let str1: *mut libc::c_char; + let str2: *mut libc::c_char; + if !arg1.is_null() && *arg1 as libc::c_int != 0 { + str1 = arg1; + } else { + str1 = CString::new("''").unwrap().as_ptr() as *mut libc::c_char; + } + + if !arg2.is_null() && *arg2 as libc::c_int != 0 { + str2 = arg2; + } else { + str2 = CString::new("''").unwrap().as_ptr() as *mut libc::c_char; + } + + fprintf(xtrace_fp, CString::new("%s ").unwrap().as_ptr(), str1); + fprintf(xtrace_fp, CString::new("%s ").unwrap().as_ptr(), (*op).word); + fprintf(xtrace_fp, CString::new("%s ").unwrap().as_ptr(), str2); + } + + fprintf(xtrace_fp, CString::new(" ]]\n").unwrap().as_ptr()); + + libc::fflush(xtrace_fp); + } +} + +#[no_mangle] +pub fn xtrace_print_arith_cmd(list: *mut WordList) { + let mut w: *mut WordList; + unsafe { + CHECK_XTRACE_FP!(); + fprintf( + xtrace_fp, + CString::new("%s").unwrap().as_ptr(), + indirection_level_string(), + ); + fprintf(xtrace_fp, CString::new("(( ").unwrap().as_ptr()); + + w = list; + while !w.is_null() { + let str: *const libc::c_char; + if !((*w).next).is_null() { + str = b" \0" as *const u8 as *const libc::c_char; + } else { + str = b"\0" as *const u8 as *const libc::c_char; + } + + fprintf( + xtrace_fp, + CString::new("%s%s").unwrap().as_ptr(), + (*(*w).word).word, + str, + ); + + w = (*w).next; + } + + fprintf(xtrace_fp, CString::new(" ))\n").unwrap().as_ptr()); + + libc::fflush(xtrace_fp); + } +} + +#[no_mangle] +pub fn print_simple_command(simple_command: *mut SIMPLE_COM) { + unsafe { + command_print_word_list( + (*simple_command).words, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + if !(*simple_command).redirects.is_null() { + cprintf(b" \0" as *const u8 as *const libc::c_char); + print_redirection_list((*simple_command).redirects); + } + } +} + +#[no_mangle] +pub fn print_heredocs(heredocs: *mut REDIRECT) { + let mut hdtail: *mut REDIRECT; + unsafe { + cprintf(b" \0" as *const u8 as *const libc::c_char); + + hdtail = heredocs; + while !hdtail.is_null() { + print_redirection(hdtail); + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + + hdtail = (*hdtail).next; + } + + was_heredoc = 1; + } +} + +#[no_mangle] +pub fn print_heredoc_bodies(heredocs: *mut REDIRECT) { + let mut hdtail: *mut REDIRECT; + unsafe { + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + hdtail = heredocs; + while !hdtail.is_null() { + print_heredoc_body(hdtail); + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + + hdtail = (*hdtail).next; + } + + was_heredoc = 1; + } +} + +#[no_mangle] +pub fn print_deferred_heredocs(cstring: *const libc::c_char) { + unsafe { + if !cstring.is_null() + && *cstring.offset(0) != 0 + && (*cstring.offset(0) != ';' as libc::c_char || *cstring.offset(1) != 0) + { + cprintf(cstring as *const libc::c_char); + } + + if !deferred_heredocs.is_null() { + print_heredoc_bodies(deferred_heredocs); + if !cstring.is_null() + && *cstring.offset(0) != 0 + && (*cstring.offset(0) != ';' as libc::c_char || *cstring.offset(1) != 0) + { + cprintf(b" \0" as *const u8 as *const libc::c_char); + } + dispose_redirects(deferred_heredocs); + was_heredoc = 1; + } + deferred_heredocs = std::ptr::null_mut() as *mut REDIRECT; + } +} + +#[no_mangle] +pub fn print_redirection_list(mut redirects: *mut REDIRECT) { + let mut heredocs: *mut REDIRECT; + let mut hdtail: *mut REDIRECT; + let mut newredir: *mut REDIRECT; + + let mut rw: *mut libc::c_char; + + heredocs = std::ptr::null_mut(); + hdtail = heredocs; + unsafe { + was_heredoc = 0; + + while !redirects.is_null() { + if (*redirects).instruction == r_instruction_r_reading_until + || (*redirects).instruction == r_instruction_r_deblank_reading_until + { + newredir = copy_redirect(redirects); + (*newredir).next = std::ptr::null_mut(); + + print_heredoc_header(newredir); + + if !heredocs.is_null() { + (*hdtail).next = newredir; + hdtail = newredir; + } else { + hdtail = newredir; + heredocs = newredir; + } + } else if (*redirects).instruction == r_instruction_r_duplicating_output_word + && ((*redirects).flags & REDIR_VARASSIGN as i32) == 0 + && (*redirects).redirector.dest == 1 + { + rw = (*(*redirects).redirectee.filename).word; + if !rw.is_null() + && *rw as libc::c_int != '-' as i32 + && DIGIT(*rw) == false + && EXPCHAR!(*rw) == 0 + { + (*redirects).instruction = r_instruction_r_err_and_out; + } + print_redirection(redirects); + (*redirects).instruction = r_instruction_r_duplicating_output_word; + } else { + print_redirection(redirects); + } + redirects = (*redirects).next; + if !redirects.is_null() { + cprintf(b" \0" as *const u8 as *const libc::c_char); + } + } + + if !heredocs.is_null() && printing_connection != 0 { + deferred_heredocs = heredocs; + } else if !heredocs.is_null() { + print_heredoc_bodies(heredocs); + dispose_redirects(heredocs); + } + } +} + +#[no_mangle] +pub fn print_heredoc_header(redirect: *mut REDIRECT) { + let kill_leading: libc::c_int; + let x: *mut libc::c_char; + unsafe { + kill_leading = + (r_instruction_r_deblank_reading_until == (*redirect).instruction) as libc::c_int; + + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*(*redirect).redirector.filename).word, + ); + } else if (*redirect).redirector.dest != 0 { + cprintf( + b"%d\0" as *const u8 as *const libc::c_char, + (*redirect).redirector.dest, + ) + } + if (*(*redirect).redirectee.filename).flags & W_QUOTED as i32 != 0 { + x = sh_single_quote((*redirect).here_doc_eof); + cprintf( + b"<<%s%s\0" as *const u8 as *const libc::c_char, + if kill_leading != 0 { + b"-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + x, + ); + libc::free(x as *mut c_void); + } else { + cprintf( + b"<<%s%s\0" as *const u8 as *const libc::c_char, + if kill_leading != 0 { + b"-\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }, + (*redirect).here_doc_eof, + ); + } + } +} + +#[no_mangle] +pub fn print_heredoc_body(redirect: *mut REDIRECT) { + unsafe { + cprintf( + b"%s%s\0" as *const u8 as *const libc::c_char, + (*(*redirect).redirectee.filename).word, + (*redirect).here_doc_eof, + ); + } +} + +#[no_mangle] +pub fn print_redirection(redirect: *mut REDIRECT) { + let redirector: libc::c_int; + let redir_fd: libc::c_int; + let redirectee: *mut WordDesc; + let redir_word: *mut WordDesc; + unsafe { + redirectee = (*redirect).redirectee.filename; + redir_fd = (*redirect).redirectee.dest; + + redir_word = (*redirect).redirector.filename; + redirector = (*redirect).redirector.dest; + + match (*redirect).instruction { + r_instruction_r_input_direction => { + if (*redirect).flags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else if !redirect.is_null() { + cprintf( + b"%d\0" as *const u8 as *const libc::c_char, + redirector as *mut libc::c_char, + ); + } + cprintf( + b"< %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + + r_instruction_r_output_direction => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else if redirector != 1 { + cprintf(b"%d\0" as *const u8 as *const libc::c_char, redirector); + } + cprintf( + b"> %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + + r_instruction_r_inputa_direction => { + cprintf(b"&\0" as *const u8 as *const libc::c_char); + } + + r_instruction_r_output_force => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else if redirector != 1 { + cprintf(b"%d\0" as *const u8 as *const libc::c_char, redirector); + } + cprintf( + b">| %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + + r_instruction_r_appending_to => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else if redirector != 1 { + cprintf(b"%d\0" as *const u8 as *const libc::c_char, redirector); + } + cprintf( + b">> %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + + r_instruction_r_input_output => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else if redirector != 1 { + cprintf( + b"%d\0" as *const u8 as *const libc::c_char, + redirector as *mut libc::c_char, + ); + } + cprintf( + b"<> %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + + r_instruction_r_deblank_reading_until | r_instruction_r_reading_until => { + print_heredoc_header(redirect); + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + print_heredoc_body(redirect); + } + + r_instruction_r_reading_string => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else if redirector != 0 { + cprintf( + b"%d\0" as *const u8 as *const libc::c_char, + redirector as *const libc::c_char, + ); + } + cprintf( + b"<<< %s\0" as *const u8 as *const libc::c_char, + (*(*redirect).redirectee.filename).word, + ); + } + + r_instruction_r_duplicating_input => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}<&%d\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + redir_fd, + ); + } else { + cprintf( + b"%d<&%d\0" as *const u8 as *const libc::c_char, + redirector, + redir_fd, + ); + } + } + + r_instruction_r_duplicating_output => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}>&%d\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + redir_fd, + ); + } else { + cprintf( + b"%d>&%d\0" as *const u8 as *const libc::c_char, + redirector, + redir_fd, + ); + } + } + + r_instruction_r_duplicating_input_word => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}<&%s\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + (*redirectee).word, + ); + } else { + cprintf( + b"%d<&%s\0" as *const u8 as *const libc::c_char, + redirector, + (*redirectee).word, + ); + } + } + + r_instruction_r_duplicating_output_word => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}>&%s\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + (*redirectee).word, + ); + } else { + cprintf( + b"%d>&%s\0" as *const u8 as *const libc::c_char, + redirector, + (*redirectee).word, + ); + } + } + + r_instruction_r_move_input => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}<&%d-\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + redir_fd, + ); + } else { + cprintf( + b"%d<&%d-\0" as *const u8 as *const libc::c_char, + redirector, + redir_fd, + ); + } + } + + r_instruction_r_move_output => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}>&%d-\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + redir_fd, + ); + } else { + cprintf( + b"%d>&%d-\0" as *const u8 as *const libc::c_char, + redirector, + redir_fd, + ); + } + } + + r_instruction_r_move_input_word => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}<&%s-\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + (*redirectee).word, + ); + } else { + cprintf( + b"%d<&%s-\0" as *const u8 as *const libc::c_char, + redirector, + (*redirectee).word, + ); + } + } + + r_instruction_r_move_output_word => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}>&%s-\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + (*redirectee).word, + ); + } else { + cprintf( + b"%d>&%s-\0" as *const u8 as *const libc::c_char, + redirector, + (*redirectee).word, + ); + } + } + + r_instruction_r_close_this => { + if (*redirect).rflags & REDIR_VARASSIGN as i32 != 0 { + cprintf( + b"{%s}>&-\0" as *const u8 as *const libc::c_char, + (*redir_word).word, + ); + } else { + cprintf(b"%d>&-\0" as *const u8 as *const libc::c_char, redirector); + } + } + + r_instruction_r_err_and_out => { + cprintf( + b"&> %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + + r_instruction_r_append_err_and_out => { + cprintf( + b"&>> %s\0" as *const u8 as *const libc::c_char, + (*redirectee).word, + ); + } + _ => {} + } + } +} + +#[no_mangle] +pub fn reset_locals() { + unsafe { + inside_function_def = 0; + indentation = 0; + printing_connection = 0; + deferred_heredocs = 0 as *mut REDIRECT; + } +} + +#[no_mangle] +pub fn print_function_def(func: *mut FUNCTION_DEF) { + let mut cmdcopy: *mut COMMAND; + let mut func_redirects: *mut REDIRECT; + + func_redirects = std::ptr::null_mut(); + unsafe { + if posixly_correct == 0 { + cprintf( + b"function %s () \n\0" as *const u8 as *const libc::c_char, + (*(*func).name).word, + ); + } else { + cprintf( + b"%s () \n\0" as *const u8 as *const libc::c_char, + (*(*func).name).word, + ); + } + + //add_unwind_protect(reset_locals, 0 ); + add_unwind_protect( + std::mem::transmute::>(reset_locals), + 0 as *mut libc::c_char, + ); + + indent(indentation); + cprintf(b"{ \n\0" as *const u8 as *const libc::c_char); + + inside_function_def += 1; + indentation += indentation_amount; + + cmdcopy = copy_command((*func).command); + if (*cmdcopy).type_0 == command_type_cm_group { + func_redirects = (*cmdcopy).redirects; + (*cmdcopy).redirects = 0 as *mut REDIRECT; + } + make_command_string_internal(if (*cmdcopy).type_0 == command_type_cm_group { + (*(*cmdcopy).value.Group).command + } else { + cmdcopy + }); + + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + + remove_unwind_protect(); + indentation -= indentation_amount; + inside_function_def -= 1; + + if !func_redirects.is_null() { + newline(b"} \0" as *const u8 as *const libc::c_char as *mut libc::c_char); + print_redirection_list(func_redirects); + (*cmdcopy).redirects = func_redirects; + } else { + newline(b"}\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + } + dispose_command(cmdcopy); +} + +#[no_mangle] +pub fn named_function_string( + name: *mut libc::c_char, + command: *mut COMMAND, + flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut result: *mut libc::c_char; + let old_indent: libc::c_int; + let old_amount: libc::c_int; + let mut cmdcopy: *mut COMMAND; + let mut func_redirects: *mut REDIRECT; + + old_indent = indentation; + old_amount = indentation_amount; + command_string_index = was_heredoc; + command_string_index = 0; + was_heredoc = 0; + deferred_heredocs = std::ptr::null_mut(); + + if !name.is_null() && *name as libc::c_int != 0 { + if find_reserved_word(name) >= 0 { + cprintf(b"function \0" as *const u8 as *const libc::c_char); + } + cprintf(name); + } + cprintf(b"() \0" as *const u8 as *const libc::c_char); + + if (flags & FUNC_MULTILINE) == 0 { + indentation = 1; + indentation_amount = 0; + } else { + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + indentation += indentation_amount; + } + + inside_function_def += 1; + + cprintf(if (flags & FUNC_MULTILINE) == 0 { + b"{ \n\0" as *const u8 as *const libc::c_char + } else { + b"{ \0" as *const u8 as *const libc::c_char + }); + + cmdcopy = copy_command(command); + + func_redirects = std::ptr::null_mut(); + if (*cmdcopy).type_0 == command_type_cm_group { + func_redirects = (*cmdcopy).redirects; + (*cmdcopy).redirects = 0 as *mut redirect; + } + make_command_string_internal(if (*cmdcopy).type_0 == command_type_cm_group { + (*(*cmdcopy).value.Group).command + } else { + cmdcopy + }); + PRINT_DEFERRED_HEREDOCS!(b"\0" as *const u8 as *const libc::c_char); + + indentation = old_indent; + indentation = old_amount; + indentation_amount = old_amount; + inside_function_def -= 1; + + if !func_redirects.is_null() { + newline(b"} \0" as *const u8 as *const libc::c_char as *mut libc::c_char); + print_redirection_list(func_redirects); + (*cmdcopy).redirects = func_redirects; + } else { + newline(b"}\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + + result = the_printed_command; + + if (flags & FUNC_MULTILINE) == 0 { + if *result.offset(2) == '\n' as libc::c_char { + libc::memmove( + result.offset(2) as *mut c_void, + result.offset(3) as *const c_void, + libc::strlen(result).wrapping_sub(2), + ); + } + } + + dispose_command(cmdcopy); + + if (flags & FUNC_EXTERNAL) != 0 { + result = remove_quoted_escapes(result); + } + + return result; + } +} + +#[no_mangle] +pub fn newline(string: *mut libc::c_char) { + unsafe { + cprintf(b"\n\0" as *const u8 as *const libc::c_char); + indent(indentation); + if !string.is_null() && *string as libc::c_int != 0 { + cprintf(string); + } + } +} + +static mut indentation_string: *mut libc::c_char = std::ptr::null_mut(); +static mut indentation_size: libc::c_int = 0; + +#[no_mangle] +fn indent(mut amount: libc::c_int) { + unsafe { + let mut i: libc::c_int; + RESIZE_MALLOCED_BUFFER!( + indentation_string, + 0 as libc::c_int, + amount, + indentation_size, + 16 + ); + + i = 0; + while amount > 0 { + *indentation_string.offset(i as isize) = ' ' as libc::c_char; + i += 1; + amount -= 1; + } + *indentation_string.offset(i as isize) = '\0' as libc::c_char; + cprintf(indentation_string); + } +} + +#[no_mangle] +fn semicolon() { + unsafe { + if command_string_index > 0 + && (*the_printed_command.offset((command_string_index - 1) as isize) + == '&' as libc::c_char + || *the_printed_command.offset((command_string_index - 1) as isize) + == '\n' as libc::c_char) + { + return; + } + + cprintf(b";\0" as *const u8 as *const libc::c_char); + } +} + +#[no_mangle] +fn the_printed_command_resize(length: libc::c_int) { + unsafe { + if the_printed_command.is_null() { + the_printed_command_size = + (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & !PRINTED_COMMAND_INITIAL_SIZE - 1; + the_printed_command = + libc::malloc(the_printed_command_size as usize) as *mut libc::c_char; + command_string_index = 0; + } else if (command_string_index + length) >= the_printed_command_size { + let mut new: libc::c_int; + new = command_string_index + length + 1; + new = (new + PRINTED_COMMAND_CROW_SIZE - 1) & !(PRINTED_COMMAND_CROW_SIZE - 1); + the_printed_command_size = new; + + the_printed_command = libc::realloc( + the_printed_command as *mut c_void, + the_printed_command_size as usize, + ) as *mut libc::c_char; + } + } +} diff --git a/utshell-0.5.0/src/readline.rs b/utshell-0.5.0/src/readline.rs new file mode 100644 index 00000000..9fd82477 --- /dev/null +++ b/utshell-0.5.0/src/readline.rs @@ -0,0 +1,7465 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +pub const control_character_threshold: u32 = 32; +pub const control_character_mask: u32 = 31; +pub const meta_character_threshold: u32 = 127; +pub const control_character_bit: u32 = 64; +pub const meta_character_bit: u32 = 128; +pub const largest_char: u32 = 255; +pub const NEWLINE: u8 = 10u8; +pub const RUBOUT: u32 = 127; +pub const TAB: u8 = 9u8; +pub const SPACE: u8 = 32u8; +pub const KEYMAP_SIZE: u32 = 257; +pub const ANYOTHERKEY: u32 = 256; +pub const ISKMAP: u32 = 1; +pub const ISMACR: u32 = 2; +pub const RL_READLINE_VERSION: u32 = 2049; +pub const RL_VERSION_MAJOR: u32 = 8; +pub const RL_VERSION_MINOR: u32 = 1; +pub const READERR: i32 = -2; +pub const RL_PROMPT_START_IGNORE: u8 = 1u8; +pub const RL_PROMPT_END_IGNORE: u8 = 2u8; +pub const NO_MATCH: u32 = 0; +pub const SINGLE_MATCH: u32 = 1; +pub const MULT_MATCH: u32 = 2; +pub const RL_STATE_NONE: u32 = 0; +pub const RL_STATE_INITIALIZING: u32 = 1; +pub const RL_STATE_INITIALIZED: u32 = 2; +pub const RL_STATE_TERMPREPPED: u32 = 4; +pub const RL_STATE_READCMD: u32 = 8; +pub const RL_STATE_METANEXT: u32 = 16; +pub const RL_STATE_DISPATCHING: u32 = 32; +pub const RL_STATE_MOREINPUT: u32 = 64; +pub const RL_STATE_ISEARCH: u32 = 128; +pub const RL_STATE_NSEARCH: u32 = 256; +pub const RL_STATE_SEARCH: u32 = 512; +pub const RL_STATE_NUMERICARG: u32 = 1024; +pub const RL_STATE_MACROINPUT: u32 = 2048; +pub const RL_STATE_MACRODEF: u32 = 4096; +pub const RL_STATE_OVERWRITE: u32 = 8192; +pub const RL_STATE_COMPLETING: u32 = 16384; +pub const RL_STATE_UNDOING: u32 = 65536; +pub const RL_STATE_INPUTPENDING: u32 = 131072; +pub const RL_STATE_TTYCSAVED: u32 = 262144; +pub const RL_STATE_CALLBACK: u32 = 524288; +pub const RL_STATE_VIMOTION: u32 = 1048576; +pub const RL_STATE_MULTIKEY: u32 = 2097152; +pub const RL_STATE_VICMDONCE: u32 = 4194304; +pub const RL_STATE_CHARSEARCH: u32 = 8388608; +pub const RL_STATE_REDISPLAYING: u32 = 16777216; +pub const RL_STATE_DONE: u32 = 33554432; +pub const MB_FIND_ANY: u32 = 0; +pub const MB_FIND_NONZERO: u32 = 1; +pub const DEFAULT_INPUTRC: &'static [u8; 11usize] = b"~/.inputrc\0"; +pub const SYS_INPUTRC: &'static [u8; 13usize] = b"/etc/inputrc\0"; +pub const RL_COMMENT_BEGIN_DEFAULT: &'static [u8; 2usize] = b"#\0"; +pub const RL_EMACS_MODESTR_DEFAULT: &'static [u8; 2usize] = b"@\0"; +pub const RL_EMACS_MODESTR_DEFLEN: u32 = 1; +pub const RL_VI_INS_MODESTR_DEFAULT: &'static [u8; 6usize] = b"(ins)\0"; +pub const RL_VI_INS_MODESTR_DEFLEN: u32 = 5; +pub const RL_VI_CMD_MODESTR_DEFAULT: &'static [u8; 6usize] = b"(cmd)\0"; +pub const RL_VI_CMD_MODESTR_DEFLEN: u32 = 5; +pub const RL_SEARCH_ISEARCH: u32 = 1; +pub const RL_SEARCH_NSEARCH: u32 = 2; +pub const RL_SEARCH_CSEARCH: u32 = 4; +pub const SF_REVERSE: u32 = 1; +pub const SF_FOUND: u32 = 2; +pub const SF_FAILED: u32 = 4; +pub const SF_CHGKMAP: u32 = 8; +pub const SF_PATTERN: u32 = 16; +pub const SF_NOCASE: u32 = 32; +pub const NUM_SAWMINUS: u32 = 1; +pub const NUM_SAWDIGITS: u32 = 2; +pub const NUM_READONE: u32 = 4; +pub const KSEQ_DISPATCHED: u32 = 1; +pub const KSEQ_SUBSEQ: u32 = 2; +pub const KSEQ_RECURSIVE: u32 = 4; +pub const VIM_DELETE: u32 = 1; +pub const VIM_CHANGE: u32 = 2; +pub const VIM_YANK: u32 = 4; +pub const VMSTATE_READ: u32 = 1; +pub const VMSTATE_NUMARG: u32 = 2; +pub const BRACKETED_PASTE_DEFAULT: u32 = 1; +pub const BRACK_PASTE_PREF: &'static [u8; 7usize] = b"\x1B[200~\0"; +pub const BRACK_PASTE_SUFF: &'static [u8; 7usize] = b"\x1B[201~\0"; +pub const BRACK_PASTE_LAST: u8 = 126u8; +pub const BRACK_PASTE_SLEN: u32 = 6; +pub const BRACK_PASTE_INIT: &'static [u8; 9usize] = b"\x1B[?2004h\0"; +pub const BRACK_PASTE_FINI: &'static [u8; 11usize] = b"\x1B[?2004l\\r\0"; +pub const _SYS_IOCTL_H: u32 = 1; +pub const _IOC_NRBITS: u32 = 8; +pub const _IOC_TYPEBITS: u32 = 8; +pub const _IOC_SIZEBITS: u32 = 14; +pub const _IOC_DIRBITS: u32 = 2; +pub const _IOC_NRMASK: u32 = 255; +pub const _IOC_TYPEMASK: u32 = 255; +pub const _IOC_SIZEMASK: u32 = 16383; +pub const _IOC_DIRMASK: u32 = 3; +pub const _IOC_NRSHIFT: u32 = 0; +pub const _IOC_TYPESHIFT: u32 = 8; +pub const _IOC_SIZESHIFT: u32 = 16; +pub const _IOC_DIRSHIFT: u32 = 30; +pub const _IOC_NONE: u32 = 0; +pub const _IOC_WRITE: u32 = 1; +pub const _IOC_READ: u32 = 2; +pub const IOC_IN: u32 = 1073741824; +pub const IOC_OUT: u32 = 2147483648; +pub const IOC_INOUT: u32 = 3221225472; +pub const IOCSIZE_MASK: u32 = 1073676288; +pub const IOCSIZE_SHIFT: u32 = 16; +pub const TCGETS: u32 = 21505; +pub const TCSETS: u32 = 21506; +pub const TCSETSW: u32 = 21507; +pub const TCSETSF: u32 = 21508; +pub const TCGETA: u32 = 21509; +pub const TCSETA: u32 = 21510; +pub const TCSETAW: u32 = 21511; +pub const TCSETAF: u32 = 21512; +pub const TCSBRK: u32 = 21513; +pub const TCXONC: u32 = 21514; +pub const TCFLSH: u32 = 21515; +pub const TIOCEXCL: u32 = 21516; +pub const TIOCNXCL: u32 = 21517; +pub const TIOCSCTTY: u32 = 21518; +pub const TIOCGPGRP: u32 = 21519; +pub const TIOCSPGRP: u32 = 21520; +pub const TIOCOUTQ: u32 = 21521; +pub const TIOCSTI: u32 = 21522; +pub const TIOCGWINSZ: u32 = 21523; +pub const TIOCSWINSZ: u32 = 21524; +pub const TIOCMGET: u32 = 21525; +pub const TIOCMBIS: u32 = 21526; +pub const TIOCMBIC: u32 = 21527; +pub const TIOCMSET: u32 = 21528; +pub const TIOCGSOFTCAR: u32 = 21529; +pub const TIOCSSOFTCAR: u32 = 21530; +pub const FIONREAD: u32 = 21531; +pub const TIOCINQ: u32 = 21531; +pub const TIOCLINUX: u32 = 21532; +pub const TIOCCONS: u32 = 21533; +pub const TIOCGSERIAL: u32 = 21534; +pub const TIOCSSERIAL: u32 = 21535; +pub const TIOCPKT: u32 = 21536; +pub const FIONBIO: u32 = 21537; +pub const TIOCNOTTY: u32 = 21538; +pub const TIOCSETD: u32 = 21539; +pub const TIOCGETD: u32 = 21540; +pub const TCSBRKP: u32 = 21541; +pub const TIOCSBRK: u32 = 21543; +pub const TIOCCBRK: u32 = 21544; +pub const TIOCGSID: u32 = 21545; +pub const TIOCGRS485: u32 = 21550; +pub const TIOCSRS485: u32 = 21551; +pub const TCGETX: u32 = 21554; +pub const TCSETX: u32 = 21555; +pub const TCSETXF: u32 = 21556; +pub const TCSETXW: u32 = 21557; +pub const TIOCVHANGUP: u32 = 21559; +pub const FIONCLEX: u32 = 21584; +pub const FIOCLEX: u32 = 21585; +pub const FIOASYNC: u32 = 21586; +pub const TIOCSERCONFIG: u32 = 21587; +pub const TIOCSERGWILD: u32 = 21588; +pub const TIOCSERSWILD: u32 = 21589; +pub const TIOCGLCKTRMIOS: u32 = 21590; +pub const TIOCSLCKTRMIOS: u32 = 21591; +pub const TIOCSERGSTRUCT: u32 = 21592; +pub const TIOCSERGETLSR: u32 = 21593; +pub const TIOCSERGETMULTI: u32 = 21594; +pub const TIOCSERSETMULTI: u32 = 21595; +pub const TIOCMIWAIT: u32 = 21596; +pub const TIOCGICOUNT: u32 = 21597; +pub const FIOQSIZE: u32 = 21600; +pub const TIOCPKT_DATA: u32 = 0; +pub const TIOCPKT_FLUSHREAD: u32 = 1; +pub const TIOCPKT_FLUSHWRITE: u32 = 2; +pub const TIOCPKT_STOP: u32 = 4; +pub const TIOCPKT_START: u32 = 8; +pub const TIOCPKT_NOSTOP: u32 = 16; +pub const TIOCPKT_DOSTOP: u32 = 32; +pub const TIOCPKT_IOCTL: u32 = 64; +pub const TIOCSER_TEMT: u32 = 1; +pub const SIOCADDRT: u32 = 35083; +pub const SIOCDELRT: u32 = 35084; +pub const SIOCRTMSG: u32 = 35085; +pub const SIOCGIFNAME: u32 = 35088; +pub const SIOCSIFLINK: u32 = 35089; +pub const SIOCGIFCONF: u32 = 35090; +pub const SIOCGIFFLAGS: u32 = 35091; +pub const SIOCSIFFLAGS: u32 = 35092; +pub const SIOCGIFADDR: u32 = 35093; +pub const SIOCSIFADDR: u32 = 35094; +pub const SIOCGIFDSTADDR: u32 = 35095; +pub const SIOCSIFDSTADDR: u32 = 35096; +pub const SIOCGIFBRDADDR: u32 = 35097; +pub const SIOCSIFBRDADDR: u32 = 35098; +pub const SIOCGIFNETMASK: u32 = 35099; +pub const SIOCSIFNETMASK: u32 = 35100; +pub const SIOCGIFMETRIC: u32 = 35101; +pub const SIOCSIFMETRIC: u32 = 35102; +pub const SIOCGIFMEM: u32 = 35103; +pub const SIOCSIFMEM: u32 = 35104; +pub const SIOCGIFMTU: u32 = 35105; +pub const SIOCSIFMTU: u32 = 35106; +pub const SIOCSIFNAME: u32 = 35107; +pub const SIOCSIFHWADDR: u32 = 35108; +pub const SIOCGIFENCAP: u32 = 35109; +pub const SIOCSIFENCAP: u32 = 35110; +pub const SIOCGIFHWADDR: u32 = 35111; +pub const SIOCGIFSLAVE: u32 = 35113; +pub const SIOCSIFSLAVE: u32 = 35120; +pub const SIOCADDMULTI: u32 = 35121; +pub const SIOCDELMULTI: u32 = 35122; +pub const SIOCGIFINDEX: u32 = 35123; +pub const SIOGIFINDEX: u32 = 35123; +pub const SIOCSIFPFLAGS: u32 = 35124; +pub const SIOCGIFPFLAGS: u32 = 35125; +pub const SIOCDIFADDR: u32 = 35126; +pub const SIOCSIFHWBROADCAST: u32 = 35127; +pub const SIOCGIFCOUNT: u32 = 35128; +pub const SIOCGIFBR: u32 = 35136; +pub const SIOCSIFBR: u32 = 35137; +pub const SIOCGIFTXQLEN: u32 = 35138; +pub const SIOCSIFTXQLEN: u32 = 35139; +pub const SIOCDARP: u32 = 35155; +pub const SIOCGARP: u32 = 35156; +pub const SIOCSARP: u32 = 35157; +pub const SIOCDRARP: u32 = 35168; +pub const SIOCGRARP: u32 = 35169; +pub const SIOCSRARP: u32 = 35170; +pub const SIOCGIFMAP: u32 = 35184; +pub const SIOCSIFMAP: u32 = 35185; +pub const SIOCADDDLCI: u32 = 35200; +pub const SIOCDELDLCI: u32 = 35201; +pub const SIOCDEVPRIVATE: u32 = 35312; +pub const SIOCPROTOPRIVATE: u32 = 35296; +pub const NCC: u32 = 8; +pub const TIOCM_LE: u32 = 1; +pub const TIOCM_DTR: u32 = 2; +pub const TIOCM_RTS: u32 = 4; +pub const TIOCM_ST: u32 = 8; +pub const TIOCM_SR: u32 = 16; +pub const TIOCM_CTS: u32 = 32; +pub const TIOCM_CAR: u32 = 64; +pub const TIOCM_RNG: u32 = 128; +pub const TIOCM_DSR: u32 = 256; +pub const TIOCM_CD: u32 = 64; +pub const TIOCM_RI: u32 = 128; +pub const N_TTY: u32 = 0; +pub const N_SLIP: u32 = 1; +pub const N_MOUSE: u32 = 2; +pub const N_PPP: u32 = 3; +pub const N_STRIP: u32 = 4; +pub const N_AX25: u32 = 5; +pub const N_X25: u32 = 6; +pub const N_6PACK: u32 = 7; +pub const N_MASC: u32 = 8; +pub const N_R3964: u32 = 9; +pub const N_PROFIBUS_FDL: u32 = 10; +pub const N_IRDA: u32 = 11; +pub const N_SMSBLOCK: u32 = 12; +pub const N_HDLC: u32 = 13; +pub const N_SYNC_PPP: u32 = 14; +pub const N_HCI: u32 = 15; +pub const no_mode: i32 = -1; +pub const vi_mode: u32 = 0; +pub const emacs_mode: u32 = 1; +pub const RL_IM_INSERT: u32 = 1; +pub const RL_IM_OVERWRITE: u32 = 0; +pub const RL_IM_DEFAULT: u32 = 1; +pub const NO_BELL: u32 = 0; +pub const AUDIBLE_BELL: u32 = 1; +pub const VISIBLE_BELL: u32 = 2; +pub const FTO: u32 = 1; +pub const BTO: i32 = -1; +pub const FFIND: u32 = 2; +pub const BFIND: i32 = -2; +pub const RL_QF_SINGLE_QUOTE: u32 = 1; +pub const RL_QF_DOUBLE_QUOTE: u32 = 2; +pub const RL_QF_BACKSLASH: u32 = 4; +pub const RL_QF_OTHER_QUOTE: u32 = 8; +pub const DEFAULT_BUFFER_SIZE: u32 = 256; +pub const NCURSES_TERMCAP_H_incl: u32 = 1; +pub const NCURSES_VERSION: &'static [u8; 4usize] = b"6.1\0"; +pub const NCURSES_DLL_H_incl: u32 = 1; +pub const EVENT_NOT_FOUND: u32 = 0; +pub const BAD_WORD_SPEC: u32 = 1; +pub const SUBST_FAILED: u32 = 2; +pub const BAD_MODIFIER: u32 = 3; +pub const NO_PREV_SUBST: u32 = 4; +pub const NON_ANCHORED_SEARCH: u32 = 0; +pub const ANCHORED_SEARCH: u32 = 1; +pub const PATTERN_SEARCH: u32 = 2; +pub const HISTORY_APPEND: u32 = 0; +pub const HISTORY_OVERWRITE: u32 = 1; +extern "C" { + pub fn wcscpy(__dest: *mut wchar_t, __src: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcsncpy(__dest: *mut wchar_t, __src: *const wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn wcscat(__dest: *mut wchar_t, __src: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcsncat(__dest: *mut wchar_t, __src: *const wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn wcscmp(__s1: *const wchar_t, __s2: *const wchar_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsncmp(__s1: *const wchar_t, __s2: *const wchar_t, __n: usize) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcscasecmp(__s1: *const wchar_t, __s2: *const wchar_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsncasecmp( + __s1: *const wchar_t, + __s2: *const wchar_t, + __n: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcscasecmp_l( + __s1: *const wchar_t, + __s2: *const wchar_t, + __loc: locale_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsncasecmp_l( + __s1: *const wchar_t, + __s2: *const wchar_t, + __n: usize, + __loc: locale_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcscoll(__s1: *const wchar_t, __s2: *const wchar_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsxfrm(__s1: *mut wchar_t, __s2: *const wchar_t, __n: usize) -> usize; +} +extern "C" { + pub fn wcscoll_l( + __s1: *const wchar_t, + __s2: *const wchar_t, + __loc: locale_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsxfrm_l( + __s1: *mut wchar_t, + __s2: *const wchar_t, + __n: usize, + __loc: locale_t, + ) -> usize; +} +extern "C" { + pub fn wcsdup(__s: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcschr(__wcs: *const wchar_t, __wc: wchar_t) -> *mut ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsrchr(__wcs: *const wchar_t, __wc: wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcschrnul(__s: *const wchar_t, __wc: wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcscspn(__wcs: *const wchar_t, __reject: *const wchar_t) -> usize; +} +extern "C" { + pub fn wcsspn(__wcs: *const wchar_t, __accept: *const wchar_t) -> usize; +} +extern "C" { + pub fn wcspbrk(__wcs: *const wchar_t, __accept: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcsstr(__haystack: *const wchar_t, __needle: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcstok( + __s: *mut wchar_t, + __delim: *const wchar_t, + __ptr: *mut *mut wchar_t, + ) -> *mut wchar_t; +} +extern "C" { + pub fn wcslen(__s: *const wchar_t) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn wcswcs(__haystack: *const wchar_t, __needle: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcsnlen(__s: *const wchar_t, __maxlen: usize) -> usize; +} +extern "C" { + pub fn wmemchr(__s: *const wchar_t, __c: wchar_t, __n: usize) -> *mut ::std::os::raw::c_int; +} +extern "C" { + pub fn wmemcmp(__s1: *const wchar_t, __s2: *const wchar_t, __n: usize) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wmemcpy(__s1: *mut wchar_t, __s2: *const wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn wmemmove(__s1: *mut wchar_t, __s2: *const wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn wmemset(__s: *mut wchar_t, __c: wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn wmempcpy(__s1: *mut wchar_t, __s2: *const wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn btowc(__c: ::std::os::raw::c_int) -> wint_t; +} +extern "C" { + pub fn wctob(__c: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mbsinit(__ps: *const mbstate_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcrtomb(__s: *mut ::std::os::raw::c_char, __wc: wchar_t, __ps: *mut mbstate_t) -> usize; +} +extern "C" { + pub fn mbsrtowcs( + __dst: *mut wchar_t, + __src: *mut *const ::std::os::raw::c_char, + __len: usize, + __ps: *mut mbstate_t, + ) -> usize; +} +extern "C" { + pub fn wcsrtombs( + __dst: *mut ::std::os::raw::c_char, + __src: *mut *const wchar_t, + __len: usize, + __ps: *mut mbstate_t, + ) -> usize; +} +extern "C" { + pub fn mbsnrtowcs( + __dst: *mut wchar_t, + __src: *mut *const ::std::os::raw::c_char, + __nmc: usize, + __len: usize, + __ps: *mut mbstate_t, + ) -> usize; +} +extern "C" { + pub fn wcsnrtombs( + __dst: *mut ::std::os::raw::c_char, + __src: *mut *const wchar_t, + __nwc: usize, + __len: usize, + __ps: *mut mbstate_t, + ) -> usize; +} +extern "C" { + pub fn wcwidth(__c: wchar_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcswidth(__s: *const wchar_t, __n: usize) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcstod(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> f64; +} +extern "C" { + pub fn wcstof(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> f32; +} +extern "C" { + pub fn wcstold(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> f64; +} +extern "C" { + pub fn wcstof32(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> _Float32; +} +extern "C" { + pub fn wcstof64(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> _Float64; +} +extern "C" { + pub fn wcstof32x(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> _Float32x; +} +extern "C" { + pub fn wcstof64x(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t) -> _Float64x; +} +extern "C" { + pub fn wcstoll_l( + __nptr: *const wchar_t, + __endptr: *mut *mut wchar_t, + __base: ::std::os::raw::c_int, + __loc: locale_t, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn wcstoull_l( + __nptr: *const wchar_t, + __endptr: *mut *mut wchar_t, + __base: ::std::os::raw::c_int, + __loc: locale_t, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn wcstod_l(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t, __loc: locale_t) -> f64; +} +extern "C" { + pub fn wcstof_l(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t, __loc: locale_t) -> f32; +} +extern "C" { + pub fn wcstold_l(__nptr: *const wchar_t, __endptr: *mut *mut wchar_t, __loc: locale_t) -> f64; +} +extern "C" { + pub fn wcstof32_l( + __nptr: *const wchar_t, + __endptr: *mut *mut wchar_t, + __loc: locale_t, + ) -> _Float32; +} +extern "C" { + pub fn wcstof64_l( + __nptr: *const wchar_t, + __endptr: *mut *mut wchar_t, + __loc: locale_t, + ) -> _Float64; +} +extern "C" { + pub fn wcstof32x_l( + __nptr: *const wchar_t, + __endptr: *mut *mut wchar_t, + __loc: locale_t, + ) -> _Float32x; +} +extern "C" { + pub fn wcstof64x_l( + __nptr: *const wchar_t, + __endptr: *mut *mut wchar_t, + __loc: locale_t, + ) -> _Float64x; +} +extern "C" { + pub fn wcpcpy(__dest: *mut wchar_t, __src: *const wchar_t) -> *mut wchar_t; +} +extern "C" { + pub fn wcpncpy(__dest: *mut wchar_t, __src: *const wchar_t, __n: usize) -> *mut wchar_t; +} +extern "C" { + pub fn open_wmemstream(__bufloc: *mut *mut wchar_t, __sizeloc: *mut usize) -> *mut FILE; +} +extern "C" { + pub fn fwide(__fp: *mut FILE, __mode: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fwprintf(__stream: *mut FILE, __format: *const wchar_t, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wprintf(__format: *const wchar_t, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn swprintf( + __s: *mut wchar_t, + __n: usize, + __format: *const wchar_t, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vfwprintf( + __s: *mut FILE, + __format: *const wchar_t, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vwprintf(__format: *const wchar_t, __arg: *mut __va_list_tag) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vswprintf( + __s: *mut wchar_t, + __n: usize, + __format: *const wchar_t, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fwscanf(__stream: *mut FILE, __format: *const wchar_t, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wscanf(__format: *const wchar_t, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn swscanf(__s: *const wchar_t, __format: *const wchar_t, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vfwscanf( + __s: *mut FILE, + __format: *const wchar_t, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vwscanf(__format: *const wchar_t, __arg: *mut __va_list_tag) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vswscanf( + __s: *const wchar_t, + __format: *const wchar_t, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgetwc(__stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn getwc(__stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn getwchar() -> wint_t; +} +extern "C" { + pub fn fputwc(__wc: wchar_t, __stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn putwc(__wc: wchar_t, __stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn putwchar(__wc: wchar_t) -> wint_t; +} +extern "C" { + pub fn fgetws( + __ws: *mut wchar_t, + __n: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> *mut wchar_t; +} +extern "C" { + pub fn fputws(__ws: *const wchar_t, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ungetwc(__wc: wint_t, __stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn getwc_unlocked(__stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn getwchar_unlocked() -> wint_t; +} +extern "C" { + pub fn fgetwc_unlocked(__stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn fputwc_unlocked(__wc: wchar_t, __stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn putwc_unlocked(__wc: wchar_t, __stream: *mut FILE) -> wint_t; +} +extern "C" { + pub fn putwchar_unlocked(__wc: wchar_t) -> wint_t; +} +extern "C" { + pub fn fgetws_unlocked( + __ws: *mut wchar_t, + __n: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> *mut wchar_t; +} +extern "C" { + pub fn fputws_unlocked(__ws: *const wchar_t, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wcsftime( + __s: *mut wchar_t, + __maxsize: usize, + __format: *const wchar_t, + __tp: *const tm, + ) -> usize; +} +extern "C" { + pub fn wcsftime_l( + __s: *mut wchar_t, + __maxsize: usize, + __format: *const wchar_t, + __tp: *const tm, + __loc: locale_t, + ) -> usize; +} +extern "C" { + pub fn iswalnum(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswalpha(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswcntrl(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswdigit(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswgraph(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswlower(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswprint(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswpunct(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswspace(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswupper(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswxdigit(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswblank(__wc: wint_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wctype(__property: *const ::std::os::raw::c_char) -> wctype_t; +} +extern "C" { + pub fn iswctype(__wc: wint_t, __desc: wctype_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn towlower(__wc: wint_t) -> wint_t; +} +extern "C" { + pub fn towupper(__wc: wint_t) -> wint_t; +} +pub type wctrans_t = *const __int32_t; +extern "C" { + pub fn wctrans(__property: *const ::std::os::raw::c_char) -> wctrans_t; +} +extern "C" { + pub fn towctrans(__wc: wint_t, __desc: wctrans_t) -> wint_t; +} +extern "C" { + pub fn iswalnum_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswalpha_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswcntrl_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswdigit_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswgraph_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswlower_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswprint_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswpunct_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswspace_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswupper_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswxdigit_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iswblank_l(__wc: wint_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wctype_l(__property: *const ::std::os::raw::c_char, __locale: locale_t) -> wctype_t; +} +extern "C" { + pub fn iswctype_l(__wc: wint_t, __desc: wctype_t, __locale: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn towlower_l(__wc: wint_t, __locale: locale_t) -> wint_t; +} +extern "C" { + pub fn towupper_l(__wc: wint_t, __locale: locale_t) -> wint_t; +} +extern "C" { + pub fn wctrans_l(__property: *const ::std::os::raw::c_char, __locale: locale_t) -> wctrans_t; +} +extern "C" { + pub fn towctrans_l(__wc: wint_t, __desc: wctrans_t, __locale: locale_t) -> wint_t; +} +extern "C" { + pub fn access( + __name: *const ::std::os::raw::c_char, + __type: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn euidaccess( + __name: *const ::std::os::raw::c_char, + __type: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn eaccess( + __name: *const ::std::os::raw::c_char, + __type: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn faccessat( + __fd: ::std::os::raw::c_int, + __file: *const ::std::os::raw::c_char, + __type: ::std::os::raw::c_int, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lseek64( + __fd: ::std::os::raw::c_int, + __offset: __off64_t, + __whence: ::std::os::raw::c_int, + ) -> __off64_t; +} +extern "C" { + pub fn read( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_void, + __nbytes: usize, + ) -> isize; +} +extern "C" { + pub fn write( + __fd: ::std::os::raw::c_int, + __buf: *const ::std::os::raw::c_void, + __n: usize, + ) -> isize; +} +extern "C" { + pub fn pread( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_void, + __nbytes: usize, + __offset: __off_t, + ) -> isize; +} +extern "C" { + pub fn pwrite( + __fd: ::std::os::raw::c_int, + __buf: *const ::std::os::raw::c_void, + __n: usize, + __offset: __off_t, + ) -> isize; +} +extern "C" { + pub fn pread64( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_void, + __nbytes: usize, + __offset: __off64_t, + ) -> isize; +} +extern "C" { + pub fn pwrite64( + __fd: ::std::os::raw::c_int, + __buf: *const ::std::os::raw::c_void, + __n: usize, + __offset: __off64_t, + ) -> isize; +} +extern "C" { + pub fn pipe2( + __pipedes: *mut ::std::os::raw::c_int, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn alarm(__seconds: ::std::os::raw::c_uint) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn sleep(__seconds: ::std::os::raw::c_uint) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn ualarm(__value: __useconds_t, __interval: __useconds_t) -> __useconds_t; +} +extern "C" { + pub fn usleep(__useconds: __useconds_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pause() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn chown( + __file: *const ::std::os::raw::c_char, + __owner: __uid_t, + __group: __gid_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fchown( + __fd: ::std::os::raw::c_int, + __owner: __uid_t, + __group: __gid_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lchown( + __file: *const ::std::os::raw::c_char, + __owner: __uid_t, + __group: __gid_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fchownat( + __fd: ::std::os::raw::c_int, + __file: *const ::std::os::raw::c_char, + __owner: __uid_t, + __group: __gid_t, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn chdir(__path: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fchdir(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getcwd(__buf: *mut ::std::os::raw::c_char, __size: usize) + -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn get_current_dir_name() -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn getwd(__buf: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn dup(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn dup3( + __fd: ::std::os::raw::c_int, + __fd2: ::std::os::raw::c_int, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__environ"] + pub static mut __environ: *mut *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}environ"] + pub static mut environ: *mut *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn execve( + __path: *const ::std::os::raw::c_char, + __argv: *const *mut ::std::os::raw::c_char, + __envp: *const *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fexecve( + __fd: ::std::os::raw::c_int, + __argv: *const *mut ::std::os::raw::c_char, + __envp: *const *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn execv( + __path: *const ::std::os::raw::c_char, + __argv: *const *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn execle( + __path: *const ::std::os::raw::c_char, + __arg: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn execl( + __path: *const ::std::os::raw::c_char, + __arg: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn execvp( + __file: *const ::std::os::raw::c_char, + __argv: *const *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn execlp( + __file: *const ::std::os::raw::c_char, + __arg: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn execvpe( + __file: *const ::std::os::raw::c_char, + __argv: *const *mut ::std::os::raw::c_char, + __envp: *const *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn nice(__inc: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _exit(__status: ::std::os::raw::c_int); +} +extern "C" { + pub fn pathconf( + __path: *const ::std::os::raw::c_char, + __name: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn fpathconf( + __fd: ::std::os::raw::c_int, + __name: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn sysconf(__name: ::std::os::raw::c_int) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn confstr( + __name: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> usize; +} +extern "C" { + pub fn getpid() -> __pid_t; +} +extern "C" { + pub fn getppid() -> __pid_t; +} +extern "C" { + pub fn getpgrp() -> __pid_t; +} +extern "C" { + pub fn __getpgid(__pid: __pid_t) -> __pid_t; +} +extern "C" { + pub fn getpgid(__pid: __pid_t) -> __pid_t; +} +extern "C" { + pub fn setpgid(__pid: __pid_t, __pgid: __pid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setpgrp() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setsid() -> __pid_t; +} +extern "C" { + pub fn getsid(__pid: __pid_t) -> __pid_t; +} +extern "C" { + pub fn getuid() -> __uid_t; +} +extern "C" { + pub fn geteuid() -> __uid_t; +} +extern "C" { + pub fn getgid() -> __gid_t; +} +extern "C" { + pub fn getegid() -> __gid_t; +} +extern "C" { + pub fn group_member(__gid: __gid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setuid(__uid: __uid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setreuid(__ruid: __uid_t, __euid: __uid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn seteuid(__uid: __uid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setgid(__gid: __gid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setregid(__rgid: __gid_t, __egid: __gid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setegid(__gid: __gid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getresuid( + __ruid: *mut __uid_t, + __euid: *mut __uid_t, + __suid: *mut __uid_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getresgid( + __rgid: *mut __gid_t, + __egid: *mut __gid_t, + __sgid: *mut __gid_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setresuid(__ruid: __uid_t, __euid: __uid_t, __suid: __uid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setresgid(__rgid: __gid_t, __egid: __gid_t, __sgid: __gid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fork() -> __pid_t; +} +extern "C" { + pub fn vfork() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ttyname_r( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __buflen: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isatty(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ttyslot() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn link( + __from: *const ::std::os::raw::c_char, + __to: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn linkat( + __fromfd: ::std::os::raw::c_int, + __from: *const ::std::os::raw::c_char, + __tofd: ::std::os::raw::c_int, + __to: *const ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn symlink( + __from: *const ::std::os::raw::c_char, + __to: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn readlink( + __path: *const ::std::os::raw::c_char, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> isize; +} +extern "C" { + pub fn symlinkat( + __from: *const ::std::os::raw::c_char, + __tofd: ::std::os::raw::c_int, + __to: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn readlinkat( + __fd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> isize; +} +extern "C" { + pub fn unlink(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn unlinkat( + __fd: ::std::os::raw::c_int, + __name: *const ::std::os::raw::c_char, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rmdir(__path: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tcgetpgrp(__fd: ::std::os::raw::c_int) -> __pid_t; +} +extern "C" { + pub fn tcsetpgrp(__fd: ::std::os::raw::c_int, __pgrp_id: __pid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getlogin() -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn getlogin_r( + __name: *mut ::std::os::raw::c_char, + __name_len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setlogin(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}optarg"] + pub static mut optarg: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}optind"] + pub static mut optind: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}opterr"] + pub static mut opterr: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}optopt"] + pub static mut optopt: ::std::os::raw::c_int; +} +extern "C" { + pub fn getopt( + ___argc: ::std::os::raw::c_int, + ___argv: *const *mut ::std::os::raw::c_char, + __shortopts: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn gethostname(__name: *mut ::std::os::raw::c_char, __len: usize) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sethostname( + __name: *const ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sethostid(__id: ::std::os::raw::c_long) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getdomainname( + __name: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setdomainname( + __name: *const ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vhangup() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn revoke(__file: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn profil( + __sample_buffer: *mut ::std::os::raw::c_ushort, + __size: usize, + __offset: usize, + __scale: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn acct(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getusershell() -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn endusershell(); +} +extern "C" { + pub fn setusershell(); +} +extern "C" { + pub fn daemon( + __nochdir: ::std::os::raw::c_int, + __noclose: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn chroot(__path: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getpass(__prompt: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn fsync(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn syncfs(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn gethostid() -> ::std::os::raw::c_long; +} +extern "C" { + pub fn sync(); +} +extern "C" { + pub fn getpagesize() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn truncate( + __file: *const ::std::os::raw::c_char, + __length: __off_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn truncate64( + __file: *const ::std::os::raw::c_char, + __length: __off64_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftruncate(__fd: ::std::os::raw::c_int, __length: __off_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftruncate64(__fd: ::std::os::raw::c_int, __length: __off64_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn brk(__addr: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sbrk(__delta: isize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn syscall(__sysno: ::std::os::raw::c_long, ...) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn lockf( + __fd: ::std::os::raw::c_int, + __cmd: ::std::os::raw::c_int, + __len: __off_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lockf64( + __fd: ::std::os::raw::c_int, + __cmd: ::std::os::raw::c_int, + __len: __off64_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn copy_file_range( + __infd: ::std::os::raw::c_int, + __pinoff: *mut __off64_t, + __outfd: ::std::os::raw::c_int, + __poutoff: *mut __off64_t, + __length: usize, + __flags: ::std::os::raw::c_uint, + ) -> isize; +} +extern "C" { + pub fn fdatasync(__fildes: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn crypt( + __key: *const ::std::os::raw::c_char, + __salt: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn swab( + __from: *const ::std::os::raw::c_void, + __to: *mut ::std::os::raw::c_void, + __n: isize, + ); +} +extern "C" { + pub fn getentropy( + __buffer: *mut ::std::os::raw::c_void, + __length: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __sysv_signal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) + -> __sighandler_t; +} +extern "C" { + pub fn sysv_signal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) -> __sighandler_t; +} +extern "C" { + pub fn signal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) -> __sighandler_t; +} +extern "C" { + pub fn kill(__pid: __pid_t, __sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn killpg(__pgrp: __pid_t, __sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn raise(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ssignal(__sig: ::std::os::raw::c_int, __handler: __sighandler_t) -> __sighandler_t; +} +extern "C" { + pub fn gsignal(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn psignal(__sig: ::std::os::raw::c_int, __s: *const ::std::os::raw::c_char); +} +extern "C" { + pub fn psiginfo(__pinfo: *const siginfo_t, __s: *const ::std::os::raw::c_char); +} +extern "C" { + #[link_name = "\u{1}__xpg_sigpause"] + pub fn sigpause(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigblock(__mask: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigsetmask(__mask: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn siggetmask() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigemptyset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigfillset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigaddset(__set: *mut sigset_t, __signo: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigdelset(__set: *mut sigset_t, __signo: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigismember( + __set: *const sigset_t, + __signo: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigisemptyset(__set: *const sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigandset( + __set: *mut sigset_t, + __left: *const sigset_t, + __right: *const sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigorset( + __set: *mut sigset_t, + __left: *const sigset_t, + __right: *const sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigprocmask( + __how: ::std::os::raw::c_int, + __set: *const sigset_t, + __oset: *mut sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigsuspend(__set: *const sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigaction( + __sig: ::std::os::raw::c_int, + __act: *const sigaction, + __oact: *mut sigaction, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigpending(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigwait( + __set: *const sigset_t, + __sig: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigwaitinfo(__set: *const sigset_t, __info: *mut siginfo_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigtimedwait( + __set: *const sigset_t, + __info: *mut siginfo_t, + __timeout: *const timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigqueue( + __pid: __pid_t, + __sig: ::std::os::raw::c_int, + __val: sigval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_sys_siglist"] + pub static mut _sys_siglist: [*const ::std::os::raw::c_char; 65usize]; +} +extern "C" { + #[link_name = "\u{1}sys_siglist"] + pub static mut sys_siglist: [*const ::std::os::raw::c_char; 65usize]; +} +extern "C" { + pub fn sigstack(__ss: *mut sigstack, __oss: *mut sigstack) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sighold(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigrelse(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigignore(__sig: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sigset(__sig: ::std::os::raw::c_int, __disp: __sighandler_t) -> __sighandler_t; +} +extern "C" { + pub fn pthread_sigmask( + __how: ::std::os::raw::c_int, + __newmask: *const __sigset_t, + __oldmask: *mut __sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pthread_kill( + __threadid: pthread_t, + __signo: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pthread_sigqueue( + __threadid: pthread_t, + __signo: ::std::os::raw::c_int, + __value: sigval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __libc_current_sigrtmin() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __libc_current_sigrtmax() -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union command__bindgen_ty_1 { + pub For: *mut for_com, + pub Case: *mut case_com, + pub While: *mut while_com, + pub If: *mut if_com, + pub Connection: *mut connection, + pub Simple: *mut simple_com, + pub Function_def: *mut function_def, + pub Group: *mut group_com, + pub Select: *mut select_com, + pub Arith: *mut arith_com, + pub Cond: *mut cond_com, + pub ArithFor: *mut arith_for_com, + pub Subshell: *mut subshell_com, + pub Coproc: *mut coproc_com, + _bindgen_union_align: u64, +} +extern "C" { + pub fn copy_function_def_contents( + arg1: *mut FUNCTION_DEF, + arg2: *mut FUNCTION_DEF, + ) -> *mut FUNCTION_DEF; +} +extern "C" { + pub fn copy_function_def(arg1: *mut FUNCTION_DEF) -> *mut FUNCTION_DEF; +} +extern "C" { + pub fn copy_word(arg1: *mut WordDesc) -> *mut WordDesc; +} +extern "C" { + pub fn copy_WordList(arg1: *mut WordList) -> *mut WordList; +} +extern "C" { + pub fn copy_command(arg1: *mut COMMAND) -> *mut COMMAND; +} + +extern "C" { + pub fn select( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *mut timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pselect( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *const timespec, + __sigmask: *const __sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn imaxabs(__n: intmax_t) -> intmax_t; +} +extern "C" { + pub fn imaxdiv(__numer: intmax_t, __denom: intmax_t) -> imaxdiv_t; +} +extern "C" { + pub fn strtoimax( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> intmax_t; +} +extern "C" { + pub fn strtoumax( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> uintmax_t; +} +extern "C" { + pub fn wcstoimax( + __nptr: *const __gwchar_t, + __endptr: *mut *mut __gwchar_t, + __base: ::std::os::raw::c_int, + ) -> intmax_t; +} +extern "C" { + pub fn wcstoumax( + __nptr: *const __gwchar_t, + __endptr: *mut *mut __gwchar_t, + __base: ::std::os::raw::c_int, + ) -> uintmax_t; +} +extern "C" { + pub fn __ctype_tolower_loc() -> *mut *const __int32_t; +} +extern "C" { + pub fn __ctype_toupper_loc() -> *mut *const __int32_t; +} +extern "C" { + pub fn isalnum(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isalpha(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iscntrl(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isdigit(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn islower(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isgraph(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isprint(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ispunct(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isspace(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isupper(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isxdigit(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tolower(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn toupper(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isblank(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isctype( + __c: ::std::os::raw::c_int, + __mask: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isascii(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn toascii(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _toupper(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _tolower(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isalnum_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isalpha_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn iscntrl_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isdigit_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn islower_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isgraph_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isprint_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ispunct_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isspace_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isupper_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isxdigit_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn isblank_l(arg1: ::std::os::raw::c_int, arg2: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __tolower_l(__c: ::std::os::raw::c_int, __l: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tolower_l(__c: ::std::os::raw::c_int, __l: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __toupper_l(__c: ::std::os::raw::c_int, __l: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn toupper_l(__c: ::std::os::raw::c_int, __l: locale_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn gettimeofday(__tv: *mut timeval, __tz: __timezone_ptr_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn settimeofday(__tv: *const timeval, __tz: *const timezone) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn adjtime(__delta: *const timeval, __olddelta: *mut timeval) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getitimer(__which: __itimer_which_t, __value: *mut itimerval) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setitimer( + __which: __itimer_which_t, + __new: *const itimerval, + __old: *mut itimerval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn utimes( + __file: *const ::std::os::raw::c_char, + __tvp: *const timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lutimes( + __file: *const ::std::os::raw::c_char, + __tvp: *const timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn futimes(__fd: ::std::os::raw::c_int, __tvp: *const timeval) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn futimesat( + __fd: ::std::os::raw::c_int, + __file: *const ::std::os::raw::c_char, + __tvp: *const timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn prlimit( + __pid: __pid_t, + __resource: __rlimit_resource, + __new_limit: *const rlimit, + __old_limit: *mut rlimit, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn prlimit64( + __pid: __pid_t, + __resource: __rlimit_resource, + __new_limit: *const rlimit64, + __old_limit: *mut rlimit64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getrlimit( + __resource: __rlimit_resource_t, + __rlimits: *mut rlimit, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getrlimit64( + __resource: __rlimit_resource_t, + __rlimits: *mut rlimit64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setrlimit( + __resource: __rlimit_resource_t, + __rlimits: *const rlimit, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setrlimit64( + __resource: __rlimit_resource_t, + __rlimits: *const rlimit64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getrusage(__who: __rusage_who_t, __usage: *mut rusage) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getpriority(__which: __priority_which_t, __who: id_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setpriority( + __which: __priority_which_t, + __who: id_t, + __prio: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn memcpy( + __dest: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn memccpy( + __dest: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn memcmp( + __s1: *const ::std::os::raw::c_void, + __s2: *const ::std::os::raw::c_void, + __n: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn memchr( + __s: *const ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn rawmemchr( + __s: *const ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn memrchr( + __s: *const ::std::os::raw::c_void, + __c: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn strcpy( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strncat( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strcoll( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strxfrm( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn strcoll_l( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __l: locale_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strxfrm_l( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: usize, + __l: locale_t, + ) -> usize; +} +extern "C" { + pub fn strdup(__s: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strndup( + __string: *const ::std::os::raw::c_char, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strchr( + __s: *const ::std::os::raw::c_char, + __c: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strchrnul( + __s: *const ::std::os::raw::c_char, + __c: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strcspn( + __s: *const ::std::os::raw::c_char, + __reject: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn strspn( + __s: *const ::std::os::raw::c_char, + __accept: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_ulong; +} + +extern "C" { + pub fn strstr( + __haystack: *const ::std::os::raw::c_char, + __needle: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strtok( + __s: *mut ::std::os::raw::c_char, + __delim: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn __strtok_r( + __s: *mut ::std::os::raw::c_char, + __delim: *const ::std::os::raw::c_char, + __save_ptr: *mut *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strtok_r( + __s: *mut ::std::os::raw::c_char, + __delim: *const ::std::os::raw::c_char, + __save_ptr: *mut *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strcasestr( + __haystack: *const ::std::os::raw::c_char, + __needle: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn memmem( + __haystack: *const ::std::os::raw::c_void, + __haystacklen: usize, + __needle: *const ::std::os::raw::c_void, + __needlelen: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn __mempcpy( + __dest: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn mempcpy( + __dest: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn strnlen(__string: *const ::std::os::raw::c_char, __maxlen: usize) -> usize; +} +extern "C" { + pub fn strerror(__errnum: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strerror_r( + __errnum: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __buflen: usize, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strerror_l( + __errnum: ::std::os::raw::c_int, + __l: locale_t, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn bcmp( + __s1: *const ::std::os::raw::c_void, + __s2: *const ::std::os::raw::c_void, + __n: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn bcopy( + __src: *const ::std::os::raw::c_void, + __dest: *mut ::std::os::raw::c_void, + __n: usize, + ); +} +extern "C" { + pub fn bzero(__s: *mut ::std::os::raw::c_void, __n: usize); +} +extern "C" { + pub fn index( + __s: *const ::std::os::raw::c_char, + __c: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rindex( + __s: *const ::std::os::raw::c_char, + __c: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ffs(__i: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ffsl(__l: ::std::os::raw::c_long) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ffsll(__ll: ::std::os::raw::c_longlong) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strcasecmp( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strcasecmp_l( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __loc: locale_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strncasecmp_l( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __n: usize, + __loc: locale_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn explicit_bzero(__s: *mut ::std::os::raw::c_void, __n: usize); +} +extern "C" { + pub fn strsep( + __stringp: *mut *mut ::std::os::raw::c_char, + __delim: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strsignal(__sig: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn __stpcpy( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn stpcpy( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn __stpncpy( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn stpncpy( + __dest: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strverscmp( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfry(__string: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn memfrob(__s: *mut ::std::os::raw::c_void, __n: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn basename(__filename: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +// extern "C" { +// pub fn __ctype_get_mb_cur_max() -> usize; +// } +extern "C" { + pub fn atof(__nptr: *const ::std::os::raw::c_char) -> f64; +} +extern "C" { + pub fn atoi(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn atol(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn atoll(__nptr: *const ::std::os::raw::c_char) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn strtod( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> f64; +} +extern "C" { + pub fn strtof( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> f32; +} +extern "C" { + pub fn strtof32( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> _Float32; +} +extern "C" { + pub fn strtof64( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> _Float64; +} +extern "C" { + pub fn strtof32x( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> _Float32x; +} +extern "C" { + pub fn strtof64x( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + ) -> _Float64x; +} +extern "C" { + pub fn strtoul( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn strtoq( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn strtouq( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn strtoll( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn strtoull( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn strfromd( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: f64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfromf( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: f32, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfroml( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: f64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfromf32( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: _Float32, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfromf64( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: _Float64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfromf32x( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: _Float32x, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strfromf64x( + __dest: *mut ::std::os::raw::c_char, + __size: usize, + __format: *const ::std::os::raw::c_char, + __f: _Float64x, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn strtol_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __loc: locale_t, + ) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn strtoul_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __loc: locale_t, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn strtoll_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __loc: locale_t, + ) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn strtoull_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __loc: locale_t, + ) -> ::std::os::raw::c_ulonglong; +} +extern "C" { + pub fn strtod_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> f64; +} +extern "C" { + pub fn strtof_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> f32; +} +extern "C" { + pub fn strtold_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> f64; +} +extern "C" { + pub fn strtof32_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> _Float32; +} +extern "C" { + pub fn strtof64_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> _Float64; +} +extern "C" { + pub fn strtof32x_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> _Float32x; +} +extern "C" { + pub fn strtof64x_l( + __nptr: *const ::std::os::raw::c_char, + __endptr: *mut *mut ::std::os::raw::c_char, + __loc: locale_t, + ) -> _Float64x; +} +extern "C" { + pub fn l64a(__n: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn a64l(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn random() -> ::std::os::raw::c_long; +} +extern "C" { + pub fn srandom(__seed: ::std::os::raw::c_uint); +} +extern "C" { + pub fn initstate( + __seed: ::std::os::raw::c_uint, + __statebuf: *mut ::std::os::raw::c_char, + __statelen: usize, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn setstate(__statebuf: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn random_r(__buf: *mut random_data, __result: *mut i32) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn srandom_r( + __seed: ::std::os::raw::c_uint, + __buf: *mut random_data, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn initstate_r( + __seed: ::std::os::raw::c_uint, + __statebuf: *mut ::std::os::raw::c_char, + __statelen: usize, + __buf: *mut random_data, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setstate_r( + __statebuf: *mut ::std::os::raw::c_char, + __buf: *mut random_data, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rand() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn srand(__seed: ::std::os::raw::c_uint); +} +extern "C" { + pub fn rand_r(__seed: *mut ::std::os::raw::c_uint) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn drand48() -> f64; +} +extern "C" { + pub fn erand48(__xsubi: *mut ::std::os::raw::c_ushort) -> f64; +} +extern "C" { + pub fn lrand48() -> ::std::os::raw::c_long; +} +extern "C" { + pub fn nrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn mrand48() -> ::std::os::raw::c_long; +} +extern "C" { + pub fn jrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn srand48(__seedval: ::std::os::raw::c_long); +} +extern "C" { + pub fn seed48(__seed16v: *mut ::std::os::raw::c_ushort) -> *mut ::std::os::raw::c_ushort; +} +extern "C" { + pub fn lcong48(__param: *mut ::std::os::raw::c_ushort); +} +extern "C" { + pub fn drand48_r(__buffer: *mut drand48_data, __result: *mut f64) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn erand48_r( + __xsubi: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + __result: *mut f64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lrand48_r( + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn nrand48_r( + __xsubi: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mrand48_r( + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn jrand48_r( + __xsubi: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + __result: *mut ::std::os::raw::c_long, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn srand48_r( + __seedval: ::std::os::raw::c_long, + __buffer: *mut drand48_data, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn seed48_r( + __seed16v: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lcong48_r( + __param: *mut ::std::os::raw::c_ushort, + __buffer: *mut drand48_data, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn malloc(__size: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn calloc(__nmemb: usize, __size: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn realloc( + __ptr: *mut ::std::os::raw::c_void, + __size: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn reallocarray( + __ptr: *mut ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn free(__ptr: *mut ::std::os::raw::c_void); +} +extern "C" { + pub fn alloca(__size: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn valloc(__size: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn posix_memalign( + __memptr: *mut *mut ::std::os::raw::c_void, + __alignment: usize, + __size: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn aligned_alloc(__alignment: usize, __size: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn abort(); +} +extern "C" { + pub fn atexit(__func: ::core::option::Option) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn at_quick_exit( + __func: ::core::option::Option, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn on_exit( + __func: ::core::option::Option< + unsafe extern "C" fn( + __status: ::std::os::raw::c_int, + __arg: *mut ::std::os::raw::c_void, + ), + >, + __arg: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn exit(__status: ::std::os::raw::c_int); +} +extern "C" { + pub fn quick_exit(__status: ::std::os::raw::c_int); +} +extern "C" { + pub fn _Exit(__status: ::std::os::raw::c_int); +} +extern "C" { + pub fn getenv(__name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn secure_getenv(__name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn putenv(__string: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setenv( + __name: *const ::std::os::raw::c_char, + __value: *const ::std::os::raw::c_char, + __replace: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn unsetenv(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clearenv() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mktemp(__template: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn mkstemp(__template: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkstemp64(__template: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkstemps( + __template: *mut ::std::os::raw::c_char, + __suffixlen: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkstemps64( + __template: *mut ::std::os::raw::c_char, + __suffixlen: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkdtemp(__template: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn mkostemp( + __template: *mut ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkostemp64( + __template: *mut ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkostemps( + __template: *mut ::std::os::raw::c_char, + __suffixlen: ::std::os::raw::c_int, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkostemps64( + __template: *mut ::std::os::raw::c_char, + __suffixlen: ::std::os::raw::c_int, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn system(__command: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn canonicalize_file_name( + __name: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn realpath( + __name: *const ::std::os::raw::c_char, + __resolved: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn bsearch( + __key: *const ::std::os::raw::c_void, + __base: *const ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + __compar: __compar_fn_t, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn qsort_r( + __base: *mut ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + __compar: __compar_d_fn_t, + __arg: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + pub fn abs(__x: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn labs(__x: ::std::os::raw::c_long) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn llabs(__x: ::std::os::raw::c_longlong) -> ::std::os::raw::c_longlong; +} +extern "C" { + pub fn div(__numer: ::std::os::raw::c_int, __denom: ::std::os::raw::c_int) -> div_t; +} +extern "C" { + pub fn ldiv(__numer: ::std::os::raw::c_long, __denom: ::std::os::raw::c_long) -> ldiv_t; +} +extern "C" { + pub fn lldiv( + __numer: ::std::os::raw::c_longlong, + __denom: ::std::os::raw::c_longlong, + ) -> lldiv_t; +} +extern "C" { + pub fn ecvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn fcvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn gcvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn qecvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn qfcvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn qgcvt( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ecvt_r( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fcvt_r( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn qecvt_r( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn qfcvt_r( + __value: f64, + __ndigit: ::std::os::raw::c_int, + __decpt: *mut ::std::os::raw::c_int, + __sign: *mut ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __len: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mbtowc( + __pwc: *mut wchar_t, + __s: *const ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn wctomb(__s: *mut ::std::os::raw::c_char, __wchar: wchar_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mbstowcs(__pwcs: *mut wchar_t, __s: *const ::std::os::raw::c_char, __n: usize) -> usize; +} +extern "C" { + pub fn wcstombs(__s: *mut ::std::os::raw::c_char, __pwcs: *const wchar_t, __n: usize) -> usize; +} +extern "C" { + pub fn rpmatch(__response: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getsubopt( + __optionp: *mut *mut ::std::os::raw::c_char, + __tokens: *const *mut ::std::os::raw::c_char, + __valuep: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn posix_openpt(__oflag: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn grantpt(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn unlockpt(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ptsname(__fd: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ptsname_r( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __buflen: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getpt() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getloadavg(__loadavg: *mut f64, __nelem: ::std::os::raw::c_int) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn xmalloc(arg1: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn xrealloc(arg1: *mut ::std::os::raw::c_void, arg2: usize) -> *mut ::std::os::raw::c_void; +} +extern "C" { + pub fn xfree(arg1: *mut ::std::os::raw::c_void); +} +extern "C" { + pub fn posix_initialize(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn num_posix_options() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn get_posix_options(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn set_posix_options(arg1: *const ::std::os::raw::c_char); +} +extern "C" { + pub fn save_posix_options(); +} +extern "C" { + pub fn string_to_rlimtype(arg1: *mut ::std::os::raw::c_char) -> rlim_t; +} +extern "C" { + pub fn print_rlimtype(arg1: rlim_t, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn all_digits(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn legal_identifier(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn importable_function_name( + arg1: *const ::std::os::raw::c_char, + arg2: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn exportable_function_name(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn check_identifier( + arg1: *mut WordDesc, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn check_selfref( + arg1: *const ::std::os::raw::c_char, + arg2: *mut ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn legal_alias_name( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn line_isblank(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn assignment( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sh_setclexec(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sh_validfd(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fd_ispipe(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn check_dev_tty(); +} +extern "C" { + pub fn move_to_high_fd( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn check_binary_file( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sh_openpipe(arg1: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sh_closepipe(arg1: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn file_exists(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn file_iswdir(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn path_dot_or_dotdot(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn absolute_pathname(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn absolute_program(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn base_pathname(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn full_pathname(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn polite_directory_format( + arg1: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn trim_pathname( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn printable_filename( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn extract_colon_unit( + arg1: *mut ::std::os::raw::c_char, + arg2: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tilde_initialize(); +} +extern "C" { + pub fn bash_tilde_find_word( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn bash_tilde_expand( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn get_group_list(arg1: *mut ::std::os::raw::c_int) -> *mut *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn get_group_array(arg1: *mut ::std::os::raw::c_int) -> *mut ::std::os::raw::c_int; +} +extern "C" { + pub fn conf_standard_path() -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn default_columns() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn array_create() -> *mut ARRAY; +} +extern "C" { + pub fn array_flush(arg1: *mut ARRAY); +} +extern "C" { + pub fn array_dispose(arg1: *mut ARRAY); +} +extern "C" { + pub fn array_copy(arg1: *mut ARRAY) -> *mut ARRAY; +} +extern "C" { + pub fn array_slice( + arg1: *mut ARRAY, + arg2: *mut ARRAY_ELEMENT, + arg3: *mut ARRAY_ELEMENT, + ) -> *mut ARRAY; +} +extern "C" { + pub fn array_walk(arg1: *mut ARRAY, arg2: sh_ae_map_func_t, arg3: *mut ::std::os::raw::c_void); +} +extern "C" { + pub fn array_shift( + arg1: *mut ARRAY, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> *mut ARRAY_ELEMENT; +} +extern "C" { + pub fn array_rshift( + arg1: *mut ARRAY, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn array_unshift_element(arg1: *mut ARRAY) -> *mut ARRAY_ELEMENT; +} +extern "C" { + pub fn array_shift_element( + arg1: *mut ARRAY, + arg2: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn array_quote(arg1: *mut ARRAY) -> *mut ARRAY; +} +extern "C" { + pub fn array_quote_escapes(arg1: *mut ARRAY) -> *mut ARRAY; +} +extern "C" { + pub fn array_dequote(arg1: *mut ARRAY) -> *mut ARRAY; +} +extern "C" { + pub fn array_dequote_escapes(arg1: *mut ARRAY) -> *mut ARRAY; +} +extern "C" { + pub fn array_remove_quoted_nulls(arg1: *mut ARRAY) -> *mut ARRAY; +} +extern "C" { + pub fn array_subrange( + arg1: *mut ARRAY, + arg2: arrayind_t, + arg3: arrayind_t, + arg4: ::std::os::raw::c_int, + arg5: ::std::os::raw::c_int, + arg6: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_patsub( + arg1: *mut ARRAY, + arg2: *mut ::std::os::raw::c_char, + arg3: *mut ::std::os::raw::c_char, + arg4: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_modcase( + arg1: *mut ARRAY, + arg2: *mut ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + arg4: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_create_element( + arg1: arrayind_t, + arg2: *mut ::std::os::raw::c_char, + ) -> *mut ARRAY_ELEMENT; +} +extern "C" { + pub fn array_copy_element(arg1: *mut ARRAY_ELEMENT) -> *mut ARRAY_ELEMENT; +} +extern "C" { + pub fn array_dispose_element(arg1: *mut ARRAY_ELEMENT); +} +extern "C" { + pub fn array_insert( + arg1: *mut ARRAY, + arg2: arrayind_t, + arg3: *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn array_remove(arg1: *mut ARRAY, arg2: arrayind_t) -> *mut ARRAY_ELEMENT; +} +extern "C" { + pub fn array_reference(arg1: *mut ARRAY, arg2: arrayind_t) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_to_word_list(arg1: *mut ARRAY) -> *mut WordList; +} +extern "C" { + pub fn array_from_word_list(arg1: *mut WordList) -> *mut ARRAY; +} +extern "C" { + pub fn array_keys_to_word_list(arg1: *mut ARRAY) -> *mut WordList; +} +extern "C" { + pub fn array_assign_list(arg1: *mut ARRAY, arg2: *mut WordList) -> *mut ARRAY; +} +extern "C" { + pub fn array_to_argv( + arg1: *mut ARRAY, + arg2: *mut ::std::os::raw::c_int, + ) -> *mut *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_to_kvpair( + arg1: *mut ARRAY, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_to_assign( + arg1: *mut ARRAY, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_to_string( + arg1: *mut ARRAY, + arg2: *mut ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn array_from_string( + arg1: *mut ::std::os::raw::c_char, + arg2: *mut ::std::os::raw::c_char, + ) -> *mut ARRAY; +} +extern "C" { + pub fn execute_array_command( + arg1: *mut ARRAY, + arg2: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn initialize_traps(); +} +extern "C" { + pub fn run_pending_traps(); +} +extern "C" { + pub fn queue_sigchld_trap(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn maybe_set_sigchld_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn set_impossible_sigchld_trap(); +} +extern "C" { + pub fn set_sigchld_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn set_debug_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn set_error_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn set_return_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn maybe_set_debug_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn maybe_set_error_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn maybe_set_return_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn set_sigint_trap(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn set_signal(arg1: ::std::os::raw::c_int, arg2: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn restore_default_signal(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn ignore_signal(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn run_exit_trap() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn run_trap_cleanup(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn run_debug_trap() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn run_error_trap(); +} +extern "C" { + pub fn run_return_trap(); +} +extern "C" { + pub fn free_trap_strings(); +} +extern "C" { + pub fn reset_signal_handlers(); +} +extern "C" { + pub fn restore_original_signals(); +} +extern "C" { + pub fn get_original_signal(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn get_all_original_signals(); +} +extern "C" { + pub fn signal_name(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn decode_signal( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn run_interrupt_trap(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn maybe_call_trap_handler(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn signal_is_special(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn signal_is_trapped(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn signal_is_pending(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn signal_is_ignored(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn signal_is_hard_ignored(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn set_signal_hard_ignored(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn set_signal_ignored(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn signal_in_progress(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn set_trap_state(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn next_pending_trap(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn first_pending_trap() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clear_pending_traps(); +} +extern "C" { + pub fn any_signals_trapped() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn check_signals(); +} +extern "C" { + pub fn check_signals_and_traps(); +} +pub type rl_dequote_func_t = ::core::option::Option< + fn( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char, +>; +pub type rl_compdisp_func_t = ::core::option::Option< + unsafe extern "C" fn( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ), +>; +pub type rl_intfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type rl_icpfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type rl_icppfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type rl_getc_func_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type rl_vintfunc_t = ::core::option::Option; +pub type rl_vcpfunc_t = + ::core::option::Option; +pub type rl_vcppfunc_t = + ::core::option::Option; +pub type rl_cpvfunc_t = + ::core::option::Option *mut ::std::os::raw::c_char>; +pub type rl_cpifunc_t = ::core::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char, +>; +pub type rl_cpcpfunc_t = ::core::option::Option< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char, +>; +pub type rl_cpcppfunc_t = ::core::option::Option< + unsafe extern "C" fn(arg1: *mut *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char, +>; +pub type KEYMAP_ENTRY_ARRAY = [KEYMAP_ENTRY; 257usize]; +extern "C" { + #[link_name = "\u{1}emacs_standard_keymap"] + pub static mut emacs_standard_keymap: KEYMAP_ENTRY_ARRAY; +} +extern "C" { + #[link_name = "\u{1}emacs_meta_keymap"] + pub static mut emacs_meta_keymap: KEYMAP_ENTRY_ARRAY; +} +extern "C" { + #[link_name = "\u{1}emacs_ctlx_keymap"] + pub static mut emacs_ctlx_keymap: KEYMAP_ENTRY_ARRAY; +} +extern "C" { + #[link_name = "\u{1}vi_insertion_keymap"] + pub static mut vi_insertion_keymap: KEYMAP_ENTRY_ARRAY; +} +extern "C" { + #[link_name = "\u{1}vi_movement_keymap"] + pub static mut vi_movement_keymap: KEYMAP_ENTRY_ARRAY; +} +extern "C" { + pub fn rl_make_bare_keymap() -> Keymap; +} +extern "C" { + pub fn rl_copy_keymap(arg1: Keymap) -> Keymap; +} +extern "C" { + pub fn rl_make_keymap() -> Keymap; +} +extern "C" { + pub fn rl_discard_keymap(arg1: Keymap); +} +extern "C" { + pub fn rl_set_keymap_name( + arg1: *const ::std::os::raw::c_char, + arg2: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}tilde_expansion_failure_hook"] + pub static mut tilde_expansion_failure_hook: tilde_hook_func_t; +} +extern "C" { + #[link_name = "\u{1}tilde_additional_prefixes"] + pub static mut tilde_additional_prefixes: *mut *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}tilde_additional_suffixes"] + pub static mut tilde_additional_suffixes: *mut *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tilde_expand(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tilde_expand_word(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tilde_find_word( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +pub const undo_code_UNDO_DELETE: undo_code = 0; +pub const undo_code_UNDO_INSERT: undo_code = 1; +pub const undo_code_UNDO_BEGIN: undo_code = 2; +pub const undo_code_UNDO_END: undo_code = 3; +pub type undo_code = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct undo_list { + pub next: *mut undo_list, + pub start: ::std::os::raw::c_int, + pub end: ::std::os::raw::c_int, + pub text: *mut ::std::os::raw::c_char, + pub what: undo_code, +} +pub type UNDO_LIST = undo_list; +extern "C" { + #[link_name = "\u{1}rl_undo_list"] + pub static mut rl_undo_list: *mut UNDO_LIST; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _funmap { + pub name: *const ::std::os::raw::c_char, + pub function: rl_command_func_t, +} +pub type FUNMAP = _funmap; +extern "C" { + #[link_name = "\u{1}funmap"] + pub static mut funmap: *mut *mut FUNMAP; +} +extern "C" { + pub fn rl_digit_argument( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_universal_argument( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_forward_byte( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_forward_char( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_forward( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_byte( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_char( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_beg_of_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_end_of_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_forward_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_refresh_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_screen( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_display( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_skip_csi_sequence( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_arrow_keys( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_previous_screen_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_next_screen_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_insert( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_quoted_insert( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_tab_insert( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_newline( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_do_lowercase_version( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_rubout( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_delete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_rubout_or_delete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_delete_horizontal_space( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_delete_or_show_completions( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_insert_comment( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_upcase_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_downcase_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_capitalize_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_transpose_words( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_transpose_chars( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_char_search( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_char_search( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_beginning_of_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_end_of_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_get_next_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_get_previous_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_operate_and_get_next( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_set_mark( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_exchange_point_and_mark( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_editing_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_emacs_editing_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_overwrite_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_re_read_init_file( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_dump_functions( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_dump_macros( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_dump_variables( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_possible_completions( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_insert_completions( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_old_menu_complete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_menu_complete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_menu_complete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_kill_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_kill_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_kill_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_backward_kill_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_kill_full_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_unix_word_rubout( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_unix_filename_rubout( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_unix_line_discard( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_copy_region_to_kill( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_kill_region( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_copy_forward_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_copy_backward_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_yank( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_yank_pop( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_yank_nth_arg( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_yank_last_arg( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bracketed_paste_begin( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_reverse_search_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_forward_search_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_start_kbd_macro( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_end_kbd_macro( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_call_last_kbd_macro( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_print_last_kbd_macro( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_revert_line( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_undo_command( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_tilde_expand( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_restart_output( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_stop_output( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_abort( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_tty_status( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_history_search_forward( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_history_search_backward( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_history_substr_search_forward( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_history_substr_search_backward( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_noninc_forward_search( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_noninc_reverse_search( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_noninc_forward_search_again( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_noninc_reverse_search_again( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_insert_close( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_callback_handler_install(arg1: *const ::std::os::raw::c_char, arg2: rl_vcpfunc_t); +} +extern "C" { + pub fn rl_callback_read_char(); +} +extern "C" { + pub fn rl_callback_handler_remove(); +} +extern "C" { + pub fn rl_callback_sigcleanup(); +} +extern "C" { + pub fn rl_vi_redo( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_undo( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_yank_arg( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_fetch_history( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_search_again( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_search( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_complete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_tilde_expand( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_prev_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_next_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_end_word( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_insert_beg( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_append_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_append_eol( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_eof_maybe( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_insertion_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_insert_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_movement_mode( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_arg_digit( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_change_case( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_put( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_column( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_delete_to( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_change_to( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_yank_to( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_yank_pop( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_rubout( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_delete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_back_to_indent( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_unix_word_rubout( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_first_print( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_char_search( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_match( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_change_char( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_subst( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_overstrike( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_overstrike_delete( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_replace( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_set_mark( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_goto_mark( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_check() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_domove( + arg1: ::std::os::raw::c_int, + arg2: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_bracktype(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_start_inserting( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn rl_vi_fWord( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_bWord( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_eWord( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_fword( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_bword( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_vi_eword( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn readline(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_set_prompt(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_expand_prompt(arg1: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_initialize() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_discard_argument() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_add_defun( + arg1: *const ::std::os::raw::c_char, + arg2: Option, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_key( + arg1: ::std::os::raw::c_int, + arg2: rl_command_func_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_key_in_map( + arg1: ::std::os::raw::c_int, + arg2: Option, + arg3: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_unbind_key(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_unbind_key_in_map(arg1: ::std::os::raw::c_int, arg2: Keymap) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_key_if_unbound( + arg1: ::std::os::raw::c_int, + arg2: rl_command_func_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_key_if_unbound_in_map( + arg1: ::std::os::raw::c_int, + arg2: Option, + arg3: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_unbind_command_in_map( + arg1: *const ::std::os::raw::c_char, + arg2: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_keyseq_in_map( + arg1: *const ::std::os::raw::c_char, + arg2: Option, + arg3: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_keyseq_if_unbound( + arg1: *const ::std::os::raw::c_char, + arg2: rl_command_func_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_bind_keyseq_if_unbound_in_map( + arg1: *const ::std::os::raw::c_char, + arg2: rl_command_func_t, + arg3: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_generic_bind( + arg1: ::std::os::raw::c_int, + arg2: *const ::std::os::raw::c_char, + arg3: *mut ::std::os::raw::c_char, + arg4: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_variable_value(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_variable_bind( + arg1: *const ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_set_key( + arg1: *const ::std::os::raw::c_char, + arg2: rl_command_func_t, + arg3: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_macro_bind( + arg1: *const ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: Keymap, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_untranslate_keyseq(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_function_of_keyseq( + arg1: *const ::std::os::raw::c_char, + arg2: Keymap, + arg3: *mut ::std::os::raw::c_int, + ) -> Option; +} +extern "C" { + pub fn rl_invoking_keyseqs_in_map( + arg1: rl_command_func_t, + arg2: Keymap, + ) -> *mut *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_empty_keymap(arg1: Keymap) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_free_keymap(arg1: Keymap); +} +extern "C" { + pub fn rl_get_keymap_name(arg1: Keymap) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_set_keymap_from_edit_mode(); +} +extern "C" { + pub fn rl_get_keymap_name_from_edit_mode() -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_add_funmap_entry( + arg1: *const ::std::os::raw::c_char, + arg2: rl_command_func_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_funmap_names() -> *mut *const ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_initialize_funmap(); +} +extern "C" { + pub fn rl_push_macro_input(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn rl_add_undo( + arg1: undo_code, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: *mut ::std::os::raw::c_char, + ); +} +extern "C" { + pub fn rl_free_undo_list(); +} +extern "C" { + pub fn rl_do_undo() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_begin_undo_group() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_end_undo_group() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_modifying( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_redisplay(); +} +extern "C" { + pub fn rl_on_new_line() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_on_new_line_with_prompt() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_forced_update_display() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_visible_line() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_message() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_reset_line_state() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_crlf() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_keep_mark_active(); +} +extern "C" { + pub fn rl_activate_mark(); +} +extern "C" { + pub fn rl_deactivate_mark(); +} +extern "C" { + pub fn rl_mark_active_p() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_message(arg1: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_show_char(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_character_len( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_redraw_prompt_last_line(); +} +extern "C" { + pub fn rl_save_prompt(); +} +extern "C" { + pub fn rl_restore_prompt(); +} +extern "C" { + pub fn rl_replace_line(arg1: *const ::std::os::raw::c_char, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn rl_delete_text( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_kill_text( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_copy_text( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_prep_terminal(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn rl_deprep_terminal(); +} +extern "C" { + pub fn rl_tty_set_default_bindings(arg1: Keymap); +} +extern "C" { + pub fn rl_tty_unset_default_bindings(arg1: Keymap); +} +extern "C" { + pub fn rl_tty_set_echoing(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_reset_terminal(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_resize_terminal(); +} +extern "C" { + pub fn rl_set_screen_size(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn rl_get_screen_size(arg1: *mut ::std::os::raw::c_int, arg2: *mut ::std::os::raw::c_int); +} +extern "C" { + pub fn rl_reset_screen_size(); +} +extern "C" { + pub fn rl_get_termcap(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_stuff_char(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_execute_next(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_pending_input() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_read_key() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_getc(arg1: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_set_keyboard_input_timeout(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_extend_line_buffer(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn rl_ding() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_alphabetic(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_free(arg1: *mut ::std::os::raw::c_void); +} +extern "C" { + pub fn rl_set_signals() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_signals() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_cleanup_after_signal(); +} +extern "C" { + pub fn rl_reset_after_signal(); +} +extern "C" { + pub fn rl_free_line_state(); +} +extern "C" { + pub fn rl_pending_signal() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_check_signals(); +} +extern "C" { + pub fn rl_echo_signal_char(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn rl_set_paren_blink_timeout(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_clear_history(); +} +extern "C" { + pub fn rl_maybe_save_line() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_maybe_unsave_line() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_maybe_replace_line() -> ::std::os::raw::c_int; +} +// extern "C" { +// pub fn rl_complete_internal(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +// } +extern "C" { + pub fn rl_display_match_list( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn rl_completion_matches( + arg1: *const ::std::os::raw::c_char, + arg2: Option, + ) -> *mut *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn rl_username_completion_function( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +// extern "C" { +// pub fn rl_filename_completion_function( +// arg1: *const ::std::os::raw::c_char, +// arg2: ::std::os::raw::c_int, +// ) -> *mut ::std::os::raw::c_char; +// } +extern "C" { + pub fn rl_completion_mode(_: Option) -> libc::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_library_version"] + pub static mut rl_library_version: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_readline_version"] + pub static mut rl_readline_version: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_gnu_readline_p"] + pub static mut rl_gnu_readline_p: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_readline_state"] + pub static mut rl_readline_state: ::std::os::raw::c_ulong; +} +extern "C" { + #[link_name = "\u{1}rl_editing_mode"] + pub static mut rl_editing_mode: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_insert_mode"] + pub static mut rl_insert_mode: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_readline_name"] + pub static mut rl_readline_name: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_prompt"] + pub static mut rl_prompt: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_display_prompt"] + pub static mut rl_display_prompt: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_line_buffer"] + pub static mut rl_line_buffer: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_point"] + pub static mut rl_point: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_end"] + pub static mut rl_end: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_mark"] + pub static mut rl_mark: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_pending_input"] + pub static mut rl_pending_input: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_explicit_arg"] + pub static mut rl_explicit_arg: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_numeric_arg"] + pub static mut rl_numeric_arg: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_last_func"] + pub static mut rl_last_func: Option; +} +extern "C" { + #[link_name = "\u{1}rl_terminal_name"] + pub static mut rl_terminal_name: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_prefer_env_winsize"] + pub static mut rl_prefer_env_winsize: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_pre_input_hook"] + pub static mut rl_pre_input_hook: rl_hook_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_event_hook"] + pub static mut rl_event_hook: rl_hook_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_signal_event_hook"] + pub static mut rl_signal_event_hook: Option; +} +extern "C" { + #[link_name = "\u{1}rl_input_available_hook"] + pub static mut rl_input_available_hook: rl_hook_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_getc_function"] + pub static mut rl_getc_function: rl_getc_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_redisplay_function"] + pub static mut rl_redisplay_function: rl_voidfunc_t; +} +extern "C" { + #[link_name = "\u{1}rl_prep_term_function"] + pub static mut rl_prep_term_function: rl_vintfunc_t; +} +extern "C" { + #[link_name = "\u{1}rl_deprep_term_function"] + pub static mut rl_deprep_term_function: Option; +} +extern "C" { + #[link_name = "\u{1}rl_executing_keymap"] + pub static mut rl_executing_keymap: Keymap; +} +extern "C" { + #[link_name = "\u{1}rl_binding_keymap"] + pub static mut rl_binding_keymap: Keymap; +} +extern "C" { + #[link_name = "\u{1}rl_executing_key"] + pub static mut rl_executing_key: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_executing_keyseq"] + pub static mut rl_executing_keyseq: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_key_sequence_length"] + pub static mut rl_key_sequence_length: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_erase_empty_line"] + pub static mut rl_erase_empty_line: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_already_prompted"] + pub static mut rl_already_prompted: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_num_chars_to_read"] + pub static mut rl_num_chars_to_read: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_executing_macro"] + pub static mut rl_executing_macro: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_catch_signals"] + pub static mut rl_catch_signals: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_catch_sigwinch"] + pub static mut rl_catch_sigwinch: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_change_environment"] + pub static mut rl_change_environment: ::std::os::raw::c_int; +} +// extern "C" { +// #[link_name = "\u{1}rl_completion_entry_function"] +// pub static mut rl_completion_entry_function: rl_compentry_func_t; +// } +extern "C" { + #[link_name = "\u{1}rl_menu_completion_entry_function"] + pub static mut rl_menu_completion_entry_function: Option; +} +// extern "C" { +// #[link_name = "\u{1}rl_ignore_some_completions_function"] +// pub static mut rl_ignore_some_completions_function: rl_compignore_func_t; +// } +extern "C" { + #[link_name = "\u{1}rl_basic_word_break_characters"] + pub static mut rl_basic_word_break_characters: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_completer_word_break_characters"] + pub static mut rl_completer_word_break_characters: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_completion_word_break_hook"] + pub static mut rl_completion_word_break_hook: rl_cpvfunc_t; +} +extern "C" { + #[link_name = "\u{1}rl_completer_quote_characters"] + pub static mut rl_completer_quote_characters: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_basic_quote_characters"] + pub static mut rl_basic_quote_characters: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_filename_quote_characters"] + pub static mut rl_filename_quote_characters: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_special_prefixes"] + pub static mut rl_special_prefixes: *const ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}rl_directory_completion_hook"] + pub static mut rl_directory_completion_hook: rl_icppfunc_t; +} +extern "C" { + #[link_name = "\u{1}rl_directory_rewrite_hook"] + pub static mut rl_directory_rewrite_hook: rl_icppfunc_t; +} +extern "C" { + #[link_name = "\u{1}rl_filename_stat_hook"] + pub static mut rl_filename_stat_hook: rl_icppfunc_t; +} +extern "C" { + #[link_name = "\u{1}rl_filename_rewrite_hook"] + pub static mut rl_filename_rewrite_hook: rl_dequote_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_completion_display_matches_hook"] + pub static mut rl_completion_display_matches_hook: rl_compdisp_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_filename_completion_desired"] + pub static mut rl_filename_completion_desired: ::std::os::raw::c_int; +} +// extern "C" { +// #[link_name = "\u{1}rl_filename_quoting_desired"] +// pub static mut rl_filename_quoting_desired: ::std::os::raw::c_int; +// } +// extern "C" { +// #[link_name = "\u{1}rl_filename_quoting_function"] +// pub static mut rl_filename_quoting_function: rl_quote_func_t; +// } +extern "C" { + #[link_name = "\u{1}rl_filename_dequoting_function"] + pub static mut rl_filename_dequoting_function: rl_dequote_func_t; +} +extern "C" { + #[link_name = "\u{1}rl_char_is_quoted_p"] + pub static mut rl_char_is_quoted_p: Option; +} +extern "C" { + #[link_name = "\u{1}rl_attempted_completion_over"] + pub static mut rl_attempted_completion_over: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_type"] + pub static mut rl_completion_type: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_invoking_key"] + pub static mut rl_completion_invoking_key: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_query_items"] + pub static mut rl_completion_query_items: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_append_character"] + pub static mut rl_completion_append_character: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_suppress_append"] + pub static mut rl_completion_suppress_append: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_quote_character"] + pub static mut rl_completion_quote_character: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_found_quote"] + pub static mut rl_completion_found_quote: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_suppress_quote"] + pub static mut rl_completion_suppress_quote: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_sort_completion_matches"] + pub static mut rl_sort_completion_matches: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_completion_mark_symlink_dirs"] + pub static mut rl_completion_mark_symlink_dirs: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_ignore_completion_duplicates"] + pub static mut rl_ignore_completion_duplicates: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_inhibit_completion"] + pub static mut rl_inhibit_completion: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_persistent_signal_handlers"] + pub static mut rl_persistent_signal_handlers: ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct readline_state { + pub point: ::std::os::raw::c_int, + pub end: ::std::os::raw::c_int, + pub mark: ::std::os::raw::c_int, + pub buflen: ::std::os::raw::c_int, + pub buffer: *mut ::std::os::raw::c_char, + pub ul: *mut UNDO_LIST, + pub prompt: *mut ::std::os::raw::c_char, + pub rlstate: ::std::os::raw::c_int, + pub done: ::std::os::raw::c_int, + pub kmap: Keymap, + pub lastfunc: rl_command_func_t, + pub insmode: ::std::os::raw::c_int, + pub edmode: ::std::os::raw::c_int, + pub kseq: *mut ::std::os::raw::c_char, + pub kseqlen: ::std::os::raw::c_int, + pub pendingin: ::std::os::raw::c_int, + pub inf: *mut FILE, + pub outf: *mut FILE, + pub macro_: *mut ::std::os::raw::c_char, + pub catchsigs: ::std::os::raw::c_int, + pub catchsigwinch: ::std::os::raw::c_int, + pub entryfunc: rl_compentry_func_t, + pub menuentryfunc: rl_compentry_func_t, + pub ignorefunc: rl_compignore_func_t, + pub attemptfunc: rl_completion_func_t, + pub wordbreakchars: *mut ::std::os::raw::c_char, + pub reserved: [::std::os::raw::c_char; 64usize], +} +extern "C" { + pub fn rl_save_state(arg1: *mut readline_state) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rl_restore_state(arg1: *mut readline_state) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_find_prev_mbchar( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_find_next_mbchar( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_compare_chars( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: *mut mbstate_t, + arg4: *mut ::std::os::raw::c_char, + arg5: ::std::os::raw::c_int, + arg6: *mut mbstate_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_get_char_len( + arg1: *mut ::std::os::raw::c_char, + arg2: *mut mbstate_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_adjust_point( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: *mut mbstate_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_read_mbchar( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_read_mbstring( + arg1: ::std::os::raw::c_int, + arg2: *mut ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_is_mbchar_matched( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + arg4: *mut ::std::os::raw::c_char, + arg5: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_char_value( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> wchar_t; +} +extern "C" { + pub fn _rl_walphabetic(arg1: wchar_t) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_byte_oriented"] + pub static mut rl_byte_oriented: ::std::os::raw::c_int; +} +extern "C" { + pub fn _setjmp(__env: *mut __jmp_buf_tag) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn longjmp(__env: *mut __jmp_buf_tag, __val: ::std::os::raw::c_int); +} +extern "C" { + pub fn _longjmp(__env: *mut __jmp_buf_tag, __val: ::std::os::raw::c_int); +} +extern "C" { + pub fn siglongjmp(__env: *mut __jmp_buf_tag, __val: ::std::os::raw::c_int); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __rl_search_context { + pub type_: ::std::os::raw::c_int, + pub sflags: ::std::os::raw::c_int, + pub search_string: *mut ::std::os::raw::c_char, + pub search_string_index: ::std::os::raw::c_int, + pub search_string_size: ::std::os::raw::c_int, + pub lines: *mut *mut ::std::os::raw::c_char, + pub allocated_line: *mut ::std::os::raw::c_char, + pub hlen: ::std::os::raw::c_int, + pub hindex: ::std::os::raw::c_int, + pub save_point: ::std::os::raw::c_int, + pub save_mark: ::std::os::raw::c_int, + pub save_line: ::std::os::raw::c_int, + pub last_found_line: ::std::os::raw::c_int, + pub prev_line_found: *mut ::std::os::raw::c_char, + pub save_undo_list: *mut UNDO_LIST, + pub keymap: Keymap, + pub okeymap: Keymap, + pub history_pos: ::std::os::raw::c_int, + pub direction: ::std::os::raw::c_int, + pub prevc: ::std::os::raw::c_int, + pub lastc: ::std::os::raw::c_int, + pub mb: [::std::os::raw::c_char; 16usize], + pub pmb: [::std::os::raw::c_char; 16usize], + pub sline: *mut ::std::os::raw::c_char, + pub sline_len: ::std::os::raw::c_int, + pub sline_index: ::std::os::raw::c_int, + pub search_terminators: *mut ::std::os::raw::c_char, +} +pub type _rl_search_cxt = __rl_search_context; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _rl_cmd { + pub map: Keymap, + pub count: ::std::os::raw::c_int, + pub key: ::std::os::raw::c_int, + pub func: rl_command_func_t, +} +extern "C" { + #[link_name = "\u{1}_rl_pending_command"] + pub static mut _rl_pending_command: _rl_cmd; +} +extern "C" { + #[link_name = "\u{1}_rl_command_to_execute"] + pub static mut _rl_command_to_execute: *mut _rl_cmd; +} +pub type _rl_arg_cxt = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __rl_keyseq_context { + pub flags: ::std::os::raw::c_int, + pub subseq_arg: ::std::os::raw::c_int, + pub subseq_retval: ::std::os::raw::c_int, + pub okey: ::std::os::raw::c_int, + pub dmap: Keymap, + pub oldmap: Keymap, + pub ocxt: *mut __rl_keyseq_context, + pub childval: ::std::os::raw::c_int, +} +pub type _rl_keyseq_cxt = __rl_keyseq_context; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __rl_vimotion_context { + pub op: ::std::os::raw::c_int, + pub state: ::std::os::raw::c_int, + pub flags: ::std::os::raw::c_int, + pub ncxt: _rl_arg_cxt, + pub numeric_arg: ::std::os::raw::c_int, + pub start: ::std::os::raw::c_int, + pub end: ::std::os::raw::c_int, + pub key: ::std::os::raw::c_int, + pub motion: ::std::os::raw::c_int, +} +pub type _rl_vimotion_cxt = __rl_vimotion_context; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __rl_callback_generic_arg { + pub count: ::std::os::raw::c_int, + pub i1: ::std::os::raw::c_int, + pub i2: ::std::os::raw::c_int, +} +pub type _rl_callback_generic_arg = __rl_callback_generic_arg; +pub type _rl_callback_func_t = ::core::option::Option< + unsafe extern "C" fn(arg1: *mut _rl_callback_generic_arg) -> ::std::os::raw::c_int, +>; +pub type _rl_sigcleanup_func_t = ::core::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int, arg2: *mut ::std::os::raw::c_void), +>; +extern "C" { + #[link_name = "\u{1}rl_complete_with_tilde_expansion"] + pub static mut rl_complete_with_tilde_expansion: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_visible_stats"] + pub static mut rl_visible_stats: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_colored_stats"] + pub static mut _rl_colored_stats: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_colored_completion_prefix"] + pub static mut _rl_colored_completion_prefix: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_line_buffer_len"] + pub static mut rl_line_buffer_len: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_arg_sign"] + pub static mut rl_arg_sign: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_visible_prompt_length"] + pub static mut rl_visible_prompt_length: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_display_fixed"] + pub static mut rl_display_fixed: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}rl_blink_matching_paren"] + pub static mut rl_blink_matching_paren: ::std::os::raw::c_int; +} +extern "C" { + #[doc = "\t\t\t\t\t\t\t\t\t *"] + #[doc = " Global functions and variables unused and undocumented\t\t *"] + #[doc = "\t\t\t\t\t\t\t\t\t *"] + pub fn rl_set_retained_kills(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_set_screen_size(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_fix_last_undo_of_type( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_savestring(arg1: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn readline_internal_setup(); +} +extern "C" { + pub fn readline_internal_teardown(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn readline_internal_char() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_keyseq_cxt_alloc() -> *mut _rl_keyseq_cxt; +} +extern "C" { + pub fn _rl_keyseq_cxt_dispose(arg1: *mut _rl_keyseq_cxt); +} +extern "C" { + pub fn _rl_keyseq_chain_dispose(); +} +extern "C" { + pub fn _rl_dispatch_callback(arg1: *mut _rl_keyseq_cxt) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_callback_data_alloc(arg1: ::std::os::raw::c_int) -> *mut _rl_callback_generic_arg; +} +extern "C" { + pub fn _rl_callback_data_dispose(arg1: *mut _rl_callback_generic_arg); +} +extern "C" { + pub fn _rl_untranslate_macro_value( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_reset_completion_state(); +} +extern "C" { + pub fn _rl_find_completion_word( + arg1: *mut ::std::os::raw::c_int, + arg2: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_free_match_list(arg1: *mut *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn _rl_strip_prompt(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_reset_prompt(); +} +extern "C" { + pub fn _rl_move_vert(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_save_prompt(); +} +extern "C" { + pub fn _rl_restore_prompt(); +} +extern "C" { + pub fn _rl_make_prompt_for_search(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_erase_at_end_of_line(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_clear_to_eol(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_clear_screen(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_update_final(); +} +extern "C" { + pub fn _rl_optimize_redisplay(); +} +extern "C" { + pub fn _rl_redisplay_after_sigwinch(); +} +extern "C" { + pub fn _rl_clean_up_for_exit(); +} +extern "C" { + pub fn _rl_erase_entire_line(); +} +extern "C" { + pub fn _rl_current_display_line() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_refresh_line(); +} +extern "C" { + pub fn _rl_any_typein() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_input_available() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_nchars_available() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_input_queued(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_insert_typein(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_unget_char(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_pushed_input_available() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_scxt_alloc( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> *mut _rl_search_cxt; +} +extern "C" { + pub fn _rl_scxt_dispose(arg1: *mut _rl_search_cxt, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_isearch_dispatch( + arg1: *mut _rl_search_cxt, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_isearch_callback(arg1: *mut _rl_search_cxt) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_isearch_cleanup( + arg1: *mut _rl_search_cxt, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_search_getchar(arg1: *mut _rl_search_cxt) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_read_bracketed_paste_prefix(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_bracketed_text(arg1: *mut usize) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_bracketed_read_key() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_bracketed_read_mbstring( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_with_macro_input(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn _rl_peek_macro_key() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_next_macro_key() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_prev_macro_key() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_push_executing_macro(); +} +extern "C" { + pub fn _rl_pop_executing_macro(); +} +extern "C" { + pub fn _rl_add_macro_char(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_kill_kbd_macro(); +} +extern "C" { + pub fn _rl_arg_overflow() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_arg_init(); +} +extern "C" { + pub fn _rl_arg_getchar() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_arg_callback(arg1: _rl_arg_cxt) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_reset_argument(); +} +extern "C" { + pub fn _rl_start_using_history(); +} +extern "C" { + pub fn _rl_free_saved_history_line() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_set_insert_mode(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_revert_previous_lines(); +} +extern "C" { + pub fn _rl_revert_all_lines(); +} +extern "C" { + pub fn _rl_init_locale() -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_init_eightbit() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_enable_paren_matching(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_init_line_state(); +} +extern "C" { + pub fn _rl_set_the_line(); +} +extern "C" { + pub fn _rl_dispatch(arg1: ::std::os::raw::c_int, arg2: Keymap) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_dispatch_subseq( + arg1: ::std::os::raw::c_int, + arg2: Keymap, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_internal_char_cleanup(); +} +extern "C" { + pub fn _rl_init_executing_keyseq(); +} +extern "C" { + pub fn _rl_term_executing_keyseq(); +} +extern "C" { + pub fn _rl_end_executing_keyseq(); +} +extern "C" { + pub fn _rl_add_executing_keyseq(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_disable_tty_signals() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_restore_tty_signals() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_nsearch_callback(arg1: *mut _rl_search_cxt) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_nsearch_cleanup( + arg1: *mut _rl_search_cxt, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_signal_handler(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_block_sigint(); +} +extern "C" { + pub fn _rl_release_sigint(); +} +extern "C" { + pub fn _rl_block_sigwinch(); +} +extern "C" { + pub fn _rl_release_sigwinch(); +} +extern "C" { + pub fn _rl_get_screen_size(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_sigwinch_resize_terminal(); +} +extern "C" { + pub fn _rl_init_terminal_io(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_output_character_function(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_cr(); +} +extern "C" { + pub fn _rl_output_some_chars(arg1: *const ::std::os::raw::c_char, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_backspace(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_enable_meta_key(); +} +extern "C" { + pub fn _rl_disable_meta_key(); +} +extern "C" { + pub fn _rl_control_keypad(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_set_cursor(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_standout_on(); +} +extern "C" { + pub fn _rl_standout_off(); +} +extern "C" { + pub fn _rl_fix_point(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn _rl_fix_mark(); +} +extern "C" { + pub fn _rl_replace_text( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_forward_char_internal(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_backward_char_internal(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_insert_char( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_overwrite_char( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_overwrite_rubout( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_rubout_char( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_char_search_internal( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_char, + arg4: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_set_mark_at_pos(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_copy_undo_entry(arg1: *mut UNDO_LIST) -> *mut UNDO_LIST; +} +extern "C" { + pub fn _rl_copy_undo_list(arg1: *mut UNDO_LIST) -> *mut UNDO_LIST; +} +extern "C" { + pub fn _rl_free_undo_list(arg1: *mut UNDO_LIST); +} +extern "C" { + pub fn _rl_ttymsg(arg1: *const ::std::os::raw::c_char, ...); +} +extern "C" { + pub fn _rl_errmsg(arg1: *const ::std::os::raw::c_char, ...); +} +extern "C" { + pub fn _rl_trace(arg1: *const ::std::os::raw::c_char, ...); +} +extern "C" { + pub fn _rl_audit_tty(arg1: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn _rl_tropen() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_abort_internal() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_null_function( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_strindex( + arg1: *const ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn _rl_qsort_string_compare( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_uppercase_p(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_lowercase_p(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_pure_alphabetic(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_digit_p(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_to_lower(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_to_upper(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_digit_value(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_vi_initialize_line(); +} +extern "C" { + pub fn _rl_vi_reset_last(); +} +extern "C" { + pub fn _rl_vi_set_last( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn _rl_vi_textmod_command(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_vi_motion_command(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_vi_done_inserting(); +} +extern "C" { + pub fn _rl_vi_domove_callback(arg1: *mut _rl_vimotion_cxt) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_vi_domove_motion_cleanup( + arg1: ::std::os::raw::c_int, + arg2: *mut _rl_vimotion_cxt, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_possible_control_prefixes"] + pub static mut _rl_possible_control_prefixes: [*const ::std::os::raw::c_char; 0usize]; +} +extern "C" { + #[link_name = "\u{1}_rl_possible_meta_prefixes"] + pub static mut _rl_possible_meta_prefixes: [*const ::std::os::raw::c_char; 0usize]; +} +extern "C" { + #[link_name = "\u{1}_rl_callback_func"] + pub static mut _rl_callback_func: _rl_callback_func_t; +} +extern "C" { + #[link_name = "\u{1}_rl_callback_data"] + pub static mut _rl_callback_data: *mut _rl_callback_generic_arg; +} +extern "C" { + #[link_name = "\u{1}_rl_complete_show_all"] + pub static mut _rl_complete_show_all: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_complete_show_unmodified"] + pub static mut _rl_complete_show_unmodified: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_complete_mark_directories"] + pub static mut _rl_complete_mark_directories: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_complete_mark_symlink_dirs"] + pub static mut _rl_complete_mark_symlink_dirs: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_completion_prefix_display_length"] + pub static mut _rl_completion_prefix_display_length: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_completion_columns"] + pub static mut _rl_completion_columns: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_print_completions_horizontally"] + pub static mut _rl_print_completions_horizontally: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_completion_case_fold"] + pub static mut _rl_completion_case_fold: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_completion_case_map"] + pub static mut _rl_completion_case_map: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_match_hidden_files"] + pub static mut _rl_match_hidden_files: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_page_completions"] + pub static mut _rl_page_completions: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_skip_completed_text"] + pub static mut _rl_skip_completed_text: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_menu_complete_prefix_first"] + pub static mut _rl_menu_complete_prefix_first: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_vis_botlin"] + pub static mut _rl_vis_botlin: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_last_c_pos"] + pub static mut _rl_last_c_pos: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_suppress_redisplay"] + pub static mut _rl_suppress_redisplay: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_want_redisplay"] + pub static mut _rl_want_redisplay: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_emacs_mode_str"] + pub static mut _rl_emacs_mode_str: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_emacs_modestr_len"] + pub static mut _rl_emacs_modestr_len: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_vi_ins_mode_str"] + pub static mut _rl_vi_ins_mode_str: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_vi_ins_modestr_len"] + pub static mut _rl_vi_ins_modestr_len: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_vi_cmd_mode_str"] + pub static mut _rl_vi_cmd_mode_str: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_vi_cmd_modestr_len"] + pub static mut _rl_vi_cmd_modestr_len: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_isearch_terminators"] + pub static mut _rl_isearch_terminators: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_iscxt"] + pub static mut _rl_iscxt: *mut _rl_search_cxt; +} +extern "C" { + #[link_name = "\u{1}_rl_executing_macro"] + pub static mut _rl_executing_macro: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_history_preserve_point"] + pub static mut _rl_history_preserve_point: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_history_saved_point"] + pub static mut _rl_history_saved_point: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_argcxt"] + pub static mut _rl_argcxt: _rl_arg_cxt; +} +extern "C" { + #[link_name = "\u{1}_rl_utf8locale"] + pub static mut _rl_utf8locale: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_echoing_p"] + pub static mut _rl_echoing_p: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_horizontal_scroll_mode"] + pub static mut _rl_horizontal_scroll_mode: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_mark_modified_lines"] + pub static mut _rl_mark_modified_lines: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_bell_preference"] + pub static mut _rl_bell_preference: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_meta_flag"] + pub static mut _rl_meta_flag: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_convert_meta_chars_to_ascii"] + pub static mut _rl_convert_meta_chars_to_ascii: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_output_meta_chars"] + pub static mut _rl_output_meta_chars: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_bind_stty_chars"] + pub static mut _rl_bind_stty_chars: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_revert_all_at_newline"] + pub static mut _rl_revert_all_at_newline: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_echo_control_chars"] + pub static mut _rl_echo_control_chars: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_show_mode_in_prompt"] + pub static mut _rl_show_mode_in_prompt: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_enable_bracketed_paste"] + pub static mut _rl_enable_bracketed_paste: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_enable_active_region"] + pub static mut _rl_enable_active_region: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_comment_begin"] + pub static mut _rl_comment_begin: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_parsing_conditionalized_out"] + pub static mut _rl_parsing_conditionalized_out: ::std::os::raw::c_uchar; +} +extern "C" { + #[link_name = "\u{1}_rl_keymap"] + pub static mut _rl_keymap: Keymap; +} +extern "C" { + #[link_name = "\u{1}_rl_in_stream"] + pub static mut _rl_in_stream: *mut FILE; +} +extern "C" { + #[link_name = "\u{1}_rl_out_stream"] + pub static mut _rl_out_stream: *mut FILE; +} +extern "C" { + #[link_name = "\u{1}_rl_last_command_was_kill"] + pub static mut _rl_last_command_was_kill: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_eof_char"] + pub static mut _rl_eof_char: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_eof_found"] + pub static mut _rl_eof_found: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_top_level"] + pub static mut _rl_top_level: sigjmp_buf; +} +extern "C" { + #[link_name = "\u{1}_rl_kscxt"] + pub static mut _rl_kscxt: *mut _rl_keyseq_cxt; +} +extern "C" { + #[link_name = "\u{1}_rl_keyseq_timeout"] + pub static mut _rl_keyseq_timeout: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_executing_keyseq_size"] + pub static mut _rl_executing_keyseq_size: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_internal_startup_hook"] + pub static mut _rl_internal_startup_hook: rl_hook_func_t; +} +extern "C" { + #[link_name = "\u{1}_rl_nscxt"] + pub static mut _rl_nscxt: *mut _rl_search_cxt; +} +extern "C" { + #[link_name = "\u{1}_rl_caught_signal"] + pub static mut _rl_caught_signal: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_sigcleanup"] + pub static mut _rl_sigcleanup: _rl_sigcleanup_func_t; +} +extern "C" { + #[link_name = "\u{1}_rl_sigcleanarg"] + pub static mut _rl_sigcleanarg: *mut ::std::os::raw::c_void; +} +extern "C" { + #[link_name = "\u{1}_rl_echoctl"] + pub static mut _rl_echoctl: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_intr_char"] + pub static mut _rl_intr_char: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_quit_char"] + pub static mut _rl_quit_char: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_susp_char"] + pub static mut _rl_susp_char: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_enable_keypad"] + pub static mut _rl_enable_keypad: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_enable_meta"] + pub static mut _rl_enable_meta: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_term_clreol"] + pub static mut _rl_term_clreol: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_clrpag"] + pub static mut _rl_term_clrpag: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_clrscroll"] + pub static mut _rl_term_clrscroll: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_im"] + pub static mut _rl_term_im: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_ic"] + pub static mut _rl_term_ic: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_ei"] + pub static mut _rl_term_ei: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_DC"] + pub static mut _rl_term_DC: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_up"] + pub static mut _rl_term_up: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_dc"] + pub static mut _rl_term_dc: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_cr"] + pub static mut _rl_term_cr: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_IC"] + pub static mut _rl_term_IC: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_term_forward_char"] + pub static mut _rl_term_forward_char: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}_rl_screenheight"] + pub static mut _rl_screenheight: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_screenwidth"] + pub static mut _rl_screenwidth: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_screenchars"] + pub static mut _rl_screenchars: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_terminal_can_insert"] + pub static mut _rl_terminal_can_insert: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_term_autowrap"] + pub static mut _rl_term_autowrap: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_optimize_typeahead"] + pub static mut _rl_optimize_typeahead: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_keep_mark_active"] + pub static mut _rl_keep_mark_active: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_doing_an_undo"] + pub static mut _rl_doing_an_undo: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_undo_group_level"] + pub static mut _rl_undo_group_level: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_vi_last_command"] + pub static mut _rl_vi_last_command: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_vi_redoing"] + pub static mut _rl_vi_redoing: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_rl_vimvcxt"] + pub static mut _rl_vimvcxt: *mut _rl_vimotion_cxt; +} +extern "C" { + pub fn opendir(__name: *const ::std::os::raw::c_char) -> *mut DIR; +} +extern "C" { + pub fn fdopendir(__fd: ::std::os::raw::c_int) -> *mut DIR; +} +extern "C" { + pub fn closedir(__dirp: *mut DIR) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn readdir(__dirp: *mut DIR) -> *mut dirent; +} +extern "C" { + pub fn readdir64(__dirp: *mut DIR) -> *mut dirent64; +} +extern "C" { + pub fn readdir_r( + __dirp: *mut DIR, + __entry: *mut dirent, + __result: *mut *mut dirent, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn readdir64_r( + __dirp: *mut DIR, + __entry: *mut dirent64, + __result: *mut *mut dirent64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rewinddir(__dirp: *mut DIR); +} +extern "C" { + pub fn seekdir(__dirp: *mut DIR, __pos: ::std::os::raw::c_long); +} +extern "C" { + pub fn telldir(__dirp: *mut DIR) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn dirfd(__dirp: *mut DIR) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn scandir( + __dir: *const ::std::os::raw::c_char, + __namelist: *mut *mut *mut dirent, + __selector: ::core::option::Option< + unsafe extern "C" fn(arg1: *const dirent) -> ::std::os::raw::c_int, + >, + __cmp: ::core::option::Option< + unsafe extern "C" fn( + arg1: *mut *const dirent, + arg2: *mut *const dirent, + ) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn scandir64( + __dir: *const ::std::os::raw::c_char, + __namelist: *mut *mut *mut dirent64, + __selector: ::core::option::Option< + unsafe extern "C" fn(arg1: *const dirent64) -> ::std::os::raw::c_int, + >, + __cmp: ::core::option::Option< + unsafe extern "C" fn( + arg1: *mut *const dirent64, + arg2: *mut *const dirent64, + ) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn scandirat( + __dfd: ::std::os::raw::c_int, + __dir: *const ::std::os::raw::c_char, + __namelist: *mut *mut *mut dirent, + __selector: ::core::option::Option< + unsafe extern "C" fn(arg1: *const dirent) -> ::std::os::raw::c_int, + >, + __cmp: ::core::option::Option< + unsafe extern "C" fn( + arg1: *mut *const dirent, + arg2: *mut *const dirent, + ) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn scandirat64( + __dfd: ::std::os::raw::c_int, + __dir: *const ::std::os::raw::c_char, + __namelist: *mut *mut *mut dirent64, + __selector: ::core::option::Option< + unsafe extern "C" fn(arg1: *const dirent64) -> ::std::os::raw::c_int, + >, + __cmp: ::core::option::Option< + unsafe extern "C" fn( + arg1: *mut *const dirent64, + arg2: *mut *const dirent64, + ) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn alphasort(__e1: *mut *const dirent, __e2: *mut *const dirent) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn alphasort64( + __e1: *mut *const dirent64, + __e2: *mut *const dirent64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getdirentries( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __nbytes: usize, + __basep: *mut __off_t, + ) -> __ssize_t; +} +extern "C" { + pub fn getdirentries64( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __nbytes: usize, + __basep: *mut __off64_t, + ) -> __ssize_t; +} +extern "C" { + pub fn versionsort(__e1: *mut *const dirent, __e2: *mut *const dirent) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn versionsort64( + __e1: *mut *const dirent64, + __e2: *mut *const dirent64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _rl_parse_colors(); +} +extern "C" { + #[link_name = "\u{1}indicator_name"] + pub static mut indicator_name: [*const ::std::os::raw::c_char; 25usize]; +} +extern "C" { + #[link_name = "\u{1}color_buf"] + pub static mut color_buf: *mut ::std::os::raw::c_char; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct winsize { + pub ws_row: ::std::os::raw::c_ushort, + pub ws_col: ::std::os::raw::c_ushort, + pub ws_xpixel: ::std::os::raw::c_ushort, + pub ws_ypixel: ::std::os::raw::c_ushort, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct termio { + pub c_iflag: ::std::os::raw::c_ushort, + pub c_oflag: ::std::os::raw::c_ushort, + pub c_cflag: ::std::os::raw::c_ushort, + pub c_lflag: ::std::os::raw::c_ushort, + pub c_line: ::std::os::raw::c_uchar, + pub c_cc: [::std::os::raw::c_uchar; 8usize], +} +extern "C" { + pub fn ioctl( + __fd: ::std::os::raw::c_int, + __request: ::std::os::raw::c_ulong, + ... + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _rl_tty_chars { + pub t_eof: ::std::os::raw::c_uchar, + pub t_eol: ::std::os::raw::c_uchar, + pub t_eol2: ::std::os::raw::c_uchar, + pub t_erase: ::std::os::raw::c_uchar, + pub t_werase: ::std::os::raw::c_uchar, + pub t_kill: ::std::os::raw::c_uchar, + pub t_reprint: ::std::os::raw::c_uchar, + pub t_intr: ::std::os::raw::c_uchar, + pub t_quit: ::std::os::raw::c_uchar, + pub t_susp: ::std::os::raw::c_uchar, + pub t_dsusp: ::std::os::raw::c_uchar, + pub t_start: ::std::os::raw::c_uchar, + pub t_stop: ::std::os::raw::c_uchar, + pub t_lnext: ::std::os::raw::c_uchar, + pub t_flush: ::std::os::raw::c_uchar, + pub t_status: ::std::os::raw::c_uchar, +} +pub type _RL_TTY_CHARS = _rl_tty_chars; +extern "C" { + #[link_name = "\u{1}PC"] + pub static mut PC: ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}UP"] + pub static mut UP: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}BC"] + pub static mut BC: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}ospeed"] + pub static mut ospeed: ::std::os::raw::c_short; +} +extern "C" { + pub fn tgetstr( + arg1: *const ::std::os::raw::c_char, + arg2: *mut *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tgoto( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tgetent( + arg1: *mut ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tgetflag(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tgetnum(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tputs( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::core::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int, + >, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn stat(__file: *const ::std::os::raw::c_char, __buf: *mut stat) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fstat(__fd: ::std::os::raw::c_int, __buf: *mut stat) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn stat64( + __file: *const ::std::os::raw::c_char, + __buf: *mut stat64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fstat64(__fd: ::std::os::raw::c_int, __buf: *mut stat64) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fstatat( + __fd: ::std::os::raw::c_int, + __file: *const ::std::os::raw::c_char, + __buf: *mut stat, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fstatat64( + __fd: ::std::os::raw::c_int, + __file: *const ::std::os::raw::c_char, + __buf: *mut stat64, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lstat64( + __file: *const ::std::os::raw::c_char, + __buf: *mut stat64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn chmod(__file: *const ::std::os::raw::c_char, __mode: __mode_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lchmod(__file: *const ::std::os::raw::c_char, __mode: __mode_t) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fchmod(__fd: ::std::os::raw::c_int, __mode: __mode_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fchmodat( + __fd: ::std::os::raw::c_int, + __file: *const ::std::os::raw::c_char, + __mode: __mode_t, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn umask(__mask: __mode_t) -> __mode_t; +} +extern "C" { + pub fn getumask() -> __mode_t; +} +extern "C" { + pub fn mkdir(__path: *const ::std::os::raw::c_char, __mode: __mode_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkdirat( + __fd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __mode: __mode_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mknod( + __path: *const ::std::os::raw::c_char, + __mode: __mode_t, + __dev: __dev_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mknodat( + __fd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __mode: __mode_t, + __dev: __dev_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkfifo(__path: *const ::std::os::raw::c_char, __mode: __mode_t) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn mkfifoat( + __fd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __mode: __mode_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn utimensat( + __fd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __times: *const timespec, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn futimens(__fd: ::std::os::raw::c_int, __times: *const timespec) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __fxstat( + __ver: ::std::os::raw::c_int, + __fildes: ::std::os::raw::c_int, + __stat_buf: *mut stat, + ) -> ::std::os::raw::c_int; +} +// extern "C" { +// pub fn __xstat( +// __ver: ::std::os::raw::c_int, +// __filename: *const ::std::os::raw::c_char, +// __stat_buf: *mut stat, +// ) -> ::std::os::raw::c_int; +// } +extern "C" { + pub fn __lxstat( + __ver: ::std::os::raw::c_int, + __filename: *const ::std::os::raw::c_char, + __stat_buf: *mut crate::src_common::stat, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __fxstatat( + __ver: ::std::os::raw::c_int, + __fildes: ::std::os::raw::c_int, + __filename: *const ::std::os::raw::c_char, + __stat_buf: *mut stat, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __fxstat64( + __ver: ::std::os::raw::c_int, + __fildes: ::std::os::raw::c_int, + __stat_buf: *mut stat64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __xstat64( + __ver: ::std::os::raw::c_int, + __filename: *const ::std::os::raw::c_char, + __stat_buf: *mut stat64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __lxstat64( + __ver: ::std::os::raw::c_int, + __filename: *const ::std::os::raw::c_char, + __stat_buf: *mut stat64, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __fxstatat64( + __ver: ::std::os::raw::c_int, + __fildes: ::std::os::raw::c_int, + __filename: *const ::std::os::raw::c_char, + __stat_buf: *mut stat64, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __xmknod( + __ver: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __mode: __mode_t, + __dev: *mut __dev_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __xmknodat( + __ver: ::std::os::raw::c_int, + __fd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __mode: __mode_t, + __dev: *mut __dev_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn statx( + __dirfd: ::std::os::raw::c_int, + __path: *const ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + __mask: ::std::os::raw::c_uint, + __buf: *mut statx, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn _hs_history_patsearch( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_adjtime(__clock_id: __clockid_t, __utx: *mut timex) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock() -> clock_t; +} +extern "C" { + pub fn time(__timer: *mut time_t) -> time_t; +} +extern "C" { + pub fn difftime(__time1: time_t, __time0: time_t) -> f64; +} +extern "C" { + pub fn mktime(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn strftime( + __s: *mut ::std::os::raw::c_char, + __maxsize: usize, + __format: *const ::std::os::raw::c_char, + __tp: *const tm, + ) -> usize; +} +extern "C" { + pub fn strptime( + __s: *const ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __tp: *mut tm, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn strftime_l( + __s: *mut ::std::os::raw::c_char, + __maxsize: usize, + __format: *const ::std::os::raw::c_char, + __tp: *const tm, + __loc: locale_t, + ) -> usize; +} +extern "C" { + pub fn strptime_l( + __s: *const ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __tp: *mut tm, + __loc: locale_t, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn gmtime(__timer: *const time_t) -> *mut tm; +} +extern "C" { + pub fn localtime(__timer: *const time_t) -> *mut tm; +} +extern "C" { + pub fn gmtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; +} +extern "C" { + pub fn localtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; +} +extern "C" { + pub fn asctime(__tp: *const tm) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ctime(__timer: *const time_t) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn asctime_r( + __tp: *const tm, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ctime_r( + __timer: *const time_t, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}__tzname"] + pub static mut __tzname: [*mut ::std::os::raw::c_char; 2usize]; +} +extern "C" { + #[link_name = "\u{1}__daylight"] + pub static mut __daylight: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__timezone"] + pub static mut __timezone: ::std::os::raw::c_long; +} +extern "C" { + #[link_name = "\u{1}tzname"] + pub static mut tzname: [*mut ::std::os::raw::c_char; 2usize]; +} +extern "C" { + pub fn tzset(); +} +extern "C" { + #[link_name = "\u{1}daylight"] + pub static mut daylight: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}timezone"] + pub static mut timezone: ::std::os::raw::c_long; +} +extern "C" { + pub fn stime(__when: *const time_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timegm(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn timelocal(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn dysize(__year: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn nanosleep( + __requested_time: *const timespec, + __remaining: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_getres(__clock_id: clockid_t, __res: *mut timespec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut timespec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_settime(__clock_id: clockid_t, __tp: *const timespec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_nanosleep( + __clock_id: clockid_t, + __flags: ::std::os::raw::c_int, + __req: *const timespec, + __rem: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_getcpuclockid(__pid: pid_t, __clock_id: *mut clockid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_create( + __clock_id: clockid_t, + __evp: *mut sigevent, + __timerid: *mut timer_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_delete(__timerid: timer_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_settime( + __timerid: timer_t, + __flags: ::std::os::raw::c_int, + __value: *const itimerspec, + __ovalue: *mut itimerspec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_gettime(__timerid: timer_t, __value: *mut itimerspec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_getoverrun(__timerid: timer_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timespec_get( + __ts: *mut timespec, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}getdate_err"] + pub static mut getdate_err: ::std::os::raw::c_int; +} +extern "C" { + pub fn getdate(__string: *const ::std::os::raw::c_char) -> *mut tm; +} +extern "C" { + pub fn getdate_r( + __string: *const ::std::os::raw::c_char, + __resbufp: *mut tm, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _hist_state { + pub entries: *mut *mut HIST_ENTRY, + pub offset: ::std::os::raw::c_int, + pub length: ::std::os::raw::c_int, + pub size: ::std::os::raw::c_int, + pub flags: ::std::os::raw::c_int, +} +pub type HISTORY_STATE = _hist_state; + +extern "C" { + pub fn history_get_history_state() -> *mut HISTORY_STATE; +} +extern "C" { + pub fn history_set_history_state(arg1: *mut HISTORY_STATE); +} +extern "C" { + pub fn add_history_time(arg1: *const ::std::os::raw::c_char); +} +extern "C" { + pub fn alloc_history_entry( + arg1: *mut ::std::os::raw::c_char, + arg2: *mut ::std::os::raw::c_char, + ) -> *mut HIST_ENTRY; +} +extern "C" { + pub fn copy_history_entry(arg1: *mut HIST_ENTRY) -> *mut HIST_ENTRY; +} +extern "C" { + pub fn stifle_history(arg1: ::std::os::raw::c_int); +} +extern "C" { + pub fn unstifle_history() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn current_history() -> *mut HIST_ENTRY; +} +extern "C" { + pub fn history_get_time(arg1: *mut HIST_ENTRY) -> time_t; +} +extern "C" { + pub fn history_total_bytes() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn next_history() -> *mut HIST_ENTRY; +} +extern "C" { + pub fn history_search( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn history_search_prefix( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn history_search_pos( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn read_history_range( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn history_truncate_file( + arg1: *const ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn history_arg_extract( + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + arg3: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn get_history_event( + arg1: *const ::std::os::raw::c_char, + arg2: *mut ::std::os::raw::c_int, + arg3: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn history_tokenize( + arg1: *const ::std::os::raw::c_char, + ) -> *mut *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}history_offset"] + pub static mut history_offset: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}history_word_delimiters"] + pub static mut history_word_delimiters: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}history_comment_char"] + pub static mut history_comment_char: ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}history_no_expand_chars"] + pub static mut history_no_expand_chars: *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}history_write_timestamps"] + pub static mut history_write_timestamps: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}history_multiline_entries"] + pub static mut history_multiline_entries: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}history_file_version"] + pub static mut history_file_version: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}max_input_history"] + pub static mut max_input_history: ::std::os::raw::c_int; +} +// extern "C" { +// #[link_name = "\u{1}stdin"] +// pub static mut stdin: *mut FILE; +// } +extern "C" { + pub fn remove(__filename: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rename( + __old: *const ::std::os::raw::c_char, + __new: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn renameat( + __oldfd: ::std::os::raw::c_int, + __old: *const ::std::os::raw::c_char, + __newfd: ::std::os::raw::c_int, + __new: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn renameat2( + __oldfd: ::std::os::raw::c_int, + __old: *const ::std::os::raw::c_char, + __newfd: ::std::os::raw::c_int, + __new: *const ::std::os::raw::c_char, + __flags: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tmpfile() -> *mut FILE; +} +extern "C" { + pub fn tmpfile64() -> *mut FILE; +} +extern "C" { + pub fn tmpnam(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tmpnam_r(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tempnam( + __dir: *const ::std::os::raw::c_char, + __pfx: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn fclose(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fflush_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fcloseall() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fopen( + __filename: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn freopen( + __filename: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + __stream: *mut FILE, + ) -> *mut FILE; +} +extern "C" { + pub fn fopen64( + __filename: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn freopen64( + __filename: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + __stream: *mut FILE, + ) -> *mut FILE; +} +extern "C" { + pub fn fdopen(__fd: ::std::os::raw::c_int, __modes: *const ::std::os::raw::c_char) + -> *mut FILE; +} +extern "C" { + pub fn fopencookie( + __magic_cookie: *mut ::std::os::raw::c_void, + __modes: *const ::std::os::raw::c_char, + __io_funcs: cookie_io_functions_t, + ) -> *mut FILE; +} +extern "C" { + pub fn fmemopen( + __s: *mut ::std::os::raw::c_void, + __len: usize, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn open_memstream( + __bufloc: *mut *mut ::std::os::raw::c_char, + __sizeloc: *mut usize, + ) -> *mut FILE; +} +extern "C" { + pub fn setbuf(__stream: *mut FILE, __buf: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn setvbuf( + __stream: *mut FILE, + __buf: *mut ::std::os::raw::c_char, + __modes: ::std::os::raw::c_int, + __n: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setbuffer(__stream: *mut FILE, __buf: *mut ::std::os::raw::c_char, __size: usize); +} +extern "C" { + pub fn setlinebuf(__stream: *mut FILE); +} +extern "C" { + pub fn vfprintf( + __s: *mut FILE, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vprintf( + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vsprintf( + __s: *mut ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn snprintf( + __s: *mut ::std::os::raw::c_char, + __maxlen: usize, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vsnprintf( + __s: *mut ::std::os::raw::c_char, + __maxlen: usize, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vasprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __f: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __asprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn asprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vdprintf( + __fd: ::std::os::raw::c_int, + __fmt: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn dprintf( + __fd: ::std::os::raw::c_int, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fscanf( + __stream: *mut FILE, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn scanf(__format: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sscanf( + __s: *const ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vfscanf( + __s: *mut FILE, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vscanf( + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vsscanf( + __s: *const ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgetc(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getc(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getchar() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getc_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getchar_unlocked() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgetc_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fputc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putchar(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fputc_unlocked(__c: ::std::os::raw::c_int, __stream: *mut FILE) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putc_unlocked(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putchar_unlocked(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getw(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putw(__w: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgets( + __s: *mut ::std::os::raw::c_char, + __n: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn fgets_unlocked( + __s: *mut ::std::os::raw::c_char, + __n: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn __getdelim( + __lineptr: *mut *mut ::std::os::raw::c_char, + __n: *mut usize, + __delimiter: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> __ssize_t; +} +extern "C" { + pub fn getdelim( + __lineptr: *mut *mut ::std::os::raw::c_char, + __n: *mut usize, + __delimiter: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> __ssize_t; +} +extern "C" { + pub fn getline( + __lineptr: *mut *mut ::std::os::raw::c_char, + __n: *mut usize, + __stream: *mut FILE, + ) -> __ssize_t; +} +extern "C" { + pub fn fputs(__s: *const ::std::os::raw::c_char, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn puts(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ungetc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fread( + __ptr: *mut ::std::os::raw::c_void, + __size: usize, + __n: usize, + __stream: *mut FILE, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn fwrite( + __ptr: *const ::std::os::raw::c_void, + __size: usize, + __n: usize, + __s: *mut FILE, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn fputs_unlocked( + __s: *const ::std::os::raw::c_char, + __stream: *mut FILE, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fread_unlocked( + __ptr: *mut ::std::os::raw::c_void, + __size: usize, + __n: usize, + __stream: *mut FILE, + ) -> usize; +} +extern "C" { + pub fn fwrite_unlocked( + __ptr: *const ::std::os::raw::c_void, + __size: usize, + __n: usize, + __stream: *mut FILE, + ) -> usize; +} +extern "C" { + pub fn fseek( + __stream: *mut FILE, + __off: ::std::os::raw::c_long, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftell(__stream: *mut FILE) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn rewind(__stream: *mut FILE); +} +extern "C" { + pub fn fseeko( + __stream: *mut FILE, + __off: __off_t, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftello(__stream: *mut FILE) -> __off_t; +} +extern "C" { + pub fn fgetpos(__stream: *mut FILE, __pos: *mut fpos_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fsetpos(__stream: *mut FILE, __pos: *const fpos_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fseeko64( + __stream: *mut FILE, + __off: __off64_t, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftello64(__stream: *mut FILE) -> __off64_t; +} +extern "C" { + pub fn fgetpos64(__stream: *mut FILE, __pos: *mut fpos64_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fsetpos64(__stream: *mut FILE, __pos: *const fpos64_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clearerr(__stream: *mut FILE); +} +extern "C" { + pub fn feof(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ferror(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clearerr_unlocked(__stream: *mut FILE); +} +extern "C" { + pub fn feof_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ferror_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn perror(__s: *const ::std::os::raw::c_char); +} +extern "C" { + #[link_name = "\u{1}sys_nerr"] + pub static mut sys_nerr: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}sys_errlist"] + pub static mut sys_errlist: [*const ::std::os::raw::c_char; 0usize]; +} +extern "C" { + #[link_name = "\u{1}_sys_nerr"] + pub static mut _sys_nerr: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}_sys_errlist"] + pub static mut _sys_errlist: [*const ::std::os::raw::c_char; 0usize]; +} +extern "C" { + pub fn fileno_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn popen( + __command: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn pclose(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ctermid(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn cuserid(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn obstack_printf( + __obstack: *mut obstack, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn obstack_vprintf( + __obstack: *mut obstack, + __format: *const ::std::os::raw::c_char, + __args: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn flockfile(__stream: *mut FILE); +} +extern "C" { + pub fn ftrylockfile(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn funlockfile(__stream: *mut FILE); +} +extern "C" { + pub fn __uflow(arg1: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __overflow(arg1: *mut FILE, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bin_str { + pub len: usize, + pub string: *const ::std::os::raw::c_char, +} +extern "C" { + #[link_name = "\u{1}_rl_color_indicator"] + pub static mut _rl_color_indicator: [bin_str; 0usize]; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _color_ext_type { + pub ext: bin_str, + pub seq: bin_str, + pub next: *mut _color_ext_type, +} +pub type COLOR_EXT_TYPE = _color_ext_type; +extern "C" { + #[link_name = "\u{1}_rl_color_ext_list"] + pub static mut _rl_color_ext_list: *mut COLOR_EXT_TYPE; +} +pub const indicator_no_C_LEFT: indicator_no = 0; +pub const indicator_no_C_RIGHT: indicator_no = 1; +pub const indicator_no_C_END: indicator_no = 2; +pub const indicator_no_C_RESET: indicator_no = 3; +pub const indicator_no_C_NORM: indicator_no = 4; +pub const indicator_no_C_FILE: indicator_no = 5; +pub const indicator_no_C_DIR: indicator_no = 6; +pub const indicator_no_C_LINK: indicator_no = 7; +pub const indicator_no_C_FIFO: indicator_no = 8; +pub const indicator_no_C_SOCK: indicator_no = 9; +pub const indicator_no_C_BLK: indicator_no = 10; +pub const indicator_no_C_CHR: indicator_no = 11; +pub const indicator_no_C_MISSING: indicator_no = 12; +pub const indicator_no_C_ORPHAN: indicator_no = 13; +pub const indicator_no_C_EXEC: indicator_no = 14; +pub const indicator_no_C_DOOR: indicator_no = 15; +pub const indicator_no_C_SETUID: indicator_no = 16; +pub const indicator_no_C_SETGID: indicator_no = 17; +pub const indicator_no_C_STICKY: indicator_no = 18; +pub const indicator_no_C_OTHER_WRITABLE: indicator_no = 19; +pub const indicator_no_C_STICKY_OTHER_WRITABLE: indicator_no = 20; +pub const indicator_no_C_CAP: indicator_no = 21; +pub const indicator_no_C_MULTIHARDLINK: indicator_no = 22; +pub const indicator_no_C_CLR_TO_EOL: indicator_no = 23; +pub type indicator_no = u32; +pub const filetype_unknown: filetype = 0; +pub const filetype_fifo: filetype = 1; +pub const filetype_chardev: filetype = 2; +pub const filetype_directory: filetype = 3; +pub const filetype_blockdev: filetype = 4; +pub const filetype_normal: filetype = 5; +pub const filetype_symbolic_link: filetype = 6; +pub const filetype_sock: filetype = 7; +pub const filetype_whiteout: filetype = 8; +pub const filetype_arg_directory: filetype = 9; +pub type filetype = u32; +extern "C" { + pub fn _rl_put_indicator(ind: *const bin_str); +} +extern "C" { + pub fn _rl_set_normal_color(); +} +extern "C" { + pub fn _rl_print_prefix_color() -> bool; +} +extern "C" { + pub fn _rl_print_color_indicator(f: *const ::std::os::raw::c_char) -> bool; +} +extern "C" { + pub fn _rl_prep_non_filename_text(); +} diff --git a/utshell-0.5.0/src/redir.rs b/utshell-0.5.0/src/redir.rs new file mode 100644 index 00000000..11a6fee5 --- /dev/null +++ b/utshell-0.5.0/src/redir.rs @@ -0,0 +1,1335 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::arrayfunc::{array_variable_part, get_array_value, valid_array_reference}; +use crate::copycmd::{copy_redirects, copy_word}; +use crate::dispose_cmd::{dispose_redirects, dispose_words}; +use crate::execute_cmd::{coproc_fdchk, dispose_exec_redirects}; +use crate::general::{all_digits, legal_number, same_file}; +use crate::input::{check_bash_input, close_buffered_fd, duplicate_buffered_stream}; +use crate::make_cmd::{make_bare_word, make_redirection, make_word_list}; +use crate::print_cmd::xtrace_fdchk; +use crate::readline::run_pending_traps; +use crate::src_common::*; +use crate::stringlib::find_string_in_alist; +use crate::subst::{ + expand_assignment_string_to_string, expand_string_to_string, expand_words_no_vars, string_list, +}; +use crate::variables::{ + bind_var_to_int, find_variable_last_nameref, get_variable_value, + stupidly_hack_special_variables, sv_ifs, +}; + +#[inline] +fn stat( + mut __path: *const libc::c_char, + mut __statbuf: *mut crate::src_common::stat, +) -> libc::c_int { + unsafe { + return __xstat(1 as libc::c_int, __path, __statbuf); + } +} + +#[inline] +fn fstat(mut __fd: libc::c_int, mut __statbuf: *mut crate::src_common::stat) -> libc::c_int { + unsafe { + return __fxstat(1 as libc::c_int, __fd, __statbuf); + } +} + +static mut rd: REDIRECTEE = REDIRECTEE { dest: 0 }; +static mut heredoc_errno: libc::c_int = 0; + +/* STRLEN_1 本æ¥ä¸ºSTRLE,由于存在冲çªï¼Œæ‰€ä»¥å°†æœ¬å®è¯¥ä¸ºSTRLEN_1,表示第一个å˜åž‹ */ +#[macro_export] +macro_rules! STRLEN_1 { + ($desc: expr) => { + if !((*($desc as *mut WORD_DESC)).word).is_null() + && *((*($desc as *mut WORD_DESC)).word).offset(0 as libc::c_int as isize) as libc::c_int + != 0 + { + if *((*($desc as *mut WORD_DESC)).word).offset(1 as libc::c_int as isize) as libc::c_int + != 0 + { + if *((*($desc as *mut WORD_DESC)).word).offset(2 as libc::c_int as isize) + as libc::c_int + != 0 + { + strlen((*($desc as *mut WORD_DESC)).word) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + } + }; +} + +#[no_mangle] +pub fn redirection_error( + mut temp: *mut REDIRECT, + mut error: libc::c_int, + mut fn_0: *mut libc::c_char, +) { + let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut allocname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oflags: libc::c_int = 0; + allocname = 0 as *mut libc::c_char; + unsafe { + if (*temp).rflags & 0x1 as libc::c_int != 0 && error < 0 as libc::c_int { + allocname = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*(*temp).redirector.filename).word) as u64) + as usize, + ) as *mut libc::c_char, + (*(*temp).redirector.filename).word, + ); + filename = allocname; + } else if (*temp).rflags & REDIR_VARASSIGN as libc::c_int == 0 as libc::c_int + && (*temp).redirector.dest < REDIR_VARASSIGN as libc::c_int + { + filename = dcgettext( + 0 as *const libc::c_char, + b"file descriptor out of range\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ); + } else if error != NOCLOBBER_REDIRECT + && (*temp).redirector.dest >= 0 as libc::c_int + && error == EBADF as libc::c_int + { + match (*temp).instruction as libc::c_uint { + r_duplicating_input | r_duplicating_output | r_move_input | r_move_output => { + allocname = itos((*temp).redirectee.dest as intmax_t); + filename = allocname; + } + r_duplicating_input_word => { + if (*temp).redirector.dest == 0 as libc::c_int { + filename = (*(*temp).redirectee.filename).word; + } else { + allocname = itos((*temp).redirector.dest as intmax_t); + filename = allocname; + } + } + r_duplicating_output_word => { + if (*temp).redirector.dest == 1 as libc::c_int { + filename = (*(*temp).redirectee.filename).word; + } else { + allocname = itos((*temp).redirector.dest as intmax_t); + filename = allocname; + } + } + _ => { + allocname = itos((*temp).redirector.dest as intmax_t); + filename = allocname; + } + } + } else if !fn_0.is_null() { + filename = fn_0; + } else if expandable_redirection_filename(temp) != 0 { + oflags = (*(*temp).redirectee.filename).flags; + if posixly_correct != 0 && interactive_shell == 0 as libc::c_int { + (*(*temp).redirectee.filename).flags |= (1 as libc::c_int) << 5 as libc::c_int; + } + (*(*temp).redirectee.filename).flags |= (1 as libc::c_int) << 10 as libc::c_int; + allocname = redirection_expand((*temp).redirectee.filename); + filename = allocname; + (*(*temp).redirectee.filename).flags = oflags; + if filename.is_null() { + filename = (*(*temp).redirectee.filename).word; + } + } else if (*temp).redirectee.dest < 0 as libc::c_int { + filename = dcgettext( + 0 as *const libc::c_char, + b"file descriptor out of range\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ); + } else { + allocname = itos((*temp).redirectee.dest as intmax_t); + filename = allocname; + } + + match error { + AMBIGUOUS_REDIRECT => { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: ambiguous redirect\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + } + NOCLOBBER_REDIRECT => { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot overwrite existing file\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + } + RESTRICTED_REDIRECT => { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: restricted: cannot redirect output\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + } + HEREDOC_REDIRECT => { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot create temp file for here-document: %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + strerror(heredoc_errno), + ); + } + BADVAR_REDIRECT => { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot assign fd to variable\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + filename, + ); + } + _ => { + internal_error( + b"%s: %s\0" as *const u8 as *const libc::c_char, + filename, + strerror(error), + ); + } + } + if !allocname.is_null() { + free(allocname as *mut libc::c_void); + } + allocname = 0 as *mut libc::c_char; + } +} +#[no_mangle] +pub fn do_redirections(mut list: *mut REDIRECT, mut flags: libc::c_int) -> libc::c_int { + let mut error: libc::c_int = 0; + let mut temp: *mut REDIRECT = 0 as *mut REDIRECT; + let mut fn_0: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if flags & (RX_UNDOABLE as i32) != 0 { + if !redirection_undo_list.is_null() { + dispose_redirects(redirection_undo_list); + redirection_undo_list = 0 as *mut libc::c_void as *mut REDIRECT; + } + if !exec_redirection_undo_list.is_null() { + dispose_exec_redirects(); + } + } + //println!("in {}:{}", stdext::function_name!(),std::line!()); + temp = list; + while !temp.is_null() { + fn_0 = 0 as *mut libc::c_char; + error = do_redirection_internal(temp, flags, &mut fn_0); + if error != 0 { + redirection_error(temp, error, fn_0); + if !fn_0.is_null() { + free(fn_0 as *mut libc::c_void); + } + fn_0 = 0 as *mut libc::c_char; + return error; + } + if !fn_0.is_null() { + free(fn_0 as *mut libc::c_void); + } + fn_0 = 0 as *mut libc::c_char; + temp = (*temp).next; + } + } + return 0 as libc::c_int; +} +fn expandable_redirection_filename(mut redirect: *mut REDIRECT) -> libc::c_int { + unsafe { + match (*redirect).instruction as libc::c_uint { + r_output_direction + | r_appending_to + | r_input_direction + | r_inputa_direction + | r_err_and_out + | r_append_err_and_out + | r_input_output + | r_output_force + | r_duplicating_input_word + | r_duplicating_output_word + | r_move_input_word + | r_move_output_word => return 1 as libc::c_int, + _ => return 0 as libc::c_int, + }; + } +} + +#[no_mangle] +pub fn redirection_expand(mut word: *mut WORD_DESC) -> *mut libc::c_char { + unsafe { + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tlist1: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tlist2: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut old: libc::c_int = 0; + + w = copy_word(word); + if posixly_correct != 0 { + (*w).flags |= (1 as libc::c_int) << 4 as libc::c_int; + } + tlist1 = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + expanding_redir = 1 as libc::c_int; + sv_ifs(b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + tlist2 = expand_words_no_vars(tlist1); + expanding_redir = 0 as libc::c_int; + /* Now we need to change the variable search order back to include the temp + environment. We force the temp environment search by forcing + executing_builtin to 1. This is what makes `read' get the right values + for the IFS-related cached variables, for example. */ + old = executing_builtin; + executing_builtin = 1 as libc::c_int; + sv_ifs(b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + executing_builtin = old; + dispose_words(tlist1); + if tlist2.is_null() || !((*tlist2).next).is_null() { + /* We expanded to no words, or to more than a single word. + Dispose of the word list and return NULL. */ + if !tlist2.is_null() { + dispose_words(tlist2); + } + return 0 as *mut libc::c_void as *mut libc::c_char; + } + result = string_list(tlist2); /* XXX savestring (tlist2->word->word)? */ + dispose_words(tlist2); + return result; + } +} + +/* Expand a here-document or here-string (determined by RI) contained in +REDIRECTEE and return the expanded document. If LENP is non-zero, put +the length of the returned string into *LENP. + +This captures everything about expanding here-documents and here-strings: +the returned document should be written directly to whatever file +descriptor is specified. In particular, it adds a newline to the end of +a here-string to preserve previous semantics. */ +fn heredoc_expand( + mut redirectee: *mut WORD_DESC, + mut ri: libc::c_uint, + mut lenp: *mut size_t, +) -> *mut libc::c_char { + unsafe { + let mut document: *mut libc::c_char = 0 as *mut libc::c_char; + let mut dlen: size_t = 0; + let mut old: libc::c_int = 0; + if ((*redirectee).word).is_null() + || *((*redirectee).word).offset(0 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + if !lenp.is_null() { + *lenp = 0 as libc::c_int as size_t; + } + return (*redirectee).word; + } + if ri as libc::c_uint != r_reading_string + && (*redirectee).flags & (1 as libc::c_int) << 1 as libc::c_int != 0 + { + if !lenp.is_null() { + (*lenp) = STRLEN_1!(redirectee); + } + return (*redirectee).word; + } + expanding_redir = 1 as libc::c_int; + sv_ifs(b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + if ri as libc::c_uint == r_reading_string { + document = expand_assignment_string_to_string((*redirectee).word, 0 as libc::c_int) + } else { + document = expand_string_to_string((*redirectee).word, 0x2 as libc::c_int) + }; + expanding_redir = 0 as libc::c_int; + old = executing_builtin; + executing_builtin = 1 as libc::c_int; + sv_ifs(b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + executing_builtin = old; + dlen = STRLEN_1!(document); + if ri as libc::c_uint == r_reading_string { + document = realloc( + document as *mut libc::c_void, + dlen.wrapping_add(2 as libc::c_int as size_t) as usize, + ) as *mut libc::c_char; + let fresh0 = dlen; + dlen = dlen.wrapping_add(1); + *document.offset(fresh0 as isize) = '\n' as i32 as libc::c_char; + *document.offset(dlen as isize) = '\0' as i32 as libc::c_char; + } + if !lenp.is_null() { + *lenp = dlen; + } + return document; + } +} +fn heredoc_write( + mut fd: libc::c_int, + mut heredoc: *mut libc::c_char, + mut herelen: size_t, +) -> libc::c_int { + let mut nw: ssize_t = 0; + let mut e: libc::c_int = 0; + unsafe { + *__errno_location() = 0 as libc::c_int; + nw = write(fd, heredoc as *const libc::c_void, herelen as usize) as i64; + e = *__errno_location(); + if nw as size_t != herelen { + if e == 0 as libc::c_int { + e = ENOSPC; + } + return e; + } + return 0 as libc::c_int; + } +} + +fn here_document_to_fd( + mut redirectee: *mut WORD_DESC, + mut ri: libc::c_uint, //枚举 +) -> libc::c_int { + unsafe { + let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + let mut fd: libc::c_int = 0; + let mut fd2: libc::c_int = 0; + let mut herepipe: [libc::c_int; 2] = [0; 2]; + let mut document: *mut libc::c_char = 0 as *mut libc::c_char; + let mut document_len: size_t = 0; + document = heredoc_expand(redirectee, ri, &mut document_len); + if document_len == 0 as libc::c_int as size_t { + fd = open( + b"/dev/null\0" as *const u8 as *const libc::c_char, + 0 as libc::c_int, + ); + r = *__errno_location(); + if document != (*redirectee).word { + if !document.is_null() { + free(document as *mut libc::c_void); + } + document = 0 as *mut libc::c_char; + } + *__errno_location() = r; + return fd; + } + if document_len <= HEREDOC_PIPESIZE as libc::c_int as size_t { + if pipe(herepipe.as_mut_ptr()) < 0 as libc::c_int { + r = *__errno_location(); + if document != (*redirectee).word { + free(document as *mut libc::c_void); + } + *__errno_location() = r; + return -(1 as libc::c_int); + } + if !((fcntl( + herepipe[1 as libc::c_int as usize], + F_GETPIPE_SZ, + 0 as libc::c_int, + ) as size_t) + < document_len) + { + r = heredoc_write(herepipe[1 as libc::c_int as usize], document, document_len); + if document != (*redirectee).word { + free(document as *mut libc::c_void); + } + close(herepipe[1 as libc::c_int as usize]); + if r != 0 { + close(herepipe[0 as libc::c_int as usize]); + *__errno_location() = r; + return -(1 as libc::c_int); + } + return herepipe[0 as libc::c_int as usize]; + } + } + fd = sh_mktmpfd( + b"sh-thd\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + (MT_USERANDOM | MT_USETMPDIR) as i32, + &mut filename, + ); + if fd < 0 as libc::c_int { + r = *__errno_location(); + if !filename.is_null() { + free(filename as *mut libc::c_void); + } + filename = 0 as *mut libc::c_char; + if document != (*redirectee).word { + if !document.is_null() { + free(document as *mut libc::c_void); + } + document = 0 as *mut libc::c_char; + } + *__errno_location() = r; + return fd; + } + + // fchmod (fd, S_IRUSR | S_IWUSR); + + fchmod(fd, (S_IRUSR | S_IWUSR) as libc::c_uint); + fcntl(fd, 2 as libc::c_int, 1 as libc::c_int); + r = 0 as libc::c_int; + + *__errno_location() = r; + r = heredoc_write(fd, document, document_len); + if document != (*redirectee).word { + if !document.is_null() { + free(document as *mut libc::c_void); + } + document = 0 as *mut libc::c_char; + } + if r != 0 { + close(fd); + unlink(filename); + free(filename as *mut libc::c_void); + *__errno_location() = r; + return -(1 as libc::c_int); + } + fd2 = open( + filename, + 0 as libc::c_int | 0 as libc::c_int, + 0o600 as libc::c_int, + ); + if fd2 < 0 as libc::c_int { + r = *__errno_location(); + unlink(filename); + free(filename as *mut libc::c_void); + close(fd); + *__errno_location() = r; + return -(1 as libc::c_int); + } + close(fd); + if unlink(filename) < 0 as libc::c_int { + r = *__errno_location(); + close(fd2); + free(filename as *mut libc::c_void); + *__errno_location() = r; + return -(1 as libc::c_int); + } + free(filename as *mut libc::c_void); + fchmod(fd2, 0o400 as libc::c_int as libc::c_uint); + return fd2; + } +} + +static mut _redir_special_filenames: [STRING_INT_ALIST; 3] = [ + { + let mut init = STRING_INT_ALIST { + word: b"/dev/tcp/*/*\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: RF_DEVTCP, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"/dev/udp/*/*\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: RF_DEVUDP, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + token: RF_END, + }; + init + }, +]; +fn redir_special_open( + mut spec: libc::c_int, + mut filename: *mut libc::c_char, + mut _flags: libc::c_int, + mut _mode: libc::c_int, + mut _ri: r_instruction, +) -> libc::c_int { + unsafe { + let mut fd: libc::c_int = 0; + fd = RF_END; + match spec { + RF_DEVTCP | RF_DEVUDP => { + if restricted != 0 { + return RESTRICTED_REDIRECT; + } + fd = netopen(filename); + } + _ => {} + } + return fd; + } +} + +fn noclobber_open( + mut filename: *mut libc::c_char, + mut flags: libc::c_int, + mut mode: libc::c_int, + mut _ri: r_instruction, +) -> libc::c_int { + unsafe { + let mut r: libc::c_int = 0; + let mut fd: libc::c_int = 0; + let mut finfo: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut finfo2: crate::src_common::stat = crate::src_common::stat { ..finfo }; + r = stat(filename, &mut finfo); + if r == 0 && S_ISREG!(finfo.st_mode) { + return NOCLOBBER_REDIRECT; + } + + flags &= !(O_TRUNC as i32); + if r != 0 as libc::c_int { + fd = open(filename, flags | O_EXCL as libc::c_int, mode); + return if fd < 0 as libc::c_int && *__errno_location() == 17 as libc::c_int { + NOCLOBBER_REDIRECT + } else { + fd + }; + } + fd = open(filename, flags, mode); + if fd < 0 as libc::c_int { + return if *__errno_location() == EEXIST as libc::c_int { + NOCLOBBER_REDIRECT + } else { + fd + }; + } + if fstat(fd, &mut finfo2) == 0 as libc::c_int + && (finfo2.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o100000 as libc::c_int as libc::c_uint) as libc::c_int + == 0 as libc::c_int + && r == 0 as libc::c_int + && (finfo.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o100000 as libc::c_int as libc::c_uint) as libc::c_int + == 0 as libc::c_int + && same_file(filename, filename, &mut finfo, &mut finfo2) != 0 + { + return fd; + } + close(fd); + *__errno_location() = EEXIST; + return NOCLOBBER_REDIRECT; + } +} + +fn redir_open( + mut filename: *mut libc::c_char, + mut flags: libc::c_int, + mut mode: libc::c_int, + mut ri: r_instruction, +) -> libc::c_int { + unsafe { + let mut fd: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut e: libc::c_int = 0; + r = find_string_in_alist( + filename, + _redir_special_filenames.as_mut_ptr(), + 1 as libc::c_int, + ); + if r >= 0 as libc::c_int { + return redir_special_open(r, filename, flags, mode, ri as libc::c_uint); + } + if noclobber != 0 && CLOBBERING_REDIRECT!(ri) { + fd = noclobber_open(filename, flags, mode, ri as libc::c_uint); + if fd == NOCLOBBER_REDIRECT { + return NOCLOBBER_REDIRECT; + } + } else { + loop { + fd = open(filename, flags, mode); + e = *__errno_location(); + if fd < 0 as libc::c_int && e == EINTR { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + run_pending_traps(); + } + *__errno_location() = e; + if !(fd < 0 as libc::c_int && *__errno_location() == EINTR) { + break; + } + } + } + return fd; + } +} + +fn do_redirection_internal( + mut redirect: *mut REDIRECT, + mut flags: libc::c_int, + mut fnp: *mut *mut libc::c_char, +) -> libc::c_int { + unsafe { + let mut redirectee: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut redir_fd: libc::c_int = 0; + let mut fd: libc::c_int = 0; + let mut redirector: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut oflags: libc::c_int = 0; + let mut lfd: intmax_t = 0; + let mut redirectee_word: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ri: r_instruction = r_output_direction; + let mut new_redirect: *mut REDIRECT = 0 as *mut REDIRECT; + let mut sd: REDIRECTEE = REDIRECTEE { dest: 0 }; + redirectee = (*redirect).redirectee.filename; + redir_fd = (*redirect).redirectee.dest; + redirector = (*redirect).redirector.dest; + ri = (*redirect).instruction; + if (*redirect).flags & RX_INTERNAL != 0 { + flags |= RX_INTERNAL; + } + if TRANSLATE_REDIRECT!(ri) { + redirectee_word = redirection_expand(redirectee); + if redirectee_word.is_null() { + return AMBIGUOUS_REDIRECT; + } else if *redirectee_word.offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && *redirectee_word.offset(1 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + sd = (*redirect).redirector; + rd.dest = 0 as libc::c_int; + new_redirect = make_redirection(sd, r_close_this, rd, 0 as libc::c_int); + } else if all_digits(redirectee_word) != 0 { + sd = (*redirect).redirector; + if legal_number(redirectee_word, &mut lfd) != 0 + && lfd as libc::c_int as intmax_t == lfd + { + rd.dest = lfd as libc::c_int; + } else { + rd.dest = -(1 as libc::c_int); + } + match ri as libc::c_uint { + r_duplicating_input_word => { + new_redirect = + make_redirection(sd, r_duplicating_input, rd, 0 as libc::c_int); + } + r_duplicating_output_word => { + new_redirect = + make_redirection(sd, r_duplicating_output, rd, 0 as libc::c_int); + } + r_move_input_word => { + new_redirect = make_redirection(sd, r_move_input, rd, 0 as libc::c_int); + } + r_move_output_word => { + new_redirect = make_redirection(sd, r_move_output, rd, 0 as libc::c_int); + } + _ => {} + } + } else if ri as libc::c_uint == r_duplicating_output_word as libc::c_int as libc::c_uint + && (*redirect).rflags & REDIR_VARASSIGN as libc::c_int == 0 as libc::c_int + && redirector == 1 as libc::c_int + { + sd = (*redirect).redirector; + rd.filename = make_bare_word(redirectee_word); + new_redirect = make_redirection(sd, r_err_and_out, rd, 0 as libc::c_int); + } else { + free(redirectee_word as *mut libc::c_void); + return REDIR_VARASSIGN; + } + free(redirectee_word as *mut libc::c_void); + if (*new_redirect).instruction as libc::c_uint + == r_err_and_out as libc::c_int as libc::c_uint + { + let mut alloca_hack: *mut libc::c_char = 0 as *mut libc::c_char; + let mut fresh1 = ::std::vec::from_elem( + 0, + ::core::mem::size_of::() as libc::c_ulong as usize, + ); + redirectee = fresh1.as_mut_ptr() as *mut WORD_DESC; + xbcopy( + (*new_redirect).redirectee.filename as *mut libc::c_char, + redirectee as *mut libc::c_char, + ::core::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + let mut fresh2 = ::std::vec::from_elem( + 0, + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*(*new_redirect).redirectee.filename).word) as u64) + as usize, + ); + alloca_hack = fresh2.as_mut_ptr() as *mut libc::c_char; + (*redirectee).word = alloca_hack; + strcpy( + (*redirectee).word, + (*(*new_redirect).redirectee.filename).word, + ); + } else { + redirectee = (*new_redirect).redirectee.filename; + } + redir_fd = (*new_redirect).redirectee.dest; + redirector = (*new_redirect).redirector.dest; + ri = (*new_redirect).instruction; + (*redirect).flags = (*new_redirect).flags; + dispose_redirects(new_redirect); + } + + let mut _current_block_flag: u64; + match ri as libc::c_uint { + r_output_direction | r_appending_to | r_input_direction | r_inputa_direction + | r_err_and_out | r_append_err_and_out | r_input_output | r_output_force => { + if posixly_correct != 0 && interactive_shell == 0 as libc::c_int { + oflags = (*redirectee).flags; + (*redirectee).flags |= W_NOGLOB!(); + } + redirectee_word = redirection_expand(redirectee); + if posixly_correct != 0 && interactive_shell == 0 as libc::c_int { + (*redirectee).flags = oflags; + } + if redirectee_word.is_null() { + return AMBIGUOUS_REDIRECT; + } + if restricted != 0 && WRITE_REDIRECT!(ri) { + free(redirectee_word as *mut libc::c_void); + return RESTRICTED_REDIRECT; + } + fd = redir_open( + redirectee_word, + (*redirect).flags, + 0o666 as libc::c_int, + ri as libc::c_uint, + ); + if !fnp.is_null() { + *fnp = redirectee_word; + } else { + free(redirectee_word as *mut libc::c_void); + } + if fd == NOCLOBBER_REDIRECT || fd == RESTRICTED_REDIRECT { + return fd; + } + if fd < 0 as libc::c_int { + return *__errno_location(); + } + if flags & (RX_ACTIVE as i32) != 0 { + if (*redirect).rflags & REDIR_VARASSIGN != 0 { + redirector = fcntl(fd, F_DUPFD as i32, SHELL_FD_BASE as libc::c_int); + r = *__errno_location(); + if redirector < 0 as libc::c_int { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"redirection error: cannot duplicate fd\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } + REDIRECTION_ERROR!(redirector, r, fd); + } + if flags & RX_UNDOABLE as i32 != 0 && (*redirect).rflags & REDIR_VARASSIGN == 0 + { + if fd != redirector + && fcntl(redirector, F_GETFD, 0 as libc::c_int) != -(1 as libc::c_int) + { + r = add_undo_redirect(redirector, ri, -(1 as libc::c_int)); + } else { + r = add_undo_close_redirect(redirector); + } + REDIRECTION_ERROR!(r, errno, fd); + } + if redirector != 0 as libc::c_int + || subshell_environment & SUBSHELL_ASYNC as libc::c_int == 0 as libc::c_int + { + check_bash_input(redirector); + } + if redirector == 1 as libc::c_int && fileno(stdout) == redirector { + fflush(stdout); + fpurge(stdout); + } else if redirector == 2 as libc::c_int && fileno(stderr) == redirector { + fflush(stderr); + fpurge(stderr); + } + + if (*redirect).rflags & REDIR_VARASSIGN as libc::c_int != 0 { + r = redir_varassign(redirect, redirector); + if r < 0 as libc::c_int { + close(redirector); + close(fd); + return r; + } + } else if fd != redirector && dup2(fd, redirector) < 0 as libc::c_int { + close(fd); + return *__errno_location(); + } + + if ri as libc::c_uint == r_input_direction as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_input_output as libc::c_int as libc::c_uint + { + duplicate_buffered_stream(fd, redirector); + } + + if flags & RX_CLEXEC as libc::c_int != 0 && redirector > 2 as libc::c_int { + fcntl(redirector, 2 as libc::c_int, 1 as libc::c_int); + } + } + if fd != redirector { + if ri as libc::c_uint == r_input_direction as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_inputa_direction as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_input_output as libc::c_int as libc::c_uint + { + close_buffered_fd(fd); + } else { + close(fd); + } + } + if ri as libc::c_uint == r_err_and_out as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_append_err_and_out as libc::c_int as libc::c_uint + { + if flags & RX_ACTIVE as libc::c_int != 0 { + if flags & RX_UNDOABLE as libc::c_int != 0 { + add_undo_redirect(2 as libc::c_int, ri, -(1 as libc::c_int)); + } + if dup2(1 as libc::c_int, 2 as libc::c_int) < 0 as libc::c_int { + return *__errno_location(); + } + } + } + } + + r_reading_until | r_deblank_reading_until | r_reading_string => { + if !redirectee.is_null() { + fd = here_document_to_fd(redirectee, ri as libc::c_uint); + if fd < 0 as libc::c_int { + heredoc_errno = *__errno_location(); + return HEREDOC_REDIRECT; + } + if (*redirect).rflags & REDIR_VARASSIGN as libc::c_int != 0 { + redirector = fcntl(fd, F_DUPFD as i32, SHELL_FD_BASE); + r = *__errno_location(); + if redirector < 0 as libc::c_int { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"redirection error: cannot duplicate fd\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } + REDIRECTION_ERROR!(r, errno, fd); + } + if flags & RX_ACTIVE as libc::c_int != 0 { + if flags & RX_UNDOABLE as libc::c_int != 0 + && (*redirect).rflags & REDIR_VARASSIGN as libc::c_int + == 0 as libc::c_int + { + if fd != redirector + && fcntl(redirector, F_GETFD, 0 as libc::c_int) + != -(1 as libc::c_int) + { + r = add_undo_redirect(redirector, ri, -(1 as libc::c_int)); + } else { + r = add_undo_close_redirect(redirector); + } + + REDIRECTION_ERROR!(r, errno, fd); + } + + check_bash_input(redirector); + + if (*redirect).rflags & REDIR_VARASSIGN != 0 { + r = redir_varassign(redirect, redirector); + if r < 0 as libc::c_int { + close(redirector); + close(fd); + return r; + } + } else if fd != redirector && dup2(fd, redirector) < 0 as libc::c_int { + r = *__errno_location(); + close(fd); + return r; + } + duplicate_buffered_stream(fd, redirector); + + if flags & RX_CLEXEC != 0 && redirector > 2 as libc::c_int { + fcntl(redirector, 2 as libc::c_int, 1 as libc::c_int); + } + } + if fd != redirector { + close_buffered_fd(fd); + } + } + } + + r_duplicating_input | r_duplicating_output | r_move_input | r_move_output => { + if flags & RX_ACTIVE as i32 != 0 && (*redirect).rflags & REDIR_VARASSIGN != 0 { + redirector = fcntl(redir_fd, 0 as libc::c_int, 10 as libc::c_int); + r = *__errno_location(); + if redirector < 0 as libc::c_int { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"redirection error: cannot duplicate fd\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } + REDIRECTION_ERROR!(redirector, r, -1); + } + if flags & RX_ACTIVE as i32 != 0 && redir_fd != redirector { + if flags & RX_UNDOABLE as i32 != 0 + && (*redirect).rflags & REDIR_VARASSIGN == 0 as libc::c_int + { + if fcntl(redirector, 1 as libc::c_int, 0 as libc::c_int) + != -(1 as libc::c_int) + { + r = add_undo_redirect(redirector, ri, redir_fd); + } else { + r = add_undo_close_redirect(redirector); + } + REDIRECTION_ERROR!(r, errno, -1); + } + if flags & RX_UNDOABLE as i32 != 0 + && (ri as libc::c_uint == r_move_input as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_move_output as libc::c_int as libc::c_uint) + { + if fcntl(redirector, 1 as libc::c_int, 0 as libc::c_int) + != -(1 as libc::c_int) + { + r = add_undo_redirect(redir_fd, r_close_this, -(1 as libc::c_int)); + REDIRECTION_ERROR!(r, errno, -1); + } + } + + if redirector != 0 as libc::c_int + || subshell_environment & SUBSHELL_ASYNC == 0 as libc::c_int + { + check_bash_input(redirector); + } + if (*redirect).rflags & REDIR_VARASSIGN != 0 { + r = redir_varassign(redirect, redirector); + if r < 0 as libc::c_int { + close(redirector); + return r; + } + } else if dup2(redir_fd, redirector) < 0 as libc::c_int { + return *__errno_location(); + } + if ri as libc::c_uint == r_duplicating_input as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_move_input as libc::c_int as libc::c_uint + { + duplicate_buffered_stream(redir_fd, redirector); + } + if (fcntl(redir_fd, F_GETFD, 0 as libc::c_int) == 1 as libc::c_int + || redir_fd < 2 as libc::c_int && flags & RX_INTERNAL as libc::c_int != 0 + || flags & RX_CLEXEC as libc::c_int != 0) + && redirector > 2 as libc::c_int + { + fcntl(redirector, 2 as libc::c_int, 1 as libc::c_int); + } + + if (*redirect).flags & RX_INTERNAL as i32 != 0 + && (*redirect).flags & RX_SAVCLEXEC as i32 != 0 + && redirector >= 3 as libc::c_int + && (redir_fd >= SHELL_FD_BASE as i32 + || (*redirect).flags & RX_SAVEFD as i32 != 0) + { + fcntl(redirector, 2 as libc::c_int, 0 as libc::c_int); + } + if ri as libc::c_uint == r_move_input as libc::c_int as libc::c_uint + || ri as libc::c_uint == r_move_output as libc::c_int as libc::c_uint + { + xtrace_fdchk(redir_fd); + close(redir_fd); + coproc_fdchk(redir_fd); + } + } + } + + r_close_this => { + if flags & RX_ACTIVE as libc::c_int != 0 { + if (*redirect).rflags & REDIR_VARASSIGN as libc::c_int != 0 { + redirector = redir_varvalue(redirect); + if redirector < 0 as libc::c_int { + return AMBIGUOUS_REDIRECT; + } + } + r = 0 as libc::c_int; + if flags & RX_UNDOABLE as i32 != 0 { + if fcntl(redirector, 1 as libc::c_int, 0 as libc::c_int) + != -(1 as libc::c_int) + { + r = add_undo_redirect(redirector, ri, -(1 as libc::c_int)); + } else { + r = add_undo_close_redirect(redirector); + } + REDIRECTION_ERROR!(r, errno, redirector); + } + + coproc_fdchk(redirector); + xtrace_fdchk(redirector); + if redirector != 0 as libc::c_int + || subshell_environment & SUBSHELL_ASYNC == 0 as libc::c_int + { + check_bash_input(redirector); + } + r = close_buffered_fd(redirector); + if r < 0 as libc::c_int + && flags & RX_INTERNAL != 0 + && (*__errno_location() == EIO || *__errno_location() == ENOSPC) + { + REDIRECTION_ERROR!(r, errno, -1); + } + } + } + + r_duplicating_input_word + | r_duplicating_output_word + | r_move_input_word + | r_move_output_word + | _ => {} + } + + return 0 as libc::c_int; + } +} +fn add_undo_redirect( + mut fd: libc::c_int, + mut ri: r_instruction, + mut fdbase: libc::c_int, +) -> libc::c_int { + let mut new_fd: libc::c_int = 0; + let mut clexec_flag: libc::c_int = 0; + let mut savefd_flag: libc::c_int = 0; + let mut new_redirect: *mut REDIRECT = 0 as *mut REDIRECT; + let mut closer: *mut REDIRECT = 0 as *mut REDIRECT; + let mut dummy_redirect: *mut REDIRECT = 0 as *mut REDIRECT; + let mut sd: REDIRECTEE = REDIRECTEE { dest: 0 }; + savefd_flag = 0 as libc::c_int; + unsafe { + new_fd = fcntl( + fd, + F_DUPFD as i32, + if fdbase < SHELL_FD_BASE { + SHELL_FD_BASE + } else { + fdbase + 1 as libc::c_int + }, + ); + if new_fd < 0 as libc::c_int { + new_fd = fcntl(fd, 0 as libc::c_int, 10 as libc::c_int); + } + if new_fd < 0 as libc::c_int { + new_fd = fcntl(fd, 0 as libc::c_int, 0 as libc::c_int); + savefd_flag = 1 as libc::c_int; + } + if new_fd < 0 as libc::c_int { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"redirection error: cannot duplicate fd\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + return -(1 as libc::c_int); + } + clexec_flag = fcntl(fd, 1 as libc::c_int, 0 as libc::c_int); + sd.dest = new_fd; + rd.dest = 0 as libc::c_int; + closer = make_redirection(sd, r_close_this, rd, 0 as libc::c_int); + (*closer).flags |= RX_INTERNAL as libc::c_int; + dummy_redirect = copy_redirects(closer); + + sd.dest = fd; + rd.dest = new_fd; + if fd == 0 as libc::c_int { + new_redirect = make_redirection(sd, r_duplicating_input, rd, 0 as libc::c_int); + } else { + new_redirect = make_redirection(sd, r_duplicating_output, rd, 0 as libc::c_int); + } + (*new_redirect).flags |= RX_INTERNAL; + if savefd_flag != 0 { + (*new_redirect).flags |= 0x40 as libc::c_int; + } + if clexec_flag == 0 as libc::c_int + && fd >= 3 as libc::c_int + && (new_fd >= SHELL_FD_BASE as libc::c_int || savefd_flag != 0) + { + (*new_redirect).flags |= RX_SAVCLEXEC; + } + (*new_redirect).next = closer; + (*closer).next = redirection_undo_list; + redirection_undo_list = new_redirect; + add_exec_redirect(dummy_redirect); + if fd >= SHELL_FD_BASE as libc::c_int + && ri as libc::c_uint != r_close_this as libc::c_int as libc::c_uint + && clexec_flag != 0 + { + sd.dest = fd; + rd.dest = new_fd; + new_redirect = make_redirection(sd, r_duplicating_output, rd, 0 as libc::c_int); + (*new_redirect).flags |= 0x8 as libc::c_int; + add_exec_redirect(new_redirect); + } + if clexec_flag != 0 || fd < 3 as libc::c_int { + fcntl(new_fd, 2 as libc::c_int, 1 as libc::c_int); + } else if (*redirection_undo_list).flags & RX_SAVCLEXEC as libc::c_int != 0 { + fcntl(new_fd, 2 as libc::c_int, 1 as libc::c_int); + } + } + return 0 as libc::c_int; +} +fn add_undo_close_redirect(mut fd: libc::c_int) -> libc::c_int { + let mut closer: *mut REDIRECT = 0 as *mut REDIRECT; + let mut sd: REDIRECTEE = REDIRECTEE { dest: 0 }; + sd.dest = fd; + unsafe { + rd.dest = 0 as libc::c_int; + closer = make_redirection(sd, r_close_this, rd, 0 as libc::c_int); + (*closer).flags |= RX_INTERNAL; + (*closer).next = redirection_undo_list; + redirection_undo_list = closer; + } + return 0 as libc::c_int; +} +fn add_exec_redirect(mut dummy_redirect: *mut REDIRECT) { + unsafe { + (*dummy_redirect).next = exec_redirection_undo_list; + exec_redirection_undo_list = dummy_redirect; + } +} +fn stdin_redirection(mut ri: r_instruction, mut redirector: libc::c_int) -> libc::c_int { + match ri as libc::c_uint { + r_input_direction + | r_inputa_direction + | r_input_output + | r_reading_until + | r_deblank_reading_until + | r_reading_string => return 1 as libc::c_int, + r_duplicating_input | r_duplicating_input_word | r_close_this => { + return (redirector == 0 as libc::c_int) as libc::c_int + } + r_output_direction + | r_appending_to + | r_duplicating_output + | r_err_and_out + | r_append_err_and_out + | r_output_force + | r_duplicating_output_word + | r_move_input + | r_move_output + | r_move_input_word + | r_move_output_word => return 0 as libc::c_int, + _ => {} + } + return 0 as libc::c_int; +} +#[no_mangle] +pub fn stdin_redirects(mut redirs: *mut REDIRECT) -> libc::c_int { + unsafe { + let mut rp: *mut REDIRECT = 0 as *mut REDIRECT; + let mut n: libc::c_int = 0; + n = 0 as libc::c_int; + rp = redirs; + + while !rp.is_null() { + if (*rp).rflags & REDIR_VARASSIGN as libc::c_int == 0 as libc::c_int { + n += stdin_redirection((*rp).instruction as libc::c_uint, (*rp).redirector.dest); + } + rp = (*rp).next; + } + + return n; + } +} +fn redir_varassign(mut redir: *mut REDIRECT, mut fd: libc::c_int) -> libc::c_int { + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + w = (*redir).redirector.filename; + v = bind_var_to_int((*w).word, fd as intmax_t); + if v.is_null() || readonly_p!(v) as libc::c_int != 0 || noassign_p!(v) as libc::c_int != 0 { + return BADVAR_REDIRECT; + } + stupidly_hack_special_variables((*w).word); + } + return 0 as libc::c_int; +} + +fn redir_varvalue(mut redir: *mut REDIRECT) -> libc::c_int { + unsafe { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut w: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vmax: intmax_t = 0; + let mut i: libc::c_int = 0; + let mut sub: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: libc::c_int = 0; + let mut vr: libc::c_int = 0; + w = (*(*redir).redirector.filename).word; + vr = valid_array_reference(w, 0 as libc::c_int); + if vr != 0 { + v = array_variable_part(w, 0 as libc::c_int, &mut sub, &mut len); + } else { + v = find_variable(w); + if v.is_null() { + v = find_variable_last_nameref(w, 0 as libc::c_int); + if !v.is_null() && (*v).attributes & 0x800 as libc::c_int != 0 { + w = (*v).value; + vr = valid_array_reference(w, 0 as libc::c_int); + if vr != 0 { + v = array_variable_part(w, 0 as libc::c_int, &mut sub, &mut len); + } else { + v = find_variable(w); + } + } + } + } + if v.is_null() || invisible_p!(v) as libc::c_int != 0 { + return -(1 as libc::c_int); + } + + if vr != 0 && (array_p!(v) as libc::c_int != 0 || assoc_p!(v) as libc::c_int != 0) { + val = get_array_value( + w, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut arrayind_t, + ); + } else { + val = get_variable_value(v); + } + if val.is_null() || *val as libc::c_int == 0 as libc::c_int { + return -(1 as libc::c_int); + } + if legal_number(val, &mut vmax) < 0 as libc::c_int { + return -(1 as libc::c_int); + } + i = vmax as libc::c_int; + return i; + } +} diff --git a/utshell-0.5.0/src/sig.rs b/utshell-0.5.0/src/sig.rs new file mode 100644 index 00000000..a2f1283a --- /dev/null +++ b/utshell-0.5.0/src/sig.rs @@ -0,0 +1,680 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::bashhist::maybe_save_shell_history; +use crate::bashline::{bashline_reset, bashline_set_event_hook}; +use crate::builtins::evalstring::parse_and_execute_cleanup; +use crate::builtins::read::{read_builtin, read_tty_cleanup}; +use crate::jobs::{ + end_job_control, give_terminal_to, hangup_all_jobs, initialize_job_signals, procsub_clear, +}; +use crate::src_common::*; +use crate::subst::{unlink_all_fifos, unlink_fifo_list}; +use crate::trap::{ + get_original_signal, run_exit_trap, run_interrupt_trap, run_trap_cleanup, + set_signal_hard_ignored, set_trap_state, signal_is_pending, signal_is_special, +}; +use crate::unwind_prot::run_unwind_protects; +use crate::variables::set_pipestatus_from_exit; +use crate::y_tab::reset_parser; + +static mut old_winch: Option = None; +#[no_mangle] +pub fn initialize_signals(mut reinit: libc::c_int) { + initialize_shell_signals(); + initialize_job_signals(); +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct termsig { + pub signum: libc::c_int, + pub orig_handler: Option, + pub orig_flags: libc::c_int, + pub core_dump: libc::c_int, +} + +static mut terminating_signals: [termsig; 17] = { + [ + { + let mut init = termsig { + signum: SIGHUP as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGINT as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGILL as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGTRAP as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGIOT as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGFPE as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGBUS as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGSEGV as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGSYS as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGPIPE as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGALRM as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGTERM as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGXCPU as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGXFSZ as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 1 as libc::c_int, + }; + init + }, + { + let mut init = termsig { + signum: SIGVTALRM as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGUSR1 as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + { + let mut init = termsig { + signum: SIGUSR2 as libc::c_int, + orig_handler: None, + orig_flags: 0 as libc::c_int, + core_dump: 0, + }; + init + }, + ] +}; + +static mut termsigs_initialized: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub fn initialize_terminating_signals() { + unsafe { + let mut i: libc::c_int = 0; + let mut act: crate::src_common::sigaction = crate::src_common::sigaction { + __sigaction_handler: sigaction__bindgen_ty_1 { sa_handler: None }, + sa_mask: __sigset_t { __val: [0; 16] }, + sa_flags: 0, + sa_restorer: None, + }; + let mut oact: crate::src_common::sigaction = crate::src_common::sigaction { + __sigaction_handler: sigaction__bindgen_ty_1 { sa_handler: None }, + sa_mask: __sigset_t { __val: [0; 16] }, + sa_flags: 0, + sa_restorer: None, + }; + + if termsigs_initialized != 0 { + return; + } + act.__sigaction_handler.sa_handler = Some(termsig_sighandler); + act.sa_flags = 0 as libc::c_int; + + sigemptyset(&mut act.sa_mask); + sigemptyset(&mut oact.sa_mask); + + i = 0; + while (i as libc::c_ulong) < TERMSIGS_LENGTH!() { + sigaddset(&mut act.sa_mask, XSIG!(i)); + i += 1; + } + i = 0; + while (i as libc::c_ulong) < TERMSIGS_LENGTH!() { + if !(signal_is_trapped(XSIG!(i)) != 0) { + sigaction(XSIG!(i), &mut act, &mut oact); + // XHANDLER!(i) = Some(oact.__sigaction_handler.sa_handler); + terminating_signals[i as usize].orig_handler = oact.__sigaction_handler.sa_handler; + XSAFLAGS!(i) = oact.sa_flags; + + if interactive_shell == 0 + && terminating_signals[i as usize].orig_handler + == ::std::mem::transmute::>( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigaction(XSIG!(i), &mut oact, &mut act); + set_signal_hard_ignored(XSIG!(i)); + } + if XSIG!(i) == SIGPROF as libc::c_int + && terminating_signals[i as usize].orig_handler.is_some() + && terminating_signals[i as usize].orig_handler + != ::std::mem::transmute::>( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigaction( + XSIG!(i), + &mut oact, + 0 as *mut c_void as *mut crate::src_common::sigaction, + ); + } + } + i += 1; + } + termsigs_initialized = 1; + } +} + +fn initialize_shell_signals() { + unsafe { + if interactive != 0 { + initialize_terminating_signals(); + } + sigemptyset(&mut top_level_mask); + sigprocmask( + SIG_BLOCK as libc::c_int, + 0 as *mut c_void as *mut sigset_t, + &mut top_level_mask, + ); + if sigismember(&mut top_level_mask, SIGCHLD as libc::c_int) != 0 { + sigdelset(&mut top_level_mask, SIGCHLD as libc::c_int); + sigprocmask( + SIG_SETMASK as libc::c_int, + &mut top_level_mask, + 0 as *mut c_void as *mut sigset_t, + ); + } + set_signal_handler( + SIGQUIT as libc::c_int, + ::std::mem::transmute::>( + 1 as libc::c_int as libc::intptr_t, + ), + ); + if interactive != 0 { + set_signal_handler(SIGINT as libc::c_int, Some(sigint_sighandler)); + get_original_signal(SIGTERM as libc::c_int); + set_signal_handler( + SIGTERM as libc::c_int, + ::std::mem::transmute::>( + 1 as libc::c_int as libc::intptr_t, + ), + ); + set_sigwinch_handler(); + } + } +} + +#[no_mangle] +pub fn reset_terminating_signals() { + let mut i: libc::c_int = 0; + let mut act: crate::src_common::sigaction = crate::src_common::sigaction { + __sigaction_handler: sigaction__bindgen_ty_1 { sa_handler: None }, + sa_mask: __sigset_t { __val: [0; 16] }, + sa_flags: 0, + sa_restorer: None, + }; + unsafe { + if termsigs_initialized == 0 { + return; + } + act.sa_flags = 0; + sigemptyset(&mut act.sa_mask); + + i = 0; + while (i as libc::c_ulong) < TERMSIGS_LENGTH!() { + if !(signal_is_trapped(XSIG!(i)) != 0 || signal_is_special(XSIG!(i)) != 0) { + act.__sigaction_handler.sa_handler = terminating_signals[i as usize].orig_handler; + + act.sa_flags = XSAFLAGS!(i); + sigaction( + XSIG!(i), + &mut act, + 0 as *mut c_void as *mut crate::src_common::sigaction, + ); + } + i += 1; + } + termsigs_initialized = 0; + } +} + +#[no_mangle] +pub fn top_level_cleanup() { + unsafe { + while parse_and_execute_level != 0 { + parse_and_execute_cleanup(-(1 as libc::c_int)); + } + unlink_fifo_list(); + run_unwind_protects(); + funcnest = 0 as libc::c_int; + breaking = funcnest; + continuing = breaking; + loop_level = continuing; + wait_intr_flag = 0 as libc::c_int; + return_catch_flag = wait_intr_flag; + comsub_ignore_return = return_catch_flag; + executing_list = comsub_ignore_return; + } +} + +#[no_mangle] +pub fn throw_to_top_level() { + let mut print_newline: libc::c_int = 0 as libc::c_int; + unsafe { + if interrupt_state != 0 { + if last_command_exit_value < 128 as libc::c_int { + last_command_exit_value = 128 + SIGINT as libc::c_int; + } + set_pipestatus_from_exit(last_command_exit_value); + print_newline = 1 as libc::c_int; + interrupt_state -= 1; + } + + if interrupt_state != 0 { + return; + } + + last_command_exit_signal = if last_command_exit_value > 128 as libc::c_int { + last_command_exit_value - 128 as libc::c_int + } else { + 0 as libc::c_int + }; + last_command_exit_value |= 128; + set_pipestatus_from_exit(last_command_exit_value); + + if signal_is_trapped(SIGINT as libc::c_int) != 0 + && signal_is_pending(SIGINT as libc::c_int) != 0 + { + run_interrupt_trap(1 as libc::c_int); + } + + while parse_and_execute_level != 0 { + parse_and_execute_cleanup(-(1 as libc::c_int)); + } + + if running_trap > 0 as libc::c_int { + run_trap_cleanup(running_trap - 1 as libc::c_int); + running_trap = 0 as libc::c_int; + } + + give_terminal_to(shell_pgrp, 0 as libc::c_int); + + restore_sigmask(); + reset_parser(); + + if interactive != 0 { + bashline_reset(); + } + + unlink_fifo_list(); + + run_unwind_protects(); + funcnest = 0 as libc::c_int; + breaking = funcnest; + continuing = breaking; + loop_level = continuing; + + wait_intr_flag = 0 as libc::c_int; + return_catch_flag = wait_intr_flag; + comsub_ignore_return = return_catch_flag; + executing_list = comsub_ignore_return; + + if interactive != 0 && print_newline != 0 { + fflush(stdout); + fprintf(stderr, b"\n\0" as *const u8 as *const libc::c_char); + fflush(stderr); + } + + if interactive != 0 + || interactive_shell != 0 && shell_initialized == 0 + || print_newline != 0 && signal_is_trapped(SIGINT as libc::c_int) != 0 + { + jump_to_top_level(DISCARD as libc::c_int); + } else { + jump_to_top_level(EXITPROG as libc::c_int); + }; + } +} + +#[no_mangle] +pub fn jump_to_top_level(mut value: libc::c_int) { + unsafe { + siglongjmp(top_level.as_mut_ptr(), value); + } +} + +#[no_mangle] +pub fn restore_sigmask() { + unsafe { + sigprocmask( + SIG_SETMASK as libc::c_int, + &mut top_level_mask, + 0 as *mut c_void as *mut sigset_t, + ); + } +} + +#[no_mangle] +pub fn termsig_sighandler(mut sig: libc::c_int) { + unsafe { + if sig != SIGHUP as libc::c_int + && sig != SIGINT as libc::c_int + && sig != SIGPIPE as libc::c_int + && sig != SIGALRM as libc::c_int + && sig != SIGTERM as libc::c_int + && sig != SIGXCPU as libc::c_int + && sig != SIGXFSZ as libc::c_int + && sig != SIGVTALRM as libc::c_int + && sig != SIGUSR1 as libc::c_int + && sig != SIGUSR2 as libc::c_int + && sig == terminating_signal + { + terminate_immediately = 1 as libc::c_int; + } + + terminating_signal = sig; + + if terminate_immediately != 0 { + if interactive_shell == 0 + || interactive == 0 + || sig != SIGHUP as libc::c_int && sig != SIGTERM as libc::c_int + || no_line_editing != 0 + || RL_ISSTATE!(RL_STATE_READCMD!()) == 0 + { + history_lines_this_session = 0 as libc::c_int; + } + terminate_immediately = 0 as libc::c_int; + termsig_handler(sig); + } + if RL_ISSTATE!(RL_STATE_SIGHANDLER!()) != 0 || RL_ISSTATE!(RL_STATE_TERMPREPPED!()) != 0 { + bashline_set_event_hook(); + } + } +} + +#[no_mangle] +pub fn termsig_handler(mut sig: libc::c_int) { + static mut handling_termsig: libc::c_int = 0 as libc::c_int; + let mut i: libc::c_int = 0; + let mut core: libc::c_int = 0; + let mut mask: sigset_t = __sigset_t { __val: [0; 16] }; + unsafe { + if handling_termsig != 0 { + return; + } + handling_termsig = 1; + terminating_signal = 0; + + if sig == SIGINT as libc::c_int && signal_is_trapped(SIGINT as libc::c_int) != 0 { + run_interrupt_trap(0 as libc::c_int); + } + if interactive_shell != 0 + && interactive != 0 + && (sig == SIGHUP as libc::c_int || sig == SIGTERM as libc::c_int) + && remember_on_history != 0 + { + maybe_save_shell_history(); + } + if this_shell_builtin == Some(read_builtin) { + read_tty_cleanup(); + } + if sig == SIGHUP as libc::c_int + && (interactive != 0 + || subshell_environment + & (SUBSHELL_COMSUB as libc::c_int | SUBSHELL_PROCSUB as libc::c_int) + != 0) + { + hangup_all_jobs(); + } + if subshell_environment & (SUBSHELL_COMSUB as libc::c_int | SUBSHELL_PROCSUB as libc::c_int) + == 0 + { + end_job_control(); + } + unlink_all_fifos(); + procsub_clear(); + + funcnest = 0 as libc::c_int; + breaking = funcnest; + continuing = breaking; + loop_level = continuing; + + wait_intr_flag = 0 as libc::c_int; + return_catch_flag = wait_intr_flag; + comsub_ignore_return = return_catch_flag; + executing_list = comsub_ignore_return; + + run_exit_trap(); + + restore_sigmask(); + + set_signal_handler(sig, None); + + kill(getpid(), sig); + + if dollar_dollar_pid != 1 as libc::c_int { + exit(128 as libc::c_int + sig); + } + sigprocmask( + SIG_SETMASK as libc::c_int, + 0 as *mut c_void as *mut sigset_t, + &mut mask, + ); + core = 0 as libc::c_int; + i = core; + while (i as libc::c_ulong) < TERMSIGS_LENGTH!() { + set_signal_handler(XSIG!(i), None); + sigdelset(&mut mask, XSIG!(i)); + if sig == XSIG!(i) { + core = XCOREDUMP!(i); + } + i += 1; + } + sigprocmask( + SIG_SETMASK as libc::c_int, + &mut mask, + 0 as *mut c_void as *mut sigset_t, + ); + if core != 0 { + ::std::ptr::write_volatile( + 0 as *mut c_void as *mut libc::c_ulong, + (0xdead0000 as libc::c_uint).wrapping_add(sig as libc::c_uint) as libc::c_ulong, + ); + } + exit(128 as libc::c_int + sig); + } +} + +#[no_mangle] +pub fn sigint_sighandler(mut sig: libc::c_int) { + unsafe { + if interrupt_state == 0 as libc::c_int { + interrupt_state += 1; + } + if wait_intr_flag != 0 { + last_command_exit_value = 128 + sig; + set_pipestatus_from_exit(last_command_exit_value); + wait_signal_received = sig; + return; + } + + if signal_is_trapped(sig) != 0 { + set_trap_state(sig); + } + if interrupt_immediately != 0 { + interrupt_immediately = 0 as libc::c_int; + set_exit_status(128 as libc::c_int + sig); + throw_to_top_level(); + } else if rl_readline_state & 0x8000 as libc::c_int as libc::c_ulong != 0 { + bashline_set_event_hook(); + } + } +} + +#[no_mangle] +pub fn sigwinch_sighandler(mut sig: libc::c_int) { + unsafe { + sigwinch_received = 1; + } +} + +#[no_mangle] +pub fn set_sigwinch_handler() { + unsafe { + old_winch = set_signal_handler(SIGWINCH as libc::c_int, old_winch); + } +} + +#[no_mangle] +pub fn unset_sigwinch_handler() { + unsafe { + set_signal_handler(SIGWINCH as libc::c_int, old_winch); + } +} + +#[no_mangle] +pub fn sigterm_sighandler(mut sig: libc::c_int) { + unsafe { + sigterm_received = 1; + } +} + +#[no_mangle] +pub fn set_signal_handler( + mut sig: libc::c_int, + mut handler: Option, +) -> Option { + unsafe { + let mut act: crate::src_common::sigaction = crate::src_common::sigaction { + __sigaction_handler: sigaction__bindgen_ty_1 { sa_handler: None }, + sa_mask: __sigset_t { __val: [0; 16] }, + sa_flags: 0, + sa_restorer: None, + }; + let mut oact: crate::src_common::sigaction = crate::src_common::sigaction { + __sigaction_handler: sigaction__bindgen_ty_1 { sa_handler: None }, + sa_mask: __sigset_t { __val: [0; 16] }, + sa_flags: 0, + sa_restorer: None, + }; + + act.__sigaction_handler.sa_handler = handler; + + act.sa_flags = 0; + + if sig == SIGCHLD as libc::c_int { + act.sa_flags |= SA_RESTART as libc::c_int; + } + if sig == SIGWINCH as libc::c_int { + act.sa_flags |= SA_RESTART as libc::c_int; + } + if sig == SIGTERM as libc::c_int && handler == Some(sigterm_sighandler) { + act.sa_flags |= SA_RESTART as libc::c_int; + } + sigemptyset(&mut act.sa_mask); + sigemptyset(&mut oact.sa_mask); + if sigaction(sig, &mut act, &mut oact) == 0 as libc::c_int { + return oact.__sigaction_handler.sa_handler; + } else { + return None; + }; + } +} diff --git a/utshell-0.5.0/src/src_common.rs b/utshell-0.5.0/src/src_common.rs new file mode 100644 index 00000000..1f37d60f --- /dev/null +++ b/utshell-0.5.0/src/src_common.rs @@ -0,0 +1,11566 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +pub use libc::*; + +pub use crate::array::array_dispose_element; +pub use crate::array::array_rshift; +pub use crate::array::array_shift; +pub use crate::builtins::help::builtin_help; +pub use crate::builtins::read::sigalrm_seen; +pub use crate::general::file_isdir; +pub use crate::general::legal_number; +pub use crate::general::make_absolute; +pub use crate::general::same_file; +pub use crate::hashlib::hash_create; +pub use crate::jobs::describe_pid; +pub use crate::jobs::reap_dead_jobs; +pub use crate::jobs::stop_pipeline; +pub use crate::jobs::wait_for; +pub use crate::list::list_reverse; +pub use crate::pcomplete::prog_completion_enabled; +pub use crate::readline::environ; +pub use crate::readline::mbstowcs; +pub use crate::readline::rl_readline_state; +pub use crate::sig::termsig_handler; +pub use crate::sig::throw_to_top_level; +pub use crate::stringlib::xbcopy; +pub use crate::trap::signal_is_ignored; +pub use crate::trap::signal_is_trapped; +pub use crate::variables::find_variable; +pub use fluent_bundle::FluentArgs; +pub use fluent_resmgr::resource_manager::ResourceManager; +pub use nix::errno::errno; +pub use nix::sys::signal::SigSet; +pub use std::env::var; +pub use std::ffi::*; +pub use std::fs::File; +pub use std::io::{Stdout, Write}; //去掉了stdout +pub use std::mem::{size_of, transmute}; +pub use std::ops::Add; +pub use std::os::linux::fs::MetadataExt; +pub use std::path::Path; +pub use std::ptr::{null_mut, read_volatile}; +pub use unic_langid::LanguageIdentifier; + +/* +#[link(name = "glob", kind = "static")] +#[link(name = "test", kind = "static")] +#[link(name = "tilde", kind = "static")] +#[link(name = "readline", kind = "static")] +#[link(name = "sh", kind = "static")] +#[link(name = "termcap", kind = "static")] +#[link(name = "test", kind = "static")] +*/ +extern "C" { + pub static mut rl_completion_entry_function: Option; + pub static mut rl_ignore_some_completions_function: Option; + pub static mut rl_filename_quoting_desired: libc::c_int; + pub static mut rl_filename_quoting_function: Option; + pub static mut rl_attempted_completion_function: Option; + pub static mut stdout: *mut libc::FILE; + pub static mut stderr: *mut libc::FILE; + pub static mut rl_instream: *mut libc::FILE; + pub static mut rl_outstream: *mut libc::FILE; + pub static is_basic_table: [libc::c_uint; 0]; + pub static mut history_expansion_char: libc::c_char; + pub static mut history_quoting_state: libc::c_int; + pub static mut history_quotes_inhibit_expansion: libc::c_int; + pub static mut history_search_delimiter_chars: *mut libc::c_char; + pub static mut history_inhibit_expansion_function: Option; + pub static mut history_lines_read_from_file: libc::c_int; + pub static mut history_base: libc::c_int; + pub static mut history_length: libc::c_int; + pub static mut history_lines_written_to_file: libc::c_int; + pub static mut history_subst_char: libc::c_char; + pub static mut rl_dispatching: libc::c_int; + pub static mut rl_done: libc::c_int; + pub static mut history_max_entries: libc::c_int; + pub static mut rl_num_chars_to_read: libc::c_int; + pub static mut rl_startup_hook: Option; + #[link_name = "\u{1}num_shell_builtins"] + pub static mut num_shell_builtins: ::std::os::raw::c_int; + pub static mut glob_ignore_case: libc::c_int; + #[link_name = "\u{1}shell_builtins"] + pub static mut shell_builtins: *mut builtin; + #[link_name = "\u{1}glob_error_return"] + pub static mut glob_error_return: *mut ::std::os::raw::c_char; + pub static mut glob_asciirange: i32; + #[link_name = "\u{1}sourcelevel"] + pub static mut sourcelevel: ::std::os::raw::c_int; + pub static mut tilde_expansion_preexpansion_hook: Option; + pub static mut sh_syntaxtab: [libc::c_int; 0]; + pub static mut sh_syntabsiz: libc::c_int; + pub static mut gnu_error_format: libc::c_int; + #[link_name = "\u{1}stdin"] + pub static mut stdin: *mut FILE; + + pub fn strlen(_: *const libc::c_char) -> libc::c_ulong; + pub fn getrusage(__who: __rusage_who_t, __usage: *mut rusage) -> ::std::os::raw::c_int; + pub fn gettimeofday(__tv: *mut timeval, __tz: __timezone_ptr_t) -> libc::c_int; + pub fn sigemptyset(__set: *mut sigset_t) -> libc::c_int; + pub fn sigaddset(__set: *mut sigset_t, __signo: libc::c_int) -> libc::c_int; + pub fn sigprocmask( + __how: libc::c_int, + __set: *const sigset_t, + __oset: *mut sigset_t, + ) -> libc::c_int; + pub fn sigaction( + __sig: libc::c_int, + __act: *const sigaction, + __oact: *mut sigaction, + ) -> libc::c_int; + pub fn sigismember(__set: *const sigset_t, __signo: libc::c_int) -> libc::c_int; + pub fn sigdelset(__set: *mut sigset_t, __signo: libc::c_int) -> libc::c_int; + pub fn xfree(_: *mut libc::c_void); + fn clearerr(__stream: *mut FILE); + pub fn strlist_resize(_: *mut STRINGLIST, _: libc::c_int) -> *mut STRINGLIST; + pub fn strlist_dispose(_: *mut STRINGLIST); + pub fn strlist_append(_: *mut STRINGLIST, _: *mut STRINGLIST) -> *mut STRINGLIST; + pub fn netopen(_: *mut libc::c_char) -> libc::c_int; + pub fn sh_mktmpfd( + _: *mut libc::c_char, + _: libc::c_int, + _: *mut *mut libc::c_char, + ) -> libc::c_int; + pub fn mbstrlen(_: *const libc::c_char) -> size_t; + pub fn dcgettext( + __domainname: *const libc::c_char, + __msgid: *const libc::c_char, + __category: i32, + ) -> *mut libc::c_char; + pub fn builtin_error(format: *const libc::c_char, ...); + pub fn builtin_warning(format: *const libc::c_char, ...); + pub fn sh_single_quote(_: *const libc::c_char) -> *mut libc::c_char; + pub fn sh_double_quote(string: *const libc::c_char) -> *mut libc::c_char; + pub fn sh_contains_shell_metas(_: *const libc::c_char) -> libc::c_int; + pub fn qsort( + __base: *mut libc::c_void, + __nmemb: libc::size_t, + __size: libc::size_t, + __compar: __compar_fn_t, + ); + pub fn strvec_len(arg1: *mut *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn mbschr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; + pub fn __ctype_b_loc() -> *mut *const libc::c_ushort; + pub fn fmtulong( + _: libc::c_ulong, + _: libc::c_int, + _: *mut libc::c_char, + _: size_t, + _: libc::c_int, + ) -> *mut libc::c_char; + pub fn match_pattern_wchar(_: *mut wchar_t, _: *mut wchar_t, _: libc::c_int) -> libc::c_int; + pub fn wmatchlen(_: *mut wchar_t, _: size_t) -> libc::c_int; + pub fn sh_stat(_: *const libc::c_char, _: *mut stat) -> libc::c_int; + pub fn sh_quote_reusable(_: *mut libc::c_char, _: libc::c_int) -> *mut libc::c_char; + pub fn strvec_to_word_list( + _: *mut *mut libc::c_char, + _: libc::c_int, + _: libc::c_int, + ) -> *mut WORD_LIST; + pub fn get_host_type() -> *mut libc::c_char; + pub fn get_os_type() -> *mut libc::c_char; + pub fn get_mach_type() -> *mut libc::c_char; + pub fn strvec_flush(_: *mut *mut libc::c_char); + pub fn sbrand(_: libc::c_ulong); + pub fn brand() -> libc::c_int; + pub fn get_urandom32() -> libc::c_uint; + pub fn parser_error(_: libc::c_int, _: *const libc::c_char, _: ...); + pub fn parse_and_execute( + _: *mut libc::c_char, + _: *const libc::c_char, + _: libc::c_int, + ) -> libc::c_int; + pub fn readline(p: *const libc::c_char) -> *mut libc::c_char; + pub fn exit_shell(_: libc::c_int) -> !; + pub fn ansiexpand( + _: *mut libc::c_char, + _: libc::c_int, + _: libc::c_int, + _: *mut libc::c_int, + ) -> *mut libc::c_char; + pub fn sh_mkdoublequoted( + _: *const libc::c_char, + _: libc::c_int, + _: libc::c_int, + ) -> *mut libc::c_char; + pub fn sh_backslash_quote_for_double_quotes(_: *mut libc::c_char) -> *mut libc::c_char; + pub fn get_current_user_info(); + pub fn utf8_mblen(_: *const libc::c_char, _: size_t) -> libc::c_int; + pub fn seedrand(); + pub fn seedrand32(); + pub fn wcsmatch(_: *mut wchar_t, _: *mut wchar_t, _: libc::c_int) -> libc::c_int; + pub fn umatchlen(_: *mut libc::c_char, _: size_t) -> libc::c_int; + pub fn match_pattern_char( + _: *mut libc::c_char, + _: *mut libc::c_char, + _: libc::c_int, + ) -> libc::c_int; + pub fn mbsmbchar(_: *const libc::c_char) -> *mut libc::c_char; + pub fn xdupmbstowcs( + _: *mut *mut wchar_t, + _: *mut *mut *mut libc::c_char, + _: *const libc::c_char, + ) -> size_t; + pub fn rl_set_keymap(map: Keymap); + pub fn rl_named_function(string: *const libc::c_char) -> *mut rl_command_func_t; + pub fn rl_invoking_keyseqs(function: *mut rl_command_func_t) -> *mut *mut libc::c_char; + pub fn rl_unbind_function_in_map(func: *mut rl_command_func_t, map: Keymap) -> i32; + pub fn rl_get_keymap() -> Keymap; + pub fn rl_bind_keyseq(keyseq: *const libc::c_char, function: *mut rl_command_func_t) -> i32; + pub fn rl_function_of_keyseq_len( + keyseq: *const libc::c_char, + len: size_t, + map: Keymap, + Type: *mut i32, + ) -> Option; + pub fn rl_translate_keyseq( + seq: *const libc::c_char, + array: *mut libc::c_char, + len: *mut i32, + ) -> i32; + pub fn rl_get_keymap_by_name(name: *const libc::c_char) -> Keymap; + pub fn rl_list_funmap_names(); + pub fn rl_function_dumper(print_readably: i32); + pub fn rl_macro_dumper(print_readably: i32); + pub fn rl_variable_dumper(print_readably: i32); + pub fn rl_read_init_file(filename: *const libc::c_char) -> i32; + pub fn rl_parse_and_bind(string: *mut libc::c_char) -> i32; + pub fn strvec_search(array: *mut *mut libc::c_char, name: *mut libc::c_char) -> i32; + pub fn strvec_dispose(array: *mut *mut libc::c_char); + pub fn sh_modcase( + _: *const libc::c_char, + _: *mut libc::c_char, + _: libc::c_int, + ) -> *mut libc::c_char; + pub fn itos(_: intmax_t) -> *mut libc::c_char; + pub fn strvec_create(_: libc::c_int) -> *mut *mut libc::c_char; + pub fn inttostr(_: intmax_t, _: *mut libc::c_char, _: size_t) -> *mut libc::c_char; + pub fn ansic_shouldquote(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn ansic_quote( + arg1: *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; + pub fn err_readonly(_: *const libc::c_char); + pub fn valid_nameref_value(_: *const libc::c_char, _: libc::c_int) -> libc::c_int; + pub fn report_error(_: *const libc::c_char, _: ...); + pub fn internal_warning(_: *const libc::c_char, _: ...); + pub fn set_exit_status(_: libc::c_int); + pub fn read_history(_: *const libc::c_char) -> libc::c_int; + pub fn using_history(); + pub fn clear_history(); + pub fn remove_history(_: libc::c_int) -> *mut HIST_ENTRY; + pub fn free_history_entry(_: *mut HIST_ENTRY) -> histdata_t; + pub fn remove_history_range(_: libc::c_int, _: libc::c_int) -> *mut *mut HIST_ENTRY; + pub fn history_list() -> *mut *mut HIST_ENTRY; + pub fn history_get(_: libc::c_int) -> *mut HIST_ENTRY; + pub fn where_history() -> libc::c_int; + pub fn history_set_pos(_: libc::c_int) -> libc::c_int; + pub fn append_history(_: libc::c_int, _: *const libc::c_char) -> libc::c_int; + pub fn __errno_location() -> *mut libc::c_int; + pub fn write_history(_: *const libc::c_char) -> libc::c_int; + pub fn history_expand(_: *mut libc::c_char, _: *mut *mut libc::c_char) -> libc::c_int; + pub fn previous_history() -> *mut HIST_ENTRY; + pub fn replace_history_entry( + _: libc::c_int, + _: *const libc::c_char, + _: histdata_t, + ) -> *mut HIST_ENTRY; + pub fn history_is_stifled() -> libc::c_int; + pub fn add_history(_: *const libc::c_char); + pub fn strmatch(_: *mut libc::c_char, _: *mut libc::c_char, _: libc::c_int) -> libc::c_int; + pub fn internal_error(arg1: *const ::std::os::raw::c_char, ...); + pub fn sh_physpath(path: *mut libc::c_char, flags: i32) -> *mut libc::c_char; + pub fn sh_makepath( + path: *const libc::c_char, + dir: *const libc::c_char, + flags: i32, + ) -> *mut libc::c_char; + pub fn dirspell(dirname: *mut libc::c_char) -> *mut libc::c_char; + pub fn sh_canonpath(path: *mut libc::c_char, flags: i32) -> *mut libc::c_char; + pub fn fpurge(stream: *mut FILE) -> i32; + pub fn strvec_from_word_list( + list: *mut WordList, + alloc: i32, + starting_index: i32, + ip: *mut i32, + ) -> *mut *mut libc::c_char; + pub fn ansicstr( + string: *mut libc::c_char, + len: i32, + flags: i32, + sawc: *mut libc::c_int, + rlen: *mut libc::c_int, + ) -> *mut libc::c_char; + pub fn __fxstat( + __ver: libc::c_int, + __fildes: libc::c_int, + __stat_buf: *mut stat, + ) -> libc::c_int; + pub fn zmapfd(_: libc::c_int, _: *mut *mut libc::c_char, _: *mut libc::c_char) -> libc::c_int; + pub fn uconvert( + s: *mut libc::c_char, + ip: *mut libc::c_long, + up: *mut libc::c_long, + ep: *mut *mut libc::c_char, + ) -> libc::c_int; + pub fn input_avail(arg1: libc::c_int) -> libc::c_int; + pub fn rl_insert_text(p: *const libc::c_char) -> libc::c_int; + pub fn zreadintr(arg1: libc::c_int, arg2: *mut libc::c_char, arg3: size_t) -> libc::ssize_t; + pub fn zreadcintr(arg1: libc::c_int, arg2: *mut libc::c_char) -> libc::ssize_t; + pub fn zread(_: libc::c_int, _: *mut libc::c_char, _: size_t) -> ssize_t; + pub fn zreadn(arg1: libc::c_int, arg2: *mut libc::c_char, arg3: size_t) -> libc::ssize_t; + pub fn zreadc(arg1: libc::c_int, arg2: *mut libc::c_char) -> libc::ssize_t; + pub fn zsyncfd(fd: libc::c_int) -> libc::c_void; + pub fn zreset(); + pub fn zgetline( + arg1: ::std::os::raw::c_int, + arg2: *mut *mut ::std::os::raw::c_char, + arg3: *mut usize, + arg4: ::std::os::raw::c_int, + arg5: ::std::os::raw::c_int, + ) -> isize; + pub fn falarm(arg1: libc::c_uint, arg2: libc::c_uint) -> libc::c_uint; + pub fn ttgetattr(arg1: libc::c_int, arg2: *mut libc::termios) -> libc::c_int; + pub fn ttsetattr(arg1: libc::c_int, arg2: *mut libc::termios) -> libc::c_int; + pub fn ttfd_noecho(arg1: libc::c_int, arg2: *mut libc::termios) -> libc::c_int; + pub fn ttfd_cbreak(fd: libc::c_int, ttp: *mut libc::termios) -> libc::c_int; + pub fn ttfd_onechar(fd: libc::c_int, ttp: *mut libc::termios) -> libc::c_int; + pub fn programmable_completions( + arg1: *const ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + arg4: ::std::os::raw::c_int, + arg5: *mut ::std::os::raw::c_int, + ) -> *mut *mut ::std::os::raw::c_char; + pub fn pcomp_set_readline_variables(arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int); + pub fn fnx_fromfs( + arg1: *mut ::std::os::raw::c_char, + arg2: size_t, + ) -> *mut ::std::os::raw::c_char; + pub fn strvec_strcmp( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; + pub fn glob_pattern_p(_: *const libc::c_char) -> libc::c_int; + pub fn strvec_resize( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut *mut ::std::os::raw::c_char; + // pub fn read_builtin(_: *mut WordList) -> libc::c_int; + pub fn sh_backslash_quote( + arg1: *mut ::std::os::raw::c_char, + arg2: *const ::std::os::raw::c_char, + arg3: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; + pub fn zcatfd(_: libc::c_int, _: libc::c_int, _: *mut libc::c_char) -> libc::c_int; + pub fn sh_mktmpfp( + nameroot: *mut libc::c_char, + flags: i32, + namep: &mut *mut libc::c_char, + ) -> *mut libc::FILE; + pub fn __strtol_internal( + __nptr: *const libc::c_char, + __endptr: *mut *mut libc::c_char, + __base: libc::c_int, + __group: libc::c_int, + ) -> libc::c_long; + pub fn strvec_mresize( + arg1: *mut *mut ::std::os::raw::c_char, + arg2: ::std::os::raw::c_int, + ) -> *mut *mut ::std::os::raw::c_char; + pub fn asprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; + pub fn strvec_mcreate(arg1: ::std::os::raw::c_int) -> *mut *mut ::std::os::raw::c_char; + pub fn programming_error(arg1: *const ::std::os::raw::c_char, ...); + pub fn __xstat( + __ver: libc::c_int, + __filename: *const libc::c_char, + __stat_buf: *mut stat, + ) -> libc::c_int; + pub fn sh_eaccess(_: *const libc::c_char, _: libc::c_int) -> libc::c_int; + pub fn getmaxchild() -> i64; + pub fn make_command_string(arg1: *mut COMMAND) -> *mut ::std::os::raw::c_char; + pub fn siglongjmp(_: *mut __jmp_buf_tag, _: libc::c_int) -> !; + pub fn sys_error(arg1: *const ::std::os::raw::c_char, ...); + pub fn sh_exit(arg1: ::std::os::raw::c_int); + pub fn optimize_fork(arg1: *mut COMMAND); + pub fn wcswidth(__s: *const wchar_t, __n: usize) -> ::std::os::raw::c_int; + pub fn putc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; + pub fn subshell_exit(arg1: ::std::os::raw::c_int); + // pub fn command_builtin(_: *mut WordList) -> libc::c_int; + // pub fn eval_builtin(_: *mut WordList) -> libc::c_int; + // pub fn source_builtin(_: *mut WordList) -> libc::c_int; + pub fn sh_regmatch( + a: *const libc::c_char, + b: *const libc::c_char, + c: libc::c_int, + ) -> libc::c_int; + // pub fn mapfile_builtin(_: *mut WordList) -> libc::c_int; + // pub fn fc_builtin(_: *mut WordList) -> libc::c_int; + // pub fn return_builtin(_: *mut WordList) -> libc::c_int; + pub fn sh_getopt_restore_istate(arg1: *mut sh_getopt_state_t); + pub fn optimize_shell_function(arg1: *mut COMMAND); + pub fn sh_getopt_save_istate() -> *mut sh_getopt_state_t; + // pub fn jobs_builtin(_: *mut WordList) -> libc::c_int; + // pub fn exec_builtin(_: *mut WordList) -> libc::c_int; + pub fn unset_bash_input(arg1: ::std::os::raw::c_int); + pub fn unbind_args(); + pub fn bind_function_def( + arg1: *const ::std::os::raw::c_char, + arg2: *mut FUNCTION_DEF, + arg3: ::std::os::raw::c_int, + ); + pub fn bind_function(arg1: *const ::std::os::raw::c_char, arg2: *mut COMMAND) + -> *mut SHELL_VAR; + pub fn difftimeval(_: *mut timeval, _: *mut timeval, _: *mut timeval) -> *mut timeval; + pub fn timeval_to_secs(tvp: *mut timeval, sp: *mut time_t, sfp: *mut libc::c_int); + pub fn addtimeval(_: *mut timeval, _: *mut timeval, _: *mut timeval) -> *mut timeval; + pub fn timeval_to_cpu(_: *mut timeval, _: *mut timeval, _: *mut timeval) -> libc::c_int; + pub fn fmtumax( + arg1: uintmax_t, + arg2: ::std::os::raw::c_int, + arg3: *mut ::std::os::raw::c_char, + arg4: usize, + arg5: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; + pub fn imaxdiv(__numer: intmax_t, __denom: intmax_t) -> imaxdiv_t; + pub fn get_new_window_size(_: libc::c_int, _: *mut libc::c_int, _: *mut libc::c_int); + pub fn getmaxgroups() -> libc::c_int; + pub fn textdomain(__domainname: *const libc::c_char) -> *mut libc::c_char; + pub fn bindtextdomain( + __domainname: *const libc::c_char, + __dirname: *const libc::c_char, + ) -> *mut libc::c_char; + pub fn __ctype_get_mb_cur_max() -> libc::size_t; + pub fn get_string_value(_: *const libc::c_char) -> *mut libc::c_char; + pub fn u32reset(); + pub fn mailstat(_: *const libc::c_char, _: *mut stat) -> libc::c_int; + pub fn isnetconn(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; + pub fn sh_setlinebuf(_: *mut FILE) -> libc::c_int; + pub fn strlist_create(arg1: ::std::os::raw::c_int) -> *mut STRINGLIST; + pub fn strlist_prefix_suffix( + arg1: *mut STRINGLIST, + arg2: *mut ::std::os::raw::c_char, + arg3: *mut ::std::os::raw::c_char, + ) -> *mut STRINGLIST; + pub fn sh_contains_quotes(arg1: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; + pub fn rl_complete_internal(_: libc::c_int) -> libc::c_int; + pub fn rl_filename_completion_function( + _: *const libc::c_char, + _: libc::c_int, + ) -> *mut libc::c_char; + pub fn set_signal_handler(arg1: libc::c_int, arg2: *mut SigHandler) -> *mut SigHandler; + pub fn rl_complete(_: libc::c_int, _: libc::c_int) -> libc::c_int; + pub fn __mbrlen(__s: *const libc::c_char, __n: size_t, __ps: *mut mbstate_t) -> size_t; + pub fn mbrtowc( + __pwc: *mut wchar_t, + __s: *const libc::c_char, + __n: size_t, + __p: *mut mbstate_t, + ) -> size_t; + pub fn __sigsetjmp( + __env: *mut __jmp_buf_tag, + __savemask: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; + pub fn mblen(s: *const libc::c_char, n: size_t) -> libc::c_int; +} + +#[no_mangle] +pub fn sh_xfree(arg: *mut libc::c_void, unval1: *const libc::c_char, unval2: libc::c_int) { + unsafe { + free(arg as *mut libc::c_void); + } +} +#[no_mangle] +pub fn sh_xmalloc( + arg: libc::c_ulong, + unval1: *const libc::c_char, + unval2: libc::c_int, +) -> *mut libc::c_void { + unsafe { malloc(arg as usize) } +} +#[no_mangle] +pub fn sh_xrealloc( + arg: *mut libc::c_void, + unval1: libc::c_ulong, + unval2: *const libc::c_char, + unval3: libc::c_int, +) -> *mut libc::c_void { + // realloc(arg as *mut libc::c_void,unval1:libc::c_ulong) + unsafe { realloc(arg as *mut libc::c_void, unval1 as libc::size_t) } +} + +pub static mut parse_and_execute_level: libc::c_int = 0 as libc::c_int; + +pub static mut expand_word_fatal: WORD_LIST = WORD_LIST { + next: 0 as *const word_list as *mut word_list, + word: 0 as *const WORD_DESC as *mut WORD_DESC, +}; +pub static mut expand_wdesc_error: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, +}; +pub static mut expand_wdesc_fatal: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, +}; + +pub static mut expand_word_error: WORD_LIST = WORD_LIST { + next: 0 as *const word_list as *mut word_list, + word: 0 as *const WORD_DESC as *mut WORD_DESC, +}; + +#[no_mangle] +pub static mut no_exit_on_failed_exec: libc::c_int = 0; +#[no_mangle] +pub unsafe fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + return *a == *b && libc::strcmp(a, b) == 0; +} + +#[no_mangle] +pub static mut primary_prompt: *mut libc::c_char = + b"\\s-\\v\\$ \0" as *const u8 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut secondary_prompt: *mut libc::c_char = + b"> \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + +pub static mut original_signals: [Option; 65] = [None; 65]; +pub const CHAR_BIT: libc::c_int = 8 as libc::c_int; + +/* Used by some builtins and the mainline code. */ +pub static mut last_shell_builtin: Option = None; +pub static mut this_shell_builtin: Option = None; + +#[macro_export] +macro_rules! GETOPT_HELP { + () => { + -99 + }; +} + +//break_1.rs +/* The depth of while's and until's. */ +#[no_mangle] +pub static mut loop_level: libc::c_int = 0 as libc::c_int; +/* Non-zero when a "break" instruction is encountered. */ +#[no_mangle] +pub static mut breaking: libc::c_int = 0 as libc::c_int; +/* Non-zero when we have encountered a continue instruction. */ +#[no_mangle] +pub static mut continuing: libc::c_int = 0 as libc::c_int; +pub type SizeT = libc::c_ulong; +pub static AL_REUSABLE: i32 = 0x01; + +//bashgetopt +#[no_mangle] +pub static mut list_optarg: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut list_optopt: libc::c_int = 0; +#[no_mangle] +pub static mut list_opttype: libc::c_int = 0; +#[no_mangle] +pub static mut lcurrent: *mut WordList = + 0 as *const libc::c_void as *mut libc::c_void as *mut WordList; +#[no_mangle] +pub static mut loptend: *mut WordList = 0 as *const WordList as *mut WordList; + +//bind +#[repr(C)] +pub struct _keymap_entry { + pub Type: libc::c_char, + pub function: Option, +} +pub type KEYMAP_ENTRY = _keymap_entry; +pub type Keymap = *mut KEYMAP_ENTRY; + +//emun +#[macro_export] +macro_rules! LFLAG { + () => { + 0x0001 + }; +} +#[macro_export] +macro_rules! PFLAG { + () => { + 0x0002 + }; +} +#[macro_export] +macro_rules! FFLAG { + () => { + 0x0004 + }; +} +#[macro_export] +macro_rules! VFLAG { + () => { + 0x0008 + }; +} +#[macro_export] +macro_rules! QFLAG { + () => { + 0x0010 + }; +} +#[macro_export] +macro_rules! MFLAG { + () => { + 0x0020 + }; +} +#[macro_export] +macro_rules! RFLAG { + () => { + 0x0040 + }; +} +#[macro_export] +macro_rules! PPFLAG { + () => { + 0x0080 + }; +} +#[macro_export] +macro_rules! VVFLAG { + () => { + 0x0100 + }; +} +#[macro_export] +macro_rules! SFLAG { + () => { + 0x0200 + }; +} +#[macro_export] +macro_rules! SSFLAG { + () => { + 0x0400 + }; +} +#[macro_export] +macro_rules! UFLAG { + () => { + 0x0800 + }; +} +#[macro_export] +macro_rules! XFLAG { + () => { + 0x1000 + }; +} +#[macro_export] +macro_rules! XXFLAG { + () => { + 0x2000 + }; +} + +#[macro_export] +macro_rules! ISKMAP { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! KEYMAP_SIZE { + () => { + 257 + }; +} + +#[macro_export] +macro_rules! ANYOTHERKEY { + () => { + KEYMAP_SIZE!() - 1 + }; +} + +//caller +#[macro_export] +macro_rules! att_cell { + ($var:expr) => { + return (*($var).value) as *mut ARRAY; + }; +} + +#[macro_export] +macro_rules! CHECK_HELPOPT { + ($l:expr) => { + if $l != std::ptr::null_mut() + && (*($l)).word != std::ptr::null_mut() + && ISHELP!((*(*($l)).word).word) == true + { + builtin_help(); + return EX_USAGE as i32; + } + }; +} + +//cd +#[repr(C)] +pub union VALUE_COMMAND { + For: *mut for_com, + Case: *mut case_com, + While: *mut while_com, + If: *mut if_com, + Connection: *mut connection, + Simple: *mut simple_com, + Function_def: *mut function_def, + Group: *mut group_com, + Select: *mut select_com, + Arith: *mut arith_com, + Cond: *mut cond_com, + ArithFor: *mut arith_for_com, + Subshell: *mut subshell_com, + Coproc: *mut coproc_com, +} + +#[macro_export] +macro_rules! DUP_JOB { + () => { + -2 + }; +} + +#[macro_export] +macro_rules! LCD_DOVARS { + () => { + 0x001 + }; +} +#[macro_export] +macro_rules! LCD_DOSPELL { + () => { + 0x002 + }; +} +#[macro_export] +macro_rules! LCD_PRINTPATH { + () => { + 0x004 + }; +} + +#[macro_export] +macro_rules! LCD_FREEDIRNAME { + () => { + 0x008 + }; +} + +#[macro_export] +macro_rules! MP_DOTILDE { + () => { + 0x01 + }; +} + +pub static mut xattrfd: i32 = -1; +pub static mut xattrflag: i32 = 0; +pub static mut verbatim_pwd: i32 = 0; +pub static mut eflag: i32 = 0; + +//command +pub const const_command_builtin: *mut libc::c_char = + b"command_builtin\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + +pub const CMD_WANT_SUBSHELL: i32 = 0x01; +pub const CMD_FORCE_SUBSHELL: i32 = 0x02; +pub const CMD_INVERT_RETURN: i32 = 0x04; +pub const CMD_IGNORE_RETURN: i32 = 0x08; +pub const CMD_NO_FUNCTIONS: i32 = 0x10; +pub const CMD_INHIBIT_EXPANSION: i32 = 0x20; +pub const CMD_NO_FORK: i32 = 0x40; +pub const CMD_TIME_PIPELINE: i32 = 0x80; +pub const CMD_TIME_POSIX: i32 = 0x100; +pub const CMD_AMPERSAND: i32 = 0x200; +pub const CMD_STDIN_REDIR: i32 = 0x400; +pub const CMD_COMMAND_BUILTIN: i32 = 0x0800; +pub const CMD_COPROC_SUBSHELL: i32 = 0x1000; +pub const CMD_LASTPIPE: i32 = 0x2000; +pub const CMD_STDPATH: i32 = 0x4000; +pub const CMD_TRY_OPTIMIZING: i32 = 0x8000; + +//common.rs +#[macro_export] +macro_rules! SUBSHELL_PAREN { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! EXECUTION_SUCCESS { + () => { + 0 + }; +} + +#[macro_export] +macro_rules! DISCARD { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! ARGS_INVOC { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! ARGS_FUNC { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! ARGS_SETBLTIN { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! EX_BADUSAGE { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! DEBUG_TRAP { + () => { + NSIG!() + 1 + }; +} + +#[macro_export] +macro_rules! NSIG { + () => { + 64 + }; +} + +#[macro_export] +macro_rules! NO_JOB { + () => { + -1 + }; +} + +#[macro_export] +macro_rules! JM_SUBSTRING { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! JM_EXACT { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! JM_STOPPED { + () => { + 0x08 + }; +} + +#[macro_export] +macro_rules! JM_FIRSTMATCH { + () => { + 0x10 + }; +} + +#[macro_export] +macro_rules! VA_NOEXPAND { + () => { + 0x001 + }; +} + +#[macro_export] +macro_rules! VA_ONEWORD { + () => { + 0x002 + }; +} + +#[macro_export] +macro_rules! ASS_NOEXPAND { + () => { + 0x0080 + }; +} + +#[macro_export] +macro_rules! att_invisible { + () => { + 0x0001000 + }; +} + +#[macro_export] +macro_rules! att_nounset { + () => { + 0x0002000 + }; +} + +#[macro_export] +macro_rules! SPECIAL_BUILTIN { + () => { + 0x08 + }; +} + +#[macro_export] +macro_rules! BUILTIN_ENABLED { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! BUILTIN_DELETED { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! DSIG_SIGPREFIX { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! DSIG_NOCASE { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! NO_SIG { + () => { + -1 + }; +} + +#[macro_export] +macro_rules! ISOCTAL { + ($c:expr) => { + ($c) >= b'0' as libc::c_char && ($c) <= b'7' as libc::c_char + }; +} + +#[macro_export] +macro_rules! J_JOBSTATE { + ($j:expr) => { + (*$j).state + }; +} + +//type +pub static EX_SUCCESS: i32 = 0; + +/* Structure containing all the non-action (binary) options; filled in by +build_actions(). */ +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _optflags { + pub pflag: libc::c_int, + pub rflag: libc::c_int, + pub Dflag: libc::c_int, + pub Eflag: libc::c_int, + pub Iflag: libc::c_int, +} + +#[macro_export] +macro_rules! CA_ALIAS { + () => { + 1 << 0 + }; +} + +#[macro_export] +macro_rules! CA_ARRAYVAR { + () => { + 1 << 1 + }; +} + +#[macro_export] +macro_rules! CA_BINDING { + () => { + 1 << 2 + }; +} + +#[macro_export] +macro_rules! CA_BUILTIN { + () => { + 1 << 3 + }; +} + +#[macro_export] +macro_rules! CA_COMMAND { + () => { + 1 << 4 + }; +} + +#[macro_export] +macro_rules! CA_DIRECTORY { + () => { + 1 << 5 + }; +} + +#[macro_export] +macro_rules! CA_DISABLED { + () => { + 1 << 6 + }; +} + +#[macro_export] +macro_rules! CA_ENABLED { + () => { + 1 << 7 + }; +} + +#[macro_export] +macro_rules! CA_EXPORT { + () => { + 1 << 8 + }; +} + +#[macro_export] +macro_rules! CA_FILE { + () => { + 1 << 9 + }; +} + +#[macro_export] +macro_rules! CA_FUNCTION { + () => { + 1 << 10 + }; +} + +#[macro_export] +macro_rules! CA_GROUP { + () => { + 1 << 11 + }; +} + +#[macro_export] +macro_rules! CA_HELPTOPIC { + () => { + 1 << 12 + }; +} + +#[macro_export] +macro_rules! CA_HOSTNAME { + () => { + 1 << 13 + }; +} + +#[macro_export] +macro_rules! CA_JOB { + () => { + 1 << 14 + }; +} + +#[macro_export] +macro_rules! CA_KEYWORD { + () => { + 1 << 15 + }; +} + +#[macro_export] +macro_rules! CA_RUNNING { + () => { + 1 << 16 + }; +} + +#[macro_export] +macro_rules! CA_SERVICE { + () => { + 1 << 17 + }; +} + +#[macro_export] +macro_rules! CA_SETOPT { + () => { + 1 << 18 + }; +} + +#[macro_export] +macro_rules! CA_SHOPT { + () => { + 1 << 19 + }; +} + +#[macro_export] +macro_rules! CA_SIGNAL { + () => { + 1 << 20 + }; +} + +#[macro_export] +macro_rules! CA_STOPPED { + () => { + 1 << 21 + }; +} + +#[macro_export] +macro_rules! CA_USER { + () => { + 1 << 22 + }; +} + +#[macro_export] +macro_rules! CA_VARIABLE { + () => { + 1 << 23 + }; +} + +#[macro_export] +macro_rules! COPT_RESERVED { + () => { + 1 << 0 + }; +} + +#[macro_export] +macro_rules! COPT_DEFAULT { + () => { + 1 << 1 + }; +} + +#[macro_export] +macro_rules! COPT_FILENAMES { + () => { + 1 << 2 + }; +} + +#[macro_export] +macro_rules! COPT_DIRNAMES { + () => { + 1 << 3 + }; +} + +#[macro_export] +macro_rules! COPT_NOQUOTE { + () => { + 1 << 4 + }; +} + +#[macro_export] +macro_rules! COPT_NOSPACE { + () => { + 1 << 5 + }; +} + +#[macro_export] +macro_rules! COPT_BASHDEFAULT { + () => { + 1 << 6 + }; +} + +#[macro_export] +macro_rules! COPT_PLUSDIRS { + () => { + 1 << 7 + }; +} + +#[macro_export] +macro_rules! COPT_NOSORT { + () => { + 1 << 8 + }; +} + +pub static mut Garg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Warg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Parg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Sarg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Xarg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Farg: *mut libc::c_char = std::ptr::null_mut(); +pub static mut Carg: *mut libc::c_char = std::ptr::null_mut(); + +//declare +#[macro_export] +macro_rules! EXITPROG { + () => { + 3 + }; +} +#[macro_export] +macro_rules! ERREXIT { + () => { + 4 + }; +} +#[macro_export] +macro_rules! FORCE_EOF { + () => { + 1 + }; +} +#[macro_export] +macro_rules! att_local { + () => { + 0x0000020 + }; +} + +#[macro_export] +macro_rules! att_assoc { + () => { + 0x0000040 /* variable is an associative array */ + }; +} + +#[macro_export] +macro_rules! att_function { + () => { + 0x0000008 /* value is a function */ + }; +} + +#[macro_export] +macro_rules! att_integer { + () => { + 0x0000010 /* internal representation is int */ + }; +} + +#[macro_export] +macro_rules! att_trace { + () => { + 0x0000080 /* function is traced with DEBUG trap */ + }; +} + +#[macro_export] +macro_rules! att_exported { + () => { + 0x0000001 /* export to environment */ + }; +} + +#[macro_export] +macro_rules! att_capcase { + () => { + 0x0000400 /* word capitalized on assignment */ + }; +} + +#[macro_export] +macro_rules! att_uppercase { + () => { + 0x0000100 /* word converted to uppercase on assignment */ + }; +} + +#[macro_export] +macro_rules! att_lowercase { + () => { + 0x0000200 /* word converted to lowercase on assignment */ + }; +} + +#[macro_export] +macro_rules! FUNC_MULTILINE { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! FUNC_EXTERNAL { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! ASS_FORCE { + () => { + 0x0020 /* force assignment even to readonly variable */ + }; +} + +#[macro_export] +macro_rules! W_COMPASSIGN { + () => { + 1 << 15 /* Compound assignment */ + }; +} + +#[macro_export] +macro_rules! att_propagate { + () => { + 0x0200000 /* propagate to previous scope */ + }; +} + +#[macro_export] +macro_rules! ASS_NAMEREF { + () => { + 0x0010 /* assigning to nameref variable */ + }; +} + +#[macro_export] +macro_rules! VALID_ECHO_OPTIONS { + () => { + CString::new("neE").unwrap().as_ptr() + }; +} + +//enable +pub const ENABLED: i32 = 1; +pub const DISABLED: i32 = 2; +pub const SPECIAL: i32 = 4; + +pub const AFLAG: i32 = 0x01; +pub const DFLAG: i32 = 0x02; +pub const FFLAG: i32 = 0x04; +pub const NFLAG: i32 = 0x08; +pub const PFLAG: i32 = 0x10; +pub const SFLAG: i32 = 0x20; + +//history.rs +pub const SFLAG_H: i32 = 0x10; +pub const PFLAG_H: i32 = 0x20; +pub const DFLAG_H: i32 = 0x80; + +pub const RTLD_LAZY: i32 = 0x00001; +pub const RTLD_NOW: i32 = 0x00002; +pub const RTLD_BINDING_MASK: i32 = 0x3; +pub const RTLD_NOLOAD: i32 = 0x00004; +pub const RTLD_DEEPBIND: i32 = 0x00008; +pub const RTLD_GLOBAL: i32 = 0x00100; + +//eval +#[macro_export] +macro_rules! SEVAL_NOHIST { + () => { + 0x004 + }; +} + +//exit +#[macro_export] +macro_rules! SYS_BASH_LOGOOUT { + () => { + CString::new(" \"/etc/utshell.utshell_logout\" ") + .unwrap() + .as_ptr() + }; +} + +//fc +#[repr(C)] +pub struct REPL { + pub next: *mut REPL, + pub pat: *mut libc::c_char, + pub rep: *mut libc::c_char, +} + +#[macro_export] +macro_rules! ISHELP { + ($s:expr) => { + STREQ!( + $s as *const libc::c_char, + CString::new("--help").unwrap().as_ptr() + ) + }; +} + +#[macro_export] +macro_rules! HN_LISTING { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! SUBSHELL_COMSUB { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! HN_FIRST { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! HIST_INVALID { + () => { + std::i32::MIN + }; +} + +#[macro_export] +macro_rules! HIST_ERANGE { + () => { + std::i32::MIN + 1 + }; +} + +#[macro_export] +macro_rules! HIST_NOTFOUND { + () => { + std::i32::MIN + 2 + }; +} + +#[macro_export] +macro_rules! MT_USETMPDIR { + () => { + 0x0001 + }; +} + +#[macro_export] +macro_rules! MT_READWRITE { + () => { + 0x0002 + }; +} + +#[macro_export] +macro_rules! MT_USERANDOM { + () => { + 0x0004 + }; +} + +#[macro_export] +macro_rules! MT_TEMPLATE { + () => { + 0x0008 + }; +} + +pub union Functions { + pub f_unlink: fn(t: *const libc::c_char) -> i32, + pub f_xfree: fn(str1: *mut libc::c_void), + pub f_set_verbose: fn(), + pub restore_funcarray_state: fn(*mut func_array_state) -> (), + pub pop_args: fn(), + pub set_current_prompt_level: fn(libc::c_int) -> (), + pub pop_stream: fn() -> (), + pub parser_restore_alias: fn() -> (), + pub xfree: fn(*mut libc::c_void) -> (), + pub dispose_fd_bitmap: fn(*mut fd_bitmap) -> (), + pub dispose_command: fn(*mut COMMAND) -> (), + pub set_history_remembering: fn() -> (), + pub restore_lastcom: fn(*mut libc::c_char) -> (), +} + +//fg_bg +#[macro_export] +macro_rules! J_JOBCONTROL { + () => { + 0x04 + }; +} + +//getopts +#[macro_export] +macro_rules! EX_MISCERROR { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! G_EOF { + () => { + -1 + }; +} + +#[macro_export] +macro_rules! G_INVALID_OPT { + () => { + -2 + }; +} + +#[macro_export] +macro_rules! G_ARG_MISSING { + () => { + -3 + }; +} + +type PTR_T = c_void; + +//enum +#[macro_export] +macro_rules! PARAMS { + ($protos:expr) => { + $protos + }; +} +pub unsafe fn hash_entries(ht: *mut HASH_TABLE) -> i32 { + if ht != std::ptr::null_mut() { + return (*ht).nentries; + } else { + return 0; + } +} + +fn HASH_ENTRIES(ht: *mut HASH_TABLE) -> i32 { + unsafe { + if ht != std::ptr::null_mut() { + return (*ht).nentries; + } else { + return 0; + } + } +} +#[macro_export] +macro_rules! pathdata { + ($x:expr) => { + (*$x).data as *mut PATH_DATA + }; +} + +//help +#[repr(C)] +struct FieldStruct { + name: *mut libc::c_char, +} + +#[macro_export] +macro_rules! EX_USAGE { + () => { + 258 + }; +} + +#[macro_export] +macro_rules! BASE_INDENT { + () => { + 4 + }; +} + +#[macro_export] +macro_rules! BUILTIN_SIZEOF { + () => { + 48 + }; +} + +#[macro_export] +macro_rules! EXIT_FAILURE { + () => { + 1 + }; +} + +//history +pub const RFLAG: libc::c_int = 0x02; +pub const WFLAG: libc::c_int = 0x04; +pub const CFLAG: libc::c_int = 0x40; + +//jobs +#[macro_export] +macro_rules! JLIST_STANDARD { + () => { + 0 + }; +} + +#[macro_export] +macro_rules! JSTATE_ANY { + () => { + 0x0 + }; +} + +#[macro_export] +macro_rules! JLIST_LONG { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! JLIST_PID_ONLY { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! JLIST_CHANGED_ONLY { + () => { + 3 + }; +} + +#[macro_export] +macro_rules! JSTATE_RUNNING { + () => { + 0x1 + }; +} + +#[macro_export] +macro_rules! JSTATE_STOPPED { + () => { + 0x2 + }; +} + +#[macro_export] +macro_rules! CMD_INHIBIT_EXPANSION { + /* Do not expand the command words. */ + () => { + 0x20 + }; +} + +//mapfile +pub const atype_array_indexed: atype = 0; + +pub const att_readonly: libc::c_int = 0x0000002; +pub const att_array: libc::c_int = 0x0000004; +pub const att_invisible: libc::c_int = 0x0001000; +pub const att_noassign: libc::c_int = 0x0004000; + +pub const MAPF_CLEARARRAY: libc::c_int = 0x01; +pub const MAPF_CHOP: libc::c_int = 0x02; + +//printf +pub type mbstate_t = __mbstate_t; + +macro_rules! IS_DIGITAL { + ($x: expr) => { + $x >= b'0' as libc::c_char && $x <= b'9' as libc::c_char + }; +} + +//pushd +#[macro_export] +macro_rules! NOCD { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! ROTATE { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! LONGFORM { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! CLEARSTAK { + () => { + 0x08 + }; +} + +pub static mut pushd_directory_list: *mut *mut libc::c_char = std::ptr::null_mut(); +pub static mut directory_list_offset: i32 = 0; +pub static mut directory_list_size: i32 = 0; + +//read +pub const ISFUNC: libc::c_int = 0; + +#[no_mangle] +pub static mut alrmbuf: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, +}; 1]; + +#[derive(Clone, Copy)] +pub struct tty_save { + pub fd: i32, + pub attrs: libc::termios, +} + +//set +#[macro_export] +macro_rules! FLAG_UNKNOWN { + () => { + 0 as *mut i32 + }; +} + +#[macro_export] +macro_rules! MINUS_O_FORMAT { + () => { + CString::new("%-15s\t%s\n") + }; +} + +#[macro_export] +macro_rules! GET_BINARY_O_OPTION_VALUE { + ($a:expr,$b:expr) => { + if (o_options[$a as usize].get_func).is_some() { + (Some((o_options[$a as usize].get_func).expect("non-null function pointer"))) + .expect("non-null function pointer")($b) + } else { + *o_options[$a as usize].variable + } + }; +} + +#[macro_export] +macro_rules! SET_BINARY_O_OPTION_VALUE { + ($a:expr,$onoff:expr,$c:expr) => { + if (o_options[$a as usize].set_func).is_some() { + (Some((o_options[$a as usize].set_func).expect("non-null function pointer"))) + .expect("non-null function pointer")($onoff, $c) + } else { + $onoff == FLAG_ON!(); + let b = $onoff; + *o_options[$a as usize].variable = b; + *o_options[$a as usize].variable + } + }; +} + +#[macro_export] +macro_rules! N_O_OPTIONS { + () => { + (std::mem::size_of::<[opp; 28]>() as usize / std::mem::size_of::() as usize) + }; +} + +#[macro_export] +macro_rules! FLAG_ON { + () => { + b'-' as i32 + }; +} + +#[macro_export] +macro_rules! FLAG_OFF { + () => { + b'+' as i32 + }; +} + +#[macro_export] +macro_rules! att_imported { + () => { + 0x0008000 + }; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct opp { + pub name: *mut libc::c_char, + pub letter: i32, + pub variable: *mut i32, + pub set_func: Option, + pub get_func: Option, +} + +#[macro_export] +macro_rules! FLAG_ERROR { + () => { + -1 + }; +} + +type setopt_set_func_t = fn(i: i32, name: *mut libc::c_char) -> i32; +type setopt_get_func_t = fn(name: *mut libc::c_char) -> i32; + +//setattr +pub const att_exported: libc::c_int = 0x0000001; +pub const att_function: libc::c_int = 0x0000008; +pub const att_integer: libc::c_int = 0x0000010; +pub const att_local: libc::c_int = 0x0000020; +pub const att_assoc: libc::c_int = 0x0000040; +pub const att_trace: libc::c_int = 0x0000080; +pub const att_uppercase: libc::c_int = 0x0000100; +pub const att_lowercase: libc::c_int = 0x0000200; +pub const att_capcase: libc::c_int = 0x0000400; +pub const att_nameref: libc::c_int = 0x0000800; +pub const att_imported: libc::c_int = 0x0008000; +pub const att_tempvar: libc::c_int = 0x0100000; +pub const att_propagate: libc::c_int = 0x0200000; + +//shift +pub static mut print_shift_error: libc::c_int = 0; + +//shopt +pub type IntmaxT = libc::c_long; +pub type ArrayindT = intmax_t; + +pub type ShVarAssignFuncT = + fn(*mut variable, *mut libc::c_char, ArrayindT, *mut libc::c_char) -> *mut variable; +pub type ShVarValueFuncT = fn(*mut variable) -> *mut variable; +pub type ShellVar = variable; + +//trap +pub const SET: libc::c_int = 0; +pub const REVERT: libc::c_int = 1; +pub const IGNORE: libc::c_int = 2; + +//type_1 +#[macro_export] +macro_rules! CDESC_ALL { + //print all descriptions of a command + () => { + 0x001 + }; +} + +#[macro_export] +macro_rules! CDESC_SHORTDESC { + //print the description for type and command -V + () => { + 0x002 + }; +} + +#[macro_export] +macro_rules! CDESC_REUSABLE { + //print in a format that may be reused as input + () => { + 0x004 + }; +} + +#[macro_export] +macro_rules! CDESC_TYPE { + //print the type for type -t + () => { + 0x008 + }; +} + +#[macro_export] +macro_rules! CDESC_PATH_ONLY { + //print the path for type -p + () => { + 0x010 + }; +} + +#[macro_export] +macro_rules! CDESC_FORCE_PATH { + //force a path search for type -P + () => { + 0x020 + }; +} + +#[macro_export] +macro_rules! CDESC_NOFUNCS { + //skip function lookup for type -f + () => { + 0x040 + }; +} + +#[macro_export] +macro_rules! CDESC_ABSPATH { + //CDESC_ABSPATH + () => { + 0x080 + }; +} + +#[macro_export] +macro_rules! CDESC_STDPATH { + () => { + 0x100 + }; +} + +#[macro_export] +macro_rules! FS_EXECABLE { + () => { + 0x2 + }; +} +#[macro_export] +macro_rules! FS_EXEC_PREFERRED { + () => { + 0x4 + }; +} + +#[macro_export] +macro_rules! FS_NODIRS { + () => { + 0x20 + }; +} + +#[macro_export] +macro_rules! MP_DOCWD { + () => { + 0 + }; +} + +#[macro_export] +macro_rules! MP_RMDOT { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! SIZEOFWORD { + () => { + std::mem::size_of::() + }; +} + +pub fn math(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 { + // 通过函数指针调用函数 + op(a, b) +} + +#[macro_export] +macro_rules! FS_EXEC_ONLY { + () => { + 0x8 + }; +} + +//ulimit +#[macro_export] +macro_rules! SIZEOFLIMIT { + () => { + std::mem::size_of::() as usize + }; +} + +#[macro_export] +macro_rules! SIZEOFLIMITS { + () => { + SIZEOFLIMIT!() * 18 + }; +} + +#[macro_export] +macro_rules! SIZEOFULCMD { + () => { + std::mem::size_of::() + }; +} + +#[macro_export] +macro_rules! LIMIT_HARD { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! LIMIT_SOFT { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! POSIXBLK { + () => { + -2 + }; +} + +#[macro_export] +macro_rules! BLOCKSIZE { + ($s:expr) => { + if $s == POSIXBLK!() { + if unsafe { posixly_correct != 0 } { + 512 + } else { + 1024 + } + } else { + $s + } + }; +} + +#[macro_export] +macro_rules! RLIM_SAVED_MAX { + () => { + RLIM_INFINITY!() + }; +} + +#[macro_export] +macro_rules! NCMDS { + () => { + SIZEOFLIMITS!() / SIZEOFLIMIT!() + }; +} + +#[macro_export] +macro_rules! RLIMIT_FILESIZE { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! RLIMIT_PIPESIZE { + () => { + 257 + }; +} + +#[macro_export] +macro_rules! PIPESIZE { + () => { + 4096 + }; +} + +#[macro_export] +macro_rules! PIPE_BUF { + () => { + PIPESIZE!() + }; +} + +#[macro_export] +macro_rules! RLIMIT_OPENFILES { + () => { + 7 + }; +} + +#[macro_export] +macro_rules! RLIMIT_VIRTMEM { + () => { + 9 + }; +} + +#[macro_export] +macro_rules! RLIMIT_MAXUPROC { + () => { + 6 + }; +} + +#[macro_export] +macro_rules! RLIM_INFINITY { + () => { + -1 + //0x7fffffff + }; +} + +#[macro_export] +macro_rules! RLIM_SAVED_CUR { + () => { + RLIM_INFINITY!() + }; +} + +pub const __RLIM_NLIMITS: __rlimit_resource = 16; +pub const __RLIMIT_NLIMITS: __rlimit_resource = 16; +pub const __RLIMIT_RTTIME: __rlimit_resource = 15; +pub const __RLIMIT_RTPRIO: __rlimit_resource = 14; +pub const __RLIMIT_NICE: __rlimit_resource = 13; +pub const __RLIMIT_MSGQUEUE: __rlimit_resource = 12; +pub const __RLIMIT_SIGPENDING: __rlimit_resource = 11; +pub const __RLIMIT_LOCKS: __rlimit_resource = 10; +pub const __RLIMIT_MEMLOCK: __rlimit_resource = 8; +pub const __RLIMIT_NPROC: __rlimit_resource = 6; +pub const RLIMIT_AS: __rlimit_resource = 9; +pub const __RLIMIT_OFILE: __rlimit_resource = 7; +pub const RLIMIT_NOFILE: __rlimit_resource = 7; +pub const __RLIMIT_RSS: __rlimit_resource = 5; +pub const RLIMIT_CORE: __rlimit_resource = 4; +pub const RLIMIT_STACK: __rlimit_resource = 3; +pub const RLIMIT_DATA: __rlimit_resource = 2; +pub const RLIMIT_FSIZE: __rlimit_resource = 1; +pub const RLIMIT_CPU: __rlimit_resource = 0; + +//umask +#[macro_export] +macro_rules! mode_t { + () => { + u32 + }; +} + +#[macro_export] +macro_rules! S_IREAD { + () => { + 0o0400 + }; +} + +#[macro_export] +macro_rules! S_IWRITE { + () => { + 0o0200 + }; +} + +#[macro_export] +macro_rules! S_IEXEC { + () => { + 0o0100 + }; +} + +#[macro_export] +macro_rules! S_IRUSR { + /* read, owner */ + () => { + S_IREAD!() + }; +} + +#[macro_export] +macro_rules! S_IWUSR { + /* write, owner */ + () => { + S_IWRITE!() + }; +} + +#[macro_export] +macro_rules! S_IXUSR { + /* execute, owner */ + () => { + S_IEXEC!() + }; +} + +#[macro_export] +macro_rules! S_IRGRP { + /* read, group */ + () => { + S_IREAD!() >> 3 + }; +} + +#[macro_export] +macro_rules! S_IWGRP { + /* write, group */ + () => { + S_IWRITE!() >> 3 + }; +} + +#[macro_export] +macro_rules! S_IXGRP { + /* execute, group */ + () => { + S_IEXEC!() >> 3 + }; +} + +#[macro_export] +macro_rules! S_IROTH { + /* read, other */ + () => { + S_IREAD!() >> 6 + }; +} + +#[macro_export] +macro_rules! S_IWOTH { + /* write, other */ + () => { + S_IWRITE!() >> 6 + }; +} + +#[macro_export] +macro_rules! S_IXOTH { + /* execute, other */ + () => { + S_IEXEC!() >> 6 + }; +} + +#[macro_export] +macro_rules! S_IRWXU { + () => { + S_IRUSR!() | S_IWUSR!() | S_IXUSR!() + }; +} + +#[macro_export] +macro_rules! S_IRWXG { + () => { + S_IRGRP!() | S_IWGRP!() | S_IXGRP!() + }; +} + +#[macro_export] +macro_rules! S_IRWXO { + () => { + S_IROTH!() | S_IWOTH!() | S_IXOTH!() + }; +} + +#[macro_export] +macro_rules! S_IRUGO { + () => { + S_IRUSR!() | S_IRGRP!() | S_IROTH!() + }; +} + +#[macro_export] +macro_rules! S_IWUGO { + () => { + S_IWUSR!() | S_IWGRP!() | S_IWOTH!() + }; +} + +#[macro_export] +macro_rules! S_IXUGO { + () => { + S_IXUSR!() | S_IXGRP!() | S_IXOTH!() + }; +} + +//wait +#[macro_export] +macro_rules! J_WAITING { + () => { + 0x08 + }; +} + +#[macro_export] +macro_rules! JWAIT_FORCE { + () => { + 1 << 1 + }; +} + +#[macro_export] +macro_rules! JWAIT_WAITING { + () => { + 1 << 3 + }; +} + +#[macro_export] +macro_rules! JWAIT_PEROOR { + () => { + 1 << 0 + }; +} + +pub type procenv_t = __jmp_buf_tag; + +//evalstring +#[macro_export] +macro_rules! CMD_INVERT_RETURN { + () => { + 0x4 + }; +} +#[macro_export] +macro_rules! CMD_TIME_PIPELINE { + () => { + 0x80 + }; +} +#[macro_export] +macro_rules! AND_AND { + () => { + 288 + }; +} +#[macro_export] +macro_rules! OR_OR { + () => { + 289 + }; +} +#[macro_export] +macro_rules! CMD_TRY_OPTIMIZING { + () => { + 0x8000 + }; +} +#[macro_export] +macro_rules! CMD_NO_FORK { + () => { + 0x40 + }; +} +#[macro_export] +macro_rules! SEVAL_NONINT { + () => { + 0x1 + }; +} +#[macro_export] +macro_rules! SEVAL_INTERACT { + () => { + 0x2 + }; +} +#[macro_export] +macro_rules! SEVAL_RESETLINE { + () => { + 0x10 + }; +} +#[macro_export] +macro_rules! SEVAL_PARSEONLY { + () => { + 0x20 + }; +} +#[macro_export] +macro_rules! SEVAL_ONECMD { + () => { + 0x100 + }; +} +#[macro_export] +macro_rules! CMD_IGNORE_RETURN { + () => { + 0x8 + }; +} +#[macro_export] +macro_rules! SEVAL_NOHISTEXP { + () => { + 0x200 + }; +} + +//evalfile +#[macro_export] +macro_rules! FEVAL_ENOENTOK { + () => { + 0x1 + }; +} +#[macro_export] +macro_rules! FEVAL_BUILTIN { + () => { + 0x2 + }; +} +#[macro_export] +macro_rules! FEVAL_UNWINDPROT { + () => { + 0x4 + }; +} +#[macro_export] +macro_rules! FEVAL_NONINT { + () => { + 0x8 + }; +} +#[macro_export] +macro_rules! FEVAL_NOPUSHARGS { + () => { + 0x100 + }; +} +#[macro_export] +macro_rules! FEVAL_LONGJMP { + () => { + 0x10 + }; +} +#[macro_export] +macro_rules! FEVAL_HISTORY { + () => { + 0x20 + }; +} +#[macro_export] +macro_rules! FEVAL_REGFILE { + () => { + 0x80 + }; +} +#[macro_export] +macro_rules! yacc_EOF { + () => { + 304 + }; +} +#[macro_export] +macro_rules! FEVAL_CHECKBINARY { + () => { + 0x40 + }; +} +#[macro_export] +macro_rules! SSIZE_MAX { + () => { + 9223372036854775807 + }; +} +#[macro_export] +macro_rules! __S_IFREG { + () => { + 0o100000 + }; +} + +#[no_mangle] +pub static mut sh_optarg: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut sh_optind: libc::c_int = 0 as libc::c_int; +pub static mut sh_curopt: libc::c_int = 0; +pub static mut nextchar: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +pub static mut sh_charindex: libc::c_int = 0; +#[no_mangle] +pub static mut sh_opterr: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut sh_optopt: libc::c_int = '?' as i32; +#[no_mangle] +pub static mut sh_badopt: libc::c_int = 0 as libc::c_int; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct word_desc { + pub word: *mut libc::c_char, + pub flags: libc::c_int, +} +pub type WordDesc = word_desc; +pub type WORD_DESC = word_desc; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct word_list { + pub next: *mut word_list, + pub word: *mut WordDesc, +} +pub type WordList = word_list; +pub type WORD_LIST = word_list; + +//alias +pub const _ISalpha: libc::c_uint = 1024; + +pub type __compar_fn_t = Option libc::c_int>; + +pub type QSFUNC = fn(*const libc::c_void, *const libc::c_void) -> libc::c_int; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct _list_of_strings { + pub list: *mut *mut libc::c_char, + pub list_size: libc::c_int, + pub list_len: libc::c_int, +} +pub type STRINGLIST = _list_of_strings; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct bucket_contents { + pub next: *mut bucket_contents, + pub key: *mut libc::c_char, + pub data: *mut libc::c_void, + pub khash: libc::c_uint, + pub times_found: libc::c_int, +} +pub type BUCKET_CONTENTS = bucket_contents; +pub type BucketContents = bucket_contents; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct hash_table { + pub bucket_array: *mut *mut BUCKET_CONTENTS, + pub nbuckets: libc::c_int, + pub nentries: libc::c_int, +} +pub type HASH_TABLE = hash_table; +pub type HashTable = hash_table; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct alias { + pub name: *mut libc::c_char, + pub value: *mut libc::c_char, + pub flags: libc::c_char, +} +pub type alias_t = alias; +pub type AliasT = alias; +pub type ITEMLIST = _list_of_items; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct _list_of_items { + pub flags: libc::c_int, + pub list_getter: Option libc::c_int>, + pub slist: *mut STRINGLIST, + pub genlist: *mut STRINGLIST, + pub genindex: libc::c_int, +} +pub type sh_alias_map_func_t = fn(*mut alias_t) -> libc::c_int; +#[no_mangle] +pub static mut alias_expand_all: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut aliases: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +pub const AL_EXPANDNEXT: libc::c_int = 0x1; +pub const HASH_NOSRCH: libc::c_int = 0x1; +pub const AL_BEINGEXPANDED: libc::c_int = 0x2; + +//array +pub const array_indexed: atype = 0; + +pub type sh_ae_map_func_t = fn(arg1: *mut ARRAY_ELEMENT, arg2: *mut libc::c_void) -> libc::c_int; + +#[macro_export] +macro_rules! element_forw { + ($ae:expr) => { + (*$ae).next + }; +} + +#[macro_export] +macro_rules! element_back { + ($ae:expr) => { + (*$ae).prev + }; +} + +#[macro_export] +macro_rules! element_index { + ($ae:expr) => { + (*$ae).ind + }; +} + +#[macro_export] +macro_rules! element_value { + ($ae:expr) => { + (*$ae).value + }; +} + +#[macro_export] +macro_rules! ADD_BEFORE { + ($ae:expr,$new:expr) => { + (*(*$ae).prev).next = $new; + (*$new).prev = (*$ae).prev; + (*$ae).prev = $new; + (*$new).next = $ae; + }; +} + +#[macro_export] +macro_rules! ADD_AFTER { + ($ae:expr,$new:expr) => { + (*(*$ae).next).prev = $new; + (*$new).next = (*$ae).next; + (*$new).prev = $ae; + (*$ae).next = $new; + }; +} + +#[macro_export] +macro_rules! REVERSE_LIST { + ($list:expr,$type:ty) => { + if !$list.is_null() && !((*$list).next).is_null() { + list_reverse($list as *mut GENERIC_LIST) as $type + } else { + $list as $type + } + }; +} + +#[macro_export] +macro_rules! array_empty { + ($a:expr) => { + (*$a).num_elements == 0 + }; +} +#[macro_export] +macro_rules! LASTREF { + ($a:expr) => { + if !(*$a).lastref.is_null() { + (*$a).lastref + } else { + element_forw!((*$a).head) + } + }; +} + +#[macro_export] +macro_rules! SET_LASTREF { + ($a:expr,$e:expr) => { + (*$a).lastref = $e + }; +} + +#[macro_export] +macro_rules! INVALIDATE_LASTREF { + ($a:expr) => { + (*$a).lastref = 0 as *mut array_element + }; +} + +#[macro_export] +macro_rules! array_max_index { + ($a:expr) => { + (*$a).max_index + }; +} + +#[macro_export] +macro_rules! array_first_index { + ($a:expr) => { + (*(*(*$a).head).next).ind + }; +} + +#[macro_export] +macro_rules! array_num_elements { + ($a:expr) => { + (*$a).num_elements + }; +} + +#[macro_export] +macro_rules! array_head { + ($a:expr) => { + (*$a).head + }; +} + +#[macro_export] +macro_rules! STRLEN { + ($s:expr) => { + if !$s.is_null() && *$s.offset(0 as isize) as libc::c_int != 0 { + if *$s.offset(1 as isize) as libc::c_int != 0 { + if *$s.offset(2 as isize) as libc::c_int != 0 { + libc::strlen($s) as i32 + } else { + 2 + } + } else { + 1 + } + } else { + 0 + } + }; +} + +#[macro_export] +macro_rules! RESIZE_MALLOCED_BUFFER { + ($srt:expr,$cind:expr, $room:expr, $csize:expr, $sincr:expr) => { + if $cind + $room >= $csize { + while $cind + $room >= $csize { + $csize += $sincr; + } + $srt = libc::realloc($srt as *mut libc::c_void, $csize as usize) as *mut libc::c_char; + } + }; +} + +//arrayfunc +pub const W_ASSIGNMENT: i32 = 1 << 2; + +pub type size_t = libc::c_ulong; +pub type wchar_t = libc::c_int; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct __mbstate_t { + pub __count: libc::c_int, + pub __value: mbstate_t_value, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub union mbstate_t_value { + pub __wch: libc::c_uint, + pub __wchb: [libc::c_char; 4], +} + +pub type __intmax_t = libc::c_long; + +pub type intmax_t = __intmax_t; +pub type arrayind_t = intmax_t; +pub type atype = libc::c_uint; +pub const array_assoc: atype = 1; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct array { + pub type_0: atype, + pub max_index: arrayind_t, + pub num_elements: libc::c_int, + pub head: *mut array_element, + pub lastref: *mut array_element, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct array_element { + pub ind: arrayind_t, + pub value: *mut libc::c_char, + pub next: *mut array_element, + pub prev: *mut array_element, +} +pub type ARRAY = array; +pub type ARRAY_ELEMENT = array_element; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct variable { + pub name: *mut libc::c_char, + pub value: *mut libc::c_char, + pub exportstr: *mut libc::c_char, + pub dynamic_value: Option, + pub assign_func: Option, + pub attributes: libc::c_int, + pub context: libc::c_int, +} +pub type sh_var_assign_func_t = + fn(*mut variable, *mut libc::c_char, arrayind_t, *mut libc::c_char) -> *mut variable; +pub type sh_var_value_func_t = fn(*mut variable) -> *mut variable; +pub type SHELL_VAR = variable; + +#[macro_export] +macro_rules! value_cell { + ($var:expr) => { + (*$var).value + }; +} +#[macro_export] +macro_rules! FREE { + ($s:expr) => { + if ($s) != std::ptr::null_mut() { + libc::free($s as *mut libc::c_void); + } + }; +} + +#[macro_export] +macro_rules! var_setarray { + ($var:expr,$arr:expr) => { + (*$var).value = $arr as *mut libc::c_char; + (*$var).value + }; +} +#[macro_export] +macro_rules! INVALIDATE_EXPORTSTR { + ($var:expr) => { + if !((*$var).exportstr.is_null()) { + libc::free((*$var).exportstr as *mut libc::c_void); + (*$var).exportstr = 0 as *mut libc::c_void as *mut libc::c_char; + } + }; +} +#[macro_export] +macro_rules! exported_p { + ($var:expr) => { + (*$var).attributes & (att_exported!()) + }; +} + +#[macro_export] +macro_rules! VUNSETATTR { + ($var:expr,$attr:expr) => { + (*$var).attributes &= !($attr) as libc::c_int; + (*$var).attributes + }; +} +#[macro_export] +macro_rules! assoc_create { + ($var:expr) => { + hash_create($var) + }; +} +#[macro_export] +macro_rules! var_setassoc { + ($var:expr,$arr:expr) => { + (*$var).value = $arr as *mut libc::c_char; + }; +} +#[macro_export] +macro_rules! assoc_p { + ($var:expr) => { + (*$var).attributes & (att_assoc as libc::c_int) + }; +} +#[macro_export] +macro_rules! assoc_cell { + ($var:expr) => { + (*$var).value as *mut hash_table + }; +} +#[macro_export] +macro_rules! array_cell { + ($var:expr) => { + (*$var).value as *mut ARRAY + }; +} +#[macro_export] +macro_rules! INVALID_NAMEREF_VALUE { + () => { + &mut nameref_invalid_value as *mut SHELL_VAR as *mut libc::c_void as *mut SHELL_VAR + }; +} +#[macro_export] +macro_rules! nameref_p { + ($var:expr) => { + (*$var).attributes & att_nameref as libc::c_int + }; +} +#[macro_export] +macro_rules! nameref_cell { + ($var:expr) => { + (*$var).value + }; +} +#[macro_export] +macro_rules! readonly_p { + ($var:expr) => { + (*$var).attributes & att_readonly as libc::c_int + }; +} +#[macro_export] +macro_rules! noassign_p { + ($var:expr) => { + (*$var).attributes & att_noassign as libc::c_int + }; +} + +#[macro_export] +macro_rules! ALL_ELEMENT_SUB { + ($c:expr) => { + $c == '@' as i32 || $c == '*' as i32 + }; +} + +#[macro_export] +macro_rules! invisible_p { + ($var:expr) => { + (*$var).attributes & att_invisible as libc::c_int + }; +} +#[macro_export] +macro_rules! integer_p { + ($var:expr) => { + (*$var).attributes & att_integer as libc::c_int + }; +} + +#[macro_export] +macro_rules! isifs { + ($c:expr) => { + *ifs_cmap.as_mut_ptr().offset($c as libc::c_uchar as isize) as libc::c_int + }; +} +#[macro_export] +macro_rules! LBRACK { + () => { + '[' + }; +} +#[macro_export] +macro_rules! RBRACK { + () => { + ']' + }; +} + +#[macro_export] +macro_rules! INDEX_ERROR { + ($var: expr, $t: expr, $s: expr) => { + if !$var.is_null() { + err_badarraysub((*$var).name); + } else { + *$t.offset(-(1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + err_badarraysub($s); + *$t.offset(-(1 as libc::c_int) as isize) = '[' as i32 as libc::c_char; + } + return 0 as *mut libc::c_void as *mut libc::c_char; + }; +} +#[macro_export] +macro_rules! var_isset { + ($var:expr) => { + (*$var).value != 0 as *mut libc::c_char + }; +} + +/* This variable means to not expand associative array subscripts more than +once, when performing variable expansion. */ +#[no_mangle] +pub static mut assoc_expand_once: libc::c_int = 0 as libc::c_int; + +/* Ditto for indexed array subscripts -- currently unused */ +#[no_mangle] +pub static mut array_expand_once: libc::c_int = 0 as libc::c_int; + +/* Standard error message to use when encountering an invalid array subscript */ +#[no_mangle] +pub static mut bash_badsub_errmsg: *const libc::c_char = + b"bad array subscript\0" as *const u8 as *const libc::c_char; + +//assoc +#[macro_export] +macro_rules! assoc_empty { + ($h:expr) => { + (*$h).nentries == 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! hash_items { + ($bucket:expr,$table:expr) => { + if !$table.is_null() && $bucket < (*$table).nbuckets { + *((*$table).bucket_array).offset($bucket as isize) + } else { + 0 as *mut libc::c_void as *mut BUCKET_CONTENTS + }; + }; +} + +//bashhist +pub type rl_linebuf_func_t = fn(*mut libc::c_char, libc::c_int) -> libc::c_int; + +#[macro_export] +macro_rules! HISTSIZE_DEFAULT { + () => { + b"500\0" as *const u8 as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! HIGN_EXPAND { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! ENOENT { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! errno { + () => { + *__errno_location() + }; +} + +#[macro_export] +macro_rules! whitespace { + ($c:expr) => { + ($c as libc::c_int == ' ' as i32 || $c as libc::c_int == '\t' as i32) + }; +} + +#[macro_export] +macro_rules! FNM_NOMATCH { + () => { + 1 + }; +} + +pub const st_stdin: stream_type = 1; + +pub type histdata_t = *mut libc::c_void; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct _hist_entry { + pub line: *mut libc::c_char, + pub timestamp: *mut libc::c_char, + pub data: histdata_t, +} +pub type HIST_ENTRY = _hist_entry; + +#[no_mangle] +pub static mut remember_on_history: libc::c_int = 0; +#[no_mangle] +pub static mut enable_history_list: libc::c_int = -1; +#[no_mangle] +pub static mut history_lines_this_session: libc::c_int = 0; +#[no_mangle] +pub static mut history_lines_in_file: libc::c_int = 0; +#[no_mangle] +pub static mut history_expansion_inhibited: libc::c_int = 0; +#[no_mangle] +pub static mut double_quotes_inhibit_history_expansion: libc::c_int = 0; +#[no_mangle] +pub static mut command_oriented_history: libc::c_int = 1; +#[no_mangle] +pub static mut current_command_first_line_saved: libc::c_int = 0; +#[no_mangle] +pub static mut current_command_line_comment: libc::c_int = 0; +#[no_mangle] +pub static mut literal_history: libc::c_int = 0; +#[no_mangle] +pub static mut force_append_history: libc::c_int = 0; +#[no_mangle] +pub static mut history_control: libc::c_int = 0; +#[no_mangle] +pub static mut hist_last_line_added: libc::c_int = 0; +#[no_mangle] +pub static mut hist_last_line_pushed: libc::c_int = 0; +#[no_mangle] +pub static mut history_reediting: libc::c_int = 0; +#[no_mangle] +pub static mut hist_verify: libc::c_int = 0; +#[no_mangle] +pub static mut dont_save_function_defs: libc::c_int = 0; + +//bashline +pub type rl_hook_func_t = fn() -> libc::c_int; +pub type rl_command_func_t = fn(libc::c_int, libc::c_int) -> libc::c_int; + +#[macro_export] +macro_rules! STREQN { + ($a:expr,$b:expr,$n:expr) => { + if $n == 0 { + 1 + } else { + (*$a.offset(0 as isize) == *$b.offset(0 as isize) + && libc::strncmp($a, $b, $n as usize) == 0) as i32 + } + }; +} + +#[macro_export] +macro_rules! STREQ { + ($a:expr, $b:expr) => { + (*$a.offset(0 as libc::c_int as isize) as libc::c_int + == *$b.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp($a, $b) == 0 as libc::c_int) + }; +} + +#[no_mangle] +pub static mut bash_readline_initialized: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut perform_hostname_completion: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut no_empty_command_completion: libc::c_int = 0; +#[no_mangle] +pub static mut force_fignore: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut dircomplete_spelling: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut dircomplete_expand: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut dircomplete_expand_relpath: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut complete_fullquote: libc::c_int = 1 as libc::c_int; +pub static mut bash_completer_word_break_characters: *mut libc::c_char = + b" \t\n\"'@><=;|&(:\0" as *const u8 as *const libc::c_char as *mut libc::c_char; +pub static mut bash_nohostname_word_break_characters: *mut libc::c_char = + b" \t\n\"'><=;|&(:\0" as *const u8 as *const libc::c_char as *mut libc::c_char; +pub static mut default_filename_quote_characters: *const libc::c_char = + b" \t\n\\\"'@<>=;|&()#$`?*[!:{~\0" as *const u8 as *const libc::c_char; +pub static mut custom_filename_quote_characters: *mut libc::c_char = + 0 as *const libc::c_char as *mut libc::c_char; +pub static mut filename_bstab: [libc::c_char; 256] = [0; 256]; +pub static mut old_rl_startup_hook: Option = unsafe { + ::std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *const libc::c_void as *mut libc::c_void, + ) +}; +pub static mut dot_in_path: libc::c_int = 0 as libc::c_int; +pub static mut dabbrev_expand_active: libc::c_int = 0 as libc::c_int; +pub static mut completion_quoting_style: libc::c_int = 3 as libc::c_int; +pub static mut vi_tab_binding: Option = unsafe { + Some(std::mem::transmute::< + unsafe extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int, + fn(libc::c_int, libc::c_int) -> libc::c_int, + >(rl_complete)) +}; + +#[macro_export] +macro_rules! control_character_mask { + () => { + 0x1f + }; +} + +#[macro_export] +macro_rules! CTRL { + ($c:expr) => { + $c & control_character_mask!() + }; +} + +#[macro_export] +macro_rules! cr_whitespace { + ($c:expr) => { + $c as libc::c_int == '\r' as i32 || $c as libc::c_int == '\n' as i32 || whitespace!($c) + }; +} + +#[macro_export] +macro_rules! DIGIT { + ($c:expr) => { + $c as libc::c_int >= '0' as i32 && $c as libc::c_int <= '9' as i32 + }; +} + +#[macro_export] +macro_rules! RL_BOOLEAN_VARIABLE_VALUE { + ($c:expr) => { + (*$c.offset(0 as isize) as libc::c_int == 'o' as i32 + && *$c.offset(1 as isize) as libc::c_int == 'n' as i32 + && *$c.offset(2 as isize) as libc::c_int == '\u{0}' as i32) + }; +} + +#[macro_export] +macro_rules! POSIX_VI_EDIT_COMMAND { + () => { + b"fc -e vi\0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! VI_EDIT_COMMAND { + () => { + b"fc -e \"${VISUAL:-${EDITOR:-vi}}\"\0" as *const u8 as *const libc::c_char + as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! EMACS_EDITING_MODE { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! EMACS_EDIT_COMMAND { + () => { + b"fc -e \"${VISUAL:-${EDITOR:-emacs}}\"\0" as *const u8 as *const libc::c_char + as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! DECLARE_MBSTATE { + ($state:expr) => { + memset( + &mut $state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + (::std::mem::size_of::() as usize), + ) + }; +} + +//brace +#[no_mangle] +pub fn mbrlen(mut __s: *const libc::c_char, mut __n: size_t, mut __ps: *mut mbstate_t) -> size_t { + unsafe { + return if !__ps.is_null() { + mbrtowc(0 as *mut libc::wchar_t as *mut i32, __s, __n, __ps) + } else { + __mbrlen(__s, __n, 0 as *mut mbstate_t) + }; + } +} + +#[macro_export] +macro_rules! ADVANCE_CHAR { + ($_str:expr, $_strsize:expr, $_i:expr,$state:expr) => { + if locale_mb_cur_max > 1 { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + + _f = is_basic(*$_str.offset($_i as isize)); + if _f != 0 { + mblength = 1 as size_t; + } else if locale_utf8locale != 0 + && *$_str.offset($_i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = + (*$_str.offset($_i as isize) as libc::c_int != 0) as libc::c_int as size_t; + } else { + state_bak = $state; + mblength = mbrlen( + $_str.offset($_i as isize), + $_strsize.wrapping_sub($_i as libc::c_ulong), + &mut $state, + ) as u64; + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + $state = state_bak; + $_i += 1; + } else if mblength == 0 as libc::c_ulong { + $_i += 1; + } else { + $_i = ($_i as libc::c_ulong).wrapping_add(mblength) as libc::c_int; + } + } else { + $_i += 1; + } + }; +} + +#[macro_export] +macro_rules! WORDDELIM { + ($c:expr) => { + (*sh_syntaxtab + .as_mut_ptr() + .offset($c as libc::c_uchar as isize) + & 0x1 as libc::c_int + != 0 + || *sh_syntaxtab + .as_mut_ptr() + .offset($c as libc::c_uchar as isize) + & 0x2000 as libc::c_int + != 0) + }; +} + +#[macro_export] +macro_rules! COMMAND_SEPARATORS { + () => { + b";|&{(`\0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! member { + ($c:expr,$s:expr) => { + (if *$c as libc::c_int != 0 { + (mbschr($s, $c as libc::c_int) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + }; +} + +#[macro_export] +macro_rules! INITIALWORD { + () => { + b"_InitialWorD_\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! EMPTYCMD { + () => { + b"_EmptycmD_\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! DEFCOMP_CMDPOS { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! CMD_IS_DIR { + ($x:expr) => { + absolute_pathname($x) == 0 as libc::c_int + && absolute_program($x) == 0 as libc::c_int + && *$x as libc::c_int != '~' as i32 + && test_for_directory($x) != 0 + }; +} + +#[macro_export] +macro_rules! TAB { + () => { + '\t' as i32 + }; +} + +#[macro_export] +macro_rules! UNDO_BEGIN { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! UNDO_END { + () => { + 3 + }; +} + +#[macro_export] +macro_rules! Q_HERE_DOCUMENT { + () => { + 0x002 + }; +} + +#[macro_export] +macro_rules! PATH_CHECKDOTDOT { + () => { + 0x0001 + }; +} + +#[macro_export] +macro_rules! PATH_CHECKEXISTS { + () => { + 0x0002 + }; +} + +#[macro_export] +macro_rules! GLOB_FAILED { + ($glist:expr) => { + $glist == &mut glob_error_return as *mut *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! CBSDQUOTE { + () => { + 0x0040 + }; +} + +#[macro_export] +macro_rules! COMPLETE_BSQUOTE { + () => { + 3 + }; +} + +#[macro_export] +macro_rules! COMPLETE_SQUOTE { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! COMPLETE_DQUOTE { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! MB_CUR_MAX { + ($s:expr) => { + if !$s.is_null() && *$s.offset(0 as isize) as libc::c_int != 0 { + if *$s.offset(1 as isize) as libc::c_int != 0 { + mbstrlen($s) as usize + } else { + 1 as usize + } + } else { + 0 as usize + } + }; +} + +#[macro_export] +macro_rules! MBSLEN { + ($s:expr) => { + if !$s.is_null() && *$s.offset(0 as isize) as libc::c_int != 0 { + if *$s.offset(1 as isize) as libc::c_int != 0 { + mbstrlen($s) as i32 + } else { + 1 + } + } else { + 0 + } + }; +} + +#[macro_export] +macro_rules! MB_STRLEN { + ($s:expr) => { + if MB_CUR_MAX!($s) > 1 { + MBSLEN!($s) + } else { + STRLEN!($s) + } + }; +} + +//bashline +#[macro_export] +macro_rules! VSETATTR_1 { + ($var:expr,$attr:expr) => { + (*$var).attributes = (*$var).attributes | (&$attr); + (*$var).attributes + }; +} + +//arrayfunc +#[macro_export] +macro_rules! VSETATTR { + ($var:expr,$attr:expr) => { + (*$var).attributes |= ($attr) as libc::c_int; + // (*$var).attributes + }; +} + +#[macro_export] +macro_rules! ESC { + () => { + CTRL!('[' as i32) + }; +} + +//brace +pub const _ISdigit: libc::c_uint = 2048; + +#[macro_export] +macro_rules! ST_BAD { + () => { + 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! ST_INT { + () => { + 1 as libc::c_int + }; +} + +#[macro_export] +macro_rules! ST_CHAR { + () => { + 2 as libc::c_int + }; +} + +#[macro_export] +macro_rules! ST_ZINT { + () => { + 3 as libc::c_int + }; +} + +#[macro_export] +macro_rules! INTMAX_MIN { + () => { + -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long + }; +} + +#[macro_export] +macro_rules! INTMAX_MAX { + () => { + 9223372036854775807 as libc::c_long - 2 as libc::c_int as libc::c_long + }; +} + +#[macro_export] +macro_rules! ERANGE { + () => { + 34 as libc::c_int + }; +} +#[macro_export] +macro_rules! BRACE_SEQ_SPECIFIER { + () => { + b"..\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! INT_MAX { + () => { + 2147483647 as libc::c_int as libc::c_long + }; +} + +#[macro_export] +macro_rules! INT_MIN { + () => { + (-(2147483647 as libc::c_int) - 1 as libc::c_int) as libc::c_long + }; +} + +#[macro_export] +macro_rules! sh_imaxabs { + ($x:expr) => { + if $x >= 0 as libc::c_int as libc::c_long { + $x + } else { + -$x + } + }; +} + +#[macro_export] +macro_rules! SIZEOF_fUNC { + ($t:ty) => { + std::mem::size_of::<$t>() + }; +} + +#[macro_export] +macro_rules! TYPE_WIDTH { + ($t:ty) => { + (SIZEOF_fUNC!($t) * CHAR_BIT as usize) as $t + }; +} + +#[macro_export] +macro_rules! TYPE_SIGNED { + ($t:ty) => { + if 0 as $t < (-1) as libc::c_int as $t { + 0 as $t + } + else { + 1 as $t + } + } +} + +#[macro_export] +macro_rules! INT_STRLEN_BOUND { + ($t:ty) => { + (std::mem::size_of::<$t>() * CHAR_BIT as usize) + - TYPE_SIGNED!($t) as usize * 302 as usize / 1000 as usize + + 1 as usize + + TYPE_SIGNED!($t) as usize + }; +} + +#[macro_export] +macro_rules! SUBOVERFLOW { + ($a:expr,$b:expr,$minv:expr,$maxv:expr) => { + ($b > 0 as libc::c_long && $a < ($minv + $b)) + || ($b < 0 as libc::c_long && $a < ($maxv + $b)) + }; +} + +#[macro_export] +macro_rules! ADDOVERFLOW { + ($a:expr,$b:expr,$minv:expr,$maxv:expr) => { + ($a > 0 as libc::c_long && $b > ($maxv - $a)) + || ($a < 0 as libc::c_long && $b < ($minv + $a)) + }; +} + +#[macro_export] +macro_rules! brace_whitespace { + ($c:expr) => { + $c == 0 + || $c as libc::c_int == ' ' as i32 + || $c as libc::c_int == '\t' as i32 + || $c as libc::c_int == '\n' as i32 + }; +} + +#[macro_export] +macro_rules! ISALPHA { + ($c:expr) => { + IN_CTYPE_DOMAIN!($c) && isalpha!($c) != 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! ISDIGIT { + ($c:expr) => { + IN_CTYPE_DOMAIN!($c) && isdigit!($c) != 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! isalpha { + ($c:expr) => { + __isctype_f!($c, _ISalpha) + }; +} + +#[macro_export] +macro_rules! isdigit { + ($c:expr) => { + __isctype_f!($c, _ISdigit) + }; +} + +#[macro_export] +macro_rules! __isctype_f { + ($c:expr,$type:expr) => { + *(*__ctype_b_loc()).offset($c as libc::c_int as isize) as libc::c_int + & ($type as libc::c_int as libc::c_ushort as libc::c_int) + }; +} + +#[macro_export] +macro_rules! IN_CTYPE_DOMAIN { + ($c:expr) => { + 1 as libc::c_int != 0 as libc::c_int + }; +} + +//bracecomp +pub type rl_compentry_func_t = fn(*const libc::c_char, libc::c_int) -> *mut libc::c_char; + +pub type rl_completion_func_t = + fn(*const libc::c_char, libc::c_int, libc::c_int) -> *mut *mut libc::c_char; + +pub type rl_quote_func_t = + fn(*mut libc::c_char, libc::c_int, *mut libc::c_char) -> *mut libc::c_char; + +pub type rl_compignore_func_t = fn(*mut *mut libc::c_char) -> libc::c_int; + +//copycmd +pub const r_append_err_and_out: r_instruction = 19; +pub const r_move_output_word: r_instruction = 18; +pub const r_move_input_word: r_instruction = 17; +pub const r_move_output: r_instruction = 16; +pub const r_move_input: r_instruction = 15; +pub const r_duplicating_output_word: r_instruction = 14; +pub const r_duplicating_input_word: r_instruction = 13; +pub const r_output_force: r_instruction = 12; +pub const r_input_output: r_instruction = 11; +pub const r_err_and_out: r_instruction = 10; +pub const r_close_this: r_instruction = 9; +pub const r_deblank_reading_until: r_instruction = 8; +pub const r_duplicating_output: r_instruction = 7; +pub const r_duplicating_input: r_instruction = 6; +pub const r_reading_string: r_instruction = 5; +pub const r_reading_until: r_instruction = 4; +pub const r_appending_to: r_instruction = 3; +pub const r_inputa_direction: r_instruction = 2; +pub const r_input_direction: r_instruction = 1; +pub const r_output_direction: r_instruction = 0; + +pub type command_type = libc::c_uint; +pub const cm_coproc: command_type = 14; +pub const cm_subshell: command_type = 13; +pub const cm_arith_for: command_type = 12; +pub const cm_cond: command_type = 11; +pub const cm_arith: command_type = 10; +pub const cm_group: command_type = 9; +pub const cm_until: command_type = 8; +pub const cm_function_def: command_type = 7; +pub const cm_connection: command_type = 6; +pub const cm_select: command_type = 5; +pub const cm_simple: command_type = 4; +pub const cm_if: command_type = 3; +pub const cm_while: command_type = 2; +pub const cm_case: command_type = 1; +pub const cm_for: command_type = 0; + +#[derive(Copy, Clone)] +#[repr(C)] +pub union REDIRECTEE { + pub dest: libc::c_int, + pub filename: *mut WordDesc, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct redirect { + pub next: *mut redirect, + pub redirector: REDIRECTEE, + pub rflags: libc::c_int, + pub flags: libc::c_int, + pub instruction: r_instruction, + pub redirectee: REDIRECTEE, + pub here_doc_eof: *mut libc::c_char, +} +pub type REDIRECT = redirect; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct command { + pub type_0: command_type, + pub flags: libc::c_int, + pub line: libc::c_int, + pub redirects: *mut REDIRECT, + pub value: command_value, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub union command_value { + pub For: *mut for_com, + pub Case: *mut case_com, + pub While: *mut while_com, + pub If: *mut if_com, + pub Connection: *mut connection, + pub Simple: *mut simple_com, + pub Function_def: *mut function_def, + pub Group: *mut group_com, + pub Select: *mut select_com, + pub Arith: *mut arith_com, + pub Cond: *mut cond_com, + pub ArithFor: *mut arith_for_com, + pub Subshell: *mut subshell_com, + pub Coproc: *mut coproc_com, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct coproc_com { + pub flags: libc::c_int, + pub name: *mut libc::c_char, + pub command: *mut COMMAND, +} +pub type COMMAND = command; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct subshell_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub command: *mut COMMAND, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct arith_for_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub init: *mut WordList, + pub test: *mut WordList, + pub step: *mut WordList, + pub action: *mut COMMAND, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct cond_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub type_0: libc::c_int, + pub op: *mut WordDesc, + pub left: *mut cond_com, + pub right: *mut cond_com, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct arith_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub exp: *mut WordList, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct select_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub name: *mut WordDesc, + pub map_list: *mut WordList, + pub action: *mut COMMAND, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct group_com { + pub ignore: libc::c_int, + pub command: *mut COMMAND, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct function_def { + pub flags: libc::c_int, + pub line: libc::c_int, + pub name: *mut WordDesc, + pub command: *mut COMMAND, + pub source_file: *mut libc::c_char, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct simple_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub words: *mut WordList, + pub redirects: *mut REDIRECT, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct connection { + pub ignore: libc::c_int, + pub first: *mut COMMAND, + pub second: *mut COMMAND, + pub connector: libc::c_int, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct if_com { + pub flags: libc::c_int, + pub test: *mut COMMAND, + pub true_case: *mut COMMAND, + pub false_case: *mut COMMAND, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct while_com { + pub flags: libc::c_int, + pub test: *mut COMMAND, + pub action: *mut COMMAND, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct case_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub word: *mut WordDesc, + pub clauses: *mut PATTERN_LIST, +} +pub type PATTERN_LIST = pattern_list; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct pattern_list { + pub next: *mut pattern_list, + pub patterns: *mut WordList, + pub action: *mut COMMAND, + pub flags: libc::c_int, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct for_com { + pub flags: libc::c_int, + pub line: libc::c_int, + pub name: *mut WordDesc, + pub map_list: *mut WordList, + pub action: *mut COMMAND, +} +pub type CONNECTION = connection; +pub type CASE_COM = case_com; +pub type FOR_COM = for_com; +pub type ARITH_FOR_COM = arith_for_com; +pub type SELECT_COM = select_com; +pub type IF_COM = if_com; +pub type WHILE_COM = while_com; +pub type ARITH_COM = arith_com; +pub type COND_COM = cond_com; +pub type SIMPLE_COM = simple_com; +pub type FUNCTION_DEF = function_def; +pub type GROUP_COM = group_com; +pub type SUBSHELL_COM = subshell_com; +pub type COPROC_COM = coproc_com; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct g_list { + pub next: *mut g_list, +} + +//error +#[no_mangle] +pub static mut the_current_maintainer: *const libc::c_char = + b"bash-maintainers@gnu.org\0" as *const u8 as *const libc::c_char; + +//eval +#[macro_export] +macro_rules! setjmp_nosigs { + ($x:expr) => { + __sigsetjmp($x, 0) + }; +} + +pub type stream_type = libc::c_uint; +pub const st_bstream: stream_type = 4; +pub const st_string: stream_type = 3; +pub const st_stream: stream_type = 2; +pub const st_none: stream_type = 0; + +#[macro_export] +macro_rules! QUIT { + () => { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + }; +} + +//execute_cmd +#[macro_export] +macro_rules! FD_BITMAP_DEFAULT_SIZE { + () => { + 32 + }; +} + +#[macro_export] +macro_rules! DESCRIBE_PID { + ($pid:expr) => { + if interactive != 0 { + describe_pid($pid); + } + }; +} + +#[macro_export] +macro_rules! NO_PID { + () => { + -1 as libc::c_int + }; +} + +#[macro_export] +macro_rules! COPY_PROCENV { + ($old:expr, $save:expr) => { + xbcopy( + $old.as_mut_ptr() as *mut libc::c_char, + $save.as_mut_ptr() as *mut libc::c_char, + size_of::() as libc::c_ulong as libc::c_int, + ); + }; +} + +#[macro_export] +macro_rules! POSIX_TIMEFORMAT { + () => { + b"real %2R\nuser %2U\nsys %2S\0" as *const u8 as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! BASH_TIMEFORMAT { + () => { + b"\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS\0" as *const u8 as *const libc::c_char + as *mut libc::c_char; + }; +} + +#[macro_export] +macro_rules! CHECK_TERMSIG { + () => { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + }; +} + +pub unsafe fn DIGIT(c: libc::c_char) -> bool { + char::from(c as u8) >= '0' && char::from(c as u8) <= '9' +} + +pub type __rusage_who = libc::c_int; +pub const RUSAGE_THREAD: __rusage_who = 1; +pub const RUSAGE_CHILDREN: __rusage_who = -1; +pub const RUSAGE_SELF: __rusage_who = 0; + +#[no_mangle] +pub static mut stdin_redir: libc::c_int = 0; +#[no_mangle] +pub static mut this_command_name: *mut libc::c_char = 0 as *mut libc::c_char; +#[no_mangle] +pub static mut the_printed_command_except_trap: *mut libc::c_char = 0 as *mut libc::c_char; +#[no_mangle] +pub static mut return_catch_flag: libc::c_int = 0; +#[no_mangle] +pub static mut return_catch_value: libc::c_int = 0; +#[no_mangle] +pub static mut return_catch: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, +}; 1]; +#[no_mangle] +pub static mut last_command_exit_value: libc::c_int = 0; +#[no_mangle] +pub static mut last_command_exit_signal: libc::c_int = 0; +#[no_mangle] +pub static mut builtin_ignoring_errexit: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut redirection_undo_list: *mut REDIRECT = + 0 as *const libc::c_void as *mut libc::c_void as *mut REDIRECT; +#[no_mangle] +pub static mut exec_redirection_undo_list: *mut REDIRECT = + 0 as *const libc::c_void as *mut libc::c_void as *mut REDIRECT; +#[no_mangle] +pub static mut executing_builtin: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut executing_list: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut comsub_ignore_return: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut subshell_environment: libc::c_int = 0; +#[no_mangle] +pub static mut subshell_level: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut this_shell_function: *mut SHELL_VAR = 0 as *const SHELL_VAR as *mut SHELL_VAR; +#[no_mangle] +pub static mut match_ignore_case: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut executing_command_builtin: libc::c_int = 0 as libc::c_int; + +pub static mut special_builtin_failed: libc::c_int = 0; +pub static mut currently_executing_command: *mut COMMAND = 0 as *const COMMAND as *mut COMMAND; +pub static mut function_line_number: libc::c_int = 0; +pub static mut showing_function_line: libc::c_int = 0; +#[no_mangle] +pub static mut line_number_for_err_trap: libc::c_int = 0; +#[no_mangle] +pub static mut funcnest: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut funcnest_max: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut evalnest: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut evalnest_max: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut sourcenest: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut sourcenest_max: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut from_return_trap: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut lastpipe_opt: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut current_fds_to_close: *mut fd_bitmap = + 0 as *const libc::c_void as *mut libc::c_void as *mut fd_bitmap; + +#[no_mangle] +pub static mut sh_coproc: Coproc = { + let mut init = coproc { + c_name: 0 as *const libc::c_char as *mut libc::c_char, + c_pid: -(1 as libc::c_int), + c_rfd: -(1 as libc::c_int), + c_wfd: -(1 as libc::c_int), + c_rsave: 0 as libc::c_int, + c_wsave: 0 as libc::c_int, + c_flags: 0 as libc::c_int, + c_status: 0 as libc::c_int, + c_lock: 0 as libc::c_int, + }; + init +}; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct cpelement { + pub next: *mut cpelement, + pub coproc: *mut coproc, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct cplist { + pub head: *mut cpelement, + pub tail: *mut cpelement, + pub ncoproc: libc::c_int, + pub lock: libc::c_int, +} +pub type cplist_t = cplist; +#[no_mangle] +pub static mut coproc_list: cplist_t = { + let mut init = cplist { + head: 0 as *const cpelement as *mut cpelement, + tail: 0 as *const cpelement as *mut cpelement, + ncoproc: 0 as libc::c_int, + lock: 0, + }; + init +}; +#[macro_export] +macro_rules! SIG_BLOCK { + () => { + 0 + }; +} + +#[macro_export] +macro_rules! SIG_SETMASK { + () => { + 2 + }; +} + +//builtins目录下使用 +//BLOCK_CHILD å˜å½¢1 +#[macro_export] +macro_rules! BLOCK_CHILD_1 { + ($nvar:expr,$ovar:expr) => { + BLOCK_SIGNAL_1!(nix::sys::signal::SIGCHLD, $nvar, $ovar); + }; +} + +//UNBLOCK_CHILDçš„å˜å½¢1 +#[macro_export] +macro_rules! UNBLOCK_CHILD_1 { + ($ovar:expr) => { + UNBLOCK_SIGNAL_1!($ovar); + }; +} +//BLOCK_SIGNALçš„å˜å½¢1 +#[macro_export] +macro_rules! BLOCK_SIGNAL_1 { + ($sig:expr, $nvar:expr, $ovar:expr) => { + $nvar.unwrap().clear(); + $nvar.unwrap().add($sig); + $nvar.unwrap().clear(); + nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_BLOCK, $nvar, $ovar); + }; +} + +//UNBLOCK_SIGNALçš„å˜å½¢1 +#[macro_export] +macro_rules! UNBLOCK_SIGNAL_1 { + ($ovar:expr) => { + nix::sys::signal::sigprocmask(nix::sys::signal::SigmaskHow::SIG_SETMASK, $ovar, None) + }; +} + +//src目录下使用 +#[macro_export] +macro_rules! BLOCK_SIGNAL { + ($sig:expr, $nvar:expr, $ovar:expr) => { + sigemptyset(&mut $nvar); + sigaddset(&mut $nvar, $sig as libc::c_int); + sigemptyset(&mut $ovar); + sigprocmask(SIG_BLOCK!(), &mut $nvar, &mut $ovar); + }; +} +#[macro_export] +macro_rules! UNBLOCK_SIGNAL { + ($ovar:expr) => { + sigprocmask(SIG_SETMASK!(), &mut $ovar, 0 as *mut sigset_t) + }; +} + +#[macro_export] +macro_rules! att_nameref { + () => { + 0x0000800 + }; +} + +#[macro_export] +macro_rules! att_readonly { + () => { + 0x0000002 + }; +} + +#[macro_export] +macro_rules! att_noassign { + () => { + 0x0004000 + }; +} + +#[macro_export] +macro_rules! att_array { + () => { + 0x0000004 + }; +} + +#[macro_export] +macro_rules! get_job_by_jid { + ($ind:expr) => { + (*jobs).offset($ind as isize) + }; +} +#[macro_export] +macro_rules! INVALID_JOB { + ($j:expr) => { + ($j < 0 || $j >= js.j_jobslots || get_job_by_jid!($j) == 0 as *mut job) + }; +} + +#[macro_export] +macro_rules! REAP { + () => { + if job_control == 0 || interactive_shell == 0 { + reap_dead_jobs(); + } + }; +} + +#[macro_export] +macro_rules! name_cell { + ($var:expr) => { + ((*$var).name) + }; +} + +#[macro_export] +macro_rules! ifsname { + ($s:expr) => { + *$s.offset(0 as libc::c_int as isize) as libc::c_int == 'I' as i32 + && *$s.offset(1 as libc::c_int as isize) as libc::c_int == 'F' as i32 + && *$s.offset(2 as libc::c_int as isize) as libc::c_int == 'S' as i32 + && *$s.offset(3 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + }; +} + +#[macro_export] +macro_rules! NUMBER_LEN { + ($s:expr) => { + if $s < 10 { + 1 + } else if $s < 100 { + 2 + } else if $s < 1000 { + 3 + } else if $s < 10000 { + 4 + } else if $s < 100000 { + 5 + } else { + 6 + }; + }; +} + +#[macro_export] +macro_rules! RP_SPACE_LEN { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! FNMATCH_IGNCASE { + () => { + if match_ignore_case != 0 { + 1 << 4 + } else { + 0 + } + }; +} + +#[macro_export] +macro_rules! CMD_WHILE { + () => { + 0 + }; +} + +#[macro_export] +macro_rules! CMD_UNTIL { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! INPUT_REDIRECT { + ($ri:expr) => { + $ri == r_input_direction as libc::c_uint + || $ri == r_inputa_direction as libc::c_uint + || $ri == r_input_output as libc::c_uint + }; +} + +#[macro_export] +macro_rules! TRANSLATE_REDIRECT { + ($ri:expr) => { + $ri == r_duplicating_input_word + || $ri == r_duplicating_output_word + || $ri == r_move_input_word + || $ri == r_move_output_word + }; +} + +#[macro_export] +macro_rules! ISOPTION { + ($s:expr, $c:expr) => { + (*$s.offset(0 as isize) as libc::c_int == '-' as i32 + && *$s.offset(1 as isize) as libc::c_int == $c as i32 + && *$s.offset(2 as isize) == 0) + }; +} + +#[macro_export] +macro_rules! EX_REDIRFAIL { + () => { + 259 + }; +} + +#[macro_export] +macro_rules! EX_BADASSIGN { + () => { + 260 + }; +} + +#[macro_export] +macro_rules! EX_EXPFAIL { + () => { + 261 + }; +} + +#[macro_export] +macro_rules! EX_DISKFALLBACK { + () => { + 262 + }; +} + +#[macro_export] +macro_rules! TRAP_STRING { + ($s:expr) => { + if signal_is_trapped($s) != 0 && signal_is_ignored($s) == 0 { + *trap_list.as_mut_ptr().offset(($s) as isize) + } else { + 0 as *mut libc::c_char + } + }; +} + +#[macro_export] +macro_rules! array_pop { + ($a:expr) => { + array_dispose_element(array_shift(($a), 1, 0)); + }; +} + +#[macro_export] +macro_rules! GET_ARRAY_FROM_VAR { + ($n:expr, $v:expr, $a:expr) => { + $v = find_variable($n); + $a = if !$v.is_null() && array_p!($v) != 0 { + array_cell!($v) + } else { + 0 as *mut ARRAY + } + }; +} + +#[macro_export] +macro_rules! trace_p { + ($var:expr) => { + (*$var).attributes & att_trace as i32 + }; +} + +#[macro_export] +macro_rules! array_push { + ($a:expr, $v:expr) => { + array_rshift($a, 1, $v) + }; +} + +#[macro_export] +macro_rules! NOTFOUND_HOOK { + () => { + b"command_not_found_handle\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! vc_isbltnenv { + ($vc:expr) => { + (*$vc).flags & VC_BLTNENV as libc::c_int != 0 + }; +} + +#[macro_export] +macro_rules! ENOEXEC { + () => { + 8 + }; +} + +#[macro_export] +macro_rules! E2BIG { + () => { + 7 + }; +} + +#[macro_export] +macro_rules! ENOMEM { + () => { + 12 + }; +} + +#[macro_export] +macro_rules! EISDIR { + () => { + 21 + }; +} + +#[macro_export] +macro_rules! HASH_BANG_BUFSIZ { + () => { + 128 + }; +} + +#[macro_export] +macro_rules! READ_SAMPLE_BUF { + ($file:expr, $buf:expr, $len:expr) => { + let mut fd_0 = open($file, O_RDONLY as libc::c_int); + if fd_0 >= 0 { + $len = read( + fd_0, + $buf.as_mut_ptr() as *mut libc::c_void, + HASH_BANG_BUFSIZ!() as libc::c_int as usize, + ) as libc::c_int; + close(fd_0); + } else { + $len = -1; + } + }; +} + +#[macro_export] +macro_rules! CTLESC { + () => { + '\u{1}' as i32 + }; +} + +//expr +pub const EXP_EXPANDED: libc::c_int = 1; +pub const ASS_NOEXPAND: libc::c_int = 128; +pub const AV_NOEXPAND: libc::c_int = 0x20; +pub const EXECUTION_FAILURE: libc::c_int = 1; +pub const DISCARD: libc::c_int = 2; +pub const FORCE_EOF: libc::c_int = 1; +pub const PREINC: libc::c_int = 14; +pub const PREDEC: libc::c_int = 15; +pub const STR: libc::c_int = 5; +pub const NUM: libc::c_int = 6; +pub const POSTINC: libc::c_int = 16; +pub const POSTDEC: libc::c_int = 17; +pub const POWER: libc::c_int = 13; +pub const LSH: libc::c_int = 9; +pub const RSH: libc::c_int = 10; +pub const LEQ: libc::c_int = 3; +pub const GEQ: libc::c_int = 4; +pub const EQEQ: libc::c_int = 1; +pub const NEQ: libc::c_int = 2; +pub const LAND: libc::c_int = 7; +pub const LOR: libc::c_int = 8; +pub const COND: libc::c_int = 12; +pub const OP_ASSIGN: libc::c_int = 11; +pub const MAX_EXPR_RECURSION_LEVEL: libc::c_int = 1024; +pub const EXPR_STACK_GROW_SIZE: libc::c_int = 10; +pub const EQ: libc::c_int = '=' as libc::c_int; +pub const NOT: libc::c_char = '!' as libc::c_char; +pub const GT: libc::c_int = '>' as libc::c_int; +pub const LT: libc::c_int = '<' as libc::c_int; +pub const BAND: libc::c_char = '&' as libc::c_char; +pub const BOR: libc::c_char = '|' as libc::c_char; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct EXPR_CONTEXT { + pub curtok: libc::c_int, + pub lasttok: libc::c_int, + pub expression: *mut libc::c_char, + pub tp: *mut libc::c_char, + pub lasttp: *mut libc::c_char, + pub tokval: intmax_t, + pub tokstr: *mut libc::c_char, + pub noeval: libc::c_int, + pub lval: lvalue, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct lvalue { + pub tokstr: *mut libc::c_char, + pub tokval: intmax_t, + pub tokvar: *mut SHELL_VAR, + pub ind: intmax_t, +} + +//find_cmd +#[no_mangle] +pub static mut check_hashed_filenames: libc::c_int = CHECKHASH_DEFAULT as libc::c_int; +#[no_mangle] +pub static mut dot_found_in_search: libc::c_int = 0; + +#[macro_export] +macro_rules! FNM_EXTMATCH { + () => { + 1 << 5 + }; +} + +#[macro_export] +macro_rules! FNM_CASEFOLD { + () => { + 1 << 4 + }; +} + +#[macro_export] +macro_rules! __S_IFDIR { + () => { + 0o40000 + }; +} + +#[macro_export] +macro_rules! __S_IFMT { + () => { + 0o170000 + }; +} + +#[macro_export] +macro_rules! __S_ISTYPE { + ($mode:expr, $mask:expr) => { + $mode & __S_IFMT!() == $mask + }; +} + +#[macro_export] +macro_rules! S_ISDIR { + ($mode:expr) => { + __S_ISTYPE!($mode, __S_IFDIR!()) + }; +} + +#[macro_export] +macro_rules! att_tempvar { + () => { + 0x0100000 + }; +} + +#[macro_export] +macro_rules! tempvar_p { + ($var:expr) => { + (*$var).attributes & att_tempvar!() + }; +} + +//flags +#[derive(Copy, Clone)] +#[repr(C)] +pub struct flags_alist { + pub name: libc::c_char, + pub value: *mut libc::c_int, +} +#[no_mangle] +pub static mut mark_modified_vars: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut asynchronous_notification: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut errexit_flag: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut exit_immediately_on_error: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut disallow_filename_globbing: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut place_keywords_in_env: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut read_but_dont_execute: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut just_one_command: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut noclobber: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut unbound_vars_is_error: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut echo_input_at_read: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut verbose_flag: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut echo_command_at_execute: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut jobs_m_flag: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut forced_interactive: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut no_symbolic_links: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut hashing_enabled: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut history_expansion: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut histexp_flag: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut interactive_comments: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut restricted: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut restricted_shell: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut privileged_mode: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut brace_expansion: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut function_trace_mode: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut error_trace_mode: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut pipefail_opt: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut shell_flags: [flags_alist; 22] = unsafe { + [ + { + let mut init = flags_alist { + name: 'a' as i32 as libc::c_char, + value: &mark_modified_vars as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'b' as i32 as libc::c_char, + value: &asynchronous_notification as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'e' as i32 as libc::c_char, + value: &errexit_flag as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'f' as i32 as libc::c_char, + value: &disallow_filename_globbing as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'h' as i32 as libc::c_char, + value: &hashing_enabled as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'i' as i32 as libc::c_char, + value: &forced_interactive as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'k' as i32 as libc::c_char, + value: &place_keywords_in_env as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'm' as i32 as libc::c_char, + value: &jobs_m_flag as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'n' as i32 as libc::c_char, + value: &read_but_dont_execute as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'p' as i32 as libc::c_char, + value: &privileged_mode as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'r' as i32 as libc::c_char, + value: &restricted as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 't' as i32 as libc::c_char, + value: &just_one_command as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'u' as i32 as libc::c_char, + value: &unbound_vars_is_error as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'v' as i32 as libc::c_char, + value: &verbose_flag as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'x' as i32 as libc::c_char, + value: &echo_command_at_execute as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'B' as i32 as libc::c_char, + value: &brace_expansion as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'C' as i32 as libc::c_char, + value: &noclobber as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'E' as i32 as libc::c_char, + value: &error_trace_mode as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'H' as i32 as libc::c_char, + value: &histexp_flag as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'P' as i32 as libc::c_char, + value: &no_symbolic_links as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 'T' as i32 as libc::c_char, + value: &function_trace_mode as *const libc::c_int as *mut libc::c_int, + }; + init + }, + { + let mut init = flags_alist { + name: 0 as libc::c_int as libc::c_char, + value: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_int, + }; + init + }, + ] +}; +#[no_mangle] +pub static mut optflags: [libc::c_char; 26] = [ + '+' as i32 as libc::c_char, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +]; + +pub const FLAG_UNKNOWN: libc::c_int = 0; +pub const FLAG_OFF: std::os::raw::c_char = b'+' as std::os::raw::c_char; +pub const FLAG_ERROR: libc::c_int = -1; +pub const FLAG_ON: std::os::raw::c_char = b'-' as std::os::raw::c_char; + +//general +pub const _ISalnum: libc::c_int = 8; +pub const _ISblank: libc::c_int = 1; +pub const _CS_PATH: libc::c_int = 0; +pub const W_HASDOLLAR: libc::c_int = 1 << 0; +pub const W_QUOTED: libc::c_int = 1 << 1; +pub const CBLANK: libc::c_int = 0x2000; +pub const CSHBRK: libc::c_int = 0x0002; +pub const CXQUOTE: libc::c_int = 0x0400; +pub const F_GETFL: libc::c_int = 3; +pub const F_SETFL: libc::c_int = 4; +pub const O_NONBLOCK: libc::c_int = 0o4000; +pub const O_NDELAY: libc::c_int = 0o4000; +pub const F_SETFD: libc::c_int = 2; +pub const FD_CLOEXEC: libc::c_int = 1; +pub const F_GETFD: libc::c_int = 1; +pub const SEEK_CUR: libc::c_int = 1; +pub const ESPIPE: libc::c_int = 29; +pub const O_RDWR: libc::c_int = 0o2; +pub const HIGH_FD_MAX: libc::c_int = 256; +pub const W_OK: libc::c_int = 2; +pub const MP_DOCWD: libc::c_int = 0x02; +pub const MP_RMDOT: libc::c_int = 0x04; +pub const PATH_MAX: libc::c_int = 4096; + +pub type __off64_t = libc::c_long; +pub type _IO_lock_t = (); +pub type __off_t = libc::c_long; + +pub type __dev_t = libc::c_ulong; +pub type __uid_t = libc::c_uint; +pub type __gid_t = libc::c_uint; +pub type __ino_t = libc::c_ulong; +pub type __mode_t = libc::c_uint; +pub type __nlink_t = libc::c_ulong; +pub type __rlim_t = libc::c_ulong; +pub type __time_t = libc::c_long; +pub type __blksize_t = libc::c_long; +pub type __blkcnt_t = libc::c_long; +pub type __syscall_slong_t = libc::c_long; +pub type __sig_atomic_t = libc::c_int; +pub type gid_t = __gid_t; +pub type uid_t = __uid_t; +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, +} + +pub type sig_atomic_t = __sig_atomic_t; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct stat { + pub st_dev: __dev_t, + pub st_ino: __ino_t, + pub st_nlink: __nlink_t, + pub st_mode: __mode_t, + pub st_uid: __uid_t, + pub st_gid: __gid_t, + pub __pad0: libc::c_int, + pub st_rdev: __dev_t, + pub st_size: __off_t, + pub st_blksize: __blksize_t, + pub st_blocks: __blkcnt_t, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + pub __glibc_reserved: [__syscall_slong_t; 3], +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct user_info { + pub uid: uid_t, + pub euid: uid_t, + pub gid: gid_t, + pub egid: gid_t, + pub user_name: *mut libc::c_char, + pub shell: *mut libc::c_char, + pub home_dir: *mut libc::c_char, +} + +pub type rlim_t = __rlim_t; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct C2RustUnnamed_1 { + pub posix_mode_var: *mut libc::c_int, +} +pub type tilde_hook_func_t = fn(*mut libc::c_char) -> *mut libc::c_char; + +#[macro_export] +macro_rules! TODIGIT { + ($c:expr) => { + ($c as libc::c_int - '0' as i32) + }; +} + +#[macro_export] +macro_rules! shellblank { + ($c: expr) => { + (*sh_syntaxtab.as_mut_ptr().offset($c) & CBLANK) + }; +} +#[macro_export] +macro_rules! shellbreak { + ($c: expr) => { + (*sh_syntaxtab.as_mut_ptr().offset($c) & CSHBRK) + }; +} +#[macro_export] +macro_rules! shellxquote { + ($c: expr) => { + (*sh_syntaxtab.as_mut_ptr().offset($c) & CXQUOTE) + }; +} +#[macro_export] +macro_rules! shellexp { + ($c: expr) => { + ($c == '$' as i32 || $c == '<' as i32 || $c == '>' as i32) + }; +} +#[macro_export] +macro_rules! isblank { + ($c: expr) => { + (__isctype_f!(($c), _ISblank)) + }; +} + +#[macro_export] +macro_rules! PATHSEP { + ($c: expr) => { + (ISDIRSEP!($c) || ($c) == 0) + }; +} +#[macro_export] +macro_rules! ISDIRSEP { + ($c: expr) => { + (($c) == '/' as i32) + }; +} +#[macro_export] +macro_rules! ABSPATH { + ($c: expr) => { + (*$c.offset(0 as libc::c_int as isize) as libc::c_int == '/' as i32) + }; +} +#[macro_export] +macro_rules! TILDE_END { + ($c: expr) => { + (($c) == '\0' as i32 || ($c) == '/' as i32 || ($c) == ':' as i32) + }; +} + +#[macro_export] +macro_rules! STANDARD_UTILS_PATH { + () => { + (b"/bin:/usr/bin:/usr/sbin:/sbin\0" as *const u8 as *const libc::c_char) + }; +} + +//hashcmd +#[no_mangle] +pub static mut hashed_filenames: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +//hashlib +#[macro_export] +macro_rules! HASH_ENTRIES { + ($ht:expr) => { + if !$ht.is_null() { + (*$ht).nentries + } else { + 0 as libc::c_int + }; + }; +} + +#[macro_export] +macro_rules! HASH_REHASH_MULTIPLIER { + () => { + 4 + }; +} + +#[macro_export] +macro_rules! FNV_OFFSET { + () => { + 2166136261 + }; +} + +#[macro_export] +macro_rules! FNV_PRIME { + () => { + 16777619 + }; +} + +#[macro_export] +macro_rules! HASH_BUCKET { + ($s:expr, $t:expr, $h:expr) => {{ + $h = hash_string($s); + $h & (((*$t).nbuckets - 1) as libc::c_uint) + }}; +} + +#[macro_export] +macro_rules! HASH_REHASH_FACTOR { + () => { + 2 + }; +} + +#[macro_export] +macro_rules! HASH_SHOULDGROW { + ($table:expr) => { + (*$table).nentries >= (*$table).nbuckets * HASH_REHASH_FACTOR!() + }; +} + +//input +pub const EAGAIN: libc::c_int = 11; +pub const X_EAGAIN: libc::c_int = EAGAIN; +pub const EWOULDBLOCK: libc::c_int = EAGAIN; +pub const X_EWOULDBLOCK: libc::c_int = EAGAIN; +pub const EINTR: libc::c_int = 4; +pub const B_UNBUFF: libc::c_int = 0x04; +pub const O_TEXT: libc::c_int = 0; +pub const B_TEXT: libc::c_int = 0x10; +pub const MAX_INPUT_BUFFER_SIZE: libc::c_int = 8172; +pub const O_RDONLY: libc::c_int = 0; +pub const EBADF: libc::c_int = 9; +pub type __ssize_t = libc::c_long; +pub type off_t = __off_t; +pub type ssize_t = __ssize_t; +pub type sh_cget_func_t = fn() -> libc::c_int; +pub type sh_cunget_func_t = fn(libc::c_int) -> libc::c_int; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct BSTREAM { + pub b_fd: libc::c_int, + pub b_buffer: *mut libc::c_char, + pub b_size: size_t, + pub b_used: size_t, + pub b_flag: libc::c_int, + pub b_inputp: size_t, +} +pub type BUFFERED_STREAM = BSTREAM; +#[derive(Copy, Clone)] +#[repr(C)] +pub union INPUT_STREAM { + pub file: *mut FILE, + pub string: *mut libc::c_char, + pub buffered_fd: libc::c_int, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct BASH_INPUT { + pub type_0: stream_type, + pub name: *mut libc::c_char, + pub location: INPUT_STREAM, + pub getter: Option, + pub ungetter: Option, +} + +#[macro_export] +macro_rules! ALLOCATE_BUFFERS { + ($n:expr) => { + if $n >= nbuffers { + allocate_buffers($n); + } + }; +} + +#[macro_export] +macro_rules! max { + ($a: expr, $b: expr) => { + if $a > $b { + $a + } else { + $b + } + }; +} +#[macro_export] +macro_rules! min { + ($a: expr, $b: expr) => { + if $a > $b { + $b + } else { + $a + } + }; +} +#[macro_export] +macro_rules! fd_is_seekable { + ($fd: expr) => { + lseek($fd, 0 as libc::c_long, SEEK_CUR) >= 0 as libc::c_long + }; +} +#[macro_export] +macro_rules! bufstream_getc { + ($bp: expr) => { + if ($bp).b_inputp == ($bp).b_used || ($bp).b_used == 0 { + b_fill_buffer(*buffers.offset(bash_input.location.buffered_fd as isize)) + } else { + let ref mut fresh10 = + (**buffers.offset(bash_input.location.buffered_fd as isize)).b_inputp; + let fresh11 = *fresh10; + *fresh10 = (*fresh10).wrapping_add(1); + *(($bp).b_buffer).offset(fresh11 as isize) as libc::c_int & 0xff as libc::c_int + } + }; +} + +//jobs +#[macro_export] +macro_rules! SIG_IGN { + () => { + ::std::mem::transmute::(1 as libc::c_int as libc::intptr_t) + }; +} + +#[macro_export] +macro_rules! SIG_DFL { + () => { + ::std::mem::transmute::(0 as libc::c_int as libc::intptr_t) + }; +} + +pub type sigjmp_buf = [__jmp_buf_tag; 1]; +pub type __jmp_buf = [libc::c_long; 8]; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct __jmp_buf_tag { + pub __jmpbuf: __jmp_buf, + pub __mask_was_saved: libc::c_int, + pub __saved_mask: __sigset_t, +} + +pub const DEFAULT_CHILD_MAX: u32 = 4096; +pub const MAX_CHILD_MAX: u32 = 32768; +pub const MAX_JOBS_IN_ARRAY: u32 = 4096; +pub const r_pidstat_table_SZ: i32 = 4096; +pub const BGPIDS_TABLE_SZ: u32 = 512; +pub const DEL_WARNSTOPPED: u32 = 1; +pub const DEL_NOBGPID: u32 = 2; +pub const JOB_SLOTS: u32 = 8; +pub const NO_PIDSTAT: i32 = -1; +pub const NO_PID: pid_t = -1; + +pub const EX_NOEXEC: i32 = 126; + +pub const ECHILD: i32 = 10; + +#[macro_export] +macro_rules! PRECYCLED { + ($p:expr) => { + 0 + }; +} + +#[macro_export] +macro_rules! __WIFSTOPPED { + ($status:expr) => { + (($status) & 0xff) == 0x7f + }; +} + +#[macro_export] +macro_rules! WIFSTOPPED { + ($status:expr) => { + (($status) & 0xff) == 0x7f + }; +} + +#[macro_export] +macro_rules! PSTOPPED { + ($p:expr) => { + WIFSTOPPED!((*$p).status) + }; +} + +#[macro_export] +macro_rules! PRUNNING { + ($p:expr) => { + (*$p).running == PS_RUNNING as libc::c_int + }; +} + +#[macro_export] +macro_rules! PALIVE { + ($p:expr) => { + PRUNNING!($p) || PSTOPPED!($p) + }; +} + +#[macro_export] +macro_rules! WAITPID { + ($pid:expr, $statusp:expr, $options:expr) => { + waitpid($pid as pid_t, $statusp, $options); + }; +} + +#[macro_export] +macro_rules! getpgid { + ($p:expr) => { + getpgpr(); + }; +} + +#[macro_export] +macro_rules! REINSTALL_SIGCHLD_HANDLER { + () => {}; +} + +pub type sh_job_map_func_t = fn(*mut JOB, libc::c_int, libc::c_int, libc::c_int) -> libc::c_int; + +pub static mut zerojs: jobstats = { + let mut init = jobstats { + c_childmax: -(1 as libc::c_long), + c_living: 0 as libc::c_int, + c_reaped: 0 as libc::c_int, + c_injobs: 0 as libc::c_int, + c_totforked: 0 as libc::c_int, + c_totreaped: 0 as libc::c_int, + j_jobslots: 0 as libc::c_int, + j_lastj: 0 as libc::c_int, + j_firstj: 0 as libc::c_int, + j_njobs: 0 as libc::c_int, + j_ndead: 0 as libc::c_int, + j_current: -(1 as libc::c_int), + j_previous: -(1 as libc::c_int), + j_lastmade: 0 as *const JOB as *mut JOB, + j_lastasync: 0 as *const JOB as *mut JOB, + }; + init +}; + +#[no_mangle] +pub static mut js: jobstats = { + let mut init = jobstats { + c_childmax: -(1 as libc::c_long), + c_living: 0 as libc::c_int, + c_reaped: 0 as libc::c_int, + c_injobs: 0 as libc::c_int, + c_totforked: 0 as libc::c_int, + c_totreaped: 0 as libc::c_int, + j_jobslots: 0 as libc::c_int, + j_lastj: 0 as libc::c_int, + j_firstj: 0 as libc::c_int, + j_njobs: 0 as libc::c_int, + j_ndead: 0 as libc::c_int, + j_current: -(1 as libc::c_int), + j_previous: -(1 as libc::c_int), + j_lastmade: 0 as *const JOB as *mut JOB, + j_lastasync: 0 as *const JOB as *mut JOB, + }; + init +}; + +#[no_mangle] +pub static mut r_pidstat_table: [ps_index_t; 4096] = [0; 4096]; + +pub static mut bgpids: bgpids = { + let init = bgpids { + storage: 0 as *const pidstat as *mut pidstat, + head: 0 as ps_index_t, + nalloc: 0 as ps_index_t, + npid: 0 as libc::c_int, + }; + init +}; + +pub static mut procsubs: procchain = { + let mut init = procchain { + head: 0 as *mut PROCESS, + end: 0 as *mut PROCESS, + nproc: 0 as libc::c_int, + }; + init +}; + +#[no_mangle] +pub static mut wait_intr_buf: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0 as libc::c_int, + __saved_mask: __sigset_t { + __val: [0; 16usize], + }, +}]; + +#[no_mangle] +pub static mut jobs: *mut *mut JOB = 0 as *const libc::c_void as *mut libc::c_void as *mut *mut JOB; + +#[no_mangle] +pub static mut shell_tty: libc::c_int = -1; +#[no_mangle] +pub static mut shell_pgrp: pid_t = -1 as libc::c_int; +pub static mut terminal_pgrp: pid_t = -1; +#[no_mangle] +pub static mut original_pgrp: pid_t = -1; +#[no_mangle] +pub static mut pipeline_pgrp: pid_t = 0 as pid_t; + +#[no_mangle] +pub static mut pgrp_pipe: [libc::c_int; 2] = [-1 as libc::c_int, -1 as libc::c_int]; +#[no_mangle] +pub static mut last_made_pid: pid_t = -1; +#[no_mangle] +pub static mut last_asynchronous_pid: pid_t = -1; +#[no_mangle] +pub static mut the_pipeline: *mut PROCESS = + 0 as *const libc::c_void as *mut libc::c_void as *mut PROCESS; +#[no_mangle] +pub static mut job_control: libc::c_int = 1; +#[no_mangle] +pub static mut running_in_background: libc::c_int = 0; +#[no_mangle] +pub static mut already_making_children: libc::c_int = 0; +#[no_mangle] +pub static mut check_window_size: libc::c_int = CHECKWINSIZE_DEFAULT as i32; +#[no_mangle] +pub static mut last_procsub_child: *mut PROCESS = + 0 as *const libc::c_void as *mut libc::c_void as *mut PROCESS; + +pub static mut pstatuses: *mut libc::c_int = 0 as *mut libc::c_int; +pub static mut statsize: libc::c_int = 0; + +pub static mut sigchld: libc::c_int = 0; +pub static mut queue_sigchld: libc::c_int = 0; + +#[macro_export] +macro_rules! QUEUE_SIGCHLD { + ($os:expr) => { + $os = sigchld; + queue_sigchld += 1; + }; +} + +#[macro_export] +macro_rules! DEADJOB { + ($j:expr) => { + (**jobs.offset($j as isize)).state as libc::c_int == JDEAD + }; +} + +#[macro_export] +macro_rules! IS_NOTIFIED { + ($j:expr) => { + (**jobs.offset($j as isize)).flags & J_NOTIFIED as libc::c_int != 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! JOBSTATE { + ($job:expr) => { + (**jobs.offset($job as isize)).state + }; +} + +#[macro_export] +macro_rules! STOPPED { + ($job:expr) => { + (**jobs.offset($job as isize)).state == JSTOPPED + }; +} + +pub const JMIXED: JOB_STATE = 8; +pub const JDEAD: JOB_STATE = 4; +pub const JSTOPPED: JOB_STATE = 2; +pub const JRUNNING: JOB_STATE = 1; +pub const JNONE: JOB_STATE = -1; + +pub static mut old_tstp: Option = None; +pub static mut old_ttou: Option = None; +pub static mut old_ttin: Option = None; +pub static mut old_cont: Option = None; //bgz +pub static mut saved_pipeline: *mut pipeline_saver = 0 as *mut pipeline_saver; +pub static mut saved_already_making_children: libc::c_int = 0; + +pub static mut jobs_list_frozen: libc::c_int = 0; +pub static mut retcode_name_buffer: [libc::c_char; 64] = [0; 64]; + +macro_rules! TYPE_WIDTH { + ($t:ty) => { + std::mem::size_of::<$t>() * 8 + }; +} + +macro_rules! TYPE_SIGNED_1 { + ($t:ty) => { + !(0 as $t < -1 as $t) + }; +} + +macro_rules! TYPE_MAXIMUM { + ($t:ty) => { + if !TYPE_SIGNED_1!($t){ + -1 as $t + } else { + (((1 as $t << (TYPE_WIDTH!($t) -2)) -1) * 2 + 1) + } + + } +} + +#[macro_export] +macro_rules! WSTOPSIG { + ($status:expr) => { + ($status & 0xff00) >> 8 + }; +} + +#[macro_export] +macro_rules! RUNNING { + ($j:expr) => { + (**jobs.offset($j as isize)).state as libc::c_int == JRUNNING + }; +} + +#[macro_export] +macro_rules! WIFSIGNALED { + ($status:expr) => { + ((($status) & 0x7f) + 1) >> 1 > 0 + }; +} + +#[macro_export] +macro_rules! WTERMSIG { + ($status:expr) => { + ($status) & 0x7f + }; +} + +#[macro_export] +macro_rules! WIFEXITED { + ($status:expr) => { + ($status) & 0x7f == 0 + }; +} + +#[macro_export] +macro_rules! WEXITSTATUS { + ($status:expr) => { + (($status) & 0xff00) >> 8 + }; +} + +#[macro_export] +macro_rules! WSTATUS { + ($t:expr) => { + $t + }; +} + +#[macro_export] +macro_rules! WIFCONTINUED { + ($status:expr) => { + $status == 0xffff + }; +} + +#[macro_export] +macro_rules! WIFCORED { + ($status:expr) => { + $status == 0x80 + }; +} + +#[macro_export] +macro_rules! J_FOREGROUND { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! IS_FOREGROUND { + ($j:expr) => { + (**jobs.offset($j as isize)).flags & J_FOREGROUND!() != 0 + }; +} + +#[macro_export] +macro_rules! CLRINTERRUPT { + () => { + interrupt_state = 0 + }; +} + +#[macro_export] +macro_rules! input_tty { + () => { + if shell_tty != -1 { + shell_tty + } else { + fileno(stderr) + } + }; +} + +#[macro_export] +macro_rules! CHECK_WAIT_INTR { + () => { + if wait_intr_flag != 0 + && wait_signal_received != 0 + && this_shell_builtin.is_some() + && this_shell_builtin == (Some(wait_builtin)) + { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + }; +} + +#[no_mangle] +pub static mut waiting_for_child: libc::c_int = 0; + +pub type SigHandler1 = Option; + +pub const ANY_PID: pid_t = -1; +#[macro_export] +macro_rules! IS_JOBCONTROL { + ($job:expr) => { + (**jobs.offset($job as isize)).flags & 0x4 as libc::c_int != 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! RL_ISSTATE { + ($x:expr) => { + rl_readline_state & ($x) + }; +} +#[macro_export] +macro_rules! RL_STATE_COMPLETING { + () => { + 0x0004000 + }; +} + +#[macro_export] +macro_rules! ADDINTERRUPT { + () => { + interrupt_state += 1 + }; +} + +#[macro_export] +macro_rules! IS_WAITING { + ($i:expr) => { + (**jobs.offset($i as isize)).flags & 0x80 as libc::c_int != 0 as libc::c_int + }; +} + +pub type cc_t = libc::c_uchar; +pub type speed_t = libc::c_uint; +pub type tcflag_t = libc::c_uint; + +#[macro_export] +macro_rules! PEXITED { + ($p:expr) => { + (*$p).running == 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! sh_longjmp { + ($x:expr,$n:expr) => { + siglongjmp($x, $n as libc::c_int) + }; +} + +pub const EINVAL: i32 = 22; + +#[macro_export] +macro_rules! IMPOSSIBLE_TRAP_HANDLER { + () => { + initialize_traps as *mut SigHandler + }; +} + +#[macro_export] +macro_rules! IGNORE_SIG { + () => { + SIG_IGN!() + }; +} + +pub const SEVAL_NOHIST: libc::c_int = 0x004; +pub const SEVAL_RESETLINE: libc::c_int = 0x010; + +#[macro_export] +macro_rules! SET_CLOSE_ON_EXEC { + ($fd:expr) => { + libc::fcntl(($fd), F_SETFD, FD_CLOEXEC) + }; +} + +pub const ENOTTY: i32 = 25; + +//list +pub type GENERIC_LIST = g_list; +#[no_mangle] +pub static mut global_error_list: GENERIC_LIST = g_list { + next: 0 as *const g_list as *mut g_list, +}; + +//local +#[derive(Copy, Clone)] +#[repr(C)] +pub struct lconv { + pub decimal_point: *mut libc::c_char, + pub thousands_sep: *mut libc::c_char, + pub grouping: *mut libc::c_char, + pub int_curr_symbol: *mut libc::c_char, + pub currency_symbol: *mut libc::c_char, + pub mon_decimal_point: *mut libc::c_char, + pub mon_thousands_sep: *mut libc::c_char, + pub mon_grouping: *mut libc::c_char, + pub positive_sign: *mut libc::c_char, + pub negative_sign: *mut libc::c_char, + pub int_frac_digits: libc::c_char, + pub frac_digits: libc::c_char, + pub p_cs_precedes: libc::c_char, + pub p_sep_by_space: libc::c_char, + pub n_cs_precedes: libc::c_char, + pub n_sep_by_space: libc::c_char, + pub p_sign_posn: libc::c_char, + pub n_sign_posn: libc::c_char, + pub int_p_cs_precedes: libc::c_char, + pub int_p_sep_by_space: libc::c_char, + pub int_n_cs_precedes: libc::c_char, + pub int_n_sep_by_space: libc::c_char, + pub int_p_sign_posn: libc::c_char, + pub int_n_sign_posn: libc::c_char, +} + +#[no_mangle] +pub static mut locale_utf8locale: libc::c_int = 0; +#[no_mangle] +pub static mut locale_mb_cur_max: libc::c_int = 0; +#[no_mangle] +pub static mut locale_shiftstates: libc::c_int = 0 as libc::c_int; +pub static mut default_locale: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +pub static mut default_domain: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +pub static mut default_dir: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +pub static mut lc_all: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +pub static mut lang: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; + +pub const LC_ALL: libc::c_int = 6; +pub const STR_LC_ALL: *const libc::c_char = b"LC_ALL\0" as *const u8 as *const libc::c_char; +pub const STR_LC_CTYPE: *const libc::c_char = b"LC_CTYPE\0" as *const u8 as *const libc::c_char; +pub const STR_LC_COLLATE: *const libc::c_char = b"LC_COLLATE\0" as *const u8 as *const libc::c_char; +pub const STR_LC_MESSAGES: *const libc::c_char = + b"LC_MESSAGES\0" as *const u8 as *const libc::c_char; +pub const STR_LC_NUMERIC: *const libc::c_char = b"LC_NUMERIC\0" as *const u8 as *const libc::c_char; +pub const STR_LC_TIME: *const libc::c_char = b"LC_TIME\0" as *const u8 as *const libc::c_char; + +pub const STR_TEXTDOMAIN: *const libc::c_char = b"TEXTDOMAIN\0" as *const u8 as *const libc::c_char; +pub const STR_TEXTDOMAINDIR: *const libc::c_char = + b"TEXTDOMAINDIR\0" as *const u8 as *const libc::c_char; + +pub const STR_PACKAGE: *const libc::c_char = b"utshell\0" as *const u8 as *const libc::c_char; +pub const STR_LOCALEDIR: *const libc::c_char = + b"/usr/local/share/locale\0" as *const u8 as *const libc::c_char; + +//mainlcheck +pub static MBOX_INITIALIZED: libc::c_int = 0x01; + +#[macro_export] +macro_rules! UPDATE_MAIL_FILE { + ($i:expr, $finfo:expr) => { + (**mailfiles.offset($i as isize)).access_time = $finfo.st_atim.tv_sec; + (**mailfiles.offset($i as isize)).mod_time = $finfo.st_mtim.tv_sec; + (**mailfiles.offset($i as isize)).file_size = $finfo.st_size; + (**mailfiles.offset($i as isize)).flags |= MBOX_INITIALIZED; + }; +} + +#[macro_export] +macro_rules! RESET_MAIL_FILE { + ($i:expr) => { + let ref mut fresh1 = (**mailfiles.offset($i as isize)).mod_time; + *fresh1 = 0 as libc::c_int as time_t; + (**mailfiles.offset($i as isize)).access_time = *fresh1; + (**mailfiles.offset($i as isize)).file_size = 0 as libc::c_int as off_t; + (**mailfiles.offset($i as isize)).flags = 0 as libc::c_int; + }; +} + +pub const DEFAULT_MAIL_DIRECTORY: *const libc::c_char = + b"/var/mail\0" as *const u8 as *const libc::c_char; + +pub type time_t = libc::c_long; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct FILEINFO { + pub name: *mut libc::c_char, + pub msg: *mut libc::c_char, + pub access_time: time_t, + pub mod_time: time_t, + pub file_size: off_t, + pub flags: libc::c_int, +} + +pub static mut mailfiles: *mut *mut FILEINFO = + 0 as *const libc::c_void as *mut libc::c_void as *mut *mut FILEINFO; +pub static mut mailfiles_count: libc::c_int = 0; +pub static mut last_time_mail_checked: time_t = 0 as libc::c_int as time_t; +#[no_mangle] +pub static mut mail_warning: libc::c_int = 0; + +//utshell.rs +pub type rl_voidfunc_t = fn() -> (); + +#[no_mangle] +pub static mut shell_initialized: libc::c_int = 0; +#[no_mangle] +pub static mut bash_argv_initialized: libc::c_int = 0; +#[no_mangle] +pub static mut global_command: *mut COMMAND = 0 as *mut COMMAND; +#[no_mangle] +pub static mut current_user: user_info = { + let init = user_info { + uid: -(1 as libc::c_int) as uid_t, + euid: -(1 as libc::c_int) as uid_t, + gid: -(1 as libc::c_int) as gid_t, + egid: -(1 as libc::c_int) as gid_t, + user_name: 0 as *mut libc::c_char, + shell: 0 as *mut libc::c_char, + home_dir: 0 as *mut libc::c_char, + }; + init +}; +#[no_mangle] +pub static mut current_host_name: *mut libc::c_char = 0 as *mut libc::c_char; +/* Non-zero means that this shell is a login shell. + Specifically: + 0 = not login shell. + 1 = login shell from getty (or equivalent fake out) + -1 = login shell from "--login" (or -l) flag. + -2 = both from getty, and from flag. +*/ +#[no_mangle] +pub static mut login_shell: libc::c_int = 0; + +/* Non-zero means that at this moment, the shell is interactive. In +general, this means that the shell is at this moment reading input +from the keyboard. */ +#[no_mangle] +pub static mut interactive: libc::c_int = 0; +#[no_mangle] +pub static mut interactive_shell: libc::c_int = 0; +#[no_mangle] +pub static mut hup_on_exit: libc::c_int = 0; +#[no_mangle] +pub static mut check_jobs_at_exit: libc::c_int = 0; +#[no_mangle] +pub static mut autocd: libc::c_int = 0; +#[no_mangle] +pub static mut startup_state: libc::c_int = 0; +#[no_mangle] +pub static mut reading_shell_script: libc::c_int = 0; +#[no_mangle] +pub static mut debugging_login_shell: libc::c_int = 0; +#[no_mangle] +pub static mut shell_environment: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; +#[no_mangle] +pub static mut executing: libc::c_int = 0; +#[no_mangle] +pub static mut current_command_number: libc::c_int = 1; +#[no_mangle] +pub static mut indirection_level: libc::c_int = 0; + +#[no_mangle] +pub static mut shell_name: *mut libc::c_char = 0 as *mut libc::c_char; +#[no_mangle] +pub static mut shell_start_time: time_t = 0; +#[no_mangle] +pub static mut shellstart: timeval = timeval { + tv_sec: 0, + tv_usec: 0, +}; +#[no_mangle] +pub static mut running_under_emacs: libc::c_int = 0; + +#[macro_export] +macro_rules! HAVE_DEV_FD { + () => { + 1 + }; +} + +#[macro_export] +macro_rules! DEFAULT_BASHRC { + () => { + // b"~/.bashrc\0" as *const u8 as *const libc::c_char as *mut libc::c_char + b"~/.utshellrc\0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[no_mangle] +pub static mut have_devfd: libc::c_int = HAVE_DEV_FD!(); + +pub static mut bashrc_file: *mut libc::c_char = DEFAULT_BASHRC!(); + +#[no_mangle] +pub static mut rpm_requires: libc::c_int = 0; +#[no_mangle] +pub static mut debugging_mode: libc::c_int = 0; +#[no_mangle] +pub static mut no_line_editing: libc::c_int = 0; +#[no_mangle] +pub static mut dump_translatable_strings: libc::c_int = 0; +#[no_mangle] +pub static mut dump_po_strings: libc::c_int = 0; +#[no_mangle] +pub static mut wordexp_only: libc::c_int = 0; +#[no_mangle] +pub static mut protected_mode: libc::c_int = 0; +#[no_mangle] +pub static mut pretty_print_mode: libc::c_int = 0; +#[no_mangle] +pub static mut posixly_correct: libc::c_int = 0; + +#[no_mangle] +pub static mut subshell_top_level: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, +}; 1]; +#[no_mangle] +pub static mut subshell_argc: libc::c_int = 0; +#[no_mangle] +pub static mut subshell_argv: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; +#[no_mangle] +pub static mut subshell_envp: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; +#[no_mangle] +pub static mut exec_argv0: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut default_buffered_input: libc::c_int = -(1 as libc::c_int); +#[no_mangle] +pub static mut read_from_stdin: libc::c_int = 0; +#[no_mangle] +pub static mut want_pending_command: libc::c_int = 0; +#[no_mangle] +pub static mut command_execution_string: *mut libc::c_char = + 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut shell_script_filename: *mut libc::c_char = + 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut malloc_trace_at_exit: libc::c_int = 0 as libc::c_int; + +#[macro_export] +macro_rules! setjmp_sigs { + ($x:expr) => { + __sigsetjmp($x, 1) + }; +} + +#[macro_export] +macro_rules! RL_STATE_TERMPREPPED { + () => { + 0x0000004 + }; +} + +#[macro_export] +macro_rules! SYS_PROFILE { + () => { + b"/etc/profile\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! RESTRICTED_SHELL_NAME { + () => { + b"rbash\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! savestring { + ($x:expr) => { + libc::strcpy( + libc::malloc((libc::strlen($x as *const libc::c_char) + 1) as usize) + as *mut libc::c_char, + $x, + ) as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! DEBUGGER_START_FILE { + () => { + b"/usr/local/share/bashdb/bashdb-main.inc\0" as *const u8 as *const libc::c_char + }; +} + +#[macro_export] +macro_rules! PROGRAM { + () => { + b"utshell\0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct passwd { + pub pw_name: *mut libc::c_char, + pub pw_passwd: *mut libc::c_char, + pub pw_uid: __uid_t, + pub pw_gid: __gid_t, + pub pw_gecos: *mut libc::c_char, + pub pw_dir: *mut libc::c_char, + pub pw_shell: *mut libc::c_char, +} + +#[macro_export] +macro_rules! PPROMPT { + () => { + b"\\s-\\v\\$ \0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! SPROMPT { + () => { + b"> \0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! MACHTYPE { + () => { + b"x86_64-pc-linux-gnu\0" as *const u8 as *const libc::c_char + }; +} + +//makecmd +#[no_mangle] +pub static mut here_doc_first_line: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut wdcache: sh_obj_cache_t = { + let mut init = objcache { + data: 0 as *const libc::c_void as *mut libc::c_void, + cs: 0 as libc::c_int, + nc: 0 as libc::c_int, + }; + init +}; +#[no_mangle] +pub static mut wlcache: sh_obj_cache_t = { + let mut init = objcache { + data: 0 as *const libc::c_void as *mut libc::c_void, + cs: 0 as libc::c_int, + nc: 0 as libc::c_int, + }; + init +}; + +#[macro_export] +macro_rules! WDCACHESIZE { + () => { + 128 + }; +} + +#[macro_export] +macro_rules! WLCACHESIZE { + () => { + 128 + }; +} + +#[macro_export] +macro_rules! ocache_create { + ($c:expr, $otype:ty, $n:expr) => { + $c.data = malloc($n * (std::mem::size_of::<*mut $otype>() as libc::c_ulong) as usize); + wdcache.cs = 128 as libc::c_int; + wdcache.nc = 0 as libc::c_int; + }; +} + +#[macro_export] +macro_rules! ocache_alloc { + ($c:expr, $otype:ty, $r:expr) => { + if $c.nc > 0 { + $c.nc -= 1; + $r = ($c.data as *mut *mut $otype).offset($c.nc as isize) as *mut $otype; + } else { + $r = malloc(std::mem::size_of::<$otype>() as usize) as *mut $otype; + } + }; +} + +#[macro_export] +macro_rules! W_NOGLOB { + () => { + 1 << 5 + }; +} + +#[macro_export] +macro_rules! W_NOSPLIT { + () => { + 1 << 4 + }; +} + +#[macro_export] +macro_rules! W_QUOTED { + () => { + 1 << 1 + }; +} + +#[macro_export] +macro_rules! W_DQUOTE { + () => { + 1 << 19 + }; +} + +#[macro_export] +macro_rules! W_NOPROCSUB { + () => { + 1 << 20 + }; +} + +#[macro_export] +macro_rules! FASTCOPY { + ($s:expr, $d:expr, $n:expr) => { + libc::memcpy( + $d as *mut libc::c_void, + $s as *const libc::c_void, + $n as libc::c_ulong as libc::size_t, + ); + }; +} + +//pathexp +#[derive(Copy, Clone)] +#[repr(C)] +pub union __mbstate_u { + pub __wch: libc::c_uint, + pub __wchb: [libc::c_char; 4], +} + +pub type sh_ignore_func_t = fn(*const libc::c_char) -> libc::c_int; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct ign { + pub val: *mut libc::c_char, + pub len: libc::c_int, + pub flags: libc::c_int, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct ignorevar { + pub varname: *mut libc::c_char, + pub ignores: *mut ign, + pub num_ignores: libc::c_int, + pub last_ignoreval: *mut libc::c_char, + pub item_func: Option, +} +pub type sh_iv_item_func_t = fn(*mut ign) -> libc::c_int; + +#[no_mangle] +pub static mut glob_dot_filenames: libc::c_int = 0; +#[no_mangle] +pub static mut extended_glob: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut glob_star: libc::c_int = 0 as libc::c_int; + +//pcomplib +pub type hash_wfunc = fn(*mut BUCKET_CONTENTS) -> libc::c_int; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct compspec { + pub refcount: libc::c_int, + pub actions: libc::c_ulong, + pub options: libc::c_ulong, + pub globpat: *mut libc::c_char, + pub words: *mut libc::c_char, + pub prefix: *mut libc::c_char, + pub suffix: *mut libc::c_char, + pub funcname: *mut libc::c_char, + pub command: *mut libc::c_char, + pub lcommand: *mut libc::c_char, + pub filterpat: *mut libc::c_char, +} +pub type COMPSPEC = compspec; + +#[no_mangle] +pub static mut prog_completes: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +#[macro_export] +macro_rules! STRDUP { + ($x:expr) => { + if !($x).is_null() { + savestring!($x) + } else { + 0 as *mut libc::c_char + } + }; +} + +pub const COMPLETE_HASH_BUCKETS: libc::c_int = 256; + +//print_cmd +pub type PFUNC = unsafe extern "C" fn(*const libc::c_char, ...) -> (); + +pub const FUNC_MULTILINE: i32 = 0x01; +pub const FUNC_EXTERNAL: i32 = 0x02; + +pub static mut indentation: libc::c_int = 0; +pub static mut indentation_amount: libc::c_int = 4; + +pub const PRINTED_COMMAND_INITIAL_SIZE: libc::c_int = 64; +pub const PRINTED_COMMAND_CROW_SIZE: libc::c_int = 128; + +pub static mut inside_function_def: libc::c_int = 0; +pub static mut skip_this_indent: libc::c_int = 0; +pub static mut was_heredoc: libc::c_int = 0; +pub static mut printing_connection: libc::c_int = 0; +pub static mut deferred_heredocs: *mut REDIRECT = 0 as *mut REDIRECT; + +pub static mut group_command_nesting: libc::c_int = 0; + +pub static mut indirection_string: *mut libc::c_char = 0 as *mut libc::c_char; +pub static mut indirection_stringsiz: libc::c_int = 0; + +pub const MB_LEN_MAX: usize = 16; //在C端这是一个å®ï¼Œ +pub const MB_CUR_MAX: usize = 1; +pub const AND_AND: i32 = 288; +pub const OR_OR: i32 = 289; + +/* å®å®šä¹‰ */ +#[macro_export] +macro_rules! CHECK_XTRACE_FP { + () => { + if !xtrace_fp.is_null() { + xtrace_fp = xtrace_fp; + } else { + xtrace_fp = stderr; + } + }; +} + +#[macro_export] +macro_rules! EXPCHAR{ + ($c:expr) => ( + if $c == b'{' as libc::c_char || $c == b'~' as libc::c_char || $c == b'$' as libc::c_char || $c == b'`' as libc::c_char{ + 1 + } + else{ + 0 + } + ) +} + +#[macro_export] +macro_rules! PRINT_DEFERRED_HEREDOCS { + ($x:expr) => { + if !deferred_heredocs.is_null() { + print_deferred_heredocs($x); + } + }; +} + +pub fn MBLEN(s: *const libc::c_char, n: size_t) -> libc::c_int { + if MB_CUR_MAX > 1 { + return unsafe { mblen(s, n) }; + } else { + return 1; + } +} + +pub type Function = fn() -> libc::c_int; + +#[no_mangle] +pub static mut the_printed_command: *mut libc::c_char = 0 as *mut libc::c_char; +#[no_mangle] +pub static mut the_printed_command_size: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut command_string_index: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut xtrace_fd: libc::c_int = -(1 as libc::c_int); +#[no_mangle] +pub static mut xtrace_fp: *mut FILE = 0 as *const FILE as *mut FILE; + +//redir +#[repr(C)] +pub struct _IO_wide_data { + pub _private: [u8; 0], +} +#[repr(C)] +pub struct _IO_codecvt { + pub _private: [u8; 0], +} +#[repr(C)] +pub struct _IO_marker { + pub _private: [u8; 0], +} + +pub const S_IFMT: libc::c_uint = 0o170000; +pub const S_IFREG: libc::c_uint = 0o100000; +pub const RX_INTERNAL: libc::c_int = 0x8; +pub const RX_SAVCLEXEC: libc::c_int = 0x20; + +pub const SUBSHELL_ASYNC: libc::c_int = 0x1; +pub const RX_CLEXEC: libc::c_int = 0x4; +pub const SHELL_FD_BASE: libc::c_int = 10; +pub const RX_SAVEFD: libc::c_int = 0x40; + +#[macro_export] +macro_rules! REDIRECTION_ERROR { + ($r:expr, $errno:expr, $fd:expr) => { + if $r < 0 as libc::c_int { + if $fd >= 0 as libc::c_int { + close($fd); + } + set_exit_status(EXECUTION_FAILURE); + return if *__errno_location() == 0 as libc::c_int { + EINVAL + } else { + *__errno_location() + }; + } + }; +} + +#[macro_export] +macro_rules! S_ISREG { + ($m:expr) => { + $m & S_IFMT == S_IFREG + }; +} + +#[macro_export] +macro_rules! CLOBBERING_REDIRECT { + ($ri:expr) => { + ($ri as libc::c_uint == r_output_direction as libc::c_int as libc::c_uint + || $ri as libc::c_uint == r_err_and_out as libc::c_int as libc::c_uint) + }; +} + +#[macro_export] +macro_rules! WRITE_REDIRECT { + ($ri:expr) => { + $ri as libc::c_uint == r_output_direction as libc::c_int as libc::c_uint + || $ri as libc::c_uint == r_input_output as libc::c_int as libc::c_uint + || $ri as libc::c_uint == r_err_and_out as libc::c_int as libc::c_uint + || $ri as libc::c_uint == r_appending_to as libc::c_int as libc::c_uint + || $ri as libc::c_uint == r_append_err_and_out as libc::c_int as libc::c_uint + || $ri as libc::c_uint == r_output_force as libc::c_int as libc::c_uint + }; +} + +// Redirection errors. +pub const AMBIGUOUS_REDIRECT: libc::c_int = -1; +pub const NOCLOBBER_REDIRECT: libc::c_int = -2; +pub const RESTRICTED_REDIRECT: libc::c_int = -3; /* can only happen in restricted shells. */ +pub const HEREDOC_REDIRECT: libc::c_int = -4; /* here-doc temp file can't be created */ +pub const BADVAR_REDIRECT: libc::c_int = -5; /* something wrong with {varname}redir */ + +pub const REDIR_VARASSIGN: libc::c_int = 0x01; +pub const HEREDOC_PIPESIZE: size_t = 65535; +pub const F_GETPIPE_SZ: libc::c_int = 1032; + +pub const EPERM: libc::c_int = 1; +pub const ENOENT: libc::c_int = 2; +pub const ESRCH: libc::c_int = 3; + +pub const EIO: libc::c_int = 5; +pub const ENXIO: libc::c_int = 6; +pub const E2BIG: libc::c_int = 7; +pub const ENOEXEC: libc::c_int = 8; + +pub const ENOMEM: libc::c_int = 12; +pub const EACCES: libc::c_int = 13; +pub const EFAULT: libc::c_int = 14; +pub const ENOTBLK: libc::c_int = 15; +pub const EBUSY: libc::c_int = 16; +pub const EEXIST: libc::c_int = 17; +pub const EXDEV: libc::c_int = 18; +pub const ENODEV: libc::c_int = 19; +pub const ENOTDIR: libc::c_int = 20; +pub const EISDIR: libc::c_int = 21; + +pub const ENFILE: libc::c_int = 23; +pub const EMFILE: libc::c_int = 24; + +pub const ETXTBSY: libc::c_int = 26; +pub const EFBIG: libc::c_int = 27; +pub const ENOSPC: libc::c_int = 28; + +pub const EROFS: libc::c_int = 30; +pub const EMLINK: libc::c_int = 31; +pub const EPIPE: libc::c_int = 32; +pub const EDOM: libc::c_int = 33; +pub const ERANGE: libc::c_int = 34; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct STRING_INT_ALIST { + pub word: *mut libc::c_char, + pub token: libc::c_int, +} + +#[no_mangle] +pub static mut expanding_redir: libc::c_int = 0; + +pub const RF_END: libc::c_int = -1; +pub const RF_DEVFD: libc::c_int = 1; +pub const RF_DEVSTDERR: libc::c_int = 2; +pub const RF_DEVSTDIN: libc::c_int = 3; +pub const RF_DEVSTDOUT: libc::c_int = 4; +pub const RF_DEVTCP: libc::c_int = 5; +pub const RF_DEVUDP: libc::c_int = 6; + +//sig +#[no_mangle] +pub static mut interrupt_state: sig_atomic_t = 0 as libc::c_int; +#[no_mangle] +pub static mut sigwinch_received: sig_atomic_t = 0 as libc::c_int; +#[no_mangle] +pub static mut sigterm_received: sig_atomic_t = 0 as libc::c_int; +#[no_mangle] +pub static mut terminating_signal: sig_atomic_t = 0 as libc::c_int; +#[no_mangle] +pub static mut top_level: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, +}; 1]; +#[no_mangle] +pub static mut top_level_mask: sigset_t = __sigset_t { __val: [0; 16] }; +#[no_mangle] +pub static mut interrupt_immediately: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut terminate_immediately: libc::c_int = 0 as libc::c_int; + +#[macro_export] +macro_rules! TERMSIGS_LENGTH { + () => { + (::std::mem::size_of::<[termsig; 17]>() as libc::c_ulong) + .wrapping_div(::std::mem::size_of::() as libc::c_ulong) + }; +} + +#[macro_export] +macro_rules! XSIG { + ($x:expr) => { + terminating_signals[$x as usize].signum + }; +} + +#[macro_export] +macro_rules! XHANDLER { + ($x:expr) => { + terminating_signals[$x as usize].orig_handler + }; +} + +#[macro_export] +macro_rules! XSAFLAGS { + ($x:expr) => { + terminating_signals[$x as usize].orig_flags + }; +} + +#[macro_export] +macro_rules! XCOREDUMP { + ($x:expr) => { + terminating_signals[$x as usize].core_dump + }; +} + +#[macro_export] +macro_rules! RL_STATE_READCMD { + () => { + 0x0000008 + }; +} + +#[macro_export] +macro_rules! RL_STATE_SIGHANDLER { + () => { + 0x0008000 + }; +} + +//subst +pub type wint_t = libc::c_uint; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct _IO_FILE { + pub _flags: libc::c_int, + pub _IO_read_ptr: *mut libc::c_char, + pub _IO_read_end: *mut libc::c_char, + pub _IO_read_base: *mut libc::c_char, + pub _IO_write_base: *mut libc::c_char, + pub _IO_write_ptr: *mut libc::c_char, + pub _IO_write_end: *mut libc::c_char, + pub _IO_buf_base: *mut libc::c_char, + pub _IO_buf_end: *mut libc::c_char, + pub _IO_save_base: *mut libc::c_char, + pub _IO_backup_base: *mut libc::c_char, + pub _IO_save_end: *mut libc::c_char, + pub _markers: *mut _IO_marker, + pub _chain: *mut _IO_FILE, + pub _fileno: libc::c_int, + pub _flags2: libc::c_int, + pub _old_offset: __off_t, + pub _cur_column: libc::c_ushort, + pub _vtable_offset: libc::c_schar, + pub _shortbuf: [libc::c_char; 1], + pub _lock: *mut libc::c_void, + pub _offset: __off64_t, + pub _codecvt: *mut _IO_codecvt, + pub _wide_data: *mut _IO_wide_data, + pub _freeres_list: *mut _IO_FILE, + pub _freeres_buf: *mut libc::c_void, + pub __pad5: size_t, + pub _mode: libc::c_int, + pub _unused2: [libc::c_char; 20], +} + +pub type __pid_t = libc::c_int; + +pub type pid_t = __pid_t; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct __sigset_t { + pub __val: [libc::c_ulong; 16], +} +pub type sigset_t = __sigset_t; + +pub type C2RustUnnamed_0 = libc::c_uint; + +pub const _ISpunct: C2RustUnnamed_0 = 4; +pub const _IScntrl: C2RustUnnamed_0 = 2; + +pub const _ISgraph: C2RustUnnamed_0 = 32768; +pub const _ISprint: C2RustUnnamed_0 = 16384; +pub const _ISspace: C2RustUnnamed_0 = 8192; +pub const _ISxdigit: C2RustUnnamed_0 = 4096; + +pub const _ISlower: C2RustUnnamed_0 = 512; +pub const _ISupper: C2RustUnnamed_0 = 256; + +pub type sh_wassign_func_t = fn(*mut WORD_DESC, libc::c_int) -> libc::c_int; +pub type sh_builtin_func_t = fn(*mut WORD_LIST) -> libc::c_int; + +pub type SigHandler = fn(libc::c_int) -> (); +pub type EXPFUNC = fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct fd_bitmap { + pub size: libc::c_int, + pub bitmap: *mut libc::c_char, +} +pub type PROCESS = process; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct process { + pub next: *mut process, + pub pid: pid_t, + pub status: WAIT, + pub running: libc::c_int, + pub command: *mut libc::c_char, +} +pub type WAIT = libc::c_int; + +#[no_mangle] +pub static mut last_command_subst_pid: pid_t = -(1 as libc::c_int); +#[no_mangle] +pub static mut current_command_subst_pid: pid_t = -(1 as libc::c_int); +#[no_mangle] +pub static mut ifs_var: *mut SHELL_VAR = 0 as *const SHELL_VAR as *mut SHELL_VAR; +#[no_mangle] +pub static mut ifs_value: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut ifs_cmap: [libc::c_uchar; 256] = [0; 256]; +#[no_mangle] +pub static mut ifs_is_set: libc::c_int = 0; +#[no_mangle] +pub static mut ifs_is_null: libc::c_int = 0; +#[no_mangle] +pub static mut ifs_firstc: [libc::c_uchar; 16] = [0; 16]; +#[no_mangle] +pub static mut ifs_firstc_len: size_t = 0; +#[no_mangle] +pub static mut inherit_errexit: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut assigning_in_environment: libc::c_int = 0; +#[no_mangle] +pub static mut subst_assign_varlist: *mut WORD_LIST = + 0 as *const libc::c_void as *mut libc::c_void as *mut WORD_LIST; +#[no_mangle] +pub static mut no_longjmp_on_fatal_error: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut allow_null_glob_expansion: libc::c_int = 0; +#[no_mangle] +pub static mut fail_glob_expansion: libc::c_int = 0; +pub static mut cached_quoted_dollar_at: *mut WORD_LIST = 0 as *const WORD_LIST as *mut WORD_LIST; + +pub static mut expand_param_error: libc::c_char = 0; +pub static mut expand_param_fatal: libc::c_char = 0; +pub static mut extract_string_error: libc::c_char = 0; +pub static mut extract_string_fatal: libc::c_char = 0; +pub static mut expand_no_split_dollar_star: libc::c_int = 0 as libc::c_int; +pub static mut garglist: *mut WORD_LIST = + 0 as *const libc::c_void as *mut libc::c_void as *mut WORD_LIST; + +//test +pub const R_OK: libc::c_int = 4; +pub const X_OK: libc::c_int = 1; + +#[macro_export] +macro_rules! FNMATCH_EXTFLAG { + () => { + if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + } + }; +} + +pub const LE: libc::c_int = 4; +pub const GE: libc::c_int = 5; +pub const NE: libc::c_int = 1; +pub const EF: libc::c_int = 2; + +pub const OT: libc::c_int = 1; +pub const NT: libc::c_int = 0; + +//trap +pub const RL_STATE_SIGHANDLER: libc::c_ulong = 0x0008000; + +#[macro_export] +macro_rules! CHECK_ALRM { + () => { + if sigalrm_seen != 0 { + siglongjmp(alrmbuf.as_mut_ptr(), 1 as libc::c_int); + } + }; +} + +pub type __sighandler_t = Option ()>; + +pub type sh_parser_state_t = _sh_parser_state_t; + +pub const NSIG: usize = 64; +pub const DEBUG_TRAP: usize = NSIG; +pub const ERROR_TRAP: usize = NSIG + 1; +pub const RETURN_TRAP: usize = NSIG + 2; +pub const BASH_NSIG: usize = NSIG + 3; +pub const EXIT_TRAP: usize = 0; + +/* Flags which describe the current handling state of a signal. */ +pub const SIG_INHERITED: libc::c_int = 0x0; /* Value inherited from parent. */ +pub const SIG_TRAPPED: libc::c_int = 0x1; /* Currently trapped. */ +pub const SIG_HARD_IGNORE: libc::c_int = 0x2; /* Signal was ignored on shell entry. */ +pub const SIG_SPECIAL: libc::c_int = 0x4; /* Treat this signal specially. */ +pub const SIG_NO_TRAP: libc::c_int = 0x8; /* Signal cannot be trapped. */ +pub const SIG_INPROGRESS: libc::c_int = 0x10; /* Signal cannot be trapped. */ +pub const SIG_CHANGED: libc::c_int = 0x20; /* Trap value changed in trap handler. */ +pub const SIG_IGNORED: libc::c_int = 0x40; /* The signal is currently being ignored. */ + +#[macro_export] +macro_rules! GETORIGSIG { + ($sig:expr) => { + original_signals[$sig as libc::c_int as usize] = + set_signal_handler($sig as libc::c_int, None); + set_signal_handler( + $sig as libc::c_int, + original_signals[$sig as libc::c_int as usize], + ); + if original_signals[$sig as libc::c_int as usize] + == ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ) + { + sigmodes[$sig as libc::c_int as usize] |= SIG_HARD_IGNORE as libc::c_int; + } + }; +} + +#[macro_export] +macro_rules! SETORIGSIG { + ($sig:expr, $handler:expr) => { + original_signals[$sig] == handler; + if original_signals[$sig] == libc::SIG_IGN { + sigmodes[$sig] |= SIG_HARD_IGNORE; + } + }; +} +#[macro_export] +macro_rules! GET_ORIGINAL_SIGNAL { + ($sig: expr) => { + if $sig && $sig < NSIG && original_signals[$sig] == initialize_traps { + GETORIGSIG!($sig) + } + }; +} + +#[macro_export] +macro_rules! SPECIAL_TRAP { + ($sig:expr) => { + $sig == 0 as libc::c_int + || $sig == 64 as libc::c_int + 1 as libc::c_int + || $sig == 64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int + || $sig == 64 as libc::c_int + 1 as libc::c_int + 2 as libc::c_int + }; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct _sh_parser_state_t { + pub parser_state: libc::c_int, + pub token_state: *mut libc::c_int, + pub token: *mut libc::c_char, + pub token_buffer_size: libc::c_int, + pub input_line_terminator: libc::c_int, + pub eof_encountered: libc::c_int, + pub prompt_string_pointer: *mut *mut libc::c_char, + pub current_command_line_count: libc::c_int, + pub remember_on_history: libc::c_int, + pub history_expansion_inhibited: libc::c_int, + pub last_command_exit_value: libc::c_int, + pub pipestatus: *mut ARRAY, + pub last_shell_builtin: Option, + pub this_shell_builtin: Option, + pub expand_aliases: libc::c_int, + pub echo_input_at_read: libc::c_int, + pub need_here_doc: libc::c_int, + pub here_doc_first_line: libc::c_int, + pub redir_stack: [*mut REDIRECT; 16], +} + +pub type sh_resetsig_func_t = fn(libc::c_int) -> (); +#[no_mangle] +pub static mut signal_names: [*mut libc::c_char; 69] = [ + b"EXIT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGHUP\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGINT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGQUIT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGILL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGTRAP\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGABRT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGBUS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGFPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGKILL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGUSR1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGSEGV\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGUSR2\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGPIPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGALRM\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGTERM\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGSTKFLT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGCHLD\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGCONT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGSTOP\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGTSTP\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGTTIN\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGTTOU\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGURG\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGXCPU\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGXFSZ\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGVTALRM\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGPROF\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGWINCH\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGIO\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGPWR\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGSYS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGJUNK(32)\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGJUNK(33)\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+2\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+3\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+4\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+5\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+6\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+7\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+8\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+9\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+10\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+11\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+12\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+13\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+14\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMIN+15\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-14\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-13\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-12\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-11\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-10\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-9\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-8\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-7\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-6\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-5\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-4\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-3\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-2\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX-1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"SIGRTMAX\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"DEBUG\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"ERR\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"RETURN\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as *const libc::c_char as *mut libc::c_char, +]; + +#[no_mangle] +pub static mut SigHandler: [Option; 65] = [None; 65]; +#[no_mangle] +pub static mut trap_list: [*mut libc::c_char; 68] = + [0 as *const libc::c_char as *mut libc::c_char; 68]; +#[no_mangle] +pub static mut pending_traps: [libc::c_int; 65] = [0; 65]; +#[no_mangle] +pub static mut running_trap: libc::c_int = 0; +#[no_mangle] +pub static mut trap_saved_exit_value: libc::c_int = 0; +#[no_mangle] +pub static mut wait_signal_received: libc::c_int = 0; +#[no_mangle] +pub static mut trapped_signal_received: libc::c_int = 0; +#[no_mangle] +pub static mut suppress_debug_trap_verbose: libc::c_int = 0 as libc::c_int; + +pub const EXITPROG: libc::c_int = 3; +pub const ERREXIT: libc::c_int = 4; + +//unwind_port +pub type VFunction = fn() -> (); +pub type sh_obj_cache_t = objcache; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct objcache { + pub data: *mut libc::c_void, + pub cs: libc::c_int, + pub nc: libc::c_int, +} +pub type UNWIND_ELT = uwp; +#[derive(Copy, Clone)] +#[repr(C)] +pub union uwp { + pub head: uwp_head, + pub arg: UWP_HEAD_0, + pub sv: UWP_HEAD_1, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct UWP_HEAD_1 { + pub uwp_head: uwp_head, + pub v: SAVED_VAR, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct SAVED_VAR { + pub variable: *mut libc::c_char, + pub size: libc::c_int, + pub desired_setting: [libc::c_char; 1], +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct uwp_head { + pub next: *mut uwp, + pub cleanup: Option, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct UWP_HEAD_0 { + pub uwp_head: uwp_head, + pub v: *mut libc::c_char, +} +pub static mut unwind_protect_list: *mut UNWIND_ELT = + 0 as *const libc::c_void as *mut libc::c_void as *mut UNWIND_ELT; +#[no_mangle] +pub static mut uwcache: sh_obj_cache_t = { + let mut init = objcache { + data: 0 as *const libc::c_void as *mut libc::c_void, + cs: 0 as libc::c_int, + nc: 0 as libc::c_int, + }; + init +}; + +//variables +pub type sh_string_func_t = fn(*mut libc::c_char) -> *mut libc::c_char; +pub type sh_sv_func_t = fn(*mut libc::c_char) -> (); + +pub type sh_var_map_func_t = fn(*mut SHELL_VAR) -> libc::c_int; + +#[macro_export] +macro_rules! Root_PS1_Value { + () => { + b"\\u@\\h:\\w# \0" as *const u8 as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! PS1_Value { + () => { + b"\\u@\\h:\\w$ \0" as *const u8 as *mut libc::c_char + }; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct timezone { + pub tz_minuteswest: libc::c_int, + pub tz_dsttime: libc::c_int, +} +pub type __timezone_ptr_t = *mut timezone; + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct timeval { + pub tv_sec: __time_t, + pub tv_usec: __suseconds_t, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct name_and_function { + pub name: *mut libc::c_char, + pub function: Option, +} + +#[no_mangle] +pub static mut global_variables: *mut VAR_CONTEXT = + 0 as *const libc::c_void as *mut libc::c_void as *mut VAR_CONTEXT; + +#[no_mangle] +pub static mut shell_variables: *mut VAR_CONTEXT = + 0 as *const libc::c_void as *mut libc::c_void as *mut VAR_CONTEXT; + +#[no_mangle] +pub static mut shell_functions: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +#[no_mangle] +pub static mut invalid_env: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +#[no_mangle] +pub static mut shell_function_defs: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +#[no_mangle] +pub static mut temporary_env: *mut HASH_TABLE = + 0 as *const libc::c_void as *mut libc::c_void as *mut HASH_TABLE; + +#[no_mangle] +pub static mut variable_context: libc::c_int = 0 as libc::c_int; + +#[no_mangle] +pub static mut localvar_inherit: libc::c_int = 0 as libc::c_int; + +#[no_mangle] +pub static mut localvar_unset: libc::c_int = 0 as libc::c_int; + +#[no_mangle] +pub static mut tempenv_assign_error: libc::c_int = 0; + +#[no_mangle] +pub static mut dollar_vars: [*mut libc::c_char; 10] = + [0 as *const libc::c_char as *mut libc::c_char; 10]; + +#[no_mangle] +pub static mut rest_of_args: *mut WORD_LIST = + 0 as *const libc::c_void as *mut libc::c_void as *mut WORD_LIST; + +#[no_mangle] +pub static mut posparam_count: libc::c_int = 0 as libc::c_int; + +#[no_mangle] +pub static mut dollar_dollar_pid: pid_t = 0; + +#[no_mangle] +pub static mut array_needs_making: libc::c_int = 1 as libc::c_int; + +#[no_mangle] +pub static mut shell_level: libc::c_int = 0 as libc::c_int; + +#[no_mangle] +pub static mut export_env: *mut *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut *mut libc::c_char; + +pub static mut export_env_index: libc::c_int = 0; +pub static mut export_env_size: libc::c_int = 0; +pub static mut winsize_assignment: libc::c_int = 0; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct saved_dollar_vars { + pub first_ten: *mut *mut libc::c_char, + pub rest: *mut WORD_LIST, + pub count: libc::c_int, +} + +#[macro_export] +macro_rules! ASS_MKLOCAL { + () => { + 0x0002 + }; +} + +#[macro_export] +macro_rules! DEFAULT_COMPAT_LEVEL { + () => { + 01 + }; +} + +#[macro_export] +macro_rules! ASS_MKGLOBAL { + () => { + 0x0008 + }; +} + +#[macro_export] +macro_rules! ASS_NOEVAL { + () => { + 0x0100 + }; +} + +#[macro_export] +macro_rules! ASS_APPEND { + () => { + 0x0001 + }; +} + +#[macro_export] +macro_rules! ASSOC_HASH_BUCKETS { + () => { + 1024 + }; +} + +#[macro_export] +macro_rules! ASS_CHKLOCAL { + () => { + 0x0040 + }; +} + +#[macro_export] +macro_rules! MKLOC_ARRAYOK { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! MKLOC_ASSOCOK { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! MKLOC_INHERIT { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! MIN_COMPAT_LEVEL { + () => { + 31 + }; +} + +#[macro_export] +macro_rules! SAVE_EXPORTSTR { + ($var:expr,$value:expr) => { + if $value.is_null() { + (*$var).exportstr = savestring!($value); + } else { + (*$var).exportstr = 0 as *mut libc::c_char; + } + }; +} + +#[macro_export] +macro_rules! set_element_value { + ($ae:expr,$val:expr) => { + (*$ae).value = $val; + }; +} + +#[macro_export] +macro_rules! local_p { + ($var:expr) => { + (*$var).attributes & att_local as libc::c_int + }; +} + +#[macro_export] +macro_rules! propagate_p { + ($var:expr) => { + (*$var).attributes & att_propagate as libc::c_int + }; +} + +#[macro_export] +macro_rules! VC_FUNCENV { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! capcase_p { + ($vc:expr) => { + (*$vc).attributes & att_capcase as libc::c_int + }; +} + +#[macro_export] +macro_rules! uppercase_p { + ($vc:expr) => { + (*$vc).attributes & att_uppercase as libc::c_int + }; +} + +#[macro_export] +macro_rules! lowercase_p { + ($vc:expr) => { + (*$vc).attributes & att_lowercase as libc::c_int + }; +} + +#[macro_export] +macro_rules! vc_isfuncenv { + ($vc:expr) => { + ((*$vc).flags & VC_FUNCENV as libc::c_int) != 0 + }; +} + +#[macro_export] +macro_rules! vc_istempenv { + ($vc:expr) => { + ((*$vc).flags & VC_TEMPFLAGS as libc::c_int) == VC_TEMPFLAGS as libc::c_int + }; +} + +#[macro_export] +macro_rules! vc_istempscope { + ($vc:expr) => { + ((*$vc).flags & (VC_TEMPENV as libc::c_int | VC_BLTNENV as libc::c_int)) != 0 as libc::c_int + }; +} + +#[macro_export] +macro_rules! vc_haslocals { + ($vc:expr) => { + ((*$vc).flags & VC_HASLOCAL as libc::c_int) != 0 + }; +} + +#[macro_export] +macro_rules! regen_p { + ($var:expr) => { + (*$var).attributes & att_regenerate as libc::c_int + }; +} + +#[macro_export] +macro_rules! add_to_export_env { + ($envstr:expr,$do_alloc:expr) => {{ + if export_env_index >= (export_env_size - 1 as libc::c_int) { + export_env_size += 16 as libc::c_int; + export_env = strvec_resize(export_env, export_env_size); + environ = export_env; + } + *export_env.offset(export_env_index as isize) = if $do_alloc != 0 { + savestring!($envstr) + } else { + $envstr + }; + export_env_index += 1; + *export_env.offset(export_env_index as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + }}; +} + +#[macro_export] +macro_rules! FREE_EXPORTSTR { + ($var:expr) => { + if !((*$var).exportstr.is_null()) { + free((*$var).exportstr as *mut libc::c_void); + } + }; +} + +#[macro_export] +macro_rules! non_unsettable_p { + ($var:expr) => { + (*$var).attributes & (att_nounset as libc::c_int) + }; +} + +#[macro_export] +macro_rules! NOW { + () => { + time(0 as *mut time_t) + }; +} + +#[macro_export] +macro_rules! nofree_p { + ($var:expr) => { + (*$var).attributes & att_nofree as libc::c_int + }; +} + +#[macro_export] +macro_rules! function_p { + ($var:expr) => { + (*$var).attributes & att_function as libc::c_int + }; +} + +#[macro_export] +macro_rules! function_cell { + ($var:expr) => { + (*$var).value as *mut COMMAND + }; +} + +#[macro_export] +macro_rules! CLEAR_EXPORTSTR { + ($var:expr) => { + (*$var).exportstr = 0 as *mut libc::c_void as *mut libc::c_char; + }; +} + +#[macro_export] +macro_rules! var_setvalue { + ($var:expr,$str:expr) => { + (*$var).value = $str + }; +} + +#[macro_export] +macro_rules! var_setfunc { + ($var:expr,$func:expr) => { + (*$var).value = $func as *mut libc::c_char; + }; +} + +#[macro_export] +macro_rules! CACHE_IMPORTSTR { + ($var:expr,$value:expr) => { + (*$var).exportstr = savestring!($value); + }; +} + +#[macro_export] +macro_rules! imported_p { + ($var:expr) => { + (*$var).attributes & (att_imported as libc::c_int) + }; +} + +#[macro_export] +macro_rules! array_p { + ($var:expr) => { + (*$var).attributes & (att_array as libc::c_int) + }; +} + +#[macro_export] +macro_rules! FIND_OR_MAKE_VARIABLE { + ($name:expr,$entry:expr) => { + $entry = find_variable($name); + if !($entry.is_null()) { + $entry = bind_variable( + $name, + b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + if !($entry.is_null()) { + (*$entry).attributes |= att_invisible as libc::c_int; + } + } + }; +} + +#[macro_export] +macro_rules! INIT_DYNAMIC_VAR { + ($v:expr, $var:expr,$val:expr,$gfunc:expr,$afunc:expr) => { + $v = bind_variable($var, ($val), 0 as libc::c_int); + (*$v).dynamic_value = $gfunc; + (*$v).assign_func = $afunc; + }; +} + +#[macro_export] +macro_rules! INIT_DYNAMIC_ARRAY_VAR { + ($v:expr,$var:expr,$gfunc:expr,$afunc:expr) => { + $v = make_new_array_variable($var); + (*$v).dynamic_value = $gfunc; + (*$v).assign_func = $afunc; + }; +} + +#[macro_export] +macro_rules! INIT_DYNAMIC_ASSOC_VAR { + ($v:expr,$var:expr,$gfunc:expr,$afunc:expr) => { + $v = make_new_assoc_variable($var); + (*$v).dynamic_value = $gfunc; + (*$v).assign_func = $afunc; + }; +} + +#[macro_export] +macro_rules! set_auto_export { + ($var:expr) => { + (*$var).attributes |= att_exported as libc::c_int; + array_needs_making = 1 as libc::c_int; + }; +} + +#[macro_export] +macro_rules! RELPATH { + ($x:expr) => { + (*$x) != b'/' as u8 as libc::c_char + }; +} + +#[macro_export] +macro_rules! assoc_copy { + ($h:expr) => { + hash_copy( + $h, + std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void, + ), + ) + }; +} + +#[macro_export] +macro_rules! VARIABLES_HASH_BUCKETS { + () => { + 1024 + }; +} + +#[macro_export] +macro_rules! FUNCTIONS_HASH_BUCKETS { + () => { + 512 + }; +} + +#[macro_export] +macro_rules! TEMPENV_HASH_BUCKETS { + () => { + 4 + }; +} + +#[macro_export] +macro_rules! BASHFUNC_PREFIX { + () => { + b"BASH_FUNC_\0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! BASHFUNC_PREFLEN { + () => { + 10 as libc::c_int + }; +} + +#[macro_export] +macro_rules! BASHFUNC_SUFFIX { + () => { + b"%%\0" as *const u8 as *const libc::c_char as *mut libc::c_char + }; +} + +#[macro_export] +macro_rules! BASHFUNC_SUFFLEN { + () => { + 2 as libc::c_int + }; +} + +#[macro_export] +macro_rules! FV_FORCETEMPENV { + () => { + 0x01 + }; +} + +#[macro_export] +macro_rules! FV_SKIPINVISIBLE { + () => { + 0x02 + }; +} + +#[macro_export] +macro_rules! FV_NODYNAMIC { + () => { + 0x04 + }; +} + +#[macro_export] +macro_rules! EXECUTION_FAILURE { + () => { + 1 as libc::c_int + }; +} + +#[macro_export] +macro_rules! DEFAULT_PATH_VALUE { + () => { + b"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.\0" as *const u8 + as *const libc::c_char as *mut libc::c_char + }; +} + +#[no_mangle] +pub static mut nameref_invalid_value: SHELL_VAR = SHELL_VAR { + name: 0 as *const libc::c_char as *mut libc::c_char, + value: 0 as *const libc::c_char as *mut libc::c_char, + exportstr: 0 as *const libc::c_char as *mut libc::c_char, + dynamic_value: None, + assign_func: None, + attributes: 0, + context: 0, +}; + +//r_bash +/* automatically generated by rust-bindgen */ +#[repr(C)] +#[derive(Copy, Clone, Debug, Default)] +pub struct __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + storage: Storage, + align: [Align; 0], +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + pub fn new(storage: Storage) -> Self { + Self { storage, align: [] } + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + *byte |= mask; + } else { + *byte &= !mask; + } + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } +} +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::core::marker::PhantomData, [T; 0]); +impl __IncompleteArrayField { + #[inline] + pub fn new() -> Self { + __IncompleteArrayField(::core::marker::PhantomData, []) + } + #[inline] + pub unsafe fn as_ptr(&self) -> *const T { + ::core::mem::transmute(self) + } + #[inline] + pub unsafe fn as_mut_ptr(&mut self) -> *mut T { + ::core::mem::transmute(self) + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::core::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::core::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::core::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +impl ::core::clone::Clone for __IncompleteArrayField { + #[inline] + fn clone(&self) -> Self { + Self::new() + } +} +pub const __EXTENSIONS__: u32 = 1; +pub const _ALL_SOURCE: u32 = 1; +pub const _GNU_SOURCE: u32 = 1; +pub const _POSIX_PTHREAD_SEMANTICS: u32 = 1; +pub const _TANDEM_SOURCE: u32 = 1; +pub const JOB_CONTROL: u32 = 1; +pub const ALIAS: u32 = 1; +pub const PUSHD_AND_POPD: u32 = 1; +pub const BRACE_EXPANSION: u32 = 1; +pub const READLINE: u32 = 1; +pub const BANG_HISTORY: u32 = 1; +pub const HISTORY: u32 = 1; +pub const HELP_BUILTIN: u32 = 1; +pub const RESTRICTED_SHELL: u32 = 1; +pub const PROCESS_SUBSTITUTION: u32 = 1; +pub const PROMPT_STRING_DECODE: u32 = 1; +pub const SELECT_COMMAND: u32 = 1; +pub const COMMAND_TIMING: u32 = 1; +pub const ARRAY_VARS: u32 = 1; +pub const DPAREN_ARITHMETIC: u32 = 1; +pub const EXTENDED_GLOB: u32 = 1; +pub const EXTGLOB_DEFAULT: u32 = 0; +pub const COND_COMMAND: u32 = 1; +pub const COND_REGEXP: u32 = 1; +pub const COPROCESS_SUPPORT: u32 = 1; +pub const ARITH_FOR_COMMAND: u32 = 1; +pub const NETWORK_REDIRECTIONS: u32 = 1; +pub const PROGRAMMABLE_COMPLETION: u32 = 1; +pub const DEBUGGER: u32 = 1; +pub const MEMSCRAMBLE: u32 = 1; +pub const CASEMOD_ATTRS: u32 = 1; +pub const CASEMOD_EXPANSIONS: u32 = 1; +pub const GLOBASCII_DEFAULT: u32 = 1; +pub const FUNCTION_IMPORT: u32 = 1; +pub const ENABLE_NLS: u32 = 1; +pub const DEFAULT_PATH_VALUE: &'static [u8; 63usize] = + b"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.\0"; +pub const STANDARD_UTILS_PATH: &'static [u8; 30usize] = b"/bin:/usr/bin:/usr/sbin:/sbin\0"; +pub const PPROMPT: &'static [u8; 11usize] = b"\\s-\\\\v\\\\$ \0"; +pub const SPROMPT: &'static [u8; 3usize] = b"> \0"; +// pub const DEFAULT_BASHRC: &'static [u8; 10usize] = b"~/.bashrc\0"; +pub const DEFAULT_BASHRC: &'static [u8; 13usize] = b"~/.utshellrc\0"; +// pub const SYS_BASH_LOGOUT: &'static [u8; 22usize] = b"/etc/bash.bash_logout\0"; //åªæœ‰å®šä¹‰ï¼Œæ²¡æœ‰ä½¿ç”¨ +pub const SYS_BASH_LOGOUT: &'static [u8; 28usize] = b"/etc/utshell.utshell_logout\0"; +pub const MULTIPLE_COPROCS: u32 = 0; +pub const CHECKWINSIZE_DEFAULT: u32 = 1; +pub const OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT: u32 = 1; +pub const CHECKHASH_DEFAULT: u32 = 0; +pub const EVALNEST_MAX: u32 = 0; +pub const SOURCENEST_MAX: u32 = 0; +pub const OLDPWD_CHECK_DIRECTORY: u32 = 1; +pub const HISTEXPAND_DEFAULT: u32 = 1; +pub const ASSOC_KVPAIR_ASSIGNMENT: u32 = 1; +pub const HAVE_STRINGIZE: u32 = 1; +pub const HAVE_LONG_DOUBLE: u32 = 1; +pub const PROTOTYPES: u32 = 1; +pub const __PROTOTYPES: u32 = 1; +pub const HAVE_LONG_LONG: u32 = 1; +pub const HAVE_UNSIGNED_LONG_LONG: u32 = 1; +pub const SIZEOF_INT: u32 = 4; +pub const SIZEOF_LONG: u32 = 8; +pub const SIZEOF_CHAR_P: u32 = 8; +pub const SIZEOF_DOUBLE: u32 = 8; +pub const SIZEOF_INTMAX_T: u32 = 8; +pub const SIZEOF_LONG_LONG: u32 = 8; +pub const SIZEOF_WCHAR_T: u32 = 4; + +pub const STDC_HEADERS: u32 = 1; +pub const HAVE_ALLOCA: u32 = 1; +pub const HAVE_ALLOCA_H: u32 = 1; +pub const MAJOR_IN_SYSMACROS: u32 = 1; +pub const HAVE_MBSTATE_T: u32 = 1; +pub const HAVE_QUAD_T: u32 = 1; +pub const HAVE_WCHAR_T: u32 = 1; +pub const HAVE_WCTYPE_T: u32 = 1; +pub const HAVE_WINT_T: u32 = 1; +pub const HAVE_DECL_SYS_SIGLIST: u32 = 1; +pub const UNDER_SYS_SIGLIST_DECLARED: u32 = 1; +pub const HAVE_SYS_SIGLIST: u32 = 1; +pub const HAVE_UNDER_SYS_SIGLIST: u32 = 1; +pub const HAVE_SYS_ERRLIST: u32 = 1; +pub const HAVE_STRUCT_DIRENT_D_INO: u32 = 1; +pub const HAVE_STRUCT_DIRENT_D_FILENO: u32 = 1; +pub const FIONREAD_IN_SYS_IOCTL: u32 = 1; +pub const GWINSZ_IN_SYS_IOCTL: u32 = 1; +pub const STRUCT_WINSIZE_IN_SYS_IOCTL: u32 = 1; +pub const TERMIOS_LDISC: u32 = 1; +pub const TERMIO_LDISC: u32 = 1; +pub const HAVE_STRUCT_STAT_ST_BLOCKS: u32 = 1; +pub const HAVE_STRUCT_TM_TM_ZONE: u32 = 1; +pub const HAVE_TM_ZONE: u32 = 1; +pub const HAVE_TIMEVAL: u32 = 1; +pub const HAVE_STRUCT_TIMEZONE: u32 = 1; +pub const WEXITSTATUS_OFFSET: u32 = 8; +pub const HAVE_STRUCT_TIMESPEC: u32 = 1; +pub const TIME_H_DEFINES_STRUCT_TIMESPEC: u32 = 1; +pub const HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC: u32 = 1; +pub const TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC: u32 = 1; +pub const HAVE_GETPW_DECLS: u32 = 1; +pub const HAVE_DECL_AUDIT_USER_TTY: u32 = 1; +pub const HAVE_DECL_CONFSTR: u32 = 1; +pub const HAVE_DECL_PRINTF: u32 = 1; +pub const HAVE_DECL_SBRK: u32 = 1; +pub const HAVE_DECL_STRCPY: u32 = 1; +pub const HAVE_DECL_STRSIGNAL: u32 = 1; +pub const HAVE_DECL_STRTOLD: u32 = 1; +pub const HAVE_DECL_STRTOIMAX: u32 = 1; +pub const HAVE_DECL_STRTOL: u32 = 1; +pub const HAVE_DECL_STRTOLL: u32 = 1; +pub const HAVE_DECL_STRTOUL: u32 = 1; +pub const HAVE_DECL_STRTOULL: u32 = 1; +pub const HAVE_DECL_STRTOUMAX: u32 = 1; +pub const GETPGRP_VOID: u32 = 1; +pub const PGRP_PIPE: u32 = 1; +pub const ULIMIT_MAXFDS: u32 = 1; +pub const CAN_REDEFINE_GETENV: u32 = 1; +pub const HAVE_STD_PUTENV: u32 = 1; +pub const HAVE_STD_UNSETENV: u32 = 1; +pub const HAVE_PRINTF_A_FORMAT: u32 = 1; +pub const HAVE_LANGINFO_CODESET: u32 = 1; +pub const HAVE_HASH_BANG_EXEC: u32 = 1; +pub const HAVE_DEV_FD: u32 = 1; +pub const DEV_FD_PREFIX: &'static [u8; 9usize] = b"/dev/fd/\0"; +pub const HAVE_DEV_STDIN: u32 = 1; +pub const VOID_SIGHANDLER: u32 = 1; +pub const HAVE_POSIX_SIGNALS: u32 = 1; +pub const HAVE_ASPRINTF: u32 = 1; +pub const HAVE_BCOPY: u32 = 1; +pub const HAVE_BZERO: u32 = 1; +pub const HAVE_CHOWN: u32 = 1; +pub const HAVE_CONFSTR: u32 = 1; +pub const HAVE_DLCLOSE: u32 = 1; +pub const HAVE_DLOPEN: u32 = 1; +pub const HAVE_DLSYM: u32 = 1; +pub const HAVE_DPRINTF: u32 = 1; +pub const HAVE_DUP2: u32 = 1; +pub const HAVE_EACCESS: u32 = 1; +pub const HAVE_FACCESSAT: u32 = 1; +pub const HAVE_FCNTL: u32 = 1; +pub const HAVE_FNMATCH: u32 = 1; +pub const FNMATCH_EQUIV_FALLBACK: u32 = 1; +pub const HAVE___FPURGE: u32 = 1; +pub const HAVE_DECL_FPURGE: u32 = 0; +pub const HAVE_GETADDRINFO: u32 = 1; +pub const HAVE_GETCWD: u32 = 1; +pub const HAVE_GETENTROPY: u32 = 1; +pub const HAVE_GETDTABLESIZE: u32 = 1; +pub const HAVE_GETGROUPS: u32 = 1; +pub const HAVE_GETHOSTBYNAME: u32 = 1; +pub const HAVE_GETHOSTNAME: u32 = 1; +pub const HAVE_GETPAGESIZE: u32 = 1; +pub const HAVE_GETPEERNAME: u32 = 1; +pub const HAVE_GETPWENT: u32 = 1; +pub const HAVE_GETPWNAM: u32 = 1; +pub const HAVE_GETPWUID: u32 = 1; +pub const HAVE_GETRANDOM: u32 = 1; +pub const HAVE_GETRLIMIT: u32 = 1; +pub const HAVE_GETRUSAGE: u32 = 1; +pub const HAVE_GETSERVBYNAME: u32 = 1; +pub const HAVE_GETSERVENT: u32 = 1; +pub const HAVE_GETTIMEOFDAY: u32 = 1; +pub const HAVE_ICONV: u32 = 1; +pub const HAVE_IMAXDIV: u32 = 1; +pub const HAVE_INET_ATON: u32 = 1; +pub const HAVE_ISASCII: u32 = 1; +pub const HAVE_ISBLANK: u32 = 1; +pub const HAVE_ISGRAPH: u32 = 1; +pub const HAVE_ISPRINT: u32 = 1; +pub const HAVE_ISSPACE: u32 = 1; +pub const HAVE_ISWCTYPE: u32 = 1; +pub const HAVE_ISWLOWER: u32 = 1; +pub const HAVE_ISWUPPER: u32 = 1; +pub const HAVE_ISXDIGIT: u32 = 1; +pub const HAVE_KILL: u32 = 1; +pub const HAVE_KILLPG: u32 = 1; +pub const HAVE_LSTAT: u32 = 1; +pub const HAVE_MBRLEN: u32 = 1; +pub const HAVE_MBRTOWC: u32 = 1; +pub const HAVE_MBSNRTOWCS: u32 = 1; +pub const HAVE_MBSRTOWCS: u32 = 1; +pub const HAVE_MEMMOVE: u32 = 1; +pub const HAVE_MEMSET: u32 = 1; +pub const HAVE_MKDTEMP: u32 = 1; +pub const HAVE_MKFIFO: u32 = 1; +pub const HAVE_MKSTEMP: u32 = 1; +pub const HAVE_PATHCONF: u32 = 1; +pub const HAVE_PSELECT: u32 = 1; +pub const HAVE_PREAD: u32 = 1; +pub const HAVE_PUTENV: u32 = 1; +pub const HAVE_RAISE: u32 = 1; +pub const HAVE_RANDOM: u32 = 1; +pub const HAVE_READLINK: u32 = 1; +pub const HAVE_REGCOMP: u32 = 1; +pub const HAVE_REGEXEC: u32 = 1; +pub const HAVE_RENAME: u32 = 1; +pub const HAVE_SBRK: u32 = 1; +pub const HAVE_SELECT: u32 = 1; +pub const HAVE_SETENV: u32 = 1; +pub const HAVE_SETITIMER: u32 = 1; +pub const HAVE_SETLINEBUF: u32 = 1; +pub const HAVE_SETLOCALE: u32 = 1; +pub const HAVE_DECL_SETREGID: u32 = 1; +pub const HAVE_SETRESGID: u32 = 1; +pub const HAVE_SETRESUID: u32 = 1; +pub const HAVE_SETVBUF: u32 = 1; +pub const HAVE_SIGINTERRUPT: u32 = 1; +pub const HAVE_POSIX_SIGSETJMP: u32 = 1; +pub const HAVE_SNPRINTF: u32 = 1; +pub const HAVE_STRCASECMP: u32 = 1; +pub const HAVE_STRCASESTR: u32 = 1; +pub const HAVE_STRCHR: u32 = 1; +pub const HAVE_STRCHRNUL: u32 = 1; +pub const HAVE_STRCOLL: u32 = 1; +pub const HAVE_STRERROR: u32 = 1; +pub const HAVE_STRFTIME: u32 = 1; +pub const HAVE_STRNLEN: u32 = 1; +pub const HAVE_STRPBRK: u32 = 1; +pub const HAVE_STRSTR: u32 = 1; +pub const HAVE_STRTOD: u32 = 1; +pub const HAVE_STRTOIMAX: u32 = 1; +pub const HAVE_STRTOL: u32 = 1; +pub const HAVE_STRTOLL: u32 = 1; +pub const HAVE_STRTOUL: u32 = 1; +pub const HAVE_STRTOULL: u32 = 1; +pub const HAVE_STRTOUMAX: u32 = 1; +pub const HAVE_STRSIGNAL: u32 = 1; +pub const HAVE_SYSCONF: u32 = 1; +pub const HAVE_SYSLOG: u32 = 1; +pub const HAVE_TCGETATTR: u32 = 1; +pub const HAVE_TCGETPGRP: u32 = 1; +pub const HAVE_TIMES: u32 = 1; +pub const HAVE_TOWLOWER: u32 = 1; +pub const HAVE_TOWUPPER: u32 = 1; +pub const HAVE_TTYNAME: u32 = 1; +pub const HAVE_TZSET: u32 = 1; +pub const HAVE_ULIMIT: u32 = 1; +pub const HAVE_UNAME: u32 = 1; +pub const HAVE_UNSETENV: u32 = 1; +pub const HAVE_VASPRINTF: u32 = 1; +pub const HAVE_VPRINTF: u32 = 1; +pub const HAVE_VSNPRINTF: u32 = 1; +pub const HAVE_WAITPID: u32 = 1; +pub const HAVE_WAIT3: u32 = 1; +pub const HAVE_WCRTOMB: u32 = 1; +pub const HAVE_WCSCOLL: u32 = 1; +pub const HAVE_WCSDUP: u32 = 1; +pub const HAVE_WCTYPE: u32 = 1; +pub const HAVE_WCSWIDTH: u32 = 1; +pub const HAVE_WCWIDTH: u32 = 1; +pub const HAVE_ARPA_INET_H: u32 = 1; +pub const HAVE_DIRENT_H: u32 = 1; +pub const HAVE_DLFCN_H: u32 = 1; +pub const HAVE_GRP_H: u32 = 1; +pub const HAVE_INTTYPES_H: u32 = 1; +pub const HAVE_LANGINFO_H: u32 = 1; +pub const HAVE_LIMITS_H: u32 = 1; +pub const HAVE_LOCALE_H: u32 = 1; +pub const HAVE_NETDB_H: u32 = 1; +pub const HAVE_NETINET_IN_H: u32 = 1; +pub const HAVE_PWD_H: u32 = 1; +pub const HAVE_REGEX_H: u32 = 1; +pub const HAVE_STDLIB_H: u32 = 1; +pub const HAVE_STDARG_H: u32 = 1; +pub const HAVE_STRING_H: u32 = 1; +pub const HAVE_STRINGS_H: u32 = 1; +pub const HAVE_MEMORY_H: u32 = 1; +pub const HAVE_STDBOOL_H: u32 = 1; +pub const HAVE_STDDEF_H: u32 = 1; +pub const HAVE_STDINT_H: u32 = 1; +pub const HAVE_SYSLOG_H: u32 = 1; +pub const HAVE_SYS_FILE_H: u32 = 1; +pub const HAVE_SYS_IOCTL_H: u32 = 1; +pub const HAVE_SYS_MMAN_H: u32 = 1; +pub const HAVE_SYS_PARAM_H: u32 = 1; +pub const HAVE_SYS_RANDOM_H: u32 = 1; +pub const HAVE_SYS_RESOURCE_H: u32 = 1; +pub const HAVE_SYS_SELECT_H: u32 = 1; +pub const HAVE_SYS_SOCKET_H: u32 = 1; +pub const HAVE_SYS_STAT_H: u32 = 1; +pub const HAVE_SYS_TIME_H: u32 = 1; +pub const TIME_WITH_SYS_TIME: u32 = 1; +pub const HAVE_SYS_TIMES_H: u32 = 1; +pub const HAVE_SYS_TYPES_H: u32 = 1; +pub const HAVE_SYS_WAIT_H: u32 = 1; +pub const HAVE_TERMCAP_H: u32 = 1; +pub const HAVE_TERMIO_H: u32 = 1; +pub const HAVE_TERMIOS_H: u32 = 1; +pub const HAVE_ULIMIT_H: u32 = 1; +pub const HAVE_UNISTD_H: u32 = 1; +pub const HAVE_WCHAR_H: u32 = 1; +pub const HAVE_WCTYPE_H: u32 = 1; +pub const HAVE_LIBDL: u32 = 1; +pub const HAVE_ARGZ_H: u32 = 1; +pub const HAVE_ERRNO_H: u32 = 1; +pub const HAVE_FCNTL_H: u32 = 1; +pub const HAVE_MALLOC_H: u32 = 1; +pub const HAVE_STDIO_EXT_H: u32 = 1; +pub const HAVE_DCGETTEXT: u32 = 1; +pub const HAVE_LOCALECONV: u32 = 1; +pub const HAVE_MEMPCPY: u32 = 1; +pub const HAVE_MMAP: u32 = 1; +pub const HAVE_MREMAP: u32 = 1; +pub const HAVE_MUNMAP: u32 = 1; +pub const HAVE_STPCPY: u32 = 1; +pub const HAVE_STRCSPN: u32 = 1; +pub const HAVE_STRDUP: u32 = 1; +pub const HAVE___ARGZ_COUNT: u32 = 1; +pub const HAVE___ARGZ_NEXT: u32 = 1; +pub const HAVE___ARGZ_STRINGIFY: u32 = 1; +pub const RESTRICTED_SHELL_NAME: &'static [u8; 6usize] = b"rbash\0"; +pub const _WCHAR_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _ISOC95_SOURCE: u32 = 1; +pub const _ISOC99_SOURCE: u32 = 1; +pub const _ISOC11_SOURCE: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const _XOPEN_SOURCE: u32 = 700; +pub const _XOPEN_SOURCE_EXTENDED: u32 = 1; +pub const _LARGEFILE64_SOURCE: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const __USE_XOPEN: u32 = 1; +pub const __USE_XOPEN_EXTENDED: u32 = 1; +pub const __USE_UNIX98: u32 = 1; +pub const _LARGEFILE_SOURCE: u32 = 1; +pub const __USE_XOPEN2K8XSI: u32 = 1; +pub const __USE_XOPEN2KXSI: u32 = 1; +pub const __USE_LARGEFILE: u32 = 1; +pub const __USE_LARGEFILE64: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_GNU: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: u32 = 201706; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 28; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __HAVE_GENERIC_SELECTION: u32 = 1; +pub const __GLIBC_USE_LIB_EXT2: u32 = 1; +pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 1; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 1; +pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 1; +pub const __HAVE_FLOAT128: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT128: u32 = 0; +pub const __HAVE_FLOAT64X: u32 = 1; +pub const __HAVE_FLOAT64X_LONG_DOUBLE: u32 = 1; +pub const __HAVE_FLOAT16: u32 = 0; +pub const __HAVE_FLOAT32: u32 = 1; +pub const __HAVE_FLOAT64: u32 = 1; +pub const __HAVE_FLOAT32X: u32 = 1; +pub const __HAVE_FLOAT128X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT16: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT32: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT64: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT32X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT64X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT128X: u32 = 0; +pub const __HAVE_FLOATN_NOT_TYPEDEF: u32 = 0; +pub const __GNUC_VA_LIST: u32 = 1; +pub const _BITS_WCHAR_H: u32 = 1; +pub const __wint_t_defined: u32 = 1; +pub const _WINT_T: u32 = 1; +pub const __mbstate_t_defined: u32 = 1; +pub const ____mbstate_t_defined: u32 = 1; +pub const ____FILE_defined: u32 = 1; +pub const __FILE_defined: u32 = 1; +pub const _BITS_TYPES_LOCALE_T_H: u32 = 1; +pub const _BITS_TYPES___LOCALE_T_H: u32 = 1; +pub const WEOF: u32 = 4294967295; +pub const _WCTYPE_H: u32 = 1; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const _BITS_WCTYPE_WCHAR_H: u32 = 1; +pub const _ENDIAN_H: u32 = 1; +pub const __LITTLE_ENDIAN: u32 = 1234; +pub const __BIG_ENDIAN: u32 = 4321; +pub const __PDP_ENDIAN: u32 = 3412; +pub const __BYTE_ORDER: u32 = 1234; +pub const __FLOAT_WORD_ORDER: u32 = 1234; +pub const LITTLE_ENDIAN: u32 = 1234; +pub const BIG_ENDIAN: u32 = 4321; +pub const PDP_ENDIAN: u32 = 3412; +pub const BYTE_ORDER: u32 = 1234; +pub const _BITS_BYTESWAP_H: u32 = 1; +pub const _BITS_UINTN_IDENTITY_H: u32 = 1; +pub const HANDLE_MULTIBYTE: u32 = 1; +pub const _LIBC_LIMITS_H_: u32 = 1; + +pub const CHAR_WIDTH: u32 = 8; +pub const SCHAR_WIDTH: u32 = 8; +pub const UCHAR_WIDTH: u32 = 8; +pub const SHRT_WIDTH: u32 = 16; +pub const USHRT_WIDTH: u32 = 16; +pub const INT_WIDTH: u32 = 32; +pub const UINT_WIDTH: u32 = 32; +pub const LONG_WIDTH: u32 = 64; +pub const ULONG_WIDTH: u32 = 64; +pub const LLONG_WIDTH: u32 = 64; +pub const ULLONG_WIDTH: u32 = 64; +pub const _BITS_POSIX1_LIM_H: u32 = 1; +pub const _POSIX_AIO_LISTIO_MAX: u32 = 2; +pub const _POSIX_AIO_MAX: u32 = 1; +pub const _POSIX_ARG_MAX: u32 = 4096; +pub const _POSIX_CHILD_MAX: u32 = 25; +pub const _POSIX_DELAYTIMER_MAX: u32 = 32; +pub const _POSIX_HOST_NAME_MAX: u32 = 255; +pub const _POSIX_LINK_MAX: u32 = 8; +pub const _POSIX_LOGIN_NAME_MAX: u32 = 9; +pub const _POSIX_MAX_CANON: u32 = 255; +pub const _POSIX_MAX_INPUT: u32 = 255; +pub const _POSIX_MQ_OPEN_MAX: u32 = 8; +pub const _POSIX_MQ_PRIO_MAX: u32 = 32; +pub const _POSIX_NAME_MAX: u32 = 14; +pub const _POSIX_NGROUPS_MAX: u32 = 8; +pub const _POSIX_OPEN_MAX: u32 = 20; +pub const _POSIX_FD_SETSIZE: u32 = 20; +pub const _POSIX_PATH_MAX: u32 = 256; +pub const _POSIX_PIPE_BUF: u32 = 512; +pub const _POSIX_RE_DUP_MAX: u32 = 255; +pub const _POSIX_RTSIG_MAX: u32 = 8; +pub const _POSIX_SEM_NSEMS_MAX: u32 = 256; +pub const _POSIX_SEM_VALUE_MAX: u32 = 32767; +pub const _POSIX_SIGQUEUE_MAX: u32 = 32; +pub const _POSIX_SSIZE_MAX: u32 = 32767; +pub const _POSIX_STREAM_MAX: u32 = 8; +pub const _POSIX_SYMLINK_MAX: u32 = 255; +pub const _POSIX_SYMLOOP_MAX: u32 = 8; +pub const _POSIX_TIMER_MAX: u32 = 32; +pub const _POSIX_TTY_NAME_MAX: u32 = 9; +pub const _POSIX_TZNAME_MAX: u32 = 6; +pub const _POSIX_QLIMIT: u32 = 1; +pub const _POSIX_HIWAT: u32 = 512; +pub const _POSIX_UIO_MAXIOV: u32 = 16; +pub const _POSIX_CLOCKRES_MIN: u32 = 20000000; +pub const NR_OPEN: u32 = 1024; +pub const NGROUPS_MAX: u32 = 65536; +pub const ARG_MAX: u32 = 131072; +pub const LINK_MAX: u32 = 127; +pub const MAX_CANON: u32 = 255; +pub const MAX_INPUT: u32 = 255; +pub const NAME_MAX: u32 = 255; + +pub const PIPE_BUF: u32 = 4096; +pub const XATTR_NAME_MAX: u32 = 255; +pub const XATTR_SIZE_MAX: u32 = 65536; +pub const XATTR_LIST_MAX: u32 = 65536; +pub const RTSIG_MAX: u32 = 32; +pub const _POSIX_THREAD_KEYS_MAX: u32 = 128; +pub const PTHREAD_KEYS_MAX: u32 = 1024; +pub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: u32 = 4; +pub const PTHREAD_DESTRUCTOR_ITERATIONS: u32 = 4; +pub const _POSIX_THREAD_THREADS_MAX: u32 = 64; +pub const AIO_PRIO_DELTA_MAX: u32 = 20; +pub const PTHREAD_STACK_MIN: u32 = 16384; +pub const DELAYTIMER_MAX: u32 = 2147483647; +pub const TTY_NAME_MAX: u32 = 32; +pub const LOGIN_NAME_MAX: u32 = 256; +pub const HOST_NAME_MAX: u32 = 64; +pub const MQ_PRIO_MAX: u32 = 32768; +pub const SEM_VALUE_MAX: u32 = 2147483647; +pub const _BITS_POSIX2_LIM_H: u32 = 1; +pub const _POSIX2_BC_BASE_MAX: u32 = 99; +pub const _POSIX2_BC_DIM_MAX: u32 = 2048; +pub const _POSIX2_BC_SCALE_MAX: u32 = 99; +pub const _POSIX2_BC_STRING_MAX: u32 = 1000; +pub const _POSIX2_COLL_WEIGHTS_MAX: u32 = 2; +pub const _POSIX2_EXPR_NEST_MAX: u32 = 32; +pub const _POSIX2_LINE_MAX: u32 = 2048; +pub const _POSIX2_RE_DUP_MAX: u32 = 255; +pub const _POSIX2_CHARCLASS_NAME_MAX: u32 = 14; +pub const BC_BASE_MAX: u32 = 99; +pub const BC_DIM_MAX: u32 = 2048; +pub const BC_SCALE_MAX: u32 = 99; +pub const BC_STRING_MAX: u32 = 1000; +pub const COLL_WEIGHTS_MAX: u32 = 255; +pub const EXPR_NEST_MAX: u32 = 32; +pub const LINE_MAX: u32 = 2048; +pub const CHARCLASS_NAME_MAX: u32 = 2048; +pub const RE_DUP_MAX: u32 = 32767; +pub const _XOPEN_LIM_H: u32 = 1; +pub const _XOPEN_IOV_MAX: u32 = 16; +pub const _BITS_UIO_LIM_H: u32 = 1; +pub const __IOV_MAX: u32 = 1024; +pub const IOV_MAX: u32 = 1024; +pub const NL_ARGMAX: u32 = 4096; +pub const NL_LANGMAX: u32 = 2048; +pub const NZERO: u32 = 20; +pub const WORD_BIT: u32 = 32; +pub const LONG_BIT: u32 = 64; +pub const _UNISTD_H: u32 = 1; +pub const _POSIX_VERSION: u32 = 200809; +pub const __POSIX2_THIS_VERSION: u32 = 200809; +pub const _POSIX2_VERSION: u32 = 200809; +pub const _POSIX2_C_VERSION: u32 = 200809; +pub const _POSIX2_C_BIND: u32 = 200809; +pub const _POSIX2_C_DEV: u32 = 200809; +pub const _POSIX2_SW_DEV: u32 = 200809; +pub const _POSIX2_LOCALEDEF: u32 = 200809; +pub const _XOPEN_VERSION: u32 = 700; +pub const _XOPEN_XCU_VERSION: u32 = 4; +pub const _XOPEN_XPG2: u32 = 1; +pub const _XOPEN_XPG3: u32 = 1; +pub const _XOPEN_XPG4: u32 = 1; +pub const _XOPEN_UNIX: u32 = 1; +pub const _XOPEN_ENH_I18N: u32 = 1; +pub const _XOPEN_LEGACY: u32 = 1; +pub const _BITS_POSIX_OPT_H: u32 = 1; +pub const _POSIX_JOB_CONTROL: u32 = 1; +pub const _POSIX_SAVED_IDS: u32 = 1; +pub const _POSIX_PRIORITY_SCHEDULING: u32 = 200809; +pub const _POSIX_SYNCHRONIZED_IO: u32 = 200809; +pub const _POSIX_FSYNC: u32 = 200809; +pub const _POSIX_MAPPED_FILES: u32 = 200809; +pub const _POSIX_MEMLOCK: u32 = 200809; +pub const _POSIX_MEMLOCK_RANGE: u32 = 200809; +pub const _POSIX_MEMORY_PROTECTION: u32 = 200809; +pub const _POSIX_CHOWN_RESTRICTED: u32 = 0; +pub const _POSIX_VDISABLE: u8 = 0u8; +pub const _POSIX_NO_TRUNC: u32 = 1; +pub const _XOPEN_REALTIME: u32 = 1; +pub const _XOPEN_REALTIME_THREADS: u32 = 1; +pub const _XOPEN_SHM: u32 = 1; +pub const _POSIX_THREADS: u32 = 200809; +pub const _POSIX_REENTRANT_FUNCTIONS: u32 = 1; +pub const _POSIX_THREAD_SAFE_FUNCTIONS: u32 = 200809; +pub const _POSIX_THREAD_PRIORITY_SCHEDULING: u32 = 200809; +pub const _POSIX_THREAD_ATTR_STACKSIZE: u32 = 200809; +pub const _POSIX_THREAD_ATTR_STACKADDR: u32 = 200809; +pub const _POSIX_THREAD_PRIO_INHERIT: u32 = 200809; +pub const _POSIX_THREAD_PRIO_PROTECT: u32 = 200809; +pub const _POSIX_THREAD_ROBUST_PRIO_INHERIT: u32 = 200809; +pub const _POSIX_THREAD_ROBUST_PRIO_PROTECT: i32 = -1; +pub const _POSIX_SEMAPHORES: u32 = 200809; +pub const _POSIX_REALTIME_SIGNALS: u32 = 200809; +pub const _POSIX_ASYNCHRONOUS_IO: u32 = 200809; +pub const _POSIX_ASYNC_IO: u32 = 1; +pub const _LFS_ASYNCHRONOUS_IO: u32 = 1; +pub const _POSIX_PRIORITIZED_IO: u32 = 200809; +pub const _LFS64_ASYNCHRONOUS_IO: u32 = 1; +pub const _LFS_LARGEFILE: u32 = 1; +pub const _LFS64_LARGEFILE: u32 = 1; +pub const _LFS64_STDIO: u32 = 1; +pub const _POSIX_SHARED_MEMORY_OBJECTS: u32 = 200809; +pub const _POSIX_CPUTIME: u32 = 0; +pub const _POSIX_THREAD_CPUTIME: u32 = 0; +pub const _POSIX_REGEXP: u32 = 1; +pub const _POSIX_READER_WRITER_LOCKS: u32 = 200809; +pub const _POSIX_SHELL: u32 = 1; +pub const _POSIX_TIMEOUTS: u32 = 200809; +pub const _POSIX_SPIN_LOCKS: u32 = 200809; +pub const _POSIX_SPAWN: u32 = 200809; +pub const _POSIX_TIMERS: u32 = 200809; +pub const _POSIX_BARRIERS: u32 = 200809; +pub const _POSIX_MESSAGE_PASSING: u32 = 200809; +pub const _POSIX_THREAD_PROCESS_SHARED: u32 = 200809; +pub const _POSIX_MONOTONIC_CLOCK: u32 = 0; +pub const _POSIX_CLOCK_SELECTION: u32 = 200809; +pub const _POSIX_ADVISORY_INFO: u32 = 200809; +pub const _POSIX_IPV6: u32 = 200809; +pub const _POSIX_RAW_SOCKETS: u32 = 200809; +pub const _POSIX2_CHAR_TERM: u32 = 200809; +pub const _POSIX_SPORADIC_SERVER: i32 = -1; +pub const _POSIX_THREAD_SPORADIC_SERVER: i32 = -1; +pub const _POSIX_TRACE: i32 = -1; +pub const _POSIX_TRACE_EVENT_FILTER: i32 = -1; +pub const _POSIX_TRACE_INHERIT: i32 = -1; +pub const _POSIX_TRACE_LOG: i32 = -1; +pub const _POSIX_TYPED_MEMORY_OBJECTS: i32 = -1; +pub const _POSIX_V7_LPBIG_OFFBIG: i32 = -1; +pub const _POSIX_V6_LPBIG_OFFBIG: i32 = -1; +pub const _XBS5_LPBIG_OFFBIG: i32 = -1; +pub const _POSIX_V7_LP64_OFF64: u32 = 1; +pub const _POSIX_V6_LP64_OFF64: u32 = 1; +pub const _XBS5_LP64_OFF64: u32 = 1; +pub const __ILP32_OFF32_CFLAGS: &'static [u8; 5usize] = b"-m32\0"; +pub const __ILP32_OFF32_LDFLAGS: &'static [u8; 5usize] = b"-m32\0"; +pub const __ILP32_OFFBIG_CFLAGS: &'static [u8; 48usize] = + b"-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64\0"; +pub const __ILP32_OFFBIG_LDFLAGS: &'static [u8; 5usize] = b"-m32\0"; +pub const __LP64_OFF64_CFLAGS: &'static [u8; 5usize] = b"-m64\0"; +pub const __LP64_OFF64_LDFLAGS: &'static [u8; 5usize] = b"-m64\0"; +pub const STDIN_FILENO: u32 = 0; +pub const STDOUT_FILENO: u32 = 1; +pub const STDERR_FILENO: u32 = 2; + +pub const F_OK: u32 = 0; +pub const SEEK_SET: u32 = 0; + +pub const SEEK_END: u32 = 2; +pub const SEEK_DATA: u32 = 3; +pub const SEEK_HOLE: u32 = 4; +pub const L_SET: u32 = 0; +pub const L_INCR: u32 = 1; +pub const L_XTND: u32 = 2; +pub const _GETOPT_POSIX_H: u32 = 1; +pub const _GETOPT_CORE_H: u32 = 1; +pub const F_ULOCK: u32 = 0; +pub const F_LOCK: u32 = 1; +pub const F_TLOCK: u32 = 2; +pub const F_TEST: u32 = 3; +pub const _BITS_SIGNUM_H: u32 = 1; +pub const _BITS_SIGNUM_GENERIC_H: u32 = 1; +pub const SIGINT: u32 = 2; +pub const SIGILL: u32 = 4; +pub const SIGABRT: u32 = 6; +pub const SIGFPE: u32 = 8; +pub const SIGSEGV: u32 = 11; +pub const SIGTERM: u32 = 15; +pub const SIGHUP: u32 = 1; +pub const SIGQUIT: u32 = 3; +pub const SIGTRAP: u32 = 5; +pub const SIGKILL: u32 = 9; +// pub const SIGBUS: u32 = 10; +pub const SIGBUS: u32 = 7; +// pub const SIGSYS: u32 = 12; +pub const SIGSYS: u32 = 31; +pub const SIGPIPE: u32 = 13; +pub const SIGALRM: u32 = 14; +// pub const SIGURG: u32 = 16; +pub const SIGURG: u32 = 23; +// pub const SIGSTOP: u32 = 17; +pub const SIGSTOP: u32 = 19; +// pub const SIGTSTP: u32 = 18; +pub const SIGTSTP: u32 = 20; +// pub const SIGCONT: u32 = 19; +pub const SIGCONT: u32 = 18; +// pub const SIGCHLD: u32 = 20; +pub const SIGCHLD: u32 = 17; +pub const SIGTTIN: u32 = 21; +pub const SIGTTOU: u32 = 22; +pub const SIGPOLL: u32 = 23; +pub const SIGXCPU: u32 = 24; +pub const SIGXFSZ: u32 = 25; +pub const SIGVTALRM: u32 = 26; +pub const SIGPROF: u32 = 27; +// pub const SIGUSR1: u32 = 30; +pub const SIGUSR1: u32 = 10; +// pub const SIGUSR2: u32 = 31; +pub const SIGUSR2: u32 = 12; +pub const SIGWINCH: u32 = 28; +// pub const SIGIO: u32 = 23; +pub const SIGIO: u32 = 29; +pub const SIGIOT: u32 = 6; +pub const SIGCLD: u32 = 20; +pub const __SIGRTMIN: u32 = 32; +pub const __SIGRTMAX: u32 = 32; +pub const _NSIG: u32 = 33; +pub const SIGSTKFLT: u32 = 16; +pub const SIGPWR: u32 = 30; +pub const __sig_atomic_t_defined: u32 = 1; +pub const __sigset_t_defined: u32 = 1; +pub const _STRUCT_TIMESPEC: u32 = 1; +pub const __siginfo_t_defined: u32 = 1; +pub const __SI_MAX_SIZE: u32 = 128; +pub const _BITS_SIGINFO_ARCH_H: u32 = 1; +pub const __SI_ERRNO_THEN_CODE: u32 = 1; +pub const __SI_HAVE_SIGSYS: u32 = 1; +pub const _BITS_SIGINFO_CONSTS_H: u32 = 1; +pub const __SI_ASYNCIO_AFTER_SIGIO: u32 = 1; +pub const _BITS_SIGINFO_CONSTS_ARCH_H: u32 = 1; +pub const __sigevent_t_defined: u32 = 1; +pub const __SIGEV_MAX_SIZE: u32 = 64; +pub const __have_pthread_attr_t: u32 = 1; +pub const _BITS_SIGEVENT_CONSTS_H: u32 = 1; + +pub const _BITS_SIGACTION_H: u32 = 1; +pub const SA_NOCLDSTOP: u32 = 1; +pub const SA_NOCLDWAIT: u32 = 2; +pub const SA_SIGINFO: u32 = 4; +pub const SA_ONSTACK: u32 = 134217728; +pub const SA_RESTART: u32 = 268435456; +pub const SA_NODEFER: u32 = 1073741824; +pub const SA_RESETHAND: u32 = 2147483648; +pub const SA_INTERRUPT: u32 = 536870912; +pub const SA_NOMASK: u32 = 1073741824; +pub const SA_ONESHOT: u32 = 2147483648; +pub const SA_STACK: u32 = 134217728; +pub const SIG_BLOCK: u32 = 0; +pub const SIG_UNBLOCK: u32 = 1; +pub const SIG_SETMASK: u32 = 2; +pub const _BITS_SIGCONTEXT_H: u32 = 1; +pub const FP_XSTATE_MAGIC1: u32 = 1179670611; +pub const FP_XSTATE_MAGIC2: u32 = 1179670597; +pub const __stack_t_defined: u32 = 1; +pub const _SYS_UCONTEXT_H: u32 = 1; +pub const __NGREG: u32 = 23; +pub const NGREG: u32 = 23; +pub const _BITS_SIGSTACK_H: u32 = 1; +pub const MINSIGSTKSZ: u32 = 2048; +pub const SIGSTKSZ: u32 = 8192; +pub const _BITS_SS_FLAGS_H: u32 = 1; +pub const __sigstack_defined: u32 = 1; +pub const _BITS_PTHREADTYPES_COMMON_H: u32 = 1; +pub const _THREAD_SHARED_TYPES_H: u32 = 1; +pub const _BITS_PTHREADTYPES_ARCH_H: u32 = 1; +pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40; +pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56; +pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_COND_T: u32 = 48; +pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4; +pub const __PTHREAD_MUTEX_LOCK_ELISION: u32 = 1; +pub const __PTHREAD_MUTEX_NUSERS_AFTER_KIND: u32 = 0; +pub const __PTHREAD_MUTEX_USE_UNION: u32 = 0; +pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1; +pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; +pub const _BITS_SIGTHREAD_H: u32 = 1; +pub const _STDINT_H: u32 = 1; +pub const _BITS_STDINT_INTN_H: u32 = 1; +pub const _BITS_STDINT_UINTN_H: u32 = 1; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i64 = -9223372036854775808; +pub const INT_FAST32_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u64 = 9223372036854775807; +pub const INT_FAST32_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const UINTPTR_MAX: i32 = -1; +pub const PTRDIFF_MIN: i64 = -9223372036854775808; +pub const PTRDIFF_MAX: u64 = 9223372036854775807; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; +pub const INT8_WIDTH: u32 = 8; +pub const UINT8_WIDTH: u32 = 8; +pub const INT16_WIDTH: u32 = 16; +pub const UINT16_WIDTH: u32 = 16; +pub const INT32_WIDTH: u32 = 32; +pub const UINT32_WIDTH: u32 = 32; +pub const INT64_WIDTH: u32 = 64; +pub const UINT64_WIDTH: u32 = 64; +pub const INT_LEAST8_WIDTH: u32 = 8; +pub const UINT_LEAST8_WIDTH: u32 = 8; +pub const INT_LEAST16_WIDTH: u32 = 16; +pub const UINT_LEAST16_WIDTH: u32 = 16; +pub const INT_LEAST32_WIDTH: u32 = 32; +pub const UINT_LEAST32_WIDTH: u32 = 32; +pub const INT_LEAST64_WIDTH: u32 = 64; +pub const UINT_LEAST64_WIDTH: u32 = 64; +pub const INT_FAST8_WIDTH: u32 = 8; +pub const UINT_FAST8_WIDTH: u32 = 8; +pub const INT_FAST16_WIDTH: u32 = 64; +pub const UINT_FAST16_WIDTH: u32 = 64; +pub const INT_FAST32_WIDTH: u32 = 64; +pub const UINT_FAST32_WIDTH: u32 = 64; +pub const INT_FAST64_WIDTH: u32 = 64; +pub const UINT_FAST64_WIDTH: u32 = 64; +pub const INTPTR_WIDTH: u32 = 64; +pub const UINTPTR_WIDTH: u32 = 64; +pub const INTMAX_WIDTH: u32 = 64; +pub const UINTMAX_WIDTH: u32 = 64; +pub const PTRDIFF_WIDTH: u32 = 64; +pub const SIG_ATOMIC_WIDTH: u32 = 32; +pub const SIZE_WIDTH: u32 = 64; +pub const WCHAR_WIDTH: u32 = 32; +pub const WINT_WIDTH: u32 = 32; + +pub const W_SPLITSPACE: u32 = 8; +pub const W_NOSPLIT: u32 = 16; +pub const W_NOGLOB: u32 = 32; +pub const W_NOSPLIT2: u32 = 64; +pub const W_TILDEEXP: u32 = 128; +pub const W_DOLLARAT: u32 = 256; +pub const W_DOLLARSTAR: u32 = 512; +pub const W_NOCOMSUB: u32 = 1024; +pub const W_ASSIGNRHS: u32 = 2048; +pub const W_NOTILDE: u32 = 4096; +pub const W_ITILDE: u32 = 8192; +pub const W_EXPANDRHS: u32 = 16384; +pub const W_COMPASSIGN: u32 = 32768; +pub const W_ASSNBLTIN: u32 = 65536; +pub const W_ASSIGNARG: u32 = 131072; +pub const W_HASQUOTEDNULL: u32 = 262144; +pub const W_DQUOTE: u32 = 524288; +pub const W_NOPROCSUB: u32 = 1048576; +pub const W_SAWQUOTEDNULL: u32 = 2097152; +pub const W_ASSIGNASSOC: u32 = 4194304; +pub const W_ASSIGNARRAY: u32 = 8388608; +pub const W_ARRAYIND: u32 = 16777216; +pub const W_ASSNGLOBAL: u32 = 33554432; +pub const W_NOBRACE: u32 = 67108864; +pub const W_COMPLETE: u32 = 134217728; +pub const W_CHKLOCAL: u32 = 268435456; +pub const W_NOASSNTILDE: u32 = 536870912; +pub const W_FORCELOCAL: u32 = 1073741824; +pub const PF_NOCOMSUB: u32 = 1; +pub const PF_IGNUNBOUND: u32 = 2; +pub const PF_NOSPLIT2: u32 = 4; +pub const PF_ASSIGNRHS: u32 = 8; +pub const PF_COMPLETE: u32 = 16; +pub const PF_EXPANDRHS: u32 = 32; +pub const PF_ALLINDS: u32 = 64; + +pub const SUBSHELL_PAREN: u32 = 2; +pub const SUBSHELL_COMSUB: u32 = 4; +pub const SUBSHELL_FORK: u32 = 8; +pub const SUBSHELL_PIPE: u32 = 16; +pub const SUBSHELL_PROCSUB: u32 = 32; +pub const SUBSHELL_COPROC: u32 = 64; +pub const SUBSHELL_RESETTRAP: u32 = 128; + +pub const CASEPAT_FALLTHROUGH: u32 = 1; +pub const CASEPAT_TESTNEXT: u32 = 2; +pub const COND_AND: u32 = 1; +pub const COND_OR: u32 = 2; +pub const COND_UNARY: u32 = 3; +pub const COND_BINARY: u32 = 4; +pub const COND_TERM: u32 = 5; +pub const COND_EXPR: u32 = 6; +pub const COPROC_RUNNING: u32 = 1; +pub const COPROC_DEAD: u32 = 2; +pub const CMDERR_DEFAULT: u32 = 0; +pub const CMDERR_BADTYPE: u32 = 1; +pub const CMDERR_BADCONN: u32 = 2; +pub const CMDERR_BADJUMP: u32 = 3; +pub const CMDERR_LAST: u32 = 3; +pub const _SYS_TYPES_H: u32 = 1; +pub const __clock_t_defined: u32 = 1; +pub const __clockid_t_defined: u32 = 1; +pub const __time_t_defined: u32 = 1; +pub const __timer_t_defined: u32 = 1; +pub const __BIT_TYPES_DEFINED__: u32 = 1; +pub const _SYS_SELECT_H: u32 = 1; +pub const __FD_ZERO_STOS: &'static [u8; 6usize] = b"stosq\0"; +pub const __timeval_defined: u32 = 1; +pub const FD_SETSIZE: u32 = 1024; +pub const _INTTYPES_H: u32 = 1; +pub const ____gwchar_t_defined: u32 = 1; +pub const __PRI64_PREFIX: &'static [u8; 2usize] = b"l\0"; +pub const __PRIPTR_PREFIX: &'static [u8; 2usize] = b"l\0"; +pub const PRId8: &'static [u8; 2usize] = b"d\0"; +pub const PRId16: &'static [u8; 2usize] = b"d\0"; +pub const PRId32: &'static [u8; 2usize] = b"d\0"; +pub const PRId64: &'static [u8; 3usize] = b"ld\0"; +pub const PRIdLEAST8: &'static [u8; 2usize] = b"d\0"; +pub const PRIdLEAST16: &'static [u8; 2usize] = b"d\0"; +pub const PRIdLEAST32: &'static [u8; 2usize] = b"d\0"; +pub const PRIdLEAST64: &'static [u8; 3usize] = b"ld\0"; +pub const PRIdFAST8: &'static [u8; 2usize] = b"d\0"; +pub const PRIdFAST16: &'static [u8; 3usize] = b"ld\0"; +pub const PRIdFAST32: &'static [u8; 3usize] = b"ld\0"; +pub const PRIdFAST64: &'static [u8; 3usize] = b"ld\0"; +pub const PRIi8: &'static [u8; 2usize] = b"i\0"; +pub const PRIi16: &'static [u8; 2usize] = b"i\0"; +pub const PRIi32: &'static [u8; 2usize] = b"i\0"; +pub const PRIi64: &'static [u8; 3usize] = b"li\0"; +pub const PRIiLEAST8: &'static [u8; 2usize] = b"i\0"; +pub const PRIiLEAST16: &'static [u8; 2usize] = b"i\0"; +pub const PRIiLEAST32: &'static [u8; 2usize] = b"i\0"; +pub const PRIiLEAST64: &'static [u8; 3usize] = b"li\0"; +pub const PRIiFAST8: &'static [u8; 2usize] = b"i\0"; +pub const PRIiFAST16: &'static [u8; 3usize] = b"li\0"; +pub const PRIiFAST32: &'static [u8; 3usize] = b"li\0"; +pub const PRIiFAST64: &'static [u8; 3usize] = b"li\0"; +pub const PRIo8: &'static [u8; 2usize] = b"o\0"; +pub const PRIo16: &'static [u8; 2usize] = b"o\0"; +pub const PRIo32: &'static [u8; 2usize] = b"o\0"; +pub const PRIo64: &'static [u8; 3usize] = b"lo\0"; +pub const PRIoLEAST8: &'static [u8; 2usize] = b"o\0"; +pub const PRIoLEAST16: &'static [u8; 2usize] = b"o\0"; +pub const PRIoLEAST32: &'static [u8; 2usize] = b"o\0"; +pub const PRIoLEAST64: &'static [u8; 3usize] = b"lo\0"; +pub const PRIoFAST8: &'static [u8; 2usize] = b"o\0"; +pub const PRIoFAST16: &'static [u8; 3usize] = b"lo\0"; +pub const PRIoFAST32: &'static [u8; 3usize] = b"lo\0"; +pub const PRIoFAST64: &'static [u8; 3usize] = b"lo\0"; +pub const PRIu8: &'static [u8; 2usize] = b"u\0"; +pub const PRIu16: &'static [u8; 2usize] = b"u\0"; +pub const PRIu32: &'static [u8; 2usize] = b"u\0"; +pub const PRIu64: &'static [u8; 3usize] = b"lu\0"; +pub const PRIuLEAST8: &'static [u8; 2usize] = b"u\0"; +pub const PRIuLEAST16: &'static [u8; 2usize] = b"u\0"; +pub const PRIuLEAST32: &'static [u8; 2usize] = b"u\0"; +pub const PRIuLEAST64: &'static [u8; 3usize] = b"lu\0"; +pub const PRIuFAST8: &'static [u8; 2usize] = b"u\0"; +pub const PRIuFAST16: &'static [u8; 3usize] = b"lu\0"; +pub const PRIuFAST32: &'static [u8; 3usize] = b"lu\0"; +pub const PRIuFAST64: &'static [u8; 3usize] = b"lu\0"; +pub const PRIx8: &'static [u8; 2usize] = b"x\0"; +pub const PRIx16: &'static [u8; 2usize] = b"x\0"; +pub const PRIx32: &'static [u8; 2usize] = b"x\0"; +pub const PRIx64: &'static [u8; 3usize] = b"lx\0"; +pub const PRIxLEAST8: &'static [u8; 2usize] = b"x\0"; +pub const PRIxLEAST16: &'static [u8; 2usize] = b"x\0"; +pub const PRIxLEAST32: &'static [u8; 2usize] = b"x\0"; +pub const PRIxLEAST64: &'static [u8; 3usize] = b"lx\0"; +pub const PRIxFAST8: &'static [u8; 2usize] = b"x\0"; +pub const PRIxFAST16: &'static [u8; 3usize] = b"lx\0"; +pub const PRIxFAST32: &'static [u8; 3usize] = b"lx\0"; +pub const PRIxFAST64: &'static [u8; 3usize] = b"lx\0"; +pub const PRIX8: &'static [u8; 2usize] = b"X\0"; +pub const PRIX16: &'static [u8; 2usize] = b"X\0"; +pub const PRIX32: &'static [u8; 2usize] = b"X\0"; +pub const PRIX64: &'static [u8; 3usize] = b"lX\0"; +pub const PRIXLEAST8: &'static [u8; 2usize] = b"X\0"; +pub const PRIXLEAST16: &'static [u8; 2usize] = b"X\0"; +pub const PRIXLEAST32: &'static [u8; 2usize] = b"X\0"; +pub const PRIXLEAST64: &'static [u8; 3usize] = b"lX\0"; +pub const PRIXFAST8: &'static [u8; 2usize] = b"X\0"; +pub const PRIXFAST16: &'static [u8; 3usize] = b"lX\0"; +pub const PRIXFAST32: &'static [u8; 3usize] = b"lX\0"; +pub const PRIXFAST64: &'static [u8; 3usize] = b"lX\0"; +pub const PRIdMAX: &'static [u8; 3usize] = b"ld\0"; +pub const PRIiMAX: &'static [u8; 3usize] = b"li\0"; +pub const PRIoMAX: &'static [u8; 3usize] = b"lo\0"; +pub const PRIuMAX: &'static [u8; 3usize] = b"lu\0"; +pub const PRIxMAX: &'static [u8; 3usize] = b"lx\0"; +pub const PRIXMAX: &'static [u8; 3usize] = b"lX\0"; +pub const PRIdPTR: &'static [u8; 3usize] = b"ld\0"; +pub const PRIiPTR: &'static [u8; 3usize] = b"li\0"; +pub const PRIoPTR: &'static [u8; 3usize] = b"lo\0"; +pub const PRIuPTR: &'static [u8; 3usize] = b"lu\0"; +pub const PRIxPTR: &'static [u8; 3usize] = b"lx\0"; +pub const PRIXPTR: &'static [u8; 3usize] = b"lX\0"; +pub const SCNd8: &'static [u8; 4usize] = b"hhd\0"; +pub const SCNd16: &'static [u8; 3usize] = b"hd\0"; +pub const SCNd32: &'static [u8; 2usize] = b"d\0"; +pub const SCNd64: &'static [u8; 3usize] = b"ld\0"; +pub const SCNdLEAST8: &'static [u8; 4usize] = b"hhd\0"; +pub const SCNdLEAST16: &'static [u8; 3usize] = b"hd\0"; +pub const SCNdLEAST32: &'static [u8; 2usize] = b"d\0"; +pub const SCNdLEAST64: &'static [u8; 3usize] = b"ld\0"; +pub const SCNdFAST8: &'static [u8; 4usize] = b"hhd\0"; +pub const SCNdFAST16: &'static [u8; 3usize] = b"ld\0"; +pub const SCNdFAST32: &'static [u8; 3usize] = b"ld\0"; +pub const SCNdFAST64: &'static [u8; 3usize] = b"ld\0"; +pub const SCNi8: &'static [u8; 4usize] = b"hhi\0"; +pub const SCNi16: &'static [u8; 3usize] = b"hi\0"; +pub const SCNi32: &'static [u8; 2usize] = b"i\0"; +pub const SCNi64: &'static [u8; 3usize] = b"li\0"; +pub const SCNiLEAST8: &'static [u8; 4usize] = b"hhi\0"; +pub const SCNiLEAST16: &'static [u8; 3usize] = b"hi\0"; +pub const SCNiLEAST32: &'static [u8; 2usize] = b"i\0"; +pub const SCNiLEAST64: &'static [u8; 3usize] = b"li\0"; +pub const SCNiFAST8: &'static [u8; 4usize] = b"hhi\0"; +pub const SCNiFAST16: &'static [u8; 3usize] = b"li\0"; +pub const SCNiFAST32: &'static [u8; 3usize] = b"li\0"; +pub const SCNiFAST64: &'static [u8; 3usize] = b"li\0"; +pub const SCNu8: &'static [u8; 4usize] = b"hhu\0"; +pub const SCNu16: &'static [u8; 3usize] = b"hu\0"; +pub const SCNu32: &'static [u8; 2usize] = b"u\0"; +pub const SCNu64: &'static [u8; 3usize] = b"lu\0"; +pub const SCNuLEAST8: &'static [u8; 4usize] = b"hhu\0"; +pub const SCNuLEAST16: &'static [u8; 3usize] = b"hu\0"; +pub const SCNuLEAST32: &'static [u8; 2usize] = b"u\0"; +pub const SCNuLEAST64: &'static [u8; 3usize] = b"lu\0"; +pub const SCNuFAST8: &'static [u8; 4usize] = b"hhu\0"; +pub const SCNuFAST16: &'static [u8; 3usize] = b"lu\0"; +pub const SCNuFAST32: &'static [u8; 3usize] = b"lu\0"; +pub const SCNuFAST64: &'static [u8; 3usize] = b"lu\0"; +pub const SCNo8: &'static [u8; 4usize] = b"hho\0"; +pub const SCNo16: &'static [u8; 3usize] = b"ho\0"; +pub const SCNo32: &'static [u8; 2usize] = b"o\0"; +pub const SCNo64: &'static [u8; 3usize] = b"lo\0"; +pub const SCNoLEAST8: &'static [u8; 4usize] = b"hho\0"; +pub const SCNoLEAST16: &'static [u8; 3usize] = b"ho\0"; +pub const SCNoLEAST32: &'static [u8; 2usize] = b"o\0"; +pub const SCNoLEAST64: &'static [u8; 3usize] = b"lo\0"; +pub const SCNoFAST8: &'static [u8; 4usize] = b"hho\0"; +pub const SCNoFAST16: &'static [u8; 3usize] = b"lo\0"; +pub const SCNoFAST32: &'static [u8; 3usize] = b"lo\0"; +pub const SCNoFAST64: &'static [u8; 3usize] = b"lo\0"; +pub const SCNx8: &'static [u8; 4usize] = b"hhx\0"; +pub const SCNx16: &'static [u8; 3usize] = b"hx\0"; +pub const SCNx32: &'static [u8; 2usize] = b"x\0"; +pub const SCNx64: &'static [u8; 3usize] = b"lx\0"; +pub const SCNxLEAST8: &'static [u8; 4usize] = b"hhx\0"; +pub const SCNxLEAST16: &'static [u8; 3usize] = b"hx\0"; +pub const SCNxLEAST32: &'static [u8; 2usize] = b"x\0"; +pub const SCNxLEAST64: &'static [u8; 3usize] = b"lx\0"; +pub const SCNxFAST8: &'static [u8; 4usize] = b"hhx\0"; +pub const SCNxFAST16: &'static [u8; 3usize] = b"lx\0"; +pub const SCNxFAST32: &'static [u8; 3usize] = b"lx\0"; +pub const SCNxFAST64: &'static [u8; 3usize] = b"lx\0"; +pub const SCNdMAX: &'static [u8; 3usize] = b"ld\0"; +pub const SCNiMAX: &'static [u8; 3usize] = b"li\0"; +pub const SCNoMAX: &'static [u8; 3usize] = b"lo\0"; +pub const SCNuMAX: &'static [u8; 3usize] = b"lu\0"; +pub const SCNxMAX: &'static [u8; 3usize] = b"lx\0"; +pub const SCNdPTR: &'static [u8; 3usize] = b"ld\0"; +pub const SCNiPTR: &'static [u8; 3usize] = b"li\0"; +pub const SCNoPTR: &'static [u8; 3usize] = b"lo\0"; +pub const SCNuPTR: &'static [u8; 3usize] = b"lu\0"; +pub const SCNxPTR: &'static [u8; 3usize] = b"lx\0"; +pub const _CTYPE_H: u32 = 1; +pub const _SYS_TIME_H: u32 = 1; +pub const _SYS_RESOURCE_H: u32 = 1; +pub const RLIM64_INFINITY: i32 = -1; +pub const __rusage_defined: u32 = 1; +pub const PRIO_MIN: i32 = -20; +pub const PRIO_MAX: u32 = 20; +pub const _STRING_H: u32 = 1; +pub const _STRINGS_H: u32 = 1; +pub const _STDLIB_H: u32 = 1; +pub const WNOHANG: u32 = 1; +pub const WUNTRACED: u32 = 2; +pub const WSTOPPED: u32 = 2; +pub const WEXITED: u32 = 4; +pub const WCONTINUED: u32 = 8; +pub const WNOWAIT: u32 = 16777216; +pub const __WNOTHREAD: u32 = 536870912; +pub const __WALL: u32 = 1073741824; +pub const __WCLONE: u32 = 2147483648; +pub const __ENUM_IDTYPE_T: u32 = 1; +pub const __W_CONTINUED: u32 = 65535; +pub const __WCOREFLAG: u32 = 128; +pub const __ldiv_t_defined: u32 = 1; +pub const __lldiv_t_defined: u32 = 1; +pub const RAND_MAX: u32 = 2147483647; +pub const EXIT_FAILURE: u32 = 1; +pub const EXIT_SUCCESS: u32 = 0; +pub const _ALLOCA_H: u32 = 1; +pub const FS_EXISTS: u32 = 1; +pub const FS_EXECABLE: u32 = 2; +pub const FS_EXEC_PREFERRED: u32 = 4; +pub const FS_EXEC_ONLY: u32 = 8; +pub const FS_DIRECTORY: u32 = 16; +pub const FS_NODIRS: u32 = 32; +pub const FS_READABLE: u32 = 64; + +pub const DIRSEP: u8 = 47u8; +pub const AS_DISPOSE: u32 = 1; +pub const NO_SIG: i32 = -1; + +pub const DSIG_SIGPREFIX: i32 = 1; +pub const DSIG_NOCASE: i32 = 2; +pub const _LIBGETTEXT_H: u32 = 1; +pub const _LIBINTL_H: u32 = 1; +pub const __USE_GNU_GETTEXT: u32 = 1; +pub const _LOCALE_H: u32 = 1; +pub const _BITS_LOCALE_H: u32 = 1; +pub const __LC_CTYPE: u32 = 0; +pub const __LC_NUMERIC: u32 = 1; +pub const __LC_TIME: u32 = 2; +pub const __LC_COLLATE: u32 = 3; +pub const __LC_MONETARY: u32 = 4; +pub const __LC_MESSAGES: u32 = 5; +pub const __LC_ALL: u32 = 6; +pub const __LC_PAPER: u32 = 7; +pub const __LC_NAME: u32 = 8; +pub const __LC_ADDRESS: u32 = 9; +pub const __LC_TELEPHONE: u32 = 10; +pub const __LC_MEASUREMENT: u32 = 11; +pub const __LC_IDENTIFICATION: u32 = 12; +pub const LC_CTYPE: u32 = 0; +pub const LC_NUMERIC: u32 = 1; +pub const LC_TIME: u32 = 2; +pub const LC_COLLATE: u32 = 3; +pub const LC_MONETARY: u32 = 4; +pub const LC_MESSAGES: u32 = 5; + +pub const LC_PAPER: u32 = 7; +pub const LC_NAME: u32 = 8; +pub const LC_ADDRESS: u32 = 9; +pub const LC_TELEPHONE: u32 = 10; +pub const LC_MEASUREMENT: u32 = 11; +pub const LC_IDENTIFICATION: u32 = 12; +pub const LC_CTYPE_MASK: u32 = 1; +pub const LC_NUMERIC_MASK: u32 = 2; +pub const LC_TIME_MASK: u32 = 4; +pub const LC_COLLATE_MASK: u32 = 8; +pub const LC_MONETARY_MASK: u32 = 16; +pub const LC_MESSAGES_MASK: u32 = 32; +pub const LC_PAPER_MASK: u32 = 128; +pub const LC_NAME_MASK: u32 = 256; +pub const LC_ADDRESS_MASK: u32 = 512; +pub const LC_TELEPHONE_MASK: u32 = 1024; +pub const LC_MEASUREMENT_MASK: u32 = 2048; +pub const LC_IDENTIFICATION_MASK: u32 = 4096; +pub const LC_ALL_MASK: u32 = 8127; + +pub const CASE_LOWER: u32 = 1; +pub const CASE_UPPER: u32 = 2; +pub const CASE_CAPITALIZE: u32 = 4; +pub const CASE_UNCAP: u32 = 8; +pub const CASE_TOGGLE: u32 = 16; +pub const CASE_TOGGLEALL: u32 = 32; +pub const CASE_UPFIRST: u32 = 64; +pub const CASE_LOWFIRST: u32 = 128; +pub const CASE_USEWORDS: u32 = 4096; +pub const FL_PREFIX: u32 = 1; +pub const FL_ADDBASE: u32 = 2; +pub const FL_HEXUPPER: u32 = 4; +pub const FL_UNSIGNED: u32 = 8; +pub const MP_DOTILDE: u32 = 1; + +pub const MP_IGNDOT: u32 = 8; +pub const PATH_CHECKDOTDOT: u32 = 1; +pub const PATH_CHECKEXISTS: u32 = 2; +pub const PATH_HARDPATH: u32 = 4; +pub const PATH_NOALLOC: u32 = 8; +pub const SHMAT_SUBEXP: u32 = 1; +pub const SHMAT_PWARN: u32 = 2; +pub const MT_USETMPDIR: u32 = 1; +pub const MT_READWRITE: u32 = 2; +pub const MT_USERANDOM: u32 = 4; +pub const MT_TEMPLATE: u32 = 8; +pub const DEFAULT_HASH_BUCKETS: u32 = 128; + +pub const HASH_CREATE: u32 = 2; +pub const ASSOC_HASH_BUCKETS: u32 = 1024; +pub const VC_HASLOCAL: u32 = 1; +pub const VC_HASTMPVAR: u32 = 2; +pub const VC_FUNCENV: u32 = 4; +pub const VC_BLTNENV: u32 = 8; +pub const VC_TEMPENV: u32 = 16; +pub const VC_TEMPFLAGS: u32 = 28; + +pub const user_attrs: u32 = 4019; +pub const attmask_user: u32 = 4095; + +pub const att_nounset: u32 = 8192; + +pub const att_special: u32 = 65536; +pub const att_nofree: u32 = 131072; +pub const att_regenerate: u32 = 262144; +pub const attmask_int: u32 = 1044480; + +pub const attmask_scope: u32 = 15728640; +pub const NAMEREF_MAX: u32 = 8; +pub const MKLOC_ASSOCOK: u32 = 1; +pub const MKLOC_ARRAYOK: u32 = 2; +pub const MKLOC_INHERIT: u32 = 4; +pub const AV_ALLOWALL: u32 = 1; +pub const AV_QUOTED: u32 = 2; +pub const AV_USEIND: u32 = 4; +pub const AV_USEVAL: u32 = 8; +pub const AV_ASSIGNRHS: u32 = 16; + +pub const VA_NOEXPAND: i32 = 1; +pub const VA_ONEWORD: i32 = 2; +pub const RX_ACTIVE: u32 = 1; +pub const RX_UNDOABLE: u32 = 2; + +pub const RX_USER: u32 = 16; + +pub const HC_IGNSPACE: u32 = 1; +pub const HC_IGNDUPS: u32 = 2; +pub const HC_ERASEDUPS: u32 = 4; +pub const HC_IGNBOTH: u32 = 3; +pub const CA_ALIAS: u32 = 1; +pub const CA_ARRAYVAR: u32 = 2; +pub const CA_BINDING: u32 = 4; +pub const CA_BUILTIN: u32 = 8; +pub const CA_COMMAND: u32 = 16; +pub const CA_DIRECTORY: u32 = 32; +pub const CA_DISABLED: u32 = 64; +pub const CA_ENABLED: u32 = 128; +pub const CA_EXPORT: u32 = 256; +pub const CA_FILE: u32 = 512; +pub const CA_FUNCTION: u32 = 1024; +pub const CA_GROUP: u32 = 2048; +pub const CA_HELPTOPIC: u32 = 4096; +pub const CA_HOSTNAME: u32 = 8192; +pub const CA_JOB: u32 = 16384; +pub const CA_KEYWORD: u32 = 32768; +pub const CA_RUNNING: u32 = 65536; +pub const CA_SERVICE: u32 = 131072; +pub const CA_SETOPT: u32 = 262144; +pub const CA_SHOPT: u32 = 524288; +pub const CA_SIGNAL: u32 = 1048576; +pub const CA_STOPPED: u32 = 2097152; +pub const CA_USER: u32 = 4194304; +pub const CA_VARIABLE: u32 = 8388608; +pub const COPT_RESERVED: u32 = 1; +pub const COPT_DEFAULT: u32 = 2; +pub const COPT_FILENAMES: u32 = 4; +pub const COPT_DIRNAMES: u32 = 8; +pub const COPT_NOQUOTE: u32 = 16; +pub const COPT_NOSPACE: u32 = 32; +pub const COPT_BASHDEFAULT: u32 = 64; +pub const COPT_PLUSDIRS: u32 = 128; +pub const COPT_NOSORT: u32 = 256; +pub const COPT_LASTUSER: u32 = 256; +pub const PCOMP_RETRYFAIL: u32 = 512; +pub const PCOMP_NOTFOUND: u32 = 1024; +pub const LIST_DYNAMIC: u32 = 1; +pub const LIST_DIRTY: u32 = 2; +pub const LIST_INITIALIZED: u32 = 4; +pub const LIST_MUSTSORT: u32 = 8; +pub const LIST_DONTFREE: u32 = 16; +pub const LIST_DONTFREEMEMBERS: u32 = 32; +pub const EMPTYCMD: &'static [u8; 11usize] = b"_EmptycmD_\0"; +pub const DEFAULTCMD: &'static [u8; 13usize] = b"_DefaultCmD_\0"; +pub const INITIALWORD: &'static [u8; 14usize] = b"_InitialWorD_\0"; +pub const _STDIO_H: u32 = 1; +pub const _____fpos_t_defined: u32 = 1; +pub const _____fpos64_t_defined: u32 = 1; +pub const __struct_FILE_defined: u32 = 1; +pub const _IO_EOF_SEEN: u32 = 16; +pub const _IO_ERR_SEEN: u32 = 32; +pub const _IO_USER_LOCK: u32 = 32768; +pub const __cookie_io_functions_t_defined: u32 = 1; +pub const _IOFBF: u32 = 0; +pub const _IOLBF: u32 = 1; +pub const _IONBF: u32 = 2; +pub const BUFSIZ: u32 = 8192; +pub const EOF: i32 = -1; +pub const P_tmpdir: &'static [u8; 5usize] = b"/tmp\0"; +pub const _BITS_STDIO_LIM_H: u32 = 1; +pub const L_tmpnam: u32 = 20; +pub const TMP_MAX: u32 = 238328; +pub const FILENAME_MAX: u32 = 4096; +pub const L_ctermid: u32 = 9; +pub const L_cuserid: u32 = 9; +pub const FOPEN_MAX: u32 = 16; +pub const RENAME_NOREPLACE: u32 = 1; +pub const RENAME_EXCHANGE: u32 = 2; +pub const RENAME_WHITEOUT: u32 = 4; +pub const DEFAULT_HOSTS_FILE: &'static [u8; 11usize] = b"/etc/hosts\0"; +pub const SYS_PROFILE: &'static [u8; 13usize] = b"/etc/profile\0"; +pub const DEBUGGER_START_FILE: &'static [u8; 46usize] = + b"/usr/local/share/utshelldb/utshelldb-main.inc\0"; +pub const FILENAME_HASH_BUCKETS: u32 = 256; +pub const HASH_RELPATH: u32 = 1; +pub const HASH_CHKDOT: u32 = 2; + +pub const QGLOB_CVTNULL: u32 = 1; +pub const QGLOB_FILENAME: u32 = 2; +pub const QGLOB_REGEXP: u32 = 4; +pub const QGLOB_CTLESC: u32 = 8; +pub const QGLOB_DEQUOTE: u32 = 16; + +pub const PATCHLEVEL: u32 = 4; +pub const Q_DOUBLE_QUOTES: u32 = 1; +pub const Q_HERE_DOCUMENT: u32 = 2; +pub const Q_KEEP_BACKSLASH: u32 = 4; +pub const Q_PATQUOTE: u32 = 8; +pub const Q_QUOTED: u32 = 16; +pub const Q_ADDEDQUOTES: u32 = 32; +pub const Q_QUOTEDNULL: u32 = 64; +pub const Q_DOLBRACE: u32 = 128; +pub const Q_ARITH: u32 = 256; +pub const Q_ARRAYSUB: u32 = 512; +pub const ASS_APPEND: i32 = 1; +pub const ASS_MKLOCAL: u32 = 2; +pub const ASS_MKASSOC: u32 = 4; +pub const ASS_MKGLOBAL: u32 = 8; +pub const ASS_NAMEREF: u32 = 16; +pub const ASS_FORCE: u32 = 32; +pub const ASS_CHKLOCAL: u32 = 64; + +pub const ASS_NOEVAL: u32 = 256; +pub const ASS_NOLONGJMP: u32 = 512; +pub const ASS_NOINVIS: u32 = 1024; +pub const SX_NOALLOC: u32 = 1; +pub const SX_VARNAME: u32 = 2; +pub const SX_REQMATCH: u32 = 4; +pub const SX_COMMAND: u32 = 8; +pub const SX_NOCTLESC: u32 = 16; +pub const SX_NOESCCTLNUL: u32 = 32; +pub const SX_NOLONGJMP: u32 = 64; +pub const SX_ARITHSUB: u32 = 128; +pub const SX_POSIXEXP: u32 = 256; +pub const SX_WORD: u32 = 512; +pub const SX_COMPLETE: u32 = 1024; +pub const SX_STRIPDQ: u32 = 2048; +pub const SD_NOJMP: u32 = 1; +pub const SD_INVERT: u32 = 2; +pub const SD_NOQUOTEDELIM: u32 = 4; +pub const SD_NOSKIPCMD: u32 = 8; +pub const SD_EXTGLOB: u32 = 16; +pub const SD_IGNOREQUOTE: u32 = 32; +pub const SD_GLOB: u32 = 64; +pub const SD_NOPROCSUB: u32 = 128; +pub const SD_COMPLETE: u32 = 256; +pub const SD_HISTEXP: u32 = 512; +pub const SD_ARITHEXP: u32 = 1024; +pub const _SYS_WAIT_H: u32 = 1; +pub const WCOREFLAG: u32 = 128; +pub const WAIT_ANY: i32 = -1; +pub const WAIT_MYPGRP: u32 = 0; +pub const JLIST_STANDARD: u32 = 0; +pub const JLIST_LONG: u32 = 1; +pub const JLIST_PID_ONLY: u32 = 2; +pub const JLIST_CHANGED_ONLY: u32 = 3; +pub const JLIST_NONINTERACTIVE: u32 = 4; +pub const LONGEST_SIGNAL_DESC: u32 = 24; +pub const JWAIT_PERROR: u32 = 1; +pub const JWAIT_FORCE: u32 = 2; +pub const JWAIT_NOWAIT: u32 = 4; +pub const JWAIT_WAITING: u32 = 8; +pub const JWAIT_NOTERM: u32 = 256; +pub const FORKSLEEP_MAX: u32 = 16; +pub const PS_DONE: u32 = 0; +pub const PS_RUNNING: u32 = 1; +pub const PS_STOPPED: u32 = 2; +pub const PS_RECYCLED: u32 = 4; +pub const J_FOREGROUND: u32 = 1; +pub const J_NOTIFIED: u32 = 2; +pub const J_JOBCONTROL: i32 = 4; +pub const J_NOHUP: u32 = 8; +pub const J_STATSAVED: u32 = 16; +pub const J_ASYNC: u32 = 32; +pub const J_PIPEFAIL: u32 = 64; +pub const J_WAITING: u32 = 128; +pub const NO_JOB: i32 = -1; +pub const DUP_JOB: i32 = -2; +pub const BAD_JOBSPEC: i32 = -3; +pub const FORK_SYNC: u32 = 0; +pub const FORK_ASYNC: u32 = 1; +pub const FORK_NOJOB: u32 = 2; +pub const FORK_NOTERM: u32 = 4; +pub const CMDSRCH_HASH: u32 = 1; +pub const CMDSRCH_STDPATH: u32 = 2; +pub const CMDSRCH_TEMPENV: u32 = 4; +pub const _SETJMP_H: u32 = 1; +pub const _BITS_SETJMP_H: u32 = 1; +pub const NOT_JUMPED: u32 = 0; + +pub const SIGEXIT: u32 = 5; +pub const slashify_in_here_document: &'static [u8; 4usize] = b"\\`$\0"; +pub const shell_meta_chars: &'static [u8; 8usize] = b"()<>;&|\0"; +pub const shell_break_chars: &'static [u8; 13usize] = b"()<>;&| \\t\\n\0"; +pub const shell_quote_chars: &'static [u8; 4usize] = b"\"`'\0"; +pub const shell_exp_chars: &'static [u8; 4usize] = b"$<>\0"; +pub const ext_glob_chars: &'static [u8; 6usize] = b"@*+?!\0"; +pub const shell_glob_chars: &'static [u8; 6usize] = b"*?[]^\0"; +pub const CWORD: u32 = 0; +pub const CSHMETA: u32 = 1; + +pub const CBACKQ: u32 = 4; +pub const CQUOTE: u32 = 8; +pub const CSPECL: u32 = 16; +pub const CEXP: u32 = 32; +pub const CBSDQUOTE: u32 = 64; +pub const CBSHDOC: u32 = 128; +pub const CGLOB: u32 = 256; +pub const CXGLOB: u32 = 512; + +pub const CSPECVAR: u32 = 2048; +pub const CSUBSTOP: u32 = 4096; + +pub const CTLESC: u8 = 1u8; +pub const CTLNUL: u8 = 127u8; +pub const _OCACHE_H_: u32 = 1; +pub const NO_PIPE: i32 = -1; +pub const REDIRECT_BOTH: i32 = -2; +pub const NO_VARIABLE: i32 = -1; + +pub const EXECUTION_SUCCESS: i32 = 0; +pub const EX_BADUSAGE: i32 = 2; +pub const EX_MISCERROR: u32 = 2; +pub const EX_RETRYFAIL: u32 = 124; +pub const EX_WEXPCOMSUB: u32 = 125; +pub const EX_BINARY_FILE: u32 = 126; + +pub const EX_NOINPUT: u32 = 126; +pub const EX_NOTFOUND: i32 = 127; +pub const EX_SHERRBASE: u32 = 256; +pub const EX_BADSYNTAX: u32 = 257; +pub const EX_USAGE: i32 = 258; +pub const EX_REDIRFAIL: u32 = 259; +pub const EX_BADASSIGN: i32 = 260; +pub const EX_EXPFAIL: u32 = 261; +pub const EX_DISKFALLBACK: u32 = 262; +pub const MATCH_ANY: u32 = 0; +pub const MATCH_BEG: u32 = 1; +pub const MATCH_END: u32 = 2; +pub const MATCH_TYPEMASK: u32 = 3; +pub const MATCH_GLOBREP: u32 = 16; +pub const MATCH_QUOTED: u32 = 32; +pub const MATCH_ASSIGNRHS: u32 = 64; +pub const MATCH_STARSUB: u32 = 128; +pub const FD_BITMAP_SIZE: u32 = 32; +pub const HEREDOC_MAX: u32 = 16; +pub const B_EOF: u32 = 1; +pub const B_ERROR: u32 = 2; + +pub const B_WASBASHINPUT: u32 = 8; + +pub const B_SHAREDBUF: i32 = 32; +pub const BUILTIN_ENABLED: i32 = 1; +pub const BUILTIN_DELETED: i32 = 2; +pub const STATIC_BUILTIN: i32 = 4; +pub const SPECIAL_BUILTIN: i32 = 8; +pub const ASSIGNMENT_BUILTIN: i32 = 16; +pub const POSIX_BUILTIN: i32 = 32; +pub const LOCALVAR_BUILTIN: i32 = 64; +pub const REQUIRES_BUILTIN: i32 = 128; +pub const BASE_INDENT: i32 = 4; +pub const PST_CASEPAT: i32 = 1; +pub const PST_ALEXPNEXT: i32 = 2; +pub const PST_ALLOWOPNBRC: i32 = 4; +pub const PST_NEEDCLOSBRC: i32 = 8; +pub const PST_DBLPAREN: u32 = 16; +pub const PST_SUBSHELL: u32 = 32; +pub const PST_CMDSUBST: u32 = 64; +pub const PST_CASESTMT: u32 = 128; +pub const PST_CONDCMD: u32 = 256; +pub const PST_CONDEXPR: u32 = 512; +pub const PST_ARITHFOR: u32 = 1024; +pub const PST_ALEXPAND: u32 = 2048; +pub const PST_EXTPAT: u32 = 4096; +pub const PST_COMPASSIGN: u32 = 8192; +pub const PST_ASSIGNOK: u32 = 16384; +pub const PST_EOFTOKEN: u32 = 32768; +pub const PST_REGEXP: u32 = 65536; +pub const PST_HEREDOC: u32 = 131072; +pub const PST_REPARSE: u32 = 262144; +pub const PST_REDIRLIST: u32 = 524288; +pub const PST_COMMENT: u32 = 1048576; +pub const PST_ENDALIAS: u32 = 2097152; +pub const DOLBRACE_PARAM: u32 = 1; +pub const DOLBRACE_OP: u32 = 2; +pub const DOLBRACE_WORD: u32 = 4; +pub const DOLBRACE_QUOTE: u32 = 64; +pub const DOLBRACE_QUOTE2: u32 = 128; +pub const YYDEBUG: u32 = 0; +pub const IF: u32 = 258; +pub const THEN: u32 = 259; +pub const ELSE: u32 = 260; +pub const ELIF: u32 = 261; +pub const FI: u32 = 262; +pub const CASE: u32 = 263; +pub const ESAC: u32 = 264; +pub const FOR: u32 = 265; +pub const SELECT: u32 = 266; +pub const WHILE: u32 = 267; +pub const UNTIL: u32 = 268; +pub const DO: u32 = 269; +pub const DONE: u32 = 270; +pub const FUNCTION: u32 = 271; +pub const COPROC: u32 = 272; +pub const COND_START: u32 = 273; +pub const COND_END: u32 = 274; +pub const COND_ERROR: u32 = 275; +pub const IN: u32 = 276; +pub const BANG: u32 = 277; +pub const TIME: u32 = 278; +pub const TIMEOPT: u32 = 279; +pub const TIMEIGN: u32 = 280; +pub const WORD: u32 = 281; +pub const ASSIGNMENT_WORD: u32 = 282; +pub const REDIR_WORD: u32 = 283; +pub const NUMBER: u32 = 284; +pub const ARITH_CMD: u32 = 285; +pub const ARITH_FOR_EXPRS: u32 = 286; +pub const COND_CMD: u32 = 287; + +pub const GREATER_GREATER: u32 = 290; +pub const LESS_LESS: u32 = 291; +pub const LESS_AND: u32 = 292; +pub const LESS_LESS_LESS: u32 = 293; +pub const GREATER_AND: u32 = 294; +pub const SEMI_SEMI: u32 = 295; +pub const SEMI_AND: u32 = 296; +pub const SEMI_SEMI_AND: u32 = 297; +pub const LESS_LESS_MINUS: u32 = 298; +pub const AND_GREATER: u32 = 299; +pub const AND_GREATER_GREATER: u32 = 300; +pub const LESS_GREATER: u32 = 301; +pub const GREATER_BAR: u32 = 302; +pub const BAR_AND: u32 = 303; +pub const yacc_EOF: u32 = 304; +pub const YYSTYPE_IS_TRIVIAL: u32 = 1; +pub const YYSTYPE_IS_DECLARED: u32 = 1; +pub const _FCNTL_H: u32 = 1; +pub const __O_LARGEFILE: u32 = 0; +pub const F_GETLK64: u32 = 5; +pub const F_SETLK64: u32 = 6; +pub const F_SETLKW64: u32 = 7; +pub const __iovec_defined: u32 = 1; +pub const O_ACCMODE: u32 = 3; + +pub const O_WRONLY: u32 = 1; + +pub const O_CREAT: u32 = 64; +pub const O_EXCL: u32 = 128; +pub const O_NOCTTY: u32 = 256; +pub const O_TRUNC: u32 = 512; +pub const O_APPEND: u32 = 1024; + +pub const O_SYNC: u32 = 1052672; +pub const O_FSYNC: u32 = 1052672; +pub const O_ASYNC: u32 = 8192; +pub const __O_DIRECTORY: u32 = 65536; +pub const __O_NOFOLLOW: u32 = 131072; +pub const __O_CLOEXEC: u32 = 524288; +pub const __O_DIRECT: u32 = 16384; +pub const __O_NOATIME: u32 = 262144; +pub const __O_PATH: u32 = 2097152; +pub const __O_DSYNC: u32 = 4096; +pub const __O_TMPFILE: u32 = 4259840; +pub const F_GETLK: u32 = 5; +pub const F_SETLK: u32 = 6; +pub const F_SETLKW: u32 = 7; +pub const F_OFD_GETLK: u32 = 36; +pub const F_OFD_SETLK: u32 = 37; +pub const F_OFD_SETLKW: u32 = 38; +pub const O_LARGEFILE: u32 = 0; +pub const O_DIRECTORY: u32 = 65536; +pub const O_NOFOLLOW: u32 = 131072; +pub const O_CLOEXEC: u32 = 524288; +pub const O_DIRECT: u32 = 16384; +pub const O_NOATIME: u32 = 262144; +pub const O_PATH: u32 = 2097152; +pub const O_TMPFILE: u32 = 4259840; +pub const O_DSYNC: u32 = 4096; +pub const O_RSYNC: u32 = 1052672; +pub const F_DUPFD: u32 = 0; + +pub const __F_SETOWN: u32 = 8; +pub const __F_GETOWN: u32 = 9; +pub const F_SETOWN: u32 = 8; +pub const F_GETOWN: u32 = 9; +pub const __F_SETSIG: u32 = 10; +pub const __F_GETSIG: u32 = 11; +pub const __F_SETOWN_EX: u32 = 15; +pub const __F_GETOWN_EX: u32 = 16; +pub const F_SETSIG: u32 = 10; +pub const F_GETSIG: u32 = 11; +pub const F_SETOWN_EX: u32 = 15; +pub const F_GETOWN_EX: u32 = 16; +pub const F_SETLEASE: u32 = 1024; +pub const F_GETLEASE: u32 = 1025; +pub const F_NOTIFY: u32 = 1026; +pub const F_SETPIPE_SZ: u32 = 1031; +pub const F_ADD_SEALS: u32 = 1033; +pub const F_GET_SEALS: u32 = 1034; +pub const F_GET_RW_HINT: u32 = 1035; +pub const F_SET_RW_HINT: u32 = 1036; +pub const F_GET_FILE_RW_HINT: u32 = 1037; +pub const F_SET_FILE_RW_HINT: u32 = 1038; +pub const F_DUPFD_CLOEXEC: u32 = 1030; + +pub const F_RDLCK: u32 = 0; +pub const F_WRLCK: u32 = 1; +pub const F_UNLCK: u32 = 2; +pub const F_EXLCK: u32 = 4; +pub const F_SHLCK: u32 = 8; +pub const LOCK_SH: u32 = 1; +pub const LOCK_EX: u32 = 2; +pub const LOCK_NB: u32 = 4; +pub const LOCK_UN: u32 = 8; +pub const LOCK_MAND: u32 = 32; +pub const LOCK_READ: u32 = 64; +pub const LOCK_WRITE: u32 = 128; +pub const LOCK_RW: u32 = 192; +pub const DN_ACCESS: u32 = 1; +pub const DN_MODIFY: u32 = 2; +pub const DN_CREATE: u32 = 4; +pub const DN_DELETE: u32 = 8; +pub const DN_RENAME: u32 = 16; +pub const DN_ATTRIB: u32 = 32; +pub const DN_MULTISHOT: u32 = 2147483648; +pub const F_SEAL_SEAL: u32 = 1; +pub const F_SEAL_SHRINK: u32 = 2; +pub const F_SEAL_GROW: u32 = 4; +pub const F_SEAL_WRITE: u32 = 8; +pub const RWF_WRITE_LIFE_NOT_SET: u32 = 0; +pub const RWH_WRITE_LIFE_NONE: u32 = 1; +pub const RWH_WRITE_LIFE_SHORT: u32 = 2; +pub const RWH_WRITE_LIFE_MEDIUM: u32 = 3; +pub const RWH_WRITE_LIFE_LONG: u32 = 4; +pub const RWH_WRITE_LIFE_EXTREME: u32 = 5; +pub const FAPPEND: u32 = 1024; +pub const FFSYNC: u32 = 1052672; +pub const FASYNC: u32 = 8192; +pub const FNONBLOCK: u32 = 2048; +pub const FNDELAY: u32 = 2048; +pub const __POSIX_FADV_DONTNEED: u32 = 4; +pub const __POSIX_FADV_NOREUSE: u32 = 5; +pub const POSIX_FADV_NORMAL: u32 = 0; +pub const POSIX_FADV_RANDOM: u32 = 1; +pub const POSIX_FADV_SEQUENTIAL: u32 = 2; +pub const POSIX_FADV_WILLNEED: u32 = 3; +pub const POSIX_FADV_DONTNEED: u32 = 4; +pub const POSIX_FADV_NOREUSE: u32 = 5; +pub const SYNC_FILE_RANGE_WAIT_BEFORE: u32 = 1; +pub const SYNC_FILE_RANGE_WRITE: u32 = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: u32 = 4; +pub const SPLICE_F_MOVE: u32 = 1; +pub const SPLICE_F_NONBLOCK: u32 = 2; +pub const SPLICE_F_MORE: u32 = 4; +pub const SPLICE_F_GIFT: u32 = 8; +pub const FALLOC_FL_KEEP_SIZE: u32 = 1; +pub const FALLOC_FL_PUNCH_HOLE: u32 = 2; +pub const FALLOC_FL_NO_HIDE_STALE: u32 = 4; +pub const FALLOC_FL_COLLAPSE_RANGE: u32 = 8; +pub const FALLOC_FL_ZERO_RANGE: u32 = 16; +pub const FALLOC_FL_INSERT_RANGE: u32 = 32; +pub const FALLOC_FL_UNSHARE_RANGE: u32 = 64; +pub const MAX_HANDLE_SZ: u32 = 128; +pub const AT_FDCWD: i32 = -100; +pub const AT_SYMLINK_NOFOLLOW: u32 = 256; +pub const AT_REMOVEDIR: u32 = 512; +pub const AT_SYMLINK_FOLLOW: u32 = 1024; +pub const AT_NO_AUTOMOUNT: u32 = 2048; +pub const AT_EMPTY_PATH: u32 = 4096; +pub const AT_STATX_SYNC_TYPE: u32 = 24576; +pub const AT_STATX_SYNC_AS_STAT: u32 = 0; +pub const AT_STATX_FORCE_SYNC: u32 = 8192; +pub const AT_STATX_DONT_SYNC: u32 = 16384; +pub const AT_EACCESS: u32 = 512; +pub const _BITS_STAT_H: u32 = 1; +pub const _STAT_VER_KERNEL: u32 = 0; +pub const _STAT_VER_LINUX: u32 = 1; +pub const _MKNOD_VER_LINUX: u32 = 0; +pub const _STAT_VER: u32 = 1; +pub const __S_IFMT: u32 = 61440; +pub const __S_IFDIR: u32 = 16384; +pub const __S_IFCHR: u32 = 8192; +pub const __S_IFBLK: u32 = 24576; +pub const __S_IFREG: u32 = 32768; +pub const __S_IFIFO: u32 = 4096; +pub const __S_IFLNK: u32 = 40960; +pub const __S_IFSOCK: u32 = 49152; +pub const __S_ISUID: u32 = 2048; +pub const __S_ISGID: u32 = 1024; +pub const __S_ISVTX: u32 = 512; +pub const __S_IREAD: u32 = 256; +pub const __S_IWRITE: u32 = 128; +pub const __S_IEXEC: u32 = 64; +pub const UTIME_NOW: u32 = 1073741823; +pub const UTIME_OMIT: u32 = 1073741822; + +pub const S_IFDIR: u32 = 16384; +pub const S_IFCHR: u32 = 8192; +pub const S_IFBLK: u32 = 24576; + +pub const S_IFIFO: u32 = 4096; +pub const S_IFLNK: u32 = 40960; +pub const S_IFSOCK: u32 = 49152; +pub const S_ISUID: u32 = 2048; +pub const S_ISGID: u32 = 1024; +pub const S_ISVTX: u32 = 512; +pub const S_IRUSR: u32 = 256; +pub const S_IWUSR: u32 = 128; +pub const S_IXUSR: u32 = 64; +pub const S_IRWXU: u32 = 448; +pub const S_IRGRP: u32 = 32; +pub const S_IWGRP: u32 = 16; +pub const S_IXGRP: u32 = 8; +pub const S_IRWXG: u32 = 56; +pub const S_IROTH: u32 = 4; +pub const S_IWOTH: u32 = 2; +pub const S_IXOTH: u32 = 1; +pub const S_IRWXO: u32 = 7; +pub const FD_NCLOEXEC: u32 = 0; +pub const O_BINARY: u32 = 0; + +pub const STAT_TIME_H: u32 = 1; +pub const _SYS_STAT_H: u32 = 1; +pub const S_IREAD: u32 = 256; +pub const S_IWRITE: u32 = 128; +pub const S_IEXEC: u32 = 64; +pub const ACCESSPERMS: u32 = 511; +pub const ALLPERMS: u32 = 4095; +pub const DEFFILEMODE: u32 = 438; +pub const S_BLKSIZE: u32 = 512; +pub const _MKNOD_VER: u32 = 0; +pub const STATX_TYPE: u32 = 1; +pub const STATX_MODE: u32 = 2; +pub const STATX_NLINK: u32 = 4; +pub const STATX_UID: u32 = 8; +pub const STATX_GID: u32 = 16; +pub const STATX_ATIME: u32 = 32; +pub const STATX_MTIME: u32 = 64; +pub const STATX_CTIME: u32 = 128; +pub const STATX_INO: u32 = 256; +pub const STATX_SIZE: u32 = 512; +pub const STATX_BLOCKS: u32 = 1024; +pub const STATX_BASIC_STATS: u32 = 2047; +pub const STATX_ALL: u32 = 4095; +pub const STATX_BTIME: u32 = 2048; +pub const STATX__RESERVED: u32 = 2147483648; +pub const STATX_ATTR_COMPRESSED: u32 = 4; +pub const STATX_ATTR_IMMUTABLE: u32 = 16; +pub const STATX_ATTR_APPEND: u32 = 32; +pub const STATX_ATTR_NODUMP: u32 = 64; +pub const STATX_ATTR_ENCRYPTED: u32 = 2048; +pub const STATX_ATTR_AUTOMOUNT: u32 = 4096; +pub const _TIME_H: u32 = 1; +pub const _BITS_TIME_H: u32 = 1; +pub const CLOCK_REALTIME: u32 = 0; +pub const CLOCK_MONOTONIC: u32 = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2; +pub const CLOCK_THREAD_CPUTIME_ID: u32 = 3; +pub const CLOCK_MONOTONIC_RAW: u32 = 4; +pub const CLOCK_REALTIME_COARSE: u32 = 5; +pub const CLOCK_MONOTONIC_COARSE: u32 = 6; +pub const CLOCK_BOOTTIME: u32 = 7; +pub const CLOCK_REALTIME_ALARM: u32 = 8; +pub const CLOCK_BOOTTIME_ALARM: u32 = 9; +pub const CLOCK_TAI: u32 = 11; +pub const TIMER_ABSTIME: u32 = 1; +pub const _BITS_TIMEX_H: u32 = 1; +pub const ADJ_OFFSET: u32 = 1; +pub const ADJ_FREQUENCY: u32 = 2; +pub const ADJ_MAXERROR: u32 = 4; +pub const ADJ_ESTERROR: u32 = 8; +pub const ADJ_STATUS: u32 = 16; +pub const ADJ_TIMECONST: u32 = 32; +pub const ADJ_TAI: u32 = 128; +pub const ADJ_SETOFFSET: u32 = 256; +pub const ADJ_MICRO: u32 = 4096; +pub const ADJ_NANO: u32 = 8192; +pub const ADJ_TICK: u32 = 16384; +pub const ADJ_OFFSET_SINGLESHOT: u32 = 32769; +pub const ADJ_OFFSET_SS_READ: u32 = 40961; +pub const MOD_OFFSET: u32 = 1; +pub const MOD_FREQUENCY: u32 = 2; +pub const MOD_MAXERROR: u32 = 4; +pub const MOD_ESTERROR: u32 = 8; +pub const MOD_STATUS: u32 = 16; +pub const MOD_TIMECONST: u32 = 32; +pub const MOD_CLKB: u32 = 16384; +pub const MOD_CLKA: u32 = 32769; +pub const MOD_TAI: u32 = 128; +pub const MOD_MICRO: u32 = 4096; +pub const MOD_NANO: u32 = 8192; +pub const STA_PLL: u32 = 1; +pub const STA_PPSFREQ: u32 = 2; +pub const STA_PPSTIME: u32 = 4; +pub const STA_FLL: u32 = 8; +pub const STA_INS: u32 = 16; +pub const STA_DEL: u32 = 32; +pub const STA_UNSYNC: u32 = 64; +pub const STA_FREQHOLD: u32 = 128; +pub const STA_PPSSIGNAL: u32 = 256; +pub const STA_PPSJITTER: u32 = 512; +pub const STA_PPSWANDER: u32 = 1024; +pub const STA_PPSERROR: u32 = 2048; +pub const STA_CLOCKERR: u32 = 4096; +pub const STA_NANO: u32 = 8192; +pub const STA_MODE: u32 = 16384; +pub const STA_CLK: u32 = 32768; +pub const STA_RONLY: u32 = 65280; +pub const __struct_tm_defined: u32 = 1; +pub const __itimerspec_defined: u32 = 1; +pub const TIME_UTC: u32 = 1; +pub const _BASH_SYSTIMES_H: u32 = 1; +pub const _SYS_TIMES_H: u32 = 1; +pub const _DIRENT_H: u32 = 1; +pub const _DIRENT_MATCHES_DIRENT64: u32 = 1; +pub const MAXNAMLEN: u32 = 255; +pub const D_FILENO_AVAILABLE: u32 = 1; +pub const _SHMBCHAR_H: u32 = 1; +pub const IS_BASIC_ASCII: u32 = 1; +pub const _STDLIB_H_: u32 = 1; +pub const S_IRUGO: u32 = 292; +pub const S_IWUGO: u32 = 146; +pub const S_IXUGO: u32 = 73; +pub const USEC_PER_SEC: u32 = 1000000; +pub const _TERMIOS_H: u32 = 1; +pub const NCCS: u32 = 32; +pub const _HAVE_STRUCT_TERMIOS_C_ISPEED: u32 = 1; +pub const _HAVE_STRUCT_TERMIOS_C_OSPEED: u32 = 1; +pub const VINTR: u32 = 0; +pub const VQUIT: u32 = 1; +pub const VERASE: u32 = 2; +pub const VKILL: u32 = 3; +pub const VEOF: u32 = 4; +pub const VTIME: u32 = 5; +pub const VMIN: u32 = 6; +pub const VSWTC: u32 = 7; +pub const VSTART: u32 = 8; +pub const VSTOP: u32 = 9; +pub const VSUSP: u32 = 10; +pub const VEOL: u32 = 11; +pub const VREPRINT: u32 = 12; +pub const VDISCARD: u32 = 13; +pub const VWERASE: u32 = 14; +pub const VLNEXT: u32 = 15; +pub const VEOL2: u32 = 16; +pub const IGNBRK: u32 = 1; +pub const BRKINT: u32 = 2; +pub const IGNPAR: u32 = 4; +pub const PARMRK: u32 = 8; +pub const INPCK: u32 = 16; +pub const ISTRIP: u32 = 32; +pub const INLCR: u32 = 64; +pub const IGNCR: u32 = 128; +pub const ICRNL: u32 = 256; +pub const IUCLC: u32 = 512; +pub const IXON: u32 = 1024; +pub const IXANY: u32 = 2048; +pub const IXOFF: u32 = 4096; +pub const IMAXBEL: u32 = 8192; +pub const IUTF8: u32 = 16384; +pub const OPOST: u32 = 1; +pub const OLCUC: u32 = 2; +pub const ONLCR: u32 = 4; +pub const OCRNL: u32 = 8; +pub const ONOCR: u32 = 16; +pub const ONLRET: u32 = 32; +pub const OFILL: u32 = 64; +pub const OFDEL: u32 = 128; +pub const NLDLY: u32 = 256; +pub const NL0: u32 = 0; +pub const NL1: u32 = 256; +pub const CRDLY: u32 = 1536; +pub const CR0: u32 = 0; +pub const CR1: u32 = 512; +pub const CR2: u32 = 1024; +pub const CR3: u32 = 1536; +pub const TABDLY: u32 = 6144; +pub const TAB0: u32 = 0; +pub const TAB1: u32 = 2048; +pub const TAB2: u32 = 4096; +pub const TAB3: u32 = 6144; +pub const BSDLY: u32 = 8192; +pub const BS0: u32 = 0; +pub const BS1: u32 = 8192; +pub const FFDLY: u32 = 32768; +pub const FF0: u32 = 0; +pub const FF1: u32 = 32768; +pub const VTDLY: u32 = 16384; +pub const VT0: u32 = 0; +pub const VT1: u32 = 16384; +pub const XTABS: u32 = 6144; +pub const CBAUD: u32 = 4111; +pub const B0: u32 = 0; +pub const B50: u32 = 1; +pub const B75: u32 = 2; +pub const B110: u32 = 3; +pub const B134: u32 = 4; +pub const B150: u32 = 5; +pub const B200: u32 = 6; +pub const B300: u32 = 7; +pub const B600: u32 = 8; +pub const B1200: u32 = 9; +pub const B1800: u32 = 10; +pub const B2400: u32 = 11; +pub const B4800: u32 = 12; +pub const B9600: u32 = 13; +pub const B19200: u32 = 14; +pub const B38400: u32 = 15; +pub const EXTA: u32 = 14; +pub const EXTB: u32 = 15; +pub const CSIZE: u32 = 48; +pub const CS5: u32 = 0; +pub const CS6: u32 = 16; +pub const CS7: u32 = 32; +pub const CS8: u32 = 48; +pub const CSTOPB: u32 = 64; +pub const CREAD: u32 = 128; +pub const PARENB: u32 = 256; +pub const PARODD: u32 = 512; +pub const HUPCL: u32 = 1024; +pub const CLOCAL: u32 = 2048; +pub const CBAUDEX: u32 = 4096; +pub const B57600: u32 = 4097; +pub const B115200: u32 = 4098; +pub const B230400: u32 = 4099; +pub const B460800: u32 = 4100; +pub const B500000: u32 = 4101; +pub const B576000: u32 = 4102; +pub const B921600: u32 = 4103; +pub const B1000000: u32 = 4104; +pub const B1152000: u32 = 4105; +pub const B1500000: u32 = 4106; +pub const B2000000: u32 = 4107; +pub const B2500000: u32 = 4108; +pub const B3000000: u32 = 4109; +pub const B3500000: u32 = 4110; +pub const B4000000: u32 = 4111; +pub const __MAX_BAUD: u32 = 4111; +pub const CIBAUD: u32 = 269418496; +pub const CMSPAR: u32 = 1073741824; +pub const CRTSCTS: u32 = 2147483648; +pub const ISIG: u32 = 1; +pub const ICANON: u32 = 2; +pub const XCASE: u32 = 4; +pub const ECHO: u32 = 8; +pub const ECHOE: u32 = 16; +pub const ECHOK: u32 = 32; +pub const ECHONL: u32 = 64; +pub const NOFLSH: u32 = 128; +pub const TOSTOP: u32 = 256; +pub const ECHOCTL: u32 = 512; +pub const ECHOPRT: u32 = 1024; +pub const ECHOKE: u32 = 2048; +pub const FLUSHO: u32 = 4096; +pub const PENDIN: u32 = 16384; +pub const IEXTEN: u32 = 32768; +pub const EXTPROC: u32 = 65536; +pub const TCOOFF: u32 = 0; +pub const TCOON: u32 = 1; +pub const TCIOFF: u32 = 2; +pub const TCION: u32 = 3; +pub const TCIFLUSH: u32 = 0; +pub const TCOFLUSH: u32 = 1; +pub const TCIOFLUSH: u32 = 2; +pub const TCSANOW: u32 = 0; +pub const TCSADRAIN: u32 = 1; +pub const TCSAFLUSH: u32 = 2; +pub const TTYDEF_IFLAG: u32 = 11554; +pub const TTYDEF_OFLAG: u32 = 6149; +pub const TTYDEF_LFLAG: u32 = 35355; +pub const TTYDEF_CFLAG: u32 = 1440; +pub const TTYDEF_SPEED: u32 = 13; +pub const CEOL: u8 = 0u8; +pub const CERASE: u32 = 127; +pub const CSTATUS: u8 = 0u8; +pub const CMIN: u32 = 1; +pub const CQUIT: u32 = 28; +pub const CTIME: u32 = 0; +pub const CBRK: u8 = 0u8; +pub const GETOPT_EOF: i32 = -1; +pub const GETOPT_HELP: i32 = -99; +pub const _SH_GETOPT_H: u32 = 1; +pub const SEVAL_NONINT: u32 = 1; +pub const SEVAL_INTERACT: u32 = 2; + +pub const SEVAL_NOFREE: u32 = 8; + +pub const SEVAL_PARSEONLY: u32 = 32; +pub const SEVAL_NOLONGJMP: u32 = 64; +pub const SEVAL_FUNCDEF: u32 = 128; +pub const SEVAL_ONECMD: u32 = 256; +pub const SEVAL_NOHISTEXP: u32 = 512; +pub const CDESC_ALL: u32 = 1; +pub const CDESC_SHORTDESC: u32 = 2; +pub const CDESC_REUSABLE: u32 = 4; +pub const CDESC_TYPE: u32 = 8; +pub const CDESC_PATH_ONLY: u32 = 16; +pub const CDESC_FORCE_PATH: u32 = 32; +pub const CDESC_NOFUNCS: u32 = 64; +pub const CDESC_ABSPATH: u32 = 128; +pub const CDESC_STDPATH: u32 = 256; +pub const JM_PREFIX: u32 = 1; +pub const JM_SUBSTRING: u32 = 2; +pub const JM_EXACT: u32 = 4; +pub const JM_STOPPED: u32 = 8; +pub const JM_FIRSTMATCH: u32 = 16; +pub const ARGS_NONE: u32 = 0; +pub const ARGS_INVOC: u32 = 1; +pub const ARGS_FUNC: u32 = 2; +pub const ARGS_SETBLTIN: u32 = 4; +pub const MAX_ATTRIBUTES: u32 = 16; +pub const TEST_PATMATCH: u32 = 1; +pub const TEST_ARITHEXP: u32 = 2; +pub const TEST_LOCALE: u32 = 4; +pub type _Float32 = f32; +pub type _Float64 = f64; +pub type _Float32x = f64; +pub type _Float64x = f64; + +pub type va_list = __builtin_va_list; +pub type __gnuc_va_list = __builtin_va_list; + +#[repr(C)] +#[derive(Copy, Clone)] +pub union __mbstate_t__bindgen_ty_1 { + pub __wch: ::std::os::raw::c_uint, + pub __wchb: [::std::os::raw::c_char; 4usize], + _bindgen_union_align: u32, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_struct { + pub __locales: [*mut __locale_data; 13usize], + pub __ctype_b: *const ::std::os::raw::c_ushort, + pub __ctype_tolower: *const ::std::os::raw::c_int, + pub __ctype_toupper: *const ::std::os::raw::c_int, + pub __names: [*const ::std::os::raw::c_char; 13usize], +} +pub type __locale_t = *mut __locale_struct; +pub type locale_t = __locale_t; + +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; + +pub type __uintmax_t = ::std::os::raw::c_ulong; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +pub type __clock_t = ::std::os::raw::c_long; + +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; + +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; + +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; + +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; + +pub type wctype_t = ::std::os::raw::c_ulong; +pub const __ISwupper: _bindgen_ty_1 = 0; +pub const __ISwlower: _bindgen_ty_1 = 1; +pub const __ISwalpha: _bindgen_ty_1 = 2; +pub const __ISwdigit: _bindgen_ty_1 = 3; +pub const __ISwxdigit: _bindgen_ty_1 = 4; +pub const __ISwspace: _bindgen_ty_1 = 5; +pub const __ISwprint: _bindgen_ty_1 = 6; +pub const __ISwgraph: _bindgen_ty_1 = 7; +pub const __ISwblank: _bindgen_ty_1 = 8; +pub const __ISwcntrl: _bindgen_ty_1 = 9; +pub const __ISwpunct: _bindgen_ty_1 = 10; +pub const __ISwalnum: _bindgen_ty_1 = 11; +pub const _ISwupper: _bindgen_ty_1 = 16777216; +pub const _ISwlower: _bindgen_ty_1 = 33554432; +pub const _ISwalpha: _bindgen_ty_1 = 67108864; +pub const _ISwdigit: _bindgen_ty_1 = 134217728; +pub const _ISwxdigit: _bindgen_ty_1 = 268435456; +pub const _ISwspace: _bindgen_ty_1 = 536870912; +pub const _ISwprint: _bindgen_ty_1 = 1073741824; +pub const _ISwgraph: _bindgen_ty_1 = -2147483648; +pub const _ISwblank: _bindgen_ty_1 = 65536; +pub const _ISwcntrl: _bindgen_ty_1 = 131072; +pub const _ISwpunct: _bindgen_ty_1 = 262144; +pub const _ISwalnum: _bindgen_ty_1 = 524288; +pub type _bindgen_ty_1 = i32; + +pub type off64_t = __off64_t; +pub type useconds_t = __useconds_t; + +pub type socklen_t = __socklen_t; + +pub const _PC_LINK_MAX: _bindgen_ty_2 = 0; +pub const _PC_MAX_CANON: _bindgen_ty_2 = 1; +pub const _PC_MAX_INPUT: _bindgen_ty_2 = 2; +pub const _PC_NAME_MAX: _bindgen_ty_2 = 3; +pub const _PC_PATH_MAX: _bindgen_ty_2 = 4; +pub const _PC_PIPE_BUF: _bindgen_ty_2 = 5; +pub const _PC_CHOWN_RESTRICTED: _bindgen_ty_2 = 6; +pub const _PC_NO_TRUNC: _bindgen_ty_2 = 7; +pub const _PC_VDISABLE: _bindgen_ty_2 = 8; +pub const _PC_SYNC_IO: _bindgen_ty_2 = 9; +pub const _PC_ASYNC_IO: _bindgen_ty_2 = 10; +pub const _PC_PRIO_IO: _bindgen_ty_2 = 11; +pub const _PC_SOCK_MAXBUF: _bindgen_ty_2 = 12; +pub const _PC_FILESIZEBITS: _bindgen_ty_2 = 13; +pub const _PC_REC_INCR_XFER_SIZE: _bindgen_ty_2 = 14; +pub const _PC_REC_MAX_XFER_SIZE: _bindgen_ty_2 = 15; +pub const _PC_REC_MIN_XFER_SIZE: _bindgen_ty_2 = 16; +pub const _PC_REC_XFER_ALIGN: _bindgen_ty_2 = 17; +pub const _PC_ALLOC_SIZE_MIN: _bindgen_ty_2 = 18; +pub const _PC_SYMLINK_MAX: _bindgen_ty_2 = 19; +pub const _PC_2_SYMLINKS: _bindgen_ty_2 = 20; +pub type _bindgen_ty_2 = u32; +pub const _SC_ARG_MAX: _bindgen_ty_3 = 0; +pub const _SC_CHILD_MAX: _bindgen_ty_3 = 1; +pub const _SC_CLK_TCK: _bindgen_ty_3 = 2; +pub const _SC_NGROUPS_MAX: _bindgen_ty_3 = 3; +pub const _SC_OPEN_MAX: _bindgen_ty_3 = 4; +pub const _SC_STREAM_MAX: _bindgen_ty_3 = 5; +pub const _SC_TZNAME_MAX: _bindgen_ty_3 = 6; +pub const _SC_JOB_CONTROL: _bindgen_ty_3 = 7; +pub const _SC_SAVED_IDS: _bindgen_ty_3 = 8; +pub const _SC_REALTIME_SIGNALS: _bindgen_ty_3 = 9; +pub const _SC_PRIORITY_SCHEDULING: _bindgen_ty_3 = 10; +pub const _SC_TIMERS: _bindgen_ty_3 = 11; +pub const _SC_ASYNCHRONOUS_IO: _bindgen_ty_3 = 12; +pub const _SC_PRIORITIZED_IO: _bindgen_ty_3 = 13; +pub const _SC_SYNCHRONIZED_IO: _bindgen_ty_3 = 14; +pub const _SC_FSYNC: _bindgen_ty_3 = 15; +pub const _SC_MAPPED_FILES: _bindgen_ty_3 = 16; +pub const _SC_MEMLOCK: _bindgen_ty_3 = 17; +pub const _SC_MEMLOCK_RANGE: _bindgen_ty_3 = 18; +pub const _SC_MEMORY_PROTECTION: _bindgen_ty_3 = 19; +pub const _SC_MESSAGE_PASSING: _bindgen_ty_3 = 20; +pub const _SC_SEMAPHORES: _bindgen_ty_3 = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: _bindgen_ty_3 = 22; +pub const _SC_AIO_LISTIO_MAX: _bindgen_ty_3 = 23; +pub const _SC_AIO_MAX: _bindgen_ty_3 = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: _bindgen_ty_3 = 25; +pub const _SC_DELAYTIMER_MAX: _bindgen_ty_3 = 26; +pub const _SC_MQ_OPEN_MAX: _bindgen_ty_3 = 27; +pub const _SC_MQ_PRIO_MAX: _bindgen_ty_3 = 28; +pub const _SC_VERSION: _bindgen_ty_3 = 29; +pub const _SC_PAGESIZE: _bindgen_ty_3 = 30; +pub const _SC_RTSIG_MAX: _bindgen_ty_3 = 31; +pub const _SC_SEM_NSEMS_MAX: _bindgen_ty_3 = 32; +pub const _SC_SEM_VALUE_MAX: _bindgen_ty_3 = 33; +pub const _SC_SIGQUEUE_MAX: _bindgen_ty_3 = 34; +pub const _SC_TIMER_MAX: _bindgen_ty_3 = 35; +pub const _SC_BC_BASE_MAX: _bindgen_ty_3 = 36; +pub const _SC_BC_DIM_MAX: _bindgen_ty_3 = 37; +pub const _SC_BC_SCALE_MAX: _bindgen_ty_3 = 38; +pub const _SC_BC_STRING_MAX: _bindgen_ty_3 = 39; +pub const _SC_COLL_WEIGHTS_MAX: _bindgen_ty_3 = 40; +pub const _SC_EQUIV_CLASS_MAX: _bindgen_ty_3 = 41; +pub const _SC_EXPR_NEST_MAX: _bindgen_ty_3 = 42; +pub const _SC_LINE_MAX: _bindgen_ty_3 = 43; +pub const _SC_RE_DUP_MAX: _bindgen_ty_3 = 44; +pub const _SC_CHARCLASS_NAME_MAX: _bindgen_ty_3 = 45; +pub const _SC_2_VERSION: _bindgen_ty_3 = 46; +pub const _SC_2_C_BIND: _bindgen_ty_3 = 47; +pub const _SC_2_C_DEV: _bindgen_ty_3 = 48; +pub const _SC_2_FORT_DEV: _bindgen_ty_3 = 49; +pub const _SC_2_FORT_RUN: _bindgen_ty_3 = 50; +pub const _SC_2_SW_DEV: _bindgen_ty_3 = 51; +pub const _SC_2_LOCALEDEF: _bindgen_ty_3 = 52; +pub const _SC_PII: _bindgen_ty_3 = 53; +pub const _SC_PII_XTI: _bindgen_ty_3 = 54; +pub const _SC_PII_SOCKET: _bindgen_ty_3 = 55; +pub const _SC_PII_INTERNET: _bindgen_ty_3 = 56; +pub const _SC_PII_OSI: _bindgen_ty_3 = 57; +pub const _SC_POLL: _bindgen_ty_3 = 58; +pub const _SC_SELECT: _bindgen_ty_3 = 59; +pub const _SC_UIO_MAXIOV: _bindgen_ty_3 = 60; +pub const _SC_IOV_MAX: _bindgen_ty_3 = 60; +pub const _SC_PII_INTERNET_STREAM: _bindgen_ty_3 = 61; +pub const _SC_PII_INTERNET_DGRAM: _bindgen_ty_3 = 62; +pub const _SC_PII_OSI_COTS: _bindgen_ty_3 = 63; +pub const _SC_PII_OSI_CLTS: _bindgen_ty_3 = 64; +pub const _SC_PII_OSI_M: _bindgen_ty_3 = 65; +pub const _SC_T_IOV_MAX: _bindgen_ty_3 = 66; +pub const _SC_THREADS: _bindgen_ty_3 = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: _bindgen_ty_3 = 68; +pub const _SC_GETGR_R_SIZE_MAX: _bindgen_ty_3 = 69; +pub const _SC_GETPW_R_SIZE_MAX: _bindgen_ty_3 = 70; +pub const _SC_LOGIN_NAME_MAX: _bindgen_ty_3 = 71; +pub const _SC_TTY_NAME_MAX: _bindgen_ty_3 = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: _bindgen_ty_3 = 73; +pub const _SC_THREAD_KEYS_MAX: _bindgen_ty_3 = 74; +pub const _SC_THREAD_STACK_MIN: _bindgen_ty_3 = 75; +pub const _SC_THREAD_THREADS_MAX: _bindgen_ty_3 = 76; +pub const _SC_THREAD_ATTR_STACKADDR: _bindgen_ty_3 = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: _bindgen_ty_3 = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: _bindgen_ty_3 = 79; +pub const _SC_THREAD_PRIO_INHERIT: _bindgen_ty_3 = 80; +pub const _SC_THREAD_PRIO_PROTECT: _bindgen_ty_3 = 81; +pub const _SC_THREAD_PROCESS_SHARED: _bindgen_ty_3 = 82; +pub const _SC_NPROCESSORS_CONF: _bindgen_ty_3 = 83; +pub const _SC_NPROCESSORS_ONLN: _bindgen_ty_3 = 84; +pub const _SC_PHYS_PAGES: _bindgen_ty_3 = 85; +pub const _SC_AVPHYS_PAGES: _bindgen_ty_3 = 86; +pub const _SC_ATEXIT_MAX: _bindgen_ty_3 = 87; +pub const _SC_PASS_MAX: _bindgen_ty_3 = 88; +pub const _SC_XOPEN_VERSION: _bindgen_ty_3 = 89; +pub const _SC_XOPEN_XCU_VERSION: _bindgen_ty_3 = 90; +pub const _SC_XOPEN_UNIX: _bindgen_ty_3 = 91; +pub const _SC_XOPEN_CRYPT: _bindgen_ty_3 = 92; +pub const _SC_XOPEN_ENH_I18N: _bindgen_ty_3 = 93; +pub const _SC_XOPEN_SHM: _bindgen_ty_3 = 94; +pub const _SC_2_CHAR_TERM: _bindgen_ty_3 = 95; +pub const _SC_2_C_VERSION: _bindgen_ty_3 = 96; +pub const _SC_2_UPE: _bindgen_ty_3 = 97; +pub const _SC_XOPEN_XPG2: _bindgen_ty_3 = 98; +pub const _SC_XOPEN_XPG3: _bindgen_ty_3 = 99; +pub const _SC_XOPEN_XPG4: _bindgen_ty_3 = 100; +pub const _SC_CHAR_BIT: _bindgen_ty_3 = 101; +pub const _SC_CHAR_MAX: _bindgen_ty_3 = 102; +pub const _SC_CHAR_MIN: _bindgen_ty_3 = 103; +pub const _SC_INT_MAX: _bindgen_ty_3 = 104; +pub const _SC_INT_MIN: _bindgen_ty_3 = 105; +pub const _SC_LONG_BIT: _bindgen_ty_3 = 106; +pub const _SC_WORD_BIT: _bindgen_ty_3 = 107; +pub const _SC_MB_LEN_MAX: _bindgen_ty_3 = 108; +pub const _SC_NZERO: _bindgen_ty_3 = 109; +pub const _SC_SSIZE_MAX: _bindgen_ty_3 = 110; +pub const _SC_SCHAR_MAX: _bindgen_ty_3 = 111; +pub const _SC_SCHAR_MIN: _bindgen_ty_3 = 112; +pub const _SC_SHRT_MAX: _bindgen_ty_3 = 113; +pub const _SC_SHRT_MIN: _bindgen_ty_3 = 114; +pub const _SC_UCHAR_MAX: _bindgen_ty_3 = 115; +pub const _SC_UINT_MAX: _bindgen_ty_3 = 116; +pub const _SC_ULONG_MAX: _bindgen_ty_3 = 117; +pub const _SC_USHRT_MAX: _bindgen_ty_3 = 118; +pub const _SC_NL_ARGMAX: _bindgen_ty_3 = 119; +pub const _SC_NL_LANGMAX: _bindgen_ty_3 = 120; +pub const _SC_NL_MSGMAX: _bindgen_ty_3 = 121; +pub const _SC_NL_NMAX: _bindgen_ty_3 = 122; +pub const _SC_NL_SETMAX: _bindgen_ty_3 = 123; +pub const _SC_NL_TEXTMAX: _bindgen_ty_3 = 124; +pub const _SC_XBS5_ILP32_OFF32: _bindgen_ty_3 = 125; +pub const _SC_XBS5_ILP32_OFFBIG: _bindgen_ty_3 = 126; +pub const _SC_XBS5_LP64_OFF64: _bindgen_ty_3 = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: _bindgen_ty_3 = 128; +pub const _SC_XOPEN_LEGACY: _bindgen_ty_3 = 129; +pub const _SC_XOPEN_REALTIME: _bindgen_ty_3 = 130; +pub const _SC_XOPEN_REALTIME_THREADS: _bindgen_ty_3 = 131; +pub const _SC_ADVISORY_INFO: _bindgen_ty_3 = 132; +pub const _SC_BARRIERS: _bindgen_ty_3 = 133; +pub const _SC_BASE: _bindgen_ty_3 = 134; +pub const _SC_C_LANG_SUPPORT: _bindgen_ty_3 = 135; +pub const _SC_C_LANG_SUPPORT_R: _bindgen_ty_3 = 136; +pub const _SC_CLOCK_SELECTION: _bindgen_ty_3 = 137; +pub const _SC_CPUTIME: _bindgen_ty_3 = 138; +pub const _SC_THREAD_CPUTIME: _bindgen_ty_3 = 139; +pub const _SC_DEVICE_IO: _bindgen_ty_3 = 140; +pub const _SC_DEVICE_SPECIFIC: _bindgen_ty_3 = 141; +pub const _SC_DEVICE_SPECIFIC_R: _bindgen_ty_3 = 142; +pub const _SC_FD_MGMT: _bindgen_ty_3 = 143; +pub const _SC_FIFO: _bindgen_ty_3 = 144; +pub const _SC_PIPE: _bindgen_ty_3 = 145; +pub const _SC_FILE_ATTRIBUTES: _bindgen_ty_3 = 146; +pub const _SC_FILE_LOCKING: _bindgen_ty_3 = 147; +pub const _SC_FILE_SYSTEM: _bindgen_ty_3 = 148; +pub const _SC_MONOTONIC_CLOCK: _bindgen_ty_3 = 149; +pub const _SC_MULTI_PROCESS: _bindgen_ty_3 = 150; +pub const _SC_SINGLE_PROCESS: _bindgen_ty_3 = 151; +pub const _SC_NETWORKING: _bindgen_ty_3 = 152; +pub const _SC_READER_WRITER_LOCKS: _bindgen_ty_3 = 153; +pub const _SC_SPIN_LOCKS: _bindgen_ty_3 = 154; +pub const _SC_REGEXP: _bindgen_ty_3 = 155; +pub const _SC_REGEX_VERSION: _bindgen_ty_3 = 156; +pub const _SC_SHELL: _bindgen_ty_3 = 157; +pub const _SC_SIGNALS: _bindgen_ty_3 = 158; +pub const _SC_SPAWN: _bindgen_ty_3 = 159; +pub const _SC_SPORADIC_SERVER: _bindgen_ty_3 = 160; +pub const _SC_THREAD_SPORADIC_SERVER: _bindgen_ty_3 = 161; +pub const _SC_SYSTEM_DATABASE: _bindgen_ty_3 = 162; +pub const _SC_SYSTEM_DATABASE_R: _bindgen_ty_3 = 163; +pub const _SC_TIMEOUTS: _bindgen_ty_3 = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: _bindgen_ty_3 = 165; +pub const _SC_USER_GROUPS: _bindgen_ty_3 = 166; +pub const _SC_USER_GROUPS_R: _bindgen_ty_3 = 167; +pub const _SC_2_PBS: _bindgen_ty_3 = 168; +pub const _SC_2_PBS_ACCOUNTING: _bindgen_ty_3 = 169; +pub const _SC_2_PBS_LOCATE: _bindgen_ty_3 = 170; +pub const _SC_2_PBS_MESSAGE: _bindgen_ty_3 = 171; +pub const _SC_2_PBS_TRACK: _bindgen_ty_3 = 172; +pub const _SC_SYMLOOP_MAX: _bindgen_ty_3 = 173; +pub const _SC_STREAMS: _bindgen_ty_3 = 174; +pub const _SC_2_PBS_CHECKPOINT: _bindgen_ty_3 = 175; +pub const _SC_V6_ILP32_OFF32: _bindgen_ty_3 = 176; +pub const _SC_V6_ILP32_OFFBIG: _bindgen_ty_3 = 177; +pub const _SC_V6_LP64_OFF64: _bindgen_ty_3 = 178; +pub const _SC_V6_LPBIG_OFFBIG: _bindgen_ty_3 = 179; +pub const _SC_HOST_NAME_MAX: _bindgen_ty_3 = 180; +pub const _SC_TRACE: _bindgen_ty_3 = 181; +pub const _SC_TRACE_EVENT_FILTER: _bindgen_ty_3 = 182; +pub const _SC_TRACE_INHERIT: _bindgen_ty_3 = 183; +pub const _SC_TRACE_LOG: _bindgen_ty_3 = 184; +pub const _SC_LEVEL1_ICACHE_SIZE: _bindgen_ty_3 = 185; +pub const _SC_LEVEL1_ICACHE_ASSOC: _bindgen_ty_3 = 186; +pub const _SC_LEVEL1_ICACHE_LINESIZE: _bindgen_ty_3 = 187; +pub const _SC_LEVEL1_DCACHE_SIZE: _bindgen_ty_3 = 188; +pub const _SC_LEVEL1_DCACHE_ASSOC: _bindgen_ty_3 = 189; +pub const _SC_LEVEL1_DCACHE_LINESIZE: _bindgen_ty_3 = 190; +pub const _SC_LEVEL2_CACHE_SIZE: _bindgen_ty_3 = 191; +pub const _SC_LEVEL2_CACHE_ASSOC: _bindgen_ty_3 = 192; +pub const _SC_LEVEL2_CACHE_LINESIZE: _bindgen_ty_3 = 193; +pub const _SC_LEVEL3_CACHE_SIZE: _bindgen_ty_3 = 194; +pub const _SC_LEVEL3_CACHE_ASSOC: _bindgen_ty_3 = 195; +pub const _SC_LEVEL3_CACHE_LINESIZE: _bindgen_ty_3 = 196; +pub const _SC_LEVEL4_CACHE_SIZE: _bindgen_ty_3 = 197; +pub const _SC_LEVEL4_CACHE_ASSOC: _bindgen_ty_3 = 198; +pub const _SC_LEVEL4_CACHE_LINESIZE: _bindgen_ty_3 = 199; +pub const _SC_IPV6: _bindgen_ty_3 = 235; +pub const _SC_RAW_SOCKETS: _bindgen_ty_3 = 236; +pub const _SC_V7_ILP32_OFF32: _bindgen_ty_3 = 237; +pub const _SC_V7_ILP32_OFFBIG: _bindgen_ty_3 = 238; +pub const _SC_V7_LP64_OFF64: _bindgen_ty_3 = 239; +pub const _SC_V7_LPBIG_OFFBIG: _bindgen_ty_3 = 240; +pub const _SC_SS_REPL_MAX: _bindgen_ty_3 = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: _bindgen_ty_3 = 242; +pub const _SC_TRACE_NAME_MAX: _bindgen_ty_3 = 243; +pub const _SC_TRACE_SYS_MAX: _bindgen_ty_3 = 244; +pub const _SC_TRACE_USER_EVENT_MAX: _bindgen_ty_3 = 245; +pub const _SC_XOPEN_STREAMS: _bindgen_ty_3 = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: _bindgen_ty_3 = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: _bindgen_ty_3 = 248; +pub type _bindgen_ty_3 = u32; + +pub const _CS_V6_WIDTH_RESTRICTED_ENVS: _bindgen_ty_4 = 1; +pub const _CS_GNU_LIBC_VERSION: _bindgen_ty_4 = 2; +pub const _CS_GNU_LIBPTHREAD_VERSION: _bindgen_ty_4 = 3; +pub const _CS_V5_WIDTH_RESTRICTED_ENVS: _bindgen_ty_4 = 4; +pub const _CS_V7_WIDTH_RESTRICTED_ENVS: _bindgen_ty_4 = 5; +pub const _CS_LFS_CFLAGS: _bindgen_ty_4 = 1000; +pub const _CS_LFS_LDFLAGS: _bindgen_ty_4 = 1001; +pub const _CS_LFS_LIBS: _bindgen_ty_4 = 1002; +pub const _CS_LFS_LINTFLAGS: _bindgen_ty_4 = 1003; +pub const _CS_LFS64_CFLAGS: _bindgen_ty_4 = 1004; +pub const _CS_LFS64_LDFLAGS: _bindgen_ty_4 = 1005; +pub const _CS_LFS64_LIBS: _bindgen_ty_4 = 1006; +pub const _CS_LFS64_LINTFLAGS: _bindgen_ty_4 = 1007; +pub const _CS_XBS5_ILP32_OFF32_CFLAGS: _bindgen_ty_4 = 1100; +pub const _CS_XBS5_ILP32_OFF32_LDFLAGS: _bindgen_ty_4 = 1101; +pub const _CS_XBS5_ILP32_OFF32_LIBS: _bindgen_ty_4 = 1102; +pub const _CS_XBS5_ILP32_OFF32_LINTFLAGS: _bindgen_ty_4 = 1103; +pub const _CS_XBS5_ILP32_OFFBIG_CFLAGS: _bindgen_ty_4 = 1104; +pub const _CS_XBS5_ILP32_OFFBIG_LDFLAGS: _bindgen_ty_4 = 1105; +pub const _CS_XBS5_ILP32_OFFBIG_LIBS: _bindgen_ty_4 = 1106; +pub const _CS_XBS5_ILP32_OFFBIG_LINTFLAGS: _bindgen_ty_4 = 1107; +pub const _CS_XBS5_LP64_OFF64_CFLAGS: _bindgen_ty_4 = 1108; +pub const _CS_XBS5_LP64_OFF64_LDFLAGS: _bindgen_ty_4 = 1109; +pub const _CS_XBS5_LP64_OFF64_LIBS: _bindgen_ty_4 = 1110; +pub const _CS_XBS5_LP64_OFF64_LINTFLAGS: _bindgen_ty_4 = 1111; +pub const _CS_XBS5_LPBIG_OFFBIG_CFLAGS: _bindgen_ty_4 = 1112; +pub const _CS_XBS5_LPBIG_OFFBIG_LDFLAGS: _bindgen_ty_4 = 1113; +pub const _CS_XBS5_LPBIG_OFFBIG_LIBS: _bindgen_ty_4 = 1114; +pub const _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS: _bindgen_ty_4 = 1115; +pub const _CS_POSIX_V6_ILP32_OFF32_CFLAGS: _bindgen_ty_4 = 1116; +pub const _CS_POSIX_V6_ILP32_OFF32_LDFLAGS: _bindgen_ty_4 = 1117; +pub const _CS_POSIX_V6_ILP32_OFF32_LIBS: _bindgen_ty_4 = 1118; +pub const _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS: _bindgen_ty_4 = 1119; +pub const _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS: _bindgen_ty_4 = 1120; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS: _bindgen_ty_4 = 1121; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LIBS: _bindgen_ty_4 = 1122; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS: _bindgen_ty_4 = 1123; +pub const _CS_POSIX_V6_LP64_OFF64_CFLAGS: _bindgen_ty_4 = 1124; +pub const _CS_POSIX_V6_LP64_OFF64_LDFLAGS: _bindgen_ty_4 = 1125; +pub const _CS_POSIX_V6_LP64_OFF64_LIBS: _bindgen_ty_4 = 1126; +pub const _CS_POSIX_V6_LP64_OFF64_LINTFLAGS: _bindgen_ty_4 = 1127; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS: _bindgen_ty_4 = 1128; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS: _bindgen_ty_4 = 1129; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LIBS: _bindgen_ty_4 = 1130; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS: _bindgen_ty_4 = 1131; +pub const _CS_POSIX_V7_ILP32_OFF32_CFLAGS: _bindgen_ty_4 = 1132; +pub const _CS_POSIX_V7_ILP32_OFF32_LDFLAGS: _bindgen_ty_4 = 1133; +pub const _CS_POSIX_V7_ILP32_OFF32_LIBS: _bindgen_ty_4 = 1134; +pub const _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS: _bindgen_ty_4 = 1135; +pub const _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS: _bindgen_ty_4 = 1136; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS: _bindgen_ty_4 = 1137; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LIBS: _bindgen_ty_4 = 1138; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS: _bindgen_ty_4 = 1139; +pub const _CS_POSIX_V7_LP64_OFF64_CFLAGS: _bindgen_ty_4 = 1140; +pub const _CS_POSIX_V7_LP64_OFF64_LDFLAGS: _bindgen_ty_4 = 1141; +pub const _CS_POSIX_V7_LP64_OFF64_LIBS: _bindgen_ty_4 = 1142; +pub const _CS_POSIX_V7_LP64_OFF64_LINTFLAGS: _bindgen_ty_4 = 1143; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS: _bindgen_ty_4 = 1144; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS: _bindgen_ty_4 = 1145; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LIBS: _bindgen_ty_4 = 1146; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS: _bindgen_ty_4 = 1147; +pub const _CS_V6_ENV: _bindgen_ty_4 = 1148; +pub const _CS_V7_ENV: _bindgen_ty_4 = 1149; +pub type _bindgen_ty_4 = u32; + +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigval { + pub sival_int: ::std::os::raw::c_int, + pub sival_ptr: *mut ::std::os::raw::c_void, + _bindgen_union_align: u64, +} +pub type __sigval_t = sigval; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t { + pub si_signo: ::std::os::raw::c_int, + pub si_errno: ::std::os::raw::c_int, + pub si_code: ::std::os::raw::c_int, + pub __pad0: ::std::os::raw::c_int, + pub _sifields: siginfo_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1 { + pub _pad: [::std::os::raw::c_int; 28usize], + pub _kill: siginfo_t__bindgen_ty_1__bindgen_ty_1, + pub _timer: siginfo_t__bindgen_ty_1__bindgen_ty_2, + pub _rt: siginfo_t__bindgen_ty_1__bindgen_ty_3, + pub _sigchld: siginfo_t__bindgen_ty_1__bindgen_ty_4, + pub _sigfault: siginfo_t__bindgen_ty_1__bindgen_ty_5, + pub _sigpoll: siginfo_t__bindgen_ty_1__bindgen_ty_6, + pub _sigsys: siginfo_t__bindgen_ty_1__bindgen_ty_7, + _bindgen_union_align: [u64; 14usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_2 { + pub si_tid: ::std::os::raw::c_int, + pub si_overrun: ::std::os::raw::c_int, + pub si_sigval: __sigval_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_3 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_sigval: __sigval_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_4 { + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_status: ::std::os::raw::c_int, + pub si_utime: __clock_t, + pub si_stime: __clock_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_5 { + pub si_addr: *mut ::std::os::raw::c_void, + pub si_addr_lsb: ::std::os::raw::c_short, + pub _bounds: siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1 { + pub _addr_bnd: siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, + pub _pkey: __uint32_t, + _bindgen_union_align: [u64; 2usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1 { + pub _lower: *mut ::std::os::raw::c_void, + pub _upper: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_6 { + pub si_band: ::std::os::raw::c_long, + pub si_fd: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_7 { + pub _call_addr: *mut ::std::os::raw::c_void, + pub _syscall: ::std::os::raw::c_int, + pub _arch: ::std::os::raw::c_uint, +} +pub const SI_ASYNCNL: _bindgen_ty_5 = -60; +pub const SI_TKILL: _bindgen_ty_5 = -6; +pub const SI_SIGIO: _bindgen_ty_5 = -5; +pub const SI_ASYNCIO: _bindgen_ty_5 = -4; +pub const SI_MESGQ: _bindgen_ty_5 = -3; +pub const SI_TIMER: _bindgen_ty_5 = -2; +pub const SI_QUEUE: _bindgen_ty_5 = -1; +pub const SI_USER: _bindgen_ty_5 = 0; +pub const SI_KERNEL: _bindgen_ty_5 = 128; +pub type _bindgen_ty_5 = i32; +pub const ILL_ILLOPC: _bindgen_ty_6 = 1; +pub const ILL_ILLOPN: _bindgen_ty_6 = 2; +pub const ILL_ILLADR: _bindgen_ty_6 = 3; +pub const ILL_ILLTRP: _bindgen_ty_6 = 4; +pub const ILL_PRVOPC: _bindgen_ty_6 = 5; +pub const ILL_PRVREG: _bindgen_ty_6 = 6; +pub const ILL_COPROC: _bindgen_ty_6 = 7; +pub const ILL_BADSTK: _bindgen_ty_6 = 8; +pub type _bindgen_ty_6 = u32; +pub const FPE_INTDIV: _bindgen_ty_7 = 1; +pub const FPE_INTOVF: _bindgen_ty_7 = 2; +pub const FPE_FLTDIV: _bindgen_ty_7 = 3; +pub const FPE_FLTOVF: _bindgen_ty_7 = 4; +pub const FPE_FLTUND: _bindgen_ty_7 = 5; +pub const FPE_FLTRES: _bindgen_ty_7 = 6; +pub const FPE_FLTINV: _bindgen_ty_7 = 7; +pub const FPE_FLTSUB: _bindgen_ty_7 = 8; +pub type _bindgen_ty_7 = u32; +pub const SEGV_MAPERR: _bindgen_ty_8 = 1; +pub const SEGV_ACCERR: _bindgen_ty_8 = 2; +pub const SEGV_BNDERR: _bindgen_ty_8 = 3; +pub const SEGV_PKUERR: _bindgen_ty_8 = 4; +pub type _bindgen_ty_8 = u32; +pub const BUS_ADRALN: _bindgen_ty_9 = 1; +pub const BUS_ADRERR: _bindgen_ty_9 = 2; +pub const BUS_OBJERR: _bindgen_ty_9 = 3; +pub const BUS_MCEERR_AR: _bindgen_ty_9 = 4; +pub const BUS_MCEERR_AO: _bindgen_ty_9 = 5; +pub type _bindgen_ty_9 = u32; +pub const TRAP_BRKPT: _bindgen_ty_10 = 1; +pub const TRAP_TRACE: _bindgen_ty_10 = 2; +pub type _bindgen_ty_10 = u32; +pub const CLD_EXITED: _bindgen_ty_11 = 1; +pub const CLD_KILLED: _bindgen_ty_11 = 2; +pub const CLD_DUMPED: _bindgen_ty_11 = 3; +pub const CLD_TRAPPED: _bindgen_ty_11 = 4; +pub const CLD_STOPPED: _bindgen_ty_11 = 5; +pub const CLD_CONTINUED: _bindgen_ty_11 = 6; +pub type _bindgen_ty_11 = u32; +pub const POLL_IN: _bindgen_ty_12 = 1; +pub const POLL_OUT: _bindgen_ty_12 = 2; +pub const POLL_MSG: _bindgen_ty_12 = 3; +pub const POLL_ERR: _bindgen_ty_12 = 4; +pub const POLL_PRI: _bindgen_ty_12 = 5; +pub const POLL_HUP: _bindgen_ty_12 = 6; +pub type _bindgen_ty_12 = u32; +pub type sigval_t = __sigval_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigevent { + pub sigev_value: __sigval_t, + pub sigev_signo: ::std::os::raw::c_int, + pub sigev_notify: ::std::os::raw::c_int, + pub _sigev_un: sigevent__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigevent__bindgen_ty_1 { + pub _pad: [::std::os::raw::c_int; 12usize], + pub _tid: __pid_t, + pub _sigev_thread: sigevent__bindgen_ty_1__bindgen_ty_1, + _bindgen_union_align: [u64; 6usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigevent__bindgen_ty_1__bindgen_ty_1 { + pub _function: ::core::option::Option, + pub _attribute: *mut pthread_attr_t, +} +pub type sigevent_t = sigevent; +pub const SIGEV_SIGNAL: _bindgen_ty_13 = 0; +pub const SIGEV_NONE: _bindgen_ty_13 = 1; +pub const SIGEV_THREAD: _bindgen_ty_13 = 2; +pub const SIGEV_THREAD_ID: _bindgen_ty_13 = 4; +pub type _bindgen_ty_13 = u32; + +pub type sighandler_t = __sighandler_t; +pub type sig_t = __sighandler_t; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigaction { + pub __sigaction_handler: sigaction__bindgen_ty_1, + pub sa_mask: __sigset_t, + pub sa_flags: ::std::os::raw::c_int, + pub sa_restorer: ::core::option::Option, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigaction__bindgen_ty_1 { + pub sa_handler: __sighandler_t, + pub sa_sigaction: ::core::option::Option< + fn(arg1: ::std::os::raw::c_int, arg2: *mut siginfo_t, arg3: *mut ::std::os::raw::c_void), + >, + _bindgen_union_align: u64, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpx_sw_bytes { + pub magic1: __uint32_t, + pub extended_size: __uint32_t, + pub xstate_bv: __uint64_t, + pub xstate_size: __uint32_t, + pub __glibc_reserved1: [__uint32_t; 7usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpreg { + pub significand: [::std::os::raw::c_ushort; 4usize], + pub exponent: ::std::os::raw::c_ushort, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpxreg { + pub significand: [::std::os::raw::c_ushort; 4usize], + pub exponent: ::std::os::raw::c_ushort, + pub __glibc_reserved1: [::std::os::raw::c_ushort; 3usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _xmmreg { + pub element: [__uint32_t; 4usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _fpstate { + pub cwd: __uint16_t, + pub swd: __uint16_t, + pub ftw: __uint16_t, + pub fop: __uint16_t, + pub rip: __uint64_t, + pub rdp: __uint64_t, + pub mxcsr: __uint32_t, + pub mxcr_mask: __uint32_t, + pub _st: [_fpxreg; 8usize], + pub _xmm: [_xmmreg; 16usize], + pub __glibc_reserved1: [__uint32_t; 24usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigcontext { + pub r8: __uint64_t, + pub r9: __uint64_t, + pub r10: __uint64_t, + pub r11: __uint64_t, + pub r12: __uint64_t, + pub r13: __uint64_t, + pub r14: __uint64_t, + pub r15: __uint64_t, + pub rdi: __uint64_t, + pub rsi: __uint64_t, + pub rbp: __uint64_t, + pub rbx: __uint64_t, + pub rdx: __uint64_t, + pub rax: __uint64_t, + pub rcx: __uint64_t, + pub rsp: __uint64_t, + pub rip: __uint64_t, + pub eflags: __uint64_t, + pub cs: ::std::os::raw::c_ushort, + pub gs: ::std::os::raw::c_ushort, + pub fs: ::std::os::raw::c_ushort, + pub __pad0: ::std::os::raw::c_ushort, + pub err: __uint64_t, + pub trapno: __uint64_t, + pub oldmask: __uint64_t, + pub cr2: __uint64_t, + pub __bindgen_anon_1: sigcontext__bindgen_ty_1, + pub __reserved1: [__uint64_t; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigcontext__bindgen_ty_1 { + pub fpstate: *mut _fpstate, + pub __fpstate_word: __uint64_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _xsave_hdr { + pub xstate_bv: __uint64_t, + pub __glibc_reserved1: [__uint64_t; 2usize], + pub __glibc_reserved2: [__uint64_t; 5usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _ymmh_state { + pub ymmh_space: [__uint32_t; 64usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _xstate { + pub fpstate: _fpstate, + pub xstate_hdr: _xsave_hdr, + pub ymmh: _ymmh_state, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct stack_t { + pub ss_sp: *mut ::std::os::raw::c_void, + pub ss_flags: ::std::os::raw::c_int, + pub ss_size: usize, +} +pub type greg_t = ::std::os::raw::c_longlong; +pub type gregset_t = [greg_t; 23usize]; +pub const REG_R8: _bindgen_ty_14 = 0; +pub const REG_R9: _bindgen_ty_14 = 1; +pub const REG_R10: _bindgen_ty_14 = 2; +pub const REG_R11: _bindgen_ty_14 = 3; +pub const REG_R12: _bindgen_ty_14 = 4; +pub const REG_R13: _bindgen_ty_14 = 5; +pub const REG_R14: _bindgen_ty_14 = 6; +pub const REG_R15: _bindgen_ty_14 = 7; +pub const REG_RDI: _bindgen_ty_14 = 8; +pub const REG_RSI: _bindgen_ty_14 = 9; +pub const REG_RBP: _bindgen_ty_14 = 10; +pub const REG_RBX: _bindgen_ty_14 = 11; +pub const REG_RDX: _bindgen_ty_14 = 12; +pub const REG_RAX: _bindgen_ty_14 = 13; +pub const REG_RCX: _bindgen_ty_14 = 14; +pub const REG_RSP: _bindgen_ty_14 = 15; +pub const REG_RIP: _bindgen_ty_14 = 16; +pub const REG_EFL: _bindgen_ty_14 = 17; +pub const REG_CSGSFS: _bindgen_ty_14 = 18; +pub const REG_ERR: _bindgen_ty_14 = 19; +pub const REG_TRAPNO: _bindgen_ty_14 = 20; +pub const REG_OLDMASK: _bindgen_ty_14 = 21; +pub const REG_CR2: _bindgen_ty_14 = 22; +pub type _bindgen_ty_14 = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _libc_fpxreg { + pub significand: [::std::os::raw::c_ushort; 4usize], + pub exponent: ::std::os::raw::c_ushort, + pub __glibc_reserved1: [::std::os::raw::c_ushort; 3usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _libc_xmmreg { + pub element: [__uint32_t; 4usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _libc_fpstate { + pub cwd: __uint16_t, + pub swd: __uint16_t, + pub ftw: __uint16_t, + pub fop: __uint16_t, + pub rip: __uint64_t, + pub rdp: __uint64_t, + pub mxcsr: __uint32_t, + pub mxcr_mask: __uint32_t, + pub _st: [_libc_fpxreg; 8usize], + pub _xmm: [_libc_xmmreg; 16usize], + pub __glibc_reserved1: [__uint32_t; 24usize], +} +pub type fpregset_t = *mut _libc_fpstate; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mcontext_t { + pub gregs: gregset_t, + pub fpregs: fpregset_t, + pub __reserved1: [::std::os::raw::c_ulonglong; 8usize], +} +#[repr(C)] +// #[derive(Debug, Copy, Clone)] +#[derive(Copy, Clone)] +pub struct ucontext_t { + pub uc_flags: ::std::os::raw::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: sigset_t, + pub __fpregs_mem: _libc_fpstate, + pub __ssp: [::std::os::raw::c_ulonglong; 4usize], +} + +pub const SS_ONSTACK: _bindgen_ty_15 = 1; +pub const SS_DISABLE: _bindgen_ty_15 = 2; +pub type _bindgen_ty_15 = u32; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigstack { + pub ss_sp: *mut ::std::os::raw::c_void, + pub ss_onstack: ::std::os::raw::c_int, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_rwlock_arch_t { + pub __readers: ::std::os::raw::c_uint, + pub __writers: ::std::os::raw::c_uint, + pub __wrphase_futex: ::std::os::raw::c_uint, + pub __writers_futex: ::std::os::raw::c_uint, + pub __pad3: ::std::os::raw::c_uint, + pub __pad4: ::std::os::raw::c_uint, + pub __cur_writer: ::std::os::raw::c_int, + pub __shared: ::std::os::raw::c_int, + pub __rwelision: ::std::os::raw::c_schar, + pub __pad1: [::std::os::raw::c_uchar; 7usize], + pub __pad2: ::std::os::raw::c_ulong, + pub __flags: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_internal_list { + pub __prev: *mut __pthread_internal_list, + pub __next: *mut __pthread_internal_list, +} +pub type __pthread_list_t = __pthread_internal_list; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_mutex_s { + pub __lock: ::std::os::raw::c_int, + pub __count: ::std::os::raw::c_uint, + pub __owner: ::std::os::raw::c_int, + pub __nusers: ::std::os::raw::c_uint, + pub __kind: ::std::os::raw::c_int, + pub __spins: ::std::os::raw::c_short, + pub __elision: ::std::os::raw::c_short, + pub __list: __pthread_list_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __pthread_cond_s { + pub __bindgen_anon_1: __pthread_cond_s__bindgen_ty_1, + pub __bindgen_anon_2: __pthread_cond_s__bindgen_ty_2, + pub __g_refs: [::std::os::raw::c_uint; 2usize], + pub __g_size: [::std::os::raw::c_uint; 2usize], + pub __g1_orig_size: ::std::os::raw::c_uint, + pub __wrefs: ::std::os::raw::c_uint, + pub __g_signals: [::std::os::raw::c_uint; 2usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __pthread_cond_s__bindgen_ty_1 { + pub __wseq: ::std::os::raw::c_ulonglong, + pub __wseq32: __pthread_cond_s__bindgen_ty_1__bindgen_ty_1, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_cond_s__bindgen_ty_1__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __pthread_cond_s__bindgen_ty_2 { + pub __g1_start: ::std::os::raw::c_ulonglong, + pub __g1_start32: __pthread_cond_s__bindgen_ty_2__bindgen_ty_1, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_cond_s__bindgen_ty_2__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +pub type pthread_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutexattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_condattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +pub type pthread_key_t = ::std::os::raw::c_uint; +pub type pthread_once_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_attr_t { + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 7usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutex_t { + pub __data: __pthread_mutex_s, + pub __size: [::std::os::raw::c_char; 40usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 5usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_cond_t { + pub __data: __pthread_cond_s, + pub __size: [::std::os::raw::c_char; 48usize], + pub __align: ::std::os::raw::c_longlong, + _bindgen_union_align: [u64; 6usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlock_t { + pub __data: __pthread_rwlock_arch_t, + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 7usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlockattr_t { + pub __size: [::std::os::raw::c_char; 8usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: u64, +} +pub type pthread_spinlock_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrier_t { + pub __size: [::std::os::raw::c_char; 32usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 4usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrierattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} + +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; + +pub type uintmax_t = __uintmax_t; +pub const r_instruction_r_output_direction: r_instruction = 0; +pub const r_instruction_r_input_direction: r_instruction = 1; +pub const r_instruction_r_inputa_direction: r_instruction = 2; +pub const r_instruction_r_appending_to: r_instruction = 3; +pub const r_instruction_r_reading_until: r_instruction = 4; +pub const r_instruction_r_reading_string: r_instruction = 5; +pub const r_instruction_r_duplicating_input: r_instruction = 6; +pub const r_instruction_r_duplicating_output: r_instruction = 7; +pub const r_instruction_r_deblank_reading_until: r_instruction = 8; +pub const r_instruction_r_close_this: r_instruction = 9; +pub const r_instruction_r_err_and_out: r_instruction = 10; +pub const r_instruction_r_input_output: r_instruction = 11; +pub const r_instruction_r_output_force: r_instruction = 12; +pub const r_instruction_r_duplicating_input_word: r_instruction = 13; +pub const r_instruction_r_duplicating_output_word: r_instruction = 14; +pub const r_instruction_r_move_input: r_instruction = 15; +pub const r_instruction_r_move_output: r_instruction = 16; +pub const r_instruction_r_move_input_word: r_instruction = 17; +pub const r_instruction_r_move_output_word: r_instruction = 18; +pub const r_instruction_r_append_err_and_out: r_instruction = 19; +pub type r_instruction = u32; +pub const command_type_cm_for: command_type = 0; +pub const command_type_cm_case: command_type = 1; +pub const command_type_cm_while: command_type = 2; +pub const command_type_cm_if: command_type = 3; +pub const command_type_cm_simple: command_type = 4; +pub const command_type_cm_select: command_type = 5; +pub const command_type_cm_connection: command_type = 6; +pub const command_type_cm_function_def: command_type = 7; +pub const command_type_cm_until: command_type = 8; +pub const command_type_cm_group: command_type = 9; +pub const command_type_cm_arith: command_type = 10; +pub const command_type_cm_cond: command_type = 11; +pub const command_type_cm_arith_for: command_type = 12; +pub const command_type_cm_subshell: command_type = 13; +pub const command_type_cm_coproc: command_type = 14; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct element { + pub word: *mut WordDesc, + pub redirect: *mut REDIRECT, +} +pub type ELEMENT = element; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct coproc { + pub c_name: *mut ::std::os::raw::c_char, + pub c_pid: pid_t, + pub c_rfd: ::std::os::raw::c_int, + pub c_wfd: ::std::os::raw::c_int, + pub c_rsave: ::std::os::raw::c_int, + pub c_wsave: ::std::os::raw::c_int, + pub c_flags: ::std::os::raw::c_int, + pub c_status: ::std::os::raw::c_int, + pub c_lock: ::std::os::raw::c_int, +} +pub type Coproc = coproc; + +pub type u_char = __u_char; +pub type u_short = __u_short; +pub type u_int = __u_int; +pub type u_long = __u_long; +pub type quad_t = __quad_t; +pub type u_quad_t = __u_quad_t; +pub type fsid_t = __fsid_t; +pub type loff_t = __loff_t; +pub type ino_t = __ino_t; +pub type ino64_t = __ino64_t; +pub type dev_t = __dev_t; +pub type mode_t = __mode_t; +pub type nlink_t = __nlink_t; +pub type id_t = __id_t; +pub type daddr_t = __daddr_t; +pub type caddr_t = __caddr_t; +pub type key_t = __key_t; +pub type clock_t = __clock_t; +pub type clockid_t = __clockid_t; + +pub type timer_t = __timer_t; +pub type suseconds_t = __suseconds_t; +pub type ulong = ::std::os::raw::c_ulong; +pub type ushort = ::std::os::raw::c_ushort; +pub type uint = ::std::os::raw::c_uint; +pub type u_int8_t = ::std::os::raw::c_uchar; +pub type u_int16_t = ::std::os::raw::c_ushort; +pub type u_int32_t = ::std::os::raw::c_uint; +pub type u_int64_t = ::std::os::raw::c_ulong; +pub type register_t = ::std::os::raw::c_long; + +pub type __fd_mask = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fd_set { + pub fds_bits: [__fd_mask; 16usize], +} +pub type fd_mask = __fd_mask; + +pub type blksize_t = __blksize_t; +pub type blkcnt_t = __blkcnt_t; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +pub type blkcnt64_t = __blkcnt64_t; +pub type fsblkcnt64_t = __fsblkcnt64_t; +pub type fsfilcnt64_t = __fsfilcnt64_t; +pub type __gwchar_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct imaxdiv_t { + pub quot: ::std::os::raw::c_long, + pub rem: ::std::os::raw::c_long, +} + +pub type _bindgen_ty_16 = u32; + +pub const __itimer_which_ITIMER_REAL: __itimer_which = 0; +pub const __itimer_which_ITIMER_VIRTUAL: __itimer_which = 1; +pub const __itimer_which_ITIMER_PROF: __itimer_which = 2; +pub type __itimer_which = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerval { + pub it_interval: timeval, + pub it_value: timeval, +} + +pub use self::__itimer_which as __itimer_which_t; + +pub const __rlimit_resource_RLIMIT_CPU: __rlimit_resource = 0; +pub const __rlimit_resource_RLIMIT_FSIZE: __rlimit_resource = 1; +pub const __rlimit_resource_RLIMIT_DATA: __rlimit_resource = 2; +pub const __rlimit_resource_RLIMIT_STACK: __rlimit_resource = 3; +pub const __rlimit_resource_RLIMIT_CORE: __rlimit_resource = 4; +pub const __rlimit_resource___RLIMIT_RSS: __rlimit_resource = 5; +pub const __rlimit_resource_RLIMIT_NOFILE: __rlimit_resource = 7; +pub const __rlimit_resource___RLIMIT_OFILE: __rlimit_resource = 7; +pub const __rlimit_resource_RLIMIT_AS: __rlimit_resource = 9; +pub const __rlimit_resource___RLIMIT_NPROC: __rlimit_resource = 6; +pub const __rlimit_resource___RLIMIT_MEMLOCK: __rlimit_resource = 8; +pub const __rlimit_resource___RLIMIT_LOCKS: __rlimit_resource = 10; +pub const __rlimit_resource___RLIMIT_SIGPENDING: __rlimit_resource = 11; +pub const __rlimit_resource___RLIMIT_MSGQUEUE: __rlimit_resource = 12; +pub const __rlimit_resource___RLIMIT_NICE: __rlimit_resource = 13; +pub const __rlimit_resource___RLIMIT_RTPRIO: __rlimit_resource = 14; +pub const __rlimit_resource___RLIMIT_RTTIME: __rlimit_resource = 15; +pub const __rlimit_resource___RLIMIT_NLIMITS: __rlimit_resource = 16; +pub const __rlimit_resource___RLIM_NLIMITS: __rlimit_resource = 16; +pub type __rlimit_resource = u32; + +pub type rlim64_t = __rlim64_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, +} +pub const __rusage_who_RUSAGE_SELF: __rusage_who = 0; +pub const __rusage_who_RUSAGE_CHILDREN: __rusage_who = -1; +pub const __rusage_who_RUSAGE_THREAD: __rusage_who = 1; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub __bindgen_anon_1: rusage__bindgen_ty_1, + pub __bindgen_anon_2: rusage__bindgen_ty_2, + pub __bindgen_anon_3: rusage__bindgen_ty_3, + pub __bindgen_anon_4: rusage__bindgen_ty_4, + pub __bindgen_anon_5: rusage__bindgen_ty_5, + pub __bindgen_anon_6: rusage__bindgen_ty_6, + pub __bindgen_anon_7: rusage__bindgen_ty_7, + pub __bindgen_anon_8: rusage__bindgen_ty_8, + pub __bindgen_anon_9: rusage__bindgen_ty_9, + pub __bindgen_anon_10: rusage__bindgen_ty_10, + pub __bindgen_anon_11: rusage__bindgen_ty_11, + pub __bindgen_anon_12: rusage__bindgen_ty_12, + pub __bindgen_anon_13: rusage__bindgen_ty_13, + pub __bindgen_anon_14: rusage__bindgen_ty_14, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_1 { + pub ru_maxrss: ::std::os::raw::c_long, + pub __ru_maxrss_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_2 { + pub ru_ixrss: ::std::os::raw::c_long, + pub __ru_ixrss_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_3 { + pub ru_idrss: ::std::os::raw::c_long, + pub __ru_idrss_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_4 { + pub ru_isrss: ::std::os::raw::c_long, + pub __ru_isrss_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_5 { + pub ru_minflt: ::std::os::raw::c_long, + pub __ru_minflt_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_6 { + pub ru_majflt: ::std::os::raw::c_long, + pub __ru_majflt_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_7 { + pub ru_nswap: ::std::os::raw::c_long, + pub __ru_nswap_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_8 { + pub ru_inblock: ::std::os::raw::c_long, + pub __ru_inblock_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_9 { + pub ru_oublock: ::std::os::raw::c_long, + pub __ru_oublock_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_10 { + pub ru_msgsnd: ::std::os::raw::c_long, + pub __ru_msgsnd_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_11 { + pub ru_msgrcv: ::std::os::raw::c_long, + pub __ru_msgrcv_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_12 { + pub ru_nsignals: ::std::os::raw::c_long, + pub __ru_nsignals_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_13 { + pub ru_nvcsw: ::std::os::raw::c_long, + pub __ru_nvcsw_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rusage__bindgen_ty_14 { + pub ru_nivcsw: ::std::os::raw::c_long, + pub __ru_nivcsw_word: __syscall_slong_t, + _bindgen_union_align: u64, +} +pub const __priority_which_PRIO_PROCESS: __priority_which = 0; +pub const __priority_which_PRIO_PGRP: __priority_which = 1; +pub const __priority_which_PRIO_USER: __priority_which = 2; +pub type __priority_which = u32; + +pub use self::__priority_which as __priority_which_t; +pub use self::__rlimit_resource as __rlimit_resource_t; +pub use self::__rusage_who as __rusage_who_t; + +pub const idtype_t_P_ALL: idtype_t = 0; +pub const idtype_t_P_PID: idtype_t = 1; +pub const idtype_t_P_PGID: idtype_t = 2; +pub type idtype_t = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct div_t { + pub quot: ::std::os::raw::c_int, + pub rem: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ldiv_t { + pub quot: ::std::os::raw::c_long, + pub rem: ::std::os::raw::c_long, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldiv_t { + pub quot: ::std::os::raw::c_longlong, + pub rem: ::std::os::raw::c_longlong, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct random_data { + pub fptr: *mut i32, + pub rptr: *mut i32, + pub state: *mut i32, + pub rand_type: ::std::os::raw::c_int, + pub rand_deg: ::std::os::raw::c_int, + pub rand_sep: ::std::os::raw::c_int, + pub end_ptr: *mut i32, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct drand48_data { + pub __x: [::std::os::raw::c_ushort; 3usize], + pub __old_x: [::std::os::raw::c_ushort; 3usize], + pub __c: ::std::os::raw::c_ushort, + pub __init: ::std::os::raw::c_ushort, + pub __a: ::std::os::raw::c_ulonglong, +} + +pub type comparison_fn_t = __compar_fn_t; +pub type __compar_d_fn_t = ::core::option::Option< + fn( + arg1: *const ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, +>; + +pub type CPFunction = ::core::option::Option *mut ::std::os::raw::c_char>; +pub type CPPFunction = ::core::option::Option *mut *mut ::std::os::raw::c_char>; +pub type sh_intfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type sh_ivoidfunc_t = ::core::option::Option ::std::os::raw::c_int>; +pub type sh_icpfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type sh_icppfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type sh_iptrfunc_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type sh_voidfunc_t = ::core::option::Option; +pub type sh_vintfunc_t = ::core::option::Option; +pub type sh_vcpfunc_t = ::core::option::Option; +pub type sh_vcppfunc_t = ::core::option::Option; +pub type sh_vptrfunc_t = ::core::option::Option; +pub type sh_wdesc_func_t = ::core::option::Option ::std::os::raw::c_int>; +pub type sh_wlist_func_t = ::core::option::Option ::std::os::raw::c_int>; +pub type sh_glist_func_t = + ::core::option::Option ::std::os::raw::c_int>; + +pub type sh_msg_func_t = ::core::option::Option< + unsafe extern "C" fn(arg1: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int, +>; +pub type sh_vmsg_func_t = + ::core::option::Option; + +pub type sh_free_func_t = ::core::option::Option; + +pub type sh_assign_func_t = + ::core::option::Option ::std::os::raw::c_int>; + +pub type sh_load_func_t = + ::core::option::Option ::std::os::raw::c_int>; +pub type sh_unload_func_t = ::core::option::Option; + +pub const atype_array_assoc: atype = 1; + +pub type sh_strlist_map_func_t = + ::core::option::Option ::std::os::raw::c_int>; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct var_context { + pub name: *mut ::std::os::raw::c_char, + pub scope: ::std::os::raw::c_int, + pub flags: ::std::os::raw::c_int, + pub up: *mut var_context, + pub down: *mut var_context, + pub table: *mut HASH_TABLE, +} +pub type VAR_CONTEXT = var_context; + +#[repr(C)] +#[derive(Copy, Clone)] +pub union _value { + pub s: *mut ::std::os::raw::c_char, + pub i: intmax_t, + pub f: *mut COMMAND, + pub a: *mut ARRAY, + pub h: *mut HASH_TABLE, + pub d: f64, + pub ld: f64, + pub v: *mut variable, + pub opaque: *mut ::std::os::raw::c_void, + _bindgen_union_align: [u8; 16usize], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _vlist { + pub list: *mut *mut SHELL_VAR, + pub list_size: usize, + pub list_len: usize, +} +pub type VARLIST = _vlist; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _G_fpos_t { + pub __pos: __off_t, + pub __state: __mbstate_t, +} +pub type __fpos_t = _G_fpos_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _G_fpos64_t { + pub __pos: __off64_t, + pub __state: __mbstate_t, +} +pub type __fpos64_t = _G_fpos64_t; + +pub type cookie_read_function_t = ::core::option::Option< + fn( + __cookie: *mut ::std::os::raw::c_void, + __buf: *mut ::std::os::raw::c_char, + __nbytes: usize, + ) -> __ssize_t, +>; +pub type cookie_write_function_t = ::core::option::Option< + fn( + __cookie: *mut ::std::os::raw::c_void, + __buf: *const ::std::os::raw::c_char, + __nbytes: usize, + ) -> __ssize_t, +>; +pub type cookie_seek_function_t = ::core::option::Option< + fn( + __cookie: *mut ::std::os::raw::c_void, + __pos: *mut __off64_t, + __w: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, +>; +pub type cookie_close_function_t = + ::core::option::Option ::std::os::raw::c_int>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _IO_cookie_io_functions_t { + pub read: cookie_read_function_t, + pub write: cookie_write_function_t, + pub seek: cookie_seek_function_t, + pub close: cookie_close_function_t, +} +pub type cookie_io_functions_t = _IO_cookie_io_functions_t; +pub type fpos_t = __fpos_t; +pub type fpos64_t = __fpos64_t; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct obstack { + _unused: [u8; 0], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _pathdata { + pub path: *mut ::std::os::raw::c_char, + pub flags: ::std::os::raw::c_int, +} +pub type PATH_DATA = _pathdata; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pipeline_saver { + pub pipeline: *mut process, + pub next: *mut pipeline_saver, +} +#[no_mangle] +pub static mut wait_intr_flag: ::std::os::raw::c_int = 0; +pub const JOB_STATE_JNONE: JOB_STATE = -1; +pub const JOB_STATE_JRUNNING: JOB_STATE = 1; +pub const JOB_STATE_JSTOPPED: JOB_STATE = 2; +pub const JOB_STATE_JDEAD: JOB_STATE = 4; +pub const JOB_STATE_JMIXED: JOB_STATE = 8; +pub type JOB_STATE = i32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct job { + pub wd: *mut ::std::os::raw::c_char, + pub pipe: *mut PROCESS, + pub pgrp: pid_t, + pub state: JOB_STATE, + pub flags: ::std::os::raw::c_int, + pub deferred: *mut COMMAND, + pub j_cleanup: sh_vptrfunc_t, + pub cleanarg: *mut ::std::os::raw::c_void, +} +pub type JOB = job; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct jobstats { + pub c_childmax: ::std::os::raw::c_long, + pub c_living: ::std::os::raw::c_int, + pub c_reaped: ::std::os::raw::c_int, + pub c_injobs: ::std::os::raw::c_int, + pub c_totforked: ::std::os::raw::c_int, + pub c_totreaped: ::std::os::raw::c_int, + pub j_jobslots: ::std::os::raw::c_int, + pub j_lastj: ::std::os::raw::c_int, + pub j_firstj: ::std::os::raw::c_int, + pub j_njobs: ::std::os::raw::c_int, + pub j_ndead: ::std::os::raw::c_int, + pub j_current: ::std::os::raw::c_int, + pub j_previous: ::std::os::raw::c_int, + pub j_lastmade: *mut JOB, + pub j_lastasync: *mut JOB, +} +pub type ps_index_t = pid_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pidstat { + pub bucket_next: ps_index_t, + pub bucket_prev: ps_index_t, + pub pid: pid_t, + pub status: ::std::os::raw::c_short, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bgpids { + pub storage: *mut pidstat, + pub head: ps_index_t, + pub nalloc: ps_index_t, + pub npid: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct procstat { + pub pid: pid_t, + pub status: ::std::os::raw::c_short, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct procchain { + pub head: *mut PROCESS, + pub end: *mut PROCESS, + pub nproc: ::std::os::raw::c_int, +} + +pub type jmp_buf = [__jmp_buf_tag; 1usize]; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _sh_input_line_state_t { + pub input_line: *mut ::std::os::raw::c_char, + pub input_line_index: usize, + pub input_line_size: usize, + pub input_line_len: usize, + pub input_property: *mut ::std::os::raw::c_char, + pub input_propsize: usize, +} +pub type sh_input_line_state_t = _sh_input_line_state_t; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct func_array_state { + pub funcname_a: *mut ARRAY, + pub funcname_v: *mut SHELL_VAR, + pub source_a: *mut ARRAY, + pub source_v: *mut SHELL_VAR, + pub lineno_a: *mut ARRAY, + pub lineno_v: *mut SHELL_VAR, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct execstate { + pub pid: pid_t, + pub subshell_env: ::std::os::raw::c_int, +} + +pub const stream_type_st_none: stream_type = 0; +pub const stream_type_st_stdin: stream_type = 1; +pub const stream_type_st_stream: stream_type = 2; +pub const stream_type_st_string: stream_type = 3; +pub const stream_type_st_bstream: stream_type = 4; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct builtin { + pub name: *mut ::std::os::raw::c_char, + pub function: Option, + pub flags: ::std::os::raw::c_int, + pub long_doc: *const *mut ::std::os::raw::c_char, + pub short_doc: *const ::std::os::raw::c_char, + pub handle: *mut ::std::os::raw::c_char, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct dstack { + pub delimiters: *mut ::std::os::raw::c_char, + pub delimiter_depth: ::std::os::raw::c_int, + pub delimiter_space: ::std::os::raw::c_int, +} + +pub const yytokentype_IF: yytokentype = 258; +pub const yytokentype_THEN: yytokentype = 259; +pub const yytokentype_ELSE: yytokentype = 260; +pub const yytokentype_ELIF: yytokentype = 261; +pub const yytokentype_FI: yytokentype = 262; +pub const yytokentype_CASE: yytokentype = 263; +pub const yytokentype_ESAC: yytokentype = 264; +pub const yytokentype_FOR: yytokentype = 265; +pub const yytokentype_SELECT: yytokentype = 266; +pub const yytokentype_WHILE: yytokentype = 267; +pub const yytokentype_UNTIL: yytokentype = 268; +pub const yytokentype_DO: yytokentype = 269; +pub const yytokentype_DONE: yytokentype = 270; +pub const yytokentype_FUNCTION: yytokentype = 271; +pub const yytokentype_COPROC: yytokentype = 272; +pub const yytokentype_COND_START: yytokentype = 273; +pub const yytokentype_COND_END: yytokentype = 274; +pub const yytokentype_COND_ERROR: yytokentype = 275; +pub const yytokentype_IN: yytokentype = 276; +pub const yytokentype_BANG: yytokentype = 277; +pub const yytokentype_TIME: yytokentype = 278; +pub const yytokentype_TIMEOPT: yytokentype = 279; +pub const yytokentype_TIMEIGN: yytokentype = 280; +pub const yytokentype_WORD: yytokentype = 281; +pub const yytokentype_ASSIGNMENT_WORD: yytokentype = 282; +pub const yytokentype_REDIR_WORD: yytokentype = 283; +pub const yytokentype_NUMBER: yytokentype = 284; +pub const yytokentype_ARITH_CMD: yytokentype = 285; +pub const yytokentype_ARITH_FOR_EXPRS: yytokentype = 286; +pub const yytokentype_COND_CMD: yytokentype = 287; +pub const yytokentype_AND_AND: yytokentype = 288; +pub const yytokentype_OR_OR: yytokentype = 289; +pub const yytokentype_GREATER_GREATER: yytokentype = 290; +pub const yytokentype_LESS_LESS: yytokentype = 291; +pub const yytokentype_LESS_AND: yytokentype = 292; +pub const yytokentype_LESS_LESS_LESS: yytokentype = 293; +pub const yytokentype_GREATER_AND: yytokentype = 294; +pub const yytokentype_SEMI_SEMI: yytokentype = 295; +pub const yytokentype_SEMI_AND: yytokentype = 296; +pub const yytokentype_SEMI_SEMI_AND: yytokentype = 297; +pub const yytokentype_LESS_LESS_MINUS: yytokentype = 298; +pub const yytokentype_AND_GREATER: yytokentype = 299; +pub const yytokentype_AND_GREATER_GREATER: yytokentype = 300; +pub const yytokentype_LESS_GREATER: yytokentype = 301; +pub const yytokentype_GREATER_BAR: yytokentype = 302; +pub const yytokentype_BAR_AND: yytokentype = 303; +pub const yytokentype_yacc_EOF: yytokentype = 304; +pub type yytokentype = u32; +#[repr(C)] +#[derive(Copy, Clone)] +pub union YYSTYPE { + pub word: *mut WordDesc, + pub number: ::std::os::raw::c_int, + pub WordList: *mut WordList, + pub command: *mut COMMAND, + pub redirect: *mut REDIRECT, + pub element: ELEMENT, + pub pattern: *mut PATTERN_LIST, + _bindgen_union_align: [u64; 2usize], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct flock { + pub l_type: ::std::os::raw::c_short, + pub l_whence: ::std::os::raw::c_short, + pub l_start: __off_t, + pub l_len: __off_t, + pub l_pid: __pid_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct flock64 { + pub l_type: ::std::os::raw::c_short, + pub l_whence: ::std::os::raw::c_short, + pub l_start: __off64_t, + pub l_len: __off64_t, + pub l_pid: __pid_t, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct iovec { + pub iov_base: *mut ::std::os::raw::c_void, + pub iov_len: usize, +} +pub const __pid_type_F_OWNER_TID: __pid_type = 0; +pub const __pid_type_F_OWNER_PID: __pid_type = 1; +pub const __pid_type_F_OWNER_PGRP: __pid_type = 2; +pub const __pid_type_F_OWNER_GID: __pid_type = 2; +pub type __pid_type = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct f_owner_ex { + pub type_: __pid_type, + pub pid: __pid_t, +} +#[repr(C)] +#[derive(Debug)] +pub struct file_handle { + pub handle_bytes: ::std::os::raw::c_uint, + pub handle_type: ::std::os::raw::c_int, + pub f_handle: __IncompleteArrayField<::std::os::raw::c_uchar>, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct stat64 { + pub st_dev: __dev_t, + pub st_ino: __ino64_t, + pub st_nlink: __nlink_t, + pub st_mode: __mode_t, + pub st_uid: __uid_t, + pub st_gid: __gid_t, + pub __pad0: ::std::os::raw::c_int, + pub st_rdev: __dev_t, + pub st_size: __off_t, + pub st_blksize: __blksize_t, + pub st_blocks: __blkcnt64_t, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + pub __glibc_reserved: [__syscall_slong_t; 3usize], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct statx_timestamp { + pub tv_sec: __int64_t, + pub tv_nsec: __uint32_t, + pub __statx_timestamp_pad1: [__int32_t; 1usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct statx { + pub stx_mask: __uint32_t, + pub stx_blksize: __uint32_t, + pub stx_attributes: __uint64_t, + pub stx_nlink: __uint32_t, + pub stx_uid: __uint32_t, + pub stx_gid: __uint32_t, + pub stx_mode: __uint16_t, + pub __statx_pad1: [__uint16_t; 1usize], + pub stx_ino: __uint64_t, + pub stx_size: __uint64_t, + pub stx_blocks: __uint64_t, + pub stx_attributes_mask: __uint64_t, + pub stx_atime: statx_timestamp, + pub stx_btime: statx_timestamp, + pub stx_ctime: statx_timestamp, + pub stx_mtime: statx_timestamp, + pub stx_rdev_major: __uint32_t, + pub stx_rdev_minor: __uint32_t, + pub stx_dev_major: __uint32_t, + pub stx_dev_minor: __uint32_t, + pub __statx_pad2: [__uint64_t; 14usize], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timex { + pub modes: ::std::os::raw::c_uint, + pub offset: __syscall_slong_t, + pub freq: __syscall_slong_t, + pub maxerror: __syscall_slong_t, + pub esterror: __syscall_slong_t, + pub status: ::std::os::raw::c_int, + pub constant: __syscall_slong_t, + pub precision: __syscall_slong_t, + pub tolerance: __syscall_slong_t, + pub time: timeval, + pub tick: __syscall_slong_t, + pub ppsfreq: __syscall_slong_t, + pub jitter: __syscall_slong_t, + pub shift: ::std::os::raw::c_int, + pub stabil: __syscall_slong_t, + pub jitcnt: __syscall_slong_t, + pub calcnt: __syscall_slong_t, + pub errcnt: __syscall_slong_t, + pub stbcnt: __syscall_slong_t, + pub tai: ::std::os::raw::c_int, + pub _bitfield_1: [i32; 11], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tm { + pub tm_sec: ::std::os::raw::c_int, + pub tm_min: ::std::os::raw::c_int, + pub tm_hour: ::std::os::raw::c_int, + pub tm_mday: ::std::os::raw::c_int, + pub tm_mon: ::std::os::raw::c_int, + pub tm_year: ::std::os::raw::c_int, + pub tm_wday: ::std::os::raw::c_int, + pub tm_yday: ::std::os::raw::c_int, + pub tm_isdst: ::std::os::raw::c_int, + pub tm_gmtoff: ::std::os::raw::c_long, + pub tm_zone: *const ::std::os::raw::c_char, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tms { + pub tms_utime: clock_t, + pub tms_stime: clock_t, + pub tms_cutime: clock_t, + pub tms_cstime: clock_t, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct dirent { + pub d_ino: __ino_t, + pub d_off: __off_t, + pub d_reclen: ::std::os::raw::c_ushort, + pub d_type: ::std::os::raw::c_uchar, + pub d_name: [::std::os::raw::c_char; 256usize], +} +pub type __ino64_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct dirent64 { + pub d_ino: __ino64_t, + pub d_off: __off64_t, + pub d_reclen: ::std::os::raw::c_ushort, + pub d_type: ::std::os::raw::c_uchar, + pub d_name: [::std::os::raw::c_char; 256usize], +} +pub const DT_UNKNOWN: _bindgen_ty_17 = 0; +pub const DT_FIFO: _bindgen_ty_17 = 1; +pub const DT_CHR: _bindgen_ty_17 = 2; +pub const DT_DIR: _bindgen_ty_17 = 4; +pub const DT_BLK: _bindgen_ty_17 = 6; +pub const DT_REG: _bindgen_ty_17 = 8; +pub const DT_LNK: _bindgen_ty_17 = 10; +pub const DT_SOCK: _bindgen_ty_17 = 12; +pub const DT_WHT: _bindgen_ty_17 = 14; +pub type _bindgen_ty_17 = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __dirstream { + pub _unused: [u8; 0], +} +pub type DIR = __dirstream; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct termios { + pub c_iflag: tcflag_t, + pub c_oflag: tcflag_t, + pub c_cflag: tcflag_t, + pub c_lflag: tcflag_t, + pub c_line: cc_t, + pub c_cc: [cc_t; 32usize], + pub c_ispeed: speed_t, + pub c_ospeed: speed_t, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub union wait { + pub w_status: ::std::os::raw::c_int, + pub w_T: wait__bindgen_ty_1, + pub w_S: wait__bindgen_ty_2, + _bindgen_union_align: u32, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct wait__bindgen_ty_1 { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u16>, + pub __bindgen_align: [u16; 0usize], +} +impl wait__bindgen_ty_1 { + #[inline] + pub fn w_Termsig(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u16) } + } + #[inline] + pub fn set_w_Termsig(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(0usize, 7u8, val as u64) + } + } + #[inline] + pub fn w_Coredump(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } + } + #[inline] + pub fn set_w_Coredump(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(7usize, 1u8, val as u64) + } + } + #[inline] + pub fn w_Retcode(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u16) } + } + #[inline] + pub fn set_w_Retcode(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn w_Fill1(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u16) } + } + #[inline] + pub fn set_w_Fill1(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(16usize, 16u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + w_Termsig: ::std::os::raw::c_ushort, + w_Coredump: ::std::os::raw::c_ushort, + w_Retcode: ::std::os::raw::c_ushort, + w_Fill1: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u16> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u16> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 7u8, { + let w_Termsig: u16 = unsafe { ::core::mem::transmute(w_Termsig) }; + w_Termsig as u64 + }); + __bindgen_bitfield_unit.set(7usize, 1u8, { + let w_Coredump: u16 = unsafe { ::core::mem::transmute(w_Coredump) }; + w_Coredump as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let w_Retcode: u16 = unsafe { ::core::mem::transmute(w_Retcode) }; + w_Retcode as u64 + }); + __bindgen_bitfield_unit.set(16usize, 16u8, { + let w_Fill1: u16 = unsafe { ::core::mem::transmute(w_Fill1) }; + w_Fill1 as u64 + }); + __bindgen_bitfield_unit + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct wait__bindgen_ty_2 { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize], u16>, + pub __bindgen_align: [u16; 0usize], +} +impl wait__bindgen_ty_2 { + #[inline] + pub fn w_Stopval(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u16) } + } + #[inline] + pub fn set_w_Stopval(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub fn w_Stopsig(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(8usize, 8u8) as u16) } + } + #[inline] + pub fn set_w_Stopsig(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(8usize, 8u8, val as u64) + } + } + #[inline] + pub fn w_Fill2(&self) -> ::std::os::raw::c_ushort { + unsafe { ::core::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u16) } + } + #[inline] + pub fn set_w_Fill2(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::core::mem::transmute(val); + self._bitfield_1.set(16usize, 16u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + w_Stopval: ::std::os::raw::c_ushort, + w_Stopsig: ::std::os::raw::c_ushort, + w_Fill2: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 4usize], u16> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize], u16> = + Default::default(); + __bindgen_bitfield_unit.set(0usize, 8u8, { + let w_Stopval: u16 = unsafe { ::core::mem::transmute(w_Stopval) }; + w_Stopval as u64 + }); + __bindgen_bitfield_unit.set(8usize, 8u8, { + let w_Stopsig: u16 = unsafe { ::core::mem::transmute(w_Stopsig) }; + w_Stopsig as u64 + }); + __bindgen_bitfield_unit.set(16usize, 16u8, { + let w_Fill2: u16 = unsafe { ::core::mem::transmute(w_Fill2) }; + w_Fill2 as u64 + }); + __bindgen_bitfield_unit + } +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sh_getopt_state { + pub gs_optarg: *mut ::std::os::raw::c_char, + pub gs_optind: ::std::os::raw::c_int, + pub gs_curopt: ::std::os::raw::c_int, + pub gs_nextchar: *mut ::std::os::raw::c_char, + pub gs_charindex: ::std::os::raw::c_int, + pub gs_flags: ::std::os::raw::c_int, +} +pub type sh_getopt_state_t = sh_getopt_state; + +pub type __builtin_va_list = [__va_list_tag; 1usize]; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __va_list_tag { + pub gp_offset: ::std::os::raw::c_uint, + pub fp_offset: ::std::os::raw::c_uint, + pub overflow_arg_area: *mut ::std::os::raw::c_void, + pub reg_save_area: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_data { + pub _address: u8, +} diff --git a/utshell-0.5.0/src/stringlib.rs b/utshell-0.5.0/src/stringlib.rs new file mode 100644 index 00000000..ea685d37 --- /dev/null +++ b/utshell-0.5.0/src/stringlib.rs @@ -0,0 +1,257 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::pathexp::quote_globbing_chars; +use crate::src_common::*; + +extern "C" { + fn strmatch(_: *mut libc::c_char, _: *mut libc::c_char, _: libc::c_int) -> libc::c_int; + fn glob_pattern_p(_: *const libc::c_char) -> libc::c_int; +} + +#[no_mangle] +pub fn find_string_in_alist( + mut string: *mut libc::c_char, + mut alist: *mut STRING_INT_ALIST, + mut flags: libc::c_int, +) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut r: libc::c_int = 0; + + r = 0; + i = r; + unsafe { + while !((*alist.offset(i as isize)).word).is_null() { + if flags != 0 { + r = (strmatch((*alist.offset(i as isize)).word, string, FNM_EXTMATCH!()) + != FNM_NOMATCH!()) as libc::c_int; + } else { + r = STREQ!(string, (*alist.offset(i as isize)).word) as libc::c_int; + } + if r != 0 { + return (*alist.offset(i as isize)).token; + } + i += 1; + } + } + return -(1 as libc::c_int); +} + +#[no_mangle] +pub fn find_token_in_alist( + mut token: libc::c_int, + mut alist: *mut STRING_INT_ALIST, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut i: libc::c_int = 0; + unsafe { + i = 0; + while !((*alist.offset(i as isize)).word).is_null() { + if (*alist.offset(i as isize)).token == token { + return savestring!((*alist.offset(i as isize)).word); + } + i += 1; + } + } + return 0 as *mut libc::c_char; +} + +#[no_mangle] +pub fn find_index_in_alist( + mut string: *mut libc::c_char, + mut alist: *mut STRING_INT_ALIST, + mut flags: libc::c_int, +) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut r: libc::c_int = 0; + unsafe { + r = 0; + i = r; + while !((*alist.offset(i as isize)).word).is_null() { + if flags != 0 { + r = (strmatch((*alist.offset(i as isize)).word, string, FNM_EXTMATCH!()) + != FNM_NOMATCH!()) as libc::c_int; + } else { + r = STREQ!(string, (*alist.offset(i as isize)).word) as libc::c_int; + } + if r != 0 { + return i; + } + i += 1; + } + } + return -(1 as libc::c_int); +} + +#[no_mangle] +pub fn substring( + mut string: *const libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut len: libc::c_int = 0; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + + len = end - start; + result = malloc((len + 1 as libc::c_int) as usize) as *mut libc::c_char; + memcpy( + result as *mut c_void, + string.offset(start as isize) as *const c_void, + len as usize, + ); + *result.offset(len as isize) = '\u{0}' as i32 as libc::c_char; + return result; + } +} + +#[no_mangle] +pub fn strsub( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut rep: *mut libc::c_char, + mut global: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut patlen: libc::c_int = 0; + let mut replen: libc::c_int = 0; + let mut templen: libc::c_int = 0; + let mut tempsize: libc::c_int = 0; + let mut repl: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + + patlen = strlen(pat) as libc::c_int; + replen = strlen(rep) as libc::c_int; + temp = 0 as *mut libc::c_char; + tempsize = 0; + templen = tempsize; + i = templen; + repl = 1; + while *string.offset(i as isize) != 0 { + if repl != 0 && STREQN!(string.offset(i as isize), pat, patlen) != 0 { + if replen != 0 { + RESIZE_MALLOCED_BUFFER!(temp, templen, replen, tempsize, (replen * 2)); + } + + r = rep; + while *r != 0 { + *temp.offset(templen as isize) = *r; + templen = templen + 1; + r = r.offset(1); + } + + i += if patlen != 0 { patlen } else { 1 }; + repl = (global != 0) as libc::c_int; + } else { + RESIZE_MALLOCED_BUFFER!(temp, templen, 1, tempsize, 16); + + *temp.offset(templen as isize) = *string.offset(i as isize); + templen = templen + 1; + i = i + 1; + } + } + + if !temp.is_null() { + *temp.offset(templen as isize) = 0 as libc::c_char; + } else { + temp = savestring!(string); + } + return temp; + } +} + +#[no_mangle] +pub fn strcreplace( + mut string: *mut libc::c_char, + mut c: libc::c_int, + mut text: *const libc::c_char, + mut do_glob: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: libc::c_int = 0; + let mut rlen: libc::c_int = 0; + let mut ind: libc::c_int = 0; + let mut tlen: libc::c_int = 0; + + len = STRLEN!(text); + rlen = len + strlen(string) as libc::c_int + 2; + ret = malloc(rlen as usize) as *mut libc::c_char; + + p = string; + r = ret; + while !p.is_null() && *p as libc::c_int != 0 { + if *p as libc::c_int == c { + if len != 0 { + ind = r.offset_from(ret) as libc::c_long as libc::c_int; + if do_glob != 0 + && (glob_pattern_p(text) != 0 || !(strchr(text, '\\' as i32)).is_null()) + { + t = quote_globbing_chars(text); + tlen = strlen(t) as libc::c_int; + RESIZE_MALLOCED_BUFFER!(ret, ind, tlen, rlen, rlen); + r = ret.offset(ind as isize); + strcpy(r, t); + r = r.offset(tlen as isize); + free(t as *mut c_void); + } else { + RESIZE_MALLOCED_BUFFER!(ret, ind, len, rlen, rlen); + r = ret.offset(ind as isize); + strcpy(r, text); + r = r.offset(len as isize); + } + } + p = p.offset(1); + } else { + if *p as libc::c_int == '\\' as i32 + && *p.offset(1 as libc::c_int as isize) as libc::c_int == c + { + p = p.offset(1); + } + ind = r.offset_from(ret) as libc::c_long as libc::c_int; + RESIZE_MALLOCED_BUFFER!(ret, ind, 2, rlen, rlen); + r = ret.offset(ind as isize); + + *r = *p; + r = r.offset(1); + p = p.offset(1); + } + } + *r = '\u{0}' as i32 as libc::c_char; + return ret; + } +} + +#[no_mangle] +pub fn strip_trailing( + mut string: *mut libc::c_char, + mut len: libc::c_int, + mut newlines_only: libc::c_int, +) { + unsafe { + while len >= 0 { + if newlines_only != 0 && *string.offset(len as isize) as libc::c_int == '\n' as i32 + || newlines_only == 0 && whitespace!(*string.offset(len as isize)) + { + len -= 1; + } else { + break; + } + } + *string.offset((len + 1 as libc::c_int) as isize) = '\u{0}' as i32 as libc::c_char; + } +} + +#[no_mangle] +pub fn xbcopy(mut s: *mut libc::c_char, mut d: *mut libc::c_char, mut n: libc::c_int) { + unsafe { + FASTCOPY!(s, d, n); + } +} diff --git a/utshell-0.5.0/src/subst.rs b/utshell-0.5.0/src/subst.rs new file mode 100644 index 00000000..542ef373 --- /dev/null +++ b/utshell-0.5.0/src/subst.rs @@ -0,0 +1,18429 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut, + unreachable_code, + non_snake_case, + unreachable_patterns, + unused_variables, + clashing_extern_declarations +)] +use crate::arrayfunc::assign_array_element; +use crate::arrayfunc::convert_var_to_array; +use crate::assoc::assoc_to_word_list; +use crate::jobs::cleanup_the_pipeline; +use crate::jobs::procsub_add; +use crate::make_cmd::make_bare_word; +use crate::readline::bash_tilde_expand; +use crate::readline::wcslen; +use crate::sig::reset_terminating_signals; +use crate::trap::reset_signal_handlers; +use crate::trap::restore_original_signals; +//use std::io::stdin; +extern "C" { + static mut stdin: *mut FILE; +} +use crate::array::array_to_string; +use crate::arrayfunc::array_expand_index; +use crate::arrayfunc::array_value; +use crate::arrayfunc::array_variable_part; +use crate::assoc::assoc_reference; +use crate::assoc::assoc_to_assign; +use crate::assoc::assoc_to_string; +use crate::builtins::set::set_shellopts; +use crate::dispose_cmd::dispose_word_desc; +use crate::error::err_badarraysub; +use crate::error::err_unboundvar; +use crate::jobs::wait_for; +use crate::readline::all_digits; +use crate::readline::array_modcase; +use crate::readline::array_patsub; +use crate::readline::array_reference; +use crate::readline::array_subrange; +use crate::sig::throw_to_top_level; +use crate::unwind_prot::add_unwind_protect; +use crate::unwind_prot::begin_unwind_frame; +use crate::unwind_prot::discard_unwind_frame; +use crate::variables::all_variables_matching_prefix; +use crate::variables::find_variable_last_nameref; +//use crate::builtins::common::number_of_args; +//use crate::flags::which_set_flags; +use crate::builtins::common::number_of_args; +use crate::expr::evalexp; +//use crate::builtins::common::number_of_args; +use crate::arrayfunc::array_keys; +use crate::arrayfunc::array_variable_name; +use crate::assoc::assoc_modcase; +use crate::assoc::assoc_patsub; +use crate::assoc::assoc_subrange; +use crate::assoc::assoc_to_kvpair; +use crate::builtins::setattr::var_attribute_string; +use crate::dispose_cmd::dispose_word; +use crate::flags::which_set_flags; +use crate::readline::array_to_assign; +use crate::readline::array_to_kvpair; +use crate::stringlib::strcreplace; +use crate::y_tab::decode_prompt_string; +//use crate::copycmd::copy_word_list; +use crate::execute_cmd::undo_partial_redirects; +use crate::pathexp::shell_glob_filename; +use crate::pathexp::unquoted_glob_pattern_p; +use crate::readline::bash_tilde_find_word; +use crate::sig::top_level_cleanup; +use crate::variables::set_pipestatus_from_exit; +//use crate::list::list_append; +use crate::arrayfunc::expand_and_quote_assoc_word; +use crate::arrayfunc::expand_and_quote_kvpair_word; +use crate::arrayfunc::kvpair_assignment_p; +use crate::arrayfunc::quote_compound_array_list; +use crate::brace::brace_expand; +use crate::builtins::common::find_shell_builtin; +use crate::builtins::common::find_special_builtin; +use crate::builtins::declare::declare_builtin; +use crate::copycmd::copy_word_list; +use crate::jobs::get_original_tty_job_signals; +use crate::make_cmd::make_word_flags; +use crate::variables::assign_in_env; +use crate::variables::find_function; +use crate::y_tab::parse_string_to_word_list; +//use crate::pathexp::quote_string_for_globbing; +use crate::arrayfunc::valid_array_reference; +use crate::builtins::evalfile::sourcelevel; +use crate::execute_cmd::close_fd_bitmap; +use crate::execute_cmd::setup_async_signals; +use crate::flags::change_flag; +use crate::general::{legal_identifier, legal_number}; +use crate::jobs::close_pgrp_pipe; +use crate::jobs::make_child; +use crate::jobs::procsub_clear; +use crate::jobs::restore_pipeline; +use crate::jobs::save_pipeline; +use crate::jobs::set_job_control; +use crate::jobs::set_sigchld_handler; +use crate::jobs::stop_making_children; +use crate::pathexp::quote_string_for_globbing; +use crate::readline::array_to_word_list; +use crate::readline::iswupper; +use crate::readline::move_to_high_fd; +use crate::readline::towlower; +use crate::readline::wcsdup; +use crate::readline::wcsrtombs; +use crate::sig::jump_to_top_level; +use crate::sig::termsig_handler; +use crate::src_common::*; +use crate::stringlib::strip_trailing; +use crate::stringlib::substring; +use crate::syntax::sh_syntaxtab; +use crate::trap::run_exit_trap; +use crate::trap::set_sigint_handler; +use crate::variables::flush_temporary_env; +use crate::variables::maybe_make_export_env; +use crate::y_tab::free_pushed_string_input; +//use crate::readline::__ctype_get_mb_cur_max; +use crate::arrayfunc::assign_array_from_string; +use crate::arrayfunc::assign_compound_array_list; +use crate::arrayfunc::convert_var_to_assoc; +use crate::arrayfunc::expand_compound_array_assignment; +use crate::dispose_cmd::dispose_words; +use crate::list::list_reverse; +use crate::make_cmd::alloc_word_desc; +use crate::make_cmd::make_word; +use crate::make_cmd::make_word_list; +use crate::print_cmd::xtrace_print_assignment; +use crate::readline::assignment; +use crate::readline::mbstowcs; +use crate::readline::mbtowc; +use crate::readline::wcschr; +use crate::variables::bind_variable; +use crate::variables::find_global_variable; +use crate::variables::find_variable; +use crate::variables::make_local_array_variable; +use crate::variables::make_local_assoc_variable; +use crate::variables::make_new_array_variable; +use crate::variables::make_new_assoc_variable; +use crate::variables::nameref_transform_name; +use crate::variables::stupidly_hack_special_variables; +use crate::version::shell_compatibility_level; +use crate::y_tab::xparse_dolparen; +#[feature(extern_types, linkage, register_tool)] +extern "C" { + fn list_append(_: *mut WordList, _: *mut WordList) -> *mut GENERIC_LIST; +} +#[inline] +fn is_basic(mut c: libc::c_char) -> libc::c_int { + unsafe { + return (*is_basic_table + .as_ptr() + .offset((c as libc::c_uchar as libc::c_int >> 5 as libc::c_int) as isize) + >> (c as libc::c_uchar as libc::c_int & 31 as libc::c_int) + & 1 as libc::c_int as libc::c_uint) as libc::c_int; + } +} +#[no_mangle] +//#[inline] +//#[linkage = "external"] +pub fn sub_append_string( + mut source: *mut libc::c_char, + mut target: *mut libc::c_char, + mut indx: *mut libc::c_int, + mut size: *mut size_t, +) -> *mut libc::c_char { + unsafe { + if !source.is_null() { + let mut n: libc::c_int = 0; + let mut srclen: size_t = 0; + srclen = if !source.is_null() + && *source.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *source.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *source.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(source) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + if srclen + >= (*size).wrapping_sub(*indx as libc::c_ulong) as libc::c_int as libc::c_ulong + { + n = srclen.wrapping_add(*indx as libc::c_ulong) as libc::c_int; + n = n + 128 as libc::c_int - n % 128 as libc::c_int; + *size = n as size_t; + target = sh_xrealloc( + target as *mut libc::c_void, + *size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 749 as libc::c_int, + ) as *mut libc::c_char; + } + libc::memcpy( + target.offset(*indx as isize) as *mut libc::c_void, + source as *const libc::c_void, + srclen as libc::size_t, + ); + *indx = (*indx as libc::c_ulong).wrapping_add(srclen) as libc::c_int as libc::c_int; + *target.offset(*indx as isize) = '\u{0}' as i32 as libc::c_char; + sh_xfree( + source as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 756 as libc::c_int, + ); + } + } + return target; +} +fn string_extract( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut charlist: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut c: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut found: libc::c_int = 0; + let mut slen: size_t = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as libc::c_ulong as usize, + ); + slen = if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + (strlen(string.offset(*sindex as isize))).wrapping_add(*sindex as u64) as u64 + } else { + 0 as libc::c_int as libc::c_ulong + }; + i = *sindex; + found = 0 as libc::c_int; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if c == '\\' as i32 { + if !(*string.offset((i + 1 as libc::c_int) as isize) != 0) { + break; + } + i += 1; + } else if flags & 0x2 as libc::c_int != 0 && c == '[' as i32 { + let mut ni: libc::c_int = 0; + ni = skipsubscript(string, i, 0 as libc::c_int); + if *string.offset(ni as isize) as libc::c_int == ']' as i32 { + i = ni; + } + } else if c != 0 + && c == *charlist.offset(0 as libc::c_int as isize) as libc::c_int + && *charlist.offset(1 as libc::c_int as isize) == 0 + || (if c != 0 { + (mbschr(charlist, c) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + found = 1 as libc::c_int; + break; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + if flags & 0x4 as libc::c_int != 0 && found == 0 as libc::c_int { + *sindex = i; + return &mut extract_string_error; + } + temp = if flags & 0x1 as libc::c_int != 0 { + 0 as *mut libc::c_void as *mut libc::c_char + } else { + substring(string, *sindex, i) + }; + *sindex = i; + + return temp; + } +} +fn string_extract_double_quoted( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut slen: size_t = 0; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + let mut j: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut t: libc::c_int = 0; + let mut c: libc::c_uchar = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pass_next: libc::c_int = 0; + let mut backquote: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut dquote: libc::c_int = 0; + let mut stripdq: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = (strlen(string.offset(*sindex as isize))).wrapping_add(*sindex as u64) as u64; + send = string.offset(slen as isize); + stripdq = flags & 0x800 as libc::c_int; + dquote = 0 as libc::c_int; + backquote = dquote; + pass_next = backquote; + temp = sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(slen) + .wrapping_sub(*sindex as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 874 as libc::c_int, + ) as *mut libc::c_char; + j = 0 as libc::c_int; + i = *sindex; + loop { + c = *string.offset(i as isize) as libc::c_uchar; + if !(c != 0) { + break; + } + if pass_next != 0 { + if stripdq == 0 as libc::c_int && c as libc::c_int != '"' as i32 + || stripdq != 0 + && (dquote != 0 + && *sh_syntaxtab.as_mut_ptr().offset(c as isize) & 0x40 as libc::c_int + != 0 + || dquote == 0 as libc::c_int) + { + let fresh0 = j; + j = j + 1; + *temp.offset(fresh0 as isize) = '\\' as i32 as libc::c_char; + } + pass_next = 0 as libc::c_int; + } else if c as libc::c_int == '\\' as i32 { + pass_next += 1; + i += 1; + continue; + } else if backquote != 0 { + if c as libc::c_int == '`' as i32 { + backquote = 0 as libc::c_int; + } + let fresh5 = j; + j = j + 1; + *temp.offset(fresh5 as isize) = c as libc::c_char; + i += 1; + continue; + } else if c as libc::c_int == '`' as i32 { + let fresh6 = j; + j = j + 1; + *temp.offset(fresh6 as isize) = c as libc::c_char; + backquote += 1; + i += 1; + continue; + } else if c as libc::c_int == '$' as i32 + && (*string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + || *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '{' as i32) + { + let mut free_ret: libc::c_int = 1 as libc::c_int; + si = i + 2 as libc::c_int; + if *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 { + ret = extract_command_subst(string, &mut si, flags & 0x400 as libc::c_int); + } else { + ret = extract_dollar_brace_string( + string, + &mut si, + 0x1 as libc::c_int, + 0 as libc::c_int, + ); + } + let fresh7 = j; + j = j + 1; + *temp.offset(fresh7 as isize) = '$' as i32 as libc::c_char; + let fresh8 = j; + j = j + 1; + *temp.offset(fresh8 as isize) = *string.offset((i + 1 as libc::c_int) as isize); + if ret.is_null() && no_longjmp_on_fatal_error != 0 { + free_ret = 0 as libc::c_int; + ret = string.offset(i as isize).offset(2 as libc::c_int as isize); + } + t = 0 as libc::c_int; + while *ret.offset(t as isize) != 0 { + *temp.offset(j as isize) = *ret.offset(t as isize); + t += 1; + j += 1; + } + *temp.offset(j as isize) = *string.offset(si as isize); + if si < i + 2 as libc::c_int { + i += 2 as libc::c_int; + } else if *string.offset(si as isize) != 0 { + j += 1; + i = si + 1 as libc::c_int; + } else { + i = si; + } + if free_ret != 0 { + sh_xfree( + ret as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 986 as libc::c_int, + ); + } + continue; + } else if !(c as libc::c_int != '"' as i32) { + if !(stripdq != 0) { + break; + } + dquote ^= 1 as libc::c_int; + i += 1; + continue; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*string.offset(i as isize)); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + send.offset_from(string.offset(i as isize)) as libc::c_long as size_t, + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh1 = i; + i = i + 1; + let fresh2 = j; + j = j + 1; + *temp.offset(fresh2 as isize) = *string.offset(fresh1 as isize); + _k += 1; + } + } else { + let fresh3 = i; + i = i + 1; + let fresh4 = j; + j = j + 1; + *temp.offset(fresh4 as isize) = *string.offset(fresh3 as isize); + } + } + *temp.offset(j as isize) = '\u{0}' as i32 as libc::c_char; + if c != 0 { + i += 1; + } + *sindex = i; + + return temp; + } +} +fn skip_double_quoted( + mut string: *mut libc::c_char, + mut slen: size_t, + mut sind: libc::c_int, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut c: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pass_next: libc::c_int = 0; + let mut backquote: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + backquote = 0 as libc::c_int; + pass_next = backquote; + i = sind; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if pass_next != 0 { + pass_next = 0 as libc::c_int; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '\\' as i32 { + pass_next += 1; + i += 1; + } else if backquote != 0 { + if c == '`' as i32 { + backquote = 0 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '`' as i32 { + backquote += 1; + i += 1; + } else if c == '$' as i32 + && (*string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + || *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '{' as i32) + { + si = i + 2 as libc::c_int; + if *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 { + ret = extract_command_subst( + string, + &mut si, + 0x1 as libc::c_int | flags & 0x400 as libc::c_int, + ); + } else { + ret = extract_dollar_brace_string( + string, + &mut si, + 0x1 as libc::c_int, + 0x1 as libc::c_int, + ); + } + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else { + if !(c != '"' as i32) { + break; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _f_1: libc::c_int = 0; + _f_1 = is_basic(*string.offset(i as isize)); + if _f_1 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_1 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + i += 1; + } else if mblength_1 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_1) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + if c != 0 { + i += 1; + } + + return i; + } +} +#[inline] +fn string_extract_single_quoted( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut i: libc::c_int = 0; + let mut slen: size_t = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + (strlen(string.offset(*sindex as isize))).wrapping_add(*sindex as libc::c_ulong as u64) + as u64 + } else { + 0 as libc::c_int as libc::c_ulong + }; + i = *sindex; + while *string.offset(i as isize) as libc::c_int != 0 + && *string.offset(i as isize) as libc::c_int != '\'' as i32 + { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + t = substring(string, *sindex, i); + if *string.offset(i as isize) != 0 { + i += 1; + } + *sindex = i; + + return t; + } +} +#[inline] +fn skip_single_quoted( + mut string: *const libc::c_char, + mut slen: size_t, + mut sind: libc::c_int, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut c: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + c = sind; + while *string.offset(c as isize) as libc::c_int != 0 + && *string.offset(c as isize) as libc::c_int != '\'' as i32 + { + if flags & 0x400 as libc::c_int != 0 + && *string.offset(c as isize) as libc::c_int == '\\' as i32 + && *string.offset((c + 1 as libc::c_int) as isize) as libc::c_int == '\'' as i32 + && *string.offset((c + 2 as libc::c_int) as isize) as libc::c_int != 0 + { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(c as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(c as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(c as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(c as isize), + slen.wrapping_sub(c as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + c += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + c += 1; + } else { + c = (c as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + c += 1; + } + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(c as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(c as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(c as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(c as isize), + slen.wrapping_sub(c as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + c += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + c += 1; + } else { + c = (c as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int as libc::c_int; + } + } else { + c += 1; + } + } + if *string.offset(c as isize) != 0 { + c += 1; + } + + return c; + } +} +fn string_extract_verbatim( + mut string: *mut libc::c_char, + mut slen: size_t, + mut sindex: *mut libc::c_int, + mut charlist: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut i: libc::c_int = 0; + let mut wcharlist: *mut wchar_t = 0 as *mut wchar_t; + let mut c: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if flags & 0x10 as libc::c_int != 0 + && *charlist.offset(0 as libc::c_int as isize) as libc::c_int == '\'' as i32 + && *charlist.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + temp = string_extract_single_quoted(string, sindex); + *sindex -= 1; + return temp; + } + if *charlist as libc::c_int == 0 as libc::c_int { + temp = string.offset(*sindex as isize); + c = (if *sindex == 0 as libc::c_int { + slen as usize + } else if !temp.is_null() && *temp.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *temp.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *temp.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(temp) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + temp = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(temp) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 1173 as libc::c_int, + ) as *mut libc::c_char, + temp, + ); + *sindex += c; + return temp; + } + i = *sindex; + wcharlist = 0 as *mut wchar_t; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + let mut mblength: size_t = 0; + if flags & 0x10 as libc::c_int == 0 as libc::c_int && c == '\u{1}' as i32 { + i += 2 as libc::c_int; + if !(i as libc::c_ulong >= slen) { + continue; + } + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else if flags & 0x20 as libc::c_int == 0 as libc::c_int + && c == '\u{1}' as i32 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '\u{7f}' as i32 + { + i += 2 as libc::c_int; + if !(i as libc::c_ulong >= slen) { + continue; + } + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + if locale_utf8locale != 0 + && slen > i as libc::c_ulong + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (if *string.offset(i as isize) as libc::c_int != 0 as libc::c_int { + 1 as libc::c_int + } else { + 0 as libc::c_int + }) as size_t; + } else { + mblength = (if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + mblen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + ) + } else { + 1 as libc::c_int + }) as size_t; + } + if mblength > 1 as libc::c_int as libc::c_ulong { + let mut wc: wchar_t = 0; + mblength = mbtowc( + &mut wc, + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong) as usize, + ) as size_t; + if mblength == -(1 as libc::c_int) as size_t + || mblength == -(2 as libc::c_int) as size_t + { + if c != 0 + && c == *charlist.offset(0 as libc::c_int as isize) as libc::c_int + && *charlist.offset(1 as libc::c_int as isize) == 0 + || (if c != 0 { + (mbschr(charlist, c) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + break; + } + } else { + if wcharlist.is_null() { + let mut len: size_t = 0; + len = mbstowcs(wcharlist, charlist, 0 as libc::c_int as usize) as u64; + if len == -(1 as libc::c_int) as libc::c_ulong { + len = 0 as libc::c_int as size_t; + } + wcharlist = sh_xmalloc( + (::std::mem::size_of::() as libc::c_ulong).wrapping_mul( + len.wrapping_add(1 as libc::c_int as libc::c_ulong), + ), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 1225 as libc::c_int, + ) as *mut wchar_t; + mbstowcs( + wcharlist, + charlist, + len.wrapping_add(1 as libc::c_int as libc::c_ulong) as usize, + ); + } + if !(wcschr(wcharlist, wc)).is_null() { + break; + } + } + } else if c != 0 + && c == *charlist.offset(0 as libc::c_int as isize) as libc::c_int + && *charlist.offset(1 as libc::c_int as isize) == 0 + || (if c != 0 { + (mbschr(charlist, c) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + break; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + if !wcharlist.is_null() { + sh_xfree( + wcharlist as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 1242 as libc::c_int, + ); + } + temp = substring(string, *sindex, i); + *sindex = i; + + return temp; + } +} +#[no_mangle] +pub fn extract_command_subst( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut xflags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + if *string.offset(*sindex as isize) as libc::c_int == '(' as i32 + || xflags & 0x400 as libc::c_int != 0 + { + return extract_delimited_string( + string, + sindex, + b"$(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + xflags | 0x8 as libc::c_int, + ); + } else { + xflags |= if no_longjmp_on_fatal_error != 0 { + 0x40 as libc::c_int + } else { + 0 as libc::c_int + }; + ret = xparse_dolparen(string, string.offset(*sindex as isize), sindex, xflags); + return ret; + }; + } +} +#[no_mangle] +pub fn extract_arithmetic_subst( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, +) -> *mut libc::c_char { + return extract_delimited_string( + string, + sindex, + b"$[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"]\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as libc::c_int, + ); +} +#[no_mangle] +pub fn extract_process_subst( + mut string: *mut libc::c_char, + mut starter: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut xflags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + xflags |= if no_longjmp_on_fatal_error != 0 { + 0x40 as libc::c_int + } else { + 0 as libc::c_int + }; + return xparse_dolparen(string, string.offset(*sindex as isize), sindex, xflags); + } +} +#[no_mangle] +pub fn extract_array_assignment_list( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut slen: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + slen = strlen(string) as libc::c_int; + if *string.offset((slen - 1 as libc::c_int) as isize) as libc::c_int == ')' as i32 { + ret = substring(string, *sindex, slen - 1 as libc::c_int); + *sindex = slen - 1 as libc::c_int; + return ret; + } + } + return 0 as *mut libc::c_char; +} +fn extract_delimited_string( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut opener: *mut libc::c_char, + mut alt_opener: *mut libc::c_char, + mut closer: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut slen: size_t = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pass_character: libc::c_int = 0; + let mut nesting_level: libc::c_int = 0; + let mut in_comment: libc::c_int = 0; + let mut len_closer: libc::c_int = 0; + let mut len_opener: libc::c_int = 0; + let mut len_alt_opener: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = (strlen(string.offset(*sindex as isize))).wrapping_add(*sindex as u64) as u64; + len_opener = (if !opener.is_null() + && *opener.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *opener.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *opener.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(opener) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + len_alt_opener = (if !alt_opener.is_null() + && *alt_opener.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *alt_opener.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *alt_opener.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(alt_opener) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + len_closer = (if !closer.is_null() + && *closer.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *closer.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *closer.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(closer) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + in_comment = 0 as libc::c_int; + pass_character = in_comment; + nesting_level = 1 as libc::c_int; + i = *sindex; + while nesting_level != 0 { + c = *string.offset(i as isize) as libc::c_int; + if i as libc::c_ulong > slen { + i = slen as libc::c_int; + i = slen as libc::c_int; + c = *string.offset(i as isize) as libc::c_int; + break; + } else { + if c == 0 as libc::c_int { + break; + } + if in_comment != 0 { + if c == '\n' as i32 { + in_comment = 0 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if pass_character != 0 { + pass_character = 0 as libc::c_int; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if flags & 0x8 as libc::c_int != 0 + && c == '#' as i32 + && (i == 0 as libc::c_int + || *string.offset((i - 1 as libc::c_int) as isize) as libc::c_int + == '\n' as i32 + || *sh_syntaxtab.as_mut_ptr().offset( + *string.offset((i - 1 as libc::c_int) as isize) as libc::c_uchar + as isize, + ) & 0x2000 as libc::c_int + != 0) + { + in_comment = 1 as libc::c_int; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _f_1: libc::c_int = 0; + _f_1 = is_basic(*string.offset(i as isize)); + if _f_1 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_1 = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + i += 1; + } else if mblength_1 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_1) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '\u{1}' as i32 || c == '\\' as i32 { + pass_character += 1; + i += 1; + } else if flags & 0x8 as libc::c_int != 0 + && *string.offset(i as isize) as libc::c_int == '$' as i32 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + { + si = i + 2 as libc::c_int; + t = extract_command_subst(string, &mut si, flags | 0x1 as libc::c_int); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else if if len_opener == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*string.offset(i as isize).offset(0 as libc::c_int as isize) as libc::c_int + == *opener.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp(string.offset(i as isize), opener, len_opener as usize) + == 0 as libc::c_int) as libc::c_int + } != 0 + { + si = i + len_opener; + t = extract_delimited_string( + string, + &mut si, + opener, + alt_opener, + closer, + flags | 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else if len_alt_opener != 0 + && (if len_alt_opener == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*string.offset(i as isize).offset(0 as libc::c_int as isize) + as libc::c_int + == *alt_opener.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp( + string.offset(i as isize), + alt_opener, + len_alt_opener as usize, + ) == 0 as libc::c_int) as libc::c_int + }) != 0 + { + si = i + len_alt_opener; + t = extract_delimited_string( + string, + &mut si, + alt_opener, + alt_opener, + closer, + flags | 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else { + if if len_closer == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*string.offset(i as isize).offset(0 as libc::c_int as isize) + as libc::c_int + == *closer.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp(string.offset(i as isize), closer, len_closer as usize) + == 0 as libc::c_int) as libc::c_int + } != 0 + { + i += len_closer - 1 as libc::c_int; + nesting_level -= 1; + if nesting_level == 0 as libc::c_int { + break; + } + } + if c == '`' as i32 { + si = i + 1 as libc::c_int; + t = string_extract( + string, + &mut si, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + flags | 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else if c == '\'' as i32 || c == '"' as i32 { + si = i + 1 as libc::c_int; + i = if c == '\'' as i32 { + skip_single_quoted(string, slen, si, 0 as libc::c_int) + } else { + skip_double_quoted(string, slen, si, 0 as libc::c_int) + }; + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_2: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_2: size_t = 0; + let mut _f_2: libc::c_int = 0; + _f_2 = is_basic(*string.offset(i as isize)); + if _f_2 != 0 { + mblength_2 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_2 = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_2 = state; + mblength_2 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_2 == -(2 as libc::c_int) as size_t + || mblength_2 == -(1 as libc::c_int) as size_t + { + state = state_bak_2; + i += 1; + } else if mblength_2 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_2) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + } + if c == 0 as libc::c_int && nesting_level != 0 { + if no_longjmp_on_fatal_error == 0 as libc::c_int { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"bad substitution: no closing `%s' in %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + closer, + string, + ); + exp_jump_to_top_level(2 as libc::c_int); + } else { + *sindex = i; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + } + si = i - *sindex - len_closer + 1 as libc::c_int; + if flags & 0x1 as libc::c_int != 0 { + result = 0 as *mut libc::c_void as *mut libc::c_char; + } else { + result = sh_xmalloc( + (1 as libc::c_int + si) as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 1491 as libc::c_int, + ) as *mut libc::c_char; + strncpy(result, string.offset(*sindex as isize), si as usize); + *result.offset(si as isize) = '\u{0}' as i32 as libc::c_char; + } + *sindex = i; + + return result; + } +} +fn extract_dollar_brace_string( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut quoted: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut slen: size_t = 0; + let mut pass_character: libc::c_int = 0; + let mut nesting_level: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut dolbrace_state: libc::c_int = 0; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + pass_character = 0 as libc::c_int; + nesting_level = 1 as libc::c_int; + slen = (strlen(string.offset(*sindex as isize))).wrapping_add(*sindex as u64) as u64; + dolbrace_state = if flags & 0x200 as libc::c_int != 0 { + 0x4 as libc::c_int + } else { + 0x1 as libc::c_int + }; + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && flags & 0x100 as libc::c_int != 0 + { + dolbrace_state = 0x40 as libc::c_int; + } + i = *sindex; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if pass_character != 0 { + pass_character = 0 as libc::c_int; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '\u{1}' as i32 || c == '\\' as i32 { + pass_character += 1; + i += 1; + } else if *string.offset(i as isize) as libc::c_int == '$' as i32 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '{' as i32 + { + nesting_level += 1; + i += 2 as libc::c_int; + } else if c == '}' as i32 { + nesting_level -= 1; + if nesting_level == 0 as libc::c_int { + break; + } + i += 1; + } else if c == '`' as i32 { + si = i + 1 as libc::c_int; + t = string_extract( + string, + &mut si, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + flags | 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else if *string.offset(i as isize) as libc::c_int == '$' as i32 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + { + si = i + 2 as libc::c_int; + t = extract_command_subst(string, &mut si, flags | 0x1 as libc::c_int); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else if (*string.offset(i as isize) as libc::c_int == '<' as i32 + || *string.offset(i as isize) as libc::c_int == '>' as i32) + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + { + si = i + 2 as libc::c_int; + t = extract_process_subst( + string, + (if *string.offset(i as isize) as libc::c_int == '<' as i32 { + b"<(\0" as *const u8 as *const libc::c_char + } else { + b">)\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char, + &mut si, + flags | 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si + 1 as libc::c_int; + } + } else if c == '"' as i32 { + si = i + 1 as libc::c_int; + i = skip_double_quoted(string, slen, si, 0 as libc::c_int); + } else if c == '\'' as i32 { + if posixly_correct != 0 + && shell_compatibility_level > 42 as libc::c_int + && dolbrace_state != 0x40 as libc::c_int + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else { + si = i + 1 as libc::c_int; + i = skip_single_quoted(string, slen, si, 0 as libc::c_int); + } + } else { + if c == '[' as i32 && dolbrace_state == 0x1 as libc::c_int { + si = skipsubscript(string, i, 0 as libc::c_int); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else if *string.offset(si as isize) as libc::c_int == ']' as i32 { + i = si; + c = *string.offset(i as isize) as libc::c_int; + } + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _f_1: libc::c_int = 0; + _f_1 = is_basic(*string.offset(i as isize)); + if _f_1 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_1 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + i += 1; + } else if mblength_1 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_1) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + if dolbrace_state == 0x1 as libc::c_int + && c == '%' as i32 + && i - *sindex > 1 as libc::c_int + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && c == '#' as i32 + && i - *sindex > 1 as libc::c_int + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && c == '/' as i32 + && i - *sindex > 1 as libc::c_int + { + dolbrace_state = 0x80 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && c == '^' as i32 + && i - *sindex > 1 as libc::c_int + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && c == ',' as i32 + && i - *sindex > 1 as libc::c_int + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && !(strchr(b"#%^,~:-=?+/\0" as *const u8 as *const libc::c_char, c)).is_null() + { + dolbrace_state = 0x2 as libc::c_int; + } else if dolbrace_state == 0x2 as libc::c_int + && (strchr(b"#%^,~:-=?+/\0" as *const u8 as *const libc::c_char, c)).is_null() + { + dolbrace_state = 0x4 as libc::c_int; + } + } + } + if c == 0 as libc::c_int && nesting_level != 0 { + if no_longjmp_on_fatal_error == 0 as libc::c_int { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"bad substitution: no closing `%s' in %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + b"}\0" as *const u8 as *const libc::c_char, + string, + ); + exp_jump_to_top_level(2 as libc::c_int); + } else { + *sindex = i; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + } + result = if flags & 0x1 as libc::c_int != 0 { + 0 as *mut libc::c_void as *mut libc::c_char + } else { + substring(string, *sindex, i) + }; + *sindex = i; + + return result; + } +} +#[no_mangle] +pub fn de_backslash(mut string: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut slen: size_t = 0; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut prev_i: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + j = 0 as libc::c_int; + i = j; + while (i as libc::c_ulong) < slen { + if *string.offset(i as isize) as libc::c_int == '\\' as i32 + && (*string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '`' as i32 + || *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '\\' as i32 + || *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '$' as i32) + { + i += 1; + } + prev_i = i; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + if j < prev_i { + loop { + let fresh9 = prev_i; + prev_i = prev_i + 1; + let fresh10 = j; + j = j + 1; + *string.offset(fresh10 as isize) = *string.offset(fresh9 as isize); + if !(prev_i < i) { + break; + } + } + } else { + j = i; + } + } + *string.offset(j as isize) = '\u{0}' as i32 as libc::c_char; + } + return string; +} +fn skip_matched_pair( + mut string: *const libc::c_char, + mut start: libc::c_int, + mut open: libc::c_int, + mut close_0: libc::c_int, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut backq: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut count: libc::c_int = 0; + let mut oldjmp: libc::c_int = 0; + let mut slen: size_t = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ss: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = (strlen(string.offset(start as isize))).wrapping_add(start as u64) as u64; + oldjmp = no_longjmp_on_fatal_error; + no_longjmp_on_fatal_error = 1 as libc::c_int; + i = start + 1 as libc::c_int; + count = 1 as libc::c_int; + backq = 0 as libc::c_int; + pass_next = backq; + ss = string as *mut libc::c_char; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if pass_next != 0 { + pass_next = 0 as libc::c_int; + if c == 0 as libc::c_int { + no_longjmp_on_fatal_error = oldjmp; + return i; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if flags & 1 as libc::c_int == 0 as libc::c_int && c == '\\' as i32 { + pass_next = 1 as libc::c_int; + i += 1; + } else if backq != 0 { + if c == '`' as i32 { + backq = 0 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if flags & 1 as libc::c_int == 0 as libc::c_int && c == '`' as i32 { + backq = 1 as libc::c_int; + i += 1; + } else if flags & 1 as libc::c_int == 0 as libc::c_int && c == open { + count += 1; + i += 1; + } else if c == close_0 { + count -= 1; + if count == 0 as libc::c_int { + break; + } + i += 1; + } else if flags & 1 as libc::c_int == 0 as libc::c_int + && (c == '\'' as i32 || c == '"' as i32) + { + i = if c == '\'' as i32 { + i += 1; + skip_single_quoted(ss, slen, i, 0 as libc::c_int) + } else { + i += 1; + skip_double_quoted(ss, slen, i, 0 as libc::c_int) + }; + } else if flags & 1 as libc::c_int == 0 as libc::c_int + && c == '$' as i32 + && (*string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + || *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '{' as i32) + { + si = i + 2 as libc::c_int; + if *string.offset(si as isize) as libc::c_int == '\u{0}' as i32 { + no_longjmp_on_fatal_error = oldjmp; + return si; + } + if *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 { + temp = extract_delimited_string( + ss, + &mut si, + b"$(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int | 0x8 as libc::c_int, + ); + } else { + temp = extract_dollar_brace_string( + ss, + &mut si, + 0 as libc::c_int, + 0x1 as libc::c_int, + ); + } + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si; + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } + i += 1; + } + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _f_1: libc::c_int = 0; + _f_1 = is_basic(*string.offset(i as isize)); + if _f_1 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_1 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + i += 1; + } else if mblength_1 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_1) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + no_longjmp_on_fatal_error = oldjmp; + + return i; + } +} +#[no_mangle] +pub fn skipsubscript( + mut string: *const libc::c_char, + mut start: libc::c_int, + mut flags: libc::c_int, +) -> libc::c_int { + return skip_matched_pair(string, start, '[' as i32, ']' as i32, flags); +} +#[no_mangle] +pub fn skip_to_delim( + mut string: *mut libc::c_char, + mut start: libc::c_int, + mut delims: *mut libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut backq: libc::c_int = 0; + let mut dquote: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut oldjmp: libc::c_int = 0; + let mut invert: libc::c_int = 0; + let mut skipquote: libc::c_int = 0; + let mut skipcmd: libc::c_int = 0; + let mut noprocsub: libc::c_int = 0; + let mut completeflag: libc::c_int = 0; + let mut arithexp: libc::c_int = 0; + let mut skipcol: libc::c_int = 0; + let mut slen: size_t = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut open: [libc::c_char; 3] = [0; 3]; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = (strlen(string.offset(start as isize))).wrapping_add(start as u64) as u64; + oldjmp = no_longjmp_on_fatal_error; + if flags & 0x1 as libc::c_int != 0 { + no_longjmp_on_fatal_error = 1 as libc::c_int; + } + invert = flags & 0x2 as libc::c_int; + skipcmd = (flags & 0x8 as libc::c_int == 0 as libc::c_int) as libc::c_int; + noprocsub = flags & 0x80 as libc::c_int; + completeflag = if flags & 0x100 as libc::c_int != 0 { + 0x400 as libc::c_int + } else { + 0 as libc::c_int + }; + arithexp = flags & 0x400 as libc::c_int; + skipcol = 0 as libc::c_int; + i = start; + dquote = 0 as libc::c_int; + backq = dquote; + pass_next = backq; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + skipquote = (flags & 0x4 as libc::c_int != 0 && (c == '\'' as i32 || c == '"' as i32)) + as libc::c_int; + if pass_next != 0 { + pass_next = 0 as libc::c_int; + if c == 0 as libc::c_int { + no_longjmp_on_fatal_error = oldjmp; + return i; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '\\' as i32 { + pass_next = 1 as libc::c_int; + i += 1; + } else if backq != 0 { + if c == '`' as i32 { + backq = 0 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '`' as i32 { + backq = 1 as libc::c_int; + i += 1; + } else if arithexp != 0 && skipcol != 0 && c == ':' as i32 { + skipcol -= 1; + i += 1; + } else if arithexp != 0 && c == '?' as i32 { + skipcol += 1; + i += 1; + } else { + if skipquote == 0 as libc::c_int + && invert == 0 as libc::c_int + && (if c != 0 { + (mbschr(delims, c) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + break; + } + if completeflag != 0 + && i > 0 as libc::c_int + && *string.offset((i - 1 as libc::c_int) as isize) as libc::c_int == '$' as i32 + && c == '\'' as i32 + { + i += 1; + i = skip_single_quoted(string, slen, i, 0x400 as libc::c_int); + } else if c == '\'' as i32 { + i += 1; + i = skip_single_quoted(string, slen, i, 0 as libc::c_int); + } else if c == '"' as i32 { + i += 1; + i = skip_double_quoted(string, slen, i, completeflag); + } else if c == '(' as i32 && arithexp != 0 { + si = i + 1 as libc::c_int; + if *string.offset(si as isize) as libc::c_int == '\u{0}' as i32 { + no_longjmp_on_fatal_error = oldjmp; + return si; + } + temp = extract_delimited_string( + string, + &mut si, + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + i = si; + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } else { + i += 1; + } + } else if c == '$' as i32 + && (skipcmd != 0 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '(' as i32 + || *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '{' as i32) + { + si = i + 2 as libc::c_int; + if *string.offset(si as isize) as libc::c_int == '\u{0}' as i32 { + no_longjmp_on_fatal_error = oldjmp; + return si; + } + if *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + { + temp = extract_delimited_string( + string, + &mut si, + b"$(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int | 0x8 as libc::c_int, + ); + } else { + temp = extract_dollar_brace_string( + string, + &mut si, + 0 as libc::c_int, + 0x1 as libc::c_int, + ); + } + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si; + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } else { + i += 1; + } + } + } else if skipcmd != 0 + && noprocsub == 0 as libc::c_int + && (c == '<' as i32 || c == '>' as i32) + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + { + si = i + 2 as libc::c_int; + if *string.offset(si as isize) as libc::c_int == '\u{0}' as i32 { + no_longjmp_on_fatal_error = oldjmp; + return si; + } + temp = extract_delimited_string( + string, + &mut si, + (if c == '<' as i32 { + b"<(\0" as *const u8 as *const libc::c_char + } else { + b">(\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char, + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x8 as libc::c_int | 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si; + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } + i += 1; + } + } else if flags & 0x10 as libc::c_int != 0 + && extended_glob != 0 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + && (if c != 0 { + (mbschr(b"?*+!@\0" as *const u8 as *const libc::c_char, c) + != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + si = i + 2 as libc::c_int; + if *string.offset(si as isize) as libc::c_int == '\u{0}' as i32 { + no_longjmp_on_fatal_error = oldjmp; + return si; + } + open[0 as libc::c_int as usize] = c as libc::c_char; + open[1 as libc::c_int as usize] = '(' as i32 as libc::c_char; + open[2 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + temp = extract_delimited_string( + string, + &mut si, + open.as_mut_ptr(), + b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + if si as libc::c_ulong >= slen { + i = slen as libc::c_int; + c = 0 as libc::c_int; + break; + } else { + i = si; + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } else { + i += 1; + } + } + } else if flags & 0x40 as libc::c_int != 0 && c == '[' as i32 { + si = i + 1 as libc::c_int; + if *string.offset(si as isize) as libc::c_int == '\u{0}' as i32 { + no_longjmp_on_fatal_error = oldjmp; + return si; + } + temp = extract_delimited_string( + string, + &mut si, + b"[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"]\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x1 as libc::c_int, + ); + i = si; + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + break; + } + i += 1; + } else { + if (skipquote != 0 || invert != 0) + && (if c != 0 { + (mbschr(delims, c) != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) == 0 as libc::c_int + { + break; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _f_1: libc::c_int = 0; + _f_1 = is_basic(*string.offset(i as isize)); + if _f_1 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_1 = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + i += 1; + } else if mblength_1 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_1) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + } + no_longjmp_on_fatal_error = oldjmp; + + return i; + } +} +#[no_mangle] +pub fn skip_to_histexp( + mut string: *mut libc::c_char, + mut start: libc::c_int, + mut delims: *mut libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut backq: libc::c_int = 0; + let mut dquote: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut oldjmp: libc::c_int = 0; + let mut histexp_comsub: libc::c_int = 0; + let mut histexp_backq: libc::c_int = 0; + let mut old_dquote: libc::c_int = 0; + let mut slen: size_t = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = (strlen(string.offset(start as isize))).wrapping_add(start as u64) as u64; + oldjmp = no_longjmp_on_fatal_error; + if flags & 0x1 as libc::c_int != 0 { + no_longjmp_on_fatal_error = 1 as libc::c_int; + } + old_dquote = 0 as libc::c_int; + histexp_backq = old_dquote; + histexp_comsub = histexp_backq; + i = start; + dquote = 0 as libc::c_int; + backq = dquote; + pass_next = backq; + loop { + c = *string.offset(i as isize) as libc::c_int; + if !(c != 0) { + break; + } + if pass_next != 0 { + pass_next = 0 as libc::c_int; + if c == 0 as libc::c_int { + no_longjmp_on_fatal_error = oldjmp; + return i; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '\\' as i32 { + pass_next = 1 as libc::c_int; + i += 1; + } else if backq != 0 && c == '`' as i32 { + backq = 0 as libc::c_int; + histexp_backq -= 1; + dquote = old_dquote; + i += 1; + } else if c == '`' as i32 { + backq = 1 as libc::c_int; + histexp_backq += 1; + old_dquote = dquote; + dquote = 0 as libc::c_int; + i += 1; + } else if dquote != 0 + && c == *delims.offset(0 as libc::c_int as isize) as libc::c_int + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '"' as i32 + { + i += 1; + } else { + if c == *delims.offset(0 as libc::c_int as isize) as libc::c_int { + break; + } + if dquote != 0 && c == '\'' as i32 { + i += 1; + } else if c == '\'' as i32 { + i += 1; + i = skip_single_quoted(string, slen, i, 0 as libc::c_int); + } else if posixly_correct == 0 as libc::c_int && c == '"' as i32 { + dquote = 1 as libc::c_int - dquote; + i += 1; + } else if c == '"' as i32 { + i += 1; + i = skip_double_quoted(string, slen, i, 0 as libc::c_int); + } else if (c == '$' as i32 || c == '<' as i32 || c == '>' as i32) + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + && *string.offset((i + 2 as libc::c_int) as isize) as libc::c_int != '(' as i32 + { + if *string.offset((i + 2 as libc::c_int) as isize) as libc::c_int + == '\u{0}' as i32 + { + no_longjmp_on_fatal_error = oldjmp; + return i + 2 as libc::c_int; + } + i += 2 as libc::c_int; + histexp_comsub += 1; + old_dquote = dquote; + dquote = 0 as libc::c_int; + } else if histexp_comsub != 0 && c == ')' as i32 { + histexp_comsub -= 1; + dquote = old_dquote; + i += 1; + } else if backq != 0 { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _f_1: libc::c_int = 0; + _f_1 = is_basic(*string.offset(i as isize)); + if _f_1 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_1 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + i += 1; + } else if mblength_1 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_1) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + no_longjmp_on_fatal_error = oldjmp; + + return i; + } +} +#[no_mangle] +pub fn char_is_quoted(mut string: *mut libc::c_char, mut eindex: libc::c_int) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut oldjmp: libc::c_int = 0; + let mut slen: size_t = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + oldjmp = no_longjmp_on_fatal_error; + no_longjmp_on_fatal_error = 1 as libc::c_int; + pass_next = 0 as libc::c_int; + i = pass_next; + while i <= eindex { + c = *string.offset(i as isize) as libc::c_int; + if pass_next != 0 { + pass_next = 0 as libc::c_int; + if i >= eindex { + no_longjmp_on_fatal_error = oldjmp; + return 1 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if c == '\\' as i32 { + pass_next = 1 as libc::c_int; + i += 1; + } else if c == '$' as i32 + && *string.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '\'' as i32 + && *string.offset((i + 2 as libc::c_int) as isize) as libc::c_int != 0 + { + i += 2 as libc::c_int; + i = skip_single_quoted(string, slen, i, 0x400 as libc::c_int); + if i > eindex { + no_longjmp_on_fatal_error = oldjmp; + return i; + } + } else if c == '\'' as i32 || c == '"' as i32 { + i = if c == '\'' as i32 { + i += 1; + skip_single_quoted(string, slen, i, 0 as libc::c_int) + } else { + i += 1; + skip_double_quoted(string, slen, i, 0x400 as libc::c_int) + }; + if i > eindex { + no_longjmp_on_fatal_error = oldjmp; + return 1 as libc::c_int; + } + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + no_longjmp_on_fatal_error = oldjmp; + } + return 0 as libc::c_int; +} +#[no_mangle] +pub fn unclosed_pair( + mut string: *mut libc::c_char, + mut eindex: libc::c_int, + mut openstr: *mut libc::c_char, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut openc: libc::c_int = 0; + let mut olen: libc::c_int = 0; + let mut slen: size_t = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + olen = strlen(openstr) as libc::c_int; + openc = 0 as libc::c_int; + pass_next = openc; + i = pass_next; + while i <= eindex { + if pass_next != 0 { + pass_next = 0 as libc::c_int; + if i >= eindex { + return 0 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } else if *string.offset(i as isize) as libc::c_int == '\\' as i32 { + pass_next = 1 as libc::c_int; + i += 1; + } else if if olen == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*string.offset(i as isize).offset(0 as libc::c_int as isize) as libc::c_int + == *openstr.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp(string.offset(i as isize), openstr, olen as usize) + == 0 as libc::c_int) as libc::c_int + } != 0 + { + openc = 1 as libc::c_int - openc; + i += olen; + } else if *string.offset(i as isize) as libc::c_int == '\'' as i32 + || *string.offset(i as isize) as libc::c_int == '"' as i32 + { + i = if *string.offset(i as isize) as libc::c_int == '\'' as i32 { + skip_single_quoted(string, slen, i, 0 as libc::c_int) + } else { + skip_double_quoted(string, slen, i, 0x400 as libc::c_int) + }; + if i > eindex { + return 0 as libc::c_int; + } + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + + return openc; + } +} +#[no_mangle] +pub fn split_at_delims( + mut string: *mut libc::c_char, + mut slen: libc::c_int, + mut delims: *mut libc::c_char, + mut sentinel: libc::c_int, + mut flags: libc::c_int, + mut nwp: *mut libc::c_int, + mut cwp: *mut libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut ts: libc::c_int = 0; + let mut te: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut nw: libc::c_int = 0; + let mut cw: libc::c_int = 0; + let mut ifs_split: libc::c_int = 0; + let mut dflags: libc::c_int = 0; + let mut token: *mut libc::c_char = 0 as *mut libc::c_char; + let mut d: *mut libc::c_char = 0 as *mut libc::c_char; + let mut d2: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tl: *mut WORD_LIST = 0 as *mut WORD_LIST; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + if !nwp.is_null() { + *nwp = 0 as libc::c_int; + } + if !cwp.is_null() { + *cwp = 0 as libc::c_int; + } + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + d = if delims.is_null() { ifs_value } else { delims }; + ifs_split = (delims == 0 as *mut libc::c_char) as libc::c_int; + d2 = 0 as *mut libc::c_char; + if !delims.is_null() { + let mut slength: size_t = 0; + let mut mblength: size_t = 1 as libc::c_int as size_t; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slength = strlen(delims) as u64; + d2 = sh_xmalloc( + slength.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2309 as libc::c_int, + ) as *mut libc::c_char; + ts = 0 as libc::c_int; + i = ts; + while *delims.offset(i as isize) != 0 { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + state_bak = state; + mblength = if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + mbrlen(delims.offset(i as isize), slength, &mut state) + } else { + 1 as libc::c_int as libc::c_ulong + }; + if mblength == -(1 as libc::c_int) as size_t + || mblength == -(2 as libc::c_int) as size_t + { + state = state_bak; + } else if mblength > 1 as libc::c_int as libc::c_ulong { + memcpy( + d2.offset(ts as isize) as *mut libc::c_void, + delims.offset(i as isize) as *const libc::c_void, + mblength as usize, + ); + ts = (ts as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + slength = (slength as libc::c_ulong).wrapping_sub(mblength) as size_t as size_t; + continue; + } + if (*delims.offset(i as isize) as libc::c_int == ' ' as i32 + || *delims.offset(i as isize) as libc::c_int == '\t' as i32) + as libc::c_int + == 0 as libc::c_int + { + let fresh11 = ts; + ts = ts + 1; + *d2.offset(fresh11 as isize) = *delims.offset(i as isize); + } + i += 1; + slength = slength.wrapping_sub(1); + } + *d2.offset(ts as isize) = '\u{0}' as i32 as libc::c_char; + } + ret = 0 as *mut libc::c_void as *mut WORD_LIST; + i = 0 as libc::c_int; + while (if *string.offset(i as isize) as libc::c_int != 0 { + (mbschr(d, *string.offset(i as isize) as libc::c_int) + != 0 as *mut libc::c_void as *mut libc::c_char) as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + && (*string.offset(i as isize) as libc::c_int == ' ' as i32 + || *string.offset(i as isize) as libc::c_int == '\t' as i32 + || *string.offset(i as isize) as libc::c_int == '\n' as i32) + { + i += 1; + } + if *string.offset(i as isize) as libc::c_int == '\u{0}' as i32 { + if !d2.is_null() { + sh_xfree( + d2 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2345 as libc::c_int, + ); + } + return ret; + } + ts = i; + nw = 0 as libc::c_int; + cw = -(1 as libc::c_int); + dflags = flags | 0x1 as libc::c_int; + loop { + te = skip_to_delim(string, ts, d, dflags); + if ts == te + && !d2.is_null() + && (if *string.offset(ts as isize) as libc::c_int != 0 { + (mbschr(d2, *string.offset(ts as isize) as libc::c_int) + != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + { + te = ts + 1 as libc::c_int; + if ifs_split != 0 { + while (if *string.offset(te as isize) as libc::c_int != 0 { + (mbschr(d, *string.offset(te as isize) as libc::c_int) + != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + && (*string.offset(te as isize) as libc::c_int == ' ' as i32 + || *string.offset(te as isize) as libc::c_int == '\t' as i32 + || *string.offset(te as isize) as libc::c_int == '\n' as i32) + && (flags & 0x4 as libc::c_int == 0 as libc::c_int + || *string.offset(te as isize) as libc::c_int != '\'' as i32 + && *string.offset(te as isize) as libc::c_int != '"' as i32) + { + te += 1; + } + } else { + while (if *string.offset(te as isize) as libc::c_int != 0 { + (mbschr(d2, *string.offset(te as isize) as libc::c_int) + != 0 as *mut libc::c_void as *mut libc::c_char) + as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + && (flags & 0x4 as libc::c_int == 0 as libc::c_int + || *string.offset(te as isize) as libc::c_int != '\'' as i32 + && *string.offset(te as isize) as libc::c_int != '"' as i32) + { + te += 1; + } + } + } + token = substring(string, ts, te); + ret = make_word_list(make_word(token), ret); + sh_xfree( + token as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2376 as libc::c_int, + ); + nw += 1; + if sentinel >= ts && sentinel <= te { + cw = nw; + } + if !cwp.is_null() && cw == -(1 as libc::c_int) && sentinel == ts - 1 as libc::c_int { + cw = nw; + } + if !cwp.is_null() && cw == -(1 as libc::c_int) && sentinel < ts { + tl = make_word_list( + make_word(b"\0" as *const u8 as *const libc::c_char), + (*ret).next, + ); + let ref mut fresh12 = (*ret).next; + *fresh12 = tl; + cw = nw; + nw += 1; + } + if *string.offset(te as isize) as libc::c_int == 0 as libc::c_int { + break; + } + i = te; + while (if *string.offset(i as isize) as libc::c_int != 0 { + (mbschr(d, *string.offset(i as isize) as libc::c_int) + != 0 as *mut libc::c_void as *mut libc::c_char) as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + && (ifs_split != 0 + || (*string.offset(i as isize) as libc::c_int == ' ' as i32 + || *string.offset(i as isize) as libc::c_int == '\t' as i32 + || *string.offset(i as isize) as libc::c_int == '\n' as i32)) + && (flags & 0x4 as libc::c_int == 0 as libc::c_int + || *string.offset(te as isize) as libc::c_int != '\'' as i32 + && *string.offset(te as isize) as libc::c_int != '"' as i32) + { + i += 1; + } + if !(*string.offset(i as isize) != 0) { + break; + } + ts = i; + } + if !cwp.is_null() && cw == -(1 as libc::c_int) && (sentinel >= slen || sentinel >= te) { + if *string.offset((sentinel - 1 as libc::c_int) as isize) as libc::c_int == ' ' as i32 + || *string.offset((sentinel - 1 as libc::c_int) as isize) as libc::c_int + == '\t' as i32 + { + token = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + ret = make_word_list(make_word(token), ret); + nw += 1; + } + cw = nw; + } + if !nwp.is_null() { + *nwp = nw; + } + if !cwp.is_null() { + *cwp = cw; + } + if !d2.is_null() { + sh_xfree( + d2 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2433 as libc::c_int, + ); + } + return if !ret.is_null() && !((*ret).next).is_null() { + list_reverse(ret as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + ret + }; + } +} +#[no_mangle] +pub fn string_list_internal( + mut list: *mut WORD_LIST, + mut sep: *mut libc::c_char, +) -> *mut libc::c_char { + unsafe { + let mut t: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut word_len: size_t = 0; + let mut sep_len: size_t = 0; + let mut result_size: size_t = 0; + if list.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if ((*list).next).is_null() { + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*(*list).word).word) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2479 as libc::c_int, + ) as *mut libc::c_char, + (*(*list).word).word, + ); + } + sep_len = if !sep.is_null() && *sep.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *sep.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *sep.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(sep) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + result_size = 0 as libc::c_int as size_t; + t = list; + while !t.is_null() { + if t != list { + result_size = + (result_size as libc::c_ulong).wrapping_add(sep_len) as size_t as size_t; + } + result_size = (result_size as libc::c_ulong) + .wrapping_add(strlen((*(*t).word).word) as u64) as size_t + as size_t; + t = (*t).next; + } + result = sh_xmalloc( + result_size.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2492 as libc::c_int, + ) as *mut libc::c_char; + r = result; + t = list; + while !t.is_null() { + if t != list && sep_len != 0 { + if sep_len > 1 as libc::c_int as libc::c_ulong { + libc::memcpy( + r as *mut libc::c_void, + sep as *const libc::c_void, + sep_len as libc::size_t, + ); + r = r.offset(sep_len as isize); + } else { + let fresh13 = r; + r = r.offset(1); + *fresh13 = *sep.offset(0 as libc::c_int as isize); + } + } + word_len = strlen((*(*t).word).word) as u64; + libc::memcpy( + r as *mut libc::c_void, + (*(*t).word).word as *const libc::c_void, + word_len as libc::size_t, + ); + r = r.offset(word_len as isize); + t = (*t).next; + } + *r = '\u{0}' as i32 as libc::c_char; + + return result; + } +} +#[no_mangle] +pub fn string_list(mut list: *mut WORD_LIST) -> *mut libc::c_char { + return string_list_internal( + list, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); +} +#[no_mangle] +pub fn ifs_firstchar(mut lenp: *mut libc::c_int) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: libc::c_int = 0; + ret = sh_xmalloc( + (16 as libc::c_int + 1 as libc::c_int) as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2536 as libc::c_int, + ) as *mut libc::c_char; + if ifs_firstc_len == 1 as libc::c_int as libc::c_ulong { + *ret.offset(0 as libc::c_int as isize) = + ifs_firstc[0 as libc::c_int as usize] as libc::c_char; + *ret.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + len = if *ret.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + } else { + memcpy( + ret as *mut libc::c_void, + ifs_firstc.as_mut_ptr() as *const libc::c_void, + ifs_firstc_len as usize, + ); + len = ifs_firstc_len as libc::c_int; + *ret.offset(len as isize) = '\u{0}' as i32 as libc::c_char; + } + if !lenp.is_null() { + *lenp = len; + } + + return ret; + } +} +#[no_mangle] +pub fn string_list_dollar_star( + mut list: *mut WORD_LIST, + mut quoted: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let vla = (__ctype_get_mb_cur_max()).wrapping_add(1 as libc::c_int as usize) as usize; + let mut sep: Vec = ::std::vec::from_elem(0, vla); + if ifs_firstc_len == 1 as libc::c_int as libc::c_ulong { + *sep.as_mut_ptr().offset(0 as libc::c_int as isize) = + ifs_firstc[0 as libc::c_int as usize] as libc::c_char; + *sep.as_mut_ptr().offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } else { + memcpy( + sep.as_mut_ptr() as *mut libc::c_void, + ifs_firstc.as_mut_ptr() as *const libc::c_void, + ifs_firstc_len as usize, + ); + *sep.as_mut_ptr().offset(ifs_firstc_len as isize) = '\u{0}' as i32 as libc::c_char; + } + ret = string_list_internal(list, sep.as_mut_ptr()); + + return ret; + } +} +#[no_mangle] +pub fn string_list_dollar_at( + mut list: *mut WORD_LIST, + mut quoted: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut ifs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let vla = (__ctype_get_mb_cur_max()).wrapping_add(1 as libc::c_int as usize) as usize; + let mut sep: Vec = ::std::vec::from_elem(0, vla); + let mut tlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + ifs = if !ifs_var.is_null() { + (*ifs_var).value + } else { + 0 as *mut libc::c_char + }; + if flags & 0x8 as libc::c_int != 0 { + *sep.as_mut_ptr().offset(0 as libc::c_int as isize) = ' ' as i32 as libc::c_char; + *sep.as_mut_ptr().offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } else if !ifs.is_null() && *ifs as libc::c_int != 0 { + if ifs_firstc_len == 1 as libc::c_int as libc::c_ulong { + *sep.as_mut_ptr().offset(0 as libc::c_int as isize) = + ifs_firstc[0 as libc::c_int as usize] as libc::c_char; + *sep.as_mut_ptr().offset(1 as libc::c_int as isize) = + '\u{0}' as i32 as libc::c_char; + } else { + memcpy( + sep.as_mut_ptr() as *mut libc::c_void, + ifs_firstc.as_mut_ptr() as *const libc::c_void, + ifs_firstc_len as usize, + ); + *sep.as_mut_ptr().offset(ifs_firstc_len as isize) = '\u{0}' as i32 as libc::c_char; + } + } else { + *sep.as_mut_ptr().offset(0 as libc::c_int as isize) = ' ' as i32 as libc::c_char; + *sep.as_mut_ptr().offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } + tlist = if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int | 0x8 as libc::c_int) != 0 { + quote_list(list) + } else { + list_quote_escapes(list) + }; + ret = string_list_internal(tlist, sep.as_mut_ptr()); + + return ret; + } +} +#[no_mangle] +pub fn string_list_pos_params( + mut pchar: libc::c_int, + mut list: *mut WORD_LIST, + mut quoted: libc::c_int, + mut pflags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + if pchar == '*' as i32 && quoted & 0x1 as libc::c_int != 0 { + tlist = quote_list(list); + word_list_remove_quoted_nulls(tlist); + ret = string_list_dollar_star(tlist, 0 as libc::c_int, 0 as libc::c_int); + } else if pchar == '*' as i32 && quoted & 0x2 as libc::c_int != 0 { + tlist = quote_list(list); + word_list_remove_quoted_nulls(tlist); + ret = string_list(tlist); + } else if pchar == '*' as i32 && quoted == 0 as libc::c_int && ifs_is_null != 0 { + ret = if expand_no_split_dollar_star != 0 { + string_list_dollar_star(list, quoted, 0 as libc::c_int) + } else { + string_list_dollar_at(list, quoted, 0 as libc::c_int) + }; + } else if pchar == '*' as i32 + && quoted == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0 + { + ret = if expand_no_split_dollar_star != 0 { + string_list_dollar_star(list, quoted, 0 as libc::c_int) + } else { + string_list_dollar_at(list, quoted, 0 as libc::c_int) + }; + } else if pchar == '*' as i32 { + ret = string_list_dollar_star(list, quoted, 0 as libc::c_int); + } else if pchar == '@' as i32 && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + ret = string_list_dollar_at(list, quoted, 0 as libc::c_int); + } else if pchar == '@' as i32 && quoted == 0 as libc::c_int && ifs_is_null != 0 { + ret = string_list_dollar_at(list, quoted, 0 as libc::c_int); + } else if pchar == '@' as i32 + && quoted == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0 + { + ret = string_list_dollar_at(list, quoted, pflags); + } else if pchar == '@' as i32 { + ret = string_list_dollar_star(list, quoted, 0 as libc::c_int); + } else { + ret = string_list(if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + quote_list(list) + } else { + list + }); + } + + return ret; + } +} +#[no_mangle] +pub fn list_string( + mut string: *mut libc::c_char, + mut separators: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut current_word: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sindex: libc::c_int = 0; + let mut sh_style_split: libc::c_int = 0; + let mut whitesep: libc::c_int = 0; + let mut xflags: libc::c_int = 0; + let mut free_word: libc::c_int = 0; + let mut slen: size_t = 0; + if string.is_null() || *string == 0 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + sh_style_split = (!separators.is_null() + && *separators.offset(0 as libc::c_int as isize) as libc::c_int == ' ' as i32 + && *separators.offset(1 as libc::c_int as isize) as libc::c_int == '\t' as i32 + && *separators.offset(2 as libc::c_int as isize) as libc::c_int == '\n' as i32 + && *separators.offset(3 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int; + xflags = 0 as libc::c_int; + s = ifs_value; + while !s.is_null() && *s as libc::c_int != 0 { + if *s as libc::c_int == '\u{1}' as i32 { + xflags |= 0x10 as libc::c_int; + } else if *s as libc::c_int == '\u{7f}' as i32 { + xflags |= 0x20 as libc::c_int; + } + s = s.offset(1); + } + slen = 0 as libc::c_int as size_t; + if quoted == 0 && !separators.is_null() && *separators as libc::c_int != 0 { + s = string; + while *s as libc::c_int != 0 + && (if *separators.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + (if *separators.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (ifs_cmap[*s as libc::c_uchar as usize] as libc::c_int != 0 as libc::c_int) + as libc::c_int + } else { + (*s as libc::c_int + == *separators.offset(0 as libc::c_int as isize) as libc::c_int) + as libc::c_int + }) + } else { + 0 as libc::c_int + }) != 0 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*s as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) + { + s = s.offset(1); + } + if *s == 0 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + string = s; + } + slen = if !string.is_null() && *string.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *string.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *string.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(string) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + result = 0 as *mut libc::c_void as *mut WORD_LIST; + sindex = 0 as libc::c_int; + while *string.offset(sindex as isize) != 0 { + current_word = string_extract_verbatim(string, slen, &mut sindex, separators, xflags); + if current_word.is_null() { + break; + } + free_word = 1 as libc::c_int; + if *current_word.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *current_word.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + t = alloc_word_desc(); + let ref mut fresh14 = (*t).word; + *fresh14 = make_quoted_char('\u{0}' as i32); + (*t).flags |= (1 as libc::c_int) << 1 as libc::c_int + | (1 as libc::c_int) << 18 as libc::c_int; + result = make_word_list(t, result); + } else if *current_word.offset(0 as libc::c_int as isize) as libc::c_int + != '\u{0}' as i32 + { + remove_quoted_nulls(current_word); + t = alloc_word_desc(); + let ref mut fresh15 = (*t).word; + *fresh15 = current_word; + result = make_word_list(t, result); + free_word = 0 as libc::c_int; + (*(*result).word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + (*(*result).word).flags |= (1 as libc::c_int) << 1 as libc::c_int; + } + if current_word.is_null() + || *current_word.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + (*(*result).word).flags |= (1 as libc::c_int) << 21 as libc::c_int; + } + } else if sh_style_split == 0 + && !(1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset( + *string.offset(sindex as isize) as libc::c_uchar as libc::c_int as isize + ) as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) + { + t = alloc_word_desc(); + let ref mut fresh16 = (*t).word; + *fresh16 = make_quoted_char('\u{0}' as i32); + (*t).flags |= (1 as libc::c_int) << 1 as libc::c_int + | (1 as libc::c_int) << 18 as libc::c_int; + result = make_word_list(t, result); + } + if free_word != 0 { + sh_xfree( + current_word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 2901 as libc::c_int, + ); + } + whitesep = (*string.offset(sindex as isize) as libc::c_int != 0 + && (if sh_style_split != 0 || separators.is_null() { + (*string.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*string.offset(sindex as isize) + as libc::c_uchar + as libc::c_int + as isize) as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) != 0) as libc::c_int; + if *string.offset(sindex as isize) != 0 { + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(sindex as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(sindex as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(sindex as isize) as libc::c_int + != 0 as libc::c_int) as libc::c_int + as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(sindex as isize), + slen.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + sindex += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + sindex += 1; + } else { + sindex = (sindex as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + sindex += 1; + } + } + while *string.offset(sindex as isize) as libc::c_int != 0 + && (if sh_style_split != 0 || separators.is_null() { + (*string.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*string.offset(sindex as isize) + as libc::c_uchar + as libc::c_int + as isize) as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) != 0 + && (if *separators.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + (if *separators.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (ifs_cmap[*string.offset(sindex as isize) as libc::c_uchar as usize] + as libc::c_int + != 0 as libc::c_int) as libc::c_int + } else { + (*string.offset(sindex as isize) as libc::c_int + == *separators.offset(0 as libc::c_int as isize) as libc::c_int) + as libc::c_int + }) + } else { + 0 as libc::c_int + }) != 0 + { + sindex += 1; + } + if *string.offset(sindex as isize) as libc::c_int != 0 + && whitesep != 0 + && (if *separators.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + (if *separators.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (ifs_cmap[*string.offset(sindex as isize) as libc::c_uchar as usize] + as libc::c_int + != 0 as libc::c_int) as libc::c_int + } else { + (*string.offset(sindex as isize) as libc::c_int + == *separators.offset(0 as libc::c_int as isize) as libc::c_int) + as libc::c_int + }) + } else { + 0 as libc::c_int + }) != 0 + && (if sh_style_split != 0 || separators.is_null() { + (*string.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*string.offset(sindex as isize) + as libc::c_uchar + as libc::c_int + as isize) as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) == 0 + { + sindex += 1; + while *string.offset(sindex as isize) as libc::c_int != 0 + && (if sh_style_split != 0 || separators.is_null() { + (*string.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *string.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()) + .offset(*string.offset(sindex as isize) as libc::c_uchar + as libc::c_int as isize) + as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) != 0 + && ifs_cmap[*string.offset(sindex as isize) as libc::c_uchar as usize] + as libc::c_int + != 0 as libc::c_int + { + sindex += 1; + } + } + } + return if !result.is_null() && !((*result).next).is_null() { + list_reverse(result as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + result + }; + } +} +#[no_mangle] +pub fn get_word_from_string( + mut stringp: *mut *mut libc::c_char, + mut separators: *mut libc::c_char, + mut endptr: *mut *mut libc::c_char, +) -> *mut libc::c_char { + unsafe { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut current_word: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sindex: libc::c_int = 0; + let mut sh_style_split: libc::c_int = 0; + let mut whitesep: libc::c_int = 0; + let mut xflags: libc::c_int = 0; + let mut local_cmap: [libc::c_uchar; 256] = [0; 256]; + let mut slen: size_t = 0; + if stringp.is_null() || (*stringp).is_null() || **stringp == 0 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + sh_style_split = (!separators.is_null() + && *separators.offset(0 as libc::c_int as isize) as libc::c_int == ' ' as i32 + && *separators.offset(1 as libc::c_int as isize) as libc::c_int == '\t' as i32 + && *separators.offset(2 as libc::c_int as isize) as libc::c_int == '\n' as i32 + && *separators.offset(3 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int; + memset( + local_cmap.as_mut_ptr() as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::<[libc::c_uchar; 256]>() as usize, + ); + xflags = 0 as libc::c_int; + s = separators; + while !s.is_null() && *s as libc::c_int != 0 { + if *s as libc::c_int == '\u{1}' as i32 { + xflags |= 0x10 as libc::c_int; + } + if *s as libc::c_int == '\u{7f}' as i32 { + xflags |= 0x20 as libc::c_int; + } + local_cmap[*s as libc::c_uchar as usize] = 1 as libc::c_int as libc::c_uchar; + s = s.offset(1); + } + s = *stringp; + slen = 0 as libc::c_int as size_t; + if sh_style_split != 0 || separators.is_null() { + while *s as libc::c_int != 0 + && (*s as libc::c_int == ' ' as i32 + || *s as libc::c_int == '\t' as i32 + || *s as libc::c_int == '\n' as i32) + && local_cmap[*s as libc::c_uchar as usize] as libc::c_int != 0 as libc::c_int + { + s = s.offset(1); + } + } else { + while *s as libc::c_int != 0 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*s as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) + && local_cmap[*s as libc::c_uchar as usize] as libc::c_int != 0 as libc::c_int + { + s = s.offset(1); + } + } + if *s == 0 { + *stringp = s; + if !endptr.is_null() { + *endptr = s; + } + return 0 as *mut libc::c_void as *mut libc::c_char; + } + sindex = 0 as libc::c_int; + slen = if !s.is_null() && *s.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *s.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *s.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(s) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + current_word = string_extract_verbatim(s, slen, &mut sindex, separators, xflags); + if !endptr.is_null() { + *endptr = s.offset(sindex as isize); + } + whitesep = (*s.offset(sindex as isize) as libc::c_int != 0 + && (if sh_style_split != 0 || separators.is_null() { + (*s.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()) + .offset(*s.offset(sindex as isize) as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) != 0) as libc::c_int; + if *s.offset(sindex as isize) != 0 { + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*s.offset(sindex as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s.offset(sindex as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*s.offset(sindex as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + s.offset(sindex as isize), + slen.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + sindex += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + sindex += 1; + } else { + sindex = (sindex as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + sindex += 1; + } + } + while *s.offset(sindex as isize) as libc::c_int != 0 + && (*s.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\n' as i32) + && local_cmap[*s.offset(sindex as isize) as libc::c_uchar as usize] as libc::c_int + != 0 as libc::c_int + { + sindex += 1; + } + if *s.offset(sindex as isize) as libc::c_int != 0 + && whitesep != 0 + && local_cmap[*s.offset(sindex as isize) as libc::c_uchar as usize] as libc::c_int + != 0 as libc::c_int + && (if sh_style_split != 0 || separators.is_null() { + (*s.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()) + .offset(*s.offset(sindex as isize) as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) == 0 + { + sindex += 1; + while *s.offset(sindex as isize) as libc::c_int != 0 + && (if sh_style_split != 0 || separators.is_null() { + (*s.offset(sindex as isize) as libc::c_int == ' ' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\t' as i32 + || *s.offset(sindex as isize) as libc::c_int == '\n' as i32) + as libc::c_int + } else { + (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*s.offset(sindex as isize) as libc::c_uchar + as libc::c_int + as isize) as libc::c_int + & _ISspace as libc::c_int as libc::c_ushort as libc::c_int + != 0) as libc::c_int + }) != 0 + && local_cmap[*s.offset(sindex as isize) as libc::c_uchar as usize] as libc::c_int + != 0 as libc::c_int + { + sindex += 1; + } + } + *stringp = s.offset(sindex as isize); + + return current_word; + } +} +#[no_mangle] +pub fn strip_trailing_ifs_whitespace( + mut string: *mut libc::c_char, + mut separators: *mut libc::c_char, + mut saw_escape: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + s = string + .offset( + (if !string.is_null() + && *string.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + (if *string.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (if *string.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(string) as usize + } else { + 2 as libc::c_int as usize + }) + } else { + 1 as libc::c_int as usize + }) + } else { + 0 as libc::c_int as usize + }) as isize, + ) + .offset(-(1 as libc::c_int as isize)); + while s > string + && ((*s as libc::c_int == ' ' as i32 + || *s as libc::c_int == '\t' as i32 + || *s as libc::c_int == '\n' as i32) + && ifs_cmap[*s as libc::c_uchar as usize] as libc::c_int != 0 as libc::c_int + || saw_escape != 0 + && *s as libc::c_int == '\u{1}' as i32 + && (*s.offset(1 as libc::c_int as isize) as libc::c_int == ' ' as i32 + || *s.offset(1 as libc::c_int as isize) as libc::c_int == '\t' as i32 + || *s.offset(1 as libc::c_int as isize) as libc::c_int == '\n' as i32)) + { + s = s.offset(-1); + } + s = s.offset(1); + *s = '\u{0}' as i32 as libc::c_char; + } + return string; +} +fn do_compound_assignment( + mut name: *mut libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + unsafe { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut mklocal: libc::c_int = 0; + let mut mkassoc: libc::c_int = 0; + let mut mkglobal: libc::c_int = 0; + let mut chklocal: libc::c_int = 0; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + mklocal = flags & 0x2 as libc::c_int; + mkassoc = flags & 0x4 as libc::c_int; + mkglobal = flags & 0x8 as libc::c_int; + chklocal = flags & 0x40 as libc::c_int; + if mklocal != 0 && variable_context != 0 { + v = find_variable(name); + newname = if v.is_null() { + nameref_transform_name(name, flags) + } else { + (*v).name + }; + if !v.is_null() + && ((*v).attributes & 0x2 as libc::c_int != 0 + && flags & 0x20 as libc::c_int == 0 as libc::c_int + || (*v).attributes & 0x4000 as libc::c_int != 0) + { + if (*v).attributes & 0x2 as libc::c_int != 0 { + err_readonly(name); + } + return v; + } + list = expand_compound_array_assignment(v, value, flags); + if mkassoc != 0 { + v = make_local_assoc_variable(newname, 0 as libc::c_int); + } else if v.is_null() + || (*v).attributes & 0x4 as libc::c_int == 0 as libc::c_int + && (*v).attributes & 0x40 as libc::c_int == 0 as libc::c_int + || (*v).context != variable_context + { + v = make_local_array_variable(newname, 0 as libc::c_int); + } + if !v.is_null() { + assign_compound_array_list(v, list, flags); + } + if !list.is_null() { + dispose_words(list); + } + } else if mkglobal != 0 && variable_context != 0 { + v = if chklocal != 0 { + find_variable(name) + } else { + 0 as *mut SHELL_VAR + }; + if !v.is_null() + && ((*v).attributes & 0x20 as libc::c_int == 0 as libc::c_int + || (*v).context != variable_context) + { + v = 0 as *mut SHELL_VAR; + } + if v.is_null() { + v = find_global_variable(name); + } + if !v.is_null() + && ((*v).attributes & 0x2 as libc::c_int != 0 + && flags & 0x20 as libc::c_int == 0 as libc::c_int + || (*v).attributes & 0x4000 as libc::c_int != 0) + { + if (*v).attributes & 0x2 as libc::c_int != 0 { + err_readonly(name); + } + return v; + } + newname = if v.is_null() { + nameref_transform_name(name, flags) + } else { + name + }; + list = expand_compound_array_assignment(v, value, flags); + if v.is_null() && mkassoc != 0 { + v = make_new_assoc_variable(newname); + } else if !v.is_null() + && mkassoc != 0 + && (*v).attributes & 0x40 as libc::c_int == 0 as libc::c_int + { + v = convert_var_to_assoc(v); + } else if v.is_null() { + v = make_new_array_variable(newname); + } else if !v.is_null() + && mkassoc == 0 as libc::c_int + && (*v).attributes & 0x4 as libc::c_int == 0 as libc::c_int + { + v = convert_var_to_array(v); + } + if !v.is_null() { + assign_compound_array_list(v, list, flags); + } + if !list.is_null() { + dispose_words(list); + } + } else { + v = assign_array_from_string(name, value, flags); + if !v.is_null() + && ((*v).attributes & 0x2 as libc::c_int != 0 + && flags & 0x20 as libc::c_int == 0 as libc::c_int + || (*v).attributes & 0x4000 as libc::c_int != 0) + { + if (*v).attributes & 0x2 as libc::c_int != 0 { + err_readonly(name); + } + return v; + } + } + + return v; + } +} +fn do_assignment_internal(mut word: *const WORD_DESC, mut expand: libc::c_int) -> libc::c_int { + unsafe { + let mut offset: libc::c_int = 0; + let mut appendop: libc::c_int = 0; + let mut assign_list: libc::c_int = 0; + let mut aflags: libc::c_int = 0; + let mut retval: libc::c_int = 0; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ni: libc::c_int = 0; + let mut string: *const libc::c_char = 0 as *const libc::c_char; + if word.is_null() || ((*word).word).is_null() { + return 0 as libc::c_int; + } + aflags = 0 as libc::c_int; + assign_list = aflags; + appendop = assign_list; + string = (*word).word; + offset = assignment(string, 0 as libc::c_int); + name = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3228 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + value = 0 as *mut libc::c_void as *mut libc::c_char; + if *name.offset(offset as isize) as libc::c_int == '=' as i32 { + if *name.offset((offset - 1 as libc::c_int) as isize) as libc::c_int == '+' as i32 { + appendop = 1 as libc::c_int; + *name.offset((offset - 1 as libc::c_int) as isize) = '\u{0}' as i32 as libc::c_char; + } + *name.offset(offset as isize) = 0 as libc::c_int as libc::c_char; + temp = name + .offset(offset as isize) + .offset(1 as libc::c_int as isize); + if expand != 0 && (*word).flags & (1 as libc::c_int) << 15 as libc::c_int != 0 { + ni = 1 as libc::c_int; + assign_list = ni; + value = extract_array_assignment_list(temp, &mut ni); + } else if expand != 0 && *temp.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + value = expand_string_if_necessary( + temp, + 0 as libc::c_int, + Some( + expand_string_assignment + as fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST, + ), + ); + } else { + value = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(temp) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3253 as libc::c_int, + ) as *mut libc::c_char, + temp, + ); + } + } + if value.is_null() { + value = sh_xmalloc( + 1 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3258 as libc::c_int, + ) as *mut libc::c_char; + *value.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } + if echo_command_at_execute != 0 { + if appendop != 0 { + *name.offset((offset - 1 as libc::c_int) as isize) = '+' as i32 as libc::c_char; + } + xtrace_print_assignment(name, value, assign_list, 1 as libc::c_int); + if appendop != 0 { + *name.offset((offset - 1 as libc::c_int) as isize) = '\u{0}' as i32 as libc::c_char; + } + } + if appendop != 0 { + aflags |= 0x1 as libc::c_int; + } + t = mbschr(name, '[' as i32); + if !t.is_null() { + if assign_list != 0 { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: cannot assign list to array member\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3282 as libc::c_int, + ); + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3282 as libc::c_int, + ); + return 0 as libc::c_int; + } + entry = assign_array_element(name, value, aflags); + if entry.is_null() { + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3286 as libc::c_int, + ); + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3286 as libc::c_int, + ); + return 0 as libc::c_int; + } + } else if assign_list != 0 { + if (*word).flags & (1 as libc::c_int) << 17 as libc::c_int != 0 + && (*word).flags & (1 as libc::c_int) << 28 as libc::c_int != 0 + { + aflags |= 0x40 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 17 as libc::c_int != 0 + && (*word).flags & (1 as libc::c_int) << 25 as libc::c_int == 0 as libc::c_int + { + aflags |= 0x2 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 17 as libc::c_int != 0 + && (*word).flags & (1 as libc::c_int) << 25 as libc::c_int != 0 + { + aflags |= 0x8 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 22 as libc::c_int != 0 { + aflags |= 0x4 as libc::c_int; + } + entry = do_compound_assignment(name, value, aflags); + } else { + entry = bind_variable(name, value, aflags); + } + if !entry.is_null() { + stupidly_hack_special_variables((*entry).name); + } else { + stupidly_hack_special_variables(name); + } + if entry.is_null() || (*entry).attributes & 0x2 as libc::c_int != 0 { + retval = 0 as libc::c_int; + } else if (*entry).attributes & 0x4000 as libc::c_int != 0 { + set_exit_status(1 as libc::c_int); + retval = 1 as libc::c_int; + } else { + retval = 1 as libc::c_int; + } + if !entry.is_null() + && retval != 0 as libc::c_int + && (*entry).attributes & 0x4000 as libc::c_int == 0 as libc::c_int + { + (*entry).attributes &= !(0x1000 as libc::c_int); + } + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3323 as libc::c_int, + ); + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3323 as libc::c_int, + ); + + return retval; + } +} +#[no_mangle] +pub fn do_assignment(mut string: *mut libc::c_char) -> libc::c_int { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + td.flags = (1 as libc::c_int) << 2 as libc::c_int; + td.word = string; + return do_assignment_internal(&mut td, 1 as libc::c_int); +} +#[no_mangle] +pub fn do_word_assignment(mut word: *mut WORD_DESC, mut flags: libc::c_int) -> libc::c_int { + return do_assignment_internal(word, 1 as libc::c_int); +} +#[no_mangle] +pub fn do_assignment_no_expand(mut string: *mut libc::c_char) -> libc::c_int { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + td.flags = (1 as libc::c_int) << 2 as libc::c_int; + td.word = string; + return do_assignment_internal(&mut td, 0 as libc::c_int); +} +#[no_mangle] +pub fn list_rest_of_args() -> *mut WORD_LIST { + unsafe { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut args: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut i: libc::c_int = 0; + i = 1 as libc::c_int; + list = 0 as *mut libc::c_void as *mut WORD_LIST; + while i < 10 as libc::c_int && !(*dollar_vars.as_mut_ptr().offset(i as isize)).is_null() { + list = make_word_list( + make_bare_word(*dollar_vars.as_mut_ptr().offset(i as isize)), + list, + ); + i += 1; + } + args = rest_of_args; + while !args.is_null() { + list = make_word_list(make_bare_word((*(*args).word).word), list); + args = (*args).next; + } + return if !list.is_null() && !((*list).next).is_null() { + list_reverse(list as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + list + }; + } +} +#[no_mangle] +pub fn get_dollar_var_value(mut ind: intmax_t) -> *mut libc::c_char { + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut WORD_LIST = 0 as *mut WORD_LIST; + if ind < 10 as libc::c_int as libc::c_long { + temp = if !(*dollar_vars.as_mut_ptr().offset(ind as isize)).is_null() { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add( + strlen(*dollar_vars.as_mut_ptr().offset(ind as isize)) as u64 + ), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3395 as libc::c_int, + ) as *mut libc::c_char, + *dollar_vars.as_mut_ptr().offset(ind as isize), + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } else { + ind -= 10 as libc::c_int as libc::c_long; + p = rest_of_args; + while !p.is_null() && { + let fresh17 = ind; + ind = ind - 1; + fresh17 != 0 + } { + p = (*p).next; + } + temp = if !p.is_null() { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*(*p).word).word) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3401 as libc::c_int, + ) as *mut libc::c_char, + (*(*p).word).word, + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + + return temp; + } +} +#[no_mangle] +pub fn string_rest_of_args(mut dollar_star: libc::c_int) -> *mut libc::c_char { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut string: *mut libc::c_char = 0 as *mut libc::c_char; + list = list_rest_of_args(); + string = if dollar_star != 0 { + string_list_dollar_star(list, 0 as libc::c_int, 0 as libc::c_int) + } else { + string_list(list) + }; + dispose_words(list); + + return string; +} +fn pos_params( + mut string: *mut libc::c_char, + mut start: libc::c_int, + mut end: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut params: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut h: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + if start == end { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + params = list_rest_of_args(); + save = params; + if save.is_null() && start > 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if start == 0 as libc::c_int { + t = make_word_list( + make_word(*dollar_vars.as_mut_ptr().offset(0 as libc::c_int as isize)), + params, + ); + params = t; + save = params; + } + i = if start != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + while !params.is_null() && i < start { + params = (*params).next; + i += 1; + } + if params.is_null() { + dispose_words(save); + return 0 as *mut libc::c_void as *mut libc::c_char; + } + t = params; + h = t; + while !params.is_null() && i < end { + t = params; + params = (*params).next; + i += 1; + } + let ref mut fresh18 = (*t).next; + *fresh18 = 0 as *mut libc::c_void as *mut WORD_LIST; + ret = string_list_pos_params( + *string.offset(0 as libc::c_int as isize) as libc::c_int, + h, + quoted, + pflags, + ); + if t != params { + let ref mut fresh19 = (*t).next; + *fresh19 = params; + } + dispose_words(save); + + return ret; + } +} +fn expand_string_if_necessary( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, + mut func: Option, +) -> *mut libc::c_char { + unsafe { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut slen: size_t = 0; + let mut i: libc::c_int = 0; + let mut saw_quote: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + strlen(string) as u64 + } else { + 0 as libc::c_int as libc::c_ulong + }; + saw_quote = 0 as libc::c_int; + i = saw_quote; + while *string.offset(i as isize) != 0 { + if *string.offset(i as isize) as libc::c_int == '$' as i32 + || *string.offset(i as isize) as libc::c_int == '`' as i32 + || *string.offset(i as isize) as libc::c_int == '<' as i32 + || *string.offset(i as isize) as libc::c_int == '>' as i32 + || *string.offset(i as isize) as libc::c_int == '\u{1}' as i32 + || *string.offset(i as isize) as libc::c_int == '~' as i32 + { + break; + } + if *string.offset(i as isize) as libc::c_int == '\'' as i32 + || *string.offset(i as isize) as libc::c_int == '\\' as i32 + || *string.offset(i as isize) as libc::c_int == '"' as i32 + { + saw_quote = 1 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + if *string.offset(i as isize) != 0 { + list = (Some(func.expect("non-null function pointer"))) + .expect("non-null function pointer")(string, quoted); + if !list.is_null() { + ret = string_list(list); + dispose_words(list); + } else { + ret = 0 as *mut libc::c_void as *mut libc::c_char; + } + } else if saw_quote != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) == 0 as libc::c_int + { + ret = string_quote_removal(string, quoted); + } else { + ret = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3526 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + } + + return ret; + } +} +#[inline] +fn expand_string_to_string_internal( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, + mut func: Option, +) -> *mut libc::c_char { + unsafe { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + list = (Some(func.expect("non-null function pointer"))).expect("non-null function pointer")( + string, quoted, + ); + if !list.is_null() { + ret = string_list(list); + dispose_words(list); + } else { + ret = 0 as *mut libc::c_void as *mut libc::c_char; + } + return ret; + } +} +#[no_mangle] +pub fn expand_string_to_string( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + return expand_string_to_string_internal( + string, + quoted, + Some(expand_string as fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST), + ); +} +#[no_mangle] +pub fn expand_string_unsplit_to_string( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + return expand_string_to_string_internal( + string, + quoted, + Some(expand_string_unsplit as fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST), + ); +} +#[no_mangle] +pub fn expand_assignment_string_to_string( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + return expand_string_to_string_internal( + string, + quoted, + Some(expand_string_assignment as fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST), + ); +} +#[no_mangle] +pub fn expand_arith_string( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut slen: size_t = 0; + let mut i: libc::c_int = 0; + let mut saw_quote: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + strlen(string) as u64 + } else { + 0 as libc::c_int as u64 + }; + saw_quote = 0 as libc::c_int; + i = saw_quote; + while *string.offset(i as isize) != 0 { + if *string.offset(i as isize) as libc::c_int == '$' as i32 + || *string.offset(i as isize) as libc::c_int == '`' as i32 + || *string.offset(i as isize) as libc::c_int == '<' as i32 + || *string.offset(i as isize) as libc::c_int == '>' as i32 + || *string.offset(i as isize) as libc::c_int == '\u{1}' as i32 + || *string.offset(i as isize) as libc::c_int == '~' as i32 + { + break; + } + if *string.offset(i as isize) as libc::c_int == '\'' as i32 + || *string.offset(i as isize) as libc::c_int == '\\' as i32 + || *string.offset(i as isize) as libc::c_int == '"' as i32 + { + saw_quote = 1 as libc::c_int; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + } + if *string.offset(i as isize) != 0 { + td.flags = + (1 as libc::c_int) << 20 as libc::c_int | (1 as libc::c_int) << 12 as libc::c_int; + td.word = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3612 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + list = call_expand_word_internal( + &mut td, + quoted, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if !list.is_null() { + tlist = word_list_split(list); + dispose_words(list); + list = tlist; + if !list.is_null() { + dequote_list(list); + } + } + if !list.is_null() { + ret = string_list(list); + dispose_words(list); + } else { + ret = 0 as *mut libc::c_void as *mut libc::c_char; + } + if !(td.word).is_null() { + sh_xfree( + td.word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3632 as libc::c_int, + ); + } + } else if saw_quote != 0 && quoted & 0x100 as libc::c_int != 0 { + ret = string_quote_removal(string, quoted); + } else if saw_quote != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) == 0 as libc::c_int + { + ret = string_quote_removal(string, quoted); + } else { + ret = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3639 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + } + + return ret; + } +} +#[no_mangle] +pub fn remove_backslashes(mut string: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + ret = sh_xmalloc( + (strlen(string)).wrapping_add(1 as libc::c_int as u64) as u64, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3652 as libc::c_int, + ) as *mut libc::c_char; + r = ret; + s = string; + while !s.is_null() && *s as libc::c_int != 0 { + if *s as libc::c_int == '\\' as i32 { + s = s.offset(1); + } + if *s as libc::c_int == 0 as libc::c_int { + break; + } + let fresh20 = s; + s = s.offset(1); + let fresh21 = r; + r = r.offset(1); + *fresh21 = *fresh20; + } + *r = '\u{0}' as i32 as libc::c_char; + + return ret; + } +} +#[no_mangle] +pub fn cond_expand_word(mut w: *mut WORD_DESC, mut special: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut qflags: libc::c_int = 0; + if ((*w).word).is_null() + || *((*w).word).offset(0 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + expand_no_split_dollar_star = 1 as libc::c_int; + (*w).flags |= (1 as libc::c_int) << 6 as libc::c_int; + l = call_expand_word_internal( + w, + 0 as libc::c_int, + 0 as libc::c_int, + 0 as *mut libc::c_int, + 0 as *mut libc::c_int, + ); + expand_no_split_dollar_star = 0 as libc::c_int; + if !l.is_null() { + if special == 0 as libc::c_int { + if !((*l).word).is_null() { + word_list_remove_quoted_nulls(l); + } + dequote_list(l); + r = string_list(l); + } else { + qflags = 0x1 as libc::c_int | 0x8 as libc::c_int; + if special == 2 as libc::c_int { + qflags |= 0x4 as libc::c_int; + } + word_list_remove_quoted_nulls(l); + p = string_list(l); + r = quote_string_for_globbing(p, qflags); + sh_xfree( + p as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3711 as libc::c_int, + ); + } + dispose_words(l); + } else { + r = 0 as *mut libc::c_void as *mut libc::c_char; + } + + return r; + } +} +fn call_expand_word_internal( + mut w: *mut WORD_DESC, + mut q: libc::c_int, + mut i: libc::c_int, + mut c: *mut libc::c_int, + mut e: *mut libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + result = expand_word_internal(w, q, i, c, e); + if result == &mut expand_word_error as *mut WORD_LIST + || result == &mut expand_word_fatal as *mut WORD_LIST + { + let ref mut fresh22 = (*w).word; + *fresh22 = 0 as *mut libc::c_void as *mut libc::c_char; + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + exp_jump_to_top_level(if result == &mut expand_word_error as *mut WORD_LIST { + 2 as libc::c_int + } else { + 1 as libc::c_int + }); + return 0 as *mut WORD_LIST; + } else { + return result; + }; + } +} +fn expand_string_internal( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + let mut tresult: *mut WORD_LIST = 0 as *mut WORD_LIST; + if string.is_null() || *string as libc::c_int == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + td.flags = 0 as libc::c_int; + td.word = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3765 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + tresult = call_expand_word_internal( + &mut td, + quoted, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if !(td.word).is_null() { + sh_xfree( + td.word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3769 as libc::c_int, + ); + } + + return tresult; + } +} +#[no_mangle] +pub fn expand_string_unsplit( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut value: *mut WORD_LIST = 0 as *mut WORD_LIST; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + expand_no_split_dollar_star = 1 as libc::c_int; + value = expand_string_internal(string, quoted); + expand_no_split_dollar_star = 0 as libc::c_int; + if !value.is_null() { + if !((*value).word).is_null() { + remove_quoted_nulls((*(*value).word).word); + (*(*value).word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + } + dequote_list(value); + } + + return value; + } +} +#[no_mangle] +pub fn expand_string_assignment( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + let mut value: *mut WORD_LIST = 0 as *mut WORD_LIST; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + expand_no_split_dollar_star = 1 as libc::c_int; + td.flags = (1 as libc::c_int) << 11 as libc::c_int; + td.word = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3828 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + value = call_expand_word_internal( + &mut td, + quoted, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + if !(td.word).is_null() { + sh_xfree( + td.word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3830 as libc::c_int, + ); + } + expand_no_split_dollar_star = 0 as libc::c_int; + if !value.is_null() { + if !((*value).word).is_null() { + remove_quoted_nulls((*(*value).word).word); + (*(*value).word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + } + dequote_list(value); + } + + return value; + } +} +#[no_mangle] +pub fn expand_prompt_string( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, + mut wflags: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut value: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + if string.is_null() || *string as libc::c_int == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + td.flags = wflags; + td.word = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3864 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + no_longjmp_on_fatal_error = 1 as libc::c_int; + value = expand_word_internal( + &mut td, + quoted, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + no_longjmp_on_fatal_error = 0 as libc::c_int; + if value == &mut expand_word_error as *mut WORD_LIST + || value == &mut expand_word_fatal as *mut WORD_LIST + { + value = make_word_list( + make_bare_word(string), + 0 as *mut libc::c_void as *mut WORD_LIST, + ); + return value; + } + if !(td.word).is_null() { + sh_xfree( + td.word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 3875 as libc::c_int, + ); + } + if !value.is_null() { + if !((*value).word).is_null() { + remove_quoted_nulls((*(*value).word).word); + (*(*value).word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + } + dequote_list(value); + } + + return value; + } +} +fn expand_string_leave_quoted( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut tlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tresult: *mut WORD_LIST = 0 as *mut WORD_LIST; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + tlist = expand_string_internal(string, quoted); + if !tlist.is_null() { + tresult = word_list_split(tlist); + dispose_words(tlist); + return tresult; + } + } + return 0 as *mut libc::c_void as *mut WORD_LIST; +} +fn expand_string_for_rhs( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, + mut op: libc::c_int, + mut pflags: libc::c_int, + mut dollar_at_p: *mut libc::c_int, + mut expanded_p: *mut libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + let mut tresult: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut old_nosplit: libc::c_int = 0; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + old_nosplit = expand_no_split_dollar_star; + expand_no_split_dollar_star = (quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + || op == '=' as i32 + || ifs_is_null == 0 as libc::c_int) + as libc::c_int; + td.flags = (1 as libc::c_int) << 14 as libc::c_int; + td.flags |= (1 as libc::c_int) << 6 as libc::c_int; + if pflags & 0x8 as libc::c_int != 0 { + td.flags |= (1 as libc::c_int) << 11 as libc::c_int; + } + if op == '=' as i32 { + td.flags |= + (1 as libc::c_int) << 11 as libc::c_int | (1 as libc::c_int) << 29 as libc::c_int; + } + td.word = string; + tresult = + call_expand_word_internal(&mut td, quoted, 1 as libc::c_int, dollar_at_p, expanded_p); + expand_no_split_dollar_star = old_nosplit; + + return tresult; + } +} +fn expand_string_for_pat( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, + mut dollar_at_p: *mut libc::c_int, + mut expanded_p: *mut libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut td: WORD_DESC = WORD_DESC { + word: 0 as *const libc::c_char as *mut libc::c_char, + flags: 0, + }; + let mut tresult: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut oexp: libc::c_int = 0; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + oexp = expand_no_split_dollar_star; + expand_no_split_dollar_star = 1 as libc::c_int; + td.flags = (1 as libc::c_int) << 6 as libc::c_int; + td.word = string; + tresult = + call_expand_word_internal(&mut td, quoted, 1 as libc::c_int, dollar_at_p, expanded_p); + expand_no_split_dollar_star = oexp; + + return tresult; + } +} +#[no_mangle] +pub fn expand_string(mut string: *mut libc::c_char, mut quoted: libc::c_int) -> *mut WORD_LIST { + unsafe { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + if string.is_null() || *string as libc::c_int == '\u{0}' as i32 { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + result = expand_string_leave_quoted(string, quoted); + return if !result.is_null() { + dequote_list(result) + } else { + result + }; + } +} +#[no_mangle] +pub fn expand_word(mut word: *mut WORD_DESC, mut quoted: libc::c_int) -> *mut WORD_LIST { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tresult: *mut WORD_LIST = 0 as *mut WORD_LIST; + tresult = call_expand_word_internal( + word, + quoted, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + result = word_list_split(tresult); + dispose_words(tresult); + return if !result.is_null() { + dequote_list(result) + } else { + result + }; +} +#[no_mangle] +pub fn expand_word_unsplit(mut word: *mut WORD_DESC, mut quoted: libc::c_int) -> *mut WORD_LIST { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + result = expand_word_leave_quoted(word, quoted); + return if !result.is_null() { + dequote_list(result) + } else { + result + }; +} +#[no_mangle] +pub fn expand_word_leave_quoted( + mut word: *mut WORD_DESC, + mut quoted: libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + expand_no_split_dollar_star = 1 as libc::c_int; + if ifs_is_null != 0 { + (*word).flags |= (1 as libc::c_int) << 4 as libc::c_int; + } + (*word).flags |= (1 as libc::c_int) << 6 as libc::c_int; + result = call_expand_word_internal( + word, + quoted, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + expand_no_split_dollar_star = 0 as libc::c_int; + + return result; + } +} +fn quote_escapes_internal( + mut string: *const libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut s: *const libc::c_char = 0 as *const libc::c_char; + let mut send: *const libc::c_char = 0 as *const libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut slen: size_t = 0; + let mut quote_spaces: libc::c_int = 0; + let mut skip_ctlesc: libc::c_int = 0; + let mut skip_ctlnul: libc::c_int = 0; + let mut nosplit: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + send = string.offset(slen as isize); + quote_spaces = + (!ifs_value.is_null() && *ifs_value as libc::c_int == 0 as libc::c_int) as libc::c_int; + nosplit = flags & 0x4 as libc::c_int; + skip_ctlnul = 0 as libc::c_int; + skip_ctlesc = skip_ctlnul; + s = ifs_value; + while !s.is_null() && *s as libc::c_int != 0 { + skip_ctlesc |= + (nosplit == 0 as libc::c_int && *s as libc::c_int == '\u{1}' as i32) as libc::c_int; + skip_ctlnul |= (nosplit == 0 as libc::c_int && *s as libc::c_int == '\u{7f}' as i32) + as libc::c_int; + s = s.offset(1); + } + result = sh_xmalloc( + slen.wrapping_mul(2 as libc::c_int as libc::c_ulong) + .wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4109 as libc::c_int, + ) as *mut libc::c_char; + t = result; + s = string; + while *s != 0 { + if skip_ctlesc == 0 as libc::c_int && *s as libc::c_int == '\u{1}' as i32 + || skip_ctlnul == 0 as libc::c_int && *s as libc::c_int == '\u{7f}' as i32 + || quote_spaces != 0 && *s as libc::c_int == ' ' as i32 + { + let fresh23 = t; + t = t.offset(1); + *fresh23 = '\u{1}' as i32 as libc::c_char; + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*s); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = (*s as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen(s, send.offset_from(s) as libc::c_long as size_t, &mut state); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh24 = s; + s = s.offset(1); + let fresh25 = t; + t = t.offset(1); + *fresh25 = *fresh24; + _k += 1; + } + } else { + let fresh26 = s; + s = s.offset(1); + let fresh27 = t; + t = t.offset(1); + *fresh27 = *fresh26; + } + } + *t = '\u{0}' as i32 as libc::c_char; + + return result; + } +} +#[no_mangle] +pub fn quote_escapes(mut string: *const libc::c_char) -> *mut libc::c_char { + return quote_escapes_internal(string, 0 as libc::c_int); +} +#[no_mangle] +pub fn quote_rhs(mut string: *const libc::c_char) -> *mut libc::c_char { + return quote_escapes_internal(string, 0x4 as libc::c_int); +} +fn list_quote_escapes(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + unsafe { + let mut w: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + w = list; + while !w.is_null() { + t = (*(*w).word).word; + let ref mut fresh28 = (*(*w).word).word; + *fresh28 = quote_escapes(t); + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4148 as libc::c_int, + ); + w = (*w).next; + } + } + return list; +} +#[no_mangle] +pub fn dequote_escapes(mut string: *const libc::c_char) -> *mut libc::c_char { + let mut s: *const libc::c_char = 0 as *const libc::c_char; + let mut send: *const libc::c_char = 0 as *const libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut slen: size_t = 0; + let mut quote_spaces: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if string.is_null() { + return 0 as *mut libc::c_char; + } + slen = strlen(string) as u64; + send = string.offset(slen as isize); + result = sh_xmalloc( + slen.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4180 as libc::c_int, + ) as *mut libc::c_char; + t = result; + if (strchr(string, '\u{1}' as i32)).is_null() { + return strcpy(result, string); + } + quote_spaces = + (!ifs_value.is_null() && *ifs_value as libc::c_int == 0 as libc::c_int) as libc::c_int; + s = string; + while *s != 0 { + if *s as libc::c_int == '\u{1}' as i32 + && (*s.offset(1 as libc::c_int as isize) as libc::c_int == '\u{1}' as i32 + || *s.offset(1 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + || quote_spaces != 0 + && *s.offset(1 as libc::c_int as isize) as libc::c_int == ' ' as i32) + { + s = s.offset(1); + if *s as libc::c_int == '\u{0}' as i32 { + break; + } + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*s); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = (*s as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen(s, send.offset_from(s) as libc::c_long as size_t, &mut state); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh29 = s; + s = s.offset(1); + let fresh30 = t; + t = t.offset(1); + *fresh30 = *fresh29; + _k += 1; + } + } else { + let fresh31 = s; + s = s.offset(1); + let fresh32 = t; + t = t.offset(1); + *fresh32 = *fresh31; + } + } + *t = '\u{0}' as i32 as libc::c_char; + } + return result; +} +fn make_quoted_char(mut c: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + temp = sh_xmalloc( + 3 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4230 as libc::c_int, + ) as *mut libc::c_char; + if c == 0 as libc::c_int { + *temp.offset(0 as libc::c_int as isize) = '\u{7f}' as i32 as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } else { + *temp.offset(0 as libc::c_int as isize) = '\u{1}' as i32 as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = c as libc::c_char; + *temp.offset(2 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } + return temp; + } +} +#[no_mangle] +pub fn quote_string(mut string: *mut libc::c_char) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut slen: size_t = 0; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if *string as libc::c_int == 0 as libc::c_int { + result = sh_xmalloc( + 2 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4258 as libc::c_int, + ) as *mut libc::c_char; + *result.offset(0 as libc::c_int as isize) = '\u{7f}' as i32 as libc::c_char; + *result.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } else { + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + send = string.offset(slen as isize); + result = sh_xmalloc( + slen.wrapping_mul(2 as libc::c_int as libc::c_ulong) + .wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4269 as libc::c_int, + ) as *mut libc::c_char; + t = result; + while string < send { + let fresh33 = t; + t = t.offset(1); + *fresh33 = '\u{1}' as i32 as libc::c_char; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*string); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = + (*string as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string, + send.offset_from(string) as libc::c_long as size_t, + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh34 = string; + string = string.offset(1); + let fresh35 = t; + t = t.offset(1); + *fresh35 = *fresh34; + _k += 1; + } + } else { + let fresh36 = string; + string = string.offset(1); + let fresh37 = t; + t = t.offset(1); + *fresh37 = *fresh36; + } + } + *t = '\u{0}' as i32 as libc::c_char; + } + } + return result; +} +#[no_mangle] +pub fn dequote_string(mut string: *mut libc::c_char) -> *mut libc::c_char { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut slen: size_t = 0; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = if !string.is_null() && *string.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *string.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *string.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(string) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + result = sh_xmalloc( + slen.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4298 as libc::c_int, + ) as *mut libc::c_char; + t = result; + if *string.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *string.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + *result.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + return result; + } + if *string.offset(0 as libc::c_int as isize) as libc::c_int == '\u{1}' as i32 + && *string.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + *result.offset(0 as libc::c_int as isize) = '\u{1}' as i32 as libc::c_char; + *result.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + return result; + } + if (strchr(string, '\u{1}' as i32)).is_null() { + return strcpy(result, string); + } + send = string.offset(slen as isize); + s = string; + while *s != 0 { + if *s as libc::c_int == '\u{1}' as i32 { + s = s.offset(1); + if *s as libc::c_int == '\u{0}' as i32 { + break; + } + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*s); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = (*s as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen(s, send.offset_from(s) as libc::c_long as size_t, &mut state); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh38 = s; + s = s.offset(1); + let fresh39 = t; + t = t.offset(1); + *fresh39 = *fresh38; + _k += 1; + } + } else { + let fresh40 = s; + s = s.offset(1); + let fresh41 = t; + t = t.offset(1); + *fresh41 = *fresh40; + } + } + *t = '\u{0}' as i32 as libc::c_char; + } + return result; +} +fn quote_list(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + let mut w: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + w = list; + unsafe { + while !w.is_null() { + t = (*(*w).word).word; + let ref mut fresh42 = (*(*w).word).word; + *fresh42 = quote_string(t); + if *t as libc::c_int == 0 as libc::c_int { + (*(*w).word).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } + (*(*w).word).flags |= (1 as libc::c_int) << 1 as libc::c_int; + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4351 as libc::c_int, + ); + w = (*w).next; + } + } + return list; +} +#[no_mangle] +pub fn dequote_word(mut word: *mut WORD_DESC) -> *mut WORD_DESC { + unsafe { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + s = dequote_string((*word).word); + if *((*word).word).offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *((*word).word).offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + (*word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + } + sh_xfree( + (*word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4365 as libc::c_int, + ); + let ref mut fresh43 = (*word).word; + *fresh43 = s; + } + return word; +} +#[no_mangle] +pub fn dequote_list(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + tlist = list; + unsafe { + while !tlist.is_null() { + s = dequote_string((*(*tlist).word).word); + if *((*(*tlist).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *((*(*tlist).word).word).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + (*(*tlist).word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + } + sh_xfree( + (*(*tlist).word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4384 as libc::c_int, + ); + let ref mut fresh44 = (*(*tlist).word).word; + *fresh44 = s; + tlist = (*tlist).next; + } + } + return list; +} +#[no_mangle] +pub fn remove_quoted_escapes(mut string: *mut libc::c_char) -> *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if !string.is_null() { + t = dequote_escapes(string); + strcpy(string, t); + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4402 as libc::c_int, + ); + } + } + return string; +} +#[no_mangle] +pub fn remove_quoted_ifs(mut string: *mut libc::c_char) -> *mut libc::c_char { + let mut slen: size_t = 0; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + send = string.offset(slen as isize); + j = 0 as libc::c_int; + i = j; + ret = sh_xmalloc( + slen.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4425 as libc::c_int, + ) as *mut libc::c_char; + while (i as libc::c_ulong) < slen { + if *string.offset(i as isize) as libc::c_int == '\u{1}' as i32 { + i += 1; + if *string.offset(i as isize) as libc::c_int == 0 as libc::c_int + || (ifs_cmap[*string.offset(i as isize) as libc::c_uchar as usize] + as libc::c_int + != 0 as libc::c_int) as libc::c_int + == 0 as libc::c_int + { + let fresh45 = j; + j = j + 1; + *ret.offset(fresh45 as isize) = '\u{1}' as i32 as libc::c_char; + } + if i as libc::c_ulong == slen { + break; + } + } + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*string.offset(i as isize)); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + send.offset_from(string.offset(i as isize)) as libc::c_long as size_t, + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh46 = i; + i = i + 1; + let fresh47 = j; + j = j + 1; + *ret.offset(fresh47 as isize) = *string.offset(fresh46 as isize); + _k += 1; + } + } else { + let fresh48 = i; + i = i + 1; + let fresh49 = j; + j = j + 1; + *ret.offset(fresh49 as isize) = *string.offset(fresh48 as isize); + } + } + *ret.offset(j as isize) = '\u{0}' as i32 as libc::c_char; + } + return ret; +} +#[no_mangle] +pub fn remove_quoted_nulls(mut string: *mut libc::c_char) -> *mut libc::c_char { + let mut slen: size_t = 0; + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut prev_i: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if (strchr(string, '\u{7f}' as i32)).is_null() { + return string; + } + slen = strlen(string) as u64; + j = 0 as libc::c_int; + i = j; + while (i as libc::c_ulong) < slen { + if *string.offset(i as isize) as libc::c_int == '\u{1}' as i32 { + i += 1; + let fresh50 = j; + j = j + 1; + *string.offset(fresh50 as isize) = '\u{1}' as i32 as libc::c_char; + if i as libc::c_ulong == slen { + break; + } + } else if *string.offset(i as isize) as libc::c_int == '\u{7f}' as i32 { + i += 1; + continue; + } + prev_i = i; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(i as isize), + slen.wrapping_sub(i as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int as libc::c_int; + } + } else { + i += 1; + } + if j < prev_i { + loop { + let fresh51 = prev_i; + prev_i = prev_i + 1; + let fresh52 = j; + j = j + 1; + *string.offset(fresh52 as isize) = *string.offset(fresh51 as isize); + if !(prev_i < i) { + break; + } + } + } else { + j = i; + } + } + *string.offset(j as isize) = '\u{0}' as i32 as libc::c_char; + } + return string; +} +#[no_mangle] +pub fn word_list_remove_quoted_nulls(mut list: *mut WORD_LIST) { + let mut t: *mut WORD_LIST = 0 as *mut WORD_LIST; + t = list; + unsafe { + while !t.is_null() { + remove_quoted_nulls((*(*t).word).word); + (*(*t).word).flags &= !((1 as libc::c_int) << 18 as libc::c_int); + t = (*t).next; + } + } +} +fn remove_upattern( + mut param: *mut libc::c_char, + mut pattern: *mut libc::c_char, + mut op: libc::c_int, +) -> *mut libc::c_char { + let mut len: size_t = 0; + let mut end: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut c: libc::c_char = 0; + unsafe { + len = if !param.is_null() && *param.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *param.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *param.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(param) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + end = param.offset(len as isize); + match op { + 1 => { + p = end; + while p >= param { + c = *p; + *p = '\u{0}' as i32 as libc::c_char; + if strmatch( + pattern, + param, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + *p = c; + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(p) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4575 as libc::c_int, + ) as *mut libc::c_char, + p, + ); + } + *p = c; + p = p.offset(-1); + } + } + 2 => { + p = param; + while p <= end { + c = *p; + *p = '\u{0}' as i32 as libc::c_char; + if strmatch( + pattern, + param, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + *p = c; + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(p) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4589 as libc::c_int, + ) as *mut libc::c_char, + p, + ); + } + *p = c; + p = p.offset(1); + } + } + 3 => { + p = param; + while p <= end { + if strmatch( + pattern, + p, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + c = *p; + *p = '\u{0}' as i32 as libc::c_char; + ret = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4601 as libc::c_int, + ) as *mut libc::c_char, + param, + ); + *p = c; + return ret; + } + p = p.offset(1); + } + } + 4 => { + p = end; + while p >= param { + if strmatch( + pattern, + p, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + c = *p; + *p = '\u{0}' as i32 as libc::c_char; + ret = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4614 as libc::c_int, + ) as *mut libc::c_char, + param, + ); + *p = c; + return ret; + } + p = p.offset(-1); + } + } + _ => {} + } + } + return param; +} +fn remove_wpattern( + mut wparam: *mut wchar_t, + mut wstrlen: size_t, + mut wpattern: *mut wchar_t, + mut op: libc::c_int, +) -> *mut wchar_t { + let mut wc: wchar_t = 0; + let mut ret: *mut wchar_t = 0 as *mut wchar_t; + let mut n: libc::c_int = 0; + unsafe { + match op { + 1 => { + n = wstrlen as libc::c_int; + while n >= 0 as libc::c_int { + wc = *wparam.offset(n as isize); + *wparam.offset(n as isize) = '\u{0}' as i32; + if wcsmatch( + wpattern, + wparam, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + *wparam.offset(n as isize) = wc; + return wcsdup(wparam.offset(n as isize)); + } + *wparam.offset(n as isize) = wc; + n -= 1; + } + } + 2 => { + n = 0 as libc::c_int; + while n as libc::c_ulong <= wstrlen { + wc = *wparam.offset(n as isize); + *wparam.offset(n as isize) = '\u{0}' as i32; + if wcsmatch( + wpattern, + wparam, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + *wparam.offset(n as isize) = wc; + return wcsdup(wparam.offset(n as isize)); + } + *wparam.offset(n as isize) = wc; + n += 1; + } + } + 3 => { + n = 0 as libc::c_int; + while n as libc::c_ulong <= wstrlen { + if wcsmatch( + wpattern, + wparam.offset(n as isize), + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + wc = *wparam.offset(n as isize); + *wparam.offset(n as isize) = '\u{0}' as i32; + ret = wcsdup(wparam); + *wparam.offset(n as isize) = wc; + return ret; + } + n += 1; + } + } + 4 => { + n = wstrlen as libc::c_int; + while n >= 0 as libc::c_int { + if wcsmatch( + wpattern, + wparam.offset(n as isize), + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }), + ) != 1 as libc::c_int + { + wc = *wparam.offset(n as isize); + *wparam.offset(n as isize) = '\u{0}' as i32; + ret = wcsdup(wparam); + *wparam.offset(n as isize) = wc; + return ret; + } + n -= 1; + } + } + _ => {} + } + } + return wparam; +} +fn remove_pattern( + mut param: *mut libc::c_char, + mut pattern: *mut libc::c_char, + mut op: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut xret: *mut libc::c_char = 0 as *mut libc::c_char; + if param.is_null() { + return param; + } + if *param as libc::c_int == '\u{0}' as i32 + || pattern.is_null() + || *pattern as libc::c_int == '\u{0}' as i32 + { + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4706 as libc::c_int, + ) as *mut libc::c_char, + param, + ); + } + if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + let mut ret: *mut wchar_t = 0 as *mut wchar_t; + let mut oret: *mut wchar_t = 0 as *mut wchar_t; + let mut n: size_t = 0; + let mut wparam: *mut wchar_t = 0 as *mut wchar_t; + let mut wpattern: *mut wchar_t = 0 as *mut wchar_t; + let mut ps: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + n = xdupmbstowcs(&mut wpattern, 0 as *mut *mut *mut libc::c_char, pattern); + if n == -(1 as libc::c_int) as size_t { + xret = remove_upattern(param, pattern, op); + return if xret == param { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4723 as libc::c_int, + ) as *mut libc::c_char, + param, + ) + } else { + xret + }; + } + n = xdupmbstowcs(&mut wparam, 0 as *mut *mut *mut libc::c_char, param); + if n == -(1 as libc::c_int) as size_t { + sh_xfree( + wpattern as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4729 as libc::c_int, + ); + xret = remove_upattern(param, pattern, op); + return if xret == param { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4731 as libc::c_int, + ) as *mut libc::c_char, + param, + ) + } else { + xret + }; + } + ret = remove_wpattern(wparam, n, wpattern, op); + oret = ret; + if ret == wparam { + sh_xfree( + wparam as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4738 as libc::c_int, + ); + sh_xfree( + wpattern as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4739 as libc::c_int, + ); + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4740 as libc::c_int, + ) as *mut libc::c_char, + param, + ); + } + sh_xfree( + wparam as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4743 as libc::c_int, + ); + sh_xfree( + wpattern as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4744 as libc::c_int, + ); + n = strlen(param) as u64; + xret = sh_xmalloc( + n.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4747 as libc::c_int, + ) as *mut libc::c_char; + memset( + &mut ps as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + n = wcsrtombs( + xret, + &mut ret as *mut *mut wchar_t as *mut *const wchar_t, + n as usize, + &mut ps, + ) as u64; + *xret.offset(n as isize) = '\u{0}' as i32 as libc::c_char; + sh_xfree( + oret as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4751 as libc::c_int, + ); + return xret; + } else { + xret = remove_upattern(param, pattern, op); + return if xret == param { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(param) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4758 as libc::c_int, + ) as *mut libc::c_char, + param, + ) + } else { + xret + }; + }; + } +} +fn match_upattern( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut mtype: libc::c_int, + mut sp: *mut *mut libc::c_char, + mut ep: *mut *mut libc::c_char, +) -> libc::c_int { + unsafe { + let mut c: libc::c_int = 0; + let mut mlen: libc::c_int = 0; + let mut len: size_t = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut npat: *mut libc::c_char = 0 as *mut libc::c_char; + let mut end: *mut libc::c_char = 0 as *mut libc::c_char; + len = if !pat.is_null() && *pat.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *pat.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *pat.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(pat) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + if *pat.offset(0 as libc::c_int as isize) as libc::c_int != '*' as i32 + || *pat.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + && *pat.offset(1 as libc::c_int as isize) as libc::c_int == '(' as i32 + && extended_glob != 0 + || *pat.offset(len.wrapping_sub(1 as libc::c_int as libc::c_ulong) as isize) + as libc::c_int + != '*' as i32 + { + let mut unescaped_backslash: libc::c_int = 0; + let mut pp: *mut libc::c_char = 0 as *mut libc::c_char; + npat = sh_xmalloc( + len.wrapping_add(3 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4793 as libc::c_int, + ) as *mut libc::c_char; + p = npat; + p1 = pat; + if mtype != 0x1 as libc::c_int + && (*p1 as libc::c_int != '*' as i32 + || *p1 as libc::c_int == '*' as i32 + && *p1.offset(1 as libc::c_int as isize) as libc::c_int == '(' as i32 + && extended_glob != 0) + { + let fresh53 = p; + p = p.offset(1); + *fresh53 = '*' as i32 as libc::c_char; + } + while *p1 != 0 { + let fresh54 = p1; + p1 = p1.offset(1); + let fresh55 = p; + p = p.offset(1); + *fresh55 = *fresh54; + } + if mtype != 0x2 as libc::c_int + && (*p1.offset(-(1 as libc::c_int) as isize) as libc::c_int == '*' as i32 && { + unescaped_backslash = (*p1.offset(-(2 as libc::c_int) as isize) as libc::c_int + == '\\' as i32) as libc::c_int; + unescaped_backslash != 0 + }) + { + pp = p1.offset(-(3 as libc::c_int as isize)); + while pp >= pat && { + let fresh56 = pp; + pp = pp.offset(-1); + *fresh56 as libc::c_int == '\\' as i32 + } { + unescaped_backslash = 1 as libc::c_int - unescaped_backslash; + } + if unescaped_backslash != 0 { + let fresh57 = p; + p = p.offset(1); + *fresh57 = '*' as i32 as libc::c_char; + } + } else if mtype != 0x2 as libc::c_int + && *p1.offset(-(1 as libc::c_int) as isize) as libc::c_int != '*' as i32 + { + let fresh58 = p; + p = p.offset(1); + *fresh58 = '*' as i32 as libc::c_char; + } + *p = '\u{0}' as i32 as libc::c_char; + } else { + npat = pat; + } + c = strmatch( + npat, + string, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ); + if npat != pat { + sh_xfree( + npat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4826 as libc::c_int, + ); + } + if c == 1 as libc::c_int { + return 0 as libc::c_int; + } + len = if !string.is_null() && *string.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *string.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *string.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(string) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + end = string.offset(len as isize); + mlen = umatchlen(pat, len); + if mlen > len as libc::c_int { + return 0 as libc::c_int; + } + match mtype { + 0 => { + p = string; + while p <= end { + if match_pattern_char( + pat, + p, + if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }, + ) != 0 + { + p1 = if mlen == -(1 as libc::c_int) { + end + } else { + p.offset(mlen as isize) + }; + if p1 > end { + break; + } + while p1 >= p { + c = *p1 as libc::c_int; + *p1 = '\u{0}' as i32 as libc::c_char; + if strmatch( + pat, + p, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + *p1 = c as libc::c_char; + *sp = p; + *ep = p1; + return 1 as libc::c_int; + } + *p1 = c as libc::c_char; + if mlen != -(1 as libc::c_int) { + break; + } + p1 = p1.offset(-1); + } + } + p = p.offset(1); + } + return 0 as libc::c_int; + } + 1 => { + if match_pattern_char( + pat, + string, + (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + return 0 as libc::c_int; + } + p = if mlen == -(1 as libc::c_int) { + end + } else { + string.offset(mlen as isize) + }; + while p >= string { + c = *p as libc::c_int; + *p = '\u{0}' as i32 as libc::c_char; + if strmatch( + pat, + string, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + *p = c as libc::c_char; + *sp = string; + *ep = p; + return 1 as libc::c_int; + } + *p = c as libc::c_char; + if mlen != -(1 as libc::c_int) { + break; + } + p = p.offset(-1); + } + return 0 as libc::c_int; + } + 2 => { + p = end.offset( + -((if mlen == -(1 as libc::c_int) { + len + } else { + mlen as libc::c_ulong + }) as isize), + ); + while p <= end { + if strmatch( + pat, + p, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + *sp = p; + *ep = end; + return 1 as libc::c_int; + } + if mlen != -(1 as libc::c_int) { + break; + } + p = p.offset(1); + } + return 0 as libc::c_int; + } + _ => {} + } + } + return 0 as libc::c_int; +} +fn match_wpattern( + mut wstring: *mut wchar_t, + mut indices: *mut *mut libc::c_char, + mut wstrlen: size_t, + mut wpat: *mut wchar_t, + mut mtype: libc::c_int, + mut sp: *mut *mut libc::c_char, + mut ep: *mut *mut libc::c_char, +) -> libc::c_int { + let mut wc: wchar_t = 0; + let mut wp: *mut wchar_t = 0 as *mut wchar_t; + let mut nwpat: *mut wchar_t = 0 as *mut wchar_t; + let mut wp1: *mut wchar_t = 0 as *mut wchar_t; + let mut len: size_t = 0; + let mut mlen: libc::c_int = 0; + let mut n: libc::c_int = 0; + let mut n1: libc::c_int = 0; + let mut n2: libc::c_int = 0; + let mut simple: libc::c_int = 0; + unsafe { + simple = (*wpat.offset(0 as libc::c_int as isize) != '\\' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '*' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '?' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '[' as i32) + as libc::c_int; + if extended_glob != 0 { + simple &= (*wpat.offset(1 as libc::c_int as isize) != '(' as i32 + || *wpat.offset(0 as libc::c_int as isize) != '*' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '?' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '+' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '!' as i32 + && *wpat.offset(0 as libc::c_int as isize) != '@' as i32) + as libc::c_int; + } + len = wcslen(wpat as *const wchar_t) as u64; + if *wpat.offset(0 as libc::c_int as isize) != '*' as i32 + || *wpat.offset(0 as libc::c_int as isize) == '*' as i32 + && *wpat.offset(1 as libc::c_int as isize) == '(' as i32 + && extended_glob != 0 + || *wpat.offset(len.wrapping_sub(1 as libc::c_int as libc::c_ulong) as isize) + != '*' as i32 + { + let mut unescaped_backslash: libc::c_int = 0; + let mut wpp: *mut wchar_t = 0 as *mut wchar_t; + nwpat = sh_xmalloc( + len.wrapping_add(3 as libc::c_int as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4958 as libc::c_int, + ) as *mut wchar_t; + wp = nwpat; + wp1 = wpat; + if *wp1 != '*' as i32 + || *wp1 == '*' as i32 + && *wp1.offset(1 as libc::c_int as isize) == '(' as i32 + && extended_glob != 0 + { + let fresh59 = wp; + wp = wp.offset(1); + *fresh59 = '*' as i32; + } + while *wp1 != '\u{0}' as i32 { + let fresh60 = wp1; + wp1 = wp1.offset(1); + let fresh61 = wp; + wp = wp.offset(1); + *fresh61 = *fresh60; + } + if *wp1.offset(-(1 as libc::c_int) as isize) == '*' as i32 && { + unescaped_backslash = + (*wp1.offset(-(2 as libc::c_int) as isize) == '\\' as i32) as libc::c_int; + unescaped_backslash != 0 + } { + wpp = wp1.offset(-(3 as libc::c_int as isize)); + while wpp >= wpat && { + let fresh62 = wpp; + wpp = wpp.offset(-1); + *fresh62 == '\\' as i32 + } { + unescaped_backslash = 1 as libc::c_int - unescaped_backslash; + } + if unescaped_backslash != 0 { + let fresh63 = wp; + wp = wp.offset(1); + *fresh63 = '*' as i32; + } + } else if *wp1.offset(-(1 as libc::c_int) as isize) != '*' as i32 { + let fresh64 = wp; + wp = wp.offset(1); + *fresh64 = '*' as i32; + } + *wp = '\u{0}' as i32; + } else { + nwpat = wpat; + } + len = wcsmatch( + nwpat, + wstring, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) as size_t; + if nwpat != wpat { + sh_xfree( + nwpat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 4986 as libc::c_int, + ); + } + if len == 1 as libc::c_int as libc::c_ulong { + return 0 as libc::c_int; + } + mlen = wmatchlen(wpat, wstrlen); + if mlen > wstrlen as libc::c_int { + return 0 as libc::c_int; + } + match mtype { + 0 => { + n = 0 as libc::c_int; + while n as libc::c_ulong <= wstrlen { + n2 = if simple != 0 { + ((if match_ignore_case != 0 && iswupper(*wpat as wint_t) != 0 { + towlower(*wpat as wint_t) + } else { + *wpat as libc::c_uint + }) == (if match_ignore_case != 0 + && iswupper(*wstring.offset(n as isize) as wint_t) != 0 + { + towlower(*wstring.offset(n as isize) as wint_t) + } else { + *wstring.offset(n as isize) as libc::c_uint + })) as libc::c_int + } else { + match_pattern_wchar( + wpat, + wstring.offset(n as isize), + if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }, + ) + }; + if n2 != 0 { + n1 = (if mlen == -(1 as libc::c_int) { + wstrlen + } else { + (n + mlen) as libc::c_ulong + }) as libc::c_int; + if n1 as libc::c_ulong > wstrlen { + break; + } + while n1 >= n { + wc = *wstring.offset(n1 as isize); + *wstring.offset(n1 as isize) = '\u{0}' as i32; + if wcsmatch( + wpat, + wstring.offset(n as isize), + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + *wstring.offset(n1 as isize) = wc; + *sp = *indices.offset(n as isize); + *ep = *indices.offset(n1 as isize); + return 1 as libc::c_int; + } + *wstring.offset(n1 as isize) = wc; + if mlen != -(1 as libc::c_int) { + break; + } + n1 -= 1; + } + } + n += 1; + } + return 0 as libc::c_int; + } + 1 => { + if match_pattern_wchar( + wpat, + wstring, + (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + return 0 as libc::c_int; + } + n = (if mlen == -(1 as libc::c_int) { + wstrlen + } else { + mlen as libc::c_ulong + }) as libc::c_int; + while n >= 0 as libc::c_int { + wc = *wstring.offset(n as isize); + *wstring.offset(n as isize) = '\u{0}' as i32; + if wcsmatch( + wpat, + wstring, + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + *wstring.offset(n as isize) = wc; + *sp = *indices.offset(0 as libc::c_int as isize); + *ep = *indices.offset(n as isize); + return 1 as libc::c_int; + } + *wstring.offset(n as isize) = wc; + if mlen != -(1 as libc::c_int) { + break; + } + n -= 1; + } + return 0 as libc::c_int; + } + 2 => { + n = wstrlen.wrapping_sub( + (if mlen == -(1 as libc::c_int) { + wstrlen + } else { + mlen as libc::c_ulong + }), + ) as libc::c_int; + while n as libc::c_ulong <= wstrlen { + if wcsmatch( + wpat, + wstring.offset(n as isize), + (if extended_glob != 0 { + (1 as libc::c_int) << 5 as libc::c_int + } else { + 0 as libc::c_int + }) | (if match_ignore_case != 0 { + (1 as libc::c_int) << 4 as libc::c_int + } else { + 0 as libc::c_int + }), + ) == 0 as libc::c_int + { + *sp = *indices.offset(n as isize); + *ep = *indices.offset(wstrlen as isize); + return 1 as libc::c_int; + } + if mlen != -(1 as libc::c_int) { + break; + } + n += 1; + } + return 0 as libc::c_int; + } + _ => {} + } + } + return 0 as libc::c_int; +} +fn match_pattern( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut mtype: libc::c_int, + mut sp: *mut *mut libc::c_char, + mut ep: *mut *mut libc::c_char, +) -> libc::c_int { + let mut ret: libc::c_int = 0; + let mut n: size_t = 0; + let mut wstring: *mut wchar_t = 0 as *mut wchar_t; + let mut wpat: *mut wchar_t = 0 as *mut wchar_t; + let mut indices: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + unsafe { + if string.is_null() || pat.is_null() || *pat as libc::c_int == 0 as libc::c_int { + return 0 as libc::c_int; + } + if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if (mbsmbchar(string)).is_null() && (mbsmbchar(pat)).is_null() { + return match_upattern(string, pat, mtype, sp, ep); + } + n = xdupmbstowcs(&mut wpat, 0 as *mut *mut *mut libc::c_char, pat); + if n == -(1 as libc::c_int) as size_t { + return match_upattern(string, pat, mtype, sp, ep); + } + n = xdupmbstowcs(&mut wstring, &mut indices, string); + if n == -(1 as libc::c_int) as size_t { + sh_xfree( + wpat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5099 as libc::c_int, + ); + return match_upattern(string, pat, mtype, sp, ep); + } + ret = match_wpattern(wstring, indices, n, wpat, mtype, sp, ep); + sh_xfree( + wpat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5104 as libc::c_int, + ); + sh_xfree( + wstring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5105 as libc::c_int, + ); + sh_xfree( + indices as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5106 as libc::c_int, + ); + return ret; + } else { + return match_upattern(string, pat, mtype, sp, ep); + }; + } +} +fn getpatspec(mut c: libc::c_int, mut value: *mut libc::c_char) -> libc::c_int { + unsafe { + if c == '#' as i32 { + return if *value as libc::c_int == '#' as i32 { + 1 as libc::c_int + } else { + 2 as libc::c_int + }; + } else { + return if *value as libc::c_int == '%' as i32 { + 3 as libc::c_int + } else { + 4 as libc::c_int + }; + }; + } +} +fn getpattern( + mut value: *mut libc::c_char, + mut quoted: libc::c_int, + mut expandpat: libc::c_int, +) -> *mut libc::c_char { + let mut pat: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tword: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + unsafe { + l = if *value as libc::c_int != 0 { + expand_string_for_pat( + value, + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + 0x8 as libc::c_int + } else { + quoted + }, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + ) + } else { + 0 as *mut WORD_LIST + }; + if !l.is_null() { + word_list_remove_quoted_nulls(l); + } + pat = string_list(l); + dispose_words(l); + if !pat.is_null() { + tword = quote_string_for_globbing(pat, 0x1 as libc::c_int); + sh_xfree( + pat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5172 as libc::c_int, + ); + pat = tword; + } + } + return pat; +} +fn list_remove_pattern( + mut list: *mut WORD_LIST, + mut pattern: *mut libc::c_char, + mut patspec: libc::c_int, + mut itype: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut new: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut tword: *mut libc::c_char = 0 as *mut libc::c_char; + new = 0 as *mut libc::c_void as *mut WORD_LIST; + l = list; + unsafe { + while !l.is_null() { + tword = remove_pattern((*(*l).word).word, pattern, patspec); + w = alloc_word_desc(); + let ref mut fresh65 = (*w).word; + *fresh65 = if !tword.is_null() { + tword + } else { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(b"\0" as *const u8 as *const libc::c_char) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5208 as libc::c_int, + ) as *mut libc::c_char, + b"\0" as *const u8 as *const libc::c_char, + ) + }; + new = make_word_list(w, new); + l = (*l).next; + } + l = if !new.is_null() && !((*new).next).is_null() { + list_reverse(new as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + new + }; + tword = string_list_pos_params(itype, l, quoted, 0 as libc::c_int); + dispose_words(l); + } + return tword; +} +fn parameter_list_remove_pattern( + mut itype: libc::c_int, + mut pattern: *mut libc::c_char, + mut patspec: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + list = list_rest_of_args(); + if list.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + ret = list_remove_pattern(list, pattern, patspec, itype, quoted); + dispose_words(list); + return ret; +} +fn array_remove_pattern( + mut var: *mut SHELL_VAR, + mut pattern: *mut libc::c_char, + mut patspec: libc::c_int, + mut starsub: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut itype: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = var; + unsafe { + itype = if starsub != 0 { '*' as i32 } else { '@' as i32 }; + a = if !v.is_null() && (*v).attributes & 0x4 as libc::c_int != 0 { + (*v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + h = if !v.is_null() && (*v).attributes & 0x40 as libc::c_int != 0 { + (*v).value as *mut HASH_TABLE + } else { + 0 as *mut HASH_TABLE + }; + list = if !a.is_null() { + array_to_word_list(a) + } else if !h.is_null() { + assoc_to_word_list(h) + } else { + 0 as *mut WORD_LIST + }; + if list.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + ret = list_remove_pattern(list, pattern, patspec, itype, quoted); + dispose_words(list); + } + return ret; +} +fn parameter_brace_remove_pattern( + mut varname: *mut libc::c_char, + mut value: *mut libc::c_char, + mut ind: libc::c_int, + mut patstr: *mut libc::c_char, + mut rtype: libc::c_int, + mut quoted: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut vtype: libc::c_int = 0; + let mut patspec: libc::c_int = 0; + let mut starsub: libc::c_int = 0; + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pattern: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + if value.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + oname = this_command_name; + this_command_name = varname; + vtype = get_var_and_type( + varname, + value, + ind as arrayind_t, + quoted, + flags, + &mut v, + &mut val, + ); + if vtype == -(1 as libc::c_int) { + this_command_name = oname; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + starsub = vtype & 128 as libc::c_int; + vtype &= !(128 as libc::c_int); + patspec = getpatspec(rtype, patstr); + if patspec == 1 as libc::c_int || patspec == 3 as libc::c_int { + patstr = patstr.offset(1); + } + temp1 = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(patstr) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5302 as libc::c_int, + ) as *mut libc::c_char, + patstr, + ); + pattern = getpattern(temp1, quoted, 1 as libc::c_int); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5304 as libc::c_int, + ); + temp1 = 0 as *mut libc::c_void as *mut libc::c_char; + match vtype { + 0 | 3 => { + temp1 = remove_pattern(val, pattern, patspec); + if vtype == 0 as libc::c_int { + if !val.is_null() { + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5313 as libc::c_int, + ); + } + } + if !temp1.is_null() { + val = if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + quote_string(temp1) + } else { + quote_escapes(temp1) + }; + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5319 as libc::c_int, + ); + temp1 = val; + } + } + 2 => { + temp1 = array_remove_pattern(v, pattern, patspec, starsub, quoted); + if !temp1.is_null() + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) == 0 as libc::c_int + { + val = quote_escapes(temp1); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5329 as libc::c_int, + ); + temp1 = val; + } + } + 1 => { + temp1 = parameter_list_remove_pattern( + *varname.offset(0 as libc::c_int as isize) as libc::c_int, + pattern, + patspec, + quoted, + ); + if !(!temp1.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !temp1.is_null() + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) == 0 as libc::c_int + { + val = quote_escapes(temp1); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5343 as libc::c_int, + ); + temp1 = val; + } + } + } + _ => {} + } + this_command_name = oname; + if !pattern.is_null() { + sh_xfree( + pattern as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5351 as libc::c_int, + ); + } + } + return temp1; +} +static mut dev_fd_list: *mut pid_t = 0 as *const libc::c_void as *mut libc::c_void as *mut pid_t; +static mut nfds: libc::c_int = 0; +static mut totfds: libc::c_int = 0; +#[no_mangle] +pub fn clear_fifo(mut i: libc::c_int) { + unsafe { + if *dev_fd_list.offset(i as isize) != 0 { + *dev_fd_list.offset(i as isize) = 0 as libc::c_int; + nfds -= 1; + } + } +} +#[no_mangle] +pub fn clear_fifo_list() { + unsafe { + let mut i: libc::c_int = 0; + if nfds == 0 as libc::c_int { + return; + } + i = 0 as libc::c_int; + while nfds != 0 && i < totfds { + clear_fifo(i); + i += 1; + } + nfds = 0 as libc::c_int; + } +} +#[no_mangle] +pub fn copy_fifo_list(mut sizep: *mut libc::c_int) -> *mut libc::c_void { + unsafe { + let mut ret: *mut libc::c_void = 0 as *mut libc::c_void; + if nfds == 0 as libc::c_int || totfds == 0 as libc::c_int { + if !sizep.is_null() { + *sizep = 0 as libc::c_int; + } + return 0 as *mut libc::c_void; + } + if !sizep.is_null() { + *sizep = totfds; + } + ret = sh_xmalloc( + (totfds as libc::c_ulong).wrapping_mul(::std::mem::size_of::() as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5676 as libc::c_int, + ); + return memcpy( + ret, + dev_fd_list as *const libc::c_void, + (totfds as libc::c_ulong).wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as usize, + ); + } +} +fn add_fifo_list(mut fd: libc::c_int) { + unsafe { + if dev_fd_list.is_null() || fd >= totfds { + let mut ofds: libc::c_int = 0; + ofds = totfds; + totfds = getdtablesize(); + if totfds < 0 as libc::c_int || totfds > 256 as libc::c_int { + totfds = 256 as libc::c_int; + } + if fd >= totfds { + totfds = fd + 2 as libc::c_int; + } + dev_fd_list = sh_xrealloc( + dev_fd_list as *mut libc::c_void, + (totfds as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5695 as libc::c_int, + ) as *mut pid_t; + memset( + dev_fd_list.offset(ofds as isize) as *mut libc::c_void, + '\u{0}' as i32, + ((totfds - ofds) as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::() as libc::c_ulong) + as usize, + ); + } + *dev_fd_list.offset(fd as isize) = 1 as libc::c_int; + nfds += 1; + } +} +#[no_mangle] +pub fn fifos_pending() -> libc::c_int { + return 0 as libc::c_int; +} +#[no_mangle] +pub fn num_fifos() -> libc::c_int { + unsafe { + return nfds; + } +} +#[no_mangle] +pub fn unlink_fifo(mut fd: libc::c_int) { + unsafe { + if *dev_fd_list.offset(fd as isize) != 0 { + close(fd); + *dev_fd_list.offset(fd as isize) = 0 as libc::c_int; + nfds -= 1; + } + } +} +#[no_mangle] +pub fn unlink_fifo_list() { + unsafe { + let mut i: libc::c_int = 0; + if nfds == 0 as libc::c_int { + return; + } + i = totfds - 1 as libc::c_int; + while nfds != 0 && i >= 0 as libc::c_int { + unlink_fifo(i); + i -= 1; + } + nfds = 0 as libc::c_int; + } +} +#[no_mangle] +pub fn unlink_all_fifos() { + unlink_fifo_list(); +} +#[no_mangle] +pub fn close_new_fifos(mut list: *mut libc::c_void, mut lsize: libc::c_int) { + let mut i: libc::c_int = 0; + let mut plist: *mut pid_t = 0 as *mut pid_t; + if list.is_null() { + unlink_fifo_list(); + return; + } + plist = list as *mut pid_t; + i = 0 as libc::c_int; + unsafe { + while i < lsize { + if *plist.offset(i as isize) == 0 as libc::c_int + && i < totfds + && *dev_fd_list.offset(i as isize) != 0 + { + unlink_fifo(i); + } + i += 1; + } + i = lsize; + while i < totfds { + unlink_fifo(i); + i += 1; + } + } +} +#[no_mangle] +pub fn find_procsub_child(mut pid: pid_t) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + if nfds == 0 as libc::c_int { + return -(1 as libc::c_int); + } + i = 0 as libc::c_int; + while i < totfds { + if *dev_fd_list.offset(i as isize) == pid { + return i; + } + i += 1; + } + return -(1 as libc::c_int); + } +} +#[no_mangle] +pub fn set_procsub_status(mut ind: libc::c_int, mut pid: pid_t, mut status: libc::c_int) { + unsafe { + if ind >= 0 as libc::c_int && ind < totfds { + *dev_fd_list.offset(ind as isize) = -(1 as libc::c_int); + } + } +} +fn reap_some_procsubs(mut max: libc::c_int) { + unsafe { + let mut i: libc::c_int = 0; + i = 0 as libc::c_int; + while nfds > 0 as libc::c_int && i < max { + if *dev_fd_list.offset(i as isize) == -(1 as libc::c_int) { + unlink_fifo(i); + } + i += 1; + } + } +} +#[no_mangle] +pub fn reap_procsubs() { + unsafe { + reap_some_procsubs(totfds); + } +} +fn make_dev_fd_filename(mut fd: libc::c_int) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut intbuf: [libc::c_char; 12] = [0; 12]; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + ret = sh_xmalloc( + (::std::mem::size_of::<[libc::c_char; 9]>() as libc::c_ulong) + .wrapping_add(8 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5862 as libc::c_int, + ) as *mut libc::c_char; + unsafe { + strcpy(ret, b"/dev/fd/\0" as *const u8 as *const libc::c_char); + p = inttostr( + fd as intmax_t, + intbuf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 12]>() as libc::c_ulong, + ); + strcpy( + ret.offset(::std::mem::size_of::<[libc::c_char; 9]>() as libc::c_ulong as isize) + .offset(-(1 as libc::c_int as isize)), + p, + ); + add_fifo_list(fd); + } + return ret; +} +fn process_substitute( + mut string: *mut libc::c_char, + mut open_for_read_in_child: libc::c_int, +) -> *mut libc::c_char { + let mut pathname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut fd: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut rc: libc::c_int = 0; + let mut function_value: libc::c_int = 0; + let mut old_pid: pid_t = 0; + let mut pid: pid_t = 0; + let mut parent_pipe_fd: libc::c_int = 0; + let mut child_pipe_fd: libc::c_int = 0; + let mut fildes: [libc::c_int; 2] = [0; 2]; + let mut old_pipeline_pgrp: pid_t = 0; + unsafe { + if string.is_null() || *string == 0 || wordexp_only != 0 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if pipe(fildes.as_mut_ptr()) < 0 as libc::c_int { + sys_error( + b"%s\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"cannot make pipe for process substitution\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + return 0 as *mut libc::c_void as *mut libc::c_char; + } + parent_pipe_fd = fildes[open_for_read_in_child as usize]; + child_pipe_fd = fildes[(1 as libc::c_int - open_for_read_in_child) as usize]; + parent_pipe_fd = move_to_high_fd(parent_pipe_fd, 1 as libc::c_int, 64 as libc::c_int); + pathname = make_dev_fd_filename(parent_pipe_fd); + if pathname.is_null() { + sys_error( + b"%s\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"cannot make pipe for process substitution\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + return 0 as *mut libc::c_void as *mut libc::c_char; + } + old_pid = last_made_pid; + old_pipeline_pgrp = pipeline_pgrp; + if pipeline_pgrp == 0 as libc::c_int + || subshell_environment + & (0x10 as libc::c_int | 0x8 as libc::c_int | 0x1 as libc::c_int) + == 0 as libc::c_int + { + pipeline_pgrp = shell_pgrp; + } + save_pipeline(1 as libc::c_int); + pid = make_child( + 0 as *mut libc::c_void as *mut libc::c_char, + 1 as libc::c_int, + ); + if pid == 0 as libc::c_int { + interactive = 0 as libc::c_int; + reset_terminating_signals(); + free_pushed_string_input(); + restore_original_signals(); + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + setup_async_signals(); + subshell_environment |= 0x4 as libc::c_int | 0x20 as libc::c_int | 0x1 as libc::c_int; + change_flag('v' as i32, '+' as i32); + if expanding_redir != 0 { + flush_temporary_env(); + } + } + set_sigchld_handler(); + stop_making_children(); + pipeline_pgrp = old_pipeline_pgrp; + if pid < 0 as libc::c_int { + sys_error( + b"%s\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"cannot make child for process substitution\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + sh_xfree( + pathname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 5986 as libc::c_int, + ); + close(parent_pipe_fd); + close(child_pipe_fd); + restore_pipeline(1 as libc::c_int); + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if pid > 0 as libc::c_int { + last_procsub_child = restore_pipeline(0 as libc::c_int); + let ref mut fresh66 = (*last_procsub_child).next; + *fresh66 = 0 as *mut process; + procsub_add(last_procsub_child); + *dev_fd_list.offset(parent_pipe_fd as isize) = pid; + ::std::ptr::write_volatile(&mut last_made_pid as *mut pid_t, old_pid); + close_pgrp_pipe(); + close(child_pipe_fd); + return pathname; + } + set_sigint_handler(); + set_job_control(0 as libc::c_int); + procsub_clear(); + if pipeline_pgrp != shell_pgrp { + pipeline_pgrp = getpid(); + } + fd = child_pipe_fd; + if open_for_read_in_child == 0 as libc::c_int { + fpurge(stdout); + } + if dup2( + fd, + if open_for_read_in_child != 0 { + 0 as libc::c_int + } else { + 1 as libc::c_int + }, + ) < 0 as libc::c_int + { + sys_error( + dcgettext( + 0 as *const libc::c_char, + b"cannot duplicate named pipe %s as fd %d\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + pathname, + if open_for_read_in_child != 0 { + 0 as libc::c_int + } else { + 1 as libc::c_int + }, + ); + exit(127 as libc::c_int); + } + if fd + != (if open_for_read_in_child != 0 { + 0 as libc::c_int + } else { + 1 as libc::c_int + }) + { + close(fd); + } + if !current_fds_to_close.is_null() { + close_fd_bitmap(current_fds_to_close); + current_fds_to_close = 0 as *mut libc::c_void as *mut fd_bitmap; + } + close(parent_pipe_fd); + *dev_fd_list.offset(parent_pipe_fd as isize) = 0 as libc::c_int; + expanding_redir = 0 as libc::c_int; + remove_quoted_escapes(string); + result = __sigsetjmp(top_level.as_mut_ptr(), 0 as libc::c_int); + if result == 0 as libc::c_int && return_catch_flag != 0 { + function_value = __sigsetjmp(return_catch.as_mut_ptr(), 0 as libc::c_int); + } else { + function_value = 0 as libc::c_int; + } + if result == 4 as libc::c_int { + rc = last_command_exit_value; + } else if result == 3 as libc::c_int { + rc = last_command_exit_value; + } else if result != 0 { + rc = 1 as libc::c_int; + } else if function_value != 0 { + rc = return_catch_value; + } else { + subshell_level += 1; + rc = parse_and_execute( + string, + b"process substitution\0" as *const u8 as *const libc::c_char, + 0x1 as libc::c_int | 0x4 as libc::c_int, + ); + } + ::std::ptr::write_volatile(&mut last_command_exit_value as *mut libc::c_int, rc); + rc = run_exit_trap(); + exit(rc); + } +} +fn read_comsub( + mut fd: libc::c_int, + mut quoted: libc::c_int, + mut flags: libc::c_int, + mut rflag: *mut libc::c_int, +) -> *mut libc::c_char { + let mut istring: *mut libc::c_char = 0 as *mut libc::c_char; + let mut buf: [libc::c_char; 512] = [0; 512]; + let mut bufp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut istring_index: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut tflag: libc::c_int = 0; + let mut skip_ctlesc: libc::c_int = 0; + let mut skip_ctlnul: libc::c_int = 0; + let mut mb_cur_max: libc::c_int = 0; + let mut istring_size: size_t = 0; + let mut bufn: ssize_t = 0; + let mut nullbyte: libc::c_int = 0; + let mut ps: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut wc: wchar_t = 0; + let mut mblen_0: size_t = 0; + let mut i: libc::c_int = 0; + istring = 0 as *mut libc::c_void as *mut libc::c_char; + tflag = 0 as libc::c_int; + bufn = tflag as ssize_t; + istring_size = bufn as size_t; + unsafe { + istring_index = istring_size as libc::c_int; + skip_ctlesc = ifs_cmap['\u{1}' as i32 as usize] as libc::c_int; + skip_ctlnul = ifs_cmap['\u{7f}' as i32 as usize] as libc::c_int; + mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + nullbyte = 0 as libc::c_int; + while !(fd < 0 as libc::c_int) { + bufn -= 1; + if bufn <= 0 as libc::c_int as libc::c_long { + bufn = zread( + fd, + buf.as_mut_ptr(), + ::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong, + ) as i64; + if bufn <= 0 as libc::c_int as libc::c_long { + break; + } + bufp = buf.as_mut_ptr(); + } + let fresh67 = bufp; + bufp = bufp.offset(1); + c = *fresh67 as libc::c_int; + if c == 0 as libc::c_int { + if nullbyte == 0 as libc::c_int { + internal_warning( + b"%s\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"command substitution: ignored null byte in input\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + nullbyte = 1 as libc::c_int; + } + } else { + if (istring_index + (mb_cur_max + 1 as libc::c_int)) as libc::c_ulong + >= istring_size + { + while (istring_index + (mb_cur_max + 1 as libc::c_int)) as libc::c_ulong + >= istring_size + { + istring_size = (istring_size as libc::c_ulong) + .wrapping_add(512 as libc::c_int as libc::c_ulong) + as size_t as size_t; + } + istring = sh_xrealloc( + istring as *mut libc::c_void, + istring_size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6221 as libc::c_int, + ) as *mut libc::c_char; + } + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + let fresh68 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh68 as isize) = '\u{1}' as i32 as libc::c_char; + } else if flags & 0x8 as libc::c_int != 0 && skip_ctlesc != 0 && c == '\u{1}' as i32 + { + let fresh69 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh69 as isize) = '\u{1}' as i32 as libc::c_char; + } else if skip_ctlesc == 0 as libc::c_int && c == '\u{1}' as i32 { + let fresh70 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh70 as isize) = '\u{1}' as i32 as libc::c_char; + } else if skip_ctlnul == 0 as libc::c_int && c == '\u{7f}' as i32 + || c == ' ' as i32 + && (!ifs_value.is_null() && *ifs_value as libc::c_int == 0 as libc::c_int) + { + let fresh71 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh71 as isize) = '\u{1}' as i32 as libc::c_char; + } + if locale_utf8locale != 0 && c & 0x80 as libc::c_int != 0 + || locale_utf8locale == 0 as libc::c_int + && mb_cur_max > 1 as libc::c_int + && c as libc::c_uchar as libc::c_int > 127 as libc::c_int + { + memset( + &mut ps as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + mblen_0 = mbrtowc( + &mut wc, + bufp.offset(-(1 as libc::c_int as isize)), + (bufn + 1 as libc::c_int as libc::c_long) as size_t, + &mut ps, + ); + if mblen_0 == -(1 as libc::c_int) as size_t + || mblen_0 == -(2 as libc::c_int) as size_t + || mblen_0 == 0 as libc::c_int as libc::c_ulong + || mblen_0 == 1 as libc::c_int as libc::c_ulong + { + let fresh72 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh72 as isize) = c as libc::c_char; + } else { + let fresh73 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh73 as isize) = c as libc::c_char; + i = 0 as libc::c_int; + while (i as libc::c_ulong) + < mblen_0.wrapping_sub(1 as libc::c_int as libc::c_ulong) + { + let fresh74 = bufp; + bufp = bufp.offset(1); + let fresh75 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh75 as isize) = *fresh74; + i += 1; + } + bufn = (bufn as libc::c_ulong) + .wrapping_sub(mblen_0.wrapping_sub(1 as libc::c_int as libc::c_ulong)) + as ssize_t as ssize_t; + } + } else { + let fresh76 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh76 as isize) = c as libc::c_char; + } + } + } + if !istring.is_null() { + *istring.offset(istring_index as isize) = '\u{0}' as i32 as libc::c_char; + } + if istring_index == 0 as libc::c_int { + if !istring.is_null() { + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6267 as libc::c_int, + ); + } + if !rflag.is_null() { + *rflag = tflag; + } + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + while istring_index > 0 as libc::c_int { + if !(*istring.offset((istring_index - 1 as libc::c_int) as isize) as libc::c_int + == '\n' as i32) + { + break; + } + istring_index -= 1; + if *istring.offset((istring_index - 1 as libc::c_int) as isize) as libc::c_int + == '\u{1}' as i32 + { + istring_index -= 1; + } + } + *istring.offset(istring_index as isize) = '\u{0}' as i32 as libc::c_char; + } else { + strip_trailing(istring, istring_index - 1 as libc::c_int, 1 as libc::c_int); + } + if !rflag.is_null() { + *rflag = tflag; + } + } + return istring; +} +#[no_mangle] +pub fn command_substitute( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, + mut flags: libc::c_int, +) -> *mut WORD_DESC { + let mut pid: pid_t = 0; + let mut old_pid: pid_t = 0; + let mut old_pipeline_pgrp: pid_t = 0; + let mut old_async_pid: pid_t = 0; + let mut istring: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result: libc::c_int = 0; + let mut fildes: [libc::c_int; 2] = [0; 2]; + let mut function_value: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut rc: libc::c_int = 0; + let mut tflag: libc::c_int = 0; + let mut fork_flags: libc::c_int = 0; + let mut ret: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut set: sigset_t = sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = sigset_t { __val: [0; 16] }; + istring = 0 as *mut libc::c_void as *mut libc::c_char; + s = string; + unsafe { + while !s.is_null() + && *s as libc::c_int != 0 + && (*sh_syntaxtab + .as_mut_ptr() + .offset(*s as libc::c_uchar as isize) + & 0x2000 as libc::c_int + != 0 + || *s as libc::c_int == '\n' as i32) + { + s = s.offset(1); + } + if s.is_null() || *s as libc::c_int == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut WORD_DESC; + } + if wordexp_only != 0 && read_but_dont_execute != 0 { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 125 as libc::c_int, + ); + jump_to_top_level(3 as libc::c_int); + } + if subst_assign_varlist.is_null() || garglist.is_null() { + maybe_make_export_env(); + } + pflags = if interactive != 0 && sourcelevel == 0 as libc::c_int { + 0x10 as libc::c_int + } else { + 0 as libc::c_int + }; + old_pid = last_made_pid; + if pipe(fildes.as_mut_ptr()) < 0 as libc::c_int { + sys_error( + b"%s\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"cannot make pipe for command substitution\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } else { + old_pipeline_pgrp = pipeline_pgrp; + if subshell_environment & (0x8 as libc::c_int | 0x10 as libc::c_int) == 0 as libc::c_int + { + pipeline_pgrp = shell_pgrp; + } + cleanup_the_pipeline(); + old_async_pid = last_asynchronous_pid; + fork_flags = if subshell_environment & 0x1 as libc::c_int != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + pid = make_child( + 0 as *mut libc::c_void as *mut libc::c_char, + fork_flags | 4 as libc::c_int, + ); + ::std::ptr::write_volatile(&mut last_asynchronous_pid as *mut pid_t, old_async_pid); + if pid == 0 as libc::c_int { + reset_signal_handlers(); + if interrupt_state != 0 as libc::c_int { + kill(getpid(), 2 as libc::c_int); + ::std::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + 0 as libc::c_int, + ); + } + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + subshell_environment |= 0x80 as libc::c_int; + } + set_sigchld_handler(); + stop_making_children(); + if pid != 0 as libc::c_int { + pipeline_pgrp = old_pipeline_pgrp; + } + if pid < 0 as libc::c_int { + sys_error(dcgettext( + 0 as *const libc::c_char, + b"cannot make child for command substitution\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + )); + } else if pid == 0 as libc::c_int { + interactive = 0 as libc::c_int; + set_sigint_handler(); + free_pushed_string_input(); + fpurge(stdout); + if dup2(fildes[1 as libc::c_int as usize], 1 as libc::c_int) < 0 as libc::c_int { + sys_error( + b"%s\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"command_substitute: cannot duplicate pipe as fd 1\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + exit(1 as libc::c_int); + } + if fildes[1 as libc::c_int as usize] != fileno(stdin) + && fildes[1 as libc::c_int as usize] != fileno(stdout) + && fildes[1 as libc::c_int as usize] != fileno(stderr) + { + close(fildes[1 as libc::c_int as usize]); + } + if fildes[0 as libc::c_int as usize] != fileno(stdin) + && fildes[0 as libc::c_int as usize] != fileno(stdout) + && fildes[0 as libc::c_int as usize] != fileno(stderr) + { + close(fildes[0 as libc::c_int as usize]); + } + subshell_environment |= 0x4 as libc::c_int; + change_flag('v' as i32, '+' as i32); + if inherit_errexit == 0 as libc::c_int { + builtin_ignoring_errexit = 0 as libc::c_int; + change_flag('e' as i32, '+' as i32); + } + set_shellopts(); + if expanding_redir != 0 { + flush_temporary_env(); + expanding_redir = 0 as libc::c_int; + } + remove_quoted_escapes(string); + startup_state = 2 as libc::c_int; + parse_and_execute_level = 0 as libc::c_int; + result = __sigsetjmp(top_level.as_mut_ptr(), 0 as libc::c_int); + if result == 0 as libc::c_int && return_catch_flag != 0 { + function_value = __sigsetjmp(return_catch.as_mut_ptr(), 0 as libc::c_int); + } else { + function_value = 0 as libc::c_int; + } + if result == 4 as libc::c_int { + rc = last_command_exit_value; + } else if result == 3 as libc::c_int { + rc = last_command_exit_value; + } else if result != 0 { + rc = 1 as libc::c_int; + } else if function_value != 0 { + rc = return_catch_value; + } else { + subshell_level += 1; + rc = parse_and_execute( + string, + b"command substitution\0" as *const u8 as *const libc::c_char, + pflags | 0x4 as libc::c_int, + ); + } + ::std::ptr::write_volatile(&mut last_command_exit_value as *mut libc::c_int, rc); + rc = run_exit_trap(); + unlink_fifo_list(); + exit(rc); + } else { + let mut dummyfd: libc::c_int = 0; + close_pgrp_pipe(); + close(fildes[1 as libc::c_int as usize]); + begin_unwind_frame( + b"read-comsub\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + dummyfd = fildes[0 as libc::c_int as usize]; + add_unwind_protect( + ::std::mem::transmute::< + unsafe extern "C" fn(libc::c_int) -> (libc::c_int), + Option, + >(close), + dummyfd as *mut libc::c_char, + ); + // add_unwind_protect( + // Some(close as fn() -> libc::c_int), + // dummyfd as &mut i8, + // ); + sigemptyset(&mut set); + sigaddset(&mut set, 2 as libc::c_int); + sigemptyset(&mut oset); + sigprocmask(0 as libc::c_int, &mut set, &mut oset); + tflag = 0 as libc::c_int; + istring = read_comsub(fildes[0 as libc::c_int as usize], quoted, flags, &mut tflag); + close(fildes[0 as libc::c_int as usize]); + discard_unwind_frame( + b"read-comsub\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut crate::src_common::__sigset_t, + ); + current_command_subst_pid = pid; + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + wait_for(pid, (1 as libc::c_int) << 8 as libc::c_int), + ); + last_command_subst_pid = pid; + ::std::ptr::write_volatile(&mut last_made_pid as *mut pid_t, old_pid); + if last_command_exit_value == 128 as libc::c_int + 2 as libc::c_int + && last_command_exit_signal == 2 as libc::c_int + { + kill(getpid(), 2 as libc::c_int); + } + ret = alloc_word_desc(); + let ref mut fresh77 = (*ret).word; + *fresh77 = istring; + (*ret).flags = tflag; + return ret; + } + } + ::std::ptr::write_volatile(&mut last_made_pid as *mut pid_t, old_pid); + if !istring.is_null() { + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6404 as libc::c_int, + ); + } + close(fildes[0 as libc::c_int as usize]); + close(fildes[1 as libc::c_int as usize]); + } + return 0 as *mut libc::c_void as *mut WORD_DESC; +} +fn array_length_reference(mut s: *mut libc::c_char) -> arrayind_t { + let mut len: libc::c_int = 0; + let mut ind: arrayind_t = 0; + let mut akey: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut c: libc::c_char = 0; + let mut array: *mut ARRAY = 0 as *mut ARRAY; + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = array_variable_part(s, 0 as libc::c_int, &mut t, &mut len); + unsafe { + if (var.is_null() + || (*var).attributes & 0x1000 as libc::c_int != 0 + || (*var).attributes & 0x40 as libc::c_int == 0 as libc::c_int + && (*var).attributes & 0x4 as libc::c_int == 0 as libc::c_int) + && unbound_vars_is_error != 0 + { + t = t.offset(-1); + c = *t; + *t = '\u{0}' as i32 as libc::c_char; + set_exit_status(1 as libc::c_int); + err_unboundvar(s); + *t = c; + return -(1 as libc::c_int) as arrayind_t; + } else { + if var.is_null() || (*var).attributes & 0x1000 as libc::c_int != 0 { + return 0 as libc::c_int as arrayind_t; + } + } + array = if (*var).attributes & 0x4 as libc::c_int != 0 { + (*var).value as *mut ARRAY + } else { + 0 as *mut libc::c_void as *mut ARRAY + }; + h = if (*var).attributes & 0x40 as libc::c_int != 0 { + (*var).value as *mut HASH_TABLE + } else { + 0 as *mut libc::c_void as *mut HASH_TABLE + }; + if (*t.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *t.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *t.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + if (*var).attributes & 0x40 as libc::c_int != 0 { + return (if !h.is_null() { + (*h).nentries + } else { + 0 as libc::c_int + }) as arrayind_t; + } else if (*var).attributes & 0x4 as libc::c_int != 0 { + return (if !array.is_null() { + (*array).num_elements + } else { + 0 as libc::c_int + }) as arrayind_t; + } else { + return (if !((*var).value).is_null() { + 1 as libc::c_int + } else { + 0 as libc::c_int + }) as arrayind_t; + } + } + if (*var).attributes & 0x40 as libc::c_int != 0 { + *t.offset((len - 1 as libc::c_int) as isize) = '\u{0}' as i32 as libc::c_char; + akey = expand_assignment_string_to_string(t, 0 as libc::c_int); + *t.offset((len - 1 as libc::c_int) as isize) = ']' as i32 as libc::c_char; + if akey.is_null() || *akey as libc::c_int == 0 as libc::c_int { + err_badarraysub(t); + if !akey.is_null() { + sh_xfree( + akey as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6625 as libc::c_int, + ); + } + return -(1 as libc::c_int) as arrayind_t; + } + t = assoc_reference((*var).value as *mut HASH_TABLE, akey); + sh_xfree( + akey as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6629 as libc::c_int, + ); + } else { + ind = array_expand_index(var, t, len, 0 as libc::c_int); + if !var.is_null() + && (*var).attributes & 0x4 as libc::c_int != 0 + && ind < 0 as libc::c_int as libc::c_long + { + ind = (*((*var).value as *mut ARRAY)).max_index + + 1 as libc::c_int as libc::c_long + + ind; + } + if ind < 0 as libc::c_int as libc::c_long { + err_badarraysub(t); + return -(1 as libc::c_int) as arrayind_t; + } + if (*var).attributes & 0x4 as libc::c_int != 0 { + t = array_reference(array, ind); + } else { + t = if ind == 0 as libc::c_int as libc::c_long { + (*var).value + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + } + len = (if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !t.is_null() && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + mbstrlen(t) as usize + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else if !t.is_null() && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(t) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + } + return len as arrayind_t; +} +fn valid_brace_expansion_word( + mut name: *mut libc::c_char, + mut var_is_special: libc::c_int, +) -> libc::c_int { + unsafe { + if *name as libc::c_int >= '0' as i32 + && *name as libc::c_int <= '9' as i32 + && all_digits(name) != 0 + { + return 1 as libc::c_int; + } else if var_is_special != 0 { + return 1 as libc::c_int; + } else if valid_array_reference(name, 0 as libc::c_int) != 0 { + return 1 as libc::c_int; + } else if legal_identifier(name) != 0 { + return 1 as libc::c_int; + } else { + return 0 as libc::c_int; + }; + } +} +fn chk_atstar( + mut name: *mut libc::c_char, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut quoted_dollar_atp: *mut libc::c_int, + mut contains_dollar_at: *mut libc::c_int, +) -> libc::c_int { + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if name.is_null() { + if !quoted_dollar_atp.is_null() { + *quoted_dollar_atp = 0 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 0 as libc::c_int; + } + return 0 as libc::c_int; + } + if *name.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = 1 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + return 1 as libc::c_int; + } else { + if *name.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && quoted == 0 as libc::c_int + { + if !contains_dollar_at.is_null() && expand_no_split_dollar_star == 0 as libc::c_int + { + *contains_dollar_at = 1 as libc::c_int; + } + return 1 as libc::c_int; + } else { + if valid_array_reference(name, 0 as libc::c_int) != 0 { + temp1 = mbschr(name, '[' as i32); + if !temp1.is_null() + && *temp1.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + && *temp1.offset(2 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = 1 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + return 1 as libc::c_int; + } + if !temp1.is_null() + && *temp1.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32 + && *temp1.offset(2 as libc::c_int as isize) as libc::c_int == ']' as i32 + && quoted == 0 as libc::c_int + { + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + return 1 as libc::c_int; + } + } + } + } + } + return 0 as libc::c_int; +} +fn parameter_brace_expand_word( + mut name: *mut libc::c_char, + mut var_is_special: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut indp: *mut arrayind_t, +) -> *mut WORD_DESC { + let mut ret: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut arg_index: intmax_t = 0; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut atype: libc::c_int = 0; + let mut rflags: libc::c_int = 0; + let mut ind: arrayind_t = 0; + ret = 0 as *mut WORD_DESC; + temp = 0 as *mut libc::c_char; + rflags = 0 as libc::c_int; + unsafe { + if !indp.is_null() { + *indp = -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long; + } + if legal_number(name, &mut arg_index) != 0 { + tt = get_dollar_var_value(arg_index); + if !tt.is_null() { + temp = if *tt as libc::c_int != 0 + && quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + { + quote_string(tt) + } else { + quote_escapes(tt) + }; + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + if !tt.is_null() { + sh_xfree( + tt as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6768 as libc::c_int, + ); + } + } else if var_is_special != 0 { + let mut sindex: libc::c_int = 0; + tt = sh_xmalloc( + (2 as libc::c_int as libc::c_ulong).wrapping_add(strlen(name) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6773 as libc::c_int, + ) as *mut libc::c_char; + sindex = 0 as libc::c_int; + *tt.offset(sindex as isize) = '$' as i32 as libc::c_char; + strcpy(tt.offset(1 as libc::c_int as isize), name); + ret = param_expand( + tt, + &mut sindex, + quoted, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + 0 as *mut libc::c_void as *mut libc::c_int, + pflags, + ); + sh_xfree( + tt as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6779 as libc::c_int, + ); + } else { + let mut current_block_79: u64; + if valid_array_reference(name, 0 as libc::c_int) != 0 { + current_block_79 = 14887093560253451645; + } else { + var = find_variable(name); + if !var.is_null() { + if !((*var).value).is_null() + && (*var).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + { + tt = 0 as *mut libc::c_void as *mut libc::c_char; + if pflags & 0x40 as libc::c_int != 0 + && (*var).attributes & 0x40 as libc::c_int != 0 + { + temp = if (*((*var).value as *mut HASH_TABLE)).nentries + == 0 as libc::c_int + { + 0 as *mut libc::c_void as *mut libc::c_char + } else { + assoc_to_string( + (*var).value as *mut HASH_TABLE, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + quoted, + ) + }; + tt = temp; + } else if pflags & 0x40 as libc::c_int != 0 + && (*var).attributes & 0x4 as libc::c_int != 0 + { + temp = if (*((*var).value as *mut ARRAY)).num_elements + == 0 as libc::c_int + { + 0 as *mut libc::c_void as *mut libc::c_char + } else { + array_to_string( + (*var).value as *mut ARRAY, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + quoted, + ) + }; + tt = temp; + } else if (*var).attributes & 0x40 as libc::c_int != 0 { + temp = assoc_reference( + (*var).value as *mut HASH_TABLE, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else if (*var).attributes & 0x4 as libc::c_int != 0 { + temp = array_reference( + (*var).value as *mut ARRAY, + 0 as libc::c_int as arrayind_t, + ); + } else { + temp = (*var).value; + } + if !temp.is_null() { + temp = if *temp as libc::c_int != 0 + && quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + { + quote_string(temp) + } else if pflags & 0x8 as libc::c_int != 0 { + quote_rhs(temp) + } else { + quote_escapes(temp) + }; + } + if !tt.is_null() { + sh_xfree( + tt as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6864 as libc::c_int, + ); + } + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + current_block_79 = 6002151390280567665; + } else { + var = find_variable_last_nameref(name, 0 as libc::c_int); + if !var.is_null() { + temp = (*var).value; + if !temp.is_null() + && *temp as libc::c_int != 0 + && valid_array_reference(temp, 0 as libc::c_int) != 0 + { + name = temp; + current_block_79 = 14887093560253451645; + } else { + if !temp.is_null() + && *temp as libc::c_int != 0 + && legal_identifier(temp) == 0 as libc::c_int + { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid variable name for name reference\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + temp, + ); + temp = &mut expand_param_error; + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + current_block_79 = 6002151390280567665; + } + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + current_block_79 = 6002151390280567665; + } + } + } + match current_block_79 { + 14887093560253451645 => { + var = + array_variable_part(name, 0 as libc::c_int, &mut tt, 0 as *mut libc::c_int); + if pflags & 0x8 as libc::c_int != 0 { + if (*tt.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *tt.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *tt.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + if !var.is_null() + && ((*var).attributes & 0x4 as libc::c_int != 0 + || (*var).attributes & 0x40 as libc::c_int != 0) + { + temp = array_value( + name, + quoted | 0x1 as libc::c_int, + 0x10 as libc::c_int, + &mut atype, + &mut ind, + ); + } else { + temp = array_value( + name, + quoted, + 0 as libc::c_int, + &mut atype, + &mut ind, + ); + } + } else { + temp = + array_value(name, quoted, 0 as libc::c_int, &mut atype, &mut ind); + } + } else if pflags & 0x4 as libc::c_int != 0 { + if *tt.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + && *tt.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + && !var.is_null() + && quoted == 0 as libc::c_int + && ifs_is_set != 0 + && ifs_is_null == 0 as libc::c_int + && ifs_firstc[0 as libc::c_int as usize] as libc::c_int != ' ' as i32 + { + temp = array_value( + name, + 0x1 as libc::c_int, + 0x10 as libc::c_int, + &mut atype, + &mut ind, + ); + } else if *tt.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + && *tt.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + temp = + array_value(name, quoted, 0 as libc::c_int, &mut atype, &mut ind); + } else if *tt.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + && *tt.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + && expand_no_split_dollar_star != 0 + && ifs_is_null != 0 + { + temp = array_value( + name, + 0x1 as libc::c_int | 0x2 as libc::c_int, + 0 as libc::c_int, + &mut atype, + &mut ind, + ); + } else if *tt.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + && *tt.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + temp = + array_value(name, quoted, 0 as libc::c_int, &mut atype, &mut ind); + } else { + temp = + array_value(name, quoted, 0 as libc::c_int, &mut atype, &mut ind); + } + } else if *tt.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + && *tt.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + && expand_no_split_dollar_star != 0 + && ifs_is_null != 0 + { + temp = array_value( + name, + 0x1 as libc::c_int | 0x2 as libc::c_int, + 0 as libc::c_int, + &mut atype, + &mut ind, + ); + } else { + temp = array_value(name, quoted, 0 as libc::c_int, &mut atype, &mut ind); + } + if atype == 0 as libc::c_int && !temp.is_null() { + temp = if *temp as libc::c_int != 0 + && quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + { + quote_string(temp) + } else { + quote_escapes(temp) + }; + rflags |= (1 as libc::c_int) << 24 as libc::c_int; + if !indp.is_null() { + *indp = ind; + } + } else if atype == 1 as libc::c_int + && !temp.is_null() + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + && quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + { + rflags |= (1 as libc::c_int) << 18 as libc::c_int; + } + } + _ => {} + } + } + if ret.is_null() { + ret = alloc_word_desc(); + let ref mut fresh78 = (*ret).word; + *fresh78 = temp; + (*ret).flags |= rflags; + } + } + return ret; +} +fn parameter_brace_find_indir( + mut name: *mut libc::c_char, + mut var_is_special: libc::c_int, + mut quoted: libc::c_int, + mut find_nameref: libc::c_int, +) -> *mut libc::c_char { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut pflags: libc::c_int = 0; + let mut oldex: libc::c_int = 0; + unsafe { + if find_nameref != 0 + && var_is_special == 0 as libc::c_int + && { + v = find_variable_last_nameref(name, 0 as libc::c_int); + !v.is_null() + } + && (*v).attributes & 0x800 as libc::c_int != 0 + && { + t = (*v).value; + !t.is_null() + } + && *t as libc::c_int != 0 + { + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(t) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6915 as libc::c_int, + ) as *mut libc::c_char, + t, + ); + } + pflags = 0x2 as libc::c_int; + if var_is_special != 0 { + pflags |= 0x8 as libc::c_int; + oldex = expand_no_split_dollar_star; + expand_no_split_dollar_star = 1 as libc::c_int; + } + w = parameter_brace_expand_word(name, var_is_special, quoted, pflags, 0 as *mut arrayind_t); + if var_is_special != 0 { + expand_no_split_dollar_star = oldex; + } + t = (*w).word; + if !t.is_null() { + temp = if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 || var_is_special != 0 + { + dequote_string(t) + } else { + dequote_escapes(t) + }; + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6939 as libc::c_int, + ); + t = temp; + } + dispose_word_desc(w); + } + return t; +} +fn parameter_brace_expand_indir( + mut name: *mut libc::c_char, + mut var_is_special: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut quoted_dollar_atp: *mut libc::c_int, + mut contains_dollar_at: *mut libc::c_int, +) -> *mut WORD_DESC { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + if var_is_special == 0 as libc::c_int && { + v = find_variable_last_nameref(name, 0 as libc::c_int); + !v.is_null() + } { + if (*v).attributes & 0x800 as libc::c_int != 0 + && { + t = (*v).value; + !t.is_null() + } + && *t as libc::c_int != 0 + { + w = alloc_word_desc(); + let ref mut fresh79 = (*w).word; + *fresh79 = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(t) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 6969 as libc::c_int, + ) as *mut libc::c_char, + t, + ); + (*w).flags = 0 as libc::c_int; + return w; + } + } + if legal_identifier(name) != 0 && v.is_null() { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid indirect expansion\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + w = alloc_word_desc(); + let ref mut fresh80 = (*w).word; + *fresh80 = &mut expand_param_error; + (*w).flags = 0 as libc::c_int; + return w; + } + t = parameter_brace_find_indir(name, var_is_special, quoted, 0 as libc::c_int); + chk_atstar(t, quoted, pflags, quoted_dollar_atp, contains_dollar_at); + if t.is_null() && valid_array_reference(name, 0 as libc::c_int) != 0 { + v = array_variable_part( + name, + 0 as libc::c_int, + 0 as *mut *mut libc::c_char, + 0 as *mut libc::c_int, + ); + if v.is_null() { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid indirect expansion\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + w = alloc_word_desc(); + let ref mut fresh81 = (*w).word; + *fresh81 = &mut expand_param_error; + (*w).flags = 0 as libc::c_int; + return w; + } else { + return 0 as *mut libc::c_void as *mut WORD_DESC; + } + } + if t.is_null() { + return 0 as *mut libc::c_void as *mut WORD_DESC; + } + if valid_brace_expansion_word( + t, + (*t as libc::c_int != 0 + && (*t as libc::c_int >= '0' as i32 + && *t as libc::c_int <= '9' as i32 + && all_digits(t) != 0 + || *t.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*t as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + || 0 as libc::c_int != 0 + && *t.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && (posixly_correct == 0 as libc::c_int + && *t.offset(1 as libc::c_int as isize) as libc::c_int == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *t.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *t.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *t.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32))) + as libc::c_int, + ) == 0 as libc::c_int + { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid variable name\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + t, + ); + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7016 as libc::c_int, + ); + w = alloc_word_desc(); + let ref mut fresh82 = (*w).word; + *fresh82 = &mut expand_param_error; + (*w).flags = 0 as libc::c_int; + return w; + } + w = parameter_brace_expand_word( + t, + (*t as libc::c_int != 0 + && (*t as libc::c_int >= '0' as i32 + && *t as libc::c_int <= '9' as i32 + && all_digits(t) != 0 + || *t.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*t as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + || 0 as libc::c_int != 0 + && *t.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && (posixly_correct == 0 as libc::c_int + && *t.offset(1 as libc::c_int as isize) as libc::c_int == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *t.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *t.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *t.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32))) + as libc::c_int, + quoted, + pflags, + 0 as *mut arrayind_t, + ); + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7024 as libc::c_int, + ); + } + return w; +} +fn parameter_brace_expand_rhs( + mut name: *mut libc::c_char, + mut value: *mut libc::c_char, + mut op: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut qdollaratp: *mut libc::c_int, + mut hasdollarat: *mut libc::c_int, +) -> *mut WORD_DESC { + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut l_hasdollat: libc::c_int = 0; + let mut sindex: libc::c_int = 0; + unsafe { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 && *value as libc::c_int != 0 { + sindex = 0 as libc::c_int; + temp = string_extract_double_quoted(value, &mut sindex, 0x800 as libc::c_int); + } else { + temp = value; + } + w = alloc_word_desc(); + l_hasdollat = 0 as libc::c_int; + l = if *temp as libc::c_int != 0 { + expand_string_for_rhs( + temp, + quoted, + op, + pflags, + &mut l_hasdollat, + 0 as *mut libc::c_void as *mut libc::c_int, + ) + } else { + 0 as *mut WORD_LIST + }; + if !hasdollarat.is_null() { + *hasdollarat = + (l_hasdollat != 0 || !l.is_null() && !((*l).next).is_null()) as libc::c_int; + } + if temp != value { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7063 as libc::c_int, + ); + } + tl = l; + while !tl.is_null() { + if !((*tl).word).is_null() + && (((*(*tl).word).word).is_null() + || *((*(*tl).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == 0 as libc::c_int) + && (*(*tl).word).flags | (1 as libc::c_int) << 21 as libc::c_int != 0 + { + t = make_quoted_char('\u{0}' as i32); + if !((*(*tl).word).word).is_null() { + sh_xfree( + (*(*tl).word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7074 as libc::c_int, + ); + } + let ref mut fresh83 = (*(*tl).word).word; + *fresh83 = t; + (*(*tl).word).flags |= (1 as libc::c_int) << 1 as libc::c_int + | (1 as libc::c_int) << 18 as libc::c_int; + (*(*tl).word).flags &= !((1 as libc::c_int) << 21 as libc::c_int); + } + tl = (*tl).next; + } + if !l.is_null() { + if !qdollaratp.is_null() && (l_hasdollat != 0 && quoted != 0 || !((*l).next).is_null()) + { + *qdollaratp = 1 as libc::c_int; + } + if !((*l).next).is_null() && ifs_is_null != 0 { + temp = string_list_internal( + l, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + (*w).flags |= (1 as libc::c_int) << 3 as libc::c_int; + } else if l_hasdollat != 0 || !((*l).next).is_null() { + temp = string_list_dollar_star(l, quoted, 0 as libc::c_int); + } else { + temp = string_list(l); + if !temp.is_null() + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int + == 0 as libc::c_int + && (*(*l).word).flags & (1 as libc::c_int) << 21 as libc::c_int != 0 + { + (*w).flags |= (1 as libc::c_int) << 21 as libc::c_int; + } + } + if ((*l).next).is_null() + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + && (*((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *((*(*l).word).word).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + && (*(*l).word).flags & (1 as libc::c_int) << 18 as libc::c_int != 0 + { + (*w).flags |= (1 as libc::c_int) << 18 as libc::c_int; + if !qdollaratp.is_null() && l_hasdollat != 0 { + *qdollaratp = 0 as libc::c_int; + } + } + dispose_words(l); + } else if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 && l_hasdollat != 0 { + temp = make_quoted_char('\u{0}' as i32); + (*w).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + if op == '-' as i32 || op == '+' as i32 { + let ref mut fresh84 = (*w).word; + *fresh84 = temp; + return w; + } + t1 = if !temp.is_null() { + dequote_string(temp) + } else { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(b"\0" as *const u8 as *const libc::c_char) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7160 as libc::c_int, + ) as *mut libc::c_char, + b"\0" as *const u8 as *const libc::c_char, + ) + }; + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7161 as libc::c_int, + ); + vname = name; + if *name as libc::c_int == '!' as i32 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*name.offset(1 as libc::c_int as isize) + as libc::c_uchar as libc::c_int + as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *name.offset(1 as libc::c_int as isize) as libc::c_uchar as libc::c_int + == '_' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int >= '0' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int <= '9' as i32 + || (posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '?' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32)) + { + vname = parameter_brace_find_indir( + name.offset(1 as libc::c_int as isize), + (*name as libc::c_int != 0 + && (*name as libc::c_int >= '0' as i32 + && *name as libc::c_int <= '9' as i32 + && all_digits(name) != 0 + || *name.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*name as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + || 1 as libc::c_int != 0 + && *name.offset(2 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + && (posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int + == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int + == '@' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int + == '*' as i32))) as libc::c_int, + quoted, + 1 as libc::c_int, + ); + if vname.is_null() || *vname as libc::c_int == 0 as libc::c_int { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid indirect expansion\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + sh_xfree( + vname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7172 as libc::c_int, + ); + sh_xfree( + t1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7173 as libc::c_int, + ); + dispose_word(w); + return &mut expand_wdesc_error; + } + if legal_identifier(vname) == 0 as libc::c_int { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid variable name\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + vname, + ); + sh_xfree( + vname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7180 as libc::c_int, + ); + sh_xfree( + t1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7181 as libc::c_int, + ); + dispose_word(w); + return &mut expand_wdesc_error; + } + } + if valid_array_reference(vname, 0 as libc::c_int) != 0 { + v = assign_array_element(vname, t1, 0 as libc::c_int); + } else { + v = bind_variable(vname, t1, 0 as libc::c_int); + } + if v.is_null() + || (*v).attributes & 0x2 as libc::c_int != 0 + || (*v).attributes & 0x4000 as libc::c_int != 0 + { + if (v.is_null() || (*v).attributes & 0x2 as libc::c_int != 0) + && interactive_shell == 0 as libc::c_int + && posixly_correct != 0 + { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + exp_jump_to_top_level(1 as libc::c_int); + } else { + if vname != name { + sh_xfree( + vname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7204 as libc::c_int, + ); + } + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 2 as libc::c_int, + ); + exp_jump_to_top_level(2 as libc::c_int); + } + } + stupidly_hack_special_variables(vname); + if vname != name { + sh_xfree( + vname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7213 as libc::c_int, + ); + } + let ref mut fresh85 = (*w).word; + *fresh85 = if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + quote_string(t1) + } else { + quote_escapes(t1) + }; + if !((*w).word).is_null() + && *((*w).word).offset(0 as libc::c_int as isize) as libc::c_int != 0 + && (*((*w).word).offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *((*w).word).offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int + == 0 as libc::c_int + { + (*w).flags &= !((1 as libc::c_int) << 21 as libc::c_int); + } + sh_xfree( + t1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7226 as libc::c_int, + ); + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + && (*((*w).word).offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *((*w).word).offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + { + (*w).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } + } + return w; +} +fn parameter_brace_expand_error( + mut name: *mut libc::c_char, + mut value: *mut libc::c_char, + mut check_null: libc::c_int, +) { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + set_exit_status(1 as libc::c_int); + if !value.is_null() && *value as libc::c_int != 0 { + l = expand_string(value, 0 as libc::c_int); + temp = string_list(l); + report_error( + b"%s: %s\0" as *const u8 as *const libc::c_char, + name, + if !temp.is_null() { + temp + } else { + b"\0" as *const u8 as *const libc::c_char + }, + ); + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7254 as libc::c_int, + ); + } + dispose_words(l); + } else if check_null == 0 as libc::c_int { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: parameter not set\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + } else { + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: parameter null or not set\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7264 as libc::c_int, + ); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7265 as libc::c_int, + ); + } + } +} +fn valid_length_expression(mut name: *mut libc::c_char) -> libc::c_int { + unsafe { + return (*name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *sh_syntaxtab + .as_mut_ptr() + .offset(*name.offset(1 as libc::c_int as isize) as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + && *name.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int >= '0' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int <= '9' as i32 + && all_digits(name.offset(1 as libc::c_int as isize)) != 0 + || valid_array_reference(name.offset(1 as libc::c_int as isize), 0 as libc::c_int) != 0 + || legal_identifier(name.offset(1 as libc::c_int as isize)) != 0) + as libc::c_int; + } +} +fn parameter_brace_expand_length(mut name: *mut libc::c_char) -> intmax_t { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut number: intmax_t = 0; + let mut arg_index: intmax_t = 0; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = 0 as *mut libc::c_void as *mut SHELL_VAR; + unsafe { + if *name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 { + number = number_of_args() as intmax_t; + } else if (*name.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *name.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + number = number_of_args() as intmax_t; + } else if *sh_syntaxtab + .as_mut_ptr() + .offset(*name.offset(1 as libc::c_int as isize) as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + && *name.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + match *name.offset(1 as libc::c_int as isize) as libc::c_int { + 45 => { + t = which_set_flags(); + } + 63 => { + t = itos(last_command_exit_value as intmax_t); + } + 36 => { + t = itos(dollar_dollar_pid as intmax_t); + } + 33 => { + if last_asynchronous_pid == -(1 as libc::c_int) { + t = 0 as *mut libc::c_void as *mut libc::c_char; + } else { + t = itos(last_asynchronous_pid as intmax_t); + } + } + 35 => { + t = itos(number_of_args() as intmax_t); + } + _ => {} + } + number = (if !t.is_null() && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(t) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as intmax_t; + if !t.is_null() { + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7325 as libc::c_int, + ); + } + } else if valid_array_reference(name.offset(1 as libc::c_int as isize), 0 as libc::c_int) + != 0 + { + number = array_length_reference(name.offset(1 as libc::c_int as isize)); + } else { + number = 0 as libc::c_int as intmax_t; + if legal_number(name.offset(1 as libc::c_int as isize), &mut arg_index) != 0 { + t = get_dollar_var_value(arg_index); + if t.is_null() && unbound_vars_is_error != 0 { + return -(9223372036854775807 as libc::c_long) + - 1 as libc::c_int as libc::c_long; + } + number = (if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !t.is_null() && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + mbstrlen(t) as usize + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else if !t.is_null() && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(t) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as intmax_t; + if !t.is_null() { + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7341 as libc::c_int, + ); + } + } else { + var = find_variable(name.offset(1 as libc::c_int as isize)); + if !var.is_null() + && (*var).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && ((*var).attributes & 0x4 as libc::c_int != 0 + || (*var).attributes & 0x40 as libc::c_int != 0) + { + if (*var).attributes & 0x40 as libc::c_int != 0 { + t = assoc_reference( + (*var).value as *mut HASH_TABLE, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else { + t = array_reference( + (*var).value as *mut ARRAY, + 0 as libc::c_int as arrayind_t, + ); + } + if t.is_null() && unbound_vars_is_error != 0 { + return -(9223372036854775807 as libc::c_long) + - 1 as libc::c_int as libc::c_long; + } + number = (if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !t.is_null() && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + mbstrlen(t) as usize + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else if !t.is_null() + && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(t) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as intmax_t; + } else if (!var.is_null() || { + var = find_variable(name.offset(1 as libc::c_int as isize)); + !var.is_null() + }) && (*var).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && (*var).attributes & 0x4 as libc::c_int == 0 as libc::c_int + && (*var).attributes & 0x40 as libc::c_int == 0 as libc::c_int + && ((*var).dynamic_value).is_none() + { + number = (if !((*var).value).is_null() { + if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !((*var).value).is_null() + && *((*var).value).offset(0 as libc::c_int as isize) as libc::c_int + != 0 + { + if *((*var).value).offset(1 as libc::c_int as isize) as libc::c_int + != 0 + { + mbstrlen((*var).value) as usize + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else if !((*var).value).is_null() + && *((*var).value).offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *((*var).value).offset(1 as libc::c_int as isize) as libc::c_int != 0 + { + if *((*var).value).offset(2 as libc::c_int as isize) as libc::c_int + != 0 + { + strlen((*var).value) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as i64; + } else if var.is_null() && unbound_vars_is_error == 0 as libc::c_int { + number = 0 as libc::c_int as i64; + } else { + newname = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(name) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7366 as libc::c_int, + ) as *mut libc::c_char, + name, + ); + *newname.offset(0 as libc::c_int as isize) = '$' as i32 as libc::c_char; + list = expand_string(newname, 0x1 as libc::c_int); + t = if !list.is_null() { + string_list(list) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + sh_xfree( + newname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7370 as libc::c_int, + ); + if !list.is_null() { + dispose_words(list); + } + number = (if !t.is_null() { + if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !t.is_null() + && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + mbstrlen(t) as usize + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else if !t.is_null() + && *t.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *t.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *t.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(t) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as intmax_t; + if !t.is_null() { + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7375 as libc::c_int, + ); + } + } + } + } + } + return number; +} +fn skiparith(mut substr: *mut libc::c_char, mut delim: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut i: libc::c_int = 0; + let mut delims: [libc::c_char; 2] = [0; 2]; + delims[0 as libc::c_int as usize] = delim as libc::c_char; + delims[1 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + i = skip_to_delim( + substr, + 0 as libc::c_int, + delims.as_mut_ptr(), + 0x400 as libc::c_int, + ); + return substr.offset(i as isize); + } +} +fn verify_substring_values( + mut v: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut substr: *mut libc::c_char, + mut vtype: libc::c_int, + mut e1p: *mut intmax_t, + mut e2p: *mut intmax_t, +) -> libc::c_int { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp2: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: arrayind_t = 0; + let mut expok: libc::c_int = 0; + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + t = skiparith(substr, ':' as i32); + unsafe { + if *t as libc::c_int != 0 && *t as libc::c_int == ':' as i32 { + *t = '\u{0}' as i32 as libc::c_char; + } else { + t = 0 as *mut libc::c_char; + } + temp1 = expand_arith_string(substr, 0x1 as libc::c_int); + *e1p = evalexp(temp1, 0 as libc::c_int, &mut expok); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7435 as libc::c_int, + ); + if expok == 0 as libc::c_int { + return 0 as libc::c_int; + } + len = -(1 as libc::c_int) as arrayind_t; + match vtype { + 0 | 3 => { + len = (if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !value.is_null() + && *value.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *value.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + mbstrlen(value) as usize + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + } + } else if !value.is_null() + && *value.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *value.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *value.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(value) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as arrayind_t; + } + 1 => { + len = (number_of_args() + 1 as libc::c_int) as arrayind_t; + if *e1p == 0 as libc::c_int as libc::c_long { + len += 1; + } + } + 2 => { + if (*v).attributes & 0x40 as libc::c_int != 0 { + h = (*v).value as *mut HASH_TABLE; + len = ((*h).nentries + (*e1p < 0 as libc::c_int as libc::c_long) as libc::c_int) + as arrayind_t; + } else { + a = value as *mut ARRAY; + len = (*a).max_index + + (*e1p < 0 as libc::c_int as libc::c_long) as libc::c_int as libc::c_long; + } + } + _ => {} + } + if len == -(1 as libc::c_int) as libc::c_long { + return -(1 as libc::c_int); + } + if *e1p < 0 as libc::c_int as libc::c_long { + *e1p += len; + } + if *e1p > len || *e1p < 0 as libc::c_int as libc::c_long { + return -(1 as libc::c_int); + } + if vtype == 2 as libc::c_int { + len = (if (*v).attributes & 0x40 as libc::c_int != 0 { + (*h).nentries + } else { + (*a).num_elements + }) as arrayind_t; + } + if !t.is_null() { + t = t.offset(1); + temp2 = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(t) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7488 as libc::c_int, + ) as *mut libc::c_char, + t, + ); + temp1 = expand_arith_string(temp2, 0x1 as libc::c_int); + sh_xfree( + temp2 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7490 as libc::c_int, + ); + *t.offset(-(1 as libc::c_int) as isize) = ':' as i32 as libc::c_char; + *e2p = evalexp(temp1, 0 as libc::c_int, &mut expok); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7493 as libc::c_int, + ); + if expok == 0 as libc::c_int { + return 0 as libc::c_int; + } + if (vtype == 2 as libc::c_int || vtype == 1 as libc::c_int) + && *e2p < 0 as libc::c_int as libc::c_long + { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: substring expression < 0\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + t, + ); + return 0 as libc::c_int; + } + if vtype != 2 as libc::c_int { + if *e2p < 0 as libc::c_int as libc::c_long { + *e2p += len; + if *e2p < 0 as libc::c_int as libc::c_long || *e2p < *e1p { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: substring expression < 0\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + t, + ); + return 0 as libc::c_int; + } + } else { + *e2p += *e1p; + } + if *e2p > len { + *e2p = len; + } + } + } else { + *e2p = len; + } + } + return 1 as libc::c_int; +} +fn get_var_and_type( + mut varname: *mut libc::c_char, + mut value: *mut libc::c_char, + mut ind: arrayind_t, + mut quoted: libc::c_int, + mut flags: libc::c_int, + mut varp: *mut *mut SHELL_VAR, + mut valp: *mut *mut libc::c_char, +) -> libc::c_int { + let mut vtype: libc::c_int = 0; + let mut want_indir: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut vname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut lind: arrayind_t = 0; + unsafe { + want_indir = (*varname as libc::c_int == '!' as i32 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()) + .offset(*varname.offset(1 as libc::c_int as isize) as libc::c_uchar + as libc::c_int as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *varname.offset(1 as libc::c_int as isize) as libc::c_uchar as libc::c_int + == '_' as i32 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int >= '0' as i32 + && *varname.offset(1 as libc::c_int as isize) as libc::c_int <= '9' as i32 + || (posixly_correct == 0 as libc::c_int + && *varname.offset(1 as libc::c_int as isize) as libc::c_int == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *varname.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32))) + as libc::c_int; + if want_indir != 0 { + vname = parameter_brace_find_indir( + varname.offset(1 as libc::c_int as isize), + (*varname as libc::c_int != 0 + && (*varname as libc::c_int >= '0' as i32 + && *varname as libc::c_int <= '9' as i32 + && all_digits(varname) != 0 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*varname as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + || 1 as libc::c_int != 0 + && *varname.offset(2 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + && (posixly_correct == 0 as libc::c_int + && *varname.offset(1 as libc::c_int as isize) as libc::c_int + == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *varname.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int + == '@' as i32 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int + == '*' as i32))) as libc::c_int, + quoted, + 1 as libc::c_int, + ); + } else { + vname = varname; + } + if vname.is_null() { + vtype = 0 as libc::c_int; + *varp = 0 as *mut libc::c_void as *mut SHELL_VAR; + *valp = 0 as *mut libc::c_void as *mut libc::c_char; + return vtype; + } + vtype = ((*vname.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *vname.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *vname.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int; + if vtype == 1 as libc::c_int + && *vname.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 + { + vtype |= 128 as libc::c_int; + } + *varp = 0 as *mut libc::c_void as *mut SHELL_VAR; + if valid_array_reference(vname, 0 as libc::c_int) != 0 { + v = array_variable_part(vname, 0 as libc::c_int, &mut temp, 0 as *mut libc::c_int); + lind = if ind + != -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long + && flags & 0x4 as libc::c_int != 0 + { + ind + } else { + 0 as libc::c_int as libc::c_long + }; + if !v.is_null() && (*v).attributes & 0x1000 as libc::c_int != 0 { + vtype = 3 as libc::c_int; + *varp = 0 as *mut libc::c_void as *mut SHELL_VAR; + *valp = 0 as *mut libc::c_void as *mut libc::c_char; + } + if !v.is_null() + && ((*v).attributes & 0x4 as libc::c_int != 0 + || (*v).attributes & 0x40 as libc::c_int != 0) + { + if (*temp.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *temp.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *temp.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + vtype = 2 as libc::c_int; + if *temp.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32 { + vtype |= 128 as libc::c_int; + } + *valp = if (*v).attributes & 0x4 as libc::c_int != 0 { + (*v).value as *mut ARRAY as *mut libc::c_char + } else { + (*v).value as *mut HASH_TABLE as *mut libc::c_char + }; + } else { + vtype = 3 as libc::c_int; + *valp = array_value( + vname, + 0x1 as libc::c_int, + flags, + 0 as *mut libc::c_void as *mut libc::c_int, + &mut lind, + ); + } + *varp = v; + } else if !v.is_null() + && ((*temp.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *temp.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *temp.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32) + { + vtype = 0 as libc::c_int; + *varp = v; + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + *valp = if !value.is_null() { + dequote_string(value) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } else { + *valp = if !value.is_null() { + dequote_escapes(value) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + } else { + vtype = 3 as libc::c_int; + *varp = v; + *valp = array_value( + vname, + 0x1 as libc::c_int, + flags, + 0 as *mut libc::c_void as *mut libc::c_int, + &mut lind, + ); + } + } else { + v = find_variable(vname); + if !v.is_null() + && (*v).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && ((*v).attributes & 0x40 as libc::c_int != 0 + || (*v).attributes & 0x4 as libc::c_int != 0) + { + vtype = 3 as libc::c_int; + *varp = v; + *valp = if (*v).attributes & 0x40 as libc::c_int != 0 { + assoc_reference( + (*v).value as *mut HASH_TABLE, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) + } else { + array_reference((*v).value as *mut ARRAY, 0 as libc::c_int as arrayind_t) + }; + } else if !value.is_null() && vtype == 0 as libc::c_int { + *varp = find_variable(vname); + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + *valp = dequote_string(value); + } else { + *valp = dequote_escapes(value); + } + } else { + *valp = value; + } + } + if want_indir != 0 { + sh_xfree( + vname as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7650 as libc::c_int, + ); + } + } + return vtype; +} +fn string_var_assignment(mut v: *mut SHELL_VAR, mut s: *mut libc::c_char) -> *mut libc::c_char { + let mut flags: [libc::c_char; 16] = [0; 16]; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + unsafe { + val = if !v.is_null() + && ((*v).attributes & 0x1000 as libc::c_int != 0 + || ((*v).value != 0 as *mut libc::c_char) as libc::c_int == 0 as libc::c_int) + { + 0 as *mut libc::c_void as *mut libc::c_char + } else { + sh_quote_reusable(s, 0 as libc::c_int) + }; + i = var_attribute_string(v, 0 as libc::c_int, flags.as_mut_ptr()); + if i == 0 as libc::c_int && val.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + ret = sh_xmalloc( + (i as libc::c_ulong) + .wrapping_add( + (if !val.is_null() && *val.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + (if *val.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (if *val.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(val) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + }) + } else { + 1 as libc::c_int as libc::c_ulong + }) + } else { + 0 as libc::c_int as libc::c_ulong + }), + ) + .wrapping_add(strlen((*v).name) as u64) + .wrapping_add(16 as libc::c_int as libc::c_ulong) + .wrapping_add(16 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7674 as libc::c_int, + ) as *mut libc::c_char; + if i > 0 as libc::c_int && val.is_null() { + sprintf( + ret, + b"declare -%s %s\0" as *const u8 as *const libc::c_char, + flags.as_mut_ptr(), + (*v).name, + ); + } else if i > 0 as libc::c_int { + sprintf( + ret, + b"declare -%s %s=%s\0" as *const u8 as *const libc::c_char, + flags.as_mut_ptr(), + (*v).name, + val, + ); + } else { + sprintf( + ret, + b"%s=%s\0" as *const u8 as *const libc::c_char, + (*v).name, + val, + ); + } + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7681 as libc::c_int, + ); + } + return ret; +} +fn array_var_assignment( + mut v: *mut SHELL_VAR, + mut itype: libc::c_int, + mut quoted: libc::c_int, + mut atype: libc::c_int, +) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut flags: [libc::c_char; 16] = [0; 16]; + let mut i: libc::c_int = 0; + if v.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + if atype == 2 as libc::c_int { + val = if (*v).attributes & 0x4 as libc::c_int != 0 { + array_to_kvpair((*v).value as *mut ARRAY, 0 as libc::c_int) + } else { + assoc_to_kvpair((*v).value as *mut HASH_TABLE, 0 as libc::c_int) + }; + } else { + val = if (*v).attributes & 0x4 as libc::c_int != 0 { + array_to_assign((*v).value as *mut ARRAY, 0 as libc::c_int) + } else { + assoc_to_assign((*v).value as *mut HASH_TABLE, 0 as libc::c_int) + }; + } + if !(val.is_null() + && ((*v).attributes & 0x1000 as libc::c_int != 0 + || ((*v).value != 0 as *mut libc::c_char) as libc::c_int == 0 as libc::c_int)) + { + if val.is_null() { + val = sh_xmalloc( + 3 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7707 as libc::c_int, + ) as *mut libc::c_char; + *val.offset(0 as libc::c_int as isize) = '(' as i32 as libc::c_char; + *val.offset(1 as libc::c_int as isize) = ')' as i32 as libc::c_char; + *val.offset(2 as libc::c_int as isize) = 0 as libc::c_int as libc::c_char; + } else { + ret = if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + quote_string(val) + } else { + quote_escapes(val) + }; + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7715 as libc::c_int, + ); + val = ret; + } + } + if atype == 2 as libc::c_int { + return val; + } + i = var_attribute_string(v, 0 as libc::c_int, flags.as_mut_ptr()); + ret = sh_xmalloc( + (i as libc::c_ulong) + .wrapping_add( + (if !val.is_null() && *val.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + (if *val.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (if *val.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(val) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + }) + } else { + 1 as libc::c_int as libc::c_ulong + }) + } else { + 0 as libc::c_int as libc::c_ulong + }), + ) + .wrapping_add(strlen((*v).name) as u64) + .wrapping_add(16 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7723 as libc::c_int, + ) as *mut libc::c_char; + if !val.is_null() { + sprintf( + ret, + b"declare -%s %s=%s\0" as *const u8 as *const libc::c_char, + flags.as_mut_ptr(), + (*v).name, + val, + ); + } else { + sprintf( + ret, + b"declare -%s %s\0" as *const u8 as *const libc::c_char, + flags.as_mut_ptr(), + (*v).name, + ); + } + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7728 as libc::c_int, + ); + } + return ret; +} +fn pos_params_assignment( + mut list: *mut WORD_LIST, + mut itype: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + temp = list_transform('Q' as i32, 0 as *mut SHELL_VAR, list, itype, quoted); + unsafe { + ret = sh_xmalloc( + (strlen(temp)).wrapping_add(8 as libc::c_int as u64) as u64, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7743 as libc::c_int, + ) as *mut libc::c_char; + strcpy(ret, b"set -- \0" as *const u8 as *const libc::c_char); + strcpy(ret.offset(7 as libc::c_int as isize), temp); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7746 as libc::c_int, + ); + } + return ret; +} +fn string_transform( + mut xc: libc::c_int, + mut v: *mut SHELL_VAR, + mut s: *mut libc::c_char, +) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut flags: [libc::c_char; 16] = [0; 16]; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut i: libc::c_int = 0; + if (xc == 'A' as i32 || xc == 'a' as i32) && v.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } else { + if xc != 'a' as i32 && xc != 'A' as i32 && s.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + } + unsafe { + match xc { + 97 => { + i = var_attribute_string(v, 0 as libc::c_int, flags.as_mut_ptr()); + ret = if i > 0 as libc::c_int { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(flags.as_mut_ptr()) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7769 as libc::c_int, + ) as *mut libc::c_char, + flags.as_mut_ptr(), + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + 65 => { + ret = string_var_assignment(v, s); + } + 75 => { + ret = sh_quote_reusable(s, 0 as libc::c_int); + } + 69 => { + t = ansiexpand( + s, + 0 as libc::c_int, + strlen(s) as libc::c_int, + 0 as *mut libc::c_int, + ); + ret = dequote_escapes(t); + sh_xfree( + t as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7781 as libc::c_int, + ); + } + 80 => { + ret = decode_prompt_string(s); + } + 81 => { + ret = sh_quote_reusable(s, 0 as libc::c_int); + } + 85 => { + ret = sh_modcase(s, 0 as *mut libc::c_char, 0x2 as libc::c_int); + } + 117 => { + ret = sh_modcase(s, 0 as *mut libc::c_char, 0x40 as libc::c_int); + } + 76 => { + ret = sh_modcase(s, 0 as *mut libc::c_char, 0x1 as libc::c_int); + } + _ => { + ret = 0 as *mut libc::c_void as *mut libc::c_char; + } + } + } + return ret; +} +fn list_transform( + mut xc: libc::c_int, + mut v: *mut SHELL_VAR, + mut list: *mut WORD_LIST, + mut itype: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut new: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut tword: *mut libc::c_char = 0 as *mut libc::c_char; + let mut qflags: libc::c_int = 0; + new = 0 as *mut libc::c_void as *mut WORD_LIST; + l = list; + unsafe { + while !l.is_null() { + tword = string_transform(xc, v, (*(*l).word).word); + w = alloc_word_desc(); + let ref mut fresh86 = (*w).word; + *fresh86 = if !tword.is_null() { + tword + } else { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(b"\0" as *const u8 as *const libc::c_char) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7821 as libc::c_int, + ) as *mut libc::c_char, + b"\0" as *const u8 as *const libc::c_char, + ) + }; + new = make_word_list(w, new); + l = (*l).next; + } + l = if !new.is_null() && !((*new).next).is_null() { + list_reverse(new as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + new + }; + qflags = quoted; + if itype == '*' as i32 && expand_no_split_dollar_star != 0 && ifs_is_null != 0 { + qflags |= 0x1 as libc::c_int; + } + tword = string_list_pos_params(itype, l, qflags, 0 as libc::c_int); + dispose_words(l); + } + return tword; +} +fn parameter_list_transform( + mut xc: libc::c_int, + mut itype: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + list = list_rest_of_args(); + if list.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if xc == 'A' as i32 { + ret = pos_params_assignment(list, itype, quoted); + } else { + ret = list_transform(xc, 0 as *mut SHELL_VAR, list, itype, quoted); + } + dispose_words(list); + return ret; +} +fn array_transform( + mut xc: libc::c_int, + mut var: *mut SHELL_VAR, + mut starsub: libc::c_int, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut itype: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = var; + itype = if starsub != 0 { '*' as i32 } else { '@' as i32 }; + if xc == 'A' as i32 { + return array_var_assignment(v, itype, quoted, 1 as libc::c_int); + } else { + if xc == 'K' as i32 { + return array_var_assignment(v, itype, quoted, 2 as libc::c_int); + } + } + unsafe { + if xc == 'a' as i32 + && ((*v).attributes & 0x1000 as libc::c_int != 0 + || ((*v).value != 0 as *mut libc::c_char) as libc::c_int == 0 as libc::c_int) + { + let mut flags: [libc::c_char; 16] = [0; 16]; + let mut i: libc::c_int = 0; + i = var_attribute_string(v, 0 as libc::c_int, flags.as_mut_ptr()); + return if i > 0 as libc::c_int { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(flags.as_mut_ptr()) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7889 as libc::c_int, + ) as *mut libc::c_char, + flags.as_mut_ptr(), + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + a = if !v.is_null() && (*v).attributes & 0x4 as libc::c_int != 0 { + (*v).value as *mut ARRAY + } else { + 0 as *mut ARRAY + }; + h = if !v.is_null() && (*v).attributes & 0x40 as libc::c_int != 0 { + (*v).value as *mut HASH_TABLE + } else { + 0 as *mut HASH_TABLE + }; + list = if !a.is_null() { + array_to_word_list(a) + } else if !h.is_null() { + assoc_to_word_list(h) + } else { + 0 as *mut WORD_LIST + }; + if list.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + ret = list_transform(xc, v, list, itype, quoted); + dispose_words(list); + } + return ret; +} +fn valid_parameter_transform(mut xform: *mut libc::c_char) -> libc::c_int { + if unsafe { *xform.offset(1 as libc::c_int as isize) != 0 } { + return 0 as libc::c_int; + } + let mut current_block_3: u64; + match unsafe { *xform.offset(0 as libc::c_int as isize) as libc::c_int } { + 65 => { + current_block_3 = 2998016214394651642; + } + 75 => { + current_block_3 = 2998016214394651642; + } + 69 => { + current_block_3 = 9692932599894361468; + } + 80 => { + current_block_3 = 1699338852606067860; + } + 81 => { + current_block_3 = 14850354526820511888; + } + 85 => { + current_block_3 = 12335206852979633349; + } + 117 => { + current_block_3 = 6485355310389479173; + } + 97 | 76 => { + current_block_3 = 10930428687648770479; + } + _ => return 0 as libc::c_int, + } + match current_block_3 { + 2998016214394651642 => { + current_block_3 = 9692932599894361468; + } + _ => {} + } + match current_block_3 { + 9692932599894361468 => { + current_block_3 = 1699338852606067860; + } + _ => {} + } + match current_block_3 { + 1699338852606067860 => { + current_block_3 = 14850354526820511888; + } + _ => {} + } + match current_block_3 { + 14850354526820511888 => { + current_block_3 = 12335206852979633349; + } + _ => {} + } + match current_block_3 { + 12335206852979633349 => { + current_block_3 = 6485355310389479173; + } + _ => {} + } + match current_block_3 { + 6485355310389479173 => {} + _ => {} + } + return 1 as libc::c_int; +} +fn parameter_brace_transform( + mut varname: *mut libc::c_char, + mut value: *mut libc::c_char, + mut ind: libc::c_int, + mut xform: *mut libc::c_char, + mut rtype: libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut vtype: libc::c_int = 0; + let mut xc: libc::c_int = 0; + let mut starsub: libc::c_int = 0; + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + xc = *xform.offset(0 as libc::c_int as isize) as libc::c_int; + } + if value.is_null() && xc != 'A' as i32 && xc != 'a' as i32 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + oname = this_command_name; + this_command_name = varname; + vtype = get_var_and_type( + varname, + value, + ind as arrayind_t, + quoted, + flags, + &mut v, + &mut val, + ); + if vtype == -(1 as libc::c_int) { + this_command_name = oname; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if valid_parameter_transform(xform) == 0 as libc::c_int { + this_command_name = oname; + return &mut expand_param_error; + } + starsub = vtype & 128 as libc::c_int; + vtype &= !(128 as libc::c_int); + if (xc == 'a' as i32 || xc == 'A' as i32) + && vtype == 0 as libc::c_int + && !varname.is_null() + && v.is_null() + { + v = find_variable(varname); + } + temp1 = 0 as *mut libc::c_void as *mut libc::c_char; + match vtype { + 0 | 3 => { + temp1 = string_transform(xc, v, val); + if vtype == 0 as libc::c_int { + if !val.is_null() { + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7980 as libc::c_int, + ); + } + } + if !temp1.is_null() { + val = if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + quote_string(temp1) + } else { + quote_escapes(temp1) + }; + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 7986 as libc::c_int, + ); + temp1 = val; + } + } + 2 => { + temp1 = array_transform(xc, v, starsub, quoted); + if !(!temp1.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !temp1.is_null() + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) == 0 as libc::c_int + { + val = quote_escapes(temp1); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8000 as libc::c_int, + ); + temp1 = val; + } + } + } + 1 => { + temp1 = parameter_list_transform( + xc, + *varname.offset(0 as libc::c_int as isize) as libc::c_int, + quoted, + ); + if !(!temp1.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !temp1.is_null() + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) == 0 as libc::c_int + { + val = quote_escapes(temp1); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8014 as libc::c_int, + ); + temp1 = val; + } + } + } + _ => {} + } + this_command_name = oname; + } + return temp1; +} +fn mb_substring( + mut string: *mut libc::c_char, + mut s: libc::c_int, + mut e: libc::c_int, +) -> *mut libc::c_char { + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut start: libc::c_int = 0; + let mut stop: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut slen: size_t = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + start = 0 as libc::c_int; + slen = if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + if !string.is_null() && *string.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *string.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *string.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(string) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + i = s; + while *string.offset(start as isize) as libc::c_int != 0 && { + let fresh87 = i; + i = i - 1; + fresh87 != 0 + } { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*string.offset(start as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(start as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(start as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(start as isize), + slen.wrapping_sub(start as libc::c_ulong), + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + start += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + start += 1; + } else { + start = (start as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + start += 1; + } + } + stop = start; + i = e - s; + while *string.offset(stop as isize) as libc::c_int != 0 && { + let fresh88 = i; + i = i - 1; + fresh88 != 0 + } { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*string.offset(stop as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(stop as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*string.offset(stop as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(stop as isize), + slen.wrapping_sub(stop as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + stop += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + stop += 1; + } else { + stop = (stop as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + stop += 1; + } + } + tt = substring(string, start, stop); + } + return tt; +} +fn parameter_brace_substring( + mut varname: *mut libc::c_char, + mut value: *mut libc::c_char, + mut ind: libc::c_int, + mut substr: *mut libc::c_char, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut e1: intmax_t = 0; + let mut e2: intmax_t = 0; + let mut vtype: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut starsub: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + if unsafe { + value.is_null() + && (*varname.offset(0 as libc::c_int as isize) as libc::c_int != '@' as i32 + && *varname.offset(0 as libc::c_int as isize) as libc::c_int != '*' as i32 + || *varname.offset(1 as libc::c_int as isize) as libc::c_int != 0) + } { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + oname = this_command_name; + this_command_name = varname; + vtype = get_var_and_type( + varname, + value, + ind as arrayind_t, + quoted, + flags, + &mut v, + &mut val, + ); + if vtype == -(1 as libc::c_int) { + this_command_name = oname; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + starsub = vtype & 128 as libc::c_int; + vtype &= !(128 as libc::c_int); + r = verify_substring_values(v, val, substr, vtype, &mut e1, &mut e2); + this_command_name = oname; + if r <= 0 as libc::c_int { + if vtype == 0 as libc::c_int { + if !val.is_null() { + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8098 as libc::c_int, + ); + } + } + return if r == 0 as libc::c_int { + &mut expand_param_error + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + match vtype { + 0 | 3 => { + if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + tt = mb_substring(val, e1 as libc::c_int, e2 as libc::c_int); + } else { + tt = substring(val, e1 as libc::c_int, e2 as libc::c_int); + } + if vtype == 0 as libc::c_int { + if !val.is_null() { + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8114 as libc::c_int, + ); + } + } + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + temp = quote_string(tt); + } else { + temp = if !tt.is_null() { + quote_escapes(tt) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + } + if !tt.is_null() { + sh_xfree( + tt as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8119 as libc::c_int, + ); + } + } + 1 | 2 => { + if vtype == 1 as libc::c_int { + tt = pos_params( + varname, + e1 as libc::c_int, + e2 as libc::c_int, + quoted, + pflags, + ); + } else if (*v).attributes & 0x40 as libc::c_int != 0 { + tt = assoc_subrange( + (*v).value as *mut HASH_TABLE, + e1, + e2, + starsub, + quoted, + pflags, + ); + } else { + tt = array_subrange((*v).value as *mut ARRAY, e1, e2, starsub, quoted, pflags); + } + if !tt.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0 { + temp = tt; + } else if !tt.is_null() + && quoted == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0 + { + temp = tt; + } else if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) == 0 as libc::c_int { + temp = if !tt.is_null() { + quote_escapes(tt) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !tt.is_null() { + sh_xfree( + tt as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8152 as libc::c_int, + ); + } + } else { + temp = tt; + } + } + _ => { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + } + } + return temp; +} +#[no_mangle] +pub fn pat_subst( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut rep: *mut libc::c_char, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut e: *mut libc::c_char = 0 as *mut libc::c_char; + let mut str: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut mstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rptr: libc::c_int = 0; + let mut mtype: libc::c_int = 0; + let mut rxpand: libc::c_int = 0; + let mut mlen: libc::c_int = 0; + let mut rsize: size_t = 0; + let mut l: size_t = 0; + let mut replen: size_t = 0; + let mut rslen: size_t = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if string.is_null() { + return strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(b"\0" as *const u8 as *const libc::c_char) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8200 as libc::c_int, + ) as *mut libc::c_char, + b"\0" as *const u8 as *const libc::c_char, + ); + } + mtype = mflags & 0x3 as libc::c_int; + rxpand = 0 as libc::c_int; + if (pat.is_null() || *pat as libc::c_int == 0 as libc::c_int) + && (mtype == 0x1 as libc::c_int || mtype == 0x2 as libc::c_int) + { + replen = if !rep.is_null() && *rep.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *rep.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *rep.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(rep) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + l = if !string.is_null() + && *string.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *string.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *string.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(string) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + ret = sh_xmalloc( + replen + .wrapping_add(l) + .wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8223 as libc::c_int, + ) as *mut libc::c_char; + if replen == 0 as libc::c_int as libc::c_ulong { + strcpy(ret, string); + } else if mtype == 0x1 as libc::c_int { + strcpy(ret, rep); + strcpy(ret.offset(replen as isize), string); + } else { + strcpy(ret, string); + strcpy(ret.offset(l as isize), rep); + } + return ret; + } else { + if *string as libc::c_int == 0 as libc::c_int + && match_pattern(string, pat, mtype, &mut s, &mut e) != 0 as libc::c_int + { + replen = if !rep.is_null() + && *rep.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *rep.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *rep.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(rep) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + ret = sh_xmalloc( + replen.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8241 as libc::c_int, + ) as *mut libc::c_char; + if replen == 0 as libc::c_int as libc::c_ulong { + *ret.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + } else { + strcpy(ret, rep); + } + return ret; + } + } + rsize = 64 as libc::c_int as size_t; + ret = sh_xmalloc( + rsize, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8249 as libc::c_int, + ) as *mut libc::c_char; + *ret.offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + send = string.offset(strlen(string) as isize); + replen = (if !rep.is_null() && *rep.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + (if *rep.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (if *rep.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(rep) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + }) + } else { + 1 as libc::c_int as libc::c_ulong + }) + } else { + 0 as libc::c_int as libc::c_ulong + }); + rptr = 0 as libc::c_int; + str = string; + while *str != 0 { + if match_pattern(str, pat, mtype, &mut s, &mut e) == 0 as libc::c_int { + break; + } + l = s.offset_from(str) as libc::c_long as size_t; + if !rep.is_null() && rxpand != 0 { + let mut x: libc::c_int = 0; + mlen = e.offset_from(s) as libc::c_long as libc::c_int; + mstr = sh_xmalloc( + (mlen + 1 as libc::c_int) as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8263 as libc::c_int, + ) as *mut libc::c_char; + x = 0 as libc::c_int; + while x < mlen { + *mstr.offset(x as isize) = *s.offset(x as isize); + x += 1; + } + *mstr.offset(mlen as isize) = '\u{0}' as i32 as libc::c_char; + rstr = strcreplace(rep, '&' as i32, mstr, 0 as libc::c_int); + sh_xfree( + mstr as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8268 as libc::c_int, + ); + rslen = strlen(rstr) as u64; + } else { + rstr = rep; + rslen = replen; + } + if (rptr as libc::c_ulong).wrapping_add(l.wrapping_add(rslen)) >= rsize { + while (rptr as libc::c_ulong).wrapping_add(l.wrapping_add(rslen)) >= rsize { + rsize = (rsize as libc::c_ulong) + .wrapping_add(64 as libc::c_int as libc::c_ulong) + as size_t as size_t; + } + ret = sh_xrealloc( + ret as *mut libc::c_void, + rsize, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8277 as libc::c_int, + ) as *mut libc::c_char; + } + if l != 0 { + strncpy(ret.offset(rptr as isize), str, l as usize); + rptr = (rptr as libc::c_ulong).wrapping_add(l) as libc::c_int as libc::c_int; + } + if replen != 0 { + strncpy(ret.offset(rptr as isize), rstr, rslen as usize); + rptr = (rptr as libc::c_ulong).wrapping_add(rslen) as libc::c_int as libc::c_int; + } + str = e; + if rstr != rep { + sh_xfree( + rstr as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8296 as libc::c_int, + ); + } + if mflags & 0x10 as libc::c_int == 0 as libc::c_int || mtype != 0 as libc::c_int { + break; + } + if s == e { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut origp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut origs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut clen: size_t = 0; + if (rptr + locale_mb_cur_max) as libc::c_ulong >= rsize { + while (rptr + locale_mb_cur_max) as libc::c_ulong >= rsize { + rsize = (rsize as libc::c_ulong) + .wrapping_add(64 as libc::c_int as libc::c_ulong) + as size_t as size_t; + } + ret = sh_xrealloc( + ret as *mut libc::c_void, + rsize, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8308 as libc::c_int, + ) as *mut libc::c_char; + } + origp = ret.offset(rptr as isize); + p = origp; + origs = str; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _k: libc::c_int = 0; + _k = is_basic(*str); + if _k != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *str as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + mblength = + (*str as libc::c_int != 0 as libc::c_int) as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + str, + send.offset_from(str) as libc::c_long as size_t, + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + _k = 0 as libc::c_int; + while (_k as libc::c_ulong) < mblength { + let fresh89 = str; + str = str.offset(1); + let fresh90 = p; + p = p.offset(1); + *fresh90 = *fresh89; + _k += 1; + } + } else { + let fresh91 = str; + str = str.offset(1); + let fresh92 = p; + p = p.offset(1); + *fresh92 = *fresh91; + } + rptr = (rptr as libc::c_long + p.offset_from(origp) as libc::c_long) as libc::c_int; + e = e.offset(str.offset_from(origs) as libc::c_long as isize); + } + } + if !str.is_null() && *str as libc::c_int != 0 { + if (rptr as libc::c_ulong).wrapping_add( + (if !str.is_null() && *str.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + (if *str.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (if *str.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(str) as usize + } else { + 2 as libc::c_int as usize + }) + } else { + 1 as libc::c_int as usize + }) + } else { + 0 as libc::c_int as usize + }) + .wrapping_add(1 as libc::c_int as usize) as u64, + ) >= rsize + { + while (rptr as libc::c_ulong).wrapping_add( + (if !str.is_null() && *str.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + (if *str.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + (if *str.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(str) as usize + } else { + 2 as libc::c_int as usize + }) + } else { + 1 as libc::c_int as usize + }) + } else { + 0 as libc::c_int as usize + }) + .wrapping_add(1 as libc::c_int as usize) as u64, + ) >= rsize + { + rsize = (rsize as libc::c_ulong) + .wrapping_add(64 as libc::c_int as libc::c_ulong) + as size_t as size_t; + } + ret = sh_xrealloc( + ret as *mut libc::c_void, + rsize, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8325 as libc::c_int, + ) as *mut libc::c_char; + } + strcpy(ret.offset(rptr as isize), str); + } else { + *ret.offset(rptr as isize) = '\u{0}' as i32 as libc::c_char; + } + } + return ret; +} +fn pos_params_pat_subst( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut rep: *mut libc::c_char, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut params: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pchar: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + params = list_rest_of_args(); + save = params; + unsafe { + if save.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + while !params.is_null() { + ret = pat_subst((*(*params).word).word, pat, rep, mflags); + w = alloc_word_desc(); + let ref mut fresh93 = (*w).word; + *fresh93 = if !ret.is_null() { + ret + } else { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(b"\0" as *const u8 as *const libc::c_char) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8353 as libc::c_int, + ) as *mut libc::c_char, + b"\0" as *const u8 as *const libc::c_char, + ) + }; + dispose_word((*params).word); + let ref mut fresh94 = (*params).word; + *fresh94 = w; + params = (*params).next; + } + pchar = if mflags & 0x80 as libc::c_int == 0x80 as libc::c_int { + '*' as i32 + } else { + '@' as i32 + }; + qflags = if mflags & 0x20 as libc::c_int == 0x20 as libc::c_int { + 0x1 as libc::c_int + } else { + 0 as libc::c_int + }; + pflags = if mflags & 0x40 as libc::c_int == 0x40 as libc::c_int { + 0x8 as libc::c_int + } else { + 0 as libc::c_int + }; + if pchar == '*' as i32 + && mflags & 0x40 as libc::c_int != 0 + && expand_no_split_dollar_star != 0 + && ifs_is_null != 0 + { + qflags |= 0x1 as libc::c_int; + } + ret = string_list_pos_params(pchar, save, qflags, pflags); + dispose_words(save); + } + return ret; +} +fn parameter_brace_patsub( + mut varname: *mut libc::c_char, + mut value: *mut libc::c_char, + mut ind: libc::c_int, + mut patsub: *mut libc::c_char, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut vtype: libc::c_int = 0; + let mut mflags: libc::c_int = 0; + let mut starsub: libc::c_int = 0; + let mut delim: libc::c_int = 0; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pat: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rep: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lpatsub: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + if value.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + oname = this_command_name; + this_command_name = varname; + vtype = get_var_and_type( + varname, + value, + ind as arrayind_t, + quoted, + flags, + &mut v, + &mut val, + ); + if vtype == -(1 as libc::c_int) { + this_command_name = oname; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + starsub = vtype & 128 as libc::c_int; + vtype &= !(128 as libc::c_int); + mflags = 0 as libc::c_int; + if *patsub as libc::c_int == '/' as i32 { + mflags |= 0x10 as libc::c_int; + patsub = patsub.offset(1); + } + lpatsub = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(patsub) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8414 as libc::c_int, + ) as *mut libc::c_char, + patsub, + ); + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + mflags |= 0x20 as libc::c_int; + } + if starsub != 0 { + mflags |= 0x80 as libc::c_int; + } + if pflags & 0x8 as libc::c_int != 0 { + mflags |= 0x40 as libc::c_int; + } + delim = skip_to_delim( + lpatsub, + if *patsub as libc::c_int == '/' as i32 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }, + b"/\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as libc::c_int, + ); + if *lpatsub.offset(delim as isize) as libc::c_int == '/' as i32 { + *lpatsub.offset(delim as isize) = 0 as libc::c_int as libc::c_char; + rep = lpatsub + .offset(delim as isize) + .offset(1 as libc::c_int as isize); + } else { + rep = 0 as *mut libc::c_void as *mut libc::c_char; + } + if !rep.is_null() && *rep as libc::c_int == '\u{0}' as i32 { + rep = 0 as *mut libc::c_void as *mut libc::c_char; + } + pat = getpattern(lpatsub, quoted, 1 as libc::c_int); + if !rep.is_null() { + if shell_compatibility_level > 42 as libc::c_int { + rep = expand_string_if_necessary( + rep, + quoted & !(0x1 as libc::c_int | 0x2 as libc::c_int), + ::std::mem::transmute:: *mut WORD_LIST>, Option>(Some( + ::std::mem::transmute::< + fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST, + fn() -> *mut WORD_LIST, + >(expand_string_unsplit), + )), + ); + } else if mflags & 0x20 as libc::c_int == 0 as libc::c_int { + rep = expand_string_if_necessary( + rep, + quoted, + ::std::mem::transmute:: *mut WORD_LIST>, Option>(Some( + ::std::mem::transmute::< + fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST, + fn() -> *mut WORD_LIST, + >(expand_string_unsplit), + )), + ); + } else { + rep = expand_string_to_string_internal( + rep, + quoted, + ::std::mem::transmute:: *mut WORD_LIST>, Option>(Some( + ::std::mem::transmute::< + fn(*mut libc::c_char, libc::c_int) -> *mut WORD_LIST, + fn() -> *mut WORD_LIST, + >(expand_string_unsplit), + )), + ); + } + } + p = pat; + if mflags & 0x10 as libc::c_int != 0 { + mflags |= 0 as libc::c_int; + } else if !pat.is_null() + && *pat.offset(0 as libc::c_int as isize) as libc::c_int == '#' as i32 + { + mflags |= 0x1 as libc::c_int; + p = p.offset(1); + } else if !pat.is_null() + && *pat.offset(0 as libc::c_int as isize) as libc::c_int == '%' as i32 + { + mflags |= 0x2 as libc::c_int; + p = p.offset(1); + } else { + mflags |= 0 as libc::c_int; + } + match vtype { + 0 | 3 => { + temp = pat_subst(val, p, rep, mflags); + if vtype == 0 as libc::c_int { + if !val.is_null() { + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8495 as libc::c_int, + ); + } + } + if !temp.is_null() { + tt = if mflags & 0x20 as libc::c_int != 0 { + quote_string(temp) + } else { + quote_escapes(temp) + }; + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8499 as libc::c_int, + ); + temp = tt; + } + } + 1 => { + if pflags & 0x4 as libc::c_int != 0 && mflags & 0x80 as libc::c_int != 0 { + mflags |= 0x40 as libc::c_int; + } + temp = pos_params_pat_subst(val, p, rep, mflags); + if !(!temp.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !(!temp.is_null() + && quoted == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0) + { + if !temp.is_null() && mflags & 0x20 as libc::c_int == 0 as libc::c_int { + tt = quote_escapes(temp); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8522 as libc::c_int, + ); + temp = tt; + } + } + } + } + 2 => { + if mflags & 0x80 as libc::c_int != 0 + && mflags & 0x40 as libc::c_int != 0 + && ifs_is_null != 0 + { + mflags |= 0x20 as libc::c_int; + } + if (*v).attributes & 0x40 as libc::c_int != 0 { + temp = assoc_patsub((*v).value as *mut HASH_TABLE, p, rep, mflags); + } else { + temp = array_patsub((*v).value as *mut ARRAY, p, rep, mflags); + } + if !(!temp.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !temp.is_null() && mflags & 0x20 as libc::c_int == 0 as libc::c_int { + tt = quote_escapes(temp); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8547 as libc::c_int, + ); + temp = tt; + } + } + } + _ => {} + } + if !pat.is_null() { + sh_xfree( + pat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8554 as libc::c_int, + ); + } + if !rep.is_null() { + sh_xfree( + rep as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8555 as libc::c_int, + ); + } + sh_xfree( + lpatsub as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8556 as libc::c_int, + ); + this_command_name = oname; + } + return temp; +} +fn pos_params_modcase( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut modop: libc::c_int, + mut mflags: libc::c_int, +) -> *mut libc::c_char { + let mut save: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut params: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pchar: libc::c_int = 0; + let mut qflags: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + params = list_rest_of_args(); + save = params; + if save.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + while !params.is_null() { + ret = sh_modcase((*(*params).word).word, pat, modop); + w = alloc_word_desc(); + let ref mut fresh95 = (*w).word; + *fresh95 = if !ret.is_null() { + ret + } else { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(b"\0" as *const u8 as *const libc::c_char) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8590 as libc::c_int, + ) as *mut libc::c_char, + b"\0" as *const u8 as *const libc::c_char, + ) + }; + dispose_word((*params).word); + let ref mut fresh96 = (*params).word; + *fresh96 = w; + params = (*params).next; + } + pchar = if mflags & 0x80 as libc::c_int == 0x80 as libc::c_int { + '*' as i32 + } else { + '@' as i32 + }; + qflags = if mflags & 0x20 as libc::c_int == 0x20 as libc::c_int { + 0x1 as libc::c_int + } else { + 0 as libc::c_int + }; + pflags = if mflags & 0x40 as libc::c_int == 0x40 as libc::c_int { + 0x8 as libc::c_int + } else { + 0 as libc::c_int + }; + if pchar == '*' as i32 && mflags & 0x40 as libc::c_int != 0 && ifs_is_null != 0 { + qflags |= 0x1 as libc::c_int; + } + ret = string_list_pos_params(pchar, save, qflags, pflags); + dispose_words(save); + } + return ret; +} +fn parameter_brace_casemod( + mut varname: *mut libc::c_char, + mut value: *mut libc::c_char, + mut ind: libc::c_int, + mut modspec: libc::c_int, + mut patspec: *mut libc::c_char, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut vtype: libc::c_int = 0; + let mut starsub: libc::c_int = 0; + let mut modop: libc::c_int = 0; + let mut mflags: libc::c_int = 0; + let mut x: libc::c_int = 0; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut pat: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lpat: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + if value.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + unsafe { + oname = this_command_name; + this_command_name = varname; + vtype = get_var_and_type( + varname, + value, + ind as arrayind_t, + quoted, + flags, + &mut v, + &mut val, + ); + if vtype == -(1 as libc::c_int) { + this_command_name = oname; + return 0 as *mut libc::c_void as *mut libc::c_char; + } + starsub = vtype & 128 as libc::c_int; + vtype &= !(128 as libc::c_int); + modop = 0 as libc::c_int; + mflags = 0 as libc::c_int; + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + mflags |= 0x20 as libc::c_int; + } + if starsub != 0 { + mflags |= 0x80 as libc::c_int; + } + if pflags & 0x8 as libc::c_int != 0 { + mflags |= 0x40 as libc::c_int; + } + p = patspec; + if modspec == '^' as i32 { + x = (!p.is_null() && *p.offset(0 as libc::c_int as isize) as libc::c_int == modspec) + as libc::c_int; + modop = if x != 0 { + 0x2 as libc::c_int + } else { + 0x40 as libc::c_int + }; + p = p.offset(x as isize); + } else if modspec == ',' as i32 { + x = (!p.is_null() && *p.offset(0 as libc::c_int as isize) as libc::c_int == modspec) + as libc::c_int; + modop = if x != 0 { + 0x1 as libc::c_int + } else { + 0x80 as libc::c_int + }; + p = p.offset(x as isize); + } else if modspec == '~' as i32 { + x = (!p.is_null() && *p.offset(0 as libc::c_int as isize) as libc::c_int == modspec) + as libc::c_int; + modop = if x != 0 { + 0x20 as libc::c_int + } else { + 0x10 as libc::c_int + }; + p = p.offset(x as isize); + } + lpat = if !p.is_null() { + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(p) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8670 as libc::c_int, + ) as *mut libc::c_char, + p, + ) + } else { + 0 as *mut libc::c_char + }; + pat = if !lpat.is_null() { + getpattern(lpat, quoted, 1 as libc::c_int) + } else { + 0 as *mut libc::c_char + }; + match vtype { + 0 | 3 => { + temp = sh_modcase(val, pat, modop); + if vtype == 0 as libc::c_int { + if !val.is_null() { + sh_xfree( + val as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8682 as libc::c_int, + ); + } + } + if !temp.is_null() { + tt = if mflags & 0x20 as libc::c_int != 0 { + quote_string(temp) + } else { + quote_escapes(temp) + }; + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8686 as libc::c_int, + ); + temp = tt; + } + } + 1 => { + temp = pos_params_modcase(val, pat, modop, mflags); + if !(!temp.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !temp.is_null() && mflags & 0x20 as libc::c_int == 0 as libc::c_int { + tt = quote_escapes(temp); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8700 as libc::c_int, + ); + temp = tt; + } + } + } + 2 => { + if mflags & 0x80 as libc::c_int != 0 + && mflags & 0x40 as libc::c_int != 0 + && ifs_is_null != 0 + { + mflags |= 0x20 as libc::c_int; + } + temp = if (*v).attributes & 0x40 as libc::c_int != 0 { + assoc_modcase((*v).value as *mut HASH_TABLE, pat, modop, mflags) + } else { + array_modcase((*v).value as *mut ARRAY, pat, modop, mflags) + }; + if !(!temp.is_null() && quoted == 0 as libc::c_int && ifs_is_null != 0) { + if !temp.is_null() && mflags & 0x20 as libc::c_int == 0 as libc::c_int { + tt = quote_escapes(temp); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8723 as libc::c_int, + ); + temp = tt; + } + } + } + _ => {} + } + if !pat.is_null() { + sh_xfree( + pat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8731 as libc::c_int, + ); + } + sh_xfree( + lpat as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8732 as libc::c_int, + ); + this_command_name = oname; + } + return temp; +} +fn chk_arithsub(mut s: *const libc::c_char, mut len: libc::c_int) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut count: libc::c_int = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + count = 0 as libc::c_int; + i = count; + while i < len { + if *s.offset(i as isize) as libc::c_int == '(' as i32 { + count += 1; + } else if *s.offset(i as isize) as libc::c_int == ')' as i32 { + count -= 1; + if count < 0 as libc::c_int { + return 0 as libc::c_int; + } + } + match *s.offset(i as isize) as libc::c_int { + 92 => { + i += 1; + if *s.offset(i as isize) != 0 { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _f_0: libc::c_int = 0; + _f_0 = is_basic(*s.offset(i as isize)); + if _f_0 != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_0 = (*s.offset(i as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int + as size_t; + } else { + state_bak_0 = state; + mblength_0 = + mbrlen(s.offset(i as isize), (len - i) as size_t, &mut state); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + i += 1; + } else if mblength_0 == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength_0) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + 39 => { + i += 1; + i = skip_single_quoted(s, len as size_t, i, 0 as libc::c_int); + } + 34 => { + i += 1; + i = skip_double_quoted( + s as *mut libc::c_char, + len as size_t, + i, + 0 as libc::c_int, + ); + } + _ => { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _f: libc::c_int = 0; + _f = is_basic(*s.offset(i as isize)); + if _f != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *s.offset(i as isize) as libc::c_int & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*s.offset(i as isize) as libc::c_int != 0 as libc::c_int) + as libc::c_int as size_t; + } else { + state_bak = state; + mblength = + mbrlen(s.offset(i as isize), (len - i) as size_t, &mut state); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + i += 1; + } else if mblength == 0 as libc::c_int as libc::c_ulong { + i += 1; + } else { + i = (i as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } + } else { + i += 1; + } + } + } + } + } + return (count == 0 as libc::c_int) as libc::c_int; +} +fn parameter_brace_expand( + mut string: *mut libc::c_char, + mut indexp: *mut libc::c_int, + mut quoted: libc::c_int, + mut pflags: libc::c_int, + mut quoted_dollar_atp: *mut libc::c_int, + mut contains_dollar_at: *mut libc::c_int, +) -> *mut WORD_DESC { + let mut current_block: u64; + let mut check_nullness: libc::c_int = 0; + let mut var_is_set: libc::c_int = 0; + let mut var_is_null: libc::c_int = 0; + let mut var_is_special: libc::c_int = 0; + let mut want_substring: libc::c_int = 0; + let mut want_indir: libc::c_int = 0; + let mut want_patsub: libc::c_int = 0; + let mut want_casemod: libc::c_int = 0; + let mut want_attributes: libc::c_int = 0; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tdesc: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut ret: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut t_index: libc::c_int = 0; + let mut sindex: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut tflag: libc::c_int = 0; + let mut modspec: libc::c_int = 0; + let mut local_pflags: libc::c_int = 0; + let mut all_element_arrayref: libc::c_int = 0; + let mut number: intmax_t = 0; + let mut ind: arrayind_t = 0; + value = 0 as *mut libc::c_void as *mut libc::c_char; + temp1 = value; + temp = temp1; + check_nullness = 0 as libc::c_int; + var_is_special = check_nullness; + var_is_null = var_is_special; + var_is_set = var_is_null; + want_attributes = 0 as libc::c_int; + want_casemod = want_attributes; + want_patsub = want_casemod; + want_indir = want_patsub; + want_substring = want_indir; + local_pflags = 0 as libc::c_int; + all_element_arrayref = 0 as libc::c_int; + unsafe { + sindex = *indexp; + sindex += 1; + t_index = sindex; + if *string.offset(t_index as isize) as libc::c_int == '#' as i32 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(*string.offset((t_index + 1 as libc::c_int) as isize) + as libc::c_uchar as libc::c_int + as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *string.offset((t_index + 1 as libc::c_int) as isize) as libc::c_int + == '_' as i32) + { + name = string_extract( + string, + &mut t_index, + b"}\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x2 as libc::c_int, + ); + } else { + name = string_extract( + string, + &mut t_index, + b"#%^,~:-=?+/@}\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x2 as libc::c_int, + ); + } + if *name as libc::c_int == 0 as libc::c_int + && sindex == t_index + && *string.offset(sindex as isize) as libc::c_int == '@' as i32 + { + name = sh_xrealloc( + name as *mut libc::c_void, + 2 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8839 as libc::c_int, + ) as *mut libc::c_char; + *name.offset(0 as libc::c_int as isize) = '@' as i32 as libc::c_char; + *name.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + t_index += 1; + } else if *name as libc::c_int == '!' as i32 + && t_index > sindex + && *string.offset(t_index as isize) as libc::c_int == '@' as i32 + && *string.offset((t_index + 1 as libc::c_int) as isize) as libc::c_int == '}' as i32 + { + name = sh_xrealloc( + name as *mut libc::c_void, + (t_index - sindex + 2 as libc::c_int) as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8846 as libc::c_int, + ) as *mut libc::c_char; + *name.offset((t_index - sindex) as isize) = '@' as i32 as libc::c_char; + *name.offset((t_index - sindex + 1 as libc::c_int) as isize) = + '\u{0}' as i32 as libc::c_char; + t_index += 1; + } + ret = 0 as *mut WORD_DESC; + tflag = 0 as libc::c_int; + ind = -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long; + if sindex == t_index + && (*string.offset(t_index as isize) as libc::c_int == '-' as i32 + || *string.offset(t_index as isize) as libc::c_int == '?' as i32 + || *string.offset(t_index as isize) as libc::c_int == '#' as i32 + || *string.offset(t_index as isize) as libc::c_int == '@' as i32) + || sindex == t_index + && *string.offset(sindex as isize) as libc::c_int == '#' as i32 + && (*string.offset((sindex + 1 as libc::c_int) as isize) as libc::c_int + == '-' as i32 + || *string.offset((sindex + 1 as libc::c_int) as isize) as libc::c_int + == '?' as i32 + || *string.offset((sindex + 1 as libc::c_int) as isize) as libc::c_int + == '#' as i32 + || *string.offset((sindex + 1 as libc::c_int) as isize) as libc::c_int + == '@' as i32) + || sindex == t_index - 1 as libc::c_int + && *string.offset(sindex as isize) as libc::c_int == '!' as i32 + && (posixly_correct == 0 as libc::c_int + && *string.offset(t_index as isize) as libc::c_int == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *string.offset(t_index as isize) as libc::c_int == '?' as i32 + || *string.offset(t_index as isize) as libc::c_int == '@' as i32 + || *string.offset(t_index as isize) as libc::c_int == '*' as i32) + { + t_index += 1; + temp1 = string_extract( + string, + &mut t_index, + b"#%:-=?+/@}\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0 as libc::c_int, + ); + name = sh_xrealloc( + name as *mut libc::c_void, + (3 as libc::c_int as libc::c_ulong).wrapping_add(strlen(temp1) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8868 as libc::c_int, + ) as *mut libc::c_char; + *name = *string.offset(sindex as isize); + if *string.offset(sindex as isize) as libc::c_int == '!' as i32 { + *name.offset(1 as libc::c_int as isize) = + *string.offset((sindex + 1 as libc::c_int) as isize); + strcpy(name.offset(2 as libc::c_int as isize), temp1); + } else { + strcpy(name.offset(1 as libc::c_int as isize), temp1); + } + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8878 as libc::c_int, + ); + } + sindex = t_index; + c = *string.offset(sindex as isize) as libc::c_int; + if c != 0 { + sindex += 1; + } + if c == ':' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*string.offset(sindex as isize) as libc::c_uchar as isize) + & 0x1000 as libc::c_int + != 0 + { + check_nullness += 1; + c = *string.offset(sindex as isize) as libc::c_int; + if c != 0 { + sindex += 1; + } + } else if c == ':' as i32 && *string.offset(sindex as isize) as libc::c_int != '}' as i32 { + want_substring = 1 as libc::c_int; + } else if c == '/' as i32 { + want_patsub = 1 as libc::c_int; + } else if c == '^' as i32 || c == ',' as i32 || c == '~' as i32 { + modspec = c; + want_casemod = 1 as libc::c_int; + } else if c == '@' as i32 + && (*string.offset(sindex as isize) as libc::c_int == 'a' as i32 + || *string.offset(sindex as isize) as libc::c_int == 'A' as i32) + && *string.offset((sindex + 1 as libc::c_int) as isize) as libc::c_int == '}' as i32 + { + want_attributes = 1 as libc::c_int; + local_pflags |= 0x40 as libc::c_int; + } + if *name.offset(0 as libc::c_int as isize) as libc::c_int == '#' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && check_nullness == 0 as libc::c_int + && (c == '-' as i32 || c == '?' as i32 || c == '#' as i32 || c == '@' as i32) + && *string.offset(sindex as isize) as libc::c_int == '}' as i32 + { + name = sh_xrealloc( + name as *mut libc::c_void, + 3 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8922 as libc::c_int, + ) as *mut libc::c_char; + *name.offset(1 as libc::c_int as isize) = c as libc::c_char; + *name.offset(2 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + let fresh97 = sindex; + sindex = sindex + 1; + c = *string.offset(fresh97 as isize) as libc::c_int; + } + if *name.offset(0 as libc::c_int as isize) as libc::c_int == '#' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && check_nullness == 0 as libc::c_int + && (if c != 0 { + (mbschr(b"%:=+/\0" as *const u8 as *const libc::c_char, c) + != 0 as *mut libc::c_void as *mut libc::c_char) as libc::c_int + } else { + 0 as libc::c_int + }) != 0 + && *string.offset(sindex as isize) as libc::c_int == '}' as i32 + { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } else { + want_indir = (*name as libc::c_int == '!' as i32 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()) + .offset(*name.offset(1 as libc::c_int as isize) as libc::c_uchar + as libc::c_int as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *name.offset(1 as libc::c_int as isize) as libc::c_uchar as libc::c_int + == '_' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int >= '0' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int <= '9' as i32 + || (posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int == '*' as i32))) + as libc::c_int; + if *name as libc::c_int != 0 + && (*name as libc::c_int >= '0' as i32 + && *name as libc::c_int <= '9' as i32 + && all_digits(name) != 0 + || *name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*name as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + || want_indir != 0 + && *name.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + && (posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int + == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *name.offset(1 as libc::c_int as isize) as libc::c_int + == '?' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int + == '@' as i32 + || *name.offset(1 as libc::c_int as isize) as libc::c_int + == '*' as i32)) + { + var_is_special += 1; + } + if *name as libc::c_int == '#' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int != 0 + { + if *string.offset((sindex - 1 as libc::c_int) as isize) as libc::c_int != '}' as i32 + || valid_length_expression(name) == 0 as libc::c_int + { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } else { + number = parameter_brace_expand_length(name); + if number + == -(9223372036854775807 as libc::c_long) - 1 as libc::c_int as libc::c_long + && unbound_vars_is_error != 0 + { + set_exit_status(1 as libc::c_int); + err_unboundvar(name.offset(1 as libc::c_int as isize)); + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8968 as libc::c_int, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 8971 as libc::c_int, + ); + *indexp = sindex; + if number < 0 as libc::c_int as libc::c_long { + return &mut expand_wdesc_error; + } else { + ret = alloc_word_desc(); + let ref mut fresh98 = (*ret).word; + *fresh98 = itos(number); + return ret; + } + } + } else { + if *name.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = 1 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + tflag |= (1 as libc::c_int) << 8 as libc::c_int; + } + if want_indir != 0 + && *string.offset((sindex - 1 as libc::c_int) as isize) as libc::c_int + == '}' as i32 + && (*string.offset((sindex - 2 as libc::c_int) as isize) as libc::c_int + == '*' as i32 + || *string.offset((sindex - 2 as libc::c_int) as isize) as libc::c_int + == '@' as i32) + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()) + .offset(*name.offset(1 as libc::c_int as isize) as libc::c_uchar + as libc::c_int as isize) as libc::c_int + & _ISalpha as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || *name.offset(1 as libc::c_int as isize) as libc::c_uchar as libc::c_int + == '_' as i32) + { + let mut x: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut xlist: *mut WORD_LIST = 0 as *mut WORD_LIST; + temp1 = + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add( + strlen(name.offset(1 as libc::c_int as isize)) as u64 + ), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9004 as libc::c_int, + ) as *mut libc::c_char, + name.offset(1 as libc::c_int as isize), + ); + number = strlen(temp1) as intmax_t; + *temp1.offset((number - 1 as libc::c_int as libc::c_long) as isize) = + '\u{0}' as i32 as libc::c_char; + x = all_variables_matching_prefix(temp1); + xlist = strvec_to_word_list(x, 0 as libc::c_int, 0 as libc::c_int); + if *string.offset((sindex - 2 as libc::c_int) as isize) as libc::c_int + == '*' as i32 + { + temp = string_list_dollar_star(xlist, quoted, 0 as libc::c_int); + } else { + temp = string_list_dollar_at(xlist, quoted, 0 as libc::c_int); + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = 1 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + tflag |= (1 as libc::c_int) << 8 as libc::c_int; + } + sh_xfree( + x as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9021 as libc::c_int, + ); + dispose_words(xlist); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9023 as libc::c_int, + ); + *indexp = sindex; + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9026 as libc::c_int, + ); + ret = alloc_word_desc(); + let ref mut fresh99 = (*ret).word; + *fresh99 = temp; + (*ret).flags = tflag; + return ret; + } + if want_indir != 0 + && *string.offset((sindex - 1 as libc::c_int) as isize) as libc::c_int + == '}' as i32 + && *string.offset((sindex - 2 as libc::c_int) as isize) as libc::c_int + == ']' as i32 + && valid_array_reference( + name.offset(1 as libc::c_int as isize), + 0 as libc::c_int, + ) != 0 + { + let mut x_0: *mut libc::c_char = 0 as *mut libc::c_char; + let mut x1: *mut libc::c_char = 0 as *mut libc::c_char; + temp1 = + strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add( + strlen(name.offset(1 as libc::c_int as isize)) as u64 + ), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9041 as libc::c_int, + ) as *mut libc::c_char, + name.offset(1 as libc::c_int as isize), + ); + x_0 = array_variable_name( + temp1, + 0 as libc::c_int, + &mut x1, + 0 as *mut libc::c_int, + ); + if !x_0.is_null() { + sh_xfree( + x_0 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9043 as libc::c_int, + ); + } + if (*x1.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 + || *x1.offset(0 as libc::c_int as isize) as libc::c_int == '*' as i32) + && *x1.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + { + temp = array_keys(temp1, quoted, pflags); + if *x1.offset(0 as libc::c_int as isize) as libc::c_int == '@' as i32 { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = 1 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + tflag |= (1 as libc::c_int) << 8 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9057 as libc::c_int, + ); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9058 as libc::c_int, + ); + *indexp = sindex; + ret = alloc_word_desc(); + let ref mut fresh100 = (*ret).word; + *fresh100 = temp; + (*ret).flags = tflag; + return ret; + } + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9067 as libc::c_int, + ); + } + if valid_brace_expansion_word( + (if want_indir != 0 { + name.offset(1 as libc::c_int as isize) + } else { + name + }), + var_is_special, + ) == 0 as libc::c_int + { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } else { + if want_indir != 0 { + tdesc = parameter_brace_expand_indir( + name.offset(1 as libc::c_int as isize), + var_is_special, + quoted, + pflags | local_pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + if tdesc == &mut expand_wdesc_error as *mut WORD_DESC + || tdesc == &mut expand_wdesc_fatal as *mut WORD_DESC + { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + current_block = 1002422616457006153; + } else { + if !tdesc.is_null() && (*tdesc).flags != 0 { + (*tdesc).flags &= !((1 as libc::c_int) << 24 as libc::c_int); + } + current_block = 10570719081292997246; + } + } else { + local_pflags |= + 0x2 as libc::c_int | pflags & (0x4 as libc::c_int | 0x8 as libc::c_int); + tdesc = parameter_brace_expand_word( + name, + var_is_special, + quoted, + local_pflags, + &mut ind, + ); + current_block = 10570719081292997246; + } + match current_block { + 1002422616457006153 => {} + _ => { + if tdesc == &mut expand_wdesc_error as *mut WORD_DESC + || tdesc == &mut expand_wdesc_fatal as *mut WORD_DESC + { + tflag = 0 as libc::c_int; + tdesc = 0 as *mut WORD_DESC; + } + if !tdesc.is_null() { + temp = (*tdesc).word; + tflag = (*tdesc).flags; + dispose_word_desc(tdesc); + } else { + temp = 0 as *mut libc::c_char; + } + if temp == &mut expand_param_error as *mut libc::c_char + || temp == &mut expand_param_fatal as *mut libc::c_char + { + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9116 as libc::c_int, + ); + } + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9117 as libc::c_int, + ); + } + return if temp == &mut expand_param_error as *mut libc::c_char { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + if valid_array_reference(name, 0 as libc::c_int) != 0 { + let mut qflags: libc::c_int = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + qflags = quoted; + if pflags & 0x8 as libc::c_int != 0 { + qflags |= 0x1 as libc::c_int; + } + t = mbschr(name, '[' as i32); + if !t.is_null() + && (*t.offset(1 as libc::c_int as isize) as libc::c_int + == '@' as i32 + || *t.offset(1 as libc::c_int as isize) as libc::c_int + == '*' as i32) + && *t.offset(2 as libc::c_int as isize) as libc::c_int + == ']' as i32 + { + all_element_arrayref = 1 as libc::c_int; + if expand_no_split_dollar_star != 0 + && *t.offset(1 as libc::c_int as isize) as libc::c_int + == '*' as i32 + { + qflags |= 0x1 as libc::c_int; + } + } + chk_atstar( + name, + qflags, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + } + var_is_set = (temp != 0 as *mut libc::c_char) as libc::c_int; + var_is_null = (check_nullness != 0 + && (var_is_set == 0 as libc::c_int + || *temp as libc::c_int == 0 as libc::c_int)) + as libc::c_int; + if check_nullness != 0 { + var_is_null |= (var_is_set != 0 + && var_is_special != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32)) + as libc::c_int; + } + if check_nullness != 0 { + var_is_null |= (var_is_set != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + && valid_array_reference(name, 0 as libc::c_int) != 0 + && chk_atstar( + name, + 0 as libc::c_int, + 0 as libc::c_int, + 0 as *mut libc::c_int, + 0 as *mut libc::c_int, + ) != 0) + as libc::c_int; + } + if c != 0 && c != '}' as i32 { + value = extract_dollar_brace_string( + string, + &mut sindex, + quoted, + if c == '%' as i32 + || c == '#' as i32 + || c == '/' as i32 + || c == '^' as i32 + || c == ',' as i32 + || c == ':' as i32 + { + 0x100 as libc::c_int | 0x200 as libc::c_int + } else { + 0x200 as libc::c_int + }, + ); + if *string.offset(sindex as isize) as libc::c_int == '}' as i32 { + sindex += 1; + current_block = 11322929247169729670; + } else { + current_block = 1002422616457006153; + } + } else { + value = 0 as *mut libc::c_void as *mut libc::c_char; + current_block = 11322929247169729670; + } + match current_block { + 1002422616457006153 => {} + _ => { + *indexp = sindex; + if want_substring != 0 + || want_patsub != 0 + || want_casemod != 0 + || c == '@' as i32 + || c == '#' as i32 + || c == '%' as i32 + || c == '}' as i32 + { + if var_is_set == 0 as libc::c_int + && unbound_vars_is_error != 0 + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + != '@' as i32 + && *name.offset(0 as libc::c_int as isize) + as libc::c_int + != '*' as i32 + || *name.offset(1 as libc::c_int as isize) + as libc::c_int + != 0) + && all_element_arrayref == 0 as libc::c_int + { + set_exit_status(1 as libc::c_int); + err_unboundvar(name); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9183 as libc::c_int, + ); + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9184 as libc::c_int, + ); + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9185 as libc::c_int, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + } + if want_substring != 0 { + temp1 = parameter_brace_substring( + name, + temp, + ind as libc::c_int, + value, + quoted, + pflags, + if tflag & (1 as libc::c_int) << 24 as libc::c_int != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9194 as libc::c_int, + ); + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9195 as libc::c_int, + ); + } + if temp1 == &mut expand_param_error as *mut libc::c_char + || temp1 == &mut expand_param_fatal as *mut libc::c_char + { + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9199 as libc::c_int, + ); + } + return if temp1 + == &mut expand_param_error as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh101 = (*ret).word; + *fresh101 = temp1; + if !temp1.is_null() + && (quoted_dollar_atp.is_null() + || *quoted_dollar_atp == 0 as libc::c_int) + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) << 1 as libc::c_int + | (1 as libc::c_int) << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0 + { + (*ret).flags |= (1 as libc::c_int) << 3 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= (1 as libc::c_int) << 3 as libc::c_int; + } + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9220 as libc::c_int, + ); + } + return ret; + } else { + if want_patsub != 0 { + temp1 = parameter_brace_patsub( + name, + temp, + ind as libc::c_int, + value, + quoted, + pflags, + if tflag & (1 as libc::c_int) << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9226 as libc::c_int, + ); + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9227 as libc::c_int, + ); + } + if temp1 == &mut expand_param_error as *mut libc::c_char + || temp1 + == &mut expand_param_fatal as *mut libc::c_char + { + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9231 as libc::c_int, + ); + } + return if temp1 + == &mut expand_param_error as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh102 = (*ret).word; + *fresh102 = temp1; + if !temp1.is_null() + && (quoted_dollar_atp.is_null() + || *quoted_dollar_atp == 0 as libc::c_int) + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9245 as libc::c_int, + ); + } + return ret; + } else { + if want_casemod != 0 { + temp1 = parameter_brace_casemod( + name, + temp, + ind as libc::c_int, + modspec, + value, + quoted, + pflags, + if tflag + & (1 as libc::c_int) << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9252 as libc::c_int, + ); + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9253 as libc::c_int, + ); + } + if temp1 + == &mut expand_param_error as *mut libc::c_char + || temp1 + == &mut expand_param_fatal + as *mut libc::c_char + { + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9257 as libc::c_int, + ); + } + return if temp1 + == &mut expand_param_error + as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh103 = (*ret).word; + *fresh103 = temp1; + if !temp1.is_null() + && (quoted_dollar_atp.is_null() + || *quoted_dollar_atp == 0 as libc::c_int) + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + if !name.is_null() { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9271 as libc::c_int, + ); + } + return ret; + } + } + } + match c { + 125 => { + current_block = 9668344364916463090; + match current_block { + 6396965539391641386 => { + temp1 = parameter_brace_transform( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + pflags, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9297 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9298 as libc::c_int, + ); + if temp1 + == &mut expand_param_error + as *mut libc::c_char + || temp1 + == &mut expand_param_fatal + as *mut libc::c_char + { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9302 as libc::c_int, + ); + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: bad substitution\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + if !string.is_null() { + string + } else { + b"??\0" as *const u8 + as *const libc::c_char + }, + ); + return if temp1 + == &mut expand_param_error + as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh104 = (*ret).word; + *fresh104 = temp1; + if !temp1.is_null() + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1 + .offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name + .offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9316 as libc::c_int, + ); + return ret; + } + 6979992077050147181 => { + current_block = 17370964531530178945; + } + 1951049175126603298 => { + if var_is_set != 0 + && var_is_null == 0 as libc::c_int + { + if c == '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = + 0 as libc::c_int; + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9359 as libc::c_int, + ); + } + if !value.is_null() { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= 0x80 as libc::c_int; + } + ret = parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9374 as libc::c_int, + ); + } else { + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + } + } else if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9381 as libc::c_int, + ); + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9387 as libc::c_int, + ); + } + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + if c == '=' as i32 && var_is_special != 0 { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"$%s: cannot assign in this way\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9393 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9394 as libc::c_int, + ); + return &mut expand_wdesc_error; + } else { + if c == '?' as i32 { + parameter_brace_expand_error( + name, + value, + check_nullness, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } else { + if c != '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp + .is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() + { + *contains_dollar_at = + 0 as libc::c_int; + } + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= + 0x80 as libc::c_int; + } + ret = + parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + } + } + } + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9423 as libc::c_int, + ); + } + current_block = 9668344364916463090; + } + _ => {} + } + match current_block { + 17370964531530178945 => { + if value.is_null() + || *value as libc::c_int == '\u{0}' as i32 + || temp.is_null() + || *temp as libc::c_int == '\u{0}' as i32 + { + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9323 as libc::c_int, + ); + } + } else { + temp1 = parameter_brace_remove_pattern( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9327 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9328 as libc::c_int, + ); + ret = alloc_word_desc(); + let ref mut fresh105 = (*ret).word; + *fresh105 = temp1; + if !temp1.is_null() + && (*temp1 + .offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name + .offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9338 as libc::c_int, + ); + return ret; + } + } + _ => {} + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9428 as libc::c_int, + ); + if ret.is_null() { + ret = alloc_word_desc(); + (*ret).flags = tflag; + let ref mut fresh106 = (*ret).word; + *fresh106 = temp; + } + return ret; + } + 64 => { + current_block = 6396965539391641386; + match current_block { + 6396965539391641386 => { + temp1 = parameter_brace_transform( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + pflags, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9297 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9298 as libc::c_int, + ); + if temp1 + == &mut expand_param_error + as *mut libc::c_char + || temp1 + == &mut expand_param_fatal + as *mut libc::c_char + { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9302 as libc::c_int, + ); + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: bad substitution\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + if !string.is_null() { + string + } else { + b"??\0" as *const u8 + as *const libc::c_char + }, + ); + return if temp1 + == &mut expand_param_error + as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh104 = (*ret).word; + *fresh104 = temp1; + if !temp1.is_null() + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1 + .offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name + .offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9316 as libc::c_int, + ); + return ret; + } + 6979992077050147181 => { + current_block = 17370964531530178945; + } + 1951049175126603298 => { + if var_is_set != 0 + && var_is_null == 0 as libc::c_int + { + if c == '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = + 0 as libc::c_int; + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9359 as libc::c_int, + ); + } + if !value.is_null() { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= 0x80 as libc::c_int; + } + ret = parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9374 as libc::c_int, + ); + } else { + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + } + } else if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9381 as libc::c_int, + ); + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9387 as libc::c_int, + ); + } + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + if c == '=' as i32 && var_is_special != 0 { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"$%s: cannot assign in this way\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9393 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9394 as libc::c_int, + ); + return &mut expand_wdesc_error; + } else { + if c == '?' as i32 { + parameter_brace_expand_error( + name, + value, + check_nullness, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } else { + if c != '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp + .is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() + { + *contains_dollar_at = + 0 as libc::c_int; + } + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= + 0x80 as libc::c_int; + } + ret = + parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + } + } + } + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9423 as libc::c_int, + ); + } + current_block = 9668344364916463090; + } + _ => {} + } + match current_block { + 17370964531530178945 => { + if value.is_null() + || *value as libc::c_int == '\u{0}' as i32 + || temp.is_null() + || *temp as libc::c_int == '\u{0}' as i32 + { + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9323 as libc::c_int, + ); + } + } else { + temp1 = parameter_brace_remove_pattern( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9327 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9328 as libc::c_int, + ); + ret = alloc_word_desc(); + let ref mut fresh105 = (*ret).word; + *fresh105 = temp1; + if !temp1.is_null() + && (*temp1 + .offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name + .offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9338 as libc::c_int, + ); + return ret; + } + } + _ => {} + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9428 as libc::c_int, + ); + if ret.is_null() { + ret = alloc_word_desc(); + (*ret).flags = tflag; + let ref mut fresh106 = (*ret).word; + *fresh106 = temp; + } + return ret; + } + 35 => { + current_block = 6979992077050147181; + match current_block { + 6396965539391641386 => { + temp1 = parameter_brace_transform( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + pflags, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9297 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9298 as libc::c_int, + ); + if temp1 + == &mut expand_param_error + as *mut libc::c_char + || temp1 + == &mut expand_param_fatal + as *mut libc::c_char + { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9302 as libc::c_int, + ); + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: bad substitution\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + if !string.is_null() { + string + } else { + b"??\0" as *const u8 + as *const libc::c_char + }, + ); + return if temp1 + == &mut expand_param_error + as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh104 = (*ret).word; + *fresh104 = temp1; + if !temp1.is_null() + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1 + .offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name + .offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9316 as libc::c_int, + ); + return ret; + } + 6979992077050147181 => { + current_block = 17370964531530178945; + } + 1951049175126603298 => { + if var_is_set != 0 + && var_is_null == 0 as libc::c_int + { + if c == '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = + 0 as libc::c_int; + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9359 as libc::c_int, + ); + } + if !value.is_null() { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= 0x80 as libc::c_int; + } + ret = parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9374 as libc::c_int, + ); + } else { + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + } + } else if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9381 as libc::c_int, + ); + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9387 as libc::c_int, + ); + } + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + if c == '=' as i32 && var_is_special != 0 { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"$%s: cannot assign in this way\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9393 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9394 as libc::c_int, + ); + return &mut expand_wdesc_error; + } else { + if c == '?' as i32 { + parameter_brace_expand_error( + name, + value, + check_nullness, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } else { + if c != '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp + .is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() + { + *contains_dollar_at = + 0 as libc::c_int; + } + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= + 0x80 as libc::c_int; + } + ret = + parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + } + } + } + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9423 as libc::c_int, + ); + } + current_block = 9668344364916463090; + } + _ => {} + } + match current_block { + 17370964531530178945 => { + if value.is_null() + || *value as libc::c_int == '\u{0}' as i32 + || temp.is_null() + || *temp as libc::c_int == '\u{0}' as i32 + { + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9323 as libc::c_int, + ); + } + } else { + temp1 = parameter_brace_remove_pattern( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9327 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9328 as libc::c_int, + ); + ret = alloc_word_desc(); + let ref mut fresh105 = (*ret).word; + *fresh105 = temp1; + if !temp1.is_null() + && (*temp1 + .offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name + .offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9338 as libc::c_int, + ); + return ret; + } + } + _ => {} + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9428 as libc::c_int, + ); + if ret.is_null() { + ret = alloc_word_desc(); + (*ret).flags = tflag; + let ref mut fresh106 = (*ret).word; + *fresh106 = temp; + } + return ret; + } + 37 => { + current_block = 17370964531530178945; + match current_block { + 6396965539391641386 => { + temp1 = parameter_brace_transform( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + pflags, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9297 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9298 as libc::c_int, + ); + if temp1 + == &mut expand_param_error + as *mut libc::c_char + || temp1 + == &mut expand_param_fatal + as *mut libc::c_char + { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9302 as libc::c_int, + ); + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: bad substitution\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + if !string.is_null() { + string + } else { + b"??\0" as *const u8 + as *const libc::c_char + }, + ); + return if temp1 + == &mut expand_param_error + as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh104 = (*ret).word; + *fresh104 = temp1; + if !temp1.is_null() + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1 + .offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name + .offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9316 as libc::c_int, + ); + return ret; + } + 6979992077050147181 => { + current_block = 17370964531530178945; + } + 1951049175126603298 => { + if var_is_set != 0 + && var_is_null == 0 as libc::c_int + { + if c == '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = + 0 as libc::c_int; + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9359 as libc::c_int, + ); + } + if !value.is_null() { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= 0x80 as libc::c_int; + } + ret = parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9374 as libc::c_int, + ); + } else { + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + } + } else if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9381 as libc::c_int, + ); + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9387 as libc::c_int, + ); + } + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + if c == '=' as i32 && var_is_special != 0 { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"$%s: cannot assign in this way\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9393 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9394 as libc::c_int, + ); + return &mut expand_wdesc_error; + } else { + if c == '?' as i32 { + parameter_brace_expand_error( + name, + value, + check_nullness, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } else { + if c != '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp + .is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() + { + *contains_dollar_at = + 0 as libc::c_int; + } + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= + 0x80 as libc::c_int; + } + ret = + parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + } + } + } + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9423 as libc::c_int, + ); + } + current_block = 9668344364916463090; + } + _ => {} + } + match current_block { + 17370964531530178945 => { + if value.is_null() + || *value as libc::c_int == '\u{0}' as i32 + || temp.is_null() + || *temp as libc::c_int == '\u{0}' as i32 + { + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9323 as libc::c_int, + ); + } + } else { + temp1 = parameter_brace_remove_pattern( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9327 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9328 as libc::c_int, + ); + ret = alloc_word_desc(); + let ref mut fresh105 = (*ret).word; + *fresh105 = temp1; + if !temp1.is_null() + && (*temp1 + .offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name + .offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9338 as libc::c_int, + ); + return ret; + } + } + _ => {} + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9428 as libc::c_int, + ); + if ret.is_null() { + ret = alloc_word_desc(); + (*ret).flags = tflag; + let ref mut fresh106 = (*ret).word; + *fresh106 = temp; + } + return ret; + } + 45 | 61 | 63 | 43 => { + current_block = 1951049175126603298; + match current_block { + 6396965539391641386 => { + temp1 = parameter_brace_transform( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + pflags, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9297 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9298 as libc::c_int, + ); + if temp1 + == &mut expand_param_error + as *mut libc::c_char + || temp1 + == &mut expand_param_fatal + as *mut libc::c_char + { + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9302 as libc::c_int, + ); + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: bad substitution\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + if !string.is_null() { + string + } else { + b"??\0" as *const u8 + as *const libc::c_char + }, + ); + return if temp1 + == &mut expand_param_error + as *mut libc::c_char + { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + ret = alloc_word_desc(); + let ref mut fresh104 = (*ret).word; + *fresh104 = temp1; + if !temp1.is_null() + && (*temp1.offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1 + .offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name.offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name + .offset(1 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= + (1 as libc::c_int) << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9316 as libc::c_int, + ); + return ret; + } + 6979992077050147181 => { + current_block = 17370964531530178945; + } + 1951049175126603298 => { + if var_is_set != 0 + && var_is_null == 0 as libc::c_int + { + if c == '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp.is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = + 0 as libc::c_int; + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9359 as libc::c_int, + ); + } + if !value.is_null() { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= 0x80 as libc::c_int; + } + ret = parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9374 as libc::c_int, + ); + } else { + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + } + } else if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9381 as libc::c_int, + ); + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9387 as libc::c_int, + ); + } + temp = 0 as *mut libc::c_void + as *mut libc::c_char; + if c == '=' as i32 && var_is_special != 0 { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"$%s: cannot assign in this way\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + name, + ); + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9393 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9394 as libc::c_int, + ); + return &mut expand_wdesc_error; + } else { + if c == '?' as i32 { + parameter_brace_expand_error( + name, + value, + check_nullness, + ); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } else { + if c != '+' as i32 { + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + && !quoted_dollar_atp + .is_null() + { + *quoted_dollar_atp = + 0 as libc::c_int; + } + if !contains_dollar_at.is_null() + { + *contains_dollar_at = + 0 as libc::c_int; + } + if quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + quoted |= + 0x80 as libc::c_int; + } + ret = + parameter_brace_expand_rhs( + name, + value, + c, + quoted, + pflags, + quoted_dollar_atp, + contains_dollar_at, + ); + } + } + } + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9423 as libc::c_int, + ); + } + current_block = 9668344364916463090; + } + _ => {} + } + match current_block { + 17370964531530178945 => { + if value.is_null() + || *value as libc::c_int == '\u{0}' as i32 + || temp.is_null() + || *temp as libc::c_int == '\u{0}' as i32 + { + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9323 as libc::c_int, + ); + } + } else { + temp1 = parameter_brace_remove_pattern( + name, + temp, + ind as libc::c_int, + value, + c, + quoted, + if tflag + & (1 as libc::c_int) + << 24 as libc::c_int + != 0 + { + 0x4 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9327 as libc::c_int, + ); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9328 as libc::c_int, + ); + ret = alloc_word_desc(); + let ref mut fresh105 = (*ret).word; + *fresh105 = temp1; + if !temp1.is_null() + && (*temp1 + .offset(0 as libc::c_int as isize) + as libc::c_int + == '\u{7f}' as i32 + && *temp1.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == '\u{0}' as i32) + && quoted + & (0x2 as libc::c_int + | 0x1 as libc::c_int) + != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 1 as libc::c_int + | (1 as libc::c_int) + << 18 as libc::c_int; + } else if !temp1.is_null() + && (*name + .offset(0 as libc::c_int as isize) + as libc::c_int + == '*' as i32 + && *name.offset( + 1 as libc::c_int as isize, + ) + as libc::c_int + == 0 as libc::c_int) + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + { + (*ret).flags |= (1 as libc::c_int) + << 3 as libc::c_int; + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 + as *const libc::c_char, + 9338 as libc::c_int, + ); + return ret; + } + } + _ => {} + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9428 as libc::c_int, + ); + if ret.is_null() { + ret = alloc_word_desc(); + (*ret).flags = tflag; + let ref mut fresh106 = (*ret).word; + *fresh106 = temp; + } + return ret; + } + 0 | _ => {} + } + } + } + } + } + } + } + } + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: bad substitution\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + if !string.is_null() { + string + } else { + b"??\0" as *const u8 as *const libc::c_char + }, + ); + if !value.is_null() { + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9284 as libc::c_int, + ); + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9285 as libc::c_int, + ); + } + sh_xfree( + name as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9286 as libc::c_int, + ); + if shell_compatibility_level <= 43 as libc::c_int { + return &mut expand_wdesc_error; + } else { + return if posixly_correct != 0 && interactive_shell == 0 as libc::c_int { + &mut expand_wdesc_fatal + } else { + &mut expand_wdesc_error + }; + }; + } +} +fn param_expand( + mut string: *mut libc::c_char, + mut sindex: *mut libc::c_int, + mut quoted: libc::c_int, + mut expanded_something: *mut libc::c_int, + mut contains_dollar_at: *mut libc::c_int, + mut quoted_dollar_at_p: *mut libc::c_int, + mut had_quoted_null_p: *mut libc::c_int, + mut pflags: libc::c_int, +) -> *mut WORD_DESC { + let mut temp2: *mut libc::c_char = 0 as *mut libc::c_char; + let mut current_block: u64; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut uerror: [libc::c_char; 3] = [0; 3]; + let mut savecmd: *mut libc::c_char = 0 as *mut libc::c_char; + let mut zindex: libc::c_int = 0; + let mut t_index: libc::c_int = 0; + let mut expok: libc::c_int = 0; + let mut c: libc::c_uchar = 0; + let mut number: intmax_t = 0; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tdesc: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut ret: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut tflag: libc::c_int = 0; + let mut nullarg: libc::c_int = 0; + let mut old_echo_input: libc::c_int = 0; + unsafe { + zindex = *sindex; + zindex += 1; + c = *string.offset(zindex as isize) as libc::c_uchar; + temp = 0 as *mut libc::c_void as *mut libc::c_char; + tdesc = 0 as *mut libc::c_void as *mut WORD_DESC; + ret = tdesc; + tflag = 0 as libc::c_int; + match c as libc::c_int { + 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 => { + temp1 = *dollar_vars + .as_mut_ptr() + .offset((c as libc::c_int - '0' as i32) as isize); + if unbound_vars_is_error != 0 && temp1.is_null() { + uerror[0 as libc::c_int as usize] = '$' as i32 as libc::c_char; + uerror[1 as libc::c_int as usize] = c as libc::c_char; + uerror[2 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + set_exit_status(1 as libc::c_int); + err_unboundvar(uerror.as_mut_ptr()); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + if !temp1.is_null() { + temp = if *temp1 as libc::c_int != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + { + quote_string(temp1) + } else { + quote_escapes(temp1) + }; + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + current_block = 14877673131977174631; + } + 36 => { + temp = itos(dollar_dollar_pid as intmax_t); + current_block = 14877673131977174631; + } + 35 => { + temp = itos(number_of_args() as intmax_t); + current_block = 14877673131977174631; + } + 63 => { + temp = itos(last_command_exit_value as intmax_t); + current_block = 14877673131977174631; + } + 45 => { + temp = which_set_flags(); + current_block = 14877673131977174631; + } + 33 => { + if last_asynchronous_pid == -(1 as libc::c_int) { + if !expanded_something.is_null() { + *expanded_something = 0 as libc::c_int; + } + temp = 0 as *mut libc::c_void as *mut libc::c_char; + if unbound_vars_is_error != 0 && pflags & 0x2 as libc::c_int == 0 as libc::c_int + { + uerror[0 as libc::c_int as usize] = '$' as i32 as libc::c_char; + uerror[1 as libc::c_int as usize] = c as libc::c_char; + uerror[2 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_char; + set_exit_status(1 as libc::c_int); + err_unboundvar(uerror.as_mut_ptr()); + return if interactive_shell != 0 { + &mut expand_wdesc_error + } else { + &mut expand_wdesc_fatal + }; + } + } else { + temp = itos(last_asynchronous_pid as intmax_t); + } + current_block = 14877673131977174631; + } + 42 => { + list = list_rest_of_args(); + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 && list.is_null() { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } else if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int | 0x8 as libc::c_int) + != 0 + { + temp = if quoted & (0x1 as libc::c_int | 0x8 as libc::c_int) != 0 { + string_list_dollar_star(list, quoted, 0 as libc::c_int) + } else { + string_list(list) + }; + if !temp.is_null() { + temp1 = if quoted & 0x1 as libc::c_int != 0 { + quote_string(temp) + } else { + temp + }; + if *temp as libc::c_int == 0 as libc::c_int { + tflag |= (1 as libc::c_int) << 18 as libc::c_int; + } + if temp != temp1 { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9589 as libc::c_int, + ); + } + temp = temp1; + } + } else { + if expand_no_split_dollar_star != 0 + && quoted == 0 as libc::c_int + && ifs_is_set == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0 + { + temp1 = string_list_dollar_star(list, quoted, pflags); + temp = if !temp1.is_null() { + quote_string(temp1) + } else { + temp1 + }; + if !temp1.is_null() + && *temp1 as libc::c_int == 0 as libc::c_int + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + tflag |= (1 as libc::c_int) << 21 as libc::c_int; + } + if !temp1.is_null() { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9609 as libc::c_int, + ); + } + } else if expand_no_split_dollar_star != 0 + && quoted == 0 as libc::c_int + && ifs_is_null != 0 + && pflags & 0x8 as libc::c_int != 0 + { + temp1 = string_list_dollar_star(list, quoted, pflags); + temp = if !temp1.is_null() { + quote_escapes(temp1) + } else { + temp1 + }; + if !temp1.is_null() { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9616 as libc::c_int, + ); + } + } else if expand_no_split_dollar_star != 0 + && quoted == 0 as libc::c_int + && ifs_is_set != 0 + && ifs_is_null == 0 as libc::c_int + && pflags & 0x8 as libc::c_int != 0 + { + temp1 = string_list_dollar_star(list, quoted, pflags); + temp = if !temp1.is_null() { + quote_string(temp1) + } else { + temp1 + }; + if !temp1.is_null() + && *temp1 as libc::c_int == 0 as libc::c_int + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + tflag |= (1 as libc::c_int) << 21 as libc::c_int; + } + if !temp1.is_null() { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9627 as libc::c_int, + ); + } + } else if expand_no_split_dollar_star != 0 + && ifs_firstc[0 as libc::c_int as usize] as libc::c_int == 0 as libc::c_int + { + temp = string_list_dollar_star(list, quoted, 0 as libc::c_int); + } else { + temp = string_list_dollar_at(list, quoted, 0 as libc::c_int); + if quoted == 0 as libc::c_int && ifs_is_null != 0 { + tflag |= (1 as libc::c_int) << 3 as libc::c_int; + } else if !temp.is_null() + && quoted == 0 as libc::c_int + && ifs_is_set != 0 + && pflags & 0x8 as libc::c_int != 0 + { + temp1 = quote_string(temp); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9654 as libc::c_int, + ); + temp = temp1; + } + } + if expand_no_split_dollar_star == 0 as libc::c_int + && !contains_dollar_at.is_null() + { + *contains_dollar_at = 1 as libc::c_int; + } + } + dispose_words(list); + current_block = 14877673131977174631; + } + 64 => { + list = list_rest_of_args(); + nullarg = 0 as libc::c_int; + l = list; + while !l.is_null() { + if !((*l).word).is_null() + && (((*(*l).word).word).is_null() + || *((*(*l).word).word).offset(0 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int) + { + nullarg = 1 as libc::c_int; + } + l = (*l).next; + } + if !quoted_dollar_at_p.is_null() + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + { + *quoted_dollar_at_p = 1 as libc::c_int; + } + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + if pflags & 0x8 as libc::c_int != 0 { + temp = string_list_dollar_at(list, quoted | 0x1 as libc::c_int, pflags); + if nullarg != 0 { + tflag |= (1 as libc::c_int) << 18 as libc::c_int; + } + } else if pflags & 0x4 as libc::c_int != 0 { + if quoted == 0 as libc::c_int + && ifs_is_set != 0 + && ifs_is_null == 0 as libc::c_int + && ifs_firstc[0 as libc::c_int as usize] as libc::c_int != ' ' as i32 + { + temp = string_list_dollar_at(list, 0x1 as libc::c_int, pflags); + } else { + temp = string_list_dollar_at(list, quoted, pflags); + } + } else { + temp = string_list_dollar_at(list, quoted, pflags); + } + tflag |= (1 as libc::c_int) << 8 as libc::c_int; + dispose_words(list); + current_block = 14877673131977174631; + } + 123 => { + tdesc = parameter_brace_expand( + string, + &mut zindex, + quoted, + pflags, + quoted_dollar_at_p, + contains_dollar_at, + ); + if tdesc == &mut expand_wdesc_error as *mut WORD_DESC + || tdesc == &mut expand_wdesc_fatal as *mut WORD_DESC + { + return tdesc; + } + temp = if !tdesc.is_null() { + (*tdesc).word + } else { + 0 as *mut libc::c_char + }; + if !tdesc.is_null() + && !((*tdesc).word).is_null() + && (*tdesc).flags & (1 as libc::c_int) << 18 as libc::c_int != 0 + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + { + if !had_quoted_null_p.is_null() { + *had_quoted_null_p = 1 as libc::c_int; + } + if *quoted_dollar_at_p == 0 as libc::c_int { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9777 as libc::c_int, + ); + temp = 0 as *mut libc::c_void as *mut libc::c_char; + let ref mut fresh107 = (*tdesc).word; + *fresh107 = temp; + } + } + ret = tdesc; + current_block = 13100549023021289889; + } + 40 => { + t_index = zindex + 1 as libc::c_int; + temp = extract_command_subst( + string, + &mut t_index, + if pflags & 0x10 as libc::c_int != 0 { + 0x400 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + zindex = t_index; + if !temp.is_null() && *temp as libc::c_int == '(' as i32 { + temp2 = 0 as *mut libc::c_char; + temp1 = temp.offset(1 as libc::c_int as isize); + temp2 = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(temp1) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9801 as libc::c_int, + ) as *mut libc::c_char, + temp1, + ); + t_index = (strlen(temp2)).wrapping_sub(1 as libc::c_int as u64) as libc::c_int; + if *temp2.offset(t_index as isize) as libc::c_int != ')' as i32 { + sh_xfree( + temp2 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9806 as libc::c_int, + ); + current_block = 8854118802046536135; + } else { + *temp2.offset(t_index as isize) = '\u{0}' as i32 as libc::c_char; + if chk_arithsub(temp2, t_index) == 0 as libc::c_int { + sh_xfree( + temp2 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9815 as libc::c_int, + ); + current_block = 8854118802046536135; + } else { + temp1 = expand_arith_string( + temp2, + 0x1 as libc::c_int | 0x100 as libc::c_int, + ); + sh_xfree( + temp2 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9824 as libc::c_int, + ); + current_block = 8017591428298988586; + } + } + } else { + current_block = 8854118802046536135; + } + match current_block { + 8017591428298988586 => {} + _ => { + old_echo_input = echo_input_at_read; + echo_input_at_read = 0 as libc::c_int; + if pflags & 0x1 as libc::c_int != 0 { + temp1 = substring(string, *sindex, zindex + 1 as libc::c_int); + } else { + tdesc = command_substitute(temp, quoted, pflags & 0x8 as libc::c_int); + temp1 = if !tdesc.is_null() { + (*tdesc).word + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !tdesc.is_null() { + dispose_word_desc(tdesc); + } + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9862 as libc::c_int, + ); + } + temp = temp1; + echo_input_at_read = old_echo_input; + current_block = 14877673131977174631; + } + } + } + 91 => { + t_index = zindex + 1 as libc::c_int; + temp = extract_arithmetic_subst(string, &mut t_index); + zindex = t_index; + if temp.is_null() { + temp = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(string) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9876 as libc::c_int, + ) as *mut libc::c_char, + string, + ); + if !expanded_something.is_null() { + *expanded_something = 0 as libc::c_int; + } + current_block = 13100549023021289889; + } else { + temp1 = expand_arith_string(temp, 0x1 as libc::c_int | 0x100 as libc::c_int); + current_block = 8017591428298988586; + } + } + _ => { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + t_index = zindex; + loop { + c = *string.offset(zindex as isize) as libc::c_uchar; + if !(c as libc::c_int != 0 + && (1 as libc::c_int != 0 + && *(*__ctype_b_loc()).offset(c as libc::c_int as isize) + as libc::c_int + & _ISalnum as libc::c_int as libc::c_ushort as libc::c_int + != 0 + || c as libc::c_int == '_' as i32)) + { + break; + } + zindex += 1; + } + temp1 = if zindex > t_index { + substring(string, t_index, zindex) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if temp1.is_null() || *temp1 as libc::c_int == '\u{0}' as i32 { + if !temp1.is_null() { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9898 as libc::c_int, + ); + } + temp = sh_xmalloc( + 2 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9899 as libc::c_int, + ) as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = '$' as i32 as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + if !expanded_something.is_null() { + *expanded_something = 0 as libc::c_int; + } + } else { + var = find_variable(temp1); + if !var.is_null() + && (*var).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && !((*var).value).is_null() + { + if (*var).attributes & 0x40 as libc::c_int != 0 + || (*var).attributes & 0x4 as libc::c_int != 0 + { + temp = if (*var).attributes & 0x4 as libc::c_int != 0 { + array_reference( + (*var).value as *mut ARRAY, + 0 as libc::c_int as arrayind_t, + ) + } else { + assoc_reference( + (*var).value as *mut HASH_TABLE, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ) + }; + if !temp.is_null() { + temp = if *temp as libc::c_int != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + { + quote_string(temp) + } else { + quote_escapes(temp) + }; + current_block = 8487579351791723214; + } else if unbound_vars_is_error != 0 { + current_block = 17199185463623757271; + } else { + current_block = 8487579351791723214; + } + } else { + temp = (*var).value; + temp = if *temp as libc::c_int != 0 + && quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + { + quote_string(temp) + } else if pflags & 0x8 as libc::c_int != 0 { + quote_rhs(temp) + } else { + quote_escapes(temp) + }; + current_block = 8487579351791723214; + } + match current_block { + 17199185463623757271 => {} + _ => { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9935 as libc::c_int, + ); + current_block = 13100549023021289889; + } + } + } else { + if !var.is_null() + && ((*var).attributes & 0x1000 as libc::c_int != 0 + || ((*var).value != 0 as *mut libc::c_char) as libc::c_int + == 0 as libc::c_int) + { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + current_block = 5123298911185657293; + } else { + var = find_variable_last_nameref(temp1, 0 as libc::c_int); + if !var.is_null() + && !((*var).value).is_null() + && (*var).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + { + temp = (*var).value; + if !temp.is_null() + && *temp as libc::c_int != 0 + && valid_array_reference(temp, 0 as libc::c_int) != 0 + { + tdesc = parameter_brace_expand_word( + temp, + (*temp as libc::c_int != 0 + && (*temp as libc::c_int >= '0' as i32 + && *temp as libc::c_int <= '9' as i32 + && all_digits(temp) != 0 + || *temp.offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32 + && *sh_syntaxtab + .as_mut_ptr() + .offset(*temp as libc::c_uchar as isize) + & 0x800 as libc::c_int + != 0 + || 0 as libc::c_int != 0 + && *temp.offset(2 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32 + && (posixly_correct == 0 as libc::c_int + && *temp.offset(1 as libc::c_int as isize) + as libc::c_int + == '#' as i32 + || posixly_correct == 0 as libc::c_int + && *temp + .offset(1 as libc::c_int as isize) + as libc::c_int + == '?' as i32 + || *temp.offset(1 as libc::c_int as isize) + as libc::c_int + == '@' as i32 + || *temp.offset(1 as libc::c_int as isize) + as libc::c_int + == '*' as i32))) + as libc::c_int, + quoted, + pflags, + 0 as *mut libc::c_void as *mut arrayind_t, + ); + if tdesc == &mut expand_wdesc_error as *mut WORD_DESC + || tdesc == &mut expand_wdesc_fatal as *mut WORD_DESC + { + return tdesc; + } + ret = tdesc; + current_block = 13100549023021289889; + } else { + if !temp.is_null() + && *temp as libc::c_int != 0 + && legal_identifier(temp) == 0 as libc::c_int + { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"%s: invalid variable name for name reference\0" + as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + temp, + ); + return &mut expand_wdesc_error; + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + current_block = 5123298911185657293; + } + } else { + current_block = 5123298911185657293; + } + } + match current_block { + 13100549023021289889 => {} + _ => { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + current_block = 17199185463623757271; + } + } + } + match current_block { + 13100549023021289889 => {} + _ => { + if unbound_vars_is_error != 0 { + set_exit_status(1 as libc::c_int); + err_unboundvar(temp1); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9980 as libc::c_int, + ); + set_exit_status(1 as libc::c_int); + return if unbound_vars_is_error != 0 + && interactive_shell == 0 as libc::c_int + { + &mut expand_wdesc_fatal + } else { + &mut expand_wdesc_error + }; + } else { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9976 as libc::c_int, + ); + } + } + } + } + current_block = 13100549023021289889; + } + } + match current_block { + 8017591428298988586 => { + savecmd = this_command_name; + this_command_name = 0 as *mut libc::c_void as *mut libc::c_char; + number = evalexp(temp1, 0x1 as libc::c_int, &mut expok); + this_command_name = savecmd; + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9832 as libc::c_int, + ); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 9833 as libc::c_int, + ); + if expok == 0 as libc::c_int { + if interactive_shell == 0 as libc::c_int && posixly_correct != 0 { + set_exit_status(1 as libc::c_int); + return &mut expand_wdesc_fatal; + } else { + return &mut expand_wdesc_error; + } + } + temp = itos(number); + current_block = 14877673131977174631; + } + _ => {} + } + match current_block { + 14877673131977174631 => { + if *string.offset(zindex as isize) != 0 { + zindex += 1; + } + } + _ => {} + } + *sindex = zindex; + if ret.is_null() { + ret = alloc_word_desc(); + (*ret).flags = tflag; + let ref mut fresh108 = (*ret).word; + *fresh108 = temp; + } + } + return ret; +} +#[no_mangle] +pub fn invalidate_cached_quoted_dollar_at() { + unsafe { + dispose_words(cached_quoted_dollar_at); + cached_quoted_dollar_at = 0 as *mut WORD_LIST; + } +} +fn expand_word_internal( + mut word: *mut WORD_DESC, + mut quoted: libc::c_int, + mut isexp: libc::c_int, + mut contains_dollar_at: *mut libc::c_int, + mut expanded_something: *mut libc::c_int, +) -> *mut WORD_LIST { + unsafe { + let mut ifs_chars: *mut libc::c_char = 0 as *mut libc::c_char; + let mut current_block: u64; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tword: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut istring: *mut libc::c_char = 0 as *mut libc::c_char; + let mut istring_size: size_t = 0; + let mut istring_index: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp1: *mut libc::c_char = 0 as *mut libc::c_char; + let mut string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut string_size: size_t = 0; + let mut sindex: libc::c_int = 0; + let mut quoted_dollar_at: libc::c_int = 0; + let mut quoted_state: libc::c_int = 0; + let mut had_quoted_null: libc::c_int = 0; + let mut has_quoted_ifs: libc::c_int = 0; + let mut has_dollar_at: libc::c_int = 0; + let mut temp_has_dollar_at: libc::c_int = 0; + let mut split_on_spaces: libc::c_int = 0; + let mut local_expanded: libc::c_int = 0; + let mut tflag: libc::c_int = 0; + let mut pflags: libc::c_int = 0; + let mut mb_cur_max: libc::c_int = 0; + let mut assignoff: libc::c_int = 0; + let mut c: libc::c_uchar = 0; + let mut t_index: libc::c_int = 0; + let mut twochars: [libc::c_char; 2] = [0; 2]; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + if *((*word).word).offset(0 as libc::c_int as isize) as libc::c_int + == (*::std::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"\"$@\"\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp( + (*word).word, + b"\"$@\"\0" as *const u8 as *const libc::c_char, + ) == 0 as libc::c_int + && (*word).flags + == (1 as libc::c_int) << 0 as libc::c_int | (1 as libc::c_int) << 1 as libc::c_int + && !(*dollar_vars.as_mut_ptr().offset(1 as libc::c_int as isize)).is_null() + { + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + if !expanded_something.is_null() { + *expanded_something = 1 as libc::c_int; + } + if !cached_quoted_dollar_at.is_null() { + return copy_word_list(cached_quoted_dollar_at); + } + list = list_rest_of_args(); + list = quote_list(list); + cached_quoted_dollar_at = copy_word_list(list); + return list; + } + istring_size = 112 as libc::c_int as size_t; + istring = sh_xmalloc( + istring_size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10110 as libc::c_int, + ) as *mut libc::c_char; + istring_index = 0 as libc::c_int; + *istring.offset(istring_index as isize) = '\u{0}' as i32 as libc::c_char; + has_dollar_at = 0 as libc::c_int; + had_quoted_null = has_dollar_at; + quoted_dollar_at = had_quoted_null; + has_quoted_ifs = 0 as libc::c_int; + split_on_spaces = 0 as libc::c_int; + quoted_state = 0 as libc::c_int; + string = (*word).word; + if !string.is_null() { + mb_cur_max = __ctype_get_mb_cur_max() as libc::c_int; + string_size = if mb_cur_max > 1 as libc::c_int { + strlen(string) as u64 + } else { + 1 as libc::c_int as libc::c_ulong + }; + if !contains_dollar_at.is_null() { + *contains_dollar_at = 0 as libc::c_int; + } + assignoff = -(1 as libc::c_int); + sindex = 0 as libc::c_int; + loop { + c = *string.offset(sindex as isize) as libc::c_uchar; + match c as libc::c_int { + 0 => { + break; + } + 1 => { + sindex += 1; + if mb_cur_max > 1 as libc::c_int + && *string.offset(sindex as isize) as libc::c_int != 0 + { + let mut i: libc::c_int = 0; + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + i = is_basic(*string.offset(sindex as isize)); + if i != 0 { + mblength = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(sindex as isize) as libc::c_int + & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength = (*string.offset(sindex as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int + as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength == -(1 as libc::c_int) as size_t + || mblength == -(2 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } + if mblength < 1 as libc::c_int as libc::c_ulong { + mblength = 1 as libc::c_int as size_t; + } + temp = sh_xmalloc( + mblength.wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10148 as libc::c_int, + ) as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + i = 0 as libc::c_int; + while (i as libc::c_ulong) < mblength { + let fresh109 = sindex; + sindex = sindex + 1; + *temp.offset((i + 1 as libc::c_int) as isize) = + *string.offset(fresh109 as isize); + i += 1; + } + *temp + .offset(mblength.wrapping_add(1 as libc::c_int as libc::c_ulong) + as isize) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + temp = sh_xmalloc( + 3 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10153 as libc::c_int, + ) as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + c = *string.offset(sindex as isize) as libc::c_uchar; + *temp.offset(1 as libc::c_int as isize) = c as libc::c_char; + *temp.offset(2 as libc::c_int as isize) = + '\u{0}' as i32 as libc::c_char; + current_block = 8423922909464824957; + } + } + 60 | 62 => { + sindex += 1; + if *string.offset(sindex as isize) as libc::c_int != '(' as i32 + || quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + || (*word).flags + & ((1 as libc::c_int) << 19 as libc::c_int + | (1 as libc::c_int) << 20 as libc::c_int) + != 0 + { + sindex -= 1; + current_block = 1398496724659307859; + } else { + t_index = sindex + 1 as libc::c_int; + temp1 = extract_process_subst( + string, + (if c as libc::c_int == '<' as i32 { + b"<(\0" as *const u8 as *const libc::c_char + } else { + b">(\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char, + &mut t_index, + 0 as libc::c_int, + ); + sindex = t_index; + temp = if !temp1.is_null() { + process_substitute( + temp1, + (c as libc::c_int == '>' as i32) as libc::c_int, + ) + } else { + 0 as *mut libc::c_char + }; + if !temp1.is_null() { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10196 as libc::c_int, + ); + } + current_block = 8423922909464824957; + } + } + 61 => { + if (*word).flags + & ((1 as libc::c_int) << 11 as libc::c_int + | (1 as libc::c_int) << 12 as libc::c_int) + != 0 + { + if isexp == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + { + current_block = 8014490948552223808; + } else { + current_block = 1398496724659307859; + } + } else { + if (*word).flags & (1 as libc::c_int) << 2 as libc::c_int != 0 + && (posixly_correct == 0 as libc::c_int + || (*word).flags & (1 as libc::c_int) << 7 as libc::c_int != 0) + && assignoff == -(1 as libc::c_int) + && sindex > 0 as libc::c_int + { + assignoff = sindex; + } + if sindex == assignoff + && *string.offset((sindex + 1 as libc::c_int) as isize) + as libc::c_int + == '~' as i32 + { + (*word).flags |= (1 as libc::c_int) << 13 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 17 as libc::c_int != 0 { + (*word).flags |= (1 as libc::c_int) << 11 as libc::c_int; + } + if isexp == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + { + has_quoted_ifs += 1; + current_block = 8014490948552223808; + } else { + current_block = 1398496724659307859; + } + } + } + 58 => { + if (*word).flags + & ((1 as libc::c_int) << 12 as libc::c_int + | (1 as libc::c_int) << 29 as libc::c_int) + != 0 + { + if isexp == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + { + current_block = 8014490948552223808; + } else { + current_block = 1398496724659307859; + } + } else { + if (*word).flags + & ((1 as libc::c_int) << 2 as libc::c_int + | (1 as libc::c_int) << 11 as libc::c_int) + != 0 + && (posixly_correct == 0 as libc::c_int + || (*word).flags & (1 as libc::c_int) << 7 as libc::c_int != 0) + && *string.offset((sindex + 1 as libc::c_int) as isize) + as libc::c_int + == '~' as i32 + { + (*word).flags |= (1 as libc::c_int) << 13 as libc::c_int; + } + if isexp == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + { + current_block = 8014490948552223808; + } else { + current_block = 1398496724659307859; + } + } + } + 126 => { + if (*word).flags + & ((1 as libc::c_int) << 12 as libc::c_int + | (1 as libc::c_int) << 19 as libc::c_int) + != 0 + || sindex > 0 as libc::c_int + && (*word).flags & (1 as libc::c_int) << 13 as libc::c_int + == 0 as libc::c_int + || quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + { + (*word).flags &= !((1 as libc::c_int) << 13 as libc::c_int); + if isexp == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + && quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) + == 0 as libc::c_int + { + current_block = 8014490948552223808; + } else { + current_block = 1398496724659307859; + } + } else { + if (*word).flags & (1 as libc::c_int) << 11 as libc::c_int != 0 { + tflag = 2 as libc::c_int; + } else if (*word).flags + & ((1 as libc::c_int) << 2 as libc::c_int + | (1 as libc::c_int) << 7 as libc::c_int) + != 0 + { + tflag = 1 as libc::c_int; + } else { + tflag = 0 as libc::c_int; + } + temp = bash_tilde_find_word( + string.offset(sindex as isize), + tflag, + &mut t_index, + ); + (*word).flags &= !((1 as libc::c_int) << 13 as libc::c_int); + if !temp.is_null() + && *temp as libc::c_int != 0 + && t_index > 0 as libc::c_int + { + temp1 = bash_tilde_expand(temp, tflag); + if !temp1.is_null() + && *temp1 as libc::c_int == '~' as i32 + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == *temp1.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp(temp, temp1) == 0 as libc::c_int) + { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10295 as libc::c_int, + ); + } + if !temp1.is_null() { + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10296 as libc::c_int, + ); + } + current_block = 1398496724659307859; + } else { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10299 as libc::c_int, + ); + temp = temp1; + sindex += t_index; + current_block = 10574327403355912886; + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10306 as libc::c_int, + ); + } + current_block = 1398496724659307859; + } + } + } + 36 => { + if !expanded_something.is_null() { + *expanded_something = 1 as libc::c_int; + } + local_expanded = 1 as libc::c_int; + temp_has_dollar_at = 0 as libc::c_int; + pflags = if (*word).flags & (1 as libc::c_int) << 10 as libc::c_int != 0 { + 0x1 as libc::c_int + } else { + 0 as libc::c_int + }; + if (*word).flags & (1 as libc::c_int) << 6 as libc::c_int != 0 { + pflags |= 0x4 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 11 as libc::c_int != 0 { + pflags |= 0x8 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 27 as libc::c_int != 0 { + pflags |= 0x10 as libc::c_int; + } + tword = param_expand( + string, + &mut sindex, + quoted, + expanded_something, + &mut temp_has_dollar_at, + &mut quoted_dollar_at, + &mut had_quoted_null, + pflags, + ); + has_dollar_at += temp_has_dollar_at; + split_on_spaces += (*tword).flags & (1 as libc::c_int) << 3 as libc::c_int; + if tword == &mut expand_wdesc_error as *mut WORD_DESC + || tword == &mut expand_wdesc_fatal as *mut WORD_DESC + { + sh_xfree( + string as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10332 as libc::c_int, + ); + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10333 as libc::c_int, + ); + return if tword == &mut expand_wdesc_error as *mut WORD_DESC { + &mut expand_word_error + } else { + &mut expand_word_fatal + }; + } + if !contains_dollar_at.is_null() && has_dollar_at != 0 { + *contains_dollar_at = 1 as libc::c_int; + } + if !tword.is_null() + && (*tword).flags & (1 as libc::c_int) << 18 as libc::c_int != 0 + { + had_quoted_null = 1 as libc::c_int; + } + if !tword.is_null() + && (*tword).flags & (1 as libc::c_int) << 21 as libc::c_int != 0 + { + had_quoted_null = 1 as libc::c_int; + } + temp = if !tword.is_null() { + (*tword).word + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + dispose_word_desc(tword); + if had_quoted_null != 0 + && !temp.is_null() + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10352 as libc::c_int, + ); + } + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } + current_block = 16465155782176963379; + } + 96 => { + let fresh110 = sindex; + sindex = sindex + 1; + t_index = fresh110; + temp = string_extract( + string, + &mut sindex, + b"`\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0x4 as libc::c_int, + ); + if temp == &mut extract_string_error as *mut libc::c_char + || temp == &mut extract_string_fatal as *mut libc::c_char + { + if sindex - 1 as libc::c_int == t_index { + sindex = t_index; + } else { + set_exit_status(1 as libc::c_int); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"bad substitution: no closing \"`\" in %s\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + string.offset(t_index as isize), + ); + sh_xfree( + string as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10375 as libc::c_int, + ); + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10376 as libc::c_int, + ); + return if temp == &mut extract_string_error as *mut libc::c_char { + &mut expand_word_error + } else { + &mut expand_word_fatal + }; + } + current_block = 1398496724659307859; + } else { + if !expanded_something.is_null() { + *expanded_something = 1 as libc::c_int; + } + local_expanded = 1 as libc::c_int; + if (*word).flags & (1 as libc::c_int) << 10 as libc::c_int != 0 { + temp1 = substring(string, t_index, sindex + 1 as libc::c_int); + } else { + de_backslash(temp); + tword = command_substitute(temp, quoted, 0 as libc::c_int); + temp1 = if !tword.is_null() { + (*tword).word + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !tword.is_null() { + dispose_word_desc(tword); + } + } + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10396 as libc::c_int, + ); + } + temp = temp1; + current_block = 8423922909464824957; + } + } + 92 => { + if *string.offset((sindex + 1 as libc::c_int) as isize) as libc::c_int + == '\n' as i32 + { + sindex += 2 as libc::c_int; + continue; + } else { + sindex += 1; + c = *string.offset(sindex as isize) as libc::c_uchar; + if quoted & 0x2 as libc::c_int != 0 + && quoted & 0x80 as libc::c_int != 0 + && c as libc::c_int == '"' as i32 + { + tflag = 0x40 as libc::c_int; + } else if quoted & 0x2 as libc::c_int != 0 { + tflag = 0x80 as libc::c_int; + } else if quoted & 0x1 as libc::c_int != 0 { + tflag = 0x40 as libc::c_int; + } else { + tflag = 0 as libc::c_int; + } + if quoted & 0x80 as libc::c_int != 0 && c as libc::c_int == '}' as i32 { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_0: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_0: size_t = 0; + let mut _i: libc::c_int = 0; + _i = is_basic(*string.offset(sindex as isize)); + if _i != 0 { + mblength_0 = 1 as libc::c_int as size_t; + } else { + state_bak_0 = state; + mblength_0 = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength_0 == -(2 as libc::c_int) as size_t + || mblength_0 == -(1 as libc::c_int) as size_t + { + state = state_bak_0; + mblength_0 = 1 as libc::c_int as size_t; + } else { + mblength_0 = + if mblength_0 < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength_0 + }; + } + temp = sh_xmalloc( + mblength_0.wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10426 as libc::c_int, + ) + as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + _i = 0 as libc::c_int; + while (_i as libc::c_ulong) < mblength_0 { + let fresh111 = sindex; + sindex = sindex + 1; + *temp.offset((_i + 1 as libc::c_int) as isize) = + *string.offset(fresh111 as isize); + _i += 1; + } + *temp.offset( + mblength_0.wrapping_add(1 as libc::c_int as libc::c_ulong) + as isize, + ) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + twochars[0 as libc::c_int as usize] = + '\u{1}' as i32 as libc::c_char; + twochars[1 as libc::c_int as usize] = c as libc::c_char; + current_block = 3893156993890508670; + } + } else if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && *sh_syntaxtab.as_mut_ptr().offset(c as isize) & tflag + == 0 as libc::c_int + && isexp == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + { + if (istring_index + 2 as libc::c_int) as libc::c_ulong + >= istring_size + { + while (istring_index + 2 as libc::c_int) as libc::c_ulong + >= istring_size + { + istring_size = (istring_size as libc::c_ulong) + .wrapping_add(128 as libc::c_int as libc::c_ulong) + as size_t + as size_t; + } + istring = sh_xrealloc( + istring as *mut libc::c_void, + istring_size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10432 as libc::c_int, + ) + as *mut libc::c_char; + } + let fresh112 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh112 as isize) = '\u{1}' as i32 as libc::c_char; + let fresh113 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh113 as isize) = '\\' as i32 as libc::c_char; + *istring.offset(istring_index as isize) = + '\u{0}' as i32 as libc::c_char; + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_1: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_1: size_t = 0; + let mut _i_0: libc::c_int = 0; + _i_0 = is_basic(*string.offset(sindex as isize)); + if _i_0 != 0 { + mblength_1 = 1 as libc::c_int as size_t; + } else { + state_bak_1 = state; + mblength_1 = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength_1 == -(2 as libc::c_int) as size_t + || mblength_1 == -(1 as libc::c_int) as size_t + { + state = state_bak_1; + mblength_1 = 1 as libc::c_int as size_t; + } else { + mblength_1 = + if mblength_1 < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength_1 + }; + } + temp = sh_xmalloc( + mblength_1.wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10437 as libc::c_int, + ) + as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + _i_0 = 0 as libc::c_int; + while (_i_0 as libc::c_ulong) < mblength_1 { + let fresh114 = sindex; + sindex = sindex + 1; + *temp.offset((_i_0 + 1 as libc::c_int) as isize) = + *string.offset(fresh114 as isize); + _i_0 += 1; + } + *temp.offset( + mblength_1.wrapping_add(1 as libc::c_int as libc::c_ulong) + as isize, + ) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + twochars[0 as libc::c_int as usize] = + '\u{1}' as i32 as libc::c_char; + twochars[1 as libc::c_int as usize] = c as libc::c_char; + current_block = 3893156993890508670; + } + } else if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && c as libc::c_int == 0 as libc::c_int + { + if (istring_index + 2 as libc::c_int) as libc::c_ulong + >= istring_size + { + while (istring_index + 2 as libc::c_int) as libc::c_ulong + >= istring_size + { + istring_size = (istring_size as libc::c_ulong) + .wrapping_add(128 as libc::c_int as libc::c_ulong) + as size_t + as size_t; + } + istring = sh_xrealloc( + istring as *mut libc::c_void, + istring_size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10442 as libc::c_int, + ) + as *mut libc::c_char; + } + let fresh115 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh115 as isize) = '\u{1}' as i32 as libc::c_char; + let fresh116 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh116 as isize) = '\\' as i32 as libc::c_char; + *istring.offset(istring_index as isize) = + '\u{0}' as i32 as libc::c_char; + continue; + } else if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + && *sh_syntaxtab.as_mut_ptr().offset(c as isize) & tflag + == 0 as libc::c_int + { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_2: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_2: size_t = 0; + let mut _i_1: libc::c_int = 0; + _i_1 = is_basic(*string.offset(sindex as isize)); + if _i_1 != 0 { + mblength_2 = 1 as libc::c_int as size_t; + } else { + state_bak_2 = state; + mblength_2 = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength_2 == -(2 as libc::c_int) as size_t + || mblength_2 == -(1 as libc::c_int) as size_t + { + state = state_bak_2; + mblength_2 = 1 as libc::c_int as size_t; + } else { + mblength_2 = + if mblength_2 < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength_2 + }; + } + temp = sh_xmalloc( + mblength_2.wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10450 as libc::c_int, + ) + as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\\' as i32 as libc::c_char; + _i_1 = 0 as libc::c_int; + while (_i_1 as libc::c_ulong) < mblength_2 { + let fresh117 = sindex; + sindex = sindex + 1; + *temp.offset((_i_1 + 1 as libc::c_int) as isize) = + *string.offset(fresh117 as isize); + _i_1 += 1; + } + *temp.offset( + mblength_2.wrapping_add(1 as libc::c_int as libc::c_ulong) + as isize, + ) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + twochars[0 as libc::c_int as usize] = + '\\' as i32 as libc::c_char; + twochars[1 as libc::c_int as usize] = c as libc::c_char; + current_block = 3893156993890508670; + } + } else if c as libc::c_int == 0 as libc::c_int { + c = '\u{7f}' as i32 as libc::c_uchar; + sindex -= 1; + current_block = 1398496724659307859; + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak_3: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_3: size_t = 0; + let mut _i_2: libc::c_int = 0; + _i_2 = is_basic(*string.offset(sindex as isize)); + if _i_2 != 0 { + mblength_3 = 1 as libc::c_int as size_t; + } else { + state_bak_3 = state; + mblength_3 = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength_3 == -(2 as libc::c_int) as size_t + || mblength_3 == -(1 as libc::c_int) as size_t + { + state = state_bak_3; + mblength_3 = 1 as libc::c_int as size_t; + } else { + mblength_3 = if mblength_3 < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength_3 + }; + } + temp = sh_xmalloc( + mblength_3.wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10460 as libc::c_int, + ) as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + _i_2 = 0 as libc::c_int; + while (_i_2 as libc::c_ulong) < mblength_3 { + let fresh118 = sindex; + sindex = sindex + 1; + *temp.offset((_i_2 + 1 as libc::c_int) as isize) = + *string.offset(fresh118 as isize); + _i_2 += 1; + } + *temp.offset( + mblength_3.wrapping_add(1 as libc::c_int as libc::c_ulong) + as isize, + ) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + twochars[0 as libc::c_int as usize] = + '\u{1}' as i32 as libc::c_char; + twochars[1 as libc::c_int as usize] = c as libc::c_char; + current_block = 3893156993890508670; + } + match current_block { + 16465155782176963379 => {} + 1398496724659307859 => {} + _ => { + sindex += 1; + current_block = 18404008029668793007; + } + } + } + } + 34 => { + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + && quoted & 0x100 as libc::c_int == 0 as libc::c_int + { + current_block = 1398496724659307859; + } else { + sindex += 1; + t_index = sindex; + temp = string_extract_double_quoted( + string, + &mut sindex, + if (*word).flags & (1 as libc::c_int) << 27 as libc::c_int != 0 { + 0x400 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + quoted_state = if t_index == 1 as libc::c_int + && *string.offset(sindex as isize) as libc::c_int == '\u{0}' as i32 + { + 2 as libc::c_int + } else { + 1 as libc::c_int + }; + if !temp.is_null() && *temp as libc::c_int != 0 { + tword = alloc_word_desc(); + let ref mut fresh121 = (*tword).word; + *fresh121 = temp; + if (*word).flags & (1 as libc::c_int) << 17 as libc::c_int != 0 { + (*tword).flags |= (*word).flags + & ((1 as libc::c_int) << 17 as libc::c_int + | (1 as libc::c_int) << 11 as libc::c_int); + } + if (*word).flags & (1 as libc::c_int) << 27 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 27 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 10 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 10 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 20 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 20 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 11 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 11 as libc::c_int; + } + temp = 0 as *mut libc::c_void as *mut libc::c_char; + temp_has_dollar_at = 0 as libc::c_int; + list = expand_word_internal( + tword, + 0x1 as libc::c_int, + 0 as libc::c_int, + &mut temp_has_dollar_at, + 0 as *mut libc::c_void as *mut libc::c_int, + ); + has_dollar_at += temp_has_dollar_at; + if list == &mut expand_word_error as *mut WORD_LIST + || list == &mut expand_word_fatal as *mut WORD_LIST + { + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10513 as libc::c_int, + ); + sh_xfree( + string as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10514 as libc::c_int, + ); + let ref mut fresh122 = (*tword).word; + *fresh122 = 0 as *mut libc::c_void as *mut libc::c_char; + dispose_word(tword); + return list; + } + dispose_word(tword); + if list.is_null() && temp_has_dollar_at != 0 { + quoted_dollar_at += 1; + continue; + } else { + if !list.is_null() + && !((*list).word).is_null() + && ((*list).next).is_null() + && (*(*list).word).flags + & (1 as libc::c_int) << 18 as libc::c_int + != 0 + { + if had_quoted_null != 0 && temp_has_dollar_at != 0 { + quoted_dollar_at += 1; + } + had_quoted_null = 1 as libc::c_int; + } + if !list.is_null() { + dequote_list(list); + } + if temp_has_dollar_at != 0 { + quoted_dollar_at += 1; + if !contains_dollar_at.is_null() { + *contains_dollar_at = 1 as libc::c_int; + } + if !expanded_something.is_null() { + *expanded_something = 1 as libc::c_int; + } + local_expanded = 1 as libc::c_int; + } + } + } else { + if !temp.is_null() { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10569 as libc::c_int, + ); + } + list = 0 as *mut libc::c_void as *mut WORD_LIST; + had_quoted_null = 1 as libc::c_int; + } + if !list.is_null() { + if !((*list).next).is_null() { + temp = if quoted_dollar_at != 0 { + string_list_dollar_at( + list, + 0x1 as libc::c_int, + 0 as libc::c_int, + ) + } else { + string_list(quote_list(list)) + }; + dispose_words(list); + current_block = 16465155782176963379; + } else { + temp = strcpy( + sh_xmalloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*(*list).word).word) as u64), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10596 as libc::c_int, + ) + as *mut libc::c_char, + (*(*list).word).word, + ); + tflag = (*(*list).word).flags; + dispose_words(list); + if tflag & (1 as libc::c_int) << 18 as libc::c_int != 0 + && (*temp.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *temp.offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32) + as libc::c_int + == 0 as libc::c_int + { + remove_quoted_nulls(temp); + } + current_block = 10637788488912693274; + } + } else { + temp = 0 as *mut libc::c_void as *mut libc::c_char; + current_block = 10637788488912693274; + } + match current_block { + 16465155782176963379 => {} + _ => { + if temp.is_null() && quoted_state == 1 as libc::c_int { + had_quoted_null = 1 as libc::c_int; + } + if temp.is_null() + && quoted_state == 1 as libc::c_int + && quoted == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 14 as libc::c_int + | (1 as libc::c_int) << 11 as libc::c_int) + == (1 as libc::c_int) << 14 as libc::c_int + { + c = '\u{7f}' as i32 as libc::c_uchar; + sindex -= 1; + had_quoted_null = 1 as libc::c_int; + current_block = 1398496724659307859; + } else { + if temp.is_null() + && quoted_state == 1 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + != 0 + { + continue; + } + current_block = 10574327403355912886; + } + } + } + } + } + 39 => { + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 { + current_block = 1398496724659307859; + } else { + sindex += 1; + t_index = sindex; + temp = string_extract_single_quoted(string, &mut sindex); + quoted_state = if t_index == 1 as libc::c_int + && *string.offset(sindex as isize) as libc::c_int == '\u{0}' as i32 + { + 2 as libc::c_int + } else { + 1 as libc::c_int + }; + if *temp as libc::c_int == '\u{0}' as i32 { + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10674 as libc::c_int, + ); + temp = 0 as *mut libc::c_void as *mut libc::c_char; + } else { + remove_quoted_escapes(temp); + } + if temp.is_null() && quoted_state == 1 as libc::c_int { + had_quoted_null = 1 as libc::c_int; + } + if temp.is_null() + && quoted_state == 1 as libc::c_int + && quoted == 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 14 as libc::c_int + | (1 as libc::c_int) << 11 as libc::c_int) + == (1 as libc::c_int) << 14 as libc::c_int + { + c = '\u{7f}' as i32 as libc::c_uchar; + sindex -= 1; + current_block = 1398496724659307859; + } else { + if temp.is_null() + && quoted_state == 1 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + != 0 + { + continue; + } + if temp.is_null() { + c = '\u{7f}' as i32 as libc::c_uchar; + sindex -= 1; + current_block = 1398496724659307859; + } else { + current_block = 10574327403355912886; + } + } + } + } + 32 => { + if ifs_is_null != 0 + || split_on_spaces != 0 + || (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int + | (1 as libc::c_int) << 11 as libc::c_int) + != 0 + && (*word).flags & (1 as libc::c_int) << 14 as libc::c_int + == 0 as libc::c_int + { + if *string.offset(sindex as isize) != 0 { + sindex += 1; + } + twochars[0 as libc::c_int as usize] = '\u{1}' as i32 as libc::c_char; + twochars[1 as libc::c_int as usize] = c as libc::c_char; + current_block = 18404008029668793007; + } else { + current_block = 8014490948552223808; + } + } + _ => { + current_block = 8014490948552223808; + } + } + match current_block { + 8014490948552223808 => { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 + || isexp == 0 as libc::c_int + && ifs_cmap[c as usize] as libc::c_int != 0 as libc::c_int + && (*word).flags + & ((1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 6 as libc::c_int) + == 0 as libc::c_int + { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) + == 0 as libc::c_int + { + has_quoted_ifs += 1; + } + if *string.offset(sindex as isize) != 0 { + sindex += 1; + } + if c as libc::c_int == 0 as libc::c_int { + c = '\u{7f}' as i32 as libc::c_uchar; + current_block = 1398496724659307859; + } else { + if mb_cur_max > 1 as libc::c_int { + sindex -= 1; + } + if mb_cur_max > 1 as libc::c_int { + let mut i_0: libc::c_int = 0; + let mut state_bak_4: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_4: size_t = 0; + i_0 = is_basic(*string.offset(sindex as isize)); + if i_0 != 0 { + mblength_4 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(sindex as isize) as libc::c_int + & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_4 = (*string.offset(sindex as isize) + as libc::c_int + != 0 as libc::c_int) + as libc::c_int + as size_t; + } else { + state_bak_4 = state; + mblength_4 = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength_4 == -(1 as libc::c_int) as size_t + || mblength_4 == -(2 as libc::c_int) as size_t + { + state = state_bak_4; + mblength_4 = 1 as libc::c_int as size_t; + } + if mblength_4 < 1 as libc::c_int as libc::c_ulong { + mblength_4 = 1 as libc::c_int as size_t; + } + temp = sh_xmalloc( + mblength_4.wrapping_add(2 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10750 as libc::c_int, + ) + as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + i_0 = 0 as libc::c_int; + while (i_0 as libc::c_ulong) < mblength_4 { + let fresh123 = sindex; + sindex = sindex + 1; + *temp.offset((i_0 + 1 as libc::c_int) as isize) = + *string.offset(fresh123 as isize); + i_0 += 1; + } + *temp.offset( + mblength_4.wrapping_add(1 as libc::c_int as libc::c_ulong) + as isize, + ) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + twochars[0 as libc::c_int as usize] = + '\u{1}' as i32 as libc::c_char; + twochars[1 as libc::c_int as usize] = c as libc::c_char; + current_block = 18404008029668793007; + } + } + } else if locale_mb_cur_max > 1 as libc::c_int { + let mut i_1: libc::c_int = 0; + let mut state_bak_5: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength_5: size_t = 0; + i_1 = is_basic(*string.offset(sindex as isize)); + if i_1 != 0 { + mblength_5 = 1 as libc::c_int as size_t; + } else if locale_utf8locale != 0 + && *string.offset(sindex as isize) as libc::c_int + & 0x80 as libc::c_int + == 0 as libc::c_int + { + mblength_5 = (*string.offset(sindex as isize) as libc::c_int + != 0 as libc::c_int) + as libc::c_int + as size_t; + } else { + state_bak_5 = state; + mblength_5 = mbrlen( + string.offset(sindex as isize), + string_size.wrapping_sub(sindex as libc::c_ulong), + &mut state, + ); + } + if mblength_5 == -(1 as libc::c_int) as size_t + || mblength_5 == -(2 as libc::c_int) as size_t + { + state = state_bak_5; + mblength_5 = 1 as libc::c_int as size_t; + } + if mblength_5 < 1 as libc::c_int as libc::c_ulong { + mblength_5 = 1 as libc::c_int as size_t; + } + temp = sh_xmalloc( + mblength_5.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10762 as libc::c_int, + ) as *mut libc::c_char; + i_1 = 0 as libc::c_int; + while (i_1 as libc::c_ulong) < mblength_5 { + let fresh124 = sindex; + sindex = sindex + 1; + *temp.offset(i_1 as isize) = *string.offset(fresh124 as isize); + i_1 += 1; + } + *temp.offset(mblength_5 as isize) = '\u{0}' as i32 as libc::c_char; + current_block = 16465155782176963379; + } else { + current_block = 1398496724659307859; + } + } + 10574327403355912886 => { + if !temp.is_null() { + temp1 = temp; + temp = quote_string(temp); + sh_xfree( + temp1 as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10644 as libc::c_int, + ); + current_block = 16465155782176963379; + } else { + c = '\u{7f}' as i32 as libc::c_uchar; + sindex -= 1; + had_quoted_null = 1 as libc::c_int; + current_block = 1398496724659307859; + } + } + 8423922909464824957 => { + if *string.offset(sindex as isize) != 0 { + sindex += 1; + } + current_block = 16465155782176963379; + } + _ => {} + } + match current_block { + 16465155782176963379 => { + if !temp.is_null() { + istring = sub_append_string( + temp, + istring, + &mut istring_index, + &mut istring_size, + ); + temp = 0 as *mut libc::c_char; + } + } + 1398496724659307859 => { + if (istring_index + 1 as libc::c_int) as libc::c_ulong >= istring_size { + while (istring_index + 1 as libc::c_int) as libc::c_ulong + >= istring_size + { + istring_size = (istring_size as libc::c_ulong) + .wrapping_add(128 as libc::c_int as libc::c_ulong) + as size_t + as size_t; + } + istring = sh_xrealloc( + istring as *mut libc::c_void, + istring_size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10766 as libc::c_int, + ) as *mut libc::c_char; + } + let fresh125 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh125 as isize) = c as libc::c_char; + *istring.offset(istring_index as isize) = '\u{0}' as i32 as libc::c_char; + sindex += 1; + } + _ => { + if (istring_index + 2 as libc::c_int) as libc::c_ulong >= istring_size { + while (istring_index + 2 as libc::c_int) as libc::c_ulong + >= istring_size + { + istring_size = (istring_size as libc::c_ulong) + .wrapping_add(128 as libc::c_int as libc::c_ulong) + as size_t + as size_t; + } + istring = sh_xrealloc( + istring as *mut libc::c_void, + istring_size, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10467 as libc::c_int, + ) as *mut libc::c_char; + } + let fresh119 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh119 as isize) = twochars[0 as libc::c_int as usize]; + let fresh120 = istring_index; + istring_index = istring_index + 1; + *istring.offset(fresh120 as isize) = twochars[1 as libc::c_int as usize]; + *istring.offset(istring_index as isize) = '\u{0}' as i32 as libc::c_char; + } + } + } + } + if *istring as libc::c_int == '\u{0}' as i32 { + if quoted_dollar_at == 0 as libc::c_int + && (had_quoted_null != 0 || quoted_state == 1 as libc::c_int) + { + *istring.offset(0 as libc::c_int as isize) = '\u{7f}' as i32 as libc::c_char; + *istring.offset(1 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + tword = alloc_word_desc(); + let ref mut fresh126 = (*tword).word; + *fresh126 = istring; + istring = 0 as *mut libc::c_char; + (*tword).flags |= (1 as libc::c_int) << 18 as libc::c_int; + list = make_word_list(tword, 0 as *mut libc::c_void as *mut WORD_LIST); + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + (*tword).flags |= (1 as libc::c_int) << 1 as libc::c_int; + } + } else if quoted_state == 0 as libc::c_int || quoted_dollar_at != 0 { + list = 0 as *mut libc::c_void as *mut WORD_LIST; + } else { + list = 0 as *mut libc::c_void as *mut WORD_LIST; + } + } else if (*word).flags & (1 as libc::c_int) << 4 as libc::c_int != 0 { + tword = alloc_word_desc(); + let ref mut fresh127 = (*tword).word; + *fresh127 = istring; + if had_quoted_null != 0 + && (*istring.offset(0 as libc::c_int as isize) as libc::c_int == '\u{7f}' as i32 + && *istring.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + { + (*tword).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } + istring = 0 as *mut libc::c_char; + if (*word).flags & (1 as libc::c_int) << 2 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 2 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 15 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 15 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 5 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 5 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 26 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 26 as libc::c_int; + } + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 { + (*tword).flags |= (1 as libc::c_int) << 1 as libc::c_int; + } + list = make_word_list(tword, 0 as *mut libc::c_void as *mut WORD_LIST); + } else { + if (*word).flags & (1 as libc::c_int) << 11 as libc::c_int != 0 { + list = list_string( + istring, + b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + quoted, + ); + tword = (*list).word; + if had_quoted_null != 0 + && (*istring.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *istring.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + (*tword).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } + sh_xfree( + list as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10851 as libc::c_int, + ); + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10852 as libc::c_int, + ); + istring = 0 as *mut libc::c_char; + current_block = 18054563751907035352; + } else { + ifs_chars = 0 as *mut libc::c_char; + ifs_chars = if quoted_dollar_at != 0 || has_dollar_at != 0 { + ifs_value + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if split_on_spaces != 0 { + if ifs_is_set == 0 as libc::c_int { + list = list_string( + istring, + b" \t\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 1 as libc::c_int, + ); + } else { + list = list_string( + istring, + b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 1 as libc::c_int, + ); + } + current_block = 16332075848674751501; + } else if has_dollar_at != 0 + && quoted_dollar_at == 0 as libc::c_int + && !ifs_chars.is_null() + && quoted == 0 as libc::c_int + && (*word).flags & (1 as libc::c_int) << 6 as libc::c_int != 0 + { + tword = alloc_word_desc(); + if *ifs_chars as libc::c_int != 0 && *ifs_chars as libc::c_int != ' ' as i32 { + list = list_string( + istring, + (if *ifs_chars as libc::c_int != 0 { + ifs_chars + } else { + b" \0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char, + 1 as libc::c_int, + ); + let ref mut fresh128 = (*tword).word; + *fresh128 = string_list(list); + } else { + let ref mut fresh129 = (*tword).word; + *fresh129 = istring; + } + if had_quoted_null != 0 + && (*istring.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *istring.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + (*tword).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } + if (*tword).word != istring { + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10918 as libc::c_int, + ); + } + istring = 0 as *mut libc::c_char; + current_block = 18054563751907035352; + } else if has_dollar_at != 0 && !ifs_chars.is_null() { + list = list_string( + istring, + (if *ifs_chars as libc::c_int != 0 { + ifs_chars + } else { + b" \0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char, + 1 as libc::c_int, + ); + current_block = 16332075848674751501; + } else { + tword = alloc_word_desc(); + if !expanded_something.is_null() + && *expanded_something == 0 as libc::c_int + && has_quoted_ifs != 0 + { + let ref mut fresh130 = (*tword).word; + *fresh130 = remove_quoted_ifs(istring); + } else { + let ref mut fresh131 = (*tword).word; + *fresh131 = istring; + } + if had_quoted_null != 0 + && (*istring.offset(0 as libc::c_int as isize) as libc::c_int + == '\u{7f}' as i32 + && *istring.offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) + { + (*tword).flags |= (1 as libc::c_int) << 18 as libc::c_int; + } else if had_quoted_null != 0 { + (*tword).flags |= (1 as libc::c_int) << 21 as libc::c_int; + } + if (*tword).word != istring { + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10936 as libc::c_int, + ); + } + istring = 0 as *mut libc::c_char; + current_block = 18054563751907035352; + } + } + match current_block { + 16332075848674751501 => {} + _ => { + if quoted & (0x1 as libc::c_int | 0x2 as libc::c_int) != 0 + || quoted_state == 2 as libc::c_int + { + (*tword).flags |= (1 as libc::c_int) << 1 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 2 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 2 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 15 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 15 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 5 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 5 as libc::c_int; + } + if (*word).flags & (1 as libc::c_int) << 26 as libc::c_int != 0 { + (*tword).flags |= (1 as libc::c_int) << 26 as libc::c_int; + } + list = make_word_list(tword, 0 as *mut libc::c_void as *mut WORD_LIST); + } + } + } + sh_xfree( + istring as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10953 as libc::c_int, + ); + return list; + } +} +#[no_mangle] +pub fn string_quote_removal( + mut string: *mut libc::c_char, + mut quoted: libc::c_int, +) -> *mut libc::c_char { + let mut slen: size_t = 0; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + let mut result_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut send: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sindex: libc::c_int = 0; + let mut tindex: libc::c_int = 0; + let mut dquote: libc::c_int = 0; + let mut c: libc::c_uchar = 0; + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + unsafe { + memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::() as usize, + ); + slen = strlen(string) as u64; + send = string.offset(slen as isize); + result_string = sh_xmalloc( + slen.wrapping_add(1 as libc::c_int as libc::c_ulong), + b"../subst.c\0" as *const u8 as *const libc::c_char, + 10980 as libc::c_int, + ) as *mut libc::c_char; + r = result_string; + sindex = 0 as libc::c_int; + dquote = sindex; + loop { + c = *string.offset(sindex as isize) as libc::c_uchar; + if !(c != 0) { + break; + } + let mut current_block_41: u64; + match c as libc::c_int { + 92 => { + sindex += 1; + c = *string.offset(sindex as isize) as libc::c_uchar; + if c as libc::c_int == 0 as libc::c_int { + let fresh132 = r; + r = r.offset(1); + *fresh132 = '\\' as i32 as libc::c_char; + current_block_41 = 13619784596304402172; + } else { + if (quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 || dquote != 0) + && *sh_syntaxtab.as_mut_ptr().offset(c as isize) & 0x40 as libc::c_int + == 0 as libc::c_int + { + let fresh133 = r; + r = r.offset(1); + *fresh133 = '\\' as i32 as libc::c_char; + } + current_block_41 = 10710088620172452289; + } + } + 39 => { + if quoted & (0x2 as libc::c_int | 0x1 as libc::c_int) != 0 || dquote != 0 { + let fresh135 = r; + r = r.offset(1); + *fresh135 = c as libc::c_char; + sindex += 1; + } else { + tindex = sindex + 1 as libc::c_int; + temp = string_extract_single_quoted(string, &mut tindex); + if !temp.is_null() { + strcpy(r, temp); + r = r.offset(strlen(r) as isize); + sh_xfree( + temp as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11014 as libc::c_int, + ); + } + sindex = tindex; + } + current_block_41 = 13619784596304402172; + } + 34 => { + dquote = 1 as libc::c_int - dquote; + sindex += 1; + current_block_41 = 13619784596304402172; + } + _ => { + current_block_41 = 10710088620172452289; + } + } + match current_block_41 { + 10710088620172452289 => { + if locale_mb_cur_max > 1 as libc::c_int { + let mut state_bak: mbstate_t = mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mblength: size_t = 0; + let mut _i: libc::c_int = 0; + _i = is_basic(*string.offset(sindex as isize)); + if _i != 0 { + mblength = 1 as libc::c_int as size_t; + } else { + state_bak = state; + mblength = mbrlen( + string.offset(sindex as isize), + send.offset_from(string.offset(sindex as isize)) as libc::c_long + as size_t, + &mut state, + ); + } + if mblength == -(2 as libc::c_int) as size_t + || mblength == -(1 as libc::c_int) as size_t + { + state = state_bak; + mblength = 1 as libc::c_int as size_t; + } else { + mblength = if mblength < 1 as libc::c_int as libc::c_ulong { + 1 as libc::c_int as libc::c_ulong + } else { + mblength + }; + } + libc::memcpy( + r as *mut libc::c_void, + string.offset(sindex as isize) as *const libc::c_void, + mblength as libc::size_t, + ); + r = r.offset(mblength as isize); + sindex = (sindex as libc::c_ulong).wrapping_add(mblength) as libc::c_int + as libc::c_int; + } else { + let fresh134 = r; + r = r.offset(1); + *fresh134 = *string.offset(sindex as isize); + sindex += 1; + } + } + _ => {} + } + } + *r = '\u{0}' as i32 as libc::c_char; + } + return result_string; +} +#[no_mangle] +pub fn setifs(mut v: *mut SHELL_VAR) { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut uc: libc::c_uchar = 0; + unsafe { + ifs_var = v; + ifs_value = (if !v.is_null() && !((*v).value).is_null() { + (*v).value + } else { + b" \t\n\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + ifs_is_set = (ifs_var != 0 as *mut SHELL_VAR) as libc::c_int; + ifs_is_null = + (ifs_is_set != 0 && *ifs_value as libc::c_int == 0 as libc::c_int) as libc::c_int; + memset( + ifs_cmap.as_mut_ptr() as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::<[libc::c_uchar; 256]>() as usize, + ); + t = ifs_value; + while !t.is_null() && *t as libc::c_int != 0 { + uc = *t as libc::c_uchar; + ifs_cmap[uc as usize] = 1 as libc::c_int as libc::c_uchar; + t = t.offset(1); + } + if ifs_value.is_null() { + ifs_firstc[0 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_uchar; + ifs_firstc_len = 1 as libc::c_int as size_t; + } else { + if locale_utf8locale != 0 + && *ifs_value as libc::c_int & 0x80 as libc::c_int == 0 as libc::c_int + { + ifs_firstc_len = (if *ifs_value as libc::c_int != 0 as libc::c_int { + 1 as libc::c_int + } else { + 0 as libc::c_int + }) as size_t; + } else { + let mut ifs_len: size_t = 0; + ifs_len = strnlen(ifs_value, __ctype_get_mb_cur_max()) as u64; + ifs_firstc_len = (if __ctype_get_mb_cur_max() > 1 as libc::c_int as usize { + mblen(ifs_value, ifs_len) + } else { + 1 as libc::c_int + }) as size_t; + } + if ifs_firstc_len == 1 as libc::c_int as libc::c_ulong + || ifs_firstc_len == 0 as libc::c_int as libc::c_ulong + || (ifs_firstc_len == -(1 as libc::c_int) as size_t + || ifs_firstc_len == -(2 as libc::c_int) as size_t) + { + ifs_firstc[0 as libc::c_int as usize] = + *ifs_value.offset(0 as libc::c_int as isize) as libc::c_uchar; + ifs_firstc[1 as libc::c_int as usize] = '\u{0}' as i32 as libc::c_uchar; + ifs_firstc_len = 1 as libc::c_int as size_t; + } else { + memcpy( + ifs_firstc.as_mut_ptr() as *mut libc::c_void, + ifs_value as *const libc::c_void, + ifs_firstc_len as usize, + ); + } + }; + } +} +#[no_mangle] +pub fn getifs() -> *mut libc::c_char { + unsafe { + return ifs_value; + } +} +#[no_mangle] +pub fn word_split(mut w: *mut WORD_DESC, mut ifs_chars: *mut libc::c_char) -> *mut WORD_LIST { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + unsafe { + if !w.is_null() { + let mut xifs: *mut libc::c_char = 0 as *mut libc::c_char; + xifs = (if (*w).flags & (1 as libc::c_int) << 1 as libc::c_int != 0 + || ifs_chars.is_null() + { + b"\0" as *const u8 as *const libc::c_char + } else { + ifs_chars + }) as *mut libc::c_char; + result = list_string( + (*w).word, + xifs, + (*w).flags & (1 as libc::c_int) << 1 as libc::c_int, + ); + } else { + result = 0 as *mut libc::c_void as *mut WORD_LIST; + } + } + return result; +} +fn word_list_split(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + let mut result: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tresult: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut e: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + t = list; + result = 0 as *mut libc::c_void as *mut WORD_LIST; + unsafe { + while !t.is_null() { + tresult = word_split((*t).word, ifs_value); + if tresult.is_null() + && !((*t).word).is_null() + && (*(*t).word).flags & (1 as libc::c_int) << 21 as libc::c_int != 0 + { + w = alloc_word_desc(); + let ref mut fresh136 = (*w).word; + *fresh136 = sh_xmalloc( + 1 as libc::c_int as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11185 as libc::c_int, + ) as *mut libc::c_char; + *((*w).word).offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char; + tresult = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + } + if result.is_null() { + e = tresult; + result = e; + } else { + let ref mut fresh137 = (*e).next; + *fresh137 = tresult; + while !((*e).next).is_null() { + e = (*e).next; + } + } + t = (*t).next; + } + } + return result; +} +fn exp_jump_to_top_level(mut v: libc::c_int) { + unsafe { + set_pipestatus_from_exit(last_command_exit_value); + expand_no_split_dollar_star = 0 as libc::c_int; + if expanding_redir != 0 { + undo_partial_redirects(); + } + expanding_redir = 0 as libc::c_int; + assigning_in_environment = 0 as libc::c_int; + if parse_and_execute_level == 0 as libc::c_int { + top_level_cleanup(); + } + jump_to_top_level(v); + } +} +fn separate_out_assignments(mut tlist: *mut WORD_LIST) -> *mut WORD_LIST { + let mut vp: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut lp: *mut WORD_LIST = 0 as *mut WORD_LIST; + if tlist.is_null() { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + unsafe { + if !subst_assign_varlist.is_null() { + dispose_words(subst_assign_varlist); + } + subst_assign_varlist = 0 as *mut libc::c_void as *mut WORD_LIST; + lp = tlist; + vp = lp; + while !lp.is_null() && (*(*lp).word).flags & (1 as libc::c_int) << 2 as libc::c_int != 0 { + vp = lp; + lp = (*lp).next; + } + if lp != tlist { + subst_assign_varlist = tlist; + let ref mut fresh138 = (*vp).next; + *fresh138 = 0 as *mut libc::c_void as *mut WORD_LIST; + tlist = lp; + } + if tlist.is_null() { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + if place_keywords_in_env != 0 { + let mut tp: *mut WORD_LIST = 0 as *mut WORD_LIST; + tp = tlist; + lp = (*tlist).next; + while !lp.is_null() { + if (*(*lp).word).flags & (1 as libc::c_int) << 2 as libc::c_int != 0 { + if subst_assign_varlist.is_null() { + vp = lp; + subst_assign_varlist = vp; + } else { + let ref mut fresh139 = (*vp).next; + *fresh139 = lp; + vp = lp; + } + let ref mut fresh140 = (*tp).next; + *fresh140 = (*lp).next; + let ref mut fresh141 = (*lp).next; + *fresh141 = 0 as *mut libc::c_void as *mut WORD_LIST; + lp = (*tp).next; + } else { + tp = lp; + lp = (*lp).next; + } + } + } + } + return tlist; +} +#[no_mangle] +pub fn expand_words(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + return expand_word_list_internal( + list, + 0x1 as libc::c_int + | 0x2 as libc::c_int + | 0x4 as libc::c_int + | 0x8 as libc::c_int + | 0x10 as libc::c_int, + ); +} +#[no_mangle] +pub fn expand_words_no_vars(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + return expand_word_list_internal( + list, + 0x2 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int | 0x10 as libc::c_int, + ); +} +#[no_mangle] +pub fn expand_words_shellexp(mut list: *mut WORD_LIST) -> *mut WORD_LIST { + return expand_word_list_internal( + list, + 0x2 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int, + ); +} +fn glob_expand_word_list(mut tlist: *mut WORD_LIST, mut eflags: libc::c_int) -> *mut WORD_LIST { + let mut glob_array: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut temp_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut glob_index: libc::c_int = 0; + let mut glob_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut output_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut disposables: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut next: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tword: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut x: libc::c_int = 0; + disposables = 0 as *mut libc::c_void as *mut WORD_LIST; + output_list = disposables; + glob_array = 0 as *mut libc::c_void as *mut *mut libc::c_char; + unsafe { + while !tlist.is_null() { + next = (*tlist).next; + if (*(*tlist).word).flags & (1 as libc::c_int) << 5 as libc::c_int == 0 as libc::c_int + && unquoted_glob_pattern_p((*(*tlist).word).word) != 0 + { + glob_array = shell_glob_filename((*(*tlist).word).word, 0x8 as libc::c_int); + if glob_array.is_null() + || glob_array == &mut glob_error_return as *mut *mut libc::c_char + { + glob_array = sh_xmalloc( + ::std::mem::size_of::<*mut libc::c_char>() as libc::c_ulong, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11413 as libc::c_int, + ) as *mut *mut libc::c_char; + let ref mut fresh142 = *glob_array.offset(0 as libc::c_int as isize); + *fresh142 = 0 as *mut libc::c_void as *mut libc::c_char; + } + if (*glob_array.offset(0 as libc::c_int as isize)).is_null() { + temp_string = dequote_string((*(*tlist).word).word); + sh_xfree( + (*(*tlist).word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11421 as libc::c_int, + ); + let ref mut fresh143 = (*(*tlist).word).word; + *fresh143 = temp_string; + } + glob_list = 0 as *mut libc::c_void as *mut WORD_LIST; + glob_index = 0 as libc::c_int; + while !(*glob_array.offset(glob_index as isize)).is_null() { + tword = make_bare_word(*glob_array.offset(glob_index as isize)); + glob_list = make_word_list(tword, glob_list); + glob_index += 1; + } + if !glob_list.is_null() { + output_list = list_append(glob_list, output_list) as *mut WORD_LIST; + let ref mut fresh144 = (*tlist).next; + *fresh144 = disposables; + disposables = tlist; + } else if fail_glob_expansion != 0 as libc::c_int { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + report_error( + dcgettext( + 0 as *const libc::c_char, + b"no match: %s\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + (*(*tlist).word).word, + ); + exp_jump_to_top_level(2 as libc::c_int); + } else if allow_null_glob_expansion == 0 as libc::c_int { + let ref mut fresh145 = (*tlist).next; + *fresh145 = output_list; + output_list = tlist; + } else { + let ref mut fresh146 = (*tlist).next; + *fresh146 = disposables; + disposables = tlist; + } + } else { + temp_string = dequote_string((*(*tlist).word).word); + sh_xfree( + (*(*tlist).word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11459 as libc::c_int, + ); + let ref mut fresh147 = (*(*tlist).word).word; + *fresh147 = temp_string; + let ref mut fresh148 = (*tlist).next; + *fresh148 = output_list; + output_list = tlist; + } + strvec_dispose(glob_array); + glob_array = 0 as *mut libc::c_void as *mut *mut libc::c_char; + tlist = next; + } + if !disposables.is_null() { + dispose_words(disposables); + } + if !output_list.is_null() { + output_list = if !output_list.is_null() && !((*output_list).next).is_null() { + list_reverse(output_list as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + output_list + }; + } + } + return output_list; +} +fn brace_expand_word_list(mut tlist: *mut WORD_LIST, mut eflags: libc::c_int) -> *mut WORD_LIST { + let mut expansions: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut temp_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut disposables: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut output_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut next: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut eindex: libc::c_int = 0; + output_list = 0 as *mut libc::c_void as *mut WORD_LIST; + disposables = output_list; + unsafe { + while !tlist.is_null() { + next = (*tlist).next; + if (*(*tlist).word).flags & (1 as libc::c_int) << 26 as libc::c_int != 0 { + let ref mut fresh149 = (*tlist).next; + *fresh149 = output_list; + output_list = tlist; + } else if (*(*tlist).word).flags + & ((1 as libc::c_int) << 15 as libc::c_int + | (1 as libc::c_int) << 17 as libc::c_int) + == (1 as libc::c_int) << 15 as libc::c_int | (1 as libc::c_int) << 17 as libc::c_int + { + let ref mut fresh150 = (*tlist).next; + *fresh150 = output_list; + output_list = tlist; + } else if !(mbschr((*(*tlist).word).word, '{' as i32)).is_null() { + expansions = brace_expand((*(*tlist).word).word); + eindex = 0 as libc::c_int; + loop { + temp_string = *expansions.offset(eindex as isize); + if temp_string.is_null() { + break; + } + w = alloc_word_desc(); + let ref mut fresh151 = (*w).word; + *fresh151 = temp_string; + if *temp_string.offset(0 as libc::c_int as isize) as libc::c_int + == *((*(*tlist).word).word).offset(0 as libc::c_int as isize) as libc::c_int + && strcmp(temp_string, (*(*tlist).word).word) == 0 as libc::c_int + { + (*w).flags = (*(*tlist).word).flags; + } else { + w = make_word_flags(w, temp_string); + } + output_list = make_word_list(w, output_list); + eindex += 1; + } + sh_xfree( + expansions as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11535 as libc::c_int, + ); + let ref mut fresh152 = (*tlist).next; + *fresh152 = disposables; + disposables = tlist; + } else { + let ref mut fresh153 = (*tlist).next; + *fresh153 = output_list; + output_list = tlist; + } + tlist = next; + } + if !disposables.is_null() { + dispose_words(disposables); + } + if !output_list.is_null() { + output_list = if !output_list.is_null() && !((*output_list).next).is_null() { + list_reverse(output_list as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + output_list + }; + } + } + return output_list; +} +fn make_internal_declare( + mut word: *mut libc::c_char, + mut option: *mut libc::c_char, + mut cmd: *mut libc::c_char, +) -> libc::c_int { + let mut t: libc::c_int = 0; + let mut r: libc::c_int = 0; + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut w: *mut WORD_DESC = 0 as *mut WORD_DESC; + w = make_word(word); + unsafe { + t = assignment((*w).word, 0 as libc::c_int); + if *((*w).word).offset(t as isize) as libc::c_int == '=' as i32 { + *((*w).word).offset(t as isize) = '\u{0}' as i32 as libc::c_char; + if *((*w).word).offset((t - 1 as libc::c_int) as isize) as libc::c_int == '+' as i32 { + *((*w).word).offset((t - 1 as libc::c_int) as isize) = + '\u{0}' as i32 as libc::c_char; + } + } + + wl = make_word_list(w, 0 as *mut libc::c_void as *mut WORD_LIST); + wl = make_word_list(make_word(option), wl); + r = declare_builtin(wl); + dispose_words(wl); + } + return r; +} +fn expand_oneword(mut value: *mut libc::c_char, mut flags: libc::c_int) -> *mut WORD_LIST { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut nl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut kvpair: libc::c_int = 0; + unsafe { + if flags == 0 as libc::c_int { + l = expand_compound_array_assignment( + 0 as *mut libc::c_void as *mut SHELL_VAR, + value, + flags, + ); + quote_compound_array_list(l, flags); + return l; + } else { + l = parse_string_to_word_list( + value, + 1 as libc::c_int, + b"array assign\0" as *const u8 as *const libc::c_char, + ); + kvpair = kvpair_assignment_p(l); + nl = l; + while !nl.is_null() { + if kvpair != 0 { + t = expand_and_quote_kvpair_word((*(*nl).word).word); + } else if (*(*nl).word).flags & (1 as libc::c_int) << 2 as libc::c_int + == 0 as libc::c_int + { + t = sh_single_quote(if !((*(*nl).word).word).is_null() { + (*(*nl).word).word + } else { + b"\0" as *const u8 as *const libc::c_char + }); + } else { + t = expand_and_quote_assoc_word((*(*nl).word).word, flags); + } + sh_xfree( + (*(*nl).word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11646 as libc::c_int, + ); + let ref mut fresh154 = (*(*nl).word).word; + *fresh154 = t; + nl = (*nl).next; + } + return l; + }; + } +} +fn expand_compound_assignment_word(mut tlist: *mut WORD_LIST, mut flags: libc::c_int) { + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut wlen: libc::c_int = 0; + let mut oind: libc::c_int = 0; + let mut t: libc::c_int = 0; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + t = assignment((*(*tlist).word).word, 0 as libc::c_int); + oind = 1 as libc::c_int; + value = extract_array_assignment_list( + ((*(*tlist).word).word) + .offset(t as isize) + .offset(1 as libc::c_int as isize), + &mut oind, + ); + l = expand_oneword(value, flags); + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11678 as libc::c_int, + ); + value = string_list(l); + wlen = (if !value.is_null() && *value.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *value.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *value.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(value) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + temp = sh_xmalloc( + (t + 3 as libc::c_int + wlen + 1 as libc::c_int) as size_t, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11684 as libc::c_int, + ) as *mut libc::c_char; + t += 1; + memcpy( + temp as *mut libc::c_void, + (*(*tlist).word).word as *const libc::c_void, + t as usize, + ); + let fresh155 = t; + t = t + 1; + *temp.offset(fresh155 as isize) = '(' as i32 as libc::c_char; + if !value.is_null() { + memcpy( + temp.offset(t as isize) as *mut libc::c_void, + value as *const libc::c_void, + wlen as usize, + ); + } + t += wlen; + let fresh156 = t; + t = t + 1; + *temp.offset(fresh156 as isize) = ')' as i32 as libc::c_char; + *temp.offset(t as isize) = '\u{0}' as i32 as libc::c_char; + sh_xfree( + (*(*tlist).word).word as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11694 as libc::c_int, + ); + let ref mut fresh157 = (*(*tlist).word).word; + *fresh157 = temp; + sh_xfree( + value as *mut libc::c_void, + b"../subst.c\0" as *const u8 as *const libc::c_char, + 11697 as libc::c_int, + ); + } +} +fn expand_declaration_argument( + mut tlist: *mut WORD_LIST, + mut wcmd: *mut WORD_LIST, +) -> *mut WORD_LIST { + let mut opts: [libc::c_char; 16] = [0; 16]; + let mut omap: [libc::c_char; 128] = [0; 128]; + let mut t: libc::c_int = 0; + let mut opti: libc::c_int = 0; + let mut oind: libc::c_int = 0; + let mut skip: libc::c_int = 0; + let mut inheriting: libc::c_int = 0; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + unsafe { + inheriting = localvar_inherit; + opti = 0 as libc::c_int; + if (*(*tlist).word).flags + & ((1 as libc::c_int) << 22 as libc::c_int + | (1 as libc::c_int) << 25 as libc::c_int + | (1 as libc::c_int) << 28 as libc::c_int + | (1 as libc::c_int) << 23 as libc::c_int) + != 0 + { + let fresh158 = opti; + opti = opti + 1; + opts[fresh158 as usize] = '-' as i32 as libc::c_char; + } + if (*(*tlist).word).flags + & ((1 as libc::c_int) << 22 as libc::c_int | (1 as libc::c_int) << 25 as libc::c_int) + == (1 as libc::c_int) << 22 as libc::c_int | (1 as libc::c_int) << 25 as libc::c_int + { + let fresh159 = opti; + opti = opti + 1; + opts[fresh159 as usize] = 'g' as i32 as libc::c_char; + let fresh160 = opti; + opti = opti + 1; + opts[fresh160 as usize] = 'A' as i32 as libc::c_char; + } else if (*(*tlist).word).flags & (1 as libc::c_int) << 22 as libc::c_int != 0 { + let fresh161 = opti; + opti = opti + 1; + opts[fresh161 as usize] = 'A' as i32 as libc::c_char; + } else if (*(*tlist).word).flags + & ((1 as libc::c_int) << 23 as libc::c_int | (1 as libc::c_int) << 25 as libc::c_int) + == (1 as libc::c_int) << 23 as libc::c_int | (1 as libc::c_int) << 25 as libc::c_int + { + let fresh162 = opti; + opti = opti + 1; + opts[fresh162 as usize] = 'g' as i32 as libc::c_char; + let fresh163 = opti; + opti = opti + 1; + opts[fresh163 as usize] = 'a' as i32 as libc::c_char; + } else if (*(*tlist).word).flags & (1 as libc::c_int) << 23 as libc::c_int != 0 { + let fresh164 = opti; + opti = opti + 1; + opts[fresh164 as usize] = 'a' as i32 as libc::c_char; + } else if (*(*tlist).word).flags & (1 as libc::c_int) << 25 as libc::c_int != 0 { + let fresh165 = opti; + opti = opti + 1; + opts[fresh165 as usize] = 'g' as i32 as libc::c_char; + } + if (*(*tlist).word).flags & (1 as libc::c_int) << 28 as libc::c_int != 0 { + let fresh166 = opti; + opti = opti + 1; + opts[fresh166 as usize] = 'G' as i32 as libc::c_char; + } + memset( + omap.as_mut_ptr() as *mut libc::c_void, + '\u{0}' as i32, + ::std::mem::size_of::<[libc::c_char; 128]>() as usize, + ); + l = (*wcmd).next; + while l != tlist { + if *((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int != '-' as i32 { + break; + } + if *((*(*l).word).word).offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *((*(*l).word).word).offset(1 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && *((*(*l).word).word).offset(2 as libc::c_int as isize) as libc::c_int + == 0 as libc::c_int + { + break; + } + oind = 1 as libc::c_int; + while *((*(*l).word).word).offset(oind as isize) != 0 { + let mut current_block_28: u64; + match *((*(*l).word).word).offset(oind as isize) as libc::c_int { + 73 => { + inheriting = 1 as libc::c_int; + current_block_28 = 9785635831371406912; + } + 105 | 108 | 117 | 99 => { + current_block_28 = 9785635831371406912; + } + _ => { + current_block_28 = 17184638872671510253; + } + } + match current_block_28 { + 9785635831371406912 => { + omap[*((*(*l).word).word).offset(oind as isize) as usize] = + 1 as libc::c_int as libc::c_char; + if opti == 0 as libc::c_int { + let fresh167 = opti; + opti = opti + 1; + opts[fresh167 as usize] = '-' as i32 as libc::c_char; + } + } + _ => {} + } + oind += 1; + } + l = (*l).next; + } + oind = 0 as libc::c_int; + while (oind as libc::c_ulong) + < ::std::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong + { + if omap[oind as usize] != 0 { + let fresh168 = opti; + opti = opti + 1; + opts[fresh168 as usize] = oind as libc::c_char; + } + oind += 1; + } + if (*(*tlist).word).flags + & ((1 as libc::c_int) << 22 as libc::c_int | (1 as libc::c_int) << 23 as libc::c_int) + == 0 as libc::c_int + { + if opti == 0 as libc::c_int { + let fresh169 = opti; + opti = opti + 1; + opts[fresh169 as usize] = '-' as i32 as libc::c_char; + let fresh170 = opti; + opti = opti + 1; + opts[fresh170 as usize] = '-' as i32 as libc::c_char; + } + } + opts[opti as usize] = '\u{0}' as i32 as libc::c_char; + expand_compound_assignment_word( + tlist, + if (*(*tlist).word).flags & (1 as libc::c_int) << 22 as libc::c_int != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + skip = 0 as libc::c_int; + if opti > 0 as libc::c_int { + t = make_internal_declare( + (*(*tlist).word).word, + opts.as_mut_ptr(), + if !wcmd.is_null() { + (*(*wcmd).word).word + } else { + 0 as *mut libc::c_char + }, + ); + if t != 0 as libc::c_int { + ::std::ptr::write_volatile(&mut last_command_exit_value as *mut libc::c_int, t); + if (*(*tlist).word).flags & (1 as libc::c_int) << 30 as libc::c_int != 0 { + skip = 1 as libc::c_int; + } else { + exp_jump_to_top_level(2 as libc::c_int); + } + } + } + if skip == 0 as libc::c_int { + t = do_word_assignment((*tlist).word, 0 as libc::c_int); + if t == 0 as libc::c_int { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + exp_jump_to_top_level(2 as libc::c_int); + } + } + t = assignment((*(*tlist).word).word, 0 as libc::c_int); + *((*(*tlist).word).word).offset(t as isize) = '\u{0}' as i32 as libc::c_char; + if *((*(*tlist).word).word).offset((t - 1 as libc::c_int) as isize) as libc::c_int + == '+' as i32 + { + *((*(*tlist).word).word).offset((t - 1 as libc::c_int) as isize) = + '\u{0}' as i32 as libc::c_char; + } + (*(*tlist).word).flags &= !((1 as libc::c_int) << 2 as libc::c_int + | (1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 15 as libc::c_int + | (1 as libc::c_int) << 17 as libc::c_int + | (1 as libc::c_int) << 22 as libc::c_int + | (1 as libc::c_int) << 23 as libc::c_int); + } + return tlist; +} +fn shell_expand_word_list(mut tlist: *mut WORD_LIST, mut eflags: libc::c_int) -> *mut WORD_LIST { + let mut expanded: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut orig_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut new_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut next: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut temp_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut wcmd: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut expanded_something: libc::c_int = 0; + let mut has_dollar_at: libc::c_int = 0; + new_list = 0 as *mut libc::c_void as *mut WORD_LIST; + wcmd = new_list; + orig_list = tlist; + unsafe { + while !tlist.is_null() { + if wcmd.is_null() + && (*(*tlist).word).flags & (1 as libc::c_int) << 16 as libc::c_int != 0 + { + wcmd = tlist; + } + next = (*tlist).next; + if (*(*tlist).word).flags + & ((1 as libc::c_int) << 15 as libc::c_int + | (1 as libc::c_int) << 17 as libc::c_int) + == (1 as libc::c_int) << 15 as libc::c_int | (1 as libc::c_int) << 17 as libc::c_int + { + expand_declaration_argument(tlist, wcmd); + } + expanded_something = 0 as libc::c_int; + expanded = expand_word_internal( + (*tlist).word, + 0 as libc::c_int, + 0 as libc::c_int, + &mut has_dollar_at, + &mut expanded_something, + ); + if expanded == &mut expand_word_error as *mut WORD_LIST + || expanded == &mut expand_word_fatal as *mut WORD_LIST + { + let ref mut fresh171 = (*(*tlist).word).word; + *fresh171 = 0 as *mut libc::c_void as *mut libc::c_char; + dispose_words(orig_list); + dispose_words(new_list); + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + if expanded == &mut expand_word_error as *mut WORD_LIST { + exp_jump_to_top_level(2 as libc::c_int); + } else { + exp_jump_to_top_level(1 as libc::c_int); + } + } + if expanded_something != 0 + && (*(*tlist).word).flags & (1 as libc::c_int) << 4 as libc::c_int + == 0 as libc::c_int + { + temp_list = word_list_split(expanded); + dispose_words(expanded); + } else { + word_list_remove_quoted_nulls(expanded); + temp_list = expanded; + } + expanded = if !temp_list.is_null() && !((*temp_list).next).is_null() { + list_reverse(temp_list as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + temp_list + }; + new_list = list_append(expanded, new_list) as *mut WORD_LIST; + tlist = next; + } + if !orig_list.is_null() { + dispose_words(orig_list); + } + if !new_list.is_null() { + new_list = if !new_list.is_null() && !((*new_list).next).is_null() { + list_reverse(new_list as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + new_list + }; + } + } + return new_list; +} +fn expand_word_list_internal(mut list: *mut WORD_LIST, mut eflags: libc::c_int) -> *mut WORD_LIST { + let mut new_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut temp_list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tint: libc::c_int = 0; + let mut savecmd: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + tempenv_assign_error = 0 as libc::c_int; + if list.is_null() { + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + new_list = copy_word_list(list); + garglist = new_list; + if eflags & 0x1 as libc::c_int != 0 { + new_list = separate_out_assignments(new_list); + garglist = new_list; + if new_list.is_null() { + if !subst_assign_varlist.is_null() { + temp_list = subst_assign_varlist; + while !temp_list.is_null() { + savecmd = this_command_name; + this_command_name = 0 as *mut libc::c_void as *mut libc::c_char; + tint = do_word_assignment((*temp_list).word, 0 as libc::c_int); + this_command_name = savecmd; + if tint == 0 as libc::c_int { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + if interactive_shell == 0 as libc::c_int + && posixly_correct != 0 + && executing_command_builtin == 0 as libc::c_int + { + exp_jump_to_top_level(1 as libc::c_int); + } else { + exp_jump_to_top_level(2 as libc::c_int); + } + } + temp_list = (*temp_list).next; + } + dispose_words(subst_assign_varlist); + subst_assign_varlist = 0 as *mut libc::c_void as *mut WORD_LIST; + } + return 0 as *mut libc::c_void as *mut WORD_LIST; + } + } + if eflags & 0x2 as libc::c_int != 0 && brace_expansion != 0 && !new_list.is_null() { + new_list = brace_expand_word_list(new_list, eflags); + } + new_list = shell_expand_word_list(new_list, eflags); + if !new_list.is_null() { + if eflags & 0x10 as libc::c_int != 0 && disallow_filename_globbing == 0 as libc::c_int { + new_list = glob_expand_word_list(new_list, eflags); + } else { + new_list = dequote_list(new_list); + } + } + if eflags & 0x1 as libc::c_int != 0 && !subst_assign_varlist.is_null() { + let mut assign_func: Option = None; + let mut is_special_builtin: libc::c_int = 0; + let mut is_builtin_or_func: libc::c_int = 0; + assign_func = if !new_list.is_null() { + Some(assign_in_env) + } else { + ::std::mem::transmute::< + Option libc::c_int>, + Option libc::c_int>, + >(Some(::std::mem::transmute::< + fn(*mut WORD_DESC, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(do_word_assignment))) + }; + tempenv_assign_error = 0 as libc::c_int; + is_builtin_or_func = (!new_list.is_null() + && !((*new_list).word).is_null() + && ((find_shell_builtin((*(*new_list).word).word)).is_some() + || !(find_function((*(*new_list).word).word)).is_null())) + as libc::c_int; + is_special_builtin = (posixly_correct != 0 + && !new_list.is_null() + && !((*new_list).word).is_null() + && (find_special_builtin((*(*new_list).word).word)).is_some()) + as libc::c_int; + temp_list = subst_assign_varlist; + while !temp_list.is_null() { + savecmd = this_command_name; + this_command_name = 0 as *mut libc::c_void as *mut libc::c_char; + assigning_in_environment = (assign_func == Some(assign_in_env)) as libc::c_int; + tint = (Some(assign_func.expect("non-null function pointer"))) + .expect("non-null function pointer")( + (*temp_list).word, is_builtin_or_func + ); + assigning_in_environment = 0 as libc::c_int; + this_command_name = savecmd; + if tint == 0 as libc::c_int { + if assign_func + == ::std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(::std::mem::transmute::< + fn(*mut WORD_DESC, libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >( + do_word_assignment + ))) + { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + if interactive_shell == 0 as libc::c_int && posixly_correct != 0 { + exp_jump_to_top_level(1 as libc::c_int); + } else { + exp_jump_to_top_level(2 as libc::c_int); + } + } else if interactive_shell == 0 as libc::c_int && is_special_builtin != 0 { + ::std::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 1 as libc::c_int, + ); + exp_jump_to_top_level(1 as libc::c_int); + } else { + tempenv_assign_error += 1; + } + } + temp_list = (*temp_list).next; + } + dispose_words(subst_assign_varlist); + subst_assign_varlist = 0 as *mut libc::c_void as *mut WORD_LIST; + } + } + return new_list; +} diff --git a/utshell-0.5.0/src/syntax.rs b/utshell-0.5.0/src/syntax.rs new file mode 100644 index 00000000..1994480d --- /dev/null +++ b/utshell-0.5.0/src/syntax.rs @@ -0,0 +1,280 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +// use libc::c_int; +// use r_bash::*; +#[no_mangle] +pub static mut sh_syntabsiz: libc::c_int = 256; + +#[no_mangle] +pub static mut sh_syntaxtab: [libc::c_int; 256] = [ + CWORD as libc::c_int, /* 0 */ + CSPECL as libc::c_int, /* CTLESC */ + CWORD as libc::c_int, /* 2 */ + CWORD as libc::c_int, /* 3 */ + CWORD as libc::c_int, /* 4 */ + CWORD as libc::c_int, /* 5 */ + CWORD as libc::c_int, /* 6 */ + CWORD as libc::c_int, /* \a */ + CWORD as libc::c_int, /* \b */ + CSHBRK as libc::c_int | CBLANK as libc::c_int, /* \t */ + CSHBRK as libc::c_int | CBSDQUOTE as libc::c_int, /* \n */ + CWORD as libc::c_int, /* \v */ + CWORD as libc::c_int, /* \f */ + CWORD as libc::c_int, /* \r */ + CWORD as libc::c_int, /* 14 */ + CWORD as libc::c_int, /* 15 */ + CWORD as libc::c_int, /* 16 */ + CWORD as libc::c_int, /* 17 */ + CWORD as libc::c_int, /* 18 */ + CWORD as libc::c_int, /* 19 */ + CWORD as libc::c_int, /* 20 */ + CWORD as libc::c_int, /* 21 */ + CWORD as libc::c_int, /* 22 */ + CWORD as libc::c_int, /* 23 */ + CWORD as libc::c_int, /* 24 */ + CWORD as libc::c_int, /* 25 */ + CWORD as libc::c_int, /* 26 */ + CWORD as libc::c_int, /* ESC */ + CWORD as libc::c_int, /* 28 */ + CWORD as libc::c_int, /* 29 */ + CWORD as libc::c_int, /* 30 */ + CWORD as libc::c_int, /* 31 */ + CSHBRK as libc::c_int | CBLANK as libc::c_int, /* SPC */ + CXGLOB as libc::c_int | CSPECVAR as libc::c_int, /* ! */ + CQUOTE as libc::c_int | CBSDQUOTE as libc::c_int | CXQUOTE as libc::c_int, /* " */ + CSPECVAR as libc::c_int, /* # */ + CEXP as libc::c_int + | CBSDQUOTE as libc::c_int + | CBSHDOC as libc::c_int + | CSPECVAR as libc::c_int, /* $ */ + CWORD as libc::c_int, /* % */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int, /* & */ + CQUOTE as libc::c_int | CXQUOTE as libc::c_int, /* ' */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int, /* ( */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int, /* ) */ + CGLOB as libc::c_int | CXGLOB as libc::c_int | CSPECVAR as libc::c_int, /* * */ + CXGLOB as libc::c_int | CSUBSTOP as libc::c_int, /* + */ + CWORD as libc::c_int, /* , */ + CSPECVAR as libc::c_int | CSUBSTOP as libc::c_int, /* - */ + CWORD as libc::c_int, /* . */ + CWORD as libc::c_int, /* / */ + CWORD as libc::c_int, /* 0 */ + CWORD as libc::c_int, /* 1 */ + CWORD as libc::c_int, /* 2 */ + CWORD as libc::c_int, /* 3 */ + CWORD as libc::c_int, /* 4 */ + CWORD as libc::c_int, /* 5 */ + CWORD as libc::c_int, /* 6 */ + CWORD as libc::c_int, /* 7 */ + CWORD as libc::c_int, /* 8 */ + CWORD as libc::c_int, /* 9 */ + CWORD as libc::c_int, /* : */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int, /* ; */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int | CEXP as libc::c_int, /* < */ + CSUBSTOP as libc::c_int, /* = */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int | CEXP as libc::c_int, /* > */ + CGLOB as libc::c_int + | CXGLOB as libc::c_int + | CSPECVAR as libc::c_int + | CSUBSTOP as libc::c_int, /* ? */ + CXGLOB as libc::c_int | CSPECVAR as libc::c_int, /* @ */ + CWORD as libc::c_int, /* A */ + CWORD as libc::c_int, /* B */ + CWORD as libc::c_int, /* C */ + CWORD as libc::c_int, /* D */ + CWORD as libc::c_int, /* E */ + CWORD as libc::c_int, /* F */ + CWORD as libc::c_int, /* G */ + CWORD as libc::c_int, /* H */ + CWORD as libc::c_int, /* I */ + CWORD as libc::c_int, /* J */ + CWORD as libc::c_int, /* K */ + CWORD as libc::c_int, /* L */ + CWORD as libc::c_int, /* M */ + CWORD as libc::c_int, /* N */ + CWORD as libc::c_int, /* O */ + CWORD as libc::c_int, /* P */ + CWORD as libc::c_int, /* Q */ + CWORD as libc::c_int, /* R */ + CWORD as libc::c_int, /* S */ + CWORD as libc::c_int, /* T */ + CWORD as libc::c_int, /* U */ + CWORD as libc::c_int, /* V */ + CWORD as libc::c_int, /* W */ + CWORD as libc::c_int, /* X */ + CWORD as libc::c_int, /* Y */ + CWORD as libc::c_int, /* Z */ + CGLOB as libc::c_int, /* [ */ + CBSDQUOTE as libc::c_int | CBSHDOC as libc::c_int | CXQUOTE as libc::c_int, /* \ */ + CGLOB as libc::c_int, /* ] */ + CGLOB as libc::c_int, /* ^ */ + CWORD as libc::c_int, /* _ */ + CBACKQ as libc::c_int + | CQUOTE as libc::c_int + | CBSDQUOTE as libc::c_int + | CBSHDOC as libc::c_int + | CXQUOTE as libc::c_int, /* ` */ + CWORD as libc::c_int, /* a */ + CWORD as libc::c_int, /* b */ + CWORD as libc::c_int, /* c */ + CWORD as libc::c_int, /* d */ + CWORD as libc::c_int, /* e */ + CWORD as libc::c_int, /* f */ + CWORD as libc::c_int, /* g */ + CWORD as libc::c_int, /* h */ + CWORD as libc::c_int, /* i */ + CWORD as libc::c_int, /* j */ + CWORD as libc::c_int, /* k */ + CWORD as libc::c_int, /* l */ + CWORD as libc::c_int, /* m */ + CWORD as libc::c_int, /* n */ + CWORD as libc::c_int, /* o */ + CWORD as libc::c_int, /* p */ + CWORD as libc::c_int, /* q */ + CWORD as libc::c_int, /* r */ + CWORD as libc::c_int, /* s */ + CWORD as libc::c_int, /* t */ + CWORD as libc::c_int, /* u */ + CWORD as libc::c_int, /* v */ + CWORD as libc::c_int, /* w */ + CWORD as libc::c_int, /* x */ + CWORD as libc::c_int, /* y */ + CWORD as libc::c_int, /* z */ + CWORD as libc::c_int, /* { */ + CSHMETA as libc::c_int | CSHBRK as libc::c_int, /* | */ + CWORD as libc::c_int, /* } */ + CWORD as libc::c_int, /* ~ */ + CSPECL as libc::c_int, /* CTLNUL */ + CWORD as libc::c_int, /* 128 */ + CWORD as libc::c_int, /* 129 */ + CWORD as libc::c_int, /* 130 */ + CWORD as libc::c_int, /* 131 */ + CWORD as libc::c_int, /* 132 */ + CWORD as libc::c_int, /* 133 */ + CWORD as libc::c_int, /* 134 */ + CWORD as libc::c_int, /* 135 */ + CWORD as libc::c_int, /* 136 */ + CWORD as libc::c_int, /* 137 */ + CWORD as libc::c_int, /* 138 */ + CWORD as libc::c_int, /* 139 */ + CWORD as libc::c_int, /* 140 */ + CWORD as libc::c_int, /* 141 */ + CWORD as libc::c_int, /* 142 */ + CWORD as libc::c_int, /* 143 */ + CWORD as libc::c_int, /* 144 */ + CWORD as libc::c_int, /* 145 */ + CWORD as libc::c_int, /* 146 */ + CWORD as libc::c_int, /* 147 */ + CWORD as libc::c_int, /* 148 */ + CWORD as libc::c_int, /* 149 */ + CWORD as libc::c_int, /* 150 */ + CWORD as libc::c_int, /* 151 */ + CWORD as libc::c_int, /* 152 */ + CWORD as libc::c_int, /* 153 */ + CWORD as libc::c_int, /* 154 */ + CWORD as libc::c_int, /* 155 */ + CWORD as libc::c_int, /* 156 */ + CWORD as libc::c_int, /* 157 */ + CWORD as libc::c_int, /* 158 */ + CWORD as libc::c_int, /* 159 */ + CWORD as libc::c_int, /* 160 */ + CWORD as libc::c_int, /* 161 */ + CWORD as libc::c_int, /* 162 */ + CWORD as libc::c_int, /* 163 */ + CWORD as libc::c_int, /* 164 */ + CWORD as libc::c_int, /* 165 */ + CWORD as libc::c_int, /* 166 */ + CWORD as libc::c_int, /* 167 */ + CWORD as libc::c_int, /* 168 */ + CWORD as libc::c_int, /* 169 */ + CWORD as libc::c_int, /* 170 */ + CWORD as libc::c_int, /* 171 */ + CWORD as libc::c_int, /* 172 */ + CWORD as libc::c_int, /* 173 */ + CWORD as libc::c_int, /* 174 */ + CWORD as libc::c_int, /* 175 */ + CWORD as libc::c_int, /* 176 */ + CWORD as libc::c_int, /* 177 */ + CWORD as libc::c_int, /* 178 */ + CWORD as libc::c_int, /* 179 */ + CWORD as libc::c_int, /* 180 */ + CWORD as libc::c_int, /* 181 */ + CWORD as libc::c_int, /* 182 */ + CWORD as libc::c_int, /* 183 */ + CWORD as libc::c_int, /* 184 */ + CWORD as libc::c_int, /* 185 */ + CWORD as libc::c_int, /* 186 */ + CWORD as libc::c_int, /* 187 */ + CWORD as libc::c_int, /* 188 */ + CWORD as libc::c_int, /* 189 */ + CWORD as libc::c_int, /* 190 */ + CWORD as libc::c_int, /* 191 */ + CWORD as libc::c_int, /* 192 */ + CWORD as libc::c_int, /* 193 */ + CWORD as libc::c_int, /* 194 */ + CWORD as libc::c_int, /* 195 */ + CWORD as libc::c_int, /* 196 */ + CWORD as libc::c_int, /* 197 */ + CWORD as libc::c_int, /* 198 */ + CWORD as libc::c_int, /* 199 */ + CWORD as libc::c_int, /* 200 */ + CWORD as libc::c_int, /* 201 */ + CWORD as libc::c_int, /* 202 */ + CWORD as libc::c_int, /* 203 */ + CWORD as libc::c_int, /* 204 */ + CWORD as libc::c_int, /* 205 */ + CWORD as libc::c_int, /* 206 */ + CWORD as libc::c_int, /* 207 */ + CWORD as libc::c_int, /* 208 */ + CWORD as libc::c_int, /* 209 */ + CWORD as libc::c_int, /* 210 */ + CWORD as libc::c_int, /* 211 */ + CWORD as libc::c_int, /* 212 */ + CWORD as libc::c_int, /* 213 */ + CWORD as libc::c_int, /* 214 */ + CWORD as libc::c_int, /* 215 */ + CWORD as libc::c_int, /* 216 */ + CWORD as libc::c_int, /* 217 */ + CWORD as libc::c_int, /* 218 */ + CWORD as libc::c_int, /* 219 */ + CWORD as libc::c_int, /* 220 */ + CWORD as libc::c_int, /* 221 */ + CWORD as libc::c_int, /* 222 */ + CWORD as libc::c_int, /* 223 */ + CWORD as libc::c_int, /* 224 */ + CWORD as libc::c_int, /* 225 */ + CWORD as libc::c_int, /* 226 */ + CWORD as libc::c_int, /* 227 */ + CWORD as libc::c_int, /* 228 */ + CWORD as libc::c_int, /* 229 */ + CWORD as libc::c_int, /* 230 */ + CWORD as libc::c_int, /* 231 */ + CWORD as libc::c_int, /* 232 */ + CWORD as libc::c_int, /* 233 */ + CWORD as libc::c_int, /* 234 */ + CWORD as libc::c_int, /* 235 */ + CWORD as libc::c_int, /* 236 */ + CWORD as libc::c_int, /* 237 */ + CWORD as libc::c_int, /* 238 */ + CWORD as libc::c_int, /* 239 */ + CWORD as libc::c_int, /* 240 */ + CWORD as libc::c_int, /* 241 */ + CWORD as libc::c_int, /* 242 */ + CWORD as libc::c_int, /* 243 */ + CWORD as libc::c_int, /* 244 */ + CWORD as libc::c_int, /* 245 */ + CWORD as libc::c_int, /* 246 */ + CWORD as libc::c_int, /* 247 */ + CWORD as libc::c_int, /* 248 */ + CWORD as libc::c_int, /* 249 */ + CWORD as libc::c_int, /* 250 */ + CWORD as libc::c_int, /* 251 */ + CWORD as libc::c_int, /* 252 */ + CWORD as libc::c_int, /* 253 */ + CWORD as libc::c_int, /* 254 */ + CWORD as libc::c_int, /* 255 */ +]; diff --git a/utshell-0.5.0/src/test.rs b/utshell-0.5.0/src/test.rs new file mode 100644 index 00000000..588efd95 --- /dev/null +++ b/utshell-0.5.0/src/test.rs @@ -0,0 +1,1139 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::arrayfunc::{array_value, valid_array_reference}; +use crate::assoc::assoc_reference; +use crate::builtins::common::number_of_args; +use crate::builtins::set::minus_o_option_value; +use crate::expr::evalexp; +use crate::general::{legal_number, same_file}; +use crate::readline::{__lxstat, array_reference}; +use crate::src_common::*; +use crate::variables::{find_variable, find_variable_noref}; +use crate::version::shell_compatibility_level; + +pub const GT: libc::c_int = 3; +pub const EQ: libc::c_int = 0; +pub const LT: libc::c_int = 2; + +#[inline] +fn get_stat_atime(mut st: *const crate::src_common::stat) -> crate::src_common::timespec { + unsafe { + return (*st).st_atim; + } +} + +#[inline] +fn get_stat_mtime(mut st: *const crate::src_common::stat) -> crate::src_common::timespec { + unsafe { + return (*st).st_mtim; + } +} + +#[inline] +fn timespec_cmp( + mut a: crate::src_common::timespec, + mut b: crate::src_common::timespec, +) -> libc::c_int { + return if a.tv_sec < b.tv_sec { + -(1 as libc::c_int) + } else if a.tv_sec > b.tv_sec { + 1 as libc::c_int + } else { + (a.tv_nsec - b.tv_nsec) as libc::c_int + }; +} + +#[inline] +fn lstat( + mut __path: *const libc::c_char, + mut __statbuf: *mut crate::src_common::stat, +) -> libc::c_int { + unsafe { + return __lxstat(1 as libc::c_int, __path, __statbuf); + } +} + +static mut test_error_return: libc::c_int = 0; +static mut pos: libc::c_int = 0; +static mut test_exit_buf: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: __sigset_t { __val: [0; 16] }, +}; 1]; +static mut argc: libc::c_int = 0; +static mut argv: *mut *mut libc::c_char = 0 as *const *mut libc::c_char as *mut *mut libc::c_char; +static mut noeval: libc::c_int = 0; +pub type __jmp_buf = [libc::c_long; 8]; + +#[no_mangle] +pub fn patcomp( + mut string: *mut libc::c_char, + mut pat: *mut libc::c_char, + mut op: libc::c_int, +) -> libc::c_int { + let mut m: libc::c_int = 0; + unsafe { + m = strmatch( + pat, + string, + FNMATCH_EXTFLAG!() | FNMATCH_IGNCASE!() + ); + return if op == EQ as libc::c_int { + (m == 0) as libc::c_int + } else { + (m != 0) as i32 + }; + } +} + +#[no_mangle] +fn integer_expected_error(mut pch: *mut libc::c_char) { + unsafe { + printf( + b"%s: integer expression expected\n\0" as *const u8 as *const libc::c_char, + pch, + ); + } +} + +#[no_mangle] +fn beyond() { + unsafe { + printf(b"argument expected\n\0" as *const u8 as *const libc::c_char); + } +} + +#[no_mangle] +fn unary_operator() -> libc::c_int { + unsafe { + let mut op: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: intmax_t = 0; + op = *argv.offset(pos as isize); + if test_unop(op) == 0 as libc::c_int { + return 0 as libc::c_int; + } + if *op.offset(1 as libc::c_int as isize) as libc::c_int == 't' as i32 { + pos += 1; + if 0 as libc::c_int != 0 && pos >= argc { + beyond(); + } + if pos < argc { + if legal_number(*argv.offset(pos as isize), &mut r) != 0 { + pos += 1; + if 0 as libc::c_int != 0 && pos >= argc { + beyond(); + } + return unary_test(op, *argv.offset((pos - 1 as libc::c_int) as isize)); + } else { + return 0 as libc::c_int; + } + } else { + return unary_test( + op, + b"1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + } + pos += 1; + if 1 as libc::c_int != 0 && pos >= argc { + beyond(); + } + pos += 1; + return unary_test(op, *argv.offset((pos - 1 as libc::c_int) as isize)); + } +} + +#[no_mangle] +pub fn test_unop(mut op: *mut libc::c_char) -> libc::c_int { + unsafe { + if *op.offset(0 as libc::c_int as isize) as libc::c_int != '-' as i32 + || (*op.offset(1 as libc::c_int as isize) as libc::c_int != 0 + && *op.offset(2 as libc::c_int as isize) as libc::c_int != 0 as libc::c_int) + { + return 0 as libc::c_int; + } + match *op.offset(1 as libc::c_int as isize) as u8 as char { + 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'k' | 'n' | 'o' | 'p' | 'r' | 's' + | 't' | 'u' | 'v' | 'w' | 'x' | 'z' | 'G' | 'L' | 'O' | 'S' | 'N' | 'R' => { + return 1; + } + _ => {} + } + return 0; + } +} + +#[no_mangle] +fn three_arguments() -> libc::c_int { + let mut value: libc::c_int = 0; + unsafe { + if test_binop(*argv.offset((pos + 1 as libc::c_int) as isize)) != 0 { + value = binary_operator(); + pos = argc; + } else if *(*argv.offset((pos + 1 as libc::c_int) as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && (*(*argv.offset((pos + 1 as libc::c_int) as isize)).offset(1 as libc::c_int as isize) + as libc::c_int + == 'a' as i32 + || *(*argv.offset((pos + 1 as libc::c_int) as isize)) + .offset(1 as libc::c_int as isize) as libc::c_int + == 'o' as i32) + && *(*argv.offset((pos + 1 as libc::c_int) as isize)).offset(2 as libc::c_int as isize) + as libc::c_int + == 0 as libc::c_int + { + if *(*argv.offset((pos + 1 as libc::c_int) as isize)).offset(1 as libc::c_int as isize) + as libc::c_int + == 'a' as i32 + { + value = (*(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + != '\u{0}' as i32 + && *(*argv.offset((pos + 2 as libc::c_int) as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + != '\u{0}' as i32) as libc::c_int; + } else { + value = (*(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + != '\u{0}' as i32 + || *(*argv.offset((pos + 2 as libc::c_int) as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + != '\u{0}' as i32) as libc::c_int; + } + pos = argc; + } else if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + pos += 1; + if 1 as libc::c_int != 0 && pos >= argc { + beyond(); + } + //value = !two_arguments(); + value = (two_arguments() == 0) as libc::c_int; + } else if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '(' as i32 + && *(*argv.offset((pos + 2 as libc::c_int) as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + == ')' as i32 + { + value = (*(*argv.offset((pos + 1 as libc::c_int) as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + != '\u{0}' as i32) as libc::c_int; + pos = argc; + } else { + printf( + b"%s: binary operator expected\n\0" as *const u8 as *const libc::c_char, + (*argv).offset((pos + 1) as isize), + ); + } + return value; + } +} + +#[no_mangle] +fn two_arguments() -> libc::c_int { + unsafe { + if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + return (*(*argv.offset((pos + 1 as libc::c_int) as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32) as libc::c_int; + } else if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int != 0 + && *(*argv.offset(pos as isize)).offset(2 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + if test_unop(*argv.offset(pos as isize)) != 0 { + return unary_operator(); + } else { + printf( + b"%s: unary operator expected\n\0" as *const u8 as *const libc::c_char, + (*argv).offset(pos as isize), + ); + } + } else { + printf( + b"%s: unary operator expected\n\0" as *const u8 as *const libc::c_char, + (*argv).offset(pos as isize), + ); + }; + return 0; + } +} + +#[no_mangle] +fn expr() -> libc::c_int { + unsafe { + if pos >= argc { + beyond(); + } + return 0 as libc::c_int ^ or(); + } +} + +#[no_mangle] +fn or() -> libc::c_int { + let mut value: libc::c_int = 0; + let mut v2: libc::c_int = 0; + value = and(); + unsafe { + if pos < argc + && *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == 'o' as i32 + && *(*argv.offset(pos as isize)).offset(2 as libc::c_int as isize) == 0 + { + pos += 1; + if 0 as libc::c_int != 0 && pos >= argc { + beyond(); + } + v2 = or(); + return (value != 0 || v2 != 0) as libc::c_int; + } + return value; + } +} + +#[no_mangle] +fn and() -> libc::c_int { + unsafe { + let mut value: libc::c_int = 0; + let mut v2: libc::c_int = 0; + value = term(); + if pos < argc + && *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == 'a' as i32 + && *(*argv.offset(pos as isize)).offset(2 as libc::c_int as isize) == 0 + { + pos += 1; + if 0 as libc::c_int != 0 && pos >= argc { + beyond(); + } + v2 = and(); + return (value != 0 && v2 != 0) as libc::c_int; + } + return value; + } +} + +#[no_mangle] +fn term() -> libc::c_int { + unsafe { + let mut value: libc::c_int = 0; + if pos >= argc { + beyond(); + } + if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + value = 0 as libc::c_int; + while pos < argc + && *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + pos += 1; + if 1 as libc::c_int != 0 && pos >= argc { + beyond(); + } + value = 1 as libc::c_int - value; + } + return if value != 0 { + (term() == 0) as libc::c_int + } else { + term() + }; + } + if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '(' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + pos += 1; + if 1 as libc::c_int != 0 && pos >= argc { + beyond(); + } + value = expr(); + if (*argv.offset(pos as isize)).is_null() { + printf(b"`)' expected\n\0" as *const u8 as *const libc::c_char); + } else if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + != ')' as i32 + || *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) as libc::c_int + != 0 + { + printf( + b"`)' expected, found %s\n\0" as *const u8 as *const libc::c_char, + (*argv).offset(pos as isize), + ); + } else { + pos += 1; + if 0 as libc::c_int != 0 && pos >= argc { + beyond(); + } + } + return value; + } + + if pos + 3 as libc::c_int <= argc + && test_binop(*argv.offset((pos + 1 as libc::c_int) as isize)) != 0 + { + value = binary_operator(); + } else if pos + 2 as libc::c_int <= argc && test_unop(*argv.offset(pos as isize)) != 0 { + value = unary_operator(); + } else { + value = (*(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + != '\u{0}' as i32) as libc::c_int; + pos += 1; + if 0 as libc::c_int != 0 && pos >= argc { + beyond(); + } + } + return value; + } +} + +#[no_mangle] +fn posixtest() -> libc::c_int { + unsafe { + let mut value: libc::c_int = 0; + match argc - 1 as libc::c_int { + 0 => { + value = 0; + pos = argc; + } + 1 => { + value = (*(*argv.offset(1 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + != '\u{0}' as i32) as libc::c_int; + pos = argc; + } + 2 => { + value = two_arguments(); + pos = argc; + } + 3 => { + value = three_arguments(); + } + 4 => { + if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32 + { + pos += 1; + if 1 as libc::c_int != 0 && pos >= argc { + beyond(); + } + //value = !three_arguments() as libc::c_int; + value = (three_arguments() == 0) as libc::c_int; + } else if *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + == '(' as i32 + && *(*argv.offset(pos as isize)).offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32 + && *(*argv.offset((argc - 1 as libc::c_int) as isize)) + .offset(0 as libc::c_int as isize) as libc::c_int + == ')' as i32 + && *(*argv.offset((argc - 1 as libc::c_int) as isize)) + .offset(1 as libc::c_int as isize) as libc::c_int + == '\u{0}' as i32 + { + pos += 1; + if 1 as libc::c_int != 0 && pos >= argc { + beyond(); + } + value = two_arguments(); + pos = argc; + } + } + _ => { + value = expr(); + } + } + return value; + } +} + +#[no_mangle] +fn binary_operator() -> libc::c_int { + unsafe { + let mut value: libc::c_int = 0; + let mut w: *mut libc::c_char = 0 as *mut libc::c_char; + w = *argv.offset((pos + 1 as libc::c_int) as isize); + if *w.offset(0 as libc::c_int as isize) as libc::c_int == '=' as i32 + && (*w.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *w.offset(1 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *w.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + || (*w.offset(0 as libc::c_int as isize) as libc::c_int == '>' as i32 + || *w.offset(0 as libc::c_int as isize) as libc::c_int == '<' as i32) + && *w.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *w.offset(0 as libc::c_int as isize) as libc::c_int == '!' as i32 + && *w.offset(1 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *w.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + value = binary_test( + w, + *argv.offset(pos as isize), + *argv.offset((pos + 2 as libc::c_int) as isize), + 0 as libc::c_int, + ); + pos += 3 as libc::c_int; + return value; + } + + if *w.offset(0 as libc::c_int as isize) as libc::c_int != '-' as i32 + || *w.offset(3 as libc::c_int as isize) as libc::c_int != '\u{0}' as i32 + || test_binop(w) == 0 as libc::c_int + { + printf( + b"%s: binary operator expected\n\0" as *const u8 as *const libc::c_char, + w, + ); + return 0; + } + value = binary_test( + w, + *argv.offset(pos as isize), + *argv.offset((pos + 2 as libc::c_int) as isize), + 0 as libc::c_int, + ); + pos += 3 as libc::c_int; + return value; + } +} + +#[no_mangle] +pub fn test_binop(mut op: *mut libc::c_char) -> libc::c_int { + unsafe { + if *op.offset(0 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *op.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return 1 as libc::c_int; + } else if (*op.offset(0 as libc::c_int as isize) as libc::c_int == '<' as i32 + || *op.offset(0 as libc::c_int as isize) as libc::c_int == '>' as i32) + && *op.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return 1 as libc::c_int; + } else if (*op.offset(0 as libc::c_int as isize) as libc::c_int == '=' as i32 + || *op.offset(0 as libc::c_int as isize) as libc::c_int == '!' as i32) + && *op.offset(1 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *op.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return 1 as libc::c_int; + } else if *op.offset(0 as libc::c_int as isize) as libc::c_int != '-' as i32 + || *op.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *op.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *op.offset(3 as libc::c_int as isize) as libc::c_int != '\u{0}' as i32 + { + return 0 as libc::c_int; + } else { + if *op.offset(2 as libc::c_int as isize) as libc::c_int == 't' as i32 { + match *op.offset(1 as libc::c_int as isize) as u8 as char { + 'n' | 'o' | 'l' | 'g' => { + return 1; + } + _ => { + return 0; + } + } + } else if *op.offset(1 as libc::c_int as isize) as libc::c_int == 'e' as i32 { + match *op.offset(2 as libc::c_int as isize) as u8 as char { + 'q' | 'f' => { + return 1; + } + _ => { + return 0; + } + } + } else if *op.offset(2 as libc::c_int as isize) as libc::c_int == 'e' as i32 { + match *op.offset(1 as libc::c_int as isize) as u8 as char { + 'n' | 'l' | 'g' => { + return 1; + } + _ => { + return 0; + } + } + } else { + return 0; + } + } + } +} + +#[no_mangle] +pub fn test_command(mut margc: libc::c_int, mut margv: *mut *mut libc::c_char) -> libc::c_int { + unsafe { + let mut value: libc::c_int = 0; + let mut code: libc::c_int = 0; + code = __sigsetjmp(test_exit_buf.as_mut_ptr(), 0 as libc::c_int); + if code != 0 { + return test_error_return; + } + + argv = margv; + if !(*margv.offset(0 as libc::c_int as isize)).is_null() + && *(*margv.offset(0 as libc::c_int as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + == '[' as i32 + && *(*margv.offset(0 as libc::c_int as isize)).offset(1 as libc::c_int as isize) + as libc::c_int + == '\u{0}' as i32 + { + margc -= 1; + if !(*margv.offset(margc as isize)).is_null() + && (*(*margv.offset(margc as isize)).offset(0 as libc::c_int as isize) + as libc::c_int + != ']' as i32 + || *(*margv.offset(margc as isize)).offset(1 as libc::c_int as isize) + as libc::c_int + != 0) + { + printf(b"missing `]'\n\0" as *const u8 as *const libc::c_char); + } + if margc < 2 as libc::c_int { + test_error_return = (0 as libc::c_int == 0) as libc::c_int; + siglongjmp(test_exit_buf.as_mut_ptr(), 1 as libc::c_int); + } + } + argc = margc; + pos = 1 as libc::c_int; + if pos >= argc { + test_error_return = (0 as libc::c_int == 0) as libc::c_int; + siglongjmp(test_exit_buf.as_mut_ptr(), 1 as libc::c_int); + } + noeval = 0 as libc::c_int; + value = posixtest(); + + if pos != argc { + if pos < argc + && *(*argv.offset(pos as isize)).offset(0 as libc::c_int as isize) as libc::c_int + == '-' as i32 + { + printf( + b"syntax error: '%s' unexpected\n\0" as *const u8 as *const libc::c_char, + (*argv).offset(pos as isize), + ); + } else { + printf(b"too many arguments\n\0" as *const u8 as *const libc::c_char); + } + } + + test_error_return = (value == 0) as libc::c_int; + siglongjmp(test_exit_buf.as_mut_ptr(), 1 as libc::c_int); + } +} + +#[no_mangle] +pub fn arithcomp( + mut s: *mut libc::c_char, + mut t: *mut libc::c_char, + op: libc::c_int, + flags: libc::c_int, +) -> libc::c_int { + let mut l: intmax_t = 0; + let mut r: intmax_t = 0; + let mut expok: libc::c_int = 0; + + if flags as libc::c_int & TEST_ARITHEXP as libc::c_int != 0 { + l = evalexp(s, EXP_EXPANDED as i32, &mut expok); + if expok == 0 { + return 0; + } + r = evalexp(t, EXP_EXPANDED as i32, &mut expok); + if expok == 0 { + return 0; + } + } else { + if legal_number(s, &mut l) == 0 { + integer_expected_error(s); + } + if legal_number(t, &mut r) == 0 { + integer_expected_error(t); + } + } + match op { + EQ => return (l == r) as libc::c_int, + NE => return (l != r) as libc::c_int, + LT => return (l < r) as libc::c_int, + GT => return (l > r) as libc::c_int, + LE => return (l <= r) as libc::c_int, + GE => return (l >= r) as libc::c_int, + _ => {} + } + return 0; +} + +#[no_mangle] +pub fn stat_mtime( + mut fn0: *mut libc::c_char, + mut st: *mut crate::src_common::stat, + mut ts: *mut crate::src_common::timespec, +) -> libc::c_int { + unsafe { + let mut r: libc::c_int = 0; + r = sh_stat(fn0, st); + if r < 0 { + return r; + } + *ts = get_stat_mtime(st); + return 0; + } +} + +#[no_mangle] +pub fn filecomp( + mut s: *mut libc::c_char, + mut t: *mut libc::c_char, + op: libc::c_int, +) -> libc::c_int { + let mut st1: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut st2: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut ts1: crate::src_common::timespec = crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }; + let mut ts2: crate::src_common::timespec = crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }; + let mut r1: libc::c_int = 0; + let mut r2: libc::c_int = 0; + + r1 = stat_mtime(s, &mut st1, &mut ts1); + if r1 < 0 { + if op == EF { + return 0; + } + } + + r2 = stat_mtime(t, &mut st2, &mut ts2); + if r2 < 0 { + if op == EF { + return 0; + } + } + + match op { + OT => { + return (r1 < r2 || r2 == 0 as libc::c_int && timespec_cmp(ts1, ts2) < 0) as libc::c_int + } + NT => { + return (r1 > r2 || r1 == 0 as libc::c_int && timespec_cmp(ts1, ts2) > 0) as libc::c_int + } + EF => return same_file(s, t, &mut st1, &mut st2), + _ => {} + } + return 0; +} + +#[no_mangle] +pub fn binary_test( + mut op: *mut libc::c_char, + mut arg1: *mut libc::c_char, + mut arg2: *mut libc::c_char, + mut flags: libc::c_int, +) -> libc::c_int { + unsafe { + let mut patmatch: libc::c_int = 0; + patmatch = flags & 1 as libc::c_int; + if *op.offset(0 as libc::c_int as isize) as libc::c_int == '=' as i32 + && (*op.offset(1 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + || *op.offset(1 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *op.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + { + return if patmatch != 0 { + patcomp(arg1, arg2, 0 as libc::c_int) + } else { + (*arg1.offset(0 as libc::c_int as isize) as libc::c_int + == *arg2.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp(arg1, arg2) == 0 as libc::c_int) as libc::c_int + }; + } else if *op.offset(0 as isize) as libc::c_int == '>' as i32 + || *op.offset(0 as isize) as libc::c_int == '<' as i32 + && *op.offset(1 as isize) as libc::c_int == '\u{0}' as i32 + { + if shell_compatibility_level > 40 as libc::c_int + && flags & TEST_LOCALE as libc::c_int != 0 + { + return if *op.offset(0 as libc::c_int as isize) as libc::c_int == '>' as i32 { + (strcoll(arg1, arg2) > 0 as libc::c_int) as libc::c_int + } else { + (strcoll(arg1, arg2) < 0 as libc::c_int) as libc::c_int + }; + } else { + return if *op.offset(0 as libc::c_int as isize) as libc::c_int == '>' as i32 { + (strcmp(arg1, arg2) > 0 as libc::c_int) as libc::c_int + } else { + (strcmp(arg1, arg2) < 0 as libc::c_int) as libc::c_int + }; + } + } else if *op.offset(0 as libc::c_int as isize) as libc::c_int == '!' as i32 + && *op.offset(1 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *op.offset(2 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32 + { + return if patmatch != 0 { + patcomp(arg1, arg2, 1 as libc::c_int) + } else { + ((*arg1.offset(0 as libc::c_int as isize) as libc::c_int + == *arg2.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp(arg1, arg2) == 0 as libc::c_int) as libc::c_int + == 0 as libc::c_int) as libc::c_int + }; + } else if *op.offset(2 as libc::c_int as isize) as libc::c_int == 't' as i32 { + match *op.offset(1 as libc::c_int as isize) as u8 as char { + 'n' => { + return filecomp(arg1, arg2, NT) as libc::c_int; + } + 'o' => { + return filecomp(arg1, arg2, OT) as libc::c_int; + } + 'l' => { + return arithcomp(arg1, arg2, LT, flags) as libc::c_int; + } + 'g' => { + return arithcomp(arg1, arg2, GT, flags) as libc::c_int; + } + _ => {} + } + } else if *op.offset(1 as libc::c_int as isize) as libc::c_int == 'e' as i32 { + match *op.offset(2 as libc::c_int as isize) as u8 as char { + 'f' => { + return filecomp(arg1, arg2, EF) as libc::c_int; + } + 'q' => { + return arithcomp(arg1, arg2, EQ, flags) as libc::c_int; + } + _ => {} + } + } else if *op.offset(2 as libc::c_int as isize) as libc::c_int == 'e' as i32 { + match *op.offset(1 as libc::c_int as isize) as u8 as char { + 'n' => { + return arithcomp(arg1, arg2, NE, flags) as libc::c_int; + } + 'g' => { + return arithcomp(arg1, arg2, GE, flags) as libc::c_int; + } + 'l' => { + return arithcomp(arg1, arg2, LE, flags) as libc::c_int; + } + _ => {} + } + } + return 0; + } +} + +//whether diff types of variables from stat at arch arm/x86? +#[no_mangle] +pub fn unary_test(mut op: *mut libc::c_char, mut arg: *mut libc::c_char) -> libc::c_int { + let mut r: intmax_t = 0; + let mut stat_buf: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut mtime: crate::src_common::timespec = crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }; + let mut atime: crate::src_common::timespec = crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + match *op.offset(1) as u8 as char { + 'a' | 'e' => { + return (sh_stat(arg, &mut stat_buf) == 0) as libc::c_int; + } + 'r' => { + return (sh_eaccess(arg, R_OK) == 0) as libc::c_int; + } + 'w' => { + return (sh_eaccess(arg, W_OK) == 0) as libc::c_int; + } + 'x' => { + return (sh_eaccess(arg, X_OK) == 0) as libc::c_int; + } + 'O' => { + return (sh_stat(arg, &mut stat_buf) == 0 && current_user.euid == stat_buf.st_uid) + as libc::c_int; + } + 'G' => { + return (sh_stat(arg, &mut stat_buf) == 0 && current_user.egid == stat_buf.st_gid) + as libc::c_int; + } + 'N' => { + if sh_stat(arg, &mut stat_buf) < 0 { + return 0; + } + atime = get_stat_atime(&mut stat_buf); + mtime = get_stat_mtime(&mut stat_buf); + return (timespec_cmp(mtime, atime) > 0) as libc::c_int; + } + 'f' => { + if sh_stat(arg, &mut stat_buf) < 0 { + return 0; + } + return (stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o100000 as libc::c_int as libc::c_uint + || stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint == 0) + as libc::c_int; + } + 'd' => { + return (sh_stat(arg, &mut stat_buf) == 0 + && stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o40000 as libc::c_int as libc::c_uint) + as libc::c_int; + } + 's' => { + return (sh_stat(arg, &mut stat_buf) == 0 && stat_buf.st_size > 0 as off_t) + as libc::c_int; + } + 'S' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o140000 as libc::c_int as libc::c_uint) + as libc::c_int; + } + 'c' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o20000 as libc::c_int as libc::c_uint) + as libc::c_int; + } + 'b' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o60000 as libc::c_int as libc::c_uint) + as libc::c_int; + } + 'p' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o170000 as libc::c_int as libc::c_uint + == 0o10000 as libc::c_int as libc::c_uint) + as libc::c_int; + } + 'L' | 'h' => { + return (*arg.offset(0 as libc::c_int as isize) as i32 != '\u{0}' as i32 + && lstat(arg, &mut stat_buf) == 0 as i32 + && stat_buf.st_mode & 0o170000 as i32 as u32 == 0o120000 as i32 as u32) + as libc::c_int; + } + 'u' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o4000 as libc::c_int as libc::c_uint + != 0 as libc::c_int as libc::c_uint) as libc::c_int; + } + 'g' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o2000 as libc::c_int as libc::c_uint + != 0 as libc::c_int as libc::c_uint) as libc::c_int; + } + 'k' => { + return (sh_stat(arg, &mut stat_buf) == 0 as libc::c_int + && stat_buf.st_mode & 0o1000 as libc::c_int as libc::c_uint + != 0 as libc::c_int as libc::c_uint) as libc::c_int; + } + 't' => { + if legal_number(arg, &mut r) == 0 as libc::c_int { + return 0 as libc::c_int; + } + return (r == r as libc::c_int as libc::c_long && isatty(r as libc::c_int) != 0) + as libc::c_int; + } + 'n' => { + return (*arg.offset(0 as libc::c_int as isize) as libc::c_int != '\u{0}' as i32) + as libc::c_int; + } + 'z' => { + return (*arg.offset(0 as libc::c_int as isize) as libc::c_int == '\u{0}' as i32) + as libc::c_int; + } + 'o' => { + return (minus_o_option_value(arg) == 1 as libc::c_int) as libc::c_int; + } + 'v' => { + if valid_array_reference(arg, 0) != 0 { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rtype: libc::c_int = 0; + let mut ret: libc::c_int = 0; + let mut flags: libc::c_int = 0; + flags = if assoc_expand_once != 0 { + 0x20 as libc::c_int + } else { + 0 as libc::c_int + }; + t = array_value( + arg, + 0 as libc::c_int, + flags, + &mut rtype, + 0 as *mut arrayind_t, + ); + ret = if !t.is_null() { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + if rtype > 0 as libc::c_int { + free(t as *mut libc::c_void); + } + return ret; + } else { + if legal_number(arg, &mut r) != 0 { + return if r >= 0 as libc::c_int as libc::c_long + && r <= number_of_args() as libc::c_long + { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + } + } + + v = find_variable(arg); + if !v.is_null() + && (*v).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && (*v).attributes & 0x4 as libc::c_int != 0 + { + let mut t_0: *mut libc::c_char = 0 as *mut libc::c_char; + t_0 = array_reference((*v).value as *mut ARRAY, 0 as libc::c_int as arrayind_t); + return if !t_0.is_null() { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + } else { + if !v.is_null() + && (*v).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && (*v).attributes & 0x40 as libc::c_int != 0 + { + let mut t_1: *mut libc::c_char = 0 as *mut libc::c_char; + t_1 = assoc_reference( + (*v).value as *mut HASH_TABLE, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + return if !t_1.is_null() { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + } + } + return if !v.is_null() + && (*v).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && !((*v).value).is_null() + { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + } + 'R' => { + v = find_variable_noref(arg); + return if !v.is_null() + && (*v).attributes & 0x1000 as libc::c_int == 0 as libc::c_int + && !((*v).value).is_null() + && (*v).attributes & 0x800 as libc::c_int != 0 + { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + } + _ => {} + } + } + return 0; +} diff --git a/utshell-0.5.0/src/trap.rs b/utshell-0.5.0/src/trap.rs new file mode 100644 index 00000000..d22133e7 --- /dev/null +++ b/utshell-0.5.0/src/trap.rs @@ -0,0 +1,1405 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::bashline::bashline_set_event_hook; +use crate::builtins::evalstring::evalstring; +use crate::builtins::wait::wait_builtin; +use crate::general::legal_number; +use crate::jobs::close_pgrp_pipe; +use crate::jobs::get_original_tty_job_signals; +use crate::jobs::give_terminal_to; +use crate::jobs::notify_and_cleanup; +use crate::jobs::restore_pgrp_pipe; +use crate::jobs::restore_pipeline; +use crate::jobs::run_sigchld_trap; +use crate::jobs::save_pgrp_pipe; +use crate::jobs::save_pipeline; +use crate::jobs::stop_making_children; +use crate::readline::array_dispose; +use crate::sig::initialize_terminating_signals; +use crate::sig::jump_to_top_level; +use crate::sig::set_signal_handler; +use crate::sig::sigint_sighandler; +use crate::sig::termsig_sighandler; +use crate::src_common::*; +use crate::variables::restore_pipestatus_array; +use crate::variables::save_pipestatus_array; +use crate::y_tab::reset_parser; +use crate::y_tab::restore_parser_state; +use crate::y_tab::save_parser_state; + +static mut sigmodes: [libc::c_int; 68] = [0; 68]; +static mut catch_flag: libc::c_int = 0; + +#[no_mangle] +pub fn initialize_traps() { + unsafe { + trap_list[EXIT_TRAP] = 0 as *mut libc::c_void as *mut libc::c_char; + trap_list[DEBUG_TRAP] = 0 as *mut libc::c_void as *mut libc::c_char; + trap_list[ERROR_TRAP] = 0 as *mut libc::c_void as *mut libc::c_char; + trap_list[RETURN_TRAP] = 0 as *mut libc::c_void as *mut libc::c_char; + + sigmodes[EXIT_TRAP] = 0 as libc::c_int; + sigmodes[DEBUG_TRAP] = 0 as libc::c_int; + sigmodes[ERROR_TRAP] = 0 as libc::c_int; + sigmodes[RETURN_TRAP] = 0 as libc::c_int; + + original_signals[EXIT_TRAP] = ::core::mem::transmute::< + Option ()>, + Option, + >(Some(initialize_traps)); + + let mut i: usize = 1; + while i < NSIG { + pending_traps[i] = 0 as libc::c_int; + trap_list[i] = ::core::mem::transmute::(libc::SIG_DFL); + sigmodes[i] = SIG_INHERITED as libc::c_int; + original_signals[i] = ::core::mem::transmute:: ()>, Option>( + Some(initialize_traps), + ); + i += 1; + } + + GETORIGSIG!(libc::SIGCHLD); + sigmodes[libc::SIGCHLD as usize] |= SIG_SPECIAL | SIG_NO_TRAP; + + GETORIGSIG!(libc::SIGINT); + sigmodes[libc::SIGINT as usize] |= SIG_SPECIAL; + + GETORIGSIG!(libc::SIGQUIT); + sigmodes[libc::SIGQUIT as usize] |= SIG_SPECIAL; + + if interactive != 0 { + GETORIGSIG!(libc::SIGTERM); + sigmodes[libc::SIGTERM as usize] |= SIG_SPECIAL; + } + get_original_tty_job_signals(); + } +} + +#[no_mangle] +pub fn signal_name(sig: libc::c_int) -> *mut libc::c_char { + unsafe { + let ret: *mut libc::c_char = if sig >= BASH_NSIG as libc::c_int + || sig < 0 as libc::c_int + || (signal_names[sig as usize]).is_null() + { + dcgettext( + 0 as *const libc::c_char, + b"invalid signal number\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ) + } else { + signal_names[sig as usize] + }; + return ret; + } +} + +#[no_mangle] +pub fn decode_signal(string: *mut libc::c_char, flags: libc::c_int) -> libc::c_int { + unsafe { + let mut sig: intmax_t = 0; + let mut name: *mut libc::c_char; + if legal_number(string, &mut sig) != 0 { + return if sig >= 0 as libc::c_int as intmax_t && sig < NSIG as intmax_t { + sig as libc::c_int + } else { + NO_SIG as libc::c_int + }; + } + + if (libc::strncmp( + string, + b"SIGRTMIN+\0" as *const u8 as *const libc::c_char, + 9, + ) == 0) + || ((flags & DSIG_NOCASE as libc::c_int) != 0 + && libc::strncasecmp( + string, + b"SIGRTMIN+\0" as *const u8 as *const libc::c_char, + 9, + ) == 0) + { + if legal_number(string.offset(9 as libc::c_int as isize), &mut sig) != 0 + && sig >= 0 as libc::c_int as intmax_t + && sig <= (__libc_current_sigrtmax() - __libc_current_sigrtmin()) as intmax_t + { + return (__libc_current_sigrtmin() as intmax_t + sig) as libc::c_int; + } else { + return NO_SIG; + } + } else if (libc::strncmp(string, b"RTMIN+\0" as *const u8 as *const libc::c_char, 6) == 0) + || ((flags & DSIG_NOCASE as libc::c_int) != 0 + && libc::strncasecmp(string, b"RTMIN+\0" as *const u8 as *const libc::c_char, 6) + == 0) + { + if legal_number(string.offset(6 as libc::c_int as isize), &mut sig) != 0 + && sig >= 0 as libc::c_int as intmax_t + && sig <= (__libc_current_sigrtmax() - __libc_current_sigrtmin()) as intmax_t + { + return (__libc_current_sigrtmin() as intmax_t + sig) as libc::c_int; + } else { + return NO_SIG; + } + } + sig = 0 as libc::c_int as intmax_t; + while sig < (BASH_NSIG) as intmax_t { + name = signal_names[sig as usize]; + if !(name.is_null() + || *name.offset(0 as libc::c_int as isize) as libc::c_int == '\0' as i32) + { + if strncmp( + name, + b"SIG\0" as *const u8 as *const libc::c_char, + 3 as libc::c_int as usize, + ) == 0 as libc::c_int + { + name = name.offset(3 as libc::c_int as isize); + if flags & DSIG_NOCASE as libc::c_int != 0 + && strcasecmp(string, name) == 0 as libc::c_int + { + return sig as libc::c_int; + } else if flags & DSIG_NOCASE as libc::c_int == 0 as libc::c_int + && strcmp(string, name) == 0 as libc::c_int + { + return sig as libc::c_int; + } else if flags & DSIG_SIGPREFIX as libc::c_int == 0 as libc::c_int { + sig += 1; + continue; + } + } + + name = signal_names[sig as usize]; + if flags & DSIG_NOCASE as libc::c_int != 0 + && strcasecmp(string, name) == 0 as libc::c_int + { + return sig as libc::c_int; + } else if flags & DSIG_NOCASE as libc::c_int == 0 as libc::c_int + && strcmp(string, name) == 0 as libc::c_int + { + return sig as libc::c_int; + } + } + sig += 1; + } + return NO_SIG; + } +} +#[no_mangle] +pub fn run_pending_traps() { + let mut sig: libc::c_int; + let old_exit_value: libc::c_int; + let mut x: libc::c_int; + let old_running: libc::c_int; + let mut save_subst_varlist: *mut WordList; + let mut save_tempenv: *mut HASH_TABLE; + let mut pstate: sh_parser_state_t = _sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + let ps: *mut ARRAY; + unsafe { + if catch_flag == 0 as libc::c_int { + return; + } + if running_trap > 0 as libc::c_int { + if running_trap == libc::SIGWINCH as libc::c_int + 1 as libc::c_int + && pending_traps[libc::SIGWINCH as usize] != 0 + { + return; + } + if evalnest_max > 0 as libc::c_int && evalnest > evalnest_max { + internal_error( + dcgettext( + 0 as *const libc::c_char, + b"trap handler: maximum trap handler level exceeded (%d)\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + evalnest_max, + ); + evalnest = 0 as libc::c_int; + jump_to_top_level(DISCARD); + } + } + trapped_signal_received = 0 as libc::c_int; + catch_flag = 0 as libc::c_int; + + old_exit_value = last_command_exit_value; + trap_saved_exit_value = last_command_exit_value; + ps = save_pipestatus_array(); + old_running = running_trap; + + //let mut current_block_56: u64; + sig = 1 as libc::c_int; + while sig < NSIG as i32 { + if pending_traps[sig as usize] != 0 { + running_trap = sig + 1 as libc::c_int; + if sig == libc::SIGINT as libc::c_int { + pending_traps[sig as usize] = 0 as libc::c_int; + run_interrupt_trap(0 as libc::c_int); + ::core::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + 0 as libc::c_int, + ); + //current_block_56 = 1345366029464561491; + } else if sig == libc::SIGCHLD as libc::c_int + && trap_list[libc::SIGCHLD as libc::c_int as usize] + != ::core::mem::transmute:: (), *mut libc::c_char>(initialize_traps) + && sigmodes[libc::SIGCHLD as libc::c_int as usize] + & SIG_INPROGRESS as libc::c_int + == 0 as libc::c_int + { + sigmodes[libc::SIGCHLD as libc::c_int as usize] |= + SIG_INPROGRESS as libc::c_int; + evalnest += 1; + x = pending_traps[sig as usize]; + pending_traps[sig as usize] = 0 as libc::c_int; + run_sigchld_trap(x); + running_trap = 0 as libc::c_int; + evalnest -= 1; + sigmodes[libc::SIGCHLD as libc::c_int as usize] &= !(SIG_INPROGRESS); + sig += 1; + /* continue here rather than reset pending_traps[SIGCHLD] below in + case there are recursive calls to run_pending_traps and children + have been reaped while run_sigchld_trap was running. */ + continue; //current_block_56 = 10599921512955367680; + } else if sig == libc::SIGCHLD as libc::c_int + && trap_list[libc::SIGCHLD as libc::c_int as usize] + == ::core::mem::transmute:: (), *mut libc::c_char>(initialize_traps) + && sigmodes[libc::SIGCHLD as usize] & SIG_INPROGRESS as libc::c_int + != 0 as libc::c_int + { + running_trap = 0 as libc::c_int; + sig += 1; + continue; // current_block_56 = 10599921512955367680; + } else if sig == libc::SIGCHLD as libc::c_int + && sigmodes[libc::SIGCHLD as usize] & SIG_INPROGRESS as libc::c_int != 0 + //else if (sig == libc::SIGCHLD && (sigmodes[libc::SIGCHLD] & SIG_INPROGRESS)) + { + running_trap = 0 as libc::c_int; + sig += 1; + continue; //current_block_56 = 10599921512955367680; + } else { + if (trap_list[sig as usize]).is_null() + || trap_list[sig as usize] + == ::core::mem::transmute::<__sighandler_t, *mut libc::c_char>( + ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ), + ) + || trap_list[sig as usize] + == ::core::mem::transmute:: (), *mut libc::c_char>( + initialize_traps, + ) + { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"run_pending_traps: bad value in trap_list[%d]: %p\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + sig, + trap_list[sig as usize], + ); + if (trap_list[sig as usize]).is_null() { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + sig, + signal_name(sig), + ); + kill(getpid(), sig); + } + } else { + save_parser_state(&mut pstate); + save_subst_varlist = subst_assign_varlist; + subst_assign_varlist = 0 as *mut WordList; + save_tempenv = temporary_env; + temporary_env = 0 as *mut HASH_TABLE; + save_pipeline(1 as libc::c_int); + pending_traps[sig as usize] = 0 as libc::c_int; + evalnest += 1; + evalstring( + savestring!(trap_list[sig as usize]), + b"trap\0" as *const u8 as *const libc::c_char, + 0x1 as libc::c_int | 0x4 as libc::c_int | 0x10 as libc::c_int, + ); + evalnest -= 1; + restore_pipeline(1 as libc::c_int); + subst_assign_varlist = save_subst_varlist; + restore_parser_state(&mut pstate); + temporary_env = save_tempenv; + } + //current_block_56 = 1345366029464561491; + } + + pending_traps[sig as usize] = 0 as libc::c_int; + running_trap = old_running; + } + sig += 1; + } + restore_pipestatus_array(ps); + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + old_exit_value, + ); + } +} + +#[no_mangle] +pub fn set_trap_state(sig: libc::c_int) { + unsafe { + catch_flag = 1 as libc::c_int; + pending_traps[sig as usize] += 1; + trapped_signal_received = sig; + } +} + +#[no_mangle] +pub fn trap_handler(sig: libc::c_int) { + unsafe { + let oerrno: libc::c_int; + if sigmodes[sig as usize] & SIG_TRAPPED == 0 as libc::c_int { + return; + } + if sig >= NSIG as libc::c_int + || (trap_list[sig as usize]) + == ::core::mem::transmute::(libc::SIG_DFL) + || trap_list[sig as usize] + == ::core::mem::transmute::(libc::SIG_IGN) + { + programming_error( + dcgettext( + 0 as *const libc::c_char, + b"trap_handler: bad signal %d\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + sig, + ); + } else { + oerrno = *__errno_location(); + set_trap_state(sig); + if this_shell_builtin.is_some() && this_shell_builtin == Some(wait_builtin) { + wait_signal_received = sig; + if waiting_for_child != 0 && wait_intr_flag != 0 { + siglongjmp(wait_intr_buf.as_mut_ptr(), 1 as libc::c_int); + } + } + if RL_ISSTATE!(RL_STATE_SIGHANDLER) != 0 { + bashline_set_event_hook(); + } + *__errno_location() = oerrno; + }; + } +} + +#[no_mangle] +pub fn next_pending_trap(start: libc::c_int) -> libc::c_int { + let mut i: libc::c_int = start; + unsafe { + while i < NSIG as libc::c_int { + if pending_traps[i as usize] != 0 { + return i; + } + i += 1; + } + } + return -(1 as libc::c_int); +} + +#[no_mangle] +pub fn first_pending_trap() -> libc::c_int { + return next_pending_trap(1 as libc::c_int); +} + +#[no_mangle] +pub fn any_signals_trapped() -> libc::c_int { + let mut i: libc::c_int = 1 as libc::c_int; + unsafe { + while i < NSIG as libc::c_int + 1 as libc::c_int { + if sigmodes[i as usize] & SIG_TRAPPED != 0 { + return i; + } + i += 1; + } + } + return -1; +} + +#[no_mangle] +pub fn clear_pending_traps() { + let mut i: libc::c_int = 1 as libc::c_int; + unsafe { + while i < NSIG as libc::c_int + 1 as libc::c_int { + pending_traps[i as usize] = 0 as libc::c_int; + i += 1; + } + } +} + +#[no_mangle] +pub fn check_signals() { + unsafe { + CHECK_ALRM!(); + QUIT!(); + } +} + +#[no_mangle] +pub fn check_signals_and_traps() { + check_signals(); + run_pending_traps(); +} + +#[no_mangle] +pub fn maybe_set_sigchld_trap(command_string: *mut libc::c_char) { + unsafe { + if sigmodes[libc::SIGCHLD as usize] & SIG_TRAPPED == 0 as libc::c_int + && trap_list[libc::SIGCHLD as libc::c_int as usize] + == ::core::mem::transmute:: (), *mut libc::c_char>(initialize_traps) + { + set_signal(libc::SIGCHLD as libc::c_int, command_string); + } + } +} + +#[no_mangle] +pub fn set_impossible_sigchld_trap() { + restore_default_signal(libc::SIGCHLD as libc::c_int); + unsafe { + change_signal( + libc::SIGCHLD as libc::c_int, + ::core::mem::transmute:: (), *mut libc::c_char>(initialize_traps), + ); + sigmodes[libc::SIGCHLD as libc::c_int as usize] &= !(SIG_TRAPPED); + } +} + +#[no_mangle] +pub fn queue_sigchld_trap(nchild: libc::c_int) { + if nchild > 0 as libc::c_int { + unsafe { + catch_flag = 1 as libc::c_int; + pending_traps[libc::SIGCHLD as libc::c_int as usize] += nchild; + trapped_signal_received = libc::SIGCHLD as libc::c_int; + } + } +} + +#[inline] +fn trap_if_untrapped(sig: libc::c_int, command: *mut libc::c_char) { + unsafe { + if sigmodes[sig as usize] & SIG_TRAPPED == 0 as libc::c_int { + set_signal(sig, command); + } + } +} + +#[no_mangle] +pub fn set_debug_trap(command: *mut libc::c_char) { + set_signal(DEBUG_TRAP as libc::c_int, command); +} +#[no_mangle] +pub fn maybe_set_debug_trap(command: *mut libc::c_char) { + unsafe { + trap_if_untrapped(DEBUG_TRAP as libc::c_int, command); + } +} +#[no_mangle] +pub fn set_error_trap(command: *mut libc::c_char) { + set_signal(ERROR_TRAP as libc::c_int, command); +} +#[no_mangle] +pub fn maybe_set_error_trap(command: *mut libc::c_char) { + trap_if_untrapped(ERROR_TRAP as libc::c_int, command); +} +#[no_mangle] +pub fn set_return_trap(command: *mut libc::c_char) { + set_signal(RETURN_TRAP as libc::c_int, command); +} +#[no_mangle] +pub fn maybe_set_return_trap(command: *mut libc::c_char) { + trap_if_untrapped(RETURN_TRAP as libc::c_int, command); +} +#[no_mangle] +pub fn set_sigint_handler() -> Option { + unsafe { + if sigmodes[libc::SIGINT as usize] & SIG_HARD_IGNORE as libc::c_int != 0 { + return Some(::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + )); + } else if sigmodes[libc::SIGINT as usize] & SIG_IGNORED != 0 { + return set_signal_handler( + libc::SIGINT as libc::c_int, + Some(::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + )), + ); + } else if sigmodes[libc::SIGINT as libc::c_int as usize] & libc::SIG_IGN as libc::c_int != 0 + { + return set_signal_handler(libc::SIGINT as libc::c_int, Some(trap_handler)); + } else if interactive != 0 { + return set_signal_handler(libc::SIGINT as libc::c_int, Some(sigint_sighandler)); + } else { + return set_signal_handler(libc::SIGINT as libc::c_int, Some(termsig_sighandler)); + }; + } +} + +#[no_mangle] +pub fn trap_to_sighandler(sig: libc::c_int) -> Option { + unsafe { + if sigmodes[sig as usize] & (SIG_IGNORED | SIG_HARD_IGNORE as libc::c_int) != 0 { + return Some(::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + )); + } else if sigmodes[sig as usize] & SIG_TRAPPED != 0 { + return Some(trap_handler); + } else { + return None; + }; + } +} + +#[no_mangle] +pub fn set_signal(sig: libc::c_int, string: *mut libc::c_char) { + let mut set: sigset_t = sigset_t { __val: [0; 16] }; + let mut oset: sigset_t = sigset_t { __val: [0; 16] }; + unsafe { + //#define SPECIAL_TRAP(s) ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP || (s) == RETURN_TRAP) + if SPECIAL_TRAP!(sig) { + change_signal(sig, savestring!(string)); + if sig == EXIT_TRAP as libc::c_int && interactive == 0 as libc::c_int { + initialize_terminating_signals(); + } + return; + } + if sigmodes[sig as usize] & SIG_HARD_IGNORE as libc::c_int != 0 { + return; + } + if sigmodes[sig as usize] & SIG_TRAPPED == 0 as libc::c_int { + if original_signals[sig as usize] + == ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )) + { + original_signals[sig as usize] = set_signal_handler( + sig, + ::core::mem::transmute::(libc::SIG_DFL), + ); + set_signal_handler(sig, original_signals[sig as usize]); + if original_signals[sig as usize] + == ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ) + { + sigmodes[sig as usize] |= SIG_HARD_IGNORE as libc::c_int; + } + } + if original_signals[sig as usize] + == ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ) + { + return; + } + } + if sigmodes[sig as usize] & SIG_NO_TRAP as libc::c_int == 0 as libc::c_int { + sigemptyset(&mut set); + sigaddset(&mut set, sig); + sigemptyset(&mut oset); + sigprocmask(0 as libc::c_int, &mut set, &mut oset); + change_signal(sig, savestring!(string)); + set_signal_handler( + sig, + ::core::mem::transmute:: ()>, Option>(Some( + ::core::mem::transmute:: (), fn() -> ()>(trap_handler), + )), + ); + sigprocmask( + 2 as libc::c_int, + &mut oset, + 0 as *mut libc::c_void as *mut sigset_t, + ); + } else { + change_signal(sig, savestring!(string)); + }; + } +} +fn free_trap_command(sig: libc::c_int) { + unsafe { + if sigmodes[sig as usize] & SIG_TRAPPED != 0 + && !(trap_list[sig as usize]).is_null() + && trap_list[sig as usize] + != ::core::mem::transmute::<__sighandler_t, *mut libc::c_char>( + ::core::mem::transmute::( + libc::SIG_DFL as libc::c_int as libc::intptr_t, + ), + ) + && !(trap_list[sig as usize]).is_null() + && trap_list[sig as usize] + != ::core::mem::transmute::, *mut libc::c_char>( + ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )), + ) + { + libc::free(trap_list[sig as usize] as *mut libc::c_void); + } + } +} +fn change_signal(sig: libc::c_int, value: *mut libc::c_char) { + unsafe { + if sigmodes[sig as usize] & SIG_INPROGRESS as libc::c_int == 0 as libc::c_int { + free_trap_command(sig); + } + trap_list[sig as usize] = value; + sigmodes[sig as usize] |= SIG_TRAPPED; + if value + == ::core::mem::transmute::<__sighandler_t, *mut libc::c_char>( + ::core::mem::transmute::(libc::SIG_IGN), + ) + { + sigmodes[sig as usize] |= SIG_IGNORED; + } else { + sigmodes[sig as usize] &= !(SIG_IGNORED); + } + if sigmodes[sig as usize] & SIG_INPROGRESS as libc::c_int != 0 { + sigmodes[sig as usize] |= SIG_CHANGED as libc::c_int; + } + } +} +#[no_mangle] +pub fn get_original_signal(sig: libc::c_int) { + unsafe { + if sig > 0 as libc::c_int + && sig < 64 as libc::c_int + 1 as libc::c_int + && original_signals[sig as usize] + == ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )) + { + original_signals[sig as usize] = set_signal_handler(sig, None); + set_signal_handler(sig, original_signals[sig as usize]); + if original_signals[sig as usize] + == ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigmodes[sig as usize] |= 0x2 as libc::c_int; + } + } + } +} +#[no_mangle] +pub fn get_all_original_signals() { + let mut i: libc::c_int; + i = 1 as libc::c_int; + unsafe { + while i < 64 as libc::c_int + 1 as libc::c_int { + if i != 0 + && i < 64 as libc::c_int + 1 as libc::c_int + && original_signals[i as usize] + == ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )) + { + original_signals[i as usize] = set_signal_handler(i, None); + set_signal_handler(i, original_signals[i as usize]); + if original_signals[i as usize] + == ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigmodes[i as usize] |= 0x2 as libc::c_int; + } + } + i += 1; + } + } +} +#[no_mangle] +pub fn set_original_signal(sig: libc::c_int, handler: Option) { + unsafe { + if sig > 0 as libc::c_int + && sig < 64 as libc::c_int + 1 as libc::c_int + && original_signals[sig as usize] + == ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )) + { + original_signals[sig as usize] = handler; + if original_signals[sig as usize] + == ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigmodes[sig as usize] |= 0x2 as libc::c_int; + } + } + } +} +#[no_mangle] +pub fn restore_default_signal(sig: libc::c_int) { + unsafe { + if sig == 0 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + 2 as libc::c_int + { + if sig != 64 as libc::c_int + 1 as libc::c_int + && sig != 64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int + && sig != 64 as libc::c_int + 1 as libc::c_int + 2 as libc::c_int + || sigmodes[sig as usize] & 0x10 as libc::c_int == 0 as libc::c_int + { + free_trap_command(sig); + } + trap_list[sig as usize] = 0 as *mut libc::c_void as *mut libc::c_char; + sigmodes[sig as usize] &= !(0x1 as libc::c_int); + if sigmodes[sig as usize] & 0x10 as libc::c_int != 0 { + sigmodes[sig as usize] |= 0x20 as libc::c_int; + } + return; + } + if sig != 0 + && sig < 64 as libc::c_int + 1 as libc::c_int + && original_signals[sig as usize] + == ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )) + { + original_signals[sig as usize] = set_signal_handler(sig, None); + set_signal_handler(sig, original_signals[sig as usize]); + if original_signals[sig as usize] + == ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigmodes[sig as usize] |= 0x2 as libc::c_int; + } + } + if sigmodes[sig as usize] & 0x2 as libc::c_int != 0 { + return; + } + if sigmodes[sig as usize] & 0x1 as libc::c_int == 0 as libc::c_int + && (sig != libc::SIGCHLD as libc::c_int + || sigmodes[sig as usize] & 0x10 as libc::c_int == 0 as libc::c_int + || trap_list[sig as usize] + != ::core::mem::transmute::, *mut libc::c_char>( + ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )), + )) + { + return; + } + if sigmodes[sig as usize] & 0x8 as libc::c_int == 0 as libc::c_int { + set_signal_handler(sig, original_signals[sig as usize]); + } + change_signal( + sig, + ::core::mem::transmute::<__sighandler_t, *mut libc::c_char>(None), + ); + sigmodes[sig as usize] &= !(0x1 as libc::c_int); + } +} +#[no_mangle] +pub fn ignore_signal(sig: libc::c_int) { + unsafe { + if (sig == 0 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + 2 as libc::c_int) + && sigmodes[sig as usize] & 0x40 as libc::c_int == 0 as libc::c_int + { + change_signal( + sig, + ::core::mem::transmute::<__sighandler_t, *mut libc::c_char>( + ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ), + ), + ); + return; + } + if sig != 0 + && sig < 64 as libc::c_int + 1 as libc::c_int + && original_signals[sig as usize] + == ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps, + )) + { + original_signals[sig as usize] = set_signal_handler(sig, None); + set_signal_handler(sig, original_signals[sig as usize]); + if original_signals[sig as usize] + == ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ) + { + sigmodes[sig as usize] |= 0x2 as libc::c_int; + } + } + if sigmodes[sig as usize] & 0x2 as libc::c_int != 0 { + return; + } + if sigmodes[sig as usize] & 0x40 as libc::c_int != 0 { + return; + } + if sigmodes[sig as usize] & 0x8 as libc::c_int == 0 as libc::c_int { + set_signal_handler( + sig, + ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ), + ); + } + change_signal( + sig, + ::core::mem::transmute::( + 1 as libc::c_int as libc::intptr_t, + ), + ); + } +} +#[no_mangle] +pub fn run_exit_trap() -> libc::c_int { + let trap_command: *mut libc::c_char; + let code: libc::c_int; + let mut function_code: libc::c_int; + let mut retval: libc::c_int; + let ps: *mut ARRAY; + unsafe { + trap_saved_exit_value = last_command_exit_value; + ps = save_pipestatus_array(); + function_code = 0 as libc::c_int; + if sigmodes[EXIT_TRAP] & SIG_TRAPPED != 0 + && sigmodes[EXIT_TRAP] & (SIG_IGNORED | SIG_INPROGRESS as libc::c_int) + == 0 as libc::c_int + { + trap_command = savestring!(trap_list[0 as libc::c_int as usize]); + + sigmodes[EXIT_TRAP] &= !(SIG_TRAPPED); + sigmodes[EXIT_TRAP] |= SIG_INPROGRESS; + retval = trap_saved_exit_value; + running_trap = 1 as libc::c_int; + code = __sigsetjmp(top_level.as_mut_ptr(), 0 as libc::c_int); + if return_catch_flag != 0 { + function_code = __sigsetjmp(return_catch.as_mut_ptr(), 0 as libc::c_int); + } + if code == 0 as libc::c_int && function_code == 0 as libc::c_int { + reset_parser(); + parse_and_execute( + trap_command, + b"exit trap\0" as *const u8 as *const libc::c_char, + 0x1 as libc::c_int | 0x4 as libc::c_int | 0x10 as libc::c_int, + ); + } else if code == ERREXIT as libc::c_int { + retval = last_command_exit_value; + } else if code == EXITPROG as libc::c_int { + retval = last_command_exit_value; + } else if function_code != 0 as libc::c_int { + retval = return_catch_value; + } else { + retval = trap_saved_exit_value; + } + running_trap = 0 as libc::c_int; + array_dispose(ps); + return retval; + } + restore_pipestatus_array(ps); + return trap_saved_exit_value; + } +} +#[no_mangle] +pub fn run_trap_cleanup(sig: libc::c_int) { + unsafe { + sigmodes[sig as usize] &= !(SIG_INPROGRESS | SIG_CHANGED); + } +} +fn _run_trap_internal(sig: libc::c_int, tag: *mut libc::c_char) -> libc::c_int { + unsafe { + let trap_command: *mut libc::c_char; + let old_trap: *mut libc::c_char; + let mut trap_exit_value: libc::c_int; + let mut save_return_catch_flag: libc::c_int = 0; + let mut function_code: libc::c_int = 0; + let old_modes: libc::c_int; + let old_running: libc::c_int; + let old_int: libc::c_int; + let mut flags: libc::c_int; + let mut save_return_catch: sigjmp_buf = [__jmp_buf_tag { + __jmpbuf: [0; 8], + __mask_was_saved: 0, + __saved_mask: sigset_t { __val: [0; 16] }, + }; 1]; + let save_subst_varlist: *mut WordList; + let save_tempenv: *mut HASH_TABLE; + let mut pstate: sh_parser_state_t = _sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + let ps: *mut ARRAY; + //old_running = -(1 as libc::c_int); + //old_modes = old_running; + ::core::ptr::write_volatile(&mut function_code as *mut libc::c_int, 0 as libc::c_int); + trap_exit_value = + ::core::ptr::read_volatile::(&function_code as *const libc::c_int); + trap_saved_exit_value = last_command_exit_value; + if sigmodes[sig as usize] & SIG_TRAPPED != 0 + && sigmodes[sig as usize] & SIG_IGNORED == 0 as libc::c_int + && trap_list[sig as usize] + != ::core::mem::transmute:: (), *mut libc::c_char>(initialize_traps) + && ((sig == 0 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int + || sig == 64 as libc::c_int + 1 as libc::c_int + 2 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + || sigmodes[sig as usize] & 0x10 as libc::c_int == 0 as libc::c_int) + { + old_trap = trap_list[sig as usize]; + old_modes = sigmodes[sig as usize]; + old_running = running_trap; + sigmodes[sig as usize] |= SIG_INPROGRESS; + sigmodes[sig as usize] &= !(SIG_CHANGED as libc::c_int); + trap_command = savestring!(old_trap); + running_trap = sig + 1 as libc::c_int; + old_int = interrupt_state; + ::core::ptr::write_volatile( + &mut interrupt_state as *mut sig_atomic_t, + 0 as libc::c_int, + ); + ps = save_pipestatus_array(); + save_parser_state(&mut pstate); + save_subst_varlist = subst_assign_varlist; + subst_assign_varlist = 0 as *mut WordList; + save_tempenv = temporary_env; + temporary_env = 0 as *mut HASH_TABLE; + if sig != DEBUG_TRAP as libc::c_int { + save_pipeline(1 as libc::c_int); + } + ::core::ptr::write_volatile( + &mut save_return_catch_flag as *mut libc::c_int, + return_catch_flag, + ); + if return_catch_flag != 0 { + xbcopy( + return_catch.as_mut_ptr() as *mut libc::c_char, + save_return_catch.as_mut_ptr() as *mut libc::c_char, + ::core::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + ::core::ptr::write_volatile( + &mut function_code as *mut libc::c_int, + __sigsetjmp(return_catch.as_mut_ptr(), 0 as libc::c_int), + ); + } + flags = 0x1 as libc::c_int | 0x4 as libc::c_int; + if sig != 64 as libc::c_int + 1 as libc::c_int + && sig != 64 as libc::c_int + 1 as libc::c_int + 2 as libc::c_int + && sig != 64 as libc::c_int + 1 as libc::c_int + 1 as libc::c_int + { + flags |= 0x10 as libc::c_int; + } + evalnest += 1; + if function_code == 0 as libc::c_int { + parse_and_execute(trap_command, tag, flags); + trap_exit_value = last_command_exit_value; + } else { + trap_exit_value = return_catch_value; + } + evalnest -= 1; + if sig != 64 as libc::c_int + 1 as libc::c_int { + restore_pipeline(1 as libc::c_int); + } + subst_assign_varlist = save_subst_varlist; + restore_parser_state(&mut pstate); + restore_pipestatus_array(ps); + temporary_env = save_tempenv; + if old_modes & 0x10 as libc::c_int == 0 as libc::c_int { + sigmodes[sig as usize] &= !(0x10 as libc::c_int); + } + running_trap = old_running; + ::core::ptr::write_volatile(&mut interrupt_state as *mut sig_atomic_t, old_int); + if sigmodes[sig as usize] & 0x20 as libc::c_int != 0 { + libc::free(old_trap as *mut libc::c_void); + sigmodes[sig as usize] &= !(0x20 as libc::c_int); + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + } + if save_return_catch_flag != 0 { + return_catch_flag = save_return_catch_flag; + return_catch_value = trap_exit_value; + xbcopy( + save_return_catch.as_mut_ptr() as *mut libc::c_char, + return_catch.as_mut_ptr() as *mut libc::c_char, + ::core::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + if function_code != 0 { + siglongjmp(return_catch.as_mut_ptr(), 1 as libc::c_int); + } + } + } + return trap_exit_value; + } +} +#[no_mangle] +pub fn run_debug_trap() -> libc::c_int { + unsafe { + let mut trap_exit_value: libc::c_int; + let old_verbose: libc::c_int; + let save_pgrp: pid_t; + let mut save_pipe: [libc::c_int; 2] = [0; 2]; + trap_exit_value = 0 as libc::c_int; + if sigmodes[(DEBUG_TRAP as libc::c_int + 1 as libc::c_int) as usize] + & SIG_TRAPPED as libc::c_int + != 0 + && sigmodes[(DEBUG_TRAP as libc::c_int + 1 as libc::c_int) as usize] & SIG_IGNORED + == 0 as libc::c_int + && sigmodes[(DEBUG_TRAP as libc::c_int + 1 as libc::c_int) as usize] + & SIG_INPROGRESS as libc::c_int + == 0 as libc::c_int + { + save_pgrp = pipeline_pgrp; + pipeline_pgrp = 0 as libc::c_int; + save_pipeline(1 as libc::c_int); + save_pgrp_pipe(save_pipe.as_mut_ptr(), 1 as libc::c_int); + stop_making_children(); + old_verbose = echo_input_at_read; + echo_input_at_read = if suppress_debug_trap_verbose != 0 { + 0 as libc::c_int + } else { + echo_input_at_read + }; + trap_exit_value = _run_trap_internal( + DEBUG_TRAP as libc::c_int + 1 as libc::c_int, + b"debug trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + echo_input_at_read = old_verbose; + pipeline_pgrp = save_pgrp; + restore_pipeline(1 as libc::c_int); + close_pgrp_pipe(); + restore_pgrp_pipe(save_pipe.as_mut_ptr()); + if pipeline_pgrp > 0 as libc::c_int + && subshell_environment + & (SUBSHELL_ASYNC as libc::c_int | SUBSHELL_PIPE as libc::c_int) + == 0 as libc::c_int + { + give_terminal_to(pipeline_pgrp, 1 as libc::c_int); + } + notify_and_cleanup(); + if debugging_mode != 0 && trap_exit_value == 2 as libc::c_int && return_catch_flag != 0 + { + return_catch_value = trap_exit_value; + siglongjmp(return_catch.as_mut_ptr(), 1 as libc::c_int); + } + } + return trap_exit_value; + } +} +#[no_mangle] +pub fn run_error_trap() { + unsafe { + if sigmodes[(ERROR_TRAP) as usize] & SIG_TRAPPED != 0 + && sigmodes[(ERROR_TRAP) as usize] & SIG_IGNORED == 0 as libc::c_int + && sigmodes[(ERROR_TRAP) as usize] & SIG_INPROGRESS as libc::c_int == 0 as libc::c_int + { + _run_trap_internal( + ERROR_TRAP as libc::c_int + 1 as libc::c_int + 1 as libc::c_int, + b"error trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + } +} +#[no_mangle] +pub fn run_return_trap() { + let old_exit_value: libc::c_int; + unsafe { + if sigmodes[(RETURN_TRAP as libc::c_int) as usize] & SIG_TRAPPED != 0 + && sigmodes[(RETURN_TRAP as libc::c_int) as usize] & SIG_IGNORED == 0 as libc::c_int + && sigmodes[(RETURN_TRAP as libc::c_int) as usize] & SIG_INPROGRESS as libc::c_int + == 0 as libc::c_int + { + old_exit_value = last_command_exit_value; + _run_trap_internal( + RETURN_TRAP as libc::c_int + 1 as libc::c_int + 2 as libc::c_int, + b"return trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + old_exit_value, + ); + } + } +} +#[no_mangle] +pub fn run_interrupt_trap(will_throw: libc::c_int) { + unsafe { + if will_throw != 0 && running_trap > 0 as libc::c_int { + run_trap_cleanup(running_trap - 1 as libc::c_int); + } + pending_traps[libc::SIGINT as usize] = 0 as libc::c_int; + catch_flag = 0 as libc::c_int; + _run_trap_internal( + libc::SIGINT as libc::c_int, + b"interrupt trap\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } +} +#[no_mangle] +pub fn free_trap_strings() { + unsafe { + let mut i: libc::c_int; + i = 0 as libc::c_int; + while i < NSIG as libc::c_int { + if trap_list[i as usize] + != ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ) + { + free_trap_string(i); + } + i += 1; + } + i = NSIG as libc::c_int; + while i < BASH_NSIG as libc::c_int { + if sigmodes[i as usize] & SIG_TRAPPED == 0 as libc::c_int { + free_trap_string(i); + trap_list[i as usize] = 0 as *mut libc::c_void as *mut libc::c_char; + } + i += 1; + } + } +} + +fn free_trap_string(sig: libc::c_int) { + change_signal( + sig, + libc::SIG_DFL as *const libc::c_char as *mut libc::c_char, + ); + + unsafe { + sigmodes[sig as usize] &= !(SIG_TRAPPED); + } +} + +fn reset_signal(sig: libc::c_int) { + unsafe { + set_signal_handler(sig, original_signals[sig as usize]); + sigmodes[sig as usize] &= !(SIG_TRAPPED); + } +} + +fn restore_signal(sig: libc::c_int) { + unsafe { + set_signal_handler(sig, original_signals[sig as usize]); + change_signal( + sig, + libc::SIG_DFL as *const libc::c_char as *mut libc::c_char, //::core::mem::transmute::(libc::SIG_DFL as libc::intptr_t), + ); + sigmodes[sig as usize] &= !(SIG_TRAPPED); + } +} + +fn reset_or_restore_signal_handlers(reset: Option) { + unsafe { + let mut i: libc::c_int; + if sigmodes[EXIT_TRAP as libc::c_int as usize] & SIG_TRAPPED != 0 { + sigmodes[EXIT_TRAP as libc::c_int as usize] &= !(SIG_TRAPPED); + if reset + != ::core::mem::transmute:: (), Option>( + reset_signal, + ) + { + free_trap_command(EXIT_TRAP as libc::c_int); + trap_list[EXIT_TRAP as libc::c_int as usize] = + 0 as *mut libc::c_void as *mut libc::c_char; + } + } + i = 1 as libc::c_int; + while i < NSIG as libc::c_int { + if sigmodes[i as usize] & SIG_TRAPPED != 0 { + if trap_list[i as usize] + == ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ) + { + set_signal_handler( + i, + ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ), + ); + } else { + (Some(reset.expect("non-null function pointer"))) + .expect("non-null function pointer")(i); + } + } else if sigmodes[i as usize] & SIG_SPECIAL as libc::c_int != 0 { + (Some(reset.expect("non-null function pointer"))) + .expect("non-null function pointer")(i); + } + pending_traps[i as usize] = 0 as libc::c_int; + i += 1; + } + if function_trace_mode == 0 as libc::c_int { + sigmodes[(DEBUG_TRAP as libc::c_int) as usize] &= !(SIG_TRAPPED); + sigmodes[(RETURN_TRAP as libc::c_int) as usize] &= !(SIG_TRAPPED); + } + if error_trace_mode == 0 as libc::c_int { + sigmodes[(ERROR_TRAP as libc::c_int) as usize] &= !(SIG_TRAPPED); + } + } +} + +#[no_mangle] +pub fn reset_signal_handlers() { + unsafe { + reset_or_restore_signal_handlers(::core::mem::transmute::< + fn(libc::c_int) -> (), + Option, + >(reset_signal)); + } +} + +#[no_mangle] +pub fn restore_original_signals() { + unsafe { + reset_or_restore_signal_handlers(::core::mem::transmute::< + fn(libc::c_int) -> (), + Option, + >(restore_signal)); + } +} + +#[no_mangle] +pub fn maybe_call_trap_handler(sig: libc::c_int) -> libc::c_int { + unsafe { + if sigmodes[sig as usize] & SIG_TRAPPED != 0 + && sigmodes[sig as usize] & SIG_IGNORED == 0 as libc::c_int + { + match sig as usize { + 2 => { + run_interrupt_trap(0 as libc::c_int); + } + EXIT_TRAP => { + run_exit_trap(); + } + DEBUG_TRAP => { + run_debug_trap(); + } + ERROR_TRAP => { + run_error_trap(); + } + _ => { + trap_handler(sig); + } + } + return 1 as libc::c_int; + } else { + return 0 as libc::c_int; + }; + } +} + +#[no_mangle] +pub fn signal_is_trapped(sig: libc::c_int) -> libc::c_int { + unsafe { + return sigmodes[sig as usize] & SIG_TRAPPED; + } +} +#[no_mangle] +pub fn signal_is_pending(sig: libc::c_int) -> libc::c_int { + unsafe { + return pending_traps[sig as usize]; + } +} + +#[no_mangle] +pub fn signal_is_special(sig: libc::c_int) -> libc::c_int { + unsafe { + return sigmodes[sig as usize] & SIG_SPECIAL as libc::c_int; + } +} + +#[no_mangle] +pub fn signal_is_ignored(sig: libc::c_int) -> libc::c_int { + unsafe { + return sigmodes[sig as usize] & SIG_HARD_IGNORE as libc::c_int; + } +} + +#[no_mangle] +pub fn signal_is_hard_ignored(sig: libc::c_int) -> libc::c_int { + unsafe { + return sigmodes[sig as usize] & SIG_HARD_IGNORE as libc::c_int; + } +} + +#[no_mangle] +pub fn set_signal_hard_ignored(sig: libc::c_int) { + unsafe { + sigmodes[sig as usize] |= SIG_HARD_IGNORE as libc::c_int; + original_signals[sig as usize] = ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ); + } +} + +#[no_mangle] +pub fn set_signal_ignored(sig: libc::c_int) { + unsafe { + original_signals[sig as usize] = ::core::mem::transmute::( + libc::SIG_IGN as libc::intptr_t, + ); + } +} + +#[no_mangle] +pub fn signal_in_progress(sig: libc::c_int) -> libc::c_int { + unsafe { + return sigmodes[sig as usize] & SIG_INPROGRESS as libc::c_int; + } +} diff --git a/utshell-0.5.0/src/unwind_prot.rs b/utshell-0.5.0/src/unwind_prot.rs new file mode 100644 index 00000000..d7ad1bcb --- /dev/null +++ b/utshell-0.5.0/src/unwind_prot.rs @@ -0,0 +1,813 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +use std::convert::TryInto; + +#[no_mangle] +pub fn uwp_init() { + unsafe { + uwcache.data = libc::malloc( + (128 as libc::c_int as libc::c_ulong) + .wrapping_mul(::std::mem::size_of::<*mut UNWIND_ELT>() as libc::c_ulong) + .try_into() + .unwrap(), + ); + uwcache.cs = 128 as libc::c_int; + uwcache.nc = 0 as libc::c_int; + } +} +fn without_interrupts( + mut function: Option, + mut arg1: *mut libc::c_char, + mut arg2: *mut libc::c_char, +) { + unsafe { + ::std::mem::transmute::<_, fn(_, _)>( + (Some(function.expect("non-null function pointer"))) + .expect("non-null function pointer"), + )(arg1, arg2); + } //unsafe +} +#[no_mangle] +pub fn begin_unwind_frame(mut tag: *mut libc::c_char) { + unsafe { + add_unwind_protect( + ::std::mem::transmute::<*mut libc::c_void, Option>(0 as *mut libc::c_void), + tag, + ); + } //unsafe +} +#[no_mangle] +pub fn discard_unwind_frame(mut tag: *mut libc::c_char) { + unsafe { + if !unwind_protect_list.is_null() { + without_interrupts( + ::std::mem::transmute::< + Option ()>, + Option, + >(Some(unwind_frame_discard_internal)), + tag, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + } //unsafe +} +#[no_mangle] +pub fn run_unwind_frame(mut tag: *mut libc::c_char) { + unsafe { + if !unwind_protect_list.is_null() { + without_interrupts( + ::std::mem::transmute::< + Option ()>, + Option, + >(Some(unwind_frame_run_internal)), + tag, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + } //unsafe +} +#[no_mangle] +pub fn add_unwind_protect(mut cleanup: Option, mut arg: *mut libc::c_char) { + unsafe { + without_interrupts( + ::std::mem::transmute::< + Option, *mut libc::c_char) -> ()>, + Option, + >(Some(add_unwind_protect_internal)), + ::std::mem::transmute::, *mut libc::c_char>(cleanup), + arg, + ); + } //unsafe +} +#[no_mangle] +pub fn remove_unwind_protect() { + unsafe { + if !unwind_protect_list.is_null() { + without_interrupts( + ::std::mem::transmute::< + Option ()>, + Option, + >(Some(remove_unwind_protect_internal)), + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + } //unsafe +} +#[no_mangle] +pub fn run_unwind_protects() { + unsafe { + if !unwind_protect_list.is_null() { + without_interrupts( + ::std::mem::transmute::< + Option ()>, + Option, + >(Some(run_unwind_protects_internal)), + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + } //unsafe +} +#[no_mangle] +pub fn clear_unwind_protect_list(mut flags: libc::c_int) { + unsafe { + let mut flag: *mut libc::c_char = 0 as *mut libc::c_char; + if !unwind_protect_list.is_null() { + flag = (if flags != 0 { + b"\0" as *const u8 as *const libc::c_char + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }) as *mut libc::c_char; + without_interrupts( + ::std::mem::transmute::< + Option ()>, + Option, + >(Some(clear_unwind_protects_internal)), + flag, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + } //unsafe +} +#[no_mangle] +pub fn have_unwind_protects() -> libc::c_int { + unsafe { + return (unwind_protect_list != 0 as *mut UNWIND_ELT) as libc::c_int; + } +} +#[no_mangle] +pub fn unwind_protect_tag_on_stack(mut tag: *const libc::c_char) -> libc::c_int { + unsafe { + let mut elt: *mut UNWIND_ELT = 0 as *mut UNWIND_ELT; + elt = unwind_protect_list; + while !elt.is_null() { + if ((*elt).head.cleanup).is_none() + && (*((*elt).arg.v).offset(0 as libc::c_int as isize) as libc::c_int + == *tag.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp((*elt).arg.v, tag) == 0 as libc::c_int) + { + return 1 as libc::c_int; + } + elt = (*elt).head.next; + } + return 0 as libc::c_int; + } //unsafe +} +fn add_unwind_protect_internal( + //need + mut cleanup: Option, + mut arg: *mut libc::c_char, +) { + unsafe { + let mut elt: *mut UNWIND_ELT = 0 as *mut UNWIND_ELT; + if uwcache.nc > 0 as libc::c_int { + uwcache.nc -= 1; + elt = *(uwcache.data as *mut *mut UNWIND_ELT).offset(uwcache.nc as isize); + } else { + elt = libc::malloc( + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ) as *mut UNWIND_ELT; + } + let ref mut fresh0 = (*elt).head.next; + *fresh0 = unwind_protect_list; + let ref mut fresh1 = (*elt).head.cleanup; + *fresh1 = cleanup; + let ref mut fresh2 = (*elt).arg.v; + *fresh2 = arg; + unwind_protect_list = elt; + } //unsafe +} +fn remove_unwind_protect_internal( + //need + mut ignore1: *mut libc::c_char, + mut ignore2: *mut libc::c_char, +) { + unsafe { + let mut elt: *mut UNWIND_ELT = 0 as *mut UNWIND_ELT; + elt = unwind_protect_list; + if !elt.is_null() { + unwind_protect_list = (*unwind_protect_list).head.next; + if uwcache.nc < uwcache.cs { + if ::std::mem::size_of::() as libc::c_ulong + <= 32 as libc::c_int as libc::c_ulong + { + let mut mzp: *mut libc::c_char = elt as *mut libc::c_char; + let mut mctmp: libc::c_ulong = + ::std::mem::size_of::() as libc::c_ulong; + let mut mcn: libc::c_long = 0; + if mctmp < 8 as libc::c_int as libc::c_ulong { + mcn = 0 as libc::c_int as libc::c_long; + } else { + mcn = mctmp + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + .wrapping_div(8 as libc::c_int as libc::c_ulong) + as libc::c_long; + mctmp &= 7 as libc::c_int as libc::c_ulong; + } + let mut loop_one = true; + loop { + if loop_one == true { + match mctmp { + 0 => { + let xch = mzp; + mzp = mzp.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 7 => { + let xch = mzp; + mzp = mzp.offset(7); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 6 => { + let xch = mzp; + mzp = mzp.offset(6); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 5 => { + let xch = mzp; + mzp = mzp.offset(5); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 4 => { + let xch = mzp; + mzp = mzp.offset(4); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 3 => { + let xch = mzp; + mzp = mzp.offset(3); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 2 => { + let xch = mzp; + mzp = mzp.offset(2); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 1 => { + let xch = mzp; + mzp = mzp.offset(1); + *xch = 0xdf as libc::c_int as libc::c_char; + } + _ => {} + } + } else { + let xch = mzp; + mzp = mzp.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + if mcn <= 0 as libc::c_int as libc::c_long { + break; + } + mcn -= 1; + loop_one = false; + } + } else { + memset( + elt as *mut libc::c_void, + 0xdf as libc::c_int, + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ); + } + let fresh11 = uwcache.nc; + uwcache.nc = uwcache.nc + 1; + let ref mut fresh12 = + *(uwcache.data as *mut *mut UNWIND_ELT).offset(fresh11 as isize); + *fresh12 = elt; + } else { + libc::free(elt as *mut libc::c_void); + } + } + } //unsafe +} +fn run_unwind_protects_internal( + //need + mut ignore1: *mut libc::c_char, + mut ignore2: *mut libc::c_char, +) { + unwind_frame_run_internal( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + ); +} +fn clear_unwind_protects_internal( + //need + mut flag: *mut libc::c_char, + mut ignore: *mut libc::c_char, +) { + unsafe { + if !flag.is_null() { + while !unwind_protect_list.is_null() { + remove_unwind_protect_internal( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + ); + } + } + unwind_protect_list = 0 as *mut libc::c_void as *mut UNWIND_ELT; + } //unsafe +} +fn unwind_frame_discard_internal( + //need + mut tag: *mut libc::c_char, + mut ignore: *mut libc::c_char, +) { + unsafe { + let mut elt: *mut UNWIND_ELT = 0 as *mut UNWIND_ELT; + let mut found: libc::c_int = 0; + found = 0 as libc::c_int; + loop { + elt = unwind_protect_list; + if elt.is_null() { + break; + } + unwind_protect_list = (*unwind_protect_list).head.next; + if ((*elt).head.cleanup).is_none() + && (*((*elt).arg.v).offset(0 as libc::c_int as isize) as libc::c_int + == *tag.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp((*elt).arg.v, tag) == 0 as libc::c_int) + { + if uwcache.nc < uwcache.cs { + if ::std::mem::size_of::() as libc::c_ulong + <= 32 as libc::c_int as libc::c_ulong + { + let mut mzp: *mut libc::c_char = elt as *mut libc::c_char; + let mut mctmp: libc::c_ulong = + ::std::mem::size_of::() as libc::c_ulong; + let mut mcn: libc::c_long = 0; + if mctmp < 8 as libc::c_int as libc::c_ulong { + mcn = 0 as libc::c_int as libc::c_long; + } else { + mcn = mctmp + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + .wrapping_div(8 as libc::c_int as libc::c_ulong) + as libc::c_long; + mctmp &= 7 as libc::c_int as libc::c_ulong; + } + let mut loop_one = true; + loop { + if loop_one == true { + match mctmp { + 0 => { + let xch = mzp; + mzp = mzp.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 7 => { + let xch = mzp; + mzp = mzp.offset(7); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 6 => { + let xch = mzp; + mzp = mzp.offset(6); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 5 => { + let xch = mzp; + mzp = mzp.offset(5); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 4 => { + let xch = mzp; + mzp = mzp.offset(4); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 3 => { + let xch = mzp; + mzp = mzp.offset(3); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 2 => { + let xch = mzp; + mzp = mzp.offset(2); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 1 => { + let xch = mzp; + mzp = mzp.offset(1); + *xch = 0xdf as libc::c_int as libc::c_char; + } + _ => {} + } + } else { + let xch = mzp; + mzp = mzp.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + if mcn <= 0 as libc::c_int as libc::c_long { + break; + } + mcn -= 1; + loop_one = false; + } + } else { + memset( + elt as *mut libc::c_void, + 0xdf as libc::c_int, + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ); + } + let fresh21 = uwcache.nc; + uwcache.nc = uwcache.nc + 1; + let ref mut fresh22 = + *(uwcache.data as *mut *mut UNWIND_ELT).offset(fresh21 as isize); + *fresh22 = elt; + } else { + libc::free(elt as *mut libc::c_void); + } + found = 1 as libc::c_int; + break; + } else if uwcache.nc < uwcache.cs { + if ::std::mem::size_of::() as libc::c_ulong + <= 32 as libc::c_int as libc::c_ulong + { + let mut mzp_0: *mut libc::c_char = elt as *mut libc::c_char; + let mut mctmp_0: libc::c_ulong = + ::std::mem::size_of::() as libc::c_ulong; + let mut mcn_0: libc::c_long = 0; + if mctmp_0 < 8 as libc::c_int as libc::c_ulong { + mcn_0 = 0 as libc::c_int as libc::c_long; + } else { + mcn_0 = mctmp_0 + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + .wrapping_div(8 as libc::c_int as libc::c_ulong) + as libc::c_long; + mctmp_0 &= 7 as libc::c_int as libc::c_ulong; + } + let mut loop_one = true; + loop { + if loop_one == true { + match mctmp_0 { + 0 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 7 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(7); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 6 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(6); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 5 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(5); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 4 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(4); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 3 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(3); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 2 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(2); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 1 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(1); + *xch = 0xdf as libc::c_int as libc::c_char; + } + _ => {} + } + } else { + let xch = mzp_0; + mzp_0 = mzp_0.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + if mcn_0 <= 0 as libc::c_int as libc::c_long { + break; + } + mcn_0 -= 1; + loop_one = false; + } + } else { + memset( + elt as *mut libc::c_void, + 0xdf as libc::c_int, + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ); + } + let fresh31 = uwcache.nc; + uwcache.nc = uwcache.nc + 1; + let ref mut fresh32 = + *(uwcache.data as *mut *mut UNWIND_ELT).offset(fresh31 as isize); + *fresh32 = elt; + } else { + libc::free(elt as *mut libc::c_void); + } + } + if found == 0 as libc::c_int { + internal_warning( + b"unwind_frame_discard: %s: frame not found\0" as *const u8 as *const libc::c_char, + tag, + ); + } + } //unsafe +} +#[inline] +fn restore_variable(mut sv: *mut SAVED_VAR) { + //need + unsafe { + libc::memcpy( + (*sv).variable as *mut libc::c_void, + ((*sv).desired_setting).as_mut_ptr() as *const libc::c_void, + (*sv).size as libc::c_ulong as libc::size_t, + ); + } //unsafe +} +fn unwind_frame_run_internal( + //need + mut tag: *mut libc::c_char, + mut ignore: *mut libc::c_char, +) { + unsafe { + let mut elt: *mut UNWIND_ELT = 0 as *mut UNWIND_ELT; + let mut found: libc::c_int = 0; + found = 0 as libc::c_int; + loop { + elt = unwind_protect_list; + if elt.is_null() { + break; + } + unwind_protect_list = (*elt).head.next; + if ((*elt).head.cleanup).is_none() { + if !tag.is_null() + && (*((*elt).arg.v).offset(0 as libc::c_int as isize) as libc::c_int + == *tag.offset(0 as libc::c_int as isize) as libc::c_int + && strcmp((*elt).arg.v, tag) == 0 as libc::c_int) + { + if uwcache.nc < uwcache.cs { + if ::std::mem::size_of::() as libc::c_ulong + <= 32 as libc::c_int as libc::c_ulong + { + let mut mzp: *mut libc::c_char = elt as *mut libc::c_char; + let mut mctmp: libc::c_ulong = + ::std::mem::size_of::() as libc::c_ulong; + let mut mcn: libc::c_long = 0; + if mctmp < 8 as libc::c_int as libc::c_ulong { + mcn = 0 as libc::c_int as libc::c_long; + } else { + mcn = mctmp + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + .wrapping_div(8 as libc::c_int as libc::c_ulong) + as libc::c_long; + mctmp &= 7 as libc::c_int as libc::c_ulong; + } + let mut loop_one = true; + loop { + if loop_one == true { + match mctmp { + 0 => { + let xch = mzp; + mzp = mzp.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 7 => { + let xch = mzp; + mzp = mzp.offset(7); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 6 => { + let xch = mzp; + mzp = mzp.offset(6); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 5 => { + let xch = mzp; + mzp = mzp.offset(5); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 4 => { + let xch = mzp; + mzp = mzp.offset(4); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 3 => { + let xch = mzp; + mzp = mzp.offset(3); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 2 => { + let xch = mzp; + mzp = mzp.offset(2); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 1 => { + let xch = mzp; + mzp = mzp.offset(1); + *xch = 0xdf as libc::c_int as libc::c_char; + } + _ => {} + } + } else { + let xch = mzp; + mzp = mzp.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + if mcn <= 0 as libc::c_int as libc::c_long { + break; + } + mcn -= 1; + loop_one = false; + } + } else { + memset( + elt as *mut libc::c_void, + 0xdf as libc::c_int, + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ); + } + let fresh41 = uwcache.nc; + uwcache.nc = uwcache.nc + 1; + let ref mut fresh42 = + *(uwcache.data as *mut *mut UNWIND_ELT).offset(fresh41 as isize); + *fresh42 = elt; + } else { + libc::free(elt as *mut libc::c_void); + } + found = 1 as libc::c_int; + break; + } + } else if (*elt).head.cleanup + == ::std::mem::transmute:: ()>, Option>(Some( + ::std::mem::transmute:: (), fn() -> ()>(restore_variable), + )) + { + restore_variable(&mut (*elt).sv.v); + } else { + ::std::mem::transmute::<_, fn(_) -> libc::c_int>( + (Some(((*elt).head.cleanup).expect("non-null function pointer"))) + .expect("non-null function pointer"), + )((*elt).arg.v); + } + if uwcache.nc < uwcache.cs { + if ::std::mem::size_of::() as libc::c_ulong + <= 32 as libc::c_int as libc::c_ulong + { + let mut mzp_0: *mut libc::c_char = elt as *mut libc::c_char; + let mut mctmp_0: libc::c_ulong = + ::std::mem::size_of::() as libc::c_ulong; + let mut mcn_0: libc::c_long = 0; + if mctmp_0 < 8 as libc::c_int as libc::c_ulong { + mcn_0 = 0 as libc::c_int as libc::c_long; + } else { + mcn_0 = mctmp_0 + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + .wrapping_div(8 as libc::c_int as libc::c_ulong) + as libc::c_long; + mctmp_0 &= 7 as libc::c_int as libc::c_ulong; + } + let mut loop_one = true; + loop { + if loop_one == true { + match mctmp_0 { + 0 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 7 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(7); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 6 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(6); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 5 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(5); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 4 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(4); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 3 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(3); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 2 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(2); + *xch = 0xdf as libc::c_int as libc::c_char; + } + 1 => { + let xch = mzp_0; + mzp_0 = mzp_0.offset(1); + *xch = 0xdf as libc::c_int as libc::c_char; + } + _ => {} + } + } else { + let xch = mzp_0; + mzp_0 = mzp_0.offset(8); + *xch = 0xdf as libc::c_int as libc::c_char; + } + if mcn_0 <= 0 as libc::c_int as libc::c_long { + break; + } + mcn_0 -= 1; + loop_one = false; + } + } else { + memset( + elt as *mut libc::c_void, + 0xdf as libc::c_int, + (::std::mem::size_of::() as libc::c_ulong) + .try_into() + .unwrap(), + ); + } + let fresh51 = uwcache.nc; + uwcache.nc = uwcache.nc + 1; + let ref mut fresh52 = + *(uwcache.data as *mut *mut UNWIND_ELT).offset(fresh51 as isize); + *fresh52 = elt; + } else { + libc::free(elt as *mut libc::c_void); + } + } + if !tag.is_null() && found == 0 as libc::c_int { + internal_warning( + b"unwind_frame_run: %s: frame not found\0" as *const u8 as *const libc::c_char, + tag, + ); + } + } //unsafe +} +fn unwind_protect_mem_internal( + //need + mut var: *mut libc::c_char, + mut psize: *mut libc::c_char, +) { + unsafe { + let mut size: libc::c_int = 0; + let mut allocated: libc::c_int = 0; + let mut elt: *mut UNWIND_ELT = 0 as *mut UNWIND_ELT; + size = *(psize as *mut libc::c_int); + allocated = (size as libc::c_ulong).wrapping_add(28 as libc::c_ulong) as libc::c_int; + if (allocated as libc::c_ulong) < ::std::mem::size_of::() as libc::c_ulong { + allocated = ::std::mem::size_of::() as libc::c_ulong as libc::c_int; + } + elt = libc::malloc((allocated as size_t).try_into().unwrap()) as *mut UNWIND_ELT; + let ref mut fresh53 = (*elt).head.next; + *fresh53 = unwind_protect_list; + let ref mut fresh54 = (*elt).head.cleanup; + *fresh54 = ::std::mem::transmute:: ()>, Option>(Some( + ::std::mem::transmute:: (), fn() -> ()>(restore_variable), + )); + let ref mut fresh55 = (*elt).sv.v.variable; + *fresh55 = var; + (*elt).sv.v.size = size; + libc::memcpy( + ((*elt).sv.v.desired_setting).as_mut_ptr() as *mut libc::c_void, + var as *const libc::c_void, + size as libc::c_ulong as libc::size_t, + ); + unwind_protect_list = elt; + } +} +#[no_mangle] +pub fn unwind_protect_mem(mut var: *mut libc::c_char, mut size: libc::c_int) { + unsafe { + without_interrupts( + Some(::std::mem::transmute::< + fn(*mut libc::c_char, *mut libc::c_char) -> (), + fn() -> (), + >(unwind_protect_mem_internal)), + var, + &mut size as *mut libc::c_int as *mut libc::c_char, + ); + } //unsafe +} diff --git a/utshell-0.5.0/src/utshell.rs b/utshell-0.5.0/src/utshell.rs new file mode 100644 index 00000000..be3f50e4 --- /dev/null +++ b/utshell-0.5.0/src/utshell.rs @@ -0,0 +1,1821 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common; +use crate::bashhist::{ + bash_history_reinit, bash_initialize_history, load_history, maybe_save_shell_history, +}; +use crate::bashline::bashline_reinitialize; +use crate::builtins::common::{initialize_shell_builtins, remember_args}; +use crate::builtins::evalfile::{force_execute_file, maybe_execute_file}; +use crate::builtins::read::read_tty_cleanup; +use crate::builtins::read::read_tty_modified; +use crate::builtins::set::{ + initialize_shell_options, list_minus_o_opts, set_minus_o_option, set_shellopts, +}; +use crate::builtins::shopt::{ + initialize_bashopts, set_bashopts, set_login_shell, shopt_listopt, shopt_setopt, +}; +use crate::dispose_cmd::dispose_words; +use crate::error::{command_error, file_error}; +use crate::eval::{pretty_print_loop, reader_loop}; +use crate::execute_cmd::{coproc_flush, executing_line_number}; +use crate::findcmd::find_path_file; +use crate::flags::{change_flag, initialize_flags}; +use crate::general::{ + absolute_program, base_pathname, check_binary_file, check_dev_tty, move_to_high_fd, + sh_unset_nodelay_mode, tilde_initialize, +}; +use crate::input::{close_buffered_fd, with_input_from_buffered_stream}; +use crate::jobs::{ + end_job_control, get_tty_state, hangup_all_jobs, initialize_job_control, set_job_control, +}; +use crate::local::set_default_locale; +use crate::local::{set_default_lang, set_default_locale_vars}; +use crate::mailcheck::{init_mail_dates, reset_mail_timer}; +use crate::make_cmd::{cmd_init, make_word, make_word_list}; +use crate::print_cmd::xtrace_init; +use crate::sig::initialize_signals; +use crate::src_common::*; +use crate::subst::{expand_string_unsplit_to_string, unlink_all_fifos, unlink_fifo_list}; +use crate::trap::{initialize_traps, run_exit_trap}; +use crate::unwind_prot::uwp_init; +use crate::variables::{ + bind_variable, delete_all_contexts, delete_all_variables, initialize_shell_variables, pop_args, + push_args, reinit_special_variables, set_pipestatus_from_exit, set_var_read_only, + sv_strict_posix, unbind_variable, +}; +use crate::version::shell_version_string; +use crate::version::show_shell_version; +use crate::y_tab::{ + bash_input, expand_aliases, initialize_bash_input, line_number, with_input_from_stdin, + with_input_from_stream, +}; +use std::convert::TryInto; + +#[link(name = "termcap")] + +extern "C" { + static mut rl_deprep_term_function: Option; + #[link_name = "\u{1}stderr"] + pub static mut stderr: *mut FILE; + #[link_name = "\u{1}stdin"] + pub static mut stdin: *mut FILE; + #[link_name = "\u{1}stdout"] + pub static mut stdout: *mut FILE; + +} +#[inline] +fn fstat(mut __fd: libc::c_int, mut __statbuf: *mut crate::src_common::stat) -> libc::c_int { + unsafe { + return __fxstat( + 1 as libc::c_int, + __fd, + __statbuf as *mut crate::src_common::stat, + ); + } //unsafe +} +static mut act_like_sh: libc::c_int = 0; +static mut su_shell: libc::c_int = 0; +static mut sourced_env: libc::c_int = 0; +static mut running_setuid: libc::c_int = 0; +static mut debugging: libc::c_int = 0; +static mut no_rc: libc::c_int = 0; +static mut no_profile: libc::c_int = 0; +static mut do_version: libc::c_int = 0; +static mut make_login_shell: libc::c_int = 0; +static mut want_initial_help: libc::c_int = 0; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct C2RustUnnamed_0 { + pub name: *const libc::c_char, + pub type_0: libc::c_int, + pub int_value: *mut libc::c_int, + pub char_value: *mut *mut libc::c_char, +} +static mut long_args: [C2RustUnnamed_0; 18] = unsafe { + [ + { + let init = C2RustUnnamed_0 { + name: b"debug\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &debugging as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"debugger\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &debugging_mode as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"dump-po-strings\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &dump_po_strings as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"dump-strings\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &dump_translatable_strings as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"help\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &want_initial_help as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"init-file\0" as *const u8 as *const libc::c_char, + type_0: 2 as libc::c_int, + int_value: 0 as *const libc::c_int as *mut libc::c_int, + char_value: &bashrc_file as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"login\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &make_login_shell as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"noediting\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &no_line_editing as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"noprofile\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &no_profile as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"norc\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &no_rc as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"posix\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &posixly_correct as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"pretty-print\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &pretty_print_mode as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"rcfile\0" as *const u8 as *const libc::c_char, + type_0: 2 as libc::c_int, + int_value: 0 as *const libc::c_int as *mut libc::c_int, + char_value: &bashrc_file as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"rpm-requires\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &rpm_requires as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"restricted\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &restricted as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"verbose\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &verbose_flag as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: b"version\0" as *const u8 as *const libc::c_char, + type_0: 1 as libc::c_int, + int_value: &do_version as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + { + let init = C2RustUnnamed_0 { + name: 0 as *const libc::c_char as *mut libc::c_char, + type_0: 1 as libc::c_int, + int_value: 0 as *const libc::c_int as *mut libc::c_int, + char_value: 0 as *const *mut libc::c_char as *mut *mut libc::c_char, + }; + init + }, + ] +}; + +static mut shell_reinitialized: libc::c_int = 0 as libc::c_int; +static mut default_input: *mut FILE = 0 as *const FILE as *mut FILE; +static mut shopt_alist: *mut STRING_INT_ALIST = + 0 as *const STRING_INT_ALIST as *mut STRING_INT_ALIST; +static mut shopt_ind: libc::c_int = 0 as libc::c_int; +static mut shopt_len: libc::c_int = 0 as libc::c_int; + +fn main_0( + mut argc: libc::c_int, + mut argv: *mut *mut libc::c_char, + mut env: *mut *mut libc::c_char, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut code: libc::c_int = 0; + let mut old_errexit_flag: libc::c_int = 0; + let mut saverst: libc::c_int = 0; + let mut locally_skip_execution: libc::c_int = 0; + let mut arg_index: libc::c_int = 0; + let mut top_level_arg_index: libc::c_int = 0; + + code = setjmp_nosigs!(top_level.as_mut_ptr()); + if code != 0 { + exit(2); + } + xtrace_init(); + check_dev_tty(); + while debugging_login_shell != 0 { + sleep(3); + } + set_default_locale(); + + running_setuid = uidget(); + + if !(getenv(b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char)).is_null() + || !(getenv(b"POSIX_PEDANTIC\0" as *const u8 as *const libc::c_char)).is_null() + { + posixly_correct = 1; + } + if setjmp_sigs!(subshell_top_level.as_mut_ptr()) != 0 { + argc = subshell_argc; + argv = subshell_argv; + env = subshell_envp; + sourced_env = 0; + } + + shell_reinitialized = 0; + + arg_index = 1; + if arg_index > argc { + arg_index = argc; + } + shell_script_filename = 0 as *mut libc::c_char; + command_execution_string = shell_script_filename; + read_from_stdin = 0; + locally_skip_execution = read_from_stdin; + want_pending_command = locally_skip_execution; + default_input = stdin; + default_buffered_input = -1; + + make_login_shell = 0; + login_shell = make_login_shell; + + if shell_initialized != 0 || !shell_name.is_null() { + if *shell_name as libc::c_int == '-' as i32 { + shell_name = shell_name.offset(1); + } + shell_reinitialize(); + if setjmp_nosigs!(top_level.as_mut_ptr()) != 0 { + exit(2); + } + } + shell_environment = env; + set_shell_name(*argv.offset(0 as isize)); + + gettimeofday(&mut shellstart, 0 as *mut crate::src_common::timezone); + shell_start_time = shellstart.tv_sec; + + arg_index = parse_long_options(argv, arg_index, argc); + + if want_initial_help != 0 { + show_shell_usage(stdout, 1); + exit(EXECUTION_SUCCESS as libc::c_int); + } + + if do_version != 0 { + show_shell_version(1); + exit(EXECUTION_SUCCESS as libc::c_int); + } + + echo_input_at_read = verbose_flag; + + this_command_name = shell_name; + arg_index = parse_shell_options(argv, arg_index, argc); + + if make_login_shell != 0 { + login_shell += 1; + login_shell = -login_shell; + } + + set_login_shell( + b"login_shell\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + (login_shell != 0) as libc::c_int, + ); + + if dump_po_strings != 0 { + dump_translatable_strings = 1; + } + + if dump_translatable_strings != 0 { + read_but_dont_execute = 1; + } + + if rpm_requires != 0 { + read_but_dont_execute = 1; + initialize_shell_builtins(); + } + + if running_setuid != 0 && privileged_mode == 0 { + disable_priv_mode(); + } + + if want_pending_command != 0 { + command_execution_string = *argv.offset(arg_index as isize); + if command_execution_string.is_null() { + report_error( + b"%s: option requires an argument\0" as *const u8 as *mut libc::c_char, + b"-c\0" as *const u8 as *const libc::c_char, + ); + exit(EX_BADUSAGE as libc::c_int); + } + arg_index += 1; + } + + this_command_name = 0 as *mut libc::c_char; + + if forced_interactive != 0 + || command_execution_string.is_null() + && wordexp_only == 0 + && (arg_index == argc || read_from_stdin != 0) + && isatty(fileno(stdin)) != 0 + && isatty(fileno(stderr)) != 0 + { + init_interactive(); + } else { + init_noninteractive(); + } + + if login_shell != 0 && interactive_shell != 0 { + i = 3; + while i < 20 { + SET_CLOSE_ON_EXEC!(i); + i += 1; + } + } + + if posixly_correct != 0 { + bind_variable( + b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char, + b"y\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + sv_strict_posix( + b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + + if !shopt_alist.is_null() { + run_shopt_alist(); + } + + shell_initialize(); + + set_default_lang(); + set_default_locale_vars(); + + if interactive_shell != 0 { + let mut term: *mut libc::c_char = 0 as *mut libc::c_char; + let mut emacs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut inside_emacs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut emacs_term: libc::c_int = 0; + let mut in_emacs: libc::c_int = 0; + + term = get_string_value(b"TERM\0" as *const u8 as *const libc::c_char); + emacs = get_string_value(b"EMACS\0" as *const u8 as *const libc::c_char); + inside_emacs = get_string_value(b"INSIDE_EMACS\0" as *const u8 as *const libc::c_char); + + if !inside_emacs.is_null() { + emacs_term = (strstr( + inside_emacs, + b",term:\0" as *const u8 as *const libc::c_char, + ) != 0 as *mut libc::c_char) as libc::c_int; + in_emacs = 1; + } else if !emacs.is_null() { + emacs_term = (strstr(emacs, b" (term:\0" as *const u8 as *const libc::c_char) + != 0 as *mut libc::c_char) as libc::c_int; + in_emacs = (emacs_term != 0 || STREQ(emacs, CString::new("t").unwrap().as_ptr())) + as libc::c_int; + } else { + emacs_term = 0; + in_emacs = emacs_term; + } + + no_line_editing |= STREQ(term, CString::new("emacs").unwrap().as_ptr()) as libc::c_int; + no_line_editing |= (in_emacs != 0 + && STREQ(term, CString::new("dumb").unwrap().as_ptr())) + as libc::c_int; + + running_under_emacs = (in_emacs != 0 + || STREQN!(term, String::from("emacs").as_ptr() as *mut libc::c_char, 5) != 0) + as libc::c_int; + running_under_emacs += (emacs_term != 0 + && STREQN!(term, String::from("eterm").as_ptr() as *mut libc::c_char, 5) != 0) + as libc::c_int; + + if running_under_emacs != 0 { + gnu_error_format = 1; + } + } + + top_level_arg_index = arg_index; + old_errexit_flag = exit_immediately_on_error; + + code = setjmp_sigs!(top_level.as_mut_ptr()); + if code != 0 { + if code == EXITPROG as libc::c_int || code == ERREXIT as libc::c_int { + exit_shell(last_command_exit_value); + } else { + set_job_control(interactive_shell); + + exit_immediately_on_error += old_errexit_flag; + locally_skip_execution += 1; + } + } + + arg_index = top_level_arg_index; + + if interactive_shell == 0 { + unbind_variable(b"PS1\0" as *const u8 as *const libc::c_char); + unbind_variable(b"PS2\0" as *const u8 as *const libc::c_char); + interactive = 0; + } else { + change_flag('i' as i32, FLAG_ON as libc::c_int); + interactive = 1; + } + + restricted_shell = shell_is_restricted(shell_name); + + saverst = restricted; + restricted = 0; + + if !(wordexp_only != 0) { + if !command_execution_string.is_null() { + arg_index = bind_args(argv, arg_index, argc, 0); + } else if arg_index != argc && read_from_stdin == 0 { + shell_script_filename = *argv.offset(arg_index as isize); + arg_index += 1; + arg_index = bind_args(argv, arg_index, argc, 1); + } else { + arg_index = bind_args(argv, arg_index, argc, 1); + } + } + + if locally_skip_execution == 0 && running_setuid == 0 { + old_errexit_flag = exit_immediately_on_error; + exit_immediately_on_error = 0; + run_startup_files(); + exit_immediately_on_error += old_errexit_flag; + } + + if act_like_sh != 0 { + bind_variable( + b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char, + b"y\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + sv_strict_posix( + b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + + restricted = (saverst != 0 || restricted != 0) as libc::c_int; + if shell_reinitialized == 0 { + maybe_make_restricted(shell_name); + } + + cmd_init(); + uwp_init(); + + if !command_execution_string.is_null() { + startup_state = 2; + + if debugging_mode != 0 { + start_debugger(); + } + + executing = 1; + run_one_command(command_execution_string); + exit_shell(last_command_exit_value); + } + + if !shell_script_filename.is_null() { + open_shell_script(shell_script_filename); + } else if interactive == 0 { + default_buffered_input = fileno(stdin); + read_from_stdin = 1; + } else if top_level_arg_index == argc { + read_from_stdin = 1; + } + + set_bash_input(); + + if debugging_mode != 0 + && locally_skip_execution == 0 + && running_setuid == 0 + && (reading_shell_script != 0 || interactive_shell == 0) + { + start_debugger(); + } + + if interactive_shell != 0 { + reset_mail_timer(); + init_mail_dates(); + + bash_initialize_history(); + + if shell_initialized == 0 && history_lines_this_session == 0 { + load_history(); + } + get_tty_state(); + } + + shell_initialized = 1; + + if pretty_print_mode != 0 && interactive_shell != 0 { + internal_warning( + b"pretty-printing mode ignored in interactive shells\0" as *const u8 + as *mut libc::c_char, + ); + pretty_print_mode = 0; + } + if pretty_print_mode != 0 { + exit_shell(pretty_print_loop()); + } + reader_loop(); + exit_shell(last_command_exit_value); + return 0; + } //unsafe +} + +fn parse_long_options( + argv: *mut *mut libc::c_char, + arg_start: libc::c_int, + arg_end: libc::c_int, +) -> libc::c_int { + unsafe { + let mut arg_index: libc::c_int = 0; + let mut longarg: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut arg_string: *mut libc::c_char = 0 as *mut libc::c_char; + + arg_index = arg_start; + while arg_index != arg_end + && { + arg_string = *argv.offset(arg_index as isize); + !arg_string.is_null() + } + && *arg_string as libc::c_int == '-' as i32 + { + longarg = 0; + + if *arg_string.offset(1 as isize) as libc::c_int == '-' as i32 + && *arg_string.offset(2 as isize) as libc::c_int != 0 + { + longarg = 1; + arg_string = arg_string.offset(1); + } + + i = 0; + while !(long_args[i as usize].name).is_null() { + if STREQ(arg_string.offset(1), long_args[i as usize].name) { + if long_args[i as usize].type_0 == 1 { + *long_args[i as usize].int_value = 1; + } else { + arg_index += 1; + if (*argv.offset(arg_index as isize)).is_null() { + report_error( + b"%s: option requires an argument\0" as *const u8 + as *const libc::c_char, + long_args[i as usize].name, + ); + exit(EX_BADUSAGE as libc::c_int); + } else { + *long_args[i as usize].char_value = *argv.offset(arg_index as isize); + } + } + break; + } else { + i += 1; + } + } + if (long_args[i as usize].name).is_null() { + if longarg != 0 { + report_error( + b"%s: invalid option\0" as *const u8 as *const libc::c_char, + *argv.offset(arg_index as isize), + ); + show_shell_usage(stderr, 0 as libc::c_int); + exit(EX_BADUSAGE as libc::c_int); + } + break; + } else { + arg_index += 1; + } + } + return arg_index; + } //unsafe +} + +fn parse_shell_options( + argv: *mut *mut libc::c_char, + arg_start: libc::c_int, + arg_end: libc::c_int, +) -> libc::c_int { + unsafe { + let mut arg_index: libc::c_int = 0; + let mut arg_character: libc::c_int = 0; + let mut on_or_off: libc::c_int = 0; + let mut next_arg: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut o_option: *mut libc::c_char = 0 as *mut libc::c_char; + let mut arg_string: *mut libc::c_char = 0 as *mut libc::c_char; + + arg_index = arg_start; + while arg_index != arg_end + && { + arg_string = *argv.offset(arg_index as isize); + !arg_string.is_null() + } + && (*arg_string as libc::c_int == '-' as i32 + || *arg_string as libc::c_int == '+' as i32) + { + next_arg = arg_index + 1; + + if *arg_string.offset(0 as isize) as libc::c_int == '-' as i32 + && (*arg_string.offset(1 as isize) as libc::c_int == '\u{0}' as i32 + || *arg_string.offset(1 as isize) as libc::c_int == '-' as i32 + && *arg_string.offset(2 as isize) as libc::c_int == '\u{0}' as i32) + { + return next_arg; + } + + i = 1; + + on_or_off = *arg_string.offset(0 as isize) as libc::c_int; + loop { + arg_character = *arg_string.offset(i as isize) as libc::c_int; + i = i + 1; + if !(arg_character != 0) { + break; + } + + match arg_character as u8 as char { + 'c' => { + want_pending_command = 1; + } + 'l' => { + make_login_shell = 1; + } + 's' => { + read_from_stdin = 1; + } + 'o' => { + o_option = *argv.offset(next_arg as isize); + if o_option.is_null() { + set_option_defaults(); + list_minus_o_opts( + -(1 as libc::c_int), + if on_or_off == '-' as i32 { 0 } else { 1 }, + ); + reset_option_defaults(); + } else { + if set_minus_o_option(on_or_off, o_option) + != EXECUTION_SUCCESS as libc::c_int + { + exit(EX_BADUSAGE as libc::c_int); + } + next_arg += 1; + } + } + 'O' => { + o_option = *argv.offset(next_arg as isize); + if o_option.is_null() { + shopt_listopt(o_option, if on_or_off == '-' as i32 { 0 } else { 1 }); + } else { + add_shopt_to_alist(o_option, on_or_off); + next_arg += 1; + } + } + 'D' => { + dump_translatable_strings = 1; + } + _ => { + if change_flag(arg_character, on_or_off) == -1 { + report_error( + b"%c%c: invalid option\0" as *const u8 as *const libc::c_char, + on_or_off, + arg_character, + ); + show_shell_usage(stderr, 0 as libc::c_int); + exit(2 as libc::c_int); + } + } + } + } + arg_index = next_arg; + } + return arg_index; + } //unsafe +} + +#[no_mangle] +pub fn exit_shell(mut s: libc::c_int) { + unsafe { + fflush(stdout); + fflush(stderr); + + if RL_ISSTATE!(RL_STATE_TERMPREPPED!()) != 0 && rl_deprep_term_function.is_some() { + (Some(rl_deprep_term_function.expect("non-null function pointer"))) + .expect("non-null function pointer")(); + } + if read_tty_modified() != 0 { + read_tty_cleanup(); + } + + if signal_is_trapped(0) != 0 { + s = run_exit_trap(); + } + + unlink_all_fifos(); + + if remember_on_history != 0 { + maybe_save_shell_history(); + } + + coproc_flush(); + + if interactive_shell != 0 && login_shell != 0 && hup_on_exit != 0 { + hangup_all_jobs(); + } + + if subshell_environment == 0 { + end_job_control(); + } + + sh_exit(s); + } //unsafe +} + +#[no_mangle] +pub fn sh_exit(s: libc::c_int) { + unsafe { + exit(s); + } +} + +#[no_mangle] +pub fn subshell_exit(mut s: libc::c_int) { + unsafe { + fflush(stdout); + fflush(stderr); + + if signal_is_trapped(0) != 0 { + s = run_exit_trap(); + } + + sh_exit(s); + } //unsafe +} + +#[no_mangle] +pub fn set_exit_status(s: libc::c_int) { + unsafe { + last_command_exit_value = s; + set_pipestatus_from_exit(last_command_exit_value); + } +} + +fn execute_env_file(env_file: *mut libc::c_char) { + unsafe { + let mut fn_0: *mut libc::c_char = 0 as *mut libc::c_char; + + if !env_file.is_null() && *env_file as libc::c_int != 0 { + fn_0 = expand_string_unsplit_to_string(env_file, Q_DOUBLE_QUOTES as libc::c_int); + if !fn_0.is_null() && *fn_0 as libc::c_int != 0 { + maybe_execute_file(fn_0, 1); + } + FREE!(fn_0); + } + } //unsafe +} + +//执行å¯åŠ¨æ–‡ä»¶ bashrcç­‰ +fn run_startup_files() { + unsafe { + let mut old_job_control: libc::c_int = 0; + let mut sourced_login: libc::c_int = 0; + let mut run_by_ssh: libc::c_int = 0; + + if interactive_shell == 0 + && no_rc == 0 + && login_shell == 0 + && act_like_sh == 0 + && !command_execution_string.is_null() + { + run_by_ssh = (!(find_variable(b"SSH_CLIENT\0" as *const u8 as *const libc::c_char)) + .is_null() + || !(find_variable(b"SSH2_CLIENT\0" as *const u8 as *const libc::c_char)).is_null()) + as libc::c_int; + + if (run_by_ssh != 0 || isnetconn(fileno(stdin)) != 0) && shell_level < 2 { + maybe_execute_file(bashrc_file, 1); + return; + } + } + + old_job_control = if interactive_shell != 0 { + set_job_control(0) + } else { + 0 + }; + + sourced_login = 0; + + if login_shell != 0 && posixly_correct == 0 { + no_rc += 1; + + if no_profile == 0 { + maybe_execute_file(SYS_PROFILE!(), 1); + + if act_like_sh != 0 { + maybe_execute_file(b"~/.profile\0" as *const u8 as *const libc::c_char, 1); + } else if maybe_execute_file( + b"~/.utshell_profile\0" as *const u8 as *const libc::c_char, + 1 as libc::c_int, + ) == 0 + && maybe_execute_file( + b"~/.utshell_login\0" as *const u8 as *const libc::c_char, + 1, + ) == 0 + { + maybe_execute_file(b"~/.profile\0" as *const u8 as *const libc::c_char, 1); + } + } + + sourced_login = 1; + } + + if interactive_shell == 0 && !(su_shell != 0 && login_shell != 0) { + if posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 && { + let fresh2 = sourced_env; + sourced_env = sourced_env + 1; + fresh2 == 0 + } { + execute_env_file(get_string_value( + b"BASH_ENV\0" as *const u8 as *const libc::c_char, + )); + } + return; + } + + if posixly_correct == 0 { + if login_shell != 0 && { + let fresh3 = sourced_login; + sourced_login = sourced_login + 1; + fresh3 == 0 + } { + no_rc += 1; + + if no_profile == 0 { + maybe_execute_file(SYS_PROFILE!(), 1); + + if act_like_sh != 0 { + maybe_execute_file(b"~/.profile\0" as *const u8 as *const libc::c_char, 1); + } else if maybe_execute_file( + b"~/.utshell_profile\0" as *const u8 as *const libc::c_char, + 1, + ) == 0 + && maybe_execute_file( + b"~/.utshell_login\0" as *const u8 as *const libc::c_char, + 1, + ) == 0 + { + maybe_execute_file(b"~/.profile\0" as *const u8 as *const libc::c_char, 1); + } + } + } + + if act_like_sh == 0 && no_rc == 0 { + maybe_execute_file(bashrc_file, 1); //问题 + } else if act_like_sh != 0 && privileged_mode == 0 && { + let fresh4 = sourced_env; + sourced_env = sourced_env + 1; + fresh4 == 0 + } { + execute_env_file(get_string_value( + b"ENV\0" as *const u8 as *const libc::c_char, + )); + } + } else if interactive_shell != 0 && privileged_mode == 0 && { + let fresh5 = sourced_env; + sourced_env = sourced_env + 1; + fresh5 == 0 + } { + execute_env_file(get_string_value( + b"ENV\0" as *const u8 as *const libc::c_char, + )); + } + set_job_control(old_job_control); + } //unsafe +} + +#[no_mangle] +pub fn shell_is_restricted(name: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + + if restricted != 0 { + return 1; + } + + temp = base_pathname(name); + if *temp as libc::c_int == '-' as i32 { + temp = temp.offset(1); + } + + return (STREQ(temp, RESTRICTED_SHELL_NAME!())) as libc::c_int; + } //unsafe +} + +#[no_mangle] +pub fn maybe_make_restricted(name: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + + temp = base_pathname(name); + if *temp as libc::c_int == '-' as i32 { + temp = temp.offset(1); + } + if restricted != 0 || STREQ(temp, RESTRICTED_SHELL_NAME!()) { + set_var_read_only(b"PATH\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + set_var_read_only(b"SHELL\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + set_var_read_only(b"ENV\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + set_var_read_only( + b"BASH_ENV\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + set_var_read_only( + b"HISTFILE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + restricted = 1; + } + return restricted; + } //unsafe +} + +fn uidget() -> libc::c_int { + unsafe { + let mut u: uid_t = 0; + u = getuid(); + if current_user.uid != u { + FREE!(current_user.user_name); + FREE!(current_user.shell); + FREE!(current_user.home_dir); + current_user.home_dir = 0 as *mut libc::c_char; + current_user.shell = current_user.home_dir; + current_user.user_name = current_user.shell; + } + current_user.uid = u; + current_user.gid = getgid(); + current_user.euid = geteuid(); + current_user.egid = getegid(); + return (current_user.uid != current_user.euid || current_user.gid != current_user.egid) + as libc::c_int; + } //unsafe +} + +#[no_mangle] +pub fn disable_priv_mode() { + unsafe { + let mut e: libc::c_int = 0; + + if setresuid(current_user.uid, current_user.uid, current_user.uid) < 0 { + e = errno!(); + sys_error( + b"cannot set uid to %d: effective uid %d\0" as *const u8 as *const libc::c_char, + current_user.uid, + current_user.euid, + ); + } + if setresgid(current_user.gid, current_user.gid, current_user.gid) < 0 as libc::c_int { + sys_error( + b"cannot set gid to %d: effective gid %d\0" as *const u8 as *const libc::c_char, + current_user.gid, + current_user.egid, + ); + } + current_user.euid = current_user.uid; + current_user.egid = current_user.gid; + } +} + +fn run_one_command(command: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut code: libc::c_int = 0; + + code = setjmp_nosigs!(top_level.as_mut_ptr()); + + if code != NOT_JUMPED as libc::c_int { + unlink_fifo_list(); + match code as i32 { + FORCE_EOF => { + last_command_exit_value = 127; + return last_command_exit_value; + } + ERREXIT | EXITPROG => return last_command_exit_value, + DISCARD => { + last_command_exit_value = 1; + return last_command_exit_value; + } + _ => { + command_error( + b"run_one_command\0" as *const u8 as *const libc::c_char, + CMDERR_BADJUMP as libc::c_int, + code, + 0, + ); + } + } + } + return parse_and_execute( + savestring!(command), + b"-c\0" as *const u8 as *const libc::c_char, + SEVAL_NOHIST as libc::c_int | SEVAL_RESETLINE as libc::c_int, + ); + } //unsafe +} + +fn bind_args( + argv: *mut *mut libc::c_char, + arg_start: libc::c_int, + arg_end: libc::c_int, + start_index: libc::c_int, +) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + let mut args: *mut WordList = 0 as *mut WordList; + let mut tl: *mut WordList = 0 as *mut WordList; + + i = arg_start; + tl = 0 as *mut WordList; + args = tl; + while i < arg_end { + if args.is_null() { + tl = make_word_list(make_word(*argv.offset(i as isize)), args); + args = tl; + } else { + (*tl).next = + make_word_list(make_word(*argv.offset(i as isize)), 0 as *mut WordList); + tl = (*tl).next; + } + i += 1; + } + + if !args.is_null() { + if start_index == 0 { + shell_name = savestring!((*(*args).word).word); + FREE!(*dollar_vars.as_mut_ptr().offset(0 as isize)); + + let ref mut _fresh7 = *dollar_vars.as_mut_ptr().offset(0 as isize); + *dollar_vars.as_mut_ptr().offset(0 as isize) = savestring!((*(*args).word).word); + remember_args((*args).next, 1); + if debugging_mode != 0 { + push_args((*args).next); + bash_argv_initialized = 1; + } + } else { + remember_args(args, 1); + if debugging_mode != 0 { + push_args(args); + bash_argv_initialized = 1; + } + } + dispose_words(args); + } + return i; + } //unsafe +} + +#[no_mangle] +pub fn unbind_args() { + unsafe { + remember_args(0 as *mut libc::c_void as *mut WordList, 1); + pop_args(); + } //unsafe +} + +fn start_debugger() { + unsafe { + let mut old_errexit: libc::c_int = 0; + let mut r: libc::c_int = 0; + + old_errexit = exit_immediately_on_error; + exit_immediately_on_error = 0; + + r = force_execute_file(DEBUGGER_START_FILE!(), 1); + if r < 0 { + internal_warning( + b"cannot start debugger; debugging mode disabled\0" as *const u8 + as *mut libc::c_char, + ); + debugging_mode = 0; + } + function_trace_mode = debugging_mode; + error_trace_mode = function_trace_mode; + + set_shellopts(); + set_bashopts(); + + exit_immediately_on_error += old_errexit; + } //unsafe +} + +fn open_shell_script(script_name: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut fd: libc::c_int = 0; + let mut e: libc::c_int = 0; + let mut fd_is_tty: libc::c_int = 0; + let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut path_filename: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut sample: [libc::c_char; 80] = [0; 80]; + let mut sample_len: libc::c_int = 0; + let mut sb: crate::src_common::stat = crate::src_common::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_mtim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + st_ctim: crate::src_common::timespec { + tv_sec: 0, + tv_nsec: 0, + }, + __glibc_reserved: [0; 3], + }; + let mut funcname_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_source_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_lineno_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut funcname_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_source_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_lineno_a: *mut ARRAY = 0 as *mut ARRAY; + + filename = savestring!(script_name); + + fd = open(filename, O_RDONLY as libc::c_int); + if fd < 0 && errno!() == ENOENT!() && absolute_program(filename) == 0 { + e = errno!(); + path_filename = find_path_file(script_name); + if !path_filename.is_null() { + free(filename as *mut c_void); + filename = path_filename; + fd = open(filename, O_RDONLY as libc::c_int); + } else { + errno!() = e; + } + } + if fd < 0 { + e = errno!(); + file_error(filename); + end_job_control(); + sh_exit(if e == ENOENT!() { + EX_NOTFOUND as libc::c_int + } else { + EX_NOINPUT as libc::c_int + }); + } + + free(*dollar_vars.as_mut_ptr().offset(0 as isize) as *mut libc::c_void); + *dollar_vars.as_mut_ptr().offset(0 as isize) = if !exec_argv0.is_null() { + savestring!(exec_argv0) + } else { + savestring!(script_name) + }; + + if !exec_argv0.is_null() { + free(exec_argv0 as *mut c_void); + exec_argv0 = 0 as *mut libc::c_char; + } + + if file_isdir(filename) != 0 { + errno!() = EISDIR!(); + file_error(filename); + end_job_control(); + sh_exit(EX_NOINPUT as libc::c_int); + } + + GET_ARRAY_FROM_VAR!( + b"FUNCNAME\0" as *const u8 as *const libc::c_char, + funcname_v, + funcname_a + ); + GET_ARRAY_FROM_VAR!( + b"BASH_SOURCE\0" as *const u8 as *const libc::c_char, + bash_source_v, + bash_source_a + ); + GET_ARRAY_FROM_VAR!( + b"BASH_LINENO\0" as *const u8 as *const libc::c_char, + bash_lineno_v, + bash_lineno_a + ); + + array_push!(bash_source_a, filename); + if !bash_lineno_a.is_null() { + t = itos(executing_line_number() as intmax_t); + array_push!(bash_lineno_a, t); + free(t as *mut c_void); + } + + array_push!( + funcname_a, + b"main\0" as *const u8 as *const libc::c_char as *mut libc::c_char + ); + + fd_is_tty = isatty(fd); + + if fd_is_tty == 0 && lseek(fd, 0, 1) != -1 as libc::c_long { + sample_len = read( + fd, + sample.as_mut_ptr() as *mut libc::c_void, + (::std::mem::size_of::<[libc::c_char; 80]>() as libc::c_ulong) + .try_into() + .unwrap(), + ) as libc::c_int; + + if sample_len < 0 { + e = errno!(); + if fstat(fd, &mut sb) == 0 && S_ISDIR!(sb.st_mode) { + errno!() = EISDIR!(); + file_error(filename); + } else { + errno!() = e; + file_error(filename); + } + + end_job_control(); + exit(EX_NOEXEC as libc::c_int); + } else { + if sample_len > 0 && check_binary_file(sample.as_mut_ptr(), sample_len) != 0 { + internal_error( + b"%s: cannot execute binary file\0" as *const u8 as *const libc::c_char, + filename, + ); + end_job_control(); + exit(EX_BINARY_FILE as libc::c_int); + } + } + lseek(fd, 0 as libc::c_long, 0); + } + + fd = move_to_high_fd(fd, 1, -(1 as libc::c_int)); + + default_buffered_input = fd; + SET_CLOSE_ON_EXEC!(default_buffered_input); + + if interactive_shell != 0 && fd_is_tty != 0 { + dup2(fd, 0 as libc::c_int); + close(fd); + fd = 0; + default_buffered_input = 0; + } else if forced_interactive != 0 && fd_is_tty == 0 { + init_interactive_script(); + } + free(filename as *mut c_void); + reading_shell_script = 1; + return fd; + } //unsafe +} + +fn set_bash_input() { + unsafe { + if interactive == 0 { + sh_unset_nodelay_mode(default_buffered_input); + } else { + sh_unset_nodelay_mode(fileno(stdin)); + } + if interactive != 0 && no_line_editing == 0 { + with_input_from_stdin(); + } else if interactive == 0 { + with_input_from_buffered_stream( + default_buffered_input, + *dollar_vars.as_mut_ptr().offset(0 as isize), + ); + } else { + with_input_from_stream(default_input, *dollar_vars.as_mut_ptr().offset(0 as isize)); + }; + } //unsafe +} + +// pub const st_none: stream_type = 0; + +#[no_mangle] +pub fn unset_bash_input(check_zero: libc::c_int) { + unsafe { + if check_zero != 0 && default_buffered_input >= 0 + || check_zero == 0 && default_buffered_input > 0 + { + close_buffered_fd(default_buffered_input); + bash_input.location.buffered_fd = -(1 as libc::c_int); + default_buffered_input = bash_input.location.buffered_fd; + bash_input.type_0 = st_none; + } + } //unsafe +} + +fn set_shell_name(argv0: *mut libc::c_char) { + unsafe { + shell_name = (if !argv0.is_null() { + base_pathname(argv0) + } else { + PROGRAM!() + }) as *mut libc::c_char; + + if !argv0.is_null() && *argv0 as libc::c_int == '-' as i32 { + if *shell_name as libc::c_int == '-' as i32 { + shell_name = shell_name.offset(1); + } + login_shell = 1; + } + + if *shell_name.offset(0 as isize) as libc::c_int == 's' as i32 + && *shell_name.offset(1 as isize) as libc::c_int == 'h' as i32 + && *shell_name.offset(2 as isize) as libc::c_int == '\u{0}' as i32 + { + act_like_sh += 1; + } + if *shell_name.offset(0 as isize) as libc::c_int == 's' as i32 + && *shell_name.offset(1 as isize) as libc::c_int == 'u' as i32 + && *shell_name.offset(2 as isize) as libc::c_int == '\u{0}' as i32 + { + su_shell += 1; + } + + shell_name = (if !argv0.is_null() { argv0 } else { PROGRAM!() }) as *mut libc::c_char; + FREE!(*dollar_vars.as_mut_ptr().offset(0 as libc::c_int as isize)); + *dollar_vars.as_mut_ptr().offset(0 as isize) = savestring!(shell_name); + + if shell_name.is_null() + || *shell_name == 0 + || *shell_name.offset(0 as isize) as libc::c_int == '-' as i32 + && *shell_name.offset(1 as isize) == 0 + { + shell_name = PROGRAM!(); + } + } //unsafe +} + +fn set_option_defaults() { + unsafe { + enable_history_list = 0; + } +} + +fn reset_option_defaults() { + unsafe { + enable_history_list = -(1 as libc::c_int); + } +} + +fn init_interactive() { + unsafe { + startup_state = 1; + interactive_shell = startup_state; + expand_aliases = interactive_shell; + interactive = 1; + + if enable_history_list == -(1 as libc::c_int) { + enable_history_list = 1; + } + remember_on_history = enable_history_list; + histexp_flag = history_expansion; + } //unsafe +} + +fn init_noninteractive() { + unsafe { + if enable_history_list == -(1 as libc::c_int) { + enable_history_list = 0; + } + + bash_history_reinit(0); + + interactive = 0; + startup_state = interactive; + interactive_shell = startup_state; + expand_aliases = posixly_correct; + no_line_editing = 1; + set_job_control((forced_interactive != 0 || jobs_m_flag != 0) as libc::c_int); + } //unsafe +} + +fn init_interactive_script() { + unsafe { + if enable_history_list == -(1 as libc::c_int) { + enable_history_list = 1; + } + init_noninteractive(); + startup_state = 1; + interactive_shell = startup_state; + expand_aliases = interactive_shell; + + remember_on_history = enable_history_list; + } //unsafe +} + +#[no_mangle] +pub fn get_current_user_info() { + unsafe { + let mut entry: *mut passwd = 0 as *mut passwd; + if (current_user.user_name).is_null() { + entry = getpwuid(current_user.uid) as *mut src_common::passwd; + if !entry.is_null() { + current_user.user_name = savestring!((*entry).pw_name); + current_user.shell = if !((*entry).pw_shell).is_null() + && *((*entry).pw_shell).offset(0 as isize) as libc::c_int != 0 + { + savestring!((*entry).pw_shell) + } else { + savestring!(b"/bin/sh\0" as *const u8 as *mut libc::c_char) + }; + current_user.home_dir = savestring!((*entry).pw_dir); + } else { + current_user.user_name = b"I have no name!\0" as *const u8 as *mut libc::c_char; + current_user.user_name = savestring!(current_user.user_name); + current_user.shell = savestring!(b"/bin/sh\0" as *const u8 as *const libc::c_char); + current_user.home_dir = savestring!(b"/\0" as *const u8 as *const libc::c_char); + } + endpwent(); + } + } //unsafe +} + +fn shell_initialize() { + unsafe { + let mut hostname: [libc::c_char; 256] = [0; 256]; + let mut should_be_restricted: libc::c_int = 0; + + if shell_initialized == 0 { + sh_setlinebuf(stderr); + sh_setlinebuf(stdout); + } + + initialize_shell_builtins(); + + initialize_traps(); + initialize_signals(0); + + if current_host_name.is_null() { + if gethostname(hostname.as_mut_ptr(), 255 as usize) < 0 { + current_host_name = b"??host??\0" as *const u8 as *mut libc::c_char; + } else { + current_host_name = savestring!(hostname.as_mut_ptr()); + } + } + if interactive_shell != 0 { + get_current_user_info(); + } + + tilde_initialize(); + + should_be_restricted = shell_is_restricted(shell_name); + + initialize_shell_variables( + shell_environment, + (privileged_mode != 0 + || restricted != 0 + || should_be_restricted != 0 + || running_setuid != 0) as libc::c_int, + ); + + initialize_job_control(jobs_m_flag); + + initialize_bash_input(); + + initialize_flags(); + + initialize_shell_options( + (privileged_mode != 0 + || restricted != 0 + || should_be_restricted != 0 + || running_setuid != 0) as libc::c_int, + ); + initialize_bashopts( + (privileged_mode != 0 + || restricted != 0 + || should_be_restricted != 0 + || running_setuid != 0) as libc::c_int, + ); + } //unsafe +} + +fn shell_reinitialize() { + unsafe { + primary_prompt = PPROMPT!(); + secondary_prompt = SPROMPT!(); + + current_command_number = 1; + + no_profile = 1; + no_rc = no_profile; + + executing = 0; + interactive = executing; + make_login_shell = interactive; + login_shell = make_login_shell; + + last_command_exit_value = 0; + line_number = last_command_exit_value; + do_version = line_number; + debugging = do_version; + + interactive_shell = 0; + forced_interactive = interactive_shell; + + running_in_background = 0; + subshell_environment = running_in_background; + + expand_aliases = 0; + bash_argv_initialized = 0; + + enable_history_list = 0; + bash_history_reinit(enable_history_list); + + restricted = 0; + bashrc_file = DEFAULT_BASHRC!(); + + delete_all_contexts(shell_variables); + delete_all_variables(shell_functions); + + reinit_special_variables(); + + bashline_reinitialize(); + + shell_reinitialized = 1; + } //unsafe +} + +fn show_shell_usage(fp: *mut FILE, extra: libc::c_int) { + unsafe { + let mut i: libc::c_int = 0; + let mut set_opts: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + if extra != 0 { + fprintf( + fp, + b"utshell, version %s-(%s)\n\0" as *const u8 as *const libc::c_char, + shell_version_string(), + MACHTYPE!(), + ); + } + fprintf( + fp, + b"Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n\0" as *const u8 as *const libc::c_char, + shell_name, + shell_name, + ); + fputs( + b"GNU long options:\n\0" as *const u8 as *const libc::c_char, + fp, + ); + + i = 0; + while !(long_args[i as usize].name).is_null() { + fprintf( + fp, + b"\t--%s\n\0" as *const u8 as *const libc::c_char, + long_args[i as usize].name, + ); + i += 1; + } + fputs( + b"Shell options:\n\0" as *const u8 as *const libc::c_char, + fp, + ); + fputs( + b"\t-ilrsD or -c command or -O shopt_option\t\t(invocation only)\n\0" as *const u8 + as *const libc::c_char, + fp, + ); + + i = 0; + set_opts = 0 as *mut libc::c_char; + while !((*shell_builtins.offset(i as isize)).name).is_null() { + if STREQ( + (*shell_builtins.offset(i as isize)).name, + b"set\0" as *const u8 as *const libc::c_char, + ) { + set_opts = savestring!((*shell_builtins.offset(i as isize)).short_doc); + break; + } else { + i += 1; + } + } + + if !set_opts.is_null() { + s = strchr(set_opts, '[' as i32); + if s.is_null() { + s = set_opts; + } + loop { + s = s.offset(1); + if !(*s as libc::c_int == '-' as i32) { + break; + } + } + t = strchr(s, ']' as i32); + if !t.is_null() { + *t = '\u{0}' as i32 as libc::c_char; + } + fprintf( + fp, + b"\t-%s or -o option\n\0" as *const u8 as *const libc::c_char, + s, + ); + + free(set_opts as *mut c_void); + } + + if extra != 0 { + fprintf( + fp, + b"Type `%s -c \"help set\"' for more information about shell options.\n\0" + as *const u8 as *const libc::c_char, + shell_name, + ); + fprintf( + fp, + b"Type `%s -c help' for more information about shell builtin commands.\n\0" + as *const u8 as *const libc::c_char, + shell_name, + ); + fprintf( + fp, + b"Use the `bashbug' command to report bugs.\n\0" as *const u8 + as *const libc::c_char, + ); + fprintf(fp, b"\n\0" as *const u8 as *const libc::c_char); + fprintf( + fp, + b"utshell home page: \n\0" as *const u8 + as *const libc::c_char, + ); + fprintf( + fp, + b"General help using GNU software: \n\0" as *const u8 + as *const libc::c_char, + ); + } + } //unsafe +} + +fn add_shopt_to_alist(opt: *mut libc::c_char, on_or_off: libc::c_int) { + unsafe { + if shopt_ind >= shopt_len { + shopt_len += 8; + shopt_alist = libc::realloc( + shopt_alist as *mut libc::c_void, + (shopt_len as usize) + .wrapping_mul(::std::mem::size_of::() as usize), + ) as *mut STRING_INT_ALIST; + } + + (*shopt_alist.offset(shopt_ind as isize)).word = opt; + (*shopt_alist.offset(shopt_ind as isize)).token = on_or_off; + shopt_ind += 1; + } //unsafe +} + +fn run_shopt_alist() { + unsafe { + let mut i: libc::c_int = 0; + + i = 0; + while i < shopt_ind { + if shopt_setopt( + (*shopt_alist.offset(i as isize)).word, + ((*shopt_alist.offset(i as isize)).token == '-' as i32) as libc::c_int, + ) != EXECUTION_SUCCESS as libc::c_int + { + exit(EX_BADUSAGE as libc::c_int); + } + i += 1; + } + free(shopt_alist as *mut c_void); + shopt_alist = 0 as *mut STRING_INT_ALIST; + shopt_len = 0; + shopt_ind = shopt_len; + } //unsafe +} +#[no_mangle] +pub fn r_main() { + //获å–å‘½ä»¤è¡Œå‚æ•° + let mut args: Vec<*mut libc::c_char> = Vec::new(); + for arg in ::std::env::args() { + args.push( + (::std::ffi::CString::new(arg)) + .expect("Failed to convert argument into CString.") + .into_raw(), + ); + } + args.push(::std::ptr::null_mut()); + + //获å–环境å˜é‡ + let mut vars: Vec<*mut libc::c_char> = Vec::new(); + for (var_name, var_value) in ::std::env::vars() { + let var: String = format!("{}={}", var_name, var_value); + vars.push( + (::std::ffi::CString::new(var)) + .expect("Failed to convert environment variable into CString.") + .into_raw(), + ); + } + vars.push(::std::ptr::null_mut()); + unsafe { + ::std::process::exit(main_0( + (args.len() - 1) as libc::c_int, + args.as_mut_ptr() as *mut *mut libc::c_char, + vars.as_mut_ptr() as *mut *mut libc::c_char, + ) as i32) + } +} diff --git a/utshell-0.5.0/src/variables.rs b/utshell-0.5.0/src/variables.rs new file mode 100644 index 00000000..0fa7b61a --- /dev/null +++ b/utshell-0.5.0/src/variables.rs @@ -0,0 +1,6747 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::alias::add_alias; +use crate::array::array_copy; +use crate::array::array_create; +use crate::arrayfunc::array_variable_name; +use crate::arrayfunc::array_variable_part; +use crate::arrayfunc::assign_array_element; +use crate::arrayfunc::bind_array_variable; +use crate::arrayfunc::convert_var_to_array; +use crate::arrayfunc::convert_var_to_assoc; +use crate::arrayfunc::make_array_variable_value; +use crate::arrayfunc::print_array_assignment; +use crate::arrayfunc::print_assoc_assignment; +use crate::arrayfunc::valid_array_reference; +use crate::assoc::assoc_dispose; +use crate::assoc::assoc_insert; +use crate::assoc::assoc_reference; +use crate::bashhist::history_number; +use crate::bashhist::setup_history_ignore; +use crate::bashline::clear_hostname_list; +use crate::bashline::enable_hostname_completion; +use crate::bashline::hostname_list_initialized; +use crate::bashline::posix_readline_initialize; +use crate::bashline::reset_completer_word_break_chars; +use crate::builtins::common::get_working_directory; +use crate::builtins::common::set_dollar_vars_unchanged; +use crate::builtins::common::set_working_directory; +use crate::builtins::common::sh_invalidid; +use crate::builtins::common::sh_notfound; +use crate::builtins::common::sh_readonly; +use crate::builtins::common::sh_restricted; +use crate::builtins::getopts::getopts_reset; +use crate::builtins::pushd::get_directory_stack; +use crate::builtins::pushd::set_dirstack_element; +use crate::builtins::set::set_current_options; +use crate::builtins::set::set_shellopts; +use crate::builtins::shopt::set_compatibility_opts; +use crate::copycmd::copy_function_def; +use crate::copycmd::copy_function_def_contents; +use crate::dispose_cmd::dispose_command; +use crate::dispose_cmd::dispose_function_def; +use crate::dispose_cmd::dispose_function_def_contents; +use crate::dispose_cmd::dispose_words; +use crate::execute_cmd::executing_line_number; +use crate::expr::evalexp; +use crate::findcmd::executable_file; +use crate::findcmd::file_status; +use crate::findcmd::find_user_command; +use crate::findcmd::setup_exec_ignore; +use crate::general::assignment; +use crate::general::file_isdir; +use crate::general::get_group_list; +use crate::general::same_file; +use crate::general::sh_validfd; +use crate::hashcmd::phash_flush; +use crate::hashcmd::phash_insert; +use crate::hashlib::hash_copy; +use crate::hashlib::hash_create; +use crate::hashlib::hash_dispose; +use crate::hashlib::hash_flush; +use crate::hashlib::hash_insert; +use crate::hashlib::hash_remove; +use crate::hashlib::hash_search; +use crate::jobs::set_maxchild; +use crate::local::locale_decpoint; +use crate::local::set_lang; +use crate::local::set_locale_var; +use crate::mailcheck::free_mail_files; +use crate::mailcheck::remember_mail_dates; +use crate::mailcheck::reset_mail_timer; +use crate::pathexp::setup_glob_ignore; +use crate::pcomplete::it_functions; +use crate::pcomplete::set_itemlist_dirty; +use crate::print_cmd::named_function_string; +use crate::print_cmd::xtrace_print_assignment; +use crate::print_cmd::xtrace_reset; +use crate::print_cmd::xtrace_set; +use crate::readline::absolute_program; +use crate::readline::all_digits; +use crate::readline::array_dispose; +use crate::readline::array_dispose_element; +use crate::readline::array_flush; +use crate::readline::array_from_word_list; +use crate::readline::array_insert; +use crate::readline::array_reference; +use crate::readline::array_rshift; +use crate::readline::array_shift; +use crate::readline::bash_tilde_expand; +use crate::readline::check_selfref; +use crate::readline::copy_command; +use crate::readline::environ; +use crate::readline::extract_colon_unit; +use crate::readline::full_pathname; +use crate::readline::history_comment_char; +use crate::readline::history_truncate_file; +use crate::readline::history_write_timestamps; +use crate::readline::legal_alias_name; +use crate::readline::legal_identifier; +use crate::readline::posix_initialize; +use crate::readline::rl_basic_word_break_characters; +use crate::readline::rl_completer_word_break_characters; +use crate::readline::rl_reset_terminal; +use crate::readline::save_posix_options; +use crate::readline::stifle_history; +use crate::readline::tzset; +use crate::readline::unstifle_history; +use crate::sig::jump_to_top_level; +use crate::sig::top_level_cleanup; +use crate::src_common::*; +use crate::subst::dequote_escapes; +use crate::subst::expand_assignment_string_to_string; +use crate::subst::invalidate_cached_quoted_dollar_at; +use crate::subst::list_rest_of_args; +use crate::subst::setifs; +use crate::version::build_version; +use crate::version::dist_version; +use crate::version::patch_level; +use crate::version::release_status; +use crate::version::shell_compatibility_level; +use crate::version::shell_version_string; +use crate::y_tab::eof_encountered; +use crate::y_tab::eof_encountered_limit; +use crate::y_tab::ignoreeof; +use crate::y_tab::line_number; +use crate::y_tab::line_number_base; +use std::convert::TryInto; + +//add by bgz +#[link(name = "history")] +#[link(name = "readline")] +extern "C" { + pub fn sh_get_home_dir() -> *mut libc::c_char; +} +//end of bgz + +#[no_mangle] +pub fn bind_spcial_variable( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, +) -> *mut libc::c_char { + unsafe { + if libc::strcmp(name, b"PS1\0" as *const u8 as *mut libc::c_char) == 0 { + if value.is_null() { + if current_user.euid == 0 { + value = Root_PS1_Value!(); + } else { + value = PS1_Value!(); + } + } + } + return value; + } +} + +#[no_mangle] +pub fn bind_variable( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut nvc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + unsafe { + value = bind_spcial_variable(name, value); + if shell_variables.is_null() { + create_variable_tables(); + } + if !temporary_env.is_null() && !value.is_null() { + bind_tempenv_variable(name, value); + } + vc = shell_variables; + while !vc.is_null() { + if vc_isfuncenv!(vc) || vc_isbltnenv!(vc) { + v = hash_lookup(name, (*vc).table); + nvc = vc; + + if !v.is_null() && nameref_p!(v) != 0 { + nv = find_variable_nameref_context(v, vc, &mut nvc); + if nv.is_null() { + nv = find_variable_last_nameref_context(v, vc, &mut nvc); + if !nv.is_null() && nameref_p!(nv) != 0 { + if nameref_cell!(nv).is_null() { + return bind_variable_internal( + (*nv).name, + value, + (*nvc).table, + 0 as libc::c_int, + flags, + ); + } else if valid_array_reference(nameref_cell!(nv), 0 as libc::c_int) + != 0 + { + return assign_array_element(nameref_cell!(nv), value, flags); + } else { + return bind_variable_internal( + nameref_cell!(nv), + value, + (*nvc).table, + 0 as libc::c_int, + flags, + ); + } + } else if nv == &mut nameref_maxloop_value as *mut SHELL_VAR { + internal_warning( + b"%s: circular name reference\0" as *const u8 + as *const libc::c_char, + (*v).name, + ); + return bind_global_variable((*v).name, value, flags); + } else { + v = nv; + } + } else if nv == &mut nameref_maxloop_value as *mut SHELL_VAR { + internal_warning( + b"%s: circular name reference\0" as *const u8 as *const libc::c_char, + (*v).name, + ); + return bind_global_variable((*v).name, value, flags); + } else { + v = nv; + } + } + + if !v.is_null() { + return bind_variable_internal( + (*v).name, + value, + (*nvc).table, + 0 as libc::c_int, + flags, + ); + } + } + + vc = (*vc).down; + } + + return bind_variable_internal( + name, + value, + (*global_variables).table, + 0 as libc::c_int, + flags, + ); + } +} + +fn STREQN(a: *const libc::c_char, b: *const libc::c_char, n: i32) -> bool { + unsafe { + if n == 0 { + return true; + } else { + return *a == *b && libc::strncmp(a, b, n as libc::size_t) == 0; + } + } +} + +fn STREQ(a: *const libc::c_char, b: *const libc::c_char) -> bool { + unsafe { + return (*a == *b) && (libc::strcmp(a, b) == 0); + } +} + +static mut nameref_maxloop_value: SHELL_VAR = SHELL_VAR { + name: 0 as *const libc::c_char as *mut libc::c_char, + value: 0 as *const libc::c_char as *mut libc::c_char, + exportstr: 0 as *const libc::c_char as *mut libc::c_char, + dynamic_value: None, + assign_func: None, + attributes: 0, + context: 0, +}; + +static mut last_table_searched: *mut HASH_TABLE = 0 as *const HASH_TABLE as *mut HASH_TABLE; + +#[inline] +fn atoi(mut __nptr: *const libc::c_char) -> libc::c_int { + unsafe { + return strtol( + __nptr, + 0 as *mut libc::c_void as *mut *mut libc::c_char, + 10 as libc::c_int, + ) as libc::c_int; + } +} + +fn create_variable_tables() { + unsafe { + if shell_variables.is_null() { + global_variables = new_var_context( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int, + ); + + shell_variables = global_variables; + (*shell_variables).scope = 0 as libc::c_int; + + (*shell_variables).table = hash_create(VARIABLES_HASH_BUCKETS!() as libc::c_int); + } + if shell_functions.is_null() { + shell_functions = hash_create(FUNCTIONS_HASH_BUCKETS!() as libc::c_int); + } + } +} + +#[no_mangle] +pub fn initialize_shell_variables(mut env: *mut *mut libc::c_char, mut privmode: libc::c_int) { + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp_string: *mut libc::c_char = 0 as *mut libc::c_char; + + let mut c: libc::c_int = 0; + let mut char_index: libc::c_int = 0; + let mut string_index: libc::c_int = 0; + let mut string_length: libc::c_int = 0; + let mut ro: libc::c_int = 0; + + let mut temp_var: *mut SHELL_VAR; + + create_variable_tables(); + + string_index = 0 as libc::c_int; + unsafe { + while !env.is_null() && { + string = *env.offset(string_index as isize); + string_index += 1; + !string.is_null() + } { + char_index = 0 as libc::c_int; + name = string; + + loop { + c = *string as libc::c_int; + string = string.offset(1); + // c != 0 && c != '=' as i32 进入循环 + if !(c != 0 && c != '=' as i32) { + break; + } + } + + if *string.offset(-(1 as libc::c_int) as isize) as libc::c_char == '=' as libc::c_char { + char_index = (string.offset_from(name) as libc::c_long + - 1 as libc::c_int as libc::c_long) as libc::c_int; + } + + if char_index == 0 as libc::c_int { + continue; + } + + *name.offset(char_index as isize) = '\0' as i32 as libc::c_char; + temp_var = 0 as *mut libc::c_void as *mut SHELL_VAR; + + if privmode == 0 as libc::c_int + && read_but_dont_execute == 0 as libc::c_int + && STREQN(BASHFUNC_PREFIX!(), name, BASHFUNC_PREFLEN!() as libc::c_int) + && STREQ( + BASHFUNC_SUFFIX!(), + name.offset((char_index - BASHFUNC_SUFFLEN!()) as libc::c_int as isize) + as *mut libc::c_char, + ) + && STREQN( + b"() {\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + string, + 4 as libc::c_int, + ) + { + let mut namelen: size_t = 0; + let mut tname: *mut libc::c_char = 0 as *mut libc::c_char; + namelen = (char_index - BASHFUNC_PREFLEN!() - BASHFUNC_SUFFLEN!()) as size_t; + tname = name.offset(BASHFUNC_PREFLEN!() as libc::c_int as isize); + *tname.offset(namelen as isize) = '\0' as i32 as libc::c_char; + + string_length = strlen(string) as libc::c_int; + + temp_string = libc::malloc( + (namelen + 2 as libc::c_int as size_t + string_length as u64) as usize, + ) as *mut libc::c_char; + + libc::memcpy( + temp_string as *mut libc::c_void, + tname as *const libc::c_void, + namelen as usize, + ); + + *temp_string.offset(namelen as isize) = ' ' as i32 as libc::c_char; + + libc::memcpy( + temp_string + .offset(namelen as isize) + .offset(1 as libc::c_int as isize) as *mut libc::c_void, + string as *const libc::c_void, + (string_length + 1 as libc::c_int) as usize, + ); + // absolute_program extern func + if absolute_program(tname) == 0 + && (posixly_correct == 0 || legal_identifier(tname) != 0) + { + // parse_and_execute extern func + parse_and_execute( + temp_string, + tname, + (SEVAL_NONINT as i32 + | SEVAL_NOHIST + | SEVAL_FUNCDEF as i32 + | SEVAL_ONECMD as i32) as libc::c_int, + ); + } else { + free(temp_string as *mut libc::c_void); + } + + temp_var = find_function(tname); + + if !temp_var.is_null() { + VSETATTR!(temp_var, (att_exported | att_imported) as libc::c_int); + array_needs_making = 1 as libc::c_int; + } else { + temp_var = bind_invalid_envvar(name, string, 0 as libc::c_int); + if !temp_var.is_null() { + VSETATTR!( + temp_var, + (att_exported | att_imported | att_invisible) as libc::c_int + ); + array_needs_making = 1 as libc::c_int; + } + last_command_exit_value = EXECUTION_FAILURE!(); + report_error( + b"error importing function definition for '%s'\0" as *const u8 + as *const libc::c_char as *mut libc::c_char, + tname, + ); + } + + *tname.offset(namelen as isize) = *BASHFUNC_SUFFIX!(); + } else { + ro = 0 as libc::c_int; + + if STREQ(name, b"SHELLOPTS\0" as *const u8 as *const libc::c_char) { + temp_var = find_variable( + b"SHELLOPTS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + ro = (!temp_var.is_null() && readonly_p!(temp_var) != 0) as libc::c_int; + if !temp_var.is_null() { + VUNSETATTR!(temp_var, att_readonly as libc::c_int); + } + } + + // legal_identifier .h 文件里定义 + if legal_identifier(name) != 0 as libc::c_int { + //bind_variable .h 文件里定义 + temp_var = bind_variable(name, string, 0 as libc::c_int); + + if !temp_var.is_null() { + VSETATTR!(temp_var, (att_exported | att_imported) as libc::c_int); + if ro != 0 { + VSETATTR!(temp_var, att_readonly as libc::c_int); + } + } + } else { + temp_var = bind_invalid_envvar(name, string, 0); + + if !temp_var.is_null() { + VSETATTR!( + temp_var, + (att_exported | att_imported | att_invisible) as libc::c_int + ); + } + } + + if !temp_var.is_null() { + array_needs_making = 1 as libc::c_int; + } + } + + *name.offset(char_index as isize) = '=' as i32 as libc::c_char; + if !temp_var.is_null() && function_p!(temp_var) == 0 { + CACHE_IMPORTSTR!(temp_var, name); + } + } + + set_pwd(); + + temp_var = set_if_not( + b"_\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + dollar_vars[0 as libc::c_int as usize], + ); + + dollar_dollar_pid = getpid(); + temp_var = set_if_not( + b"PATH\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + DEFAULT_PATH_VALUE!(), + ); + temp_var = set_if_not( + b"TERM\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"dumb\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + + set_if_not( + b"PS1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + primary_prompt, + ); + + //set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt); + set_if_not( + b"PS2\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + secondary_prompt, + ); + + if current_user.euid == 0 { + // h file aready define + bind_variable( + b"PS4\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"+ \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + } else { + set_if_not( + b"PS4\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"+ \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + + temp_var = bind_variable( + b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b" \t\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + + setifs(temp_var); + set_machine_vars(); + + if interactive_shell != 0 { + temp_var = set_if_not( + b"MAILCHECK\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + (if posixly_correct != 0 { + b"600\0" as *const u8 as *const libc::c_char + } else { + b"60\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char, + ); + VSETATTR!(temp_var, att_integer); + } + + initialize_shell_level(); + set_ppid(); + set_argv0(); + + temp_var = bind_variable( + b"OPTIND\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + VSETATTR!(temp_var, att_integer); + getopts_reset(0 as libc::c_int); + bind_variable( + b"OPTERR\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + b"1\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 0, + ); + sh_opterr = 1; + + if login_shell == 1 as libc::c_int && posixly_correct == 0 as libc::c_int { + set_home_var(); + } + + name = get_bash_name(); + temp_var = bind_variable( + b"BASH\0" as *const u8 as *const libc::c_char, + name, + 0 as libc::c_int, + ); + free(name as *mut libc::c_void); + + set_shell_var(); + bind_variable( + b"BASH_VERSION\0" as *const u8 as *const libc::c_char, + shell_version_string(), + 0 as libc::c_int, + ); + + make_vers_array(); + + if !command_execution_string.is_null() { + bind_variable( + b"BASH_EXECUTION_STRING\0" as *const u8 as *const libc::c_char, + command_execution_string, + 0 as libc::c_int, + ); + } + + temp_var = find_variable(b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char); + if temp_var.is_null() { + temp_var = find_variable(b"POSIX_PEDANTIC\0" as *const u8 as *const libc::c_char); + } + if !temp_var.is_null() && imported_p!(temp_var) as libc::c_int != 0 { + sv_strict_posix((*temp_var).name); + } + + if remember_on_history != 0 { + // extern c file + name = bash_tilde_expand( + if posixly_correct != 0 { + b"~/.sh_history\0" as *const u8 as *const libc::c_char + } else { + // b"~/.bash_history\0" as *const u8 as *const libc::c_char + b"~/.utshell_history\0" as *const u8 as *const libc::c_char + }, + 0 as libc::c_int, + ); + set_if_not( + b"HISTFILE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + name, + ); + free(name as *mut libc::c_void); + } + + // extern c file + seedrand(); + seedrand32(); + + if interactive_shell != 0 { + temp_var = find_variable(b"IGNOREEOF\0" as *const u8 as *const libc::c_char); + if temp_var.is_null() { + temp_var = find_variable(b"ignoreeof\0" as *const u8 as *const libc::c_char); + } + if !temp_var.is_null() && imported_p!(temp_var) != 0 as libc::c_int { + sv_ignoreeof((*temp_var).name); + } + } + + if interactive_shell != 0 && remember_on_history != 0 { + sv_history_control( + b"HISTCONTROL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + sv_histignore(b"HISTIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + sv_histtimefmt( + b"HISTTIMEFORMAT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + + uidset(); + + temp_var = find_variable(b"BASH_XTRACEFD\0" as *const u8 as *const libc::c_char); + if !temp_var.is_null() && imported_p!(temp_var) as libc::c_int != 0 { + sv_xtracefd((*temp_var).name); + } + } + sv_shcompat(b"BASH_COMPAT\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + + sv_funcnest(b"FUNCNEST\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + + initialize_dynamic_variables(); +} + +fn set_machine_vars() { + let mut temp_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + temp_var = set_if_not( + b"HOSTTYPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + get_host_type() as *mut libc::c_char, + ); + + temp_var = set_if_not( + b"OSTYPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + get_os_type() as *mut libc::c_char, + ); + + temp_var = set_if_not( + b"MACHTYPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + get_mach_type() as *mut libc::c_char, + ); + + temp_var = set_if_not( + b"HOSTNAME\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + current_host_name, + ); + } +} + +#[no_mangle] +fn set_home_var() { + let mut temp_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + temp_var = find_variable(b"HOME\0" as *const u8 as *const libc::c_char); + unsafe { + if temp_var.is_null() { + temp_var = bind_variable( + b"HOME\0" as *const u8 as *const libc::c_char, + sh_get_home_dir(), + 0 as libc::c_int, + ); + } + } +} + +fn set_shell_var() { + let mut temp_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + temp_var = find_variable(b"SHELL\0" as *const u8 as *const libc::c_char); + unsafe { + if temp_var.is_null() { + if (current_user.shell).is_null() { + // get_current_user_info in file of shell.c + get_current_user_info(); + } + temp_var = bind_variable( + b"SHELL\0" as *const u8 as *const libc::c_char, + current_user.shell, + 0 as libc::c_int, + ); + } + } +} + +fn get_bash_name() -> *mut libc::c_char { + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if login_shell == 1 as libc::c_int && RELPATH!(shell_name) { + if (current_user.shell).is_null() { + // get_current_user_info in file of shell.c + get_current_user_info(); + } + name = savestring!(current_user.shell); + } else if ABSPATH!(shell_name) { + name = savestring!(shell_name); + } else if *shell_name.offset(0 as libc::c_int as isize) as libc::c_int == '.' as i32 + && *shell_name.offset(1 as libc::c_int as isize) as libc::c_int == '/' as i32 + { + let mut cdir: *mut libc::c_char = 0 as *mut libc::c_char; + let mut len: libc::c_int = 0; + + cdir = get_string_value(b"PWD\0" as *const u8 as *const libc::c_char); + if !cdir.is_null() { + len = strlen(cdir) as libc::c_int; + name = libc::malloc( + (len as isize + strlen(shell_name) as isize + 1 as libc::c_int as isize) + .try_into() + .unwrap(), + ) as *mut libc::c_char; + strcpy(name, cdir); + strcpy( + name.offset(len as isize), + shell_name.offset(1 as libc::c_int as isize), + ); + } else { + name = savestring!(shell_name); + } + } else { + let mut tname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: libc::c_int = 0; + tname = find_user_command(shell_name); + if tname.is_null() { + s = file_status(shell_name); + if s & FS_EXECABLE as libc::c_int != 0 { + tname = make_absolute( + shell_name, + get_string_value(b"PWD\0" as *const u8 as *const libc::c_char), + ); + if *shell_name as libc::c_int == '.' as i32 { + //sh_canonpath in extern file + name = sh_canonpath( + tname, + (PATH_CHECKDOTDOT | PATH_CHECKEXISTS) as libc::c_int, + ); + if name.is_null() { + name = tname; + } else { + free(tname as *mut libc::c_void); + } + } else { + name = tname; + } + } else { + if (current_user.shell).is_null() { + // get_current_user_info in file of shell.c + get_current_user_info(); + } + name = savestring!(current_user.shell); + } + } else { + name = full_pathname(tname); + free(tname as *mut libc::c_void); + } + } + } + return name; +} + +#[no_mangle] +pub fn adjust_shell_level(mut change: libc::c_int) { + let mut new_level: [libc::c_char; 5] = [0; 5]; + let mut old_SHLVL: *mut libc::c_char = 0 as *mut libc::c_char; + let mut old_level: intmax_t = 0; + let mut temp_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + old_SHLVL = get_string_value(b"SHLVL\0" as *const u8 as *const libc::c_char); + unsafe { + if old_SHLVL.is_null() + || *old_SHLVL as libc::c_int == '\0' as i32 + || legal_number(old_SHLVL, &mut old_level) == 0 as libc::c_int + { + old_level = 0 as libc::c_int as intmax_t; + } + shell_level = (old_level + change as libc::c_long) as libc::c_int; + if shell_level < 0 as libc::c_int { + shell_level = 0 as libc::c_int; + } else if shell_level >= 1000 as libc::c_int { + internal_warning( + 0 as *const libc::c_char, + b"shell level (%d) too high, resetting to 1\0" as *const u8 as *const libc::c_char, + shell_level, + ); + shell_level = 1 as libc::c_int; + } + if shell_level < 10 as libc::c_int { + new_level[0 as libc::c_int as usize] = (shell_level + '0' as i32) as libc::c_char; + new_level[1 as libc::c_int as usize] = '\0' as i32 as libc::c_char; + } else if shell_level < 100 as libc::c_int { + new_level[0 as libc::c_int as usize] = + (shell_level / 10 as libc::c_int + '0' as i32) as libc::c_char; + new_level[1 as libc::c_int as usize] = + (shell_level % 10 as libc::c_int + '0' as i32) as libc::c_char; + new_level[2 as libc::c_int as usize] = '\0' as i32 as libc::c_char; + } else if shell_level < 1000 as libc::c_int { + new_level[0 as libc::c_int as usize] = + (shell_level / 100 as libc::c_int + '0' as i32) as libc::c_char; + old_level = (shell_level % 100 as libc::c_int) as intmax_t; + new_level[1 as libc::c_int as usize] = (old_level / 10 as libc::c_int as libc::c_long + + '0' as i32 as libc::c_long) + as libc::c_char; + new_level[2 as libc::c_int as usize] = (old_level % 10 as libc::c_int as libc::c_long + + '0' as i32 as libc::c_long) + as libc::c_char; + new_level[3 as libc::c_int as usize] = '\0' as i32 as libc::c_char; + } + + temp_var = bind_variable( + b"SHLVL\0" as *const u8 as *const libc::c_char, + new_level.as_mut_ptr(), + 0 as libc::c_int, + ); + + set_auto_export!(temp_var); + } +} + +fn initialize_shell_level() { + adjust_shell_level(1 as libc::c_int); +} + +#[no_mangle] +pub fn set_pwd() { + let mut temp_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut home_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut temp_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut home_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut current_dir: *mut libc::c_char = 0 as *mut libc::c_char; + home_var = find_variable(b"HOME\0" as *const u8 as *const libc::c_char); + unsafe { + home_string = if !home_var.is_null() { + value_cell!(home_var) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + + temp_var = find_variable(b"PWD\0" as *const u8 as *const libc::c_char); + + if !temp_var.is_null() + && imported_p!(temp_var) != 0 as libc::c_int + && { + temp_string = value_cell!(temp_var); + !temp_string.is_null() + } + && *temp_string as libc::c_int == '/' as i32 + && same_file( + temp_string, + b".\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut crate::src_common::stat, + 0 as *mut libc::c_void as *mut crate::src_common::stat, + ) != 0 + { + // sh_canonpath are extern func + current_dir = sh_canonpath( + temp_string, + PATH_CHECKDOTDOT as libc::c_int | PATH_CHECKEXISTS as libc::c_int, + ); + + if current_dir.is_null() { + // get_working_directory are extern func + current_dir = get_working_directory( + b"shell_init\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else { + // set_working_directory are extern func + set_working_directory(current_dir); + } + if posixly_correct != 0 && !current_dir.is_null() { + //bind_variable are extern func + temp_var = bind_variable( + b"PWD\0" as *const u8 as *const libc::c_char, + current_dir, + 0 as libc::c_int, + ); + set_auto_export!(temp_var); + } + free(current_dir as *mut libc::c_void); + } else if !home_string.is_null() + && interactive_shell != 0 + && login_shell != 0 + && same_file( + home_string, + b".\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut crate::src_common::stat, + 0 as *mut libc::c_void as *mut crate::src_common::stat, + ) != 0 + { + // set_working_directory are extern func + set_working_directory(home_string); + + //bind_variable are extern func + temp_var = bind_variable( + b"PWD\0" as *const u8 as *const libc::c_char, + home_string, + 0 as libc::c_int, + ); + set_auto_export!(temp_var); + } else { + // get_working_directory are extern func + temp_string = get_working_directory( + b"shell-init\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + + if !temp_string.is_null() { + temp_var = bind_variable( + b"PWD\0" as *const u8 as *const libc::c_char, + temp_string, + 0 as libc::c_int, + ); + set_auto_export!(temp_var); + free(temp_string as *mut libc::c_void); + } + } + + temp_var = find_variable(b"OLDPWD\0" as *const u8 as *const libc::c_char); + if temp_var.is_null() + || value_cell!(temp_var).is_null() + || file_isdir(value_cell!(temp_var)) == 0 as libc::c_int + { + temp_var = bind_variable( + b"OLDPWD\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int, + ); + + VSETATTR!(temp_var, (att_exported | att_invisible)); + } + } +} + +#[no_mangle] +pub fn set_ppid() { + // æš‚æ—¶å®šä¹‰çš„å® æœ‰é—®é¢˜ 还得修改 + let mut namebuf: [libc::c_char; (INT_STRLEN_BOUND!(uid_t) + 1) as usize] = + [0; (INT_STRLEN_BOUND!(uid_t) + 1) as usize]; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp_var: *mut SHELL_VAR; + unsafe { + name = inttostr( + getppid() as intmax_t, + namebuf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(uid_t) + 1) as usize]>() + as libc::c_ulong as size_t, + ); + temp_var = find_variable(b"PPID\0" as *const u8 as *const libc::c_char); + if !temp_var.is_null() { + VUNSETATTR!(temp_var, (att_readonly | att_exported)); + } + + temp_var = bind_variable( + b"PPID\0" as *const u8 as *const libc::c_char, + name, + 0 as libc::c_int, + ); + + VSETATTR!(temp_var, (att_readonly | att_integer)); + } +} + +fn uidset() { + // INT_STRLEN_BOUND(uid_t) + 1 + let mut buff: [libc::c_char; (INT_STRLEN_BOUND!(uid_t) + 1) as usize] = + [0; (INT_STRLEN_BOUND!(uid_t) + 1) as usize]; + let mut b: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + b = inttostr( + current_user.uid as intmax_t, + buff.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(uid_t) + 1) as usize]>() + as libc::c_ulong as size_t, + ); + v = find_variable(b"UID\0" as *const u8 as *const libc::c_char); + if v.is_null() { + v = bind_variable( + b"UID\0" as *const u8 as *const libc::c_char, + b, + 0 as libc::c_int, + ); + VSETATTR!(v, (att_readonly | att_integer) as libc::c_int); + } + if current_user.euid != current_user.uid { + b = inttostr( + current_user.euid as intmax_t, + buff.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(uid_t) + 1) as usize]>() + as libc::c_ulong as size_t, + ); + } + v = find_variable(b"EUID\0" as *const u8 as *const libc::c_char); + if v.is_null() { + v = bind_variable( + b"EUID\0" as *const u8 as *const libc::c_char, + b, + 0 as libc::c_int, + ); + VSETATTR!(v, (att_readonly | att_integer)); + } + } +} + +fn make_vers_array() { + let mut vv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut av: *mut ARRAY = 0 as *mut ARRAY; + + let mut s: *mut libc::c_char = 0 as *mut libc::c_char; + let mut d: [libc::c_char; 32] = [0; 32]; + + const b: [libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize] = + [0 as libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]; + unbind_variable_noref(b"BASH_VERSINFO\0" as *const u8 as *const libc::c_char); + + vv = make_new_array_variable( + b"BASH_VERSINFO\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + unsafe { + av = array_cell!(vv); + strcpy(d.as_mut_ptr(), dist_version); + s = libc::strchr(d.as_mut_ptr(), '.' as i32); + if !s.is_null() { + *s = '\0' as i32 as libc::c_char; + s = s.offset(1 as isize); + } + array_insert(av, 0 as libc::c_int as arrayind_t, d.as_mut_ptr()); + array_insert(av, 1 as libc::c_int as arrayind_t, s); + + s = inttostr( + patch_level as intmax_t, + b.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>() + as libc::c_ulong as u64, + ); + array_insert(av, 2 as libc::c_int as arrayind_t, s); + s = inttostr( + build_version as intmax_t, + b.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>() + as libc::c_ulong as u64, + ); + array_insert(av, 3 as libc::c_int as arrayind_t, s); + array_insert( + av, + 4 as libc::c_int as arrayind_t, + release_status as *mut libc::c_char, + ); + array_insert(av, 5 as libc::c_int as arrayind_t, get_mach_type()); + VSETATTR!(vv, att_readonly); + } +} + +#[no_mangle] +pub fn sh_set_lines_and_columns_out(mut lines: libc::c_int, mut cols: libc::c_int) { + let mut val: [libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize] = + [0 as libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]; + + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if winsize_assignment != 0 { + return; + } + + v = inttostr( + lines as intmax_t, + val.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>() + as libc::c_ulong as u64, + ); + + bind_variable( + b"LINES\0" as *const u8 as *const libc::c_char, + v, + 0 as libc::c_int, + ); + v = inttostr( + cols as intmax_t, + val.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>() + as libc::c_ulong as u64, + ); + bind_variable( + b"COLUMNS\0" as *const u8 as *const libc::c_char, + v, + 0 as libc::c_int, + ); + } +} + +#[no_mangle] +pub fn print_var_list(mut list: *mut *mut SHELL_VAR) { + let mut i: libc::c_int = 0 as libc::c_int; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + while !list.is_null() && { + var = *list.offset(i as isize); + !var.is_null() + } { + if invisible_p!(var) == 0 { + print_assignment(var); + } + i += 1; + } + } +} + +#[no_mangle] +pub fn print_func_list(mut list: *mut *mut SHELL_VAR) { + let mut i: libc::c_int = 0; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + i = 0 as libc::c_int; + unsafe { + while !list.is_null() && { + var = *list.offset(i as isize); + !var.is_null() + } { + libc::printf(b"%s \0" as *const u8 as *const libc::c_char, (*var).name); + print_var_function(var); + libc::printf(b"\n\0" as *const u8 as *const libc::c_char); + i += 1; + } + } +} + +#[no_mangle] +pub fn print_assignment(var: *mut SHELL_VAR) { + unsafe { + if !var_isset!(var) { + return; + } + if function_p!(var) != 0 { + libc::printf(b"%s\0" as *const u8 as *const libc::c_char, (*var).name); + print_var_function(var); + libc::printf(b"\n\0" as *const u8 as *const libc::c_char); + } else if array_p!(var) != 0 { + print_array_assignment(var, 0 as libc::c_int); + } else if assoc_p!(var) != 0 { + print_assoc_assignment(var, 0 as libc::c_int); + } else { + libc::printf(b"%s=\0" as *const u8 as *const libc::c_char, (*var).name); + print_var_value(var, 1 as libc::c_int); + libc::printf(b"\n\0" as *const u8 as *const libc::c_char); + } + } +} + +pub fn print_var_value(mut var: *mut SHELL_VAR, mut quote: libc::c_int) { + unsafe { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + if !var_isset!(var) { + return; + } + if quote != 0 + && posixly_correct == 0 as libc::c_int + && ansic_shouldquote(value_cell!(var)) != 0 + { + t = ansic_quote(value_cell!(var), 0 as libc::c_int, 0 as *mut libc::c_int); + libc::printf(b"%s\0" as *const u8 as *const libc::c_char, t); + if !t.is_null() { + libc::free(t as *mut libc::c_void); + } + } else if quote != 0 && sh_contains_shell_metas(value_cell!(var)) != 0 { + t = sh_single_quote(value_cell!(var)); + libc::printf(b"%s\0" as *const u8 as *const libc::c_char, t); + if !t.is_null() { + libc::free(t as *mut libc::c_void); + } + } else { + libc::printf( + b"%s\0" as *const u8 as *const libc::c_char, + value_cell!(var), + ); + }; + } +} + +#[no_mangle] +pub fn print_var_function(mut var: *mut SHELL_VAR) { + unsafe { + let mut x: *mut libc::c_char = 0 as *mut libc::c_char; + if function_p!(var) != 0 as libc::c_int && var_isset!(var) { + x = named_function_string( + 0 as *mut libc::c_void as *mut libc::c_char, + function_cell!(var), + (FUNC_MULTILINE | FUNC_EXTERNAL) as libc::c_int, + ); + libc::printf(b"%s\0" as *const u8 as *const libc::c_char, x); + } + } +} + +fn null_assign( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + return self_0; +} + +fn null_array_assign( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut ind: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + return self_0; +} + +fn get_self(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + return self_0; +} + +fn init_dynamic_array_var( + mut name: *mut libc::c_char, + mut getfunc: Option, + mut setfunc: Option, + mut attrs: libc::c_int, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(name); + if !v.is_null() { + return v; + } + unsafe { + INIT_DYNAMIC_ARRAY_VAR!(v, name, getfunc, setfunc); + if attrs != 0 { + VSETATTR!(v, attrs); + } + } + return v; +} + +fn init_dynamic_assoc_var( + mut name: *mut libc::c_char, + mut getfunc: Option, + mut setfunc: Option, + mut attrs: libc::c_int, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(name); + if !v.is_null() { + return v; + } + unsafe { + INIT_DYNAMIC_ASSOC_VAR!(v, name, getfunc, setfunc); + + if attrs != 0 { + VSETATTR!(v, attrs); + } + } + return v; +} + +static mut seconds_value_assigned: intmax_t = 0; + +fn assign_seconds( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut nval: intmax_t = 0; + let mut expok: libc::c_int = 0; + unsafe { + if integer_p!(self_0) != 0 as libc::c_int { + nval = evalexp(value, 0 as libc::c_int, &mut expok); + } else { + expok = legal_number(value, &mut nval); + } + seconds_value_assigned = if expok != 0 { + nval + } else { + 0 as libc::c_int as libc::c_long + }; + gettimeofday(&mut shellstart, 0 as *mut crate::src_common::timezone); + shell_start_time = shellstart.tv_sec; + } + return self_0; +} + +fn get_seconds(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut time_since_start: time_t = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tv: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + unsafe { + gettimeofday(&mut tv, 0 as *mut crate::src_common::timezone); + time_since_start = tv.tv_sec - shell_start_time; + + p = itos(seconds_value_assigned + time_since_start); + if !(value_cell!(var).is_null()) { + libc::free(value_cell!(var) as *mut libc::c_void); + } + VSETATTR!(var, att_integer); + var_setvalue!(var, p); + } + return var; +} + +fn init_seconds_var() -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + v = find_variable(b"SECONDS\0" as *const u8 as *const libc::c_char); + unsafe { + if !v.is_null() { + if legal_number(value_cell!(v), &mut seconds_value_assigned) == 0 as libc::c_int { + seconds_value_assigned = 0 as libc::c_int as intmax_t; + } + } + if !v.is_null() { + INIT_DYNAMIC_VAR!( + v, + b"SECONDS\0" as *const u8 as *const libc::c_char, + value_cell!(v), + Some(get_seconds), + Some(assign_seconds) + ); + } else { + INIT_DYNAMIC_VAR!( + v, + b"SECONDS\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_seconds), + Some(assign_seconds) + ); + } + } + return v; +} + +#[no_mangle] +pub static mut last_random_value: libc::c_int = 0; +static mut seeded_subshell: libc::c_int = 0 as libc::c_int; + +fn assign_random( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut seedval: intmax_t = 0; + let mut expok: libc::c_int = 0; + unsafe { + if integer_p!(self_0) != 0 { + seedval = evalexp(value, 0 as libc::c_int, &mut expok); + } else { + expok = legal_number(value, &mut seedval); + } + if expok == 0 as libc::c_int { + return self_0; + } + sbrand(seedval as libc::c_ulong); + if subshell_environment != 0 { + seeded_subshell = getpid(); + } + } + return self_0; +} + +#[no_mangle] +pub fn get_random_number() -> libc::c_int { + let mut rv: libc::c_int = 0; + let mut pid: libc::c_int = 0; + unsafe { + pid = getpid(); + if subshell_environment != 0 && seeded_subshell != pid { + seedrand(); + seeded_subshell = pid; + } + loop { + rv = brand(); + if rv == last_random_value { + break; + } + } + last_random_value = rv; + return last_random_value; + } +} + +fn get_random(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut rv: libc::c_int = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + rv = get_random_number(); + unsafe { + p = itos(rv as intmax_t); + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + + VSETATTR!(var, att_integer); + var_setvalue!(var, p); + } + return var; +} + +#[no_mangle] +pub fn get_urandom(var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut rv: libc::c_uint = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + rv = get_urandom32(); + p = itos(rv as intmax_t); + if !(value_cell!(var)).is_null() { + libc::free(value_cell!(var) as *mut libc::c_void); + } + VSETATTR!(var, att_integer); + var_setvalue!(var, p); + } + return var; +} + +fn assign_lineno( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut new_value: intmax_t = 0; + unsafe { + if value.is_null() + || *value as libc::c_int == '\0' as i32 + || legal_number(value, &mut new_value) == 0 as libc::c_int + { + new_value = 0 as libc::c_int as intmax_t; + } + line_number_base = new_value as libc::c_int; + line_number = line_number_base; + } + return var; +} + +fn get_lineno(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ln: libc::c_int = 0; + ln = executing_line_number(); + unsafe { + p = itos(ln as intmax_t); + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +fn assign_subshell( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut new_value: intmax_t = 0; + unsafe { + if value.is_null() + || *value as libc::c_int == '\0' as i32 + || legal_number(value, &mut new_value) == 0 as libc::c_int + { + new_value = 0 as libc::c_int as intmax_t; + } + subshell_level = new_value as libc::c_int; + } + return var; +} + +fn get_subshell(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + p = itos(subshell_level as intmax_t); + if !(value_cell!(var).is_null()) { + libc::free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +fn get_epochseconds(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut now: intmax_t = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + now = NOW!(); + p = itos(now); + if !(value_cell!(var).is_null()) { + libc::free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +fn get_epochrealtime(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut buf: [libc::c_char; 32] = [0; 32]; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tv: crate::src_common::timeval = crate::src_common::timeval { + tv_sec: 0, + tv_usec: 0, + }; + unsafe { + gettimeofday(&mut tv, 0 as *mut crate::src_common::timezone); + libc::snprintf( + buf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; 32]>() as usize, + b"%u%c%06u\0" as *const u8 as *const libc::c_char, + tv.tv_sec as libc::c_uint, + locale_decpoint(), + tv.tv_usec as libc::c_uint, + ); + p = savestring!(&mut buf[0]); + if !(value_cell!(var).is_null()) { + libc::free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +fn get_bashpid(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut pid: libc::c_int = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + pid = getpid(); + p = itos(pid as intmax_t); + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +fn get_bash_argv0(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + p = savestring!(dollar_vars[0]); + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +static mut static_shell_name: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; + +fn assign_bash_argv0( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut vlen: size_t = 0; + if value.is_null() { + return var; + } + unsafe { + if !(dollar_vars[0 as libc::c_int as usize]).is_null() { + libc::free(dollar_vars[0 as libc::c_int as usize] as *mut libc::c_void); + } + dollar_vars[0 as libc::c_int as usize] = 0 as *mut libc::c_char; + dollar_vars[0 as libc::c_int as usize] = savestring!(value); + + vlen = STRLEN!(value) as size_t; + static_shell_name = libc::realloc( + static_shell_name as *mut libc::c_void, + (vlen + 1) as libc::c_int as usize, + ) as *mut libc::c_char; + strcpy(static_shell_name, value); + shell_name = static_shell_name; + } + return var; +} + +fn set_argv0() { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(b"BASH_ARGV0\0" as *const u8 as *const libc::c_char); + unsafe { + if !v.is_null() && imported_p!(v) != 0 { + assign_bash_argv0( + v, + value_cell!(v), + 0 as libc::c_int as arrayind_t, + 0 as *mut libc::c_char, + ); + } + } +} + +fn get_bash_command(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if !the_printed_command_except_trap.is_null() { + p = savestring!(the_printed_command_except_trap); + } else { + p = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *p = '\0' as i32 as libc::c_char; + } + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + + var_setvalue!(var, p); + } + return var; +} + +fn get_histcmd(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut n: libc::c_int = 0; + unsafe { + n = history_number() - executing; + p = itos(n as intmax_t); + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, p); + } + return var; +} + +fn get_comp_wordbreaks(mut var: *mut SHELL_VAR) -> *mut SHELL_VAR { + unsafe { + if rl_completer_word_break_characters.is_null() + && bash_readline_initialized == 0 as libc::c_int + { + enable_hostname_completion(perform_hostname_completion); + } + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, savestring!(rl_completer_word_break_characters)); + } + return var; +} + +fn assign_comp_wordbreaks( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut unused: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + unsafe { + if !rl_completer_word_break_characters.is_null() + && rl_completer_word_break_characters + != rl_basic_word_break_characters as *mut libc::c_char + { + free(rl_completer_word_break_characters as *mut libc::c_void); + } + rl_completer_word_break_characters = savestring!(value); + } + return self_0; +} + +fn assign_dirstack( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut ind: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + set_dirstack_element(ind, 1 as libc::c_int, value); + return self_0; +} + +fn get_dirstack(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + l = get_directory_stack(0 as libc::c_int); + unsafe { + a = array_from_word_list(l); + array_dispose((*self_0).value as *mut ARRAY); + dispose_words(l); + + var_setarray!(self_0, a); + } + return self_0; +} + +fn get_groupset(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut i: libc::c_int = 0; + let mut ng: libc::c_int = 0; + let mut a: *mut ARRAY = 0 as *mut ARRAY; + static mut group_set: *mut *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut *mut libc::c_char; + unsafe { + if group_set.is_null() { + group_set = get_group_list(&mut ng); + a = array_cell!(self_0); + i = 0 as libc::c_int; + while i < ng { + array_insert(a, i as arrayind_t, *group_set.offset(i as isize)); + i += 1; + i; + } + } + } + return self_0; +} + +fn get_bashargcv(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + static mut self_semaphore: libc::c_int = 0 as libc::c_int; + unsafe { + if self_semaphore == 0 as libc::c_int + && variable_context == 0 as libc::c_int + && debugging_mode == 0 as libc::c_int + { + self_semaphore = 1 as libc::c_int; + init_bash_argv(); + self_semaphore = 0 as libc::c_int; + } + } + return self_0; +} + +fn build_hashcmd(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut i: libc::c_int = 0; + let mut k: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + h = assoc_cell!(self_0); + + if !h.is_null() { + assoc_dispose(h); + } + + if hashed_filenames.is_null() || HASH_ENTRIES!(hashed_filenames) == 0 { + var_setvalue!(self_0, 0 as *mut libc::c_char); + return self_0; + } + + h = assoc_create!((*hashed_filenames).nbuckets); + + i = 0 as libc::c_int; + + while i < (*hashed_filenames).nbuckets { + item = hash_items!(i, hashed_filenames); + while !item.is_null() { + k = savestring!((*item).key); + v = (*((*item).data as *mut PATH_DATA)).path; + assoc_insert(h, k, v); + item = (*item).next; + } + i += 1; + i; + } + var_setvalue!(self_0, h as *mut libc::c_char); + } + return self_0; +} + +fn get_hashcmd(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + build_hashcmd(self_0); + return self_0; +} + +fn assign_hashcmd( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut ind: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut full_path: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + if restricted != 0 { + if !(libc::strchr(value, '/' as i32).is_null()) { + sh_restricted(value); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + full_path = find_user_command(value); + if full_path.is_null() + || *full_path as libc::c_int == 0 as libc::c_int + || executable_file(full_path) == 0 as libc::c_int + { + sh_notfound(value); + libc::free(full_path as *mut libc::c_void); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + libc::free(full_path as *mut libc::c_void); + } + phash_insert(key, value, 0 as libc::c_int, 0 as libc::c_int); + } + return build_hashcmd(self_0); +} + +fn build_aliasvar(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut h: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut i: libc::c_int = 0; + let mut k: *mut libc::c_char = 0 as *mut libc::c_char; + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + let mut item: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + h = assoc_cell!(self_0); + + if !h.is_null() { + assoc_dispose(h); + } + if aliases.is_null() || HASH_ENTRIES!(aliases) == 0 { + var_setvalue!(self_0, 0 as *mut libc::c_void as *mut libc::c_char); + return self_0; + } + h = assoc_create!((*aliases).nbuckets); + + i = 0 as libc::c_int; + while i < (*aliases).nbuckets { + item = if !aliases.is_null() && i < (*aliases).nbuckets { + *((*aliases).bucket_array).offset(i as isize) + } else { + 0 as *mut libc::c_void as *mut BUCKET_CONTENTS + }; + while !item.is_null() { + k = savestring!((*item).key); + v = (*((*item).data as *mut alias_t)).value; + assoc_insert(h, k, v); + item = (*item).next; + } + i += 1; + i; + } + var_setvalue!(self_0, h as *mut libc::c_char); + } + return self_0; +} + +fn get_aliasvar(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + build_aliasvar(self_0); + return self_0; +} + +fn assign_aliasvar( + mut self_0: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut ind: arrayind_t, + mut key: *mut libc::c_char, +) -> *mut SHELL_VAR { + unsafe { + if legal_alias_name(key, 0 as libc::c_int) == 0 as libc::c_int { + report_error( + b"'%s': invalid alias name\0" as *const u8 as *const libc::c_char, + key, + ); + return self_0; + } + + add_alias(key, value); + return build_aliasvar(self_0); + } +} + +fn get_funcname(mut self_0: *mut SHELL_VAR) -> *mut SHELL_VAR { + return self_0; +} + +#[no_mangle] +pub fn make_funcname_visible(mut on_or_off: libc::c_int) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(b"FUNCNAME\0" as *const u8 as *const libc::c_char); + unsafe { + if v.is_null() || !((*v).dynamic_value).is_some() { + return; + } + if on_or_off != 0 { + VUNSETATTR!(v, att_invisible); + } else { + VSETATTR!(v, att_invisible); + }; + } +} + +fn init_funcname_var() -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(b"FUNCNAME\0" as *const u8 as *const libc::c_char); + if !v.is_null() { + return v; + } + unsafe { + INIT_DYNAMIC_ARRAY_VAR!( + v, + b"FUNCNAME\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_funcname), + Some(null_array_assign) + ); + + VSETATTR!(v, att_invisible | att_noassign); + } + return v; +} + +fn initialize_dynamic_variables() { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + v = init_seconds_var(); + unsafe { + INIT_DYNAMIC_VAR!( + v, + b"BASH_ARGV0\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_bash_argv0), + Some(assign_bash_argv0) + ); + + INIT_DYNAMIC_VAR!( + v, + b"BASH_COMMAND\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_bash_command), + std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void + ) + ); + + INIT_DYNAMIC_VAR!( + v, + b"BASH_SUBSHELL\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_subshell), + Some(assign_subshell) + ); + + INIT_DYNAMIC_VAR!( + v, + b"RANDOM\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_random), + Some(assign_random) + ); + + VSETATTR!(v, att_integer); + + INIT_DYNAMIC_VAR!( + v, + b"SRANDOM\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_urandom), + std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void + ) + ); + + VSETATTR!(v, att_integer); + + INIT_DYNAMIC_VAR!( + v, + b"LINENO\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_lineno), + Some(assign_lineno) + ); + + VSETATTR!(v, att_regenerate); + + INIT_DYNAMIC_VAR!( + v, + b"BASHPID\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_bashpid), + Some(null_assign) + ); + + VSETATTR!(v, att_integer); + + INIT_DYNAMIC_VAR!( + v, + b"EPOCHSECONDS\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_epochseconds), + Some(null_assign) + ); + + VSETATTR!(v, att_regenerate); + + INIT_DYNAMIC_VAR!( + v, + b"EPOCHREALTIME\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_epochrealtime), + Some(null_assign) + ); + + VSETATTR!(v, att_regenerate); + + INIT_DYNAMIC_VAR!( + v, + b"HISTCMD\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_histcmd), + std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void + ) + ); + + VSETATTR!(v, att_integer); + + INIT_DYNAMIC_VAR!( + v, + b"COMP_WORDBREAKS\0" as *const u8 as *const libc::c_char, + 0 as *mut libc::c_void as *mut libc::c_char, + Some(get_comp_wordbreaks), + Some(assign_comp_wordbreaks) + ); + + v = init_dynamic_array_var( + b"DIRSTACK\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_dirstack), + Some(assign_dirstack), + 0 as libc::c_int, + ); + + v = init_dynamic_array_var( + b"GROUPS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_groupset), + Some(null_array_assign), + att_noassign as libc::c_int, + ); + + v = init_dynamic_array_var( + b"BASH_ARGC\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_bashargcv), + Some(null_array_assign), + (att_noassign | att_nounset as i32) as libc::c_int, + ); + + v = init_dynamic_array_var( + b"BASH_ARGV\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_bashargcv), + Some(null_array_assign), + (att_noassign | att_nounset as i32) as libc::c_int, + ); + + v = init_dynamic_array_var( + b"BASH_SOURCE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_self), + Some(null_array_assign), + (att_noassign | att_nounset as i32) as libc::c_int, + ); + + v = init_dynamic_array_var( + b"BASH_LINENO\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_self), + Some(null_array_assign), + (att_noassign | att_nounset as i32) as libc::c_int, + ); + + v = init_dynamic_assoc_var( + b"BASH_CMDS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_hashcmd), + Some(assign_hashcmd), + att_nofree as libc::c_int, + ); + + v = init_dynamic_assoc_var( + b"BASH_ALIASES\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + Some(get_aliasvar), + Some(assign_aliasvar), + att_nofree as libc::c_int, + ); + v = init_funcname_var(); + } +} + +fn hash_lookup(mut name: *const libc::c_char, mut hashed_vars: *mut HASH_TABLE) -> *mut SHELL_VAR { + let mut bucket: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + bucket = hash_search(name, hashed_vars, 0 as libc::c_int); + unsafe { + if !bucket.is_null() { + last_table_searched = hashed_vars; + } + return if !bucket.is_null() { + (*bucket).data as *mut SHELL_VAR + } else { + 0 as *mut libc::c_void as *mut SHELL_VAR + }; + } +} + +#[no_mangle] +pub fn var_lookup(mut name: *const libc::c_char, mut vcontext: *mut VAR_CONTEXT) -> *mut SHELL_VAR { + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = 0 as *mut libc::c_void as *mut SHELL_VAR; + vc = vcontext; + unsafe { + while !vc.is_null() { + v = hash_lookup(name, (*vc).table); + if !v.is_null() { + break; + } + vc = (*vc).down; + } + } + return v; +} + +fn find_variable_internal(mut name: *const libc::c_char, mut flags: libc::c_int) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut search_tempenv: libc::c_int = 0; + let mut force_tempenv: libc::c_int = 0; + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + + var = 0 as *mut libc::c_void as *mut SHELL_VAR; + unsafe { + force_tempenv = flags & FV_FORCETEMPENV!(); + search_tempenv = (force_tempenv != 0 + || (expanding_redir == 0 as libc::c_int && subshell_environment != 0)) + as libc::c_int; + if search_tempenv != 0 && !temporary_env.is_null() { + var = hash_lookup(name, temporary_env); + } + if var.is_null() { + if (flags & FV_SKIPINVISIBLE!()) == 0 as libc::c_int { + var = var_lookup(name, shell_variables); + } else { + vc = shell_variables; + while !vc.is_null() { + var = hash_lookup(name, (*vc).table); + if !var.is_null() && invisible_p!(var) != 0 { + var = 0 as *mut SHELL_VAR; + } + if !var.is_null() { + break; + } + vc = (*vc).down; + } + } + } + if var.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + + if ((*var).dynamic_value).is_some() { + return Some(((*var).dynamic_value).expect("non-null function pointer")) + .expect("non-null function pointer")(var); + } else { + return var; + }; + } +} + +#[no_mangle] +pub fn find_variable_nameref(mut v: *mut SHELL_VAR) -> *mut SHELL_VAR { + let mut level: libc::c_int = 0; + let mut flags: libc::c_int = 0; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut orig: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut oldv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + level = 0 as libc::c_int; + + orig = v; + unsafe { + while !v.is_null() && nameref_p!(v) != 0 { + level += 1; + level; + if level > NAMEREF_MAX as libc::c_int { + return 0 as *mut SHELL_VAR; + } + newname = nameref_cell!(v); + if newname.is_null() || *newname as libc::c_int == '\0' as i32 { + return 0 as *mut SHELL_VAR; + } + oldv = v; + flags = 0 as libc::c_int; + if expanding_redir == 0 as libc::c_int + && (assigning_in_environment != 0 || executing_builtin != 0) + { + flags |= FV_FORCETEMPENV!(); + } + v = find_variable_internal(newname, flags); + if v == orig || v == oldv { + internal_warning( + b"%s: circular name reference\0" as *const u8 as *const libc::c_char, + (*orig).name, + ); + if variable_context != 0 && (*v).context != 0 { + return find_global_variable_noref((*v).name); + } else { + return 0 as *mut SHELL_VAR; + } + } + } + } + return v; +} + +#[no_mangle] +pub fn find_variable_last_nameref( + mut name: *const libc::c_char, + mut vflags: libc::c_int, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut level: libc::c_int = 0; + let mut flags: libc::c_int = 0; + v = find_variable_noref(name); + nv = v; + level = 0 as libc::c_int; + unsafe { + while !v.is_null() && nameref_p!(v) != 0 as libc::c_int { + level += 1; + level; + if level > NAMEREF_MAX as libc::c_int { + return 0 as *mut SHELL_VAR; + } + newname = nameref_cell!(v); + if newname.is_null() || *newname as libc::c_int == '\0' as i32 { + return if vflags != 0 && invisible_p!(v) != 0 { + v + } else { + 0 as *mut SHELL_VAR + }; + } + nv = v; + flags = 0 as libc::c_int; + if expanding_redir == 0 as libc::c_int + && (assigning_in_environment != 0 || executing_builtin != 0) + { + flags |= FV_FORCETEMPENV!() as libc::c_int; + } + v = find_variable_internal(newname, flags); + } + } + return nv; +} + +#[no_mangle] +pub fn find_global_variable_last_nameref( + mut name: *const libc::c_char, + mut vflags: libc::c_int, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut level: libc::c_int = 0; + v = find_global_variable_noref(name); + nv = v; + level = 0 as libc::c_int; + unsafe { + while !v.is_null() && nameref_p!(v) != 0 { + level += 1; + level; + if level > NAMEREF_MAX as libc::c_int { + return 0 as *mut SHELL_VAR; + } + newname = nameref_cell!(v); + if newname.is_null() || *newname as libc::c_int == '\0' as i32 { + return if vflags != 0 && invisible_p!(v) != 0 { + v + } else { + 0 as *mut SHELL_VAR + }; + } + nv = v; + v = find_global_variable_noref(newname); + } + } + return nv; +} + +fn find_nameref_at_context(mut v: *mut SHELL_VAR, mut vc: *mut VAR_CONTEXT) -> *mut SHELL_VAR { + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv2: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut level: libc::c_int = 0; + nv = v; + level = 1 as libc::c_int; + unsafe { + while !nv.is_null() && nameref_p!(nv) != 0 { + level += 1; + level; + if level > NAMEREF_MAX as libc::c_int { + return &mut nameref_maxloop_value; + } + newname = nameref_cell!(nv); + if newname.is_null() || *newname as libc::c_int == '\0' as i32 { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + nv2 = hash_lookup(newname, (*vc).table); + if nv2.is_null() { + break; + } + nv = nv2; + } + } + return nv; +} + +fn find_variable_nameref_context( + mut v: *mut SHELL_VAR, + mut vc: *mut VAR_CONTEXT, + mut nvcp: *mut *mut VAR_CONTEXT, +) -> *mut SHELL_VAR { + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv2: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nvc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + + nv = v; + nvc = vc; + unsafe { + while !nvc.is_null() { + nv2 = find_nameref_at_context(nv, nvc); + if nv2 == &mut nameref_maxloop_value as *mut SHELL_VAR { + return nv2; + } + if !nv2.is_null() { + nv = nv2; + if !(*nvcp).is_null() { + *nvcp = nvc; + } + if nameref_p!(nv) == 0 as libc::c_int { + break; + } + } + nvc = (*nvc).down; + } + return if nameref_p!(nv) as libc::c_int != 0 { + 0 as *mut libc::c_void as *mut SHELL_VAR + } else { + nv + }; + } +} + +fn find_variable_last_nameref_context( + mut v: *mut SHELL_VAR, + mut vc: *mut VAR_CONTEXT, + mut nvcp: *mut *mut VAR_CONTEXT, +) -> *mut SHELL_VAR { + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv2: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nvc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + nv = v; + nvc = vc; + unsafe { + while !nvc.is_null() { + nv2 = find_nameref_at_context(nv, nvc); + if nv2 == &mut nameref_maxloop_value as *mut SHELL_VAR { + return nv2; + } + if !nv2.is_null() { + nv = nv2; + if !(*nvcp).is_null() { + *nvcp = nvc; + } + } + nvc = (*nvc).down; + } + return if nameref_p!(nv) != 0 { + nv + } else { + 0 as *mut libc::c_void as *mut SHELL_VAR + }; + } +} + +#[no_mangle] +pub fn find_variable_nameref_for_create( + mut name: *const libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = find_variable_last_nameref(name, 1 as libc::c_int); + unsafe { + if flags & 1 as libc::c_int != 0 + && !var.is_null() + && (*var).attributes & nameref_p!(var) != 0 + && invisible_p!(var) != 0 + { + internal_warning( + b"%s: removing nameref attribute\0" as *const u8 as *const libc::c_char, + name, + ); + VUNSETATTR!(var, att_nameref); + } + if !var.is_null() && nameref_p!(var) as libc::c_int != 0 { + if legal_identifier(nameref_cell!(var)) == 0 as libc::c_int { + if !nameref_cell!(var).is_null() { + sh_invalidid(nameref_cell!(var)); + } else { + sh_invalidid(b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + return INVALID_NAMEREF_VALUE!(); + } + } + } + return var; +} + +pub fn find_variable_nameref_for_assignment( + mut name: *const libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = find_variable_last_nameref(name, 1 as libc::c_int); + unsafe { + if !var.is_null() && nameref_p!(var) != 0 && invisible_p!(var) != 0 { + internal_warning( + b"%s: removing nameref attribute\0" as *const u8 as *const libc::c_char, + name, + ); + + VUNSETATTR!(var, att_nameref); + } + if !var.is_null() && nameref_p!(var) != 0 { + if valid_nameref_value(nameref_cell!(var), 1 as libc::c_int) == 0 as libc::c_int { + if !nameref_cell!(var).is_null() { + sh_invalidid(nameref_cell!(var)); + } else { + sh_invalidid(b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } + return INVALID_NAMEREF_VALUE!(); + } + } + } + return var; +} + +#[no_mangle] +pub fn nameref_transform_name( + mut name: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + v = 0 as *mut SHELL_VAR; + unsafe { + if flags & ASS_MKLOCAL!() != 0 { + v = find_variable_last_nameref(name, 1 as libc::c_int); + if !v.is_null() && (*v).context != variable_context { + v = 0 as *mut SHELL_VAR; + } + } else if flags & ASS_MKGLOBAL!() != 0 { + v = if flags & ASS_CHKLOCAL!() != 0 { + find_variable_last_nameref(name, 1 as libc::c_int) + } else { + find_global_variable_last_nameref(name, 1 as libc::c_int) + }; + } + if !v.is_null() + && nameref_p!(v) != 0 + && valid_nameref_value(nameref_cell!(v), 1 as libc::c_int) != 0 + { + return nameref_cell!(v); + } + } + return name; +} + +#[no_mangle] +pub fn find_variable_tempenv(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = find_variable_internal(name, FV_FORCETEMPENV!() as libc::c_int); + if unsafe { !var.is_null() && nameref_p!(var) != 0 } { + var = find_variable_nameref(var); + } + return var; +} + +#[no_mangle] +pub fn find_variable_notempenv(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = find_variable_internal(name, 0 as libc::c_int); + if unsafe { !var.is_null() && nameref_p!(var) != 0 } { + var = find_variable_nameref(var); + } + return var; +} + +#[no_mangle] +pub fn find_global_variable(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + var = var_lookup(name, global_variables); + if !var.is_null() && nameref_p!(var) != 0 { + var = find_variable_nameref(var); + } + if var.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + return if ((*var).dynamic_value).is_some() { + (Some(((*var).dynamic_value).expect("non-null function pointer"))) + .expect("non-null function pointer")(var) + } else { + var + }; + } +} +#[no_mangle] +pub fn find_global_variable_noref(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + var = var_lookup(name, global_variables); + if var.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + return if ((*var).dynamic_value).is_some() { + (Some(((*var).dynamic_value).expect("non-null function pointer"))) + .expect("non-null function pointer")(var) + } else { + var + }; + } +} + +#[no_mangle] +pub fn find_shell_variable(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + var = var_lookup(name, shell_variables); + if !var.is_null() && nameref_p!(var) != 0 { + var = find_variable_nameref(var); + } + if var.is_null() { + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + return if ((*var).dynamic_value).is_some() { + (Some(((*var).dynamic_value).expect("non-null function pointer"))) + .expect("non-null function pointer")(var) + } else { + var + }; + } +} +#[no_mangle] +pub fn find_variable(name: *const libc::c_char) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut flags: libc::c_int = 0; + unsafe { + last_table_searched = 0 as *mut HASH_TABLE; + + flags = 0 as libc::c_int; + if expanding_redir == 0 as libc::c_int + && (assigning_in_environment != 0 || executing_builtin != 0) + { + flags |= FV_FORCETEMPENV!(); + } + + v = find_variable_internal(name, flags); + + if !v.is_null() && nameref_p!(v) != 0 { + // PS1打å°å€¼ + v = find_variable_nameref(v); + } + } + return v; +} + +#[no_mangle] +pub fn find_variable_no_invisible(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut flags: libc::c_int = 0; + unsafe { + last_table_searched = 0 as *mut HASH_TABLE; + flags = FV_SKIPINVISIBLE!(); + if expanding_redir == 0 as libc::c_int + && (assigning_in_environment != 0 || executing_builtin != 0) + { + flags |= FV_FORCETEMPENV!(); + } + v = find_variable_internal(name, flags); + if !v.is_null() && nameref_p!(v) != 0 { + v = find_variable_nameref(v); + } + } + return v; +} + +#[no_mangle] +pub fn find_variable_for_assignment(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut flags: libc::c_int = 0; + unsafe { + last_table_searched = 0 as *mut HASH_TABLE; + flags = 0 as libc::c_int; + if expanding_redir == 0 as libc::c_int + && (assigning_in_environment != 0 || executing_builtin != 0) + { + flags |= FV_FORCETEMPENV!(); + } + v = find_variable_internal(name, flags); + if !v.is_null() && nameref_p!(v) != 0 { + v = find_variable_nameref(v); + } + } + return v; +} + +#[no_mangle] +pub fn find_variable_noref(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut flags: libc::c_int = 0; + unsafe { + flags = 0 as libc::c_int; + if expanding_redir == 0 as libc::c_int + && (assigning_in_environment != 0 || executing_builtin != 0) + { + flags |= FV_FORCETEMPENV!(); + } + } + v = find_variable_internal(name, flags); + return v; +} + +#[no_mangle] +pub fn find_function(mut name: *const libc::c_char) -> *mut SHELL_VAR { + unsafe { + return hash_lookup(name, shell_functions); + } +} + +#[no_mangle] +pub fn find_function_def(mut name: *const libc::c_char) -> *mut FUNCTION_DEF { + unsafe { + return hash_lookup(name, shell_function_defs) as *mut FUNCTION_DEF; + } +} + +#[no_mangle] +pub fn get_variable_value(mut var: *mut SHELL_VAR) -> *mut libc::c_char { + unsafe { + if var.is_null() { + return 0 as *mut libc::c_void as *mut libc::c_char; + } else if array_p!(var) != 0 { + return array_reference(array_cell!(var), 0 as libc::c_int as arrayind_t); + } else if assoc_p!(var) != 0 { + return assoc_reference( + assoc_cell!(var), + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } else { + return value_cell!(var); + }; + } +} + +#[no_mangle] +pub fn get_string_value(mut var_name: *const libc::c_char) -> *mut libc::c_char { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = find_variable(var_name); + return if !var.is_null() { + get_variable_value(var) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; +} + +#[no_mangle] +pub fn sh_get_env_value_rename(mut v: *const libc::c_char) -> *mut libc::c_char { + return get_string_value(v); +} + +#[no_mangle] +pub fn validate_inherited_value(mut var: *mut SHELL_VAR, mut type_0: libc::c_int) -> libc::c_int { + unsafe { + if type_0 == att_array as libc::c_int && assoc_p!(var) != 0 { + return 0 as libc::c_int; + } else if type_0 == att_assoc as libc::c_int && array_p!(var) != 0 { + return 0 as libc::c_int; + } else { + return 1 as libc::c_int; + }; + } +} +#[no_mangle] +pub fn var_sametype(mut v1: *mut SHELL_VAR, mut v2: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if v1.is_null() || v2.is_null() { + return 0 as libc::c_int; + } else if assoc_p!(v1) != 0 && assoc_p!(v2) != 0 { + return 1 as libc::c_int; + } else if array_p!(v1) != 0 && array_p!(v2) != 0 { + return 1 as libc::c_int; + } else if array_p!(v1) != 0 || array_p!(v2) != 0 { + return 0 as libc::c_int; + } else if assoc_p!(v1) != 0 || assoc_p!(v2) != 0 { + return 0 as libc::c_int; + } else { + return 1 as libc::c_int; + } + } +} + +#[no_mangle] +pub fn set_if_not(mut name: *mut libc::c_char, mut value: *mut libc::c_char) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + if shell_variables.is_null() { + create_variable_tables(); + } + + v = find_variable(name); + + if v.is_null() { + v = bind_variable_internal( + name, + value, + (*global_variables).table, + HASH_NOSRCH as libc::c_int, + 0 as libc::c_int, + ); + } + } + return v; +} + +#[no_mangle] +pub fn make_local_variable( + mut name: *const libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut new_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut old_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut old_ref: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut was_tmpvar: bool = false; + let mut old_value: *mut libc::c_char = 0 as *mut libc::c_char; + + old_ref = find_variable_noref(name); + unsafe { + if !old_ref.is_null() && nameref_p!(old_ref) == 0 { + old_ref = 0 as *mut SHELL_VAR; + } + old_var = find_variable(name); + if old_ref.is_null() + && !old_var.is_null() + && local_p!(old_var) != 0 + && (*old_var).context == variable_context + { + if !((*old_var).value).is_null() { + libc::free((*old_var).value as *mut libc::c_void); + (*old_var).value = 0 as *mut libc::c_char; + } + return old_var; + } + if !old_ref.is_null() && local_p!(old_ref) != 0 && (*old_ref).context == variable_context { + return old_ref; + } + if !old_ref.is_null() { + old_var = old_ref; + } + + was_tmpvar = !old_var.is_null() && tempvar_p!(old_var) != 0; + + loop { + if was_tmpvar + && (*old_var).context == variable_context + && last_table_searched != temporary_env + { + VUNSETATTR!(old_var, att_invisible); + new_var = old_var; + vc = shell_variables; + while !vc.is_null() { + if vc_isfuncenv!(vc) && (*vc).scope == variable_context { + break; + } + vc = (*vc).down; + } + break; + return old_var; + } + + if was_tmpvar { + old_value = value_cell!(old_var); + } else { + old_value = 0 as *mut libc::c_char; + } + + vc = shell_variables; + while !vc.is_null() { + if vc_isfuncenv!(vc) && (*vc).scope == variable_context { + break; + } + vc = (*vc).down; + } + + if vc.is_null() { + internal_error( + b"make_local_variable: no function context at current scope\0" as *const u8 + as *const libc::c_char, + ); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } else if ((*vc).table).is_null() { + (*vc).table = hash_create(TEMPENV_HASH_BUCKETS!() as libc::c_int); + } + if !old_var.is_null() + && (noassign_p!(old_var) != 0 + || (readonly_p!(old_var) != 0 && (*old_var).context == 0)) + { + if readonly_p!(old_var) != 0 { + sh_readonly(name as *mut libc::c_char); + } else if noassign_p!(old_var) != 0 { + builtin_error( + b"%s: variable may not be assigned value\0" as *const u8 + as *mut libc::c_char, + name, + ); + } + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + if old_var.is_null() { + new_var = make_new_variable(name, (*vc).table); + } else { + new_var = make_new_variable(name, (*vc).table); + if was_tmpvar { + var_setvalue!(new_var, savestring!(old_value)); + } else if localvar_inherit != 0 || (flags & MKLOC_INHERIT!()) != 0 { + if assoc_p!(old_var) != 0 { + var_setassoc!(new_var, assoc_copy!(assoc_cell!(old_var))); + } else if array_p!(old_var) != 0 { + var_setarray!(new_var, array_copy(array_cell!(old_var))); + } else if !value_cell!(old_var).is_null() { + var_setvalue!(new_var, savestring!(value_cell!(old_var))); + } else { + var_setvalue!(new_var, 0 as *mut libc::c_void as *mut libc::c_char); + } + } + if localvar_inherit != 0 || (flags & MKLOC_INHERIT!()) != 0 { + (*new_var).attributes = (*old_var).attributes & (!att_nameref) as libc::c_int; + + (*new_var).dynamic_value = (*old_var).dynamic_value; + (*new_var).assign_func = (*old_var).assign_func; + } else { + if exported_p!(old_var) != 0 { + (*new_var).attributes = att_exported as libc::c_int; + } else { + (*new_var).attributes = 0 as libc::c_int; + } + } + } + break; + } + + (*vc).flags |= VC_HASLOCAL as libc::c_int; + (*new_var).context = variable_context; + + VSETATTR!(new_var, att_local); + if ifsname!(name) { + setifs(new_var); + } + if !was_tmpvar && value_cell!(new_var) == 0 as *mut libc::c_char { + VSETATTR!(new_var, att_invisible); + } + } + return new_var; +} + +fn new_shell_variable(mut name: *const libc::c_char) -> *mut SHELL_VAR { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + entry = libc::malloc(std::mem::size_of::() as usize) as *mut SHELL_VAR; + (*entry).name = savestring!(name); + var_setvalue!(entry, 0 as *mut libc::c_void as *mut libc::c_char); + CLEAR_EXPORTSTR!(entry); + + (*entry).dynamic_value = std::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void); + (*entry).assign_func = std::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void, + ); + (*entry).attributes = 0 as libc::c_int; + (*entry).context = 0 as libc::c_int; + } + return entry; +} + +fn make_new_variable(mut name: *const libc::c_char, mut table: *mut HASH_TABLE) -> *mut SHELL_VAR { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + unsafe { + entry = new_shell_variable(name); + if shell_variables.is_null() { + create_variable_tables(); + } + elt = hash_insert(savestring!(name), table, HASH_NOSRCH as libc::c_int); + (*elt).data = entry as *mut libc::c_void; + } + return entry; +} + +#[no_mangle] +pub fn make_new_array_variable(mut name: *mut libc::c_char) -> *mut SHELL_VAR { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut array: *mut ARRAY = 0 as *mut ARRAY; + unsafe { + entry = make_new_variable(name, (*global_variables).table); + array = array_create(); + + var_setarray!(entry, array); + VSETATTR!(entry, att_array); + } + return entry; +} + +#[no_mangle] +pub fn make_local_array_variable( + mut name: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut array: *mut ARRAY = 0 as *mut ARRAY; + let mut assoc_ok: libc::c_int = 0; + + assoc_ok = flags & MKLOC_ASSOCOK!() as libc::c_int; + + var = make_local_variable(name, flags & MKLOC_INHERIT!() as libc::c_int); + unsafe { + if var.is_null() || array_p!(var) != 0 || (assoc_ok != 0 && assoc_p!(var) != 0) { + return var; + } + if localvar_inherit != 0 && assoc_p!(var) != 0 { + internal_warning( + b"%s: cannot inherit value from incompatible type\0" as *const u8 + as *const libc::c_char, + name, + ); + VUNSETATTR!(var, att_array); + dispose_variable_value(var); + array = array_create(); + var_setarray!(var, array); + } else if localvar_inherit != 0 { + var = convert_var_to_array(var); + } else { + dispose_variable_value(var); + array = array_create(); + var_setarray!(var, array); + } + VSETATTR!(var, att_array); + } + return var; +} + +#[no_mangle] +pub fn make_new_assoc_variable(mut name: *mut libc::c_char) -> *mut SHELL_VAR { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut hash: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + unsafe { + entry = make_new_variable(name, (*global_variables).table); + hash = assoc_create!(ASSOC_HASH_BUCKETS!()); + + var_setassoc!(entry, hash); + VSETATTR!(entry, att_assoc); + } + return entry; +} + +#[no_mangle] +pub fn make_local_assoc_variable( + mut name: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut hash: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + let mut array_ok: libc::c_int = 0; + array_ok = flags & MKLOC_ARRAYOK!() as libc::c_int; + + var = make_local_variable(name, flags & MKLOC_INHERIT!() as libc::c_int); + unsafe { + if var.is_null() || assoc_p!(var) != 0 || (array_ok != 0 && array_p!(var) != 0) { + return var; + } + if localvar_inherit != 0 && array_p!(var) != 0 { + internal_warning( + b"%s: cannot inherit value from incompatible type\0" as *const u8 + as *const libc::c_char, + name, + ); + VUNSETATTR!(var, att_array); + + dispose_variable_value(var); + hash = assoc_create!(ASSOC_HASH_BUCKETS as libc::c_int); + var_setassoc!(var, hash); + } else if localvar_inherit != 0 { + var = convert_var_to_assoc(var); + } else { + dispose_variable_value(var); + hash = assoc_create!(ASSOC_HASH_BUCKETS as libc::c_int); + var_setassoc!(var, hash); + } + VSETATTR!(var, att_assoc); + } + return var; +} + +#[no_mangle] +pub fn make_variable_value( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut libc::c_char { + let mut current_block: u64; + let mut retval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lval: intmax_t = 0; + let mut rval: intmax_t = 0; + let mut expok: libc::c_int = 0; + let mut olen: libc::c_int = 0; + let mut op: libc::c_int = 0; + + let mut T_flags: bool = false; + unsafe { + loop { + if flags & ASS_NOEVAL!() as libc::c_int == 0 as libc::c_int && integer_p!(var) != 0 { + if flags & ASS_APPEND!() as libc::c_int != 0 { + oval = value_cell!(var); + lval = evalexp(oval, 0 as libc::c_int, &mut expok); + if expok == 0 as libc::c_int { + if flags & (ASS_NOLONGJMP as libc::c_int) != 0 { + T_flags = true; + break; + } else { + top_level_cleanup(); + jump_to_top_level(DISCARD as libc::c_int); + } + } + } + + rval = evalexp(value, 0 as libc::c_int, &mut expok); + if expok == 0 as libc::c_int { + if flags & (ASS_NOLONGJMP as libc::c_int) != 0 { + T_flags = true; + break; + } else { + top_level_cleanup(); + jump_to_top_level(DISCARD as libc::c_int); + } + } + + if flags & (ASS_APPEND as libc::c_int) != 0 { + rval += lval; + } + retval = itos(rval); + } else if flags & ASS_NOEVAL!() == 0 as libc::c_int + && (capcase_p!(var) != 0 || uppercase_p!(var) != 0 || lowercase_p!(var) != 0) + { + if flags & ASS_APPEND as libc::c_int != 0 { + oval = get_variable_value(var); + if oval.is_null() { + oval = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + olen = STRLEN!(oval); + if !value.is_null() { + retval = libc::malloc(olen as usize + STRLEN!(value) as usize + 1 as usize) + as *mut libc::c_char; + } else { + retval = libc::malloc(olen as usize + 1 as usize) as *mut libc::c_char; + } + strcpy(retval, oval); + + if !value.is_null() { + strcpy(retval.offset(olen as isize), value); + } + } else if *value != 0 { + retval = savestring!(value); + } else { + retval = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *retval.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + + op = if capcase_p!(var) != 0 { + CASE_CAPITALIZE as libc::c_int + } else if uppercase_p!(var) != 0 { + CASE_UPPER as libc::c_int + } else { + CASE_LOWER as libc::c_int + }; + + oval = sh_modcase(retval, 0 as *mut libc::c_char, op); + free(retval as *mut libc::c_void); + retval = oval; + } else if !value.is_null() { + if flags & ASS_APPEND as libc::c_int != 0 as libc::c_int { + oval = get_variable_value(var); + if oval.is_null() { + oval = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + olen = STRLEN!(oval); + if !value.is_null() { + retval = libc::malloc( + (olen as size_t + STRLEN!(value) as size_t + 1 as u64) as usize, + ) as *mut libc::c_char; + } else { + retval = + libc::malloc((olen as size_t + 1 as u64) as usize) as *mut libc::c_char; + } + strcpy(retval, oval); + if !value.is_null() { + strcpy(retval.offset(olen as isize), value); + } + } else if *value != 0 { + retval = savestring!(value); + } else { + retval = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *retval = '\0' as i32 as libc::c_char; + } + } else { + retval = 0 as *mut libc::c_void as *mut libc::c_char; + } + break; + } + + if T_flags { + if flags & ASS_APPEND as libc::c_int != 0 as libc::c_int { + oval = get_variable_value(var); + if oval.is_null() { + oval = b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + olen = STRLEN!(oval); + if !value.is_null() { + retval = libc::malloc( + (olen as size_t + STRLEN!(value) as size_t + 1 as u64) as usize, + ) as *mut libc::c_char; + } else { + retval = libc::malloc(olen as usize + 1 as usize) as *mut libc::c_char; + } + strcpy(retval, oval); + if !value.is_null() { + strcpy(retval.offset(olen as isize), value); + } + } else if *value != 0 { + retval = savestring!(value); + } else { + retval = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *retval = '\0' as i32 as libc::c_char; + } + } + } + return retval; +} + +fn can_optimize_assignment( + mut entry: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut aflags: libc::c_int, +) -> libc::c_int { + if aflags & ASS_APPEND as libc::c_int == 0 as libc::c_int { + return 0 as libc::c_int; + } + unsafe { + if array_p!(entry) != 0 || assoc_p!(entry) != 0 { + return 0 as libc::c_int; + } + if integer_p!(entry) != 0 + || uppercase_p!(entry) != 0 + || lowercase_p!(entry) != 0 + || capcase_p!(entry) != 0 + { + return 0 as libc::c_int; + } + if readonly_p!(entry) != 0 || noassign_p!(entry) != 0 { + return 0 as libc::c_int; + } + } + return 1 as libc::c_int; +} + +fn optimized_assignment( + mut entry: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut aflags: libc::c_int, +) -> *mut SHELL_VAR { + let mut len: size_t = 0; + let mut vlen: size_t = 0; + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + let mut new: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + v = value_cell!(entry); + + len = STRLEN!(v) as size_t; + vlen = STRLEN!(value) as size_t; + + new = libc::realloc( + v as *mut libc::c_void, + vlen as usize + len as usize + 8 as usize, + ) as *mut libc::c_char; + if vlen == 1 as size_t { + *new.offset(len as isize) = *value; + *new.offset((len + 1) as isize) = '\0' as i32 as libc::c_char; + } else { + strcpy(new.offset(len as isize), value); + } + + var_setvalue!(entry, new); + } + return entry; +} + +fn bind_variable_internal( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, + mut table: *mut HASH_TABLE, + mut hflags: libc::c_int, + mut aflags: libc::c_int, +) -> *mut SHELL_VAR { + let mut newval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut tentry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + entry = if hflags & HASH_NOSRCH as libc::c_int != 0 { + 0 as *mut libc::c_void as *mut SHELL_VAR + } else { + hash_lookup(name, table) + }; + + let mut T_flags: bool = false; + unsafe { + if !entry.is_null() + && nameref_p!(entry) != 0 + && invisible_p!(entry) == 0 as libc::c_int + && table == (*global_variables).table + { + entry = find_global_variable((*entry).name); + if entry.is_null() { + entry = find_variable_last_nameref(name, 0 as libc::c_int); + } + if entry.is_null() { + return entry; + } + } + loop { + T_flags = false; + if !entry.is_null() && invisible_p!(entry) != 0 && nameref_p!(entry) != 0 { + if aflags & ASS_FORCE as libc::c_int == 0 as libc::c_int + && !value.is_null() + && valid_nameref_value(value, 0 as libc::c_int) == 0 as libc::c_int + { + sh_invalidid(value); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + T_flags = true; + break; + } else if !entry.is_null() && nameref_p!(entry) as libc::c_int != 0 { + newval = nameref_cell!(entry); + if valid_nameref_value(newval, 0 as libc::c_int) == 0 as libc::c_int { + sh_invalidid(newval); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + if valid_array_reference(newval, 0 as libc::c_int) != 0 { + tname = array_variable_name( + newval, + 0 as libc::c_int, + 0 as *mut *mut libc::c_char, + 0 as *mut libc::c_int, + ); + if !tname.is_null() + && ({ + tentry = find_variable_noref(tname); + !tentry.is_null() + } && nameref_p!(tentry) as libc::c_int != 0) + { + internal_warning( + b"%s: removing nameref attribute\0" as *const u8 as *const libc::c_char, + name_cell!(tentry), + ); + if !(value_cell!(tentry).is_null()) { + free(value_cell!(tentry) as *mut libc::c_void); + } + var_setvalue!(tentry, 0 as *mut libc::c_void as *mut libc::c_char); + VUNSETATTR!(tentry, att_nameref); + } + free(tname as *mut libc::c_void); + entry = assign_array_element( + newval, + make_variable_value(entry, value, aflags), + aflags | ASS_NAMEREF as libc::c_int, + ); + if entry.is_null() { + return entry; + } + } else { + entry = make_new_variable(newval, table); + var_setvalue!(entry, make_variable_value(entry, value, aflags)); + } + } else if entry.is_null() { + entry = make_new_variable(name, table); + var_setvalue!(entry, make_variable_value(entry, value, aflags)); + } else if ((*entry).assign_func).is_some() { + if readonly_p!(entry) != 0 && aflags & ASS_FORCE as libc::c_int == 0 as libc::c_int + || noassign_p!(entry) != 0 + { + if readonly_p!(entry) != 0 { + err_readonly(name_cell!(entry)); + } + return entry; + } + + INVALIDATE_EXPORTSTR!(entry); + newval = if aflags & ASS_APPEND as libc::c_int != 0 { + make_variable_value(entry, value, aflags) + } else { + value + }; + if assoc_p!(entry) != 0 { + entry = (Some(((*entry).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + entry, + newval, + -(1 as libc::c_int) as arrayind_t, + savestring!(b"0\0" as *const u8 as *const libc::c_char), + ); + } else if array_p!(entry) != 0 { + entry = (Some(((*entry).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + entry, + newval, + 0 as libc::c_int as arrayind_t, + 0 as *mut libc::c_char, + ); + } else { + entry = (Some(((*entry).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + entry, + newval, + -(1 as libc::c_int) as arrayind_t, + 0 as *mut libc::c_char, + ); + } + if newval != value { + free(newval as *mut libc::c_void); + } + return entry; + } else { + if readonly_p!(entry) != 0 && aflags & ASS_FORCE as libc::c_int == 0 as libc::c_int + || noassign_p!(entry) != 0 + { + if readonly_p!(entry) != 0 { + err_readonly(name_cell!(entry)); + } + return entry; + } + VUNSETATTR!(entry, att_invisible); + if can_optimize_assignment(entry, value, aflags) != 0 { + INVALIDATE_EXPORTSTR!(entry); + optimized_assignment(entry, value, aflags); + + if mark_modified_vars != 0 { + VSETATTR!(entry, att_exported); + } + if exported_p!(entry) != 0 { + array_needs_making = 1 as libc::c_int; + } + return entry; + } + + if assoc_p!(entry) != 0 || array_p!(entry) != 0 { + newval = make_array_variable_value( + entry, + 0 as libc::c_int as arrayind_t, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + aflags, + ); + } else { + newval = make_variable_value(entry, value, aflags); + } + INVALIDATE_EXPORTSTR!(entry); + + if assoc_p!(entry) != 0 { + assoc_insert( + assoc_cell!(entry), + savestring!(b"0\0" as *const u8 as *const libc::c_char), + newval, + ); + free(newval as *mut libc::c_void); + } else if array_p!(entry) != 0 { + array_insert(array_cell!(entry), 0 as libc::c_int as arrayind_t, newval); + free(newval as *mut libc::c_void); + } else { + if !value_cell!(entry).is_null() { + free(value_cell!(entry) as *mut libc::c_void); + } + var_setvalue!(entry, newval); + } + } + break; + } + + if T_flags { + if readonly_p!(entry) != 0 && aflags & ASS_FORCE as libc::c_int == 0 as libc::c_int + || noassign_p!(entry) != 0 + { + if readonly_p!(entry) != 0 { + err_readonly(name_cell!(entry)); + } + return entry; + } + VUNSETATTR!(entry, att_invisible); + if can_optimize_assignment(entry, value, aflags) != 0 { + INVALIDATE_EXPORTSTR!(entry); + optimized_assignment(entry, value, aflags); + + if mark_modified_vars != 0 { + VSETATTR!(entry, att_exported); + } + if exported_p!(entry) != 0 { + array_needs_making = 1 as libc::c_int; + } + return entry; + } + + if assoc_p!(entry) != 0 || array_p!(entry) != 0 { + newval = make_array_variable_value( + entry, + 0 as libc::c_int as arrayind_t, + b"0\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + value, + aflags, + ); + } else { + newval = make_variable_value(entry, value, aflags); + } + INVALIDATE_EXPORTSTR!(entry); + + if assoc_p!(entry) != 0 { + assoc_insert( + (*entry).value as *mut HASH_TABLE, + savestring!(b"0\0" as *const u8 as *const libc::c_char), + newval, + ); + free(newval as *mut libc::c_void); + } else if array_p!(entry) != 0 { + array_insert(array_cell!(entry), 0 as libc::c_int as arrayind_t, newval); + free(newval as *mut libc::c_void); + } else { + if !value_cell!(entry).is_null() { + free(value_cell!(entry) as *mut libc::c_void); + } + var_setvalue!(entry, newval); + } + } + + if mark_modified_vars != 0 { + VSETATTR!(entry, att_exported); + } + if exported_p!(entry) != 0 { + array_needs_making = 1 as libc::c_int; + } + } + return entry; +} + +#[no_mangle] +pub fn bind_global_variable( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + unsafe { + if shell_variables.is_null() { + create_variable_tables(); + } + + return bind_variable_internal( + name, + value, + (*global_variables).table, + 0 as libc::c_int, + flags, + ); + } +} + +fn bind_invalid_envvar( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + unsafe { + if invalid_env.is_null() { + invalid_env = hash_create(64 as libc::c_int); + } + return bind_variable_internal(name, value, invalid_env, HASH_NOSRCH as libc::c_int, flags); + } +} + +#[no_mangle] +pub fn bind_variable_value( + mut var: *mut SHELL_VAR, + mut value: *mut libc::c_char, + mut aflags: libc::c_int, +) -> *mut SHELL_VAR { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut invis: libc::c_int = 0; + unsafe { + invis = invisible_p!(var); + VUNSETATTR!(var, att_invisible); + + if ((*var).assign_func).is_some() { + t = if aflags & ASS_APPEND as libc::c_int != 0 { + make_variable_value(var, value, aflags) + } else { + value + }; + (Some(((*var).assign_func).expect("non-null function pointer"))) + .expect("non-null function pointer")( + var, + t, + -(1 as libc::c_int) as arrayind_t, + 0 as *mut libc::c_char, + ); + if t != value && !t.is_null() { + free(t as *mut libc::c_void); + } + } else { + t = make_variable_value(var, value, aflags); + if aflags & (ASS_NAMEREF as libc::c_int | ASS_FORCE as libc::c_int) + == ASS_NAMEREF as libc::c_int + && check_selfref(name_cell!(var), t, 0 as libc::c_int) != 0 + { + if variable_context != 0 { + internal_warning( + b"%s: circular name reference\0" as *const u8 as *const libc::c_char, + name_cell!(var), + ); + } else { + internal_error( + b"%s: nameref variable self references not allowed\0" as *const u8 + as *const libc::c_char, + name_cell!(var), + ); + free(t as *mut libc::c_void); + if invis != 0 { + VSETATTR!(var, att_invisible); + } + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + } + if aflags & ASS_NAMEREF as libc::c_int != 0 + && valid_nameref_value(t, 0 as libc::c_int) == 0 as libc::c_int + { + free(t as *mut libc::c_void); + if invis != 0 { + VSETATTR!(var, att_invisible); + } + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, t); + } + INVALIDATE_EXPORTSTR!(var); + + if mark_modified_vars != 0 { + VSETATTR!(var, att_exported); + } + if exported_p!(var) != 0 { + array_needs_making = 1 as libc::c_int; + } + } + return var; +} + +#[no_mangle] +pub fn bind_int_variable( + mut lhs: *mut libc::c_char, + mut rhs: *mut libc::c_char, + mut flags: libc::c_int, +) -> *mut SHELL_VAR { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut isint: libc::c_int = 0; + let mut isarr: libc::c_int = 0; + let mut implicitarray: libc::c_int = 0; + implicitarray = 0 as libc::c_int; + isarr = implicitarray; + isint = isarr; + unsafe { + if valid_array_reference( + lhs, + (flags & ASS_NOEXPAND as libc::c_int != 0 as libc::c_int) as libc::c_int, + ) != 0 + { + isarr = 1 as libc::c_int; + v = array_variable_part( + lhs, + (flags & ASS_NOEXPAND as libc::c_int != 0 as libc::c_int) as libc::c_int, + 0 as *mut *mut libc::c_char, + 0 as *mut libc::c_int, + ); + } else if legal_identifier(lhs) == 0 as libc::c_int { + sh_invalidid(lhs); + return 0 as *mut libc::c_void as *mut SHELL_VAR; + } else { + v = find_variable(lhs); + } + if !v.is_null() { + isint = integer_p!(v); + VUNSETATTR!(v, att_integer); + + if array_p!(v) != 0 && isarr == 0 as libc::c_int { + implicitarray = 1 as libc::c_int; + } + } + if isarr != 0 { + v = assign_array_element(lhs, rhs, flags); + } else if implicitarray != 0 { + v = bind_array_variable(lhs, 0 as libc::c_int as arrayind_t, rhs, 0 as libc::c_int); + } else { + v = bind_variable(lhs, rhs, 0 as libc::c_int); + } + if !v.is_null() { + if isint != 0 { + VSETATTR!(v, att_integer); + } + VUNSETATTR!(v, att_invisible); + } + if !v.is_null() && nameref_p!(v) != 0 { + internal_warning( + b"%s: assigning integer to name reference\0" as *const u8 as *const libc::c_char, + lhs, + ); + } + } + return v; +} + +#[no_mangle] +pub fn bind_var_to_int(mut var: *mut libc::c_char, mut val: intmax_t) -> *mut SHELL_VAR { + let mut ibuf: [libc::c_char; (INT_STRLEN_BOUND!(intmax_t) + 1) as usize] = + [0; (INT_STRLEN_BOUND!(intmax_t) + 1) as usize]; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + p = fmtulong( + val as libc::c_ulong, + 10 as libc::c_int, + ibuf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(intmax_t) + 1) as usize]>() + as size_t, + 0 as libc::c_int, + ); + } + return bind_int_variable(var, p, 0 as libc::c_int); +} + +#[no_mangle] +pub fn bind_function(mut name: *const libc::c_char, mut value: *mut COMMAND) -> *mut SHELL_VAR { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + entry = find_function(name); + unsafe { + if entry.is_null() { + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + elt = hash_insert(savestring!(name), shell_functions, 0x1 as libc::c_int); + entry = new_shell_variable(name); + (*elt).data = entry as *mut libc::c_void; + } else { + INVALIDATE_EXPORTSTR!(entry); + } + if !var_isset!(entry) { + dispose_command(function_cell!(entry) as *mut COMMAND); + } + if !value.is_null() { + var_setfunc!(entry, copy_command(value)); + } else { + var_setfunc!(entry, 0); + } + + VSETATTR!(entry, att_function); + + if mark_modified_vars != 0 { + VSETATTR!(entry, att_function); + } + + VUNSETATTR!(entry, att_invisible); + + if exported_p!(entry) != 0 { + array_needs_making = 1 as libc::c_int; + } + set_itemlist_dirty(&mut it_functions); + } + return entry; +} + +#[no_mangle] +pub fn bind_function_def( + mut name: *const libc::c_char, + mut value: *mut FUNCTION_DEF, + mut flags: libc::c_int, +) { + let mut entry: *mut FUNCTION_DEF = 0 as *mut FUNCTION_DEF; + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut cmd: *mut COMMAND = 0 as *mut COMMAND; + + entry = find_function_def(name); + unsafe { + if !entry.is_null() && flags & 1 as libc::c_int != 0 { + dispose_function_def_contents(entry); + entry = copy_function_def_contents(value, entry); + } else if !entry.is_null() { + return; + } else { + cmd = (*value).command; + (*value).command = 0 as *mut COMMAND; + entry = copy_function_def(value); + (*value).command = cmd; + elt = hash_insert( + savestring!(name), + shell_function_defs, + HASH_NOSRCH as libc::c_int, + ); + (*elt).data = entry as *mut *mut libc::c_void as *mut libc::c_void; + }; + } +} + +#[no_mangle] +pub fn assign_in_env(mut word: *mut WORD_DESC, mut flags: libc::c_int) -> libc::c_int { + let mut offset: libc::c_int = 0; + let mut aflags: libc::c_int = 0; + let mut name: *mut libc::c_char = 0 as *mut libc::c_char; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + let mut newname: *mut libc::c_char = 0 as *mut libc::c_char; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut string: *const libc::c_char = 0 as *const libc::c_char; + + unsafe { + string = (*word).word; + aflags = 0 as libc::c_int; + offset = assignment(string, 0 as libc::c_int); + name = savestring!(string); + newname = name; + value = 0 as *mut libc::c_void as *mut libc::c_char; + + if *name.offset(offset as isize) as libc::c_int == '=' as i32 { + *name.offset(offset as isize) = 0 as libc::c_int as libc::c_char; + if *name.offset((offset - 1 as libc::c_int) as isize) as libc::c_int == '+' as i32 { + *name.offset((offset - 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + aflags |= ASS_APPEND as libc::c_int; + } + + if legal_identifier(name) == 0 as libc::c_int { + sh_invalidid(name); + return 0 as libc::c_int; + } + + var = find_variable(name); + if var.is_null() { + var = find_variable_last_nameref(name, 1 as libc::c_int); + if !var.is_null() + && nameref_p!(var) != 0 + && valid_nameref_value((*var).value, 2 as libc::c_int) != 0 + { + newname = nameref_cell!(var); + var = 0 as *mut SHELL_VAR; + } + } else { + newname = nameref_cell!(var); + } + if !var.is_null() && (readonly_p!(var) != 0 || noassign_p!(var) != 0) { + if readonly_p!(var) != 0 { + err_readonly(name); + } + free(name as *mut libc::c_void); + return 0 as libc::c_int; + } + temp = name + .offset(offset as isize) + .offset(1 as libc::c_int as isize); + + value = expand_assignment_string_to_string(temp, 0 as libc::c_int); + + if !var.is_null() && aflags & ASS_APPEND as libc::c_int != 0 { + if value.is_null() { + value = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *value.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + temp = make_variable_value(var, value, aflags); + if !value.is_null() { + free(value as *mut libc::c_void); + } + value = 0 as *mut libc::c_char; + value = temp; + } + } + if temporary_env.is_null() { + temporary_env = hash_create(TEMPENV_HASH_BUCKETS!() as libc::c_int); + } + var = hash_lookup(newname, temporary_env); + if var.is_null() { + var = make_new_variable(newname, temporary_env); + } else { + if !(value_cell!(var).is_null()) { + free(value_cell!(var) as *mut libc::c_void); + } + var_setvalue!(var, value); + } + + if value.is_null() { + value = libc::malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *value.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + + (*var).value = value; + (*var).attributes |= att_exported as libc::c_int | att_tempvar as libc::c_int; + (*var).context = variable_context; + + INVALIDATE_EXPORTSTR!(var); + + (*var).exportstr = mk_env_string(newname, value, 0 as libc::c_int); + array_needs_making = 1 as libc::c_int; + + if flags != 0 { + if STREQ( + newname, + b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char, + ) || STREQ( + newname, + b"POSIX_PEDANDTIC\0" as *const u8 as *const libc::c_char, + ) { + save_posix_options(); + } + stupidly_hack_special_variables(newname); + } + if echo_command_at_execute != 0 { + xtrace_print_assignment(name, value, 0 as libc::c_int, 1 as libc::c_int); + } + free(name as *mut libc::c_void); + } + return 1 as libc::c_int; +} + +fn dispose_variable_value(mut var: *mut SHELL_VAR) { + unsafe { + if function_p!(var) != 0 { + dispose_command((*var).value as *mut COMMAND); + } else if array_p!(var) != 0 { + array_dispose(array_cell!(var) as *mut ARRAY); + } else if assoc_p!(var) as libc::c_int != 0 { + assoc_dispose(assoc_cell!(var) as *mut HASH_TABLE); + } else if nameref_p!(var) != 0 { + if !nameref_cell!(var).is_null() { + free(nameref_cell!(var) as *mut libc::c_void); + } + } else if !value_cell!(var).is_null() { + free(value_cell!(var) as *mut libc::c_void); + } + } +} + +#[no_mangle] +pub fn dispose_variable(mut var: *mut SHELL_VAR) { + if var.is_null() { + return; + } + unsafe { + if nofree_p!(var) == 0 as libc::c_int { + dispose_variable_value(var); + } + + FREE_EXPORTSTR!(var); + free((*var).name as *mut libc::c_void); + + if exported_p!(var) != 0 { + array_needs_making = 1 as libc::c_int; + } + free(var as *mut libc::c_void); + } +} + +#[no_mangle] +pub fn unbind_variable(mut name: *const libc::c_char) -> libc::c_int { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut nv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut r: libc::c_int = 0; + unsafe { + v = var_lookup(name, shell_variables); + nv = if !v.is_null() && nameref_p!(v) != 0 { + find_variable_nameref(v) + } else { + 0 as *mut libc::c_void as *mut SHELL_VAR + }; + r = if !nv.is_null() { + makunbound((*nv).name, shell_variables) + } else { + makunbound(name, shell_variables) + }; + } + return r; +} + +#[no_mangle] +pub fn unbind_nameref(mut name: *const libc::c_char) -> libc::c_int { + unsafe { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = var_lookup(name, shell_variables); + if !v.is_null() && nameref_p!(v) != 0 { + return makunbound(name, shell_variables); + } + return 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn unbind_variable_noref(mut name: *const libc::c_char) -> libc::c_int { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + v = var_lookup(name, shell_variables); + if !v.is_null() { + return makunbound(name, shell_variables); + } + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn check_unbind_variable(mut name: *const libc::c_char) -> libc::c_int { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(name); + unsafe { + if !v.is_null() && readonly_p!(v) != 0 { + internal_error( + b"%s: cannot unset: readonly %s\0" as *const u8 as *const libc::c_char, + name, + b"variable\0" as *const u8 as *const libc::c_char, + ); + return -(2 as libc::c_int); + } else if !v.is_null() && non_unsettable_p!(v) != 0 { + internal_error( + b"%s: cannot unset\0" as *const u8 as *const libc::c_char, + name, + ); + return -(2 as libc::c_int); + } + } + return unbind_variable(name); +} + +#[no_mangle] +pub fn unbind_func(mut name: *const libc::c_char) -> libc::c_int { + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut func: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + elt = hash_remove(name, shell_functions, 0 as libc::c_int); + if elt.is_null() { + return -(1 as libc::c_int); + } + set_itemlist_dirty(&mut it_functions); + func = (*elt).data as *mut SHELL_VAR; + + if !func.is_null() { + if exported_p!(func) != 0 { + array_needs_making += 1; + array_needs_making; + } + dispose_variable(func); + } + free((*elt).key as *mut libc::c_void); + free(elt as *mut libc::c_void); + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn unbind_function_def(mut name: *const libc::c_char) -> libc::c_int { + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut funcdef: *mut FUNCTION_DEF = 0 as *mut FUNCTION_DEF; + unsafe { + elt = hash_remove(name, shell_function_defs, 0 as libc::c_int); + if elt.is_null() { + return -(1 as libc::c_int); + } + funcdef = (*elt).data as *mut FUNCTION_DEF; + + if !funcdef.is_null() { + dispose_function_def(funcdef); + } + free((*elt).key as *mut libc::c_void); + free(elt as *mut libc::c_void); + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn delete_var(mut name: *const libc::c_char, mut vc: *mut VAR_CONTEXT) -> libc::c_int { + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut old_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut v: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + elt = 0 as *mut libc::c_void as *mut BUCKET_CONTENTS; + v = vc; + unsafe { + while !v.is_null() { + elt = hash_remove(name, (*v).table, 0 as libc::c_int); + if !elt.is_null() { + break; + } + v = (*v).down; + } + if elt.is_null() { + return -(1 as libc::c_int); + } + old_var = (*elt).data as *mut SHELL_VAR; + free((*elt).key as *mut libc::c_void); + free(elt as *mut libc::c_void); + dispose_variable(old_var); + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn makunbound(mut name: *const libc::c_char, mut vc: *mut VAR_CONTEXT) -> libc::c_int { + let mut elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut new_elt: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut old_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut v: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + elt = 0 as *mut libc::c_void as *mut BUCKET_CONTENTS; + v = vc; + unsafe { + while !v.is_null() { + elt = hash_remove(name, (*v).table, 0 as libc::c_int); + if !elt.is_null() { + break; + } + v = (*v).down; + } + if elt.is_null() { + return -(1 as libc::c_int); + } + old_var = (*elt).data as *mut SHELL_VAR; + + if !old_var.is_null() && exported_p!(old_var) != 0 { + array_needs_making += 1; + array_needs_making; + } + if !old_var.is_null() + && local_p!(old_var) != 0 + && ((*old_var).context == variable_context + || localvar_unset != 0 && (*old_var).context < variable_context) + { + if nofree_p!(old_var) != 0 { + var_setvalue!(old_var, 0 as *mut libc::c_void as *mut libc::c_char); + } else if array_p!(old_var) != 0 { + array_dispose((*old_var).value as *mut ARRAY); + } else if assoc_p!(old_var) != 0 { + assoc_dispose((*old_var).value as *mut HASH_TABLE); + } else if nameref_p!(old_var) != 0 { + if !(nameref_cell!(old_var).is_null()) { + free(nameref_cell!(old_var) as *mut libc::c_void); + } + } else { + if !value_cell!(old_var).is_null() { + free(value_cell!(old_var) as *mut libc::c_void); + } + } + (*old_var).attributes = if exported_p!(old_var) != 0 && tempvar_p!(old_var) != 0 { + att_exported as libc::c_int + } else { + 0 as libc::c_int + }; + VSETATTR!(old_var, att_local); + VSETATTR!(old_var, att_invisible); + var_setvalue!(old_var, 0 as *mut libc::c_void as *mut libc::c_char); + INVALIDATE_EXPORTSTR!(old_var); + + if !((*old_var).exportstr).is_null() { + free((*old_var).exportstr as *mut libc::c_void); + (*old_var).exportstr = 0 as *mut libc::c_void as *mut libc::c_char; + } + new_elt = hash_insert(savestring!((*old_var).name), (*v).table, 0 as libc::c_int); + (*new_elt).data = old_var as *mut libc::c_void; + stupidly_hack_special_variables((*old_var).name); + free((*elt).key as *mut libc::c_void); + free(elt as *mut libc::c_void); + return 0 as libc::c_int; + } + t = savestring!(name); + free((*elt).key as *mut libc::c_void); + free(elt as *mut libc::c_void); + dispose_variable(old_var); + stupidly_hack_special_variables(t); + free(t as *mut libc::c_void); + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn kill_all_local_variables() { + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + unsafe { + vc = shell_variables; + while !vc.is_null() { + if vc_isfuncenv!(vc) && (*vc).scope == variable_context { + break; + } + vc = (*vc).down; + } + if vc.is_null() { + return; + } + if !((*vc).table).is_null() && vc_haslocals!(vc) { + delete_all_variables((*vc).table); + hash_dispose((*vc).table); + } + (*vc).table = 0 as *mut libc::c_void as *mut HASH_TABLE; + } +} + +fn free_variable_hash_data(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = data as *mut SHELL_VAR; + dispose_variable(var); +} + +#[no_mangle] +pub fn delete_all_variables(mut hashed_vars: *mut HASH_TABLE) { + unsafe { + hash_flush( + hashed_vars, + ::core::mem::transmute:: ()>, sh_free_func_t>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + free_variable_hash_data, + ), + )), + ); + } +} + +#[no_mangle] +pub fn set_var_read_only(mut name: *mut libc::c_char) { + let mut entry: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + entry = find_variable(name); + unsafe { + FIND_OR_MAKE_VARIABLE!(name, entry); + VSETATTR!(entry, att_readonly); + } +} + +fn vlist_alloc(mut nentries: libc::c_int) -> *mut VARLIST { + let mut vlist: *mut VARLIST = 0 as *mut VARLIST; + unsafe { + vlist = libc::malloc(std::mem::size_of::() as usize) as *mut VARLIST; + (*vlist).list = libc::malloc( + ((nentries + 1 as libc::c_int) as usize) + * (std::mem::size_of::<*mut SHELL_VAR>() as usize), + ) as *mut *mut SHELL_VAR; + + (*vlist).list_size = nentries as usize; + (*vlist).list_len = 0 as libc::c_int as usize; + + *((*vlist).list).offset(0 as libc::c_int as isize) = + 0 as *mut libc::c_void as *mut SHELL_VAR; + } + return vlist; +} + +fn vlist_realloc(mut vlist: *mut VARLIST, mut n: libc::c_int) -> *mut VARLIST { + if vlist.is_null() { + vlist = vlist_alloc(n); + return vlist; + } + unsafe { + if n as size_t > (*vlist).list_size as u64 { + (*vlist).list_size = n as usize; + (*vlist).list = libc::realloc( + (*vlist).list as *mut libc::c_void, + ((*vlist).list_size + 1 as usize) + * (std::mem::size_of::<*mut SHELL_VAR>() as usize), + ) as *mut *mut SHELL_VAR; + } + } + return vlist; +} + +fn vlist_add(mut vlist: *mut VARLIST, mut var: *mut SHELL_VAR, mut flags: libc::c_int) { + let mut i: libc::c_int = 0; + i = 0 as libc::c_int; + unsafe { + while (i as size_t) < (*vlist).list_len as u64 { + if STREQ((*var).name, (**((*vlist).list).offset(i as isize)).name) { + break; + } + i += 1; + i; + } + if (i as size_t) < (*vlist).list_len as u64 { + return; + } + if i as size_t >= (*vlist).list_size as u64 { + vlist = vlist_realloc( + vlist, + ((*vlist).list_size + 16 as libc::c_int as usize) as libc::c_int, + ); + } + + *((*vlist).list).offset((*vlist).list_len as isize) = var; + (*vlist).list_len = (*vlist).list_len + 1 as usize; + *((*vlist).list).offset((*vlist).list_len as isize) = + 0 as *mut libc::c_void as *mut SHELL_VAR; + } +} + +#[no_mangle] +pub fn map_over( + mut function: Option, + mut vc: *mut VAR_CONTEXT, +) -> *mut *mut SHELL_VAR { + let mut v: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut vlist: *mut VARLIST = 0 as *mut VARLIST; + let mut ret: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + let mut nentries: libc::c_int = 0; + nentries = 0 as libc::c_int; + v = vc; + unsafe { + while !v.is_null() { + nentries += HASH_ENTRIES!((*v).table); + v = (*v).down; + } + if nentries == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut *mut SHELL_VAR; + } + vlist = vlist_alloc(nentries); + v = vc; + while !v.is_null() { + flatten((*v).table, function, vlist, 0 as libc::c_int); + v = (*v).down; + } + ret = (*vlist).list; + free(vlist as *mut libc::c_void); + } + return ret; +} + +#[no_mangle] +pub fn map_over_funcs(mut function: Option) -> *mut *mut SHELL_VAR { + let mut vlist: *mut VARLIST = 0 as *mut VARLIST; + let mut ret: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + unsafe { + if shell_functions.is_null() || HASH_ENTRIES!(shell_functions) == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut *mut SHELL_VAR; + } + vlist = vlist_alloc(HASH_ENTRIES!(shell_functions)); + flatten(shell_functions, function, vlist, 0 as libc::c_int); + ret = (*vlist).list; + free(vlist as *mut libc::c_void); + } + return ret; +} + +fn flatten( + mut var_hash_table: *mut HASH_TABLE, + mut func: Option, + mut vlist: *mut VARLIST, + mut flags: libc::c_int, +) { + let mut i: libc::c_int = 0; + let mut tlist: *mut BUCKET_CONTENTS = 0 as *mut BUCKET_CONTENTS; + let mut r: libc::c_int = 0; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + if var_hash_table.is_null() + || HASH_ENTRIES!(var_hash_table) == 0 as libc::c_int + || vlist.is_null() && func.is_none() + { + return; + } + i = 0 as libc::c_int; + + while i < (*var_hash_table).nbuckets { + tlist = hash_items!(i, var_hash_table); + while !tlist.is_null() { + var = (*tlist).data as *mut SHELL_VAR; + r = if func.is_some() { + Some(func.expect("non-null function pointer")) + .expect("non-null function pointer")(var) + } else { + 1 as libc::c_int + }; + if r != 0 && !vlist.is_null() { + vlist_add(vlist, var, flags); + } + tlist = (*tlist).next; + } + i += 1; + i; + } + } +} + +#[no_mangle] +pub fn sort_variables(mut array: *mut *mut SHELL_VAR) { + unsafe { + qsort( + array as *mut libc::c_void, + strvec_len(array as *mut *mut libc::c_char) as usize, + std::mem::size_of::<*mut SHELL_VAR>() as usize, + std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some( + qsort_var_comp as fn(*mut *mut SHELL_VAR, *mut *mut SHELL_VAR) -> libc::c_int, + )), + ) + } +} + +fn qsort_var_comp(mut var1: *mut *mut SHELL_VAR, mut var2: *mut *mut SHELL_VAR) -> libc::c_int { + let mut result: libc::c_int = 0; + unsafe { + result = *((**var1).name).offset(0 as libc::c_int as isize) as libc::c_int + - *((**var2).name).offset(0 as libc::c_int as isize) as libc::c_int; + if result == 0 as libc::c_int { + result = libc::strcmp((**var1).name, (**var2).name); + } + } + return result; +} + +fn vapply(mut func: Option) -> *mut *mut SHELL_VAR { + let mut list: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + unsafe { + list = map_over(func, shell_variables); + } + if !list.is_null() { + sort_variables(list); + } + return list; +} + +fn fapply(mut func: Option) -> *mut *mut SHELL_VAR { + let mut list: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + list = map_over_funcs(func); + if !list.is_null() { + sort_variables(list); + } + return list; +} + +#[no_mangle] +pub fn all_shell_variables() -> *mut *mut SHELL_VAR { + unsafe { + return vapply(std::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void)); + } +} +#[no_mangle] +pub fn all_shell_functions() -> *mut *mut SHELL_VAR { + unsafe { + return fapply(::core::mem::transmute::< + *mut libc::c_void, + Option, + >(0 as *mut libc::c_void)); + } +} +fn visible_var(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if invisible_p!(var) == 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} + +#[no_mangle] +pub fn all_visible_functions() -> *mut *mut SHELL_VAR { + unsafe { + return fapply(::core::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(::core::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(visible_var)))); + } +} + +#[no_mangle] +pub fn all_visible_variables() -> *mut *mut SHELL_VAR { + unsafe { + return vapply(::core::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(::core::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(visible_var)))); + } +} +fn visible_and_exported(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if invisible_p!(var) == 0 && exported_p!(var) != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} + +fn export_environment_candidate(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if exported_p!(var) != 0 && invisible_p!(var) == 0 as libc::c_int || imported_p!(var) != 0 { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} + +fn local_and_exported(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if invisible_p!(var) == 0 as libc::c_int + && local_p!(var) != 0 + && (*var).context == variable_context + && exported_p!(var) != 0 + { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} + +#[no_mangle] +pub fn all_exported_variables() -> *mut *mut SHELL_VAR { + unsafe { + return vapply(std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(std::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(visible_and_exported)))); + } +} + +#[no_mangle] +pub fn local_exported_variables() -> *mut *mut SHELL_VAR { + unsafe { + return vapply(::core::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(::core::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(local_and_exported)))); + } +} +fn variable_in_context(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if local_p!(var) != 0 && (*var).context == variable_context { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} +fn visible_variable_in_context(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if invisible_p!(var) == 0 as libc::c_int + && local_p!(var) != 0 + && (*var).context == variable_context + { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} + +#[no_mangle] +pub fn all_local_variables(mut visible_only: libc::c_int) -> *mut *mut SHELL_VAR { + let mut vlist: *mut VARLIST = 0 as *mut VARLIST; + let mut ret: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + unsafe { + vc = shell_variables; + vc = shell_variables; + while !vc.is_null() { + if vc_isfuncenv!(vc) && (*vc).scope == variable_context { + break; + } + vc = (*vc).down; + } + if vc.is_null() { + internal_error( + b"all_local_variables: no function context at current scope\0" as *const u8 + as *const libc::c_char, + ); + return 0 as *mut libc::c_void as *mut *mut SHELL_VAR; + } + if ((*vc).table).is_null() + || HASH_ENTRIES!((*vc).table) == 0 as libc::c_int + || vc_haslocals!(vc) + { + return 0 as *mut libc::c_void as *mut *mut SHELL_VAR; + } + vlist = vlist_alloc(HASH_ENTRIES!((*vc).table)); + if visible_only != 0 { + flatten( + (*vc).table, + ::core::mem::transmute:: libc::c_int>, Option>( + Some(::core::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(visible_variable_in_context)), + ), + vlist, + 0 as libc::c_int, + ); + } else { + flatten( + (*vc).table, + ::core::mem::transmute:: libc::c_int>, Option>( + Some(::core::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(variable_in_context)), + ), + vlist, + 0 as libc::c_int, + ); + } + ret = (*vlist).list; + free(vlist as *mut libc::c_void); + if !ret.is_null() { + sort_variables(ret); + } + } + return ret; +} + +fn visible_array_vars(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + if invisible_p!(var) == 0 as libc::c_int && (array_p!(var) != 0 || assoc_p!(var) != 0) { + 1 as libc::c_int + } else { + 0 as libc::c_int + } + } +} + +#[no_mangle] +pub fn all_array_variables() -> *mut *mut SHELL_VAR { + unsafe { + return vapply(std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(std::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(visible_array_vars)))); + } +} + +#[no_mangle] +pub fn all_variables_matching_prefix(mut prefix: *const libc::c_char) -> *mut *mut libc::c_char { + let mut varlist: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + let mut rlist: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut vind: libc::c_int = 0; + let mut rind: libc::c_int = 0; + let mut plen: libc::c_int = 0; + unsafe { + plen = STRLEN!(prefix); + + varlist = all_visible_variables(); + vind = 0 as libc::c_int; + + while !varlist.is_null() && !(*varlist.offset(vind as isize)).is_null() { + vind += 1; + vind; + } + if varlist.is_null() || vind == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + rlist = strvec_create(vind + 1 as libc::c_int); + rind = 0 as libc::c_int; + vind = rind; + while !(*varlist.offset(vind as isize)).is_null() { + if plen == 0 as libc::c_int + || STREQN(prefix, (**varlist.offset(vind as isize)).name, plen) + { + *rlist.offset(rind as isize) = savestring!((**varlist.offset(vind as isize)).name); + rind += 1; + } + vind += 1; + } + *rlist.offset(rind as isize) = 0 as *mut libc::c_char; + free(varlist as *mut libc::c_void); + } + return rlist; +} + +fn bind_tempenv_variable( + mut name: *const libc::c_char, + mut value: *mut libc::c_char, +) -> *mut SHELL_VAR { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + unsafe { + var = if !temporary_env.is_null() { + hash_lookup(name, temporary_env) + } else { + 0 as *mut libc::c_void as *mut SHELL_VAR + }; + + if !var.is_null() { + if !((*var).value).is_null() { + free((*var).value as *mut libc::c_void); + } + var_setvalue!(var, savestring!(value)); + INVALIDATE_EXPORTSTR!(var); + } + } + return var; +} + +#[no_mangle] +pub fn find_tempenv_variable(mut name: *const libc::c_char) -> *mut SHELL_VAR { + unsafe { + return if !temporary_env.is_null() { + hash_lookup(name, temporary_env) + } else { + 0 as *mut libc::c_void as *mut SHELL_VAR + }; + } +} +#[no_mangle] +pub static mut tempvar_list: *mut *mut libc::c_char = + 0 as *const *mut libc::c_char as *mut *mut libc::c_char; + +#[no_mangle] +pub static mut tvlist_ind: libc::c_int = 0; +fn push_posix_temp_var(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut binding_table: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + + var = data as *mut SHELL_VAR; + unsafe { + v = bind_variable( + (*var).name, + value_cell!(var), + ASS_FORCE as libc::c_int | ASS_NOLONGJMP as libc::c_int, + ); + + binding_table = if (*v).context != 0 { + (*shell_variables).table + } else { + (*global_variables).table + }; + if (*v).context == 0 as libc::c_int { + (*var).attributes &= !(att_tempvar as libc::c_int | att_propagate as libc::c_int); + } + if !v.is_null() { + (*v).attributes |= (*var).attributes; + if (*v).context > 0 as libc::c_int && local_p!(v) == 0 as libc::c_int { + (*v).attributes |= att_propagate as libc::c_int; + } else { + (*v).attributes &= !(att_propagate as libc::c_int); + } + } + if find_special_var((*var).name) >= 0 as libc::c_int { + *tempvar_list.offset(tvlist_ind as isize) = savestring!((*var).name); + tvlist_ind += 1; + } + } + dispose_variable(var); +} + +fn push_temp_var(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut binding_table: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + var = data as *mut SHELL_VAR; + unsafe { + binding_table = (*shell_variables).table; + if binding_table.is_null() { + if shell_variables == global_variables { + (*global_variables).table = hash_create(VARIABLES_HASH_BUCKETS!() as libc::c_int); + (*shell_variables).table = (*global_variables).table; + binding_table = (*shell_variables).table; + } else { + (*shell_variables).table = hash_create(TEMPENV_HASH_BUCKETS!() as libc::c_int); + binding_table = (*shell_variables).table; + } + } + + v = bind_variable_internal( + (*var).name, + value_cell!(var), + binding_table, + 0 as libc::c_int, + ASS_FORCE as libc::c_int | ASS_NOLONGJMP as libc::c_int, + ); + if !v.is_null() { + (*v).context = (*shell_variables).scope; + } + if binding_table == (*global_variables).table { + (*var).attributes &= !(att_tempvar as libc::c_int | att_propagate as libc::c_int); + } else { + (*var).attributes |= att_propagate as libc::c_int; + if binding_table == (*shell_variables).table { + (*shell_variables).flags |= VC_HASTMPVAR as libc::c_int; + } + } + if !v.is_null() { + (*v).attributes |= (*var).attributes; + } + if find_special_var((*var).name) >= 0 as libc::c_int { + *tempvar_list.offset(tvlist_ind as isize) = savestring!((*var).name); + tvlist_ind += 1; + } + } + dispose_variable(var); +} + +fn propagate_temp_var(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = data as *mut SHELL_VAR; + unsafe { + if tempvar_p!(var) != 0 && (*var).attributes & att_propagate as libc::c_int != 0 { + push_temp_var(data); + } else { + if find_special_var((*var).name) >= 0 as libc::c_int { + *tempvar_list.offset(tvlist_ind as isize) = savestring!((*var).name); + tvlist_ind += 1; + } + dispose_variable(var); + }; + } +} + +fn dispose_temporary_env(mut pushf: sh_free_func_t) { + let mut i: libc::c_int = 0; + let mut disposer: *mut HASH_TABLE = 0 as *mut HASH_TABLE; + unsafe { + tempvar_list = strvec_create(HASH_ENTRIES!(temporary_env) + 1 as libc::c_int); + tvlist_ind = 0 as libc::c_int; + *tempvar_list.offset(tvlist_ind as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + + disposer = temporary_env; + temporary_env = 0 as *mut libc::c_void as *mut HASH_TABLE; + + hash_flush(disposer, pushf); + hash_dispose(disposer); + + *tempvar_list.offset(tvlist_ind as isize) = 0 as *mut libc::c_char; + + array_needs_making = 1 as libc::c_int; + i = 0 as libc::c_int; + while i < tvlist_ind { + stupidly_hack_special_variables(*tempvar_list.offset(i as isize)); + i += 1; + i; + } + strvec_dispose(tempvar_list); + tempvar_list = 0 as *mut *mut libc::c_char; + tvlist_ind = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn dispose_used_env_vars() { + unsafe { + if !temporary_env.is_null() { + dispose_temporary_env( + ::core::mem::transmute:: ()>, sh_free_func_t>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + propagate_temp_var, + ), + )), + ); + maybe_make_export_env(); + } + } +} + +#[no_mangle] +pub fn merge_temporary_env() { + unsafe { + if !temporary_env.is_null() { + dispose_temporary_env( + ::core::mem::transmute:: ()>, sh_free_func_t>( + if posixly_correct != 0 { + Some(::core::mem::transmute::< + fn(*mut libc::c_void) -> (), + fn() -> (), + >(push_posix_temp_var)) + } else { + Some(::core::mem::transmute::< + fn(*mut libc::c_void) -> (), + fn() -> (), + >(push_temp_var)) + }, + ), + ); + } + } +} +#[no_mangle] +pub fn merge_function_temporary_env() { + unsafe { + if !temporary_env.is_null() { + dispose_temporary_env( + ::core::mem::transmute:: ()>, sh_free_func_t>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + push_temp_var, + ), + )), + ); + } + } +} + +#[no_mangle] +pub fn flush_temporary_env() { + unsafe { + if !temporary_env.is_null() { + hash_flush( + temporary_env, + ::core::mem::transmute:: ()>, sh_free_func_t>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + free_variable_hash_data, + ), + )), + ); + hash_dispose(temporary_env); + temporary_env = 0 as *mut libc::c_void as *mut HASH_TABLE; + } + } +} + +#[inline] +fn mk_env_string( + mut name: *const libc::c_char, + mut value: *const libc::c_char, + mut isfunc: libc::c_int, +) -> *mut libc::c_char { + let mut name_len: size_t = 0; + let mut value_len: size_t = 0; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut q: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + name_len = strlen(name) as size_t; + value_len = STRLEN!(value) as size_t; + + if isfunc != 0 && !value.is_null() { + p = libc::malloc( + BASHFUNC_PREFLEN!() as usize + + name_len as usize + + BASHFUNC_SUFFLEN!() as usize + + value_len as usize + + 2 as usize, + ) as *mut libc::c_char; + q = p; + memcpy( + q as *mut libc::c_void, + BASHFUNC_PREFIX!() as *const c_void, + BASHFUNC_PREFLEN!() as usize, + ); + q = q.offset(10 as libc::c_int as isize); + memcpy( + q as *mut libc::c_void, + name as *const libc::c_void, + name_len as usize, + ); + q = q.offset(name_len as isize); + memcpy( + q as *mut libc::c_void, + b"%%\0" as *const u8 as *const libc::c_char as *const libc::c_void, + BASHFUNC_SUFFLEN!() as libc::c_int as usize, + ); + q = q.offset(BASHFUNC_SUFFLEN!() as libc::c_int as isize); + } else { + p = libc::malloc(2 as usize + name_len as usize + value_len as usize) + as *mut libc::c_char; + memcpy( + p as *mut libc::c_void, + name as *const libc::c_void, + name_len as usize, + ); + q = p.offset(name_len as isize); + } + + *q.offset(0 as libc::c_int as isize) = '=' as i32 as libc::c_char; + + if !value.is_null() && *value as libc::c_int != 0 { + if isfunc != 0 { + t = dequote_escapes(value); + value_len = STRLEN!(t) as u64; + memcpy( + q.offset(1 as libc::c_int as isize) as *mut libc::c_void, + t as *const libc::c_void, + (value_len + 1) as libc::c_int as usize, + ); + free(t as *mut libc::c_void); + } else { + memcpy( + q.offset(1 as libc::c_int as isize) as *mut libc::c_void, + value as *const libc::c_void, + (value_len + 1) as libc::c_int as usize, + ); + } + } else { + *q.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + } + return p; +} + +fn make_env_array_from_var_list(mut vars: *mut *mut SHELL_VAR) -> *mut *mut libc::c_char { + unsafe { + let mut i: libc::c_int = 0; + let mut list_index: libc::c_int = 0; + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut list: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut value: *mut libc::c_char = 0 as *mut libc::c_char; + + list = strvec_create(1 as libc::c_int + strvec_len(vars as *mut *mut libc::c_char)); + let mut current_block_19: u64; + i = 0 as libc::c_int; + list_index = 0 as libc::c_int; + + loop { + var = *vars.offset(i as isize); + if var.is_null() { + break; + } + if regen_p!(var) != 0 && ((*var).dynamic_value).is_some() { + var = (Some(((*var).dynamic_value).expect("non-null function pointer"))) + .expect("non-null function pointer")(var); + INVALIDATE_EXPORTSTR!(var); + } + if !((*var).exportstr).is_null() { + value = (*var).exportstr; + } else if function_p!(var) != 0 { + value = named_function_string( + 0 as *mut libc::c_void as *mut libc::c_char, + function_cell!(var), + 0 as libc::c_int, + ); + } else if array_p!(var) != 0 { + i += 1; + continue; + } else if assoc_p!(var) != 0 { + i += 1; + continue; + } else { + value = (*var).value; + } + if !value.is_null() { + *list.offset(list_index as isize) = if value == (*var).exportstr { + savestring!(value) + } else { + mk_env_string((*var).name, value, function_p!(var) as libc::c_int) + }; + + if value != (*var).exportstr { + SAVE_EXPORTSTR!(var, (*list).offset(list_index as isize)) + } + list_index += 1; + list_index; + } + i += 1; + i; + } + + *(list.offset((list_index as size_t).try_into().unwrap())) = + 0 as *mut libc::c_void as *mut libc::c_char; + + return list; + } +} + +fn make_var_export_array(mut vcxt: *mut VAR_CONTEXT) -> *mut *mut libc::c_char { + let mut list: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut vars: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + unsafe { + vars = map_over( + std::mem::transmute:: libc::c_int>, Option>(Some( + std::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + export_environment_candidate, + ), + )), + vcxt, + ); + if vars.is_null() { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + list = make_env_array_from_var_list(vars); + free(vars as *mut libc::c_void); + } + return list; +} + +fn make_func_export_array() -> *mut *mut libc::c_char { + let mut list: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut vars: *mut *mut SHELL_VAR = 0 as *mut *mut SHELL_VAR; + unsafe { + vars = map_over_funcs(std::mem::transmute::< + Option libc::c_int>, + Option, + >(Some(std::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(visible_and_exported)))); + if vars.is_null() { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + list = make_env_array_from_var_list(vars); + free(vars as *mut libc::c_void); + } + return list; +} + +#[no_mangle] +pub fn add_or_supercede_exported_var( + mut assign: *mut libc::c_char, + mut do_alloc: libc::c_int, +) -> *mut *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut equal_offset: libc::c_int = 0; + unsafe { + equal_offset = assignment(assign, 0 as libc::c_int); + if equal_offset == 0 as libc::c_int { + return export_env; + } + if *assign.offset((equal_offset + 1 as libc::c_int) as isize) as libc::c_int == '(' as i32 + && libc::strncmp( + assign + .offset(equal_offset as isize) + .offset(2 as libc::c_int as isize), + b") {\0" as *const u8 as *const libc::c_char, + 3 as libc::c_int as usize, + ) == 0 as libc::c_int + { + equal_offset += 4 as libc::c_int; + } + i = 0 as libc::c_int; + while i < export_env_index { + if STREQN( + assign, + *export_env.offset(i as isize) as *mut libc::c_char, + equal_offset + 1, + ) { + free(*export_env.offset(i as isize) as *mut libc::c_void); + *export_env.offset(i as isize) = if do_alloc != 0 { + savestring!(assign) + } else { + assign + }; + return export_env; + } + i += 1; + i; + } + + add_to_export_env!(assign, do_alloc); + return export_env; + } +} + +fn add_temp_array_to_env( + mut temp_array: *mut *mut libc::c_char, + mut do_alloc: libc::c_int, + mut do_supercede: libc::c_int, +) { + let mut i: libc::c_int = 0; + if temp_array.is_null() { + return; + } + i = 0 as libc::c_int; + unsafe { + while !(*temp_array.offset(i as isize)).is_null() { + if do_supercede != 0 { + export_env = + add_or_supercede_exported_var(*temp_array.offset(i as isize), do_alloc); + } else { + add_to_export_env!(*temp_array.offset(i as isize), do_alloc); + } + i += 1; + } + free(temp_array as *mut libc::c_void); + } +} + +fn n_shell_variables() -> libc::c_int { + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut n: libc::c_int = 0; + unsafe { + n = 0 as libc::c_int; + vc = shell_variables; + + while !vc.is_null() { + n += HASH_ENTRIES!((*vc).table); + vc = (*vc).down; + } + } + return n; +} + +#[no_mangle] +pub fn chkexport(mut name: *mut libc::c_char) -> libc::c_int { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(name); + unsafe { + if !v.is_null() && exported_p!(v) != 0 { + array_needs_making = 1 as libc::c_int; + maybe_make_export_env(); + return 1 as libc::c_int; + } + } + return 0 as libc::c_int; +} + +#[no_mangle] +pub fn maybe_make_export_env() { + let mut temp_array: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut new_size: libc::c_int = 0; + let mut tcxt: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut icxt: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + unsafe { + if array_needs_making != 0 { + if !export_env.is_null() { + strvec_flush(export_env); + } + new_size = n_shell_variables() + + HASH_ENTRIES!(shell_functions) + + 1 as libc::c_int + + HASH_ENTRIES!(temporary_env) + + HASH_ENTRIES!(invalid_env); + if new_size > export_env_size { + export_env_size = new_size; + export_env = strvec_resize(export_env, export_env_size); + environ = export_env; + } + export_env_index = 0 as libc::c_int; + *export_env.offset(export_env_index as isize) = + 0 as *mut libc::c_void as *mut libc::c_char; + + if !temporary_env.is_null() { + tcxt = new_var_context( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int, + ); + (*tcxt).table = temporary_env; + (*tcxt).down = shell_variables; + } else { + tcxt = shell_variables; + } + if !invalid_env.is_null() { + icxt = new_var_context( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int, + ); + (*icxt).table = invalid_env; + (*icxt).down = tcxt; + } else { + icxt = tcxt; + } + temp_array = make_var_export_array(icxt); + if !temp_array.is_null() { + add_temp_array_to_env(temp_array, 0 as libc::c_int, 0 as libc::c_int); + } + if icxt != tcxt { + free(icxt as *mut libc::c_void); + } + if tcxt != shell_variables { + free(tcxt as *mut libc::c_void); + } + temp_array = if restricted != 0 { + 0 as *mut *mut libc::c_char + } else { + make_func_export_array() + }; + if !temp_array.is_null() { + add_temp_array_to_env(temp_array, 0 as libc::c_int, 0 as libc::c_int); + } + array_needs_making = 0 as libc::c_int; + } + } +} + +#[no_mangle] +pub fn update_export_env_inplace( + mut env_prefix: *mut libc::c_char, + mut preflen: libc::c_int, + mut value: *mut libc::c_char, +) { + let mut evar: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + evar = libc::malloc((STRLEN!(value) + preflen + 1) as usize) as *mut libc::c_char; + libc::strcpy(evar, env_prefix); + if !value.is_null() { + libc::strcpy(evar.offset(preflen as isize), value); + } + export_env = add_or_supercede_exported_var(evar, 0 as libc::c_int); + } +} + +#[no_mangle] +pub fn put_command_name_into_env(mut command_name: *mut libc::c_char) { + update_export_env_inplace( + b"_=\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + 2 as libc::c_int, + command_name, + ); +} + +#[no_mangle] +pub fn new_var_context(mut name: *mut libc::c_char, mut flags: libc::c_int) -> *mut VAR_CONTEXT { + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + unsafe { + vc = libc::malloc(std::mem::size_of::() as usize) as *mut VAR_CONTEXT; + + (*vc).name = if !name.is_null() { + savestring!(name) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + + (*vc).scope = variable_context; + (*vc).flags = flags; + (*vc).down = 0 as *mut libc::c_void as *mut VAR_CONTEXT; + (*vc).up = (*vc).down; + (*vc).table = 0 as *mut libc::c_void as *mut HASH_TABLE; + } + return vc; +} + +#[no_mangle] +pub fn dispose_var_context(mut vc: *mut VAR_CONTEXT) { + unsafe { + if !((*vc).name).is_null() { + free((*vc).name as *mut libc::c_void); + } + (*vc).name = 0 as *mut libc::c_char; + if !((*vc).table).is_null() { + delete_all_variables((*vc).table); + hash_dispose((*vc).table); + } + free(vc as *mut libc::c_void); + } +} + +fn set_context(mut var: *mut SHELL_VAR) -> libc::c_int { + unsafe { + (*var).context = variable_context; + return (*var).context; + } +} + +#[no_mangle] +pub fn push_var_context( + mut name: *mut libc::c_char, + mut flags: libc::c_int, + mut tempvars: *mut HASH_TABLE, +) -> *mut VAR_CONTEXT { + let mut vc: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut posix_func_behavior: libc::c_int = 0; + posix_func_behavior = 0 as libc::c_int; + + vc = new_var_context(name, flags); + unsafe { + if posix_func_behavior != 0 + && (flags & VC_FUNCENV!()) as libc::c_int != 0 + && tempvars == temporary_env + { + merge_temporary_env(); + } else if !tempvars.is_null() { + (*vc).table = tempvars; + flatten( + tempvars, + std::mem::transmute:: libc::c_int>, Option>( + Some(std::mem::transmute::< + fn(*mut SHELL_VAR) -> libc::c_int, + fn() -> libc::c_int, + >(set_context)), + ), + 0 as *mut libc::c_void as *mut VARLIST, + 0 as libc::c_int, + ); + (*vc).flags |= VC_HASTMPVAR as libc::c_int; + } + (*vc).down = shell_variables; + (*shell_variables).up = vc; + shell_variables = vc; + return shell_variables; + } +} + +#[inline] +fn push_posix_tempvar_internal(mut var: *mut SHELL_VAR, mut isbltin: libc::c_int) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut posix_var_behavior: libc::c_int = 0; + unsafe { + posix_var_behavior = (posixly_correct != 0 && isbltin != 0) as libc::c_int; + v = 0 as *mut SHELL_VAR; + + if local_p!(var) != 0 && STREQ((*var).name, b"-\0" as *const u8 as *const libc::c_char) { + set_current_options(value_cell!(var)); + set_shellopts(); + } else if tempvar_p!(var) != 0 && posix_var_behavior != 0 { + v = bind_variable( + (*var).name, + value_cell!(var), + ASS_FORCE as libc::c_int | ASS_NOLONGJMP as libc::c_int, + ); + if !v.is_null() { + (*v).attributes |= (*var).attributes; + if (*v).context == 0 as libc::c_int { + (*v).attributes &= !(att_tempvar as libc::c_int | att_propagate as libc::c_int); + } + } + } else if tempvar_p!(var) != 0 && propagate_p!(var) != 0 { + if (vc_isfuncenv!(shell_variables) || vc_istempenv!(shell_variables)) + && ((*shell_variables).table).is_null() + { + (*shell_variables).table = hash_create(VARIABLES_HASH_BUCKETS!() as libc::c_int); + } + + v = bind_variable_internal( + (*var).name, + value_cell!(var), + (*shell_variables).table, + 0 as libc::c_int, + 0 as libc::c_int, + ); + if !v.is_null() { + (*v).context = (*shell_variables).scope; + } + if shell_variables == global_variables { + (*var).attributes &= !(att_tempvar as libc::c_int | att_propagate as libc::c_int); + } else { + (*shell_variables).flags |= VC_HASTMPVAR as libc::c_int; + } + if !v.is_null() { + (*v).attributes |= (*var).attributes; + } + } else { + stupidly_hack_special_variables((*var).name); + } + if !v.is_null() && (array_p!(var) != 0 || assoc_p!(var) != 0) { + if !((*v).value).is_null() { + free((*v).value as *mut libc::c_void); + } + (*v).value = 0 as *mut libc::c_char; + if array_p!(var) != 0 { + var_setarray!(v, array_copy(array_cell!(var)) as *mut libc::c_char); + } else { + var_setassoc!(v, assoc_copy!(assoc_cell!(var))); + } + } + } + dispose_variable(var); +} + +fn push_func_var(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = data as *mut SHELL_VAR; + push_posix_tempvar_internal(var, 0 as libc::c_int); +} + +fn push_builtin_var(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = data as *mut SHELL_VAR; + push_posix_tempvar_internal(var, 1 as libc::c_int); +} + +#[no_mangle] +pub fn pop_var_context() { + let mut ret: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut vcxt: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + unsafe { + vcxt = shell_variables; + + if !vc_isfuncenv!(vcxt) { + internal_error( + b"pop_var_context: head of shell_variables not a function context\0" as *const u8 + as *const libc::c_char, + ); + return; + } + ret = (*vcxt).down; + + if !ret.is_null() { + (*ret).up = 0 as *mut libc::c_void as *mut VAR_CONTEXT; + shell_variables = ret; + if !((*vcxt).table).is_null() { + hash_flush( + (*vcxt).table, + std::mem::transmute:: ()>, sh_free_func_t>(Some( + std::mem::transmute:: (), fn() -> ()>( + push_func_var, + ), + )), + ); + } + dispose_var_context(vcxt); + } else { + internal_error( + b"pop_var_context: no global_variables context\0" as *const u8 + as *const libc::c_char, + ); + }; + } +} + +#[no_mangle] +pub fn delete_all_contexts(mut vcxt: *mut VAR_CONTEXT) { + let mut v: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut t: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + v = vcxt; + unsafe { + while v != global_variables { + t = (*v).down; + dispose_var_context(v); + v = t; + } + delete_all_variables((*global_variables).table); + shell_variables = global_variables; + } +} + +#[no_mangle] +pub fn push_scope(mut flags: libc::c_int, mut tmpvars: *mut HASH_TABLE) -> *mut VAR_CONTEXT { + return push_var_context(0 as *mut libc::c_void as *mut libc::c_char, flags, tmpvars); +} + +fn push_exported_var(mut data: *mut libc::c_void) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = data as *mut SHELL_VAR; + unsafe { + if tempvar_p!(var) != 0 + && exported_p!(var) != 0 + && (*var).attributes & att_propagate as libc::c_int != 0 + { + (*var).attributes &= !(att_tempvar as libc::c_int); + v = bind_variable_internal( + (*var).name, + value_cell!(var), + (*shell_variables).table, + 0 as libc::c_int, + 0 as libc::c_int, + ); + if shell_variables == global_variables { + (*var).attributes &= !(att_propagate as libc::c_int); + } + if !v.is_null() { + (*v).attributes |= (*var).attributes; + (*v).context = (*shell_variables).scope; + } + } else { + stupidly_hack_special_variables((*var).name); + } + } + dispose_variable(var); +} + +#[no_mangle] +pub fn pop_scope(mut is_special: libc::c_int) { + let mut vcxt: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut ret: *mut VAR_CONTEXT = 0 as *mut VAR_CONTEXT; + let mut is_bltinenv: libc::c_int = 0; + unsafe { + vcxt = shell_variables; + if !vc_istempscope!(vcxt) { + internal_error( + b"pop_scope: head of shell_variables not a temporary environment scope\0" + as *const u8 as *const libc::c_char, + ); + return; + } + + is_bltinenv = if vc_isbltnenv!(vcxt) { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + + ret = (*vcxt).down; + if !ret.is_null() { + (*ret).up = 0 as *mut libc::c_void as *mut VAR_CONTEXT; + } + shell_variables = ret; + if !((*vcxt).name).is_null() { + free((*vcxt).name as *mut libc::c_void); + } + (*vcxt).name = 0 as *mut libc::c_char; + + if !((*vcxt).table.is_null()) { + if is_special != 0 { + hash_flush( + (*vcxt).table, + std::mem::transmute:: ()>, sh_free_func_t>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + push_builtin_var, + ), + )), + ); + } else { + hash_flush( + (*vcxt).table, + std::mem::transmute:: ()>, sh_free_func_t>(Some( + ::core::mem::transmute:: (), fn() -> ()>( + push_exported_var, + ), + )), + ); + } + hash_dispose((*vcxt).table); + } + free(vcxt as *mut libc::c_void); + sv_ifs(b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + } +} + +static mut dollar_arg_stack: *mut saved_dollar_vars = + 0 as *const libc::c_void as *mut libc::c_void as *mut saved_dollar_vars; +static mut dollar_arg_stack_slots: libc::c_int = 0; +static mut dollar_arg_stack_index: libc::c_int = 0; + +fn save_dollar_vars() -> *mut *mut libc::c_char { + let mut ret: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut i: libc::c_int = 0; + unsafe { + ret = strvec_create(10 as libc::c_int); + i = 1 as libc::c_int; + while i < 10 as libc::c_int { + *ret.offset(i as isize) = dollar_vars[i as usize]; + dollar_vars[i as usize] = 0 as *mut libc::c_void as *mut libc::c_char; + i += 1; + i; + } + } + return ret; +} + +fn restore_dollar_vars(mut args: *mut *mut libc::c_char) { + let mut i: libc::c_int = 0; + i = 1 as libc::c_int; + unsafe { + while i < 10 as libc::c_int { + dollar_vars[i as usize] = *args.offset(i as isize); + i += 1; + i; + } + } +} + +fn free_dollar_vars() { + let mut i: libc::c_int = 0; + i = 1 as libc::c_int; + unsafe { + while i < 10 as libc::c_int { + if !(dollar_vars[i as usize]).is_null() { + free(dollar_vars[i as usize] as *mut libc::c_void); + } + + dollar_vars[i as usize] = 0 as *mut libc::c_void as *mut libc::c_char; + i += 1; + i; + } + } +} +fn free_saved_dollar_vars(mut args: *mut *mut libc::c_char) { + let mut i: libc::c_int = 0; + i = 1 as libc::c_int; + unsafe { + while i < 10 as libc::c_int { + if !(*args.offset(i as isize)).is_null() { + free(*args.offset(i as isize) as *mut libc::c_void); + } + // *args.offset(i as isize) = 0 as *mut libc::c_char; + i += 1; + i; + } + } +} + +#[no_mangle] +pub fn clear_dollar_vars() { + free_dollar_vars(); + unsafe { + dispose_words(rest_of_args); + rest_of_args = 0 as *mut libc::c_void as *mut WORD_LIST; + posparam_count = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn push_context( + mut name: *mut libc::c_char, + mut is_subshell: libc::c_int, + mut tempvars: *mut HASH_TABLE, +) { + if is_subshell == 0 as libc::c_int { + push_dollar_vars(); + } + unsafe { + variable_context += 1; + variable_context; + } + push_var_context(name, 0x4 as libc::c_int, tempvars); +} + +#[no_mangle] +pub fn pop_context() { + pop_dollar_vars(); + unsafe { + variable_context -= 1; + variable_context; + } + pop_var_context(); + sv_ifs(b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn push_dollar_vars() { + unsafe { + if dollar_arg_stack_index + 2 as libc::c_int > dollar_arg_stack_slots { + dollar_arg_stack_slots += 10 as libc::c_int; + dollar_arg_stack = libc::realloc( + dollar_arg_stack as *mut libc::c_void, + (dollar_arg_stack_slots as usize) + * std::mem::size_of::() as usize, + ) as *mut saved_dollar_vars; + } + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).count = posparam_count; + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten = save_dollar_vars(); + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).rest = rest_of_args; + dollar_arg_stack_index = dollar_arg_stack_index + 1; + + rest_of_args = 0 as *mut libc::c_void as *mut WORD_LIST; + posparam_count = 0 as libc::c_int; + + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten = + 0 as *mut libc::c_void as *mut *mut libc::c_char; + + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).rest = + 0 as *mut libc::c_void as *mut WORD_LIST; + } +} + +#[no_mangle] +pub fn pop_dollar_vars() { + unsafe { + if dollar_arg_stack.is_null() || dollar_arg_stack_index == 0 as libc::c_int { + return; + } + clear_dollar_vars(); + dollar_arg_stack_index -= 1; + rest_of_args = (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).rest; + restore_dollar_vars((*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten); + free( + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten + as *mut libc::c_void, + ); + + posparam_count = (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).count; + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten = + 0 as *mut libc::c_void as *mut *mut libc::c_char; + + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).rest = + 0 as *mut libc::c_void as *mut WORD_LIST; + + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).count = 0 as libc::c_int; + } + set_dollar_vars_unchanged(); + invalidate_cached_quoted_dollar_at(); +} + +#[no_mangle] +pub fn dispose_saved_dollar_vars() { + unsafe { + if dollar_arg_stack.is_null() || dollar_arg_stack_index == 0 as libc::c_int { + return; + } + dollar_arg_stack_index -= 1; + dispose_words((*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).rest); + free_saved_dollar_vars( + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten, + ); + free( + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten + as *mut libc::c_void, + ); + + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).first_ten = + 0 as *mut libc::c_void as *mut *mut libc::c_char; + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).rest = + 0 as *mut libc::c_void as *mut WORD_LIST; + (*dollar_arg_stack.offset(dollar_arg_stack_index as isize)).count = 0 as libc::c_int; + } +} + +#[no_mangle] +pub fn init_bash_argv() { + unsafe { + if bash_argv_initialized == 0 as libc::c_int { + save_bash_argv(); + bash_argv_initialized = 1 as libc::c_int; + } + } +} +#[no_mangle] +pub fn save_bash_argv() { + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + list = list_rest_of_args(); + push_args(list); + dispose_words(list); +} + +#[no_mangle] +pub fn push_args(mut list: *mut WORD_LIST) { + let mut bash_argv_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_argc_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_argv_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_argc_a: *mut ARRAY = 0 as *mut ARRAY; + + let mut l: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut i: arrayind_t = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + GET_ARRAY_FROM_VAR!( + b"BASH_ARGV\0" as *const u8 as *const libc::c_char, + bash_argv_v, + bash_argv_a + ); + + GET_ARRAY_FROM_VAR!( + b"BASH_ARGC\0" as *const u8 as *const libc::c_char, + bash_argv_v, + bash_argv_a + ); + + l = list; + i = 0 as libc::c_int as arrayind_t; + while !l.is_null() { + array_push!(bash_argv_a, (*(*l).word).word); + l = (*l).next; + i += 1; + i; + } + t = itos(i); + array_push!(bash_argv_a, t); + free(t as *mut libc::c_void); + } +} + +#[no_mangle] +pub fn pop_args() { + let mut bash_argv_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_argc_v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut bash_argv_a: *mut ARRAY = 0 as *mut ARRAY; + let mut bash_argc_a: *mut ARRAY = 0 as *mut ARRAY; + let mut ce: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + + let mut i: intmax_t = 0; + unsafe { + GET_ARRAY_FROM_VAR!( + b"BASH_ARGV\0" as *const u8 as *const libc::c_char, + bash_argv_v, + bash_argv_a + ); + + GET_ARRAY_FROM_VAR!( + b"BASH_ARGC\0" as *const u8 as *const libc::c_char, + bash_argv_v, + bash_argv_a + ); + + ce = array_shift(bash_argc_a, 1 as libc::c_int, 0 as libc::c_int); + + if ce.is_null() || legal_number((*ce).value, &mut i) == 0 as libc::c_int { + i = 0 as libc::c_int as intmax_t; + } + + while i > 0 as libc::c_int as libc::c_long { + array_pop!(bash_argc_a); + i -= 1; + i; + } + array_dispose_element(ce); + } +} + +static mut special_vars: [name_and_function; 38] = { + [ + { + let mut init = name_and_function { + name: b"BASH_COMPAT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_shcompat), + }; + init + }, + { + let mut init = name_and_function { + name: b"BASH_XTRACEFD\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_xtracefd), + }; + init + }, + { + let mut init = name_and_function { + name: b"CHILD_MAX\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_childmax), + }; + init + }, + { + let mut init = name_and_function { + name: b"COMP_WORDBREAKS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_comp_wordbreaks), + }; + init + }, + { + let mut init = name_and_function { + name: b"EXECIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_execignore), + }; + init + }, + { + let mut init = name_and_function { + name: b"FUNCNEST\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_funcnest), + }; + init + }, + { + let mut init = name_and_function { + name: b"GLOBIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_globignore), + }; + init + }, + { + let mut init = name_and_function { + name: b"HISTCONTROL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_history_control), + }; + init + }, + { + let mut init = name_and_function { + name: b"HISTFILESIZE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_histignore), + }; + init + }, + { + let mut init = name_and_function { + name: b"HISTIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_histsize), + }; + init + }, + { + let mut init = name_and_function { + name: b"HISTSIZE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_histsize), + }; + init + }, + { + let mut init = name_and_function { + name: b"HISTTIMEFORMAT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_histtimefmt), + }; + init + }, + { + let mut init = name_and_function { + name: b"HOSTFILE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_hostfile), + }; + init + }, + { + let mut init = name_and_function { + name: b"IFS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_ifs), + }; + init + }, + { + let mut init = name_and_function { + name: b"IGNOREEOF\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_ignoreeof), + }; + init + }, + { + let mut init = name_and_function { + name: b"LANG\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"LC_ALL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"LC_COLLATE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"LC_CTYPE\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"LC_MESSAGES\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"LC_NUMERIC\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"LC_TIME\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"MAIL\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_mail), + }; + init + }, + { + let mut init = name_and_function { + name: b"MAILCHECK\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_mail), + }; + init + }, + { + let mut init = name_and_function { + name: b"MAILPATH\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_mail), + }; + init + }, + { + let mut init = name_and_function { + name: b"OPTERR\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_opterr), + }; + init + }, + { + let mut init = name_and_function { + name: b"OPTIND\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_optind), + }; + init + }, + { + let mut init = name_and_function { + name: b"PATH\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_path), + }; + init + }, + { + let mut init = name_and_function { + name: b"POSIXLY_CORRECT\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_strict_posix), + }; + init + }, + { + let mut init = name_and_function { + name: b"TERM\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_terminal), + }; + init + }, + { + let mut init = name_and_function { + name: b"TERMCAP\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_terminal), + }; + init + }, + { + let mut init = name_and_function { + name: b"TERMINFO\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_terminal), + }; + init + }, + { + let mut init = name_and_function { + name: b"TEXTDOMAIN\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"TEXTDOMAINDIR\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_locale), + }; + init + }, + { + let mut init = name_and_function { + name: b"TZ\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_tz), + }; + init + }, + { + let mut init = name_and_function { + name: b"histchars\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_histchars), + }; + init + }, + { + let mut init = name_and_function { + name: b"ignoreeof\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + function: Some(sv_ignoreeof), + }; + init + }, + { + let mut init = name_and_function { + name: 0 as *const libc::c_char as *mut libc::c_char, + function: None, + }; + init + }, + ] +}; + +fn sv_compare(mut sv1: *mut name_and_function, mut sv2: *mut name_and_function) -> libc::c_int { + let mut r: libc::c_int = 0; + unsafe { + r = *((*sv1).name).offset(0 as libc::c_int as isize) as libc::c_int + - *((*sv2).name).offset(0 as libc::c_int as isize) as libc::c_int; + if r == 0 as libc::c_int { + r = libc::strcmp((*sv1).name, (*sv2).name); + } + } + return r; +} + +#[inline] +fn find_special_var(mut name: *const libc::c_char) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut r: libc::c_int = 0; + i = 0 as libc::c_int; + unsafe { + while !(special_vars[i as usize].name).is_null() { + r = *(special_vars[i as usize].name).offset(0 as libc::c_int as isize) as libc::c_int + - *name.offset(0 as libc::c_int as isize) as libc::c_int; + if r == 0 as libc::c_int { + r = libc::strcmp(special_vars[i as usize].name, name); + } + if r == 0 as libc::c_int { + return i; + } else { + if r > 0 as libc::c_int { + break; + } + i += 1; + i; + } + } + return -(1 as libc::c_int); + } +} + +#[no_mangle] +pub fn stupidly_hack_special_variables(mut name: *mut libc::c_char) { + static mut sv_sorted: libc::c_int = 0 as libc::c_int; + let mut i: libc::c_int = 0; + unsafe { + if sv_sorted == 0 as libc::c_int { + qsort( + special_vars.as_mut_ptr() as *mut libc::c_void, + (std::mem::size_of::<[name_and_function; 38]>() as usize) + .wrapping_div(std::mem::size_of::() as usize) + .wrapping_sub(1 as libc::c_int as usize), + std::mem::size_of::() as usize, + std::mem::transmute:: libc::c_int>, Option>(Some( + std::mem::transmute::< + fn(*mut name_and_function, *mut name_and_function) -> libc::c_int, + fn() -> libc::c_int, + >(sv_compare), + )), + ); + sv_sorted = 1 as libc::c_int; + } + i = find_special_var(name); + if i != -(1 as libc::c_int) { + (Some( + ((*special_vars.as_mut_ptr().offset(i as isize)).function) + .expect("non-null function pointer"), + )) + .expect("non-null function pointer")(name); + } + } +} + +#[no_mangle] +pub fn reinit_special_variables() { + sv_comp_wordbreaks( + b"COMP_WORDBREAKS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + sv_globignore(b"GLOBIGNORE\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + sv_opterr(b"OPTERR\0" as *const u8 as *const libc::c_char as *mut libc::c_char); +} + +#[no_mangle] +pub fn sv_ifs(mut name: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(b"IFS\0" as *const u8 as *const libc::c_char); + setifs(v); +} + +#[no_mangle] +pub fn sv_path(mut name: *mut libc::c_char) { + unsafe { + phash_flush(); + } +} + +#[no_mangle] +pub fn sv_mail(mut name: *mut libc::c_char) { + unsafe { + if *name.offset(4 as libc::c_int as isize) as libc::c_int == 'C' as i32 { + reset_mail_timer(); + } else { + free_mail_files(); + remember_mail_dates(); + }; + } +} + +#[no_mangle] +pub fn sv_funcnest(mut name: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut num: intmax_t = 0; + v = find_variable(name); + unsafe { + if v.is_null() { + funcnest_max = 0 as libc::c_int; + } else if legal_number((*v).value, &mut num) == 0 as libc::c_int { + funcnest_max = 0 as libc::c_int; + } else { + funcnest_max = num as libc::c_int; + }; + } +} +#[no_mangle] +pub fn sv_execignore(mut name: *mut libc::c_char) { + unsafe { + setup_exec_ignore(name); + } +} + +#[no_mangle] +pub fn sv_globignore(mut name: *mut libc::c_char) { + unsafe { + if privileged_mode == 0 as libc::c_int { + setup_glob_ignore(name); + } + } +} + +#[no_mangle] +pub fn sv_comp_wordbreaks(mut name: *mut libc::c_char) { + let mut sv: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + sv = find_variable(name); + if sv.is_null() { + reset_completer_word_break_chars(); + } +} +#[no_mangle] +pub fn sv_terminal(mut name: *mut libc::c_char) { + unsafe { + if interactive_shell != 0 && no_line_editing == 0 as libc::c_int { + rl_reset_terminal(get_string_value( + b"TERM\0" as *const u8 as *const libc::c_char, + )); + } + } +} +#[no_mangle] +pub fn sv_hostfile(mut name: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(name); + if v.is_null() { + clear_hostname_list(); + } else { + unsafe { + hostname_list_initialized = 0 as libc::c_int; + } + } +} + +#[no_mangle] +pub fn sv_histsize(mut name: *mut libc::c_char) { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut num: intmax_t = 0; + let mut hmax: libc::c_int = 0; + temp = get_string_value(name); + unsafe { + if !temp.is_null() && *temp as libc::c_int != 0 { + if legal_number(temp, &mut num) != 0 { + hmax = num as libc::c_int; + if hmax < 0 as libc::c_int + && *name.offset(4 as libc::c_int as isize) as libc::c_int == 'S' as i32 + { + unstifle_history(); + } else if *name.offset(4 as libc::c_int as isize) as libc::c_int == 'S' as i32 { + stifle_history(hmax); + hmax = where_history(); + + if history_lines_this_session > hmax { + history_lines_this_session = hmax; + } + } else if hmax >= 0 as libc::c_int { + history_truncate_file( + get_string_value(b"HISTFILE\0" as *const u8 as *const libc::c_char), + hmax, + ); + if hmax < history_lines_in_file { + history_lines_in_file = hmax; + } + } + } + } else if *name.offset(4 as libc::c_int as isize) as libc::c_int == 'S' as i32 { + unstifle_history(); + } + } +} + +#[no_mangle] +pub fn sv_histignore(mut name: *mut libc::c_char) { + setup_history_ignore(name); +} + +#[no_mangle] +pub fn sv_history_control(mut name: *mut libc::c_char) { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tptr: libc::c_int = 0; + unsafe { + history_control = 0 as libc::c_int; + temp = get_string_value(name); + if temp.is_null() || *temp as libc::c_int == 0 as libc::c_int { + return; + } + tptr = 0 as libc::c_int; + + loop { + val = extract_colon_unit(temp, &mut tptr); + if val.is_null() { + break; + } + if STREQ(val, b"ignorespace\0" as *const u8 as *const libc::c_char) { + history_control |= HC_IGNSPACE as libc::c_int; + } else if STREQ(val, b"ignoredups\0" as *const u8 as *const libc::c_char) { + history_control |= HC_IGNDUPS as libc::c_int; + } else if STREQ(val, b"ignoreboth\0" as *const u8 as *const libc::c_char) { + history_control |= HC_IGNBOTH as libc::c_int | 0x2 as libc::c_int; + } else if STREQ(val, b"erasedups\0" as *const u8 as *const libc::c_char) { + history_control |= HC_ERASEDUPS as libc::c_int; + } + free(val as *mut libc::c_void); + } + } +} + +#[no_mangle] +pub fn sv_histchars(mut name: *mut libc::c_char) { + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + temp = get_string_value(name); + unsafe { + if !temp.is_null() { + history_expansion_char = *temp; + if *temp.offset(0 as libc::c_int as isize) as libc::c_int != 0 + && *temp.offset(1 as libc::c_int as isize) as libc::c_int != 0 + { + history_subst_char = *temp.offset(1 as libc::c_int as isize); + if *temp.offset(2 as libc::c_int as isize) != 0 { + history_comment_char = *temp.offset(2 as libc::c_int as isize); + } + } + } else { + history_expansion_char = '!' as i32 as libc::c_char; + history_subst_char = '^' as i32 as libc::c_char; + history_comment_char = '#' as i32 as libc::c_char; + }; + } +} + +#[no_mangle] +pub fn sv_histtimefmt(mut name: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + v = find_variable(name); + unsafe { + if !v.is_null() { + if history_comment_char as libc::c_int == 0 as libc::c_int { + history_comment_char = '#' as i32 as libc::c_char; + } + } + history_write_timestamps = (v != 0 as *mut SHELL_VAR) as libc::c_int; + } +} + +#[no_mangle] +pub fn sv_tz(mut name: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + + v = find_variable(name); + unsafe { + if !v.is_null() && exported_p!(v) != 0 { + array_needs_making = 1 as libc::c_int; + } else if v.is_null() { + array_needs_making = 1 as libc::c_int; + } + if array_needs_making != 0 { + maybe_make_export_env(); + tzset(); + } + } +} + +#[no_mangle] +pub fn sv_ignoreeof(mut name: *mut libc::c_char) { + let mut tmp_var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + eof_encountered = 0 as libc::c_int; + + tmp_var = find_variable(name); + ignoreeof = if (!tmp_var.is_null()) && var_isset!(tmp_var) { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + + temp = if !tmp_var.is_null() { + value_cell!(tmp_var) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !temp.is_null() { + eof_encountered_limit = if *temp as libc::c_int != 0 && all_digits(temp) != 0 { + atoi(temp) + } else { + 10 as libc::c_int + }; + } + } + set_shellopts(); +} + +#[no_mangle] +pub fn sv_optind(mut name: *mut libc::c_char) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: libc::c_int = 0; + + var = find_variable(b"OPTIND\0" as *const u8 as *const libc::c_char); + unsafe { + tt = if !var.is_null() { + get_variable_value(var) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !tt.is_null() && *tt as libc::c_int != 0 { + s = atoi(tt); + if s < 0 as libc::c_int || s == 1 as libc::c_int { + s = 0 as libc::c_int; + } + } else { + s = 0 as libc::c_int; + } + } + getopts_reset(s); +} + +#[no_mangle] +pub fn sv_opterr(mut name: *mut libc::c_char) { + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + unsafe { + tt = get_string_value(b"OPTERR\0" as *const u8 as *const libc::c_char); + sh_opterr = if !tt.is_null() && *tt as libc::c_int != 0 { + atoi(tt) + } else { + 1 as libc::c_int + }; + } +} + +#[no_mangle] +pub fn sv_strict_posix(mut name: *mut libc::c_char) { + let mut var: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + var = find_variable(name); + unsafe { + posixly_correct = if (!var.is_null()) && var_isset!(var) { + 1 as libc::c_int + } else { + 0 as libc::c_int + }; + + posix_initialize(posixly_correct); + if interactive_shell != 0 { + posix_readline_initialize(posixly_correct); + } + } + set_shellopts(); +} + +#[no_mangle] +pub fn sv_locale(mut name: *mut libc::c_char) { + let mut v: *mut libc::c_char = 0 as *mut libc::c_char; + let mut r: libc::c_int = 0; + v = get_string_value(name); + unsafe { + if *name.offset(0 as libc::c_int as isize) as libc::c_int == 'L' as i32 + && *name.offset(1 as libc::c_int as isize) as libc::c_int == 'A' as i32 + { + r = set_lang(name, v); + } else { + r = set_locale_var(name, v); + } + if r == 0 as libc::c_int && posixly_correct != 0 { + set_exit_status(1 as libc::c_int); + } + } +} + +#[no_mangle] +pub fn set_pipestatus_array(mut ps: *mut libc::c_int, mut nproc: libc::c_int) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut a: *mut ARRAY = 0 as *mut ARRAY; + let mut ae: *mut ARRAY_ELEMENT = 0 as *mut ARRAY_ELEMENT; + let mut i: libc::c_int = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tbuf: [libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize] = + [0; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]; + + v = find_variable(b"PIPESTATUS\0" as *const u8 as *const libc::c_char); + if v.is_null() { + v = make_new_array_variable( + b"PIPESTATUS\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + unsafe { + if array_p!(v) == 0 as libc::c_int { + return; + } + + a = array_cell!(v); + + if a.is_null() || array_num_elements!(a) == 0 as libc::c_int { + i = 0 as libc::c_int; + while i < nproc { + t = inttostr( + *ps.offset(i as isize) as intmax_t, + tbuf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>( + ) as size_t, + ); + array_insert(a, i as arrayind_t, t); + i += 1; + i; + } + return; + } + + if array_num_elements!(a) == nproc && nproc == 1 as libc::c_int { + ae = element_forw!((*a).head); + free(element_value!(ae) as *mut libc::c_void); + set_element_value!(ae, itos(*ps.offset(0 as libc::c_int as isize) as intmax_t)); + } else if array_num_elements!(a) <= nproc { + ae = (*a).head; + + i = 0 as libc::c_int; + + while i < (*a).num_elements { + ae = (*ae).next; + free(element_value!(ae) as *mut libc::c_void); + set_element_value!(ae, itos(*ps.offset(i as libc::c_int as isize) as intmax_t)); + i += 1; + i; + } + while i < nproc { + t = inttostr( + *ps.offset(i as isize) as intmax_t, + tbuf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>( + ) as u64, + ); + array_insert(a, i as arrayind_t, t); + i += 1; + i; + } + } else { + array_flush(a); + i = 0 as libc::c_int; + while *ps.offset(i as isize) != -(1 as libc::c_int) { + t = inttostr( + *ps.offset(i as isize) as intmax_t, + tbuf.as_mut_ptr(), + std::mem::size_of::<[libc::c_char; (INT_STRLEN_BOUND!(libc::c_int) + 1) as usize]>( + ) as u64, + ); + array_insert(a, i as arrayind_t, t); + i += 1; + i; + } + }; + } +} + +#[no_mangle] +pub fn save_pipestatus_array() -> *mut ARRAY { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut a: *mut ARRAY = 0 as *mut ARRAY; + v = find_variable(b"PIPESTATUS\0" as *const u8 as *const libc::c_char); + unsafe { + if v.is_null() || array_p!(v) == 0 as libc::c_int || (array_cell!(v)).is_null() { + return 0 as *mut libc::c_void as *mut ARRAY; + } + a = array_copy((*v).value as *mut ARRAY); + } + return a; +} + +#[no_mangle] +pub fn restore_pipestatus_array(mut a: *mut ARRAY) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut a2: *mut ARRAY = 0 as *mut ARRAY; + v = find_variable(b"PIPESTATUS\0" as *const u8 as *const libc::c_char); + unsafe { + if v.is_null() || array_p!(v) == 0 as libc::c_int || (array_cell!(v)).is_null() { + return; + } + a2 = array_cell!(v); + var_setarray!(v, a); + + array_dispose(a2); + } +} + +#[no_mangle] +pub fn set_pipestatus_from_exit(mut s: libc::c_int) { + unsafe { + static mut v: [libc::c_int; 2] = [0 as libc::c_int, -(1 as libc::c_int)]; + v[0 as libc::c_int as usize] = s; + set_pipestatus_array(v.as_mut_ptr(), 1 as libc::c_int); + } +} + +#[no_mangle] +pub fn sv_xtracefd(mut name: *mut libc::c_char) { + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut e: *mut libc::c_char = 0 as *mut libc::c_char; + let mut fd: libc::c_int = 0; + let mut fp: *mut FILE = 0 as *mut FILE; + v = find_variable(name); + unsafe { + if v.is_null() { + xtrace_reset(); + return; + } + t = (*v).value; + if t.is_null() || *t as libc::c_int == 0 as libc::c_int { + xtrace_reset(); + } else { + fd = strtol(t, &mut e, 10 as libc::c_int) as libc::c_int; + if e != t && *e as libc::c_int == '\0' as i32 && sh_validfd(fd) != 0 { + fp = fdopen(fd, b"w\0" as *const u8 as *const libc::c_char); + if fp.is_null() { + internal_error( + b"%s: %s: cannot open as FILE\0" as *const u8 as *const libc::c_char, + name, + value_cell!(v), + ); + } else { + xtrace_set(fd, fp); + } + } else { + internal_error( + b"%s: %s: invalid value for trace file descriptor\0" as *const u8 + as *const libc::c_char, + name, + value_cell!(v), + ); + } + }; + } +} + +#[no_mangle] +pub fn sv_shcompat(mut name: *mut libc::c_char) { + let mut current_block: u64; + let mut v: *mut SHELL_VAR = 0 as *mut SHELL_VAR; + let mut val: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tens: libc::c_int = 0; + let mut ones: libc::c_int = 0; + let mut compatval: libc::c_int = 0; + + v = find_variable(name); + unsafe { + if v.is_null() { + shell_compatibility_level = DEFAULT_COMPAT_LEVEL!() as libc::c_int; + set_compatibility_opts(); + return; + } + val = value_cell!(v); + + if val.is_null() || *val as libc::c_int == '\0' as i32 { + shell_compatibility_level = DEFAULT_COMPAT_LEVEL!() as libc::c_int; + set_compatibility_opts(); + return; + } + + if ISDIGIT!(*val.offset(0 as libc::c_int as isize) as libc::c_int) + && *val.offset(1 as libc::c_int as isize) as libc::c_int == '.' as i32 + && { + if *val.offset(2 as libc::c_int as isize) == 0 + && *val.offset(3 as libc::c_int as isize) == 0 + { + ISDIGIT!(1 as libc::c_int) + } else { + ISDIGIT!(0 as libc::c_int) + } + } + { + tens = *val.offset(0 as libc::c_int as isize) as libc::c_int - '0' as i32; + ones = *val.offset(2 as libc::c_int as isize) as libc::c_int - '0' as i32; + compatval = tens * 10 as libc::c_int + ones; + } else if ISDIGIT!(*val.offset(0 as libc::c_int as isize) as libc::c_int) && { + if *val.offset(1 as libc::c_int as isize) == 0 + && *val.offset(2 as libc::c_int as isize) == 0 + { + ISDIGIT!(1 as libc::c_int) + } else { + ISDIGIT!(0 as libc::c_int) + } + } { + tens = *val.offset(0 as libc::c_int as isize) as libc::c_int - '0' as i32; + ones = *val.offset(1 as libc::c_int as isize) as libc::c_int - '0' as i32; + compatval = tens * 10 as libc::c_int + ones; + } else { + internal_error( + b"%s: %s: compatibility value out of range\0" as *const u8 as *const libc::c_char, + name, + val, + ); + shell_compatibility_level = DEFAULT_COMPAT_LEVEL!() as libc::c_int; + set_compatibility_opts(); + return; + } + + if !(compatval < MIN_COMPAT_LEVEL!() as libc::c_int + || compatval > DEFAULT_COMPAT_LEVEL!() as libc::c_int) + { + internal_error( + b"%s: %s: compatibility value out of range\0" as *const u8 as *const libc::c_char, + name, + val, + ); + shell_compatibility_level = DEFAULT_COMPAT_LEVEL!() as libc::c_int; + set_compatibility_opts(); + return; + } + + shell_compatibility_level = compatval; + } + set_compatibility_opts(); +} + +#[no_mangle] +pub fn sv_childmax(mut name: *mut libc::c_char) { + let mut tt: *mut libc::c_char = 0 as *mut libc::c_char; + let mut s: libc::c_int = 0; + + tt = get_string_value(name); + unsafe { + s = if !tt.is_null() && *tt as libc::c_int != 0 { + atoi(tt) + } else { + 0 as libc::c_int + }; + set_maxchild(s); + } +} diff --git a/utshell-0.5.0/src/version.rs b/utshell-0.5.0/src/version.rs new file mode 100644 index 00000000..b43663da --- /dev/null +++ b/utshell-0.5.0/src/version.rs @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +use crate::src_common::*; +use std::convert::TryInto; + +/* The distribution version number of this shell. */ +#[no_mangle] +pub static mut dist_version: *const libc::c_char = b"5.1\0" as *const u8 as *const libc::c_char; + +/* It's important that there be no other strings in this file that match the +regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh +looks for to find the patch level (for the sccs version string). */ +#[no_mangle] +pub static mut patch_level: libc::c_int = 4 as libc::c_int; + +/* The last built version of this shell. */ +#[no_mangle] +pub static mut build_version: libc::c_int = 1 as libc::c_int; + +/* The release status of this shell. */ +#[no_mangle] +pub static mut release_status: *const libc::c_char = + b"release\0" as *const u8 as *const libc::c_char; + +/* A version string for use by sccs and the what command. */ +#[no_mangle] +pub static mut sccs_version: *const libc::c_char = + b"@(#)utshell version 0.5 release GNU\0" as *const u8 as *const libc::c_char; + +#[no_mangle] +pub static mut bash_copyright: *const libc::c_char = + b"Copyright (C) 2020 Free Software Foundation, Inc.\0" as *const u8 as *const libc::c_char; +#[no_mangle] +pub static mut bash_license: *const libc::c_char = + b"License GPLv3+: GNU GPL version 3 or later \n\0" + as *const u8 as *const libc::c_char; + +#[no_mangle] +pub static mut shell_compatibility_level: libc::c_int = 51 as libc::c_int; +#[no_mangle] +pub fn shell_version_string() -> *mut libc::c_char { + unsafe { + static mut tt: [libc::c_char; 32] = ['\u{0}' as i32 as libc::c_char; 32]; + if tt[0 as libc::c_int as usize] as libc::c_int == '\u{0}' as i32 { + if !release_status.is_null() { + snprintf( + tt.as_mut_ptr() as *mut libc::c_char, + (::std::mem::size_of::<[libc::c_char; 32]>() as libc::c_ulong) + .try_into() + .unwrap(), + b"%s.%d(%d)-%s\0" as *const u8 as *const libc::c_char, + dist_version, + patch_level, + build_version, + release_status, + ); + } else { + snprintf( + tt.as_mut_ptr() as *mut libc::c_char, + (::std::mem::size_of::<[libc::c_char; 32]>() as libc::c_ulong) + .try_into() + .unwrap(), + b"%s.%d(%d)\0" as *const u8 as *const libc::c_char, + dist_version, + patch_level, + build_version, + ); + } + } + return tt.as_mut_ptr() as *mut libc::c_char; + } +} +#[no_mangle] +pub fn show_shell_version(mut extended: libc::c_int) { + unsafe { + printf( + dcgettext( + 0 as *const libc::c_char, + b"GNU utshell, version %s (%s)\n\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + shell_version_string(), + if cfg!(target_arch = "x86_64") { + b"x86_64-uos-linux-gnu\0" as *const u8 as *const libc::c_char + } else if cfg!(target_arch = "aarch64") { + b"aarch64-uos-linux-gnu\0" as *const u8 as *const libc::c_char + } else { + b"unknow-uos-linux-gnu\0" as *const u8 as *const libc::c_char + }, + ); + if extended != 0 { + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + dcgettext(0 as *const libc::c_char, bash_copyright, 5 as libc::c_int), + ); + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + dcgettext(0 as *const libc::c_char, bash_license, 5 as libc::c_int), + ); + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"This is free software; you are free to change and redistribute it.\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + ); + printf( + b"%s\n\0" as *const u8 as *const libc::c_char, + dcgettext( + 0 as *const libc::c_char, + b"There is NO WARRANTY, to the extent permitted by law.\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } + } +} diff --git a/utshell-0.5.0/src/y_tab.rs b/utshell-0.5.0/src/y_tab.rs new file mode 100644 index 00000000..4314f463 --- /dev/null +++ b/utshell-0.5.0/src/y_tab.rs @@ -0,0 +1,13191 @@ +/* + * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut, + unreachable_code, + non_snake_case, + unreachable_patterns, + unused_variables, + clashing_extern_declarations +)] + +use crate::src_common; +use crate::alias::*; +use crate::arrayfunc::*; +use crate::bashhist::*; +use crate::bashline::*; +use crate::builtins::common::{builtin_address_internal, read_octal}; +use crate::builtins::evalstring::parse_string; +use crate::builtins::exit::exit_builtin; +use crate::dispose_cmd::*; +use crate::general::*; +use crate::general::{legal_identifier, legal_number}; +use crate::input::*; +use crate::jobs::*; +use crate::local::*; +use crate::mailcheck::*; +use crate::make_cmd::*; +use crate::readline::clearerr; +use crate::sig::*; +use crate::src_common::alias; +use crate::src_common::builtin; +use crate::src_common::*; +use crate::stringlib::*; +use crate::subst::*; +pub use crate::syntax::sh_syntaxtab; +use crate::test::*; +use crate::trap::*; +use crate::variables::bind_variable; +use crate::variables::get_string_value; +use crate::variables::restore_pipestatus_array; +use crate::variables::save_pipestatus_array; +use crate::variables::set_pipestatus_from_exit; +use crate::variables::sv_tz; +use crate::version::dist_version; +use crate::version::*; + +extern "C" { + static mut stdin: *mut FILE; + fn get_new_window_size(_: libc::c_int, _: *mut libc::c_int, _: *mut libc::c_int); + fn set_signal_handler(_: libc::c_int, _: Option) -> Option; + +} + +pub type yy_state_t = yytype_int16; +pub type yytype_int16 = libc::c_short; + +pub type yysymbol_kind_t = libc::c_int; +pub const YYSYMBOL_timespec: yysymbol_kind_t = 98; +pub const YYSYMBOL_pipeline: yysymbol_kind_t = 97; +pub const YYSYMBOL_pipeline_command: yysymbol_kind_t = 96; +pub const YYSYMBOL_simple_list1: yysymbol_kind_t = 95; +pub const YYSYMBOL_simple_list: yysymbol_kind_t = 94; +pub const YYSYMBOL_newline_list: yysymbol_kind_t = 93; +pub const YYSYMBOL_list_terminator: yysymbol_kind_t = 92; +pub const YYSYMBOL_simple_list_terminator: yysymbol_kind_t = 91; +pub const YYSYMBOL_list1: yysymbol_kind_t = 90; +pub const YYSYMBOL_list0: yysymbol_kind_t = 89; +pub const YYSYMBOL_compound_list: yysymbol_kind_t = 88; +pub const YYSYMBOL_list: yysymbol_kind_t = 87; +pub const YYSYMBOL_pattern: yysymbol_kind_t = 86; +pub const YYSYMBOL_case_clause_sequence: yysymbol_kind_t = 85; +pub const YYSYMBOL_pattern_list: yysymbol_kind_t = 84; +pub const YYSYMBOL_case_clause: yysymbol_kind_t = 83; +pub const YYSYMBOL_elif_clause: yysymbol_kind_t = 82; +pub const YYSYMBOL_cond_command: yysymbol_kind_t = 81; +pub const YYSYMBOL_arith_command: yysymbol_kind_t = 80; +pub const YYSYMBOL_group_command: yysymbol_kind_t = 79; +pub const YYSYMBOL_if_command: yysymbol_kind_t = 78; +pub const YYSYMBOL_coproc: yysymbol_kind_t = 77; +pub const YYSYMBOL_subshell: yysymbol_kind_t = 76; +pub const YYSYMBOL_function_body: yysymbol_kind_t = 75; +pub const YYSYMBOL_function_def: yysymbol_kind_t = 74; +pub const YYSYMBOL_case_command: yysymbol_kind_t = 73; +pub const YYSYMBOL_select_command: yysymbol_kind_t = 72; +pub const YYSYMBOL_arith_for_command: yysymbol_kind_t = 71; +pub const YYSYMBOL_for_command: yysymbol_kind_t = 70; +pub const YYSYMBOL_shell_command: yysymbol_kind_t = 69; +pub const YYSYMBOL_command: yysymbol_kind_t = 68; +pub const YYSYMBOL_simple_command: yysymbol_kind_t = 67; +pub const YYSYMBOL_redirection_list: yysymbol_kind_t = 66; +pub const YYSYMBOL_simple_command_element: yysymbol_kind_t = 65; +pub const YYSYMBOL_redirection: yysymbol_kind_t = 64; +pub const YYSYMBOL_word_list: yysymbol_kind_t = 63; +pub const YYSYMBOL_inputunit: yysymbol_kind_t = 62; +pub const YYSYMBOL_YYACCEPT: yysymbol_kind_t = 61; +pub const YYSYMBOL_60_: yysymbol_kind_t = 60; +pub const YYSYMBOL_59_: yysymbol_kind_t = 59; +pub const YYSYMBOL_58_: yysymbol_kind_t = 58; +pub const YYSYMBOL_57_: yysymbol_kind_t = 57; +pub const YYSYMBOL_56_: yysymbol_kind_t = 56; +pub const YYSYMBOL_55_: yysymbol_kind_t = 55; +pub const YYSYMBOL_54_: yysymbol_kind_t = 54; +pub const YYSYMBOL_53_: yysymbol_kind_t = 53; +pub const YYSYMBOL_yacc_EOF: yysymbol_kind_t = 52; +pub const YYSYMBOL_51_n_: yysymbol_kind_t = 51; +pub const YYSYMBOL_50_: yysymbol_kind_t = 50; +pub const YYSYMBOL_49_: yysymbol_kind_t = 49; +pub const YYSYMBOL_BAR_AND: yysymbol_kind_t = 48; +pub const YYSYMBOL_GREATER_BAR: yysymbol_kind_t = 47; +pub const YYSYMBOL_LESS_GREATER: yysymbol_kind_t = 46; +pub const YYSYMBOL_AND_GREATER_GREATER: yysymbol_kind_t = 45; +pub const YYSYMBOL_AND_GREATER: yysymbol_kind_t = 44; +pub const YYSYMBOL_LESS_LESS_MINUS: yysymbol_kind_t = 43; +pub const YYSYMBOL_SEMI_SEMI_AND: yysymbol_kind_t = 42; +pub const YYSYMBOL_SEMI_AND: yysymbol_kind_t = 41; +pub const YYSYMBOL_SEMI_SEMI: yysymbol_kind_t = 40; +pub const YYSYMBOL_GREATER_AND: yysymbol_kind_t = 39; +pub const YYSYMBOL_LESS_LESS_LESS: yysymbol_kind_t = 38; +pub const YYSYMBOL_LESS_AND: yysymbol_kind_t = 37; +pub const YYSYMBOL_LESS_LESS: yysymbol_kind_t = 36; +pub const YYSYMBOL_GREATER_GREATER: yysymbol_kind_t = 35; +pub const YYSYMBOL_OR_OR: yysymbol_kind_t = 34; +pub const YYSYMBOL_AND_AND: yysymbol_kind_t = 33; +pub const YYSYMBOL_COND_CMD: yysymbol_kind_t = 32; +pub const YYSYMBOL_ARITH_FOR_EXPRS: yysymbol_kind_t = 31; +pub const YYSYMBOL_ARITH_CMD: yysymbol_kind_t = 30; +pub const YYSYMBOL_NUMBER: yysymbol_kind_t = 29; +pub const YYSYMBOL_REDIR_WORD: yysymbol_kind_t = 28; +pub const YYSYMBOL_ASSIGNMENT_WORD: yysymbol_kind_t = 27; +pub const YYSYMBOL_WORD: yysymbol_kind_t = 26; +pub const YYSYMBOL_TIMEIGN: yysymbol_kind_t = 25; +pub const YYSYMBOL_TIMEOPT: yysymbol_kind_t = 24; +pub const YYSYMBOL_TIME: yysymbol_kind_t = 23; +pub const YYSYMBOL_BANG: yysymbol_kind_t = 22; +pub const YYSYMBOL_IN: yysymbol_kind_t = 21; +pub const YYSYMBOL_COND_ERROR: yysymbol_kind_t = 20; +pub const YYSYMBOL_COND_END: yysymbol_kind_t = 19; +pub const YYSYMBOL_COND_START: yysymbol_kind_t = 18; +pub const YYSYMBOL_COPROC: yysymbol_kind_t = 17; +pub const YYSYMBOL_FUNCTION: yysymbol_kind_t = 16; +pub const YYSYMBOL_DONE: yysymbol_kind_t = 15; +pub const YYSYMBOL_DO: yysymbol_kind_t = 14; +pub const YYSYMBOL_UNTIL: yysymbol_kind_t = 13; +pub const YYSYMBOL_WHILE: yysymbol_kind_t = 12; +pub const YYSYMBOL_SELECT: yysymbol_kind_t = 11; +pub const YYSYMBOL_FOR: yysymbol_kind_t = 10; +pub const YYSYMBOL_ESAC: yysymbol_kind_t = 9; +pub const YYSYMBOL_CASE: yysymbol_kind_t = 8; +pub const YYSYMBOL_FI: yysymbol_kind_t = 7; +pub const YYSYMBOL_ELIF: yysymbol_kind_t = 6; +pub const YYSYMBOL_ELSE: yysymbol_kind_t = 5; +pub const YYSYMBOL_THEN: yysymbol_kind_t = 4; +pub const YYSYMBOL_IF: yysymbol_kind_t = 3; +pub const YYSYMBOL_YYUNDEF: yysymbol_kind_t = 2; +pub const YYSYMBOL_YYerror: yysymbol_kind_t = 1; +pub const YYSYMBOL_YYEOF: yysymbol_kind_t = 0; +pub const YYSYMBOL_YYEMPTY: yysymbol_kind_t = -2; +pub type yytype_int8 = libc::c_schar; +pub type STRING_SAVER = string_saver; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct string_saver { + pub next: *mut string_saver, + pub expand_alias: libc::c_int, + pub saved_line: *mut libc::c_char, + pub expander: *mut alias_t, + pub saved_line_size: size_t, + pub saved_line_index: size_t, + pub saved_line_terminator: libc::c_int, + pub flags: libc::c_int, +} +pub type alias_t = alias; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct dstack { + pub delimiters: *mut libc::c_char, + pub delimiter_depth: libc::c_int, + pub delimiter_space: libc::c_int, +} +pub type yy_state_fast_t = libc::c_int; +#[derive(Copy, Clone)] +#[repr(C)] +pub union INPUT_STREAM { + pub file: *mut FILE, + pub string: *mut libc::c_char, + pub buffered_fd: libc::c_int, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct BASH_INPUT { + pub type_0: stream_type, + pub name: *mut libc::c_char, + pub location: INPUT_STREAM, + pub getter: Option, + pub ungetter: Option, +} +pub type sh_cunget_func_t = fn(libc::c_int) -> libc::c_int; +pub type sh_cget_func_t = fn() -> libc::c_int; +pub type stream_type = libc::c_uint; +pub const st_bstream: stream_type = 4; +pub const st_string: stream_type = 3; +pub const st_stream: stream_type = 2; +pub const st_stdin: stream_type = 1; +pub const st_none: stream_type = 0; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct user_info { + pub uid: uid_t, + pub euid: uid_t, + pub gid: gid_t, + pub egid: gid_t, + pub user_name: *mut libc::c_char, + pub shell: *mut libc::c_char, + pub home_dir: *mut libc::c_char, +} +pub type yytype_uint8 = libc::c_uchar; + +#[derive(Copy, Clone)] +#[repr(C)] +pub union yyalloc { + pub yyss_alloc: yy_state_t, + pub yyvs_alloc: YYSTYPE, +} + +pub type sh_input_line_state_t = _sh_input_line_state_t; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct _sh_input_line_state_t { + pub input_line: *mut libc::c_char, + pub input_line_index: size_t, + pub input_line_size: size_t, + pub input_line_len: size_t, + pub input_property: *mut libc::c_char, + pub input_propsize: size_t, +} +pub type STREAM_SAVER = stream_saver; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct stream_saver { + pub next: *mut stream_saver, + pub bash_input: BASH_INPUT, + pub line: libc::c_int, + pub bstream: *mut BUFFERED_STREAM, +} +pub type BUFFERED_STREAM = BSTREAM; + +#[inline] +fn mbrlen(mut __s: *const libc::c_char, mut __n: size_t, mut __ps: *mut mbstate_t) -> size_t { + unsafe { + return if !__ps.is_null() { + mbrtowc(0 as *mut wchar_t, __s, __n, __ps) + } else { + __mbrlen(__s, __n, 0 as *mut mbstate_t) + }; + } +} +static mut shell_input_line_property: *mut libc::c_char = + 0 as *const libc::c_char as *mut libc::c_char; +static mut shell_input_line_propsize: size_t = 0 as libc::c_int as size_t; + +#[no_mangle] +pub static mut ps1_prompt: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut ps2_prompt: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut ps0_prompt: *mut libc::c_char = 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut prompt_string_pointer: *mut *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut *mut libc::c_char; +#[no_mangle] +pub static mut current_prompt_string: *mut libc::c_char = + 0 as *const libc::c_char as *mut libc::c_char; +#[no_mangle] +pub static mut expand_aliases: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut promptvars: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut extended_quote: libc::c_int = 1 as libc::c_int; +#[no_mangle] +pub static mut current_command_line_count: libc::c_int = 0; +#[no_mangle] +pub static mut saved_command_line_count: libc::c_int = 0; +#[no_mangle] +pub static mut shell_eof_token: libc::c_int = 0; +#[no_mangle] +pub static mut current_token: libc::c_int = 0; +#[no_mangle] +pub static mut parser_state: libc::c_int = 0; +static mut redir_stack: [*mut REDIRECT; 16] = [0 as *const REDIRECT as *mut REDIRECT; 16]; +#[no_mangle] +pub static mut need_here_doc: libc::c_int = 0; +static mut shell_input_line: *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char; +static mut shell_input_line_index: size_t = 0; +static mut shell_input_line_size: size_t = 0; +static mut shell_input_line_len: size_t = 0; +static mut shell_input_line_terminator: libc::c_int = 0; +static mut function_dstart: libc::c_int = 0; +static mut function_bstart: libc::c_int = 0; +static mut arith_for_lineno: libc::c_int = 0; +static mut current_decoded_prompt: *mut libc::c_char = + 0 as *const libc::c_char as *mut libc::c_char; +static mut last_read_token: libc::c_int = 0; +static mut token_before_that: libc::c_int = 0; +static mut two_tokens_ago: libc::c_int = 0; +static mut global_extglob: libc::c_int = 0; +static mut word_lineno: [libc::c_int; 129] = [0; 129]; +static mut word_top: libc::c_int = -(1 as libc::c_int); +static mut token_to_read: libc::c_int = 0; +static mut word_desc_to_read: *mut WORD_DESC = 0 as *const WORD_DESC as *mut WORD_DESC; +static mut source: REDIRECTEE = REDIRECTEE { dest: 0 }; +static mut redir: REDIRECTEE = REDIRECTEE { dest: 0 }; +static mut yytranslate: [yytype_int8; 305] = [ + 0 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 49 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 59 as libc::c_int as yytype_int8, + 60 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 50 as libc::c_int as yytype_int8, + 55 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 54 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 53 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 8 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 10 as libc::c_int as yytype_int8, + 11 as libc::c_int as yytype_int8, + 12 as libc::c_int as yytype_int8, + 13 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 16 as libc::c_int as yytype_int8, + 17 as libc::c_int as yytype_int8, + 18 as libc::c_int as yytype_int8, + 19 as libc::c_int as yytype_int8, + 20 as libc::c_int as yytype_int8, + 21 as libc::c_int as yytype_int8, + 22 as libc::c_int as yytype_int8, + 23 as libc::c_int as yytype_int8, + 24 as libc::c_int as yytype_int8, + 25 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 27 as libc::c_int as yytype_int8, + 28 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 30 as libc::c_int as yytype_int8, + 31 as libc::c_int as yytype_int8, + 32 as libc::c_int as yytype_int8, + 33 as libc::c_int as yytype_int8, + 34 as libc::c_int as yytype_int8, + 35 as libc::c_int as yytype_int8, + 36 as libc::c_int as yytype_int8, + 37 as libc::c_int as yytype_int8, + 38 as libc::c_int as yytype_int8, + 39 as libc::c_int as yytype_int8, + 40 as libc::c_int as yytype_int8, + 41 as libc::c_int as yytype_int8, + 42 as libc::c_int as yytype_int8, + 43 as libc::c_int as yytype_int8, + 44 as libc::c_int as yytype_int8, + 45 as libc::c_int as yytype_int8, + 46 as libc::c_int as yytype_int8, + 47 as libc::c_int as yytype_int8, + 48 as libc::c_int as yytype_int8, + 52 as libc::c_int as yytype_int8, +]; +static mut yypact: [yytype_int16; 346] = [ + 313 as libc::c_int as yytype_int16, + 108 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(6 as libc::c_int) as yytype_int16, + 8 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 10 as libc::c_int as yytype_int16, + 513 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 363 as libc::c_int as yytype_int16, + 153 as libc::c_int as yytype_int16, + -(21 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 593 as libc::c_int as yytype_int16, + 606 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 14 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 113 as libc::c_int as yytype_int16, + 41 as libc::c_int as yytype_int16, + 127 as libc::c_int as yytype_int16, + 72 as libc::c_int as yytype_int16, + 85 as libc::c_int as yytype_int16, + 92 as libc::c_int as yytype_int16, + 95 as libc::c_int as yytype_int16, + 98 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 100 as libc::c_int as yytype_int16, + 105 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 65 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 551 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 572 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 146 as libc::c_int as yytype_int16, + 140 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 67 as libc::c_int as yytype_int16, + 363 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 133 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 93 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 104 as libc::c_int as yytype_int16, + 156 as libc::c_int as yytype_int16, + 161 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 551 as libc::c_int as yytype_int16, + 572 as libc::c_int as yytype_int16, + 163 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 167 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 152 as libc::c_int as yytype_int16, + 208 as libc::c_int as yytype_int16, + 217 as libc::c_int as yytype_int16, + 129 as libc::c_int as yytype_int16, + 220 as libc::c_int as yytype_int16, + 150 as libc::c_int as yytype_int16, + 221 as libc::c_int as yytype_int16, + 223 as libc::c_int as yytype_int16, + 225 as libc::c_int as yytype_int16, + 233 as libc::c_int as yytype_int16, + 234 as libc::c_int as yytype_int16, + 238 as libc::c_int as yytype_int16, + 239 as libc::c_int as yytype_int16, + 158 as libc::c_int as yytype_int16, + 240 as libc::c_int as yytype_int16, + 162 as libc::c_int as yytype_int16, + 241 as libc::c_int as yytype_int16, + 243 as libc::c_int as yytype_int16, + 244 as libc::c_int as yytype_int16, + 252 as libc::c_int as yytype_int16, + 253 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 194 as libc::c_int as yytype_int16, + 227 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 572 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 463 as libc::c_int as yytype_int16, + 463 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(7 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 59 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 52 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 62 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 235 as libc::c_int as yytype_int16, + 572 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 572 as libc::c_int as yytype_int16, + 572 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 413 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 191 as libc::c_int as yytype_int16, + 191 as libc::c_int as yytype_int16, + 245 as libc::c_int as yytype_int16, + 245 as libc::c_int as yytype_int16, + 203 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 37 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 176 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 270 as libc::c_int as yytype_int16, + 228 as libc::c_int as yytype_int16, + 76 as libc::c_int as yytype_int16, + 79 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 176 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 278 as libc::c_int as yytype_int16, + 282 as libc::c_int as yytype_int16, + 563 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 572 as libc::c_int as yytype_int16, + 572 as libc::c_int as yytype_int16, + 563 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 67 as libc::c_int as yytype_int16, + 67 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 291 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 294 as libc::c_int as yytype_int16, + 175 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 28 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 292 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 187 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 250 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 295 as libc::c_int as yytype_int16, + 413 as libc::c_int as yytype_int16, + 187 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 251 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 563 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 304 as libc::c_int as yytype_int16, + 314 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 196 as libc::c_int as yytype_int16, + 196 as libc::c_int as yytype_int16, + 196 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 179 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 296 as libc::c_int as yytype_int16, + -(28 as libc::c_int) as yytype_int16, + 302 as libc::c_int as yytype_int16, + 274 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 87 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 318 as libc::c_int as yytype_int16, + 276 as libc::c_int as yytype_int16, + 322 as libc::c_int as yytype_int16, + 280 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(7 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 111 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 39 as libc::c_int as yytype_int16, + 319 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 114 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 115 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 226 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 413 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 329 as libc::c_int as yytype_int16, + 288 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 332 as libc::c_int as yytype_int16, + 297 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 413 as libc::c_int as yytype_int16, + 338 as libc::c_int as yytype_int16, + 303 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 339 as libc::c_int as yytype_int16, + 305 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, +]; +static mut yydefact: [yytype_uint8; 346] = [ + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 169 as libc::c_int as yytype_uint8, + 53 as libc::c_int as yytype_uint8, + 54 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 115 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 3 as libc::c_int as yytype_uint8, + 6 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 55 as libc::c_int as yytype_uint8, + 58 as libc::c_int as yytype_uint8, + 60 as libc::c_int as yytype_uint8, + 168 as libc::c_int as yytype_uint8, + 61 as libc::c_int as yytype_uint8, + 65 as libc::c_int as yytype_uint8, + 75 as libc::c_int as yytype_uint8, + 69 as libc::c_int as yytype_uint8, + 66 as libc::c_int as yytype_uint8, + 63 as libc::c_int as yytype_uint8, + 71 as libc::c_int as yytype_uint8, + 64 as libc::c_int as yytype_uint8, + 70 as libc::c_int as yytype_uint8, + 72 as libc::c_int as yytype_uint8, + 73 as libc::c_int as yytype_uint8, + 74 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 153 as libc::c_int as yytype_uint8, + 160 as libc::c_int as yytype_uint8, + 161 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 4 as libc::c_int as yytype_uint8, + 5 as libc::c_int as yytype_uint8, + 135 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 53 as libc::c_int as yytype_uint8, + 110 as libc::c_int as yytype_uint8, + 106 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 149 as libc::c_int as yytype_uint8, + 148 as libc::c_int as yytype_uint8, + 150 as libc::c_int as yytype_uint8, + 165 as libc::c_int as yytype_uint8, + 162 as libc::c_int as yytype_uint8, + 170 as libc::c_int as yytype_uint8, + 171 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 15 as libc::c_int as yytype_uint8, + 24 as libc::c_int as yytype_uint8, + 39 as libc::c_int as yytype_uint8, + 33 as libc::c_int as yytype_uint8, + 48 as libc::c_int as yytype_uint8, + 30 as libc::c_int as yytype_uint8, + 42 as libc::c_int as yytype_uint8, + 36 as libc::c_int as yytype_uint8, + 45 as libc::c_int as yytype_uint8, + 27 as libc::c_int as yytype_uint8, + 51 as libc::c_int as yytype_uint8, + 52 as libc::c_int as yytype_uint8, + 21 as libc::c_int as yytype_uint8, + 18 as libc::c_int as yytype_uint8, + 9 as libc::c_int as yytype_uint8, + 10 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 1 as libc::c_int as yytype_uint8, + 53 as libc::c_int as yytype_uint8, + 59 as libc::c_int as yytype_uint8, + 56 as libc::c_int as yytype_uint8, + 62 as libc::c_int as yytype_uint8, + 146 as libc::c_int as yytype_uint8, + 147 as libc::c_int as yytype_uint8, + 2 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 154 as libc::c_int as yytype_uint8, + 155 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 164 as libc::c_int as yytype_uint8, + 163 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 152 as libc::c_int as yytype_uint8, + 134 as libc::c_int as yytype_uint8, + 136 as libc::c_int as yytype_uint8, + 145 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 103 as libc::c_int as yytype_uint8, + 101 as libc::c_int as yytype_uint8, + 108 as libc::c_int as yytype_uint8, + 107 as libc::c_int as yytype_uint8, + 116 as libc::c_int as yytype_uint8, + 172 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 17 as libc::c_int as yytype_uint8, + 26 as libc::c_int as yytype_uint8, + 41 as libc::c_int as yytype_uint8, + 35 as libc::c_int as yytype_uint8, + 50 as libc::c_int as yytype_uint8, + 32 as libc::c_int as yytype_uint8, + 44 as libc::c_int as yytype_uint8, + 38 as libc::c_int as yytype_uint8, + 47 as libc::c_int as yytype_uint8, + 29 as libc::c_int as yytype_uint8, + 23 as libc::c_int as yytype_uint8, + 20 as libc::c_int as yytype_uint8, + 13 as libc::c_int as yytype_uint8, + 14 as libc::c_int as yytype_uint8, + 16 as libc::c_int as yytype_uint8, + 25 as libc::c_int as yytype_uint8, + 40 as libc::c_int as yytype_uint8, + 34 as libc::c_int as yytype_uint8, + 49 as libc::c_int as yytype_uint8, + 31 as libc::c_int as yytype_uint8, + 43 as libc::c_int as yytype_uint8, + 37 as libc::c_int as yytype_uint8, + 46 as libc::c_int as yytype_uint8, + 28 as libc::c_int as yytype_uint8, + 22 as libc::c_int as yytype_uint8, + 19 as libc::c_int as yytype_uint8, + 11 as libc::c_int as yytype_uint8, + 12 as libc::c_int as yytype_uint8, + 114 as libc::c_int as yytype_uint8, + 105 as libc::c_int as yytype_uint8, + 57 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 158 as libc::c_int as yytype_uint8, + 159 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 104 as libc::c_int as yytype_uint8, + 109 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 156 as libc::c_int as yytype_uint8, + 157 as libc::c_int as yytype_uint8, + 167 as libc::c_int as yytype_uint8, + 166 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 111 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 138 as libc::c_int as yytype_uint8, + 139 as libc::c_int as yytype_uint8, + 137 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 120 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 7 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 86 as libc::c_int as yytype_uint8, + 87 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 67 as libc::c_int as yytype_uint8, + 68 as libc::c_int as yytype_uint8, + 102 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 99 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 113 as libc::c_int as yytype_uint8, + 140 as libc::c_int as yytype_uint8, + 141 as libc::c_int as yytype_uint8, + 142 as libc::c_int as yytype_uint8, + 143 as libc::c_int as yytype_uint8, + 144 as libc::c_int as yytype_uint8, + 98 as libc::c_int as yytype_uint8, + 126 as libc::c_int as yytype_uint8, + 128 as libc::c_int as yytype_uint8, + 130 as libc::c_int as yytype_uint8, + 121 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 96 as libc::c_int as yytype_uint8, + 132 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 76 as libc::c_int as yytype_uint8, + 8 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 77 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 88 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 89 as libc::c_int as yytype_uint8, + 100 as libc::c_int as yytype_uint8, + 112 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 127 as libc::c_int as yytype_uint8, + 129 as libc::c_int as yytype_uint8, + 131 as libc::c_int as yytype_uint8, + 97 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 78 as libc::c_int as yytype_uint8, + 79 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 84 as libc::c_int as yytype_uint8, + 85 as libc::c_int as yytype_uint8, + 90 as libc::c_int as yytype_uint8, + 91 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 117 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 133 as libc::c_int as yytype_uint8, + 122 as libc::c_int as yytype_uint8, + 123 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 151 as libc::c_int as yytype_uint8, + 119 as libc::c_int as yytype_uint8, + 124 as libc::c_int as yytype_uint8, + 125 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 82 as libc::c_int as yytype_uint8, + 83 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 0 as libc::c_int as yytype_uint8, + 94 as libc::c_int as yytype_uint8, + 95 as libc::c_int as yytype_uint8, + 118 as libc::c_int as yytype_uint8, + 80 as libc::c_int as yytype_uint8, + 81 as libc::c_int as yytype_uint8, + 92 as libc::c_int as yytype_uint8, + 93 as libc::c_int as yytype_uint8, +]; +static mut yypgoto: [yytype_int16; 38] = [ + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 117 as libc::c_int as yytype_int16, + -(37 as libc::c_int) as yytype_int16, + -(19 as libc::c_int) as yytype_int16, + -(67 as libc::c_int) as yytype_int16, + 353 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(8 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(184 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 53 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 142 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 102 as libc::c_int as yytype_int16, + -(203 as libc::c_int) as yytype_int16, + -(2 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + 283 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(47 as libc::c_int) as yytype_int16, + -(49 as libc::c_int) as yytype_int16, + -(204 as libc::c_int) as yytype_int16, + -(118 as libc::c_int) as yytype_int16, + 6 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + -(204 as libc::c_int) as yytype_int16, +]; +static mut yydefgoto: [yytype_int16; 38] = [ + 0 as libc::c_int as yytype_int16, + 34 as libc::c_int as yytype_int16, + 241 as libc::c_int as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 122 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + 40 as libc::c_int as yytype_int16, + 41 as libc::c_int as yytype_int16, + 42 as libc::c_int as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 152 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + 48 as libc::c_int as yytype_int16, + 49 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 227 as libc::c_int as yytype_int16, + 233 as libc::c_int as yytype_int16, + 234 as libc::c_int as yytype_int16, + 235 as libc::c_int as yytype_int16, + 277 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 117 as libc::c_int as yytype_int16, + 136 as libc::c_int as yytype_int16, + 137 as libc::c_int as yytype_int16, + 125 as libc::c_int as yytype_int16, + 75 as libc::c_int as yytype_int16, + 60 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 138 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, +]; +static mut yytable: [yytype_int16; 662] = [ + 59 as libc::c_int as yytype_int16, + 70 as libc::c_int as yytype_int16, + 121 as libc::c_int as yytype_int16, + 154 as libc::c_int as yytype_int16, + 65 as libc::c_int as yytype_int16, + 66 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 250 as libc::c_int as yytype_int16, + 132 as libc::c_int as yytype_int16, + 254 as libc::c_int as yytype_int16, + 191 as libc::c_int as yytype_int16, + 192 as libc::c_int as yytype_int16, + 139 as libc::c_int as yytype_int16, + 141 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 146 as libc::c_int as yytype_int16, + 144 as libc::c_int as yytype_int16, + 76 as libc::c_int as yytype_int16, + 120 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 61 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 302 as libc::c_int as yytype_int16, + 196 as libc::c_int as yytype_int16, + 197 as libc::c_int as yytype_int16, + 64 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 116 as libc::c_int as yytype_int16, + 257 as libc::c_int as yytype_int16, + 303 as libc::c_int as yytype_int16, + 121 as libc::c_int as yytype_int16, + 62 as libc::c_int as yytype_int16, + 259 as libc::c_int as yytype_int16, + 67 as libc::c_int as yytype_int16, + 274 as libc::c_int as yytype_int16, + 79 as libc::c_int as yytype_int16, + 63 as libc::c_int as yytype_int16, + 100 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 198 as libc::c_int as yytype_int16, + 199 as libc::c_int as yytype_int16, + 200 as libc::c_int as yytype_int16, + 287 as libc::c_int as yytype_int16, + 288 as libc::c_int as yytype_int16, + 300 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 71 as libc::c_int as yytype_int16, + 120 as libc::c_int as yytype_int16, + 237 as libc::c_int as yytype_int16, + 101 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 275 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 151 as libc::c_int as yytype_int16, + 153 as libc::c_int as yytype_int16, + 133 as libc::c_int as yytype_int16, + 149 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 275 as libc::c_int as yytype_int16, + 118 as libc::c_int as yytype_int16, + 203 as libc::c_int as yytype_int16, + 105 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 142 as libc::c_int as yytype_int16, + 150 as libc::c_int as yytype_int16, + 220 as libc::c_int as yytype_int16, + 221 as libc::c_int as yytype_int16, + 204 as libc::c_int as yytype_int16, + 294 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 210 as libc::c_int as yytype_int16, + 189 as libc::c_int as yytype_int16, + 190 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 201 as libc::c_int as yytype_int16, + 193 as libc::c_int as yytype_int16, + 194 as libc::c_int as yytype_int16, + 211 as libc::c_int as yytype_int16, + 217 as libc::c_int as yytype_int16, + 188 as libc::c_int as yytype_int16, + 218 as libc::c_int as yytype_int16, + 276 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 246 as libc::c_int as yytype_int16, + 202 as libc::c_int as yytype_int16, + 302 as libc::c_int as yytype_int16, + 248 as libc::c_int as yytype_int16, + 238 as libc::c_int as yytype_int16, + 208 as libc::c_int as yytype_int16, + 209 as libc::c_int as yytype_int16, + 276 as libc::c_int as yytype_int16, + 109 as libc::c_int as yytype_int16, + 317 as libc::c_int as yytype_int16, + 215 as libc::c_int as yytype_int16, + 307 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 72 as libc::c_int as yytype_int16, + 73 as libc::c_int as yytype_int16, + 74 as libc::c_int as yytype_int16, + 219 as libc::c_int as yytype_int16, + 205 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 110 as libc::c_int as yytype_int16, + 143 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 121 as libc::c_int as yytype_int16, + 130 as libc::c_int as yytype_int16, + 121 as libc::c_int as yytype_int16, + 188 as libc::c_int as yytype_int16, + 111 as libc::c_int as yytype_int16, + 212 as libc::c_int as yytype_int16, + 131 as libc::c_int as yytype_int16, + 112 as libc::c_int as yytype_int16, + 337 as libc::c_int as yytype_int16, + 338 as libc::c_int as yytype_int16, + 113 as libc::c_int as yytype_int16, + 314 as libc::c_int as yytype_int16, + 114 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 321 as libc::c_int as yytype_int16, + 325 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 115 as libc::c_int as yytype_int16, + 195 as libc::c_int as yytype_int16, + 247 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 249 as libc::c_int as yytype_int16, + 134 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 102 as libc::c_int as yytype_int16, + 206 as libc::c_int as yytype_int16, + 207 as libc::c_int as yytype_int16, + 103 as libc::c_int as yytype_int16, + 140 as libc::c_int as yytype_int16, + 308 as libc::c_int as yytype_int16, + 213 as libc::c_int as yytype_int16, + 214 as libc::c_int as yytype_int16, + 228 as libc::c_int as yytype_int16, + 229 as libc::c_int as yytype_int16, + 230 as libc::c_int as yytype_int16, + 231 as libc::c_int as yytype_int16, + 232 as libc::c_int as yytype_int16, + 236 as libc::c_int as yytype_int16, + 106 as libc::c_int as yytype_int16, + 145 as libc::c_int as yytype_int16, + 160 as libc::c_int as yytype_int16, + 107 as libc::c_int as yytype_int16, + 242 as libc::c_int as yytype_int16, + 161 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 251 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 251 as libc::c_int as yytype_int16, + 253 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 258 as libc::c_int as yytype_int16, + 315 as libc::c_int as yytype_int16, + 104 as libc::c_int as yytype_int16, + 147 as libc::c_int as yytype_int16, + 322 as libc::c_int as yytype_int16, + 326 as libc::c_int as yytype_int16, + 126 as libc::c_int as yytype_int16, + 127 as libc::c_int as yytype_int16, + 148 as libc::c_int as yytype_int16, + 164 as libc::c_int as yytype_int16, + 77 as libc::c_int as yytype_int16, + 78 as libc::c_int as yytype_int16, + 165 as libc::c_int as yytype_int16, + 188 as libc::c_int as yytype_int16, + 188 as libc::c_int as yytype_int16, + 155 as libc::c_int as yytype_int16, + 108 as libc::c_int as yytype_int16, + 174 as libc::c_int as yytype_int16, + 162 as libc::c_int as yytype_int16, + 273 as libc::c_int as yytype_int16, + 175 as libc::c_int as yytype_int16, + 178 as libc::c_int as yytype_int16, + 128 as libc::c_int as yytype_int16, + 129 as libc::c_int as yytype_int16, + 179 as libc::c_int as yytype_int16, + 156 as libc::c_int as yytype_int16, + 283 as libc::c_int as yytype_int16, + 282 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 123 as libc::c_int as yytype_int16, + 124 as libc::c_int as yytype_int16, + 251 as libc::c_int as yytype_int16, + 251 as libc::c_int as yytype_int16, + 239 as libc::c_int as yytype_int16, + 240 as libc::c_int as yytype_int16, + 243 as libc::c_int as yytype_int16, + 292 as libc::c_int as yytype_int16, + 291 as libc::c_int as yytype_int16, + 166 as libc::c_int as yytype_int16, + 151 as libc::c_int as yytype_int16, + 224 as libc::c_int as yytype_int16, + 225 as libc::c_int as yytype_int16, + 226 as libc::c_int as yytype_int16, + 151 as libc::c_int as yytype_int16, + 157 as libc::c_int as yytype_int16, + 281 as libc::c_int as yytype_int16, + 176 as libc::c_int as yytype_int16, + 269 as libc::c_int as yytype_int16, + 270 as libc::c_int as yytype_int16, + 271 as libc::c_int as yytype_int16, + 180 as libc::c_int as yytype_int16, + 297 as libc::c_int as yytype_int16, + 298 as libc::c_int as yytype_int16, + 299 as libc::c_int as yytype_int16, + 260 as libc::c_int as yytype_int16, + 261 as libc::c_int as yytype_int16, + 126 as libc::c_int as yytype_int16, + 127 as libc::c_int as yytype_int16, + 72 as libc::c_int as yytype_int16, + 73 as libc::c_int as yytype_int16, + 74 as libc::c_int as yytype_int16, + 196 as libc::c_int as yytype_int16, + 197 as libc::c_int as yytype_int16, + 329 as libc::c_int as yytype_int16, + 225 as libc::c_int as yytype_int16, + 306 as libc::c_int as yytype_int16, + 158 as libc::c_int as yytype_int16, + 278 as libc::c_int as yytype_int16, + 279 as libc::c_int as yytype_int16, + 72 as libc::c_int as yytype_int16, + 73 as libc::c_int as yytype_int16, + 74 as libc::c_int as yytype_int16, + 222 as libc::c_int as yytype_int16, + 223 as libc::c_int as yytype_int16, + 313 as libc::c_int as yytype_int16, + 159 as libc::c_int as yytype_int16, + 285 as libc::c_int as yytype_int16, + 286 as libc::c_int as yytype_int16, + 163 as libc::c_int as yytype_int16, + 167 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 168 as libc::c_int as yytype_int16, + 151 as libc::c_int as yytype_int16, + 169 as libc::c_int as yytype_int16, + 186 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 320 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 170 as libc::c_int as yytype_int16, + 171 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 172 as libc::c_int as yytype_int16, + 173 as libc::c_int as yytype_int16, + 177 as libc::c_int as yytype_int16, + 181 as libc::c_int as yytype_int16, + 332 as libc::c_int as yytype_int16, + 182 as libc::c_int as yytype_int16, + 183 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 251 as libc::c_int as yytype_int16, + 251 as libc::c_int as yytype_int16, + 184 as libc::c_int as yytype_int16, + 185 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 244 as libc::c_int as yytype_int16, + 245 as libc::c_int as yytype_int16, + 187 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 255 as libc::c_int as yytype_int16, + 316 as libc::c_int as yytype_int16, + 216 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 256 as libc::c_int as yytype_int16, + 262 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 319 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 268 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 323 as libc::c_int as yytype_int16, + 324 as libc::c_int as yytype_int16, + 280 as libc::c_int as yytype_int16, + 284 as libc::c_int as yytype_int16, + 293 as libc::c_int as yytype_int16, + 289 as libc::c_int as yytype_int16, + 295 as libc::c_int as yytype_int16, + 327 as libc::c_int as yytype_int16, + 328 as libc::c_int as yytype_int16, + 1 as libc::c_int as yytype_int16, + 331 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 304 as libc::c_int as yytype_int16, + 296 as libc::c_int as yytype_int16, + 333 as libc::c_int as yytype_int16, + 334 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 275 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 341 as libc::c_int as yytype_int16, + 252 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 305 as libc::c_int as yytype_int16, + 309 as libc::c_int as yytype_int16, + 310 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 311 as libc::c_int as yytype_int16, + 312 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 335 as libc::c_int as yytype_int16, + 318 as libc::c_int as yytype_int16, + 336 as libc::c_int as yytype_int16, + 339 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 342 as libc::c_int as yytype_int16, + 344 as libc::c_int as yytype_int16, + 340 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 343 as libc::c_int as yytype_int16, + 69 as libc::c_int as yytype_int16, + 345 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 330 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 272 as libc::c_int as yytype_int16, + 301 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 72 as libc::c_int as yytype_int16, + 73 as libc::c_int as yytype_int16, + 74 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 263 as libc::c_int as yytype_int16, + 264 as libc::c_int as yytype_int16, + 265 as libc::c_int as yytype_int16, + 266 as libc::c_int as yytype_int16, + 267 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 290 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 68 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 2 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 119 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 20 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 135 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 80 as libc::c_int as yytype_int16, + 81 as libc::c_int as yytype_int16, + 82 as libc::c_int as yytype_int16, + 83 as libc::c_int as yytype_int16, + 84 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 85 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 86 as libc::c_int as yytype_int16, + 87 as libc::c_int as yytype_int16, + 90 as libc::c_int as yytype_int16, + 91 as libc::c_int as yytype_int16, + 92 as libc::c_int as yytype_int16, + 93 as libc::c_int as yytype_int16, + 94 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 88 as libc::c_int as yytype_int16, + 89 as libc::c_int as yytype_int16, + 95 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 96 as libc::c_int as yytype_int16, + 97 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 98 as libc::c_int as yytype_int16, + 99 as libc::c_int as yytype_int16, +]; +static mut yycheck: [yytype_int16; 662] = [ + 2 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + 70 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 210 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 212 as libc::c_int as yytype_int16, + 128 as libc::c_int as yytype_int16, + 129 as libc::c_int as yytype_int16, + 61 as libc::c_int as yytype_int16, + 62 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 64 as libc::c_int as yytype_int16, + 63 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 34 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 215 as libc::c_int as yytype_int16, + 60 as libc::c_int as yytype_int16, + 70 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 219 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 31 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 49 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 248 as libc::c_int as yytype_int16, + 249 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 32 as libc::c_int as yytype_int16, + 69 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 67 as libc::c_int as yytype_int16, + 68 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 0 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 189 as libc::c_int as yytype_int16, + 190 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 258 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 126 as libc::c_int as yytype_int16, + 127 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 130 as libc::c_int as yytype_int16, + 131 as libc::c_int as yytype_int16, + 21 as libc::c_int as yytype_int16, + 151 as libc::c_int as yytype_int16, + 122 as libc::c_int as yytype_int16, + 153 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 140 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 144 as libc::c_int as yytype_int16, + 145 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 60 as libc::c_int as yytype_int16, + 149 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 157 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 151 as libc::c_int as yytype_int16, + 48 as libc::c_int as yytype_int16, + 153 as libc::c_int as yytype_int16, + 154 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 53 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 325 as libc::c_int as yytype_int16, + 326 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 134 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 128 as libc::c_int as yytype_int16, + 129 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 142 as libc::c_int as yytype_int16, + 143 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 147 as libc::c_int as yytype_int16, + 148 as libc::c_int as yytype_int16, + 196 as libc::c_int as yytype_int16, + 197 as libc::c_int as yytype_int16, + 198 as libc::c_int as yytype_int16, + 199 as libc::c_int as yytype_int16, + 200 as libc::c_int as yytype_int16, + 201 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 204 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 210 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 212 as libc::c_int as yytype_int16, + 211 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 216 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 34 as libc::c_int as yytype_int16, + 14 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 24 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 217 as libc::c_int as yytype_int16, + 218 as libc::c_int as yytype_int16, + 19 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 235 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 49 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 25 as libc::c_int as yytype_int16, + 242 as libc::c_int as yytype_int16, + 241 as libc::c_int as yytype_int16, + 189 as libc::c_int as yytype_int16, + 190 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 248 as libc::c_int as yytype_int16, + 249 as libc::c_int as yytype_int16, + 203 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 205 as libc::c_int as yytype_int16, + 253 as libc::c_int as yytype_int16, + 252 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 215 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 219 as libc::c_int as yytype_int16, + 60 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 40 as libc::c_int as yytype_int16, + 41 as libc::c_int as yytype_int16, + 42 as libc::c_int as yytype_int16, + 56 as libc::c_int as yytype_int16, + 40 as libc::c_int as yytype_int16, + 41 as libc::c_int as yytype_int16, + 42 as libc::c_int as yytype_int16, + 224 as libc::c_int as yytype_int16, + 225 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 34 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 33 as libc::c_int as yytype_int16, + 34 as libc::c_int as yytype_int16, + 5 as libc::c_int as yytype_int16, + 6 as libc::c_int as yytype_int16, + 282 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 237 as libc::c_int as yytype_int16, + 238 as libc::c_int as yytype_int16, + 50 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 193 as libc::c_int as yytype_int16, + 194 as libc::c_int as yytype_int16, + 291 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 246 as libc::c_int as yytype_int16, + 247 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 258 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 303 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 317 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 325 as libc::c_int as yytype_int16, + 326 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 60 as libc::c_int as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 296 as libc::c_int as yytype_int16, + 60 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 303 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 307 as libc::c_int as yytype_int16, + 308 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 7 as libc::c_int as yytype_int16, + 314 as libc::c_int as yytype_int16, + 315 as libc::c_int as yytype_int16, + 1 as libc::c_int as yytype_int16, + 317 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 4 as libc::c_int as yytype_int16, + 321 as libc::c_int as yytype_int16, + 322 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 329 as libc::c_int as yytype_int16, + 211 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 22 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 15 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 9 as libc::c_int as yytype_int16, + 58 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 316 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 235 as libc::c_int as yytype_int16, + 276 as libc::c_int as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 22 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 50 as libc::c_int as yytype_int16, + 51 as libc::c_int as yytype_int16, + 52 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 57 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 22 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 51 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 3 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 57 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 16 as libc::c_int as yytype_int16, + 17 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 22 as libc::c_int as yytype_int16, + 23 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + 228 as libc::c_int as yytype_int16, + 229 as libc::c_int as yytype_int16, + 230 as libc::c_int as yytype_int16, + 231 as libc::c_int as yytype_int16, + 232 as libc::c_int as yytype_int16, + 3 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 57 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 18 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 251 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 30 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 3 as libc::c_int as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 57 as libc::c_int as yytype_int16, + 8 as libc::c_int as yytype_int16, + 59 as libc::c_int as yytype_int16, + 10 as libc::c_int as yytype_int16, + 11 as libc::c_int as yytype_int16, + 12 as libc::c_int as yytype_int16, + 13 as libc::c_int as yytype_int16, + 26 as libc::c_int as yytype_int16, + 27 as libc::c_int as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + 18 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 30 as libc::c_int as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 28 as libc::c_int as yytype_int16, + 29 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 51 as libc::c_int as yytype_int16, + 43 as libc::c_int as yytype_int16, + 44 as libc::c_int as yytype_int16, + 45 as libc::c_int as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + 57 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 59 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 43 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + 35 as libc::c_int as yytype_int16, + 36 as libc::c_int as yytype_int16, + 37 as libc::c_int as yytype_int16, + 38 as libc::c_int as yytype_int16, + 39 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, + 43 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 46 as libc::c_int as yytype_int16, + 47 as libc::c_int as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + -(1 as libc::c_int) as yytype_int16, + 54 as libc::c_int as yytype_int16, + 55 as libc::c_int as yytype_int16, +]; +#[no_mangle] +pub static mut EOF_Reached: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub fn return_EOF() -> libc::c_int { + return -(1 as libc::c_int); +} +static mut yystos: [yytype_int8; 346] = [ + 0 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 8 as libc::c_int as yytype_int8, + 10 as libc::c_int as yytype_int8, + 11 as libc::c_int as yytype_int8, + 12 as libc::c_int as yytype_int8, + 13 as libc::c_int as yytype_int8, + 16 as libc::c_int as yytype_int8, + 17 as libc::c_int as yytype_int8, + 18 as libc::c_int as yytype_int8, + 22 as libc::c_int as yytype_int8, + 23 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 27 as libc::c_int as yytype_int8, + 28 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 30 as libc::c_int as yytype_int8, + 35 as libc::c_int as yytype_int8, + 36 as libc::c_int as yytype_int8, + 37 as libc::c_int as yytype_int8, + 38 as libc::c_int as yytype_int8, + 39 as libc::c_int as yytype_int8, + 43 as libc::c_int as yytype_int8, + 44 as libc::c_int as yytype_int8, + 45 as libc::c_int as yytype_int8, + 46 as libc::c_int as yytype_int8, + 47 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 52 as libc::c_int as yytype_int8, + 54 as libc::c_int as yytype_int8, + 55 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 59 as libc::c_int as yytype_int8, + 62 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 65 as libc::c_int as yytype_int8, + 67 as libc::c_int as yytype_int8, + 68 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 71 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 73 as libc::c_int as yytype_int8, + 74 as libc::c_int as yytype_int8, + 76 as libc::c_int as yytype_int8, + 77 as libc::c_int as yytype_int8, + 78 as libc::c_int as yytype_int8, + 79 as libc::c_int as yytype_int8, + 80 as libc::c_int as yytype_int8, + 81 as libc::c_int as yytype_int8, + 94 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 97 as libc::c_int as yytype_int8, + 98 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 52 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 31 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 67 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 32 as libc::c_int as yytype_int8, + 50 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 52 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 24 as libc::c_int as yytype_int8, + 25 as libc::c_int as yytype_int8, + 59 as libc::c_int as yytype_int8, + 35 as libc::c_int as yytype_int8, + 36 as libc::c_int as yytype_int8, + 37 as libc::c_int as yytype_int8, + 38 as libc::c_int as yytype_int8, + 39 as libc::c_int as yytype_int8, + 43 as libc::c_int as yytype_int8, + 46 as libc::c_int as yytype_int8, + 47 as libc::c_int as yytype_int8, + 54 as libc::c_int as yytype_int8, + 55 as libc::c_int as yytype_int8, + 35 as libc::c_int as yytype_int8, + 36 as libc::c_int as yytype_int8, + 37 as libc::c_int as yytype_int8, + 38 as libc::c_int as yytype_int8, + 39 as libc::c_int as yytype_int8, + 43 as libc::c_int as yytype_int8, + 46 as libc::c_int as yytype_int8, + 47 as libc::c_int as yytype_int8, + 54 as libc::c_int as yytype_int8, + 55 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 0 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 65 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 66 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 52 as libc::c_int as yytype_int8, + 91 as libc::c_int as yytype_int8, + 33 as libc::c_int as yytype_int8, + 34 as libc::c_int as yytype_int8, + 49 as libc::c_int as yytype_int8, + 50 as libc::c_int as yytype_int8, + 48 as libc::c_int as yytype_int8, + 53 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 89 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 50 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 50 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 59 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 75 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 66 as libc::c_int as yytype_int8, + 19 as libc::c_int as yytype_int8, + 25 as libc::c_int as yytype_int8, + 60 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 29 as libc::c_int as yytype_int8, + 56 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 60 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 33 as libc::c_int as yytype_int8, + 34 as libc::c_int as yytype_int8, + 49 as libc::c_int as yytype_int8, + 50 as libc::c_int as yytype_int8, + 51 as libc::c_int as yytype_int8, + 21 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 21 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 21 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 60 as libc::c_int as yytype_int8, + 66 as libc::c_int as yytype_int8, + 66 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 97 as libc::c_int as yytype_int8, + 97 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 82 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 83 as libc::c_int as yytype_int8, + 84 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 63 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 63 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 75 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 75 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 40 as libc::c_int as yytype_int8, + 41 as libc::c_int as yytype_int8, + 42 as libc::c_int as yytype_int8, + 84 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 59 as libc::c_int as yytype_int8, + 86 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 75 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 40 as libc::c_int as yytype_int8, + 41 as libc::c_int as yytype_int8, + 42 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 86 as libc::c_int as yytype_int8, + 53 as libc::c_int as yytype_int8, + 60 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 60 as libc::c_int as yytype_int8, + 26 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 14 as libc::c_int as yytype_int8, + 57 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 82 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, + 15 as libc::c_int as yytype_int8, + 58 as libc::c_int as yytype_int8, +]; +#[no_mangle] +pub static mut bash_input: BASH_INPUT = BASH_INPUT { + type_0: st_none, + name: 0 as *const libc::c_char as *mut libc::c_char, + location: INPUT_STREAM { + file: 0 as *const FILE as *mut FILE, + }, + getter: None, + ungetter: None, +}; +#[no_mangle] +pub fn initialize_bash_input() { + unsafe { + bash_input.type_0 = st_none; + if !(bash_input.name).is_null() { + free(bash_input.name as *mut libc::c_void); + } + bash_input.name = 0 as *mut libc::c_char; + bash_input.name = 0 as *mut libc::c_void as *mut libc::c_char; + bash_input.location.file = 0 as *mut libc::c_void as *mut FILE; + bash_input.location.string = 0 as *mut libc::c_void as *mut libc::c_char; + bash_input.getter = ::core::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void, + ); + bash_input.ungetter = ::core::mem::transmute::<*mut libc::c_void, Option>( + 0 as *mut libc::c_void, + ); + } +} +#[no_mangle] +pub fn init_yy_io( + mut get: Option, + mut unget: Option, + mut type_0: stream_type, + mut name: *const libc::c_char, + mut location: INPUT_STREAM, +) { + unsafe { + bash_input.type_0 = type_0; + if !(bash_input.name).is_null() { + free(bash_input.name as *mut libc::c_void); + } + bash_input.name = 0 as *mut libc::c_char; + bash_input.name = if !name.is_null() { + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(name) as u64) as usize, + ) as *mut libc::c_char, + name, + ) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + + bash_input.location = location; + bash_input.getter = get; + bash_input.ungetter = unget; + } +} +static mut yyr1: [yytype_int8; 173] = [ + 0 as libc::c_int as yytype_int8, + 61 as libc::c_int as yytype_int8, + 62 as libc::c_int as yytype_int8, + 62 as libc::c_int as yytype_int8, + 62 as libc::c_int as yytype_int8, + 62 as libc::c_int as yytype_int8, + 62 as libc::c_int as yytype_int8, + 63 as libc::c_int as yytype_int8, + 63 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 64 as libc::c_int as yytype_int8, + 65 as libc::c_int as yytype_int8, + 65 as libc::c_int as yytype_int8, + 65 as libc::c_int as yytype_int8, + 66 as libc::c_int as yytype_int8, + 66 as libc::c_int as yytype_int8, + 67 as libc::c_int as yytype_int8, + 67 as libc::c_int as yytype_int8, + 68 as libc::c_int as yytype_int8, + 68 as libc::c_int as yytype_int8, + 68 as libc::c_int as yytype_int8, + 68 as libc::c_int as yytype_int8, + 68 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 69 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 70 as libc::c_int as yytype_int8, + 71 as libc::c_int as yytype_int8, + 71 as libc::c_int as yytype_int8, + 71 as libc::c_int as yytype_int8, + 71 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 72 as libc::c_int as yytype_int8, + 73 as libc::c_int as yytype_int8, + 73 as libc::c_int as yytype_int8, + 73 as libc::c_int as yytype_int8, + 74 as libc::c_int as yytype_int8, + 74 as libc::c_int as yytype_int8, + 74 as libc::c_int as yytype_int8, + 74 as libc::c_int as yytype_int8, + 75 as libc::c_int as yytype_int8, + 75 as libc::c_int as yytype_int8, + 76 as libc::c_int as yytype_int8, + 77 as libc::c_int as yytype_int8, + 77 as libc::c_int as yytype_int8, + 77 as libc::c_int as yytype_int8, + 77 as libc::c_int as yytype_int8, + 77 as libc::c_int as yytype_int8, + 78 as libc::c_int as yytype_int8, + 78 as libc::c_int as yytype_int8, + 78 as libc::c_int as yytype_int8, + 79 as libc::c_int as yytype_int8, + 80 as libc::c_int as yytype_int8, + 81 as libc::c_int as yytype_int8, + 82 as libc::c_int as yytype_int8, + 82 as libc::c_int as yytype_int8, + 82 as libc::c_int as yytype_int8, + 83 as libc::c_int as yytype_int8, + 83 as libc::c_int as yytype_int8, + 84 as libc::c_int as yytype_int8, + 84 as libc::c_int as yytype_int8, + 84 as libc::c_int as yytype_int8, + 84 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 85 as libc::c_int as yytype_int8, + 86 as libc::c_int as yytype_int8, + 86 as libc::c_int as yytype_int8, + 87 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 88 as libc::c_int as yytype_int8, + 89 as libc::c_int as yytype_int8, + 89 as libc::c_int as yytype_int8, + 89 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 90 as libc::c_int as yytype_int8, + 91 as libc::c_int as yytype_int8, + 91 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 92 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 93 as libc::c_int as yytype_int8, + 94 as libc::c_int as yytype_int8, + 94 as libc::c_int as yytype_int8, + 94 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 95 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 96 as libc::c_int as yytype_int8, + 97 as libc::c_int as yytype_int8, + 97 as libc::c_int as yytype_int8, + 97 as libc::c_int as yytype_int8, + 98 as libc::c_int as yytype_int8, + 98 as libc::c_int as yytype_int8, + 98 as libc::c_int as yytype_int8, + 98 as libc::c_int as yytype_int8, +]; +#[no_mangle] +pub fn yy_input_name() -> *mut libc::c_char { + unsafe { + return (if !(bash_input.name).is_null() { + bash_input.name as *const libc::c_char + } else { + b"stdin\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + } +} +fn yy_getc() -> libc::c_int { + // 获å–终端一个字符 + unsafe { + return (Some((bash_input.getter).expect("non-null function pointer"))) + .expect("non-null function pointer")(); + } +} +fn yy_ungetc(mut c: libc::c_int) -> libc::c_int { + unsafe { + return (Some((bash_input.ungetter).expect("non-null function pointer"))) + .expect("non-null function pointer")(c); + } +} +static mut yyr2: [yytype_int8; 173] = [ + 0 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 10 as libc::c_int as yytype_int8, + 10 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 10 as libc::c_int as yytype_int8, + 10 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 9 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 7 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 6 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 5 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 0 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 4 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 1 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 2 as libc::c_int as yytype_int8, + 3 as libc::c_int as yytype_int8, +]; +#[no_mangle] +pub static mut current_readline_prompt: *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char; +#[no_mangle] +pub static mut current_readline_line: *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char; +#[no_mangle] +pub static mut current_readline_line_index: libc::c_int = 0 as libc::c_int; +fn yy_readline_get() -> libc::c_int { + // 读å–å‘½ä»¤è¡Œæ•°æ® + let mut old_sigint: Option = None; + let mut line_len: libc::c_int = 0; + let mut c: libc::c_uchar = 0; + unsafe { + if current_readline_line.is_null() { + if bash_readline_initialized == 0 as libc::c_int { + initialize_readline(); + } + if job_control != 0 { + give_terminal_to(shell_pgrp, 0 as libc::c_int); + } + old_sigint = ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps as fn() -> (), + )); + if signal_is_ignored(2 as libc::c_int) == 0 as libc::c_int { + old_sigint = set_signal_handler( + 2 as libc::c_int, + Some(sigint_sighandler as fn(libc::c_int) -> ()), + ); + } + sh_unset_nodelay_mode(fileno(rl_instream)); + current_readline_line = readline(if !current_readline_prompt.is_null() { + // 读å–终端字符 + current_readline_prompt as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }); + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if signal_is_ignored(2 as libc::c_int) == 0 as libc::c_int { + if old_sigint + != ::core::mem::transmute:: ()>, Option>(Some( + initialize_traps as fn() -> (), + )) + { + set_signal_handler(2 as libc::c_int, old_sigint); + } + } + if current_readline_line.is_null() { + return -(1 as libc::c_int); + } + current_readline_line_index = 0 as libc::c_int; + line_len = strlen(current_readline_line) as libc::c_int; + current_readline_line = realloc( + current_readline_line as *mut libc::c_void, + (2 as libc::c_int + line_len) as usize, + ) as *mut libc::c_char; + let fresh0 = line_len; + line_len = line_len + 1; + *current_readline_line.offset(fresh0 as isize) = '\n' as i32 as libc::c_char; + *current_readline_line.offset(line_len as isize) = '\0' as i32 as libc::c_char; + } + if *current_readline_line.offset(current_readline_line_index as isize) as libc::c_int + == 0 as libc::c_int + { + free(current_readline_line as *mut libc::c_void); + current_readline_line = 0 as *mut libc::c_void as *mut libc::c_char; + return yy_readline_get(); + } else { + let fresh1 = current_readline_line_index; + current_readline_line_index = current_readline_line_index + 1; + c = *current_readline_line.offset(fresh1 as isize) as libc::c_uchar; + return c as libc::c_int; + }; + } +} +fn yy_readline_unget(mut c: libc::c_int) -> libc::c_int { + unsafe { + if current_readline_line_index != 0 && !current_readline_line.is_null() { + current_readline_line_index -= 1; + *current_readline_line.offset(current_readline_line_index as isize) = c as libc::c_char; + } + + return c; + } +} +#[no_mangle] +pub fn with_input_from_stdin() { + unsafe { + let mut location: INPUT_STREAM = INPUT_STREAM { + file: 0 as *const FILE as *mut FILE, + }; + if bash_input.type_0 as libc::c_uint != st_stdin as libc::c_int as libc::c_uint + && stream_on_stack(st_stdin) == 0 as libc::c_int + { + location.string = current_readline_line; + init_yy_io( + Some(yy_readline_get as fn() -> libc::c_int), + ::core::mem::transmute:: libc::c_int>, Option>( + Some(::core::mem::transmute::< + fn(libc::c_int) -> libc::c_int, + fn() -> libc::c_int, + >(yy_readline_unget)), + ), + st_stdin as libc::c_int as libc::c_uint, + b"readline stdin\0" as *const u8 as *const libc::c_char, + location, + ); + } + } +} +#[no_mangle] +pub fn parser_will_prompt() -> libc::c_int { + unsafe { + return (current_readline_line.is_null() + || *current_readline_line.offset(current_readline_line_index as isize) as libc::c_int + == 0 as libc::c_int) as libc::c_int; + } +} +fn yy_string_get() -> libc::c_int { + unsafe { + let mut string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut c: libc::c_uchar = 0; + string = bash_input.location.string; + if !string.is_null() && *string as libc::c_int != 0 { + let fresh2 = string; + + string = string.offset(1); + + c = *fresh2 as libc::c_uchar; + bash_input.location.string = string; + return c as libc::c_int; + } else { + return -(1 as libc::c_int); + }; + } +} +fn yy_string_unget(mut c: libc::c_int) -> libc::c_int { + unsafe { + bash_input.location.string = (bash_input.location.string).offset(-1); + *bash_input.location.string = c as libc::c_char; + + return c; + } +} +#[no_mangle] +pub fn with_input_from_string(mut string: *mut libc::c_char, mut name: *const libc::c_char) { + unsafe { + let mut location: INPUT_STREAM = INPUT_STREAM { + file: 0 as *const FILE as *mut FILE, + }; + location.string = string; + init_yy_io( + Some(yy_string_get as fn() -> libc::c_int), + ::core::mem::transmute:: libc::c_int>, Option>(Some( + ::core::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + yy_string_unget, + ), + )), + st_string as libc::c_int as libc::c_uint, + name, + location, + ); + } +} +fn rewind_input_string() { + unsafe { + let mut xchars: libc::c_int = 0; + xchars = shell_input_line_len.wrapping_sub(shell_input_line_index) as libc::c_int; + if *(bash_input.location.string).offset(-(1 as libc::c_int) as isize) as libc::c_int + == '\n' as i32 + { + xchars += 1; + xchars; + } + bash_input.location.string = (bash_input.location.string).offset(-(xchars as isize)); + } +} +fn yydestruct( + mut yymsg: *const libc::c_char, + mut _yykind: yysymbol_kind_t, + mut _yyvaluep: *mut YYSTYPE, +) { + if yymsg.is_null() { + yymsg = b"Deleting\0" as *const u8 as *const libc::c_char; + } +} +fn yy_stream_get() -> libc::c_int { + unsafe { + let mut result: libc::c_int = 0; + result = -(1 as libc::c_int); + if !(bash_input.location.file).is_null() { + result = getc_with_restart(bash_input.location.file); + } + return result; + } +} +#[no_mangle] +pub static mut yychar: libc::c_int = 0; +#[no_mangle] +pub static mut yylval: YYSTYPE = YYSTYPE { + word: 0 as *const WORD_DESC as *mut WORD_DESC, +}; +#[no_mangle] +pub static mut yynerrs: libc::c_int = 0; +fn yy_stream_unget(mut c: libc::c_int) -> libc::c_int { + unsafe { + return ungetc_with_restart(c, bash_input.location.file); + } +} + +#[no_mangle] +pub fn yyparse() -> libc::c_int { + unsafe { + let mut current_block: u64; + let mut yystate: yy_state_fast_t = 0 as libc::c_int; + let mut yyerrstatus: libc::c_int = 0 as libc::c_int; + let mut yystacksize: libc::c_long = 200 as libc::c_int as libc::c_long; + let mut yyssa: [yy_state_t; 200] = [0; 200]; + let mut yyss: *mut yy_state_t = yyssa.as_mut_ptr(); + let mut yyssp: *mut yy_state_t = yyss; + let mut yyvsa: [YYSTYPE; 200] = [YYSTYPE { + word: 0 as *const WORD_DESC as *mut WORD_DESC, + }; 200]; + let mut yyvs: *mut YYSTYPE = yyvsa.as_mut_ptr(); + let mut yyvsp: *mut YYSTYPE = yyvs; + let mut yyn: libc::c_int = 0; + let mut yyresult: libc::c_int = 0; + let mut yytoken: yysymbol_kind_t = YYSYMBOL_YYEMPTY; + let mut yyval: YYSTYPE = YYSTYPE { + word: 0 as *const WORD_DESC as *mut WORD_DESC, + }; + let mut yylen: libc::c_int = 0 as libc::c_int; + yychar = -(2 as libc::c_int); + 's_46: loop { + (0 as libc::c_int != 0 && (0 as libc::c_int <= yystate && yystate < 346 as libc::c_int)) + as libc::c_int; + *yyssp = yystate as yy_state_t; + if yyss + .offset(yystacksize as isize) + .offset(-(1 as libc::c_int as isize)) + <= yyssp + { + let mut yysize: libc::c_long = + yyssp.offset_from(yyss) as libc::c_long + 1 as libc::c_int as libc::c_long; + if 10000 as libc::c_int as libc::c_long <= yystacksize { + current_block = 5105078013716444332; + break; + } + yystacksize *= 2 as libc::c_int as libc::c_long; + if (10000 as libc::c_int as libc::c_long) < yystacksize { + yystacksize = 10000 as libc::c_int as libc::c_long; + } + let mut yyss1: *mut yy_state_t = yyss; + let mut yyptr: *mut yyalloc = malloc( + (yystacksize + * (::core::mem::size_of::() as libc::c_ulong as libc::c_long + + ::core::mem::size_of::() as libc::c_ulong as libc::c_long) + + (::core::mem::size_of::() as libc::c_ulong as libc::c_long + - 1 as libc::c_int as libc::c_long)) as usize, + ) as *mut yyalloc; + if yyptr.is_null() { + current_block = 5105078013716444332; + break; + } else { + let mut yynewbytes: libc::c_long = 0; + libc::memcpy( + &mut (*yyptr).yyss_alloc as *mut yy_state_t as *mut libc::c_void, + yyss as *const libc::c_void, + (yysize as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::() as libc::c_ulong) + as libc::size_t, + ); + yyss = &mut (*yyptr).yyss_alloc; + yynewbytes = yystacksize + * ::core::mem::size_of::() as libc::c_ulong as libc::c_long + + (::core::mem::size_of::() as libc::c_ulong as libc::c_long + - 1 as libc::c_int as libc::c_long); + yyptr = yyptr.offset( + (yynewbytes + / ::core::mem::size_of::() as libc::c_ulong as libc::c_long) + as isize, + ); + let mut yynewbytes_0: libc::c_long = 0; + libc::memcpy( + &mut (*yyptr).yyvs_alloc as *mut YYSTYPE as *mut libc::c_void, + yyvs as *const libc::c_void, + (yysize as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::() as libc::c_ulong) + as libc::size_t, + ); + yyvs = &mut (*yyptr).yyvs_alloc; + yynewbytes_0 = yystacksize + * ::core::mem::size_of::() as libc::c_ulong as libc::c_long + + (::core::mem::size_of::() as libc::c_ulong as libc::c_long + - 1 as libc::c_int as libc::c_long); + yyptr = yyptr.offset( + (yynewbytes_0 + / ::core::mem::size_of::() as libc::c_ulong as libc::c_long) + as isize, + ); + if yyss1 != yyssa.as_mut_ptr() { + free(yyss1 as *mut libc::c_void); + } + yyssp = yyss + .offset(yysize as isize) + .offset(-(1 as libc::c_int as isize)); + yyvsp = yyvs + .offset(yysize as isize) + .offset(-(1 as libc::c_int as isize)); + if yyss + .offset(yystacksize as isize) + .offset(-(1 as libc::c_int as isize)) + <= yyssp + { + current_block = 12092114409115356139; + break; + } + } + } + if yystate == 118 as libc::c_int { + current_block = 4635604590554438705; + break; + } + yyn = yypact[yystate as usize] as libc::c_int; + if yyn == -(204 as libc::c_int) { + current_block = 13954386586367199081; + } else { + if yychar == -(2 as libc::c_int) { + yychar = yylex(); + } + if yychar <= 0 as libc::c_int { + yychar = 0 as libc::c_int; + yytoken = YYSYMBOL_YYEOF; + current_block = 6174974146017752131; + } else if yychar == 256 as libc::c_int { + yychar = 257 as libc::c_int; + yytoken = YYSYMBOL_YYerror; + current_block = 5467060717235750116; + } else { + yytoken = (if 0 as libc::c_int <= yychar && yychar <= 304 as libc::c_int { + yytranslate[yychar as usize] as yysymbol_kind_t as libc::c_int + } else { + YYSYMBOL_YYUNDEF as libc::c_int + }) as yysymbol_kind_t; + current_block = 6174974146017752131; + } + match current_block { + 5467060717235750116 => {} + _ => { + yyn += yytoken as libc::c_int; + if yyn < 0 as libc::c_int + || (661 as libc::c_int) < yyn + || yycheck[yyn as usize] as libc::c_int != yytoken as libc::c_int + { + current_block = 13954386586367199081; + } else { + yyn = yytable[yyn as usize] as libc::c_int; + if yyn <= 0 as libc::c_int { + yyn = -yyn; + current_block = 15246589712108891992; + } else { + if yyerrstatus != 0 { + yyerrstatus -= 1; + yyerrstatus; + } + yystate = yyn; + yyvsp = yyvsp.offset(1); + *yyvsp = yylval; + yychar = -(2 as libc::c_int); + current_block = 7425917188841100089; + } + } + } + } + } + match current_block { + 13954386586367199081 => { + yyn = yydefact[yystate as usize] as libc::c_int; + if yyn == 0 as libc::c_int { + yytoken = (if yychar == -(2 as libc::c_int) { + YYSYMBOL_YYEMPTY as libc::c_int + } else if 0 as libc::c_int <= yychar && yychar <= 304 as libc::c_int { + yytranslate[yychar as usize] as yysymbol_kind_t as libc::c_int + } else { + YYSYMBOL_YYUNDEF as libc::c_int + }) as yysymbol_kind_t; + if yyerrstatus == 0 { + yynerrs += 1; + yynerrs; + yyerror(b"syntax error\0" as *const u8 as *const libc::c_char); + } + if yyerrstatus == 3 as libc::c_int { + if yychar <= 0 as libc::c_int { + if yychar == 0 as libc::c_int { + current_block = 12092114409115356139; + break; + } + } else { + yydestruct( + b"Error: discarding\0" as *const u8 as *const libc::c_char, + yytoken, + &mut yylval, + ); + yychar = -(2 as libc::c_int); + } + } + current_block = 5467060717235750116; + } else { + current_block = 15246589712108891992; + } + } + _ => {} + } + match current_block { + 15246589712108891992 => { + yylen = yyr2[yyn as usize] as libc::c_int; + yyval = *yyvsp.offset((1 as libc::c_int - yylen) as isize); + match yyn { + 2 => { + global_command = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + eof_encountered = 0 as libc::c_int; + if parser_state & 0x40 as libc::c_int != 0 { + parser_state |= 0x8000 as libc::c_int; + } + current_block = 4635604590554438705; + break; + } + 3 => { + global_command = 0 as *mut libc::c_void as *mut COMMAND; + if parser_state & 0x40 as libc::c_int != 0 { + parser_state |= 0x8000 as libc::c_int; + } + current_block = 4635604590554438705; + break; + } + 4 => { + global_command = 0 as *mut libc::c_void as *mut COMMAND; + eof_encountered = 0 as libc::c_int; + if interactive != 0 && parse_and_execute_level == 0 as libc::c_int { + current_block = 4635604590554438705; + break; + } else { + current_block = 12092114409115356139; + break; + } + } + 5 => { + global_command = 0 as *mut libc::c_void as *mut COMMAND; + if last_command_exit_value == 0 as libc::c_int { + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 2 as libc::c_int, + ); + } + if interactive != 0 && parse_and_execute_level == 0 as libc::c_int { + current_block = 5793491756164225964; + break; + } else { + current_block = 12092114409115356139; + break; + } + } + 6 => { + global_command = 0 as *mut libc::c_void as *mut COMMAND; + handle_eof_input_unit(); + current_block = 4635604590554438705; + break; + } + 7 => { + yyval.WordList = make_word_list( + (*yyvsp.offset(0 as libc::c_int as isize)).word, + 0 as *mut libc::c_void as *mut WORD_LIST, + ); + current_block = 12964251834421583797; + } + 8 => { + yyval.WordList = make_word_list( + (*yyvsp.offset(0 as libc::c_int as isize)).word, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).WordList, + ); + current_block = 12964251834421583797; + } + 9 => { + source.dest = 1 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_output_direction, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 10 => { + source.dest = 0 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_input_direction, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 11 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_output_direction, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 12 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_input_direction, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 13 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_output_direction, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 14 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_input_direction, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 15 => { + source.dest = 1 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_appending_to, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 16 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_appending_to, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 17 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_appending_to, redir, 0x1 as libc::c_int); + current_block = 12964251834421583797; + } + 18 => { + source.dest = 1 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_output_force, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 19 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_output_force, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 20 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_output_force, redir, 0x1 as libc::c_int); + current_block = 12964251834421583797; + } + 21 => { + source.dest = 0 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_input_output, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 22 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_input_output, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 23 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_input_output, redir, 0x1 as libc::c_int); + current_block = 12964251834421583797; + } + 24 => { + source.dest = 0 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_reading_until, redir, 0 as libc::c_int); + push_heredoc(yyval.redirect); + current_block = 12964251834421583797; + } + 25 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_reading_until, redir, 0 as libc::c_int); + push_heredoc(yyval.redirect); + current_block = 12964251834421583797; + } + 26 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_reading_until, + redir, + 0x1 as libc::c_int, + ); + push_heredoc(yyval.redirect); + current_block = 12964251834421583797; + } + 27 => { + source.dest = 0 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_deblank_reading_until, + redir, + 0 as libc::c_int, + ); + push_heredoc(yyval.redirect); + current_block = 12964251834421583797; + } + 28 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_deblank_reading_until, + redir, + 0 as libc::c_int, + ); + push_heredoc(yyval.redirect); + current_block = 12964251834421583797; + } + 29 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_deblank_reading_until, + redir, + 0x1 as libc::c_int, + ); + push_heredoc(yyval.redirect); + current_block = 12964251834421583797; + } + 30 => { + source.dest = 0 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_reading_string, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 31 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_reading_string, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 32 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_reading_string, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 33 => { + source.dest = 0 as libc::c_int; + redir.dest = (*yyvsp.offset(0 as libc::c_int as isize)).number; + yyval.redirect = make_redirection( + source, + r_duplicating_input, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 34 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.dest = (*yyvsp.offset(0 as libc::c_int as isize)).number; + yyval.redirect = make_redirection( + source, + r_duplicating_input, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 35 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.dest = (*yyvsp.offset(0 as libc::c_int as isize)).number; + yyval.redirect = make_redirection( + source, + r_duplicating_input, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 36 => { + source.dest = 1 as libc::c_int; + redir.dest = (*yyvsp.offset(0 as libc::c_int as isize)).number; + yyval.redirect = make_redirection( + source, + r_duplicating_output, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 37 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.dest = (*yyvsp.offset(0 as libc::c_int as isize)).number; + yyval.redirect = make_redirection( + source, + r_duplicating_output, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 38 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.dest = (*yyvsp.offset(0 as libc::c_int as isize)).number; + yyval.redirect = make_redirection( + source, + r_duplicating_output, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 39 => { + source.dest = 0 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_duplicating_input_word, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 40 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_duplicating_input_word, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 41 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_duplicating_input_word, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 42 => { + source.dest = 1 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_duplicating_output_word, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 43 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_duplicating_output_word, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 44 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_duplicating_output_word, + redir, + 0x1 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 45 => { + source.dest = 1 as libc::c_int; + redir.dest = 0 as libc::c_int; + yyval.redirect = + make_redirection(source, r_close_this, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 46 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.dest = 0 as libc::c_int; + yyval.redirect = + make_redirection(source, r_close_this, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 47 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.dest = 0 as libc::c_int; + yyval.redirect = + make_redirection(source, r_close_this, redir, 0x1 as libc::c_int); + current_block = 12964251834421583797; + } + 48 => { + source.dest = 0 as libc::c_int; + redir.dest = 0 as libc::c_int; + yyval.redirect = + make_redirection(source, r_close_this, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 49 => { + source.dest = (*yyvsp.offset(-(2 as libc::c_int) as isize)).number; + redir.dest = 0 as libc::c_int; + yyval.redirect = + make_redirection(source, r_close_this, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 50 => { + source.filename = (*yyvsp.offset(-(2 as libc::c_int) as isize)).word; + redir.dest = 0 as libc::c_int; + yyval.redirect = + make_redirection(source, r_close_this, redir, 0x1 as libc::c_int); + current_block = 12964251834421583797; + } + 51 => { + source.dest = 1 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = + make_redirection(source, r_err_and_out, redir, 0 as libc::c_int); + current_block = 12964251834421583797; + } + 52 => { + source.dest = 1 as libc::c_int; + redir.filename = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.redirect = make_redirection( + source, + r_append_err_and_out, + redir, + 0 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 53 => { + yyval.element.word = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.element.redirect = 0 as *mut REDIRECT; + current_block = 12964251834421583797; + } + 54 => { + yyval.element.word = (*yyvsp.offset(0 as libc::c_int as isize)).word; + yyval.element.redirect = 0 as *mut REDIRECT; + current_block = 12964251834421583797; + } + 55 => { + yyval.element.redirect = + (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + yyval.element.word = 0 as *mut WORD_DESC; + current_block = 12964251834421583797; + } + 56 => { + yyval.redirect = (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + current_block = 12964251834421583797; + } + 57 => { + let mut t: *mut REDIRECT = 0 as *mut REDIRECT; + t = (*yyvsp.offset(-(1 as libc::c_int) as isize)).redirect; + while !((*t).next).is_null() { + t = (*t).next; + } + (*t).next = (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + yyval.redirect = (*yyvsp.offset(-(1 as libc::c_int) as isize)).redirect; + current_block = 12964251834421583797; + } + 58 => { + yyval.command = make_simple_command( + // 感觉有点问题 1008 + (*yyvsp.offset(0 as libc::c_int as isize)).element, + 0 as *mut libc::c_void as *mut COMMAND, + ); + current_block = 12964251834421583797; + } + 59 => { + yyval.command = make_simple_command( + (*yyvsp.offset(0 as libc::c_int as isize)).element, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + current_block = 12964251834421583797; + } + 60 => { + yyval.command = clean_simple_command( + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + current_block = 12964251834421583797; + } + 61 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 62 => { + let mut tc: *mut COMMAND = 0 as *mut COMMAND; + tc = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + if !tc.is_null() && !((*tc).redirects).is_null() { + let mut t_0: *mut REDIRECT = 0 as *mut REDIRECT; + t_0 = (*tc).redirects; + while !((*t_0).next).is_null() { + t_0 = (*t_0).next; + } + (*t_0).next = (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } else if !tc.is_null() { + (*tc).redirects = + (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } + yyval.command = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + current_block = 12964251834421583797; + } + 63 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 64 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 65 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 66 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 67 => { + yyval.command = make_while_command( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + current_block = 12964251834421583797; + } + 68 => { + yyval.command = make_until_command( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + current_block = 12964251834421583797; + } + 69 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 70 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 71 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 72 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 73 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 74 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 75 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 76 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 77 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 78 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 79 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 80 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(8 as libc::c_int) as isize)).word, + if !((*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .is_null() + && !((*(*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .next) + .is_null() + { + list_reverse( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + as *mut GENERIC_LIST, + ) as *mut WORD_LIST + } else { + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + }, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 81 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(8 as libc::c_int) as isize)).word, + if !((*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .is_null() + && !((*(*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .next) + .is_null() + { + list_reverse( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + as *mut GENERIC_LIST, + ) as *mut WORD_LIST + } else { + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + }, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 82 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(7 as libc::c_int) as isize)).word, + 0 as *mut libc::c_void as *mut WORD_LIST, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 83 => { + yyval.command = make_for_command( + (*yyvsp.offset(-(7 as libc::c_int) as isize)).word, + 0 as *mut libc::c_void as *mut WORD_LIST, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 84 => { + yyval.command = make_arith_for_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + arith_for_lineno, + ); + if (yyval.command).is_null() { + current_block = 15232662153667146846; + } else { + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + } + 85 => { + yyval.command = make_arith_for_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + arith_for_lineno, + ); + if (yyval.command).is_null() { + current_block = 15232662153667146846; + } else { + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + } + 86 => { + yyval.command = make_arith_for_command( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).WordList, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + arith_for_lineno, + ); + if (yyval.command).is_null() { + current_block = 15232662153667146846; + } else { + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + } + 87 => { + yyval.command = make_arith_for_command( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).WordList, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + arith_for_lineno, + ); + if (yyval.command).is_null() { + current_block = 15232662153667146846; + } else { + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + } + 88 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 89 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 90 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 91 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).word, + make_word_list( + make_word(b"\"$@\"\0" as *const u8 as *const libc::c_char), + 0 as *mut libc::c_void as *mut WORD_LIST, + ), + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 92 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(8 as libc::c_int) as isize)).word, + if !((*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .is_null() + && !((*(*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .next) + .is_null() + { + list_reverse( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + as *mut GENERIC_LIST, + ) as *mut WORD_LIST + } else { + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + }, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 93 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(8 as libc::c_int) as isize)).word, + if !((*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .is_null() + && !((*(*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList) + .next) + .is_null() + { + list_reverse( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + as *mut GENERIC_LIST, + ) as *mut WORD_LIST + } else { + (*yyvsp.offset(-(5 as libc::c_int) as isize)).WordList + }, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 94 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(7 as libc::c_int) as isize)).word, + 0 as *mut libc::c_void as *mut WORD_LIST, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 95 => { + yyval.command = make_select_command( + (*yyvsp.offset(-(7 as libc::c_int) as isize)).word, + 0 as *mut libc::c_void as *mut WORD_LIST, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 96 => { + yyval.command = make_case_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + 0 as *mut libc::c_void as *mut PATTERN_LIST, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 97 => { + yyval.command = make_case_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).word, + (*yyvsp.offset(-(2 as libc::c_int) as isize)).pattern, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 98 => { + yyval.command = make_case_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern, + word_lineno[word_top as usize], + ); + if word_top > 0 as libc::c_int { + word_top -= 1; + word_top; + } + current_block = 12964251834421583797; + } + 99 => { + yyval.command = make_function_def( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + function_dstart, + function_bstart, + ); + current_block = 12964251834421583797; + } + 100 => { + yyval.command = make_function_def( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).word, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + function_dstart, + function_bstart, + ); + current_block = 12964251834421583797; + } + 101 => { + yyval.command = make_function_def( + (*yyvsp.offset(-(1 as libc::c_int) as isize)).word, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + function_dstart, + function_bstart, + ); + current_block = 12964251834421583797; + } + 102 => { + yyval.command = make_function_def( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).word, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + function_dstart, + function_bstart, + ); + current_block = 12964251834421583797; + } + 103 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 104 => { + let mut tc_0: *mut COMMAND = 0 as *mut COMMAND; + tc_0 = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + if !tc_0.is_null() && !((*tc_0).redirects).is_null() { + let mut t_1: *mut REDIRECT = 0 as *mut REDIRECT; + t_1 = (*tc_0).redirects; + while !((*t_1).next).is_null() { + t_1 = (*t_1).next; + } + (*t_1).next = (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } else if !tc_0.is_null() { + (*tc_0).redirects = + (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } + yyval.command = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + current_block = 12964251834421583797; + } + 105 => { + yyval.command = make_subshell_command( + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + (*yyval.command).flags |= 0x1 as libc::c_int; + current_block = 12964251834421583797; + } + 106 => { + yyval.command = make_coproc_command( + b"COPROC\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + (*yyval.command).flags |= 0x1 as libc::c_int | 0x1000 as libc::c_int; + current_block = 12964251834421583797; + } + 107 => { + let mut tc_1: *mut COMMAND = 0 as *mut COMMAND; + tc_1 = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + if !tc_1.is_null() && !((*tc_1).redirects).is_null() { + let mut t_2: *mut REDIRECT = 0 as *mut REDIRECT; + t_2 = (*tc_1).redirects; + while !((*t_2).next).is_null() { + t_2 = (*t_2).next; + } + (*t_2).next = (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } else if !tc_1.is_null() { + (*tc_1).redirects = + (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } + yyval.command = make_coproc_command( + b"COPROC\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + (*yyval.command).flags |= 0x1 as libc::c_int | 0x1000 as libc::c_int; + current_block = 12964251834421583797; + } + 108 => { + yyval.command = make_coproc_command( + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).word).word, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + (*yyval.command).flags |= 0x1 as libc::c_int | 0x1000 as libc::c_int; + current_block = 12964251834421583797; + } + 109 => { + let mut tc_2: *mut COMMAND = 0 as *mut COMMAND; + tc_2 = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + if !tc_2.is_null() && !((*tc_2).redirects).is_null() { + let mut t_3: *mut REDIRECT = 0 as *mut REDIRECT; + t_3 = (*tc_2).redirects; + while !((*t_3).next).is_null() { + t_3 = (*t_3).next; + } + (*t_3).next = (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } else if !tc_2.is_null() { + (*tc_2).redirects = + (*yyvsp.offset(0 as libc::c_int as isize)).redirect; + } + yyval.command = make_coproc_command( + (*(*yyvsp.offset(-(2 as libc::c_int) as isize)).word).word, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + (*yyval.command).flags |= 0x1 as libc::c_int | 0x1000 as libc::c_int; + current_block = 12964251834421583797; + } + 110 => { + yyval.command = make_coproc_command( + b"COPROC\0" as *const u8 as *const libc::c_char + as *mut libc::c_char, + clean_simple_command( + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ), + ); + (*yyval.command).flags |= 0x1 as libc::c_int | 0x1000 as libc::c_int; + current_block = 12964251834421583797; + } + 111 => { + yyval.command = make_if_command( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + 0 as *mut libc::c_void as *mut COMMAND, + ); + current_block = 12964251834421583797; + } + 112 => { + yyval.command = make_if_command( + (*yyvsp.offset(-(5 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + current_block = 12964251834421583797; + } + 113 => { + yyval.command = make_if_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + current_block = 12964251834421583797; + } + 114 => { + yyval.command = make_group_command( + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + ); + current_block = 12964251834421583797; + } + 115 => { + yyval.command = make_arith_command( + (*yyvsp.offset(0 as libc::c_int as isize)).WordList, + ); + current_block = 12964251834421583797; + } + 116 => { + yyval.command = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + current_block = 12964251834421583797; + } + 117 => { + yyval.command = make_if_command( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + 0 as *mut libc::c_void as *mut COMMAND, + ); + current_block = 12964251834421583797; + } + 118 => { + yyval.command = make_if_command( + (*yyvsp.offset(-(4 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + current_block = 12964251834421583797; + } + 119 => { + yyval.command = make_if_command( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + current_block = 12964251834421583797; + } + 121 => { + let ref mut fresh3 = + (*(*yyvsp.offset(0 as libc::c_int as isize)).pattern).next; + *fresh3 = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + yyval.pattern = (*yyvsp.offset(0 as libc::c_int as isize)).pattern; + current_block = 12964251834421583797; + } + 122 => { + yyval.pattern = make_pattern_list( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).WordList, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + current_block = 12964251834421583797; + } + 123 => { + yyval.pattern = make_pattern_list( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).WordList, + 0 as *mut libc::c_void as *mut COMMAND, + ); + current_block = 12964251834421583797; + } + 124 => { + yyval.pattern = make_pattern_list( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).WordList, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ); + current_block = 12964251834421583797; + } + 125 => { + yyval.pattern = make_pattern_list( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).WordList, + 0 as *mut libc::c_void as *mut COMMAND, + ); + current_block = 12964251834421583797; + } + 126 => { + yyval.pattern = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + current_block = 12964251834421583797; + } + 127 => { + let ref mut fresh4 = + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).next; + *fresh4 = (*yyvsp.offset(-(2 as libc::c_int) as isize)).pattern; + yyval.pattern = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + current_block = 12964251834421583797; + } + 128 => { + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).flags |= + 0x1 as libc::c_int; + yyval.pattern = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + current_block = 12964251834421583797; + } + 129 => { + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).flags |= + 0x1 as libc::c_int; + let ref mut fresh5 = + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).next; + *fresh5 = (*yyvsp.offset(-(2 as libc::c_int) as isize)).pattern; + yyval.pattern = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + current_block = 12964251834421583797; + } + 130 => { + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).flags |= + 0x2 as libc::c_int; + yyval.pattern = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + current_block = 12964251834421583797; + } + 131 => { + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).flags |= + 0x2 as libc::c_int; + let ref mut fresh6 = + (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern).next; + *fresh6 = (*yyvsp.offset(-(2 as libc::c_int) as isize)).pattern; + yyval.pattern = (*yyvsp.offset(-(1 as libc::c_int) as isize)).pattern; + current_block = 12964251834421583797; + } + 132 => { + yyval.WordList = make_word_list( + (*yyvsp.offset(0 as libc::c_int as isize)).word, + 0 as *mut libc::c_void as *mut WORD_LIST, + ); + current_block = 12964251834421583797; + } + 133 => { + yyval.WordList = make_word_list( + (*yyvsp.offset(0 as libc::c_int as isize)).word, + (*yyvsp.offset(-(2 as libc::c_int) as isize)).WordList, + ); + current_block = 12964251834421583797; + } + 134 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + if need_here_doc != 0 { + gather_here_documents(); + } + current_block = 12964251834421583797; + } + 136 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 138 => { + if (*(*yyvsp.offset(-(2 as libc::c_int) as isize)).command).type_0 + as libc::c_uint + == cm_connection as libc::c_int as libc::c_uint + { + yyval.command = connect_async_list( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + 0 as *mut libc::c_void as *mut COMMAND, + '&' as i32, + ); + } else { + yyval.command = command_connect( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + 0 as *mut libc::c_void as *mut COMMAND, + '&' as i32, + ); + } + current_block = 12964251834421583797; + } + 140 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + 288 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 141 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + 289 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 142 => { + if (*(*yyvsp.offset(-(3 as libc::c_int) as isize)).command).type_0 + as libc::c_uint + == cm_connection as libc::c_int as libc::c_uint + { + yyval.command = connect_async_list( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + '&' as i32, + ); + } else { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + '&' as i32, + ); + } + current_block = 12964251834421583797; + } + 143 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ';' as i32, + ); + current_block = 12964251834421583797; + } + 144 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ';' as i32, + ); + current_block = 12964251834421583797; + } + 145 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 148 => { + yyval.number = '\n' as i32; + current_block = 12964251834421583797; + } + 149 => { + yyval.number = ';' as i32; + current_block = 12964251834421583797; + } + 150 => { + yyval.number = 304 as libc::c_int; + current_block = 12964251834421583797; + } + 153 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + if need_here_doc != 0 { + gather_here_documents(); + } + if parser_state & 0x40 as libc::c_int != 0 + && current_token == shell_eof_token + { + global_command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + eof_encountered = 0 as libc::c_int; + rewind_input_string(); + current_block = 4635604590554438705; + break; + } + current_block = 12964251834421583797; + } + 154 => { + if (*(*yyvsp.offset(-(1 as libc::c_int) as isize)).command).type_0 + as libc::c_uint + == cm_connection as libc::c_int as libc::c_uint + { + yyval.command = connect_async_list( + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + 0 as *mut libc::c_void as *mut COMMAND, + '&' as i32, + ); + } else { + yyval.command = command_connect( + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command, + 0 as *mut libc::c_void as *mut COMMAND, + '&' as i32, + ); + } + if need_here_doc != 0 { + gather_here_documents(); + } + if parser_state & 0x40 as libc::c_int != 0 + && current_token == shell_eof_token + { + global_command = + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + eof_encountered = 0 as libc::c_int; + rewind_input_string(); + current_block = 4635604590554438705; + break; + } + current_block = 12964251834421583797; + } + 155 => { + yyval.command = (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + if need_here_doc != 0 { + gather_here_documents(); + } + if parser_state & 0x40 as libc::c_int != 0 + && current_token == shell_eof_token + { + global_command = + (*yyvsp.offset(-(1 as libc::c_int) as isize)).command; + eof_encountered = 0 as libc::c_int; + rewind_input_string(); + current_block = 4635604590554438705; + break; + } + current_block = 12964251834421583797; + } + 156 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + 288 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 157 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + 289 as libc::c_int, + ); + current_block = 12964251834421583797; + } + 158 => { + if (*(*yyvsp.offset(-(2 as libc::c_int) as isize)).command).type_0 + as libc::c_uint + == cm_connection as libc::c_int as libc::c_uint + { + yyval.command = connect_async_list( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + '&' as i32, + ); + } else { + yyval.command = command_connect( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + '&' as i32, + ); + } + current_block = 12964251834421583797; + } + 159 => { + yyval.command = command_connect( + (*yyvsp.offset(-(2 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + ';' as i32, + ); + current_block = 12964251834421583797; + } + 160 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 161 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 162 => { + if !((*yyvsp.offset(0 as libc::c_int as isize)).command).is_null() { + (*(*yyvsp.offset(0 as libc::c_int as isize)).command).flags ^= + 0x4 as libc::c_int; + } + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 163 => { + if !((*yyvsp.offset(0 as libc::c_int as isize)).command).is_null() { + (*(*yyvsp.offset(0 as libc::c_int as isize)).command).flags |= + (*yyvsp.offset(-(1 as libc::c_int) as isize)).number; + } + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 164 => { + let mut x: ELEMENT = element { + word: 0 as *mut WORD_DESC, + redirect: 0 as *mut REDIRECT, + }; + x.word = 0 as *mut WORD_DESC; + x.redirect = 0 as *mut REDIRECT; + yyval.command = + make_simple_command(x, 0 as *mut libc::c_void as *mut COMMAND); + (*yyval.command).flags |= + (*yyvsp.offset(-(1 as libc::c_int) as isize)).number; + if (*yyvsp.offset(0 as libc::c_int as isize)).number == '\n' as i32 { + token_to_read = '\n' as i32; + } else if (*yyvsp.offset(0 as libc::c_int as isize)).number + == ';' as i32 + { + token_to_read = ';' as i32; + } + parser_state &= !(0x80000 as libc::c_int); + current_block = 12964251834421583797; + } + 165 => { + let mut x_0: ELEMENT = element { + word: 0 as *mut WORD_DESC, + redirect: 0 as *mut REDIRECT, + }; + x_0.word = 0 as *mut WORD_DESC; + x_0.redirect = 0 as *mut REDIRECT; + yyval.command = + make_simple_command(x_0, 0 as *mut libc::c_void as *mut COMMAND); + (*yyval.command).flags |= 0x4 as libc::c_int; + if (*yyvsp.offset(0 as libc::c_int as isize)).number == '\n' as i32 { + token_to_read = '\n' as i32; + } + if (*yyvsp.offset(0 as libc::c_int as isize)).number == ';' as i32 { + token_to_read = ';' as i32; + } + parser_state &= !(0x80000 as libc::c_int); + current_block = 12964251834421583797; + } + 166 => { + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + '|' as i32, + ); + current_block = 12964251834421583797; + } + 167 => { + let mut tc_3: *mut COMMAND = 0 as *mut COMMAND; + let mut rd: REDIRECTEE = REDIRECTEE { dest: 0 }; + let mut sd: REDIRECTEE = REDIRECTEE { dest: 0 }; + let mut r: *mut REDIRECT = 0 as *mut REDIRECT; + tc_3 = if (*(*yyvsp.offset(-(3 as libc::c_int) as isize)).command) + .type_0 as libc::c_uint + == cm_simple as libc::c_int as libc::c_uint + { + (*(*yyvsp.offset(-(3 as libc::c_int) as isize)).command) + .value + .Simple as *mut COMMAND + } else { + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command + }; + sd.dest = 2 as libc::c_int; + rd.dest = 1 as libc::c_int; + r = make_redirection(sd, r_duplicating_output, rd, 0 as libc::c_int); + if !((*tc_3).redirects).is_null() { + let mut t_4: *mut REDIRECT = 0 as *mut REDIRECT; + t_4 = (*tc_3).redirects; + while !((*t_4).next).is_null() { + t_4 = (*t_4).next; + } + (*t_4).next = r; + } else { + (*tc_3).redirects = r; + } + yyval.command = command_connect( + (*yyvsp.offset(-(3 as libc::c_int) as isize)).command, + (*yyvsp.offset(0 as libc::c_int as isize)).command, + '|' as i32, + ); + current_block = 12964251834421583797; + } + 168 => { + yyval.command = (*yyvsp.offset(0 as libc::c_int as isize)).command; + current_block = 12964251834421583797; + } + 169 => { + yyval.number = 0x80 as libc::c_int; + current_block = 12964251834421583797; + } + 170 => { + yyval.number = 0x80 as libc::c_int | 0x100 as libc::c_int; + current_block = 12964251834421583797; + } + 171 => { + yyval.number = 0x80 as libc::c_int | 0x100 as libc::c_int; + current_block = 12964251834421583797; + } + 172 => { + yyval.number = 0x80 as libc::c_int | 0x100 as libc::c_int; + current_block = 12964251834421583797; + } + _ => { + current_block = 12964251834421583797; + } + } + match current_block { + 12964251834421583797 => { + yyvsp = yyvsp.offset(-(yylen as isize)); + yyssp = yyssp.offset(-(yylen as isize)); + yylen = 0 as libc::c_int; + yyvsp = yyvsp.offset(1); + *yyvsp = yyval; + let yylhs: libc::c_int = + yyr1[yyn as usize] as libc::c_int - 61 as libc::c_int; + let yyi: libc::c_int = + yypgoto[yylhs as usize] as libc::c_int + *yyssp as libc::c_int; + yystate = if 0 as libc::c_int <= yyi + && yyi <= 661 as libc::c_int + && yycheck[yyi as usize] as libc::c_int == *yyssp as libc::c_int + { + yytable[yyi as usize] as libc::c_int + } else { + yydefgoto[yylhs as usize] as libc::c_int + }; + current_block = 7425917188841100089; + } + _ => { + yynerrs += 1; + yynerrs; + yyvsp = yyvsp.offset(-(yylen as isize)); + yyssp = yyssp.offset(-(yylen as isize)); + yylen = 0 as libc::c_int; + yystate = *yyssp as yy_state_fast_t; + current_block = 5467060717235750116; + } + } + } + _ => {} + } + match current_block { + 5467060717235750116 => { + yyerrstatus = 3 as libc::c_int; + loop { + yyn = yypact[yystate as usize] as libc::c_int; + if !(yyn == -(204 as libc::c_int)) { + yyn += YYSYMBOL_YYerror as libc::c_int; + if 0 as libc::c_int <= yyn + && yyn <= 661 as libc::c_int + && yycheck[yyn as usize] as libc::c_int + == YYSYMBOL_YYerror as libc::c_int + { + yyn = yytable[yyn as usize] as libc::c_int; + if (0 as libc::c_int) < yyn { + break; + } + } + } + if yyssp == yyss { + current_block = 12092114409115356139; + break 's_46; + } + yydestruct( + b"Error: popping\0" as *const u8 as *const libc::c_char, + yystos[yystate as usize] as yysymbol_kind_t, + yyvsp, + ); + yyvsp = yyvsp.offset(-(1 as libc::c_int as isize)); + yyssp = yyssp.offset(-(1 as libc::c_int as isize)); + yystate = *yyssp as yy_state_fast_t; + } + yyvsp = yyvsp.offset(1); + *yyvsp = yylval; + yystate = yyn; + } + _ => {} + } + yyssp = yyssp.offset(1); + yyssp; + } + match current_block { + 5105078013716444332 => { + yyerror(b"memory exhausted\0" as *const u8 as *const libc::c_char); + yyresult = 2 as libc::c_int; + current_block = 14803667992492250202; + } + 12092114409115356139 => { + yyresult = 1 as libc::c_int; + current_block = 14803667992492250202; + } + 5793491756164225964 => { + handle_eof_input_unit(); + current_block = 4635604590554438705; + } + _ => {} + } + match current_block { + 4635604590554438705 => { + yyresult = 0 as libc::c_int; + } + _ => {} + } + if yychar != -(2 as libc::c_int) { + yytoken = (if 0 as libc::c_int <= yychar && yychar <= 304 as libc::c_int { + yytranslate[yychar as usize] as yysymbol_kind_t as libc::c_int + } else { + YYSYMBOL_YYUNDEF as libc::c_int + }) as yysymbol_kind_t; + yydestruct( + b"Cleanup: discarding lookahead\0" as *const u8 as *const libc::c_char, + yytoken, + &mut yylval, + ); + } + yyvsp = yyvsp.offset(-(yylen as isize)); + yyssp = yyssp.offset(-(yylen as isize)); + while yyssp != yyss { + yydestruct( + b"Cleanup: popping\0" as *const u8 as *const libc::c_char, + yystos[*yyssp as libc::c_int as usize] as yysymbol_kind_t, + yyvsp, + ); + yyvsp = yyvsp.offset(-(1 as libc::c_int as isize)); + yyssp = yyssp.offset(-(1 as libc::c_int as isize)); + } + if yyss != yyssa.as_mut_ptr() { + free(yyss as *mut libc::c_void); + } + return yyresult; + } +} + +#[no_mangle] +pub fn with_input_from_stream(mut stream: *mut FILE, mut name: *const libc::c_char) { + unsafe { + let mut location: INPUT_STREAM = INPUT_STREAM { + file: 0 as *const FILE as *mut FILE, + }; + location.file = stream; + init_yy_io( + Some(yy_stream_get as fn() -> libc::c_int), + ::core::mem::transmute:: libc::c_int>, Option>(Some( + ::core::mem::transmute:: libc::c_int, fn() -> libc::c_int>( + yy_stream_unget, + ), + )), + st_stream as libc::c_int as libc::c_uint, + name, + location, + ); + } +} +#[no_mangle] +pub static mut line_number: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut line_number_base: libc::c_int = 0 as libc::c_int; +static mut cond_lineno: libc::c_int = 0; +static mut cond_token: libc::c_int = 0; +#[no_mangle] +pub static mut stream_list: *mut STREAM_SAVER = + 0 as *const libc::c_void as *mut libc::c_void as *mut STREAM_SAVER; +#[no_mangle] +pub fn push_stream(mut reset_lineno: libc::c_int) { + unsafe { + let mut saver: *mut STREAM_SAVER = + malloc(::core::mem::size_of::() as usize) as *mut STREAM_SAVER; + xbcopy( + &mut bash_input as *mut BASH_INPUT as *mut libc::c_char, + &mut (*saver).bash_input as *mut BASH_INPUT as *mut libc::c_char, + ::core::mem::size_of::() as libc::c_ulong as libc::c_int, + ); + (*saver).bstream = 0 as *mut libc::c_void as *mut BUFFERED_STREAM; + + if bash_input.type_0 as libc::c_uint == st_bstream as libc::c_int as libc::c_uint + && bash_input.location.buffered_fd >= 0 as libc::c_int + { + (*saver).bstream = set_buffered_stream( + bash_input.location.buffered_fd, + 0 as *mut libc::c_void as *mut BUFFERED_STREAM, + ); + } + (*saver).line = line_number; + bash_input.name = 0 as *mut libc::c_void as *mut libc::c_char; + (*saver).next = stream_list; + stream_list = saver; + EOF_Reached = 0 as libc::c_int; + if reset_lineno != 0 { + line_number = 0 as libc::c_int; + } + } +} +#[no_mangle] +pub fn pop_stream() { + unsafe { + if stream_list.is_null() { + EOF_Reached = 1 as libc::c_int; + } else { + let mut saver: *mut STREAM_SAVER = stream_list; + EOF_Reached = 0 as libc::c_int; + stream_list = (*stream_list).next; + init_yy_io( + (*saver).bash_input.getter, + (*saver).bash_input.ungetter, + (*saver).bash_input.type_0 as libc::c_uint, + (*saver).bash_input.name, + (*saver).bash_input.location, + ); + if bash_input.type_0 as libc::c_uint == st_bstream as libc::c_int as libc::c_uint + && bash_input.location.buffered_fd >= 0 as libc::c_int + { + if bash_input_fd_changed != 0 { + bash_input_fd_changed = 0 as libc::c_int; + if default_buffered_input >= 0 as libc::c_int { + bash_input.location.buffered_fd = default_buffered_input; + (*(*saver).bstream).b_fd = default_buffered_input; + fcntl(default_buffered_input, 2 as libc::c_int, 1 as libc::c_int); + } + } + set_buffered_stream(bash_input.location.buffered_fd, (*saver).bstream); + } + line_number = (*saver).line; + if !((*saver).bash_input.name).is_null() { + free((*saver).bash_input.name as *mut libc::c_void); + } + (*saver).bash_input.name = 0 as *mut libc::c_char; + free(saver as *mut libc::c_void); + }; + } +} +#[no_mangle] +pub fn stream_on_stack(mut type_0: stream_type) -> libc::c_int { + unsafe { + let mut s: *mut STREAM_SAVER = 0 as *mut STREAM_SAVER; + s = stream_list; + while !s.is_null() { + if (*s).bash_input.type_0 as libc::c_uint == type_0 as libc::c_uint { + return 1 as libc::c_int; + } + s = (*s).next; + } + return 0 as libc::c_int; + } +} +#[no_mangle] +pub fn save_token_state() -> *mut libc::c_int { + unsafe { + let mut ret: *mut libc::c_int = 0 as *mut libc::c_int; + + ret = malloc( + (4 as libc::c_int as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::() as libc::c_ulong) + as usize, + ) as *mut libc::c_int; + + *ret.offset(0 as libc::c_int as isize) = last_read_token; + *ret.offset(1 as libc::c_int as isize) = token_before_that; + *ret.offset(2 as libc::c_int as isize) = two_tokens_ago; + *ret.offset(3 as libc::c_int as isize) = current_token; + + return ret; + } +} +#[no_mangle] +pub fn restore_token_state(mut ts: *mut libc::c_int) { + unsafe { + if ts.is_null() { + return; + } + + last_read_token = *ts.offset(0 as libc::c_int as isize); + token_before_that = *ts.offset(1 as libc::c_int as isize); + two_tokens_ago = *ts.offset(2 as libc::c_int as isize); + current_token = *ts.offset(3 as libc::c_int as isize); + } +} +#[no_mangle] +pub static mut pushed_string_list: *mut STRING_SAVER = + 0 as *const libc::c_void as *mut libc::c_void as *mut STRING_SAVER; +fn push_string(mut s: *mut libc::c_char, mut expand: libc::c_int, mut ap: *mut alias_t) { + unsafe { + let mut temp: *mut STRING_SAVER = + malloc(::core::mem::size_of::() as usize) as *mut STRING_SAVER; + (*temp).expand_alias = expand; + (*temp).saved_line = shell_input_line; + (*temp).saved_line_size = shell_input_line_size; + (*temp).saved_line_index = shell_input_line_index; + (*temp).saved_line_terminator = shell_input_line_terminator; + (*temp).flags = 0 as libc::c_int; + (*temp).expander = ap; + if !ap.is_null() { + (*temp).flags = 0x1 as libc::c_int; + } + (*temp).next = pushed_string_list; + pushed_string_list = temp; + if !ap.is_null() { + (*ap).flags = ((*ap).flags as libc::c_int | 0x2 as libc::c_int) as libc::c_char; + } + shell_input_line = s; + shell_input_line_size = + if !s.is_null() && *s.offset(0 as libc::c_int as isize) as libc::c_int != 0 { + if *s.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *s.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(s) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + shell_input_line_index = 0 as libc::c_int as size_t; + shell_input_line_terminator = '\0' as i32; + set_line_mbstate(); + } +} +fn pop_string() { + unsafe { + let mut t: *mut STRING_SAVER = 0 as *mut STRING_SAVER; + + if !shell_input_line.is_null() { + free(shell_input_line as *mut libc::c_void); + } + shell_input_line = 0 as *mut libc::c_char; + shell_input_line = (*pushed_string_list).saved_line; + shell_input_line_index = (*pushed_string_list).saved_line_index; + shell_input_line_size = (*pushed_string_list).saved_line_size; + shell_input_line_terminator = (*pushed_string_list).saved_line_terminator; + if (*pushed_string_list).expand_alias != 0 { + parser_state |= 0x2 as libc::c_int; + } else { + parser_state &= !(0x2 as libc::c_int); + } + t = pushed_string_list; + pushed_string_list = (*pushed_string_list).next; + if !((*t).expander).is_null() { + (*(*t).expander).flags = + ((*(*t).expander).flags as libc::c_int & !(0x2 as libc::c_int)) as libc::c_char; + } + free(t as *mut libc::c_char as *mut libc::c_void); + + set_line_mbstate(); + } +} +fn free_string_list() { + unsafe { + let mut t: *mut STRING_SAVER = 0 as *mut STRING_SAVER; + let mut t1: *mut STRING_SAVER = 0 as *mut STRING_SAVER; + + t = pushed_string_list; + while !t.is_null() { + t1 = (*t).next; + if !((*t).saved_line).is_null() { + free((*t).saved_line as *mut libc::c_void); + } + (*t).saved_line = 0 as *mut libc::c_char; + if !((*t).expander).is_null() { + (*(*t).expander).flags = + ((*(*t).expander).flags as libc::c_int & !(0x2 as libc::c_int)) as libc::c_char; + } + free(t as *mut libc::c_char as *mut libc::c_void); + t = t1; + } + pushed_string_list = 0 as *mut libc::c_void as *mut STRING_SAVER; + } +} +#[no_mangle] +pub fn free_pushed_string_input() { + free_string_list(); +} +#[no_mangle] +pub fn parser_expanding_alias() -> libc::c_int { + unsafe { + return (!pushed_string_list.is_null() && !((*pushed_string_list).expander).is_null()) + as libc::c_int; + } +} +#[no_mangle] +pub fn parser_save_alias() { + unsafe { + push_string( + 0 as *mut libc::c_void as *mut libc::c_char, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut alias_t, + ); + (*pushed_string_list).flags = 0x4 as libc::c_int; + } +} +#[no_mangle] +pub fn parser_restore_alias() { + unsafe { + if !pushed_string_list.is_null() { + pop_string(); + } + } +} +#[no_mangle] +pub fn clear_string_list_expander(mut ap: *mut alias_t) { + unsafe { + let mut t: *mut STRING_SAVER = 0 as *mut STRING_SAVER; + + t = pushed_string_list; + while !t.is_null() { + if !((*t).expander).is_null() && (*t).expander == ap { + (*t).expander = 0 as *mut alias_t; + } + t = (*t).next; + } + } +} +#[no_mangle] +pub fn clear_shell_input_line() { + unsafe { + if !shell_input_line.is_null() { + shell_input_line_index = 0 as libc::c_int as size_t; + *shell_input_line.offset(shell_input_line_index as isize) = '\0' as i32 as libc::c_char; + } + } +} +fn read_a_line(mut remove_quoted_newline: libc::c_int) -> *mut libc::c_char { + unsafe { + static mut line_buffer: *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char; + static mut buffer_size: libc::c_int = 0 as libc::c_int; + let mut indx: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut peekc: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + + if no_line_editing != 0 + && (interactive != 0 + && (bash_input.type_0 as libc::c_uint == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint)) + { + print_prompt(); + } + indx = 0 as libc::c_int; + pass_next = indx; + loop { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + c = yy_getc(); + if c == 0 as libc::c_int { + continue; + } + if c == -(1 as libc::c_int) { + if interactive != 0 + && bash_input.type_0 as libc::c_uint == st_stream as libc::c_int as libc::c_uint + { + clearerr(stdin); + } + + if indx == 0 as libc::c_int { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + c = '\n' as i32; + } + + if indx + 2 as libc::c_int >= buffer_size { + while indx + 2 as libc::c_int >= buffer_size { + buffer_size += 128 as libc::c_int; + } + line_buffer = realloc(line_buffer as *mut libc::c_void, buffer_size as usize) + as *mut libc::c_char; + } + + if pass_next != 0 { + let fresh7 = indx; + indx = indx + 1; + *line_buffer.offset(fresh7 as isize) = c as libc::c_char; + pass_next = 0 as libc::c_int; + } else if c == '\\' as i32 && remove_quoted_newline != 0 { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + peekc = yy_getc(); + if peekc == '\n' as i32 { + line_number += 1; + line_number; + + continue; + } else { + yy_ungetc(peekc); + pass_next = 1 as libc::c_int; + let fresh8 = indx; + indx = indx + 1; + + *line_buffer.offset(fresh8 as isize) = c as libc::c_char; + } + } else { + if remove_quoted_newline != 0 && (c == '\u{1}' as i32 || c == '\u{7f}' as i32) { + let fresh9 = indx; + indx = indx + 1; + + *line_buffer.offset(fresh9 as isize) = '\u{1}' as i32 as libc::c_char; + } + let fresh10 = indx; + indx = indx + 1; + + *line_buffer.offset(fresh10 as isize) = c as libc::c_char; + } + if c == '\n' as i32 { + *line_buffer.offset(indx as isize) = '\0' as i32 as libc::c_char; + + return line_buffer; + } + } + } +} +#[no_mangle] +pub fn read_secondary_line(mut remove_quoted_newline: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut _n: libc::c_int = 0; + let mut _c: libc::c_int = 0; + prompt_string_pointer = &mut ps2_prompt; + if interactive != 0 + && (bash_input.type_0 as libc::c_uint == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint == st_stream as libc::c_int as libc::c_uint) + { + prompt_again(); + } + ret = read_a_line(remove_quoted_newline); + + if !ret.is_null() && remember_on_history != 0 && parser_state & 0x20000 as libc::c_int != 0 + { + current_command_line_count += 1; + current_command_line_count; + maybe_add_history(ret); + } + + return ret; + } +} +#[no_mangle] +pub static mut word_token_alist: [STRING_INT_ALIST; 23] = [ + { + let mut init = STRING_INT_ALIST { + word: b"if\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 258 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"then\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 259 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"else\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 260 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"elif\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 261 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"fi\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 262 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"case\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 263 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"esac\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 264 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"for\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 265 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"select\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 266 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"while\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 267 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"until\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 268 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"do\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 269 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"done\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 270 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"in\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 276 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"function\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 271 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"time\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 278 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"{\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '{' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"}\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '}' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"!\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 277 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"[[\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 273 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"]]\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 274 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"coproc\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 272 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + token: 0 as libc::c_int, + }; + init + }, +]; +#[no_mangle] +pub static mut other_token_alist: [STRING_INT_ALIST; 31] = [ + { + let mut init = STRING_INT_ALIST { + word: b"--\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 280 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"-p\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 279 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"&&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 288 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"||\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 289 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b">>\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 290 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"<<\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 291 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"<&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 292 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b">&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 294 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b";;\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 295 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b";&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 296 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b";;&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 297 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"<<-\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 298 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"<<<\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 293 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"&>\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 299 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"&>>\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 300 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"<>\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 301 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b">|\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 302 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"|&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 303 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"EOF\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: 304 as libc::c_int, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b">\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '>' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"<\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '<' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"-\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '-' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"{\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '{' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"}\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '}' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b";\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: ';' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"(\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '(' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b")\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: ')' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"|\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '|' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"&\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '&' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: b"newline\0" as *const u8 as *const libc::c_char as *mut libc::c_char, + token: '\n' as i32, + }; + init + }, + { + let mut init = STRING_INT_ALIST { + word: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + token: 0 as libc::c_int, + }; + init + }, +]; +#[no_mangle] +pub static mut dstack: dstack = { + let mut init = dstack { + delimiters: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + delimiter_depth: 0 as libc::c_int, + delimiter_space: 0 as libc::c_int, + }; + init +}; +static mut temp_dstack: dstack = { + let mut init = dstack { + delimiters: 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char, + delimiter_depth: 0 as libc::c_int, + delimiter_space: 0 as libc::c_int, + }; + init +}; +static mut eol_ungetc_lookahead: libc::c_int = 0 as libc::c_int; +static mut unquoted_backslash: libc::c_int = 0 as libc::c_int; +fn shell_getc(mut remove_quoted_newline: libc::c_int) -> libc::c_int { + // shell获å–字符 + unsafe { + let mut current_block: u64; + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut truncating: libc::c_int = 0; + let mut last_was_backslash: libc::c_int = 0; + let mut uc: libc::c_uchar = 0; + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + last_was_backslash = 0 as libc::c_int; + + if sigwinch_received != 0 { + ::core::ptr::write_volatile( + &mut sigwinch_received as *mut sig_atomic_t, + 0 as libc::c_int, + ); + get_new_window_size( + 0 as libc::c_int, + 0 as *mut libc::c_int, + 0 as *mut libc::c_int, + ); + } + + if eol_ungetc_lookahead != 0 { + c = eol_ungetc_lookahead; + eol_ungetc_lookahead = 0 as libc::c_int; + return c; + } + if shell_input_line.is_null() + || *shell_input_line.offset(shell_input_line_index as isize) == 0 + && pushed_string_list.is_null() + { + line_number += 1; + line_number; + if !shell_input_line.is_null() + && shell_input_line_size >= 32768 as libc::c_int as size_t + { + free(shell_input_line as *mut libc::c_void); + shell_input_line = 0 as *mut libc::c_char; + shell_input_line_size = 0 as libc::c_int as size_t; + } + current_block = 11101796020613380314; + } else { + current_block = 9354102534551541821; + } + + '_next_alias_char: loop { + match current_block { + 11101796020613380314 => { + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + truncating = 0 as libc::c_int; + i = truncating; + shell_input_line_terminator = 0 as libc::c_int; + if interactive_shell == 0 as libc::c_int + || interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint) + { + notify_and_cleanup(); + } + if no_line_editing != 0 + && (interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint)) + { + print_prompt(); + } + if bash_input.type_0 as libc::c_uint == st_stream as libc::c_int as libc::c_uint + { + clearerr(stdin); + } + loop { + c = yy_getc(); + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + if c == '\0' as i32 { + if !(bash_input.type_0 as libc::c_uint + == st_string as libc::c_int as libc::c_uint) + { + continue; + } + if i == 0 as libc::c_int { + shell_input_line_terminator = -(1 as libc::c_int); + } + *shell_input_line.offset(i as isize) = '\0' as i32 as libc::c_char; + c = -(1 as libc::c_int); + break; + } else { + if shell_input_line_size + > (18446744073709551615 as libc::c_ulong) + .wrapping_sub(256 as libc::c_int as libc::c_ulong) + { + let mut n: size_t = 0; + n = (18446744073709551615 as libc::c_ulong) + .wrapping_sub(i as libc::c_ulong); + if n <= 2 as libc::c_int as size_t { + if truncating == 0 as libc::c_int { + internal_warning( + dcgettext( + 0 as *const libc::c_char, + b"shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%lu): line truncated\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + shell_input_line_size, + 18446744073709551615 as libc::c_ulong, + ); + } + *shell_input_line.offset(i as isize) = + '\0' as i32 as libc::c_char; + truncating = 1 as libc::c_int; + } + if shell_input_line_size < 18446744073709551615 as libc::c_ulong { + shell_input_line_size = 18446744073709551615 as libc::c_ulong; + shell_input_line = realloc( + shell_input_line as *mut libc::c_void, + shell_input_line_size as usize, + ) + as *mut libc::c_char; + } + } else if (i + 2 as libc::c_int) as size_t >= shell_input_line_size { + while (i + 2 as libc::c_int) as size_t >= shell_input_line_size { + shell_input_line_size = shell_input_line_size + .wrapping_add(256 as libc::c_int as size_t); + } + shell_input_line = realloc( + shell_input_line as *mut libc::c_void, + shell_input_line_size as usize, + ) + as *mut libc::c_char; + } + if c == -(1 as libc::c_int) { + if bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint + { + clearerr(stdin); + } + if i == 0 as libc::c_int { + shell_input_line_terminator = -(1 as libc::c_int); + } + *shell_input_line.offset(i as isize) = '\0' as i32 as libc::c_char; + break; + } else { + if truncating == 0 as libc::c_int || c == '\n' as i32 { + let fresh11 = i; + i = i + 1; + *shell_input_line.offset(fresh11 as isize) = c as libc::c_char; + } + if c == '\n' as i32 { + i -= 1; + *shell_input_line.offset(i as isize) = + '\0' as i32 as libc::c_char; + current_command_line_count += 1; + current_command_line_count; + break; + } else { + last_was_backslash = (last_was_backslash == 0 as libc::c_int + && c == '\\' as i32) + as libc::c_int; + } + } + } + } + shell_input_line_index = 0 as libc::c_int as size_t; + shell_input_line_len = i as size_t; + set_line_mbstate(); + if remember_on_history != 0 + && !shell_input_line.is_null() + && *shell_input_line.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + let mut expansions: *mut libc::c_char = 0 as *mut libc::c_char; + if (if dstack.delimiter_depth != 0 { + *(dstack.delimiters) + .offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + }) == '\'' as i32 + { + history_quoting_state = '\'' as i32; + } else if (if dstack.delimiter_depth != 0 { + *(dstack.delimiters) + .offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + }) == '"' as i32 + { + history_quoting_state = '"' as i32; + } else { + history_quoting_state = 0 as libc::c_int; + } + expansions = + pre_process_line(shell_input_line, 1 as libc::c_int, 1 as libc::c_int); + history_quoting_state = 0 as libc::c_int; + if expansions != shell_input_line { + free(shell_input_line as *mut libc::c_void); + shell_input_line = expansions; + shell_input_line_len = if !shell_input_line.is_null() { + strlen(shell_input_line) as u64 + } else { + 0 as libc::c_int as libc::c_ulong + }; + if shell_input_line_len == 0 as libc::c_int as size_t { + current_command_line_count -= 1; + current_command_line_count; + } + shell_input_line_size = shell_input_line_len; + set_line_mbstate(); + } + } else if remember_on_history != 0 + && !shell_input_line.is_null() + && *shell_input_line.offset(0 as libc::c_int as isize) as libc::c_int + == '\0' as i32 + && current_command_line_count > 1 as libc::c_int + { + if if dstack.delimiter_depth != 0 { + *(dstack.delimiters) + .offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + } != 0 + { + maybe_add_history(shell_input_line); + } else { + let mut hdcs: *mut libc::c_char = 0 as *mut libc::c_char; + hdcs = history_delimiting_chars(shell_input_line); + if !hdcs.is_null() + && *hdcs.offset(0 as libc::c_int as isize) as libc::c_int + == ';' as i32 + { + maybe_add_history(shell_input_line); + } + } + } + if !shell_input_line.is_null() { + if echo_input_at_read != 0 + && (*shell_input_line.offset(0 as libc::c_int as isize) as libc::c_int + != 0 + || shell_input_line_terminator != -(1 as libc::c_int)) + && shell_eof_token == 0 as libc::c_int + { + fprintf( + stderr, + b"%s\n\0" as *const u8 as *const libc::c_char, + shell_input_line, + ); + } + if shell_input_line_terminator != -(1 as libc::c_int) { + if shell_input_line_size + < (18446744073709551615 as libc::c_ulong) + .wrapping_sub(3 as libc::c_int as libc::c_ulong) + && shell_input_line_len.wrapping_add(3 as libc::c_int as size_t) + > shell_input_line_size + { + shell_input_line_size = + shell_input_line_size.wrapping_add(2 as libc::c_int as size_t); + shell_input_line = realloc( + shell_input_line as *mut libc::c_void, + (1 as libc::c_int as size_t).wrapping_add(shell_input_line_size) + as usize, + ) + as *mut libc::c_char; + } + if bash_input.type_0 as libc::c_uint + == st_string as libc::c_int as libc::c_uint + && (!pushed_string_list.is_null() + && !((*pushed_string_list).expander).is_null()) + as libc::c_int + == 0 as libc::c_int + && last_was_backslash != 0 + && c == -(1 as libc::c_int) + && remove_quoted_newline != 0 + { + *shell_input_line.offset(shell_input_line_len as isize) = + '\\' as i32 as libc::c_char; + } else { + *shell_input_line.offset(shell_input_line_len as isize) = + '\n' as i32 as libc::c_char; + } + *shell_input_line.offset( + shell_input_line_len.wrapping_add(1 as libc::c_int as size_t) + as isize, + ) = '\0' as i32 as libc::c_char; + if shell_input_line_len.wrapping_add(2 as libc::c_int as size_t) + > shell_input_line_propsize + { + shell_input_line_propsize = + shell_input_line_len.wrapping_add(2 as libc::c_int as size_t); + shell_input_line_property = realloc( + shell_input_line_property as *mut libc::c_void, + shell_input_line_propsize as usize, + ) + as *mut libc::c_char; + } + *shell_input_line_property.offset(shell_input_line_len as isize) = + 1 as libc::c_int as libc::c_char; + } + current_block = 9354102534551541821; + } else { + shell_input_line_size = 0 as libc::c_int as size_t; + prompt_string_pointer = &mut current_prompt_string; + if interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint) + { + prompt_again(); + } + current_block = 11101796020613380314; + } + } + _ => { + if shell_input_line_index == 0 as libc::c_int as size_t { + unquoted_backslash = 0 as libc::c_int; + } + uc = *shell_input_line.offset(shell_input_line_index as isize) as libc::c_uchar; + if uc != 0 { + unquoted_backslash = (unquoted_backslash == 0 as libc::c_int + && uc as libc::c_int == '\\' as i32) + as libc::c_int; + shell_input_line_index = shell_input_line_index.wrapping_add(1); + shell_input_line_index; + } + if uc as libc::c_int == 0 as libc::c_int + && !pushed_string_list.is_null() + && (*pushed_string_list).flags != 0x4 as libc::c_int + && (*pushed_string_list).flags != 0x2 as libc::c_int + && parser_state & 0x100000 as libc::c_int == 0 as libc::c_int + && parser_state & 0x200000 as libc::c_int == 0 as libc::c_int + && shell_input_line_index > 0 as libc::c_int as size_t + && *sh_syntaxtab.as_mut_ptr().offset(*shell_input_line.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_uchar + as isize) + & 0x2000 as libc::c_int + == 0 as libc::c_int + && *shell_input_line.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + != '\n' as i32 + && unquoted_backslash == 0 as libc::c_int + && *sh_syntaxtab.as_mut_ptr().offset(*shell_input_line.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_uchar + as isize) + & 0x1 as libc::c_int + == 0 as libc::c_int + && ((if dstack.delimiter_depth != 0 { + *(dstack.delimiters) + .offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + }) != '\'' as i32 + && (if dstack.delimiter_depth != 0 { + *(dstack.delimiters) + .offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + }) != '"' as i32) + { + parser_state |= 0x200000 as libc::c_int; + return ' ' as i32; + } + loop { + if uc as libc::c_int == 0 as libc::c_int + && !pushed_string_list.is_null() + && (*pushed_string_list).flags != 0x4 as libc::c_int + { + parser_state &= !(0x200000 as libc::c_int); + pop_string(); + uc = *shell_input_line.offset(shell_input_line_index as isize) + as libc::c_uchar; + if uc != 0 { + shell_input_line_index = shell_input_line_index.wrapping_add(1); + shell_input_line_index; + } + } + if uc as libc::c_int == '\\' as i32 + && remove_quoted_newline != 0 + && *shell_input_line.offset(shell_input_line_index as isize) + as libc::c_int + == '\n' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint) + { + prompt_again(); + } + line_number += 1; + line_number; + if !pushed_string_list.is_null() + && !((*pushed_string_list).expander).is_null() + && *shell_input_line.offset( + shell_input_line_index.wrapping_add(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + == '\0' as i32 + { + uc = 0 as libc::c_int as libc::c_uchar; + } else { + if !(!pushed_string_list.is_null() + && !((*pushed_string_list).expander).is_null() + && *shell_input_line.offset( + shell_input_line_index + .wrapping_add(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + != '\0' as i32) + { + current_block = 11101796020613380314; + break; + } + shell_input_line_index = shell_input_line_index.wrapping_add(1); + shell_input_line_index; + current_block = 9354102534551541821; + break; + } + } else { + if uc as libc::c_int == 0 as libc::c_int + && shell_input_line_terminator == -(1 as libc::c_int) + { + return if shell_input_line_index != 0 as libc::c_int as size_t { + '\n' as i32 + } else { + -(1 as libc::c_int) + }; + } + if !(uc as libc::c_int == 0 as libc::c_int + && bash_input.type_0 as libc::c_uint + == st_string as libc::c_int as libc::c_uint + && *bash_input.location.string as libc::c_int != 0 + && !pushed_string_list.is_null() + && (*pushed_string_list).flags == 0x4 as libc::c_int + && shell_input_line_terminator == 0 as libc::c_int) + { + break '_next_alias_char; + } + shell_input_line_index = 0 as libc::c_int as size_t; + current_block = 11101796020613380314; + break; + } + } + } + } + } + + return uc as libc::c_int; + } +} +fn shell_ungetc(mut c: libc::c_int) { + unsafe { + if !shell_input_line.is_null() && shell_input_line_index != 0 { + shell_input_line_index = shell_input_line_index.wrapping_sub(1); + *shell_input_line.offset(shell_input_line_index as isize) = c as libc::c_char; + } else { + eol_ungetc_lookahead = c; + }; + } +} +#[no_mangle] +pub fn parser_remaining_input() -> *mut libc::c_char { + unsafe { + if shell_input_line.is_null() { + return 0 as *mut libc::c_char; + } + if (shell_input_line_index as libc::c_int) < 0 as libc::c_int + || shell_input_line_index >= shell_input_line_len + { + return b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + return shell_input_line.offset(shell_input_line_index as isize); + } +} +fn discard_until(mut character: libc::c_int) { + let mut c: libc::c_int = 0; + loop { + c = shell_getc(0 as libc::c_int); + if !(c != -(1 as libc::c_int) && c != character) { + break; + } + } + if c != -(1 as libc::c_int) { + shell_ungetc(c); + } +} +#[no_mangle] +pub fn execute_variable_command(mut command: *mut libc::c_char, mut vname: *mut libc::c_char) { + unsafe { + let mut last_lastarg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ps: sh_parser_state_t = _sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + save_parser_state(&mut ps); + last_lastarg = get_string_value(b"_\0" as *const u8 as *const libc::c_char); + if !last_lastarg.is_null() { + last_lastarg = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(last_lastarg) as u64) + as usize, + ) as *mut libc::c_char, + last_lastarg, + ); + } + + parse_and_execute( + strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(command) as u64) + as usize, + ) as *mut libc::c_char, + command, + ), + vname, + 0x1 as libc::c_int | 0x4 as libc::c_int, + ); + + restore_parser_state(&mut ps); + bind_variable( + b"_\0" as *const u8 as *const libc::c_char, + last_lastarg, + 0 as libc::c_int, + ); + + if !last_lastarg.is_null() { + free(last_lastarg as *mut libc::c_void); + } + last_lastarg = 0 as *mut libc::c_char; + if token_to_read == '\n' as i32 { + token_to_read = 0 as libc::c_int; + } + } +} +#[no_mangle] +pub fn push_token(mut x: libc::c_int) { + unsafe { + two_tokens_ago = token_before_that; + token_before_that = last_read_token; + last_read_token = current_token; + current_token = x; + } +} +static mut token: *mut libc::c_char = + 0 as *const libc::c_void as *mut libc::c_void as *mut libc::c_char; +static mut token_buffer_size: libc::c_int = 0; +fn yylex() -> libc::c_int { + unsafe { + if interactive != 0 && (current_token == 0 as libc::c_int || current_token == '\n' as i32) { + if (prompt_string_pointer.is_null() + || prompt_string_pointer == &mut ps1_prompt as *mut *mut libc::c_char) + && parse_and_execute_level == 0 as libc::c_int + && time_to_check_mail() != 0 + { + check_mail(); + reset_mail_timer(); + } + if token_to_read == 0 as libc::c_int + && (interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint)) + { + prompt_again(); + } + } + two_tokens_ago = token_before_that; + token_before_that = last_read_token; + last_read_token = current_token; + current_token = read_token(0 as libc::c_int); + if parser_state & 0x8000 as libc::c_int != 0 && current_token == shell_eof_token { + current_token = 304 as libc::c_int; + if bash_input.type_0 as libc::c_uint == st_string as libc::c_int as libc::c_uint { + rewind_input_string(); + } + } + parser_state &= !(0x8000 as libc::c_int); + return current_token; + } +} +static mut esacs_needed_count: libc::c_int = 0; +static mut expecting_in_token: libc::c_int = 0; +fn push_heredoc(mut r: *mut REDIRECT) { + unsafe { + if need_here_doc >= 16 as libc::c_int { + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + 2 as libc::c_int, + ); + need_here_doc = 0 as libc::c_int; + report_syntax_error(dcgettext( + 0 as *const libc::c_char, + b"maximum here-document count exceeded\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + )); + reset_parser(); + exit_shell(last_command_exit_value); + } + + let fresh12 = need_here_doc; + need_here_doc = need_here_doc + 1; + redir_stack[fresh12 as usize] = r; + } +} +#[no_mangle] +pub fn gather_here_documents() { + unsafe { + let mut r: libc::c_int = 0; + r = 0 as libc::c_int; + + here_doc_first_line = 1 as libc::c_int; + while need_here_doc > 0 as libc::c_int { + parser_state |= 0x20000 as libc::c_int; + let fresh13 = r; + r = r + 1; + make_here_document(redir_stack[fresh13 as usize], line_number); + parser_state &= !(0x20000 as libc::c_int); + need_here_doc -= 1; + need_here_doc; + redir_stack[(r - 1 as libc::c_int) as usize] = 0 as *mut REDIRECT; + } + here_doc_first_line = 0 as libc::c_int; + } +} +static mut open_brace_count: libc::c_int = 0; +fn mk_alexpansion(mut s: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut l: libc::c_int = 0; + let mut r: *mut libc::c_char = 0 as *mut libc::c_char; + + l = strlen(s) as libc::c_int; + r = malloc((l + 2 as libc::c_int) as usize) as *mut libc::c_char; + strcpy(r, s); + + *r.offset(l as isize) = '\0' as i32 as libc::c_char; + + return r; + } +} +fn alias_expand_token(mut tokstr: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut expanded: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ap: *mut alias_t = 0 as *mut alias_t; + if (parser_state & 0x2 as libc::c_int != 0 + || (last_read_token == 282 as libc::c_int + || parser_state & 0x80000 as libc::c_int != 0 + && (last_read_token == '<' as i32 + || last_read_token == '>' as i32 + || last_read_token == 290 as libc::c_int + || last_read_token == 302 as libc::c_int + || last_read_token == 301 as libc::c_int + || last_read_token == 298 as libc::c_int + || last_read_token == 291 as libc::c_int + || last_read_token == 293 as libc::c_int + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int + || last_read_token == 299 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + || last_read_token != 295 as libc::c_int + && last_read_token != 296 as libc::c_int + && last_read_token != 297 as libc::c_int + && reserved_word_acceptable(last_read_token) != 0)) + && parser_state & 0x1 as libc::c_int == 0 as libc::c_int + { + ap = find_alias(tokstr); + if !ap.is_null() && (*ap).flags as libc::c_int & 0x2 as libc::c_int != 0 { + return -(100 as libc::c_int); + } + expanded = if !ap.is_null() { + mk_alexpansion((*ap).value) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if !expanded.is_null() { + push_string( + expanded, + (*ap).flags as libc::c_int & 0x1 as libc::c_int, + ap, + ); + return -(99 as libc::c_int); + } else { + return -(100 as libc::c_int); + } + } + return -(100 as libc::c_int); + } +} +fn time_command_acceptable() -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + + if posixly_correct != 0 && shell_compatibility_level > 41 as libc::c_int { + i = shell_input_line_index as libc::c_int; + while (i as size_t) < shell_input_line_len + && (*shell_input_line.offset(i as isize) as libc::c_int == ' ' as i32 + || *shell_input_line.offset(i as isize) as libc::c_int == '\t' as i32) + { + i += 1; + i; + } + if *shell_input_line.offset(i as isize) as libc::c_int == '-' as i32 { + return 0 as libc::c_int; + } + } + + match last_read_token { + 0 | 59 | 10 => { + if token_before_that == '|' as i32 { + return 0 as libc::c_int; + } + } + 288 | 289 | 38 | 267 | 269 | 268 | 258 | 259 | 261 | 260 | 123 | 40 | 41 | 277 + | 278 | 279 | 280 => {} + _ => return 0 as libc::c_int, + } + return 1 as libc::c_int; + } +} +fn special_case_tokens(mut tokstr: *mut libc::c_char) -> libc::c_int { + unsafe { + if last_read_token == 281 as libc::c_int + && (token_before_that == 265 as libc::c_int + || token_before_that == 263 as libc::c_int + || token_before_that == 266 as libc::c_int) + && (*tokstr.offset(0 as libc::c_int as isize) as libc::c_int == 'i' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == 'n' as i32 + && *tokstr.offset(2 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int) + { + if token_before_that == 263 as libc::c_int { + parser_state |= 0x1 as libc::c_int; + esacs_needed_count += 1; + esacs_needed_count; + } + if expecting_in_token != 0 { + expecting_in_token -= 1; + expecting_in_token; + } + return 276 as libc::c_int; + } + + if expecting_in_token != 0 + && (last_read_token == 281 as libc::c_int || last_read_token == '\n' as i32) + && (*tokstr.offset(0 as libc::c_int as isize) as libc::c_int == 'i' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == 'n' as i32 + && *tokstr.offset(2 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int) + { + if parser_state & 0x80 as libc::c_int != 0 { + parser_state |= 0x1 as libc::c_int; + esacs_needed_count += 1; + esacs_needed_count; + } + expecting_in_token -= 1; + expecting_in_token; + return 276 as libc::c_int; + } else if expecting_in_token != 0 + && (last_read_token == '\n' as i32 || last_read_token == ';' as i32) + && (*tokstr.offset(0 as libc::c_int as isize) as libc::c_int == 'd' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == 'o' as i32 + && *tokstr.offset(2 as libc::c_int as isize) as libc::c_int == '\0' as i32) + { + expecting_in_token -= 1; + expecting_in_token; + return 269 as libc::c_int; + } + if last_read_token == 281 as libc::c_int + && (token_before_that == 265 as libc::c_int || token_before_that == 266 as libc::c_int) + && (*tokstr.offset(0 as libc::c_int as isize) as libc::c_int == 'd' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == 'o' as i32 + && *tokstr.offset(2 as libc::c_int as isize) as libc::c_int == '\0' as i32) + { + if expecting_in_token != 0 { + expecting_in_token -= 1; + expecting_in_token; + } + return 269 as libc::c_int; + } + if esacs_needed_count != 0 { + if last_read_token == 276 as libc::c_int + && (*tokstr.offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"esac\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp(tokstr, b"esac\0" as *const u8 as *const libc::c_char) + == 0 as libc::c_int) + { + esacs_needed_count -= 1; + esacs_needed_count; + parser_state &= !(0x1 as libc::c_int); + return 264 as libc::c_int; + } + } + if parser_state & 0x4 as libc::c_int != 0 { + parser_state &= !(0x4 as libc::c_int); + if *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == '{' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + open_brace_count += 1; + open_brace_count; + function_bstart = line_number; + return '{' as i32; + } + } + + if last_read_token == 286 as libc::c_int + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == 'd' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == 'o' as i32 + && *tokstr.offset(2 as libc::c_int as isize) == 0 + { + return 269 as libc::c_int; + } + if last_read_token == 286 as libc::c_int + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == '{' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + open_brace_count += 1; + open_brace_count; + + return '{' as i32; + } + if open_brace_count != 0 + && reserved_word_acceptable(last_read_token) != 0 + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == '}' as i32 + && *tokstr.offset(1 as libc::c_int as isize) == 0 + { + open_brace_count -= 1; + open_brace_count; + + return '}' as i32; + } + if last_read_token == 278 as libc::c_int + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == 'p' as i32 + && *tokstr.offset(2 as libc::c_int as isize) == 0 + { + return 279 as libc::c_int; + } + if last_read_token == 278 as libc::c_int + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *tokstr.offset(2 as libc::c_int as isize) == 0 + { + return 280 as libc::c_int; + } + if last_read_token == 279 as libc::c_int + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *tokstr.offset(2 as libc::c_int as isize) == 0 + { + return 280 as libc::c_int; + } + if parser_state & 0x200 as libc::c_int != 0 + && *tokstr.offset(0 as libc::c_int as isize) as libc::c_int == ']' as i32 + && *tokstr.offset(1 as libc::c_int as isize) as libc::c_int == ']' as i32 + && *tokstr.offset(2 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + return 274 as libc::c_int; + } + return -(1 as libc::c_int); + } +} +#[no_mangle] +pub fn reset_parser() { + unsafe { + dstack.delimiter_depth = 0 as libc::c_int; + open_brace_count = 0 as libc::c_int; + if parser_state & 0x1000 as libc::c_int != 0 { + extended_glob = global_extglob; + } + parser_state = 0 as libc::c_int; + here_doc_first_line = 0 as libc::c_int; + if !pushed_string_list.is_null() { + free_string_list(); + } + if !shell_input_line.is_null() { + free(shell_input_line as *mut libc::c_void); + shell_input_line = 0 as *mut libc::c_void as *mut libc::c_char; + shell_input_line_index = 0 as libc::c_int as size_t; + shell_input_line_size = shell_input_line_index; + } + if !word_desc_to_read.is_null() { + free(word_desc_to_read as *mut libc::c_void); + } + word_desc_to_read = 0 as *mut WORD_DESC; + word_desc_to_read = 0 as *mut libc::c_void as *mut WORD_DESC; + eol_ungetc_lookahead = 0 as libc::c_int; + current_token = '\n' as i32; + last_read_token = '\n' as i32; + token_to_read = '\n' as i32; + } +} +#[no_mangle] +pub fn reset_readahead_token() { + unsafe { + if token_to_read == '\n' as i32 { + token_to_read = 0 as libc::c_int; + } + } +} +fn read_token(mut command: libc::c_int) -> libc::c_int { + unsafe { + let mut character: libc::c_int = 0; + let mut peek_char: libc::c_int = 0; + let mut result: libc::c_int = 0; + if command == 1 as libc::c_int { + reset_parser(); + return '\n' as i32; + } + + if token_to_read != 0 { + result = token_to_read; + if token_to_read == 281 as libc::c_int || token_to_read == 282 as libc::c_int { + yylval.word = word_desc_to_read; + word_desc_to_read = 0 as *mut libc::c_void as *mut WORD_DESC; + } + token_to_read = 0 as libc::c_int; + return result; + } + if parser_state & (0x100 as libc::c_int | 0x200 as libc::c_int) == 0x100 as libc::c_int { + cond_lineno = line_number; + parser_state |= 0x200 as libc::c_int; + yylval.command = parse_cond_command(); + if cond_token != 274 as libc::c_int { + cond_error(); + return -(1 as libc::c_int); + } + token_to_read = 274 as libc::c_int; + parser_state &= !(0x200 as libc::c_int | 0x100 as libc::c_int); + return 287 as libc::c_int; + } + + loop { + loop { + character = shell_getc(1 as libc::c_int); + if !(character != -(1 as libc::c_int) + && *sh_syntaxtab + .as_mut_ptr() + .offset(character as libc::c_uchar as isize) + & 0x2000 as libc::c_int + != 0) + { + break; + } + } + if character == -(1 as libc::c_int) { + EOF_Reached = 1 as libc::c_int; + return 304 as libc::c_int; + } + if character == '\0' as i32 + && bash_input.type_0 as libc::c_uint == st_string as libc::c_int as libc::c_uint + && (!pushed_string_list.is_null() && !((*pushed_string_list).expander).is_null()) + as libc::c_int + == 0 as libc::c_int + { + EOF_Reached = 1 as libc::c_int; + return 304 as libc::c_int; + } + if character == '#' as i32 + && (interactive == 0 || interactive_comments != 0) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + parser_state |= 0x100000 as libc::c_int; + discard_until('\n' as i32); + shell_getc(0 as libc::c_int); + parser_state &= !(0x100000 as libc::c_int); + character = '\n' as i32; + } + if character == '\n' as i32 { + if need_here_doc != 0 { + gather_here_documents(); + } + + parser_state &= !(0x2 as libc::c_int); + parser_state &= !(0x4000 as libc::c_int); + + return character; + } + if !(parser_state & 0x10000 as libc::c_int != 0) { + if *sh_syntaxtab + .as_mut_ptr() + .offset(character as libc::c_uchar as isize) + & 0x1 as libc::c_int + != 0 + && parser_state & 0x10 as libc::c_int == 0 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if character == '<' as i32 || character == '>' as i32 { + parser_state &= !(0x2 as libc::c_int); + } + parser_state &= !(0x4000 as libc::c_int); + if parser_state & 0x40 as libc::c_int != 0 && character == shell_eof_token { + peek_char = shell_getc(0 as libc::c_int); + } else { + peek_char = shell_getc(1 as libc::c_int); + } + if character == peek_char { + match character { + 60 => { + peek_char = shell_getc(1 as libc::c_int); + if peek_char == '-' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 298 as libc::c_int; + } else if peek_char == '<' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 293 as libc::c_int; + } else { + shell_ungetc(peek_char); + return 291 as libc::c_int; + } + } + 62 => return 290 as libc::c_int, + 59 => { + parser_state |= 0x1 as libc::c_int; + parser_state &= !(0x2 as libc::c_int); + + peek_char = shell_getc(1 as libc::c_int); + if peek_char == '&' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 297 as libc::c_int; + } else { + shell_ungetc(peek_char); + return 295 as libc::c_int; + } + } + 38 => return 288 as libc::c_int, + 124 => return 289 as libc::c_int, + 40 => { + result = parse_dparen(character); + if !(result == -(2 as libc::c_int)) { + return result; + } + } + _ => {} + } + } else if character == '<' as i32 + && peek_char == '&' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 292 as libc::c_int; + } else if character == '>' as i32 + && peek_char == '&' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 294 as libc::c_int; + } else if character == '<' as i32 + && peek_char == '>' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 301 as libc::c_int; + } else if character == '>' as i32 + && peek_char == '|' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 302 as libc::c_int; + } else if character == '&' as i32 + && peek_char == '>' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + peek_char = shell_getc(1 as libc::c_int); + if peek_char == '>' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 300 as libc::c_int; + } else { + shell_ungetc(peek_char); + return 299 as libc::c_int; + } + } else if character == '|' as i32 + && peek_char == '&' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return 303 as libc::c_int; + } else if character == ';' as i32 + && peek_char == '&' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + parser_state |= 0x1 as libc::c_int; + parser_state &= !(0x2 as libc::c_int); + return 296 as libc::c_int; + } + shell_ungetc(peek_char); + if character == ')' as i32 + && last_read_token == '(' as i32 + && token_before_that == 281 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + parser_state |= 0x4 as libc::c_int; + parser_state &= !(0x2 as libc::c_int); + function_dstart = line_number; + } + if character == '(' as i32 + && parser_state & 0x1 as libc::c_int == 0 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + parser_state |= 0x20 as libc::c_int; + } else if parser_state & 0x1 as libc::c_int != 0 + && character == ')' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + parser_state &= !(0x1 as libc::c_int); + } else if parser_state & 0x20 as libc::c_int != 0 + && character == ')' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + parser_state &= !(0x20 as libc::c_int); + } + if (character != '>' as i32 && character != '<' as i32 + || peek_char != '(' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return character; + } + } + if character == '-' as i32 + && (last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + return character; + } + } + result = read_token_word(character); + if !(result == -(99 as libc::c_int)) { + break; + } + } + return result; + } +} +static mut matched_pair_error: libc::c_char = 0; +fn parse_matched_pair( + mut qc: libc::c_int, + mut open: libc::c_int, + mut close: libc::c_int, + mut lenp: *mut libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut current_block: u64; + let mut count: libc::c_int = 0; + let mut ch: libc::c_int = 0; + let mut prevch: libc::c_int = 0; + let mut tflags: libc::c_int = 0; + let mut nestlen: libc::c_int = 0; + let mut ttranslen: libc::c_int = 0; + let mut start_lineno: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nestret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ttrans: *mut libc::c_char = 0 as *mut libc::c_char; + let mut retind: libc::c_int = 0; + let mut retsize: libc::c_int = 0; + let mut rflags: libc::c_int = 0; + let mut dolbrace_state: libc::c_int = 0; + dolbrace_state = if flags & 0x40 as libc::c_int != 0 { + 0x1 as libc::c_int + } else { + 0 as libc::c_int + }; + count = 1 as libc::c_int; + tflags = 0 as libc::c_int; + if flags & 0x8 as libc::c_int != 0 + && qc != '`' as i32 + && qc != '\'' as i32 + && qc != '"' as i32 + && flags & 0x4 as libc::c_int == 0 as libc::c_int + { + tflags |= 0x2 as libc::c_int; + } + rflags = if qc == '"' as i32 { + 0x4 as libc::c_int + } else { + flags & 0x4 as libc::c_int + }; + retsize = 64 as libc::c_int; + ret = malloc(retsize as usize) as *mut libc::c_char; + retind = 0 as libc::c_int; + start_lineno = line_number; + ch = -(1 as libc::c_int); + while count != 0 { + prevch = ch; + ch = shell_getc( + (qc != '\'' as i32 && tflags & 0x8 as libc::c_int == 0 as libc::c_int) + as libc::c_int, + ); + if ch == -(1 as libc::c_int) { + free(ret as *mut libc::c_void); + + parser_error( + start_lineno, + dcgettext( + 0 as *const libc::c_char, + b"unexpected EOF while looking for matching `%c'\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + close, + ); + EOF_Reached = 1 as libc::c_int; + return &mut matched_pair_error; + } + if ch == '\n' as i32 + && (interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint)) + { + prompt_again(); + } + if tflags & 0x4 as libc::c_int != 0 { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) as *mut libc::c_char; + } + + let fresh14 = retind; + retind = retind + 1; + *ret.offset(fresh14 as isize) = ch as libc::c_char; + + if ch == '\n' as i32 { + tflags &= !(0x4 as libc::c_int); + } + } else { + if tflags & 0x2 as libc::c_int != 0 + && tflags & 0x4 as libc::c_int == 0 as libc::c_int + && ch == '#' as i32 + && (retind == 0 as libc::c_int + || *ret.offset((retind - 1 as libc::c_int) as isize) as libc::c_int + == '\n' as i32 + || *sh_syntaxtab + .as_mut_ptr() + .offset(*ret.offset((retind - 1 as libc::c_int) as isize) + as libc::c_uchar as isize) + & 0x2000 as libc::c_int + != 0) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x4 as libc::c_int; + } + if tflags & 0x8 as libc::c_int != 0 { + tflags &= !(0x8 as libc::c_int); + if qc != '\'' as i32 && ch == '\n' as i32 { + if retind > 0 as libc::c_int { + retind -= 1; + retind; + } + } else { + if retind + 2 as libc::c_int >= retsize { + while retind + 2 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + if ch == '\u{1}' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + let fresh15 = retind; + retind = retind + 1; + *ret.offset(fresh15 as isize) = '\u{1}' as i32 as libc::c_char; + } + + let fresh16 = retind; + retind = retind + 1; + *ret.offset(fresh16 as isize) = ch as libc::c_char; + } + } else if parser_state & 0x40000 as libc::c_int != 0 + && open == '\'' as i32 + && (ch == '\u{1}' as i32 || ch == '\u{7f}' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh17 = retind; + retind = retind + 1; + *ret.offset(fresh17 as isize) = ch as libc::c_char; + } else if (ch == '\u{1}' as i32 || ch == '\u{7f}' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 2 as libc::c_int >= retsize { + while retind + 2 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh18 = retind; + retind = retind + 1; + *ret.offset(fresh18 as isize) = '\u{1}' as i32 as libc::c_char; + let fresh19 = retind; + retind = retind + 1; + *ret.offset(fresh19 as isize) = ch as libc::c_char; + } else { + if ch == close + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + count -= 1; + count; + } else if open != close + && tflags & 0x1 as libc::c_int != 0 + && open == '{' as i32 + && ch == open + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + count += 1; + count; + } else if flags & 0x1 as libc::c_int == 0 as libc::c_int + && ch == open + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + count += 1; + count; + } + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh20 = retind; + retind = retind + 1; + *ret.offset(fresh20 as isize) = ch as libc::c_char; + + if count == 0 as libc::c_int { + break; + } + if open == '\'' as i32 { + if flags & 0x2 as libc::c_int != 0 + && ch == '\\' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x8 as libc::c_int; + } + } else { + if ch == '\\' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x8 as libc::c_int; + } + if flags & 0x40 as libc::c_int != 0 { + if dolbrace_state == 0x1 as libc::c_int + && ch == '%' as i32 + && retind > 1 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && ch == '#' as i32 + && retind > 1 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && ch == '/' as i32 + && retind > 1 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x80 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && ch == '^' as i32 + && retind > 1 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && ch == ',' as i32 + && retind > 1 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x40 as libc::c_int; + } else if dolbrace_state == 0x1 as libc::c_int + && !(strchr( + b"#%^,~:-=?+/\0" as *const u8 as *const libc::c_char, + ch, + )) + .is_null() + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x2 as libc::c_int; + } else if dolbrace_state == 0x2 as libc::c_int + && (strchr( + b"#%^,~:-=?+/\0" as *const u8 as *const libc::c_char, + ch, + )) + .is_null() + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + dolbrace_state = 0x4 as libc::c_int; + } + } + if posixly_correct != 0 + && shell_compatibility_level > 41 as libc::c_int + && dolbrace_state != 0x40 as libc::c_int + && dolbrace_state != 0x80 as libc::c_int + && flags & 0x4 as libc::c_int != 0 + && flags & 0x40 as libc::c_int != 0 + && ch == '\'' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + continue; + } + if open != close { + if *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x8 as libc::c_int + != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if dstack.delimiter_depth + 2 as libc::c_int + > dstack.delimiter_space + { + dstack.delimiter_space += 10 as libc::c_int; + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::() + as libc::c_ulong) + as usize, + ) + as *mut libc::c_char; + } + *(dstack.delimiters).offset(dstack.delimiter_depth as isize) = + ch as libc::c_char; + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + if tflags & 0x1 as libc::c_int != 0 + && ch == '\'' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + nestret = parse_matched_pair( + ch, + ch, + ch, + &mut nestlen, + 0x2 as libc::c_int | rflags, + ); + } else { + nestret = parse_matched_pair(ch, ch, ch, &mut nestlen, rflags); + } + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + if nestret == &mut matched_pair_error as *mut libc::c_char { + free(ret as *mut libc::c_void); + return &mut matched_pair_error; + } + if tflags & 0x1 as libc::c_int != 0 + && ch == '\'' as i32 + && (extended_quote != 0 + || rflags & 0x4 as libc::c_int == 0 as libc::c_int) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + ttrans = ansiexpand( + nestret, + 0 as libc::c_int, + nestlen - 1 as libc::c_int, + &mut ttranslen, + ); + free(nestret as *mut libc::c_void); + if shell_compatibility_level > 42 as libc::c_int + && rflags & 0x4 as libc::c_int != 0 + && dolbrace_state == 0x80 as libc::c_int + && flags & 0x40 as libc::c_int != 0 + { + nestret = sh_single_quote(ttrans); + free(ttrans as *mut libc::c_void); + nestlen = strlen(nestret) as libc::c_int; + } else if rflags & 0x4 as libc::c_int == 0 as libc::c_int { + nestret = sh_single_quote(ttrans); + free(ttrans as *mut libc::c_void); + nestlen = strlen(nestret) as libc::c_int; + } else { + nestret = ttrans; + nestlen = ttranslen; + } + retind -= 2 as libc::c_int; + } else if tflags & 0x1 as libc::c_int != 0 + && ch == '"' as i32 + && (extended_quote != 0 + || rflags & 0x4 as libc::c_int == 0 as libc::c_int) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + ttrans = localeexpand( + nestret, + 0 as libc::c_int, + nestlen - 1 as libc::c_int, + start_lineno, + &mut ttranslen, + ); + free(nestret as *mut libc::c_void); + nestret = + sh_mkdoublequoted(ttrans, ttranslen, 0 as libc::c_int); + free(ttrans as *mut libc::c_void); + nestlen = ttranslen + 2 as libc::c_int; + retind -= 2 as libc::c_int; + } + if nestlen != 0 { + if retind + nestlen >= retsize { + while retind + nestlen >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + strcpy(ret.offset(retind as isize), nestret); + retind += nestlen; + } + if !nestret.is_null() { + free(nestret as *mut libc::c_void); + } + nestret = 0 as *mut libc::c_char; + current_block = 16813369756331276724; + } else if flags & (0x20 as libc::c_int | 0x40 as libc::c_int) != 0 + && tflags & 0x1 as libc::c_int != 0 + && (ch == '(' as i32 || ch == '{' as i32 || ch == '[' as i32) + { + current_block = 11507125668437329568; + } else if flags & (0x20 as libc::c_int | 0x40 as libc::c_int) != 0 + && tflags & 0x1000 as libc::c_int != 0 + && ch == '(' as i32 + { + current_block = 11507125668437329568; + } else { + current_block = 16813369756331276724; + } + } else if open == '"' as i32 + && ch == '`' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + nestret = parse_matched_pair( + 0 as libc::c_int, + '`' as i32, + '`' as i32, + &mut nestlen, + rflags, + ); + if nestret == &mut matched_pair_error as *mut libc::c_char { + free(ret as *mut libc::c_void); + return &mut matched_pair_error; + } + if nestlen != 0 { + if retind + nestlen >= retsize { + while retind + nestlen >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + strcpy(ret.offset(retind as isize), nestret); + retind += nestlen; + } + if !nestret.is_null() { + free(nestret as *mut libc::c_void); + } + nestret = 0 as *mut libc::c_char; + current_block = 16813369756331276724; + } else if open != '`' as i32 + && tflags & 0x1 as libc::c_int != 0 + && (ch == '(' as i32 || ch == '{' as i32 || ch == '[' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + current_block = 11507125668437329568; + } else { + current_block = 16813369756331276724; + } + match current_block { + 11507125668437329568 => { + if open == ch { + count -= 1; + count; + } + if ch == '(' as i32 { + nestret = parse_comsub( + 0 as libc::c_int, + '(' as i32, + ')' as i32, + &mut nestlen, + (rflags | 0x8 as libc::c_int) & !(0x4 as libc::c_int), + ); + } else if ch == '{' as i32 { + nestret = parse_matched_pair( + 0 as libc::c_int, + '{' as i32, + '}' as i32, + &mut nestlen, + 0x1 as libc::c_int | 0x40 as libc::c_int | rflags, + ); + } else if ch == '[' as i32 { + nestret = parse_matched_pair( + 0 as libc::c_int, + '[' as i32, + ']' as i32, + &mut nestlen, + rflags, + ); + } + if nestret == &mut matched_pair_error as *mut libc::c_char { + free(ret as *mut libc::c_void); + return &mut matched_pair_error; + } + if nestlen != 0 { + if retind + nestlen >= retsize { + while retind + nestlen >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + strcpy(ret.offset(retind as isize), nestret); + retind += nestlen; + } + if !nestret.is_null() { + free(nestret as *mut libc::c_void); + } + nestret = 0 as *mut libc::c_char; + } + _ => {} + } + if (ch == '<' as i32 || ch == '>' as i32) + && tflags & 0x1000 as libc::c_int == 0 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x1000 as libc::c_int; + } else { + tflags &= !(0x1000 as libc::c_int); + } + if ch == '$' as i32 + && tflags & 0x1 as libc::c_int == 0 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x1 as libc::c_int; + } else { + tflags &= !(0x1 as libc::c_int); + } + } + } + } + } + + *ret.offset(retind as isize) = '\0' as i32 as libc::c_char; + + if !lenp.is_null() { + *lenp = retind; + } + return ret; + } +} +fn parse_comsub( + mut qc: libc::c_int, + mut open: libc::c_int, + mut close: libc::c_int, + mut lenp: *mut libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut current_block: u64; + let mut count: libc::c_int = 0; + let mut ch: libc::c_int = 0; + let mut peekc: libc::c_int = 0; + let mut tflags: libc::c_int = 0; + let mut lex_rwlen: libc::c_int = 0; + let mut lex_wlen: libc::c_int = 0; + let mut lex_firstind: libc::c_int = 0; + let mut nestlen: libc::c_int = 0; + let mut ttranslen: libc::c_int = 0; + let mut start_lineno: libc::c_int = 0; + let mut orig_histexp: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut nestret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ttrans: *mut libc::c_char = 0 as *mut libc::c_char; + let mut heredelim: *mut libc::c_char = 0 as *mut libc::c_char; + let mut retind: libc::c_int = 0; + let mut retsize: libc::c_int = 0; + let mut rflags: libc::c_int = 0; + let mut hdlen: libc::c_int = 0; + peekc = shell_getc(0 as libc::c_int); + shell_ungetc(peekc); + if peekc == '(' as i32 { + return parse_matched_pair(qc, open, close, lenp, 0 as libc::c_int); + } + count = 1 as libc::c_int; + tflags = 0x10 as libc::c_int; + orig_histexp = history_expansion_inhibited; + if flags & 0x8 as libc::c_int != 0 + && qc != '\'' as i32 + && qc != '"' as i32 + && flags & 0x4 as libc::c_int == 0 as libc::c_int + { + tflags |= 0x20 as libc::c_int; + } + if tflags & 0x20 as libc::c_int != 0 + && (interactive == 0 as libc::c_int || interactive_comments != 0) + { + tflags |= 0x2 as libc::c_int; + } + rflags = flags & 0x4 as libc::c_int; + retsize = 64 as libc::c_int; + ret = malloc(retsize as usize) as *mut libc::c_char; + retind = 0 as libc::c_int; + start_lineno = line_number; + lex_wlen = 0 as libc::c_int; + lex_rwlen = lex_wlen; + heredelim = 0 as *mut libc::c_char; + lex_firstind = -(1 as libc::c_int); + while count != 0 { + ch = shell_getc( + (qc != '\'' as i32 + && tflags & (0x4 as libc::c_int | 0x8 as libc::c_int | 0x400 as libc::c_int) + == 0 as libc::c_int) as libc::c_int, + ); + if !(ch == -(1 as libc::c_int)) { + if ch == '\n' as i32 { + if tflags & 0x100 as libc::c_int != 0 && !heredelim.is_null() { + tflags &= !(0x100 as libc::c_int); + tflags |= 0x80 as libc::c_int; + history_expansion_inhibited = 1 as libc::c_int; + lex_firstind = retind + 1 as libc::c_int; + } else if tflags & 0x80 as libc::c_int != 0 { + let mut tind: libc::c_int = 0; + tind = lex_firstind; + while tflags & 0x200 as libc::c_int != 0 + && *ret.offset(tind as isize) as libc::c_int == '\t' as i32 + { + tind += 1; + tind; + } + if retind - tind == hdlen + && (if hdlen == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret.offset(tind as isize).offset(0 as libc::c_int as isize) + as libc::c_int + == *heredelim.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp( + ret.offset(tind as isize), + heredelim, + hdlen as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + { + tflags &= !(0x200 as libc::c_int + | 0x80 as libc::c_int + | 0x400 as libc::c_int); + free(heredelim as *mut libc::c_void); + heredelim = 0 as *mut libc::c_char; + lex_firstind = -(1 as libc::c_int); + history_expansion_inhibited = orig_histexp; + } else { + lex_firstind = retind + 1 as libc::c_int; + } + } + } + if ch == '\n' as i32 + && (interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint)) + { + prompt_again(); + } + if tflags & 0x80 as libc::c_int != 0 && ch == close && count == 1 as libc::c_int { + let mut tind_0: libc::c_int = 0; + tind_0 = lex_firstind; + while tflags & 0x200 as libc::c_int != 0 + && *ret.offset(tind_0 as isize) as libc::c_int == '\t' as i32 + { + tind_0 += 1; + tind_0; + } + if retind - tind_0 == hdlen + && (if hdlen == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(tind_0 as isize) + .offset(0 as libc::c_int as isize) + as libc::c_int + == *heredelim.offset(0 as libc::c_int as isize) as libc::c_int + && strncmp(ret.offset(tind_0 as isize), heredelim, hdlen as usize) + == 0 as libc::c_int) as libc::c_int + }) != 0 + { + tflags &= + !(0x200 as libc::c_int | 0x80 as libc::c_int | 0x400 as libc::c_int); + free(heredelim as *mut libc::c_void); + heredelim = 0 as *mut libc::c_char; + lex_firstind = -(1 as libc::c_int); + history_expansion_inhibited = orig_histexp; + } + } + if tflags & (0x4 as libc::c_int | 0x80 as libc::c_int) != 0 { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh21 = retind; + retind = retind + 1; + *ret.offset(fresh21 as isize) = ch as libc::c_char; + + if tflags & 0x4 as libc::c_int != 0 && ch == '\n' as i32 { + tflags &= !(0x4 as libc::c_int); + } + continue; + } else if tflags & 0x8 as libc::c_int != 0 { + tflags &= !(0x8 as libc::c_int); + if qc != '\'' as i32 && ch == '\n' as i32 { + if retind > 0 as libc::c_int { + retind -= 1; + retind; + } + continue; + } else { + if retind + 2 as libc::c_int >= retsize { + while retind + 2 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + if ch == '\u{1}' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + let fresh22 = retind; + retind = retind + 1; + *ret.offset(fresh22 as isize) = '\u{1}' as i32 as libc::c_char; + } + + let fresh23 = retind; + retind = retind + 1; + *ret.offset(fresh23 as isize) = ch as libc::c_char; + + continue; + } + } else { + if *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x2 as libc::c_int + != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags &= !(0x800 as libc::c_int); + } else if tflags & 0x800 as libc::c_int != 0 { + lex_wlen += 1; + lex_wlen; + } else { + tflags |= 0x800 as libc::c_int; + lex_wlen = 0 as libc::c_int; + if tflags & 0x10 as libc::c_int != 0 { + lex_rwlen = 0 as libc::c_int; + } + } + if *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x2000 as libc::c_int + != 0 + && tflags & 0x100 as libc::c_int == 0 as libc::c_int + && lex_rwlen == 0 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh24 = retind; + retind = retind + 1; + *ret.offset(fresh24 as isize) = ch as libc::c_char; + + continue; + } else { + if tflags & 0x100 as libc::c_int != 0 { + if lex_firstind == -(1 as libc::c_int) + && *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x2 as libc::c_int + == 0 as libc::c_int + { + lex_firstind = retind; + } else if lex_firstind >= 0 as libc::c_int + && tflags & 0x8 as libc::c_int == 0 as libc::c_int + && *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x2 as libc::c_int + != 0 + { + if heredelim.is_null() { + nestret = substring(ret, lex_firstind, retind); + heredelim = string_quote_removal(nestret, 0 as libc::c_int); + hdlen = (if !heredelim.is_null() + && *heredelim.offset(0 as libc::c_int as isize) + as libc::c_int + != 0 + { + if *heredelim.offset(1 as libc::c_int as isize) + as libc::c_int + != 0 + { + if *heredelim.offset(2 as libc::c_int as isize) + as libc::c_int + != 0 + { + strlen(heredelim) as usize + } else { + 2 as libc::c_int as usize + } + } else { + 1 as libc::c_int as usize + } + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + if (*heredelim.offset(0 as libc::c_int as isize) as libc::c_int + == *nestret.offset(0 as libc::c_int as isize) + as libc::c_int + && strcmp(heredelim, nestret) == 0 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + { + tflags |= 0x400 as libc::c_int; + } + free(nestret as *mut libc::c_void); + } + if ch == '\n' as i32 { + tflags |= 0x80 as libc::c_int; + tflags &= !(0x100 as libc::c_int); + lex_firstind = retind + 1 as libc::c_int; + history_expansion_inhibited = 1 as libc::c_int; + } else { + lex_firstind = -(1 as libc::c_int); + } + } + } + if tflags & 0x10 as libc::c_int == 0 as libc::c_int + && tflags & 0x20 as libc::c_int != 0 + && tflags & 0x4 as libc::c_int == 0 as libc::c_int + && (*sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x1 as libc::c_int + != 0 + || ch == '\n' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh25 = retind; + retind = retind + 1; + *ret.offset(fresh25 as isize) = ch as libc::c_char; + + peekc = shell_getc(1 as libc::c_int); + if ch == peekc + && (ch == '&' as i32 || ch == '|' as i32 || ch == ';' as i32) + { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh26 = retind; + retind = retind + 1; + *ret.offset(fresh26 as isize) = peekc as libc::c_char; + + tflags |= 0x10 as libc::c_int; + lex_rwlen = 0 as libc::c_int; + continue; + } else if ch == '\n' as i32 + || (ch == ';' as i32 || ch == '&' as i32 || ch == '|' as i32) + { + shell_ungetc(peekc); + tflags |= 0x10 as libc::c_int; + lex_rwlen = 0 as libc::c_int; + continue; + } else if ch == -(1 as libc::c_int) { + current_block = 12717184829685720462; + } else { + retind -= 1; + retind; + shell_ungetc(peekc); + current_block = 7923086311623215889; + } + } else { + current_block = 7923086311623215889; + } + match current_block { + 12717184829685720462 => {} + _ => { + if tflags & 0x10 as libc::c_int != 0 { + if *(*__ctype_b_loc()) + .offset(ch as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISlower as libc::c_int as libc::c_ushort as libc::c_int + != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = + realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh27 = retind; + retind = retind + 1; + *ret.offset(fresh27 as isize) = ch as libc::c_char; + + lex_rwlen += 1; + lex_rwlen; + continue; + } else if lex_rwlen == 4 as libc::c_int + && *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x2 as libc::c_int + != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"case\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"case\0" as *const u8 as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + } != 0 + { + tflags |= 0x40 as libc::c_int; + tflags &= !(0x10 as libc::c_int); + } else if if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"esac\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"esac\0" as *const u8 as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + } != 0 + { + tflags &= !(0x40 as libc::c_int); + tflags |= 0x10 as libc::c_int; + lex_rwlen = 0 as libc::c_int; + } else if (if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"done\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"done\0" as *const u8 as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + || (if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"then\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"then\0" as *const u8 + as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + || (if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"else\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"else\0" as *const u8 + as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + || (if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"elif\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"elif\0" as *const u8 + as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + || (if 4 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(4 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 5], + &[libc::c_char; 5], + >( + b"time\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(4 as libc::c_int as isize)), + b"time\0" as *const u8 + as *const libc::c_char, + 4 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + { + tflags |= 0x10 as libc::c_int; + lex_rwlen = 0 as libc::c_int; + } else if *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x1 as libc::c_int + == 0 as libc::c_int + { + tflags &= !(0x10 as libc::c_int); + } else { + lex_rwlen = 0 as libc::c_int; + } + } else if !(tflags & 0x2 as libc::c_int != 0 + && ch == '#' as i32 + && (lex_rwlen == 0 as libc::c_int + || tflags & 0x800 as libc::c_int != 0 + && lex_wlen == 0 as libc::c_int) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0) + { + if tflags & 0x40 as libc::c_int == 0 as libc::c_int + && (*(*__ctype_b_loc()) + .offset(ch as libc::c_uchar as libc::c_int as isize) + as libc::c_int + & _ISblank as libc::c_int as libc::c_ushort + as libc::c_int + != 0 + || ch == '\n' as i32) + && lex_rwlen == 2 as libc::c_int + && (if 2 as libc::c_int == 0 as libc::c_int { + 1 as libc::c_int + } else { + (*ret + .offset(retind as isize) + .offset(-(2 as libc::c_int as isize)) + .offset(0 as libc::c_int as isize) + as libc::c_int + == (*::core::mem::transmute::< + &[u8; 3], + &[libc::c_char; 3], + >( + b"do\0" + )) + [0 as libc::c_int as usize] + as libc::c_int + && strncmp( + ret.offset(retind as isize) + .offset(-(2 as libc::c_int as isize)), + b"do\0" as *const u8 as *const libc::c_char, + 2 as libc::c_int as usize, + ) == 0 as libc::c_int) + as libc::c_int + }) != 0 + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + lex_rwlen = 0 as libc::c_int; + } else if tflags & 0x40 as libc::c_int != 0 + && ch != '\n' as i32 + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags &= !(0x10 as libc::c_int); + } else if *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x2 as libc::c_int + == 0 as libc::c_int + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags &= !(0x10 as libc::c_int); + } + } + } + if tflags & 0x4 as libc::c_int == 0 as libc::c_int + && tflags & 0x20 as libc::c_int != 0 + && ch == '<' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + let fresh28 = retind; + retind = retind + 1; + + *ret.offset(fresh28 as isize) = ch as libc::c_char; + + peekc = shell_getc(1 as libc::c_int); + if !(peekc == -(1 as libc::c_int)) { + if peekc == ch { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc( + ret as *mut libc::c_void, + retsize as usize, + ) + as *mut libc::c_char; + } + let fresh29 = retind; + retind = retind + 1; + + *ret.offset(fresh29 as isize) = peekc as libc::c_char; + + peekc = shell_getc(1 as libc::c_int); + if !(peekc == -(1 as libc::c_int)) { + if peekc == '-' as i32 { + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc( + ret as *mut libc::c_void, + retsize as usize, + ) + as *mut libc::c_char; + } + + let fresh30 = retind; + retind = retind + 1; + *ret.offset(fresh30 as isize) = + peekc as libc::c_char; + tflags |= 0x200 as libc::c_int; + } else { + shell_ungetc(peekc); + } + if peekc != '<' as i32 { + tflags |= 0x100 as libc::c_int; + lex_firstind = -(1 as libc::c_int); + } + continue; + } + } else { + shell_ungetc(peekc); + continue; + } + } + } else { + if tflags & 0x2 as libc::c_int != 0 + && tflags & 0x4 as libc::c_int == 0 as libc::c_int + && ch == '#' as i32 + && (tflags & 0x10 as libc::c_int != 0 + && lex_rwlen == 0 as libc::c_int + || tflags & 0x800 as libc::c_int != 0 + && lex_wlen == 0 as libc::c_int) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x4 as libc::c_int; + } + if (ch == '\u{1}' as i32 || ch == '\u{7f}' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if retind + 2 as libc::c_int >= retsize { + while retind + 2 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = + realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + + let fresh31 = retind; + retind = retind + 1; + *ret.offset(fresh31 as isize) = + '\u{1}' as i32 as libc::c_char; + let fresh32 = retind; + retind = retind + 1; + *ret.offset(fresh32 as isize) = ch as libc::c_char; + + continue; + } else { + if ch == close + && tflags & 0x40 as libc::c_int == 0 as libc::c_int + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + count -= 1; + count; + } else if flags & 0x1 as libc::c_int == 0 as libc::c_int + && tflags & 0x40 as libc::c_int == 0 as libc::c_int + && ch == open + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + count += 1; + count; + } + if retind + 1 as libc::c_int >= retsize { + while retind + 1 as libc::c_int >= retsize { + retsize += 64 as libc::c_int; + } + ret = + realloc(ret as *mut libc::c_void, retsize as usize) + as *mut libc::c_char; + } + let fresh33 = retind; + retind = retind + 1; + + *ret.offset(fresh33 as isize) = ch as libc::c_char; + + if count == 0 as libc::c_int { + break; + } + if ch == '\\' as i32 + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x8 as libc::c_int; + } + if *sh_syntaxtab + .as_mut_ptr() + .offset(ch as libc::c_uchar as isize) + & 0x8 as libc::c_int + != 0 + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if dstack.delimiter_depth + 2 as libc::c_int + > dstack.delimiter_space + { + dstack.delimiter_space += 10 as libc::c_int; + + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong) + .wrapping_mul(::core::mem::size_of::< + libc::c_char, + >( + ) + as libc::c_ulong) + as usize, + ) + as *mut libc::c_char; + } + + *(dstack.delimiters) + .offset(dstack.delimiter_depth as isize) = + ch as libc::c_char; + + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + if tflags & 0x1 as libc::c_int != 0 + && ch == '\'' as i32 + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub( + 1 as libc::c_int as size_t, + ) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + nestret = parse_matched_pair( + ch, + ch, + ch, + &mut nestlen, + 0x2 as libc::c_int | rflags, + ); + } else { + nestret = parse_matched_pair( + ch, + ch, + ch, + &mut nestlen, + rflags, + ); + } + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + if nestret + == &mut matched_pair_error as *mut libc::c_char + { + free(ret as *mut libc::c_void); + return &mut matched_pair_error; + } + if tflags & 0x1 as libc::c_int != 0 + && ch == '\'' as i32 + && (extended_quote != 0 + || rflags & 0x4 as libc::c_int + == 0 as libc::c_int) + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub( + 1 as libc::c_int as size_t, + ) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + ttrans = ansiexpand( + nestret, + 0 as libc::c_int, + nestlen - 1 as libc::c_int, + &mut ttranslen, + ); + free(nestret as *mut libc::c_void); + if rflags & 0x4 as libc::c_int == 0 as libc::c_int { + nestret = sh_single_quote(ttrans); + free(ttrans as *mut libc::c_void); + nestlen = strlen(nestret) as libc::c_int; + } else { + nestret = ttrans; + nestlen = ttranslen; + } + retind -= 2 as libc::c_int; + } else if tflags & 0x1 as libc::c_int != 0 + && ch == '"' as i32 + && (extended_quote != 0 + || rflags & 0x4 as libc::c_int + == 0 as libc::c_int) + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub( + 1 as libc::c_int as size_t, + ) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + ttrans = localeexpand( + nestret, + 0 as libc::c_int, + nestlen - 1 as libc::c_int, + start_lineno, + &mut ttranslen, + ); + free(nestret as *mut libc::c_void); + nestret = sh_mkdoublequoted( + ttrans, + ttranslen, + 0 as libc::c_int, + ); + free(ttrans as *mut libc::c_void); + nestlen = ttranslen + 2 as libc::c_int; + retind -= 2 as libc::c_int; + } + if nestlen != 0 { + if retind + nestlen >= retsize { + while retind + nestlen >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc( + ret as *mut libc::c_void, + retsize as usize, + ) + as *mut libc::c_char; + } + strcpy(ret.offset(retind as isize), nestret); + retind += nestlen; + } + if !nestret.is_null() { + free(nestret as *mut libc::c_void); + } + nestret = 0 as *mut libc::c_char; + } else if tflags & 0x1 as libc::c_int != 0 + && (ch == '(' as i32 + || ch == '{' as i32 + || ch == '[' as i32) + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if tflags & 0x40 as libc::c_int == 0 as libc::c_int + && open == ch + { + count -= 1; + count; + } + if ch == '(' as i32 { + nestret = parse_comsub( + 0 as libc::c_int, + '(' as i32, + ')' as i32, + &mut nestlen, + (rflags | 0x8 as libc::c_int) + & !(0x4 as libc::c_int), + ); + } else if ch == '{' as i32 { + nestret = parse_matched_pair( + 0 as libc::c_int, + '{' as i32, + '}' as i32, + &mut nestlen, + 0x1 as libc::c_int + | 0x40 as libc::c_int + | rflags, + ); + } else if ch == '[' as i32 { + nestret = parse_matched_pair( + 0 as libc::c_int, + '[' as i32, + ']' as i32, + &mut nestlen, + rflags, + ); + } + if nestret + == &mut matched_pair_error as *mut libc::c_char + { + free(ret as *mut libc::c_void); + return &mut matched_pair_error; + } + if nestlen != 0 { + if retind + nestlen >= retsize { + while retind + nestlen >= retsize { + retsize += 64 as libc::c_int; + } + ret = realloc( + ret as *mut libc::c_void, + retsize as usize, + ) + as *mut libc::c_char; + } + strcpy(ret.offset(retind as isize), nestret); + retind += nestlen; + } + if !nestret.is_null() { + free(nestret as *mut libc::c_void); + } + nestret = 0 as *mut libc::c_char; + } + if ch == '$' as i32 + && tflags & 0x1 as libc::c_int == 0 as libc::c_int + && (if shell_input_line_index + > 1 as libc::c_int as size_t + { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + tflags |= 0x1 as libc::c_int; + } else { + tflags &= !(0x1 as libc::c_int); + } + continue; + } + } + } + } + } + } + } + + history_expansion_inhibited = orig_histexp; + free(ret as *mut libc::c_void); + if !heredelim.is_null() { + free(heredelim as *mut libc::c_void); + } + heredelim = 0 as *mut libc::c_char; + parser_error( + start_lineno, + dcgettext( + 0 as *const libc::c_char, + b"unexpected EOF while looking for matching `%c'\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + close, + ); + EOF_Reached = 1 as libc::c_int; + return &mut matched_pair_error; + } + + history_expansion_inhibited = orig_histexp; + if !heredelim.is_null() { + free(heredelim as *mut libc::c_void); + } + + heredelim = 0 as *mut libc::c_char; + + *ret.offset(retind as isize) = '\0' as i32 as libc::c_char; + + if !lenp.is_null() { + *lenp = retind; + } + return ret; + } +} +#[no_mangle] +pub fn xparse_dolparen( + mut base: *mut libc::c_char, + mut string: *mut libc::c_char, + mut indp: *mut libc::c_int, + mut flags: libc::c_int, +) -> *mut libc::c_char { + unsafe { + let mut ps: sh_parser_state_t = _sh_parser_state_t { + parser_state: 0, + token_state: 0 as *mut libc::c_int, + token: 0 as *mut libc::c_char, + token_buffer_size: 0, + input_line_terminator: 0, + eof_encountered: 0, + prompt_string_pointer: 0 as *mut *mut libc::c_char, + current_command_line_count: 0, + remember_on_history: 0, + history_expansion_inhibited: 0, + last_command_exit_value: 0, + pipestatus: 0 as *mut ARRAY, + last_shell_builtin: None, + this_shell_builtin: None, + expand_aliases: 0, + echo_input_at_read: 0, + need_here_doc: 0, + here_doc_first_line: 0, + redir_stack: [0 as *mut REDIRECT; 16], + }; + let mut ls: sh_input_line_state_t = _sh_input_line_state_t { + input_line: 0 as *mut libc::c_char, + input_line_index: 0, + input_line_size: 0, + input_line_len: 0, + input_property: 0 as *mut libc::c_char, + input_propsize: 0, + }; + let mut orig_ind: libc::c_int = 0; + let mut nc: libc::c_int = 0; + let mut sflags: libc::c_int = 0; + let mut orig_eof_token: libc::c_int = 0; + let mut start_lineno: libc::c_int = 0; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ep: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ostring: *mut libc::c_char = 0 as *mut libc::c_char; + let mut saved_pushed_strings: *mut STRING_SAVER = 0 as *mut STRING_SAVER; + orig_ind = *indp; + ostring = string; + start_lineno = line_number; + if *string as libc::c_int == 0 as libc::c_int { + if flags & 0x1 as libc::c_int != 0 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + + ret = malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *ret.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + + return ret; + } + sflags = 0x1 as libc::c_int | 0x4 as libc::c_int | 0x8 as libc::c_int; + if flags & 0x40 as libc::c_int != 0 { + sflags |= 0x40 as libc::c_int; + } + save_parser_state(&mut ps); + save_input_line_state(&mut ls); + + orig_eof_token = shell_eof_token; + echo_input_at_read = 0 as libc::c_int; + saved_pushed_strings = pushed_string_list; + pushed_string_list = 0 as *mut libc::c_void as *mut STRING_SAVER; + parser_state |= 0x40 as libc::c_int | 0x8000 as libc::c_int; + shell_eof_token = ')' as i32; + + nc = parse_string( + string, + b"command substitution\0" as *const u8 as *const libc::c_char, + sflags, + &mut ep, + ); + + if current_token == shell_eof_token { + yychar = -(2 as libc::c_int); + } + + reset_parser(); + restore_input_line_state(&mut ls); + shell_eof_token = orig_eof_token; + restore_parser_state(&mut ps); + pushed_string_list = saved_pushed_strings; + token_to_read = 0 as libc::c_int; + if nc < 0 as libc::c_int { + clear_shell_input_line(); + + if bash_input.type_0 as libc::c_uint != st_string as libc::c_int as libc::c_uint { + parser_state &= !(0x40 as libc::c_int | 0x8000 as libc::c_int); + } + + jump_to_top_level(-nc); + } + if *ep.offset(-(1 as libc::c_int) as isize) as libc::c_int != ')' as i32 { + while ep > ostring + && *ep.offset(-(1 as libc::c_int) as isize) as libc::c_int == '\n' as i32 + { + ep = ep.offset(-1); + + ep; + } + } + + nc = ep.offset_from(ostring) as libc::c_long as libc::c_int; + + *indp = (ep.offset_from(base) as libc::c_long - 1 as libc::c_int as libc::c_long) + as libc::c_int; + if *base.offset(*indp as isize) as libc::c_int != ')' as i32 { + parser_error( + start_lineno, + dcgettext( + 0 as *const libc::c_char, + b"unexpected EOF while looking for matching `%c'\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ')' as i32, + ); + jump_to_top_level(2 as libc::c_int); + } + + if flags & 0x1 as libc::c_int != 0 { + return 0 as *mut libc::c_void as *mut libc::c_char; + } + if nc == 0 as libc::c_int { + ret = malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *ret.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } else { + ret = substring(ostring, 0 as libc::c_int, nc - 1 as libc::c_int); + } + return ret; + } +} +fn parse_dparen(mut c: libc::c_int) -> libc::c_int { + unsafe { + let mut cmdtyp: libc::c_int = 0; + let mut sline: libc::c_int = 0; + let mut wval: *mut libc::c_char = 0 as *mut libc::c_char; + let mut wd: *mut WORD_DESC = 0 as *mut WORD_DESC; + if last_read_token == 265 as libc::c_int { + arith_for_lineno = line_number; + cmdtyp = parse_arith_cmd(&mut wval, 0 as libc::c_int); + if cmdtyp == 1 as libc::c_int { + wd = alloc_word_desc(); + (*wd).word = wval; + + yylval.WordList = make_word_list(wd, 0 as *mut libc::c_void as *mut WORD_LIST); + return 286 as libc::c_int; + } else { + return -(1 as libc::c_int); + } + } + if reserved_word_acceptable(last_read_token) != 0 { + sline = line_number; + cmdtyp = parse_arith_cmd(&mut wval, 0 as libc::c_int); + if cmdtyp == 1 as libc::c_int { + wd = alloc_word_desc(); + (*wd).word = wval; + (*wd).flags = (1 as libc::c_int) << 1 as libc::c_int + | (1 as libc::c_int) << 4 as libc::c_int + | (1 as libc::c_int) << 5 as libc::c_int + | (1 as libc::c_int) << 19 as libc::c_int; + + yylval.WordList = make_word_list(wd, 0 as *mut libc::c_void as *mut WORD_LIST); + return 285 as libc::c_int; + } else if cmdtyp == 0 as libc::c_int { + push_string( + wval, + 0 as libc::c_int, + 0 as *mut libc::c_void as *mut alias_t, + ); + + (*pushed_string_list).flags = 0x2 as libc::c_int; + if parser_state & 0x1 as libc::c_int == 0 as libc::c_int { + parser_state |= 0x20 as libc::c_int; + } + + return c; + } else { + return -(1 as libc::c_int); + } + } + return -(2 as libc::c_int); + } +} +fn parse_arith_cmd(mut ep: *mut *mut libc::c_char, mut adddq: libc::c_int) -> libc::c_int { + unsafe { + let mut exp_lineno: libc::c_int = 0; + let mut rval: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut ttok: *mut libc::c_char = 0 as *mut libc::c_char; + let mut tokstr: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ttoklen: libc::c_int = 0; + exp_lineno = line_number; + ttok = parse_matched_pair( + 0 as libc::c_int, + '(' as i32, + ')' as i32, + &mut ttoklen, + 0 as libc::c_int, + ); + rval = 1 as libc::c_int; + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + c = shell_getc(0 as libc::c_int); + if c != ')' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + rval = 0 as libc::c_int; + } + tokstr = malloc((ttoklen + 4 as libc::c_int) as usize) as *mut libc::c_char; + if rval == 1 as libc::c_int && adddq != 0 { + *tokstr.offset(0 as libc::c_int as isize) = '"' as i32 as libc::c_char; + + strncpy( + tokstr.offset(1 as libc::c_int as isize), + ttok, + (ttoklen - 1 as libc::c_int) as libc::c_ulong as usize, + ); + *tokstr.offset(ttoklen as isize) = '"' as i32 as libc::c_char; + *tokstr.offset((ttoklen + 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + } else if rval == 1 as libc::c_int { + strncpy(tokstr, ttok, (ttoklen - 1 as libc::c_int) as usize); + *tokstr.offset((ttoklen - 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + } else { + *tokstr.offset(0 as libc::c_int as isize) = '(' as i32 as libc::c_char; + + strncpy( + tokstr.offset(1 as libc::c_int as isize), + ttok, + (ttoklen - 1 as libc::c_int) as usize, + ); + *tokstr.offset(ttoklen as isize) = ')' as i32 as libc::c_char; + *tokstr.offset((ttoklen + 1 as libc::c_int) as isize) = c as libc::c_char; + *tokstr.offset((ttoklen + 2 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + } + *ep = tokstr; + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + ttok = 0 as *mut libc::c_char; + return rval; + } +} +fn cond_error() { + unsafe { + let mut etext: *mut libc::c_char = 0 as *mut libc::c_char; + if EOF_Reached != 0 && cond_token != 275 as libc::c_int { + parser_error( + cond_lineno, + dcgettext( + 0 as *const libc::c_char, + b"unexpected EOF while looking for `]]'\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } else if cond_token != 275 as libc::c_int { + etext = error_token_from_token(cond_token); + if !etext.is_null() { + parser_error( + cond_lineno, + dcgettext( + 0 as *const libc::c_char, + b"syntax error in conditional expression: unexpected token `%s'\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + etext, + ); + free(etext as *mut libc::c_void); + } else { + parser_error( + cond_lineno, + dcgettext( + 0 as *const libc::c_char, + b"syntax error in conditional expression\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } + } + } +} +fn cond_expr() -> *mut COND_COM { + return cond_or(); +} +fn cond_or() -> *mut COND_COM { + unsafe { + let mut l: *mut COND_COM = 0 as *mut COND_COM; + let mut r: *mut COND_COM = 0 as *mut COND_COM; + l = cond_and(); + if cond_token == 289 as libc::c_int { + r = cond_or(); + l = make_cond_node( + 2 as libc::c_int, + 0 as *mut libc::c_void as *mut WORD_DESC, + l, + r, + ); + } + return l; + } +} +fn cond_and() -> *mut COND_COM { + unsafe { + let mut l: *mut COND_COM = 0 as *mut COND_COM; + let mut r: *mut COND_COM = 0 as *mut COND_COM; + l = cond_term(); + if cond_token == 288 as libc::c_int { + r = cond_and(); + l = make_cond_node( + 1 as libc::c_int, + 0 as *mut libc::c_void as *mut WORD_DESC, + l, + r, + ); + } + return l; + } +} +fn cond_skip_newlines() -> libc::c_int { + unsafe { + loop { + cond_token = read_token(0 as libc::c_int); + if !(cond_token == '\n' as i32) { + break; + } + if interactive != 0 + && (bash_input.type_0 as libc::c_uint == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint) + { + prompt_again(); + } + } + return cond_token; + } +} +fn cond_term() -> *mut COND_COM { + unsafe { + let mut op: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut term: *mut COND_COM = 0 as *mut COND_COM; + let mut tleft: *mut COND_COM = 0 as *mut COND_COM; + let mut tright: *mut COND_COM = 0 as *mut COND_COM; + let mut tok: libc::c_int = 0; + let mut lineno: libc::c_int = 0; + let mut etext: *mut libc::c_char = 0 as *mut libc::c_char; + tok = cond_skip_newlines(); + lineno = line_number; + if tok == 274 as libc::c_int { + cond_token = 275 as libc::c_int; + return 0 as *mut libc::c_void as *mut COND_COM; + } else if tok == '(' as i32 { + term = cond_expr(); + if cond_token != ')' as i32 { + if !term.is_null() { + dispose_cond_node(term); + } + etext = error_token_from_token(cond_token); + if !etext.is_null() { + parser_error( + lineno, + dcgettext( + 0 as *const libc::c_char, + b"unexpected token `%s', expected `)'\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + etext, + ); + free(etext as *mut libc::c_void); + } else { + parser_error( + lineno, + dcgettext( + 0 as *const libc::c_char, + b"expected `)'\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } + cond_token = 275 as libc::c_int; + return 0 as *mut libc::c_void as *mut COND_COM; + } + term = make_cond_node( + 6 as libc::c_int, + 0 as *mut libc::c_void as *mut WORD_DESC, + term, + 0 as *mut libc::c_void as *mut COND_COM, + ); + cond_skip_newlines(); + } else if tok == 277 as libc::c_int + || tok == 281 as libc::c_int + && (*((*yylval.word).word).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *((*yylval.word).word).offset(1 as libc::c_int as isize) as libc::c_int + == '\0' as i32) + { + if tok == 281 as libc::c_int { + dispose_word(yylval.word); + } + term = cond_term(); + if !term.is_null() { + (*term).flags |= 0x4 as libc::c_int; + } + } else if tok == 281 as libc::c_int + && *((*yylval.word).word).offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *((*yylval.word).word).offset(1 as libc::c_int as isize) as libc::c_int != 0 + && *((*yylval.word).word).offset(2 as libc::c_int as isize) as libc::c_int + == 0 as libc::c_int + && test_unop((*yylval.word).word) != 0 + { + op = yylval.word; + tok = read_token(0 as libc::c_int); + if tok == 281 as libc::c_int { + tleft = make_cond_node( + 5 as libc::c_int, + yylval.word, + 0 as *mut libc::c_void as *mut COND_COM, + 0 as *mut libc::c_void as *mut COND_COM, + ); + term = make_cond_node( + 3 as libc::c_int, + op, + tleft, + 0 as *mut libc::c_void as *mut COND_COM, + ); + } else { + dispose_word(op); + etext = error_token_from_token(tok); + if !etext.is_null() { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected argument `%s' to conditional unary operator\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + etext, + ); + free(etext as *mut libc::c_void); + } else { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected argument to conditional unary operator\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } + cond_token = 275 as libc::c_int; + return 0 as *mut libc::c_void as *mut COND_COM; + } + cond_skip_newlines(); + } else if tok == 281 as libc::c_int { + tleft = make_cond_node( + 5 as libc::c_int, + yylval.word, + 0 as *mut libc::c_void as *mut COND_COM, + 0 as *mut libc::c_void as *mut COND_COM, + ); + tok = read_token(0 as libc::c_int); + if tok == 281 as libc::c_int && test_binop((*yylval.word).word) != 0 { + op = yylval.word; + if *((*op).word).offset(0 as libc::c_int as isize) as libc::c_int == '=' as i32 + && (*((*op).word).offset(1 as libc::c_int as isize) as libc::c_int + == '\0' as i32 + || *((*op).word).offset(1 as libc::c_int as isize) as libc::c_int + == '=' as i32 + && *((*op).word).offset(2 as libc::c_int as isize) as libc::c_int + == '\0' as i32) + { + parser_state |= 0x1000 as libc::c_int; + } else if *((*op).word).offset(0 as libc::c_int as isize) as libc::c_int + == '!' as i32 + && *((*op).word).offset(1 as libc::c_int as isize) as libc::c_int == '=' as i32 + && *((*op).word).offset(2 as libc::c_int as isize) as libc::c_int == '\0' as i32 + { + parser_state |= 0x1000 as libc::c_int; + } + } else if tok == 281 as libc::c_int + && (*((*yylval.word).word).offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 3], &[libc::c_char; 3]>(b"=~\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp( + (*yylval.word).word, + b"=~\0" as *const u8 as *const libc::c_char, + ) == 0 as libc::c_int) + { + op = yylval.word; + parser_state |= 0x10000 as libc::c_int; + } else if tok == '<' as i32 || tok == '>' as i32 { + op = make_word_from_token(tok); + } else if tok == 274 as libc::c_int + || tok == 288 as libc::c_int + || tok == 289 as libc::c_int + || tok == ')' as i32 + { + op = make_word(b"-n\0" as *const u8 as *const libc::c_char); + term = make_cond_node( + 3 as libc::c_int, + op, + tleft, + 0 as *mut libc::c_void as *mut COND_COM, + ); + cond_token = tok; + return term; + } else { + etext = error_token_from_token(tok); + if !etext.is_null() { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected token `%s', conditional binary operator expected\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + etext, + ); + free(etext as *mut libc::c_void); + } else { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"conditional binary operator expected\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } + dispose_cond_node(tleft); + cond_token = 275 as libc::c_int; + return 0 as *mut libc::c_void as *mut COND_COM; + } + + if parser_state & 0x1000 as libc::c_int != 0 { + extended_glob = 1 as libc::c_int; + } + tok = read_token(0 as libc::c_int); + if parser_state & 0x1000 as libc::c_int != 0 { + extended_glob = global_extglob; + } + parser_state &= !(0x10000 as libc::c_int | 0x1000 as libc::c_int); + + if tok == 281 as libc::c_int { + tright = make_cond_node( + 5 as libc::c_int, + yylval.word, + 0 as *mut libc::c_void as *mut COND_COM, + 0 as *mut libc::c_void as *mut COND_COM, + ); + term = make_cond_node(4 as libc::c_int, op, tleft, tright); + } else { + etext = error_token_from_token(tok); + if !etext.is_null() { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected argument `%s' to conditional binary operator\0" + as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + etext, + ); + free(etext as *mut libc::c_void); + } else { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected argument to conditional binary operator\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } + dispose_cond_node(tleft); + dispose_word(op); + cond_token = 275 as libc::c_int; + return 0 as *mut libc::c_void as *mut COND_COM; + } + cond_skip_newlines(); + } else { + if tok < 256 as libc::c_int { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected token `%c' in conditional command\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + tok, + ); + } else { + etext = error_token_from_token(tok); + if !etext.is_null() { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected token `%s' in conditional command\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + etext, + ); + free(etext as *mut libc::c_void); + } else { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected token %d in conditional command\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + tok, + ); + } + } + cond_token = 275 as libc::c_int; + return 0 as *mut libc::c_void as *mut COND_COM; + } + return term; + } +} +fn parse_cond_command() -> *mut COMMAND { + unsafe { + let mut cexp: *mut COND_COM = 0 as *mut COND_COM; + global_extglob = extended_glob; + cexp = cond_expr(); + return make_cond_command(cexp); + } +} +fn token_is_assignment(mut t: *mut libc::c_char, mut i: libc::c_int) -> libc::c_int { + unsafe { + let mut r: libc::c_int = 0; + let mut atoken: *mut libc::c_char = 0 as *mut libc::c_char; + atoken = malloc((i + 3 as libc::c_int) as usize) as *mut libc::c_char; + + memcpy( + atoken as *mut libc::c_void, + t as *const libc::c_void, + i as usize, + ); + + *atoken.offset(i as isize) = '=' as i32 as libc::c_char; + *atoken.offset((i + 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + + r = assignment( + atoken, + (parser_state & 0x2000 as libc::c_int != 0 as libc::c_int) as libc::c_int, + ); + free(atoken as *mut libc::c_void); + return (r > 0 as libc::c_int && r == i) as libc::c_int; + } +} +fn token_is_ident(mut t: *mut libc::c_char, mut i: libc::c_int) -> libc::c_int { + unsafe { + let mut c: libc::c_uchar = 0; + let mut r: libc::c_int = 0; + + c = *t.offset(i as isize) as libc::c_uchar; + + *t.offset(i as isize) = '\0' as i32 as libc::c_char; + + r = legal_identifier(t); + + *t.offset(i as isize) = c as libc::c_char; + + return r; + } +} +fn read_token_word(mut character: libc::c_int) -> libc::c_int { + unsafe { + let mut current_block: u64; + let mut the_word: *mut WORD_DESC = 0 as *mut WORD_DESC; + let mut token_index: libc::c_int = 0; + let mut all_digit_token: libc::c_int = 0; + let mut dollar_present: libc::c_int = 0; + let mut compound_assignment: libc::c_int = 0; + let mut quoted: libc::c_int = 0; + let mut pass_next_character: libc::c_int = 0; + let mut cd: libc::c_int = 0; + let mut result: libc::c_int = 0; + let mut peek_char: libc::c_int = 0; + let mut ttok: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ttrans: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ttoklen: libc::c_int = 0; + let mut ttranslen: libc::c_int = 0; + let mut lvalue: intmax_t = 0; + + if token_buffer_size < 496 as libc::c_int { + token_buffer_size = 496 as libc::c_int; + token = realloc(token as *mut libc::c_void, token_buffer_size as usize) + as *mut libc::c_char; + } + + token_index = 0 as libc::c_int; + all_digit_token = (character >= '0' as i32 && character <= '9' as i32) as libc::c_int; + compound_assignment = 0 as libc::c_int; + pass_next_character = compound_assignment; + quoted = pass_next_character; + dollar_present = quoted; + while !(character == -(1 as libc::c_int)) { + if pass_next_character != 0 { + pass_next_character = 0 as libc::c_int; + current_block = 2802315260714836178; + } else { + cd = if dstack.delimiter_depth != 0 { + *(dstack.delimiters) + .offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + }; + if character == '\\' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + peek_char = shell_getc(0 as libc::c_int); + if peek_char == '\n' as i32 { + character = '\n' as i32; + current_block = 2410910991445625210; + } else { + shell_ungetc(peek_char); + if cd == 0 as libc::c_int + || cd == '`' as i32 + || cd == '"' as i32 + && peek_char >= 0 as libc::c_int + && *sh_syntaxtab.as_mut_ptr().offset(peek_char as isize) + & 0x40 as libc::c_int + != 0 + { + pass_next_character += 1; + pass_next_character; + } + quoted = 1 as libc::c_int; + current_block = 11877077252304325915; + } + } else if *sh_syntaxtab + .as_mut_ptr() + .offset(character as libc::c_uchar as isize) + & 0x8 as libc::c_int + != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if dstack.delimiter_depth + 2 as libc::c_int > dstack.delimiter_space { + dstack.delimiter_space += 10 as libc::c_int; + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong).wrapping_mul( + ::core::mem::size_of::() as libc::c_ulong, + ) as usize, + ) as *mut libc::c_char; + } + *(dstack.delimiters).offset(dstack.delimiter_depth as isize) = + character as libc::c_char; + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + + ttok = parse_matched_pair( + character, + character, + character, + &mut ttoklen, + if character == '`' as i32 { + 0x8 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + if token_index + (ttoklen + 2 as libc::c_int) >= token_buffer_size { + while token_index + (ttoklen + 2 as libc::c_int) >= token_buffer_size { + token_buffer_size += 512 as libc::c_int; + } + token = realloc(token as *mut libc::c_void, token_buffer_size as usize) + as *mut libc::c_char; + } + + let fresh34 = token_index; + token_index = token_index + 1; + + *token.offset(fresh34 as isize) = character as libc::c_char; + + strcpy(token.offset(token_index as isize), ttok); + token_index += ttoklen; + all_digit_token = 0 as libc::c_int; + if character != '`' as i32 { + quoted = 1 as libc::c_int; + } + dollar_present |= (character == '"' as i32 + && !(strchr(ttok, '$' as i32)).is_null()) + as libc::c_int; + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + ttok = 0 as *mut libc::c_char; + current_block = 2410910991445625210; + } else if parser_state & 0x10000 as libc::c_int != 0 + && (character == '(' as i32 || character == '|' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if character == '|' as i32 { + current_block = 11877077252304325915; + } else { + if dstack.delimiter_depth + 2 as libc::c_int > dstack.delimiter_space { + dstack.delimiter_space += 10 as libc::c_int; + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong).wrapping_mul( + ::core::mem::size_of::() as libc::c_ulong, + ) as usize, + ) as *mut libc::c_char; + } + *(dstack.delimiters).offset(dstack.delimiter_depth as isize) = + character as libc::c_char; + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + + ttok = parse_matched_pair( + cd, + '(' as i32, + ')' as i32, + &mut ttoklen, + 0 as libc::c_int, + ); + + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + if token_index + (ttoklen + 2 as libc::c_int) >= token_buffer_size { + while token_index + (ttoklen + 2 as libc::c_int) >= token_buffer_size { + token_buffer_size += 512 as libc::c_int; + } + token = realloc(token as *mut libc::c_void, token_buffer_size as usize) + as *mut libc::c_char; + } + let fresh35 = token_index; + token_index = token_index + 1; + *token.offset(fresh35 as isize) = character as libc::c_char; + strcpy(token.offset(token_index as isize), ttok); + token_index += ttoklen; + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + + ttok = 0 as *mut libc::c_char; + all_digit_token = 0 as libc::c_int; + dollar_present = all_digit_token; + current_block = 2410910991445625210; + } + } else { + if extended_glob != 0 + && (character == '@' as i32 + || character == '*' as i32 + || character == '+' as i32 + || character == '?' as i32 + || character == '!' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + peek_char = shell_getc(1 as libc::c_int); + if peek_char == '(' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if dstack.delimiter_depth + 2 as libc::c_int > dstack.delimiter_space { + dstack.delimiter_space += 10 as libc::c_int; + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong).wrapping_mul( + ::core::mem::size_of::() as libc::c_ulong, + ) as usize, + ) + as *mut libc::c_char; + } + *(dstack.delimiters).offset(dstack.delimiter_depth as isize) = + peek_char as libc::c_char; + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + + ttok = parse_matched_pair( + cd, + '(' as i32, + ')' as i32, + &mut ttoklen, + 0 as libc::c_int, + ); + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + + if token_index + (ttoklen + 3 as libc::c_int) >= token_buffer_size { + while token_index + (ttoklen + 3 as libc::c_int) + >= token_buffer_size + { + token_buffer_size += 512 as libc::c_int; + } + token = + realloc(token as *mut libc::c_void, token_buffer_size as usize) + as *mut libc::c_char; + } + + let fresh36 = token_index; + token_index = token_index + 1; + + *token.offset(fresh36 as isize) = character as libc::c_char; + + let fresh37 = token_index; + token_index = token_index + 1; + + *token.offset(fresh37 as isize) = peek_char as libc::c_char; + + strcpy(token.offset(token_index as isize), ttok); + token_index += ttoklen; + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + ttok = 0 as *mut libc::c_char; + all_digit_token = 0 as libc::c_int; + dollar_present = all_digit_token; + current_block = 2410910991445625210; + } else { + shell_ungetc(peek_char); + current_block = 7072655752890836508; + } + } else { + current_block = 7072655752890836508; + } + match current_block { + 2410910991445625210 => {} + _ => { + if character == '$' as i32 + || character == '<' as i32 + || character == '>' as i32 + { + peek_char = shell_getc(1 as libc::c_int); + if (peek_char == '(' as i32 + || (peek_char == '{' as i32 || peek_char == '[' as i32) + && character == '$' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if peek_char == '{' as i32 { + ttok = parse_matched_pair( + cd, + '{' as i32, + '}' as i32, + &mut ttoklen, + 0x1 as libc::c_int | 0x40 as libc::c_int, + ); + } else if peek_char == '(' as i32 { + if dstack.delimiter_depth + 2 as libc::c_int + > dstack.delimiter_space + { + dstack.delimiter_space += 10 as libc::c_int; + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong) + .wrapping_mul( + ::core::mem::size_of::() + as libc::c_ulong, + ) + as usize, + ) + as *mut libc::c_char; + } + + *(dstack.delimiters) + .offset(dstack.delimiter_depth as isize) = + peek_char as libc::c_char; + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + ttok = parse_comsub( + cd, + '(' as i32, + ')' as i32, + &mut ttoklen, + 0x8 as libc::c_int, + ); + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + } else { + ttok = parse_matched_pair( + cd, + '[' as i32, + ']' as i32, + &mut ttoklen, + 0 as libc::c_int, + ); + } + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + if token_index + (ttoklen + 3 as libc::c_int) + >= token_buffer_size + { + while token_index + (ttoklen + 3 as libc::c_int) + >= token_buffer_size + { + token_buffer_size += 512 as libc::c_int; + } + + token = realloc( + token as *mut libc::c_void, + token_buffer_size as usize, + ) + as *mut libc::c_char; + } + let fresh38 = token_index; + token_index = token_index + 1; + + *token.offset(fresh38 as isize) = character as libc::c_char; + + let fresh39 = token_index; + token_index = token_index + 1; + + *token.offset(fresh39 as isize) = peek_char as libc::c_char; + + strcpy(token.offset(token_index as isize), ttok); + token_index += ttoklen; + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + ttok = 0 as *mut libc::c_char; + dollar_present = 1 as libc::c_int; + all_digit_token = 0 as libc::c_int; + current_block = 2410910991445625210; + } else if character == '$' as i32 + && (peek_char == '\'' as i32 || peek_char == '"' as i32) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + let mut first_line: libc::c_int = 0; + first_line = line_number; + if dstack.delimiter_depth + 2 as libc::c_int + > dstack.delimiter_space + { + dstack.delimiter_space += 10 as libc::c_int; + dstack.delimiters = realloc( + dstack.delimiters as *mut libc::c_void, + (dstack.delimiter_space as libc::c_ulong).wrapping_mul( + ::core::mem::size_of::() + as libc::c_ulong, + ) as usize, + ) + as *mut libc::c_char; + } + + *(dstack.delimiters).offset(dstack.delimiter_depth as isize) = + peek_char as libc::c_char; + dstack.delimiter_depth += 1; + dstack.delimiter_depth; + + ttok = parse_matched_pair( + peek_char, + peek_char, + peek_char, + &mut ttoklen, + if peek_char == '\'' as i32 { + 0x2 as libc::c_int + } else { + 0 as libc::c_int + }, + ); + dstack.delimiter_depth -= 1; + dstack.delimiter_depth; + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + if peek_char == '\'' as i32 { + ttrans = ansiexpand( + ttok, + 0 as libc::c_int, + ttoklen - 1 as libc::c_int, + &mut ttranslen, + ); + free(ttok as *mut libc::c_void); + ttok = sh_single_quote(ttrans); + free(ttrans as *mut libc::c_void); + ttranslen = strlen(ttok) as libc::c_int; + ttrans = ttok; + } else { + ttrans = localeexpand( + ttok, + 0 as libc::c_int, + ttoklen - 1 as libc::c_int, + first_line, + &mut ttranslen, + ); + + free(ttok as *mut libc::c_void); + ttok = + sh_mkdoublequoted(ttrans, ttranslen, 0 as libc::c_int); + free(ttrans as *mut libc::c_void); + + ttranslen += 2 as libc::c_int; + ttrans = ttok; + } + if token_index + (ttranslen + 1 as libc::c_int) + >= token_buffer_size + { + while token_index + (ttranslen + 1 as libc::c_int) + >= token_buffer_size + { + token_buffer_size += 512 as libc::c_int; + } + token = realloc( + token as *mut libc::c_void, + token_buffer_size as usize, + ) + as *mut libc::c_char; + } + strcpy(token.offset(token_index as isize), ttrans); + token_index += ttranslen; + if !ttrans.is_null() { + free(ttrans as *mut libc::c_void); + } + ttrans = 0 as *mut libc::c_char; + quoted = 1 as libc::c_int; + all_digit_token = 0 as libc::c_int; + current_block = 2410910991445625210; + } else if character == '$' as i32 + && peek_char == '$' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if token_index + 3 as libc::c_int >= token_buffer_size { + while token_index + 3 as libc::c_int >= token_buffer_size { + token_buffer_size += 512 as libc::c_int; + } + + token = realloc( + token as *mut libc::c_void, + token_buffer_size as usize, + ) + as *mut libc::c_char; + } + let fresh40 = token_index; + token_index = token_index + 1; + + *token.offset(fresh40 as isize) = '$' as i32 as libc::c_char; + + let fresh41 = token_index; + token_index = token_index + 1; + + *token.offset(fresh41 as isize) = peek_char as libc::c_char; + + dollar_present = 1 as libc::c_int; + all_digit_token = 0 as libc::c_int; + current_block = 2410910991445625210; + } else { + shell_ungetc(peek_char); + current_block = 11099343707781121639; + } + } else if character == '[' as i32 + && (token_index > 0 as libc::c_int + && ((last_read_token == 282 as libc::c_int + || parser_state & 0x80000 as libc::c_int != 0 + && (last_read_token == '<' as i32 + || last_read_token == '>' as i32 + || last_read_token == 290 as libc::c_int + || last_read_token == 302 as libc::c_int + || last_read_token == 301 as libc::c_int + || last_read_token == 298 as libc::c_int + || last_read_token == 291 as libc::c_int + || last_read_token == 293 as libc::c_int + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int + || last_read_token == 299 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + || last_read_token != 295 as libc::c_int + && last_read_token != 296 as libc::c_int + && last_read_token != 297 as libc::c_int + && reserved_word_acceptable(last_read_token) != 0) + && parser_state & 0x1 as libc::c_int == 0 as libc::c_int) + && token_is_ident(token, token_index) != 0 + || token_index == 0 as libc::c_int + && parser_state & 0x2000 as libc::c_int != 0) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + ttok = parse_matched_pair( + cd, + '[' as i32, + ']' as i32, + &mut ttoklen, + 0x20 as libc::c_int, + ); + if ttok == &mut matched_pair_error as *mut libc::c_char { + return -(1 as libc::c_int); + } + if token_index + (ttoklen + 2 as libc::c_int) >= token_buffer_size { + while token_index + (ttoklen + 2 as libc::c_int) + >= token_buffer_size + { + token_buffer_size += 512 as libc::c_int; + } + + token = realloc( + token as *mut libc::c_void, + token_buffer_size as usize, + ) + as *mut libc::c_char; + } + let fresh42 = token_index; + token_index = token_index + 1; + + *token.offset(fresh42 as isize) = character as libc::c_char; + + strcpy(token.offset(token_index as isize), ttok); + token_index += ttoklen; + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + ttok = 0 as *mut libc::c_char; + all_digit_token = 0 as libc::c_int; + current_block = 2410910991445625210; + } else if character == '=' as i32 + && token_index > 0 as libc::c_int + && ((last_read_token == 282 as libc::c_int + || parser_state & 0x80000 as libc::c_int != 0 + && (last_read_token == '<' as i32 + || last_read_token == '>' as i32 + || last_read_token == 290 as libc::c_int + || last_read_token == 302 as libc::c_int + || last_read_token == 301 as libc::c_int + || last_read_token == 298 as libc::c_int + || last_read_token == 291 as libc::c_int + || last_read_token == 293 as libc::c_int + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int + || last_read_token == 299 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + || last_read_token != 295 as libc::c_int + && last_read_token != 296 as libc::c_int + && last_read_token != 297 as libc::c_int + && reserved_word_acceptable(last_read_token) != 0) + && parser_state & 0x1 as libc::c_int == 0 as libc::c_int + || parser_state & 0x4000 as libc::c_int != 0) + && token_is_assignment(token, token_index) != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + peek_char = shell_getc(1 as libc::c_int); + if peek_char == '(' as i32 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + ttok = parse_compound_assignment(&mut ttoklen); + if token_index + (ttoklen + 4 as libc::c_int) + >= token_buffer_size + { + while token_index + (ttoklen + 4 as libc::c_int) + >= token_buffer_size + { + token_buffer_size += 512 as libc::c_int; + } + + token = realloc( + token as *mut libc::c_void, + token_buffer_size as usize, + ) + as *mut libc::c_char; + } + let fresh43 = token_index; + token_index = token_index + 1; + + *token.offset(fresh43 as isize) = '=' as i32 as libc::c_char; + + let fresh44 = token_index; + token_index = token_index + 1; + + *token.offset(fresh44 as isize) = '(' as i32 as libc::c_char; + + if !ttok.is_null() { + strcpy(token.offset(token_index as isize), ttok); + token_index += ttoklen; + } + let fresh45 = token_index; + token_index = token_index + 1; + + *token.offset(fresh45 as isize) = ')' as i32 as libc::c_char; + + if !ttok.is_null() { + free(ttok as *mut libc::c_void); + } + ttok = 0 as *mut libc::c_char; + all_digit_token = 0 as libc::c_int; + compound_assignment = 1 as libc::c_int; + current_block = 2410910991445625210; + } else { + shell_ungetc(peek_char); + current_block = 11099343707781121639; + } + } else { + current_block = 11099343707781121639; + } + match current_block { + 2410910991445625210 => {} + _ => { + if *sh_syntaxtab + .as_mut_ptr() + .offset(character as libc::c_uchar as isize) + & 0x2 as libc::c_int + != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index + .wrapping_sub(1 as libc::c_int as size_t) + as isize, + ) + as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + shell_ungetc(character); + break; + } else { + current_block = 11877077252304325915; + } + } + } + } + } + } + match current_block { + 2410910991445625210 => {} + _ => { + if character == '\u{1}' as i32 || character == '\u{7f}' as i32 { + if token_index + 2 as libc::c_int >= token_buffer_size { + while token_index + 2 as libc::c_int >= token_buffer_size { + token_buffer_size += 512 as libc::c_int; + } + + token = + realloc(token as *mut libc::c_void, token_buffer_size as usize) + as *mut libc::c_char; + } + let fresh46 = token_index; + token_index = token_index + 1; + + *token.offset(fresh46 as isize) = '\u{1}' as i32 as libc::c_char; + + current_block = 8115217508953982058; + } else { + current_block = 2802315260714836178; + } + } + } + } + match current_block { + 2802315260714836178 => { + if token_index + 1 as libc::c_int >= token_buffer_size { + while token_index + 1 as libc::c_int >= token_buffer_size { + token_buffer_size += 512 as libc::c_int; + } + + token = realloc(token as *mut libc::c_void, token_buffer_size as usize) + as *mut libc::c_char; + } + current_block = 8115217508953982058; + } + _ => {} + } + match current_block { + 8115217508953982058 => { + let fresh47 = token_index; + token_index = token_index + 1; + + *token.offset(fresh47 as isize) = character as libc::c_char; + + all_digit_token &= + (character >= '0' as i32 && character <= '9' as i32) as libc::c_int; + dollar_present |= (character == '$' as i32) as libc::c_int; + } + _ => {} + } + if character == '\n' as i32 + && (interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint)) + { + prompt_again(); + } + cd = if dstack.delimiter_depth != 0 { + *(dstack.delimiters).offset((dstack.delimiter_depth - 1 as libc::c_int) as isize) + as libc::c_int + } else { + 0 as libc::c_int + }; + character = shell_getc( + (cd != '\'' as i32 && pass_next_character == 0 as libc::c_int) as libc::c_int, + ); + } + + *token.offset(token_index as isize) = '\0' as i32 as libc::c_char; + + if all_digit_token != 0 + && (character == '<' as i32 + || character == '>' as i32 + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int) + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if legal_number(token, &mut lvalue) != 0 && lvalue as libc::c_int as intmax_t == lvalue + { + yylval.number = lvalue as libc::c_int; + return 284 as libc::c_int; + } + } + result = if if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property + .offset(shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) as isize) + as libc::c_int + } else { + 1 as libc::c_int + } != 0 + { + special_case_tokens(token) + } else { + -(1 as libc::c_int) + }; + if result >= 0 as libc::c_int { + return result; + } + if posixly_correct != 0 + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if dollar_present == 0 && quoted == 0 && reserved_word_acceptable(last_read_token) != 0 + { + let mut i: libc::c_int = 0; + i = 0 as libc::c_int; + + while !(word_token_alist[i as usize].word).is_null() { + if *token.offset(0 as libc::c_int as isize) as libc::c_int + == *(word_token_alist[i as usize].word).offset(0 as libc::c_int as isize) + as libc::c_int + && strcmp(token, word_token_alist[i as usize].word) == 0 as libc::c_int + { + if parser_state & 0x1 as libc::c_int != 0 + && word_token_alist[i as usize].token != 264 as libc::c_int + { + break; + } + if word_token_alist[i as usize].token == 278 as libc::c_int + && time_command_acceptable() == 0 as libc::c_int + { + break; + } + if parser_state & 0x1 as libc::c_int != 0 + && last_read_token == '|' as i32 + && word_token_alist[i as usize].token == 264 as libc::c_int + { + break; + } + if word_token_alist[i as usize].token == 264 as libc::c_int { + parser_state &= !(0x1 as libc::c_int | 0x80 as libc::c_int); + } else if word_token_alist[i as usize].token == 263 as libc::c_int { + parser_state |= 0x80 as libc::c_int; + } else if word_token_alist[i as usize].token == 274 as libc::c_int { + parser_state &= !(0x100 as libc::c_int | 0x200 as libc::c_int); + } else if word_token_alist[i as usize].token == 273 as libc::c_int { + parser_state |= 0x100 as libc::c_int; + } else if word_token_alist[i as usize].token == '{' as i32 { + open_brace_count += 1; + open_brace_count; + } else if word_token_alist[i as usize].token == '}' as i32 + && open_brace_count != 0 + { + open_brace_count -= 1; + open_brace_count; + } + return word_token_alist[i as usize].token; + } else { + i += 1; + i; + } + } + } + } + if expand_aliases != 0 && quoted == 0 as libc::c_int { + result = alias_expand_token(token); + if result == -(99 as libc::c_int) { + return -(99 as libc::c_int); + } else if result == -(100 as libc::c_int) { + parser_state &= !(0x2 as libc::c_int); + } + } + if posixly_correct == 0 as libc::c_int + && (if shell_input_line_index > 1 as libc::c_int as size_t { + *shell_input_line_property.offset( + shell_input_line_index.wrapping_sub(1 as libc::c_int as size_t) as isize, + ) as libc::c_int + } else { + 1 as libc::c_int + }) != 0 + { + if dollar_present == 0 && quoted == 0 && reserved_word_acceptable(last_read_token) != 0 + { + let mut i_0: libc::c_int = 0; + i_0 = 0 as libc::c_int; + while !(word_token_alist[i_0 as usize].word).is_null() { + if *token.offset(0 as libc::c_int as isize) as libc::c_int + == *(word_token_alist[i_0 as usize].word).offset(0 as libc::c_int as isize) + as libc::c_int + && strcmp(token, word_token_alist[i_0 as usize].word) == 0 as libc::c_int + { + if parser_state & 0x1 as libc::c_int != 0 + && word_token_alist[i_0 as usize].token != 264 as libc::c_int + { + break; + } + if word_token_alist[i_0 as usize].token == 278 as libc::c_int + && time_command_acceptable() == 0 as libc::c_int + { + break; + } + if parser_state & 0x1 as libc::c_int != 0 + && last_read_token == '|' as i32 + && word_token_alist[i_0 as usize].token == 264 as libc::c_int + { + break; + } + if word_token_alist[i_0 as usize].token == 264 as libc::c_int { + parser_state &= !(0x1 as libc::c_int | 0x80 as libc::c_int); + } else if word_token_alist[i_0 as usize].token == 263 as libc::c_int { + parser_state |= 0x80 as libc::c_int; + } else if word_token_alist[i_0 as usize].token == 274 as libc::c_int { + parser_state &= !(0x100 as libc::c_int | 0x200 as libc::c_int); + } else if word_token_alist[i_0 as usize].token == 273 as libc::c_int { + parser_state |= 0x100 as libc::c_int; + } else if word_token_alist[i_0 as usize].token == '{' as i32 { + open_brace_count += 1; + open_brace_count; + } else if word_token_alist[i_0 as usize].token == '}' as i32 + && open_brace_count != 0 + { + open_brace_count -= 1; + open_brace_count; + } + return word_token_alist[i_0 as usize].token; + } else { + i_0 += 1; + i_0; + } + } + } + } + the_word = alloc_word_desc(); + + (*the_word).word = malloc((1 as libc::c_int + token_index) as usize) as *mut libc::c_char; + (*the_word).flags = 0 as libc::c_int; + strcpy((*the_word).word, token); + if dollar_present != 0 { + (*the_word).flags |= (1 as libc::c_int) << 0 as libc::c_int; + } + if quoted != 0 { + (*the_word).flags |= (1 as libc::c_int) << 1 as libc::c_int; + } + if compound_assignment != 0 + && *token.offset((token_index - 1 as libc::c_int) as isize) as libc::c_int == ')' as i32 + { + (*the_word).flags |= (1 as libc::c_int) << 15 as libc::c_int; + } + if assignment( + token, + (parser_state & 0x2000 as libc::c_int != 0 as libc::c_int) as libc::c_int, + ) != 0 + { + (*the_word).flags |= (1 as libc::c_int) << 2 as libc::c_int; + if (last_read_token == 282 as libc::c_int + || parser_state & 0x80000 as libc::c_int != 0 + && (last_read_token == '<' as i32 + || last_read_token == '>' as i32 + || last_read_token == 290 as libc::c_int + || last_read_token == 302 as libc::c_int + || last_read_token == 301 as libc::c_int + || last_read_token == 298 as libc::c_int + || last_read_token == 291 as libc::c_int + || last_read_token == 293 as libc::c_int + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int + || last_read_token == 299 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + || last_read_token != 295 as libc::c_int + && last_read_token != 296 as libc::c_int + && last_read_token != 297 as libc::c_int + && reserved_word_acceptable(last_read_token) != 0) + && parser_state & 0x1 as libc::c_int == 0 as libc::c_int + || parser_state & 0x2000 as libc::c_int != 0 as libc::c_int + { + (*the_word).flags |= (1 as libc::c_int) << 4 as libc::c_int; + if parser_state & 0x2000 as libc::c_int != 0 { + (*the_word).flags |= (1 as libc::c_int) << 5 as libc::c_int; + } + } + } + if last_read_token == 282 as libc::c_int + || parser_state & 0x80000 as libc::c_int != 0 + && (last_read_token == '<' as i32 + || last_read_token == '>' as i32 + || last_read_token == 290 as libc::c_int + || last_read_token == 302 as libc::c_int + || last_read_token == 301 as libc::c_int + || last_read_token == 298 as libc::c_int + || last_read_token == 291 as libc::c_int + || last_read_token == 293 as libc::c_int + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int + || last_read_token == 299 as libc::c_int) as libc::c_int + == 0 as libc::c_int + || last_read_token != 295 as libc::c_int + && last_read_token != 296 as libc::c_int + && last_read_token != 297 as libc::c_int + && reserved_word_acceptable(last_read_token) != 0 + { + let mut b: *mut builtin = 0 as *mut builtin; + b = builtin_address_internal(token, 0 as libc::c_int); + if !b.is_null() && (*b).flags & 0x10 as libc::c_int != 0 { + parser_state |= 0x4000 as libc::c_int; + } else if *token.offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"eval\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp(token, b"eval\0" as *const u8 as *const libc::c_char) == 0 as libc::c_int + || *token.offset(0 as libc::c_int as isize) as libc::c_int + == (*::core::mem::transmute::<&[u8; 4], &[libc::c_char; 4]>(b"let\0")) + [0 as libc::c_int as usize] as libc::c_int + && strcmp(token, b"let\0" as *const u8 as *const libc::c_char) + == 0 as libc::c_int + { + parser_state |= 0x4000 as libc::c_int; + } + } + yylval.word = the_word; + if *token.offset(0 as libc::c_int as isize) as libc::c_int == '{' as i32 + && *token.offset((token_index - 1 as libc::c_int) as isize) as libc::c_int == '}' as i32 + && (character == '<' as i32 || character == '>' as i32) + { + *token.offset((token_index - 1 as libc::c_int) as isize) = '\0' as i32 as libc::c_char; + if legal_identifier(token.offset(1 as libc::c_int as isize)) != 0 + || valid_array_reference(token.offset(1 as libc::c_int as isize), 0 as libc::c_int) + != 0 + { + strcpy((*the_word).word, token.offset(1 as libc::c_int as isize)); + yylval.word = the_word; + return 283 as libc::c_int; + } else { + yylval.word = the_word; + } + } + + result = if (*the_word).flags + & ((1 as libc::c_int) << 2 as libc::c_int | (1 as libc::c_int) << 4 as libc::c_int) + == (1 as libc::c_int) << 2 as libc::c_int | (1 as libc::c_int) << 4 as libc::c_int + { + 282 as libc::c_int + } else { + 281 as libc::c_int + }; + + match last_read_token { + 271 => { + parser_state |= 0x4 as libc::c_int; + function_dstart = line_number; + } + 263 | 266 | 265 => { + if word_top < 128 as libc::c_int { + word_top += 1; + word_top; + } + word_lineno[word_top as usize] = line_number; + expecting_in_token += 1; + expecting_in_token; + } + _ => {} + } + + return result; + } +} +fn reserved_word_acceptable(mut toksym: libc::c_int) -> libc::c_int { + unsafe { + match toksym { + 10 | 59 | 40 | 41 | 124 | 38 | 123 | 125 | 288 | 277 | 303 | 269 | 270 | 261 | 260 + | 264 | 262 | 258 | 289 | 295 | 296 | 297 | 259 | 278 | 279 | 280 | 272 | 268 | 267 + | 0 => return 1 as libc::c_int, + _ => { + if last_read_token == 281 as libc::c_int && token_before_that == 272 as libc::c_int + { + return 1 as libc::c_int; + } + if last_read_token == 281 as libc::c_int && token_before_that == 271 as libc::c_int + { + return 1 as libc::c_int; + } + return 0 as libc::c_int; + } + }; + } +} +#[no_mangle] +pub fn find_reserved_word(mut tokstr: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut i: libc::c_int = 0; + i = 0 as libc::c_int; + while !(word_token_alist[i as usize].word).is_null() { + if *tokstr.offset(0 as libc::c_int as isize) as libc::c_int + == *(word_token_alist[i as usize].word).offset(0 as libc::c_int as isize) + as libc::c_int + && strcmp(tokstr, word_token_alist[i as usize].word) == 0 as libc::c_int + { + return i; + } + i += 1; + i; + } + return -(1 as libc::c_int); + } +} +#[no_mangle] +pub fn parser_in_command_position() -> libc::c_int { + unsafe { + return (last_read_token == 282 as libc::c_int + || parser_state & 0x80000 as libc::c_int != 0 + && (last_read_token == '<' as i32 + || last_read_token == '>' as i32 + || last_read_token == 290 as libc::c_int + || last_read_token == 302 as libc::c_int + || last_read_token == 301 as libc::c_int + || last_read_token == 298 as libc::c_int + || last_read_token == 291 as libc::c_int + || last_read_token == 293 as libc::c_int + || last_read_token == 292 as libc::c_int + || last_read_token == 294 as libc::c_int + || last_read_token == 299 as libc::c_int) as libc::c_int + == 0 as libc::c_int + || last_read_token != 295 as libc::c_int + && last_read_token != 296 as libc::c_int + && last_read_token != 297 as libc::c_int + && reserved_word_acceptable(last_read_token) != 0) as libc::c_int; + } +} +static mut no_semi_successors: [libc::c_int; 21] = [ + '\n' as i32, + '{' as i32, + '(' as i32, + ')' as i32, + ';' as i32, + '&' as i32, + '|' as i32, + 263 as libc::c_int, + 269 as libc::c_int, + 260 as libc::c_int, + 258 as libc::c_int, + 295 as libc::c_int, + 296 as libc::c_int, + 297 as libc::c_int, + 259 as libc::c_int, + 268 as libc::c_int, + 267 as libc::c_int, + 288 as libc::c_int, + 289 as libc::c_int, + 276 as libc::c_int, + 0 as libc::c_int, +]; +#[no_mangle] +pub fn history_delimiting_chars(mut line: *const libc::c_char) -> *mut libc::c_char { + unsafe { + static mut last_was_heredoc: libc::c_int = 0 as libc::c_int; + let mut i: libc::c_int = 0; + + if parser_state & 0x20000 as libc::c_int == 0 as libc::c_int { + last_was_heredoc = 0 as libc::c_int; + } + if dstack.delimiter_depth != 0 as libc::c_int { + return b"\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + if parser_state & 0x20000 as libc::c_int != 0 { + if last_was_heredoc != 0 { + last_was_heredoc = 0 as libc::c_int; + return b"\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + return (if here_doc_first_line != 0 { + b"\n\0" as *const u8 as *const libc::c_char + } else { + b"\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + } + if parser_state & 0x2000 as libc::c_int != 0 { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + if token_before_that == ')' as i32 { + if two_tokens_ago == '(' as i32 { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } else if parser_state & 0x80 as libc::c_int != 0 { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } else { + return b"; \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + } else if token_before_that == 281 as libc::c_int && two_tokens_ago == 271 as libc::c_int { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } else if parser_state & 0x20000 as libc::c_int == 0 as libc::c_int + && current_command_line_count > 1 as libc::c_int + && last_read_token == '\n' as i32 + && !(strstr(line, b"<<\0" as *const u8 as *const libc::c_char)).is_null() + { + last_was_heredoc = 1 as libc::c_int; + return b"\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } else if parser_state & 0x20000 as libc::c_int == 0 as libc::c_int + && current_command_line_count > 1 as libc::c_int + && need_here_doc > 0 as libc::c_int + { + return b"\n\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } else if token_before_that == 281 as libc::c_int && two_tokens_ago == 265 as libc::c_int { + i = shell_input_line_index as libc::c_int; + while *shell_input_line.offset(i as isize) as libc::c_int == ' ' as i32 + || *shell_input_line.offset(i as isize) as libc::c_int == '\t' as i32 + { + i += 1; + i; + } + if *shell_input_line.offset(i as isize) as libc::c_int != 0 + && *shell_input_line.offset(i as isize) as libc::c_int == 'i' as i32 + && *shell_input_line.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == 'n' as i32 + { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + return b";\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } else if two_tokens_ago == 263 as libc::c_int + && token_before_that == 281 as libc::c_int + && parser_state & 0x80 as libc::c_int != 0 + { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + i = 0 as libc::c_int; + + while no_semi_successors[i as usize] != 0 { + if token_before_that == no_semi_successors[i as usize] { + return b" \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + i += 1; + i; + } + if line_isblank(line) != 0 { + return b"\0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } + return b"; \0" as *const u8 as *const libc::c_char as *mut libc::c_char; + } +} +fn prompt_again() { + unsafe { + let mut temp_prompt: *mut libc::c_char = 0 as *mut libc::c_char; + if interactive == 0 as libc::c_int + || !pushed_string_list.is_null() && !((*pushed_string_list).expander).is_null() + { + return; + } + ps1_prompt = get_string_value(b"PS1\0" as *const u8 as *const libc::c_char); + ps2_prompt = get_string_value(b"PS2\0" as *const u8 as *const libc::c_char); + ps0_prompt = get_string_value(b"PS0\0" as *const u8 as *const libc::c_char); + if prompt_string_pointer.is_null() { + prompt_string_pointer = &mut ps1_prompt; + } + temp_prompt = if !(*prompt_string_pointer).is_null() { + decode_prompt_string(*prompt_string_pointer) + } else { + 0 as *mut libc::c_void as *mut libc::c_char + }; + if temp_prompt.is_null() { + temp_prompt = malloc(1 as libc::c_int as usize) as *mut libc::c_char; + *temp_prompt.offset(0 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + current_prompt_string = *prompt_string_pointer; + prompt_string_pointer = &mut ps2_prompt; + if no_line_editing == 0 { + if !current_readline_prompt.is_null() { + free(current_readline_prompt as *mut libc::c_void); + } + current_readline_prompt = 0 as *mut libc::c_char; + current_readline_prompt = temp_prompt; + } else { + if !current_decoded_prompt.is_null() { + free(current_decoded_prompt as *mut libc::c_void); + } + current_decoded_prompt = 0 as *mut libc::c_char; + current_decoded_prompt = temp_prompt; + }; + } +} +#[no_mangle] +pub fn get_current_prompt_level() -> libc::c_int { + unsafe { + return if !current_prompt_string.is_null() && current_prompt_string == ps2_prompt { + 2 as libc::c_int + } else { + 1 as libc::c_int + }; + } +} +#[no_mangle] +pub fn set_current_prompt_level(mut x: libc::c_int) { + unsafe { + prompt_string_pointer = if x == 2 as libc::c_int { + &mut ps2_prompt + } else { + &mut ps1_prompt + }; + current_prompt_string = *prompt_string_pointer; + } +} +fn print_prompt() { + unsafe { + fprintf( + stderr, + b"%s\0" as *const u8 as *const libc::c_char, + current_decoded_prompt, + ); + fflush(stderr); + } +} +fn prompt_history_number(mut pmt: *mut libc::c_char) -> libc::c_int { + unsafe { + let mut ret: libc::c_int = 0; + ret = history_number(); + if ret == 1 as libc::c_int { + return ret; + } + if pmt == ps1_prompt { + return ret; + } else if pmt == ps2_prompt && command_oriented_history == 0 as libc::c_int { + return ret; + } else if pmt == ps2_prompt + && command_oriented_history != 0 + && current_command_first_line_saved != 0 + { + return ret - 1 as libc::c_int; + } else { + return ret - 1 as libc::c_int; + }; + } +} +#[no_mangle] +pub fn decode_prompt_string(mut string: *mut libc::c_char) -> *mut libc::c_char { + unsafe { + let mut current_block: u64; + let mut list: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut result: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut orig_string: *mut libc::c_char = 0 as *mut libc::c_char; + let mut save_dstack: dstack = dstack { + delimiters: 0 as *mut libc::c_char, + delimiter_depth: 0, + delimiter_space: 0, + }; + let mut last_exit_value: libc::c_int = 0; + let mut last_comsub_pid: libc::c_int = 0; + let mut result_size: size_t = 0; + let mut result_index: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut n: libc::c_int = 0; + let mut i: libc::c_int = 0; + let mut temp: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t_host: *mut libc::c_char = 0 as *mut libc::c_char; + let mut octal_string: [libc::c_char; 4] = [0; 4]; + let mut tm: *mut tm = 0 as *mut tm; + let mut the_time: time_t = 0; + let mut timebuf: [libc::c_char; 128] = [0; 128]; + let mut timefmt: *mut libc::c_char = 0 as *mut libc::c_char; + result_size = 48 as libc::c_int as size_t; + result = malloc(result_size as usize) as *mut libc::c_char; + result_index = 0 as libc::c_int; + + *result.offset(result_index as isize) = 0 as libc::c_int as libc::c_char; + + temp = 0 as *mut libc::c_void as *mut libc::c_char; + orig_string = string; + loop { + let fresh48 = string; + + string = string.offset(1); + + c = *fresh48 as libc::c_int; + if !(c != 0) { + break; + } + if posixly_correct != 0 && c == '!' as i32 { + if *string as libc::c_int == '!' as i32 { + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add( + strlen(b"!\0" as *const u8 as *const libc::c_char) as u64 + ) as usize, + ) as *mut libc::c_char, + b"!\0" as *const u8 as *const libc::c_char, + ); + } else { + temp = itos(prompt_history_number(orig_string) as intmax_t); + + string = string.offset(-1); + + string; + } + } else if c == '\\' as i32 { + c = *string as libc::c_int; + match c { + 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 => { + strncpy(octal_string.as_mut_ptr(), string, 3 as libc::c_int as usize); + octal_string[3 as libc::c_int as usize] = '\0' as i32 as libc::c_char; + n = read_octal(octal_string.as_mut_ptr()); + temp = malloc(3 as libc::c_int as usize) as *mut libc::c_char; + + if n == '\u{1}' as i32 || n == '\u{7f}' as i32 { + *temp.offset(0 as libc::c_int as isize) = + '\u{1}' as i32 as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = n as libc::c_char; + *temp.offset(2 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } else if n == -(1 as libc::c_int) { + *temp.offset(0 as libc::c_int as isize) = '\\' as i32 as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } else { + *temp.offset(0 as libc::c_int as isize) = n as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + + c = 0 as libc::c_int; + while n != -(1 as libc::c_int) + && c < 3 as libc::c_int + && (*string as libc::c_int >= '0' as i32 + && *string as libc::c_int <= '7' as i32) + { + string = string.offset(1); + + string; + c += 1; + c; + } + c = 0 as libc::c_int; + current_block = 6294327190052088242; + } + 100 | 116 | 84 | 64 | 65 => { + time(&mut the_time); + sv_tz(b"TZ\0" as *const u8 as *const libc::c_char as *mut libc::c_char); + tm = localtime(&mut the_time) as *mut src_common::tm; + if c == 'd' as i32 { + n = strftime( + timebuf.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 128]>() as usize, + b"%a %b %d\0" as *const u8 as *const libc::c_char, + tm as *const libc::tm, + ) as libc::c_int; + } else if c == 't' as i32 { + n = strftime( + timebuf.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 128]>() as usize, + b"%H:%M:%S\0" as *const u8 as *const libc::c_char, + tm as *const libc::tm, + ) as libc::c_int; + } else if c == 'T' as i32 { + n = strftime( + timebuf.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 128]>() as usize, + b"%I:%M:%S\0" as *const u8 as *const libc::c_char, + tm as *const libc::tm, + ) as libc::c_int; + } else if c == '@' as i32 { + n = strftime( + timebuf.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 128]>() as usize, + b"%I:%M %p\0" as *const u8 as *const libc::c_char, + tm as *const libc::tm, + ) as libc::c_int; + } else if c == 'A' as i32 { + n = strftime( + timebuf.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 128]>() as usize, + b"%H:%M\0" as *const u8 as *const libc::c_char, + tm as *const libc::tm, + ) as libc::c_int; + } + if n == 0 as libc::c_int { + timebuf[0 as libc::c_int as usize] = '\0' as i32 as libc::c_char; + } else { + timebuf[(::core::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + as usize] = '\0' as i32 as libc::c_char; + } + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(timebuf.as_mut_ptr()) as u64) + as usize, + ) as *mut libc::c_char, + timebuf.as_mut_ptr(), + ); + current_block = 6294327190052088242; + } + 68 => { + if *string.offset(1 as libc::c_int as isize) as libc::c_int != '{' as i32 { + current_block = 3323500006713522785; + } else { + time(&mut the_time); + tm = localtime(&mut the_time) as *mut src_common::tm; + + string = string.offset(2 as libc::c_int as isize); + + timefmt = malloc( + (strlen(string)).wrapping_add(3 as libc::c_int as u64) as usize + ) as *mut libc::c_char; + t = timefmt; + while *string as libc::c_int != 0 + && *string as libc::c_int != '}' as i32 + { + let fresh49 = string; + + string = string.offset(1); + + let fresh50 = t; + + t = t.offset(1); + + *fresh50 = *fresh49; + } + *t = '\0' as i32 as libc::c_char; + c = *string as libc::c_int; + if *timefmt.offset(0 as libc::c_int as isize) as libc::c_int + == '\0' as i32 + { + *timefmt.offset(0 as libc::c_int as isize) = + '%' as i32 as libc::c_char; + *timefmt.offset(1 as libc::c_int as isize) = + 'X' as i32 as libc::c_char; + *timefmt.offset(2 as libc::c_int as isize) = + '\0' as i32 as libc::c_char; + } + n = strftime( + timebuf.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 128]>() as usize, + timefmt, + tm as *const libc::tm, + ) as libc::c_int; + free(timefmt as *mut libc::c_void); + if n == 0 as libc::c_int { + timebuf[0 as libc::c_int as usize] = '\0' as i32 as libc::c_char; + } else { + timebuf[(::core::mem::size_of::<[libc::c_char; 128]>() + as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + as usize] = '\0' as i32 as libc::c_char; + } + if promptvars != 0 || posixly_correct != 0 { + temp = sh_backslash_quote_for_double_quotes(timebuf.as_mut_ptr()); + } else { + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(timebuf.as_mut_ptr()) as u64) + as usize, + ) as *mut libc::c_char, + timebuf.as_mut_ptr(), + ); + } + current_block = 6294327190052088242; + } + } + 110 => { + temp = malloc(3 as libc::c_int as usize) as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = (if no_line_editing != 0 { + '\n' as i32 + } else { + '\r' as i32 + }) + as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = (if no_line_editing != 0 { + '\0' as i32 + } else { + '\n' as i32 + }) + as libc::c_char; + *temp.offset(2 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + current_block = 6294327190052088242; + } + 115 => { + temp = base_pathname(shell_name); + if promptvars != 0 || posixly_correct != 0 { + temp = sh_backslash_quote_for_double_quotes(temp); + } else { + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(temp) as u64) + as usize, + ) as *mut libc::c_char, + temp, + ); + } + current_block = 6294327190052088242; + } + 118 | 86 => { + temp = malloc(16 as libc::c_int as usize) as *mut libc::c_char; + if c == 'v' as i32 { + strcpy(temp, dist_version); + } else { + sprintf( + temp, + b"%s.%d\0" as *const u8 as *const libc::c_char, + dist_version, + patch_level, + ); + } + current_block = 6294327190052088242; + } + 119 | 87 => { + let mut t_string: [libc::c_char; 4096] = [0; 4096]; + let mut tlen: libc::c_int = 0; + temp = get_string_value(b"PWD\0" as *const u8 as *const libc::c_char); + if temp.is_null() { + if (getcwd( + t_string.as_mut_ptr(), + ::core::mem::size_of::<[libc::c_char; 4096]>() as usize, + )) + .is_null() + { + t_string[0 as libc::c_int as usize] = '.' as i32 as libc::c_char; + tlen = 1 as libc::c_int; + } else { + tlen = strlen(t_string.as_mut_ptr()) as libc::c_int; + } + } else { + tlen = (::core::mem::size_of::<[libc::c_char; 4096]>() as libc::c_ulong) + .wrapping_sub(1 as libc::c_int as libc::c_ulong) + as libc::c_int; + strncpy(t_string.as_mut_ptr(), temp, tlen as usize); + } + t_string[tlen as usize] = '\0' as i32 as libc::c_char; + if c == 'W' as i32 && { + t = get_string_value(b"HOME\0" as *const u8 as *const libc::c_char); + t.is_null() + || (*t.offset(0 as libc::c_int as isize) as libc::c_int + == t_string[0 as libc::c_int as usize] as libc::c_int + && strcmp(t, t_string.as_mut_ptr()) == 0 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + } { + if (t_string[0 as libc::c_int as usize] as libc::c_int == '/' as i32 + && t_string[1 as libc::c_int as usize] as libc::c_int + == 0 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + && (t_string[0 as libc::c_int as usize] as libc::c_int + == '/' as i32 + && t_string[1 as libc::c_int as usize] as libc::c_int + == '/' as i32 + && t_string[2 as libc::c_int as usize] as libc::c_int + == 0 as libc::c_int) + as libc::c_int + == 0 as libc::c_int + { + t = strrchr(t_string.as_mut_ptr(), '/' as i32); + if !t.is_null() { + memmove( + t_string.as_mut_ptr() as *mut libc::c_void, + t.offset(1 as libc::c_int as isize) as *const libc::c_void, + strlen(t) as usize, + ); + } + } + } else { + temp = polite_directory_format(t_string.as_mut_ptr()); + if temp != t_string.as_mut_ptr() { + strcpy(t_string.as_mut_ptr(), temp); + } + } + temp = trim_pathname( + t_string.as_mut_ptr(), + 4096 as libc::c_int - 1 as libc::c_int, + ); + if promptvars != 0 || posixly_correct != 0 { + temp = sh_backslash_quote_for_double_quotes(t_string.as_mut_ptr()); + } else { + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(t_string.as_mut_ptr()) as u64) + as usize, + ) as *mut libc::c_char, + t_string.as_mut_ptr(), + ); + } + current_block = 6294327190052088242; + } + 117 => { + if (current_user.user_name).is_null() { + get_current_user_info(); + } + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(current_user.user_name) as u64) + as usize, + ) as *mut libc::c_char, + current_user.user_name, + ); + current_block = 6294327190052088242; + } + 104 | 72 => { + t_host = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(current_host_name) as u64) + as usize, + ) as *mut libc::c_char, + current_host_name, + ); + if c == 'h' as i32 && { + t = strchr(t_host, '.' as i32); + !t.is_null() + } { + *t = '\0' as i32 as libc::c_char; + } + if promptvars != 0 || posixly_correct != 0 { + temp = sh_backslash_quote_for_double_quotes(t_host); + } else { + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen(t_host) as u64) + as usize, + ) as *mut libc::c_char, + t_host, + ); + } + free(t_host as *mut libc::c_void); + current_block = 6294327190052088242; + } + 35 => { + n = current_command_number; + if orig_string != ps0_prompt + && orig_string != ps1_prompt + && orig_string != ps2_prompt + { + n -= 1; + n; + } + temp = itos(n as intmax_t); + current_block = 6294327190052088242; + } + 33 => { + temp = itos(prompt_history_number(orig_string) as intmax_t); + current_block = 6294327190052088242; + } + 36 => { + temp = malloc(3 as libc::c_int as usize) as *mut libc::c_char; + t = temp; + if (promptvars != 0 || posixly_correct != 0) + && current_user.euid != 0 as libc::c_int as uid_t + { + let fresh51 = t; + + t = t.offset(1); + + *fresh51 = '\\' as i32 as libc::c_char; + } + let fresh52 = t; + + t = t.offset(1); + + *fresh52 = (if current_user.euid == 0 as libc::c_int as uid_t { + '#' as i32 + } else { + '$' as i32 + }) as libc::c_char; + *t = '\0' as i32 as libc::c_char; + current_block = 6294327190052088242; + } + 106 => { + temp = itos(count_all_jobs() as intmax_t); + current_block = 6294327190052088242; + } + 108 => { + temp = ttyname(fileno(stdin)); + t = (if !temp.is_null() { + base_pathname(temp) as *const libc::c_char + } else { + b"tty\0" as *const u8 as *const libc::c_char + }) as *mut libc::c_char; + temp = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(t) as u64) + as usize, + ) as *mut libc::c_char, + t, + ); + current_block = 6294327190052088242; + } + 91 | 93 => { + if no_line_editing != 0 { + string = string.offset(1); + + string; + continue; + } else { + temp = malloc(3 as libc::c_int as usize) as *mut libc::c_char; + n = if c == '[' as i32 { + '\u{1}' as i32 + } else { + '\u{2}' as i32 + }; + i = 0 as libc::c_int; + if n == '\u{1}' as i32 || n == '\u{7f}' as i32 { + let fresh53 = i; + i = i + 1; + + *temp.offset(fresh53 as isize) = '\u{1}' as i32 as libc::c_char; + } + + let fresh54 = i; + i = i + 1; + + *temp.offset(fresh54 as isize) = n as libc::c_char; + *temp.offset(i as isize) = '\0' as i32 as libc::c_char; + } + current_block = 6294327190052088242; + } + 92 | 97 | 101 | 114 => { + temp = malloc(2 as libc::c_int as usize) as *mut libc::c_char; + if c == 'a' as i32 { + *temp.offset(0 as libc::c_int as isize) = + '\u{7}' as i32 as libc::c_char; + } else if c == 'e' as i32 { + *temp.offset(0 as libc::c_int as isize) = + '\u{1b}' as i32 as libc::c_char; + } else if c == 'r' as i32 { + *temp.offset(0 as libc::c_int as isize) = '\r' as i32 as libc::c_char; + } else { + *temp.offset(0 as libc::c_int as isize) = c as libc::c_char; + } + *temp.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + current_block = 6294327190052088242; + } + _ => { + current_block = 3323500006713522785; + } + } + match current_block { + 6294327190052088242 => {} + _ => { + temp = malloc(3 as libc::c_int as usize) as *mut libc::c_char; + *temp.offset(0 as libc::c_int as isize) = '\\' as i32 as libc::c_char; + *temp.offset(1 as libc::c_int as isize) = c as libc::c_char; + *temp.offset(2 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + } + } else { + if (result_index + 3 as libc::c_int) as size_t >= result_size { + while (result_index + 3 as libc::c_int) as size_t >= result_size { + result_size = result_size.wrapping_add(48 as libc::c_int as size_t); + } + result = realloc(result as *mut libc::c_void, result_size as usize) + as *mut libc::c_char; + } + if c == '\u{1}' as i32 || c == '\u{7f}' as i32 { + let fresh55 = result_index; + result_index = result_index + 1; + *result.offset(fresh55 as isize) = '\u{1}' as i32 as libc::c_char; + } + + let fresh56 = result_index; + result_index = result_index + 1; + *result.offset(fresh56 as isize) = c as libc::c_char; + *result.offset(result_index as isize) = '\0' as i32 as libc::c_char; + + continue; + } + if c != 0 { + string = string.offset(1); + + string; + } + result = sub_append_string(temp, result, &mut result_index, &mut result_size); + temp = 0 as *mut libc::c_void as *mut libc::c_char; + + *result.offset(result_index as isize) = '\0' as i32 as libc::c_char; + } + + save_dstack = dstack; + dstack = temp_dstack; + dstack.delimiter_depth = 0 as libc::c_int; + if promptvars != 0 || posixly_correct != 0 { + last_exit_value = last_command_exit_value; + last_comsub_pid = last_command_subst_pid; + list = expand_prompt_string(result, 0x1 as libc::c_int, 0 as libc::c_int); + free(result as *mut libc::c_void); + result = string_list(list); + dispose_words(list); + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + last_exit_value, + ); + last_command_subst_pid = last_comsub_pid; + } else { + t = dequote_string(result); + free(result as *mut libc::c_void); + result = t; + } + dstack = save_dstack; + + return result; + } +} +#[no_mangle] +pub fn yyerror(mut _msg: *const libc::c_char) -> libc::c_int { + report_syntax_error(0 as *mut libc::c_void as *mut libc::c_char); + reset_parser(); + return 0 as libc::c_int; +} +fn error_token_from_token(mut tok: libc::c_int) -> *mut libc::c_char { + unsafe { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + t = find_token_in_alist(tok, word_token_alist.as_mut_ptr(), 0 as libc::c_int); + if !t.is_null() { + return t; + } + t = find_token_in_alist(tok, other_token_alist.as_mut_ptr(), 0 as libc::c_int); + if !t.is_null() { + return t; + } + t = 0 as *mut libc::c_void as *mut libc::c_char; + match current_token { + 281 | 282 => { + if !(yylval.word).is_null() { + t = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong) + .wrapping_add(strlen((*yylval.word).word) as u64) + as usize, + ) as *mut libc::c_char, + (*yylval.word).word, + ); + } + } + 284 => { + t = itos(yylval.number as intmax_t); + } + 285 => { + if !(yylval.WordList).is_null() { + t = string_list(yylval.WordList); + } + } + 286 => { + if !(yylval.WordList).is_null() { + t = string_list_internal( + yylval.WordList, + b" ; \0" as *const u8 as *const libc::c_char as *mut libc::c_char, + ); + } + } + 287 => { + t = 0 as *mut libc::c_void as *mut libc::c_char; + } + _ => {} + } + return t; + } +} +fn error_token_from_text() -> *mut libc::c_char { + unsafe { + let mut msg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut token_end: libc::c_int = 0; + let mut i: libc::c_int = 0; + t = shell_input_line; + i = shell_input_line_index as libc::c_int; + token_end = 0 as libc::c_int; + msg = 0 as *mut libc::c_void as *mut libc::c_char; + if i != 0 && *t.offset(i as isize) as libc::c_int == '\0' as i32 { + i -= 1; + i; + } + while i != 0 + && (*t.offset(i as isize) as libc::c_int == ' ' as i32 + || *t.offset(i as isize) as libc::c_int == '\t' as i32 + || *t.offset(i as isize) as libc::c_int == '\n' as i32) + { + i -= 1; + i; + } + if i != 0 { + token_end = i + 1 as libc::c_int; + } + while i != 0 + && (if *t.offset(i as isize) as libc::c_int != 0 { + (mbschr( + b" \n\t;|&\0" as *const u8 as *const libc::c_char, + *t.offset(i as isize) as libc::c_int, + ) != 0 as *mut libc::c_void as *mut libc::c_char) as libc::c_int + } else { + 0 as libc::c_int + }) == 0 as libc::c_int + { + i -= 1; + i; + } + while i != token_end + && (*t.offset(i as isize) as libc::c_int == ' ' as i32 + || *t.offset(i as isize) as libc::c_int == '\t' as i32 + || *t.offset(i as isize) as libc::c_int == '\n' as i32) + { + i += 1; + i; + } + if token_end != 0 || i == 0 as libc::c_int && token_end == 0 as libc::c_int { + if token_end != 0 { + msg = substring(t, i, token_end); + } else { + msg = malloc(2 as libc::c_int as usize) as *mut libc::c_char; + + *msg.offset(0 as libc::c_int as isize) = *t.offset(i as isize); + *msg.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + } + return msg; + } +} +fn print_offending_line() { + unsafe { + let mut msg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut token_end: libc::c_int = 0; + msg = strcpy( + malloc( + (1 as libc::c_int as libc::c_ulong).wrapping_add(strlen(shell_input_line) as u64) + as usize, + ) as *mut libc::c_char, + shell_input_line, + ); + token_end = strlen(msg) as libc::c_int; + while token_end != 0 + && *msg.offset((token_end - 1 as libc::c_int) as isize) as libc::c_int == '\n' as i32 + { + token_end -= 1; + + *msg.offset(token_end as isize) = '\0' as i32 as libc::c_char; + } + + parser_error( + line_number, + b"`%s'\0" as *const u8 as *const libc::c_char, + msg, + ); + free(msg as *mut libc::c_void); + } +} +fn report_syntax_error(mut message: *mut libc::c_char) { + unsafe { + let mut msg: *mut libc::c_char = 0 as *mut libc::c_char; + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + if !message.is_null() { + parser_error( + line_number, + b"%s\0" as *const u8 as *const libc::c_char, + message, + ); + if interactive != 0 && EOF_Reached != 0 { + EOF_Reached = 0 as libc::c_int; + } + + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + if executing_builtin != 0 && parse_and_execute_level != 0 { + 257 as libc::c_int + } else { + 2 as libc::c_int + }, + ); + set_pipestatus_from_exit(last_command_exit_value); + return; + } + if current_token != 0 as libc::c_int && EOF_Reached == 0 as libc::c_int && { + msg = error_token_from_token(current_token); + !msg.is_null() + } { + if ansic_shouldquote(msg) != 0 { + p = ansic_quote(msg, 0 as libc::c_int, 0 as *mut libc::c_int); + free(msg as *mut libc::c_void); + msg = p; + } + + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"syntax error near unexpected token `%s'\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + msg, + ); + + free(msg as *mut libc::c_void); + if interactive == 0 as libc::c_int { + print_offending_line(); + } + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + if executing_builtin != 0 && parse_and_execute_level != 0 { + 257 as libc::c_int + } else { + 2 as libc::c_int + }, + ); + + set_pipestatus_from_exit(last_command_exit_value); + return; + } + + if !shell_input_line.is_null() && *shell_input_line as libc::c_int != 0 { + msg = error_token_from_text(); + if !msg.is_null() { + parser_error( + line_number, + dcgettext( + 0 as *const libc::c_char, + b"syntax error near `%s'\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ), + msg, + ); + free(msg as *mut libc::c_void); + } + if interactive == 0 as libc::c_int { + print_offending_line(); + } + } else { + msg = if EOF_Reached != 0 { + dcgettext( + 0 as *const libc::c_char, + b"syntax error: unexpected end of file\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ) + } else { + dcgettext( + 0 as *const libc::c_char, + b"syntax error\0" as *const u8 as *const libc::c_char, + 5 as libc::c_int, + ) + }; + parser_error( + line_number, + b"%s\0" as *const u8 as *const libc::c_char, + msg, + ); + if interactive != 0 && EOF_Reached != 0 { + EOF_Reached = 0 as libc::c_int; + } + } + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + if executing_builtin != 0 && parse_and_execute_level != 0 { + 257 as libc::c_int + } else { + 2 as libc::c_int + }, + ); + + set_pipestatus_from_exit(last_command_exit_value); + } +} +#[no_mangle] +pub static mut ignoreeof: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut eof_encountered: libc::c_int = 0 as libc::c_int; +#[no_mangle] +pub static mut eof_encountered_limit: libc::c_int = 10 as libc::c_int; +fn handle_eof_input_unit() { + unsafe { + if interactive != 0 { + if EOF_Reached != 0 { + EOF_Reached = 0 as libc::c_int; + } + if ignoreeof != 0 { + if eof_encountered < eof_encountered_limit { + fprintf( + stderr, + dcgettext( + 0 as *const libc::c_char, + b"Use \"%s\" to leave the shell.\n\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + if login_shell != 0 { + b"logout\0" as *const u8 as *const libc::c_char + } else { + b"exit\0" as *const u8 as *const libc::c_char + }, + ); + eof_encountered += 1; + eof_encountered; + current_token = '\n' as i32; + last_read_token = current_token; + prompt_string_pointer = 0 as *mut libc::c_void as *mut *mut libc::c_char; + prompt_again(); + return; + } + } + reset_parser(); + last_shell_builtin = this_shell_builtin; + this_shell_builtin = Some(exit_builtin as fn(*mut WORD_LIST) -> libc::c_int); + exit_builtin(0 as *mut libc::c_void as *mut WORD_LIST); + } else { + EOF_Reached = 1 as libc::c_int; + }; + } +} +static mut parse_string_error: WORD_LIST = word_list { + next: 0 as *const word_list as *mut word_list, + word: 0 as *const WORD_DESC as *mut WORD_DESC, +}; +#[no_mangle] +pub fn parse_string_to_word_list( + mut s: *mut libc::c_char, + mut flags: libc::c_int, + mut whom: *const libc::c_char, +) -> *mut WORD_LIST { + unsafe { + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tok: libc::c_int = 0; + let mut orig_current_token: libc::c_int = 0; + let mut orig_line_number: libc::c_int = 0; + let mut orig_input_terminator: libc::c_int = 0; + let mut orig_line_count: libc::c_int = 0; + let mut old_echo_input: libc::c_int = 0; + let mut old_expand_aliases: libc::c_int = 0; + let mut _ea: libc::c_int = 0; + let mut old_remember_on_history: libc::c_int = 0; + let mut old_history_expansion_inhibited: libc::c_int = 0; + + old_remember_on_history = remember_on_history; + old_history_expansion_inhibited = history_expansion_inhibited; + bash_history_disable(); + orig_line_number = line_number; + orig_line_count = current_command_line_count; + orig_input_terminator = shell_input_line_terminator; + old_echo_input = echo_input_at_read; + old_expand_aliases = expand_aliases; + push_stream(1 as libc::c_int); + last_read_token = 281 as libc::c_int; + current_command_line_count = 0 as libc::c_int; + expand_aliases = 0 as libc::c_int; + echo_input_at_read = expand_aliases; + with_input_from_string(s, whom); + wl = 0 as *mut libc::c_void as *mut WORD_LIST; + if flags & 1 as libc::c_int != 0 { + parser_state |= 0x2000 as libc::c_int | 0x40000 as libc::c_int; + } + + loop { + tok = read_token(0 as libc::c_int); + if !(tok != 304 as libc::c_int) { + break; + } + if tok == '\n' as i32 && *bash_input.location.string as libc::c_int == '\0' as i32 { + break; + } + if tok == '\n' as i32 { + continue; + } + + if tok != 281 as libc::c_int && tok != 282 as libc::c_int { + line_number = orig_line_number + line_number - 1 as libc::c_int; + orig_current_token = current_token; + current_token = tok; + yyerror(0 as *const libc::c_char); + current_token = orig_current_token; + if !wl.is_null() { + dispose_words(wl); + } + wl = &mut parse_string_error; + break; + } else { + wl = make_word_list(yylval.word, wl); + } + } + + last_read_token = '\n' as i32; + pop_stream(); + remember_on_history = old_remember_on_history; + history_expansion_inhibited = old_history_expansion_inhibited; + echo_input_at_read = old_echo_input; + expand_aliases = old_expand_aliases; + current_command_line_count = orig_line_count; + shell_input_line_terminator = orig_input_terminator; + if flags & 1 as libc::c_int != 0 { + parser_state &= !(0x2000 as libc::c_int | 0x40000 as libc::c_int); + } + if wl == &mut parse_string_error as *mut WORD_LIST { + set_exit_status(1 as libc::c_int); + if interactive_shell == 0 as libc::c_int && posixly_correct != 0 { + jump_to_top_level(1 as libc::c_int); + } else { + jump_to_top_level(2 as libc::c_int); + } + } + + return if !wl.is_null() && !((*wl).next).is_null() { + list_reverse(wl as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + wl + }; + } +} +fn parse_compound_assignment(mut retlenp: *mut libc::c_int) -> *mut libc::c_char { + unsafe { + let mut wl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut rl: *mut WORD_LIST = 0 as *mut WORD_LIST; + let mut tok: libc::c_int = 0; + let mut orig_line_number: libc::c_int = 0; + let mut orig_token_size: libc::c_int = 0; + let mut orig_last_token: libc::c_int = 0; + let mut assignok: libc::c_int = 0; + let mut saved_token: *mut libc::c_char = 0 as *mut libc::c_char; + let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; + + saved_token = token; + orig_token_size = token_buffer_size; + orig_line_number = line_number; + orig_last_token = last_read_token; + last_read_token = 281 as libc::c_int; + token = 0 as *mut libc::c_void as *mut libc::c_char; + token_buffer_size = 0 as libc::c_int; + assignok = parser_state & 0x4000 as libc::c_int; + wl = 0 as *mut libc::c_void as *mut WORD_LIST; + parser_state |= 0x2000 as libc::c_int; + + loop { + tok = read_token(0 as libc::c_int); + if !(tok != ')' as i32) { + break; + } + + if tok == '\n' as i32 { + if interactive != 0 + && (bash_input.type_0 as libc::c_uint + == st_stdin as libc::c_int as libc::c_uint + || bash_input.type_0 as libc::c_uint + == st_stream as libc::c_int as libc::c_uint) + { + prompt_again(); + } + } else if tok != 281 as libc::c_int && tok != 282 as libc::c_int { + current_token = tok; + if tok == 304 as libc::c_int { + parser_error( + orig_line_number, + dcgettext( + 0 as *const libc::c_char, + b"unexpected EOF while looking for matching `)'\0" as *const u8 + as *const libc::c_char, + 5 as libc::c_int, + ), + ); + } else { + yyerror(0 as *const libc::c_char); + } + if !wl.is_null() { + dispose_words(wl); + } + wl = &mut parse_string_error; + break; + } else { + wl = make_word_list(yylval.word, wl); + } + } + if !token.is_null() { + free(token as *mut libc::c_void); + } + + token = 0 as *mut libc::c_char; + token = saved_token; + token_buffer_size = orig_token_size; + parser_state &= !(0x2000 as libc::c_int); + if wl == &mut parse_string_error as *mut WORD_LIST { + set_exit_status(1 as libc::c_int); + last_read_token = '\n' as i32; + if interactive_shell == 0 as libc::c_int && posixly_correct != 0 { + jump_to_top_level(1 as libc::c_int); + } else { + jump_to_top_level(2 as libc::c_int); + } + } + last_read_token = orig_last_token; + + if !wl.is_null() { + rl = if !wl.is_null() && !((*wl).next).is_null() { + list_reverse(wl as *mut GENERIC_LIST) as *mut WORD_LIST + } else { + wl + }; + ret = string_list(rl); + dispose_words(rl); + } else { + ret = 0 as *mut libc::c_void as *mut libc::c_char; + } + if !retlenp.is_null() { + *retlenp = (if !ret.is_null() && *ret as libc::c_int != 0 { + strlen(ret) as usize + } else { + 0 as libc::c_int as usize + }) as libc::c_int; + } + if assignok != 0 { + parser_state |= 0x4000 as libc::c_int; + } + return ret; + } +} +#[no_mangle] +pub fn save_parser_state(mut ps: *mut sh_parser_state_t) -> *mut sh_parser_state_t { + unsafe { + if ps.is_null() { + ps = malloc(::core::mem::size_of::() as usize) + as *mut sh_parser_state_t; + } + if ps.is_null() { + return 0 as *mut libc::c_void as *mut sh_parser_state_t; + } + + (*ps).parser_state = parser_state; + (*ps).token_state = save_token_state(); + (*ps).input_line_terminator = shell_input_line_terminator; + (*ps).eof_encountered = eof_encountered; + (*ps).prompt_string_pointer = prompt_string_pointer; + (*ps).current_command_line_count = current_command_line_count; + (*ps).remember_on_history = remember_on_history; + (*ps).history_expansion_inhibited = history_expansion_inhibited; + (*ps).last_command_exit_value = last_command_exit_value; + (*ps).pipestatus = save_pipestatus_array(); + (*ps).last_shell_builtin = last_shell_builtin; + (*ps).this_shell_builtin = this_shell_builtin; + (*ps).expand_aliases = expand_aliases; + (*ps).echo_input_at_read = echo_input_at_read; + (*ps).need_here_doc = need_here_doc; + (*ps).here_doc_first_line = here_doc_first_line; + if need_here_doc == 0 as libc::c_int { + (*ps).redir_stack[0 as libc::c_int as usize] = 0 as *mut REDIRECT; + } else { + memcpy( + ((*ps).redir_stack).as_mut_ptr() as *mut libc::c_void, + redir_stack.as_mut_ptr() as *const libc::c_void, + (::core::mem::size_of::<*mut REDIRECT>() as libc::c_ulong) + .wrapping_mul(16 as libc::c_int as libc::c_ulong) as usize, + ); + } + (*ps).token = token; + (*ps).token_buffer_size = token_buffer_size; + token = 0 as *mut libc::c_char; + token_buffer_size = 0 as libc::c_int; + + return ps; + } +} +#[no_mangle] +pub fn restore_parser_state(mut ps: *mut sh_parser_state_t) { + unsafe { + let mut _i: libc::c_int = 0; + if ps.is_null() { + return; + } + + parser_state = (*ps).parser_state; + if !((*ps).token_state).is_null() { + restore_token_state((*ps).token_state); + free((*ps).token_state as *mut libc::c_void); + } + shell_input_line_terminator = (*ps).input_line_terminator; + eof_encountered = (*ps).eof_encountered; + prompt_string_pointer = (*ps).prompt_string_pointer; + current_command_line_count = (*ps).current_command_line_count; + remember_on_history = (*ps).remember_on_history; + history_expansion_inhibited = (*ps).history_expansion_inhibited; + ::core::ptr::write_volatile( + &mut last_command_exit_value as *mut libc::c_int, + (*ps).last_command_exit_value, + ); + restore_pipestatus_array((*ps).pipestatus); + last_shell_builtin = (*ps).last_shell_builtin; + this_shell_builtin = (*ps).this_shell_builtin; + expand_aliases = (*ps).expand_aliases; + echo_input_at_read = (*ps).echo_input_at_read; + need_here_doc = (*ps).need_here_doc; + here_doc_first_line = (*ps).here_doc_first_line; + if need_here_doc == 0 as libc::c_int { + redir_stack[0 as libc::c_int as usize] = 0 as *mut REDIRECT; + } else { + memcpy( + redir_stack.as_mut_ptr() as *mut libc::c_void, + ((*ps).redir_stack).as_mut_ptr() as *const libc::c_void, + (::core::mem::size_of::<*mut REDIRECT>() as libc::c_ulong) + .wrapping_mul(16 as libc::c_int as libc::c_ulong) as usize, + ); + } + if !token.is_null() { + free(token as *mut libc::c_void); + } + token = 0 as *mut libc::c_char; + token = (*ps).token; + token_buffer_size = (*ps).token_buffer_size; + } +} +#[no_mangle] +pub fn save_input_line_state(mut ls: *mut sh_input_line_state_t) -> *mut sh_input_line_state_t { + unsafe { + if ls.is_null() { + ls = malloc(::core::mem::size_of::() as usize) + as *mut sh_input_line_state_t; + } + if ls.is_null() { + return 0 as *mut libc::c_void as *mut sh_input_line_state_t; + } + + (*ls).input_line = shell_input_line; + (*ls).input_line_size = shell_input_line_size; + (*ls).input_line_len = shell_input_line_len; + (*ls).input_line_index = shell_input_line_index; + (*ls).input_property = shell_input_line_property; + (*ls).input_propsize = shell_input_line_propsize; + shell_input_line = 0 as *mut libc::c_char; + shell_input_line_index = 0 as libc::c_int as size_t; + shell_input_line_len = shell_input_line_index; + shell_input_line_size = shell_input_line_len; + shell_input_line_property = 0 as *mut libc::c_char; + shell_input_line_propsize = 0 as libc::c_int as size_t; + + return ls; + } +} +#[no_mangle] +pub fn restore_input_line_state(mut ls: *mut sh_input_line_state_t) { + unsafe { + if !shell_input_line.is_null() { + free(shell_input_line as *mut libc::c_void); + } + shell_input_line = 0 as *mut libc::c_char; + shell_input_line = (*ls).input_line; + shell_input_line_size = (*ls).input_line_size; + shell_input_line_len = (*ls).input_line_len; + shell_input_line_index = (*ls).input_line_index; + if !shell_input_line_property.is_null() { + free(shell_input_line_property as *mut libc::c_void); + } + shell_input_line_property = 0 as *mut libc::c_char; + shell_input_line_property = (*ls).input_property; + shell_input_line_propsize = (*ls).input_propsize; + } +} +fn set_line_mbstate() { + unsafe { + let mut c: libc::c_int = 0; + let mut i: size_t = 0; + let mut previ: size_t = 0; + let mut len: size_t = 0; + let mut mbs: mbstate_t = __mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut prevs: mbstate_t = __mbstate_t { + __count: 0, + __value: mbstate_t_value { __wch: 0 }, + }; + let mut mbclen: size_t = 0; + let mut ilen: libc::c_int = 0; + if shell_input_line.is_null() { + return; + } + len = if !shell_input_line.is_null() + && *shell_input_line.offset(0 as libc::c_int as isize) as libc::c_int != 0 + { + if *shell_input_line.offset(1 as libc::c_int as isize) as libc::c_int != 0 { + if *shell_input_line.offset(2 as libc::c_int as isize) as libc::c_int != 0 { + strlen(shell_input_line) as u64 + } else { + 2 as libc::c_int as libc::c_ulong + } + } else { + 1 as libc::c_int as libc::c_ulong + } + } else { + 0 as libc::c_int as libc::c_ulong + }; + if len == 0 as libc::c_int as size_t { + return; + } + + if shell_input_line_propsize >= 32768 as libc::c_int as size_t + && len < (32768 as libc::c_int >> 1 as libc::c_int) as size_t + { + free(shell_input_line_property as *mut libc::c_void); + shell_input_line_property = 0 as *mut libc::c_char; + shell_input_line_propsize = 0 as libc::c_int as size_t; + } + if len.wrapping_add(1 as libc::c_int as size_t) > shell_input_line_propsize { + shell_input_line_propsize = len.wrapping_add(1 as libc::c_int as size_t); + shell_input_line_property = realloc( + shell_input_line_property as *mut libc::c_void, + shell_input_line_propsize as usize, + ) as *mut libc::c_char; + } + if locale_mb_cur_max == 1 as libc::c_int { + memset( + shell_input_line_property as *mut libc::c_void, + 1 as libc::c_int, + len as usize, + ); + return; + } + if locale_utf8locale == 0 as libc::c_int { + memset( + &mut prevs as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + ::core::mem::size_of::() as libc::c_ulong as usize, + ); + } + + previ = 0 as libc::c_int as size_t; + i = previ; + while i < len { + if locale_utf8locale == 0 as libc::c_int { + mbs = prevs; + } + c = *shell_input_line.offset(i as isize) as libc::c_int; + if c == -(1 as libc::c_int) { + let mut j: size_t = 0; + j = i; + while j < len { + *shell_input_line_property.offset(j as isize) = + 1 as libc::c_int as libc::c_char; + + j = j.wrapping_add(1); + j; + } + break; + } else { + if locale_utf8locale != 0 { + if (*shell_input_line.offset(previ as isize) as libc::c_uchar as libc::c_int) + < 128 as libc::c_int + { + mbclen = 1 as libc::c_int as size_t; + } else { + ilen = utf8_mblen( + shell_input_line.offset(previ as isize), + i.wrapping_sub(previ) + .wrapping_add(1 as libc::c_int as size_t), + ); + mbclen = if ilen == -(1 as libc::c_int) { + -(1 as libc::c_int) as size_t + } else if ilen == -(2 as libc::c_int) { + -(2 as libc::c_int) as size_t + } else { + ilen as size_t + }; + } + } else { + mbclen = mbrlen( + shell_input_line.offset(previ as isize), + i.wrapping_sub(previ) + .wrapping_add(1 as libc::c_int as size_t), + &mut mbs, + ); + } + if mbclen == 1 as libc::c_int as size_t || mbclen == -(1 as libc::c_int) as size_t { + mbclen = 1 as libc::c_int as size_t; + previ = i.wrapping_add(1 as libc::c_int as size_t); + } else if mbclen == -(2 as libc::c_int) as size_t { + mbclen = 0 as libc::c_int as size_t; + } else if mbclen > 1 as libc::c_int as size_t { + mbclen = 0 as libc::c_int as size_t; + previ = i.wrapping_add(1 as libc::c_int as size_t); + if locale_utf8locale == 0 as libc::c_int { + prevs = mbs; + } + } else { + let mut j_0: size_t = 0; + j_0 = i; + while j_0 < len { + *shell_input_line_property.offset(j_0 as isize) = + 1 as libc::c_int as libc::c_char; + + j_0 = j_0.wrapping_add(1); + j_0; + } + break; + } + + *shell_input_line_property.offset(i as isize) = mbclen as libc::c_char; + + i = i.wrapping_add(1); + i; + } + } + } +} diff --git a/utshell-0.5.0/variable/Makefile b/utshell-0.5.0/variable/Makefile new file mode 100644 index 00000000..1c44d03b --- /dev/null +++ b/utshell-0.5.0/variable/Makefile @@ -0,0 +1,33 @@ +Machine = $(shell uname -m) +MACHTYPE = $(shell ../lib/support/config.sub $(Machine)-linux) +OS = $(shell echo $(MACHTYPE) | sed 's/^\(.*\)-\([^-]*-[^-]*\)$$/\2/') +VENDOR = pc + +CC=gcc +CFLAGS=-Wall -g -fPIC + +AR=ar +ARFLAGS=-rcs + +TARGET=libvar_params.a + +SYSTEM_FLAGS = -DCONF_HOSTTYPE='"$(Machine)"' -DCONF_OSTYPE='"$(OS)"' -DCONF_MACHTYPE='"$(MACHTYPE)"' +CFLAGS += $(SYSTEM_FLAGS) + + +SRCS=$(wildcard *.c) + +OBJS=$(patsubst %.c,%.o,$(SRCS)) + +.PHONY: all clean + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + +%.o: %.c %.h + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJS) $(TARGET) diff --git a/utshell-0.5.0/variable/alias.h b/utshell-0.5.0/variable/alias.h new file mode 100644 index 00000000..2c7feda8 --- /dev/null +++ b/utshell-0.5.0/variable/alias.h @@ -0,0 +1,74 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* alias.h -- structure definitions. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_ALIAS_H_) +#define _ALIAS_H_ + +#include "stdc.h" + +#include "hashlib.h" + +typedef struct alias { + char *name; + char *value; + char flags; +} alias_t; + +/* Values for `flags' member of struct alias. */ +#define AL_EXPANDNEXT 0x1 +#define AL_BEINGEXPANDED 0x2 + +/* The list of known aliases. */ +extern HASH_TABLE *aliases; + +extern void initialize_aliases PARAMS((void)); + +/* Scan the list of aliases looking for one with NAME. Return NULL + if the alias doesn't exist, else a pointer to the alias. */ +extern alias_t *find_alias PARAMS((char *)); + +/* Return the value of the alias for NAME, or NULL if there is none. */ +extern char *get_alias_value PARAMS((char *)); + +/* Make a new alias from NAME and VALUE. If NAME can be found, + then replace its value. */ +extern void add_alias PARAMS((char *, char *)); + +/* Remove the alias with name NAME from the alias list. Returns + the index of the removed alias, or -1 if the alias didn't exist. */ +extern int remove_alias PARAMS((char *)); + +/* Remove all aliases. */ +extern void delete_all_aliases PARAMS((void)); + +/* Return an array of all defined aliases. */ +extern alias_t **all_aliases PARAMS((void)); + +/* Expand a single word for aliases. */ +extern char *alias_expand_word PARAMS((char *)); + +/* Return a new line, with any aliases expanded. */ +extern char *alias_expand PARAMS((char *)); + +/* Helper definition for the parser */ +extern void clear_string_list_expander PARAMS((alias_t *)); + +#endif /* _ALIAS_H_ */ diff --git a/utshell-0.5.0/variable/array.c b/utshell-0.5.0/variable/array.c new file mode 100644 index 00000000..4d5a53d8 --- /dev/null +++ b/utshell-0.5.0/variable/array.c @@ -0,0 +1,192 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* + * array.c - functions to create, destroy, access, and manipulate arrays + * of strings. + * + * Arrays are sparse doubly-linked lists. An element's index is stored + * with it. + * + * Chet Ramey + * chet@ins.cwru.edu + */ + +/* Copyright (C) 1997-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#if defined (ARRAY_VARS) + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include "bashansi.h" + +#include "shell.h" +#include "array.h" +#include "common.h" + +#define ADD_BEFORE(ae, new) \ + do { \ + ae->prev->next = new; \ + new->prev = ae->prev; \ + ae->prev = new; \ + new->next = ae; \ + } while(0) + +#define ADD_AFTER(ae, new) \ + do { \ + ae->next->prev = new; \ + new->next = ae->next; \ + new->prev = ae; \ + ae->next = new; \ + } while (0) + + + +#define IS_LASTREF(a) (a->lastref) + +#define LASTREF_START(a, i) \ + (IS_LASTREF(a) && i >= element_index(a->lastref)) ? a->lastref \ + : element_forw(a->head) + +#define LASTREF(a) (a->lastref ? a->lastref : element_forw(a->head)) + +#define INVALIDATE_LASTREF(a) a->lastref = 0 +#define SET_LASTREF(a, e) a->lastref = (e) +#define UNSET_LASTREF(a) a->lastref = 0; + +#if defined (TEST_ARRAY) +/* + * To make a running version, compile -DTEST_ARRAY and link with: + * xmalloc.o syntax.o lib/malloc/libmalloc.a lib/sh/libsh.a + */ +int interrupt_immediately = 0; + + +void +fatal_error(const char *s, ...) +{ + fprintf(stderr, "array_test: fatal memory error\n"); + abort(); +} + +void +programming_error(const char *s, ...) +{ + fprintf(stderr, "array_test: fatal programming error\n"); + abort(); +} + + +main() +{ + ARRAY *a, *new_a, *copy_of_a; + ARRAY_ELEMENT *ae, *aew; + char *s; + + a = array_create(); + array_insert(a, 1, "one"); + array_insert(a, 7, "seven"); + array_insert(a, 4, "four"); + array_insert(a, 1029, "one thousand twenty-nine"); + array_insert(a, 12, "twelve"); + array_insert(a, 42, "forty-two"); + print_array(a); + s = array_to_string (a, " ", 0); + printf("s = %s\n", s); + copy_of_a = array_from_string(s, " "); + printf("copy_of_a:"); + print_array(copy_of_a); + array_dispose(copy_of_a); + printf("\n"); + free(s); + ae = array_remove(a, 4); + array_dispose_element(ae); + ae = array_remove(a, 1029); + array_dispose_element(ae); + array_insert(a, 16, "sixteen"); + print_array(a); + s = array_to_string (a, " ", 0); + printf("s = %s\n", s); + copy_of_a = array_from_string(s, " "); + printf("copy_of_a:"); + print_array(copy_of_a); + array_dispose(copy_of_a); + printf("\n"); + free(s); + array_insert(a, 2, "two"); + array_insert(a, 1029, "new one thousand twenty-nine"); + array_insert(a, 0, "zero"); + array_insert(a, 134, ""); + print_array(a); + s = array_to_string (a, ":", 0); + printf("s = %s\n", s); + copy_of_a = array_from_string(s, ":"); + printf("copy_of_a:"); + print_array(copy_of_a); + array_dispose(copy_of_a); + printf("\n"); + free(s); + new_a = array_copy(a); + print_array(new_a); + s = array_to_string (new_a, ":", 0); + printf("s = %s\n", s); + copy_of_a = array_from_string(s, ":"); + free(s); + printf("copy_of_a:"); + print_array(copy_of_a); + array_shift(copy_of_a, 2, AS_DISPOSE); + printf("copy_of_a shifted by two:"); + print_array(copy_of_a); + ae = array_shift(copy_of_a, 2, 0); + printf("copy_of_a shifted by two:"); + print_array(copy_of_a); + for ( ; ae; ) { + aew = element_forw(ae); + array_dispose_element(ae); + ae = aew; + } + array_rshift(copy_of_a, 1, (char *)0); + printf("copy_of_a rshift by 1:"); + print_array(copy_of_a); + array_rshift(copy_of_a, 2, "new element zero"); + printf("copy_of_a rshift again by 2 with new element zero:"); + print_array(copy_of_a); + s = array_to_assign(copy_of_a, 0); + printf("copy_of_a=%s\n", s); + free(s); + ae = array_shift(copy_of_a, array_num_elements(copy_of_a), 0); + for ( ; ae; ) { + aew = element_forw(ae); + array_dispose_element(ae); + ae = aew; + } + array_dispose(copy_of_a); + printf("\n"); + array_dispose(a); + array_dispose(new_a); +} + +#endif /* TEST_ARRAY */ +#endif /* ARRAY_VARS */ diff --git a/utshell-0.5.0/variable/array.h b/utshell-0.5.0/variable/array.h new file mode 100644 index 00000000..8a0e00a2 --- /dev/null +++ b/utshell-0.5.0/variable/array.h @@ -0,0 +1,128 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* array.h -- definitions for the interface exported by array.c that allows + the rest of the shell to manipulate array variables. */ + +/* Copyright (C) 1997-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + + +#ifndef _ARRAY_H_ +#define _ARRAY_H_ + +#include "stdc.h" + +typedef intmax_t arrayind_t; + +enum atype {array_indexed, array_assoc}; /* only array_indexed used */ + +typedef struct array { + enum atype type; + arrayind_t max_index; + int num_elements; + struct array_element *head; + struct array_element *lastref; +} ARRAY; + +typedef struct array_element { + arrayind_t ind; + char *value; + struct array_element *next, *prev; +} ARRAY_ELEMENT; + +typedef int sh_ae_map_func_t PARAMS((ARRAY_ELEMENT *, void *)); + +/* Basic operations on entire arrays */ +extern ARRAY *array_create PARAMS((void)); +extern void array_flush PARAMS((ARRAY *)); +extern void array_dispose PARAMS((ARRAY *)); +extern ARRAY *array_copy PARAMS((ARRAY *)); +extern ARRAY *array_slice PARAMS((ARRAY *, ARRAY_ELEMENT *, ARRAY_ELEMENT *)); +extern void array_walk PARAMS((ARRAY *, sh_ae_map_func_t *, void *)); + +extern ARRAY_ELEMENT *array_shift PARAMS((ARRAY *, int, int)); +extern int array_rshift PARAMS((ARRAY *, int, char *)); +extern ARRAY_ELEMENT *array_unshift_element PARAMS((ARRAY *)); +extern int array_shift_element PARAMS((ARRAY *, char *)); + +extern ARRAY *array_quote PARAMS((ARRAY *)); +extern ARRAY *array_quote_escapes PARAMS((ARRAY *)); +extern ARRAY *array_dequote PARAMS((ARRAY *)); +extern ARRAY *array_dequote_escapes PARAMS((ARRAY *)); +extern ARRAY *array_remove_quoted_nulls PARAMS((ARRAY *)); + +extern char *array_subrange PARAMS((ARRAY *, arrayind_t, arrayind_t, int, int, int)); +extern char *array_patsub PARAMS((ARRAY *, char *, char *, int)); +extern char *array_modcase PARAMS((ARRAY *, char *, int, int)); + +/* Basic operations on array elements. */ +extern ARRAY_ELEMENT *array_create_element PARAMS((arrayind_t, char *)); +extern ARRAY_ELEMENT *array_copy_element PARAMS((ARRAY_ELEMENT *)); +extern void array_dispose_element PARAMS((ARRAY_ELEMENT *)); + +extern int array_insert PARAMS((ARRAY *, arrayind_t, char *)); +extern ARRAY_ELEMENT *array_remove PARAMS((ARRAY *, arrayind_t)); +extern char *array_reference PARAMS((ARRAY *, arrayind_t)); + +/* Converting to and from arrays */ +extern WORD_LIST *array_to_word_list PARAMS((ARRAY *)); +extern ARRAY *array_from_word_list PARAMS((WORD_LIST *)); +extern WORD_LIST *array_keys_to_word_list PARAMS((ARRAY *)); + +extern ARRAY *array_assign_list PARAMS((ARRAY *, WORD_LIST *)); + +extern char **array_to_argv PARAMS((ARRAY *, int *)); + +extern char *array_to_kvpair PARAMS((ARRAY *, int)); +extern char *array_to_assign PARAMS((ARRAY *, int)); +extern char *array_to_string PARAMS((ARRAY *, char *, int)); +extern ARRAY *array_from_string PARAMS((char *, char *)); + +/* Flags for array_shift */ +#define AS_DISPOSE 0x01 + +#define array_num_elements(a) ((a)->num_elements) +#define array_max_index(a) ((a)->max_index) +#define array_first_index(a) ((a)->head->next->ind) +#define array_head(a) ((a)->head) +#define array_empty(a) ((a)->num_elements == 0) + +#define element_value(ae) ((ae)->value) +#define element_index(ae) ((ae)->ind) +#define element_forw(ae) ((ae)->next) +#define element_back(ae) ((ae)->prev) + +#define set_element_value(ae, val) ((ae)->value = (val)) + +/* Convenience */ +#define array_push(a,v) \ + do { array_rshift ((a), 1, (v)); } while (0) +#define array_pop(a) \ + do { array_dispose_element (array_shift ((a), 1, 0)); } while (0) + +#define GET_ARRAY_FROM_VAR(n, v, a) \ + do { \ + (v) = find_variable (n); \ + (a) = ((v) && array_p ((v))) ? array_cell (v) : (ARRAY *)0; \ + } while (0) + +#define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*') + +/* In eval.c, but uses ARRAY * */ +extern int execute_array_command PARAMS((ARRAY *, void *)); + +#endif /* _ARRAY_H_ */ diff --git a/utshell-0.5.0/variable/arrayfunc.h b/utshell-0.5.0/variable/arrayfunc.h new file mode 100644 index 00000000..2420ccf9 --- /dev/null +++ b/utshell-0.5.0/variable/arrayfunc.h @@ -0,0 +1,101 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* arrayfunc.h -- declarations for miscellaneous array functions in arrayfunc.c */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_ARRAYFUNC_H_) +#define _ARRAYFUNC_H_ + +/* Must include variables.h before including this file. */ + +#if defined (ARRAY_VARS) + +/* This variable means to not expand associative array subscripts more than + once, when performing variable expansion. */ +extern int assoc_expand_once; + +/* The analog for indexed array subscripts */ +extern int array_expand_once; + +/* Flags for array_value_internal and callers array_value/get_array_value */ +#define AV_ALLOWALL 0x001 +#define AV_QUOTED 0x002 +#define AV_USEIND 0x004 +#define AV_USEVAL 0x008 /* XXX - should move this */ +#define AV_ASSIGNRHS 0x010 /* no splitting, special case ${a[@]} */ +#define AV_NOEXPAND 0x020 /* don't run assoc subscripts through word expansion */ + +/* Flags for valid_array_reference. Value 1 is reserved for skipsubscript() */ +#define VA_NOEXPAND 0x001 +#define VA_ONEWORD 0x002 + +extern SHELL_VAR *convert_var_to_array PARAMS((SHELL_VAR *)); +extern SHELL_VAR *convert_var_to_assoc PARAMS((SHELL_VAR *)); + +extern char *make_array_variable_value PARAMS((SHELL_VAR *, arrayind_t, char *, char *, int)); + +extern SHELL_VAR *bind_array_variable PARAMS((char *, arrayind_t, char *, int)); +extern SHELL_VAR *bind_array_element PARAMS((SHELL_VAR *, arrayind_t, char *, int)); +extern SHELL_VAR *assign_array_element PARAMS((char *, char *, int)); + +extern SHELL_VAR *bind_assoc_variable PARAMS((SHELL_VAR *, char *, char *, char *, int)); + +extern SHELL_VAR *find_or_make_array_variable PARAMS((char *, int)); + +extern SHELL_VAR *assign_array_from_string PARAMS((char *, char *, int)); +extern SHELL_VAR *assign_array_var_from_word_list PARAMS((SHELL_VAR *, WORD_LIST *, int)); + +extern WORD_LIST *expand_compound_array_assignment PARAMS((SHELL_VAR *, char *, int)); +extern void assign_compound_array_list PARAMS((SHELL_VAR *, WORD_LIST *, int)); +extern SHELL_VAR *assign_array_var_from_string PARAMS((SHELL_VAR *, char *, int)); + +extern char *expand_and_quote_assoc_word PARAMS((char *, int)); +extern void quote_compound_array_list PARAMS((WORD_LIST *, int)); + +extern int kvpair_assignment_p PARAMS((WORD_LIST *)); +extern char *expand_and_quote_kvpair_word PARAMS((char *)); + +extern int unbind_array_element PARAMS((SHELL_VAR *, char *, int)); +extern int skipsubscript PARAMS((const char *, int, int)); + +extern void print_array_assignment PARAMS((SHELL_VAR *, int)); +extern void print_assoc_assignment PARAMS((SHELL_VAR *, int)); + +extern arrayind_t array_expand_index PARAMS((SHELL_VAR *, char *, int, int)); +extern int valid_array_reference PARAMS((const char *, int)); +extern char *array_value PARAMS((const char *, int, int, int *, arrayind_t *)); +extern char *get_array_value PARAMS((const char *, int, int *, arrayind_t *)); + +extern char *array_keys PARAMS((char *, int, int)); + +extern char *array_variable_name PARAMS((const char *, int, char **, int *)); +extern SHELL_VAR *array_variable_part PARAMS((const char *, int, char **, int *)); + +#else + +#define AV_ALLOWALL 0 +#define AV_QUOTED 0 +#define AV_USEIND 0 +#define AV_ASSIGNRHS 0 + +#define VA_ONEWORD 0 + +#endif + +#endif /* !_ARRAYFUNC_H_ */ diff --git a/utshell-0.5.0/variable/assoc.h b/utshell-0.5.0/variable/assoc.h new file mode 100644 index 00000000..7143836f --- /dev/null +++ b/utshell-0.5.0/variable/assoc.h @@ -0,0 +1,66 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* assoc.h -- definitions for the interface exported by assoc.c that allows + the rest of the shell to manipulate associative array variables. */ + +/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _ASSOC_H_ +#define _ASSOC_H_ + +#include "stdc.h" +#include "hashlib.h" + +#define ASSOC_HASH_BUCKETS 1024 + +#define assoc_empty(h) ((h)->nentries == 0) +#define assoc_num_elements(h) ((h)->nentries) + +#define assoc_create(n) (hash_create((n))) + +#define assoc_copy(h) (hash_copy((h), 0)) + +#define assoc_walk(h, f) (hash_walk((h), (f)) + +extern void assoc_dispose PARAMS((HASH_TABLE *)); +extern void assoc_flush PARAMS((HASH_TABLE *)); + +extern int assoc_insert PARAMS((HASH_TABLE *, char *, char *)); +extern PTR_T assoc_replace PARAMS((HASH_TABLE *, char *, char *)); +extern void assoc_remove PARAMS((HASH_TABLE *, char *)); + +extern char *assoc_reference PARAMS((HASH_TABLE *, char *)); + +extern char *assoc_subrange PARAMS((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int)); +extern char *assoc_patsub PARAMS((HASH_TABLE *, char *, char *, int)); +extern char *assoc_modcase PARAMS((HASH_TABLE *, char *, int, int)); + +extern HASH_TABLE *assoc_quote PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_quote_escapes PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_dequote PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_dequote_escapes PARAMS((HASH_TABLE *)); +extern HASH_TABLE *assoc_remove_quoted_nulls PARAMS((HASH_TABLE *)); + +extern char *assoc_to_kvpair PARAMS((HASH_TABLE *, int)); +extern char *assoc_to_assign PARAMS((HASH_TABLE *, int)); + +extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *)); +extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *)); + +extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int)); +#endif /* _ASSOC_H_ */ diff --git a/utshell-0.5.0/variable/bashansi.h b/utshell-0.5.0/variable/bashansi.h new file mode 100644 index 00000000..7c55a631 --- /dev/null +++ b/utshell-0.5.0/variable/bashansi.h @@ -0,0 +1,42 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashansi.h -- Typically included information required by picky compilers. */ + +/* Copyright (C) 1993-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHANSI_H_) +#define _BASHANSI_H_ + +#if defined (HAVE_STRING_H) +# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H) +# include +# endif +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STRINGS_H) +# include +#endif /* !HAVE_STRINGS_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "stdlib.h" +#endif /* !HAVE_STDLIB_H */ + +#endif /* !_BASHANSI_H_ */ diff --git a/utshell-0.5.0/variable/bashgetopt.h b/utshell-0.5.0/variable/bashgetopt.h new file mode 100644 index 00000000..fb8bf0d6 --- /dev/null +++ b/utshell-0.5.0/variable/bashgetopt.h @@ -0,0 +1,42 @@ +/* bashgetopt.h -- extern declarations for stuff defined in bashgetopt.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* See getopt.h for the explanation of these variables. */ + +#if !defined (__BASH_GETOPT_H) +# define __BASH_GETOPT_H + +#include "stdc.h" + +#define GETOPT_EOF -1 +#define GETOPT_HELP -99 + +extern char *list_optarg; + +extern int list_optopt; +extern int list_opttype; + +extern WORD_LIST *lcurrent; +extern WORD_LIST *loptend; + +extern int internal_getopt PARAMS((WORD_LIST *, char *)); +extern void reset_internal_getopt PARAMS((void)); + +#endif /* !__BASH_GETOPT_H */ diff --git a/utshell-0.5.0/variable/bashhist.h b/utshell-0.5.0/variable/bashhist.h new file mode 100644 index 00000000..3f71639a --- /dev/null +++ b/utshell-0.5.0/variable/bashhist.h @@ -0,0 +1,90 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashhist.h -- interface to the bash history functions in bashhist.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHHIST_H_) +#define _BASHHIST_H_ + +#include "stdc.h" + +/* Flag values for history_control */ +#define HC_IGNSPACE 0x01 +#define HC_IGNDUPS 0x02 +#define HC_ERASEDUPS 0x04 + +#define HC_IGNBOTH (HC_IGNSPACE|HC_IGNDUPS) + +#if defined (STRICT_POSIX) +# undef HISTEXPAND_DEFAULT +# define HISTEXPAND_DEFAULT 0 +#else +# if !defined (HISTEXPAND_DEFAULT) +# define HISTEXPAND_DEFAULT 1 +# endif /* !HISTEXPAND_DEFAULT */ +#endif + +extern int remember_on_history; +extern int enable_history_list; /* value for `set -o history' */ +extern int literal_history; /* controlled by `shopt lithist' */ +extern int force_append_history; +extern int history_lines_this_session; +extern int history_lines_in_file; +extern int history_expansion; +extern int history_control; +extern int command_oriented_history; +extern int current_command_first_line_saved; +extern int current_command_first_line_comment; +extern int hist_last_line_added; +extern int hist_last_line_pushed; + +extern int dont_save_function_defs; + +# if defined (READLINE) +extern int hist_verify; +# endif + +# if defined (BANG_HISTORY) +extern int history_expansion_inhibited; +extern int double_quotes_inhibit_history_expansion; +# endif /* BANG_HISTORY */ + +extern void bash_initialize_history PARAMS((void)); +extern void bash_history_reinit PARAMS((int)); +extern void bash_history_disable PARAMS((void)); +extern void bash_history_enable PARAMS((void)); +extern void bash_clear_history PARAMS((void)); +extern int bash_delete_histent PARAMS((int)); +extern int bash_delete_history_range PARAMS((int, int)); +extern int bash_delete_last_history PARAMS((void)); +extern void load_history PARAMS((void)); +extern void save_history PARAMS((void)); +extern int maybe_append_history PARAMS((char *)); +extern int maybe_save_shell_history PARAMS((void)); +extern char *pre_process_line PARAMS((char *, int, int)); +extern void maybe_add_history PARAMS((char *)); +extern void bash_add_history PARAMS((char *)); +extern int check_add_history PARAMS((char *, int)); +extern int history_number PARAMS((void)); + +extern void setup_history_ignore PARAMS((char *)); + +extern char *last_history_line PARAMS((void)); + +#endif /* _BASHHIST_H_ */ diff --git a/utshell-0.5.0/variable/bashintl.h b/utshell-0.5.0/variable/bashintl.h new file mode 100644 index 00000000..90810cbe --- /dev/null +++ b/utshell-0.5.0/variable/bashintl.h @@ -0,0 +1,55 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashintl.h -- Internationalization functions and defines. */ + +/* Copyright (C) 1996-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHINTL_H_) +#define _BASHINTL_H_ + +#if defined (BUILDTOOL) +# undef ENABLE_NLS +# define ENABLE_NLS 0 +#endif + +/* Include this *after* config.h */ +#include "gettext.h" + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#define _(msgid) gettext(msgid) +#define N_(msgid) msgid +#define D_(d, msgid) dgettext(d, msgid) + +#define P_(m1, m2, n) ngettext(m1, m2, n) + +#if defined (HAVE_SETLOCALE) && !defined (LC_ALL) +# undef HAVE_SETLOCALE +#endif + +#if !defined (HAVE_SETLOCALE) +# define setlocale(cat, loc) +#endif + +#if !defined (HAVE_LOCALE_H) || !defined (HAVE_LOCALECONV) +# define locale_decpoint() '.' +#endif + +#endif /* !_BASHINTL_H_ */ diff --git a/utshell-0.5.0/variable/bashjmp.h b/utshell-0.5.0/variable/bashjmp.h new file mode 100644 index 00000000..bfcf102f --- /dev/null +++ b/utshell-0.5.0/variable/bashjmp.h @@ -0,0 +1,47 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashjmp.h -- wrapper for setjmp.h with necessary bash definitions. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _BASHJMP_H_ +#define _BASHJMP_H_ + +#include "posixjmp.h" + +extern procenv_t top_level; +extern procenv_t subshell_top_level; +extern procenv_t return_catch; /* used by `return' builtin */ +extern procenv_t wait_intr_buf; + +extern int no_longjmp_on_fatal_error; + +#define SHFUNC_RETURN() sh_longjmp (return_catch, 1) + +#define COPY_PROCENV(old, save) \ + xbcopy ((char *)old, (char *)save, sizeof (procenv_t)); + +/* Values for the second argument to longjmp/siglongjmp. */ +#define NOT_JUMPED 0 /* Not returning from a longjmp. */ +#define FORCE_EOF 1 /* We want to stop parsing. */ +#define DISCARD 2 /* Discard current command. */ +#define EXITPROG 3 /* Unconditionally exit the program now. */ +#define ERREXIT 4 /* Exit due to error condition */ +#define SIGEXIT 5 /* Exit due to fatal terminating signal */ + +#endif /* _BASHJMP_H_ */ diff --git a/utshell-0.5.0/variable/bashline.h b/utshell-0.5.0/variable/bashline.h new file mode 100644 index 00000000..1a4b88b5 --- /dev/null +++ b/utshell-0.5.0/variable/bashline.h @@ -0,0 +1,70 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashline.h -- interface to the bash readline functions in bashline.c. */ + +/* Copyright (C) 1993-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHLINE_H_) +#define _BASHLINE_H_ + +#include "stdc.h" + +extern int bash_readline_initialized; +extern int hostname_list_initialized; + +/* these are controlled via shopt */ +extern int perform_hostname_completion; +extern int no_empty_command_completion; +extern int force_fignore; +extern int dircomplete_spelling; +extern int dircomplete_expand; +extern int dircomplete_expand_relpath; +extern int complete_fullquote; + +extern void posix_readline_initialize PARAMS((int)); +extern void reset_completer_word_break_chars PARAMS((void)); +extern int enable_hostname_completion PARAMS((int)); +extern void initialize_readline PARAMS((void)); +extern void bashline_reset PARAMS((void)); +extern void bashline_reinitialize PARAMS((void)); +extern int bash_re_edit PARAMS((char *)); + +extern void bashline_set_event_hook PARAMS((void)); +extern void bashline_reset_event_hook PARAMS((void)); + +extern int bind_keyseq_to_unix_command PARAMS((char *)); +extern int bash_execute_unix_command PARAMS((int, int)); +extern int print_unix_command_map PARAMS((void)); +extern int unbind_unix_command PARAMS((char *)); + +extern char **bash_default_completion PARAMS((const char *, int, int, int, int)); + +void set_directory_hook PARAMS((void)); + +/* Used by programmable completion code. */ +extern char *command_word_completion_function PARAMS((const char *, int)); +extern char *bash_groupname_completion_function PARAMS((const char *, int)); +extern char *bash_servicename_completion_function PARAMS((const char *, int)); + +extern char **get_hostname_list PARAMS((void)); +extern void clear_hostname_list PARAMS((void)); + +extern char **bash_directory_completion_matches PARAMS((const char *)); +extern char *bash_dequote_text PARAMS((const char *)); + +#endif /* _BASHLINE_H_ */ diff --git a/utshell-0.5.0/variable/bashtypes.h b/utshell-0.5.0/variable/bashtypes.h new file mode 100644 index 00000000..33eda19a --- /dev/null +++ b/utshell-0.5.0/variable/bashtypes.h @@ -0,0 +1,43 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* bashtypes.h -- Bash system types. */ + +/* Copyright (C) 1993-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_BASHTYPES_H_) +# define _BASHTYPES_H_ + +#if defined (CRAY) +# define word __word +#endif + +#include + +#if defined (CRAY) +# undef word +#endif + +#if defined (HAVE_INTTYPES_H) +# include +#endif + +#if HAVE_STDINT_H +# include +#endif + +#endif /* _BASHTYPES_H_ */ diff --git a/utshell-0.5.0/variable/builtext.h b/utshell-0.5.0/variable/builtext.h new file mode 100644 index 00000000..a7723fa1 --- /dev/null +++ b/utshell-0.5.0/variable/builtext.h @@ -0,0 +1,188 @@ +/* builtext.h - The list of builtins found in libbuiltins.a. */ +#if defined (ALIAS) +extern int alias_builtin PARAMS((WORD_LIST *)); +extern char * const alias_doc[]; +#endif /* ALIAS */ +#if defined (ALIAS) +extern int unalias_builtin PARAMS((WORD_LIST *)); +extern char * const unalias_doc[]; +#endif /* ALIAS */ +#if defined (READLINE) +extern int bind_builtin PARAMS((WORD_LIST *)); +extern char * const bind_doc[]; +#endif /* READLINE */ +extern int break_builtin PARAMS((WORD_LIST *)); +extern char * const break_doc[]; +extern int continue_builtin PARAMS((WORD_LIST *)); +extern char * const continue_doc[]; +extern int builtin_builtin PARAMS((WORD_LIST *)); +extern char * const builtin_doc[]; +#if defined (DEBUGGER) +extern int caller_builtin PARAMS((WORD_LIST *)); +extern char * const caller_doc[]; +#endif /* DEBUGGER */ +extern int cd_builtin PARAMS((WORD_LIST *)); +extern char * const cd_doc[]; +extern int pwd_builtin PARAMS((WORD_LIST *)); +extern char * const pwd_doc[]; +extern int colon_builtin PARAMS((WORD_LIST *)); +extern char * const colon_doc[]; +extern int colon_builtin PARAMS((WORD_LIST *)); +extern char * const true_doc[]; +extern int false_builtin PARAMS((WORD_LIST *)); +extern char * const false_doc[]; +extern int command_builtin PARAMS((WORD_LIST *)); +extern char * const command_doc[]; +extern int declare_builtin PARAMS((WORD_LIST *)); +extern char * const declare_doc[]; +extern int declare_builtin PARAMS((WORD_LIST *)); +extern char * const typeset_doc[]; +extern int local_builtin PARAMS((WORD_LIST *)); +extern char * const local_doc[]; +#if defined (V9_ECHO) +extern int echo_builtin PARAMS((WORD_LIST *)); +extern char * const echo_doc[]; +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) +extern int echo_builtin PARAMS((WORD_LIST *)); +extern char * const echo_doc[]; +#endif /* !V9_ECHO */ +extern int enable_builtin PARAMS((WORD_LIST *)); +extern char * const enable_doc[]; +extern int eval_builtin PARAMS((WORD_LIST *)); +extern char * const eval_doc[]; +extern int getopts_builtin PARAMS((WORD_LIST *)); +extern char * const getopts_doc[]; +extern int exec_builtin PARAMS((WORD_LIST *)); +extern char * const exec_doc[]; +extern int exit_builtin PARAMS((WORD_LIST *)); +extern char * const exit_doc[]; +extern int logout_builtin PARAMS((WORD_LIST *)); +extern char * const logout_doc[]; +#if defined (HISTORY) +extern int fc_builtin PARAMS((WORD_LIST *)); +extern char * const fc_doc[]; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +extern int fg_builtin PARAMS((WORD_LIST *)); +extern char * const fg_doc[]; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +extern int bg_builtin PARAMS((WORD_LIST *)); +extern char * const bg_doc[]; +#endif /* JOB_CONTROL */ +extern int hash_builtin PARAMS((WORD_LIST *)); +extern char * const hash_doc[]; +#if defined (HELP_BUILTIN) +extern int help_builtin PARAMS((WORD_LIST *)); +extern char * const help_doc[]; +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) +extern int history_builtin PARAMS((WORD_LIST *)); +extern char * const history_doc[]; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +extern int jobs_builtin PARAMS((WORD_LIST *)); +extern char * const jobs_doc[]; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +extern int disown_builtin PARAMS((WORD_LIST *)); +extern char * const disown_doc[]; +#endif /* JOB_CONTROL */ +extern int kill_builtin PARAMS((WORD_LIST *)); +extern char * const kill_doc[]; +extern int let_builtin PARAMS((WORD_LIST *)); +extern char * const let_doc[]; +extern int read_builtin PARAMS((WORD_LIST *)); +extern char * const read_doc[]; +extern int return_builtin PARAMS((WORD_LIST *)); +extern char * const return_doc[]; +extern int set_builtin PARAMS((WORD_LIST *)); +extern char * const set_doc[]; +extern int unset_builtin PARAMS((WORD_LIST *)); +extern char * const unset_doc[]; +extern int export_builtin PARAMS((WORD_LIST *)); +extern char * const export_doc[]; +extern int readonly_builtin PARAMS((WORD_LIST *)); +extern char * const readonly_doc[]; +extern int shift_builtin PARAMS((WORD_LIST *)); +extern char * const shift_doc[]; +extern int source_builtin PARAMS((WORD_LIST *)); +extern char * const source_doc[]; +extern int source_builtin PARAMS((WORD_LIST *)); +extern char * const dot_doc[]; +#if defined (JOB_CONTROL) +extern int suspend_builtin PARAMS((WORD_LIST *)); +extern char * const suspend_doc[]; +#endif /* JOB_CONTROL */ +extern int test_builtin PARAMS((WORD_LIST *)); +extern char * const test_doc[]; +extern int test_builtin PARAMS((WORD_LIST *)); +extern char * const test_bracket_doc[]; +extern int times_builtin PARAMS((WORD_LIST *)); +extern char * const times_doc[]; +extern int trap_builtin PARAMS((WORD_LIST *)); +extern char * const trap_doc[]; +extern int type_builtin PARAMS((WORD_LIST *)); +extern char * const type_doc[]; +#if !defined (_MINIX) +extern int ulimit_builtin PARAMS((WORD_LIST *)); +extern char * const ulimit_doc[]; +#endif /* !_MINIX */ +extern int umask_builtin PARAMS((WORD_LIST *)); +extern char * const umask_doc[]; +#if defined (JOB_CONTROL) +extern int wait_builtin PARAMS((WORD_LIST *)); +extern char * const wait_doc[]; +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) +extern int wait_builtin PARAMS((WORD_LIST *)); +extern char * const wait_doc[]; +#endif /* !JOB_CONTROL */ +extern char * const for_doc[]; +extern char * const arith_for_doc[]; +extern char * const select_doc[]; +extern char * const time_doc[]; +extern char * const case_doc[]; +extern char * const if_doc[]; +extern char * const while_doc[]; +extern char * const until_doc[]; +extern char * const coproc_doc[]; +extern char * const function_doc[]; +extern char * const grouping_braces_doc[]; +extern char * const fg_percent_doc[]; +extern char * const arith_doc[]; +extern char * const conditional_doc[]; +extern char * const variable_help_doc[]; +#if defined (PUSHD_AND_POPD) +extern int pushd_builtin PARAMS((WORD_LIST *)); +extern char * const pushd_doc[]; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +extern int popd_builtin PARAMS((WORD_LIST *)); +extern char * const popd_doc[]; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +extern int dirs_builtin PARAMS((WORD_LIST *)); +extern char * const dirs_doc[]; +#endif /* PUSHD_AND_POPD */ +extern int shopt_builtin PARAMS((WORD_LIST *)); +extern char * const shopt_doc[]; +extern int printf_builtin PARAMS((WORD_LIST *)); +extern char * const printf_doc[]; +#if defined (PROGRAMMABLE_COMPLETION) +extern int complete_builtin PARAMS((WORD_LIST *)); +extern char * const complete_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +extern int compgen_builtin PARAMS((WORD_LIST *)); +extern char * const compgen_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +extern int compopt_builtin PARAMS((WORD_LIST *)); +extern char * const compopt_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +extern int mapfile_builtin PARAMS((WORD_LIST *)); +extern char * const mapfile_doc[]; +extern int mapfile_builtin PARAMS((WORD_LIST *)); +extern char * const readarray_doc[]; diff --git a/utshell-0.5.0/variable/builtins.h b/utshell-0.5.0/variable/builtins.h new file mode 100644 index 00000000..f57437bb --- /dev/null +++ b/utshell-0.5.0/variable/builtins.h @@ -0,0 +1,69 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* builtins.h -- What a builtin looks like, and where to find them. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef BUILTINS_H +#define BUILTINS_H + +#include "config.h" + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "command.h" +#include "general.h" + +#if defined (ALIAS) +#include "alias.h" +#endif + +/* Flags describing various things about a builtin. */ +#define BUILTIN_ENABLED 0x01 /* This builtin is enabled. */ +#define BUILTIN_DELETED 0x02 /* This has been deleted with enable -d. */ +#define STATIC_BUILTIN 0x04 /* This builtin is not dynamically loaded. */ +#define SPECIAL_BUILTIN 0x08 /* This is a Posix `special' builtin. */ +#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ +#define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */ +#define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */ +#define REQUIRES_BUILTIN 0x80 /* This builtin requires other files. */ + +#define BASE_INDENT 4 + +/* The thing that we build the array of builtins out of. */ +struct builtin { + char *name; /* The name that the user types. */ + sh_builtin_func_t *function; /* The address of the invoked function. */ + int flags; /* One of the #defines above. */ + char * const *long_doc; /* NULL terminated array of strings. */ + const char *short_doc; /* Short version of documentation. */ + char *handle; /* for future use */ +}; + +/* Found in builtins.c, created by builtins/mkbuiltins. */ +extern int num_shell_builtins; /* Number of shell builtins. */ +extern struct builtin static_shell_builtins[]; +extern struct builtin *shell_builtins; +extern struct builtin *current_builtin; + +#endif /* BUILTINS_H */ diff --git a/utshell-0.5.0/variable/chardefs.h b/utshell-0.5.0/variable/chardefs.h new file mode 100644 index 00000000..3cf1326a --- /dev/null +++ b/utshell-0.5.0/variable/chardefs.h @@ -0,0 +1,164 @@ +/* chardefs.h -- Character definitions for readline. */ + +/* Copyright (C) 1994-2015 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#ifndef _CHARDEFS_H_ +#define _CHARDEFS_H_ + +#include + +#if defined (HAVE_CONFIG_H) +# if defined (HAVE_STRING_H) +# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H) +# include +# endif +# include +# endif /* HAVE_STRING_H */ +# if defined (HAVE_STRINGS_H) +# include +# endif /* HAVE_STRINGS_H */ +#else +# include +#endif /* !HAVE_CONFIG_H */ + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifdef CTRL +# undef CTRL +#endif +#ifdef UNCTRL +# undef UNCTRL +#endif + +/* Some character stuff. */ +#define control_character_threshold 0x020 /* Smaller than this is control. */ +#define control_character_mask 0x1f /* 0x20 - 1 */ +#define meta_character_threshold 0x07f /* Larger than this is Meta. */ +#define control_character_bit 0x40 /* 0x000000, must be off. */ +#define meta_character_bit 0x080 /* x0000000, must be on. */ +#define largest_char 255 /* Largest character value. */ + +#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) +#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) + +#define CTRL(c) ((c) & control_character_mask) +#define META(c) ((c) | meta_character_bit) + +#define UNMETA(c) ((c) & (~meta_character_bit)) +#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit)) + +#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII)) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus) +# define isxdigit(c) (isdigit((unsigned char)(c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#if defined (CTYPE_NON_ASCII) +# define NON_NEGATIVE(c) 1 +#else +# define NON_NEGATIVE(c) ((unsigned char)(c) == (c)) +#endif + +/* Some systems define these; we want our definitions. */ +#undef ISPRINT + +/* Beware: these only work with single-byte ASCII characters. */ + +#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c)) +#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c)) +#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c)) +#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c)) +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c)) +#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c)) + +#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c)) +#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c)) +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') + +#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c)) +#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c)) + +#ifndef _rl_to_upper +# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c)) +# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c)) +#endif + +#ifndef _rl_digit_value +# define _rl_digit_value(x) ((x) - '0') +#endif + +#ifndef _rl_isident +# define _rl_isident(c) (ISALNUM(c) || (c) == '_') +#endif + +#ifndef ISOCTAL +# define ISOCTAL(c) ((c) >= '0' && (c) <= '7') +#endif +#define OCTVALUE(c) ((c) - '0') + +#define HEXVALUE(c) \ + (((c) >= 'a' && (c) <= 'f') \ + ? (c)-'a'+10 \ + : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') + +#ifndef NEWLINE +#define NEWLINE '\n' +#endif + +#ifndef RETURN +#define RETURN CTRL('M') +#endif + +#ifndef RUBOUT +#define RUBOUT 0x7f +#endif + +#ifndef TAB +#define TAB '\t' +#endif + +#ifdef ABORT_CHAR +#undef ABORT_CHAR +#endif +#define ABORT_CHAR CTRL('G') + +#ifdef PAGE +#undef PAGE +#endif +#define PAGE CTRL('L') + +#ifdef SPACE +#undef SPACE +#endif +#define SPACE ' ' /* XXX - was 0x20 */ + +#ifdef ESC +#undef ESC +#endif +#define ESC CTRL('[') + +#endif /* _CHARDEFS_H_ */ diff --git a/utshell-0.5.0/variable/chartypes.h b/utshell-0.5.0/variable/chartypes.h new file mode 100644 index 00000000..098cfb96 --- /dev/null +++ b/utshell-0.5.0/variable/chartypes.h @@ -0,0 +1,113 @@ +/* chartypes.h -- extend ctype.h */ + +/* Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _SH_CHARTYPES_H +#define _SH_CHARTYPES_H + +#include + +/* Jim Meyering writes: + + "... Some ctype macros are valid only for character codes that + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when + using /bin/cc or gcc but without giving an ansi option). So, all + ctype uses should be through macros like ISPRINT... If + STDC_HEADERS is defined, then autoconf has verified that the ctype + macros don't need to be guarded with references to isascii. ... + Defining IN_CTYPE_DOMAIN to 1 should let any compiler worth its salt + eliminate the && through constant folding." + Solaris defines some of these symbols so we must undefine them first. */ + +#if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#if !defined (isspace) && !defined (HAVE_ISSPACE) +# define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f') +#endif + +#if !defined (isprint) && !defined (HAVE_ISPRINT) +# define isprint(c) (isalpha((unsigned char)c) || isdigit((unsigned char)c) || ispunct((unsigned char)c)) +#endif + +#if defined (isblank) || defined (HAVE_ISBLANK) +# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank ((unsigned char)c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif + +#if defined (isgraph) || defined (HAVE_ISGRAPH) +# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c)) +#else +# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c) && !isspace ((unsigned char)c)) +#endif + +#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) +# define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#undef ISPRINT + +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c)) +#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c)) +#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c)) +#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c)) +#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char)c)) +#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c)) +#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct ((unsigned char)c)) +#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char)c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c)) +#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c)) + +#define ISLETTER(c) (ISALPHA(c)) + +#define DIGIT(c) ((c) >= '0' && (c) <= '9') + +#define ISWORD(c) (ISLETTER(c) || DIGIT(c) || ((c) == '_')) + +#define HEXVALUE(c) \ + (((c) >= 'a' && (c) <= 'f') \ + ? (c)-'a'+10 \ + : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') + +#ifndef ISOCTAL +# define ISOCTAL(c) ((c) >= '0' && (c) <= '7') +#endif +#define OCTVALUE(c) ((c) - '0') + +#define TODIGIT(c) ((c) - '0') +#define TOCHAR(c) ((c) + '0') + +#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c)) +#define TOUPPER(c) (ISLOWER(c) ? toupper(c) : (c)) + +#ifndef TOCTRL + /* letter to control char -- ASCII. The TOUPPER is in there so \ce and + \cE will map to the same character in $'...' expansions. */ +# define TOCTRL(x) ((x) == '?' ? 0x7f : (TOUPPER(x) & 0x1f)) +#endif +#ifndef UNCTRL + /* control char to letter -- ASCII */ +# define UNCTRL(x) (TOUPPER(x) ^ 0x40) +#endif + +#endif /* _SH_CHARTYPES_H */ diff --git a/utshell-0.5.0/variable/command.h b/utshell-0.5.0/variable/command.h new file mode 100644 index 00000000..6dc337fb --- /dev/null +++ b/utshell-0.5.0/variable/command.h @@ -0,0 +1,409 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* command.h -- The structures used internally to represent commands, and + the extern declarations of the functions used to create them. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_COMMAND_H_) +#define _COMMAND_H_ + +#include "stdc.h" + +/* Instructions describing what kind of thing to do for a redirection. */ +enum r_instruction { + r_output_direction, r_input_direction, r_inputa_direction, + r_appending_to, r_reading_until, r_reading_string, + r_duplicating_input, r_duplicating_output, r_deblank_reading_until, + r_close_this, r_err_and_out, r_input_output, r_output_force, + r_duplicating_input_word, r_duplicating_output_word, + r_move_input, r_move_output, r_move_input_word, r_move_output_word, + r_append_err_and_out +}; + +/* Redirection flags; values for rflags */ +#define REDIR_VARASSIGN 0x01 + +/* Redirection errors. */ +#define AMBIGUOUS_REDIRECT -1 +#define NOCLOBBER_REDIRECT -2 +#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */ +#define HEREDOC_REDIRECT -4 /* here-doc temp file can't be created */ +#define BADVAR_REDIRECT -5 /* something wrong with {varname}redir */ + +#define CLOBBERING_REDIRECT(ri) \ + (ri == r_output_direction || ri == r_err_and_out) + +#define OUTPUT_REDIRECT(ri) \ + (ri == r_output_direction || ri == r_input_output || ri == r_err_and_out || ri == r_append_err_and_out) + +#define INPUT_REDIRECT(ri) \ + (ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output) + +#define WRITE_REDIRECT(ri) \ + (ri == r_output_direction || \ + ri == r_input_output || \ + ri == r_err_and_out || \ + ri == r_appending_to || \ + ri == r_append_err_and_out || \ + ri == r_output_force) + +/* redirection needs translation */ +#define TRANSLATE_REDIRECT(ri) \ + (ri == r_duplicating_input_word || ri == r_duplicating_output_word || \ + ri == r_move_input_word || ri == r_move_output_word) + +/* Command Types: */ +enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, + cm_connection, cm_function_def, cm_until, cm_group, + cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc }; + +/* Possible values for the `flags' field of a WORD_DESC. */ +#define W_HASDOLLAR (1 << 0) /* Dollar sign present. */ +#define W_QUOTED (1 << 1) /* Some form of quote character is present. */ +#define W_ASSIGNMENT (1 << 2) /* This word is a variable assignment. */ +#define W_SPLITSPACE (1 << 3) /* Split this word on " " regardless of IFS */ +#define W_NOSPLIT (1 << 4) /* Do not perform word splitting on this word because ifs is empty string. */ +#define W_NOGLOB (1 << 5) /* Do not perform globbing on this word. */ +#define W_NOSPLIT2 (1 << 6) /* Don't split word except for $@ expansion (using spaces) because context does not allow it. */ +#define W_TILDEEXP (1 << 7) /* Tilde expand this assignment word */ +#define W_DOLLARAT (1 << 8) /* $@ and its special handling -- UNUSED */ +#define W_DOLLARSTAR (1 << 9) /* $* and its special handling -- UNUSED */ +#define W_NOCOMSUB (1 << 10) /* Don't perform command substitution on this word */ +#define W_ASSIGNRHS (1 << 11) /* Word is rhs of an assignment statement */ +#define W_NOTILDE (1 << 12) /* Don't perform tilde expansion on this word */ +#define W_ITILDE (1 << 13) /* Internal flag for word expansion */ +#define W_EXPANDRHS (1 << 14) /* Expanding word in ${paramOPword} */ +#define W_COMPASSIGN (1 << 15) /* Compound assignment */ +#define W_ASSNBLTIN (1 << 16) /* word is a builtin command that takes assignments */ +#define W_ASSIGNARG (1 << 17) /* word is assignment argument to command */ +#define W_HASQUOTEDNULL (1 << 18) /* word contains a quoted null character */ +#define W_DQUOTE (1 << 19) /* word should be treated as if double-quoted */ +#define W_NOPROCSUB (1 << 20) /* don't perform process substitution */ +#define W_SAWQUOTEDNULL (1 << 21) /* word contained a quoted null that was removed */ +#define W_ASSIGNASSOC (1 << 22) /* word looks like associative array assignment */ +#define W_ASSIGNARRAY (1 << 23) /* word looks like a compound indexed array assignment */ +#define W_ARRAYIND (1 << 24) /* word is an array index being expanded */ +#define W_ASSNGLOBAL (1 << 25) /* word is a global assignment to declare (declare/typeset -g) */ +#define W_NOBRACE (1 << 26) /* Don't perform brace expansion */ +#define W_COMPLETE (1 << 27) /* word is being expanded for completion */ +#define W_CHKLOCAL (1 << 28) /* check for local vars on assignment */ +#define W_NOASSNTILDE (1 << 29) /* don't do tilde expansion like an assignment statement */ +#define W_FORCELOCAL (1 << 30) /* force assignments to be to local variables, non-fatal on assignment errors */ + +/* Flags for the `pflags' argument to param_expand() and various + parameter_brace_expand_xxx functions; also used for string_list_dollar_at */ +#define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ +#define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */ +#define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */ +#define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */ +#define PF_COMPLETE 0x10 /* same as W_COMPLETE, sets SX_COMPLETE */ +#define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */ +#define PF_ALLINDS 0x40 /* array, act as if [@] was supplied */ + +/* Possible values for subshell_environment */ +#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */ +#define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */ +#define SUBSHELL_COMSUB 0x04 /* subshell caused by `command` or $(command) */ +#define SUBSHELL_FORK 0x08 /* subshell caused by executing a disk command */ +#define SUBSHELL_PIPE 0x10 /* subshell from a pipeline element */ +#define SUBSHELL_PROCSUB 0x20 /* subshell caused by <(command) or >(command) */ +#define SUBSHELL_COPROC 0x40 /* subshell from a coproc pipeline */ +#define SUBSHELL_RESETTRAP 0x80 /* subshell needs to reset trap strings on first call to trap */ + +/* A structure which represents a word. */ +typedef struct word_desc { + char *word; /* Zero terminated string. */ + int flags; /* Flags associated with this word. */ +} WORD_DESC; + +/* A linked list of words. */ +typedef struct word_list { + struct word_list *next; + WORD_DESC *word; +} WORD_LIST; + + +/* **************************************************************** */ +/* */ +/* Shell Command Structs */ +/* */ +/* **************************************************************** */ + +/* What a redirection descriptor looks like. If the redirection instruction + is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise + use the file in FILENAME. Out-of-range descriptors are identified by a + negative DEST. */ + +typedef union { + int dest; /* Place to redirect REDIRECTOR to, or ... */ + WORD_DESC *filename; /* filename to redirect to. */ +} REDIRECTEE; + +/* Structure describing a redirection. If REDIRECTOR is negative, the parser + (or translator in redir.c) encountered an out-of-range file descriptor. */ +typedef struct redirect { + struct redirect *next; /* Next element, or NULL. */ + REDIRECTEE redirector; /* Descriptor or varname to be redirected. */ + int rflags; /* Private flags for this redirection */ + int flags; /* Flag value for `open'. */ + enum r_instruction instruction; /* What to do with the information. */ + REDIRECTEE redirectee; /* File descriptor or filename */ + char *here_doc_eof; /* The word that appeared in <flags. */ +#define CMD_WANT_SUBSHELL 0x01 /* User wants a subshell: ( command ) */ +#define CMD_FORCE_SUBSHELL 0x02 /* Shell needs to force a subshell. */ +#define CMD_INVERT_RETURN 0x04 /* Invert the exit value. */ +#define CMD_IGNORE_RETURN 0x08 /* Ignore the exit value. For set -e. */ +#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */ +#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */ +#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */ +#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */ +#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */ +#define CMD_AMPERSAND 0x200 /* command & */ +#define CMD_STDIN_REDIR 0x400 /* async command needs implicit . +*/ + +#include "config.h" + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include "chartypes.h" +#include "bashtypes.h" +#include "posixstat.h" +#include + +#include + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include "bashansi.h" +#include "bashintl.h" + +#define NEED_FPURGE_DECL + +#include "shell.h" +#include "maxpath.h" +#include "flags.h" +#include "parser.h" +#include "jobs.h" +#include "builtins.h" +#include "input.h" +#include "execute_cmd.h" +#include "trap.h" +#include "bashgetopt.h" +#include "common.h" +#include "builtext.h" +#include "tilde.h" + +#if defined (HISTORY) +# include "bashhist.h" +#endif + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern const char * const bash_getcwd_errstr; + +/* Used by some builtins and the mainline code. */ +sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL; +sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL; + +extern void builtin_error_prolog(); + +void +#if defined (PREFER_STDARG) +builtin_error (const char *format, ...) +#else +builtin_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + builtin_error_prolog (); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + va_end (args); + fprintf (stderr, "\n"); +} + +void +#if defined (PREFER_STDARG) +builtin_warning (const char *format, ...) +#else +builtin_warning (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + builtin_error_prolog (); + fprintf (stderr, _("warning: ")); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + va_end (args); + fprintf (stderr, "\n"); +} diff --git a/utshell-0.5.0/variable/common.h b/utshell-0.5.0/variable/common.h new file mode 100644 index 00000000..a4f9275d --- /dev/null +++ b/utshell-0.5.0/variable/common.h @@ -0,0 +1,252 @@ +/* common.h -- extern declarations for functions defined in common.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (__COMMON_H) +# define __COMMON_H + +#include "stdc.h" + +#define ISOPTION(s, c) (s[0] == '-' && s[1] == c && !s[2]) +#define ISHELP(s) (STREQ ((s), "--help")) + +#define CHECK_HELPOPT(l) \ +do { \ + if ((l) && (l)->word && ISHELP((l)->word->word)) \ + { \ + builtin_help (); \ + return (EX_USAGE); \ + } \ +} while (0) + +#define CASE_HELPOPT \ + case GETOPT_HELP: \ + builtin_help (); \ + return (EX_USAGE) + +/* Flag values for parse_and_execute () */ +#define SEVAL_NONINT 0x001 +#define SEVAL_INTERACT 0x002 +#define SEVAL_NOHIST 0x004 +#define SEVAL_NOFREE 0x008 +#define SEVAL_RESETLINE 0x010 +#define SEVAL_PARSEONLY 0x020 +#define SEVAL_NOLONGJMP 0x040 +#define SEVAL_FUNCDEF 0x080 /* only allow function definitions */ +#define SEVAL_ONECMD 0x100 /* only allow a single command */ +#define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */ + +/* Flags for describe_command, shared between type.def and command.def */ +#define CDESC_ALL 0x001 /* type -a */ +#define CDESC_SHORTDESC 0x002 /* command -V */ +#define CDESC_REUSABLE 0x004 /* command -v */ +#define CDESC_TYPE 0x008 /* type -t */ +#define CDESC_PATH_ONLY 0x010 /* type -p */ +#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */ +#define CDESC_NOFUNCS 0x040 /* type -f */ +#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */ +#define CDESC_STDPATH 0x100 /* command -p */ + +/* Flags for get_job_by_name */ +#define JM_PREFIX 0x01 /* prefix of job name */ +#define JM_SUBSTRING 0x02 /* substring of job name */ +#define JM_EXACT 0x04 /* match job name exactly */ +#define JM_STOPPED 0x08 /* match stopped jobs only */ +#define JM_FIRSTMATCH 0x10 /* return first matching job */ + +/* Flags for remember_args and value of changed_dollar_vars */ +#define ARGS_NONE 0x0 +#define ARGS_INVOC 0x01 +#define ARGS_FUNC 0x02 +#define ARGS_SETBLTIN 0x04 + +/* Maximum number of attribute letters */ +#define MAX_ATTRIBUTES 16 + +/* Functions from common.c */ +extern void builtin_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); +extern void builtin_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); +extern void builtin_usage PARAMS((void)); +extern void no_args PARAMS((WORD_LIST *)); +extern int no_options PARAMS((WORD_LIST *)); + +/* common error message functions */ +extern void sh_needarg PARAMS((char *)); +extern void sh_neednumarg PARAMS((char *)); +extern void sh_notfound PARAMS((char *)); +extern void sh_invalidopt PARAMS((char *)); +extern void sh_invalidoptname PARAMS((char *)); +extern void sh_invalidid PARAMS((char *)); +extern void sh_invalidnum PARAMS((char *)); +extern void sh_invalidsig PARAMS((char *)); +extern void sh_erange PARAMS((char *, char *)); +extern void sh_badpid PARAMS((char *)); +extern void sh_badjob PARAMS((char *)); +extern void sh_readonly PARAMS((const char *)); +extern void sh_nojobs PARAMS((char *)); +extern void sh_restricted PARAMS((char *)); +extern void sh_notbuiltin PARAMS((char *)); +extern void sh_wrerror PARAMS((void)); +extern void sh_ttyerror PARAMS((int)); +extern int sh_chkwrite PARAMS((int)); + +extern char **make_builtin_argv PARAMS((WORD_LIST *, int *)); +extern void remember_args PARAMS((WORD_LIST *, int)); +extern void shift_args PARAMS((int)); +extern int number_of_args PARAMS((void)); + +extern int dollar_vars_changed PARAMS((void)); +extern void set_dollar_vars_unchanged PARAMS((void)); +extern void set_dollar_vars_changed PARAMS((void)); + +extern int get_numeric_arg PARAMS((WORD_LIST *, int, intmax_t *)); +extern int get_exitstat PARAMS((WORD_LIST *)); +extern int read_octal PARAMS((char *)); + +/* Keeps track of the current working directory. */ +extern char *the_current_working_directory; +extern char *get_working_directory PARAMS((char *)); +extern void set_working_directory PARAMS((char *)); + +#if defined (JOB_CONTROL) +extern int get_job_by_name PARAMS((const char *, int)); +extern int get_job_spec PARAMS((WORD_LIST *)); +#endif +extern int display_signal_list PARAMS((WORD_LIST *, int)); + +/* It's OK to declare a function as returning a Function * without + providing a definition of what a `Function' is. */ +extern struct builtin *builtin_address_internal PARAMS((char *, int)); +extern sh_builtin_func_t *find_shell_builtin PARAMS((char *)); +extern sh_builtin_func_t *builtin_address PARAMS((char *)); +extern sh_builtin_func_t *find_special_builtin PARAMS((char *)); +extern void initialize_shell_builtins PARAMS((void)); + +/* Functions from exit.def */ +extern void bash_logout PARAMS((void)); + +/* Functions from getopts.def */ +extern void getopts_reset PARAMS((int)); + +/* Functions from help.def */ +extern void builtin_help PARAMS((void)); + +/* Functions from read.def */ +extern void read_tty_cleanup PARAMS((void)); +extern int read_tty_modified PARAMS((void)); + +/* Functions from set.def */ +extern int minus_o_option_value PARAMS((char *)); +extern void list_minus_o_opts PARAMS((int, int)); +extern char **get_minus_o_opts PARAMS((void)); +extern int set_minus_o_option PARAMS((int, char *)); + +extern void set_shellopts PARAMS((void)); +extern void parse_shellopts PARAMS((char *)); +extern void initialize_shell_options PARAMS((int)); + +extern void reset_shell_options PARAMS((void)); + +extern char *get_current_options PARAMS((void)); +extern void set_current_options PARAMS((const char *)); + +/* Functions from shopt.def */ +extern void reset_shopt_options PARAMS((void)); +extern char **get_shopt_options PARAMS((void)); + +extern int shopt_setopt PARAMS((char *, int)); +extern int shopt_listopt PARAMS((char *, int)); + +extern int set_login_shell PARAMS((char *, int)); + +extern void set_bashopts PARAMS((void)); +extern void parse_bashopts PARAMS((char *)); +extern void initialize_bashopts PARAMS((int)); + +extern void set_compatibility_opts PARAMS((void)); + +/* Functions from type.def */ +extern int describe_command PARAMS((char *, int)); + +/* Functions from setattr.def */ +extern int set_or_show_attributes PARAMS((WORD_LIST *, int, int)); +extern int show_all_var_attributes PARAMS((int, int)); +extern int show_local_var_attributes PARAMS((int, int)); +extern int show_var_attributes PARAMS((SHELL_VAR *, int, int)); +extern int show_name_attributes PARAMS((char *, int)); +extern int show_localname_attributes PARAMS((char *, int)); +extern int show_func_attributes PARAMS((char *, int)); +extern void set_var_attribute PARAMS((char *, int, int)); +extern int var_attribute_string PARAMS((SHELL_VAR *, int, char *)); + +/* Functions from pushd.def */ +extern char *get_dirstack_from_string PARAMS((char *)); +extern char *get_dirstack_element PARAMS((intmax_t, int)); +extern void set_dirstack_element PARAMS((intmax_t, int, char *)); +extern WORD_LIST *get_directory_stack PARAMS((int)); + +/* Functions from evalstring.c */ +extern int parse_and_execute PARAMS((char *, const char *, int)); +extern int evalstring PARAMS((char *, const char *, int)); +extern void parse_and_execute_cleanup PARAMS((int)); +extern int parse_string PARAMS((char *, const char *, int, char **)); +extern int should_suppress_fork PARAMS((COMMAND *)); +extern int can_optimize_connection PARAMS((COMMAND *)); +extern void optimize_fork PARAMS((COMMAND *)); +extern void optimize_subshell_command PARAMS((COMMAND *)); +extern void optimize_shell_function PARAMS((COMMAND *)); + +/* Functions from evalfile.c */ +extern int maybe_execute_file PARAMS((const char *, int)); +extern int force_execute_file PARAMS((const char *, int)); +extern int source_file PARAMS((const char *, int)); +extern int fc_execute_file PARAMS((const char *)); + +/* variables from common.c */ +extern sh_builtin_func_t *this_shell_builtin; +extern sh_builtin_func_t *last_shell_builtin; + +extern SHELL_VAR *builtin_bind_variable PARAMS((char *, char *, int)); +extern int builtin_unbind_variable PARAMS((const char *)); + +/* variables from evalfile.c */ +extern int sourcelevel; + +/* variables from evalstring.c */ +extern int parse_and_execute_level; + +/* variables from break.def/continue.def */ +extern int breaking; +extern int continuing; +extern int loop_level; + +/* variables from read.def */ +extern int sigalrm_seen; + +/* variables from shift.def */ +extern int print_shift_error; + +/* variables from source.def */ +extern int source_searches_cwd; +extern int source_uses_path; + +/* variables from wait.def */ +extern int wait_intr_flag; + +#endif /* !__COMMON_H */ diff --git a/utshell-0.5.0/variable/config-bot.h b/utshell-0.5.0/variable/config-bot.h new file mode 100644 index 00000000..d19618f1 --- /dev/null +++ b/utshell-0.5.0/variable/config-bot.h @@ -0,0 +1,208 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* config-bot.h */ +/* modify settings or make new ones based on what autoconf tells us. */ + +/* Copyright (C) 1989-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/*********************************************************/ +/* Modify or set defines based on the configure results. */ +/*********************************************************/ + +#if !defined (HAVE_VPRINTF) && defined (HAVE_DOPRNT) +# define USE_VFPRINTF_EMULATION +# define HAVE_VPRINTF +#endif + +#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRLIMIT) +# define HAVE_RESOURCE +#endif + +#if !defined (GETPGRP_VOID) +# define HAVE_BSD_PGRP +#endif + +/* Try this without testing __STDC__ for the time being. */ +#if defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +#else +# if defined (HAVE_VARARGS_H) +# define PREFER_VARARGS +# define USE_VARARGS +# endif +#endif + +#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && defined (HAVE_NETINET_IN_H) +# define HAVE_NETWORK +#endif + +#if defined (HAVE_REGEX_H) && defined (HAVE_REGCOMP) && defined (HAVE_REGEXEC) +# define HAVE_POSIX_REGEXP +#endif + +/* backwards compatibility between different autoconf versions */ +#if HAVE_DECL_SYS_SIGLIST && !defined (SYS_SIGLIST_DECLARED) +# define SYS_SIGLIST_DECLARED +#endif + +/***********************************************************************/ +/* Unset defines based on what configure reports as missing or broken. */ +/***********************************************************************/ + +/* Ultrix botches type-ahead when switching from canonical to + non-canonical mode, at least through version 4.3 */ +#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix) +# define TERMIOS_MISSING +#endif + +/* If we have a getcwd(3), but one that does not dynamically allocate memory, + #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do + not do this on Solaris, because their implementation of loopback mounts + breaks the traditional file system assumptions that getcwd uses. */ +#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS) +# undef HAVE_GETCWD +#endif + +#if !defined (HAVE_DEV_FD) && defined (NAMED_PIPES_MISSING) +# undef PROCESS_SUBSTITUTION +#endif + +#if defined (JOB_CONTROL_MISSING) +# undef JOB_CONTROL +#endif + +#if defined (STRCOLL_BROKEN) +# undef HAVE_STRCOLL +#endif + +#if !defined (HAVE_POSIX_REGEXP) +# undef COND_REGEXP +#endif + +#if !HAVE_MKSTEMP +# undef USE_MKSTEMP +#endif + +#if !HAVE_MKDTEMP +# undef USE_MKDTMP +#endif + +/* If the shell is called by this name, it will become restricted. */ +#if defined (RESTRICTED_SHELL) +# define RESTRICTED_SHELL_NAME "rbash" +#endif + +/***********************************************************/ +/* Make sure feature defines have necessary prerequisites. */ +/***********************************************************/ + +/* BANG_HISTORY requires HISTORY. */ +#if defined (BANG_HISTORY) && !defined (HISTORY) +# define HISTORY +#endif /* BANG_HISTORY && !HISTORY */ + +#if defined (READLINE) && !defined (HISTORY) +# define HISTORY +#endif + +#if defined (PROGRAMMABLE_COMPLETION) && !defined (READLINE) +# undef PROGRAMMABLE_COMPLETION +#endif + +#if !defined (V9_ECHO) +# undef DEFAULT_ECHO_TO_XPG +#endif + +#if !defined (PROMPT_STRING_DECODE) +# undef PPROMPT +# define PPROMPT "$ " +#endif + +#if !defined (HAVE_SYSLOG) || !defined (HAVE_SYSLOG_H) +# undef SYSLOG_HISTORY +#endif + +/************************************************/ +/* check multibyte capability for I18N code */ +/************************************************/ + +/* For platforms which support the ISO C amendment 1 functionality we + support user defined character classes. */ +/* Solaris 2.5 has a bug: must be included before . */ +#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H) +# include +# include +# if defined (HAVE_ISWCTYPE) && \ + defined (HAVE_ISWLOWER) && \ + defined (HAVE_ISWUPPER) && \ + defined (HAVE_MBSRTOWCS) && \ + defined (HAVE_MBRTOWC) && \ + defined (HAVE_MBRLEN) && \ + defined (HAVE_TOWLOWER) && \ + defined (HAVE_TOWUPPER) && \ + defined (HAVE_WCHAR_T) && \ + defined (HAVE_WCTYPE_T) && \ + defined (HAVE_WINT_T) && \ + defined (HAVE_WCWIDTH) && \ + defined (HAVE_WCTYPE) + /* system is supposed to support XPG5 */ +# define HANDLE_MULTIBYTE 1 +# endif +#endif + +/* If we don't want multibyte chars even on a system that supports them, let + the configuring user turn multibyte support off. */ +#if defined (NO_MULTIBYTE_SUPPORT) +# undef HANDLE_MULTIBYTE +#endif + +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ +#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T) +# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0) +# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0) +# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0) +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +# define mbrlen(s, n, ps) (mbrlen) (s, n, 0) +# define mbstate_t int +#endif + +/* Make sure MB_LEN_MAX is at least 16 (some systems define + MB_LEN_MAX as 1) */ +#ifdef HANDLE_MULTIBYTE +# include +# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16) +# undef MB_LEN_MAX +# endif +# if !defined (MB_LEN_MAX) +# define MB_LEN_MAX 16 +# endif +#endif + +/************************************************/ +/* end of multibyte capability checks for I18N */ +/************************************************/ + +/******************************************************************/ +/* Placeholder for builders to #undef any unwanted features from */ +/* config-top.h or created by configure (such as the default mail */ +/* file for mail checking). */ +/******************************************************************/ + +/* If you don't want bash to provide a default mail file to check. */ +/* #undef DEFAULT_MAIL_DIRECTORY */ diff --git a/utshell-0.5.0/variable/config-top.h b/utshell-0.5.0/variable/config-top.h new file mode 100644 index 00000000..04ea05fe --- /dev/null +++ b/utshell-0.5.0/variable/config-top.h @@ -0,0 +1,200 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* config-top.h - various user-settable options not under the control of autoconf. */ + +/* Copyright (C) 2002-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to + continue processing arguments after one of them fails. This is + what POSIX.2 specifies. */ +#define CONTINUE_AFTER_KILL_ERROR + +#define NON_INTERACTIVE_LOGIN_SHELLS + +/* Define BREAK_COMPLAINS if you want the non-standard, but useful + error messages about `break' and `continue' out of context. */ +#define BREAK_COMPLAINS + +/* Define CD_COMPLAINS if you want the non-standard, but sometimes-desired + error messages about multiple directory arguments to `cd'. */ +#define CD_COMPLAINS + +/* Define BUFFERED_INPUT if you want the shell to do its own input + buffering, rather than using stdio. Do not undefine this; it's + required to preserve semantics required by POSIX. */ +#define BUFFERED_INPUT + +/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute + `command' whenever possible. This is a big efficiency improvement. */ +#define ONESHOT + +/* Define V9_ECHO if you want to give the echo builtin backslash-escape + interpretation using the -e option, in the style of the Bell Labs 9th + Edition version of echo. You cannot emulate the System V echo behavior + without this option. */ +#define V9_ECHO + +/* Define DONT_REPORT_SIGPIPE if you don't want to see `Broken pipe' messages + when a job like `cat jobs.c | exit 1' terminates due to a SIGPIPE. */ +#define DONT_REPORT_SIGPIPE + +/* Define DONT_REPORT_SIGTERM if you don't want to see `Terminates' message + when a job exits due to SIGTERM, since that's the default signal sent + by the kill builtin. */ +#define DONT_REPORT_SIGTERM + +/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins + like `echo' and `printf' to report errors when output does not succeed + due to EPIPE. */ +#define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS + +/* The default value of the PATH variable. */ +#ifndef DEFAULT_PATH_VALUE +#define DEFAULT_PATH_VALUE \ + "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:." +#endif + +/* If you want to unconditionally set a value for PATH in every restricted + shell, set this. */ +/* #define RBASH_STATIC_PATH_VALUE "/rbin:/usr/rbin" */ + +/* The value for PATH when invoking `command -p'. This is only used when + the Posix.2 confstr () function, or CS_PATH define are not present. */ +#ifndef STANDARD_UTILS_PATH +#define STANDARD_UTILS_PATH \ + "/bin:/usr/bin:/usr/sbin:/sbin" +#endif + +/* Default primary and secondary prompt strings. */ +#define PPROMPT "\\s-\\v\\$ " +#define SPROMPT "> " + +/* Undefine this if you don't want the ksh-compatible behavior of reprinting + the select menu after a valid choice is made only if REPLY is set to NULL + in the body of the select command. The menu is always reprinted if the + reply to the select query is an empty line. */ +#define KSH_COMPATIBLE_SELECT + +/* Default interactive shell startup file. */ +// #define DEFAULT_BASHRC "~/.bashrc" +#define DEFAULT_BASHRC "~/.utshellrc" + +/* System-wide .bashrc file for interactive shells. */ +/* #define SYS_BASHRC "/etc/bash.bashrc" */ + +/* System-wide .bash_logout for login shells. */ +// #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" +#define SYS_BASH_LOGOUT "/etc/utshell.utshell_logout" + +/* Define this to make non-interactive shells begun with argv[0][0] == '-' + run the startup files when not in posix mode. */ +/* #define NON_INTERACTIVE_LOGIN_SHELLS */ + +/* Define this if you want bash to try to check whether it's being run by + sshd and source the .bashrc if so (like the rshd behavior). This checks + for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment, + which can be fooled under certain not-uncommon circumstances. */ +#define SSH_SOURCE_BASHRC + +/* Define if you want the case-toggling operators (~[~]) and the + `capcase' variable attribute (declare -c). */ +/* TAG: bash-5.2 disable */ +#define CASEMOD_TOGGLECASE +#define CASEMOD_CAPCASE + +/* This is used as the name of a shell function to call when a command + name is not found. If you want to name it something other than the + default ("command_not_found_handle"), change it here. */ +/* #define NOTFOUND_HOOK "command_not_found_handle" */ + +/* Define if you want each line saved to the history list in bashhist.c: + bash_add_history() to be sent to syslog(). */ +/* #define SYSLOG_HISTORY */ +#if defined (SYSLOG_HISTORY) +# define SYSLOG_FACILITY LOG_USER +# define SYSLOG_LEVEL LOG_INFO +# define OPENLOG_OPTS LOG_PID +#endif + +/* Define if you want syslogging history to be controllable at runtime via a + shell option; if defined, the value is the default for the syslog_history + shopt option */ +#if defined (SYSLOG_HISTORY) +/* #define SYSLOG_SHOPT 1 */ +#endif + +/* Define if you want to include code in shell.c to support wordexp(3) */ +/* #define WORDEXP_OPTION */ + +/* Define as 1 if you want to enable code that implements multiple coprocs + executing simultaneously */ +#ifndef MULTIPLE_COPROCS +# define MULTIPLE_COPROCS 0 +#endif + +/* Define to 0 if you want the checkwinsize option off by default, 1 if you + want it on. */ +#define CHECKWINSIZE_DEFAULT 1 + +/* Define to 1 if you want to optimize for sequential array assignment when + using indexed arrays, 0 if you want bash-4.2 behavior, which favors + random access but is O(N) for each array assignment. */ +#define OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT 1 + +/* Define to 1 if you want to be able to export indexed arrays to processes + using the foo=([0]=one [1]=two) and so on */ +/* #define ARRAY_EXPORT 1 */ + +/* Define to 1 if you want the shell to exit if it is running setuid and its + attempt to drop privilege using setuid(getuid()) fails with errno == EAGAIN */ +/* #define EXIT_ON_SETUID_FAILURE 1 */ + +/* Define to 1 if you want the shell to re-check $PATH if a hashed filename + no longer exists. This behavior is the default in Posix mode. */ +#define CHECKHASH_DEFAULT 0 + +/* Define to the maximum level of recursion you want for the eval builtin + and trap handlers (since traps are run as if run by eval). + 0 means the limit is not active. */ +#define EVALNEST_MAX 0 + +/* Define to the maximum level of recursion you want for the source/. builtin. + 0 means the limit is not active. */ +#define SOURCENEST_MAX 0 + +/* Define to use libc mktemp/mkstemp instead of replacements in lib/sh/tmpfile.c */ +#define USE_MKTEMP +#define USE_MKSTEMP +#define USE_MKDTEMP + +/* Define to force the value of OLDPWD inherited from the environment to be a + directory */ +#define OLDPWD_CHECK_DIRECTORY 1 + +/* Define to set the initial size of the history list ($HISTSIZE). This must + be a string. */ +/*#define HISTSIZE_DEFAULT "500"*/ + +/* Define to 0 if you want history expansion to be disabled by default in + interactive shells; define to 1 for the historical behavior of enabling + when the shell is interactive. */ +#define HISTEXPAND_DEFAULT 1 + +/* Undefine or define to 0 if you don't want to allow associative array + assignment using a compound list of key-value pairs. */ +#define ASSOC_KVPAIR_ASSIGNMENT 1 diff --git a/utshell-0.5.0/variable/config.h b/utshell-0.5.0/variable/config.h new file mode 100644 index 00000000..b33a9e0d --- /dev/null +++ b/utshell-0.5.0/variable/config.h @@ -0,0 +1,1208 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h -- Configuration file for bash. */ + +/* Copyright (C) 1987-2009,2011-2012 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* Template settings for autoconf */ + +#define __EXTENSIONS__ 1 +#define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 +/* #undef _POSIX_SOURCE */ +/* #undef _POSIX_1_SOURCE */ +#define _POSIX_PTHREAD_SEMANTICS 1 +#define _TANDEM_SOURCE 1 +/* #undef _MINIX */ + +/* Configuration feature settings controllable by autoconf. */ + +/* Define JOB_CONTROL if your operating system supports + BSD-like job control. */ +#define JOB_CONTROL 1 + +/* Define ALIAS if you want the alias features. */ +#define ALIAS 1 + +/* Define PUSHD_AND_POPD if you want those commands to be compiled in. + (Also the `dirs' commands.) */ +#define PUSHD_AND_POPD 1 + +/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh: + foo{a,b} -> fooa foob. Even if this is compiled in (the default) you + can turn it off at shell startup with `-nobraceexpansion', or during + shell execution with `set +o braceexpand'. */ +#define BRACE_EXPANSION 1 + +/* Define READLINE to get the nifty/glitzy editing features. + This is on by default. You can turn it off interactively + with the -nolineediting flag. */ +#define READLINE 1 + +/* Define BANG_HISTORY if you want to have Csh style "!" history expansion. + This is unrelated to READLINE. */ +#define BANG_HISTORY 1 + +/* Define HISTORY if you want to have access to previously typed commands. + + If both HISTORY and READLINE are defined, you can get at the commands + with line editing commands, and you can directly manipulate the history + from the command line. + + If only HISTORY is defined, the `fc' and `history' builtins are + available. */ +#define HISTORY 1 + +/* Define this if you want completion that puts all alternatives into + a brace expansion shell expression. */ +#if defined (BRACE_EXPANSION) && defined (READLINE) +# define BRACE_COMPLETION +#endif /* BRACE_EXPANSION */ + +/* Define DEFAULT_ECHO_TO_XPG if you want the echo builtin to interpret + the backslash-escape characters by default, like the XPG Single Unix + Specification V2 for echo. + This requires that V9_ECHO be defined. */ +/* #undef DEFAULT_ECHO_TO_XPG */ + +/* Define HELP_BUILTIN if you want the `help' shell builtin and the long + documentation strings compiled into the shell. */ +#define HELP_BUILTIN 1 + +/* Define RESTRICTED_SHELL if you want the generated shell to have the + ability to be a restricted one. The shell thus generated can become + restricted by being run with the name "rbash", or by setting the -r + flag. */ +#define RESTRICTED_SHELL 1 + +/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the + shell builtin "foo", even if it has been disabled with "enable -n foo". */ +/* #undef DISABLED_BUILTINS */ + +/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process + substitution features "<(file)". */ +/* Right now, you cannot do this on machines without fully operational + FIFO support. This currently include NeXT and Alliant. */ +#define PROCESS_SUBSTITUTION 1 + +/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special + characters in PS1 and PS2 expanded. Variable expansion will still be + performed. */ +#define PROMPT_STRING_DECODE 1 + +/* Define SELECT_COMMAND if you want the Korn-shell style `select' command: + select word in word_list; do command_list; done */ +#define SELECT_COMMAND 1 + +/* Define COMMAND_TIMING of you want the ksh-style `time' reserved word and + the ability to time pipelines, functions, and builtins. */ +#define COMMAND_TIMING 1 + +/* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */ +#define ARRAY_VARS 1 + +/* Define DPAREN_ARITHMETIC if you want the ksh-style ((...)) arithmetic + evaluation command. */ +#define DPAREN_ARITHMETIC 1 + +/* Define EXTENDED_GLOB if you want the ksh-style [*+@?!](patlist) extended + pattern matching. */ +#define EXTENDED_GLOB 1 + +/* Define EXTGLOB_DEFAULT to the value you'd like the extglob shell option + to have by default */ +#define EXTGLOB_DEFAULT 0 + +/* Define COND_COMMAND if you want the ksh-style [[...]] conditional + command. */ +#define COND_COMMAND 1 + +/* Define COND_REGEXP if you want extended regular expression matching and the + =~ binary operator in the [[...]] conditional command. */ +#define COND_REGEXP 1 + +/* Define COPROCESS_SUPPORT if you want support for ksh-like coprocesses and + the `coproc' reserved word */ +#define COPROCESS_SUPPORT 1 + +/* Define ARITH_FOR_COMMAND if you want the ksh93-style + for (( init; test; step )) do list; done + arithmetic for command. */ +#define ARITH_FOR_COMMAND 1 + +/* Define NETWORK_REDIRECTIONS if you want /dev/(tcp|udp)/host/port to open + socket connections when used in redirections */ +#define NETWORK_REDIRECTIONS 1 + +/* Define PROGRAMMABLE_COMPLETION for the programmable completion features + and the complete builtin. */ +#define PROGRAMMABLE_COMPLETION 1 + +/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte + characters, even if the OS supports them. */ +/* #undef NO_MULTIBYTE_SUPPORT */ + +/* Define DEBUGGER if you want to compile in some features used only by the + bash debugger. */ +#define DEBUGGER 1 + +/* Define STRICT_POSIX if you want bash to be strictly posix.2 conformant by + default (except for echo; that is controlled separately). */ +/* #undef STRICT_POSIX */ + +/* Define MEMSCRAMBLE if you want the bash malloc and free to scramble + memory contents on malloc() and free(). */ +#define MEMSCRAMBLE 1 + +/* Define for case-modifying variable attributes; variables modified on + assignment */ +#define CASEMOD_ATTRS 1 + +/* Define for case-modifying word expansions */ +#define CASEMOD_EXPANSIONS 1 + +/* Define to make the `direxpand' shopt option enabled by default. */ +/* #undef DIRCOMPLETE_EXPAND_DEFAULT */ + +/* Define to make the `globasciiranges' shopt option enabled by default. */ +#define GLOBASCII_DEFAULT 1 + +/* Define to allow functions to be imported from the environment. */ +#define FUNCTION_IMPORT 1 + +/* Define AFS if you are using Transarc's AFS. */ +/* #undef AFS */ + +#define ENABLE_NLS 1 + +/* End of configuration settings controllable by autoconf. */ +/* Other settable options appear in config-top.h. */ + +#include "config-top.h" + +/* Beginning of autoconf additions. */ + +/* Characteristics of the C compiler */ +/* #undef const */ + +/* #undef inline */ + +#define restrict __restrict + +/* #undef volatile */ + +/* Define if cpp supports the ANSI-C stringizing `#' operator */ +#define HAVE_STRINGIZE 1 + +/* Define if the compiler supports `long double' variables. */ +#define HAVE_LONG_DOUBLE 1 + +#define PROTOTYPES 1 +#define __PROTOTYPES 1 + +/* #undef __CHAR_UNSIGNED__ */ + +/* Define if the compiler supports `long long' variables. */ +#define HAVE_LONG_LONG 1 + +#define HAVE_UNSIGNED_LONG_LONG 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 8 + +/* The number of bytes in a pointer to char. */ +#define SIZEOF_CHAR_P 8 + +/* The number of bytes in a double (hopefully 8). */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in an `intmax_t'. */ +#define SIZEOF_INTMAX_T 8 + +/* The number of bytes in a `long long', if we have one. */ +#define SIZEOF_LONG_LONG 8 + +/* The number of bytes in a `wchar_t', if supported */ +#define SIZEOF_WCHAR_T 4 + +/* System paths */ + +#define DEFAULT_MAIL_DIRECTORY "/var/mail" + +/* Characteristics of the system's header files and libraries that affect + the compilation environment. */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to use GNU libc extensions */ +#define _GNU_SOURCE 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Memory management functions. */ + +/* Define if using the bash version of malloc in lib/malloc/malloc.c */ +/* #undef USING_BASH_MALLOC */ + +/* #undef DISABLE_MALLOC_WRAPPERS */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + + +/* SYSTEM TYPES */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `int' if doesn't define. */ +/* #undef sigset_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define to `short' if doesn't define. */ +#define bits16_t short + +/* Define to `unsigned short' if doesn't define. */ +#define u_bits16_t unsigned short + +/* Define to `int' if doesn't define. */ +#define bits32_t int + +/* Define to `unsigned int' if doesn't define. */ +#define u_bits32_t unsigned int + +/* Define to `double' if doesn't define. */ +#define bits64_t char * + +/* Define to `unsigned int' if doesn't define. */ +/* #undef u_int */ + +/* Define to `unsigned long' if doesn't define. */ +/* #undef u_long */ + +/* Define to `int' if doesn't define. */ +/* #undef ptrdiff_t */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define to `int' if doesn't define. */ +/* #undef ssize_t */ + +/* Define to `long' if doesn't define. */ +/* #undef intmax_t */ + +/* Define to `unsigned long' if doesn't define. */ +/* #undef uintmax_t */ + +/* Define to integer type wide enough to hold a pointer if doesn't define. */ +/* #undef uintptr_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define to `long' if doesn't define. */ +/* #undef clock_t */ + +/* Define to `long' if doesn't define. */ +/* #undef time_t */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `unsigned int' if doesn't define. */ +/* #undef socklen_t */ + +/* Define to `int' if doesn't define. */ +/* #undef sig_atomic_t */ + +#define HAVE_MBSTATE_T 1 + +/* Define if you have quad_t in . */ +#define HAVE_QUAD_T 1 + +/* Define if you have wchar_t in . */ +#define HAVE_WCHAR_T 1 + +/* Define if you have wctype_t in . */ +#define HAVE_WCTYPE_T 1 + +/* Define if you have wint_t in . */ +#define HAVE_WINT_T 1 + +#define RLIMTYPE rlim_t + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +#define GETGROUPS_T gid_t + +/* Characteristics of the machine archictecture. */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the machine architecture is big-endian. */ +/* #undef WORDS_BIGENDIAN */ + +/* Check for the presence of certain non-function symbols in the system + libraries. */ + +/* Define if `sys_siglist' is declared by or . */ +#define HAVE_DECL_SYS_SIGLIST 1 +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define if `_sys_siglist' is declared by or . */ +#define UNDER_SYS_SIGLIST_DECLARED 1 + +#define HAVE_SYS_SIGLIST 1 + +#define HAVE_UNDER_SYS_SIGLIST 1 + +#define HAVE_SYS_ERRLIST 1 + +/* #undef HAVE_TZNAME */ +/* #undef HAVE_DECL_TZNAME */ + +/* Characteristics of some of the system structures. */ + +#define HAVE_STRUCT_DIRENT_D_INO 1 + +#define HAVE_STRUCT_DIRENT_D_FILENO 1 + +/* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */ + +/* #undef TIOCSTAT_IN_SYS_IOCTL */ + +#define FIONREAD_IN_SYS_IOCTL 1 + +#define GWINSZ_IN_SYS_IOCTL 1 + +#define STRUCT_WINSIZE_IN_SYS_IOCTL 1 + +/* #undef TM_IN_SYS_TIME */ + +/* #undef STRUCT_WINSIZE_IN_TERMIOS */ + +/* #undef SPEED_T_IN_SYS_TYPES */ + +#define TERMIOS_LDISC 1 + +#define TERMIO_LDISC 1 + +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 + +#define HAVE_STRUCT_TM_TM_ZONE 1 +#define HAVE_TM_ZONE 1 + +#define HAVE_TIMEVAL 1 + +#define HAVE_STRUCT_TIMEZONE 1 + +#define WEXITSTATUS_OFFSET 8 + +#define HAVE_STRUCT_TIMESPEC 1 +#define TIME_H_DEFINES_STRUCT_TIMESPEC 1 +/* #undef SYS_TIME_H_DEFINES_STRUCT_TIMESPEC */ +/* #undef PTHREAD_H_DEFINES_STRUCT_TIMESPEC */ + +#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1 +#define TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC 1 +/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */ +/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */ +/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */ + +/* Characteristics of definitions in the system header files. */ + +#define HAVE_GETPW_DECLS 1 + +/* #undef HAVE_RESOURCE */ + +/* #undef HAVE_LIBC_FNM_EXTMATCH */ + +/* Define if you have and it defines AUDIT_USER_TTY */ +#define HAVE_DECL_AUDIT_USER_TTY 1 + +#define HAVE_DECL_CONFSTR 1 + +#define HAVE_DECL_PRINTF 1 + +#define HAVE_DECL_SBRK 1 + +#define HAVE_DECL_STRCPY 1 + +#define HAVE_DECL_STRSIGNAL 1 + +#define HAVE_DECL_STRTOLD 1 + +/* #undef PRI_MACROS_BROKEN */ + +/* #undef STRTOLD_BROKEN */ + +/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */ +/* #undef WCONTINUED_BROKEN */ + +/* These are checked with BASH_CHECK_DECL */ + +#define HAVE_DECL_STRTOIMAX 1 +#define HAVE_DECL_STRTOL 1 +#define HAVE_DECL_STRTOLL 1 +#define HAVE_DECL_STRTOUL 1 +#define HAVE_DECL_STRTOULL 1 +#define HAVE_DECL_STRTOUMAX 1 + +/* Characteristics of system calls and C library functions. */ + +/* Define if the `getpgrp' function takes no argument. */ +#define GETPGRP_VOID 1 + +/* #undef NAMED_PIPES_MISSING */ + +/* #undef OPENDIR_NOT_ROBUST */ + +#define PGRP_PIPE 1 + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* #undef STAT_MACROS_BROKEN */ + +#define ULIMIT_MAXFDS 1 + +#define CAN_REDEFINE_GETENV 1 + +#define HAVE_STD_PUTENV 1 + +#define HAVE_STD_UNSETENV 1 + +#define HAVE_PRINTF_A_FORMAT 1 + +/* #undef CTYPE_NON_ASCII */ + +/* Define if you have and nl_langinfo(CODESET). */ +#define HAVE_LANGINFO_CODESET 1 + +/* Characteristics of properties exported by the kernel. */ + +/* Define if the kernel can exec files beginning with #! */ +#define HAVE_HASH_BANG_EXEC 1 + +/* Define if you have the /dev/fd devices to map open files into the file system. */ +#define HAVE_DEV_FD 1 + +/* Defined to /dev/fd or /proc/self/fd (linux). */ +#define DEV_FD_PREFIX "/dev/fd/" + +/* Define if you have the /dev/stdin device. */ +#define HAVE_DEV_STDIN 1 + +/* The type of iconv's `inbuf' argument */ +#define ICONV_CONST + +/* Type and behavior of signal handling functions. */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if return type of signal handlers is void */ +#define VOID_SIGHANDLER 1 + +/* #undef MUST_REINSTALL_SIGHANDLERS */ + +/* #undef HAVE_BSD_SIGNALS */ + +#define HAVE_POSIX_SIGNALS 1 + +/* #undef HAVE_USG_SIGHOLD */ + +/* #undef UNUSABLE_RT_SIGNALS */ + +/* Presence of system and C library functions. */ + +/* Define if you have the asprintf function. */ +#define HAVE_ASPRINTF 1 + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bzero function. */ +#define HAVE_BZERO 1 + +/* Define if you have the chown function. */ +#define HAVE_CHOWN 1 + +/* Define if you have the confstr function. */ +#define HAVE_CONFSTR 1 + +/* Define if you have the dlclose function. */ +#define HAVE_DLCLOSE 1 + +/* Define if you have the dlopen function. */ +#define HAVE_DLOPEN 1 + +/* Define if you have the dlsym function. */ +#define HAVE_DLSYM 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have the dprintf function. */ +#define HAVE_DPRINTF 1 + +/* Define if you have the dup2 function. */ +#define HAVE_DUP2 1 + +/* Define if you have the eaccess function. */ +#define HAVE_EACCESS 1 + +/* Define if you have the faccessat function. */ +#define HAVE_FACCESSAT 1 + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the fnmatch function. */ +#define HAVE_FNMATCH 1 + +/* Can fnmatch be used as a fallback to match [=equiv=] with collation weights? */ +#define FNMATCH_EQUIV_FALLBACK 0 + +/* Define if you have the fpurge/__fpurge function. */ +/* #undef HAVE_FPURGE */ +#define HAVE___FPURGE 1 +#define HAVE_DECL_FPURGE 0 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getdtablesize function. */ +#define HAVE_GETDTABLESIZE 1 + +/* Define if you have the getgroups function. */ +#define HAVE_GETGROUPS 1 + +/* Define if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + +/* Define if you have the getpwent function. */ +#define HAVE_GETPWENT 1 + +/* Define if you have the getpwnam function. */ +#define HAVE_GETPWNAM 1 + +/* Define if you have the getpwuid function. */ +#define HAVE_GETPWUID 1 + +/* Define if you have the getrlimit function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the getservbyname function. */ +#define HAVE_GETSERVBYNAME 1 + +/* Define if you have the getservent function. */ +#define HAVE_GETSERVENT 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the getwd function. */ +/* #undef HAVE_GETWD */ + +/* Define if you have the iconv function. */ +#define HAVE_ICONV 1 + +/* Define if you have the imaxdiv function. */ +#define HAVE_IMAXDIV 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the isascii function. */ +#define HAVE_ISASCII 1 + +/* Define if you have the isblank function. */ +#define HAVE_ISBLANK 1 + +/* Define if you have the isgraph function. */ +#define HAVE_ISGRAPH 1 + +/* Define if you have the isprint function. */ +#define HAVE_ISPRINT 1 + +/* Define if you have the isspace function. */ +#define HAVE_ISSPACE 1 + +/* Define if you have the iswctype function. */ +#define HAVE_ISWCTYPE 1 + +/* Define if you have the iswlower function. */ +#define HAVE_ISWLOWER 1 + +/* Define if you have the iswupper function. */ +#define HAVE_ISWUPPER 1 + +/* Define if you have the isxdigit function. */ +#define HAVE_ISXDIGIT 1 + +/* Define if you have the kill function. */ +#define HAVE_KILL 1 + +/* Define if you have the killpg function. */ +#define HAVE_KILLPG 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the locale_charset function. */ +/* #undef HAVE_LOCALE_CHARSET */ + +/* Define if you have the mbrlen function. */ +#define HAVE_MBRLEN 1 + +/* Define if you have the mbrtowc function. */ +#define HAVE_MBRTOWC 1 + +/* Define if you have the mbscasecmp function. */ +/* #undef HAVE_MBSCASECMP */ + +/* Define if you have the mbschr function. */ +/* #undef HAVE_MBSCHR */ + +/* Define if you have the mbscmp function. */ +/* #undef HAVE_MBSCMP */ + +/* Define if you have the mbsnrtowcs function. */ +#define HAVE_MBSNRTOWCS 1 + +/* Define if you have the mbsrtowcs function. */ +#define HAVE_MBSRTOWCS 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the mkfifo function. */ +#define HAVE_MKFIFO 1 + +/* Define if you have the mkstemp function. */ +#define HAVE_MKSTEMP 1 + +/* Define if you have the pathconf function. */ +#define HAVE_PATHCONF 1 + +/* Define if you have the pselect function. */ +#define HAVE_PSELECT 1 + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the raise function. */ +#define HAVE_RAISE 1 + +/* Define if you have the random function. */ +#define HAVE_RANDOM 1 + +/* Define if you have the readlink function. */ +#define HAVE_READLINK 1 + +/* Define if you have the regcomp function. */ +#define HAVE_REGCOMP 1 + +/* Define if you have the regexec function. */ +#define HAVE_REGEXEC 1 + +/* Define if you have the rename function. */ +#define HAVE_RENAME 1 + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the setdtablesize function. */ +/* #undef HAVE_SETDTABLESIZE */ + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the setitimer function. */ +#define HAVE_SETITIMER 1 + +/* Define if you have the setlinebuf function. */ +#define HAVE_SETLINEBUF 1 + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setostype function. */ +/* #undef HAVE_SETOSTYPE */ + +/* Define if you have the setregid function. */ +/* #undef HAVE_SETREGID */ +#define HAVE_DECL_SETREGID 1 + +/* Define if you have the setvbuf function. */ +#define HAVE_SETVBUF 1 + +/* Define if you have the siginterrupt function. */ +#define HAVE_SIGINTERRUPT 1 + +/* Define if you have the POSIX.1-style sigsetjmp function. */ +#define HAVE_POSIX_SIGSETJMP 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strcasestr function. */ +#define HAVE_STRCASESTR 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strchrnul function. */ +#define HAVE_STRCHRNUL 1 + +/* Define if you have the strcoll function. */ +#define HAVE_STRCOLL 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have the strnlen function. */ +#define HAVE_STRNLEN 1 + +/* Define if you have the strpbrk function. */ +#define HAVE_STRPBRK 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtoimax function. */ +#define HAVE_STRTOIMAX 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoll function. */ +#define HAVE_STRTOLL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the strtoull function. */ +#define HAVE_STRTOULL 1 + +/* Define if you have the strtoumax function. */ +#define HAVE_STRTOUMAX 1 + +/* Define if you have the strsignal function or macro. */ +#define HAVE_STRSIGNAL 1 + +/* Define if you have the sysconf function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have the syslog function. */ +#define HAVE_SYSLOG 1 + +/* Define if you have the tcgetattr function. */ +#define HAVE_TCGETATTR 1 + +/* Define if you have the tcgetpgrp function. */ +#define HAVE_TCGETPGRP 1 + +/* Define if you have the times function. */ +#define HAVE_TIMES 1 + +/* Define if you have the towlower function. */ +#define HAVE_TOWLOWER 1 + +/* Define if you have the towupper function. */ +#define HAVE_TOWUPPER 1 + +/* Define if you have the ttyname function. */ +#define HAVE_TTYNAME 1 + +/* Define if you have the tzset function. */ +#define HAVE_TZSET 1 + +/* Define if you have the ulimit function. */ +#define HAVE_ULIMIT 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the unsetenv function. */ +#define HAVE_UNSETENV 1 + +/* Define if you have the vasprintf function. */ +#define HAVE_VASPRINTF 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the waitpid function. */ +#define HAVE_WAITPID 1 + +/* Define if you have the wait3 function. */ +#define HAVE_WAIT3 1 + +/* Define if you have the wcrtomb function. */ +#define HAVE_WCRTOMB 1 + +/* Define if you have the wcscoll function. */ +#define HAVE_WCSCOLL 1 + +/* Define if you have the wcsdup function. */ +#define HAVE_WCSDUP 1 + +/* Define if you have the wctype function. */ +#define HAVE_WCTYPE 1 + +/* Define if you have the wcswidth function. */ +#define HAVE_WCSWIDTH 1 + +/* Define if you have the wcwidth function. */ +#define HAVE_WCWIDTH 1 + +/* and if it works */ +/* #undef WCWIDTH_BROKEN */ + +/* Presence of certain system include files. */ + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_LANGINFO_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LIBAUDIT_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_LIBINTL_H */ + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MBSTR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTEM_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_STREAM_H */ + +/* Define if you have */ +#define HAVE_SYS_TIME_H 1 + +#define TIME_WITH_SYS_TIME 1 + +/* Define if you have */ +#define HAVE_SYS_TIMES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMCAP_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_ULIMIT_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_VARARGS_H */ + +/* Define if you have the header file. */ +#define HAVE_WCHAR_H 1 + +/* Define if you have the header file. */ +#define HAVE_WCTYPE_H 1 + +/* Presence of certain system libraries. */ + +#define HAVE_LIBDL 1 + +/* #undef HAVE_LIBSUN */ + +/* #undef HAVE_LIBSOCKET */ + +/* Are we running the GNU C library, version 2.1 or later? */ +/* #undef GLIBC21 */ + +/* Are we running SVR5 (UnixWare 7)? */ +/* #undef SVR5 */ + +/* Are we running SVR4.2? */ +/* #undef SVR4_2 */ + +/* Are we running some version of SVR4? */ +/* #undef SVR4 */ + +/* Define if job control is unusable or unsupported. */ +/* #undef JOB_CONTROL_MISSING */ + +/* Do we need to define _KERNEL to get the RLIMIT_* defines from + ? */ +/* #undef RLIMIT_NEEDS_KERNEL */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Do strcoll(3) and strcmp(3) give different results in the default locale? */ +/* #undef STRCOLL_BROKEN */ + +/* #undef DUP2_BROKEN */ + +/* #undef GETCWD_BROKEN */ + +/* #undef DEV_FD_STAT_BROKEN */ + +/* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */ + +/* Define if you have the header file. */ +#define HAVE_ARGZ_H 1 + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDIO_EXT_H 1 + +/* Define if you have the `dcgettext' function. */ +#define HAVE_DCGETTEXT 1 + +/* Define if you have the `localeconv' function. */ +#define HAVE_LOCALECONV 1 + +/* Define if your system has a working `malloc' function. */ +/* #undef HAVE_MALLOC */ + +/* Define if you have the `mempcpy' function. */ +#define HAVE_MEMPCPY 1 + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if you have the `mremap' function. */ +#define HAVE_MREMAP 1 + +/* Define if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define if you have the `nl_langinfo' function. */ +/* #undef HAVE_NL_LANGINFO */ + +/* Define if you have the `stpcpy' function. */ +#define HAVE_STPCPY 1 + +/* Define if you have the `strcspn' function. */ +#define HAVE_STRCSPN 1 + +/* Define if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the `__argz_count' function. */ +#define HAVE___ARGZ_COUNT 1 + +/* Define if you have the `__argz_next' function. */ +#define HAVE___ARGZ_NEXT 1 + +/* Define if you have the `__argz_stringify' function. */ +#define HAVE___ARGZ_STRINGIFY 1 + +/* End additions for lib/intl */ + +#include "config-bot.h" + +#endif /* _CONFIG_H_ */ diff --git a/utshell-0.5.0/variable/conftypes.h b/utshell-0.5.0/variable/conftypes.h new file mode 100644 index 00000000..ea677ccd --- /dev/null +++ b/utshell-0.5.0/variable/conftypes.h @@ -0,0 +1,59 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* conftypes.h -- defines for build and host system. */ + +/* Copyright (C) 2001, 2005, 2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_CONFTYPES_H_) +#define _CONFTYPES_H_ + +/* Placeholder for future modifications if cross-compiling or building a + `fat' binary, e.g. on Apple Rhapsody. These values are used in multiple + files, so they appear here. */ +#if !defined (RHAPSODY) && !defined (MACOSX) +# define HOSTTYPE CONF_HOSTTYPE +# define OSTYPE CONF_OSTYPE +# define MACHTYPE CONF_MACHTYPE +#else /* RHAPSODY */ +# if defined(__powerpc__) || defined(__ppc__) +# define HOSTTYPE "powerpc" +# elif defined(__i386__) +# define HOSTTYPE "i386" +# else +# define HOSTTYPE CONF_HOSTTYPE +# endif + +# define OSTYPE CONF_OSTYPE +# define VENDOR CONF_VENDOR + +# define MACHTYPE HOSTTYPE "-" VENDOR "-" OSTYPE +#endif /* RHAPSODY */ + +#ifndef HOSTTYPE +# define HOSTTYPE "unknown" +#endif + +#ifndef OSTYPE +# define OSTYPE "unknown" +#endif + +#ifndef MACHTYPE +# define MACHTYPE "unknown" +#endif + +#endif /* _CONFTYPES_H_ */ diff --git a/utshell-0.5.0/variable/dispose_cmd.h b/utshell-0.5.0/variable/dispose_cmd.h new file mode 100644 index 00000000..7d5d6c32 --- /dev/null +++ b/utshell-0.5.0/variable/dispose_cmd.h @@ -0,0 +1,41 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* dispose_cmd.h -- Functions appearing in dispose_cmd.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_DISPOSE_CMD_H_) +#define _DISPOSE_CMD_H_ + +#include "stdc.h" + +extern void dispose_command PARAMS((COMMAND *)); +extern void dispose_word_desc PARAMS((WORD_DESC *)); +extern void dispose_word PARAMS((WORD_DESC *)); +extern void dispose_words PARAMS((WORD_LIST *)); +extern void dispose_word_array PARAMS((char **)); +extern void dispose_redirects PARAMS((REDIRECT *)); + +#if defined (COND_COMMAND) +extern void dispose_cond_node PARAMS((COND_COM *)); +#endif + +extern void dispose_function_def_contents PARAMS((FUNCTION_DEF *)); +extern void dispose_function_def PARAMS((FUNCTION_DEF *)); + +#endif /* !_DISPOSE_CMD_H_ */ diff --git a/utshell-0.5.0/variable/error.c b/utshell-0.5.0/variable/error.c new file mode 100644 index 00000000..6af57fed --- /dev/null +++ b/utshell-0.5.0/variable/error.c @@ -0,0 +1,415 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* error.c -- Functions for handling errors. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include "bashtypes.h" +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "bashansi.h" +#include "bashintl.h" + +#include "shell.h" +#include "execute_cmd.h" +#include "flags.h" +#include "input.h" + +#if defined (HISTORY) +# include "bashhist.h" +#endif + +extern int executing_line_number PARAMS((void)); + + + +#if defined (JOB_CONTROL) +extern pid_t shell_pgrp; +extern int give_terminal_to PARAMS((pid_t, int)); +#endif /* JOB_CONTROL */ + +#if defined (ARRAY_VARS) +extern const char * const bash_badsub_errmsg; +#endif + +/* The current maintainer of the shell. You change this in the + Makefile. */ +#if !defined (MAINTAINER) +#define MAINTAINER "bash-maintainers@gnu.org" +#endif + +// int gnu_error_format = 0; +extern int gnu_error_format; + +static void +error_prolog (print_lineno) + int print_lineno; +{ + char *ename; + int line; + + ename = get_name_for_error (); + line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1; + + if (line > 0) + fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line); + else + fprintf (stderr, "%s: ", ename); +} + + +void +#if defined (PREFER_STDARG) +programming_error (const char *format, ...) +#else +programming_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + char *h; + +#if defined (JOB_CONTROL) + give_terminal_to (shell_pgrp, 0); +#endif /* JOB_CONTROL */ + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + va_end (args); + +#if defined (HISTORY) + if (remember_on_history) + { + h = last_history_line (); + fprintf (stderr, _("last command: %s\n"), h ? h : "(null)"); + } +#endif + +#if 0 + fprintf (stderr, "Report this to %s\n", the_current_maintainer); +#endif + + fprintf (stderr, _("Aborting...")); + fflush (stderr); + + abort (); +} + +/* Print an error message and, if `set -e' has been executed, exit the + shell. Used in this file by file_error and programming_error. Used + outside this file mostly to report substitution and expansion errors, + and for bad invocation options. */ +void +#if defined (PREFER_STDARG) +report_error (const char *format, ...) +#else +report_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + error_prolog (1); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); + if (exit_immediately_on_error) + { + if (last_command_exit_value == 0) + last_command_exit_value = EXECUTION_FAILURE; + exit_shell (last_command_exit_value); + } +} + +void +#if defined (PREFER_STDARG) +fatal_error (const char *format, ...) +#else +fatal_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + error_prolog (0); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); + sh_exit (2); +} + +void +#if defined (PREFER_STDARG) +internal_error (const char *format, ...) +#else +internal_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + error_prolog (1); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); +} + +void +#if defined (PREFER_STDARG) +internal_warning (const char *format, ...) +#else +internal_warning (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + error_prolog (1); + fprintf (stderr, _("warning: ")); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); +} + +void +#if defined (PREFER_STDARG) +internal_inform (const char *format, ...) +#else +internal_inform (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + error_prolog (1); + /* TRANSLATORS: this is a prefix for informational messages. */ + fprintf (stderr, _("INFORM: ")); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); +} + +void +#if defined (PREFER_STDARG) +sys_error (const char *format, ...) +#else +sys_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + int e; + va_list args; + + e = errno; + error_prolog (0); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, ": %s\n", strerror (e)); + + va_end (args); +} + +/* An error from the parser takes the general form + + shell_name: input file name: line number: message + + The input file name and line number are omitted if the shell is + currently interactive. If the shell is not currently interactive, + the input file name is inserted only if it is different from the + shell name. */ +void +#if defined (PREFER_STDARG) +parser_error (int lineno, const char *format, ...) +#else +parser_error (lineno, format, va_alist) + int lineno; + const char *format; + va_dcl +#endif +{ + va_list args; + char *ename, *iname; + + ename = get_name_for_error (); + iname = yy_input_name (); + + if (interactive) + fprintf (stderr, "%s: ", ename); + else if (interactive_shell) + fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno); + else if (STREQ (ename, iname)) + fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno); + else + fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); + + if (exit_immediately_on_error) + exit_shell (last_command_exit_value = 2); +} + +#ifdef DEBUG +/* This assumes ASCII and is suitable only for debugging */ +char * +strescape (str) + const char *str; +{ + char *r, *result; + unsigned char *s; + + r = result = (char *)xmalloc (strlen (str) * 2 + 1); + + for (s = (unsigned char *)str; s && *s; s++) + { + if (*s < ' ') + { + *r++ = '^'; + *r++ = *s+64; + } + else if (*s == 127) + { + *r++ = '^'; + *r++ = '?'; + } + else + *r++ = *s; + } + + *r = '\0'; + return result; +} + +void +#if defined (PREFER_STDARG) +itrace (const char *format, ...) +#else +itrace (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + fprintf(stderr, "TRACE: pid %ld: ", (long)getpid()); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + fprintf (stderr, "\n"); + + va_end (args); + + fflush(stderr); +} + +/* A trace function for silent debugging -- doesn't require a control + terminal. */ +void +#if defined (PREFER_STDARG) +trace (const char *format, ...) +#else +trace (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + static FILE *tracefp = (FILE *)NULL; + + if (tracefp == NULL) + tracefp = fopen("/tmp/bash-trace.log", "a+"); + + if (tracefp == NULL) + tracefp = stderr; + else + fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */ + + fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid()); + + SH_VA_START (args, format); + + vfprintf (tracefp, format, args); + fprintf (tracefp, "\n"); + + va_end (args); + + fflush(tracefp); +} + +#endif /* DEBUG */ + +/* **************************************************************** */ +/* */ +/* Common error reporting */ +/* */ +/* **************************************************************** */ diff --git a/utshell-0.5.0/variable/error.h b/utshell-0.5.0/variable/error.h new file mode 100644 index 00000000..ecd6f0c8 --- /dev/null +++ b/utshell-0.5.0/variable/error.h @@ -0,0 +1,74 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* error.h -- External declarations of functions appearing in error.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_ERROR_H_) +#define _ERROR_H_ + +#include "stdc.h" + +/* Get the name of the shell or shell script for an error message. */ +extern char *get_name_for_error PARAMS((void)); + +/* Report an error having to do with FILENAME. */ +extern void file_error PARAMS((const char *)); + +/* Report a programmer's error, and abort. Pass REASON, and ARG1 ... ARG5. */ +extern void programming_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* General error reporting. Pass FORMAT and ARG1 ... ARG5. */ +extern void report_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Error messages for parts of the parser that don't call report_syntax_error */ +extern void parser_error PARAMS((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); + +/* Report an unrecoverable error and exit. Pass FORMAT and ARG1 ... ARG5. */ +extern void fatal_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report a system error, like BSD warn(3). */ +extern void sys_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report an internal error. */ +extern void internal_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report an internal warning. */ +extern void internal_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Report an internal informational notice. */ +extern void internal_inform PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); + +/* Debugging functions, not enabled in released version. */ +extern char *strescape PARAMS((const char *)); +extern void itrace PARAMS((const char *, ...)) __attribute__ ((__format__ (printf, 1, 2))); +extern void trace PARAMS((const char *, ...)) __attribute__ ((__format__ (printf, 1, 2))); + +/* Report an error having to do with command parsing or execution. */ +extern void command_error PARAMS((const char *, int, int, int)); + +extern char *command_errstr PARAMS((int)); + +/* Specific error message functions that eventually call report_error or + internal_error. */ + +extern void err_badarraysub PARAMS((const char *)); +extern void err_unboundvar PARAMS((const char *)); +extern void err_readonly PARAMS((const char *)); + +#endif /* !_ERROR_H_ */ diff --git a/utshell-0.5.0/variable/execute_cmd.h b/utshell-0.5.0/variable/execute_cmd.h new file mode 100644 index 00000000..43cfb218 --- /dev/null +++ b/utshell-0.5.0/variable/execute_cmd.h @@ -0,0 +1,127 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* execute_cmd.h - functions from execute_cmd.c. */ + +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_EXECUTE_CMD_H_) +#define _EXECUTE_CMD_H_ + +#include "stdc.h" +#include "variables.h" +#include "command.h" + + +#if defined (ARRAY_VARS) +struct func_array_state + { + ARRAY *funcname_a; + SHELL_VAR *funcname_v; + ARRAY *source_a; + SHELL_VAR *source_v; + ARRAY *lineno_a; + SHELL_VAR *lineno_v; + }; +#endif + +/* Placeholder for later expansion to include more execution state */ +/* XXX - watch out for pid_t */ +struct execstate + { + pid_t pid; + int subshell_env; + }; + + +/* Variables declared in execute_cmd.c, used by many other files */ +extern int return_catch_flag; +extern int return_catch_value; +extern volatile int last_command_exit_value; +extern int last_command_exit_signal; +extern int builtin_ignoring_errexit; +extern int executing_builtin; +extern int executing_list; +extern int comsub_ignore_return; +extern int subshell_level; +extern int match_ignore_case; +extern int executing_command_builtin; +extern int funcnest, funcnest_max; +extern int evalnest, evalnest_max; +extern int sourcenest, sourcenest_max; +extern int stdin_redir; +extern int line_number_for_err_trap; + +extern char *the_printed_command_except_trap; + +extern char *this_command_name; +extern SHELL_VAR *this_shell_function; + +/* Functions declared in execute_cmd.c, used by many other files */ + +extern struct fd_bitmap *new_fd_bitmap PARAMS((int)); +extern void dispose_fd_bitmap PARAMS((struct fd_bitmap *)); +extern void close_fd_bitmap PARAMS((struct fd_bitmap *)); +extern int executing_line_number PARAMS((void)); +extern int execute_command PARAMS((COMMAND *)); +extern int execute_command_internal PARAMS((COMMAND *, int, int, int, struct fd_bitmap *)); +extern int shell_execve PARAMS((char *, char **, char **)); +extern void setup_async_signals PARAMS((void)); +extern void async_redirect_stdin PARAMS((void)); + +extern void undo_partial_redirects PARAMS((void)); +extern void dispose_partial_redirects PARAMS((void)); +extern void dispose_exec_redirects PARAMS((void)); + +extern int execute_shell_function PARAMS((SHELL_VAR *, WORD_LIST *)); + +extern struct coproc *getcoprocbypid PARAMS((pid_t)); +extern struct coproc *getcoprocbyname PARAMS((const char *)); + +extern void coproc_init PARAMS((struct coproc *)); +extern struct coproc *coproc_alloc PARAMS((char *, pid_t)); +extern void coproc_dispose PARAMS((struct coproc *)); +extern void coproc_flush PARAMS((void)); +extern void coproc_close PARAMS((struct coproc *)); +extern void coproc_closeall PARAMS((void)); +extern void coproc_reap PARAMS((void)); +extern pid_t coproc_active PARAMS((void)); + +extern void coproc_rclose PARAMS((struct coproc *, int)); +extern void coproc_wclose PARAMS((struct coproc *, int)); +extern void coproc_fdclose PARAMS((struct coproc *, int)); + +extern void coproc_checkfd PARAMS((struct coproc *, int)); +extern void coproc_fdchk PARAMS((int)); + +extern void coproc_pidchk PARAMS((pid_t, int)); + +extern void coproc_fdsave PARAMS((struct coproc *)); +extern void coproc_fdrestore PARAMS((struct coproc *)); + +extern void coproc_setvars PARAMS((struct coproc *)); +extern void coproc_unsetvars PARAMS((struct coproc *)); + +#if defined (PROCESS_SUBSTITUTION) +extern void close_all_files PARAMS((void)); +#endif + +#if defined (ARRAY_VARS) +extern void restore_funcarray_state PARAMS((struct func_array_state *)); +#endif + +#endif /* _EXECUTE_CMD_H_ */ diff --git a/utshell-0.5.0/variable/externs.h b/utshell-0.5.0/variable/externs.h new file mode 100644 index 00000000..d87cf67a --- /dev/null +++ b/utshell-0.5.0/variable/externs.h @@ -0,0 +1,549 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* externs.h -- extern function declarations which do not appear in their + own header file. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Make sure that this is included *after* config.h! */ + +#if !defined (_EXTERNS_H_) +# define _EXTERNS_H_ + +#include "stdc.h" + +/* Functions from expr.c. */ +#define EXP_EXPANDED 0x01 + +extern intmax_t evalexp PARAMS((char *, int, int *)); + +/* Functions from print_cmd.c. */ +#define FUNC_MULTILINE 0x01 +#define FUNC_EXTERNAL 0x02 + +extern char *make_command_string PARAMS((COMMAND *)); +extern char *named_function_string PARAMS((char *, COMMAND *, int)); + +extern void print_command PARAMS((COMMAND *)); +extern void print_simple_command PARAMS((SIMPLE_COM *)); +extern void print_word_list PARAMS((WORD_LIST *, char *)); + +/* debugger support */ +extern void print_for_command_head PARAMS((FOR_COM *)); +#if defined (SELECT_COMMAND) +extern void print_select_command_head PARAMS((SELECT_COM *)); +#endif +extern void print_case_command_head PARAMS((CASE_COM *)); +#if defined (DPAREN_ARITHMETIC) +extern void print_arith_command PARAMS((WORD_LIST *)); +#endif +#if defined (COND_COMMAND) +extern void print_cond_command PARAMS((COND_COM *)); +#endif + +/* set -x support */ +extern void xtrace_init PARAMS((void)); +#ifdef NEED_XTRACE_SET_DECL +extern void xtrace_set PARAMS((int, FILE *)); +#endif +extern void xtrace_fdchk PARAMS((int)); +extern void xtrace_reset PARAMS((void)); +extern char *indirection_level_string PARAMS((void)); +extern void xtrace_print_assignment PARAMS((char *, char *, int, int)); +extern void xtrace_print_word_list PARAMS((WORD_LIST *, int)); +extern void xtrace_print_for_command_head PARAMS((FOR_COM *)); +#if defined (SELECT_COMMAND) +extern void xtrace_print_select_command_head PARAMS((SELECT_COM *)); +#endif +extern void xtrace_print_case_command_head PARAMS((CASE_COM *)); +#if defined (DPAREN_ARITHMETIC) +extern void xtrace_print_arith_cmd PARAMS((WORD_LIST *)); +#endif +#if defined (COND_COMMAND) +extern void xtrace_print_cond_term PARAMS((int, int, WORD_DESC *, char *, char *)); +#endif + +/* Functions from shell.c. */ +extern void exit_shell PARAMS((int)) __attribute__((__noreturn__)); +extern void sh_exit PARAMS((int)) __attribute__((__noreturn__)); +extern void subshell_exit PARAMS((int)) __attribute__((__noreturn__)); +extern void set_exit_status PARAMS((int)); +extern void disable_priv_mode PARAMS((void)); +extern void unbind_args PARAMS((void)); + +#if defined (RESTRICTED_SHELL) +extern int shell_is_restricted PARAMS((char *)); +extern int maybe_make_restricted PARAMS((char *)); +#endif + +extern void unset_bash_input PARAMS((int)); +extern void get_current_user_info PARAMS((void)); + +/* Functions from eval.c. */ +extern int reader_loop PARAMS((void)); +extern int pretty_print_loop PARAMS((void)); +extern int parse_command PARAMS((void)); +extern int read_command PARAMS((void)); + +/* Functions from braces.c. */ +#if defined (BRACE_EXPANSION) +extern char **brace_expand PARAMS((char *)); +#endif + +/* Miscellaneous functions from parse.y */ +extern int yyparse PARAMS((void)); +extern int return_EOF PARAMS((void)); +extern void push_token PARAMS((int)); +extern char *xparse_dolparen PARAMS((char *, char *, int *, int)); +extern void reset_parser PARAMS((void)); +extern void reset_readahead_token PARAMS((void)); +extern WORD_LIST *parse_string_to_word_list PARAMS((char *, int, const char *)); + +extern int parser_will_prompt PARAMS((void)); +extern int parser_in_command_position PARAMS((void)); + +extern void free_pushed_string_input PARAMS((void)); + +extern int parser_expanding_alias PARAMS((void)); +extern void parser_save_alias PARAMS((void)); +extern void parser_restore_alias PARAMS((void)); + +extern void clear_shell_input_line PARAMS((void)); + +extern char *decode_prompt_string PARAMS((char *)); + +extern int get_current_prompt_level PARAMS((void)); +extern void set_current_prompt_level PARAMS((int)); + +#if defined (HISTORY) +extern char *history_delimiting_chars PARAMS((const char *)); +#endif + +/* Declarations for functions defined in locale.c */ +extern void set_default_locale PARAMS((void)); +extern void set_default_locale_vars PARAMS((void)); +extern int set_locale_var PARAMS((char *, char *)); +extern int set_lang PARAMS((char *, char *)); +extern void set_default_lang PARAMS((void)); +extern char *get_locale_var PARAMS((char *)); +extern char *localetrans PARAMS((char *, int, int *)); +extern char *mk_msgstr PARAMS((char *, int *)); +extern char *localeexpand PARAMS((char *, int, int, int, int *)); +#ifndef locale_decpoint +extern int locale_decpoint PARAMS((void)); +#endif + +/* Declarations for functions defined in list.c. */ +extern void list_walk PARAMS((GENERIC_LIST *, sh_glist_func_t *)); +extern void wlist_walk PARAMS((WORD_LIST *, sh_icpfunc_t *)); +extern GENERIC_LIST *list_reverse (); +extern int list_length (); +extern GENERIC_LIST *list_append (); +extern GENERIC_LIST *list_remove (); + +/* Declarations for functions defined in stringlib.c */ +extern int find_string_in_alist PARAMS((char *, STRING_INT_ALIST *, int)); +extern char *find_token_in_alist PARAMS((int, STRING_INT_ALIST *, int)); +extern int find_index_in_alist PARAMS((char *, STRING_INT_ALIST *, int)); + +extern char *substring PARAMS((const char *, int, int)); +extern char *strsub PARAMS((char *, char *, char *, int)); +extern char *strcreplace PARAMS((char *, int, const char *, int)); +extern void strip_leading PARAMS((char *)); +extern void strip_trailing PARAMS((char *, int, int)); +extern void xbcopy PARAMS((char *, char *, int)); + +/* Functions from version.c. */ +extern char *shell_version_string PARAMS((void)); +extern void show_shell_version PARAMS((int)); + +/* Functions from the bash library, lib/sh/libsh.a. These should really + go into a separate include file. */ + +/* declarations for functions defined in lib/sh/casemod.c */ +extern char *sh_modcase PARAMS((const char *, char *, int)); + +/* Defines for flags argument to sh_modcase. These need to agree with what's + in lib/sh/casemode.c */ +#define CASE_LOWER 0x0001 +#define CASE_UPPER 0x0002 +#define CASE_CAPITALIZE 0x0004 +#define CASE_UNCAP 0x0008 +#define CASE_TOGGLE 0x0010 +#define CASE_TOGGLEALL 0x0020 +#define CASE_UPFIRST 0x0040 +#define CASE_LOWFIRST 0x0080 + +#define CASE_USEWORDS 0x1000 + +/* declarations for functions defined in lib/sh/clktck.c */ +extern long get_clk_tck PARAMS((void)); + +/* declarations for functions defined in lib/sh/clock.c */ +extern void clock_t_to_secs (); +extern void print_clock_t (); + +/* Declarations for functions defined in lib/sh/dprintf.c */ +#if !defined (HAVE_DPRINTF) +extern void dprintf PARAMS((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); +#endif + +/* Declarations for functions defined in lib/sh/fmtulong.c */ +#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ +#define FL_ADDBASE 0x02 /* add base# prefix to converted value */ +#define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ +#define FL_UNSIGNED 0x08 /* don't add any sign */ + +extern char *fmtulong PARAMS((unsigned long int, int, char *, size_t, int)); + +/* Declarations for functions defined in lib/sh/fmtulong.c */ +#if defined (HAVE_LONG_LONG) +extern char *fmtullong PARAMS((unsigned long long int, int, char *, size_t, int)); +#endif + +/* Declarations for functions defined in lib/sh/fmtumax.c */ +extern char *fmtumax PARAMS((uintmax_t, int, char *, size_t, int)); + +/* Declarations for functions defined in lib/sh/fnxform.c */ +extern char *fnx_fromfs PARAMS((char *, size_t)); +extern char *fnx_tofs PARAMS((char *, size_t)); + +/* Declarations for functions defined in lib/sh/fpurge.c */ + +#if defined NEED_FPURGE_DECL +#if !HAVE_DECL_FPURGE + +#if HAVE_FPURGE +# define fpurge _bash_fpurge +#endif +extern int fpurge PARAMS((FILE *stream)); + +#endif /* HAVE_DECL_FPURGE */ +#endif /* NEED_FPURGE_DECL */ + +/* Declarations for functions defined in lib/sh/getcwd.c */ +#if !defined (HAVE_GETCWD) +extern char *getcwd PARAMS((char *, size_t)); +#endif + +/* Declarations for functions defined in lib/sh/input_avail.c */ +extern int input_avail PARAMS((int)); + +/* Declarations for functions defined in lib/sh/itos.c */ +extern char *inttostr PARAMS((intmax_t, char *, size_t)); +extern char *itos PARAMS((intmax_t)); +extern char *mitos PARAMS((intmax_t)); +extern char *uinttostr PARAMS((uintmax_t, char *, size_t)); +extern char *uitos PARAMS((uintmax_t)); + +/* declarations for functions defined in lib/sh/makepath.c */ +#define MP_DOTILDE 0x01 +#define MP_DOCWD 0x02 +#define MP_RMDOT 0x04 +#define MP_IGNDOT 0x08 + +extern char *sh_makepath PARAMS((const char *, const char *, int)); + +/* declarations for functions defined in lib/sh/mbscasecmp.c */ +#if !defined (HAVE_MBSCASECMP) +extern char *mbscasecmp PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/mbschr.c */ +#if !defined (HAVE_MBSCHR) +extern char *mbschr PARAMS((const char *, int)); +#endif + +/* declarations for functions defined in lib/sh/mbscmp.c */ +#if !defined (HAVE_MBSCMP) +extern char *mbscmp PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/netconn.c */ +extern int isnetconn PARAMS((int)); + +/* declarations for functions defined in lib/sh/netopen.c */ +extern int netopen PARAMS((char *)); + +/* Declarations for functions defined in lib/sh/oslib.c */ + +#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN) +extern int dup2 PARAMS((int, int)); +#endif + +#if !defined (HAVE_GETDTABLESIZE) +extern int getdtablesize PARAMS((void)); +#endif /* !HAVE_GETDTABLESIZE */ + +#if !defined (HAVE_GETHOSTNAME) +extern int gethostname PARAMS((char *, int)); +#endif /* !HAVE_GETHOSTNAME */ + +extern int getmaxgroups PARAMS((void)); +extern long getmaxchild PARAMS((void)); + +/* declarations for functions defined in lib/sh/pathcanon.c */ +#define PATH_CHECKDOTDOT 0x0001 +#define PATH_CHECKEXISTS 0x0002 +#define PATH_HARDPATH 0x0004 +#define PATH_NOALLOC 0x0008 + +extern char *sh_canonpath PARAMS((char *, int)); + +/* declarations for functions defined in lib/sh/pathphys.c */ +extern char *sh_physpath PARAMS((char *, int)); +extern char *sh_realpath PARAMS((const char *, char *)); + +/* declarations for functions defined in lib/sh/random.c */ +extern int brand PARAMS((void)); +extern void sbrand PARAMS((unsigned long)); /* set bash random number generator. */ +extern void seedrand PARAMS((void)); /* seed generator randomly */ +extern void seedrand32 PARAMS((void)); +extern u_bits32_t get_urandom32 PARAMS((void)); + +/* declarations for functions defined in lib/sh/setlinebuf.c */ +#ifdef NEED_SH_SETLINEBUF_DECL +extern int sh_setlinebuf PARAMS((FILE *)); +#endif + +/* declarations for functions defined in lib/sh/shaccess.c */ +extern int sh_eaccess PARAMS((const char *, int)); + +/* declarations for functions defined in lib/sh/shmatch.c */ +extern int sh_regmatch PARAMS((const char *, const char *, int)); + +/* defines for flags argument to sh_regmatch. */ +#define SHMAT_SUBEXP 0x001 /* save subexpressions in SH_REMATCH */ +#define SHMAT_PWARN 0x002 /* print a warning message on invalid regexp */ + +/* declarations for functions defined in lib/sh/shmbchar.c */ +extern size_t mbstrlen PARAMS((const char *)); +extern char *mbsmbchar PARAMS((const char *)); +extern int sh_mbsnlen PARAMS((const char *, size_t, int)); + +/* declarations for functions defined in lib/sh/shquote.c */ +extern char *sh_single_quote PARAMS((const char *)); +extern char *sh_double_quote PARAMS((const char *)); +extern char *sh_mkdoublequoted PARAMS((const char *, int, int)); +extern char *sh_un_double_quote PARAMS((char *)); +extern char *sh_backslash_quote PARAMS((char *, const char *, int)); +extern char *sh_backslash_quote_for_double_quotes PARAMS((char *)); +extern char *sh_quote_reusable PARAMS((char *, int)); +extern int sh_contains_shell_metas PARAMS((const char *)); +extern int sh_contains_quotes PARAMS((const char *)); + +/* declarations for functions defined in lib/sh/spell.c */ +extern int spname PARAMS((char *, char *)); +extern char *dirspell PARAMS((char *)); + +/* declarations for functions defined in lib/sh/strcasecmp.c */ +#if !defined (HAVE_STRCASECMP) +extern int strncasecmp PARAMS((const char *, const char *, size_t)); +extern int strcasecmp PARAMS((const char *, const char *)); +#endif /* HAVE_STRCASECMP */ + +/* declarations for functions defined in lib/sh/strcasestr.c */ +#if ! HAVE_STRCASESTR +extern char *strcasestr PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/strchrnul.c */ +#if ! HAVE_STRCHRNUL +extern char *strchrnul PARAMS((const char *, int)); +#endif + +/* declarations for functions defined in lib/sh/strerror.c */ +#if !defined (HAVE_STRERROR) && !defined (strerror) +extern char *strerror PARAMS((int)); +#endif + +/* declarations for functions defined in lib/sh/strftime.c */ +#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL) +extern size_t strftime PARAMS((char *, size_t, const char *, const struct tm *)); +#endif + +/* declarations for functions and structures defined in lib/sh/stringlist.c */ + +/* This is a general-purpose argv-style array struct. */ +typedef struct _list_of_strings { + char **list; + int list_size; + int list_len; +} STRINGLIST; + +typedef int sh_strlist_map_func_t PARAMS((char *)); + +extern STRINGLIST *strlist_create PARAMS((int)); +extern STRINGLIST *strlist_resize PARAMS((STRINGLIST *, int)); +extern void strlist_flush PARAMS((STRINGLIST *)); +extern void strlist_dispose PARAMS((STRINGLIST *)); +extern int strlist_remove PARAMS((STRINGLIST *, char *)); +extern STRINGLIST *strlist_copy PARAMS((STRINGLIST *)); +extern STRINGLIST *strlist_merge PARAMS((STRINGLIST *, STRINGLIST *)); +extern STRINGLIST *strlist_append PARAMS((STRINGLIST *, STRINGLIST *)); +extern STRINGLIST *strlist_prefix_suffix PARAMS((STRINGLIST *, char *, char *)); +extern void strlist_print PARAMS((STRINGLIST *, char *)); +extern void strlist_walk PARAMS((STRINGLIST *, sh_strlist_map_func_t *)); +extern void strlist_sort PARAMS((STRINGLIST *)); + +/* declarations for functions defined in lib/sh/stringvec.c */ + +extern char **strvec_create PARAMS((int)); +extern char **strvec_resize PARAMS((char **, int)); +extern char **strvec_mcreate PARAMS((int)); +extern char **strvec_mresize PARAMS((char **, int)); +extern void strvec_flush PARAMS((char **)); +extern void strvec_dispose PARAMS((char **)); +extern int strvec_remove PARAMS((char **, char *)); +extern int strvec_len PARAMS((char **)); +extern int strvec_search PARAMS((char **, char *)); +extern char **strvec_copy PARAMS((char **)); +extern int strvec_posixcmp PARAMS((char **, char **)); +extern int strvec_strcmp PARAMS((char **, char **)); +extern void strvec_sort PARAMS((char **, int)); + +extern char **strvec_from_word_list PARAMS((WORD_LIST *, int, int, int *)); +extern WORD_LIST *strvec_to_word_list PARAMS((char **, int, int)); + +/* declarations for functions defined in lib/sh/strnlen.c */ +#if !defined (HAVE_STRNLEN) +extern size_t strnlen PARAMS((const char *, size_t)); +#endif + +/* declarations for functions defined in lib/sh/strpbrk.c */ +#if !defined (HAVE_STRPBRK) +extern char *strpbrk PARAMS((const char *, const char *)); +#endif + +/* declarations for functions defined in lib/sh/strtod.c */ +#if !defined (HAVE_STRTOD) +extern double strtod PARAMS((const char *, char **)); +#endif + +/* declarations for functions defined in lib/sh/strtol.c */ +#if !HAVE_DECL_STRTOL +extern long strtol PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtoll.c */ +#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOLL +extern long long strtoll PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtoul.c */ +#if !HAVE_DECL_STRTOUL +extern unsigned long strtoul PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtoull.c */ +#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOULL +extern unsigned long long strtoull PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strimax.c */ +#if !HAVE_DECL_STRTOIMAX +extern intmax_t strtoimax PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strumax.c */ +#if !HAVE_DECL_STRTOUMAX +extern uintmax_t strtoumax PARAMS((const char *, char **, int)); +#endif + +/* declarations for functions defined in lib/sh/strtrans.c */ +extern char *ansicstr PARAMS((char *, int, int, int *, int *)); +extern char *ansic_quote PARAMS((char *, int, int *)); +extern int ansic_shouldquote PARAMS((const char *)); +extern char *ansiexpand PARAMS((char *, int, int, int *)); + +/* declarations for functions defined in lib/sh/timeval.c. No prototypes + so we don't have to count on having a definition of struct timeval in + scope when this file is included. */ +extern void timeval_to_secs (); +extern void print_timeval (); + +/* declarations for functions defined in lib/sh/tmpfile.c */ +#define MT_USETMPDIR 0x0001 +#define MT_READWRITE 0x0002 +#define MT_USERANDOM 0x0004 +#define MT_TEMPLATE 0x0008 + +extern char *sh_mktmpname PARAMS((char *, int)); +extern int sh_mktmpfd PARAMS((char *, int, char **)); +/* extern FILE *sh_mktmpfp PARAMS((char *, int, char **)); */ +extern char *sh_mktmpdir PARAMS((char *, int)); + +/* declarations for functions defined in lib/sh/uconvert.c */ +extern int uconvert PARAMS((char *, long *, long *, char **)); + +/* declarations for functions defined in lib/sh/ufuncs.c */ +extern unsigned int falarm PARAMS((unsigned int, unsigned int)); +extern unsigned int fsleep PARAMS((unsigned int, unsigned int)); + +/* declarations for functions defined in lib/sh/unicode.c */ +extern int u32cconv PARAMS((unsigned long, char *)); +extern void u32reset PARAMS((void)); + +/* declarations for functions defined in lib/sh/utf8.c */ +extern char *utf8_mbschr PARAMS((const char *, int)); +extern int utf8_mbscmp PARAMS((const char *, const char *)); +extern char *utf8_mbsmbchar PARAMS((const char *)); +extern int utf8_mbsnlen PARAMS((const char *, size_t, int)); +extern int utf8_mblen PARAMS((const char *, size_t)); +extern size_t utf8_mbstrlen PARAMS((const char *)); + +/* declarations for functions defined in lib/sh/wcsnwidth.c */ +#if defined (HANDLE_MULTIBYTE) +extern int wcsnwidth PARAMS((const wchar_t *, size_t, int)); +#endif + +/* declarations for functions defined in lib/sh/winsize.c */ +extern void get_new_window_size PARAMS((int, int *, int *)); + +/* declarations for functions defined in lib/sh/zcatfd.c */ +extern int zcatfd PARAMS((int, int, char *)); + +/* declarations for functions defined in lib/sh/zgetline.c */ +extern ssize_t zgetline PARAMS((int, char **, size_t *, int, int)); + +/* declarations for functions defined in lib/sh/zmapfd.c */ +extern int zmapfd PARAMS((int, char **, char *)); + +/* declarations for functions defined in lib/sh/zread.c */ +extern ssize_t zread PARAMS((int, char *, size_t)); +extern ssize_t zreadretry PARAMS((int, char *, size_t)); +extern ssize_t zreadintr PARAMS((int, char *, size_t)); +extern ssize_t zreadc PARAMS((int, char *)); +extern ssize_t zreadcintr PARAMS((int, char *)); +extern ssize_t zreadn PARAMS((int, char *, size_t)); +extern void zreset PARAMS((void)); +extern void zsyncfd PARAMS((int)); + +/* declarations for functions defined in lib/sh/zwrite.c */ +extern int zwrite PARAMS((int, char *, size_t)); + +/* declarations for functions defined in lib/glob/gmisc.c */ +extern int match_pattern_char PARAMS((char *, char *, int)); +extern int umatchlen PARAMS((char *, size_t)); + +#if defined (HANDLE_MULTIBYTE) +extern int match_pattern_wchar PARAMS((wchar_t *, wchar_t *, int)); +extern int wmatchlen PARAMS((wchar_t *, size_t)); +#endif + +#endif /* _EXTERNS_H_ */ diff --git a/utshell-0.5.0/variable/flags.h b/utshell-0.5.0/variable/flags.h new file mode 100644 index 00000000..dd51f3b2 --- /dev/null +++ b/utshell-0.5.0/variable/flags.h @@ -0,0 +1,88 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* flags.h -- a list of all the flags that the shell knows about. You add + a flag to this program by adding the name here, and in flags.c. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_FLAGS_H_) +#define _FLAGS_H_ + +#include "stdc.h" + +/* Welcome to the world of Un*x, where everything is slightly backwards. */ +#define FLAG_ON '-' +#define FLAG_OFF '+' + +#define FLAG_ERROR -1 +#define FLAG_UNKNOWN (int *)0 + +/* The thing that we build the array of flags out of. */ +struct flags_alist { + char name; + int *value; +}; + +extern const struct flags_alist shell_flags[]; +extern char optflags[]; + +extern int + mark_modified_vars, errexit_flag, exit_immediately_on_error, + disallow_filename_globbing, + place_keywords_in_env, read_but_dont_execute, + just_one_command, unbound_vars_is_error, echo_input_at_read, verbose_flag, + echo_command_at_execute, noclobber, + hashing_enabled, forced_interactive, privileged_mode, jobs_m_flag, + asynchronous_notification, interactive_comments, no_symbolic_links, + function_trace_mode, error_trace_mode, pipefail_opt; + +/* -c, -s invocation options -- not really flags, but they show up in $- */ +extern int want_pending_command, read_from_stdin; + +#if 0 +extern int lexical_scoping; +#endif + +#if defined (BRACE_EXPANSION) +extern int brace_expansion; +#endif + +#if defined (BANG_HISTORY) +extern int history_expansion; +extern int histexp_flag; +#endif /* BANG_HISTORY */ + +#if defined (RESTRICTED_SHELL) +extern int restricted; +extern int restricted_shell; +#endif /* RESTRICTED_SHELL */ + +extern int *find_flag PARAMS((int)); +extern int change_flag PARAMS((int, int)); +extern char *which_set_flags PARAMS((void)); +extern void reset_shell_flags PARAMS((void)); + +extern char *get_current_flags PARAMS((void)); +extern void set_current_flags PARAMS((const char *)); + +extern void initialize_flags PARAMS((void)); + +/* A macro for efficiency. */ +#define change_flag_char(flag, on_or_off) change_flag (flag, on_or_off) + +#endif /* _FLAGS_H_ */ diff --git a/utshell-0.5.0/variable/general.h b/utshell-0.5.0/variable/general.h new file mode 100644 index 00000000..1c1d1c67 --- /dev/null +++ b/utshell-0.5.0/variable/general.h @@ -0,0 +1,372 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* general.h -- defines that everybody likes to use. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_GENERAL_H_) +#define _GENERAL_H_ + +#include "stdc.h" + +#include "bashtypes.h" +#include "chartypes.h" + +#if defined (HAVE_SYS_RESOURCE_H) && defined (RLIMTYPE) +# if defined (HAVE_SYS_TIME_H) +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include "xmalloc.h" + +/* NULL pointer type. */ +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* Hardly used anymore */ +#define pointer_to_int(x) (int)((char *)x - (char *)0) + +#if defined (alpha) && defined (__GNUC__) && !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif + +#if !defined (strcpy) && (defined (HAVE_DECL_STRCPY) && !HAVE_DECL_STRCPY) +extern char *strcpy PARAMS((char *, const char *)); +#endif + +#if !defined (savestring) +# define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x)) +#endif + +#ifndef member +# define member(c, s) ((c) ? ((char *)mbschr ((s), (c)) != (char *)NULL) : 0) +#endif + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifndef CHAR_MAX +# ifdef __CHAR_UNSIGNED__ +# define CHAR_MAX 0xff +# else +# define CHAR_MAX 0x7f +# endif +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* The width in bits of the integer type or expression T. + Padding bits are not supported; this is checked at compile-time below. */ +#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) + +/* Bound on length of the string representing an unsigned integer + value representable in B bits. log10 (2.0) < 146/485. The + smallest value of B where this bound is not tight is 2621. */ +#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((TYPE_WIDTH (t) - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) + +/* Updated version adapted from gnulib/intprops.h, not used right now. + Changes the approximation of log10(2) from 302/1000 to 146/485. */ +#if 0 +#define INT_STRLEN_BOUND(t) \ + (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - TYPE_SIGNED (t)) + TYPE_SIGNED(t)) +#endif + +/* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + +/* Define exactly what a legal shell identifier consists of. */ +#define legal_variable_starter(c) (ISALPHA(c) || (c == '_')) +#define legal_variable_char(c) (ISALNUM(c) || c == '_') + +/* Definitions used in subst.c and by the `read' builtin for field + splitting. */ +#define spctabnl(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') + +/* All structs which contain a `next' field should have that field + as the first field in the struct. This means that functions + can be written to handle the general case for linked lists. */ +typedef struct g_list { + struct g_list *next; +} GENERIC_LIST; + +/* Here is a generic structure for associating character strings + with integers. It is used in the parser for shell tokenization. */ +typedef struct { + char *word; + int token; +} STRING_INT_ALIST; + +/* A macro to avoid making an unnecessary function call. */ +#define REVERSE_LIST(list, type) \ + ((list && list->next) ? (type)list_reverse ((GENERIC_LIST *)list) \ + : (type)(list)) + +#if __GNUC__ > 1 +# define FASTCOPY(s, d, n) __builtin_memcpy ((d), (s), (n)) +#else /* !__GNUC__ */ +# if !defined (HAVE_BCOPY) +# if !defined (HAVE_MEMMOVE) +# define FASTCOPY(s, d, n) memcpy ((d), (s), (n)) +# else +# define FASTCOPY(s, d, n) memmove ((d), (s), (n)) +# endif /* !HAVE_MEMMOVE */ +# else /* HAVE_BCOPY */ +# define FASTCOPY(s, d, n) bcopy ((s), (d), (n)) +# endif /* HAVE_BCOPY */ +#endif /* !__GNUC__ */ + +/* String comparisons that possibly save a function call each. */ +#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) +#define STREQN(a, b, n) ((n == 0) ? (1) \ + : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)) + +/* More convenience definitions that possibly save system or libc calls. */ +#define STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0) +#define FREE(s) do { if (s) free (s); s = NULL; } while (0) +#define MEMBER(c, s) (((c) && c == (s)[0] && !(s)[1]) || (member(c, s))) + +/* A fairly hairy macro to check whether an allocated string has more room, + and to resize it using xrealloc if it does not. + STR is the string (char *) + CIND is the current index into the string (int) + ROOM is the amount of additional room we need in the string (int) + CSIZE is the currently-allocated size of STR (int) + SINCR is how much to increment CSIZE before calling xrealloc (int) */ + +#define RESIZE_MALLOCED_BUFFER(str, cind, room, csize, sincr) \ + do { \ + if ((cind) + (room) >= csize) \ + { \ + while ((cind) + (room) >= csize) \ + csize += (sincr); \ + str = xrealloc (str, csize); \ + } \ + } while (0) + +/* Function pointers can be declared as (Function *)foo. */ +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); /* no longer used */ +typedef char **CPPFunction (); /* no longer used */ +#endif /* _FUNCTION_DEF */ + +#ifndef SH_FUNCTION_TYPEDEF +# define SH_FUNCTION_TYPEDEF + +/* Shell function typedefs with prototypes */ +/* `Generic' function pointer typedefs */ + +typedef int sh_intfunc_t PARAMS((int)); +typedef int sh_ivoidfunc_t PARAMS((void)); +typedef int sh_icpfunc_t PARAMS((char *)); +typedef int sh_icppfunc_t PARAMS((char **)); +typedef int sh_iptrfunc_t PARAMS((PTR_T)); + +typedef void sh_voidfunc_t PARAMS((void)); +typedef void sh_vintfunc_t PARAMS((int)); +typedef void sh_vcpfunc_t PARAMS((char *)); +typedef void sh_vcppfunc_t PARAMS((char **)); +typedef void sh_vptrfunc_t PARAMS((PTR_T)); + +typedef int sh_wdesc_func_t PARAMS((WORD_DESC *)); +typedef int sh_wlist_func_t PARAMS((WORD_LIST *)); + +typedef int sh_glist_func_t PARAMS((GENERIC_LIST *)); + +typedef char *sh_string_func_t PARAMS((char *)); /* like savestring, et al. */ + +typedef int sh_msg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ +typedef void sh_vmsg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ + +/* Specific function pointer typedefs. Most of these could be done + with #defines. */ +typedef void sh_sv_func_t PARAMS((char *)); /* sh_vcpfunc_t */ +typedef void sh_free_func_t PARAMS((PTR_T)); /* sh_vptrfunc_t */ +typedef void sh_resetsig_func_t PARAMS((int)); /* sh_vintfunc_t */ + +typedef int sh_ignore_func_t PARAMS((const char *)); /* sh_icpfunc_t */ + +typedef int sh_assign_func_t PARAMS((const char *)); +typedef int sh_wassign_func_t PARAMS((WORD_DESC *, int)); + +typedef int sh_load_func_t PARAMS((char *)); +typedef void sh_unload_func_t PARAMS((char *)); + +typedef int sh_builtin_func_t PARAMS((WORD_LIST *)); /* sh_wlist_func_t */ + +#endif /* SH_FUNCTION_TYPEDEF */ + +#define NOW ((time_t) time ((time_t *) 0)) +#define GETTIME(tv) gettimeofday(&(tv), NULL) + +/* Some defines for calling file status functions. */ +#define FS_EXISTS 0x1 +#define FS_EXECABLE 0x2 +#define FS_EXEC_PREFERRED 0x4 +#define FS_EXEC_ONLY 0x8 +#define FS_DIRECTORY 0x10 +#define FS_NODIRS 0x20 +#define FS_READABLE 0x40 + +/* Default maximum for move_to_high_fd */ +#define HIGH_FD_MAX 256 + +/* The type of function passed as the fourth argument to qsort(3). */ +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +/* Some useful definitions for Unix pathnames. Argument convention: + x == string, c == character */ + +#if !defined (__CYGWIN__) +# define ABSPATH(x) ((x)[0] == '/') +# define RELPATH(x) ((x)[0] != '/') +#else /* __CYGWIN__ */ +# define ABSPATH(x) (((x)[0] && ISALPHA((unsigned char)(x)[0]) && (x)[1] == ':') || ISDIRSEP((x)[0])) +# define RELPATH(x) (ABSPATH(x) == 0) +#endif /* __CYGWIN__ */ + +#define ROOTEDPATH(x) (ABSPATH(x)) + +#define DIRSEP '/' +#if !defined (__CYGWIN__) +# define ISDIRSEP(c) ((c) == '/') +#else +# define ISDIRSEP(c) ((c) == '/' || (c) == '\\') +#endif /* __CYGWIN__ */ +#define PATHSEP(c) (ISDIRSEP(c) || (c) == 0) + +#define DOT_OR_DOTDOT(s) (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) +#if defined (HANDLE_MULTIBYTE) +#define WDOT_OR_DOTDOT(w) (w[0] == L'.' && (w[1] == L'\0' || (w[1] == L'.' && w[2] == L'\0'))) +#endif + +#if 0 +/* Declarations for functions defined in xmalloc.c */ +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); +#endif + +/* Declarations for functions defined in general.c */ +extern void posix_initialize PARAMS((int)); + +extern int num_posix_options PARAMS((void)); +extern char *get_posix_options PARAMS((char *)); +extern void set_posix_options PARAMS((const char *)); + +extern void save_posix_options PARAMS((void)); + +#if defined (RLIMTYPE) +extern RLIMTYPE string_to_rlimtype PARAMS((char *)); +extern void print_rlimtype PARAMS((RLIMTYPE, int)); +#endif + +extern int all_digits PARAMS((const char *)); +extern int legal_number PARAMS((const char *, intmax_t *)); +extern int legal_identifier PARAMS((const char *)); +extern int importable_function_name PARAMS((const char *, size_t)); +extern int exportable_function_name PARAMS((const char *)); +extern int check_identifier PARAMS((WORD_DESC *, int)); +extern int valid_nameref_value PARAMS((const char *, int)); +extern int check_selfref PARAMS((const char *, char *, int)); +extern int legal_alias_name PARAMS((const char *, int)); +extern int line_isblank PARAMS((const char *)); +extern int assignment PARAMS((const char *, int)); + +extern int sh_unset_nodelay_mode PARAMS((int)); +extern int sh_setclexec PARAMS((int)); +extern int sh_validfd PARAMS((int)); +extern int fd_ispipe PARAMS((int)); +extern void check_dev_tty PARAMS((void)); +extern int move_to_high_fd PARAMS((int, int, int)); +extern int check_binary_file PARAMS((const char *, int)); + +#ifdef _POSIXSTAT_H_ +extern int same_file PARAMS((const char *, const char *, struct stat *, struct stat *)); +#endif + +extern int sh_openpipe PARAMS((int *)); +extern int sh_closepipe PARAMS((int *)); + +extern int file_exists PARAMS((const char *)); +extern int file_isdir PARAMS((const char *)); +extern int file_iswdir PARAMS((const char *)); +extern int path_dot_or_dotdot PARAMS((const char *)); +extern int absolute_pathname PARAMS((const char *)); +extern int absolute_program PARAMS((const char *)); + +extern char *make_absolute PARAMS((const char *, const char *)); +extern char *base_pathname PARAMS((char *)); +extern char *full_pathname PARAMS((char *)); +extern char *polite_directory_format PARAMS((char *)); +extern char *trim_pathname PARAMS((char *, int)); +extern char *printable_filename PARAMS((char *, int)); + +extern char *extract_colon_unit PARAMS((char *, int *)); + +extern void tilde_initialize PARAMS((void)); +extern char *bash_tilde_find_word PARAMS((const char *, int, int *)); +extern char *bash_tilde_expand PARAMS((const char *, int)); + +extern int group_member PARAMS((gid_t)); +extern char **get_group_list PARAMS((int *)); +extern int *get_group_array PARAMS((int *)); + +extern char *conf_standard_path PARAMS((void)); +extern int default_columns PARAMS((void)); + +#endif /* _GENERAL_H_ */ diff --git a/utshell-0.5.0/variable/gettext.h b/utshell-0.5.0/variable/gettext.h new file mode 100644 index 00000000..97a1f36d --- /dev/null +++ b/utshell-0.5.0/variable/gettext.h @@ -0,0 +1,70 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff --git a/utshell-0.5.0/variable/glob.h b/utshell-0.5.0/variable/glob.h new file mode 100644 index 00000000..ca3a66cf --- /dev/null +++ b/utshell-0.5.0/variable/glob.h @@ -0,0 +1,46 @@ +/* File-name wildcard pattern matching for GNU. + Copyright (C) 1985-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include "stdc.h" + +#define GX_MARKDIRS 0x001 /* mark directory names with trailing `/' */ +#define GX_NOCASE 0x002 /* ignore case */ +#define GX_MATCHDOT 0x004 /* match `.' literally */ +#define GX_MATCHDIRS 0x008 /* match only directory names */ +#define GX_ALLDIRS 0x010 /* match all directory names, no others */ +#define GX_NULLDIR 0x100 /* internal -- no directory preceding pattern */ +#define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */ +#define GX_GLOBSTAR 0x400 /* turn on special handling of ** */ +#define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */ +#define GX_SYMLINK 0x1000 /* internal -- symlink to a directory */ + +extern int glob_pattern_p PARAMS((const char *)); +extern char **glob_vector PARAMS((char *, char *, int)); +extern char **glob_filename PARAMS((char *, int)); + +extern int extglob_pattern_p PARAMS((const char *)); + +extern char *glob_error_return; +extern int noglob_dot_filenames; +extern int glob_ignore_case; + +#endif /* _GLOB_H_ */ diff --git a/utshell-0.5.0/variable/hashlib.c b/utshell-0.5.0/variable/hashlib.c new file mode 100644 index 00000000..61a463cc --- /dev/null +++ b/utshell-0.5.0/variable/hashlib.c @@ -0,0 +1,170 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* hashlib.c -- functions to manage and access hash tables for bash. */ + +/* Copyright (C) 1987,1989,1991,1995,1998,2001,2003,2005,2006,2008,2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include "bashansi.h" + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include "shell.h" +#include "hashlib.h" + +/* tunable constants for rehashing */ +#define HASH_REHASH_MULTIPLIER 4 +#define HASH_REHASH_FACTOR 2 + +#define HASH_SHOULDGROW(table) \ + ((table)->nentries >= (table)->nbuckets * HASH_REHASH_FACTOR) + +/* an initial approximation */ +#define HASH_SHOULDSHRINK(table) \ + (((table)->nbuckets > DEFAULT_HASH_BUCKETS) && \ + ((table)->nentries < (table)->nbuckets / HASH_REHASH_MULTIPLIER)) + +/* Rely on properties of unsigned division (unsigned/int -> unsigned) and + don't discard the upper 32 bits of the value, if present. */ +#define HASH_BUCKET(s, t, h) (((h) = hash_string (s)) & ((t)->nbuckets - 1)) + +#define FNV_OFFSET 2166136261 +#define FNV_PRIME 16777619 + + + +#if defined (DEBUG) || defined (TEST_HASHING) +void +hash_pstats (table, name) + HASH_TABLE *table; + char *name; +{ + register int slot, bcount; + register BUCKET_CONTENTS *bc; + + if (name == 0) + name = "unknown hash table"; + + fprintf (stderr, "%s: %d buckets; %d items\n", name, table->nbuckets, table->nentries); + + /* Print out a count of how many strings hashed to each bucket, so we can + see how even the distribution is. */ + for (slot = 0; slot < table->nbuckets; slot++) + { + bc = hash_items (slot, table); + + fprintf (stderr, "\tslot %3d: ", slot); + for (bcount = 0; bc; bc = bc->next) + bcount++; + + fprintf (stderr, "%d\n", bcount); + } +} +#endif + +#ifdef TEST_HASHING + +/* link with xmalloc.o and lib/malloc/libmalloc.a */ +#undef NULL +#include + +#ifndef NULL +#define NULL 0 +#endif + +HASH_TABLE *table, *ntable; + +int interrupt_immediately = 0; +int running_trap = 0; + +int +signal_is_trapped (s) + int s; +{ + return (0); +} + +void +programming_error (const char *format, ...) +{ + abort(); +} + +void +fatal_error (const char *format, ...) +{ + abort(); +} + +void +internal_warning (const char *format, ...) +{ +} + +int +main () +{ + char string[256]; + int count = 0; + BUCKET_CONTENTS *tt; + +#if defined (TEST_NBUCKETS) + table = hash_create (TEST_NBUCKETS); +#else + table = hash_create (0); +#endif + + for (;;) + { + char *temp_string; + if (fgets (string, sizeof (string), stdin) == 0) + break; + if (!*string) + break; + temp_string = savestring (string); + tt = hash_insert (temp_string, table, 0); + if (tt->times_found) + { + fprintf (stderr, "You have already added item `%s'\n", string); + free (temp_string); + temp_string = NULL + } + else + { + count++; + } + } + + hash_pstats (table, "hash test"); + + ntable = hash_copy (table, (sh_string_func_t *)NULL); + hash_flush (table, (sh_free_func_t *)NULL); + hash_pstats (ntable, "hash copy test"); + + exit (0); +} + +#endif /* TEST_HASHING */ diff --git a/utshell-0.5.0/variable/hashlib.h b/utshell-0.5.0/variable/hashlib.h new file mode 100644 index 00000000..6cf0406c --- /dev/null +++ b/utshell-0.5.0/variable/hashlib.h @@ -0,0 +1,93 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* hashlib.h -- the data structures used in hashing in Bash. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_HASHLIB_H_) +#define _HASHLIB_H_ + +#include "stdc.h" + +#ifndef PTR_T +# ifdef __STDC__ +# define PTR_T void * +# else +# define PTR_T char * +# endif +#endif + +typedef struct bucket_contents { + struct bucket_contents *next; /* Link to next hashed key in this bucket. */ + char *key; /* What we look up. */ + PTR_T data; /* What we really want. */ + unsigned int khash; /* What key hashes to */ + int times_found; /* Number of times this item has been found. */ +} BUCKET_CONTENTS; + +typedef struct hash_table { + BUCKET_CONTENTS **bucket_array; /* Where the data is kept. */ + int nbuckets; /* How many buckets does this table have. */ + int nentries; /* How many entries does this table have. */ +} HASH_TABLE; + +typedef int hash_wfunc PARAMS((BUCKET_CONTENTS *)); + +/* Operations on tables as a whole */ +extern HASH_TABLE *hash_create PARAMS((int)); +extern HASH_TABLE *hash_copy PARAMS((HASH_TABLE *, sh_string_func_t *)); +extern void hash_flush PARAMS((HASH_TABLE *, sh_free_func_t *)); +extern void hash_dispose PARAMS((HASH_TABLE *)); +extern void hash_walk PARAMS((HASH_TABLE *, hash_wfunc *)); + +/* Operations to extract information from or pieces of tables */ +extern int hash_bucket PARAMS((const char *, HASH_TABLE *)); +extern int hash_size PARAMS((HASH_TABLE *)); + +/* Operations on hash table entries */ +extern BUCKET_CONTENTS *hash_search PARAMS((const char *, HASH_TABLE *, int)); +extern BUCKET_CONTENTS *hash_insert PARAMS((char *, HASH_TABLE *, int)); +extern BUCKET_CONTENTS *hash_remove PARAMS((const char *, HASH_TABLE *, int)); + +/* Miscellaneous */ +extern unsigned int hash_string PARAMS((const char *)); + +/* Redefine the function as a macro for speed. */ +#define hash_items(bucket, table) \ + ((table && (bucket < table->nbuckets)) ? \ + table->bucket_array[bucket] : \ + (BUCKET_CONTENTS *)NULL) + +/* Default number of buckets in the hash table. */ +#define DEFAULT_HASH_BUCKETS 128 /* must be power of two */ + +#define HASH_ENTRIES(ht) ((ht) ? (ht)->nentries : 0) + +/* flags for hash_search and hash_insert */ +#define HASH_NOSRCH 0x01 +#define HASH_CREATE 0x02 + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +#endif /* _HASHLIB_H */ diff --git a/utshell-0.5.0/variable/history.h b/utshell-0.5.0/variable/history.h new file mode 100644 index 00000000..5211cb38 --- /dev/null +++ b/utshell-0.5.0/variable/history.h @@ -0,0 +1,286 @@ +/* history.h -- the names of functions that you can call in history. */ + +/* Copyright (C) 1989-2015 Free Software Foundation, Inc. + + This file contains the GNU History Library (History), a set of + routines for managing the text of previously typed lines. + + History is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + History is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with History. If not, see . +*/ + +#ifndef _HISTORY_H_ +#define _HISTORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include /* XXX - for history timestamp code */ + +#if defined READLINE_LIBRARY +# include "rlstdc.h" +# include "rltypedefs.h" +#else +# include "rlstdc.h" +# include "rltypedefs.h" +#endif + +#ifdef __STDC__ +typedef void *histdata_t; +#else +typedef char *histdata_t; +#endif + +/* The structure used to store a history entry. */ +typedef struct _hist_entry { + char *line; + char *timestamp; /* char * rather than time_t for read/write */ + histdata_t data; +} HIST_ENTRY; + +/* Size of the history-library-managed space in history entry HS. */ +#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp)) + +/* A structure used to pass the current state of the history stuff around. */ +typedef struct _hist_state { + HIST_ENTRY **entries; /* Pointer to the entries themselves. */ + int offset; /* The location pointer within this array. */ + int length; /* Number of elements within this array. */ + int size; /* Number of slots allocated to this array. */ + int flags; +} HISTORY_STATE; + +/* Flag values for the `flags' member of HISTORY_STATE. */ +#define HS_STIFLED 0x01 + +/* Initialization and state management. */ + +/* Begin a session in which the history functions might be used. This + just initializes the interactive variables. */ +extern void using_history PARAMS((void)); + +/* Return the current HISTORY_STATE of the history. */ +extern HISTORY_STATE *history_get_history_state PARAMS((void)); + +/* Set the state of the current history array to STATE. */ +extern void history_set_history_state PARAMS((HISTORY_STATE *)); + +/* Manage the history list. */ + +/* Place STRING at the end of the history list. + The associated data field (if any) is set to NULL. */ +extern void add_history PARAMS((const char *)); + +/* Change the timestamp associated with the most recent history entry to + STRING. */ +extern void add_history_time PARAMS((const char *)); + +/* Remove an entry from the history list. WHICH is the magic number that + tells us which element to delete. The elements are numbered from 0. */ +extern HIST_ENTRY *remove_history PARAMS((int)); + +/* Remove a set of entries from the history list: FIRST to LAST, inclusive */ +extern HIST_ENTRY **remove_history_range PARAMS((int, int)); + +/* Allocate a history entry consisting of STRING and TIMESTAMP and return + a pointer to it. */ +extern HIST_ENTRY *alloc_history_entry PARAMS((char *, char *)); + +/* Copy the history entry H, but not the (opaque) data pointer */ +extern HIST_ENTRY *copy_history_entry PARAMS((HIST_ENTRY *)); + +/* Free the history entry H and return any application-specific data + associated with it. */ +extern histdata_t free_history_entry PARAMS((HIST_ENTRY *)); + +/* Make the history entry at WHICH have LINE and DATA. This returns + the old entry so you can dispose of the data. In the case of an + invalid WHICH, a NULL pointer is returned. */ +extern HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t)); + +/* Clear the history list and start over. */ +extern void clear_history PARAMS((void)); + +/* Stifle the history list, remembering only MAX number of entries. */ +extern void stifle_history PARAMS((int)); + +/* Stop stifling the history. This returns the previous amount the + history was stifled by. The value is positive if the history was + stifled, negative if it wasn't. */ +extern int unstifle_history PARAMS((void)); + +/* Return 1 if the history is stifled, 0 if it is not. */ +extern int history_is_stifled PARAMS((void)); + +/* Information about the history list. */ + +/* Return a NULL terminated array of HIST_ENTRY which is the current input + history. Element 0 of this list is the beginning of time. If there + is no history, return NULL. */ +extern HIST_ENTRY **history_list PARAMS((void)); + +/* Returns the number which says what history element we are now + looking at. */ +extern int where_history PARAMS((void)); + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +extern HIST_ENTRY *current_history PARAMS((void)); + +/* Return the history entry which is logically at OFFSET in the history + array. OFFSET is relative to history_base. */ +extern HIST_ENTRY *history_get PARAMS((int)); + +/* Return the timestamp associated with the HIST_ENTRY * passed as an + argument */ +extern time_t history_get_time PARAMS((HIST_ENTRY *)); + +/* Return the number of bytes that the primary history entries are using. + This just adds up the lengths of the_history->lines. */ +extern int history_total_bytes PARAMS((void)); + +/* Moving around the history list. */ + +/* Set the position in the history list to POS. */ +extern int history_set_pos PARAMS((int)); + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry, return + a NULL pointer. */ +extern HIST_ENTRY *previous_history PARAMS((void)); + +/* Move history_offset forward to the next item in the input_history, + and return the a pointer to that entry. If there is no next entry, + return a NULL pointer. */ +extern HIST_ENTRY *next_history PARAMS((void)); + +/* Searching the history list. */ + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, + else through subsequent. If the string is found, then + current_history () is the history entry, and the value of this function + is the offset in the line of that history entry that the string was + found in. Otherwise, nothing is changed, and a -1 is returned. */ +extern int history_search PARAMS((const char *, int)); + +/* Search the history for STRING, starting at history_offset. + The search is anchored: matching lines must begin with string. + DIRECTION is as in history_search(). */ +extern int history_search_prefix PARAMS((const char *, int)); + +/* Search for STRING in the history list, starting at POS, an + absolute index into the list. DIR, if negative, says to search + backwards from POS, else forwards. + Returns the absolute index of the history element where STRING + was found, or -1 otherwise. */ +extern int history_search_pos PARAMS((const char *, int, int)); + +/* Managing the history file. */ + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +extern int read_history PARAMS((const char *)); + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +extern int read_history_range PARAMS((const char *, int, int)); + +/* Write the current history to FILENAME. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history (). */ +extern int write_history PARAMS((const char *)); + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +extern int append_history PARAMS((int, const char *)); + +/* Truncate the history file, leaving only the last NLINES lines. */ +extern int history_truncate_file PARAMS((const char *, int)); + +/* History expansion. */ + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + -1) If there was an error in expansion. + 2) If the returned line should just be printed. + + If an error occurred in expansion, then OUTPUT contains a descriptive + error message. */ +extern int history_expand PARAMS((char *, char **)); + +/* Extract a string segment consisting of the FIRST through LAST + arguments present in STRING. Arguments are broken up as in + the shell. */ +extern char *history_arg_extract PARAMS((int, int, const char *)); + +/* Return the text of the history event beginning at the current + offset into STRING. Pass STRING with *INDEX equal to the + history_expansion_char that begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. */ +extern char *get_history_event PARAMS((const char *, int *, int)); + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +extern char **history_tokenize PARAMS((const char *)); + +/* Exported history variables. */ +extern int history_base; +extern int history_length; +extern int history_max_entries; +extern int history_offset; + +extern int history_lines_read_from_file; +extern int history_lines_written_to_file; + +extern char history_expansion_char; +extern char history_subst_char; +extern char *history_word_delimiters; +extern char history_comment_char; +extern char *history_no_expand_chars; +extern char *history_search_delimiter_chars; + +extern int history_quotes_inhibit_expansion; +extern int history_quoting_state; + +extern int history_write_timestamps; + +/* These two are undocumented; the second is reserved for future use */ +extern int history_multiline_entries; +extern int history_file_version; + +/* Backwards compatibility */ +extern int max_input_history; + +/* If set, this function is called to decide whether or not a particular + history expansion should be treated as a special case for the calling + application and not expanded. */ +extern rl_linebuf_func_t *history_inhibit_expansion_function; + +#ifdef __cplusplus +} +#endif + +#endif /* !_HISTORY_H_ */ diff --git a/utshell-0.5.0/variable/input.h b/utshell-0.5.0/variable/input.h new file mode 100644 index 00000000..1d7c216f --- /dev/null +++ b/utshell-0.5.0/variable/input.h @@ -0,0 +1,136 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* input.h -- Structures and unions used for reading input. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_INPUT_H_) +#define _INPUT_H_ + +#include "stdc.h" + +/* Function pointers can be declared as (Function *)foo. */ +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); /* no longer used */ +typedef char **CPPFunction (); /* no longer used */ +#endif /* _FUNCTION_DEF */ + +typedef int sh_cget_func_t PARAMS((void)); /* sh_ivoidfunc_t */ +typedef int sh_cunget_func_t PARAMS((int)); /* sh_intfunc_t */ + +enum stream_type {st_none, st_stdin, st_stream, st_string, st_bstream}; + +#if defined (BUFFERED_INPUT) + +/* Possible values for b_flag. */ +#undef B_EOF +#undef B_ERROR /* There are some systems with this define */ +#undef B_UNBUFF + +#define B_EOF 0x01 +#define B_ERROR 0x02 +#define B_UNBUFF 0x04 +#define B_WASBASHINPUT 0x08 +#define B_TEXT 0x10 +#define B_SHAREDBUF 0x20 /* shared input buffer */ + +/* A buffered stream. Like a FILE *, but with our own buffering and + synchronization. Look in input.c for the implementation. */ +typedef struct BSTREAM +{ + int b_fd; + char *b_buffer; /* The buffer that holds characters read. */ + size_t b_size; /* How big the buffer is. */ + size_t b_used; /* How much of the buffer we're using, */ + int b_flag; /* Flag values. */ + size_t b_inputp; /* The input pointer, index into b_buffer. */ +} BUFFERED_STREAM; + +#if 0 +extern BUFFERED_STREAM **buffers; +#endif + +extern int default_buffered_input; +extern int bash_input_fd_changed; + +#endif /* BUFFERED_INPUT */ + +typedef union { + FILE *file; + char *string; +#if defined (BUFFERED_INPUT) + int buffered_fd; +#endif +} INPUT_STREAM; + +typedef struct { + enum stream_type type; + char *name; + INPUT_STREAM location; + sh_cget_func_t *getter; + sh_cunget_func_t *ungetter; +} BASH_INPUT; + +extern BASH_INPUT bash_input; + +/* Functions from parse.y whose use directly or indirectly depends on the + definitions in this file. */ +extern void initialize_bash_input PARAMS((void)); +extern void init_yy_io PARAMS((sh_cget_func_t *, sh_cunget_func_t *, enum stream_type, const char *, INPUT_STREAM)); +extern char *yy_input_name PARAMS((void)); +extern void with_input_from_stdin PARAMS((void)); +extern void with_input_from_string PARAMS((char *, const char *)); +extern void with_input_from_stream PARAMS((FILE *, const char *)); +extern void push_stream PARAMS((int)); +extern void pop_stream PARAMS((void)); +extern int stream_on_stack PARAMS((enum stream_type)); +extern char *read_secondary_line PARAMS((int)); +extern int find_reserved_word PARAMS((char *)); +extern void gather_here_documents PARAMS((void)); +extern void execute_variable_command PARAMS((char *, char *)); + +extern int *save_token_state PARAMS((void)); +extern void restore_token_state PARAMS((int *)); + +/* Functions from input.c */ +extern int getc_with_restart PARAMS((FILE *)); +extern int ungetc_with_restart PARAMS((int, FILE *)); + +#if defined (BUFFERED_INPUT) +/* Functions from input.c. */ +extern int fd_is_bash_input PARAMS((int)); +extern int set_bash_input_fd PARAMS((int)); +extern int save_bash_input PARAMS((int, int)); +extern int check_bash_input PARAMS((int)); +extern int duplicate_buffered_stream PARAMS((int, int)); +extern BUFFERED_STREAM *fd_to_buffered_stream PARAMS((int)); +extern BUFFERED_STREAM *set_buffered_stream PARAMS((int, BUFFERED_STREAM *)); +extern BUFFERED_STREAM *open_buffered_stream PARAMS((char *)); +extern void free_buffered_stream PARAMS((BUFFERED_STREAM *)); +extern int close_buffered_stream PARAMS((BUFFERED_STREAM *)); +extern int close_buffered_fd PARAMS((int)); +extern int sync_buffered_stream PARAMS((int)); +extern int buffered_getchar PARAMS((void)); +extern int buffered_ungetchar PARAMS((int)); +extern void with_input_from_buffered_stream PARAMS((int, char *)); +#endif /* BUFFERED_INPUT */ + +#endif /* _INPUT_H_ */ diff --git a/utshell-0.5.0/variable/jobs.h b/utshell-0.5.0/variable/jobs.h new file mode 100644 index 00000000..0cbc4754 --- /dev/null +++ b/utshell-0.5.0/variable/jobs.h @@ -0,0 +1,323 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* jobs.h -- structures and definitions used by the jobs.c file. */ + +/* Copyright (C) 1993-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_JOBS_H_) +# define _JOBS_H_ + +#include "quit.h" +#include "siglist.h" + +#include "stdc.h" + +#include "posixwait.h" + +/* Defines controlling the fashion in which jobs are listed. */ +#define JLIST_STANDARD 0 +#define JLIST_LONG 1 +#define JLIST_PID_ONLY 2 +#define JLIST_CHANGED_ONLY 3 +#define JLIST_NONINTERACTIVE 4 + +/* I looked it up. For pretty_print_job (). The real answer is 24. */ +#define LONGEST_SIGNAL_DESC 24 + +/* Defines for the wait_for_* functions and for the wait builtin to use */ +#define JWAIT_PERROR (1 << 0) +#define JWAIT_FORCE (1 << 1) +#define JWAIT_NOWAIT (1 << 2) /* don't waitpid(), just return status if already exited */ +#define JWAIT_WAITING (1 << 3) /* wait for jobs marked J_WAITING only */ + +/* flags for wait_for */ +#define JWAIT_NOTERM (1 << 8) /* wait_for doesn't give terminal away */ + +/* The max time to sleep while retrying fork() on EAGAIN failure */ +#define FORKSLEEP_MAX 16 + +/* We keep an array of jobs. Each entry in the array is a linked list + of processes that are piped together. The first process encountered is + the group leader. */ + +/* Values for the `running' field of a struct process. */ +#define PS_DONE 0 +#define PS_RUNNING 1 +#define PS_STOPPED 2 +#define PS_RECYCLED 4 + +/* Each child of the shell is remembered in a STRUCT PROCESS. A circular + chain of such structures is a pipeline. */ +typedef struct process { + struct process *next; /* Next process in the pipeline. A circular chain. */ + pid_t pid; /* Process ID. */ + WAIT status; /* The status of this command as returned by wait. */ + int running; /* Non-zero if this process is running. */ + char *command; /* The particular program that is running. */ +} PROCESS; + +struct pipeline_saver { + struct process *pipeline; + struct pipeline_saver *next; +}; + + extern int wait_intr_flag ; +/* PALIVE really means `not exited' */ +#define PSTOPPED(p) (WIFSTOPPED((p)->status)) +#define PRUNNING(p) ((p)->running == PS_RUNNING) +#define PALIVE(p) (PRUNNING(p) || PSTOPPED(p)) + +#define PEXITED(p) ((p)->running == PS_DONE) +#if defined (RECYCLES_PIDS) +# define PRECYCLED(p) ((p)->running == PS_RECYCLED) +#else +# define PRECYCLED(p) (0) +#endif +#define PDEADPROC(p) (PEXITED(p) || PRECYCLED(p)) + +#define get_job_by_jid(ind) (jobs[(ind)]) + +/* A description of a pipeline's state. */ +typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE; +#define JOBSTATE(job) (jobs[(job)]->state) +#define J_JOBSTATE(j) ((j)->state) + +#define STOPPED(j) (jobs[(j)]->state == JSTOPPED) +#define RUNNING(j) (jobs[(j)]->state == JRUNNING) +#define DEADJOB(j) (jobs[(j)]->state == JDEAD) + +#define INVALID_JOB(j) ((j) < 0 || (j) >= js.j_jobslots || get_job_by_jid(j) == 0) + +/* Values for the FLAGS field in the JOB struct below. */ +#define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground. */ +#define J_NOTIFIED 0x02 /* Non-zero if already notified about job state. */ +#define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */ +#define J_NOHUP 0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */ +#define J_STATSAVED 0x10 /* A process in this job had status saved via $! */ +#define J_ASYNC 0x20 /* Job was started asynchronously */ +#define J_PIPEFAIL 0x40 /* pipefail set when job was started */ +#define J_WAITING 0x80 /* one of a list of jobs for which we are waiting */ + +#define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0) +#define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0) +#define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0) +#define IS_ASYNC(j) ((jobs[j]->flags & J_ASYNC) != 0) +#define IS_WAITING(j) ((jobs[j]->flags & J_WAITING) != 0) + +typedef struct job { + char *wd; /* The working directory at time of invocation. */ + PROCESS *pipe; /* The pipeline of processes that make up this job. */ + pid_t pgrp; /* The process ID of the process group (necessary). */ + JOB_STATE state; /* The state that this job is in. */ + int flags; /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */ +#if defined (JOB_CONTROL) + COMMAND *deferred; /* Commands that will execute when this job is done. */ + sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */ + PTR_T cleanarg; /* Argument passed to (*j_cleanup)() */ +#endif /* JOB_CONTROL */ +} JOB; + +struct jobstats { + /* limits */ + long c_childmax; + /* child process statistics */ + int c_living; /* running or stopped child processes */ + int c_reaped; /* exited child processes still in jobs list */ + int c_injobs; /* total number of child processes in jobs list */ + /* child process totals */ + int c_totforked; /* total number of children this shell has forked */ + int c_totreaped; /* total number of children this shell has reaped */ + /* job counters and indices */ + int j_jobslots; /* total size of jobs array */ + int j_lastj; /* last (newest) job allocated */ + int j_firstj; /* first (oldest) job allocated */ + int j_njobs; /* number of non-NULL jobs in jobs array */ + int j_ndead; /* number of JDEAD jobs in jobs array */ + /* */ + int j_current; /* current job */ + int j_previous; /* previous job */ + /* */ + JOB *j_lastmade; /* last job allocated by stop_pipeline */ + JOB *j_lastasync; /* last async job allocated by stop_pipeline */ +}; + +/* Revised to accommodate new hash table bgpids implementation. */ +typedef pid_t ps_index_t; + +struct pidstat { + ps_index_t bucket_next; + ps_index_t bucket_prev; + + pid_t pid; + bits16_t status; /* only 8 bits really needed */ +}; + +struct bgpids { + struct pidstat *storage; /* storage arena */ + + ps_index_t head; + ps_index_t nalloc; + + int npid; +}; + +#define NO_PIDSTAT (ps_index_t)-1 + +/* standalone process status struct, without bgpids indexes */ +struct procstat { + pid_t pid; + bits16_t status; +}; + +/* A standalone singly-linked list of PROCESS *, used in various places + including keeping track of process substitutions. */ +struct procchain { + PROCESS *head; + PROCESS *end; + int nproc; +}; + +#define NO_JOB -1 /* An impossible job array index. */ +#define DUP_JOB -2 /* A possible return value for get_job_spec (). */ +#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */ + +/* A value which cannot be a process ID. */ +#define NO_PID (pid_t)-1 + +#define ANY_PID (pid_t)-1 + +/* flags for make_child () */ +#define FORK_SYNC 0 /* normal synchronous process */ +#define FORK_ASYNC 1 /* background process */ +#define FORK_NOJOB 2 /* don't put process in separate pgrp */ +#define FORK_NOTERM 4 /* don't give terminal to any pgrp */ + +/* System calls. */ +#if !defined (HAVE_UNISTD_H) +extern pid_t fork (), getpid (), getpgrp (); +#endif /* !HAVE_UNISTD_H */ + +/* Stuff from the jobs.c file. */ +extern struct jobstats js; + +extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp; +extern volatile pid_t last_made_pid, last_asynchronous_pid; +extern int asynchronous_notification; + +extern int already_making_children; +extern int running_in_background; + +extern PROCESS *last_procsub_child; + +extern JOB **jobs; + +extern void making_children PARAMS((void)); +extern void stop_making_children PARAMS((void)); +extern void cleanup_the_pipeline PARAMS((void)); +extern void discard_last_procsub_child PARAMS((void)); +extern void save_pipeline PARAMS((int)); +extern PROCESS *restore_pipeline PARAMS((int)); +extern void start_pipeline PARAMS((void)); +extern int stop_pipeline PARAMS((int, COMMAND *)); +extern int discard_pipeline PARAMS((PROCESS *)); +extern void append_process PARAMS((char *, pid_t, int, int)); + +extern void save_proc_status PARAMS((pid_t, int)); + +extern PROCESS *procsub_add PARAMS((PROCESS *)); +extern PROCESS *procsub_search PARAMS((pid_t)); +extern PROCESS *procsub_delete PARAMS((pid_t)); +extern int procsub_waitpid PARAMS((pid_t)); +extern void procsub_waitall PARAMS((void)); +extern void procsub_clear PARAMS((void)); +extern void procsub_prune PARAMS((void)); + +extern void delete_job PARAMS((int, int)); +extern void nohup_job PARAMS((int)); +extern void delete_all_jobs PARAMS((int)); +extern void nohup_all_jobs PARAMS((int)); + +extern int count_all_jobs PARAMS((void)); + +extern void terminate_current_pipeline PARAMS((void)); +extern void terminate_stopped_jobs PARAMS((void)); +extern void hangup_all_jobs PARAMS((void)); +extern void kill_current_pipeline PARAMS((void)); + +#if defined (__STDC__) && defined (pid_t) +extern int get_job_by_pid PARAMS((int, int, PROCESS **)); +extern void describe_pid PARAMS((int)); +#else +extern int get_job_by_pid PARAMS((pid_t, int, PROCESS **)); +extern void describe_pid PARAMS((pid_t)); +#endif + +extern void list_one_job PARAMS((JOB *, int, int, int)); +extern void list_all_jobs PARAMS((int)); +extern void list_stopped_jobs PARAMS((int)); +extern void list_running_jobs PARAMS((int)); + +extern pid_t make_child PARAMS((char *, int)); + +extern int get_tty_state PARAMS((void)); +extern int set_tty_state PARAMS((void)); + +extern int job_exit_status PARAMS((int)); +extern int job_exit_signal PARAMS((int)); + +extern int wait_for_single_pid PARAMS((pid_t, int)); +extern void wait_for_background_pids PARAMS((struct procstat *)); +extern int wait_for PARAMS((pid_t, int)); +extern int wait_for_job PARAMS((int, int, struct procstat *)); +extern int wait_for_any_job PARAMS((int, struct procstat *)); + +extern void wait_sigint_cleanup PARAMS((void)); + +extern void notify_and_cleanup PARAMS((void)); +extern void reap_dead_jobs PARAMS((void)); +extern int start_job PARAMS((int, int)); +extern int kill_pid PARAMS((pid_t, int, int)); +extern int initialize_job_control PARAMS((int)); +extern void initialize_job_signals PARAMS((void)); +extern int give_terminal_to PARAMS((pid_t, int)); + +extern void run_sigchld_trap PARAMS((int)); + +extern int freeze_jobs_list PARAMS((void)); +extern void unfreeze_jobs_list PARAMS((void)); +extern void set_jobs_list_frozen PARAMS((int)); +extern int set_job_control PARAMS((int)); +extern void without_job_control PARAMS((void)); +extern void end_job_control PARAMS((void)); +extern void restart_job_control PARAMS((void)); +extern void set_sigchld_handler PARAMS((void)); +extern void ignore_tty_job_signals PARAMS((void)); +extern void default_tty_job_signals PARAMS((void)); +extern void get_original_tty_job_signals PARAMS((void)); + +extern void init_job_stats PARAMS((void)); + +extern void close_pgrp_pipe PARAMS((void)); +extern void save_pgrp_pipe PARAMS((int *, int)); +extern void restore_pgrp_pipe PARAMS((int *)); + +extern void set_maxchild PARAMS((int)); + +extern int job_control; /* set to 0 in nojobs.c */ + +#endif /* _JOBS_H_ */ diff --git a/utshell-0.5.0/variable/keymaps.h b/utshell-0.5.0/variable/keymaps.h new file mode 100644 index 00000000..4ccba8de --- /dev/null +++ b/utshell-0.5.0/variable/keymaps.h @@ -0,0 +1,100 @@ +/* keymaps.h -- Manipulation of readline keymaps. */ + +/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#ifndef _KEYMAPS_H_ +#define _KEYMAPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "chardefs.h" +# include "rltypedefs.h" +#else +# include "rlstdc.h" +# include "chardefs.h" +# include "rltypedefs.h" +#endif + +/* A keymap contains one entry for each key in the ASCII set. + Each entry consists of a type and a pointer. + FUNCTION is the address of a function to run, or the + address of a keymap to indirect through. + TYPE says which kind of thing FUNCTION is. */ +typedef struct _keymap_entry { + char type; + rl_command_func_t *function; +} KEYMAP_ENTRY; + +/* This must be large enough to hold bindings for all of the characters + in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x, + and so on) plus one for subsequence matching. */ +#define KEYMAP_SIZE 257 +#define ANYOTHERKEY KEYMAP_SIZE-1 + +typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; +typedef KEYMAP_ENTRY *Keymap; + +/* The values that TYPE can have in a keymap entry. */ +#define ISFUNC 0 +#define ISKMAP 1 +#define ISMACR 2 + +extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap; + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); + +/* Return a new keymap which is a copy of MAP. */ +extern Keymap rl_copy_keymap PARAMS((Keymap)); + +/* Return a new keymap with the printing characters bound to rl_insert, + the lowercase Meta characters bound to run their equivalents, and + the Meta digits bound to produce numeric arguments. */ +extern Keymap rl_make_keymap PARAMS((void)); + +/* Free the storage associated with a keymap. */ +extern void rl_discard_keymap PARAMS((Keymap)); + +/* These functions actually appear in bind.c */ + +/* Return the keymap corresponding to a given name. Names look like + `emacs' or `emacs-meta' or `vi-insert'. */ +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); + +/* Return the current keymap. */ +extern Keymap rl_get_keymap PARAMS((void)); + +/* Set the current keymap to MAP. */ +extern void rl_set_keymap PARAMS((Keymap)); + +/* Set the name of MAP to NAME */ +extern int rl_set_keymap_name PARAMS((const char *, Keymap)); + +#ifdef __cplusplus +} +#endif + +#endif /* _KEYMAPS_H_ */ diff --git a/utshell-0.5.0/variable/make_cmd.h b/utshell-0.5.0/variable/make_cmd.h new file mode 100644 index 00000000..ddfa964c --- /dev/null +++ b/utshell-0.5.0/variable/make_cmd.h @@ -0,0 +1,73 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* make_cmd.h -- Declarations of functions found in make_cmd.c */ + +/* Copyright (C) 1993-2009,2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_MAKE_CMD_H_) +#define _MAKE_CMD_H_ + +#include "stdc.h" + +extern int here_doc_first_line; + +extern void cmd_init PARAMS((void)); + +extern WORD_DESC *alloc_word_desc PARAMS((void)); +extern WORD_DESC *make_bare_word PARAMS((const char *)); +extern WORD_DESC *make_word_flags PARAMS((WORD_DESC *, const char *)); +extern WORD_DESC *make_word PARAMS((const char *)); +extern WORD_DESC *make_word_from_token PARAMS((int)); + +extern WORD_LIST *make_word_list PARAMS((WORD_DESC *, WORD_LIST *)); + +#define add_string_to_list(s, l) make_word_list (make_word(s), (l)) + +extern COMMAND *make_command PARAMS((enum command_type, SIMPLE_COM *)); +extern COMMAND *command_connect PARAMS((COMMAND *, COMMAND *, int)); +extern COMMAND *make_for_command PARAMS((WORD_DESC *, WORD_LIST *, COMMAND *, int)); +extern COMMAND *make_group_command PARAMS((COMMAND *)); +extern COMMAND *make_case_command PARAMS((WORD_DESC *, PATTERN_LIST *, int)); +extern PATTERN_LIST *make_pattern_list PARAMS((WORD_LIST *, COMMAND *)); +extern COMMAND *make_if_command PARAMS((COMMAND *, COMMAND *, COMMAND *)); +extern COMMAND *make_while_command PARAMS((COMMAND *, COMMAND *)); +extern COMMAND *make_until_command PARAMS((COMMAND *, COMMAND *)); +extern COMMAND *make_bare_simple_command PARAMS((void)); +extern COMMAND *make_simple_command PARAMS((ELEMENT, COMMAND *)); +extern void make_here_document PARAMS((REDIRECT *, int)); +extern REDIRECT *make_redirection PARAMS((REDIRECTEE, enum r_instruction, REDIRECTEE, int)); +extern COMMAND *make_function_def PARAMS((WORD_DESC *, COMMAND *, int, int)); +extern COMMAND *clean_simple_command PARAMS((COMMAND *)); + +extern COMMAND *make_arith_command PARAMS((WORD_LIST *)); + +extern COMMAND *make_select_command PARAMS((WORD_DESC *, WORD_LIST *, COMMAND *, int)); + +#if defined (COND_COMMAND) +extern COND_COM *make_cond_node PARAMS((int, WORD_DESC *, COND_COM *, COND_COM *)); +extern COMMAND *make_cond_command PARAMS((COND_COM *)); +#endif + +extern COMMAND *make_arith_for_command PARAMS((WORD_LIST *, COMMAND *, int)); + +extern COMMAND *make_subshell_command PARAMS((COMMAND *)); +extern COMMAND *make_coproc_command PARAMS((char *, COMMAND *)); + +extern COMMAND *connect_async_list PARAMS((COMMAND *, COMMAND *, int)); + +#endif /* !_MAKE_CMD_H */ diff --git a/utshell-0.5.0/variable/maxpath.h b/utshell-0.5.0/variable/maxpath.h new file mode 100644 index 00000000..db2e1fb4 --- /dev/null +++ b/utshell-0.5.0/variable/maxpath.h @@ -0,0 +1,75 @@ +/* maxpath.h - Find out what this system thinks PATH_MAX and NAME_MAX are. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_MAXPATH_H_) +#define _MAXPATH_H_ + +/* These values are supposed to be in or one of the files + it includes. */ +#if defined (HAVE_LIMITS_H) +# include +#endif /* !HAVE_LIMITS_H */ + +/* If PATH_MAX is not defined, look for MAXPATHLEN */ +#if !defined (PATH_MAX) +# if defined (HAVE_SYS_PARAM_H) +# include +# define maxpath_param_h +# endif +# if defined (MAXPATHLEN) && !defined (PATH_MAX) +# define PATH_MAX MAXPATHLEN +# endif /* MAXPATHLEN && !PATH_MAX */ +#endif /* !PATH_MAX */ + +/* If NAME_MAX is not defined, look for MAXNAMLEN */ +#if !defined (NAME_MAX) +# if defined (HAVE_SYS_PARAM_H) && !defined (maxpath_param_h) +# include +# endif +# if defined (MAXNAMLEN) && !defined (NAME_MAX) +# define NAME_MAX MAXNAMLEN +# endif /* MAXNAMLEN && !NAME_MAX */ +#endif /* !NAME_MAX */ + +/* Default POSIX values */ +#if !defined (PATH_MAX) && defined (_POSIX_PATH_MAX) +# define PATH_MAX _POSIX_PATH_MAX +#endif + +#if !defined (NAME_MAX) && defined (_POSIX_NAME_MAX) +# define NAME_MAX _POSIX_NAME_MAX +#endif + + +/* Default values */ +#if !defined (PATH_MAX) +# define PATH_MAX 1024 +#endif + +#if !defined (NAME_MAX) +# define NAME_MAX 14 +#endif + +#if PATH_MAX < 1024 +# undef PATH_MAX +# define PATH_MAX 1024 +#endif + +#endif /* _MAXPATH_H_ */ diff --git a/utshell-0.5.0/variable/ocache.h b/utshell-0.5.0/variable/ocache.h new file mode 100644 index 00000000..c596c272 --- /dev/null +++ b/utshell-0.5.0/variable/ocache.h @@ -0,0 +1,133 @@ +/* ocache.h -- a minimal object caching implementation. */ + +/* Copyright (C) 2002 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_OCACHE_H_) +#define _OCACHE_H_ 1 + +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +#define OC_MEMSET(memp, xch, nbytes) \ +do { \ + if ((nbytes) <= 32) { \ + register char * mzp = (char *)(memp); \ + unsigned long mctmp = (nbytes); \ + register long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = xch; \ + case 7: *mzp++ = xch; \ + case 6: *mzp++ = xch; \ + case 5: *mzp++ = xch; \ + case 4: *mzp++ = xch; \ + case 3: *mzp++ = xch; \ + case 2: *mzp++ = xch; \ + case 1: *mzp++ = xch; if(mcn <= 0) break; mcn--; } \ + } \ + } else \ + memset ((memp), (xch), (nbytes)); \ +} while(0) + +typedef struct objcache { + PTR_T data; + int cs; /* cache size, number of objects */ + int nc; /* number of cache entries */ +} sh_obj_cache_t; + +/* Create an object cache C of N pointers to OTYPE. */ +#define ocache_create(c, otype, n) \ + do { \ + (c).data = xmalloc((n) * sizeof (otype *)); \ + (c).cs = (n); \ + (c).nc = 0; \ + } while (0) + +/* Destroy an object cache C. */ +#define ocache_destroy(c) \ + do { \ + if ((c).data) \ + xfree ((c).data); \ + (c).data = 0; \ + (c).cs = (c).nc = 0; \ + } while (0) + +/* Free all cached items, which are pointers to OTYPE, in object cache C. */ +#define ocache_flush(c, otype) \ + do { \ + while ((c).nc > 0) \ + xfree (((otype **)((c).data))[--(c).nc]); \ + } while (0) + +/* + * Allocate a new item of type pointer to OTYPE, using data from object + * cache C if any cached items exist, otherwise calling xmalloc. Return + * the object in R. + */ +#define ocache_alloc(c, otype, r) \ + do { \ + if ((c).nc > 0) { \ + (r) = (otype *)((otype **)((c).data))[--(c).nc]; \ + } else \ + (r) = (otype *)xmalloc (sizeof (otype)); \ + } while (0) + +/* + * Free an item R of type pointer to OTYPE, adding to object cache C if + * there is room and calling xfree if the cache is full. If R is added + * to the object cache, the contents are scrambled. + */ +#define ocache_free(c, otype, r) \ + do { \ + if ((c).nc < (c).cs) { \ + OC_MEMSET ((r), 0xdf, sizeof(otype)); \ + ((otype **)((c).data))[(c).nc++] = (r); \ + } else \ + xfree (r); \ + } while (0) + +/* + * One may declare and use an object cache as (for instance): + * + * sh_obj_cache_t wdcache = {0, 0, 0}; + * sh_obj_cache_t wlcache = {0, 0, 0}; + * + * ocache_create(wdcache, WORD_DESC, 30); + * ocache_create(wlcache, WORD_LIST, 30); + * + * WORD_DESC *wd; + * ocache_alloc (wdcache, WORD_DESC, wd); + * + * WORD_LIST *wl; + * ocache_alloc (wlcache, WORD_LIST, wl); + * + * ocache_free(wdcache, WORD_DESC, wd); + * ocache_free(wlcache, WORD_LIST, wl); + * + * The use is almost arbitrary. + */ + +#endif /* _OCACHE_H */ diff --git a/utshell-0.5.0/variable/parser.h b/utshell-0.5.0/variable/parser.h new file mode 100644 index 00000000..f9a56607 --- /dev/null +++ b/utshell-0.5.0/variable/parser.h @@ -0,0 +1,101 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* parser.h -- Everything you wanted to know about the parser, but were + afraid to ask. */ + +/* Copyright (C) 1995-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_PARSER_H_) +# define _PARSER_H_ + +# include "command.h" +# include "input.h" + +/* Possible states for the parser that require it to do special things. */ +#define PST_CASEPAT 0x000001 /* in a case pattern list */ +#define PST_ALEXPNEXT 0x000002 /* expand next word for aliases */ +#define PST_ALLOWOPNBRC 0x000004 /* allow open brace for function def */ +#define PST_NEEDCLOSBRC 0x000008 /* need close brace */ +#define PST_DBLPAREN 0x000010 /* double-paren parsing */ +#define PST_SUBSHELL 0x000020 /* ( ... ) subshell */ +#define PST_CMDSUBST 0x000040 /* $( ... ) command substitution */ +#define PST_CASESTMT 0x000080 /* parsing a case statement */ +#define PST_CONDCMD 0x000100 /* parsing a [[...]] command */ +#define PST_CONDEXPR 0x000200 /* parsing the guts of [[...]] */ +#define PST_ARITHFOR 0x000400 /* parsing an arithmetic for command - unused */ +#define PST_ALEXPAND 0x000800 /* OK to expand aliases - unused */ +#define PST_EXTPAT 0x001000 /* parsing an extended shell pattern */ +#define PST_COMPASSIGN 0x002000 /* parsing x=(...) compound assignment */ +#define PST_ASSIGNOK 0x004000 /* assignment statement ok in this context */ +#define PST_EOFTOKEN 0x008000 /* yylex checks against shell_eof_token */ +#define PST_REGEXP 0x010000 /* parsing an ERE/BRE as a single word */ +#define PST_HEREDOC 0x020000 /* reading body of here-document */ +#define PST_REPARSE 0x040000 /* re-parsing in parse_string_to_word_list */ +#define PST_REDIRLIST 0x080000 /* parsing a list of redirections preceding a simple command name */ +#define PST_COMMENT 0x100000 /* parsing a shell comment; used by aliases */ +#define PST_ENDALIAS 0x200000 /* just finished expanding and consuming an alias */ + +/* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ +struct dstack { +/* DELIMITERS is a stack of the nested delimiters that we have + encountered so far. */ + char *delimiters; + +/* Offset into the stack of delimiters. */ + int delimiter_depth; + +/* How many slots are allocated to DELIMITERS. */ + int delimiter_space; +}; + +/* States we can be in while scanning a ${...} expansion. Shared between + parse.y and subst.c */ +#define DOLBRACE_PARAM 0x01 +#define DOLBRACE_OP 0x02 +#define DOLBRACE_WORD 0x04 + +#define DOLBRACE_QUOTE 0x40 /* single quote is special in double quotes */ +#define DOLBRACE_QUOTE2 0x80 /* single quote is semi-special in double quotes */ + +/* variable declarations from parse.y */ +extern struct dstack dstack; + +extern char *primary_prompt; +extern char *secondary_prompt; + +extern char *current_prompt_string; + +extern char *ps1_prompt; +extern char *ps2_prompt; +extern char *ps0_prompt; + +extern int expand_aliases; +extern int current_command_line_count; +extern int saved_command_line_count; +extern int shell_eof_token; +extern int current_token; +extern int parser_state; +extern int need_here_doc; + +extern int ignoreeof; +extern int eof_encountered; +extern int eof_encountered_limit; + +extern int line_number, line_number_base; + +#endif /* _PARSER_H_ */ diff --git a/utshell-0.5.0/variable/pathexp.h b/utshell-0.5.0/variable/pathexp.h new file mode 100644 index 00000000..a43edf73 --- /dev/null +++ b/utshell-0.5.0/variable/pathexp.h @@ -0,0 +1,108 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* pathexp.h -- The shell interface to the globbing library. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_PATHEXP_H_) +#define _PATHEXP_H_ + +#if defined (USE_POSIX_GLOB_LIBRARY) +# define GLOB_FAILED(glist) !(glist) +#else /* !USE_POSIX_GLOB_LIBRARY */ +# define GLOB_FAILED(glist) (glist) == (char **)&glob_error_return +extern int noglob_dot_filenames; +extern char *glob_error_return; +#endif /* !USE_POSIX_GLOB_LIBRARY */ + +/* Flag values for quote_string_for_globbing */ +#define QGLOB_CVTNULL 0x01 /* convert QUOTED_NULL strings to '\0' */ +#define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */ +#define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */ +#define QGLOB_CTLESC 0x08 /* turn CTLESC CTLESC into CTLESC for BREs */ +#define QGLOB_DEQUOTE 0x10 /* like dequote_string but quote glob chars */ + +#if defined (EXTENDED_GLOB) +/* Flags to OR with other flag args to strmatch() to enabled the extended + pattern matching. */ +# define FNMATCH_EXTFLAG (extended_glob ? FNM_EXTMATCH : 0) +#else +# define FNMATCH_EXTFLAG 0 +#endif /* !EXTENDED_GLOB */ + +#define FNMATCH_IGNCASE (match_ignore_case ? FNM_CASEFOLD : 0) +#define FNMATCH_NOCASEGLOB (glob_ignore_case ? FNM_CASEFOLD : 0) + +extern int glob_dot_filenames; +extern int extended_glob; +extern int glob_star; +extern int match_ignore_case; /* doesn't really belong here */ + +extern int unquoted_glob_pattern_p PARAMS((char *)); + +/* PATHNAME can contain characters prefixed by CTLESC; this indicates + that the character is to be quoted. We quote it here in the style + that the glob library recognizes. If flags includes QGLOB_CVTNULL, + we change quoted null strings (pathname[0] == CTLNUL) into empty + strings (pathname[0] == 0). If this is called after quote removal + is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote + removal has not been done (for example, before attempting to match a + pattern while executing a case statement), flags should include + QGLOB_CVTNULL. If flags includes QGLOB_FILENAME, appropriate quoting + to match a filename should be performed. */ +extern char *quote_string_for_globbing PARAMS((const char *, int)); + +extern int glob_char_p PARAMS((const char *)); +extern char *quote_globbing_chars PARAMS((const char *)); + +/* Call the glob library to do globbing on PATHNAME. FLAGS is additional + flags to pass to QUOTE_STRING_FOR_GLOBBING, mostly having to do with + whether or not we've already performed quote removal. */ +extern char **shell_glob_filename PARAMS((const char *, int)); + +/* Filename completion ignore. Used to implement the "fignore" facility of + tcsh, GLOBIGNORE (like ksh-93 FIGNORE), and EXECIGNORE. + + It is passed a NULL-terminated array of (char *)'s that must be + free()'d if they are deleted. The first element (names[0]) is the + least-common-denominator string of the matching patterns (i.e. + u produces names[0] = "und", names[1] = "under.c", names[2] = + "undun.c", name[3] = NULL). */ + +struct ign { + char *val; + int len, flags; +}; + +typedef int sh_iv_item_func_t PARAMS((struct ign *)); + +struct ignorevar { + char *varname; /* FIGNORE, GLOBIGNORE, or EXECIGNORE */ + struct ign *ignores; /* Store the ignore strings here */ + int num_ignores; /* How many are there? */ + char *last_ignoreval; /* Last value of variable - cached for speed */ + sh_iv_item_func_t *item_func; /* Called when each item is parsed from $`varname' */ +}; + +extern void setup_ignore_patterns PARAMS((struct ignorevar *)); + +extern void setup_glob_ignore PARAMS((char *)); +extern int should_ignore_glob_matches PARAMS((void)); +extern void ignore_glob_matches PARAMS((char **)); + +#endif diff --git a/utshell-0.5.0/variable/pathnames.h b/utshell-0.5.0/variable/pathnames.h new file mode 100644 index 00000000..b5c3cb27 --- /dev/null +++ b/utshell-0.5.0/variable/pathnames.h @@ -0,0 +1,33 @@ +/* pathnames.h -- absolute filenames that bash wants for various defaults. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_PATHNAMES_H_) +#define _PATHNAMES_H_ + +/* The default file for hostname completion. */ +#define DEFAULT_HOSTS_FILE "/etc/hosts" + +/* The default login shell startup file. */ +#define SYS_PROFILE "/etc/profile" + +/* The default location of the bash debugger initialization/startup file. */ +#define DEBUGGER_START_FILE "/usr/share/bashdb/bashdb-main.inc" + +#endif /* _PATHNAMES_H */ diff --git a/utshell-0.5.0/variable/pcomplete.c b/utshell-0.5.0/variable/pcomplete.c new file mode 100644 index 00000000..aebacd4c --- /dev/null +++ b/utshell-0.5.0/variable/pcomplete.c @@ -0,0 +1,124 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* pcomplete.c - functions to generate lists of matches for programmable completion. */ + +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#if defined (PROGRAMMABLE_COMPLETION) + +#include "bashtypes.h" +#include "posixstat.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include "posixtime.h" + +#include +#include "bashansi.h" +#include "bashintl.h" + +#include "shell.h" +#include "pcomplete.h" +#include "alias.h" +#include "bashline.h" +#include "execute_cmd.h" +#include "pathexp.h" + +#if defined (JOB_CONTROL) +# include "jobs.h" +#endif + +#if !defined (NSIG) +# include "trap.h" +#endif + +#include "shmbutil.h" + +#include "builtins.h" +#include "common.h" +#include "builtext.h" + +#include +#include "strmatch.h" + +#include "rlconf.h" +#include "readline.h" +#include "history.h" + +#ifdef STRDUP +# undef STRDUP +#endif +#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) + +typedef SHELL_VAR **SVFUNC (); + +#ifndef HAVE_STRPBRK +extern char *strpbrk PARAMS((char *, char *)); +#endif + +extern STRING_INT_ALIST word_token_alist[]; +extern char *signal_names[]; + +#if defined (DEBUG) +#if defined (PREFER_STDARG) +static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#endif +#endif /* DEBUG */ + + + +#ifdef DEBUG +/* Debugging code */ +static void +#if defined (PREFER_STDARG) +debug_printf (const char *format, ...) +#else +debug_printf (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + + if (progcomp_debug == 0) + return; + + SH_VA_START (args, format); + + fprintf (stdout, "DEBUG: "); + vfprintf (stdout, format, args); + fprintf (stdout, "\n"); + + rl_on_new_line (); + + va_end (args); +} +#endif +#endif \ No newline at end of file diff --git a/utshell-0.5.0/variable/pcomplete.h b/utshell-0.5.0/variable/pcomplete.h new file mode 100644 index 00000000..b4e7e7fd --- /dev/null +++ b/utshell-0.5.0/variable/pcomplete.h @@ -0,0 +1,178 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* pcomplete.h - structure definitions and other stuff for programmable + completion. */ + +/* Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_PCOMPLETE_H_) +# define _PCOMPLETE_H_ + +#include "stdc.h" +#include "hashlib.h" + +typedef struct compspec { + int refcount; + unsigned long actions; + unsigned long options; + char *globpat; + char *words; + char *prefix; + char *suffix; + char *funcname; + char *command; + char *lcommand; + char *filterpat; +} COMPSPEC; + +/* Values for COMPSPEC actions. These are things the shell knows how to + build internally. */ +#define CA_ALIAS (1<<0) +#define CA_ARRAYVAR (1<<1) +#define CA_BINDING (1<<2) +#define CA_BUILTIN (1<<3) +#define CA_COMMAND (1<<4) +#define CA_DIRECTORY (1<<5) +#define CA_DISABLED (1<<6) +#define CA_ENABLED (1<<7) +#define CA_EXPORT (1<<8) +#define CA_FILE (1<<9) +#define CA_FUNCTION (1<<10) +#define CA_GROUP (1<<11) +#define CA_HELPTOPIC (1<<12) +#define CA_HOSTNAME (1<<13) +#define CA_JOB (1<<14) +#define CA_KEYWORD (1<<15) +#define CA_RUNNING (1<<16) +#define CA_SERVICE (1<<17) +#define CA_SETOPT (1<<18) +#define CA_SHOPT (1<<19) +#define CA_SIGNAL (1<<20) +#define CA_STOPPED (1<<21) +#define CA_USER (1<<22) +#define CA_VARIABLE (1<<23) + +/* Values for COMPSPEC options field. */ +#define COPT_RESERVED (1<<0) /* reserved for other use */ +#define COPT_DEFAULT (1<<1) +#define COPT_FILENAMES (1<<2) +#define COPT_DIRNAMES (1<<3) +#define COPT_NOQUOTE (1<<4) +#define COPT_NOSPACE (1<<5) +#define COPT_BASHDEFAULT (1<<6) +#define COPT_PLUSDIRS (1<<7) +#define COPT_NOSORT (1<<8) + +#define COPT_LASTUSER COPT_NOSORT + +#define PCOMP_RETRYFAIL (COPT_LASTUSER << 1) +#define PCOMP_NOTFOUND (COPT_LASTUSER << 2) + + +/* List of items is used by the code that implements the programmable + completions. */ +typedef struct _list_of_items { + int flags; + int (*list_getter) PARAMS((struct _list_of_items *)); /* function to call to get the list */ + + STRINGLIST *slist; + + /* These may or may not be used. */ + STRINGLIST *genlist; /* for handing to the completion code one item at a time */ + int genindex; /* index of item last handed to completion code */ + +} ITEMLIST; + +/* Values for ITEMLIST -> flags */ +#define LIST_DYNAMIC 0x001 +#define LIST_DIRTY 0x002 +#define LIST_INITIALIZED 0x004 +#define LIST_MUSTSORT 0x008 +#define LIST_DONTFREE 0x010 +#define LIST_DONTFREEMEMBERS 0x020 + +#define EMPTYCMD "_EmptycmD_" +#define DEFAULTCMD "_DefaultCmD_" +#define INITIALWORD "_InitialWorD_" + +extern HASH_TABLE *prog_completes; + +extern char *pcomp_line; +extern int pcomp_ind; + +extern int prog_completion_enabled; +extern int progcomp_alias; + +/* Not all of these are used yet. */ +extern ITEMLIST it_aliases; +extern ITEMLIST it_arrayvars; +extern ITEMLIST it_bindings; +extern ITEMLIST it_builtins; +extern ITEMLIST it_commands; +extern ITEMLIST it_directories; +extern ITEMLIST it_disabled; +extern ITEMLIST it_enabled; +extern ITEMLIST it_exports; +extern ITEMLIST it_files; +extern ITEMLIST it_functions; +extern ITEMLIST it_groups; +extern ITEMLIST it_helptopics; +extern ITEMLIST it_hostnames; +extern ITEMLIST it_jobs; +extern ITEMLIST it_keywords; +extern ITEMLIST it_running; +extern ITEMLIST it_services; +extern ITEMLIST it_setopts; +extern ITEMLIST it_shopts; +extern ITEMLIST it_signals; +extern ITEMLIST it_stopped; +extern ITEMLIST it_users; +extern ITEMLIST it_variables; + +extern COMPSPEC *pcomp_curcs; +extern const char *pcomp_curcmd; + +/* Functions from pcomplib.c */ +extern COMPSPEC *compspec_create PARAMS((void)); +extern void compspec_dispose PARAMS((COMPSPEC *)); +extern COMPSPEC *compspec_copy PARAMS((COMPSPEC *)); + +extern void progcomp_create PARAMS((void)); +extern void progcomp_flush PARAMS((void)); +extern void progcomp_dispose PARAMS((void)); + +extern int progcomp_size PARAMS((void)); + +extern int progcomp_insert PARAMS((char *, COMPSPEC *)); +extern int progcomp_remove PARAMS((char *)); + +extern COMPSPEC *progcomp_search PARAMS((const char *)); + +extern void progcomp_walk PARAMS((hash_wfunc *)); + +/* Functions from pcomplete.c */ +extern void set_itemlist_dirty PARAMS((ITEMLIST *)); + +extern STRINGLIST *completions_to_stringlist PARAMS((char **)); + +extern STRINGLIST *gen_compspec_completions PARAMS((COMPSPEC *, const char *, const char *, int, int, int *)); +extern char **programmable_completions PARAMS((const char *, const char *, int, int, int *)); + +extern void pcomp_set_readline_variables PARAMS((int, int)); +extern void pcomp_set_compspec_options PARAMS((COMPSPEC *, int, int)); +#endif /* _PCOMPLETE_H_ */ diff --git a/utshell-0.5.0/variable/posixjmp.h b/utshell-0.5.0/variable/posixjmp.h new file mode 100644 index 00000000..9c7e99ed --- /dev/null +++ b/utshell-0.5.0/variable/posixjmp.h @@ -0,0 +1,46 @@ +/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ + +/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXJMP_H_ +#define _POSIXJMP_H_ + +#include + +/* This *must* be included *after* config.h */ + +#if defined (HAVE_POSIX_SIGSETJMP) +# define procenv_t sigjmp_buf + +# define setjmp_nosigs(x) sigsetjmp((x), 0) +# define setjmp_sigs(x) sigsetjmp((x), 1) + +# define _rl_longjmp(x, n) siglongjmp((x), (n)) +# define sh_longjmp(x, n) siglongjmp((x), (n)) +#else +# define procenv_t jmp_buf + +# define setjmp_nosigs setjmp +# define setjmp_sigs setjmp + +# define _rl_longjmp(x, n) longjmp((x), (n)) +# define sh_longjmp(x, n) longjmp((x), (n)) +#endif + +#endif /* _POSIXJMP_H_ */ diff --git a/utshell-0.5.0/variable/posixstat.h b/utshell-0.5.0/variable/posixstat.h new file mode 100644 index 00000000..b6077860 --- /dev/null +++ b/utshell-0.5.0/variable/posixstat.h @@ -0,0 +1,162 @@ +/* posixstat.h -- Posix stat(2) definitions for systems that + don't have them. */ + +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of . + It relies on the local sys/stat.h to work though. */ +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ + +#include + +#if defined (STAT_MACROS_BROKEN) +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISREG +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ + +/* Posix 1003.1 5.6.1.1 file types */ + +/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but + do not provide the S_IS* macros that Posix requires. */ + +#if defined (_S_IFMT) && !defined (S_IFMT) +#define S_IFMT _S_IFMT +#endif +#if defined (_S_IFIFO) && !defined (S_IFIFO) +#define S_IFIFO _S_IFIFO +#endif +#if defined (_S_IFCHR) && !defined (S_IFCHR) +#define S_IFCHR _S_IFCHR +#endif +#if defined (_S_IFDIR) && !defined (S_IFDIR) +#define S_IFDIR _S_IFDIR +#endif +#if defined (_S_IFBLK) && !defined (S_IFBLK) +#define S_IFBLK _S_IFBLK +#endif +#if defined (_S_IFREG) && !defined (S_IFREG) +#define S_IFREG _S_IFREG +#endif +#if defined (_S_IFLNK) && !defined (S_IFLNK) +#define S_IFLNK _S_IFLNK +#endif +#if defined (_S_IFSOCK) && !defined (S_IFSOCK) +#define S_IFSOCK _S_IFSOCK +#endif + +/* Test for each symbol individually and define the ones necessary (some + systems claiming Posix compatibility define some but not all). */ + +#if defined (S_IFBLK) && !defined (S_ISBLK) +#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ +#endif + +#if defined (S_IFCHR) && !defined (S_ISCHR) +#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ +#endif + +#if defined (S_IFDIR) && !defined (S_ISDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ +#endif + +#if defined (S_IFREG) && !defined (S_ISREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ +#endif + +#if defined (S_IFIFO) && !defined (S_ISFIFO) +#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ +#endif + +#if defined (S_IFLNK) && !defined (S_ISLNK) +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ +#endif + +#if defined (S_IFSOCK) && !defined (S_ISSOCK) +#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ +#endif + +/* + * POSIX 1003.1 5.6.1.2 File Modes + */ + +#if !defined (S_IRWXU) +# if !defined (S_IREAD) +# define S_IREAD 00400 +# define S_IWRITE 00200 +# define S_IEXEC 00100 +# endif /* S_IREAD */ + +# if !defined (S_IRUSR) +# define S_IRUSR S_IREAD /* read, owner */ +# define S_IWUSR S_IWRITE /* write, owner */ +# define S_IXUSR S_IEXEC /* execute, owner */ + +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ + +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IRUSR */ + +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#else /* !S_IRWXU */ + /* S_IRWXU is defined, but "group" and "other" bits might not be + (happens in certain versions of MinGW). */ +# if !defined (S_IRGRP) +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ +# endif /* !S_IRGRP */ + +# if !defined (S_IROTH) +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IROTH */ +# if !defined (S_IRWXG) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# endif +# if !defined (S_IRWXO) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +# endif +#endif /* !S_IRWXU */ + +/* These are non-standard, but are used in builtins.c$symbolic_umask() */ +#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#endif /* _POSIXSTAT_H_ */ diff --git a/utshell-0.5.0/variable/posixtime.h b/utshell-0.5.0/variable/posixtime.h new file mode 100644 index 00000000..a83e436b --- /dev/null +++ b/utshell-0.5.0/variable/posixtime.h @@ -0,0 +1,61 @@ +/* posixtime.h -- wrapper for time.h, sys/times.h mess. */ + +/* Copyright (C) 1999 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXTIME_H_ +#define _POSIXTIME_H_ + +/* include this after config.h */ +/* Some systems require this, mostly for the definition of `struct timezone'. + For example, Dynix/ptx has that definition in rather than + sys/time.h */ +#if defined (TIME_WITH_SYS_TIME) +# include +# include +#else +# if defined (HAVE_SYS_TIME_H) +# include +# else +# include +# endif +#endif + +#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK) +# if !defined (CLK_TCK) +# if defined (HZ) +# define CLK_TCK HZ +# else +# define CLK_TCK 60 /* 60HZ */ +# endif +# endif /* !CLK_TCK */ +#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */ + +#if !HAVE_TIMEVAL +struct timeval +{ + time_t tv_sec; + long int tv_usec; +}; +#endif + +#if !HAVE_GETTIMEOFDAY +extern int gettimeofday PARAMS((struct timeval *, void *)); +#endif + +#endif /* _POSIXTIME_H_ */ diff --git a/utshell-0.5.0/variable/posixwait.h b/utshell-0.5.0/variable/posixwait.h new file mode 100644 index 00000000..63b59c24 --- /dev/null +++ b/utshell-0.5.0/variable/posixwait.h @@ -0,0 +1,107 @@ +/* posixwait.h -- job control definitions from POSIX 1003.1 */ + +/* Copyright (C) 1997 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_POSIXWAIT_H_) +# define _POSIXWAIT_H_ + +/* If _POSIX_VERSION is not defined, we assume that defines + a `union wait' and various macros used to manipulate it. Look in + unionwait.h for the things we expect to find. */ +#if defined (HAVE_SYS_WAIT_H) +# include +#else /* !HAVE_SYS_WAIT_H */ +# if !defined (_POSIX_VERSION) +# include "unionwait.h" +# endif +#endif /* !HAVE_SYS_WAIT_H */ + +/* How to get the status of a job. For Posix, this is just an + int, but for other systems we have to crack the union wait. */ +#if !defined (_POSIX_VERSION) +typedef union wait WAIT; +# define WSTATUS(t) (t.w_status) +#else /* _POSIX_VERSION */ +typedef int WAIT; +# define WSTATUS(t) (t) +#endif /* _POSIX_VERSION */ + +/* Make sure that parameters to wait3 are defined. */ +#if !defined (WNOHANG) +# define WNOHANG 1 +# define WUNTRACED 2 +#endif /* WNOHANG */ + +/* More Posix P1003.1 definitions. In the POSIX versions, the parameter is + passed as an `int', in the non-POSIX version, as `union wait'. */ +#if defined (_POSIX_VERSION) + +# if !defined (WSTOPSIG) +# define WSTOPSIG(s) ((s) >> 8) +# endif /* !WSTOPSIG */ + +# if !defined (WTERMSIG) +# define WTERMSIG(s) ((s) & 0177) +# endif /* !WTERMSIG */ + +# if !defined (WEXITSTATUS) +# define WEXITSTATUS(s) ((s) >> 8) +# endif /* !WEXITSTATUS */ + +# if !defined (WIFSTOPPED) +# define WIFSTOPPED(s) (((s) & 0177) == 0177) +# endif /* !WIFSTOPPED */ + +# if !defined (WIFEXITED) +# define WIFEXITED(s) (((s) & 0377) == 0) +# endif /* !WIFEXITED */ + +# if !defined (WIFSIGNALED) +# define WIFSIGNALED(s) (!WIFSTOPPED(s) && !WIFEXITED(s)) +# endif /* !WIFSIGNALED */ + +# if !defined (WIFCORED) +# if defined (WCOREDUMP) +# define WIFCORED(s) (WCOREDUMP(s)) +# else +# define WIFCORED(s) ((s) & 0200) +# endif +# endif /* !WIFCORED */ + +#else /* !_POSIX_VERSION */ + +# if !defined (WSTOPSIG) +# define WSTOPSIG(s) ((s).w_stopsig) +# endif /* !WSTOPSIG */ + +# if !defined (WTERMSIG) +# define WTERMSIG(s) ((s).w_termsig) +# endif /* !WTERMSIG */ + +# if !defined (WEXITSTATUS) +# define WEXITSTATUS(s) ((s).w_retcode) +# endif /* !WEXITSTATUS */ + +# if !defined (WIFCORED) +# define WIFCORED(s) ((s).w_coredump) +# endif /* !WIFCORED */ + +#endif /* !_POSIX_VERSION */ + +#endif /* !_POSIXWAIT_H_ */ diff --git a/utshell-0.5.0/variable/print_cmd.c b/utshell-0.5.0/variable/print_cmd.c new file mode 100644 index 00000000..decee1ef --- /dev/null +++ b/utshell-0.5.0/variable/print_cmd.c @@ -0,0 +1,185 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* print_command -- A way to make readable commands from a command tree. */ + +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#include "config.h" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include "bashansi.h" +#include "bashintl.h" + +#define NEED_XTRACE_SET_DECL + +#include "shell.h" +#include "flags.h" +// #include "y.tab.h" /* use <...> so we pick it up from the build directory */ +#include "input.h" + +#include "shmbutil.h" + +#include "common.h" + +#if !HAVE_DECL_PRINTF +extern int printf PARAMS((const char *, ...)); /* Yuck. Double yuck. */ +#endif +#include "conftypes.h" + + +#if defined (PREFER_STDARG) + +extern void cprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); +static void xprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); +#else +#define PFUNC VFunction +static void cprintf (); +static void xprintf (); +#endif + +static void the_printed_command_resize PARAMS((int)); + + +extern char *the_printed_command ; +extern int the_printed_command_size ; +extern int command_string_index ; + + +/* How to make the string. */ +extern void +#if defined (PREFER_STDARG) +cprintf (const char *control, ...) +#else +cprintf (control, va_alist) + const char *control; + va_dcl +#endif +{ + register const char *s; + char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (unsigned int) + 1]; + int digit_arg, arg_len, c; + va_list args; + + SH_VA_START (args, control); + + arg_len = strlen (control); + the_printed_command_resize (arg_len + 1); + + char_arg[1] = '\0'; + s = control; + while (s && *s) + { + c = *s++; + argp = (char *)NULL; + if (c != '%' || !*s) + { + char_arg[0] = c; + argp = char_arg; + arg_len = 1; + } + else + { + c = *s++; + switch (c) + { + case '%': + char_arg[0] = c; + argp = char_arg; + arg_len = 1; + break; + + case 's': + argp = va_arg (args, char *); + arg_len = strlen (argp); + break; + + case 'd': + /* Represent an out-of-range file descriptor with an out-of-range + integer value. We can do this because the only use of `%d' in + the calls to cprintf is to output a file descriptor number for + a redirection. */ + digit_arg = va_arg (args, int); + if (digit_arg < 0) + { + sprintf (intbuf, "%u", (unsigned int)-1); + argp = intbuf; + } + else + argp = inttostr (digit_arg, intbuf, sizeof (intbuf)); + arg_len = strlen (argp); + break; + + case 'c': + char_arg[0] = va_arg (args, int); + argp = char_arg; + arg_len = 1; + break; + + default: + programming_error (_("cprintf: `%c': invalid format character"), c); + /*NOTREACHED*/ + } + } + + if (argp && arg_len) + { + the_printed_command_resize (arg_len + 1); + FASTCOPY (argp, the_printed_command + command_string_index, arg_len); + command_string_index += arg_len; + } + } + + va_end (args); + + the_printed_command[command_string_index] = '\0'; +} + + +//variables.rs中使用 +char * +get_host_type() +{ + return HOSTTYPE; +} + +char * +get_os_type() +{ + return OSTYPE; +} + +char * +get_mach_type() +{ + return MACHTYPE; +} + diff --git a/utshell-0.5.0/variable/printf.c b/utshell-0.5.0/variable/printf.c new file mode 100644 index 00000000..c5d015c7 --- /dev/null +++ b/utshell-0.5.0/variable/printf.c @@ -0,0 +1,102 @@ +#include "config.h" + +#include "bashtypes.h" + +#include +#if defined (HAVE_LIMITS_H) +# include +#else + /* Assume 32-bit ints. */ +# define INT_MAX 2147483647 +# define INT_MIN (-2147483647-1) +#endif + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include +#include "chartypes.h" + +#ifdef HAVE_INTTYPES_H +# include +#endif + +#include "posixtime.h" +#include "bashansi.h" +#include "bashintl.h" + +#define NEED_STRFTIME_DECL + +#include "shell.h" +#include "shmbutil.h" +#include "stdc.h" +#include "bashgetopt.h" +#include "common.h" + + +#if !HAVE_ASPRINTF +extern int asprintf PARAMS((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); +#endif + +#if !HAVE_VSNPRINTF +extern int vsnprintf PARAMS((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0))); +#endif + + +#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN) +typedef long double floatmax_t; +# define FLOATMAX_CONV "L" +# define strtofltmax strtold +#else +typedef double floatmax_t; +# define FLOATMAX_CONV "" +# define strtofltmax strtod +#endif + +/* printf -v var support */ +static char *vbuf; +static size_t vbsize; +static int vblen; + +static int +#if defined (PREFER_STDARG) +vbprintf (const char *format, ...) +#else +vbprintf (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + size_t nlen; + int blen; + + SH_VA_START (args, format); + blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); + va_end (args); + + nlen = vblen + blen + 1; + if (nlen >= vbsize) + { + vbsize = ((nlen + 63) >> 6) << 6; + vbuf = (char *)xrealloc (vbuf, vbsize); + SH_VA_START (args, format); + blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); + va_end (args); + } + + vblen += blen; + vbuf[vblen] = '\0'; + +#ifdef DEBUG + if (strlen (vbuf) != vblen) + internal_error ("printf:vbprintf: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); +#endif + + return (blen); +} + + diff --git a/utshell-0.5.0/variable/quit.h b/utshell-0.5.0/variable/quit.h new file mode 100644 index 00000000..6470ed5d --- /dev/null +++ b/utshell-0.5.0/variable/quit.h @@ -0,0 +1,82 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* quit.h -- How to handle SIGINT gracefully. */ + +/* Copyright (C) 1993-2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_QUIT_H_) +#define _QUIT_H_ + +#include "sig.h" /* for sig_atomic_t */ + +/* Non-zero means SIGINT has already occurred. */ +extern volatile sig_atomic_t interrupt_state; +extern volatile sig_atomic_t terminating_signal; + +/* Macro to call a great deal. SIGINT just sets the interrupt_state variable. + When it is safe, put QUIT in the code, and the "interrupt" will take + place. The same scheme is used for terminating signals (e.g., SIGHUP) + and the terminating_signal variable. That calls a function which will + end up exiting the shell. */ +#define QUIT \ + do { \ + if (terminating_signal) termsig_handler (terminating_signal); \ + if (interrupt_state) throw_to_top_level (); \ + } while (0) + +#define CHECK_ALRM \ + do { \ + if (sigalrm_seen) \ + sh_longjmp (alrmbuf, 1); \ + } while (0) + +#define SETINTERRUPT interrupt_state = 1 +#define CLRINTERRUPT interrupt_state = 0 + +#define ADDINTERRUPT interrupt_state++ +#define DELINTERRUPT interrupt_state-- + +#define ISINTERRUPT interrupt_state != 0 + +/* The same sort of thing, this time just for signals that would ordinarily + cause the shell to terminate. */ + +#define CHECK_TERMSIG \ + do { \ + if (terminating_signal) termsig_handler (terminating_signal); \ + } while (0) + +#define LASTSIG() \ + (terminating_signal ? terminating_signal : (interrupt_state ? SIGINT : 0)) + +#define CHECK_WAIT_INTR \ + do { \ + if (wait_intr_flag && wait_signal_received && this_shell_builtin && (this_shell_builtin == wait_builtin)) \ + sh_longjmp (wait_intr_buf, 1); \ + } while (0) + +#define RESET_SIGTERM \ + do { \ + sigterm_received = 0; \ + } while (0) + +#define CHECK_SIGTERM \ + do { \ + if (sigterm_received) termsig_handler (SIGTERM); \ + } while (0) +#endif /* _QUIT_H_ */ diff --git a/utshell-0.5.0/variable/readline.h b/utshell-0.5.0/variable/readline.h new file mode 100644 index 00000000..a0f9ed17 --- /dev/null +++ b/utshell-0.5.0/variable/readline.h @@ -0,0 +1,969 @@ +/* Readline.h -- the names of functions callable from within readline. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_READLINE_H_) +#define _READLINE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "rltypedefs.h" +# include "keymaps.h" +# include "tilde.h" +#else +# include "rlstdc.h" +# include "rltypedefs.h" +# include "keymaps.h" +# include "tilde.h" +#endif + +/* Hex-encoded Readline version number. */ +#define RL_READLINE_VERSION 0x0801 /* Readline 8.0 */ +#define RL_VERSION_MAJOR 8 +#define RL_VERSION_MINOR 1 + +/* Readline data structures. */ + +/* Maintaining the state of undo. We remember individual deletes and inserts + on a chain of things to do. */ + +/* The actions that undo knows how to undo. Notice that UNDO_DELETE means + to insert some text, and UNDO_INSERT means to delete some text. I.e., + the code tells undo what to undo, not how to undo it. */ +enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; + +/* What an element of THE_UNDO_LIST looks like. */ +typedef struct undo_list { + struct undo_list *next; + int start, end; /* Where the change took place. */ + char *text; /* The text to insert, if undoing a delete. */ + enum undo_code what; /* Delete, Insert, Begin, End. */ +} UNDO_LIST; + +/* The current undo list for RL_LINE_BUFFER. */ +extern UNDO_LIST *rl_undo_list; + +/* The data structure for mapping textual names to code addresses. */ +typedef struct _funmap { + const char *name; + rl_command_func_t *function; +} FUNMAP; + +extern FUNMAP **funmap; + +/* **************************************************************** */ +/* */ +/* Functions available to bind to key sequences */ +/* */ +/* **************************************************************** */ + +/* Bindable commands for numeric arguments. */ +extern int rl_digit_argument PARAMS((int, int)); +extern int rl_universal_argument PARAMS((int, int)); + +/* Bindable commands for moving the cursor. */ +extern int rl_forward_byte PARAMS((int, int)); +extern int rl_forward_char PARAMS((int, int)); +extern int rl_forward PARAMS((int, int)); +extern int rl_backward_byte PARAMS((int, int)); +extern int rl_backward_char PARAMS((int, int)); +extern int rl_backward PARAMS((int, int)); +extern int rl_beg_of_line PARAMS((int, int)); +extern int rl_end_of_line PARAMS((int, int)); +extern int rl_forward_word PARAMS((int, int)); +extern int rl_backward_word PARAMS((int, int)); +extern int rl_refresh_line PARAMS((int, int)); +extern int rl_clear_screen PARAMS((int, int)); +extern int rl_clear_display PARAMS((int, int)); +extern int rl_skip_csi_sequence PARAMS((int, int)); +extern int rl_arrow_keys PARAMS((int, int)); + +extern int rl_previous_screen_line PARAMS((int, int)); +extern int rl_next_screen_line PARAMS((int, int)); + +/* Bindable commands for inserting and deleting text. */ +extern int rl_insert PARAMS((int, int)); +extern int rl_quoted_insert PARAMS((int, int)); +extern int rl_tab_insert PARAMS((int, int)); +extern int rl_newline PARAMS((int, int)); +extern int rl_do_lowercase_version PARAMS((int, int)); +extern int rl_rubout PARAMS((int, int)); +extern int rl_delete PARAMS((int, int)); +extern int rl_rubout_or_delete PARAMS((int, int)); +extern int rl_delete_horizontal_space PARAMS((int, int)); +extern int rl_delete_or_show_completions PARAMS((int, int)); +extern int rl_insert_comment PARAMS((int, int)); + +/* Bindable commands for changing case. */ +extern int rl_upcase_word PARAMS((int, int)); +extern int rl_downcase_word PARAMS((int, int)); +extern int rl_capitalize_word PARAMS((int, int)); + +/* Bindable commands for transposing characters and words. */ +extern int rl_transpose_words PARAMS((int, int)); +extern int rl_transpose_chars PARAMS((int, int)); + +/* Bindable commands for searching within a line. */ +extern int rl_char_search PARAMS((int, int)); +extern int rl_backward_char_search PARAMS((int, int)); + +/* Bindable commands for readline's interface to the command history. */ +extern int rl_beginning_of_history PARAMS((int, int)); +extern int rl_end_of_history PARAMS((int, int)); +extern int rl_get_next_history PARAMS((int, int)); +extern int rl_get_previous_history PARAMS((int, int)); +extern int rl_operate_and_get_next PARAMS((int, int)); + +/* Bindable commands for managing the mark and region. */ +extern int rl_set_mark PARAMS((int, int)); +extern int rl_exchange_point_and_mark PARAMS((int, int)); + +/* Bindable commands to set the editing mode (emacs or vi). */ +extern int rl_vi_editing_mode PARAMS((int, int)); +extern int rl_emacs_editing_mode PARAMS((int, int)); + +/* Bindable commands to change the insert mode (insert or overwrite) */ +extern int rl_overwrite_mode PARAMS((int, int)); + +/* Bindable commands for managing key bindings. */ +extern int rl_re_read_init_file PARAMS((int, int)); +extern int rl_dump_functions PARAMS((int, int)); +extern int rl_dump_macros PARAMS((int, int)); +extern int rl_dump_variables PARAMS((int, int)); + +/* Bindable commands for word completion. */ +extern int rl_complete PARAMS((int, int)); +extern int rl_possible_completions PARAMS((int, int)); +extern int rl_insert_completions PARAMS((int, int)); +extern int rl_old_menu_complete PARAMS((int, int)); +extern int rl_menu_complete PARAMS((int, int)); +extern int rl_backward_menu_complete PARAMS((int, int)); + +/* Bindable commands for killing and yanking text, and managing the kill ring. */ +extern int rl_kill_word PARAMS((int, int)); +extern int rl_backward_kill_word PARAMS((int, int)); +extern int rl_kill_line PARAMS((int, int)); +extern int rl_backward_kill_line PARAMS((int, int)); +extern int rl_kill_full_line PARAMS((int, int)); +extern int rl_unix_word_rubout PARAMS((int, int)); +extern int rl_unix_filename_rubout PARAMS((int, int)); +extern int rl_unix_line_discard PARAMS((int, int)); +extern int rl_copy_region_to_kill PARAMS((int, int)); +extern int rl_kill_region PARAMS((int, int)); +extern int rl_copy_forward_word PARAMS((int, int)); +extern int rl_copy_backward_word PARAMS((int, int)); +extern int rl_yank PARAMS((int, int)); +extern int rl_yank_pop PARAMS((int, int)); +extern int rl_yank_nth_arg PARAMS((int, int)); +extern int rl_yank_last_arg PARAMS((int, int)); +extern int rl_bracketed_paste_begin PARAMS((int, int)); +/* Not available unless _WIN32 is defined. */ +#if defined (_WIN32) +extern int rl_paste_from_clipboard PARAMS((int, int)); +#endif + +/* Bindable commands for incremental searching. */ +extern int rl_reverse_search_history PARAMS((int, int)); +extern int rl_forward_search_history PARAMS((int, int)); + +/* Bindable keyboard macro commands. */ +extern int rl_start_kbd_macro PARAMS((int, int)); +extern int rl_end_kbd_macro PARAMS((int, int)); +extern int rl_call_last_kbd_macro PARAMS((int, int)); +extern int rl_print_last_kbd_macro PARAMS((int, int)); + +/* Bindable undo commands. */ +extern int rl_revert_line PARAMS((int, int)); +extern int rl_undo_command PARAMS((int, int)); + +/* Bindable tilde expansion commands. */ +extern int rl_tilde_expand PARAMS((int, int)); + +/* Bindable terminal control commands. */ +extern int rl_restart_output PARAMS((int, int)); +extern int rl_stop_output PARAMS((int, int)); + +/* Miscellaneous bindable commands. */ +extern int rl_abort PARAMS((int, int)); +extern int rl_tty_status PARAMS((int, int)); + +/* Bindable commands for incremental and non-incremental history searching. */ +extern int rl_history_search_forward PARAMS((int, int)); +extern int rl_history_search_backward PARAMS((int, int)); +extern int rl_history_substr_search_forward PARAMS((int, int)); +extern int rl_history_substr_search_backward PARAMS((int, int)); +extern int rl_noninc_forward_search PARAMS((int, int)); +extern int rl_noninc_reverse_search PARAMS((int, int)); +extern int rl_noninc_forward_search_again PARAMS((int, int)); +extern int rl_noninc_reverse_search_again PARAMS((int, int)); + +/* Bindable command used when inserting a matching close character. */ +extern int rl_insert_close PARAMS((int, int)); + +/* Not available unless READLINE_CALLBACKS is defined. */ +extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *)); +extern void rl_callback_read_char PARAMS((void)); +extern void rl_callback_handler_remove PARAMS((void)); +extern void rl_callback_sigcleanup PARAMS((void)); + +/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ +/* VI-mode bindable commands. */ +extern int rl_vi_redo PARAMS((int, int)); +extern int rl_vi_undo PARAMS((int, int)); +extern int rl_vi_yank_arg PARAMS((int, int)); +extern int rl_vi_fetch_history PARAMS((int, int)); +extern int rl_vi_search_again PARAMS((int, int)); +extern int rl_vi_search PARAMS((int, int)); +extern int rl_vi_complete PARAMS((int, int)); +extern int rl_vi_tilde_expand PARAMS((int, int)); +extern int rl_vi_prev_word PARAMS((int, int)); +extern int rl_vi_next_word PARAMS((int, int)); +extern int rl_vi_end_word PARAMS((int, int)); +extern int rl_vi_insert_beg PARAMS((int, int)); +extern int rl_vi_append_mode PARAMS((int, int)); +extern int rl_vi_append_eol PARAMS((int, int)); +extern int rl_vi_eof_maybe PARAMS((int, int)); +extern int rl_vi_insertion_mode PARAMS((int, int)); +extern int rl_vi_insert_mode PARAMS((int, int)); +extern int rl_vi_movement_mode PARAMS((int, int)); +extern int rl_vi_arg_digit PARAMS((int, int)); +extern int rl_vi_change_case PARAMS((int, int)); +extern int rl_vi_put PARAMS((int, int)); +extern int rl_vi_column PARAMS((int, int)); +extern int rl_vi_delete_to PARAMS((int, int)); +extern int rl_vi_change_to PARAMS((int, int)); +extern int rl_vi_yank_to PARAMS((int, int)); +extern int rl_vi_yank_pop PARAMS((int, int)); +extern int rl_vi_rubout PARAMS((int, int)); +extern int rl_vi_delete PARAMS((int, int)); +extern int rl_vi_back_to_indent PARAMS((int, int)); +extern int rl_vi_unix_word_rubout PARAMS((int, int)); +extern int rl_vi_first_print PARAMS((int, int)); +extern int rl_vi_char_search PARAMS((int, int)); +extern int rl_vi_match PARAMS((int, int)); +extern int rl_vi_change_char PARAMS((int, int)); +extern int rl_vi_subst PARAMS((int, int)); +extern int rl_vi_overstrike PARAMS((int, int)); +extern int rl_vi_overstrike_delete PARAMS((int, int)); +extern int rl_vi_replace PARAMS((int, int)); +extern int rl_vi_set_mark PARAMS((int, int)); +extern int rl_vi_goto_mark PARAMS((int, int)); + +/* VI-mode utility functions. */ +extern int rl_vi_check PARAMS((void)); +extern int rl_vi_domove PARAMS((int, int *)); +extern int rl_vi_bracktype PARAMS((int)); + +extern void rl_vi_start_inserting PARAMS((int, int, int)); + +/* VI-mode pseudo-bindable commands, used as utility functions. */ +extern int rl_vi_fWord PARAMS((int, int)); +extern int rl_vi_bWord PARAMS((int, int)); +extern int rl_vi_eWord PARAMS((int, int)); +extern int rl_vi_fword PARAMS((int, int)); +extern int rl_vi_bword PARAMS((int, int)); +extern int rl_vi_eword PARAMS((int, int)); + +/* **************************************************************** */ +/* */ +/* Well Published Functions */ +/* */ +/* **************************************************************** */ + +/* Readline functions. */ +/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ +extern char *readline PARAMS((const char *)); + +extern int rl_set_prompt PARAMS((const char *)); +extern int rl_expand_prompt PARAMS((char *)); + +extern int rl_initialize PARAMS((void)); + +/* Undocumented; unused by readline */ +extern int rl_discard_argument PARAMS((void)); + +/* Utility functions to bind keys to readline commands. */ +extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int)); +extern int rl_bind_key PARAMS((int, rl_command_func_t *)); +extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap)); +extern int rl_unbind_key PARAMS((int)); +extern int rl_unbind_key_in_map PARAMS((int, Keymap)); +extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *)); +extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap)); +extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap)); +extern int rl_unbind_command_in_map PARAMS((const char *, Keymap)); +extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *)); +extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); +extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *)); +extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); +extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap)); + +extern char *rl_variable_value PARAMS((const char *)); +extern int rl_variable_bind PARAMS((const char *, const char *)); + +/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */ +extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap)); + +/* Backwards compatibility, use rl_generic_bind instead. */ +extern int rl_macro_bind PARAMS((const char *, const char *, Keymap)); + +/* Undocumented in the texinfo manual; not really useful to programs. */ +extern int rl_translate_keyseq PARAMS((const char *, char *, int *)); +extern char *rl_untranslate_keyseq PARAMS((int)); + +extern rl_command_func_t *rl_named_function PARAMS((const char *)); +extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *)); +extern rl_command_func_t *rl_function_of_keyseq_len PARAMS((const char *, size_t, Keymap, int *)); + +extern void rl_list_funmap_names PARAMS((void)); +extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap)); +extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *)); + +extern void rl_function_dumper PARAMS((int)); +extern void rl_macro_dumper PARAMS((int)); +extern void rl_variable_dumper PARAMS((int)); + +extern int rl_read_init_file PARAMS((const char *)); +extern int rl_parse_and_bind PARAMS((char *)); + +/* Functions for manipulating keymaps. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); +extern int rl_empty_keymap PARAMS((Keymap)); +extern Keymap rl_copy_keymap PARAMS((Keymap)); +extern Keymap rl_make_keymap PARAMS((void)); +extern void rl_discard_keymap PARAMS((Keymap)); +extern void rl_free_keymap PARAMS((Keymap)); + +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); +extern char *rl_get_keymap_name PARAMS((Keymap)); +extern void rl_set_keymap PARAMS((Keymap)); +extern Keymap rl_get_keymap PARAMS((void)); + +extern int rl_set_keymap_name PARAMS((const char *, Keymap)); + +/* Undocumented; used internally only. */ +extern void rl_set_keymap_from_edit_mode PARAMS((void)); +extern char *rl_get_keymap_name_from_edit_mode PARAMS((void)); + +/* Functions for manipulating the funmap, which maps command names to functions. */ +extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *)); +extern const char **rl_funmap_names PARAMS((void)); +/* Undocumented, only used internally -- there is only one funmap, and this + function may be called only once. */ +extern void rl_initialize_funmap PARAMS((void)); + +/* Utility functions for managing keyboard macros. */ +extern void rl_push_macro_input PARAMS((char *)); + +/* Functions for undoing, from undo.c */ +extern void rl_add_undo PARAMS((enum undo_code, int, int, char *)); +extern void rl_free_undo_list PARAMS((void)); +extern int rl_do_undo PARAMS((void)); +extern int rl_begin_undo_group PARAMS((void)); +extern int rl_end_undo_group PARAMS((void)); +extern int rl_modifying PARAMS((int, int)); + +/* Functions for redisplay. */ +extern void rl_redisplay PARAMS((void)); +extern int rl_on_new_line PARAMS((void)); +extern int rl_on_new_line_with_prompt PARAMS((void)); +extern int rl_forced_update_display PARAMS((void)); +extern int rl_clear_visible_line PARAMS((void)); +extern int rl_clear_message PARAMS((void)); +extern int rl_reset_line_state PARAMS((void)); +extern int rl_crlf PARAMS((void)); + +/* Functions to manage the mark and region, especially the notion of an + active mark and an active region. */ +extern void rl_keep_mark_active PARAMS((void)); + +extern void rl_activate_mark PARAMS((void)); +extern void rl_deactivate_mark PARAMS((void)); +extern int rl_mark_active_p PARAMS((void)); + +#if defined (USE_VARARGS) && defined (PREFER_STDARG) +extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#else +extern int rl_message (); +#endif + +extern int rl_show_char PARAMS((int)); + +/* Undocumented in texinfo manual. */ +extern int rl_character_len PARAMS((int, int)); +extern void rl_redraw_prompt_last_line PARAMS((void)); + +/* Save and restore internal prompt redisplay information. */ +extern void rl_save_prompt PARAMS((void)); +extern void rl_restore_prompt PARAMS((void)); + +/* Modifying text. */ +extern void rl_replace_line PARAMS((const char *, int)); +extern int rl_insert_text PARAMS((const char *)); +extern int rl_delete_text PARAMS((int, int)); +extern int rl_kill_text PARAMS((int, int)); +extern char *rl_copy_text PARAMS((int, int)); + +/* Terminal and tty mode management. */ +extern void rl_prep_terminal PARAMS((int)); +extern void rl_deprep_terminal PARAMS((void)); +extern void rl_tty_set_default_bindings PARAMS((Keymap)); +extern void rl_tty_unset_default_bindings PARAMS((Keymap)); + +extern int rl_tty_set_echoing PARAMS((int)); +extern int rl_reset_terminal PARAMS((const char *)); +extern void rl_resize_terminal PARAMS((void)); +extern void rl_set_screen_size PARAMS((int, int)); +extern void rl_get_screen_size PARAMS((int *, int *)); +extern void rl_reset_screen_size PARAMS((void)); + +extern char *rl_get_termcap PARAMS((const char *)); + +/* Functions for character input. */ +extern int rl_stuff_char PARAMS((int)); +extern int rl_execute_next PARAMS((int)); +extern int rl_clear_pending_input PARAMS((void)); +extern int rl_read_key PARAMS((void)); +extern int rl_getc PARAMS((FILE *)); +extern int rl_set_keyboard_input_timeout PARAMS((int)); + +/* `Public' utility functions . */ +extern void rl_extend_line_buffer PARAMS((int)); +extern int rl_ding PARAMS((void)); +extern int rl_alphabetic PARAMS((int)); +extern void rl_free PARAMS((void *)); + +/* Readline signal handling, from signals.c */ +extern int rl_set_signals PARAMS((void)); +extern int rl_clear_signals PARAMS((void)); +extern void rl_cleanup_after_signal PARAMS((void)); +extern void rl_reset_after_signal PARAMS((void)); +extern void rl_free_line_state PARAMS((void)); + +extern int rl_pending_signal PARAMS((void)); +extern void rl_check_signals PARAMS((void)); + +extern void rl_echo_signal_char PARAMS((int)); + +extern int rl_set_paren_blink_timeout PARAMS((int)); + +/* History management functions. */ + +extern void rl_clear_history PARAMS((void)); + +/* Undocumented. */ +extern int rl_maybe_save_line PARAMS((void)); +extern int rl_maybe_unsave_line PARAMS((void)); +extern int rl_maybe_replace_line PARAMS((void)); + +/* Completion functions. */ +extern int rl_complete_internal PARAMS((int)); +extern void rl_display_match_list PARAMS((char **, int, int)); + +extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)); +extern char *rl_username_completion_function PARAMS((const char *, int)); +extern char *rl_filename_completion_function PARAMS((const char *, int)); + +extern int rl_completion_mode PARAMS((rl_command_func_t *)); + +#if 0 +/* Backwards compatibility (compat.c). These will go away sometime. */ +extern void free_undo_list PARAMS((void)); +extern int maybe_save_line PARAMS((void)); +extern int maybe_unsave_line PARAMS((void)); +extern int maybe_replace_line PARAMS((void)); + +extern int ding PARAMS((void)); +extern int alphabetic PARAMS((int)); +extern int crlf PARAMS((void)); + +extern char **completion_matches PARAMS((char *, rl_compentry_func_t *)); +extern char *username_completion_function PARAMS((const char *, int)); +extern char *filename_completion_function PARAMS((const char *, int)); +#endif + +/* **************************************************************** */ +/* */ +/* Well Published Variables */ +/* */ +/* **************************************************************** */ + +/* The version of this incarnation of the readline library. */ +extern const char *rl_library_version; /* e.g., "4.2" */ +extern int rl_readline_version; /* e.g., 0x0402 */ + +/* True if this is real GNU readline. */ +extern int rl_gnu_readline_p; + +/* Flags word encapsulating the current readline state. */ +extern unsigned long rl_readline_state; + +/* Says which editing mode readline is currently using. 1 means emacs mode; + 0 means vi mode. */ +extern int rl_editing_mode; + +/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means + overwrite mode. Reset to insert mode on each input line. */ +extern int rl_insert_mode; + +/* The name of the calling program. You should initialize this to + whatever was in argv[0]. It is used when parsing conditionals. */ +extern const char *rl_readline_name; + +/* The prompt readline uses. This is set from the argument to + readline (), and should not be assigned to directly. */ +extern char *rl_prompt; + +/* The prompt string that is actually displayed by rl_redisplay. Public so + applications can more easily supply their own redisplay functions. */ +extern char *rl_display_prompt; + +/* The line buffer that is in use. */ +extern char *rl_line_buffer; + +/* The location of point, and end. */ +extern int rl_point; +extern int rl_end; + +/* The mark, or saved cursor position. */ +extern int rl_mark; + +/* Flag to indicate that readline has finished with the current input + line and should return it. */ +extern int rl_done; + +/* If set to a character value, that will be the next keystroke read. */ +extern int rl_pending_input; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +extern int rl_dispatching; + +/* Non-zero if the user typed a numeric argument before executing the + current function. */ +extern int rl_explicit_arg; + +/* The current value of the numeric argument specified by the user. */ +extern int rl_numeric_arg; + +/* The address of the last command function Readline executed. */ +extern rl_command_func_t *rl_last_func; + +/* The name of the terminal to use. */ +extern const char *rl_terminal_name; + +/* The input and output streams. */ +extern FILE *rl_instream; +extern FILE *rl_outstream; + +/* If non-zero, Readline gives values of LINES and COLUMNS from the environment + greater precedence than values fetched from the kernel when computing the + screen dimensions. */ +extern int rl_prefer_env_winsize; + +/* If non-zero, then this is the address of a function to call just + before readline_internal () prints the first prompt. */ +extern rl_hook_func_t *rl_startup_hook; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +extern rl_hook_func_t *rl_pre_input_hook; + +/* The address of a function to call periodically while Readline is + awaiting character input, or NULL, for no event handling. */ +extern rl_hook_func_t *rl_event_hook; + +/* The address of a function to call if a read is interrupted by a signal. */ +extern rl_hook_func_t *rl_signal_event_hook; + +/* The address of a function to call if Readline needs to know whether or not + there is data available from the current input source. */ +extern rl_hook_func_t *rl_input_available_hook; + +/* The address of the function to call to fetch a character from the current + Readline input stream */ +extern rl_getc_func_t *rl_getc_function; + +extern rl_voidfunc_t *rl_redisplay_function; + +extern rl_vintfunc_t *rl_prep_term_function; +extern rl_voidfunc_t *rl_deprep_term_function; + +/* Dispatch variables. */ +extern Keymap rl_executing_keymap; +extern Keymap rl_binding_keymap; + +extern int rl_executing_key; +extern char *rl_executing_keyseq; +extern int rl_key_sequence_length; + +/* Display variables. */ +/* If non-zero, readline will erase the entire line, including any prompt, + if the only thing typed on an otherwise-blank line is something bound to + rl_newline. */ +extern int rl_erase_empty_line; + +/* If non-zero, the application has already printed the prompt (rl_prompt) + before calling readline, so readline should not output it the first time + redisplay is done. */ +extern int rl_already_prompted; + +/* A non-zero value means to read only this many characters rather than + up to a character bound to accept-line. */ +extern int rl_num_chars_to_read; + +/* The text of a currently-executing keyboard macro. */ +extern char *rl_executing_macro; + +/* Variables to control readline signal handling. */ +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +extern int rl_catch_signals; + +/* If non-zero, readline will install a signal handler for SIGWINCH + that also attempts to call any calling application's SIGWINCH signal + handler. Note that the terminal is not cleaned up before the + application's signal handler is called; use rl_cleanup_after_signal() + to do that. */ +extern int rl_catch_sigwinch; + +/* If non-zero, the readline SIGWINCH handler will modify LINES and + COLUMNS in the environment. */ +extern int rl_change_environment; + +/* Completion variables. */ +/* Pointer to the generator function for completion_matches (). + NULL means to use rl_filename_completion_function (), the default + filename completer. */ +extern rl_compentry_func_t *rl_completion_entry_function; + +/* Optional generator for menu completion. Default is + rl_completion_entry_function (rl_filename_completion_function). */ +extern rl_compentry_func_t *rl_menu_completion_entry_function; + +/* If rl_ignore_some_completions_function is non-NULL it is the address + of a function to call after all of the possible matches have been + generated, but before the actual completion is done to the input line. + The function is called with one argument; a NULL terminated array + of (char *). If your function removes any of the elements, they + must be free()'ed. */ +extern rl_compignore_func_t *rl_ignore_some_completions_function; + +/* Pointer to alternative function to create matches. + Function is called with TEXT, START, and END. + START and END are indices in RL_LINE_BUFFER saying what the boundaries + of TEXT are. + If this function exists and returns NULL then call the value of + rl_completion_entry_function to try to match, otherwise use the + array of strings returned. */ +extern rl_completion_func_t *rl_attempted_completion_function; + +/* The basic list of characters that signal a break between words for the + completer routine. The initial contents of this variable is what + breaks words in the shell, i.e. "n\"\\'`@$>". */ +extern const char *rl_basic_word_break_characters; + +/* The list of characters that signal a break between words for + rl_complete_internal. The default list is the contents of + rl_basic_word_break_characters. */ +extern /*const*/ char *rl_completer_word_break_characters; + +/* Hook function to allow an application to set the completion word + break characters before readline breaks up the line. Allows + position-dependent word break characters. */ +extern rl_cpvfunc_t *rl_completion_word_break_hook; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +extern const char *rl_completer_quote_characters; + +/* List of quote characters which cause a word break. */ +extern const char *rl_basic_quote_characters; + +/* List of characters that need to be quoted in filenames by the completer. */ +extern const char *rl_filename_quote_characters; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +extern const char *rl_special_prefixes; + +/* If non-zero, then this is the address of a function to call when + completing on a directory name. The function is called with + the address of a string (the current directory name) as an arg. It + changes what is displayed when the possible completions are printed + or inserted. The directory completion hook should perform + any necessary dequoting. This function should return 1 if it modifies + the directory name pointer passed as an argument. If the directory + completion hook returns 0, it should not modify the directory name + pointer passed as an argument. */ +extern rl_icppfunc_t *rl_directory_completion_hook; + +/* If non-zero, this is the address of a function to call when completing + a directory name. This function takes the address of the directory name + to be modified as an argument. Unlike rl_directory_completion_hook, it + only modifies the directory name used in opendir(2), not what is displayed + when the possible completions are printed or inserted. If set, it takes + precedence over rl_directory_completion_hook. The directory rewrite + hook should perform any necessary dequoting. This function has the same + return value properties as the directory_completion_hook. + + I'm not happy with how this works yet, so it's undocumented. I'm trying + it in bash to see how well it goes. */ +extern rl_icppfunc_t *rl_directory_rewrite_hook; + +/* If non-zero, this is the address of a function for the completer to call + before deciding which character to append to a completed name. It should + modify the directory name passed as an argument if appropriate, and return + non-zero if it modifies the name. This should not worry about dequoting + the filename; that has already happened by the time it gets here. */ +extern rl_icppfunc_t *rl_filename_stat_hook; + +/* If non-zero, this is the address of a function to call when reading + directory entries from the filesystem for completion and comparing + them to the partial word to be completed. The function should + either return its first argument (if no conversion takes place) or + newly-allocated memory. This can, for instance, convert filenames + between character sets for comparison against what's typed at the + keyboard. The returned value is what is added to the list of + matches. The second argument is the length of the filename to be + converted. */ +extern rl_dequote_func_t *rl_filename_rewrite_hook; + +/* Backwards compatibility with previous versions of readline. */ +#define rl_symbolic_link_hook rl_directory_completion_hook + +/* If non-zero, then this is the address of a function to call when + completing a word would normally display the list of possible matches. + This function is called instead of actually doing the display. + It takes three arguments: (char **matches, int num_matches, int max_length) + where MATCHES is the array of strings that matched, NUM_MATCHES is the + number of strings in that array, and MAX_LENGTH is the length of the + longest string in that array. */ +extern rl_compdisp_func_t *rl_completion_display_matches_hook; + +/* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ +extern int rl_filename_completion_desired; + +/* Non-zero means that the results of the matches are to be quoted using + double quotes (or an application-specific quoting mechanism) if the + filename contains any characters in rl_word_break_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ +extern int rl_filename_quoting_desired; + +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +extern rl_quote_func_t *rl_filename_quoting_function; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. */ +extern rl_dequote_func_t *rl_filename_dequoting_function; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +extern rl_linebuf_func_t *rl_char_is_quoted_p; + +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +extern int rl_attempted_completion_over; + +/* Set to a character describing the type of completion being attempted by + rl_complete_internal; available for use by application completion + functions. */ +extern int rl_completion_type; + +/* Set to the last key used to invoke one of the completion functions */ +extern int rl_completion_invoking_key; + +/* Up to this many items will be displayed in response to a + possible-completions call. After that, we ask the user if she + is sure she wants to see them all. The default value is 100. */ +extern int rl_completion_query_items; + +/* Character appended to completed words when at the end of the line. The + default is a space. Nothing is added if this is '\0'. */ +extern int rl_completion_append_character; + +/* If set to non-zero by an application completion function, + rl_completion_append_character will not be appended. */ +extern int rl_completion_suppress_append; + +/* Set to any quote character readline thinks it finds before any application + completion function is called. */ +extern int rl_completion_quote_character; + +/* Set to a non-zero value if readline found quoting anywhere in the word to + be completed; set before any application completion function is called. */ +extern int rl_completion_found_quote; + +/* If non-zero, the completion functions don't append any closing quote. + This is set to 0 by rl_complete_internal and may be changed by an + application-specific completion function. */ +extern int rl_completion_suppress_quote; + +/* If non-zero, readline will sort the completion matches. On by default. */ +extern int rl_sort_completion_matches; + +/* If non-zero, a slash will be appended to completed filenames that are + symbolic links to directory names, subject to the value of the + mark-directories variable (which is user-settable). This exists so + that application completion functions can override the user's preference + (set via the mark-symlinked-directories variable) if appropriate. + It's set to the value of _rl_complete_mark_symlink_dirs in + rl_complete_internal before any application-specific completion + function is called, so without that function doing anything, the user's + preferences are honored. */ +extern int rl_completion_mark_symlink_dirs; + +/* If non-zero, then disallow duplicates in the matches. */ +extern int rl_ignore_completion_duplicates; + +/* If this is non-zero, completion is (temporarily) inhibited, and the + completion character will be inserted as any other. */ +extern int rl_inhibit_completion; + +/* Applications can set this to non-zero to have readline's signal handlers + installed during the entire duration of reading a complete line, as in + readline-6.2. This should be used with care, because it can result in + readline receiving signals and not handling them until it's called again + via rl_callback_read_char, thereby stealing them from the application. + By default, signal handlers are only active while readline is active. */ +extern int rl_persistent_signal_handlers; + +/* Input error; can be returned by (*rl_getc_function) if readline is reading + a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */ +#define READERR (-2) + +/* Definitions available for use by readline clients. */ +#define RL_PROMPT_START_IGNORE '\001' +#define RL_PROMPT_END_IGNORE '\002' + +/* Possible values for do_replace argument to rl_filename_quoting_function, + called by rl_complete_internal. */ +#define NO_MATCH 0 +#define SINGLE_MATCH 1 +#define MULT_MATCH 2 + +/* Possible state values for rl_readline_state */ +#define RL_STATE_NONE 0x000000 /* no state; before first call */ + +#define RL_STATE_INITIALIZING 0x0000001 /* initializing */ +#define RL_STATE_INITIALIZED 0x0000002 /* initialization done */ +#define RL_STATE_TERMPREPPED 0x0000004 /* terminal is prepped */ +#define RL_STATE_READCMD 0x0000008 /* reading a command key */ +#define RL_STATE_METANEXT 0x0000010 /* reading input after ESC */ +#define RL_STATE_DISPATCHING 0x0000020 /* dispatching to a command */ +#define RL_STATE_MOREINPUT 0x0000040 /* reading more input in a command function */ +#define RL_STATE_ISEARCH 0x0000080 /* doing incremental search */ +#define RL_STATE_NSEARCH 0x0000100 /* doing non-inc search */ +#define RL_STATE_SEARCH 0x0000200 /* doing a history search */ +#define RL_STATE_NUMERICARG 0x0000400 /* reading numeric argument */ +#define RL_STATE_MACROINPUT 0x0000800 /* getting input from a macro */ +#define RL_STATE_MACRODEF 0x0001000 /* defining keyboard macro */ +#define RL_STATE_OVERWRITE 0x0002000 /* overwrite mode */ +#define RL_STATE_COMPLETING 0x0004000 /* doing completion */ +#define RL_STATE_SIGHANDLER 0x0008000 /* in readline sighandler */ +#define RL_STATE_UNDOING 0x0010000 /* doing an undo */ +#define RL_STATE_INPUTPENDING 0x0020000 /* rl_execute_next called */ +#define RL_STATE_TTYCSAVED 0x0040000 /* tty special chars saved */ +#define RL_STATE_CALLBACK 0x0080000 /* using the callback interface */ +#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */ +#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */ +#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */ +#define RL_STATE_CHARSEARCH 0x0800000 /* vi mode char search */ +#define RL_STATE_REDISPLAYING 0x1000000 /* updating terminal display */ + +#define RL_STATE_DONE 0x2000000 /* done; accepted line */ + +#define RL_SETSTATE(x) (rl_readline_state |= (x)) +#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) +#define RL_ISSTATE(x) (rl_readline_state & (x)) + +struct readline_state { + /* line state */ + int point; + int end; + int mark; + int buflen; + char *buffer; + UNDO_LIST *ul; + char *prompt; + + /* global state */ + int rlstate; + int done; + Keymap kmap; + + /* input state */ + rl_command_func_t *lastfunc; + int insmode; + int edmode; + char *kseq; + int kseqlen; + + int pendingin; + FILE *inf; + FILE *outf; + char *macro; + + /* signal state */ + int catchsigs; + int catchsigwinch; + + /* search state */ + + /* completion state */ + rl_compentry_func_t *entryfunc; + rl_compentry_func_t *menuentryfunc; + rl_compignore_func_t *ignorefunc; + rl_completion_func_t *attemptfunc; + char *wordbreakchars; + + /* options state */ + + /* hook state */ + + /* reserved for future expansion, so the struct size doesn't change */ + char reserved[64]; +}; + +extern int rl_save_state PARAMS((struct readline_state *)); +extern int rl_restore_state PARAMS((struct readline_state *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _READLINE_H_ */ diff --git a/utshell-0.5.0/variable/rlconf.h b/utshell-0.5.0/variable/rlconf.h new file mode 100644 index 00000000..b6d6a2f1 --- /dev/null +++ b/utshell-0.5.0/variable/rlconf.h @@ -0,0 +1,79 @@ +/* rlconf.h -- readline configuration definitions */ + +/* Copyright (C) 1992-2015 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RLCONF_H_) +#define _RLCONF_H_ + +/* Define this if you want the vi-mode editing available. */ +#define VI_MODE + +/* Define this to get an indication of file type when listing completions. */ +#define VISIBLE_STATS + +/* Define this to get support for colors when listing completions and in + other places. */ +#define COLOR_SUPPORT + +/* This definition is needed by readline.c, rltty.c, and signals.c. */ +/* If on, then readline handles signals in a way that doesn't suck. */ +#define HANDLE_SIGNALS + +/* Ugly but working hack for binding prefix meta. */ +#define PREFIX_META_HACK + +/* The next-to-last-ditch effort file name for a user-specific init file. */ +#define DEFAULT_INPUTRC "~/.inputrc" + +/* The ultimate last-ditch filename for an init file -- system-wide. */ +#define SYS_INPUTRC "/etc/inputrc" + +/* If defined, expand tabs to spaces. */ +#define DISPLAY_TABS + +/* If defined, use the terminal escape sequence to move the cursor forward + over a character when updating the line rather than rewriting it. */ +/* #define HACK_TERMCAP_MOTION */ + +/* The string inserted by the `insert comment' command. */ +#define RL_COMMENT_BEGIN_DEFAULT "#" + +/* Define this if you want code that allows readline to be used in an + X `callback' style. */ +#define READLINE_CALLBACKS + +/* Define this if you want the cursor to indicate insert or overwrite mode. */ +/* #define CURSOR_MODE */ + +/* Define this if you want to enable code that talks to the Linux kernel + tty auditing system. */ +/* #define ENABLE_TTY_AUDIT_SUPPORT */ + +/* Defaults for the various editing mode indicators, inserted at the beginning + of the last (maybe only) line of the prompt if show-mode-in-prompt is on */ +#define RL_EMACS_MODESTR_DEFAULT "@" +#define RL_EMACS_MODESTR_DEFLEN 1 + +#define RL_VI_INS_MODESTR_DEFAULT "(ins)" +#define RL_VI_INS_MODESTR_DEFLEN 5 +#define RL_VI_CMD_MODESTR_DEFAULT "(cmd)" +#define RL_VI_CMD_MODESTR_DEFLEN 5 + +#endif /* _RLCONF_H_ */ diff --git a/utshell-0.5.0/variable/rlstdc.h b/utshell-0.5.0/variable/rlstdc.h new file mode 100644 index 00000000..2aaa30ba --- /dev/null +++ b/utshell-0.5.0/variable/rlstdc.h @@ -0,0 +1,57 @@ +/* stdc.h -- macros to make source compile on both ANSI C and K&R C compilers. */ + +/* Copyright (C) 1993-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_RL_STDC_H_) +#define _RL_STDC_H_ + +/* Adapted from BSD /usr/include/sys/cdefs.h. */ + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(x) +# endif +#endif + +/* Moved from config.h.in because readline.h:rl_message depends on these + defines. */ +#if defined (__STDC__) && defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +#else +# if defined (HAVE_VARARGS_H) +# define PREFER_VARARGS +# define USE_VARARGS +# endif +#endif + +#endif /* !_RL_STDC_H_ */ diff --git a/utshell-0.5.0/variable/rltypedefs.h b/utshell-0.5.0/variable/rltypedefs.h new file mode 100644 index 00000000..f9f5cd3a --- /dev/null +++ b/utshell-0.5.0/variable/rltypedefs.h @@ -0,0 +1,100 @@ +/* rltypedefs.h -- Type declarations for readline functions. */ + +/* Copyright (C) 2000-2011 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#ifndef _RL_TYPEDEFS_H_ +#define _RL_TYPEDEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Old-style, attempt to mark as deprecated in some way people will notice. */ + +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF + +#if defined(__GNUC__) || defined(__clang__) +typedef int Function () __attribute__ ((deprecated)); +typedef void VFunction () __attribute__ ((deprecated)); +typedef char *CPFunction () __attribute__ ((deprecated)); +typedef char **CPPFunction () __attribute__ ((deprecated)); +#else +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); +typedef char **CPPFunction (); +#endif + +#endif /* _FUNCTION_DEF */ + +/* New style. */ + +#if !defined (_RL_FUNCTION_TYPEDEF) +# define _RL_FUNCTION_TYPEDEF + +/* Bindable functions */ +typedef int rl_command_func_t PARAMS((int, int)); + +/* Typedefs for the completion system */ +typedef char *rl_compentry_func_t PARAMS((const char *, int)); +typedef char **rl_completion_func_t PARAMS((const char *, int, int)); + +typedef char *rl_quote_func_t PARAMS((char *, int, char *)); +typedef char *rl_dequote_func_t PARAMS((char *, int)); + +typedef int rl_compignore_func_t PARAMS((char **)); + +typedef void rl_compdisp_func_t PARAMS((char **, int, int)); + +/* Type for input and pre-read hook functions like rl_event_hook */ +typedef int rl_hook_func_t PARAMS((void)); + +/* Input function type */ +typedef int rl_getc_func_t PARAMS((FILE *)); + +/* Generic function that takes a character buffer (which could be the readline + line buffer) and an index into it (which could be rl_point) and returns + an int. */ +typedef int rl_linebuf_func_t PARAMS((char *, int)); + +/* `Generic' function pointer typedefs */ +typedef int rl_intfunc_t PARAMS((int)); +#define rl_ivoidfunc_t rl_hook_func_t +typedef int rl_icpfunc_t PARAMS((char *)); +typedef int rl_icppfunc_t PARAMS((char **)); + +typedef void rl_voidfunc_t PARAMS((void)); +typedef void rl_vintfunc_t PARAMS((int)); +typedef void rl_vcpfunc_t PARAMS((char *)); +typedef void rl_vcppfunc_t PARAMS((char **)); + +typedef char *rl_cpvfunc_t PARAMS((void)); +typedef char *rl_cpifunc_t PARAMS((int)); +typedef char *rl_cpcpfunc_t PARAMS((char *)); +typedef char *rl_cpcppfunc_t PARAMS((char **)); + +#endif /* _RL_FUNCTION_TYPEDEF */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RL_TYPEDEFS_H_ */ diff --git a/utshell-0.5.0/variable/shell.h b/utshell-0.5.0/variable/shell.h new file mode 100644 index 00000000..bda3c37d --- /dev/null +++ b/utshell-0.5.0/variable/shell.h @@ -0,0 +1,231 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* shell.h -- The data structures used by the shell */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "bashjmp.h" + +#include "command.h" +#include "syntax.h" +#include "general.h" +#include "error.h" +#include "variables.h" +#include "arrayfunc.h" +#include "quit.h" +#include "maxpath.h" +#include "unwind_prot.h" +#include "dispose_cmd.h" +#include "make_cmd.h" +#include "ocache.h" +#include "subst.h" +#include "sig.h" +#include "pathnames.h" +#include "externs.h" + +extern int EOF_Reached; + +#define NO_PIPE -1 +#define REDIRECT_BOTH -2 + +#define NO_VARIABLE -1 + +/* Values that can be returned by execute_command (). */ +#define EXECUTION_FAILURE 1 +#define EXECUTION_SUCCESS 0 + +/* Usage messages by builtins result in a return status of 2. */ +#define EX_BADUSAGE 2 + +#define EX_MISCERROR 2 + +/* Special exit statuses used by the shell, internally and externally. */ +#define EX_RETRYFAIL 124 +#define EX_WEXPCOMSUB 125 +#define EX_BINARY_FILE 126 +#define EX_NOEXEC 126 +#define EX_NOINPUT 126 +#define EX_NOTFOUND 127 + +#define EX_SHERRBASE 256 /* all special error values are > this. */ + +#define EX_BADSYNTAX 257 /* shell syntax error */ +#define EX_USAGE 258 /* syntax error in usage */ +#define EX_REDIRFAIL 259 /* redirection failed */ +#define EX_BADASSIGN 260 /* variable assignment error */ +#define EX_EXPFAIL 261 /* word expansion failed */ +#define EX_DISKFALLBACK 262 /* fall back to disk command from builtin */ + +/* Flag values that control parameter pattern substitution. */ +#define MATCH_ANY 0x000 +#define MATCH_BEG 0x001 +#define MATCH_END 0x002 + +#define MATCH_TYPEMASK 0x003 + +#define MATCH_GLOBREP 0x010 +#define MATCH_QUOTED 0x020 +#define MATCH_ASSIGNRHS 0x040 +#define MATCH_STARSUB 0x080 + +/* Some needed external declarations. */ +extern char **shell_environment; +extern WORD_LIST *rest_of_args; + +/* Generalized global variables. */ +extern char *command_execution_string; + +extern int debugging_mode; +extern int executing, login_shell; +extern int interactive, interactive_shell; +extern int startup_state; +extern int reading_shell_script; +extern int shell_initialized; +extern int rpm_requires; +extern int bash_argv_initialized; +extern int subshell_environment; +extern int current_command_number; +extern int indirection_level; +extern int shell_compatibility_level; +extern int running_under_emacs; + +extern int posixly_correct; +extern int no_line_editing; + +extern char *shell_name; +extern char *current_host_name; + +extern int subshell_argc; +extern char **subshell_argv; +extern char **subshell_envp; + +/* variables managed using shopt */ +extern int hup_on_exit; +extern int check_jobs_at_exit; +extern int autocd; +extern int check_window_size; + +/* from version.c */ +extern int build_version, patch_level; +extern char *dist_version, *release_status; + +extern int locale_mb_cur_max; +extern int locale_utf8locale; + +/* Structure to pass around that holds a bitmap of file descriptors + to close, and the size of that structure. Used in execute_cmd.c. */ +struct fd_bitmap { + int size; + char *bitmap; +}; + +#define FD_BITMAP_SIZE 32 + +#define CTLESC '\001' +#define CTLNUL '\177' + +/* Information about the current user. */ +struct user_info { + uid_t uid, euid; + gid_t gid, egid; + char *user_name; + char *shell; /* shell from the password file */ + char *home_dir; +}; + +extern struct user_info current_user; + +/* Force gcc to not clobber X on a longjmp(). Old versions of gcc mangle + this badly. */ +#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 8) +# define USE_VAR(x) ((void) &(x)) +#else +# define USE_VAR(x) +#endif + +#define HEREDOC_MAX 16 + +/* Structure in which to save partial parsing state when doing things like + PROMPT_COMMAND and bash_execute_unix_command execution. */ + +typedef struct _sh_parser_state_t { + + /* parsing state */ + int parser_state; + int *token_state; + + char *token; + int token_buffer_size; + + /* input line state -- line number saved elsewhere */ + int input_line_terminator; + int eof_encountered; + +#if defined (HANDLE_MULTIBYTE) + /* Nothing right now for multibyte state, but might want something later. */ +#endif + + char **prompt_string_pointer; + + /* history state affecting or modified by the parser */ + int current_command_line_count; +#if defined (HISTORY) + int remember_on_history; + int history_expansion_inhibited; +#endif + + /* execution state possibly modified by the parser */ + int last_command_exit_value; +#if defined (ARRAY_VARS) + ARRAY *pipestatus; +#endif + sh_builtin_func_t *last_shell_builtin, *this_shell_builtin; + + /* flags state affecting the parser */ + int expand_aliases; + int echo_input_at_read; + int need_here_doc; + int here_doc_first_line; + + /* structures affecting the parser */ + REDIRECT *redir_stack[HEREDOC_MAX]; +} sh_parser_state_t; + +typedef struct _sh_input_line_state_t { + char *input_line; + size_t input_line_index; + size_t input_line_size; + size_t input_line_len; +#if defined (HANDLE_MULTIBYTE) + char *input_property; + size_t input_propsize; +#endif +} sh_input_line_state_t; + +/* Let's try declaring these here. */ +extern char *parser_remaining_input PARAMS((void)); + +extern sh_parser_state_t *save_parser_state PARAMS((sh_parser_state_t *)); +extern void restore_parser_state PARAMS((sh_parser_state_t *)); + +extern sh_input_line_state_t *save_input_line_state PARAMS((sh_input_line_state_t *)); +extern void restore_input_line_state PARAMS((sh_input_line_state_t *)); diff --git a/utshell-0.5.0/variable/shmbchar.h b/utshell-0.5.0/variable/shmbchar.h new file mode 100644 index 00000000..a4f3f247 --- /dev/null +++ b/utshell-0.5.0/variable/shmbchar.h @@ -0,0 +1,112 @@ +/* Multibyte character data type. + Copyright (C) 2001, 2005-2007, 2009-2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible . */ + +#ifndef _SHMBCHAR_H +#define _SHMBCHAR_H 1 + +#if defined (HANDLE_MULTIBYTE) + +#include + +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.1 has a bug: and must be included before + . */ +#include +#include +#include +#include + + +/* is_basic(c) tests whether the single-byte character c is in the + ISO C "basic character set". */ + +#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) +/* The character set is ISO-646, not EBCDIC. */ +# define IS_BASIC_ASCII 1 + +extern const unsigned int is_basic_table[]; + +static inline int +is_basic (char c) +{ + return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31)) + & 1; +} + +#else + +static inline int +is_basic (char c) +{ + switch (c) + { + case '\b': case '\r': case '\n': + case '\t': case '\v': case '\f': + case ' ': case '!': case '"': case '#': case '%': + case '&': case '\'': case '(': case ')': case '*': + case '+': case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': + case '?': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': + case 'Z': + case '[': case '\\': case ']': case '^': case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': + case 'z': case '{': case '|': case '}': case '~': + return 1; + default: + return 0; + } +} + +#endif + +#endif /* HANDLE_MULTIBYTE */ +#endif /* _SHMBCHAR_H */ diff --git a/utshell-0.5.0/variable/shmbutil.h b/utshell-0.5.0/variable/shmbutil.h new file mode 100644 index 00000000..83d9ec3e --- /dev/null +++ b/utshell-0.5.0/variable/shmbutil.h @@ -0,0 +1,551 @@ +/* shmbutil.h -- utility functions for multibyte characters. */ + +/* Copyright (C) 2002-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_SH_MBUTIL_H_) +#define _SH_MBUTIL_H_ + +#include "stdc.h" + +/* Include config.h for HANDLE_MULTIBYTE */ +#include "config.h" + +#if defined (HANDLE_MULTIBYTE) +#include "shmbchar.h" + +extern size_t xwcsrtombs PARAMS((char *, const wchar_t **, size_t, mbstate_t *)); +extern size_t xmbsrtowcs PARAMS((wchar_t *, const char **, size_t, mbstate_t *)); +extern size_t xdupmbstowcs PARAMS((wchar_t **, char ***, const char *)); + +extern size_t mbstrlen PARAMS((const char *)); + +extern char *xstrchr PARAMS((const char *, int)); + +extern int locale_mb_cur_max; /* XXX */ +extern int locale_utf8locale; /* XXX */ + +#ifndef MB_INVALIDCH +#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2) +#define MB_NULLWCH(x) ((x) == 0) +#endif + +#define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0) +#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s)) + +#define MBLEN(s, n) ((MB_CUR_MAX > 1) ? mblen ((s), (n)) : 1) +#define MBRLEN(s, n, p) ((MB_CUR_MAX > 1) ? mbrlen ((s), (n), (p)) : 1) + +#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0) +#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0) +#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80) + +#else /* !HANDLE_MULTIBYTE */ + +#undef MB_LEN_MAX +#undef MB_CUR_MAX + +#define MB_LEN_MAX 1 +#define MB_CUR_MAX 1 + +#undef xstrchr +#define xstrchr(s, c) strchr(s, c) + +#ifndef MB_INVALIDCH +#define MB_INVALIDCH(x) (0) +#define MB_NULLWCH(x) (0) +#endif + +#define MB_STRLEN(s) (STRLEN(s)) + +#define MBLEN(s, n) 1 +#define MBRLEN(s, n, p) 1 + +#ifndef wchar_t +# define wchar_t int +#endif + +#define UTF8_SINGLEBYTE(c) (1) +#define UTF8_MBFIRSTCHAR(c) (0) + +#endif /* !HANDLE_MULTIBYTE */ + +/* Declare and initialize a multibyte state. Call must be terminated + with `;'. */ +#if defined (HANDLE_MULTIBYTE) +# define DECLARE_MBSTATE \ + mbstate_t state; \ + memset (&state, '\0', sizeof (mbstate_t)) +#else +# define DECLARE_MBSTATE +#endif /* !HANDLE_MULTIBYTE */ + +/* Initialize or reinitialize a multibyte state named `state'. Call must be + terminated with `;'. */ +#if defined (HANDLE_MULTIBYTE) +# define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t)) +#else +# define INITIALIZE_MBSTATE +#endif /* !HANDLE_MULTIBYTE */ + +/* Advance one (possibly multi-byte) character in string _STR of length + _STRSIZE, starting at index _I. STATE must have already been declared. */ +#if defined (HANDLE_MULTIBYTE) +# define ADVANCE_CHAR(_str, _strsize, _i) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _f; \ +\ + _f = is_basic ((_str)[_i]); \ + if (_f) \ + mblength = 1; \ + else if (locale_utf8locale && (((_str)[_i] & 0x80) == 0)) \ + mblength = (_str)[_i] != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \ + } \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + (_i)++; \ + } \ + else if (mblength == 0) \ + (_i)++; \ + else \ + (_i) += mblength; \ + } \ + else \ + (_i)++; \ + } \ + while (0) +#else +# define ADVANCE_CHAR(_str, _strsize, _i) (_i)++ +#endif /* !HANDLE_MULTIBYTE */ + +/* Advance one (possibly multibyte) character in the string _STR of length + _STRSIZE. + SPECIAL: assume that _STR will be incremented by 1 after this call. */ +#if defined (HANDLE_MULTIBYTE) +# define ADVANCE_CHAR_P(_str, _strsize) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _f; \ +\ + _f = is_basic (*(_str)); \ + if (_f) \ + mblength = 1; \ + else if (locale_utf8locale && ((*(_str) & 0x80) == 0)) \ + mblength = *(_str) != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_str), (_strsize), &state); \ + } \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + (_str) += (mblength < 1) ? 0 : (mblength - 1); \ + } \ + } \ + while (0) +#else +# define ADVANCE_CHAR_P(_str, _strsize) +#endif /* !HANDLE_MULTIBYTE */ + +/* Back up one (possibly multi-byte) character in string _STR of length + _STRSIZE, starting at index _I. STATE must have already been declared. */ +#if defined (HANDLE_MULTIBYTE) +# define BACKUP_CHAR(_str, _strsize, _i) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _x, _p; /* _x == temp index into string, _p == prev index */ \ +\ + _x = _p = 0; \ + while (_x < (_i)) \ + { \ + state_bak = state; \ + mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + _x++; \ + } \ + else if (mblength == 0) \ + _x++; \ + else \ + { \ + _p = _x; /* _p == start of prev mbchar */ \ + _x += mblength; \ + } \ + } \ + (_i) = _p; \ + } \ + else \ + (_i)--; \ + } \ + while (0) +#else +# define BACKUP_CHAR(_str, _strsize, _i) (_i)-- +#endif /* !HANDLE_MULTIBYTE */ + +/* Back up one (possibly multibyte) character in the string _BASE of length + _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ). + SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */ +#if defined (HANDLE_MULTIBYTE) +# define BACKUP_CHAR_P(_base, _strsize, _str) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \ +\ + _x = _p = _base; \ + while (_x < (_str)) \ + { \ + state_bak = state; \ + mblength = mbrlen (_x, (_strsize) - _x, &state); \ +\ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + _x++; \ + } \ + else if (mblength == 0) \ + _x++; \ + else \ + { \ + _p = _x; /* _p == start of prev mbchar */ \ + _x += mblength; \ + } \ + } \ + (_str) = _p; \ + } \ + else \ + (_str)--; \ + } \ + while (0) +#else +# define BACKUP_CHAR_P(_base, _strsize, _str) (_str)-- +#endif /* !HANDLE_MULTIBYTE */ + +/* Copy a single character from the string _SRC to the string _DST. + _SRCEND is a pointer to the end of _SRC. */ +#if defined (HANDLE_MULTIBYTE) +# define COPY_CHAR_P(_dst, _src, _srcend) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _k; \ +\ + _k = is_basic (*(_src)); \ + if (_k) \ + mblength = 1; \ + else if (locale_utf8locale && ((*(_src) & 0x80) == 0)) \ + mblength = *(_src) != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src), (_srcend) - (_src), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + for (_k = 0; _k < mblength; _k++) \ + *(_dst)++ = *(_src)++; \ + } \ + else \ + *(_dst)++ = *(_src)++; \ + } \ + while (0) +#else +# define COPY_CHAR_P(_dst, _src, _srcend) *(_dst)++ = *(_src)++ +#endif /* !HANDLE_MULTIBYTE */ + +/* Copy a single character from the string _SRC at index _SI to the string + _DST at index _DI. _SRCEND is a pointer to the end of _SRC. */ +#if defined (HANDLE_MULTIBYTE) +# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _k; \ +\ + _k = is_basic (*((_src) + (_si))); \ + if (_k) \ + mblength = 1; \ + else \ + {\ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + for (_k = 0; _k < mblength; _k++) \ + _dst[_di++] = _src[_si++]; \ + } \ + else \ + _dst[_di++] = _src[_si++]; \ + } \ + while (0) +#else +# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) _dst[_di++] = _src[_si++] +#endif /* !HANDLE_MULTIBYTE */ + +/**************************************************************** + * * + * The following are only guaranteed to work in subst.c * + * * + ****************************************************************/ + +#if defined (HANDLE_MULTIBYTE) +# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _i; \ +\ + _i = is_basic (*((_src) + (_si))); \ + if (_i) \ + mblength = 1; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + temp = xmalloc (mblength + 2); \ + temp[0] = _escchar; \ + for (_i = 0; _i < mblength; _i++) \ + temp[_i + 1] = _src[_si++]; \ + temp[mblength + 1] = '\0'; \ +\ + goto add_string; \ + } \ + else \ + { \ + _dst[0] = _escchar; \ + _dst[1] = _sc; \ + } \ + } \ + while (0) +#else +# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \ + _dst[0] = _escchar; \ + _dst[1] = _sc +#endif /* !HANDLE_MULTIBYTE */ + +#if defined (HANDLE_MULTIBYTE) +# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + mbstate_t state_bak; \ + size_t mblength; \ + int _i; \ +\ + _i = is_basic (*((_src) + (_si))); \ + if (_i) \ + mblength = 1; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \ + } \ + if (mblength == (size_t)-2 || mblength == (size_t)-1) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + else \ + mblength = (mblength < 1) ? 1 : mblength; \ +\ + FASTCOPY(((_src) + (_si)), (_dst), mblength); \ +\ + (_dst) += mblength; \ + (_si) += mblength; \ + } \ + else \ + { \ + *(_dst)++ = _src[(_si)]; \ + (_si)++; \ + } \ + } \ + while (0) +#else +# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \ + *(_dst)++ = _src[(_si)]; \ + (_si)++ +#endif /* !HANDLE_MULTIBYTE */ + +#if HANDLE_MULTIBYTE +# define SADD_MBCHAR(_dst, _src, _si, _srcsize) \ + do \ + { \ + if (locale_mb_cur_max > 1) \ + { \ + int i; \ + mbstate_t state_bak; \ + size_t mblength; \ +\ + i = is_basic (*((_src) + (_si))); \ + if (i) \ + mblength = 1; \ + else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ + mblength = (_src)[_si] != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ + } \ + if (mblength == (size_t)-1 || mblength == (size_t)-2) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + if (mblength < 1) \ + mblength = 1; \ +\ + _dst = (char *)xmalloc (mblength + 1); \ + for (i = 0; i < mblength; i++) \ + (_dst)[i] = (_src)[(_si)++]; \ + (_dst)[mblength] = '\0'; \ +\ + goto add_string; \ + } \ + } \ + while (0) + +#else +# define SADD_MBCHAR(_dst, _src, _si, _srcsize) +#endif + +/* Watch out when using this -- it's just straight textual substitution */ +#if defined (HANDLE_MULTIBYTE) +# define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \ +\ + int i; \ + mbstate_t state_bak; \ + size_t mblength; \ +\ + i = is_basic (*((_src) + (_si))); \ + if (i) \ + mblength = 1; \ + else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ + mblength = (_src)[_si] != 0; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ + } \ + if (mblength == (size_t)-1 || mblength == (size_t)-2) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + if (mblength < 1) \ + mblength = 1; \ +\ + (_dst) = (char *)xmalloc (mblength + 2); \ + (_dst)[0] = CTLESC; \ + for (i = 0; i < mblength; i++) \ + (_dst)[i+1] = (_src)[(_si)++]; \ + (_dst)[mblength+1] = '\0'; \ +\ + goto add_string + +# define SADD_MBCHAR_BODY(_dst, _src, _si, _srcsize) \ +\ + int i; \ + mbstate_t state_bak; \ + size_t mblength; \ +\ + i = is_basic (*((_src) + (_si))); \ + if (i) \ + mblength = 1; \ + else \ + { \ + state_bak = state; \ + mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ + } \ + if (mblength == (size_t)-1 || mblength == (size_t)-2) \ + { \ + state = state_bak; \ + mblength = 1; \ + } \ + if (mblength < 1) \ + mblength = 1; \ +\ + (_dst) = (char *)xmalloc (mblength + 1); \ + for (i = 0; i < mblength; i++) \ + (_dst)[i+1] = (_src)[(_si)++]; \ + (_dst)[mblength+1] = '\0'; \ +\ + goto add_string + +#endif /* HANDLE_MULTIBYTE */ +#endif /* _SH_MBUTIL_H_ */ diff --git a/utshell-0.5.0/variable/sig.h b/utshell-0.5.0/variable/sig.h new file mode 100644 index 00000000..4f90a889 --- /dev/null +++ b/utshell-0.5.0/variable/sig.h @@ -0,0 +1,141 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* sig.h -- header file for signal handler definitions. */ + +/* Copyright (C) 1994-2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* Make sure that this is included *after* config.h! */ + +#if !defined (_SIG_H_) +# define _SIG_H_ + +#include "stdc.h" + +#include /* for sig_atomic_t */ + +#if !defined (SIGABRT) && defined (SIGIOT) +# define SIGABRT SIGIOT +#endif + +#define sighandler RETSIGTYPE +typedef RETSIGTYPE SigHandler PARAMS((int)); + +#if defined (VOID_SIGHANDLER) +# define SIGRETURN(n) return +#else +# define SIGRETURN(n) return(n) +#endif /* !VOID_SIGHANDLER */ + +/* Here is a definition for set_signal_handler () which simply expands to + a call to signal () for non-Posix systems. The code for set_signal_handler + in the Posix case resides in general.c. */ +#if !defined (HAVE_POSIX_SIGNALS) +# define set_signal_handler(sig, handler) (SigHandler *)signal (sig, handler) +#else +extern SigHandler *set_signal_handler PARAMS((int, SigHandler *)); /* in sig.c */ +#endif /* _POSIX_VERSION */ + +#if !defined (SIGCHLD) && defined (SIGCLD) +# define SIGCHLD SIGCLD +#endif + +#if !defined (HAVE_POSIX_SIGNALS) && !defined (sigmask) +# define sigmask(x) (1 << ((x)-1)) +#endif /* !HAVE_POSIX_SIGNALS && !sigmask */ + +#if !defined (HAVE_POSIX_SIGNALS) +# if !defined (SIG_BLOCK) +# define SIG_BLOCK 2 +# define SIG_SETMASK 3 +# endif /* SIG_BLOCK */ + +/* sigset_t defined in config.h */ + +/* Make sure there is nothing inside the signal set. */ +# define sigemptyset(set) (*(set) = 0) + +/* Initialize the signal set to hold all signals. */ +# define sigfillset(set) (*set) = sigmask (NSIG) - 1 + +/* Add SIG to the contents of SET. */ +# define sigaddset(set, sig) *(set) |= sigmask (sig) + +/* Delete SIG from signal set SET. */ +# define sigdelset(set, sig) *(set) &= ~sigmask (sig) + +/* Is SIG a member of the signal set SET? */ +# define sigismember(set, sig) ((*(set) & sigmask (sig)) != 0) + +/* Suspend the process until the reception of one of the signals + not present in SET. */ +# define sigsuspend(set) sigpause (*(set)) +#endif /* !HAVE_POSIX_SIGNALS */ + +/* These definitions are used both in POSIX and non-POSIX implementations. */ + +#define BLOCK_SIGNAL(sig, nvar, ovar) \ +do { \ + sigemptyset (&nvar); \ + sigaddset (&nvar, sig); \ + sigemptyset (&ovar); \ + sigprocmask (SIG_BLOCK, &nvar, &ovar); \ +} while (0) + +#define UNBLOCK_SIGNAL(ovar) sigprocmask (SIG_SETMASK, &ovar, (sigset_t *) NULL) + +#if defined (HAVE_POSIX_SIGNALS) +# define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar) +# define UNBLOCK_CHILD(ovar) UNBLOCK_SIGNAL(ovar) +#else /* !HAVE_POSIX_SIGNALS */ +# define BLOCK_CHILD(nvar, ovar) ovar = sigblock (sigmask (SIGCHLD)) +# define UNBLOCK_CHILD(ovar) sigsetmask (ovar) +#endif /* !HAVE_POSIX_SIGNALS */ + +/* Extern variables */ +extern volatile sig_atomic_t sigwinch_received; +extern volatile sig_atomic_t sigterm_received; + +extern int interrupt_immediately; /* no longer used */ +extern int terminate_immediately; + +/* Functions from sig.c. */ +extern sighandler termsig_sighandler PARAMS((int)); +extern void termsig_handler PARAMS((int)); +extern sighandler sigint_sighandler PARAMS((int)); +extern void initialize_signals PARAMS((int)); +extern void initialize_terminating_signals PARAMS((void)); +extern void reset_terminating_signals PARAMS((void)); +extern void top_level_cleanup PARAMS((void)); +extern void throw_to_top_level PARAMS((void)); +extern void jump_to_top_level PARAMS((int)) __attribute__((__noreturn__)); +extern void restore_sigmask PARAMS((void)); + +extern sighandler sigwinch_sighandler PARAMS((int)); +extern void set_sigwinch_handler PARAMS((void)); +extern void unset_sigwinch_handler PARAMS((void)); + +extern sighandler sigterm_sighandler PARAMS((int)); + +/* Functions defined in trap.c. */ +extern SigHandler *set_sigint_handler PARAMS((void)); +extern SigHandler *trap_to_sighandler PARAMS((int)); +extern sighandler trap_handler PARAMS((int)); + +extern int block_trapped_signals PARAMS((sigset_t *, sigset_t *)); +extern int unblock_trapped_signals PARAMS((sigset_t *)); +#endif /* _SIG_H_ */ diff --git a/utshell-0.5.0/variable/siglist.h b/utshell-0.5.0/variable/siglist.h new file mode 100644 index 00000000..6d04ae84 --- /dev/null +++ b/utshell-0.5.0/variable/siglist.h @@ -0,0 +1,45 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* siglist.h -- encapsulate various definitions for sys_siglist */ + +/* Copyright (C) 1993, 2001, 2005, 2008-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_SIGLIST_H_) +#define _SIGLIST_H_ + +#if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_STRSIGNAL) + +#if defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_SYS_SIGLIST) && !defined (sys_siglist) +# define sys_siglist _sys_siglist +#endif /* HAVE_UNDER_SYS_SIGLIST && !HAVE_SYS_SIGLIST && !sys_siglist */ + +#if !defined (sys_siglist) +extern char *sys_siglist[]; +#endif /* !sys_siglist */ + +#endif /* !SYS_SIGLIST_DECLARED && !HAVE_STRSIGNAL */ + +#if !defined (strsignal) && !defined (HAVE_STRSIGNAL) +# define strsignal(sig) (char *)sys_siglist[sig] +#endif /* !strsignal && !HAVE_STRSIGNAL */ + +#if !defined (strsignal) && !HAVE_DECL_STRSIGNAL +extern char *strsignal PARAMS((int)); +#endif + +#endif /* _SIGLIST_H */ diff --git a/utshell-0.5.0/variable/stdc.h b/utshell-0.5.0/variable/stdc.h new file mode 100644 index 00000000..7b9282cc --- /dev/null +++ b/utshell-0.5.0/variable/stdc.h @@ -0,0 +1,89 @@ +/* stdc.h -- macros to make source compile on both ANSI C and K&R C + compilers. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_STDC_H_) +#define _STDC_H_ + +/* Adapted from BSD /usr/include/sys/cdefs.h. */ + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +/* Fortify, at least, has trouble with this definition */ +#if defined (HAVE_STRINGIZE) +# define CPP_STRING(x) #x +#else +# define CPP_STRING(x) "x" +#endif + +#if !defined (__STDC__) + +#if defined (__GNUC__) /* gcc with -traditional */ +# if !defined (signed) +# define signed __signed +# endif +# if !defined (volatile) +# define volatile __volatile +# endif +#else /* !__GNUC__ */ +# if !defined (inline) +# define inline +# endif +# if !defined (signed) +# define signed +# endif +# if !defined (volatile) +# define volatile +# endif +#endif /* !__GNUC__ */ + +#endif /* !__STDC__ */ + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(x) +# endif +#endif + +/* For those situations when gcc handles inlining a particular function but + other compilers complain. */ +#ifdef __GNUC__ +# define INLINE inline +#else +# define INLINE +#endif + +#if defined (PREFER_STDARG) +# define SH_VA_START(va, arg) va_start(va, arg) +#else +# define SH_VA_START(va, arg) va_start(va) +#endif + +#endif /* !_STDC_H_ */ diff --git a/utshell-0.5.0/variable/strmatch.h b/utshell-0.5.0/variable/strmatch.h new file mode 100644 index 00000000..0d7e00de --- /dev/null +++ b/utshell-0.5.0/variable/strmatch.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne-Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _STRMATCH_H +#define _STRMATCH_H 1 + +#include "config.h" + +#include "stdc.h" + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `strmatch'. */ + +/* standard flags are like fnmatch(3). */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +/* extended flags not available in most libc fnmatch versions, but we undef + them to avoid any possible warnings. */ +#undef FNM_LEADING_DIR +#undef FNM_CASEFOLD +#undef FNM_EXTMATCH + +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ + +#define FNM_FIRSTCHAR (1 << 6) /* Match only the first character */ + +/* Value returned by `strmatch' if STRING does not match PATTERN. */ +#undef FNM_NOMATCH + +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int strmatch PARAMS((char *, char *, int)); + +#if HANDLE_MULTIBYTE +extern int wcsmatch PARAMS((wchar_t *, wchar_t *, int)); +#endif + +#endif /* _STRMATCH_H */ diff --git a/utshell-0.5.0/variable/subst.h b/utshell-0.5.0/variable/subst.h new file mode 100644 index 00000000..838ee1e6 --- /dev/null +++ b/utshell-0.5.0/variable/subst.h @@ -0,0 +1,355 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* subst.h -- Names of externally visible functions in subst.c. */ + +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_SUBST_H_) +#define _SUBST_H_ + +#include "stdc.h" + +/* Constants which specify how to handle backslashes and quoting in + expand_word_internal (). Q_DOUBLE_QUOTES means to use the function + slashify_in_quotes () to decide whether the backslash should be + retained. Q_HERE_DOCUMENT means slashify_in_here_document () to + decide whether to retain the backslash. Q_KEEP_BACKSLASH means + to unconditionally retain the backslash. Q_PATQUOTE means that we're + expanding a pattern ${var%#[#%]pattern} in an expansion surrounded + by double quotes. Q_DOLBRACE means we are expanding a ${...} word, so + backslashes should also escape { and } and be removed. */ +#define Q_DOUBLE_QUOTES 0x001 +#define Q_HERE_DOCUMENT 0x002 +#define Q_KEEP_BACKSLASH 0x004 +#define Q_PATQUOTE 0x008 +#define Q_QUOTED 0x010 +#define Q_ADDEDQUOTES 0x020 +#define Q_QUOTEDNULL 0x040 +#define Q_DOLBRACE 0x080 +#define Q_ARITH 0x100 /* expanding string for arithmetic evaluation */ +#define Q_ARRAYSUB 0x200 /* expanding indexed array subscript */ + +/* Flag values controlling how assignment statements are treated. */ +#define ASS_APPEND 0x0001 +#define ASS_MKLOCAL 0x0002 +#define ASS_MKASSOC 0x0004 +#define ASS_MKGLOBAL 0x0008 /* force global assignment */ +#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */ +#define ASS_FORCE 0x0020 /* force assignment even to readonly variable */ +#define ASS_CHKLOCAL 0x0040 /* check local variable before assignment */ +#define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */ +#define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */ +#define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */ +#define ASS_NOINVIS 0x0400 /* don't resolve local invisible variables */ + +/* Flags for the string extraction functions. */ +#define SX_NOALLOC 0x0001 /* just skip; don't return substring */ +#define SX_VARNAME 0x0002 /* variable name; for string_extract () */ +#define SX_REQMATCH 0x0004 /* closing/matching delimiter required */ +#define SX_COMMAND 0x0008 /* extracting a shell script/command */ +#define SX_NOCTLESC 0x0010 /* don't honor CTLESC quoting */ +#define SX_NOESCCTLNUL 0x0020 /* don't let CTLESC quote CTLNUL */ +#define SX_NOLONGJMP 0x0040 /* don't longjmp on fatal error */ +#define SX_ARITHSUB 0x0080 /* extracting $(( ... )) (currently unused) */ +#define SX_POSIXEXP 0x0100 /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */ +#define SX_WORD 0x0200 /* extracting word in ${param op word} */ +#define SX_COMPLETE 0x0400 /* extracting word for completion */ +#define SX_STRIPDQ 0x0800 /* strip double quotes when extracting double-quoted string */ + +/* Remove backslashes which are quoting backquotes from STRING. Modifies + STRING, and returns a pointer to it. */ +extern char * de_backslash PARAMS((char *)); + +/* Replace instances of \! in a string with !. */ +extern void unquote_bang PARAMS((char *)); + +/* Extract the $( construct in STRING, and return a new string. + Start extracting at (SINDEX) as if we had just seen "$(". + Make (SINDEX) get the position just after the matching ")". + XFLAGS is additional flags to pass to other extraction functions, */ +extern char *extract_command_subst PARAMS((char *, int *, int)); + +/* Extract the $[ construct in STRING, and return a new string. + Start extracting at (SINDEX) as if we had just seen "$[". + Make (SINDEX) get the position just after the matching "]". */ +extern char *extract_arithmetic_subst PARAMS((char *, int *)); + +#if defined (PROCESS_SUBSTITUTION) +/* Extract the <( or >( construct in STRING, and return a new string. + Start extracting at (SINDEX) as if we had just seen "<(". + Make (SINDEX) get the position just after the matching ")". */ +extern char *extract_process_subst PARAMS((char *, char *, int *, int)); +#endif /* PROCESS_SUBSTITUTION */ + +/* Extract the name of the variable to bind to from the assignment string. */ +extern char *assignment_name PARAMS((char *)); + +/* Return a single string of all the words present in LIST, separating + each word with SEP. */ +extern char *string_list_internal PARAMS((WORD_LIST *, char *)); + +/* Return a single string of all the words present in LIST, separating + each word with a space. */ +extern char *string_list PARAMS((WORD_LIST *)); + +/* Turn $* into a single string, obeying POSIX rules. */ +extern char *string_list_dollar_star PARAMS((WORD_LIST *, int, int)); + +/* Expand $@ into a single string, obeying POSIX rules. */ +extern char *string_list_dollar_at PARAMS((WORD_LIST *, int, int)); + +/* Turn the positional parameters into a string, understanding quoting and + the various subtleties of using the first character of $IFS as the + separator. Calls string_list_dollar_at, string_list_dollar_star, and + string_list as appropriate. */ +extern char *string_list_pos_params PARAMS((int, WORD_LIST *, int, int)); + +/* Perform quoted null character removal on each element of LIST. + This modifies LIST. */ +extern void word_list_remove_quoted_nulls PARAMS((WORD_LIST *)); + +/* This performs word splitting and quoted null character removal on + STRING. */ +extern WORD_LIST *list_string PARAMS((char *, char *, int)); + +extern char *ifs_firstchar PARAMS((int *)); +extern char *get_word_from_string PARAMS((char **, char *, char **)); +extern char *strip_trailing_ifs_whitespace PARAMS((char *, char *, int)); + +/* Given STRING, an assignment string, get the value of the right side + of the `=', and bind it to the left side. If EXPAND is true, then + perform tilde expansion, parameter expansion, command substitution, + and arithmetic expansion on the right-hand side. Do not perform word + splitting on the result of expansion. */ +extern int do_assignment PARAMS((char *)); +extern int do_assignment_no_expand PARAMS((char *)); +extern int do_word_assignment PARAMS((WORD_DESC *, int)); + +/* Append SOURCE to TARGET at INDEX. SIZE is the current amount + of space allocated to TARGET. SOURCE can be NULL, in which + case nothing happens. Gets rid of SOURCE by free ()ing it. + Returns TARGET in case the location has changed. */ +extern char *sub_append_string PARAMS((char *, char *, int *, size_t *)); + +/* Append the textual representation of NUMBER to TARGET. + INDEX and SIZE are as in SUB_APPEND_STRING. */ +extern char *sub_append_number PARAMS((intmax_t, char *, int *, int *)); + +/* Return the word list that corresponds to `$*'. */ +extern WORD_LIST *list_rest_of_args PARAMS((void)); + +/* Make a single large string out of the dollar digit variables, + and the rest_of_args. If DOLLAR_STAR is 1, then obey the special + case of "$*" with respect to IFS. */ +extern char *string_rest_of_args PARAMS((int)); + +/* Expand STRING by performing parameter expansion, command substitution, + and arithmetic expansion. Dequote the resulting WORD_LIST before + returning it, but do not perform word splitting. The call to + remove_quoted_nulls () is made here because word splitting normally + takes care of quote removal. */ +extern WORD_LIST *expand_string_unsplit PARAMS((char *, int)); + +/* Expand the rhs of an assignment statement. */ +extern WORD_LIST *expand_string_assignment PARAMS((char *, int)); + +/* Expand a prompt string. */ +extern WORD_LIST *expand_prompt_string PARAMS((char *, int, int)); + +/* Expand STRING just as if you were expanding a word. This also returns + a list of words. Note that filename globbing is *NOT* done for word + or string expansion, just when the shell is expanding a command. This + does parameter expansion, command substitution, arithmetic expansion, + and word splitting. Dequote the resultant WORD_LIST before returning. */ +extern WORD_LIST *expand_string PARAMS((char *, int)); + +/* Convenience functions that expand strings to strings, taking care of + converting the WORD_LIST * returned by the expand_string* functions + to a string and deallocating the WORD_LIST *. */ +extern char *expand_string_to_string PARAMS((char *, int)); +extern char *expand_string_unsplit_to_string PARAMS((char *, int)); +extern char *expand_assignment_string_to_string PARAMS((char *, int)); + +/* Expand an arithmetic expression string */ +extern char *expand_arith_string PARAMS((char *, int)); + +/* De-quote quoted characters in STRING. */ +extern char *dequote_string PARAMS((char *)); + +/* De-quote CTLESC-escaped CTLESC or CTLNUL characters in STRING. */ +extern char *dequote_escapes PARAMS((const char *)); + +extern WORD_DESC *dequote_word PARAMS((WORD_DESC *)); + +/* De-quote quoted characters in each word in LIST. */ +extern WORD_LIST *dequote_list PARAMS((WORD_LIST *)); + +/* Expand WORD, performing word splitting on the result. This does + parameter expansion, command substitution, arithmetic expansion, + word splitting, and quote removal. */ +extern WORD_LIST *expand_word PARAMS((WORD_DESC *, int)); + +/* Expand WORD, but do not perform word splitting on the result. This + does parameter expansion, command substitution, arithmetic expansion, + and quote removal. */ +extern WORD_LIST *expand_word_unsplit PARAMS((WORD_DESC *, int)); +extern WORD_LIST *expand_word_leave_quoted PARAMS((WORD_DESC *, int)); + +/* Return the value of a positional parameter. This handles values > 10. */ +extern char *get_dollar_var_value PARAMS((intmax_t)); + +/* Quote a string to protect it from word splitting. */ +extern char *quote_string PARAMS((char *)); + +/* Quote escape characters (characters special to internals of expansion) + in a string. */ +extern char *quote_escapes PARAMS((const char *)); + +/* And remove such quoted special characters. */ +extern char *remove_quoted_escapes PARAMS((char *)); + +/* Remove CTLNUL characters from STRING unless they are quoted with CTLESC. */ +extern char *remove_quoted_nulls PARAMS((char *)); + +/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the + backslash quoting rules for within double quotes. */ +extern char *string_quote_removal PARAMS((char *, int)); + +/* Perform quote removal on word WORD. This allocates and returns a new + WORD_DESC *. */ +extern WORD_DESC *word_quote_removal PARAMS((WORD_DESC *, int)); + +/* Perform quote removal on all words in LIST. If QUOTED is non-zero, + the members of the list are treated as if they are surrounded by + double quotes. Return a new list, or NULL if LIST is NULL. */ +extern WORD_LIST *word_list_quote_removal PARAMS((WORD_LIST *, int)); + +/* Called when IFS is changed to maintain some private variables. */ +extern void setifs PARAMS((SHELL_VAR *)); + +/* Return the value of $IFS, or " \t\n" if IFS is unset. */ +extern char *getifs PARAMS((void)); + +/* This splits a single word into a WORD LIST on $IFS, but only if the word + is not quoted. list_string () performs quote removal for us, even if we + don't do any splitting. */ +extern WORD_LIST *word_split PARAMS((WORD_DESC *, char *)); + +/* Take the list of words in LIST and do the various substitutions. Return + a new list of words which is the expanded list, and without things like + variable assignments. */ +extern WORD_LIST *expand_words PARAMS((WORD_LIST *)); + +/* Same as expand_words (), but doesn't hack variable or environment + variables. */ +extern WORD_LIST *expand_words_no_vars PARAMS((WORD_LIST *)); + +/* Perform the `normal shell expansions' on a WORD_LIST. These are + brace expansion, tilde expansion, parameter and variable substitution, + command substitution, arithmetic expansion, and word splitting. */ +extern WORD_LIST *expand_words_shellexp PARAMS((WORD_LIST *)); + +extern WORD_DESC *command_substitute PARAMS((char *, int, int)); +extern char *pat_subst PARAMS((char *, char *, char *, int)); + +#if defined (PROCESS_SUBSTITUTION) +extern int fifos_pending PARAMS((void)); +extern int num_fifos PARAMS((void)); +extern void unlink_fifo_list PARAMS((void)); +extern void unlink_all_fifos PARAMS((void)); +extern void unlink_fifo PARAMS((int)); + +extern void *copy_fifo_list PARAMS((int *)); +extern void close_new_fifos PARAMS((void *, int)); + +extern void clear_fifo_list PARAMS((void)); + +extern int find_procsub_child PARAMS((pid_t)); +extern void set_procsub_status PARAMS((int, pid_t, int)); + +extern void wait_procsubs PARAMS((void)); +extern void reap_procsubs PARAMS((void)); +#endif + +extern WORD_LIST *list_string_with_quotes PARAMS((char *)); + +#if defined (ARRAY_VARS) +extern char *extract_array_assignment_list PARAMS((char *, int *)); +#endif + +#if defined (COND_COMMAND) +extern char *remove_backslashes PARAMS((char *)); +extern char *cond_expand_word PARAMS((WORD_DESC *, int)); +#endif + +/* Flags for skip_to_delim */ +#define SD_NOJMP 0x001 /* don't longjmp on fatal error. */ +#define SD_INVERT 0x002 /* look for chars NOT in passed set */ +#define SD_NOQUOTEDELIM 0x004 /* don't let single or double quotes act as delimiters */ +#define SD_NOSKIPCMD 0x008 /* don't skip over $(, <(, or >( command/process substitution; parse them as commands */ +#define SD_EXTGLOB 0x010 /* skip over extended globbing patterns if appropriate */ +#define SD_IGNOREQUOTE 0x020 /* single and double quotes are not special */ +#define SD_GLOB 0x040 /* skip over glob patterns like bracket expressions */ +#define SD_NOPROCSUB 0x080 /* don't parse process substitutions as commands */ +#define SD_COMPLETE 0x100 /* skip_to_delim during completion */ +#define SD_HISTEXP 0x200 /* skip_to_delim during history expansion */ +#define SD_ARITHEXP 0x400 /* skip_to_delim during arithmetic expansion */ + +extern int skip_to_delim PARAMS((char *, int, char *, int)); + +#if defined (BANG_HISTORY) +extern int skip_to_histexp PARAMS((char *, int, char *, int)); +#endif + +#if defined (READLINE) +extern int char_is_quoted PARAMS((char *, int)); +extern int unclosed_pair PARAMS((char *, int, char *)); +extern WORD_LIST *split_at_delims PARAMS((char *, int, char *, int, int, int *, int *)); +#endif + +/* Variables used to keep track of the characters in IFS. */ +extern SHELL_VAR *ifs_var; +extern char *ifs_value; +extern unsigned char ifs_cmap[]; +extern int ifs_is_set, ifs_is_null; + +#if defined (HANDLE_MULTIBYTE) +extern unsigned char ifs_firstc[]; +extern size_t ifs_firstc_len; +#else +extern unsigned char ifs_firstc; +#endif + +extern int assigning_in_environment; +extern int expanding_redir; +extern int inherit_errexit; + +extern pid_t last_command_subst_pid; + +/* Evaluates to 1 if C is a character in $IFS. */ +#define isifs(c) (ifs_cmap[(unsigned char)(c)] != 0) + +/* How to determine the quoted state of the character C. */ +#define QUOTED_CHAR(c) ((c) == CTLESC) + +/* Is the first character of STRING a quoted NULL character? */ +#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0') + +extern void invalidate_cached_quoted_dollar_at PARAMS((void)); + +#endif /* !_SUBST_H_ */ diff --git a/utshell-0.5.0/variable/syntax.h b/utshell-0.5.0/variable/syntax.h new file mode 100644 index 00000000..5d9eedd0 --- /dev/null +++ b/utshell-0.5.0/variable/syntax.h @@ -0,0 +1,107 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* syntax.h -- Syntax definitions for the shell */ + +/* Copyright (C) 2000, 2001, 2005, 2008, 2009-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _SYNTAX_H_ +#define _SYNTAX_H_ + +/* Defines for use by mksyntax.c */ + +#define slashify_in_quotes "\\`$\"\n" +#define slashify_in_here_document "\\`$" + +#define shell_meta_chars "()<>;&|" +#define shell_break_chars "()<>;&| \t\n" + +#define shell_quote_chars "\"`'" + +#if defined (PROCESS_SUBSTITUTION) +# define shell_exp_chars "$<>" +#else +# define shell_exp_chars "$" +#endif + +#if defined (EXTENDED_GLOB) +# define ext_glob_chars "@*+?!" +#else +# define ext_glob_chars "" +#endif +#define shell_glob_chars "*?[]^" + +/* Defines shared by mksyntax.c and the rest of the shell code. */ + +/* Values for character flags in syntax tables */ + +#define CWORD 0x0000 /* nothing special; an ordinary character */ +#define CSHMETA 0x0001 /* shell meta character */ +#define CSHBRK 0x0002 /* shell break character */ +#define CBACKQ 0x0004 /* back quote */ +#define CQUOTE 0x0008 /* shell quote character */ +#define CSPECL 0x0010 /* special character that needs quoting */ +#define CEXP 0x0020 /* shell expansion character */ +#define CBSDQUOTE 0x0040 /* characters escaped by backslash in double quotes */ +#define CBSHDOC 0x0080 /* characters escaped by backslash in here doc */ +#define CGLOB 0x0100 /* globbing characters */ +#define CXGLOB 0x0200 /* extended globbing characters */ +#define CXQUOTE 0x0400 /* cquote + backslash */ +#define CSPECVAR 0x0800 /* single-character shell variable name */ +#define CSUBSTOP 0x1000 /* values of OP for ${word[:]OPstuff} */ +#define CBLANK 0x2000 /* whitespace (blank) character */ + +/* Defines for use by the rest of the shell. */ +extern int sh_syntaxtab[]; +extern int sh_syntabsiz; + +#define shellmeta(c) (sh_syntaxtab[(unsigned char)(c)] & CSHMETA) +#define shellbreak(c) (sh_syntaxtab[(unsigned char)(c)] & CSHBRK) +#define shellquote(c) (sh_syntaxtab[(unsigned char)(c)] & CQUOTE) +#define shellxquote(c) (sh_syntaxtab[(unsigned char)(c)] & CXQUOTE) + +#define shellblank(c) (sh_syntaxtab[(unsigned char)(c)] & CBLANK) + +#define parserblank(c) ((c) == ' ' || (c) == '\t') + +#define issyntype(c, t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) != 0) +#define notsyntype(c,t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) == 0) + +#if defined (PROCESS_SUBSTITUTION) +# define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>') +#else +# define shellexp(c) ((c) == '$') +#endif + +#if defined (EXTENDED_GLOB) +# define PATTERN_CHAR(c) \ + ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!') +#else +# define PATTERN_CHAR(c) 0 +#endif + +#define GLOB_CHAR(c) \ + ((c) == '*' || (c) == '?' || (c) == '[' || (c) == ']' || (c) == '^') + +#define CTLESC '\001' +#define CTLNUL '\177' + +#if !defined (HAVE_ISBLANK) && !defined (isblank) +# define isblank(x) ((x) == ' ' || (x) == '\t') +#endif + +#endif /* _SYNTAX_H_ */ diff --git a/utshell-0.5.0/variable/tilde.h b/utshell-0.5.0/variable/tilde.h new file mode 100644 index 00000000..e26dd047 --- /dev/null +++ b/utshell-0.5.0/variable/tilde.h @@ -0,0 +1,80 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992-2009 Free Software Foundation, Inc. + + This file contains the Readline Library (Readline), a set of + routines for providing Emacs style line input to programs that ask + for it. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +/* Find the portion of the string beginning with ~ that should be expanded. */ +extern char *tilde_find_word PARAMS((const char *, int, int *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/utshell-0.5.0/variable/trap.h b/utshell-0.5.0/variable/trap.h new file mode 100644 index 00000000..3ed96502 --- /dev/null +++ b/utshell-0.5.0/variable/trap.h @@ -0,0 +1,129 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* trap.h -- data structures used in the trap mechanism. */ + +/* Copyright (C) 1993-2013 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_TRAP_H_) +#define _TRAP_H_ + +#include "stdc.h" + +#if !defined (SIG_DFL) +#include "bashtypes.h" +#include +#endif /* SIG_DFL */ + +#if !defined (NSIG) +#define NSIG 64 +#endif /* !NSIG */ + +#define NO_SIG -1 +#define DEFAULT_SIG SIG_DFL +#define IGNORE_SIG SIG_IGN + +/* Special shell trap names. */ +#define DEBUG_TRAP NSIG +#define ERROR_TRAP NSIG+1 +#define RETURN_TRAP NSIG+2 +#define EXIT_TRAP 0 + +/* system signals plus special bash traps */ +#define BASH_NSIG NSIG+3 + +/* Flags values for decode_signal() */ +#define DSIG_SIGPREFIX 0x01 /* don't allow `SIG' PREFIX */ +#define DSIG_NOCASE 0x02 /* case-insensitive comparison */ + +/* A value which can never be the target of a trap handler. */ +#define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps + +#define signal_object_p(x,f) (decode_signal (x,f) != NO_SIG) + +#define TRAP_STRING(s) \ + (signal_is_trapped (s) && signal_is_ignored (s) == 0) ? trap_list[s] \ + : (char *)NULL + +extern char *trap_list[]; + +extern int trapped_signal_received; +extern int wait_signal_received; +extern int running_trap; +extern int trap_saved_exit_value; +extern int suppress_debug_trap_verbose; + +/* Externally-visible functions declared in trap.c. */ +extern void initialize_traps PARAMS((void)); + +extern void run_pending_traps PARAMS((void)); + +extern void queue_sigchld_trap PARAMS((int)); +extern void maybe_set_sigchld_trap PARAMS((char *)); +extern void set_impossible_sigchld_trap PARAMS((void)); +extern void set_sigchld_trap PARAMS((char *)); + +extern void set_debug_trap PARAMS((char *)); +extern void set_error_trap PARAMS((char *)); +extern void set_return_trap PARAMS((char *)); + +extern void maybe_set_debug_trap PARAMS((char *)); +extern void maybe_set_error_trap PARAMS((char *)); +extern void maybe_set_return_trap PARAMS((char *)); + +extern void set_sigint_trap PARAMS((char *)); +extern void set_signal PARAMS((int, char *)); + +extern void restore_default_signal PARAMS((int)); +extern void ignore_signal PARAMS((int)); +extern int run_exit_trap PARAMS((void)); +extern void run_trap_cleanup PARAMS((int)); +extern int run_debug_trap PARAMS((void)); +extern void run_error_trap PARAMS((void)); +extern void run_return_trap PARAMS((void)); + +extern void free_trap_strings PARAMS((void)); +extern void reset_signal_handlers PARAMS((void)); +extern void restore_original_signals PARAMS((void)); + +extern void get_original_signal PARAMS((int)); +extern void get_all_original_signals PARAMS((void)); + +extern char *signal_name PARAMS((int)); + +extern int decode_signal PARAMS((char *, int)); +extern void run_interrupt_trap PARAMS((int)); +extern int maybe_call_trap_handler PARAMS((int)); +extern int signal_is_special PARAMS((int)); +extern int signal_is_trapped PARAMS((int)); +extern int signal_is_pending PARAMS((int)); +extern int signal_is_ignored PARAMS((int)); +extern int signal_is_hard_ignored PARAMS((int)); +extern void set_signal_hard_ignored PARAMS((int)); +extern void set_signal_ignored PARAMS((int)); +extern int signal_in_progress PARAMS((int)); + +extern void set_trap_state PARAMS((int)); + +extern int next_pending_trap PARAMS((int)); +extern int first_pending_trap PARAMS((void)); +extern void clear_pending_traps PARAMS((void)); +extern int any_signals_trapped PARAMS((void)); +extern void check_signals PARAMS((void)); +extern void check_signals_and_traps PARAMS((void)); + +#endif /* _TRAP_H_ */ diff --git a/utshell-0.5.0/variable/unwind_prot.h b/utshell-0.5.0/variable/unwind_prot.h new file mode 100644 index 00000000..db3e4eba --- /dev/null +++ b/utshell-0.5.0/variable/unwind_prot.h @@ -0,0 +1,53 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* unwind_prot.h - Macros and functions for hacking unwind protection. */ + +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_UNWIND_PROT_H) +#define _UNWIND_PROT_H + +extern void uwp_init PARAMS((void)); + +/* Run a function without interrupts. */ +extern void begin_unwind_frame PARAMS((char *)); +extern void discard_unwind_frame PARAMS((char *)); +extern void run_unwind_frame PARAMS((char *)); +extern void add_unwind_protect (); /* Not portable to arbitrary C99 hosts. */ +extern void remove_unwind_protect PARAMS((void)); +extern void run_unwind_protects PARAMS((void)); +extern void clear_unwind_protect_list PARAMS((int)); +extern int have_unwind_protects PARAMS((void)); +extern int unwind_protect_tag_on_stack PARAMS((const char *)); +extern void uwp_init PARAMS((void)); + +/* Define for people who like their code to look a certain way. */ +#define end_unwind_frame() + +/* How to protect a variable. */ +#define unwind_protect_var(X) unwind_protect_mem ((char *)&(X), sizeof (X)) +extern void unwind_protect_mem PARAMS((char *, int)); + +/* Backwards compatibility */ +#define unwind_protect_int unwind_protect_var +#define unwind_protect_short unwind_protect_var +#define unwind_protect_string unwind_protect_var +#define unwind_protect_pointer unwind_protect_var +#define unwind_protect_jmp_buf unwind_protect_var + +#endif /* _UNWIND_PROT_H */ diff --git a/utshell-0.5.0/variable/variables.h b/utshell-0.5.0/variable/variables.h new file mode 100644 index 00000000..d7074e40 --- /dev/null +++ b/utshell-0.5.0/variable/variables.h @@ -0,0 +1,459 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* variables.h -- data structures for shell variables. */ + +/* Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_VARIABLES_H_) +#define _VARIABLES_H_ + +#include "stdc.h" +#include "array.h" +#include "assoc.h" + +/* Shell variables and functions are stored in hash tables. */ +#include "hashlib.h" + +#include "conftypes.h" + +/* A variable context. */ +typedef struct var_context { + char *name; /* empty or NULL means global context */ + int scope; /* 0 means global context */ + int flags; + struct var_context *up; /* previous function calls */ + struct var_context *down; /* down towards global context */ + HASH_TABLE *table; /* variables at this scope */ +} VAR_CONTEXT; + +/* Flags for var_context->flags */ +#define VC_HASLOCAL 0x01 +#define VC_HASTMPVAR 0x02 +#define VC_FUNCENV 0x04 /* also function if name != NULL */ +#define VC_BLTNENV 0x08 /* builtin_env */ +#define VC_TEMPENV 0x10 /* temporary_env */ + +#define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV) + +/* Accessing macros */ +#define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0) +#define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0) +#define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV) + +#define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0) + +#define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0) +#define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0) + +/* What a shell variable looks like. */ + +typedef struct variable *sh_var_value_func_t PARAMS((struct variable *)); +typedef struct variable *sh_var_assign_func_t PARAMS((struct variable *, char *, arrayind_t, char *)); + +/* For the future */ +union _value { + char *s; /* string value */ + intmax_t i; /* int value */ + COMMAND *f; /* function */ + ARRAY *a; /* array */ + HASH_TABLE *h; /* associative array */ + double d; /* floating point number */ +#if defined (HAVE_LONG_DOUBLE) + long double ld; /* long double */ +#endif + struct variable *v; /* possible indirect variable use */ + void *opaque; /* opaque data for future use */ +}; + +typedef struct variable { + char *name; /* Symbol that the user types. */ + char *value; /* Value that is returned. */ + char *exportstr; /* String for the environment. */ + sh_var_value_func_t *dynamic_value; /* Function called to return a `dynamic' + value for a variable, like $SECONDS + or $RANDOM. */ + sh_var_assign_func_t *assign_func; /* Function called when this `special + variable' is assigned a value in + bind_variable. */ + int attributes; /* export, readonly, array, invisible... */ + int context; /* Which context this variable belongs to. */ +} SHELL_VAR; + +typedef struct _vlist { + SHELL_VAR **list; + size_t list_size; /* allocated size */ + size_t list_len; /* current number of entries */ +} VARLIST; + +/* The various attributes that a given variable can have. */ +/* First, the user-visible attributes */ +#define att_exported 0x0000001 /* export to environment */ +#define att_readonly 0x0000002 /* cannot change */ +#define att_array 0x0000004 /* value is an array */ +#define att_function 0x0000008 /* value is a function */ +#define att_integer 0x0000010 /* internal representation is int */ +#define att_local 0x0000020 /* variable is local to a function */ +#define att_assoc 0x0000040 /* variable is an associative array */ +#define att_trace 0x0000080 /* function is traced with DEBUG trap */ +#define att_uppercase 0x0000100 /* word converted to uppercase on assignment */ +#define att_lowercase 0x0000200 /* word converted to lowercase on assignment */ +#define att_capcase 0x0000400 /* word capitalized on assignment */ +#define att_nameref 0x0000800 /* word is a name reference */ + +#define user_attrs (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase|att_nameref) + +#define attmask_user 0x0000fff + +/* Internal attributes used for bookkeeping */ +#define att_invisible 0x0001000 /* cannot see */ +#define att_nounset 0x0002000 /* cannot unset */ +#define att_noassign 0x0004000 /* assignment not allowed */ +#define att_imported 0x0008000 /* came from environment */ +#define att_special 0x0010000 /* requires special handling */ +#define att_nofree 0x0020000 /* do not free value on unset */ +#define att_regenerate 0x0040000 /* regenerate when exported */ + +#define attmask_int 0x00ff000 + +/* Internal attributes used for variable scoping. */ +#define att_tempvar 0x0100000 /* variable came from the temp environment */ +#define att_propagate 0x0200000 /* propagate to previous scope */ + +#define attmask_scope 0x0f00000 + +#define exported_p(var) ((((var)->attributes) & (att_exported))) +#define readonly_p(var) ((((var)->attributes) & (att_readonly))) +#define array_p(var) ((((var)->attributes) & (att_array))) +#define function_p(var) ((((var)->attributes) & (att_function))) +#define integer_p(var) ((((var)->attributes) & (att_integer))) +#define local_p(var) ((((var)->attributes) & (att_local))) +#define assoc_p(var) ((((var)->attributes) & (att_assoc))) +#define trace_p(var) ((((var)->attributes) & (att_trace))) +#define uppercase_p(var) ((((var)->attributes) & (att_uppercase))) +#define lowercase_p(var) ((((var)->attributes) & (att_lowercase))) +#define capcase_p(var) ((((var)->attributes) & (att_capcase))) +#define nameref_p(var) ((((var)->attributes) & (att_nameref))) + +#define invisible_p(var) ((((var)->attributes) & (att_invisible))) +#define non_unsettable_p(var) ((((var)->attributes) & (att_nounset))) +#define noassign_p(var) ((((var)->attributes) & (att_noassign))) +#define imported_p(var) ((((var)->attributes) & (att_imported))) +#define specialvar_p(var) ((((var)->attributes) & (att_special))) +#define nofree_p(var) ((((var)->attributes) & (att_nofree))) +#define regen_p(var) ((((var)->attributes) & (att_regenerate))) + +#define tempvar_p(var) ((((var)->attributes) & (att_tempvar))) +#define propagate_p(var) ((((var)->attributes) & (att_propagate))) + +/* Variable names: lvalues */ +#define name_cell(var) ((var)->name) + +/* Accessing variable values: rvalues */ +#define value_cell(var) ((var)->value) +#define function_cell(var) (COMMAND *)((var)->value) +#define array_cell(var) (ARRAY *)((var)->value) +#define assoc_cell(var) (HASH_TABLE *)((var)->value) +#define nameref_cell(var) ((var)->value) /* so it can change later */ + +#define NAMEREF_MAX 8 /* only 8 levels of nameref indirection */ + +#define var_isset(var) ((var)->value != 0) +#define var_isunset(var) ((var)->value == 0) +#define var_isnull(var) ((var)->value && *(var)->value == 0) + +/* Assigning variable values: lvalues */ +#define var_setvalue(var, str) ((var)->value = (str)) +#define var_setfunc(var, func) ((var)->value = (char *)(func)) +#define var_setarray(var, arr) ((var)->value = (char *)(arr)) +#define var_setassoc(var, arr) ((var)->value = (char *)(arr)) +#define var_setref(var, str) ((var)->value = (str)) + +/* Make VAR be auto-exported. */ +#define set_auto_export(var) \ + do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0) + +#define SETVARATTR(var, attr, undo) \ + ((undo == 0) ? ((var)->attributes |= (attr)) \ + : ((var)->attributes &= ~(attr))) + +#define VSETATTR(var, attr) ((var)->attributes |= (attr)) +#define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr)) + +#define VGETFLAGS(var) ((var)->attributes) + +#define VSETFLAGS(var, flags) ((var)->attributes = (flags)) +#define VCLRFLAGS(var) ((var)->attributes = 0) + +/* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */ +#define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL +#define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL +#define SET_EXPORTSTR(var, value) (var)->exportstr = (value) +#define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL + +#define FREE_EXPORTSTR(var) \ + do { if ((var)->exportstr) free ((var)->exportstr); } while (0) + +#define CACHE_IMPORTSTR(var, value) \ + (var)->exportstr = savestring (value) + +#define INVALIDATE_EXPORTSTR(var) \ + do { \ + if ((var)->exportstr) \ + { \ + free ((var)->exportstr); \ + (var)->exportstr = (char *)NULL; \ + } \ + } while (0) + +#define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0') + +/* Flag values for make_local_variable and its array counterparts */ +#define MKLOC_ASSOCOK 0x01 +#define MKLOC_ARRAYOK 0x02 +#define MKLOC_INHERIT 0x04 + +/* Special value for nameref with invalid value for creation or assignment */ +extern SHELL_VAR nameref_invalid_value; +#define INVALID_NAMEREF_VALUE (void *)&nameref_invalid_value + +/* Stuff for hacking variables. */ +typedef int sh_var_map_func_t PARAMS((SHELL_VAR *)); + +/* Where we keep the variables and functions */ +extern VAR_CONTEXT *global_variables; +extern VAR_CONTEXT *shell_variables; + +extern HASH_TABLE *shell_functions; +extern HASH_TABLE *temporary_env; + +extern int variable_context; +extern char *dollar_vars[]; +extern char **export_env; + +extern int tempenv_assign_error; +extern int array_needs_making; +extern int shell_level; + +/* XXX */ +extern WORD_LIST *rest_of_args; +extern int posparam_count; +extern pid_t dollar_dollar_pid; + +extern int localvar_inherit; /* declared in variables.c */ + +extern void initialize_shell_variables PARAMS((char **, int)); + +extern int validate_inherited_value PARAMS((SHELL_VAR *, int)); + +extern SHELL_VAR *set_if_not PARAMS((char *, char *)); + +extern void sh_set_lines_and_columns PARAMS((int, int)); +extern void set_pwd PARAMS((void)); +extern void set_ppid PARAMS((void)); +extern void make_funcname_visible PARAMS((int)); + +extern SHELL_VAR *var_lookup PARAMS((const char *, VAR_CONTEXT *)); + +extern SHELL_VAR *find_function PARAMS((const char *)); +extern FUNCTION_DEF *find_function_def PARAMS((const char *)); +extern SHELL_VAR *find_variable PARAMS((const char *)); +extern SHELL_VAR *find_variable_noref PARAMS((const char *)); +extern SHELL_VAR *find_variable_last_nameref PARAMS((const char *, int)); +extern SHELL_VAR *find_global_variable_last_nameref PARAMS((const char *, int)); +extern SHELL_VAR *find_variable_nameref PARAMS((SHELL_VAR *)); +extern SHELL_VAR *find_variable_nameref_for_create PARAMS((const char *, int)); +extern SHELL_VAR *find_variable_nameref_for_assignment PARAMS((const char *, int)); +/*extern SHELL_VAR *find_variable_internal PARAMS((const char *, int));*/ +extern SHELL_VAR *find_variable_tempenv PARAMS((const char *)); +extern SHELL_VAR *find_variable_notempenv PARAMS((const char *)); +extern SHELL_VAR *find_global_variable PARAMS((const char *)); +extern SHELL_VAR *find_global_variable_noref PARAMS((const char *)); +extern SHELL_VAR *find_shell_variable PARAMS((const char *)); +extern SHELL_VAR *find_tempenv_variable PARAMS((const char *)); +extern SHELL_VAR *find_variable_no_invisible PARAMS((const char *)); +extern SHELL_VAR *find_variable_for_assignment PARAMS((const char *)); +extern char *nameref_transform_name PARAMS((char *, int)); +extern SHELL_VAR *copy_variable PARAMS((SHELL_VAR *)); +extern SHELL_VAR *make_local_variable PARAMS((const char *, int)); +extern SHELL_VAR *bind_variable PARAMS((const char *, char *, int)); +extern SHELL_VAR *bind_global_variable PARAMS((const char *, char *, int)); +extern SHELL_VAR *bind_function PARAMS((const char *, COMMAND *)); + +extern void bind_function_def PARAMS((const char *, FUNCTION_DEF *, int)); + +extern SHELL_VAR **map_over PARAMS((sh_var_map_func_t *, VAR_CONTEXT *)); +SHELL_VAR **map_over_funcs PARAMS((sh_var_map_func_t *)); + +extern SHELL_VAR **all_shell_variables PARAMS((void)); +extern SHELL_VAR **all_shell_functions PARAMS((void)); +extern SHELL_VAR **all_visible_variables PARAMS((void)); +extern SHELL_VAR **all_visible_functions PARAMS((void)); +extern SHELL_VAR **all_exported_variables PARAMS((void)); +extern SHELL_VAR **local_exported_variables PARAMS((void)); +extern SHELL_VAR **all_local_variables PARAMS((int)); +#if defined (ARRAY_VARS) +extern SHELL_VAR **all_array_variables PARAMS((void)); +#endif +extern char **all_variables_matching_prefix PARAMS((const char *)); + +extern char **make_var_array PARAMS((HASH_TABLE *)); +extern char **add_or_supercede_exported_var PARAMS((char *, int)); + +extern char *get_variable_value PARAMS((SHELL_VAR *)); +extern char *get_string_value PARAMS((const char *)); +extern char *sh_get_env_value PARAMS((const char *)); +extern char *make_variable_value PARAMS((SHELL_VAR *, char *, int)); + +extern SHELL_VAR *bind_variable_value PARAMS((SHELL_VAR *, char *, int)); +extern SHELL_VAR *bind_int_variable PARAMS((char *, char *, int)); +extern SHELL_VAR *bind_var_to_int PARAMS((char *, intmax_t)); + +extern int assign_in_env PARAMS((WORD_DESC *, int)); + +extern int unbind_variable PARAMS((const char *)); +extern int check_unbind_variable PARAMS((const char *)); +extern int unbind_nameref PARAMS((const char *)); +extern int unbind_variable_noref PARAMS((const char *)); +extern int unbind_func PARAMS((const char *)); +extern int unbind_function_def PARAMS((const char *)); +extern int delete_var PARAMS((const char *, VAR_CONTEXT *)); +extern int makunbound PARAMS((const char *, VAR_CONTEXT *)); +extern int kill_local_variable PARAMS((const char *)); +extern void delete_all_variables PARAMS((HASH_TABLE *)); +extern void delete_all_contexts PARAMS((VAR_CONTEXT *)); + +extern VAR_CONTEXT *new_var_context PARAMS((char *, int)); +extern void dispose_var_context PARAMS((VAR_CONTEXT *)); +extern VAR_CONTEXT *push_var_context PARAMS((char *, int, HASH_TABLE *)); +extern void pop_var_context PARAMS((void)); +extern VAR_CONTEXT *push_scope PARAMS((int, HASH_TABLE *)); +extern void pop_scope PARAMS((int)); + +extern void clear_dollar_vars PARAMS((void)); + +extern void push_context PARAMS((char *, int, HASH_TABLE *)); +extern void pop_context PARAMS((void)); +extern void push_dollar_vars PARAMS((void)); +extern void pop_dollar_vars PARAMS((void)); +extern void dispose_saved_dollar_vars PARAMS((void)); + +extern void init_bash_argv PARAMS((void)); +extern void save_bash_argv PARAMS((void)); +extern void push_args PARAMS((WORD_LIST *)); +extern void pop_args PARAMS((void)); + +extern void adjust_shell_level PARAMS((int)); +extern void non_unsettable PARAMS((char *)); +extern void dispose_variable PARAMS((SHELL_VAR *)); +extern void dispose_used_env_vars PARAMS((void)); +extern void dispose_function_env PARAMS((void)); +extern void dispose_builtin_env PARAMS((void)); +extern void merge_temporary_env PARAMS((void)); +extern void flush_temporary_env PARAMS((void)); +extern void merge_builtin_env PARAMS((void)); +extern void kill_all_local_variables PARAMS((void)); + +extern void set_var_read_only PARAMS((char *)); +extern void set_func_read_only PARAMS((const char *)); +extern void set_var_auto_export PARAMS((char *)); +extern void set_func_auto_export PARAMS((const char *)); + +extern void sort_variables PARAMS((SHELL_VAR **)); + +extern int chkexport PARAMS((char *)); +extern void maybe_make_export_env PARAMS((void)); +extern void update_export_env_inplace PARAMS((char *, int, char *)); +extern void put_command_name_into_env PARAMS((char *)); +extern void put_gnu_argv_flags_into_env PARAMS((intmax_t, char *)); + +extern void print_var_list PARAMS((SHELL_VAR **)); +extern void print_func_list PARAMS((SHELL_VAR **)); +extern void print_assignment PARAMS((SHELL_VAR *)); +extern void print_var_value PARAMS((SHELL_VAR *, int)); +extern void print_var_function PARAMS((SHELL_VAR *)); + +#if defined (ARRAY_VARS) +extern SHELL_VAR *make_new_array_variable PARAMS((char *)); +extern SHELL_VAR *make_local_array_variable PARAMS((char *, int)); + +extern SHELL_VAR *make_new_assoc_variable PARAMS((char *)); +extern SHELL_VAR *make_local_assoc_variable PARAMS((char *, int)); + +extern void set_pipestatus_array PARAMS((int *, int)); +extern ARRAY *save_pipestatus_array PARAMS((void)); +extern void restore_pipestatus_array PARAMS((ARRAY *)); +#endif + +extern void set_pipestatus_from_exit PARAMS((int)); + +/* The variable in NAME has just had its state changed. Check to see if it + is one of the special ones where something special happens. */ +extern void stupidly_hack_special_variables PARAMS((char *)); + +/* Reinitialize some special variables that have external effects upon unset + when the shell reinitializes itself. */ +extern void reinit_special_variables PARAMS((void)); + +extern int get_random_number PARAMS((void)); + +/* The `special variable' functions that get called when a particular + variable is set. */ +extern void sv_ifs PARAMS((char *)); +extern void sv_path PARAMS((char *)); +extern void sv_mail PARAMS((char *)); +extern void sv_funcnest PARAMS((char *)); +extern void sv_execignore PARAMS((char *)); +extern void sv_globignore PARAMS((char *)); +extern void sv_ignoreeof PARAMS((char *)); +extern void sv_strict_posix PARAMS((char *)); +extern void sv_optind PARAMS((char *)); +extern void sv_opterr PARAMS((char *)); +extern void sv_locale PARAMS((char *)); +extern void sv_xtracefd PARAMS((char *)); +extern void sv_shcompat PARAMS((char *)); + +#if defined (READLINE) +extern void sv_comp_wordbreaks PARAMS((char *)); +extern void sv_terminal PARAMS((char *)); +extern void sv_hostfile PARAMS((char *)); +extern void sv_winsize PARAMS((char *)); +#endif + +#if defined (__CYGWIN__) +extern void sv_home PARAMS((char *)); +#endif + +#if defined (HISTORY) +extern void sv_histsize PARAMS((char *)); +extern void sv_histignore PARAMS((char *)); +extern void sv_history_control PARAMS((char *)); +# if defined (BANG_HISTORY) +extern void sv_histchars PARAMS((char *)); +# endif +extern void sv_histtimefmt PARAMS((char *)); +#endif /* HISTORY */ + +#if defined (HAVE_TZSET) +extern void sv_tz PARAMS((char *)); +#endif + +#if defined (JOB_CONTROL) +extern void sv_childmax PARAMS((char *)); +#endif + +#endif /* !_VARIABLES_H_ */ diff --git a/utshell-0.5.0/variable/xmalloc.h b/utshell-0.5.0/variable/xmalloc.h new file mode 100644 index 00000000..752b8b19 --- /dev/null +++ b/utshell-0.5.0/variable/xmalloc.h @@ -0,0 +1,67 @@ +//# This file was modified by UnionTech Software Technology Co., Ltd. in 2023/05/30 +/* xmalloc.h -- defines for the `x' memory allocation functions */ + +/* Copyright (C) 2001-2020 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_XMALLOC_H_) +#define _XMALLOC_H_ + +#include "stdc.h" +#include "bashansi.h" + +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +/* Allocation functions in xmalloc.c */ +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); + +#if defined(USING_BASH_MALLOC) && !defined (DISABLE_MALLOC_WRAPPERS) +extern PTR_T sh_xmalloc PARAMS((size_t, const char *, int)); +extern PTR_T sh_xrealloc PARAMS((void *, size_t, const char *, int)); +extern void sh_xfree PARAMS((void *, const char *, int)); + +#define xmalloc(x) sh_xmalloc((x), __FILE__, __LINE__) +#define xrealloc(x, n) sh_xrealloc((x), (n), __FILE__, __LINE__) +#define xfree(x) sh_xfree((x), __FILE__, __LINE__) + +#ifdef free +#undef free +#endif +#define free(x) sh_xfree((x), __FILE__, __LINE__) + +extern PTR_T sh_malloc PARAMS((size_t, const char *, int)); + +#ifdef malloc +#undef malloc +#endif +#define malloc(x) sh_malloc((x), __FILE__, __LINE__) + +#endif /* USING_BASH_MALLOC */ + +#endif /* _XMALLOC_H_ */ diff --git a/utshell-0.5.0/vendor/async-trait/.cargo-checksum.json b/utshell-0.5.0/vendor/async-trait/.cargo-checksum.json new file mode 100644 index 00000000..463a2836 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"c3fa0686c2633fa0aee8044fb543af437d2180c3d56875934ae824603ec18d13","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"caa22edc176059d74c0ad5b7266fd8e8d4164f67b597164c9aa41244a9f08df3","build.rs":"9f9975151b7e9cae692471ff00059392207d8bd66ed51a4d1de61f85693e8e3c","src/args.rs":"6eed5497db91752b3aae597943c39e769f60406b37055304e69e4699f1f87b15","src/bound.rs":"ea6a8d0c1a33521163e5546463f68f6dbda0d35a59e75597be6bf04e0b7b23ad","src/expand.rs":"2d0b0f122c3ec393ce67db6fa177626d8fca0c4f5558b42f4fee219f31b97f9e","src/lib.rs":"1153f494f064422f63d1fe625b0e8029c47b4ce8b3c5f64f0d94ef62798f999a","src/lifetime.rs":"e5ccfba2fa7ecb226cba247286c661f20a84e9a0ad2d789bdfee166cd5250160","src/parse.rs":"cd9032fe2c6dcf41050b3a59b9fb98eb9700a29bbe2fa011ee2854014c1666b7","src/receiver.rs":"356b4ac3e45607d041927799b12c1390c28e6333079343a38799d31ff5dfbe33","src/verbatim.rs":"45d0b691fab21f20d3414733f00d82845442d23b6f2547f8d6880a709d0d3b2a","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/executor/mod.rs":"3cf48614288715f625514a73ae642f649c2635a402a3ad90278bbee116a7234c","tests/test.rs":"2eba31217eeff7f67e786f4c279d1168385204c07c4b28b607a29ce9ede9d86a","tests/ui/arg-implementation-detail.rs":"7199aba887dd0a8a14c86ec16542a73a70244930f8202940f43e40a62f72d200","tests/ui/arg-implementation-detail.stderr":"c3ff1a2a9a9ca4368cb8719e2a035a6d2d45b367212bec2b1fe2712fcfbbbe5d","tests/ui/bare-trait-object.rs":"4546e8bd6682de11920fa4c768295fed61954484ef0550dfadbc5677b77f29a5","tests/ui/bare-trait-object.stderr":"0e1d5902f1ed99a60c6126416806b7c40f4ac9bdd78f26d8e6d866738cc332df","tests/ui/consider-restricting.rs":"bff794222d9324241155568d541e7beac0238b66ce14039b242d4392f4e531b6","tests/ui/consider-restricting.stderr":"a8f7f45aa196febb5d7550597f47b72ba0176d05599260e56a438148b42de840","tests/ui/delimiter-span.rs":"f4fd804223ce3be0d4eecdfd222afdd835c5393e2473ff4932116163943c0bc9","tests/ui/delimiter-span.stderr":"7b5bbe4be3be533d31d1302649b317465bc28cc7f042b98ec78e8b9a82828155","tests/ui/lifetime-defined-here.rs":"3139a3d92cf787c43afd93da2d967ee80d114ee3a0b9c924da9601b5c6614ef5","tests/ui/lifetime-defined-here.stderr":"0d4236821e0f43e5ae38a99319a64020576e78a49a71d8c94eb8a486d384308c","tests/ui/lifetime-span.rs":"bbcaa92c2bc08e18cf0c7e9ca1f0bd8080772ebde8b067d819eb2fd662e47b3b","tests/ui/lifetime-span.stderr":"db67c5078ab66725227b8f4c612ff97b39cb45d5d6b7a4191766a34a6c711547","tests/ui/missing-async-in-impl.rs":"5a5538d08d11c145211a92af0d8973eee8b21f33b90adda85430805bd3dbbc83","tests/ui/missing-async-in-impl.stderr":"2916bc8a51e25f4dd18eaf433b916d533943eac2c1afbee64e9a89e7b928040d","tests/ui/missing-async-in-trait.rs":"dc67241593f270233ba885df92e59164126416e68d49d8d62edc251666b5db6e","tests/ui/missing-async-in-trait.stderr":"67e66e7b19358830deff3ba01f5d701a9ae05c4e6fa9c081c49c1c75efbb7ade","tests/ui/missing-body.rs":"d06c0da8c6044e7c790b924136f167e2edc0d0d3fa01f23521f3f08ca605929b","tests/ui/missing-body.stderr":"e5ee994398bf8294324d61df02467a4229f68f4113bf5acc004851c03d66ec6a","tests/ui/must-use.rs":"75090c7df984df0996464337f60371d198bd0caf3f9f44b10d1e131f15fd4fca","tests/ui/must-use.stderr":"3f4c30eb0234da366b6dc360b0ff85ef5f621003055fb64a0e1fc18d4a0e244f","tests/ui/no-attribute-macro.rs":"99aaad298a8ef366029e53b6d320b14f18e04057a117ff58a0aebad65f01e22f","tests/ui/no-attribute-macro.stderr":"a6ae9bb5914777c780021e223877bc21f38e7716d351ab98aef668dc349bd3ab","tests/ui/self-span.rs":"67ddde05907d7014bfb3f2c63d427b1d72d6c4369a9108a4335dac6bee5832b2","tests/ui/self-span.stderr":"016ef4f29156250f073f4f6cd3096d2889325709bd693938e0d368077b752551","tests/ui/send-not-implemented.rs":"affbbe8bc9c3501d3db3a024e06daa9d076f1d142dba290c7aa1ea119daebd19","tests/ui/send-not-implemented.stderr":"b2cd38ce3cadda8f9e641b98e37db51afba47eab21d29cbfc47a90c8a444aa27","tests/ui/unreachable.rs":"be0aa7cc129fe42a1fbd85e36b3f08c6a2bd16c90ed2e33fc4c50e40ce085bcd","tests/ui/unreachable.stderr":"73beb71cb74076f2cb45485271de31658cf59f4143e62daa34b9f2a8980ddfcd","tests/ui/unsupported-self.rs":"f7855bc39dab1fd2f533fb2e873a27c3757dcb9fb57001e4b19f58d3dda36d01","tests/ui/unsupported-self.stderr":"64fc5d45cb51330f0a1e85e69a28b69ddda12a109aa6a8ba3eaee1ac58d93b5f"},"package":"c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/async-trait/Cargo.toml b/utshell-0.5.0/vendor/async-trait/Cargo.toml new file mode 100644 index 00000000..ad75a205 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/Cargo.toml @@ -0,0 +1,63 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.56" +name = "async-trait" +version = "0.1.77" +authors = ["David Tolnay "] +description = "Type erasure for async trait methods" +documentation = "https://docs.rs/async-trait" +readme = "README.md" +keywords = ["async"] +categories = [ + "asynchronous", + "no-std", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/async-trait" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +proc-macro = true + +[dependencies.proc-macro2] +version = "1.0.74" + +[dependencies.quote] +version = "1.0.35" + +[dependencies.syn] +version = "2.0.46" +features = [ + "full", + "visit-mut", +] + +[dev-dependencies.futures] +version = "0.3.30" + +[dev-dependencies.rustversion] +version = "1.0.13" + +[dev-dependencies.tracing] +version = "0.1.40" + +[dev-dependencies.tracing-attributes] +version = "0.1.27" + +[dev-dependencies.trybuild] +version = "1.0.81" +features = ["diff"] diff --git a/utshell-0.5.0/vendor/async-trait/LICENSE-APACHE b/utshell-0.5.0/vendor/async-trait/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/utshell-0.5.0/vendor/async-trait/LICENSE-MIT b/utshell-0.5.0/vendor/async-trait/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/async-trait/README.md b/utshell-0.5.0/vendor/async-trait/README.md new file mode 100644 index 00000000..97dbac95 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/README.md @@ -0,0 +1,275 @@ +Async trait methods +=================== + +[github](https://github.com/dtolnay/async-trait) +[crates.io](https://crates.io/crates/async-trait) +[docs.rs](https://docs.rs/async-trait) +[build status](https://github.com/dtolnay/async-trait/actions?query=branch%3Amaster) + +The stabilization of async functions in traits in Rust 1.75 did not include +support for using traits containing async functions as `dyn Trait`. Trying to +use dyn with an async trait produces the following error: + +```rust +pub trait Trait { + async fn f(&self); +} + +pub fn make() -> Box { + unimplemented!() +} +``` + +```console +error[E0038]: the trait `Trait` cannot be made into an object + --> src/main.rs:5:22 + | +5 | pub fn make() -> Box { + | ^^^^^^^^^ `Trait` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> src/main.rs:2:14 + | +1 | pub trait Trait { + | ----- this trait cannot be made into an object... +2 | async fn f(&self); + | ^ ...because method `f` is `async` + = help: consider moving `f` to another trait +``` + +This crate provides an attribute macro to make async fn in traits work with dyn +traits. + +Please refer to [*why async fn in traits are hard*][hard] for a deeper analysis +of how this implementation differs from what the compiler and language deliver +natively. + +[hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/ + +
+ +## Example + +This example implements the core of a highly effective advertising platform +using async fn in a trait. + +The only thing to notice here is that we write an `#[async_trait]` macro on top +of traits and trait impls that contain async fn, and then they work. We get to +have `Vec>` or `&[&dyn Advertisement]`, for +example. + +```rust +use async_trait::async_trait; + +#[async_trait] +trait Advertisement { + async fn run(&self); +} + +struct Modal; + +#[async_trait] +impl Advertisement for Modal { + async fn run(&self) { + self.render_fullscreen().await; + for _ in 0..4u16 { + remind_user_to_join_mailing_list().await; + } + self.hide_for_now().await; + } +} + +struct AutoplayingVideo { + media_url: String, +} + +#[async_trait] +impl Advertisement for AutoplayingVideo { + async fn run(&self) { + let stream = connect(&self.media_url).await; + stream.play().await; + + // Video probably persuaded user to join our mailing list! + Modal.run().await; + } +} +``` + +
+ +## Supported features + +It is the intention that all features of Rust traits should work nicely with +\#\[async_trait\], but the edge cases are numerous. *Please file an issue if you +see unexpected borrow checker errors, type errors, or warnings.* There is no use +of `unsafe` in the expanded code, so rest assured that if your code compiles it +can't be that badly broken. + +- 👍 Self by value, by reference, by mut reference, or no self; +- 👍 Any number of arguments, any return value; +- 👍 Generic type parameters and lifetime parameters; +- 👍 Associated types; +- 👍 Having async and non-async functions in the same trait; +- 👍 Default implementations provided by the trait; +- 👍 Elided lifetimes. + +
+ +## Explanation + +Async fns get transformed into methods that return `Pin>` and delegate to an async block. + +For example the `impl Advertisement for AutoplayingVideo` above would be +expanded as: + +```rust +impl Advertisement for AutoplayingVideo { + fn run<'async_trait>( + &'async_trait self, + ) -> Pin + Send + 'async_trait>> + where + Self: Sync + 'async_trait, + { + Box::pin(async move { + /* the original method body */ + }) + } +} +``` + +
+ +## Non-threadsafe futures + +Not all async traits need futures that are `dyn Future + Send`. To avoid having +Send and Sync bounds placed on the async trait methods, invoke the async trait +macro as `#[async_trait(?Send)]` on both the trait and the impl blocks. + +
+ +## Elided lifetimes + +Be aware that async fn syntax does not allow lifetime elision outside of `&` and +`&mut` references. (This is true even when not using #\[async_trait\].) +Lifetimes must be named or marked by the placeholder `'_`. + +Fortunately the compiler is able to diagnose missing lifetimes with a good error +message. + +```rust +type Elided<'a> = &'a usize; + +#[async_trait] +trait Test { + async fn test(not_okay: Elided, okay: &usize) {} +} +``` + +```console +error[E0726]: implicit elided lifetime not allowed here + --> src/main.rs:9:29 + | +9 | async fn test(not_okay: Elided, okay: &usize) {} + | ^^^^^^- help: indicate the anonymous lifetime: `<'_>` +``` + +The fix is to name the lifetime or use `'_`. + +```rust +#[async_trait] +trait Test { + // either + async fn test<'e>(elided: Elided<'e>) {} + // or + async fn test(elided: Elided<'_>) {} +} +``` + +
+ +## Dyn traits + +Traits with async methods can be used as trait objects as long as they meet the +usual requirements for dyn -- no methods with type parameters, no self by value, +no associated types, etc. + +```rust +#[async_trait] +pub trait ObjectSafe { + async fn f(&self); + async fn g(&mut self); +} + +impl ObjectSafe for MyType {...} + +let value: MyType = ...; +let object = &value as &dyn ObjectSafe; // make trait object +``` + +The one wrinkle is in traits that provide default implementations of async +methods. In order for the default implementation to produce a future that is +Send, the async\_trait macro must emit a bound of `Self: Sync` on trait methods +that take `&self` and a bound `Self: Send` on trait methods that take `&mut +self`. An example of the former is visible in the expanded code in the +explanation section above. + +If you make a trait with async methods that have default implementations, +everything will work except that the trait cannot be used as a trait object. +Creating a value of type `&dyn Trait` will produce an error that looks like +this: + +```console +error: the trait `Test` cannot be made into an object + --> src/main.rs:8:5 + | +8 | async fn cannot_dyn(&self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``` + +For traits that need to be object safe and need to have default implementations +for some async methods, there are two resolutions. Either you can add Send +and/or Sync as supertraits (Send if there are `&mut self` methods with default +implementations, Sync if there are `&self` methods with default implementations) +to constrain all implementors of the trait such that the default implementations +are applicable to them: + +```rust +#[async_trait] +pub trait ObjectSafe: Sync { // added supertrait + async fn can_dyn(&self) {} +} + +let object = &value as &dyn ObjectSafe; +``` + +or you can strike the problematic methods from your trait object by bounding +them with `Self: Sized`: + +```rust +#[async_trait] +pub trait ObjectSafe { + async fn cannot_dyn(&self) where Self: Sized {} + + // presumably other methods +} + +let object = &value as &dyn ObjectSafe; +``` + +
+ +#### License + + +Licensed under either of
Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/utshell-0.5.0/vendor/async-trait/build.rs b/utshell-0.5.0/vendor/async-trait/build.rs new file mode 100644 index 00000000..db7c5f0e --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/build.rs @@ -0,0 +1,31 @@ +use std::env; +use std::process::Command; +use std::str; + +fn main() { + println!("cargo:rerun-if-env-changed=DOCS_RS"); + + let compiler = match rustc_minor_version() { + Some(compiler) => compiler, + None => return, + }; + + if compiler < 45 { + println!("cargo:rustc-cfg=no_span_mixed_site"); + } + + if compiler < 47 { + println!("cargo:rustc-cfg=self_span_hack"); + } +} + +fn rustc_minor_version() -> Option { + let rustc = env::var_os("RUSTC")?; + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() +} diff --git a/utshell-0.5.0/vendor/async-trait/src/args.rs b/utshell-0.5.0/vendor/async-trait/src/args.rs new file mode 100644 index 00000000..72d97e95 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/args.rs @@ -0,0 +1,36 @@ +use proc_macro2::Span; +use syn::parse::{Error, Parse, ParseStream, Result}; +use syn::Token; + +#[derive(Copy, Clone)] +pub struct Args { + pub local: bool, +} + +mod kw { + syn::custom_keyword!(Send); +} + +impl Parse for Args { + fn parse(input: ParseStream) -> Result { + match try_parse(input) { + Ok(args) if input.is_empty() => Ok(args), + _ => Err(error()), + } + } +} + +fn try_parse(input: ParseStream) -> Result { + if input.peek(Token![?]) { + input.parse::()?; + input.parse::()?; + Ok(Args { local: true }) + } else { + Ok(Args { local: false }) + } +} + +fn error() -> Error { + let msg = "expected #[async_trait] or #[async_trait(?Send)]"; + Error::new(Span::call_site(), msg) +} diff --git a/utshell-0.5.0/vendor/async-trait/src/bound.rs b/utshell-0.5.0/vendor/async-trait/src/bound.rs new file mode 100644 index 00000000..50182f6d --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/bound.rs @@ -0,0 +1,48 @@ +use proc_macro2::{Ident, Span, TokenStream}; +use quote::quote_spanned; +use syn::punctuated::Punctuated; +use syn::{Token, TypeParamBound}; + +pub type Supertraits = Punctuated; + +pub enum InferredBound { + Send, + Sync, +} + +pub fn has_bound(supertraits: &Supertraits, bound: &InferredBound) -> bool { + for supertrait in supertraits { + if let TypeParamBound::Trait(supertrait) = supertrait { + if supertrait.path.is_ident(bound) + || supertrait.path.segments.len() == 3 + && (supertrait.path.segments[0].ident == "std" + || supertrait.path.segments[0].ident == "core") + && supertrait.path.segments[1].ident == "marker" + && supertrait.path.segments[2].ident == *bound + { + return true; + } + } + } + false +} + +impl InferredBound { + fn as_str(&self) -> &str { + match self { + InferredBound::Send => "Send", + InferredBound::Sync => "Sync", + } + } + + pub fn spanned_path(&self, span: Span) -> TokenStream { + let ident = Ident::new(self.as_str(), span); + quote_spanned!(span=> ::core::marker::#ident) + } +} + +impl PartialEq for Ident { + fn eq(&self, bound: &InferredBound) -> bool { + self == bound.as_str() + } +} diff --git a/utshell-0.5.0/vendor/async-trait/src/expand.rs b/utshell-0.5.0/vendor/async-trait/src/expand.rs new file mode 100644 index 00000000..2a8b3c29 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/expand.rs @@ -0,0 +1,484 @@ +use crate::bound::{has_bound, InferredBound, Supertraits}; +use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes}; +use crate::parse::Item; +use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf}; +use crate::verbatim::VerbatimFn; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, ToTokens}; +use std::collections::BTreeSet as Set; +use std::mem; +use syn::punctuated::Punctuated; +use syn::visit_mut::{self, VisitMut}; +use syn::{ + parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericArgument, GenericParam, + Generics, Ident, ImplItem, Lifetime, LifetimeParam, Pat, PatIdent, PathArguments, Receiver, + ReturnType, Signature, Token, TraitItem, Type, TypePath, WhereClause, +}; + +impl ToTokens for Item { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Item::Trait(item) => item.to_tokens(tokens), + Item::Impl(item) => item.to_tokens(tokens), + } + } +} + +#[derive(Clone, Copy)] +enum Context<'a> { + Trait { + generics: &'a Generics, + supertraits: &'a Supertraits, + }, + Impl { + impl_generics: &'a Generics, + associated_type_impl_traits: &'a Set, + }, +} + +impl Context<'_> { + fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator { + let generics = match self { + Context::Trait { generics, .. } => generics, + Context::Impl { impl_generics, .. } => impl_generics, + }; + generics.params.iter().filter_map(move |param| { + if let GenericParam::Lifetime(param) = param { + if used.contains(¶m.lifetime) { + return Some(param); + } + } + None + }) + } +} + +pub fn expand(input: &mut Item, is_local: bool) { + match input { + Item::Trait(input) => { + let context = Context::Trait { + generics: &input.generics, + supertraits: &input.supertraits, + }; + for inner in &mut input.items { + if let TraitItem::Fn(method) = inner { + let sig = &mut method.sig; + if sig.asyncness.is_some() { + let block = &mut method.default; + let mut has_self = has_self_in_sig(sig); + method.attrs.push(parse_quote!(#[must_use])); + if let Some(block) = block { + has_self |= has_self_in_block(block); + transform_block(context, sig, block); + method.attrs.push(lint_suppress_with_body()); + } else { + method.attrs.push(lint_suppress_without_body()); + } + let has_default = method.default.is_some(); + transform_sig(context, sig, has_self, has_default, is_local); + } + } + } + } + Item::Impl(input) => { + let mut associated_type_impl_traits = Set::new(); + for inner in &input.items { + if let ImplItem::Type(assoc) = inner { + if let Type::ImplTrait(_) = assoc.ty { + associated_type_impl_traits.insert(assoc.ident.clone()); + } + } + } + + let context = Context::Impl { + impl_generics: &input.generics, + associated_type_impl_traits: &associated_type_impl_traits, + }; + for inner in &mut input.items { + match inner { + ImplItem::Fn(method) if method.sig.asyncness.is_some() => { + let sig = &mut method.sig; + let block = &mut method.block; + let has_self = has_self_in_sig(sig) || has_self_in_block(block); + transform_block(context, sig, block); + transform_sig(context, sig, has_self, false, is_local); + method.attrs.push(lint_suppress_with_body()); + } + ImplItem::Verbatim(tokens) => { + let mut method = match syn::parse2::(tokens.clone()) { + Ok(method) if method.sig.asyncness.is_some() => method, + _ => continue, + }; + let sig = &mut method.sig; + let has_self = has_self_in_sig(sig); + transform_sig(context, sig, has_self, false, is_local); + method.attrs.push(lint_suppress_with_body()); + *tokens = quote!(#method); + } + _ => {} + } + } + } + } +} + +fn lint_suppress_with_body() -> Attribute { + parse_quote! { + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + } +} + +fn lint_suppress_without_body() -> Attribute { + parse_quote! { + #[allow( + clippy::type_complexity, + clippy::type_repetition_in_bounds + )] + } +} + +// Input: +// async fn f(&self, x: &T) -> Ret; +// +// Output: +// fn f<'life0, 'life1, 'async_trait, T>( +// &'life0 self, +// x: &'life1 T, +// ) -> Pin + Send + 'async_trait>> +// where +// 'life0: 'async_trait, +// 'life1: 'async_trait, +// T: 'async_trait, +// Self: Sync + 'async_trait; +fn transform_sig( + context: Context, + sig: &mut Signature, + has_self: bool, + has_default: bool, + is_local: bool, +) { + let default_span = sig.asyncness.take().unwrap().span; + sig.fn_token.span = default_span; + + let (ret_arrow, ret) = match &sig.output { + ReturnType::Default => (Token![->](default_span), quote_spanned!(default_span=> ())), + ReturnType::Type(arrow, ret) => (*arrow, quote!(#ret)), + }; + + let mut lifetimes = CollectLifetimes::new(); + for arg in &mut sig.inputs { + match arg { + FnArg::Receiver(arg) => lifetimes.visit_receiver_mut(arg), + FnArg::Typed(arg) => lifetimes.visit_type_mut(&mut arg.ty), + } + } + + for param in &mut sig.generics.params { + match param { + GenericParam::Type(param) => { + let param_name = ¶m.ident; + let span = match param.colon_token.take() { + Some(colon_token) => colon_token.span, + None => param_name.span(), + }; + let bounds = mem::replace(&mut param.bounds, Punctuated::new()); + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned!(span=> #param_name: 'async_trait + #bounds)); + } + GenericParam::Lifetime(param) => { + let param_name = ¶m.lifetime; + let span = match param.colon_token.take() { + Some(colon_token) => colon_token.span, + None => param_name.span(), + }; + let bounds = mem::replace(&mut param.bounds, Punctuated::new()); + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned!(span=> #param: 'async_trait + #bounds)); + } + GenericParam::Const(_) => {} + } + } + + for param in context.lifetimes(&lifetimes.explicit) { + let param = ¶m.lifetime; + let span = param.span(); + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned!(span=> #param: 'async_trait)); + } + + if sig.generics.lt_token.is_none() { + sig.generics.lt_token = Some(Token![<](sig.ident.span())); + } + if sig.generics.gt_token.is_none() { + sig.generics.gt_token = Some(Token![>](sig.paren_token.span.join())); + } + + for elided in lifetimes.elided { + sig.generics.params.push(parse_quote!(#elided)); + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned!(elided.span()=> #elided: 'async_trait)); + } + + sig.generics + .params + .push(parse_quote_spanned!(default_span=> 'async_trait)); + + if has_self { + let bounds: &[InferredBound] = if let Some(receiver) = sig.receiver() { + match receiver.ty.as_ref() { + // self: &Self + Type::Reference(ty) if ty.mutability.is_none() => &[InferredBound::Sync], + // self: Arc + Type::Path(ty) + if { + let segment = ty.path.segments.last().unwrap(); + segment.ident == "Arc" + && match &segment.arguments { + PathArguments::AngleBracketed(arguments) => { + arguments.args.len() == 1 + && match &arguments.args[0] { + GenericArgument::Type(Type::Path(arg)) => { + arg.path.is_ident("Self") + } + _ => false, + } + } + _ => false, + } + } => + { + &[InferredBound::Sync, InferredBound::Send] + } + _ => &[InferredBound::Send], + } + } else { + &[InferredBound::Send] + }; + + let bounds = bounds.iter().filter_map(|bound| { + let assume_bound = match context { + Context::Trait { supertraits, .. } => !has_default || has_bound(supertraits, bound), + Context::Impl { .. } => true, + }; + if assume_bound || is_local { + None + } else { + Some(bound.spanned_path(default_span)) + } + }); + + where_clause_or_default(&mut sig.generics.where_clause) + .predicates + .push(parse_quote_spanned! {default_span=> + Self: #(#bounds +)* 'async_trait + }); + } + + for (i, arg) in sig.inputs.iter_mut().enumerate() { + match arg { + FnArg::Receiver(receiver) => { + if receiver.reference.is_none() { + receiver.mutability = None; + } + } + FnArg::Typed(arg) => { + if match *arg.ty { + Type::Reference(_) => false, + _ => true, + } { + if let Pat::Ident(pat) = &mut *arg.pat { + pat.by_ref = None; + pat.mutability = None; + } else { + let positional = positional_arg(i, &arg.pat); + let m = mut_pat(&mut arg.pat); + arg.pat = parse_quote!(#m #positional); + } + } + AddLifetimeToImplTrait.visit_type_mut(&mut arg.ty); + } + } + } + + let bounds = if is_local { + quote_spanned!(default_span=> 'async_trait) + } else { + quote_spanned!(default_span=> ::core::marker::Send + 'async_trait) + }; + sig.output = parse_quote_spanned! {default_span=> + #ret_arrow ::core::pin::Pin + #bounds + >> + }; +} + +// Input: +// async fn f(&self, x: &T, (a, b): (A, B)) -> Ret { +// self + x + a + b +// } +// +// Output: +// Box::pin(async move { +// let ___ret: Ret = { +// let __self = self; +// let x = x; +// let (a, b) = __arg1; +// +// __self + x + a + b +// }; +// +// ___ret +// }) +fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) { + let mut self_span = None; + let decls = sig + .inputs + .iter() + .enumerate() + .map(|(i, arg)| match arg { + FnArg::Receiver(Receiver { + self_token, + mutability, + .. + }) => { + let ident = Ident::new("__self", self_token.span); + self_span = Some(self_token.span); + quote!(let #mutability #ident = #self_token;) + } + FnArg::Typed(arg) => { + // If there is a #[cfg(...)] attribute that selectively enables + // the parameter, forward it to the variable. + // + // This is currently not applied to the `self` parameter. + let attrs = arg.attrs.iter().filter(|attr| attr.path().is_ident("cfg")); + + if let Type::Reference(_) = *arg.ty { + quote!() + } else if let Pat::Ident(PatIdent { + ident, mutability, .. + }) = &*arg.pat + { + quote! { + #(#attrs)* + let #mutability #ident = #ident; + } + } else { + let pat = &arg.pat; + let ident = positional_arg(i, pat); + if let Pat::Wild(_) = **pat { + quote! { + #(#attrs)* + let #ident = #ident; + } + } else { + quote! { + #(#attrs)* + let #pat = { + let #ident = #ident; + #ident + }; + } + } + } + } + }) + .collect::>(); + + if let Some(span) = self_span { + let mut replace_self = ReplaceSelf(span); + replace_self.visit_block_mut(block); + } + + let stmts = &block.stmts; + let let_ret = match &mut sig.output { + ReturnType::Default => quote_spanned! {block.brace_token.span=> + #(#decls)* + let () = { #(#stmts)* }; + }, + ReturnType::Type(_, ret) => { + if contains_associated_type_impl_trait(context, ret) { + if decls.is_empty() { + quote!(#(#stmts)*) + } else { + quote!(#(#decls)* { #(#stmts)* }) + } + } else { + quote_spanned! {block.brace_token.span=> + if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<#ret> { + return __ret; + } + #(#decls)* + let __ret: #ret = { #(#stmts)* }; + #[allow(unreachable_code)] + __ret + } + } + } + }; + let box_pin = quote_spanned!(block.brace_token.span=> + Box::pin(async move { #let_ret }) + ); + block.stmts = parse_quote!(#box_pin); +} + +fn positional_arg(i: usize, pat: &Pat) -> Ident { + let span: Span = syn::spanned::Spanned::span(pat); + #[cfg(not(no_span_mixed_site))] + let span = span.resolved_at(Span::mixed_site()); + format_ident!("__arg{}", i, span = span) +} + +fn contains_associated_type_impl_trait(context: Context, ret: &mut Type) -> bool { + struct AssociatedTypeImplTraits<'a> { + set: &'a Set, + contains: bool, + } + + impl<'a> VisitMut for AssociatedTypeImplTraits<'a> { + fn visit_type_path_mut(&mut self, ty: &mut TypePath) { + if ty.qself.is_none() + && ty.path.segments.len() == 2 + && ty.path.segments[0].ident == "Self" + && self.set.contains(&ty.path.segments[1].ident) + { + self.contains = true; + } + visit_mut::visit_type_path_mut(self, ty); + } + } + + match context { + Context::Trait { .. } => false, + Context::Impl { + associated_type_impl_traits, + .. + } => { + let mut visit = AssociatedTypeImplTraits { + set: associated_type_impl_traits, + contains: false, + }; + visit.visit_type_mut(ret); + visit.contains + } + } +} + +fn where_clause_or_default(clause: &mut Option) -> &mut WhereClause { + clause.get_or_insert_with(|| WhereClause { + where_token: Default::default(), + predicates: Punctuated::new(), + }) +} diff --git a/utshell-0.5.0/vendor/async-trait/src/lib.rs b/utshell-0.5.0/vendor/async-trait/src/lib.rs new file mode 100644 index 00000000..7a485746 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/lib.rs @@ -0,0 +1,356 @@ +//! [![github]](https://github.com/dtolnay/async-trait) [![crates-io]](https://crates.io/crates/async-trait) [![docs-rs]](https://docs.rs/async-trait) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//!

Type erasure for async trait methods

+//! +//! The stabilization of async functions in traits in Rust 1.75 did not include +//! support for using traits containing async functions as `dyn Trait`. Trying +//! to use dyn with an async trait produces the following error: +//! +//! ```compile_fail +//! pub trait Trait { +//! async fn f(&self); +//! } +//! +//! pub fn make() -> Box { +//! unimplemented!() +//! } +//! ``` +//! +//! ```text +//! error[E0038]: the trait `Trait` cannot be made into an object +//! --> src/main.rs:5:22 +//! | +//! 5 | pub fn make() -> Box { +//! | ^^^^^^^^^ `Trait` cannot be made into an object +//! | +//! note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit +//! --> src/main.rs:2:14 +//! | +//! 1 | pub trait Trait { +//! | ----- this trait cannot be made into an object... +//! 2 | async fn f(&self); +//! | ^ ...because method `f` is `async` +//! = help: consider moving `f` to another trait +//! ``` +//! +//! This crate provides an attribute macro to make async fn in traits work with +//! dyn traits. +//! +//! Please refer to [*why async fn in traits are hard*][hard] for a deeper +//! analysis of how this implementation differs from what the compiler and +//! language deliver natively. +//! +//! [hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/ +//! +//!
+//! +//! # Example +//! +//! This example implements the core of a highly effective advertising platform +//! using async fn in a trait. +//! +//! The only thing to notice here is that we write an `#[async_trait]` macro on +//! top of traits and trait impls that contain async fn, and then they work. We +//! get to have `Vec>` or `&[&dyn Advertisement]`, +//! for example. +//! +//! ``` +//! use async_trait::async_trait; +//! +//! #[async_trait] +//! trait Advertisement { +//! async fn run(&self); +//! } +//! +//! struct Modal; +//! +//! #[async_trait] +//! impl Advertisement for Modal { +//! async fn run(&self) { +//! self.render_fullscreen().await; +//! for _ in 0..4u16 { +//! remind_user_to_join_mailing_list().await; +//! } +//! self.hide_for_now().await; +//! } +//! } +//! +//! struct AutoplayingVideo { +//! media_url: String, +//! } +//! +//! #[async_trait] +//! impl Advertisement for AutoplayingVideo { +//! async fn run(&self) { +//! let stream = connect(&self.media_url).await; +//! stream.play().await; +//! +//! // Video probably persuaded user to join our mailing list! +//! Modal.run().await; +//! } +//! } +//! # +//! # impl Modal { +//! # async fn render_fullscreen(&self) {} +//! # async fn hide_for_now(&self) {} +//! # } +//! # +//! # async fn remind_user_to_join_mailing_list() {} +//! # +//! # struct Stream; +//! # async fn connect(_media_url: &str) -> Stream { Stream } +//! # impl Stream { +//! # async fn play(&self) {} +//! # } +//! ``` +//! +//!

+//! +//! # Supported features +//! +//! It is the intention that all features of Rust traits should work nicely with +//! #\[async_trait\], but the edge cases are numerous. Please file an issue if +//! you see unexpected borrow checker errors, type errors, or warnings. There is +//! no use of `unsafe` in the expanded code, so rest assured that if your code +//! compiles it can't be that badly broken. +//! +//! > ☑ Self by value, by reference, by mut reference, or no self;
+//! > ☑ Any number of arguments, any return value;
+//! > ☑ Generic type parameters and lifetime parameters;
+//! > ☑ Associated types;
+//! > ☑ Having async and non-async functions in the same trait;
+//! > ☑ Default implementations provided by the trait;
+//! > ☑ Elided lifetimes.
+//! +//!
+//! +//! # Explanation +//! +//! Async fns get transformed into methods that return `Pin>` and delegate to an async block. +//! +//! For example the `impl Advertisement for AutoplayingVideo` above would be +//! expanded as: +//! +//! ``` +//! # const IGNORE: &str = stringify! { +//! impl Advertisement for AutoplayingVideo { +//! fn run<'async_trait>( +//! &'async_trait self, +//! ) -> Pin + Send + 'async_trait>> +//! where +//! Self: Sync + 'async_trait, +//! { +//! Box::pin(async move { +//! /* the original method body */ +//! }) +//! } +//! } +//! # }; +//! ``` +//! +//!

+//! +//! # Non-threadsafe futures +//! +//! Not all async traits need futures that are `dyn Future + Send`. To avoid +//! having Send and Sync bounds placed on the async trait methods, invoke the +//! async trait macro as `#[async_trait(?Send)]` on both the trait and the impl +//! blocks. +//! +//!
+//! +//! # Elided lifetimes +//! +//! Be aware that async fn syntax does not allow lifetime elision outside of `&` +//! and `&mut` references. (This is true even when not using #\[async_trait\].) +//! Lifetimes must be named or marked by the placeholder `'_`. +//! +//! Fortunately the compiler is able to diagnose missing lifetimes with a good +//! error message. +//! +//! ```compile_fail +//! # use async_trait::async_trait; +//! # +//! type Elided<'a> = &'a usize; +//! +//! #[async_trait] +//! trait Test { +//! async fn test(not_okay: Elided, okay: &usize) {} +//! } +//! ``` +//! +//! ```text +//! error[E0726]: implicit elided lifetime not allowed here +//! --> src/main.rs:9:29 +//! | +//! 9 | async fn test(not_okay: Elided, okay: &usize) {} +//! | ^^^^^^- help: indicate the anonymous lifetime: `<'_>` +//! ``` +//! +//! The fix is to name the lifetime or use `'_`. +//! +//! ``` +//! # use async_trait::async_trait; +//! # +//! # type Elided<'a> = &'a usize; +//! # +//! #[async_trait] +//! trait Test { +//! // either +//! async fn test<'e>(elided: Elided<'e>) {} +//! # } +//! # #[async_trait] +//! # trait Test2 { +//! // or +//! async fn test(elided: Elided<'_>) {} +//! } +//! ``` +//! +//!

+//! +//! # Dyn traits +//! +//! Traits with async methods can be used as trait objects as long as they meet +//! the usual requirements for dyn -- no methods with type parameters, no self +//! by value, no associated types, etc. +//! +//! ``` +//! # use async_trait::async_trait; +//! # +//! #[async_trait] +//! pub trait ObjectSafe { +//! async fn f(&self); +//! async fn g(&mut self); +//! } +//! +//! # const IGNORE: &str = stringify! { +//! impl ObjectSafe for MyType {...} +//! +//! let value: MyType = ...; +//! # }; +//! # +//! # struct MyType; +//! # +//! # #[async_trait] +//! # impl ObjectSafe for MyType { +//! # async fn f(&self) {} +//! # async fn g(&mut self) {} +//! # } +//! # +//! # let value: MyType = MyType; +//! let object = &value as &dyn ObjectSafe; // make trait object +//! ``` +//! +//! The one wrinkle is in traits that provide default implementations of async +//! methods. In order for the default implementation to produce a future that is +//! Send, the async_trait macro must emit a bound of `Self: Sync` on trait +//! methods that take `&self` and a bound `Self: Send` on trait methods that +//! take `&mut self`. An example of the former is visible in the expanded code +//! in the explanation section above. +//! +//! If you make a trait with async methods that have default implementations, +//! everything will work except that the trait cannot be used as a trait object. +//! Creating a value of type `&dyn Trait` will produce an error that looks like +//! this: +//! +//! ```text +//! error: the trait `Test` cannot be made into an object +//! --> src/main.rs:8:5 +//! | +//! 8 | async fn cannot_dyn(&self) {} +//! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//! ``` +//! +//! For traits that need to be object safe and need to have default +//! implementations for some async methods, there are two resolutions. Either +//! you can add Send and/or Sync as supertraits (Send if there are `&mut self` +//! methods with default implementations, Sync if there are `&self` methods with +//! default implementations) to constrain all implementors of the trait such that +//! the default implementations are applicable to them: +//! +//! ``` +//! # use async_trait::async_trait; +//! # +//! #[async_trait] +//! pub trait ObjectSafe: Sync { // added supertrait +//! async fn can_dyn(&self) {} +//! } +//! # +//! # struct MyType; +//! # +//! # #[async_trait] +//! # impl ObjectSafe for MyType {} +//! # +//! # let value = MyType; +//! +//! let object = &value as &dyn ObjectSafe; +//! ``` +//! +//! or you can strike the problematic methods from your trait object by +//! bounding them with `Self: Sized`: +//! +//! ``` +//! # use async_trait::async_trait; +//! # +//! #[async_trait] +//! pub trait ObjectSafe { +//! async fn cannot_dyn(&self) where Self: Sized {} +//! +//! // presumably other methods +//! } +//! # +//! # struct MyType; +//! # +//! # #[async_trait] +//! # impl ObjectSafe for MyType {} +//! # +//! # let value = MyType; +//! +//! let object = &value as &dyn ObjectSafe; +//! ``` + +#![doc(html_root_url = "https://docs.rs/async-trait/0.1.77")] +#![allow( + clippy::default_trait_access, + clippy::doc_markdown, + clippy::explicit_auto_deref, + clippy::if_not_else, + clippy::items_after_statements, + clippy::match_like_matches_macro, + clippy::module_name_repetitions, + clippy::shadow_unrelated, + clippy::similar_names, + clippy::too_many_lines +)] + +extern crate proc_macro; + +mod args; +mod bound; +mod expand; +mod lifetime; +mod parse; +mod receiver; +mod verbatim; + +use crate::args::Args; +use crate::expand::expand; +use crate::parse::Item; +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; + +#[proc_macro_attribute] +pub fn async_trait(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as Args); + let mut item = parse_macro_input!(input as Item); + expand(&mut item, args.local); + TokenStream::from(quote!(#item)) +} diff --git a/utshell-0.5.0/vendor/async-trait/src/lifetime.rs b/utshell-0.5.0/vendor/async-trait/src/lifetime.rs new file mode 100644 index 00000000..a7babfb6 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/lifetime.rs @@ -0,0 +1,112 @@ +use proc_macro2::{Span, TokenStream}; +use std::mem; +use syn::visit_mut::{self, VisitMut}; +use syn::{ + parse_quote_spanned, token, Expr, GenericArgument, Lifetime, Receiver, ReturnType, Token, Type, + TypeBareFn, TypeImplTrait, TypeParen, TypePtr, TypeReference, +}; + +pub struct CollectLifetimes { + pub elided: Vec, + pub explicit: Vec, +} + +impl CollectLifetimes { + pub fn new() -> Self { + CollectLifetimes { + elided: Vec::new(), + explicit: Vec::new(), + } + } + + fn visit_opt_lifetime(&mut self, reference: Token![&], lifetime: &mut Option) { + match lifetime { + None => *lifetime = Some(self.next_lifetime(reference.span)), + Some(lifetime) => self.visit_lifetime(lifetime), + } + } + + fn visit_lifetime(&mut self, lifetime: &mut Lifetime) { + if lifetime.ident == "_" { + *lifetime = self.next_lifetime(lifetime.span()); + } else { + self.explicit.push(lifetime.clone()); + } + } + + fn next_lifetime(&mut self, span: Span) -> Lifetime { + let name = format!("'life{}", self.elided.len()); + let life = Lifetime::new(&name, span); + self.elided.push(life.clone()); + life + } +} + +impl VisitMut for CollectLifetimes { + fn visit_receiver_mut(&mut self, arg: &mut Receiver) { + if let Some((reference, lifetime)) = &mut arg.reference { + self.visit_opt_lifetime(*reference, lifetime); + } else { + visit_mut::visit_type_mut(self, &mut arg.ty); + } + } + + fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) { + self.visit_opt_lifetime(ty.and_token, &mut ty.lifetime); + visit_mut::visit_type_reference_mut(self, ty); + } + + fn visit_generic_argument_mut(&mut self, gen: &mut GenericArgument) { + if let GenericArgument::Lifetime(lifetime) = gen { + self.visit_lifetime(lifetime); + } + visit_mut::visit_generic_argument_mut(self, gen); + } +} + +pub struct AddLifetimeToImplTrait; + +impl VisitMut for AddLifetimeToImplTrait { + fn visit_type_impl_trait_mut(&mut self, ty: &mut TypeImplTrait) { + let span = ty.impl_token.span; + let lifetime = parse_quote_spanned!(span=> 'async_trait); + ty.bounds.insert(0, lifetime); + if let Some(punct) = ty.bounds.pairs_mut().next().unwrap().punct_mut() { + punct.span = span; + } + visit_mut::visit_type_impl_trait_mut(self, ty); + } + + fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) { + parenthesize_impl_trait(&mut ty.elem, ty.and_token.span); + visit_mut::visit_type_reference_mut(self, ty); + } + + fn visit_type_ptr_mut(&mut self, ty: &mut TypePtr) { + parenthesize_impl_trait(&mut ty.elem, ty.star_token.span); + visit_mut::visit_type_ptr_mut(self, ty); + } + + fn visit_type_bare_fn_mut(&mut self, ty: &mut TypeBareFn) { + if let ReturnType::Type(arrow, return_type) = &mut ty.output { + parenthesize_impl_trait(return_type, arrow.spans[0]); + } + visit_mut::visit_type_bare_fn_mut(self, ty); + } + + fn visit_expr_mut(&mut self, _e: &mut Expr) { + // Do not recurse into impl Traits inside of an array length expression. + // + // fn outer(arg: [u8; { fn inner(_: impl Trait) {}; 0 }]); + } +} + +fn parenthesize_impl_trait(elem: &mut Type, paren_span: Span) { + if let Type::ImplTrait(_) = *elem { + let placeholder = Type::Verbatim(TokenStream::new()); + *elem = Type::Paren(TypeParen { + paren_token: token::Paren(paren_span), + elem: Box::new(mem::replace(elem, placeholder)), + }); + } +} diff --git a/utshell-0.5.0/vendor/async-trait/src/parse.rs b/utshell-0.5.0/vendor/async-trait/src/parse.rs new file mode 100644 index 00000000..ebd25351 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/parse.rs @@ -0,0 +1,34 @@ +use proc_macro2::Span; +use syn::parse::{Error, Parse, ParseStream, Result}; +use syn::{Attribute, ItemImpl, ItemTrait, Token}; + +pub enum Item { + Trait(ItemTrait), + Impl(ItemImpl), +} + +impl Parse for Item { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let mut lookahead = input.lookahead1(); + if lookahead.peek(Token![unsafe]) { + let ahead = input.fork(); + ahead.parse::()?; + lookahead = ahead.lookahead1(); + } + if lookahead.peek(Token![pub]) || lookahead.peek(Token![trait]) { + let mut item: ItemTrait = input.parse()?; + item.attrs = attrs; + Ok(Item::Trait(item)) + } else if lookahead.peek(Token![impl]) { + let mut item: ItemImpl = input.parse()?; + if item.trait_.is_none() { + return Err(Error::new(Span::call_site(), "expected a trait impl")); + } + item.attrs = attrs; + Ok(Item::Impl(item)) + } else { + Err(lookahead.error()) + } + } +} diff --git a/utshell-0.5.0/vendor/async-trait/src/receiver.rs b/utshell-0.5.0/vendor/async-trait/src/receiver.rs new file mode 100644 index 00000000..f5791bff --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/receiver.rs @@ -0,0 +1,172 @@ +use proc_macro2::{Group, Span, TokenStream, TokenTree}; +use syn::visit_mut::{self, VisitMut}; +use syn::{ + Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, Path, Receiver, Signature, Token, TypePath, +}; + +pub fn has_self_in_sig(sig: &mut Signature) -> bool { + let mut visitor = HasSelf(false); + visitor.visit_signature_mut(sig); + visitor.0 +} + +pub fn has_self_in_block(block: &mut Block) -> bool { + let mut visitor = HasSelf(false); + visitor.visit_block_mut(block); + visitor.0 +} + +fn has_self_in_token_stream(tokens: TokenStream) -> bool { + tokens.into_iter().any(|tt| match tt { + TokenTree::Ident(ident) => ident == "Self", + TokenTree::Group(group) => has_self_in_token_stream(group.stream()), + _ => false, + }) +} + +pub fn mut_pat(pat: &mut Pat) -> Option { + let mut visitor = HasMutPat(None); + visitor.visit_pat_mut(pat); + visitor.0 +} + +fn contains_fn(tokens: TokenStream) -> bool { + tokens.into_iter().any(|tt| match tt { + TokenTree::Ident(ident) => ident == "fn", + TokenTree::Group(group) => contains_fn(group.stream()), + _ => false, + }) +} + +struct HasMutPat(Option); + +impl VisitMut for HasMutPat { + fn visit_pat_ident_mut(&mut self, i: &mut PatIdent) { + if let Some(m) = i.mutability { + self.0 = Some(m); + } else { + visit_mut::visit_pat_ident_mut(self, i); + } + } +} + +struct HasSelf(bool); + +impl VisitMut for HasSelf { + fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) { + self.0 |= expr.path.segments[0].ident == "Self"; + visit_mut::visit_expr_path_mut(self, expr); + } + + fn visit_type_path_mut(&mut self, ty: &mut TypePath) { + self.0 |= ty.path.segments[0].ident == "Self"; + visit_mut::visit_type_path_mut(self, ty); + } + + fn visit_receiver_mut(&mut self, _arg: &mut Receiver) { + self.0 = true; + } + + fn visit_item_mut(&mut self, _: &mut Item) { + // Do not recurse into nested items. + } + + fn visit_macro_mut(&mut self, mac: &mut Macro) { + if !contains_fn(mac.tokens.clone()) { + self.0 |= has_self_in_token_stream(mac.tokens.clone()); + } + } +} + +pub struct ReplaceSelf(pub Span); + +impl ReplaceSelf { + #[cfg_attr(not(self_span_hack), allow(clippy::unused_self))] + fn prepend_underscore_to_self(&self, ident: &mut Ident) -> bool { + let modified = ident == "self"; + if modified { + *ident = Ident::new("__self", ident.span()); + #[cfg(self_span_hack)] + ident.set_span(self.0); + } + modified + } + + fn visit_token_stream(&mut self, tokens: &mut TokenStream) -> bool { + let mut out = Vec::new(); + let mut modified = false; + visit_token_stream_impl(self, tokens.clone(), &mut modified, &mut out); + if modified { + *tokens = TokenStream::from_iter(out); + } + return modified; + + fn visit_token_stream_impl( + visitor: &mut ReplaceSelf, + tokens: TokenStream, + modified: &mut bool, + out: &mut Vec, + ) { + for tt in tokens { + match tt { + TokenTree::Ident(mut ident) => { + *modified |= visitor.prepend_underscore_to_self(&mut ident); + out.push(TokenTree::Ident(ident)); + } + TokenTree::Group(group) => { + let mut content = group.stream(); + *modified |= visitor.visit_token_stream(&mut content); + let mut new = Group::new(group.delimiter(), content); + new.set_span(group.span()); + out.push(TokenTree::Group(new)); + } + other => out.push(other), + } + } + } + } +} + +impl VisitMut for ReplaceSelf { + fn visit_ident_mut(&mut self, i: &mut Ident) { + self.prepend_underscore_to_self(i); + } + + fn visit_path_mut(&mut self, p: &mut Path) { + if p.segments.len() == 1 { + // Replace `self`, but not `self::function`. + self.visit_ident_mut(&mut p.segments[0].ident); + } + for segment in &mut p.segments { + self.visit_path_arguments_mut(&mut segment.arguments); + } + } + + fn visit_item_mut(&mut self, i: &mut Item) { + // Visit `macro_rules!` because locally defined macros can refer to + // `self`. + // + // Visit `futures::select` and similar select macros, which commonly + // appear syntactically like an item despite expanding to an expression. + // + // Otherwise, do not recurse into nested items. + if let Item::Macro(i) = i { + if i.mac.path.is_ident("macro_rules") + || i.mac.path.segments.last().unwrap().ident == "select" + { + self.visit_macro_mut(&mut i.mac); + } + } + } + + fn visit_macro_mut(&mut self, mac: &mut Macro) { + // We can't tell in general whether `self` inside a macro invocation + // refers to the self in the argument list or a different self + // introduced within the macro. Heuristic: if the macro input contains + // `fn`, then `self` is more likely to refer to something other than the + // outer function's self argument. + if !contains_fn(mac.tokens.clone()) { + self.visit_token_stream(&mut mac.tokens); + } + } +} diff --git a/utshell-0.5.0/vendor/async-trait/src/verbatim.rs b/utshell-0.5.0/vendor/async-trait/src/verbatim.rs new file mode 100644 index 00000000..d064f6ee --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/src/verbatim.rs @@ -0,0 +1,34 @@ +use proc_macro2::TokenStream; +use quote::{ToTokens, TokenStreamExt}; +use syn::parse::{Parse, ParseStream, Result}; +use syn::{Attribute, Signature, Token, Visibility}; + +pub struct VerbatimFn { + pub attrs: Vec, + pub vis: Visibility, + pub defaultness: Option, + pub sig: Signature, + pub semi_token: Token![;], +} + +impl Parse for VerbatimFn { + fn parse(input: ParseStream) -> Result { + Ok(VerbatimFn { + attrs: input.call(Attribute::parse_outer)?, + vis: input.parse()?, + defaultness: input.parse()?, + sig: input.parse()?, + semi_token: input.parse()?, + }) + } +} + +impl ToTokens for VerbatimFn { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.vis.to_tokens(tokens); + self.defaultness.to_tokens(tokens); + self.sig.to_tokens(tokens); + self.semi_token.to_tokens(tokens); + } +} diff --git a/utshell-0.5.0/vendor/async-trait/tests/compiletest.rs b/utshell-0.5.0/vendor/async-trait/tests/compiletest.rs new file mode 100644 index 00000000..7974a624 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/compiletest.rs @@ -0,0 +1,7 @@ +#[rustversion::attr(not(nightly), ignore)] +#[cfg_attr(miri, ignore)] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/utshell-0.5.0/vendor/async-trait/tests/executor/mod.rs b/utshell-0.5.0/vendor/async-trait/tests/executor/mod.rs new file mode 100644 index 00000000..912fb798 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/executor/mod.rs @@ -0,0 +1,36 @@ +use std::future::Future; +use std::pin::Pin; +use std::ptr; +use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; + +// Executor for a future that resolves immediately (test only). +#[allow(clippy::missing_panics_doc)] +pub fn block_on_simple(mut fut: F) -> F::Output { + unsafe fn clone(_null: *const ()) -> RawWaker { + unimplemented!() + } + + unsafe fn wake(_null: *const ()) { + unimplemented!() + } + + unsafe fn wake_by_ref(_null: *const ()) { + unimplemented!() + } + + unsafe fn drop(_null: *const ()) {} + + let data = ptr::null(); + let vtable = &RawWakerVTable::new(clone, wake, wake_by_ref, drop); + let raw_waker = RawWaker::new(data, vtable); + let waker = unsafe { Waker::from_raw(raw_waker) }; + let mut cx = Context::from_waker(&waker); + + // fut does not move until it gets dropped. + let fut = unsafe { Pin::new_unchecked(&mut fut) }; + + match fut.poll(&mut cx) { + Poll::Ready(output) => output, + Poll::Pending => panic!("future did not resolve immediately"), + } +} diff --git a/utshell-0.5.0/vendor/async-trait/tests/test.rs b/utshell-0.5.0/vendor/async-trait/tests/test.rs new file mode 100644 index 00000000..b78c9ffe --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/test.rs @@ -0,0 +1,1605 @@ +#![cfg_attr( + async_trait_nightly_testing, + feature(impl_trait_in_assoc_type, min_specialization) +)] +#![deny(rust_2021_compatibility)] +#![allow( + clippy::let_underscore_untyped, + clippy::let_unit_value, + clippy::missing_panics_doc, + clippy::missing_safety_doc, + clippy::needless_return, + clippy::non_minimal_cfg, + clippy::trivially_copy_pass_by_ref, + clippy::unused_async +)] + +use async_trait::async_trait; + +pub mod executor; + +// Dummy module to check that the expansion refer to rust's core crate +mod core {} + +#[async_trait] +trait Trait { + type Assoc; + + async fn selfvalue(self) + where + Self: Sized, + { + } + + async fn selfref(&self) {} + + async fn selfmut(&mut self) {} + + async fn required() -> Self::Assoc; + + async fn elided_lifetime(_x: &str) {} + + async fn explicit_lifetime<'a>(_x: &'a str) {} + + async fn generic_type_param(x: Box) -> T { + *x + } + + async fn calls(&self) { + self.selfref().await; + Self::elided_lifetime("").await; + ::elided_lifetime("").await; + } + + async fn calls_mut(&mut self) { + self.selfmut().await; + } +} + +struct Struct; + +#[async_trait] +impl Trait for Struct { + type Assoc = (); + + async fn selfvalue(self) {} + + async fn selfref(&self) {} + + async fn selfmut(&mut self) {} + + async fn required() -> Self::Assoc {} + + async fn elided_lifetime(_x: &str) {} + + async fn explicit_lifetime<'a>(_x: &'a str) {} + + async fn generic_type_param(x: Box) -> T { + *x + } + + async fn calls(&self) { + self.selfref().await; + Self::elided_lifetime("").await; + ::elided_lifetime("").await; + } + + async fn calls_mut(&mut self) { + self.selfmut().await; + } +} + +pub async fn test() { + let mut s = Struct; + s.selfref().await; + s.selfmut().await; + s.selfvalue().await; + + Struct::required().await; + Struct::elided_lifetime("").await; + Struct::explicit_lifetime("").await; + Struct::generic_type_param(Box::new("")).await; + + let mut s = Struct; + s.calls().await; + s.calls_mut().await; +} + +pub async fn test_object_safe_without_default() { + #[async_trait] + trait ObjectSafe { + async fn f(&self); + } + + #[async_trait] + impl ObjectSafe for Struct { + async fn f(&self) {} + } + + let object = &Struct as &dyn ObjectSafe; + object.f().await; +} + +pub async fn test_object_safe_with_default() { + #[async_trait] + trait ObjectSafe: Sync { + async fn f(&self) {} + } + + #[async_trait] + impl ObjectSafe for Struct { + async fn f(&self) {} + } + + let object = &Struct as &dyn ObjectSafe; + object.f().await; +} + +pub async fn test_object_no_send() { + #[async_trait(?Send)] + trait ObjectSafe: Sync { + async fn f(&self) {} + } + + #[async_trait(?Send)] + impl ObjectSafe for Struct { + async fn f(&self) {} + } + + let object = &Struct as &dyn ObjectSafe; + object.f().await; +} + +#[async_trait] +pub unsafe trait UnsafeTrait {} + +#[async_trait] +unsafe impl UnsafeTrait for () {} + +#[async_trait] +pub(crate) unsafe trait UnsafeTraitPubCrate {} + +#[async_trait] +unsafe trait UnsafeTraitPrivate {} + +pub async fn test_can_destruct() { + #[async_trait] + trait CanDestruct { + async fn f(&self, foos: (u8, u8, u8, u8)); + } + + #[async_trait] + impl CanDestruct for Struct { + async fn f(&self, (a, ref mut b, ref c, d): (u8, u8, u8, u8)) { + let _a: u8 = a; + let _b: &mut u8 = b; + let _c: &u8 = c; + let _d: u8 = d; + } + } +} + +pub async fn test_self_in_macro() { + #[async_trait] + trait Trait { + async fn a(self); + async fn b(&mut self); + async fn c(&self); + } + + #[async_trait] + impl Trait for String { + async fn a(self) { + println!("{}", self); + } + async fn b(&mut self) { + println!("{}", self); + } + async fn c(&self) { + println!("{}", self); + } + } +} + +pub async fn test_inference() { + #[async_trait] + pub trait Trait { + async fn f() -> Box> { + Box::new(std::iter::empty()) + } + } +} + +pub async fn test_internal_items() { + #[async_trait] + #[allow(dead_code, clippy::items_after_statements)] + pub trait Trait: Sized { + async fn f(self) { + struct Struct; + + impl Struct { + fn f(self) { + let _ = self; + } + } + } + } +} + +pub async fn test_unimplemented() { + #[async_trait] + pub trait Trait { + async fn f() { + unimplemented!() + } + } +} + +// https://github.com/dtolnay/async-trait/issues/1 +pub mod issue1 { + use async_trait::async_trait; + + #[async_trait] + trait Issue1 { + async fn f(&self); + } + + #[async_trait] + impl Issue1 for Vec { + async fn f(&self) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/2 +pub mod issue2 { + use async_trait::async_trait; + use std::future::Future; + + #[async_trait] + pub trait Issue2: Future { + async fn flatten(self) -> ::Output + where + Self::Output: Future + Send, + Self: Sized, + { + let nested_future = self.await; + nested_future.await + } + } +} + +// https://github.com/dtolnay/async-trait/issues/9 +pub mod issue9 { + use async_trait::async_trait; + + #[async_trait] + pub trait Issue9: Sized + Send { + async fn f(_x: Self) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/11 +pub mod issue11 { + use async_trait::async_trait; + use std::sync::Arc; + + #[async_trait] + trait Issue11 { + async fn example(self: Arc); + } + + struct Struct; + + #[async_trait] + impl Issue11 for Struct { + async fn example(self: Arc) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/15 +pub mod issue15 { + use async_trait::async_trait; + use std::marker::PhantomData; + + trait Trait {} + + #[async_trait] + trait Issue15 { + async fn myfn(&self, _: PhantomData) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/17 +pub mod issue17 { + use async_trait::async_trait; + + #[async_trait] + trait Issue17 { + async fn f(&self); + } + + struct Struct { + string: String, + } + + #[async_trait] + impl Issue17 for Struct { + async fn f(&self) { + println!("{}", self.string); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/23 +pub mod issue23 { + use async_trait::async_trait; + + #[async_trait] + pub trait Issue23 { + async fn f(self); + + async fn g(mut self) + where + Self: Sized, + { + do_something(&mut self); + } + } + + struct S {} + + #[async_trait] + impl Issue23 for S { + async fn f(mut self) { + do_something(&mut self); + } + } + + fn do_something(_: &mut T) {} +} + +// https://github.com/dtolnay/async-trait/issues/25 +#[cfg(async_trait_nightly_testing)] +pub mod issue25 { + use crate::executor; + use async_trait::async_trait; + use std::fmt::{Display, Write}; + + #[async_trait] + trait AsyncToString { + async fn async_to_string(&self) -> String; + } + + #[async_trait] + impl AsyncToString for String { + async fn async_to_string(&self) -> String { + "special".to_owned() + } + } + + macro_rules! hide_from_stable_parser { + ($($tt:tt)*) => { + $($tt)* + }; + } + + hide_from_stable_parser! { + #[async_trait] + impl AsyncToString for T { + default async fn async_to_string(&self) -> String { + let mut buf = String::new(); + buf.write_fmt(format_args!("{}", self)).unwrap(); + buf + } + } + } + + #[test] + fn test() { + let fut = true.async_to_string(); + assert_eq!(executor::block_on_simple(fut), "true"); + + let string = String::new(); + let fut = string.async_to_string(); + assert_eq!(executor::block_on_simple(fut), "special"); + } +} + +// https://github.com/dtolnay/async-trait/issues/28 +pub mod issue28 { + use async_trait::async_trait; + + struct Str<'a>(&'a str); + + #[async_trait] + trait Trait1<'a> { + async fn f(x: Str<'a>) -> &'a str; + async fn g(x: Str<'a>) -> &'a str { + x.0 + } + } + + #[async_trait] + impl<'a> Trait1<'a> for str { + async fn f(x: Str<'a>) -> &'a str { + x.0 + } + } + + #[async_trait] + trait Trait2 { + async fn f(); + } + + #[async_trait] + impl<'a> Trait2 for &'a () { + async fn f() {} + } + + #[async_trait] + trait Trait3<'a, 'b> { + async fn f(_: &'a &'b ()); // chain 'a and 'b + async fn g(_: &'b ()); // chain 'b only + async fn h(); // do not chain + } +} + +// https://github.com/dtolnay/async-trait/issues/31 +pub mod issue31 { + use async_trait::async_trait; + + pub struct Struct<'a> { + pub name: &'a str, + } + + #[async_trait] + pub trait Trait<'a> { + async fn hello(thing: Struct<'a>) -> String; + async fn hello_twice(one: Struct<'a>, two: Struct<'a>) -> String { + let str1 = Self::hello(one).await; + let str2 = Self::hello(two).await; + str1 + &str2 + } + } +} + +// https://github.com/dtolnay/async-trait/issues/42 +pub mod issue42 { + use async_trait::async_trait; + + #[async_trait] + pub trait Context: Sized { + async fn from_parts() -> Self; + } + + pub struct TokenContext; + + #[async_trait] + impl Context for TokenContext { + async fn from_parts() -> TokenContext { + TokenContext + } + } +} + +// https://github.com/dtolnay/async-trait/issues/44 +pub mod issue44 { + use async_trait::async_trait; + + #[async_trait] + pub trait StaticWithWhereSelf + where + Box: Sized, + Self: Sized + Send, + { + async fn get_one() -> u8 { + 1 + } + } + + pub struct Struct; + + #[async_trait] + impl StaticWithWhereSelf for Struct {} +} + +// https://github.com/dtolnay/async-trait/issues/45 +pub mod issue45 { + use crate::executor; + use async_trait::async_trait; + use std::fmt::Debug; + use std::sync::atomic::{AtomicU64, Ordering}; + use std::sync::{Arc, Mutex}; + use tracing::event::Event; + use tracing::field::{Field, Visit}; + use tracing::span::{Attributes, Id, Record}; + use tracing::{info, instrument, subscriber, Metadata, Subscriber}; + + #[async_trait] + pub trait Parent { + async fn foo(&mut self, v: usize); + } + + #[async_trait] + pub trait Child { + async fn bar(&self); + } + + #[derive(Debug)] + struct Impl(usize); + + #[async_trait] + impl Parent for Impl { + #[instrument] + async fn foo(&mut self, v: usize) { + self.0 = v; + self.bar().await; + } + } + + #[async_trait] + impl Child for Impl { + // Let's check that tracing detects the renaming of the `self` variable + // too, as tracing::instrument is not going to be able to skip the + // `self` argument if it can't find it in the function signature. + #[instrument(skip(self))] + async fn bar(&self) { + info!(val = self.0); + } + } + + // A simple subscriber implementation to test the behavior of async-trait + // with tokio-rs/tracing. This implementation is not robust against race + // conditions, but it's not an issue here as we are only polling on a single + // future at a time. + #[derive(Debug)] + struct SubscriberInner { + current_depth: AtomicU64, + // We assert that nested functions work. If the fix were to break, we + // would see two top-level functions instead of `bar` nested in `foo`. + max_depth: AtomicU64, + max_span_id: AtomicU64, + // Name of the variable / value / depth when the event was recorded. + value: Mutex>, + } + + #[derive(Debug, Clone)] + struct TestSubscriber { + inner: Arc, + } + + impl TestSubscriber { + fn new() -> Self { + TestSubscriber { + inner: Arc::new(SubscriberInner { + current_depth: AtomicU64::new(0), + max_depth: AtomicU64::new(0), + max_span_id: AtomicU64::new(1), + value: Mutex::new(None), + }), + } + } + } + + struct U64Visitor(Option<(&'static str, u64)>); + + impl Visit for U64Visitor { + fn record_debug(&mut self, _field: &Field, _value: &dyn Debug) {} + + fn record_u64(&mut self, field: &Field, value: u64) { + self.0 = Some((field.name(), value)); + } + } + + impl Subscriber for TestSubscriber { + fn enabled(&self, _metadata: &Metadata) -> bool { + true + } + fn new_span(&self, _span: &Attributes) -> Id { + Id::from_u64(self.inner.max_span_id.fetch_add(1, Ordering::AcqRel)) + } + fn record(&self, _span: &Id, _values: &Record) {} + fn record_follows_from(&self, _span: &Id, _follows: &Id) {} + fn event(&self, event: &Event) { + let mut visitor = U64Visitor(None); + event.record(&mut visitor); + if let Some((s, v)) = visitor.0 { + let current_depth = self.inner.current_depth.load(Ordering::Acquire); + *self.inner.value.lock().unwrap() = Some((s, v, current_depth)); + } + } + fn enter(&self, _span: &Id) { + let old_depth = self.inner.current_depth.fetch_add(1, Ordering::AcqRel); + if old_depth + 1 > self.inner.max_depth.load(Ordering::Acquire) { + self.inner.max_depth.fetch_add(1, Ordering::AcqRel); + } + } + fn exit(&self, _span: &Id) { + self.inner.current_depth.fetch_sub(1, Ordering::AcqRel); + } + } + + #[test] + fn tracing() { + // Create the future outside of the subscriber, as no call to tracing + // should be made until the future is polled. + let mut struct_impl = Impl(0); + let fut = struct_impl.foo(5); + let subscriber = TestSubscriber::new(); + subscriber::with_default(subscriber.clone(), || executor::block_on_simple(fut)); + // Did we enter bar inside of foo? + assert_eq!(subscriber.inner.max_depth.load(Ordering::Acquire), 2); + // Have we exited all spans? + assert_eq!(subscriber.inner.current_depth.load(Ordering::Acquire), 0); + // Did we create only two spans? Note: spans start at 1, hence the -1. + assert_eq!(subscriber.inner.max_span_id.load(Ordering::Acquire) - 1, 2); + // Was the value recorded at the right depth i.e. in the right function? + // If so, was it the expected value? + assert_eq!(*subscriber.inner.value.lock().unwrap(), Some(("val", 5, 2))); + } +} + +// https://github.com/dtolnay/async-trait/issues/46 +pub mod issue46 { + use async_trait::async_trait; + + macro_rules! implement_commands_workaround { + ($tyargs:tt : $ty:tt) => { + #[async_trait] + pub trait AsyncCommands1: Sized { + async fn f<$tyargs: $ty>(&mut self, x: $tyargs) { + self.f(x).await + } + } + }; + } + + implement_commands_workaround!(K: Send); + + macro_rules! implement_commands { + ($tyargs:ident : $ty:ident) => { + #[async_trait] + pub trait AsyncCommands2: Sized { + async fn f<$tyargs: $ty>(&mut self, x: $tyargs) { + self.f(x).await + } + } + }; + } + + implement_commands!(K: Send); +} + +// https://github.com/dtolnay/async-trait/issues/53 +pub mod issue53 { + use async_trait::async_trait; + + pub struct Unit; + pub struct Tuple(u8); + pub struct Struct { + pub x: u8, + } + + #[async_trait] + pub trait Trait { + async fn method(); + } + + #[async_trait] + impl Trait for Unit { + async fn method() { + let _ = Self; + } + } + + #[async_trait] + impl Trait for Tuple { + async fn method() { + let _ = Self(0); + } + } + + #[async_trait] + impl Trait for Struct { + async fn method() { + let _ = Self { x: 0 }; + } + } + + #[async_trait] + impl Trait for std::marker::PhantomData { + async fn method() { + let _ = Self; + } + } +} + +// https://github.com/dtolnay/async-trait/issues/57 +#[cfg(async_trait_nightly_testing)] +pub mod issue57 { + use crate::executor; + use async_trait::async_trait; + + #[async_trait] + trait Trait { + async fn const_generic(_: [T; C]) {} + } + + struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn const_generic(_: [T; C]) {} + } + + #[test] + fn test() { + let fut = Struct::const_generic([0; 10]); + executor::block_on_simple(fut); + } +} + +// https://github.com/dtolnay/async-trait/issues/68 +pub mod issue68 { + #[async_trait::async_trait] + pub trait Example { + async fn method(&self) { + macro_rules! t { + () => {{ + let _: &Self = self; + }}; + } + t!(); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/73 +pub mod issue73 { + use async_trait::async_trait; + + #[async_trait] + pub trait Example { + const ASSOCIATED: &'static str; + + async fn associated(&self) { + println!("Associated:{}", Self::ASSOCIATED); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/81 +pub mod issue81 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn handle(&self); + } + + pub enum Enum { + Variant, + } + + #[async_trait] + impl Trait for Enum { + async fn handle(&self) { + let Enum::Variant = self; + let Self::Variant = self; + } + } +} + +// https://github.com/dtolnay/async-trait/issues/83 +pub mod issue83 { + #![allow(clippy::needless_arbitrary_self_type)] + + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn f(&self) {} + async fn g(self: &Self) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/85 +pub mod issue85 { + #![deny(non_snake_case)] + + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + #[allow(non_snake_case)] + async fn camelCase(); + } + + pub struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn camelCase() {} + } +} + +// https://github.com/dtolnay/async-trait/issues/87 +pub mod issue87 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn f(&self); + } + + pub enum Tuple { + V(), + } + + pub enum Struct { + V {}, + } + + #[async_trait] + impl Trait for Tuple { + async fn f(&self) { + let Tuple::V() = self; + let Self::V() = self; + let _ = Self::V; + let _ = Self::V(); + } + } + + #[async_trait] + impl Trait for Struct { + async fn f(&self) { + let Struct::V {} = self; + let Self::V {} = self; + let _ = Self::V {}; + } + } +} + +// https://github.com/dtolnay/async-trait/issues/89 +pub mod issue89 { + #![allow(bare_trait_objects)] + + use async_trait::async_trait; + + #[async_trait] + trait Trait { + async fn f(&self); + } + + #[async_trait] + impl Trait for dyn Send + Sync { + async fn f(&self) {} + } + + #[async_trait] + impl Trait for dyn Fn(i8) + Send + Sync { + async fn f(&self) {} + } + + #[async_trait] + impl Trait for (dyn Fn(u8) + Send + Sync) { + async fn f(&self) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/92 +pub mod issue92 { + use async_trait::async_trait; + + macro_rules! mac { + ($($tt:tt)*) => { + $($tt)* + }; + } + + pub struct Struct { + _x: T, + } + + impl Struct { + const ASSOCIATED1: &'static str = "1"; + async fn associated1() {} + } + + #[async_trait] + pub trait Trait + where + mac!(Self): Send, + { + const ASSOCIATED2: &'static str; + type Associated2; + + #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)] + async fn associated2(&self) { + // trait items + mac!(let _: Self::Associated2;); + mac!(let _: ::Associated2;); + mac!(let _: ::Associated2;); + mac!(Self::ASSOCIATED2;); + mac!(::ASSOCIATED2;); + mac!(::ASSOCIATED2;); + mac!(let _ = Self::associated2(self);); + mac!(let _ = ::associated2(self);); + mac!(let _ = ::associated2(self);); + } + } + + #[async_trait] + impl Trait for Struct + where + mac!(Self): Send, + { + const ASSOCIATED2: &'static str = "2"; + type Associated2 = (); + + #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)] + async fn associated2(&self) { + // inherent items + mac!(Self::ASSOCIATED1;); + mac!(::ASSOCIATED1;); + mac!(let _ = Self::associated1();); + mac!(let _ = ::associated1();); + + // trait items + mac!(let (): ::Associated2;); + mac!(Self::ASSOCIATED2;); + mac!(::ASSOCIATED2;); + mac!(::ASSOCIATED2;); + mac!(let _ = Self::associated2(self);); + mac!(let _ = ::associated2(self);); + mac!(let _ = ::associated2(self);); + } + } + + pub struct Unit; + + #[async_trait] + impl Trait for Unit { + const ASSOCIATED2: &'static str = "2"; + type Associated2 = (); + + async fn associated2(&self) { + mac!(let Self: Self = *self;); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/92#issuecomment-683370136 +pub mod issue92_2 { + use async_trait::async_trait; + + macro_rules! mac { + ($($tt:tt)*) => { + $($tt)* + }; + } + + pub trait Trait1 { + fn func1(); + } + + #[async_trait] + pub trait Trait2: Trait1 { + async fn func2() { + mac!(Self::func1()); + + macro_rules! mac2 { + ($($tt:tt)*) => { + Self::func1(); + }; + } + mac2!(); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/104 +pub mod issue104 { + use async_trait::async_trait; + + #[async_trait] + trait T1 { + async fn id(&self) -> i32; + } + + macro_rules! impl_t1 { + ($ty:ty, $id:expr) => { + #[async_trait] + impl T1 for $ty { + async fn id(&self) -> i32 { + $id + } + } + }; + } + + struct Foo; + + impl_t1!(Foo, 1); +} + +// https://github.com/dtolnay/async-trait/issues/106 +pub mod issue106 { + use async_trait::async_trait; + use std::future::Future; + + #[async_trait] + pub trait ProcessPool: Send + Sync { + type ThreadPool; + + async fn spawn(&self, work: F) -> T + where + F: FnOnce(&Self::ThreadPool) -> Fut + Send, + Fut: Future + 'static; + } + + #[async_trait] + impl

ProcessPool for &P + where + P: ?Sized + ProcessPool, + { + type ThreadPool = P::ThreadPool; + + async fn spawn(&self, work: F) -> T + where + F: FnOnce(&Self::ThreadPool) -> Fut + Send, + Fut: Future + 'static, + { + (**self).spawn(work).await + } + } +} + +// https://github.com/dtolnay/async-trait/issues/110 +pub mod issue110 { + use async_trait::async_trait; + use std::marker::PhantomData; + + #[async_trait] + pub trait Loader { + async fn load(&self, key: &str); + } + + pub struct AwsEc2MetadataLoader<'a> { + marker: PhantomData<&'a ()>, + } + + #[async_trait] + impl Loader for AwsEc2MetadataLoader<'_> { + async fn load(&self, _key: &str) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/120 +pub mod issue120 { + #![deny(clippy::trivially_copy_pass_by_ref)] + + use async_trait::async_trait; + + #[async_trait] + trait Trait { + async fn f(&self); + } + + #[async_trait] + impl Trait for () { + async fn f(&self) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/123 +pub mod issue123 { + use async_trait::async_trait; + + #[async_trait] + trait Trait { + async fn f(&self) -> &str + where + T: 'async_trait, + { + "default" + } + } + + #[async_trait] + impl Trait for () {} +} + +// https://github.com/dtolnay/async-trait/issues/129 +pub mod issue129 { + use async_trait::async_trait; + + #[async_trait] + pub trait TestTrait { + async fn a(_b: u8, c: u8) -> u8 { + c + } + } + + pub struct TestStruct; + + #[async_trait] + impl TestTrait for TestStruct { + async fn a(_b: u8, c: u8) -> u8 { + c + } + } +} + +// https://github.com/dtolnay/async-trait/issues/134 +#[cfg(async_trait_nightly_testing)] +pub mod issue134 { + use async_trait::async_trait; + + #[async_trait] + trait TestTrait { + async fn run(self) + where + Self: Sized, + { + } + } + + pub struct TestStruct; + + #[async_trait] + impl TestTrait for TestStruct { + async fn run(self) + where + Self: Sized, + { + } + } +} + +// https://github.com/dtolnay/async-trait/pull/125#pullrequestreview-491880881 +pub mod drop_order { + use crate::executor; + use async_trait::async_trait; + use std::sync::atomic::{AtomicBool, Ordering}; + + struct Flagger<'a>(&'a AtomicBool); + + impl Drop for Flagger<'_> { + fn drop(&mut self) { + self.0.fetch_xor(true, Ordering::AcqRel); + } + } + + #[async_trait] + trait Trait { + async fn async_trait(_: Flagger<'_>, flag: &AtomicBool); + } + + struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn async_trait(_: Flagger<'_>, flag: &AtomicBool) { + flag.fetch_or(true, Ordering::AcqRel); + } + } + + async fn standalone(_: Flagger<'_>, flag: &AtomicBool) { + flag.fetch_or(true, Ordering::AcqRel); + } + + #[async_trait] + trait SelfTrait { + async fn async_trait(self, flag: &AtomicBool); + } + + #[async_trait] + impl SelfTrait for Flagger<'_> { + async fn async_trait(self, flag: &AtomicBool) { + flag.fetch_or(true, Ordering::AcqRel); + } + } + + #[test] + fn test_drop_order() { + // 0 : 0 ^ 1 = 1 | 1 = 1 (if flagger then block) + // 0 : 0 | 1 = 1 ^ 1 = 0 (if block then flagger) + + let flag = AtomicBool::new(false); + executor::block_on_simple(standalone(Flagger(&flag), &flag)); + assert!(!flag.load(Ordering::Acquire)); + + executor::block_on_simple(Struct::async_trait(Flagger(&flag), &flag)); + assert!(!flag.load(Ordering::Acquire)); + + executor::block_on_simple(Flagger(&flag).async_trait(&flag)); + assert!(!flag.load(Ordering::Acquire)); + } +} + +// https://github.com/dtolnay/async-trait/issues/145 +pub mod issue145 { + #![deny(clippy::type_complexity)] + + use async_trait::async_trait; + + #[async_trait] + pub trait ManageConnection: Sized + Send + Sync + 'static { + type Connection: Send + 'static; + type Error: Send + 'static; + + async fn connect(&self) -> Result; + } +} + +// https://github.com/dtolnay/async-trait/issues/147 +pub mod issue147 { + #![deny(clippy::let_unit_value)] + + use async_trait::async_trait; + + pub struct MyType; + + #[async_trait] + pub trait MyTrait { + async fn x(); + async fn y() -> (); + async fn z(); + } + + #[async_trait] + impl MyTrait for MyType { + async fn x() {} + async fn y() -> () {} + async fn z() { + unimplemented!() + } + } +} + +// https://github.com/dtolnay/async-trait/issues/149 +pub mod issue149 { + use async_trait::async_trait; + + pub struct Thing; + pub trait Ret {} + impl Ret for Thing {} + + pub async fn ok() -> &'static dyn Ret { + return &Thing; + } + + #[async_trait] + pub trait Trait { + async fn fail() -> &'static dyn Ret { + return &Thing; + } + } +} + +// https://github.com/dtolnay/async-trait/issues/152 +#[cfg(async_trait_nightly_testing)] +pub mod issue152 { + use async_trait::async_trait; + + #[async_trait] + trait Trait { + type Assoc; + + async fn f(&self) -> Self::Assoc; + } + + struct Struct; + + #[async_trait] + impl Trait for Struct { + type Assoc = impl Sized; + + async fn f(&self) -> Self::Assoc {} + } +} + +// https://github.com/dtolnay/async-trait/issues/154 +pub mod issue154 { + #![deny(clippy::items_after_statements)] + + use async_trait::async_trait; + + #[async_trait] + pub trait MyTrait { + async fn f(&self); + } + + pub struct Struct; + + #[async_trait] + impl MyTrait for Struct { + async fn f(&self) { + const MAX: u16 = 128; + println!("{}", MAX); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/158 +pub mod issue158 { + use async_trait::async_trait; + + fn f() {} + + #[async_trait] + pub trait Trait { + async fn f(&self) { + self::f(); + } + } +} + +// https://github.com/dtolnay/async-trait/issues/161 +#[allow(clippy::mut_mut)] +pub mod issue161 { + use async_trait::async_trait; + use futures::future::FutureExt; + use std::sync::Arc; + + #[async_trait] + pub trait Trait { + async fn f(self: Arc); + } + + pub struct MyStruct(bool); + + #[async_trait] + impl Trait for MyStruct { + async fn f(self: Arc) { + futures::select! { + () = async { + println!("{}", self.0); + }.fuse() => {} + } + } + } +} + +// https://github.com/dtolnay/async-trait/issues/169 +#[deny(where_clauses_object_safety)] +pub mod issue169 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait: ::core::marker::Sync { + async fn f(&self) {} + } + + pub fn test(_t: &dyn Trait) {} +} + +// https://github.com/dtolnay/async-trait/issues/177 +pub mod issue177 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn foo(&self, _callback: impl FnMut(&str) + Send) {} + } + + pub struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn foo(&self, _callback: impl FnMut(&str) + Send) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/183 +pub mod issue183 { + #![deny(clippy::shadow_same)] + + use async_trait::async_trait; + + #[async_trait] + trait Foo { + async fn foo(_n: i32) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/199 +pub mod issue199 { + use async_trait::async_trait; + use std::cell::Cell; + + struct IncrementOnDrop<'a>(&'a Cell); + + impl<'a> Drop for IncrementOnDrop<'a> { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } + } + + #[async_trait(?Send)] + trait Trait { + async fn f(counter: &Cell, arg: IncrementOnDrop<'_>); + } + + struct Struct; + + #[async_trait(?Send)] + impl Trait for Struct { + async fn f(counter: &Cell, _: IncrementOnDrop<'_>) { + assert_eq!(counter.get(), 0); // second arg not dropped yet + } + } + + #[test] + fn test() { + let counter = Cell::new(0); + let future = Struct::f(&counter, IncrementOnDrop(&counter)); + assert_eq!(counter.get(), 0); + drop(future); + assert_eq!(counter.get(), 1); + } +} + +// https://github.com/dtolnay/async-trait/issues/204 +pub mod issue204 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn f(arg: &impl Trait); + async fn g(arg: *const impl Trait); + } +} + +// https://github.com/dtolnay/async-trait/issues/210 +pub mod issue210 { + use async_trait::async_trait; + use std::sync::Arc; + + #[async_trait] + pub trait Trait { + async fn f(self: Arc) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/226 +pub mod issue226 { + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn cfg_param(&self, param: u8); + async fn cfg_param_wildcard(&self, _: u8); + async fn cfg_param_tuple(&self, (left, right): (u8, u8)); + } + + struct Struct; + + #[async_trait] + impl Trait for Struct { + async fn cfg_param(&self, #[cfg(any())] param: u8, #[cfg(all())] _unused: u8) {} + + async fn cfg_param_wildcard(&self, #[cfg(any())] _: u8, #[cfg(all())] _: u8) {} + + async fn cfg_param_tuple( + &self, + #[cfg(any())] (left, right): (u8, u8), + #[cfg(all())] (_left, _right): (u8, u8), + ) { + } + } +} + +// https://github.com/dtolnay/async-trait/issues/232 +pub mod issue232 { + use async_trait::async_trait; + + #[async_trait] + pub trait Generic { + async fn take_ref(&self, thing: &T); + } + + pub struct One; + + #[async_trait] + impl Generic for One { + async fn take_ref(&self, _: &T) {} + } + + pub struct Two; + + #[async_trait] + impl Generic<(T, T)> for Two { + async fn take_ref(&self, (a, b): &(T, T)) { + let _ = a; + let _ = b; + } + } + + pub struct Three; + + #[async_trait] + impl Generic<(T, T, T)> for Three { + async fn take_ref(&self, (_a, _b, _c): &(T, T, T)) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/234 +pub mod issue234 { + use async_trait::async_trait; + + pub struct Droppable; + + impl Drop for Droppable { + fn drop(&mut self) {} + } + + pub struct Tuple(T, U); + + #[async_trait] + pub trait Trait { + async fn f(arg: Tuple); + } + + pub struct UnderscorePattern; + + #[async_trait] + impl Trait for UnderscorePattern { + async fn f(Tuple(_, _int): Tuple) {} + } + + pub struct DotDotPattern; + + #[async_trait] + impl Trait for DotDotPattern { + async fn f(Tuple { 1: _int, .. }: Tuple) {} + } +} + +// https://github.com/dtolnay/async-trait/issues/236 +pub mod issue236 { + #![deny(clippy::async_yields_async)] + #![allow(clippy::manual_async_fn)] + + use async_trait::async_trait; + use std::future::{self, Future, Ready}; + + // Does not trigger the lint. + pub async fn async_fn() -> Ready<()> { + future::ready(()) + } + + #[allow(clippy::async_yields_async)] + pub fn impl_future_fn() -> impl Future> { + async { future::ready(()) } + } + + // The async_trait attribute turns the former into the latter, so we make it + // put its own allow(async_yeilds_async) to remain consistent with async fn. + #[async_trait] + pub trait Trait { + async fn f() -> Ready<()> { + future::ready(()) + } + } +} + +// https://github.com/dtolnay/async-trait/issues/238 +pub mod issue238 { + #![deny(single_use_lifetimes)] + + use async_trait::async_trait; + + #[async_trait] + pub trait Trait { + async fn f(); + } + + pub struct Struct; + + #[async_trait] + impl Trait for &Struct { + async fn f() {} + } +} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.rs new file mode 100644 index 00000000..b83aa72f --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.rs @@ -0,0 +1,22 @@ +use async_trait::async_trait; + +pub struct Struct; + +#[async_trait] +pub trait Trait { + async fn f((_a, _b): (Struct, Struct)) { + // Expands to something like: + // + // fn f(__arg0: (Struct, Struct)) -> … { + // Box::pin(async move { + // let (_a, _b) = __arg0; + // … + // }) + // } + // + // but user's code must not be allowed to name that temporary argument: + let _ = __arg0; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.stderr new file mode 100644 index 00000000..e7426888 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/arg-implementation-detail.stderr @@ -0,0 +1,5 @@ +error[E0425]: cannot find value `__arg0` in this scope + --> tests/ui/arg-implementation-detail.rs:18:17 + | +18 | let _ = __arg0; + | ^^^^^^ not found in this scope diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.rs new file mode 100644 index 00000000..afcd6b44 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.rs @@ -0,0 +1,15 @@ +#![deny(bare_trait_objects)] + +use async_trait::async_trait; + +#[async_trait] +trait Trait { + async fn f(&self); +} + +#[async_trait] +impl Trait for Send + Sync { + async fn f(&self) {} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.stderr new file mode 100644 index 00000000..7ff6af12 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/bare-trait-object.stderr @@ -0,0 +1,14 @@ +error[E0782]: trait objects must include the `dyn` keyword + --> tests/ui/bare-trait-object.rs:11:16 + | +11 | impl Trait for Send + Sync { + | ^^^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +11 | impl Trait for dyn Send + Sync { + | +++ +help: alternatively use a blanket implementation to implement `Trait` for all types that also implement `Send + Sync` + | +11 | impl Trait for T { + | ++++++++++++++++ ~ diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.rs new file mode 100644 index 00000000..e23c8b15 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.rs @@ -0,0 +1,26 @@ +// https://github.com/rust-lang/rust/issues/93828 + +use async_trait::async_trait; + +pub trait IntoUrl {} + +#[async_trait] +pub trait ClientExt { + async fn publish(&self, url: T); +} + +struct Client; + +#[async_trait] +impl ClientExt for Client { + async fn publish(&self, url: T) {} +} + +struct Client2; + +#[async_trait] +impl ClientExt for Client2 { + async fn publish(&self, url: T) {} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.stderr new file mode 100644 index 00000000..66e96371 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/consider-restricting.stderr @@ -0,0 +1,33 @@ +error: future cannot be sent between threads safely + --> tests/ui/consider-restricting.rs:16:49 + | +16 | async fn publish(&self, url: T) {} + | ^^ future created by async block is not `Send` + | +note: captured value is not `Send` + --> tests/ui/consider-restricting.rs:16:41 + | +16 | async fn publish(&self, url: T) {} + | ^^^ has type `T` which is not `Send` + = note: required for the cast from `Pin>` to `Pin + Send + 'async_trait)>>` +help: consider further restricting this bound + | +16 | async fn publish(&self, url: T) {} + | +++++++++++++++++++ + +error: future cannot be sent between threads safely + --> tests/ui/consider-restricting.rs:23:40 + | +23 | async fn publish(&self, url: T) {} + | ^^ future created by async block is not `Send` + | +note: captured value is not `Send` + --> tests/ui/consider-restricting.rs:23:32 + | +23 | async fn publish(&self, url: T) {} + | ^^^ has type `T` which is not `Send` + = note: required for the cast from `Pin>` to `Pin + Send + 'async_trait)>>` +help: consider further restricting this bound + | +23 | async fn publish(&self, url: T) {} + | +++++++++++++++++++ diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.rs new file mode 100644 index 00000000..51a44a24 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.rs @@ -0,0 +1,24 @@ +#![allow(unused_macro_rules)] + +use async_trait::async_trait; + +macro_rules! picky { + ($(t:tt)*) => {}; +} + +#[async_trait] +trait Trait { + async fn method(); +} + +struct Struct; + +#[async_trait] +impl Trait for Struct { + async fn method() { + picky!({ 123, self }); + picky!({ 123 }); + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.stderr new file mode 100644 index 00000000..f03da4c9 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/delimiter-span.stderr @@ -0,0 +1,21 @@ +error: no rules expected the token `{` + --> tests/ui/delimiter-span.rs:19:16 + | +5 | macro_rules! picky { + | ------------------ when calling this macro +... +19 | picky!({ 123, self }); + | ^ no rules expected this token in macro call + | + = note: while trying to match sequence start + +error: no rules expected the token `{` + --> tests/ui/delimiter-span.rs:20:16 + | +5 | macro_rules! picky { + | ------------------ when calling this macro +... +20 | picky!({ 123 }); + | ^ no rules expected this token in macro call + | + = note: while trying to match sequence start diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.rs new file mode 100644 index 00000000..237cf667 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.rs @@ -0,0 +1,23 @@ +use async_trait::async_trait; + +#[async_trait] +trait Foo { + async fn bar(&self, x: &str, y: &'_ str) -> &'static str; +} + +struct S(String); + +#[async_trait] +impl Foo for S { + async fn bar(&self, x: &str, y: &'_ str) -> &'static str { + if false { + &self.0 + } else if false { + x + } else { + y + } + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.stderr new file mode 100644 index 00000000..9ffef5b4 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-defined-here.stderr @@ -0,0 +1,29 @@ +error: lifetime may not live long enough + --> tests/ui/lifetime-defined-here.rs:12:49 + | +12 | async fn bar(&self, x: &str, y: &'_ str) -> &'static str { + | - ^^^^^^^^^^^^ type annotation requires that `'life0` must outlive `'static` + | | + | lifetime `'life0` defined here + +error: lifetime may not live long enough + --> tests/ui/lifetime-defined-here.rs:12:49 + | +12 | async fn bar(&self, x: &str, y: &'_ str) -> &'static str { + | - ^^^^^^^^^^^^ type annotation requires that `'life1` must outlive `'static` + | | + | lifetime `'life1` defined here + +error: lifetime may not live long enough + --> tests/ui/lifetime-defined-here.rs:12:49 + | +12 | async fn bar(&self, x: &str, y: &'_ str) -> &'static str { + | -- ^^^^^^^^^^^^ type annotation requires that `'life2` must outlive `'static` + | | + | lifetime `'life2` defined here + +help: the following changes may resolve your lifetime errors + | + = help: replace `'life0` with `'static` + = help: replace `'life1` with `'static` + = help: replace `'life2` with `'static` diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.rs new file mode 100644 index 00000000..01981e6d --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.rs @@ -0,0 +1,36 @@ +use async_trait::async_trait; + +struct A; +struct B; + +#[async_trait] +pub trait Trait<'r> { + async fn method(&'r self); +} + +#[async_trait] +impl Trait for A { + async fn method(&self) {} +} + +#[async_trait] +impl<'r> Trait<'r> for B { + async fn method(&self) {} +} + +#[async_trait] +pub trait Trait2 { + async fn method<'r>(&'r self); +} + +#[async_trait] +impl Trait2 for A { + async fn method(&self) {} +} + +#[async_trait] +impl<'r> Trait2<'r> for B { + async fn method(&'r self) {} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.stderr new file mode 100644 index 00000000..fa16ac7e --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/lifetime-span.stderr @@ -0,0 +1,24 @@ +error[E0726]: implicit elided lifetime not allowed here + --> tests/ui/lifetime-span.rs:12:6 + | +12 | impl Trait for A { + | ^^^^^ expected lifetime parameter + | +help: indicate the anonymous lifetime + | +12 | impl Trait<'_> for A { + | ++++ + +error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied + --> tests/ui/lifetime-span.rs:32:10 + | +32 | impl<'r> Trait2<'r> for B { + | ^^^^^^---- help: remove these generics + | | + | expected 0 lifetime arguments + | +note: trait defined here, with 0 lifetime parameters + --> tests/ui/lifetime-span.rs:22:11 + | +22 | pub trait Trait2 { + | ^^^^^^ diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.rs new file mode 100644 index 00000000..3a5f58c3 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.rs @@ -0,0 +1,15 @@ +use async_trait::async_trait; + +#[async_trait] +pub trait Trait { + async fn method(); +} + +pub struct Struct; + +#[async_trait] +impl Trait for Struct { + fn method() {} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.stderr new file mode 100644 index 00000000..e461c85d --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-impl.stderr @@ -0,0 +1,8 @@ +error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration + --> tests/ui/missing-async-in-impl.rs:12:14 + | +5 | async fn method(); + | -------- lifetimes in impl do not match this method in trait +... +12 | fn method() {} + | ^ lifetimes do not match method in trait diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.rs new file mode 100644 index 00000000..56fea7a1 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.rs @@ -0,0 +1,15 @@ +use async_trait::async_trait; + +#[async_trait] +pub trait Trait { + fn method(); +} + +pub struct Struct; + +#[async_trait] +impl Trait for Struct { + async fn method() {} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.stderr new file mode 100644 index 00000000..c92c38da --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-async-in-trait.stderr @@ -0,0 +1,8 @@ +error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration + --> tests/ui/missing-async-in-trait.rs:12:14 + | +5 | fn method(); + | - lifetimes in impl do not match this method in trait +... +12 | async fn method() {} + | ^^^^^^^^ lifetimes do not match method in trait diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.rs new file mode 100644 index 00000000..f3e1126d --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.rs @@ -0,0 +1,15 @@ +use async_trait::async_trait; + +#[async_trait] +trait Trait { + async fn f(&self); +} + +struct Thing; + +#[async_trait] +impl Trait for Thing { + async fn f(&self); +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.stderr new file mode 100644 index 00000000..e6ddb425 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/missing-body.stderr @@ -0,0 +1,7 @@ +error: associated function in `impl` without body + --> tests/ui/missing-body.rs:12:5 + | +12 | async fn f(&self); + | ^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the function: `{ }` diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/must-use.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/must-use.rs new file mode 100644 index 00000000..7ad0d9bf --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/must-use.rs @@ -0,0 +1,21 @@ +#![deny(unused_must_use)] + +use async_trait::async_trait; + +#[async_trait] +trait Interface { + async fn f(&self); +} + +struct Thing; + +#[async_trait] +impl Interface for Thing { + async fn f(&self) {} +} + +pub async fn f() { + Thing.f(); +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/must-use.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/must-use.stderr new file mode 100644 index 00000000..79e0a7a2 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/must-use.stderr @@ -0,0 +1,23 @@ +error: unused pinned boxed `Future` trait object that must be used + --> tests/ui/must-use.rs:18:5 + | +18 | Thing.f(); + | ^^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them +note: the lint level is defined here + --> tests/ui/must-use.rs:1:9 + | +1 | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: unused return value of `Interface::f` that must be used + --> tests/ui/must-use.rs:18:5 + | +18 | Thing.f(); + | ^^^^^^^^^ + | +help: use `let _ = ...` to ignore the resulting value + | +18 | let _ = Thing.f(); + | +++++++ diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.rs new file mode 100644 index 00000000..c0fb431b --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.rs @@ -0,0 +1,13 @@ +pub trait Trait { + async fn method(&self); +} + +pub struct Struct; + +impl Trait for Struct { + async fn method(&self) {} +} + +fn main() { + let _: &dyn Trait; +} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.stderr new file mode 100644 index 00000000..cb15522b --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/no-attribute-macro.stderr @@ -0,0 +1,16 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> tests/ui/no-attribute-macro.rs:12:12 + | +12 | let _: &dyn Trait; + | ^^^^^^^^^^ `Trait` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> tests/ui/no-attribute-macro.rs:2:14 + | +1 | pub trait Trait { + | ----- this trait cannot be made into an object... +2 | async fn method(&self); + | ^^^^^^ ...because method `method` is `async` + = help: consider moving `method` to another trait + = help: only type `Struct` is seen to implement the trait in this crate, consider using it directly instead + = note: `Trait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/self-span.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/self-span.rs new file mode 100644 index 00000000..b01f2470 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/self-span.rs @@ -0,0 +1,30 @@ +use async_trait::async_trait; + +pub struct S {} + +pub enum E { + V {}, +} + +#[async_trait] +pub trait Trait { + async fn method(self); +} + +#[async_trait] +impl Trait for S { + async fn method(self) { + let _: () = self; + let _: Self = Self; + } +} + +#[async_trait] +impl Trait for E { + async fn method(self) { + let _: () = self; + let _: Self = Self::V; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/self-span.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/self-span.stderr new file mode 100644 index 00000000..04493f89 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/self-span.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> tests/ui/self-span.rs:17:21 + | +17 | let _: () = self; + | -- ^^^^ expected `()`, found `S` + | | + | expected due to this + +error: the `Self` constructor can only be used with tuple or unit structs + --> tests/ui/self-span.rs:18:23 + | +18 | let _: Self = Self; + | ^^^^ help: use curly brackets: `Self { /* fields */ }` + +error[E0308]: mismatched types + --> tests/ui/self-span.rs:25:21 + | +25 | let _: () = self; + | -- ^^^^ expected `()`, found `E` + | | + | expected due to this + +error[E0533]: expected value, found struct variant `Self::V` + --> tests/ui/self-span.rs:26:23 + | +26 | let _: Self = Self::V; + | ^^^^^^^ not a value diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.rs new file mode 100644 index 00000000..d8883fb4 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.rs @@ -0,0 +1,22 @@ +use async_trait::async_trait; +use std::sync::Mutex; + +async fn f() {} + +#[async_trait] +trait Test { + async fn test(&self) { + let mutex = Mutex::new(()); + let _guard = mutex.lock().unwrap(); + f().await; + } + + async fn test_ret(&self) -> bool { + let mutex = Mutex::new(()); + let _guard = mutex.lock().unwrap(); + f().await; + true + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.stderr new file mode 100644 index 00000000..7152b98f --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/send-not-implemented.stderr @@ -0,0 +1,42 @@ +error: future cannot be sent between threads safely + --> tests/ui/send-not-implemented.rs:8:26 + | +8 | async fn test(&self) { + | __________________________^ +9 | | let mutex = Mutex::new(()); +10 | | let _guard = mutex.lock().unwrap(); +11 | | f().await; +12 | | } + | |_____^ future created by async block is not `Send` + | + = help: within `{async block@$DIR/tests/ui/send-not-implemented.rs:8:26: 12:6}`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` +note: future is not `Send` as this value is used across an await + --> tests/ui/send-not-implemented.rs:11:13 + | +10 | let _guard = mutex.lock().unwrap(); + | ------ has type `MutexGuard<'_, ()>` which is not `Send` +11 | f().await; + | ^^^^^ await occurs here, with `_guard` maybe used later + = note: required for the cast from `Pin>` to `Pin + Send>>` + +error: future cannot be sent between threads safely + --> tests/ui/send-not-implemented.rs:14:38 + | +14 | async fn test_ret(&self) -> bool { + | ______________________________________^ +15 | | let mutex = Mutex::new(()); +16 | | let _guard = mutex.lock().unwrap(); +17 | | f().await; +18 | | true +19 | | } + | |_____^ future created by async block is not `Send` + | + = help: within `{async block@$DIR/tests/ui/send-not-implemented.rs:14:38: 19:6}`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` +note: future is not `Send` as this value is used across an await + --> tests/ui/send-not-implemented.rs:17:13 + | +16 | let _guard = mutex.lock().unwrap(); + | ------ has type `MutexGuard<'_, ()>` which is not `Send` +17 | f().await; + | ^^^^^ await occurs here, with `_guard` maybe used later + = note: required for the cast from `Pin>` to `Pin + Send>>` diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.rs new file mode 100644 index 00000000..cac28264 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.rs @@ -0,0 +1,20 @@ +#![deny(warnings)] + +use async_trait::async_trait; + +#[async_trait] +pub trait Trait { + async fn f() { + unimplemented!() + } +} + +#[async_trait] +pub trait TraitFoo { + async fn f() { + let _y = unimplemented!(); + let _z = _y; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.stderr new file mode 100644 index 00000000..08595e5a --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/unreachable.stderr @@ -0,0 +1,14 @@ +error: unreachable statement + --> tests/ui/unreachable.rs:16:9 + | +15 | let _y = unimplemented!(); + | ---------------- any code following this expression is unreachable +16 | let _z = _y; + | ^^^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> tests/ui/unreachable.rs:1:9 + | +1 | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unreachable_code)]` implied by `#[deny(warnings)]` diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.rs b/utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.rs new file mode 100644 index 00000000..5868c614 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.rs @@ -0,0 +1,15 @@ +use async_trait::async_trait; + +#[async_trait] +pub trait Trait { + async fn method(); +} + +#[async_trait] +impl Trait for &'static str { + async fn method() { + let _ = Self; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.stderr b/utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.stderr new file mode 100644 index 00000000..14939459 --- /dev/null +++ b/utshell-0.5.0/vendor/async-trait/tests/ui/unsupported-self.stderr @@ -0,0 +1,5 @@ +error: the `Self` constructor can only be used with tuple or unit structs + --> tests/ui/unsupported-self.rs:11:17 + | +11 | let _ = Self; + | ^^^^ diff --git a/utshell-0.5.0/vendor/autocfg/.cargo-checksum.json b/utshell-0.5.0/vendor/autocfg/.cargo-checksum.json new file mode 100644 index 00000000..e4cc3fc4 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"3d91565ed13de572a9ebde408a0c98e33f931d6ab52f212b0830a60b4ab26b77","Cargo.toml":"39f627122dceaad42146634719fde802fca3baa1b3908753af723074ae2a6d69","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"27995d58ad5c1145c1a8cd86244ce844886958a35eb2b78c6b772748669999ac","README.md":"4c8f9b5016f2a0c3dbeca5bc41241f57db5568f803e58c1fa480ae2b3638d0a9","examples/integers.rs":"589ff4271566dfa322becddf3e2c7b592e6e0bc97b02892ce75619b7e452e930","examples/paths.rs":"1b30e466b824ce8df7ad0a55334424131d9d2573d6cf9f7d5d50c09c8901d526","examples/traits.rs":"cbee6a3e1f7db60b02ae25b714926517144a77cb492021f492774cf0e1865a9e","examples/versions.rs":"38535e6d9f5bfae0de474a3db79a40e8f5da8ba9334c5ff4c363de9bc99d4d12","src/error.rs":"12de7dafea4a35d1dc2f0fa79bfa038386bbbea72bf083979f4ddf227999eeda","src/lib.rs":"6fa01458e8f9258d84f83ead24fdb0cdf9aec10838b0262f1dfbdf79c530c537","src/tests.rs":"f0e6dc1ad9223c0336c02e215ea3940acb2af6c3bc8fd791e16cd4e786e6a608","src/version.rs":"175727d5f02f2fe2271ddc9b041db2a5b9c6fe0f95afd17c73a4d982612764a3","tests/rustflags.rs":"5c8169b88216055019db61b5d7baf4abdf675e3b14b54f5037bb1e3acd0a5d3f"},"package":"d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/autocfg/Cargo.lock b/utshell-0.5.0/vendor/autocfg/Cargo.lock new file mode 100644 index 00000000..2b148536 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" diff --git a/utshell-0.5.0/vendor/autocfg/Cargo.toml b/utshell-0.5.0/vendor/autocfg/Cargo.toml new file mode 100644 index 00000000..f8bd64c0 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/Cargo.toml @@ -0,0 +1,24 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +name = "autocfg" +version = "1.1.0" +authors = ["Josh Stone "] +exclude = ["/.github/**", "/bors.toml"] +description = "Automatic cfg for Rust compiler features" +readme = "README.md" +keywords = ["rustc", "build", "autoconf"] +categories = ["development-tools::build-utils"] +license = "Apache-2.0 OR MIT" +repository = "https://github.com/cuviper/autocfg" + +[dependencies] diff --git a/utshell-0.5.0/vendor/autocfg/LICENSE-APACHE b/utshell-0.5.0/vendor/autocfg/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/autocfg/LICENSE-MIT b/utshell-0.5.0/vendor/autocfg/LICENSE-MIT new file mode 100644 index 00000000..44fbc4d8 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2018 Josh Stone + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/autocfg/README.md b/utshell-0.5.0/vendor/autocfg/README.md new file mode 100644 index 00000000..8c95696c --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/README.md @@ -0,0 +1,95 @@ +autocfg +======= + +[![autocfg crate](https://img.shields.io/crates/v/autocfg.svg)](https://crates.io/crates/autocfg) +[![autocfg documentation](https://docs.rs/autocfg/badge.svg)](https://docs.rs/autocfg) +![minimum rustc 1.0](https://img.shields.io/badge/rustc-1.0+-red.svg) +![build status](https://github.com/cuviper/autocfg/workflows/master/badge.svg) + +A Rust library for build scripts to automatically configure code based on +compiler support. Code snippets are dynamically tested to see if the `rustc` +will accept them, rather than hard-coding specific version support. + + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[build-dependencies] +autocfg = "1" +``` + +Then use it in your `build.rs` script to detect compiler features. For +example, to test for 128-bit integer support, it might look like: + +```rust +extern crate autocfg; + +fn main() { + let ac = autocfg::new(); + ac.emit_has_type("i128"); + + // (optional) We don't need to rerun for anything external. + autocfg::rerun_path("build.rs"); +} +``` + +If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line +for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the +rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that +should only be used when the compiler supports it. + + +## Release Notes + +- 1.1.0 (2022-02-07) + - Use `CARGO_ENCODED_RUSTFLAGS` when it is set. + +- 1.0.1 (2020-08-20) + - Apply `RUSTFLAGS` for more `--target` scenarios, by @adamreichold. + +- 1.0.0 (2020-01-08) + - 🎉 Release 1.0! 🎉 (no breaking changes) + - Add `probe_expression` and `emit_expression_cfg` to test arbitrary expressions. + - Add `probe_constant` and `emit_constant_cfg` to test arbitrary constant expressions. + +- 0.1.7 (2019-10-20) + - Apply `RUSTFLAGS` when probing `$TARGET != $HOST`, mainly for sysroot, by @roblabla. + +- 0.1.6 (2019-08-19) + - Add `probe`/`emit_sysroot_crate`, by @leo60228. + +- 0.1.5 (2019-07-16) + - Mask some warnings from newer rustc. + +- 0.1.4 (2019-05-22) + - Relax `std`/`no_std` probing to a warning instead of an error. + - Improve `rustc` bootstrap compatibility. + +- 0.1.3 (2019-05-21) + - Auto-detects if `#![no_std]` is needed for the `$TARGET`. + +- 0.1.2 (2019-01-16) + - Add `rerun_env(ENV)` to print `cargo:rerun-if-env-changed=ENV`. + - Add `rerun_path(PATH)` to print `cargo:rerun-if-changed=PATH`. + + +## Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.0.0`. Compatibility is +its entire reason for existence, so this crate will be extremely conservative +about raising this requirement. If this is ever deemed necessary, it will be +treated as a major breaking change for semver purposes. + + +## License + +This project is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. diff --git a/utshell-0.5.0/vendor/autocfg/examples/integers.rs b/utshell-0.5.0/vendor/autocfg/examples/integers.rs new file mode 100644 index 00000000..23d4cba6 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/examples/integers.rs @@ -0,0 +1,9 @@ +extern crate autocfg; + +fn main() { + // Normally, cargo will set `OUT_DIR` for build scripts. + let ac = autocfg::AutoCfg::with_dir("target").unwrap(); + for i in 3..8 { + ac.emit_has_type(&format!("i{}", 1 << i)); + } +} diff --git a/utshell-0.5.0/vendor/autocfg/examples/paths.rs b/utshell-0.5.0/vendor/autocfg/examples/paths.rs new file mode 100644 index 00000000..b7a6ca7a --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/examples/paths.rs @@ -0,0 +1,22 @@ +extern crate autocfg; + +fn main() { + // Normally, cargo will set `OUT_DIR` for build scripts. + let ac = autocfg::AutoCfg::with_dir("target").unwrap(); + + // since ancient times... + ac.emit_has_path("std::vec::Vec"); + ac.emit_path_cfg("std::vec::Vec", "has_vec"); + + // rustc 1.10.0 + ac.emit_has_path("std::panic::PanicInfo"); + ac.emit_path_cfg("std::panic::PanicInfo", "has_panic_info"); + + // rustc 1.20.0 + ac.emit_has_path("std::mem::ManuallyDrop"); + ac.emit_path_cfg("std::mem::ManuallyDrop", "has_manually_drop"); + + // rustc 1.25.0 + ac.emit_has_path("std::ptr::NonNull"); + ac.emit_path_cfg("std::ptr::NonNull", "has_non_null"); +} diff --git a/utshell-0.5.0/vendor/autocfg/examples/traits.rs b/utshell-0.5.0/vendor/autocfg/examples/traits.rs new file mode 100644 index 00000000..c1ca0038 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/examples/traits.rs @@ -0,0 +1,26 @@ +extern crate autocfg; + +fn main() { + // Normally, cargo will set `OUT_DIR` for build scripts. + let ac = autocfg::AutoCfg::with_dir("target").unwrap(); + + // since ancient times... + ac.emit_has_trait("std::ops::Add"); + ac.emit_trait_cfg("std::ops::Add", "has_ops"); + + // trait parameters have to be provided + ac.emit_has_trait("std::borrow::Borrow"); + ac.emit_trait_cfg("std::borrow::Borrow", "has_borrow"); + + // rustc 1.8.0 + ac.emit_has_trait("std::ops::AddAssign"); + ac.emit_trait_cfg("std::ops::AddAssign", "has_assign_ops"); + + // rustc 1.12.0 + ac.emit_has_trait("std::iter::Sum"); + ac.emit_trait_cfg("std::iter::Sum", "has_sum"); + + // rustc 1.28.0 + ac.emit_has_trait("std::alloc::GlobalAlloc"); + ac.emit_trait_cfg("std::alloc::GlobalAlloc", "has_global_alloc"); +} diff --git a/utshell-0.5.0/vendor/autocfg/examples/versions.rs b/utshell-0.5.0/vendor/autocfg/examples/versions.rs new file mode 100644 index 00000000..992919b7 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/examples/versions.rs @@ -0,0 +1,9 @@ +extern crate autocfg; + +fn main() { + // Normally, cargo will set `OUT_DIR` for build scripts. + let ac = autocfg::AutoCfg::with_dir("target").unwrap(); + for i in 0..100 { + ac.emit_rustc_version(1, i); + } +} diff --git a/utshell-0.5.0/vendor/autocfg/src/error.rs b/utshell-0.5.0/vendor/autocfg/src/error.rs new file mode 100644 index 00000000..46248354 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/src/error.rs @@ -0,0 +1,69 @@ +use std::error; +use std::fmt; +use std::io; +use std::num; +use std::str; + +/// A common error type for the `autocfg` crate. +#[derive(Debug)] +pub struct Error { + kind: ErrorKind, +} + +impl error::Error for Error { + fn description(&self) -> &str { + "AutoCfg error" + } + + fn cause(&self) -> Option<&error::Error> { + match self.kind { + ErrorKind::Io(ref e) => Some(e), + ErrorKind::Num(ref e) => Some(e), + ErrorKind::Utf8(ref e) => Some(e), + ErrorKind::Other(_) => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match self.kind { + ErrorKind::Io(ref e) => e.fmt(f), + ErrorKind::Num(ref e) => e.fmt(f), + ErrorKind::Utf8(ref e) => e.fmt(f), + ErrorKind::Other(s) => s.fmt(f), + } + } +} + +#[derive(Debug)] +enum ErrorKind { + Io(io::Error), + Num(num::ParseIntError), + Utf8(str::Utf8Error), + Other(&'static str), +} + +pub fn from_io(e: io::Error) -> Error { + Error { + kind: ErrorKind::Io(e), + } +} + +pub fn from_num(e: num::ParseIntError) -> Error { + Error { + kind: ErrorKind::Num(e), + } +} + +pub fn from_utf8(e: str::Utf8Error) -> Error { + Error { + kind: ErrorKind::Utf8(e), + } +} + +pub fn from_str(s: &'static str) -> Error { + Error { + kind: ErrorKind::Other(s), + } +} diff --git a/utshell-0.5.0/vendor/autocfg/src/lib.rs b/utshell-0.5.0/vendor/autocfg/src/lib.rs new file mode 100644 index 00000000..cbe393a9 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/src/lib.rs @@ -0,0 +1,453 @@ +//! A Rust library for build scripts to automatically configure code based on +//! compiler support. Code snippets are dynamically tested to see if the `rustc` +//! will accept them, rather than hard-coding specific version support. +//! +//! +//! ## Usage +//! +//! Add this to your `Cargo.toml`: +//! +//! ```toml +//! [build-dependencies] +//! autocfg = "1" +//! ``` +//! +//! Then use it in your `build.rs` script to detect compiler features. For +//! example, to test for 128-bit integer support, it might look like: +//! +//! ```rust +//! extern crate autocfg; +//! +//! fn main() { +//! # // Normally, cargo will set `OUT_DIR` for build scripts. +//! # std::env::set_var("OUT_DIR", "target"); +//! let ac = autocfg::new(); +//! ac.emit_has_type("i128"); +//! +//! // (optional) We don't need to rerun for anything external. +//! autocfg::rerun_path("build.rs"); +//! } +//! ``` +//! +//! If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line +//! for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the +//! rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that +//! should only be used when the compiler supports it. +//! +//! ## Caution +//! +//! Many of the probing methods of `AutoCfg` document the particular template they +//! use, **subject to change**. The inputs are not validated to make sure they are +//! semantically correct for their expected use, so it's _possible_ to escape and +//! inject something unintended. However, such abuse is unsupported and will not +//! be considered when making changes to the templates. + +#![deny(missing_debug_implementations)] +#![deny(missing_docs)] +// allow future warnings that can't be fixed while keeping 1.0 compatibility +#![allow(unknown_lints)] +#![allow(bare_trait_objects)] +#![allow(ellipsis_inclusive_range_patterns)] + +/// Local macro to avoid `std::try!`, deprecated in Rust 1.39. +macro_rules! try { + ($result:expr) => { + match $result { + Ok(value) => value, + Err(error) => return Err(error), + } + }; +} + +use std::env; +use std::ffi::OsString; +use std::fs; +use std::io::{stderr, Write}; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; +#[allow(deprecated)] +use std::sync::atomic::ATOMIC_USIZE_INIT; +use std::sync::atomic::{AtomicUsize, Ordering}; + +mod error; +pub use error::Error; + +mod version; +use version::Version; + +#[cfg(test)] +mod tests; + +/// Helper to detect compiler features for `cfg` output in build scripts. +#[derive(Clone, Debug)] +pub struct AutoCfg { + out_dir: PathBuf, + rustc: PathBuf, + rustc_version: Version, + target: Option, + no_std: bool, + rustflags: Vec, +} + +/// Writes a config flag for rustc on standard out. +/// +/// This looks like: `cargo:rustc-cfg=CFG` +/// +/// Cargo will use this in arguments to rustc, like `--cfg CFG`. +pub fn emit(cfg: &str) { + println!("cargo:rustc-cfg={}", cfg); +} + +/// Writes a line telling Cargo to rerun the build script if `path` changes. +/// +/// This looks like: `cargo:rerun-if-changed=PATH` +/// +/// This requires at least cargo 0.7.0, corresponding to rustc 1.6.0. Earlier +/// versions of cargo will simply ignore the directive. +pub fn rerun_path(path: &str) { + println!("cargo:rerun-if-changed={}", path); +} + +/// Writes a line telling Cargo to rerun the build script if the environment +/// variable `var` changes. +/// +/// This looks like: `cargo:rerun-if-env-changed=VAR` +/// +/// This requires at least cargo 0.21.0, corresponding to rustc 1.20.0. Earlier +/// versions of cargo will simply ignore the directive. +pub fn rerun_env(var: &str) { + println!("cargo:rerun-if-env-changed={}", var); +} + +/// Create a new `AutoCfg` instance. +/// +/// # Panics +/// +/// Panics if `AutoCfg::new()` returns an error. +pub fn new() -> AutoCfg { + AutoCfg::new().unwrap() +} + +impl AutoCfg { + /// Create a new `AutoCfg` instance. + /// + /// # Common errors + /// + /// - `rustc` can't be executed, from `RUSTC` or in the `PATH`. + /// - The version output from `rustc` can't be parsed. + /// - `OUT_DIR` is not set in the environment, or is not a writable directory. + /// + pub fn new() -> Result { + match env::var_os("OUT_DIR") { + Some(d) => Self::with_dir(d), + None => Err(error::from_str("no OUT_DIR specified!")), + } + } + + /// Create a new `AutoCfg` instance with the specified output directory. + /// + /// # Common errors + /// + /// - `rustc` can't be executed, from `RUSTC` or in the `PATH`. + /// - The version output from `rustc` can't be parsed. + /// - `dir` is not a writable directory. + /// + pub fn with_dir>(dir: T) -> Result { + let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); + let rustc: PathBuf = rustc.into(); + let rustc_version = try!(Version::from_rustc(&rustc)); + + let target = env::var_os("TARGET"); + + // Sanity check the output directory + let dir = dir.into(); + let meta = try!(fs::metadata(&dir).map_err(error::from_io)); + if !meta.is_dir() || meta.permissions().readonly() { + return Err(error::from_str("output path is not a writable directory")); + } + + let mut ac = AutoCfg { + rustflags: rustflags(&target, &dir), + out_dir: dir, + rustc: rustc, + rustc_version: rustc_version, + target: target, + no_std: false, + }; + + // Sanity check with and without `std`. + if !ac.probe("").unwrap_or(false) { + ac.no_std = true; + if !ac.probe("").unwrap_or(false) { + // Neither worked, so assume nothing... + ac.no_std = false; + let warning = b"warning: autocfg could not probe for `std`\n"; + stderr().write_all(warning).ok(); + } + } + Ok(ac) + } + + /// Test whether the current `rustc` reports a version greater than + /// or equal to "`major`.`minor`". + pub fn probe_rustc_version(&self, major: usize, minor: usize) -> bool { + self.rustc_version >= Version::new(major, minor, 0) + } + + /// Sets a `cfg` value of the form `rustc_major_minor`, like `rustc_1_29`, + /// if the current `rustc` is at least that version. + pub fn emit_rustc_version(&self, major: usize, minor: usize) { + if self.probe_rustc_version(major, minor) { + emit(&format!("rustc_{}_{}", major, minor)); + } + } + + fn probe>(&self, code: T) -> Result { + #[allow(deprecated)] + static ID: AtomicUsize = ATOMIC_USIZE_INIT; + + let id = ID.fetch_add(1, Ordering::Relaxed); + let mut command = Command::new(&self.rustc); + command + .arg("--crate-name") + .arg(format!("probe{}", id)) + .arg("--crate-type=lib") + .arg("--out-dir") + .arg(&self.out_dir) + .arg("--emit=llvm-ir"); + + if let Some(target) = self.target.as_ref() { + command.arg("--target").arg(target); + } + + command.args(&self.rustflags); + + command.arg("-").stdin(Stdio::piped()); + let mut child = try!(command.spawn().map_err(error::from_io)); + let mut stdin = child.stdin.take().expect("rustc stdin"); + + if self.no_std { + try!(stdin.write_all(b"#![no_std]\n").map_err(error::from_io)); + } + try!(stdin.write_all(code.as_ref()).map_err(error::from_io)); + drop(stdin); + + let status = try!(child.wait().map_err(error::from_io)); + Ok(status.success()) + } + + /// Tests whether the given sysroot crate can be used. + /// + /// The test code is subject to change, but currently looks like: + /// + /// ```ignore + /// extern crate CRATE as probe; + /// ``` + pub fn probe_sysroot_crate(&self, name: &str) -> bool { + self.probe(format!("extern crate {} as probe;", name)) // `as _` wasn't stabilized until Rust 1.33 + .unwrap_or(false) + } + + /// Emits a config value `has_CRATE` if `probe_sysroot_crate` returns true. + pub fn emit_sysroot_crate(&self, name: &str) { + if self.probe_sysroot_crate(name) { + emit(&format!("has_{}", mangle(name))); + } + } + + /// Tests whether the given path can be used. + /// + /// The test code is subject to change, but currently looks like: + /// + /// ```ignore + /// pub use PATH; + /// ``` + pub fn probe_path(&self, path: &str) -> bool { + self.probe(format!("pub use {};", path)).unwrap_or(false) + } + + /// Emits a config value `has_PATH` if `probe_path` returns true. + /// + /// Any non-identifier characters in the `path` will be replaced with + /// `_` in the generated config value. + pub fn emit_has_path(&self, path: &str) { + if self.probe_path(path) { + emit(&format!("has_{}", mangle(path))); + } + } + + /// Emits the given `cfg` value if `probe_path` returns true. + pub fn emit_path_cfg(&self, path: &str, cfg: &str) { + if self.probe_path(path) { + emit(cfg); + } + } + + /// Tests whether the given trait can be used. + /// + /// The test code is subject to change, but currently looks like: + /// + /// ```ignore + /// pub trait Probe: TRAIT + Sized {} + /// ``` + pub fn probe_trait(&self, name: &str) -> bool { + self.probe(format!("pub trait Probe: {} + Sized {{}}", name)) + .unwrap_or(false) + } + + /// Emits a config value `has_TRAIT` if `probe_trait` returns true. + /// + /// Any non-identifier characters in the trait `name` will be replaced with + /// `_` in the generated config value. + pub fn emit_has_trait(&self, name: &str) { + if self.probe_trait(name) { + emit(&format!("has_{}", mangle(name))); + } + } + + /// Emits the given `cfg` value if `probe_trait` returns true. + pub fn emit_trait_cfg(&self, name: &str, cfg: &str) { + if self.probe_trait(name) { + emit(cfg); + } + } + + /// Tests whether the given type can be used. + /// + /// The test code is subject to change, but currently looks like: + /// + /// ```ignore + /// pub type Probe = TYPE; + /// ``` + pub fn probe_type(&self, name: &str) -> bool { + self.probe(format!("pub type Probe = {};", name)) + .unwrap_or(false) + } + + /// Emits a config value `has_TYPE` if `probe_type` returns true. + /// + /// Any non-identifier characters in the type `name` will be replaced with + /// `_` in the generated config value. + pub fn emit_has_type(&self, name: &str) { + if self.probe_type(name) { + emit(&format!("has_{}", mangle(name))); + } + } + + /// Emits the given `cfg` value if `probe_type` returns true. + pub fn emit_type_cfg(&self, name: &str, cfg: &str) { + if self.probe_type(name) { + emit(cfg); + } + } + + /// Tests whether the given expression can be used. + /// + /// The test code is subject to change, but currently looks like: + /// + /// ```ignore + /// pub fn probe() { let _ = EXPR; } + /// ``` + pub fn probe_expression(&self, expr: &str) -> bool { + self.probe(format!("pub fn probe() {{ let _ = {}; }}", expr)) + .unwrap_or(false) + } + + /// Emits the given `cfg` value if `probe_expression` returns true. + pub fn emit_expression_cfg(&self, expr: &str, cfg: &str) { + if self.probe_expression(expr) { + emit(cfg); + } + } + + /// Tests whether the given constant expression can be used. + /// + /// The test code is subject to change, but currently looks like: + /// + /// ```ignore + /// pub const PROBE: () = ((), EXPR).0; + /// ``` + pub fn probe_constant(&self, expr: &str) -> bool { + self.probe(format!("pub const PROBE: () = ((), {}).0;", expr)) + .unwrap_or(false) + } + + /// Emits the given `cfg` value if `probe_constant` returns true. + pub fn emit_constant_cfg(&self, expr: &str, cfg: &str) { + if self.probe_constant(expr) { + emit(cfg); + } + } +} + +fn mangle(s: &str) -> String { + s.chars() + .map(|c| match c { + 'A'...'Z' | 'a'...'z' | '0'...'9' => c, + _ => '_', + }) + .collect() +} + +fn dir_contains_target( + target: &Option, + dir: &Path, + cargo_target_dir: Option, +) -> bool { + target + .as_ref() + .and_then(|target| { + dir.to_str().and_then(|dir| { + let mut cargo_target_dir = cargo_target_dir + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from("target")); + cargo_target_dir.push(target); + + cargo_target_dir + .to_str() + .map(|cargo_target_dir| dir.contains(&cargo_target_dir)) + }) + }) + .unwrap_or(false) +} + +fn rustflags(target: &Option, dir: &Path) -> Vec { + // Starting with rust-lang/cargo#9601, shipped in Rust 1.55, Cargo always sets + // CARGO_ENCODED_RUSTFLAGS for any host/target build script invocation. This + // includes any source of flags, whether from the environment, toml config, or + // whatever may come in the future. The value is either an empty string, or a + // list of arguments separated by the ASCII unit separator (US), 0x1f. + if let Ok(a) = env::var("CARGO_ENCODED_RUSTFLAGS") { + return if a.is_empty() { + Vec::new() + } else { + a.split('\x1f').map(str::to_string).collect() + }; + } + + // Otherwise, we have to take a more heuristic approach, and we don't + // support values from toml config at all. + // + // Cargo only applies RUSTFLAGS for building TARGET artifact in + // cross-compilation environment. Sadly, we don't have a way to detect + // when we're building HOST artifact in a cross-compilation environment, + // so for now we only apply RUSTFLAGS when cross-compiling an artifact. + // + // See https://github.com/cuviper/autocfg/pull/10#issuecomment-527575030. + if *target != env::var_os("HOST") + || dir_contains_target(target, dir, env::var_os("CARGO_TARGET_DIR")) + { + if let Ok(rustflags) = env::var("RUSTFLAGS") { + // This is meant to match how cargo handles the RUSTFLAGS environment variable. + // See https://github.com/rust-lang/cargo/blob/69aea5b6f69add7c51cca939a79644080c0b0ba0/src/cargo/core/compiler/build_context/target_info.rs#L434-L441 + return rustflags + .split(' ') + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(str::to_string) + .collect(); + } + } + + Vec::new() +} diff --git a/utshell-0.5.0/vendor/autocfg/src/tests.rs b/utshell-0.5.0/vendor/autocfg/src/tests.rs new file mode 100644 index 00000000..d3b1fbb9 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/src/tests.rs @@ -0,0 +1,174 @@ +use super::AutoCfg; +use std::env; +use std::path::Path; + +impl AutoCfg { + fn core_std(&self, path: &str) -> String { + let krate = if self.no_std { "core" } else { "std" }; + format!("{}::{}", krate, path) + } + + fn assert_std(&self, probe_result: bool) { + assert_eq!(!self.no_std, probe_result); + } + + fn assert_min(&self, major: usize, minor: usize, probe_result: bool) { + assert_eq!(self.probe_rustc_version(major, minor), probe_result); + } + + fn for_test() -> Result { + match env::var_os("TESTS_TARGET_DIR") { + Some(d) => Self::with_dir(d), + None => Self::with_dir("target"), + } + } +} + +#[test] +fn autocfg_version() { + let ac = AutoCfg::for_test().unwrap(); + println!("version: {:?}", ac.rustc_version); + assert!(ac.probe_rustc_version(1, 0)); +} + +#[test] +fn version_cmp() { + use super::version::Version; + let v123 = Version::new(1, 2, 3); + + assert!(Version::new(1, 0, 0) < v123); + assert!(Version::new(1, 2, 2) < v123); + assert!(Version::new(1, 2, 3) == v123); + assert!(Version::new(1, 2, 4) > v123); + assert!(Version::new(1, 10, 0) > v123); + assert!(Version::new(2, 0, 0) > v123); +} + +#[test] +fn probe_add() { + let ac = AutoCfg::for_test().unwrap(); + let add = ac.core_std("ops::Add"); + let add_rhs = add.clone() + ""; + let add_rhs_output = add.clone() + ""; + let dyn_add_rhs_output = "dyn ".to_string() + &*add_rhs_output; + assert!(ac.probe_path(&add)); + assert!(ac.probe_trait(&add)); + assert!(ac.probe_trait(&add_rhs)); + assert!(ac.probe_trait(&add_rhs_output)); + ac.assert_min(1, 27, ac.probe_type(&dyn_add_rhs_output)); +} + +#[test] +fn probe_as_ref() { + let ac = AutoCfg::for_test().unwrap(); + let as_ref = ac.core_std("convert::AsRef"); + let as_ref_str = as_ref.clone() + ""; + let dyn_as_ref_str = "dyn ".to_string() + &*as_ref_str; + assert!(ac.probe_path(&as_ref)); + assert!(ac.probe_trait(&as_ref_str)); + assert!(ac.probe_type(&as_ref_str)); + ac.assert_min(1, 27, ac.probe_type(&dyn_as_ref_str)); +} + +#[test] +fn probe_i128() { + let ac = AutoCfg::for_test().unwrap(); + let i128_path = ac.core_std("i128"); + ac.assert_min(1, 26, ac.probe_path(&i128_path)); + ac.assert_min(1, 26, ac.probe_type("i128")); +} + +#[test] +fn probe_sum() { + let ac = AutoCfg::for_test().unwrap(); + let sum = ac.core_std("iter::Sum"); + let sum_i32 = sum.clone() + ""; + let dyn_sum_i32 = "dyn ".to_string() + &*sum_i32; + ac.assert_min(1, 12, ac.probe_path(&sum)); + ac.assert_min(1, 12, ac.probe_trait(&sum)); + ac.assert_min(1, 12, ac.probe_trait(&sum_i32)); + ac.assert_min(1, 12, ac.probe_type(&sum_i32)); + ac.assert_min(1, 27, ac.probe_type(&dyn_sum_i32)); +} + +#[test] +fn probe_std() { + let ac = AutoCfg::for_test().unwrap(); + ac.assert_std(ac.probe_sysroot_crate("std")); +} + +#[test] +fn probe_alloc() { + let ac = AutoCfg::for_test().unwrap(); + ac.assert_min(1, 36, ac.probe_sysroot_crate("alloc")); +} + +#[test] +fn probe_bad_sysroot_crate() { + let ac = AutoCfg::for_test().unwrap(); + assert!(!ac.probe_sysroot_crate("doesnt_exist")); +} + +#[test] +fn probe_no_std() { + let ac = AutoCfg::for_test().unwrap(); + assert!(ac.probe_type("i32")); + assert!(ac.probe_type("[i32]")); + ac.assert_std(ac.probe_type("Vec")); +} + +#[test] +fn probe_expression() { + let ac = AutoCfg::for_test().unwrap(); + assert!(ac.probe_expression(r#""test".trim_left()"#)); + ac.assert_min(1, 30, ac.probe_expression(r#""test".trim_start()"#)); + ac.assert_std(ac.probe_expression("[1, 2, 3].to_vec()")); +} + +#[test] +fn probe_constant() { + let ac = AutoCfg::for_test().unwrap(); + assert!(ac.probe_constant("1 + 2 + 3")); + ac.assert_min(1, 33, ac.probe_constant("{ let x = 1 + 2 + 3; x * x }")); + ac.assert_min(1, 39, ac.probe_constant(r#""test".len()"#)); +} + +#[test] +fn dir_does_not_contain_target() { + assert!(!super::dir_contains_target( + &Some("x86_64-unknown-linux-gnu".into()), + Path::new("/project/target/debug/build/project-ea75983148559682/out"), + None, + )); +} + +#[test] +fn dir_does_contain_target() { + assert!(super::dir_contains_target( + &Some("x86_64-unknown-linux-gnu".into()), + Path::new( + "/project/target/x86_64-unknown-linux-gnu/debug/build/project-0147aca016480b9d/out" + ), + None, + )); +} + +#[test] +fn dir_does_not_contain_target_with_custom_target_dir() { + assert!(!super::dir_contains_target( + &Some("x86_64-unknown-linux-gnu".into()), + Path::new("/project/custom/debug/build/project-ea75983148559682/out"), + Some("custom".into()), + )); +} + +#[test] +fn dir_does_contain_target_with_custom_target_dir() { + assert!(super::dir_contains_target( + &Some("x86_64-unknown-linux-gnu".into()), + Path::new( + "/project/custom/x86_64-unknown-linux-gnu/debug/build/project-0147aca016480b9d/out" + ), + Some("custom".into()), + )); +} diff --git a/utshell-0.5.0/vendor/autocfg/src/version.rs b/utshell-0.5.0/vendor/autocfg/src/version.rs new file mode 100644 index 00000000..378c21e6 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/src/version.rs @@ -0,0 +1,60 @@ +use std::path::Path; +use std::process::Command; +use std::str; + +use super::{error, Error}; + +/// A version structure for making relative comparisons. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct Version { + major: usize, + minor: usize, + patch: usize, +} + +impl Version { + /// Creates a `Version` instance for a specific `major.minor.patch` version. + pub fn new(major: usize, minor: usize, patch: usize) -> Self { + Version { + major: major, + minor: minor, + patch: patch, + } + } + + pub fn from_rustc(rustc: &Path) -> Result { + // Get rustc's verbose version + let output = try!(Command::new(rustc) + .args(&["--version", "--verbose"]) + .output() + .map_err(error::from_io)); + if !output.status.success() { + return Err(error::from_str("could not execute rustc")); + } + let output = try!(str::from_utf8(&output.stdout).map_err(error::from_utf8)); + + // Find the release line in the verbose version output. + let release = match output.lines().find(|line| line.starts_with("release: ")) { + Some(line) => &line["release: ".len()..], + None => return Err(error::from_str("could not find rustc release")), + }; + + // Strip off any extra channel info, e.g. "-beta.N", "-nightly" + let version = match release.find('-') { + Some(i) => &release[..i], + None => release, + }; + + // Split the version into semver components. + let mut iter = version.splitn(3, '.'); + let major = try!(iter.next().ok_or(error::from_str("missing major version"))); + let minor = try!(iter.next().ok_or(error::from_str("missing minor version"))); + let patch = try!(iter.next().ok_or(error::from_str("missing patch version"))); + + Ok(Version::new( + try!(major.parse().map_err(error::from_num)), + try!(minor.parse().map_err(error::from_num)), + try!(patch.parse().map_err(error::from_num)), + )) + } +} diff --git a/utshell-0.5.0/vendor/autocfg/tests/rustflags.rs b/utshell-0.5.0/vendor/autocfg/tests/rustflags.rs new file mode 100644 index 00000000..f0545466 --- /dev/null +++ b/utshell-0.5.0/vendor/autocfg/tests/rustflags.rs @@ -0,0 +1,33 @@ +extern crate autocfg; + +use std::env; + +/// Tests that autocfg uses the RUSTFLAGS or CARGO_ENCODED_RUSTFLAGS +/// environment variables when running rustc. +#[test] +fn test_with_sysroot() { + // Use the same path as this test binary. + let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf(); + env::set_var("OUT_DIR", &format!("{}", dir.display())); + + // If we have encoded rustflags, they take precedence, even if empty. + env::set_var("CARGO_ENCODED_RUSTFLAGS", ""); + env::set_var("RUSTFLAGS", &format!("-L {}", dir.display())); + let ac = autocfg::AutoCfg::new().unwrap(); + assert!(ac.probe_sysroot_crate("std")); + assert!(!ac.probe_sysroot_crate("autocfg")); + + // Now try again with useful encoded args. + env::set_var( + "CARGO_ENCODED_RUSTFLAGS", + &format!("-L\x1f{}", dir.display()), + ); + let ac = autocfg::AutoCfg::new().unwrap(); + assert!(ac.probe_sysroot_crate("autocfg")); + + // Try the old-style RUSTFLAGS, ensuring HOST != TARGET. + env::remove_var("CARGO_ENCODED_RUSTFLAGS"); + env::set_var("HOST", "lol"); + let ac = autocfg::AutoCfg::new().unwrap(); + assert!(ac.probe_sysroot_crate("autocfg")); +} diff --git a/utshell-0.5.0/vendor/bitflags/.cargo-checksum.json b/utshell-0.5.0/vendor/bitflags/.cargo-checksum.json new file mode 100644 index 00000000..7e8d470b --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"d362fc1fccaaf4d421bcf0fe8b80ddb4f625dade0c1ee52d08bd0b95509a49d1","CODE_OF_CONDUCT.md":"42634d0f6d922f49857175af991802822f7f920487aefa2ee250a50d12251a66","Cargo.toml":"87aced7532a7974eb37ab5fe6037f0abafc36d6b2d74891ecd2bf2f14f50d11e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"baa8604f8afb34fd93b9c79729daafb884dedcaf34023e4af8ad037d916061fd","src/example_generated.rs":"e43eb59e90f317f38d436670a6067d2fd9eb35fb319fe716184e4a04e24ed1b2","src/lib.rs":"e6477688535ee326d27238aeedc9cb4320ac35b9d17a4deda09e0587b0ccdbd4","tests/basic.rs":"146f1cbf6279bc609242cd3349f29cb21b41294f5e4921875f5ec95bd83529a2","tests/compile-fail/impls/copy.rs":"b791371237ddc75a7c04d2130e03b462c9c00a80dca08bd45aa97433d9c0d13a","tests/compile-fail/impls/copy.stderr.beta":"77d83484ce221d4b6ff2f7de843929a452d779fcfff428122710dd8218c298e3","tests/compile-fail/impls/eq.rs":"0cee8b9e07d537890e0189710293b53972d0fab63c09366f33c391065afafa99","tests/compile-fail/impls/eq.stderr.beta":"381fc6143d45ce76d7cecc47aa59cb69fe5e79c0b60a4a85d5c6163b400b3cc7","tests/compile-fail/non_integer_base/all_defined.rs":"95e14cad9e94560262f2862c3c01865ac30369b69da1001b0e7285cb55e6cb75","tests/compile-fail/non_integer_base/all_defined.stderr.beta":"1760739a276690903bb03844025587d37939f5dfcbfab309db3c86f32bdbf748","tests/compile-fail/non_integer_base/all_missing.rs":"b3d9da619d23213731ba2581aa7999c796c3c79aaf4f0ee6b11ceec08a11537f","tests/compile-fail/non_integer_base/all_missing.stderr.beta":"37e102290d3867e175b21976be798939f294efb17580d5b51e7b17b590d55132","tests/compile-fail/visibility/private_field.rs":"38e4d3fe6471829360d12c8d09b097f6a21aa93fb51eac3b215d96bdae23316b","tests/compile-fail/visibility/private_field.stderr.beta":"5aa24a3ebb39326f31927721c5017b8beb66c3e501fb865a3fa814c9763bfa0f","tests/compile-fail/visibility/private_flags.rs":"2ce4235802aa4e9c96c4e77d9e31d8401ef58dcda4741325184f0764ab1fe393","tests/compile-fail/visibility/private_flags.stderr.beta":"f3eb9f7baf2689258f3519ff7ee5c6ec3c237264ebcfe63f40c40f2023e5022f","tests/compile-fail/visibility/pub_const.rs":"8f813a97ac518c5ea8ac65b184101912452384afaf7b8d6c5e62f8370eca3c0a","tests/compile-fail/visibility/pub_const.stderr.beta":"823976ae1794d7f5372e2ec9aabba497e7bb88004722904c38da342ed98e8962","tests/compile-pass/impls/convert.rs":"88fe80bfb9cd5779f0e1d92c9ec02a8b6bb67e334c07f2309e9c0ba5ef776eb0","tests/compile-pass/impls/default.rs":"c508f9a461691f44b45142fa5ad599f02326e1de4c0cbca6c0593f4652eba109","tests/compile-pass/impls/inherent_methods.rs":"ecc26388e9a394bfa7a5bb69a5d621ab3d4d1e53f28f657bb8e78fe79f437913","tests/compile-pass/redefinition/core.rs":"ff5b6e72f87acc6ebb12405d3c0f6e3fa62e669933656a454bb63b30ea44179c","tests/compile-pass/redefinition/stringify.rs":"1edbce42b900c14425d7ffa14e83e165ebe452d7dccd8c0a8a821bdec64f5c93","tests/compile-pass/repr/c.rs":"6fda17f7c2edfcd155314579e83d0fc8a16209e400f1f9a5ca77bd9a799041f2","tests/compile-pass/repr/transparent.rs":"6cdc87a2137d8a4e0c8ce9b6cba83c82255f8ea125951bf614418685600489ce","tests/compile-pass/visibility/bits_field.rs":"1f3e5ba5a047440066a9f6bf7b7af33f5b06f6b1da3dd9af6886168199a7ea0a","tests/compile-pass/visibility/pub_in.rs":"e95312ff60966d42ec4bc00225507895a9b8ec24056ce6a9edd9145be35d730f","tests/compile.rs":"f27c67a7dd183ca30efea1b6e0880e3469a6dd63b92b1fd711c082df182c9eec"},"package":"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/bitflags/CHANGELOG.md b/utshell-0.5.0/vendor/bitflags/CHANGELOG.md new file mode 100644 index 00000000..12fea167 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/CHANGELOG.md @@ -0,0 +1,206 @@ +# 1.3.2 + +- Allow `non_snake_case` in generated flags types ([#256]) + +[#252]: https://github.com/bitflags/bitflags/pull/256 + +# 1.3.1 + +- Revert unconditional `#[repr(transparent)]` ([#252]) + +[#252]: https://github.com/bitflags/bitflags/pull/252 + +# 1.3.0 (yanked) + +- Add `#[repr(transparent)]` ([#187]) + +- End `empty` doc comment with full stop ([#202]) + +- Fix typo in crate root docs ([#206]) + +- Document from_bits_unchecked unsafety ([#207]) + +- Let `is_all` ignore extra bits ([#211]) + +- Allows empty flag definition ([#225]) + +- Making crate accessible from std ([#227]) + +- Make `from_bits` a const fn ([#229]) + +- Allow multiple bitflags structs in one macro invocation ([#235]) + +- Add named functions to perform set operations ([#244]) + +- Fix typos in method docs ([#245]) + +- Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246]) + +- Fix regression (in an unreleased feature) and simplify tests ([#247]) + +- Use `Self` and fix bug when overriding `stringify!` ([#249]) + +[#187]: https://github.com/bitflags/bitflags/pull/187 +[#202]: https://github.com/bitflags/bitflags/pull/202 +[#206]: https://github.com/bitflags/bitflags/pull/206 +[#207]: https://github.com/bitflags/bitflags/pull/207 +[#211]: https://github.com/bitflags/bitflags/pull/211 +[#225]: https://github.com/bitflags/bitflags/pull/225 +[#227]: https://github.com/bitflags/bitflags/pull/227 +[#229]: https://github.com/bitflags/bitflags/pull/229 +[#235]: https://github.com/bitflags/bitflags/pull/235 +[#244]: https://github.com/bitflags/bitflags/pull/244 +[#245]: https://github.com/bitflags/bitflags/pull/245 +[#246]: https://github.com/bitflags/bitflags/pull/246 +[#247]: https://github.com/bitflags/bitflags/pull/247 +[#249]: https://github.com/bitflags/bitflags/pull/249 + +# 1.2.1 + +- Remove extraneous `#[inline]` attributes ([#194]) + +[#194]: https://github.com/bitflags/bitflags/pull/194 + +# 1.2.0 + +- Fix typo: {Lower, Upper}Exp - {Lower, Upper}Hex ([#183]) + +- Add support for "unknown" bits ([#188]) + +[#183]: https://github.com/rust-lang-nursery/bitflags/pull/183 +[#188]: https://github.com/rust-lang-nursery/bitflags/pull/188 + +# 1.1.0 + +This is a re-release of `1.0.5`, which was yanked due to a bug in the RLS. + +# 1.0.5 + +- Use compiletest_rs flags supported by stable toolchain ([#171]) + +- Put the user provided attributes first ([#173]) + +- Make bitflags methods `const` on newer compilers ([#175]) + +[#171]: https://github.com/rust-lang-nursery/bitflags/pull/171 +[#173]: https://github.com/rust-lang-nursery/bitflags/pull/173 +[#175]: https://github.com/rust-lang-nursery/bitflags/pull/175 + +# 1.0.4 + +- Support Rust 2018 style macro imports ([#165]) + + ```rust + use bitflags::bitflags; + ``` + +[#165]: https://github.com/rust-lang-nursery/bitflags/pull/165 + +# 1.0.3 + +- Improve zero value flag handling and documentation ([#157]) + +[#157]: https://github.com/rust-lang-nursery/bitflags/pull/157 + +# 1.0.2 + +- 30% improvement in compile time of bitflags crate ([#156]) + +- Documentation improvements ([#153]) + +- Implementation cleanup ([#149]) + +[#156]: https://github.com/rust-lang-nursery/bitflags/pull/156 +[#153]: https://github.com/rust-lang-nursery/bitflags/pull/153 +[#149]: https://github.com/rust-lang-nursery/bitflags/pull/149 + +# 1.0.1 +- Add support for `pub(restricted)` specifier on the bitflags struct ([#135]) +- Optimize performance of `all()` when called from a separate crate ([#136]) + +[#135]: https://github.com/rust-lang-nursery/bitflags/pull/135 +[#136]: https://github.com/rust-lang-nursery/bitflags/pull/136 + +# 1.0.0 +- **[breaking change]** Macro now generates [associated constants](https://doc.rust-lang.org/reference/items.html#associated-constants) ([#24]) + +- **[breaking change]** Minimum supported version is Rust **1.20**, due to usage of associated constants + +- After being broken in 0.9, the `#[deprecated]` attribute is now supported again ([#112]) + +- Other improvements to unit tests and documentation ([#106] and [#115]) + +[#24]: https://github.com/rust-lang-nursery/bitflags/pull/24 +[#106]: https://github.com/rust-lang-nursery/bitflags/pull/106 +[#112]: https://github.com/rust-lang-nursery/bitflags/pull/112 +[#115]: https://github.com/rust-lang-nursery/bitflags/pull/115 + +## How to update your code to use associated constants +Assuming the following structure definition: +```rust +bitflags! { + struct Something: u8 { + const FOO = 0b01, + const BAR = 0b10 + } +} +``` +In 0.9 and older you could do: +```rust +let x = FOO.bits | BAR.bits; +``` +Now you must use: +```rust +let x = Something::FOO.bits | Something::BAR.bits; +``` + +# 0.9.1 +- Fix the implementation of `Formatting` traits when other formatting traits were present in scope ([#105]) + +[#105]: https://github.com/rust-lang-nursery/bitflags/pull/105 + +# 0.9.0 +- **[breaking change]** Use struct keyword instead of flags to define bitflag types ([#84]) + +- **[breaking change]** Terminate const items with semicolons instead of commas ([#87]) + +- Implement the `Hex`, `Octal`, and `Binary` formatting traits ([#86]) + +- Printing an empty flag value with the `Debug` trait now prints "(empty)" instead of nothing ([#85]) + +- The `bitflags!` macro can now be used inside of a fn body, to define a type local to that function ([#74]) + +[#74]: https://github.com/rust-lang-nursery/bitflags/pull/74 +[#84]: https://github.com/rust-lang-nursery/bitflags/pull/84 +[#85]: https://github.com/rust-lang-nursery/bitflags/pull/85 +[#86]: https://github.com/rust-lang-nursery/bitflags/pull/86 +[#87]: https://github.com/rust-lang-nursery/bitflags/pull/87 + +# 0.8.2 +- Update feature flag used when building bitflags as a dependency of the Rust toolchain + +# 0.8.1 +- Allow bitflags to be used as a dependency of the Rust toolchain + +# 0.8.0 +- Add support for the experimental `i128` and `u128` integer types ([#57]) +- Add set method: `flags.set(SOME_FLAG, true)` or `flags.set(SOME_FLAG, false)` ([#55]) + This may break code that defines its own set method + +[#55]: https://github.com/rust-lang-nursery/bitflags/pull/55 +[#57]: https://github.com/rust-lang-nursery/bitflags/pull/57 + +# 0.7.1 +*(yanked)* + +# 0.7.0 +- Implement the Extend trait ([#49]) +- Allow definitions inside the `bitflags!` macro to refer to items imported from other modules ([#51]) + +[#49]: https://github.com/rust-lang-nursery/bitflags/pull/49 +[#51]: https://github.com/rust-lang-nursery/bitflags/pull/51 + +# 0.6.0 +- The `no_std` feature was removed as it is now the default +- The `assignment_operators` feature was remove as it is now enabled by default +- Some clippy suggestions have been applied diff --git a/utshell-0.5.0/vendor/bitflags/CODE_OF_CONDUCT.md b/utshell-0.5.0/vendor/bitflags/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..f7add90a --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at coc@senaite.org. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org \ No newline at end of file diff --git a/utshell-0.5.0/vendor/bitflags/Cargo.toml b/utshell-0.5.0/vendor/bitflags/Cargo.toml new file mode 100644 index 00000000..9d54c725 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/Cargo.toml @@ -0,0 +1,58 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "bitflags" +version = "1.3.2" +authors = ["The Rust Project Developers"] +exclude = ["bors.toml"] +description = "A macro to generate structures which behave like bitflags.\n" +homepage = "https://github.com/bitflags/bitflags" +documentation = "https://docs.rs/bitflags" +readme = "README.md" +keywords = ["bit", "bitmask", "bitflags", "flags"] +categories = ["no-std"] +license = "MIT/Apache-2.0" +repository = "https://github.com/bitflags/bitflags" +[package.metadata.docs.rs] +features = ["example_generated"] +[dependencies.compiler_builtins] +version = "0.1.2" +optional = true + +[dependencies.core] +version = "1.0.0" +optional = true +package = "rustc-std-workspace-core" +[dev-dependencies.rustversion] +version = "1.0" + +[dev-dependencies.serde] +version = "1.0" + +[dev-dependencies.serde_derive] +version = "1.0" + +[dev-dependencies.serde_json] +version = "1.0" + +[dev-dependencies.trybuild] +version = "1.0" + +[dev-dependencies.walkdir] +version = "2.3" + +[features] +default = [] +example_generated = [] +rustc-dep-of-std = ["core", "compiler_builtins"] diff --git a/utshell-0.5.0/vendor/bitflags/LICENSE-APACHE b/utshell-0.5.0/vendor/bitflags/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/bitflags/LICENSE-MIT b/utshell-0.5.0/vendor/bitflags/LICENSE-MIT new file mode 100644 index 00000000..39d4bdb5 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/bitflags/README.md b/utshell-0.5.0/vendor/bitflags/README.md new file mode 100644 index 00000000..0da0f853 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/README.md @@ -0,0 +1,32 @@ +bitflags +======== + +[![Rust](https://github.com/bitflags/bitflags/workflows/Rust/badge.svg)](https://github.com/bitflags/bitflags/actions) +[![Join the chat at https://gitter.im/bitflags/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bitflags/Lobby?utm_source=badge&utm_medium=badge&utm_content=badge) +[![Latest version](https://img.shields.io/crates/v/bitflags.svg)](https://crates.io/crates/bitflags) +[![Documentation](https://docs.rs/bitflags/badge.svg)](https://docs.rs/bitflags) +![License](https://img.shields.io/crates/l/bitflags.svg) + +A Rust macro to generate structures which behave like a set of bitflags + +- [Documentation](https://docs.rs/bitflags) +- [Release notes](https://github.com/bitflags/bitflags/releases) + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +bitflags = "1.3" +``` + +and this to your source code: + +```rust +use bitflags::bitflags; +``` + +## Rust Version Support + +The minimum supported Rust version is 1.46 due to use of associated constants and const functions. diff --git a/utshell-0.5.0/vendor/bitflags/src/example_generated.rs b/utshell-0.5.0/vendor/bitflags/src/example_generated.rs new file mode 100644 index 00000000..cf188d99 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/src/example_generated.rs @@ -0,0 +1,14 @@ +//! This module shows an example of code generated by the macro. **IT MUST NOT BE USED OUTSIDE THIS +//! CRATE**. + +bitflags! { + /// This is the same `Flags` struct defined in the [crate level example](../index.html#example). + /// Note that this struct is just for documentation purposes only, it must not be used outside + /// this crate. + pub struct Flags: u32 { + const A = 0b00000001; + const B = 0b00000010; + const C = 0b00000100; + const ABC = Self::A.bits | Self::B.bits | Self::C.bits; + } +} diff --git a/utshell-0.5.0/vendor/bitflags/src/lib.rs b/utshell-0.5.0/vendor/bitflags/src/lib.rs new file mode 100644 index 00000000..935e432f --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/src/lib.rs @@ -0,0 +1,1729 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A typesafe bitmask flag generator useful for sets of C-style bitmask flags. +//! It can be used for creating typesafe wrappers around C APIs. +//! +//! The `bitflags!` macro generates `struct`s that manage a set of flags. The +//! flags should only be defined for integer types, otherwise unexpected type +//! errors may occur at compile time. +//! +//! # Example +//! +//! ``` +//! use bitflags::bitflags; +//! +//! bitflags! { +//! struct Flags: u32 { +//! const A = 0b00000001; +//! const B = 0b00000010; +//! const C = 0b00000100; +//! const ABC = Self::A.bits | Self::B.bits | Self::C.bits; +//! } +//! } +//! +//! fn main() { +//! let e1 = Flags::A | Flags::C; +//! let e2 = Flags::B | Flags::C; +//! assert_eq!((e1 | e2), Flags::ABC); // union +//! assert_eq!((e1 & e2), Flags::C); // intersection +//! assert_eq!((e1 - e2), Flags::A); // set difference +//! assert_eq!(!e2, Flags::A); // set complement +//! } +//! ``` +//! +//! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code +//! generated by the above `bitflags!` expansion. +//! +//! The generated `struct`s can also be extended with type and trait +//! implementations: +//! +//! ``` +//! use std::fmt; +//! +//! use bitflags::bitflags; +//! +//! bitflags! { +//! struct Flags: u32 { +//! const A = 0b00000001; +//! const B = 0b00000010; +//! } +//! } +//! +//! impl Flags { +//! pub fn clear(&mut self) { +//! self.bits = 0; // The `bits` field can be accessed from within the +//! // same module where the `bitflags!` macro was invoked. +//! } +//! } +//! +//! impl fmt::Display for Flags { +//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +//! write!(f, "hi!") +//! } +//! } +//! +//! fn main() { +//! let mut flags = Flags::A | Flags::B; +//! flags.clear(); +//! assert!(flags.is_empty()); +//! assert_eq!(format!("{}", flags), "hi!"); +//! assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); +//! assert_eq!(format!("{:?}", Flags::B), "B"); +//! } +//! ``` +//! +//! # Visibility +//! +//! The generated structs and their associated flag constants are not exported +//! out of the current module by default. A definition can be exported out of +//! the current module by adding `pub` before `struct`: +//! +//! ``` +//! mod example { +//! use bitflags::bitflags; +//! +//! bitflags! { +//! pub struct Flags1: u32 { +//! const A = 0b00000001; +//! } +//! +//! # pub +//! struct Flags2: u32 { +//! const B = 0b00000010; +//! } +//! } +//! } +//! +//! fn main() { +//! let flag1 = example::Flags1::A; +//! let flag2 = example::Flags2::B; // error: const `B` is private +//! } +//! ``` +//! +//! # Attributes +//! +//! Attributes can be attached to the generated `struct`s by placing them +//! before the `struct` keyword. +//! +//! ## Representations +//! +//! It's valid to add a `#[repr(C)]` or `#[repr(transparent)]` attribute to a type +//! generated by `bitflags!`. In these cases, the type is guaranteed to be a newtype. +//! +//! ``` +//! use bitflags::bitflags; +//! +//! bitflags! { +//! #[repr(transparent)] +//! struct Flags: u32 { +//! const A = 0b00000001; +//! const B = 0b00000010; +//! const C = 0b00000100; +//! } +//! } +//! ``` +//! +//! # Trait implementations +//! +//! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash` +//! traits are automatically derived for the `struct`s using the `derive` attribute. +//! Additional traits can be derived by providing an explicit `derive` +//! attribute on `struct`. +//! +//! The `Extend` and `FromIterator` traits are implemented for the `struct`s, +//! too: `Extend` adds the union of the instances of the `struct` iterated over, +//! while `FromIterator` calculates the union. +//! +//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also +//! implemented by displaying the bits value of the internal struct. +//! +//! ## Operators +//! +//! The following operator traits are implemented for the generated `struct`s: +//! +//! - `BitOr` and `BitOrAssign`: union +//! - `BitAnd` and `BitAndAssign`: intersection +//! - `BitXor` and `BitXorAssign`: toggle +//! - `Sub` and `SubAssign`: set difference +//! - `Not`: set complement +//! +//! # Methods +//! +//! The following methods are defined for the generated `struct`s: +//! +//! - `empty`: an empty set of flags +//! - `all`: the set of all defined flags +//! - `bits`: the raw value of the flags currently stored +//! - `from_bits`: convert from underlying bit representation, unless that +//! representation contains bits that do not correspond to a +//! defined flag +//! - `from_bits_truncate`: convert from underlying bit representation, dropping +//! any bits that do not correspond to defined flags +//! - `from_bits_unchecked`: convert from underlying bit representation, keeping +//! all bits (even those not corresponding to defined +//! flags) +//! - `is_empty`: `true` if no flags are currently stored +//! - `is_all`: `true` if currently set flags exactly equal all defined flags +//! - `intersects`: `true` if there are flags common to both `self` and `other` +//! - `contains`: `true` if all of the flags in `other` are contained within `self` +//! - `insert`: inserts the specified flags in-place +//! - `remove`: removes the specified flags in-place +//! - `toggle`: the specified flags will be inserted if not present, and removed +//! if they are. +//! - `set`: inserts or removes the specified flags depending on the passed value +//! - `intersection`: returns a new set of flags, containing only the flags present +//! in both `self` and `other` (the argument to the function). +//! - `union`: returns a new set of flags, containing any flags present in +//! either `self` or `other` (the argument to the function). +//! - `difference`: returns a new set of flags, containing all flags present in +//! `self` without any of the flags present in `other` (the +//! argument to the function). +//! - `symmetric_difference`: returns a new set of flags, containing all flags +//! present in either `self` or `other` (the argument +//! to the function), but not both. +//! - `complement`: returns a new set of flags, containing all flags which are +//! not set in `self`, but which are allowed for this type. +//! +//! ## Default +//! +//! The `Default` trait is not automatically implemented for the generated structs. +//! +//! If your default value is equal to `0` (which is the same value as calling `empty()` +//! on the generated struct), you can simply derive `Default`: +//! +//! ``` +//! use bitflags::bitflags; +//! +//! bitflags! { +//! // Results in default value with bits: 0 +//! #[derive(Default)] +//! struct Flags: u32 { +//! const A = 0b00000001; +//! const B = 0b00000010; +//! const C = 0b00000100; +//! } +//! } +//! +//! fn main() { +//! let derived_default: Flags = Default::default(); +//! assert_eq!(derived_default.bits(), 0); +//! } +//! ``` +//! +//! If your default value is not equal to `0` you need to implement `Default` yourself: +//! +//! ``` +//! use bitflags::bitflags; +//! +//! bitflags! { +//! struct Flags: u32 { +//! const A = 0b00000001; +//! const B = 0b00000010; +//! const C = 0b00000100; +//! } +//! } +//! +//! // explicit `Default` implementation +//! impl Default for Flags { +//! fn default() -> Flags { +//! Flags::A | Flags::C +//! } +//! } +//! +//! fn main() { +//! let implemented_default: Flags = Default::default(); +//! assert_eq!(implemented_default, (Flags::A | Flags::C)); +//! } +//! ``` +//! +//! # Zero Flags +//! +//! Flags with a value equal to zero will have some strange behavior that one should be aware of. +//! +//! ``` +//! use bitflags::bitflags; +//! +//! bitflags! { +//! struct Flags: u32 { +//! const NONE = 0b00000000; +//! const SOME = 0b00000001; +//! } +//! } +//! +//! fn main() { +//! let empty = Flags::empty(); +//! let none = Flags::NONE; +//! let some = Flags::SOME; +//! +//! // Zero flags are treated as always present +//! assert!(empty.contains(Flags::NONE)); +//! assert!(none.contains(Flags::NONE)); +//! assert!(some.contains(Flags::NONE)); +//! +//! // Zero flags will be ignored when testing for emptiness +//! assert!(none.is_empty()); +//! } +//! ``` +//! +//! Users should generally avoid defining a flag with a value of zero. + +#![cfg_attr(not(test), no_std)] +#![doc(html_root_url = "https://docs.rs/bitflags/1.3.2")] + +#[doc(hidden)] +pub extern crate core as _core; + +/// The macro used to generate the flag structures. +/// +/// See the [crate level docs](../bitflags/index.html) for complete documentation. +/// +/// # Example +/// +/// ``` +/// use bitflags::bitflags; +/// +/// bitflags! { +/// struct Flags: u32 { +/// const A = 0b00000001; +/// const B = 0b00000010; +/// const C = 0b00000100; +/// const ABC = Self::A.bits | Self::B.bits | Self::C.bits; +/// } +/// } +/// +/// fn main() { +/// let e1 = Flags::A | Flags::C; +/// let e2 = Flags::B | Flags::C; +/// assert_eq!((e1 | e2), Flags::ABC); // union +/// assert_eq!((e1 & e2), Flags::C); // intersection +/// assert_eq!((e1 - e2), Flags::A); // set difference +/// assert_eq!(!e2, Flags::A); // set complement +/// } +/// ``` +/// +/// The generated `struct`s can also be extended with type and trait +/// implementations: +/// +/// ``` +/// use std::fmt; +/// +/// use bitflags::bitflags; +/// +/// bitflags! { +/// struct Flags: u32 { +/// const A = 0b00000001; +/// const B = 0b00000010; +/// } +/// } +/// +/// impl Flags { +/// pub fn clear(&mut self) { +/// self.bits = 0; // The `bits` field can be accessed from within the +/// // same module where the `bitflags!` macro was invoked. +/// } +/// } +/// +/// impl fmt::Display for Flags { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "hi!") +/// } +/// } +/// +/// fn main() { +/// let mut flags = Flags::A | Flags::B; +/// flags.clear(); +/// assert!(flags.is_empty()); +/// assert_eq!(format!("{}", flags), "hi!"); +/// assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); +/// assert_eq!(format!("{:?}", Flags::B), "B"); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! bitflags { + ( + $(#[$outer:meta])* + $vis:vis struct $BitFlags:ident: $T:ty { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:ident = $value:expr; + )* + } + + $($t:tt)* + ) => { + $(#[$outer])* + #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] + $vis struct $BitFlags { + bits: $T, + } + + __impl_bitflags! { + $BitFlags: $T { + $( + $(#[$inner $($args)*])* + $Flag = $value; + )* + } + } + + bitflags! { + $($t)* + } + }; + () => {}; +} + +// A helper macro to implement the `all` function. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_all_bitflags { + ( + $BitFlags:ident: $T:ty { + $( + $(#[$attr:ident $($args:tt)*])* + $Flag:ident = $value:expr; + )+ + } + ) => { + // See `Debug::fmt` for why this approach is taken. + #[allow(non_snake_case)] + trait __BitFlags { + $( + const $Flag: $T = 0; + )+ + } + #[allow(non_snake_case)] + impl __BitFlags for $BitFlags { + $( + __impl_bitflags! { + #[allow(deprecated)] + $(? #[$attr $($args)*])* + const $Flag: $T = Self::$Flag.bits; + } + )+ + } + Self { bits: $(::$Flag)|+ } + }; + ( + $BitFlags:ident: $T:ty { } + ) => { + Self { bits: 0 } + }; +} + +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __impl_bitflags { + ( + $BitFlags:ident: $T:ty { + $( + $(#[$attr:ident $($args:tt)*])* + $Flag:ident = $value:expr; + )* + } + ) => { + impl $crate::_core::fmt::Debug for $BitFlags { + fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { + // This convoluted approach is to handle #[cfg]-based flag + // omission correctly. For example it needs to support: + // + // #[cfg(unix)] const A: Flag = /* ... */; + // #[cfg(windows)] const B: Flag = /* ... */; + + // Unconditionally define a check for every flag, even disabled + // ones. + #[allow(non_snake_case)] + trait __BitFlags { + $( + #[inline] + fn $Flag(&self) -> bool { false } + )* + } + + // Conditionally override the check for just those flags that + // are not #[cfg]ed away. + #[allow(non_snake_case)] + impl __BitFlags for $BitFlags { + $( + __impl_bitflags! { + #[allow(deprecated)] + #[inline] + $(? #[$attr $($args)*])* + fn $Flag(&self) -> bool { + if Self::$Flag.bits == 0 && self.bits != 0 { + false + } else { + self.bits & Self::$Flag.bits == Self::$Flag.bits + } + } + } + )* + } + + let mut first = true; + $( + if ::$Flag(self) { + if !first { + f.write_str(" | ")?; + } + first = false; + f.write_str($crate::_core::stringify!($Flag))?; + } + )* + let extra_bits = self.bits & !Self::all().bits(); + if extra_bits != 0 { + if !first { + f.write_str(" | ")?; + } + first = false; + f.write_str("0x")?; + $crate::_core::fmt::LowerHex::fmt(&extra_bits, f)?; + } + if first { + f.write_str("(empty)")?; + } + Ok(()) + } + } + impl $crate::_core::fmt::Binary for $BitFlags { + fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { + $crate::_core::fmt::Binary::fmt(&self.bits, f) + } + } + impl $crate::_core::fmt::Octal for $BitFlags { + fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { + $crate::_core::fmt::Octal::fmt(&self.bits, f) + } + } + impl $crate::_core::fmt::LowerHex for $BitFlags { + fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { + $crate::_core::fmt::LowerHex::fmt(&self.bits, f) + } + } + impl $crate::_core::fmt::UpperHex for $BitFlags { + fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { + $crate::_core::fmt::UpperHex::fmt(&self.bits, f) + } + } + + #[allow(dead_code)] + impl $BitFlags { + $( + $(#[$attr $($args)*])* + pub const $Flag: Self = Self { bits: $value }; + )* + + /// Returns an empty set of flags. + #[inline] + pub const fn empty() -> Self { + Self { bits: 0 } + } + + /// Returns the set containing all flags. + #[inline] + pub const fn all() -> Self { + __impl_all_bitflags! { + $BitFlags: $T { + $( + $(#[$attr $($args)*])* + $Flag = $value; + )* + } + } + } + + /// Returns the raw value of the flags currently stored. + #[inline] + pub const fn bits(&self) -> $T { + self.bits + } + + /// Convert from underlying bit representation, unless that + /// representation contains bits that do not correspond to a flag. + #[inline] + pub const fn from_bits(bits: $T) -> $crate::_core::option::Option { + if (bits & !Self::all().bits()) == 0 { + $crate::_core::option::Option::Some(Self { bits }) + } else { + $crate::_core::option::Option::None + } + } + + /// Convert from underlying bit representation, dropping any bits + /// that do not correspond to flags. + #[inline] + pub const fn from_bits_truncate(bits: $T) -> Self { + Self { bits: bits & Self::all().bits } + } + + /// Convert from underlying bit representation, preserving all + /// bits (even those not corresponding to a defined flag). + /// + /// # Safety + /// + /// The caller of the `bitflags!` macro can chose to allow or + /// disallow extra bits for their bitflags type. + /// + /// The caller of `from_bits_unchecked()` has to ensure that + /// all bits correspond to a defined flag or that extra bits + /// are valid for this bitflags type. + #[inline] + pub const unsafe fn from_bits_unchecked(bits: $T) -> Self { + Self { bits } + } + + /// Returns `true` if no flags are currently stored. + #[inline] + pub const fn is_empty(&self) -> bool { + self.bits() == Self::empty().bits() + } + + /// Returns `true` if all flags are currently set. + #[inline] + pub const fn is_all(&self) -> bool { + Self::all().bits | self.bits == self.bits + } + + /// Returns `true` if there are flags common to both `self` and `other`. + #[inline] + pub const fn intersects(&self, other: Self) -> bool { + !(Self { bits: self.bits & other.bits}).is_empty() + } + + /// Returns `true` if all of the flags in `other` are contained within `self`. + #[inline] + pub const fn contains(&self, other: Self) -> bool { + (self.bits & other.bits) == other.bits + } + + /// Inserts the specified flags in-place. + #[inline] + pub fn insert(&mut self, other: Self) { + self.bits |= other.bits; + } + + /// Removes the specified flags in-place. + #[inline] + pub fn remove(&mut self, other: Self) { + self.bits &= !other.bits; + } + + /// Toggles the specified flags in-place. + #[inline] + pub fn toggle(&mut self, other: Self) { + self.bits ^= other.bits; + } + + /// Inserts or removes the specified flags depending on the passed value. + #[inline] + pub fn set(&mut self, other: Self, value: bool) { + if value { + self.insert(other); + } else { + self.remove(other); + } + } + + /// Returns the intersection between the flags in `self` and + /// `other`. + /// + /// Specifically, the returned set contains only the flags which are + /// present in *both* `self` *and* `other`. + /// + /// This is equivalent to using the `&` operator (e.g. + /// [`ops::BitAnd`]), as in `flags & other`. + /// + /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html + #[inline] + #[must_use] + pub const fn intersection(self, other: Self) -> Self { + Self { bits: self.bits & other.bits } + } + + /// Returns the union of between the flags in `self` and `other`. + /// + /// Specifically, the returned set contains all flags which are + /// present in *either* `self` *or* `other`, including any which are + /// present in both (see [`Self::symmetric_difference`] if that + /// is undesirable). + /// + /// This is equivalent to using the `|` operator (e.g. + /// [`ops::BitOr`]), as in `flags | other`. + /// + /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html + #[inline] + #[must_use] + pub const fn union(self, other: Self) -> Self { + Self { bits: self.bits | other.bits } + } + + /// Returns the difference between the flags in `self` and `other`. + /// + /// Specifically, the returned set contains all flags present in + /// `self`, except for the ones present in `other`. + /// + /// It is also conceptually equivalent to the "bit-clear" operation: + /// `flags & !other` (and this syntax is also supported). + /// + /// This is equivalent to using the `-` operator (e.g. + /// [`ops::Sub`]), as in `flags - other`. + /// + /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html + #[inline] + #[must_use] + pub const fn difference(self, other: Self) -> Self { + Self { bits: self.bits & !other.bits } + } + + /// Returns the [symmetric difference][sym-diff] between the flags + /// in `self` and `other`. + /// + /// Specifically, the returned set contains the flags present which + /// are present in `self` or `other`, but that are not present in + /// both. Equivalently, it contains the flags present in *exactly + /// one* of the sets `self` and `other`. + /// + /// This is equivalent to using the `^` operator (e.g. + /// [`ops::BitXor`]), as in `flags ^ other`. + /// + /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference + /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html + #[inline] + #[must_use] + pub const fn symmetric_difference(self, other: Self) -> Self { + Self { bits: self.bits ^ other.bits } + } + + /// Returns the complement of this set of flags. + /// + /// Specifically, the returned set contains all the flags which are + /// not set in `self`, but which are allowed for this type. + /// + /// Alternatively, it can be thought of as the set difference + /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`) + /// + /// This is equivalent to using the `!` operator (e.g. + /// [`ops::Not`]), as in `!flags`. + /// + /// [`Self::all()`]: Self::all + /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html + #[inline] + #[must_use] + pub const fn complement(self) -> Self { + Self::from_bits_truncate(!self.bits) + } + + } + + impl $crate::_core::ops::BitOr for $BitFlags { + type Output = Self; + + /// Returns the union of the two sets of flags. + #[inline] + fn bitor(self, other: $BitFlags) -> Self { + Self { bits: self.bits | other.bits } + } + } + + impl $crate::_core::ops::BitOrAssign for $BitFlags { + /// Adds the set of flags. + #[inline] + fn bitor_assign(&mut self, other: Self) { + self.bits |= other.bits; + } + } + + impl $crate::_core::ops::BitXor for $BitFlags { + type Output = Self; + + /// Returns the left flags, but with all the right flags toggled. + #[inline] + fn bitxor(self, other: Self) -> Self { + Self { bits: self.bits ^ other.bits } + } + } + + impl $crate::_core::ops::BitXorAssign for $BitFlags { + /// Toggles the set of flags. + #[inline] + fn bitxor_assign(&mut self, other: Self) { + self.bits ^= other.bits; + } + } + + impl $crate::_core::ops::BitAnd for $BitFlags { + type Output = Self; + + /// Returns the intersection between the two sets of flags. + #[inline] + fn bitand(self, other: Self) -> Self { + Self { bits: self.bits & other.bits } + } + } + + impl $crate::_core::ops::BitAndAssign for $BitFlags { + /// Disables all flags disabled in the set. + #[inline] + fn bitand_assign(&mut self, other: Self) { + self.bits &= other.bits; + } + } + + impl $crate::_core::ops::Sub for $BitFlags { + type Output = Self; + + /// Returns the set difference of the two sets of flags. + #[inline] + fn sub(self, other: Self) -> Self { + Self { bits: self.bits & !other.bits } + } + } + + impl $crate::_core::ops::SubAssign for $BitFlags { + /// Disables all flags enabled in the set. + #[inline] + fn sub_assign(&mut self, other: Self) { + self.bits &= !other.bits; + } + } + + impl $crate::_core::ops::Not for $BitFlags { + type Output = Self; + + /// Returns the complement of this set of flags. + #[inline] + fn not(self) -> Self { + Self { bits: !self.bits } & Self::all() + } + } + + impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags { + fn extend>(&mut self, iterator: T) { + for item in iterator { + self.insert(item) + } + } + } + + impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags { + fn from_iter>(iterator: T) -> Self { + let mut result = Self::empty(); + result.extend(iterator); + result + } + } + }; + + // Every attribute that the user writes on a const is applied to the + // corresponding const that we generate, but within the implementation of + // Debug and all() we want to ignore everything but #[cfg] attributes. In + // particular, including a #[deprecated] attribute on those items would fail + // to compile. + // https://github.com/bitflags/bitflags/issues/109 + // + // Input: + // + // ? #[cfg(feature = "advanced")] + // ? #[deprecated(note = "Use something else.")] + // ? #[doc = r"High quality documentation."] + // fn f() -> i32 { /* ... */ } + // + // Output: + // + // #[cfg(feature = "advanced")] + // fn f() -> i32 { /* ... */ } + ( + $(#[$filtered:meta])* + ? #[cfg $($cfgargs:tt)*] + $(? #[$rest:ident $($restargs:tt)*])* + fn $($item:tt)* + ) => { + __impl_bitflags! { + $(#[$filtered])* + #[cfg $($cfgargs)*] + $(? #[$rest $($restargs)*])* + fn $($item)* + } + }; + ( + $(#[$filtered:meta])* + // $next != `cfg` + ? #[$next:ident $($nextargs:tt)*] + $(? #[$rest:ident $($restargs:tt)*])* + fn $($item:tt)* + ) => { + __impl_bitflags! { + $(#[$filtered])* + // $next filtered out + $(? #[$rest $($restargs)*])* + fn $($item)* + } + }; + ( + $(#[$filtered:meta])* + fn $($item:tt)* + ) => { + $(#[$filtered])* + fn $($item)* + }; + + // Every attribute that the user writes on a const is applied to the + // corresponding const that we generate, but within the implementation of + // Debug and all() we want to ignore everything but #[cfg] attributes. In + // particular, including a #[deprecated] attribute on those items would fail + // to compile. + // https://github.com/bitflags/bitflags/issues/109 + // + // const version + // + // Input: + // + // ? #[cfg(feature = "advanced")] + // ? #[deprecated(note = "Use something else.")] + // ? #[doc = r"High quality documentation."] + // const f: i32 { /* ... */ } + // + // Output: + // + // #[cfg(feature = "advanced")] + // const f: i32 { /* ... */ } + ( + $(#[$filtered:meta])* + ? #[cfg $($cfgargs:tt)*] + $(? #[$rest:ident $($restargs:tt)*])* + const $($item:tt)* + ) => { + __impl_bitflags! { + $(#[$filtered])* + #[cfg $($cfgargs)*] + $(? #[$rest $($restargs)*])* + const $($item)* + } + }; + ( + $(#[$filtered:meta])* + // $next != `cfg` + ? #[$next:ident $($nextargs:tt)*] + $(? #[$rest:ident $($restargs:tt)*])* + const $($item:tt)* + ) => { + __impl_bitflags! { + $(#[$filtered])* + // $next filtered out + $(? #[$rest $($restargs)*])* + const $($item)* + } + }; + ( + $(#[$filtered:meta])* + const $($item:tt)* + ) => { + $(#[$filtered])* + const $($item)* + }; +} + +#[cfg(feature = "example_generated")] +pub mod example_generated; + +#[cfg(test)] +mod tests { + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; + + bitflags! { + #[doc = "> The first principle is that you must not fool yourself — and"] + #[doc = "> you are the easiest person to fool."] + #[doc = "> "] + #[doc = "> - Richard Feynman"] + #[derive(Default)] + struct Flags: u32 { + const A = 0b00000001; + #[doc = " macros are way better at generating code than trans is"] + const B = 0b00000010; + const C = 0b00000100; + #[doc = "* cmr bed"] + #[doc = "* strcat table"] + #[doc = " wait what?"] + const ABC = Self::A.bits | Self::B.bits | Self::C.bits; + } + + struct _CfgFlags: u32 { + #[cfg(unix)] + const _CFG_A = 0b01; + #[cfg(windows)] + const _CFG_B = 0b01; + #[cfg(unix)] + const _CFG_C = Self::_CFG_A.bits | 0b10; + } + + struct AnotherSetOfFlags: i8 { + const ANOTHER_FLAG = -1_i8; + } + + struct LongFlags: u32 { + const LONG_A = 0b1111111111111111; + } + } + + bitflags! { + struct EmptyFlags: u32 { + } + } + + #[test] + fn test_bits() { + assert_eq!(Flags::empty().bits(), 0b00000000); + assert_eq!(Flags::A.bits(), 0b00000001); + assert_eq!(Flags::ABC.bits(), 0b00000111); + + assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); + assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8); + + assert_eq!(EmptyFlags::empty().bits(), 0b00000000); + } + + #[test] + fn test_from_bits() { + assert_eq!(Flags::from_bits(0), Some(Flags::empty())); + assert_eq!(Flags::from_bits(0b1), Some(Flags::A)); + assert_eq!(Flags::from_bits(0b10), Some(Flags::B)); + assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B)); + assert_eq!(Flags::from_bits(0b1000), None); + + assert_eq!( + AnotherSetOfFlags::from_bits(!0_i8), + Some(AnotherSetOfFlags::ANOTHER_FLAG) + ); + + assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty())); + assert_eq!(EmptyFlags::from_bits(0b1), None); + } + + #[test] + fn test_from_bits_truncate() { + assert_eq!(Flags::from_bits_truncate(0), Flags::empty()); + assert_eq!(Flags::from_bits_truncate(0b1), Flags::A); + assert_eq!(Flags::from_bits_truncate(0b10), Flags::B); + assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B)); + assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty()); + assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A); + + assert_eq!( + AnotherSetOfFlags::from_bits_truncate(0_i8), + AnotherSetOfFlags::empty() + ); + + assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty()); + assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty()); + } + + #[test] + fn test_from_bits_unchecked() { + let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; + assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty()); + assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A); + assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B); + + assert_eq!( + unsafe { Flags::from_bits_unchecked(0b11) }, + (Flags::A | Flags::B) + ); + assert_eq!( + unsafe { Flags::from_bits_unchecked(0b1000) }, + (extra | Flags::empty()) + ); + assert_eq!( + unsafe { Flags::from_bits_unchecked(0b1001) }, + (extra | Flags::A) + ); + + let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) }; + assert_eq!( + unsafe { EmptyFlags::from_bits_unchecked(0b1000) }, + (extra | EmptyFlags::empty()) + ); + } + + #[test] + fn test_is_empty() { + assert!(Flags::empty().is_empty()); + assert!(!Flags::A.is_empty()); + assert!(!Flags::ABC.is_empty()); + + assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty()); + + assert!(EmptyFlags::empty().is_empty()); + assert!(EmptyFlags::all().is_empty()); + } + + #[test] + fn test_is_all() { + assert!(Flags::all().is_all()); + assert!(!Flags::A.is_all()); + assert!(Flags::ABC.is_all()); + + let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; + assert!(!extra.is_all()); + assert!(!(Flags::A | extra).is_all()); + assert!((Flags::ABC | extra).is_all()); + + assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all()); + + assert!(EmptyFlags::all().is_all()); + assert!(EmptyFlags::empty().is_all()); + } + + #[test] + fn test_two_empties_do_not_intersect() { + let e1 = Flags::empty(); + let e2 = Flags::empty(); + assert!(!e1.intersects(e2)); + + assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG)); + } + + #[test] + fn test_empty_does_not_intersect_with_full() { + let e1 = Flags::empty(); + let e2 = Flags::ABC; + assert!(!e1.intersects(e2)); + } + + #[test] + fn test_disjoint_intersects() { + let e1 = Flags::A; + let e2 = Flags::B; + assert!(!e1.intersects(e2)); + } + + #[test] + fn test_overlapping_intersects() { + let e1 = Flags::A; + let e2 = Flags::A | Flags::B; + assert!(e1.intersects(e2)); + } + + #[test] + fn test_contains() { + let e1 = Flags::A; + let e2 = Flags::A | Flags::B; + assert!(!e1.contains(e2)); + assert!(e2.contains(e1)); + assert!(Flags::ABC.contains(e2)); + + assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG)); + + assert!(EmptyFlags::empty().contains(EmptyFlags::empty())); + } + + #[test] + fn test_insert() { + let mut e1 = Flags::A; + let e2 = Flags::A | Flags::B; + e1.insert(e2); + assert_eq!(e1, e2); + + let mut e3 = AnotherSetOfFlags::empty(); + e3.insert(AnotherSetOfFlags::ANOTHER_FLAG); + assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG); + } + + #[test] + fn test_remove() { + let mut e1 = Flags::A | Flags::B; + let e2 = Flags::A | Flags::C; + e1.remove(e2); + assert_eq!(e1, Flags::B); + + let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG; + e3.remove(AnotherSetOfFlags::ANOTHER_FLAG); + assert_eq!(e3, AnotherSetOfFlags::empty()); + } + + #[test] + fn test_operators() { + let e1 = Flags::A | Flags::C; + let e2 = Flags::B | Flags::C; + assert_eq!((e1 | e2), Flags::ABC); // union + assert_eq!((e1 & e2), Flags::C); // intersection + assert_eq!((e1 - e2), Flags::A); // set difference + assert_eq!(!e2, Flags::A); // set complement + assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle + let mut e3 = e1; + e3.toggle(e2); + assert_eq!(e3, Flags::A | Flags::B); + + let mut m4 = AnotherSetOfFlags::empty(); + m4.toggle(AnotherSetOfFlags::empty()); + assert_eq!(m4, AnotherSetOfFlags::empty()); + } + + #[test] + fn test_operators_unchecked() { + let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; + let e1 = Flags::A | Flags::C | extra; + let e2 = Flags::B | Flags::C; + assert_eq!((e1 | e2), (Flags::ABC | extra)); // union + assert_eq!((e1 & e2), Flags::C); // intersection + assert_eq!((e1 - e2), (Flags::A | extra)); // set difference + assert_eq!(!e2, Flags::A); // set complement + assert_eq!(!e1, Flags::B); // set complement + assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle + let mut e3 = e1; + e3.toggle(e2); + assert_eq!(e3, Flags::A | Flags::B | extra); + } + + #[test] + fn test_set_ops_basic() { + let ab = Flags::A.union(Flags::B); + let ac = Flags::A.union(Flags::C); + let bc = Flags::B.union(Flags::C); + assert_eq!(ab.bits, 0b011); + assert_eq!(bc.bits, 0b110); + assert_eq!(ac.bits, 0b101); + + assert_eq!(ab, Flags::B.union(Flags::A)); + assert_eq!(ac, Flags::C.union(Flags::A)); + assert_eq!(bc, Flags::C.union(Flags::B)); + + assert_eq!(ac, Flags::A | Flags::C); + assert_eq!(bc, Flags::B | Flags::C); + assert_eq!(ab.union(bc), Flags::ABC); + + assert_eq!(ac, Flags::A | Flags::C); + assert_eq!(bc, Flags::B | Flags::C); + + assert_eq!(ac.union(bc), ac | bc); + assert_eq!(ac.union(bc), Flags::ABC); + assert_eq!(bc.union(ac), Flags::ABC); + + assert_eq!(ac.intersection(bc), ac & bc); + assert_eq!(ac.intersection(bc), Flags::C); + assert_eq!(bc.intersection(ac), Flags::C); + + assert_eq!(ac.difference(bc), ac - bc); + assert_eq!(bc.difference(ac), bc - ac); + assert_eq!(ac.difference(bc), Flags::A); + assert_eq!(bc.difference(ac), Flags::B); + + assert_eq!(bc.complement(), !bc); + assert_eq!(bc.complement(), Flags::A); + assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B)); + assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B)); + } + + #[test] + fn test_set_ops_const() { + // These just test that these compile and don't cause use-site panics + // (would be possible if we had some sort of UB) + const INTERSECT: Flags = Flags::all().intersection(Flags::C); + const UNION: Flags = Flags::A.union(Flags::C); + const DIFFERENCE: Flags = Flags::all().difference(Flags::A); + const COMPLEMENT: Flags = Flags::C.complement(); + const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE); + assert_eq!(INTERSECT, Flags::C); + assert_eq!(UNION, Flags::A | Flags::C); + assert_eq!(DIFFERENCE, Flags::all() - Flags::A); + assert_eq!(COMPLEMENT, !Flags::C); + assert_eq!(SYM_DIFFERENCE, (Flags::A | Flags::C) ^ (Flags::all() - Flags::A)); + } + + #[test] + fn test_set_ops_unchecked() { + let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; + let e1 = Flags::A.union(Flags::C).union(extra); + let e2 = Flags::B.union(Flags::C); + assert_eq!(e1.bits, 0b1101); + assert_eq!(e1.union(e2), (Flags::ABC | extra)); + assert_eq!(e1.intersection(e2), Flags::C); + assert_eq!(e1.difference(e2), Flags::A | extra); + assert_eq!(e2.difference(e1), Flags::B); + assert_eq!(e2.complement(), Flags::A); + assert_eq!(e1.complement(), Flags::B); + assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle + } + + #[test] + fn test_set_ops_exhaustive() { + // Define a flag that contains gaps to help exercise edge-cases, + // especially around "unknown" flags (e.g. ones outside of `all()` + // `from_bits_unchecked`). + // - when lhs and rhs both have different sets of unknown flags. + // - unknown flags at both ends, and in the middle + // - cases with "gaps". + bitflags! { + struct Test: u16 { + // Intentionally no `A` + const B = 0b000000010; + // Intentionally no `C` + const D = 0b000001000; + const E = 0b000010000; + const F = 0b000100000; + const G = 0b001000000; + // Intentionally no `H` + const I = 0b100000000; + } + } + let iter_test_flags = + || (0..=0b111_1111_1111).map(|bits| unsafe { Test::from_bits_unchecked(bits) }); + + for a in iter_test_flags() { + assert_eq!( + a.complement(), + Test::from_bits_truncate(!a.bits), + "wrong result: !({:?})", + a, + ); + assert_eq!(a.complement(), !a, "named != op: !({:?})", a); + for b in iter_test_flags() { + // Check that the named operations produce the expected bitwise + // values. + assert_eq!( + a.union(b).bits, + a.bits | b.bits, + "wrong result: `{:?}` | `{:?}`", + a, + b, + ); + assert_eq!( + a.intersection(b).bits, + a.bits & b.bits, + "wrong result: `{:?}` & `{:?}`", + a, + b, + ); + assert_eq!( + a.symmetric_difference(b).bits, + a.bits ^ b.bits, + "wrong result: `{:?}` ^ `{:?}`", + a, + b, + ); + assert_eq!( + a.difference(b).bits, + a.bits & !b.bits, + "wrong result: `{:?}` - `{:?}`", + a, + b, + ); + // Note: Difference is checked as both `a - b` and `b - a` + assert_eq!( + b.difference(a).bits, + b.bits & !a.bits, + "wrong result: `{:?}` - `{:?}`", + b, + a, + ); + // Check that the named set operations are equivalent to the + // bitwise equivalents + assert_eq!(a.union(b), a | b, "named != op: `{:?}` | `{:?}`", a, b,); + assert_eq!( + a.intersection(b), + a & b, + "named != op: `{:?}` & `{:?}`", + a, + b, + ); + assert_eq!( + a.symmetric_difference(b), + a ^ b, + "named != op: `{:?}` ^ `{:?}`", + a, + b, + ); + assert_eq!(a.difference(b), a - b, "named != op: `{:?}` - `{:?}`", a, b,); + // Note: Difference is checked as both `a - b` and `b - a` + assert_eq!(b.difference(a), b - a, "named != op: `{:?}` - `{:?}`", b, a,); + // Verify that the operations which should be symmetric are + // actually symmetric. + assert_eq!(a.union(b), b.union(a), "asymmetry: `{:?}` | `{:?}`", a, b,); + assert_eq!( + a.intersection(b), + b.intersection(a), + "asymmetry: `{:?}` & `{:?}`", + a, + b, + ); + assert_eq!( + a.symmetric_difference(b), + b.symmetric_difference(a), + "asymmetry: `{:?}` ^ `{:?}`", + a, + b, + ); + } + } + } + + #[test] + fn test_set() { + let mut e1 = Flags::A | Flags::C; + e1.set(Flags::B, true); + e1.set(Flags::C, false); + + assert_eq!(e1, Flags::A | Flags::B); + } + + #[test] + fn test_assignment_operators() { + let mut m1 = Flags::empty(); + let e1 = Flags::A | Flags::C; + // union + m1 |= Flags::A; + assert_eq!(m1, Flags::A); + // intersection + m1 &= e1; + assert_eq!(m1, Flags::A); + // set difference + m1 -= m1; + assert_eq!(m1, Flags::empty()); + // toggle + m1 ^= e1; + assert_eq!(m1, e1); + } + + #[test] + fn test_const_fn() { + const _M1: Flags = Flags::empty(); + + const M2: Flags = Flags::A; + assert_eq!(M2, Flags::A); + + const M3: Flags = Flags::C; + assert_eq!(M3, Flags::C); + } + + #[test] + fn test_extend() { + let mut flags; + + flags = Flags::empty(); + flags.extend([].iter().cloned()); + assert_eq!(flags, Flags::empty()); + + flags = Flags::empty(); + flags.extend([Flags::A, Flags::B].iter().cloned()); + assert_eq!(flags, Flags::A | Flags::B); + + flags = Flags::A; + flags.extend([Flags::A, Flags::B].iter().cloned()); + assert_eq!(flags, Flags::A | Flags::B); + + flags = Flags::B; + flags.extend([Flags::A, Flags::ABC].iter().cloned()); + assert_eq!(flags, Flags::ABC); + } + + #[test] + fn test_from_iterator() { + assert_eq!([].iter().cloned().collect::(), Flags::empty()); + assert_eq!( + [Flags::A, Flags::B].iter().cloned().collect::(), + Flags::A | Flags::B + ); + assert_eq!( + [Flags::A, Flags::ABC].iter().cloned().collect::(), + Flags::ABC + ); + } + + #[test] + fn test_lt() { + let mut a = Flags::empty(); + let mut b = Flags::empty(); + + assert!(!(a < b) && !(b < a)); + b = Flags::B; + assert!(a < b); + a = Flags::C; + assert!(!(a < b) && b < a); + b = Flags::C | Flags::B; + assert!(a < b); + } + + #[test] + fn test_ord() { + let mut a = Flags::empty(); + let mut b = Flags::empty(); + + assert!(a <= b && a >= b); + a = Flags::A; + assert!(a > b && a >= b); + assert!(b < a && b <= a); + b = Flags::B; + assert!(b > a && b >= a); + assert!(a < b && a <= b); + } + + fn hash(t: &T) -> u64 { + let mut s = DefaultHasher::new(); + t.hash(&mut s); + s.finish() + } + + #[test] + fn test_hash() { + let mut x = Flags::empty(); + let mut y = Flags::empty(); + assert_eq!(hash(&x), hash(&y)); + x = Flags::all(); + y = Flags::ABC; + assert_eq!(hash(&x), hash(&y)); + } + + #[test] + fn test_default() { + assert_eq!(Flags::empty(), Flags::default()); + } + + #[test] + fn test_debug() { + assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); + assert_eq!(format!("{:?}", Flags::empty()), "(empty)"); + assert_eq!(format!("{:?}", Flags::ABC), "A | B | C | ABC"); + let extra = unsafe { Flags::from_bits_unchecked(0xb8) }; + assert_eq!(format!("{:?}", extra), "0xb8"); + assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8"); + + assert_eq!( + format!("{:?}", Flags::ABC | extra), + "A | B | C | ABC | 0xb8" + ); + + assert_eq!(format!("{:?}", EmptyFlags::empty()), "(empty)"); + } + + #[test] + fn test_binary() { + assert_eq!(format!("{:b}", Flags::ABC), "111"); + assert_eq!(format!("{:#b}", Flags::ABC), "0b111"); + let extra = unsafe { Flags::from_bits_unchecked(0b1010000) }; + assert_eq!(format!("{:b}", Flags::ABC | extra), "1010111"); + assert_eq!(format!("{:#b}", Flags::ABC | extra), "0b1010111"); + } + + #[test] + fn test_octal() { + assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777"); + assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777"); + let extra = unsafe { LongFlags::from_bits_unchecked(0o5000000) }; + assert_eq!(format!("{:o}", LongFlags::LONG_A | extra), "5177777"); + assert_eq!(format!("{:#o}", LongFlags::LONG_A | extra), "0o5177777"); + } + + #[test] + fn test_lowerhex() { + assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff"); + assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff"); + let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; + assert_eq!(format!("{:x}", LongFlags::LONG_A | extra), "e0ffff"); + assert_eq!(format!("{:#x}", LongFlags::LONG_A | extra), "0xe0ffff"); + } + + #[test] + fn test_upperhex() { + assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF"); + assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF"); + let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; + assert_eq!(format!("{:X}", LongFlags::LONG_A | extra), "E0FFFF"); + assert_eq!(format!("{:#X}", LongFlags::LONG_A | extra), "0xE0FFFF"); + } + + mod submodule { + bitflags! { + pub struct PublicFlags: i8 { + const X = 0; + } + + struct PrivateFlags: i8 { + const Y = 0; + } + } + + #[test] + fn test_private() { + let _ = PrivateFlags::Y; + } + } + + #[test] + fn test_public() { + let _ = submodule::PublicFlags::X; + } + + mod t1 { + mod foo { + pub type Bar = i32; + } + + bitflags! { + /// baz + struct Flags: foo::Bar { + const A = 0b00000001; + #[cfg(foo)] + const B = 0b00000010; + #[cfg(foo)] + const C = 0b00000010; + } + } + } + + #[test] + fn test_in_function() { + bitflags! { + struct Flags: u8 { + const A = 1; + #[cfg(any())] // false + const B = 2; + } + } + assert_eq!(Flags::all(), Flags::A); + assert_eq!(format!("{:?}", Flags::A), "A"); + } + + #[test] + fn test_deprecated() { + bitflags! { + pub struct TestFlags: u32 { + #[deprecated(note = "Use something else.")] + const ONE = 1; + } + } + } + + #[test] + fn test_pub_crate() { + mod module { + bitflags! { + pub (crate) struct Test: u8 { + const FOO = 1; + } + } + } + + assert_eq!(module::Test::FOO.bits(), 1); + } + + #[test] + fn test_pub_in_module() { + mod module { + mod submodule { + bitflags! { + // `pub (in super)` means only the module `module` will + // be able to access this. + pub (in super) struct Test: u8 { + const FOO = 1; + } + } + } + + mod test { + // Note: due to `pub (in super)`, + // this cannot be accessed directly by the testing code. + pub(super) fn value() -> u8 { + super::submodule::Test::FOO.bits() + } + } + + pub fn value() -> u8 { + test::value() + } + } + + assert_eq!(module::value(), 1) + } + + #[test] + fn test_zero_value_flags() { + bitflags! { + struct Flags: u32 { + const NONE = 0b0; + const SOME = 0b1; + } + } + + assert!(Flags::empty().contains(Flags::NONE)); + assert!(Flags::SOME.contains(Flags::NONE)); + assert!(Flags::NONE.is_empty()); + + assert_eq!(format!("{:?}", Flags::empty()), "NONE"); + assert_eq!(format!("{:?}", Flags::SOME), "SOME"); + } + + #[test] + fn test_empty_bitflags() { + bitflags! {} + } + + #[test] + fn test_u128_bitflags() { + bitflags! { + struct Flags128: u128 { + const A = 0x0000_0000_0000_0000_0000_0000_0000_0001; + const B = 0x0000_0000_0000_1000_0000_0000_0000_0000; + const C = 0x8000_0000_0000_0000_0000_0000_0000_0000; + const ABC = Self::A.bits | Self::B.bits | Self::C.bits; + } + } + + assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C); + assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001); + assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000); + assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000); + assert_eq!( + Flags128::ABC.bits, + 0x8000_0000_0000_1000_0000_0000_0000_0001 + ); + assert_eq!(format!("{:?}", Flags128::A), "A"); + assert_eq!(format!("{:?}", Flags128::B), "B"); + assert_eq!(format!("{:?}", Flags128::C), "C"); + assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC"); + } + + #[test] + fn test_serde_bitflags_serialize() { + let flags = SerdeFlags::A | SerdeFlags::B; + + let serialized = serde_json::to_string(&flags).unwrap(); + + assert_eq!(serialized, r#"{"bits":3}"#); + } + + #[test] + fn test_serde_bitflags_deserialize() { + let deserialized: SerdeFlags = serde_json::from_str(r#"{"bits":12}"#).unwrap(); + + let expected = SerdeFlags::C | SerdeFlags::D; + + assert_eq!(deserialized.bits, expected.bits); + } + + #[test] + fn test_serde_bitflags_roundtrip() { + let flags = SerdeFlags::A | SerdeFlags::B; + + let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap(); + + assert_eq!(deserialized.bits, flags.bits); + } + + bitflags! { + #[derive(serde::Serialize, serde::Deserialize)] + struct SerdeFlags: u32 { + const A = 1; + const B = 2; + const C = 4; + const D = 8; + } + } +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/basic.rs b/utshell-0.5.0/vendor/bitflags/tests/basic.rs new file mode 100644 index 00000000..73a52bec --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/basic.rs @@ -0,0 +1,20 @@ +#![no_std] + +use bitflags::bitflags; + +bitflags! { + /// baz + struct Flags: u32 { + const A = 0b00000001; + #[doc = "bar"] + const B = 0b00000010; + const C = 0b00000100; + #[doc = "foo"] + const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits; + } +} + +#[test] +fn basic() { + assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C); +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.rs new file mode 100644 index 00000000..38f4822f --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.rs @@ -0,0 +1,10 @@ +use bitflags::bitflags; + +bitflags! { + #[derive(Clone, Copy)] + struct Flags: u32 { + const A = 0b00000001; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.stderr.beta new file mode 100644 index 00000000..0c13aa50 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/copy.stderr.beta @@ -0,0 +1,27 @@ +error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Flags` + --> $DIR/copy.rs:3:1 + | +3 | / bitflags! { +4 | | #[derive(Clone, Copy)] + | | ----- first implementation here +5 | | struct Flags: u32 { +6 | | const A = 0b00000001; +7 | | } +8 | | } + | |_^ conflicting implementation for `Flags` + | + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `Flags` + --> $DIR/copy.rs:3:1 + | +3 | / bitflags! { +4 | | #[derive(Clone, Copy)] + | | ---- first implementation here +5 | | struct Flags: u32 { +6 | | const A = 0b00000001; +7 | | } +8 | | } + | |_^ conflicting implementation for `Flags` + | + = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.rs new file mode 100644 index 00000000..4abbd630 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.rs @@ -0,0 +1,10 @@ +use bitflags::bitflags; + +bitflags! { + #[derive(PartialEq, Eq)] + struct Flags: u32 { + const A = 0b00000001; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.stderr.beta new file mode 100644 index 00000000..8a1a3b41 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/impls/eq.stderr.beta @@ -0,0 +1,55 @@ +error[E0119]: conflicting implementations of trait `std::cmp::PartialEq` for type `Flags` + --> $DIR/eq.rs:3:1 + | +3 | / bitflags! { +4 | | #[derive(PartialEq, Eq)] + | | --------- first implementation here +5 | | struct Flags: u32 { +6 | | const A = 0b00000001; +7 | | } +8 | | } + | |_^ conflicting implementation for `Flags` + | + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `std::cmp::Eq` for type `Flags` + --> $DIR/eq.rs:3:1 + | +3 | / bitflags! { +4 | | #[derive(PartialEq, Eq)] + | | -- first implementation here +5 | | struct Flags: u32 { +6 | | const A = 0b00000001; +7 | | } +8 | | } + | |_^ conflicting implementation for `Flags` + | + = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `std::marker::StructuralPartialEq` for type `Flags` + --> $DIR/eq.rs:3:1 + | +3 | / bitflags! { +4 | | #[derive(PartialEq, Eq)] + | | --------- first implementation here +5 | | struct Flags: u32 { +6 | | const A = 0b00000001; +7 | | } +8 | | } + | |_^ conflicting implementation for `Flags` + | + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `std::marker::StructuralEq` for type `Flags` + --> $DIR/eq.rs:3:1 + | +3 | / bitflags! { +4 | | #[derive(PartialEq, Eq)] + | | -- first implementation here +5 | | struct Flags: u32 { +6 | | const A = 0b00000001; +7 | | } +8 | | } + | |_^ conflicting implementation for `Flags` + | + = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.rs new file mode 100644 index 00000000..c2856b10 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.rs @@ -0,0 +1,123 @@ +use std::{ + fmt::{ + self, + Debug, + Display, + LowerHex, + UpperHex, + Octal, + Binary, + }, + ops::{ + BitAnd, + BitOr, + BitXor, + BitAndAssign, + BitOrAssign, + BitXorAssign, + Not, + }, +}; + +use bitflags::bitflags; + +// Ideally we'd actually want this to work, but currently need something like `num`'s `Zero` +// With some design work it could be made possible +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct MyInt(u8); + +impl BitAnd for MyInt { + type Output = Self; + + fn bitand(self, other: Self) -> Self { + MyInt(self.0 & other.0) + } +} + +impl BitOr for MyInt { + type Output = Self; + + fn bitor(self, other: Self) -> Self { + MyInt(self.0 | other.0) + } +} + +impl BitXor for MyInt { + type Output = Self; + + fn bitxor(self, other: Self) -> Self { + MyInt(self.0 ^ other.0) + } +} + +impl BitAndAssign for MyInt { + fn bitand_assign(&mut self, other: Self) { + self.0 &= other.0 + } +} + +impl BitOrAssign for MyInt { + fn bitor_assign(&mut self, other: Self) { + self.0 |= other.0 + } +} + +impl BitXorAssign for MyInt { + fn bitxor_assign(&mut self, other: Self) { + self.0 ^= other.0 + } +} + +impl Debug for MyInt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.0, f) + } +} + +impl Display for MyInt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl LowerHex for MyInt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + LowerHex::fmt(&self.0, f) + } +} + +impl UpperHex for MyInt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + UpperHex::fmt(&self.0, f) + } +} + +impl Octal for MyInt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Octal::fmt(&self.0, f) + } +} + +impl Binary for MyInt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Binary::fmt(&self.0, f) + } +} + +impl Not for MyInt { + type Output = MyInt; + + fn not(self) -> Self { + MyInt(!self.0) + } +} + +bitflags! { + struct Flags128: MyInt { + const A = MyInt(0b0000_0001u8); + const B = MyInt(0b0000_0010u8); + const C = MyInt(0b0000_0100u8); + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta new file mode 100644 index 00000000..1f0fb5cf --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/all_defined.rs:115:1 + | +115 | / bitflags! { +116 | | struct Flags128: MyInt { +117 | | const A = MyInt(0b0000_0001u8); +118 | | const B = MyInt(0b0000_0010u8); +119 | | const C = MyInt(0b0000_0100u8); +120 | | } +121 | | } + | |_^ expected struct `MyInt`, found integer + | + = note: this error originates in the macro `__impl_all_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/all_defined.rs:115:1 + | +115 | / bitflags! { +116 | | struct Flags128: MyInt { +117 | | const A = MyInt(0b0000_0001u8); +118 | | const B = MyInt(0b0000_0010u8); +119 | | const C = MyInt(0b0000_0100u8); +120 | | } +121 | | } + | |_^ expected struct `MyInt`, found integer + | + = note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.rs new file mode 100644 index 00000000..fff6b2cc --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.rs @@ -0,0 +1,13 @@ +use bitflags::bitflags; + +struct MyInt(u8); + +bitflags! { + struct Flags128: MyInt { + const A = MyInt(0b0000_0001); + const B = MyInt(0b0000_0010); + const C = MyInt(0b0000_0100); + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta new file mode 100644 index 00000000..ee95f836 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta @@ -0,0 +1,13 @@ +error[E0204]: the trait `Copy` may not be implemented for this type + --> $DIR/all_missing.rs:5:1 + | +5 | / bitflags! { +6 | | struct Flags128: MyInt { +7 | | const A = MyInt(0b0000_0001); +8 | | const B = MyInt(0b0000_0010); +9 | | const C = MyInt(0b0000_0100); +10 | | } +11 | | } + | |_^ this field does not implement `Copy` + | + = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.rs new file mode 100644 index 00000000..a6a3912a --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.rs @@ -0,0 +1,13 @@ +mod example { + use bitflags::bitflags; + + bitflags! { + pub struct Flags1: u32 { + const FLAG_A = 0b00000001; + } + } +} + +fn main() { + let flag1 = example::Flags1::FLAG_A.bits; +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.stderr.beta new file mode 100644 index 00000000..58a04660 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_field.stderr.beta @@ -0,0 +1,10 @@ +error[E0616]: field `bits` of struct `Flags1` is private + --> $DIR/private_field.rs:12:41 + | +12 | let flag1 = example::Flags1::FLAG_A.bits; + | ^^^^ private field + | +help: a method `bits` also exists, call it with parentheses + | +12 | let flag1 = example::Flags1::FLAG_A.bits(); + | ^^ diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.rs new file mode 100644 index 00000000..85a5b186 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.rs @@ -0,0 +1,18 @@ +mod example { + use bitflags::bitflags; + + bitflags! { + pub struct Flags1: u32 { + const FLAG_A = 0b00000001; + } + + struct Flags2: u32 { + const FLAG_B = 0b00000010; + } + } +} + +fn main() { + let flag1 = example::Flags1::FLAG_A; + let flag2 = example::Flags2::FLAG_B; +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta new file mode 100644 index 00000000..d23f8320 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta @@ -0,0 +1,18 @@ +error[E0603]: struct `Flags2` is private + --> $DIR/private_flags.rs:17:26 + | +17 | let flag2 = example::Flags2::FLAG_B; + | ^^^^^^ private struct + | +note: the struct `Flags2` is defined here + --> $DIR/private_flags.rs:4:5 + | +4 | / bitflags! { +5 | | pub struct Flags1: u32 { +6 | | const FLAG_A = 0b00000001; +7 | | } +... | +11 | | } +12 | | } + | |_____^ + = note: this error originates in the macro `bitflags` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.rs new file mode 100644 index 00000000..b90f0ce9 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.rs @@ -0,0 +1,9 @@ +use bitflags::bitflags; + +bitflags! { + pub struct Flags1: u32 { + pub const FLAG_A = 0b00000001; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta new file mode 100644 index 00000000..b01122c7 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta @@ -0,0 +1,5 @@ +error: no rules expected the token `pub` + --> $DIR/pub_const.rs:5:9 + | +5 | pub const FLAG_A = 0b00000001; + | ^^^ no rules expected this token in macro call diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/convert.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/convert.rs new file mode 100644 index 00000000..1f02982a --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/convert.rs @@ -0,0 +1,17 @@ +use bitflags::bitflags; + +bitflags! { + struct Flags: u32 { + const A = 0b00000001; + } +} + +impl From for Flags { + fn from(v: u32) -> Flags { + Flags::from_bits_truncate(v) + } +} + +fn main() { + +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/default.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/default.rs new file mode 100644 index 00000000..a97b6536 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/default.rs @@ -0,0 +1,10 @@ +use bitflags::bitflags; + +bitflags! { + #[derive(Default)] + struct Flags: u32 { + const A = 0b00000001; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/inherent_methods.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/inherent_methods.rs new file mode 100644 index 00000000..3052c460 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/impls/inherent_methods.rs @@ -0,0 +1,15 @@ +use bitflags::bitflags; + +bitflags! { + struct Flags: u32 { + const A = 0b00000001; + } +} + +impl Flags { + pub fn new() -> Flags { + Flags::A + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/core.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/core.rs new file mode 100644 index 00000000..47549215 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/core.rs @@ -0,0 +1,14 @@ +use bitflags::bitflags; + +// Checks for possible errors caused by overriding names used by `bitflags!` internally. + +mod core {} +mod _core {} + +bitflags! { + struct Test: u8 { + const A = 1; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/stringify.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/stringify.rs new file mode 100644 index 00000000..b04f2f6a --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/redefinition/stringify.rs @@ -0,0 +1,19 @@ +use bitflags::bitflags; + +// Checks for possible errors caused by overriding names used by `bitflags!` internally. + +#[allow(unused_macros)] +macro_rules! stringify { + ($($t:tt)*) => { "..." }; +} + +bitflags! { + struct Test: u8 { + const A = 1; + } +} + +fn main() { + // Just make sure we don't call the redefined `stringify` macro + assert_eq!(format!("{:?}", Test::A), "A"); +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/c.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/c.rs new file mode 100644 index 00000000..6feba36e --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/c.rs @@ -0,0 +1,10 @@ +use bitflags::bitflags; + +bitflags! { + #[repr(C)] + struct Flags: u32 { + const A = 0b00000001; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/transparent.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/transparent.rs new file mode 100644 index 00000000..e38db4dd --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/repr/transparent.rs @@ -0,0 +1,10 @@ +use bitflags::bitflags; + +bitflags! { + #[repr(transparent)] + struct Flags: u32 { + const A = 0b00000001; + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/bits_field.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/bits_field.rs new file mode 100644 index 00000000..33a7967e --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/bits_field.rs @@ -0,0 +1,11 @@ +use bitflags::bitflags; + +bitflags! { + pub struct Flags1: u32 { + const FLAG_A = 0b00000001; + } +} + +fn main() { + assert_eq!(0b00000001, Flags1::FLAG_A.bits); +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/pub_in.rs b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/pub_in.rs new file mode 100644 index 00000000..c11050e3 --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile-pass/visibility/pub_in.rs @@ -0,0 +1,19 @@ +mod a { + mod b { + use bitflags::bitflags; + + bitflags! { + pub(in crate::a) struct Flags: u32 { + const FLAG_A = 0b00000001; + } + } + } + + pub fn flags() -> u32 { + b::Flags::FLAG_A.bits() + } +} + +fn main() { + assert_eq!(0b00000001, a::flags()); +} diff --git a/utshell-0.5.0/vendor/bitflags/tests/compile.rs b/utshell-0.5.0/vendor/bitflags/tests/compile.rs new file mode 100644 index 00000000..ed02d01e --- /dev/null +++ b/utshell-0.5.0/vendor/bitflags/tests/compile.rs @@ -0,0 +1,63 @@ +use std::{ + fs, + ffi::OsStr, + io, + path::Path, +}; + +use walkdir::WalkDir; + +#[test] +fn fail() { + prepare_stderr_files("tests/compile-fail").unwrap(); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/compile-fail/**/*.rs"); +} + +#[test] +fn pass() { + let t = trybuild::TestCases::new(); + t.pass("tests/compile-pass/**/*.rs"); +} + +// Compiler messages may change between versions +// We don't want to have to track these too closely for `bitflags`, but +// having some message to check makes sure user-facing errors are sensical. +// +// The approach we use is to run the test on all compilers, but only check stderr +// output on beta (which is the next stable release). We do this by default ignoring +// any `.stderr` files in the `compile-fail` directory, and copying `.stderr.beta` files +// when we happen to be running on a beta compiler. +fn prepare_stderr_files(path: impl AsRef) -> io::Result<()> { + for entry in WalkDir::new(path) { + let entry = entry?; + + if entry.path().extension().and_then(OsStr::to_str) == Some("beta") { + let renamed = entry.path().with_extension(""); + + // Unconditionally remove a corresponding `.stderr` file for a `.stderr.beta` + // file if it exists. On `beta` compilers, we'll recreate it. On other compilers, + // we don't want to end up checking it anyways. + if renamed.exists() { + fs::remove_file(&renamed)?; + } + + rename_beta_stderr(entry.path(), renamed)?; + } + } + + Ok(()) +} + +#[rustversion::beta] +fn rename_beta_stderr(from: impl AsRef, to: impl AsRef) -> io::Result<()> { + fs::copy(from, to)?; + + Ok(()) +} + +#[rustversion::not(beta)] +fn rename_beta_stderr(_: impl AsRef, _: impl AsRef) -> io::Result<()> { + Ok(()) +} diff --git a/utshell-0.5.0/vendor/cfg-if/.cargo-checksum.json b/utshell-0.5.0/vendor/cfg-if/.cargo-checksum.json new file mode 100644 index 00000000..93e07c19 --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5b2a8f6e5256957c029cf3a8912d51438e7faa5891c5c102c312f6d4599c1f00","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"2406e83ee174e30aa67f8ab266836fa78545012b196395aff37c152321e2c713","src/lib.rs":"54b0f108b0dc48a077c52c0bcd22b64ef4de083e5e2b7d405e50ae4d78224f1b","tests/xcrate.rs":"c0734dae6e63beafcd60bf53546115a2320735b51035c9e2387fdf9301580934"},"package":"baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/cfg-if/Cargo.toml b/utshell-0.5.0/vendor/cfg-if/Cargo.toml new file mode 100644 index 00000000..13a32ba2 --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/Cargo.toml @@ -0,0 +1,36 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "cfg-if" +version = "1.0.0" +authors = ["Alex Crichton "] +description = "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n" +homepage = "https://github.com/alexcrichton/cfg-if" +documentation = "https://docs.rs/cfg-if" +readme = "README.md" +license = "MIT/Apache-2.0" +repository = "https://github.com/alexcrichton/cfg-if" +[dependencies.compiler_builtins] +version = "0.1.2" +optional = true + +[dependencies.core] +version = "1.0.0" +optional = true +package = "rustc-std-workspace-core" + +[features] +rustc-dep-of-std = ["core", "compiler_builtins"] +[badges.travis-ci] +repository = "alexcrichton/cfg-if" diff --git a/utshell-0.5.0/vendor/cfg-if/LICENSE-APACHE b/utshell-0.5.0/vendor/cfg-if/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/cfg-if/LICENSE-MIT b/utshell-0.5.0/vendor/cfg-if/LICENSE-MIT new file mode 100644 index 00000000..39e0ed66 --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/cfg-if/README.md b/utshell-0.5.0/vendor/cfg-if/README.md new file mode 100644 index 00000000..50b5e3b2 --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/README.md @@ -0,0 +1,47 @@ +# cfg-if + +[Documentation](https://docs.rs/cfg-if) + +A macro to ergonomically define an item depending on a large number of #[cfg] +parameters. Structured like an if-else chain, the first matching branch is the +item that gets emitted. + +```toml +[dependencies] +cfg-if = "0.1" +``` + +## Example + +```rust +cfg_if::cfg_if! { + if #[cfg(unix)] { + fn foo() { /* unix specific functionality */ } + } else if #[cfg(target_pointer_width = "32")] { + fn foo() { /* non-unix, 32-bit functionality */ } + } else { + fn foo() { /* fallback implementation */ } + } +} + +fn main() { + foo(); +} +``` + +# License + +This project is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `cfg-if` by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/cfg-if/src/lib.rs b/utshell-0.5.0/vendor/cfg-if/src/lib.rs new file mode 100644 index 00000000..52bbbe0f --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/src/lib.rs @@ -0,0 +1,176 @@ +//! A macro for defining `#[cfg]` if-else statements. +//! +//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C +//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases, +//! emitting the implementation which matches first. +//! +//! This allows you to conveniently provide a long list `#[cfg]`'d blocks of code +//! without having to rewrite each clause multiple times. +//! +//! # Example +//! +//! ``` +//! cfg_if::cfg_if! { +//! if #[cfg(unix)] { +//! fn foo() { /* unix specific functionality */ } +//! } else if #[cfg(target_pointer_width = "32")] { +//! fn foo() { /* non-unix, 32-bit functionality */ } +//! } else { +//! fn foo() { /* fallback implementation */ } +//! } +//! } +//! +//! # fn main() {} +//! ``` + +#![no_std] +#![doc(html_root_url = "https://docs.rs/cfg-if")] +#![deny(missing_docs)] +#![cfg_attr(test, deny(warnings))] + +/// The main macro provided by this crate. See crate documentation for more +/// information. +#[macro_export] +macro_rules! cfg_if { + // match if/else chains with a final `else` + ($( + if #[cfg($meta:meta)] { $($tokens:tt)* } + ) else * else { + $($tokens2:tt)* + }) => { + $crate::cfg_if! { + @__items + () ; + $( ( ($meta) ($($tokens)*) ), )* + ( () ($($tokens2)*) ), + } + }; + + // match if/else chains lacking a final `else` + ( + if #[cfg($i_met:meta)] { $($i_tokens:tt)* } + $( + else if #[cfg($e_met:meta)] { $($e_tokens:tt)* } + )* + ) => { + $crate::cfg_if! { + @__items + () ; + ( ($i_met) ($($i_tokens)*) ), + $( ( ($e_met) ($($e_tokens)*) ), )* + ( () () ), + } + }; + + // Internal and recursive macro to emit all the items + // + // Collects all the negated cfgs in a list at the beginning and after the + // semicolon is all the remaining items + (@__items ($($not:meta,)*) ; ) => {}; + (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($tokens:tt)*) ), $($rest:tt)*) => { + // Emit all items within one block, applying an appropriate #[cfg]. The + // #[cfg] will require all `$m` matchers specified and must also negate + // all previous matchers. + #[cfg(all($($m,)* not(any($($not),*))))] $crate::cfg_if! { @__identity $($tokens)* } + + // Recurse to emit all other items in `$rest`, and when we do so add all + // our `$m` matchers to the list of `$not` matchers as future emissions + // will have to negate everything we just matched as well. + $crate::cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } + }; + + // Internal macro to make __apply work out right for different match types, + // because of how macros matching/expand stuff. + (@__identity $($tokens:tt)*) => { + $($tokens)* + }; +} + +#[cfg(test)] +mod tests { + cfg_if! { + if #[cfg(test)] { + use core::option::Option as Option2; + fn works1() -> Option2 { Some(1) } + } else { + fn works1() -> Option { None } + } + } + + cfg_if! { + if #[cfg(foo)] { + fn works2() -> bool { false } + } else if #[cfg(test)] { + fn works2() -> bool { true } + } else { + fn works2() -> bool { false } + } + } + + cfg_if! { + if #[cfg(foo)] { + fn works3() -> bool { false } + } else { + fn works3() -> bool { true } + } + } + + cfg_if! { + if #[cfg(test)] { + use core::option::Option as Option3; + fn works4() -> Option3 { Some(1) } + } + } + + cfg_if! { + if #[cfg(foo)] { + fn works5() -> bool { false } + } else if #[cfg(test)] { + fn works5() -> bool { true } + } + } + + #[test] + fn it_works() { + assert!(works1().is_some()); + assert!(works2()); + assert!(works3()); + assert!(works4().is_some()); + assert!(works5()); + } + + #[test] + #[allow(clippy::assertions_on_constants)] + fn test_usage_within_a_function() { + cfg_if! {if #[cfg(debug_assertions)] { + // we want to put more than one thing here to make sure that they + // all get configured properly. + assert!(cfg!(debug_assertions)); + assert_eq!(4, 2+2); + } else { + assert!(works1().is_some()); + assert_eq!(10, 5+5); + }} + } + + trait Trait { + fn blah(&self); + } + + #[allow(dead_code)] + struct Struct; + + impl Trait for Struct { + cfg_if! { + if #[cfg(feature = "blah")] { + fn blah(&self) { + unimplemented!(); + } + } else { + fn blah(&self) { + unimplemented!(); + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/cfg-if/tests/xcrate.rs b/utshell-0.5.0/vendor/cfg-if/tests/xcrate.rs new file mode 100644 index 00000000..e7b4a362 --- /dev/null +++ b/utshell-0.5.0/vendor/cfg-if/tests/xcrate.rs @@ -0,0 +1,14 @@ +cfg_if::cfg_if! { + if #[cfg(foo)] { + fn works() -> bool { false } + } else if #[cfg(test)] { + fn works() -> bool { true } + } else { + fn works() -> bool { false } + } +} + +#[test] +fn smoke() { + assert!(works()); +} diff --git a/utshell-0.5.0/vendor/chunky-vec/.cargo-checksum.json b/utshell-0.5.0/vendor/chunky-vec/.cargo-checksum.json new file mode 100644 index 00000000..8d85d17e --- /dev/null +++ b/utshell-0.5.0/vendor/chunky-vec/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"3ab88cdacffa2756abe4460dda1ef403b304e79f814a2ec71b9c9a013dce2bf6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ea4a2543160e8e33d4e2d2b40339c90e0ab2960cfa59a65264b66782d7f9e35f","README.md":"382da770bccf4ebe07dded523a9ab5e4daead902edbbbffd20740404e73ee3d5","src/lib.rs":"01dc7e2a981fc95825584916d320fd60232b07fc88761126c89b12da3e3f20e5"},"package":"bb7bdea464ae038f09197b82430b921c53619fc8d2bcaf7b151013b3ca008017"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/chunky-vec/Cargo.toml b/utshell-0.5.0/vendor/chunky-vec/Cargo.toml new file mode 100644 index 00000000..f436628b --- /dev/null +++ b/utshell-0.5.0/vendor/chunky-vec/Cargo.toml @@ -0,0 +1,24 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "chunky-vec" +version = "0.1.0" +authors = ["Dan Glastonbury "] +description = "A pin safe, append only vector never moves the backing store for an element.\n" +keywords = ["data-structure", "vector", "pin"] +categories = ["data-structures"] +license = "Apache-2.0/MIT" +repository = "https://github.com/djg/chunky-vec" + +[dependencies] diff --git a/utshell-0.5.0/vendor/chunky-vec/LICENSE-APACHE b/utshell-0.5.0/vendor/chunky-vec/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/chunky-vec/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/chunky-vec/LICENSE-MIT b/utshell-0.5.0/vendor/chunky-vec/LICENSE-MIT new file mode 100644 index 00000000..f79cf5d3 --- /dev/null +++ b/utshell-0.5.0/vendor/chunky-vec/LICENSE-MIT @@ -0,0 +1,27 @@ +MIT License + +Copyright (c) 2020 Daniel Glastonbury + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/chunky-vec/README.md b/utshell-0.5.0/vendor/chunky-vec/README.md new file mode 100644 index 00000000..e57317c0 --- /dev/null +++ b/utshell-0.5.0/vendor/chunky-vec/README.md @@ -0,0 +1,6 @@ +# Chunky Vec + +[![License: MIT/Apache-2.0](https://img.shields.io/crates/l/chunky-vec.svg)](#license) + +This crate provides a pin-safe, append-only vector which guarantees never +to move the storage for an element once it has been allocated. diff --git a/utshell-0.5.0/vendor/chunky-vec/src/lib.rs b/utshell-0.5.0/vendor/chunky-vec/src/lib.rs new file mode 100644 index 00000000..dc815525 --- /dev/null +++ b/utshell-0.5.0/vendor/chunky-vec/src/lib.rs @@ -0,0 +1,343 @@ +//! This crate provides a pin-safe, append-only vector which guarantees never +//! to move the storage for an element once it has been allocated. + +use std::{ + ops::{Index, IndexMut}, + slice, +}; + +struct Chunk { + /// The elements of this chunk. + elements: Vec, +} + +impl Chunk { + fn with_capacity(capacity: usize) -> Self { + let elements = Vec::with_capacity(capacity); + assert_eq!(elements.capacity(), capacity); + Self { elements } + } + + fn len(&self) -> usize { + self.elements.len() + } + + /// Returns the number of available empty elements. + fn available(&self) -> usize { + self.elements.capacity() - self.elements.len() + } + + /// Returns a shared reference to the element at the given index. + /// + /// # Panics + /// + /// Panics if the index is out of bounds. + pub fn get(&self, index: usize) -> Option<&T> { + self.elements.get(index) + } + + /// Returns an exclusive reference to the element at the given index. + /// + /// # Panics + /// + /// Panics if the index is out of bounds. + pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + self.elements.get_mut(index) + } + + /// Pushes a new value into the fixed capacity entry. + /// + /// # Panics + /// + /// If the entry is already at its capacity. + /// Note that this panic should never happen since the entry is only ever + /// accessed by its outer chunk vector that checks before pushing. + pub fn push(&mut self, new_value: T) { + if self.available() == 0 { + panic!("No available elements.") + } + self.elements.push(new_value); + } + + pub fn push_get(&mut self, new_value: T) -> &mut T { + self.push(new_value); + unsafe { + let last = self.elements.len() - 1; + self.elements.get_unchecked_mut(last) + } + } + + /// Returns an iterator over the elements of the chunk. + pub fn iter(&self) -> slice::Iter { + self.elements.iter() + } + + /// Returns an iterator over the elements of the chunk. + pub fn iter_mut(&mut self) -> slice::IterMut { + self.elements.iter_mut() + } +} + +impl Index for Chunk { + type Output = T; + + fn index(&self, index: usize) -> &Self::Output { + self.get(index).expect("index out of bounds") + } +} + +impl IndexMut for Chunk { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + self.get_mut(index).expect("index out of bounds") + } +} + +/// Pin safe vector +/// +/// An append only vector that never moves the backing store for each element. +pub struct ChunkyVec { + /// The chunks holding elements + chunks: Vec>, +} + +impl Default for ChunkyVec { + fn default() -> Self { + Self { + chunks: Vec::default(), + } + } +} + +impl Unpin for ChunkyVec {} + +impl ChunkyVec { + const DEFAULT_CAPACITY: usize = 32; + + pub fn len(&self) -> usize { + if self.chunks.is_empty() { + 0 + } else { + // # Safety - There is at least one chunk here. + (self.chunks.len() - 1) * Self::DEFAULT_CAPACITY + self.chunks.last().unwrap().len() + } + } + + pub fn is_empty(&self) -> bool { + // # Safety - Since it's impossible to pop, at least one chunk means we're not empty. + self.chunks.is_empty() + } + + /// Returns an iterator that yields shared references to the elements of the bucket vector. + pub fn iter(&self) -> Iter { + Iter::new(self) + } + + /// Returns an iterator that yields exclusive reference to the elements of the bucket vector. + pub fn iter_mut(&mut self) -> IterMut { + IterMut::new(self) + } + + /// Returns a shared reference to the element at the given index if any. + pub fn get(&self, index: usize) -> Option<&T> { + let (x, y) = ( + index / Self::DEFAULT_CAPACITY, + index % Self::DEFAULT_CAPACITY, + ); + self.chunks.get(x).and_then(|chunk| chunk.get(y)) + } + + /// Returns an exclusive reference to the element at the given index if any. + pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + let (x, y) = ( + index / Self::DEFAULT_CAPACITY, + index % Self::DEFAULT_CAPACITY, + ); + self.chunks.get_mut(x).and_then(|chunk| chunk.get_mut(y)) + } + + /// Pushes a new element onto the bucket vector. + /// + /// # Note + /// + /// This operation will never move other elements, reallocates or otherwise + /// invalidate pointers of elements contained by the bucket vector. + pub fn push(&mut self, new_value: T) { + self.push_get(new_value); + } + + pub fn push_get(&mut self, new_value: T) -> &mut T { + if self.chunks.last().map(Chunk::available).unwrap_or_default() == 0 { + self.chunks.push(Chunk::with_capacity(Self::DEFAULT_CAPACITY)); + } + // Safety: Guaranteed to have a chunk with available elements + unsafe { + let last = self.chunks.len() - 1; + self.chunks.get_unchecked_mut(last).push_get(new_value) + } + } +} + +impl Index for ChunkyVec { + type Output = T; + + fn index(&self, index: usize) -> &Self::Output { + self.get(index).expect("index out of bounds") + } +} + +impl IndexMut for ChunkyVec { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + self.get_mut(index).expect("index out of bounds") + } +} + +/// An iterator yielding shared references to the elements of a ChunkyVec. +#[derive(Clone)] +pub struct Iter<'a, T> { + /// Chunks iterator. + chunks: slice::Iter<'a, Chunk>, + /// Forward iterator for `next`. + iter: Option>, + /// Number of elements that are to be yielded by the iterator. + len: usize, +} + +impl<'a, T> Iter<'a, T> { + /// Creates a new iterator over the ChunkyVec + pub(crate) fn new(vec: &'a ChunkyVec) -> Self { + let len = vec.len(); + Self { + chunks: vec.chunks.iter(), + iter: None, + len, + } + } +} + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + loop { + if let Some(ref mut iter) = self.iter { + if let front @ Some(_) = iter.next() { + self.len -= 1; + return front; + } + } + self.iter = Some(self.chunks.next()?.iter()); + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +impl<'a, T> ExactSizeIterator for Iter<'a, T> { + fn len(&self) -> usize { + self.len + } +} + +/// An iterator yielding exclusive references to the elements of a ChunkVec. +pub struct IterMut<'a, T> { + /// Chunks iterator. + chunks: slice::IterMut<'a, Chunk>, + /// Forward iterator for `next`. + iter: Option>, + /// Number of elements that are to be yielded by the iterator. + len: usize, +} + +impl<'a, T> IterMut<'a, T> { + /// Creates a new iterator over the bucket vector. + pub(crate) fn new(vec: &'a mut ChunkyVec) -> Self { + let len = vec.len(); + Self { + chunks: vec.chunks.iter_mut(), + iter: None, + len, + } + } +} + +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + loop { + if let Some(ref mut iter) = self.iter { + if let front @ Some(_) = iter.next() { + self.len -= 1; + return front; + } + } + self.iter = Some(self.chunks.next()?.iter_mut()); + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len(), Some(self.len())) + } +} + +impl<'a, T> ExactSizeIterator for IterMut<'a, T> { + fn len(&self) -> usize { + self.len + } +} +impl<'a, T> IntoIterator for &'a ChunkyVec { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl<'a, T> IntoIterator for &'a mut ChunkyVec { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn iterate_empty() { + let v = ChunkyVec::::default(); + for i in &v { + println!("{:?}", i); + } + } + + #[test] + fn iterate_multiple_chunks() { + let mut v = ChunkyVec::::default(); + for i in 0..33 { + v.push(i); + } + let mut iter = v.iter(); + for _ in 0..32 { + iter.next(); + } + assert_eq!(iter.next(), Some(&32)); + assert_eq!(iter.next(), None); + } + + #[test] + fn index_multiple_chunks() { + let mut v = ChunkyVec::::default(); + for i in 0..33 { + v.push(i); + } + assert_eq!(v.get(32), Some(&32)); + assert_eq!(v[32], 32); + } +} diff --git a/utshell-0.5.0/vendor/displaydoc/.cargo-checksum.json b/utshell-0.5.0/vendor/displaydoc/.cargo-checksum.json new file mode 100644 index 00000000..a1f0964f --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"ac4b11a820a3251453aa5eed99f2e34758281c4794234376532ab1686fc4092e","Cargo.lock":"764c7f380095ccd0c22e10470ed71a1c38899a502943f70baf1b0641f30d61a9","Cargo.toml":"6eac127183532630ea388e11f07a33c1a8537175d4f1269290eacd0b5010b41d","LICENSE-APACHE":"7cfd738c53d61c79f07e348f622bf7707c9084237054d37fbe07788a75f5881c","LICENSE-MIT":"36516aefdc84c5d5a1e7485425913a22dbda69eb1930c5e84d6ae4972b5194b9","README.md":"60628c334f71eba035e7ba4d5ba4df966c9de953260f9d1f28b0141ad06a07a8","README.tpl":"a8b023f5f39b795ef553c2b75551d6ad42db6597362c8909101f4bc8c8994bcc","examples/simple.rs":"dd37ed49175e86124cf58aba6fdcf4b4c2adc13a2414d4a2ba31cfab21638415","src/attr.rs":"1aeaf46ea739f63bf7eca5a575ca4345ff325c16e959fb59b5671b9a338d5ddc","src/expand.rs":"a0e6c062e00b9e68a0811a7d4d739e7572cd4a5dd962dc3519c0c8bfa1e84d8b","src/fmt.rs":"9734d3b51206f73ca8d9a513bee46d72215ff877797500887d43bc64af639c37","src/lib.rs":"de304b1de4a60700c0a031c6bd568da7ed24f5169edcfc16b7009e9e9494daed","tests/compile_tests.rs":"6cd211e343c42873a287b02581bd342b09ae508022fc82022714ebdc625935aa","tests/happy.rs":"ebd93ca6cea7c2ab77c59f990335ca34714e19365fddd40a6eca5f180bf7cb75","tests/no_std/enum_prefix.rs":"fd2a565ceddffe0433f83c6d0c9b15bc1db96fbf952f222ff04bc0dc1ea34d41","tests/no_std/enum_prefix_missing.rs":"4ed8aaef3d9274b377837b90fb9a80315df502b1c569de3213b7a2e7fa613322","tests/no_std/enum_prefix_missing.stderr":"add42a5efa90502483b2fcd0152289b62c1d5b790faf9e46d8d930e4e474b781","tests/no_std/multi_line.rs":"6ce3c1554f8bffa409f42a12517f2ef79e884ce22c79d2514455263a9254ae10","tests/no_std/multi_line.stderr":"ee076d8d02e187fe9651429a755599752b82be5910aa19e9312cf678779b2c03","tests/no_std/multi_line_allow.rs":"ef1f5a6b551e81ec6405626c939d81fe6db279bd5c2c66a2c5cc6e30a318cdbe","tests/no_std/with.rs":"3607edede6069527e792e000bfe0062f539ec342048aa2b2322556f6d6462bcc","tests/no_std/without.rs":"518cd04d73bd950e70f2d515d2cdae48b0f409fbefa2132b4d9a1b97e9c0a406","tests/no_std/without.stderr":"b3ade743ec5597f433cfb6ac378db239207d349bc99b21d9f75399a8df6ec4ae","tests/num_in_field.rs":"cd83f7d79ae065a97dcb53b2e92dc57e2f269e12433d1cd4644cb0ec6b2a4d0f","tests/std/enum_prefix.rs":"fd2a565ceddffe0433f83c6d0c9b15bc1db96fbf952f222ff04bc0dc1ea34d41","tests/std/enum_prefix_missing.rs":"4ed8aaef3d9274b377837b90fb9a80315df502b1c569de3213b7a2e7fa613322","tests/std/enum_prefix_missing.stderr":"ac4b4ac371b6e134bc1781854e3bc4df2afecdb29182a9c8328ee1d37c0fef3d","tests/std/multi_line.rs":"86726db8140e5bf9f690ac3f2d607a7a9d74b9b79fae7945480cff62cf3e8700","tests/std/multi_line.stderr":"ed9de88820f5a0cacdf26f955790b1c433c784a432cf723a963211011e1ccd7b","tests/std/multi_line_allow.rs":"ef1f5a6b551e81ec6405626c939d81fe6db279bd5c2c66a2c5cc6e30a318cdbe","tests/std/multiple.rs":"a4194da6b5bef919bb0107ddb91c548421ef9812d69894bef5e5b6f316af8eee","tests/std/without.rs":"80a59e296ee3c205960b9e8dd18c1d2b210d8fd096e89652d482b963010f340b","tests/std/without.stderr":"fc699e263f1148b1db7f5ea63f0d952c74f997c8155578ff4efaf1cd9f8db8d4","tests/variantless.rs":"84495a36014bdc090b8e5d97442bcfd3229d07f0d40579e450e71596ef9a7b50","update-readme.sh":"794668cc4eb58da01049effb0370db4799e7a70a9db777edfba83d92c33e821a"},"package":"487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/displaydoc/CHANGELOG.md b/utshell-0.5.0/vendor/displaydoc/CHANGELOG.md new file mode 100644 index 00000000..4513b4ad --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/CHANGELOG.md @@ -0,0 +1,50 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## [Unreleased] - ReleaseDate + +# [0.2.4] - 2022-05-02 + +## Added +- Updated `syn` dependency to 2.0 +- Support for empty enums +- Implicitly require fmt::Display on all type parameters unless overridden + +## Changed +- Bumped MSRV to 1.56 + +# [0.2.3] - 2021-07-16 +## Added +- Added `#[displaydoc("..")]` attribute for overriding a doc comment + +# [0.2.2] - 2021-07-01 +## Added +- Added prefix feature to use the doc comment from an enum and prepend it + before the error message from each variant. + +# [0.2.1] - 2021-03-26 +## Added +- Added opt in support for ignoring extra doc attributes + +# [0.2.0] - 2021-03-16 +## Changed + +- (BREAKING) disallow multiple `doc` attributes in display impl + [https://github.com/yaahc/displaydoc/pull/22]. Allowing and ignoring extra + doc attributes made it too easy to accidentally create a broken display + implementation with missing context without realizing it, this change turns + that into a hard error and directs users towards block comments if multiple + lines are needed. + + +[Unreleased]: https://github.com/yaahc/displaydoc/compare/v0.2.4...HEAD +[0.2.4]: https://github.com/yaahc/displaydoc/compare/v0.2.3...v0.2.4 +[0.2.3]: https://github.com/yaahc/displaydoc/compare/v0.2.2...v0.2.3 +[0.2.2]: https://github.com/yaahc/displaydoc/compare/v0.2.1...v0.2.2 +[0.2.1]: https://github.com/yaahc/displaydoc/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/yaahc/displaydoc/releases/tag/v0.2.0 diff --git a/utshell-0.5.0/vendor/displaydoc/Cargo.lock b/utshell-0.5.0/vendor/displaydoc/Cargo.lock new file mode 100644 index 00000000..30580d94 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/Cargo.lock @@ -0,0 +1,264 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "basic-toml" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +dependencies = [ + "serde", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + +[[package]] +name = "displaydoc" +version = "0.2.4" +dependencies = [ + "libc", + "pretty_assertions", + "proc-macro2", + "quote", + "rustversion", + "static_assertions", + "syn 2.0.15", + "thiserror", + "trybuild", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "libc" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "output_vt100" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" +dependencies = [ + "winapi", +] + +[[package]] +name = "pretty_assertions" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" +dependencies = [ + "ansi_term", + "ctor", + "difference", + "output_vt100", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "serde" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" + +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "trybuild" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +dependencies = [ + "basic-toml", + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/utshell-0.5.0/vendor/displaydoc/Cargo.toml b/utshell-0.5.0/vendor/displaydoc/Cargo.toml new file mode 100644 index 00000000..1affcca6 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/Cargo.toml @@ -0,0 +1,114 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "displaydoc" +version = "0.2.4" +authors = ["Jane Lusby "] +description = """ +A derive macro for implementing the display Trait via a doc comment and string interpolation +""" +homepage = "https://github.com/yaahc/displaydoc" +documentation = "https://docs.rs/displaydoc" +readme = "README.md" +keywords = [ + "display", + "derive", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/yaahc/displaydoc" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[package.metadata.release] +no-dev-version = true +pre-release-hook = ["./update-readme.sh"] + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "Unreleased" +replace = "{{version}}" + +[[package.metadata.release.pre-release-replacements]] +file = "src/lib.rs" +search = '#!\[doc\(html_root_url.*' +replace = "#![doc(html_root_url = \"https://docs.rs/{{crate_name}}/{{version}}\")]" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "ReleaseDate" +replace = "{{date}}" + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "" +replace = """ + + +# [Unreleased] - ReleaseDate""" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = '\.\.\.HEAD' +replace = "...{{tag_name}}" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "" +replace = """ + +[Unreleased]: https://github.com/yaahc/{{crate_name}}/compare/{{tag_name}}...HEAD""" +exactly = 1 + +[lib] +path = "src/lib.rs" +proc-macro = true + +[dependencies.proc-macro2] +version = "1.0" + +[dependencies.quote] +version = "1.0" + +[dependencies.syn] +version = "2.0" + +[dev-dependencies.libc] +version = "0.2" +default-features = false + +[dev-dependencies.pretty_assertions] +version = "0.6.1" + +[dev-dependencies.rustversion] +version = "1.0.0" + +[dev-dependencies.static_assertions] +version = "1.1" + +[dev-dependencies.thiserror] +version = "1.0.24" + +[dev-dependencies.trybuild] +version = "1.0" + +[features] +default = ["std"] +std = [] diff --git a/utshell-0.5.0/vendor/displaydoc/LICENSE-APACHE b/utshell-0.5.0/vendor/displaydoc/LICENSE-APACHE new file mode 100644 index 00000000..f47c9411 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/displaydoc/LICENSE-MIT b/utshell-0.5.0/vendor/displaydoc/LICENSE-MIT new file mode 100644 index 00000000..458723b3 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/displaydoc/README.md b/utshell-0.5.0/vendor/displaydoc/README.md new file mode 100644 index 00000000..b8fa0915 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/README.md @@ -0,0 +1,115 @@ +derive(Display) /// `From` +=============== + +[![Latest Version](https://img.shields.io/crates/v/displaydoc.svg)](https://crates.io/crates/displaydoc) +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/displaydoc) + +This library provides a convenient derive macro for the standard library's +[`core::fmt::Display`] trait. + +[`core::fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html + +```toml +[dependencies] +displaydoc = "0.2" +``` + +*Compiler support: requires rustc 1.56+* + +
+ +### Example + +*Demonstration alongside the [`Error`][std::error::Error] derive macro from [`thiserror`](https://docs.rs/thiserror/1.0.25/thiserror/index.html), +to propagate source locations from [`io::Error`][std::io::Error] with the `#[source]` attribute:* +```rust +use std::io; +use displaydoc::Display; +use thiserror::Error; + +#[derive(Display, Error, Debug)] +pub enum DataStoreError { + /// data store disconnected + Disconnect(#[source] io::Error), + /// the data for key `{0}` is not available + Redaction(String), + /// invalid header (expected {expected:?}, found {found:?}) + InvalidHeader { + expected: String, + found: String, + }, + /// unknown data store error + Unknown, +} + +let error = DataStoreError::Redaction("CLASSIFIED CONTENT".to_string()); +assert!("the data for key `CLASSIFIED CONTENT` is not available" == &format!("{}", error)); +``` +*Note that although [`io::Error`][std::io::Error] implements `Display`, we do not add it to the +generated message for `DataStoreError::Disconnect`, since it is already made available via +`#[source]`. See further context on avoiding duplication in error reports at the rust blog +[here](https://github.com/yaahc/blog.rust-lang.org/blob/master/posts/inside-rust/2021-05-15-What-the-error-handling-project-group-is-working-towards.md#duplicate-information-issue).* + +
+ +### Details + +- A `fmt::Display` impl is generated for your enum if you provide + a docstring comment on each variant as shown above in the example. The + `Display` derive macro supports a shorthand for interpolating fields from + the error: + - `/// {var}` ⟶ `write!("{}", self.var)` + - `/// {0}` ⟶ `write!("{}", self.0)` + - `/// {var:?}` ⟶ `write!("{:?}", self.var)` + - `/// {0:?}` ⟶ `write!("{:?}", self.0)` +- This also works with structs and [generic types][crate::Display#generic-type-parameters]: +```rust +/// oh no, an error: {0} +#[derive(Display)] +pub struct Error(pub E); + +let error: Error<&str> = Error("muahaha i am an error"); +assert!("oh no, an error: muahaha i am an error" == &format!("{}", error)); +``` + +- Two optional attributes can be added to your types next to the derive: + + - `#[ignore_extra_doc_attributes]` makes the macro ignore any doc + comment attributes (or `///` lines) after the first. Multi-line + comments using `///` are otherwise treated as an error, so use this + attribute or consider switching to block doc comments (`/** */`). + + - `#[prefix_enum_doc_attributes]` combines the doc comment message on + your enum itself with the messages for each variant, in the format + “enum: variantâ€. When added to an enum, the doc comment on the enum + becomes mandatory. When added to any other type, it has no effect. + +- In case you want to have an independent doc comment, the + `#[displaydoc("...")` atrribute may be used on the variant or struct to + override it. + +
+ +### FAQ + +1. **Is this crate `no_std` compatible?** + * Yes! This crate implements the [`core::fmt::Display`] trait, not the [`std::fmt::Display`] trait, so it should work in `std` and `no_std` environments. Just add `default-features = false`. + +2. **Does this crate work with `Path` and `PathBuf` via the `Display` trait?** + * Yuuup. This crate uses @dtolnay's [autoref specialization technique](https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md) to add a special trait for types to get the display impl. It then specializes for `Path` and `PathBuf`, and when either of these types are found, it calls `self.display()` to get a `std::path::Display<'_>` type which can be used with the `Display` format specifier! + + +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/utshell-0.5.0/vendor/displaydoc/README.tpl b/utshell-0.5.0/vendor/displaydoc/README.tpl new file mode 100644 index 00000000..b131fb8a --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/README.tpl @@ -0,0 +1,23 @@ +derive(Display) /// `From` +=============== + +[![Latest Version](https://img.shields.io/crates/v/displaydoc.svg)](https://crates.io/crates/displaydoc) +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/displaydoc) + +{{readme}} + + +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/utshell-0.5.0/vendor/displaydoc/examples/simple.rs b/utshell-0.5.0/vendor/displaydoc/examples/simple.rs new file mode 100644 index 00000000..1f9fd119 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/examples/simple.rs @@ -0,0 +1,36 @@ +use displaydoc::Display; + +#[derive(Debug, Display)] +pub enum DataStoreError { + /// data store disconnected + Disconnect, + /// the data for key `{0}` is not available + Redaction(String), + /// invalid header (expected {expected:?}, found {found:?}) + InvalidHeader { expected: String, found: String }, + /// unknown data store error + Unknown, +} + +fn main() { + let disconnect = DataStoreError::Disconnect; + println!( + "Enum value `Disconnect` should be printed as:\n\t{}", + disconnect + ); + + let redaction = DataStoreError::Redaction(String::from("Dummy")); + println!( + "Enum value `Redaction` should be printed as:\n\t{}", + redaction + ); + + let invalid_header = DataStoreError::InvalidHeader { + expected: String::from("https"), + found: String::from("http"), + }; + println!( + "Enum value `InvalidHeader` should be printed as:\n\t{}", + invalid_header + ); +} diff --git a/utshell-0.5.0/vendor/displaydoc/src/attr.rs b/utshell-0.5.0/vendor/displaydoc/src/attr.rs new file mode 100644 index 00000000..a965d04d --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/src/attr.rs @@ -0,0 +1,137 @@ +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; +use syn::{Attribute, LitStr, Meta, Result}; + +#[derive(Clone)] +pub(crate) struct Display { + pub(crate) fmt: LitStr, + pub(crate) args: TokenStream, +} + +pub(crate) struct VariantDisplay { + pub(crate) r#enum: Option, + pub(crate) variant: Display, +} + +impl ToTokens for Display { + fn to_tokens(&self, tokens: &mut TokenStream) { + let fmt = &self.fmt; + let args = &self.args; + tokens.extend(quote! { + write!(formatter, #fmt #args) + }); + } +} + +impl ToTokens for VariantDisplay { + fn to_tokens(&self, tokens: &mut TokenStream) { + if let Some(ref r#enum) = self.r#enum { + r#enum.to_tokens(tokens); + tokens.extend(quote! { ?; write!(formatter, ": ")?; }); + } + self.variant.to_tokens(tokens); + } +} + +pub(crate) struct AttrsHelper { + ignore_extra_doc_attributes: bool, + prefix_enum_doc_attributes: bool, +} + +impl AttrsHelper { + pub(crate) fn new(attrs: &[Attribute]) -> Self { + let ignore_extra_doc_attributes = attrs + .iter() + .any(|attr| attr.path().is_ident("ignore_extra_doc_attributes")); + let prefix_enum_doc_attributes = attrs + .iter() + .any(|attr| attr.path().is_ident("prefix_enum_doc_attributes")); + + Self { + ignore_extra_doc_attributes, + prefix_enum_doc_attributes, + } + } + + pub(crate) fn display(&self, attrs: &[Attribute]) -> Result> { + let displaydoc_attr = attrs.iter().find(|attr| attr.path().is_ident("displaydoc")); + + if let Some(displaydoc_attr) = displaydoc_attr { + let lit = displaydoc_attr + .parse_args() + .expect("#[displaydoc(\"foo\")] must contain string arguments"); + let mut display = Display { + fmt: lit, + args: TokenStream::new(), + }; + + display.expand_shorthand(); + return Ok(Some(display)); + } + + let num_doc_attrs = attrs + .iter() + .filter(|attr| attr.path().is_ident("doc")) + .count(); + + if !self.ignore_extra_doc_attributes && num_doc_attrs > 1 { + panic!("Multi-line comments are disabled by default by displaydoc. Please consider using block doc comments (/** */) or adding the #[ignore_extra_doc_attributes] attribute to your type next to the derive."); + } + + for attr in attrs { + if attr.path().is_ident("doc") { + let lit = match &attr.meta { + Meta::NameValue(syn::MetaNameValue { + value: + syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }), + .. + }) => lit, + _ => unimplemented!(), + }; + + // Make an attempt at cleaning up multiline doc comments. + let doc_str = lit + .value() + .lines() + .map(|line| line.trim().trim_start_matches('*').trim()) + .collect::>() + .join("\n"); + + let lit = LitStr::new(doc_str.trim(), lit.span()); + + let mut display = Display { + fmt: lit, + args: TokenStream::new(), + }; + + display.expand_shorthand(); + return Ok(Some(display)); + } + } + + Ok(None) + } + + pub(crate) fn display_with_input( + &self, + r#enum: &[Attribute], + variant: &[Attribute], + ) -> Result> { + let r#enum = if self.prefix_enum_doc_attributes { + let result = self + .display(r#enum)? + .expect("Missing doc comment on enum with #[prefix_enum_doc_attributes]. Please remove the attribute or add a doc comment to the enum itself."); + + Some(result) + } else { + None + }; + + Ok(self + .display(variant)? + .map(|variant| VariantDisplay { r#enum, variant })) + } +} diff --git a/utshell-0.5.0/vendor/displaydoc/src/expand.rs b/utshell-0.5.0/vendor/displaydoc/src/expand.rs new file mode 100644 index 00000000..8a84390b --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/src/expand.rs @@ -0,0 +1,410 @@ +use super::attr::AttrsHelper; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{ + punctuated::Punctuated, + token::{Colon, Comma, PathSep, Plus, Where}, + Data, DataEnum, DataStruct, DeriveInput, Error, Fields, Generics, Ident, Path, PathArguments, + PathSegment, PredicateType, Result, TraitBound, TraitBoundModifier, Type, TypeParam, + TypeParamBound, TypePath, WhereClause, WherePredicate, +}; + +use std::collections::HashMap; + +pub(crate) fn derive(input: &DeriveInput) -> Result { + let impls = match &input.data { + Data::Struct(data) => impl_struct(input, data), + Data::Enum(data) => impl_enum(input, data), + Data::Union(_) => Err(Error::new_spanned(input, "Unions are not supported")), + }?; + + let helpers = specialization(); + let dummy_const = format_ident!("_DERIVE_Display_FOR_{}", input.ident); + Ok(quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + #helpers + #impls + }; + }) +} + +#[cfg(feature = "std")] +fn specialization() -> TokenStream { + quote! { + trait DisplayToDisplayDoc { + fn __displaydoc_display(&self) -> Self; + } + + impl DisplayToDisplayDoc for &T { + fn __displaydoc_display(&self) -> Self { + self + } + } + + // If the `std` feature gets enabled we want to ensure that any crate + // using displaydoc can still reference the std crate, which is already + // being compiled in by whoever enabled the `std` feature in + // `displaydoc`, even if the crates using displaydoc are no_std. + extern crate std; + + trait PathToDisplayDoc { + fn __displaydoc_display(&self) -> std::path::Display<'_>; + } + + impl PathToDisplayDoc for std::path::Path { + fn __displaydoc_display(&self) -> std::path::Display<'_> { + self.display() + } + } + + impl PathToDisplayDoc for std::path::PathBuf { + fn __displaydoc_display(&self) -> std::path::Display<'_> { + self.display() + } + } + } +} + +#[cfg(not(feature = "std"))] +fn specialization() -> TokenStream { + quote! {} +} + +fn impl_struct(input: &DeriveInput, data: &DataStruct) -> Result { + let ty = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let where_clause = generate_where_clause(&input.generics, where_clause); + + let helper = AttrsHelper::new(&input.attrs); + + let display = helper.display(&input.attrs)?.map(|display| { + let pat = match &data.fields { + Fields::Named(fields) => { + let var = fields.named.iter().map(|field| &field.ident); + quote!(Self { #(#var),* }) + } + Fields::Unnamed(fields) => { + let var = (0..fields.unnamed.len()).map(|i| format_ident!("_{}", i)); + quote!(Self(#(#var),*)) + } + Fields::Unit => quote!(_), + }; + quote! { + impl #impl_generics core::fmt::Display for #ty #ty_generics #where_clause { + fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + // NB: This destructures the fields of `self` into named variables (for unnamed + // fields, it uses _0, _1, etc as above). The `#[allow(unused_variables)]` + // section means it doesn't have to parse the individual field references out of + // the docstring. + #[allow(unused_variables)] + let #pat = self; + #display + } + } + } + }); + + Ok(quote! { #display }) +} + +/// Create a `where` predicate for `ident`, without any [bound][TypeParamBound]s yet. +fn new_empty_where_type_predicate(ident: Ident) -> PredicateType { + let mut path_segments = Punctuated::::new(); + path_segments.push_value(PathSegment { + ident, + arguments: PathArguments::None, + }); + PredicateType { + lifetimes: None, + bounded_ty: Type::Path(TypePath { + qself: None, + path: Path { + leading_colon: None, + segments: path_segments, + }, + }), + colon_token: Colon { + spans: [Span::call_site()], + }, + bounds: Punctuated::::new(), + } +} + +/// Create a `where` clause that we can add [WherePredicate]s to. +fn new_empty_where_clause() -> WhereClause { + WhereClause { + where_token: Where { + span: Span::call_site(), + }, + predicates: Punctuated::::new(), + } +} + +enum UseGlobalPrefix { + LeadingColon, + #[allow(dead_code)] + NoLeadingColon, +} + +/// Create a path with segments composed of [Idents] *without* any [PathArguments]. +fn join_paths(name_segments: &[&str], use_global_prefix: UseGlobalPrefix) -> Path { + let mut segments = Punctuated::::new(); + assert!(!name_segments.is_empty()); + segments.push_value(PathSegment { + ident: Ident::new(name_segments[0], Span::call_site()), + arguments: PathArguments::None, + }); + for name in name_segments[1..].iter() { + segments.push_punct(PathSep { + spans: [Span::call_site(), Span::mixed_site()], + }); + segments.push_value(PathSegment { + ident: Ident::new(name, Span::call_site()), + arguments: PathArguments::None, + }); + } + Path { + leading_colon: match use_global_prefix { + UseGlobalPrefix::LeadingColon => Some(PathSep { + spans: [Span::call_site(), Span::mixed_site()], + }), + UseGlobalPrefix::NoLeadingColon => None, + }, + segments, + } +} + +/// Push `new_type_predicate` onto the end of `where_clause`. +fn append_where_clause_type_predicate( + where_clause: &mut WhereClause, + new_type_predicate: PredicateType, +) { + // Push a comma at the end if there are already any `where` predicates. + if !where_clause.predicates.is_empty() { + where_clause.predicates.push_punct(Comma { + spans: [Span::call_site()], + }); + } + where_clause + .predicates + .push_value(WherePredicate::Type(new_type_predicate)); +} + +/// Add a requirement for [core::fmt::Display] to a `where` predicate for some type. +fn add_display_constraint_to_type_predicate( + predicate_that_needs_a_display_impl: &mut PredicateType, +) { + // Create a `Path` of `::core::fmt::Display`. + let display_path = join_paths(&["core", "fmt", "Display"], UseGlobalPrefix::LeadingColon); + + let display_bound = TypeParamBound::Trait(TraitBound { + paren_token: None, + modifier: TraitBoundModifier::None, + lifetimes: None, + path: display_path, + }); + if !predicate_that_needs_a_display_impl.bounds.is_empty() { + predicate_that_needs_a_display_impl.bounds.push_punct(Plus { + spans: [Span::call_site()], + }); + } + + predicate_that_needs_a_display_impl + .bounds + .push_value(display_bound); +} + +/// Map each declared generic type parameter to the set of all trait boundaries declared on it. +/// +/// These boundaries may come from the declaration site: +/// pub enum E { ... } +/// or a `where` clause after the parameter declarations: +/// pub enum E where T: MyTrait { ... } +/// This method will return the boundaries from both of those cases. +fn extract_trait_constraints_from_source( + where_clause: &WhereClause, + type_params: &[&TypeParam], +) -> HashMap> { + // Add trait bounds provided at the declaration site of type parameters for the struct/enum. + let mut param_constraint_mapping: HashMap> = type_params + .iter() + .map(|type_param| { + let trait_bounds: Vec = type_param + .bounds + .iter() + .flat_map(|bound| match bound { + TypeParamBound::Trait(trait_bound) => Some(trait_bound), + _ => None, + }) + .cloned() + .collect(); + (type_param.ident.clone(), trait_bounds) + }) + .collect(); + + // Add trait bounds from `where` clauses, which may be type parameters or types containing + // those parameters. + for predicate in where_clause.predicates.iter() { + // We only care about type and not lifetime constraints here. + if let WherePredicate::Type(ref pred_ty) = predicate { + let ident = match &pred_ty.bounded_ty { + Type::Path(TypePath { path, qself: None }) => match path.get_ident() { + None => continue, + Some(ident) => ident, + }, + _ => continue, + }; + // We ignore any type constraints that aren't direct references to type + // parameters of the current enum of struct definition. No types can be + // constrained in a `where` clause unless they are a type parameter or a generic + // type instantiated with one of the type parameters, so by only allowing single + // identifiers, we can be sure that the constrained type is a type parameter + // that is contained in `param_constraint_mapping`. + if let Some((_, ref mut known_bounds)) = param_constraint_mapping + .iter_mut() + .find(|(id, _)| *id == ident) + { + for bound in pred_ty.bounds.iter() { + // We only care about trait bounds here. + if let TypeParamBound::Trait(ref bound) = bound { + known_bounds.push(bound.clone()); + } + } + } + } + } + + param_constraint_mapping +} + +/// Hygienically add `where _: Display` to the set of [TypeParamBound]s for `ident`, creating such +/// a set if necessary. +fn ensure_display_in_where_clause_for_type(where_clause: &mut WhereClause, ident: Ident) { + for pred_ty in where_clause + .predicates + .iter_mut() + // Find the `where` predicate constraining the current type param, if it exists. + .flat_map(|predicate| match predicate { + WherePredicate::Type(pred_ty) => Some(pred_ty), + // We're looking through type constraints, not lifetime constraints. + _ => None, + }) + { + // Do a complicated destructuring in order to check if the type being constrained in this + // `where` clause is the type we're looking for, so we can use the mutable reference to + // `pred_ty` if so. + let matches_desired_type = matches!( + &pred_ty.bounded_ty, + Type::Path(TypePath { path, .. }) if Some(&ident) == path.get_ident()); + if matches_desired_type { + add_display_constraint_to_type_predicate(pred_ty); + return; + } + } + + // If there is no `where` predicate for the current type param, we will construct one. + let mut new_type_predicate = new_empty_where_type_predicate(ident); + add_display_constraint_to_type_predicate(&mut new_type_predicate); + append_where_clause_type_predicate(where_clause, new_type_predicate); +} + +/// For all declared type parameters, add a [core::fmt::Display] constraint, unless the type +/// parameter already has any type constraint. +fn ensure_where_clause_has_display_for_all_unconstrained_members( + where_clause: &mut WhereClause, + type_params: &[&TypeParam], +) { + let param_constraint_mapping = extract_trait_constraints_from_source(where_clause, type_params); + + for (ident, known_bounds) in param_constraint_mapping.into_iter() { + // If the type parameter has any constraints already, we don't want to touch it, to avoid + // breaking use cases where a type parameter only needs to impl `Debug`, for example. + if known_bounds.is_empty() { + ensure_display_in_where_clause_for_type(where_clause, ident); + } + } +} + +/// Generate a `where` clause that ensures all generic type parameters `impl` +/// [core::fmt::Display] unless already constrained. +/// +/// This approach allows struct/enum definitions deriving [crate::Display] to avoid hardcoding +/// a [core::fmt::Display] constraint into every type parameter. +/// +/// If the type parameter isn't already constrained, we add a `where _: Display` clause to our +/// display implementation to expect to be able to format every enum case or struct member. +/// +/// In fact, we would preferably only require `where _: Display` or `where _: Debug` where the +/// format string actually requires it. However, while [`std::fmt` defines a formal syntax for +/// `format!()`][format syntax], it *doesn't* expose the actual logic to parse the format string, +/// which appears to live in [`rustc_parse_format`]. While we use the [`syn`] crate to parse rust +/// syntax, it also doesn't currently provide any method to introspect a `format!()` string. It +/// would be nice to contribute this upstream in [`syn`]. +/// +/// [format syntax]: std::fmt#syntax +/// [`rustc_parse_format`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse_format/index.html +fn generate_where_clause(generics: &Generics, where_clause: Option<&WhereClause>) -> WhereClause { + let mut where_clause = where_clause.cloned().unwrap_or_else(new_empty_where_clause); + let type_params: Vec<&TypeParam> = generics.type_params().collect(); + ensure_where_clause_has_display_for_all_unconstrained_members(&mut where_clause, &type_params); + where_clause +} + +fn impl_enum(input: &DeriveInput, data: &DataEnum) -> Result { + let ty = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let where_clause = generate_where_clause(&input.generics, where_clause); + + let helper = AttrsHelper::new(&input.attrs); + + let displays = data + .variants + .iter() + .map(|variant| helper.display_with_input(&input.attrs, &variant.attrs)) + .collect::>>()?; + + if data.variants.is_empty() { + Ok(quote! { + impl #impl_generics core::fmt::Display for #ty #ty_generics #where_clause { + fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + unreachable!("empty enums cannot be instantiated and thus cannot be printed") + } + } + }) + } else if displays.iter().any(Option::is_some) { + let arms = data + .variants + .iter() + .zip(displays) + .map(|(variant, display)| { + let display = + display.ok_or_else(|| Error::new_spanned(variant, "missing doc comment"))?; + let ident = &variant.ident; + Ok(match &variant.fields { + Fields::Named(fields) => { + let var = fields.named.iter().map(|field| &field.ident); + quote!(Self::#ident { #(#var),* } => { #display }) + } + Fields::Unnamed(fields) => { + let var = (0..fields.unnamed.len()).map(|i| format_ident!("_{}", i)); + quote!(Self::#ident(#(#var),*) => { #display }) + } + Fields::Unit => quote!(Self::#ident => { #display }), + }) + }) + .collect::>>()?; + Ok(quote! { + impl #impl_generics core::fmt::Display for #ty #ty_generics #where_clause { + fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + #[allow(unused_variables)] + match self { + #(#arms,)* + } + } + } + }) + } else { + Err(Error::new_spanned(input, "Missing doc comments")) + } +} diff --git a/utshell-0.5.0/vendor/displaydoc/src/fmt.rs b/utshell-0.5.0/vendor/displaydoc/src/fmt.rs new file mode 100644 index 00000000..3334a82f --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/src/fmt.rs @@ -0,0 +1,159 @@ +use crate::attr::Display; +use proc_macro2::TokenStream; +use quote::quote_spanned; +use syn::{Ident, LitStr}; + +macro_rules! peek_next { + ($read:ident) => { + match $read.chars().next() { + Some(next) => next, + None => return, + } + }; +} + +impl Display { + // Transform `"error {var}"` to `"error {}", var`. + pub(crate) fn expand_shorthand(&mut self) { + let span = self.fmt.span(); + let fmt = self.fmt.value(); + let mut read = fmt.as_str(); + let mut out = String::new(); + let mut args = TokenStream::new(); + + while let Some(brace) = read.find('{') { + out += &read[..=brace]; + read = &read[brace + 1..]; + + // skip cases where we find a {{ + if read.starts_with('{') { + out.push('{'); + read = &read[1..]; + continue; + } + + let next = peek_next!(read); + + let var = match next { + '0'..='9' => take_int(&mut read), + 'a'..='z' | 'A'..='Z' | '_' => take_ident(&mut read), + _ => return, + }; + + let ident = Ident::new(&var, span); + + let next = peek_next!(read); + + let arg = if cfg!(feature = "std") && next == '}' { + quote_spanned!(span=> , #ident.__displaydoc_display()) + } else { + quote_spanned!(span=> , #ident) + }; + + args.extend(arg); + } + + out += read; + self.fmt = LitStr::new(&out, self.fmt.span()); + self.args = args; + } +} + +fn take_int(read: &mut &str) -> String { + let mut int = String::new(); + int.push('_'); + for (i, ch) in read.char_indices() { + match ch { + '0'..='9' => int.push(ch), + _ => { + *read = &read[i..]; + break; + } + } + } + int +} + +fn take_ident(read: &mut &str) -> String { + let mut ident = String::new(); + for (i, ch) in read.char_indices() { + match ch { + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => ident.push(ch), + _ => { + *read = &read[i..]; + break; + } + } + } + ident +} + +#[cfg(test)] +mod tests { + use super::*; + use pretty_assertions::assert_eq; + use proc_macro2::Span; + + fn assert(input: &str, fmt: &str, args: &str) { + let mut display = Display { + fmt: LitStr::new(input, Span::call_site()), + args: TokenStream::new(), + }; + display.expand_shorthand(); + assert_eq!(fmt, display.fmt.value()); + assert_eq!(args, display.args.to_string()); + } + + #[test] + fn test_expand() { + assert("fn main() {{ }}", "fn main() {{ }}", ""); + } + + #[test] + #[cfg_attr(not(feature = "std"), ignore)] + fn test_std_expand() { + assert( + "{v} {v:?} {0} {0:?}", + "{} {:?} {} {:?}", + ", v . __displaydoc_display () , v , _0 . __displaydoc_display () , _0", + ); + assert("error {var}", "error {}", ", var . __displaydoc_display ()"); + + assert( + "error {var1}", + "error {}", + ", var1 . __displaydoc_display ()", + ); + + assert( + "error {var1var}", + "error {}", + ", var1var . __displaydoc_display ()", + ); + + assert( + "The path {0}", + "The path {}", + ", _0 . __displaydoc_display ()", + ); + assert("The path {0:?}", "The path {:?}", ", _0"); + } + + #[test] + #[cfg_attr(feature = "std", ignore)] + fn test_nostd_expand() { + assert( + "{v} {v:?} {0} {0:?}", + "{} {:?} {} {:?}", + ", v , v , _0 , _0", + ); + assert("error {var}", "error {}", ", var"); + + assert("The path {0}", "The path {}", ", _0"); + assert("The path {0:?}", "The path {:?}", ", _0"); + + assert("error {var1}", "error {}", ", var1"); + + assert("error {var1var}", "error {}", ", var1var"); + } +} diff --git a/utshell-0.5.0/vendor/displaydoc/src/lib.rs b/utshell-0.5.0/vendor/displaydoc/src/lib.rs new file mode 100644 index 00000000..e4653d67 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/src/lib.rs @@ -0,0 +1,187 @@ +//! This library provides a convenient derive macro for the standard library's +//! [`core::fmt::Display`] trait. +//! +//! [`core::fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html +//! +//! ```toml +//! [dependencies] +//! displaydoc = "0.2" +//! ``` +//! +//! *Compiler support: requires rustc 1.56+* +//! +//!
+//! +//! ## Example +//! +//! *Demonstration alongside the [`Error`][std::error::Error] derive macro from [`thiserror`](https://docs.rs/thiserror/1.0.25/thiserror/index.html), +//! to propagate source locations from [`io::Error`][std::io::Error] with the `#[source]` attribute:* +//! ```rust +//! use std::io; +//! use displaydoc::Display; +//! use thiserror::Error; +//! +//! #[derive(Display, Error, Debug)] +//! pub enum DataStoreError { +//! /// data store disconnected +//! Disconnect(#[source] io::Error), +//! /// the data for key `{0}` is not available +//! Redaction(String), +//! /// invalid header (expected {expected:?}, found {found:?}) +//! InvalidHeader { +//! expected: String, +//! found: String, +//! }, +//! /// unknown data store error +//! Unknown, +//! } +//! +//! let error = DataStoreError::Redaction("CLASSIFIED CONTENT".to_string()); +//! assert!("the data for key `CLASSIFIED CONTENT` is not available" == &format!("{}", error)); +//! ``` +//! *Note that although [`io::Error`][std::io::Error] implements `Display`, we do not add it to the +//! generated message for `DataStoreError::Disconnect`, since it is already made available via +//! `#[source]`. See further context on avoiding duplication in error reports at the rust blog +//! [here](https://github.com/yaahc/blog.rust-lang.org/blob/master/posts/inside-rust/2021-05-15-What-the-error-handling-project-group-is-working-towards.md#duplicate-information-issue).* +//! +//!
+//! +//! ## Details +//! +//! - A `fmt::Display` impl is generated for your enum if you provide +//! a docstring comment on each variant as shown above in the example. The +//! `Display` derive macro supports a shorthand for interpolating fields from +//! the error: +//! - `/// {var}` ⟶ `write!("{}", self.var)` +//! - `/// {0}` ⟶ `write!("{}", self.0)` +//! - `/// {var:?}` ⟶ `write!("{:?}", self.var)` +//! - `/// {0:?}` ⟶ `write!("{:?}", self.0)` +//! - This also works with structs and [generic types][crate::Display#generic-type-parameters]: +//! ```rust +//! # use displaydoc::Display; +//! /// oh no, an error: {0} +//! #[derive(Display)] +//! pub struct Error(pub E); +//! +//! let error: Error<&str> = Error("muahaha i am an error"); +//! assert!("oh no, an error: muahaha i am an error" == &format!("{}", error)); +//! ``` +//! +//! - Two optional attributes can be added to your types next to the derive: +//! +//! - `#[ignore_extra_doc_attributes]` makes the macro ignore any doc +//! comment attributes (or `///` lines) after the first. Multi-line +//! comments using `///` are otherwise treated as an error, so use this +//! attribute or consider switching to block doc comments (`/** */`). +//! +//! - `#[prefix_enum_doc_attributes]` combines the doc comment message on +//! your enum itself with the messages for each variant, in the format +//! “enum: variantâ€. When added to an enum, the doc comment on the enum +//! becomes mandatory. When added to any other type, it has no effect. +//! +//! - In case you want to have an independent doc comment, the +//! `#[displaydoc("...")` atrribute may be used on the variant or struct to +//! override it. +//! +//!
+//! +//! ## FAQ +//! +//! 1. **Is this crate `no_std` compatible?** +//! * Yes! This crate implements the [`core::fmt::Display`] trait, not the [`std::fmt::Display`] trait, so it should work in `std` and `no_std` environments. Just add `default-features = false`. +//! +//! 2. **Does this crate work with `Path` and `PathBuf` via the `Display` trait?** +//! * Yuuup. This crate uses @dtolnay's [autoref specialization technique](https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md) to add a special trait for types to get the display impl. It then specializes for `Path` and `PathBuf`, and when either of these types are found, it calls `self.display()` to get a `std::path::Display<'_>` type which can be used with the `Display` format specifier! +#![doc(html_root_url = "https://docs.rs/displaydoc/0.2.3")] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![warn( + rust_2018_idioms, + unreachable_pub, + bad_style, + dead_code, + improper_ctypes, + non_shorthand_field_patterns, + no_mangle_generic_items, + overflowing_literals, + path_statements, + patterns_in_fns_without_body, + private_in_public, + unconditional_recursion, + unused, + unused_allocation, + unused_comparisons, + unused_parens, + while_true +)] +#![allow(clippy::try_err)] + +#[allow(unused_extern_crates)] +extern crate proc_macro; + +mod attr; +mod expand; +mod fmt; + +use proc_macro::TokenStream; +use syn::{parse_macro_input, DeriveInput}; + +/// [Custom `#[derive(...)]` macro](https://doc.rust-lang.org/edition-guide/rust-2018/macros/custom-derive.html) +/// for implementing [`fmt::Display`][core::fmt::Display] via doc comment attributes. +/// +/// ### Generic Type Parameters +/// +/// Type parameters to an enum or struct using this macro should *not* need to +/// have an explicit `Display` constraint at the struct or enum definition +/// site. A `Display` implementation for the `derive`d struct or enum is +/// generated assuming each type parameter implements `Display`, but that should +/// be possible without adding the constraint to the struct definition itself: +/// ```rust +/// use displaydoc::Display; +/// +/// /// oh no, an error: {0} +/// #[derive(Display)] +/// pub struct Error(pub E); +/// +/// // No need to require `E: Display`, since `displaydoc::Display` adds that implicitly. +/// fn generate_error(e: E) -> Error { Error(e) } +/// +/// assert!("oh no, an error: muahaha" == &format!("{}", generate_error("muahaha"))); +/// ``` +/// +/// ### Using [`Debug`][core::fmt::Debug] Implementations with Type Parameters +/// However, if a type parameter must instead be constrained with the +/// [`Debug`][core::fmt::Debug] trait so that some field may be printed with +/// `{:?}`, that constraint must currently still also be specified redundantly +/// at the struct or enum definition site. If a struct or enum field is being +/// formatted with `{:?}` via [`displaydoc`][crate], and a generic type +/// parameter must implement `Debug` to do that, then that struct or enum +/// definition will need to propagate the `Debug` constraint to every type +/// parameter it's instantiated with: +/// ```rust +/// use core::fmt::Debug; +/// use displaydoc::Display; +/// +/// /// oh no, an error: {0:?} +/// #[derive(Display)] +/// pub struct Error(pub E); +/// +/// // `E: Debug` now has to propagate to callers. +/// fn generate_error(e: E) -> Error { Error(e) } +/// +/// assert!("oh no, an error: \"cool\"" == &format!("{}", generate_error("cool"))); +/// +/// // Try this with a struct that doesn't impl `Display` at all, unlike `str`. +/// #[derive(Debug)] +/// pub struct Oh; +/// assert!("oh no, an error: Oh" == &format!("{}", generate_error(Oh))); +/// ``` +#[proc_macro_derive( + Display, + attributes(ignore_extra_doc_attributes, prefix_enum_doc_attributes, displaydoc) +)] +pub fn derive_error(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + expand::derive(&input) + .unwrap_or_else(|err| err.to_compile_error()) + .into() +} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/compile_tests.rs b/utshell-0.5.0/vendor/displaydoc/tests/compile_tests.rs new file mode 100644 index 00000000..ac7427a7 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/compile_tests.rs @@ -0,0 +1,29 @@ +#[allow(unused_attributes)] +#[rustversion::attr(not(nightly), ignore)] +#[test] +fn no_std() { + let t = trybuild::TestCases::new(); + #[cfg(not(feature = "std"))] + t.compile_fail("tests/no_std/without.rs"); + #[cfg(not(feature = "std"))] + t.compile_fail("tests/no_std/multi_line.rs"); + #[cfg(not(feature = "std"))] + t.pass("tests/no_std/multi_line_allow.rs"); + #[cfg(not(feature = "std"))] + t.compile_fail("tests/no_std/enum_prefix_missing.rs"); + #[cfg(not(feature = "std"))] + t.pass("tests/no_std/enum_prefix.rs"); + #[cfg(feature = "std")] + t.compile_fail("tests/std/without.rs"); + #[cfg(feature = "std")] + t.compile_fail("tests/std/multi_line.rs"); + #[cfg(feature = "std")] + t.pass("tests/std/multi_line_allow.rs"); + #[cfg(feature = "std")] + t.compile_fail("tests/std/enum_prefix_missing.rs"); + #[cfg(feature = "std")] + t.pass("tests/std/enum_prefix.rs"); + #[cfg(feature = "std")] + t.pass("tests/std/multiple.rs"); + t.pass("tests/no_std/with.rs"); +} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/happy.rs b/utshell-0.5.0/vendor/displaydoc/tests/happy.rs new file mode 100644 index 00000000..f8fde9c6 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/happy.rs @@ -0,0 +1,152 @@ +use displaydoc::Display; + +#[cfg(feature = "std")] +use std::path::PathBuf; + +#[derive(Display)] +/// Just a basic struct {thing} +struct HappyStruct { + thing: &'static str, +} + +#[derive(Display)] +#[ignore_extra_doc_attributes] +/// Just a basic struct {thing} +/// and this line should get ignored +struct HappyStruct2 { + thing: &'static str, +} + +#[derive(Display)] +enum Happy { + /// I really like Variant1 + Variant1, + /// Variant2 is pretty swell 2 + Variant2, + /// Variant3 is okay {sometimes} + Variant3 { sometimes: &'static str }, + /** + * Variant4 wants to have a lot of lines + * + * Lets see how this works out for it + */ + Variant4, + /// Variant5 has a parameter {0} and some regular comments + // A regular comment that won't get picked + Variant5(u32), + + /// The path {0} + #[cfg(feature = "std")] + Variant6(PathBuf), + + /// These docs are ignored + #[displaydoc("Variant7 has a parameter {0} and uses #[displaydoc]")] + /// These docs are also ignored + Variant7(u32), +} + +// Used for testing indented doc comments +mod inner_mod { + use super::Display; + + #[derive(Display)] + pub enum InnerHappy { + /// I really like Variant1 + Variant1, + /// Variant2 is pretty swell 2 + Variant2, + /// Variant3 is okay {sometimes} + Variant3 { sometimes: &'static str }, + /** + * Variant4 wants to have a lot of lines + * + * Lets see how this works out for it + */ + Variant4, + /// Variant5 has a parameter {0} and some regular comments + // A regular comment that won't get picked + Variant5(u32), + + /** what happens if we + * put text on the first line? + */ + Variant6, + + /** + what happens if we don't use *? + */ + Variant7, + + /** + * + * what about extra new lines? + */ + Variant8, + } +} + +fn assert_display(input: T, expected: &'static str) { + let out = format!("{}", input); + assert_eq!(expected, out); +} + +#[test] +fn does_it_print() { + assert_display(Happy::Variant1, "I really like Variant1"); + assert_display(Happy::Variant2, "Variant2 is pretty swell 2"); + assert_display(Happy::Variant3 { sometimes: "hi" }, "Variant3 is okay hi"); + assert_display( + Happy::Variant4, + "Variant4 wants to have a lot of lines\n\nLets see how this works out for it", + ); + assert_display( + Happy::Variant5(2), + "Variant5 has a parameter 2 and some regular comments", + ); + assert_display( + Happy::Variant7(2), + "Variant7 has a parameter 2 and uses #[displaydoc]", + ); + assert_display(HappyStruct { thing: "hi" }, "Just a basic struct hi"); + + assert_display(HappyStruct2 { thing: "hi2" }, "Just a basic struct hi2"); + + assert_display(inner_mod::InnerHappy::Variant1, "I really like Variant1"); + assert_display( + inner_mod::InnerHappy::Variant2, + "Variant2 is pretty swell 2", + ); + assert_display( + inner_mod::InnerHappy::Variant3 { sometimes: "hi" }, + "Variant3 is okay hi", + ); + assert_display( + inner_mod::InnerHappy::Variant4, + "Variant4 wants to have a lot of lines\n\nLets see how this works out for it", + ); + assert_display( + inner_mod::InnerHappy::Variant5(2), + "Variant5 has a parameter 2 and some regular comments", + ); + assert_display( + inner_mod::InnerHappy::Variant6, + "what happens if we\nput text on the first line?", + ); + assert_display( + inner_mod::InnerHappy::Variant7, + "what happens if we don\'t use *?", + ); + assert_display( + inner_mod::InnerHappy::Variant8, + "what about extra new lines?", + ); +} + +#[test] +#[cfg(feature = "std")] +fn does_it_print_path() { + assert_display( + Happy::Variant6(PathBuf::from("/var/log/happy")), + "The path /var/log/happy", + ); +} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix.rs b/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix.rs new file mode 100644 index 00000000..b8482cac --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix.rs @@ -0,0 +1,36 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +#[prefix_enum_doc_attributes] +enum TestType { + /// this variant is too + Variant1, + + /// this variant is two + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.rs b/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.rs new file mode 100644 index 00000000..474073e8 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.rs @@ -0,0 +1,35 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +#[derive(Display)] +#[prefix_enum_doc_attributes] +enum TestType { + /// this variant is too + Variant1, + + /// this variant is two + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.stderr b/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.stderr new file mode 100644 index 00000000..8d402325 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/enum_prefix_missing.stderr @@ -0,0 +1,22 @@ +error: proc-macro derive panicked + --> $DIR/enum_prefix_missing.rs:22:10 + | +22 | #[derive(Display)] + | ^^^^^^^ + | + = help: message: Missing doc comment on enum with #[prefix_enum_doc_attributes]. Please remove the attribute or add a doc comment to the enum itself. + +error[E0277]: `TestType` doesn't implement `Display` + --> $DIR/enum_prefix_missing.rs:32:37 + | +32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^ `TestType` cannot be formatted with the default formatter + | + = help: the trait `Display` is not implemented for `TestType` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `assert_impl_all` + --> $DIR/enum_prefix_missing.rs:32:1 + | +32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + = note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.rs b/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.rs new file mode 100644 index 00000000..351f6a4e --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.rs @@ -0,0 +1,37 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +enum TestType { + /// This one is okay + Variant1, + + /// Multi + /// line + /// doc. + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.stderr b/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.stderr new file mode 100644 index 00000000..ae4956e3 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line.stderr @@ -0,0 +1,22 @@ +error: proc-macro derive panicked + --> $DIR/multi_line.rs:23:10 + | +23 | #[derive(Display)] + | ^^^^^^^ + | + = help: message: Multi-line comments are disabled by default by displaydoc. Please consider using block doc comments (/** */) or adding the #[ignore_extra_doc_attributes] attribute to your type next to the derive. + +error[E0277]: `TestType` doesn't implement `Display` + --> $DIR/multi_line.rs:34:37 + | +34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^ `TestType` cannot be formatted with the default formatter + | + = help: the trait `Display` is not implemented for `TestType` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `assert_impl_all` + --> $DIR/multi_line.rs:34:1 + | +34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + = note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line_allow.rs b/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line_allow.rs new file mode 100644 index 00000000..22511d9e --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/multi_line_allow.rs @@ -0,0 +1,38 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +#[ignore_extra_doc_attributes] +enum TestType { + /// This one is okay + Variant1, + + /// Multi + /// line + /// doc. + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/with.rs b/utshell-0.5.0/vendor/displaydoc/tests/no_std/with.rs new file mode 100644 index 00000000..eba74609 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/with.rs @@ -0,0 +1,32 @@ +#![feature(lang_items, start)] +#![no_std] + +#[start] +#[cfg(not(feature = "std"))] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} + +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} + +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +#[cfg(feature = "std")] +fn main() {} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +struct FakeType; + +static_assertions::assert_impl_all!(FakeType: core::fmt::Display); diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/without.rs b/utshell-0.5.0/vendor/displaydoc/tests/no_std/without.rs new file mode 100644 index 00000000..aab3164f --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/without.rs @@ -0,0 +1,28 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +/// this type is pretty swell +struct FakeType; + +static_assertions::assert_impl_all!(FakeType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/no_std/without.stderr b/utshell-0.5.0/vendor/displaydoc/tests/no_std/without.stderr new file mode 100644 index 00000000..afcea63f --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/no_std/without.stderr @@ -0,0 +1,22 @@ +warning: unused import: `displaydoc::Display` + --> $DIR/without.rs:20:5 + | +20 | use displaydoc::Display; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default + +error[E0277]: `FakeType` doesn't implement `Display` + --> $DIR/without.rs:25:37 + | +25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display); + | ^^^^^^^^ `FakeType` cannot be formatted with the default formatter + | + = help: the trait `Display` is not implemented for `FakeType` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `assert_impl_all` + --> $DIR/without.rs:25:1 + | +25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + = note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/displaydoc/tests/num_in_field.rs b/utshell-0.5.0/vendor/displaydoc/tests/num_in_field.rs new file mode 100644 index 00000000..ab90f0d7 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/num_in_field.rs @@ -0,0 +1,22 @@ +/// {foo1} {foo2} +#[derive(displaydoc::Display)] +pub struct Test { + foo1: String, + foo2: String, +} + +fn assert_display(input: T, expected: &'static str) { + let out = format!("{}", input); + assert_eq!(expected, out); +} + +#[test] +fn does_it_print() { + assert_display( + Test { + foo1: "hi".into(), + foo2: "hello".into(), + }, + "hi hello", + ); +} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix.rs b/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix.rs new file mode 100644 index 00000000..b8482cac --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix.rs @@ -0,0 +1,36 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +#[prefix_enum_doc_attributes] +enum TestType { + /// this variant is too + Variant1, + + /// this variant is two + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.rs b/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.rs new file mode 100644 index 00000000..474073e8 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.rs @@ -0,0 +1,35 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +#[derive(Display)] +#[prefix_enum_doc_attributes] +enum TestType { + /// this variant is too + Variant1, + + /// this variant is two + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.stderr b/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.stderr new file mode 100644 index 00000000..fe4b5ef7 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/enum_prefix_missing.stderr @@ -0,0 +1,22 @@ +error: proc-macro derive panicked + --> $DIR/enum_prefix_missing.rs:22:10 + | +22 | #[derive(Display)] + | ^^^^^^^ + | + = help: message: Missing doc comment on enum with #[prefix_enum_doc_attributes]. Please remove the attribute or add a doc comment to the enum itself. + +error[E0277]: `TestType` doesn't implement `std::fmt::Display` + --> $DIR/enum_prefix_missing.rs:32:37 + | +32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^ `TestType` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `TestType` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `assert_impl_all` + --> $DIR/enum_prefix_missing.rs:32:1 + | +32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + = note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.rs b/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.rs new file mode 100644 index 00000000..5b0f2cfd --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.rs @@ -0,0 +1 @@ +../no_std/multi_line.rs \ No newline at end of file diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.stderr b/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.stderr new file mode 100644 index 00000000..a8b6602b --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line.stderr @@ -0,0 +1,22 @@ +error: proc-macro derive panicked + --> $DIR/multi_line.rs:23:10 + | +23 | #[derive(Display)] + | ^^^^^^^ + | + = help: message: Multi-line comments are disabled by default by displaydoc. Please consider using block doc comments (/** */) or adding the #[ignore_extra_doc_attributes] attribute to your type next to the derive. + +error[E0277]: `TestType` doesn't implement `std::fmt::Display` + --> $DIR/multi_line.rs:34:37 + | +34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^ `TestType` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `TestType` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `assert_impl_all` + --> $DIR/multi_line.rs:34:1 + | +34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + = note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line_allow.rs b/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line_allow.rs new file mode 100644 index 00000000..22511d9e --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/multi_line_allow.rs @@ -0,0 +1,38 @@ +#![cfg_attr(not(feature = "std"), feature(lang_items, start))] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg_attr(not(feature = "std"), start)] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +#[ignore_extra_doc_attributes] +enum TestType { + /// This one is okay + Variant1, + + /// Multi + /// line + /// doc. + Variant2, +} + +static_assertions::assert_impl_all!(TestType: core::fmt::Display); + +#[cfg(feature = "std")] +fn main() {} diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/multiple.rs b/utshell-0.5.0/vendor/displaydoc/tests/std/multiple.rs new file mode 100644 index 00000000..b0a4de0f --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/multiple.rs @@ -0,0 +1,38 @@ +#![feature(lang_items, start)] +#![no_std] + +#[start] +#[cfg(not(feature = "std"))] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + 0 +} + +#[lang = "eh_personality"] +#[no_mangle] +#[cfg(not(feature = "std"))] +pub extern "C" fn rust_eh_personality() {} + +#[panic_handler] +#[cfg(not(feature = "std"))] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + libc::abort(); + } +} + +#[cfg(feature = "std")] +fn main() {} + +use displaydoc::Display; + +/// this type is pretty swell +#[derive(Display)] +struct FakeType; + +static_assertions::assert_impl_all!(FakeType: core::fmt::Display); + +/// this type is pretty swell2 +#[derive(Display)] +struct FakeType2; + +static_assertions::assert_impl_all!(FakeType2: core::fmt::Display); diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/without.rs b/utshell-0.5.0/vendor/displaydoc/tests/std/without.rs new file mode 100644 index 00000000..6b5b7148 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/without.rs @@ -0,0 +1 @@ +../no_std/without.rs \ No newline at end of file diff --git a/utshell-0.5.0/vendor/displaydoc/tests/std/without.stderr b/utshell-0.5.0/vendor/displaydoc/tests/std/without.stderr new file mode 100644 index 00000000..552ae826 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/std/without.stderr @@ -0,0 +1,22 @@ +warning: unused import: `displaydoc::Display` + --> $DIR/without.rs:20:5 + | +20 | use displaydoc::Display; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default + +error[E0277]: `FakeType` doesn't implement `std::fmt::Display` + --> $DIR/without.rs:25:37 + | +25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display); + | ^^^^^^^^ `FakeType` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `FakeType` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `assert_impl_all` + --> $DIR/without.rs:25:1 + | +25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all` + = note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/displaydoc/tests/variantless.rs b/utshell-0.5.0/vendor/displaydoc/tests/variantless.rs new file mode 100644 index 00000000..bc23ed46 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/tests/variantless.rs @@ -0,0 +1,6 @@ +use displaydoc::Display; + +#[derive(Display)] +enum EmptyInside {} + +static_assertions::assert_impl_all!(EmptyInside: core::fmt::Display); diff --git a/utshell-0.5.0/vendor/displaydoc/update-readme.sh b/utshell-0.5.0/vendor/displaydoc/update-readme.sh new file mode 100644 index 00000000..90db1a81 --- /dev/null +++ b/utshell-0.5.0/vendor/displaydoc/update-readme.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash + +cargo readme > ./README.md +git add ./README.md +git commit -m "Update readme" || true diff --git a/utshell-0.5.0/vendor/dunce/.cargo-checksum.json b/utshell-0.5.0/vendor/dunce/.cargo-checksum.json new file mode 100644 index 00000000..536d2892 --- /dev/null +++ b/utshell-0.5.0/vendor/dunce/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"8a145fbb954c2e34238698efb18cf654a671a79db0731e3ffbe7c197a53f269e","LICENSE":"a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499","README.md":"890653901012199b8780375755a8a0b5b6eafcded2c3bccace87099bdfba9274","src/lib.rs":"ed0d70d8b377aed2d43d574acdcc54a4bc33a73241c4c7058838197543f48156"},"package":"56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/dunce/Cargo.toml b/utshell-0.5.0/vendor/dunce/Cargo.toml new file mode 100644 index 00000000..355c2a65 --- /dev/null +++ b/utshell-0.5.0/vendor/dunce/Cargo.toml @@ -0,0 +1,42 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "dunce" +version = "1.0.4" +authors = ["Kornel "] +description = "Normalize Windows paths to the most compatible format, avoiding UNC where possible" +homepage = "https://lib.rs/crates/dunce" +documentation = "https://docs.rs/dunce" +readme = "README.md" +keywords = [ + "realpath", + "unc", + "canonicalize", + "windows", + "deunc", +] +categories = ["filesystem"] +license = "CC0-1.0 OR MIT-0 OR Apache-2.0" +repository = "https://gitlab.com/kornelski/dunce" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[badges.appveyor] +repository = "pornel/dunce" + +[badges.gitlab] +repository = "kornelski/dunce" + +[badges.maintenance] +status = "passively-maintained" diff --git a/utshell-0.5.0/vendor/dunce/LICENSE b/utshell-0.5.0/vendor/dunce/LICENSE new file mode 100644 index 00000000..0e259d42 --- /dev/null +++ b/utshell-0.5.0/vendor/dunce/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/utshell-0.5.0/vendor/dunce/README.md b/utshell-0.5.0/vendor/dunce/README.md new file mode 100644 index 00000000..40a9c103 --- /dev/null +++ b/utshell-0.5.0/vendor/dunce/README.md @@ -0,0 +1,17 @@ +# Dunce (de-UNC) + +In Windows the regular paths (`C:\foo`) are supported by all programs, +but have lots of bizarre restrictions for backwards compatibility with MS-DOS. +There are also Windows NT UNC paths (`\\?\C:\foo`), which are more robust and with fewer gotchas, +but are rarely supported by Windows programs. Even Microsoft's own! + +This crate converts Windows UNC paths to the MS-DOS-compatible format whenever possible, +but leaves UNC paths as-is when they can't be unambiguously expressed in a simpler way. +This allows legacy programs to access all paths they can possibly access, +and doesn't break any paths for UNC-aware programs. + +In Rust the worst UNC offender is the `fs::canonicalize()` function. This crate provides +a drop-in replacement for it that returns paths you'd expect. + +On non-Windows platforms these functions leave paths unmodified, so it's safe to use them +unconditionally for all platforms. diff --git a/utshell-0.5.0/vendor/dunce/src/lib.rs b/utshell-0.5.0/vendor/dunce/src/lib.rs new file mode 100644 index 00000000..8f11ec0e --- /dev/null +++ b/utshell-0.5.0/vendor/dunce/src/lib.rs @@ -0,0 +1,324 @@ +//! Filesystem paths in Windows are a total mess. This crate normalizes paths to the most +//! compatible (but still correct) format, so that you don't have to worry about the mess. +//! +//! In Windows the regular/legacy paths (`C:\foo`) are supported by all programs, but have +//! lots of bizarre restrictions for backwards compatibility with MS-DOS. +//! +//! And there are Windows NT UNC paths (`\\?\C:\foo`), which are more robust and with fewer +//! gotchas, but are rarely supported by Windows programs. Even Microsoft's own! +//! +//! This crate converts paths to legacy format whenever possible, but leaves UNC paths as-is +//! when they can't be unambiguously expressed in a simpler way. This allows legacy programs +//! to access all paths they can possibly access, and UNC-aware programs to access all paths. +//! +//! On non-Windows platforms these functions leave paths unmodified, so it's safe to use them +//! unconditionally for all platforms. +//! +//! Parsing is based on https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx +//! +//! [Project homepage](https://crates.rs/crates/dunce). +#![doc(html_logo_url = "https://assets.gitlab-static.net/uploads/-/system/project/avatar/4717715/dyc.png")] + +#[cfg(any(windows, test))] +use std::ffi::OsStr; +use std::fs; +use std::io; +#[cfg(windows)] +use std::os::windows::ffi::OsStrExt; +#[cfg(windows)] +use std::path::{Component, Prefix}; +use std::path::{Path, PathBuf}; + +/// Takes any path, and when possible, converts Windows UNC paths to regular paths. +/// +/// On non-Windows this is no-op. +/// +/// `\\?\C:\Windows` will be converted to `C:\Windows`, +/// but `\\?\C:\COM` will be left as-is (due to a reserved filename). +/// +/// Use this to pass arbitrary paths to programs that may not be UNC-aware. +/// It's generally safe to pass UNC paths to legacy programs, because +/// the paths contain a reserved character, so will gracefully fail +/// if used with wrong APIs. +/// +/// This function does not perform any I/O. +/// +/// Currently paths with unpaired surrogates aren't converted even if they +/// can be due to limitations of Rust's `OsStr` API. +#[inline] +pub fn simplified(path: &Path) -> &Path { + if is_safe_to_strip_unc(path) { + // unfortunately we can't safely strip prefix from a non-Unicode path + path.to_str().and_then(|s| s.get(4..)).map(Path::new).unwrap_or(path) + } else { + path + } +} + +/// Like `std::fs::canonicalize()`, but on Windows it outputs the most +/// compatible form of a path instead of UNC. +#[inline(always)] +pub fn canonicalize>(path: P) -> io::Result { + let path = path.as_ref(); + + #[cfg(not(windows))] + { + fs::canonicalize(path) + } + #[cfg(windows)] + { + canonicalize_win(path) + } +} + +#[cfg(windows)] +fn canonicalize_win(path: &Path) -> io::Result { + let real_path = fs::canonicalize(path)?; + Ok(if is_safe_to_strip_unc(&real_path) { + real_path.to_str().and_then(|s| s.get(4..)).map(PathBuf::from).unwrap_or(real_path) + } else { + real_path + }) +} + +pub use self::canonicalize as realpath; + +#[cfg(any(windows,test))] +fn windows_char_len(s: &OsStr) -> usize { + #[cfg(not(windows))] + let len = s.to_string_lossy().chars().map(|c| if c as u32 <= 0xFFFF {1} else {2}).sum(); + #[cfg(windows)] + let len = s.encode_wide().count(); + len +} + +#[cfg(any(windows,test))] +fn is_valid_filename(file_name: &OsStr) -> bool { + let file_name = file_name.as_ref(); + if windows_char_len(file_name) > 255 { + return false; + } + + // Non-unicode is safe, but Rust can't reasonably losslessly operate on such strings + let file_name = if let Some(s) = file_name.to_str() { + s + } else { + return false; + }; + if file_name.is_empty() { + return false; + } + // Only ASCII subset is checked, and UTF-8 is safe for that + let byte_str = file_name.as_bytes(); + for &c in byte_str { + match c { + 0..=31 | + b'<' | b'>' | b':' | b'"' | + b'/' | b'\\' | b'|' | b'?' | b'*' => return false, + _ => {}, + } + } + + // Filename can't end with . or space (except before extension, but this checks the whole name) + let last_char = byte_str[byte_str.len()-1]; + if last_char == b' ' || last_char == b'.' { + return false; + } + true +} + +#[cfg(any(windows, test))] +const RESERVED_NAMES: [&'static str; 22] = [ + "AUX", "NUL", "PRN", "CON", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", + "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", +]; + +#[cfg(any(windows, test))] +fn is_reserved>(file_name: P) -> bool { + // con.txt is reserved too + if let Some(stem) = Path::new(&file_name).file_stem() { + // all reserved DOS names have ASCII-compatible stem + if let Some(name) = stem.to_str() { + // "con.. .txt" is "CON" for DOS + let trimmed = right_trim(name); + if trimmed.len() <= 4 { + for name in &RESERVED_NAMES { + if name.eq_ignore_ascii_case(trimmed) { + return true; + } + } + } + } + } + false +} + +#[cfg(not(windows))] +#[inline] +fn is_safe_to_strip_unc(_path: &Path) -> bool { + false +} + +#[cfg(windows)] +fn is_safe_to_strip_unc(path: &Path) -> bool { + let mut components = path.components(); + match components.next() { + Some(Component::Prefix(p)) => match p.kind() { + Prefix::VerbatimDisk(..) => {}, + _ => return false, // Other kinds of UNC paths + }, + _ => return false, // relative or empty + } + + for component in components { + match component { + Component::RootDir => {}, + Component::Normal(file_name) => { + // it doesn't allocate in most cases, + // and checks are interested only in the ASCII subset, so lossy is fine + if !is_valid_filename(file_name) || is_reserved(file_name) { + return false; + } + } + _ => return false, // UNC paths take things like ".." literally + }; + } + + if windows_char_len(path.as_os_str()) > 260 { // However, if the path is going to be used as a directory it's 248 + return false; + } + true +} + +/// Trim '.' and ' ' +#[cfg(any(windows, test))] +fn right_trim(mut s: &str) -> &str { + while s.len() > 0 { + let last = s.len()-1; + unsafe { + if s.as_bytes()[last] == b'.' || s.as_bytes()[last] == b' ' { + s = s.get_unchecked(0..last) // trim of ASCII byte can't break UTF-8 + } else { + break; + } + } + } + s +} + +#[test] +fn trim_test() { + assert_eq!("a", right_trim("a.")); + assert_eq!("Ä…", right_trim("Ä….")); + assert_eq!("a", right_trim("a ")); + assert_eq!("Ä…Ä…", right_trim("Ä…Ä… ")); + assert_eq!("a", right_trim("a. . . .... ")); + assert_eq!("a. . . ..ź", right_trim("a. . . ..ź.. ")); + assert_eq!(" b", right_trim(" b")); + assert_eq!(" ã¹", right_trim(" ã¹")); + assert_eq!("c. c", right_trim("c. c.")); + assert_eq!("。", right_trim("。")); + assert_eq!("", right_trim("")); +} + +#[test] +fn reserved() { + assert!(is_reserved("CON")); + assert!(is_reserved("con")); + assert!(is_reserved("con.con")); + assert!(is_reserved("COM4")); + assert!(is_reserved("COM4.txt")); + assert!(is_reserved("COM4 .txt")); + assert!(is_reserved("con.")); + assert!(is_reserved("con .")); + assert!(is_reserved("con ")); + assert!(is_reserved("con . ")); + assert!(is_reserved("con . .txt")); + assert!(is_reserved("con.....txt")); + assert!(is_reserved("PrN.....")); + + assert!(!is_reserved(" PrN.....")); + assert!(!is_reserved(" CON")); + assert!(!is_reserved("COM0")); + assert!(!is_reserved("COM77")); + assert!(!is_reserved(" CON ")); + assert!(!is_reserved(".CON")); + assert!(!is_reserved("@CON")); + assert!(!is_reserved("not.CON")); + assert!(!is_reserved("CON。")); +} + +#[test] +fn len() { + assert_eq!(1, windows_char_len(OsStr::new("a"))); + assert_eq!(1, windows_char_len(OsStr::new("€"))); + assert_eq!(1, windows_char_len(OsStr::new("本"))); + assert_eq!(2, windows_char_len(OsStr::new("ðŸ§"))); + assert_eq!(2, windows_char_len(OsStr::new("®®"))); +} + +#[test] +fn valid() { + assert!(!is_valid_filename("..".as_ref())); + assert!(!is_valid_filename(".".as_ref())); + assert!(!is_valid_filename("aaaaaaaaaa:".as_ref())); + assert!(!is_valid_filename("Ä…:Ä…".as_ref())); + assert!(!is_valid_filename("".as_ref())); + assert!(!is_valid_filename("a ".as_ref())); + assert!(!is_valid_filename(" a. ".as_ref())); + assert!(!is_valid_filename("a/".as_ref())); + assert!(!is_valid_filename("/a".as_ref())); + assert!(!is_valid_filename("/".as_ref())); + assert!(!is_valid_filename("\\".as_ref())); + assert!(!is_valid_filename("\\a".as_ref())); + assert!(!is_valid_filename("".as_ref())); + assert!(!is_valid_filename("a*".as_ref())); + assert!(!is_valid_filename("?x".as_ref())); + assert!(!is_valid_filename("a\0a".as_ref())); + assert!(!is_valid_filename("\x1f".as_ref())); + assert!(!is_valid_filename(::std::iter::repeat("a").take(257).collect::().as_ref())); + + assert!(is_valid_filename(::std::iter::repeat("®").take(254).collect::().as_ref())); + assert!(is_valid_filename("ファイル".as_ref())); + assert!(is_valid_filename("a".as_ref())); + assert!(is_valid_filename("a.aaaaaaaa".as_ref())); + assert!(is_valid_filename("a........a".as_ref())); + assert!(is_valid_filename(" b".as_ref())); +} + +#[test] +#[cfg(windows)] +fn realpath_test() { + assert_eq!(r"C:\WINDOWS", canonicalize(r"C:\Windows").unwrap().to_str().unwrap().to_uppercase()); + assert_ne!(r".", canonicalize(r".").unwrap().to_str().unwrap()); +} + +#[test] +#[cfg(windows)] +fn strip() { + assert_eq!(Path::new(r"C:\foo\😀"), simplified(Path::new(r"\\?\C:\foo\😀"))); + assert_eq!(Path::new(r"\\?\serv\"), simplified(Path::new(r"\\?\serv\"))); + assert_eq!(Path::new(r"\\.\C:\notdisk"), simplified(Path::new(r"\\.\C:\notdisk"))); + assert_eq!(Path::new(r"\\?\GLOBALROOT\Device\ImDisk0\path\to\file.txt"), simplified(Path::new(r"\\?\GLOBALROOT\Device\ImDisk0\path\to\file.txt"))); +} + +#[test] +#[cfg(windows)] +fn safe() { + assert!(is_safe_to_strip_unc(Path::new(r"\\?\C:\foo\bar"))); + assert!(is_safe_to_strip_unc(Path::new(r"\\?\Z:\foo\bar\"))); + assert!(is_safe_to_strip_unc(Path::new(r"\\?\Z:\😀\🎃\"))); + assert!(is_safe_to_strip_unc(Path::new(r"\\?\c:\foo"))); + + let long = ::std::iter::repeat("®").take(160).collect::(); + assert!(is_safe_to_strip_unc(Path::new(&format!(r"\\?\c:\{}", long)))); + assert!(!is_safe_to_strip_unc(Path::new(&format!(r"\\?\c:\{}\{}", long, long)))); + + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\C:\foo\.\bar"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\C:\foo\..\bar"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c\foo"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c\foo/bar"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c:foo"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\cc:foo"))); + assert!(!is_safe_to_strip_unc(Path::new(r"\\?\c:foo\bar"))); +} diff --git a/utshell-0.5.0/vendor/elsa/.cargo-checksum.json b/utshell-0.5.0/vendor/elsa/.cargo-checksum.json new file mode 100644 index 00000000..2695c46a --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"b153d32e5a52e6a1866a11eaf51d6e4bf379996f3926e1ecf89da1a78824593b","Cargo.toml":"d14cb65426d3e38bcc5c7c752a728761766feb1ebe2bb9e196123c9d8a9f3cec","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"15656cc11a8331f28c0986b8ab97220d3e76f98e60ed388b5ffad37dfac4710c","README.md":"72ec631a7cc4907ab80d87776b8eb1929d7cbd76b260f2fdb913714787f30dac","examples/arena.rs":"dd44f11e4b4e8b1eedca5ce5205aef3efface3c8888daa16b735dd476362b335","examples/fluentresource.rs":"d2bc2a1b02e6c92819bc608d91214591d8dc7d52f7f524c24e39ba5fe28ee6fe","examples/mutable_arena.rs":"553541b20ac97339cf89e2ef60810490f8362520911f3279f4129a30c2af6eb6","examples/string_interner.rs":"d8b427b71e6c340bf8ee01bc1245c82839fa6efb3dde6b91aab8791f0dfebbf9","examples/sync.rs":"bf9f395c029129fac6247068874b9514e0a174d342174dc4c65716acdbce3741","src/index_map.rs":"372c40a803deccfab07f62544138f488b040d4fb45b35d9e7aed09a560147cc9","src/index_set.rs":"2a1be6ff43b037abdf308c2548d5ba915553830669002ca0d8c2fa2157055c04","src/lib.rs":"d26839bf88764445d2ec453b269b4359761186afda947101ee42c344cb0ad940","src/map.rs":"57911793c69efce2cb2b6950e1062981c458e6eca7b0db5dcb24a88b297e9c98","src/sync.rs":"29cd04117f758c613d07cefb63d1aa40e682849f0029aa3056c4d0facc6d322b","src/vec.rs":"c9f053f0e22dc40ff1137d60b87650bf521f09a41111c4b8329b37af59893697"},"package":"714f766f3556b44e7e4776ad133fcc3445a489517c25c704ace411bb14790194"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/elsa/Cargo.lock b/utshell-0.5.0/vendor/elsa/Cargo.lock new file mode 100644 index 00000000..09536e78 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/Cargo.lock @@ -0,0 +1,39 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "elsa" +version = "1.9.0" +dependencies = [ + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" diff --git a/utshell-0.5.0/vendor/elsa/Cargo.toml b/utshell-0.5.0/vendor/elsa/Cargo.toml new file mode 100644 index 00000000..5b9517bc --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/Cargo.toml @@ -0,0 +1,47 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "elsa" +version = "1.9.0" +authors = ["Manish Goregaokar "] +description = "Append-only collections for Rust where borrows to entries can outlive insertions" +documentation = "https://docs.rs/elsa/" +readme = "README.md" +keywords = [ + "data-structure", + "map", + "frozen", + "cache", + "arena", +] +categories = [ + "data-structures", + "caching", +] +license = "MIT/Apache-2.0" +repository = "https://github.com/manishearth/elsa" + +[package.metadata.docs.rs] +features = ["indexmap"] + +[[example]] +name = "string_interner" +path = "examples/string_interner.rs" +required-features = ["indexmap"] + +[dependencies.indexmap] +version = "1.6" +optional = true + +[dependencies.stable_deref_trait] +version = "1.1.1" diff --git a/utshell-0.5.0/vendor/elsa/LICENSE-APACHE b/utshell-0.5.0/vendor/elsa/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/elsa/LICENSE-MIT b/utshell-0.5.0/vendor/elsa/LICENSE-MIT new file mode 100644 index 00000000..d74f9e93 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/LICENSE-MIT @@ -0,0 +1,27 @@ +MIT License + +Copyright (c) 2019 Manish Goregaokar + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/elsa/README.md b/utshell-0.5.0/vendor/elsa/README.md new file mode 100644 index 00000000..cd4a5b94 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/README.md @@ -0,0 +1,19 @@ +## elsa + +[![Build Status](https://travis-ci.org/Manishearth/elsa.svg?branch=master)](https://travis-ci.org/Manishearth/elsa) +[![Current Version](https://img.shields.io/crates/v/elsa.svg)](https://crates.io/crates/elsa) +[![License: MIT/Apache-2.0](https://img.shields.io/crates/l/elsa.svg)](#license) + +_🎵 Immutability never bothered me anyway 🎶_ + +This crate provides various "frozen" collections. + +These are append-only collections where references to entries can be held on to even across insertions. This is safe because these collections only support storing data that's present behind some indirection -- i.e. `String`, `Vec`, `Box`, etc, and they only yield references to the data behind the allocation (`&str`, `&[T]`, and `&T` respectively) + +The typical use case is having a global cache of strings or other data which the rest of the program borrows from. + +### Running all examples + +```bash +cargo test --examples --features indexmap +``` diff --git a/utshell-0.5.0/vendor/elsa/examples/arena.rs b/utshell-0.5.0/vendor/elsa/examples/arena.rs new file mode 100644 index 00000000..79913c2e --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/examples/arena.rs @@ -0,0 +1,56 @@ +use elsa::FrozenVec; + +fn main() { + let arena = Arena::new(); + let lonely = arena.add_thing("lonely", vec![]); + let best_friend = arena.add_thing("best friend", vec![lonely]); + let threes_a_crowd = arena.add_thing("threes a crowd", vec![lonely, best_friend]); + let rando = arena.add_thing("rando", vec![]); + let _facebook = arena.add_thing("facebook", vec![rando, threes_a_crowd, lonely, best_friend]); + + assert!(cmp_ref(lonely, best_friend.friends[0])); + assert!(cmp_ref(best_friend, threes_a_crowd.friends[1])); + arena.dump(); +} + +struct Arena<'arena> { + things: FrozenVec>>, +} + +struct Thing<'arena> { + pub friends: Vec>, + pub name: &'static str, +} + +type ThingRef<'arena> = &'arena Thing<'arena>; + +impl<'arena> Arena<'arena> { + fn new() -> Arena<'arena> { + Arena { + things: FrozenVec::new(), + } + } + + fn add_thing( + &'arena self, + name: &'static str, + friends: Vec>, + ) -> ThingRef<'arena> { + let idx = self.things.len(); + self.things.push(Box::new(Thing { name, friends })); + &self.things[idx] + } + + fn dump(&'arena self) { + for thing in &self.things { + println!("friends of {}:", thing.name); + for friend in &thing.friends { + println!("\t{}", friend.name); + } + } + } +} + +fn cmp_ref(x: &T, y: &T) -> bool { + x as *const T as usize == y as *const T as usize +} diff --git a/utshell-0.5.0/vendor/elsa/examples/fluentresource.rs b/utshell-0.5.0/vendor/elsa/examples/fluentresource.rs new file mode 100644 index 00000000..dba4aaed --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/examples/fluentresource.rs @@ -0,0 +1,50 @@ +use elsa::FrozenMap; + +/// Stores some parsed AST representation of the file +#[derive(Debug)] +pub struct FluentResource<'mgr>(&'mgr str); + +impl<'mgr> FluentResource<'mgr> { + pub fn new(s: &'mgr str) -> Self { + // very simple parse step + FluentResource(&s[0..1]) + } +} + +/// Stores loaded files and parsed ASTs +/// +/// Parsed ASTs are zero-copy and +/// contain references to the files +pub struct ResourceManager<'mgr> { + strings: FrozenMap, + resources: FrozenMap>>, +} + +impl<'mgr> ResourceManager<'mgr> { + pub fn new() -> Self { + ResourceManager { + strings: FrozenMap::new(), + resources: FrozenMap::new(), + } + } + + pub fn get_resource(&'mgr self, path: &str) -> &'mgr FluentResource<'mgr> { + let strings = &self.strings; + + if strings.get(path).is_some() { + return self.resources.get(path).unwrap(); + } else { + // pretend to load a file + let string = format!("file for {}", path); + let val = self.strings.insert(path.to_string(), string); + let res = FluentResource::new(val); + self.resources.insert(path.to_string(), Box::new(res)) + } + } +} + +fn main() { + let manager = ResourceManager::new(); + let resource = manager.get_resource("somefile.ftl"); + println!("{:?}", resource); +} diff --git a/utshell-0.5.0/vendor/elsa/examples/mutable_arena.rs b/utshell-0.5.0/vendor/elsa/examples/mutable_arena.rs new file mode 100644 index 00000000..d5db2d33 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/examples/mutable_arena.rs @@ -0,0 +1,79 @@ +use elsa::FrozenVec; + +fn main() { + let arena = Arena::new(); + let lonely = arena.add_person("lonely", vec![]); + let best_friend = arena.add_person("best friend", vec![lonely]); + let threes_a_crowd = arena.add_person("threes a crowd", vec![lonely, best_friend]); + let rando = arena.add_person("rando", vec![]); + let _everyone = arena.add_person( + "follows everyone", + vec![rando, threes_a_crowd, lonely, best_friend], + ); + arena.dump(); +} + +struct Arena<'arena> { + people: FrozenVec>>, +} + +struct Person<'arena> { + pub follows: FrozenVec>, + pub reverse_follows: FrozenVec>, + pub name: &'static str, +} + +type PersonRef<'arena> = &'arena Person<'arena>; + +impl<'arena> Arena<'arena> { + fn new() -> Arena<'arena> { + Arena { + people: FrozenVec::new(), + } + } + + fn add_person( + &'arena self, + name: &'static str, + follows: Vec>, + ) -> PersonRef<'arena> { + let idx = self.people.len(); + self.people.push(Box::new(Person { + name, + follows: follows.into(), + reverse_follows: Default::default(), + })); + let me = &self.people[idx]; + for friend in &me.follows { + friend.reverse_follows.push(me) + } + me + } + + fn dump(&'arena self) { + for thing in &self.people { + println!("{} network:", thing.name); + println!("\tfollowing:"); + for friend in &thing.follows { + println!("\t\t{}", friend.name); + } + println!("\tfollowers:"); + for friend in &thing.reverse_follows { + println!("\t\t{}", friend.name); + } + } + } +} + +// Note that the following will cause the above code to stop compiling +// since non-eyepatched custom destructors can potentially +// read deallocated data. +// +// impl<'arena> Drop for Person<'arena> { +// fn drop(&mut self) { +// println!("goodbye {:?}", self.name); +// for friend in &self.follows { +// println!("\t\t{}", friend.name); +// } +// } +// } diff --git a/utshell-0.5.0/vendor/elsa/examples/string_interner.rs b/utshell-0.5.0/vendor/elsa/examples/string_interner.rs new file mode 100644 index 00000000..fd039f7b --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/examples/string_interner.rs @@ -0,0 +1,61 @@ +use std::collections::BTreeSet; +use std::convert::AsRef; + +use elsa::FrozenIndexSet; + +struct StringInterner { + set: FrozenIndexSet, +} + +impl StringInterner { + fn new() -> Self { + StringInterner { + set: FrozenIndexSet::new(), + } + } + + fn get_or_intern(&self, value: T) -> usize + where + T: AsRef, + { + // TODO use Entry in case the standard Entry API gets improved + // (here to avoid premature allocation or double lookup) + self.set.insert_full(value.as_ref().to_string()).0 + } + + fn get(&self, value: T) -> Option + where + T: AsRef, + { + self.set.get_full(value.as_ref()).map(|(i, _r)| i) + } + + fn resolve(&self, index: usize) -> Option<&str> { + self.set.get_index(index) + } +} + +fn main() { + let interner = StringInterner::new(); + let lonely = interner.get_or_intern("lonely"); + let best_friend = interner.get_or_intern("best friend"); + let threes_a_crowd = interner.get_or_intern("threes a crowd"); + let rando = interner.get_or_intern("rando"); + let _facebook = interner.get_or_intern("facebook"); + + let best_friend_2 = interner.get_or_intern("best friend"); + let best_friend_3 = interner.get("best friend").unwrap(); + + let best_friend_ref = interner.resolve(best_friend).unwrap(); + + let mut set = BTreeSet::new(); + set.insert(lonely); + set.insert(best_friend); + set.insert(threes_a_crowd); + set.insert(rando); + set.insert(best_friend_2); + assert_eq!(set.len(), 4); + assert_eq!(best_friend, best_friend_2); + assert_eq!(best_friend_2, best_friend_3); + assert_eq!(best_friend_ref, "best friend"); +} diff --git a/utshell-0.5.0/vendor/elsa/examples/sync.rs b/utshell-0.5.0/vendor/elsa/examples/sync.rs new file mode 100644 index 00000000..c6d9eb3c --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/examples/sync.rs @@ -0,0 +1,26 @@ +use elsa::sync::*; + +use std::sync::Arc; +use std::thread; +use std::time::Duration; + +fn main() { + let a = Arc::new(FrozenMap::new()); + for i in 1..10 { + let b = a.clone(); + thread::spawn(move || { + b.insert(i, i.to_string()); + thread::sleep(Duration::from_millis(300)); + loop { + if let Some(opposite) = b.get(&(10 - i)) { + assert!(opposite.parse::().unwrap() == 10 - i); + break; + } else { + thread::sleep(Duration::from_millis(200)); + } + } + }); + } + + thread::sleep(Duration::from_millis(1000)); +} diff --git a/utshell-0.5.0/vendor/elsa/src/index_map.rs b/utshell-0.5.0/vendor/elsa/src/index_map.rs new file mode 100644 index 00000000..fb70b7f2 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/src/index_map.rs @@ -0,0 +1,237 @@ +use std::borrow::Borrow; +use std::cell::{Cell, UnsafeCell}; +use std::collections::hash_map::RandomState; +use std::hash::{BuildHasher, Hash}; +use std::iter::FromIterator; +use std::ops::Index; + +use indexmap::IndexMap; +use stable_deref_trait::StableDeref; + +/// Append-only version of `indexmap::IndexMap` where +/// insertion does not require mutable access +pub struct FrozenIndexMap { + map: UnsafeCell>, + /// Eq/Hash implementations can have side-effects, and using Rc it is possible + /// for FrozenIndexMap::insert to be called on a key that itself contains the same + /// `FrozenIndexMap`, whose `eq` implementation also calls FrozenIndexMap::insert + /// + /// We use this `in_use` flag to guard against any reentrancy. + in_use: Cell, +} + +// safety: UnsafeCell implies !Sync + +impl FrozenIndexMap { + pub fn new() -> Self { + Self { + map: UnsafeCell::new(Default::default()), + in_use: Cell::new(false), + } + } +} + +impl FrozenIndexMap { + // these should never return &K or &V + // these should never delete any entries + pub fn insert(&self, k: K, v: V) -> &V::Target { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + &*(*map).entry(k).or_insert(v) + }; + self.in_use.set(false); + ret + } + + // these should never return &K or &V + // these should never delete any entries + pub fn insert_full(&self, k: K, v: V) -> (usize, &V::Target) { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + let entry = (*map).entry(k); + let index = entry.index(); + (index, &**entry.or_insert(v)) + }; + self.in_use.set(false); + ret + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenIndexMap; + /// + /// let map = FrozenIndexMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + pub fn get(&self, k: &Q) -> Option<&V::Target> + where + K: Borrow, + Q: Hash + Eq, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get(k).map(|x| &**x) + }; + self.in_use.set(false); + ret + } + + pub fn get_index(&self, index: usize) -> Option<(&K::Target, &V::Target)> + where + K: StableDeref, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get_index(index).map(|(k, v)| (&**k, &**v)) + }; + self.in_use.set(false); + ret + } + + /// Applies a function to the owner of the value corresponding to the key (if any). + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenIndexMap; + /// + /// let map = FrozenIndexMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a"))); + /// assert_eq!(map.map_get(&2, Clone::clone), None); + /// ``` + pub fn map_get(&self, k: &Q, f: F) -> Option + where + K: Borrow, + Q: Hash + Eq, + F: FnOnce(&V) -> T, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get(k).map(f) + }; + self.in_use.set(false); + ret + } +} + +impl FrozenIndexMap { + /// Collects the contents of this map into a vector of tuples. + /// + /// The order of the entries is as if iterating an [`IndexMap`]. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenIndexMap; + /// + /// let map = FrozenIndexMap::new(); + /// map.insert(1, Box::new("a")); + /// map.insert(2, Box::new("b")); + /// let tuple_vec = map.into_tuple_vec(); + /// + /// assert_eq!(tuple_vec, vec![(1, Box::new("a")), (2, Box::new("b"))]); + /// ``` + pub fn into_tuple_vec(self) -> Vec<(K, V)> { + self.map.into_inner().into_iter().collect::>() + } + + pub fn into_map(self) -> IndexMap { + self.map.into_inner() + } + + /// Get mutable access to the underlying [`IndexMap`]. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + pub fn as_mut(&mut self) -> &mut IndexMap { + unsafe { &mut *self.map.get() } + } + + /// Returns true if the map contains no elements. + pub fn is_empty(&self) -> bool { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).is_empty() + }; + self.in_use.set(false); + ret + } +} + +impl From> for FrozenIndexMap { + fn from(map: IndexMap) -> Self { + Self { + map: UnsafeCell::new(map), + in_use: Cell::new(false), + } + } +} + +impl Index<&Q> for FrozenIndexMap +where + Q: Eq + Hash, + K: Eq + Hash + Borrow, + V: StableDeref, + S: BuildHasher, +{ + type Output = V::Target; + + /// # Examples + /// + /// ``` + /// use elsa::FrozenIndexMap; + /// + /// let map = FrozenIndexMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map[&1], "a"); + /// ``` + fn index(&self, idx: &Q) -> &V::Target { + self.get(&idx) + .expect("attempted to index FrozenIndexMap with unknown key") + } +} + +impl FromIterator<(K, V)> for FrozenIndexMap { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + let map: IndexMap<_, _, _> = iter.into_iter().collect(); + map.into() + } +} + +impl Default for FrozenIndexMap { + fn default() -> Self { + Self { + map: UnsafeCell::new(Default::default()), + in_use: Cell::new(false), + } + } +} diff --git a/utshell-0.5.0/vendor/elsa/src/index_set.rs b/utshell-0.5.0/vendor/elsa/src/index_set.rs new file mode 100644 index 00000000..9e99632a --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/src/index_set.rs @@ -0,0 +1,182 @@ +use std::borrow::Borrow; +use std::cell::{Cell, UnsafeCell}; +use std::collections::hash_map::RandomState; +use std::hash::{BuildHasher, Hash}; +use std::iter::FromIterator; +use std::ops::Index; + +use indexmap::IndexSet; +use stable_deref_trait::StableDeref; + +/// Append-only version of `indexmap::IndexSet` where +/// insertion does not require mutable access +pub struct FrozenIndexSet { + set: UnsafeCell>, + /// Eq/Hash implementations can have side-effects, and using Rc it is possible + /// for FrozenIndexSet::insert to be called on a key that itself contains the same + /// `FrozenIndexSet`, whose `eq` implementation also calls FrozenIndexSet::insert + /// + /// We use this `in_use` flag to guard against any reentrancy. + in_use: Cell, +} + +// safety: UnsafeCell implies !Sync + +impl FrozenIndexSet { + pub fn new() -> Self { + Self::from(IndexSet::new()) + } +} + +impl FrozenIndexSet { + // these should never return &T + // these should never delete any entries + pub fn insert(&self, value: T) -> &T::Target { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let set = self.set.get(); + let (index, _was_vacant) = (*set).insert_full(value); + &*(*set)[index] + }; + self.in_use.set(false); + ret + } + + // these should never return &T + // these should never delete any entries + pub fn insert_full(&self, value: T) -> (usize, &T::Target) { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let set = self.set.get(); + let (index, _was_vacant) = (*set).insert_full(value); + (index, &*(*set)[index]) + }; + self.in_use.set(false); + ret + } + + // TODO implement in case the standard Entry API gets improved + // // TODO avoid double lookup + // pub fn entry(&self, value: &Q) -> Entry + // where Q: Hash + Equivalent + ToOwned + // { + // assert!(!self.in_use.get()); + // self.in_use.set(true); + // unsafe { + // let set = self.set.get(); + // match (*set).get_full(value) { + // Some((index, reference)) => { + // Entry::Occupied(OccupiedEntry { + // index, + // reference, + // set: &*set, + // }) + // } + // None => { + // Entry::Vacant(VacantEntry { + // value: Cow::Borrowed(value), + // set: &*set, + // }) + // } + // } + // } + // } + + pub fn get(&self, k: &Q) -> Option<&T::Target> + where + T: Borrow, + Q: Hash + Eq, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let set = self.set.get(); + (*set).get(k).map(|x| &**x) + }; + self.in_use.set(false); + ret + } + + pub fn get_full(&self, k: &Q) -> Option<(usize, &T::Target)> + where + T: Borrow, + Q: Hash + Eq, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let set = self.set.get(); + (*set).get_full(k).map(|(i, x)| (i, &**x)) + }; + self.in_use.set(false); + ret + } + + pub fn get_index(&self, index: usize) -> Option<&T::Target> { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let set = self.set.get(); + (*set).get_index(index).map(|r| &**r) + }; + self.in_use.set(false); + ret + } +} + +impl FrozenIndexSet { + pub fn into_set(self) -> IndexSet { + self.set.into_inner() + } + + /// Get mutable access to the underlying [`IndexSet`]. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + pub fn as_mut(&mut self) -> &mut IndexSet { + unsafe { &mut *self.set.get() } + } + + // TODO add more +} + +impl From> for FrozenIndexSet { + fn from(set: IndexSet) -> Self { + Self { + set: UnsafeCell::new(set), + in_use: Cell::new(false), + } + } +} + +impl Index for FrozenIndexSet { + type Output = T::Target; + fn index(&self, idx: usize) -> &T::Target { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let set = self.set.get(); + &*(*set)[idx] + }; + self.in_use.set(false); + ret + } +} + +impl FromIterator for FrozenIndexSet { + fn from_iter(iter: U) -> Self + where + U: IntoIterator, + { + let set: IndexSet<_, _> = iter.into_iter().collect(); + set.into() + } +} + +impl Default for FrozenIndexSet { + fn default() -> Self { + Self::from(IndexSet::default()) + } +} diff --git a/utshell-0.5.0/vendor/elsa/src/lib.rs b/utshell-0.5.0/vendor/elsa/src/lib.rs new file mode 100644 index 00000000..848dceb3 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/src/lib.rs @@ -0,0 +1,29 @@ +//! _🎵 Immutability never bothered me anyway 🎶_ +//! +//! This crate provides various "Frozen" collections. +//! +//! These are append-only collections where references to entries can be held +//! on to even across insertions. This is safe because these collections only +//! support storing data that's present behind some indirection -- i.e. `String`, +//! `Vec`, `Box`, etc, and they only yield references to the data behind the +//! allocation (`&str`, `&[T]`, and `&T` respectively) +//! +//! The typical use case is having a global cache of strings or other data which the rest of the program borrows from. + +pub mod map; +pub mod vec; + +#[cfg(feature = "indexmap")] +pub mod index_map; +#[cfg(feature = "indexmap")] +pub mod index_set; + +pub mod sync; + +pub use map::{FrozenBTreeMap, FrozenMap}; +pub use vec::FrozenVec; + +#[cfg(feature = "indexmap")] +pub use index_map::FrozenIndexMap; +#[cfg(feature = "indexmap")] +pub use index_set::FrozenIndexSet; diff --git a/utshell-0.5.0/vendor/elsa/src/map.rs b/utshell-0.5.0/vendor/elsa/src/map.rs new file mode 100644 index 00000000..147a2ec1 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/src/map.rs @@ -0,0 +1,497 @@ +use std::borrow::Borrow; +use std::cell::{Cell, UnsafeCell}; +use std::collections::hash_map::RandomState; +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::hash::{BuildHasher, Hash}; +use std::iter::FromIterator; +use std::ops::Index; + +use stable_deref_trait::StableDeref; + +/// Append-only version of `std::collections::HashMap` where +/// insertion does not require mutable access +pub struct FrozenMap { + map: UnsafeCell>, + /// Eq/Hash implementations can have side-effects, and using Rc it is possible + /// for FrozenMap::insert to be called on a key that itself contains the same + /// `FrozenMap`, whose `eq` implementation also calls FrozenMap::insert + /// + /// We use this `in_use` flag to guard against any reentrancy. + in_use: Cell, +} + +// safety: UnsafeCell implies !Sync + +impl FrozenMap { + pub fn new() -> Self { + Self { + map: UnsafeCell::new(Default::default()), + in_use: Cell::new(false), + } + } + + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.len(), 0); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.len(), 1); + /// ``` + pub fn len(&self) -> usize { + assert!(!self.in_use.get()); + self.in_use.set(true); + let len = unsafe { + let map = self.map.get(); + (*map).len() + }; + self.in_use.set(false); + len + } + + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.is_empty(), true); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.is_empty(), false); + /// ``` + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl FrozenMap { + // these should never return &K or &V + // these should never delete any entries + pub fn insert(&self, k: K, v: V) -> &V::Target { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + &*(*map).entry(k).or_insert(v) + }; + self.in_use.set(false); + ret + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + pub fn get(&self, k: &Q) -> Option<&V::Target> + where + K: Borrow, + Q: Hash + Eq, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get(k).map(|x| &**x) + }; + self.in_use.set(false); + ret + } + + /// Applies a function to the owner of the value corresponding to the key (if any). + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a"))); + /// assert_eq!(map.map_get(&2, Clone::clone), None); + /// ``` + pub fn map_get(&self, k: &Q, f: F) -> Option + where + K: Borrow, + Q: Hash + Eq, + F: FnOnce(&V) -> T, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get(k).map(f) + }; + self.in_use.set(false); + ret + } +} + +impl FrozenMap { + /// Collects the contents of this map into a vector of tuples. + /// + /// The order of the entries is as if iterating a [`HashMap`] (stochastic). + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// map.insert(2, Box::new("b")); + /// let mut tuple_vec = map.into_tuple_vec(); + /// tuple_vec.sort(); + /// + /// assert_eq!(tuple_vec, vec![(1, Box::new("a")), (2, Box::new("b"))]); + /// ``` + pub fn into_tuple_vec(self) -> Vec<(K, V)> { + self.map.into_inner().into_iter().collect::>() + } + + pub fn into_map(self) -> HashMap { + self.map.into_inner() + } + + // TODO add more +} + +impl FrozenMap { + /// Returns a reference to the key and value matching a borrowed + /// key. + /// + /// The key argument may be any borrowed form of the map's key type, + /// but [`Hash`] and [`Eq`] on the borrowed form *must* match those + /// for the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(Box::new("1"), Box::new("a")); + /// assert_eq!(map.get_key_value(&"1"), Some((&"1", &"a"))); + /// assert_eq!(map.get_key_value(&"2"), None); + /// ``` + pub fn get_key_value(&self, k: &Q) -> Option<(&K::Target, &V::Target)> + where + K: Borrow, + Q: Hash + Eq, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get_key_value(k).map(|(k, v)| (&**k, &**v)) + }; + self.in_use.set(false); + ret + } +} + +impl std::convert::AsMut> for FrozenMap { + /// Get mutable access to the underlying [`HashMap`]. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + fn as_mut(&mut self) -> &mut HashMap { + unsafe { &mut *self.map.get() } + } +} + +impl From> for FrozenMap { + fn from(map: HashMap) -> Self { + Self { + map: UnsafeCell::new(map), + in_use: Cell::new(false), + } + } +} + +impl Index<&Q> for FrozenMap +where + Q: Eq + Hash, + K: Eq + Hash + Borrow, + V: StableDeref, + S: BuildHasher, +{ + type Output = V::Target; + + /// # Examples + /// + /// ``` + /// use elsa::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map[&1], "a"); + /// ``` + fn index(&self, idx: &Q) -> &V::Target { + self.get(idx) + .expect("attempted to index FrozenMap with unknown key") + } +} + +impl FromIterator<(K, V)> for FrozenMap { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + let map: HashMap<_, _, _> = iter.into_iter().collect(); + map.into() + } +} + +impl Default for FrozenMap { + fn default() -> Self { + Self { + map: UnsafeCell::new(Default::default()), + in_use: Cell::new(false), + } + } +} + +/// Append-only version of `std::collections::BTreeMap` where +/// insertion does not require mutable access +pub struct FrozenBTreeMap { + map: UnsafeCell>, + /// Eq/Hash implementations can have side-effects, and using Rc it is possible + /// for FrozenBTreeMap::insert to be called on a key that itself contains the same + /// `FrozenBTreeMap`, whose `eq` implementation also calls FrozenBTreeMap::insert + /// + /// We use this `in_use` flag to guard against any reentrancy. + in_use: Cell, +} + +// safety: UnsafeCell implies !Sync + +impl FrozenBTreeMap { + pub fn new() -> Self { + Self { + map: UnsafeCell::new(Default::default()), + in_use: Cell::new(false), + } + } + + /// # Examples + /// + /// ``` + /// use elsa::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// assert_eq!(map.len(), 0); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.len(), 1); + /// ``` + pub fn len(&self) -> usize { + assert!(!self.in_use.get()); + self.in_use.set(true); + let len = unsafe { + let map = self.map.get(); + (*map).len() + }; + self.in_use.set(false); + len + } + + /// # Examples + /// + /// ``` + /// use elsa::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// assert_eq!(map.is_empty(), true); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.is_empty(), false); + /// ``` + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl FrozenBTreeMap { + // these should never return &K or &V + // these should never delete any entries + pub fn insert(&self, k: K, v: V) -> &V::Target { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + &*(*map).entry(k).or_insert(v) + }; + self.in_use.set(false); + ret + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + pub fn get(&self, k: &Q) -> Option<&V::Target> + where + K: Borrow, + Q: Ord, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get(k).map(|x| &**x) + }; + self.in_use.set(false); + ret + } + + /// Applies a function to the owner of the value corresponding to the key (if any). + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a"))); + /// assert_eq!(map.map_get(&2, Clone::clone), None); + /// ``` + pub fn map_get(&self, k: &Q, f: F) -> Option + where + K: Borrow, + Q: Ord, + F: FnOnce(&V) -> T, + { + assert!(!self.in_use.get()); + self.in_use.set(true); + let ret = unsafe { + let map = self.map.get(); + (*map).get(k).map(f) + }; + self.in_use.set(false); + ret + } +} + +impl FrozenBTreeMap { + /// Collects the contents of this map into a vector of tuples. + /// + /// The order of the entries is as if iterating a [`BTreeMap`] (ordered by key). + /// + /// # Examples + /// + /// ``` + /// use elsa::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// map.insert(2, Box::new("b")); + /// let mut tuple_vec = map.into_tuple_vec(); + /// tuple_vec.sort(); + /// + /// assert_eq!(tuple_vec, vec![(1, Box::new("a")), (2, Box::new("b"))]); + /// ``` + pub fn into_tuple_vec(self) -> Vec<(K, V)> { + self.map.into_inner().into_iter().collect::>() + } + + pub fn into_map(self) -> BTreeMap { + self.map.into_inner() + } + + // TODO add more +} + +impl std::convert::AsMut> for FrozenBTreeMap { + /// Get mutable access to the underlying [`HashMap`]. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + fn as_mut(&mut self) -> &mut BTreeMap { + unsafe { &mut *self.map.get() } + } +} + +impl From> for FrozenBTreeMap { + fn from(map: BTreeMap) -> Self { + Self { + map: UnsafeCell::new(map), + in_use: Cell::new(false), + } + } +} + +impl Index<&Q> for FrozenBTreeMap +where + Q: Ord, + K: Clone + Ord + Borrow, + V: StableDeref, +{ + type Output = V::Target; + + /// # Examples + /// + /// ``` + /// use elsa::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map[&1], "a"); + /// ``` + fn index(&self, idx: &Q) -> &V::Target { + self.get(idx) + .expect("attempted to index FrozenBTreeMap with unknown key") + } +} + +impl FromIterator<(K, V)> for FrozenBTreeMap { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + let map: BTreeMap<_, _> = iter.into_iter().collect(); + map.into() + } +} + +impl Default for FrozenBTreeMap { + fn default() -> Self { + Self { + map: UnsafeCell::new(Default::default()), + in_use: Cell::new(false), + } + } +} diff --git a/utshell-0.5.0/vendor/elsa/src/sync.rs b/utshell-0.5.0/vendor/elsa/src/sync.rs new file mode 100644 index 00000000..13b1f902 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/src/sync.rs @@ -0,0 +1,858 @@ +//! **This module is experimental** +//! +//! This module provides threadsafe versions of FrozenMap and FrozenVec, +//! ideal for use as a cache. +//! +//! These lock internally, however locks only last as long as the method calls +//! + +use stable_deref_trait::StableDeref; +use std::alloc::Layout; +use std::borrow::Borrow; +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::hash::Hash; +use std::iter::{FromIterator, IntoIterator}; +use std::ops::Index; + +use std::sync::atomic::AtomicPtr; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; +use std::sync::RwLock; + +/// Append-only threadsafe version of `std::collections::HashMap` where +/// insertion does not require mutable access +pub struct FrozenMap { + map: RwLock>, +} + +impl Default for FrozenMap { + fn default() -> Self { + Self { + map: Default::default(), + } + } +} + +impl FrozenMap { + pub fn new() -> Self { + Self::default() + } +} + +impl FrozenMap { + // these should never return &K or &V + // these should never delete any entries + + /// If the key exists in the map, returns a reference + /// to the corresponding value, otherwise inserts a + /// new entry in the map for that key and returns a + /// reference to the given value. + /// + /// Existing values are never overwritten. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.insert(1, Box::new("a")), &"a"); + /// assert_eq!(map.insert(1, Box::new("b")), &"a"); + /// ``` + pub fn insert(&self, k: K, v: V) -> &V::Target { + let mut map = self.map.write().unwrap(); + let ret = unsafe { + let inserted = &**map.entry(k).or_insert(v); + &*(inserted as *const _) + }; + ret + } + + /// If the key exists in the map, returns a reference to the corresponding + /// value, otherwise inserts a new entry in the map for that key and the + /// value returned by the creation function, and returns a reference to the + /// generated value. + /// + /// Existing values are never overwritten. + /// + /// The key may be any borrowed form of the map's key type, but [`Hash`] and + /// [`Eq`] on the borrowed form *must* match those for the key type. + /// + /// **Note** that the write lock is held for the duration of this function’s + /// execution, even while the value creation function is executing (if + /// needed). This will block any concurrent `get` or `insert` calls. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.insert_with(1, || Box::new("a")), &"a"); + /// assert_eq!(map.insert_with(1, || unreachable!()), &"a"); + /// ``` + pub fn insert_with(&self, k: K, f: impl FnOnce() -> V) -> &V::Target { + let mut map = self.map.write().unwrap(); + let ret = unsafe { + let inserted = &**map.entry(k).or_insert_with(f); + &*(inserted as *const _) + }; + ret + } + + /// If the key exists in the map, returns a reference to the corresponding + /// value, otherwise inserts a new entry in the map for that key and the + /// value returned by the creation function, and returns a reference to the + /// generated value. + /// + /// Existing values are never overwritten. + /// + /// The key may be any borrowed form of the map's key type, but [`Hash`] and + /// [`Eq`] on the borrowed form *must* match those for the key type. + /// + /// **Note** that the write lock is held for the duration of this function’s + /// execution, even while the value creation function is executing (if + /// needed). This will block any concurrent `get` or `insert` calls. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.insert_with_key(1, |_| Box::new("a")), &"a"); + /// assert_eq!(map.insert_with_key(1, |_| unreachable!()), &"a"); + /// ``` + pub fn insert_with_key(&self, k: K, f: impl FnOnce(&K) -> V) -> &V::Target { + let mut map = self.map.write().unwrap(); + let ret = unsafe { + let inserted = &**map.entry(k).or_insert_with_key(f); + &*(inserted as *const _) + }; + ret + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + pub fn get(&self, k: &Q) -> Option<&V::Target> + where + K: Borrow, + Q: Hash + Eq, + { + let map = self.map.read().unwrap(); + let ret = unsafe { map.get(k).map(|x| &*(&**x as *const V::Target)) }; + ret + } + + /// Applies a function to the owner of the value corresponding to the key (if any). + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a"))); + /// assert_eq!(map.map_get(&2, Clone::clone), None); + /// ``` + pub fn map_get(&self, k: &Q, f: F) -> Option + where + K: Borrow, + Q: Hash + Eq, + F: FnOnce(&V) -> T, + { + let map = self.map.read().unwrap(); + let ret = map.get(k).map(f); + ret + } +} + +impl FrozenMap { + /// Collects the contents of this map into a vector of tuples. + /// + /// The order of the entries is as if iterating a [`HashMap`] (stochastic). + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.insert(1, Box::new("a")); + /// map.insert(2, Box::new("b")); + /// let mut tuple_vec = map.into_tuple_vec(); + /// tuple_vec.sort(); + /// + /// assert_eq!(tuple_vec, vec![(1, Box::new("a")), (2, Box::new("b"))]); + /// ``` + pub fn into_tuple_vec(self) -> Vec<(K, V)> { + self.map + .into_inner() + .unwrap() + .into_iter() + .collect::>() + } + + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.len(), 0); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.len(), 1); + /// ``` + pub fn len(&self) -> usize { + let map = self.map.read().unwrap(); + map.len() + } + + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.is_empty(), true); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.is_empty(), false); + /// ``` + pub fn is_empty(&self) -> bool { + let map = self.map.read().unwrap(); + map.is_empty() + } + + // TODO add more +} + +impl FrozenMap { + pub fn keys_cloned(&self) -> Vec { + self.map.read().unwrap().keys().cloned().collect() + } +} + +impl FrozenMap { + /// Returns a copy of the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// map.get_copy_or_insert(1, 6); + /// assert_eq!(map.get_copy(&1), Some(6)); + /// assert_eq!(map.get_copy(&2), None); + /// ``` + pub fn get_copy(&self, k: &Q) -> Option + where + K: Borrow, + Q: Hash + Eq, + { + let map = self.map.read().unwrap(); + map.get(k).cloned() + } + + /// If the key exists in the map, returns a reference + /// to the corresponding value, otherwise inserts a + /// new entry in the map for that key and returns a + /// reference to the given value. + /// + /// Existing values are never overwritten. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.get_copy_or_insert(1, 6), 6); + /// assert_eq!(map.get_copy_or_insert(1, 12), 6); + /// ``` + pub fn get_copy_or_insert(&self, k: K, v: V) -> V { + let mut map = self.map.write().unwrap(); + // This is safe because `or_insert` does not overwrite existing values + let inserted = map.entry(k).or_insert(v); + *inserted + } + + /// If the key exists in the map, returns a reference to the corresponding + /// value, otherwise inserts a new entry in the map for that key and the + /// value returned by the creation function, and returns a reference to the + /// generated value. + /// + /// Existing values are never overwritten. + /// + /// The key may be any borrowed form of the map's key type, but [`Hash`] and + /// [`Eq`] on the borrowed form *must* match those for the key type. + /// + /// **Note** that the write lock is held for the duration of this function’s + /// execution, even while the value creation function is executing (if + /// needed). This will block any concurrent `get` or `insert` calls. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.get_copy_or_insert_with(1, || 6), 6); + /// assert_eq!(map.get_copy_or_insert_with(1, || unreachable!()), 6); + /// ``` + pub fn get_copy_or_insert_with(&self, k: K, f: impl FnOnce() -> V) -> V { + let mut map = self.map.write().unwrap(); + // This is safe because `or_insert_with` does not overwrite existing values + let inserted = map.entry(k).or_insert_with(f); + *inserted + } + + /// If the key exists in the map, returns a reference to the corresponding + /// value, otherwise inserts a new entry in the map for that key and the + /// value returned by the creation function, and returns a reference to the + /// generated value. + /// + /// Existing values are never overwritten. + /// + /// The key may be any borrowed form of the map's key type, but [`Hash`] and + /// [`Eq`] on the borrowed form *must* match those for the key type. + /// + /// **Note** that the write lock is held for the duration of this function’s + /// execution, even while the value creation function is executing (if + /// needed). This will block any concurrent `get` or `insert` calls. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenMap; + /// + /// let map = FrozenMap::new(); + /// assert_eq!(map.get_copy_or_insert_with_key(1, |_| 6), 6); + /// assert_eq!(map.get_copy_or_insert_with_key(1, |_| unreachable!()), 6); + /// ``` + pub fn get_copy_or_insert_with_key(&self, k: K, f: impl FnOnce(&K) -> V) -> V { + let mut map = self.map.write().unwrap(); + // This is safe because `or_insert_with_key` does not overwrite existing values + let inserted = map.entry(k).or_insert_with_key(f); + *inserted + } +} + +impl std::convert::AsMut> for FrozenMap { + /// Get mutable access to the underlying [`HashMap`]. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + fn as_mut(&mut self) -> &mut HashMap { + self.map.get_mut().unwrap() + } +} + +/// Append-only threadsafe version of `std::vec::Vec` where +/// insertion does not require mutable access +pub struct FrozenVec { + vec: RwLock>, +} + +impl FrozenVec { + /// Returns the number of elements in the vector. + pub fn len(&self) -> usize { + let vec = self.vec.read().unwrap(); + vec.len() + } + + /// Returns `true` if the vector contains no elements. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl FrozenVec { + pub fn new() -> Self { + Default::default() + } + + // these should never return &T + // these should never delete any entries + + pub fn push(&self, val: T) { + let mut vec = self.vec.write().unwrap(); + vec.push(val); + } + + /// Push, immediately getting a reference to the element + pub fn push_get(&self, val: T) -> &T::Target { + let mut vec = self.vec.write().unwrap(); + vec.push(val); + unsafe { &*(&**vec.get_unchecked(vec.len() - 1) as *const T::Target) } + } + + /// Push, immediately getting a an index of the element + /// + /// Index can then be used with the `get` method + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenVec; + /// + /// let map = FrozenVec::new(); + /// let idx = map.push_get_index(String::from("a")); + /// assert_eq!(map.get(idx), Some("a")); + /// assert_eq!(idx, 0); + /// assert_eq!(map.push_get_index(String::from("b")), 1); + /// ``` + pub fn push_get_index(&self, val: T) -> usize { + let mut vec = self.vec.write().unwrap(); + let index = vec.len(); + vec.push(val); + return index; + } + + pub fn get(&self, index: usize) -> Option<&T::Target> { + let vec = self.vec.read().unwrap(); + unsafe { vec.get(index).map(|x| &*(&**x as *const T::Target)) } + } +} + +impl FrozenVec { + /// Returns the internal vector backing this structure + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenVec; + /// + /// let map = FrozenVec::new(); + /// map.push("a"); + /// map.push("b"); + /// let tuple_vec = map.into_vec(); + /// + /// assert_eq!(tuple_vec, vec!["a", "b"]); + /// ``` + pub fn into_vec(self) -> Vec { + self.vec.into_inner().unwrap() + } + + // TODO add more +} + +impl std::convert::AsMut> for FrozenVec { + /// Get mutable access to the underlying vector. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + fn as_mut(&mut self) -> &mut Vec { + self.vec.get_mut().unwrap() + } +} + +impl Default for FrozenVec { + fn default() -> Self { + Self { + vec: Default::default(), + } + } +} + +/// Append-only threadsafe version of `std::vec::Vec` where +/// insertion does not require mutable access. +/// Does not have locks, only allows `Copy` types and will +/// spinlock on contention. The spinlocks are really rare as +/// they only happen on reallocation due to a push going over +/// the capacity. +pub struct LockFreeFrozenVec { + data: AtomicPtr, + len: AtomicUsize, + cap: AtomicUsize, +} + +impl Drop for LockFreeFrozenVec { + fn drop(&mut self) { + let cap = *self.cap.get_mut(); + let layout = Self::layout(cap); + if cap != 0 { + unsafe { + std::alloc::dealloc((*self.data.get_mut()).cast(), layout); + } + } + } +} + +impl Default for LockFreeFrozenVec { + fn default() -> Self { + Self { + // FIXME: use `std::ptr::invalid_mut()` once that is stable. + data: AtomicPtr::new(std::mem::align_of::() as *mut T), + len: AtomicUsize::new(0), + cap: AtomicUsize::new(0), + } + } +} + +impl LockFreeFrozenVec { + pub fn new() -> Self { + Default::default() + } + + pub fn with_capacity(cap: usize) -> Self { + Self { + data: AtomicPtr::new(unsafe { std::alloc::alloc(Self::layout(cap)) }.cast()), + len: AtomicUsize::new(0), + cap: AtomicUsize::new(cap), + } + } + + fn lock(&self, f: impl FnOnce(&mut *mut T) -> U) -> U { + let mut ptr; + loop { + ptr = self.data.swap(std::ptr::null_mut(), Ordering::Acquire); + if !ptr.is_null() { + // Wheeeee spinlock + break; + } + } + + let ret = f(&mut ptr); + self.data.store(ptr, Ordering::Release); + ret + } + + fn layout(cap: usize) -> Layout { + Layout::array::(cap).unwrap() + } + + // these should never return &T + // these should never delete any entries + + const NOT_ZST: () = if std::mem::size_of::() == 0 { + panic!("`LockFreeFrozenVec` cannot be used with ZSTs"); + }; + + pub fn push(&self, val: T) -> usize { + // This statement actually does something: it evaluates a constant. + #[allow(path_statements)] + { + Self::NOT_ZST + } + self.lock(|ptr| { + // These values must be consistent with the pointer we got. + let len = self.len.load(Ordering::Acquire); + let cap = self.cap.load(Ordering::Acquire); + if len >= cap { + if cap == 0 { + // No memory allocated yet + let layout = Self::layout(128); + // SAFETY: `LockFreeFrozenVec` statically rejects zsts + unsafe { + *ptr = std::alloc::alloc(layout).cast::(); + } + // This is written before the end of the `lock` closure, so no one will observe this + // until the data pointer has been updated anyway. + self.cap.store(128, Ordering::Release); + } else { + // Out of memory, realloc with double the capacity + let layout = Self::layout(cap); + let new_size = layout.size() * 2; + // SAFETY: `LockFreeFrozenVec` statically rejects zsts and the input `ptr` has always been + // allocated at the size stated in `cap`. + unsafe { + *ptr = std::alloc::realloc((*ptr).cast(), layout, new_size).cast::(); + } + // This is written before the end of the `lock` closure, so no one will observe this + // until the data pointer has been updated anyway. + self.cap.store(cap * 2, Ordering::Release); + } + assert!(!ptr.is_null()); + } + unsafe { + ptr.add(len).write(val); + } + // This is written before updating the data pointer. Other `push` calls cannot observe this, + // because they are blocked on aquiring the data pointer before they ever read the `len`. + // `get` may read the length before actually aquiring the data pointer lock, but that is fine, + // as once it is able to aquire the lock, there will be actually the right number of elements + // stored. + self.len.store(len + 1, Ordering::Release); + len + }) + } + + pub fn get(&self, index: usize) -> Option { + // The length can only grow, so just doing the length check + // independently of the `lock` and read is fine. Worst case we + // read an old length value and end up returning `None` even if + // another thread already inserted the value. + let len = self.len.load(Ordering::Relaxed); + if index >= len { + return None; + } + self.lock(|ptr| Some(unsafe { ptr.add(index).read() })) + } + + pub fn is_empty(&self) -> bool { + self.len.load(Ordering::Relaxed) == 0 + } +} + +#[test] +fn test_non_lockfree() { + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + struct Moo(i32); + + for vec in [ + LockFreeFrozenVec::new(), + LockFreeFrozenVec::with_capacity(1), + LockFreeFrozenVec::with_capacity(2), + LockFreeFrozenVec::with_capacity(1000), + ] { + assert_eq!(vec.get(1), None); + + vec.push(Moo(1)); + let i = vec.push(Moo(2)); + vec.push(Moo(3)); + + assert_eq!(vec.get(i), Some(Moo(2))); + + std::thread::scope(|s| { + s.spawn(|| { + for i in 0..1000 { + vec.push(Moo(i)); + } + }); + s.spawn(|| { + for i in 0..1000 { + vec.push(Moo(i)); + } + }); + for i in 0..2000 { + while vec.get(i).is_none() {} + } + }); + } + // Test dropping empty vecs + for _ in [ + LockFreeFrozenVec::<()>::new(), + LockFreeFrozenVec::with_capacity(1), + LockFreeFrozenVec::with_capacity(2), + LockFreeFrozenVec::with_capacity(1000), + ] {} +} + +// TODO: Implement IntoIterator for LockFreeFrozenVec + +/// Append-only threadsafe version of `std::collections::BTreeMap` where +/// insertion does not require mutable access +#[derive(Debug)] +pub struct FrozenBTreeMap(RwLock>); + +impl FrozenBTreeMap { + pub fn new() -> Self { + Self(RwLock::new(BTreeMap::new())) + } + + // these should never return &K or &V + // these should never delete any entries + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Ord`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); + /// ``` + pub fn get(&self, k: &Q) -> Option<&V::Target> + where + K: Borrow, + Q: Ord, + { + let map = self.0.read().unwrap(); + let ret = unsafe { map.get(k).map(|x| &*(&**x as *const V::Target)) }; + ret + } + + /// Insert a new value into the map. Does nothing if the key is already occupied. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.get(&1), Some(&"a")); + /// ``` + pub fn insert(&self, k: K, v: V) -> &V::Target { + let mut map = self.0.write().unwrap(); + let ret = unsafe { + let inserted = &**map.entry(k).or_insert(v); + &*(inserted as *const _) + }; + ret + } + + /// Applies a function to the owner of the value corresponding to the key (if any). + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Ord`] on the borrowed form *must* match those for + /// the key type. + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a"))); + /// assert_eq!(map.map_get(&2, Clone::clone), None); + /// ``` + pub fn map_get(&self, k: &Q, f: F) -> Option + where + K: Borrow, + Q: Ord, + F: FnOnce(&V) -> T, + { + let map = self.0.read().unwrap(); + let ret = map.get(k).map(f); + ret + } +} + +impl FrozenBTreeMap { + /// Collects the contents of this map into a vector of tuples. + /// + /// The order of the entries is as if iterating a [`BTreeMap`] (ordered by key). + /// + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// map.insert(2, Box::new("b")); + /// let tuple_vec = map.into_tuple_vec(); + /// + /// assert_eq!(tuple_vec, vec![(1, Box::new("a")), (2, Box::new("b"))]); + /// ``` + pub fn into_tuple_vec(self) -> Vec<(K, V)> { + self.0.into_inner().unwrap().into_iter().collect::>() + } + + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// assert_eq!(map.len(), 0); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.len(), 1); + /// ``` + pub fn len(&self) -> usize { + let map = self.0.read().unwrap(); + map.len() + } + + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// assert_eq!(map.is_empty(), true); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map.is_empty(), false); + /// ``` + pub fn is_empty(&self) -> bool { + let map = self.0.read().unwrap(); + map.is_empty() + } +} + +impl From> for FrozenBTreeMap { + fn from(map: BTreeMap) -> Self { + Self(RwLock::new(map)) + } +} + +impl Index<&Q> for FrozenBTreeMap +where + Q: Ord, + K: Clone + Ord + Borrow, + V: StableDeref, +{ + type Output = V::Target; + + /// # Examples + /// + /// ``` + /// use elsa::sync::FrozenBTreeMap; + /// + /// let map = FrozenBTreeMap::new(); + /// map.insert(1, Box::new("a")); + /// assert_eq!(map[&1], "a"); + /// ``` + fn index(&self, idx: &Q) -> &V::Target { + self.get(idx) + .expect("attempted to index FrozenBTreeMap with unknown key") + } +} + +impl FromIterator<(K, V)> for FrozenBTreeMap { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + let map: BTreeMap<_, _> = iter.into_iter().collect(); + map.into() + } +} + +impl Default for FrozenBTreeMap { + fn default() -> Self { + Self::new() + } +} diff --git a/utshell-0.5.0/vendor/elsa/src/vec.rs b/utshell-0.5.0/vendor/elsa/src/vec.rs new file mode 100644 index 00000000..33b6e6a5 --- /dev/null +++ b/utshell-0.5.0/vendor/elsa/src/vec.rs @@ -0,0 +1,347 @@ +use std::cell::UnsafeCell; +use std::cmp::Ordering; +use std::iter::FromIterator; +use std::ops::Index; + +use stable_deref_trait::StableDeref; + +/// Append-only version of `std::vec::Vec` where +/// insertion does not require mutable access +pub struct FrozenVec { + vec: UnsafeCell>, + // XXXManishearth do we need a reentrancy guard here as well? + // StableDeref may not guarantee that there are no side effects +} + +// safety: UnsafeCell implies !Sync + +impl FrozenVec { + /// Constructs a new, empty vector. + pub fn new() -> Self { + Self { + vec: UnsafeCell::new(Default::default()), + } + } +} + +impl FrozenVec { + // these should never return &T + // these should never delete any entries + + /// Appends an element to the back of the vector. + pub fn push(&self, val: T) { + unsafe { + let vec = self.vec.get(); + (*vec).push(val) + } + } +} + +impl FrozenVec { + /// Push, immediately getting a reference to the element + pub fn push_get(&self, val: T) -> &T::Target { + unsafe { + let vec = self.vec.get(); + (*vec).push(val); + &*(&**(*vec).get_unchecked((*vec).len() - 1) as *const T::Target) + } + } + + /// Returns a reference to an element. + pub fn get(&self, index: usize) -> Option<&T::Target> { + unsafe { + let vec = self.vec.get(); + (*vec).get(index).map(|x| &**x) + } + } + + /// Returns a reference to an element, without doing bounds checking. + /// + /// ## Safety + /// + /// `index` must be in bounds, i.e. it must be less than `self.len()` + pub unsafe fn get_unchecked(&self, index: usize) -> &T::Target { + let vec = self.vec.get(); + &**(*vec).get_unchecked(index) + } +} + +impl FrozenVec { + /// Returns a copy of an element. + pub fn get_copy(&self, index: usize) -> Option { + unsafe { + let vec = self.vec.get(); + (*vec).get(index).copied() + } + } +} + +impl FrozenVec { + /// Returns the number of elements in the vector. + pub fn len(&self) -> usize { + unsafe { + let vec = self.vec.get(); + (*vec).len() + } + } + + /// Returns `true` if the vector contains no elements. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl FrozenVec { + /// Returns the first element of the vector, or `None` if empty. + pub fn first(&self) -> Option<&T::Target> { + unsafe { + let vec = self.vec.get(); + (*vec).first().map(|x| &**x) + } + } + + /// Returns the last element of the vector, or `None` if empty. + pub fn last(&self) -> Option<&T::Target> { + unsafe { + let vec = self.vec.get(); + (*vec).last().map(|x| &**x) + } + } + /// Returns an iterator over the vector. + pub fn iter(&self) -> Iter { + self.into_iter() + } +} + +impl FrozenVec { + /// Converts the frozen vector into a plain vector. + pub fn into_vec(self) -> Vec { + self.vec.into_inner() + } +} + +impl FrozenVec { + // binary search functions: they need to be reimplemented here to be safe (instead of calling + // their equivalents directly on the underlying Vec), as they run user callbacks that could + // reentrantly call other functions on this vector + + /// Binary searches this sorted vector for a given element, analogous to [slice::binary_search]. + pub fn binary_search(&self, x: &T::Target) -> Result + where + T::Target: Ord, + { + self.binary_search_by(|p| p.cmp(x)) + } + + /// Binary searches this sorted vector with a comparator function, analogous to + /// [slice::binary_search_by]. + pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result + where + F: FnMut(&'a T::Target) -> Ordering, + { + let mut size = self.len(); + let mut left = 0; + let mut right = size; + while left < right { + let mid = left + size / 2; + + // safety: like the core algorithm, mid is always within original vector len; in + // pathlogical cases, user could push to the vector in the meantime, but this can only + // increase the length, keeping this safe + let cmp = f(unsafe { self.get_unchecked(mid) }); + + if cmp == Ordering::Less { + left = mid + 1; + } else if cmp == Ordering::Greater { + right = mid; + } else { + return Ok(mid); + } + + size = right - left; + } + Err(left) + } + + /// Binary searches this sorted vector with a key extraction function, analogous to + /// [slice::binary_search_by_key]. + pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result + where + F: FnMut(&'a T::Target) -> B, + B: Ord, + { + self.binary_search_by(|k| f(k).cmp(b)) + } + + /// Returns the index of the partition point according to the given predicate + /// (the index of the first element of the second partition), analogous to + /// [slice::partition_point]. + pub fn partition_point

(&self, mut pred: P) -> usize + where + P: FnMut(&T::Target) -> bool, + { + let mut left = 0; + let mut right = self.len(); + + while left != right { + let mid = left + (right - left) / 2; + // safety: like in binary_search_by + let value = unsafe { self.get_unchecked(mid) }; + if pred(value) { + left = mid + 1; + } else { + right = mid; + } + } + + left + } + + // TODO add more +} + +impl std::convert::AsMut> for FrozenVec { + /// Get mutable access to the underlying vector. + /// + /// This is safe, as it requires a `&mut self`, ensuring nothing is using + /// the 'frozen' contents. + fn as_mut(&mut self) -> &mut Vec { + unsafe { &mut *self.vec.get() } + } +} + +impl Default for FrozenVec { + fn default() -> Self { + FrozenVec::new() + } +} + +impl From> for FrozenVec { + fn from(vec: Vec) -> Self { + Self { + vec: UnsafeCell::new(vec), + } + } +} + +impl Index for FrozenVec { + type Output = T::Target; + fn index(&self, idx: usize) -> &T::Target { + self.get(idx).unwrap_or_else(|| { + panic!( + "index out of bounds: the len is {} but the index is {}", + self.len(), + idx + ) + }) + } +} + +impl FromIterator for FrozenVec { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + let vec: Vec<_> = iter.into_iter().collect(); + vec.into() + } +} + +/// Iterator over FrozenVec, obtained via `.iter()` +/// +/// It is safe to push to the vector during iteration +pub struct Iter<'a, T> { + vec: &'a FrozenVec, + idx: usize, +} + +impl<'a, T: StableDeref> Iterator for Iter<'a, T> { + type Item = &'a T::Target; + fn next(&mut self) -> Option<&'a T::Target> { + if let Some(ret) = self.vec.get(self.idx) { + self.idx += 1; + Some(ret) + } else { + None + } + } +} + +impl<'a, T: StableDeref> IntoIterator for &'a FrozenVec { + type Item = &'a T::Target; + type IntoIter = Iter<'a, T>; + fn into_iter(self) -> Iter<'a, T> { + Iter { vec: self, idx: 0 } + } +} + +#[test] +fn test_iteration() { + let vec = vec!["a", "b", "c", "d"]; + let frozen: FrozenVec<_> = vec.clone().into(); + + assert_eq!(vec, frozen.iter().collect::>()); + for (e1, e2) in vec.iter().zip(frozen.iter()) { + assert_eq!(*e1, e2); + } + + assert_eq!(vec.len(), frozen.iter().count()) +} + +#[test] +fn test_accessors() { + let vec: FrozenVec = FrozenVec::new(); + + assert_eq!(vec.is_empty(), true); + assert_eq!(vec.len(), 0); + assert_eq!(vec.first(), None); + assert_eq!(vec.last(), None); + assert_eq!(vec.get(1), None); + + vec.push("a".to_string()); + vec.push("b".to_string()); + vec.push("c".to_string()); + + assert_eq!(vec.is_empty(), false); + assert_eq!(vec.len(), 3); + assert_eq!(vec.first(), Some("a")); + assert_eq!(vec.last(), Some("c")); + assert_eq!(vec.get(1), Some("b")); +} + +#[test] +fn test_non_stable_deref() { + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + struct Moo(i32); + let vec: FrozenVec = FrozenVec::new(); + + assert_eq!(vec.is_empty(), true); + assert_eq!(vec.len(), 0); + assert_eq!(vec.get_copy(1), None); + + vec.push(Moo(1)); + vec.push(Moo(2)); + vec.push(Moo(3)); + + assert_eq!(vec.is_empty(), false); + assert_eq!(vec.len(), 3); + assert_eq!(vec.get_copy(1), Some(Moo(2))); +} + +#[test] +fn test_binary_search() { + let vec: FrozenVec<_> = vec!["ab", "cde", "fghij"].into(); + + assert_eq!(vec.binary_search("cde"), Ok(1)); + assert_eq!(vec.binary_search("cdf"), Err(2)); + assert_eq!(vec.binary_search("a"), Err(0)); + assert_eq!(vec.binary_search("g"), Err(3)); + + assert_eq!(vec.binary_search_by_key(&1, |x| x.len()), Err(0)); + assert_eq!(vec.binary_search_by_key(&3, |x| x.len()), Ok(1)); + assert_eq!(vec.binary_search_by_key(&4, |x| x.len()), Err(2)); + + assert_eq!(vec.partition_point(|x| x.len() < 4), 2); + assert_eq!(vec.partition_point(|_| false), 0); + assert_eq!(vec.partition_point(|_| true), 3); +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/.cargo-checksum.json b/utshell-0.5.0/vendor/fluent-bundle/.cargo-checksum.json new file mode 100644 index 00000000..5ad5a9d2 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"87a01e2e130c153cac13b916dba613ff4d9dde0795ebc607932d9ea9c960cf77","LICENSE-APACHE":"5db2b182453ff32ed40f7da63589c9667a3f8bd8b16b1471b152caae56f77e45","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"444c8934a3bbec88cbf5e41d7b5fcb2d1f9c7e2c69a906f6df5fe18171942157","benches/resolver.rs":"bd46c8b710ac1898a0e69324a7ecf9aa38d577337bc5855a07ca0ad1043603a1","benches/resolver_iai.rs":"e9e940f4c09908069d474d379a0230dfc6fa44325300d72975e8f1d9ef64f6f1","examples/README.md":"99a51f7d388d2da3c5291e68de5264feaf642ba9a22f6f882c3b940c1b6429b2","src/args.rs":"51346e9ec84f2eeb4462e0e993b1bbb307585a2a40e41f6d0d745889bca56a7d","src/bundle.rs":"3da63b685acf559ee80fa489885da126f7c68405026ac065a07e559e2186a77f","src/concurrent.rs":"be77275513918809b98c554b26a65c6a9cf2a7bf52db3bbaf21ebdd34d94c651","src/entry.rs":"e1507b0e4c3e6d0d2efc5d622f4156a5156b9eeb40d9c5353cb7fdc236c38189","src/errors.rs":"a357f3a09335d31e362aa99a8d82eab4e238fdec8498141990f61ede58f4dabb","src/lib.rs":"58a0c929322f83aac41280da035b50adbcdb05d8a8376359d58c177cd9755eab","src/memoizer.rs":"922084f71f02d0532056db9b41cec4c1434001fe60215ee6f6ac8e3fd2518f12","src/message.rs":"4a3c95d3ecd016aeaa5da07e99d78de62f13aac8aa447818aabd0f63f2d143c4","src/resolver/errors.rs":"beaf41fabbfd11211cb2c3db6ca0ba26bccf75817bed05a92b980393edfb3f9f","src/resolver/expression.rs":"f18413de1a6b3ba43c062e24d58a60d63f4dad66bcec67ed55756ff5014f9347","src/resolver/inline_expression.rs":"089ad6745d0790478ea698fd530f2236c550889f9be75e245ed94bba4b883884","src/resolver/mod.rs":"d1b15ce110ea49876909412c12c4c1841052bb80f4838a934dfccd6a5264855c","src/resolver/pattern.rs":"64162a7e2ad0df82d463d14ac6a472005bba4cef4a7e73fe2a9529e811124a85","src/resolver/scope.rs":"816f51146c38affea54c6e0911e3522f998485829e619cca5f72cec05180de59","src/resource.rs":"cd56a14c01da2a689a408f0e5edd789e8557ae9327fa79788bf4ddb9c83431c7","src/types/mod.rs":"1cd65301fb32233fd241a79c6fa873edcb40a271330601360f72e2c452900509","src/types/number.rs":"2d3b403e5f545e2f4a3a16aec0bb019a4cc8e5ac0ab2db5642ba8039fbe203a8","src/types/plural.rs":"f28834e71d6970d5eb48089132f5242433b1e62b90765d85e3c76f805eecc92e"},"package":"e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/fluent-bundle/Cargo.toml b/utshell-0.5.0/vendor/fluent-bundle/Cargo.toml new file mode 100644 index 00000000..6d36ec3a --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/Cargo.toml @@ -0,0 +1,78 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "fluent-bundle" +version = "0.15.2" +authors = ["Zibi Braniecki ", "Staś Małolepszy "] +include = ["src/**/*", "benches/*.rs", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +description = "A localization system designed to unleash the entire expressive power of\nnatural language translations.\n" +homepage = "http://www.projectfluent.org" +readme = "README.md" +keywords = ["localization", "l10n", "i18n", "intl", "internationalization"] +categories = ["localization", "internationalization"] +license = "Apache-2.0/MIT" +repository = "https://github.com/projectfluent/fluent-rs" + +[[bench]] +name = "resolver" +harness = false + +[[bench]] +name = "resolver_iai" +harness = false +[dependencies.fluent-langneg] +version = "0.13" + +[dependencies.fluent-syntax] +version = "0.11" + +[dependencies.intl-memoizer] +version = "0.5" + +[dependencies.intl_pluralrules] +version = "7.0.1" + +[dependencies.rustc-hash] +version = "1" + +[dependencies.self_cell] +version = "0.10" + +[dependencies.smallvec] +version = "1" + +[dependencies.unic-langid] +version = "0.9" +[dev-dependencies.criterion] +version = "0.3" + +[dev-dependencies.iai] +version = "0.1" + +[dev-dependencies.rand] +version = "0.8" + +[dev-dependencies.serde] +version = "1.0" +features = ["derive"] + +[dev-dependencies.serde_yaml] +version = "0.8" + +[dev-dependencies.unic-langid] +version = "0.9" +features = ["macros"] + +[features] +all-benchmarks = [] +default = [] diff --git a/utshell-0.5.0/vendor/fluent-bundle/LICENSE-APACHE b/utshell-0.5.0/vendor/fluent-bundle/LICENSE-APACHE new file mode 100644 index 00000000..35582f16 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Mozilla + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/fluent-bundle/LICENSE-MIT b/utshell-0.5.0/vendor/fluent-bundle/LICENSE-MIT new file mode 100644 index 00000000..5655fa31 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright 2017 Mozilla + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/utshell-0.5.0/vendor/fluent-bundle/README.md b/utshell-0.5.0/vendor/fluent-bundle/README.md new file mode 100644 index 00000000..c8e1b112 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/README.md @@ -0,0 +1,111 @@ +# Fluent + +`fluent-rs` is a Rust implementation of [Project Fluent][], a localization +framework designed to unleash the entire expressive power of natural language +translations. + +[![crates.io](https://img.shields.io/crates/v/fluent-bundle.svg)](https://crates.io/crates/fluent-bundle) +[![Build and test](https://github.com/projectfluent/fluent-rs/workflows/Build%20and%20test/badge.svg)](https://github.com/projectfluent/fluent-rs/actions?query=branch%3Amaster+workflow%3A%22Build+and+test%22) +[![Coverage Status](https://coveralls.io/repos/github/projectfluent/fluent-rs/badge.svg?branch=master)](https://coveralls.io/github/projectfluent/fluent-rs?branch=master) + +Project Fluent keeps simple things simple and makes complex things possible. +The syntax used for describing translations is easy to read and understand. At +the same time it allows, when necessary, to represent complex concepts from +natural languages like gender, plurals, conjugations, and others. + +[Documentation][] + +[Project Fluent]: http://projectfluent.org +[Documentation]: https://docs.rs/fluent/ + +Usage +----- + +```rust +use fluent_bundle::{FluentBundle, FluentResource}; +use unic_langid::langid; + +fn main() { + let ftl_string = "hello-world = Hello, world!".to_owned(); + let res = FluentResource::try_new(ftl_string) + .expect("Could not parse an FTL string."); + + let langid_en = langid!("en"); + let mut bundle = FluentBundle::new(vec![langid_en]); + + bundle.add_resource(&res) + .expect("Failed to add FTL resources to the bundle."); + + let msg = bundle.get_message("hello-world") + .expect("Failed to retrieve a message."); + let val = msg.value.expect("Message has no value."); + + let mut errors = vec![]; + let value = bundle.format_pattern(val, None, &mut errors); + + assert_eq!(&value, "Hello, world!"); +} +``` + + +Status +------ + +The implementation is in its early stages and supports only some of the Project +Fluent's spec. Consult the [list of milestones][] for more information about +release planning and scope. + +[list of milestones]: https://github.com/projectfluent/fluent-rs/milestones + + +Local Development +----------------- + + cargo build + cargo test + cargo bench + cargo run --example simple-app + +When submitting a PR please use [`cargo fmt`][] (nightly). + +[`cargo fmt`]: https://github.com/rust-lang-nursery/rustfmt + + +Learn the FTL syntax +-------------------- + +FTL is a localization file format used for describing translation resources. +FTL stands for _Fluent Translation List_. + +FTL is designed to be simple to read, but at the same time allows to represent +complex concepts from natural languages like gender, plurals, conjugations, and +others. + + hello-user = Hello, { $username }! + +[Read the Fluent Syntax Guide][] in order to learn more about the syntax. If +you're a tool author you may be interested in the formal [EBNF grammar][]. + +[Read the Fluent Syntax Guide]: http://projectfluent.org/fluent/guide/ +[EBNF grammar]: https://github.com/projectfluent/fluent/tree/master/spec + + +Get Involved +------------ + +`fluent-rs` is open-source, licensed under the Apache License, Version 2.0. We +encourage everyone to take a look at our code and we'll listen to your +feedback. + + +Discuss +------- + +We'd love to hear your thoughts on Project Fluent! Whether you're a localizer +looking for a better way to express yourself in your language, or a developer +trying to make your app localizable and multilingual, or a hacker looking for +a project to contribute to, please do get in touch on the mailing list and the +IRC channel. + + - Discourse: https://discourse.mozilla.org/c/fluent + - IRC channel: [irc://irc.mozilla.org/l20n](irc://irc.mozilla.org/l20n) diff --git a/utshell-0.5.0/vendor/fluent-bundle/benches/resolver.rs b/utshell-0.5.0/vendor/fluent-bundle/benches/resolver.rs new file mode 100644 index 00000000..2116d1b9 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/benches/resolver.rs @@ -0,0 +1,168 @@ +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::BenchmarkId; +use criterion::Criterion; +use std::collections::HashMap; +use std::fs::File; +use std::io; +use std::io::Read; +use std::rc::Rc; + +use fluent_bundle::{FluentArgs, FluentBundle, FluentResource, FluentValue}; +use fluent_syntax::ast; +use unic_langid::langid; + +fn read_file(path: &str) -> Result { + let mut f = File::open(path)?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + Ok(s) +} + +fn get_strings(tests: &[&'static str]) -> HashMap<&'static str, String> { + let mut ftl_strings = HashMap::new(); + for test in tests { + let path = format!("./benches/{}.ftl", test); + ftl_strings.insert(*test, read_file(&path).expect("Couldn't load file")); + } + return ftl_strings; +} + +fn get_ids(res: &FluentResource) -> Vec { + res.entries() + .filter_map(|entry| match entry { + ast::Entry::Message(ast::Message { id, .. }) => Some(id.name.to_owned()), + _ => None, + }) + .collect() +} + +fn get_args(name: &str) -> Option { + match name { + "preferences" => { + let mut prefs_args = FluentArgs::new(); + prefs_args.set("name", FluentValue::from("John")); + prefs_args.set("tabCount", FluentValue::from(5)); + prefs_args.set("count", FluentValue::from(3)); + prefs_args.set("version", FluentValue::from("65.0")); + prefs_args.set("path", FluentValue::from("/tmp")); + prefs_args.set("num", FluentValue::from(4)); + prefs_args.set("email", FluentValue::from("john@doe.com")); + prefs_args.set("value", FluentValue::from(4.5)); + prefs_args.set("unit", FluentValue::from("mb")); + prefs_args.set("service-name", FluentValue::from("Mozilla Disk")); + Some(prefs_args) + } + _ => None, + } +} + +fn add_functions(name: &'static str, bundle: &mut FluentBundle) { + match name { + "preferences" => { + bundle + .add_function("PLATFORM", |_args, _named_args| { + return "linux".into(); + }) + .expect("Failed to add a function to the bundle."); + } + _ => {} + } +} + +fn get_bundle(name: &'static str, source: &str) -> (FluentBundle, Vec) { + let res = FluentResource::try_new(source.to_owned()).expect("Couldn't parse an FTL source"); + let ids = get_ids(&res); + let lids = vec![langid!("en")]; + let mut bundle = FluentBundle::new(lids); + bundle + .add_resource(res) + .expect("Couldn't add FluentResource to the FluentBundle"); + add_functions(name, &mut bundle); + (bundle, ids) +} + +fn resolver_bench(c: &mut Criterion) { + let tests = &[ + #[cfg(feature = "all-benchmarks")] + "simple", + "preferences", + #[cfg(feature = "all-benchmarks")] + "menubar", + #[cfg(feature = "all-benchmarks")] + "unescape", + ]; + let ftl_strings = get_strings(tests); + + let mut group = c.benchmark_group("construct"); + for name in tests { + let source = ftl_strings.get(name).expect("Failed to find the source."); + group.bench_with_input(BenchmarkId::from_parameter(name), &source, |b, source| { + let res = Rc::new( + FluentResource::try_new(source.to_string()).expect("Couldn't parse an FTL source"), + ); + b.iter(|| { + let lids = vec![langid!("en")]; + let mut bundle = FluentBundle::new(lids); + bundle + .add_resource(res.clone()) + .expect("Couldn't add FluentResource to the FluentBundle"); + add_functions(name, &mut bundle); + }) + }); + } + group.finish(); + + let mut group = c.benchmark_group("resolve"); + for name in tests { + let source = ftl_strings.get(name).expect("Failed to find the source."); + group.bench_with_input(BenchmarkId::from_parameter(name), &source, |b, source| { + let (bundle, ids) = get_bundle(name, source); + let args = get_args(name); + b.iter(|| { + let mut s = String::new(); + for id in &ids { + let msg = bundle.get_message(id).expect("Message found"); + let mut errors = vec![]; + if let Some(value) = msg.value() { + let _ = bundle.write_pattern(&mut s, value, args.as_ref(), &mut errors); + s.clear(); + } + for attr in msg.attributes() { + let _ = + bundle.write_pattern(&mut s, attr.value(), args.as_ref(), &mut errors); + s.clear(); + } + assert!(errors.len() == 0, "Resolver errors: {:#?}", errors); + } + }) + }); + } + group.finish(); + + let mut group = c.benchmark_group("resolve_to_str"); + for name in tests { + let source = ftl_strings.get(name).expect("Failed to find the source."); + group.bench_with_input(BenchmarkId::from_parameter(name), &source, |b, source| { + let (bundle, ids) = get_bundle(name, source); + let args = get_args(name); + b.iter(|| { + for id in &ids { + let msg = bundle.get_message(id).expect("Message found"); + let mut errors = vec![]; + if let Some(value) = msg.value() { + let _ = bundle.format_pattern(value, args.as_ref(), &mut errors); + } + for attr in msg.attributes() { + let _ = bundle.format_pattern(attr.value(), args.as_ref(), &mut errors); + } + assert!(errors.len() == 0, "Resolver errors: {:#?}", errors); + } + }) + }); + } + group.finish(); +} + +criterion_group!(benches, resolver_bench); +criterion_main!(benches); diff --git a/utshell-0.5.0/vendor/fluent-bundle/benches/resolver_iai.rs b/utshell-0.5.0/vendor/fluent-bundle/benches/resolver_iai.rs new file mode 100644 index 00000000..10212f6f --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/benches/resolver_iai.rs @@ -0,0 +1,79 @@ +use fluent_bundle::{FluentArgs, FluentBundle, FluentResource, FluentValue}; +use fluent_syntax::ast; +use unic_langid::{langid, LanguageIdentifier}; + +const LANG_EN: LanguageIdentifier = langid!("en"); + +fn add_functions(name: &'static str, bundle: &mut FluentBundle) { + match name { + "preferences" => { + bundle + .add_function("PLATFORM", |_args, _named_args| { + return "linux".into(); + }) + .expect("Failed to add a function to the bundle."); + } + _ => {} + } +} + +fn get_args(name: &str) -> Option { + match name { + "preferences" => { + let mut prefs_args = FluentArgs::new(); + prefs_args.set("name", FluentValue::from("John")); + prefs_args.set("tabCount", FluentValue::from(5)); + prefs_args.set("count", FluentValue::from(3)); + prefs_args.set("version", FluentValue::from("65.0")); + prefs_args.set("path", FluentValue::from("/tmp")); + prefs_args.set("num", FluentValue::from(4)); + prefs_args.set("email", FluentValue::from("john@doe.com")); + prefs_args.set("value", FluentValue::from(4.5)); + prefs_args.set("unit", FluentValue::from("mb")); + prefs_args.set("service-name", FluentValue::from("Mozilla Disk")); + Some(prefs_args) + } + _ => None, + } +} + +fn get_ids(res: &FluentResource) -> Vec { + res.entries() + .filter_map(|entry| match entry { + ast::Entry::Message(ast::Message { id, .. }) => Some(id.name.to_owned()), + _ => None, + }) + .collect() +} + +fn iai_resolve_preferences() { + let files = &[include_str!("preferences.ftl")]; + for source in files { + let res = FluentResource::try_new(source.to_string()).expect("failed to parse FTL."); + let ids = get_ids(&res); + let mut bundle = FluentBundle::new(vec![LANG_EN]); + bundle.add_resource(res).expect("Failed to add a resource."); + add_functions("preferences", &mut bundle); + let args = get_args("preferences"); + let mut s = String::new(); + for id in &ids { + let msg = bundle.get_message(id).expect("Message found"); + let mut errors = vec![]; + if let Some(value) = msg.value() { + bundle + .write_pattern(&mut s, value, args.as_ref(), &mut errors) + .expect("Failed to write a pattern."); + s.clear(); + } + for attr in msg.attributes() { + bundle + .write_pattern(&mut s, attr.value(), args.as_ref(), &mut errors) + .expect("Failed to write a pattern."); + s.clear(); + } + assert!(errors.len() == 0, "Resolver errors: {:#?}", errors); + } + } +} + +iai::main!(iai_resolve_preferences); diff --git a/utshell-0.5.0/vendor/fluent-bundle/examples/README.md b/utshell-0.5.0/vendor/fluent-bundle/examples/README.md new file mode 100644 index 00000000..2411aeb9 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/examples/README.md @@ -0,0 +1,6 @@ +This directory contains a set of examples +of how to use Fluent. + +Start with the `simple-app.rs` which is a very +trivial example of a command line application +with localization handled by Fluent. diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/args.rs b/utshell-0.5.0/vendor/fluent-bundle/src/args.rs new file mode 100644 index 00000000..b2d17a84 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/args.rs @@ -0,0 +1,120 @@ +use std::borrow::Cow; +use std::iter::FromIterator; + +use crate::types::FluentValue; + +/// A map of arguments passed from the code to +/// the localization to be used for message +/// formatting. +/// +/// # Example +/// +/// ``` +/// use fluent_bundle::{FluentArgs, FluentBundle, FluentResource}; +/// +/// let mut args = FluentArgs::new(); +/// args.set("user", "John"); +/// args.set("emailCount", 5); +/// +/// let res = FluentResource::try_new(r#" +/// +/// msg-key = Hello, { $user }. You have { $emailCount } messages. +/// +/// "#.to_string()) +/// .expect("Failed to parse FTL."); +/// +/// let mut bundle = FluentBundle::default(); +/// +/// // For this example, we'll turn on BiDi support. +/// // Please, be careful when doing it, it's a risky move. +/// bundle.set_use_isolating(false); +/// +/// bundle.add_resource(res) +/// .expect("Failed to add a resource."); +/// +/// let mut err = vec![]; +/// +/// let msg = bundle.get_message("msg-key") +/// .expect("Failed to retrieve a message."); +/// let value = msg.value() +/// .expect("Failed to retrieve a value."); +/// +/// assert_eq!( +/// bundle.format_pattern(value, Some(&args), &mut err), +/// "Hello, John. You have 5 messages." +/// ); +/// ``` +#[derive(Debug, Default)] +pub struct FluentArgs<'args>(Vec<(Cow<'args, str>, FluentValue<'args>)>); + +impl<'args> FluentArgs<'args> { + pub fn new() -> Self { + Self::default() + } + + pub fn with_capacity(capacity: usize) -> Self { + Self(Vec::with_capacity(capacity)) + } + + pub fn get(&self, key: K) -> Option<&FluentValue<'args>> + where + K: Into>, + { + let key = key.into(); + if let Ok(idx) = self.0.binary_search_by_key(&&key, |(k, _)| k) { + Some(&self.0[idx].1) + } else { + None + } + } + + pub fn set(&mut self, key: K, value: V) + where + K: Into>, + V: Into>, + { + let key = key.into(); + let idx = match self.0.binary_search_by_key(&&key, |(k, _)| k) { + Ok(idx) => idx, + Err(idx) => idx, + }; + self.0.insert(idx, (key, value.into())); + } + + pub fn iter(&self) -> impl Iterator { + self.0.iter().map(|(k, v)| (k.as_ref(), v)) + } +} + +impl<'args, K, V> FromIterator<(K, V)> for FluentArgs<'args> +where + K: Into>, + V: Into>, +{ + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + let iter = iter.into_iter(); + let mut args = if let Some(size) = iter.size_hint().1 { + FluentArgs::with_capacity(size) + } else { + FluentArgs::new() + }; + + for (k, v) in iter { + args.set(k, v); + } + + args + } +} + +impl<'args> IntoIterator for FluentArgs<'args> { + type Item = (Cow<'args, str>, FluentValue<'args>); + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/bundle.rs b/utshell-0.5.0/vendor/fluent-bundle/src/bundle.rs new file mode 100644 index 00000000..3d085cfe --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/bundle.rs @@ -0,0 +1,615 @@ +//! `FluentBundle` is a collection of localization messages in Fluent. +//! +//! It stores a list of messages in a single locale which can reference one another, use the same +//! internationalization formatters, functions, scopeironmental variables and are expected to be used +//! together. + +use rustc_hash::FxHashMap; +use std::borrow::Borrow; +use std::borrow::Cow; +use std::collections::hash_map::Entry as HashEntry; +use std::default::Default; +use std::fmt; + +use fluent_syntax::ast; +use intl_memoizer::IntlLangMemoizer; +use unic_langid::LanguageIdentifier; + +use crate::args::FluentArgs; +use crate::entry::Entry; +use crate::entry::GetEntry; +use crate::errors::{EntryKind, FluentError}; +use crate::memoizer::MemoizerKind; +use crate::message::FluentMessage; +use crate::resolver::{ResolveValue, Scope, WriteValue}; +use crate::resource::FluentResource; +use crate::types::FluentValue; + +/// A collection of localization messages for a single locale, which are meant +/// to be used together in a single view, widget or any other UI abstraction. +/// +/// # Examples +/// +/// ``` +/// use fluent_bundle::{FluentBundle, FluentResource, FluentValue, FluentArgs}; +/// use unic_langid::langid; +/// +/// // 1. Create a FluentResource +/// +/// let ftl_string = String::from("intro = Welcome, { $name }."); +/// let resource = FluentResource::try_new(ftl_string) +/// .expect("Could not parse an FTL string."); +/// +/// +/// // 2. Create a FluentBundle +/// +/// let langid_en = langid!("en-US"); +/// let mut bundle = FluentBundle::new(vec![langid_en]); +/// +/// +/// // 3. Add the resource to the bundle +/// +/// bundle.add_resource(&resource) +/// .expect("Failed to add FTL resources to the bundle."); +/// +/// +/// // 4. Retrieve a FluentMessage from the bundle +/// +/// let msg = bundle.get_message("intro") +/// .expect("Message doesn't exist."); +/// +/// let mut args = FluentArgs::new(); +/// args.set("name", "Rustacean"); +/// +/// +/// // 5. Format the value of the message +/// +/// let mut errors = vec![]; +/// +/// let pattern = msg.value() +/// .expect("Message has no value."); +/// +/// assert_eq!( +/// bundle.format_pattern(&pattern, Some(&args), &mut errors), +/// // The placeholder is wrapper in Unicode Directionality Marks +/// // to indicate that the placeholder may be of different direction +/// // than surrounding string. +/// "Welcome, \u{2068}Rustacean\u{2069}." +/// ); +/// +/// ``` +/// +/// # `FluentBundle` Life Cycle +/// +/// ## Create a bundle +/// +/// To create a bundle, call [`FluentBundle::new`] with a locale list that represents the best +/// possible fallback chain for a given locale. The simplest case is a one-locale list. +/// +/// Fluent uses [`LanguageIdentifier`] which can be created using `langid!` macro. +/// +/// ## Add Resources +/// +/// Next, call [`add_resource`](FluentBundle::add_resource) one or more times, supplying translations in the FTL syntax. +/// +/// Since [`FluentBundle`] is generic over anything that can borrow a [`FluentResource`], +/// one can use [`FluentBundle`] to own its resources, store references to them, +/// or even [`Rc`](std::rc::Rc) or [`Arc`](std::sync::Arc). +/// +/// The [`FluentBundle`] instance is now ready to be used for localization. +/// +/// ## Format +/// +/// To format a translation, call [`get_message`](FluentBundle::get_message) to retrieve a [`FluentMessage`], +/// and then call [`format_pattern`](FluentBundle::format_pattern) on the message value or attribute in order to +/// retrieve the translated string. +/// +/// The result of [`format_pattern`](FluentBundle::format_pattern) is an +/// [`Cow`](std::borrow::Cow). It is +/// recommended to treat the result as opaque from the perspective of the program and use it only +/// to display localized messages. Do not examine it or alter in any way before displaying. This +/// is a general good practice as far as all internationalization operations are concerned. +/// +/// If errors were encountered during formatting, they will be +/// accumulated in the [`Vec`](FluentError) passed as the third argument. +/// +/// While they are not fatal, they usually indicate problems with the translation, +/// and should be logged or reported in a way that allows the developer to notice +/// and fix them. +/// +/// +/// # Locale Fallback Chain +/// +/// [`FluentBundle`] stores messages in a single locale, but keeps a locale fallback chain for the +/// purpose of language negotiation with i18n formatters. For instance, if date and time formatting +/// are not available in the first locale, [`FluentBundle`] will use its `locales` fallback chain +/// to negotiate a sensible fallback for date and time formatting. +/// +/// # Concurrency +/// +/// As you may have noticed, [`fluent_bundle::FluentBundle`](crate::FluentBundle) is a specialization of [`fluent_bundle::bundle::FluentBundle`](crate::bundle::FluentBundle) +/// which works with an [`IntlLangMemoizer`] over [`RefCell`](std::cell::RefCell). +/// In scenarios where the memoizer must work concurrently, there's an implementation of +/// [`IntlLangMemoizer`](intl_memoizer::concurrent::IntlLangMemoizer) that uses [`Mutex`](std::sync::Mutex) and there's [`FluentBundle::new_concurrent`] which works with that. +pub struct FluentBundle { + pub locales: Vec, + pub(crate) resources: Vec, + pub(crate) entries: FxHashMap, + pub(crate) intls: M, + pub(crate) use_isolating: bool, + pub(crate) transform: Option Cow>, + pub(crate) formatter: Option Option>, +} + +impl FluentBundle { + /// Adds a resource to the bundle, returning an empty [`Result`] on success. + /// + /// If any entry in the resource uses the same identifier as an already + /// existing key in the bundle, the new entry will be ignored and a + /// `FluentError::Overriding` will be added to the result. + /// + /// The method can take any type that can be borrowed to `FluentResource`: + /// - FluentResource + /// - &FluentResource + /// - Rc + /// - Arc + /// + /// This allows the user to introduce custom resource management and share + /// resources between instances of `FluentBundle`. + /// + /// # Examples + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from(" + /// hello = Hi! + /// goodbye = Bye! + /// "); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Could not parse an FTL string."); + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// bundle.add_resource(resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// assert_eq!(true, bundle.has_message("hello")); + /// ``` + /// + /// # Whitespace + /// + /// Message ids must have no leading whitespace. Message values that span + /// multiple lines must have leading whitespace on all but the first line. These + /// are standard FTL syntax rules that may prove a bit troublesome in source + /// code formatting. The [`indoc!`] crate can help with stripping extra indentation + /// if you wish to indent your entire message. + /// + /// [FTL syntax]: https://projectfluent.org/fluent/guide/ + /// [`indoc!`]: https://github.com/dtolnay/indoc + /// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html + pub fn add_resource(&mut self, r: R) -> Result<(), Vec> + where + R: Borrow, + { + let mut errors = vec![]; + + let res = r.borrow(); + let res_pos = self.resources.len(); + + for (entry_pos, entry) in res.entries().enumerate() { + let (id, entry) = match entry { + ast::Entry::Message(ast::Message { ref id, .. }) => { + (id.name, Entry::Message((res_pos, entry_pos))) + } + ast::Entry::Term(ast::Term { ref id, .. }) => { + (id.name, Entry::Term((res_pos, entry_pos))) + } + _ => continue, + }; + + match self.entries.entry(id.to_string()) { + HashEntry::Vacant(empty) => { + empty.insert(entry); + } + HashEntry::Occupied(_) => { + let kind = match entry { + Entry::Message(..) => EntryKind::Message, + Entry::Term(..) => EntryKind::Term, + _ => unreachable!(), + }; + errors.push(FluentError::Overriding { + kind, + id: id.to_string(), + }); + } + } + } + self.resources.push(r); + + if errors.is_empty() { + Ok(()) + } else { + Err(errors) + } + } + + /// Adds a resource to the bundle, returning an empty [`Result`] on success. + /// + /// If any entry in the resource uses the same identifier as an already + /// existing key in the bundle, the entry will override the previous one. + /// + /// The method can take any type that can be borrowed as FluentResource: + /// - FluentResource + /// - &FluentResource + /// - Rc + /// - Arc + /// + /// This allows the user to introduce custom resource management and share + /// resources between instances of `FluentBundle`. + /// + /// # Examples + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from(" + /// hello = Hi! + /// goodbye = Bye! + /// "); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Could not parse an FTL string."); + /// + /// let ftl_string = String::from(" + /// hello = Another Hi! + /// "); + /// let resource2 = FluentResource::try_new(ftl_string) + /// .expect("Could not parse an FTL string."); + /// + /// let langid_en = langid!("en-US"); + /// + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// bundle.add_resource(resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// + /// bundle.add_resource_overriding(resource2); + /// + /// let mut errors = vec![]; + /// let msg = bundle.get_message("hello") + /// .expect("Failed to retrieve the message"); + /// let value = msg.value().expect("Failed to retrieve the value of the message"); + /// assert_eq!(bundle.format_pattern(value, None, &mut errors), "Another Hi!"); + /// ``` + /// + /// # Whitespace + /// + /// Message ids must have no leading whitespace. Message values that span + /// multiple lines must have leading whitespace on all but the first line. These + /// are standard FTL syntax rules that may prove a bit troublesome in source + /// code formatting. The [`indoc!`] crate can help with stripping extra indentation + /// if you wish to indent your entire message. + /// + /// [FTL syntax]: https://projectfluent.org/fluent/guide/ + /// [`indoc!`]: https://github.com/dtolnay/indoc + /// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html + pub fn add_resource_overriding(&mut self, r: R) + where + R: Borrow, + { + let res = r.borrow(); + let res_pos = self.resources.len(); + + for (entry_pos, entry) in res.entries().enumerate() { + let (id, entry) = match entry { + ast::Entry::Message(ast::Message { ref id, .. }) => { + (id.name, Entry::Message((res_pos, entry_pos))) + } + ast::Entry::Term(ast::Term { ref id, .. }) => { + (id.name, Entry::Term((res_pos, entry_pos))) + } + _ => continue, + }; + + self.entries.insert(id.to_string(), entry); + } + self.resources.push(r); + } + + /// When formatting patterns, `FluentBundle` inserts + /// Unicode Directionality Isolation Marks to indicate + /// that the direction of a placeable may differ from + /// the surrounding message. + /// + /// This is important for cases such as when a + /// right-to-left user name is presented in the + /// left-to-right message. + /// + /// In some cases, such as testing, the user may want + /// to disable the isolating. + pub fn set_use_isolating(&mut self, value: bool) { + self.use_isolating = value; + } + + /// This method allows to specify a function that will + /// be called on all textual fragments of the pattern + /// during formatting. + /// + /// This is currently primarly used for pseudolocalization, + /// and `fluent-pseudo` crate provides a function + /// that can be passed here. + pub fn set_transform(&mut self, func: Option Cow>) { + self.transform = func; + } + + /// This method allows to specify a function that will + /// be called before any `FluentValue` is formatted + /// allowing overrides. + /// + /// It's particularly useful for plugging in an external + /// formatter for `FluentValue::Number`. + pub fn set_formatter(&mut self, func: Option Option>) { + self.formatter = func; + } + + /// Returns true if this bundle contains a message with the given id. + /// + /// # Examples + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from("hello = Hi!"); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Failed to parse an FTL string."); + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// bundle.add_resource(&resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// assert_eq!(true, bundle.has_message("hello")); + /// + /// ``` + pub fn has_message(&self, id: &str) -> bool + where + R: Borrow, + { + self.get_entry_message(id).is_some() + } + + /// Retrieves a `FluentMessage` from a bundle. + /// + /// # Examples + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from("hello-world = Hello World!"); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Failed to parse an FTL string."); + /// + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// + /// bundle.add_resource(&resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// + /// let msg = bundle.get_message("hello-world"); + /// assert_eq!(msg.is_some(), true); + /// ``` + pub fn get_message<'l>(&'l self, id: &str) -> Option> + where + R: Borrow, + { + self.get_entry_message(id).map(Into::into) + } + + /// Writes a formatted pattern which comes from a `FluentMessage`. + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from("hello-world = Hello World!"); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Failed to parse an FTL string."); + /// + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// + /// bundle.add_resource(&resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// + /// let msg = bundle.get_message("hello-world") + /// .expect("Failed to retrieve a FluentMessage."); + /// + /// let pattern = msg.value() + /// .expect("Missing Value."); + /// let mut errors = vec![]; + /// + /// let mut s = String::new(); + /// bundle.write_pattern(&mut s, &pattern, None, &mut errors) + /// .expect("Failed to write."); + /// + /// assert_eq!(s, "Hello World!"); + /// ``` + pub fn write_pattern<'bundle, W>( + &'bundle self, + w: &mut W, + pattern: &'bundle ast::Pattern<&str>, + args: Option<&'bundle FluentArgs>, + errors: &mut Vec, + ) -> fmt::Result + where + R: Borrow, + W: fmt::Write, + M: MemoizerKind, + { + let mut scope = Scope::new(self, args, Some(errors)); + pattern.write(w, &mut scope) + } + + /// Formats a pattern which comes from a `FluentMessage`. + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from("hello-world = Hello World!"); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Failed to parse an FTL string."); + /// + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// + /// bundle.add_resource(&resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// + /// let msg = bundle.get_message("hello-world") + /// .expect("Failed to retrieve a FluentMessage."); + /// + /// let pattern = msg.value() + /// .expect("Missing Value."); + /// let mut errors = vec![]; + /// + /// let result = bundle.format_pattern(&pattern, None, &mut errors); + /// + /// assert_eq!(result, "Hello World!"); + /// ``` + pub fn format_pattern<'bundle>( + &'bundle self, + pattern: &'bundle ast::Pattern<&str>, + args: Option<&'bundle FluentArgs>, + errors: &mut Vec, + ) -> Cow<'bundle, str> + where + R: Borrow, + M: MemoizerKind, + { + let mut scope = Scope::new(self, args, Some(errors)); + let value = pattern.resolve(&mut scope); + value.as_string(&scope) + } + + /// Makes the provided rust function available to messages with the name `id`. See + /// the [FTL syntax guide] to learn how these are used in messages. + /// + /// FTL functions accept both positional and named args. The rust function you + /// provide therefore has two parameters: a slice of values for the positional + /// args, and a `FluentArgs` for named args. + /// + /// # Examples + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource, FluentValue}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from("length = { STRLEN(\"12345\") }"); + /// let resource = FluentResource::try_new(ftl_string) + /// .expect("Could not parse an FTL string."); + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// bundle.add_resource(&resource) + /// .expect("Failed to add FTL resources to the bundle."); + /// + /// // Register a fn that maps from string to string length + /// bundle.add_function("STRLEN", |positional, _named| match positional { + /// [FluentValue::String(str)] => str.len().into(), + /// _ => FluentValue::Error, + /// }).expect("Failed to add a function to the bundle."); + /// + /// let msg = bundle.get_message("length").expect("Message doesn't exist."); + /// let mut errors = vec![]; + /// let pattern = msg.value().expect("Message has no value."); + /// let value = bundle.format_pattern(&pattern, None, &mut errors); + /// assert_eq!(&value, "5"); + /// ``` + /// + /// [FTL syntax guide]: https://projectfluent.org/fluent/guide/functions.html + pub fn add_function(&mut self, id: &str, func: F) -> Result<(), FluentError> + where + F: for<'a> Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Sync + Send + 'static, + { + match self.entries.entry(id.to_owned()) { + HashEntry::Vacant(entry) => { + entry.insert(Entry::Function(Box::new(func))); + Ok(()) + } + HashEntry::Occupied(_) => Err(FluentError::Overriding { + kind: EntryKind::Function, + id: id.to_owned(), + }), + } + } +} + +impl Default for FluentBundle { + fn default() -> Self { + Self::new(vec![LanguageIdentifier::default()]) + } +} + +impl FluentBundle { + /// Constructs a FluentBundle. The first element in `locales` should be the + /// language this bundle represents, and will be used to determine the + /// correct plural rules for this bundle. You can optionally provide extra + /// languages in the list; they will be used as fallback date and time + /// formatters if a formatter for the primary language is unavailable. + /// + /// # Examples + /// + /// ``` + /// use fluent_bundle::FluentBundle; + /// use fluent_bundle::FluentResource; + /// use unic_langid::langid; + /// + /// let langid_en = langid!("en-US"); + /// let mut bundle: FluentBundle = FluentBundle::new(vec![langid_en]); + /// ``` + /// + /// # Errors + /// + /// This will panic if no formatters can be found for the locales. + pub fn new(locales: Vec) -> Self { + let first_locale = locales.get(0).cloned().unwrap_or_default(); + Self { + locales, + resources: vec![], + entries: FxHashMap::default(), + intls: IntlLangMemoizer::new(first_locale), + use_isolating: true, + transform: None, + formatter: None, + } + } +} + +impl crate::memoizer::MemoizerKind for IntlLangMemoizer { + fn new(lang: LanguageIdentifier) -> Self + where + Self: Sized, + { + Self::new(lang) + } + + fn with_try_get_threadsafe(&self, args: I::Args, cb: U) -> Result + where + Self: Sized, + I: intl_memoizer::Memoizable + Send + Sync + 'static, + I::Args: Send + Sync + 'static, + U: FnOnce(&I) -> R, + { + self.with_try_get(args, cb) + } + + fn stringify_value( + &self, + value: &dyn crate::types::FluentType, + ) -> std::borrow::Cow<'static, str> { + value.as_string(self) + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/concurrent.rs b/utshell-0.5.0/vendor/fluent-bundle/src/concurrent.rs new file mode 100644 index 00000000..b87225ef --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/concurrent.rs @@ -0,0 +1,59 @@ +use intl_memoizer::{concurrent::IntlLangMemoizer, Memoizable}; +use rustc_hash::FxHashMap; +use unic_langid::LanguageIdentifier; + +use crate::bundle::FluentBundle; +use crate::memoizer::MemoizerKind; +use crate::types::FluentType; + +impl FluentBundle { + /// A constructor analogous to [`FluentBundle::new`] but operating + /// on a concurrent version of [`IntlLangMemoizer`] over [`Mutex`](std::sync::Mutex). + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::bundle::FluentBundle; + /// use fluent_bundle::FluentResource; + /// use unic_langid::langid; + /// + /// let langid_en = langid!("en-US"); + /// let mut bundle: FluentBundle = + /// FluentBundle::new_concurrent(vec![langid_en]); + /// ``` + pub fn new_concurrent(locales: Vec) -> Self { + let first_locale = locales.get(0).cloned().unwrap_or_default(); + Self { + locales, + resources: vec![], + entries: FxHashMap::default(), + intls: IntlLangMemoizer::new(first_locale), + use_isolating: true, + transform: None, + formatter: None, + } + } +} + +impl MemoizerKind for IntlLangMemoizer { + fn new(lang: LanguageIdentifier) -> Self + where + Self: Sized, + { + Self::new(lang) + } + + fn with_try_get_threadsafe(&self, args: I::Args, cb: U) -> Result + where + Self: Sized, + I: Memoizable + Send + Sync + 'static, + I::Args: Send + Sync + 'static, + U: FnOnce(&I) -> R, + { + self.with_try_get(args, cb) + } + + fn stringify_value(&self, value: &dyn FluentType) -> std::borrow::Cow<'static, str> { + value.as_string_threadsafe(self) + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/entry.rs b/utshell-0.5.0/vendor/fluent-bundle/src/entry.rs new file mode 100644 index 00000000..1ac8ecf0 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/entry.rs @@ -0,0 +1,62 @@ +//! `Entry` is used to store Messages, Terms and Functions in `FluentBundle` instances. + +use std::borrow::Borrow; + +use fluent_syntax::ast; + +use crate::args::FluentArgs; +use crate::bundle::FluentBundle; +use crate::resource::FluentResource; +use crate::types::FluentValue; + +pub type FluentFunction = + Box Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Send + Sync>; + +pub enum Entry { + Message((usize, usize)), + Term((usize, usize)), + Function(FluentFunction), +} + +pub trait GetEntry { + fn get_entry_message(&self, id: &str) -> Option<&ast::Message<&str>>; + fn get_entry_term(&self, id: &str) -> Option<&ast::Term<&str>>; + fn get_entry_function(&self, id: &str) -> Option<&FluentFunction>; +} + +impl<'bundle, R: Borrow, M> GetEntry for FluentBundle { + fn get_entry_message(&self, id: &str) -> Option<&ast::Message<&str>> { + self.entries.get(id).and_then(|ref entry| match entry { + Entry::Message(pos) => { + let res = self.resources.get(pos.0)?.borrow(); + if let ast::Entry::Message(ref msg) = res.get_entry(pos.1)? { + Some(msg) + } else { + None + } + } + _ => None, + }) + } + + fn get_entry_term(&self, id: &str) -> Option<&ast::Term<&str>> { + self.entries.get(id).and_then(|ref entry| match entry { + Entry::Term(pos) => { + let res = self.resources.get(pos.0)?.borrow(); + if let ast::Entry::Term(ref msg) = res.get_entry(pos.1)? { + Some(msg) + } else { + None + } + } + _ => None, + }) + } + + fn get_entry_function(&self, id: &str) -> Option<&FluentFunction> { + self.entries.get(id).and_then(|ref entry| match entry { + Entry::Function(function) => Some(function), + _ => None, + }) + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/errors.rs b/utshell-0.5.0/vendor/fluent-bundle/src/errors.rs new file mode 100644 index 00000000..ec4a02c4 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/errors.rs @@ -0,0 +1,86 @@ +use crate::resolver::ResolverError; +use fluent_syntax::parser::ParserError; +use std::error::Error; + +#[derive(Debug, PartialEq, Clone)] +pub enum EntryKind { + Message, + Term, + Function, +} + +impl std::fmt::Display for EntryKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Message => f.write_str("message"), + Self::Term => f.write_str("term"), + Self::Function => f.write_str("function"), + } + } +} + +/// Core error type for Fluent runtime system. +/// +/// It contains three main types of errors that may come up +/// during runtime use of the fluent-bundle crate. +#[derive(Debug, PartialEq, Clone)] +pub enum FluentError { + /// An error which occurs when + /// [`FluentBundle::add_resource`](crate::bundle::FluentBundle::add_resource) + /// adds entries that are already registered in a given [`FluentBundle`](crate::FluentBundle). + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::{FluentBundle, FluentResource}; + /// use unic_langid::langid; + /// + /// let ftl_string = String::from("intro = Welcome, { $name }."); + /// let res1 = FluentResource::try_new(ftl_string) + /// .expect("Could not parse an FTL string."); + /// + /// let ftl_string = String::from("intro = Hi, { $name }."); + /// let res2 = FluentResource::try_new(ftl_string) + /// .expect("Could not parse an FTL string."); + /// + /// let langid_en = langid!("en-US"); + /// let mut bundle = FluentBundle::new(vec![langid_en]); + /// + /// bundle.add_resource(&res1) + /// .expect("Failed to add FTL resources to the bundle."); + /// + /// assert!(bundle.add_resource(&res2).is_err()); + /// ``` + Overriding { + kind: EntryKind, + id: String, + }, + ParserError(ParserError), + ResolverError(ResolverError), +} + +impl std::fmt::Display for FluentError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Overriding { kind, id } => { + write!(f, "Attempt to override an existing {}: \"{}\".", kind, id) + } + Self::ParserError(err) => write!(f, "Parser error: {}", err), + Self::ResolverError(err) => write!(f, "Resolver error: {}", err), + } + } +} + +impl Error for FluentError {} + +impl From for FluentError { + fn from(error: ResolverError) -> Self { + Self::ResolverError(error) + } +} + +impl From for FluentError { + fn from(error: ParserError) -> Self { + Self::ParserError(error) + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/lib.rs b/utshell-0.5.0/vendor/fluent-bundle/src/lib.rs new file mode 100644 index 00000000..faf3e9ba --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/lib.rs @@ -0,0 +1,127 @@ +//! Fluent is a modern localization system designed to improve how software is translated. +//! +//! `fluent-bundle` is a mid-level component of the [Fluent Localization +//! System](https://www.projectfluent.org). +//! +//! The crate builds on top of the low level [`fluent-syntax`](../fluent-syntax) package, and provides +//! foundational types and structures required for executing localization at runtime. +//! +//! There are four core concepts to understand Fluent runtime: +//! +//! * [`FluentMessage`] - A single translation unit +//! * [`FluentResource`] - A list of [`FluentMessage`] units +//! * [`FluentBundle`](crate::bundle::FluentBundle) - A collection of [`FluentResource`] lists +//! * [`FluentArgs`] - A list of elements used to resolve a [`FluentMessage`] value +//! +//! ## Example +//! +//! ``` +//! use fluent_bundle::{FluentBundle, FluentValue, FluentResource, FluentArgs}; +//! // Used to provide a locale for the bundle. +//! use unic_langid::langid; +//! +//! // 1. Crate a FluentResource +//! +//! let ftl_string = r#" +//! +//! hello-world = Hello, world! +//! intro = Welcome, { $name }. +//! +//! "#.to_string(); +//! +//! let res = FluentResource::try_new(ftl_string) +//! .expect("Failed to parse an FTL string."); +//! +//! +//! // 2. Crate a FluentBundle +//! +//! let langid_en = langid!("en-US"); +//! let mut bundle = FluentBundle::new(vec![langid_en]); +//! +//! +//! // 3. Add the resource to the bundle +//! +//! bundle +//! .add_resource(res) +//! .expect("Failed to add FTL resources to the bundle."); +//! +//! +//! // 4. Retrieve a FluentMessage from the bundle +//! +//! let msg = bundle.get_message("hello-world") +//! .expect("Message doesn't exist."); +//! +//! +//! // 5. Format the value of the simple message +//! +//! let mut errors = vec![]; +//! +//! let pattern = msg.value() +//! .expect("Message has no value."); +//! +//! let value = bundle.format_pattern(&pattern, None, &mut errors); +//! +//! assert_eq!( +//! bundle.format_pattern(&pattern, None, &mut errors), +//! "Hello, world!" +//! ); +//! +//! // 6. Format the value of the message with arguments +//! +//! let mut args = FluentArgs::new(); +//! args.set("name", "John"); +//! +//! let msg = bundle.get_message("intro") +//! .expect("Message doesn't exist."); +//! +//! let pattern = msg.value() +//! .expect("Message has no value."); +//! +//! // The FSI/PDI isolation marks ensure that the direction of +//! // the text from the variable is not affected by the translation. +//! assert_eq!( +//! bundle.format_pattern(&pattern, Some(&args), &mut errors), +//! "Welcome, \u{2068}John\u{2069}." +//! ); +//! ``` +//! +//! # Ergonomics & Higher Level APIs +//! +//! Reading the example, you may notice how verbose it feels. +//! Many core methods are fallible, others accumulate errors, and there +//! are intermediate structures used in operations. +//! +//! This is intentional as it serves as building blocks for variety of different +//! scenarios allowing implementations to handle errors, cache and +//! optimize results. +//! +//! At the moment it is expected that users will use +//! the `fluent-bundle` crate directly, while the ecosystem +//! matures and higher level APIs are being developed. +mod args; +pub mod bundle; +mod concurrent; +mod entry; +mod errors; +#[doc(hidden)] +pub mod memoizer; +mod message; +#[doc(hidden)] +pub mod resolver; +mod resource; +pub mod types; + +pub use args::FluentArgs; +/// Specialized [`FluentBundle`](crate::bundle::FluentBundle) over +/// non-concurrent [`IntlLangMemoizer`](intl_memoizer::IntlLangMemoizer). +/// +/// This is the basic variant of the [`FluentBundle`](crate::bundle::FluentBundle). +/// +/// The concurrent specialization, can be constructed with +/// [`FluentBundle::new_concurrent`](crate::bundle::FluentBundle::new_concurrent). +pub type FluentBundle = bundle::FluentBundle; +pub use errors::FluentError; +pub use message::{FluentAttribute, FluentMessage}; +pub use resource::FluentResource; +#[doc(inline)] +pub use types::FluentValue; diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/memoizer.rs b/utshell-0.5.0/vendor/fluent-bundle/src/memoizer.rs new file mode 100644 index 00000000..c738a857 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/memoizer.rs @@ -0,0 +1,18 @@ +use crate::types::FluentType; +use intl_memoizer::Memoizable; +use unic_langid::LanguageIdentifier; + +pub trait MemoizerKind: 'static { + fn new(lang: LanguageIdentifier) -> Self + where + Self: Sized; + + fn with_try_get_threadsafe(&self, args: I::Args, cb: U) -> Result + where + Self: Sized, + I: Memoizable + Send + Sync + 'static, + I::Args: Send + Sync + 'static, + U: FnOnce(&I) -> R; + + fn stringify_value(&self, value: &dyn FluentType) -> std::borrow::Cow<'static, str>; +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/message.rs b/utshell-0.5.0/vendor/fluent-bundle/src/message.rs new file mode 100644 index 00000000..a6cc00d7 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/message.rs @@ -0,0 +1,274 @@ +use fluent_syntax::ast; + +/// [`FluentAttribute`] is a component of a compound [`FluentMessage`]. +/// +/// It represents a key-value pair providing a translation of a component +/// of a user interface widget localized by the given message. +/// +/// # Example +/// +/// ``` +/// use fluent_bundle::{FluentResource, FluentBundle}; +/// +/// let source = r#" +/// +/// confirm-modal = Are you sure? +/// .confirm = Yes +/// .cancel = No +/// .tooltip = Closing the window will lose all unsaved data. +/// +/// "#; +/// +/// let resource = FluentResource::try_new(source.to_string()) +/// .expect("Failed to parse the resource."); +/// +/// let mut bundle = FluentBundle::default(); +/// bundle.add_resource(resource) +/// .expect("Failed to add a resource."); +/// +/// let msg = bundle.get_message("confirm-modal") +/// .expect("Failed to retrieve a message."); +/// +/// let mut err = vec![]; +/// +/// let attributes = msg.attributes().map(|attr| { +/// bundle.format_pattern(attr.value(), None, &mut err) +/// }).collect::>(); +/// +/// assert_eq!(attributes[0], "Yes"); +/// assert_eq!(attributes[1], "No"); +/// assert_eq!(attributes[2], "Closing the window will lose all unsaved data."); +/// ``` +#[derive(Debug, PartialEq)] +pub struct FluentAttribute<'m> { + node: &'m ast::Attribute<&'m str>, +} + +impl<'m> FluentAttribute<'m> { + /// Retrieves an id of an attribute. + /// + /// # Example + /// + /// ``` + /// # use fluent_bundle::{FluentResource, FluentBundle}; + /// # let source = r#" + /// # confirm-modal = + /// # .confirm = Yes + /// # "#; + /// # let resource = FluentResource::try_new(source.to_string()) + /// # .expect("Failed to parse the resource."); + /// # let mut bundle = FluentBundle::default(); + /// # bundle.add_resource(resource) + /// # .expect("Failed to add a resource."); + /// let msg = bundle.get_message("confirm-modal") + /// .expect("Failed to retrieve a message."); + /// + /// let attr1 = msg.attributes().next() + /// .expect("Failed to retrieve an attribute."); + /// + /// assert_eq!(attr1.id(), "confirm"); + /// ``` + pub fn id(&self) -> &'m str { + &self.node.id.name + } + + /// Retrieves an value of an attribute. + /// + /// # Example + /// + /// ``` + /// # use fluent_bundle::{FluentResource, FluentBundle}; + /// # let source = r#" + /// # confirm-modal = + /// # .confirm = Yes + /// # "#; + /// # let resource = FluentResource::try_new(source.to_string()) + /// # .expect("Failed to parse the resource."); + /// # let mut bundle = FluentBundle::default(); + /// # bundle.add_resource(resource) + /// # .expect("Failed to add a resource."); + /// let msg = bundle.get_message("confirm-modal") + /// .expect("Failed to retrieve a message."); + /// + /// let attr1 = msg.attributes().next() + /// .expect("Failed to retrieve an attribute."); + /// + /// let mut err = vec![]; + /// + /// let value = attr1.value(); + /// assert_eq!( + /// bundle.format_pattern(value, None, &mut err), + /// "Yes" + /// ); + /// ``` + pub fn value(&self) -> &'m ast::Pattern<&'m str> { + &self.node.value + } +} + +impl<'m> From<&'m ast::Attribute<&'m str>> for FluentAttribute<'m> { + fn from(attr: &'m ast::Attribute<&'m str>) -> Self { + FluentAttribute { node: attr } + } +} + +/// [`FluentMessage`] is a basic translation unit of the Fluent system. +/// +/// The instance of a message is returned from the +/// [`FluentBundle::get_message`](crate::bundle::FluentBundle::get_message) +/// method, for the lifetime of the [`FluentBundle`](crate::bundle::FluentBundle) instance. +/// +/// # Example +/// +/// ``` +/// use fluent_bundle::{FluentResource, FluentBundle}; +/// +/// let source = r#" +/// +/// hello-world = Hello World! +/// +/// "#; +/// +/// let resource = FluentResource::try_new(source.to_string()) +/// .expect("Failed to parse the resource."); +/// +/// let mut bundle = FluentBundle::default(); +/// bundle.add_resource(resource) +/// .expect("Failed to add a resource."); +/// +/// let msg = bundle.get_message("hello-world") +/// .expect("Failed to retrieve a message."); +/// +/// assert!(msg.value().is_some()); +/// ``` +/// +/// That value can be then passed to +/// [`FluentBundle::format_pattern`](crate::bundle::FluentBundle::format_pattern) to be formatted +/// within the context of a given [`FluentBundle`](crate::bundle::FluentBundle) instance. +/// +/// # Compound Message +/// +/// A message may contain a `value`, but it can also contain a list of [`FluentAttribute`] elements. +/// +/// If a message contains attributes, it is called a "compound" message. +/// +/// In such case, the message contains a list of key-value attributes that represent +/// different translation values associated with a single translation unit. +/// +/// This is useful for scenarios where a [`FluentMessage`] is associated with a +/// complex User Interface widget which has multiple attributes that need to be translated. +/// ```text +/// confirm-modal = Are you sure? +/// .confirm = Yes +/// .cancel = No +/// .tooltip = Closing the window will lose all unsaved data. +/// ``` +#[derive(Debug, PartialEq)] +pub struct FluentMessage<'m> { + node: &'m ast::Message<&'m str>, +} + +impl<'m> FluentMessage<'m> { + /// Retrieves an option of a [`ast::Pattern`](fluent_syntax::ast::Pattern). + /// + /// # Example + /// + /// ``` + /// # use fluent_bundle::{FluentResource, FluentBundle}; + /// # let source = r#" + /// # hello-world = Hello World! + /// # "#; + /// # let resource = FluentResource::try_new(source.to_string()) + /// # .expect("Failed to parse the resource."); + /// # let mut bundle = FluentBundle::default(); + /// # bundle.add_resource(resource) + /// # .expect("Failed to add a resource."); + /// let msg = bundle.get_message("hello-world") + /// .expect("Failed to retrieve a message."); + /// + /// if let Some(value) = msg.value() { + /// let mut err = vec![]; + /// assert_eq!( + /// bundle.format_pattern(value, None, &mut err), + /// "Hello World!" + /// ); + /// # assert_eq!(err.len(), 0); + /// } + /// ``` + pub fn value(&self) -> Option<&'m ast::Pattern<&'m str>> { + self.node.value.as_ref() + } + + /// An iterator over [`FluentAttribute`] elements. + /// + /// # Example + /// + /// ``` + /// # use fluent_bundle::{FluentResource, FluentBundle}; + /// # let source = r#" + /// # hello-world = + /// # .label = This is a label + /// # .accesskey = C + /// # "#; + /// # let resource = FluentResource::try_new(source.to_string()) + /// # .expect("Failed to parse the resource."); + /// # let mut bundle = FluentBundle::default(); + /// # bundle.add_resource(resource) + /// # .expect("Failed to add a resource."); + /// let msg = bundle.get_message("hello-world") + /// .expect("Failed to retrieve a message."); + /// + /// let mut err = vec![]; + /// + /// for attr in msg.attributes() { + /// let _ = bundle.format_pattern(attr.value(), None, &mut err); + /// } + /// # assert_eq!(err.len(), 0); + /// ``` + pub fn attributes(&self) -> impl Iterator> { + self.node.attributes.iter().map(Into::into) + } + + /// Retrieve a single [`FluentAttribute`] element. + /// + /// # Example + /// + /// ``` + /// # use fluent_bundle::{FluentResource, FluentBundle}; + /// # let source = r#" + /// # hello-world = + /// # .label = This is a label + /// # .accesskey = C + /// # "#; + /// # let resource = FluentResource::try_new(source.to_string()) + /// # .expect("Failed to parse the resource."); + /// # let mut bundle = FluentBundle::default(); + /// # bundle.add_resource(resource) + /// # .expect("Failed to add a resource."); + /// let msg = bundle.get_message("hello-world") + /// .expect("Failed to retrieve a message."); + /// + /// let mut err = vec![]; + /// + /// if let Some(attr) = msg.get_attribute("label") { + /// assert_eq!( + /// bundle.format_pattern(attr.value(), None, &mut err), + /// "This is a label" + /// ); + /// } + /// # assert_eq!(err.len(), 0); + /// ``` + pub fn get_attribute(&self, key: &str) -> Option> { + self.node + .attributes + .iter() + .find(|attr| attr.id.name == key) + .map(Into::into) + } +} + +impl<'m> From<&'m ast::Message<&'m str>> for FluentMessage<'m> { + fn from(msg: &'m ast::Message<&'m str>) -> Self { + FluentMessage { node: msg } + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resolver/errors.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/errors.rs new file mode 100644 index 00000000..831d8474 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/errors.rs @@ -0,0 +1,96 @@ +use fluent_syntax::ast::InlineExpression; +use std::error::Error; + +#[derive(Debug, PartialEq, Clone)] +pub enum ReferenceKind { + Function { + id: String, + }, + Message { + id: String, + attribute: Option, + }, + Term { + id: String, + attribute: Option, + }, + Variable { + id: String, + }, +} + +impl From<&InlineExpression> for ReferenceKind +where + T: ToString, +{ + fn from(exp: &InlineExpression) -> Self { + match exp { + InlineExpression::FunctionReference { id, .. } => Self::Function { + id: id.name.to_string(), + }, + InlineExpression::MessageReference { id, attribute } => Self::Message { + id: id.name.to_string(), + attribute: attribute.as_ref().map(|i| i.name.to_string()), + }, + InlineExpression::TermReference { id, attribute, .. } => Self::Term { + id: id.name.to_string(), + attribute: attribute.as_ref().map(|i| i.name.to_string()), + }, + InlineExpression::VariableReference { id, .. } => Self::Variable { + id: id.name.to_string(), + }, + _ => unreachable!(), + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub enum ResolverError { + Reference(ReferenceKind), + NoValue(String), + MissingDefault, + Cyclic, + TooManyPlaceables, +} + +impl std::fmt::Display for ResolverError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Reference(exp) => match exp { + ReferenceKind::Function { id } => write!(f, "Unknown function: {}()", id), + ReferenceKind::Message { + id, + attribute: None, + } => write!(f, "Unknown message: {}", id), + ReferenceKind::Message { + id, + attribute: Some(attribute), + } => write!(f, "Unknown attribute: {}.{}", id, attribute), + ReferenceKind::Term { + id, + attribute: None, + } => write!(f, "Unknown term: -{}", id), + ReferenceKind::Term { + id, + attribute: Some(attribute), + } => write!(f, "Unknown attribute: -{}.{}", id, attribute), + ReferenceKind::Variable { id } => write!(f, "Unknown variable: ${}", id), + }, + Self::NoValue(id) => write!(f, "No value: {}", id), + Self::MissingDefault => f.write_str("No default"), + Self::Cyclic => f.write_str("Cyclical dependency detected"), + Self::TooManyPlaceables => f.write_str("Too many placeables"), + } + } +} + +impl From<&InlineExpression> for ResolverError +where + T: ToString, +{ + fn from(exp: &InlineExpression) -> Self { + Self::Reference(exp.into()) + } +} + +impl Error for ResolverError {} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resolver/expression.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/expression.rs new file mode 100644 index 00000000..d0d02dec --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/expression.rs @@ -0,0 +1,66 @@ +use super::scope::Scope; +use super::WriteValue; + +use std::borrow::Borrow; +use std::fmt; + +use fluent_syntax::ast; + +use crate::memoizer::MemoizerKind; +use crate::resolver::{ResolveValue, ResolverError}; +use crate::resource::FluentResource; +use crate::types::FluentValue; + +impl<'p> WriteValue for ast::Expression<&'p str> { + fn write<'scope, 'errors, W, R, M>( + &'scope self, + w: &mut W, + scope: &mut Scope<'scope, 'errors, R, M>, + ) -> fmt::Result + where + W: fmt::Write, + R: Borrow, + M: MemoizerKind, + { + match self { + Self::Inline(exp) => exp.write(w, scope), + Self::Select { selector, variants } => { + let selector = selector.resolve(scope); + match selector { + FluentValue::String(_) | FluentValue::Number(_) => { + for variant in variants { + let key = match variant.key { + ast::VariantKey::Identifier { name } => name.into(), + ast::VariantKey::NumberLiteral { value } => { + FluentValue::try_number(value) + } + }; + if key.matches(&selector, scope) { + return variant.value.write(w, scope); + } + } + } + _ => {} + } + + for variant in variants { + if variant.default { + return variant.value.write(w, scope); + } + } + scope.add_error(ResolverError::MissingDefault); + Ok(()) + } + } + } + + fn write_error(&self, w: &mut W) -> fmt::Result + where + W: fmt::Write, + { + match self { + Self::Inline(exp) => exp.write_error(w), + Self::Select { .. } => unreachable!(), + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resolver/inline_expression.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/inline_expression.rs new file mode 100644 index 00000000..b9e89b6e --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/inline_expression.rs @@ -0,0 +1,181 @@ +use super::scope::Scope; +use super::{ResolveValue, ResolverError, WriteValue}; + +use std::borrow::Borrow; +use std::fmt; + +use fluent_syntax::ast; +use fluent_syntax::unicode::{unescape_unicode, unescape_unicode_to_string}; + +use crate::entry::GetEntry; +use crate::memoizer::MemoizerKind; +use crate::resource::FluentResource; +use crate::types::FluentValue; + +impl<'p> WriteValue for ast::InlineExpression<&'p str> { + fn write<'scope, 'errors, W, R, M>( + &'scope self, + w: &mut W, + scope: &mut Scope<'scope, 'errors, R, M>, + ) -> fmt::Result + where + W: fmt::Write, + R: Borrow, + M: MemoizerKind, + { + match self { + Self::StringLiteral { value } => unescape_unicode(w, value), + Self::MessageReference { id, attribute } => { + if let Some(msg) = scope.bundle.get_entry_message(id.name) { + if let Some(attr) = attribute { + msg.attributes + .iter() + .find_map(|a| { + if a.id.name == attr.name { + Some(scope.track(w, &a.value, self)) + } else { + None + } + }) + .unwrap_or_else(|| scope.write_ref_error(w, self)) + } else { + msg.value + .as_ref() + .map(|value| scope.track(w, value, self)) + .unwrap_or_else(|| { + scope.add_error(ResolverError::NoValue(id.name.to_string())); + w.write_char('{')?; + self.write_error(w)?; + w.write_char('}') + }) + } + } else { + scope.write_ref_error(w, self) + } + } + Self::NumberLiteral { value } => FluentValue::try_number(*value).write(w, scope), + Self::TermReference { + id, + attribute, + arguments, + } => { + let (_, resolved_named_args) = scope.get_arguments(arguments.as_ref()); + + scope.local_args = Some(resolved_named_args); + let result = scope + .bundle + .get_entry_term(id.name) + .and_then(|term| { + if let Some(attr) = attribute { + term.attributes.iter().find_map(|a| { + if a.id.name == attr.name { + Some(scope.track(w, &a.value, self)) + } else { + None + } + }) + } else { + Some(scope.track(w, &term.value, self)) + } + }) + .unwrap_or_else(|| scope.write_ref_error(w, self)); + scope.local_args = None; + result + } + Self::FunctionReference { id, arguments } => { + let (resolved_positional_args, resolved_named_args) = + scope.get_arguments(Some(arguments)); + + let func = scope.bundle.get_entry_function(id.name); + + if let Some(func) = func { + let result = func(resolved_positional_args.as_slice(), &resolved_named_args); + if let FluentValue::Error = result { + self.write_error(w) + } else { + w.write_str(&result.as_string(scope)) + } + } else { + scope.write_ref_error(w, self) + } + } + Self::VariableReference { id } => { + let args = scope.local_args.as_ref().or(scope.args); + + if let Some(arg) = args.and_then(|args| args.get(id.name)) { + arg.write(w, scope) + } else { + if scope.local_args.is_none() { + scope.add_error(self.into()); + } + w.write_char('{')?; + self.write_error(w)?; + w.write_char('}') + } + } + Self::Placeable { expression } => expression.write(w, scope), + } + } + + fn write_error(&self, w: &mut W) -> fmt::Result + where + W: fmt::Write, + { + match self { + Self::MessageReference { + id, + attribute: Some(attribute), + } => write!(w, "{}.{}", id.name, attribute.name), + Self::MessageReference { + id, + attribute: None, + } => w.write_str(id.name), + Self::TermReference { + id, + attribute: Some(attribute), + .. + } => write!(w, "-{}.{}", id.name, attribute.name), + Self::TermReference { + id, + attribute: None, + .. + } => write!(w, "-{}", id.name), + Self::FunctionReference { id, .. } => write!(w, "{}()", id.name), + Self::VariableReference { id } => write!(w, "${}", id.name), + _ => unreachable!(), + } + } +} + +impl<'p> ResolveValue for ast::InlineExpression<&'p str> { + fn resolve<'source, 'errors, R, M>( + &'source self, + scope: &mut Scope<'source, 'errors, R, M>, + ) -> FluentValue<'source> + where + R: Borrow, + M: MemoizerKind, + { + match self { + Self::StringLiteral { value } => unescape_unicode_to_string(value).into(), + Self::NumberLiteral { value } => FluentValue::try_number(*value), + Self::VariableReference { id } => { + let args = scope.local_args.as_ref().or(scope.args); + + if let Some(arg) = args.and_then(|args| args.get(id.name)) { + arg.clone() + } else { + if scope.local_args.is_none() { + scope.add_error(self.into()); + } + FluentValue::Error + } + } + _ => { + let mut result = String::new(); + self.write(&mut result, scope).expect("Failed to write"); + result.into() + } + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resolver/mod.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/mod.rs new file mode 100644 index 00000000..f137bcc9 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/mod.rs @@ -0,0 +1,42 @@ +pub mod errors; +mod expression; +mod inline_expression; +mod pattern; +mod scope; + +pub use errors::ResolverError; +pub use scope::Scope; + +use std::borrow::Borrow; +use std::fmt; + +use crate::memoizer::MemoizerKind; +use crate::resource::FluentResource; +use crate::types::FluentValue; + +// Converts an AST node to a `FluentValue`. +pub(crate) trait ResolveValue { + fn resolve<'source, 'errors, R, M>( + &'source self, + scope: &mut Scope<'source, 'errors, R, M>, + ) -> FluentValue<'source> + where + R: Borrow, + M: MemoizerKind; +} + +pub(crate) trait WriteValue { + fn write<'source, 'errors, W, R, M>( + &'source self, + w: &mut W, + scope: &mut Scope<'source, 'errors, R, M>, + ) -> fmt::Result + where + W: fmt::Write, + R: Borrow, + M: MemoizerKind; + + fn write_error(&self, _w: &mut W) -> fmt::Result + where + W: fmt::Write; +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resolver/pattern.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/pattern.rs new file mode 100644 index 00000000..4e01d4ca --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/pattern.rs @@ -0,0 +1,108 @@ +use super::scope::Scope; +use super::{ResolverError, WriteValue}; + +use std::borrow::Borrow; +use std::fmt; + +use fluent_syntax::ast; + +use crate::memoizer::MemoizerKind; +use crate::resolver::ResolveValue; +use crate::resource::FluentResource; +use crate::types::FluentValue; + +const MAX_PLACEABLES: u8 = 100; + +impl<'p> WriteValue for ast::Pattern<&'p str> { + fn write<'scope, 'errors, W, R, M>( + &'scope self, + w: &mut W, + scope: &mut Scope<'scope, 'errors, R, M>, + ) -> fmt::Result + where + W: fmt::Write, + R: Borrow, + M: MemoizerKind, + { + let len = self.elements.len(); + + for elem in &self.elements { + if scope.dirty { + return Ok(()); + } + + match elem { + ast::PatternElement::TextElement { value } => { + if let Some(ref transform) = scope.bundle.transform { + w.write_str(&transform(value))?; + } else { + w.write_str(value)?; + } + } + ast::PatternElement::Placeable { ref expression } => { + scope.placeables += 1; + if scope.placeables > MAX_PLACEABLES { + scope.dirty = true; + scope.add_error(ResolverError::TooManyPlaceables); + return Ok(()); + } + + let needs_isolation = scope.bundle.use_isolating + && len > 1 + && !matches!( + expression, + ast::Expression::Inline(ast::InlineExpression::MessageReference { .. },) + | ast::Expression::Inline( + ast::InlineExpression::TermReference { .. }, + ) + | ast::Expression::Inline( + ast::InlineExpression::StringLiteral { .. }, + ) + ); + if needs_isolation { + w.write_char('\u{2068}')?; + } + scope.maybe_track(w, self, expression)?; + if needs_isolation { + w.write_char('\u{2069}')?; + } + } + } + } + Ok(()) + } + + fn write_error(&self, _w: &mut W) -> fmt::Result + where + W: fmt::Write, + { + unreachable!() + } +} + +impl<'p> ResolveValue for ast::Pattern<&'p str> { + fn resolve<'source, 'errors, R, M>( + &'source self, + scope: &mut Scope<'source, 'errors, R, M>, + ) -> FluentValue<'source> + where + R: Borrow, + M: MemoizerKind, + { + let len = self.elements.len(); + + if len == 1 { + if let ast::PatternElement::TextElement { value } = self.elements[0] { + return scope + .bundle + .transform + .map_or_else(|| value.into(), |transform| transform(value).into()); + } + } + + let mut result = String::new(); + self.write(&mut result, scope) + .expect("Failed to write to a string."); + result.into() + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resolver/scope.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/scope.rs new file mode 100644 index 00000000..00470113 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resolver/scope.rs @@ -0,0 +1,141 @@ +use crate::bundle::FluentBundle; +use crate::memoizer::MemoizerKind; +use crate::resolver::{ResolveValue, ResolverError, WriteValue}; +use crate::types::FluentValue; +use crate::{FluentArgs, FluentError, FluentResource}; +use fluent_syntax::ast; +use std::borrow::Borrow; +use std::fmt; + +/// State for a single `ResolveValue::to_value` call. +pub struct Scope<'scope, 'errors, R, M> { + /// The current `FluentBundle` instance. + pub bundle: &'scope FluentBundle, + /// The current arguments passed by the developer. + pub(super) args: Option<&'scope FluentArgs<'scope>>, + /// Local args + pub(super) local_args: Option>, + /// The running count of resolved placeables. Used to detect the Billion + /// Laughs and Quadratic Blowup attacks. + pub(super) placeables: u8, + /// Tracks hashes to prevent infinite recursion. + travelled: smallvec::SmallVec<[&'scope ast::Pattern<&'scope str>; 2]>, + /// Track errors accumulated during resolving. + pub errors: Option<&'errors mut Vec>, + /// Makes the resolver bail. + pub dirty: bool, +} + +impl<'scope, 'errors, R, M> Scope<'scope, 'errors, R, M> { + pub fn new( + bundle: &'scope FluentBundle, + args: Option<&'scope FluentArgs>, + errors: Option<&'errors mut Vec>, + ) -> Self { + Scope { + bundle, + args, + local_args: None, + placeables: 0, + travelled: Default::default(), + errors, + dirty: false, + } + } + + pub fn add_error(&mut self, error: ResolverError) { + if let Some(errors) = self.errors.as_mut() { + errors.push(error.into()); + } + } + + // This method allows us to lazily add Pattern on the stack, + // only if the Pattern::resolve has been called on an empty stack. + // + // This is the case when pattern is called from Bundle and it + // allows us to fast-path simple resolutions, and only use the stack + // for placeables. + pub fn maybe_track( + &mut self, + w: &mut W, + pattern: &'scope ast::Pattern<&str>, + exp: &'scope ast::Expression<&str>, + ) -> fmt::Result + where + R: Borrow, + W: fmt::Write, + M: MemoizerKind, + { + if self.travelled.is_empty() { + self.travelled.push(pattern); + } + exp.write(w, self)?; + if self.dirty { + w.write_char('{')?; + exp.write_error(w)?; + w.write_char('}') + } else { + Ok(()) + } + } + + pub fn track( + &mut self, + w: &mut W, + pattern: &'scope ast::Pattern<&str>, + exp: &ast::InlineExpression<&str>, + ) -> fmt::Result + where + R: Borrow, + W: fmt::Write, + M: MemoizerKind, + { + if self.travelled.contains(&pattern) { + self.add_error(ResolverError::Cyclic); + w.write_char('{')?; + exp.write_error(w)?; + w.write_char('}') + } else { + self.travelled.push(pattern); + let result = pattern.write(w, self); + self.travelled.pop(); + result + } + } + + pub fn write_ref_error( + &mut self, + w: &mut W, + exp: &ast::InlineExpression<&str>, + ) -> fmt::Result + where + W: fmt::Write, + { + self.add_error(exp.into()); + w.write_char('{')?; + exp.write_error(w)?; + w.write_char('}') + } + + pub fn get_arguments( + &mut self, + arguments: Option<&'scope ast::CallArguments<&'scope str>>, + ) -> (Vec>, FluentArgs<'scope>) + where + R: Borrow, + M: MemoizerKind, + { + if let Some(ast::CallArguments { positional, named }) = arguments { + let positional = positional.iter().map(|expr| expr.resolve(self)).collect(); + + let named = named + .iter() + .map(|arg| (arg.name.name, arg.value.resolve(self))) + .collect(); + + (positional, named) + } else { + (Vec::new(), FluentArgs::new()) + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/resource.rs b/utshell-0.5.0/vendor/fluent-bundle/src/resource.rs new file mode 100644 index 00000000..0c39c838 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/resource.rs @@ -0,0 +1,171 @@ +use fluent_syntax::ast; +use fluent_syntax::parser::{parse_runtime, ParserError}; + +use self_cell::self_cell; + +type Resource<'s> = ast::Resource<&'s str>; + +self_cell!( + pub struct InnerFluentResource { + owner: String, + + #[covariant] + dependent: Resource, + } + + impl {Debug} +); + +/// A resource containing a list of localization messages. +/// +/// [`FluentResource`] wraps an [`Abstract Syntax Tree`](../fluent_syntax/ast/index.html) produced by the +/// [`parser`](../fluent_syntax/parser/index.html) and provides an access to a list +/// of its entries. +/// +/// A good mental model for a resource is a single FTL file, but in the future +/// there's nothing preventing a resource from being stored in a data base, +/// pre-parsed format or in some other structured form. +/// +/// # Example +/// +/// ``` +/// use fluent_bundle::FluentResource; +/// +/// let source = r#" +/// +/// hello-world = Hello World! +/// +/// "#; +/// +/// let resource = FluentResource::try_new(source.to_string()) +/// .expect("Errors encountered while parsing a resource."); +/// +/// assert_eq!(resource.entries().count(), 1); +/// ``` +/// +/// # Ownership +/// +/// A resource owns the source string and the AST contains references +/// to the slices of the source. +#[derive(Debug)] +pub struct FluentResource(InnerFluentResource); + +impl FluentResource { + /// A fallible constructor of a new [`FluentResource`]. + /// + /// It takes an encoded `Fluent Translation List` string, parses + /// it and stores both, the input string and the AST view of it, + /// for runtime use. + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::FluentResource; + /// + /// let source = r#" + /// + /// hello-world = Hello, { $user }! + /// + /// "#; + /// + /// let resource = FluentResource::try_new(source.to_string()); + /// + /// assert!(resource.is_ok()); + /// ``` + /// + /// # Errors + /// + /// The method will return the resource irrelevant of parse errors + /// encountered during parsing of the source, but in case of errors, + /// the `Err` variant will contain both the structure and a vector + /// of errors. + pub fn try_new(source: String) -> Result)> { + let mut errors = None; + + let res = InnerFluentResource::new(source, |source| match parse_runtime(source.as_str()) { + Ok(ast) => ast, + Err((ast, err)) => { + errors = Some(err); + ast + } + }); + + match errors { + None => Ok(Self(res)), + Some(err) => Err((Self(res), err)), + } + } + + /// Returns a reference to the source string that was used + /// to construct the [`FluentResource`]. + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::FluentResource; + /// + /// let source = "hello-world = Hello, { $user }!"; + /// + /// let resource = FluentResource::try_new(source.to_string()) + /// .expect("Failed to parse FTL."); + /// + /// assert_eq!( + /// resource.source(), + /// "hello-world = Hello, { $user }!" + /// ); + /// ``` + pub fn source(&self) -> &str { + &self.0.borrow_owner() + } + + /// Returns an iterator over [`entries`](fluent_syntax::ast::Entry) of the [`FluentResource`]. + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::FluentResource; + /// use fluent_syntax::ast; + /// + /// let source = r#" + /// + /// hello-world = Hello, { $user }! + /// + /// "#; + /// + /// let resource = FluentResource::try_new(source.to_string()) + /// .expect("Failed to parse FTL."); + /// + /// assert_eq!( + /// resource.entries().count(), + /// 1 + /// ); + /// assert!(matches!(resource.entries().next(), Some(ast::Entry::Message(_)))); + /// ``` + pub fn entries(&self) -> impl Iterator> { + self.0.borrow_dependent().body.iter() + } + + /// Returns an [`Entry`](fluent_syntax::ast::Entry) at the + /// given index out of the [`FluentResource`]. + /// + /// # Example + /// + /// ``` + /// use fluent_bundle::FluentResource; + /// use fluent_syntax::ast; + /// + /// let source = r#" + /// + /// hello-world = Hello, { $user }! + /// + /// "#; + /// + /// let resource = FluentResource::try_new(source.to_string()) + /// .expect("Failed to parse FTL."); + /// + /// assert!(matches!(resource.get_entry(0), Some(ast::Entry::Message(_)))); + /// ``` + pub fn get_entry(&self, idx: usize) -> Option<&ast::Entry<&str>> { + self.0.borrow_dependent().body.get(idx) + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/types/mod.rs b/utshell-0.5.0/vendor/fluent-bundle/src/types/mod.rs new file mode 100644 index 00000000..714fe4c7 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/types/mod.rs @@ -0,0 +1,202 @@ +//! `types` module contains types necessary for Fluent runtime +//! value handling. +//! The core struct is [`FluentValue`] which is a type that can be passed +//! to the [`FluentBundle::format_pattern`](crate::bundle::FluentBundle) as an argument, it can be passed +//! to any Fluent Function, and any function may return it. +//! +//! This part of functionality is not fully hashed out yet, since we're waiting +//! for the internationalization APIs to mature, at which point all number +//! formatting operations will be moved out of Fluent. +//! +//! For now, [`FluentValue`] can be a string, a number, or a custom [`FluentType`] +//! which allows users of the library to implement their own types of values, +//! such as dates, or more complex structures needed for their bindings. +mod number; +mod plural; + +pub use number::*; +use plural::PluralRules; + +use std::any::Any; +use std::borrow::{Borrow, Cow}; +use std::fmt; +use std::str::FromStr; + +use intl_pluralrules::{PluralCategory, PluralRuleType}; + +use crate::memoizer::MemoizerKind; +use crate::resolver::Scope; +use crate::resource::FluentResource; + +pub trait FluentType: fmt::Debug + AnyEq + 'static { + fn duplicate(&self) -> Box; + fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> Cow<'static, str>; + fn as_string_threadsafe( + &self, + intls: &intl_memoizer::concurrent::IntlLangMemoizer, + ) -> Cow<'static, str>; +} + +impl PartialEq for dyn FluentType + Send { + fn eq(&self, other: &Self) -> bool { + self.equals(other.as_any()) + } +} + +pub trait AnyEq: Any + 'static { + fn equals(&self, other: &dyn Any) -> bool; + fn as_any(&self) -> &dyn Any; +} + +impl AnyEq for T { + fn equals(&self, other: &dyn Any) -> bool { + other + .downcast_ref::() + .map_or(false, |that| self == that) + } + fn as_any(&self) -> &dyn Any { + self + } +} + +/// The `FluentValue` enum represents values which can be formatted to a String. +/// +/// Those values are either passed as arguments to [`FluentBundle::format_pattern`][] or +/// produced by functions, or generated in the process of pattern resolution. +/// +/// [`FluentBundle::format_pattern`]: ../bundle/struct.FluentBundle.html#method.format_pattern +#[derive(Debug)] +pub enum FluentValue<'source> { + String(Cow<'source, str>), + Number(FluentNumber), + Custom(Box), + None, + Error, +} + +impl<'s> PartialEq for FluentValue<'s> { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (FluentValue::String(s), FluentValue::String(s2)) => s == s2, + (FluentValue::Number(s), FluentValue::Number(s2)) => s == s2, + (FluentValue::Custom(s), FluentValue::Custom(s2)) => s == s2, + _ => false, + } + } +} + +impl<'s> Clone for FluentValue<'s> { + fn clone(&self) -> Self { + match self { + FluentValue::String(s) => FluentValue::String(s.clone()), + FluentValue::Number(s) => FluentValue::Number(s.clone()), + FluentValue::Custom(s) => { + let new_value: Box = s.duplicate(); + FluentValue::Custom(new_value) + } + FluentValue::Error => FluentValue::Error, + FluentValue::None => FluentValue::None, + } + } +} + +impl<'source> FluentValue<'source> { + pub fn try_number(v: S) -> Self { + let s = v.to_string(); + if let Ok(num) = FluentNumber::from_str(&s) { + num.into() + } else { + s.into() + } + } + + pub fn matches, M>( + &self, + other: &FluentValue, + scope: &Scope, + ) -> bool + where + M: MemoizerKind, + { + match (self, other) { + (&FluentValue::String(ref a), &FluentValue::String(ref b)) => a == b, + (&FluentValue::Number(ref a), &FluentValue::Number(ref b)) => a == b, + (&FluentValue::String(ref a), &FluentValue::Number(ref b)) => { + let cat = match a.as_ref() { + "zero" => PluralCategory::ZERO, + "one" => PluralCategory::ONE, + "two" => PluralCategory::TWO, + "few" => PluralCategory::FEW, + "many" => PluralCategory::MANY, + "other" => PluralCategory::OTHER, + _ => return false, + }; + scope + .bundle + .intls + .with_try_get_threadsafe::( + (PluralRuleType::CARDINAL,), + |pr| pr.0.select(b) == Ok(cat), + ) + .unwrap() + } + _ => false, + } + } + + pub fn write(&self, w: &mut W, scope: &Scope) -> fmt::Result + where + W: fmt::Write, + R: Borrow, + M: MemoizerKind, + { + if let Some(formatter) = &scope.bundle.formatter { + if let Some(val) = formatter(self, &scope.bundle.intls) { + return w.write_str(&val); + } + } + match self { + FluentValue::String(s) => w.write_str(s), + FluentValue::Number(n) => w.write_str(&n.as_string()), + FluentValue::Custom(s) => w.write_str(&scope.bundle.intls.stringify_value(&**s)), + FluentValue::Error => Ok(()), + FluentValue::None => Ok(()), + } + } + + pub fn as_string, M>(&self, scope: &Scope) -> Cow<'source, str> + where + M: MemoizerKind, + { + if let Some(formatter) = &scope.bundle.formatter { + if let Some(val) = formatter(self, &scope.bundle.intls) { + return val.into(); + } + } + match self { + FluentValue::String(s) => s.clone(), + FluentValue::Number(n) => n.as_string(), + FluentValue::Custom(s) => scope.bundle.intls.stringify_value(&**s), + FluentValue::Error => "".into(), + FluentValue::None => "".into(), + } + } +} + +impl<'source> From for FluentValue<'source> { + fn from(s: String) -> Self { + FluentValue::String(s.into()) + } +} + +impl<'source> From<&'source str> for FluentValue<'source> { + fn from(s: &'source str) -> Self { + FluentValue::String(s.into()) + } +} + +impl<'source> From> for FluentValue<'source> { + fn from(s: Cow<'source, str>) -> Self { + FluentValue::String(s) + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/types/number.rs b/utshell-0.5.0/vendor/fluent-bundle/src/types/number.rs new file mode 100644 index 00000000..d39291ff --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/types/number.rs @@ -0,0 +1,252 @@ +use std::borrow::Cow; +use std::convert::TryInto; +use std::default::Default; +use std::str::FromStr; + +use intl_pluralrules::operands::PluralOperands; + +use crate::args::FluentArgs; +use crate::types::FluentValue; + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum FluentNumberStyle { + Decimal, + Currency, + Percent, +} + +impl std::default::Default for FluentNumberStyle { + fn default() -> Self { + Self::Decimal + } +} + +impl From<&str> for FluentNumberStyle { + fn from(input: &str) -> Self { + match input { + "decimal" => Self::Decimal, + "currency" => Self::Currency, + "percent" => Self::Percent, + _ => Self::default(), + } + } +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum FluentNumberCurrencyDisplayStyle { + Symbol, + Code, + Name, +} + +impl std::default::Default for FluentNumberCurrencyDisplayStyle { + fn default() -> Self { + Self::Symbol + } +} + +impl From<&str> for FluentNumberCurrencyDisplayStyle { + fn from(input: &str) -> Self { + match input { + "symbol" => Self::Symbol, + "code" => Self::Code, + "name" => Self::Name, + _ => Self::default(), + } + } +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct FluentNumberOptions { + pub style: FluentNumberStyle, + pub currency: Option, + pub currency_display: FluentNumberCurrencyDisplayStyle, + pub use_grouping: bool, + pub minimum_integer_digits: Option, + pub minimum_fraction_digits: Option, + pub maximum_fraction_digits: Option, + pub minimum_significant_digits: Option, + pub maximum_significant_digits: Option, +} + +impl Default for FluentNumberOptions { + fn default() -> Self { + Self { + style: Default::default(), + currency: None, + currency_display: Default::default(), + use_grouping: true, + minimum_integer_digits: None, + minimum_fraction_digits: None, + maximum_fraction_digits: None, + minimum_significant_digits: None, + maximum_significant_digits: None, + } + } +} + +impl FluentNumberOptions { + pub fn merge(&mut self, opts: &FluentArgs) { + for (key, value) in opts.iter() { + match (key, value) { + ("style", FluentValue::String(n)) => { + self.style = n.as_ref().into(); + } + ("currency", FluentValue::String(n)) => { + self.currency = Some(n.to_string()); + } + ("currencyDisplay", FluentValue::String(n)) => { + self.currency_display = n.as_ref().into(); + } + ("useGrouping", FluentValue::String(n)) => { + self.use_grouping = n != "false"; + } + ("minimumIntegerDigits", FluentValue::Number(n)) => { + self.minimum_integer_digits = Some(n.into()); + } + ("minimumFractionDigits", FluentValue::Number(n)) => { + self.minimum_fraction_digits = Some(n.into()); + } + ("maximumFractionDigits", FluentValue::Number(n)) => { + self.maximum_fraction_digits = Some(n.into()); + } + ("minimumSignificantDigits", FluentValue::Number(n)) => { + self.minimum_significant_digits = Some(n.into()); + } + ("maximumSignificantDigits", FluentValue::Number(n)) => { + self.maximum_significant_digits = Some(n.into()); + } + _ => {} + } + } + } +} + +#[derive(Debug, PartialEq, Clone)] +pub struct FluentNumber { + pub value: f64, + pub options: FluentNumberOptions, +} + +impl FluentNumber { + pub const fn new(value: f64, options: FluentNumberOptions) -> Self { + Self { value, options } + } + + pub fn as_string(&self) -> Cow<'static, str> { + let mut val = self.value.to_string(); + if let Some(minfd) = self.options.minimum_fraction_digits { + if let Some(pos) = val.find('.') { + let frac_num = val.len() - pos - 1; + let missing = if frac_num > minfd { + 0 + } else { + minfd - frac_num + }; + val = format!("{}{}", val, "0".repeat(missing)); + } else { + val = format!("{}.{}", val, "0".repeat(minfd)); + } + } + val.into() + } +} + +impl FromStr for FluentNumber { + type Err = std::num::ParseFloatError; + + fn from_str(input: &str) -> Result { + f64::from_str(input).map(|n| { + let mfd = input.find('.').map(|pos| input.len() - pos - 1); + let opts = FluentNumberOptions { + minimum_fraction_digits: mfd, + ..Default::default() + }; + Self::new(n, opts) + }) + } +} + +impl<'l> From for FluentValue<'l> { + fn from(input: FluentNumber) -> Self { + FluentValue::Number(input) + } +} + +macro_rules! from_num { + ($num:ty) => { + impl From<$num> for FluentNumber { + fn from(n: $num) -> Self { + Self { + value: n as f64, + options: FluentNumberOptions::default(), + } + } + } + impl From<&$num> for FluentNumber { + fn from(n: &$num) -> Self { + Self { + value: *n as f64, + options: FluentNumberOptions::default(), + } + } + } + impl From for $num { + fn from(input: FluentNumber) -> Self { + input.value as $num + } + } + impl From<&FluentNumber> for $num { + fn from(input: &FluentNumber) -> Self { + input.value as $num + } + } + impl From<$num> for FluentValue<'_> { + fn from(n: $num) -> Self { + FluentValue::Number(n.into()) + } + } + impl From<&$num> for FluentValue<'_> { + fn from(n: &$num) -> Self { + FluentValue::Number(n.into()) + } + } + }; + ($($num:ty)+) => { + $(from_num!($num);)+ + }; +} + +impl From<&FluentNumber> for PluralOperands { + fn from(input: &FluentNumber) -> Self { + let mut operands: Self = input + .value + .try_into() + .expect("Failed to generate operands out of FluentNumber"); + if let Some(mfd) = input.options.minimum_fraction_digits { + if mfd > operands.v { + operands.f *= 10_u64.pow(mfd as u32 - operands.v as u32); + operands.v = mfd; + } + } + // XXX: Add support for other options. + operands + } +} + +from_num!(i8 i16 i32 i64 i128 isize); +from_num!(u8 u16 u32 u64 u128 usize); +from_num!(f32 f64); + +#[cfg(test)] +mod tests { + use crate::types::FluentValue; + + #[test] + fn value_from_copy_ref() { + let x = 1i16; + let y = &x; + let z: FluentValue = y.into(); + assert_eq!(z, FluentValue::try_number(1)); + } +} diff --git a/utshell-0.5.0/vendor/fluent-bundle/src/types/plural.rs b/utshell-0.5.0/vendor/fluent-bundle/src/types/plural.rs new file mode 100644 index 00000000..1151fd6d --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-bundle/src/types/plural.rs @@ -0,0 +1,22 @@ +use fluent_langneg::{negotiate_languages, NegotiationStrategy}; +use intl_memoizer::Memoizable; +use intl_pluralrules::{PluralRuleType, PluralRules as IntlPluralRules}; +use unic_langid::LanguageIdentifier; + +pub struct PluralRules(pub IntlPluralRules); + +impl Memoizable for PluralRules { + type Args = (PluralRuleType,); + type Error = &'static str; + fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + let default_lang: LanguageIdentifier = "en".parse().unwrap(); + let pr_lang = negotiate_languages( + &[lang], + &IntlPluralRules::get_locales(args.0), + Some(&default_lang), + NegotiationStrategy::Lookup, + )[0] + .clone(); + Ok(Self(IntlPluralRules::create(pr_lang, args.0)?)) + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/.cargo-checksum.json b/utshell-0.5.0/vendor/fluent-fallback/.cargo-checksum.json new file mode 100644 index 00000000..fd4e6435 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"009535601424c3994d30788b8baa50b3527c5c36e26c882e87f023ac23feaee6","Cargo.lock":"ed57b6934296727509b6cf3379bc5039ff63a28f936eac8ec972428aec569793","Cargo.toml":"6ed10beb1162c35f9ff8d0027b1e4a89f4363fda0fe0a361627d3a8580161829","LICENSE-APACHE":"5db2b182453ff32ed40f7da63589c9667a3f8bd8b16b1471b152caae56f77e45","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"f722df51c6c20153f073b5dda208b2a23e1d6a6351af0d5dac8dd35090c10b1f","examples/resources/en-US/simple.ftl":"55e8a72973d239c6ed3eb3d9cbc21d37dc90cea9fad85d1d8d73c96d63941629","examples/resources/pl/simple.ftl":"d63d7c62c225897d9f28f166c17e038b8f780dca9e9ee640e81360f23219a212","examples/simple-fallback.rs":"c61dc1a42b09bda3137bb72a08205db4630f47ce6faf9e0aceca4cade02422af","src/bundles.rs":"0696cff42b360fd018746d96136af2a3c38b7b3fdd681642168db8f915f729e3","src/cache.rs":"d0e886b95999120baf513d0438491c68cf37e9f99c515cdcf250ffc8f263f439","src/env.rs":"c11b27dcaf76a0f69d31007f8027cbdc6fb1330082afd28cf9f30aeb0352d127","src/errors.rs":"7424e9cc2cabc20cd987901a663671bfe063749547d271f47ddf67c3d12e1646","src/generator.rs":"f0c9f71baa3ef0e0f205692eb8719390234f7c4d609614b86969d69b8cee52de","src/lib.rs":"f8ee9e689af6d35faa8a2c49b73d3d41c6c27ac655ea0cce045d684e5c3307e4","src/localization.rs":"3fa84b81308e890d9a013e0b05cde7f7811e4f708ca5e5fa9e24ec67315de33c","src/pin_cell/README.md":"b230e479f0ce5de00ce6638aa47cdf1bd30a934df5f3ad33523c3b9f16ffb02b","src/pin_cell/mod.rs":"7247334eb4c6753babe8aeceacf1b36bdbbd60aed86754da61e09e87f1da24d1","src/pin_cell/pin_mut.rs":"116d0ac2353fbc4d2d1084610f90a9aa414b4607bb01595528025ed49889127c","src/pin_cell/pin_ref.rs":"e67ef14faf7d1d47e082732d3a5446e4ae78a25b9577f0819faa1705b236f01d","src/types.rs":"dbe93bf1cfec9b1e28612124c13d37cb0c1e1ba405ce4f4bd16cf3dde98cbb01","tests/localization_test.rs":"c98a27cf8fff60790a67447da584851201a4cadc51482bc81a8c950391513069","tests/resources/en-US/test.ftl":"1103dafb98582e728ddcd30b3fa8ffc1b9d4231cc86296f4e2d8865e9d40b25d","tests/resources/en-US/test2.ftl":"821c99ed74f57635e02877fccf6c2ac9e388997e646c850cd0f86cbd3238b490","tests/resources/pl/test.ftl":"5f7f7a9a8ef2c7175c2a9e2d68ff3748667e8ede877bb6b8a72337ac24e5dfeb","tests/resources/pl/test2.ftl":"68550e8e37adfb49c03a95e6b0a6501d58fbfb6e498cda00b52fc258758245b9"},"package":"08fdcccdeb6c01cb085f2bb3420506e6c67f025cee5db047529838c673a7d82b"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/fluent-fallback/CHANGELOG.md b/utshell-0.5.0/vendor/fluent-fallback/CHANGELOG.md new file mode 100644 index 00000000..1c6598c4 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/CHANGELOG.md @@ -0,0 +1,68 @@ +# Changelog + +## Unreleased + + - … + +## fluent-fallback 0.7.0 (Nov 9, 2022) + - The `ResourceId`s are now stored as a `HashSet` rather than as a Vec. Adding a + duplicate `ResourceId` is now a noop. + +## fluent-fallback 0.6.0 (Dec 17, 2021) + - Add `ResourceId` struct which allows fluent resources to be optional. + +## fluent-fallback 0.5.0 (Jul 8, 2021) + - Separate out `Bundles` for state management. + +## fluent-fallback 0.4.4 (May 3, 2021) + - Fix waiting from multiple tasks. (#224) + - Bind locale iterator generics of `LocalesProvider` and `BundleGenerator`. + +## fluent-fallback 0.4.3 (April 26, 2021) + - Align errors even closer to fluent.js + +## fluent-fallback 0.4.2 (April 9, 2021) + - Align errors closer to fluent.js + +## fluent-fallback 0.4.0 (February 9, 2021) + - Use `fluent-bundle` 0.15. + +## fluent-fallback 0.3.0 (February 3, 2021) + - Handle locale management in `Localization`. + +## fluent-fallback 0.2.2 (January 16, 2021) + - Invalidate bundles on resource list change. + +## fluent-fallback 0.2.1 (January 15, 2021) + - Add `Localization::is_sync` + +## fluent-fallback 0.2.0 (January 12, 2021) + - Separate `Sync` and `Async` bundle generators. + - Reorganize fallback logic. + - Separate out prefetching trait. + - Vendor in pin-cell. + +## fluent-fallback 0.1.0 (January 3, 2021) + - Update `fluent-bundle` to 0.14. + - Switch from `elsa` to `chunky-vec`. + - Add `Localization::with_generator`. + - Add support for Streamed bundles. + - Add `LocalizationError`. + - Make `L10nKey`, `L10nMessage` and `L10nAttribute` types. + +## fluent-fallback 0.0.4 (May 6, 2020) + - Update `fluent-bundle` to 0.12. + - Update `unic-langid` to 0.9. + +## fluent-fallback 0.0.3 (February 13, 2020) + - Update `fluent-bundle` to 0.10. + - Update `unic-langid` to 0.8. + +## fluent-fallback 0.0.2 (November 26, 2019) + - Update `fluent-bundle` to 0.9. + - Update `unic-langid` to 0.7. + +## fluent-fallback 0.0.1 (August 1, 2019) + + - This is the first release to be listed in the CHANGELOG. + - Basic support for language fallbacking and runtime locale changes. diff --git a/utshell-0.5.0/vendor/fluent-fallback/Cargo.lock b/utshell-0.5.0/vendor/fluent-fallback/Cargo.lock new file mode 100644 index 00000000..f16220d2 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/Cargo.lock @@ -0,0 +1,415 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "async-trait" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "chunky-vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7bdea464ae038f09197b82430b921c53619fc8d2bcaf7b151013b3ca008017" + +[[package]] +name = "displaydoc" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "fluent-bundle" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" +dependencies = [ + "fluent-langneg", + "fluent-syntax", + "intl-memoizer", + "intl_pluralrules", + "rustc-hash", + "self_cell", + "smallvec", + "unic-langid", +] + +[[package]] +name = "fluent-fallback" +version = "0.7.0" +dependencies = [ + "async-trait", + "chunky-vec", + "fluent-bundle", + "fluent-langneg", + "futures", + "once_cell", + "rustc-hash", + "tokio", + "unic-langid", +] + +[[package]] +name = "fluent-langneg" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94" +dependencies = [ + "unic-langid", +] + +[[package]] +name = "fluent-syntax" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" +dependencies = [ + "thiserror", +] + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "intl-memoizer" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" +dependencies = [ + "type-map", + "unic-langid", +] + +[[package]] +name = "intl_pluralrules" +version = "7.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" +dependencies = [ + "unic-langid", +] + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "self_cell" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinystr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2" +dependencies = [ + "displaydoc", +] + +[[package]] +name = "tokio" +version = "1.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +dependencies = [ + "autocfg", + "num_cpus", + "pin-project-lite", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "type-map" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "unic-langid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" +dependencies = [ + "unic-langid-impl", + "unic-langid-macros", +] + +[[package]] +name = "unic-langid-impl" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" +dependencies = [ + "tinystr", +] + +[[package]] +name = "unic-langid-macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055e618bf694161ffff0466d95cef3e1a5edc59f6ba1888e97801f2b4ebdc4fe" +dependencies = [ + "proc-macro-hack", + "tinystr", + "unic-langid-impl", + "unic-langid-macros-impl", +] + +[[package]] +name = "unic-langid-macros-impl" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8" +dependencies = [ + "proc-macro-hack", + "quote", + "syn", + "unic-langid-impl", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" diff --git a/utshell-0.5.0/vendor/fluent-fallback/Cargo.toml b/utshell-0.5.0/vendor/fluent-fallback/Cargo.toml new file mode 100644 index 00000000..105de939 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/Cargo.toml @@ -0,0 +1,74 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "fluent-fallback" +version = "0.7.0" +authors = [ + "Zibi Braniecki ", + "Staś Małolepszy ", +] +description = """ +High-level abstraction model for managing localization resources +and runtime localization lifecycle. +""" +homepage = "http://www.projectfluent.org" +readme = "README.md" +keywords = [ + "localization", + "l10n", + "i18n", + "intl", + "internationalization", +] +categories = [ + "localization", + "internationalization", +] +license = "Apache-2.0/MIT" +repository = "https://github.com/projectfluent/fluent-rs" +resolver = "1" + +[dependencies.async-trait] +version = "0.1" + +[dependencies.chunky-vec] +version = "0.1" + +[dependencies.fluent-bundle] +version = "0.15.2" + +[dependencies.futures] +version = "0.3" + +[dependencies.once_cell] +version = "1.9" + +[dependencies.rustc-hash] +version = "1" + +[dependencies.unic-langid] +version = "0.9" + +[dev-dependencies.fluent-langneg] +version = "0.13" + +[dev-dependencies.tokio] +version = "1.0" +features = [ + "rt-multi-thread", + "macros", +] + +[dev-dependencies.unic-langid] +version = "0.9" +features = ["macros"] diff --git a/utshell-0.5.0/vendor/fluent-fallback/LICENSE-APACHE b/utshell-0.5.0/vendor/fluent-fallback/LICENSE-APACHE new file mode 100644 index 00000000..35582f16 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Mozilla + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/fluent-fallback/LICENSE-MIT b/utshell-0.5.0/vendor/fluent-fallback/LICENSE-MIT new file mode 100644 index 00000000..5655fa31 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright 2017 Mozilla + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/utshell-0.5.0/vendor/fluent-fallback/README.md b/utshell-0.5.0/vendor/fluent-fallback/README.md new file mode 100644 index 00000000..25f9350f --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/README.md @@ -0,0 +1,102 @@ +# Fluent + +`fluent-fallback` is a Rust implementation of the [Project Fluent][] higher level API. + +The `Localization` struct encapsulates a persistant localization context providing +language fallbacking. The instance remains available throughout the whole life cycle of +the corresponding UI, reacting to events such as locale changes, resource updates etc. + +The API can be used directly, or can serve as an example of state manager for `fluent-bundle` and `fluent-resmgr`. + +[![crates.io](https://img.shields.io/crates/v/fluent-fallback.svg)](https://crates.io/crates/fluent-fallback) +[![Build and test](https://github.com/projectfluent/fluent-rs/workflows/Build%20and%20test/badge.svg)](https://github.com/projectfluent/fluent-rs/actions?query=branch%3Amaster+workflow%3A%22Build+and+test%22) +[![Coverage Status](https://coveralls.io/repos/github/projectfluent/fluent-rs/badge.svg?branch=master)](https://coveralls.io/github/projectfluent/fluent-rs?branch=master) + +Project Fluent keeps simple things simple and makes complex things possible. +The syntax used for describing translations is easy to read and understand. At +the same time it allows, when necessary, to represent complex concepts from +natural languages like gender, plurals, conjugations, and others. + +[Documentation][] + +[Project Fluent]: http://projectfluent.org +[Documentation]: https://docs.rs/fluent/ + +Usage +----- + +```rust +use fluent_fallback::Localization; + +fn main() { + // generate_messages is a closure that returns an iterator over FluentBundle + // instances. + let loc = Localization::new(vec!["simple.ftl".into()], generate_messages); + + let value = bundle.format_value("hello-world", None); + + assert_eq!(&value, "Hello, world!"); +} +``` + + +Status +------ + +The implementation is in its early stages and supports only some of the Project +Fluent's spec. Consult the [list of milestones][] for more information about +release planning and scope. + +[list of milestones]: https://github.com/projectfluent/fluent-rs/milestones + + +Local Development +----------------- + + cargo build + cargo test + cargo run --example simple-fallback + +When submitting a PR please use [`cargo fmt`][] (nightly). + +[`cargo fmt`]: https://github.com/rust-lang-nursery/rustfmt + + +Learn the FTL syntax +-------------------- + +FTL is a localization file format used for describing translation resources. +FTL stands for _Fluent Translation List_. + +FTL is designed to be simple to read, but at the same time allows to represent +complex concepts from natural languages like gender, plurals, conjugations, and +others. + + hello-user = Hello, { $username }! + +[Read the Fluent Syntax Guide][] in order to learn more about the syntax. If +you're a tool author you may be interested in the formal [EBNF grammar][]. + +[Read the Fluent Syntax Guide]: http://projectfluent.org/fluent/guide/ +[EBNF grammar]: https://github.com/projectfluent/fluent/tree/master/spec + + +Get Involved +------------ + +`fluent-rs` is open-source, licensed under the Apache License, Version 2.0. We +encourage everyone to take a look at our code and we'll listen to your +feedback. + + +Discuss +------- + +We'd love to hear your thoughts on Project Fluent! Whether you're a localizer +looking for a better way to express yourself in your language, or a developer +trying to make your app localizable and multilingual, or a hacker looking for +a project to contribute to, please do get in touch on the mailing list and the +IRC channel. + + - Discourse: https://discourse.mozilla.org/c/fluent + - IRC channel: [irc://irc.mozilla.org/l20n](irc://irc.mozilla.org/l20n) diff --git a/utshell-0.5.0/vendor/fluent-fallback/examples/resources/en-US/simple.ftl b/utshell-0.5.0/vendor/fluent-fallback/examples/resources/en-US/simple.ftl new file mode 100644 index 00000000..99f0a6bb --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/examples/resources/en-US/simple.ftl @@ -0,0 +1,7 @@ +missing-arg-error = Error: Please provide a number as argument. +input-parse-error = Error: Could not parse input `{ $input }`. Reason: { $reason } +response-msg = + { $value -> + [one] "{ $input }" has one Collatz step. + *[other] "{ $input }" has { $value } Collatz steps. + } diff --git a/utshell-0.5.0/vendor/fluent-fallback/examples/resources/pl/simple.ftl b/utshell-0.5.0/vendor/fluent-fallback/examples/resources/pl/simple.ftl new file mode 100644 index 00000000..16173dd9 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/examples/resources/pl/simple.ftl @@ -0,0 +1,8 @@ +missing-arg-error = Błąd: Proszę wprowadzić liczbę jako argument. +input-parse-error = Błąd: Nie udało się sparsować `{ $input }`. Powód: { $reason } +response-msg = + { $value -> + [one] "{ $input }" ma jeden krok Collatza. + [few] "{ $input }" ma { $value } kroki Collatza. + *[many] "{ $input }" ma { $value } kroków Collatza. + } diff --git a/utshell-0.5.0/vendor/fluent-fallback/examples/simple-fallback.rs b/utshell-0.5.0/vendor/fluent-fallback/examples/simple-fallback.rs new file mode 100644 index 00000000..efdc04af --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/examples/simple-fallback.rs @@ -0,0 +1,237 @@ +//! This is an example of a simple application +//! which calculates the Collatz conjecture. +//! +//! The function itself is trivial on purpose, +//! so that we can focus on understanding how +//! the application can be made localizable +//! via Fluent. +//! +//! To try the app launch `cargo run --example simple-fallback NUM (LOCALES)` +//! +//! NUM is a number to be calculated, and LOCALES is an optional +//! parameter with a comma-separated list of locales requested by the user. +//! +//! Example: +//! +//! cargo run --example simple-fallback 123 de,pl +//! +//! If the second argument is omitted, `en-US` locale is used as the +//! default one. + +use std::{env, fs, io, path::PathBuf, str::FromStr}; + +use fluent_bundle::{FluentArgs, FluentBundle, FluentResource}; +use fluent_fallback::{ + generator::{BundleGenerator, FluentBundleResult}, + types::ResourceId, + Localization, +}; +use fluent_langneg::{negotiate_languages, NegotiationStrategy}; + +use rustc_hash::FxHashSet; +use unic_langid::{langid, LanguageIdentifier}; + +/// This helper struct holds the scheme for converting +/// resource paths into full paths. It is used to customise +/// `fluent-fallback::SyncLocalization`. +struct Bundles { + res_path_scheme: PathBuf, +} + +/// This helper function allows us to read the list +/// of available locales by reading the list of +/// directories in `./examples/resources`. +/// +/// It is expected that every directory inside it +/// has a name that is a valid BCP47 language tag. +fn get_available_locales() -> io::Result> { + let mut dir = env::current_dir()?; + if dir.to_string_lossy().ends_with("fluent-rs") { + dir.push("fluent-fallback"); + } + dir.push("examples"); + dir.push("resources"); + let res_dir = fs::read_dir(dir)?; + + let locales = res_dir + .into_iter() + .filter_map(|entry| entry.ok()) + .filter(|entry| entry.path().is_dir()) + .filter_map(|dir| { + let file_name = dir.file_name(); + let name = file_name.to_str()?; + Some(name.parse().expect("Parsing failed.")) + }) + .collect(); + Ok(locales) +} + +fn resolve_app_locales<'l>(args: &[String]) -> Vec { + let default_locale = langid!("en-US"); + let available = get_available_locales().expect("Retrieving available locales failed."); + + let requested: Vec = args.get(2).map_or(vec![], |arg| { + arg.split(",") + .map(|s| s.parse().expect("Parsing locale failed.")) + .collect() + }); + + negotiate_languages( + &requested, + &available, + Some(&default_locale), + NegotiationStrategy::Filtering, + ) + .into_iter() + .cloned() + .collect() +} + +fn get_resource_manager() -> Bundles { + let mut res_path_scheme = env::current_dir().expect("Failed to retrieve current dir."); + + if res_path_scheme.to_string_lossy().ends_with("fluent-rs") { + res_path_scheme.push("fluent-fallback"); + } + res_path_scheme.push("examples"); + res_path_scheme.push("resources"); + + res_path_scheme.push("{locale}"); + res_path_scheme.push("{res_id}"); + + Bundles { res_path_scheme } +} + +static L10N_RESOURCES: &[&str] = &["simple.ftl"]; + +fn main() { + let args: Vec = env::args().collect(); + + let app_locales: Vec = resolve_app_locales(&args); + + let bundles = get_resource_manager(); + + let loc = Localization::with_env( + L10N_RESOURCES.iter().map(|&res| res.into()), + true, + app_locales, + bundles, + ); + let bundles = loc.bundles(); + + let mut errors = vec![]; + + match args.get(1) { + Some(input) => match isize::from_str(&input) { + Ok(i) => { + let mut args = FluentArgs::new(); + args.set("input", i); + args.set("value", collatz(i)); + let value = bundles + .format_value_sync("response-msg", Some(&args), &mut errors) + .unwrap() + .unwrap(); + println!("{}", value); + } + Err(err) => { + let mut args = FluentArgs::new(); + args.set("input", input.as_str()); + args.set("reason", err.to_string()); + let value = bundles + .format_value_sync("input-parse-error-msg", Some(&args), &mut errors) + .unwrap() + .unwrap(); + println!("{}", value); + } + }, + None => { + let value = bundles + .format_value_sync("missing-arg-error", None, &mut errors) + .unwrap() + .unwrap(); + println!("{}", value); + } + } +} + +/// Collatz conjecture calculating function. +fn collatz(n: isize) -> isize { + match n { + 1 => 0, + _ => match n % 2 { + 0 => 1 + collatz(n / 2), + _ => 1 + collatz(n * 3 + 1), + }, + } +} + +/// Bundle iterator used by BundleGeneratorSync implementation for Locales. +struct BundleIter { + res_path_scheme: String, + locales: as IntoIterator>::IntoIter, + res_ids: FxHashSet, +} + +impl Iterator for BundleIter { + type Item = FluentBundleResult; + + fn next(&mut self) -> Option { + let locale = self.locales.next()?; + let res_path_scheme = self + .res_path_scheme + .as_str() + .replace("{locale}", &locale.to_string()); + let mut bundle = FluentBundle::new(vec![locale]); + + let mut errors = vec![]; + + for res_id in &self.res_ids { + let res_path = res_path_scheme.as_str().replace("{res_id}", &res_id.value); + let source = fs::read_to_string(res_path).unwrap(); + let res = match FluentResource::try_new(source) { + Ok(res) => res, + Err((res, err)) => { + errors.extend(err.into_iter().map(Into::into)); + res + } + }; + bundle.add_resource(res).unwrap(); + } + + if errors.is_empty() { + Some(Ok(bundle)) + } else { + Some(Err((bundle, errors))) + } + } +} + +impl futures::Stream for BundleIter { + type Item = FluentBundleResult; + + fn poll_next( + self: std::pin::Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + todo!() + } +} + +impl BundleGenerator for Bundles { + type Resource = FluentResource; + type LocalesIter = std::vec::IntoIter; + type Iter = BundleIter; + type Stream = BundleIter; + + fn bundles_iter( + &self, + locales: std::vec::IntoIter, + res_ids: FxHashSet, + ) -> Self::Iter { + BundleIter { + res_path_scheme: self.res_path_scheme.to_string_lossy().to_string(), + locales, + res_ids, + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/bundles.rs b/utshell-0.5.0/vendor/fluent-fallback/src/bundles.rs new file mode 100644 index 00000000..7ab726d6 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/bundles.rs @@ -0,0 +1,426 @@ +use crate::{ + cache::{AsyncCache, Cache}, + env::LocalesProvider, + errors::LocalizationError, + generator::{BundleGenerator, BundleIterator, BundleStream}, + types::{L10nAttribute, L10nKey, L10nMessage, ResourceId}, +}; +use fluent_bundle::{FluentArgs, FluentBundle, FluentError}; +use rustc_hash::FxHashSet; +use std::borrow::Cow; + +pub enum BundlesInner +where + G: BundleGenerator, +{ + Iter(Cache), + Stream(AsyncCache), +} + +pub struct Bundles(BundlesInner) +where + G: BundleGenerator; + +impl Bundles +where + G: BundleGenerator, + G::Iter: BundleIterator, +{ + pub fn prefetch_sync(&self) { + match &self.0 { + BundlesInner::Iter(iter) => iter.prefetch(), + BundlesInner::Stream(_) => panic!("Can't prefetch a sync bundle set asynchronously"), + } + } +} + +impl Bundles +where + G: BundleGenerator, + G::Stream: BundleStream, +{ + pub async fn prefetch_async(&self) { + match &self.0 { + BundlesInner::Iter(_) => panic!("Can't prefetch a async bundle set synchronously"), + BundlesInner::Stream(stream) => stream.prefetch().await, + } + } +} + +impl Bundles +where + G: BundleGenerator, +{ + pub fn new

(sync: bool, res_ids: FxHashSet, generator: &G, provider: &P) -> Self + where + G: BundleGenerator, + P: LocalesProvider, + { + Self(if sync { + BundlesInner::Iter(Cache::new( + generator.bundles_iter(provider.locales(), res_ids), + )) + } else { + BundlesInner::Stream(AsyncCache::new( + generator.bundles_stream(provider.locales(), res_ids), + )) + }) + } + + pub async fn format_value<'l>( + &'l self, + id: &'l str, + args: Option<&'l FluentArgs<'_>>, + errors: &mut Vec, + ) -> Option> { + match &self.0 { + BundlesInner::Iter(cache) => Self::format_value_from_iter(cache, id, args, errors), + BundlesInner::Stream(stream) => { + Self::format_value_from_stream(stream, id, args, errors).await + } + } + } + + pub async fn format_values<'l>( + &'l self, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Vec>> { + match &self.0 { + BundlesInner::Iter(cache) => Self::format_values_from_iter(cache, keys, errors), + BundlesInner::Stream(stream) => { + Self::format_values_from_stream(stream, keys, errors).await + } + } + } + + pub async fn format_messages<'l>( + &'l self, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Vec>> { + match &self.0 { + BundlesInner::Iter(cache) => Self::format_messages_from_iter(cache, keys, errors), + BundlesInner::Stream(stream) => { + Self::format_messages_from_stream(stream, keys, errors).await + } + } + } + + pub fn format_value_sync<'l>( + &'l self, + id: &'l str, + args: Option<&'l FluentArgs>, + errors: &mut Vec, + ) -> Result>, LocalizationError> { + match &self.0 { + BundlesInner::Iter(cache) => Ok(Self::format_value_from_iter(cache, id, args, errors)), + BundlesInner::Stream(_) => Err(LocalizationError::SyncRequestInAsyncMode), + } + } + + pub fn format_values_sync<'l>( + &'l self, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Result>>, LocalizationError> { + match &self.0 { + BundlesInner::Iter(cache) => Ok(Self::format_values_from_iter(cache, keys, errors)), + BundlesInner::Stream(_) => Err(LocalizationError::SyncRequestInAsyncMode), + } + } + + pub fn format_messages_sync<'l>( + &'l self, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Result>>, LocalizationError> { + match &self.0 { + BundlesInner::Iter(cache) => Ok(Self::format_messages_from_iter(cache, keys, errors)), + BundlesInner::Stream(_) => Err(LocalizationError::SyncRequestInAsyncMode), + } + } +} + +macro_rules! format_value_from_inner { + ($step:expr, $id:expr, $args:expr, $errors:expr) => { + let mut found_message = false; + + while let Some(bundle) = $step { + let bundle = bundle.as_ref().unwrap_or_else(|(bundle, err)| { + $errors.extend(err.iter().cloned().map(Into::into)); + bundle + }); + + if let Some(msg) = bundle.get_message($id) { + found_message = true; + if let Some(value) = msg.value() { + let mut format_errors = vec![]; + let result = bundle.format_pattern(value, $args, &mut format_errors); + if !format_errors.is_empty() { + $errors.push(LocalizationError::Resolver { + id: $id.to_string(), + locale: bundle.locales[0].clone(), + errors: format_errors, + }); + } + return Some(result); + } else { + $errors.push(LocalizationError::MissingValue { + id: $id.to_string(), + locale: Some(bundle.locales[0].clone()), + }); + } + } else { + $errors.push(LocalizationError::MissingMessage { + id: $id.to_string(), + locale: Some(bundle.locales[0].clone()), + }); + } + } + if found_message { + $errors.push(LocalizationError::MissingValue { + id: $id.to_string(), + locale: None, + }); + } else { + $errors.push(LocalizationError::MissingMessage { + id: $id.to_string(), + locale: None, + }); + } + return None; + }; +} + +#[derive(Clone)] +enum Value<'l> { + Present(Cow<'l, str>), + Missing, + None, +} + +macro_rules! format_values_from_inner { + ($step:expr, $keys:expr, $errors:expr) => { + let mut cells = vec![Value::None; $keys.len()]; + + while let Some(bundle) = $step { + let bundle = bundle.as_ref().unwrap_or_else(|(bundle, err)| { + $errors.extend(err.iter().cloned().map(Into::into)); + bundle + }); + + let mut has_missing = false; + + for (key, cell) in $keys + .iter() + .zip(&mut cells) + .filter(|(_, cell)| !matches!(cell, Value::Present(_))) + { + if let Some(msg) = bundle.get_message(&key.id) { + if let Some(value) = msg.value() { + let mut format_errors = vec![]; + *cell = Value::Present(bundle.format_pattern( + value, + key.args.as_ref(), + &mut format_errors, + )); + if !format_errors.is_empty() { + $errors.push(LocalizationError::Resolver { + id: key.id.to_string(), + locale: bundle.locales[0].clone(), + errors: format_errors, + }); + } + } else { + *cell = Value::Missing; + has_missing = true; + $errors.push(LocalizationError::MissingValue { + id: key.id.to_string(), + locale: Some(bundle.locales[0].clone()), + }); + } + } else { + has_missing = true; + $errors.push(LocalizationError::MissingMessage { + id: key.id.to_string(), + locale: Some(bundle.locales[0].clone()), + }); + } + } + if !has_missing { + break; + } + } + + return $keys + .iter() + .zip(cells) + .map(|(key, value)| match value { + Value::Present(value) => Some(value), + Value::Missing => { + $errors.push(LocalizationError::MissingValue { + id: key.id.to_string(), + locale: None, + }); + None + } + Value::None => { + $errors.push(LocalizationError::MissingMessage { + id: key.id.to_string(), + locale: None, + }); + None + } + }) + .collect(); + }; +} + +macro_rules! format_messages_from_inner { + ($step:expr, $keys:expr, $errors:expr) => { + let mut result = vec![None; $keys.len()]; + + let mut is_complete = false; + + while let Some(bundle) = $step { + let bundle = bundle.as_ref().unwrap_or_else(|(bundle, err)| { + $errors.extend(err.iter().cloned().map(Into::into)); + bundle + }); + + let mut has_missing = false; + for (key, cell) in $keys + .iter() + .zip(&mut result) + .filter(|(_, cell)| cell.is_none()) + { + let mut format_errors = vec![]; + let msg = Self::format_message_from_bundle(bundle, key, &mut format_errors); + + if msg.is_none() { + has_missing = true; + $errors.push(LocalizationError::MissingMessage { + id: key.id.to_string(), + locale: Some(bundle.locales[0].clone()), + }); + } else if !format_errors.is_empty() { + $errors.push(LocalizationError::Resolver { + id: key.id.to_string(), + locale: bundle.locales.get(0).cloned().unwrap(), + errors: format_errors, + }); + } + + *cell = msg; + } + if !has_missing { + is_complete = true; + break; + } + } + + if !is_complete { + for (key, _) in $keys + .iter() + .zip(&mut result) + .filter(|(_, cell)| cell.is_none()) + { + $errors.push(LocalizationError::MissingMessage { + id: key.id.to_string(), + locale: None, + }); + } + } + + return result; + }; +} + +impl Bundles +where + G: BundleGenerator, +{ + fn format_value_from_iter<'l>( + cache: &'l Cache, + id: &'l str, + args: Option<&'l FluentArgs>, + errors: &mut Vec, + ) -> Option> { + let mut bundle_iter = cache.into_iter(); + format_value_from_inner!(bundle_iter.next(), id, args, errors); + } + + async fn format_value_from_stream<'l>( + stream: &'l AsyncCache, + id: &'l str, + args: Option<&'l FluentArgs<'_>>, + errors: &mut Vec, + ) -> Option> { + use futures::StreamExt; + + let mut bundle_stream = stream.stream(); + format_value_from_inner!(bundle_stream.next().await, id, args, errors); + } + + async fn format_messages_from_stream<'l>( + stream: &'l AsyncCache, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Vec>> { + use futures::StreamExt; + let mut bundle_stream = stream.stream(); + format_messages_from_inner!(bundle_stream.next().await, keys, errors); + } + + async fn format_values_from_stream<'l>( + stream: &'l AsyncCache, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Vec>> { + use futures::StreamExt; + let mut bundle_stream = stream.stream(); + + format_values_from_inner!(bundle_stream.next().await, keys, errors); + } + + fn format_message_from_bundle<'l>( + bundle: &'l FluentBundle, + key: &'l L10nKey, + format_errors: &mut Vec, + ) -> Option> { + let msg = bundle.get_message(&key.id)?; + let value = msg + .value() + .map(|pattern| bundle.format_pattern(pattern, key.args.as_ref(), format_errors)); + let attributes = msg + .attributes() + .map(|attr| { + let value = bundle.format_pattern(attr.value(), key.args.as_ref(), format_errors); + L10nAttribute { + name: attr.id().into(), + value, + } + }) + .collect(); + Some(L10nMessage { value, attributes }) + } + + fn format_messages_from_iter<'l>( + cache: &'l Cache, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Vec>> { + let mut bundle_iter = cache.into_iter(); + format_messages_from_inner!(bundle_iter.next(), keys, errors); + } + + fn format_values_from_iter<'l>( + cache: &'l Cache, + keys: &'l [L10nKey<'l>], + errors: &mut Vec, + ) -> Vec>> { + let mut bundle_iter = cache.into_iter(); + format_values_from_inner!(bundle_iter.next(), keys, errors); + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/cache.rs b/utshell-0.5.0/vendor/fluent-fallback/src/cache.rs new file mode 100644 index 00000000..32bc33fa --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/cache.rs @@ -0,0 +1,253 @@ +use std::{ + cell::{RefCell, UnsafeCell}, + cmp::Ordering, + pin::Pin, + task::Context, + task::Poll, + task::Waker, +}; + +use crate::generator::{BundleIterator, BundleStream}; +use crate::pin_cell::{PinCell, PinMut}; +use chunky_vec::ChunkyVec; +use futures::{ready, Stream}; + +pub struct Cache +where + I: Iterator, +{ + iter: RefCell, + items: UnsafeCell>, + res: std::marker::PhantomData, +} + +impl Cache +where + I: Iterator, +{ + pub fn new(iter: I) -> Self { + Self { + iter: RefCell::new(iter), + items: Default::default(), + res: std::marker::PhantomData, + } + } + + pub fn len(&self) -> usize { + unsafe { + let items = self.items.get(); + (*items).len() + } + } + + pub fn get(&self, index: usize) -> Option<&I::Item> { + unsafe { + let items = self.items.get(); + (*items).get(index) + } + } + + /// Push, immediately getting a reference to the element + pub fn push_get(&self, new_value: I::Item) -> &I::Item { + unsafe { + let items = self.items.get(); + (*items).push_get(new_value) + } + } +} + +impl Cache +where + I: BundleIterator + Iterator, +{ + pub fn prefetch(&self) { + self.iter.borrow_mut().prefetch_sync(); + } +} + +pub struct CacheIter<'a, I, R> +where + I: Iterator, +{ + cache: &'a Cache, + curr: usize, +} + +impl<'a, I, R> Iterator for CacheIter<'a, I, R> +where + I: Iterator, +{ + type Item = &'a I::Item; + + fn next(&mut self) -> Option { + let cache_len = self.cache.len(); + match self.curr.cmp(&cache_len) { + Ordering::Less => { + // Cached value + self.curr += 1; + self.cache.get(self.curr - 1) + } + Ordering::Equal => { + // Get the next item from the iterator + let item = self.cache.iter.borrow_mut().next(); + self.curr += 1; + if let Some(item) = item { + Some(self.cache.push_get(item)) + } else { + None + } + } + Ordering::Greater => { + // Ran off the end of the cache + None + } + } + } +} + +impl<'a, I, R> IntoIterator for &'a Cache +where + I: Iterator, +{ + type Item = &'a I::Item; + type IntoIter = CacheIter<'a, I, R>; + + fn into_iter(self) -> Self::IntoIter { + CacheIter { + cache: self, + curr: 0, + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +pub struct AsyncCache +where + S: Stream, +{ + stream: PinCell, + items: UnsafeCell>, + // TODO: Should probably be an SmallVec<[Waker; 1]> or something? I guess + // multiple pending wakes are not really all that common. + pending_wakes: RefCell>, + res: std::marker::PhantomData, +} + +impl AsyncCache +where + S: Stream, +{ + pub fn new(stream: S) -> Self { + Self { + stream: PinCell::new(stream), + items: Default::default(), + pending_wakes: Default::default(), + res: std::marker::PhantomData, + } + } + + pub fn len(&self) -> usize { + unsafe { + let items = self.items.get(); + (*items).len() + } + } + + pub fn get(&self, index: usize) -> Poll> { + unsafe { + let items = self.items.get(); + (*items).get(index).into() + } + } + + /// Push, immediately getting a reference to the element + pub fn push_get(&self, new_value: S::Item) -> &S::Item { + unsafe { + let items = self.items.get(); + (*items).push_get(new_value) + } + } + + pub fn stream(&self) -> AsyncCacheStream<'_, S, R> { + AsyncCacheStream { + cache: self, + curr: 0, + } + } +} + +impl AsyncCache +where + S: BundleStream + Stream, +{ + pub async fn prefetch(&self) { + let pin = unsafe { Pin::new_unchecked(&self.stream) }; + unsafe { PinMut::as_mut(&mut pin.borrow_mut()).get_unchecked_mut() } + .prefetch_async() + .await + } +} + +impl AsyncCache +where + S: Stream, +{ + // Helper function that gets the next value from wrapped stream. + fn poll_next_item(&self, cx: &mut Context<'_>) -> Poll> { + let pin = unsafe { Pin::new_unchecked(&self.stream) }; + let poll = PinMut::as_mut(&mut pin.borrow_mut()).poll_next(cx); + if poll.is_ready() { + let wakers = std::mem::take(&mut *self.pending_wakes.borrow_mut()); + for waker in wakers { + waker.wake(); + } + } else { + self.pending_wakes.borrow_mut().push(cx.waker().clone()); + } + poll + } +} + +pub struct AsyncCacheStream<'a, S, R> +where + S: Stream, +{ + cache: &'a AsyncCache, + curr: usize, +} + +impl<'a, S, R> Stream for AsyncCacheStream<'a, S, R> +where + S: Stream, +{ + type Item = &'a S::Item; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let cache_len = self.cache.len(); + match self.curr.cmp(&cache_len) { + Ordering::Less => { + // Cached value + self.curr += 1; + self.cache.get(self.curr - 1) + } + Ordering::Equal => { + // Get the next item from the stream + let item = ready!(self.cache.poll_next_item(cx)); + self.curr += 1; + if let Some(item) = item { + Some(self.cache.push_get(item)).into() + } else { + None.into() + } + } + Ordering::Greater => { + // Ran off the end of the cache + None.into() + } + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/env.rs b/utshell-0.5.0/vendor/fluent-fallback/src/env.rs new file mode 100644 index 00000000..cf340fcf --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/env.rs @@ -0,0 +1,84 @@ +//! Traits required to provide environment driven data for [`Localization`](crate::Localization). +//! +//! Since [`Localization`](crate::Localization) is a long-lived structure, +//! the model in which the user provides ability for the system to react to changes +//! is by implementing the given environmental trait and triggering +//! [`Localization::on_change`](crate::Localization::on_change) method. +//! +//! At the moment just a single trait is provided, which allows the +//! environment to feed a selection of locales to be provided to the instance. +//! +//! The locales provided to [`Localization`](crate::Localization) should be +//! already negotiated to ensure that the resources in those locales +//! are available. The list should also be sorted according to the user +//! preference, as the order is significant for how [`Localization`](crate::Localization) performs +//! fallbacking. +use unic_langid::LanguageIdentifier; + +/// A trait used to provide a selection of locales to be used by the +/// [`Localization`](crate::Localization) instance for runtime +/// locale fallbacking. +/// +/// # Example +/// ``` +/// use fluent_fallback::{Localization, env::LocalesProvider}; +/// use fluent_resmgr::ResourceManager; +/// use unic_langid::LanguageIdentifier; +/// use std::{ +/// rc::Rc, +/// cell::RefCell +/// }; +/// +/// #[derive(Clone)] +/// struct Env { +/// locales: Rc>>, +/// } +/// +/// impl Env { +/// pub fn new(locales: Vec) -> Self { +/// Self { locales: Rc::new(RefCell::new(locales)) } +/// } +/// +/// pub fn set_locales(&mut self, new_locales: Vec) { +/// let mut locales = self.locales.borrow_mut(); +/// locales.clear(); +/// locales.extend(new_locales); +/// } +/// } +/// +/// impl LocalesProvider for Env { +/// type Iter = as IntoIterator>::IntoIter; +/// fn locales(&self) -> Self::Iter { +/// self.locales.borrow().clone().into_iter() +/// } +/// } +/// +/// let res_mgr = ResourceManager::new("./path/{locale}/".to_string()); +/// +/// let mut env = Env::new(vec![ +/// "en-GB".parse().unwrap() +/// ]); +/// +/// let mut loc = Localization::with_env(vec![], true, env.clone(), res_mgr); +/// +/// env.set_locales(vec![ +/// "de".parse().unwrap(), +/// "en-GB".parse().unwrap(), +/// ]); +/// +/// loc.on_change(); +/// +/// // The next format call will attempt to localize to `de` first and +/// // fallback on `en-GB`. +/// ``` +pub trait LocalesProvider { + type Iter: Iterator; + fn locales(&self) -> Self::Iter; +} + +impl LocalesProvider for Vec { + type Iter = as IntoIterator>::IntoIter; + fn locales(&self) -> Self::Iter { + self.clone().into_iter() + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/errors.rs b/utshell-0.5.0/vendor/fluent-fallback/src/errors.rs new file mode 100644 index 00000000..9170fb1c --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/errors.rs @@ -0,0 +1,71 @@ +use fluent_bundle::FluentError; +use std::error::Error; +use unic_langid::LanguageIdentifier; + +#[derive(Debug, PartialEq)] +pub enum LocalizationError { + Bundle { + error: FluentError, + }, + Resolver { + id: String, + locale: LanguageIdentifier, + errors: Vec, + }, + MissingMessage { + id: String, + locale: Option, + }, + MissingValue { + id: String, + locale: Option, + }, + SyncRequestInAsyncMode, +} + +impl From for LocalizationError { + fn from(error: FluentError) -> Self { + Self::Bundle { error } + } +} + +impl std::fmt::Display for LocalizationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Bundle { error } => write!(f, "[fluent][bundle] error: {}", error), + Self::Resolver { id, locale, errors } => { + let errors: Vec = errors.iter().map(|err| err.to_string()).collect(); + write!( + f, + "[fluent][resolver] errors in {}/{}: {}", + locale, + id, + errors.join(", ") + ) + } + Self::MissingMessage { + id, + locale: Some(locale), + } => write!(f, "[fluent] Missing message in locale {}: {}", locale, id), + Self::MissingMessage { id, locale: None } => { + write!(f, "[fluent] Couldn't find a message: {}", id) + } + Self::MissingValue { + id, + locale: Some(locale), + } => write!( + f, + "[fluent] Message has no value in locale {}: {}", + locale, id + ), + Self::MissingValue { id, locale: None } => { + write!(f, "[fluent] Couldn't find a message with value: {}", id) + } + Self::SyncRequestInAsyncMode => { + write!(f, "Triggered synchronous format while in async mode") + } + } + } +} + +impl Error for LocalizationError {} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/generator.rs b/utshell-0.5.0/vendor/fluent-fallback/src/generator.rs new file mode 100644 index 00000000..f13af63c --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/generator.rs @@ -0,0 +1,41 @@ +use fluent_bundle::{FluentBundle, FluentError, FluentResource}; +use futures::Stream; +use rustc_hash::FxHashSet; +use std::borrow::Borrow; +use unic_langid::LanguageIdentifier; + +use crate::types::ResourceId; + +pub type FluentBundleResult = Result, (FluentBundle, Vec)>; + +pub trait BundleIterator { + fn prefetch_sync(&mut self) {} +} + +#[async_trait::async_trait(?Send)] +pub trait BundleStream { + async fn prefetch_async(&mut self) {} +} + +pub trait BundleGenerator { + type Resource: Borrow; + type LocalesIter: Iterator; + type Iter: Iterator>; + type Stream: Stream>; + + fn bundles_iter( + &self, + _locales: Self::LocalesIter, + _res_ids: FxHashSet, + ) -> Self::Iter { + unimplemented!(); + } + + fn bundles_stream( + &self, + _locales: Self::LocalesIter, + _res_ids: FxHashSet, + ) -> Self::Stream { + unimplemented!(); + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/lib.rs b/utshell-0.5.0/vendor/fluent-fallback/src/lib.rs new file mode 100644 index 00000000..9dbadc5b --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/lib.rs @@ -0,0 +1,118 @@ +//! Fluent is a modern localization system designed to improve how software is translated. +//! +//! `fluent-fallback` is a high-level component of the [Fluent Localization +//! System](https://www.projectfluent.org). +//! +//! The crate builds on top of the mid-level [`fluent-bundle`](../fluent-bundle) package, and provides an ergonomic API for highly flexible localization. +//! +//! The functionality of this level is complete, but the API itself is in the +//! early stages and the goal of being ergonomic is yet to be achieved. +//! +//! If the user is willing to work through the challenge of setting up the +//! boiler-plate that will eventually go away, `fluent-fallback` provides +//! a powerful abstraction around [`FluentBundle`](fluent_bundle::FluentBundle) coupled +//! with a localization resource management system. +//! +//! The main struct, [`Localization`], is a long-lived, reactive, multi-lingual +//! struct which allows for strong error recovery and locale +//! fallbacking, exposing synchronous and asynchronous ergonomic methods +//! for [`L10nMessage`](types::L10nMessage) retrieval. +//! +//! [`Localization`] is also an API that is to be used when designing bindings +//! to user interface systems, such as DOM, React, and others. +//! +//! # Example +//! +//! ``` +//! use fluent_fallback::{Localization, types::{ResourceType, ToResourceId}}; +//! use fluent_resmgr::ResourceManager; +//! use unic_langid::langid; +//! +//! let res_mgr = ResourceManager::new("./tests/resources/{locale}/".to_string()); +//! +//! let loc = Localization::with_env( +//! vec![ +//! "test.ftl".into(), +//! "test2.ftl".to_resource_id(ResourceType::Optional), +//! ], +//! true, +//! vec![langid!("en-US")], +//! res_mgr, +//! ); +//! let bundles = loc.bundles(); +//! +//! let mut errors = vec![]; +//! let value = bundles.format_value_sync("hello-world", None, &mut errors) +//! .expect("Failed to format a value"); +//! +//! assert_eq!(value, Some("Hello World [en]".into())); +//! ``` +//! +//! The above example is far from the ergonomical API style the Fluent project +//! is aiming for, but it represents the full scope of functionality intended +//! for the model. +//! +//! # Resource Management +//! +//! Resource management is one of the most complicated parts of a localization system. +//! In particular, modern software may have needs for both synchronous +//! and asynchronous I/O. That, in turn has a large impact on what can happen +//! in case of missing resources, or errors. +//! +//! Resource identifiers can refer to resources that are either required or optional. +//! In the above example, `"test.ftl"` is a required resource (the default using `.into()`), +//! and `"test2.ftl" is an optional resource, which you can create via the +//! [`ToResourceId`](fluent_fallback::types::ToResourceId) trait. +//! +//! A required resource must be present in order for the a bundle to be considered valid. +//! If a required resource is missing for a given locale, a bundle will not be generated for that locale. +//! +//! A bundle is still considered valid if an optional resource is missing. A bundle will still be generated +//! and the entries for the missing optional resource will simply be missing from the bundle. This should be +//! used sparingly in exceptional cases where you do not want `Localization` to fall back to the next +//! locale if there is a missing resource. Marking all resources as optional will increase the state space +//! that the solver has to search through, and will have a negative impact on performance. +//! +//! Currently, [`Localization`] can be specialized over an implementation of +//! [`generator::BundleGenerator`] trait which provides a method to generate an +//! [`Iterator`] and [`Stream`](futures::stream::Stream). +//! +//! This is not very elegant and will likely be improved in the future, but for the time being, if +//! the customer doesn't need one of the modes, the unnecessary method should use the +//! `unimplemented!()` macro as its body. +//! +//! `fluent-resmgr` provides a simple resource manager which handles synchronous I/O +//! and uses local file system to store resources in a directory structure. +//! +//! That model is often sufficient and the user can either use `fluent-resmgr` or write +//! a similar API to provide the generator for [`Localization`]. +//! +//! Alternatively, a much more sophisticated resource manager can be used. Mozilla +//! for its needs in Firefox uses [`L10nRegistry`](https://github.com/zbraniecki/l10nregistry-rs) +//! library which implements [`BundleGenerator`](generator::BundleGenerator). +//! +//! # Locale Management +//! +//! As a long lived structure, the [`Localization`] is intended to handle runtime locale +//! management. +//! +//! In the example above, [`Vec`](unic_langid::LanguageIdentifier) +//! provides a static list of locales that the [`Localization`] handles, but that's just the +//! simplest implementation of the [`env::LocalesProvider`], and one can implement +//! a much more sophisticated one that reacts to user or environment driven changes, and +//! called [`Localization::on_change`] to trigger a new locales to be used for the +//! next translation request. +//! +//! See [`env::LocalesProvider`] trait for an example of a reactive system implementation. +mod bundles; +mod cache; +pub mod env; +mod errors; +pub mod generator; +mod localization; +mod pin_cell; +pub mod types; + +pub use bundles::Bundles; +pub use errors::LocalizationError; +pub use localization::Localization; diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/localization.rs b/utshell-0.5.0/vendor/fluent-fallback/src/localization.rs new file mode 100644 index 00000000..5424bcf3 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/localization.rs @@ -0,0 +1,137 @@ +use crate::{ + bundles::Bundles, + env::LocalesProvider, + generator::{BundleGenerator, BundleIterator, BundleStream}, + types::ResourceId, +}; +use once_cell::sync::OnceCell; +use rustc_hash::FxHashSet; +use std::rc::Rc; + +pub struct Localization +where + G: BundleGenerator, + P: LocalesProvider, +{ + bundles: OnceCell>>, + generator: G, + provider: P, + sync: bool, + res_ids: FxHashSet, +} + +impl Localization +where + G: BundleGenerator + Default, + P: LocalesProvider + Default, +{ + pub fn new(res_ids: I, sync: bool) -> Self + where + I: IntoIterator, + { + Self { + bundles: OnceCell::new(), + generator: G::default(), + provider: P::default(), + sync, + res_ids: FxHashSet::from_iter(res_ids.into_iter()), + } + } +} + +impl Localization +where + G: BundleGenerator, + P: LocalesProvider, +{ + pub fn with_env(res_ids: I, sync: bool, provider: P, generator: G) -> Self + where + I: IntoIterator, + { + Self { + bundles: OnceCell::new(), + generator, + provider, + sync, + res_ids: FxHashSet::from_iter(res_ids.into_iter()), + } + } + + pub fn is_sync(&self) -> bool { + self.sync + } + + pub fn add_resource_id>(&mut self, res_id: T) { + self.res_ids.insert(res_id.into()); + self.on_change(); + } + + pub fn add_resource_ids(&mut self, res_ids: Vec) { + self.res_ids.extend(res_ids); + self.on_change(); + } + + pub fn remove_resource_id>(&mut self, res_id: T) -> usize { + self.res_ids.retain(|x| !res_id.eq(x)); + self.on_change(); + self.res_ids.len() + } + + pub fn remove_resource_ids(&mut self, res_ids: Vec) -> usize { + self.res_ids.retain(|x| !res_ids.contains(x)); + self.on_change(); + self.res_ids.len() + } + + pub fn set_async(&mut self) { + if self.sync { + self.sync = false; + self.on_change(); + } + } + + pub fn on_change(&mut self) { + self.bundles.take(); + } +} + +impl Localization +where + G: BundleGenerator, + G::Iter: BundleIterator, + P: LocalesProvider, +{ + pub fn prefetch_sync(&mut self) { + let bundles = self.bundles(); + bundles.prefetch_sync(); + } +} + +impl Localization +where + G: BundleGenerator, + G::Stream: BundleStream, + P: LocalesProvider, +{ + pub async fn prefetch_async(&mut self) { + let bundles = self.bundles(); + bundles.prefetch_async().await + } +} + +impl Localization +where + G: BundleGenerator, + P: LocalesProvider, +{ + pub fn bundles(&self) -> &Rc> { + self.bundles.get_or_init(|| { + Rc::new(Bundles::new( + self.sync, + self.res_ids.clone(), + &self.generator, + &self.provider, + )) + }) + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/README.md b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/README.md new file mode 100644 index 00000000..b1c475f5 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/README.md @@ -0,0 +1,2 @@ +This is a temporary fork of https://github.com/withoutboats/pin-cell until +https://github.com/withoutboats/pin-cell/issues/6 gets resolved. diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/mod.rs b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/mod.rs new file mode 100644 index 00000000..175f9677 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/mod.rs @@ -0,0 +1,97 @@ +#![deny(missing_docs, missing_debug_implementations)] +//! This library defines the `PinCell` type, a pinning variant of the standard +//! library's `RefCell`. +//! +//! It is not safe to "pin project" through a `RefCell` - getting a pinned +//! reference to something inside the `RefCell` when you have a pinned +//! refernece to the `RefCell` - because `RefCell` is too powerful. +//! +//! A `PinCell` is slightly less powerful than `RefCell`: unlike a `RefCell`, +//! one cannot get a mutable reference into a `PinCell`, only a pinned mutable +//! reference (`Pin<&mut T>`). This makes pin projection safe, allowing you +//! to use interior mutability with the knowledge that `T` will never actually +//! be moved out of the `RefCell` that wraps it. + +mod pin_mut; +mod pin_ref; + +use core::cell::{BorrowMutError, RefCell, RefMut}; +use core::pin::Pin; + +pub use pin_mut::PinMut; +pub use pin_ref::PinRef; + +/// A mutable memory location with dynamically checked borrow rules +/// +/// Unlike `RefCell`, this type only allows *pinned* mutable access to the +/// inner value, enabling a "pin-safe" version of interior mutability. +/// +/// See the standard library documentation for more information. +#[derive(Default, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] +pub struct PinCell { + inner: RefCell, +} + +impl PinCell { + /// Creates a new `PinCell` containing `value`. + pub const fn new(value: T) -> PinCell { + PinCell { + inner: RefCell::new(value), + } + } +} + +impl PinCell { + /// Mutably borrows the wrapped value, preserving its pinnedness. + /// + /// The borrow lasts until the returned `PinMut` or all `PinMut`s derived + /// from it exit scope. The value cannot be borrowed while this borrow is + /// active. + pub fn borrow_mut(self: Pin<&Self>) -> PinMut<'_, T> { + self.try_borrow_mut().expect("already borrowed") + } + + /// Mutably borrows the wrapped value, preserving its pinnedness, + /// returning an error if the value is currently borrowed. + /// + /// The borrow lasts until the returned `PinMut` or all `PinMut`s derived + /// from it exit scope. The value cannot be borrowed while this borrow is + /// active. + /// + /// This is the non-panicking variant of `borrow_mut`. + pub fn try_borrow_mut<'a>(self: Pin<&'a Self>) -> Result, BorrowMutError> { + let ref_mut: RefMut<'a, T> = Pin::get_ref(self).inner.try_borrow_mut()?; + + // this is a pin projection from Pin<&PinCell> to Pin> + // projecting is safe because: + // + // - for (PinCell: Unpin) imples (RefMut: Unpin) + // holds true + // - PinCell does not implement Drop + // + // see discussion on tracking issue #49150 about pin projection + // invariants + let pin_ref_mut: Pin> = unsafe { Pin::new_unchecked(ref_mut) }; + + Ok(PinMut { inner: pin_ref_mut }) + } +} + +impl From for PinCell { + fn from(value: T) -> PinCell { + PinCell::new(value) + } +} + +impl From> for PinCell { + fn from(cell: RefCell) -> PinCell { + PinCell { inner: cell } + } +} + +impl From> for RefCell { + fn from(input: PinCell) -> Self { + input.inner + } +} +// TODO CoerceUnsized diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_mut.rs b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_mut.rs new file mode 100644 index 00000000..09a4d4a6 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_mut.rs @@ -0,0 +1,50 @@ +use core::cell::RefMut; +use core::fmt; +use core::ops::Deref; +use core::pin::Pin; + +#[derive(Debug)] +/// A wrapper type for a mutably borrowed value from a `PinCell`. +pub struct PinMut<'a, T: ?Sized> { + pub(crate) inner: Pin>, +} + +impl<'a, T: ?Sized> Deref for PinMut<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + &*self.inner + } +} + +impl<'a, T: ?Sized> PinMut<'a, T> { + /// Get a pinned mutable reference to the value inside this wrapper. + pub fn as_mut<'b>(orig: &'b mut PinMut<'a, T>) -> Pin<&'b mut T> { + orig.inner.as_mut() + } +} + +/* TODO implement these APIs + +impl<'a, T: ?Sized> PinMut<'a, T> { + pub fn map(orig: PinMut<'a, T>, f: F) -> PinMut<'a, U> where + F: FnOnce(Pin<&mut T>) -> Pin<&mut U>, + { + panic!() + } + + pub fn map_split(orig: PinMut<'a, T>, f: F) -> (PinMut<'a, U>, PinMut<'a, V>) where + F: FnOnce(Pin<&mut T>) -> (Pin<&mut U>, Pin<&mut V>) + { + panic!() + } +} +*/ + +impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinMut<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(&**self, f) + } +} + +// TODO CoerceUnsized diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_ref.rs b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_ref.rs new file mode 100644 index 00000000..46f9cfda --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/pin_cell/pin_ref.rs @@ -0,0 +1,47 @@ +use core::cell::Ref; +use core::fmt; +use core::ops::Deref; +use core::pin::Pin; + +#[derive(Debug)] +/// A wrapper type for a immutably borrowed value from a `PinCell`. +pub struct PinRef<'a, T: ?Sized> { + pub(crate) inner: Pin>, +} + +impl<'a, T: ?Sized> Deref for PinRef<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + &*self.inner + } +} + +/* TODO implement these APIs + +impl<'a, T: ?Sized> PinRef<'a, T> { + pub fn clone(orig: &PinRef<'a, T>) -> PinRef<'a, T> { + panic!() + } + + pub fn map(orig: PinRef<'a, T>, f: F) -> PinRef<'a, U> where + F: FnOnce(Pin<&T>) -> Pin<&U>, + { + panic!() + } + + pub fn map_split(orig: PinRef<'a, T>, f: F) -> (PinRef<'a, U>, PinRef<'a, V>) where + F: FnOnce(Pin<&T>) -> (Pin<&U>, Pin<&V>) + { + panic!() + } +} +*/ + +impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinRef<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(&**self, f) + } +} + +// TODO CoerceUnsized diff --git a/utshell-0.5.0/vendor/fluent-fallback/src/types.rs b/utshell-0.5.0/vendor/fluent-fallback/src/types.rs new file mode 100644 index 00000000..6b87fa05 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/src/types.rs @@ -0,0 +1,141 @@ +use fluent_bundle::FluentArgs; +use std::borrow::Cow; + +#[derive(Debug)] +pub struct L10nKey<'l> { + pub id: Cow<'l, str>, + pub args: Option>, +} + +impl<'l> From<&'l str> for L10nKey<'l> { + fn from(id: &'l str) -> Self { + Self { + id: id.into(), + args: None, + } + } +} + +#[derive(Debug, Clone)] +pub struct L10nAttribute<'l> { + pub name: Cow<'l, str>, + pub value: Cow<'l, str>, +} + +#[derive(Debug, Clone)] +pub struct L10nMessage<'l> { + pub value: Option>, + pub attributes: Vec>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ResourceType { + /// This is a required resource. + /// + /// A bundle generator should not consider a solution as valid + /// if this resource is missing. + /// + /// This is the default when creating a [`ResourceId`]. + Required, + + /// This is an optional resource. + /// + /// A bundle generator should still populate a partial solution + /// even if this resource is missing. + /// + /// This is intended for experimental and/or under-development + /// resources that may not have content for all supported locales. + /// + /// This should be used sparingly, as it will greatly increase + /// the state space of the search for valid solutions which can + /// have a severe impact on performance. + Optional, +} + +/// A resource identifier for a localization resource. +#[derive(Debug, Clone, Hash)] +pub struct ResourceId { + /// The resource identifier. + pub value: String, + + /// The [`ResourceType`] for this resource. + /// + /// The default value (when converting from another type) is + /// [`ResourceType::Required`]. You should only set this to + /// [`ResourceType::Optional`] for experimental or under-development + /// features that may not yet have content in all eventually-supported locales. + /// + /// Setting this value to [`ResourceType::Optional`] for all resources + /// may have a severe impact on performance due to increasing the state space + /// of the solver. + pub resource_type: ResourceType, +} + +impl ResourceId { + pub fn new>(value: S, resource_type: ResourceType) -> Self { + Self { + value: value.into(), + resource_type, + } + } + + /// Returns [`true`] if the resource has [`ResourceType::Required`], + /// otherwise returns [`false`]. + pub fn is_required(&self) -> bool { + matches!(self.resource_type, ResourceType::Required) + } + + /// Returns [`true`] if the resource has [`ResourceType::Optional`], + /// otherwise returns [`false`]. + pub fn is_optional(&self) -> bool { + matches!(self.resource_type, ResourceType::Optional) + } +} + +impl> From for ResourceId { + fn from(id: S) -> Self { + Self { + value: id.into(), + resource_type: ResourceType::Required, + } + } +} + +impl std::fmt::Display for ResourceId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.value) + } +} + +impl PartialEq for ResourceId { + fn eq(&self, other: &str) -> bool { + self.value.as_str().eq(other) + } +} + +impl Eq for ResourceId {} +impl PartialEq for ResourceId { + fn eq(&self, other: &Self) -> bool { + self.value.eq(&other.value) + } +} + +/// A trait for creating a [`ResourceId`] from another type. +/// +/// This differs from the [`From`] trait in that the [`From`] trait +/// always takes the default resource type of [`ResourceType::Required`]. +/// +/// If you need to create a resource with a non-default [`ResourceType`], +/// such as [`ResourceType::Optional`], then use this trait. +/// +/// This trait is automatically implemented for types that implement [`Into`]. +pub trait ToResourceId { + /// Creates a [`ResourceId`] from [`self`], given a [`ResourceType`]. + fn to_resource_id(self, resource_type: ResourceType) -> ResourceId; +} + +impl> ToResourceId for S { + fn to_resource_id(self, resource_type: ResourceType) -> ResourceId { + ResourceId::new(self.into(), resource_type) + } +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/tests/localization_test.rs b/utshell-0.5.0/vendor/fluent-fallback/tests/localization_test.rs new file mode 100644 index 00000000..b48f0a05 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/tests/localization_test.rs @@ -0,0 +1,518 @@ +use std::borrow::Cow; +use std::fs; + +use fluent_bundle::{ + resolver::errors::{ReferenceKind, ResolverError}, + FluentArgs, FluentBundle, FluentError, FluentResource, +}; +use fluent_fallback::{ + env::LocalesProvider, + generator::{BundleGenerator, FluentBundleResult}, + types::{L10nKey, ResourceId}, + Localization, LocalizationError, +}; +use rustc_hash::FxHashSet; +use std::cell::RefCell; +use std::rc::Rc; +use unic_langid::{langid, LanguageIdentifier}; + +struct InnerLocales { + locales: RefCell>, +} + +impl InnerLocales { + pub fn insert(&self, index: usize, element: LanguageIdentifier) { + self.locales.borrow_mut().insert(index, element); + } +} + +#[derive(Clone)] +struct Locales { + inner: Rc, +} + +impl Locales { + pub fn new(locales: Vec) -> Self { + Self { + inner: Rc::new(InnerLocales { + locales: RefCell::new(locales), + }), + } + } + + pub fn insert(&mut self, index: usize, element: LanguageIdentifier) { + self.inner.insert(index, element); + } +} + +impl LocalesProvider for Locales { + type Iter = as IntoIterator>::IntoIter; + fn locales(&self) -> Self::Iter { + self.inner.locales.borrow().clone().into_iter() + } +} + +// Due to limitation of trait, we need a nameable Iterator type. Due to the +// lack of GATs, these have to own members instead of taking slices. +struct BundleIter { + locales: as IntoIterator>::IntoIter, + res_ids: FxHashSet, +} + +impl Iterator for BundleIter { + type Item = FluentBundleResult; + + fn next(&mut self) -> Option { + let locale = self.locales.next()?; + + let mut bundle = FluentBundle::new(vec![locale.clone()]); + bundle.set_use_isolating(false); + + let mut errors = vec![]; + + for res_id in &self.res_ids { + let full_path = format!("./tests/resources/{}/{}", locale, res_id); + let source = fs::read_to_string(full_path).unwrap(); + let res = match FluentResource::try_new(source) { + Ok(res) => res, + Err((res, err)) => { + errors.extend(err.into_iter().map(Into::into)); + res + } + }; + bundle.add_resource(res).unwrap(); + } + if errors.is_empty() { + Some(Ok(bundle)) + } else { + Some(Err((bundle, errors))) + } + } +} + +impl futures::Stream for BundleIter { + type Item = FluentBundleResult; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if let Some(locale) = self.locales.next() { + let mut bundle = FluentBundle::new(vec![locale.clone()]); + bundle.set_use_isolating(false); + + let mut errors = vec![]; + for res_id in &self.res_ids { + let full_path = format!("./tests/resources/{}/{}", locale, res_id.value); + let source = fs::read_to_string(full_path).unwrap(); + let res = match FluentResource::try_new(source) { + Ok(res) => res, + Err((res, err)) => { + errors.extend(err.into_iter().map(Into::into)); + res + } + }; + bundle.add_resource(res).unwrap(); + } + if errors.is_empty() { + Some(Ok(bundle)).into() + } else { + Some(Err((bundle, errors))).into() + } + } else { + None.into() + } + } +} + +struct ResourceManager; + +impl BundleGenerator for ResourceManager { + type Resource = FluentResource; + type LocalesIter = std::vec::IntoIter; + type Iter = BundleIter; + type Stream = BundleIter; + + fn bundles_iter( + &self, + locales: Self::LocalesIter, + res_ids: FxHashSet, + ) -> Self::Iter { + BundleIter { locales, res_ids } + } + + fn bundles_stream( + &self, + locales: Self::LocalesIter, + res_ids: FxHashSet, + ) -> Self::Stream { + BundleIter { locales, res_ids } + } +} + +#[test] +fn localization_format() { + let resource_ids: Vec = vec!["test.ftl".into(), "test2.ftl".into()]; + let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales, res_mgr); + let bundles = loc.bundles(); + + let value = bundles + .format_value_sync("hello-world", None, &mut errors) + .unwrap(); + assert_eq!(value, Some(Cow::Borrowed("Hello World [pl]"))); + + let value = bundles + .format_value_sync("missing-message", None, &mut errors) + .unwrap(); + assert_eq!(value, None); + + let value = bundles + .format_value_sync("hello-world-3", None, &mut errors) + .unwrap(); + assert_eq!(value, Some(Cow::Borrowed("Hello World 3 [en]"))); + + assert_eq!(errors.len(), 4); +} + +#[test] +fn localization_on_change() { + let resource_ids: Vec = vec!["test.ftl".into(), "test2.ftl".into()]; + + let mut locales = Locales::new(vec![langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let mut loc = Localization::with_env(resource_ids, true, locales.clone(), res_mgr); + let bundles = loc.bundles(); + + let value = bundles + .format_value_sync("hello-world", None, &mut errors) + .unwrap(); + assert_eq!(value, Some(Cow::Borrowed("Hello World [en]"))); + + locales.insert(0, langid!("pl")); + loc.on_change(); + + let bundles = loc.bundles(); + let value = bundles + .format_value_sync("hello-world", None, &mut errors) + .unwrap(); + assert_eq!(value, Some(Cow::Borrowed("Hello World [pl]"))); +} + +#[test] +fn localization_format_value_missing_errors() { + let resource_ids: Vec = vec!["test.ftl".into(), "test2.ftl".into()]; + + let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales.clone(), res_mgr); + let bundles = loc.bundles(); + + let _ = bundles + .format_value_sync("missing-message", None, &mut errors) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: None + }, + ] + ); + + errors.clear(); + + let _ = bundles + .format_value_sync("message-3", None, &mut errors) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: None + }, + ] + ); +} + +#[test] +fn localization_format_value_sync_missing_errors() { + let resource_ids: Vec = vec!["test.ftl".into(), "test2.ftl".into()]; + + let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales.clone(), res_mgr); + let bundles = loc.bundles(); + + let _ = bundles + .format_value_sync("missing-message", None, &mut errors) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: None + }, + ] + ); + + errors.clear(); + + let _ = bundles + .format_value_sync("message-3", None, &mut errors) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: None + }, + ] + ); +} + +#[test] +fn localization_format_values_sync_missing_errors() { + let resource_ids: Vec = vec!["test.ftl".into(), "test2.ftl".into()]; + + let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales.clone(), res_mgr); + let bundles = loc.bundles(); + + let _ = bundles + .format_values_sync( + &["missing-message".into(), "missing-message-2".into()], + &mut errors, + ) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingMessage { + id: "missing-message-2".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingMessage { + id: "missing-message-2".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: None + }, + LocalizationError::MissingMessage { + id: "missing-message-2".to_string(), + locale: None + }, + ] + ); + + errors.clear(); + + let _ = bundles + .format_values_sync(&["message-3".into()], &mut errors) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingValue { + id: "message-3".to_string(), + locale: None + }, + ] + ); +} + +#[test] +fn localization_format_messages_sync_missing_errors() { + let resource_ids: Vec = vec!["test.ftl".into(), "test2.ftl".into()]; + + let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales.clone(), res_mgr); + let bundles = loc.bundles(); + + let _ = bundles + .format_messages_sync( + &["missing-message".into(), "missing-message-2".into()], + &mut errors, + ) + .unwrap(); + assert_eq!( + errors, + vec![ + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingMessage { + id: "missing-message-2".to_string(), + locale: Some(langid!("pl")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingMessage { + id: "missing-message-2".to_string(), + locale: Some(langid!("en-US")) + }, + LocalizationError::MissingMessage { + id: "missing-message".to_string(), + locale: None + }, + LocalizationError::MissingMessage { + id: "missing-message-2".to_string(), + locale: None + }, + ] + ); +} + +#[test] +fn localization_format_missing_argument_error() { + let resource_ids: Vec = vec!["test2.ftl".into()]; + let locales = Locales::new(vec![langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales, res_mgr); + let bundles = loc.bundles(); + + let mut args = FluentArgs::new(); + args.set("userName", "John"); + let keys = vec![L10nKey { + id: "message-4".into(), + args: Some(args), + }]; + + let msgs = bundles.format_messages_sync(&keys, &mut errors).unwrap(); + assert_eq!( + msgs.get(0).unwrap().as_ref().unwrap().value, + Some(Cow::Borrowed("Hello, John. [en]")) + ); + assert_eq!(errors.len(), 0); + + let keys = vec![L10nKey { + id: "message-4".into(), + args: None, + }]; + let msgs = bundles.format_messages_sync(&keys, &mut errors).unwrap(); + assert_eq!( + msgs.get(0).unwrap().as_ref().unwrap().value, + Some(Cow::Borrowed("Hello, {$userName}. [en]")) + ); + assert_eq!( + errors, + vec![LocalizationError::Resolver { + id: "message-4".to_string(), + locale: langid!("en-US"), + errors: vec![FluentError::ResolverError(ResolverError::Reference( + ReferenceKind::Variable { + id: "userName".to_string(), + } + ))], + },] + ); +} + +#[tokio::test] +async fn localization_handle_state_changes_mid_async() { + let resource_ids: Vec = vec!["test.ftl".into()]; + let locales = Locales::new(vec![langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let mut loc = Localization::with_env(resource_ids, false, locales, res_mgr); + + let bundles = loc.bundles().clone(); + + loc.add_resource_id("test2.ftl".to_string()); + + bundles.format_value("key", None, &mut errors).await; +} + +#[test] +fn localization_duplicate_resources() { + let resource_ids: Vec = + vec!["test.ftl".into(), "test2.ftl".into(), "test2.ftl".into()]; + let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]); + let res_mgr = ResourceManager; + let mut errors = vec![]; + + let loc = Localization::with_env(resource_ids, true, locales, res_mgr); + let bundles = loc.bundles(); + + let value = bundles + .format_value_sync("hello-world", None, &mut errors) + .unwrap(); + assert_eq!(value, Some(Cow::Borrowed("Hello World [pl]"))); + + assert_eq!(errors.len(), 0, "There were no errors"); +} diff --git a/utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test.ftl b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test.ftl new file mode 100644 index 00000000..c6a7390a --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test.ftl @@ -0,0 +1,4 @@ +hello-world = Hello World [en] + +message-1 = Message 1 Value [en] + .attr1 = Message 1 Attribute [en] diff --git a/utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test2.ftl b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test2.ftl new file mode 100644 index 00000000..faeae76c --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/en-US/test2.ftl @@ -0,0 +1,10 @@ +hello-world-2 = Hello World 2 [en] +hello-world-3 = Hello World 3 [en] + +message-2 = Message 2 Value [en] + .attr1 = Message 2 Attribute [en] + +message-3 = + .attr1 = Message 3 Attribute [en] + +message-4 = Hello, { $userName }. [en] diff --git a/utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test.ftl b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test.ftl new file mode 100644 index 00000000..6e2f8835 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test.ftl @@ -0,0 +1,4 @@ +hello-world = Hello World [pl] + +message-1 = Message 1 Value [pl] + .attr1 = Message 1 Attribute [pl] diff --git a/utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test2.ftl b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test2.ftl new file mode 100644 index 00000000..35d646a5 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-fallback/tests/resources/pl/test2.ftl @@ -0,0 +1,9 @@ +hello-world-2 = Hello World 2 [pl] + +message-2 = Message 2 Value [pl] + .attr1 = Message 2 Attribute [pl] + +message-3 = + .attr1 = Message 3 Attribute [pl] + +message-4 = Hello, { $userName }. [pl] diff --git a/utshell-0.5.0/vendor/fluent-langneg/.cargo-checksum.json b/utshell-0.5.0/vendor/fluent-langneg/.cargo-checksum.json new file mode 100644 index 00000000..bf0abede --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"1b11d8d30fe978704012e27981f8d50a3462319594b54ed2e71eaf85284d61eb","README.md":"a4f17c795725dcb84cdf1e327a61306e82aaa2ca1908c9ea95c0fbe9d53216fd","benches/negotiate.rs":"f14c49d75413fb4b248f8f586c046340d61f0682eb0860db326f1f415e1bceb9","src/accepted_languages.rs":"74fe73bb8c3f36d3b8b85bfdc55731c234c20e92245b0f89eb1e8b68af47c17c","src/lib.rs":"529e3c9810688c3a5d216c977b968a775f83a85c2da90d669f2cfc5eb6c71361","src/negotiate/likely_subtags.rs":"44531e2bbf3a2155771f197f863dffdce403d3e8dd0e1d4f36f7178e52e5a3a3","src/negotiate/mod.rs":"e8aa5ecf08b866d83c957230586cb9c03880473406d7cca28cadf9e883310a15"},"package":"2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/fluent-langneg/Cargo.toml b/utshell-0.5.0/vendor/fluent-langneg/Cargo.toml new file mode 100644 index 00000000..58aae3c6 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/Cargo.toml @@ -0,0 +1,61 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "fluent-langneg" +version = "0.13.0" +authors = ["Zibi Braniecki "] +include = ["src/**/*", "benches/*.rs", "Cargo.toml", "README.md"] +description = "A library for language and locale negotiation.\n" +homepage = "http://projectfluent.org/" +readme = "README.md" +categories = ["internationalization", "localization"] +license = "Apache-2.0" +repository = "https://github.com/projectfluent/fluent-langneg-rs" + +[[bench]] +name = "negotiate" +harness = false +[dependencies.unic-langid] +version = "0.9" +[dev-dependencies.criterion] +version = "0.3" + +[dev-dependencies.serde] +version = "1.0" +features = ["derive"] + +[dev-dependencies.serde_json] +version = "1.0" + +[dev-dependencies.unic-langid] +version = "0.9" +features = ["macros"] + +[dev-dependencies.unic-locale] +version = "0.9" +features = ["macros"] + +[features] +cldr = ["unic-langid/likelysubtags"] +default = [] +[badges.coveralls] +branch = "master" +repository = "projectfluent/fluent-langneg-rs" +service = "github" + +[badges.maintenance] +status = "actively-developed" + +[badges.travis-ci] +repository = "projectfluent/fluent-langneg-rs" diff --git a/utshell-0.5.0/vendor/fluent-langneg/README.md b/utshell-0.5.0/vendor/fluent-langneg/README.md new file mode 100644 index 00000000..bdff7649 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/README.md @@ -0,0 +1,113 @@ +# Fluent LangNeg + +**Fluent LangNeg is a library for language and locale identifier negotiation.** + +[![crates.io](http://meritbadge.herokuapp.com/fluent-langneg)](https://crates.io/crates/fluent-langneg) +[![Build Status](https://travis-ci.org/projectfluent/fluent-langneg-rs.svg?branch=master)](https://travis-ci.org/projectfluent/fluent-langneg-rs) +[![Coverage Status](https://coveralls.io/repos/github/projectfluent/fluent-langneg-rs/badge.svg?branch=master)](https://coveralls.io/github/projectfluent/fluent-langneg-rs?branch=master) + +Introduction +------------ + +This is a Rust implementation of fluent-langneg library which is a part of Project Fluent. + +The library uses [unic-langid](https://github.com/zbraniecki/unic-locale) and [unic-locale](https://github.com/zbraniecki/unic-locale) to retrieve and operate on Unicode Language and Locale Identifiers. +The library provides algorithm for negotiating between lists of locales. + +Usage +----- + +```rust +use fluent_langneg::negotiate_languages; +use fluent_langneg::NegotiationStrategy; +use fluent_langneg::convert_vec_str_to_langids_lossy; +use unic_langid::LanguageIdentifier + +// Since langid parsing from string is fallible, we'll use a helper +// function which strips any langids that failed to parse. +let requested = convert_vec_str_to_langids_lossy(&["de-DE", "fr-FR", "en-US"]); +let available = convert_vec_str_to_langids_lossy(&["it", "fr", "de-AT", "fr-CA", "en-US"]); +let default: LanguageIdentifier = "en-US".parse().expect("Parsing langid failed."); + +let supported = negotiate_languages( + &requested, + &available, + Some(&default), + NegotiationStrategy::Filtering +); + +let expected = convert_vec_str_to_langids_lossy(&["de-AT", "fr", "fr-CA", "en-US"]); +assert_eq!(supported, + expected.iter().map(|t| t.as_ref()).collect::>()); +``` + +See [docs.rs][] for more examples. + +[docs.rs]: https://docs.rs/fluent-langneg/ + +Status +------ + +The implementation is complete according to fluent-langneg +corpus of tests, which means that it parses, serializes and negotiates as expected. + +The negotiation methods can operate on lists of `LanguageIdentifier` or `Locale`. + +The remaining work is on the path to 1.0 is to gain in-field experience of using it, +add more tests and ensure that bad input is correctly handled. + +Compatibility +------------- + +The API is based on [UTS 35][] definition of [Unicode Locale Identifier][] and is aiming to +parse and serialize all locale identifiers according to that definition. + +*Note*: Unicode Locale Identifier is similar, but different, from what [BCP47][] specifies under +the name Language Tag. +For most locale management and negotiation needs, the Unicode Locale Identifier used in this crate is likely a better choice, +but in some case, like HTTP Accepted Headers, you may need the complete BCP47 Language Tag implementation which +this crate does not provide. + +Language negotiation algorithms are custom Project Fluent solutions, +based on [RFC4647][]. + +The language negotiation strategies aim to replicate the best-effort matches with +the most limited amount of data. The algorithm returns reasonable +results without any database, but the results can be improved with either limited +or full [CLDR likely-subtags][] database. + +The result is a balance chosen for Project Fluent and may differ from other +implementations of language negotiation algorithms which may choose different +tradeoffs. + +[BCP47]: https://tools.ietf.org/html/bcp47 +[RFC6067]: https://www.ietf.org/rfc/rfc6067.txt +[UTS 35]: http://www.unicode.org/reports/tr35/#Locale_Extension_Key_and_Type_Data +[RFC4647]: https://tools.ietf.org/html/rfc4647 +[CLDR likely-subtags]: http://www.unicode.org/cldr/charts/latest/supplemental/likely_subtags.html +[Unicode Locale Identifier]: (http://unicode.org/reports/tr35/#Identifiers) + +Alternatives +------------ + +Although Fluent Locale aims to stay close to W3C Accepted Languages, it does not aim +to implement the full behavior and some aspects of the language negotiation strategy +recommended by W3C, such as weights, are not a target right now. + +For such purposes, [rust-language-tags][] crate seems to be a better choice. + +[rust-language-tags]: https://github.com/pyfisch/rust-language-tags + +Performance +----------- + +The crate is considered to be fully optimized for production. + + +Develop +------- + + cargo build + cargo test + cargo bench + diff --git a/utshell-0.5.0/vendor/fluent-langneg/benches/negotiate.rs b/utshell-0.5.0/vendor/fluent-langneg/benches/negotiate.rs new file mode 100644 index 00000000..2ca70d59 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/benches/negotiate.rs @@ -0,0 +1,40 @@ +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::Criterion; + +use fluent_langneg::convert_vec_str_to_langids_lossy; +use fluent_langneg::negotiate_languages; + +use unic_langid::LanguageIdentifier; + +#[no_mangle] +#[inline(never)] +fn do_negotiate<'a>( + requested: &[LanguageIdentifier], + available: &'a [LanguageIdentifier], +) -> Vec<&'a LanguageIdentifier> { + negotiate_languages( + requested, + available, + None, + fluent_langneg::NegotiationStrategy::Filtering, + ) +} + +fn negotiate_bench(c: &mut Criterion) { + let requested = &["de", "it", "ru"]; + let available = &[ + "en-US", "fr", "de", "en-GB", "it", "pl", "ru", "sr-Cyrl", "sr-Latn", "zh-Hant", "zh-Hans", + "ja-JP", "he-IL", "de-DE", "de-IT", + ]; + + let requested = convert_vec_str_to_langids_lossy(requested); + let available = convert_vec_str_to_langids_lossy(available); + + c.bench_function("negotiate", |b| { + b.iter(|| do_negotiate(&requested, &available)) + }); +} + +criterion_group!(benches, negotiate_bench); +criterion_main!(benches); diff --git a/utshell-0.5.0/vendor/fluent-langneg/src/accepted_languages.rs b/utshell-0.5.0/vendor/fluent-langneg/src/accepted_languages.rs new file mode 100644 index 00000000..58cf2777 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/src/accepted_languages.rs @@ -0,0 +1,41 @@ +//! This function parses Accept-Language string into a list of language tags that +//! can be later passed to language negotiation functions. +//! +//! # Example: +//! +//! ``` +//! use fluent_langneg::negotiate_languages; +//! use fluent_langneg::NegotiationStrategy; +//! use fluent_langneg::parse_accepted_languages; +//! use fluent_langneg::convert_vec_str_to_langids_lossy; +//! use unic_langid::LanguageIdentifier; +//! +//! let requested = parse_accepted_languages("de-AT;0.9,de-DE;0.8,de;0.7;en-US;0.5"); +//! let available = convert_vec_str_to_langids_lossy(&["fr", "pl", "de", "en-US"]); +//! let default: LanguageIdentifier = "en-US".parse().expect("Failed to parse a langid."); +//! +//! let supported = negotiate_languages( +//! &requested, +//! &available, +//! Some(&default), +//! NegotiationStrategy::Filtering +//! ); +//! +//! let expected = convert_vec_str_to_langids_lossy(&["de", "en-US"]); +//! assert_eq!(supported, +//! expected.iter().map(|t| t.as_ref()).collect::>()); +//! ``` +//! +//! This function ignores the weights associated with the locales, since Fluent Locale +//! language negotiation only uses the order of locales, not the weights. +//! + +use unic_langid::LanguageIdentifier; + +pub fn parse(s: &str) -> Vec { + s.split(',') + .map(|t| t.trim().split(';').nth(0).unwrap()) + .filter(|t| !t.is_empty()) + .filter_map(|t| t.parse().ok()) + .collect() +} diff --git a/utshell-0.5.0/vendor/fluent-langneg/src/lib.rs b/utshell-0.5.0/vendor/fluent-langneg/src/lib.rs new file mode 100644 index 00000000..865bfc27 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/src/lib.rs @@ -0,0 +1,49 @@ +//! fluent-langneg is an API for operating on locales and language tags. +//! It's part of Project Fluent, a localization framework designed to unleash +//! the expressive power of the natural language. +//! +//! The primary use of fluent-langneg is to parse/modify/serialize language tags +//! and to perform language negotiation. +//! +//! fluent-langneg operates on a subset of [BCP47](http://tools.ietf.org/html/bcp47). +//! It can parse full BCP47 language tags, and will serialize them back, +//! but currently only allows for operations on primary subtags and +//! unicode extension keys. +//! +//! In result fluent-langneg is not suited to replace full implementations of +//! BCP47 like [rust-language-tags](https://github.com/pyfisch/rust-language-tags), +//! but is arguably a better option for use cases involving operations on +//! language tags and for language negotiation. + +pub mod accepted_languages; +pub mod negotiate; + +pub use accepted_languages::parse as parse_accepted_languages; +pub use negotiate::negotiate_languages; +pub use negotiate::NegotiationStrategy; + +use unic_langid::{LanguageIdentifier, LanguageIdentifierError}; + +pub fn convert_vec_str_to_langids<'a, I, J>( + input: I, +) -> Result, LanguageIdentifierError> +where + I: IntoIterator, + J: AsRef<[u8]> + 'a, +{ + input + .into_iter() + .map(|s| LanguageIdentifier::from_bytes(s.as_ref())) + .collect() +} + +pub fn convert_vec_str_to_langids_lossy<'a, I, J>(input: I) -> Vec +where + I: IntoIterator, + J: AsRef<[u8]> + 'a, +{ + input + .into_iter() + .filter_map(|t| LanguageIdentifier::from_bytes(t.as_ref()).ok()) + .collect() +} diff --git a/utshell-0.5.0/vendor/fluent-langneg/src/negotiate/likely_subtags.rs b/utshell-0.5.0/vendor/fluent-langneg/src/negotiate/likely_subtags.rs new file mode 100644 index 00000000..60a7b7a5 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/src/negotiate/likely_subtags.rs @@ -0,0 +1,39 @@ +use unic_langid::LanguageIdentifier; + +static REGION_MATCHING_KEYS: &[&str] = &[ + "az", "bg", "cs", "de", "es", "fi", "fr", "hu", "it", "lt", "lv", "nl", "pl", "ro", "ru", +]; + +pub trait MockLikelySubtags { + fn maximize(&mut self) -> bool; +} + +impl MockLikelySubtags for LanguageIdentifier { + fn maximize(&mut self) -> bool { + let extended = match self.to_string().as_str() { + "en" => "en-Latn-US", + "fr" => "fr-Latn-FR", + "sr" => "sr-Cyrl-SR", + "sr-RU" => "sr-Latn-SR", + "az-IR" => "az-Arab-IR", + "zh-GB" => "zh-Hant-GB", + "zh-US" => "zh-Hant-US", + _ => { + let lang = self.language; + + for subtag in REGION_MATCHING_KEYS { + if lang == *subtag { + self.region = Some(subtag.parse().unwrap()); + return true; + } + } + return false; + } + }; + let langid: LanguageIdentifier = extended.parse().expect("Failed to parse langid."); + self.language = langid.language; + self.script = langid.script; + self.region = langid.region; + true + } +} diff --git a/utshell-0.5.0/vendor/fluent-langneg/src/negotiate/mod.rs b/utshell-0.5.0/vendor/fluent-langneg/src/negotiate/mod.rs new file mode 100644 index 00000000..4b3587fd --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-langneg/src/negotiate/mod.rs @@ -0,0 +1,233 @@ +//! Language Negotiation is a process in which locales from different +//! sources are filtered and sorted in an effort to produce the best +//! possible selection of them. +//! +//! There are multiple language negotiation strategies, most popular is +//! described in [RFC4647](https://www.ietf.org/rfc/rfc4647.txt). +//! +//! The algorithm is based on the BCP4647 3.3.2 Extended Filtering algorithm, +//! with several modifications. +//! +//! # Example: +//! +//! ``` +//! use fluent_langneg::negotiate_languages; +//! use fluent_langneg::NegotiationStrategy; +//! use fluent_langneg::convert_vec_str_to_langids_lossy; +//! use unic_langid::LanguageIdentifier; +//! +//! let requested = convert_vec_str_to_langids_lossy(&["pl", "fr", "en-US"]); +//! let available = convert_vec_str_to_langids_lossy(&["it", "de", "fr", "en-GB", "en_US"]); +//! let default: LanguageIdentifier = "en-US".parse().expect("Parsing langid failed."); +//! +//! let supported = negotiate_languages( +//! &requested, +//! &available, +//! Some(&default), +//! NegotiationStrategy::Filtering +//! ); +//! +//! let expected = convert_vec_str_to_langids_lossy(&["fr", "en-US", "en-GB"]); +//! assert_eq!(supported, +//! expected.iter().map(|t| t.as_ref()).collect::>()); +//! ``` +//! +//! # The exact algorithm is custom, and consists of a 6 level strategy: +//! +//! ### 1) Attempt to find an exact match for each requested locale in available locales. +//! +//! Example: +//! +//! ```text +//! // [requested] * [available] = [supported] +//! +//! ["en-US"] * ["en-US"] = ["en-US"] +//! ``` +//! +//! ### 2) Attempt to match a requested locale to an available locale treated as a locale range. +//! +//! Example: +//! +//! ```text +//! // [requested] * [available] = [supported] +//! +//! ["en-US"] * ["en"] = ["en"] +//! ^^ +//! |-- becomes "en-*-*-*" +//! ``` +//! +//! ### 3) Maximize the requested locale to find the best match in available locales. +//! +//! This part uses ICU's likelySubtags or similar database. +//! +//! Example: +//! +//! ```text +//! // [requested] * [available] = [supported] +//! +//! ["en"] * ["en-GB", "en-US"] = ["en-US"] +//! ^^ ^^^^^ ^^^^^ +//! | | | +//! | |----------- become "en-*-GB-*" and "en-*-US-*" +//! | +//! |-- ICU likelySubtags expands it to "en-Latn-US" +//! ``` +//! +//! ### 4) Attempt to look up for a different variant of the same locale. +//! +//! Example: +//! +//! ```text +//! // [requested] * [available] = [supported] +//! +//! ["ja-JP-win"] * ["ja-JP-mac"] = ["ja-JP-mac"] +//! ^^^^^^^^^ ^^^^^^^^^ +//! | |-- become "ja-*-JP-mac" +//! | +//! |----------- replace variant with range: "ja-JP-*" +//! ``` +//! +//! ### 5) Look up for a maximized version of the requested locale, stripped of the region code. +//! +//! Example: +//! +//! ```text +//! // [requested] * [available] = [supported] +//! +//! ["en-CA"] * ["en-ZA", "en-US"] = ["en-US", "en-ZA"] +//! ^^^^^ +//! | ^^^^^ ^^^^^ +//! | | | +//! | |----------- become "en-*-ZA-*" and "en-*-US-*" +//! | +//! |----------- strip region produces "en", then lookup likelySubtag: "en-Latn-US" +//! ``` +//! +//! +//! ### 6) Attempt to look up for a different region of the same locale. +//! +//! Example: +//! +//! ```text +//! // [requested] * [available] = [supported] +//! +//! ["en-GB"] * ["en-AU"] = ["en-AU"] +//! ^^^^^ ^^^^^ +//! | |-- become "en-*-AU-*" +//! | +//! |----- replace region with range: "en-*" +//! ``` +//! + +use unic_langid::LanguageIdentifier; + +#[cfg(not(feature = "cldr"))] +mod likely_subtags; +#[cfg(not(feature = "cldr"))] +use likely_subtags::MockLikelySubtags; + +#[derive(PartialEq, Debug, Clone, Copy)] +pub enum NegotiationStrategy { + Filtering, + Matching, + Lookup, +} + +pub fn filter_matches<'a, R: 'a + AsRef, A: 'a + AsRef>( + requested: &[R], + available: &'a [A], + strategy: NegotiationStrategy, +) -> Vec<&'a A> { + let mut supported_locales = vec![]; + + let mut available_locales: Vec<&A> = available.iter().collect(); + + for req in requested { + let mut req = req.as_ref().to_owned(); + macro_rules! test_strategy { + ($self_as_range:expr, $other_as_range:expr) => {{ + let mut match_found = false; + available_locales.retain(|locale| { + if strategy != NegotiationStrategy::Filtering && match_found { + return true; + } + + if locale + .as_ref() + .matches(&req, $self_as_range, $other_as_range) + { + match_found = true; + supported_locales.push(*locale); + return false; + } + true + }); + + if match_found { + match strategy { + NegotiationStrategy::Filtering => {} + NegotiationStrategy::Matching => continue, + NegotiationStrategy::Lookup => break, + } + } + }}; + } + + // 1) Try to find a simple (case-insensitive) string match for the request. + test_strategy!(false, false); + + // 2) Try to match against the available locales treated as ranges. + test_strategy!(true, false); + + // Per Unicode TR35, 4.4 Locale Matching, we don't add likely subtags to + // requested locales, so we'll skip it from the rest of the steps. + if req.language.is_empty() { + continue; + } + + // 3) Try to match against a maximized version of the requested locale + if req.maximize() { + test_strategy!(true, false); + } + + // 4) Try to match against a variant as a range + req.clear_variants(); + test_strategy!(true, true); + + // 5) Try to match against the likely subtag without region + req.region = None; + if req.maximize() { + test_strategy!(true, false); + } + + // 6) Try to match against a region as a range + req.region = None; + test_strategy!(true, true); + } + + supported_locales +} + +pub fn negotiate_languages< + 'a, + R: 'a + AsRef, + A: 'a + AsRef + PartialEq, +>( + requested: &[R], + available: &'a [A], + default: Option<&'a A>, + strategy: NegotiationStrategy, +) -> Vec<&'a A> { + let mut supported = filter_matches(requested, available, strategy); + + if let Some(default) = default { + if strategy == NegotiationStrategy::Lookup { + if supported.is_empty() { + supported.push(default); + } + } else if !supported.contains(&default) { + supported.push(default); + } + } + supported +} diff --git a/utshell-0.5.0/vendor/fluent-resmgr/.cargo-checksum.json b/utshell-0.5.0/vendor/fluent-resmgr/.cargo-checksum.json new file mode 100644 index 00000000..c04bc17c --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"3322060941367949ebf6aba1d6efe59281664719b5628ba49a2a15c0469d322c","Cargo.lock":"503c8e3b5c7e76657528df7327ad5f6afaaab8dd740d4585f3818ee86c1988d6","Cargo.toml":"3e1d088208652ae79dec27426929507087dbfb02921aa79492d887540e20148a","LICENSE-APACHE":"5db2b182453ff32ed40f7da63589c9667a3f8bd8b16b1471b152caae56f77e45","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"2421e420987be15ddb72ce68a80283141f79cfe8ce588450bc17dbf0c8f4fd71","examples/resources/en-US/common.ftl":"7172de93f08043b178fffcfa030ef2a039b169a0aa53c805302e6815c0dd90d6","examples/resources/en-US/errors.ftl":"170f002f95d7401555c7b365d3e10a7c20cf1ed2e1d0d708128c7a31071ac100","examples/resources/en-US/simple.ftl":"564e2dc286b64f4c8d7df077a688f847d51a9c37eed9d88d518b8c8cdb157f00","examples/resources/pl/common.ftl":"c10a9c5332c41522b9aa5110faf84b21c266cc72a2fa656fefff6c68c1747542","examples/resources/pl/errors.ftl":"812d4e17578b246e108224c473ada1b27d2951cf4e96dbc6bb62f4fad4f1d11e","examples/resources/pl/simple.ftl":"b7ec54cde7e45a85a93c22cc16931e14746fa61f3b31db6b6266cb78d09967ec","examples/simple-resmgr.rs":"5da7fc6df43715159493c692f918c6ca5c5ddca24f0ef2b0cc8ac90abfdbb532","src/lib.rs":"358f54c55d3e485de58993da7f8a2328f7e6ac747f8e21490abeab614187fc2b","src/resource_manager.rs":"c9ee0a5fbc228d3cab1dbccdc8ccd697710c02035e210cf751a9ef02a4ce95a8","tests/localization_test.rs":"4eff47635d39825ca9bfb22d7283417c9216a330fdd4301b9e3a3fd52892317a","tests/resources/en-US/test.ftl":"2b7f34bde3c1096bef9de38fa84a4620457fa9bd090406de5c7736a21f8e20f0","tests/resources/pl/test.ftl":"874d9cab2d51a7b6b80677f0603c1094635b047a844802dcf1a10108fb60cd6d"},"package":"f7144b87452708dd3217fdb41aefb74cf261fde09cd055ee2e1f4634b5beb380"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/fluent-resmgr/CHANGELOG.md b/utshell-0.5.0/vendor/fluent-resmgr/CHANGELOG.md new file mode 100644 index 00000000..95fbc64c --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog + +## Unreleased + + - … + +## fluent-resmgr 0.0.6 (Nov 9, 2022) + - Update `fluent-fallback` to 0.7.0. + +## fluent-resmgr 0.0.5 (Dec 17, 2021) + - Update `fluent-fallback` to 0.6.0. + +## fluent-resmgr 0.0.4 (May 6, 2020) + - Update `fluent-bundle` to 0.12. + - Update `unic-langid` to 0.9. + - Update `fluent-fallback` to 0.0.4. + +## fluent-resmgr 0.0.3 (February 13, 2020) + - Update `fluent-bundle` to 0.10. + - Update `unic-langid` to 0.8. + - Update `fluent-fallback` to 0.0.3. + +## fluent-resmgr 0.0.2 (November 26, 2019) + - Update `fluent-bundle` to 0.9. + - Update `unic-langid` to 0.7. + +## fluent-resmgr 0.0.1 (August 1, 2019) + + - This is the first release to be listed in the CHANGELOG. + - Basic support fluent-fallback 0.1 and fluent-bundle 0.7 diff --git a/utshell-0.5.0/vendor/fluent-resmgr/Cargo.lock b/utshell-0.5.0/vendor/fluent-resmgr/Cargo.lock new file mode 100644 index 00000000..e592caac --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/Cargo.lock @@ -0,0 +1,395 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "async-trait" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "chunky-vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7bdea464ae038f09197b82430b921c53619fc8d2bcaf7b151013b3ca008017" + +[[package]] +name = "displaydoc" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "elsa" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b4b5d23ed6b6948d68240aafa4ac98e568c9a020efd9d4201a6288bc3006e09" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "fluent-bundle" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" +dependencies = [ + "fluent-langneg", + "fluent-syntax", + "intl-memoizer", + "intl_pluralrules", + "rustc-hash", + "self_cell", + "smallvec", + "unic-langid", +] + +[[package]] +name = "fluent-fallback" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08fdcccdeb6c01cb085f2bb3420506e6c67f025cee5db047529838c673a7d82b" +dependencies = [ + "async-trait", + "chunky-vec", + "fluent-bundle", + "futures", + "once_cell", + "rustc-hash", + "unic-langid", +] + +[[package]] +name = "fluent-langneg" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94" +dependencies = [ + "unic-langid", +] + +[[package]] +name = "fluent-resmgr" +version = "0.0.6" +dependencies = [ + "elsa", + "fluent-bundle", + "fluent-fallback", + "fluent-langneg", + "futures", + "rustc-hash", + "unic-langid", +] + +[[package]] +name = "fluent-syntax" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" +dependencies = [ + "thiserror", +] + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "intl-memoizer" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" +dependencies = [ + "type-map", + "unic-langid", +] + +[[package]] +name = "intl_pluralrules" +version = "7.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" +dependencies = [ + "unic-langid", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "self_cell" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinystr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2" +dependencies = [ + "displaydoc", +] + +[[package]] +name = "type-map" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "unic-langid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" +dependencies = [ + "unic-langid-impl", + "unic-langid-macros", +] + +[[package]] +name = "unic-langid-impl" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" +dependencies = [ + "tinystr", +] + +[[package]] +name = "unic-langid-macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055e618bf694161ffff0466d95cef3e1a5edc59f6ba1888e97801f2b4ebdc4fe" +dependencies = [ + "proc-macro-hack", + "tinystr", + "unic-langid-impl", + "unic-langid-macros-impl", +] + +[[package]] +name = "unic-langid-macros-impl" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8" +dependencies = [ + "proc-macro-hack", + "quote", + "syn", + "unic-langid-impl", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" diff --git a/utshell-0.5.0/vendor/fluent-resmgr/Cargo.toml b/utshell-0.5.0/vendor/fluent-resmgr/Cargo.toml new file mode 100644 index 00000000..db64a69d --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/Cargo.toml @@ -0,0 +1,63 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "fluent-resmgr" +version = "0.0.6" +authors = [ + "Zibi Braniecki ", + "Staś Małolepszy ", +] +description = """ +Resource manager for Fluent localization resources. +""" +homepage = "http://www.projectfluent.org" +readme = "README.md" +keywords = [ + "localization", + "l10n", + "i18n", + "intl", + "internationalization", +] +categories = [ + "localization", + "internationalization", +] +license = "Apache-2.0/MIT" +repository = "https://github.com/projectfluent/fluent-rs" +resolver = "1" + +[dependencies.elsa] +version = "1.5" + +[dependencies.fluent-bundle] +version = "0.15.2" + +[dependencies.fluent-fallback] +version = "0.7.0" + +[dependencies.futures] +version = "0.3" + +[dependencies.rustc-hash] +version = "1" + +[dependencies.unic-langid] +version = "0.9" + +[dev-dependencies.fluent-langneg] +version = "0.13" + +[dev-dependencies.unic-langid] +version = "0.9" +features = ["macros"] diff --git a/utshell-0.5.0/vendor/fluent-resmgr/LICENSE-APACHE b/utshell-0.5.0/vendor/fluent-resmgr/LICENSE-APACHE new file mode 100644 index 00000000..35582f16 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Mozilla + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/fluent-resmgr/LICENSE-MIT b/utshell-0.5.0/vendor/fluent-resmgr/LICENSE-MIT new file mode 100644 index 00000000..5655fa31 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright 2017 Mozilla + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/utshell-0.5.0/vendor/fluent-resmgr/README.md b/utshell-0.5.0/vendor/fluent-resmgr/README.md new file mode 100644 index 00000000..ec4f3fb2 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/README.md @@ -0,0 +1,99 @@ +# Fluent Resource Manager + +`fluent-resmgr` is an implementation of resource manager for [Project Fluent][]. + +Resource Manager provides a standalone solution for managing localization resources which +can be used by `fluent-fallback` or other higher level bindings. + +[![crates.io](https://img.shields.io/crates/v/fluent-resmgr.svg)](https://crates.io/crates/fluent-resmgr) +[![Build and test](https://github.com/projectfluent/fluent-rs/workflows/Build%20and%20test/badge.svg)](https://github.com/projectfluent/fluent-rs/actions?query=branch%3Amaster+workflow%3A%22Build+and+test%22) +[![Coverage Status](https://coveralls.io/repos/github/projectfluent/fluent-rs/badge.svg?branch=master)](https://coveralls.io/github/projectfluent/fluent-rs?branch=master) + +Project Fluent keeps simple things simple and makes complex things possible. +The syntax used for describing translations is easy to read and understand. At +the same time it allows, when necessary, to represent complex concepts from +natural languages like gender, plurals, conjugations, and others. + +[Documentation][] + +[Project Fluent]: http://projectfluent.org +[Documentation]: https://docs.rs/fluent/ + +Usage +----- + +```rust +use fluent_resmgr::resource_manager::ResourceManager; + +fn main() { + let mgr = ResourceManager::new("./examples/resources/{locale}/{res_id}".into()); + + let bundle = mgr.get_bundle(locales, resources); + + let value = bundle.format_value("hello-world", None); + + assert_eq!(&value, "Hello, world!"); +} +``` + + +Status +------ + +The implementation is in its early stages and supports only some of the Project +Fluent's spec. Consult the [list of milestones][] for more information about +release planning and scope. + +[list of milestones]: https://github.com/projectfluent/fluent-rs/milestones + + +Local Development +----------------- + + cargo build + cargo test + cargo run --example simple + +When submitting a PR please use [`cargo fmt`][] (nightly). + +[`cargo fmt`]: https://github.com/rust-lang-nursery/rustfmt + + +Learn the FTL syntax +-------------------- + +FTL is a localization file format used for describing translation resources. +FTL stands for _Fluent Translation List_. + +FTL is designed to be simple to read, but at the same time allows to represent +complex concepts from natural languages like gender, plurals, conjugations, and +others. + + hello-user = Hello, { $username }! + +[Read the Fluent Syntax Guide][] in order to learn more about the syntax. If +you're a tool author you may be interested in the formal [EBNF grammar][]. + +[Read the Fluent Syntax Guide]: http://projectfluent.org/fluent/guide/ +[EBNF grammar]: https://github.com/projectfluent/fluent/tree/master/spec + + +Get Involved +------------ + +`fluent-rs` is open-source, licensed under the Apache License, Version 2.0. We +encourage everyone to take a look at our code and we'll listen to your +feedback. + + +Discuss +------- + +We'd love to hear your thoughts on Project Fluent! Whether you're a localizer +looking for a better way to express yourself in your language, or a developer +trying to make your app localizable and multilingual, or a hacker looking for +a project to contribute to, please do get in touch on the mailing list and the +IRC channel. + + - Discourse: https://discourse.mozilla.org/c/fluent + - IRC channel: [irc://irc.mozilla.org/l20n](irc://irc.mozilla.org/l20n) diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/common.ftl b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/common.ftl new file mode 100644 index 00000000..09e3bdaa --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/common.ftl @@ -0,0 +1 @@ +hello-world = Hello World! diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/errors.ftl b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/errors.ftl new file mode 100644 index 00000000..6a228bbe --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/errors.ftl @@ -0,0 +1,2 @@ +missing-arg-error = Error: Please provide a number as argument. +input-parse-error = Error: Could not parse input `{ $input }`. Reason: { $reason } diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/simple.ftl b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/simple.ftl new file mode 100644 index 00000000..104d3e30 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/en-US/simple.ftl @@ -0,0 +1,5 @@ +response-msg = + { $value -> + [one] "{ $input }" has one Collatz step. + *[other] "{ $input }" has { $value } Collatz steps. + } diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/common.ftl b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/common.ftl new file mode 100644 index 00000000..5f6a3d9f --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/common.ftl @@ -0,0 +1 @@ +hello-world = Witaj, Świecie! diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/errors.ftl b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/errors.ftl new file mode 100644 index 00000000..f27124a3 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/errors.ftl @@ -0,0 +1,2 @@ +missing-arg-error = Błąd: Proszę wprowadzić liczbę jako argument. +input-parse-error = Błąd: Nie udało się sparsować `{ $input }`. Powód: { $reason } diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/simple.ftl b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/simple.ftl new file mode 100644 index 00000000..7a17d125 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/resources/pl/simple.ftl @@ -0,0 +1,6 @@ +response-msg = + { $value -> + [one] "{ $input }" ma jeden krok Collatza. + [few] "{ $input }" ma { $value } kroki Collatza. + *[many] "{ $input }" ma { $value } kroków Collatza. + } diff --git a/utshell-0.5.0/vendor/fluent-resmgr/examples/simple-resmgr.rs b/utshell-0.5.0/vendor/fluent-resmgr/examples/simple-resmgr.rs new file mode 100644 index 00000000..50c076be --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/examples/simple-resmgr.rs @@ -0,0 +1,151 @@ +//! This is an example of a simple application +//! which calculates the Collatz conjecture. +//! +//! The function itself is trivial on purpose, +//! so that we can focus on understanding how +//! the application can be made localizable +//! via Fluent. +//! +//! To try the app launch `cargo run --example simple NUM (LOCALES)` +//! +//! NUM is a number to be calculated, and LOCALES is an optional +//! parameter with a comma-separated list of locales requested by the user. +//! +//! Example: +//! +//! caron run --example simple 123 de,pl +//! +//! If the second argument is omitted, `en-US` locale is used as the +//! default one. +use fluent_bundle::{FluentArgs, FluentValue}; +use fluent_langneg::{negotiate_languages, NegotiationStrategy}; +use fluent_resmgr::resource_manager::ResourceManager; +use std::env; +use std::fs; +use std::io; +use std::path::PathBuf; +use std::str::FromStr; +use unic_langid::LanguageIdentifier; + +/// This helper function allows us to read the list +/// of available locales by reading the list of +/// directories in `./examples/resources`. +/// +/// It is expected that every directory inside it +/// has a name that is a valid BCP47 language tag. +fn get_available_locales() -> Result, io::Error> { + let mut locales = vec![]; + + let res_path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("examples") + .join("resources"); + let res_dir = fs::read_dir(res_path)?; + for entry in res_dir { + if let Ok(entry) = entry { + let path = entry.path(); + if path.is_dir() { + if let Some(name) = path.file_name() { + if let Some(name) = name.to_str() { + let langid: LanguageIdentifier = name.parse().expect("Parsing failed."); + locales.push(langid); + } + } + } + } + } + return Ok(locales); +} + +fn main() { + let resources = vec!["simple.ftl".into(), "errors.ftl".into()]; + + // 1. Get the command line arguments. + let args: Vec = env::args().collect(); + + let res_path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("examples") + .join("resources"); + let mgr = ResourceManager::new(format!( + "{}/{{locale}}/{{res_id}}", + res_path.to_str().unwrap() + )); + + // 2. If the argument length is more than 1, + // take the second argument as a comma-separated + // list of requested locales. + let requested: Vec = args.get(2).map_or(vec![], |arg| { + arg.split(",") + .map(|s| s.parse().expect("Parsing locale failed.")) + .collect() + }); + + // 3. Negotiate it against the avialable ones + let default_locale: LanguageIdentifier = "en-US".parse().expect("Parsing failed."); + let available = get_available_locales().expect("Retrieving available locales failed."); + let resolved_locales = negotiate_languages( + &requested, + &available, + Some(&default_locale), + NegotiationStrategy::Filtering, + ); + + // 5. Get a bundle for given paths and locales. + let bundle = mgr.get_bundle( + resolved_locales.into_iter().map(|s| s.to_owned()).collect(), + resources, + ); + + // 6. Check if the input is provided. + match args.get(1) { + Some(input) => { + // 6.1. Cast it to a number. + match isize::from_str(&input) { + Ok(i) => { + // 6.2. Construct a map of arguments + // to format the message. + let mut args = FluentArgs::new(); + args.set("input", FluentValue::from(i)); + args.set("value", FluentValue::from(collatz(i))); + // 6.3. Format the message. + let mut errors = vec![]; + let msg = bundle.get_message("response-msg").expect("Message exists"); + let pattern = msg.value().expect("Message has a value"); + let value = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!("{}", value); + } + Err(err) => { + let mut args = FluentArgs::new(); + args.set("input", FluentValue::from(input.to_string())); + args.set("reason", FluentValue::from(err.to_string())); + let mut errors = vec![]; + let msg = bundle + .get_message("input-parse-error-msg") + .expect("Message exists"); + let pattern = msg.value().expect("Message has a value"); + let value = bundle.format_pattern(&pattern, Some(&args), &mut errors); + println!("{}", value); + } + } + } + None => { + let mut errors = vec![]; + let msg = bundle + .get_message("missing-arg-error") + .expect("Message exists"); + let pattern = msg.value().expect("Message has a value"); + let value = bundle.format_pattern(&pattern, None, &mut errors); + println!("{}", value); + } + } +} + +/// Collatz conjecture calculating function. +fn collatz(n: isize) -> isize { + match n { + 1 => 0, + _ => match n % 2 { + 0 => 1 + collatz(n / 2), + _ => 1 + collatz(n * 3 + 1), + }, + } +} diff --git a/utshell-0.5.0/vendor/fluent-resmgr/src/lib.rs b/utshell-0.5.0/vendor/fluent-resmgr/src/lib.rs new file mode 100644 index 00000000..fd4b048e --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/src/lib.rs @@ -0,0 +1,3 @@ +pub mod resource_manager; + +pub use resource_manager::ResourceManager; diff --git a/utshell-0.5.0/vendor/fluent-resmgr/src/resource_manager.rs b/utshell-0.5.0/vendor/fluent-resmgr/src/resource_manager.rs new file mode 100644 index 00000000..7a01be74 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/src/resource_manager.rs @@ -0,0 +1,140 @@ +use elsa::FrozenMap; +use fluent_bundle::{FluentBundle, FluentResource}; +use fluent_fallback::{ + generator::{BundleGenerator, FluentBundleResult}, + types::ResourceId, +}; +use futures::stream::Stream; +use rustc_hash::FxHashSet; +use std::fs; +use std::io; +use std::iter; +use unic_langid::LanguageIdentifier; + +fn read_file(path: &str) -> Result { + fs::read_to_string(path) +} + +pub struct ResourceManager { + resources: FrozenMap>, + path_scheme: String, +} + +impl ResourceManager { + pub fn new(path_scheme: String) -> Self { + ResourceManager { + resources: FrozenMap::new(), + path_scheme, + } + } + + fn get_resource(&self, res_id: &str, locale: &str) -> &FluentResource { + let path = self + .path_scheme + .replace("{locale}", locale) + .replace("{res_id}", res_id); + if let Some(res) = self.resources.get(&path) { + res + } else { + let string = read_file(&path).unwrap(); + let res = match FluentResource::try_new(string) { + Ok(res) => res, + Err((res, _err)) => res, + }; + self.resources.insert(path.to_string(), Box::new(res)) + } + } + + pub fn get_bundle( + &self, + locales: Vec, + resource_ids: Vec, + ) -> FluentBundle<&FluentResource> { + let mut bundle = FluentBundle::new(locales.clone()); + for res_id in &resource_ids { + let res = self.get_resource(res_id, &locales[0].to_string()); + bundle.add_resource(res).unwrap(); + } + bundle + } + + pub fn get_bundles( + &self, + locales: Vec, + resource_ids: Vec, + ) -> impl Iterator> { + let res_mgr = self; + let mut ptr = 0; + + iter::from_fn(move || { + locales.get(ptr).map(|locale| { + ptr += 1; + let mut bundle = FluentBundle::new(vec![locale.clone()]); + for res_id in &resource_ids { + let res = res_mgr.get_resource(res_id, &locale.to_string()); + bundle.add_resource(res).unwrap(); + } + bundle + }) + }) + } +} + +// Due to limitation of trait, we need a nameable Iterator type. Due to the +// lack of GATs, these have to own members instead of taking slices. +pub struct BundleIter { + locales: as IntoIterator>::IntoIter, + res_ids: FxHashSet, +} + +impl Iterator for BundleIter { + type Item = FluentBundleResult; + + fn next(&mut self) -> Option { + let locale = self.locales.next()?; + + let mut bundle = FluentBundle::new(vec![locale.clone()]); + + for res_id in self.res_ids.iter() { + let full_path = format!("./tests/resources/{}/{}", locale, res_id); + let source = fs::read_to_string(full_path).unwrap(); + let res = FluentResource::try_new(source).unwrap(); + bundle.add_resource(res).unwrap(); + } + Some(Ok(bundle)) + } +} + +impl Stream for BundleIter { + type Item = FluentBundleResult; + + fn poll_next( + self: std::pin::Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + todo!() + } +} + +impl BundleGenerator for ResourceManager { + type Resource = FluentResource; + type LocalesIter = std::vec::IntoIter; + type Iter = BundleIter; + type Stream = BundleIter; + + fn bundles_iter( + &self, + locales: Self::LocalesIter, + res_ids: FxHashSet, + ) -> Self::Iter { + BundleIter { locales, res_ids } + } + + fn bundles_stream( + &self, + _locales: Self::LocalesIter, + _res_ids: FxHashSet, + ) -> Self::Stream { + todo!() + } +} diff --git a/utshell-0.5.0/vendor/fluent-resmgr/tests/localization_test.rs b/utshell-0.5.0/vendor/fluent-resmgr/tests/localization_test.rs new file mode 100644 index 00000000..78ebcfbc --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/tests/localization_test.rs @@ -0,0 +1,46 @@ +use fluent_fallback::Localization; +use fluent_resmgr::resource_manager::ResourceManager; +use std::borrow::Cow; +use unic_langid::langid; + +#[test] +fn localization_format_value() { + let res_mgr = ResourceManager::new("./tests/resources/{locale}/{res_id}".into()); + + let loc = Localization::with_env( + vec!["test.ftl".into()], + true, + vec!["en-US".parse().unwrap(), "pl".parse().unwrap()], + res_mgr, + ); + let bundles = loc.bundles(); + let mut errors = vec![]; + + let value = bundles + .format_value_sync("hello-world", None, &mut errors) + .unwrap(); + assert_eq!(value, Some(Cow::Borrowed("Hello World"))); + + let value2 = bundles + .format_value_sync("new-message", None, &mut errors) + .unwrap(); + assert_eq!(value2, Some(Cow::Borrowed("Nowa Wiadomość"))); + + let value3 = bundles + .format_value_sync("missing-message", None, &mut errors) + .unwrap(); + assert_eq!(value3, None); +} + +#[test] +fn resmgr_get_bundle() { + let res_mgr = ResourceManager::new("./tests/resources/{locale}/{res_id}".into()); + + let bundle = res_mgr.get_bundle(vec![langid!("en-US")], vec!["test.ftl".into()]); + + let mut errors = vec![]; + let msg = bundle.get_message("hello-world").expect("Message exists"); + let pattern = msg.value().expect("Message has a value"); + let value = bundle.format_pattern(&pattern, None, &mut errors); + assert_eq!(value, "Hello World"); +} diff --git a/utshell-0.5.0/vendor/fluent-resmgr/tests/resources/en-US/test.ftl b/utshell-0.5.0/vendor/fluent-resmgr/tests/resources/en-US/test.ftl new file mode 100644 index 00000000..3751fe5a --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/tests/resources/en-US/test.ftl @@ -0,0 +1 @@ +hello-world = Hello World diff --git a/utshell-0.5.0/vendor/fluent-resmgr/tests/resources/pl/test.ftl b/utshell-0.5.0/vendor/fluent-resmgr/tests/resources/pl/test.ftl new file mode 100644 index 00000000..2c42c539 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-resmgr/tests/resources/pl/test.ftl @@ -0,0 +1,2 @@ +hello-world = Witaj Świecie +new-message = Nowa Wiadomość diff --git a/utshell-0.5.0/vendor/fluent-syntax/.cargo-checksum.json b/utshell-0.5.0/vendor/fluent-syntax/.cargo-checksum.json new file mode 100644 index 00000000..d1941314 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"3fd2bd8414b6f818747e28ac2e78d0d99795946f2b4c74ca5e5ca9ce1bc8f8e2","Cargo.toml":"a98f67a3a7a2c050115fffb1863b9eb7ff0de131f2125b25753aa5eb3793bef8","LICENSE-APACHE":"5db2b182453ff32ed40f7da63589c9667a3f8bd8b16b1471b152caae56f77e45","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"0ceb23fff33406f7663d967601e1ad7650a4664565c42d618961cc3a8fc81ea5","benches/contexts/README.md":"562d317f507caedd62cbe00e6b2bb350cb970168e5ebd5b3c497e68696e21e8b","benches/parser.rs":"b207acac3cc05025a323646dc72bc32b675740ebdcc602fc37f2ca42df9c6fb3","benches/parser_iai.rs":"10253310d8abbe979ae0833df4bb0d1e2b770d1e94fe99416dec7fcd23aa3f16","src/ast/helper.rs":"39187bbc97823ba0f3a9baadd76ddc59140bf09cddeb92997dd872e41b305375","src/ast/mod.rs":"389032943da7c1809d6b4bc903ab13662d715945bbd3df974a47b29e0884715f","src/bin/parser.rs":"06aa90e1b78f5f845c46b8abba86028c4c157555b580ea59b8a08b7ccba9907c","src/bin/update_fixtures.rs":"387ca0e6331942369a3a3aa6c5ae013aa1c87c612215ce20f486ca37d4acd55d","src/lib.rs":"b4a11659d3d233073a1d820872a1d48141d3343401295032f494f251af591d78","src/parser/comment.rs":"dff6546043538e3573eea98ea7eda3fd55d5846e4dbcb38a0595844862d979af","src/parser/core.rs":"4ef1a455ef50235bb3ab8da0c8da90caf73fd346f1b5e96d67ee8b3fc039ad04","src/parser/errors.rs":"7ac92c323c15f9efa10a37a5ba3894f7a348cadbd5bfc053afef901bbe53ad4b","src/parser/expression.rs":"737b6670e849e8f04b06146ebddb59b8da9f082660f427a564e7eb52ec674326","src/parser/helper.rs":"26ba1d0d64455220cc054a2c7c23051854b1915bf7d1028f4db7ec8a8dc9114b","src/parser/macros.rs":"d5927d8e6757b50bbdeb122eb3a9bde7ab939a7ba41c9dfeff216d3839a5162b","src/parser/mod.rs":"27378f63f5e98890b0928d54e0a7edf4828179bf37f9ed9e5e8c2eaac111bd75","src/parser/pattern.rs":"4566796f34b5b47f76aa682355b664001e370ff313537e32649d815e4d5edd5b","src/parser/runtime.rs":"280aefcd960a4e1d402132c38c6764582e471853aa0ef143b099edbdd41f4b6c","src/parser/slice.rs":"aad45bc35ecc3ff68bcd5b2671fecb134a4535d6ee463092422dfc5cc8b25a1d","src/unicode.rs":"799299d1895e0123dc837648bdd5adb2d16f9b8312d1f070570a03d40c2d4a07"},"package":"c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/fluent-syntax/Cargo.lock b/utshell-0.5.0/vendor/fluent-syntax/Cargo.lock new file mode 100644 index 00000000..46ad03de --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/Cargo.lock @@ -0,0 +1,672 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bstr" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9" + +[[package]] +name = "byteorder" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" + +[[package]] +name = "cast" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "const_fn" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" + +[[package]] +name = "criterion" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools 0.10.0", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" +dependencies = [ + "cast", + "itertools 0.9.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" +dependencies = [ + "cfg-if", + "const_fn", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "csv" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "fluent-syntax" +version = "0.11.0" +dependencies = [ + "criterion", + "glob", + "iai", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "half" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" + +[[package]] +name = "hermit-abi" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +dependencies = [ + "libc", +] + +[[package]] +name = "iai" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71a816c97c42258aa5834d07590b718b4c9a598944cd39a52dc25b351185d678" + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "memoffset" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "plotters" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" + +[[package]] +name = "plotters-svg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +dependencies = [ + "byteorder", +] + +[[package]] +name = "regex-syntax" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.123" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.123" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinytemplate" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64" + +[[package]] +name = "web-sys" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/utshell-0.5.0/vendor/fluent-syntax/Cargo.toml b/utshell-0.5.0/vendor/fluent-syntax/Cargo.toml new file mode 100644 index 00000000..cc6851d4 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/Cargo.toml @@ -0,0 +1,78 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "fluent-syntax" +version = "0.11.0" +authors = ["Zibi Braniecki ", "Staś Małolepszy "] +include = ["src/**/*", "benches/*.rs", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +description = "Parser/Serializer tools for Fluent Syntax. \n" +homepage = "http://www.projectfluent.org" +readme = "README.md" +keywords = ["localization", "l10n", "i18n", "intl", "internationalization"] +categories = ["localization", "internationalization"] +license = "Apache-2.0/MIT" +repository = "https://github.com/projectfluent/fluent-rs" + +[[bin]] +name = "parser" +path = "src/bin/parser.rs" + +[[bin]] +name = "update_fixtures" +path = "src/bin/update_fixtures.rs" +required-features = ["json"] + +[[test]] +name = "parser_fixtures" +path = "tests/parser_fixtures.rs" +required-features = ["json"] + +[[bench]] +name = "parser" +harness = false + +[[bench]] +name = "parser_iai" +harness = false +[dependencies.serde] +version = "1.0" +features = ["derive"] +optional = true + +[dependencies.serde_json] +version = "1.0" +optional = true + +[dependencies.thiserror] +version = "1.0" +[dev-dependencies.criterion] +version = "0.3" + +[dev-dependencies.glob] +version = "0.3" + +[dev-dependencies.iai] +version = "0.1" + +[dev-dependencies.serde] +version = "1.0" +features = ["derive"] + +[dev-dependencies.serde_json] +version = "1.0" + +[features] +all-benchmarks = [] +default = [] +json = ["serde", "serde_json"] diff --git a/utshell-0.5.0/vendor/fluent-syntax/LICENSE-APACHE b/utshell-0.5.0/vendor/fluent-syntax/LICENSE-APACHE new file mode 100644 index 00000000..35582f16 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Mozilla + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/fluent-syntax/LICENSE-MIT b/utshell-0.5.0/vendor/fluent-syntax/LICENSE-MIT new file mode 100644 index 00000000..5655fa31 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright 2017 Mozilla + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/utshell-0.5.0/vendor/fluent-syntax/README.md b/utshell-0.5.0/vendor/fluent-syntax/README.md new file mode 100644 index 00000000..f7214aae --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/README.md @@ -0,0 +1,63 @@ +# Fluent Syntax + +`fluent-syntax` is a parser/serializer API for the Fluent Syntax, part of the [Project Fluent](https://projectfluent.org/), a localization +framework designed to unleash the entire expressive power of natural language translations. + +[![crates.io](https://meritbadge.herokuapp.com/fluent-syntax)](https://crates.io/crates/fluent-syntax) +[![Build and test](https://github.com/projectfluent/fluent-rs/workflows/Build%20and%20test/badge.svg)](https://github.com/projectfluent/fluent-rs/actions?query=branch%3Amaster+workflow%3A%22Build+and+test%22) +[![Coverage Status](https://coveralls.io/repos/github/projectfluent/fluent-rs/badge.svg?branch=master)](https://coveralls.io/github/projectfluent/fluent-rs?branch=master) + +Status +------ + +The crate currently provides just a parser, which is tracking Fluent Syntax on its way to 1.0. + +Local Development +----------------- + + cargo build + cargo test + cargo bench + +When submitting a PR please use [`cargo fmt`][] (nightly). + +[`cargo fmt`]: https://github.com/rust-lang-nursery/rustfmt + + +Learn the FTL syntax +-------------------- + +FTL is a localization file format used for describing translation resources. +FTL stands for _Fluent Translation List_. + +FTL is designed to be simple to read, but at the same time allows to represent +complex concepts from natural languages like gender, plurals, conjugations, and +others. + + hello-user = Hello, { $username }! + +[Read the Fluent Syntax Guide][] in order to learn more about the syntax. If +you're a tool author you may be interested in the formal [EBNF grammar][]. + +[Read the Fluent Syntax Guide]: http://projectfluent.org/fluent/guide/ +[EBNF grammar]: https://github.com/projectfluent/fluent/tree/master/spec + + +Get Involved +------------ + +`fluent-rs` is open-source, licensed under the Apache License, Version 2.0. We +encourage everyone to take a look at our code and we'll listen to your +feedback. + + +Discuss +------- + +We'd love to hear your thoughts on Project Fluent! Whether you're a localizer +looking for a better way to express yourself in your language, or a developer +trying to make your app localizable and multilingual, or a hacker looking for +a project to contribute to, please do get in touch on discourse and the IRC channel. + + - Discourse: https://discourse.mozilla.org/c/fluent + - IRC channel: [irc://irc.mozilla.org/l20n](irc://irc.mozilla.org/l20n) diff --git a/utshell-0.5.0/vendor/fluent-syntax/benches/contexts/README.md b/utshell-0.5.0/vendor/fluent-syntax/benches/contexts/README.md new file mode 100644 index 00000000..7d37ac0f --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/benches/contexts/README.md @@ -0,0 +1,4 @@ +The following context is extracted from +the `browser.xhtml` localization context +from mozilla-central rev 51efc4b931f7 +from 2020-03-03. diff --git a/utshell-0.5.0/vendor/fluent-syntax/benches/parser.rs b/utshell-0.5.0/vendor/fluent-syntax/benches/parser.rs new file mode 100644 index 00000000..f14725a5 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/benches/parser.rs @@ -0,0 +1,141 @@ +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::Criterion; +use std::collections::HashMap; +use std::fs; +use std::io; + +use fluent_syntax::parser::parse_runtime; + +fn read_file(path: &str) -> Result { + fs::read_to_string(path) +} + +#[cfg(feature = "all-benchmarks")] +fn get_resources(tests: &[&'static str]) -> HashMap<&'static str, String> { + let mut ftl_strings = HashMap::new(); + for test in tests { + let path = format!("./benches/{}", test); + ftl_strings.insert(*test, read_file(&path).expect("Couldn't load file")); + } + return ftl_strings; +} + +fn get_ctxs(tests: &[&'static str]) -> HashMap<&'static str, Vec> { + let mut ftl_strings = HashMap::new(); + for test in tests { + let paths = fs::read_dir(format!("./benches/contexts/{}", test)).unwrap(); + let strings = paths + .into_iter() + .map(|p| { + let p = p.unwrap().path(); + let path = p.to_str().unwrap(); + read_file(path).unwrap() + }) + .collect::>(); + ftl_strings.insert(*test, strings); + } + return ftl_strings; +} + +fn parse_bench(c: &mut Criterion) { + #[cfg(feature = "all-benchmarks")] + { + let tests = &["simple.ftl", "preferences.ftl", "menubar.ftl"]; + + let mut group = c.benchmark_group("parse_resource"); + + for (name, resource) in get_resources(tests) { + group.bench_with_input(name, &resource, |b, source| { + b.iter(|| parse_runtime(source.as_str()).expect("Parsing of the FTL failed.")) + }); + } + + group.finish(); + } + + let ctx_names = &["browser", "preferences"]; + + #[cfg(feature = "all-benchmarks")] + { + use fluent_syntax::parser::parse; + + let mut group = c.benchmark_group("parse_ctx"); + + for (name, ctx) in get_ctxs(ctx_names) { + group.bench_with_input(name, &ctx, |b, ctx| { + b.iter(|| { + for source in ctx { + parse(source.as_str()).expect("Parsing of the FTL failed."); + } + }) + }); + } + + group.finish(); + } + + { + let mut group = c.benchmark_group("parse_ctx_runtime"); + + for (name, ctx) in get_ctxs(ctx_names) { + group.bench_with_input(name, &ctx, |b, ctx| { + b.iter(|| { + for source in ctx { + parse_runtime(source.as_str()).expect("Parsing of the FTL failed."); + } + }) + }); + } + + group.finish(); + } + + #[cfg(feature = "all-benchmarks")] + { + use fluent_syntax::unicode::{unescape_unicode, unescape_unicode_to_string}; + + let strings = &[ + "foo", + "This is an example value", + "Hello \\u00e3\\u00e9 World", + "\\u004c\\u006f\\u0072\\u0065\\u006d \\u0069\\u0070\\u0073\\u0075\\u006d \\u0064\\u006f\\u006c\\u006f\\u0072 \\u0073\\u0069\\u0074 \\u0061\\u006d\\u0065\\u0074", + "Let me introduce \\\"The\\\" Fluent", + "And here's an example of \\\\ a character to be escaped", + "But this message is completely unescape free", + "And so is this one", + "Maybe this one is as well completely escape free", + "Welcome to Mozilla Firefox", + "\\u0054\\u0068\\u0065\\u0073\\u0065 \\u0073\\u0065\\u0074\\u0074\\u0069\\u006e\\u0067\\u0073 \\u0061\\u0072\\u0065 \\u0074\\u0061\\u0069\\u006c\\u006f\\u0072\\u0065\\u0064 \\u0074\\u006f \\u0079\\u006f\\u0075\\u0072 \\u0063\\u006f\\u006d\\u0070\\u0075\\u0074\\u0065\\u0072\\u2019\\u0073 \\u0068\\u0061\\u0072\\u0064\\u0077\\u0061\\u0072\\u0065 \\u0061\\u006e\\u0064 \\u006f\\u0070\\u0065\\u0072\\u0061\\u0074\\u0069\\u006e\\u0067 \\u0073\\u0079\\u0073\\u0074\\u0065\\u006d\\u002e", + "These settings are tailored to your computer’s hardware and operating system", + "Use recommended performance settings", + "\\u0041\\u0064\\u0064\\u0069\\u0074\\u0069\\u006f\\u006e\\u0061\\u006c \\u0063\\u006f\\u006e\\u0074\\u0065\\u006e\\u0074 \\u0070\\u0072\\u006f\\u0063\\u0065\\u0073\\u0073\\u0065\\u0073 \\u0063\\u0061\\u006e \\u0069\\u006d\\u0070\\u0072\\u006f\\u0076\\u0065 \\u0070\\u0065\\u0072\\u0066\\u006f\\u0072\\u006d\\u0061\\u006e\\u0063\\u0065 \\u0077\\u0068\\u0065\\u006e \\u0075\\u0073\\u0069\\u006e\\u0067 \\u006d\\u0075\\u006c\\u0074\\u0069\\u0070\\u006c\\u0065 \\u0074\\u0061\\u0062\\u0073\\u002c \\u0062\\u0075\\u0074 \\u0077\\u0069\\u006c\\u006c \\u0061\\u006c\\u0073\\u006f \\u0075\\u0073\\u0065 \\u006d\\u006f\\u0072\\u0065 \\u006d\\u0065\\u006d\\u006f\\u0072\\u0079\\u002e", + "Additional content processes can improve performance when using multiple tabs, but will also use more memory.", + ]; + + let mut group = c.benchmark_group("unicode"); + + group.bench_function("writer", |b| { + b.iter(|| { + let mut result = String::new(); + for s in strings { + unescape_unicode(&mut result, s).unwrap(); + result.clear(); + } + }) + }); + + group.bench_function("to_string", |b| { + b.iter(|| { + for s in strings { + let _ = unescape_unicode_to_string(s); + } + }) + }); + + group.finish(); + } +} + +criterion_group!(benches, parse_bench,); +criterion_main!(benches); diff --git a/utshell-0.5.0/vendor/fluent-syntax/benches/parser_iai.rs b/utshell-0.5.0/vendor/fluent-syntax/benches/parser_iai.rs new file mode 100644 index 00000000..f2eed5e5 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/benches/parser_iai.rs @@ -0,0 +1,15 @@ +use fluent_syntax::parser::parse_runtime; + +fn iai_parse_ctx_runtime() { + let files = &[ + include_str!("contexts/browser/appmenu.ftl"), + include_str!("contexts/browser/browser.ftl"), + include_str!("contexts/browser/menubar.ftl"), + include_str!("contexts/preferences/preferences.ftl"), + ]; + for source in files { + parse_runtime(*source).expect("Parsing of the FTL failed."); + } +} + +iai::main!(iai_parse_ctx_runtime); diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/ast/helper.rs b/utshell-0.5.0/vendor/fluent-syntax/src/ast/helper.rs new file mode 100644 index 00000000..923437d2 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/ast/helper.rs @@ -0,0 +1,25 @@ +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +use super::Comment; +// This is a helper struct used to properly deserialize referential +// JSON comments which are single continous String, into a vec of +// content slices. +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(untagged))] +pub enum CommentDef { + Single { content: S }, + Multi { content: Vec }, +} + +impl<'s, S> From> for Comment { + fn from(input: CommentDef) -> Self { + match input { + CommentDef::Single { content } => Self { + content: vec![content], + }, + CommentDef::Multi { content } => Self { content }, + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/ast/mod.rs b/utshell-0.5.0/vendor/fluent-syntax/src/ast/mod.rs new file mode 100644 index 00000000..5b79bb3e --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/ast/mod.rs @@ -0,0 +1,1446 @@ +//! Abstract Syntax Tree representation of the Fluent Translation List. +//! +//! The AST of Fluent contains all nodes structures to represent a complete +//! representation of the FTL resource. +//! +//! The tree preserves all semantic information and allow for round-trip +//! of a canonically written FTL resource. +//! +//! The root node is called [`Resource`] and contains a list of [`Entry`] nodes +//! representing all possible entries in the Fluent Translation List. +//! +//! # Example +//! +//! ``` +//! use fluent_syntax::parser; +//! use fluent_syntax::ast; +//! +//! let ftl = r#" +//! +//! ## This is a message comment +//! hello-world = Hello World! +//! .tooltip = Tooltip for you, { $userName }. +//! +//! "#; +//! +//! let resource = parser::parse(ftl) +//! .expect("Failed to parse an FTL resource."); +//! +//! assert_eq!( +//! resource.body[0], +//! ast::Entry::Message( +//! ast::Message { +//! id: ast::Identifier { +//! name: "hello-world" +//! }, +//! value: Some(ast::Pattern { +//! elements: vec![ +//! ast::PatternElement::TextElement { +//! value: "Hello World!" +//! }, +//! ] +//! }), +//! attributes: vec![ +//! ast::Attribute { +//! id: ast::Identifier { +//! name: "tooltip" +//! }, +//! value: ast::Pattern { +//! elements: vec![ +//! ast::PatternElement::TextElement { +//! value: "Tooltip for you, " +//! }, +//! ast::PatternElement::Placeable { +//! expression: ast::Expression::Inline( +//! ast::InlineExpression::VariableReference { +//! id: ast::Identifier { +//! name: "userName" +//! } +//! } +//! ) +//! }, +//! ast::PatternElement::TextElement { +//! value: "." +//! }, +//! ] +//! } +//! } +//! ], +//! comment: Some( +//! ast::Comment { +//! content: vec!["This is a message comment"] +//! } +//! ) +//! } +//! ), +//! ); +//! ``` +//! +//! ## Errors +//! +//! Fluent AST preserves blocks containing invaid syntax as [`Entry::Junk`]. +//! +//! ## White space +//! +//! At the moment, AST does not preserve white space. In result only a +//! canonical form of the AST is suitable for a round-trip. +mod helper; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// Root node of a Fluent Translation List. +/// +/// A [`Resource`] contains a body with a list of [`Entry`] nodes. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = ""; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Resource { + pub body: Vec>, +} + +/// A top-level node representing an entry of a [`Resource`]. +/// +/// Every [`Entry`] is a standalone element and the parser is capable +/// of recovering from errors by identifying a beginning of a next entry. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// key = Value +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ) +/// ] +/// } +/// ); +/// ``` +/// +/// # Junk Entry +/// +/// If FTL source contains invalid FTL content, it will be preserved +/// in form of [`Entry::Junk`] nodes. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// g@rb@ge En!ry +/// +/// "#; +/// +/// let (resource, _) = parser::parse(ftl) +/// .expect_err("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Junk { +/// content: "g@rb@ge En!ry\n\n" +/// } +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub enum Entry { + Message(Message), + Term(Term), + Comment(Comment), + GroupComment(Comment), + ResourceComment(Comment), + Junk { content: S }, +} + +/// Message node represents the most common [`Entry`] in an FTL [`Resource`]. +/// +/// A message is a localization unit with a [`Identifier`] unique within a given +/// [`Resource`], and a value or attributes with associated [`Pattern`]. +/// +/// A message can contain a simple text value, or a compound combination of value +/// and attributes which together can be used to localize a complex User Interface +/// element. +/// +/// Finally, each [`Message`] may have an associated [`Comment`]. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = Hello, World! +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello, World!" +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }) +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Message { + pub id: Identifier, + pub value: Option>, + pub attributes: Vec>, + pub comment: Option>, +} + +/// A Fluent [`Term`]. +/// +/// Terms are semantically similar to [`Message`] nodes, but +/// they represent a separate concept in Fluent system. +/// +/// Every term has to have a value, and the parser will +/// report errors when term references are used in wrong positions. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// -brand-name = Nightly +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Term(ast::Term { +/// id: ast::Identifier { +/// name: "brand-name" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Nightly" +/// } +/// ] +/// }, +/// attributes: vec![], +/// comment: None, +/// }) +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Term { + pub id: Identifier, + pub value: Pattern, + pub attributes: Vec>, + pub comment: Option>, +} + +/// Pattern contains a value of a [`Message`], [`Term`] or an [`Attribute`]. +/// +/// Each pattern is a list of [`PatternElement`] nodes representing +/// either a simple textual value, or a combination of text literals +/// and placeholder [`Expression`] nodes. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = Hello, World! +/// +/// welcome = Welcome, { $userName }. +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello, World!" +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "welcome" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Welcome, " +/// }, +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Inline( +/// ast::InlineExpression::VariableReference { +/// id: ast::Identifier { +/// name: "userName" +/// } +/// } +/// ) +/// }, +/// ast::PatternElement::TextElement { +/// value: "." +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Pattern { + pub elements: Vec>, +} + +/// PatternElement is an element of a [`Pattern`]. +/// +/// Each [`PatternElement`] node represents +/// either a simple textual value, or a combination of text literals +/// and placeholder [`Expression`] nodes. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = Hello, World! +/// +/// welcome = Welcome, { $userName }. +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello, World!" +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "welcome" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Welcome, " +/// }, +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Inline( +/// ast::InlineExpression::VariableReference { +/// id: ast::Identifier { +/// name: "userName" +/// } +/// } +/// ) +/// }, +/// ast::PatternElement::TextElement { +/// value: "." +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub enum PatternElement { + TextElement { value: S }, + Placeable { expression: Expression }, +} + +/// Attribute represents a part of a [`Message`] or [`Term`]. +/// +/// Attributes are used to express a compound list of keyed +/// [`Pattern`] elements on an entry. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = +/// .title = This is a title +/// .accesskey = T +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: None, +/// attributes: vec![ +/// ast::Attribute { +/// id: ast::Identifier { +/// name: "title" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "This is a title" +/// }, +/// ] +/// } +/// }, +/// ast::Attribute { +/// id: ast::Identifier { +/// name: "accesskey" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "T" +/// }, +/// ] +/// } +/// } +/// ], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Attribute { + pub id: Identifier, + pub value: Pattern, +} + +/// Identifier is part of nodes such as [`Message`], [`Term`] and [`Attribute`]. +/// +/// It is used to associate a unique key with an [`Entry`] or an [`Attribute`] +/// and in [`Expression`] nodes to refer to another entry. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = Value +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value" +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Identifier { + pub name: S, +} + +/// Variant is a single branch of a value in a [`Select`](Expression::Select) expression. +/// +/// It's a pair of [`VariantKey`] and [`Pattern`]. If the selector match the +/// key, then the value of the variant is returned as the value of the expression. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = { $var -> +/// [key1] Value 1 +/// *[other] Value 2 +/// } +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Select { +/// selector: ast::InlineExpression::VariableReference { +/// id: ast::Identifier { name: "var" }, +/// }, +/// variants: vec![ +/// ast::Variant { +/// key: ast::VariantKey::Identifier { +/// name: "key1" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 1", +/// } +/// ] +/// }, +/// default: false, +/// }, +/// ast::Variant { +/// key: ast::VariantKey::Identifier { +/// name: "other" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 2", +/// } +/// ] +/// }, +/// default: true, +/// }, +/// ] +/// } +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub struct Variant { + pub key: VariantKey, + pub value: Pattern, + pub default: bool, +} + +/// A key of a [`Variant`]. +/// +/// Variant key can be either an identifier or a number. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// hello-world = { $var -> +/// [0] Value 1 +/// *[other] Value 2 +/// } +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Select { +/// selector: ast::InlineExpression::VariableReference { +/// id: ast::Identifier { name: "var" }, +/// }, +/// variants: vec![ +/// ast::Variant { +/// key: ast::VariantKey::NumberLiteral { +/// value: "0" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 1", +/// } +/// ] +/// }, +/// default: false, +/// }, +/// ast::Variant { +/// key: ast::VariantKey::Identifier { +/// name: "other" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 2", +/// } +/// ] +/// }, +/// default: true, +/// }, +/// ] +/// } +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub enum VariantKey { + Identifier { name: S }, + NumberLiteral { value: S }, +} + +/// Fluent [`Comment`]. +/// +/// In Fluent, comments may be standalone, or associated with +/// an entry such as [`Term`] or [`Message`]. +/// +/// When used as a standalone [`Entry`], comments may appear in one of +/// three levels: +/// +/// * Standalone comment +/// * Group comment associated with a group of messages +/// * Resource comment associated with the whole resource +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// ## A standalone level comment +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Comment(ast::Comment { +/// content: vec![ +/// "A standalone level comment" +/// ] +/// }) +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(from = "helper::CommentDef"))] +pub struct Comment { + pub content: Vec, +} + +/// List of arguments for a [`FunctionReference`](InlineExpression::FunctionReference) or a +/// [`TermReference`](InlineExpression::TermReference). +/// +/// Function and Term reference may contain a list of positional and +/// named arguments passed to them. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// key = { FUNC($var1, "literal", style: "long") } +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Inline( +/// ast::InlineExpression::FunctionReference { +/// id: ast::Identifier { +/// name: "FUNC" +/// }, +/// arguments: ast::CallArguments { +/// positional: vec![ +/// ast::InlineExpression::VariableReference { +/// id: ast::Identifier { +/// name: "var1" +/// } +/// }, +/// ast::InlineExpression::StringLiteral { +/// value: "literal", +/// } +/// ], +/// named: vec![ +/// ast::NamedArgument { +/// name: ast::Identifier { +/// name: "style" +/// }, +/// value: ast::InlineExpression::StringLiteral +/// { +/// value: "long" +/// } +/// } +/// ], +/// } +/// } +/// ) +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ) +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone, Default)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub struct CallArguments { + pub positional: Vec>, + pub named: Vec>, +} + +/// A key-value pair used in [`CallArguments`]. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// key = { FUNC(style: "long") } +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Inline( +/// ast::InlineExpression::FunctionReference { +/// id: ast::Identifier { +/// name: "FUNC" +/// }, +/// arguments: ast::CallArguments { +/// positional: vec![], +/// named: vec![ +/// ast::NamedArgument { +/// name: ast::Identifier { +/// name: "style" +/// }, +/// value: ast::InlineExpression::StringLiteral +/// { +/// value: "long" +/// } +/// } +/// ], +/// } +/// } +/// ) +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ) +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub struct NamedArgument { + pub name: Identifier, + pub value: InlineExpression, +} + +/// A subset of expressions which can be used as [`Placeable`](PatternElement::Placeable), +/// [`selector`](Expression::Select), or in [`CallArguments`]. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// key = { $emailCount } +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Inline( +/// ast::InlineExpression::VariableReference { +/// id: ast::Identifier { +/// name: "emailCount" +/// }, +/// } +/// ) +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ) +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "type"))] +pub enum InlineExpression { + /// Single line string literal enclosed in `"`. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { "this is a literal" } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::StringLiteral { + /// value: "this is a literal", + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + StringLiteral { value: S }, + /// A number literal. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { -0.5 } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::NumberLiteral { + /// value: "-0.5", + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + NumberLiteral { value: S }, + /// A function reference. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { FUNC() } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::FunctionReference { + /// id: ast::Identifier { + /// name: "FUNC" + /// }, + /// arguments: ast::CallArguments::default(), + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + FunctionReference { + id: Identifier, + arguments: CallArguments, + }, + /// A reference to another message. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { key2 } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::MessageReference { + /// id: ast::Identifier { + /// name: "key2" + /// }, + /// attribute: None, + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + MessageReference { + id: Identifier, + attribute: Option>, + }, + /// A reference to a term. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { -brand-name } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::TermReference { + /// id: ast::Identifier { + /// name: "brand-name" + /// }, + /// attribute: None, + /// arguments: None, + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + TermReference { + id: Identifier, + attribute: Option>, + arguments: Option>, + }, + /// A reference to a variable. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { $var1 } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::VariableReference { + /// id: ast::Identifier { + /// name: "var1" + /// }, + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + VariableReference { id: Identifier }, + /// A placeable which may contain another expression. + /// + /// # Example + /// + /// ``` + /// use fluent_syntax::parser; + /// use fluent_syntax::ast; + /// + /// let ftl = r#" + /// + /// key = { { "placeable" } } + /// + /// "#; + /// + /// let resource = parser::parse(ftl) + /// .expect("Failed to parse an FTL resource."); + /// + /// assert_eq!( + /// resource, + /// ast::Resource { + /// body: vec![ + /// ast::Entry::Message( + /// ast::Message { + /// id: ast::Identifier { + /// name: "key" + /// }, + /// value: Some(ast::Pattern { + /// elements: vec![ + /// ast::PatternElement::Placeable { + /// expression: ast::Expression::Inline( + /// ast::InlineExpression::Placeable { + /// expression: Box::new( + /// ast::Expression::Inline( + /// ast::InlineExpression::StringLiteral { + /// value: "placeable" + /// } + /// ) + /// ) + /// } + /// ) + /// }, + /// ] + /// }), + /// attributes: vec![], + /// comment: None, + /// } + /// ) + /// ] + /// } + /// ); + /// ``` + Placeable { expression: Box> }, +} + +/// An expression that is either a select expression or an inline expression. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// +/// key = { $var -> +/// [key1] Value 1 +/// *[other] Value 2 +/// } +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource, +/// ast::Resource { +/// body: vec![ +/// ast::Entry::Message(ast::Message { +/// id: ast::Identifier { +/// name: "key" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::Placeable { +/// expression: ast::Expression::Select { +/// selector: ast::InlineExpression::VariableReference { +/// id: ast::Identifier { name: "var" }, +/// }, +/// variants: vec![ +/// ast::Variant { +/// key: ast::VariantKey::Identifier { +/// name: "key1" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 1", +/// } +/// ] +/// }, +/// default: false, +/// }, +/// ast::Variant { +/// key: ast::VariantKey::Identifier { +/// name: "other" +/// }, +/// value: ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 2", +/// } +/// ] +/// }, +/// default: true, +/// }, +/// ] +/// } +/// } +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// }), +/// ] +/// } +/// ); +/// ``` +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(untagged))] +pub enum Expression { + Select { + selector: InlineExpression, + variants: Vec>, + }, + Inline(InlineExpression), +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/bin/parser.rs b/utshell-0.5.0/vendor/fluent-syntax/src/bin/parser.rs new file mode 100644 index 00000000..46275a72 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/bin/parser.rs @@ -0,0 +1,42 @@ +use fluent_syntax::parser::parse; +use std::env; +use std::fs::File; +use std::io; +use std::io::Read; + +fn read_file(path: &str) -> Result { + let mut f = File::open(path)?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + Ok(s) +} + +fn main() { + let args: Vec = env::args().collect(); + let source = read_file(args.get(1).expect("Pass an argument")).expect("Failed to fetch file"); + + let (ast, errors) = match parse(source.as_str()) { + Ok(ast) => (ast, None), + Err((ast, err)) => (ast, Some(err)), + }; + + #[cfg(feature = "json")] + { + let target_json = serde_json::to_string_pretty(&ast).unwrap(); + println!("{}", target_json); + } + #[cfg(not(feature = "json"))] + { + use std::fmt::Write; + let mut result = String::new(); + write!(result, "{:#?}", ast).unwrap(); + println!("{}", result); + } + + if let Some(errors) = errors { + println!("\n======== Errors ========== \n"); + for err in errors { + println!("Err: {:#?}", err); + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/bin/update_fixtures.rs b/utshell-0.5.0/vendor/fluent-syntax/src/bin/update_fixtures.rs new file mode 100644 index 00000000..01e7a02a --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/bin/update_fixtures.rs @@ -0,0 +1,44 @@ +use std::fs; +use std::io; + +use fluent_syntax::parser::parse; + +fn read_file(path: &str) -> Result { + fs::read_to_string(path) +} + +fn write_file(path: &str, source: &str) -> Result<(), io::Error> { + fs::write(path, source) +} + +fn main() { + let samples = &["menubar", "preferences", "simple"]; + let contexts = &["browser", "preferences"]; + + for sample in samples { + let path = format!("./benches/{}.ftl", sample); + let source = read_file(&path).unwrap(); + let ast = parse(source).unwrap(); + let target_json = serde_json::to_string_pretty(&ast).unwrap(); + let new_path = format!("./tests/fixtures/benches/{}.json", sample); + write_file(&new_path, &target_json).unwrap(); + } + + for test in contexts { + let paths = fs::read_dir(format!("./benches/contexts/{}", test)).unwrap(); + for path in paths.into_iter() { + let p = path.unwrap().path(); + let file_name = p.file_name().unwrap().to_str().unwrap(); + let path = p.to_str().unwrap(); + let source = read_file(path).unwrap(); + let ast = parse(source).unwrap(); + let target_json = serde_json::to_string_pretty(&ast).unwrap(); + let new_path = format!( + "./tests/fixtures/benches/contexts/{}/{}", + test, + file_name.replace(".ftl", ".json") + ); + write_file(&new_path, &target_json).unwrap(); + } + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/lib.rs b/utshell-0.5.0/vendor/fluent-syntax/src/lib.rs new file mode 100644 index 00000000..5b9cbbfe --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/lib.rs @@ -0,0 +1,51 @@ +//! Fluent is a modern localization system designed to improve how software is translated. +//! +//! `fluent-syntax` is the lowest level component of the [Fluent Localization +//! System](https://www.projectfluent.org). +//! +//! It exposes components necessary for parsing and tooling operations on Fluent Translation Lists ("FTL"). +//! +//! The crate provides a [`parser`] module which allows for parsing of an +//! input string to an Abstract Syntax Tree defined in the [`ast`] module. +//! +//! The [`unicode`] module exposes a set of helper functions used to decode +//! escaped unicode literals according to Fluent specification. +//! +//! # Example +//! +//! ``` +//! use fluent_syntax::parser; +//! use fluent_syntax::ast; +//! +//! let ftl = r#" +//! +//! hello-world = Hello World! +//! +//! "#; +//! +//! let resource = parser::parse(ftl) +//! .expect("Failed to parse an FTL resource."); +//! +//! assert_eq!( +//! resource.body[0], +//! ast::Entry::Message( +//! ast::Message { +//! id: ast::Identifier { +//! name: "hello-world" +//! }, +//! value: Some(ast::Pattern { +//! elements: vec![ +//! ast::PatternElement::TextElement { +//! value: "Hello World!" +//! }, +//! ] +//! }), +//! attributes: vec![], +//! comment: None, +//! } +//! ), +//! ); +//! ``` +pub mod ast; +pub mod parser; +pub mod unicode; diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/comment.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/comment.rs new file mode 100644 index 00000000..a63483c1 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/comment.rs @@ -0,0 +1,89 @@ +use super::{core::Parser, core::Result, Slice}; +use crate::ast; + +#[derive(Debug, PartialEq, Clone, Copy)] +pub(super) enum Level { + None = 0, + Regular = 1, + Group = 2, + Resource = 3, +} + +impl<'s, S> Parser +where + S: Slice<'s>, +{ + pub(super) fn get_comment(&mut self) -> Result<(ast::Comment, Level)> { + let mut level = Level::None; + let mut content = vec![]; + + while self.ptr < self.length { + let line_level = self.get_comment_level(); + if line_level == Level::None { + self.ptr -= 1; + break; + } else if level != Level::None && line_level != level { + self.ptr -= line_level as usize; + break; + } + + level = line_level; + + if self.ptr == self.length { + break; + } else if self.is_current_byte(b'\n') { + content.push(self.get_comment_line()); + } else { + if let Err(e) = self.expect_byte(b' ') { + if content.is_empty() { + return Err(e); + } else { + self.ptr -= line_level as usize; + break; + } + } + content.push(self.get_comment_line()); + } + self.skip_eol(); + } + + Ok((ast::Comment { content }, level)) + } + + pub(super) fn skip_comment(&mut self) { + loop { + while self.ptr < self.length && !self.is_current_byte(b'\n') { + self.ptr += 1; + } + self.ptr += 1; + if self.is_current_byte(b'#') { + self.ptr += 1; + } else { + break; + } + } + } + + fn get_comment_level(&mut self) -> Level { + if self.take_byte_if(b'#') { + if self.take_byte_if(b'#') { + if self.take_byte_if(b'#') { + return Level::Resource; + } + return Level::Group; + } + return Level::Regular; + } + Level::None + } + + fn get_comment_line(&mut self) -> S { + let start_pos = self.ptr; + + while !self.is_eol() { + self.ptr += 1; + } + + self.source.slice(start_pos..self.ptr) + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/core.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/core.rs new file mode 100644 index 00000000..68ad8dc0 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/core.rs @@ -0,0 +1,307 @@ +use super::{ + comment, + errors::{ErrorKind, ParserError}, + slice::Slice, +}; +use crate::ast; + +pub type Result = std::result::Result; + +pub struct Parser { + pub(super) source: S, + pub(super) ptr: usize, + pub(super) length: usize, +} + +impl<'s, S> Parser +where + S: Slice<'s>, +{ + pub fn new(source: S) -> Self { + let length = source.as_ref().as_bytes().len(); + Self { + source, + ptr: 0, + length, + } + } + + pub fn parse( + mut self, + ) -> std::result::Result, (ast::Resource, Vec)> { + let mut errors = vec![]; + + let mut body = vec![]; + + self.skip_blank_block(); + let mut last_comment = None; + let mut last_blank_count = 0; + + while self.ptr < self.length { + let entry_start = self.ptr; + let mut entry = self.get_entry(entry_start); + + if let Some(comment) = last_comment.take() { + match entry { + Ok(ast::Entry::Message(ref mut msg)) if last_blank_count < 2 => { + msg.comment = Some(comment); + } + Ok(ast::Entry::Term(ref mut term)) if last_blank_count < 2 => { + term.comment = Some(comment); + } + _ => { + body.push(ast::Entry::Comment(comment)); + } + } + } + + match entry { + Ok(ast::Entry::Comment(comment)) => { + last_comment = Some(comment); + } + Ok(entry) => { + body.push(entry); + } + Err(mut err) => { + self.skip_to_next_entry_start(); + err.slice = Some(entry_start..self.ptr); + errors.push(err); + let content = self.source.slice(entry_start..self.ptr); + body.push(ast::Entry::Junk { content }); + } + } + last_blank_count = self.skip_blank_block(); + } + + if let Some(last_comment) = last_comment.take() { + body.push(ast::Entry::Comment(last_comment)); + } + if errors.is_empty() { + Ok(ast::Resource { body }) + } else { + Err((ast::Resource { body }, errors)) + } + } + + fn get_entry(&mut self, entry_start: usize) -> Result> { + let entry = match get_current_byte!(self) { + Some(b'#') => { + let (comment, level) = self.get_comment()?; + match level { + comment::Level::Regular => ast::Entry::Comment(comment), + comment::Level::Group => ast::Entry::GroupComment(comment), + comment::Level::Resource => ast::Entry::ResourceComment(comment), + comment::Level::None => unreachable!(), + } + } + Some(b'-') => ast::Entry::Term(self.get_term(entry_start)?), + _ => ast::Entry::Message(self.get_message(entry_start)?), + }; + Ok(entry) + } + + pub fn get_message(&mut self, entry_start: usize) -> Result> { + let id = self.get_identifier()?; + self.skip_blank_inline(); + self.expect_byte(b'=')?; + let pattern = self.get_pattern()?; + + self.skip_blank_block(); + + let attributes = self.get_attributes(); + + if pattern.is_none() && attributes.is_empty() { + let entry_id = id.name.as_ref().to_owned(); + return error!( + ErrorKind::ExpectedMessageField { entry_id }, + entry_start, self.ptr + ); + } + + Ok(ast::Message { + id, + value: pattern, + attributes, + comment: None, + }) + } + + pub fn get_term(&mut self, entry_start: usize) -> Result> { + self.expect_byte(b'-')?; + let id = self.get_identifier()?; + self.skip_blank_inline(); + self.expect_byte(b'=')?; + self.skip_blank_inline(); + + let value = self.get_pattern()?; + + self.skip_blank_block(); + + let attributes = self.get_attributes(); + + if let Some(value) = value { + Ok(ast::Term { + id, + value, + attributes, + comment: None, + }) + } else { + error!( + ErrorKind::ExpectedTermField { + entry_id: id.name.as_ref().to_owned() + }, + entry_start, self.ptr + ) + } + } + + fn get_attributes(&mut self) -> Vec> { + let mut attributes = vec![]; + + loop { + let line_start = self.ptr; + self.skip_blank_inline(); + if !self.take_byte_if(b'.') { + self.ptr = line_start; + break; + } + + if let Ok(attr) = self.get_attribute() { + attributes.push(attr); + } else { + self.ptr = line_start; + break; + } + } + attributes + } + + fn get_attribute(&mut self) -> Result> { + let id = self.get_identifier()?; + self.skip_blank_inline(); + self.expect_byte(b'=')?; + let pattern = self.get_pattern()?; + + match pattern { + Some(pattern) => Ok(ast::Attribute { id, value: pattern }), + None => error!(ErrorKind::MissingValue, self.ptr), + } + } + + pub(super) fn get_identifier_unchecked(&mut self) -> ast::Identifier { + let mut ptr = self.ptr; + + while matches!(get_byte!(self, ptr), Some(b) if b.is_ascii_alphanumeric() || *b == b'-' || *b == b'_') + { + ptr += 1; + } + + let name = self.source.slice(self.ptr - 1..ptr); + self.ptr = ptr; + + ast::Identifier { name } + } + + pub(super) fn get_identifier(&mut self) -> Result> { + if !self.is_identifier_start() { + return error!( + ErrorKind::ExpectedCharRange { + range: "a-zA-Z".to_string() + }, + self.ptr + ); + } + self.ptr += 1; + Ok(self.get_identifier_unchecked()) + } + + pub(super) fn get_attribute_accessor(&mut self) -> Result>> { + if self.take_byte_if(b'.') { + let ident = self.get_identifier()?; + Ok(Some(ident)) + } else { + Ok(None) + } + } + + fn get_variant_key(&mut self) -> Result> { + self.skip_blank(); + + let key = if self.is_number_start() { + ast::VariantKey::NumberLiteral { + value: self.get_number_literal()?, + } + } else { + ast::VariantKey::Identifier { + name: self.get_identifier()?.name, + } + }; + + self.skip_blank(); + + self.expect_byte(b']')?; + + Ok(key) + } + + pub(super) fn get_variants(&mut self) -> Result>> { + let mut variants = Vec::with_capacity(2); + let mut has_default = false; + + loop { + let default = self.take_byte_if(b'*'); + if default { + if has_default { + return error!(ErrorKind::MultipleDefaultVariants, self.ptr); + } else { + has_default = true; + } + } + + if !self.take_byte_if(b'[') { + break; + } + + let key = self.get_variant_key()?; + + let value = self.get_pattern()?; + + if let Some(value) = value { + variants.push(ast::Variant { + key, + value, + default, + }); + self.skip_blank(); + } else { + return error!(ErrorKind::MissingValue, self.ptr); + } + } + + if has_default { + Ok(variants) + } else { + error!(ErrorKind::MissingDefaultVariant, self.ptr) + } + } + + pub(super) fn get_placeable(&mut self) -> Result> { + self.skip_blank(); + let exp = self.get_expression()?; + self.skip_blank_inline(); + self.expect_byte(b'}')?; + + let invalid_expression_found = match &exp { + ast::Expression::Inline(ast::InlineExpression::TermReference { + ref attribute, .. + }) => attribute.is_some(), + _ => false, + }; + if invalid_expression_found { + return error!(ErrorKind::TermAttributeAsPlaceable, self.ptr); + } + + Ok(exp) + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/errors.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/errors.rs new file mode 100644 index 00000000..2c29f97b --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/errors.rs @@ -0,0 +1,169 @@ +use std::ops::Range; +use thiserror::Error; + +/// Error containing information about an error encountered by the Fluent Parser. +/// +/// Errors in Fluent Parser are non-fatal, and the syntax has been +/// designed to allow for strong recovery. +/// +/// In result [`ParserError`] is designed to point at the slice of +/// the input that is most likely to be a complete fragment from after +/// the end of a valid entry, to the start of the next valid entry, with +/// the invalid syntax in the middle. +/// +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// key1 = Value 1 +/// +/// g@Rb@ge = #2y ds +/// +/// key2 = Value 2 +/// +/// "#; +/// +/// let (resource, errors) = parser::parse_runtime(ftl) +/// .expect_err("Resource should contain errors."); +/// +/// assert_eq!( +/// errors, +/// vec![ +/// parser::ParserError { +/// pos: 18..19, +/// slice: Some(17..35), +/// kind: parser::ErrorKind::ExpectedToken('=') +/// } +/// ] +/// ); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key1" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 1" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// +/// assert_eq!( +/// resource.body[1], +/// ast::Entry::Junk { +/// content: "g@Rb@ge = #2y ds\n\n" +/// } +/// ); +/// +/// assert_eq!( +/// resource.body[2], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key2" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 2" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// ``` +/// +/// The information contained in the `ParserError` should allow the tooling +/// to display rich contextual annotations of the error slice, using +/// crates such as `annotate-snippers`. +#[derive(Error, Debug, PartialEq, Clone)] +#[error("{}", self.kind)] +pub struct ParserError { + /// Precise location of where the parser encountered the error. + pub pos: Range, + /// Slice of the input from the end of the last valid entry to the beginning + /// of the next valid entry with the invalid syntax in the middle. + pub slice: Option>, + /// The type of the error that the parser encountered. + pub kind: ErrorKind, +} + +macro_rules! error { + ($kind:expr, $start:expr) => {{ + Err(ParserError { + pos: $start..$start + 1, + slice: None, + kind: $kind, + }) + }}; + ($kind:expr, $start:expr, $end:expr) => {{ + Err(ParserError { + pos: $start..$end, + slice: None, + kind: $kind, + }) + }}; +} + +/// Kind of an error associated with the [`ParserError`]. +#[derive(Error, Debug, PartialEq, Clone)] +pub enum ErrorKind { + #[error("Expected a token starting with \"{0}\"")] + ExpectedToken(char), + #[error("Expected one of \"{range}\"")] + ExpectedCharRange { range: String }, + #[error("Expected a message field for \"{entry_id}\"")] + ExpectedMessageField { entry_id: String }, + #[error("Expected a term field for \"{entry_id}\"")] + ExpectedTermField { entry_id: String }, + #[error("Callee is not allowed here")] + ForbiddenCallee, + #[error("The select expression must have a default variant")] + MissingDefaultVariant, + #[error("Expected a value")] + MissingValue, + #[error("A select expression can only have one default variant")] + MultipleDefaultVariants, + #[error("Message references can't be used as a selector")] + MessageReferenceAsSelector, + #[error("Term references can't be used as a selector")] + TermReferenceAsSelector, + #[error("Message attributes can't be used as a selector")] + MessageAttributeAsSelector, + #[error("Term attributes can't be used as a selector")] + TermAttributeAsPlaceable, + #[error("Unterminated string literal")] + UnterminatedStringLiteral, + #[error("Positional arguments must come before named arguments")] + PositionalArgumentFollowsNamed, + #[error("The \"{0}\" argument appears twice")] + DuplicatedNamedArgument(String), + #[error("Unknown escape sequence")] + UnknownEscapeSequence(String), + #[error("Invalid unicode escape sequence, \"{0}\"")] + InvalidUnicodeEscapeSequence(String), + #[error("Unbalanced closing brace")] + UnbalancedClosingBrace, + #[error("Expected an inline expression")] + ExpectedInlineExpression, + #[error("Expected a simple expression as selector")] + ExpectedSimpleExpressionAsSelector, + #[error("Expected a string or number literal")] + ExpectedLiteral, +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/expression.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/expression.rs new file mode 100644 index 00000000..c5ccb32b --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/expression.rs @@ -0,0 +1,224 @@ +use super::errors::{ErrorKind, ParserError}; +use super::{core::Parser, core::Result, slice::Slice}; +use crate::ast; + +impl<'s, S> Parser +where + S: Slice<'s>, +{ + pub(super) fn get_expression(&mut self) -> Result> { + let exp = self.get_inline_expression(false)?; + + self.skip_blank(); + + if !self.is_current_byte(b'-') || !self.is_byte_at(b'>', self.ptr + 1) { + if let ast::InlineExpression::TermReference { ref attribute, .. } = exp { + if attribute.is_some() { + return error!(ErrorKind::TermAttributeAsPlaceable, self.ptr); + } + } + return Ok(ast::Expression::Inline(exp)); + } + + match exp { + ast::InlineExpression::MessageReference { ref attribute, .. } => { + if attribute.is_none() { + return error!(ErrorKind::MessageReferenceAsSelector, self.ptr); + } else { + return error!(ErrorKind::MessageAttributeAsSelector, self.ptr); + } + } + ast::InlineExpression::TermReference { ref attribute, .. } => { + if attribute.is_none() { + return error!(ErrorKind::TermReferenceAsSelector, self.ptr); + } + } + ast::InlineExpression::StringLiteral { .. } + | ast::InlineExpression::NumberLiteral { .. } + | ast::InlineExpression::VariableReference { .. } + | ast::InlineExpression::FunctionReference { .. } => {} + _ => { + return error!(ErrorKind::ExpectedSimpleExpressionAsSelector, self.ptr); + } + }; + + self.ptr += 2; // -> + + self.skip_blank_inline(); + if !self.skip_eol() { + return error!( + ErrorKind::ExpectedCharRange { + range: "\n | \r\n".to_string() + }, + self.ptr + ); + } + self.skip_blank(); + + let variants = self.get_variants()?; + + Ok(ast::Expression::Select { + selector: exp, + variants, + }) + } + + pub(super) fn get_inline_expression( + &mut self, + only_literal: bool, + ) -> Result> { + match get_current_byte!(self) { + Some(b'"') => { + self.ptr += 1; // " + let start = self.ptr; + while let Some(b) = get_current_byte!(self) { + match b { + b'\\' => match get_byte!(self, self.ptr + 1) { + Some(b'\\') | Some(b'{') | Some(b'"') => self.ptr += 2, + Some(b'u') => { + self.ptr += 2; + self.skip_unicode_escape_sequence(4)?; + } + Some(b'U') => { + self.ptr += 2; + self.skip_unicode_escape_sequence(6)?; + } + b => { + let seq = b.unwrap_or(&b' ').to_string(); + return error!(ErrorKind::UnknownEscapeSequence(seq), self.ptr); + } + }, + b'"' => { + break; + } + b'\n' => { + return error!(ErrorKind::UnterminatedStringLiteral, self.ptr); + } + _ => self.ptr += 1, + } + } + + self.expect_byte(b'"')?; + let slice = self.source.slice(start..self.ptr - 1); + Ok(ast::InlineExpression::StringLiteral { value: slice }) + } + Some(b) if b.is_ascii_digit() => { + let num = self.get_number_literal()?; + Ok(ast::InlineExpression::NumberLiteral { value: num }) + } + Some(b'-') if !only_literal => { + self.ptr += 1; // - + if self.is_identifier_start() { + self.ptr += 1; + let id = self.get_identifier_unchecked(); + let attribute = self.get_attribute_accessor()?; + let arguments = self.get_call_arguments()?; + Ok(ast::InlineExpression::TermReference { + id, + attribute, + arguments, + }) + } else { + self.ptr -= 1; + let num = self.get_number_literal()?; + Ok(ast::InlineExpression::NumberLiteral { value: num }) + } + } + Some(b'$') if !only_literal => { + self.ptr += 1; // $ + let id = self.get_identifier()?; + Ok(ast::InlineExpression::VariableReference { id }) + } + Some(b) if b.is_ascii_alphabetic() => { + self.ptr += 1; + let id = self.get_identifier_unchecked(); + let arguments = self.get_call_arguments()?; + if let Some(arguments) = arguments { + if !Self::is_callee(&id.name) { + return error!(ErrorKind::ForbiddenCallee, self.ptr); + } + + Ok(ast::InlineExpression::FunctionReference { id, arguments }) + } else { + let attribute = self.get_attribute_accessor()?; + Ok(ast::InlineExpression::MessageReference { id, attribute }) + } + } + Some(b'{') if !only_literal => { + self.ptr += 1; // { + let exp = self.get_placeable()?; + Ok(ast::InlineExpression::Placeable { + expression: Box::new(exp), + }) + } + _ if only_literal => error!(ErrorKind::ExpectedLiteral, self.ptr), + _ => error!(ErrorKind::ExpectedInlineExpression, self.ptr), + } + } + + pub fn get_call_arguments(&mut self) -> Result>> { + self.skip_blank(); + if !self.take_byte_if(b'(') { + return Ok(None); + } + + let mut positional = vec![]; + let mut named = vec![]; + let mut argument_names = vec![]; + + self.skip_blank(); + + while self.ptr < self.length { + if self.is_current_byte(b')') { + break; + } + + let expr = self.get_inline_expression(false)?; + + if let ast::InlineExpression::MessageReference { + ref id, + attribute: None, + } = expr + { + self.skip_blank(); + if self.is_current_byte(b':') { + if argument_names.contains(&id.name) { + return error!( + ErrorKind::DuplicatedNamedArgument(id.name.as_ref().to_owned()), + self.ptr + ); + } + self.ptr += 1; + self.skip_blank(); + let val = self.get_inline_expression(true)?; + + argument_names.push(id.name.clone()); + named.push(ast::NamedArgument { + name: ast::Identifier { + name: id.name.clone(), + }, + value: val, + }); + } else { + if !argument_names.is_empty() { + return error!(ErrorKind::PositionalArgumentFollowsNamed, self.ptr); + } + positional.push(expr); + } + } else { + if !argument_names.is_empty() { + return error!(ErrorKind::PositionalArgumentFollowsNamed, self.ptr); + } + positional.push(expr); + } + + self.skip_blank(); + self.take_byte_if(b','); + self.skip_blank(); + } + + self.expect_byte(b')')?; + + Ok(Some(ast::CallArguments { positional, named })) + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/helper.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/helper.rs new file mode 100644 index 00000000..11544d68 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/helper.rs @@ -0,0 +1,169 @@ +use super::errors::{ErrorKind, ParserError}; +use super::{core::Parser, core::Result, slice::Slice}; + +impl<'s, S> Parser +where + S: Slice<'s>, +{ + pub(super) fn is_current_byte(&self, b: u8) -> bool { + get_current_byte!(self) == Some(&b) + } + + pub(super) fn is_byte_at(&self, b: u8, pos: usize) -> bool { + get_byte!(self, pos) == Some(&b) + } + + pub(super) fn skip_to_next_entry_start(&mut self) { + while let Some(b) = get_current_byte!(self) { + let new_line = self.ptr == 0 || get_byte!(self, self.ptr - 1) == Some(&b'\n'); + + if new_line && (b.is_ascii_alphabetic() || [b'-', b'#'].contains(b)) { + break; + } + + self.ptr += 1; + } + } + + pub(super) fn skip_eol(&mut self) -> bool { + match get_current_byte!(self) { + Some(b'\n') => { + self.ptr += 1; + true + } + Some(b'\r') if self.is_byte_at(b'\n', self.ptr + 1) => { + self.ptr += 2; + true + } + _ => false, + } + } + + pub(super) fn skip_unicode_escape_sequence(&mut self, length: usize) -> Result<()> { + let start = self.ptr; + for _ in 0..length { + match get_current_byte!(self) { + Some(b) if b.is_ascii_hexdigit() => self.ptr += 1, + _ => break, + } + } + if self.ptr - start != length { + let end = if self.ptr >= self.length { + self.ptr + } else { + self.ptr + 1 + }; + let seq = self.source.slice(start..end).as_ref().to_owned(); + return error!(ErrorKind::InvalidUnicodeEscapeSequence(seq), self.ptr); + } + Ok(()) + } + + pub(super) fn is_identifier_start(&self) -> bool { + matches!(get_current_byte!(self), Some(b) if b.is_ascii_alphabetic()) + } + + pub(super) fn take_byte_if(&mut self, b: u8) -> bool { + if self.is_current_byte(b) { + self.ptr += 1; + true + } else { + false + } + } + + pub(super) fn skip_blank_block(&mut self) -> usize { + let mut count = 0; + loop { + let start = self.ptr; + self.skip_blank_inline(); + if !self.skip_eol() { + self.ptr = start; + break; + } + count += 1; + } + count + } + + pub(super) fn skip_blank(&mut self) { + loop { + match get_current_byte!(self) { + Some(b' ') | Some(b'\n') => self.ptr += 1, + Some(b'\r') if get_byte!(self, self.ptr + 1) == Some(&b'\n') => self.ptr += 2, + _ => break, + } + } + } + + pub(super) fn skip_blank_inline(&mut self) -> usize { + let start = self.ptr; + while let Some(b' ') = get_current_byte!(self) { + self.ptr += 1; + } + self.ptr - start + } + + pub(super) fn is_byte_pattern_continuation(b: u8) -> bool { + !matches!(b, b'.' | b'}' | b'[' | b'*') + } + + pub(super) fn is_callee(name: &S) -> bool { + name.as_ref() + .as_bytes() + .iter() + .all(|c| c.is_ascii_uppercase() || c.is_ascii_digit() || *c == b'_' || *c == b'-') + } + + pub(super) fn expect_byte(&mut self, b: u8) -> Result<()> { + if !self.is_current_byte(b) { + return error!(ErrorKind::ExpectedToken(b as char), self.ptr); + } + self.ptr += 1; + Ok(()) + } + + pub(super) fn is_number_start(&self) -> bool { + matches!(get_current_byte!(self), Some(b) if b.is_ascii_digit() || b == &b'-') + } + + pub(super) fn is_eol(&self) -> bool { + match get_current_byte!(self) { + Some(b'\n') => true, + Some(b'\r') if self.is_byte_at(b'\n', self.ptr + 1) => true, + None => true, + _ => false, + } + } + + pub(super) fn skip_digits(&mut self) -> Result<()> { + let start = self.ptr; + loop { + match get_current_byte!(self) { + Some(b) if b.is_ascii_digit() => self.ptr += 1, + _ => break, + } + } + if start == self.ptr { + error!( + ErrorKind::ExpectedCharRange { + range: "0-9".to_string() + }, + self.ptr + ) + } else { + Ok(()) + } + } + + pub(super) fn get_number_literal(&mut self) -> Result { + let start = self.ptr; + self.take_byte_if(b'-'); + self.skip_digits()?; + if self.take_byte_if(b'.') { + self.skip_digits()?; + } + + Ok(self.source.slice(start..self.ptr)) + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/macros.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/macros.rs new file mode 100644 index 00000000..671d5432 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/macros.rs @@ -0,0 +1,11 @@ +macro_rules! get_byte { + ($s:expr, $idx:expr) => { + $s.source.as_ref().as_bytes().get($idx) + }; +} + +macro_rules! get_current_byte { + ($s:expr) => { + $s.source.as_ref().as_bytes().get($s.ptr) + }; +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/mod.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/mod.rs new file mode 100644 index 00000000..52edfdc3 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/mod.rs @@ -0,0 +1,278 @@ +//! Fluent Translation List parsing utilities +//! +//! FTL resources can be parsed using one of two methods: +//! * [`parse`] - parses an input into a complete Abstract Syntax Tree representation with all source information preserved. +//! * [`parse_runtime`] - parses an input into a runtime optimized Abstract Syntax Tree +//! representation with comments stripped. +//! +//! # Example +//! +//! ``` +//! use fluent_syntax::parser; +//! use fluent_syntax::ast; +//! +//! let ftl = r#" +//! #### Resource Level Comment +//! +//! ## This is a message comment +//! hello-world = Hello World! +//! +//! "#; +//! +//! let resource = parser::parse(ftl) +//! .expect("Failed to parse an FTL resource."); +//! +//! assert_eq!( +//! resource.body[0], +//! ast::Entry::ResourceComment( +//! ast::Comment { +//! content: vec![ +//! "Resource Level Comment" +//! ] +//! } +//! ) +//! ); +//! assert_eq!( +//! resource.body[1], +//! ast::Entry::Message( +//! ast::Message { +//! id: ast::Identifier { +//! name: "hello-world" +//! }, +//! value: Some(ast::Pattern { +//! elements: vec![ +//! ast::PatternElement::TextElement { +//! value: "Hello World!" +//! }, +//! ] +//! }), +//! attributes: vec![], +//! comment: Some( +//! ast::Comment { +//! content: vec!["This is a message comment"] +//! } +//! ) +//! } +//! ), +//! ); +//! ``` +//! +//! # Error Recovery +//! +//! In both modes the parser is lenient, attempting to recover from errors. +//! +//! The [`Result`] return the resulting AST in both scenarios, and in the +//! error scenario a vector of [`ParserError`] elements is returned as well. +//! +//! Any unparsed parts of the input are returned as [`ast::Entry::Junk`] elements. +#[macro_use] +mod errors; +#[macro_use] +mod macros; +mod comment; +mod core; +mod expression; +mod helper; +mod pattern; +mod runtime; +mod slice; + +use crate::ast; +pub use errors::{ErrorKind, ParserError}; +pub use slice::Slice; + +/// Parser result always returns an AST representation of the input, +/// and if parsing errors were encountered, a list of [`ParserError`] elements +/// is also returned. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// key1 = Value 1 +/// +/// g@Rb@ge = #2y ds +/// +/// key2 = Value 2 +/// +/// "#; +/// +/// let (resource, errors) = parser::parse_runtime(ftl) +/// .expect_err("Resource should contain errors."); +/// +/// assert_eq!( +/// errors, +/// vec![ +/// parser::ParserError { +/// pos: 18..19, +/// slice: Some(17..35), +/// kind: parser::ErrorKind::ExpectedToken('=') +/// } +/// ] +/// ); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key1" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 1" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// +/// assert_eq!( +/// resource.body[1], +/// ast::Entry::Junk { +/// content: "g@Rb@ge = #2y ds\n\n" +/// } +/// ); +/// +/// assert_eq!( +/// resource.body[2], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key2" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 2" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// ``` +pub type Result = std::result::Result, (ast::Resource, Vec)>; + +/// Parses an input into a complete Abstract Syntax Tree representation with +/// all source information preserved. +/// +/// This mode is intended for tooling, linters and other scenarios where +/// complete representation, with comments, is preferred over speed and memory +/// utilization. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// #### Resource Level Comment +/// +/// ## This is a message comment +/// hello-world = Hello World! +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::ResourceComment( +/// ast::Comment { +/// content: vec![ +/// "Resource Level Comment" +/// ] +/// } +/// ) +/// ); +/// assert_eq!( +/// resource.body[1], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello World!" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: Some( +/// ast::Comment { +/// content: vec!["This is a message comment"] +/// } +/// ) +/// } +/// ), +/// ); +/// ``` +pub fn parse<'s, S>(input: S) -> Result +where + S: Slice<'s>, +{ + core::Parser::new(input).parse() +} + +/// Parses an input into an Abstract Syntax Tree representation with comments stripped. +/// +/// This mode is intended for runtime use of Fluent. It currently strips all +/// comments improving parsing performance and reducing the size of the AST tree. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// #### Resource Level Comment +/// +/// ## This is a message comment +/// hello-world = Hello World! +/// +/// "#; +/// +/// let resource = parser::parse_runtime(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello World!" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// ``` +pub fn parse_runtime<'s, S>(input: S) -> Result +where + S: Slice<'s>, +{ + core::Parser::new(input).parse_runtime() +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/pattern.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/pattern.rs new file mode 100644 index 00000000..516326d7 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/pattern.rs @@ -0,0 +1,207 @@ +use super::errors::{ErrorKind, ParserError}; +use super::{core::Parser, core::Result, slice::Slice}; +use crate::ast; + +#[derive(Debug, PartialEq)] +enum TextElementTermination { + LineFeed, + CRLF, + PlaceableStart, + EOF, +} + +// This enum tracks the placement of the text element in the pattern, which is needed for +// dedentation logic. +#[derive(Debug, PartialEq)] +enum TextElementPosition { + InitialLineStart, + LineStart, + Continuation, +} + +// This enum allows us to mark pointers in the source which will later become text elements +// but without slicing them out of the source string. This makes the indentation adjustments +// cheaper since they'll happen on the pointers, rather than extracted slices. +#[derive(Debug)] +enum PatternElementPlaceholders { + Placeable(ast::Expression), + // (start, end, indent, position) + TextElement(usize, usize, usize, TextElementPosition), +} + +// This enum tracks whether the text element is blank or not. +// This is important to identify text elements which should not be taken into account +// when calculating common indent. +#[derive(Debug, PartialEq)] +enum TextElementType { + Blank, + NonBlank, +} + +impl<'s, S> Parser +where + S: Slice<'s>, +{ + pub(super) fn get_pattern(&mut self) -> Result>> { + let mut elements = vec![]; + let mut last_non_blank = None; + let mut common_indent = None; + + self.skip_blank_inline(); + + let mut text_element_role = if self.skip_eol() { + self.skip_blank_block(); + TextElementPosition::LineStart + } else { + TextElementPosition::InitialLineStart + }; + + while self.ptr < self.length { + if self.take_byte_if(b'{') { + if text_element_role == TextElementPosition::LineStart { + common_indent = Some(0); + } + let exp = self.get_placeable()?; + last_non_blank = Some(elements.len()); + elements.push(PatternElementPlaceholders::Placeable(exp)); + text_element_role = TextElementPosition::Continuation; + } else { + let slice_start = self.ptr; + let mut indent = 0; + if text_element_role == TextElementPosition::LineStart { + indent = self.skip_blank_inline(); + if let Some(b) = get_current_byte!(self) { + if indent == 0 { + if b != &b'\r' && b != &b'\n' { + break; + } + } else if !Self::is_byte_pattern_continuation(*b) { + self.ptr = slice_start; + break; + } + } else { + break; + } + } + let (start, end, text_element_type, termination_reason) = self.get_text_slice()?; + if start != end { + if text_element_role == TextElementPosition::LineStart + && text_element_type == TextElementType::NonBlank + { + if let Some(common) = common_indent { + if indent < common { + common_indent = Some(indent); + } + } else { + common_indent = Some(indent); + } + } + if text_element_role != TextElementPosition::LineStart + || text_element_type == TextElementType::NonBlank + || termination_reason == TextElementTermination::LineFeed + { + if text_element_type == TextElementType::NonBlank { + last_non_blank = Some(elements.len()); + } + elements.push(PatternElementPlaceholders::TextElement( + slice_start, + end, + indent, + text_element_role, + )); + } + } + + text_element_role = match termination_reason { + TextElementTermination::LineFeed => TextElementPosition::LineStart, + TextElementTermination::CRLF => TextElementPosition::LineStart, + TextElementTermination::PlaceableStart => TextElementPosition::Continuation, + TextElementTermination::EOF => TextElementPosition::Continuation, + }; + } + } + + if let Some(last_non_blank) = last_non_blank { + let elements = elements + .into_iter() + .take(last_non_blank + 1) + .enumerate() + .map(|(i, elem)| match elem { + PatternElementPlaceholders::Placeable(expression) => { + ast::PatternElement::Placeable { expression } + } + PatternElementPlaceholders::TextElement(start, end, indent, role) => { + let start = if role == TextElementPosition::LineStart { + common_indent.map_or_else( + || start + indent, + |common_indent| start + std::cmp::min(indent, common_indent), + ) + } else { + start + }; + let mut value = self.source.slice(start..end); + if last_non_blank == i { + value.trim(); + } + ast::PatternElement::TextElement { value } + } + }) + .collect(); + return Ok(Some(ast::Pattern { elements })); + } + + Ok(None) + } + + fn get_text_slice( + &mut self, + ) -> Result<(usize, usize, TextElementType, TextElementTermination)> { + let start_pos = self.ptr; + let mut text_element_type = TextElementType::Blank; + + while let Some(b) = get_current_byte!(self) { + match b { + b' ' => self.ptr += 1, + b'\n' => { + self.ptr += 1; + return Ok(( + start_pos, + self.ptr, + text_element_type, + TextElementTermination::LineFeed, + )); + } + b'\r' if self.is_byte_at(b'\n', self.ptr + 1) => { + self.ptr += 1; + return Ok(( + start_pos, + self.ptr - 1, + text_element_type, + TextElementTermination::CRLF, + )); + } + b'{' => { + return Ok(( + start_pos, + self.ptr, + text_element_type, + TextElementTermination::PlaceableStart, + )); + } + b'}' => { + return error!(ErrorKind::UnbalancedClosingBrace, self.ptr); + } + _ => { + text_element_type = TextElementType::NonBlank; + self.ptr += 1 + } + } + } + Ok(( + start_pos, + self.ptr, + text_element_type, + TextElementTermination::EOF, + )) + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/runtime.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/runtime.rs new file mode 100644 index 00000000..e116ceae --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/runtime.rs @@ -0,0 +1,61 @@ +use super::{ + core::{Parser, Result}, + errors::ParserError, + slice::Slice, +}; +use crate::ast; + +impl<'s, S> Parser +where + S: Slice<'s>, +{ + pub fn parse_runtime( + mut self, + ) -> std::result::Result, (ast::Resource, Vec)> { + let mut errors = vec![]; + + // That default allocation gives the lowest + // number of instructions and cycles in ioi. + let mut body = Vec::with_capacity(6); + + self.skip_blank_block(); + + while self.ptr < self.length { + let entry_start = self.ptr; + let entry = self.get_entry_runtime(entry_start); + + match entry { + Ok(Some(entry)) => { + body.push(entry); + } + Ok(None) => {} + Err(mut err) => { + self.skip_to_next_entry_start(); + err.slice = Some(entry_start..self.ptr); + errors.push(err); + let content = self.source.slice(entry_start..self.ptr); + body.push(ast::Entry::Junk { content }); + } + } + self.skip_blank_block(); + } + + if errors.is_empty() { + Ok(ast::Resource { body }) + } else { + Err((ast::Resource { body }, errors)) + } + } + + fn get_entry_runtime(&mut self, entry_start: usize) -> Result>> { + let entry = match get_current_byte!(self) { + Some(b'#') => { + self.skip_comment(); + None + } + Some(b'-') => Some(ast::Entry::Term(self.get_term(entry_start)?)), + _ => Some(ast::Entry::Message(self.get_message(entry_start)?)), + }; + Ok(entry) + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/parser/slice.rs b/utshell-0.5.0/vendor/fluent-syntax/src/parser/slice.rs new file mode 100644 index 00000000..d44f8251 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/parser/slice.rs @@ -0,0 +1,25 @@ +use std::ops::Range; +pub trait Slice<'s>: AsRef + Clone + PartialEq { + fn slice(&self, range: Range) -> Self; + fn trim(&mut self); +} + +impl<'s> Slice<'s> for String { + fn slice(&self, range: Range) -> Self { + self[range].to_string() + } + + fn trim(&mut self) { + *self = self.trim_end().to_string(); + } +} + +impl<'s> Slice<'s> for &'s str { + fn slice(&self, range: Range) -> Self { + &self[range] + } + + fn trim(&mut self) { + *self = self.trim_end(); + } +} diff --git a/utshell-0.5.0/vendor/fluent-syntax/src/unicode.rs b/utshell-0.5.0/vendor/fluent-syntax/src/unicode.rs new file mode 100644 index 00000000..ab95a868 --- /dev/null +++ b/utshell-0.5.0/vendor/fluent-syntax/src/unicode.rs @@ -0,0 +1,159 @@ +//! A set of helper functions for unescaping Fluent unicode escape sequences. +//! +//! # Unicode +//! +//! Fluent supports UTF-8 in all FTL resources, but it also allows +//! unicode sequences to be escaped in [`String +//! Literals`](super::ast::InlineExpression::StringLiteral). +//! +//! Four byte sequences are encoded with `\u` and six byte +//! sqeuences using `\U`. +//! ## Example +//! +//! ``` +//! use fluent_syntax::unicode::unescape_unicode_to_string; +//! +//! assert_eq!( +//! unescape_unicode_to_string("Foo \\u5bd2 Bar"), +//! "Foo 寒 Bar" +//! ); +//! +//! assert_eq!( +//! unescape_unicode_to_string("Foo \\U01F68A Bar"), +//! "Foo 🚊 Bar" +//! ); +//! ``` +//! +//! # Other unescapes +//! +//! This also allows for a char `"` to be present inside an FTL string literal, +//! and for `\` itself to be escaped. +//! +//! ## Example +//! +//! ``` +//! use fluent_syntax::unicode::unescape_unicode_to_string; +//! +//! assert_eq!( +//! unescape_unicode_to_string("Foo \\\" Bar"), +//! "Foo \" Bar" +//! ); +//! assert_eq!( +//! unescape_unicode_to_string("Foo \\\\ Bar"), +//! "Foo \\ Bar" +//! ); +//! ``` +use std::borrow::Cow; +use std::char; +use std::fmt; + +const UNKNOWN_CHAR: char = '�'; + +fn encode_unicode(s: Option<&str>) -> char { + s.and_then(|s| u32::from_str_radix(s, 16).ok().and_then(char::from_u32)) + .unwrap_or(UNKNOWN_CHAR) +} + +/// Unescapes to a writer without allocating. +/// +/// ## Example +/// +/// ``` +/// use fluent_syntax::unicode::unescape_unicode; +/// +/// let mut s = String::new(); +/// unescape_unicode(&mut s, "Foo \\U01F60A Bar"); +/// assert_eq!(s, "Foo 😊 Bar"); +/// ``` +pub fn unescape_unicode(w: &mut W, input: &str) -> fmt::Result +where + W: fmt::Write, +{ + let bytes = input.as_bytes(); + + let mut start = 0; + let mut ptr = 0; + + while let Some(b) = bytes.get(ptr) { + if b != &b'\\' { + ptr += 1; + continue; + } + if start != ptr { + w.write_str(&input[start..ptr])?; + } + + ptr += 1; + + let new_char = match bytes.get(ptr) { + Some(b'\\') => '\\', + Some(b'"') => '"', + Some(u @ b'u') | Some(u @ b'U') => { + let seq_start = ptr + 1; + let len = if u == &b'u' { 4 } else { 6 }; + ptr += len; + encode_unicode(input.get(seq_start..seq_start + len)) + } + _ => UNKNOWN_CHAR, + }; + ptr += 1; + w.write_char(new_char)?; + start = ptr; + } + if start != ptr { + w.write_str(&input[start..ptr])?; + } + Ok(()) +} + +/// Unescapes to a `Cow` optionally allocating. +/// +/// ## Example +/// +/// ``` +/// use fluent_syntax::unicode::unescape_unicode_to_string; +/// +/// assert_eq!( +/// unescape_unicode_to_string("Foo \\U01F60A Bar"), +/// "Foo 😊 Bar" +/// ); +/// ``` +pub fn unescape_unicode_to_string(input: &str) -> Cow { + let bytes = input.as_bytes(); + let mut result = Cow::from(input); + + let mut ptr = 0; + + while let Some(b) = bytes.get(ptr) { + if b != &b'\\' { + if let Cow::Owned(ref mut s) = result { + s.push(*b as char); + } + ptr += 1; + continue; + } + + if let Cow::Borrowed(_) = result { + result = Cow::from(&input[0..ptr]); + } + + ptr += 1; + + let new_char = match bytes.get(ptr) { + Some(b'\\') => '\\', + Some(b'"') => '"', + Some(u @ b'u') | Some(u @ b'U') => { + let start = ptr + 1; + let len = if u == &b'u' { 4 } else { 6 }; + ptr += len; + input + .get(start..(start + len)) + .map_or(UNKNOWN_CHAR, |slice| encode_unicode(Some(slice))) + } + _ => UNKNOWN_CHAR, + }; + result.to_mut().push(new_char); + ptr += 1; + } + result +} diff --git a/utshell-0.5.0/vendor/futures-channel/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-channel/.cargo-checksum.json new file mode 100644 index 00000000..831098ef --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"042bcef7e6361cc21e948695a1ac1afabb447a8336cb135567fe8355ff2b468d","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"faccd17503a06e7df67feb53da22dba6a8ea80ee88736ed37fae038d0d0906dd","benches/sync_mpsc.rs":"1019dd027f104f58883f396ff70efc3dd69b3a7d62df17af090e07b2b05eaf66","src/lib.rs":"322f624b2cbad1ed7e2845811035c2a91b0fa6ed98a456f57b5d3d481fb7fbd9","src/lock.rs":"38655a797456ea4f67d132c42055cf74f18195e875c3b337fc81a12901f79292","src/mpsc/mod.rs":"ecb48325aad15406ed79bf7271440bfbab5af19d5e7c7d8018e8b19613ae1558","src/mpsc/queue.rs":"0856f8b744c537c291d60cc7879ddb2d8cd686a6ac0e4a79c6877f8c3f8f6dbc","src/mpsc/sink_impl.rs":"c9977b530187e82c912fcd46e08316e48ed246e77bb2419d53020e69e403d086","src/oneshot.rs":"1e4e33c75d72b5d11cc23710e2a08099e04b72bf2368b68e7c1eb0beb6fc03fa","tests/channel.rs":"88f4a41d82b5c1b01e153d071a2bf48e0697355908c55ca42342ed45e63fdec8","tests/mpsc-close.rs":"cb3a427403051a731701de5d2a489f8a7b7a5eaceb5edfafef4a539e63588d3c","tests/mpsc-size_hint.rs":"50fba3495bdf4e91a84ad105b148b6cd72f73f64a85703414eeb2d07732c66b9","tests/mpsc.rs":"5e09a49bea7b7ee30c9845bc5e80565d720c6e2355bcac4a0c745b3c7e6cc212","tests/oneshot.rs":"0f97d28852a1fd1327211772f43322c93916a639be3f2581e49ad37c9f8a2f88"},"package":"eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-channel/Cargo.toml b/utshell-0.5.0/vendor/futures-channel/Cargo.toml new file mode 100644 index 00000000..8142bdae --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/Cargo.toml @@ -0,0 +1,52 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "futures-channel" +version = "0.3.30" +description = """ +Channels for asynchronous communication using futures-rs. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[dependencies.futures-core] +version = "0.3.30" +default-features = false + +[dependencies.futures-sink] +version = "0.3.30" +optional = true +default-features = false + +[dev-dependencies] + +[features] +alloc = ["futures-core/alloc"] +cfg-target-has-atomic = [] +default = ["std"] +sink = ["futures-sink"] +std = [ + "alloc", + "futures-core/std", +] +unstable = [] diff --git a/utshell-0.5.0/vendor/futures-channel/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-channel/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-channel/LICENSE-MIT b/utshell-0.5.0/vendor/futures-channel/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-channel/README.md b/utshell-0.5.0/vendor/futures-channel/README.md new file mode 100644 index 00000000..e886bd1c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/README.md @@ -0,0 +1,23 @@ +# futures-channel + +Channels for asynchronous communication using futures-rs. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-channel = "0.3" +``` + +The current `futures-channel` requires Rust 1.56 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-channel/benches/sync_mpsc.rs b/utshell-0.5.0/vendor/futures-channel/benches/sync_mpsc.rs new file mode 100644 index 00000000..7c3c3d3a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/benches/sync_mpsc.rs @@ -0,0 +1,135 @@ +#![feature(test)] + +extern crate test; +use crate::test::Bencher; + +use { + futures::{ + channel::mpsc::{self, Sender, UnboundedSender}, + ready, + sink::Sink, + stream::{Stream, StreamExt}, + task::{Context, Poll}, + }, + futures_test::task::noop_context, + std::pin::Pin, +}; + +/// Single producer, single consumer +#[bench] +fn unbounded_1_tx(b: &mut Bencher) { + let mut cx = noop_context(); + b.iter(|| { + let (tx, mut rx) = mpsc::unbounded(); + + // 1000 iterations to avoid measuring overhead of initialization + // Result should be divided by 1000 + for i in 0..1000 { + // Poll, not ready, park + assert_eq!(Poll::Pending, rx.poll_next_unpin(&mut cx)); + + UnboundedSender::unbounded_send(&tx, i).unwrap(); + + // Now poll ready + assert_eq!(Poll::Ready(Some(i)), rx.poll_next_unpin(&mut cx)); + } + }) +} + +/// 100 producers, single consumer +#[bench] +fn unbounded_100_tx(b: &mut Bencher) { + let mut cx = noop_context(); + b.iter(|| { + let (tx, mut rx) = mpsc::unbounded(); + + let tx: Vec<_> = (0..100).map(|_| tx.clone()).collect(); + + // 1000 send/recv operations total, result should be divided by 1000 + for _ in 0..10 { + for (i, x) in tx.iter().enumerate() { + assert_eq!(Poll::Pending, rx.poll_next_unpin(&mut cx)); + + UnboundedSender::unbounded_send(x, i).unwrap(); + + assert_eq!(Poll::Ready(Some(i)), rx.poll_next_unpin(&mut cx)); + } + } + }) +} + +#[bench] +fn unbounded_uncontended(b: &mut Bencher) { + let mut cx = noop_context(); + b.iter(|| { + let (tx, mut rx) = mpsc::unbounded(); + + for i in 0..1000 { + UnboundedSender::unbounded_send(&tx, i).expect("send"); + // No need to create a task, because poll is not going to park. + assert_eq!(Poll::Ready(Some(i)), rx.poll_next_unpin(&mut cx)); + } + }) +} + +/// A Stream that continuously sends incrementing number of the queue +struct TestSender { + tx: Sender, + last: u32, // Last number sent +} + +// Could be a Future, it doesn't matter +impl Stream for TestSender { + type Item = u32; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = &mut *self; + let mut tx = Pin::new(&mut this.tx); + + ready!(tx.as_mut().poll_ready(cx)).unwrap(); + tx.as_mut().start_send(this.last + 1).unwrap(); + this.last += 1; + assert_eq!(Poll::Pending, tx.as_mut().poll_flush(cx)); + Poll::Ready(Some(this.last)) + } +} + +/// Single producers, single consumer +#[bench] +fn bounded_1_tx(b: &mut Bencher) { + let mut cx = noop_context(); + b.iter(|| { + let (tx, mut rx) = mpsc::channel(0); + + let mut tx = TestSender { tx, last: 0 }; + + for i in 0..1000 { + assert_eq!(Poll::Ready(Some(i + 1)), tx.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Pending, tx.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(i + 1)), rx.poll_next_unpin(&mut cx)); + } + }) +} + +/// 100 producers, single consumer +#[bench] +fn bounded_100_tx(b: &mut Bencher) { + let mut cx = noop_context(); + b.iter(|| { + // Each sender can send one item after specified capacity + let (tx, mut rx) = mpsc::channel(0); + + let mut tx: Vec<_> = (0..100).map(|_| TestSender { tx: tx.clone(), last: 0 }).collect(); + + for i in 0..10 { + for x in &mut tx { + // Send an item + assert_eq!(Poll::Ready(Some(i + 1)), x.poll_next_unpin(&mut cx)); + // Then block + assert_eq!(Poll::Pending, x.poll_next_unpin(&mut cx)); + // Recv the item + assert_eq!(Poll::Ready(Some(i + 1)), rx.poll_next_unpin(&mut cx)); + } + } + }) +} diff --git a/utshell-0.5.0/vendor/futures-channel/src/lib.rs b/utshell-0.5.0/vendor/futures-channel/src/lib.rs new file mode 100644 index 00000000..f611e6b9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/src/lib.rs @@ -0,0 +1,42 @@ +//! Asynchronous channels. +//! +//! Like threads, concurrent tasks sometimes need to communicate with each +//! other. This module contains two basic abstractions for doing so: +//! +//! - [oneshot], a way of sending a single value from one task to another. +//! - [mpsc], a multi-producer, single-consumer channel for sending values +//! between tasks, analogous to the similarly-named structure in the standard +//! library. +//! +//! All items are only available when the `std` or `alloc` feature of this +//! library is activated, and it is activated by default. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + single_use_lifetimes, + unreachable_pub +)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod lock; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "std")] +pub mod mpsc; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub mod oneshot; diff --git a/utshell-0.5.0/vendor/futures-channel/src/lock.rs b/utshell-0.5.0/vendor/futures-channel/src/lock.rs new file mode 100644 index 00000000..b328d0f7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/src/lock.rs @@ -0,0 +1,102 @@ +//! A "mutex" which only supports `try_lock` +//! +//! As a futures library the eventual call to an event loop should be the only +//! thing that ever blocks, so this is assisted with a fast user-space +//! implementation of a lock that can only have a `try_lock` operation. + +use core::cell::UnsafeCell; +use core::ops::{Deref, DerefMut}; +use core::sync::atomic::AtomicBool; +use core::sync::atomic::Ordering::SeqCst; + +/// A "mutex" around a value, similar to `std::sync::Mutex`. +/// +/// This lock only supports the `try_lock` operation, however, and does not +/// implement poisoning. +#[derive(Debug)] +pub(crate) struct Lock { + locked: AtomicBool, + data: UnsafeCell, +} + +/// Sentinel representing an acquired lock through which the data can be +/// accessed. +pub(crate) struct TryLock<'a, T> { + __ptr: &'a Lock, +} + +// The `Lock` structure is basically just a `Mutex`, and these two impls are +// intended to mirror the standard library's corresponding impls for `Mutex`. +// +// If a `T` is sendable across threads, so is the lock, and `T` must be sendable +// across threads to be `Sync` because it allows mutable access from multiple +// threads. +unsafe impl Send for Lock {} +unsafe impl Sync for Lock {} + +impl Lock { + /// Creates a new lock around the given value. + pub(crate) fn new(t: T) -> Self { + Self { locked: AtomicBool::new(false), data: UnsafeCell::new(t) } + } + + /// Attempts to acquire this lock, returning whether the lock was acquired or + /// not. + /// + /// If `Some` is returned then the data this lock protects can be accessed + /// through the sentinel. This sentinel allows both mutable and immutable + /// access. + /// + /// If `None` is returned then the lock is already locked, either elsewhere + /// on this thread or on another thread. + pub(crate) fn try_lock(&self) -> Option> { + if !self.locked.swap(true, SeqCst) { + Some(TryLock { __ptr: self }) + } else { + None + } + } +} + +impl Deref for TryLock<'_, T> { + type Target = T; + fn deref(&self) -> &T { + // The existence of `TryLock` represents that we own the lock, so we + // can safely access the data here. + unsafe { &*self.__ptr.data.get() } + } +} + +impl DerefMut for TryLock<'_, T> { + fn deref_mut(&mut self) -> &mut T { + // The existence of `TryLock` represents that we own the lock, so we + // can safely access the data here. + // + // Additionally, we're the *only* `TryLock` in existence so mutable + // access should be ok. + unsafe { &mut *self.__ptr.data.get() } + } +} + +impl Drop for TryLock<'_, T> { + fn drop(&mut self) { + self.__ptr.locked.store(false, SeqCst); + } +} + +#[cfg(test)] +mod tests { + use super::Lock; + + #[test] + fn smoke() { + let a = Lock::new(1); + let mut a1 = a.try_lock().unwrap(); + assert!(a.try_lock().is_none()); + assert_eq!(*a1, 1); + *a1 = 2; + drop(a1); + assert_eq!(*a.try_lock().unwrap(), 2); + assert_eq!(*a.try_lock().unwrap(), 2); + } +} diff --git a/utshell-0.5.0/vendor/futures-channel/src/mpsc/mod.rs b/utshell-0.5.0/vendor/futures-channel/src/mpsc/mod.rs new file mode 100644 index 00000000..64f7526f --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/src/mpsc/mod.rs @@ -0,0 +1,1372 @@ +//! A multi-producer, single-consumer queue for sending values across +//! asynchronous tasks. +//! +//! Similarly to the `std`, channel creation provides [`Receiver`] and +//! [`Sender`] handles. [`Receiver`] implements [`Stream`] and allows a task to +//! read values out of the channel. If there is no message to read from the +//! channel, the current task will be notified when a new value is sent. +//! [`Sender`] implements the `Sink` trait and allows a task to send messages into +//! the channel. If the channel is at capacity, the send will be rejected and +//! the task will be notified when additional capacity is available. In other +//! words, the channel provides backpressure. +//! +//! Unbounded channels are also available using the `unbounded` constructor. +//! +//! # Disconnection +//! +//! When all [`Sender`] handles have been dropped, it is no longer +//! possible to send values into the channel. This is considered the termination +//! event of the stream. As such, [`Receiver::poll_next`] +//! will return `Ok(Ready(None))`. +//! +//! If the [`Receiver`] handle is dropped, then messages can no longer +//! be read out of the channel. In this case, all further attempts to send will +//! result in an error. +//! +//! # Clean Shutdown +//! +//! If the [`Receiver`] is simply dropped, then it is possible for +//! there to be messages still in the channel that will not be processed. As +//! such, it is usually desirable to perform a "clean" shutdown. To do this, the +//! receiver will first call `close`, which will prevent any further messages to +//! be sent into the channel. Then, the receiver consumes the channel to +//! completion, at which point the receiver can be dropped. +//! +//! [`Sender`]: struct.Sender.html +//! [`Receiver`]: struct.Receiver.html +//! [`Stream`]: ../../futures_core/stream/trait.Stream.html +//! [`Receiver::poll_next`]: +//! ../../futures_core/stream/trait.Stream.html#tymethod.poll_next + +// At the core, the channel uses an atomic FIFO queue for message passing. This +// queue is used as the primary coordination primitive. In order to enforce +// capacity limits and handle back pressure, a secondary FIFO queue is used to +// send parked task handles. +// +// The general idea is that the channel is created with a `buffer` size of `n`. +// The channel capacity is `n + num-senders`. Each sender gets one "guaranteed" +// slot to hold a message. This allows `Sender` to know for a fact that a send +// will succeed *before* starting to do the actual work of sending the value. +// Since most of this work is lock-free, once the work starts, it is impossible +// to safely revert. +// +// If the sender is unable to process a send operation, then the current +// task is parked and the handle is sent on the parked task queue. +// +// Note that the implementation guarantees that the channel capacity will never +// exceed the configured limit, however there is no *strict* guarantee that the +// receiver will wake up a parked task *immediately* when a slot becomes +// available. However, it will almost always unpark a task when a slot becomes +// available and it is *guaranteed* that a sender will be unparked when the +// message that caused the sender to become parked is read out of the channel. +// +// The steps for sending a message are roughly: +// +// 1) Increment the channel message count +// 2) If the channel is at capacity, push the task handle onto the wait queue +// 3) Push the message onto the message queue. +// +// The steps for receiving a message are roughly: +// +// 1) Pop a message from the message queue +// 2) Pop a task handle from the wait queue +// 3) Decrement the channel message count. +// +// It's important for the order of operations on lock-free structures to happen +// in reverse order between the sender and receiver. This makes the message +// queue the primary coordination structure and establishes the necessary +// happens-before semantics required for the acquire / release semantics used +// by the queue structure. + +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::__internal::AtomicWaker; +use futures_core::task::{Context, Poll, Waker}; +use std::fmt; +use std::pin::Pin; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::SeqCst; +use std::sync::{Arc, Mutex}; +use std::thread; + +use crate::mpsc::queue::Queue; + +mod queue; +#[cfg(feature = "sink")] +mod sink_impl; + +struct UnboundedSenderInner { + // Channel state shared between the sender and receiver. + inner: Arc>, +} + +struct BoundedSenderInner { + // Channel state shared between the sender and receiver. + inner: Arc>, + + // Handle to the task that is blocked on this sender. This handle is sent + // to the receiver half in order to be notified when the sender becomes + // unblocked. + sender_task: Arc>, + + // `true` if the sender might be blocked. This is an optimization to avoid + // having to lock the mutex most of the time. + maybe_parked: bool, +} + +// We never project Pin<&mut SenderInner> to `Pin<&mut T>` +impl Unpin for UnboundedSenderInner {} +impl Unpin for BoundedSenderInner {} + +/// The transmission end of a bounded mpsc channel. +/// +/// This value is created by the [`channel`] function. +pub struct Sender(Option>); + +/// The transmission end of an unbounded mpsc channel. +/// +/// This value is created by the [`unbounded`] function. +pub struct UnboundedSender(Option>); + +trait AssertKinds: Send + Sync + Clone {} +impl AssertKinds for UnboundedSender {} + +/// The receiving end of a bounded mpsc channel. +/// +/// This value is created by the [`channel`] function. +pub struct Receiver { + inner: Option>>, +} + +/// The receiving end of an unbounded mpsc channel. +/// +/// This value is created by the [`unbounded`] function. +pub struct UnboundedReceiver { + inner: Option>>, +} + +// `Pin<&mut UnboundedReceiver>` is never projected to `Pin<&mut T>` +impl Unpin for UnboundedReceiver {} + +/// The error type for [`Sender`s](Sender) used as `Sink`s. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SendError { + kind: SendErrorKind, +} + +/// The error type returned from [`try_send`](Sender::try_send). +#[derive(Clone, PartialEq, Eq)] +pub struct TrySendError { + err: SendError, + val: T, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +enum SendErrorKind { + Full, + Disconnected, +} + +/// The error type returned from [`try_next`](Receiver::try_next). +pub struct TryRecvError { + _priv: (), +} + +impl fmt::Display for SendError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_full() { + write!(f, "send failed because channel is full") + } else { + write!(f, "send failed because receiver is gone") + } + } +} + +impl std::error::Error for SendError {} + +impl SendError { + /// Returns `true` if this error is a result of the channel being full. + pub fn is_full(&self) -> bool { + match self.kind { + SendErrorKind::Full => true, + _ => false, + } + } + + /// Returns `true` if this error is a result of the receiver being dropped. + pub fn is_disconnected(&self) -> bool { + match self.kind { + SendErrorKind::Disconnected => true, + _ => false, + } + } +} + +impl fmt::Debug for TrySendError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TrySendError").field("kind", &self.err.kind).finish() + } +} + +impl fmt::Display for TrySendError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_full() { + write!(f, "send failed because channel is full") + } else { + write!(f, "send failed because receiver is gone") + } + } +} + +impl std::error::Error for TrySendError {} + +impl TrySendError { + /// Returns `true` if this error is a result of the channel being full. + pub fn is_full(&self) -> bool { + self.err.is_full() + } + + /// Returns `true` if this error is a result of the receiver being dropped. + pub fn is_disconnected(&self) -> bool { + self.err.is_disconnected() + } + + /// Returns the message that was attempted to be sent but failed. + pub fn into_inner(self) -> T { + self.val + } + + /// Drops the message and converts into a `SendError`. + pub fn into_send_error(self) -> SendError { + self.err + } +} + +impl fmt::Debug for TryRecvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("TryRecvError").finish() + } +} + +impl fmt::Display for TryRecvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "receiver channel is empty") + } +} + +impl std::error::Error for TryRecvError {} + +struct UnboundedInner { + // Internal channel state. Consists of the number of messages stored in the + // channel as well as a flag signalling that the channel is closed. + state: AtomicUsize, + + // Atomic, FIFO queue used to send messages to the receiver + message_queue: Queue, + + // Number of senders in existence + num_senders: AtomicUsize, + + // Handle to the receiver's task. + recv_task: AtomicWaker, +} + +struct BoundedInner { + // Max buffer size of the channel. If `None` then the channel is unbounded. + buffer: usize, + + // Internal channel state. Consists of the number of messages stored in the + // channel as well as a flag signalling that the channel is closed. + state: AtomicUsize, + + // Atomic, FIFO queue used to send messages to the receiver + message_queue: Queue, + + // Atomic, FIFO queue used to send parked task handles to the receiver. + parked_queue: Queue>>, + + // Number of senders in existence + num_senders: AtomicUsize, + + // Handle to the receiver's task. + recv_task: AtomicWaker, +} + +// Struct representation of `Inner::state`. +#[derive(Clone, Copy)] +struct State { + // `true` when the channel is open + is_open: bool, + + // Number of messages in the channel + num_messages: usize, +} + +// The `is_open` flag is stored in the left-most bit of `Inner::state` +const OPEN_MASK: usize = usize::max_value() - (usize::max_value() >> 1); + +// When a new channel is created, it is created in the open state with no +// pending messages. +const INIT_STATE: usize = OPEN_MASK; + +// The maximum number of messages that a channel can track is `usize::max_value() >> 1` +const MAX_CAPACITY: usize = !(OPEN_MASK); + +// The maximum requested buffer size must be less than the maximum capacity of +// a channel. This is because each sender gets a guaranteed slot. +const MAX_BUFFER: usize = MAX_CAPACITY >> 1; + +// Sent to the consumer to wake up blocked producers +struct SenderTask { + task: Option, + is_parked: bool, +} + +impl SenderTask { + fn new() -> Self { + Self { task: None, is_parked: false } + } + + fn notify(&mut self) { + self.is_parked = false; + + if let Some(task) = self.task.take() { + task.wake(); + } + } +} + +/// Creates a bounded mpsc channel for communicating between asynchronous tasks. +/// +/// Being bounded, this channel provides backpressure to ensure that the sender +/// outpaces the receiver by only a limited amount. The channel's capacity is +/// equal to `buffer + num-senders`. In other words, each sender gets a +/// guaranteed slot in the channel capacity, and on top of that there are +/// `buffer` "first come, first serve" slots available to all senders. +/// +/// The [`Receiver`] returned implements the [`Stream`] trait, while [`Sender`] +/// implements `Sink`. +pub fn channel(buffer: usize) -> (Sender, Receiver) { + // Check that the requested buffer size does not exceed the maximum buffer + // size permitted by the system. + assert!(buffer < MAX_BUFFER, "requested buffer size too large"); + + let inner = Arc::new(BoundedInner { + buffer, + state: AtomicUsize::new(INIT_STATE), + message_queue: Queue::new(), + parked_queue: Queue::new(), + num_senders: AtomicUsize::new(1), + recv_task: AtomicWaker::new(), + }); + + let tx = BoundedSenderInner { + inner: inner.clone(), + sender_task: Arc::new(Mutex::new(SenderTask::new())), + maybe_parked: false, + }; + + let rx = Receiver { inner: Some(inner) }; + + (Sender(Some(tx)), rx) +} + +/// Creates an unbounded mpsc channel for communicating between asynchronous +/// tasks. +/// +/// A `send` on this channel will always succeed as long as the receive half has +/// not been closed. If the receiver falls behind, messages will be arbitrarily +/// buffered. +/// +/// **Note** that the amount of available system memory is an implicit bound to +/// the channel. Using an `unbounded` channel has the ability of causing the +/// process to run out of memory. In this case, the process will be aborted. +pub fn unbounded() -> (UnboundedSender, UnboundedReceiver) { + let inner = Arc::new(UnboundedInner { + state: AtomicUsize::new(INIT_STATE), + message_queue: Queue::new(), + num_senders: AtomicUsize::new(1), + recv_task: AtomicWaker::new(), + }); + + let tx = UnboundedSenderInner { inner: inner.clone() }; + + let rx = UnboundedReceiver { inner: Some(inner) }; + + (UnboundedSender(Some(tx)), rx) +} + +/* + * + * ===== impl Sender ===== + * + */ + +impl UnboundedSenderInner { + fn poll_ready_nb(&self) -> Poll> { + let state = decode_state(self.inner.state.load(SeqCst)); + if state.is_open { + Poll::Ready(Ok(())) + } else { + Poll::Ready(Err(SendError { kind: SendErrorKind::Disconnected })) + } + } + + // Push message to the queue and signal to the receiver + fn queue_push_and_signal(&self, msg: T) { + // Push the message onto the message queue + self.inner.message_queue.push(msg); + + // Signal to the receiver that a message has been enqueued. If the + // receiver is parked, this will unpark the task. + self.inner.recv_task.wake(); + } + + // Increment the number of queued messages. Returns the resulting number. + fn inc_num_messages(&self) -> Option { + let mut curr = self.inner.state.load(SeqCst); + + loop { + let mut state = decode_state(curr); + + // The receiver end closed the channel. + if !state.is_open { + return None; + } + + // This probably is never hit? Odds are the process will run out of + // memory first. It may be worth to return something else in this + // case? + assert!( + state.num_messages < MAX_CAPACITY, + "buffer space \ + exhausted; sending this messages would overflow the state" + ); + + state.num_messages += 1; + + let next = encode_state(&state); + match self.inner.state.compare_exchange(curr, next, SeqCst, SeqCst) { + Ok(_) => return Some(state.num_messages), + Err(actual) => curr = actual, + } + } + } + + /// Returns whether the senders send to the same receiver. + fn same_receiver(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.inner, &other.inner) + } + + /// Returns whether the sender send to this receiver. + fn is_connected_to(&self, inner: &Arc>) -> bool { + Arc::ptr_eq(&self.inner, inner) + } + + /// Returns pointer to the Arc containing sender + /// + /// The returned pointer is not referenced and should be only used for hashing! + fn ptr(&self) -> *const UnboundedInner { + &*self.inner + } + + /// Returns whether this channel is closed without needing a context. + fn is_closed(&self) -> bool { + !decode_state(self.inner.state.load(SeqCst)).is_open + } + + /// Closes this channel from the sender side, preventing any new messages. + fn close_channel(&self) { + // There's no need to park this sender, its dropping, + // and we don't want to check for capacity, so skip + // that stuff from `do_send`. + + self.inner.set_closed(); + self.inner.recv_task.wake(); + } +} + +impl BoundedSenderInner { + /// Attempts to send a message on this `Sender`, returning the message + /// if there was an error. + fn try_send(&mut self, msg: T) -> Result<(), TrySendError> { + // If the sender is currently blocked, reject the message + if !self.poll_unparked(None).is_ready() { + return Err(TrySendError { err: SendError { kind: SendErrorKind::Full }, val: msg }); + } + + // The channel has capacity to accept the message, so send it + self.do_send_b(msg) + } + + // Do the send without failing. + // Can be called only by bounded sender. + fn do_send_b(&mut self, msg: T) -> Result<(), TrySendError> { + // Anyone calling do_send *should* make sure there is room first, + // but assert here for tests as a sanity check. + debug_assert!(self.poll_unparked(None).is_ready()); + + // First, increment the number of messages contained by the channel. + // This operation will also atomically determine if the sender task + // should be parked. + // + // `None` is returned in the case that the channel has been closed by the + // receiver. This happens when `Receiver::close` is called or the + // receiver is dropped. + let park_self = match self.inc_num_messages() { + Some(num_messages) => { + // Block if the current number of pending messages has exceeded + // the configured buffer size + num_messages > self.inner.buffer + } + None => { + return Err(TrySendError { + err: SendError { kind: SendErrorKind::Disconnected }, + val: msg, + }) + } + }; + + // If the channel has reached capacity, then the sender task needs to + // be parked. This will send the task handle on the parked task queue. + // + // However, when `do_send` is called while dropping the `Sender`, + // `task::current()` can't be called safely. In this case, in order to + // maintain internal consistency, a blank message is pushed onto the + // parked task queue. + if park_self { + self.park(); + } + + self.queue_push_and_signal(msg); + + Ok(()) + } + + // Push message to the queue and signal to the receiver + fn queue_push_and_signal(&self, msg: T) { + // Push the message onto the message queue + self.inner.message_queue.push(msg); + + // Signal to the receiver that a message has been enqueued. If the + // receiver is parked, this will unpark the task. + self.inner.recv_task.wake(); + } + + // Increment the number of queued messages. Returns the resulting number. + fn inc_num_messages(&self) -> Option { + let mut curr = self.inner.state.load(SeqCst); + + loop { + let mut state = decode_state(curr); + + // The receiver end closed the channel. + if !state.is_open { + return None; + } + + // This probably is never hit? Odds are the process will run out of + // memory first. It may be worth to return something else in this + // case? + assert!( + state.num_messages < MAX_CAPACITY, + "buffer space \ + exhausted; sending this messages would overflow the state" + ); + + state.num_messages += 1; + + let next = encode_state(&state); + match self.inner.state.compare_exchange(curr, next, SeqCst, SeqCst) { + Ok(_) => return Some(state.num_messages), + Err(actual) => curr = actual, + } + } + } + + fn park(&mut self) { + { + let mut sender = self.sender_task.lock().unwrap(); + sender.task = None; + sender.is_parked = true; + } + + // Send handle over queue + let t = self.sender_task.clone(); + self.inner.parked_queue.push(t); + + // Check to make sure we weren't closed after we sent our task on the + // queue + let state = decode_state(self.inner.state.load(SeqCst)); + self.maybe_parked = state.is_open; + } + + /// Polls the channel to determine if there is guaranteed capacity to send + /// at least one item without waiting. + /// + /// # Return value + /// + /// This method returns: + /// + /// - `Poll::Ready(Ok(_))` if there is sufficient capacity; + /// - `Poll::Pending` if the channel may not have + /// capacity, in which case the current task is queued to be notified once + /// capacity is available; + /// - `Poll::Ready(Err(SendError))` if the receiver has been dropped. + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + let state = decode_state(self.inner.state.load(SeqCst)); + if !state.is_open { + return Poll::Ready(Err(SendError { kind: SendErrorKind::Disconnected })); + } + + self.poll_unparked(Some(cx)).map(Ok) + } + + /// Returns whether the senders send to the same receiver. + fn same_receiver(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.inner, &other.inner) + } + + /// Returns whether the sender send to this receiver. + fn is_connected_to(&self, receiver: &Arc>) -> bool { + Arc::ptr_eq(&self.inner, receiver) + } + + /// Returns pointer to the Arc containing sender + /// + /// The returned pointer is not referenced and should be only used for hashing! + fn ptr(&self) -> *const BoundedInner { + &*self.inner + } + + /// Returns whether this channel is closed without needing a context. + fn is_closed(&self) -> bool { + !decode_state(self.inner.state.load(SeqCst)).is_open + } + + /// Closes this channel from the sender side, preventing any new messages. + fn close_channel(&self) { + // There's no need to park this sender, its dropping, + // and we don't want to check for capacity, so skip + // that stuff from `do_send`. + + self.inner.set_closed(); + self.inner.recv_task.wake(); + } + + fn poll_unparked(&mut self, cx: Option<&mut Context<'_>>) -> Poll<()> { + // First check the `maybe_parked` variable. This avoids acquiring the + // lock in most cases + if self.maybe_parked { + // Get a lock on the task handle + let mut task = self.sender_task.lock().unwrap(); + + if !task.is_parked { + self.maybe_parked = false; + return Poll::Ready(()); + } + + // At this point, an unpark request is pending, so there will be an + // unpark sometime in the future. We just need to make sure that + // the correct task will be notified. + // + // Update the task in case the `Sender` has been moved to another + // task + task.task = cx.map(|cx| cx.waker().clone()); + + Poll::Pending + } else { + Poll::Ready(()) + } + } +} + +impl Sender { + /// Attempts to send a message on this `Sender`, returning the message + /// if there was an error. + pub fn try_send(&mut self, msg: T) -> Result<(), TrySendError> { + if let Some(inner) = &mut self.0 { + inner.try_send(msg) + } else { + Err(TrySendError { err: SendError { kind: SendErrorKind::Disconnected }, val: msg }) + } + } + + /// Send a message on the channel. + /// + /// This function should only be called after + /// [`poll_ready`](Sender::poll_ready) has reported that the channel is + /// ready to receive a message. + pub fn start_send(&mut self, msg: T) -> Result<(), SendError> { + self.try_send(msg).map_err(|e| e.err) + } + + /// Polls the channel to determine if there is guaranteed capacity to send + /// at least one item without waiting. + /// + /// # Return value + /// + /// This method returns: + /// + /// - `Poll::Ready(Ok(_))` if there is sufficient capacity; + /// - `Poll::Pending` if the channel may not have + /// capacity, in which case the current task is queued to be notified once + /// capacity is available; + /// - `Poll::Ready(Err(SendError))` if the receiver has been dropped. + pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + let inner = self.0.as_mut().ok_or(SendError { kind: SendErrorKind::Disconnected })?; + inner.poll_ready(cx) + } + + /// Returns whether this channel is closed without needing a context. + pub fn is_closed(&self) -> bool { + self.0.as_ref().map(BoundedSenderInner::is_closed).unwrap_or(true) + } + + /// Closes this channel from the sender side, preventing any new messages. + pub fn close_channel(&mut self) { + if let Some(inner) = &mut self.0 { + inner.close_channel(); + } + } + + /// Disconnects this sender from the channel, closing it if there are no more senders left. + pub fn disconnect(&mut self) { + self.0 = None; + } + + /// Returns whether the senders send to the same receiver. + pub fn same_receiver(&self, other: &Self) -> bool { + match (&self.0, &other.0) { + (Some(inner), Some(other)) => inner.same_receiver(other), + _ => false, + } + } + + /// Returns whether the sender send to this receiver. + pub fn is_connected_to(&self, receiver: &Receiver) -> bool { + match (&self.0, &receiver.inner) { + (Some(inner), Some(receiver)) => inner.is_connected_to(receiver), + _ => false, + } + } + + /// Hashes the receiver into the provided hasher + pub fn hash_receiver(&self, hasher: &mut H) + where + H: std::hash::Hasher, + { + use std::hash::Hash; + + let ptr = self.0.as_ref().map(|inner| inner.ptr()); + ptr.hash(hasher); + } +} + +impl UnboundedSender { + /// Check if the channel is ready to receive a message. + pub fn poll_ready(&self, _: &mut Context<'_>) -> Poll> { + let inner = self.0.as_ref().ok_or(SendError { kind: SendErrorKind::Disconnected })?; + inner.poll_ready_nb() + } + + /// Returns whether this channel is closed without needing a context. + pub fn is_closed(&self) -> bool { + self.0.as_ref().map(UnboundedSenderInner::is_closed).unwrap_or(true) + } + + /// Closes this channel from the sender side, preventing any new messages. + pub fn close_channel(&self) { + if let Some(inner) = &self.0 { + inner.close_channel(); + } + } + + /// Disconnects this sender from the channel, closing it if there are no more senders left. + pub fn disconnect(&mut self) { + self.0 = None; + } + + // Do the send without parking current task. + fn do_send_nb(&self, msg: T) -> Result<(), TrySendError> { + if let Some(inner) = &self.0 { + if inner.inc_num_messages().is_some() { + inner.queue_push_and_signal(msg); + return Ok(()); + } + } + + Err(TrySendError { err: SendError { kind: SendErrorKind::Disconnected }, val: msg }) + } + + /// Send a message on the channel. + /// + /// This method should only be called after `poll_ready` has been used to + /// verify that the channel is ready to receive a message. + pub fn start_send(&mut self, msg: T) -> Result<(), SendError> { + self.do_send_nb(msg).map_err(|e| e.err) + } + + /// Sends a message along this channel. + /// + /// This is an unbounded sender, so this function differs from `Sink::send` + /// by ensuring the return type reflects that the channel is always ready to + /// receive messages. + pub fn unbounded_send(&self, msg: T) -> Result<(), TrySendError> { + self.do_send_nb(msg) + } + + /// Returns whether the senders send to the same receiver. + pub fn same_receiver(&self, other: &Self) -> bool { + match (&self.0, &other.0) { + (Some(inner), Some(other)) => inner.same_receiver(other), + _ => false, + } + } + + /// Returns whether the sender send to this receiver. + pub fn is_connected_to(&self, receiver: &UnboundedReceiver) -> bool { + match (&self.0, &receiver.inner) { + (Some(inner), Some(receiver)) => inner.is_connected_to(receiver), + _ => false, + } + } + + /// Hashes the receiver into the provided hasher + pub fn hash_receiver(&self, hasher: &mut H) + where + H: std::hash::Hasher, + { + use std::hash::Hash; + + let ptr = self.0.as_ref().map(|inner| inner.ptr()); + ptr.hash(hasher); + } + + /// Return the number of messages in the queue or 0 if channel is disconnected. + pub fn len(&self) -> usize { + if let Some(sender) = &self.0 { + decode_state(sender.inner.state.load(SeqCst)).num_messages + } else { + 0 + } + } + + /// Return false is channel has no queued messages, true otherwise. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl Clone for Sender { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl Clone for UnboundedSender { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl Clone for UnboundedSenderInner { + fn clone(&self) -> Self { + // Since this atomic op isn't actually guarding any memory and we don't + // care about any orderings besides the ordering on the single atomic + // variable, a relaxed ordering is acceptable. + let mut curr = self.inner.num_senders.load(SeqCst); + + loop { + // If the maximum number of senders has been reached, then fail + if curr == MAX_BUFFER { + panic!("cannot clone `Sender` -- too many outstanding senders"); + } + + debug_assert!(curr < MAX_BUFFER); + + let next = curr + 1; + match self.inner.num_senders.compare_exchange(curr, next, SeqCst, SeqCst) { + Ok(_) => { + // The ABA problem doesn't matter here. We only care that the + // number of senders never exceeds the maximum. + return Self { inner: self.inner.clone() }; + } + Err(actual) => curr = actual, + } + } + } +} + +impl Clone for BoundedSenderInner { + fn clone(&self) -> Self { + // Since this atomic op isn't actually guarding any memory and we don't + // care about any orderings besides the ordering on the single atomic + // variable, a relaxed ordering is acceptable. + let mut curr = self.inner.num_senders.load(SeqCst); + + loop { + // If the maximum number of senders has been reached, then fail + if curr == self.inner.max_senders() { + panic!("cannot clone `Sender` -- too many outstanding senders"); + } + + debug_assert!(curr < self.inner.max_senders()); + + let next = curr + 1; + match self.inner.num_senders.compare_exchange(curr, next, SeqCst, SeqCst) { + Ok(_) => { + // The ABA problem doesn't matter here. We only care that the + // number of senders never exceeds the maximum. + return Self { + inner: self.inner.clone(), + sender_task: Arc::new(Mutex::new(SenderTask::new())), + maybe_parked: false, + }; + } + Err(actual) => curr = actual, + } + } + } +} + +impl Drop for UnboundedSenderInner { + fn drop(&mut self) { + // Ordering between variables don't matter here + let prev = self.inner.num_senders.fetch_sub(1, SeqCst); + + if prev == 1 { + self.close_channel(); + } + } +} + +impl Drop for BoundedSenderInner { + fn drop(&mut self) { + // Ordering between variables don't matter here + let prev = self.inner.num_senders.fetch_sub(1, SeqCst); + + if prev == 1 { + self.close_channel(); + } + } +} + +impl fmt::Debug for Sender { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Sender").field("closed", &self.is_closed()).finish() + } +} + +impl fmt::Debug for UnboundedSender { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("UnboundedSender").field("closed", &self.is_closed()).finish() + } +} + +/* + * + * ===== impl Receiver ===== + * + */ + +impl Receiver { + /// Closes the receiving half of a channel, without dropping it. + /// + /// This prevents any further messages from being sent on the channel while + /// still enabling the receiver to drain messages that are buffered. + pub fn close(&mut self) { + if let Some(inner) = &mut self.inner { + inner.set_closed(); + + // Wake up any threads waiting as they'll see that we've closed the + // channel and will continue on their merry way. + while let Some(task) = unsafe { inner.parked_queue.pop_spin() } { + task.lock().unwrap().notify(); + } + } + } + + /// Tries to receive the next message without notifying a context if empty. + /// + /// It is not recommended to call this function from inside of a future, + /// only when you've otherwise arranged to be notified when the channel is + /// no longer empty. + /// + /// This function returns: + /// * `Ok(Some(t))` when message is fetched + /// * `Ok(None)` when channel is closed and no messages left in the queue + /// * `Err(e)` when there are no messages available, but channel is not yet closed + pub fn try_next(&mut self) -> Result, TryRecvError> { + match self.next_message() { + Poll::Ready(msg) => Ok(msg), + Poll::Pending => Err(TryRecvError { _priv: () }), + } + } + + fn next_message(&mut self) -> Poll> { + let inner = match self.inner.as_mut() { + None => return Poll::Ready(None), + Some(inner) => inner, + }; + // Pop off a message + match unsafe { inner.message_queue.pop_spin() } { + Some(msg) => { + // If there are any parked task handles in the parked queue, + // pop one and unpark it. + self.unpark_one(); + + // Decrement number of messages + self.dec_num_messages(); + + Poll::Ready(Some(msg)) + } + None => { + let state = decode_state(inner.state.load(SeqCst)); + if state.is_closed() { + // If closed flag is set AND there are no pending messages + // it means end of stream + self.inner = None; + Poll::Ready(None) + } else { + // If queue is open, we need to return Pending + // to be woken up when new messages arrive. + // If queue is closed but num_messages is non-zero, + // it means that senders updated the state, + // but didn't put message to queue yet, + // so we need to park until sender unparks the task + // after queueing the message. + Poll::Pending + } + } + } + } + + // Unpark a single task handle if there is one pending in the parked queue + fn unpark_one(&mut self) { + if let Some(inner) = &mut self.inner { + if let Some(task) = unsafe { inner.parked_queue.pop_spin() } { + task.lock().unwrap().notify(); + } + } + } + + fn dec_num_messages(&self) { + if let Some(inner) = &self.inner { + // OPEN_MASK is highest bit, so it's unaffected by subtraction + // unless there's underflow, and we know there's no underflow + // because number of messages at this point is always > 0. + inner.state.fetch_sub(1, SeqCst); + } + } +} + +// The receiver does not ever take a Pin to the inner T +impl Unpin for Receiver {} + +impl FusedStream for Receiver { + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +impl Stream for Receiver { + type Item = T; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + // Try to read a message off of the message queue. + match self.next_message() { + Poll::Ready(msg) => { + if msg.is_none() { + self.inner = None; + } + Poll::Ready(msg) + } + Poll::Pending => { + // There are no messages to read, in this case, park. + self.inner.as_ref().unwrap().recv_task.register(cx.waker()); + // Check queue again after parking to prevent race condition: + // a message could be added to the queue after previous `next_message` + // before `register` call. + self.next_message() + } + } + } + + fn size_hint(&self) -> (usize, Option) { + if let Some(inner) = &self.inner { + decode_state(inner.state.load(SeqCst)).size_hint() + } else { + (0, Some(0)) + } + } +} + +impl Drop for Receiver { + fn drop(&mut self) { + // Drain the channel of all pending messages + self.close(); + if self.inner.is_some() { + loop { + match self.next_message() { + Poll::Ready(Some(_)) => {} + Poll::Ready(None) => break, + Poll::Pending => { + let state = decode_state(self.inner.as_ref().unwrap().state.load(SeqCst)); + + // If the channel is closed, then there is no need to park. + if state.is_closed() { + break; + } + + // TODO: Spinning isn't ideal, it might be worth + // investigating using a condvar or some other strategy + // here. That said, if this case is hit, then another thread + // is about to push the value into the queue and this isn't + // the only spinlock in the impl right now. + thread::yield_now(); + } + } + } + } + } +} + +impl fmt::Debug for Receiver { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let closed = if let Some(ref inner) = self.inner { + decode_state(inner.state.load(SeqCst)).is_closed() + } else { + false + }; + + f.debug_struct("Receiver").field("closed", &closed).finish() + } +} + +impl UnboundedReceiver { + /// Closes the receiving half of a channel, without dropping it. + /// + /// This prevents any further messages from being sent on the channel while + /// still enabling the receiver to drain messages that are buffered. + pub fn close(&mut self) { + if let Some(inner) = &mut self.inner { + inner.set_closed(); + } + } + + /// Tries to receive the next message without notifying a context if empty. + /// + /// It is not recommended to call this function from inside of a future, + /// only when you've otherwise arranged to be notified when the channel is + /// no longer empty. + /// + /// This function returns: + /// * `Ok(Some(t))` when message is fetched + /// * `Ok(None)` when channel is closed and no messages left in the queue + /// * `Err(e)` when there are no messages available, but channel is not yet closed + pub fn try_next(&mut self) -> Result, TryRecvError> { + match self.next_message() { + Poll::Ready(msg) => Ok(msg), + Poll::Pending => Err(TryRecvError { _priv: () }), + } + } + + fn next_message(&mut self) -> Poll> { + let inner = match self.inner.as_mut() { + None => return Poll::Ready(None), + Some(inner) => inner, + }; + // Pop off a message + match unsafe { inner.message_queue.pop_spin() } { + Some(msg) => { + // Decrement number of messages + self.dec_num_messages(); + + Poll::Ready(Some(msg)) + } + None => { + let state = decode_state(inner.state.load(SeqCst)); + if state.is_closed() { + // If closed flag is set AND there are no pending messages + // it means end of stream + self.inner = None; + Poll::Ready(None) + } else { + // If queue is open, we need to return Pending + // to be woken up when new messages arrive. + // If queue is closed but num_messages is non-zero, + // it means that senders updated the state, + // but didn't put message to queue yet, + // so we need to park until sender unparks the task + // after queueing the message. + Poll::Pending + } + } + } + } + + fn dec_num_messages(&self) { + if let Some(inner) = &self.inner { + // OPEN_MASK is highest bit, so it's unaffected by subtraction + // unless there's underflow, and we know there's no underflow + // because number of messages at this point is always > 0. + inner.state.fetch_sub(1, SeqCst); + } + } +} + +impl FusedStream for UnboundedReceiver { + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +impl Stream for UnboundedReceiver { + type Item = T; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + // Try to read a message off of the message queue. + match self.next_message() { + Poll::Ready(msg) => { + if msg.is_none() { + self.inner = None; + } + Poll::Ready(msg) + } + Poll::Pending => { + // There are no messages to read, in this case, park. + self.inner.as_ref().unwrap().recv_task.register(cx.waker()); + // Check queue again after parking to prevent race condition: + // a message could be added to the queue after previous `next_message` + // before `register` call. + self.next_message() + } + } + } + + fn size_hint(&self) -> (usize, Option) { + if let Some(inner) = &self.inner { + decode_state(inner.state.load(SeqCst)).size_hint() + } else { + (0, Some(0)) + } + } +} + +impl Drop for UnboundedReceiver { + fn drop(&mut self) { + // Drain the channel of all pending messages + self.close(); + if self.inner.is_some() { + loop { + match self.next_message() { + Poll::Ready(Some(_)) => {} + Poll::Ready(None) => break, + Poll::Pending => { + let state = decode_state(self.inner.as_ref().unwrap().state.load(SeqCst)); + + // If the channel is closed, then there is no need to park. + if state.is_closed() { + break; + } + + // TODO: Spinning isn't ideal, it might be worth + // investigating using a condvar or some other strategy + // here. That said, if this case is hit, then another thread + // is about to push the value into the queue and this isn't + // the only spinlock in the impl right now. + thread::yield_now(); + } + } + } + } + } +} + +impl fmt::Debug for UnboundedReceiver { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let closed = if let Some(ref inner) = self.inner { + decode_state(inner.state.load(SeqCst)).is_closed() + } else { + false + }; + + f.debug_struct("Receiver").field("closed", &closed).finish() + } +} + +/* + * + * ===== impl Inner ===== + * + */ + +impl UnboundedInner { + // Clear `open` flag in the state, keep `num_messages` intact. + fn set_closed(&self) { + let curr = self.state.load(SeqCst); + if !decode_state(curr).is_open { + return; + } + + self.state.fetch_and(!OPEN_MASK, SeqCst); + } +} + +impl BoundedInner { + // The return value is such that the total number of messages that can be + // enqueued into the channel will never exceed MAX_CAPACITY + fn max_senders(&self) -> usize { + MAX_CAPACITY - self.buffer + } + + // Clear `open` flag in the state, keep `num_messages` intact. + fn set_closed(&self) { + let curr = self.state.load(SeqCst); + if !decode_state(curr).is_open { + return; + } + + self.state.fetch_and(!OPEN_MASK, SeqCst); + } +} + +unsafe impl Send for UnboundedInner {} +unsafe impl Sync for UnboundedInner {} + +unsafe impl Send for BoundedInner {} +unsafe impl Sync for BoundedInner {} + +impl State { + fn is_closed(&self) -> bool { + !self.is_open && self.num_messages == 0 + } + + fn size_hint(&self) -> (usize, Option) { + if self.is_open { + (self.num_messages, None) + } else { + (self.num_messages, Some(self.num_messages)) + } + } +} + +/* + * + * ===== Helpers ===== + * + */ + +fn decode_state(num: usize) -> State { + State { is_open: num & OPEN_MASK == OPEN_MASK, num_messages: num & MAX_CAPACITY } +} + +fn encode_state(state: &State) -> usize { + let mut num = state.num_messages; + + if state.is_open { + num |= OPEN_MASK; + } + + num +} diff --git a/utshell-0.5.0/vendor/futures-channel/src/mpsc/queue.rs b/utshell-0.5.0/vendor/futures-channel/src/mpsc/queue.rs new file mode 100644 index 00000000..02ec633f --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/src/mpsc/queue.rs @@ -0,0 +1,174 @@ +/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of Dmitry Vyukov. + */ + +//! A mostly lock-free multi-producer, single consumer queue for sending +//! messages between asynchronous tasks. +//! +//! The queue implementation is essentially the same one used for mpsc channels +//! in the standard library. +//! +//! Note that the current implementation of this queue has a caveat of the `pop` +//! method, and see the method for more information about it. Due to this +//! caveat, this queue may not be appropriate for all use-cases. + +// http://www.1024cores.net/home/lock-free-algorithms +// /queues/non-intrusive-mpsc-node-based-queue + +// NOTE: this implementation is lifted from the standard library and only +// slightly modified + +pub(super) use self::PopResult::*; + +use std::cell::UnsafeCell; +use std::ptr; +use std::sync::atomic::{AtomicPtr, Ordering}; +use std::thread; + +/// A result of the `pop` function. +pub(super) enum PopResult { + /// Some data has been popped + Data(T), + /// The queue is empty + Empty, + /// The queue is in an inconsistent state. Popping data should succeed, but + /// some pushers have yet to make enough progress in order allow a pop to + /// succeed. It is recommended that a pop() occur "in the near future" in + /// order to see if the sender has made progress or not + Inconsistent, +} + +struct Node { + next: AtomicPtr, + value: Option, +} + +/// The multi-producer single-consumer structure. This is not cloneable, but it +/// may be safely shared so long as it is guaranteed that there is only one +/// popper at a time (many pushers are allowed). +pub(super) struct Queue { + head: AtomicPtr>, + tail: UnsafeCell<*mut Node>, +} + +unsafe impl Send for Queue {} +unsafe impl Sync for Queue {} + +impl Node { + unsafe fn new(v: Option) -> *mut Self { + Box::into_raw(Box::new(Self { next: AtomicPtr::new(ptr::null_mut()), value: v })) + } +} + +impl Queue { + /// Creates a new queue that is safe to share among multiple producers and + /// one consumer. + pub(super) fn new() -> Self { + let stub = unsafe { Node::new(None) }; + Self { head: AtomicPtr::new(stub), tail: UnsafeCell::new(stub) } + } + + /// Pushes a new value onto this queue. + pub(super) fn push(&self, t: T) { + unsafe { + let n = Node::new(Some(t)); + let prev = self.head.swap(n, Ordering::AcqRel); + (*prev).next.store(n, Ordering::Release); + } + } + + /// Pops some data from this queue. + /// + /// Note that the current implementation means that this function cannot + /// return `Option`. It is possible for this queue to be in an + /// inconsistent state where many pushes have succeeded and completely + /// finished, but pops cannot return `Some(t)`. This inconsistent state + /// happens when a pusher is preempted at an inopportune moment. + /// + /// This inconsistent state means that this queue does indeed have data, but + /// it does not currently have access to it at this time. + /// + /// This function is unsafe because only one thread can call it at a time. + pub(super) unsafe fn pop(&self) -> PopResult { + let tail = *self.tail.get(); + let next = (*tail).next.load(Ordering::Acquire); + + if !next.is_null() { + *self.tail.get() = next; + assert!((*tail).value.is_none()); + assert!((*next).value.is_some()); + let ret = (*next).value.take().unwrap(); + drop(Box::from_raw(tail)); + return Data(ret); + } + + if self.head.load(Ordering::Acquire) == tail { + Empty + } else { + Inconsistent + } + } + + /// Pop an element similarly to `pop` function, but spin-wait on inconsistent + /// queue state instead of returning `Inconsistent`. + /// + /// This function is unsafe because only one thread can call it at a time. + pub(super) unsafe fn pop_spin(&self) -> Option { + loop { + match self.pop() { + Empty => return None, + Data(t) => return Some(t), + // Inconsistent means that there will be a message to pop + // in a short time. This branch can only be reached if + // values are being produced from another thread, so there + // are a few ways that we can deal with this: + // + // 1) Spin + // 2) thread::yield_now() + // 3) task::current().unwrap() & return Pending + // + // For now, thread::yield_now() is used, but it would + // probably be better to spin a few times then yield. + Inconsistent => { + thread::yield_now(); + } + } + } + } +} + +impl Drop for Queue { + fn drop(&mut self) { + unsafe { + let mut cur = *self.tail.get(); + while !cur.is_null() { + let next = (*cur).next.load(Ordering::Relaxed); + drop(Box::from_raw(cur)); + cur = next; + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-channel/src/mpsc/sink_impl.rs b/utshell-0.5.0/vendor/futures-channel/src/mpsc/sink_impl.rs new file mode 100644 index 00000000..1be20162 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/src/mpsc/sink_impl.rs @@ -0,0 +1,73 @@ +use super::{SendError, Sender, TrySendError, UnboundedSender}; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use std::pin::Pin; + +impl Sink for Sender { + type Error = SendError; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + (*self).poll_ready(cx) + } + + fn start_send(mut self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> { + (*self).start_send(msg) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match (*self).poll_ready(cx) { + Poll::Ready(Err(ref e)) if e.is_disconnected() => { + // If the receiver disconnected, we consider the sink to be flushed. + Poll::Ready(Ok(())) + } + x => x, + } + } + + fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + self.disconnect(); + Poll::Ready(Ok(())) + } +} + +impl Sink for UnboundedSender { + type Error = SendError; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Self::poll_ready(&*self, cx) + } + + fn start_send(mut self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> { + Self::start_send(&mut *self, msg) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + self.disconnect(); + Poll::Ready(Ok(())) + } +} + +impl Sink for &UnboundedSender { + type Error = SendError; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + UnboundedSender::poll_ready(*self, cx) + } + + fn start_send(self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> { + self.unbounded_send(msg).map_err(TrySendError::into_send_error) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + self.close_channel(); + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-channel/src/oneshot.rs b/utshell-0.5.0/vendor/futures-channel/src/oneshot.rs new file mode 100644 index 00000000..fe5b115a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/src/oneshot.rs @@ -0,0 +1,488 @@ +//! A channel for sending a single message between asynchronous tasks. +//! +//! This is a single-producer, single-consumer channel. + +use alloc::sync::Arc; +use core::fmt; +use core::pin::Pin; +use core::sync::atomic::AtomicBool; +use core::sync::atomic::Ordering::SeqCst; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll, Waker}; + +use crate::lock::Lock; + +/// A future for a value that will be provided by another asynchronous task. +/// +/// This is created by the [`channel`] function. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Receiver { + inner: Arc>, +} + +/// A means of transmitting a single value to another task. +/// +/// This is created by the [`channel`] function. +pub struct Sender { + inner: Arc>, +} + +// The channels do not ever project Pin to the inner T +impl Unpin for Receiver {} +impl Unpin for Sender {} + +/// Internal state of the `Receiver`/`Sender` pair above. This is all used as +/// the internal synchronization between the two for send/recv operations. +struct Inner { + /// Indicates whether this oneshot is complete yet. This is filled in both + /// by `Sender::drop` and by `Receiver::drop`, and both sides interpret it + /// appropriately. + /// + /// For `Receiver`, if this is `true`, then it's guaranteed that `data` is + /// unlocked and ready to be inspected. + /// + /// For `Sender` if this is `true` then the oneshot has gone away and it + /// can return ready from `poll_canceled`. + complete: AtomicBool, + + /// The actual data being transferred as part of this `Receiver`. This is + /// filled in by `Sender::complete` and read by `Receiver::poll`. + /// + /// Note that this is protected by `Lock`, but it is in theory safe to + /// replace with an `UnsafeCell` as it's actually protected by `complete` + /// above. I wouldn't recommend doing this, however, unless someone is + /// supremely confident in the various atomic orderings here and there. + data: Lock>, + + /// Field to store the task which is blocked in `Receiver::poll`. + /// + /// This is filled in when a oneshot is polled but not ready yet. Note that + /// the `Lock` here, unlike in `data` above, is important to resolve races. + /// Both the `Receiver` and the `Sender` halves understand that if they + /// can't acquire the lock then some important interference is happening. + rx_task: Lock>, + + /// Like `rx_task` above, except for the task blocked in + /// `Sender::poll_canceled`. Additionally, `Lock` cannot be `UnsafeCell`. + tx_task: Lock>, +} + +/// Creates a new one-shot channel for sending a single value across asynchronous tasks. +/// +/// The channel works for a spsc (single-producer, single-consumer) scheme. +/// +/// This function is similar to Rust's channel constructor found in the standard +/// library. Two halves are returned, the first of which is a `Sender` handle, +/// used to signal the end of a computation and provide its value. The second +/// half is a `Receiver` which implements the `Future` trait, resolving to the +/// value that was given to the `Sender` handle. +/// +/// Each half can be separately owned and sent across tasks. +/// +/// # Examples +/// +/// ``` +/// use futures::channel::oneshot; +/// use std::{thread, time::Duration}; +/// +/// let (sender, receiver) = oneshot::channel::(); +/// +/// thread::spawn(|| { +/// println!("THREAD: sleeping zzz..."); +/// thread::sleep(Duration::from_millis(1000)); +/// println!("THREAD: i'm awake! sending."); +/// sender.send(3).unwrap(); +/// }); +/// +/// println!("MAIN: doing some useful stuff"); +/// +/// futures::executor::block_on(async { +/// println!("MAIN: waiting for msg..."); +/// println!("MAIN: got: {:?}", receiver.await) +/// }); +/// ``` +pub fn channel() -> (Sender, Receiver) { + let inner = Arc::new(Inner::new()); + let receiver = Receiver { inner: inner.clone() }; + let sender = Sender { inner }; + (sender, receiver) +} + +impl Inner { + fn new() -> Self { + Self { + complete: AtomicBool::new(false), + data: Lock::new(None), + rx_task: Lock::new(None), + tx_task: Lock::new(None), + } + } + + fn send(&self, t: T) -> Result<(), T> { + if self.complete.load(SeqCst) { + return Err(t); + } + + // Note that this lock acquisition may fail if the receiver + // is closed and sets the `complete` flag to `true`, whereupon + // the receiver may call `poll()`. + if let Some(mut slot) = self.data.try_lock() { + assert!(slot.is_none()); + *slot = Some(t); + drop(slot); + + // If the receiver called `close()` between the check at the + // start of the function, and the lock being released, then + // the receiver may not be around to receive it, so try to + // pull it back out. + if self.complete.load(SeqCst) { + // If lock acquisition fails, then receiver is actually + // receiving it, so we're good. + if let Some(mut slot) = self.data.try_lock() { + if let Some(t) = slot.take() { + return Err(t); + } + } + } + Ok(()) + } else { + // Must have been closed + Err(t) + } + } + + fn poll_canceled(&self, cx: &mut Context<'_>) -> Poll<()> { + // Fast path up first, just read the flag and see if our other half is + // gone. This flag is set both in our destructor and the oneshot + // destructor, but our destructor hasn't run yet so if it's set then the + // oneshot is gone. + if self.complete.load(SeqCst) { + return Poll::Ready(()); + } + + // If our other half is not gone then we need to park our current task + // and move it into the `tx_task` slot to get notified when it's + // actually gone. + // + // If `try_lock` fails, then the `Receiver` is in the process of using + // it, so we can deduce that it's now in the process of going away and + // hence we're canceled. If it succeeds then we just store our handle. + // + // Crucially we then check `complete` *again* before we return. + // While we were storing our handle inside `tx_task` the + // `Receiver` may have been dropped. The first thing it does is set the + // flag, and if it fails to acquire the lock it assumes that we'll see + // the flag later on. So... we then try to see the flag later on! + let handle = cx.waker().clone(); + match self.tx_task.try_lock() { + Some(mut p) => *p = Some(handle), + None => return Poll::Ready(()), + } + if self.complete.load(SeqCst) { + Poll::Ready(()) + } else { + Poll::Pending + } + } + + fn is_canceled(&self) -> bool { + self.complete.load(SeqCst) + } + + fn drop_tx(&self) { + // Flag that we're a completed `Sender` and try to wake up a receiver. + // Whether or not we actually stored any data will get picked up and + // translated to either an item or cancellation. + // + // Note that if we fail to acquire the `rx_task` lock then that means + // we're in one of two situations: + // + // 1. The receiver is trying to block in `poll` + // 2. The receiver is being dropped + // + // In the first case it'll check the `complete` flag after it's done + // blocking to see if it succeeded. In the latter case we don't need to + // wake up anyone anyway. So in both cases it's ok to ignore the `None` + // case of `try_lock` and bail out. + // + // The first case crucially depends on `Lock` using `SeqCst` ordering + // under the hood. If it instead used `Release` / `Acquire` ordering, + // then it would not necessarily synchronize with `inner.complete` + // and deadlock might be possible, as was observed in + // https://github.com/rust-lang/futures-rs/pull/219. + self.complete.store(true, SeqCst); + + if let Some(mut slot) = self.rx_task.try_lock() { + if let Some(task) = slot.take() { + drop(slot); + task.wake(); + } + } + + // If we registered a task for cancel notification drop it to reduce + // spurious wakeups + if let Some(mut slot) = self.tx_task.try_lock() { + drop(slot.take()); + } + } + + fn close_rx(&self) { + // Flag our completion and then attempt to wake up the sender if it's + // blocked. See comments in `drop` below for more info + self.complete.store(true, SeqCst); + if let Some(mut handle) = self.tx_task.try_lock() { + if let Some(task) = handle.take() { + drop(handle); + task.wake() + } + } + } + + fn try_recv(&self) -> Result, Canceled> { + // If we're complete, either `::close_rx` or `::drop_tx` was called. + // We can assume a successful send if data is present. + if self.complete.load(SeqCst) { + if let Some(mut slot) = self.data.try_lock() { + if let Some(data) = slot.take() { + return Ok(Some(data)); + } + } + Err(Canceled) + } else { + Ok(None) + } + } + + fn recv(&self, cx: &mut Context<'_>) -> Poll> { + // Check to see if some data has arrived. If it hasn't then we need to + // block our task. + // + // Note that the acquisition of the `rx_task` lock might fail below, but + // the only situation where this can happen is during `Sender::drop` + // when we are indeed completed already. If that's happening then we + // know we're completed so keep going. + let done = if self.complete.load(SeqCst) { + true + } else { + let task = cx.waker().clone(); + match self.rx_task.try_lock() { + Some(mut slot) => { + *slot = Some(task); + false + } + None => true, + } + }; + + // If we're `done` via one of the paths above, then look at the data and + // figure out what the answer is. If, however, we stored `rx_task` + // successfully above we need to check again if we're completed in case + // a message was sent while `rx_task` was locked and couldn't notify us + // otherwise. + // + // If we're not done, and we're not complete, though, then we've + // successfully blocked our task and we return `Pending`. + if done || self.complete.load(SeqCst) { + // If taking the lock fails, the sender will realise that the we're + // `done` when it checks the `complete` flag on the way out, and + // will treat the send as a failure. + if let Some(mut slot) = self.data.try_lock() { + if let Some(data) = slot.take() { + return Poll::Ready(Ok(data)); + } + } + Poll::Ready(Err(Canceled)) + } else { + Poll::Pending + } + } + + fn drop_rx(&self) { + // Indicate to the `Sender` that we're done, so any future calls to + // `poll_canceled` are weeded out. + self.complete.store(true, SeqCst); + + // If we've blocked a task then there's no need for it to stick around, + // so we need to drop it. If this lock acquisition fails, though, then + // it's just because our `Sender` is trying to take the task, so we + // let them take care of that. + if let Some(mut slot) = self.rx_task.try_lock() { + let task = slot.take(); + drop(slot); + drop(task); + } + + // Finally, if our `Sender` wants to get notified of us going away, it + // would have stored something in `tx_task`. Here we try to peel that + // out and unpark it. + // + // Note that the `try_lock` here may fail, but only if the `Sender` is + // in the process of filling in the task. If that happens then we + // already flagged `complete` and they'll pick that up above. + if let Some(mut handle) = self.tx_task.try_lock() { + if let Some(task) = handle.take() { + drop(handle); + task.wake() + } + } + } +} + +impl Sender { + /// Completes this oneshot with a successful result. + /// + /// This function will consume `self` and indicate to the other end, the + /// [`Receiver`], that the value provided is the result of the computation + /// this represents. + /// + /// If the value is successfully enqueued for the remote end to receive, + /// then `Ok(())` is returned. If the receiving end was dropped before + /// this function was called, however, then `Err(t)` is returned. + pub fn send(self, t: T) -> Result<(), T> { + self.inner.send(t) + } + + /// Polls this `Sender` half to detect whether its associated + /// [`Receiver`] has been dropped. + /// + /// # Return values + /// + /// If `Ready(())` is returned then the associated `Receiver` has been + /// dropped, which means any work required for sending should be canceled. + /// + /// If `Pending` is returned then the associated `Receiver` is still + /// alive and may be able to receive a message if sent. The current task, + /// however, is scheduled to receive a notification if the corresponding + /// `Receiver` goes away. + pub fn poll_canceled(&mut self, cx: &mut Context<'_>) -> Poll<()> { + self.inner.poll_canceled(cx) + } + + /// Creates a future that resolves when this `Sender`'s corresponding + /// [`Receiver`] half has hung up. + /// + /// This is a utility wrapping [`poll_canceled`](Sender::poll_canceled) + /// to expose a [`Future`]. + pub fn cancellation(&mut self) -> Cancellation<'_, T> { + Cancellation { inner: self } + } + + /// Tests to see whether this `Sender`'s corresponding `Receiver` + /// has been dropped. + /// + /// Unlike [`poll_canceled`](Sender::poll_canceled), this function does not + /// enqueue a task for wakeup upon cancellation, but merely reports the + /// current state, which may be subject to concurrent modification. + pub fn is_canceled(&self) -> bool { + self.inner.is_canceled() + } + + /// Tests to see whether this `Sender` is connected to the given `Receiver`. That is, whether + /// they were created by the same call to `channel`. + pub fn is_connected_to(&self, receiver: &Receiver) -> bool { + Arc::ptr_eq(&self.inner, &receiver.inner) + } +} + +impl Drop for Sender { + fn drop(&mut self) { + self.inner.drop_tx() + } +} + +impl fmt::Debug for Sender { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Sender").field("complete", &self.inner.complete).finish() + } +} + +/// A future that resolves when the receiving end of a channel has hung up. +/// +/// This is an `.await`-friendly interface around [`poll_canceled`](Sender::poll_canceled). +#[must_use = "futures do nothing unless you `.await` or poll them"] +#[derive(Debug)] +pub struct Cancellation<'a, T> { + inner: &'a mut Sender, +} + +impl Future for Cancellation<'_, T> { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + self.inner.poll_canceled(cx) + } +} + +/// Error returned from a [`Receiver`] when the corresponding [`Sender`] is +/// dropped. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct Canceled; + +impl fmt::Display for Canceled { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "oneshot canceled") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Canceled {} + +impl Receiver { + /// Gracefully close this receiver, preventing any subsequent attempts to + /// send to it. + /// + /// Any `send` operation which happens after this method returns is + /// guaranteed to fail. After calling this method, you can use + /// [`Receiver::poll`](core::future::Future::poll) to determine whether a + /// message had previously been sent. + pub fn close(&mut self) { + self.inner.close_rx() + } + + /// Attempts to receive a message outside of the context of a task. + /// + /// Does not schedule a task wakeup or have any other side effects. + /// + /// A return value of `None` must be considered immediately stale (out of + /// date) unless [`close`](Receiver::close) has been called first. + /// + /// Returns an error if the sender was dropped. + pub fn try_recv(&mut self) -> Result, Canceled> { + self.inner.try_recv() + } +} + +impl Future for Receiver { + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.inner.recv(cx) + } +} + +impl FusedFuture for Receiver { + fn is_terminated(&self) -> bool { + if self.inner.complete.load(SeqCst) { + if let Some(slot) = self.inner.data.try_lock() { + if slot.is_some() { + return false; + } + } + true + } else { + false + } + } +} + +impl Drop for Receiver { + fn drop(&mut self) { + self.inner.drop_rx() + } +} + +impl fmt::Debug for Receiver { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Receiver").field("complete", &self.inner.complete).finish() + } +} diff --git a/utshell-0.5.0/vendor/futures-channel/tests/channel.rs b/utshell-0.5.0/vendor/futures-channel/tests/channel.rs new file mode 100644 index 00000000..5f01a8ef --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/tests/channel.rs @@ -0,0 +1,66 @@ +use futures::channel::mpsc; +use futures::executor::block_on; +use futures::future::poll_fn; +use futures::sink::SinkExt; +use futures::stream::StreamExt; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::thread; + +#[test] +fn sequence() { + let (tx, rx) = mpsc::channel(1); + + let amt = 20; + let t = thread::spawn(move || block_on(send_sequence(amt, tx))); + let list: Vec<_> = block_on(rx.collect()); + let mut list = list.into_iter(); + for i in (1..=amt).rev() { + assert_eq!(list.next(), Some(i)); + } + assert_eq!(list.next(), None); + + t.join().unwrap(); +} + +async fn send_sequence(n: u32, mut sender: mpsc::Sender) { + for x in 0..n { + sender.send(n - x).await.unwrap(); + } +} + +#[test] +fn drop_sender() { + let (tx, mut rx) = mpsc::channel::(1); + drop(tx); + let f = poll_fn(|cx| rx.poll_next_unpin(cx)); + assert_eq!(block_on(f), None) +} + +#[test] +fn drop_rx() { + let (mut tx, rx) = mpsc::channel::(1); + block_on(tx.send(1)).unwrap(); + drop(rx); + assert!(block_on(tx.send(1)).is_err()); +} + +#[test] +fn drop_order() { + static DROPS: AtomicUsize = AtomicUsize::new(0); + let (mut tx, rx) = mpsc::channel(1); + + struct A; + + impl Drop for A { + fn drop(&mut self) { + DROPS.fetch_add(1, Ordering::SeqCst); + } + } + + block_on(tx.send(A)).unwrap(); + assert_eq!(DROPS.load(Ordering::SeqCst), 0); + drop(rx); + assert_eq!(DROPS.load(Ordering::SeqCst), 1); + assert!(block_on(tx.send(A)).is_err()); + assert_eq!(DROPS.load(Ordering::SeqCst), 2); +} diff --git a/utshell-0.5.0/vendor/futures-channel/tests/mpsc-close.rs b/utshell-0.5.0/vendor/futures-channel/tests/mpsc-close.rs new file mode 100644 index 00000000..1a14067e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/tests/mpsc-close.rs @@ -0,0 +1,299 @@ +use futures::channel::mpsc; +use futures::executor::block_on; +use futures::future::Future; +use futures::sink::SinkExt; +use futures::stream::StreamExt; +use futures::task::{Context, Poll}; +use std::pin::Pin; +use std::sync::{Arc, Weak}; +use std::thread; +use std::time::{Duration, Instant}; + +#[test] +fn smoke() { + let (mut sender, receiver) = mpsc::channel(1); + + let t = thread::spawn(move || while let Ok(()) = block_on(sender.send(42)) {}); + + // `receiver` needs to be dropped for `sender` to stop sending and therefore before the join. + block_on(receiver.take(3).for_each(|_| futures::future::ready(()))); + + t.join().unwrap() +} + +#[test] +fn multiple_senders_disconnect() { + { + let (mut tx1, mut rx) = mpsc::channel(1); + let (tx2, mut tx3, mut tx4) = (tx1.clone(), tx1.clone(), tx1.clone()); + + // disconnect, dropping and Sink::poll_close should all close this sender but leave the + // channel open for other senders + tx1.disconnect(); + drop(tx2); + block_on(tx3.close()).unwrap(); + + assert!(tx1.is_closed()); + assert!(tx3.is_closed()); + assert!(!tx4.is_closed()); + + block_on(tx4.send(5)).unwrap(); + assert_eq!(block_on(rx.next()), Some(5)); + + // dropping the final sender will close the channel + drop(tx4); + assert_eq!(block_on(rx.next()), None); + } + + { + let (mut tx1, mut rx) = mpsc::unbounded(); + let (tx2, mut tx3, mut tx4) = (tx1.clone(), tx1.clone(), tx1.clone()); + + // disconnect, dropping and Sink::poll_close should all close this sender but leave the + // channel open for other senders + tx1.disconnect(); + drop(tx2); + block_on(tx3.close()).unwrap(); + + assert!(tx1.is_closed()); + assert!(tx3.is_closed()); + assert!(!tx4.is_closed()); + + block_on(tx4.send(5)).unwrap(); + assert_eq!(block_on(rx.next()), Some(5)); + + // dropping the final sender will close the channel + drop(tx4); + assert_eq!(block_on(rx.next()), None); + } +} + +#[test] +fn multiple_senders_close_channel() { + { + let (mut tx1, mut rx) = mpsc::channel(1); + let mut tx2 = tx1.clone(); + + // close_channel should shut down the whole channel + tx1.close_channel(); + + assert!(tx1.is_closed()); + assert!(tx2.is_closed()); + + let err = block_on(tx2.send(5)).unwrap_err(); + assert!(err.is_disconnected()); + + assert_eq!(block_on(rx.next()), None); + } + + { + let (tx1, mut rx) = mpsc::unbounded(); + let mut tx2 = tx1.clone(); + + // close_channel should shut down the whole channel + tx1.close_channel(); + + assert!(tx1.is_closed()); + assert!(tx2.is_closed()); + + let err = block_on(tx2.send(5)).unwrap_err(); + assert!(err.is_disconnected()); + + assert_eq!(block_on(rx.next()), None); + } +} + +#[test] +fn single_receiver_drop_closes_channel_and_drains() { + { + let ref_count = Arc::new(0); + let weak_ref = Arc::downgrade(&ref_count); + + let (sender, receiver) = mpsc::unbounded(); + sender.unbounded_send(ref_count).expect("failed to send"); + + // Verify that the sent message is still live. + assert!(weak_ref.upgrade().is_some()); + + drop(receiver); + + // The sender should know the channel is closed. + assert!(sender.is_closed()); + + // Verify that the sent message has been dropped. + assert!(weak_ref.upgrade().is_none()); + } + + { + let ref_count = Arc::new(0); + let weak_ref = Arc::downgrade(&ref_count); + + let (mut sender, receiver) = mpsc::channel(1); + sender.try_send(ref_count).expect("failed to send"); + + // Verify that the sent message is still live. + assert!(weak_ref.upgrade().is_some()); + + drop(receiver); + + // The sender should know the channel is closed. + assert!(sender.is_closed()); + + // Verify that the sent message has been dropped. + assert!(weak_ref.upgrade().is_none()); + assert!(sender.is_closed()); + } +} + +// Stress test that `try_send()`s occurring concurrently with receiver +// close/drops don't appear as successful sends. +#[cfg_attr(miri, ignore)] // Miri is too slow +#[test] +fn stress_try_send_as_receiver_closes() { + const AMT: usize = 10000; + // To provide variable timing characteristics (in the hopes of + // reproducing the collision that leads to a race), we busy-re-poll + // the test MPSC receiver a variable number of times before actually + // stopping. We vary this countdown between 1 and the following + // value. + const MAX_COUNTDOWN: usize = 20; + // When we detect that a successfully sent item is still in the + // queue after a disconnect, we spin for up to 100ms to confirm that + // it is a persistent condition and not a concurrency illusion. + const SPIN_TIMEOUT_S: u64 = 10; + const SPIN_SLEEP_MS: u64 = 10; + struct TestRx { + rx: mpsc::Receiver>, + // The number of times to query `rx` before dropping it. + poll_count: usize, + } + struct TestTask { + command_rx: mpsc::Receiver, + test_rx: Option>>, + countdown: usize, + } + impl TestTask { + /// Create a new TestTask + fn new() -> (TestTask, mpsc::Sender) { + let (command_tx, command_rx) = mpsc::channel::(0); + ( + TestTask { + command_rx, + test_rx: None, + countdown: 0, // 0 means no countdown is in progress. + }, + command_tx, + ) + } + } + impl Future for TestTask { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // Poll the test channel, if one is present. + if let Some(rx) = &mut self.test_rx { + if let Poll::Ready(v) = rx.poll_next_unpin(cx) { + let _ = v.expect("test finished unexpectedly!"); + } + self.countdown -= 1; + // Busy-poll until the countdown is finished. + cx.waker().wake_by_ref(); + } + // Accept any newly submitted MPSC channels for testing. + match self.command_rx.poll_next_unpin(cx) { + Poll::Ready(Some(TestRx { rx, poll_count })) => { + self.test_rx = Some(rx); + self.countdown = poll_count; + cx.waker().wake_by_ref(); + } + Poll::Ready(None) => return Poll::Ready(()), + Poll::Pending => {} + } + if self.countdown == 0 { + // Countdown complete -- drop the Receiver. + self.test_rx = None; + } + Poll::Pending + } + } + let (f, mut cmd_tx) = TestTask::new(); + let bg = thread::spawn(move || block_on(f)); + for i in 0..AMT { + let (mut test_tx, rx) = mpsc::channel(0); + let poll_count = i % MAX_COUNTDOWN; + cmd_tx.try_send(TestRx { rx, poll_count }).unwrap(); + let mut prev_weak: Option> = None; + let mut attempted_sends = 0; + let mut successful_sends = 0; + loop { + // Create a test item. + let item = Arc::new(()); + let weak = Arc::downgrade(&item); + match test_tx.try_send(item) { + Ok(_) => { + prev_weak = Some(weak); + successful_sends += 1; + } + Err(ref e) if e.is_full() => {} + Err(ref e) if e.is_disconnected() => { + // Test for evidence of the race condition. + if let Some(prev_weak) = prev_weak { + if prev_weak.upgrade().is_some() { + // The previously sent item is still allocated. + // However, there appears to be some aspect of the + // concurrency that can legitimately cause the Arc + // to be momentarily valid. Spin for up to 100ms + // waiting for the previously sent item to be + // dropped. + let t0 = Instant::now(); + let mut spins = 0; + loop { + if prev_weak.upgrade().is_none() { + break; + } + assert!( + t0.elapsed() < Duration::from_secs(SPIN_TIMEOUT_S), + "item not dropped on iteration {} after \ + {} sends ({} successful). spin=({})", + i, + attempted_sends, + successful_sends, + spins + ); + spins += 1; + thread::sleep(Duration::from_millis(SPIN_SLEEP_MS)); + } + } + } + break; + } + Err(ref e) => panic!("unexpected error: {}", e), + } + attempted_sends += 1; + } + } + drop(cmd_tx); + bg.join().expect("background thread join"); +} + +#[test] +fn unbounded_try_next_after_none() { + let (tx, mut rx) = mpsc::unbounded::(); + // Drop the sender, close the channel. + drop(tx); + // Receive the end of channel. + assert_eq!(Ok(None), rx.try_next().map_err(|_| ())); + // None received, check we can call `try_next` again. + assert_eq!(Ok(None), rx.try_next().map_err(|_| ())); +} + +#[test] +fn bounded_try_next_after_none() { + let (tx, mut rx) = mpsc::channel::(17); + // Drop the sender, close the channel. + drop(tx); + // Receive the end of channel. + assert_eq!(Ok(None), rx.try_next().map_err(|_| ())); + // None received, check we can call `try_next` again. + assert_eq!(Ok(None), rx.try_next().map_err(|_| ())); +} diff --git a/utshell-0.5.0/vendor/futures-channel/tests/mpsc-size_hint.rs b/utshell-0.5.0/vendor/futures-channel/tests/mpsc-size_hint.rs new file mode 100644 index 00000000..d9cdaa31 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/tests/mpsc-size_hint.rs @@ -0,0 +1,40 @@ +use futures::channel::mpsc; +use futures::stream::Stream; + +#[test] +fn unbounded_size_hint() { + let (tx, mut rx) = mpsc::unbounded::(); + assert_eq!((0, None), rx.size_hint()); + tx.unbounded_send(1).unwrap(); + assert_eq!((1, None), rx.size_hint()); + rx.try_next().unwrap().unwrap(); + assert_eq!((0, None), rx.size_hint()); + tx.unbounded_send(2).unwrap(); + tx.unbounded_send(3).unwrap(); + assert_eq!((2, None), rx.size_hint()); + drop(tx); + assert_eq!((2, Some(2)), rx.size_hint()); + rx.try_next().unwrap().unwrap(); + assert_eq!((1, Some(1)), rx.size_hint()); + rx.try_next().unwrap().unwrap(); + assert_eq!((0, Some(0)), rx.size_hint()); +} + +#[test] +fn channel_size_hint() { + let (mut tx, mut rx) = mpsc::channel::(10); + assert_eq!((0, None), rx.size_hint()); + tx.try_send(1).unwrap(); + assert_eq!((1, None), rx.size_hint()); + rx.try_next().unwrap().unwrap(); + assert_eq!((0, None), rx.size_hint()); + tx.try_send(2).unwrap(); + tx.try_send(3).unwrap(); + assert_eq!((2, None), rx.size_hint()); + drop(tx); + assert_eq!((2, Some(2)), rx.size_hint()); + rx.try_next().unwrap().unwrap(); + assert_eq!((1, Some(1)), rx.size_hint()); + rx.try_next().unwrap().unwrap(); + assert_eq!((0, Some(0)), rx.size_hint()); +} diff --git a/utshell-0.5.0/vendor/futures-channel/tests/mpsc.rs b/utshell-0.5.0/vendor/futures-channel/tests/mpsc.rs new file mode 100644 index 00000000..f5d7198d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/tests/mpsc.rs @@ -0,0 +1,657 @@ +use futures::channel::{mpsc, oneshot}; +use futures::executor::{block_on, block_on_stream}; +use futures::future::{poll_fn, FutureExt}; +use futures::pin_mut; +use futures::sink::{Sink, SinkExt}; +use futures::stream::{Stream, StreamExt}; +use futures::task::{Context, Poll}; +use futures_test::task::{new_count_waker, noop_context}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; +use std::thread; + +trait AssertSend: Send {} +impl AssertSend for mpsc::Sender {} +impl AssertSend for mpsc::Receiver {} + +#[test] +fn send_recv() { + let (mut tx, rx) = mpsc::channel::(16); + + block_on(tx.send(1)).unwrap(); + drop(tx); + let v: Vec<_> = block_on(rx.collect()); + assert_eq!(v, vec![1]); +} + +#[test] +fn send_recv_no_buffer() { + // Run on a task context + block_on(poll_fn(move |cx| { + let (tx, rx) = mpsc::channel::(0); + pin_mut!(tx, rx); + + assert!(tx.as_mut().poll_flush(cx).is_ready()); + assert!(tx.as_mut().poll_ready(cx).is_ready()); + + // Send first message + assert!(tx.as_mut().start_send(1).is_ok()); + assert!(tx.as_mut().poll_ready(cx).is_pending()); + + // poll_ready said Pending, so no room in buffer, therefore new sends + // should get rejected with is_full. + assert!(tx.as_mut().start_send(0).unwrap_err().is_full()); + assert!(tx.as_mut().poll_ready(cx).is_pending()); + + // Take the value + assert_eq!(rx.as_mut().poll_next(cx), Poll::Ready(Some(1))); + assert!(tx.as_mut().poll_ready(cx).is_ready()); + + // Send second message + assert!(tx.as_mut().poll_ready(cx).is_ready()); + assert!(tx.as_mut().start_send(2).is_ok()); + assert!(tx.as_mut().poll_ready(cx).is_pending()); + + // Take the value + assert_eq!(rx.as_mut().poll_next(cx), Poll::Ready(Some(2))); + assert!(tx.as_mut().poll_ready(cx).is_ready()); + + Poll::Ready(()) + })); +} + +#[test] +fn send_shared_recv() { + let (mut tx1, rx) = mpsc::channel::(16); + let mut rx = block_on_stream(rx); + let mut tx2 = tx1.clone(); + + block_on(tx1.send(1)).unwrap(); + assert_eq!(rx.next(), Some(1)); + + block_on(tx2.send(2)).unwrap(); + assert_eq!(rx.next(), Some(2)); +} + +#[test] +fn send_recv_threads() { + let (mut tx, rx) = mpsc::channel::(16); + + let t = thread::spawn(move || { + block_on(tx.send(1)).unwrap(); + }); + + let v: Vec<_> = block_on(rx.take(1).collect()); + assert_eq!(v, vec![1]); + + t.join().unwrap(); +} + +#[test] +fn send_recv_threads_no_capacity() { + let (mut tx, rx) = mpsc::channel::(0); + + let t = thread::spawn(move || { + block_on(tx.send(1)).unwrap(); + block_on(tx.send(2)).unwrap(); + }); + + let v: Vec<_> = block_on(rx.collect()); + assert_eq!(v, vec![1, 2]); + + t.join().unwrap(); +} + +#[test] +fn recv_close_gets_none() { + let (mut tx, mut rx) = mpsc::channel::(10); + + // Run on a task context + block_on(poll_fn(move |cx| { + rx.close(); + + assert_eq!(rx.poll_next_unpin(cx), Poll::Ready(None)); + match tx.poll_ready(cx) { + Poll::Pending | Poll::Ready(Ok(_)) => panic!(), + Poll::Ready(Err(e)) => assert!(e.is_disconnected()), + }; + + Poll::Ready(()) + })); +} + +#[test] +fn tx_close_gets_none() { + let (_, mut rx) = mpsc::channel::(10); + + // Run on a task context + block_on(poll_fn(move |cx| { + assert_eq!(rx.poll_next_unpin(cx), Poll::Ready(None)); + Poll::Ready(()) + })); +} + +// #[test] +// fn spawn_sends_items() { +// let core = local_executor::Core::new(); +// let stream = unfold(0, |i| Some(ok::<_,u8>((i, i + 1)))); +// let rx = mpsc::spawn(stream, &core, 1); +// assert_eq!(core.run(rx.take(4).collect()).unwrap(), +// [0, 1, 2, 3]); +// } + +// #[test] +// fn spawn_kill_dead_stream() { +// use std::thread; +// use std::time::Duration; +// use futures::future::Either; +// use futures::sync::oneshot; +// +// // a stream which never returns anything (maybe a remote end isn't +// // responding), but dropping it leads to observable side effects +// // (like closing connections, releasing limited resources, ...) +// #[derive(Debug)] +// struct Dead { +// // when dropped you should get Err(oneshot::Canceled) on the +// // receiving end +// done: oneshot::Sender<()>, +// } +// impl Stream for Dead { +// type Item = (); +// type Error = (); +// +// fn poll(&mut self) -> Poll, Self::Error> { +// Ok(Poll::Pending) +// } +// } +// +// // need to implement a timeout for the test, as it would hang +// // forever right now +// let (timeout_tx, timeout_rx) = oneshot::channel(); +// thread::spawn(move || { +// thread::sleep(Duration::from_millis(1000)); +// let _ = timeout_tx.send(()); +// }); +// +// let core = local_executor::Core::new(); +// let (done_tx, done_rx) = oneshot::channel(); +// let stream = Dead{done: done_tx}; +// let rx = mpsc::spawn(stream, &core, 1); +// let res = core.run( +// Ok::<_, ()>(()) +// .into_future() +// .then(move |_| { +// // now drop the spawned stream: maybe some timeout exceeded, +// // or some connection on this end was closed by the remote +// // end. +// drop(rx); +// // and wait for the spawned stream to release its resources +// done_rx +// }) +// .select2(timeout_rx) +// ); +// match res { +// Err(Either::A((oneshot::Canceled, _))) => (), +// _ => { +// panic!("dead stream wasn't canceled"); +// }, +// } +// } + +#[test] +fn stress_shared_unbounded() { + const AMT: u32 = if cfg!(miri) { 100 } else { 10000 }; + const NTHREADS: u32 = 8; + let (tx, rx) = mpsc::unbounded::(); + + let t = thread::spawn(move || { + let result: Vec<_> = block_on(rx.collect()); + assert_eq!(result.len(), (AMT * NTHREADS) as usize); + for item in result { + assert_eq!(item, 1); + } + }); + + for _ in 0..NTHREADS { + let tx = tx.clone(); + + thread::spawn(move || { + for _ in 0..AMT { + tx.unbounded_send(1).unwrap(); + } + }); + } + + drop(tx); + + t.join().ok().unwrap(); +} + +#[test] +fn stress_shared_bounded_hard() { + const AMT: u32 = if cfg!(miri) { 100 } else { 10000 }; + const NTHREADS: u32 = 8; + let (tx, rx) = mpsc::channel::(0); + + let t = thread::spawn(move || { + let result: Vec<_> = block_on(rx.collect()); + assert_eq!(result.len(), (AMT * NTHREADS) as usize); + for item in result { + assert_eq!(item, 1); + } + }); + + for _ in 0..NTHREADS { + let mut tx = tx.clone(); + + thread::spawn(move || { + for _ in 0..AMT { + block_on(tx.send(1)).unwrap(); + } + }); + } + + drop(tx); + + t.join().unwrap(); +} + +#[allow(clippy::same_item_push)] +#[test] +fn stress_receiver_multi_task_bounded_hard() { + const AMT: usize = if cfg!(miri) { 100 } else { 10_000 }; + const NTHREADS: u32 = 2; + + let (mut tx, rx) = mpsc::channel::(0); + let rx = Arc::new(Mutex::new(Some(rx))); + let n = Arc::new(AtomicUsize::new(0)); + + let mut th = vec![]; + + for _ in 0..NTHREADS { + let rx = rx.clone(); + let n = n.clone(); + + let t = thread::spawn(move || { + let mut i = 0; + + loop { + i += 1; + let mut rx_opt = rx.lock().unwrap(); + if let Some(rx) = &mut *rx_opt { + if i % 5 == 0 { + let item = block_on(rx.next()); + + if item.is_none() { + *rx_opt = None; + break; + } + + n.fetch_add(1, Ordering::Relaxed); + } else { + // Just poll + let n = n.clone(); + match rx.poll_next_unpin(&mut noop_context()) { + Poll::Ready(Some(_)) => { + n.fetch_add(1, Ordering::Relaxed); + } + Poll::Ready(None) => { + *rx_opt = None; + break; + } + Poll::Pending => {} + } + } + } else { + break; + } + } + }); + + th.push(t); + } + + for i in 0..AMT { + block_on(tx.send(i)).unwrap(); + } + drop(tx); + + for t in th { + t.join().unwrap(); + } + + assert_eq!(AMT, n.load(Ordering::Relaxed)); +} + +/// Stress test that receiver properly receives all the messages +/// after sender dropped. +#[test] +fn stress_drop_sender() { + const ITER: usize = if cfg!(miri) { 100 } else { 10000 }; + + fn list() -> impl Stream { + let (tx, rx) = mpsc::channel(1); + thread::spawn(move || { + block_on(send_one_two_three(tx)); + }); + rx + } + + for _ in 0..ITER { + let v: Vec<_> = block_on(list().collect()); + assert_eq!(v, vec![1, 2, 3]); + } +} + +async fn send_one_two_three(mut tx: mpsc::Sender) { + for i in 1..=3 { + tx.send(i).await.unwrap(); + } +} + +/// Stress test that after receiver dropped, +/// no messages are lost. +fn stress_close_receiver_iter() { + let (tx, rx) = mpsc::unbounded(); + let mut rx = block_on_stream(rx); + let (unwritten_tx, unwritten_rx) = std::sync::mpsc::channel(); + let th = thread::spawn(move || { + for i in 1.. { + if tx.unbounded_send(i).is_err() { + unwritten_tx.send(i).expect("unwritten_tx"); + return; + } + } + }); + + // Read one message to make sure thread effectively started + assert_eq!(Some(1), rx.next()); + + rx.close(); + + for i in 2.. { + match rx.next() { + Some(r) => assert!(i == r), + None => { + let unwritten = unwritten_rx.recv().expect("unwritten_rx"); + assert_eq!(unwritten, i); + th.join().unwrap(); + return; + } + } + } +} + +#[test] +fn stress_close_receiver() { + const ITER: usize = if cfg!(miri) { 50 } else { 10000 }; + + for _ in 0..ITER { + stress_close_receiver_iter(); + } +} + +async fn stress_poll_ready_sender(mut sender: mpsc::Sender, count: u32) { + for i in (1..=count).rev() { + sender.send(i).await.unwrap(); + } +} + +/// Tests that after `poll_ready` indicates capacity a channel can always send without waiting. +#[allow(clippy::same_item_push)] +#[test] +fn stress_poll_ready() { + const AMT: u32 = if cfg!(miri) { 100 } else { 1000 }; + const NTHREADS: u32 = 8; + + /// Run a stress test using the specified channel capacity. + fn stress(capacity: usize) { + let (tx, rx) = mpsc::channel(capacity); + let mut threads = Vec::new(); + for _ in 0..NTHREADS { + let sender = tx.clone(); + threads.push(thread::spawn(move || block_on(stress_poll_ready_sender(sender, AMT)))); + } + drop(tx); + + let result: Vec<_> = block_on(rx.collect()); + assert_eq!(result.len() as u32, AMT * NTHREADS); + + for thread in threads { + thread.join().unwrap(); + } + } + + stress(0); + stress(1); + stress(8); + stress(16); +} + +#[test] +fn try_send_1() { + const N: usize = if cfg!(miri) { 100 } else { 3000 }; + let (mut tx, rx) = mpsc::channel(0); + + let t = thread::spawn(move || { + for i in 0..N { + loop { + if tx.try_send(i).is_ok() { + break; + } + } + } + }); + + let result: Vec<_> = block_on(rx.collect()); + for (i, j) in result.into_iter().enumerate() { + assert_eq!(i, j); + } + + t.join().unwrap(); +} + +#[test] +fn try_send_2() { + let (mut tx, rx) = mpsc::channel(0); + let mut rx = block_on_stream(rx); + + tx.try_send("hello").unwrap(); + + let (readytx, readyrx) = oneshot::channel::<()>(); + + let th = thread::spawn(move || { + block_on(poll_fn(|cx| { + assert!(tx.poll_ready(cx).is_pending()); + Poll::Ready(()) + })); + + drop(readytx); + block_on(tx.send("goodbye")).unwrap(); + }); + + let _ = block_on(readyrx); + assert_eq!(rx.next(), Some("hello")); + assert_eq!(rx.next(), Some("goodbye")); + assert_eq!(rx.next(), None); + + th.join().unwrap(); +} + +#[test] +fn try_send_fail() { + let (mut tx, rx) = mpsc::channel(0); + let mut rx = block_on_stream(rx); + + tx.try_send("hello").unwrap(); + + // This should fail + assert!(tx.try_send("fail").is_err()); + + assert_eq!(rx.next(), Some("hello")); + + tx.try_send("goodbye").unwrap(); + drop(tx); + + assert_eq!(rx.next(), Some("goodbye")); + assert_eq!(rx.next(), None); +} + +#[test] +fn try_send_recv() { + let (mut tx, mut rx) = mpsc::channel(1); + tx.try_send("hello").unwrap(); + tx.try_send("hello").unwrap(); + tx.try_send("hello").unwrap_err(); // should be full + rx.try_next().unwrap(); + rx.try_next().unwrap(); + rx.try_next().unwrap_err(); // should be empty + tx.try_send("hello").unwrap(); + rx.try_next().unwrap(); + rx.try_next().unwrap_err(); // should be empty +} + +#[test] +fn same_receiver() { + let (mut txa1, _) = mpsc::channel::(1); + let txa2 = txa1.clone(); + + let (mut txb1, _) = mpsc::channel::(1); + let txb2 = txb1.clone(); + + assert!(txa1.same_receiver(&txa2)); + assert!(txb1.same_receiver(&txb2)); + assert!(!txa1.same_receiver(&txb1)); + + txa1.disconnect(); + txb1.close_channel(); + + assert!(!txa1.same_receiver(&txa2)); + assert!(txb1.same_receiver(&txb2)); +} + +#[test] +fn is_connected_to() { + let (txa, rxa) = mpsc::channel::(1); + let (txb, rxb) = mpsc::channel::(1); + + assert!(txa.is_connected_to(&rxa)); + assert!(txb.is_connected_to(&rxb)); + assert!(!txa.is_connected_to(&rxb)); + assert!(!txb.is_connected_to(&rxa)); +} + +#[test] +fn hash_receiver() { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hasher; + + let mut hasher_a1 = DefaultHasher::new(); + let mut hasher_a2 = DefaultHasher::new(); + let mut hasher_b1 = DefaultHasher::new(); + let mut hasher_b2 = DefaultHasher::new(); + let (mut txa1, _) = mpsc::channel::(1); + let txa2 = txa1.clone(); + + let (mut txb1, _) = mpsc::channel::(1); + let txb2 = txb1.clone(); + + txa1.hash_receiver(&mut hasher_a1); + let hash_a1 = hasher_a1.finish(); + txa2.hash_receiver(&mut hasher_a2); + let hash_a2 = hasher_a2.finish(); + txb1.hash_receiver(&mut hasher_b1); + let hash_b1 = hasher_b1.finish(); + txb2.hash_receiver(&mut hasher_b2); + let hash_b2 = hasher_b2.finish(); + + assert_eq!(hash_a1, hash_a2); + assert_eq!(hash_b1, hash_b2); + assert!(hash_a1 != hash_b1); + + txa1.disconnect(); + txb1.close_channel(); + + let mut hasher_a1 = DefaultHasher::new(); + let mut hasher_a2 = DefaultHasher::new(); + let mut hasher_b1 = DefaultHasher::new(); + let mut hasher_b2 = DefaultHasher::new(); + + txa1.hash_receiver(&mut hasher_a1); + let hash_a1 = hasher_a1.finish(); + txa2.hash_receiver(&mut hasher_a2); + let hash_a2 = hasher_a2.finish(); + txb1.hash_receiver(&mut hasher_b1); + let hash_b1 = hasher_b1.finish(); + txb2.hash_receiver(&mut hasher_b2); + let hash_b2 = hasher_b2.finish(); + + assert!(hash_a1 != hash_a2); + assert_eq!(hash_b1, hash_b2); +} + +#[test] +fn send_backpressure() { + let (waker, counter) = new_count_waker(); + let mut cx = Context::from_waker(&waker); + + let (mut tx, mut rx) = mpsc::channel(1); + block_on(tx.send(1)).unwrap(); + + let mut task = tx.send(2); + assert_eq!(task.poll_unpin(&mut cx), Poll::Pending); + assert_eq!(counter, 0); + + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 1); + assert_eq!(counter, 1); + assert_eq!(task.poll_unpin(&mut cx), Poll::Ready(Ok(()))); + + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 2); +} + +#[test] +fn send_backpressure_multi_senders() { + let (waker, counter) = new_count_waker(); + let mut cx = Context::from_waker(&waker); + + let (mut tx1, mut rx) = mpsc::channel(1); + let mut tx2 = tx1.clone(); + block_on(tx1.send(1)).unwrap(); + + let mut task = tx2.send(2); + assert_eq!(task.poll_unpin(&mut cx), Poll::Pending); + assert_eq!(counter, 0); + + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 1); + assert_eq!(counter, 1); + assert_eq!(task.poll_unpin(&mut cx), Poll::Ready(Ok(()))); + + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 2); +} + +/// Test that empty channel has zero length and that non-empty channel has length equal to number +/// of enqueued items +#[test] +fn unbounded_len() { + let (tx, mut rx) = mpsc::unbounded(); + assert_eq!(tx.len(), 0); + assert!(tx.is_empty()); + tx.unbounded_send(1).unwrap(); + assert_eq!(tx.len(), 1); + assert!(!tx.is_empty()); + tx.unbounded_send(2).unwrap(); + assert_eq!(tx.len(), 2); + assert!(!tx.is_empty()); + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 1); + assert_eq!(tx.len(), 1); + assert!(!tx.is_empty()); + let item = block_on(rx.next()).unwrap(); + assert_eq!(item, 2); + assert_eq!(tx.len(), 0); + assert!(tx.is_empty()); +} diff --git a/utshell-0.5.0/vendor/futures-channel/tests/oneshot.rs b/utshell-0.5.0/vendor/futures-channel/tests/oneshot.rs new file mode 100644 index 00000000..6b48376d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-channel/tests/oneshot.rs @@ -0,0 +1,256 @@ +use futures::channel::oneshot::{self, Sender}; +use futures::executor::block_on; +use futures::future::{poll_fn, FutureExt}; +use futures::task::{Context, Poll}; +use futures_test::task::panic_waker_ref; +use std::sync::mpsc; +use std::thread; + +#[test] +fn smoke_poll() { + let (mut tx, rx) = oneshot::channel::(); + let mut rx = Some(rx); + let f = poll_fn(|cx| { + assert!(tx.poll_canceled(cx).is_pending()); + assert!(tx.poll_canceled(cx).is_pending()); + drop(rx.take()); + assert!(tx.poll_canceled(cx).is_ready()); + assert!(tx.poll_canceled(cx).is_ready()); + Poll::Ready(()) + }); + + block_on(f); +} + +#[test] +fn cancel_notifies() { + let (mut tx, rx) = oneshot::channel::(); + + let t = thread::spawn(move || { + block_on(tx.cancellation()); + }); + drop(rx); + t.join().unwrap(); +} + +#[test] +fn cancel_lots() { + const N: usize = if cfg!(miri) { 100 } else { 20000 }; + + let (tx, rx) = mpsc::channel::<(Sender<_>, mpsc::Sender<_>)>(); + let t = thread::spawn(move || { + for (mut tx, tx2) in rx { + block_on(tx.cancellation()); + tx2.send(()).unwrap(); + } + }); + + for _ in 0..N { + let (otx, orx) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + tx.send((otx, tx2)).unwrap(); + drop(orx); + rx2.recv().unwrap(); + } + drop(tx); + + t.join().unwrap(); +} + +#[test] +fn cancel_after_sender_drop_doesnt_notify() { + let (mut tx, rx) = oneshot::channel::(); + let mut cx = Context::from_waker(panic_waker_ref()); + assert_eq!(tx.poll_canceled(&mut cx), Poll::Pending); + drop(tx); + drop(rx); +} + +#[test] +fn close() { + let (mut tx, mut rx) = oneshot::channel::(); + rx.close(); + block_on(poll_fn(|cx| { + match rx.poll_unpin(cx) { + Poll::Ready(Err(_)) => {} + _ => panic!(), + }; + assert!(tx.poll_canceled(cx).is_ready()); + Poll::Ready(()) + })); +} + +#[test] +fn close_wakes() { + let (mut tx, mut rx) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + let t = thread::spawn(move || { + rx.close(); + rx2.recv().unwrap(); + }); + block_on(tx.cancellation()); + tx2.send(()).unwrap(); + t.join().unwrap(); +} + +#[test] +fn is_canceled() { + let (tx, rx) = oneshot::channel::(); + assert!(!tx.is_canceled()); + drop(rx); + assert!(tx.is_canceled()); +} + +#[test] +fn cancel_sends() { + const N: usize = if cfg!(miri) { 100 } else { 20000 }; + + let (tx, rx) = mpsc::channel::>(); + let t = thread::spawn(move || { + for otx in rx { + let _ = otx.send(42); + } + }); + + for _ in 0..N { + let (otx, mut orx) = oneshot::channel::(); + tx.send(otx).unwrap(); + + orx.close(); + let _ = block_on(orx); + } + + drop(tx); + t.join().unwrap(); +} + +// #[test] +// fn spawn_sends_items() { +// let core = local_executor::Core::new(); +// let future = ok::<_, ()>(1); +// let rx = spawn(future, &core); +// assert_eq!(core.run(rx).unwrap(), 1); +// } +// +// #[test] +// fn spawn_kill_dead_stream() { +// use std::thread; +// use std::time::Duration; +// use futures::future::Either; +// use futures::sync::oneshot; +// +// // a future which never returns anything (forever accepting incoming +// // connections), but dropping it leads to observable side effects +// // (like closing listening sockets, releasing limited resources, +// // ...) +// #[derive(Debug)] +// struct Dead { +// // when dropped you should get Err(oneshot::Canceled) on the +// // receiving end +// done: oneshot::Sender<()>, +// } +// impl Future for Dead { +// type Item = (); +// type Error = (); +// +// fn poll(&mut self) -> Poll { +// Ok(Poll::Pending) +// } +// } +// +// // need to implement a timeout for the test, as it would hang +// // forever right now +// let (timeout_tx, timeout_rx) = oneshot::channel(); +// thread::spawn(move || { +// thread::sleep(Duration::from_millis(1000)); +// let _ = timeout_tx.send(()); +// }); +// +// let core = local_executor::Core::new(); +// let (done_tx, done_rx) = oneshot::channel(); +// let future = Dead{done: done_tx}; +// let rx = spawn(future, &core); +// let res = core.run( +// Ok::<_, ()>(()) +// .into_future() +// .then(move |_| { +// // now drop the spawned future: maybe some timeout exceeded, +// // or some connection on this end was closed by the remote +// // end. +// drop(rx); +// // and wait for the spawned future to release its resources +// done_rx +// }) +// .select2(timeout_rx) +// ); +// match res { +// Err(Either::A((oneshot::Canceled, _))) => (), +// Ok(Either::B(((), _))) => { +// panic!("dead future wasn't canceled (timeout)"); +// }, +// _ => { +// panic!("dead future wasn't canceled (unexpected result)"); +// }, +// } +// } +// +// #[test] +// fn spawn_dont_kill_forgot_dead_stream() { +// use std::thread; +// use std::time::Duration; +// use futures::future::Either; +// use futures::sync::oneshot; +// +// // a future which never returns anything (forever accepting incoming +// // connections), but dropping it leads to observable side effects +// // (like closing listening sockets, releasing limited resources, +// // ...) +// #[derive(Debug)] +// struct Dead { +// // when dropped you should get Err(oneshot::Canceled) on the +// // receiving end +// done: oneshot::Sender<()>, +// } +// impl Future for Dead { +// type Item = (); +// type Error = (); +// +// fn poll(&mut self) -> Poll { +// Ok(Poll::Pending) +// } +// } +// +// // need to implement a timeout for the test, as it would hang +// // forever right now +// let (timeout_tx, timeout_rx) = oneshot::channel(); +// thread::spawn(move || { +// thread::sleep(Duration::from_millis(1000)); +// let _ = timeout_tx.send(()); +// }); +// +// let core = local_executor::Core::new(); +// let (done_tx, done_rx) = oneshot::channel(); +// let future = Dead{done: done_tx}; +// let rx = spawn(future, &core); +// let res = core.run( +// Ok::<_, ()>(()) +// .into_future() +// .then(move |_| { +// // forget the spawned future: should keep running, i.e. hit +// // the timeout below. +// rx.forget(); +// // and wait for the spawned future to release its resources +// done_rx +// }) +// .select2(timeout_rx) +// ); +// match res { +// Err(Either::A((oneshot::Canceled, _))) => { +// panic!("forgotten dead future was canceled"); +// }, +// Ok(Either::B(((), _))) => (), // reached timeout +// _ => { +// panic!("forgotten dead future was canceled (unexpected result)"); +// }, +// } +// } diff --git a/utshell-0.5.0/vendor/futures-core/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-core/.cargo-checksum.json new file mode 100644 index 00000000..b43772f8 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"21a7215adbf49919270abecb9deb8d81a32383f4d2163d82869139cbffe6648e","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"e8258273fed6f1796485777655118f2369fd3f000191e9d8cdbd10bf052946a9","src/future.rs":"0cb559fad0d43566dab959e929c4631c25cf749e2e29a5444fbcad464c9262ae","src/lib.rs":"eacd5816fbb914ca061d49ff6203723ebbe639eb7c45ebfa8a0613069d174111","src/stream.rs":"f1c7ab84161c5d5b424655b257fc3183eb6f2ed5324ba4006a70f9a4b0dc8872","src/task/__internal/atomic_waker.rs":"e5184bcc772c1472a2f0f9899bd3e388b74b771d327d801a5ea7e4aca6e57715","src/task/__internal/mod.rs":"1cc15fd61942a29ea558c5f4d5782e46adcfd914cab82be084a6882fa9afc122","src/task/mod.rs":"e213602a2fe5ae78ad5f1ca20e6d32dcbab17aba5b6b072fb927a72da99b4a11","src/task/poll.rs":"74c2717c1f9a37587a367da1b690d1cd2312e95dbaffca42be4755f1cd164bb8"},"package":"dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-core/Cargo.toml b/utshell-0.5.0/vendor/futures-core/Cargo.toml new file mode 100644 index 00000000..a97c11a5 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/Cargo.toml @@ -0,0 +1,45 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.36" +name = "futures-core" +version = "0.3.30" +description = """ +The core traits and types in for the `futures` library. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[dependencies.portable-atomic] +version = "1.3" +features = ["require-cas"] +optional = true +default-features = false + +[dev-dependencies] + +[features] +alloc = [] +cfg-target-has-atomic = [] +default = ["std"] +std = ["alloc"] +unstable = [] diff --git a/utshell-0.5.0/vendor/futures-core/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-core/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-core/LICENSE-MIT b/utshell-0.5.0/vendor/futures-core/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-core/README.md b/utshell-0.5.0/vendor/futures-core/README.md new file mode 100644 index 00000000..96e0e064 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/README.md @@ -0,0 +1,23 @@ +# futures-core + +The core traits and types in for the `futures` library. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-core = "0.3" +``` + +The current `futures-core` requires Rust 1.36 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-core/src/future.rs b/utshell-0.5.0/vendor/futures-core/src/future.rs new file mode 100644 index 00000000..7540cd02 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/future.rs @@ -0,0 +1,103 @@ +//! Futures. + +use core::ops::DerefMut; +use core::pin::Pin; +use core::task::{Context, Poll}; + +#[doc(no_inline)] +pub use core::future::Future; + +/// An owned dynamically typed [`Future`] for use in cases where you can't +/// statically type your result or need to add some indirection. +#[cfg(feature = "alloc")] +pub type BoxFuture<'a, T> = Pin + Send + 'a>>; + +/// `BoxFuture`, but without the `Send` requirement. +#[cfg(feature = "alloc")] +pub type LocalBoxFuture<'a, T> = Pin + 'a>>; + +/// A future which tracks whether or not the underlying future +/// should no longer be polled. +/// +/// `is_terminated` will return `true` if a future should no longer be polled. +/// Usually, this state occurs after `poll` (or `try_poll`) returned +/// `Poll::Ready`. However, `is_terminated` may also return `true` if a future +/// has become inactive and can no longer make progress and should be ignored +/// or dropped rather than being `poll`ed again. +pub trait FusedFuture: Future { + /// Returns `true` if the underlying future should no longer be polled. + fn is_terminated(&self) -> bool; +} + +impl FusedFuture for &mut F { + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } +} + +impl

FusedFuture for Pin

+where + P: DerefMut + Unpin, + P::Target: FusedFuture, +{ + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } +} + +mod private_try_future { + use super::Future; + + pub trait Sealed {} + + impl Sealed for F where F: ?Sized + Future> {} +} + +/// A convenience for futures that return `Result` values that includes +/// a variety of adapters tailored to such futures. +pub trait TryFuture: Future + private_try_future::Sealed { + /// The type of successful values yielded by this future + type Ok; + + /// The type of failures yielded by this future + type Error; + + /// Poll this `TryFuture` as if it were a `Future`. + /// + /// This method is a stopgap for a compiler limitation that prevents us from + /// directly inheriting from the `Future` trait; in the future it won't be + /// needed. + fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; +} + +impl TryFuture for F +where + F: ?Sized + Future>, +{ + type Ok = T; + type Error = E; + + #[inline] + fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.poll(cx) + } +} + +#[cfg(feature = "alloc")] +mod if_alloc { + use super::*; + use alloc::boxed::Box; + + impl FusedFuture for Box { + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } + } + + #[cfg(feature = "std")] + impl FusedFuture for std::panic::AssertUnwindSafe { + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-core/src/lib.rs b/utshell-0.5.0/vendor/futures-core/src/lib.rs new file mode 100644 index 00000000..9c31d8d9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/lib.rs @@ -0,0 +1,27 @@ +//! Core traits and types for asynchronous operations in Rust. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)] +// It cannot be included in the published code because this lints have false positives in the minimum required version. +#![cfg_attr(test, warn(single_use_lifetimes))] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] + +#[cfg(feature = "alloc")] +extern crate alloc; + +pub mod future; +#[doc(no_inline)] +pub use self::future::{FusedFuture, Future, TryFuture}; + +pub mod stream; +#[doc(no_inline)] +pub use self::stream::{FusedStream, Stream, TryStream}; + +#[macro_use] +pub mod task; diff --git a/utshell-0.5.0/vendor/futures-core/src/stream.rs b/utshell-0.5.0/vendor/futures-core/src/stream.rs new file mode 100644 index 00000000..ad5350b7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/stream.rs @@ -0,0 +1,235 @@ +//! Asynchronous streams. + +use core::ops::DerefMut; +use core::pin::Pin; +use core::task::{Context, Poll}; + +/// An owned dynamically typed [`Stream`] for use in cases where you can't +/// statically type your result or need to add some indirection. +#[cfg(feature = "alloc")] +pub type BoxStream<'a, T> = Pin + Send + 'a>>; + +/// `BoxStream`, but without the `Send` requirement. +#[cfg(feature = "alloc")] +pub type LocalBoxStream<'a, T> = Pin + 'a>>; + +/// A stream of values produced asynchronously. +/// +/// If `Future` is an asynchronous version of `T`, then `Stream` is an asynchronous version of `Iterator`. A stream +/// represents a sequence of value-producing events that occur asynchronously to +/// the caller. +/// +/// The trait is modeled after `Future`, but allows `poll_next` to be called +/// even after a value has been produced, yielding `None` once the stream has +/// been fully exhausted. +#[must_use = "streams do nothing unless polled"] +pub trait Stream { + /// Values yielded by the stream. + type Item; + + /// Attempt to pull out the next value of this stream, registering the + /// current task for wakeup if the value is not yet available, and returning + /// `None` if the stream is exhausted. + /// + /// # Return value + /// + /// There are several possible return values, each indicating a distinct + /// stream state: + /// + /// - `Poll::Pending` means that this stream's next value is not ready + /// yet. Implementations will ensure that the current task will be notified + /// when the next value may be ready. + /// + /// - `Poll::Ready(Some(val))` means that the stream has successfully + /// produced a value, `val`, and may produce further values on subsequent + /// `poll_next` calls. + /// + /// - `Poll::Ready(None)` means that the stream has terminated, and + /// `poll_next` should not be invoked again. + /// + /// # Panics + /// + /// Once a stream has finished (returned `Ready(None)` from `poll_next`), calling its + /// `poll_next` method again may panic, block forever, or cause other kinds of + /// problems; the `Stream` trait places no requirements on the effects of + /// such a call. However, as the `poll_next` method is not marked `unsafe`, + /// Rust's usual rules apply: calls must never cause undefined behavior + /// (memory corruption, incorrect use of `unsafe` functions, or the like), + /// regardless of the stream's state. + /// + /// If this is difficult to guard against then the [`fuse`] adapter can be used + /// to ensure that `poll_next` always returns `Ready(None)` in subsequent + /// calls. + /// + /// [`fuse`]: https://docs.rs/futures/0.3/futures/stream/trait.StreamExt.html#method.fuse + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + + /// Returns the bounds on the remaining length of the stream. + /// + /// Specifically, `size_hint()` returns a tuple where the first element + /// is the lower bound, and the second element is the upper bound. + /// + /// The second half of the tuple that is returned is an [`Option`]`<`[`usize`]`>`. + /// A [`None`] here means that either there is no known upper bound, or the + /// upper bound is larger than [`usize`]. + /// + /// # Implementation notes + /// + /// It is not enforced that a stream implementation yields the declared + /// number of elements. A buggy stream may yield less than the lower bound + /// or more than the upper bound of elements. + /// + /// `size_hint()` is primarily intended to be used for optimizations such as + /// reserving space for the elements of the stream, but must not be + /// trusted to e.g., omit bounds checks in unsafe code. An incorrect + /// implementation of `size_hint()` should not lead to memory safety + /// violations. + /// + /// That said, the implementation should provide a correct estimation, + /// because otherwise it would be a violation of the trait's protocol. + /// + /// The default implementation returns `(0, `[`None`]`)` which is correct for any + /// stream. + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, None) + } +} + +impl Stream for &mut S { + type Item = S::Item; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + S::poll_next(Pin::new(&mut **self), cx) + } + + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + +impl

Stream for Pin

+where + P: DerefMut + Unpin, + P::Target: Stream, +{ + type Item = ::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + +/// A stream which tracks whether or not the underlying stream +/// should no longer be polled. +/// +/// `is_terminated` will return `true` if a future should no longer be polled. +/// Usually, this state occurs after `poll_next` (or `try_poll_next`) returned +/// `Poll::Ready(None)`. However, `is_terminated` may also return `true` if a +/// stream has become inactive and can no longer make progress and should be +/// ignored or dropped rather than being polled again. +pub trait FusedStream: Stream { + /// Returns `true` if the stream should no longer be polled. + fn is_terminated(&self) -> bool; +} + +impl FusedStream for &mut F { + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } +} + +impl

FusedStream for Pin

+where + P: DerefMut + Unpin, + P::Target: FusedStream, +{ + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } +} + +mod private_try_stream { + use super::Stream; + + pub trait Sealed {} + + impl Sealed for S where S: ?Sized + Stream> {} +} + +/// A convenience for streams that return `Result` values that includes +/// a variety of adapters tailored to such futures. +pub trait TryStream: Stream + private_try_stream::Sealed { + /// The type of successful values yielded by this future + type Ok; + + /// The type of failures yielded by this future + type Error; + + /// Poll this `TryStream` as if it were a `Stream`. + /// + /// This method is a stopgap for a compiler limitation that prevents us from + /// directly inheriting from the `Stream` trait; in the future it won't be + /// needed. + fn try_poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>>; +} + +impl TryStream for S +where + S: ?Sized + Stream>, +{ + type Ok = T; + type Error = E; + + fn try_poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + self.poll_next(cx) + } +} + +#[cfg(feature = "alloc")] +mod if_alloc { + use super::*; + use alloc::boxed::Box; + + impl Stream for Box { + type Item = S::Item; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self).poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } + } + + #[cfg(feature = "std")] + impl Stream for std::panic::AssertUnwindSafe { + type Item = S::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + unsafe { self.map_unchecked_mut(|x| &mut x.0) }.poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + } + + impl FusedStream for Box { + fn is_terminated(&self) -> bool { + ::is_terminated(&**self) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-core/src/task/__internal/atomic_waker.rs b/utshell-0.5.0/vendor/futures-core/src/task/__internal/atomic_waker.rs new file mode 100644 index 00000000..2fc594b8 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/task/__internal/atomic_waker.rs @@ -0,0 +1,421 @@ +use core::cell::UnsafeCell; +use core::fmt; +use core::task::Waker; + +use atomic::AtomicUsize; +use atomic::Ordering::{AcqRel, Acquire, Release}; + +#[cfg(feature = "portable-atomic")] +use portable_atomic as atomic; + +#[cfg(not(feature = "portable-atomic"))] +use core::sync::atomic; + +/// A synchronization primitive for task wakeup. +/// +/// Sometimes the task interested in a given event will change over time. +/// An `AtomicWaker` can coordinate concurrent notifications with the consumer +/// potentially "updating" the underlying task to wake up. This is useful in +/// scenarios where a computation completes in another thread and wants to +/// notify the consumer, but the consumer is in the process of being migrated to +/// a new logical task. +/// +/// Consumers should call `register` before checking the result of a computation +/// and producers should call `wake` after producing the computation (this +/// differs from the usual `thread::park` pattern). It is also permitted for +/// `wake` to be called **before** `register`. This results in a no-op. +/// +/// A single `AtomicWaker` may be reused for any number of calls to `register` or +/// `wake`. +/// +/// # Memory ordering +/// +/// Calling `register` "acquires" all memory "released" by calls to `wake` +/// before the call to `register`. Later calls to `wake` will wake the +/// registered waker (on contention this wake might be triggered in `register`). +/// +/// For concurrent calls to `register` (should be avoided) the ordering is only +/// guaranteed for the winning call. +/// +/// # Examples +/// +/// Here is a simple example providing a `Flag` that can be signalled manually +/// when it is ready. +/// +/// ``` +/// use futures::future::Future; +/// use futures::task::{Context, Poll, AtomicWaker}; +/// use std::sync::Arc; +/// use std::sync::atomic::AtomicBool; +/// use std::sync::atomic::Ordering::Relaxed; +/// use std::pin::Pin; +/// +/// struct Inner { +/// waker: AtomicWaker, +/// set: AtomicBool, +/// } +/// +/// #[derive(Clone)] +/// struct Flag(Arc); +/// +/// impl Flag { +/// pub fn new() -> Self { +/// Self(Arc::new(Inner { +/// waker: AtomicWaker::new(), +/// set: AtomicBool::new(false), +/// })) +/// } +/// +/// pub fn signal(&self) { +/// self.0.set.store(true, Relaxed); +/// self.0.waker.wake(); +/// } +/// } +/// +/// impl Future for Flag { +/// type Output = (); +/// +/// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { +/// // quick check to avoid registration if already done. +/// if self.0.set.load(Relaxed) { +/// return Poll::Ready(()); +/// } +/// +/// self.0.waker.register(cx.waker()); +/// +/// // Need to check condition **after** `register` to avoid a race +/// // condition that would result in lost notifications. +/// if self.0.set.load(Relaxed) { +/// Poll::Ready(()) +/// } else { +/// Poll::Pending +/// } +/// } +/// } +/// ``` +pub struct AtomicWaker { + state: AtomicUsize, + waker: UnsafeCell>, +} + +// `AtomicWaker` is a multi-consumer, single-producer transfer cell. The cell +// stores a `Waker` value produced by calls to `register` and many threads can +// race to take the waker (to wake it) by calling `wake`. +// +// If a new `Waker` instance is produced by calling `register` before an +// existing one is consumed, then the existing one is overwritten. +// +// While `AtomicWaker` is single-producer, the implementation ensures memory +// safety. In the event of concurrent calls to `register`, there will be a +// single winner whose waker will get stored in the cell. The losers will not +// have their tasks woken. As such, callers should ensure to add synchronization +// to calls to `register`. +// +// The implementation uses a single `AtomicUsize` value to coordinate access to +// the `Waker` cell. There are two bits that are operated on independently. +// These are represented by `REGISTERING` and `WAKING`. +// +// The `REGISTERING` bit is set when a producer enters the critical section. The +// `WAKING` bit is set when a consumer enters the critical section. Neither bit +// being set is represented by `WAITING`. +// +// A thread obtains an exclusive lock on the waker cell by transitioning the +// state from `WAITING` to `REGISTERING` or `WAKING`, depending on the operation +// the thread wishes to perform. When this transition is made, it is guaranteed +// that no other thread will access the waker cell. +// +// # Registering +// +// On a call to `register`, an attempt to transition the state from WAITING to +// REGISTERING is made. On success, the caller obtains a lock on the waker cell. +// +// If the lock is obtained, then the thread sets the waker cell to the waker +// provided as an argument. Then it attempts to transition the state back from +// `REGISTERING` -> `WAITING`. +// +// If this transition is successful, then the registering process is complete +// and the next call to `wake` will observe the waker. +// +// If the transition fails, then there was a concurrent call to `wake` that was +// unable to access the waker cell (due to the registering thread holding the +// lock). To handle this, the registering thread removes the waker it just set +// from the cell and calls `wake` on it. This call to wake represents the +// attempt to wake by the other thread (that set the `WAKING` bit). The state is +// then transitioned from `REGISTERING | WAKING` back to `WAITING`. This +// transition must succeed because, at this point, the state cannot be +// transitioned by another thread. +// +// # Waking +// +// On a call to `wake`, an attempt to transition the state from `WAITING` to +// `WAKING` is made. On success, the caller obtains a lock on the waker cell. +// +// If the lock is obtained, then the thread takes ownership of the current value +// in the waker cell, and calls `wake` on it. The state is then transitioned +// back to `WAITING`. This transition must succeed as, at this point, the state +// cannot be transitioned by another thread. +// +// If the thread is unable to obtain the lock, the `WAKING` bit is still. This +// is because it has either been set by the current thread but the previous +// value included the `REGISTERING` bit **or** a concurrent thread is in the +// `WAKING` critical section. Either way, no action must be taken. +// +// If the current thread is the only concurrent call to `wake` and another +// thread is in the `register` critical section, when the other thread **exits** +// the `register` critical section, it will observe the `WAKING` bit and handle +// the wake itself. +// +// If another thread is in the `wake` critical section, then it will handle +// waking the task. +// +// # A potential race (is safely handled). +// +// Imagine the following situation: +// +// * Thread A obtains the `wake` lock and wakes a task. +// +// * Before thread A releases the `wake` lock, the woken task is scheduled. +// +// * Thread B attempts to wake the task. In theory this should result in the +// task being woken, but it cannot because thread A still holds the wake lock. +// +// This case is handled by requiring users of `AtomicWaker` to call `register` +// **before** attempting to observe the application state change that resulted +// in the task being awoken. The wakers also change the application state before +// calling wake. +// +// Because of this, the waker will do one of two things. +// +// 1) Observe the application state change that Thread B is woken for. In this +// case, it is OK for Thread B's wake to be lost. +// +// 2) Call register before attempting to observe the application state. Since +// Thread A still holds the `wake` lock, the call to `register` will result +// in the task waking itself and get scheduled again. + +/// Idle state +const WAITING: usize = 0; + +/// A new waker value is being registered with the `AtomicWaker` cell. +const REGISTERING: usize = 0b01; + +/// The waker currently registered with the `AtomicWaker` cell is being woken. +const WAKING: usize = 0b10; + +impl AtomicWaker { + /// Create an `AtomicWaker`. + pub const fn new() -> Self { + // Make sure that task is Sync + trait AssertSync: Sync {} + impl AssertSync for Waker {} + + Self { state: AtomicUsize::new(WAITING), waker: UnsafeCell::new(None) } + } + + /// Registers the waker to be notified on calls to `wake`. + /// + /// The new task will take place of any previous tasks that were registered + /// by previous calls to `register`. Any calls to `wake` that happen after + /// a call to `register` (as defined by the memory ordering rules), will + /// notify the `register` caller's task and deregister the waker from future + /// notifications. Because of this, callers should ensure `register` gets + /// invoked with a new `Waker` **each** time they require a wakeup. + /// + /// It is safe to call `register` with multiple other threads concurrently + /// calling `wake`. This will result in the `register` caller's current + /// task being notified once. + /// + /// This function is safe to call concurrently, but this is generally a bad + /// idea. Concurrent calls to `register` will attempt to register different + /// tasks to be notified. One of the callers will win and have its task set, + /// but there is no guarantee as to which caller will succeed. + /// + /// # Examples + /// + /// Here is how `register` is used when implementing a flag. + /// + /// ``` + /// use futures::future::Future; + /// use futures::task::{Context, Poll, AtomicWaker}; + /// use std::sync::atomic::AtomicBool; + /// use std::sync::atomic::Ordering::Relaxed; + /// use std::pin::Pin; + /// + /// struct Flag { + /// waker: AtomicWaker, + /// set: AtomicBool, + /// } + /// + /// impl Future for Flag { + /// type Output = (); + /// + /// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + /// // Register **before** checking `set` to avoid a race condition + /// // that would result in lost notifications. + /// self.waker.register(cx.waker()); + /// + /// if self.set.load(Relaxed) { + /// Poll::Ready(()) + /// } else { + /// Poll::Pending + /// } + /// } + /// } + /// ``` + pub fn register(&self, waker: &Waker) { + match self + .state + .compare_exchange(WAITING, REGISTERING, Acquire, Acquire) + .unwrap_or_else(|x| x) + { + WAITING => { + unsafe { + // Locked acquired, update the waker cell + + // Avoid cloning the waker if the old waker will awaken the same task. + match &*self.waker.get() { + Some(old_waker) if old_waker.will_wake(waker) => (), + _ => *self.waker.get() = Some(waker.clone()), + } + + // Release the lock. If the state transitioned to include + // the `WAKING` bit, this means that at least one wake has + // been called concurrently. + // + // Start by assuming that the state is `REGISTERING` as this + // is what we just set it to. If this holds, we know that no + // other writes were performed in the meantime, so there is + // nothing to acquire, only release. In case of concurrent + // wakers, we need to acquire their releases, so success needs + // to do both. + let res = self.state.compare_exchange(REGISTERING, WAITING, AcqRel, Acquire); + + match res { + Ok(_) => { + // memory ordering: acquired self.state during CAS + // - if previous wakes went through it syncs with + // their final release (`fetch_and`) + // - if there was no previous wake the next wake + // will wake us, no sync needed. + } + Err(actual) => { + // This branch can only be reached if at least one + // concurrent thread called `wake`. In this + // case, `actual` **must** be `REGISTERING | + // `WAKING`. + debug_assert_eq!(actual, REGISTERING | WAKING); + + // Take the waker to wake once the atomic operation has + // completed. + let waker = (*self.waker.get()).take().unwrap(); + + // We need to return to WAITING state (clear our lock and + // concurrent WAKING flag). This needs to acquire all + // WAKING fetch_or releases and it needs to release our + // update to self.waker, so we need a `swap` operation. + self.state.swap(WAITING, AcqRel); + + // memory ordering: we acquired the state for all + // concurrent wakes, but future wakes might still + // need to wake us in case we can't make progress + // from the pending wakes. + // + // So we simply schedule to come back later (we could + // also simply leave the registration in place above). + waker.wake(); + } + } + } + } + WAKING => { + // Currently in the process of waking the task, i.e., + // `wake` is currently being called on the old task handle. + // + // memory ordering: we acquired the state for all + // concurrent wakes, but future wakes might still + // need to wake us in case we can't make progress + // from the pending wakes. + // + // So we simply schedule to come back later (we + // could also spin here trying to acquire the lock + // to register). + waker.wake_by_ref(); + } + state => { + // In this case, a concurrent thread is holding the + // "registering" lock. This probably indicates a bug in the + // caller's code as racing to call `register` doesn't make much + // sense. + // + // memory ordering: don't care. a concurrent register() is going + // to succeed and provide proper memory ordering. + // + // We just want to maintain memory safety. It is ok to drop the + // call to `register`. + debug_assert!(state == REGISTERING || state == REGISTERING | WAKING); + } + } + } + + /// Calls `wake` on the last `Waker` passed to `register`. + /// + /// If `register` has not been called yet, then this does nothing. + pub fn wake(&self) { + if let Some(waker) = self.take() { + waker.wake(); + } + } + + /// Returns the last `Waker` passed to `register`, so that the user can wake it. + /// + /// + /// Sometimes, just waking the AtomicWaker is not fine grained enough. This allows the user + /// to take the waker and then wake it separately, rather than performing both steps in one + /// atomic action. + /// + /// If a waker has not been registered, this returns `None`. + pub fn take(&self) -> Option { + // AcqRel ordering is used in order to acquire the value of the `task` + // cell as well as to establish a `release` ordering with whatever + // memory the `AtomicWaker` is associated with. + match self.state.fetch_or(WAKING, AcqRel) { + WAITING => { + // The waking lock has been acquired. + let waker = unsafe { (*self.waker.get()).take() }; + + // Release the lock + self.state.fetch_and(!WAKING, Release); + + waker + } + state => { + // There is a concurrent thread currently updating the + // associated task. + // + // Nothing more to do as the `WAKING` bit has been set. It + // doesn't matter if there are concurrent registering threads or + // not. + // + debug_assert!( + state == REGISTERING || state == REGISTERING | WAKING || state == WAKING + ); + None + } + } + } +} + +impl Default for AtomicWaker { + fn default() -> Self { + Self::new() + } +} + +impl fmt::Debug for AtomicWaker { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "AtomicWaker") + } +} + +unsafe impl Send for AtomicWaker {} +unsafe impl Sync for AtomicWaker {} diff --git a/utshell-0.5.0/vendor/futures-core/src/task/__internal/mod.rs b/utshell-0.5.0/vendor/futures-core/src/task/__internal/mod.rs new file mode 100644 index 00000000..c2487422 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/task/__internal/mod.rs @@ -0,0 +1,7 @@ +#[cfg_attr(target_os = "none", cfg(any(target_has_atomic = "ptr", feature = "portable-atomic")))] +mod atomic_waker; +#[cfg_attr( + target_os = "none", + cfg(any(target_has_atomic = "ptr", feature = "portable-atomic")) +)] +pub use self::atomic_waker::AtomicWaker; diff --git a/utshell-0.5.0/vendor/futures-core/src/task/mod.rs b/utshell-0.5.0/vendor/futures-core/src/task/mod.rs new file mode 100644 index 00000000..19e4eaec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/task/mod.rs @@ -0,0 +1,10 @@ +//! Task notification. + +#[macro_use] +mod poll; + +#[doc(hidden)] +pub mod __internal; + +#[doc(no_inline)] +pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; diff --git a/utshell-0.5.0/vendor/futures-core/src/task/poll.rs b/utshell-0.5.0/vendor/futures-core/src/task/poll.rs new file mode 100644 index 00000000..607e78e0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-core/src/task/poll.rs @@ -0,0 +1,12 @@ +/// Extracts the successful type of a `Poll`. +/// +/// This macro bakes in propagation of `Pending` signals by returning early. +#[macro_export] +macro_rules! ready { + ($e:expr $(,)?) => { + match $e { + $crate::task::Poll::Ready(t) => t, + $crate::task::Poll::Pending => return $crate::task::Poll::Pending, + } + }; +} diff --git a/utshell-0.5.0/vendor/futures-executor/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-executor/.cargo-checksum.json new file mode 100644 index 00000000..58426bb1 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"e4d8d4332a374f631c050d2c0315f0c90f8b1bc32bde8e5ec94671428f3e6ecd","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"05ba6a5490962c4df45b78e9ad928a29dd5c3fad749284d5b812ca7e765feb6d","benches/thread_notify.rs":"e601968527bee85766f32d2d11de5ed8f6b4bd5a29989b5c369a52bd3cd3d024","src/enter.rs":"e3e890a8fa649e76cd2ce915abb11b67d15f3c5ae5e8e374142e0363917b2406","src/lib.rs":"08a25594c789cb4ce1c8929a9ddd745e67fee1db373e011a7ebe135933522614","src/local_pool.rs":"78177af55564fdfcfdc9f3974afe7d9d0682a7e4654761d83a8fc02abb34a7dc","src/thread_pool.rs":"e52f8527bc37c511513d77d183b44e3991a7b324aaed5d17bee0d092cf448a5b","src/unpark_mutex.rs":"e186464d9bdec22a6d1e1d900ed03a1154e6b0d422ede9bd3b768657cdbb6113","tests/local_pool.rs":"9639c9a290e23faab3913c6fec190853f890defaed6ffe67de177eca5d88932a"},"package":"a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-executor/Cargo.toml b/utshell-0.5.0/vendor/futures-executor/Cargo.toml new file mode 100644 index 00000000..1f5472d0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/Cargo.toml @@ -0,0 +1,60 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "futures-executor" +version = "0.3.30" +description = """ +Executors for asynchronous tasks based on the futures-rs library. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[dependencies.futures-core] +version = "0.3.30" +default-features = false + +[dependencies.futures-task] +version = "0.3.30" +default-features = false + +[dependencies.futures-util] +version = "0.3.30" +default-features = false + +[dependencies.num_cpus] +version = "1.8.0" +optional = true + +[dev-dependencies] + +[features] +default = ["std"] +std = [ + "futures-core/std", + "futures-task/std", + "futures-util/std", +] +thread-pool = [ + "std", + "num_cpus", +] diff --git a/utshell-0.5.0/vendor/futures-executor/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-executor/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-executor/LICENSE-MIT b/utshell-0.5.0/vendor/futures-executor/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-executor/README.md b/utshell-0.5.0/vendor/futures-executor/README.md new file mode 100644 index 00000000..724ff5bb --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/README.md @@ -0,0 +1,23 @@ +# futures-executor + +Executors for asynchronous tasks based on the futures-rs library. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-executor = "0.3" +``` + +The current `futures-executor` requires Rust 1.56 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-executor/benches/thread_notify.rs b/utshell-0.5.0/vendor/futures-executor/benches/thread_notify.rs new file mode 100644 index 00000000..88d0447c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/benches/thread_notify.rs @@ -0,0 +1,109 @@ +#![feature(test)] + +extern crate test; +use crate::test::Bencher; + +use futures::executor::block_on; +use futures::future::Future; +use futures::task::{Context, Poll, Waker}; +use std::pin::Pin; + +#[bench] +fn thread_yield_single_thread_one_wait(b: &mut Bencher) { + const NUM: usize = 10_000; + + struct Yield { + rem: usize, + } + + impl Future for Yield { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if self.rem == 0 { + Poll::Ready(()) + } else { + self.rem -= 1; + cx.waker().wake_by_ref(); + Poll::Pending + } + } + } + + b.iter(|| { + let y = Yield { rem: NUM }; + block_on(y); + }); +} + +#[bench] +fn thread_yield_single_thread_many_wait(b: &mut Bencher) { + const NUM: usize = 10_000; + + struct Yield { + rem: usize, + } + + impl Future for Yield { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if self.rem == 0 { + Poll::Ready(()) + } else { + self.rem -= 1; + cx.waker().wake_by_ref(); + Poll::Pending + } + } + } + + b.iter(|| { + for _ in 0..NUM { + let y = Yield { rem: 1 }; + block_on(y); + } + }); +} + +#[bench] +fn thread_yield_multi_thread(b: &mut Bencher) { + use std::sync::mpsc; + use std::thread; + + const NUM: usize = 1_000; + + let (tx, rx) = mpsc::sync_channel::(10_000); + + struct Yield { + rem: usize, + tx: mpsc::SyncSender, + } + impl Unpin for Yield {} + + impl Future for Yield { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if self.rem == 0 { + Poll::Ready(()) + } else { + self.rem -= 1; + self.tx.send(cx.waker().clone()).unwrap(); + Poll::Pending + } + } + } + + thread::spawn(move || { + while let Ok(task) = rx.recv() { + task.wake(); + } + }); + + b.iter(move || { + let y = Yield { rem: NUM, tx: tx.clone() }; + + block_on(y); + }); +} diff --git a/utshell-0.5.0/vendor/futures-executor/src/enter.rs b/utshell-0.5.0/vendor/futures-executor/src/enter.rs new file mode 100644 index 00000000..cb58c30b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/src/enter.rs @@ -0,0 +1,80 @@ +use std::cell::Cell; +use std::fmt; + +thread_local!(static ENTERED: Cell = Cell::new(false)); + +/// Represents an executor context. +/// +/// For more details, see [`enter` documentation](enter()). +pub struct Enter { + _priv: (), +} + +/// An error returned by `enter` if an execution scope has already been +/// entered. +pub struct EnterError { + _priv: (), +} + +impl fmt::Debug for EnterError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("EnterError").finish() + } +} + +impl fmt::Display for EnterError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "an execution scope has already been entered") + } +} + +impl std::error::Error for EnterError {} + +/// Marks the current thread as being within the dynamic extent of an +/// executor. +/// +/// Executor implementations should call this function before beginning to +/// execute a task, and drop the returned [`Enter`](Enter) value after +/// completing task execution: +/// +/// ``` +/// use futures::executor::enter; +/// +/// let enter = enter().expect("..."); +/// /* run task */ +/// drop(enter); +/// ``` +/// +/// Doing so ensures that executors aren't +/// accidentally invoked in a nested fashion. +/// +/// # Error +/// +/// Returns an error if the current thread is already marked, in which case the +/// caller should panic with a tailored error message. +pub fn enter() -> Result { + ENTERED.with(|c| { + if c.get() { + Err(EnterError { _priv: () }) + } else { + c.set(true); + + Ok(Enter { _priv: () }) + } + }) +} + +impl fmt::Debug for Enter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Enter").finish() + } +} + +impl Drop for Enter { + fn drop(&mut self) { + ENTERED.with(|c| { + assert!(c.get()); + c.set(false); + }); + } +} diff --git a/utshell-0.5.0/vendor/futures-executor/src/lib.rs b/utshell-0.5.0/vendor/futures-executor/src/lib.rs new file mode 100644 index 00000000..b1af8754 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/src/lib.rs @@ -0,0 +1,76 @@ +//! Built-in executors and related tools. +//! +//! All asynchronous computation occurs within an executor, which is +//! capable of spawning futures as tasks. This module provides several +//! built-in executors, as well as tools for building your own. +//! +//! All items are only available when the `std` feature of this +//! library is activated, and it is activated by default. +//! +//! # Using a thread pool (M:N task scheduling) +//! +//! Most of the time tasks should be executed on a [thread pool](ThreadPool). +//! A small set of worker threads can handle a very large set of spawned tasks +//! (which are much lighter weight than threads). Tasks spawned onto the pool +//! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on +//! the created threads. +//! +//! # Spawning additional tasks +//! +//! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method +//! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used +//! instead. +//! +//! # Single-threaded execution +//! +//! In addition to thread pools, it's possible to run a task (and the tasks +//! it spawns) entirely within a single thread via the [`LocalPool`] executor. +//! Aside from cutting down on synchronization costs, this executor also makes +//! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The +//! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively +//! little work between I/O operations. +//! +//! There is also a convenience function [`block_on`] for simply running a +//! future to completion on the current thread. +//! +//! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj +//! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + single_use_lifetimes, + unreachable_pub +)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] +#![cfg_attr(docsrs, feature(doc_cfg))] + +#[cfg(feature = "std")] +mod local_pool; +#[cfg(feature = "std")] +pub use crate::local_pool::{block_on, block_on_stream, BlockingStream, LocalPool, LocalSpawner}; + +#[cfg(feature = "thread-pool")] +#[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] +#[cfg(feature = "std")] +mod thread_pool; +#[cfg(feature = "thread-pool")] +#[cfg(feature = "std")] +mod unpark_mutex; +#[cfg(feature = "thread-pool")] +#[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] +#[cfg(feature = "std")] +pub use crate::thread_pool::{ThreadPool, ThreadPoolBuilder}; + +#[cfg(feature = "std")] +mod enter; +#[cfg(feature = "std")] +pub use crate::enter::{enter, Enter, EnterError}; diff --git a/utshell-0.5.0/vendor/futures-executor/src/local_pool.rs b/utshell-0.5.0/vendor/futures-executor/src/local_pool.rs new file mode 100644 index 00000000..8a9bc2fc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/src/local_pool.rs @@ -0,0 +1,402 @@ +use crate::enter; +use futures_core::future::Future; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use futures_task::{waker_ref, ArcWake}; +use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError}; +use futures_util::pin_mut; +use futures_util::stream::FuturesUnordered; +use futures_util::stream::StreamExt; +use std::cell::RefCell; +use std::ops::{Deref, DerefMut}; +use std::rc::{Rc, Weak}; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; +use std::thread::{self, Thread}; + +/// A single-threaded task pool for polling futures to completion. +/// +/// This executor allows you to multiplex any number of tasks onto a single +/// thread. It's appropriate to poll strictly I/O-bound futures that do very +/// little work in between I/O actions. +/// +/// To get a handle to the pool that implements +/// [`Spawn`](futures_task::Spawn), use the +/// [`spawner()`](LocalPool::spawner) method. Because the executor is +/// single-threaded, it supports a special form of task spawning for non-`Send` +/// futures, via [`spawn_local_obj`](futures_task::LocalSpawn::spawn_local_obj). +#[derive(Debug)] +pub struct LocalPool { + pool: FuturesUnordered>, + incoming: Rc, +} + +/// A handle to a [`LocalPool`](LocalPool) that implements +/// [`Spawn`](futures_task::Spawn). +#[derive(Clone, Debug)] +pub struct LocalSpawner { + incoming: Weak, +} + +type Incoming = RefCell>>; + +pub(crate) struct ThreadNotify { + /// The (single) executor thread. + thread: Thread, + /// A flag to ensure a wakeup (i.e. `unpark()`) is not "forgotten" + /// before the next `park()`, which may otherwise happen if the code + /// being executed as part of the future(s) being polled makes use of + /// park / unpark calls of its own, i.e. we cannot assume that no other + /// code uses park / unpark on the executing `thread`. + unparked: AtomicBool, +} + +thread_local! { + static CURRENT_THREAD_NOTIFY: Arc = Arc::new(ThreadNotify { + thread: thread::current(), + unparked: AtomicBool::new(false), + }); +} + +impl ArcWake for ThreadNotify { + fn wake_by_ref(arc_self: &Arc) { + // Make sure the wakeup is remembered until the next `park()`. + let unparked = arc_self.unparked.swap(true, Ordering::Release); + if !unparked { + // If the thread has not been unparked yet, it must be done + // now. If it was actually parked, it will run again, + // otherwise the token made available by `unpark` + // may be consumed before reaching `park()`, but `unparked` + // ensures it is not forgotten. + arc_self.thread.unpark(); + } + } +} + +// Set up and run a basic single-threaded spawner loop, invoking `f` on each +// turn. +fn run_executor) -> Poll>(mut f: F) -> T { + let _enter = enter().expect( + "cannot execute `LocalPool` executor from within \ + another executor", + ); + + CURRENT_THREAD_NOTIFY.with(|thread_notify| { + let waker = waker_ref(thread_notify); + let mut cx = Context::from_waker(&waker); + loop { + if let Poll::Ready(t) = f(&mut cx) { + return t; + } + + // Wait for a wakeup. + while !thread_notify.unparked.swap(false, Ordering::Acquire) { + // No wakeup occurred. It may occur now, right before parking, + // but in that case the token made available by `unpark()` + // is guaranteed to still be available and `park()` is a no-op. + thread::park(); + } + } + }) +} + +/// Check for a wakeup, but don't consume it. +fn woken() -> bool { + CURRENT_THREAD_NOTIFY.with(|thread_notify| thread_notify.unparked.load(Ordering::Acquire)) +} + +impl LocalPool { + /// Create a new, empty pool of tasks. + pub fn new() -> Self { + Self { pool: FuturesUnordered::new(), incoming: Default::default() } + } + + /// Get a clonable handle to the pool as a [`Spawn`]. + pub fn spawner(&self) -> LocalSpawner { + LocalSpawner { incoming: Rc::downgrade(&self.incoming) } + } + + /// Run all tasks in the pool to completion. + /// + /// ``` + /// use futures::executor::LocalPool; + /// + /// let mut pool = LocalPool::new(); + /// + /// // ... spawn some initial tasks using `spawn.spawn()` or `spawn.spawn_local()` + /// + /// // run *all* tasks in the pool to completion, including any newly-spawned ones. + /// pool.run(); + /// ``` + /// + /// The function will block the calling thread until *all* tasks in the pool + /// are complete, including any spawned while running existing tasks. + pub fn run(&mut self) { + run_executor(|cx| self.poll_pool(cx)) + } + + /// Runs all the tasks in the pool until the given future completes. + /// + /// ``` + /// use futures::executor::LocalPool; + /// + /// let mut pool = LocalPool::new(); + /// # let my_app = async {}; + /// + /// // run tasks in the pool until `my_app` completes + /// pool.run_until(my_app); + /// ``` + /// + /// The function will block the calling thread *only* until the future `f` + /// completes; there may still be incomplete tasks in the pool, which will + /// be inert after the call completes, but can continue with further use of + /// one of the pool's run or poll methods. While the function is running, + /// however, all tasks in the pool will try to make progress. + pub fn run_until(&mut self, future: F) -> F::Output { + pin_mut!(future); + + run_executor(|cx| { + { + // if our main task is done, so are we + let result = future.as_mut().poll(cx); + if let Poll::Ready(output) = result { + return Poll::Ready(output); + } + } + + let _ = self.poll_pool(cx); + Poll::Pending + }) + } + + /// Runs all tasks and returns after completing one future or until no more progress + /// can be made. Returns `true` if one future was completed, `false` otherwise. + /// + /// ``` + /// use futures::executor::LocalPool; + /// use futures::task::LocalSpawnExt; + /// use futures::future::{ready, pending}; + /// + /// let mut pool = LocalPool::new(); + /// let spawner = pool.spawner(); + /// + /// spawner.spawn_local(ready(())).unwrap(); + /// spawner.spawn_local(ready(())).unwrap(); + /// spawner.spawn_local(pending()).unwrap(); + /// + /// // Run the two ready tasks and return true for them. + /// pool.try_run_one(); // returns true after completing one of the ready futures + /// pool.try_run_one(); // returns true after completing the other ready future + /// + /// // the remaining task can not be completed + /// assert!(!pool.try_run_one()); // returns false + /// ``` + /// + /// This function will not block the calling thread and will return the moment + /// that there are no tasks left for which progress can be made or after exactly one + /// task was completed; Remaining incomplete tasks in the pool can continue with + /// further use of one of the pool's run or poll methods. + /// Though only one task will be completed, progress may be made on multiple tasks. + pub fn try_run_one(&mut self) -> bool { + run_executor(|cx| { + loop { + self.drain_incoming(); + + match self.pool.poll_next_unpin(cx) { + // Success! + Poll::Ready(Some(())) => return Poll::Ready(true), + // The pool was empty. + Poll::Ready(None) => return Poll::Ready(false), + Poll::Pending => (), + } + + if !self.incoming.borrow().is_empty() { + // New tasks were spawned; try again. + continue; + } else if woken() { + // The pool yielded to us, but there's more progress to be made. + return Poll::Pending; + } else { + return Poll::Ready(false); + } + } + }) + } + + /// Runs all tasks in the pool and returns if no more progress can be made + /// on any task. + /// + /// ``` + /// use futures::executor::LocalPool; + /// use futures::task::LocalSpawnExt; + /// use futures::future::{ready, pending}; + /// + /// let mut pool = LocalPool::new(); + /// let spawner = pool.spawner(); + /// + /// spawner.spawn_local(ready(())).unwrap(); + /// spawner.spawn_local(ready(())).unwrap(); + /// spawner.spawn_local(pending()).unwrap(); + /// + /// // Runs the two ready task and returns. + /// // The empty task remains in the pool. + /// pool.run_until_stalled(); + /// ``` + /// + /// This function will not block the calling thread and will return the moment + /// that there are no tasks left for which progress can be made; + /// remaining incomplete tasks in the pool can continue with further use of one + /// of the pool's run or poll methods. While the function is running, all tasks + /// in the pool will try to make progress. + pub fn run_until_stalled(&mut self) { + run_executor(|cx| match self.poll_pool(cx) { + // The pool is empty. + Poll::Ready(()) => Poll::Ready(()), + Poll::Pending => { + if woken() { + Poll::Pending + } else { + // We're stalled for now. + Poll::Ready(()) + } + } + }); + } + + /// Poll `self.pool`, re-filling it with any newly-spawned tasks. + /// Repeat until either the pool is empty, or it returns `Pending`. + /// + /// Returns `Ready` if the pool was empty, and `Pending` otherwise. + /// + /// NOTE: the pool may call `wake`, so `Pending` doesn't necessarily + /// mean that the pool can't make progress. + fn poll_pool(&mut self, cx: &mut Context<'_>) -> Poll<()> { + loop { + self.drain_incoming(); + + let pool_ret = self.pool.poll_next_unpin(cx); + + // We queued up some new tasks; add them and poll again. + if !self.incoming.borrow().is_empty() { + continue; + } + + match pool_ret { + Poll::Ready(Some(())) => continue, + Poll::Ready(None) => return Poll::Ready(()), + Poll::Pending => return Poll::Pending, + } + } + } + + /// Empty the incoming queue of newly-spawned tasks. + fn drain_incoming(&mut self) { + let mut incoming = self.incoming.borrow_mut(); + for task in incoming.drain(..) { + self.pool.push(task) + } + } +} + +impl Default for LocalPool { + fn default() -> Self { + Self::new() + } +} + +/// Run a future to completion on the current thread. +/// +/// This function will block the caller until the given future has completed. +/// +/// Use a [`LocalPool`](LocalPool) if you need finer-grained control over +/// spawned tasks. +pub fn block_on(f: F) -> F::Output { + pin_mut!(f); + run_executor(|cx| f.as_mut().poll(cx)) +} + +/// Turn a stream into a blocking iterator. +/// +/// When `next` is called on the resulting `BlockingStream`, the caller +/// will be blocked until the next element of the `Stream` becomes available. +pub fn block_on_stream(stream: S) -> BlockingStream { + BlockingStream { stream } +} + +/// An iterator which blocks on values from a stream until they become available. +#[derive(Debug)] +pub struct BlockingStream { + stream: S, +} + +impl Deref for BlockingStream { + type Target = S; + fn deref(&self) -> &Self::Target { + &self.stream + } +} + +impl DerefMut for BlockingStream { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.stream + } +} + +impl BlockingStream { + /// Convert this `BlockingStream` into the inner `Stream` type. + pub fn into_inner(self) -> S { + self.stream + } +} + +impl Iterator for BlockingStream { + type Item = S::Item; + + fn next(&mut self) -> Option { + LocalPool::new().run_until(self.stream.next()) + } + + fn size_hint(&self) -> (usize, Option) { + self.stream.size_hint() + } +} + +impl Spawn for LocalSpawner { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + if let Some(incoming) = self.incoming.upgrade() { + incoming.borrow_mut().push(future.into()); + Ok(()) + } else { + Err(SpawnError::shutdown()) + } + } + + fn status(&self) -> Result<(), SpawnError> { + if self.incoming.upgrade().is_some() { + Ok(()) + } else { + Err(SpawnError::shutdown()) + } + } +} + +impl LocalSpawn for LocalSpawner { + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + if let Some(incoming) = self.incoming.upgrade() { + incoming.borrow_mut().push(future); + Ok(()) + } else { + Err(SpawnError::shutdown()) + } + } + + fn status_local(&self) -> Result<(), SpawnError> { + if self.incoming.upgrade().is_some() { + Ok(()) + } else { + Err(SpawnError::shutdown()) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-executor/src/thread_pool.rs b/utshell-0.5.0/vendor/futures-executor/src/thread_pool.rs new file mode 100644 index 00000000..53710089 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/src/thread_pool.rs @@ -0,0 +1,380 @@ +use crate::enter; +use crate::unpark_mutex::UnparkMutex; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_task::{waker_ref, ArcWake}; +use futures_task::{FutureObj, Spawn, SpawnError}; +use futures_util::future::FutureExt; +use std::cmp; +use std::fmt; +use std::io; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::mpsc; +use std::sync::{Arc, Mutex}; +use std::thread; + +/// A general-purpose thread pool for scheduling tasks that poll futures to +/// completion. +/// +/// The thread pool multiplexes any number of tasks onto a fixed number of +/// worker threads. +/// +/// This type is a clonable handle to the threadpool itself. +/// Cloning it will only create a new reference, not a new threadpool. +/// +/// This type is only available when the `thread-pool` feature of this +/// library is activated. +#[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] +pub struct ThreadPool { + state: Arc, +} + +/// Thread pool configuration object. +/// +/// This type is only available when the `thread-pool` feature of this +/// library is activated. +#[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] +pub struct ThreadPoolBuilder { + pool_size: usize, + stack_size: usize, + name_prefix: Option, + after_start: Option>, + before_stop: Option>, +} + +trait AssertSendSync: Send + Sync {} +impl AssertSendSync for ThreadPool {} + +struct PoolState { + tx: Mutex>, + rx: Mutex>, + cnt: AtomicUsize, + size: usize, +} + +impl fmt::Debug for ThreadPool { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ThreadPool").field("size", &self.state.size).finish() + } +} + +impl fmt::Debug for ThreadPoolBuilder { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ThreadPoolBuilder") + .field("pool_size", &self.pool_size) + .field("name_prefix", &self.name_prefix) + .finish() + } +} + +enum Message { + Run(Task), + Close, +} + +impl ThreadPool { + /// Creates a new thread pool with the default configuration. + /// + /// See documentation for the methods in + /// [`ThreadPoolBuilder`](ThreadPoolBuilder) for details on the default + /// configuration. + pub fn new() -> Result { + ThreadPoolBuilder::new().create() + } + + /// Create a default thread pool configuration, which can then be customized. + /// + /// See documentation for the methods in + /// [`ThreadPoolBuilder`](ThreadPoolBuilder) for details on the default + /// configuration. + pub fn builder() -> ThreadPoolBuilder { + ThreadPoolBuilder::new() + } + + /// Spawns a future that will be run to completion. + /// + /// > **Note**: This method is similar to `Spawn::spawn_obj`, except that + /// > it is guaranteed to always succeed. + pub fn spawn_obj_ok(&self, future: FutureObj<'static, ()>) { + let task = Task { + future, + wake_handle: Arc::new(WakeHandle { exec: self.clone(), mutex: UnparkMutex::new() }), + exec: self.clone(), + }; + self.state.send(Message::Run(task)); + } + + /// Spawns a task that polls the given future with output `()` to + /// completion. + /// + /// ``` + /// # { + /// use futures::executor::ThreadPool; + /// + /// let pool = ThreadPool::new().unwrap(); + /// + /// let future = async { /* ... */ }; + /// pool.spawn_ok(future); + /// # } + /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 + /// ``` + /// + /// > **Note**: This method is similar to `SpawnExt::spawn`, except that + /// > it is guaranteed to always succeed. + pub fn spawn_ok(&self, future: Fut) + where + Fut: Future + Send + 'static, + { + self.spawn_obj_ok(FutureObj::new(Box::new(future))) + } +} + +impl Spawn for ThreadPool { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + self.spawn_obj_ok(future); + Ok(()) + } +} + +impl PoolState { + fn send(&self, msg: Message) { + self.tx.lock().unwrap().send(msg).unwrap(); + } + + fn work( + &self, + idx: usize, + after_start: Option>, + before_stop: Option>, + ) { + let _scope = enter().unwrap(); + if let Some(after_start) = after_start { + after_start(idx); + } + loop { + let msg = self.rx.lock().unwrap().recv().unwrap(); + match msg { + Message::Run(task) => task.run(), + Message::Close => break, + } + } + if let Some(before_stop) = before_stop { + before_stop(idx); + } + } +} + +impl Clone for ThreadPool { + fn clone(&self) -> Self { + self.state.cnt.fetch_add(1, Ordering::Relaxed); + Self { state: self.state.clone() } + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + if self.state.cnt.fetch_sub(1, Ordering::Relaxed) == 1 { + for _ in 0..self.state.size { + self.state.send(Message::Close); + } + } + } +} + +impl ThreadPoolBuilder { + /// Create a default thread pool configuration. + /// + /// See the other methods on this type for details on the defaults. + pub fn new() -> Self { + Self { + pool_size: cmp::max(1, num_cpus::get()), + stack_size: 0, + name_prefix: None, + after_start: None, + before_stop: None, + } + } + + /// Set size of a future ThreadPool + /// + /// The size of a thread pool is the number of worker threads spawned. By + /// default, this is equal to the number of CPU cores. + /// + /// # Panics + /// + /// Panics if `pool_size == 0`. + pub fn pool_size(&mut self, size: usize) -> &mut Self { + assert!(size > 0); + self.pool_size = size; + self + } + + /// Set stack size of threads in the pool, in bytes. + /// + /// By default, worker threads use Rust's standard stack size. + pub fn stack_size(&mut self, stack_size: usize) -> &mut Self { + self.stack_size = stack_size; + self + } + + /// Set thread name prefix of a future ThreadPool. + /// + /// Thread name prefix is used for generating thread names. For example, if prefix is + /// `my-pool-`, then threads in the pool will get names like `my-pool-1` etc. + /// + /// By default, worker threads are assigned Rust's standard thread name. + pub fn name_prefix>(&mut self, name_prefix: S) -> &mut Self { + self.name_prefix = Some(name_prefix.into()); + self + } + + /// Execute the closure `f` immediately after each worker thread is started, + /// but before running any tasks on it. + /// + /// This hook is intended for bookkeeping and monitoring. + /// The closure `f` will be dropped after the `builder` is dropped + /// and all worker threads in the pool have executed it. + /// + /// The closure provided will receive an index corresponding to the worker + /// thread it's running on. + pub fn after_start(&mut self, f: F) -> &mut Self + where + F: Fn(usize) + Send + Sync + 'static, + { + self.after_start = Some(Arc::new(f)); + self + } + + /// Execute closure `f` just prior to shutting down each worker thread. + /// + /// This hook is intended for bookkeeping and monitoring. + /// The closure `f` will be dropped after the `builder` is dropped + /// and all threads in the pool have executed it. + /// + /// The closure provided will receive an index corresponding to the worker + /// thread it's running on. + pub fn before_stop(&mut self, f: F) -> &mut Self + where + F: Fn(usize) + Send + Sync + 'static, + { + self.before_stop = Some(Arc::new(f)); + self + } + + /// Create a [`ThreadPool`](ThreadPool) with the given configuration. + pub fn create(&mut self) -> Result { + let (tx, rx) = mpsc::channel(); + let pool = ThreadPool { + state: Arc::new(PoolState { + tx: Mutex::new(tx), + rx: Mutex::new(rx), + cnt: AtomicUsize::new(1), + size: self.pool_size, + }), + }; + + for counter in 0..self.pool_size { + let state = pool.state.clone(); + let after_start = self.after_start.clone(); + let before_stop = self.before_stop.clone(); + let mut thread_builder = thread::Builder::new(); + if let Some(ref name_prefix) = self.name_prefix { + thread_builder = thread_builder.name(format!("{}{}", name_prefix, counter)); + } + if self.stack_size > 0 { + thread_builder = thread_builder.stack_size(self.stack_size); + } + thread_builder.spawn(move || state.work(counter, after_start, before_stop))?; + } + Ok(pool) + } +} + +impl Default for ThreadPoolBuilder { + fn default() -> Self { + Self::new() + } +} + +/// A task responsible for polling a future to completion. +struct Task { + future: FutureObj<'static, ()>, + exec: ThreadPool, + wake_handle: Arc, +} + +struct WakeHandle { + mutex: UnparkMutex, + exec: ThreadPool, +} + +impl Task { + /// Actually run the task (invoking `poll` on the future) on the current + /// thread. + fn run(self) { + let Self { mut future, wake_handle, mut exec } = self; + let waker = waker_ref(&wake_handle); + let mut cx = Context::from_waker(&waker); + + // Safety: The ownership of this `Task` object is evidence that + // we are in the `POLLING`/`REPOLL` state for the mutex. + unsafe { + wake_handle.mutex.start_poll(); + + loop { + let res = future.poll_unpin(&mut cx); + match res { + Poll::Pending => {} + Poll::Ready(()) => return wake_handle.mutex.complete(), + } + let task = Self { future, wake_handle: wake_handle.clone(), exec }; + match wake_handle.mutex.wait(task) { + Ok(()) => return, // we've waited + Err(task) => { + // someone's notified us + future = task.future; + exec = task.exec; + } + } + } + } + } +} + +impl fmt::Debug for Task { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Task").field("contents", &"...").finish() + } +} + +impl ArcWake for WakeHandle { + fn wake_by_ref(arc_self: &Arc) { + if let Ok(task) = arc_self.mutex.notify() { + arc_self.exec.state.send(Message::Run(task)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::mpsc; + + #[test] + fn test_drop_after_start() { + { + let (tx, rx) = mpsc::sync_channel(2); + let _cpu_pool = ThreadPoolBuilder::new() + .pool_size(2) + .after_start(move |_| tx.send(1).unwrap()) + .create() + .unwrap(); + + // After ThreadPoolBuilder is deconstructed, the tx should be dropped + // so that we can use rx as an iterator. + let count = rx.into_iter().count(); + assert_eq!(count, 2); + } + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 + } +} diff --git a/utshell-0.5.0/vendor/futures-executor/src/unpark_mutex.rs b/utshell-0.5.0/vendor/futures-executor/src/unpark_mutex.rs new file mode 100644 index 00000000..ac5112cf --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/src/unpark_mutex.rs @@ -0,0 +1,137 @@ +use std::cell::UnsafeCell; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::SeqCst; + +/// A "lock" around data `D`, which employs a *helping* strategy. +/// +/// Used to ensure that concurrent `unpark` invocations lead to (1) `poll` being +/// invoked on only a single thread at a time (2) `poll` being invoked at least +/// once after each `unpark` (unless the future has completed). +pub(crate) struct UnparkMutex { + // The state of task execution (state machine described below) + status: AtomicUsize, + + // The actual task data, accessible only in the POLLING state + inner: UnsafeCell>, +} + +// `UnparkMutex` functions in many ways like a `Mutex`, except that on +// acquisition failure, the current lock holder performs the desired work -- +// re-polling. +// +// As such, these impls mirror those for `Mutex`. In particular, a reference +// to `UnparkMutex` can be used to gain `&mut` access to the inner data, which +// must therefore be `Send`. +unsafe impl Send for UnparkMutex {} +unsafe impl Sync for UnparkMutex {} + +// There are four possible task states, listed below with their possible +// transitions: + +// The task is blocked, waiting on an event +const WAITING: usize = 0; // --> POLLING + +// The task is actively being polled by a thread; arrival of additional events +// of interest should move it to the REPOLL state +const POLLING: usize = 1; // --> WAITING, REPOLL, or COMPLETE + +// The task is actively being polled, but will need to be re-polled upon +// completion to ensure that all events were observed. +const REPOLL: usize = 2; // --> POLLING + +// The task has finished executing (either successfully or with an error/panic) +const COMPLETE: usize = 3; // No transitions out + +impl UnparkMutex { + pub(crate) fn new() -> Self { + Self { status: AtomicUsize::new(WAITING), inner: UnsafeCell::new(None) } + } + + /// Attempt to "notify" the mutex that a poll should occur. + /// + /// An `Ok` result indicates that the `POLLING` state has been entered, and + /// the caller can proceed to poll the future. An `Err` result indicates + /// that polling is not necessary (because the task is finished or the + /// polling has been delegated). + pub(crate) fn notify(&self) -> Result { + let mut status = self.status.load(SeqCst); + loop { + match status { + // The task is idle, so try to run it immediately. + WAITING => { + match self.status.compare_exchange(WAITING, POLLING, SeqCst, SeqCst) { + Ok(_) => { + let data = unsafe { + // SAFETY: we've ensured mutual exclusion via + // the status protocol; we are the only thread + // that has transitioned to the POLLING state, + // and we won't transition back to QUEUED until + // the lock is "released" by this thread. See + // the protocol diagram above. + (*self.inner.get()).take().unwrap() + }; + return Ok(data); + } + Err(cur) => status = cur, + } + } + + // The task is being polled, so we need to record that it should + // be *repolled* when complete. + POLLING => match self.status.compare_exchange(POLLING, REPOLL, SeqCst, SeqCst) { + Ok(_) => return Err(()), + Err(cur) => status = cur, + }, + + // The task is already scheduled for polling, or is complete, so + // we've got nothing to do. + _ => return Err(()), + } + } + } + + /// Alert the mutex that polling is about to begin, clearing any accumulated + /// re-poll requests. + /// + /// # Safety + /// + /// Callable only from the `POLLING`/`REPOLL` states, i.e. between + /// successful calls to `notify` and `wait`/`complete`. + pub(crate) unsafe fn start_poll(&self) { + self.status.store(POLLING, SeqCst); + } + + /// Alert the mutex that polling completed with `Pending`. + /// + /// # Safety + /// + /// Callable only from the `POLLING`/`REPOLL` states, i.e. between + /// successful calls to `notify` and `wait`/`complete`. + pub(crate) unsafe fn wait(&self, data: D) -> Result<(), D> { + *self.inner.get() = Some(data); + + match self.status.compare_exchange(POLLING, WAITING, SeqCst, SeqCst) { + // no unparks came in while we were running + Ok(_) => Ok(()), + + // guaranteed to be in REPOLL state; just clobber the + // state and run again. + Err(status) => { + assert_eq!(status, REPOLL); + self.status.store(POLLING, SeqCst); + Err((*self.inner.get()).take().unwrap()) + } + } + } + + /// Alert the mutex that the task has completed execution and should not be + /// notified again. + /// + /// # Safety + /// + /// Callable only from the `POLLING`/`REPOLL` states, i.e. between + /// successful calls to `notify` and `wait`/`complete`. + pub(crate) unsafe fn complete(&self) { + self.status.store(COMPLETE, SeqCst); + } +} diff --git a/utshell-0.5.0/vendor/futures-executor/tests/local_pool.rs b/utshell-0.5.0/vendor/futures-executor/tests/local_pool.rs new file mode 100644 index 00000000..72ce74b7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-executor/tests/local_pool.rs @@ -0,0 +1,496 @@ +use futures::channel::oneshot; +use futures::executor::LocalPool; +use futures::future::{self, lazy, poll_fn, Future}; +use futures::task::{Context, LocalSpawn, LocalSpawnExt, Poll, Spawn, SpawnExt, Waker}; +use std::cell::{Cell, RefCell}; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::thread; +use std::time::Duration; + +struct Pending(Rc<()>); + +impl Future for Pending { + type Output = (); + + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> { + Poll::Pending + } +} + +fn pending() -> Pending { + Pending(Rc::new(())) +} + +#[test] +fn run_until_single_future() { + let mut cnt = 0; + + { + let mut pool = LocalPool::new(); + let fut = lazy(|_| { + cnt += 1; + }); + pool.run_until(fut); + } + + assert_eq!(cnt, 1); +} + +#[test] +fn run_until_ignores_spawned() { + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + spawn.spawn_local_obj(Box::pin(pending()).into()).unwrap(); + pool.run_until(lazy(|_| ())); +} + +#[test] +fn run_until_executes_spawned() { + let (tx, rx) = oneshot::channel(); + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + spawn + .spawn_local_obj( + Box::pin(lazy(move |_| { + tx.send(()).unwrap(); + })) + .into(), + ) + .unwrap(); + pool.run_until(rx).unwrap(); +} + +#[test] +fn run_returns_if_empty() { + let mut pool = LocalPool::new(); + pool.run(); + pool.run(); +} + +#[test] +fn run_executes_spawned() { + let cnt = Rc::new(Cell::new(0)); + let cnt2 = cnt.clone(); + + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + let spawn2 = pool.spawner(); + + spawn + .spawn_local_obj( + Box::pin(lazy(move |_| { + spawn2 + .spawn_local_obj( + Box::pin(lazy(move |_| { + cnt2.set(cnt2.get() + 1); + })) + .into(), + ) + .unwrap(); + })) + .into(), + ) + .unwrap(); + + pool.run(); + + assert_eq!(cnt.get(), 1); +} + +#[test] +fn run_spawn_many() { + const ITER: usize = 200; + + let cnt = Rc::new(Cell::new(0)); + + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + for _ in 0..ITER { + let cnt = cnt.clone(); + spawn + .spawn_local_obj( + Box::pin(lazy(move |_| { + cnt.set(cnt.get() + 1); + })) + .into(), + ) + .unwrap(); + } + + pool.run(); + + assert_eq!(cnt.get(), ITER); +} + +#[test] +fn try_run_one_returns_if_empty() { + let mut pool = LocalPool::new(); + assert!(!pool.try_run_one()); +} + +#[test] +fn try_run_one_executes_one_ready() { + const ITER: usize = 200; + + let cnt = Rc::new(Cell::new(0)); + + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + for _ in 0..ITER { + spawn.spawn_local_obj(Box::pin(pending()).into()).unwrap(); + + let cnt = cnt.clone(); + spawn + .spawn_local_obj( + Box::pin(lazy(move |_| { + cnt.set(cnt.get() + 1); + })) + .into(), + ) + .unwrap(); + + spawn.spawn_local_obj(Box::pin(pending()).into()).unwrap(); + } + + for i in 0..ITER { + assert_eq!(cnt.get(), i); + assert!(pool.try_run_one()); + assert_eq!(cnt.get(), i + 1); + } + assert!(!pool.try_run_one()); +} + +#[test] +fn try_run_one_returns_on_no_progress() { + const ITER: usize = 10; + + let cnt = Rc::new(Cell::new(0)); + + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + let waker: Rc>> = Rc::new(Cell::new(None)); + { + let cnt = cnt.clone(); + let waker = waker.clone(); + spawn + .spawn_local_obj( + Box::pin(poll_fn(move |ctx| { + cnt.set(cnt.get() + 1); + waker.set(Some(ctx.waker().clone())); + if cnt.get() == ITER { + Poll::Ready(()) + } else { + Poll::Pending + } + })) + .into(), + ) + .unwrap(); + } + + for i in 0..ITER - 1 { + assert_eq!(cnt.get(), i); + assert!(!pool.try_run_one()); + assert_eq!(cnt.get(), i + 1); + let w = waker.take(); + assert!(w.is_some()); + w.unwrap().wake(); + } + assert!(pool.try_run_one()); + assert_eq!(cnt.get(), ITER); +} + +#[test] +fn try_run_one_runs_sub_futures() { + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + let cnt = Rc::new(Cell::new(0)); + + let inner_spawner = spawn.clone(); + let cnt1 = cnt.clone(); + spawn + .spawn_local_obj( + Box::pin(poll_fn(move |_| { + cnt1.set(cnt1.get() + 1); + + let cnt2 = cnt1.clone(); + inner_spawner + .spawn_local_obj(Box::pin(lazy(move |_| cnt2.set(cnt2.get() + 1))).into()) + .unwrap(); + + Poll::Pending + })) + .into(), + ) + .unwrap(); + + pool.try_run_one(); + assert_eq!(cnt.get(), 2); +} + +#[test] +fn run_until_stalled_returns_if_empty() { + let mut pool = LocalPool::new(); + pool.run_until_stalled(); + pool.run_until_stalled(); +} + +#[test] +fn run_until_stalled_returns_multiple_times() { + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + let cnt = Rc::new(Cell::new(0)); + + let cnt1 = cnt.clone(); + spawn.spawn_local_obj(Box::pin(lazy(move |_| cnt1.set(cnt1.get() + 1))).into()).unwrap(); + pool.run_until_stalled(); + assert_eq!(cnt.get(), 1); + + let cnt2 = cnt.clone(); + spawn.spawn_local_obj(Box::pin(lazy(move |_| cnt2.set(cnt2.get() + 1))).into()).unwrap(); + pool.run_until_stalled(); + assert_eq!(cnt.get(), 2); +} + +#[test] +fn run_until_stalled_runs_spawned_sub_futures() { + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + let cnt = Rc::new(Cell::new(0)); + + let inner_spawner = spawn.clone(); + let cnt1 = cnt.clone(); + spawn + .spawn_local_obj( + Box::pin(poll_fn(move |_| { + cnt1.set(cnt1.get() + 1); + + let cnt2 = cnt1.clone(); + inner_spawner + .spawn_local_obj(Box::pin(lazy(move |_| cnt2.set(cnt2.get() + 1))).into()) + .unwrap(); + + Poll::Pending + })) + .into(), + ) + .unwrap(); + + pool.run_until_stalled(); + assert_eq!(cnt.get(), 2); +} + +#[test] +fn run_until_stalled_executes_all_ready() { + const ITER: usize = if cfg!(miri) { 50 } else { 200 }; + const PER_ITER: usize = 3; + + let cnt = Rc::new(Cell::new(0)); + + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + for i in 0..ITER { + for _ in 0..PER_ITER { + spawn.spawn_local_obj(Box::pin(pending()).into()).unwrap(); + + let cnt = cnt.clone(); + spawn + .spawn_local_obj( + Box::pin(lazy(move |_| { + cnt.set(cnt.get() + 1); + })) + .into(), + ) + .unwrap(); + + // also add some pending tasks to test if they are ignored + spawn.spawn_local_obj(Box::pin(pending()).into()).unwrap(); + } + assert_eq!(cnt.get(), i * PER_ITER); + pool.run_until_stalled(); + assert_eq!(cnt.get(), (i + 1) * PER_ITER); + } +} + +#[test] +#[should_panic] +fn nesting_run() { + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + spawn + .spawn_obj( + Box::pin(lazy(|_| { + let mut pool = LocalPool::new(); + pool.run(); + })) + .into(), + ) + .unwrap(); + + pool.run(); +} + +#[test] +#[should_panic] +fn nesting_run_run_until_stalled() { + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + spawn + .spawn_obj( + Box::pin(lazy(|_| { + let mut pool = LocalPool::new(); + pool.run_until_stalled(); + })) + .into(), + ) + .unwrap(); + + pool.run(); +} + +#[test] +fn tasks_are_scheduled_fairly() { + let state = Rc::new(RefCell::new([0, 0])); + + struct Spin { + state: Rc>, + idx: usize, + } + + impl Future for Spin { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + let mut state = self.state.borrow_mut(); + + if self.idx == 0 { + let diff = state[0] - state[1]; + + assert!(diff.abs() <= 1); + + if state[0] >= 50 { + return Poll::Ready(()); + } + } + + state[self.idx] += 1; + + if state[self.idx] >= 100 { + return Poll::Ready(()); + } + + cx.waker().wake_by_ref(); + Poll::Pending + } + } + + let mut pool = LocalPool::new(); + let spawn = pool.spawner(); + + spawn.spawn_local_obj(Box::pin(Spin { state: state.clone(), idx: 0 }).into()).unwrap(); + + spawn.spawn_local_obj(Box::pin(Spin { state, idx: 1 }).into()).unwrap(); + + pool.run(); +} + +// Tests that the use of park/unpark in user-code has no +// effect on the expected behavior of the executor. +#[test] +fn park_unpark_independence() { + let mut done = false; + + let future = future::poll_fn(move |cx| { + if done { + return Poll::Ready(()); + } + done = true; + cx.waker().clone().wake(); // (*) + // some user-code that temporarily parks the thread + let test = thread::current(); + let latch = Arc::new(AtomicBool::new(false)); + let signal = latch.clone(); + thread::spawn(move || { + thread::sleep(Duration::from_millis(10)); + signal.store(true, Ordering::SeqCst); + test.unpark() + }); + while !latch.load(Ordering::Relaxed) { + thread::park(); + } + Poll::Pending // Expect to be called again due to (*). + }); + + futures::executor::block_on(future) +} + +struct SelfWaking { + wakeups_remaining: Rc>, +} + +impl Future for SelfWaking { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if *self.wakeups_remaining.borrow() != 0 { + *self.wakeups_remaining.borrow_mut() -= 1; + cx.waker().wake_by_ref(); + } + + Poll::Pending + } +} + +/// Regression test for https://github.com/rust-lang/futures-rs/pull/2593 +/// +/// The issue was that self-waking futures could cause `run_until_stalled` +/// to exit early, even when progress could still be made. +#[test] +fn self_waking_run_until_stalled() { + let wakeups_remaining = Rc::new(RefCell::new(10)); + + let mut pool = LocalPool::new(); + let spawner = pool.spawner(); + for _ in 0..3 { + let wakeups_remaining = Rc::clone(&wakeups_remaining); + spawner.spawn_local(SelfWaking { wakeups_remaining }).unwrap(); + } + + // This should keep polling until there are no more wakeups. + pool.run_until_stalled(); + + assert_eq!(*wakeups_remaining.borrow(), 0); +} + +/// Regression test for https://github.com/rust-lang/futures-rs/pull/2593 +/// +/// The issue was that self-waking futures could cause `try_run_one` +/// to exit early, even when progress could still be made. +#[test] +fn self_waking_try_run_one() { + let wakeups_remaining = Rc::new(RefCell::new(10)); + + let mut pool = LocalPool::new(); + let spawner = pool.spawner(); + for _ in 0..3 { + let wakeups_remaining = Rc::clone(&wakeups_remaining); + spawner.spawn_local(SelfWaking { wakeups_remaining }).unwrap(); + } + + spawner.spawn(future::ready(())).unwrap(); + + // The `ready` future should complete. + assert!(pool.try_run_one()); + + // The self-waking futures are each polled once. + assert_eq!(*wakeups_remaining.borrow(), 7); +} diff --git a/utshell-0.5.0/vendor/futures-io/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-io/.cargo-checksum.json new file mode 100644 index 00000000..e6b4865c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-io/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"a2f46c222bebd5fae127414ffb34535af67be92b58bafcc39a16523ffc33ee83","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"575430be5c47352d85f36b44dcc2c2851a6a19e2384593415c4af22c6654cee7","src/lib.rs":"526e9700c28250b7512f122952257d57adc38eb001af92ef25bdb48a8c453175"},"package":"a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-io/Cargo.toml b/utshell-0.5.0/vendor/futures-io/Cargo.toml new file mode 100644 index 00000000..d08683c6 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-io/Cargo.toml @@ -0,0 +1,37 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.36" +name = "futures-io" +version = "0.3.30" +description = """ +The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[dependencies] + +[features] +default = ["std"] +std = [] +unstable = [] diff --git a/utshell-0.5.0/vendor/futures-io/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-io/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-io/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-io/LICENSE-MIT b/utshell-0.5.0/vendor/futures-io/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-io/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-io/README.md b/utshell-0.5.0/vendor/futures-io/README.md new file mode 100644 index 00000000..da6eec28 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-io/README.md @@ -0,0 +1,23 @@ +# futures-io + +The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-io = "0.3" +``` + +The current `futures-io` requires Rust 1.36 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-io/src/lib.rs b/utshell-0.5.0/vendor/futures-io/src/lib.rs new file mode 100644 index 00000000..e91eb784 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-io/src/lib.rs @@ -0,0 +1,558 @@ +//! Asynchronous I/O +//! +//! This crate contains the `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and +//! `AsyncBufRead` traits, the asynchronous analogs to +//! `std::io::{Read, Write, Seek, BufRead}`. The primary difference is +//! that these traits integrate with the asynchronous task system. +//! +//! All items of this library are only available when the `std` feature of this +//! library is activated, and it is activated by default. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)] +// It cannot be included in the published code because this lints have false positives in the minimum required version. +#![cfg_attr(test, warn(single_use_lifetimes))] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] +#![cfg_attr(docsrs, feature(doc_cfg))] + +#[cfg(feature = "std")] +mod if_std { + use std::io; + use std::ops::DerefMut; + use std::pin::Pin; + use std::task::{Context, Poll}; + + // Re-export some types from `std::io` so that users don't have to deal + // with conflicts when `use`ing `futures::io` and `std::io`. + #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 + #[doc(no_inline)] + pub use io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom}; + + /// Read bytes asynchronously. + /// + /// This trait is analogous to the `std::io::Read` trait, but integrates + /// with the asynchronous task system. In particular, the `poll_read` + /// method, unlike `Read::read`, will automatically queue the current task + /// for wakeup and return if data is not yet available, rather than blocking + /// the calling thread. + pub trait AsyncRead { + /// Attempt to read from the `AsyncRead` into `buf`. + /// + /// On success, returns `Poll::Ready(Ok(num_bytes_read))`. + /// + /// If no data is available for reading, the method returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes + /// readable or is closed. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll>; + + /// Attempt to read from the `AsyncRead` into `bufs` using vectored + /// IO operations. + /// + /// This method is similar to `poll_read`, but allows data to be read + /// into multiple buffers using a single operation. + /// + /// On success, returns `Poll::Ready(Ok(num_bytes_read))`. + /// + /// If no data is available for reading, the method returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes + /// readable or is closed. + /// By default, this method delegates to using `poll_read` on the first + /// nonempty buffer in `bufs`, or an empty one if none exists. Objects which + /// support vectored IO should override this method. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + fn poll_read_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + for b in bufs { + if !b.is_empty() { + return self.poll_read(cx, b); + } + } + + self.poll_read(cx, &mut []) + } + } + + /// Write bytes asynchronously. + /// + /// This trait is analogous to the `std::io::Write` trait, but integrates + /// with the asynchronous task system. In particular, the `poll_write` + /// method, unlike `Write::write`, will automatically queue the current task + /// for wakeup and return if the writer cannot take more data, rather than blocking + /// the calling thread. + pub trait AsyncWrite { + /// Attempt to write bytes from `buf` into the object. + /// + /// On success, returns `Poll::Ready(Ok(num_bytes_written))`. + /// + /// If the object is not ready for writing, the method returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes + /// writable or is closed. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + /// + /// `poll_write` must try to make progress by flushing the underlying object if + /// that is the only way the underlying object can become writable again. + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll>; + + /// Attempt to write bytes from `bufs` into the object using vectored + /// IO operations. + /// + /// This method is similar to `poll_write`, but allows data from multiple buffers to be written + /// using a single operation. + /// + /// On success, returns `Poll::Ready(Ok(num_bytes_written))`. + /// + /// If the object is not ready for writing, the method returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes + /// writable or is closed. + /// + /// By default, this method delegates to using `poll_write` on the first + /// nonempty buffer in `bufs`, or an empty one if none exists. Objects which + /// support vectored IO should override this method. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + for b in bufs { + if !b.is_empty() { + return self.poll_write(cx, b); + } + } + + self.poll_write(cx, &[]) + } + + /// Attempt to flush the object, ensuring that any buffered data reach + /// their destination. + /// + /// On success, returns `Poll::Ready(Ok(()))`. + /// + /// If flushing cannot immediately complete, this method returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object can make + /// progress towards flushing. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + /// + /// It only makes sense to do anything here if you actually buffer data. + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + + /// Attempt to close the object. + /// + /// On success, returns `Poll::Ready(Ok(()))`. + /// + /// If closing cannot immediately complete, this function returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object can make + /// progress towards closing. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + } + + /// Seek bytes asynchronously. + /// + /// This trait is analogous to the `std::io::Seek` trait, but integrates + /// with the asynchronous task system. In particular, the `poll_seek` + /// method, unlike `Seek::seek`, will automatically queue the current task + /// for wakeup and return if data is not yet available, rather than blocking + /// the calling thread. + pub trait AsyncSeek { + /// Attempt to seek to an offset, in bytes, in a stream. + /// + /// A seek beyond the end of a stream is allowed, but behavior is defined + /// by the implementation. + /// + /// If the seek operation completed successfully, + /// this method returns the new position from the start of the stream. + /// That position can be used later with [`SeekFrom::Start`]. + /// + /// # Errors + /// + /// Seeking to a negative offset is considered an error. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + fn poll_seek( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll>; + } + + /// Read bytes asynchronously. + /// + /// This trait is analogous to the `std::io::BufRead` trait, but integrates + /// with the asynchronous task system. In particular, the `poll_fill_buf` + /// method, unlike `BufRead::fill_buf`, will automatically queue the current task + /// for wakeup and return if data is not yet available, rather than blocking + /// the calling thread. + pub trait AsyncBufRead: AsyncRead { + /// Attempt to return the contents of the internal buffer, filling it with more data + /// from the inner reader if it is empty. + /// + /// On success, returns `Poll::Ready(Ok(buf))`. + /// + /// If no data is available for reading, the method returns + /// `Poll::Pending` and arranges for the current task (via + /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes + /// readable or is closed. + /// + /// This function is a lower-level call. It needs to be paired with the + /// [`consume`] method to function properly. When calling this + /// method, none of the contents will be "read" in the sense that later + /// calling [`poll_read`] may return the same contents. As such, [`consume`] must + /// be called with the number of bytes that are consumed from this buffer to + /// ensure that the bytes are never returned twice. + /// + /// [`poll_read`]: AsyncRead::poll_read + /// [`consume`]: AsyncBufRead::consume + /// + /// An empty buffer returned indicates that the stream has reached EOF. + /// + /// # Implementation + /// + /// This function may not return errors of kind `WouldBlock` or + /// `Interrupted`. Implementations must convert `WouldBlock` into + /// `Poll::Pending` and either internally retry or convert + /// `Interrupted` into another error kind. + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + + /// Tells this buffer that `amt` bytes have been consumed from the buffer, + /// so they should no longer be returned in calls to [`poll_read`]. + /// + /// This function is a lower-level call. It needs to be paired with the + /// [`poll_fill_buf`] method to function properly. This function does + /// not perform any I/O, it simply informs this object that some amount of + /// its buffer, returned from [`poll_fill_buf`], has been consumed and should + /// no longer be returned. As such, this function may do odd things if + /// [`poll_fill_buf`] isn't called before calling it. + /// + /// The `amt` must be `<=` the number of bytes in the buffer returned by + /// [`poll_fill_buf`]. + /// + /// [`poll_read`]: AsyncRead::poll_read + /// [`poll_fill_buf`]: AsyncBufRead::poll_fill_buf + fn consume(self: Pin<&mut Self>, amt: usize); + } + + macro_rules! deref_async_read { + () => { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Pin::new(&mut **self).poll_read(cx, buf) + } + + fn poll_read_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + Pin::new(&mut **self).poll_read_vectored(cx, bufs) + } + }; + } + + impl AsyncRead for Box { + deref_async_read!(); + } + + impl AsyncRead for &mut T { + deref_async_read!(); + } + + impl

AsyncRead for Pin

+ where + P: DerefMut + Unpin, + P::Target: AsyncRead, + { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + self.get_mut().as_mut().poll_read(cx, buf) + } + + fn poll_read_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + self.get_mut().as_mut().poll_read_vectored(cx, bufs) + } + } + + macro_rules! delegate_async_read_to_stdio { + () => { + fn poll_read( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Poll::Ready(io::Read::read(&mut *self, buf)) + } + + fn poll_read_vectored( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + Poll::Ready(io::Read::read_vectored(&mut *self, bufs)) + } + }; + } + + impl AsyncRead for &[u8] { + delegate_async_read_to_stdio!(); + } + + macro_rules! deref_async_write { + () => { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut **self).poll_write(cx, buf) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Pin::new(&mut **self).poll_write_vectored(cx, bufs) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self).poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self).poll_close(cx) + } + }; + } + + impl AsyncWrite for Box { + deref_async_write!(); + } + + impl AsyncWrite for &mut T { + deref_async_write!(); + } + + impl

AsyncWrite for Pin

+ where + P: DerefMut + Unpin, + P::Target: AsyncWrite, + { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + self.get_mut().as_mut().poll_write(cx, buf) + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + self.get_mut().as_mut().poll_write_vectored(cx, bufs) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_flush(cx) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_close(cx) + } + } + + macro_rules! delegate_async_write_to_stdio { + () => { + fn poll_write( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Poll::Ready(io::Write::write(&mut *self, buf)) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Poll::Ready(io::Write::write_vectored(&mut *self, bufs)) + } + + fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(io::Write::flush(&mut *self)) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.poll_flush(cx) + } + }; + } + + impl AsyncWrite for Vec { + delegate_async_write_to_stdio!(); + } + + macro_rules! deref_async_seek { + () => { + fn poll_seek( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + Pin::new(&mut **self).poll_seek(cx, pos) + } + }; + } + + impl AsyncSeek for Box { + deref_async_seek!(); + } + + impl AsyncSeek for &mut T { + deref_async_seek!(); + } + + impl

AsyncSeek for Pin

+ where + P: DerefMut + Unpin, + P::Target: AsyncSeek, + { + fn poll_seek( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + self.get_mut().as_mut().poll_seek(cx, pos) + } + } + + macro_rules! deref_async_buf_read { + () => { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self.get_mut()).poll_fill_buf(cx) + } + + fn consume(mut self: Pin<&mut Self>, amt: usize) { + Pin::new(&mut **self).consume(amt) + } + }; + } + + impl AsyncBufRead for Box { + deref_async_buf_read!(); + } + + impl AsyncBufRead for &mut T { + deref_async_buf_read!(); + } + + impl

AsyncBufRead for Pin

+ where + P: DerefMut + Unpin, + P::Target: AsyncBufRead, + { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_fill_buf(cx) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + self.get_mut().as_mut().consume(amt) + } + } + + macro_rules! delegate_async_buf_read_to_stdio { + () => { + fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(io::BufRead::fill_buf(self.get_mut())) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + io::BufRead::consume(self.get_mut(), amt) + } + }; + } + + impl AsyncBufRead for &[u8] { + delegate_async_buf_read_to_stdio!(); + } +} + +#[cfg(feature = "std")] +pub use self::if_std::*; diff --git a/utshell-0.5.0/vendor/futures-macro/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-macro/.cargo-checksum.json new file mode 100644 index 00000000..ef7abfe9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"a6394fbbe6143c8954364368159714b49ab1db61e19b73f0d50caa8cb3df1fc6","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/executor.rs":"d2c8545c3438262484da3cddb6d998928bfef8d6d191480c13c0c390f15fe0f1","src/join.rs":"eb1b7beb09e877a88fb76ba195b87b657681234002386ab3519f33b0a6670098","src/lib.rs":"8324c4d5cc4e9e377b2f95afde751168d7e94196c1f2cb35802193c900ca0026","src/select.rs":"6c8193b36ecd06d91036a0502d76ea35b4393537b5fc0432df67aa49f831ad18","src/stream_select.rs":"5fb84834a40876ab1fd975c3af67594d0c5a4f8d724cb164db9bee71e70d14b1"},"package":"87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-macro/Cargo.toml b/utshell-0.5.0/vendor/futures-macro/Cargo.toml new file mode 100644 index 00000000..00891d05 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/Cargo.toml @@ -0,0 +1,37 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "futures-macro" +version = "0.3.30" +description = """ +The futures-rs procedural macro implementations. +""" +homepage = "https://rust-lang.github.io/futures-rs" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[lib] +proc-macro = true + +[dependencies.proc-macro2] +version = "1.0.60" + +[dependencies.quote] +version = "1.0" + +[dependencies.syn] +version = "2.0.8" +features = ["full"] + +[features] diff --git a/utshell-0.5.0/vendor/futures-macro/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-macro/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-macro/LICENSE-MIT b/utshell-0.5.0/vendor/futures-macro/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-macro/src/executor.rs b/utshell-0.5.0/vendor/futures-macro/src/executor.rs new file mode 100644 index 00000000..7f1d0a93 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/src/executor.rs @@ -0,0 +1,56 @@ +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::{quote, quote_spanned, ToTokens}; + +pub(crate) fn test(args: TokenStream, item: TokenStream) -> TokenStream { + if !args.is_empty() { + return syn::Error::new_spanned(proc_macro2::TokenStream::from(args), "invalid argument") + .to_compile_error() + .into(); + } + + let mut input = syn::parse_macro_input!(item as syn::ItemFn); + + if input.sig.asyncness.take().is_none() { + return syn::Error::new_spanned(input.sig.fn_token, "Only async functions are supported") + .to_compile_error() + .into(); + } + + // If type mismatch occurs, the current rustc points to the last statement. + let (last_stmt_start_span, last_stmt_end_span) = { + let mut last_stmt = input + .block + .stmts + .last() + .map(ToTokens::into_token_stream) + .unwrap_or_default() + .into_iter(); + // `Span` on stable Rust has a limitation that only points to the first + // token, not the whole tokens. We can work around this limitation by + // using the first/last span of the tokens like + // `syn::Error::new_spanned` does. + let start = last_stmt.next().map_or_else(Span::call_site, |t| t.span()); + let end = last_stmt.last().map_or(start, |t| t.span()); + (start, end) + }; + + let path = quote_spanned! {last_stmt_start_span=> + ::futures_test::__private + }; + let body = &input.block; + input.block.stmts = vec![syn::Stmt::Expr( + syn::parse2(quote_spanned! {last_stmt_end_span=> + #path::block_on(async #body) + }) + .unwrap(), + None, + )]; + + let gen = quote! { + #[::core::prelude::v1::test] + #input + }; + + gen.into() +} diff --git a/utshell-0.5.0/vendor/futures-macro/src/join.rs b/utshell-0.5.0/vendor/futures-macro/src/join.rs new file mode 100644 index 00000000..94e356f7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/src/join.rs @@ -0,0 +1,144 @@ +//! The futures-rs `join! macro implementation. + +use proc_macro::TokenStream; +use proc_macro2::{Span, TokenStream as TokenStream2}; +use quote::{format_ident, quote}; +use syn::parse::{Parse, ParseStream}; +use syn::{Expr, Ident, Token}; + +#[derive(Default)] +struct Join { + fut_exprs: Vec, +} + +impl Parse for Join { + fn parse(input: ParseStream<'_>) -> syn::Result { + let mut join = Self::default(); + + while !input.is_empty() { + join.fut_exprs.push(input.parse::()?); + + if !input.is_empty() { + input.parse::()?; + } + } + + Ok(join) + } +} + +fn bind_futures(fut_exprs: Vec, span: Span) -> (Vec, Vec) { + let mut future_let_bindings = Vec::with_capacity(fut_exprs.len()); + let future_names: Vec<_> = fut_exprs + .into_iter() + .enumerate() + .map(|(i, expr)| { + let name = format_ident!("_fut{}", i, span = span); + future_let_bindings.push(quote! { + // Move future into a local so that it is pinned in one place and + // is no longer accessible by the end user. + let mut #name = __futures_crate::future::maybe_done(#expr); + let mut #name = unsafe { __futures_crate::Pin::new_unchecked(&mut #name) }; + }); + name + }) + .collect(); + + (future_let_bindings, future_names) +} + +/// The `join!` macro. +pub(crate) fn join(input: TokenStream) -> TokenStream { + let parsed = syn::parse_macro_input!(input as Join); + + // should be def_site, but that's unstable + let span = Span::call_site(); + + let (future_let_bindings, future_names) = bind_futures(parsed.fut_exprs, span); + + let poll_futures = future_names.iter().map(|fut| { + quote! { + __all_done &= __futures_crate::future::Future::poll( + #fut.as_mut(), __cx).is_ready(); + } + }); + let take_outputs = future_names.iter().map(|fut| { + quote! { + #fut.as_mut().take_output().unwrap(), + } + }); + + TokenStream::from(quote! { { + #( #future_let_bindings )* + + __futures_crate::future::poll_fn(move |__cx: &mut __futures_crate::task::Context<'_>| { + let mut __all_done = true; + #( #poll_futures )* + if __all_done { + __futures_crate::task::Poll::Ready(( + #( #take_outputs )* + )) + } else { + __futures_crate::task::Poll::Pending + } + }).await + } }) +} + +/// The `try_join!` macro. +pub(crate) fn try_join(input: TokenStream) -> TokenStream { + let parsed = syn::parse_macro_input!(input as Join); + + // should be def_site, but that's unstable + let span = Span::call_site(); + + let (future_let_bindings, future_names) = bind_futures(parsed.fut_exprs, span); + + let poll_futures = future_names.iter().map(|fut| { + quote! { + if __futures_crate::future::Future::poll( + #fut.as_mut(), __cx).is_pending() + { + __all_done = false; + } else if #fut.as_mut().output_mut().unwrap().is_err() { + // `.err().unwrap()` rather than `.unwrap_err()` so that we don't introduce + // a `T: Debug` bound. + // Also, for an error type of ! any code after `err().unwrap()` is unreachable. + #[allow(unreachable_code)] + return __futures_crate::task::Poll::Ready( + __futures_crate::Err( + #fut.as_mut().take_output().unwrap().err().unwrap() + ) + ); + } + } + }); + let take_outputs = future_names.iter().map(|fut| { + quote! { + // `.ok().unwrap()` rather than `.unwrap()` so that we don't introduce + // an `E: Debug` bound. + // Also, for an ok type of ! any code after `ok().unwrap()` is unreachable. + #[allow(unreachable_code)] + #fut.as_mut().take_output().unwrap().ok().unwrap(), + } + }); + + TokenStream::from(quote! { { + #( #future_let_bindings )* + + #[allow(clippy::diverging_sub_expression)] + __futures_crate::future::poll_fn(move |__cx: &mut __futures_crate::task::Context<'_>| { + let mut __all_done = true; + #( #poll_futures )* + if __all_done { + __futures_crate::task::Poll::Ready( + __futures_crate::Ok(( + #( #take_outputs )* + )) + ) + } else { + __futures_crate::task::Poll::Pending + } + }).await + } }) +} diff --git a/utshell-0.5.0/vendor/futures-macro/src/lib.rs b/utshell-0.5.0/vendor/futures-macro/src/lib.rs new file mode 100644 index 00000000..0afe34b8 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/src/lib.rs @@ -0,0 +1,61 @@ +//! The futures-rs procedural macro implementations. + +#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] + +// Since https://github.com/rust-lang/cargo/pull/7700 `proc_macro` is part of the prelude for +// proc-macro crates, but to support older compilers we still need this explicit `extern crate`. +#[allow(unused_extern_crates)] +extern crate proc_macro; + +use proc_macro::TokenStream; + +mod executor; +mod join; +mod select; +mod stream_select; + +/// The `join!` macro. +#[proc_macro] +pub fn join_internal(input: TokenStream) -> TokenStream { + crate::join::join(input) +} + +/// The `try_join!` macro. +#[proc_macro] +pub fn try_join_internal(input: TokenStream) -> TokenStream { + crate::join::try_join(input) +} + +/// The `select!` macro. +#[proc_macro] +pub fn select_internal(input: TokenStream) -> TokenStream { + crate::select::select(input) +} + +/// The `select_biased!` macro. +#[proc_macro] +pub fn select_biased_internal(input: TokenStream) -> TokenStream { + crate::select::select_biased(input) +} + +// TODO: Change this to doc comment once rustdoc bug fixed: https://github.com/rust-lang/futures-rs/pull/2435 +// The `test` attribute. +#[proc_macro_attribute] +pub fn test_internal(input: TokenStream, item: TokenStream) -> TokenStream { + crate::executor::test(input, item) +} + +/// The `stream_select!` macro. +#[proc_macro] +pub fn stream_select_internal(input: TokenStream) -> TokenStream { + crate::stream_select::stream_select(input.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/utshell-0.5.0/vendor/futures-macro/src/select.rs b/utshell-0.5.0/vendor/futures-macro/src/select.rs new file mode 100644 index 00000000..2789b3e6 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/src/select.rs @@ -0,0 +1,330 @@ +//! The futures-rs `select! macro implementation. + +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::{format_ident, quote}; +use syn::parse::{Parse, ParseStream}; +use syn::{parse_quote, Expr, Ident, Pat, Token}; + +mod kw { + syn::custom_keyword!(complete); +} + +struct Select { + // span of `complete`, then expression after `=> ...` + complete: Option, + default: Option, + normal_fut_exprs: Vec, + normal_fut_handlers: Vec<(Pat, Expr)>, +} + +#[allow(clippy::large_enum_variant)] +enum CaseKind { + Complete, + Default, + Normal(Pat, Expr), +} + +impl Parse for Select { + fn parse(input: ParseStream<'_>) -> syn::Result { + let mut select = Self { + complete: None, + default: None, + normal_fut_exprs: vec![], + normal_fut_handlers: vec![], + }; + + while !input.is_empty() { + let case_kind = if input.peek(kw::complete) { + // `complete` + if select.complete.is_some() { + return Err(input.error("multiple `complete` cases found, only one allowed")); + } + input.parse::()?; + CaseKind::Complete + } else if input.peek(Token![default]) { + // `default` + if select.default.is_some() { + return Err(input.error("multiple `default` cases found, only one allowed")); + } + input.parse::()?; + CaseKind::Default + } else { + // ` = ` + let pat = Pat::parse_multi_with_leading_vert(input)?; + input.parse::()?; + let expr = input.parse()?; + CaseKind::Normal(pat, expr) + }; + + // `=> ` + input.parse::]>()?; + let expr = input.parse::()?; + + // Commas after the expression are only optional if it's a `Block` + // or it is the last branch in the `match`. + let is_block = match expr { + Expr::Block(_) => true, + _ => false, + }; + if is_block || input.is_empty() { + input.parse::>()?; + } else { + input.parse::()?; + } + + match case_kind { + CaseKind::Complete => select.complete = Some(expr), + CaseKind::Default => select.default = Some(expr), + CaseKind::Normal(pat, fut_expr) => { + select.normal_fut_exprs.push(fut_expr); + select.normal_fut_handlers.push((pat, expr)); + } + } + } + + Ok(select) + } +} + +// Enum over all the cases in which the `select!` waiting has completed and the result +// can be processed. +// +// `enum __PrivResult<_1, _2, ...> { _1(_1), _2(_2), ..., Complete }` +fn declare_result_enum( + result_ident: Ident, + variants: usize, + complete: bool, + span: Span, +) -> (Vec, syn::ItemEnum) { + // "_0", "_1", "_2" + let variant_names: Vec = + (0..variants).map(|num| format_ident!("_{}", num, span = span)).collect(); + + let type_parameters = &variant_names; + let variants = &variant_names; + + let complete_variant = if complete { Some(quote!(Complete)) } else { None }; + + let enum_item = parse_quote! { + enum #result_ident<#(#type_parameters,)*> { + #( + #variants(#type_parameters), + )* + #complete_variant + } + }; + + (variant_names, enum_item) +} + +/// The `select!` macro. +pub(crate) fn select(input: TokenStream) -> TokenStream { + select_inner(input, true) +} + +/// The `select_biased!` macro. +pub(crate) fn select_biased(input: TokenStream) -> TokenStream { + select_inner(input, false) +} + +fn select_inner(input: TokenStream, random: bool) -> TokenStream { + let parsed = syn::parse_macro_input!(input as Select); + + // should be def_site, but that's unstable + let span = Span::call_site(); + + let enum_ident = Ident::new("__PrivResult", span); + + let (variant_names, enum_item) = declare_result_enum( + enum_ident.clone(), + parsed.normal_fut_exprs.len(), + parsed.complete.is_some(), + span, + ); + + // bind non-`Ident` future exprs w/ `let` + let mut future_let_bindings = Vec::with_capacity(parsed.normal_fut_exprs.len()); + let bound_future_names: Vec<_> = parsed + .normal_fut_exprs + .into_iter() + .zip(variant_names.iter()) + .map(|(expr, variant_name)| { + match expr { + syn::Expr::Path(path) => { + // Don't bind futures that are already a path. + // This prevents creating redundant stack space + // for them. + // Passing Futures by path requires those Futures to implement Unpin. + // We check for this condition here in order to be able to + // safely use Pin::new_unchecked(&mut #path) later on. + future_let_bindings.push(quote! { + __futures_crate::async_await::assert_fused_future(&#path); + __futures_crate::async_await::assert_unpin(&#path); + }); + path + } + _ => { + // Bind and pin the resulting Future on the stack. This is + // necessary to support direct select! calls on !Unpin + // Futures. The Future is not explicitly pinned here with + // a Pin call, but assumed as pinned. The actual Pin is + // created inside the poll() function below to defer the + // creation of the temporary pointer, which would otherwise + // increase the size of the generated Future. + // Safety: This is safe since the lifetime of the Future + // is totally constraint to the lifetime of the select! + // expression, and the Future can't get moved inside it + // (it is shadowed). + future_let_bindings.push(quote! { + let mut #variant_name = #expr; + }); + parse_quote! { #variant_name } + } + } + }) + .collect(); + + // For each future, make an `&mut dyn FnMut(&mut Context<'_>) -> Option>` + // to use for polling that individual future. These will then be put in an array. + let poll_functions = bound_future_names.iter().zip(variant_names.iter()).map( + |(bound_future_name, variant_name)| { + // Below we lazily create the Pin on the Future below. + // This is done in order to avoid allocating memory in the generator + // for the Pin variable. + // Safety: This is safe because one of the following condition applies: + // 1. The Future is passed by the caller by name, and we assert that + // it implements Unpin. + // 2. The Future is created in scope of the select! function and will + // not be moved for the duration of it. It is thereby stack-pinned + quote! { + let mut #variant_name = |__cx: &mut __futures_crate::task::Context<'_>| { + let mut #bound_future_name = unsafe { + __futures_crate::Pin::new_unchecked(&mut #bound_future_name) + }; + if __futures_crate::future::FusedFuture::is_terminated(&#bound_future_name) { + __futures_crate::None + } else { + __futures_crate::Some(__futures_crate::future::FutureExt::poll_unpin( + &mut #bound_future_name, + __cx, + ).map(#enum_ident::#variant_name)) + } + }; + let #variant_name: &mut dyn FnMut( + &mut __futures_crate::task::Context<'_> + ) -> __futures_crate::Option<__futures_crate::task::Poll<_>> = &mut #variant_name; + } + }, + ); + + let none_polled = if parsed.complete.is_some() { + quote! { + __futures_crate::task::Poll::Ready(#enum_ident::Complete) + } + } else { + quote! { + panic!("all futures in select! were completed,\ + but no `complete =>` handler was provided") + } + }; + + let branches = parsed.normal_fut_handlers.into_iter().zip(variant_names.iter()).map( + |((pat, expr), variant_name)| { + quote! { + #enum_ident::#variant_name(#pat) => { #expr }, + } + }, + ); + let branches = quote! { #( #branches )* }; + + let complete_branch = parsed.complete.map(|complete_expr| { + quote! { + #enum_ident::Complete => { #complete_expr }, + } + }); + + let branches = quote! { + #branches + #complete_branch + }; + + let await_select_fut = if parsed.default.is_some() { + // For select! with default this returns the Poll result + quote! { + __poll_fn(&mut __futures_crate::task::Context::from_waker( + __futures_crate::task::noop_waker_ref() + )) + } + } else { + quote! { + __futures_crate::future::poll_fn(__poll_fn).await + } + }; + + let execute_result_expr = if let Some(default_expr) = &parsed.default { + // For select! with default __select_result is a Poll, otherwise not + quote! { + match __select_result { + __futures_crate::task::Poll::Ready(result) => match result { + #branches + }, + _ => #default_expr + } + } + } else { + quote! { + match __select_result { + #branches + } + } + }; + + let shuffle = if random { + quote! { + __futures_crate::async_await::shuffle(&mut __select_arr); + } + } else { + quote!() + }; + + TokenStream::from(quote! { { + #enum_item + + let __select_result = { + #( #future_let_bindings )* + + let mut __poll_fn = |__cx: &mut __futures_crate::task::Context<'_>| { + let mut __any_polled = false; + + #( #poll_functions )* + + let mut __select_arr = [#( #variant_names ),*]; + #shuffle + for poller in &mut __select_arr { + let poller: &mut &mut dyn FnMut( + &mut __futures_crate::task::Context<'_> + ) -> __futures_crate::Option<__futures_crate::task::Poll<_>> = poller; + match poller(__cx) { + __futures_crate::Some(x @ __futures_crate::task::Poll::Ready(_)) => + return x, + __futures_crate::Some(__futures_crate::task::Poll::Pending) => { + __any_polled = true; + } + __futures_crate::None => {} + } + } + + if !__any_polled { + #none_polled + } else { + __futures_crate::task::Poll::Pending + } + }; + + #await_select_fut + }; + + #execute_result_expr + } }) +} diff --git a/utshell-0.5.0/vendor/futures-macro/src/stream_select.rs b/utshell-0.5.0/vendor/futures-macro/src/stream_select.rs new file mode 100644 index 00000000..9927b530 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-macro/src/stream_select.rs @@ -0,0 +1,113 @@ +use proc_macro2::TokenStream; +use quote::{format_ident, quote, ToTokens}; +use syn::{parse::Parser, punctuated::Punctuated, Expr, Index, Token}; + +/// The `stream_select!` macro. +pub(crate) fn stream_select(input: TokenStream) -> Result { + let args = Punctuated::::parse_terminated.parse2(input)?; + if args.len() < 2 { + return Ok(quote! { + compile_error!("stream select macro needs at least two arguments.") + }); + } + let generic_idents = (0..args.len()).map(|i| format_ident!("_{}", i)).collect::>(); + let field_idents = (0..args.len()).map(|i| format_ident!("__{}", i)).collect::>(); + let field_idents_2 = (0..args.len()).map(|i| format_ident!("___{}", i)).collect::>(); + let field_indices = (0..args.len()).map(Index::from).collect::>(); + let args = args.iter().map(|e| e.to_token_stream()); + + Ok(quote! { + { + #[derive(Debug)] + struct StreamSelect<#(#generic_idents),*> (#(Option<#generic_idents>),*); + + enum StreamEnum<#(#generic_idents),*> { + #( + #generic_idents(#generic_idents) + ),*, + None, + } + + impl __futures_crate::stream::Stream for StreamEnum<#(#generic_idents),*> + where #(#generic_idents: __futures_crate::stream::Stream + ::std::marker::Unpin,)* + { + type Item = ITEM; + + fn poll_next(mut self: ::std::pin::Pin<&mut Self>, cx: &mut __futures_crate::task::Context<'_>) -> __futures_crate::task::Poll> { + match self.get_mut() { + #( + Self::#generic_idents(#generic_idents) => ::std::pin::Pin::new(#generic_idents).poll_next(cx) + ),*, + Self::None => panic!("StreamEnum::None should never be polled!"), + } + } + } + + impl __futures_crate::stream::Stream for StreamSelect<#(#generic_idents),*> + where #(#generic_idents: __futures_crate::stream::Stream + ::std::marker::Unpin,)* + { + type Item = ITEM; + + fn poll_next(mut self: ::std::pin::Pin<&mut Self>, cx: &mut __futures_crate::task::Context<'_>) -> __futures_crate::task::Poll> { + let Self(#(ref mut #field_idents),*) = self.get_mut(); + #( + let mut #field_idents_2 = false; + )* + let mut any_pending = false; + { + let mut stream_array = [#(#field_idents.as_mut().map(|f| StreamEnum::#generic_idents(f)).unwrap_or(StreamEnum::None)),*]; + __futures_crate::async_await::shuffle(&mut stream_array); + + for mut s in stream_array { + if let StreamEnum::None = s { + continue; + } else { + match __futures_crate::stream::Stream::poll_next(::std::pin::Pin::new(&mut s), cx) { + r @ __futures_crate::task::Poll::Ready(Some(_)) => { + return r; + }, + __futures_crate::task::Poll::Pending => { + any_pending = true; + }, + __futures_crate::task::Poll::Ready(None) => { + match s { + #( + StreamEnum::#generic_idents(_) => { #field_idents_2 = true; } + ),*, + StreamEnum::None => panic!("StreamEnum::None should never be polled!"), + } + }, + } + } + } + } + #( + if #field_idents_2 { + *#field_idents = None; + } + )* + if any_pending { + __futures_crate::task::Poll::Pending + } else { + __futures_crate::task::Poll::Ready(None) + } + } + + fn size_hint(&self) -> (usize, Option) { + let mut s = (0, Some(0)); + #( + if let Some(new_hint) = self.#field_indices.as_ref().map(|s| s.size_hint()) { + s.0 += new_hint.0; + // We can change this out for `.zip` when the MSRV is 1.46.0 or higher. + s.1 = s.1.and_then(|a| new_hint.1.map(|b| a + b)); + } + )* + s + } + } + + StreamSelect(#(Some(#args)),*) + + } + }) +} diff --git a/utshell-0.5.0/vendor/futures-sink/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-sink/.cargo-checksum.json new file mode 100644 index 00000000..28c76502 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-sink/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"b5b85ca76f61d54448baa14cd1366f2eceb185385cd495112e0f88b76609bff6","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"a509e1ce84f285190130def6d2b9e3861988f9be725f7697f09fba347601d86f","src/lib.rs":"90c41f91e4b6764a218d4f337a9a46fba1e256f59f67b0afa5352ba92bf641c0"},"package":"9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-sink/Cargo.toml b/utshell-0.5.0/vendor/futures-sink/Cargo.toml new file mode 100644 index 00000000..73725b04 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-sink/Cargo.toml @@ -0,0 +1,33 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.36" +name = "futures-sink" +version = "0.3.30" +description = """ +The asynchronous `Sink` trait for the futures-rs library. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] + +[features] +alloc = [] +default = ["std"] +std = ["alloc"] diff --git a/utshell-0.5.0/vendor/futures-sink/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-sink/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-sink/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-sink/LICENSE-MIT b/utshell-0.5.0/vendor/futures-sink/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-sink/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-sink/README.md b/utshell-0.5.0/vendor/futures-sink/README.md new file mode 100644 index 00000000..1d683e95 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-sink/README.md @@ -0,0 +1,23 @@ +# futures-sink + +The asynchronous `Sink` trait for the futures-rs library. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-sink = "0.3" +``` + +The current `futures-sink` requires Rust 1.36 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-sink/src/lib.rs b/utshell-0.5.0/vendor/futures-sink/src/lib.rs new file mode 100644 index 00000000..0328740e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-sink/src/lib.rs @@ -0,0 +1,240 @@ +//! Asynchronous sinks +//! +//! This crate contains the `Sink` trait which allows values to be sent +//! asynchronously. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)] +// It cannot be included in the published code because this lints have false positives in the minimum required version. +#![cfg_attr(test, warn(single_use_lifetimes))] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] + +#[cfg(feature = "alloc")] +extern crate alloc; + +use core::ops::DerefMut; +use core::pin::Pin; +use core::task::{Context, Poll}; + +/// A `Sink` is a value into which other values can be sent, asynchronously. +/// +/// Basic examples of sinks include the sending side of: +/// +/// - Channels +/// - Sockets +/// - Pipes +/// +/// In addition to such "primitive" sinks, it's typical to layer additional +/// functionality, such as buffering, on top of an existing sink. +/// +/// Sending to a sink is "asynchronous" in the sense that the value may not be +/// sent in its entirety immediately. Instead, values are sent in a two-phase +/// way: first by initiating a send, and then by polling for completion. This +/// two-phase setup is analogous to buffered writing in synchronous code, where +/// writes often succeed immediately, but internally are buffered and are +/// *actually* written only upon flushing. +/// +/// In addition, the `Sink` may be *full*, in which case it is not even possible +/// to start the sending process. +/// +/// As with `Future` and `Stream`, the `Sink` trait is built from a few core +/// required methods, and a host of default methods for working in a +/// higher-level way. The `Sink::send_all` combinator is of particular +/// importance: you can use it to send an entire stream to a sink, which is +/// the simplest way to ultimately consume a stream. +#[must_use = "sinks do nothing unless polled"] +pub trait Sink { + /// The type of value produced by the sink when an error occurs. + type Error; + + /// Attempts to prepare the `Sink` to receive a value. + /// + /// This method must be called and return `Poll::Ready(Ok(()))` prior to + /// each call to `start_send`. + /// + /// This method returns `Poll::Ready` once the underlying sink is ready to + /// receive data. If this method returns `Poll::Pending`, the current task + /// is registered to be notified (via `cx.waker().wake_by_ref()`) when `poll_ready` + /// should be called again. + /// + /// In most cases, if the sink encounters an error, the sink will + /// permanently be unable to receive items. + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + + /// Begin the process of sending a value to the sink. + /// Each call to this function must be preceded by a successful call to + /// `poll_ready` which returned `Poll::Ready(Ok(()))`. + /// + /// As the name suggests, this method only *begins* the process of sending + /// the item. If the sink employs buffering, the item isn't fully processed + /// until the buffer is fully flushed. Since sinks are designed to work with + /// asynchronous I/O, the process of actually writing out the data to an + /// underlying object takes place asynchronously. **You *must* use + /// `poll_flush` or `poll_close` in order to guarantee completion of a + /// send**. + /// + /// Implementations of `poll_ready` and `start_send` will usually involve + /// flushing behind the scenes in order to make room for new messages. + /// It is only necessary to call `poll_flush` if you need to guarantee that + /// *all* of the items placed into the `Sink` have been sent. + /// + /// In most cases, if the sink encounters an error, the sink will + /// permanently be unable to receive items. + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error>; + + /// Flush any remaining output from this sink. + /// + /// Returns `Poll::Ready(Ok(()))` when no buffered items remain. If this + /// value is returned then it is guaranteed that all previous values sent + /// via `start_send` have been flushed. + /// + /// Returns `Poll::Pending` if there is more work left to do, in which + /// case the current task is scheduled (via `cx.waker().wake_by_ref()`) to wake up when + /// `poll_flush` should be called again. + /// + /// In most cases, if the sink encounters an error, the sink will + /// permanently be unable to receive items. + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + + /// Flush any remaining output and close this sink, if necessary. + /// + /// Returns `Poll::Ready(Ok(()))` when no buffered items remain and the sink + /// has been successfully closed. + /// + /// Returns `Poll::Pending` if there is more work left to do, in which + /// case the current task is scheduled (via `cx.waker().wake_by_ref()`) to wake up when + /// `poll_close` should be called again. + /// + /// If this function encounters an error, the sink should be considered to + /// have failed permanently, and no more `Sink` methods should be called. + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; +} + +impl + Unpin, Item> Sink for &mut S { + type Error = S::Error; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self).poll_ready(cx) + } + + fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + Pin::new(&mut **self).start_send(item) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self).poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut **self).poll_close(cx) + } +} + +impl Sink for Pin

+where + P: DerefMut + Unpin, + P::Target: Sink, +{ + type Error = >::Error; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_ready(cx) + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + self.get_mut().as_mut().start_send(item) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_flush(cx) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.get_mut().as_mut().poll_close(cx) + } +} + +#[cfg(feature = "alloc")] +mod if_alloc { + use super::*; + use core::convert::Infallible as Never; + + impl Sink for alloc::vec::Vec { + type Error = Never; + + fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn start_send(self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> { + // TODO: impl Unpin for Vec {} + unsafe { self.get_unchecked_mut() }.push(item); + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + } + + impl Sink for alloc::collections::VecDeque { + type Error = Never; + + fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn start_send(self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> { + // TODO: impl Unpin for Vec {} + unsafe { self.get_unchecked_mut() }.push_back(item); + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + } + + impl + Unpin, Item> Sink for alloc::boxed::Box { + type Error = S::Error; + + fn poll_ready( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + Pin::new(&mut **self).poll_ready(cx) + } + + fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + Pin::new(&mut **self).start_send(item) + } + + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + Pin::new(&mut **self).poll_flush(cx) + } + + fn poll_close( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + Pin::new(&mut **self).poll_close(cx) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-task/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-task/.cargo-checksum.json new file mode 100644 index 00000000..dba3b240 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5a775281eaadf4834ea23834fb053b72a9c8a301d3c99cc5255a4f147f5f0d56","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"6762ad0401a70d3b3e1faf6967b310de688da34c16174fd079ebc88fcff2cc4c","src/arc_wake.rs":"0e3f7d7883b75337b0b92ff55e477f0bf96f6eb08def7d953676a289fd9696ec","src/future_obj.rs":"20f210f33c6e61b3889d971fee2d9c23c1661da0e715d51c74f8c6d049c56135","src/lib.rs":"872e38468fd65eacbdd4ede61096eeeb296b41daad42f51a37172c250190315a","src/noop_waker.rs":"41246601dab77f69bf09257afc3321031a5a31a7eda51787029870eda9922356","src/spawn.rs":"cd0dafb52700e087a2793bb42d70da84e9e10181d5407ea74843d935f40cea02","src/waker.rs":"ed3e4e5f83016e253fe5faf4ded28d4f6ad64e01d015e4eb421004a1dd7b7639","src/waker_ref.rs":"3b65daca6d9236f653ff3be2599e5e30696416a6bab4902cdab2850a17942dd8"},"package":"38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-task/Cargo.toml b/utshell-0.5.0/vendor/futures-task/Cargo.toml new file mode 100644 index 00000000..52085847 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/Cargo.toml @@ -0,0 +1,37 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "futures-task" +version = "0.3.30" +description = """ +Tools for working with tasks. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] + +[dev-dependencies] + +[features] +alloc = [] +cfg-target-has-atomic = [] +default = ["std"] +std = ["alloc"] +unstable = [] diff --git a/utshell-0.5.0/vendor/futures-task/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-task/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-task/LICENSE-MIT b/utshell-0.5.0/vendor/futures-task/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-task/README.md b/utshell-0.5.0/vendor/futures-task/README.md new file mode 100644 index 00000000..1ebec2d7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/README.md @@ -0,0 +1,23 @@ +# futures-task + +Tools for working with tasks. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-task = "0.3" +``` + +The current `futures-task` requires Rust 1.56 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-task/src/arc_wake.rs b/utshell-0.5.0/vendor/futures-task/src/arc_wake.rs new file mode 100644 index 00000000..aa6de0fc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/arc_wake.rs @@ -0,0 +1,49 @@ +use alloc::sync::Arc; + +/// A way of waking up a specific task. +/// +/// By implementing this trait, types that are expected to be wrapped in an `Arc` +/// can be converted into [`Waker`] objects. +/// Those Wakers can be used to signal executors that a task it owns +/// is ready to be `poll`ed again. +/// +/// Currently, there are two ways to convert `ArcWake` into [`Waker`]: +/// +/// * [`waker`](super::waker()) converts `Arc` into [`Waker`]. +/// * [`waker_ref`](super::waker_ref()) converts `&Arc` into [`WakerRef`] that +/// provides access to a [`&Waker`][`Waker`]. +/// +/// [`Waker`]: std::task::Waker +/// [`WakerRef`]: super::WakerRef +// Note: Send + Sync required because `Arc` doesn't automatically imply +// those bounds, but `Waker` implements them. +pub trait ArcWake: Send + Sync { + /// Indicates that the associated task is ready to make progress and should + /// be `poll`ed. + /// + /// This function can be called from an arbitrary thread, including threads which + /// did not create the `ArcWake` based [`Waker`]. + /// + /// Executors generally maintain a queue of "ready" tasks; `wake` should place + /// the associated task onto this queue. + /// + /// [`Waker`]: std::task::Waker + fn wake(self: Arc) { + Self::wake_by_ref(&self) + } + + /// Indicates that the associated task is ready to make progress and should + /// be `poll`ed. + /// + /// This function can be called from an arbitrary thread, including threads which + /// did not create the `ArcWake` based [`Waker`]. + /// + /// Executors generally maintain a queue of "ready" tasks; `wake_by_ref` should place + /// the associated task onto this queue. + /// + /// This function is similar to [`wake`](ArcWake::wake), but must not consume the provided data + /// pointer. + /// + /// [`Waker`]: std::task::Waker + fn wake_by_ref(arc_self: &Arc); +} diff --git a/utshell-0.5.0/vendor/futures-task/src/future_obj.rs b/utshell-0.5.0/vendor/futures-task/src/future_obj.rs new file mode 100644 index 00000000..071392af --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/future_obj.rs @@ -0,0 +1,335 @@ +use core::{ + fmt, + future::Future, + marker::PhantomData, + mem, + pin::Pin, + task::{Context, Poll}, +}; + +/// A custom trait object for polling futures, roughly akin to +/// `Box + 'a>`. +/// +/// This custom trait object was introduced as currently it is not possible to +/// take `dyn Trait` by value and `Box` is not available in no_std +/// contexts. +pub struct LocalFutureObj<'a, T> { + future: *mut (dyn Future + 'static), + drop_fn: unsafe fn(*mut (dyn Future + 'static)), + _marker: PhantomData<&'a ()>, +} + +// As LocalFutureObj only holds pointers, even if we move it, the pointed to values won't move, +// so this is safe as long as we don't provide any way for a user to directly access the pointers +// and move their values. +impl Unpin for LocalFutureObj<'_, T> {} + +#[allow(single_use_lifetimes)] +#[allow(clippy::transmute_ptr_to_ptr)] +unsafe fn remove_future_lifetime<'a, T>( + ptr: *mut (dyn Future + 'a), +) -> *mut (dyn Future + 'static) { + mem::transmute(ptr) +} + +#[allow(single_use_lifetimes)] +unsafe fn remove_drop_lifetime<'a, T>( + ptr: unsafe fn(*mut (dyn Future + 'a)), +) -> unsafe fn(*mut (dyn Future + 'static)) { + mem::transmute(ptr) +} + +impl<'a, T> LocalFutureObj<'a, T> { + /// Create a `LocalFutureObj` from a custom trait object representation. + #[inline] + pub fn new + 'a>(f: F) -> Self { + Self { + future: unsafe { remove_future_lifetime(f.into_raw()) }, + drop_fn: unsafe { remove_drop_lifetime(F::drop) }, + _marker: PhantomData, + } + } + + /// Converts the `LocalFutureObj` into a `FutureObj`. + /// + /// # Safety + /// + /// To make this operation safe one has to ensure that the `UnsafeFutureObj` + /// instance from which this `LocalFutureObj` was created actually + /// implements `Send`. + #[inline] + pub unsafe fn into_future_obj(self) -> FutureObj<'a, T> { + FutureObj(self) + } +} + +impl fmt::Debug for LocalFutureObj<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("LocalFutureObj").finish() + } +} + +impl<'a, T> From> for LocalFutureObj<'a, T> { + #[inline] + fn from(f: FutureObj<'a, T>) -> Self { + f.0 + } +} + +impl Future for LocalFutureObj<'_, T> { + type Output = T; + + #[inline] + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + unsafe { Pin::new_unchecked(&mut *self.future).poll(cx) } + } +} + +impl Drop for LocalFutureObj<'_, T> { + fn drop(&mut self) { + unsafe { (self.drop_fn)(self.future) } + } +} + +/// A custom trait object for polling futures, roughly akin to +/// `Box + Send + 'a>`. +/// +/// This custom trait object was introduced as currently it is not possible to +/// take `dyn Trait` by value and `Box` is not available in no_std +/// contexts. +/// +/// You should generally not need to use this type outside of `no_std` or when +/// implementing `Spawn`, consider using `BoxFuture` instead. +pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>); + +impl Unpin for FutureObj<'_, T> {} +unsafe impl Send for FutureObj<'_, T> {} + +impl<'a, T> FutureObj<'a, T> { + /// Create a `FutureObj` from a custom trait object representation. + #[inline] + pub fn new + Send>(f: F) -> Self { + Self(LocalFutureObj::new(f)) + } +} + +impl fmt::Debug for FutureObj<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FutureObj").finish() + } +} + +impl Future for FutureObj<'_, T> { + type Output = T; + + #[inline] + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.0).poll(cx) + } +} + +/// A custom implementation of a future trait object for `FutureObj`, providing +/// a vtable with drop support. +/// +/// This custom representation is typically used only in `no_std` contexts, +/// where the default `Box`-based implementation is not available. +/// +/// # Safety +/// +/// See the safety notes on individual methods for what guarantees an +/// implementor must provide. +pub unsafe trait UnsafeFutureObj<'a, T>: 'a { + /// Convert an owned instance into a (conceptually owned) fat pointer. + /// + /// # Safety + /// + /// ## Implementor + /// + /// The trait implementor must guarantee that it is safe to convert the + /// provided `*mut (dyn Future + 'a)` into a `Pin<&mut (dyn + /// Future + 'a)>` and call methods on it, non-reentrantly, + /// until `UnsafeFutureObj::drop` is called with it. + #[allow(clippy::unnecessary_safety_doc)] + fn into_raw(self) -> *mut (dyn Future + 'a); + + /// Drops the future represented by the given fat pointer. + /// + /// # Safety + /// + /// ## Implementor + /// + /// The trait implementor must guarantee that it is safe to call this + /// function once per `into_raw` invocation. + /// + /// ## Caller + /// + /// The caller must ensure: + /// + /// * the pointer passed was obtained from an `into_raw` invocation from + /// this same trait object + /// * the pointer is not currently in use as a `Pin<&mut (dyn Future + 'a)>` + /// * the pointer must not be used again after this function is called + unsafe fn drop(ptr: *mut (dyn Future + 'a)); +} + +unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for &'a mut F +where + F: Future + Unpin + 'a, +{ + fn into_raw(self) -> *mut (dyn Future + 'a) { + self as *mut dyn Future + } + + unsafe fn drop(_ptr: *mut (dyn Future + 'a)) {} +} + +unsafe impl<'a, T> UnsafeFutureObj<'a, T> for &'a mut (dyn Future + Unpin + 'a) { + fn into_raw(self) -> *mut (dyn Future + 'a) { + self as *mut dyn Future + } + + unsafe fn drop(_ptr: *mut (dyn Future + 'a)) {} +} + +unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<&'a mut F> +where + F: Future + 'a, +{ + fn into_raw(self) -> *mut (dyn Future + 'a) { + unsafe { self.get_unchecked_mut() as *mut dyn Future } + } + + unsafe fn drop(_ptr: *mut (dyn Future + 'a)) {} +} + +unsafe impl<'a, T> UnsafeFutureObj<'a, T> for Pin<&'a mut (dyn Future + 'a)> { + fn into_raw(self) -> *mut (dyn Future + 'a) { + unsafe { self.get_unchecked_mut() as *mut dyn Future } + } + + unsafe fn drop(_ptr: *mut (dyn Future + 'a)) {} +} + +#[cfg(feature = "alloc")] +mod if_alloc { + use super::*; + use alloc::boxed::Box; + + unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box + where + F: Future + 'a, + { + fn into_raw(self) -> *mut (dyn Future + 'a) { + Box::into_raw(self) + } + + unsafe fn drop(ptr: *mut (dyn Future + 'a)) { + drop(Box::from_raw(ptr.cast::())) + } + } + + unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Box + 'a> { + fn into_raw(self) -> *mut (dyn Future + 'a) { + Box::into_raw(self) + } + + unsafe fn drop(ptr: *mut (dyn Future + 'a)) { + drop(Box::from_raw(ptr)) + } + } + + unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Box + Send + 'a> { + fn into_raw(self) -> *mut (dyn Future + 'a) { + Box::into_raw(self) + } + + unsafe fn drop(ptr: *mut (dyn Future + 'a)) { + drop(Box::from_raw(ptr)) + } + } + + unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin> + where + F: Future + 'a, + { + fn into_raw(self) -> *mut (dyn Future + 'a) { + let mut this = mem::ManuallyDrop::new(self); + unsafe { this.as_mut().get_unchecked_mut() as *mut _ } + } + + unsafe fn drop(ptr: *mut (dyn Future + 'a)) { + drop(Pin::from(Box::from_raw(ptr))) + } + } + + unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin + 'a>> { + fn into_raw(self) -> *mut (dyn Future + 'a) { + let mut this = mem::ManuallyDrop::new(self); + unsafe { this.as_mut().get_unchecked_mut() as *mut _ } + } + + unsafe fn drop(ptr: *mut (dyn Future + 'a)) { + drop(Pin::from(Box::from_raw(ptr))) + } + } + + unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin + Send + 'a>> { + fn into_raw(self) -> *mut (dyn Future + 'a) { + let mut this = mem::ManuallyDrop::new(self); + unsafe { this.as_mut().get_unchecked_mut() as *mut _ } + } + + unsafe fn drop(ptr: *mut (dyn Future + 'a)) { + drop(Pin::from(Box::from_raw(ptr))) + } + } + + impl<'a, F: Future + Send + 'a> From> for FutureObj<'a, ()> { + fn from(boxed: Box) -> Self { + Self::new(boxed) + } + } + + impl<'a> From + Send + 'a>> for FutureObj<'a, ()> { + fn from(boxed: Box + Send + 'a>) -> Self { + Self::new(boxed) + } + } + + impl<'a, F: Future + Send + 'a> From>> for FutureObj<'a, ()> { + fn from(boxed: Pin>) -> Self { + Self::new(boxed) + } + } + + impl<'a> From + Send + 'a>>> for FutureObj<'a, ()> { + fn from(boxed: Pin + Send + 'a>>) -> Self { + Self::new(boxed) + } + } + + impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { + fn from(boxed: Box) -> Self { + Self::new(boxed) + } + } + + impl<'a> From + 'a>> for LocalFutureObj<'a, ()> { + fn from(boxed: Box + 'a>) -> Self { + Self::new(boxed) + } + } + + impl<'a, F: Future + 'a> From>> for LocalFutureObj<'a, ()> { + fn from(boxed: Pin>) -> Self { + Self::new(boxed) + } + } + + impl<'a> From + 'a>>> for LocalFutureObj<'a, ()> { + fn from(boxed: Pin + 'a>>) -> Self { + Self::new(boxed) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-task/src/lib.rs b/utshell-0.5.0/vendor/futures-task/src/lib.rs new file mode 100644 index 00000000..33896d8b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/lib.rs @@ -0,0 +1,50 @@ +//! Tools for working with tasks. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub)] +// It cannot be included in the published code because this lints have false positives in the minimum required version. +#![cfg_attr(test, warn(single_use_lifetimes))] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] + +#[cfg(feature = "alloc")] +extern crate alloc; + +mod spawn; +pub use crate::spawn::{LocalSpawn, Spawn, SpawnError}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod arc_wake; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use crate::arc_wake::ArcWake; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod waker; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use crate::waker::waker; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod waker_ref; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use crate::waker_ref::{waker_ref, WakerRef}; + +mod future_obj; +pub use crate::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj}; + +mod noop_waker; +pub use crate::noop_waker::noop_waker; +pub use crate::noop_waker::noop_waker_ref; + +#[doc(no_inline)] +pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; diff --git a/utshell-0.5.0/vendor/futures-task/src/noop_waker.rs b/utshell-0.5.0/vendor/futures-task/src/noop_waker.rs new file mode 100644 index 00000000..f76a8a2e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/noop_waker.rs @@ -0,0 +1,63 @@ +//! Utilities for creating zero-cost wakers that don't do anything. + +use core::ptr::null; +use core::task::{RawWaker, RawWakerVTable, Waker}; + +unsafe fn noop_clone(_data: *const ()) -> RawWaker { + noop_raw_waker() +} + +unsafe fn noop(_data: *const ()) {} + +const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); + +const fn noop_raw_waker() -> RawWaker { + RawWaker::new(null(), &NOOP_WAKER_VTABLE) +} + +/// Create a new [`Waker`] which does +/// nothing when `wake()` is called on it. +/// +/// # Examples +/// +/// ``` +/// use futures::task::noop_waker; +/// let waker = noop_waker(); +/// waker.wake(); +/// ``` +#[inline] +pub fn noop_waker() -> Waker { + // FIXME: Since 1.46.0 we can use transmute in consts, allowing this function to be const. + unsafe { Waker::from_raw(noop_raw_waker()) } +} + +/// Get a static reference to a [`Waker`] which +/// does nothing when `wake()` is called on it. +/// +/// # Examples +/// +/// ``` +/// use futures::task::noop_waker_ref; +/// let waker = noop_waker_ref(); +/// waker.wake_by_ref(); +/// ``` +#[inline] +pub fn noop_waker_ref() -> &'static Waker { + struct SyncRawWaker(RawWaker); + unsafe impl Sync for SyncRawWaker {} + + static NOOP_WAKER_INSTANCE: SyncRawWaker = SyncRawWaker(noop_raw_waker()); + + // SAFETY: `Waker` is #[repr(transparent)] over its `RawWaker`. + unsafe { &*(&NOOP_WAKER_INSTANCE.0 as *const RawWaker as *const Waker) } +} + +#[cfg(test)] +mod tests { + #[test] + #[cfg(feature = "std")] + fn issue_2091_cross_thread_segfault() { + let waker = std::thread::spawn(super::noop_waker_ref).join().unwrap(); + waker.wake_by_ref(); + } +} diff --git a/utshell-0.5.0/vendor/futures-task/src/spawn.rs b/utshell-0.5.0/vendor/futures-task/src/spawn.rs new file mode 100644 index 00000000..4a9a45a4 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/spawn.rs @@ -0,0 +1,192 @@ +use crate::{FutureObj, LocalFutureObj}; +use core::fmt; + +/// The `Spawn` trait allows for pushing futures onto an executor that will +/// run them to completion. +pub trait Spawn { + /// Spawns a future that will be run to completion. + /// + /// # Errors + /// + /// The executor may be unable to spawn tasks. Spawn errors should + /// represent relatively rare scenarios, such as the executor + /// having been shut down so that it is no longer able to accept + /// tasks. + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError>; + + /// Determines whether the executor is able to spawn new tasks. + /// + /// This method will return `Ok` when the executor is *likely* + /// (but not guaranteed) to accept a subsequent spawn attempt. + /// Likewise, an `Err` return means that `spawn` is likely, but + /// not guaranteed, to yield an error. + #[inline] + fn status(&self) -> Result<(), SpawnError> { + Ok(()) + } +} + +/// The `LocalSpawn` is similar to [`Spawn`], but allows spawning futures +/// that don't implement `Send`. +pub trait LocalSpawn { + /// Spawns a future that will be run to completion. + /// + /// # Errors + /// + /// The executor may be unable to spawn tasks. Spawn errors should + /// represent relatively rare scenarios, such as the executor + /// having been shut down so that it is no longer able to accept + /// tasks. + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError>; + + /// Determines whether the executor is able to spawn new tasks. + /// + /// This method will return `Ok` when the executor is *likely* + /// (but not guaranteed) to accept a subsequent spawn attempt. + /// Likewise, an `Err` return means that `spawn` is likely, but + /// not guaranteed, to yield an error. + #[inline] + fn status_local(&self) -> Result<(), SpawnError> { + Ok(()) + } +} + +/// An error that occurred during spawning. +pub struct SpawnError { + _priv: (), +} + +impl fmt::Debug for SpawnError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("SpawnError").field(&"shutdown").finish() + } +} + +impl fmt::Display for SpawnError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Executor is shutdown") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for SpawnError {} + +impl SpawnError { + /// Spawning failed because the executor has been shut down. + pub fn shutdown() -> Self { + Self { _priv: () } + } + + /// Check whether spawning failed to the executor being shut down. + pub fn is_shutdown(&self) -> bool { + true + } +} + +impl Spawn for &Sp { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + Sp::spawn_obj(self, future) + } + + fn status(&self) -> Result<(), SpawnError> { + Sp::status(self) + } +} + +impl Spawn for &mut Sp { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + Sp::spawn_obj(self, future) + } + + fn status(&self) -> Result<(), SpawnError> { + Sp::status(self) + } +} + +impl LocalSpawn for &Sp { + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + Sp::spawn_local_obj(self, future) + } + + fn status_local(&self) -> Result<(), SpawnError> { + Sp::status_local(self) + } +} + +impl LocalSpawn for &mut Sp { + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + Sp::spawn_local_obj(self, future) + } + + fn status_local(&self) -> Result<(), SpawnError> { + Sp::status_local(self) + } +} + +#[cfg(feature = "alloc")] +mod if_alloc { + use super::*; + use alloc::{boxed::Box, rc::Rc}; + + impl Spawn for Box { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + (**self).spawn_obj(future) + } + + fn status(&self) -> Result<(), SpawnError> { + (**self).status() + } + } + + impl LocalSpawn for Box { + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + (**self).spawn_local_obj(future) + } + + fn status_local(&self) -> Result<(), SpawnError> { + (**self).status_local() + } + } + + impl Spawn for Rc { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + (**self).spawn_obj(future) + } + + fn status(&self) -> Result<(), SpawnError> { + (**self).status() + } + } + + impl LocalSpawn for Rc { + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + (**self).spawn_local_obj(future) + } + + fn status_local(&self) -> Result<(), SpawnError> { + (**self).status_local() + } + } + + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + impl Spawn for alloc::sync::Arc { + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { + (**self).spawn_obj(future) + } + + fn status(&self) -> Result<(), SpawnError> { + (**self).status() + } + } + + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + impl LocalSpawn for alloc::sync::Arc { + fn spawn_local_obj(&self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + (**self).spawn_local_obj(future) + } + + fn status_local(&self) -> Result<(), SpawnError> { + (**self).status_local() + } + } +} diff --git a/utshell-0.5.0/vendor/futures-task/src/waker.rs b/utshell-0.5.0/vendor/futures-task/src/waker.rs new file mode 100644 index 00000000..79112569 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/waker.rs @@ -0,0 +1,59 @@ +use super::arc_wake::ArcWake; +use alloc::sync::Arc; +use core::mem; +use core::task::{RawWaker, RawWakerVTable, Waker}; + +pub(super) fn waker_vtable() -> &'static RawWakerVTable { + &RawWakerVTable::new( + clone_arc_raw::, + wake_arc_raw::, + wake_by_ref_arc_raw::, + drop_arc_raw::, + ) +} + +/// Creates a [`Waker`] from an `Arc`. +/// +/// The returned [`Waker`] will call +/// [`ArcWake.wake()`](ArcWake::wake) if awoken. +pub fn waker(wake: Arc) -> Waker +where + W: ArcWake + 'static, +{ + let ptr = Arc::into_raw(wake).cast::<()>(); + + unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::())) } +} + +// FIXME: panics on Arc::clone / refcount changes could wreak havoc on the +// code here. We should guard against this by aborting. + +#[allow(clippy::redundant_clone)] // The clone here isn't actually redundant. +unsafe fn increase_refcount(data: *const ()) { + // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop + let arc = mem::ManuallyDrop::new(Arc::::from_raw(data.cast::())); + // Now increase refcount, but don't drop new refcount either + let _arc_clone: mem::ManuallyDrop<_> = arc.clone(); +} + +// used by `waker_ref` +unsafe fn clone_arc_raw(data: *const ()) -> RawWaker { + increase_refcount::(data); + RawWaker::new(data, waker_vtable::()) +} + +unsafe fn wake_arc_raw(data: *const ()) { + let arc: Arc = Arc::from_raw(data.cast::()); + ArcWake::wake(arc); +} + +// used by `waker_ref` +unsafe fn wake_by_ref_arc_raw(data: *const ()) { + // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop + let arc = mem::ManuallyDrop::new(Arc::::from_raw(data.cast::())); + ArcWake::wake_by_ref(&arc); +} + +unsafe fn drop_arc_raw(data: *const ()) { + drop(Arc::::from_raw(data.cast::())) +} diff --git a/utshell-0.5.0/vendor/futures-task/src/waker_ref.rs b/utshell-0.5.0/vendor/futures-task/src/waker_ref.rs new file mode 100644 index 00000000..aac41095 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-task/src/waker_ref.rs @@ -0,0 +1,66 @@ +use super::arc_wake::ArcWake; +use super::waker::waker_vtable; +use alloc::sync::Arc; +use core::marker::PhantomData; +use core::mem::ManuallyDrop; +use core::ops::Deref; +use core::task::{RawWaker, Waker}; + +/// A [`Waker`] that is only valid for a given lifetime. +/// +/// Note: this type implements [`Deref`](std::ops::Deref), +/// so it can be used to get a `&Waker`. +#[derive(Debug)] +pub struct WakerRef<'a> { + waker: ManuallyDrop, + _marker: PhantomData<&'a ()>, +} + +impl<'a> WakerRef<'a> { + /// Create a new [`WakerRef`] from a [`Waker`] reference. + #[inline] + pub fn new(waker: &'a Waker) -> Self { + // copy the underlying (raw) waker without calling a clone, + // as we won't call Waker::drop either. + let waker = ManuallyDrop::new(unsafe { core::ptr::read(waker) }); + Self { waker, _marker: PhantomData } + } + + /// Create a new [`WakerRef`] from a [`Waker`] that must not be dropped. + /// + /// Note: this if for rare cases where the caller created a [`Waker`] in + /// an unsafe way (that will be valid only for a lifetime to be determined + /// by the caller), and the [`Waker`] doesn't need to or must not be + /// destroyed. + #[inline] + pub fn new_unowned(waker: ManuallyDrop) -> Self { + Self { waker, _marker: PhantomData } + } +} + +impl Deref for WakerRef<'_> { + type Target = Waker; + + #[inline] + fn deref(&self) -> &Waker { + &self.waker + } +} + +/// Creates a reference to a [`Waker`] from a reference to `Arc`. +/// +/// The resulting [`Waker`] will call +/// [`ArcWake.wake()`](ArcWake::wake) if awoken. +#[inline] +pub fn waker_ref(wake: &Arc) -> WakerRef<'_> +where + W: ArcWake, +{ + // simply copy the pointer instead of using Arc::into_raw, + // as we don't actually keep a refcount by using ManuallyDrop.< + let ptr = Arc::as_ptr(wake).cast::<()>(); + + let waker = + ManuallyDrop::new(unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::())) }); + WakerRef::new_unowned(waker) +} diff --git a/utshell-0.5.0/vendor/futures-util/.cargo-checksum.json b/utshell-0.5.0/vendor/futures-util/.cargo-checksum.json new file mode 100644 index 00000000..cb289ae2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"33994b66c2e81f51a0d212b6d1fa87039b97578e2ce9ee270f0c31e31bc21174","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"4094b953bfd2bb2687df0c3c3deb05c307c14ac084e6a79878342b8ee56aa710","benches/bilock.rs":"6f59b71f9b9ca5751018a985eff0ea8d63d4cb6d18a17e672e17bc786b972c20","benches/flatten_unordered.rs":"79330465a5d8f2d6e450861e7ca2ed8ae7fe78a5fb221b6ab7121227810c1bcf","benches/futures_unordered.rs":"5eb8280be8d8fb7bd5fb103ce20db10f618f47e180a402105e0d5e9f8c9fe35a","benches/select.rs":"ca0a79bc3434f0fc025e0b0e37941ba1d592b40f36ce6544cdfede9f23e70581","src/abortable.rs":"38bcb3d48361e4cfa89cc2e225c5f1dc97129837da834d28b69cff3bbf5200a6","src/async_await/join_mod.rs":"8f83c0001df867f5eb47a4174bf4a0c0b548f8ff3be3b532e0c759ad981b87da","src/async_await/mod.rs":"9a81d2eb3c89a31e1241c50438ff92d08d5c1fa879f0f8d52bfbcc261aa88272","src/async_await/pending.rs":"7971ec1d5d89ad80390e2a0c51e396257b2e78f1436cce79ea2b55ac2f13b328","src/async_await/poll.rs":"440c19a89fd42b12da09ff48a69523b5a8a5baea0bcd2f860589a0ab996ed781","src/async_await/random.rs":"daf229cd01595d38ef0f6284865fe2f60ed3b8134f7a15c82564b97ff3a5be98","src/async_await/select_mod.rs":"414c7fb7923cfe21116d558bf3cd1a6ae5bef4ed01f9877f0e7cb3e42ee6c79d","src/async_await/stream_select_mod.rs":"83da70ea9ab215ba9c799539fdcc78de237881dffa8be312934422d88b21dacb","src/compat/compat01as03.rs":"6728ffd4f0a92d4e6aff8b7ff7916ad7ae20a317633d2739813a3b6ffc814204","src/compat/compat03as01.rs":"7cf29e57f8ee14b64123b3d2c16dceced25af5491a5ef81b655b2de2e9587fbe","src/compat/executor.rs":"3e40b4ccd905a99eab42c47fefc5502b530eef869158ce9ceaa28f8f1638436f","src/compat/mod.rs":"6cf3412f6a3f9ee8406118ea75de65468a83febc6ba61bdbad69261f0cfea02e","src/fns.rs":"f8e396128791169098a38a82c3c28aaa6dd5d40718635f7cc30b59b32f7110b8","src/future/abortable.rs":"373ce61c0c7c31718ff572113503bb88f55e3b49ed5d028a3dfafd69070f44c1","src/future/either.rs":"fb00002e68b5c46c8ded09e91efe0be7362c168a1ea00dc5906e1c8c7e38aaa4","src/future/future/catch_unwind.rs":"08b0ac049cdee28325d378209aa5bb4d91b14a29ddd9c2b0e5c661b61f9cfcfe","src/future/future/flatten.rs":"5bf9846cef8dec5dcc38b992653e11146bc149a0d3efc09b1f8268bd29de0b2b","src/future/future/fuse.rs":"65b80a1ba7556e2ef35ce8d23e47489a2a6eb6d1c3ef9ac4e080c63e69eaa07d","src/future/future/map.rs":"de607c2a4d80d2bddb590781c37328ddd294bb9d5064a9ecb99455244239b597","src/future/future/mod.rs":"d1cfcf1e45207705dd858bf4087b611792ac266d098ee7ed103d6a2b0d7bdd0f","src/future/future/remote_handle.rs":"2ae17a409569b32c78e20026a8ecdf667352c2597a4a0a8deefa4761fafcb223","src/future/future/shared.rs":"55b4b14859ce0dc3ea7555de24f286015f9f6e6028b6daa647926a0c2d4eade3","src/future/join.rs":"38b55fc7cdbbdaaa525e51f8ce09783dbbcb65eabfd7de9f46610593e0bbef17","src/future/join_all.rs":"4893629a9e5342f92fe58165dbb2ec80107c2ae4a0dbf97c9bba6847dbab0743","src/future/lazy.rs":"d161fc4108a97348c1becbbd5ba8fccb7225dcf1d81c097666f5c8b40718251d","src/future/maybe_done.rs":"559e41cb170f9fe7246d2a5b112527a9f9cbca63b8a5a872b3aa9c861f70f307","src/future/mod.rs":"22e7253ad13bce4f2aa4ee4f4023dc81a9131b01d4605cce33c0d8640b3b0113","src/future/option.rs":"73daca814800b91b707753dcfe074265372b0077fae2504ea6efddc713453579","src/future/pending.rs":"3967984d2061e6b201c407f28ba8392a21fc9ef7c0b9201e2e244110af0782c5","src/future/poll_fn.rs":"8e54bf57d60e01d496ae31df35e0b96868f4bda504c024a14f51ab723d67885f","src/future/poll_immediate.rs":"7e199fc102894c9095de17af602a7c8f05d427269aefce5d71cd5136d54659c0","src/future/ready.rs":"c9860ccd8ac529f44f66dee73ca9b9d7f1b1b3e5e9e4dc70c59640c752553d58","src/future/select.rs":"0c358a5ae079858f31c61cf6ea835205fdb9092d07536778440b975995d2626c","src/future/select_all.rs":"5b304210c34cc2bd84f7b1819baa30a68eea2ee578b10b243f5dd884ee9a4791","src/future/select_ok.rs":"dc35027db70c0111399c6ab6f7c977e6e7362f069a3891e4a62006c52643528e","src/future/try_future/into_future.rs":"d966bde7b06a88443f0efd877e95f91541778c4e713f3f4b66e00ca5d3f352b6","src/future/try_future/mod.rs":"991edb3b52903ceb3bcb6599d04d898509023cd038c5974f4872eaafa9748f08","src/future/try_future/try_flatten.rs":"16c02e1780bd312b8b386e41c1d9dd4bcc4e8ef10f26007364f857b3adcc6e99","src/future/try_future/try_flatten_err.rs":"130f3fc3fd95a19f4e4a50e69301106fab02f77d0faf3aac9c473a92b826c2ca","src/future/try_join.rs":"1836931f8ba32da41c6810e6acc0ea2fee75b74b3153e760c4542cb12b220540","src/future/try_join_all.rs":"5df69dcae742816b9ba68a0152a3a39a1154fccf22af36683158ae7abb5edc11","src/future/try_maybe_done.rs":"1cce46b2ee43ad51b7c5f9c02bc90a890af32bc549ce99098a2c8813508051e1","src/future/try_select.rs":"5d6187ace76b5f26e60c713a1fe9fcb9cbb0d161c5881c532ce9472a230b595d","src/io/allow_std.rs":"a125959c255fd344399fb0be19218a8ee7d613ce2485d6df9cdbc2ed5d3987df","src/io/buf_reader.rs":"46a1e24046c5bc2ab8f266e3d904281bec3ab4ba6c13d4213a52599b57b8de66","src/io/buf_writer.rs":"d6666b8dde60eefbb7fa69da4a2eea2b34ea0e4a85e21e5ac6e83cc680ea9140","src/io/chain.rs":"12f508fc39c3234a71a0f886505245c5d659aed09c7d874b1bd8ca0a0d456cf3","src/io/close.rs":"9832210a870637198fa58642cdf2779afab71f2e31a9953e663fa6854bd73ac7","src/io/copy.rs":"cb2466dcd7ea8bb1f07d00c03e66ed55abf71fe4be6937adc9f533ef9d99fb2d","src/io/copy_buf.rs":"e9a5f6aac8375e298bddb332f23d8b626d056ce452b58f772a05df7e2cd326cf","src/io/copy_buf_abortable.rs":"ced73b6420e892f220965315ed44ec774de4b44082ea53d0c9c64dbed72feed6","src/io/cursor.rs":"c12e9b82c6eff2108a5524b026d73fbb2c250072e8e3f673cc04d4da02a553b8","src/io/empty.rs":"6ae40b4bc8fc41572abad2d013285d78d8df445868d41fac77bde508ec9bc1a5","src/io/fill_buf.rs":"a3623e037db59efab227a769698098597f1b531a75b6c045e75f068c0137c738","src/io/flush.rs":"0c9b588dfd9da039dc123ba9448ac31ca21ee3da0a164a21f6c2c182183d43e2","src/io/into_sink.rs":"ab5bdb12bff62672175b69b8c9f5a4bbbea716b9cf89169ed6a723ab43da9df8","src/io/line_writer.rs":"16c151c68d89b7c2ab929c4a782539b1ad512b723eed9b544f50f1ff06f0b661","src/io/lines.rs":"137279b6b899ce438fb1b0ee9e6a412976f9f9db54fb7b961d2bad8787a26b1e","src/io/mod.rs":"eefa437d5ac91efb1328d9f50f10572206c7323be1c9919ca10e5ce1973f5c46","src/io/read.rs":"4ea675a83cec98a22c9c4731ff980209f0cf67f63c71871cd1deed53c1266345","src/io/read_exact.rs":"ddebd58db9f6766efa3f50543fb51b138538533921e1ee1da4621fff9c64efe2","src/io/read_line.rs":"e2829eb128f441c10dfc48f089a9dda7b6540753c9700f24cc9585e94affc11c","src/io/read_to_end.rs":"5e9e38dc087623dac5a3ae3ad329ed44ffe4f6205a78e546adadc3ffb76703fc","src/io/read_to_string.rs":"bef4cc292dd95fa9c850d0438ad0cf49a8cc4caf40a0384f763f8c9512ad9e79","src/io/read_until.rs":"354507ce95242a735940f0aaa6ef11cc7d6d0505ae148f05277ce6e7537f168a","src/io/read_vectored.rs":"bd7f442c92f2cb320075d0983b0d08d51c23078898d72e6c2857cf6c7ad4cec7","src/io/repeat.rs":"53bc472e4bd7d286bf90765ce574f13b7aabc871c4f04f712da7cea160491390","src/io/seek.rs":"9863e9fb6495eb6e1f8c45c283c8a6993b9bdb1462f75a3e525e135c6840dec7","src/io/sink.rs":"30a503631d196e5da92c386d0afc1af9656a5f7682456cfa2489a2c30a05cac5","src/io/split.rs":"b3702ba2f6e09ea014c809d45d9cc3bc7d20fc1e2a7281a8ca109656a9c421fe","src/io/take.rs":"c53fec5b5e8c3742b7e60e6ebfa625cf2e566fbea193fb1eee2f0a8e561d63d5","src/io/window.rs":"ec6a9d20a7b252a5b272a74afa32e2279d372b806840ab985eae17bc06a25d27","src/io/write.rs":"60670eb00f999f2e2c43b099759a7fb030325b323744d88c9d20f75926ec30df","src/io/write_all.rs":"8fcd4ff233650b5abd20f7b987000cac095d8de23445572de588dccf710623c6","src/io/write_all_vectored.rs":"53becf89c031bf4c3073f0903ce809eee7606b1b4fbeb518605875badba216d3","src/io/write_vectored.rs":"bc98ff4a709cb75cd9ffedefa8ef251089a49906b98e142d76447ddf4ac098bb","src/lib.rs":"515fe2c6fb0a7dd2a249a8411805bb7c36a6142466a405544a309346a009c9e9","src/lock/bilock.rs":"ac9ce60edba8faacee3f0aa48ad03e39510af20ad238d9aa7d0071a9186af3d2","src/lock/mod.rs":"17505464b0d63d00ccbfc0e512b4a0edb4c6d8fef98c6ac46d0dd43c995a0673","src/lock/mutex.rs":"745c68e571f84a7456681cd683b2b8eed28ea8b6d3f9a38337efad105a65e0b6","src/never.rs":"2066481ab04921269cfa768cb8b778a035ab6aa49ec404d9ac0aeb07a4bf6094","src/sink/buffer.rs":"33a7380f8232225a8e9ac5ee138fd095979efa3a64f9fecf5fcaf2e78fcbc355","src/sink/close.rs":"f2f31c884f048163abebd4f5a877b7b4306f7d02beae428325636fd00ed42ca9","src/sink/drain.rs":"60262bf3ef48c09b4d52e52953f9437d536e20f63690b73e975388751405d239","src/sink/err_into.rs":"ced2998b2b0b792d80f7543523c9e07e8f5d20a4336cae93084b995e46671b15","src/sink/fanout.rs":"66dcde056e0bbee4e0074d331838ed2743dc872ea1597f05d61970523dc34926","src/sink/feed.rs":"64b9d296d37aedde37e1421c459ebcd9a7e8814db905996996167850124f3b3f","src/sink/flush.rs":"fbba344f428ca7636541ba013f7db2ece480b404a9e0b421c5537552d61e2492","src/sink/map_err.rs":"0f68f444ef13fe7115164be855c3b7b1d269e1119e69fcdad1706988255641f1","src/sink/mod.rs":"37cf379170f3099992eb59f3181be4c4e4a5c2d3581dbe424d22ab360840d321","src/sink/send.rs":"56aaba9aa4a562e0af39473a5779206d91b0acb1fced4fc06cd8b959d1897524","src/sink/send_all.rs":"a8e4956604fe73e321b0a3896c2018bc5c27149f2862f8406112db140b3aa2dd","src/sink/unfold.rs":"5febcfb9295a79fe1187284d0d45055c787e399b00d73c0e85a0446ae2246d18","src/sink/with.rs":"850cd3b96304df1f38360a0bc60b02d485535e399ef7642acdd9add7876867d8","src/sink/with_flat_map.rs":"5e0f527b33ee8f1cc6a6a46d45b6d74dad5c735d88b2cb24e1cb34fdc6ef501b","src/stream/abortable.rs":"935d79aa44d793f4abe87ca27a9e4a20891500488cf942693cd2756d65b3aab2","src/stream/empty.rs":"5000c856186408a17f68bbef432d4a1a3edb7fb5a07ed8699342fef04b10a181","src/stream/futures_ordered.rs":"ca388121e9fae6ad250bd71b40da4bcf2eb0e56bdccd9086315141cd2a9759ee","src/stream/futures_unordered/abort.rs":"bdfece9f91accafd5122be36d628c37c5b219ac0eecec181267840fbb1e95a45","src/stream/futures_unordered/iter.rs":"01f8aaa2ac7ea493bf727a945424cc6ae695c9a0c289ac57cbb26697abb05827","src/stream/futures_unordered/mod.rs":"ef0abe0c4877e9e1cb74ed14e8afc5749c1756d5c4a5b7c8dc2a34211f04ce92","src/stream/futures_unordered/ready_to_run_queue.rs":"d2a3ab210175503cdec7d7625baf1e53f62b45fc1433d417d01ec21c33ffedba","src/stream/futures_unordered/task.rs":"2b780bcc97844bc0bdeced7bb4318066e86ba082c08c8628c9b2e92bfe36fb61","src/stream/iter.rs":"609fa821a460e901a54ae51f8da58220881157cef02b8b7b8c9e4321c2d05a23","src/stream/mod.rs":"9a0f4428681bf447c3b34eab0de58322ca0f0ab8cf9e0daf0e761d3fc9346e5e","src/stream/once.rs":"d7b70adabad1f10af711ac3dcef33fd4c287e9852fdb678406e7ff350ba8fd47","src/stream/pending.rs":"84aaa15c8bbb17a250da5b1b5f0c7f6717410915d63340a3fcbf098bebe19d6f","src/stream/poll_fn.rs":"35952ea514b8aade14a3934d7777006475f50bbf0c5b50141710e31637f980be","src/stream/poll_immediate.rs":"e7a53ff8275ebe89dab8f9b984cce2ee0fde0a828e540b77c5500ca017d5bb98","src/stream/repeat.rs":"e4e4a9b6f2fca72bcbf098c3ac0c4a41323a840741d4dce9d9416464b7e8bd0d","src/stream/repeat_with.rs":"525780d24f3f99152b879765ca6eab99bcc0c757dc6654b6635c099b93ea654d","src/stream/select.rs":"28eb422c0eca9fd02778a6003004471b3489db09746a70e617a506303ea8b81d","src/stream/select_all.rs":"19ef94abcf63fa9e46a73b6ab783642d2d069a015c7fa57fea36eeac7b6f2a20","src/stream/select_with_strategy.rs":"caa0f5d1fd02824b48a1cd2be13a6f96b532039eb88cf47ea5d2becf58595073","src/stream/stream/all.rs":"267a2cc251775fa0c60c6e41ae1e4a9611fc493be0fd1c3494ca75f24d60de51","src/stream/stream/any.rs":"a3eb3eecce02142b8eb95d0b8a62178f177c8152d63f52da5effbe3a4be45580","src/stream/stream/buffer_unordered.rs":"b0f7a1c72cee178e7bfd8990e6e426c1258eeba6d952b82c6be8e4cac0a054ea","src/stream/stream/buffered.rs":"e37d08d6a18090ba37079937575920cc8c7569f4183dba710d3f4b94c11da01b","src/stream/stream/catch_unwind.rs":"b2e801ff744d5d9e17177ec1156b0ab67bdd56b94c618ed8590344ec8a0f35e7","src/stream/stream/chain.rs":"809b6b5c8372f65341dc9810d39f60ae3bcf74a78f133b4ab8d289fb5f2a7cbb","src/stream/stream/chunks.rs":"9f872b473de14d2251584050f04d56eada9c3b1d8dc3e746bdd57c1f757bfc6f","src/stream/stream/collect.rs":"6e4d2d580189f7d3b6b294b6b17437e8e2570502f08c11786a71caac207f0309","src/stream/stream/concat.rs":"171ea941b45c0295ed978c3f318a449ea295e33cb4ea82c764f4e9e7c48ad5de","src/stream/stream/count.rs":"ff218aea3d2d2456c8163926ea0c357b2752e92578e5fd4bec6b789fe1246556","src/stream/stream/cycle.rs":"ed7e3d15e7b1adec5ad5789b0d3186b5995a3353cc974fb7f41a72f6d8ad4cbb","src/stream/stream/enumerate.rs":"fc7565d21d39565790859eeac9ae8dd74123a9d15b88258d3abe894f1876cc39","src/stream/stream/filter.rs":"5d871f416d41baff3733121f564229fe31bdf7dfaaeb78ab940fafba6ab4b7c6","src/stream/stream/filter_map.rs":"179045a5ab1295e77ab5cfea1964be69dc50984ef8ac9ee04034adf0a043514f","src/stream/stream/flatten.rs":"69493fc106a1447abe109fd54375bb30363f7bc419463a8f835e4c80d97f2186","src/stream/stream/flatten_unordered.rs":"dd5216fc0e34d09cc69ae6b3c4690efe8ff01404853756bf5aa6b92eb2e6750b","src/stream/stream/fold.rs":"75d61d4321db1bcbbdd1a0102d9ad60206275777167c008fc8953e50cd978a09","src/stream/stream/for_each.rs":"07bca889821bad18ff083e54abe679fbeb8cd19c086581c2f2722cba6b42263f","src/stream/stream/for_each_concurrent.rs":"4e1e7eb3d4ccfae0e8000651b75834e2960a7f9c62ab92dba35a0bdbbf5bbb21","src/stream/stream/forward.rs":"cd024ba1a3d5098d3ff2d5178a12e068916cc4307284b00c18dbc54b554a5560","src/stream/stream/fuse.rs":"061c5385f12f80c7906cb15ddb8f455ced6ce21d1de9a97de9db2616407c0cac","src/stream/stream/into_future.rs":"b46ad45cc03ddd778a9ffaa0d603c8ee0b411f49333100160959942cde9588bd","src/stream/stream/map.rs":"b91bdd5b33821a50c9b5034261a14f89ff1a9d541ab99b9d9a6921b12a5d434e","src/stream/stream/mod.rs":"df12e6db862e46850e06c2aad0fdcad6acccb1419120cf0cb9ce94b98890c5fd","src/stream/stream/next.rs":"7b4d5a22b5e00aa191ea82346bb1f392121cc68692864a8230e462d59e622928","src/stream/stream/peek.rs":"2e08e6990c31186c97edb21737f83fe8640a19561062879af83090935aef99cf","src/stream/stream/ready_chunks.rs":"7e17c49ff29c106c13a2ec13fb05f32ff048e482b47a157d3965bd03c38c01c2","src/stream/stream/scan.rs":"54489c8efef60dbf3c35ee803afee5c5ea7c364fb9b68939a04956e46febb856","src/stream/stream/select_next_some.rs":"0094eccc96cfe78d9b6d0a9bdb82cada8fb7929770a3ac00ffcb5441d7dc4f51","src/stream/stream/skip.rs":"61f7ec7fe25663d2c87cffaad19ed27eda032842edb8af731b521025b244f120","src/stream/stream/skip_while.rs":"6f114a3fa538bd479e4fa24d8aa0e0e0454613643a97c44242c5683ae7293b82","src/stream/stream/split.rs":"685187ea9a68e604b8a89c321329484288b94fc2b4e204fa1ca537aab0e8360f","src/stream/stream/take.rs":"57d381b482c3d584c4c26b0e15941bc2ea58e3f39a2e5c74391a2ee7b825cc8c","src/stream/stream/take_until.rs":"0f1fa7d158192a5dee32392dfdd062c15dab6d246b0ca267e91aae490d7d7fdb","src/stream/stream/take_while.rs":"2f57a6e5b903c045da642e9a40eb19dabbc612a80a6ce8098df1a1973555f108","src/stream/stream/then.rs":"c995c6b0d9151927b26b10fba70e135dfc41224b969d1367dc8c11697218c1e9","src/stream/stream/unzip.rs":"e7beedc2192604e0091ac3d0265b487127a37c780198838f6419c21ef1b38df0","src/stream/stream/zip.rs":"3890b40daea00341fac6ac977de0b534d1ec7cdaabece44af5df2ca56026fe62","src/stream/try_stream/and_then.rs":"6f92b333955f5ec30fddf8e087e3f60ebf53a054769fc72c80bbccdf13a9431e","src/stream/try_stream/into_async_read.rs":"5b200c76ccb95460d94286ca8e63f5454940eb62b5f15aae998da48aa06fbffd","src/stream/try_stream/into_stream.rs":"4fee94e89956a42871fc4a0cdba7ae1b7d4265e884528799cd227c9dd851acce","src/stream/try_stream/mod.rs":"865e920e0409730bb61e84f56763d21e83bfe6b56126f8330633d4b9505b925b","src/stream/try_stream/or_else.rs":"473ca77e0e81a1a0834d2d882076b8823a5a3027b2d7d78f887be2d5edfd0de3","src/stream/try_stream/try_all.rs":"58a4c9abe3b2d6ad2debcfc09701bb828732c9d7edf2a42f12a74beff5ae2db0","src/stream/try_stream/try_any.rs":"822f21af5cb27b1269046af076415216fdfc9e0b9fd877cb6e7d65c69d659471","src/stream/try_stream/try_buffer_unordered.rs":"64e698ea6aefbe7e32d48e737553b20b9cde5c258963bb20486b48b7d6899660","src/stream/try_stream/try_buffered.rs":"38f60d7290f44471a02084c6b394b754c224a84ee8d2ba01c08568168b48a21f","src/stream/try_stream/try_chunks.rs":"69c4d85a256250d73c6372d8047e6055da7eac918cb5d7ef4f3697898f4dcb4c","src/stream/try_stream/try_collect.rs":"979920e3034dad6c75961e3f6b4c0234691db7063eca1a05562cc5d41f2943c1","src/stream/try_stream/try_concat.rs":"f2330ebeeab30273e9ac0e8600bfe2f405ce671f6386e688b3afb1d2fdd7c2c6","src/stream/try_stream/try_filter.rs":"1344e9aea05e2d0078f30caff176a99e1ccb8fcdf0a287817abc82fbaf09c48b","src/stream/try_stream/try_filter_map.rs":"285e7ea875a3ea3e16942c1b1acae5a1cb26b9bac476dce3903547cb99306602","src/stream/try_stream/try_flatten.rs":"e05614d86a27ab8386476eea35fd424c07e5f7f99cf0401d63a6655eb7ca1247","src/stream/try_stream/try_flatten_unordered.rs":"1cc4c4a5ea0a8db3010958f34fb1886dcfbd2e1584082d2004030eb70b13cd6c","src/stream/try_stream/try_fold.rs":"b96aa2fe1a16f625d5045028a86ff8684dcf5198ef8c7c072f52f39aeaa8b619","src/stream/try_stream/try_for_each.rs":"3f3901d618333b740d470eb02fcbb645df92483493872298bb7bd0382646028a","src/stream/try_stream/try_for_each_concurrent.rs":"78a94a77f329862c2a245ec3add97e49c534985f0d9da98f205b7fa3c7c08df3","src/stream/try_stream/try_next.rs":"6e29473153db1435906e79f7eaa13ce9da842d4528ba9eb1c0034665feacc565","src/stream/try_stream/try_ready_chunks.rs":"e8a658f5e48bb5c12b59998adbc5534f7eb830d0a60b53c0a3acd945752166fd","src/stream/try_stream/try_skip_while.rs":"7c2fa31fe8b0b4e59c5d7f2972c8d9f83e8f01a687b08f5cd631f92a14b402f1","src/stream/try_stream/try_take_while.rs":"2783664637aff0442f0c9204d35600139c941332310f70495cbc4dc345cae99d","src/stream/try_stream/try_unfold.rs":"aaf0f4857a4ec8233ac842ae509f29e5a210827a0bb40cfc0dc3e858f153d2b4","src/stream/unfold.rs":"201428f3dfcd10c556367d9aa87c4ae20fc9db6396380674b3b8c43b5d2a307e","src/task/mod.rs":"781f6d7d2484d6bd88ef9533d5c4729eeb8d4ee9bb8b9f4bad7049a78e190c32","src/task/spawn.rs":"8ff3a3652d8d2cb45717324b6ead9c3f111629e7eb0c0b33d3639a0e7c5bbf3e","src/unfold_state.rs":"ffe848071a99d6afcdbe8281a8a77a559a7dde434fc41f734c90e6b9b5d8a5af"},"package":"3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures-util/Cargo.toml b/utshell-0.5.0/vendor/futures-util/Cargo.toml new file mode 100644 index 00000000..c95816a2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/Cargo.toml @@ -0,0 +1,135 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "futures-util" +version = "0.3.30" +description = """ +Common utilities and extension traits for the futures-rs library. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[dependencies.futures-channel] +version = "0.3.30" +features = ["std"] +optional = true +default-features = false + +[dependencies.futures-core] +version = "0.3.30" +default-features = false + +[dependencies.futures-io] +version = "0.3.30" +features = ["std"] +optional = true +default-features = false + +[dependencies.futures-macro] +version = "=0.3.30" +optional = true +default-features = false + +[dependencies.futures-sink] +version = "0.3.30" +optional = true +default-features = false + +[dependencies.futures-task] +version = "0.3.30" +default-features = false + +[dependencies.futures_01] +version = "0.1.25" +optional = true +package = "futures" + +[dependencies.memchr] +version = "2.2" +optional = true + +[dependencies.pin-project-lite] +version = "0.2.6" + +[dependencies.pin-utils] +version = "0.1.0" + +[dependencies.slab] +version = "0.4.2" +optional = true + +[dependencies.tokio-io] +version = "0.1.9" +optional = true + +[dev-dependencies.tokio] +version = "0.1.11" + +[features] +alloc = [ + "futures-core/alloc", + "futures-task/alloc", +] +async-await = [] +async-await-macro = [ + "async-await", + "futures-macro", +] +bilock = [] +cfg-target-has-atomic = [] +channel = [ + "std", + "futures-channel", +] +compat = [ + "std", + "futures_01", +] +default = [ + "std", + "async-await", + "async-await-macro", +] +io = [ + "std", + "futures-io", + "memchr", +] +io-compat = [ + "io", + "compat", + "tokio-io", +] +portable-atomic = ["futures-core/portable-atomic"] +sink = ["futures-sink"] +std = [ + "alloc", + "futures-core/std", + "futures-task/std", + "slab", +] +unstable = [ + "futures-core/unstable", + "futures-task/unstable", +] +write-all-vectored = ["io"] diff --git a/utshell-0.5.0/vendor/futures-util/LICENSE-APACHE b/utshell-0.5.0/vendor/futures-util/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures-util/LICENSE-MIT b/utshell-0.5.0/vendor/futures-util/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures-util/README.md b/utshell-0.5.0/vendor/futures-util/README.md new file mode 100644 index 00000000..60e2c210 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/README.md @@ -0,0 +1,23 @@ +# futures-util + +Common utilities and extension traits for the futures-rs library. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures-util = "0.3" +``` + +The current `futures-util` requires Rust 1.56 or later. + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures-util/benches/bilock.rs b/utshell-0.5.0/vendor/futures-util/benches/bilock.rs new file mode 100644 index 00000000..013f3351 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/benches/bilock.rs @@ -0,0 +1,68 @@ +#![feature(test)] +#![cfg(feature = "bilock")] + +extern crate test; + +use futures::task::Poll; +use futures_test::task::noop_context; +use futures_util::lock::BiLock; + +use crate::test::Bencher; + +#[bench] +fn contended(b: &mut Bencher) { + let mut context = noop_context(); + + b.iter(|| { + let (x, y) = BiLock::new(1); + + for _ in 0..1000 { + let x_guard = match x.poll_lock(&mut context) { + Poll::Ready(guard) => guard, + _ => panic!(), + }; + + // Try poll second lock while first lock still holds the lock + match y.poll_lock(&mut context) { + Poll::Pending => (), + _ => panic!(), + }; + + drop(x_guard); + + let y_guard = match y.poll_lock(&mut context) { + Poll::Ready(guard) => guard, + _ => panic!(), + }; + + drop(y_guard); + } + (x, y) + }); +} + +#[bench] +fn lock_unlock(b: &mut Bencher) { + let mut context = noop_context(); + + b.iter(|| { + let (x, y) = BiLock::new(1); + + for _ in 0..1000 { + let x_guard = match x.poll_lock(&mut context) { + Poll::Ready(guard) => guard, + _ => panic!(), + }; + + drop(x_guard); + + let y_guard = match y.poll_lock(&mut context) { + Poll::Ready(guard) => guard, + _ => panic!(), + }; + + drop(y_guard); + } + (x, y) + }) +} diff --git a/utshell-0.5.0/vendor/futures-util/benches/flatten_unordered.rs b/utshell-0.5.0/vendor/futures-util/benches/flatten_unordered.rs new file mode 100644 index 00000000..517b2816 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/benches/flatten_unordered.rs @@ -0,0 +1,58 @@ +#![feature(test)] + +extern crate test; +use crate::test::Bencher; + +use futures::channel::oneshot; +use futures::executor::block_on; +use futures::future; +use futures::stream::{self, StreamExt}; +use futures::task::Poll; +use futures_util::FutureExt; +use std::collections::VecDeque; +use std::thread; + +#[bench] +fn oneshot_streams(b: &mut Bencher) { + const STREAM_COUNT: usize = 10_000; + const STREAM_ITEM_COUNT: usize = 1; + + b.iter(|| { + let mut txs = VecDeque::with_capacity(STREAM_COUNT); + let mut rxs = Vec::new(); + + for _ in 0..STREAM_COUNT { + let (tx, rx) = oneshot::channel(); + txs.push_back(tx); + rxs.push(rx); + } + + thread::spawn(move || { + let mut last = 1; + while let Some(tx) = txs.pop_front() { + let _ = tx.send(stream::iter(last..last + STREAM_ITEM_COUNT)); + last += STREAM_ITEM_COUNT; + } + }); + + let mut flatten = stream::iter(rxs) + .map(|recv| recv.into_stream().map(|val| val.unwrap()).flatten()) + .flatten_unordered(None); + + block_on(future::poll_fn(move |cx| { + let mut count = 0; + loop { + match flatten.poll_next_unpin(cx) { + Poll::Ready(None) => break, + Poll::Ready(Some(_)) => { + count += 1; + } + _ => {} + } + } + assert_eq!(count, STREAM_COUNT * STREAM_ITEM_COUNT); + + Poll::Ready(()) + })) + }); +} diff --git a/utshell-0.5.0/vendor/futures-util/benches/futures_unordered.rs b/utshell-0.5.0/vendor/futures-util/benches/futures_unordered.rs new file mode 100644 index 00000000..d5fe7a59 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/benches/futures_unordered.rs @@ -0,0 +1,43 @@ +#![feature(test)] + +extern crate test; +use crate::test::Bencher; + +use futures::channel::oneshot; +use futures::executor::block_on; +use futures::future; +use futures::stream::{FuturesUnordered, StreamExt}; +use futures::task::Poll; +use std::collections::VecDeque; +use std::thread; + +#[bench] +fn oneshots(b: &mut Bencher) { + const NUM: usize = 10_000; + + b.iter(|| { + let mut txs = VecDeque::with_capacity(NUM); + let mut rxs = FuturesUnordered::new(); + + for _ in 0..NUM { + let (tx, rx) = oneshot::channel(); + txs.push_back(tx); + rxs.push(rx); + } + + thread::spawn(move || { + while let Some(tx) = txs.pop_front() { + let _ = tx.send("hello"); + } + }); + + block_on(future::poll_fn(move |cx| { + loop { + if let Poll::Ready(None) = rxs.poll_next_unpin(cx) { + break; + } + } + Poll::Ready(()) + })) + }); +} diff --git a/utshell-0.5.0/vendor/futures-util/benches/select.rs b/utshell-0.5.0/vendor/futures-util/benches/select.rs new file mode 100644 index 00000000..5410a952 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/benches/select.rs @@ -0,0 +1,35 @@ +#![feature(test)] + +extern crate test; +use crate::test::Bencher; + +use futures::executor::block_on; +use futures::stream::{repeat, select, StreamExt}; + +#[bench] +fn select_streams(b: &mut Bencher) { + const STREAM_COUNT: usize = 10_000; + + b.iter(|| { + let stream1 = repeat(1).take(STREAM_COUNT); + let stream2 = repeat(2).take(STREAM_COUNT); + let stream3 = repeat(3).take(STREAM_COUNT); + let stream4 = repeat(4).take(STREAM_COUNT); + let stream5 = repeat(5).take(STREAM_COUNT); + let stream6 = repeat(6).take(STREAM_COUNT); + let stream7 = repeat(7).take(STREAM_COUNT); + let count = block_on(async { + let count = select( + stream1, + select( + stream2, + select(stream3, select(stream4, select(stream5, select(stream6, stream7)))), + ), + ) + .count() + .await; + count + }); + assert_eq!(count, STREAM_COUNT * 7); + }); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/abortable.rs b/utshell-0.5.0/vendor/futures-util/src/abortable.rs new file mode 100644 index 00000000..9dbcfc2b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/abortable.rs @@ -0,0 +1,209 @@ +use crate::task::AtomicWaker; +use alloc::sync::Arc; +use core::fmt; +use core::pin::Pin; +use core::sync::atomic::{AtomicBool, Ordering}; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_core::Stream; +use pin_project_lite::pin_project; + +pin_project! { + /// A future/stream which can be remotely short-circuited using an `AbortHandle`. + #[derive(Debug, Clone)] + #[must_use = "futures/streams do nothing unless you poll them"] + pub struct Abortable { + #[pin] + task: T, + inner: Arc, + } +} + +impl Abortable { + /// Creates a new `Abortable` future/stream using an existing `AbortRegistration`. + /// `AbortRegistration`s can be acquired through `AbortHandle::new`. + /// + /// When `abort` is called on the handle tied to `reg` or if `abort` has + /// already been called, the future/stream will complete immediately without making + /// any further progress. + /// + /// # Examples: + /// + /// Usage with futures: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::{Abortable, AbortHandle, Aborted}; + /// + /// let (abort_handle, abort_registration) = AbortHandle::new_pair(); + /// let future = Abortable::new(async { 2 }, abort_registration); + /// abort_handle.abort(); + /// assert_eq!(future.await, Err(Aborted)); + /// # }); + /// ``` + /// + /// Usage with streams: + /// + /// ``` + /// # futures::executor::block_on(async { + /// # use futures::future::{Abortable, AbortHandle}; + /// # use futures::stream::{self, StreamExt}; + /// + /// let (abort_handle, abort_registration) = AbortHandle::new_pair(); + /// let mut stream = Abortable::new(stream::iter(vec![1, 2, 3]), abort_registration); + /// abort_handle.abort(); + /// assert_eq!(stream.next().await, None); + /// # }); + /// ``` + pub fn new(task: T, reg: AbortRegistration) -> Self { + Self { task, inner: reg.inner } + } + + /// Checks whether the task has been aborted. Note that all this + /// method indicates is whether [`AbortHandle::abort`] was *called*. + /// This means that it will return `true` even if: + /// * `abort` was called after the task had completed. + /// * `abort` was called while the task was being polled - the task may still be running and + /// will not be stopped until `poll` returns. + pub fn is_aborted(&self) -> bool { + self.inner.aborted.load(Ordering::Relaxed) + } +} + +/// A registration handle for an `Abortable` task. +/// Values of this type can be acquired from `AbortHandle::new` and are used +/// in calls to `Abortable::new`. +#[derive(Debug)] +pub struct AbortRegistration { + pub(crate) inner: Arc, +} + +impl AbortRegistration { + /// Create an [`AbortHandle`] from the given [`AbortRegistration`]. + /// + /// The created [`AbortHandle`] is functionally the same as any other + /// [`AbortHandle`]s that are associated with the same [`AbortRegistration`], + /// such as the one created by [`AbortHandle::new_pair`]. + pub fn handle(&self) -> AbortHandle { + AbortHandle { inner: self.inner.clone() } + } +} + +/// A handle to an `Abortable` task. +#[derive(Debug, Clone)] +pub struct AbortHandle { + inner: Arc, +} + +impl AbortHandle { + /// Creates an (`AbortHandle`, `AbortRegistration`) pair which can be used + /// to abort a running future or stream. + /// + /// This function is usually paired with a call to [`Abortable::new`]. + pub fn new_pair() -> (Self, AbortRegistration) { + let inner = + Arc::new(AbortInner { waker: AtomicWaker::new(), aborted: AtomicBool::new(false) }); + + (Self { inner: inner.clone() }, AbortRegistration { inner }) + } +} + +// Inner type storing the waker to awaken and a bool indicating that it +// should be aborted. +#[derive(Debug)] +pub(crate) struct AbortInner { + pub(crate) waker: AtomicWaker, + pub(crate) aborted: AtomicBool, +} + +/// Indicator that the `Abortable` task was aborted. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Aborted; + +impl fmt::Display for Aborted { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "`Abortable` future has been aborted") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Aborted {} + +impl Abortable { + fn try_poll( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + poll: impl Fn(Pin<&mut T>, &mut Context<'_>) -> Poll, + ) -> Poll> { + // Check if the task has been aborted + if self.is_aborted() { + return Poll::Ready(Err(Aborted)); + } + + // attempt to complete the task + if let Poll::Ready(x) = poll(self.as_mut().project().task, cx) { + return Poll::Ready(Ok(x)); + } + + // Register to receive a wakeup if the task is aborted in the future + self.inner.waker.register(cx.waker()); + + // Check to see if the task was aborted between the first check and + // registration. + // Checking with `is_aborted` which uses `Relaxed` is sufficient because + // `register` introduces an `AcqRel` barrier. + if self.is_aborted() { + return Poll::Ready(Err(Aborted)); + } + + Poll::Pending + } +} + +impl Future for Abortable +where + Fut: Future, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.try_poll(cx, |fut, cx| fut.poll(cx)) + } +} + +impl Stream for Abortable +where + St: Stream, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.try_poll(cx, |stream, cx| stream.poll_next(cx)).map(Result::ok).map(Option::flatten) + } +} + +impl AbortHandle { + /// Abort the `Abortable` stream/future associated with this handle. + /// + /// Notifies the Abortable task associated with this handle that it + /// should abort. Note that if the task is currently being polled on + /// another thread, it will not immediately stop running. Instead, it will + /// continue to run until its poll method returns. + pub fn abort(&self) { + self.inner.aborted.store(true, Ordering::Relaxed); + self.inner.waker.wake(); + } + + /// Checks whether [`AbortHandle::abort`] was *called* on any associated + /// [`AbortHandle`]s, which includes all the [`AbortHandle`]s linked with + /// the same [`AbortRegistration`]. This means that it will return `true` + /// even if: + /// * `abort` was called after the task had completed. + /// * `abort` was called while the task was being polled - the task may still be running and + /// will not be stopped until `poll` returns. + /// + /// This operation has a Relaxed ordering. + pub fn is_aborted(&self) -> bool { + self.inner.aborted.load(Ordering::Relaxed) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/join_mod.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/join_mod.rs new file mode 100644 index 00000000..28f3b232 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/join_mod.rs @@ -0,0 +1,110 @@ +//! The `join` macro. + +macro_rules! document_join_macro { + ($join:item $try_join:item) => { + /// Polls multiple futures simultaneously, returning a tuple + /// of all results once complete. + /// + /// While `join!(a, b)` is similar to `(a.await, b.await)`, + /// `join!` polls both futures concurrently and therefore is more efficient. + /// + /// This macro is only usable inside of async functions, closures, and blocks. + /// It is also gated behind the `async-await` feature of this library, which is + /// activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::join; + /// + /// let a = async { 1 }; + /// let b = async { 2 }; + /// assert_eq!(join!(a, b), (1, 2)); + /// + /// // `join!` is variadic, so you can pass any number of futures + /// let c = async { 3 }; + /// let d = async { 4 }; + /// let e = async { 5 }; + /// assert_eq!(join!(c, d, e), (3, 4, 5)); + /// # }); + /// ``` + $join + + /// Polls multiple futures simultaneously, resolving to a [`Result`] containing + /// either a tuple of the successful outputs or an error. + /// + /// `try_join!` is similar to [`join!`], but completes immediately if any of + /// the futures return an error. + /// + /// This macro is only usable inside of async functions, closures, and blocks. + /// It is also gated behind the `async-await` feature of this library, which is + /// activated by default. + /// + /// # Examples + /// + /// When used on multiple futures that return `Ok`, `try_join!` will return + /// `Ok` of a tuple of the values: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::try_join; + /// + /// let a = async { Ok::(1) }; + /// let b = async { Ok::(2) }; + /// assert_eq!(try_join!(a, b), Ok((1, 2))); + /// + /// // `try_join!` is variadic, so you can pass any number of futures + /// let c = async { Ok::(3) }; + /// let d = async { Ok::(4) }; + /// let e = async { Ok::(5) }; + /// assert_eq!(try_join!(c, d, e), Ok((3, 4, 5))); + /// # }); + /// ``` + /// + /// If one of the futures resolves to an error, `try_join!` will return + /// that error: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::try_join; + /// + /// let a = async { Ok::(1) }; + /// let b = async { Err::(2) }; + /// + /// assert_eq!(try_join!(a, b), Err(2)); + /// # }); + /// ``` + $try_join + } +} + +#[allow(unreachable_pub)] +#[doc(hidden)] +pub use futures_macro::join_internal; + +#[allow(unreachable_pub)] +#[doc(hidden)] +pub use futures_macro::try_join_internal; + +document_join_macro! { + #[macro_export] + macro_rules! join { + ($($tokens:tt)*) => {{ + use $crate::__private as __futures_crate; + $crate::join_internal! { + $( $tokens )* + } + }} + } + + #[macro_export] + macro_rules! try_join { + ($($tokens:tt)*) => {{ + use $crate::__private as __futures_crate; + $crate::try_join_internal! { + $( $tokens )* + } + }} + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/mod.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/mod.rs new file mode 100644 index 00000000..7e3f12c9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/mod.rs @@ -0,0 +1,60 @@ +//! Await +//! +//! This module contains a number of functions and combinators for working +//! with `async`/`await` code. + +use futures_core::future::{FusedFuture, Future}; +use futures_core::stream::{FusedStream, Stream}; + +#[macro_use] +mod poll; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +pub use self::poll::*; + +#[macro_use] +mod pending; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +pub use self::pending::*; + +// Primary export is a macro +#[cfg(feature = "async-await-macro")] +mod join_mod; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +#[cfg(feature = "async-await-macro")] +pub use self::join_mod::*; + +// Primary export is a macro +#[cfg(feature = "async-await-macro")] +mod select_mod; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +#[cfg(feature = "async-await-macro")] +pub use self::select_mod::*; + +// Primary export is a macro +#[cfg(feature = "std")] +#[cfg(feature = "async-await-macro")] +mod stream_select_mod; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +#[cfg(feature = "std")] +#[cfg(feature = "async-await-macro")] +pub use self::stream_select_mod::*; + +#[cfg(feature = "std")] +#[cfg(feature = "async-await-macro")] +mod random; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +#[cfg(feature = "std")] +#[cfg(feature = "async-await-macro")] +pub use self::random::*; + +#[doc(hidden)] +#[inline(always)] +pub fn assert_unpin(_: &T) {} + +#[doc(hidden)] +#[inline(always)] +pub fn assert_fused_future(_: &T) {} + +#[doc(hidden)] +#[inline(always)] +pub fn assert_fused_stream(_: &T) {} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/pending.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/pending.rs new file mode 100644 index 00000000..5d7a4318 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/pending.rs @@ -0,0 +1,43 @@ +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; + +/// A macro which yields to the event loop once. +/// +/// This is equivalent to returning [`Poll::Pending`](futures_core::task::Poll) +/// from a [`Future::poll`](futures_core::future::Future::poll) implementation. +/// Similarly, when using this macro, it must be ensured that [`wake`](std::task::Waker::wake) +/// is called somewhere when further progress can be made. +/// +/// This macro is only usable inside of async functions, closures, and blocks. +/// It is also gated behind the `async-await` feature of this library, which is +/// activated by default. +#[macro_export] +macro_rules! pending { + () => { + $crate::__private::async_await::pending_once().await + }; +} + +#[doc(hidden)] +pub fn pending_once() -> PendingOnce { + PendingOnce { is_ready: false } +} + +#[allow(missing_debug_implementations)] +#[doc(hidden)] +pub struct PendingOnce { + is_ready: bool, +} + +impl Future for PendingOnce { + type Output = (); + fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + if self.is_ready { + Poll::Ready(()) + } else { + self.is_ready = true; + Poll::Pending + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/poll.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/poll.rs new file mode 100644 index 00000000..b62f45a9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/poll.rs @@ -0,0 +1,39 @@ +use crate::future::FutureExt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; + +/// A macro which returns the result of polling a future once within the +/// current `async` context. +/// +/// This macro is only usable inside of `async` functions, closures, and blocks. +/// It is also gated behind the `async-await` feature of this library, which is +/// activated by default. +/// +/// If you need the result of polling a [`Stream`](crate::stream::Stream), +/// you can use this macro with the [`next`](crate::stream::StreamExt::next) method: +/// `poll!(stream.next())`. +#[macro_export] +macro_rules! poll { + ($x:expr $(,)?) => { + $crate::__private::async_await::poll($x).await + }; +} + +#[doc(hidden)] +pub fn poll(future: F) -> PollOnce { + PollOnce { future } +} + +#[allow(missing_debug_implementations)] +#[doc(hidden)] +pub struct PollOnce { + future: F, +} + +impl Future for PollOnce { + type Output = Poll; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready(self.future.poll_unpin(cx)) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/random.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/random.rs new file mode 100644 index 00000000..4f8c7254 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/random.rs @@ -0,0 +1,54 @@ +use std::{ + cell::Cell, + collections::hash_map::DefaultHasher, + hash::Hasher, + num::Wrapping, + sync::atomic::{AtomicUsize, Ordering}, +}; + +// Based on [Fisher–Yates shuffle]. +// +// [Fisher–Yates shuffle]: https://en.wikipedia.org/wiki/Fisher–Yates_shuffle +#[doc(hidden)] +pub fn shuffle(slice: &mut [T]) { + for i in (1..slice.len()).rev() { + slice.swap(i, gen_index(i + 1)); + } +} + +/// Return a value from `0..n`. +fn gen_index(n: usize) -> usize { + (random() % n as u64) as usize +} + +/// Pseudorandom number generator based on [xorshift*]. +/// +/// [xorshift*]: https://en.wikipedia.org/wiki/Xorshift#xorshift* +fn random() -> u64 { + thread_local! { + static RNG: Cell> = Cell::new(Wrapping(prng_seed())); + } + + fn prng_seed() -> u64 { + static COUNTER: AtomicUsize = AtomicUsize::new(0); + + // Any non-zero seed will do + let mut seed = 0; + while seed == 0 { + let mut hasher = DefaultHasher::new(); + hasher.write_usize(COUNTER.fetch_add(1, Ordering::Relaxed)); + seed = hasher.finish(); + } + seed + } + + RNG.with(|rng| { + let mut x = rng.get(); + debug_assert_ne!(x.0, 0); + x ^= x >> 12; + x ^= x << 25; + x ^= x >> 27; + rng.set(x); + x.0.wrapping_mul(0x2545_f491_4f6c_dd1d) + }) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/select_mod.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/select_mod.rs new file mode 100644 index 00000000..1d13067d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/select_mod.rs @@ -0,0 +1,336 @@ +//! The `select` macro. + +macro_rules! document_select_macro { + // This branch is required for `futures 0.3.1`, from before select_biased was introduced + ($select:item) => { + /// Polls multiple futures and streams simultaneously, executing the branch + /// for the future that finishes first. If multiple futures are ready, + /// one will be pseudo-randomly selected at runtime. Futures directly + /// passed to `select!` must be `Unpin` and implement `FusedFuture`. + /// + /// If an expression which yields a `Future` is passed to `select!` + /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin` + /// requirement is relaxed, since the macro will pin the resulting `Future` + /// on the stack. However the `Future` returned by the expression must + /// still implement `FusedFuture`. + /// + /// Futures and streams which are not already fused can be fused using the + /// `.fuse()` method. Note, though, that fusing a future or stream directly + /// in the call to `select!` will not be enough to prevent it from being + /// polled after completion if the `select!` call is in a loop, so when + /// `select!`ing in a loop, users should take care to `fuse()` outside of + /// the loop. + /// + /// `select!` can be used as an expression and will return the return + /// value of the selected branch. For this reason the return type of every + /// branch in a `select!` must be the same. + /// + /// This macro is only usable inside of async functions, closures, and blocks. + /// It is also gated behind the `async-await` feature of this library, which is + /// activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::select; + /// let mut a = future::ready(4); + /// let mut b = future::pending::<()>(); + /// + /// let res = select! { + /// a_res = a => a_res + 1, + /// _ = b => 0, + /// }; + /// assert_eq!(res, 5); + /// # }); + /// ``` + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// use futures::select; + /// let mut st = stream::iter(vec![2]).fuse(); + /// let mut fut = future::pending::<()>(); + /// + /// select! { + /// x = st.next() => assert_eq!(Some(2), x), + /// _ = fut => panic!(), + /// }; + /// # }); + /// ``` + /// + /// As described earlier, `select` can directly select on expressions + /// which return `Future`s - even if those do not implement `Unpin`: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::select; + /// + /// // Calling the following async fn returns a Future which does not + /// // implement Unpin + /// async fn async_identity_fn(arg: usize) -> usize { + /// arg + /// } + /// + /// let res = select! { + /// a_res = async_identity_fn(62).fuse() => a_res + 1, + /// b_res = async_identity_fn(13).fuse() => b_res, + /// }; + /// assert!(res == 63 || res == 13); + /// # }); + /// ``` + /// + /// If a similar async function is called outside of `select` to produce + /// a `Future`, the `Future` must be pinned in order to be able to pass + /// it to `select`. This can be achieved via `Box::pin` for pinning a + /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future` + /// on the stack. + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::select; + /// use futures::pin_mut; + /// + /// // Calling the following async fn returns a Future which does not + /// // implement Unpin + /// async fn async_identity_fn(arg: usize) -> usize { + /// arg + /// } + /// + /// let fut_1 = async_identity_fn(1).fuse(); + /// let fut_2 = async_identity_fn(2).fuse(); + /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap + /// pin_mut!(fut_2); // Pins the Future on the stack + /// + /// let res = select! { + /// a_res = fut_1 => a_res, + /// b_res = fut_2 => b_res, + /// }; + /// assert!(res == 1 || res == 2); + /// # }); + /// ``` + /// + /// `select` also accepts a `complete` branch and a `default` branch. + /// `complete` will run if all futures and streams have already been + /// exhausted. `default` will run if no futures or streams are + /// immediately ready. `complete` takes priority over `default` in + /// the case where all futures have completed. + /// A motivating use-case for passing `Future`s by name as well as for + /// `complete` blocks is to call `select!` in a loop, which is + /// demonstrated in the following example: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::select; + /// let mut a_fut = future::ready(4); + /// let mut b_fut = future::ready(6); + /// let mut total = 0; + /// + /// loop { + /// select! { + /// a = a_fut => total += a, + /// b = b_fut => total += b, + /// complete => break, + /// default => panic!(), // never runs (futures run first, then complete) + /// }; + /// } + /// assert_eq!(total, 10); + /// # }); + /// ``` + /// + /// Note that the futures that have been matched over can still be mutated + /// from inside the `select!` block's branches. This can be used to implement + /// more complex behavior such as timer resets or writing into the head of + /// a stream. + $select + }; + + ($select:item $select_biased:item) => { + document_select_macro!($select); + + /// Polls multiple futures and streams simultaneously, executing the branch + /// for the future that finishes first. Unlike [`select!`], if multiple futures are ready, + /// one will be selected in order of declaration. Futures directly + /// passed to `select_biased!` must be `Unpin` and implement `FusedFuture`. + /// + /// If an expression which yields a `Future` is passed to `select_biased!` + /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin` + /// requirement is relaxed, since the macro will pin the resulting `Future` + /// on the stack. However the `Future` returned by the expression must + /// still implement `FusedFuture`. + /// + /// Futures and streams which are not already fused can be fused using the + /// `.fuse()` method. Note, though, that fusing a future or stream directly + /// in the call to `select_biased!` will not be enough to prevent it from being + /// polled after completion if the `select_biased!` call is in a loop, so when + /// `select_biased!`ing in a loop, users should take care to `fuse()` outside of + /// the loop. + /// + /// `select_biased!` can be used as an expression and will return the return + /// value of the selected branch. For this reason the return type of every + /// branch in a `select_biased!` must be the same. + /// + /// This macro is only usable inside of async functions, closures, and blocks. + /// It is also gated behind the `async-await` feature of this library, which is + /// activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::select_biased; + /// let mut a = future::ready(4); + /// let mut b = future::pending::<()>(); + /// + /// let res = select_biased! { + /// a_res = a => a_res + 1, + /// _ = b => 0, + /// }; + /// assert_eq!(res, 5); + /// # }); + /// ``` + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// use futures::select_biased; + /// let mut st = stream::iter(vec![2]).fuse(); + /// let mut fut = future::pending::<()>(); + /// + /// select_biased! { + /// x = st.next() => assert_eq!(Some(2), x), + /// _ = fut => panic!(), + /// }; + /// # }); + /// ``` + /// + /// As described earlier, `select_biased` can directly select on expressions + /// which return `Future`s - even if those do not implement `Unpin`: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::select_biased; + /// + /// // Calling the following async fn returns a Future which does not + /// // implement Unpin + /// async fn async_identity_fn(arg: usize) -> usize { + /// arg + /// } + /// + /// let res = select_biased! { + /// a_res = async_identity_fn(62).fuse() => a_res + 1, + /// b_res = async_identity_fn(13).fuse() => b_res, + /// }; + /// assert!(res == 63 || res == 12); + /// # }); + /// ``` + /// + /// If a similar async function is called outside of `select_biased` to produce + /// a `Future`, the `Future` must be pinned in order to be able to pass + /// it to `select_biased`. This can be achieved via `Box::pin` for pinning a + /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future` + /// on the stack. + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::select_biased; + /// use futures::pin_mut; + /// + /// // Calling the following async fn returns a Future which does not + /// // implement Unpin + /// async fn async_identity_fn(arg: usize) -> usize { + /// arg + /// } + /// + /// let fut_1 = async_identity_fn(1).fuse(); + /// let fut_2 = async_identity_fn(2).fuse(); + /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap + /// pin_mut!(fut_2); // Pins the Future on the stack + /// + /// let res = select_biased! { + /// a_res = fut_1 => a_res, + /// b_res = fut_2 => b_res, + /// }; + /// assert!(res == 1 || res == 2); + /// # }); + /// ``` + /// + /// `select_biased` also accepts a `complete` branch and a `default` branch. + /// `complete` will run if all futures and streams have already been + /// exhausted. `default` will run if no futures or streams are + /// immediately ready. `complete` takes priority over `default` in + /// the case where all futures have completed. + /// A motivating use-case for passing `Future`s by name as well as for + /// `complete` blocks is to call `select_biased!` in a loop, which is + /// demonstrated in the following example: + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::select_biased; + /// let mut a_fut = future::ready(4); + /// let mut b_fut = future::ready(6); + /// let mut total = 0; + /// + /// loop { + /// select_biased! { + /// a = a_fut => total += a, + /// b = b_fut => total += b, + /// complete => break, + /// default => panic!(), // never runs (futures run first, then complete) + /// }; + /// } + /// assert_eq!(total, 10); + /// # }); + /// ``` + /// + /// Note that the futures that have been matched over can still be mutated + /// from inside the `select_biased!` block's branches. This can be used to implement + /// more complex behavior such as timer resets or writing into the head of + /// a stream. + /// + /// [`select!`]: macro.select.html + $select_biased + }; +} + +#[cfg(feature = "std")] +#[allow(unreachable_pub)] +#[doc(hidden)] +pub use futures_macro::select_internal; + +#[allow(unreachable_pub)] +#[doc(hidden)] +pub use futures_macro::select_biased_internal; + +document_select_macro! { + #[cfg(feature = "std")] + #[macro_export] + macro_rules! select { + ($($tokens:tt)*) => {{ + use $crate::__private as __futures_crate; + $crate::select_internal! { + $( $tokens )* + } + }} + } + + #[macro_export] + macro_rules! select_biased { + ($($tokens:tt)*) => {{ + use $crate::__private as __futures_crate; + $crate::select_biased_internal! { + $( $tokens )* + } + }} + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/async_await/stream_select_mod.rs b/utshell-0.5.0/vendor/futures-util/src/async_await/stream_select_mod.rs new file mode 100644 index 00000000..61e3fa1c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/async_await/stream_select_mod.rs @@ -0,0 +1,38 @@ +//! The `stream_select` macro. + +#[allow(unreachable_pub)] +#[doc(hidden)] +pub use futures_macro::stream_select_internal; + +/// Combines several streams, all producing the same `Item` type, into one stream. +/// This is similar to `select_all` but does not require the streams to all be the same type. +/// It also keeps the streams inline, and does not require `Box`s to be allocated. +/// Streams passed to this macro must be `Unpin`. +/// +/// If multiple streams are ready, one will be pseudo randomly selected at runtime. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::{stream, StreamExt, stream_select}; +/// let endless_ints = |i| stream::iter(vec![i].into_iter().cycle()).fuse(); +/// +/// let mut endless_numbers = stream_select!(endless_ints(1i32), endless_ints(2), endless_ints(3)); +/// match endless_numbers.next().await { +/// Some(1) => println!("Got a 1"), +/// Some(2) => println!("Got a 2"), +/// Some(3) => println!("Got a 3"), +/// _ => unreachable!(), +/// } +/// # }); +/// ``` +#[macro_export] +macro_rules! stream_select { + ($($tokens:tt)*) => {{ + use $crate::__private as __futures_crate; + $crate::stream_select_internal! { + $( $tokens )* + } + }} +} diff --git a/utshell-0.5.0/vendor/futures-util/src/compat/compat01as03.rs b/utshell-0.5.0/vendor/futures-util/src/compat/compat01as03.rs new file mode 100644 index 00000000..36de1da9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/compat/compat01as03.rs @@ -0,0 +1,454 @@ +use futures_01::executor::{ + spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01, Spawn as Spawn01, + UnsafeNotify as UnsafeNotify01, +}; +use futures_01::{Async as Async01, Future as Future01, Stream as Stream01}; +#[cfg(feature = "sink")] +use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01}; +use futures_core::{future::Future as Future03, stream::Stream as Stream03, task as task03}; +#[cfg(feature = "sink")] +use futures_sink::Sink as Sink03; +use std::pin::Pin; +use std::task::Context; + +#[cfg(feature = "io-compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use io::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; + +/// Converts a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite +/// object to a futures 0.3-compatible version, +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Compat01As03 { + pub(crate) inner: Spawn01, +} + +impl Unpin for Compat01As03 {} + +impl Compat01As03 { + /// Wraps a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite + /// object in a futures 0.3-compatible wrapper. + pub fn new(object: T) -> Self { + Self { inner: spawn01(object) } + } + + fn in_notify(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut T) -> R) -> R { + let notify = &WakerToHandle(cx.waker()); + self.inner.poll_fn_notify(notify, 0, f) + } + + /// Get a reference to 0.1 Future, Stream, AsyncRead, or AsyncWrite object contained within. + pub fn get_ref(&self) -> &T { + self.inner.get_ref() + } + + /// Get a mutable reference to 0.1 Future, Stream, AsyncRead or AsyncWrite object contained + /// within. + pub fn get_mut(&mut self) -> &mut T { + self.inner.get_mut() + } + + /// Consume this wrapper to return the underlying 0.1 Future, Stream, AsyncRead, or + /// AsyncWrite object. + pub fn into_inner(self) -> T { + self.inner.into_inner() + } +} + +/// Extension trait for futures 0.1 [`Future`](futures_01::future::Future) +pub trait Future01CompatExt: Future01 { + /// Converts a futures 0.1 + /// [`Future`](futures_01::future::Future) + /// into a futures 0.3 + /// [`Future>`](futures_core::future::Future). + /// + /// ``` + /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 + /// # futures::executor::block_on(async { + /// # // TODO: These should be all using `futures::compat`, but that runs up against Cargo + /// # // feature issues + /// use futures_util::compat::Future01CompatExt; + /// + /// let future = futures_01::future::ok::(1); + /// assert_eq!(future.compat().await, Ok(1)); + /// # }); + /// ``` + fn compat(self) -> Compat01As03 + where + Self: Sized, + { + Compat01As03::new(self) + } +} +impl Future01CompatExt for Fut {} + +/// Extension trait for futures 0.1 [`Stream`](futures_01::stream::Stream) +pub trait Stream01CompatExt: Stream01 { + /// Converts a futures 0.1 + /// [`Stream`](futures_01::stream::Stream) + /// into a futures 0.3 + /// [`Stream>`](futures_core::stream::Stream). + /// + /// ``` + /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 + /// # futures::executor::block_on(async { + /// use futures::stream::StreamExt; + /// use futures_util::compat::Stream01CompatExt; + /// + /// let stream = futures_01::stream::once::(Ok(1)); + /// let mut stream = stream.compat(); + /// assert_eq!(stream.next().await, Some(Ok(1))); + /// assert_eq!(stream.next().await, None); + /// # }); + /// ``` + fn compat(self) -> Compat01As03 + where + Self: Sized, + { + Compat01As03::new(self) + } +} +impl Stream01CompatExt for St {} + +/// Extension trait for futures 0.1 [`Sink`](futures_01::sink::Sink) +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub trait Sink01CompatExt: Sink01 { + /// Converts a futures 0.1 + /// [`Sink`](futures_01::sink::Sink) + /// into a futures 0.3 + /// [`Sink`](futures_sink::Sink). + /// + /// ``` + /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 + /// # futures::executor::block_on(async { + /// use futures::{sink::SinkExt, stream::StreamExt}; + /// use futures_util::compat::{Stream01CompatExt, Sink01CompatExt}; + /// + /// let (tx, rx) = futures_01::unsync::mpsc::channel(1); + /// let (mut tx, mut rx) = (tx.sink_compat(), rx.compat()); + /// + /// tx.send(1).await.unwrap(); + /// drop(tx); + /// assert_eq!(rx.next().await, Some(Ok(1))); + /// assert_eq!(rx.next().await, None); + /// # }); + /// ``` + fn sink_compat(self) -> Compat01As03Sink + where + Self: Sized, + { + Compat01As03Sink::new(self) + } +} +#[cfg(feature = "sink")] +impl Sink01CompatExt for Si {} + +fn poll_01_to_03(x: Result, E>) -> task03::Poll> { + match x? { + Async01::Ready(t) => task03::Poll::Ready(Ok(t)), + Async01::NotReady => task03::Poll::Pending, + } +} + +impl Future03 for Compat01As03 { + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> task03::Poll { + poll_01_to_03(self.in_notify(cx, Future01::poll)) + } +} + +impl Stream03 for Compat01As03 { + type Item = Result; + + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + match self.in_notify(cx, Stream01::poll)? { + Async01::Ready(Some(t)) => task03::Poll::Ready(Some(Ok(t))), + Async01::Ready(None) => task03::Poll::Ready(None), + Async01::NotReady => task03::Poll::Pending, + } + } +} + +/// Converts a futures 0.1 Sink object to a futures 0.3-compatible version +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +#[derive(Debug)] +#[must_use = "sinks do nothing unless polled"] +pub struct Compat01As03Sink { + pub(crate) inner: Spawn01, + pub(crate) buffer: Option, + pub(crate) close_started: bool, +} + +#[cfg(feature = "sink")] +impl Unpin for Compat01As03Sink {} + +#[cfg(feature = "sink")] +impl Compat01As03Sink { + /// Wraps a futures 0.1 Sink object in a futures 0.3-compatible wrapper. + pub fn new(inner: S) -> Self { + Self { inner: spawn01(inner), buffer: None, close_started: false } + } + + fn in_notify(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut S) -> R) -> R { + let notify = &WakerToHandle(cx.waker()); + self.inner.poll_fn_notify(notify, 0, f) + } + + /// Get a reference to 0.1 Sink object contained within. + pub fn get_ref(&self) -> &S { + self.inner.get_ref() + } + + /// Get a mutable reference to 0.1 Sink contained within. + pub fn get_mut(&mut self) -> &mut S { + self.inner.get_mut() + } + + /// Consume this wrapper to return the underlying 0.1 Sink. + pub fn into_inner(self) -> S { + self.inner.into_inner() + } +} + +#[cfg(feature = "sink")] +impl Stream03 for Compat01As03Sink +where + S: Stream01, +{ + type Item = Result; + + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + match self.in_notify(cx, Stream01::poll)? { + Async01::Ready(Some(t)) => task03::Poll::Ready(Some(Ok(t))), + Async01::Ready(None) => task03::Poll::Ready(None), + Async01::NotReady => task03::Poll::Pending, + } + } +} + +#[cfg(feature = "sink")] +impl Sink03 for Compat01As03Sink +where + S: Sink01, +{ + type Error = S::SinkError; + + fn start_send(mut self: Pin<&mut Self>, item: SinkItem) -> Result<(), Self::Error> { + debug_assert!(self.buffer.is_none()); + self.buffer = Some(item); + Ok(()) + } + + fn poll_ready( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + match self.buffer.take() { + Some(item) => match self.in_notify(cx, |f| f.start_send(item))? { + AsyncSink01::Ready => task03::Poll::Ready(Ok(())), + AsyncSink01::NotReady(i) => { + self.buffer = Some(i); + task03::Poll::Pending + } + }, + None => task03::Poll::Ready(Ok(())), + } + } + + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + let item = self.buffer.take(); + match self.in_notify(cx, |f| match item { + Some(i) => match f.start_send(i)? { + AsyncSink01::Ready => f.poll_complete().map(|i| (i, None)), + AsyncSink01::NotReady(t) => Ok((Async01::NotReady, Some(t))), + }, + None => f.poll_complete().map(|i| (i, None)), + })? { + (Async01::Ready(_), _) => task03::Poll::Ready(Ok(())), + (Async01::NotReady, item) => { + self.buffer = item; + task03::Poll::Pending + } + } + } + + fn poll_close( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + let item = self.buffer.take(); + let close_started = self.close_started; + + let result = self.in_notify(cx, |f| { + if !close_started { + if let Some(item) = item { + if let AsyncSink01::NotReady(item) = f.start_send(item)? { + return Ok((Async01::NotReady, Some(item), false)); + } + } + + if let Async01::NotReady = f.poll_complete()? { + return Ok((Async01::NotReady, None, false)); + } + } + + Ok((::close(f)?, None, true)) + }); + + match result? { + (Async01::Ready(_), _, _) => task03::Poll::Ready(Ok(())), + (Async01::NotReady, item, close_started) => { + self.buffer = item; + self.close_started = close_started; + task03::Poll::Pending + } + } + } +} + +struct NotifyWaker(task03::Waker); + +#[allow(missing_debug_implementations)] // false positive: this is private type +#[derive(Clone)] +struct WakerToHandle<'a>(&'a task03::Waker); + +impl From> for NotifyHandle01 { + fn from(handle: WakerToHandle<'_>) -> Self { + let ptr = Box::new(NotifyWaker(handle.0.clone())); + + unsafe { Self::new(Box::into_raw(ptr)) } + } +} + +impl Notify01 for NotifyWaker { + fn notify(&self, _: usize) { + self.0.wake_by_ref(); + } +} + +unsafe impl UnsafeNotify01 for NotifyWaker { + unsafe fn clone_raw(&self) -> NotifyHandle01 { + WakerToHandle(&self.0).into() + } + + unsafe fn drop_raw(&self) { + let ptr: *const dyn UnsafeNotify01 = self; + drop(Box::from_raw(ptr as *mut dyn UnsafeNotify01)); + } +} + +#[cfg(feature = "io-compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] +mod io { + use super::*; + use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03}; + use std::io::Error; + use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01}; + + /// Extension trait for tokio-io [`AsyncRead`](tokio_io::AsyncRead) + #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] + pub trait AsyncRead01CompatExt: AsyncRead01 { + /// Converts a tokio-io [`AsyncRead`](tokio_io::AsyncRead) into a futures-io 0.3 + /// [`AsyncRead`](futures_io::AsyncRead). + /// + /// ``` + /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 + /// # futures::executor::block_on(async { + /// use futures::io::AsyncReadExt; + /// use futures_util::compat::AsyncRead01CompatExt; + /// + /// let input = b"Hello World!"; + /// let reader /* : impl tokio_io::AsyncRead */ = std::io::Cursor::new(input); + /// let mut reader /* : impl futures::io::AsyncRead + Unpin */ = reader.compat(); + /// + /// let mut output = Vec::with_capacity(12); + /// reader.read_to_end(&mut output).await.unwrap(); + /// assert_eq!(output, input); + /// # }); + /// ``` + fn compat(self) -> Compat01As03 + where + Self: Sized, + { + Compat01As03::new(self) + } + } + impl AsyncRead01CompatExt for R {} + + /// Extension trait for tokio-io [`AsyncWrite`](tokio_io::AsyncWrite) + #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] + pub trait AsyncWrite01CompatExt: AsyncWrite01 { + /// Converts a tokio-io [`AsyncWrite`](tokio_io::AsyncWrite) into a futures-io 0.3 + /// [`AsyncWrite`](futures_io::AsyncWrite). + /// + /// ``` + /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 + /// # futures::executor::block_on(async { + /// use futures::io::AsyncWriteExt; + /// use futures_util::compat::AsyncWrite01CompatExt; + /// + /// let input = b"Hello World!"; + /// let mut cursor = std::io::Cursor::new(Vec::with_capacity(12)); + /// + /// let mut writer = (&mut cursor).compat(); + /// writer.write_all(input).await.unwrap(); + /// + /// assert_eq!(cursor.into_inner(), input); + /// # }); + /// ``` + fn compat(self) -> Compat01As03 + where + Self: Sized, + { + Compat01As03::new(self) + } + } + impl AsyncWrite01CompatExt for W {} + + impl AsyncRead03 for Compat01As03 { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> task03::Poll> { + poll_01_to_03(self.in_notify(cx, |x| x.poll_read(buf))) + } + } + + impl AsyncWrite03 for Compat01As03 { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> task03::Poll> { + poll_01_to_03(self.in_notify(cx, |x| x.poll_write(buf))) + } + + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + poll_01_to_03(self.in_notify(cx, AsyncWrite01::poll_flush)) + } + + fn poll_close( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> task03::Poll> { + poll_01_to_03(self.in_notify(cx, AsyncWrite01::shutdown)) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/compat/compat03as01.rs b/utshell-0.5.0/vendor/futures-util/src/compat/compat03as01.rs new file mode 100644 index 00000000..5d3a6e92 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/compat/compat03as01.rs @@ -0,0 +1,265 @@ +use crate::task::{self as task03, ArcWake as ArcWake03, WakerRef}; +use futures_01::{ + task as task01, Async as Async01, Future as Future01, Poll as Poll01, Stream as Stream01, +}; +#[cfg(feature = "sink")] +use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01}; +use futures_core::{ + future::TryFuture as TryFuture03, + stream::TryStream as TryStream03, + task::{RawWaker, RawWakerVTable}, +}; +#[cfg(feature = "sink")] +use futures_sink::Sink as Sink03; +#[cfg(feature = "sink")] +use std::marker::PhantomData; +use std::{mem, pin::Pin, sync::Arc, task::Context}; + +/// Converts a futures 0.3 [`TryFuture`](futures_core::future::TryFuture) or +/// [`TryStream`](futures_core::stream::TryStream) into a futures 0.1 +/// [`Future`](futures_01::future::Future) or +/// [`Stream`](futures_01::stream::Stream). +#[derive(Debug, Clone, Copy)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Compat { + pub(crate) inner: T, +} + +/// Converts a futures 0.3 [`Sink`](futures_sink::Sink) into a futures 0.1 +/// [`Sink`](futures_01::sink::Sink). +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +#[derive(Debug)] +#[must_use = "sinks do nothing unless polled"] +pub struct CompatSink { + inner: T, + _phantom: PhantomData, +} + +impl Compat { + /// Creates a new [`Compat`]. + /// + /// For types which implement appropriate futures `0.3` + /// traits, the result will be a type which implements + /// the corresponding futures 0.1 type. + pub fn new(inner: T) -> Self { + Self { inner } + } + + /// Get a reference to 0.3 Future, Stream, AsyncRead, or AsyncWrite object + /// contained within. + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Get a mutable reference to 0.3 Future, Stream, AsyncRead, or AsyncWrite object + /// contained within. + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Returns the inner item. + pub fn into_inner(self) -> T { + self.inner + } +} + +#[cfg(feature = "sink")] +impl CompatSink { + /// Creates a new [`CompatSink`]. + pub fn new(inner: T) -> Self { + Self { inner, _phantom: PhantomData } + } + + /// Get a reference to 0.3 Sink contained within. + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Get a mutable reference to 0.3 Sink contained within. + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Returns the inner item. + pub fn into_inner(self) -> T { + self.inner + } +} + +fn poll_03_to_01(x: task03::Poll>) -> Result, E> { + match x? { + task03::Poll::Ready(t) => Ok(Async01::Ready(t)), + task03::Poll::Pending => Ok(Async01::NotReady), + } +} + +impl Future01 for Compat +where + Fut: TryFuture03 + Unpin, +{ + type Item = Fut::Ok; + type Error = Fut::Error; + + fn poll(&mut self) -> Poll01 { + with_context(self, |inner, cx| poll_03_to_01(inner.try_poll(cx))) + } +} + +impl Stream01 for Compat +where + St: TryStream03 + Unpin, +{ + type Item = St::Ok; + type Error = St::Error; + + fn poll(&mut self) -> Poll01, Self::Error> { + with_context(self, |inner, cx| match inner.try_poll_next(cx)? { + task03::Poll::Ready(None) => Ok(Async01::Ready(None)), + task03::Poll::Ready(Some(t)) => Ok(Async01::Ready(Some(t))), + task03::Poll::Pending => Ok(Async01::NotReady), + }) + } +} + +#[cfg(feature = "sink")] +impl Sink01 for CompatSink +where + T: Sink03 + Unpin, +{ + type SinkItem = Item; + type SinkError = T::Error; + + fn start_send(&mut self, item: Self::SinkItem) -> StartSend01 { + with_sink_context(self, |mut inner, cx| match inner.as_mut().poll_ready(cx)? { + task03::Poll::Ready(()) => inner.start_send(item).map(|()| AsyncSink01::Ready), + task03::Poll::Pending => Ok(AsyncSink01::NotReady(item)), + }) + } + + fn poll_complete(&mut self) -> Poll01<(), Self::SinkError> { + with_sink_context(self, |inner, cx| poll_03_to_01(inner.poll_flush(cx))) + } + + fn close(&mut self) -> Poll01<(), Self::SinkError> { + with_sink_context(self, |inner, cx| poll_03_to_01(inner.poll_close(cx))) + } +} + +#[derive(Clone)] +struct Current(task01::Task); + +impl Current { + fn new() -> Self { + Self(task01::current()) + } + + fn as_waker(&self) -> WakerRef<'_> { + unsafe fn ptr_to_current<'a>(ptr: *const ()) -> &'a Current { + &*(ptr as *const Current) + } + fn current_to_ptr(current: &Current) -> *const () { + current as *const Current as *const () + } + + unsafe fn clone(ptr: *const ()) -> RawWaker { + // Lazily create the `Arc` only when the waker is actually cloned. + // FIXME: remove `transmute` when a `Waker` -> `RawWaker` conversion + // function is landed in `core`. + mem::transmute::(task03::waker(Arc::new( + ptr_to_current(ptr).clone(), + ))) + } + unsafe fn drop(_: *const ()) {} + unsafe fn wake(ptr: *const ()) { + ptr_to_current(ptr).0.notify() + } + + let ptr = current_to_ptr(self); + let vtable = &RawWakerVTable::new(clone, wake, wake, drop); + WakerRef::new_unowned(std::mem::ManuallyDrop::new(unsafe { + task03::Waker::from_raw(RawWaker::new(ptr, vtable)) + })) + } +} + +impl ArcWake03 for Current { + fn wake_by_ref(arc_self: &Arc) { + arc_self.0.notify(); + } +} + +fn with_context(compat: &mut Compat, f: F) -> R +where + T: Unpin, + F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> R, +{ + let current = Current::new(); + let waker = current.as_waker(); + let mut cx = Context::from_waker(&waker); + f(Pin::new(&mut compat.inner), &mut cx) +} + +#[cfg(feature = "sink")] +fn with_sink_context(compat: &mut CompatSink, f: F) -> R +where + T: Unpin, + F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> R, +{ + let current = Current::new(); + let waker = current.as_waker(); + let mut cx = Context::from_waker(&waker); + f(Pin::new(&mut compat.inner), &mut cx) +} + +#[cfg(feature = "io-compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] +mod io { + use super::*; + use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03}; + use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01}; + + fn poll_03_to_io(x: task03::Poll>) -> Result { + match x { + task03::Poll::Ready(Ok(t)) => Ok(t), + task03::Poll::Pending => Err(std::io::ErrorKind::WouldBlock.into()), + task03::Poll::Ready(Err(e)) => Err(e), + } + } + + impl std::io::Read for Compat { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let current = Current::new(); + let waker = current.as_waker(); + let mut cx = Context::from_waker(&waker); + poll_03_to_io(Pin::new(&mut self.inner).poll_read(&mut cx, buf)) + } + } + + impl AsyncRead01 for Compat {} + + impl std::io::Write for Compat { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + let current = Current::new(); + let waker = current.as_waker(); + let mut cx = Context::from_waker(&waker); + poll_03_to_io(Pin::new(&mut self.inner).poll_write(&mut cx, buf)) + } + + fn flush(&mut self) -> std::io::Result<()> { + let current = Current::new(); + let waker = current.as_waker(); + let mut cx = Context::from_waker(&waker); + poll_03_to_io(Pin::new(&mut self.inner).poll_flush(&mut cx)) + } + } + + impl AsyncWrite01 for Compat { + fn shutdown(&mut self) -> std::io::Result> { + let current = Current::new(); + let waker = current.as_waker(); + let mut cx = Context::from_waker(&waker); + poll_03_to_01(Pin::new(&mut self.inner).poll_close(&mut cx)) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/compat/executor.rs b/utshell-0.5.0/vendor/futures-util/src/compat/executor.rs new file mode 100644 index 00000000..ea0c67a0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/compat/executor.rs @@ -0,0 +1,86 @@ +use super::{Compat, Future01CompatExt}; +use crate::{ + future::{FutureExt, TryFutureExt, UnitError}, + task::SpawnExt, +}; +use futures_01::future::{ExecuteError as ExecuteError01, Executor as Executor01}; +use futures_01::Future as Future01; +use futures_task::{FutureObj, Spawn as Spawn03, SpawnError as SpawnError03}; + +/// A future that can run on a futures 0.1 +/// [`Executor`](futures_01::future::Executor). +pub type Executor01Future = Compat>>; + +/// Extension trait for futures 0.1 [`Executor`](futures_01::future::Executor). +pub trait Executor01CompatExt: Executor01 + Clone + Send + 'static { + /// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a + /// futures 0.3 [`Spawn`](futures_task::Spawn). + /// + /// ``` + /// # if cfg!(miri) { return; } // Miri does not support epoll + /// use futures::task::SpawnExt; + /// use futures::future::{FutureExt, TryFutureExt}; + /// use futures_util::compat::Executor01CompatExt; + /// use tokio::executor::DefaultExecutor; + /// + /// # let (tx, rx) = futures::channel::oneshot::channel(); + /// + /// let spawner = DefaultExecutor::current().compat(); + /// let future03 = async move { + /// println!("Running on the pool"); + /// spawner.spawn(async { + /// println!("Spawned!"); + /// # tx.send(42).unwrap(); + /// }).unwrap(); + /// }; + /// + /// let future01 = future03.unit_error().boxed().compat(); + /// + /// tokio::run(future01); + /// # futures::executor::block_on(rx).unwrap(); + /// ``` + fn compat(self) -> Executor01As03 + where + Self: Sized; +} + +impl Executor01CompatExt for Ex +where + Ex: Executor01 + Clone + Send + 'static, +{ + fn compat(self) -> Executor01As03 { + Executor01As03 { executor01: self } + } +} + +/// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a +/// futures 0.3 [`Spawn`](futures_task::Spawn). +#[derive(Debug, Clone)] +pub struct Executor01As03 { + executor01: Ex, +} + +impl Spawn03 for Executor01As03 +where + Ex: Executor01 + Clone + Send + 'static, +{ + fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03> { + let future = future.unit_error().compat(); + + self.executor01.execute(future).map_err(|_| SpawnError03::shutdown()) + } +} + +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl Executor01 for Compat +where + for<'a> &'a Sp: Spawn03, + Fut: Future01 + Send + 'static, +{ + fn execute(&self, future: Fut) -> Result<(), ExecuteError01> { + (&self.inner) + .spawn(future.compat().map(|_| ())) + .expect("unable to spawn future from Compat executor"); + Ok(()) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/compat/mod.rs b/utshell-0.5.0/vendor/futures-util/src/compat/mod.rs new file mode 100644 index 00000000..4812803e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/compat/mod.rs @@ -0,0 +1,22 @@ +//! Interop between `futures` 0.1 and 0.3. +//! +//! This module is only available when the `compat` feature of this +//! library is activated. + +mod executor; +pub use self::executor::{Executor01As03, Executor01CompatExt, Executor01Future}; + +mod compat01as03; +#[cfg(feature = "io-compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] +pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; +pub use self::compat01as03::{Compat01As03, Future01CompatExt, Stream01CompatExt}; +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub use self::compat01as03::{Compat01As03Sink, Sink01CompatExt}; + +mod compat03as01; +pub use self::compat03as01::Compat; +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub use self::compat03as01::CompatSink; diff --git a/utshell-0.5.0/vendor/futures-util/src/fns.rs b/utshell-0.5.0/vendor/futures-util/src/fns.rs new file mode 100644 index 00000000..37ee03e6 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/fns.rs @@ -0,0 +1,372 @@ +use core::fmt::{self, Debug}; +use core::marker::PhantomData; + +pub trait FnOnce1 { + type Output; + fn call_once(self, arg: A) -> Self::Output; +} + +impl FnOnce1 for T +where + T: FnOnce(A) -> R, +{ + type Output = R; + fn call_once(self, arg: A) -> R { + self(arg) + } +} + +pub trait FnMut1: FnOnce1 { + fn call_mut(&mut self, arg: A) -> Self::Output; +} + +impl FnMut1 for T +where + T: FnMut(A) -> R, +{ + fn call_mut(&mut self, arg: A) -> R { + self(arg) + } +} + +// Not used, but present for completeness +#[allow(unreachable_pub)] +pub trait Fn1: FnMut1 { + fn call(&self, arg: A) -> Self::Output; +} + +impl Fn1 for T +where + T: Fn(A) -> R, +{ + fn call(&self, arg: A) -> R { + self(arg) + } +} + +macro_rules! trivial_fn_impls { + ($name:ident <$($arg:ident),*> $t:ty = $debug:literal) => { + impl<$($arg),*> Copy for $t {} + impl<$($arg),*> Clone for $t { + fn clone(&self) -> Self { *self } + } + impl<$($arg),*> Debug for $t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str($debug) + } + } + impl<$($arg,)* A> FnMut1 for $t where Self: FnOnce1 { + fn call_mut(&mut self, arg: A) -> Self::Output { + self.call_once(arg) + } + } + impl<$($arg,)* A> Fn1 for $t where Self: FnOnce1 { + fn call(&self, arg: A) -> Self::Output { + self.call_once(arg) + } + } + pub(crate) fn $name<$($arg),*>() -> $t { + Default::default() + } + } +} + +pub struct OkFn(PhantomData); + +impl Default for OkFn { + fn default() -> Self { + Self(PhantomData) + } +} + +impl FnOnce1 for OkFn { + type Output = Result; + fn call_once(self, arg: A) -> Self::Output { + Ok(arg) + } +} + +trivial_fn_impls!(ok_fn OkFn = "Ok"); + +#[derive(Debug, Copy, Clone, Default)] +pub struct ChainFn(F, G); + +impl FnOnce1 for ChainFn +where + F: FnOnce1, + G: FnOnce1, +{ + type Output = G::Output; + fn call_once(self, arg: A) -> Self::Output { + self.1.call_once(self.0.call_once(arg)) + } +} +impl FnMut1 for ChainFn +where + F: FnMut1, + G: FnMut1, +{ + fn call_mut(&mut self, arg: A) -> Self::Output { + self.1.call_mut(self.0.call_mut(arg)) + } +} +impl Fn1 for ChainFn +where + F: Fn1, + G: Fn1, +{ + fn call(&self, arg: A) -> Self::Output { + self.1.call(self.0.call(arg)) + } +} +pub(crate) fn chain_fn(f: F, g: G) -> ChainFn { + ChainFn(f, g) +} + +#[derive(Default)] +pub struct MergeResultFn; + +impl FnOnce1> for MergeResultFn { + type Output = T; + fn call_once(self, arg: Result) -> Self::Output { + match arg { + Ok(x) => x, + Err(x) => x, + } + } +} +trivial_fn_impls!(merge_result_fn <> MergeResultFn = "merge_result"); + +#[derive(Debug, Copy, Clone, Default)] +pub struct InspectFn(F); + +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl FnOnce1 for InspectFn +where + F: for<'a> FnOnce1<&'a A, Output = ()>, +{ + type Output = A; + fn call_once(self, arg: A) -> Self::Output { + self.0.call_once(&arg); + arg + } +} +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl FnMut1 for InspectFn +where + F: for<'a> FnMut1<&'a A, Output = ()>, +{ + fn call_mut(&mut self, arg: A) -> Self::Output { + self.0.call_mut(&arg); + arg + } +} +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl Fn1 for InspectFn +where + F: for<'a> Fn1<&'a A, Output = ()>, +{ + fn call(&self, arg: A) -> Self::Output { + self.0.call(&arg); + arg + } +} +pub(crate) fn inspect_fn(f: F) -> InspectFn { + InspectFn(f) +} + +#[derive(Debug, Copy, Clone, Default)] +pub struct MapOkFn(F); + +impl FnOnce1> for MapOkFn +where + F: FnOnce1, +{ + type Output = Result; + fn call_once(self, arg: Result) -> Self::Output { + arg.map(|x| self.0.call_once(x)) + } +} +impl FnMut1> for MapOkFn +where + F: FnMut1, +{ + fn call_mut(&mut self, arg: Result) -> Self::Output { + arg.map(|x| self.0.call_mut(x)) + } +} +impl Fn1> for MapOkFn +where + F: Fn1, +{ + fn call(&self, arg: Result) -> Self::Output { + arg.map(|x| self.0.call(x)) + } +} +pub(crate) fn map_ok_fn(f: F) -> MapOkFn { + MapOkFn(f) +} + +#[derive(Debug, Copy, Clone, Default)] +pub struct MapErrFn(F); + +impl FnOnce1> for MapErrFn +where + F: FnOnce1, +{ + type Output = Result; + fn call_once(self, arg: Result) -> Self::Output { + arg.map_err(|x| self.0.call_once(x)) + } +} +impl FnMut1> for MapErrFn +where + F: FnMut1, +{ + fn call_mut(&mut self, arg: Result) -> Self::Output { + arg.map_err(|x| self.0.call_mut(x)) + } +} +impl Fn1> for MapErrFn +where + F: Fn1, +{ + fn call(&self, arg: Result) -> Self::Output { + arg.map_err(|x| self.0.call(x)) + } +} +pub(crate) fn map_err_fn(f: F) -> MapErrFn { + MapErrFn(f) +} + +#[derive(Debug, Copy, Clone)] +pub struct InspectOkFn(F); + +impl<'a, F, T, E> FnOnce1<&'a Result> for InspectOkFn +where + F: FnOnce1<&'a T, Output = ()>, +{ + type Output = (); + fn call_once(self, arg: &'a Result) -> Self::Output { + if let Ok(x) = arg { + self.0.call_once(x) + } + } +} +impl<'a, F, T, E> FnMut1<&'a Result> for InspectOkFn +where + F: FnMut1<&'a T, Output = ()>, +{ + fn call_mut(&mut self, arg: &'a Result) -> Self::Output { + if let Ok(x) = arg { + self.0.call_mut(x) + } + } +} +impl<'a, F, T, E> Fn1<&'a Result> for InspectOkFn +where + F: Fn1<&'a T, Output = ()>, +{ + fn call(&self, arg: &'a Result) -> Self::Output { + if let Ok(x) = arg { + self.0.call(x) + } + } +} +pub(crate) fn inspect_ok_fn(f: F) -> InspectOkFn { + InspectOkFn(f) +} + +#[derive(Debug, Copy, Clone)] +pub struct InspectErrFn(F); + +impl<'a, F, T, E> FnOnce1<&'a Result> for InspectErrFn +where + F: FnOnce1<&'a E, Output = ()>, +{ + type Output = (); + fn call_once(self, arg: &'a Result) -> Self::Output { + if let Err(x) = arg { + self.0.call_once(x) + } + } +} +impl<'a, F, T, E> FnMut1<&'a Result> for InspectErrFn +where + F: FnMut1<&'a E, Output = ()>, +{ + fn call_mut(&mut self, arg: &'a Result) -> Self::Output { + if let Err(x) = arg { + self.0.call_mut(x) + } + } +} +impl<'a, F, T, E> Fn1<&'a Result> for InspectErrFn +where + F: Fn1<&'a E, Output = ()>, +{ + fn call(&self, arg: &'a Result) -> Self::Output { + if let Err(x) = arg { + self.0.call(x) + } + } +} +pub(crate) fn inspect_err_fn(f: F) -> InspectErrFn { + InspectErrFn(f) +} + +pub(crate) type MapOkOrElseFn = ChainFn, ChainFn, MergeResultFn>>; +pub(crate) fn map_ok_or_else_fn(f: F, g: G) -> MapOkOrElseFn { + chain_fn(map_ok_fn(f), chain_fn(map_err_fn(g), merge_result_fn())) +} + +#[derive(Debug, Copy, Clone, Default)] +pub struct UnwrapOrElseFn(F); + +impl FnOnce1> for UnwrapOrElseFn +where + F: FnOnce1, +{ + type Output = T; + fn call_once(self, arg: Result) -> Self::Output { + arg.unwrap_or_else(|x| self.0.call_once(x)) + } +} +impl FnMut1> for UnwrapOrElseFn +where + F: FnMut1, +{ + fn call_mut(&mut self, arg: Result) -> Self::Output { + arg.unwrap_or_else(|x| self.0.call_mut(x)) + } +} +impl Fn1> for UnwrapOrElseFn +where + F: Fn1, +{ + fn call(&self, arg: Result) -> Self::Output { + arg.unwrap_or_else(|x| self.0.call(x)) + } +} +pub(crate) fn unwrap_or_else_fn(f: F) -> UnwrapOrElseFn { + UnwrapOrElseFn(f) +} + +pub struct IntoFn(PhantomData T>); + +impl Default for IntoFn { + fn default() -> Self { + Self(PhantomData) + } +} +impl FnOnce1 for IntoFn +where + A: Into, +{ + type Output = T; + fn call_once(self, arg: A) -> Self::Output { + arg.into() + } +} + +trivial_fn_impls!(into_fn IntoFn = "Into::into"); diff --git a/utshell-0.5.0/vendor/futures-util/src/future/abortable.rs b/utshell-0.5.0/vendor/futures-util/src/future/abortable.rs new file mode 100644 index 00000000..d017ab73 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/abortable.rs @@ -0,0 +1,19 @@ +use super::assert_future; +use crate::future::{AbortHandle, Abortable, Aborted}; +use futures_core::future::Future; + +/// Creates a new `Abortable` future and an `AbortHandle` which can be used to stop it. +/// +/// This function is a convenient (but less flexible) alternative to calling +/// `AbortHandle::new` and `Abortable::new` manually. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +pub fn abortable(future: Fut) -> (Abortable, AbortHandle) +where + Fut: Future, +{ + let (handle, reg) = AbortHandle::new_pair(); + let abortable = assert_future::, _>(Abortable::new(future, reg)); + (abortable, handle) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/either.rs b/utshell-0.5.0/vendor/futures-util/src/future/either.rs new file mode 100644 index 00000000..27e5064d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/either.rs @@ -0,0 +1,317 @@ +use core::pin::Pin; +use core::task::{Context, Poll}; +use futures_core::future::{FusedFuture, Future}; +use futures_core::stream::{FusedStream, Stream}; +#[cfg(feature = "sink")] +use futures_sink::Sink; + +/// Combines two different futures, streams, or sinks having the same associated types into a single type. +/// +/// This is useful when conditionally choosing between two distinct future types: +/// +/// ```rust +/// use futures::future::Either; +/// +/// # futures::executor::block_on(async { +/// let cond = true; +/// +/// let fut = if cond { +/// Either::Left(async move { 12 }) +/// } else { +/// Either::Right(async move { 44 }) +/// }; +/// +/// assert_eq!(fut.await, 12); +/// # }) +/// ``` +#[derive(Debug, Clone)] +pub enum Either { + /// First branch of the type + Left(/* #[pin] */ A), + /// Second branch of the type + Right(/* #[pin] */ B), +} + +impl Either { + /// Convert `Pin<&Either>` to `Either, Pin<&B>>`, + /// pinned projections of the inner variants. + pub fn as_pin_ref(self: Pin<&Self>) -> Either, Pin<&B>> { + // SAFETY: We can use `new_unchecked` because the `inner` parts are + // guaranteed to be pinned, as they come from `self` which is pinned. + unsafe { + match *Pin::get_ref(self) { + Either::Left(ref inner) => Either::Left(Pin::new_unchecked(inner)), + Either::Right(ref inner) => Either::Right(Pin::new_unchecked(inner)), + } + } + } + + /// Convert `Pin<&mut Either>` to `Either, Pin<&mut B>>`, + /// pinned projections of the inner variants. + pub fn as_pin_mut(self: Pin<&mut Self>) -> Either, Pin<&mut B>> { + // SAFETY: `get_unchecked_mut` is fine because we don't move anything. + // We can use `new_unchecked` because the `inner` parts are guaranteed + // to be pinned, as they come from `self` which is pinned, and we never + // offer an unpinned `&mut A` or `&mut B` through `Pin<&mut Self>`. We + // also don't have an implementation of `Drop`, nor manual `Unpin`. + unsafe { + match *Pin::get_unchecked_mut(self) { + Either::Left(ref mut inner) => Either::Left(Pin::new_unchecked(inner)), + Either::Right(ref mut inner) => Either::Right(Pin::new_unchecked(inner)), + } + } + } +} + +impl Either<(T, A), (T, B)> { + /// Factor out a homogeneous type from an either of pairs. + /// + /// Here, the homogeneous type is the first element of the pairs. + pub fn factor_first(self) -> (T, Either) { + match self { + Either::Left((x, a)) => (x, Either::Left(a)), + Either::Right((x, b)) => (x, Either::Right(b)), + } + } +} + +impl Either<(A, T), (B, T)> { + /// Factor out a homogeneous type from an either of pairs. + /// + /// Here, the homogeneous type is the second element of the pairs. + pub fn factor_second(self) -> (Either, T) { + match self { + Either::Left((a, x)) => (Either::Left(a), x), + Either::Right((b, x)) => (Either::Right(b), x), + } + } +} + +impl Either { + /// Extract the value of an either over two equivalent types. + pub fn into_inner(self) -> T { + match self { + Either::Left(x) => x, + Either::Right(x) => x, + } + } +} + +impl Future for Either +where + A: Future, + B: Future, +{ + type Output = A::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.as_pin_mut() { + Either::Left(x) => x.poll(cx), + Either::Right(x) => x.poll(cx), + } + } +} + +impl FusedFuture for Either +where + A: FusedFuture, + B: FusedFuture, +{ + fn is_terminated(&self) -> bool { + match self { + Either::Left(x) => x.is_terminated(), + Either::Right(x) => x.is_terminated(), + } + } +} + +impl Stream for Either +where + A: Stream, + B: Stream, +{ + type Item = A::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_next(cx), + Either::Right(x) => x.poll_next(cx), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + Either::Left(x) => x.size_hint(), + Either::Right(x) => x.size_hint(), + } + } +} + +impl FusedStream for Either +where + A: FusedStream, + B: FusedStream, +{ + fn is_terminated(&self) -> bool { + match self { + Either::Left(x) => x.is_terminated(), + Either::Right(x) => x.is_terminated(), + } + } +} + +#[cfg(feature = "sink")] +impl Sink for Either +where + A: Sink, + B: Sink, +{ + type Error = A::Error; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_ready(cx), + Either::Right(x) => x.poll_ready(cx), + } + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + match self.as_pin_mut() { + Either::Left(x) => x.start_send(item), + Either::Right(x) => x.start_send(item), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_flush(cx), + Either::Right(x) => x.poll_flush(cx), + } + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_close(cx), + Either::Right(x) => x.poll_close(cx), + } + } +} + +#[cfg(feature = "io")] +#[cfg(feature = "std")] +mod if_std { + use super::*; + + use core::pin::Pin; + use core::task::{Context, Poll}; + use futures_io::{ + AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom, + }; + + impl AsyncRead for Either + where + A: AsyncRead, + B: AsyncRead, + { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_read(cx, buf), + Either::Right(x) => x.poll_read(cx, buf), + } + } + + fn poll_read_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_read_vectored(cx, bufs), + Either::Right(x) => x.poll_read_vectored(cx, bufs), + } + } + } + + impl AsyncWrite for Either + where + A: AsyncWrite, + B: AsyncWrite, + { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_write(cx, buf), + Either::Right(x) => x.poll_write(cx, buf), + } + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_write_vectored(cx, bufs), + Either::Right(x) => x.poll_write_vectored(cx, bufs), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_flush(cx), + Either::Right(x) => x.poll_flush(cx), + } + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_close(cx), + Either::Right(x) => x.poll_close(cx), + } + } + } + + impl AsyncSeek for Either + where + A: AsyncSeek, + B: AsyncSeek, + { + fn poll_seek( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_seek(cx, pos), + Either::Right(x) => x.poll_seek(cx, pos), + } + } + } + + impl AsyncBufRead for Either + where + A: AsyncBufRead, + B: AsyncBufRead, + { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.as_pin_mut() { + Either::Left(x) => x.poll_fill_buf(cx), + Either::Right(x) => x.poll_fill_buf(cx), + } + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + match self.as_pin_mut() { + Either::Left(x) => x.consume(amt), + Either::Right(x) => x.consume(amt), + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/catch_unwind.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/catch_unwind.rs new file mode 100644 index 00000000..0e09d6ee --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/catch_unwind.rs @@ -0,0 +1,38 @@ +use core::any::Any; +use core::pin::Pin; +use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}; + +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`catch_unwind`](super::FutureExt::catch_unwind) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct CatchUnwind { + #[pin] + future: Fut, + } +} + +impl CatchUnwind +where + Fut: Future + UnwindSafe, +{ + pub(super) fn new(future: Fut) -> Self { + Self { future } + } +} + +impl Future for CatchUnwind +where + Fut: Future + UnwindSafe, +{ + type Output = Result>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let f = self.project().future; + catch_unwind(AssertUnwindSafe(|| f.poll(cx)))?.map(Ok) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/flatten.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/flatten.rs new file mode 100644 index 00000000..bd767af3 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/flatten.rs @@ -0,0 +1,153 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + #[project = FlattenProj] + #[derive(Debug)] + pub enum Flatten { + First { #[pin] f: Fut1 }, + Second { #[pin] f: Fut2 }, + Empty, + } +} + +impl Flatten { + pub(crate) fn new(future: Fut1) -> Self { + Self::First { f: future } + } +} + +impl FusedFuture for Flatten +where + Fut: Future, + Fut::Output: Future, +{ + fn is_terminated(&self) -> bool { + match self { + Self::Empty => true, + _ => false, + } + } +} + +impl Future for Flatten +where + Fut: Future, + Fut::Output: Future, +{ + type Output = ::Output; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready(loop { + match self.as_mut().project() { + FlattenProj::First { f } => { + let f = ready!(f.poll(cx)); + self.set(Self::Second { f }); + } + FlattenProj::Second { f } => { + let output = ready!(f.poll(cx)); + self.set(Self::Empty); + break output; + } + FlattenProj::Empty => panic!("Flatten polled after completion"), + } + }) + } +} + +impl FusedStream for Flatten +where + Fut: Future, + Fut::Output: Stream, +{ + fn is_terminated(&self) -> bool { + match self { + Self::Empty => true, + _ => false, + } + } +} + +impl Stream for Flatten +where + Fut: Future, + Fut::Output: Stream, +{ + type Item = ::Item; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(loop { + match self.as_mut().project() { + FlattenProj::First { f } => { + let f = ready!(f.poll(cx)); + self.set(Self::Second { f }); + } + FlattenProj::Second { f } => { + let output = ready!(f.poll_next(cx)); + if output.is_none() { + self.set(Self::Empty); + } + break output; + } + FlattenProj::Empty => break None, + } + }) + } +} + +#[cfg(feature = "sink")] +impl Sink for Flatten +where + Fut: Future, + Fut::Output: Sink, +{ + type Error = >::Error; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(loop { + match self.as_mut().project() { + FlattenProj::First { f } => { + let f = ready!(f.poll(cx)); + self.set(Self::Second { f }); + } + FlattenProj::Second { f } => { + break ready!(f.poll_ready(cx)); + } + FlattenProj::Empty => panic!("poll_ready called after eof"), + } + }) + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + match self.project() { + FlattenProj::First { .. } => panic!("poll_ready not called first"), + FlattenProj::Second { f } => f.start_send(item), + FlattenProj::Empty => panic!("start_send called after eof"), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + FlattenProj::First { .. } => Poll::Ready(Ok(())), + FlattenProj::Second { f } => f.poll_flush(cx), + FlattenProj::Empty => panic!("poll_flush called after eof"), + } + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let res = match self.as_mut().project() { + FlattenProj::Second { f } => f.poll_close(cx), + _ => Poll::Ready(Ok(())), + }; + if res.is_ready() { + self.set(Self::Empty); + } + res + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/fuse.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/fuse.rs new file mode 100644 index 00000000..22579067 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/fuse.rs @@ -0,0 +1,91 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`fuse`](super::FutureExt::fuse) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Fuse { + #[pin] + inner: Option, + } +} + +impl Fuse { + pub(super) fn new(f: Fut) -> Self { + Self { inner: Some(f) } + } +} + +impl Fuse { + /// Creates a new `Fuse`-wrapped future which is already terminated. + /// + /// This can be useful in combination with looping and the `select!` + /// macro, which bypasses terminated futures. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::future::{Fuse, FusedFuture, FutureExt}; + /// use futures::select; + /// use futures::stream::StreamExt; + /// use futures::pin_mut; + /// + /// let (sender, mut stream) = mpsc::unbounded(); + /// + /// // Send a few messages into the stream + /// sender.unbounded_send(()).unwrap(); + /// sender.unbounded_send(()).unwrap(); + /// drop(sender); + /// + /// // Use `Fuse::terminated()` to create an already-terminated future + /// // which may be instantiated later. + /// let foo_printer = Fuse::terminated(); + /// pin_mut!(foo_printer); + /// + /// loop { + /// select! { + /// _ = foo_printer => {}, + /// () = stream.select_next_some() => { + /// if !foo_printer.is_terminated() { + /// println!("Foo is already being printed!"); + /// } else { + /// foo_printer.set(async { + /// // do some other async operations + /// println!("Printing foo from `foo_printer` future"); + /// }.fuse()); + /// } + /// }, + /// complete => break, // `foo_printer` is terminated and the stream is done + /// } + /// } + /// # }); + /// ``` + pub fn terminated() -> Self { + Self { inner: None } + } +} + +impl FusedFuture for Fuse { + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +impl Future for Fuse { + type Output = Fut::Output; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.as_mut().project().inner.as_pin_mut() { + Some(fut) => fut.poll(cx).map(|output| { + self.project().inner.set(None); + output + }), + None => Poll::Pending, + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/map.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/map.rs new file mode 100644 index 00000000..7471aba0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/map.rs @@ -0,0 +1,66 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +use crate::fns::FnOnce1; + +pin_project! { + /// Internal Map future + #[project = MapProj] + #[project_replace = MapProjReplace] + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub enum Map { + Incomplete { + #[pin] + future: Fut, + f: F, + }, + Complete, + } +} + +impl Map { + /// Creates a new Map. + pub(crate) fn new(future: Fut, f: F) -> Self { + Self::Incomplete { future, f } + } +} + +impl FusedFuture for Map +where + Fut: Future, + F: FnOnce1, +{ + fn is_terminated(&self) -> bool { + match self { + Self::Incomplete { .. } => false, + Self::Complete => true, + } + } +} + +impl Future for Map +where + Fut: Future, + F: FnOnce1, +{ + type Output = T; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.as_mut().project() { + MapProj::Incomplete { future, .. } => { + let output = ready!(future.poll(cx)); + match self.project_replace(Map::Complete) { + MapProjReplace::Incomplete { f, .. } => Poll::Ready(f.call_once(output)), + MapProjReplace::Complete => unreachable!(), + } + } + MapProj::Complete => { + panic!("Map must not be polled after it returned `Poll::Ready`") + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/mod.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/mod.rs new file mode 100644 index 00000000..955af377 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/mod.rs @@ -0,0 +1,606 @@ +//! Futures +//! +//! This module contains a number of functions for working with `Future`s, +//! including the `FutureExt` trait which adds methods to `Future` types. + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +use core::pin::Pin; + +use crate::fns::{inspect_fn, into_fn, ok_fn, InspectFn, IntoFn, OkFn}; +use crate::future::{assert_future, Either}; +use crate::never::Never; +use crate::stream::assert_stream; +#[cfg(feature = "alloc")] +use futures_core::future::{BoxFuture, LocalBoxFuture}; +use futures_core::{ + future::Future, + stream::Stream, + task::{Context, Poll}, +}; +use pin_utils::pin_mut; + +// Combinators + +mod flatten; +mod fuse; +mod map; + +delegate_all!( + /// Future for the [`flatten`](super::FutureExt::flatten) method. + Flatten( + flatten::Flatten::Output> + ): Debug + Future + FusedFuture + New[|x: F| flatten::Flatten::new(x)] + where F: Future +); + +delegate_all!( + /// Stream for the [`flatten_stream`](FutureExt::flatten_stream) method. + FlattenStream( + flatten::Flatten::Output> + ): Debug + Sink + Stream + FusedStream + New[|x: F| flatten::Flatten::new(x)] + where F: Future +); + +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use fuse::Fuse; + +delegate_all!( + /// Future for the [`map`](super::FutureExt::map) method. + Map( + map::Map + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| map::Map::new(x, f)] +); + +delegate_all!( + /// Stream for the [`into_stream`](FutureExt::into_stream) method. + IntoStream( + crate::stream::Once + ): Debug + Stream + FusedStream + New[|x: F| crate::stream::Once::new(x)] +); + +delegate_all!( + /// Future for the [`map_into`](FutureExt::map_into) combinator. + MapInto( + Map> + ): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, into_fn())] +); + +delegate_all!( + /// Future for the [`then`](FutureExt::then) method. + Then( + flatten::Flatten, Fut2> + ): Debug + Future + FusedFuture + New[|x: Fut1, y: F| flatten::Flatten::new(Map::new(x, y))] +); + +delegate_all!( + /// Future for the [`inspect`](FutureExt::inspect) method. + Inspect( + map::Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| map::Map::new(x, inspect_fn(f))] +); + +delegate_all!( + /// Future for the [`never_error`](super::FutureExt::never_error) combinator. + NeverError( + Map> + ): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, ok_fn())] +); + +delegate_all!( + /// Future for the [`unit_error`](super::FutureExt::unit_error) combinator. + UnitError( + Map> + ): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, ok_fn())] +); + +#[cfg(feature = "std")] +mod catch_unwind; +#[cfg(feature = "std")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::catch_unwind::CatchUnwind; + +#[cfg(feature = "channel")] +#[cfg_attr(docsrs, doc(cfg(feature = "channel")))] +#[cfg(feature = "std")] +mod remote_handle; +#[cfg(feature = "channel")] +#[cfg_attr(docsrs, doc(cfg(feature = "channel")))] +#[cfg(feature = "std")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::remote_handle::{Remote, RemoteHandle}; + +#[cfg(feature = "std")] +mod shared; +#[cfg(feature = "std")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::shared::{Shared, WeakShared}; + +impl FutureExt for T where T: Future {} + +/// An extension trait for `Future`s that provides a variety of convenient +/// adapters. +pub trait FutureExt: Future { + /// Map this future's output to a different type, returning a new future of + /// the resulting type. + /// + /// This function is similar to the `Option::map` or `Iterator::map` where + /// it will change the type of the underlying future. This is useful to + /// chain along a computation once a future has been resolved. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it, similar to the existing `map` methods in the + /// standard library. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let future = async { 1 }; + /// let new_future = future.map(|x| x + 3); + /// assert_eq!(new_future.await, 4); + /// # }); + /// ``` + fn map(self, f: F) -> Map + where + F: FnOnce(Self::Output) -> U, + Self: Sized, + { + assert_future::(Map::new(self, f)) + } + + /// Map this future's output to a different type, returning a new future of + /// the resulting type. + /// + /// This function is equivalent to calling `map(Into::into)` but allows naming + /// the return type. + fn map_into(self) -> MapInto + where + Self::Output: Into, + Self: Sized, + { + assert_future::(MapInto::new(self)) + } + + /// Chain on a computation for when a future finished, passing the result of + /// the future to the provided closure `f`. + /// + /// The returned value of the closure must implement the `Future` trait + /// and can represent some more work to be done before the composed future + /// is finished. + /// + /// The closure `f` is only run *after* successful completion of the `self` + /// future. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let future_of_1 = async { 1 }; + /// let future_of_4 = future_of_1.then(|x| async move { x + 3 }); + /// assert_eq!(future_of_4.await, 4); + /// # }); + /// ``` + fn then(self, f: F) -> Then + where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized, + { + assert_future::(Then::new(self, f)) + } + + /// Wrap this future in an `Either` future, making it the left-hand variant + /// of that `Either`. + /// + /// This can be used in combination with the `right_future` method to write `if` + /// statements that evaluate to different futures in different branches. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let x = 6; + /// let future = if x < 10 { + /// async { true }.left_future() + /// } else { + /// async { false }.right_future() + /// }; + /// + /// assert_eq!(future.await, true); + /// # }); + /// ``` + fn left_future(self) -> Either + where + B: Future, + Self: Sized, + { + assert_future::(Either::Left(self)) + } + + /// Wrap this future in an `Either` future, making it the right-hand variant + /// of that `Either`. + /// + /// This can be used in combination with the `left_future` method to write `if` + /// statements that evaluate to different futures in different branches. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let x = 6; + /// let future = if x > 10 { + /// async { true }.left_future() + /// } else { + /// async { false }.right_future() + /// }; + /// + /// assert_eq!(future.await, false); + /// # }); + /// ``` + fn right_future(self) -> Either + where + A: Future, + Self: Sized, + { + assert_future::(Either::Right(self)) + } + + /// Convert this future into a single element stream. + /// + /// The returned stream contains single success if this future resolves to + /// success or single error if this future resolves into error. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::stream::StreamExt; + /// + /// let future = async { 17 }; + /// let stream = future.into_stream(); + /// let collected: Vec<_> = stream.collect().await; + /// assert_eq!(collected, vec![17]); + /// # }); + /// ``` + fn into_stream(self) -> IntoStream + where + Self: Sized, + { + assert_stream::(IntoStream::new(self)) + } + + /// Flatten the execution of this future when the output of this + /// future is itself another future. + /// + /// This can be useful when combining futures together to flatten the + /// computation out the final result. + /// + /// This method is roughly equivalent to `self.then(|x| x)`. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let nested_future = async { async { 1 } }; + /// let future = nested_future.flatten(); + /// assert_eq!(future.await, 1); + /// # }); + /// ``` + fn flatten(self) -> Flatten + where + Self::Output: Future, + Self: Sized, + { + let f = Flatten::new(self); + assert_future::<<::Output as Future>::Output, _>(f) + } + + /// Flatten the execution of this future when the successful result of this + /// future is a stream. + /// + /// This can be useful when stream initialization is deferred, and it is + /// convenient to work with that stream as if stream was available at the + /// call site. + /// + /// Note that this function consumes this future and returns a wrapped + /// version of it. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::stream::{self, StreamExt}; + /// + /// let stream_items = vec![17, 18, 19]; + /// let future_of_a_stream = async { stream::iter(stream_items) }; + /// + /// let stream = future_of_a_stream.flatten_stream(); + /// let list: Vec<_> = stream.collect().await; + /// assert_eq!(list, vec![17, 18, 19]); + /// # }); + /// ``` + fn flatten_stream(self) -> FlattenStream + where + Self::Output: Stream, + Self: Sized, + { + assert_stream::<::Item, _>(FlattenStream::new(self)) + } + + /// Fuse a future such that `poll` will never again be called once it has + /// completed. This method can be used to turn any `Future` into a + /// `FusedFuture`. + /// + /// Normally, once a future has returned `Poll::Ready` from `poll`, + /// any further calls could exhibit bad behavior such as blocking + /// forever, panicking, never returning, etc. If it is known that `poll` + /// may be called too often then this method can be used to ensure that it + /// has defined semantics. + /// + /// If a `fuse`d future is `poll`ed after having returned `Poll::Ready` + /// previously, it will return `Poll::Pending`, from `poll` again (and will + /// continue to do so for all future calls to `poll`). + /// + /// This combinator will drop the underlying future as soon as it has been + /// completed to ensure resources are reclaimed as soon as possible. + fn fuse(self) -> Fuse + where + Self: Sized, + { + let f = Fuse::new(self); + assert_future::(f) + } + + /// Do something with the output of a future before passing it on. + /// + /// When using futures, you'll often chain several of them together. While + /// working on such code, you might want to check out what's happening at + /// various parts in the pipeline, without consuming the intermediate + /// value. To do that, insert a call to `inspect`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let future = async { 1 }; + /// let new_future = future.inspect(|&x| println!("about to resolve: {}", x)); + /// assert_eq!(new_future.await, 1); + /// # }); + /// ``` + fn inspect(self, f: F) -> Inspect + where + F: FnOnce(&Self::Output), + Self: Sized, + { + assert_future::(Inspect::new(self, f)) + } + + /// Catches unwinding panics while polling the future. + /// + /// In general, panics within a future can propagate all the way out to the + /// task level. This combinator makes it possible to halt unwinding within + /// the future itself. It's most commonly used within task executors. It's + /// not recommended to use this for error handling. + /// + /// Note that this method requires the `UnwindSafe` bound from the standard + /// library. This isn't always applied automatically, and the standard + /// library provides an `AssertUnwindSafe` wrapper type to apply it + /// after-the fact. To assist using this method, the `Future` trait is also + /// implemented for `AssertUnwindSafe` where `F` implements `Future`. + /// + /// This method is only available when the `std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::{self, FutureExt, Ready}; + /// + /// let future = future::ready(2); + /// assert!(future.catch_unwind().await.is_ok()); + /// + /// let future = future::lazy(|_| -> Ready { + /// unimplemented!() + /// }); + /// assert!(future.catch_unwind().await.is_err()); + /// # }); + /// ``` + #[cfg(feature = "std")] + fn catch_unwind(self) -> CatchUnwind + where + Self: Sized + ::std::panic::UnwindSafe, + { + assert_future::>, _>(CatchUnwind::new( + self, + )) + } + + /// Create a cloneable handle to this future where all handles will resolve + /// to the same result. + /// + /// The `shared` combinator method provides a method to convert any future + /// into a cloneable future. It enables a future to be polled by multiple + /// threads. + /// + /// This method is only available when the `std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// + /// let future = async { 6 }; + /// let shared1 = future.shared(); + /// let shared2 = shared1.clone(); + /// + /// assert_eq!(6, shared1.await); + /// assert_eq!(6, shared2.await); + /// # }); + /// ``` + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::FutureExt; + /// use futures::executor::block_on; + /// use std::thread; + /// + /// let future = async { 6 }; + /// let shared1 = future.shared(); + /// let shared2 = shared1.clone(); + /// let join_handle = thread::spawn(move || { + /// assert_eq!(6, block_on(shared2)); + /// }); + /// assert_eq!(6, shared1.await); + /// join_handle.join().unwrap(); + /// # }); + /// ``` + #[cfg(feature = "std")] + fn shared(self) -> Shared + where + Self: Sized, + Self::Output: Clone, + { + assert_future::(Shared::new(self)) + } + + /// Turn this future into a future that yields `()` on completion and sends + /// its output to another future on a separate task. + /// + /// This can be used with spawning executors to easily retrieve the result + /// of a future executing on a separate task or thread. + /// + /// This method is only available when the `std` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "channel")] + #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] + #[cfg(feature = "std")] + fn remote_handle(self) -> (Remote, RemoteHandle) + where + Self: Sized, + { + let (wrapped, handle) = remote_handle::remote_handle(self); + (assert_future::<(), _>(wrapped), handle) + } + + /// Wrap the future in a Box, pinning it. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "alloc")] + fn boxed<'a>(self) -> BoxFuture<'a, Self::Output> + where + Self: Sized + Send + 'a, + { + assert_future::(Box::pin(self)) + } + + /// Wrap the future in a Box, pinning it. + /// + /// Similar to `boxed`, but without the `Send` requirement. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "alloc")] + fn boxed_local<'a>(self) -> LocalBoxFuture<'a, Self::Output> + where + Self: Sized + 'a, + { + assert_future::(Box::pin(self)) + } + + /// Turns a [`Future`](Future) into a + /// [`TryFuture](futures_core::future::TryFuture). + fn unit_error(self) -> UnitError + where + Self: Sized, + { + assert_future::, _>(UnitError::new(self)) + } + + /// Turns a [`Future`](Future) into a + /// [`TryFuture](futures_core::future::TryFuture). + fn never_error(self) -> NeverError + where + Self: Sized, + { + assert_future::, _>(NeverError::new(self)) + } + + /// A convenience for calling `Future::poll` on `Unpin` future types. + fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll + where + Self: Unpin, + { + Pin::new(self).poll(cx) + } + + /// Evaluates and consumes the future, returning the resulting output if + /// the future is ready after the first call to `Future::poll`. + /// + /// If `poll` instead returns `Poll::Pending`, `None` is returned. + /// + /// This method is useful in cases where immediacy is more important than + /// waiting for a result. It is also convenient for quickly obtaining + /// the value of a future that is known to always resolve immediately. + /// + /// # Examples + /// + /// ``` + /// # use futures::prelude::*; + /// use futures::{future::ready, future::pending}; + /// let future_ready = ready("foobar"); + /// let future_pending = pending::<&'static str>(); + /// + /// assert_eq!(future_ready.now_or_never(), Some("foobar")); + /// assert_eq!(future_pending.now_or_never(), None); + /// ``` + /// + /// In cases where it is absolutely known that a future should always + /// resolve immediately and never return `Poll::Pending`, this method can + /// be combined with `expect()`: + /// + /// ``` + /// # use futures::{prelude::*, future::ready}; + /// let future_ready = ready("foobar"); + /// + /// assert_eq!(future_ready.now_or_never().expect("Future not ready"), "foobar"); + /// ``` + fn now_or_never(self) -> Option + where + Self: Sized, + { + let noop_waker = crate::task::noop_waker(); + let mut cx = Context::from_waker(&noop_waker); + + let this = self; + pin_mut!(this); + match this.poll(&mut cx) { + Poll::Ready(x) => Some(x), + _ => None, + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/remote_handle.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/remote_handle.rs new file mode 100644 index 00000000..1358902c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/remote_handle.rs @@ -0,0 +1,126 @@ +use { + crate::future::{CatchUnwind, FutureExt}, + futures_channel::oneshot::{self, Receiver, Sender}, + futures_core::{ + future::Future, + ready, + task::{Context, Poll}, + }, + pin_project_lite::pin_project, + std::{ + any::Any, + fmt, + panic::{self, AssertUnwindSafe}, + pin::Pin, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + thread, + }, +}; + +/// The handle to a remote future returned by +/// [`remote_handle`](crate::future::FutureExt::remote_handle). When you drop this, +/// the remote future will be woken up to be dropped by the executor. +/// +/// ## Unwind safety +/// +/// When the remote future panics, [Remote] will catch the unwind and transfer it to +/// the thread where `RemoteHandle` is being awaited. This is good for the common +/// case where [Remote] is spawned on a threadpool. It is unlikely that other code +/// in the executor working thread shares mutable data with the spawned future and we +/// preserve the executor from losing its working threads. +/// +/// If you run the future locally and send the handle of to be awaited elsewhere, you +/// must be careful with regard to unwind safety because the thread in which the future +/// is polled will keep running after the panic and the thread running the [RemoteHandle] +/// will unwind. +#[must_use = "dropping a remote handle cancels the underlying future"] +#[derive(Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "channel")))] +pub struct RemoteHandle { + rx: Receiver>, + keep_running: Arc, +} + +impl RemoteHandle { + /// Drops this handle *without* canceling the underlying future. + /// + /// This method can be used if you want to drop the handle, but let the + /// execution continue. + pub fn forget(self) { + self.keep_running.store(true, Ordering::SeqCst); + } +} + +impl Future for RemoteHandle { + type Output = T; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match ready!(self.rx.poll_unpin(cx)) { + Ok(Ok(output)) => Poll::Ready(output), + // the remote future panicked. + Ok(Err(e)) => panic::resume_unwind(e), + // The oneshot sender was dropped. + Err(e) => panic::resume_unwind(Box::new(e)), + } + } +} + +type SendMsg = Result<::Output, Box<(dyn Any + Send + 'static)>>; + +pin_project! { + /// A future which sends its output to the corresponding `RemoteHandle`. + /// Created by [`remote_handle`](crate::future::FutureExt::remote_handle). + #[must_use = "futures do nothing unless you `.await` or poll them"] + #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] + pub struct Remote { + tx: Option>>, + keep_running: Arc, + #[pin] + future: CatchUnwind>, + } +} + +impl fmt::Debug for Remote { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Remote").field(&self.future).finish() + } +} + +impl Future for Remote { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + let this = self.project(); + + if this.tx.as_mut().unwrap().poll_canceled(cx).is_ready() + && !this.keep_running.load(Ordering::SeqCst) + { + // Cancelled, bail out + return Poll::Ready(()); + } + + let output = ready!(this.future.poll(cx)); + + // if the receiving end has gone away then that's ok, we just ignore the + // send error here. + drop(this.tx.take().unwrap().send(output)); + Poll::Ready(()) + } +} + +pub(super) fn remote_handle(future: Fut) -> (Remote, RemoteHandle) { + let (tx, rx) = oneshot::channel(); + let keep_running = Arc::new(AtomicBool::new(false)); + + // Unwind Safety: See the docs for RemoteHandle. + let wrapped = Remote { + future: AssertUnwindSafe(future).catch_unwind(), + tx: Some(tx), + keep_running: keep_running.clone(), + }; + + (wrapped, RemoteHandle { rx, keep_running }) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/future/shared.rs b/utshell-0.5.0/vendor/futures-util/src/future/future/shared.rs new file mode 100644 index 00000000..9ab3b4f1 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/future/shared.rs @@ -0,0 +1,409 @@ +use crate::task::{waker_ref, ArcWake}; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll, Waker}; +use slab::Slab; +use std::cell::UnsafeCell; +use std::fmt; +use std::hash::Hasher; +use std::pin::Pin; +use std::ptr; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::{Acquire, SeqCst}; +use std::sync::{Arc, Mutex, Weak}; + +/// Future for the [`shared`](super::FutureExt::shared) method. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Shared { + inner: Option>>, + waker_key: usize, +} + +struct Inner { + future_or_output: UnsafeCell>, + notifier: Arc, +} + +struct Notifier { + state: AtomicUsize, + wakers: Mutex>>>, +} + +/// A weak reference to a [`Shared`] that can be upgraded much like an `Arc`. +pub struct WeakShared(Weak>); + +impl Clone for WeakShared { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl fmt::Debug for Shared { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Shared") + .field("inner", &self.inner) + .field("waker_key", &self.waker_key) + .finish() + } +} + +impl fmt::Debug for Inner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Inner").finish() + } +} + +impl fmt::Debug for WeakShared { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("WeakShared").finish() + } +} + +enum FutureOrOutput { + Future(Fut), + Output(Fut::Output), +} + +unsafe impl Send for Inner +where + Fut: Future + Send, + Fut::Output: Send + Sync, +{ +} + +unsafe impl Sync for Inner +where + Fut: Future + Send, + Fut::Output: Send + Sync, +{ +} + +const IDLE: usize = 0; +const POLLING: usize = 1; +const COMPLETE: usize = 2; +const POISONED: usize = 3; + +const NULL_WAKER_KEY: usize = usize::max_value(); + +impl Shared { + pub(super) fn new(future: Fut) -> Self { + let inner = Inner { + future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)), + notifier: Arc::new(Notifier { + state: AtomicUsize::new(IDLE), + wakers: Mutex::new(Some(Slab::new())), + }), + }; + + Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY } + } +} + +impl Shared +where + Fut: Future, +{ + /// Returns [`Some`] containing a reference to this [`Shared`]'s output if + /// it has already been computed by a clone or [`None`] if it hasn't been + /// computed yet or this [`Shared`] already returned its output from + /// [`poll`](Future::poll). + pub fn peek(&self) -> Option<&Fut::Output> { + if let Some(inner) = self.inner.as_ref() { + match inner.notifier.state.load(SeqCst) { + COMPLETE => unsafe { return Some(inner.output()) }, + POISONED => panic!("inner future panicked during poll"), + _ => {} + } + } + None + } + + /// Creates a new [`WeakShared`] for this [`Shared`]. + /// + /// Returns [`None`] if it has already been polled to completion. + pub fn downgrade(&self) -> Option> { + if let Some(inner) = self.inner.as_ref() { + return Some(WeakShared(Arc::downgrade(inner))); + } + None + } + + /// Gets the number of strong pointers to this allocation. + /// + /// Returns [`None`] if it has already been polled to completion. + /// + /// # Safety + /// + /// This method by itself is safe, but using it correctly requires extra care. Another thread + /// can change the strong count at any time, including potentially between calling this method + /// and acting on the result. + #[allow(clippy::unnecessary_safety_doc)] + pub fn strong_count(&self) -> Option { + self.inner.as_ref().map(|arc| Arc::strong_count(arc)) + } + + /// Gets the number of weak pointers to this allocation. + /// + /// Returns [`None`] if it has already been polled to completion. + /// + /// # Safety + /// + /// This method by itself is safe, but using it correctly requires extra care. Another thread + /// can change the weak count at any time, including potentially between calling this method + /// and acting on the result. + #[allow(clippy::unnecessary_safety_doc)] + pub fn weak_count(&self) -> Option { + self.inner.as_ref().map(|arc| Arc::weak_count(arc)) + } + + /// Hashes the internal state of this `Shared` in a way that's compatible with `ptr_eq`. + pub fn ptr_hash(&self, state: &mut H) { + match self.inner.as_ref() { + Some(arc) => { + state.write_u8(1); + ptr::hash(Arc::as_ptr(arc), state); + } + None => { + state.write_u8(0); + } + } + } + + /// Returns `true` if the two `Shared`s point to the same future (in a vein similar to + /// `Arc::ptr_eq`). + /// + /// Returns `false` if either `Shared` has terminated. + pub fn ptr_eq(&self, rhs: &Self) -> bool { + let lhs = match self.inner.as_ref() { + Some(lhs) => lhs, + None => return false, + }; + let rhs = match rhs.inner.as_ref() { + Some(rhs) => rhs, + None => return false, + }; + Arc::ptr_eq(lhs, rhs) + } +} + +impl Inner +where + Fut: Future, +{ + /// Safety: callers must first ensure that `self.inner.state` + /// is `COMPLETE` + unsafe fn output(&self) -> &Fut::Output { + match &*self.future_or_output.get() { + FutureOrOutput::Output(ref item) => item, + FutureOrOutput::Future(_) => unreachable!(), + } + } +} + +impl Inner +where + Fut: Future, + Fut::Output: Clone, +{ + /// Registers the current task to receive a wakeup when we are awoken. + fn record_waker(&self, waker_key: &mut usize, cx: &mut Context<'_>) { + let mut wakers_guard = self.notifier.wakers.lock().unwrap(); + + let wakers = match wakers_guard.as_mut() { + Some(wakers) => wakers, + None => return, + }; + + let new_waker = cx.waker(); + + if *waker_key == NULL_WAKER_KEY { + *waker_key = wakers.insert(Some(new_waker.clone())); + } else { + match wakers[*waker_key] { + Some(ref old_waker) if new_waker.will_wake(old_waker) => {} + // Could use clone_from here, but Waker doesn't specialize it. + ref mut slot => *slot = Some(new_waker.clone()), + } + } + debug_assert!(*waker_key != NULL_WAKER_KEY); + } + + /// Safety: callers must first ensure that `inner.state` + /// is `COMPLETE` + unsafe fn take_or_clone_output(self: Arc) -> Fut::Output { + match Arc::try_unwrap(self) { + Ok(inner) => match inner.future_or_output.into_inner() { + FutureOrOutput::Output(item) => item, + FutureOrOutput::Future(_) => unreachable!(), + }, + Err(inner) => inner.output().clone(), + } + } +} + +impl FusedFuture for Shared +where + Fut: Future, + Fut::Output: Clone, +{ + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +impl Future for Shared +where + Fut: Future, + Fut::Output: Clone, +{ + type Output = Fut::Output; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + + let inner = this.inner.take().expect("Shared future polled again after completion"); + + // Fast path for when the wrapped future has already completed + if inner.notifier.state.load(Acquire) == COMPLETE { + // Safety: We're in the COMPLETE state + return unsafe { Poll::Ready(inner.take_or_clone_output()) }; + } + + inner.record_waker(&mut this.waker_key, cx); + + match inner + .notifier + .state + .compare_exchange(IDLE, POLLING, SeqCst, SeqCst) + .unwrap_or_else(|x| x) + { + IDLE => { + // Lock acquired, fall through + } + POLLING => { + // Another task is currently polling, at this point we just want + // to ensure that the waker for this task is registered + this.inner = Some(inner); + return Poll::Pending; + } + COMPLETE => { + // Safety: We're in the COMPLETE state + return unsafe { Poll::Ready(inner.take_or_clone_output()) }; + } + POISONED => panic!("inner future panicked during poll"), + _ => unreachable!(), + } + + let waker = waker_ref(&inner.notifier); + let mut cx = Context::from_waker(&waker); + + struct Reset<'a> { + state: &'a AtomicUsize, + did_not_panic: bool, + } + + impl Drop for Reset<'_> { + fn drop(&mut self) { + if !self.did_not_panic { + self.state.store(POISONED, SeqCst); + } + } + } + + let mut reset = Reset { state: &inner.notifier.state, did_not_panic: false }; + + let output = { + let future = unsafe { + match &mut *inner.future_or_output.get() { + FutureOrOutput::Future(fut) => Pin::new_unchecked(fut), + _ => unreachable!(), + } + }; + + let poll_result = future.poll(&mut cx); + reset.did_not_panic = true; + + match poll_result { + Poll::Pending => { + if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok() + { + // Success + drop(reset); + this.inner = Some(inner); + return Poll::Pending; + } else { + unreachable!() + } + } + Poll::Ready(output) => output, + } + }; + + unsafe { + *inner.future_or_output.get() = FutureOrOutput::Output(output); + } + + inner.notifier.state.store(COMPLETE, SeqCst); + + // Wake all tasks and drop the slab + let mut wakers_guard = inner.notifier.wakers.lock().unwrap(); + let mut wakers = wakers_guard.take().unwrap(); + for waker in wakers.drain().flatten() { + waker.wake(); + } + + drop(reset); // Make borrow checker happy + drop(wakers_guard); + + // Safety: We're in the COMPLETE state + unsafe { Poll::Ready(inner.take_or_clone_output()) } + } +} + +impl Clone for Shared +where + Fut: Future, +{ + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY } + } +} + +impl Drop for Shared +where + Fut: Future, +{ + fn drop(&mut self) { + if self.waker_key != NULL_WAKER_KEY { + if let Some(ref inner) = self.inner { + if let Ok(mut wakers) = inner.notifier.wakers.lock() { + if let Some(wakers) = wakers.as_mut() { + wakers.remove(self.waker_key); + } + } + } + } + } +} + +impl ArcWake for Notifier { + fn wake_by_ref(arc_self: &Arc) { + let wakers = &mut *arc_self.wakers.lock().unwrap(); + if let Some(wakers) = wakers.as_mut() { + for (_key, opt_waker) in wakers { + if let Some(waker) = opt_waker.take() { + waker.wake(); + } + } + } + } +} + +impl WeakShared { + /// Attempts to upgrade this [`WeakShared`] into a [`Shared`]. + /// + /// Returns [`None`] if all clones of the [`Shared`] have been dropped or polled + /// to completion. + pub fn upgrade(&self) -> Option> { + Some(Shared { inner: Some(self.0.upgrade()?), waker_key: NULL_WAKER_KEY }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/join.rs b/utshell-0.5.0/vendor/futures-util/src/future/join.rs new file mode 100644 index 00000000..740ffbc9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/join.rs @@ -0,0 +1,217 @@ +#![allow(non_snake_case)] + +use super::assert_future; +use crate::future::{maybe_done, MaybeDone}; +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +macro_rules! generate { + ($( + $(#[$doc:meta])* + ($Join:ident, <$($Fut:ident),*>), + )*) => ($( + pin_project! { + $(#[$doc])* + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct $Join<$($Fut: Future),*> { + $(#[pin] $Fut: MaybeDone<$Fut>,)* + } + } + + impl<$($Fut),*> fmt::Debug for $Join<$($Fut),*> + where + $( + $Fut: Future + fmt::Debug, + $Fut::Output: fmt::Debug, + )* + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(stringify!($Join)) + $(.field(stringify!($Fut), &self.$Fut))* + .finish() + } + } + + impl<$($Fut: Future),*> $Join<$($Fut),*> { + fn new($($Fut: $Fut),*) -> Self { + Self { + $($Fut: maybe_done($Fut)),* + } + } + } + + impl<$($Fut: Future),*> Future for $Join<$($Fut),*> { + type Output = ($($Fut::Output),*); + + fn poll( + self: Pin<&mut Self>, cx: &mut Context<'_> + ) -> Poll { + let mut all_done = true; + let mut futures = self.project(); + $( + all_done &= futures.$Fut.as_mut().poll(cx).is_ready(); + )* + + if all_done { + Poll::Ready(($(futures.$Fut.take_output().unwrap()), *)) + } else { + Poll::Pending + } + } + } + + impl<$($Fut: FusedFuture),*> FusedFuture for $Join<$($Fut),*> { + fn is_terminated(&self) -> bool { + $( + self.$Fut.is_terminated() + ) && * + } + } + )*) +} + +generate! { + /// Future for the [`join`](join()) function. + (Join, ), + + /// Future for the [`join3`] function. + (Join3, ), + + /// Future for the [`join4`] function. + (Join4, ), + + /// Future for the [`join5`] function. + (Join5, ), +} + +/// Joins the result of two futures, waiting for them both to complete. +/// +/// This function will return a new future which awaits both futures to +/// complete. The returned future will finish with a tuple of both results. +/// +/// Note that this function consumes the passed futures and returns a +/// wrapped version of it. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = async { 1 }; +/// let b = async { 2 }; +/// let pair = future::join(a, b); +/// +/// assert_eq!(pair.await, (1, 2)); +/// # }); +/// ``` +pub fn join(future1: Fut1, future2: Fut2) -> Join +where + Fut1: Future, + Fut2: Future, +{ + let f = Join::new(future1, future2); + assert_future::<(Fut1::Output, Fut2::Output), _>(f) +} + +/// Same as [`join`](join()), but with more futures. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = async { 1 }; +/// let b = async { 2 }; +/// let c = async { 3 }; +/// let tuple = future::join3(a, b, c); +/// +/// assert_eq!(tuple.await, (1, 2, 3)); +/// # }); +/// ``` +pub fn join3( + future1: Fut1, + future2: Fut2, + future3: Fut3, +) -> Join3 +where + Fut1: Future, + Fut2: Future, + Fut3: Future, +{ + let f = Join3::new(future1, future2, future3); + assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output), _>(f) +} + +/// Same as [`join`](join()), but with more futures. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = async { 1 }; +/// let b = async { 2 }; +/// let c = async { 3 }; +/// let d = async { 4 }; +/// let tuple = future::join4(a, b, c, d); +/// +/// assert_eq!(tuple.await, (1, 2, 3, 4)); +/// # }); +/// ``` +pub fn join4( + future1: Fut1, + future2: Fut2, + future3: Fut3, + future4: Fut4, +) -> Join4 +where + Fut1: Future, + Fut2: Future, + Fut3: Future, + Fut4: Future, +{ + let f = Join4::new(future1, future2, future3, future4); + assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output), _>(f) +} + +/// Same as [`join`](join()), but with more futures. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = async { 1 }; +/// let b = async { 2 }; +/// let c = async { 3 }; +/// let d = async { 4 }; +/// let e = async { 5 }; +/// let tuple = future::join5(a, b, c, d, e); +/// +/// assert_eq!(tuple.await, (1, 2, 3, 4, 5)); +/// # }); +/// ``` +pub fn join5( + future1: Fut1, + future2: Fut2, + future3: Fut3, + future4: Fut4, + future5: Fut5, +) -> Join5 +where + Fut1: Future, + Fut2: Future, + Fut3: Future, + Fut4: Future, + Fut5: Future, +{ + let f = Join5::new(future1, future2, future3, future4, future5); + assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output, Fut5::Output), _>(f) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/join_all.rs b/utshell-0.5.0/vendor/futures-util/src/future/join_all.rs new file mode 100644 index 00000000..79eee8df --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/join_all.rs @@ -0,0 +1,167 @@ +//! Definition of the `JoinAll` combinator, waiting for all of a list of futures +//! to finish. + +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::fmt; +use core::future::Future; +use core::iter::FromIterator; +use core::mem; +use core::pin::Pin; +use core::task::{Context, Poll}; + +use super::{assert_future, MaybeDone}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +use crate::stream::{Collect, FuturesOrdered, StreamExt}; + +pub(crate) fn iter_pin_mut(slice: Pin<&mut [T]>) -> impl Iterator> { + // Safety: `std` _could_ make this unsound if it were to decide Pin's + // invariants aren't required to transmit through slices. Otherwise this has + // the same safety as a normal field pin projection. + unsafe { slice.get_unchecked_mut() }.iter_mut().map(|t| unsafe { Pin::new_unchecked(t) }) +} + +#[must_use = "futures do nothing unless you `.await` or poll them"] +/// Future for the [`join_all`] function. +pub struct JoinAll +where + F: Future, +{ + kind: JoinAllKind, +} + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +pub(crate) const SMALL: usize = 30; + +enum JoinAllKind +where + F: Future, +{ + Small { + elems: Pin]>>, + }, + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + Big { + fut: Collect, Vec>, + }, +} + +impl fmt::Debug for JoinAll +where + F: Future + fmt::Debug, + F::Output: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.kind { + JoinAllKind::Small { ref elems } => { + f.debug_struct("JoinAll").field("elems", elems).finish() + } + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + JoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f), + } + } +} + +/// Creates a future which represents a collection of the outputs of the futures +/// given. +/// +/// The returned future will drive execution for all of its underlying futures, +/// collecting the results into a destination `Vec` in the same order as they +/// were provided. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +/// +/// # See Also +/// +/// `join_all` will switch to the more powerful [`FuturesOrdered`] for performance +/// reasons if the number of futures is large. You may want to look into using it or +/// its counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly. +/// +/// Some examples for additional functionality provided by these are: +/// +/// * Adding new futures to the set even after it has been started. +/// +/// * Only polling the specific futures that have been woken. In cases where +/// you have a lot of futures this will result in much more efficient polling. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future::join_all; +/// +/// async fn foo(i: u32) -> u32 { i } +/// +/// let futures = vec![foo(1), foo(2), foo(3)]; +/// +/// assert_eq!(join_all(futures).await, [1, 2, 3]); +/// # }); +/// ``` +pub fn join_all(iter: I) -> JoinAll +where + I: IntoIterator, + I::Item: Future, +{ + let iter = iter.into_iter(); + + #[cfg(target_os = "none")] + #[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))] + { + let kind = + JoinAllKind::Small { elems: iter.map(MaybeDone::Future).collect::>().into() }; + + assert_future::::Output>, _>(JoinAll { kind }) + } + + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + { + let kind = match iter.size_hint().1 { + Some(max) if max <= SMALL => JoinAllKind::Small { + elems: iter.map(MaybeDone::Future).collect::>().into(), + }, + _ => JoinAllKind::Big { fut: iter.collect::>().collect() }, + }; + + assert_future::::Output>, _>(JoinAll { kind }) + } +} + +impl Future for JoinAll +where + F: Future, +{ + type Output = Vec; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match &mut self.kind { + JoinAllKind::Small { elems } => { + let mut all_done = true; + + for elem in iter_pin_mut(elems.as_mut()) { + if elem.poll(cx).is_pending() { + all_done = false; + } + } + + if all_done { + let mut elems = mem::replace(elems, Box::pin([])); + let result = + iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect(); + Poll::Ready(result) + } else { + Poll::Pending + } + } + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + JoinAllKind::Big { fut } => Pin::new(fut).poll(cx), + } + } +} + +impl FromIterator for JoinAll { + fn from_iter>(iter: T) -> Self { + join_all(iter) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/lazy.rs b/utshell-0.5.0/vendor/futures-util/src/future/lazy.rs new file mode 100644 index 00000000..e9a8cf2f --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/lazy.rs @@ -0,0 +1,60 @@ +use super::assert_future; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`lazy`] function. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Lazy { + f: Option, +} + +// safe because we never generate `Pin<&mut F>` +impl Unpin for Lazy {} + +/// Creates a new future that allows delayed execution of a closure. +/// +/// The provided closure is only run once the future is polled. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::lazy(|_| 1); +/// assert_eq!(a.await, 1); +/// +/// let b = future::lazy(|_| -> i32 { +/// panic!("oh no!") +/// }); +/// drop(b); // closure is never run +/// # }); +/// ``` +pub fn lazy(f: F) -> Lazy +where + F: FnOnce(&mut Context<'_>) -> R, +{ + assert_future::(Lazy { f: Some(f) }) +} + +impl FusedFuture for Lazy +where + F: FnOnce(&mut Context<'_>) -> R, +{ + fn is_terminated(&self) -> bool { + self.f.is_none() + } +} + +impl Future for Lazy +where + F: FnOnce(&mut Context<'_>) -> R, +{ + type Output = R; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready((self.f.take().expect("Lazy polled after completion"))(cx)) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/maybe_done.rs b/utshell-0.5.0/vendor/futures-util/src/future/maybe_done.rs new file mode 100644 index 00000000..26e6c275 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/maybe_done.rs @@ -0,0 +1,104 @@ +//! Definition of the MaybeDone combinator + +use super::assert_future; +use core::mem; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::task::{Context, Poll}; + +/// A future that may have completed. +/// +/// This is created by the [`maybe_done()`] function. +#[derive(Debug)] +pub enum MaybeDone { + /// A not-yet-completed future + Future(/* #[pin] */ Fut), + /// The output of the completed future + Done(Fut::Output), + /// The empty variant after the result of a [`MaybeDone`] has been + /// taken using the [`take_output`](MaybeDone::take_output) method. + Gone, +} + +impl Unpin for MaybeDone {} + +/// Wraps a future into a `MaybeDone` +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// use futures::pin_mut; +/// +/// let future = future::maybe_done(async { 5 }); +/// pin_mut!(future); +/// assert_eq!(future.as_mut().take_output(), None); +/// let () = future.as_mut().await; +/// assert_eq!(future.as_mut().take_output(), Some(5)); +/// assert_eq!(future.as_mut().take_output(), None); +/// # }); +/// ``` +pub fn maybe_done(future: Fut) -> MaybeDone { + assert_future::<(), _>(MaybeDone::Future(future)) +} + +impl MaybeDone { + /// Returns an [`Option`] containing a mutable reference to the output of the future. + /// The output of this method will be [`Some`] if and only if the inner + /// future has been completed and [`take_output`](MaybeDone::take_output) + /// has not yet been called. + #[inline] + pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Output> { + unsafe { + match self.get_unchecked_mut() { + MaybeDone::Done(res) => Some(res), + _ => None, + } + } + } + + /// Attempt to take the output of a `MaybeDone` without driving it + /// towards completion. + #[inline] + pub fn take_output(self: Pin<&mut Self>) -> Option { + match &*self { + Self::Done(_) => {} + Self::Future(_) | Self::Gone => return None, + } + unsafe { + match mem::replace(self.get_unchecked_mut(), Self::Gone) { + MaybeDone::Done(output) => Some(output), + _ => unreachable!(), + } + } + } +} + +impl FusedFuture for MaybeDone { + fn is_terminated(&self) -> bool { + match self { + Self::Future(_) => false, + Self::Done(_) | Self::Gone => true, + } + } +} + +impl Future for MaybeDone { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + unsafe { + match self.as_mut().get_unchecked_mut() { + MaybeDone::Future(f) => { + let res = ready!(Pin::new_unchecked(f).poll(cx)); + self.set(Self::Done(res)); + } + MaybeDone::Done(_) => {} + MaybeDone::Gone => panic!("MaybeDone polled after value taken"), + } + } + Poll::Ready(()) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/mod.rs b/utshell-0.5.0/vendor/futures-util/src/future/mod.rs new file mode 100644 index 00000000..2d8fa4f6 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/mod.rs @@ -0,0 +1,131 @@ +//! Asynchronous values. +//! +//! This module contains: +//! +//! - The [`Future`] trait. +//! - The [`FutureExt`] and [`TryFutureExt`] trait, which provides adapters for +//! chaining and composing futures. +//! - Top-level future combinators like [`lazy`](lazy()) which creates a future +//! from a closure that defines its return value, and [`ready`](ready()), +//! which constructs a future with an immediate defined value. + +#[doc(no_inline)] +pub use core::future::Future; + +#[cfg(feature = "alloc")] +pub use futures_core::future::{BoxFuture, LocalBoxFuture}; +pub use futures_core::future::{FusedFuture, TryFuture}; +pub use futures_task::{FutureObj, LocalFutureObj, UnsafeFutureObj}; + +// Extension traits and combinators +#[allow(clippy::module_inception)] +mod future; +pub use self::future::{ + Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, MapInto, NeverError, Then, UnitError, +}; + +#[deprecated(note = "This is now an alias for [Flatten](Flatten)")] +pub use self::future::FlattenStream; + +#[cfg(feature = "std")] +pub use self::future::CatchUnwind; + +#[cfg(feature = "channel")] +#[cfg_attr(docsrs, doc(cfg(feature = "channel")))] +#[cfg(feature = "std")] +pub use self::future::{Remote, RemoteHandle}; + +#[cfg(feature = "std")] +pub use self::future::{Shared, WeakShared}; + +mod try_future; +pub use self::try_future::{ + AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto, + OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse, +}; + +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub use self::try_future::FlattenSink; + +// Primitive futures + +mod lazy; +pub use self::lazy::{lazy, Lazy}; + +mod pending; +pub use self::pending::{pending, Pending}; + +mod maybe_done; +pub use self::maybe_done::{maybe_done, MaybeDone}; + +mod try_maybe_done; +pub use self::try_maybe_done::{try_maybe_done, TryMaybeDone}; + +mod option; +pub use self::option::OptionFuture; + +mod poll_fn; +pub use self::poll_fn::{poll_fn, PollFn}; + +mod poll_immediate; +pub use self::poll_immediate::{poll_immediate, PollImmediate}; + +mod ready; +pub use self::ready::{err, ok, ready, Ready}; + +mod join; +pub use self::join::{join, join3, join4, join5, Join, Join3, Join4, Join5}; + +#[cfg(feature = "alloc")] +mod join_all; +#[cfg(feature = "alloc")] +pub use self::join_all::{join_all, JoinAll}; + +mod select; +pub use self::select::{select, Select}; + +#[cfg(feature = "alloc")] +mod select_all; +#[cfg(feature = "alloc")] +pub use self::select_all::{select_all, SelectAll}; + +mod try_join; +pub use self::try_join::{ + try_join, try_join3, try_join4, try_join5, TryJoin, TryJoin3, TryJoin4, TryJoin5, +}; + +#[cfg(feature = "alloc")] +mod try_join_all; +#[cfg(feature = "alloc")] +pub use self::try_join_all::{try_join_all, TryJoinAll}; + +mod try_select; +pub use self::try_select::{try_select, TrySelect}; + +#[cfg(feature = "alloc")] +mod select_ok; +#[cfg(feature = "alloc")] +pub use self::select_ok::{select_ok, SelectOk}; + +mod either; +pub use self::either::Either; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod abortable; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted}; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use abortable::abortable; + +// Just a helper function to ensure the futures we're returning all have the +// right implementations. +pub(crate) fn assert_future(future: F) -> F +where + F: Future, +{ + future +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/option.rs b/utshell-0.5.0/vendor/futures-util/src/future/option.rs new file mode 100644 index 00000000..0bc37775 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/option.rs @@ -0,0 +1,64 @@ +//! Definition of the `Option` (optional step) combinator + +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// A future representing a value which may or may not be present. + /// + /// Created by the [`From`] implementation for [`Option`](std::option::Option). + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::OptionFuture; + /// + /// let mut a: OptionFuture<_> = Some(async { 123 }).into(); + /// assert_eq!(a.await, Some(123)); + /// + /// a = None.into(); + /// assert_eq!(a.await, None); + /// # }); + /// ``` + #[derive(Debug, Clone)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct OptionFuture { + #[pin] + inner: Option, + } +} + +impl Default for OptionFuture { + fn default() -> Self { + Self { inner: None } + } +} + +impl Future for OptionFuture { + type Output = Option; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.project().inner.as_pin_mut() { + Some(x) => x.poll(cx).map(Some), + None => Poll::Ready(None), + } + } +} + +impl FusedFuture for OptionFuture { + fn is_terminated(&self) -> bool { + match &self.inner { + Some(x) => x.is_terminated(), + None => true, + } + } +} + +impl From> for OptionFuture { + fn from(option: Option) -> Self { + Self { inner: option } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/pending.rs b/utshell-0.5.0/vendor/futures-util/src/future/pending.rs new file mode 100644 index 00000000..b8e28686 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/pending.rs @@ -0,0 +1,55 @@ +use super::assert_future; +use core::marker; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`pending()`] function. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Pending { + _data: marker::PhantomData, +} + +impl FusedFuture for Pending { + fn is_terminated(&self) -> bool { + true + } +} + +/// Creates a future which never resolves, representing a computation that never +/// finishes. +/// +/// The returned future will forever return [`Poll::Pending`]. +/// +/// # Examples +/// +/// ```ignore +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let future = future::pending(); +/// let () = future.await; +/// unreachable!(); +/// # }); +/// ``` +#[cfg_attr(docsrs, doc(alias = "never"))] +pub fn pending() -> Pending { + assert_future::(Pending { _data: marker::PhantomData }) +} + +impl Future for Pending { + type Output = T; + + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + Poll::Pending + } +} + +impl Unpin for Pending {} + +impl Clone for Pending { + fn clone(&self) -> Self { + pending() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/poll_fn.rs b/utshell-0.5.0/vendor/futures-util/src/future/poll_fn.rs new file mode 100644 index 00000000..19311570 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/poll_fn.rs @@ -0,0 +1,58 @@ +//! Definition of the `PollFn` adapter combinator + +use super::assert_future; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; + +/// Future for the [`poll_fn`] function. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct PollFn { + f: F, +} + +impl Unpin for PollFn {} + +/// Creates a new future wrapping around a function returning [`Poll`]. +/// +/// Polling the returned future delegates to the wrapped function. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future::poll_fn; +/// use futures::task::{Context, Poll}; +/// +/// fn read_line(_cx: &mut Context<'_>) -> Poll { +/// Poll::Ready("Hello, World!".into()) +/// } +/// +/// let read_future = poll_fn(read_line); +/// assert_eq!(read_future.await, "Hello, World!".to_owned()); +/// # }); +/// ``` +pub fn poll_fn(f: F) -> PollFn +where + F: FnMut(&mut Context<'_>) -> Poll, +{ + assert_future::(PollFn { f }) +} + +impl fmt::Debug for PollFn { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PollFn").finish() + } +} + +impl Future for PollFn +where + F: FnMut(&mut Context<'_>) -> Poll, +{ + type Output = T; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + (&mut self.f)(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/poll_immediate.rs b/utshell-0.5.0/vendor/futures-util/src/future/poll_immediate.rs new file mode 100644 index 00000000..5ae555c7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/poll_immediate.rs @@ -0,0 +1,126 @@ +use super::assert_future; +use core::pin::Pin; +use futures_core::task::{Context, Poll}; +use futures_core::{FusedFuture, Future, Stream}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`poll_immediate`](poll_immediate()) function. + /// + /// It will never return [Poll::Pending](core::task::Poll::Pending) + #[derive(Debug, Clone)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct PollImmediate { + #[pin] + future: Option + } +} + +impl Future for PollImmediate +where + F: Future, +{ + type Output = Option; + + #[inline] + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + let inner = + this.future.as_mut().as_pin_mut().expect("PollImmediate polled after completion"); + match inner.poll(cx) { + Poll::Ready(t) => { + this.future.set(None); + Poll::Ready(Some(t)) + } + Poll::Pending => Poll::Ready(None), + } + } +} + +impl FusedFuture for PollImmediate { + fn is_terminated(&self) -> bool { + self.future.is_none() + } +} + +/// A [Stream](crate::stream::Stream) implementation that can be polled repeatedly until the future is done. +/// The stream will never return [Poll::Pending](core::task::Poll::Pending) +/// so polling it in a tight loop is worse than using a blocking synchronous function. +/// ``` +/// # futures::executor::block_on(async { +/// use futures::task::Poll; +/// use futures::{StreamExt, future, pin_mut}; +/// use future::FusedFuture; +/// +/// let f = async { 1_u32 }; +/// pin_mut!(f); +/// let mut r = future::poll_immediate(f); +/// assert_eq!(r.next().await, Some(Poll::Ready(1))); +/// +/// let f = async {futures::pending!(); 42_u8}; +/// pin_mut!(f); +/// let mut p = future::poll_immediate(f); +/// assert_eq!(p.next().await, Some(Poll::Pending)); +/// assert!(!p.is_terminated()); +/// assert_eq!(p.next().await, Some(Poll::Ready(42))); +/// assert!(p.is_terminated()); +/// assert_eq!(p.next().await, None); +/// # }); +/// ``` +impl Stream for PollImmediate +where + F: Future, +{ + type Item = Poll; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + match this.future.as_mut().as_pin_mut() { + // inner is gone, so we can signal that the stream is closed. + None => Poll::Ready(None), + Some(fut) => Poll::Ready(Some(fut.poll(cx).map(|t| { + this.future.set(None); + t + }))), + } + } +} + +/// Creates a future that is immediately ready with an Option of a value. +/// Specifically this means that [poll](core::future::Future::poll()) always returns [Poll::Ready](core::task::Poll::Ready). +/// +/// # Caution +/// +/// When consuming the future by this function, note the following: +/// +/// - This function does not guarantee that the future will run to completion, so it is generally incompatible with passing the non-cancellation-safe future by value. +/// - Even if the future is cancellation-safe, creating and dropping new futures frequently may lead to performance problems. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let r = future::poll_immediate(async { 1_u32 }); +/// assert_eq!(r.await, Some(1)); +/// +/// let p = future::poll_immediate(future::pending::()); +/// assert_eq!(p.await, None); +/// # }); +/// ``` +/// +/// ### Reusing a future +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::{future, pin_mut}; +/// let f = async {futures::pending!(); 42_u8}; +/// pin_mut!(f); +/// assert_eq!(None, future::poll_immediate(&mut f).await); +/// assert_eq!(42, f.await); +/// # }); +/// ``` +pub fn poll_immediate(f: F) -> PollImmediate { + assert_future::, PollImmediate>(PollImmediate { future: Some(f) }) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/ready.rs b/utshell-0.5.0/vendor/futures-util/src/future/ready.rs new file mode 100644 index 00000000..e3d791b3 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/ready.rs @@ -0,0 +1,82 @@ +use super::assert_future; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`ready`](ready()) function. +#[derive(Debug, Clone)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Ready(Option); + +impl Ready { + /// Unwraps the value from this immediately ready future. + #[inline] + pub fn into_inner(mut self) -> T { + self.0.take().unwrap() + } +} + +impl Unpin for Ready {} + +impl FusedFuture for Ready { + fn is_terminated(&self) -> bool { + self.0.is_none() + } +} + +impl Future for Ready { + type Output = T; + + #[inline] + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + Poll::Ready(self.0.take().expect("Ready polled after completion")) + } +} + +/// Creates a future that is immediately ready with a value. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ready(1); +/// assert_eq!(a.await, 1); +/// # }); +/// ``` +pub fn ready(t: T) -> Ready { + assert_future::(Ready(Some(t))) +} + +/// Create a future that is immediately ready with a success value. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ok::(1); +/// assert_eq!(a.await, Ok(1)); +/// # }); +/// ``` +pub fn ok(t: T) -> Ready> { + Ready(Some(Ok(t))) +} + +/// Create a future that is immediately ready with an error value. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::err::(1); +/// assert_eq!(a.await, Err(1)); +/// # }); +/// ``` +pub fn err(err: E) -> Ready> { + Ready(Some(Err(err))) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/select.rs b/utshell-0.5.0/vendor/futures-util/src/future/select.rs new file mode 100644 index 00000000..7e33d195 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/select.rs @@ -0,0 +1,134 @@ +use super::assert_future; +use crate::future::{Either, FutureExt}; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`select()`] function. +#[must_use = "futures do nothing unless you `.await` or poll them"] +#[derive(Debug)] +pub struct Select { + inner: Option<(A, B)>, +} + +impl Unpin for Select {} + +/// Waits for either one of two differently-typed futures to complete. +/// +/// This function will return a new future which awaits for either one of both +/// futures to complete. The returned future will finish with both the value +/// resolved and a future representing the completion of the other work. +/// +/// Note that this function consumes the receiving futures and returns a +/// wrapped version of them. +/// +/// Also note that if both this and the second future have the same +/// output type you can use the `Either::factor_first` method to +/// conveniently extract out the value at the end. +/// +/// # Examples +/// +/// A simple example +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::{ +/// pin_mut, +/// future::Either, +/// future::self, +/// }; +/// +/// // These two futures have different types even though their outputs have the same type. +/// let future1 = async { +/// future::pending::<()>().await; // will never finish +/// 1 +/// }; +/// let future2 = async { +/// future::ready(2).await +/// }; +/// +/// // 'select' requires Future + Unpin bounds +/// pin_mut!(future1); +/// pin_mut!(future2); +/// +/// let value = match future::select(future1, future2).await { +/// Either::Left((value1, _)) => value1, // `value1` is resolved from `future1` +/// // `_` represents `future2` +/// Either::Right((value2, _)) => value2, // `value2` is resolved from `future2` +/// // `_` represents `future1` +/// }; +/// +/// assert!(value == 2); +/// # }); +/// ``` +/// +/// A more complex example +/// +/// ``` +/// use futures::future::{self, Either, Future, FutureExt}; +/// +/// // A poor-man's join implemented on top of select +/// +/// fn join(a: A, b: B) -> impl Future +/// where A: Future + Unpin, +/// B: Future + Unpin, +/// { +/// future::select(a, b).then(|either| { +/// match either { +/// Either::Left((x, b)) => b.map(move |y| (x, y)).left_future(), +/// Either::Right((y, a)) => a.map(move |x| (x, y)).right_future(), +/// } +/// }) +/// } +/// ``` +pub fn select(future1: A, future2: B) -> Select +where + A: Future + Unpin, + B: Future + Unpin, +{ + assert_future::, _>(Select { + inner: Some((future1, future2)), + }) +} + +impl Future for Select +where + A: Future + Unpin, + B: Future + Unpin, +{ + type Output = Either<(A::Output, B), (B::Output, A)>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + /// When compiled with `-C opt-level=z`, this function will help the compiler eliminate the `None` branch, where + /// `Option::unwrap` does not. + #[inline(always)] + fn unwrap_option(value: Option) -> T { + match value { + None => unreachable!(), + Some(value) => value, + } + } + + let (a, b) = self.inner.as_mut().expect("cannot poll Select twice"); + + if let Poll::Ready(val) = a.poll_unpin(cx) { + return Poll::Ready(Either::Left((val, unwrap_option(self.inner.take()).1))); + } + + if let Poll::Ready(val) = b.poll_unpin(cx) { + return Poll::Ready(Either::Right((val, unwrap_option(self.inner.take()).0))); + } + + Poll::Pending + } +} + +impl FusedFuture for Select +where + A: Future + Unpin, + B: Future + Unpin, +{ + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/select_all.rs b/utshell-0.5.0/vendor/futures-util/src/future/select_all.rs new file mode 100644 index 00000000..0a51d0da --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/select_all.rs @@ -0,0 +1,75 @@ +use super::assert_future; +use crate::future::FutureExt; +use alloc::vec::Vec; +use core::iter::FromIterator; +use core::mem; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; + +/// Future for the [`select_all`] function. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct SelectAll { + inner: Vec, +} + +impl Unpin for SelectAll {} + +/// Creates a new future which will select over a list of futures. +/// +/// The returned future will wait for any future within `iter` to be ready. Upon +/// completion the item resolved will be returned, along with the index of the +/// future that was ready and the list of all the remaining futures. +/// +/// There are no guarantees provided on the order of the list with the remaining +/// futures. They might be swapped around, reversed, or completely random. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +/// +/// # Panics +/// +/// This function will panic if the iterator specified contains no items. +pub fn select_all(iter: I) -> SelectAll +where + I: IntoIterator, + I::Item: Future + Unpin, +{ + let ret = SelectAll { inner: iter.into_iter().collect() }; + assert!(!ret.inner.is_empty()); + assert_future::<(::Output, usize, Vec), _>(ret) +} + +impl SelectAll { + /// Consumes this combinator, returning the underlying futures. + pub fn into_inner(self) -> Vec { + self.inner + } +} + +impl Future for SelectAll { + type Output = (Fut::Output, usize, Vec); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.poll_unpin(cx) { + Poll::Pending => None, + Poll::Ready(e) => Some((i, e)), + }); + match item { + Some((idx, res)) => { + #[allow(clippy::let_underscore_future)] + let _ = self.inner.swap_remove(idx); + let rest = mem::take(&mut self.inner); + Poll::Ready((res, idx, rest)) + } + None => Poll::Pending, + } + } +} + +impl FromIterator for SelectAll { + fn from_iter>(iter: T) -> Self { + select_all(iter) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/select_ok.rs b/utshell-0.5.0/vendor/futures-util/src/future/select_ok.rs new file mode 100644 index 00000000..5d557993 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/select_ok.rs @@ -0,0 +1,85 @@ +use super::assert_future; +use crate::future::TryFutureExt; +use alloc::vec::Vec; +use core::iter::FromIterator; +use core::mem; +use core::pin::Pin; +use futures_core::future::{Future, TryFuture}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`select_ok`] function. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct SelectOk { + inner: Vec, +} + +impl Unpin for SelectOk {} + +/// Creates a new future which will select the first successful future over a list of futures. +/// +/// The returned future will wait for any future within `iter` to be ready and Ok. Unlike +/// `select_all`, this will only return the first successful completion, or the last +/// failure. This is useful in contexts where any success is desired and failures +/// are ignored, unless all the futures fail. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +/// +/// # Panics +/// +/// This function will panic if the iterator specified contains no items. +pub fn select_ok(iter: I) -> SelectOk +where + I: IntoIterator, + I::Item: TryFuture + Unpin, +{ + let ret = SelectOk { inner: iter.into_iter().collect() }; + assert!(!ret.inner.is_empty(), "iterator provided to select_ok was empty"); + assert_future::< + Result<(::Ok, Vec), ::Error>, + _, + >(ret) +} + +impl Future for SelectOk { + type Output = Result<(Fut::Ok, Vec), Fut::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // loop until we've either exhausted all errors, a success was hit, or nothing is ready + loop { + let item = + self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) { + Poll::Pending => None, + Poll::Ready(e) => Some((i, e)), + }); + match item { + Some((idx, res)) => { + // always remove Ok or Err, if it's not the last Err continue looping + drop(self.inner.remove(idx)); + match res { + Ok(e) => { + let rest = mem::take(&mut self.inner); + return Poll::Ready(Ok((e, rest))); + } + Err(e) => { + if self.inner.is_empty() { + return Poll::Ready(Err(e)); + } + } + } + } + None => { + // based on the filter above, nothing is ready, return + return Poll::Pending; + } + } + } + } +} + +impl FromIterator for SelectOk { + fn from_iter>(iter: T) -> Self { + select_ok(iter) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_future/into_future.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_future/into_future.rs new file mode 100644 index 00000000..9f093d0e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_future/into_future.rs @@ -0,0 +1,36 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future, TryFuture}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`into_future`](super::TryFutureExt::into_future) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct IntoFuture { + #[pin] + future: Fut, + } +} + +impl IntoFuture { + #[inline] + pub(crate) fn new(future: Fut) -> Self { + Self { future } + } +} + +impl FusedFuture for IntoFuture { + fn is_terminated(&self) -> bool { + self.future.is_terminated() + } +} + +impl Future for IntoFuture { + type Output = Result; + + #[inline] + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.project().future.try_poll(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_future/mod.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_future/mod.rs new file mode 100644 index 00000000..e5bc7007 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_future/mod.rs @@ -0,0 +1,625 @@ +//! Futures +//! +//! This module contains a number of functions for working with `Future`s, +//! including the `FutureExt` trait which adds methods to `Future` types. + +#[cfg(feature = "compat")] +use crate::compat::Compat; +use core::pin::Pin; +use futures_core::{ + future::TryFuture, + stream::TryStream, + task::{Context, Poll}, +}; +#[cfg(feature = "sink")] +use futures_sink::Sink; + +use crate::fns::{ + inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, map_ok_or_else_fn, + unwrap_or_else_fn, InspectErrFn, InspectOkFn, IntoFn, MapErrFn, MapOkFn, MapOkOrElseFn, + UnwrapOrElseFn, +}; +use crate::future::{assert_future, Inspect, Map}; +use crate::stream::assert_stream; + +// Combinators +mod into_future; +mod try_flatten; +mod try_flatten_err; + +delegate_all!( + /// Future for the [`try_flatten`](TryFutureExt::try_flatten) method. + TryFlatten( + try_flatten::TryFlatten + ): Debug + Future + FusedFuture + New[|x: Fut1| try_flatten::TryFlatten::new(x)] +); + +delegate_all!( + /// Future for the [`try_flatten_err`](TryFutureExt::try_flatten_err) method. + TryFlattenErr( + try_flatten_err::TryFlattenErr + ): Debug + Future + FusedFuture + New[|x: Fut1| try_flatten_err::TryFlattenErr::new(x)] +); + +delegate_all!( + /// Future for the [`try_flatten_stream`](TryFutureExt::try_flatten_stream) method. + TryFlattenStream( + try_flatten::TryFlatten + ): Debug + Sink + Stream + FusedStream + New[|x: Fut| try_flatten::TryFlatten::new(x)] + where Fut: TryFuture +); + +#[cfg(feature = "sink")] +delegate_all!( + /// Sink for the [`flatten_sink`](TryFutureExt::flatten_sink) method. + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + FlattenSink( + try_flatten::TryFlatten + ): Debug + Sink + Stream + FusedStream + New[|x: Fut| try_flatten::TryFlatten::new(x)] +); + +delegate_all!( + /// Future for the [`and_then`](TryFutureExt::and_then) method. + AndThen( + TryFlatten, Fut2> + ): Debug + Future + FusedFuture + New[|x: Fut1, f: F| TryFlatten::new(MapOk::new(x, f))] +); + +delegate_all!( + /// Future for the [`or_else`](TryFutureExt::or_else) method. + OrElse( + TryFlattenErr, Fut2> + ): Debug + Future + FusedFuture + New[|x: Fut1, f: F| TryFlattenErr::new(MapErr::new(x, f))] +); + +delegate_all!( + /// Future for the [`err_into`](TryFutureExt::err_into) method. + ErrInto( + MapErr> + ): Debug + Future + FusedFuture + New[|x: Fut| MapErr::new(x, into_fn())] +); + +delegate_all!( + /// Future for the [`ok_into`](TryFutureExt::ok_into) method. + OkInto( + MapOk> + ): Debug + Future + FusedFuture + New[|x: Fut| MapOk::new(x, into_fn())] +); + +delegate_all!( + /// Future for the [`inspect_ok`](super::TryFutureExt::inspect_ok) method. + InspectOk( + Inspect, InspectOkFn> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_ok_fn(f))] +); + +delegate_all!( + /// Future for the [`inspect_err`](super::TryFutureExt::inspect_err) method. + InspectErr( + Inspect, InspectErrFn> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_err_fn(f))] +); + +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::into_future::IntoFuture; + +delegate_all!( + /// Future for the [`map_ok`](TryFutureExt::map_ok) method. + MapOk( + Map, MapOkFn> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_ok_fn(f))] +); + +delegate_all!( + /// Future for the [`map_err`](TryFutureExt::map_err) method. + MapErr( + Map, MapErrFn> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_err_fn(f))] +); + +delegate_all!( + /// Future for the [`map_ok_or_else`](TryFutureExt::map_ok_or_else) method. + MapOkOrElse( + Map, MapOkOrElseFn> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(IntoFuture::new(x), map_ok_or_else_fn(f, g))] +); + +delegate_all!( + /// Future for the [`unwrap_or_else`](TryFutureExt::unwrap_or_else) method. + UnwrapOrElse( + Map, UnwrapOrElseFn> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), unwrap_or_else_fn(f))] +); + +impl TryFutureExt for Fut {} + +/// Adapters specific to [`Result`]-returning futures +pub trait TryFutureExt: TryFuture { + /// Flattens the execution of this future when the successful result of this + /// future is a [`Sink`]. + /// + /// This can be useful when sink initialization is deferred, and it is + /// convenient to work with that sink as if the sink was available at the + /// call site. + /// + /// Note that this function consumes this future and returns a wrapped + /// version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::{Future, TryFutureExt}; + /// use futures::sink::Sink; + /// # use futures::channel::mpsc::{self, SendError}; + /// # type T = i32; + /// # type E = SendError; + /// + /// fn make_sink_async() -> impl Future, + /// E, + /// >> { // ... } + /// # let (tx, _rx) = mpsc::unbounded::(); + /// # futures::future::ready(Ok(tx)) + /// # } + /// fn take_sink(sink: impl Sink) { /* ... */ } + /// + /// let fut = make_sink_async(); + /// take_sink(fut.flatten_sink()) + /// ``` + #[cfg(feature = "sink")] + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + fn flatten_sink(self) -> FlattenSink + where + Self::Ok: Sink, + Self: Sized, + { + crate::sink::assert_sink::(FlattenSink::new(self)) + } + + /// Maps this future's success value to a different value. + /// + /// This method can be used to change the [`Ok`](TryFuture::Ok) type of the + /// future into a different type. It is similar to the [`Result::map`] + /// method. You can use this method to chain along a computation once the + /// future has been resolved. + /// + /// The provided closure `f` will only be called if this future is resolved + /// to an [`Ok`]. If it resolves to an [`Err`], panics, or is dropped, then + /// the provided closure will never be invoked. + /// + /// Note that this method consumes the future it is called on and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Ok::(1) }; + /// let future = future.map_ok(|x| x + 3); + /// assert_eq!(future.await, Ok(4)); + /// # }); + /// ``` + /// + /// Calling [`map_ok`](TryFutureExt::map_ok) on an errored future has no + /// effect: + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Err::(1) }; + /// let future = future.map_ok(|x| x + 3); + /// assert_eq!(future.await, Err(1)); + /// # }); + /// ``` + fn map_ok(self, f: F) -> MapOk + where + F: FnOnce(Self::Ok) -> T, + Self: Sized, + { + assert_future::, _>(MapOk::new(self, f)) + } + + /// Maps this future's success value to a different value, and permits for error handling resulting in the same type. + /// + /// This method can be used to coalesce your [`Ok`](TryFuture::Ok) type and [`Error`](TryFuture::Error) into another type, + /// where that type is the same for both outcomes. + /// + /// The provided closure `f` will only be called if this future is resolved + /// to an [`Ok`]. If it resolves to an [`Err`], panics, or is dropped, then + /// the provided closure will never be invoked. + /// + /// The provided closure `e` will only be called if this future is resolved + /// to an [`Err`]. If it resolves to an [`Ok`], panics, or is dropped, then + /// the provided closure will never be invoked. + /// + /// Note that this method consumes the future it is called on and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Ok::(5) }; + /// let future = future.map_ok_or_else(|x| x * 2, |x| x + 3); + /// assert_eq!(future.await, 8); + /// + /// let future = async { Err::(5) }; + /// let future = future.map_ok_or_else(|x| x * 2, |x| x + 3); + /// assert_eq!(future.await, 10); + /// # }); + /// ``` + /// + fn map_ok_or_else(self, e: E, f: F) -> MapOkOrElse + where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized, + { + assert_future::(MapOkOrElse::new(self, f, e)) + } + + /// Maps this future's error value to a different value. + /// + /// This method can be used to change the [`Error`](TryFuture::Error) type + /// of the future into a different type. It is similar to the + /// [`Result::map_err`] method. You can use this method for example to + /// ensure that futures have the same [`Error`](TryFuture::Error) type when + /// using [`select!`] or [`join!`]. + /// + /// The provided closure `f` will only be called if this future is resolved + /// to an [`Err`]. If it resolves to an [`Ok`], panics, or is dropped, then + /// the provided closure will never be invoked. + /// + /// Note that this method consumes the future it is called on and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Err::(1) }; + /// let future = future.map_err(|x| x + 3); + /// assert_eq!(future.await, Err(4)); + /// # }); + /// ``` + /// + /// Calling [`map_err`](TryFutureExt::map_err) on a successful future has + /// no effect: + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Ok::(1) }; + /// let future = future.map_err(|x| x + 3); + /// assert_eq!(future.await, Ok(1)); + /// # }); + /// ``` + /// + /// [`join!`]: crate::join + /// [`select!`]: crate::select + fn map_err(self, f: F) -> MapErr + where + F: FnOnce(Self::Error) -> E, + Self: Sized, + { + assert_future::, _>(MapErr::new(self, f)) + } + + /// Maps this future's [`Error`](TryFuture::Error) to a new error type + /// using the [`Into`](std::convert::Into) trait. + /// + /// This method does for futures what the `?`-operator does for + /// [`Result`]: It lets the compiler infer the type of the resulting + /// error. Just as [`map_err`](TryFutureExt::map_err), this is useful for + /// example to ensure that futures have the same [`Error`](TryFuture::Error) + /// type when using [`select!`] or [`join!`]. + /// + /// Note that this method consumes the future it is called on and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future_err_u8 = async { Err::<(), u8>(1) }; + /// let future_err_i32 = future_err_u8.err_into::(); + /// # }); + /// ``` + /// + /// [`join!`]: crate::join + /// [`select!`]: crate::select + fn err_into(self) -> ErrInto + where + Self: Sized, + Self::Error: Into, + { + assert_future::, _>(ErrInto::new(self)) + } + + /// Maps this future's [`Ok`](TryFuture::Ok) to a new type + /// using the [`Into`](std::convert::Into) trait. + fn ok_into(self) -> OkInto + where + Self: Sized, + Self::Ok: Into, + { + assert_future::, _>(OkInto::new(self)) + } + + /// Executes another future after this one resolves successfully. The + /// success value is passed to a closure to create this subsequent future. + /// + /// The provided closure `f` will only be called if this future is resolved + /// to an [`Ok`]. If this future resolves to an [`Err`], panics, or is + /// dropped, then the provided closure will never be invoked. The + /// [`Error`](TryFuture::Error) type of this future and the future + /// returned by `f` have to match. + /// + /// Note that this method consumes the future it is called on and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Ok::(1) }; + /// let future = future.and_then(|x| async move { Ok::(x + 3) }); + /// assert_eq!(future.await, Ok(4)); + /// # }); + /// ``` + /// + /// Calling [`and_then`](TryFutureExt::and_then) on an errored future has no + /// effect: + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Err::(1) }; + /// let future = future.and_then(|x| async move { Err::(x + 3) }); + /// assert_eq!(future.await, Err(1)); + /// # }); + /// ``` + fn and_then(self, f: F) -> AndThen + where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_future::, _>(AndThen::new(self, f)) + } + + /// Executes another future if this one resolves to an error. The + /// error value is passed to a closure to create this subsequent future. + /// + /// The provided closure `f` will only be called if this future is resolved + /// to an [`Err`]. If this future resolves to an [`Ok`], panics, or is + /// dropped, then the provided closure will never be invoked. The + /// [`Ok`](TryFuture::Ok) type of this future and the future returned by `f` + /// have to match. + /// + /// Note that this method consumes the future it is called on and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Err::(1) }; + /// let future = future.or_else(|x| async move { Err::(x + 3) }); + /// assert_eq!(future.await, Err(4)); + /// # }); + /// ``` + /// + /// Calling [`or_else`](TryFutureExt::or_else) on a successful future has + /// no effect: + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Ok::(1) }; + /// let future = future.or_else(|x| async move { Ok::(x + 3) }); + /// assert_eq!(future.await, Ok(1)); + /// # }); + /// ``` + fn or_else(self, f: F) -> OrElse + where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_future::, _>(OrElse::new(self, f)) + } + + /// Do something with the success value of a future before passing it on. + /// + /// When using futures, you'll often chain several of them together. While + /// working on such code, you might want to check out what's happening at + /// various parts in the pipeline, without consuming the intermediate + /// value. To do that, insert a call to `inspect_ok`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::TryFutureExt; + /// + /// let future = async { Ok::<_, ()>(1) }; + /// let new_future = future.inspect_ok(|&x| println!("about to resolve: {}", x)); + /// assert_eq!(new_future.await, Ok(1)); + /// # }); + /// ``` + fn inspect_ok(self, f: F) -> InspectOk + where + F: FnOnce(&Self::Ok), + Self: Sized, + { + assert_future::, _>(InspectOk::new(self, f)) + } + + /// Do something with the error value of a future before passing it on. + /// + /// When using futures, you'll often chain several of them together. While + /// working on such code, you might want to check out what's happening at + /// various parts in the pipeline, without consuming the intermediate + /// value. To do that, insert a call to `inspect_err`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::TryFutureExt; + /// + /// let future = async { Err::<(), _>(1) }; + /// let new_future = future.inspect_err(|&x| println!("about to error: {}", x)); + /// assert_eq!(new_future.await, Err(1)); + /// # }); + /// ``` + fn inspect_err(self, f: F) -> InspectErr + where + F: FnOnce(&Self::Error), + Self: Sized, + { + assert_future::, _>(InspectErr::new(self, f)) + } + + /// Flatten the execution of this future when the successful result of this + /// future is another future. + /// + /// This is equivalent to `future.and_then(|x| x)`. + fn try_flatten(self) -> TryFlatten + where + Self::Ok: TryFuture, + Self: Sized, + { + assert_future::::Ok, Self::Error>, _>(TryFlatten::new(self)) + } + + /// Flatten the execution of this future when the successful result of this + /// future is a stream. + /// + /// This can be useful when stream initialization is deferred, and it is + /// convenient to work with that stream as if stream was available at the + /// call site. + /// + /// Note that this function consumes this future and returns a wrapped + /// version of it. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future::TryFutureExt; + /// use futures::stream::{self, TryStreamExt}; + /// + /// let stream_items = vec![17, 18, 19].into_iter().map(Ok); + /// let future_of_a_stream = async { Ok::<_, ()>(stream::iter(stream_items)) }; + /// + /// let stream = future_of_a_stream.try_flatten_stream(); + /// let list = stream.try_collect::>().await; + /// assert_eq!(list, Ok(vec![17, 18, 19])); + /// # }); + /// ``` + fn try_flatten_stream(self) -> TryFlattenStream + where + Self::Ok: TryStream, + Self: Sized, + { + assert_stream::::Ok, Self::Error>, _>(TryFlattenStream::new( + self, + )) + } + + /// Unwraps this future's output, producing a future with this future's + /// [`Ok`](TryFuture::Ok) type as its + /// [`Output`](std::future::Future::Output) type. + /// + /// If this future is resolved successfully, the returned future will + /// contain the original future's success value as output. Otherwise, the + /// closure `f` is called with the error value to produce an alternate + /// success value. + /// + /// This method is similar to the [`Result::unwrap_or_else`] method. + /// + /// # Examples + /// + /// ``` + /// use futures::future::TryFutureExt; + /// + /// # futures::executor::block_on(async { + /// let future = async { Err::<(), &str>("Boom!") }; + /// let future = future.unwrap_or_else(|_| ()); + /// assert_eq!(future.await, ()); + /// # }); + /// ``` + fn unwrap_or_else(self, f: F) -> UnwrapOrElse + where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok, + { + assert_future::(UnwrapOrElse::new(self, f)) + } + + /// Wraps a [`TryFuture`] into a future compatible with libraries using + /// futures 0.1 future definitions. Requires the `compat` feature to enable. + #[cfg(feature = "compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] + fn compat(self) -> Compat + where + Self: Sized + Unpin, + { + Compat::new(self) + } + + /// Wraps a [`TryFuture`] into a type that implements + /// [`Future`](std::future::Future). + /// + /// [`TryFuture`]s currently do not implement the + /// [`Future`](std::future::Future) trait due to limitations of the + /// compiler. + /// + /// # Examples + /// + /// ``` + /// use futures::future::{Future, TryFuture, TryFutureExt}; + /// + /// # type T = i32; + /// # type E = (); + /// fn make_try_future() -> impl TryFuture { // ... } + /// # async { Ok::(1) } + /// # } + /// fn take_future(future: impl Future>) { /* ... */ } + /// + /// take_future(make_try_future().into_future()); + /// ``` + fn into_future(self) -> IntoFuture + where + Self: Sized, + { + assert_future::, _>(IntoFuture::new(self)) + } + + /// A convenience method for calling [`TryFuture::try_poll`] on [`Unpin`] + /// future types. + fn try_poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll> + where + Self: Unpin, + { + Pin::new(self).try_poll(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten.rs new file mode 100644 index 00000000..1ce4559a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten.rs @@ -0,0 +1,162 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future, TryFuture}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + #[project = TryFlattenProj] + #[derive(Debug)] + pub enum TryFlatten { + First { #[pin] f: Fut1 }, + Second { #[pin] f: Fut2 }, + Empty, + } +} + +impl TryFlatten { + pub(crate) fn new(future: Fut1) -> Self { + Self::First { f: future } + } +} + +impl FusedFuture for TryFlatten +where + Fut: TryFuture, + Fut::Ok: TryFuture, +{ + fn is_terminated(&self) -> bool { + match self { + Self::Empty => true, + _ => false, + } + } +} + +impl Future for TryFlatten +where + Fut: TryFuture, + Fut::Ok: TryFuture, +{ + type Output = Result<::Ok, Fut::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready(loop { + match self.as_mut().project() { + TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { + Ok(f) => self.set(Self::Second { f }), + Err(e) => { + self.set(Self::Empty); + break Err(e); + } + }, + TryFlattenProj::Second { f } => { + let output = ready!(f.try_poll(cx)); + self.set(Self::Empty); + break output; + } + TryFlattenProj::Empty => panic!("TryFlatten polled after completion"), + } + }) + } +} + +impl FusedStream for TryFlatten +where + Fut: TryFuture, + Fut::Ok: TryStream, +{ + fn is_terminated(&self) -> bool { + match self { + Self::Empty => true, + _ => false, + } + } +} + +impl Stream for TryFlatten +where + Fut: TryFuture, + Fut::Ok: TryStream, +{ + type Item = Result<::Ok, Fut::Error>; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(loop { + match self.as_mut().project() { + TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { + Ok(f) => self.set(Self::Second { f }), + Err(e) => { + self.set(Self::Empty); + break Some(Err(e)); + } + }, + TryFlattenProj::Second { f } => { + let output = ready!(f.try_poll_next(cx)); + if output.is_none() { + self.set(Self::Empty); + } + break output; + } + TryFlattenProj::Empty => break None, + } + }) + } +} + +#[cfg(feature = "sink")] +impl Sink for TryFlatten +where + Fut: TryFuture, + Fut::Ok: Sink, +{ + type Error = Fut::Error; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(loop { + match self.as_mut().project() { + TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { + Ok(f) => self.set(Self::Second { f }), + Err(e) => { + self.set(Self::Empty); + break Err(e); + } + }, + TryFlattenProj::Second { f } => { + break ready!(f.poll_ready(cx)); + } + TryFlattenProj::Empty => panic!("poll_ready called after eof"), + } + }) + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + match self.project() { + TryFlattenProj::First { .. } => panic!("poll_ready not called first"), + TryFlattenProj::Second { f } => f.start_send(item), + TryFlattenProj::Empty => panic!("start_send called after eof"), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.project() { + TryFlattenProj::First { .. } => Poll::Ready(Ok(())), + TryFlattenProj::Second { f } => f.poll_flush(cx), + TryFlattenProj::Empty => panic!("poll_flush called after eof"), + } + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let res = match self.as_mut().project() { + TryFlattenProj::Second { f } => f.poll_close(cx), + _ => Poll::Ready(Ok(())), + }; + if res.is_ready() { + self.set(Self::Empty); + } + res + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten_err.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten_err.rs new file mode 100644 index 00000000..39b7d9f5 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_future/try_flatten_err.rs @@ -0,0 +1,62 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future, TryFuture}; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + #[project = TryFlattenErrProj] + #[derive(Debug)] + pub enum TryFlattenErr { + First { #[pin] f: Fut1 }, + Second { #[pin] f: Fut2 }, + Empty, + } +} + +impl TryFlattenErr { + pub(crate) fn new(future: Fut1) -> Self { + Self::First { f: future } + } +} + +impl FusedFuture for TryFlattenErr +where + Fut: TryFuture, + Fut::Error: TryFuture, +{ + fn is_terminated(&self) -> bool { + match self { + Self::Empty => true, + _ => false, + } + } +} + +impl Future for TryFlattenErr +where + Fut: TryFuture, + Fut::Error: TryFuture, +{ + type Output = Result::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Poll::Ready(loop { + match self.as_mut().project() { + TryFlattenErrProj::First { f } => match ready!(f.try_poll(cx)) { + Err(f) => self.set(Self::Second { f }), + Ok(e) => { + self.set(Self::Empty); + break Ok(e); + } + }, + TryFlattenErrProj::Second { f } => { + let output = ready!(f.try_poll(cx)); + self.set(Self::Empty); + break output; + } + TryFlattenErrProj::Empty => panic!("TryFlattenErr polled after completion"), + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_join.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_join.rs new file mode 100644 index 00000000..6af1f0cc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_join.rs @@ -0,0 +1,256 @@ +#![allow(non_snake_case)] + +use crate::future::{assert_future, try_maybe_done, TryMaybeDone}; +use core::fmt; +use core::pin::Pin; +use futures_core::future::{Future, TryFuture}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +macro_rules! generate { + ($( + $(#[$doc:meta])* + ($Join:ident, ), + )*) => ($( + pin_project! { + $(#[$doc])* + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct $Join { + #[pin] Fut1: TryMaybeDone, + $(#[pin] $Fut: TryMaybeDone<$Fut>,)* + } + } + + impl fmt::Debug for $Join + where + Fut1: TryFuture + fmt::Debug, + Fut1::Ok: fmt::Debug, + Fut1::Error: fmt::Debug, + $( + $Fut: TryFuture + fmt::Debug, + $Fut::Ok: fmt::Debug, + $Fut::Error: fmt::Debug, + )* + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct(stringify!($Join)) + .field("Fut1", &self.Fut1) + $(.field(stringify!($Fut), &self.$Fut))* + .finish() + } + } + + impl $Join + where + Fut1: TryFuture, + $( + $Fut: TryFuture + ),* + { + fn new(Fut1: Fut1, $($Fut: $Fut),*) -> Self { + Self { + Fut1: try_maybe_done(Fut1), + $($Fut: try_maybe_done($Fut)),* + } + } + } + + impl Future for $Join + where + Fut1: TryFuture, + $( + $Fut: TryFuture + ),* + { + type Output = Result<(Fut1::Ok, $($Fut::Ok),*), Fut1::Error>; + + fn poll( + self: Pin<&mut Self>, cx: &mut Context<'_> + ) -> Poll { + let mut all_done = true; + let mut futures = self.project(); + all_done &= futures.Fut1.as_mut().poll(cx)?.is_ready(); + $( + all_done &= futures.$Fut.as_mut().poll(cx)?.is_ready(); + )* + + if all_done { + Poll::Ready(Ok(( + futures.Fut1.take_output().unwrap(), + $( + futures.$Fut.take_output().unwrap() + ),* + ))) + } else { + Poll::Pending + } + } + } + )*) +} + +generate! { + /// Future for the [`try_join`](try_join()) function. + (TryJoin, ), + + /// Future for the [`try_join3`] function. + (TryJoin3, ), + + /// Future for the [`try_join4`] function. + (TryJoin4, ), + + /// Future for the [`try_join5`] function. + (TryJoin5, ), +} + +/// Joins the result of two futures, waiting for them both to complete or +/// for one to produce an error. +/// +/// This function will return a new future which awaits both futures to +/// complete. If successful, the returned future will finish with a tuple of +/// both results. If unsuccessful, it will complete with the first error +/// encountered. +/// +/// Note that this function consumes the passed futures and returns a +/// wrapped version of it. +/// +/// # Examples +/// +/// When used on multiple futures that return [`Ok`], `try_join` will return +/// [`Ok`] of a tuple of the values: +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ready(Ok::(1)); +/// let b = future::ready(Ok::(2)); +/// let pair = future::try_join(a, b); +/// +/// assert_eq!(pair.await, Ok((1, 2))); +/// # }); +/// ``` +/// +/// If one of the futures resolves to an error, `try_join` will return +/// that error: +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ready(Ok::(1)); +/// let b = future::ready(Err::(2)); +/// let pair = future::try_join(a, b); +/// +/// assert_eq!(pair.await, Err(2)); +/// # }); +/// ``` +pub fn try_join(future1: Fut1, future2: Fut2) -> TryJoin +where + Fut1: TryFuture, + Fut2: TryFuture, +{ + assert_future::, _>(TryJoin::new(future1, future2)) +} + +/// Same as [`try_join`](try_join()), but with more futures. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ready(Ok::(1)); +/// let b = future::ready(Ok::(2)); +/// let c = future::ready(Ok::(3)); +/// let tuple = future::try_join3(a, b, c); +/// +/// assert_eq!(tuple.await, Ok((1, 2, 3))); +/// # }); +/// ``` +pub fn try_join3( + future1: Fut1, + future2: Fut2, + future3: Fut3, +) -> TryJoin3 +where + Fut1: TryFuture, + Fut2: TryFuture, + Fut3: TryFuture, +{ + assert_future::, _>(TryJoin3::new( + future1, future2, future3, + )) +} + +/// Same as [`try_join`](try_join()), but with more futures. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ready(Ok::(1)); +/// let b = future::ready(Ok::(2)); +/// let c = future::ready(Ok::(3)); +/// let d = future::ready(Ok::(4)); +/// let tuple = future::try_join4(a, b, c, d); +/// +/// assert_eq!(tuple.await, Ok((1, 2, 3, 4))); +/// # }); +/// ``` +pub fn try_join4( + future1: Fut1, + future2: Fut2, + future3: Fut3, + future4: Fut4, +) -> TryJoin4 +where + Fut1: TryFuture, + Fut2: TryFuture, + Fut3: TryFuture, + Fut4: TryFuture, +{ + assert_future::, _>( + TryJoin4::new(future1, future2, future3, future4), + ) +} + +/// Same as [`try_join`](try_join()), but with more futures. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future; +/// +/// let a = future::ready(Ok::(1)); +/// let b = future::ready(Ok::(2)); +/// let c = future::ready(Ok::(3)); +/// let d = future::ready(Ok::(4)); +/// let e = future::ready(Ok::(5)); +/// let tuple = future::try_join5(a, b, c, d, e); +/// +/// assert_eq!(tuple.await, Ok((1, 2, 3, 4, 5))); +/// # }); +/// ``` +pub fn try_join5( + future1: Fut1, + future2: Fut2, + future3: Fut3, + future4: Fut4, + future5: Fut5, +) -> TryJoin5 +where + Fut1: TryFuture, + Fut2: TryFuture, + Fut3: TryFuture, + Fut4: TryFuture, + Fut5: TryFuture, +{ + assert_future::, _>( + TryJoin5::new(future1, future2, future3, future4, future5), + ) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_join_all.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_join_all.rs new file mode 100644 index 00000000..2d6a2a02 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_join_all.rs @@ -0,0 +1,201 @@ +//! Definition of the `TryJoinAll` combinator, waiting for all of a list of +//! futures to finish with either success or error. + +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::fmt; +use core::future::Future; +use core::iter::FromIterator; +use core::mem; +use core::pin::Pin; +use core::task::{Context, Poll}; + +use super::{assert_future, join_all, IntoFuture, TryFuture, TryMaybeDone}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +use crate::stream::{FuturesOrdered, TryCollect, TryStreamExt}; +use crate::TryFutureExt; + +enum FinalState { + Pending, + AllDone, + Error(E), +} + +/// Future for the [`try_join_all`] function. +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct TryJoinAll +where + F: TryFuture, +{ + kind: TryJoinAllKind, +} + +enum TryJoinAllKind +where + F: TryFuture, +{ + Small { + elems: Pin>]>>, + }, + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + Big { + fut: TryCollect>, Vec>, + }, +} + +impl fmt::Debug for TryJoinAll +where + F: TryFuture + fmt::Debug, + F::Ok: fmt::Debug, + F::Error: fmt::Debug, + F::Output: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.kind { + TryJoinAllKind::Small { ref elems } => { + f.debug_struct("TryJoinAll").field("elems", elems).finish() + } + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + TryJoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f), + } + } +} + +/// Creates a future which represents either a collection of the results of the +/// futures given or an error. +/// +/// The returned future will drive execution for all of its underlying futures, +/// collecting the results into a destination `Vec` in the same order as they +/// were provided. +/// +/// If any future returns an error then all other futures will be canceled and +/// an error will be returned immediately. If all futures complete successfully, +/// however, then the returned future will succeed with a `Vec` of all the +/// successful results. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +/// +/// # See Also +/// +/// `try_join_all` will switch to the more powerful [`FuturesOrdered`] for performance +/// reasons if the number of futures is large. You may want to look into using it or +/// it's counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly. +/// +/// Some examples for additional functionality provided by these are: +/// +/// * Adding new futures to the set even after it has been started. +/// +/// * Only polling the specific futures that have been woken. In cases where +/// you have a lot of futures this will result in much more efficient polling. +/// +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::future::{self, try_join_all}; +/// +/// let futures = vec![ +/// future::ok::(1), +/// future::ok::(2), +/// future::ok::(3), +/// ]; +/// +/// assert_eq!(try_join_all(futures).await, Ok(vec![1, 2, 3])); +/// +/// let futures = vec![ +/// future::ok::(1), +/// future::err::(2), +/// future::ok::(3), +/// ]; +/// +/// assert_eq!(try_join_all(futures).await, Err(2)); +/// # }); +/// ``` +pub fn try_join_all(iter: I) -> TryJoinAll +where + I: IntoIterator, + I::Item: TryFuture, +{ + let iter = iter.into_iter().map(TryFutureExt::into_future); + + #[cfg(target_os = "none")] + #[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))] + { + let kind = TryJoinAllKind::Small { + elems: iter.map(TryMaybeDone::Future).collect::>().into(), + }; + + assert_future::::Ok>, ::Error>, _>( + TryJoinAll { kind }, + ) + } + + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + { + let kind = match iter.size_hint().1 { + Some(max) if max <= join_all::SMALL => TryJoinAllKind::Small { + elems: iter.map(TryMaybeDone::Future).collect::>().into(), + }, + _ => TryJoinAllKind::Big { fut: iter.collect::>().try_collect() }, + }; + + assert_future::::Ok>, ::Error>, _>( + TryJoinAll { kind }, + ) + } +} + +impl Future for TryJoinAll +where + F: TryFuture, +{ + type Output = Result, F::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match &mut self.kind { + TryJoinAllKind::Small { elems } => { + let mut state = FinalState::AllDone; + + for elem in join_all::iter_pin_mut(elems.as_mut()) { + match elem.try_poll(cx) { + Poll::Pending => state = FinalState::Pending, + Poll::Ready(Ok(())) => {} + Poll::Ready(Err(e)) => { + state = FinalState::Error(e); + break; + } + } + } + + match state { + FinalState::Pending => Poll::Pending, + FinalState::AllDone => { + let mut elems = mem::replace(elems, Box::pin([])); + let results = join_all::iter_pin_mut(elems.as_mut()) + .map(|e| e.take_output().unwrap()) + .collect(); + Poll::Ready(Ok(results)) + } + FinalState::Error(e) => { + let _ = mem::replace(elems, Box::pin([])); + Poll::Ready(Err(e)) + } + } + } + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + TryJoinAllKind::Big { fut } => Pin::new(fut).poll(cx), + } + } +} + +impl FromIterator for TryJoinAll +where + F: TryFuture, +{ + fn from_iter>(iter: T) -> Self { + try_join_all(iter) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_maybe_done.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_maybe_done.rs new file mode 100644 index 00000000..24044d2c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_maybe_done.rs @@ -0,0 +1,92 @@ +//! Definition of the TryMaybeDone combinator + +use super::assert_future; +use core::mem; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future, TryFuture}; +use futures_core::ready; +use futures_core::task::{Context, Poll}; + +/// A future that may have completed with an error. +/// +/// This is created by the [`try_maybe_done()`] function. +#[derive(Debug)] +pub enum TryMaybeDone { + /// A not-yet-completed future + Future(/* #[pin] */ Fut), + /// The output of the completed future + Done(Fut::Ok), + /// The empty variant after the result of a [`TryMaybeDone`] has been + /// taken using the [`take_output`](TryMaybeDone::take_output) method, + /// or if the future returned an error. + Gone, +} + +impl Unpin for TryMaybeDone {} + +/// Wraps a future into a `TryMaybeDone` +pub fn try_maybe_done(future: Fut) -> TryMaybeDone { + assert_future::, _>(TryMaybeDone::Future(future)) +} + +impl TryMaybeDone { + /// Returns an [`Option`] containing a mutable reference to the output of the future. + /// The output of this method will be [`Some`] if and only if the inner + /// future has completed successfully and [`take_output`](TryMaybeDone::take_output) + /// has not yet been called. + #[inline] + pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Ok> { + unsafe { + match self.get_unchecked_mut() { + TryMaybeDone::Done(res) => Some(res), + _ => None, + } + } + } + + /// Attempt to take the output of a `TryMaybeDone` without driving it + /// towards completion. + #[inline] + pub fn take_output(self: Pin<&mut Self>) -> Option { + match &*self { + Self::Done(_) => {} + Self::Future(_) | Self::Gone => return None, + } + unsafe { + match mem::replace(self.get_unchecked_mut(), Self::Gone) { + TryMaybeDone::Done(output) => Some(output), + _ => unreachable!(), + } + } + } +} + +impl FusedFuture for TryMaybeDone { + fn is_terminated(&self) -> bool { + match self { + Self::Future(_) => false, + Self::Done(_) | Self::Gone => true, + } + } +} + +impl Future for TryMaybeDone { + type Output = Result<(), Fut::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + unsafe { + match self.as_mut().get_unchecked_mut() { + TryMaybeDone::Future(f) => match ready!(Pin::new_unchecked(f).try_poll(cx)) { + Ok(res) => self.set(Self::Done(res)), + Err(e) => { + self.set(Self::Gone); + return Poll::Ready(Err(e)); + } + }, + TryMaybeDone::Done(_) => {} + TryMaybeDone::Gone => panic!("TryMaybeDone polled after value taken"), + } + } + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/future/try_select.rs b/utshell-0.5.0/vendor/futures-util/src/future/try_select.rs new file mode 100644 index 00000000..bc282f7d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/future/try_select.rs @@ -0,0 +1,85 @@ +use crate::future::{Either, TryFutureExt}; +use core::pin::Pin; +use futures_core::future::{Future, TryFuture}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`try_select()`] function. +#[must_use = "futures do nothing unless you `.await` or poll them"] +#[derive(Debug)] +pub struct TrySelect { + inner: Option<(A, B)>, +} + +impl Unpin for TrySelect {} + +type EitherOk = Either<(::Ok, B), (::Ok, A)>; +type EitherErr = Either<(::Error, B), (::Error, A)>; + +/// Waits for either one of two differently-typed futures to complete. +/// +/// This function will return a new future which awaits for either one of both +/// futures to complete. The returned future will finish with both the value +/// resolved and a future representing the completion of the other work. +/// +/// Note that this function consumes the receiving futures and returns a +/// wrapped version of them. +/// +/// Also note that if both this and the second future have the same +/// success/error type you can use the `Either::factor_first` method to +/// conveniently extract out the value at the end. +/// +/// # Examples +/// +/// ``` +/// use futures::future::{self, Either, Future, FutureExt, TryFuture, TryFutureExt}; +/// +/// // A poor-man's try_join implemented on top of select +/// +/// fn try_join(a: A, b: B) -> impl TryFuture +/// where A: TryFuture + Unpin + 'static, +/// B: TryFuture + Unpin + 'static, +/// E: 'static, +/// { +/// future::try_select(a, b).then(|res| -> Box> + Unpin> { +/// match res { +/// Ok(Either::Left((x, b))) => Box::new(b.map_ok(move |y| (x, y))), +/// Ok(Either::Right((y, a))) => Box::new(a.map_ok(move |x| (x, y))), +/// Err(Either::Left((e, _))) => Box::new(future::err(e)), +/// Err(Either::Right((e, _))) => Box::new(future::err(e)), +/// } +/// }) +/// } +/// ``` +pub fn try_select(future1: A, future2: B) -> TrySelect +where + A: TryFuture + Unpin, + B: TryFuture + Unpin, +{ + super::assert_future::, EitherErr>, _>(TrySelect { + inner: Some((future1, future2)), + }) +} + +impl Future for TrySelect +where + A: TryFuture, + B: TryFuture, +{ + type Output = Result, EitherErr>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let (mut a, mut b) = self.inner.take().expect("cannot poll Select twice"); + match a.try_poll_unpin(cx) { + Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Left((x, b)))), + Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Left((x, b)))), + Poll::Pending => match b.try_poll_unpin(cx) { + Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Right((x, a)))), + Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Right((x, a)))), + Poll::Pending => { + self.inner = Some((a, b)); + Poll::Pending + } + }, + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/allow_std.rs b/utshell-0.5.0/vendor/futures-util/src/io/allow_std.rs new file mode 100644 index 00000000..ec30ee31 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/allow_std.rs @@ -0,0 +1,200 @@ +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom}; +use std::pin::Pin; +use std::{fmt, io}; + +/// A simple wrapper type which allows types which implement only +/// implement `std::io::Read` or `std::io::Write` +/// to be used in contexts which expect an `AsyncRead` or `AsyncWrite`. +/// +/// If these types issue an error with the kind `io::ErrorKind::WouldBlock`, +/// it is expected that they will notify the current task on readiness. +/// Synchronous `std` types should not issue errors of this kind and +/// are safe to use in this context. However, using these types with +/// `AllowStdIo` will cause the event loop to block, so they should be used +/// with care. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct AllowStdIo(T); + +impl Unpin for AllowStdIo {} + +macro_rules! try_with_interrupt { + ($e:expr) => { + loop { + match $e { + Ok(e) => { + break e; + } + Err(ref e) if e.kind() == ::std::io::ErrorKind::Interrupted => { + continue; + } + Err(e) => { + return Poll::Ready(Err(e)); + } + } + } + }; +} + +impl AllowStdIo { + /// Creates a new `AllowStdIo` from an existing IO object. + pub fn new(io: T) -> Self { + Self(io) + } + + /// Returns a reference to the contained IO object. + pub fn get_ref(&self) -> &T { + &self.0 + } + + /// Returns a mutable reference to the contained IO object. + pub fn get_mut(&mut self) -> &mut T { + &mut self.0 + } + + /// Consumes self and returns the contained IO object. + pub fn into_inner(self) -> T { + self.0 + } +} + +impl io::Write for AllowStdIo +where + T: io::Write, +{ + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.0.write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { + self.0.write_fmt(fmt) + } +} + +impl AsyncWrite for AllowStdIo +where + T: io::Write, +{ + fn poll_write( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Poll::Ready(Ok(try_with_interrupt!(self.0.write(buf)))) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Poll::Ready(Ok(try_with_interrupt!(self.0.write_vectored(bufs)))) + } + + fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + try_with_interrupt!(self.0.flush()); + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.poll_flush(cx) + } +} + +impl io::Read for AllowStdIo +where + T: io::Read, +{ + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.0.read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + self.0.read_to_string(buf) + } + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + self.0.read_exact(buf) + } +} + +impl AsyncRead for AllowStdIo +where + T: io::Read, +{ + fn poll_read( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Poll::Ready(Ok(try_with_interrupt!(self.0.read(buf)))) + } + + fn poll_read_vectored( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs)))) + } +} + +impl io::Seek for AllowStdIo +where + T: io::Seek, +{ + fn seek(&mut self, pos: SeekFrom) -> io::Result { + self.0.seek(pos) + } +} + +impl AsyncSeek for AllowStdIo +where + T: io::Seek, +{ + fn poll_seek( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos)))) + } +} + +impl io::BufRead for AllowStdIo +where + T: io::BufRead, +{ + fn fill_buf(&mut self) -> io::Result<&[u8]> { + self.0.fill_buf() + } + fn consume(&mut self, amt: usize) { + self.0.consume(amt) + } +} + +impl AsyncBufRead for AllowStdIo +where + T: io::BufRead, +{ + fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + let this: *mut Self = &mut *self as *mut _; + Poll::Ready(Ok(try_with_interrupt!(unsafe { &mut *this }.0.fill_buf()))) + } + + fn consume(mut self: Pin<&mut Self>, amt: usize) { + self.0.consume(amt) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/buf_reader.rs b/utshell-0.5.0/vendor/futures-util/src/io/buf_reader.rs new file mode 100644 index 00000000..0334a9f0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/buf_reader.rs @@ -0,0 +1,263 @@ +use super::DEFAULT_BUF_SIZE; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSliceMut, SeekFrom}; +use pin_project_lite::pin_project; +use std::io::{self, Read}; +use std::pin::Pin; +use std::{cmp, fmt}; + +pin_project! { + /// The `BufReader` struct adds buffering to any reader. + /// + /// It can be excessively inefficient to work directly with a [`AsyncRead`] + /// instance. A `BufReader` performs large, infrequent reads on the underlying + /// [`AsyncRead`] and maintains an in-memory buffer of the results. + /// + /// `BufReader` can improve the speed of programs that make *small* and + /// *repeated* read calls to the same file or network socket. It does not + /// help when reading very large amounts at once, or reading just one or a few + /// times. It also provides no advantage when reading from a source that is + /// already in memory, like a `Vec`. + /// + /// When the `BufReader` is dropped, the contents of its buffer will be + /// discarded. Creating multiple instances of a `BufReader` on the same + /// stream can cause data loss. + /// + /// [`AsyncRead`]: futures_io::AsyncRead + /// + // TODO: Examples + pub struct BufReader { + #[pin] + inner: R, + buffer: Box<[u8]>, + pos: usize, + cap: usize, + } +} + +impl BufReader { + /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB, + /// but may change in the future. + pub fn new(inner: R) -> Self { + Self::with_capacity(DEFAULT_BUF_SIZE, inner) + } + + /// Creates a new `BufReader` with the specified buffer capacity. + pub fn with_capacity(capacity: usize, inner: R) -> Self { + unsafe { + let mut buffer = Vec::with_capacity(capacity); + buffer.set_len(capacity); + super::initialize(&inner, &mut buffer); + Self { inner, buffer: buffer.into_boxed_slice(), pos: 0, cap: 0 } + } + } + + delegate_access_inner!(inner, R, ()); + + /// Returns a reference to the internally buffered data. + /// + /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty. + pub fn buffer(&self) -> &[u8] { + &self.buffer[self.pos..self.cap] + } + + /// Invalidates all data in the internal buffer. + #[inline] + fn discard_buffer(self: Pin<&mut Self>) { + let this = self.project(); + *this.pos = 0; + *this.cap = 0; + } +} + +impl BufReader { + /// Seeks relative to the current position. If the new position lies within the buffer, + /// the buffer will not be flushed, allowing for more efficient seeks. + /// This method does not return the location of the underlying reader, so the caller + /// must track this information themselves if it is required. + pub fn seek_relative(self: Pin<&mut Self>, offset: i64) -> SeeKRelative<'_, R> { + SeeKRelative { inner: self, offset, first: true } + } + + /// Attempts to seek relative to the current position. If the new position lies within the buffer, + /// the buffer will not be flushed, allowing for more efficient seeks. + /// This method does not return the location of the underlying reader, so the caller + /// must track this information themselves if it is required. + pub fn poll_seek_relative( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + offset: i64, + ) -> Poll> { + let pos = self.pos as u64; + if offset < 0 { + if let Some(new_pos) = pos.checked_sub((-offset) as u64) { + *self.project().pos = new_pos as usize; + return Poll::Ready(Ok(())); + } + } else if let Some(new_pos) = pos.checked_add(offset as u64) { + if new_pos <= self.cap as u64 { + *self.project().pos = new_pos as usize; + return Poll::Ready(Ok(())); + } + } + self.poll_seek(cx, SeekFrom::Current(offset)).map(|res| res.map(|_| ())) + } +} + +impl AsyncRead for BufReader { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + // If we don't have any buffered data and we're doing a massive read + // (larger than our internal buffer), bypass our internal buffer + // entirely. + if self.pos == self.cap && buf.len() >= self.buffer.len() { + let res = ready!(self.as_mut().project().inner.poll_read(cx, buf)); + self.discard_buffer(); + return Poll::Ready(res); + } + let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?; + let nread = rem.read(buf)?; + self.consume(nread); + Poll::Ready(Ok(nread)) + } + + fn poll_read_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + let total_len = bufs.iter().map(|b| b.len()).sum::(); + if self.pos == self.cap && total_len >= self.buffer.len() { + let res = ready!(self.as_mut().project().inner.poll_read_vectored(cx, bufs)); + self.discard_buffer(); + return Poll::Ready(res); + } + let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?; + let nread = rem.read_vectored(bufs)?; + self.consume(nread); + Poll::Ready(Ok(nread)) + } +} + +impl AsyncBufRead for BufReader { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + // If we've reached the end of our internal buffer then we need to fetch + // some more data from the underlying reader. + // Branch using `>=` instead of the more correct `==` + // to tell the compiler that the pos..cap slice is always valid. + if *this.pos >= *this.cap { + debug_assert!(*this.pos == *this.cap); + *this.cap = ready!(this.inner.poll_read(cx, this.buffer))?; + *this.pos = 0; + } + Poll::Ready(Ok(&this.buffer[*this.pos..*this.cap])) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + *self.project().pos = cmp::min(self.pos + amt, self.cap); + } +} + +impl AsyncWrite for BufReader { + delegate_async_write!(inner); +} + +impl fmt::Debug for BufReader { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("BufReader") + .field("reader", &self.inner) + .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buffer.len())) + .finish() + } +} + +impl AsyncSeek for BufReader { + /// Seek to an offset, in bytes, in the underlying reader. + /// + /// The position used for seeking with `SeekFrom::Current(_)` is the + /// position the underlying reader would be at if the `BufReader` had no + /// internal buffer. + /// + /// Seeking always discards the internal buffer, even if the seek position + /// would otherwise fall within it. This guarantees that calling + /// `.into_inner()` immediately after a seek yields the underlying reader + /// at the same position. + /// + /// To seek without discarding the internal buffer, use + /// [`BufReader::seek_relative`](BufReader::seek_relative) or + /// [`BufReader::poll_seek_relative`](BufReader::poll_seek_relative). + /// + /// See [`AsyncSeek`](futures_io::AsyncSeek) for more details. + /// + /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)` + /// where `n` minus the internal buffer length overflows an `i64`, two + /// seeks will be performed instead of one. If the second seek returns + /// `Err`, the underlying reader will be left at the same position it would + /// have if you called `seek` with `SeekFrom::Current(0)`. + fn poll_seek( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + let result: u64; + if let SeekFrom::Current(n) = pos { + let remainder = (self.cap - self.pos) as i64; + // it should be safe to assume that remainder fits within an i64 as the alternative + // means we managed to allocate 8 exbibytes and that's absurd. + // But it's not out of the realm of possibility for some weird underlying reader to + // support seeking by i64::min_value() so we need to handle underflow when subtracting + // remainder. + if let Some(offset) = n.checked_sub(remainder) { + result = + ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?; + } else { + // seek backwards by our remainder, and then by the offset + ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(-remainder)))?; + self.as_mut().discard_buffer(); + result = ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(n)))?; + } + } else { + // Seeking with Start/End doesn't care about our buffer length. + result = ready!(self.as_mut().project().inner.poll_seek(cx, pos))?; + } + self.discard_buffer(); + Poll::Ready(Ok(result)) + } +} + +/// Future for the [`BufReader::seek_relative`](self::BufReader::seek_relative) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct SeeKRelative<'a, R> { + inner: Pin<&'a mut BufReader>, + offset: i64, + first: bool, +} + +impl Future for SeeKRelative<'_, R> +where + R: AsyncRead + AsyncSeek, +{ + type Output = io::Result<()>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let offset = self.offset; + if self.first { + self.first = false; + self.inner.as_mut().poll_seek_relative(cx, offset) + } else { + self.inner + .as_mut() + .as_mut() + .poll_seek(cx, SeekFrom::Current(offset)) + .map(|res| res.map(|_| ())) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/buf_writer.rs b/utshell-0.5.0/vendor/futures-util/src/io/buf_writer.rs new file mode 100644 index 00000000..cb74863a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/buf_writer.rs @@ -0,0 +1,224 @@ +use super::DEFAULT_BUF_SIZE; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, SeekFrom}; +use pin_project_lite::pin_project; +use std::fmt; +use std::io::{self, Write}; +use std::pin::Pin; +use std::ptr; + +pin_project! { + /// Wraps a writer and buffers its output. + /// + /// It can be excessively inefficient to work directly with something that + /// implements [`AsyncWrite`]. A `BufWriter` keeps an in-memory buffer of data and + /// writes it to an underlying writer in large, infrequent batches. + /// + /// `BufWriter` can improve the speed of programs that make *small* and + /// *repeated* write calls to the same file or network socket. It does not + /// help when writing very large amounts at once, or writing just one or a few + /// times. It also provides no advantage when writing to a destination that is + /// in memory, like a `Vec`. + /// + /// When the `BufWriter` is dropped, the contents of its buffer will be + /// discarded. Creating multiple instances of a `BufWriter` on the same + /// stream can cause data loss. If you need to write out the contents of its + /// buffer, you must manually call flush before the writer is dropped. + /// + /// [`AsyncWrite`]: futures_io::AsyncWrite + /// [`flush`]: super::AsyncWriteExt::flush + /// + // TODO: Examples + pub struct BufWriter { + #[pin] + inner: W, + buf: Vec, + written: usize, + } +} + +impl BufWriter { + /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB, + /// but may change in the future. + pub fn new(inner: W) -> Self { + Self::with_capacity(DEFAULT_BUF_SIZE, inner) + } + + /// Creates a new `BufWriter` with the specified buffer capacity. + pub fn with_capacity(cap: usize, inner: W) -> Self { + Self { inner, buf: Vec::with_capacity(cap), written: 0 } + } + + pub(super) fn flush_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + let len = this.buf.len(); + let mut ret = Ok(()); + while *this.written < len { + match ready!(this.inner.as_mut().poll_write(cx, &this.buf[*this.written..])) { + Ok(0) => { + ret = Err(io::Error::new( + io::ErrorKind::WriteZero, + "failed to write the buffered data", + )); + break; + } + Ok(n) => *this.written += n, + Err(e) => { + ret = Err(e); + break; + } + } + } + if *this.written > 0 { + this.buf.drain(..*this.written); + } + *this.written = 0; + Poll::Ready(ret) + } + + delegate_access_inner!(inner, W, ()); + + /// Returns a reference to the internally buffered data. + pub fn buffer(&self) -> &[u8] { + &self.buf + } + + /// Capacity of `buf`. how many chars can be held in buffer + pub(super) fn capacity(&self) -> usize { + self.buf.capacity() + } + + /// Remaining number of bytes to reach `buf` 's capacity + #[inline] + pub(super) fn spare_capacity(&self) -> usize { + self.buf.capacity() - self.buf.len() + } + + /// Write a byte slice directly into buffer + /// + /// Will truncate the number of bytes written to `spare_capacity()` so you want to + /// calculate the size of your slice to avoid losing bytes + /// + /// Based on `std::io::BufWriter` + pub(super) fn write_to_buf(self: Pin<&mut Self>, buf: &[u8]) -> usize { + let available = self.spare_capacity(); + let amt_to_buffer = available.min(buf.len()); + + // SAFETY: `amt_to_buffer` is <= buffer's spare capacity by construction. + unsafe { + self.write_to_buffer_unchecked(&buf[..amt_to_buffer]); + } + + amt_to_buffer + } + + /// Write byte slice directly into `self.buf` + /// + /// Based on `std::io::BufWriter` + #[inline] + unsafe fn write_to_buffer_unchecked(self: Pin<&mut Self>, buf: &[u8]) { + debug_assert!(buf.len() <= self.spare_capacity()); + let this = self.project(); + let old_len = this.buf.len(); + let buf_len = buf.len(); + let src = buf.as_ptr(); + let dst = this.buf.as_mut_ptr().add(old_len); + ptr::copy_nonoverlapping(src, dst, buf_len); + this.buf.set_len(old_len + buf_len); + } + + /// Write directly using `inner`, bypassing buffering + pub(super) fn inner_poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + self.project().inner.poll_write(cx, buf) + } + + /// Write directly using `inner`, bypassing buffering + pub(super) fn inner_poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + self.project().inner.poll_write_vectored(cx, bufs) + } +} + +impl AsyncWrite for BufWriter { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + if self.buf.len() + buf.len() > self.buf.capacity() { + ready!(self.as_mut().flush_buf(cx))?; + } + if buf.len() >= self.buf.capacity() { + self.project().inner.poll_write(cx, buf) + } else { + Poll::Ready(self.project().buf.write(buf)) + } + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + let total_len = bufs.iter().map(|b| b.len()).sum::(); + if self.buf.len() + total_len > self.buf.capacity() { + ready!(self.as_mut().flush_buf(cx))?; + } + if total_len >= self.buf.capacity() { + self.project().inner.poll_write_vectored(cx, bufs) + } else { + Poll::Ready(self.project().buf.write_vectored(bufs)) + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().flush_buf(cx))?; + self.project().inner.poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().flush_buf(cx))?; + self.project().inner.poll_close(cx) + } +} + +impl AsyncRead for BufWriter { + delegate_async_read!(inner); +} + +impl AsyncBufRead for BufWriter { + delegate_async_buf_read!(inner); +} + +impl fmt::Debug for BufWriter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("BufWriter") + .field("writer", &self.inner) + .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity())) + .field("written", &self.written) + .finish() + } +} + +impl AsyncSeek for BufWriter { + /// Seek to the offset, in bytes, in the underlying writer. + /// + /// Seeking always writes out the internal buffer before seeking. + fn poll_seek( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + ready!(self.as_mut().flush_buf(cx))?; + self.project().inner.poll_seek(cx, pos) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/chain.rs b/utshell-0.5.0/vendor/futures-util/src/io/chain.rs new file mode 100644 index 00000000..728a3d2d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/chain.rs @@ -0,0 +1,142 @@ +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead, IoSliceMut}; +use pin_project_lite::pin_project; +use std::fmt; +use std::io; +use std::pin::Pin; + +pin_project! { + /// Reader for the [`chain`](super::AsyncReadExt::chain) method. + #[must_use = "readers do nothing unless polled"] + pub struct Chain { + #[pin] + first: T, + #[pin] + second: U, + done_first: bool, + } +} + +impl Chain +where + T: AsyncRead, + U: AsyncRead, +{ + pub(super) fn new(first: T, second: U) -> Self { + Self { first, second, done_first: false } + } + + /// Gets references to the underlying readers in this `Chain`. + pub fn get_ref(&self) -> (&T, &U) { + (&self.first, &self.second) + } + + /// Gets mutable references to the underlying readers in this `Chain`. + /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying readers as doing so may corrupt the internal state of this + /// `Chain`. + pub fn get_mut(&mut self) -> (&mut T, &mut U) { + (&mut self.first, &mut self.second) + } + + /// Gets pinned mutable references to the underlying readers in this `Chain`. + /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying readers as doing so may corrupt the internal state of this + /// `Chain`. + pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) { + let this = self.project(); + (this.first, this.second) + } + + /// Consumes the `Chain`, returning the wrapped readers. + pub fn into_inner(self) -> (T, U) { + (self.first, self.second) + } +} + +impl fmt::Debug for Chain +where + T: fmt::Debug, + U: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Chain") + .field("t", &self.first) + .field("u", &self.second) + .field("done_first", &self.done_first) + .finish() + } +} + +impl AsyncRead for Chain +where + T: AsyncRead, + U: AsyncRead, +{ + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + let this = self.project(); + + if !*this.done_first { + match ready!(this.first.poll_read(cx, buf)?) { + 0 if !buf.is_empty() => *this.done_first = true, + n => return Poll::Ready(Ok(n)), + } + } + this.second.poll_read(cx, buf) + } + + fn poll_read_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + let this = self.project(); + + if !*this.done_first { + let n = ready!(this.first.poll_read_vectored(cx, bufs)?); + if n == 0 && bufs.iter().any(|b| !b.is_empty()) { + *this.done_first = true + } else { + return Poll::Ready(Ok(n)); + } + } + this.second.poll_read_vectored(cx, bufs) + } +} + +impl AsyncBufRead for Chain +where + T: AsyncBufRead, + U: AsyncBufRead, +{ + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + if !*this.done_first { + match ready!(this.first.poll_fill_buf(cx)?) { + buf if buf.is_empty() => { + *this.done_first = true; + } + buf => return Poll::Ready(Ok(buf)), + } + } + this.second.poll_fill_buf(cx) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + let this = self.project(); + + if !*this.done_first { + this.first.consume(amt) + } else { + this.second.consume(amt) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/close.rs b/utshell-0.5.0/vendor/futures-util/src/io/close.rs new file mode 100644 index 00000000..b9445927 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/close.rs @@ -0,0 +1,28 @@ +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncWrite; +use std::io; +use std::pin::Pin; + +/// Future for the [`close`](super::AsyncWriteExt::close) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Close<'a, W: ?Sized> { + writer: &'a mut W, +} + +impl Unpin for Close<'_, W> {} + +impl<'a, W: AsyncWrite + ?Sized + Unpin> Close<'a, W> { + pub(super) fn new(writer: &'a mut W) -> Self { + Self { writer } + } +} + +impl Future for Close<'_, W> { + type Output = io::Result<()>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut *self.writer).poll_close(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/copy.rs b/utshell-0.5.0/vendor/futures-util/src/io/copy.rs new file mode 100644 index 00000000..c80add27 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/copy.rs @@ -0,0 +1,58 @@ +use super::{copy_buf, BufReader, CopyBuf}; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncRead, AsyncWrite}; +use pin_project_lite::pin_project; +use std::io; +use std::pin::Pin; + +/// Creates a future which copies all the bytes from one object to another. +/// +/// The returned future will copy all the bytes read from this `AsyncRead` into the +/// `writer` specified. This future will only complete once the `reader` has hit +/// EOF and all bytes have been written to and flushed from the `writer` +/// provided. +/// +/// On success the number of bytes is returned. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncWriteExt, Cursor}; +/// +/// let reader = Cursor::new([1, 2, 3, 4]); +/// let mut writer = Cursor::new(vec![0u8; 5]); +/// +/// let bytes = io::copy(reader, &mut writer).await?; +/// writer.close().await?; +/// +/// assert_eq!(bytes, 4); +/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn copy(reader: R, writer: &mut W) -> Copy<'_, R, W> +where + R: AsyncRead, + W: AsyncWrite + Unpin + ?Sized, +{ + Copy { inner: copy_buf(BufReader::new(reader), writer) } +} + +pin_project! { + /// Future for the [`copy()`] function. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Copy<'a, R, W: ?Sized> { + #[pin] + inner: CopyBuf<'a, BufReader, W>, + } +} + +impl Future for Copy<'_, R, W> { + type Output = io::Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.project().inner.poll(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/copy_buf.rs b/utshell-0.5.0/vendor/futures-util/src/io/copy_buf.rs new file mode 100644 index 00000000..50f7abdc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/copy_buf.rs @@ -0,0 +1,78 @@ +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncWrite}; +use pin_project_lite::pin_project; +use std::io; +use std::pin::Pin; + +/// Creates a future which copies all the bytes from one object to another. +/// +/// The returned future will copy all the bytes read from this `AsyncBufRead` into the +/// `writer` specified. This future will only complete once the `reader` has hit +/// EOF and all bytes have been written to and flushed from the `writer` +/// provided. +/// +/// On success the number of bytes is returned. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncWriteExt, Cursor}; +/// +/// let reader = Cursor::new([1, 2, 3, 4]); +/// let mut writer = Cursor::new(vec![0u8; 5]); +/// +/// let bytes = io::copy_buf(reader, &mut writer).await?; +/// writer.close().await?; +/// +/// assert_eq!(bytes, 4); +/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn copy_buf(reader: R, writer: &mut W) -> CopyBuf<'_, R, W> +where + R: AsyncBufRead, + W: AsyncWrite + Unpin + ?Sized, +{ + CopyBuf { reader, writer, amt: 0 } +} + +pin_project! { + /// Future for the [`copy_buf()`] function. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct CopyBuf<'a, R, W: ?Sized> { + #[pin] + reader: R, + writer: &'a mut W, + amt: u64, + } +} + +impl Future for CopyBuf<'_, R, W> +where + R: AsyncBufRead, + W: AsyncWrite + Unpin + ?Sized, +{ + type Output = io::Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + loop { + let buffer = ready!(this.reader.as_mut().poll_fill_buf(cx))?; + if buffer.is_empty() { + ready!(Pin::new(&mut this.writer).poll_flush(cx))?; + return Poll::Ready(Ok(*this.amt)); + } + + let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?; + if i == 0 { + return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); + } + *this.amt += i as u64; + this.reader.as_mut().consume(i); + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/copy_buf_abortable.rs b/utshell-0.5.0/vendor/futures-util/src/io/copy_buf_abortable.rs new file mode 100644 index 00000000..ed22d623 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/copy_buf_abortable.rs @@ -0,0 +1,124 @@ +use crate::abortable::{AbortHandle, AbortInner, Aborted}; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncWrite}; +use pin_project_lite::pin_project; +use std::io; +use std::pin::Pin; +use std::sync::atomic::Ordering; +use std::sync::Arc; + +/// Creates a future which copies all the bytes from one object to another, with its `AbortHandle`. +/// +/// The returned future will copy all the bytes read from this `AsyncBufRead` into the +/// `writer` specified. This future will only complete once abort has been requested or the `reader` has hit +/// EOF and all bytes have been written to and flushed from the `writer` +/// provided. +/// +/// On success the number of bytes is returned. If aborted, `Aborted` is returned. Otherwise, the underlying error is returned. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncWriteExt, Cursor}; +/// use futures::future::Aborted; +/// +/// let reader = Cursor::new([1, 2, 3, 4]); +/// let mut writer = Cursor::new(vec![0u8; 5]); +/// +/// let (fut, abort_handle) = io::copy_buf_abortable(reader, &mut writer); +/// let bytes = fut.await; +/// abort_handle.abort(); +/// writer.close().await.unwrap(); +/// match bytes { +/// Ok(Ok(n)) => { +/// assert_eq!(n, 4); +/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); +/// Ok(n) +/// }, +/// Ok(Err(a)) => { +/// Err::(a) +/// } +/// Err(e) => panic!("{}", e) +/// } +/// # }).unwrap(); +/// ``` +pub fn copy_buf_abortable( + reader: R, + writer: &mut W, +) -> (CopyBufAbortable<'_, R, W>, AbortHandle) +where + R: AsyncBufRead, + W: AsyncWrite + Unpin + ?Sized, +{ + let (handle, reg) = AbortHandle::new_pair(); + (CopyBufAbortable { reader, writer, amt: 0, inner: reg.inner }, handle) +} + +pin_project! { + /// Future for the [`copy_buf_abortable()`] function. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct CopyBufAbortable<'a, R, W: ?Sized> { + #[pin] + reader: R, + writer: &'a mut W, + amt: u64, + inner: Arc + } +} + +macro_rules! ready_or_break { + ($e:expr $(,)?) => { + match $e { + $crate::task::Poll::Ready(t) => t, + $crate::task::Poll::Pending => break, + } + }; +} + +impl Future for CopyBufAbortable<'_, R, W> +where + R: AsyncBufRead, + W: AsyncWrite + Unpin + Sized, +{ + type Output = Result, io::Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + loop { + // Check if the task has been aborted + if this.inner.aborted.load(Ordering::Relaxed) { + return Poll::Ready(Ok(Err(Aborted))); + } + + // Read some bytes from the reader, and if we have reached EOF, return total bytes read + let buffer = ready_or_break!(this.reader.as_mut().poll_fill_buf(cx))?; + if buffer.is_empty() { + ready_or_break!(Pin::new(&mut this.writer).poll_flush(cx))?; + return Poll::Ready(Ok(Ok(*this.amt))); + } + + // Pass the buffer to the writer, and update the amount written + let i = ready_or_break!(Pin::new(&mut this.writer).poll_write(cx, buffer))?; + if i == 0 { + return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); + } + *this.amt += i as u64; + this.reader.as_mut().consume(i); + } + // Schedule the task to be woken up again. + // Never called unless Poll::Pending is returned from io objects. + this.inner.waker.register(cx.waker()); + + // Check to see if the task was aborted between the first check and + // registration. + // Checking with `Relaxed` is sufficient because + // `register` introduces an `AcqRel` barrier. + if this.inner.aborted.load(Ordering::Relaxed) { + return Poll::Ready(Ok(Err(Aborted))); + } + Poll::Pending + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/cursor.rs b/utshell-0.5.0/vendor/futures-util/src/io/cursor.rs new file mode 100644 index 00000000..c6e2aeea --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/cursor.rs @@ -0,0 +1,232 @@ +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom}; +use std::io; +use std::pin::Pin; + +/// A `Cursor` wraps an in-memory buffer and provides it with a +/// [`AsyncSeek`] implementation. +/// +/// `Cursor`s are used with in-memory buffers, anything implementing +/// `AsRef<[u8]>`, to allow them to implement [`AsyncRead`] and/or [`AsyncWrite`], +/// allowing these buffers to be used anywhere you might use a reader or writer +/// that does actual I/O. +/// +/// This library implements some I/O traits on various types which +/// are commonly used as a buffer, like `Cursor<`[`Vec`]`>` and +/// `Cursor<`[`&[u8]`][bytes]`>`. +/// +/// [`AsyncSeek`]: trait.AsyncSeek.html +/// [`AsyncRead`]: trait.AsyncRead.html +/// [`AsyncWrite`]: trait.AsyncWrite.html +/// [bytes]: https://doc.rust-lang.org/std/primitive.slice.html +#[derive(Clone, Debug, Default)] +pub struct Cursor { + inner: io::Cursor, +} + +impl Cursor { + /// Creates a new cursor wrapping the provided underlying in-memory buffer. + /// + /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`) + /// is not empty. So writing to cursor starts with overwriting `Vec` + /// content, not with appending to it. + /// + /// # Examples + /// + /// ``` + /// use futures::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// ``` + pub fn new(inner: T) -> Self { + Self { inner: io::Cursor::new(inner) } + } + + /// Consumes this cursor, returning the underlying value. + /// + /// # Examples + /// + /// ``` + /// use futures::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let vec = buff.into_inner(); + /// ``` + pub fn into_inner(self) -> T { + self.inner.into_inner() + } + + /// Gets a reference to the underlying value in this cursor. + /// + /// # Examples + /// + /// ``` + /// use futures::io::Cursor; + /// + /// let buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let reference = buff.get_ref(); + /// ``` + pub fn get_ref(&self) -> &T { + self.inner.get_ref() + } + + /// Gets a mutable reference to the underlying value in this cursor. + /// + /// Care should be taken to avoid modifying the internal I/O state of the + /// underlying value as it may corrupt this cursor's position. + /// + /// # Examples + /// + /// ``` + /// use futures::io::Cursor; + /// + /// let mut buff = Cursor::new(Vec::new()); + /// # fn force_inference(_: &Cursor>) {} + /// # force_inference(&buff); + /// + /// let reference = buff.get_mut(); + /// ``` + pub fn get_mut(&mut self) -> &mut T { + self.inner.get_mut() + } + + /// Returns the current position of this cursor. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncSeekExt, Cursor, SeekFrom}; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.position(), 0); + /// + /// buff.seek(SeekFrom::Current(2)).await?; + /// assert_eq!(buff.position(), 2); + /// + /// buff.seek(SeekFrom::Current(-1)).await?; + /// assert_eq!(buff.position(), 1); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + pub fn position(&self) -> u64 { + self.inner.position() + } + + /// Sets the position of this cursor. + /// + /// # Examples + /// + /// ``` + /// use futures::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.position(), 0); + /// + /// buff.set_position(2); + /// assert_eq!(buff.position(), 2); + /// + /// buff.set_position(4); + /// assert_eq!(buff.position(), 4); + /// ``` + pub fn set_position(&mut self, pos: u64) { + self.inner.set_position(pos) + } +} + +impl AsyncSeek for Cursor +where + T: AsRef<[u8]> + Unpin, +{ + fn poll_seek( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + Poll::Ready(io::Seek::seek(&mut self.inner, pos)) + } +} + +impl + Unpin> AsyncRead for Cursor { + fn poll_read( + mut self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Poll::Ready(io::Read::read(&mut self.inner, buf)) + } + + fn poll_read_vectored( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + Poll::Ready(io::Read::read_vectored(&mut self.inner, bufs)) + } +} + +impl AsyncBufRead for Cursor +where + T: AsRef<[u8]> + Unpin, +{ + fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(io::BufRead::fill_buf(&mut self.get_mut().inner)) + } + + fn consume(mut self: Pin<&mut Self>, amt: usize) { + io::BufRead::consume(&mut self.inner, amt) + } +} + +macro_rules! delegate_async_write_to_stdio { + () => { + fn poll_write( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Poll::Ready(io::Write::write(&mut self.inner, buf)) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs)) + } + + fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(io::Write::flush(&mut self.inner)) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.poll_flush(cx) + } + }; +} + +impl AsyncWrite for Cursor<&mut [u8]> { + delegate_async_write_to_stdio!(); +} + +impl AsyncWrite for Cursor<&mut Vec> { + delegate_async_write_to_stdio!(); +} + +impl AsyncWrite for Cursor> { + delegate_async_write_to_stdio!(); +} + +impl AsyncWrite for Cursor> { + delegate_async_write_to_stdio!(); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/empty.rs b/utshell-0.5.0/vendor/futures-util/src/io/empty.rs new file mode 100644 index 00000000..02f6103f --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/empty.rs @@ -0,0 +1,59 @@ +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead}; +use std::fmt; +use std::io; +use std::pin::Pin; + +/// Reader for the [`empty()`] function. +#[must_use = "readers do nothing unless polled"] +pub struct Empty { + _priv: (), +} + +/// Constructs a new handle to an empty reader. +/// +/// All reads from the returned reader will return `Poll::Ready(Ok(0))`. +/// +/// # Examples +/// +/// A slightly sad example of not reading anything into a buffer: +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncReadExt}; +/// +/// let mut buffer = String::new(); +/// let mut reader = io::empty(); +/// reader.read_to_string(&mut buffer).await?; +/// assert!(buffer.is_empty()); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn empty() -> Empty { + Empty { _priv: () } +} + +impl AsyncRead for Empty { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + _: &mut Context<'_>, + _: &mut [u8], + ) -> Poll> { + Poll::Ready(Ok(0)) + } +} + +impl AsyncBufRead for Empty { + #[inline] + fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(&[])) + } + #[inline] + fn consume(self: Pin<&mut Self>, _: usize) {} +} + +impl fmt::Debug for Empty { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("Empty { .. }") + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/fill_buf.rs b/utshell-0.5.0/vendor/futures-util/src/io/fill_buf.rs new file mode 100644 index 00000000..45862b8e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/fill_buf.rs @@ -0,0 +1,47 @@ +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncBufRead; +use std::io; +use std::pin::Pin; +use std::slice; + +/// Future for the [`fill_buf`](super::AsyncBufReadExt::fill_buf) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct FillBuf<'a, R: ?Sized> { + reader: Option<&'a mut R>, +} + +impl Unpin for FillBuf<'_, R> {} + +impl<'a, R: AsyncBufRead + ?Sized + Unpin> FillBuf<'a, R> { + pub(super) fn new(reader: &'a mut R) -> Self { + Self { reader: Some(reader) } + } +} + +impl<'a, R> Future for FillBuf<'a, R> +where + R: AsyncBufRead + ?Sized + Unpin, +{ + type Output = io::Result<&'a [u8]>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + let reader = this.reader.take().expect("Polled FillBuf after completion"); + + match Pin::new(&mut *reader).poll_fill_buf(cx) { + Poll::Ready(Ok(slice)) => { + // With polonius it is possible to remove this lifetime transmutation and just have + // the correct lifetime of the reference inferred based on which branch is taken + let slice: &'a [u8] = unsafe { slice::from_raw_parts(slice.as_ptr(), slice.len()) }; + Poll::Ready(Ok(slice)) + } + Poll::Ready(Err(err)) => Poll::Ready(Err(err)), + Poll::Pending => { + this.reader = Some(reader); + Poll::Pending + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/flush.rs b/utshell-0.5.0/vendor/futures-util/src/io/flush.rs new file mode 100644 index 00000000..b75d14c5 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/flush.rs @@ -0,0 +1,31 @@ +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncWrite; +use std::io; +use std::pin::Pin; + +/// Future for the [`flush`](super::AsyncWriteExt::flush) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Flush<'a, W: ?Sized> { + writer: &'a mut W, +} + +impl Unpin for Flush<'_, W> {} + +impl<'a, W: AsyncWrite + ?Sized + Unpin> Flush<'a, W> { + pub(super) fn new(writer: &'a mut W) -> Self { + Self { writer } + } +} + +impl Future for Flush<'_, W> +where + W: AsyncWrite + ?Sized + Unpin, +{ + type Output = io::Result<()>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut *self.writer).poll_flush(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/into_sink.rs b/utshell-0.5.0/vendor/futures-util/src/io/into_sink.rs new file mode 100644 index 00000000..6a41ee22 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/into_sink.rs @@ -0,0 +1,82 @@ +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncWrite; +use futures_sink::Sink; +use pin_project_lite::pin_project; +use std::io; +use std::pin::Pin; + +#[derive(Debug)] +struct Block { + offset: usize, + bytes: Item, +} + +pin_project! { + /// Sink for the [`into_sink`](super::AsyncWriteExt::into_sink) method. + #[must_use = "sinks do nothing unless polled"] + #[derive(Debug)] + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + pub struct IntoSink { + #[pin] + writer: W, + // An outstanding block for us to push into the underlying writer, along with an offset of how + // far into this block we have written already. + buffer: Option>, + } +} + +impl> IntoSink { + pub(super) fn new(writer: W) -> Self { + Self { writer, buffer: None } + } + + /// If we have an outstanding block in `buffer` attempt to push it into the writer, does _not_ + /// flush the writer after it succeeds in pushing the block into it. + fn poll_flush_buffer( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.project(); + + if let Some(buffer) = this.buffer { + loop { + let bytes = buffer.bytes.as_ref(); + let written = ready!(this.writer.as_mut().poll_write(cx, &bytes[buffer.offset..]))?; + buffer.offset += written; + if buffer.offset == bytes.len() { + break; + } + } + } + *this.buffer = None; + Poll::Ready(Ok(())) + } +} + +impl> Sink for IntoSink { + type Error = io::Error; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.poll_flush_buffer(cx))?; + Poll::Ready(Ok(())) + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + debug_assert!(self.buffer.is_none()); + *self.project().buffer = Some(Block { offset: 0, bytes: item }); + Ok(()) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().poll_flush_buffer(cx))?; + ready!(self.project().writer.poll_flush(cx))?; + Poll::Ready(Ok(())) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().poll_flush_buffer(cx))?; + ready!(self.project().writer.poll_close(cx))?; + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/line_writer.rs b/utshell-0.5.0/vendor/futures-util/src/io/line_writer.rs new file mode 100644 index 00000000..71cd6683 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/line_writer.rs @@ -0,0 +1,155 @@ +use super::buf_writer::BufWriter; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncWrite; +use futures_io::IoSlice; +use pin_project_lite::pin_project; +use std::io; +use std::pin::Pin; + +pin_project! { +/// Wrap a writer, like [`BufWriter`] does, but prioritizes buffering lines +/// +/// This was written based on `std::io::LineWriter` which goes into further details +/// explaining the code. +/// +/// Buffering is actually done using `BufWriter`. This class will leverage `BufWriter` +/// to write on-each-line. +#[derive(Debug)] +pub struct LineWriter { + #[pin] + buf_writer: BufWriter, +} +} + +impl LineWriter { + /// Create a new `LineWriter` with default buffer capacity. The default is currently 1KB + /// which was taken from `std::io::LineWriter` + pub fn new(inner: W) -> LineWriter { + LineWriter::with_capacity(1024, inner) + } + + /// Creates a new `LineWriter` with the specified buffer capacity. + pub fn with_capacity(capacity: usize, inner: W) -> LineWriter { + LineWriter { buf_writer: BufWriter::with_capacity(capacity, inner) } + } + + /// Flush `buf_writer` if last char is "new line" + fn flush_if_completed_line(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + match this.buf_writer.buffer().last().copied() { + Some(b'\n') => this.buf_writer.flush_buf(cx), + _ => Poll::Ready(Ok(())), + } + } + + /// Returns a reference to `buf_writer`'s internally buffered data. + pub fn buffer(&self) -> &[u8] { + self.buf_writer.buffer() + } + + /// Acquires a reference to the underlying sink or stream that this combinator is + /// pulling from. + pub fn get_ref(&self) -> &W { + self.buf_writer.get_ref() + } +} + +impl AsyncWrite for LineWriter { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + let mut this = self.as_mut().project(); + let newline_index = match memchr::memrchr(b'\n', buf) { + None => { + ready!(self.as_mut().flush_if_completed_line(cx)?); + return self.project().buf_writer.poll_write(cx, buf); + } + Some(newline_index) => newline_index + 1, + }; + + ready!(this.buf_writer.as_mut().poll_flush(cx)?); + + let lines = &buf[..newline_index]; + + let flushed = { ready!(this.buf_writer.as_mut().inner_poll_write(cx, lines))? }; + + if flushed == 0 { + return Poll::Ready(Ok(0)); + } + + let tail = if flushed >= newline_index { + &buf[flushed..] + } else if newline_index - flushed <= this.buf_writer.capacity() { + &buf[flushed..newline_index] + } else { + let scan_area = &buf[flushed..]; + let scan_area = &scan_area[..this.buf_writer.capacity()]; + match memchr::memrchr(b'\n', scan_area) { + Some(newline_index) => &scan_area[..newline_index + 1], + None => scan_area, + } + }; + + let buffered = this.buf_writer.as_mut().write_to_buf(tail); + Poll::Ready(Ok(flushed + buffered)) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + let mut this = self.as_mut().project(); + // `is_write_vectored()` is handled in original code, but not in this crate + // see https://github.com/rust-lang/rust/issues/70436 + + let last_newline_buf_idx = bufs + .iter() + .enumerate() + .rev() + .find_map(|(i, buf)| memchr::memchr(b'\n', buf).map(|_| i)); + let last_newline_buf_idx = match last_newline_buf_idx { + None => { + ready!(self.as_mut().flush_if_completed_line(cx)?); + return self.project().buf_writer.poll_write_vectored(cx, bufs); + } + Some(i) => i, + }; + + ready!(this.buf_writer.as_mut().poll_flush(cx)?); + + let (lines, tail) = bufs.split_at(last_newline_buf_idx + 1); + + let flushed = { ready!(this.buf_writer.as_mut().inner_poll_write_vectored(cx, lines))? }; + if flushed == 0 { + return Poll::Ready(Ok(0)); + } + + let lines_len = lines.iter().map(|buf| buf.len()).sum(); + if flushed < lines_len { + return Poll::Ready(Ok(flushed)); + } + + let buffered: usize = tail + .iter() + .filter(|buf| !buf.is_empty()) + .map(|buf| this.buf_writer.as_mut().write_to_buf(buf)) + .take_while(|&n| n > 0) + .sum(); + + Poll::Ready(Ok(flushed + buffered)) + } + + /// Forward to `buf_writer` 's `BufWriter::poll_flush()` + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.as_mut().project().buf_writer.poll_flush(cx) + } + + /// Forward to `buf_writer` 's `BufWriter::poll_close()` + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.as_mut().project().buf_writer.poll_close(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/lines.rs b/utshell-0.5.0/vendor/futures-util/src/io/lines.rs new file mode 100644 index 00000000..b5561bfa --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/lines.rs @@ -0,0 +1,47 @@ +use super::read_line::read_line_internal; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncBufRead; +use pin_project_lite::pin_project; +use std::io; +use std::mem; +use std::pin::Pin; + +pin_project! { + /// Stream for the [`lines`](super::AsyncBufReadExt::lines) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Lines { + #[pin] + reader: R, + buf: String, + bytes: Vec, + read: usize, + } +} + +impl Lines { + pub(super) fn new(reader: R) -> Self { + Self { reader, buf: String::new(), bytes: Vec::new(), read: 0 } + } +} + +impl Stream for Lines { + type Item = io::Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + let n = ready!(read_line_internal(this.reader, cx, this.buf, this.bytes, this.read))?; + if n == 0 && this.buf.is_empty() { + return Poll::Ready(None); + } + if this.buf.ends_with('\n') { + this.buf.pop(); + if this.buf.ends_with('\r') { + this.buf.pop(); + } + } + Poll::Ready(Some(Ok(mem::take(this.buf)))) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/mod.rs b/utshell-0.5.0/vendor/futures-util/src/io/mod.rs new file mode 100644 index 00000000..fdad60b1 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/mod.rs @@ -0,0 +1,841 @@ +//! Asynchronous I/O. +//! +//! This module is the asynchronous version of `std::io`. It defines four +//! traits, [`AsyncRead`], [`AsyncWrite`], [`AsyncSeek`], and [`AsyncBufRead`], +//! which mirror the `Read`, `Write`, `Seek`, and `BufRead` traits of the +//! standard library. However, these traits integrate with the asynchronous +//! task system, so that if an I/O object isn't ready for reading (or writing), +//! the thread is not blocked, and instead the current task is queued to be +//! woken when I/O is ready. +//! +//! In addition, the [`AsyncReadExt`], [`AsyncWriteExt`], [`AsyncSeekExt`], and +//! [`AsyncBufReadExt`] extension traits offer a variety of useful combinators +//! for operating with asynchronous I/O objects, including ways to work with +//! them using futures, streams and sinks. +//! +//! This module is only available when the `std` feature of this +//! library is activated, and it is activated by default. + +#[cfg(feature = "io-compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] +use crate::compat::Compat; +use crate::future::assert_future; +use crate::stream::assert_stream; +use std::{pin::Pin, ptr}; + +// Re-export some types from `std::io` so that users don't have to deal +// with conflicts when `use`ing `futures::io` and `std::io`. +#[doc(no_inline)] +pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom}; + +pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; + +// used by `BufReader` and `BufWriter` +// https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1 +const DEFAULT_BUF_SIZE: usize = 8 * 1024; + +/// Initializes a buffer if necessary. +/// +/// A buffer is currently always initialized. +#[inline] +unsafe fn initialize(_reader: &R, buf: &mut [u8]) { + ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len()) +} + +mod allow_std; +pub use self::allow_std::AllowStdIo; + +mod buf_reader; +pub use self::buf_reader::{BufReader, SeeKRelative}; + +mod buf_writer; +pub use self::buf_writer::BufWriter; + +mod line_writer; +pub use self::line_writer::LineWriter; + +mod chain; +pub use self::chain::Chain; + +mod close; +pub use self::close::Close; + +mod copy; +pub use self::copy::{copy, Copy}; + +mod copy_buf; +pub use self::copy_buf::{copy_buf, CopyBuf}; + +mod copy_buf_abortable; +pub use self::copy_buf_abortable::{copy_buf_abortable, CopyBufAbortable}; + +mod cursor; +pub use self::cursor::Cursor; + +mod empty; +pub use self::empty::{empty, Empty}; + +mod fill_buf; +pub use self::fill_buf::FillBuf; + +mod flush; +pub use self::flush::Flush; + +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +mod into_sink; +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub use self::into_sink::IntoSink; + +mod lines; +pub use self::lines::Lines; + +mod read; +pub use self::read::Read; + +mod read_vectored; +pub use self::read_vectored::ReadVectored; + +mod read_exact; +pub use self::read_exact::ReadExact; + +mod read_line; +pub use self::read_line::ReadLine; + +mod read_to_end; +pub use self::read_to_end::ReadToEnd; + +mod read_to_string; +pub use self::read_to_string::ReadToString; + +mod read_until; +pub use self::read_until::ReadUntil; + +mod repeat; +pub use self::repeat::{repeat, Repeat}; + +mod seek; +pub use self::seek::Seek; + +mod sink; +pub use self::sink::{sink, Sink}; + +mod split; +pub use self::split::{ReadHalf, ReuniteError, WriteHalf}; + +mod take; +pub use self::take::Take; + +mod window; +pub use self::window::Window; + +mod write; +pub use self::write::Write; + +mod write_vectored; +pub use self::write_vectored::WriteVectored; + +mod write_all; +pub use self::write_all::WriteAll; + +#[cfg(feature = "write-all-vectored")] +mod write_all_vectored; +#[cfg(feature = "write-all-vectored")] +pub use self::write_all_vectored::WriteAllVectored; + +/// An extension trait which adds utility methods to `AsyncRead` types. +pub trait AsyncReadExt: AsyncRead { + /// Creates an adaptor which will chain this stream with another. + /// + /// The returned `AsyncRead` instance will first read all bytes from this object + /// until EOF is encountered. Afterwards the output is equivalent to the + /// output of `next`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let reader1 = Cursor::new([1, 2, 3, 4]); + /// let reader2 = Cursor::new([5, 6, 7, 8]); + /// + /// let mut reader = reader1.chain(reader2); + /// let mut buffer = Vec::new(); + /// + /// // read the value into a Vec. + /// reader.read_to_end(&mut buffer).await?; + /// assert_eq!(buffer, [1, 2, 3, 4, 5, 6, 7, 8]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn chain(self, next: R) -> Chain + where + Self: Sized, + R: AsyncRead, + { + assert_read(Chain::new(self, next)) + } + + /// Tries to read some bytes directly into the given `buf` in asynchronous + /// manner, returning a future type. + /// + /// The returned future will resolve to the number of bytes read once the read + /// operation is completed. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let mut reader = Cursor::new([1, 2, 3, 4]); + /// let mut output = [0u8; 5]; + /// + /// let bytes = reader.read(&mut output[..]).await?; + /// + /// // This is only guaranteed to be 4 because `&[u8]` is a synchronous + /// // reader. In a real system you could get anywhere from 1 to + /// // `output.len()` bytes in a single read. + /// assert_eq!(bytes, 4); + /// assert_eq!(output, [1, 2, 3, 4, 0]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(Read::new(self, buf)) + } + + /// Creates a future which will read from the `AsyncRead` into `bufs` using vectored + /// IO operations. + /// + /// The returned future will resolve to the number of bytes read once the read + /// operation is completed. + fn read_vectored<'a>(&'a mut self, bufs: &'a mut [IoSliceMut<'a>]) -> ReadVectored<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(ReadVectored::new(self, bufs)) + } + + /// Creates a future which will read exactly enough bytes to fill `buf`, + /// returning an error if end of file (EOF) is hit sooner. + /// + /// The returned future will resolve once the read operation is completed. + /// + /// In the case of an error the buffer and the object will be discarded, with + /// the error yielded. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let mut reader = Cursor::new([1, 2, 3, 4]); + /// let mut output = [0u8; 4]; + /// + /// reader.read_exact(&mut output).await?; + /// + /// assert_eq!(output, [1, 2, 3, 4]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + /// + /// ## EOF is hit before `buf` is filled + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{self, AsyncReadExt, Cursor}; + /// + /// let mut reader = Cursor::new([1, 2, 3, 4]); + /// let mut output = [0u8; 5]; + /// + /// let result = reader.read_exact(&mut output).await; + /// + /// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof); + /// # }); + /// ``` + fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(ReadExact::new(self, buf)) + } + + /// Creates a future which will read all the bytes from this `AsyncRead`. + /// + /// On success the total number of bytes read is returned. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let mut reader = Cursor::new([1, 2, 3, 4]); + /// let mut output = Vec::with_capacity(4); + /// + /// let bytes = reader.read_to_end(&mut output).await?; + /// + /// assert_eq!(bytes, 4); + /// assert_eq!(output, vec![1, 2, 3, 4]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec) -> ReadToEnd<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(ReadToEnd::new(self, buf)) + } + + /// Creates a future which will read all the bytes from this `AsyncRead`. + /// + /// On success the total number of bytes read is returned. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let mut reader = Cursor::new(&b"1234"[..]); + /// let mut buffer = String::with_capacity(4); + /// + /// let bytes = reader.read_to_string(&mut buffer).await?; + /// + /// assert_eq!(bytes, 4); + /// assert_eq!(buffer, String::from("1234")); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn read_to_string<'a>(&'a mut self, buf: &'a mut String) -> ReadToString<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(ReadToString::new(self, buf)) + } + + /// Helper method for splitting this read/write object into two halves. + /// + /// The two halves returned implement the `AsyncRead` and `AsyncWrite` + /// traits, respectively. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{self, AsyncReadExt, Cursor}; + /// + /// // Note that for `Cursor` the read and write halves share a single + /// // seek position. This may or may not be true for other types that + /// // implement both `AsyncRead` and `AsyncWrite`. + /// + /// let reader = Cursor::new([1, 2, 3, 4]); + /// let mut buffer = Cursor::new(vec![0, 0, 0, 0, 5, 6, 7, 8]); + /// let mut writer = Cursor::new(vec![0u8; 5]); + /// + /// { + /// let (buffer_reader, mut buffer_writer) = (&mut buffer).split(); + /// io::copy(reader, &mut buffer_writer).await?; + /// io::copy(buffer_reader, &mut writer).await?; + /// } + /// + /// assert_eq!(buffer.into_inner(), [1, 2, 3, 4, 5, 6, 7, 8]); + /// assert_eq!(writer.into_inner(), [5, 6, 7, 8, 0]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn split(self) -> (ReadHalf, WriteHalf) + where + Self: AsyncWrite + Sized, + { + let (r, w) = split::split(self); + (assert_read(r), assert_write(w)) + } + + /// Creates an AsyncRead adapter which will read at most `limit` bytes + /// from the underlying reader. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let reader = Cursor::new(&b"12345678"[..]); + /// let mut buffer = [0; 5]; + /// + /// let mut take = reader.take(4); + /// let n = take.read(&mut buffer).await?; + /// + /// assert_eq!(n, 4); + /// assert_eq!(&buffer, b"1234\0"); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn take(self, limit: u64) -> Take + where + Self: Sized, + { + assert_read(Take::new(self, limit)) + } + + /// Wraps an [`AsyncRead`] in a compatibility wrapper that allows it to be + /// used as a futures 0.1 / tokio-io 0.1 `AsyncRead`. If the wrapped type + /// implements [`AsyncWrite`] as well, the result will also implement the + /// futures 0.1 / tokio 0.1 `AsyncWrite` trait. + /// + /// Requires the `io-compat` feature to enable. + #[cfg(feature = "io-compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] + fn compat(self) -> Compat + where + Self: Sized + Unpin, + { + Compat::new(self) + } +} + +impl AsyncReadExt for R {} + +/// An extension trait which adds utility methods to `AsyncWrite` types. +pub trait AsyncWriteExt: AsyncWrite { + /// Creates a future which will entirely flush this `AsyncWrite`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AllowStdIo, AsyncWriteExt}; + /// use std::io::{BufWriter, Cursor}; + /// + /// let mut output = vec![0u8; 5]; + /// + /// { + /// let writer = Cursor::new(&mut output); + /// let mut buffered = AllowStdIo::new(BufWriter::new(writer)); + /// buffered.write_all(&[1, 2]).await?; + /// buffered.write_all(&[3, 4]).await?; + /// buffered.flush().await?; + /// } + /// + /// assert_eq!(output, [1, 2, 3, 4, 0]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn flush(&mut self) -> Flush<'_, Self> + where + Self: Unpin, + { + assert_future::, _>(Flush::new(self)) + } + + /// Creates a future which will entirely close this `AsyncWrite`. + fn close(&mut self) -> Close<'_, Self> + where + Self: Unpin, + { + assert_future::, _>(Close::new(self)) + } + + /// Creates a future which will write bytes from `buf` into the object. + /// + /// The returned future will resolve to the number of bytes written once the write + /// operation is completed. + fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(Write::new(self, buf)) + } + + /// Creates a future which will write bytes from `bufs` into the object using vectored + /// IO operations. + /// + /// The returned future will resolve to the number of bytes written once the write + /// operation is completed. + fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectored<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(WriteVectored::new(self, bufs)) + } + + /// Write data into this object. + /// + /// Creates a future that will write the entire contents of the buffer `buf` into + /// this `AsyncWrite`. + /// + /// The returned future will not complete until all the data has been written. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncWriteExt, Cursor}; + /// + /// let mut writer = Cursor::new(vec![0u8; 5]); + /// + /// writer.write_all(&[1, 2, 3, 4]).await?; + /// + /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(WriteAll::new(self, buf)) + } + + /// Attempts to write multiple buffers into this writer. + /// + /// Creates a future that will write the entire contents of `bufs` into this + /// `AsyncWrite` using [vectored writes]. + /// + /// The returned future will not complete until all the data has been + /// written. + /// + /// [vectored writes]: std::io::Write::write_vectored + /// + /// # Notes + /// + /// Unlike `io::Write::write_vectored`, this takes a *mutable* reference to + /// a slice of `IoSlice`s, not an immutable one. That's because we need to + /// modify the slice to keep track of the bytes already written. + /// + /// Once this futures returns, the contents of `bufs` are unspecified, as + /// this depends on how many calls to `write_vectored` were necessary. It is + /// best to understand this function as taking ownership of `bufs` and to + /// not use `bufs` afterwards. The underlying buffers, to which the + /// `IoSlice`s point (but not the `IoSlice`s themselves), are unchanged and + /// can be reused. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::AsyncWriteExt; + /// use futures_util::io::Cursor; + /// use std::io::IoSlice; + /// + /// let mut writer = Cursor::new(Vec::new()); + /// let bufs = &mut [ + /// IoSlice::new(&[1]), + /// IoSlice::new(&[2, 3]), + /// IoSlice::new(&[4, 5, 6]), + /// ]; + /// + /// writer.write_all_vectored(bufs).await?; + /// // Note: the contents of `bufs` is now unspecified, see the Notes section. + /// + /// assert_eq!(writer.into_inner(), &[1, 2, 3, 4, 5, 6]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + #[cfg(feature = "write-all-vectored")] + fn write_all_vectored<'a>( + &'a mut self, + bufs: &'a mut [IoSlice<'a>], + ) -> WriteAllVectored<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(WriteAllVectored::new(self, bufs)) + } + + /// Wraps an [`AsyncWrite`] in a compatibility wrapper that allows it to be + /// used as a futures 0.1 / tokio-io 0.1 `AsyncWrite`. + /// Requires the `io-compat` feature to enable. + #[cfg(feature = "io-compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] + fn compat_write(self) -> Compat + where + Self: Sized + Unpin, + { + Compat::new(self) + } + + /// Allow using an [`AsyncWrite`] as a [`Sink`](futures_sink::Sink)`>`. + /// + /// This adapter produces a sink that will write each value passed to it + /// into the underlying writer. + /// + /// Note that this function consumes the given writer, returning a wrapped + /// version. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::AsyncWriteExt; + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(vec![Ok([1, 2, 3]), Ok([4, 5, 6])]); + /// + /// let mut writer = vec![]; + /// + /// stream.forward((&mut writer).into_sink()).await?; + /// + /// assert_eq!(writer, vec![1, 2, 3, 4, 5, 6]); + /// # Ok::<(), Box>(()) + /// # })?; + /// # Ok::<(), Box>(()) + /// ``` + #[cfg(feature = "sink")] + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + fn into_sink>(self) -> IntoSink + where + Self: Sized, + { + crate::sink::assert_sink::(IntoSink::new(self)) + } +} + +impl AsyncWriteExt for W {} + +/// An extension trait which adds utility methods to `AsyncSeek` types. +pub trait AsyncSeekExt: AsyncSeek { + /// Creates a future which will seek an IO object, and then yield the + /// new position in the object and the object itself. + /// + /// In the case of an error the buffer and the object will be discarded, with + /// the error yielded. + fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self> + where + Self: Unpin, + { + assert_future::, _>(Seek::new(self, pos)) + } + + /// Creates a future which will return the current seek position from the + /// start of the stream. + /// + /// This is equivalent to `self.seek(SeekFrom::Current(0))`. + fn stream_position(&mut self) -> Seek<'_, Self> + where + Self: Unpin, + { + self.seek(SeekFrom::Current(0)) + } +} + +impl AsyncSeekExt for S {} + +/// An extension trait which adds utility methods to `AsyncBufRead` types. +pub trait AsyncBufReadExt: AsyncBufRead { + /// Creates a future which will wait for a non-empty buffer to be available from this I/O + /// object or EOF to be reached. + /// + /// This method is the async equivalent to [`BufRead::fill_buf`](std::io::BufRead::fill_buf). + /// + /// ```rust + /// # futures::executor::block_on(async { + /// use futures::{io::AsyncBufReadExt as _, stream::{iter, TryStreamExt as _}}; + /// + /// let mut stream = iter(vec![Ok(vec![1, 2, 3]), Ok(vec![4, 5, 6])]).into_async_read(); + /// + /// assert_eq!(stream.fill_buf().await?, vec![1, 2, 3]); + /// stream.consume_unpin(2); + /// + /// assert_eq!(stream.fill_buf().await?, vec![3]); + /// stream.consume_unpin(1); + /// + /// assert_eq!(stream.fill_buf().await?, vec![4, 5, 6]); + /// stream.consume_unpin(3); + /// + /// assert_eq!(stream.fill_buf().await?, vec![]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn fill_buf(&mut self) -> FillBuf<'_, Self> + where + Self: Unpin, + { + assert_future::, _>(FillBuf::new(self)) + } + + /// A convenience for calling [`AsyncBufRead::consume`] on [`Unpin`] IO types. + /// + /// ```rust + /// # futures::executor::block_on(async { + /// use futures::{io::AsyncBufReadExt as _, stream::{iter, TryStreamExt as _}}; + /// + /// let mut stream = iter(vec![Ok(vec![1, 2, 3])]).into_async_read(); + /// + /// assert_eq!(stream.fill_buf().await?, vec![1, 2, 3]); + /// stream.consume_unpin(2); + /// + /// assert_eq!(stream.fill_buf().await?, vec![3]); + /// stream.consume_unpin(1); + /// + /// assert_eq!(stream.fill_buf().await?, vec![]); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn consume_unpin(&mut self, amt: usize) + where + Self: Unpin, + { + Pin::new(self).consume(amt) + } + + /// Creates a future which will read all the bytes associated with this I/O + /// object into `buf` until the delimiter `byte` or EOF is reached. + /// This method is the async equivalent to [`BufRead::read_until`](std::io::BufRead::read_until). + /// + /// This function will read bytes from the underlying stream until the + /// delimiter or EOF is found. Once found, all bytes up to, and including, + /// the delimiter (if found) will be appended to `buf`. + /// + /// The returned future will resolve to the number of bytes read once the read + /// operation is completed. + /// + /// In the case of an error the buffer and the object will be discarded, with + /// the error yielded. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncBufReadExt, Cursor}; + /// + /// let mut cursor = Cursor::new(b"lorem-ipsum"); + /// let mut buf = vec![]; + /// + /// // cursor is at 'l' + /// let num_bytes = cursor.read_until(b'-', &mut buf).await?; + /// assert_eq!(num_bytes, 6); + /// assert_eq!(buf, b"lorem-"); + /// buf.clear(); + /// + /// // cursor is at 'i' + /// let num_bytes = cursor.read_until(b'-', &mut buf).await?; + /// assert_eq!(num_bytes, 5); + /// assert_eq!(buf, b"ipsum"); + /// buf.clear(); + /// + /// // cursor is at EOF + /// let num_bytes = cursor.read_until(b'-', &mut buf).await?; + /// assert_eq!(num_bytes, 0); + /// assert_eq!(buf, b""); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec) -> ReadUntil<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(ReadUntil::new(self, byte, buf)) + } + + /// Creates a future which will read all the bytes associated with this I/O + /// object into `buf` until a newline (the 0xA byte) or EOF is reached, + /// This method is the async equivalent to [`BufRead::read_line`](std::io::BufRead::read_line). + /// + /// This function will read bytes from the underlying stream until the + /// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes + /// up to, and including, the delimiter (if found) will be appended to + /// `buf`. + /// + /// The returned future will resolve to the number of bytes read once the read + /// operation is completed. + /// + /// In the case of an error the buffer and the object will be discarded, with + /// the error yielded. + /// + /// # Errors + /// + /// This function has the same error semantics as [`read_until`] and will + /// also return an error if the read bytes are not valid UTF-8. If an I/O + /// error is encountered then `buf` may contain some bytes already read in + /// the event that all data read so far was valid UTF-8. + /// + /// [`read_until`]: AsyncBufReadExt::read_until + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncBufReadExt, Cursor}; + /// + /// let mut cursor = Cursor::new(b"foo\nbar"); + /// let mut buf = String::new(); + /// + /// // cursor is at 'f' + /// let num_bytes = cursor.read_line(&mut buf).await?; + /// assert_eq!(num_bytes, 4); + /// assert_eq!(buf, "foo\n"); + /// buf.clear(); + /// + /// // cursor is at 'b' + /// let num_bytes = cursor.read_line(&mut buf).await?; + /// assert_eq!(num_bytes, 3); + /// assert_eq!(buf, "bar"); + /// buf.clear(); + /// + /// // cursor is at EOF + /// let num_bytes = cursor.read_line(&mut buf).await?; + /// assert_eq!(num_bytes, 0); + /// assert_eq!(buf, ""); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self> + where + Self: Unpin, + { + assert_future::, _>(ReadLine::new(self, buf)) + } + + /// Returns a stream over the lines of this reader. + /// This method is the async equivalent to [`BufRead::lines`](std::io::BufRead::lines). + /// + /// The stream returned from this function will yield instances of + /// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline + /// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end. + /// + /// [`io::Result`]: std::io::Result + /// [`String`]: String + /// + /// # Errors + /// + /// Each line of the stream has the same error semantics as [`AsyncBufReadExt::read_line`]. + /// + /// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncBufReadExt, Cursor}; + /// use futures::stream::StreamExt; + /// + /// let cursor = Cursor::new(b"lorem\nipsum\xc2\r\ndolor"); + /// + /// let mut lines_stream = cursor.lines().map(|l| l.unwrap_or(String::from("invalid UTF_8"))); + /// assert_eq!(lines_stream.next().await, Some(String::from("lorem"))); + /// assert_eq!(lines_stream.next().await, Some(String::from("invalid UTF_8"))); + /// assert_eq!(lines_stream.next().await, Some(String::from("dolor"))); + /// assert_eq!(lines_stream.next().await, None); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + fn lines(self) -> Lines + where + Self: Sized, + { + assert_stream::, _>(Lines::new(self)) + } +} + +impl AsyncBufReadExt for R {} + +// Just a helper function to ensure the reader we're returning all have the +// right implementations. +pub(crate) fn assert_read(reader: R) -> R +where + R: AsyncRead, +{ + reader +} +// Just a helper function to ensure the writer we're returning all have the +// right implementations. +pub(crate) fn assert_write(writer: W) -> W +where + W: AsyncWrite, +{ + writer +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read.rs b/utshell-0.5.0/vendor/futures-util/src/io/read.rs new file mode 100644 index 00000000..677ba818 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read.rs @@ -0,0 +1,30 @@ +use crate::io::AsyncRead; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use std::io; +use std::pin::Pin; + +/// Future for the [`read`](super::AsyncReadExt::read) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Read<'a, R: ?Sized> { + reader: &'a mut R, + buf: &'a mut [u8], +} + +impl Unpin for Read<'_, R> {} + +impl<'a, R: AsyncRead + ?Sized + Unpin> Read<'a, R> { + pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self { + Self { reader, buf } + } +} + +impl Future for Read<'_, R> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + Pin::new(&mut this.reader).poll_read(cx, this.buf) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read_exact.rs b/utshell-0.5.0/vendor/futures-util/src/io/read_exact.rs new file mode 100644 index 00000000..cd0b20e5 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read_exact.rs @@ -0,0 +1,42 @@ +use crate::io::AsyncRead; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use std::io; +use std::mem; +use std::pin::Pin; + +/// Future for the [`read_exact`](super::AsyncReadExt::read_exact) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReadExact<'a, R: ?Sized> { + reader: &'a mut R, + buf: &'a mut [u8], +} + +impl Unpin for ReadExact<'_, R> {} + +impl<'a, R: AsyncRead + ?Sized + Unpin> ReadExact<'a, R> { + pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self { + Self { reader, buf } + } +} + +impl Future for ReadExact<'_, R> { + type Output = io::Result<()>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + while !this.buf.is_empty() { + let n = ready!(Pin::new(&mut this.reader).poll_read(cx, this.buf))?; + { + let (_, rest) = mem::take(&mut this.buf).split_at_mut(n); + this.buf = rest; + } + if n == 0 { + return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into())); + } + } + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read_line.rs b/utshell-0.5.0/vendor/futures-util/src/io/read_line.rs new file mode 100644 index 00000000..df782c95 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read_line.rs @@ -0,0 +1,58 @@ +use super::read_until::read_until_internal; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncBufRead; +use std::io; +use std::mem; +use std::pin::Pin; +use std::str; + +/// Future for the [`read_line`](super::AsyncBufReadExt::read_line) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReadLine<'a, R: ?Sized> { + reader: &'a mut R, + buf: &'a mut String, + bytes: Vec, + read: usize, +} + +impl Unpin for ReadLine<'_, R> {} + +impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadLine<'a, R> { + pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self { + Self { reader, bytes: mem::take(buf).into_bytes(), buf, read: 0 } + } +} + +pub(super) fn read_line_internal( + reader: Pin<&mut R>, + cx: &mut Context<'_>, + buf: &mut String, + bytes: &mut Vec, + read: &mut usize, +) -> Poll> { + let ret = ready!(read_until_internal(reader, cx, b'\n', bytes, read)); + if str::from_utf8(bytes).is_err() { + bytes.clear(); + Poll::Ready(ret.and_then(|_| { + Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8")) + })) + } else { + debug_assert!(buf.is_empty()); + debug_assert_eq!(*read, 0); + // Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`. + mem::swap(unsafe { buf.as_mut_vec() }, bytes); + Poll::Ready(ret) + } +} + +impl Future for ReadLine<'_, R> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let Self { reader, buf, bytes, read } = &mut *self; + read_line_internal(Pin::new(reader), cx, buf, bytes, read) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read_to_end.rs b/utshell-0.5.0/vendor/futures-util/src/io/read_to_end.rs new file mode 100644 index 00000000..919d7d13 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read_to_end.rs @@ -0,0 +1,91 @@ +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncRead; +use std::io; +use std::pin::Pin; +use std::vec::Vec; + +/// Future for the [`read_to_end`](super::AsyncReadExt::read_to_end) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReadToEnd<'a, R: ?Sized> { + reader: &'a mut R, + buf: &'a mut Vec, + start_len: usize, +} + +impl Unpin for ReadToEnd<'_, R> {} + +impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToEnd<'a, R> { + pub(super) fn new(reader: &'a mut R, buf: &'a mut Vec) -> Self { + let start_len = buf.len(); + Self { reader, buf, start_len } + } +} + +struct Guard<'a> { + buf: &'a mut Vec, + len: usize, +} + +impl Drop for Guard<'_> { + fn drop(&mut self) { + unsafe { + self.buf.set_len(self.len); + } + } +} + +// This uses an adaptive system to extend the vector when it fills. We want to +// avoid paying to allocate and zero a huge chunk of memory if the reader only +// has 4 bytes while still making large reads if the reader does have a ton +// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every +// time is 4,500 times (!) slower than this if the reader has a very small +// amount of data to return. +// +// Because we're extending the buffer with uninitialized data for trusted +// readers, we need to make sure to truncate that if any of this panics. +pub(super) fn read_to_end_internal( + mut rd: Pin<&mut R>, + cx: &mut Context<'_>, + buf: &mut Vec, + start_len: usize, +) -> Poll> { + let mut g = Guard { len: buf.len(), buf }; + loop { + if g.len == g.buf.len() { + unsafe { + g.buf.reserve(32); + let capacity = g.buf.capacity(); + g.buf.set_len(capacity); + super::initialize(&rd, &mut g.buf[g.len..]); + } + } + + let buf = &mut g.buf[g.len..]; + match ready!(rd.as_mut().poll_read(cx, buf)) { + Ok(0) => return Poll::Ready(Ok(g.len - start_len)), + Ok(n) => { + // We can't allow bogus values from read. If it is too large, the returned vec could have its length + // set past its capacity, or if it overflows the vec could be shortened which could create an invalid + // string if this is called via read_to_string. + assert!(n <= buf.len()); + g.len += n; + } + Err(e) => return Poll::Ready(Err(e)), + } + } +} + +impl Future for ReadToEnd<'_, A> +where + A: AsyncRead + ?Sized + Unpin, +{ + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + read_to_end_internal(Pin::new(&mut this.reader), cx, this.buf, this.start_len) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read_to_string.rs b/utshell-0.5.0/vendor/futures-util/src/io/read_to_string.rs new file mode 100644 index 00000000..c175396d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read_to_string.rs @@ -0,0 +1,59 @@ +use super::read_to_end::read_to_end_internal; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncRead; +use std::pin::Pin; +use std::vec::Vec; +use std::{io, mem, str}; + +/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReadToString<'a, R: ?Sized> { + reader: &'a mut R, + buf: &'a mut String, + bytes: Vec, + start_len: usize, +} + +impl Unpin for ReadToString<'_, R> {} + +impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToString<'a, R> { + pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self { + let start_len = buf.len(); + Self { reader, bytes: mem::take(buf).into_bytes(), buf, start_len } + } +} + +fn read_to_string_internal( + reader: Pin<&mut R>, + cx: &mut Context<'_>, + buf: &mut String, + bytes: &mut Vec, + start_len: usize, +) -> Poll> { + let ret = ready!(read_to_end_internal(reader, cx, bytes, start_len)); + if str::from_utf8(bytes).is_err() { + Poll::Ready(ret.and_then(|_| { + Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8")) + })) + } else { + debug_assert!(buf.is_empty()); + // Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`. + mem::swap(unsafe { buf.as_mut_vec() }, bytes); + Poll::Ready(ret) + } +} + +impl Future for ReadToString<'_, A> +where + A: AsyncRead + ?Sized + Unpin, +{ + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let Self { reader, buf, bytes, start_len } = &mut *self; + read_to_string_internal(Pin::new(reader), cx, buf, bytes, *start_len) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read_until.rs b/utshell-0.5.0/vendor/futures-util/src/io/read_until.rs new file mode 100644 index 00000000..72b59eab --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read_until.rs @@ -0,0 +1,60 @@ +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncBufRead; +use std::io; +use std::mem; +use std::pin::Pin; + +/// Future for the [`read_until`](super::AsyncBufReadExt::read_until) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReadUntil<'a, R: ?Sized> { + reader: &'a mut R, + byte: u8, + buf: &'a mut Vec, + read: usize, +} + +impl Unpin for ReadUntil<'_, R> {} + +impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadUntil<'a, R> { + pub(super) fn new(reader: &'a mut R, byte: u8, buf: &'a mut Vec) -> Self { + Self { reader, byte, buf, read: 0 } + } +} + +pub(super) fn read_until_internal( + mut reader: Pin<&mut R>, + cx: &mut Context<'_>, + byte: u8, + buf: &mut Vec, + read: &mut usize, +) -> Poll> { + loop { + let (done, used) = { + let available = ready!(reader.as_mut().poll_fill_buf(cx))?; + if let Some(i) = memchr::memchr(byte, available) { + buf.extend_from_slice(&available[..=i]); + (true, i + 1) + } else { + buf.extend_from_slice(available); + (false, available.len()) + } + }; + reader.as_mut().consume(used); + *read += used; + if done || used == 0 { + return Poll::Ready(Ok(mem::replace(read, 0))); + } + } +} + +impl Future for ReadUntil<'_, R> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let Self { reader, byte, buf, read } = &mut *self; + read_until_internal(Pin::new(reader), cx, *byte, buf, read) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/read_vectored.rs b/utshell-0.5.0/vendor/futures-util/src/io/read_vectored.rs new file mode 100644 index 00000000..4e22df57 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/read_vectored.rs @@ -0,0 +1,30 @@ +use crate::io::AsyncRead; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use std::io::{self, IoSliceMut}; +use std::pin::Pin; + +/// Future for the [`read_vectored`](super::AsyncReadExt::read_vectored) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct ReadVectored<'a, R: ?Sized> { + reader: &'a mut R, + bufs: &'a mut [IoSliceMut<'a>], +} + +impl Unpin for ReadVectored<'_, R> {} + +impl<'a, R: AsyncRead + ?Sized + Unpin> ReadVectored<'a, R> { + pub(super) fn new(reader: &'a mut R, bufs: &'a mut [IoSliceMut<'a>]) -> Self { + Self { reader, bufs } + } +} + +impl Future for ReadVectored<'_, R> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + Pin::new(&mut this.reader).poll_read_vectored(cx, this.bufs) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/repeat.rs b/utshell-0.5.0/vendor/futures-util/src/io/repeat.rs new file mode 100644 index 00000000..2828bf01 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/repeat.rs @@ -0,0 +1,66 @@ +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncRead, IoSliceMut}; +use std::fmt; +use std::io; +use std::pin::Pin; + +/// Reader for the [`repeat()`] function. +#[must_use = "readers do nothing unless polled"] +pub struct Repeat { + byte: u8, +} + +/// Creates an instance of a reader that infinitely repeats one byte. +/// +/// All reads from this reader will succeed by filling the specified buffer with +/// the given byte. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncReadExt}; +/// +/// let mut buffer = [0; 3]; +/// let mut reader = io::repeat(0b101); +/// reader.read_exact(&mut buffer).await.unwrap(); +/// assert_eq!(buffer, [0b101, 0b101, 0b101]); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn repeat(byte: u8) -> Repeat { + Repeat { byte } +} + +impl AsyncRead for Repeat { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + for slot in &mut *buf { + *slot = self.byte; + } + Poll::Ready(Ok(buf.len())) + } + + #[inline] + fn poll_read_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + let mut nwritten = 0; + for buf in bufs { + nwritten += ready!(self.as_mut().poll_read(cx, buf))?; + } + Poll::Ready(Ok(nwritten)) + } +} + +impl fmt::Debug for Repeat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("Repeat { .. }") + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/seek.rs b/utshell-0.5.0/vendor/futures-util/src/io/seek.rs new file mode 100644 index 00000000..0aa23713 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/seek.rs @@ -0,0 +1,30 @@ +use crate::io::{AsyncSeek, SeekFrom}; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use std::io; +use std::pin::Pin; + +/// Future for the [`seek`](crate::io::AsyncSeekExt::seek) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Seek<'a, S: ?Sized> { + seek: &'a mut S, + pos: SeekFrom, +} + +impl Unpin for Seek<'_, S> {} + +impl<'a, S: AsyncSeek + ?Sized + Unpin> Seek<'a, S> { + pub(super) fn new(seek: &'a mut S, pos: SeekFrom) -> Self { + Self { seek, pos } + } +} + +impl Future for Seek<'_, S> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + Pin::new(&mut this.seek).poll_seek(cx, this.pos) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/sink.rs b/utshell-0.5.0/vendor/futures-util/src/io/sink.rs new file mode 100644 index 00000000..4a32ca70 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/sink.rs @@ -0,0 +1,67 @@ +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncWrite, IoSlice}; +use std::fmt; +use std::io; +use std::pin::Pin; + +/// Writer for the [`sink()`] function. +#[must_use = "writers do nothing unless polled"] +pub struct Sink { + _priv: (), +} + +/// Creates an instance of a writer which will successfully consume all data. +/// +/// All calls to `poll_write` on the returned instance will return `Poll::Ready(Ok(buf.len()))` +/// and the contents of the buffer will not be inspected. +/// +/// # Examples +/// +/// ```rust +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncWriteExt}; +/// +/// let buffer = vec![1, 2, 3, 5, 8]; +/// let mut writer = io::sink(); +/// let num_bytes = writer.write(&buffer).await?; +/// assert_eq!(num_bytes, 5); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn sink() -> Sink { + Sink { _priv: () } +} + +impl AsyncWrite for Sink { + #[inline] + fn poll_write( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Poll::Ready(Ok(buf.len())) + } + + #[inline] + fn poll_write_vectored( + self: Pin<&mut Self>, + _: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Poll::Ready(Ok(bufs.iter().map(|b| b.len()).sum())) + } + + #[inline] + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + #[inline] + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } +} + +impl fmt::Debug for Sink { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("Sink { .. }") + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/split.rs b/utshell-0.5.0/vendor/futures-util/src/io/split.rs new file mode 100644 index 00000000..81d1e6dc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/split.rs @@ -0,0 +1,129 @@ +use crate::lock::BiLock; +use core::fmt; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncRead, AsyncWrite, IoSlice, IoSliceMut}; +use std::io; +use std::pin::Pin; + +/// The readable half of an object returned from `AsyncRead::split`. +#[derive(Debug)] +pub struct ReadHalf { + handle: BiLock, +} + +/// The writable half of an object returned from `AsyncRead::split`. +#[derive(Debug)] +pub struct WriteHalf { + handle: BiLock, +} + +fn lock_and_then(lock: &BiLock, cx: &mut Context<'_>, f: F) -> Poll> +where + F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> Poll>, +{ + let mut l = ready!(lock.poll_lock(cx)); + f(l.as_pin_mut(), cx) +} + +pub(super) fn split(t: T) -> (ReadHalf, WriteHalf) { + let (a, b) = BiLock::new(t); + (ReadHalf { handle: a }, WriteHalf { handle: b }) +} + +impl ReadHalf { + /// Checks if this `ReadHalf` and some `WriteHalf` were split from the same stream. + pub fn is_pair_of(&self, other: &WriteHalf) -> bool { + self.handle.is_pair_of(&other.handle) + } +} + +impl ReadHalf { + /// Attempts to put the two "halves" of a split `AsyncRead + AsyncWrite` back + /// together. Succeeds only if the `ReadHalf` and `WriteHalf` are + /// a matching pair originating from the same call to `AsyncReadExt::split`. + pub fn reunite(self, other: WriteHalf) -> Result> { + self.handle + .reunite(other.handle) + .map_err(|err| ReuniteError(ReadHalf { handle: err.0 }, WriteHalf { handle: err.1 })) + } +} + +impl WriteHalf { + /// Checks if this `WriteHalf` and some `ReadHalf` were split from the same stream. + pub fn is_pair_of(&self, other: &ReadHalf) -> bool { + self.handle.is_pair_of(&other.handle) + } +} + +impl WriteHalf { + /// Attempts to put the two "halves" of a split `AsyncRead + AsyncWrite` back + /// together. Succeeds only if the `ReadHalf` and `WriteHalf` are + /// a matching pair originating from the same call to `AsyncReadExt::split`. + pub fn reunite(self, other: ReadHalf) -> Result> { + other.reunite(self) + } +} + +impl AsyncRead for ReadHalf { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + lock_and_then(&self.handle, cx, |l, cx| l.poll_read(cx, buf)) + } + + fn poll_read_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + lock_and_then(&self.handle, cx, |l, cx| l.poll_read_vectored(cx, bufs)) + } +} + +impl AsyncWrite for WriteHalf { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + lock_and_then(&self.handle, cx, |l, cx| l.poll_write(cx, buf)) + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + lock_and_then(&self.handle, cx, |l, cx| l.poll_write_vectored(cx, bufs)) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + lock_and_then(&self.handle, cx, |l, cx| l.poll_flush(cx)) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + lock_and_then(&self.handle, cx, |l, cx| l.poll_close(cx)) + } +} + +/// Error indicating a `ReadHalf` and `WriteHalf` were not two halves +/// of a `AsyncRead + AsyncWrite`, and thus could not be `reunite`d. +pub struct ReuniteError(pub ReadHalf, pub WriteHalf); + +impl fmt::Debug for ReuniteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("ReuniteError").field(&"...").finish() + } +} + +impl fmt::Display for ReuniteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "tried to reunite a ReadHalf and WriteHalf that don't form a pair") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ReuniteError {} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/take.rs b/utshell-0.5.0/vendor/futures-util/src/io/take.rs new file mode 100644 index 00000000..2c494804 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/take.rs @@ -0,0 +1,125 @@ +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead}; +use pin_project_lite::pin_project; +use std::pin::Pin; +use std::{cmp, io}; + +pin_project! { + /// Reader for the [`take`](super::AsyncReadExt::take) method. + #[derive(Debug)] + #[must_use = "readers do nothing unless you `.await` or poll them"] + pub struct Take { + #[pin] + inner: R, + limit: u64, + } +} + +impl Take { + pub(super) fn new(inner: R, limit: u64) -> Self { + Self { inner, limit } + } + + /// Returns the remaining number of bytes that can be + /// read before this instance will return EOF. + /// + /// # Note + /// + /// This instance may reach `EOF` after reading fewer bytes than indicated by + /// this method if the underlying [`AsyncRead`] instance reaches EOF. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let reader = Cursor::new(&b"12345678"[..]); + /// let mut buffer = [0; 2]; + /// + /// let mut take = reader.take(4); + /// let n = take.read(&mut buffer).await?; + /// + /// assert_eq!(take.limit(), 2); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + pub fn limit(&self) -> u64 { + self.limit + } + + /// Sets the number of bytes that can be read before this instance will + /// return EOF. This is the same as constructing a new `Take` instance, so + /// the amount of bytes read and the previous limit value don't matter when + /// calling this method. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::io::{AsyncReadExt, Cursor}; + /// + /// let reader = Cursor::new(&b"12345678"[..]); + /// let mut buffer = [0; 4]; + /// + /// let mut take = reader.take(4); + /// let n = take.read(&mut buffer).await?; + /// + /// assert_eq!(n, 4); + /// assert_eq!(take.limit(), 0); + /// + /// take.set_limit(10); + /// let n = take.read(&mut buffer).await?; + /// assert_eq!(n, 4); + /// + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + pub fn set_limit(&mut self, limit: u64) { + self.limit = limit + } + + delegate_access_inner!(inner, R, ()); +} + +impl AsyncRead for Take { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + let this = self.project(); + + if *this.limit == 0 { + return Poll::Ready(Ok(0)); + } + + let max = cmp::min(buf.len() as u64, *this.limit) as usize; + let n = ready!(this.inner.poll_read(cx, &mut buf[..max]))?; + *this.limit -= n as u64; + Poll::Ready(Ok(n)) + } +} + +impl AsyncBufRead for Take { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + // Don't call into inner reader at all at EOF because it may still block + if *this.limit == 0 { + return Poll::Ready(Ok(&[])); + } + + let buf = ready!(this.inner.poll_fill_buf(cx)?); + let cap = cmp::min(buf.len() as u64, *this.limit) as usize; + Poll::Ready(Ok(&buf[..cap])) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + let this = self.project(); + + // Don't let callers reset the limit by passing an overlarge value + let amt = cmp::min(amt as u64, *this.limit) as usize; + *this.limit -= amt as u64; + this.inner.consume(amt); + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/window.rs b/utshell-0.5.0/vendor/futures-util/src/io/window.rs new file mode 100644 index 00000000..d8572823 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/window.rs @@ -0,0 +1,104 @@ +use std::ops::{Bound, Range, RangeBounds}; + +/// An owned window around an underlying buffer. +/// +/// Normally slices work great for considering sub-portions of a buffer, but +/// unfortunately a slice is a *borrowed* type in Rust which has an associated +/// lifetime. When working with future and async I/O these lifetimes are not +/// always appropriate, and are sometimes difficult to store in tasks. This +/// type strives to fill this gap by providing an "owned slice" around an +/// underlying buffer of bytes. +/// +/// A `Window` wraps an underlying buffer, `T`, and has configurable +/// start/end indexes to alter the behavior of the `AsRef<[u8]>` implementation +/// that this type carries. +/// +/// This type can be particularly useful when working with the `write_all` +/// combinator in this crate. Data can be sliced via `Window`, consumed by +/// `write_all`, and then earned back once the write operation finishes through +/// the `into_inner` method on this type. +#[derive(Debug)] +pub struct Window { + inner: T, + range: Range, +} + +impl> Window { + /// Creates a new window around the buffer `t` defaulting to the entire + /// slice. + /// + /// Further methods can be called on the returned `Window` to alter the + /// window into the data provided. + pub fn new(t: T) -> Self { + Self { range: 0..t.as_ref().len(), inner: t } + } + + /// Gets a shared reference to the underlying buffer inside of this + /// `Window`. + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying buffer inside of this + /// `Window`. + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Consumes this `Window`, returning the underlying buffer. + pub fn into_inner(self) -> T { + self.inner + } + + /// Returns the starting index of this window into the underlying buffer + /// `T`. + pub fn start(&self) -> usize { + self.range.start + } + + /// Returns the end index of this window into the underlying buffer + /// `T`. + pub fn end(&self) -> usize { + self.range.end + } + + /// Changes the range of this window to the range specified. + /// + /// # Panics + /// + /// This method will panic if `range` is out of bounds for the underlying + /// slice or if [`start_bound()`] of `range` comes after the [`end_bound()`]. + /// + /// [`start_bound()`]: std::ops::RangeBounds::start_bound + /// [`end_bound()`]: std::ops::RangeBounds::end_bound + pub fn set>(&mut self, range: R) { + let start = match range.start_bound() { + Bound::Included(n) => *n, + Bound::Excluded(n) => *n + 1, + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(n) => *n + 1, + Bound::Excluded(n) => *n, + Bound::Unbounded => self.inner.as_ref().len(), + }; + + assert!(end <= self.inner.as_ref().len()); + assert!(start <= end); + + self.range.start = start; + self.range.end = end; + } +} + +impl> AsRef<[u8]> for Window { + fn as_ref(&self) -> &[u8] { + &self.inner.as_ref()[self.range.start..self.range.end] + } +} + +impl> AsMut<[u8]> for Window { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.inner.as_mut()[self.range.start..self.range.end] + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/write.rs b/utshell-0.5.0/vendor/futures-util/src/io/write.rs new file mode 100644 index 00000000..c47ef9e2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/write.rs @@ -0,0 +1,30 @@ +use crate::io::AsyncWrite; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use std::io; +use std::pin::Pin; + +/// Future for the [`write`](super::AsyncWriteExt::write) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Write<'a, W: ?Sized> { + writer: &'a mut W, + buf: &'a [u8], +} + +impl Unpin for Write<'_, W> {} + +impl<'a, W: AsyncWrite + ?Sized + Unpin> Write<'a, W> { + pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self { + Self { writer, buf } + } +} + +impl Future for Write<'_, W> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + Pin::new(&mut this.writer).poll_write(cx, this.buf) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/write_all.rs b/utshell-0.5.0/vendor/futures-util/src/io/write_all.rs new file mode 100644 index 00000000..08c025f9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/write_all.rs @@ -0,0 +1,43 @@ +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncWrite; +use std::io; +use std::mem; +use std::pin::Pin; + +/// Future for the [`write_all`](super::AsyncWriteExt::write_all) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct WriteAll<'a, W: ?Sized> { + writer: &'a mut W, + buf: &'a [u8], +} + +impl Unpin for WriteAll<'_, W> {} + +impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAll<'a, W> { + pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self { + Self { writer, buf } + } +} + +impl Future for WriteAll<'_, W> { + type Output = io::Result<()>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = &mut *self; + while !this.buf.is_empty() { + let n = ready!(Pin::new(&mut this.writer).poll_write(cx, this.buf))?; + { + let (_, rest) = mem::take(&mut this.buf).split_at(n); + this.buf = rest; + } + if n == 0 { + return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); + } + } + + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/write_all_vectored.rs b/utshell-0.5.0/vendor/futures-util/src/io/write_all_vectored.rs new file mode 100644 index 00000000..a8fc4c64 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/write_all_vectored.rs @@ -0,0 +1,193 @@ +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_io::AsyncWrite; +use futures_io::IoSlice; +use std::io; +use std::pin::Pin; + +/// Future for the +/// [`write_all_vectored`](super::AsyncWriteExt::write_all_vectored) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct WriteAllVectored<'a, W: ?Sized + Unpin> { + writer: &'a mut W, + bufs: &'a mut [IoSlice<'a>], +} + +impl Unpin for WriteAllVectored<'_, W> {} + +impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAllVectored<'a, W> { + pub(super) fn new(writer: &'a mut W, mut bufs: &'a mut [IoSlice<'a>]) -> Self { + IoSlice::advance_slices(&mut bufs, 0); + Self { writer, bufs } + } +} + +impl Future for WriteAllVectored<'_, W> { + type Output = io::Result<()>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = &mut *self; + while !this.bufs.is_empty() { + let n = ready!(Pin::new(&mut this.writer).poll_write_vectored(cx, this.bufs))?; + if n == 0 { + return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); + } else { + IoSlice::advance_slices(&mut this.bufs, n); + } + } + + Poll::Ready(Ok(())) + } +} + +#[cfg(test)] +mod tests { + use std::cmp::min; + use std::future::Future; + use std::io; + use std::pin::Pin; + use std::task::{Context, Poll}; + + use crate::io::{AsyncWrite, AsyncWriteExt, IoSlice}; + use crate::task::noop_waker; + + /// Create a new writer that reads from at most `n_bufs` and reads + /// `per_call` bytes (in total) per call to write. + fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter { + TestWriter { n_bufs, per_call, written: Vec::new() } + } + + // TODO: maybe move this the future-test crate? + struct TestWriter { + n_bufs: usize, + per_call: usize, + written: Vec, + } + + impl AsyncWrite for TestWriter { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + self.poll_write_vectored(cx, &[IoSlice::new(buf)]) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + _cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + let mut left = self.per_call; + let mut written = 0; + for buf in bufs.iter().take(self.n_bufs) { + let n = min(left, buf.len()); + self.written.extend_from_slice(&buf[0..n]); + left -= n; + written += n; + } + Poll::Ready(Ok(written)) + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + } + + // TODO: maybe move this the future-test crate? + macro_rules! assert_poll_ok { + ($e:expr, $expected:expr) => { + let expected = $expected; + match $e { + Poll::Ready(Ok(ok)) if ok == expected => {} + got => { + panic!("unexpected result, got: {:?}, wanted: Ready(Ok({:?}))", got, expected) + } + } + }; + } + + #[test] + fn test_writer_read_from_one_buf() { + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + let mut dst = test_writer(1, 2); + let mut dst = Pin::new(&mut dst); + + assert_poll_ok!(dst.as_mut().poll_write(&mut cx, &[]), 0); + assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, &[]), 0); + + // Read at most 2 bytes. + assert_poll_ok!(dst.as_mut().poll_write(&mut cx, &[1, 1, 1]), 2); + let bufs = &[IoSlice::new(&[2, 2, 2])]; + assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 2); + + // Only read from first buf. + let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])]; + assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 1); + + assert_eq!(dst.written, &[1, 1, 2, 2, 3]); + } + + #[test] + fn test_writer_read_from_multiple_bufs() { + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + let mut dst = test_writer(3, 3); + let mut dst = Pin::new(&mut dst); + + // Read at most 3 bytes from two buffers. + let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; + assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3); + + // Read at most 3 bytes from three buffers. + let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; + assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3); + + assert_eq!(dst.written, &[1, 2, 2, 3, 4, 5]); + } + + #[test] + fn test_write_all_vectored() { + let waker = noop_waker(); + let mut cx = Context::from_waker(&waker); + + #[rustfmt::skip] // Becomes unreadable otherwise. + let tests: Vec<(_, &'static [u8])> = vec![ + (vec![], &[]), + (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), + (vec![IoSlice::new(&[1])], &[1]), + (vec![IoSlice::new(&[1, 2])], &[1, 2]), + (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), + (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), + (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), + (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), + (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), + (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), + (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), + (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), + (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), + (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), + ]; + + for (mut input, wanted) in tests { + let mut dst = test_writer(2, 2); + { + let mut future = dst.write_all_vectored(&mut *input); + match Pin::new(&mut future).poll(&mut cx) { + Poll::Ready(Ok(())) => {} + other => panic!("unexpected result polling future: {:?}", other), + } + } + assert_eq!(&*dst.written, &*wanted); + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/io/write_vectored.rs b/utshell-0.5.0/vendor/futures-util/src/io/write_vectored.rs new file mode 100644 index 00000000..14a01d73 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/io/write_vectored.rs @@ -0,0 +1,30 @@ +use crate::io::AsyncWrite; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use std::io::{self, IoSlice}; +use std::pin::Pin; + +/// Future for the [`write_vectored`](super::AsyncWriteExt::write_vectored) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct WriteVectored<'a, W: ?Sized> { + writer: &'a mut W, + bufs: &'a [IoSlice<'a>], +} + +impl Unpin for WriteVectored<'_, W> {} + +impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteVectored<'a, W> { + pub(super) fn new(writer: &'a mut W, bufs: &'a [IoSlice<'a>]) -> Self { + Self { writer, bufs } + } +} + +impl Future for WriteVectored<'_, W> { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + Pin::new(&mut this.writer).poll_write_vectored(cx, this.bufs) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/lib.rs b/utshell-0.5.0/vendor/futures-util/src/lib.rs new file mode 100644 index 00000000..208eb73a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/lib.rs @@ -0,0 +1,337 @@ +//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s, +//! and the `AsyncRead` and `AsyncWrite` traits. + +#![cfg_attr(feature = "write-all-vectored", feature(io_slice_advance))] +#![cfg_attr(not(feature = "std"), no_std)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + single_use_lifetimes, + unreachable_pub +)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] +#![cfg_attr(docsrs, feature(doc_cfg))] + +#[cfg(all(feature = "bilock", not(feature = "unstable")))] +compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); + +#[cfg(feature = "alloc")] +extern crate alloc; + +// Macro re-exports +pub use futures_core::ready; +pub use pin_utils::pin_mut; + +#[cfg(feature = "async-await")] +#[macro_use] +mod async_await; +#[cfg(feature = "async-await")] +#[doc(hidden)] +pub use self::async_await::*; + +// Not public API. +#[cfg(feature = "async-await")] +#[doc(hidden)] +pub mod __private { + pub use crate::*; + pub use core::{ + option::Option::{self, None, Some}, + pin::Pin, + result::Result::{Err, Ok}, + }; + + pub mod async_await { + pub use crate::async_await::*; + } +} + +#[cfg(feature = "sink")] +macro_rules! delegate_sink { + ($field:ident, $item:ty) => { + fn poll_ready( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_ready(cx) + } + + fn start_send(self: core::pin::Pin<&mut Self>, item: $item) -> Result<(), Self::Error> { + self.project().$field.start_send(item) + } + + fn poll_flush( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_flush(cx) + } + + fn poll_close( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_close(cx) + } + }; +} + +macro_rules! delegate_future { + ($field:ident) => { + fn poll( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll { + self.project().$field.poll(cx) + } + }; +} + +macro_rules! delegate_stream { + ($field:ident) => { + fn poll_next( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_next(cx) + } + fn size_hint(&self) -> (usize, Option) { + self.$field.size_hint() + } + }; +} + +#[cfg(feature = "io")] +#[cfg(feature = "std")] +macro_rules! delegate_async_write { + ($field:ident) => { + fn poll_write( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + buf: &[u8], + ) -> core::task::Poll> { + self.project().$field.poll_write(cx, buf) + } + fn poll_write_vectored( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + bufs: &[std::io::IoSlice<'_>], + ) -> core::task::Poll> { + self.project().$field.poll_write_vectored(cx, bufs) + } + fn poll_flush( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_flush(cx) + } + fn poll_close( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_close(cx) + } + }; +} + +#[cfg(feature = "io")] +#[cfg(feature = "std")] +macro_rules! delegate_async_read { + ($field:ident) => { + fn poll_read( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + buf: &mut [u8], + ) -> core::task::Poll> { + self.project().$field.poll_read(cx, buf) + } + + fn poll_read_vectored( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + bufs: &mut [std::io::IoSliceMut<'_>], + ) -> core::task::Poll> { + self.project().$field.poll_read_vectored(cx, bufs) + } + }; +} + +#[cfg(feature = "io")] +#[cfg(feature = "std")] +macro_rules! delegate_async_buf_read { + ($field:ident) => { + fn poll_fill_buf( + self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll> { + self.project().$field.poll_fill_buf(cx) + } + + fn consume(self: core::pin::Pin<&mut Self>, amt: usize) { + self.project().$field.consume(amt) + } + }; +} + +macro_rules! delegate_access_inner { + ($field:ident, $inner:ty, ($($ind:tt)*)) => { + /// Acquires a reference to the underlying sink or stream that this combinator is + /// pulling from. + pub fn get_ref(&self) -> &$inner { + (&self.$field) $($ind get_ref())* + } + + /// Acquires a mutable reference to the underlying sink or stream that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// sink or stream which may otherwise confuse this combinator. + pub fn get_mut(&mut self) -> &mut $inner { + (&mut self.$field) $($ind get_mut())* + } + + /// Acquires a pinned mutable reference to the underlying sink or stream that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// sink or stream which may otherwise confuse this combinator. + pub fn get_pin_mut(self: core::pin::Pin<&mut Self>) -> core::pin::Pin<&mut $inner> { + self.project().$field $($ind get_pin_mut())* + } + + /// Consumes this combinator, returning the underlying sink or stream. + /// + /// Note that this may discard intermediate state of this combinator, so + /// care should be taken to avoid losing resources when this is called. + pub fn into_inner(self) -> $inner { + self.$field $($ind into_inner())* + } + } +} + +macro_rules! delegate_all { + (@trait Future $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> futures_core::future::Future for $name<$($arg),*> where $t: futures_core::future::Future $(, $($bound)*)* { + type Output = <$t as futures_core::future::Future>::Output; + + delegate_future!(inner); + } + }; + (@trait FusedFuture $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> futures_core::future::FusedFuture for $name<$($arg),*> where $t: futures_core::future::FusedFuture $(, $($bound)*)* { + fn is_terminated(&self) -> bool { + self.inner.is_terminated() + } + } + }; + (@trait Stream $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> futures_core::stream::Stream for $name<$($arg),*> where $t: futures_core::stream::Stream $(, $($bound)*)* { + type Item = <$t as futures_core::stream::Stream>::Item; + + delegate_stream!(inner); + } + }; + (@trait FusedStream $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> futures_core::stream::FusedStream for $name<$($arg),*> where $t: futures_core::stream::FusedStream $(, $($bound)*)* { + fn is_terminated(&self) -> bool { + self.inner.is_terminated() + } + } + }; + (@trait Sink $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + #[cfg(feature = "sink")] + impl<_Item, $($arg),*> futures_sink::Sink<_Item> for $name<$($arg),*> where $t: futures_sink::Sink<_Item> $(, $($bound)*)* { + type Error = <$t as futures_sink::Sink<_Item>>::Error; + + delegate_sink!(inner, _Item); + } + }; + (@trait Debug $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> core::fmt::Debug for $name<$($arg),*> where $t: core::fmt::Debug $(, $($bound)*)* { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Debug::fmt(&self.inner, f) + } + } + }; + (@trait AccessInner[$inner:ty, ($($ind:tt)*)] $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> $name<$($arg),*> $(where $($bound)*)* { + delegate_access_inner!(inner, $inner, ($($ind)*)); + } + }; + (@trait New[|$($param:ident: $paramt:ty),*| $cons:expr] $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { + impl<$($arg),*> $name<$($arg),*> $(where $($bound)*)* { + pub(crate) fn new($($param: $paramt),*) -> Self { + Self { inner: $cons } + } + } + }; + ($(#[$attr:meta])* $name:ident<$($arg:ident),*>($t:ty) : $ftrait:ident $([$($targs:tt)*])* $({$($item:tt)*})* $(where $($bound:tt)*)*) => { + pin_project_lite::pin_project! { + #[must_use = "futures/streams/sinks do nothing unless you `.await` or poll them"] + $(#[$attr])* + pub struct $name< $($arg),* > $(where $($bound)*)* { #[pin] inner: $t } + } + + impl<$($arg),*> $name< $($arg),* > $(where $($bound)*)* { + $($($item)*)* + } + + delegate_all!(@trait $ftrait $([$($targs)*])* $name<$($arg),*>($t) $(where $($bound)*)*); + }; + ($(#[$attr:meta])* $name:ident<$($arg:ident),*>($t:ty) : $ftrait:ident $([$($ftargs:tt)*])* + $strait:ident $([$($stargs:tt)*])* $(+ $trait:ident $([$($targs:tt)*])*)* $({$($item:tt)*})* $(where $($bound:tt)*)*) => { + delegate_all!($(#[$attr])* $name<$($arg),*>($t) : $strait $([$($stargs)*])* $(+ $trait $([$($targs)*])*)* $({$($item)*})* $(where $($bound)*)*); + + delegate_all!(@trait $ftrait $([$($ftargs)*])* $name<$($arg),*>($t) $(where $($bound)*)*); + }; +} + +pub mod future; +#[doc(no_inline)] +pub use crate::future::{Future, FutureExt, TryFuture, TryFutureExt}; + +pub mod stream; +#[doc(no_inline)] +pub use crate::stream::{Stream, StreamExt, TryStream, TryStreamExt}; + +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub mod sink; +#[cfg(feature = "sink")] +#[doc(no_inline)] +pub use crate::sink::{Sink, SinkExt}; + +pub mod task; + +pub mod never; + +#[cfg(feature = "compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "compat")))] +pub mod compat; + +#[cfg(feature = "io")] +#[cfg_attr(docsrs, doc(cfg(feature = "io")))] +#[cfg(feature = "std")] +pub mod io; +#[cfg(feature = "io")] +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use crate::io::{ + AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite, + AsyncWriteExt, +}; + +#[cfg(feature = "alloc")] +pub mod lock; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod abortable; + +mod fns; +mod unfold_state; diff --git a/utshell-0.5.0/vendor/futures-util/src/lock/bilock.rs b/utshell-0.5.0/vendor/futures-util/src/lock/bilock.rs new file mode 100644 index 00000000..a89678e0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/lock/bilock.rs @@ -0,0 +1,298 @@ +//! Futures-powered synchronization primitives. + +use alloc::boxed::Box; +use alloc::sync::Arc; +use core::cell::UnsafeCell; +use core::ops::{Deref, DerefMut}; +use core::pin::Pin; +use core::sync::atomic::AtomicPtr; +use core::sync::atomic::Ordering::SeqCst; +use core::{fmt, ptr}; +#[cfg(feature = "bilock")] +use futures_core::future::Future; +use futures_core::task::{Context, Poll, Waker}; + +/// A type of futures-powered synchronization primitive which is a mutex between +/// two possible owners. +/// +/// This primitive is not as generic as a full-blown mutex but is sufficient for +/// many use cases where there are only two possible owners of a resource. The +/// implementation of `BiLock` can be more optimized for just the two possible +/// owners. +/// +/// Note that it's possible to use this lock through a poll-style interface with +/// the `poll_lock` method but you can also use it as a future with the `lock` +/// method that consumes a `BiLock` and returns a future that will resolve when +/// it's locked. +/// +/// A `BiLock` is typically used for "split" operations where data which serves +/// two purposes wants to be split into two to be worked with separately. For +/// example a TCP stream could be both a reader and a writer or a framing layer +/// could be both a stream and a sink for messages. A `BiLock` enables splitting +/// these two and then using each independently in a futures-powered fashion. +/// +/// This type is only available when the `bilock` feature of this +/// library is activated. +#[derive(Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] +pub struct BiLock { + arc: Arc>, +} + +#[derive(Debug)] +struct Inner { + state: AtomicPtr, + value: Option>, +} + +unsafe impl Send for Inner {} +unsafe impl Sync for Inner {} + +impl BiLock { + /// Creates a new `BiLock` protecting the provided data. + /// + /// Two handles to the lock are returned, and these are the only two handles + /// that will ever be available to the lock. These can then be sent to separate + /// tasks to be managed there. + /// + /// The data behind the bilock is considered to be pinned, which allows `Pin` + /// references to locked data. However, this means that the locked value + /// will only be available through `Pin<&mut T>` (not `&mut T`) unless `T` is `Unpin`. + /// Similarly, reuniting the lock and extracting the inner value is only + /// possible when `T` is `Unpin`. + pub fn new(t: T) -> (Self, Self) { + let arc = Arc::new(Inner { + state: AtomicPtr::new(ptr::null_mut()), + value: Some(UnsafeCell::new(t)), + }); + + (Self { arc: arc.clone() }, Self { arc }) + } + + /// Attempt to acquire this lock, returning `Pending` if it can't be + /// acquired. + /// + /// This function will acquire the lock in a nonblocking fashion, returning + /// immediately if the lock is already held. If the lock is successfully + /// acquired then `Poll::Ready` is returned with a value that represents + /// the locked value (and can be used to access the protected data). The + /// lock is unlocked when the returned `BiLockGuard` is dropped. + /// + /// If the lock is already held then this function will return + /// `Poll::Pending`. In this case the current task will also be scheduled + /// to receive a notification when the lock would otherwise become + /// available. + /// + /// # Panics + /// + /// This function will panic if called outside the context of a future's + /// task. + pub fn poll_lock(&self, cx: &mut Context<'_>) -> Poll> { + let mut waker = None; + loop { + let n = self.arc.state.swap(invalid_ptr(1), SeqCst); + match n as usize { + // Woohoo, we grabbed the lock! + 0 => return Poll::Ready(BiLockGuard { bilock: self }), + + // Oops, someone else has locked the lock + 1 => {} + + // A task was previously blocked on this lock, likely our task, + // so we need to update that task. + _ => unsafe { + let mut prev = Box::from_raw(n); + *prev = cx.waker().clone(); + waker = Some(prev); + }, + } + + // type ascription for safety's sake! + let me: Box = waker.take().unwrap_or_else(|| Box::new(cx.waker().clone())); + let me = Box::into_raw(me); + + match self.arc.state.compare_exchange(invalid_ptr(1), me, SeqCst, SeqCst) { + // The lock is still locked, but we've now parked ourselves, so + // just report that we're scheduled to receive a notification. + Ok(_) => return Poll::Pending, + + // Oops, looks like the lock was unlocked after our swap above + // and before the compare_exchange. Deallocate what we just + // allocated and go through the loop again. + Err(n) if n.is_null() => unsafe { + waker = Some(Box::from_raw(me)); + }, + + // The top of this loop set the previous state to 1, so if we + // failed the CAS above then it's because the previous value was + // *not* zero or one. This indicates that a task was blocked, + // but we're trying to acquire the lock and there's only one + // other reference of the lock, so it should be impossible for + // that task to ever block itself. + Err(n) => panic!("invalid state: {}", n as usize), + } + } + } + + /// Perform a "blocking lock" of this lock, consuming this lock handle and + /// returning a future to the acquired lock. + /// + /// This function consumes the `BiLock` and returns a sentinel future, + /// `BiLockAcquire`. The returned future will resolve to + /// `BiLockAcquired` which represents a locked lock similarly to + /// `BiLockGuard`. + /// + /// Note that the returned future will never resolve to an error. + #[cfg(feature = "bilock")] + #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] + pub fn lock(&self) -> BiLockAcquire<'_, T> { + BiLockAcquire { bilock: self } + } + + /// Returns `true` only if the other `BiLock` originated from the same call to `BiLock::new`. + pub fn is_pair_of(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.arc, &other.arc) + } + + /// Attempts to put the two "halves" of a `BiLock` back together and + /// recover the original value. Succeeds only if the two `BiLock`s + /// originated from the same call to `BiLock::new`. + pub fn reunite(self, other: Self) -> Result> + where + T: Unpin, + { + if self.is_pair_of(&other) { + drop(other); + let inner = Arc::try_unwrap(self.arc) + .ok() + .expect("futures: try_unwrap failed in BiLock::reunite"); + Ok(unsafe { inner.into_value() }) + } else { + Err(ReuniteError(self, other)) + } + } + + fn unlock(&self) { + let n = self.arc.state.swap(ptr::null_mut(), SeqCst); + match n as usize { + // we've locked the lock, shouldn't be possible for us to see an + // unlocked lock. + 0 => panic!("invalid unlocked state"), + + // Ok, no one else tried to get the lock, we're done. + 1 => {} + + // Another task has parked themselves on this lock, let's wake them + // up as its now their turn. + _ => unsafe { + Box::from_raw(n).wake(); + }, + } + } +} + +impl Inner { + unsafe fn into_value(mut self) -> T { + self.value.take().unwrap().into_inner() + } +} + +impl Drop for Inner { + fn drop(&mut self) { + assert!(self.state.load(SeqCst).is_null()); + } +} + +/// Error indicating two `BiLock`s were not two halves of a whole, and +/// thus could not be `reunite`d. +#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] +pub struct ReuniteError(pub BiLock, pub BiLock); + +impl fmt::Debug for ReuniteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("ReuniteError").field(&"...").finish() + } +} + +impl fmt::Display for ReuniteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "tried to reunite two BiLocks that don't form a pair") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ReuniteError {} + +/// Returned RAII guard from the `poll_lock` method. +/// +/// This structure acts as a sentinel to the data in the `BiLock` itself, +/// implementing `Deref` and `DerefMut` to `T`. When dropped, the lock will be +/// unlocked. +#[derive(Debug)] +#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] +pub struct BiLockGuard<'a, T> { + bilock: &'a BiLock, +} + +// We allow parallel access to T via Deref, so Sync bound is also needed here. +unsafe impl Sync for BiLockGuard<'_, T> {} + +impl Deref for BiLockGuard<'_, T> { + type Target = T; + fn deref(&self) -> &T { + unsafe { &*self.bilock.arc.value.as_ref().unwrap().get() } + } +} + +impl DerefMut for BiLockGuard<'_, T> { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.bilock.arc.value.as_ref().unwrap().get() } + } +} + +impl BiLockGuard<'_, T> { + /// Get a mutable pinned reference to the locked value. + pub fn as_pin_mut(&mut self) -> Pin<&mut T> { + // Safety: we never allow moving a !Unpin value out of a bilock, nor + // allow mutable access to it + unsafe { Pin::new_unchecked(&mut *self.bilock.arc.value.as_ref().unwrap().get()) } + } +} + +impl Drop for BiLockGuard<'_, T> { + fn drop(&mut self) { + self.bilock.unlock(); + } +} + +/// Future returned by `BiLock::lock` which will resolve when the lock is +/// acquired. +#[cfg(feature = "bilock")] +#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] +#[must_use = "futures do nothing unless you `.await` or poll them"] +#[derive(Debug)] +pub struct BiLockAcquire<'a, T> { + bilock: &'a BiLock, +} + +// Pinning is never projected to fields +#[cfg(feature = "bilock")] +impl Unpin for BiLockAcquire<'_, T> {} + +#[cfg(feature = "bilock")] +impl<'a, T> Future for BiLockAcquire<'a, T> { + type Output = BiLockGuard<'a, T>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.bilock.poll_lock(cx) + } +} + +// Based on core::ptr::invalid_mut. Equivalent to `addr as *mut T`, but is strict-provenance compatible. +#[allow(clippy::useless_transmute)] +#[inline] +fn invalid_ptr(addr: usize) -> *mut T { + // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that + // pointer). + unsafe { core::mem::transmute(addr) } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/lock/mod.rs b/utshell-0.5.0/vendor/futures-util/src/lock/mod.rs new file mode 100644 index 00000000..8ca0ff62 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/lock/mod.rs @@ -0,0 +1,27 @@ +//! Futures-powered synchronization primitives. +//! +//! This module is only available when the `std` or `alloc` feature of this +//! library is activated, and it is activated by default. + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(any(feature = "sink", feature = "io"))] +#[cfg(not(feature = "bilock"))] +pub(crate) use self::bilock::BiLock; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "bilock")] +#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] +pub use self::bilock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError}; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "std")] +pub use self::mutex::{ + MappedMutexGuard, Mutex, MutexGuard, MutexLockFuture, OwnedMutexGuard, OwnedMutexLockFuture, +}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(any(feature = "bilock", feature = "sink", feature = "io"))] +#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] +#[cfg_attr(not(feature = "bilock"), allow(unreachable_pub))] +mod bilock; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "std")] +mod mutex; diff --git a/utshell-0.5.0/vendor/futures-util/src/lock/mutex.rs b/utshell-0.5.0/vendor/futures-util/src/lock/mutex.rs new file mode 100644 index 00000000..335ad142 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/lock/mutex.rs @@ -0,0 +1,551 @@ +use std::cell::UnsafeCell; +use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex as StdMutex}; +use std::{fmt, mem}; + +use slab::Slab; + +use futures_core::future::{FusedFuture, Future}; +use futures_core::task::{Context, Poll, Waker}; + +/// A futures-aware mutex. +/// +/// # Fairness +/// +/// This mutex provides no fairness guarantees. Tasks may not acquire the mutex +/// in the order that they requested the lock, and it's possible for a single task +/// which repeatedly takes the lock to starve other tasks, which may be left waiting +/// indefinitely. +pub struct Mutex { + state: AtomicUsize, + waiters: StdMutex>, + value: UnsafeCell, +} + +impl fmt::Debug for Mutex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let state = self.state.load(Ordering::SeqCst); + f.debug_struct("Mutex") + .field("is_locked", &((state & IS_LOCKED) != 0)) + .field("has_waiters", &((state & HAS_WAITERS) != 0)) + .finish() + } +} + +impl From for Mutex { + fn from(t: T) -> Self { + Self::new(t) + } +} + +impl Default for Mutex { + fn default() -> Self { + Self::new(Default::default()) + } +} + +enum Waiter { + Waiting(Waker), + Woken, +} + +impl Waiter { + fn register(&mut self, waker: &Waker) { + match self { + Self::Waiting(w) if waker.will_wake(w) => {} + _ => *self = Self::Waiting(waker.clone()), + } + } + + fn wake(&mut self) { + match mem::replace(self, Self::Woken) { + Self::Waiting(waker) => waker.wake(), + Self::Woken => {} + } + } +} + +const IS_LOCKED: usize = 1 << 0; +const HAS_WAITERS: usize = 1 << 1; + +impl Mutex { + /// Creates a new futures-aware mutex. + pub fn new(t: T) -> Self { + Self { + state: AtomicUsize::new(0), + waiters: StdMutex::new(Slab::new()), + value: UnsafeCell::new(t), + } + } + + /// Consumes this mutex, returning the underlying data. + /// + /// # Examples + /// + /// ``` + /// use futures::lock::Mutex; + /// + /// let mutex = Mutex::new(0); + /// assert_eq!(mutex.into_inner(), 0); + /// ``` + pub fn into_inner(self) -> T { + self.value.into_inner() + } +} + +impl Mutex { + /// Attempt to acquire the lock immediately. + /// + /// If the lock is currently held, this will return `None`. + pub fn try_lock(&self) -> Option> { + let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire); + if (old_state & IS_LOCKED) == 0 { + Some(MutexGuard { mutex: self }) + } else { + None + } + } + + /// Attempt to acquire the lock immediately. + /// + /// If the lock is currently held, this will return `None`. + pub fn try_lock_owned(self: &Arc) -> Option> { + let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire); + if (old_state & IS_LOCKED) == 0 { + Some(OwnedMutexGuard { mutex: self.clone() }) + } else { + None + } + } + + /// Acquire the lock asynchronously. + /// + /// This method returns a future that will resolve once the lock has been + /// successfully acquired. + pub fn lock(&self) -> MutexLockFuture<'_, T> { + MutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE } + } + + /// Acquire the lock asynchronously. + /// + /// This method returns a future that will resolve once the lock has been + /// successfully acquired. + pub fn lock_owned(self: Arc) -> OwnedMutexLockFuture { + OwnedMutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE } + } + + /// Returns a mutable reference to the underlying data. + /// + /// Since this call borrows the `Mutex` mutably, no actual locking needs to + /// take place -- the mutable borrow statically guarantees no locks exist. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::lock::Mutex; + /// + /// let mut mutex = Mutex::new(0); + /// *mutex.get_mut() = 10; + /// assert_eq!(*mutex.lock().await, 10); + /// # }); + /// ``` + pub fn get_mut(&mut self) -> &mut T { + // We know statically that there are no other references to `self`, so + // there's no need to lock the inner mutex. + unsafe { &mut *self.value.get() } + } + + fn remove_waker(&self, wait_key: usize, wake_another: bool) { + if wait_key != WAIT_KEY_NONE { + let mut waiters = self.waiters.lock().unwrap(); + match waiters.remove(wait_key) { + Waiter::Waiting(_) => {} + Waiter::Woken => { + // We were awoken, but then dropped before we could + // wake up to acquire the lock. Wake up another + // waiter. + if wake_another { + if let Some((_i, waiter)) = waiters.iter_mut().next() { + waiter.wake(); + } + } + } + } + if waiters.is_empty() { + self.state.fetch_and(!HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock + } + } + } + + // Unlocks the mutex. Called by MutexGuard and MappedMutexGuard when they are + // dropped. + fn unlock(&self) { + let old_state = self.state.fetch_and(!IS_LOCKED, Ordering::AcqRel); + if (old_state & HAS_WAITERS) != 0 { + let mut waiters = self.waiters.lock().unwrap(); + if let Some((_i, waiter)) = waiters.iter_mut().next() { + waiter.wake(); + } + } + } +} + +// Sentinel for when no slot in the `Slab` has been dedicated to this object. +const WAIT_KEY_NONE: usize = usize::MAX; + +/// A future which resolves when the target mutex has been successfully acquired, owned version. +pub struct OwnedMutexLockFuture { + // `None` indicates that the mutex was successfully acquired. + mutex: Option>>, + wait_key: usize, +} + +impl fmt::Debug for OwnedMutexLockFuture { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OwnedMutexLockFuture") + .field("was_acquired", &self.mutex.is_none()) + .field("mutex", &self.mutex) + .field( + "wait_key", + &(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }), + ) + .finish() + } +} + +impl FusedFuture for OwnedMutexLockFuture { + fn is_terminated(&self) -> bool { + self.mutex.is_none() + } +} + +impl Future for OwnedMutexLockFuture { + type Output = OwnedMutexGuard; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.get_mut(); + + let mutex = this.mutex.as_ref().expect("polled OwnedMutexLockFuture after completion"); + + if let Some(lock) = mutex.try_lock_owned() { + mutex.remove_waker(this.wait_key, false); + this.mutex = None; + return Poll::Ready(lock); + } + + { + let mut waiters = mutex.waiters.lock().unwrap(); + if this.wait_key == WAIT_KEY_NONE { + this.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone())); + if waiters.len() == 1 { + mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock + } + } else { + waiters[this.wait_key].register(cx.waker()); + } + } + + // Ensure that we haven't raced `MutexGuard::drop`'s unlock path by + // attempting to acquire the lock again. + if let Some(lock) = mutex.try_lock_owned() { + mutex.remove_waker(this.wait_key, false); + this.mutex = None; + return Poll::Ready(lock); + } + + Poll::Pending + } +} + +impl Drop for OwnedMutexLockFuture { + fn drop(&mut self) { + if let Some(mutex) = self.mutex.as_ref() { + // This future was dropped before it acquired the mutex. + // + // Remove ourselves from the map, waking up another waiter if we + // had been awoken to acquire the lock. + mutex.remove_waker(self.wait_key, true); + } + } +} + +/// An RAII guard returned by the `lock_owned` and `try_lock_owned` methods. +/// When this structure is dropped (falls out of scope), the lock will be +/// unlocked. +pub struct OwnedMutexGuard { + mutex: Arc>, +} + +impl fmt::Debug for OwnedMutexGuard { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OwnedMutexGuard") + .field("value", &&**self) + .field("mutex", &self.mutex) + .finish() + } +} + +impl Drop for OwnedMutexGuard { + fn drop(&mut self) { + self.mutex.unlock() + } +} + +impl Deref for OwnedMutexGuard { + type Target = T; + fn deref(&self) -> &T { + unsafe { &*self.mutex.value.get() } + } +} + +impl DerefMut for OwnedMutexGuard { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.mutex.value.get() } + } +} + +/// A future which resolves when the target mutex has been successfully acquired. +pub struct MutexLockFuture<'a, T: ?Sized> { + // `None` indicates that the mutex was successfully acquired. + mutex: Option<&'a Mutex>, + wait_key: usize, +} + +impl fmt::Debug for MutexLockFuture<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("MutexLockFuture") + .field("was_acquired", &self.mutex.is_none()) + .field("mutex", &self.mutex) + .field( + "wait_key", + &(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }), + ) + .finish() + } +} + +impl FusedFuture for MutexLockFuture<'_, T> { + fn is_terminated(&self) -> bool { + self.mutex.is_none() + } +} + +impl<'a, T: ?Sized> Future for MutexLockFuture<'a, T> { + type Output = MutexGuard<'a, T>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mutex = self.mutex.expect("polled MutexLockFuture after completion"); + + if let Some(lock) = mutex.try_lock() { + mutex.remove_waker(self.wait_key, false); + self.mutex = None; + return Poll::Ready(lock); + } + + { + let mut waiters = mutex.waiters.lock().unwrap(); + if self.wait_key == WAIT_KEY_NONE { + self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone())); + if waiters.len() == 1 { + mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock + } + } else { + waiters[self.wait_key].register(cx.waker()); + } + } + + // Ensure that we haven't raced `MutexGuard::drop`'s unlock path by + // attempting to acquire the lock again. + if let Some(lock) = mutex.try_lock() { + mutex.remove_waker(self.wait_key, false); + self.mutex = None; + return Poll::Ready(lock); + } + + Poll::Pending + } +} + +impl Drop for MutexLockFuture<'_, T> { + fn drop(&mut self) { + if let Some(mutex) = self.mutex { + // This future was dropped before it acquired the mutex. + // + // Remove ourselves from the map, waking up another waiter if we + // had been awoken to acquire the lock. + mutex.remove_waker(self.wait_key, true); + } + } +} + +/// An RAII guard returned by the `lock` and `try_lock` methods. +/// When this structure is dropped (falls out of scope), the lock will be +/// unlocked. +pub struct MutexGuard<'a, T: ?Sized> { + mutex: &'a Mutex, +} + +impl<'a, T: ?Sized> MutexGuard<'a, T> { + /// Returns a locked view over a portion of the locked data. + /// + /// # Example + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::lock::{Mutex, MutexGuard}; + /// + /// let data = Mutex::new(Some("value".to_string())); + /// { + /// let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap()); + /// assert_eq!(&*locked_str, "value"); + /// } + /// # }); + /// ``` + #[inline] + pub fn map(this: Self, f: F) -> MappedMutexGuard<'a, T, U> + where + F: FnOnce(&mut T) -> &mut U, + { + let mutex = this.mutex; + let value = f(unsafe { &mut *this.mutex.value.get() }); + // Don't run the `drop` method for MutexGuard. The ownership of the underlying + // locked state is being moved to the returned MappedMutexGuard. + mem::forget(this); + MappedMutexGuard { mutex, value, _marker: PhantomData } + } +} + +impl fmt::Debug for MutexGuard<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("MutexGuard").field("value", &&**self).field("mutex", &self.mutex).finish() + } +} + +impl Drop for MutexGuard<'_, T> { + fn drop(&mut self) { + self.mutex.unlock() + } +} + +impl Deref for MutexGuard<'_, T> { + type Target = T; + fn deref(&self) -> &T { + unsafe { &*self.mutex.value.get() } + } +} + +impl DerefMut for MutexGuard<'_, T> { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.mutex.value.get() } + } +} + +/// An RAII guard returned by the `MutexGuard::map` and `MappedMutexGuard::map` methods. +/// When this structure is dropped (falls out of scope), the lock will be unlocked. +pub struct MappedMutexGuard<'a, T: ?Sized, U: ?Sized> { + mutex: &'a Mutex, + value: *mut U, + _marker: PhantomData<&'a mut U>, +} + +impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> { + /// Returns a locked view over a portion of the locked data. + /// + /// # Example + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::lock::{MappedMutexGuard, Mutex, MutexGuard}; + /// + /// let data = Mutex::new(Some("value".to_string())); + /// { + /// let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap()); + /// let locked_char = MappedMutexGuard::map(locked_str, |s| s.get_mut(0..1).unwrap()); + /// assert_eq!(&*locked_char, "v"); + /// } + /// # }); + /// ``` + #[inline] + pub fn map(this: Self, f: F) -> MappedMutexGuard<'a, T, V> + where + F: FnOnce(&mut U) -> &mut V, + { + let mutex = this.mutex; + let value = f(unsafe { &mut *this.value }); + // Don't run the `drop` method for MappedMutexGuard. The ownership of the underlying + // locked state is being moved to the returned MappedMutexGuard. + mem::forget(this); + MappedMutexGuard { mutex, value, _marker: PhantomData } + } +} + +impl fmt::Debug for MappedMutexGuard<'_, T, U> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("MappedMutexGuard") + .field("value", &&**self) + .field("mutex", &self.mutex) + .finish() + } +} + +impl Drop for MappedMutexGuard<'_, T, U> { + fn drop(&mut self) { + self.mutex.unlock() + } +} + +impl Deref for MappedMutexGuard<'_, T, U> { + type Target = U; + fn deref(&self) -> &U { + unsafe { &*self.value } + } +} + +impl DerefMut for MappedMutexGuard<'_, T, U> { + fn deref_mut(&mut self) -> &mut U { + unsafe { &mut *self.value } + } +} + +// Mutexes can be moved freely between threads and acquired on any thread so long +// as the inner value can be safely sent between threads. +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +// It's safe to switch which thread the acquire is being attempted on so long as +// `T` can be accessed on that thread. +unsafe impl Send for MutexLockFuture<'_, T> {} + +// doesn't have any interesting `&self` methods (only Debug) +unsafe impl Sync for MutexLockFuture<'_, T> {} + +// It's safe to switch which thread the acquire is being attempted on so long as +// `T` can be accessed on that thread. +unsafe impl Send for OwnedMutexLockFuture {} + +// doesn't have any interesting `&self` methods (only Debug) +unsafe impl Sync for OwnedMutexLockFuture {} + +// Safe to send since we don't track any thread-specific details-- the inner +// lock is essentially spinlock-equivalent (attempt to flip an atomic bool) +unsafe impl Send for MutexGuard<'_, T> {} +unsafe impl Sync for MutexGuard<'_, T> {} + +unsafe impl Send for OwnedMutexGuard {} +unsafe impl Sync for OwnedMutexGuard {} + +unsafe impl Send for MappedMutexGuard<'_, T, U> {} +unsafe impl Sync for MappedMutexGuard<'_, T, U> {} + +#[test] +fn test_mutex_guard_debug_not_recurse() { + let mutex = Mutex::new(42); + let guard = mutex.try_lock().unwrap(); + let _ = format!("{:?}", guard); + let guard = MutexGuard::map(guard, |n| n); + let _ = format!("{:?}", guard); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/never.rs b/utshell-0.5.0/vendor/futures-util/src/never.rs new file mode 100644 index 00000000..e811f97d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/never.rs @@ -0,0 +1,18 @@ +//! This module contains the `Never` type. +//! +//! Values of this type can never be created and will never exist. + +/// A type with no possible values. +/// +/// This is used to indicate values which can never be created, such as the +/// error type of infallible futures. +/// +/// This type is a stable equivalent to the `!` type from `std`. +/// +/// This is currently an alias for [`std::convert::Infallible`], but in +/// the future it may be an alias for [`!`][never]. +/// See ["Future compatibility" section of `std::convert::Infallible`][infallible] for more. +/// +/// [never]: https://doc.rust-lang.org/nightly/std/primitive.never.html +/// [infallible]: https://doc.rust-lang.org/nightly/std/convert/enum.Infallible.html#future-compatibility +pub type Never = core::convert::Infallible; diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/buffer.rs b/utshell-0.5.0/vendor/futures-util/src/sink/buffer.rs new file mode 100644 index 00000000..4aa6c360 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/buffer.rs @@ -0,0 +1,105 @@ +use alloc::collections::VecDeque; +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink for the [`buffer`](super::SinkExt::buffer) method. + #[derive(Debug)] + #[must_use = "sinks do nothing unless polled"] + pub struct Buffer { + #[pin] + sink: Si, + buf: VecDeque, + + // Track capacity separately from the `VecDeque`, which may be rounded up + capacity: usize, + } +} + +impl, Item> Buffer { + pub(super) fn new(sink: Si, capacity: usize) -> Self { + Self { sink, buf: VecDeque::with_capacity(capacity), capacity } + } + + delegate_access_inner!(sink, Si, ()); + + fn try_empty_buffer(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + ready!(this.sink.as_mut().poll_ready(cx))?; + while let Some(item) = this.buf.pop_front() { + this.sink.as_mut().start_send(item)?; + if !this.buf.is_empty() { + ready!(this.sink.as_mut().poll_ready(cx))?; + } + } + Poll::Ready(Ok(())) + } +} + +// Forwarding impl of Stream from the underlying sink +impl Stream for Buffer +where + S: Sink + Stream, +{ + type Item = S::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().sink.poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + self.sink.size_hint() + } +} + +impl FusedStream for Buffer +where + S: Sink + FusedStream, +{ + fn is_terminated(&self) -> bool { + self.sink.is_terminated() + } +} + +impl, Item> Sink for Buffer { + type Error = Si::Error; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.capacity == 0 { + return self.project().sink.poll_ready(cx); + } + + let _ = self.as_mut().try_empty_buffer(cx)?; + + if self.buf.len() >= self.capacity { + Poll::Pending + } else { + Poll::Ready(Ok(())) + } + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + if self.capacity == 0 { + self.project().sink.start_send(item) + } else { + self.project().buf.push_back(item); + Ok(()) + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().try_empty_buffer(cx))?; + debug_assert!(self.buf.is_empty()); + self.project().sink.poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().try_empty_buffer(cx))?; + debug_assert!(self.buf.is_empty()); + self.project().sink.poll_close(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/close.rs b/utshell-0.5.0/vendor/futures-util/src/sink/close.rs new file mode 100644 index 00000000..43eea74b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/close.rs @@ -0,0 +1,32 @@ +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +/// Future for the [`close`](super::SinkExt::close) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Close<'a, Si: ?Sized, Item> { + sink: &'a mut Si, + _phantom: PhantomData, +} + +impl Unpin for Close<'_, Si, Item> {} + +/// A future that completes when the sink has finished closing. +/// +/// The sink itself is returned after closing is complete. +impl<'a, Si: Sink + Unpin + ?Sized, Item> Close<'a, Si, Item> { + pub(super) fn new(sink: &'a mut Si) -> Self { + Self { sink, _phantom: PhantomData } + } +} + +impl + Unpin + ?Sized, Item> Future for Close<'_, Si, Item> { + type Output = Result<(), Si::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.sink).poll_close(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/drain.rs b/utshell-0.5.0/vendor/futures-util/src/sink/drain.rs new file mode 100644 index 00000000..1a5480c0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/drain.rs @@ -0,0 +1,59 @@ +use super::assert_sink; +use crate::never::Never; +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +/// Sink for the [`drain`] function. +#[derive(Debug)] +#[must_use = "sinks do nothing unless polled"] +pub struct Drain { + marker: PhantomData, +} + +/// Create a sink that will just discard all items given to it. +/// +/// Similar to [`io::Sink`](::std::io::Sink). +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::sink::{self, SinkExt}; +/// +/// let mut drain = sink::drain(); +/// drain.send(5).await?; +/// # Ok::<(), futures::never::Never>(()) }).unwrap(); +/// ``` +pub fn drain() -> Drain { + assert_sink::(Drain { marker: PhantomData }) +} + +impl Unpin for Drain {} + +impl Clone for Drain { + fn clone(&self) -> Self { + drain() + } +} + +impl Sink for Drain { + type Error = Never; + + fn poll_ready(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn start_send(self: Pin<&mut Self>, _item: T) -> Result<(), Self::Error> { + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/err_into.rs b/utshell-0.5.0/vendor/futures-util/src/sink/err_into.rs new file mode 100644 index 00000000..a64d1337 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/err_into.rs @@ -0,0 +1,57 @@ +use crate::sink::{SinkExt, SinkMapErr}; +use futures_core::stream::{FusedStream, Stream}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink for the [`sink_err_into`](super::SinkExt::sink_err_into) method. + #[derive(Debug)] + #[must_use = "sinks do nothing unless polled"] + pub struct SinkErrInto, Item, E> { + #[pin] + sink: SinkMapErr E>, + } +} + +impl SinkErrInto +where + Si: Sink, + Si::Error: Into, +{ + pub(super) fn new(sink: Si) -> Self { + Self { sink: SinkExt::sink_map_err(sink, Into::into) } + } + + delegate_access_inner!(sink, Si, (.)); +} + +impl Sink for SinkErrInto +where + Si: Sink, + Si::Error: Into, +{ + type Error = E; + + delegate_sink!(sink, Item); +} + +// Forwarding impl of Stream from the underlying sink +impl Stream for SinkErrInto +where + S: Sink + Stream, + S::Error: Into, +{ + type Item = S::Item; + + delegate_stream!(sink); +} + +impl FusedStream for SinkErrInto +where + S: Sink + FusedStream, + S::Error: Into, +{ + fn is_terminated(&self) -> bool { + self.sink.is_terminated() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/fanout.rs b/utshell-0.5.0/vendor/futures-util/src/sink/fanout.rs new file mode 100644 index 00000000..fe2038f2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/fanout.rs @@ -0,0 +1,111 @@ +use core::fmt::{Debug, Formatter, Result as FmtResult}; +use core::pin::Pin; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink that clones incoming items and forwards them to two sinks at the same time. + /// + /// Backpressure from any downstream sink propagates up, which means that this sink + /// can only process items as fast as its _slowest_ downstream sink. + #[must_use = "sinks do nothing unless polled"] + pub struct Fanout { + #[pin] + sink1: Si1, + #[pin] + sink2: Si2 + } +} + +impl Fanout { + pub(super) fn new(sink1: Si1, sink2: Si2) -> Self { + Self { sink1, sink2 } + } + + /// Get a shared reference to the inner sinks. + pub fn get_ref(&self) -> (&Si1, &Si2) { + (&self.sink1, &self.sink2) + } + + /// Get a mutable reference to the inner sinks. + pub fn get_mut(&mut self) -> (&mut Si1, &mut Si2) { + (&mut self.sink1, &mut self.sink2) + } + + /// Get a pinned mutable reference to the inner sinks. + pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut Si1>, Pin<&mut Si2>) { + let this = self.project(); + (this.sink1, this.sink2) + } + + /// Consumes this combinator, returning the underlying sinks. + /// + /// Note that this may discard intermediate state of this combinator, + /// so care should be taken to avoid losing resources when this is called. + pub fn into_inner(self) -> (Si1, Si2) { + (self.sink1, self.sink2) + } +} + +impl Debug for Fanout { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + f.debug_struct("Fanout").field("sink1", &self.sink1).field("sink2", &self.sink2).finish() + } +} + +impl Sink for Fanout +where + Si1: Sink, + Item: Clone, + Si2: Sink, +{ + type Error = Si1::Error; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + let sink1_ready = this.sink1.poll_ready(cx)?.is_ready(); + let sink2_ready = this.sink2.poll_ready(cx)?.is_ready(); + let ready = sink1_ready && sink2_ready; + if ready { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + let this = self.project(); + + this.sink1.start_send(item.clone())?; + this.sink2.start_send(item)?; + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + let sink1_ready = this.sink1.poll_flush(cx)?.is_ready(); + let sink2_ready = this.sink2.poll_flush(cx)?.is_ready(); + let ready = sink1_ready && sink2_ready; + if ready { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + let sink1_ready = this.sink1.poll_close(cx)?.is_ready(); + let sink2_ready = this.sink2.poll_close(cx)?.is_ready(); + let ready = sink1_ready && sink2_ready; + if ready { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/feed.rs b/utshell-0.5.0/vendor/futures-util/src/sink/feed.rs new file mode 100644 index 00000000..6701f7a1 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/feed.rs @@ -0,0 +1,43 @@ +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +/// Future for the [`feed`](super::SinkExt::feed) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Feed<'a, Si: ?Sized, Item> { + sink: &'a mut Si, + item: Option, +} + +// Pinning is never projected to children +impl Unpin for Feed<'_, Si, Item> {} + +impl<'a, Si: Sink + Unpin + ?Sized, Item> Feed<'a, Si, Item> { + pub(super) fn new(sink: &'a mut Si, item: Item) -> Self { + Feed { sink, item: Some(item) } + } + + pub(super) fn sink_pin_mut(&mut self) -> Pin<&mut Si> { + Pin::new(self.sink) + } + + pub(super) fn is_item_pending(&self) -> bool { + self.item.is_some() + } +} + +impl + Unpin + ?Sized, Item> Future for Feed<'_, Si, Item> { + type Output = Result<(), Si::Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.get_mut(); + let mut sink = Pin::new(&mut this.sink); + ready!(sink.as_mut().poll_ready(cx))?; + let item = this.item.take().expect("polled Feed after completion"); + sink.as_mut().start_send(item)?; + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/flush.rs b/utshell-0.5.0/vendor/futures-util/src/sink/flush.rs new file mode 100644 index 00000000..35a8372d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/flush.rs @@ -0,0 +1,36 @@ +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +/// Future for the [`flush`](super::SinkExt::flush) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Flush<'a, Si: ?Sized, Item> { + sink: &'a mut Si, + _phantom: PhantomData, +} + +// Pin is never projected to a field. +impl Unpin for Flush<'_, Si, Item> {} + +/// A future that completes when the sink has finished processing all +/// pending requests. +/// +/// The sink itself is returned after flushing is complete; this adapter is +/// intended to be used when you want to stop sending to the sink until +/// all current requests are processed. +impl<'a, Si: Sink + Unpin + ?Sized, Item> Flush<'a, Si, Item> { + pub(super) fn new(sink: &'a mut Si) -> Self { + Self { sink, _phantom: PhantomData } + } +} + +impl + Unpin + ?Sized, Item> Future for Flush<'_, Si, Item> { + type Output = Result<(), Si::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.sink).poll_flush(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/map_err.rs b/utshell-0.5.0/vendor/futures-util/src/sink/map_err.rs new file mode 100644 index 00000000..9d2ab7b2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/map_err.rs @@ -0,0 +1,65 @@ +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink for the [`sink_map_err`](super::SinkExt::sink_map_err) method. + #[derive(Debug, Clone)] + #[must_use = "sinks do nothing unless polled"] + pub struct SinkMapErr { + #[pin] + sink: Si, + f: Option, + } +} + +impl SinkMapErr { + pub(super) fn new(sink: Si, f: F) -> Self { + Self { sink, f: Some(f) } + } + + delegate_access_inner!(sink, Si, ()); + + fn take_f(self: Pin<&mut Self>) -> F { + self.project().f.take().expect("polled MapErr after completion") + } +} + +impl Sink for SinkMapErr +where + Si: Sink, + F: FnOnce(Si::Error) -> E, +{ + type Error = E; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.as_mut().project().sink.poll_ready(cx).map_err(|e| self.as_mut().take_f()(e)) + } + + fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + self.as_mut().project().sink.start_send(item).map_err(|e| self.as_mut().take_f()(e)) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.as_mut().project().sink.poll_flush(cx).map_err(|e| self.as_mut().take_f()(e)) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.as_mut().project().sink.poll_close(cx).map_err(|e| self.as_mut().take_f()(e)) + } +} + +// Forwarding impl of Stream from the underlying sink +impl Stream for SinkMapErr { + type Item = S::Item; + + delegate_stream!(sink); +} + +impl FusedStream for SinkMapErr { + fn is_terminated(&self) -> bool { + self.sink.is_terminated() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/mod.rs b/utshell-0.5.0/vendor/futures-util/src/sink/mod.rs new file mode 100644 index 00000000..147e9adc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/mod.rs @@ -0,0 +1,344 @@ +//! Asynchronous sinks. +//! +//! This module contains: +//! +//! - The [`Sink`] trait, which allows you to asynchronously write data. +//! - The [`SinkExt`] trait, which provides adapters for chaining and composing +//! sinks. + +use crate::future::{assert_future, Either}; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::stream::{Stream, TryStream}; +use futures_core::task::{Context, Poll}; + +#[cfg(feature = "compat")] +use crate::compat::CompatSink; + +pub use futures_sink::Sink; + +mod close; +pub use self::close::Close; + +mod drain; +pub use self::drain::{drain, Drain}; + +mod fanout; +pub use self::fanout::Fanout; + +mod feed; +pub use self::feed::Feed; + +mod flush; +pub use self::flush::Flush; + +mod err_into; +pub use self::err_into::SinkErrInto; + +mod map_err; +pub use self::map_err::SinkMapErr; + +mod send; +pub use self::send::Send; + +mod send_all; +pub use self::send_all::SendAll; + +mod unfold; +pub use self::unfold::{unfold, Unfold}; + +mod with; +pub use self::with::With; + +mod with_flat_map; +pub use self::with_flat_map::WithFlatMap; + +#[cfg(feature = "alloc")] +mod buffer; +#[cfg(feature = "alloc")] +pub use self::buffer::Buffer; + +impl SinkExt for T where T: Sink {} + +/// An extension trait for `Sink`s that provides a variety of convenient +/// combinator functions. +pub trait SinkExt: Sink { + /// Composes a function *in front of* the sink. + /// + /// This adapter produces a new sink that passes each value through the + /// given function `f` before sending it to `self`. + /// + /// To process each value, `f` produces a *future*, which is then polled to + /// completion before passing its result down to the underlying sink. If the + /// future produces an error, that error is returned by the new sink. + /// + /// Note that this function consumes the given sink, returning a wrapped + /// version, much like `Iterator::map`. + fn with(self, f: F) -> With + where + F: FnMut(U) -> Fut, + Fut: Future>, + E: From, + Self: Sized, + { + assert_sink::(With::new(self, f)) + } + + /// Composes a function *in front of* the sink. + /// + /// This adapter produces a new sink that passes each value through the + /// given function `f` before sending it to `self`. + /// + /// To process each value, `f` produces a *stream*, of which each value + /// is passed to the underlying sink. A new value will not be accepted until + /// the stream has been drained + /// + /// Note that this function consumes the given sink, returning a wrapped + /// version, much like `Iterator::flat_map`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::sink::SinkExt; + /// use futures::stream::{self, StreamExt}; + /// + /// let (tx, rx) = mpsc::channel(5); + /// + /// let mut tx = tx.with_flat_map(|x| { + /// stream::iter(vec![Ok(42); x]) + /// }); + /// + /// tx.send(5).await.unwrap(); + /// drop(tx); + /// let received: Vec = rx.collect().await; + /// assert_eq!(received, vec![42, 42, 42, 42, 42]); + /// # }); + /// ``` + fn with_flat_map(self, f: F) -> WithFlatMap + where + F: FnMut(U) -> St, + St: Stream>, + Self: Sized, + { + assert_sink::(WithFlatMap::new(self, f)) + } + + /* + fn with_map(self, f: F) -> WithMap + where F: FnMut(U) -> Self::SinkItem, + Self: Sized; + + fn with_filter(self, f: F) -> WithFilter + where F: FnMut(Self::SinkItem) -> bool, + Self: Sized; + + fn with_filter_map(self, f: F) -> WithFilterMap + where F: FnMut(U) -> Option, + Self: Sized; + */ + + /// Transforms the error returned by the sink. + fn sink_map_err(self, f: F) -> SinkMapErr + where + F: FnOnce(Self::Error) -> E, + Self: Sized, + { + assert_sink::(SinkMapErr::new(self, f)) + } + + /// Map this sink's error to a different error type using the `Into` trait. + /// + /// If wanting to map errors of a `Sink + Stream`, use `.sink_err_into().err_into()`. + fn sink_err_into(self) -> err_into::SinkErrInto + where + Self: Sized, + Self::Error: Into, + { + assert_sink::(SinkErrInto::new(self)) + } + + /// Adds a fixed-size buffer to the current sink. + /// + /// The resulting sink will buffer up to `capacity` items when the + /// underlying sink is unwilling to accept additional items. Calling `flush` + /// on the buffered sink will attempt to both empty the buffer and complete + /// processing on the underlying sink. + /// + /// Note that this function consumes the given sink, returning a wrapped + /// version, much like `Iterator::map`. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "alloc")] + fn buffer(self, capacity: usize) -> Buffer + where + Self: Sized, + { + assert_sink::(Buffer::new(self, capacity)) + } + + /// Close the sink. + fn close(&mut self) -> Close<'_, Self, Item> + where + Self: Unpin, + { + assert_future::, _>(Close::new(self)) + } + + /// Fanout items to multiple sinks. + /// + /// This adapter clones each incoming item and forwards it to both this as well as + /// the other sink at the same time. + fn fanout(self, other: Si) -> Fanout + where + Self: Sized, + Item: Clone, + Si: Sink, + { + assert_sink::(Fanout::new(self, other)) + } + + /// Flush the sink, processing all pending items. + /// + /// This adapter is intended to be used when you want to stop sending to the sink + /// until all current requests are processed. + fn flush(&mut self) -> Flush<'_, Self, Item> + where + Self: Unpin, + { + assert_future::, _>(Flush::new(self)) + } + + /// A future that completes after the given item has been fully processed + /// into the sink, including flushing. + /// + /// Note that, **because of the flushing requirement, it is usually better + /// to batch together items to send via `feed` or `send_all`, + /// rather than flushing between each item.** + fn send(&mut self, item: Item) -> Send<'_, Self, Item> + where + Self: Unpin, + { + assert_future::, _>(Send::new(self, item)) + } + + /// A future that completes after the given item has been received + /// by the sink. + /// + /// Unlike `send`, the returned future does not flush the sink. + /// It is the caller's responsibility to ensure all pending items + /// are processed, which can be done via `flush` or `close`. + fn feed(&mut self, item: Item) -> Feed<'_, Self, Item> + where + Self: Unpin, + { + assert_future::, _>(Feed::new(self, item)) + } + + /// A future that completes after the given stream has been fully processed + /// into the sink, including flushing. + /// + /// This future will drive the stream to keep producing items until it is + /// exhausted, sending each item to the sink. It will complete once both the + /// stream is exhausted, the sink has received all items, and the sink has + /// been flushed. Note that the sink is **not** closed. If the stream produces + /// an error, that error will be returned by this future without flushing the sink. + /// + /// Doing `sink.send_all(stream)` is roughly equivalent to + /// `stream.forward(sink)`. The returned future will exhaust all items from + /// `stream` and send them to `self`. + fn send_all<'a, St>(&'a mut self, stream: &'a mut St) -> SendAll<'a, Self, St> + where + St: TryStream + Stream + Unpin + ?Sized, + // St: Stream> + Unpin + ?Sized, + Self: Unpin, + { + // TODO: type mismatch resolving `::Item == std::result::Result>::Error>` + // assert_future::, _>(SendAll::new(self, stream)) + SendAll::new(self, stream) + } + + /// Wrap this sink in an `Either` sink, making it the left-hand variant + /// of that `Either`. + /// + /// This can be used in combination with the `right_sink` method to write `if` + /// statements that evaluate to different streams in different branches. + fn left_sink(self) -> Either + where + Si2: Sink, + Self: Sized, + { + assert_sink::(Either::Left(self)) + } + + /// Wrap this stream in an `Either` stream, making it the right-hand variant + /// of that `Either`. + /// + /// This can be used in combination with the `left_sink` method to write `if` + /// statements that evaluate to different streams in different branches. + fn right_sink(self) -> Either + where + Si1: Sink, + Self: Sized, + { + assert_sink::(Either::Right(self)) + } + + /// Wraps a [`Sink`] into a sink compatible with libraries using + /// futures 0.1 `Sink`. Requires the `compat` feature to be enabled. + #[cfg(feature = "compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] + fn compat(self) -> CompatSink + where + Self: Sized + Unpin, + { + CompatSink::new(self) + } + + /// A convenience method for calling [`Sink::poll_ready`] on [`Unpin`] + /// sink types. + fn poll_ready_unpin(&mut self, cx: &mut Context<'_>) -> Poll> + where + Self: Unpin, + { + Pin::new(self).poll_ready(cx) + } + + /// A convenience method for calling [`Sink::start_send`] on [`Unpin`] + /// sink types. + fn start_send_unpin(&mut self, item: Item) -> Result<(), Self::Error> + where + Self: Unpin, + { + Pin::new(self).start_send(item) + } + + /// A convenience method for calling [`Sink::poll_flush`] on [`Unpin`] + /// sink types. + fn poll_flush_unpin(&mut self, cx: &mut Context<'_>) -> Poll> + where + Self: Unpin, + { + Pin::new(self).poll_flush(cx) + } + + /// A convenience method for calling [`Sink::poll_close`] on [`Unpin`] + /// sink types. + fn poll_close_unpin(&mut self, cx: &mut Context<'_>) -> Poll> + where + Self: Unpin, + { + Pin::new(self).poll_close(cx) + } +} + +// Just a helper function to ensure the sinks we're returning all have the +// right implementations. +pub(crate) fn assert_sink(sink: S) -> S +where + S: Sink, +{ + sink +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/send.rs b/utshell-0.5.0/vendor/futures-util/src/sink/send.rs new file mode 100644 index 00000000..6d21f33f --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/send.rs @@ -0,0 +1,41 @@ +use super::Feed; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +/// Future for the [`send`](super::SinkExt::send) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Send<'a, Si: ?Sized, Item> { + feed: Feed<'a, Si, Item>, +} + +// Pinning is never projected to children +impl Unpin for Send<'_, Si, Item> {} + +impl<'a, Si: Sink + Unpin + ?Sized, Item> Send<'a, Si, Item> { + pub(super) fn new(sink: &'a mut Si, item: Item) -> Self { + Self { feed: Feed::new(sink, item) } + } +} + +impl + Unpin + ?Sized, Item> Future for Send<'_, Si, Item> { + type Output = Result<(), Si::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + + if this.feed.is_item_pending() { + ready!(Pin::new(&mut this.feed).poll(cx))?; + debug_assert!(!this.feed.is_item_pending()); + } + + // we're done sending the item, but want to block on flushing the + // sink + ready!(this.feed.sink_pin_mut().poll_flush(cx))?; + + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/send_all.rs b/utshell-0.5.0/vendor/futures-util/src/sink/send_all.rs new file mode 100644 index 00000000..1302dd21 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/send_all.rs @@ -0,0 +1,100 @@ +use crate::stream::{Fuse, StreamExt, TryStreamExt}; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{Stream, TryStream}; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +/// Future for the [`send_all`](super::SinkExt::send_all) method. +#[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993 +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct SendAll<'a, Si, St> +where + Si: ?Sized, + St: ?Sized + TryStream, +{ + sink: &'a mut Si, + stream: Fuse<&'a mut St>, + buffered: Option, +} + +impl fmt::Debug for SendAll<'_, Si, St> +where + Si: fmt::Debug + ?Sized, + St: fmt::Debug + ?Sized + TryStream, + St::Ok: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SendAll") + .field("sink", &self.sink) + .field("stream", &self.stream) + .field("buffered", &self.buffered) + .finish() + } +} + +// Pinning is never projected to any fields +impl Unpin for SendAll<'_, Si, St> +where + Si: Unpin + ?Sized, + St: TryStream + Unpin + ?Sized, +{ +} + +impl<'a, Si, St, Ok, Error> SendAll<'a, Si, St> +where + Si: Sink + Unpin + ?Sized, + St: TryStream + Stream + Unpin + ?Sized, +{ + pub(super) fn new(sink: &'a mut Si, stream: &'a mut St) -> Self { + Self { sink, stream: stream.fuse(), buffered: None } + } + + fn try_start_send( + &mut self, + cx: &mut Context<'_>, + item: St::Ok, + ) -> Poll> { + debug_assert!(self.buffered.is_none()); + match Pin::new(&mut self.sink).poll_ready(cx)? { + Poll::Ready(()) => Poll::Ready(Pin::new(&mut self.sink).start_send(item)), + Poll::Pending => { + self.buffered = Some(item); + Poll::Pending + } + } + } +} + +impl Future for SendAll<'_, Si, St> +where + Si: Sink + Unpin + ?Sized, + St: Stream> + Unpin + ?Sized, +{ + type Output = Result<(), Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = &mut *self; + // If we've got an item buffered already, we need to write it to the + // sink before we can do anything else + if let Some(item) = this.buffered.take() { + ready!(this.try_start_send(cx, item))? + } + + loop { + match this.stream.try_poll_next_unpin(cx)? { + Poll::Ready(Some(item)) => ready!(this.try_start_send(cx, item))?, + Poll::Ready(None) => { + ready!(Pin::new(&mut this.sink).poll_flush(cx))?; + return Poll::Ready(Ok(())); + } + Poll::Pending => { + ready!(Pin::new(&mut this.sink).poll_flush(cx))?; + return Poll::Pending; + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/unfold.rs b/utshell-0.5.0/vendor/futures-util/src/sink/unfold.rs new file mode 100644 index 00000000..dea1307b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/unfold.rs @@ -0,0 +1,89 @@ +use super::assert_sink; +use crate::unfold_state::UnfoldState; +use core::{future::Future, pin::Pin}; +use futures_core::ready; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink for the [`unfold`] function. + #[derive(Debug)] + #[must_use = "sinks do nothing unless polled"] + pub struct Unfold { + function: F, + #[pin] + state: UnfoldState, + } +} + +/// Create a sink from a function which processes one item at a time. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::sink::{self, SinkExt}; +/// +/// let unfold = sink::unfold(0, |mut sum, i: i32| { +/// async move { +/// sum += i; +/// eprintln!("{}", i); +/// Ok::<_, futures::never::Never>(sum) +/// } +/// }); +/// futures::pin_mut!(unfold); +/// unfold.send(5).await?; +/// # Ok::<(), futures::never::Never>(()) }).unwrap(); +/// ``` +pub fn unfold(init: T, function: F) -> Unfold +where + F: FnMut(T, Item) -> R, + R: Future>, +{ + assert_sink::(Unfold { function, state: UnfoldState::Value { value: init } }) +} + +impl Sink for Unfold +where + F: FnMut(T, Item) -> R, + R: Future>, +{ + type Error = E; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.poll_flush(cx) + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + let mut this = self.project(); + let future = match this.state.as_mut().take_value() { + Some(value) => (this.function)(value, item), + None => panic!("start_send called without poll_ready being called first"), + }; + this.state.set(UnfoldState::Future { future }); + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + Poll::Ready(if let Some(future) = this.state.as_mut().project_future() { + match ready!(future.poll(cx)) { + Ok(state) => { + this.state.set(UnfoldState::Value { value: state }); + Ok(()) + } + Err(err) => { + this.state.set(UnfoldState::Empty); + Err(err) + } + } + } else { + Ok(()) + }) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.poll_flush(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/with.rs b/utshell-0.5.0/vendor/futures-util/src/sink/with.rs new file mode 100644 index 00000000..86d3dcc7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/with.rs @@ -0,0 +1,134 @@ +use core::fmt; +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink for the [`with`](super::SinkExt::with) method. + #[must_use = "sinks do nothing unless polled"] + pub struct With { + #[pin] + sink: Si, + f: F, + #[pin] + state: Option, + _phantom: PhantomData Item>, + } +} + +impl fmt::Debug for With +where + Si: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("With").field("sink", &self.sink).field("state", &self.state).finish() + } +} + +impl With +where + Si: Sink, + F: FnMut(U) -> Fut, + Fut: Future, +{ + pub(super) fn new(sink: Si, f: F) -> Self + where + Fut: Future>, + E: From, + { + Self { state: None, sink, f, _phantom: PhantomData } + } +} + +impl Clone for With +where + Si: Clone, + F: Clone, + Fut: Clone, +{ + fn clone(&self) -> Self { + Self { + state: self.state.clone(), + sink: self.sink.clone(), + f: self.f.clone(), + _phantom: PhantomData, + } + } +} + +// Forwarding impl of Stream from the underlying sink +impl Stream for With +where + S: Stream + Sink, + F: FnMut(U) -> Fut, + Fut: Future, +{ + type Item = S::Item; + + delegate_stream!(sink); +} + +impl With +where + Si: Sink, + F: FnMut(U) -> Fut, + Fut: Future>, + E: From, +{ + delegate_access_inner!(sink, Si, ()); + + /// Completes the processing of previous item if any. + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + let item = match this.state.as_mut().as_pin_mut() { + None => return Poll::Ready(Ok(())), + Some(fut) => ready!(fut.poll(cx))?, + }; + this.state.set(None); + this.sink.start_send(item)?; + Poll::Ready(Ok(())) + } +} + +impl Sink for With +where + Si: Sink, + F: FnMut(U) -> Fut, + Fut: Future>, + E: From, +{ + type Error = E; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().poll(cx))?; + ready!(self.project().sink.poll_ready(cx)?); + Poll::Ready(Ok(())) + } + + fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> { + let mut this = self.project(); + + assert!(this.state.is_none()); + this.state.set(Some((this.f)(item))); + Ok(()) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().poll(cx))?; + ready!(self.project().sink.poll_flush(cx)?); + Poll::Ready(Ok(())) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().poll(cx))?; + ready!(self.project().sink.poll_close(cx)?); + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/sink/with_flat_map.rs b/utshell-0.5.0/vendor/futures-util/src/sink/with_flat_map.rs new file mode 100644 index 00000000..2ae877a2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/sink/with_flat_map.rs @@ -0,0 +1,127 @@ +use core::fmt; +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Sink for the [`with_flat_map`](super::SinkExt::with_flat_map) method. + #[must_use = "sinks do nothing unless polled"] + pub struct WithFlatMap { + #[pin] + sink: Si, + f: F, + #[pin] + stream: Option, + buffer: Option, + _marker: PhantomData, + } +} + +impl fmt::Debug for WithFlatMap +where + Si: fmt::Debug, + St: fmt::Debug, + Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("WithFlatMap") + .field("sink", &self.sink) + .field("stream", &self.stream) + .field("buffer", &self.buffer) + .finish() + } +} + +impl WithFlatMap +where + Si: Sink, + F: FnMut(U) -> St, + St: Stream>, +{ + pub(super) fn new(sink: Si, f: F) -> Self { + Self { sink, f, stream: None, buffer: None, _marker: PhantomData } + } + + delegate_access_inner!(sink, Si, ()); + + fn try_empty_stream(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if this.buffer.is_some() { + ready!(this.sink.as_mut().poll_ready(cx))?; + let item = this.buffer.take().unwrap(); + this.sink.as_mut().start_send(item)?; + } + if let Some(mut some_stream) = this.stream.as_mut().as_pin_mut() { + while let Some(item) = ready!(some_stream.as_mut().poll_next(cx)?) { + match this.sink.as_mut().poll_ready(cx)? { + Poll::Ready(()) => this.sink.as_mut().start_send(item)?, + Poll::Pending => { + *this.buffer = Some(item); + return Poll::Pending; + } + }; + } + } + this.stream.set(None); + Poll::Ready(Ok(())) + } +} + +// Forwarding impl of Stream from the underlying sink +impl Stream for WithFlatMap +where + S: Stream + Sink, + F: FnMut(U) -> St, + St: Stream>, +{ + type Item = S::Item; + + delegate_stream!(sink); +} + +impl FusedStream for WithFlatMap +where + S: FusedStream + Sink, + F: FnMut(U) -> St, + St: Stream>, +{ + fn is_terminated(&self) -> bool { + self.sink.is_terminated() + } +} + +impl Sink for WithFlatMap +where + Si: Sink, + F: FnMut(U) -> St, + St: Stream>, +{ + type Error = Si::Error; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.try_empty_stream(cx) + } + + fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> { + let mut this = self.project(); + + assert!(this.stream.is_none()); + this.stream.set(Some((this.f)(item))); + Ok(()) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().try_empty_stream(cx)?); + self.project().sink.poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.as_mut().try_empty_stream(cx)?); + self.project().sink.poll_close(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/abortable.rs b/utshell-0.5.0/vendor/futures-util/src/stream/abortable.rs new file mode 100644 index 00000000..1fea8958 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/abortable.rs @@ -0,0 +1,19 @@ +use super::assert_stream; +use crate::stream::{AbortHandle, Abortable}; +use crate::Stream; + +/// Creates a new `Abortable` stream and an `AbortHandle` which can be used to stop it. +/// +/// This function is a convenient (but less flexible) alternative to calling +/// `AbortHandle::new` and `Abortable::new` manually. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +pub fn abortable(stream: St) -> (Abortable, AbortHandle) +where + St: Stream, +{ + let (handle, reg) = AbortHandle::new_pair(); + let abortable = assert_stream::(Abortable::new(stream, reg)); + (abortable, handle) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/empty.rs b/utshell-0.5.0/vendor/futures-util/src/stream/empty.rs new file mode 100644 index 00000000..e4fd8732 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/empty.rs @@ -0,0 +1,45 @@ +use super::assert_stream; +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; + +/// Stream for the [`empty`] function. +#[derive(Debug)] +#[must_use = "streams do nothing unless polled"] +pub struct Empty { + _phantom: PhantomData, +} + +/// Creates a stream which contains no elements. +/// +/// The returned stream will always return `Ready(None)` when polled. +pub fn empty() -> Empty { + assert_stream::(Empty { _phantom: PhantomData }) +} + +impl Unpin for Empty {} + +impl FusedStream for Empty { + fn is_terminated(&self) -> bool { + true + } +} + +impl Stream for Empty { + type Item = T; + + fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(None) + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(0)) + } +} + +impl Clone for Empty { + fn clone(&self) -> Self { + empty() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/futures_ordered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/futures_ordered.rs new file mode 100644 index 00000000..2cc144e8 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/futures_ordered.rs @@ -0,0 +1,249 @@ +use crate::stream::{FuturesUnordered, StreamExt}; +use alloc::collections::binary_heap::{BinaryHeap, PeekMut}; +use core::cmp::Ordering; +use core::fmt::{self, Debug}; +use core::iter::FromIterator; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::{ + task::{Context, Poll}, + FusedStream, +}; +use pin_project_lite::pin_project; + +pin_project! { + #[must_use = "futures do nothing unless you `.await` or poll them"] + #[derive(Debug)] + struct OrderWrapper { + #[pin] + data: T, // A future or a future's output + // Use i64 for index since isize may overflow in 32-bit targets. + index: i64, + } +} + +impl PartialEq for OrderWrapper { + fn eq(&self, other: &Self) -> bool { + self.index == other.index + } +} + +impl Eq for OrderWrapper {} + +impl PartialOrd for OrderWrapper { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for OrderWrapper { + fn cmp(&self, other: &Self) -> Ordering { + // BinaryHeap is a max heap, so compare backwards here. + other.index.cmp(&self.index) + } +} + +impl Future for OrderWrapper +where + T: Future, +{ + type Output = OrderWrapper; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let index = self.index; + self.project().data.poll(cx).map(|output| OrderWrapper { data: output, index }) + } +} + +/// An unbounded queue of futures. +/// +/// This "combinator" is similar to [`FuturesUnordered`], but it imposes a FIFO +/// order on top of the set of futures. While futures in the set will race to +/// completion in parallel, results will only be returned in the order their +/// originating futures were added to the queue. +/// +/// Futures are pushed into this queue and their realized values are yielded in +/// order. This structure is optimized to manage a large number of futures. +/// Futures managed by [`FuturesOrdered`] will only be polled when they generate +/// notifications. This reduces the required amount of work needed to coordinate +/// large numbers of futures. +/// +/// When a [`FuturesOrdered`] is first created, it does not contain any futures. +/// Calling [`poll_next`](FuturesOrdered::poll_next) in this state will result +/// in [`Poll::Ready(None)`](Poll::Ready) to be returned. Futures are submitted +/// to the queue using [`push_back`](FuturesOrdered::push_back) (or +/// [`push_front`](FuturesOrdered::push_front)); however, the future will +/// **not** be polled at this point. [`FuturesOrdered`] will only poll managed +/// futures when [`FuturesOrdered::poll_next`] is called. As such, it +/// is important to call [`poll_next`](FuturesOrdered::poll_next) after pushing +/// new futures. +/// +/// If [`FuturesOrdered::poll_next`] returns [`Poll::Ready(None)`](Poll::Ready) +/// this means that the queue is currently not managing any futures. A future +/// may be submitted to the queue at a later time. At that point, a call to +/// [`FuturesOrdered::poll_next`] will either return the future's resolved value +/// **or** [`Poll::Pending`] if the future has not yet completed. When +/// multiple futures are submitted to the queue, [`FuturesOrdered::poll_next`] +/// will return [`Poll::Pending`] until the first future completes, even if +/// some of the later futures have already completed. +/// +/// Note that you can create a ready-made [`FuturesOrdered`] via the +/// [`collect`](Iterator::collect) method, or you can start with an empty queue +/// with the [`FuturesOrdered::new`] constructor. +/// +/// This type is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +#[must_use = "streams do nothing unless polled"] +pub struct FuturesOrdered { + in_progress_queue: FuturesUnordered>, + queued_outputs: BinaryHeap>, + next_incoming_index: i64, + next_outgoing_index: i64, +} + +impl Unpin for FuturesOrdered {} + +impl FuturesOrdered { + /// Constructs a new, empty `FuturesOrdered` + /// + /// The returned [`FuturesOrdered`] does not contain any futures and, in + /// this state, [`FuturesOrdered::poll_next`] will return + /// [`Poll::Ready(None)`](Poll::Ready). + pub fn new() -> Self { + Self { + in_progress_queue: FuturesUnordered::new(), + queued_outputs: BinaryHeap::new(), + next_incoming_index: 0, + next_outgoing_index: 0, + } + } + + /// Returns the number of futures contained in the queue. + /// + /// This represents the total number of in-flight futures, both + /// those currently processing and those that have completed but + /// which are waiting for earlier futures to complete. + pub fn len(&self) -> usize { + self.in_progress_queue.len() + self.queued_outputs.len() + } + + /// Returns `true` if the queue contains no futures + pub fn is_empty(&self) -> bool { + self.in_progress_queue.is_empty() && self.queued_outputs.is_empty() + } + + /// Push a future into the queue. + /// + /// This function submits the given future to the internal set for managing. + /// This function will not call [`poll`](Future::poll) on the submitted + /// future. The caller must ensure that [`FuturesOrdered::poll_next`] is + /// called in order to receive task notifications. + #[deprecated(note = "use `push_back` instead")] + pub fn push(&mut self, future: Fut) { + self.push_back(future); + } + + /// Pushes a future to the back of the queue. + /// + /// This function submits the given future to the internal set for managing. + /// This function will not call [`poll`](Future::poll) on the submitted + /// future. The caller must ensure that [`FuturesOrdered::poll_next`] is + /// called in order to receive task notifications. + pub fn push_back(&mut self, future: Fut) { + let wrapped = OrderWrapper { data: future, index: self.next_incoming_index }; + self.next_incoming_index += 1; + self.in_progress_queue.push(wrapped); + } + + /// Pushes a future to the front of the queue. + /// + /// This function submits the given future to the internal set for managing. + /// This function will not call [`poll`](Future::poll) on the submitted + /// future. The caller must ensure that [`FuturesOrdered::poll_next`] is + /// called in order to receive task notifications. This future will be + /// the next future to be returned complete. + pub fn push_front(&mut self, future: Fut) { + let wrapped = OrderWrapper { data: future, index: self.next_outgoing_index - 1 }; + self.next_outgoing_index -= 1; + self.in_progress_queue.push(wrapped); + } +} + +impl Default for FuturesOrdered { + fn default() -> Self { + Self::new() + } +} + +impl Stream for FuturesOrdered { + type Item = Fut::Output; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = &mut *self; + + // Check to see if we've already received the next value + if let Some(next_output) = this.queued_outputs.peek_mut() { + if next_output.index == this.next_outgoing_index { + this.next_outgoing_index += 1; + return Poll::Ready(Some(PeekMut::pop(next_output).data)); + } + } + + loop { + match ready!(this.in_progress_queue.poll_next_unpin(cx)) { + Some(output) => { + if output.index == this.next_outgoing_index { + this.next_outgoing_index += 1; + return Poll::Ready(Some(output.data)); + } else { + this.queued_outputs.push(output) + } + } + None => return Poll::Ready(None), + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl Debug for FuturesOrdered { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "FuturesOrdered {{ ... }}") + } +} + +impl FromIterator for FuturesOrdered { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + let acc = Self::new(); + iter.into_iter().fold(acc, |mut acc, item| { + acc.push_back(item); + acc + }) + } +} + +impl FusedStream for FuturesOrdered { + fn is_terminated(&self) -> bool { + self.in_progress_queue.is_terminated() && self.queued_outputs.is_empty() + } +} + +impl Extend for FuturesOrdered { + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + for item in iter { + self.push_back(item); + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/abort.rs b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/abort.rs new file mode 100644 index 00000000..1a42d243 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/abort.rs @@ -0,0 +1,12 @@ +pub(super) fn abort(s: &str) -> ! { + struct DoublePanic; + + impl Drop for DoublePanic { + fn drop(&mut self) { + panic!("panicking twice to abort the program"); + } + } + + let _bomb = DoublePanic; + panic!("{}", s); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/iter.rs b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/iter.rs new file mode 100644 index 00000000..20248c70 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/iter.rs @@ -0,0 +1,172 @@ +use super::task::Task; +use super::FuturesUnordered; +use core::marker::PhantomData; +use core::pin::Pin; +use core::ptr; +use core::sync::atomic::Ordering::Relaxed; + +/// Mutable iterator over all futures in the unordered set. +#[derive(Debug)] +pub struct IterPinMut<'a, Fut> { + pub(super) task: *const Task, + pub(super) len: usize, + pub(super) _marker: PhantomData<&'a mut FuturesUnordered>, +} + +/// Mutable iterator over all futures in the unordered set. +#[derive(Debug)] +pub struct IterMut<'a, Fut: Unpin>(pub(super) IterPinMut<'a, Fut>); + +/// Immutable iterator over all futures in the unordered set. +#[derive(Debug)] +pub struct IterPinRef<'a, Fut> { + pub(super) task: *const Task, + pub(super) len: usize, + pub(super) pending_next_all: *mut Task, + pub(super) _marker: PhantomData<&'a FuturesUnordered>, +} + +/// Immutable iterator over all the futures in the unordered set. +#[derive(Debug)] +pub struct Iter<'a, Fut: Unpin>(pub(super) IterPinRef<'a, Fut>); + +/// Owned iterator over all futures in the unordered set. +#[derive(Debug)] +pub struct IntoIter { + pub(super) len: usize, + pub(super) inner: FuturesUnordered, +} + +impl Iterator for IntoIter { + type Item = Fut; + + fn next(&mut self) -> Option { + // `head_all` can be accessed directly and we don't need to spin on + // `Task::next_all` since we have exclusive access to the set. + let task = self.inner.head_all.get_mut(); + + if (*task).is_null() { + return None; + } + + unsafe { + // Moving out of the future is safe because it is `Unpin` + let future = (*(**task).future.get()).take().unwrap(); + + // Mutable access to a previously shared `FuturesUnordered` implies + // that the other threads already released the object before the + // current thread acquired it, so relaxed ordering can be used and + // valid `next_all` checks can be skipped. + let next = (**task).next_all.load(Relaxed); + *task = next; + if !task.is_null() { + *(**task).prev_all.get() = ptr::null_mut(); + } + self.len -= 1; + Some(future) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl ExactSizeIterator for IntoIter {} + +impl<'a, Fut> Iterator for IterPinMut<'a, Fut> { + type Item = Pin<&'a mut Fut>; + + fn next(&mut self) -> Option { + if self.task.is_null() { + return None; + } + + unsafe { + let future = (*(*self.task).future.get()).as_mut().unwrap(); + + // Mutable access to a previously shared `FuturesUnordered` implies + // that the other threads already released the object before the + // current thread acquired it, so relaxed ordering can be used and + // valid `next_all` checks can be skipped. + let next = (*self.task).next_all.load(Relaxed); + self.task = next; + self.len -= 1; + Some(Pin::new_unchecked(future)) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl ExactSizeIterator for IterPinMut<'_, Fut> {} + +impl<'a, Fut: Unpin> Iterator for IterMut<'a, Fut> { + type Item = &'a mut Fut; + + fn next(&mut self) -> Option { + self.0.next().map(Pin::get_mut) + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl ExactSizeIterator for IterMut<'_, Fut> {} + +impl<'a, Fut> Iterator for IterPinRef<'a, Fut> { + type Item = Pin<&'a Fut>; + + fn next(&mut self) -> Option { + if self.task.is_null() { + return None; + } + + unsafe { + let future = (*(*self.task).future.get()).as_ref().unwrap(); + + // Relaxed ordering can be used since acquire ordering when + // `head_all` was initially read for this iterator implies acquire + // ordering for all previously inserted nodes (and we don't need to + // read `len_all` again for any other nodes). + let next = (*self.task).spin_next_all(self.pending_next_all, Relaxed); + self.task = next; + self.len -= 1; + Some(Pin::new_unchecked(future)) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl ExactSizeIterator for IterPinRef<'_, Fut> {} + +impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> { + type Item = &'a Fut; + + fn next(&mut self) -> Option { + self.0.next().map(Pin::get_ref) + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl ExactSizeIterator for Iter<'_, Fut> {} + +// SAFETY: we do nothing thread-local and there is no interior mutability, +// so the usual structural `Send`/`Sync` apply. +unsafe impl Send for IterPinRef<'_, Fut> {} +unsafe impl Sync for IterPinRef<'_, Fut> {} + +unsafe impl Send for IterPinMut<'_, Fut> {} +unsafe impl Sync for IterPinMut<'_, Fut> {} + +unsafe impl Send for IntoIter {} +unsafe impl Sync for IntoIter {} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/mod.rs b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/mod.rs new file mode 100644 index 00000000..dedf75de --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/mod.rs @@ -0,0 +1,652 @@ +//! An unbounded set of futures. +//! +//! This module is only available when the `std` or `alloc` feature of this +//! library is activated, and it is activated by default. + +use crate::task::AtomicWaker; +use alloc::sync::{Arc, Weak}; +use core::cell::UnsafeCell; +use core::fmt::{self, Debug}; +use core::iter::FromIterator; +use core::marker::PhantomData; +use core::mem; +use core::pin::Pin; +use core::ptr; +use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst}; +use core::sync::atomic::{AtomicBool, AtomicPtr}; +use futures_core::future::Future; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError}; + +mod abort; + +mod iter; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/102352 +pub use self::iter::{IntoIter, Iter, IterMut, IterPinMut, IterPinRef}; + +mod task; +use self::task::Task; + +mod ready_to_run_queue; +use self::ready_to_run_queue::{Dequeue, ReadyToRunQueue}; + +/// A set of futures which may complete in any order. +/// +/// See [`FuturesOrdered`](crate::stream::FuturesOrdered) for a version of this +/// type that preserves a FIFO order. +/// +/// This structure is optimized to manage a large number of futures. +/// Futures managed by [`FuturesUnordered`] will only be polled when they +/// generate wake-up notifications. This reduces the required amount of work +/// needed to poll large numbers of futures. +/// +/// [`FuturesUnordered`] can be filled by [`collect`](Iterator::collect)ing an +/// iterator of futures into a [`FuturesUnordered`], or by +/// [`push`](FuturesUnordered::push)ing futures onto an existing +/// [`FuturesUnordered`]. When new futures are added, +/// [`poll_next`](Stream::poll_next) must be called in order to begin receiving +/// wake-ups for new futures. +/// +/// Note that you can create a ready-made [`FuturesUnordered`] via the +/// [`collect`](Iterator::collect) method, or you can start with an empty set +/// with the [`FuturesUnordered::new`] constructor. +/// +/// This type is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +#[must_use = "streams do nothing unless polled"] +pub struct FuturesUnordered { + ready_to_run_queue: Arc>, + head_all: AtomicPtr>, + is_terminated: AtomicBool, +} + +unsafe impl Send for FuturesUnordered {} +unsafe impl Sync for FuturesUnordered {} +impl Unpin for FuturesUnordered {} + +impl Spawn for FuturesUnordered> { + fn spawn_obj(&self, future_obj: FutureObj<'static, ()>) -> Result<(), SpawnError> { + self.push(future_obj); + Ok(()) + } +} + +impl LocalSpawn for FuturesUnordered> { + fn spawn_local_obj(&self, future_obj: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { + self.push(future_obj); + Ok(()) + } +} + +// FuturesUnordered is implemented using two linked lists. One which links all +// futures managed by a `FuturesUnordered` and one that tracks futures that have +// been scheduled for polling. The first linked list allows for thread safe +// insertion of nodes at the head as well as forward iteration, but is otherwise +// not thread safe and is only accessed by the thread that owns the +// `FuturesUnordered` value for any other operations. The second linked list is +// an implementation of the intrusive MPSC queue algorithm described by +// 1024cores.net. +// +// When a future is submitted to the set, a task is allocated and inserted in +// both linked lists. The next call to `poll_next` will (eventually) see this +// task and call `poll` on the future. +// +// Before a managed future is polled, the current context's waker is replaced +// with one that is aware of the specific future being run. This ensures that +// wake-up notifications generated by that specific future are visible to +// `FuturesUnordered`. When a wake-up notification is received, the task is +// inserted into the ready to run queue, so that its future can be polled later. +// +// Each task is wrapped in an `Arc` and thereby atomically reference counted. +// Also, each task contains an `AtomicBool` which acts as a flag that indicates +// whether the task is currently inserted in the atomic queue. When a wake-up +// notification is received, the task will only be inserted into the ready to +// run queue if it isn't inserted already. + +impl Default for FuturesUnordered { + fn default() -> Self { + Self::new() + } +} + +impl FuturesUnordered { + /// Constructs a new, empty [`FuturesUnordered`]. + /// + /// The returned [`FuturesUnordered`] does not contain any futures. + /// In this state, [`FuturesUnordered::poll_next`](Stream::poll_next) will + /// return [`Poll::Ready(None)`](Poll::Ready). + pub fn new() -> Self { + let stub = Arc::new(Task { + future: UnsafeCell::new(None), + next_all: AtomicPtr::new(ptr::null_mut()), + prev_all: UnsafeCell::new(ptr::null()), + len_all: UnsafeCell::new(0), + next_ready_to_run: AtomicPtr::new(ptr::null_mut()), + queued: AtomicBool::new(true), + ready_to_run_queue: Weak::new(), + woken: AtomicBool::new(false), + }); + let stub_ptr = Arc::as_ptr(&stub); + let ready_to_run_queue = Arc::new(ReadyToRunQueue { + waker: AtomicWaker::new(), + head: AtomicPtr::new(stub_ptr as *mut _), + tail: UnsafeCell::new(stub_ptr), + stub, + }); + + Self { + head_all: AtomicPtr::new(ptr::null_mut()), + ready_to_run_queue, + is_terminated: AtomicBool::new(false), + } + } + + /// Returns the number of futures contained in the set. + /// + /// This represents the total number of in-flight futures. + pub fn len(&self) -> usize { + let (_, len) = self.atomic_load_head_and_len_all(); + len + } + + /// Returns `true` if the set contains no futures. + pub fn is_empty(&self) -> bool { + // Relaxed ordering can be used here since we don't need to read from + // the head pointer, only check whether it is null. + self.head_all.load(Relaxed).is_null() + } + + /// Push a future into the set. + /// + /// This method adds the given future to the set. This method will not + /// call [`poll`](core::future::Future::poll) on the submitted future. The caller must + /// ensure that [`FuturesUnordered::poll_next`](Stream::poll_next) is called + /// in order to receive wake-up notifications for the given future. + pub fn push(&self, future: Fut) { + let task = Arc::new(Task { + future: UnsafeCell::new(Some(future)), + next_all: AtomicPtr::new(self.pending_next_all()), + prev_all: UnsafeCell::new(ptr::null_mut()), + len_all: UnsafeCell::new(0), + next_ready_to_run: AtomicPtr::new(ptr::null_mut()), + queued: AtomicBool::new(true), + ready_to_run_queue: Arc::downgrade(&self.ready_to_run_queue), + woken: AtomicBool::new(false), + }); + + // Reset the `is_terminated` flag if we've previously marked ourselves + // as terminated. + self.is_terminated.store(false, Relaxed); + + // Right now our task has a strong reference count of 1. We transfer + // ownership of this reference count to our internal linked list + // and we'll reclaim ownership through the `unlink` method below. + let ptr = self.link(task); + + // We'll need to get the future "into the system" to start tracking it, + // e.g. getting its wake-up notifications going to us tracking which + // futures are ready. To do that we unconditionally enqueue it for + // polling here. + self.ready_to_run_queue.enqueue(ptr); + } + + /// Returns an iterator that allows inspecting each future in the set. + pub fn iter(&self) -> Iter<'_, Fut> + where + Fut: Unpin, + { + Iter(Pin::new(self).iter_pin_ref()) + } + + /// Returns an iterator that allows inspecting each future in the set. + pub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> { + let (task, len) = self.atomic_load_head_and_len_all(); + let pending_next_all = self.pending_next_all(); + + IterPinRef { task, len, pending_next_all, _marker: PhantomData } + } + + /// Returns an iterator that allows modifying each future in the set. + pub fn iter_mut(&mut self) -> IterMut<'_, Fut> + where + Fut: Unpin, + { + IterMut(Pin::new(self).iter_pin_mut()) + } + + /// Returns an iterator that allows modifying each future in the set. + pub fn iter_pin_mut(mut self: Pin<&mut Self>) -> IterPinMut<'_, Fut> { + // `head_all` can be accessed directly and we don't need to spin on + // `Task::next_all` since we have exclusive access to the set. + let task = *self.head_all.get_mut(); + let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } }; + + IterPinMut { task, len, _marker: PhantomData } + } + + /// Returns the current head node and number of futures in the list of all + /// futures within a context where access is shared with other threads + /// (mostly for use with the `len` and `iter_pin_ref` methods). + fn atomic_load_head_and_len_all(&self) -> (*const Task, usize) { + let task = self.head_all.load(Acquire); + let len = if task.is_null() { + 0 + } else { + unsafe { + (*task).spin_next_all(self.pending_next_all(), Acquire); + *(*task).len_all.get() + } + }; + + (task, len) + } + + /// Releases the task. It destroys the future inside and either drops + /// the `Arc` or transfers ownership to the ready to run queue. + /// The task this method is called on must have been unlinked before. + fn release_task(&mut self, task: Arc>) { + // `release_task` must only be called on unlinked tasks + debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all()); + unsafe { + debug_assert!((*task.prev_all.get()).is_null()); + } + + // The future is done, try to reset the queued flag. This will prevent + // `wake` from doing any work in the future + let prev = task.queued.swap(true, SeqCst); + + // Drop the future, even if it hasn't finished yet. This is safe + // because we're dropping the future on the thread that owns + // `FuturesUnordered`, which correctly tracks `Fut`'s lifetimes and + // such. + unsafe { + // Set to `None` rather than `take()`ing to prevent moving the + // future. + *task.future.get() = None; + } + + // If the queued flag was previously set, then it means that this task + // is still in our internal ready to run queue. We then transfer + // ownership of our reference count to the ready to run queue, and it'll + // come along and free it later, noticing that the future is `None`. + // + // If, however, the queued flag was *not* set then we're safe to + // release our reference count on the task. The queued flag was set + // above so all future `enqueue` operations will not actually + // enqueue the task, so our task will never see the ready to run queue + // again. The task itself will be deallocated once all reference counts + // have been dropped elsewhere by the various wakers that contain it. + if prev { + mem::forget(task); + } + } + + /// Insert a new task into the internal linked list. + fn link(&self, task: Arc>) -> *const Task { + // `next_all` should already be reset to the pending state before this + // function is called. + debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all()); + let ptr = Arc::into_raw(task); + + // Atomically swap out the old head node to get the node that should be + // assigned to `next_all`. + let next = self.head_all.swap(ptr as *mut _, AcqRel); + + unsafe { + // Store the new list length in the new node. + let new_len = if next.is_null() { + 1 + } else { + // Make sure `next_all` has been written to signal that it is + // safe to read `len_all`. + (*next).spin_next_all(self.pending_next_all(), Acquire); + *(*next).len_all.get() + 1 + }; + *(*ptr).len_all.get() = new_len; + + // Write the old head as the next node pointer, signaling to other + // threads that `len_all` and `next_all` are ready to read. + (*ptr).next_all.store(next, Release); + + // `prev_all` updates don't need to be synchronized, as the field is + // only ever used after exclusive access has been acquired. + if !next.is_null() { + *(*next).prev_all.get() = ptr; + } + } + + ptr + } + + /// Remove the task from the linked list tracking all tasks currently + /// managed by `FuturesUnordered`. + /// This method is unsafe because it has be guaranteed that `task` is a + /// valid pointer. + unsafe fn unlink(&mut self, task: *const Task) -> Arc> { + // Compute the new list length now in case we're removing the head node + // and won't be able to retrieve the correct length later. + let head = *self.head_all.get_mut(); + debug_assert!(!head.is_null()); + let new_len = *(*head).len_all.get() - 1; + + let task = Arc::from_raw(task); + let next = task.next_all.load(Relaxed); + let prev = *task.prev_all.get(); + task.next_all.store(self.pending_next_all(), Relaxed); + *task.prev_all.get() = ptr::null_mut(); + + if !next.is_null() { + *(*next).prev_all.get() = prev; + } + + if !prev.is_null() { + (*prev).next_all.store(next, Relaxed); + } else { + *self.head_all.get_mut() = next; + } + + // Store the new list length in the head node. + let head = *self.head_all.get_mut(); + if !head.is_null() { + *(*head).len_all.get() = new_len; + } + + task + } + + /// Returns the reserved value for `Task::next_all` to indicate a pending + /// assignment from the thread that inserted the task. + /// + /// `FuturesUnordered::link` needs to update `Task` pointers in an order + /// that ensures any iterators created on other threads can correctly + /// traverse the entire `Task` list using the chain of `next_all` pointers. + /// This could be solved with a compare-exchange loop that stores the + /// current `head_all` in `next_all` and swaps out `head_all` with the new + /// `Task` pointer if the head hasn't already changed. Under heavy thread + /// contention, this compare-exchange loop could become costly. + /// + /// An alternative is to initialize `next_all` to a reserved pending state + /// first, perform an atomic swap on `head_all`, and finally update + /// `next_all` with the old head node. Iterators will then either see the + /// pending state value or the correct next node pointer, and can reload + /// `next_all` as needed until the correct value is loaded. The number of + /// retries needed (if any) would be small and will always be finite, so + /// this should generally perform better than the compare-exchange loop. + /// + /// A valid `Task` pointer in the `head_all` list is guaranteed to never be + /// this value, so it is safe to use as a reserved value until the correct + /// value can be written. + fn pending_next_all(&self) -> *mut Task { + // The `ReadyToRunQueue` stub is never inserted into the `head_all` + // list, and its pointer value will remain valid for the lifetime of + // this `FuturesUnordered`, so we can make use of its value here. + Arc::as_ptr(&self.ready_to_run_queue.stub) as *mut _ + } +} + +impl Stream for FuturesUnordered { + type Item = Fut::Output; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let len = self.len(); + + // Keep track of how many child futures we have polled, + // in case we want to forcibly yield. + let mut polled = 0; + let mut yielded = 0; + + // Ensure `parent` is correctly set. + self.ready_to_run_queue.waker.register(cx.waker()); + + loop { + // Safety: &mut self guarantees the mutual exclusion `dequeue` + // expects + let task = match unsafe { self.ready_to_run_queue.dequeue() } { + Dequeue::Empty => { + if self.is_empty() { + // We can only consider ourselves terminated once we + // have yielded a `None` + *self.is_terminated.get_mut() = true; + return Poll::Ready(None); + } else { + return Poll::Pending; + } + } + Dequeue::Inconsistent => { + // At this point, it may be worth yielding the thread & + // spinning a few times... but for now, just yield using the + // task system. + cx.waker().wake_by_ref(); + return Poll::Pending; + } + Dequeue::Data(task) => task, + }; + + debug_assert!(task != self.ready_to_run_queue.stub()); + + // Safety: + // - `task` is a valid pointer. + // - We are the only thread that accesses the `UnsafeCell` that + // contains the future + let future = match unsafe { &mut *(*task).future.get() } { + Some(future) => future, + + // If the future has already gone away then we're just + // cleaning out this task. See the comment in + // `release_task` for more information, but we're basically + // just taking ownership of our reference count here. + None => { + // This case only happens when `release_task` was called + // for this task before and couldn't drop the task + // because it was already enqueued in the ready to run + // queue. + + // Safety: `task` is a valid pointer + let task = unsafe { Arc::from_raw(task) }; + + // Double check that the call to `release_task` really + // happened. Calling it required the task to be unlinked. + debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all()); + unsafe { + debug_assert!((*task.prev_all.get()).is_null()); + } + continue; + } + }; + + // Safety: `task` is a valid pointer + let task = unsafe { self.unlink(task) }; + + // Unset queued flag: This must be done before polling to ensure + // that the future's task gets rescheduled if it sends a wake-up + // notification **during** the call to `poll`. + let prev = task.queued.swap(false, SeqCst); + assert!(prev); + + // We're going to need to be very careful if the `poll` + // method below panics. We need to (a) not leak memory and + // (b) ensure that we still don't have any use-after-frees. To + // manage this we do a few things: + // + // * A "bomb" is created which if dropped abnormally will call + // `release_task`. That way we'll be sure the memory management + // of the `task` is managed correctly. In particular + // `release_task` will drop the future. This ensures that it is + // dropped on this thread and not accidentally on a different + // thread (bad). + // * We unlink the task from our internal queue to preemptively + // assume it'll panic, in which case we'll want to discard it + // regardless. + struct Bomb<'a, Fut> { + queue: &'a mut FuturesUnordered, + task: Option>>, + } + + impl Drop for Bomb<'_, Fut> { + fn drop(&mut self) { + if let Some(task) = self.task.take() { + self.queue.release_task(task); + } + } + } + + let mut bomb = Bomb { task: Some(task), queue: &mut *self }; + + // Poll the underlying future with the appropriate waker + // implementation. This is where a large bit of the unsafety + // starts to stem from internally. The waker is basically just + // our `Arc>` and can schedule the future for polling by + // enqueuing itself in the ready to run queue. + // + // Critically though `Task` won't actually access `Fut`, the + // future, while it's floating around inside of wakers. + // These structs will basically just use `Fut` to size + // the internal allocation, appropriately accessing fields and + // deallocating the task if need be. + let res = { + let task = bomb.task.as_ref().unwrap(); + // We are only interested in whether the future is awoken before it + // finishes polling, so reset the flag here. + task.woken.store(false, Relaxed); + let waker = Task::waker_ref(task); + let mut cx = Context::from_waker(&waker); + + // Safety: We won't move the future ever again + let future = unsafe { Pin::new_unchecked(future) }; + + future.poll(&mut cx) + }; + polled += 1; + + match res { + Poll::Pending => { + let task = bomb.task.take().unwrap(); + // If the future was awoken during polling, we assume + // the future wanted to explicitly yield. + yielded += task.woken.load(Relaxed) as usize; + bomb.queue.link(task); + + // If a future yields, we respect it and yield here. + // If all futures have been polled, we also yield here to + // avoid starving other tasks waiting on the executor. + // (polling the same future twice per iteration may cause + // the problem: https://github.com/rust-lang/futures-rs/pull/2333) + if yielded >= 2 || polled == len { + cx.waker().wake_by_ref(); + return Poll::Pending; + } + continue; + } + Poll::Ready(output) => return Poll::Ready(Some(output)), + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +impl Debug for FuturesUnordered { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "FuturesUnordered {{ ... }}") + } +} + +impl FuturesUnordered { + /// Clears the set, removing all futures. + pub fn clear(&mut self) { + *self = Self::new(); + } +} + +impl Drop for FuturesUnordered { + fn drop(&mut self) { + // When a `FuturesUnordered` is dropped we want to drop all futures + // associated with it. At the same time though there may be tons of + // wakers flying around which contain `Task` references + // inside them. We'll let those naturally get deallocated. + while !self.head_all.get_mut().is_null() { + let head = *self.head_all.get_mut(); + let task = unsafe { self.unlink(head) }; + self.release_task(task); + } + + // Note that at this point we could still have a bunch of tasks in the + // ready to run queue. None of those tasks, however, have futures + // associated with them so they're safe to destroy on any thread. At + // this point the `FuturesUnordered` struct, the owner of the one strong + // reference to the ready to run queue will drop the strong reference. + // At that point whichever thread releases the strong refcount last (be + // it this thread or some other thread as part of an `upgrade`) will + // clear out the ready to run queue and free all remaining tasks. + // + // While that freeing operation isn't guaranteed to happen here, it's + // guaranteed to happen "promptly" as no more "blocking work" will + // happen while there's a strong refcount held. + } +} + +impl<'a, Fut: Unpin> IntoIterator for &'a FuturesUnordered { + type Item = &'a Fut; + type IntoIter = Iter<'a, Fut>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a, Fut: Unpin> IntoIterator for &'a mut FuturesUnordered { + type Item = &'a mut Fut; + type IntoIter = IterMut<'a, Fut>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +impl IntoIterator for FuturesUnordered { + type Item = Fut; + type IntoIter = IntoIter; + + fn into_iter(mut self) -> Self::IntoIter { + // `head_all` can be accessed directly and we don't need to spin on + // `Task::next_all` since we have exclusive access to the set. + let task = *self.head_all.get_mut(); + let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } }; + + IntoIter { len, inner: self } + } +} + +impl FromIterator for FuturesUnordered { + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + let acc = Self::new(); + iter.into_iter().fold(acc, |acc, item| { + acc.push(item); + acc + }) + } +} + +impl FusedStream for FuturesUnordered { + fn is_terminated(&self) -> bool { + self.is_terminated.load(Relaxed) + } +} + +impl Extend for FuturesUnordered { + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + for item in iter { + self.push(item); + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs new file mode 100644 index 00000000..a924935d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs @@ -0,0 +1,109 @@ +use crate::task::AtomicWaker; +use alloc::sync::Arc; +use core::cell::UnsafeCell; +use core::ptr; +use core::sync::atomic::AtomicPtr; +use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release}; + +use super::abort::abort; +use super::task::Task; + +pub(super) enum Dequeue { + Data(*const Task), + Empty, + Inconsistent, +} + +pub(super) struct ReadyToRunQueue { + // The waker of the task using `FuturesUnordered`. + pub(super) waker: AtomicWaker, + + // Head/tail of the readiness queue + pub(super) head: AtomicPtr>, + pub(super) tail: UnsafeCell<*const Task>, + pub(super) stub: Arc>, +} + +/// An MPSC queue into which the tasks containing the futures are inserted +/// whenever the future inside is scheduled for polling. +impl ReadyToRunQueue { + /// The enqueue function from the 1024cores intrusive MPSC queue algorithm. + pub(super) fn enqueue(&self, task: *const Task) { + unsafe { + debug_assert!((*task).queued.load(Relaxed)); + + // This action does not require any coordination + (*task).next_ready_to_run.store(ptr::null_mut(), Relaxed); + + // Note that these atomic orderings come from 1024cores + let task = task as *mut _; + let prev = self.head.swap(task, AcqRel); + (*prev).next_ready_to_run.store(task, Release); + } + } + + /// The dequeue function from the 1024cores intrusive MPSC queue algorithm + /// + /// Note that this is unsafe as it required mutual exclusion (only one + /// thread can call this) to be guaranteed elsewhere. + pub(super) unsafe fn dequeue(&self) -> Dequeue { + let mut tail = *self.tail.get(); + let mut next = (*tail).next_ready_to_run.load(Acquire); + + if tail == self.stub() { + if next.is_null() { + return Dequeue::Empty; + } + + *self.tail.get() = next; + tail = next; + next = (*next).next_ready_to_run.load(Acquire); + } + + if !next.is_null() { + *self.tail.get() = next; + debug_assert!(tail != self.stub()); + return Dequeue::Data(tail); + } + + if self.head.load(Acquire) as *const _ != tail { + return Dequeue::Inconsistent; + } + + self.enqueue(self.stub()); + + next = (*tail).next_ready_to_run.load(Acquire); + + if !next.is_null() { + *self.tail.get() = next; + return Dequeue::Data(tail); + } + + Dequeue::Inconsistent + } + + pub(super) fn stub(&self) -> *const Task { + Arc::as_ptr(&self.stub) + } +} + +impl Drop for ReadyToRunQueue { + fn drop(&mut self) { + // Once we're in the destructor for `Inner` we need to clear out + // the ready to run queue of tasks if there's anything left in there. + // + // Note that each task has a strong reference count associated with it + // which is owned by the ready to run queue. All tasks should have had + // their futures dropped already by the `FuturesUnordered` destructor + // above, so we're just pulling out tasks and dropping their refcounts. + unsafe { + loop { + match self.dequeue() { + Dequeue::Empty => break, + Dequeue::Inconsistent => abort("inconsistent in drop"), + Dequeue::Data(ptr) => drop(Arc::from_raw(ptr)), + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/task.rs b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/task.rs new file mode 100644 index 00000000..ec2114ef --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/futures_unordered/task.rs @@ -0,0 +1,125 @@ +use alloc::sync::{Arc, Weak}; +use core::cell::UnsafeCell; +use core::sync::atomic::Ordering::{self, Relaxed, SeqCst}; +use core::sync::atomic::{AtomicBool, AtomicPtr}; + +use super::abort::abort; +use super::ReadyToRunQueue; +use crate::task::{waker_ref, ArcWake, WakerRef}; + +pub(super) struct Task { + // The future + pub(super) future: UnsafeCell>, + + // Next pointer for linked list tracking all active tasks (use + // `spin_next_all` to read when access is shared across threads) + pub(super) next_all: AtomicPtr>, + + // Previous task in linked list tracking all active tasks + pub(super) prev_all: UnsafeCell<*const Task>, + + // Length of the linked list tracking all active tasks when this node was + // inserted (use `spin_next_all` to synchronize before reading when access + // is shared across threads) + pub(super) len_all: UnsafeCell, + + // Next pointer in ready to run queue + pub(super) next_ready_to_run: AtomicPtr>, + + // Queue that we'll be enqueued to when woken + pub(super) ready_to_run_queue: Weak>, + + // Whether or not this task is currently in the ready to run queue + pub(super) queued: AtomicBool, + + // Whether the future was awoken during polling + // It is possible for this flag to be set to true after the polling, + // but it will be ignored. + pub(super) woken: AtomicBool, +} + +// `Task` can be sent across threads safely because it ensures that +// the underlying `Fut` type isn't touched from any of its methods. +// +// The parent (`super`) module is trusted not to access `future` +// across different threads. +unsafe impl Send for Task {} +unsafe impl Sync for Task {} + +impl ArcWake for Task { + fn wake_by_ref(arc_self: &Arc) { + let inner = match arc_self.ready_to_run_queue.upgrade() { + Some(inner) => inner, + None => return, + }; + + arc_self.woken.store(true, Relaxed); + + // It's our job to enqueue this task it into the ready to run queue. To + // do this we set the `queued` flag, and if successful we then do the + // actual queueing operation, ensuring that we're only queued once. + // + // Once the task is inserted call `wake` to notify the parent task, + // as it'll want to come along and run our task later. + // + // Note that we don't change the reference count of the task here, + // we merely enqueue the raw pointer. The `FuturesUnordered` + // implementation guarantees that if we set the `queued` flag that + // there's a reference count held by the main `FuturesUnordered` queue + // still. + let prev = arc_self.queued.swap(true, SeqCst); + if !prev { + inner.enqueue(Arc::as_ptr(arc_self)); + inner.waker.wake(); + } + } +} + +impl Task { + /// Returns a waker reference for this task without cloning the Arc. + pub(super) fn waker_ref(this: &Arc) -> WakerRef<'_> { + waker_ref(this) + } + + /// Spins until `next_all` is no longer set to `pending_next_all`. + /// + /// The temporary `pending_next_all` value is typically overwritten fairly + /// quickly after a node is inserted into the list of all futures, so this + /// should rarely spin much. + /// + /// When it returns, the correct `next_all` value is returned. + /// + /// `Relaxed` or `Acquire` ordering can be used. `Acquire` ordering must be + /// used before `len_all` can be safely read. + #[inline] + pub(super) fn spin_next_all( + &self, + pending_next_all: *mut Self, + ordering: Ordering, + ) -> *const Self { + loop { + let next = self.next_all.load(ordering); + if next != pending_next_all { + return next; + } + } + } +} + +impl Drop for Task { + fn drop(&mut self) { + // Since `Task` is sent across all threads for any lifetime, + // regardless of `Fut`, we, to guarantee memory safety, can't actually + // touch `Fut` at any time except when we have a reference to the + // `FuturesUnordered` itself . + // + // Consequently it *should* be the case that we always drop futures from + // the `FuturesUnordered` instance. This is a bomb, just in case there's + // a bug in that logic. + unsafe { + if (*self.future.get()).is_some() { + abort("future still here when dropping"); + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/iter.rs b/utshell-0.5.0/vendor/futures-util/src/stream/iter.rs new file mode 100644 index 00000000..20471c2e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/iter.rs @@ -0,0 +1,49 @@ +use super::assert_stream; +use core::pin::Pin; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; + +/// Stream for the [`iter`] function. +#[derive(Debug, Clone)] +#[must_use = "streams do nothing unless polled"] +pub struct Iter { + iter: I, +} + +impl Unpin for Iter {} + +/// Converts an `Iterator` into a `Stream` which is always ready +/// to yield the next value. +/// +/// Iterators in Rust don't express the ability to block, so this adapter +/// simply always calls `iter.next()` and returns that. +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// +/// let stream = stream::iter(vec![17, 19]); +/// assert_eq!(vec![17, 19], stream.collect::>().await); +/// # }); +/// ``` +pub fn iter(i: I) -> Iter +where + I: IntoIterator, +{ + assert_stream::(Iter { iter: i.into_iter() }) +} + +impl Stream for Iter +where + I: Iterator, +{ + type Item = I::Item; + + fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(self.iter.next()) + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/mod.rs b/utshell-0.5.0/vendor/futures-util/src/stream/mod.rs new file mode 100644 index 00000000..2438e58b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/mod.rs @@ -0,0 +1,148 @@ +//! Asynchronous streams. +//! +//! This module contains: +//! +//! - The [`Stream`] trait, for objects that can asynchronously produce a +//! sequence of values. +//! - The [`StreamExt`] and [`TryStreamExt`] trait, which provides adapters for +//! chaining and composing streams. +//! - Top-level stream constructors like [`iter`](iter()) which creates a +//! stream from an iterator. + +#[cfg(feature = "alloc")] +pub use futures_core::stream::{BoxStream, LocalBoxStream}; +pub use futures_core::stream::{FusedStream, Stream, TryStream}; + +// Extension traits and combinators + +#[allow(clippy::module_inception)] +mod stream; +pub use self::stream::{ + All, Any, Chain, Collect, Concat, Count, Cycle, Enumerate, Filter, FilterMap, FlatMap, Flatten, + Fold, ForEach, Fuse, Inspect, Map, Next, NextIf, NextIfEq, Peek, PeekMut, Peekable, Scan, + SelectNextSome, Skip, SkipWhile, StreamExt, StreamFuture, Take, TakeUntil, TakeWhile, Then, + Unzip, Zip, +}; + +#[cfg(feature = "std")] +pub use self::stream::CatchUnwind; + +#[cfg(feature = "alloc")] +pub use self::stream::Chunks; + +#[cfg(feature = "alloc")] +pub use self::stream::ReadyChunks; + +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub use self::stream::Forward; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use self::stream::{ + BufferUnordered, Buffered, FlatMapUnordered, FlattenUnordered, ForEachConcurrent, +}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +#[cfg(feature = "alloc")] +pub use self::stream::{ReuniteError, SplitSink, SplitStream}; + +mod try_stream; +pub use self::try_stream::{ + try_unfold, AndThen, ErrInto, InspectErr, InspectOk, IntoStream, MapErr, MapOk, OrElse, TryAll, + TryAny, TryCollect, TryConcat, TryFilter, TryFilterMap, TryFlatten, TryFold, TryForEach, + TryNext, TrySkipWhile, TryStreamExt, TryTakeWhile, TryUnfold, +}; + +#[cfg(feature = "io")] +#[cfg_attr(docsrs, doc(cfg(feature = "io")))] +#[cfg(feature = "std")] +pub use self::try_stream::IntoAsyncRead; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use self::try_stream::{ + TryBufferUnordered, TryBuffered, TryFlattenUnordered, TryForEachConcurrent, +}; + +#[cfg(feature = "alloc")] +pub use self::try_stream::{TryChunks, TryChunksError, TryReadyChunks, TryReadyChunksError}; + +// Primitive streams + +mod iter; +pub use self::iter::{iter, Iter}; + +mod repeat; +pub use self::repeat::{repeat, Repeat}; + +mod repeat_with; +pub use self::repeat_with::{repeat_with, RepeatWith}; + +mod empty; +pub use self::empty::{empty, Empty}; + +mod once; +pub use self::once::{once, Once}; + +mod pending; +pub use self::pending::{pending, Pending}; + +mod poll_fn; +pub use self::poll_fn::{poll_fn, PollFn}; + +mod poll_immediate; +pub use self::poll_immediate::{poll_immediate, PollImmediate}; + +mod select; +pub use self::select::{select, Select}; + +mod select_with_strategy; +pub use self::select_with_strategy::{select_with_strategy, PollNext, SelectWithStrategy}; + +mod unfold; +pub use self::unfold::{unfold, Unfold}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod futures_ordered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use self::futures_ordered::FuturesOrdered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub mod futures_unordered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use self::futures_unordered::FuturesUnordered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub mod select_all; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use self::select_all::{select_all, SelectAll}; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod abortable; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted}; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use abortable::abortable; + +// Just a helper function to ensure the streams we're returning all have the +// right implementations. +pub(crate) fn assert_stream(stream: S) -> S +where + S: Stream, +{ + stream +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/once.rs b/utshell-0.5.0/vendor/futures-util/src/stream/once.rs new file mode 100644 index 00000000..ee21c8b5 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/once.rs @@ -0,0 +1,67 @@ +use super::assert_stream; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +/// Creates a stream of a single element. +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// +/// let stream = stream::once(async { 17 }); +/// let collected = stream.collect::>().await; +/// assert_eq!(collected, vec![17]); +/// # }); +/// ``` +pub fn once(future: Fut) -> Once { + assert_stream::(Once::new(future)) +} + +pin_project! { + /// A stream which emits single element and then EOF. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Once { + #[pin] + future: Option + } +} + +impl Once { + pub(crate) fn new(future: Fut) -> Self { + Self { future: Some(future) } + } +} + +impl Stream for Once { + type Item = Fut::Output; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + let v = match this.future.as_mut().as_pin_mut() { + Some(fut) => ready!(fut.poll(cx)), + None => return Poll::Ready(None), + }; + + this.future.set(None); + Poll::Ready(Some(v)) + } + + fn size_hint(&self) -> (usize, Option) { + if self.future.is_some() { + (1, Some(1)) + } else { + (0, Some(0)) + } + } +} + +impl FusedStream for Once { + fn is_terminated(&self) -> bool { + self.future.is_none() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/pending.rs b/utshell-0.5.0/vendor/futures-util/src/stream/pending.rs new file mode 100644 index 00000000..d7030ff3 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/pending.rs @@ -0,0 +1,45 @@ +use super::assert_stream; +use core::marker; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; + +/// Stream for the [`pending()`] function. +#[derive(Debug)] +#[must_use = "streams do nothing unless polled"] +pub struct Pending { + _data: marker::PhantomData, +} + +/// Creates a stream which never returns any elements. +/// +/// The returned stream will always return `Pending` when polled. +pub fn pending() -> Pending { + assert_stream::(Pending { _data: marker::PhantomData }) +} + +impl Unpin for Pending {} + +impl FusedStream for Pending { + fn is_terminated(&self) -> bool { + true + } +} + +impl Stream for Pending { + type Item = T; + + fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Pending + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(0)) + } +} + +impl Clone for Pending { + fn clone(&self) -> Self { + pending() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/poll_fn.rs b/utshell-0.5.0/vendor/futures-util/src/stream/poll_fn.rs new file mode 100644 index 00000000..b9bd7d16 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/poll_fn.rs @@ -0,0 +1,57 @@ +//! Definition of the `PollFn` combinator + +use super::assert_stream; +use core::fmt; +use core::pin::Pin; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; + +/// Stream for the [`poll_fn`] function. +#[must_use = "streams do nothing unless polled"] +pub struct PollFn { + f: F, +} + +impl Unpin for PollFn {} + +impl fmt::Debug for PollFn { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PollFn").finish() + } +} + +/// Creates a new stream wrapping a function returning `Poll>`. +/// +/// Polling the returned stream calls the wrapped function. +/// +/// # Examples +/// +/// ``` +/// use futures::stream::poll_fn; +/// use futures::task::Poll; +/// +/// let mut counter = 1usize; +/// +/// let read_stream = poll_fn(move |_| -> Poll> { +/// if counter == 0 { return Poll::Ready(None); } +/// counter -= 1; +/// Poll::Ready(Some("Hello, World!".to_owned())) +/// }); +/// ``` +pub fn poll_fn(f: F) -> PollFn +where + F: FnMut(&mut Context<'_>) -> Poll>, +{ + assert_stream::(PollFn { f }) +} + +impl Stream for PollFn +where + F: FnMut(&mut Context<'_>) -> Poll>, +{ + type Item = T; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + (&mut self.f)(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/poll_immediate.rs b/utshell-0.5.0/vendor/futures-util/src/stream/poll_immediate.rs new file mode 100644 index 00000000..c7e8a5b3 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/poll_immediate.rs @@ -0,0 +1,80 @@ +use core::pin::Pin; +use futures_core::task::{Context, Poll}; +use futures_core::Stream; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [poll_immediate](poll_immediate()) function. + /// + /// It will never return [Poll::Pending](core::task::Poll::Pending) + #[derive(Debug, Clone)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct PollImmediate { + #[pin] + stream: Option + } +} + +impl Stream for PollImmediate +where + S: Stream, +{ + type Item = Poll; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + let stream = match this.stream.as_mut().as_pin_mut() { + // inner is gone, so we can continue to signal that the stream is closed. + None => return Poll::Ready(None), + Some(inner) => inner, + }; + + match stream.poll_next(cx) { + Poll::Ready(Some(t)) => Poll::Ready(Some(Poll::Ready(t))), + Poll::Ready(None) => { + this.stream.set(None); + Poll::Ready(None) + } + Poll::Pending => Poll::Ready(Some(Poll::Pending)), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.stream.as_ref().map_or((0, Some(0)), Stream::size_hint) + } +} + +impl super::FusedStream for PollImmediate { + fn is_terminated(&self) -> bool { + self.stream.is_none() + } +} + +/// Creates a new stream that always immediately returns [Poll::Ready](core::task::Poll::Ready) when awaiting it. +/// +/// This is useful when immediacy is more important than waiting for the next item to be ready. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// use futures::task::Poll; +/// +/// let mut r = stream::poll_immediate(Box::pin(stream::iter(1_u32..3))); +/// assert_eq!(r.next().await, Some(Poll::Ready(1))); +/// assert_eq!(r.next().await, Some(Poll::Ready(2))); +/// assert_eq!(r.next().await, None); +/// +/// let mut p = stream::poll_immediate(Box::pin(stream::once(async { +/// futures::pending!(); +/// 42_u8 +/// }))); +/// assert_eq!(p.next().await, Some(Poll::Pending)); +/// assert_eq!(p.next().await, Some(Poll::Ready(42))); +/// assert_eq!(p.next().await, None); +/// # }); +/// ``` +pub fn poll_immediate(s: S) -> PollImmediate { + super::assert_stream::, PollImmediate>(PollImmediate { stream: Some(s) }) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/repeat.rs b/utshell-0.5.0/vendor/futures-util/src/stream/repeat.rs new file mode 100644 index 00000000..3f9aa87d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/repeat.rs @@ -0,0 +1,58 @@ +use super::assert_stream; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; + +/// Stream for the [`repeat`] function. +#[derive(Debug, Clone)] +#[must_use = "streams do nothing unless polled"] +pub struct Repeat { + item: T, +} + +/// Create a stream which produces the same item repeatedly. +/// +/// The stream never terminates. Note that you likely want to avoid +/// usage of `collect` or such on the returned stream as it will exhaust +/// available memory as it tries to just fill up all RAM. +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// +/// let stream = stream::repeat(9); +/// assert_eq!(vec![9, 9, 9], stream.take(3).collect::>().await); +/// # }); +/// ``` +pub fn repeat(item: T) -> Repeat +where + T: Clone, +{ + assert_stream::(Repeat { item }) +} + +impl Unpin for Repeat {} + +impl Stream for Repeat +where + T: Clone, +{ + type Item = T; + + fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Some(self.item.clone())) + } + + fn size_hint(&self) -> (usize, Option) { + (usize::max_value(), None) + } +} + +impl FusedStream for Repeat +where + T: Clone, +{ + fn is_terminated(&self) -> bool { + false + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/repeat_with.rs b/utshell-0.5.0/vendor/futures-util/src/stream/repeat_with.rs new file mode 100644 index 00000000..f5a81b4e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/repeat_with.rs @@ -0,0 +1,93 @@ +use super::assert_stream; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; + +/// An stream that repeats elements of type `A` endlessly by +/// applying the provided closure `F: FnMut() -> A`. +/// +/// This `struct` is created by the [`repeat_with()`] function. +/// See its documentation for more. +#[derive(Debug, Clone)] +#[must_use = "streams do nothing unless polled"] +pub struct RepeatWith { + repeater: F, +} + +impl A> Unpin for RepeatWith {} + +impl A> Stream for RepeatWith { + type Item = A; + + fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Some((&mut self.repeater)())) + } + + fn size_hint(&self) -> (usize, Option) { + (usize::max_value(), None) + } +} + +impl A> FusedStream for RepeatWith { + fn is_terminated(&self) -> bool { + false + } +} + +/// Creates a new stream that repeats elements of type `A` endlessly by +/// applying the provided closure, the repeater, `F: FnMut() -> A`. +/// +/// The `repeat_with()` function calls the repeater over and over again. +/// +/// Infinite stream like `repeat_with()` are often used with adapters like +/// [`stream.take()`], in order to make them finite. +/// +/// If the element type of the stream you need implements [`Clone`], and +/// it is OK to keep the source element in memory, you should instead use +/// the [`stream.repeat()`] function. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// +/// // let's assume we have some value of a type that is not `Clone` +/// // or which don't want to have in memory just yet because it is expensive: +/// #[derive(PartialEq, Debug)] +/// struct Expensive; +/// +/// // a particular value forever: +/// let mut things = stream::repeat_with(|| Expensive); +/// +/// assert_eq!(Some(Expensive), things.next().await); +/// assert_eq!(Some(Expensive), things.next().await); +/// assert_eq!(Some(Expensive), things.next().await); +/// # }); +/// ``` +/// +/// Using mutation and going finite: +/// +/// ```rust +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// +/// // From the zeroth to the third power of two: +/// let mut curr = 1; +/// let mut pow2 = stream::repeat_with(|| { let tmp = curr; curr *= 2; tmp }) +/// .take(4); +/// +/// assert_eq!(Some(1), pow2.next().await); +/// assert_eq!(Some(2), pow2.next().await); +/// assert_eq!(Some(4), pow2.next().await); +/// assert_eq!(Some(8), pow2.next().await); +/// +/// // ... and now we're done +/// assert_eq!(None, pow2.next().await); +/// # }); +/// ``` +pub fn repeat_with A>(repeater: F) -> RepeatWith { + assert_stream::(RepeatWith { repeater }) +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/select.rs b/utshell-0.5.0/vendor/futures-util/src/stream/select.rs new file mode 100644 index 00000000..0c1e3af7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/select.rs @@ -0,0 +1,117 @@ +use super::assert_stream; +use crate::stream::{select_with_strategy, PollNext, SelectWithStrategy}; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`select()`] function. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Select { + #[pin] + inner: SelectWithStrategy PollNext, PollNext>, + } +} + +/// This function will attempt to pull items from both streams. Each +/// stream will be polled in a round-robin fashion, and whenever a stream is +/// ready to yield an item that item is yielded. +/// +/// After one of the two input streams completes, the remaining one will be +/// polled exclusively. The returned stream completes when both input +/// streams have completed. +/// +/// Note that this function consumes both streams and returns a wrapped +/// version of them. +/// +/// ## Examples +/// +/// ```rust +/// # futures::executor::block_on(async { +/// use futures::stream::{ repeat, select, StreamExt }; +/// +/// let left = repeat(1); +/// let right = repeat(2); +/// +/// let mut out = select(left, right); +/// +/// for _ in 0..100 { +/// // We should be alternating. +/// assert_eq!(1, out.select_next_some().await); +/// assert_eq!(2, out.select_next_some().await); +/// } +/// # }); +/// ``` +pub fn select(stream1: St1, stream2: St2) -> Select +where + St1: Stream, + St2: Stream, +{ + fn round_robin(last: &mut PollNext) -> PollNext { + last.toggle() + } + + assert_stream::(Select { + inner: select_with_strategy(stream1, stream2, round_robin), + }) +} + +impl Select { + /// Acquires a reference to the underlying streams that this combinator is + /// pulling from. + pub fn get_ref(&self) -> (&St1, &St2) { + self.inner.get_ref() + } + + /// Acquires a mutable reference to the underlying streams that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + pub fn get_mut(&mut self) -> (&mut St1, &mut St2) { + self.inner.get_mut() + } + + /// Acquires a pinned mutable reference to the underlying streams that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) { + let this = self.project(); + this.inner.get_pin_mut() + } + + /// Consumes this combinator, returning the underlying streams. + /// + /// Note that this may discard intermediate state of this combinator, so + /// care should be taken to avoid losing resources when this is called. + pub fn into_inner(self) -> (St1, St2) { + self.inner.into_inner() + } +} + +impl FusedStream for Select +where + St1: Stream, + St2: Stream, +{ + fn is_terminated(&self) -> bool { + self.inner.is_terminated() + } +} + +impl Stream for Select +where + St1: Stream, + St2: Stream, +{ + type Item = St1::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + this.inner.poll_next(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/select_all.rs b/utshell-0.5.0/vendor/futures-util/src/stream/select_all.rs new file mode 100644 index 00000000..121b6a0e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/select_all.rs @@ -0,0 +1,249 @@ +//! An unbounded set of streams + +use core::fmt::{self, Debug}; +use core::iter::FromIterator; +use core::pin::Pin; + +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; + +use super::assert_stream; +use crate::stream::{futures_unordered, FuturesUnordered, StreamExt, StreamFuture}; + +/// An unbounded set of streams +/// +/// This "combinator" provides the ability to maintain a set of streams +/// and drive them all to completion. +/// +/// Streams are pushed into this set and their realized values are +/// yielded as they become ready. Streams will only be polled when they +/// generate notifications. This allows to coordinate a large number of streams. +/// +/// Note that you can create a ready-made `SelectAll` via the +/// `select_all` function in the `stream` module, or you can start with an +/// empty set with the `SelectAll::new` constructor. +#[must_use = "streams do nothing unless polled"] +pub struct SelectAll { + inner: FuturesUnordered>, +} + +impl Debug for SelectAll { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "SelectAll {{ ... }}") + } +} + +impl SelectAll { + /// Constructs a new, empty `SelectAll` + /// + /// The returned `SelectAll` does not contain any streams and, in this + /// state, `SelectAll::poll` will return `Poll::Ready(None)`. + pub fn new() -> Self { + Self { inner: FuturesUnordered::new() } + } + + /// Returns the number of streams contained in the set. + /// + /// This represents the total number of in-flight streams. + pub fn len(&self) -> usize { + self.inner.len() + } + + /// Returns `true` if the set contains no streams + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + /// Push a stream into the set. + /// + /// This function submits the given stream to the set for managing. This + /// function will not call `poll` on the submitted stream. The caller must + /// ensure that `SelectAll::poll` is called in order to receive task + /// notifications. + pub fn push(&mut self, stream: St) { + self.inner.push(stream.into_future()); + } + + /// Returns an iterator that allows inspecting each stream in the set. + pub fn iter(&self) -> Iter<'_, St> { + Iter(self.inner.iter()) + } + + /// Returns an iterator that allows modifying each stream in the set. + pub fn iter_mut(&mut self) -> IterMut<'_, St> { + IterMut(self.inner.iter_mut()) + } + + /// Clears the set, removing all streams. + pub fn clear(&mut self) { + self.inner.clear() + } +} + +impl Default for SelectAll { + fn default() -> Self { + Self::new() + } +} + +impl Stream for SelectAll { + type Item = St::Item; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + loop { + match ready!(self.inner.poll_next_unpin(cx)) { + Some((Some(item), remaining)) => { + self.push(remaining); + return Poll::Ready(Some(item)); + } + Some((None, _)) => { + // `FuturesUnordered` thinks it isn't terminated + // because it yielded a Some. + // We do not return, but poll `FuturesUnordered` + // in the next loop iteration. + } + None => return Poll::Ready(None), + } + } + } +} + +impl FusedStream for SelectAll { + fn is_terminated(&self) -> bool { + self.inner.is_terminated() + } +} + +/// Convert a list of streams into a `Stream` of results from the streams. +/// +/// This essentially takes a list of streams (e.g. a vector, an iterator, etc.) +/// and bundles them together into a single stream. +/// The stream will yield items as they become available on the underlying +/// streams internally, in the order they become available. +/// +/// Note that the returned set can also be used to dynamically push more +/// streams into the set as they become available. +/// +/// This function is only available when the `std` or `alloc` feature of this +/// library is activated, and it is activated by default. +pub fn select_all(streams: I) -> SelectAll +where + I: IntoIterator, + I::Item: Stream + Unpin, +{ + let mut set = SelectAll::new(); + + for stream in streams { + set.push(stream); + } + + assert_stream::<::Item, _>(set) +} + +impl FromIterator for SelectAll { + fn from_iter>(iter: T) -> Self { + select_all(iter) + } +} + +impl Extend for SelectAll { + fn extend>(&mut self, iter: T) { + for st in iter { + self.push(st) + } + } +} + +impl IntoIterator for SelectAll { + type Item = St; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter(self.inner.into_iter()) + } +} + +impl<'a, St: Stream + Unpin> IntoIterator for &'a SelectAll { + type Item = &'a St; + type IntoIter = Iter<'a, St>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a, St: Stream + Unpin> IntoIterator for &'a mut SelectAll { + type Item = &'a mut St; + type IntoIter = IterMut<'a, St>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +/// Immutable iterator over all streams in the unordered set. +#[derive(Debug)] +pub struct Iter<'a, St: Unpin>(futures_unordered::Iter<'a, StreamFuture>); + +/// Mutable iterator over all streams in the unordered set. +#[derive(Debug)] +pub struct IterMut<'a, St: Unpin>(futures_unordered::IterMut<'a, StreamFuture>); + +/// Owned iterator over all streams in the unordered set. +#[derive(Debug)] +pub struct IntoIter(futures_unordered::IntoIter>); + +impl<'a, St: Stream + Unpin> Iterator for Iter<'a, St> { + type Item = &'a St; + + fn next(&mut self) -> Option { + let st = self.0.next()?; + let next = st.get_ref(); + // This should always be true because FuturesUnordered removes completed futures. + debug_assert!(next.is_some()); + next + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl ExactSizeIterator for Iter<'_, St> {} + +impl<'a, St: Stream + Unpin> Iterator for IterMut<'a, St> { + type Item = &'a mut St; + + fn next(&mut self) -> Option { + let st = self.0.next()?; + let next = st.get_mut(); + // This should always be true because FuturesUnordered removes completed futures. + debug_assert!(next.is_some()); + next + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl ExactSizeIterator for IterMut<'_, St> {} + +impl Iterator for IntoIter { + type Item = St; + + fn next(&mut self) -> Option { + let st = self.0.next()?; + let next = st.into_inner(); + // This should always be true because FuturesUnordered removes completed futures. + debug_assert!(next.is_some()); + next + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl ExactSizeIterator for IntoIter {} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/select_with_strategy.rs b/utshell-0.5.0/vendor/futures-util/src/stream/select_with_strategy.rs new file mode 100644 index 00000000..224d5f82 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/select_with_strategy.rs @@ -0,0 +1,304 @@ +use super::assert_stream; +use core::{fmt, pin::Pin}; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +/// Type to tell [`SelectWithStrategy`] which stream to poll next. +#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] +pub enum PollNext { + /// Poll the first stream. + Left, + /// Poll the second stream. + Right, +} + +impl PollNext { + /// Toggle the value and return the old one. + pub fn toggle(&mut self) -> Self { + let old = *self; + *self = self.other(); + old + } + + fn other(&self) -> PollNext { + match self { + PollNext::Left => PollNext::Right, + PollNext::Right => PollNext::Left, + } + } +} + +impl Default for PollNext { + fn default() -> Self { + PollNext::Left + } +} + +enum InternalState { + Start, + LeftFinished, + RightFinished, + BothFinished, +} + +impl InternalState { + fn finish(&mut self, ps: PollNext) { + match (&self, ps) { + (InternalState::Start, PollNext::Left) => { + *self = InternalState::LeftFinished; + } + (InternalState::Start, PollNext::Right) => { + *self = InternalState::RightFinished; + } + (InternalState::LeftFinished, PollNext::Right) + | (InternalState::RightFinished, PollNext::Left) => { + *self = InternalState::BothFinished; + } + _ => {} + } + } +} + +pin_project! { + /// Stream for the [`select_with_strategy()`] function. See function docs for details. + #[must_use = "streams do nothing unless polled"] + #[project = SelectWithStrategyProj] + pub struct SelectWithStrategy { + #[pin] + stream1: St1, + #[pin] + stream2: St2, + internal_state: InternalState, + state: State, + clos: Clos, + } +} + +/// This function will attempt to pull items from both streams. You provide a +/// closure to tell [`SelectWithStrategy`] which stream to poll. The closure can +/// store state on `SelectWithStrategy` to which it will receive a `&mut` on every +/// invocation. This allows basing the strategy on prior choices. +/// +/// After one of the two input streams completes, the remaining one will be +/// polled exclusively. The returned stream completes when both input +/// streams have completed. +/// +/// Note that this function consumes both streams and returns a wrapped +/// version of them. +/// +/// ## Examples +/// +/// ### Priority +/// This example shows how to always prioritize the left stream. +/// +/// ```rust +/// # futures::executor::block_on(async { +/// use futures::stream::{ repeat, select_with_strategy, PollNext, StreamExt }; +/// +/// let left = repeat(1); +/// let right = repeat(2); +/// +/// // We don't need any state, so let's make it an empty tuple. +/// // We must provide some type here, as there is no way for the compiler +/// // to infer it. As we don't need to capture variables, we can just +/// // use a function pointer instead of a closure. +/// fn prio_left(_: &mut ()) -> PollNext { PollNext::Left } +/// +/// let mut out = select_with_strategy(left, right, prio_left); +/// +/// for _ in 0..100 { +/// // Whenever we poll out, we will alwas get `1`. +/// assert_eq!(1, out.select_next_some().await); +/// } +/// # }); +/// ``` +/// +/// ### Round Robin +/// This example shows how to select from both streams round robin. +/// Note: this special case is provided by [`futures-util::stream::select`]. +/// +/// ```rust +/// # futures::executor::block_on(async { +/// use futures::stream::{ repeat, select_with_strategy, PollNext, StreamExt }; +/// +/// let left = repeat(1); +/// let right = repeat(2); +/// +/// let rrobin = |last: &mut PollNext| last.toggle(); +/// +/// let mut out = select_with_strategy(left, right, rrobin); +/// +/// for _ in 0..100 { +/// // We should be alternating now. +/// assert_eq!(1, out.select_next_some().await); +/// assert_eq!(2, out.select_next_some().await); +/// } +/// # }); +/// ``` +pub fn select_with_strategy( + stream1: St1, + stream2: St2, + which: Clos, +) -> SelectWithStrategy +where + St1: Stream, + St2: Stream, + Clos: FnMut(&mut State) -> PollNext, + State: Default, +{ + assert_stream::(SelectWithStrategy { + stream1, + stream2, + state: Default::default(), + internal_state: InternalState::Start, + clos: which, + }) +} + +impl SelectWithStrategy { + /// Acquires a reference to the underlying streams that this combinator is + /// pulling from. + pub fn get_ref(&self) -> (&St1, &St2) { + (&self.stream1, &self.stream2) + } + + /// Acquires a mutable reference to the underlying streams that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + pub fn get_mut(&mut self) -> (&mut St1, &mut St2) { + (&mut self.stream1, &mut self.stream2) + } + + /// Acquires a pinned mutable reference to the underlying streams that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) { + let this = self.project(); + (this.stream1, this.stream2) + } + + /// Consumes this combinator, returning the underlying streams. + /// + /// Note that this may discard intermediate state of this combinator, so + /// care should be taken to avoid losing resources when this is called. + pub fn into_inner(self) -> (St1, St2) { + (self.stream1, self.stream2) + } +} + +impl FusedStream for SelectWithStrategy +where + St1: Stream, + St2: Stream, + Clos: FnMut(&mut State) -> PollNext, +{ + fn is_terminated(&self) -> bool { + match self.internal_state { + InternalState::BothFinished => true, + _ => false, + } + } +} + +#[inline] +fn poll_side( + select: &mut SelectWithStrategyProj<'_, St1, St2, Clos, State>, + side: PollNext, + cx: &mut Context<'_>, +) -> Poll> +where + St1: Stream, + St2: Stream, +{ + match side { + PollNext::Left => select.stream1.as_mut().poll_next(cx), + PollNext::Right => select.stream2.as_mut().poll_next(cx), + } +} + +#[inline] +fn poll_inner( + select: &mut SelectWithStrategyProj<'_, St1, St2, Clos, State>, + side: PollNext, + cx: &mut Context<'_>, +) -> Poll> +where + St1: Stream, + St2: Stream, +{ + let first_done = match poll_side(select, side, cx) { + Poll::Ready(Some(item)) => return Poll::Ready(Some(item)), + Poll::Ready(None) => { + select.internal_state.finish(side); + true + } + Poll::Pending => false, + }; + let other = side.other(); + match poll_side(select, other, cx) { + Poll::Ready(None) => { + select.internal_state.finish(other); + if first_done { + Poll::Ready(None) + } else { + Poll::Pending + } + } + a => a, + } +} + +impl Stream for SelectWithStrategy +where + St1: Stream, + St2: Stream, + Clos: FnMut(&mut State) -> PollNext, +{ + type Item = St1::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + match this.internal_state { + InternalState::Start => { + let next_side = (this.clos)(this.state); + poll_inner(&mut this, next_side, cx) + } + InternalState::LeftFinished => match this.stream2.poll_next(cx) { + Poll::Ready(None) => { + *this.internal_state = InternalState::BothFinished; + Poll::Ready(None) + } + a => a, + }, + InternalState::RightFinished => match this.stream1.poll_next(cx) { + Poll::Ready(None) => { + *this.internal_state = InternalState::BothFinished; + Poll::Ready(None) + } + a => a, + }, + InternalState::BothFinished => Poll::Ready(None), + } + } +} + +impl fmt::Debug for SelectWithStrategy +where + St1: fmt::Debug, + St2: fmt::Debug, + State: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SelectWithStrategy") + .field("stream1", &self.stream1) + .field("stream2", &self.stream2) + .field("state", &self.state) + .finish() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/all.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/all.rs new file mode 100644 index 00000000..1435c798 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/all.rs @@ -0,0 +1,93 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`all`](super::StreamExt::all) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct All { + #[pin] + stream: St, + f: F, + done: bool, + #[pin] + future: Option, + } +} + +impl fmt::Debug for All +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("All") + .field("stream", &self.stream) + .field("done", &self.done) + .field("future", &self.future) + .finish() + } +} + +impl All +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, done: false, future: None } + } +} + +impl FusedFuture for All +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.done && self.future.is_none() + } +} + +impl Future for All +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + type Output = bool; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + // we're currently processing a future to produce a new value + let res = ready!(fut.poll(cx)); + this.future.set(None); + if !res { + *this.done = true; + break false; + } // early exit + } else if !*this.done { + // we're waiting on a new item from the stream + match ready!(this.stream.as_mut().poll_next(cx)) { + Some(item) => { + this.future.set(Some((this.f)(item))); + } + None => { + *this.done = true; + break true; + } + } + } else { + panic!("All polled after completion") + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/any.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/any.rs new file mode 100644 index 00000000..cc3d695b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/any.rs @@ -0,0 +1,93 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`any`](super::StreamExt::any) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Any { + #[pin] + stream: St, + f: F, + done: bool, + #[pin] + future: Option, + } +} + +impl fmt::Debug for Any +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Any") + .field("stream", &self.stream) + .field("done", &self.done) + .field("future", &self.future) + .finish() + } +} + +impl Any +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, done: false, future: None } + } +} + +impl FusedFuture for Any +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.done && self.future.is_none() + } +} + +impl Future for Any +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + type Output = bool; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + // we're currently processing a future to produce a new value + let res = ready!(fut.poll(cx)); + this.future.set(None); + if res { + *this.done = true; + break true; + } // early exit + } else if !*this.done { + // we're waiting on a new item from the stream + match ready!(this.stream.as_mut().poll_next(cx)) { + Some(item) => { + this.future.set(Some((this.f)(item))); + } + None => { + *this.done = true; + break false; + } + } + } else { + panic!("Any polled after completion") + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/buffer_unordered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/buffer_unordered.rs new file mode 100644 index 00000000..91b0f6bc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/buffer_unordered.rs @@ -0,0 +1,120 @@ +use crate::stream::{Fuse, FuturesUnordered, StreamExt}; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`buffer_unordered`](super::StreamExt::buffer_unordered) + /// method. + #[must_use = "streams do nothing unless polled"] + pub struct BufferUnordered + where + St: Stream, + { + #[pin] + stream: Fuse, + in_progress_queue: FuturesUnordered, + max: usize, + } +} + +impl fmt::Debug for BufferUnordered +where + St: Stream + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("BufferUnordered") + .field("stream", &self.stream) + .field("in_progress_queue", &self.in_progress_queue) + .field("max", &self.max) + .finish() + } +} + +impl BufferUnordered +where + St: Stream, + St::Item: Future, +{ + pub(super) fn new(stream: St, n: usize) -> Self { + Self { + stream: super::Fuse::new(stream), + in_progress_queue: FuturesUnordered::new(), + max: n, + } + } + + delegate_access_inner!(stream, St, (.)); +} + +impl Stream for BufferUnordered +where + St: Stream, + St::Item: Future, +{ + type Item = ::Output; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + // First up, try to spawn off as many futures as possible by filling up + // our queue of futures. + while this.in_progress_queue.len() < *this.max { + match this.stream.as_mut().poll_next(cx) { + Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut), + Poll::Ready(None) | Poll::Pending => break, + } + } + + // Attempt to pull the next value from the in_progress_queue + match this.in_progress_queue.poll_next_unpin(cx) { + x @ Poll::Pending | x @ Poll::Ready(Some(_)) => return x, + Poll::Ready(None) => {} + } + + // If more values are still coming from the stream, we're not done yet + if this.stream.is_done() { + Poll::Ready(None) + } else { + Poll::Pending + } + } + + fn size_hint(&self) -> (usize, Option) { + let queue_len = self.in_progress_queue.len(); + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(queue_len); + let upper = match upper { + Some(x) => x.checked_add(queue_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for BufferUnordered +where + St: Stream, + St::Item: Future, +{ + fn is_terminated(&self) -> bool { + self.in_progress_queue.is_terminated() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for BufferUnordered +where + S: Stream + Sink, + S::Item: Future, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/buffered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/buffered.rs new file mode 100644 index 00000000..5854eb7e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/buffered.rs @@ -0,0 +1,118 @@ +use crate::stream::{Fuse, FusedStream, FuturesOrdered, StreamExt}; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`buffered`](super::StreamExt::buffered) method. + #[must_use = "streams do nothing unless polled"] + pub struct Buffered + where + St: Stream, + St::Item: Future, + { + #[pin] + stream: Fuse, + in_progress_queue: FuturesOrdered, + max: usize, + } +} + +impl fmt::Debug for Buffered +where + St: Stream + fmt::Debug, + St::Item: Future, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Buffered") + .field("stream", &self.stream) + .field("in_progress_queue", &self.in_progress_queue) + .field("max", &self.max) + .finish() + } +} + +impl Buffered +where + St: Stream, + St::Item: Future, +{ + pub(super) fn new(stream: St, n: usize) -> Self { + Self { stream: super::Fuse::new(stream), in_progress_queue: FuturesOrdered::new(), max: n } + } + + delegate_access_inner!(stream, St, (.)); +} + +impl Stream for Buffered +where + St: Stream, + St::Item: Future, +{ + type Item = ::Output; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + // First up, try to spawn off as many futures as possible by filling up + // our queue of futures. + while this.in_progress_queue.len() < *this.max { + match this.stream.as_mut().poll_next(cx) { + Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut), + Poll::Ready(None) | Poll::Pending => break, + } + } + + // Attempt to pull the next value from the in_progress_queue + let res = this.in_progress_queue.poll_next_unpin(cx); + if let Some(val) = ready!(res) { + return Poll::Ready(Some(val)); + } + + // If more values are still coming from the stream, we're not done yet + if this.stream.is_done() { + Poll::Ready(None) + } else { + Poll::Pending + } + } + + fn size_hint(&self) -> (usize, Option) { + let queue_len = self.in_progress_queue.len(); + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(queue_len); + let upper = match upper { + Some(x) => x.checked_add(queue_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for Buffered +where + St: Stream, + St::Item: Future, +{ + fn is_terminated(&self) -> bool { + self.stream.is_done() && self.in_progress_queue.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Buffered +where + S: Stream + Sink, + S::Item: Future, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/catch_unwind.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/catch_unwind.rs new file mode 100644 index 00000000..09a6dc1b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/catch_unwind.rs @@ -0,0 +1,61 @@ +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; +use std::any::Any; +use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}; +use std::pin::Pin; + +pin_project! { + /// Stream for the [`catch_unwind`](super::StreamExt::catch_unwind) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct CatchUnwind { + #[pin] + stream: St, + caught_unwind: bool, + } +} + +impl CatchUnwind { + pub(super) fn new(stream: St) -> Self { + Self { stream, caught_unwind: false } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for CatchUnwind { + type Item = Result>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if *this.caught_unwind { + Poll::Ready(None) + } else { + let res = catch_unwind(AssertUnwindSafe(|| this.stream.as_mut().poll_next(cx))); + + match res { + Ok(poll) => poll.map(|opt| opt.map(Ok)), + Err(e) => { + *this.caught_unwind = true; + Poll::Ready(Some(Err(e))) + } + } + } + } + + fn size_hint(&self) -> (usize, Option) { + if self.caught_unwind { + (0, Some(0)) + } else { + self.stream.size_hint() + } + } +} + +impl FusedStream for CatchUnwind { + fn is_terminated(&self) -> bool { + self.caught_unwind || self.stream.is_terminated() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/chain.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/chain.rs new file mode 100644 index 00000000..36ff1e53 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/chain.rs @@ -0,0 +1,76 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`chain`](super::StreamExt::chain) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Chain { + #[pin] + first: Option, + #[pin] + second: St2, + } +} + +// All interactions with `Pin<&mut Chain<..>>` happen through these methods +impl Chain +where + St1: Stream, + St2: Stream, +{ + pub(super) fn new(stream1: St1, stream2: St2) -> Self { + Self { first: Some(stream1), second: stream2 } + } +} + +impl FusedStream for Chain +where + St1: Stream, + St2: FusedStream, +{ + fn is_terminated(&self) -> bool { + self.first.is_none() && self.second.is_terminated() + } +} + +impl Stream for Chain +where + St1: Stream, + St2: Stream, +{ + type Item = St1::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + if let Some(first) = this.first.as_mut().as_pin_mut() { + if let Some(item) = ready!(first.poll_next(cx)) { + return Poll::Ready(Some(item)); + } + + this.first.set(None); + } + this.second.poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + if let Some(first) = &self.first { + let (first_lower, first_upper) = first.size_hint(); + let (second_lower, second_upper) = self.second.size_hint(); + + let lower = first_lower.saturating_add(second_lower); + + let upper = match (first_upper, second_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None, + }; + + (lower, upper) + } else { + self.second.size_hint() + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/chunks.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/chunks.rs new file mode 100644 index 00000000..2a71ebc6 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/chunks.rs @@ -0,0 +1,103 @@ +use crate::stream::Fuse; +use alloc::vec::Vec; +use core::mem; +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`chunks`](super::StreamExt::chunks) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Chunks { + #[pin] + stream: Fuse, + items: Vec, + cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 + } +} + +impl Chunks { + pub(super) fn new(stream: St, capacity: usize) -> Self { + assert!(capacity > 0); + + Self { + stream: super::Fuse::new(stream), + items: Vec::with_capacity(capacity), + cap: capacity, + } + } + + fn take(self: Pin<&mut Self>) -> Vec { + let cap = self.cap; + mem::replace(self.project().items, Vec::with_capacity(cap)) + } + + delegate_access_inner!(stream, St, (.)); +} + +impl Stream for Chunks { + type Item = Vec; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.as_mut().project(); + loop { + match ready!(this.stream.as_mut().poll_next(cx)) { + // Push the item into the buffer and check whether it is full. + // If so, replace our buffer with a new and empty one and return + // the full one. + Some(item) => { + this.items.push(item); + if this.items.len() >= *this.cap { + return Poll::Ready(Some(self.take())); + } + } + + // Since the underlying stream ran out of values, return what we + // have buffered, if we have anything. + None => { + let last = if this.items.is_empty() { + None + } else { + let full_buf = mem::take(this.items); + Some(full_buf) + }; + + return Poll::Ready(last); + } + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let chunk_len = usize::from(!self.items.is_empty()); + let (lower, upper) = self.stream.size_hint(); + let lower = (lower / self.cap).saturating_add(chunk_len); + let upper = match upper { + Some(x) => x.checked_add(chunk_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for Chunks { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() && self.items.is_empty() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Chunks +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/collect.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/collect.rs new file mode 100644 index 00000000..970ac26d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/collect.rs @@ -0,0 +1,56 @@ +use core::mem; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`collect`](super::StreamExt::collect) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Collect { + #[pin] + stream: St, + collection: C, + } +} + +impl Collect { + fn finish(self: Pin<&mut Self>) -> C { + mem::take(self.project().collection) + } + + pub(super) fn new(stream: St) -> Self { + Self { stream, collection: Default::default() } + } +} + +impl FusedFuture for Collect +where + St: FusedStream, + C: Default + Extend, +{ + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for Collect +where + St: Stream, + C: Default + Extend, +{ + type Output = C; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.as_mut().project(); + loop { + match ready!(this.stream.as_mut().poll_next(cx)) { + Some(e) => this.collection.extend(Some(e)), + None => return Poll::Ready(self.finish()), + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/concat.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/concat.rs new file mode 100644 index 00000000..7e058b23 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/concat.rs @@ -0,0 +1,62 @@ +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`concat`](super::StreamExt::concat) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Concat { + #[pin] + stream: St, + accum: Option, + } +} + +impl Concat +where + St: Stream, + St::Item: Extend<::Item> + IntoIterator + Default, +{ + pub(super) fn new(stream: St) -> Self { + Self { stream, accum: None } + } +} + +impl Future for Concat +where + St: Stream, + St::Item: Extend<::Item> + IntoIterator + Default, +{ + type Output = St::Item; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + + loop { + match ready!(this.stream.as_mut().poll_next(cx)) { + None => return Poll::Ready(this.accum.take().unwrap_or_default()), + Some(e) => { + if let Some(a) = this.accum { + a.extend(e) + } else { + *this.accum = Some(e) + } + } + } + } + } +} + +impl FusedFuture for Concat +where + St: FusedStream, + St::Item: Extend<::Item> + IntoIterator + Default, +{ + fn is_terminated(&self) -> bool { + self.accum.is_none() && self.stream.is_terminated() + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/count.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/count.rs new file mode 100644 index 00000000..513cab7b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/count.rs @@ -0,0 +1,53 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`count`](super::StreamExt::count) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Count { + #[pin] + stream: St, + count: usize + } +} + +impl fmt::Debug for Count +where + St: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Count").field("stream", &self.stream).field("count", &self.count).finish() + } +} + +impl Count { + pub(super) fn new(stream: St) -> Self { + Self { stream, count: 0 } + } +} + +impl FusedFuture for Count { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for Count { + type Output = usize; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + + Poll::Ready(loop { + match ready!(this.stream.as_mut().poll_next(cx)) { + Some(_) => *this.count += 1, + None => break *this.count, + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/cycle.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/cycle.rs new file mode 100644 index 00000000..507431d2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/cycle.rs @@ -0,0 +1,68 @@ +use core::pin::Pin; +use core::usize; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`cycle`](super::StreamExt::cycle) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Cycle { + orig: St, + #[pin] + stream: St, + } +} + +impl Cycle +where + St: Clone + Stream, +{ + pub(super) fn new(stream: St) -> Self { + Self { orig: stream.clone(), stream } + } +} + +impl Stream for Cycle +where + St: Clone + Stream, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + match ready!(this.stream.as_mut().poll_next(cx)) { + None => { + this.stream.set(this.orig.clone()); + this.stream.poll_next(cx) + } + item => Poll::Ready(item), + } + } + + fn size_hint(&self) -> (usize, Option) { + // the cycle stream is either empty or infinite + match self.orig.size_hint() { + size @ (0, Some(0)) => size, + (0, _) => (0, None), + _ => (usize::max_value(), None), + } + } +} + +impl FusedStream for Cycle +where + St: Clone + Stream, +{ + fn is_terminated(&self) -> bool { + // the cycle stream is either empty or infinite + if let (0, Some(0)) = self.size_hint() { + true + } else { + false + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/enumerate.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/enumerate.rs new file mode 100644 index 00000000..1cf9d49a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/enumerate.rs @@ -0,0 +1,64 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`enumerate`](super::StreamExt::enumerate) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Enumerate { + #[pin] + stream: St, + count: usize, + } +} + +impl Enumerate { + pub(super) fn new(stream: St) -> Self { + Self { stream, count: 0 } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Enumerate { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Stream for Enumerate { + type Item = (usize, St::Item); + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + match ready!(this.stream.poll_next(cx)) { + Some(item) => { + let prev_count = *this.count; + *this.count += 1; + Poll::Ready(Some((prev_count, item))) + } + None => Poll::Ready(None), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.stream.size_hint() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Enumerate +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/filter.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/filter.rs new file mode 100644 index 00000000..997fe997 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/filter.rs @@ -0,0 +1,117 @@ +use crate::fns::FnMut1; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`filter`](super::StreamExt::filter) method. + #[must_use = "streams do nothing unless polled"] + pub struct Filter + where St: Stream, + { + #[pin] + stream: St, + f: F, + #[pin] + pending_fut: Option, + pending_item: Option, + } +} + +impl fmt::Debug for Filter +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Filter") + .field("stream", &self.stream) + .field("pending_fut", &self.pending_fut) + .field("pending_item", &self.pending_item) + .finish() + } +} + +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl Filter +where + St: Stream, + F: for<'a> FnMut1<&'a St::Item, Output = Fut>, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending_fut: None, pending_item: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Filter +where + St: Stream + FusedStream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.pending_fut.is_none() && self.stream.is_terminated() + } +} + +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl Stream for Filter +where + St: Stream, + F: for<'a> FnMut1<&'a St::Item, Output = Fut>, + Fut: Future, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + Poll::Ready(loop { + if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { + let res = ready!(fut.poll(cx)); + this.pending_fut.set(None); + if res { + break this.pending_item.take(); + } + *this.pending_item = None; + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + this.pending_fut.set(Some(this.f.call_mut(&item))); + *this.pending_item = Some(item); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let pending_len = usize::from(self.pending_item.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Filter +where + S: Stream + Sink, + F: FnMut(&S::Item) -> Fut, + Fut: Future, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/filter_map.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/filter_map.rs new file mode 100644 index 00000000..6b7d0070 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/filter_map.rs @@ -0,0 +1,111 @@ +use crate::fns::FnMut1; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`filter_map`](super::StreamExt::filter_map) method. + #[must_use = "streams do nothing unless polled"] + pub struct FilterMap { + #[pin] + stream: St, + f: F, + #[pin] + pending: Option, + } +} + +impl fmt::Debug for FilterMap +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FilterMap") + .field("stream", &self.stream) + .field("pending", &self.pending) + .finish() + } +} + +impl FilterMap +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for FilterMap +where + St: Stream + FusedStream, + F: FnMut1, + Fut: Future>, +{ + fn is_terminated(&self) -> bool { + self.pending.is_none() && self.stream.is_terminated() + } +} + +impl Stream for FilterMap +where + St: Stream, + F: FnMut1, + Fut: Future>, +{ + type Item = T; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + Poll::Ready(loop { + if let Some(p) = this.pending.as_mut().as_pin_mut() { + // We have an item in progress, poll that until it's done + let item = ready!(p.poll(cx)); + this.pending.set(None); + if item.is_some() { + break item; + } + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + // No item in progress, but the stream is still going + this.pending.set(Some(this.f.call_mut(item))); + } else { + // The stream is done + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let pending_len = usize::from(self.pending.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for FilterMap +where + S: Stream + Sink, + F: FnMut1, + Fut: Future, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten.rs new file mode 100644 index 00000000..9f6b7a47 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten.rs @@ -0,0 +1,73 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`flatten`](super::StreamExt::flatten) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Flatten { + #[pin] + stream: St, + #[pin] + next: Option, + } +} + +impl Flatten { + pub(super) fn new(stream: St) -> Self { + Self { stream, next: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Flatten +where + St: FusedStream, + St::Item: Stream, +{ + fn is_terminated(&self) -> bool { + self.next.is_none() && self.stream.is_terminated() + } +} + +impl Stream for Flatten +where + St: Stream, + St::Item: Stream, +{ + type Item = ::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + Poll::Ready(loop { + if let Some(s) = this.next.as_mut().as_pin_mut() { + if let Some(item) = ready!(s.poll_next(cx)) { + break Some(item); + } else { + this.next.set(None); + } + } else if let Some(s) = ready!(this.stream.as_mut().poll_next(cx)) { + this.next.set(Some(s)); + } else { + break None; + } + }) + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Flatten +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten_unordered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten_unordered.rs new file mode 100644 index 00000000..44c6ace2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/flatten_unordered.rs @@ -0,0 +1,536 @@ +use alloc::sync::Arc; +use core::{ + cell::UnsafeCell, + convert::identity, + fmt, + marker::PhantomData, + num::NonZeroUsize, + pin::Pin, + sync::atomic::{AtomicU8, Ordering}, +}; + +use pin_project_lite::pin_project; + +use futures_core::{ + future::Future, + ready, + stream::{FusedStream, Stream}, + task::{Context, Poll, Waker}, +}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use futures_task::{waker, ArcWake}; + +use crate::stream::FuturesUnordered; + +/// Stream for the [`flatten_unordered`](super::StreamExt::flatten_unordered) +/// method. +pub type FlattenUnordered = FlattenUnorderedWithFlowController; + +/// There is nothing to poll and stream isn't being polled/waking/woken at the moment. +const NONE: u8 = 0; + +/// Inner streams need to be polled. +const NEED_TO_POLL_INNER_STREAMS: u8 = 1; + +/// The base stream needs to be polled. +const NEED_TO_POLL_STREAM: u8 = 0b10; + +/// Both base stream and inner streams need to be polled. +const NEED_TO_POLL_ALL: u8 = NEED_TO_POLL_INNER_STREAMS | NEED_TO_POLL_STREAM; + +/// The current stream is being polled at the moment. +const POLLING: u8 = 0b100; + +/// Stream is being woken at the moment. +const WAKING: u8 = 0b1000; + +/// The stream was waked and will be polled. +const WOKEN: u8 = 0b10000; + +/// Internal polling state of the stream. +#[derive(Clone, Debug)] +struct SharedPollState { + state: Arc, +} + +impl SharedPollState { + /// Constructs new `SharedPollState` with the given state. + fn new(value: u8) -> SharedPollState { + SharedPollState { state: Arc::new(AtomicU8::new(value)) } + } + + /// Attempts to start polling, returning stored state in case of success. + /// Returns `None` if either waker is waking at the moment. + fn start_polling( + &self, + ) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> { + let value = self + .state + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| { + if value & WAKING == NONE { + Some(POLLING) + } else { + None + } + }) + .ok()?; + let bomb = PollStateBomb::new(self, SharedPollState::reset); + + Some((value, bomb)) + } + + /// Attempts to start the waking process and performs bitwise or with the given value. + /// + /// If some waker is already in progress or stream is already woken/being polled, waking process won't start, however + /// state will be disjuncted with the given value. + fn start_waking( + &self, + to_poll: u8, + ) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> { + let value = self + .state + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| { + let mut next_value = value | to_poll; + if value & (WOKEN | POLLING) == NONE { + next_value |= WAKING; + } + + if next_value != value { + Some(next_value) + } else { + None + } + }) + .ok()?; + + // Only start the waking process if we're not in the polling/waking phase and the stream isn't woken already + if value & (WOKEN | POLLING | WAKING) == NONE { + let bomb = PollStateBomb::new(self, SharedPollState::stop_waking); + + Some((value, bomb)) + } else { + None + } + } + + /// Sets current state to + /// - `!POLLING` allowing to use wakers + /// - `WOKEN` if the state was changed during `POLLING` phase as waker will be called, + /// or `will_be_woken` flag supplied + /// - `!WAKING` as + /// * Wakers called during the `POLLING` phase won't propagate their calls + /// * `POLLING` phase can't start if some of the wakers are active + /// So no wrapped waker can touch the inner waker's cell, it's safe to poll again. + fn stop_polling(&self, to_poll: u8, will_be_woken: bool) -> u8 { + self.state + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |mut value| { + let mut next_value = to_poll; + + value &= NEED_TO_POLL_ALL; + if value != NONE || will_be_woken { + next_value |= WOKEN; + } + next_value |= value; + + Some(next_value & !POLLING & !WAKING) + }) + .unwrap() + } + + /// Toggles state to non-waking, allowing to start polling. + fn stop_waking(&self) -> u8 { + let value = self + .state + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| { + let next_value = value & !WAKING | WOKEN; + + if next_value != value { + Some(next_value) + } else { + None + } + }) + .unwrap_or_else(identity); + + debug_assert!(value & (WOKEN | POLLING | WAKING) == WAKING); + value + } + + /// Resets current state allowing to poll the stream and wake up wakers. + fn reset(&self) -> u8 { + self.state.swap(NEED_TO_POLL_ALL, Ordering::SeqCst) + } +} + +/// Used to execute some function on the given state when dropped. +struct PollStateBomb<'a, F: FnOnce(&SharedPollState) -> u8> { + state: &'a SharedPollState, + drop: Option, +} + +impl<'a, F: FnOnce(&SharedPollState) -> u8> PollStateBomb<'a, F> { + /// Constructs new bomb with the given state. + fn new(state: &'a SharedPollState, drop: F) -> Self { + Self { state, drop: Some(drop) } + } + + /// Deactivates bomb, forces it to not call provided function when dropped. + fn deactivate(mut self) { + self.drop.take(); + } +} + +impl u8> Drop for PollStateBomb<'_, F> { + fn drop(&mut self) { + if let Some(drop) = self.drop.take() { + (drop)(self.state); + } + } +} + +/// Will update state with the provided value on `wake_by_ref` call +/// and then, if there is a need, call `inner_waker`. +struct WrappedWaker { + inner_waker: UnsafeCell>, + poll_state: SharedPollState, + need_to_poll: u8, +} + +unsafe impl Send for WrappedWaker {} +unsafe impl Sync for WrappedWaker {} + +impl WrappedWaker { + /// Replaces given waker's inner_waker for polling stream/futures which will + /// update poll state on `wake_by_ref` call. Use only if you need several + /// contexts. + /// + /// ## Safety + /// + /// This function will modify waker's `inner_waker` via `UnsafeCell`, so + /// it should be used only during `POLLING` phase by one thread at the time. + unsafe fn replace_waker(self_arc: &mut Arc, cx: &Context<'_>) { + *self_arc.inner_waker.get() = cx.waker().clone().into(); + } + + /// Attempts to start the waking process for the waker with the given value. + /// If succeeded, then the stream isn't yet woken and not being polled at the moment. + fn start_waking(&self) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> { + self.poll_state.start_waking(self.need_to_poll) + } +} + +impl ArcWake for WrappedWaker { + fn wake_by_ref(self_arc: &Arc) { + if let Some((_, state_bomb)) = self_arc.start_waking() { + // Safety: now state is not `POLLING` + let waker_opt = unsafe { self_arc.inner_waker.get().as_ref().unwrap() }; + + if let Some(inner_waker) = waker_opt.clone() { + // Stop waking to allow polling stream + drop(state_bomb); + + // Wake up inner waker + inner_waker.wake(); + } + } + } +} + +pin_project! { + /// Future which polls optional inner stream. + /// + /// If it's `Some`, it will attempt to call `poll_next` on it, + /// returning `Some((item, next_item_fut))` in case of `Poll::Ready(Some(...))` + /// or `None` in case of `Poll::Ready(None)`. + /// + /// If `poll_next` will return `Poll::Pending`, it will be forwarded to + /// the future and current task will be notified by waker. + #[must_use = "futures do nothing unless you `.await` or poll them"] + struct PollStreamFut { + #[pin] + stream: Option, + } +} + +impl PollStreamFut { + /// Constructs new `PollStreamFut` using given `stream`. + fn new(stream: impl Into>) -> Self { + Self { stream: stream.into() } + } +} + +impl Future for PollStreamFut { + type Output = Option<(St::Item, PollStreamFut)>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut stream = self.project().stream; + + let item = if let Some(stream) = stream.as_mut().as_pin_mut() { + ready!(stream.poll_next(cx)) + } else { + None + }; + let next_item_fut = PollStreamFut::new(stream.get_mut().take()); + let out = item.map(|item| (item, next_item_fut)); + + Poll::Ready(out) + } +} + +pin_project! { + /// Stream for the [`flatten_unordered`](super::StreamExt::flatten_unordered) + /// method with ability to specify flow controller. + #[project = FlattenUnorderedWithFlowControllerProj] + #[must_use = "streams do nothing unless polled"] + pub struct FlattenUnorderedWithFlowController where St: Stream { + #[pin] + inner_streams: FuturesUnordered>, + #[pin] + stream: St, + poll_state: SharedPollState, + limit: Option, + is_stream_done: bool, + inner_streams_waker: Arc, + stream_waker: Arc, + flow_controller: PhantomData + } +} + +impl fmt::Debug for FlattenUnorderedWithFlowController +where + St: Stream + fmt::Debug, + St::Item: Stream + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FlattenUnorderedWithFlowController") + .field("poll_state", &self.poll_state) + .field("inner_streams", &self.inner_streams) + .field("limit", &self.limit) + .field("stream", &self.stream) + .field("is_stream_done", &self.is_stream_done) + .field("flow_controller", &self.flow_controller) + .finish() + } +} + +impl FlattenUnorderedWithFlowController +where + St: Stream, + Fc: FlowController::Item>, + St::Item: Stream + Unpin, +{ + pub(crate) fn new( + stream: St, + limit: Option, + ) -> FlattenUnorderedWithFlowController { + let poll_state = SharedPollState::new(NEED_TO_POLL_STREAM); + + FlattenUnorderedWithFlowController { + inner_streams: FuturesUnordered::new(), + stream, + is_stream_done: false, + limit: limit.and_then(NonZeroUsize::new), + inner_streams_waker: Arc::new(WrappedWaker { + inner_waker: UnsafeCell::new(None), + poll_state: poll_state.clone(), + need_to_poll: NEED_TO_POLL_INNER_STREAMS, + }), + stream_waker: Arc::new(WrappedWaker { + inner_waker: UnsafeCell::new(None), + poll_state: poll_state.clone(), + need_to_poll: NEED_TO_POLL_STREAM, + }), + poll_state, + flow_controller: PhantomData, + } + } + + delegate_access_inner!(stream, St, ()); +} + +/// Returns the next flow step based on the received item. +pub trait FlowController { + /// Handles an item producing `FlowStep` describing the next flow step. + fn next_step(item: I) -> FlowStep; +} + +impl FlowController for () { + fn next_step(item: I) -> FlowStep { + FlowStep::Continue(item) + } +} + +/// Describes the next flow step. +#[derive(Debug, Clone)] +pub enum FlowStep { + /// Just yields an item and continues standard flow. + Continue(C), + /// Immediately returns an underlying item from the function. + Return(R), +} + +impl FlattenUnorderedWithFlowControllerProj<'_, St, Fc> +where + St: Stream, +{ + /// Checks if current `inner_streams` bucket size is greater than optional limit. + fn is_exceeded_limit(&self) -> bool { + self.limit.map_or(false, |limit| self.inner_streams.len() >= limit.get()) + } +} + +impl FusedStream for FlattenUnorderedWithFlowController +where + St: FusedStream, + Fc: FlowController::Item>, + St::Item: Stream + Unpin, +{ + fn is_terminated(&self) -> bool { + self.stream.is_terminated() && self.inner_streams.is_empty() + } +} + +impl Stream for FlattenUnorderedWithFlowController +where + St: Stream, + Fc: FlowController::Item>, + St::Item: Stream + Unpin, +{ + type Item = ::Item; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut next_item = None; + let mut need_to_poll_next = NONE; + + let mut this = self.as_mut().project(); + + // Attempt to start polling, in case some waker is holding the lock, wait in loop + let (mut poll_state_value, state_bomb) = loop { + if let Some(value) = this.poll_state.start_polling() { + break value; + } + }; + + // Safety: now state is `POLLING`. + unsafe { + WrappedWaker::replace_waker(this.stream_waker, cx); + WrappedWaker::replace_waker(this.inner_streams_waker, cx) + }; + + if poll_state_value & NEED_TO_POLL_STREAM != NONE { + let mut stream_waker = None; + + // Here we need to poll the base stream. + // + // To improve performance, we will attempt to place as many items as we can + // to the `FuturesUnordered` bucket before polling inner streams + loop { + if this.is_exceeded_limit() || *this.is_stream_done { + // We either exceeded the limit or the stream is exhausted + if !*this.is_stream_done { + // The stream needs to be polled in the next iteration + need_to_poll_next |= NEED_TO_POLL_STREAM; + } + + break; + } else { + let mut cx = Context::from_waker( + stream_waker.get_or_insert_with(|| waker(this.stream_waker.clone())), + ); + + match this.stream.as_mut().poll_next(&mut cx) { + Poll::Ready(Some(item)) => { + let next_item_fut = match Fc::next_step(item) { + // Propagates an item immediately (the main use-case is for errors) + FlowStep::Return(item) => { + need_to_poll_next |= NEED_TO_POLL_STREAM + | (poll_state_value & NEED_TO_POLL_INNER_STREAMS); + poll_state_value &= !NEED_TO_POLL_INNER_STREAMS; + + next_item = Some(item); + + break; + } + // Yields an item and continues processing (normal case) + FlowStep::Continue(inner_stream) => { + PollStreamFut::new(inner_stream) + } + }; + // Add new stream to the inner streams bucket + this.inner_streams.as_mut().push(next_item_fut); + // Inner streams must be polled afterward + poll_state_value |= NEED_TO_POLL_INNER_STREAMS; + } + Poll::Ready(None) => { + // Mark the base stream as done + *this.is_stream_done = true; + } + Poll::Pending => { + break; + } + } + } + } + } + + if poll_state_value & NEED_TO_POLL_INNER_STREAMS != NONE { + let inner_streams_waker = waker(this.inner_streams_waker.clone()); + let mut cx = Context::from_waker(&inner_streams_waker); + + match this.inner_streams.as_mut().poll_next(&mut cx) { + Poll::Ready(Some(Some((item, next_item_fut)))) => { + // Push next inner stream item future to the list of inner streams futures + this.inner_streams.as_mut().push(next_item_fut); + // Take the received item + next_item = Some(item); + // On the next iteration, inner streams must be polled again + need_to_poll_next |= NEED_TO_POLL_INNER_STREAMS; + } + Poll::Ready(Some(None)) => { + // On the next iteration, inner streams must be polled again + need_to_poll_next |= NEED_TO_POLL_INNER_STREAMS; + } + _ => {} + } + } + + // We didn't have any `poll_next` panic, so it's time to deactivate the bomb + state_bomb.deactivate(); + + // Call the waker at the end of polling if + let mut force_wake = + // we need to poll the stream and didn't reach the limit yet + need_to_poll_next & NEED_TO_POLL_STREAM != NONE && !this.is_exceeded_limit() + // or we need to poll the inner streams again + || need_to_poll_next & NEED_TO_POLL_INNER_STREAMS != NONE; + + // Stop polling and swap the latest state + poll_state_value = this.poll_state.stop_polling(need_to_poll_next, force_wake); + // If state was changed during `POLLING` phase, we also need to manually call a waker + force_wake |= poll_state_value & NEED_TO_POLL_ALL != NONE; + + let is_done = *this.is_stream_done && this.inner_streams.is_empty(); + + if next_item.is_some() || is_done { + Poll::Ready(next_item) + } else { + if force_wake { + cx.waker().wake_by_ref(); + } + + Poll::Pending + } + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for FlattenUnorderedWithFlowController +where + St: Stream + Sink, +{ + type Error = St::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/fold.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/fold.rs new file mode 100644 index 00000000..b8b55ecb --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/fold.rs @@ -0,0 +1,88 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`fold`](super::StreamExt::fold) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Fold { + #[pin] + stream: St, + f: F, + accum: Option, + #[pin] + future: Option, + } +} + +impl fmt::Debug for Fold +where + St: fmt::Debug, + Fut: fmt::Debug, + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Fold") + .field("stream", &self.stream) + .field("accum", &self.accum) + .field("future", &self.future) + .finish() + } +} + +impl Fold +where + St: Stream, + F: FnMut(T, St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F, t: T) -> Self { + Self { stream, f, accum: Some(t), future: None } + } +} + +impl FusedFuture for Fold +where + St: Stream, + F: FnMut(T, St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.accum.is_none() && self.future.is_none() + } +} + +impl Future for Fold +where + St: Stream, + F: FnMut(T, St::Item) -> Fut, + Fut: Future, +{ + type Output = T; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + // we're currently processing a future to produce a new accum value + *this.accum = Some(ready!(fut.poll(cx))); + this.future.set(None); + } else if this.accum.is_some() { + // we're waiting on a new item from the stream + let res = ready!(this.stream.as_mut().poll_next(cx)); + let a = this.accum.take().unwrap(); + if let Some(item) = res { + this.future.set(Some((this.f)(a, item))); + } else { + break a; + } + } else { + panic!("Fold polled after completion") + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each.rs new file mode 100644 index 00000000..5302b0e0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each.rs @@ -0,0 +1,78 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`for_each`](super::StreamExt::for_each) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct ForEach { + #[pin] + stream: St, + f: F, + #[pin] + future: Option, + } +} + +impl fmt::Debug for ForEach +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ForEach") + .field("stream", &self.stream) + .field("future", &self.future) + .finish() + } +} + +impl ForEach +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, future: None } + } +} + +impl FusedFuture for ForEach +where + St: FusedStream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.future.is_none() && self.stream.is_terminated() + } +} + +impl Future for ForEach +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + let mut this = self.project(); + loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + ready!(fut.poll(cx)); + this.future.set(None); + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + this.future.set(Some((this.f)(item))); + } else { + break; + } + } + Poll::Ready(()) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each_concurrent.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each_concurrent.rs new file mode 100644 index 00000000..6c18753e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/for_each_concurrent.rs @@ -0,0 +1,119 @@ +use crate::stream::{FuturesUnordered, StreamExt}; +use core::fmt; +use core::num::NonZeroUsize; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`for_each_concurrent`](super::StreamExt::for_each_concurrent) + /// method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct ForEachConcurrent { + #[pin] + stream: Option, + f: F, + futures: FuturesUnordered, + limit: Option, + } +} + +impl fmt::Debug for ForEachConcurrent +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ForEachConcurrent") + .field("stream", &self.stream) + .field("futures", &self.futures) + .field("limit", &self.limit) + .finish() + } +} + +impl ForEachConcurrent +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, limit: Option, f: F) -> Self { + Self { + stream: Some(stream), + // Note: `limit` = 0 gets ignored. + limit: limit.and_then(NonZeroUsize::new), + f, + futures: FuturesUnordered::new(), + } + } +} + +impl FusedFuture for ForEachConcurrent +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.stream.is_none() && self.futures.is_empty() + } +} + +impl Future for ForEachConcurrent +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + let mut this = self.project(); + loop { + let mut made_progress_this_iter = false; + + // Check if we've already created a number of futures greater than `limit` + if this.limit.map(|limit| limit.get() > this.futures.len()).unwrap_or(true) { + let mut stream_completed = false; + let elem = if let Some(stream) = this.stream.as_mut().as_pin_mut() { + match stream.poll_next(cx) { + Poll::Ready(Some(elem)) => { + made_progress_this_iter = true; + Some(elem) + } + Poll::Ready(None) => { + stream_completed = true; + None + } + Poll::Pending => None, + } + } else { + None + }; + if stream_completed { + this.stream.set(None); + } + if let Some(elem) = elem { + this.futures.push((this.f)(elem)); + } + } + + match this.futures.poll_next_unpin(cx) { + Poll::Ready(Some(())) => made_progress_this_iter = true, + Poll::Ready(None) => { + if this.stream.is_none() { + return Poll::Ready(()); + } + } + Poll::Pending => {} + } + + if !made_progress_this_iter { + return Poll::Pending; + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/forward.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/forward.rs new file mode 100644 index 00000000..1fe24273 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/forward.rs @@ -0,0 +1,75 @@ +use crate::stream::Fuse; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`forward`](super::StreamExt::forward) method. + #[project = ForwardProj] + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Forward { + #[pin] + sink: Option, + #[pin] + stream: Fuse, + buffered_item: Option, + } +} + +impl Forward { + pub(crate) fn new(stream: St, sink: Si) -> Self { + Self { sink: Some(sink), stream: Fuse::new(stream), buffered_item: None } + } +} + +impl FusedFuture for Forward +where + Si: Sink, + St: Stream>, +{ + fn is_terminated(&self) -> bool { + self.sink.is_none() + } +} + +impl Future for Forward +where + Si: Sink, + St: Stream>, +{ + type Output = Result<(), E>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let ForwardProj { mut sink, mut stream, buffered_item } = self.project(); + let mut si = sink.as_mut().as_pin_mut().expect("polled `Forward` after completion"); + + loop { + // If we've got an item buffered already, we need to write it to the + // sink before we can do anything else + if buffered_item.is_some() { + ready!(si.as_mut().poll_ready(cx))?; + si.as_mut().start_send(buffered_item.take().unwrap())?; + } + + match stream.as_mut().poll_next(cx)? { + Poll::Ready(Some(item)) => { + *buffered_item = Some(item); + } + Poll::Ready(None) => { + ready!(si.poll_close(cx))?; + sink.set(None); + return Poll::Ready(Ok(())); + } + Poll::Pending => { + ready!(si.poll_flush(cx))?; + return Poll::Pending; + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/fuse.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/fuse.rs new file mode 100644 index 00000000..fe67813e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/fuse.rs @@ -0,0 +1,75 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`fuse`](super::StreamExt::fuse) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Fuse { + #[pin] + stream: St, + done: bool, + } +} + +impl Fuse { + pub(super) fn new(stream: St) -> Self { + Self { stream, done: false } + } + + /// Returns whether the underlying stream has finished or not. + /// + /// If this method returns `true`, then all future calls to poll are + /// guaranteed to return `None`. If this returns `false`, then the + /// underlying stream is still in use. + pub fn is_done(&self) -> bool { + self.done + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Fuse { + fn is_terminated(&self) -> bool { + self.done + } +} + +impl Stream for Fuse { + type Item = S::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + + if *this.done { + return Poll::Ready(None); + } + + let item = ready!(this.stream.poll_next(cx)); + if item.is_none() { + *this.done = true; + } + Poll::Ready(item) + } + + fn size_hint(&self) -> (usize, Option) { + if self.done { + (0, Some(0)) + } else { + self.stream.size_hint() + } + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl, Item> Sink for Fuse { + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/into_future.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/into_future.rs new file mode 100644 index 00000000..8abfddcc --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/into_future.rs @@ -0,0 +1,90 @@ +use crate::stream::StreamExt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; + +/// Future for the [`into_future`](super::StreamExt::into_future) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct StreamFuture { + stream: Option, +} + +impl StreamFuture { + pub(super) fn new(stream: St) -> Self { + Self { stream: Some(stream) } + } + + /// Acquires a reference to the underlying stream that this combinator is + /// pulling from. + /// + /// This method returns an `Option` to account for the fact that `StreamFuture`'s + /// implementation of `Future::poll` consumes the underlying stream during polling + /// in order to return it to the caller of `Future::poll` if the stream yielded + /// an element. + pub fn get_ref(&self) -> Option<&St> { + self.stream.as_ref() + } + + /// Acquires a mutable reference to the underlying stream that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + /// + /// This method returns an `Option` to account for the fact that `StreamFuture`'s + /// implementation of `Future::poll` consumes the underlying stream during polling + /// in order to return it to the caller of `Future::poll` if the stream yielded + /// an element. + pub fn get_mut(&mut self) -> Option<&mut St> { + self.stream.as_mut() + } + + /// Acquires a pinned mutable reference to the underlying stream that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + /// + /// This method returns an `Option` to account for the fact that `StreamFuture`'s + /// implementation of `Future::poll` consumes the underlying stream during polling + /// in order to return it to the caller of `Future::poll` if the stream yielded + /// an element. + pub fn get_pin_mut(self: Pin<&mut Self>) -> Option> { + self.get_mut().stream.as_mut().map(Pin::new) + } + + /// Consumes this combinator, returning the underlying stream. + /// + /// Note that this may discard intermediate state of this combinator, so + /// care should be taken to avoid losing resources when this is called. + /// + /// This method returns an `Option` to account for the fact that `StreamFuture`'s + /// implementation of `Future::poll` consumes the underlying stream during polling + /// in order to return it to the caller of `Future::poll` if the stream yielded + /// an element. + pub fn into_inner(self) -> Option { + self.stream + } +} + +impl FusedFuture for StreamFuture { + fn is_terminated(&self) -> bool { + self.stream.is_none() + } +} + +impl Future for StreamFuture { + type Output = (Option, St); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let item = { + let s = self.stream.as_mut().expect("polling StreamFuture twice"); + ready!(s.poll_next_unpin(cx)) + }; + let stream = self.stream.take().unwrap(); + Poll::Ready((item, stream)) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/map.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/map.rs new file mode 100644 index 00000000..88bb6129 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/map.rs @@ -0,0 +1,77 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +use crate::fns::FnMut1; + +pin_project! { + /// Stream for the [`map`](super::StreamExt::map) method. + #[must_use = "streams do nothing unless polled"] + pub struct Map { + #[pin] + stream: St, + f: F, + } +} + +impl fmt::Debug for Map +where + St: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Map").field("stream", &self.stream).finish() + } +} + +impl Map { + pub(crate) fn new(stream: St, f: F) -> Self { + Self { stream, f } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Map +where + St: FusedStream, + F: FnMut1, +{ + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Stream for Map +where + St: Stream, + F: FnMut1, +{ + type Item = F::Output; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + let res = ready!(this.stream.as_mut().poll_next(cx)); + Poll::Ready(res.map(|x| this.f.call_mut(x))) + } + + fn size_hint(&self) -> (usize, Option) { + self.stream.size_hint() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Map +where + St: Stream + Sink, + F: FnMut1, +{ + type Error = St::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/mod.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/mod.rs new file mode 100644 index 00000000..2da7036b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/mod.rs @@ -0,0 +1,1697 @@ +//! Streams +//! +//! This module contains a number of functions for working with `Stream`s, +//! including the `StreamExt` trait which adds methods to `Stream` types. + +use crate::future::{assert_future, Either}; +use crate::stream::assert_stream; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +use core::pin::Pin; +#[cfg(feature = "sink")] +use futures_core::stream::TryStream; +#[cfg(feature = "alloc")] +use futures_core::stream::{BoxStream, LocalBoxStream}; +use futures_core::{ + future::Future, + stream::{FusedStream, Stream}, + task::{Context, Poll}, +}; +#[cfg(feature = "sink")] +use futures_sink::Sink; + +use crate::fns::{inspect_fn, InspectFn}; + +mod chain; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::chain::Chain; + +mod collect; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::collect::Collect; + +mod unzip; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::unzip::Unzip; + +mod concat; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::concat::Concat; + +mod count; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::count::Count; + +mod cycle; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::cycle::Cycle; + +mod enumerate; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::enumerate::Enumerate; + +mod filter; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::filter::Filter; + +mod filter_map; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::filter_map::FilterMap; + +mod flatten; + +delegate_all!( + /// Stream for the [`flatten`](StreamExt::flatten) method. + Flatten( + flatten::Flatten + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St| flatten::Flatten::new(x)] + where St: Stream +); + +mod fold; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::fold::Fold; + +mod any; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::any::Any; + +mod all; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::all::All; + +#[cfg(feature = "sink")] +mod forward; + +#[cfg(feature = "sink")] +delegate_all!( + /// Future for the [`forward`](super::StreamExt::forward) method. + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + Forward( + forward::Forward + ): Debug + Future + FusedFuture + New[|x: St, y: Si| forward::Forward::new(x, y)] + where St: TryStream +); + +mod for_each; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::for_each::ForEach; + +mod fuse; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::fuse::Fuse; + +mod into_future; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::into_future::StreamFuture; + +delegate_all!( + /// Stream for the [`inspect`](StreamExt::inspect) method. + Inspect( + map::Map> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St, f: F| map::Map::new(x, inspect_fn(f))] +); + +mod map; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::map::Map; + +delegate_all!( + /// Stream for the [`flat_map`](StreamExt::flat_map) method. + FlatMap( + flatten::Flatten, U> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| flatten::Flatten::new(Map::new(x, f))] +); + +mod next; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::next::Next; + +mod select_next_some; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::select_next_some::SelectNextSome; + +mod peek; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::peek::{NextIf, NextIfEq, Peek, PeekMut, Peekable}; + +mod skip; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::skip::Skip; + +mod skip_while; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::skip_while::SkipWhile; + +mod take; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::take::Take; + +mod take_while; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::take_while::TakeWhile; + +mod take_until; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::take_until::TakeUntil; + +mod then; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::then::Then; + +mod zip; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::zip::Zip; + +#[cfg(feature = "alloc")] +mod chunks; +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::chunks::Chunks; + +#[cfg(feature = "alloc")] +mod ready_chunks; +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::ready_chunks::ReadyChunks; + +mod scan; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::scan::Scan; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod buffer_unordered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::buffer_unordered::BufferUnordered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod buffered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::buffered::Buffered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub(crate) mod flatten_unordered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] +pub use self::flatten_unordered::FlattenUnordered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +delegate_all!( + /// Stream for the [`flat_map_unordered`](StreamExt::flat_map_unordered) method. + FlatMapUnordered( + FlattenUnordered> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, limit: Option, f: F| FlattenUnordered::new(Map::new(x, f), limit)] + where St: Stream, U: Stream, U: Unpin, F: FnMut(St::Item) -> U +); + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod for_each_concurrent; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::for_each_concurrent::ForEachConcurrent; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +#[cfg(feature = "alloc")] +mod split; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "sink")] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::split::{ReuniteError, SplitSink, SplitStream}; + +#[cfg(feature = "std")] +mod catch_unwind; +#[cfg(feature = "std")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::catch_unwind::CatchUnwind; + +impl StreamExt for T where T: Stream {} + +/// An extension trait for `Stream`s that provides a variety of convenient +/// combinator functions. +pub trait StreamExt: Stream { + /// Creates a future that resolves to the next item in the stream. + /// + /// Note that because `next` doesn't take ownership over the stream, + /// the [`Stream`] type must be [`Unpin`]. If you want to use `next` with a + /// [`!Unpin`](Unpin) stream, you'll first have to pin the stream. This can + /// be done by boxing the stream using [`Box::pin`] or + /// pinning it to the stack using the `pin_mut!` macro from the `pin_utils` + /// crate. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let mut stream = stream::iter(1..=3); + /// + /// assert_eq!(stream.next().await, Some(1)); + /// assert_eq!(stream.next().await, Some(2)); + /// assert_eq!(stream.next().await, Some(3)); + /// assert_eq!(stream.next().await, None); + /// # }); + /// ``` + fn next(&mut self) -> Next<'_, Self> + where + Self: Unpin, + { + assert_future::, _>(Next::new(self)) + } + + /// Converts this stream into a future of `(next_item, tail_of_stream)`. + /// If the stream terminates, then the next item is [`None`]. + /// + /// The returned future can be used to compose streams and futures together + /// by placing everything into the "world of futures". + /// + /// Note that because `into_future` moves the stream, the [`Stream`] type + /// must be [`Unpin`]. If you want to use `into_future` with a + /// [`!Unpin`](Unpin) stream, you'll first have to pin the stream. This can + /// be done by boxing the stream using [`Box::pin`] or + /// pinning it to the stack using the `pin_mut!` macro from the `pin_utils` + /// crate. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=3); + /// + /// let (item, stream) = stream.into_future().await; + /// assert_eq!(Some(1), item); + /// + /// let (item, stream) = stream.into_future().await; + /// assert_eq!(Some(2), item); + /// # }); + /// ``` + fn into_future(self) -> StreamFuture + where + Self: Sized + Unpin, + { + assert_future::<(Option, Self), _>(StreamFuture::new(self)) + } + + /// Maps this stream's items to a different type, returning a new stream of + /// the resulting type. + /// + /// The provided closure is executed over all elements of this stream as + /// they are made available. It is executed inline with calls to + /// [`poll_next`](Stream::poll_next). + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it, similar to the existing `map` methods in the + /// standard library. + /// + /// See [`StreamExt::then`](Self::then) if you want to use a closure that + /// returns a future instead of a value. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=3); + /// let stream = stream.map(|x| x + 3); + /// + /// assert_eq!(vec![4, 5, 6], stream.collect::>().await); + /// # }); + /// ``` + fn map(self, f: F) -> Map + where + F: FnMut(Self::Item) -> T, + Self: Sized, + { + assert_stream::(Map::new(self, f)) + } + + /// Creates a stream which gives the current iteration count as well as + /// the next value. + /// + /// The stream returned yields pairs `(i, val)`, where `i` is the + /// current index of iteration and `val` is the value returned by the + /// stream. + /// + /// `enumerate()` keeps its count as a [`usize`]. If you want to count by a + /// different sized integer, the [`zip`](StreamExt::zip) function provides similar + /// functionality. + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so enumerating more than + /// [`prim@usize::max_value()`] elements either produces the wrong result or panics. If + /// debug assertions are enabled, a panic is guaranteed. + /// + /// # Panics + /// + /// The returned stream might panic if the to-be-returned index would + /// overflow a [`usize`]. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(vec!['a', 'b', 'c']); + /// + /// let mut stream = stream.enumerate(); + /// + /// assert_eq!(stream.next().await, Some((0, 'a'))); + /// assert_eq!(stream.next().await, Some((1, 'b'))); + /// assert_eq!(stream.next().await, Some((2, 'c'))); + /// assert_eq!(stream.next().await, None); + /// # }); + /// ``` + fn enumerate(self) -> Enumerate + where + Self: Sized, + { + assert_stream::<(usize, Self::Item), _>(Enumerate::new(self)) + } + + /// Filters the values produced by this stream according to the provided + /// asynchronous predicate. + /// + /// As values of this stream are made available, the provided predicate `f` + /// will be run against them. If the predicate returns a `Future` which + /// resolves to `true`, then the stream will yield the value, but if the + /// predicate returns a `Future` which resolves to `false`, then the value + /// will be discarded and the next value will be produced. + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it, similar to the existing `filter` methods in the + /// standard library. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10); + /// let events = stream.filter(|x| future::ready(x % 2 == 0)); + /// + /// assert_eq!(vec![2, 4, 6, 8, 10], events.collect::>().await); + /// # }); + /// ``` + fn filter(self, f: F) -> Filter + where + F: FnMut(&Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_stream::(Filter::new(self, f)) + } + + /// Filters the values produced by this stream while simultaneously mapping + /// them to a different type according to the provided asynchronous closure. + /// + /// As values of this stream are made available, the provided function will + /// be run on them. If the future returned by the predicate `f` resolves to + /// [`Some(item)`](Some) then the stream will yield the value `item`, but if + /// it resolves to [`None`] then the next value will be produced. + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it, similar to the existing `filter_map` methods in + /// the standard library. + /// + /// # Examples + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10); + /// let events = stream.filter_map(|x| async move { + /// if x % 2 == 0 { Some(x + 1) } else { None } + /// }); + /// + /// assert_eq!(vec![3, 5, 7, 9, 11], events.collect::>().await); + /// # }); + /// ``` + fn filter_map(self, f: F) -> FilterMap + where + F: FnMut(Self::Item) -> Fut, + Fut: Future>, + Self: Sized, + { + assert_stream::(FilterMap::new(self, f)) + } + + /// Computes from this stream's items new items of a different type using + /// an asynchronous closure. + /// + /// The provided closure `f` will be called with an `Item` once a value is + /// ready, it returns a future which will then be run to completion + /// to produce the next value on this stream. + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it. + /// + /// See [`StreamExt::map`](Self::map) if you want to use a closure that + /// returns a value instead of a future. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=3); + /// let stream = stream.then(|x| async move { x + 3 }); + /// + /// assert_eq!(vec![4, 5, 6], stream.collect::>().await); + /// # }); + /// ``` + fn then(self, f: F) -> Then + where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_stream::(Then::new(self, f)) + } + + /// Transforms a stream into a collection, returning a + /// future representing the result of that computation. + /// + /// The returned future will be resolved when the stream terminates. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::StreamExt; + /// use std::thread; + /// + /// let (tx, rx) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// for i in 1..=5 { + /// tx.unbounded_send(i).unwrap(); + /// } + /// }); + /// + /// let output = rx.collect::>().await; + /// assert_eq!(output, vec![1, 2, 3, 4, 5]); + /// # }); + /// ``` + fn collect>(self) -> Collect + where + Self: Sized, + { + assert_future::(Collect::new(self)) + } + + /// Converts a stream of pairs into a future, which + /// resolves to pair of containers. + /// + /// `unzip()` produces a future, which resolves to two + /// collections: one from the left elements of the pairs, + /// and one from the right elements. + /// + /// The returned future will be resolved when the stream terminates. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::StreamExt; + /// use std::thread; + /// + /// let (tx, rx) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// tx.unbounded_send((1, 2)).unwrap(); + /// tx.unbounded_send((3, 4)).unwrap(); + /// tx.unbounded_send((5, 6)).unwrap(); + /// }); + /// + /// let (o1, o2): (Vec<_>, Vec<_>) = rx.unzip().await; + /// assert_eq!(o1, vec![1, 3, 5]); + /// assert_eq!(o2, vec![2, 4, 6]); + /// # }); + /// ``` + fn unzip(self) -> Unzip + where + FromA: Default + Extend, + FromB: Default + Extend, + Self: Sized + Stream, + { + assert_future::<(FromA, FromB), _>(Unzip::new(self)) + } + + /// Concatenate all items of a stream into a single extendable + /// destination, returning a future representing the end result. + /// + /// This combinator will extend the first item with the contents + /// of all the subsequent results of the stream. If the stream is + /// empty, the default value will be returned. + /// + /// Works with all collections that implement the + /// [`Extend`](std::iter::Extend) trait. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::StreamExt; + /// use std::thread; + /// + /// let (tx, rx) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// for i in (0..3).rev() { + /// let n = i * 3; + /// tx.unbounded_send(vec![n + 1, n + 2, n + 3]).unwrap(); + /// } + /// }); + /// + /// let result = rx.concat().await; + /// + /// assert_eq!(result, vec![7, 8, 9, 4, 5, 6, 1, 2, 3]); + /// # }); + /// ``` + fn concat(self) -> Concat + where + Self: Sized, + Self::Item: Extend<<::Item as IntoIterator>::Item> + IntoIterator + Default, + { + assert_future::(Concat::new(self)) + } + + /// Drives the stream to completion, counting the number of items. + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so counting elements of a + /// stream with more than [`usize::MAX`] elements either produces the wrong + /// result or panics. If debug assertions are enabled, a panic is guaranteed. + /// + /// # Panics + /// + /// This function might panic if the iterator has more than [`usize::MAX`] + /// elements. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10); + /// let count = stream.count().await; + /// + /// assert_eq!(count, 10); + /// # }); + /// ``` + fn count(self) -> Count + where + Self: Sized, + { + assert_future::(Count::new(self)) + } + + /// Repeats a stream endlessly. + /// + /// The stream never terminates. Note that you likely want to avoid + /// usage of `collect` or such on the returned stream as it will exhaust + /// available memory as it tries to just fill up all RAM. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// let a = [1, 2, 3]; + /// let mut s = stream::iter(a.iter()).cycle(); + /// + /// assert_eq!(s.next().await, Some(&1)); + /// assert_eq!(s.next().await, Some(&2)); + /// assert_eq!(s.next().await, Some(&3)); + /// assert_eq!(s.next().await, Some(&1)); + /// assert_eq!(s.next().await, Some(&2)); + /// assert_eq!(s.next().await, Some(&3)); + /// assert_eq!(s.next().await, Some(&1)); + /// # }); + /// ``` + fn cycle(self) -> Cycle + where + Self: Sized + Clone, + { + assert_stream::(Cycle::new(self)) + } + + /// Execute an accumulating asynchronous computation over a stream, + /// collecting all the values into one final result. + /// + /// This combinator will accumulate all values returned by this stream + /// according to the closure provided. The initial state is also provided to + /// this method and then is returned again by each execution of the closure. + /// Once the entire stream has been exhausted the returned future will + /// resolve to this value. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let number_stream = stream::iter(0..6); + /// let sum = number_stream.fold(0, |acc, x| async move { acc + x }); + /// assert_eq!(sum.await, 15); + /// # }); + /// ``` + fn fold(self, init: T, f: F) -> Fold + where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_future::(Fold::new(self, f, init)) + } + + /// Execute predicate over asynchronous stream, and return `true` if any element in stream satisfied a predicate. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let number_stream = stream::iter(0..10); + /// let contain_three = number_stream.any(|i| async move { i == 3 }); + /// assert_eq!(contain_three.await, true); + /// # }); + /// ``` + fn any(self, f: F) -> Any + where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_future::(Any::new(self, f)) + } + + /// Execute predicate over asynchronous stream, and return `true` if all element in stream satisfied a predicate. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let number_stream = stream::iter(0..10); + /// let less_then_twenty = number_stream.all(|i| async move { i < 20 }); + /// assert_eq!(less_then_twenty.await, true); + /// # }); + /// ``` + fn all(self, f: F) -> All + where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_future::(All::new(self, f)) + } + + /// Flattens a stream of streams into just one continuous stream. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::StreamExt; + /// use std::thread; + /// + /// let (tx1, rx1) = mpsc::unbounded(); + /// let (tx2, rx2) = mpsc::unbounded(); + /// let (tx3, rx3) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// tx1.unbounded_send(1).unwrap(); + /// tx1.unbounded_send(2).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx2.unbounded_send(3).unwrap(); + /// tx2.unbounded_send(4).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx3.unbounded_send(rx1).unwrap(); + /// tx3.unbounded_send(rx2).unwrap(); + /// }); + /// + /// let output = rx3.flatten().collect::>().await; + /// assert_eq!(output, vec![1, 2, 3, 4]); + /// # }); + /// ``` + fn flatten(self) -> Flatten + where + Self::Item: Stream, + Self: Sized, + { + assert_stream::<::Item, _>(Flatten::new(self)) + } + + /// Flattens a stream of streams into just one continuous stream. Polls + /// inner streams produced by the base stream concurrently. + /// + /// The only argument is an optional limit on the number of concurrently + /// polled streams. If this limit is not `None`, no more than `limit` streams + /// will be polled at the same time. The `limit` argument is of type + /// `Into>`, and so can be provided as either `None`, + /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as + /// no limit at all, and will have the same result as passing in `None`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::StreamExt; + /// use std::thread; + /// + /// let (tx1, rx1) = mpsc::unbounded(); + /// let (tx2, rx2) = mpsc::unbounded(); + /// let (tx3, rx3) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// tx1.unbounded_send(1).unwrap(); + /// tx1.unbounded_send(2).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx2.unbounded_send(3).unwrap(); + /// tx2.unbounded_send(4).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx3.unbounded_send(rx1).unwrap(); + /// tx3.unbounded_send(rx2).unwrap(); + /// }); + /// + /// let mut output = rx3.flatten_unordered(None).collect::>().await; + /// output.sort(); + /// + /// assert_eq!(output, vec![1, 2, 3, 4]); + /// # }); + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn flatten_unordered(self, limit: impl Into>) -> FlattenUnordered + where + Self::Item: Stream + Unpin, + Self: Sized, + { + assert_stream::<::Item, _>(FlattenUnordered::new(self, limit.into())) + } + + /// Maps a stream like [`StreamExt::map`] but flattens nested `Stream`s. + /// + /// [`StreamExt::map`] is very useful, but if it produces a `Stream` instead, + /// you would have to chain combinators like `.map(f).flatten()` while this + /// combinator provides ability to write `.flat_map(f)` instead of chaining. + /// + /// The provided closure which produces inner streams is executed over all elements + /// of stream as last inner stream is terminated and next stream item is available. + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it, similar to the existing `flat_map` methods in the + /// standard library. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=3); + /// let stream = stream.flat_map(|x| stream::iter(vec![x + 3; x])); + /// + /// assert_eq!(vec![4, 5, 5, 6, 6, 6], stream.collect::>().await); + /// # }); + /// ``` + fn flat_map(self, f: F) -> FlatMap + where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized, + { + assert_stream::(FlatMap::new(self, f)) + } + + /// Maps a stream like [`StreamExt::map`] but flattens nested `Stream`s + /// and polls them concurrently, yielding items in any order, as they made + /// available. + /// + /// [`StreamExt::map`] is very useful, but if it produces `Stream`s + /// instead, and you need to poll all of them concurrently, you would + /// have to use something like `for_each_concurrent` and merge values + /// by hand. This combinator provides ability to collect all values + /// from concurrently polled streams into one stream. + /// + /// The first argument is an optional limit on the number of concurrently + /// polled streams. If this limit is not `None`, no more than `limit` streams + /// will be polled at the same time. The `limit` argument is of type + /// `Into>`, and so can be provided as either `None`, + /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as + /// no limit at all, and will have the same result as passing in `None`. + /// + /// The provided closure which produces inner streams is executed over + /// all elements of stream as next stream item is available and limit + /// of concurrently processed streams isn't exceeded. + /// + /// Note that this function consumes the stream passed into it and + /// returns a wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..5); + /// let stream = stream.flat_map_unordered(1, |x| stream::iter(vec![x; x])); + /// let mut values = stream.collect::>().await; + /// values.sort(); + /// + /// assert_eq!(vec![1usize, 2, 2, 3, 3, 3, 4, 4, 4, 4], values); + /// # }); + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn flat_map_unordered( + self, + limit: impl Into>, + f: F, + ) -> FlatMapUnordered + where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized, + { + assert_stream::(FlatMapUnordered::new(self, limit.into(), f)) + } + + /// Combinator similar to [`StreamExt::fold`] that holds internal state + /// and produces a new stream. + /// + /// Accepts initial state and closure which will be applied to each element + /// of the stream until provided closure returns `None`. Once `None` is + /// returned, stream will be terminated. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10); + /// + /// let stream = stream.scan(0, |state, x| { + /// *state += x; + /// future::ready(if *state < 10 { Some(x) } else { None }) + /// }); + /// + /// assert_eq!(vec![1, 2, 3], stream.collect::>().await); + /// # }); + /// ``` + fn scan(self, initial_state: S, f: F) -> Scan + where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future>, + Self: Sized, + { + assert_stream::(Scan::new(self, initial_state, f)) + } + + /// Skip elements on this stream while the provided asynchronous predicate + /// resolves to `true`. + /// + /// This function, like `Iterator::skip_while`, will skip elements on the + /// stream until the predicate `f` resolves to `false`. Once one element + /// returns `false`, all future elements will be returned from the underlying + /// stream. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10); + /// + /// let stream = stream.skip_while(|x| future::ready(*x <= 5)); + /// + /// assert_eq!(vec![6, 7, 8, 9, 10], stream.collect::>().await); + /// # }); + /// ``` + fn skip_while(self, f: F) -> SkipWhile + where + F: FnMut(&Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_stream::(SkipWhile::new(self, f)) + } + + /// Take elements from this stream while the provided asynchronous predicate + /// resolves to `true`. + /// + /// This function, like `Iterator::take_while`, will take elements from the + /// stream until the predicate `f` resolves to `false`. Once one element + /// returns `false`, it will always return that the stream is done. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10); + /// + /// let stream = stream.take_while(|x| future::ready(*x <= 5)); + /// + /// assert_eq!(vec![1, 2, 3, 4, 5], stream.collect::>().await); + /// # }); + /// ``` + fn take_while(self, f: F) -> TakeWhile + where + F: FnMut(&Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_stream::(TakeWhile::new(self, f)) + } + + /// Take elements from this stream until the provided future resolves. + /// + /// This function will take elements from the stream until the provided + /// stopping future `fut` resolves. Once the `fut` future becomes ready, + /// this stream combinator will always return that the stream is done. + /// + /// The stopping future may return any type. Once the stream is stopped + /// the result of the stopping future may be accessed with `TakeUntil::take_result()`. + /// The stream may also be resumed with `TakeUntil::take_future()`. + /// See the documentation of [`TakeUntil`] for more information. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// use futures::task::Poll; + /// + /// let stream = stream::iter(1..=10); + /// + /// let mut i = 0; + /// let stop_fut = future::poll_fn(|_cx| { + /// i += 1; + /// if i <= 5 { + /// Poll::Pending + /// } else { + /// Poll::Ready(()) + /// } + /// }); + /// + /// let stream = stream.take_until(stop_fut); + /// + /// assert_eq!(vec![1, 2, 3, 4, 5], stream.collect::>().await); + /// # }); + /// ``` + fn take_until(self, fut: Fut) -> TakeUntil + where + Fut: Future, + Self: Sized, + { + assert_stream::(TakeUntil::new(self, fut)) + } + + /// Runs this stream to completion, executing the provided asynchronous + /// closure for each element on the stream. + /// + /// The closure provided will be called for each item this stream produces, + /// yielding a future. That future will then be executed to completion + /// before moving on to the next item. + /// + /// The returned value is a `Future` where the `Output` type is `()`; it is + /// executed entirely for its side effects. + /// + /// To process each item in the stream and produce another stream instead + /// of a single future, use `then` instead. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// + /// let mut x = 0; + /// + /// { + /// let fut = stream::repeat(1).take(3).for_each(|item| { + /// x += item; + /// future::ready(()) + /// }); + /// fut.await; + /// } + /// + /// assert_eq!(x, 3); + /// # }); + /// ``` + fn for_each(self, f: F) -> ForEach + where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_future::<(), _>(ForEach::new(self, f)) + } + + /// Runs this stream to completion, executing the provided asynchronous + /// closure for each element on the stream concurrently as elements become + /// available. + /// + /// This is similar to [`StreamExt::for_each`], but the futures + /// produced by the closure are run concurrently (but not in parallel-- + /// this combinator does not introduce any threads). + /// + /// The closure provided will be called for each item this stream produces, + /// yielding a future. That future will then be executed to completion + /// concurrently with the other futures produced by the closure. + /// + /// The first argument is an optional limit on the number of concurrent + /// futures. If this limit is not `None`, no more than `limit` futures + /// will be run concurrently. The `limit` argument is of type + /// `Into>`, and so can be provided as either `None`, + /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as + /// no limit at all, and will have the same result as passing in `None`. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::oneshot; + /// use futures::stream::{self, StreamExt}; + /// + /// let (tx1, rx1) = oneshot::channel(); + /// let (tx2, rx2) = oneshot::channel(); + /// let (tx3, rx3) = oneshot::channel(); + /// + /// let fut = stream::iter(vec![rx1, rx2, rx3]).for_each_concurrent( + /// /* limit */ 2, + /// |rx| async move { + /// rx.await.unwrap(); + /// } + /// ); + /// tx1.send(()).unwrap(); + /// tx2.send(()).unwrap(); + /// tx3.send(()).unwrap(); + /// fut.await; + /// # }) + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn for_each_concurrent( + self, + limit: impl Into>, + f: F, + ) -> ForEachConcurrent + where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized, + { + assert_future::<(), _>(ForEachConcurrent::new(self, limit.into(), f)) + } + + /// Creates a new stream of at most `n` items of the underlying stream. + /// + /// Once `n` items have been yielded from this stream then it will always + /// return that the stream is done. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10).take(3); + /// + /// assert_eq!(vec![1, 2, 3], stream.collect::>().await); + /// # }); + /// ``` + fn take(self, n: usize) -> Take + where + Self: Sized, + { + assert_stream::(Take::new(self, n)) + } + + /// Creates a new stream which skips `n` items of the underlying stream. + /// + /// Once `n` items have been skipped from this stream then it will always + /// return the remaining items on this stream. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(1..=10).skip(5); + /// + /// assert_eq!(vec![6, 7, 8, 9, 10], stream.collect::>().await); + /// # }); + /// ``` + fn skip(self, n: usize) -> Skip + where + Self: Sized, + { + assert_stream::(Skip::new(self, n)) + } + + /// Fuse a stream such that [`poll_next`](Stream::poll_next) will never + /// again be called once it has finished. This method can be used to turn + /// any `Stream` into a `FusedStream`. + /// + /// Normally, once a stream has returned [`None`] from + /// [`poll_next`](Stream::poll_next) any further calls could exhibit bad + /// behavior such as block forever, panic, never return, etc. If it is known + /// that [`poll_next`](Stream::poll_next) may be called after stream + /// has already finished, then this method can be used to ensure that it has + /// defined semantics. + /// + /// The [`poll_next`](Stream::poll_next) method of a `fuse`d stream + /// is guaranteed to return [`None`] after the underlying stream has + /// finished. + /// + /// # Examples + /// + /// ``` + /// use futures::executor::block_on_stream; + /// use futures::stream::{self, StreamExt}; + /// use futures::task::Poll; + /// + /// let mut x = 0; + /// let stream = stream::poll_fn(|_| { + /// x += 1; + /// match x { + /// 0..=2 => Poll::Ready(Some(x)), + /// 3 => Poll::Ready(None), + /// _ => panic!("should not happen") + /// } + /// }).fuse(); + /// + /// let mut iter = block_on_stream(stream); + /// assert_eq!(Some(1), iter.next()); + /// assert_eq!(Some(2), iter.next()); + /// assert_eq!(None, iter.next()); + /// assert_eq!(None, iter.next()); + /// // ... + /// ``` + fn fuse(self) -> Fuse + where + Self: Sized, + { + assert_stream::(Fuse::new(self)) + } + + /// Borrows a stream, rather than consuming it. + /// + /// This is useful to allow applying stream adaptors while still retaining + /// ownership of the original stream. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let mut stream = stream::iter(1..5); + /// + /// let sum = stream.by_ref() + /// .take(2) + /// .fold(0, |a, b| async move { a + b }) + /// .await; + /// assert_eq!(sum, 3); + /// + /// // You can use the stream again + /// let sum = stream.take(2) + /// .fold(0, |a, b| async move { a + b }) + /// .await; + /// assert_eq!(sum, 7); + /// # }); + /// ``` + fn by_ref(&mut self) -> &mut Self { + self + } + + /// Catches unwinding panics while polling the stream. + /// + /// Caught panic (if any) will be the last element of the resulting stream. + /// + /// In general, panics within a stream can propagate all the way out to the + /// task level. This combinator makes it possible to halt unwinding within + /// the stream itself. It's most commonly used within task executors. This + /// method should not be used for error handling. + /// + /// Note that this method requires the `UnwindSafe` bound from the standard + /// library. This isn't always applied automatically, and the standard + /// library provides an `AssertUnwindSafe` wrapper type to apply it + /// after-the fact. To assist using this method, the [`Stream`] trait is + /// also implemented for `AssertUnwindSafe` where `St` implements + /// [`Stream`]. + /// + /// This method is only available when the `std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream = stream::iter(vec![Some(10), None, Some(11)]); + /// // Panic on second element + /// let stream_panicking = stream.map(|o| o.unwrap()); + /// // Collect all the results + /// let stream = stream_panicking.catch_unwind(); + /// + /// let results: Vec> = stream.collect().await; + /// match results[0] { + /// Ok(10) => {} + /// _ => panic!("unexpected result!"), + /// } + /// assert!(results[1].is_err()); + /// assert_eq!(results.len(), 2); + /// # }); + /// ``` + #[cfg(feature = "std")] + fn catch_unwind(self) -> CatchUnwind + where + Self: Sized + std::panic::UnwindSafe, + { + assert_stream(CatchUnwind::new(self)) + } + + /// Wrap the stream in a Box, pinning it. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "alloc")] + fn boxed<'a>(self) -> BoxStream<'a, Self::Item> + where + Self: Sized + Send + 'a, + { + assert_stream::(Box::pin(self)) + } + + /// Wrap the stream in a Box, pinning it. + /// + /// Similar to `boxed`, but without the `Send` requirement. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "alloc")] + fn boxed_local<'a>(self) -> LocalBoxStream<'a, Self::Item> + where + Self: Sized + 'a, + { + assert_stream::(Box::pin(self)) + } + + /// An adaptor for creating a buffered list of pending futures. + /// + /// If this stream's item can be converted into a future, then this adaptor + /// will buffer up to at most `n` futures and then return the outputs in the + /// same order as the underlying stream. No more than `n` futures will be + /// buffered at any point in time, and less than `n` may also be buffered + /// depending on the state of each future. + /// + /// The returned stream will be a stream of each future's output. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn buffered(self, n: usize) -> Buffered + where + Self::Item: Future, + Self: Sized, + { + assert_stream::<::Output, _>(Buffered::new(self, n)) + } + + /// An adaptor for creating a buffered list of pending futures (unordered). + /// + /// If this stream's item can be converted into a future, then this adaptor + /// will buffer up to `n` futures and then return the outputs in the order + /// in which they complete. No more than `n` futures will be buffered at + /// any point in time, and less than `n` may also be buffered depending on + /// the state of each future. + /// + /// The returned stream will be a stream of each future's output. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::oneshot; + /// use futures::stream::{self, StreamExt}; + /// + /// let (send_one, recv_one) = oneshot::channel(); + /// let (send_two, recv_two) = oneshot::channel(); + /// + /// let stream_of_futures = stream::iter(vec![recv_one, recv_two]); + /// let mut buffered = stream_of_futures.buffer_unordered(10); + /// + /// send_two.send(2i32)?; + /// assert_eq!(buffered.next().await, Some(Ok(2i32))); + /// + /// send_one.send(1i32)?; + /// assert_eq!(buffered.next().await, Some(Ok(1i32))); + /// + /// assert_eq!(buffered.next().await, None); + /// # Ok::<(), i32>(()) }).unwrap(); + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn buffer_unordered(self, n: usize) -> BufferUnordered + where + Self::Item: Future, + Self: Sized, + { + assert_stream::<::Output, _>(BufferUnordered::new(self, n)) + } + + /// An adapter for zipping two streams together. + /// + /// The zipped stream waits for both streams to produce an item, and then + /// returns that pair. If either stream ends then the zipped stream will + /// also end. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream1 = stream::iter(1..=3); + /// let stream2 = stream::iter(5..=10); + /// + /// let vec = stream1.zip(stream2) + /// .collect::>() + /// .await; + /// assert_eq!(vec![(1, 5), (2, 6), (3, 7)], vec); + /// # }); + /// ``` + /// + fn zip(self, other: St) -> Zip + where + St: Stream, + Self: Sized, + { + assert_stream::<(Self::Item, St::Item), _>(Zip::new(self, other)) + } + + /// Adapter for chaining two streams. + /// + /// The resulting stream emits elements from the first stream, and when + /// first stream reaches the end, emits the elements from the second stream. + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// + /// let stream1 = stream::iter(vec![Ok(10), Err(false)]); + /// let stream2 = stream::iter(vec![Err(true), Ok(20)]); + /// + /// let stream = stream1.chain(stream2); + /// + /// let result: Vec<_> = stream.collect().await; + /// assert_eq!(result, vec![ + /// Ok(10), + /// Err(false), + /// Err(true), + /// Ok(20), + /// ]); + /// # }); + /// ``` + fn chain(self, other: St) -> Chain + where + St: Stream, + Self: Sized, + { + assert_stream::(Chain::new(self, other)) + } + + /// Creates a new stream which exposes a `peek` method. + /// + /// Calling `peek` returns a reference to the next item in the stream. + fn peekable(self) -> Peekable + where + Self: Sized, + { + assert_stream::(Peekable::new(self)) + } + + /// An adaptor for chunking up items of the stream inside a vector. + /// + /// This combinator will attempt to pull items from this stream and buffer + /// them into a local vector. At most `capacity` items will get buffered + /// before they're yielded from the returned stream. + /// + /// Note that the vectors returned from this iterator may not always have + /// `capacity` elements. If the underlying stream ended and only a partial + /// vector was created, it'll be returned. Additionally if an error happens + /// from the underlying stream then the currently buffered items will be + /// yielded. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Panics + /// + /// This method will panic if `capacity` is zero. + #[cfg(feature = "alloc")] + fn chunks(self, capacity: usize) -> Chunks + where + Self: Sized, + { + assert_stream::, _>(Chunks::new(self, capacity)) + } + + /// An adaptor for chunking up ready items of the stream inside a vector. + /// + /// This combinator will attempt to pull ready items from this stream and + /// buffer them into a local vector. At most `capacity` items will get + /// buffered before they're yielded from the returned stream. If underlying + /// stream returns `Poll::Pending`, and collected chunk is not empty, it will + /// be immediately returned. + /// + /// If the underlying stream ended and only a partial vector was created, + /// it will be returned. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Panics + /// + /// This method will panic if `capacity` is zero. + #[cfg(feature = "alloc")] + fn ready_chunks(self, capacity: usize) -> ReadyChunks + where + Self: Sized, + { + assert_stream::, _>(ReadyChunks::new(self, capacity)) + } + + /// A future that completes after the given stream has been fully processed + /// into the sink and the sink has been flushed and closed. + /// + /// This future will drive the stream to keep producing items until it is + /// exhausted, sending each item to the sink. It will complete once the + /// stream is exhausted, the sink has received and flushed all items, and + /// the sink is closed. Note that neither the original stream nor provided + /// sink will be output by this future. Pass the sink by `Pin<&mut S>` + /// (for example, via `forward(&mut sink)` inside an `async` fn/block) in + /// order to preserve access to the `Sink`. If the stream produces an error, + /// that error will be returned by this future without flushing/closing the sink. + #[cfg(feature = "sink")] + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + fn forward(self, sink: S) -> Forward + where + S: Sink, + Self: TryStream + Sized, + // Self: TryStream + Sized + Stream::Ok, ::Error>>, + { + // TODO: type mismatch resolving `::Item == std::result::Result<::Ok, ::Error>` + // assert_future::, _>(Forward::new(self, sink)) + Forward::new(self, sink) + } + + /// Splits this `Stream + Sink` object into separate `Sink` and `Stream` + /// objects. + /// + /// This can be useful when you want to split ownership between tasks, or + /// allow direct interaction between the two objects (e.g. via + /// `Sink::send_all`). + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + #[cfg(feature = "sink")] + #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn split(self) -> (SplitSink, SplitStream) + where + Self: Sink + Sized, + { + let (sink, stream) = split::split(self); + ( + crate::sink::assert_sink::(sink), + assert_stream::(stream), + ) + } + + /// Do something with each item of this stream, afterwards passing it on. + /// + /// This is similar to the `Iterator::inspect` method in the standard + /// library where it allows easily inspecting each value as it passes + /// through the stream, for example to debug what's going on. + fn inspect(self, f: F) -> Inspect + where + F: FnMut(&Self::Item), + Self: Sized, + { + assert_stream::(Inspect::new(self, f)) + } + + /// Wrap this stream in an `Either` stream, making it the left-hand variant + /// of that `Either`. + /// + /// This can be used in combination with the `right_stream` method to write `if` + /// statements that evaluate to different streams in different branches. + fn left_stream(self) -> Either + where + B: Stream, + Self: Sized, + { + assert_stream::(Either::Left(self)) + } + + /// Wrap this stream in an `Either` stream, making it the right-hand variant + /// of that `Either`. + /// + /// This can be used in combination with the `left_stream` method to write `if` + /// statements that evaluate to different streams in different branches. + fn right_stream(self) -> Either + where + B: Stream, + Self: Sized, + { + assert_stream::(Either::Right(self)) + } + + /// A convenience method for calling [`Stream::poll_next`] on [`Unpin`] + /// stream types. + fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll> + where + Self: Unpin, + { + Pin::new(self).poll_next(cx) + } + + /// Returns a [`Future`] that resolves when the next item in this stream is + /// ready. + /// + /// This is similar to the [`next`][StreamExt::next] method, but it won't + /// resolve to [`None`] if used on an empty [`Stream`]. Instead, the + /// returned future type will return `true` from + /// [`FusedFuture::is_terminated`][] when the [`Stream`] is empty, allowing + /// [`select_next_some`][StreamExt::select_next_some] to be easily used with + /// the [`select!`] macro. + /// + /// If the future is polled after this [`Stream`] is empty it will panic. + /// Using the future with a [`FusedFuture`][]-aware primitive like the + /// [`select!`] macro will prevent this. + /// + /// [`FusedFuture`]: futures_core::future::FusedFuture + /// [`FusedFuture::is_terminated`]: futures_core::future::FusedFuture::is_terminated + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::{future, select}; + /// use futures::stream::{StreamExt, FuturesUnordered}; + /// + /// let mut fut = future::ready(1); + /// let mut async_tasks = FuturesUnordered::new(); + /// let mut total = 0; + /// loop { + /// select! { + /// num = fut => { + /// // First, the `ready` future completes. + /// total += num; + /// // Then we spawn a new task onto `async_tasks`, + /// async_tasks.push(async { 5 }); + /// }, + /// // On the next iteration of the loop, the task we spawned + /// // completes. + /// num = async_tasks.select_next_some() => { + /// total += num; + /// } + /// // Finally, both the `ready` future and `async_tasks` have + /// // finished, so we enter the `complete` branch. + /// complete => break, + /// } + /// } + /// assert_eq!(total, 6); + /// # }); + /// ``` + /// + /// [`select!`]: crate::select + fn select_next_some(&mut self) -> SelectNextSome<'_, Self> + where + Self: Unpin + FusedStream, + { + assert_future::(SelectNextSome::new(self)) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/next.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/next.rs new file mode 100644 index 00000000..8d8347aa --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/next.rs @@ -0,0 +1,34 @@ +use crate::stream::StreamExt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`next`](super::StreamExt::next) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Next<'a, St: ?Sized> { + stream: &'a mut St, +} + +impl Unpin for Next<'_, St> {} + +impl<'a, St: ?Sized + Stream + Unpin> Next<'a, St> { + pub(super) fn new(stream: &'a mut St) -> Self { + Self { stream } + } +} + +impl FusedFuture for Next<'_, St> { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for Next<'_, St> { + type Output = Option; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.stream.poll_next_unpin(cx) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/peek.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/peek.rs new file mode 100644 index 00000000..ea3d6243 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/peek.rs @@ -0,0 +1,433 @@ +use crate::fns::FnOnce1; +use crate::stream::{Fuse, StreamExt}; +use core::fmt; +use core::marker::PhantomData; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// A `Stream` that implements a `peek` method. + /// + /// The `peek` method can be used to retrieve a reference + /// to the next `Stream::Item` if available. A subsequent + /// call to `poll` will return the owned item. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Peekable { + #[pin] + stream: Fuse, + peeked: Option, + } +} + +impl Peekable { + pub(super) fn new(stream: St) -> Self { + Self { stream: stream.fuse(), peeked: None } + } + + delegate_access_inner!(stream, St, (.)); + + /// Produces a future which retrieves a reference to the next item + /// in the stream, or `None` if the underlying stream terminates. + pub fn peek(self: Pin<&mut Self>) -> Peek<'_, St> { + Peek { inner: Some(self) } + } + + /// Peek retrieves a reference to the next item in the stream. + /// + /// This method polls the underlying stream and return either a reference + /// to the next item if the stream is ready or passes through any errors. + pub fn poll_peek(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if this.peeked.is_some() { + break this.peeked.as_ref(); + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + *this.peeked = Some(item); + } else { + break None; + } + }) + } + + /// Produces a future which retrieves a mutable reference to the next item + /// in the stream, or `None` if the underlying stream terminates. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// use futures::pin_mut; + /// + /// let stream = stream::iter(vec![1, 2, 3]).peekable(); + /// pin_mut!(stream); + /// + /// assert_eq!(stream.as_mut().peek_mut().await, Some(&mut 1)); + /// assert_eq!(stream.as_mut().next().await, Some(1)); + /// + /// // Peek into the stream and modify the value which will be returned next + /// if let Some(p) = stream.as_mut().peek_mut().await { + /// if *p == 2 { + /// *p = 5; + /// } + /// } + /// + /// assert_eq!(stream.collect::>().await, vec![5, 3]); + /// # }); + /// ``` + pub fn peek_mut(self: Pin<&mut Self>) -> PeekMut<'_, St> { + PeekMut { inner: Some(self) } + } + + /// Peek retrieves a mutable reference to the next item in the stream. + pub fn poll_peek_mut( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if this.peeked.is_some() { + break this.peeked.as_mut(); + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + *this.peeked = Some(item); + } else { + break None; + } + }) + } + + /// Creates a future which will consume and return the next value of this + /// stream if a condition is true. + /// + /// If `func` returns `true` for the next value of this stream, consume and + /// return it. Otherwise, return `None`. + /// + /// # Examples + /// + /// Consume a number if it's equal to 0. + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// use futures::pin_mut; + /// + /// let stream = stream::iter(0..5).peekable(); + /// pin_mut!(stream); + /// // The first item of the stream is 0; consume it. + /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, Some(0)); + /// // The next item returned is now 1, so `consume` will return `false`. + /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, None); + /// // `next_if` saves the value of the next item if it was not equal to `expected`. + /// assert_eq!(stream.next().await, Some(1)); + /// # }); + /// ``` + /// + /// Consume any number less than 10. + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// use futures::pin_mut; + /// + /// let stream = stream::iter(1..20).peekable(); + /// pin_mut!(stream); + /// // Consume all numbers less than 10 + /// while stream.as_mut().next_if(|&x| x < 10).await.is_some() {} + /// // The next value returned will be 10 + /// assert_eq!(stream.next().await, Some(10)); + /// # }); + /// ``` + pub fn next_if(self: Pin<&mut Self>, func: F) -> NextIf<'_, St, F> + where + F: FnOnce(&St::Item) -> bool, + { + NextIf { inner: Some((self, func)) } + } + + /// Creates a future which will consume and return the next item if it is + /// equal to `expected`. + /// + /// # Example + /// + /// Consume a number if it's equal to 0. + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt}; + /// use futures::pin_mut; + /// + /// let stream = stream::iter(0..5).peekable(); + /// pin_mut!(stream); + /// // The first item of the stream is 0; consume it. + /// assert_eq!(stream.as_mut().next_if_eq(&0).await, Some(0)); + /// // The next item returned is now 1, so `consume` will return `false`. + /// assert_eq!(stream.as_mut().next_if_eq(&0).await, None); + /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`. + /// assert_eq!(stream.next().await, Some(1)); + /// # }); + /// ``` + pub fn next_if_eq<'a, T>(self: Pin<&'a mut Self>, expected: &'a T) -> NextIfEq<'a, St, T> + where + T: ?Sized, + St::Item: PartialEq, + { + NextIfEq { + inner: NextIf { inner: Some((self, NextIfEqFn { expected, _next: PhantomData })) }, + } + } +} + +impl FusedStream for Peekable { + fn is_terminated(&self) -> bool { + self.peeked.is_none() && self.stream.is_terminated() + } +} + +impl Stream for Peekable { + type Item = S::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + if let Some(item) = this.peeked.take() { + return Poll::Ready(Some(item)); + } + this.stream.poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + let peek_len = usize::from(self.peeked.is_some()); + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(peek_len); + let upper = match upper { + Some(x) => x.checked_add(peek_len), + None => None, + }; + (lower, upper) + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Peekable +where + S: Sink + Stream, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} + +pin_project! { + /// Future for the [`Peekable::peek`](self::Peekable::peek) method. + #[must_use = "futures do nothing unless polled"] + pub struct Peek<'a, St: Stream> { + inner: Option>>, + } +} + +impl fmt::Debug for Peek<'_, St> +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Peek").field("inner", &self.inner).finish() + } +} + +impl FusedFuture for Peek<'_, St> { + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +impl<'a, St> Future for Peek<'a, St> +where + St: Stream, +{ + type Output = Option<&'a St::Item>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let inner = self.project().inner; + if let Some(peekable) = inner { + ready!(peekable.as_mut().poll_peek(cx)); + + inner.take().unwrap().poll_peek(cx) + } else { + panic!("Peek polled after completion") + } + } +} + +pin_project! { + /// Future for the [`Peekable::peek_mut`](self::Peekable::peek_mut) method. + #[must_use = "futures do nothing unless polled"] + pub struct PeekMut<'a, St: Stream> { + inner: Option>>, + } +} + +impl fmt::Debug for PeekMut<'_, St> +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PeekMut").field("inner", &self.inner).finish() + } +} + +impl FusedFuture for PeekMut<'_, St> { + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +impl<'a, St> Future for PeekMut<'a, St> +where + St: Stream, +{ + type Output = Option<&'a mut St::Item>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let inner = self.project().inner; + if let Some(peekable) = inner { + ready!(peekable.as_mut().poll_peek_mut(cx)); + + inner.take().unwrap().poll_peek_mut(cx) + } else { + panic!("PeekMut polled after completion") + } + } +} + +pin_project! { + /// Future for the [`Peekable::next_if`](self::Peekable::next_if) method. + #[must_use = "futures do nothing unless polled"] + pub struct NextIf<'a, St: Stream, F> { + inner: Option<(Pin<&'a mut Peekable>, F)>, + } +} + +impl fmt::Debug for NextIf<'_, St, F> +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("NextIf").field("inner", &self.inner.as_ref().map(|(s, _f)| s)).finish() + } +} + +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl FusedFuture for NextIf<'_, St, F> +where + St: Stream, + F: for<'a> FnOnce1<&'a St::Item, Output = bool>, +{ + fn is_terminated(&self) -> bool { + self.inner.is_none() + } +} + +#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 +impl Future for NextIf<'_, St, F> +where + St: Stream, + F: for<'a> FnOnce1<&'a St::Item, Output = bool>, +{ + type Output = Option; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let inner = self.project().inner; + if let Some((peekable, _)) = inner { + let res = ready!(peekable.as_mut().poll_next(cx)); + + let (peekable, func) = inner.take().unwrap(); + match res { + Some(ref matched) if func.call_once(matched) => Poll::Ready(res), + other => { + let peekable = peekable.project(); + // Since we called `self.next()`, we consumed `self.peeked`. + assert!(peekable.peeked.is_none()); + *peekable.peeked = other; + Poll::Ready(None) + } + } + } else { + panic!("NextIf polled after completion") + } + } +} + +pin_project! { + /// Future for the [`Peekable::next_if_eq`](self::Peekable::next_if_eq) method. + #[must_use = "futures do nothing unless polled"] + pub struct NextIfEq<'a, St: Stream, T: ?Sized> { + #[pin] + inner: NextIf<'a, St, NextIfEqFn<'a, T, St::Item>>, + } +} + +impl fmt::Debug for NextIfEq<'_, St, T> +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, + T: ?Sized, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("NextIfEq") + .field("inner", &self.inner.inner.as_ref().map(|(s, _f)| s)) + .finish() + } +} + +impl FusedFuture for NextIfEq<'_, St, T> +where + St: Stream, + T: ?Sized, + St::Item: PartialEq, +{ + fn is_terminated(&self) -> bool { + self.inner.is_terminated() + } +} + +impl Future for NextIfEq<'_, St, T> +where + St: Stream, + T: ?Sized, + St::Item: PartialEq, +{ + type Output = Option; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.project().inner.poll(cx) + } +} + +struct NextIfEqFn<'a, T: ?Sized, Item> { + expected: &'a T, + _next: PhantomData, +} + +impl FnOnce1<&Item> for NextIfEqFn<'_, T, Item> +where + T: ?Sized, + Item: PartialEq, +{ + type Output = bool; + + fn call_once(self, next: &Item) -> Self::Output { + next == self.expected + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/ready_chunks.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/ready_chunks.rs new file mode 100644 index 00000000..192054c4 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/ready_chunks.rs @@ -0,0 +1,93 @@ +use crate::stream::{Fuse, StreamExt}; +use alloc::vec::Vec; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`ready_chunks`](super::StreamExt::ready_chunks) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct ReadyChunks { + #[pin] + stream: Fuse, + cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 + } +} + +impl ReadyChunks { + pub(super) fn new(stream: St, capacity: usize) -> Self { + assert!(capacity > 0); + + Self { stream: stream.fuse(), cap: capacity } + } + + delegate_access_inner!(stream, St, (.)); +} + +impl Stream for ReadyChunks { + type Item = Vec; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + let mut items: Vec = Vec::new(); + + loop { + match this.stream.as_mut().poll_next(cx) { + // Flush all collected data if underlying stream doesn't contain + // more ready values + Poll::Pending => { + return if items.is_empty() { Poll::Pending } else { Poll::Ready(Some(items)) } + } + + // Push the ready item into the buffer and check whether it is full. + // If so, replace our buffer with a new and empty one and return + // the full one. + Poll::Ready(Some(item)) => { + if items.is_empty() { + items.reserve(*this.cap); + } + items.push(item); + if items.len() >= *this.cap { + return Poll::Ready(Some(items)); + } + } + + // Since the underlying stream ran out of values, return what we + // have buffered, if we have anything. + Poll::Ready(None) => { + let last = if items.is_empty() { None } else { Some(items) }; + + return Poll::Ready(last); + } + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.stream.size_hint(); + let lower = lower / self.cap; + (lower, upper) + } +} + +impl FusedStream for ReadyChunks { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for ReadyChunks +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/scan.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/scan.rs new file mode 100644 index 00000000..f5cfde9c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/scan.rs @@ -0,0 +1,128 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +struct StateFn { + state: S, + f: F, +} + +pin_project! { + /// Stream for the [`scan`](super::StreamExt::scan) method. + #[must_use = "streams do nothing unless polled"] + pub struct Scan { + #[pin] + stream: St, + state_f: Option>, + #[pin] + future: Option, + } +} + +impl fmt::Debug for Scan +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, + S: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Scan") + .field("stream", &self.stream) + .field("state", &self.state_f.as_ref().map(|s| &s.state)) + .field("future", &self.future) + .field("done_taking", &self.is_done_taking()) + .finish() + } +} + +impl Scan { + /// Checks if internal state is `None`. + fn is_done_taking(&self) -> bool { + self.state_f.is_none() + } +} + +impl Scan +where + St: Stream, + F: FnMut(&mut S, St::Item) -> Fut, + Fut: Future>, +{ + pub(super) fn new(stream: St, initial_state: S, f: F) -> Self { + Self { stream, state_f: Some(StateFn { state: initial_state, f }), future: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for Scan +where + St: Stream, + F: FnMut(&mut S, St::Item) -> Fut, + Fut: Future>, +{ + type Item = B; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.is_done_taking() { + return Poll::Ready(None); + } + + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + let item = ready!(fut.poll(cx)); + this.future.set(None); + + if item.is_none() { + *this.state_f = None; + } + + break item; + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + let state_f = this.state_f.as_mut().unwrap(); + this.future.set(Some((state_f.f)(&mut state_f.state, item))) + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + if self.is_done_taking() { + (0, Some(0)) + } else { + self.stream.size_hint() // can't know a lower bound, due to the predicate + } + } +} + +impl FusedStream for Scan +where + St: FusedStream, + F: FnMut(&mut S, St::Item) -> Fut, + Fut: Future>, +{ + fn is_terminated(&self) -> bool { + self.is_done_taking() || self.future.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Scan +where + St: Stream + Sink, +{ + type Error = St::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/select_next_some.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/select_next_some.rs new file mode 100644 index 00000000..3115e14d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/select_next_some.rs @@ -0,0 +1,42 @@ +use crate::stream::StreamExt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::FusedStream; +use futures_core::task::{Context, Poll}; + +/// Future for the [`select_next_some`](super::StreamExt::select_next_some) +/// method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct SelectNextSome<'a, St: ?Sized> { + stream: &'a mut St, +} + +impl<'a, St: ?Sized> SelectNextSome<'a, St> { + pub(super) fn new(stream: &'a mut St) -> Self { + Self { stream } + } +} + +impl FusedFuture for SelectNextSome<'_, St> { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for SelectNextSome<'_, St> { + type Output = St::Item; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + assert!(!self.stream.is_terminated(), "SelectNextSome polled after terminated"); + + if let Some(item) = ready!(self.stream.poll_next_unpin(cx)) { + Poll::Ready(item) + } else { + debug_assert!(self.stream.is_terminated()); + cx.waker().wake_by_ref(); + Poll::Pending + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/skip.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/skip.rs new file mode 100644 index 00000000..f4957795 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/skip.rs @@ -0,0 +1,70 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`skip`](super::StreamExt::skip) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Skip { + #[pin] + stream: St, + remaining: usize, + } +} + +impl Skip { + pub(super) fn new(stream: St, n: usize) -> Self { + Self { stream, remaining: n } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Skip { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Stream for Skip { + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + while *this.remaining > 0 { + if ready!(this.stream.as_mut().poll_next(cx)).is_some() { + *this.remaining -= 1; + } else { + return Poll::Ready(None); + } + } + + this.stream.poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.stream.size_hint(); + + let lower = lower.saturating_sub(self.remaining); + let upper = upper.map(|x| x.saturating_sub(self.remaining)); + + (lower, upper) + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Skip +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/skip_while.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/skip_while.rs new file mode 100644 index 00000000..dabd5eef --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/skip_while.rs @@ -0,0 +1,124 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`skip_while`](super::StreamExt::skip_while) method. + #[must_use = "streams do nothing unless polled"] + pub struct SkipWhile where St: Stream { + #[pin] + stream: St, + f: F, + #[pin] + pending_fut: Option, + pending_item: Option, + done_skipping: bool, + } +} + +impl fmt::Debug for SkipWhile +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SkipWhile") + .field("stream", &self.stream) + .field("pending_fut", &self.pending_fut) + .field("pending_item", &self.pending_item) + .field("done_skipping", &self.done_skipping) + .finish() + } +} + +impl SkipWhile +where + St: Stream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for SkipWhile +where + St: FusedStream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.pending_item.is_none() && self.stream.is_terminated() + } +} + +impl Stream for SkipWhile +where + St: Stream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if *this.done_skipping { + return this.stream.poll_next(cx); + } + + Poll::Ready(loop { + if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { + let skipped = ready!(fut.poll(cx)); + let item = this.pending_item.take(); + this.pending_fut.set(None); + if !skipped { + *this.done_skipping = true; + break item; + } + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + this.pending_fut.set(Some((this.f)(&item))); + *this.pending_item = Some(item); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + if self.done_skipping { + self.stream.size_hint() + } else { + let pending_len = usize::from(self.pending_item.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for SkipWhile +where + S: Stream + Sink, + F: FnMut(&S::Item) -> Fut, + Fut: Future, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/split.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/split.rs new file mode 100644 index 00000000..1a7fdcb3 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/split.rs @@ -0,0 +1,224 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use futures_sink::Sink; + +use crate::lock::BiLock; + +/// A `Stream` part of the split pair +#[derive(Debug)] +#[must_use = "streams do nothing unless polled"] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub struct SplitStream(BiLock); + +impl Unpin for SplitStream {} + +impl SplitStream { + /// Returns `true` if the `SplitStream` and `SplitSink` originate from the same call to `StreamExt::split`. + pub fn is_pair_of(&self, other: &SplitSink) -> bool { + other.is_pair_of(&self) + } +} + +impl SplitStream { + /// Attempts to put the two "halves" of a split `Stream + Sink` back + /// together. Succeeds only if the `SplitStream` and `SplitSink` are + /// a matching pair originating from the same call to `StreamExt::split`. + pub fn reunite(self, other: SplitSink) -> Result> + where + S: Sink, + { + other.reunite(self) + } +} + +impl Stream for SplitStream { + type Item = S::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + ready!(self.0.poll_lock(cx)).as_pin_mut().poll_next(cx) + } +} + +#[allow(non_snake_case)] +fn SplitSink, Item>(lock: BiLock) -> SplitSink { + SplitSink { lock, slot: None } +} + +/// A `Sink` part of the split pair +#[derive(Debug)] +#[must_use = "sinks do nothing unless polled"] +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub struct SplitSink { + lock: BiLock, + slot: Option, +} + +impl Unpin for SplitSink {} + +impl + Unpin, Item> SplitSink { + /// Attempts to put the two "halves" of a split `Stream + Sink` back + /// together. Succeeds only if the `SplitStream` and `SplitSink` are + /// a matching pair originating from the same call to `StreamExt::split`. + pub fn reunite(self, other: SplitStream) -> Result> { + self.lock.reunite(other.0).map_err(|err| ReuniteError(SplitSink(err.0), SplitStream(err.1))) + } +} + +impl SplitSink { + /// Returns `true` if the `SplitStream` and `SplitSink` originate from the same call to `StreamExt::split`. + pub fn is_pair_of(&self, other: &SplitStream) -> bool { + self.lock.is_pair_of(&other.0) + } +} + +impl, Item> SplitSink { + fn poll_flush_slot( + mut inner: Pin<&mut S>, + slot: &mut Option, + cx: &mut Context<'_>, + ) -> Poll> { + if slot.is_some() { + ready!(inner.as_mut().poll_ready(cx))?; + Poll::Ready(inner.start_send(slot.take().unwrap())) + } else { + Poll::Ready(Ok(())) + } + } + + fn poll_lock_and_flush_slot( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let this = &mut *self; + let mut inner = ready!(this.lock.poll_lock(cx)); + Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx) + } +} + +impl, Item> Sink for SplitSink { + type Error = S::Error; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + loop { + if self.slot.is_none() { + return Poll::Ready(Ok(())); + } + ready!(self.as_mut().poll_lock_and_flush_slot(cx))?; + } + } + + fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), S::Error> { + self.slot = Some(item); + Ok(()) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = &mut *self; + let mut inner = ready!(this.lock.poll_lock(cx)); + ready!(Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx))?; + inner.as_pin_mut().poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = &mut *self; + let mut inner = ready!(this.lock.poll_lock(cx)); + ready!(Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx))?; + inner.as_pin_mut().poll_close(cx) + } +} + +pub(super) fn split, Item>(s: S) -> (SplitSink, SplitStream) { + let (a, b) = BiLock::new(s); + let read = SplitStream(a); + let write = SplitSink(b); + (write, read) +} + +/// Error indicating a `SplitSink` and `SplitStream` were not two halves +/// of a `Stream + Split`, and thus could not be `reunite`d. +#[cfg_attr(docsrs, doc(cfg(feature = "sink")))] +pub struct ReuniteError(pub SplitSink, pub SplitStream); + +impl fmt::Debug for ReuniteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("ReuniteError").field(&"...").finish() + } +} + +impl fmt::Display for ReuniteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "tried to reunite a SplitStream and SplitSink that don't form a pair") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ReuniteError {} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{sink::Sink, stream::StreamExt}; + use core::marker::PhantomData; + + struct NopStream { + phantom: PhantomData, + } + + impl Stream for NopStream { + type Item = Item; + + fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + todo!() + } + } + + impl Sink for NopStream { + type Error = (); + + fn poll_ready( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + todo!() + } + + fn start_send(self: Pin<&mut Self>, _item: Item) -> Result<(), Self::Error> { + todo!() + } + + fn poll_flush( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + todo!() + } + + fn poll_close( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + todo!() + } + } + + #[test] + fn test_pairing() { + let s1 = NopStream::<()> { phantom: PhantomData }; + let (sink1, stream1) = s1.split(); + assert!(sink1.is_pair_of(&stream1)); + assert!(stream1.is_pair_of(&sink1)); + + let s2 = NopStream::<()> { phantom: PhantomData }; + let (sink2, stream2) = s2.split(); + assert!(sink2.is_pair_of(&stream2)); + assert!(stream2.is_pair_of(&sink2)); + + assert!(!sink1.is_pair_of(&stream2)); + assert!(!stream1.is_pair_of(&sink2)); + assert!(!sink2.is_pair_of(&stream1)); + assert!(!stream2.is_pair_of(&sink1)); + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/take.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/take.rs new file mode 100644 index 00000000..29d6c39e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/take.rs @@ -0,0 +1,86 @@ +use core::cmp; +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`take`](super::StreamExt::take) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Take { + #[pin] + stream: St, + remaining: usize, + } +} + +impl Take { + pub(super) fn new(stream: St, n: usize) -> Self { + Self { stream, remaining: n } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for Take +where + St: Stream, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.remaining == 0 { + Poll::Ready(None) + } else { + let this = self.project(); + let next = ready!(this.stream.poll_next(cx)); + if next.is_some() { + *this.remaining -= 1; + } else { + *this.remaining = 0; + } + Poll::Ready(next) + } + } + + fn size_hint(&self) -> (usize, Option) { + if self.remaining == 0 { + return (0, Some(0)); + } + + let (lower, upper) = self.stream.size_hint(); + + let lower = cmp::min(lower, self.remaining); + + let upper = match upper { + Some(x) if x < self.remaining => Some(x), + _ => Some(self.remaining), + }; + + (lower, upper) + } +} + +impl FusedStream for Take +where + St: FusedStream, +{ + fn is_terminated(&self) -> bool { + self.remaining == 0 || self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Take +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/take_until.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/take_until.rs new file mode 100644 index 00000000..d14f9ce1 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/take_until.rs @@ -0,0 +1,170 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +// FIXME: docs, tests + +pin_project! { + /// Stream for the [`take_until`](super::StreamExt::take_until) method. + #[must_use = "streams do nothing unless polled"] + pub struct TakeUntil { + #[pin] + stream: St, + // Contains the inner Future on start and None once the inner Future is resolved + // or taken out by the user. + #[pin] + fut: Option, + // Contains fut's return value once fut is resolved + fut_result: Option, + // Whether the future was taken out by the user. + free: bool, + } +} + +impl fmt::Debug for TakeUntil +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, + Fut: Future + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TakeUntil").field("stream", &self.stream).field("fut", &self.fut).finish() + } +} + +impl TakeUntil +where + St: Stream, + Fut: Future, +{ + pub(super) fn new(stream: St, fut: Fut) -> Self { + Self { stream, fut: Some(fut), fut_result: None, free: false } + } + + delegate_access_inner!(stream, St, ()); + + /// Extract the stopping future out of the combinator. + /// The future is returned only if it isn't resolved yet, ie. if the stream isn't stopped yet. + /// Taking out the future means the combinator will be yielding + /// elements from the wrapped stream without ever stopping it. + pub fn take_future(&mut self) -> Option { + if self.fut.is_some() { + self.free = true; + } + + self.fut.take() + } + + /// Once the stopping future is resolved, this method can be used + /// to extract the value returned by the stopping future. + /// + /// This may be used to retrieve arbitrary data from the stopping + /// future, for example a reason why the stream was stopped. + /// + /// This method will return `None` if the future isn't resolved yet, + /// or if the result was already taken out. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt}; + /// use futures::task::Poll; + /// + /// let stream = stream::iter(1..=10); + /// + /// let mut i = 0; + /// let stop_fut = future::poll_fn(|_cx| { + /// i += 1; + /// if i <= 5 { + /// Poll::Pending + /// } else { + /// Poll::Ready("reason") + /// } + /// }); + /// + /// let mut stream = stream.take_until(stop_fut); + /// let _ = stream.by_ref().collect::>().await; + /// + /// let result = stream.take_result().unwrap(); + /// assert_eq!(result, "reason"); + /// # }); + /// ``` + pub fn take_result(&mut self) -> Option { + self.fut_result.take() + } + + /// Whether the stream was stopped yet by the stopping future + /// being resolved. + pub fn is_stopped(&self) -> bool { + !self.free && self.fut.is_none() + } +} + +impl Stream for TakeUntil +where + St: Stream, + Fut: Future, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if let Some(f) = this.fut.as_mut().as_pin_mut() { + if let Poll::Ready(result) = f.poll(cx) { + this.fut.set(None); + *this.fut_result = Some(result); + } + } + + if !*this.free && this.fut.is_none() { + // Future resolved, inner stream stopped + Poll::Ready(None) + } else { + // Future either not resolved yet or taken out by the user + let item = ready!(this.stream.poll_next(cx)); + if item.is_none() { + this.fut.set(None); + } + Poll::Ready(item) + } + } + + fn size_hint(&self) -> (usize, Option) { + if self.is_stopped() { + return (0, Some(0)); + } + + self.stream.size_hint() + } +} + +impl FusedStream for TakeUntil +where + St: Stream, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.is_stopped() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TakeUntil +where + S: Stream + Sink, + Fut: Future, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/take_while.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/take_while.rs new file mode 100644 index 00000000..92569430 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/take_while.rs @@ -0,0 +1,124 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`take_while`](super::StreamExt::take_while) method. + #[must_use = "streams do nothing unless polled"] + pub struct TakeWhile { + #[pin] + stream: St, + f: F, + #[pin] + pending_fut: Option, + pending_item: Option, + done_taking: bool, + } +} + +impl fmt::Debug for TakeWhile +where + St: Stream + fmt::Debug, + St::Item: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TakeWhile") + .field("stream", &self.stream) + .field("pending_fut", &self.pending_fut) + .field("pending_item", &self.pending_item) + .field("done_taking", &self.done_taking) + .finish() + } +} + +impl TakeWhile +where + St: Stream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending_fut: None, pending_item: None, done_taking: false } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for TakeWhile +where + St: Stream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + type Item = St::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.done_taking { + return Poll::Ready(None); + } + + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { + let take = ready!(fut.poll(cx)); + let item = this.pending_item.take(); + this.pending_fut.set(None); + if take { + break item; + } else { + *this.done_taking = true; + break None; + } + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + this.pending_fut.set(Some((this.f)(&item))); + *this.pending_item = Some(item); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + if self.done_taking { + return (0, Some(0)); + } + + let pending_len = usize::from(self.pending_item.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +impl FusedStream for TakeWhile +where + St: FusedStream, + F: FnMut(&St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.done_taking || self.pending_item.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TakeWhile +where + S: Stream + Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/then.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/then.rs new file mode 100644 index 00000000..9192c0b0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/then.rs @@ -0,0 +1,101 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`then`](super::StreamExt::then) method. + #[must_use = "streams do nothing unless polled"] + pub struct Then { + #[pin] + stream: St, + #[pin] + future: Option, + f: F, + } +} + +impl fmt::Debug for Then +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Then").field("stream", &self.stream).field("future", &self.future).finish() + } +} + +impl Then +where + St: Stream, + F: FnMut(St::Item) -> Fut, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, future: None, f } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for Then +where + St: FusedStream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.future.is_none() && self.stream.is_terminated() + } +} + +impl Stream for Then +where + St: Stream, + F: FnMut(St::Item) -> Fut, + Fut: Future, +{ + type Item = Fut::Output; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + let item = ready!(fut.poll(cx)); + this.future.set(None); + break Some(item); + } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { + this.future.set(Some((this.f)(item))); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let future_len = usize::from(self.future.is_some()); + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(future_len); + let upper = match upper { + Some(x) => x.checked_add(future_len), + None => None, + }; + (lower, upper) + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for Then +where + S: Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/unzip.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/unzip.rs new file mode 100644 index 00000000..a88cf032 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/unzip.rs @@ -0,0 +1,63 @@ +use core::mem; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`unzip`](super::StreamExt::unzip) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Unzip { + #[pin] + stream: St, + left: FromA, + right: FromB, + } +} + +impl Unzip { + fn finish(self: Pin<&mut Self>) -> (FromA, FromB) { + let this = self.project(); + (mem::take(this.left), mem::take(this.right)) + } + + pub(super) fn new(stream: St) -> Self { + Self { stream, left: Default::default(), right: Default::default() } + } +} + +impl FusedFuture for Unzip +where + St: FusedStream, + FromA: Default + Extend, + FromB: Default + Extend, +{ + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for Unzip +where + St: Stream, + FromA: Default + Extend, + FromB: Default + Extend, +{ + type Output = (FromA, FromB); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<(FromA, FromB)> { + let mut this = self.as_mut().project(); + loop { + match ready!(this.stream.as_mut().poll_next(cx)) { + Some(e) => { + this.left.extend(Some(e.0)); + this.right.extend(Some(e.1)); + } + None => return Poll::Ready(self.finish()), + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/stream/zip.rs b/utshell-0.5.0/vendor/futures-util/src/stream/stream/zip.rs new file mode 100644 index 00000000..25a47e96 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/stream/zip.rs @@ -0,0 +1,128 @@ +use crate::stream::{Fuse, StreamExt}; +use core::cmp; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`zip`](super::StreamExt::zip) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct Zip { + #[pin] + stream1: Fuse, + #[pin] + stream2: Fuse, + queued1: Option, + queued2: Option, + } +} + +impl Zip { + pub(super) fn new(stream1: St1, stream2: St2) -> Self { + Self { stream1: stream1.fuse(), stream2: stream2.fuse(), queued1: None, queued2: None } + } + + /// Acquires a reference to the underlying streams that this combinator is + /// pulling from. + pub fn get_ref(&self) -> (&St1, &St2) { + (self.stream1.get_ref(), self.stream2.get_ref()) + } + + /// Acquires a mutable reference to the underlying streams that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + pub fn get_mut(&mut self) -> (&mut St1, &mut St2) { + (self.stream1.get_mut(), self.stream2.get_mut()) + } + + /// Acquires a pinned mutable reference to the underlying streams that this + /// combinator is pulling from. + /// + /// Note that care must be taken to avoid tampering with the state of the + /// stream which may otherwise confuse this combinator. + pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) { + let this = self.project(); + (this.stream1.get_pin_mut(), this.stream2.get_pin_mut()) + } + + /// Consumes this combinator, returning the underlying streams. + /// + /// Note that this may discard intermediate state of this combinator, so + /// care should be taken to avoid losing resources when this is called. + pub fn into_inner(self) -> (St1, St2) { + (self.stream1.into_inner(), self.stream2.into_inner()) + } +} + +impl FusedStream for Zip +where + St1: Stream, + St2: Stream, +{ + fn is_terminated(&self) -> bool { + self.stream1.is_terminated() && self.stream2.is_terminated() + } +} + +impl Stream for Zip +where + St1: Stream, + St2: Stream, +{ + type Item = (St1::Item, St2::Item); + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if this.queued1.is_none() { + match this.stream1.as_mut().poll_next(cx) { + Poll::Ready(Some(item1)) => *this.queued1 = Some(item1), + Poll::Ready(None) | Poll::Pending => {} + } + } + if this.queued2.is_none() { + match this.stream2.as_mut().poll_next(cx) { + Poll::Ready(Some(item2)) => *this.queued2 = Some(item2), + Poll::Ready(None) | Poll::Pending => {} + } + } + + if this.queued1.is_some() && this.queued2.is_some() { + let pair = (this.queued1.take().unwrap(), this.queued2.take().unwrap()); + Poll::Ready(Some(pair)) + } else if this.stream1.is_done() || this.stream2.is_done() { + Poll::Ready(None) + } else { + Poll::Pending + } + } + + fn size_hint(&self) -> (usize, Option) { + let queued1_len = usize::from(self.queued1.is_some()); + let queued2_len = usize::from(self.queued2.is_some()); + let (stream1_lower, stream1_upper) = self.stream1.size_hint(); + let (stream2_lower, stream2_upper) = self.stream2.size_hint(); + + let stream1_lower = stream1_lower.saturating_add(queued1_len); + let stream2_lower = stream2_lower.saturating_add(queued2_len); + + let lower = cmp::min(stream1_lower, stream2_lower); + + let upper = match (stream1_upper, stream2_upper) { + (Some(x), Some(y)) => { + let x = x.saturating_add(queued1_len); + let y = y.saturating_add(queued2_len); + Some(cmp::min(x, y)) + } + (Some(x), None) => x.checked_add(queued1_len), + (None, Some(y)) => y.checked_add(queued2_len), + (None, None) => None, + }; + + (lower, upper) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/and_then.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/and_then.rs new file mode 100644 index 00000000..2f8b6f25 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/and_then.rs @@ -0,0 +1,105 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`and_then`](super::TryStreamExt::and_then) method. + #[must_use = "streams do nothing unless polled"] + pub struct AndThen { + #[pin] + stream: St, + #[pin] + future: Option, + f: F, + } +} + +impl fmt::Debug for AndThen +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("AndThen") + .field("stream", &self.stream) + .field("future", &self.future) + .finish() + } +} + +impl AndThen +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, future: None, f } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for AndThen +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: TryFuture, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + let item = ready!(fut.try_poll(cx)); + this.future.set(None); + break Some(item); + } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + this.future.set(Some((this.f)(item))); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let future_len = usize::from(self.future.is_some()); + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(future_len); + let upper = match upper { + Some(x) => x.checked_add(future_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for AndThen +where + St: TryStream + FusedStream, + F: FnMut(St::Ok) -> Fut, + Fut: TryFuture, +{ + fn is_terminated(&self) -> bool { + self.future.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for AndThen +where + S: Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_async_read.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_async_read.rs new file mode 100644 index 00000000..ffbfc7ea --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_async_read.rs @@ -0,0 +1,166 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncBufRead, AsyncRead, AsyncWrite}; +use pin_project_lite::pin_project; +use std::cmp; +use std::io::{Error, Result}; + +pin_project! { + /// Reader for the [`into_async_read`](super::TryStreamExt::into_async_read) method. + #[derive(Debug)] + #[must_use = "readers do nothing unless polled"] + #[cfg_attr(docsrs, doc(cfg(feature = "io")))] + pub struct IntoAsyncRead + where + St: TryStream, + St::Ok: AsRef<[u8]>, + { + #[pin] + stream: St, + state: ReadState, + } +} + +#[derive(Debug)] +enum ReadState> { + Ready { chunk: T, chunk_start: usize }, + PendingChunk, + Eof, +} + +impl IntoAsyncRead +where + St: TryStream, + St::Ok: AsRef<[u8]>, +{ + pub(super) fn new(stream: St) -> Self { + Self { stream, state: ReadState::PendingChunk } + } +} + +impl AsyncRead for IntoAsyncRead +where + St: TryStream, + St::Ok: AsRef<[u8]>, +{ + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + let mut this = self.project(); + + loop { + match this.state { + ReadState::Ready { chunk, chunk_start } => { + let chunk = chunk.as_ref(); + let len = cmp::min(buf.len(), chunk.len() - *chunk_start); + + buf[..len].copy_from_slice(&chunk[*chunk_start..*chunk_start + len]); + *chunk_start += len; + + if chunk.len() == *chunk_start { + *this.state = ReadState::PendingChunk; + } + + return Poll::Ready(Ok(len)); + } + ReadState::PendingChunk => match ready!(this.stream.as_mut().try_poll_next(cx)) { + Some(Ok(chunk)) => { + if !chunk.as_ref().is_empty() { + *this.state = ReadState::Ready { chunk, chunk_start: 0 }; + } + } + Some(Err(err)) => { + *this.state = ReadState::Eof; + return Poll::Ready(Err(err)); + } + None => { + *this.state = ReadState::Eof; + return Poll::Ready(Ok(0)); + } + }, + ReadState::Eof => { + return Poll::Ready(Ok(0)); + } + } + } + } +} + +impl AsyncWrite for IntoAsyncRead +where + St: TryStream + AsyncWrite, + St::Ok: AsRef<[u8]>, +{ + fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll> { + let this = self.project(); + this.stream.poll_write(cx, buf) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + this.stream.poll_flush(cx) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.project(); + this.stream.poll_close(cx) + } +} + +impl AsyncBufRead for IntoAsyncRead +where + St: TryStream, + St::Ok: AsRef<[u8]>, +{ + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + while let ReadState::PendingChunk = this.state { + match ready!(this.stream.as_mut().try_poll_next(cx)) { + Some(Ok(chunk)) => { + if !chunk.as_ref().is_empty() { + *this.state = ReadState::Ready { chunk, chunk_start: 0 }; + } + } + Some(Err(err)) => { + *this.state = ReadState::Eof; + return Poll::Ready(Err(err)); + } + None => { + *this.state = ReadState::Eof; + return Poll::Ready(Ok(&[])); + } + } + } + + if let &mut ReadState::Ready { ref chunk, chunk_start } = this.state { + let chunk = chunk.as_ref(); + return Poll::Ready(Ok(&chunk[chunk_start..])); + } + + // To get to this point we must be in ReadState::Eof + Poll::Ready(Ok(&[])) + } + + fn consume(self: Pin<&mut Self>, amount: usize) { + let this = self.project(); + + // https://github.com/rust-lang/futures-rs/pull/1556#discussion_r281644295 + if amount == 0 { + return; + } + if let ReadState::Ready { chunk, chunk_start } = this.state { + *chunk_start += amount; + debug_assert!(*chunk_start <= chunk.as_ref().len()); + if *chunk_start >= chunk.as_ref().len() { + *this.state = ReadState::PendingChunk; + } + } else { + debug_assert!(false, "Attempted to consume from IntoAsyncRead without chunk"); + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_stream.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_stream.rs new file mode 100644 index 00000000..2126258a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/into_stream.rs @@ -0,0 +1,52 @@ +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`into_stream`](super::TryStreamExt::into_stream) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct IntoStream { + #[pin] + stream: St, + } +} + +impl IntoStream { + #[inline] + pub(super) fn new(stream: St) -> Self { + Self { stream } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for IntoStream { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Stream for IntoStream { + type Item = Result; + + #[inline] + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().stream.try_poll_next(cx) + } + + fn size_hint(&self) -> (usize, Option) { + self.stream.size_hint() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl, Item> Sink for IntoStream { + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/mod.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/mod.rs new file mode 100644 index 00000000..7b55444b --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/mod.rs @@ -0,0 +1,1251 @@ +//! Streams +//! +//! This module contains a number of functions for working with `Streams`s +//! that return `Result`s, allowing for short-circuiting computations. + +#[cfg(feature = "compat")] +use crate::compat::Compat; +use crate::fns::{ + inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, InspectErrFn, InspectOkFn, + IntoFn, MapErrFn, MapOkFn, +}; +use crate::future::assert_future; +use crate::stream::assert_stream; +use crate::stream::{Inspect, Map}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +use core::pin::Pin; + +use futures_core::{ + future::{Future, TryFuture}, + stream::TryStream, + task::{Context, Poll}, +}; + +mod and_then; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::and_then::AndThen; + +delegate_all!( + /// Stream for the [`err_into`](super::TryStreamExt::err_into) method. + ErrInto( + MapErr> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St| MapErr::new(x, into_fn())] +); + +delegate_all!( + /// Stream for the [`inspect_ok`](super::TryStreamExt::inspect_ok) method. + InspectOk( + Inspect, InspectOkFn> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Inspect::new(IntoStream::new(x), inspect_ok_fn(f))] +); + +delegate_all!( + /// Stream for the [`inspect_err`](super::TryStreamExt::inspect_err) method. + InspectErr( + Inspect, InspectErrFn> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Inspect::new(IntoStream::new(x), inspect_err_fn(f))] +); + +mod into_stream; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::into_stream::IntoStream; + +delegate_all!( + /// Stream for the [`map_ok`](super::TryStreamExt::map_ok) method. + MapOk( + Map, MapOkFn> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Map::new(IntoStream::new(x), map_ok_fn(f))] +); + +delegate_all!( + /// Stream for the [`map_err`](super::TryStreamExt::map_err) method. + MapErr( + Map, MapErrFn> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Map::new(IntoStream::new(x), map_err_fn(f))] +); + +mod or_else; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::or_else::OrElse; + +mod try_next; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_next::TryNext; + +mod try_for_each; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_for_each::TryForEach; + +mod try_filter; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_filter::TryFilter; + +mod try_filter_map; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_filter_map::TryFilterMap; + +mod try_flatten; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_flatten::TryFlatten; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod try_flatten_unordered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_flatten_unordered::TryFlattenUnordered; + +mod try_collect; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_collect::TryCollect; + +mod try_concat; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_concat::TryConcat; + +#[cfg(feature = "alloc")] +mod try_chunks; +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_chunks::{TryChunks, TryChunksError}; + +#[cfg(feature = "alloc")] +mod try_ready_chunks; +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_ready_chunks::{TryReadyChunks, TryReadyChunksError}; + +mod try_fold; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_fold::TryFold; + +mod try_unfold; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_unfold::{try_unfold, TryUnfold}; + +mod try_skip_while; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_skip_while::TrySkipWhile; + +mod try_take_while; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_take_while::TryTakeWhile; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod try_buffer_unordered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_buffer_unordered::TryBufferUnordered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod try_buffered; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_buffered::TryBuffered; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +mod try_for_each_concurrent; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_for_each_concurrent::TryForEachConcurrent; + +#[cfg(feature = "io")] +#[cfg(feature = "std")] +mod into_async_read; +#[cfg(feature = "io")] +#[cfg_attr(docsrs, doc(cfg(feature = "io")))] +#[cfg(feature = "std")] +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::into_async_read::IntoAsyncRead; + +mod try_all; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_all::TryAll; + +mod try_any; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 +pub use self::try_any::TryAny; + +impl TryStreamExt for S {} + +/// Adapters specific to `Result`-returning streams +pub trait TryStreamExt: TryStream { + /// Wraps the current stream in a new stream which converts the error type + /// into the one provided. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryStreamExt}; + /// + /// let mut stream = + /// stream::iter(vec![Ok(()), Err(5i32)]) + /// .err_into::(); + /// + /// assert_eq!(stream.try_next().await, Ok(Some(()))); + /// assert_eq!(stream.try_next().await, Err(5i64)); + /// # }) + /// ``` + fn err_into(self) -> ErrInto + where + Self: Sized, + Self::Error: Into, + { + assert_stream::, _>(ErrInto::new(self)) + } + + /// Wraps the current stream in a new stream which maps the success value + /// using the provided closure. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryStreamExt}; + /// + /// let mut stream = + /// stream::iter(vec![Ok(5), Err(0)]) + /// .map_ok(|x| x + 2); + /// + /// assert_eq!(stream.try_next().await, Ok(Some(7))); + /// assert_eq!(stream.try_next().await, Err(0)); + /// # }) + /// ``` + fn map_ok(self, f: F) -> MapOk + where + Self: Sized, + F: FnMut(Self::Ok) -> T, + { + assert_stream::, _>(MapOk::new(self, f)) + } + + /// Wraps the current stream in a new stream which maps the error value + /// using the provided closure. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryStreamExt}; + /// + /// let mut stream = + /// stream::iter(vec![Ok(5), Err(0)]) + /// .map_err(|x| x + 2); + /// + /// assert_eq!(stream.try_next().await, Ok(Some(5))); + /// assert_eq!(stream.try_next().await, Err(2)); + /// # }) + /// ``` + fn map_err(self, f: F) -> MapErr + where + Self: Sized, + F: FnMut(Self::Error) -> E, + { + assert_stream::, _>(MapErr::new(self, f)) + } + + /// Chain on a computation for when a value is ready, passing the successful + /// results to the provided closure `f`. + /// + /// This function can be used to run a unit of work when the next successful + /// value on a stream is ready. The closure provided will be yielded a value + /// when ready, and the returned future will then be run to completion to + /// produce the next value on this stream. + /// + /// Any errors produced by this stream will not be passed to the closure, + /// and will be passed through. + /// + /// The returned value of the closure must implement the `TryFuture` trait + /// and can represent some more work to be done before the composed stream + /// is finished. + /// + /// Note that this function consumes the receiving stream and returns a + /// wrapped version of it. + /// + /// To process the entire stream and return a single future representing + /// success or error, use `try_for_each` instead. + /// + /// # Examples + /// + /// ``` + /// use futures::channel::mpsc; + /// use futures::future; + /// use futures::stream::TryStreamExt; + /// + /// let (_tx, rx) = mpsc::channel::>(1); + /// + /// let rx = rx.and_then(|result| { + /// future::ok(if result % 2 == 0 { + /// Some(result) + /// } else { + /// None + /// }) + /// }); + /// ``` + fn and_then(self, f: F) -> AndThen + where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_stream::, _>(AndThen::new(self, f)) + } + + /// Chain on a computation for when an error happens, passing the + /// erroneous result to the provided closure `f`. + /// + /// This function can be used to run a unit of work and attempt to recover from + /// an error if one happens. The closure provided will be yielded an error + /// when one appears, and the returned future will then be run to completion + /// to produce the next value on this stream. + /// + /// Any successful values produced by this stream will not be passed to the + /// closure, and will be passed through. + /// + /// The returned value of the closure must implement the [`TryFuture`](futures_core::future::TryFuture) trait + /// and can represent some more work to be done before the composed stream + /// is finished. + /// + /// Note that this function consumes the receiving stream and returns a + /// wrapped version of it. + fn or_else(self, f: F) -> OrElse + where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_stream::, _>(OrElse::new(self, f)) + } + + /// Do something with the success value of this stream, afterwards passing + /// it on. + /// + /// This is similar to the `StreamExt::inspect` method where it allows + /// easily inspecting the success value as it passes through the stream, for + /// example to debug what's going on. + fn inspect_ok(self, f: F) -> InspectOk + where + F: FnMut(&Self::Ok), + Self: Sized, + { + assert_stream::, _>(InspectOk::new(self, f)) + } + + /// Do something with the error value of this stream, afterwards passing it on. + /// + /// This is similar to the `StreamExt::inspect` method where it allows + /// easily inspecting the error value as it passes through the stream, for + /// example to debug what's going on. + fn inspect_err(self, f: F) -> InspectErr + where + F: FnMut(&Self::Error), + Self: Sized, + { + assert_stream::, _>(InspectErr::new(self, f)) + } + + /// Wraps a [`TryStream`] into a type that implements + /// [`Stream`](futures_core::stream::Stream) + /// + /// [`TryStream`]s currently do not implement the + /// [`Stream`](futures_core::stream::Stream) trait because of limitations + /// of the compiler. + /// + /// # Examples + /// + /// ``` + /// use futures::stream::{Stream, TryStream, TryStreamExt}; + /// + /// # type T = i32; + /// # type E = (); + /// fn make_try_stream() -> impl TryStream { // ... } + /// # futures::stream::empty() + /// # } + /// fn take_stream(stream: impl Stream>) { /* ... */ } + /// + /// take_stream(make_try_stream().into_stream()); + /// ``` + fn into_stream(self) -> IntoStream + where + Self: Sized, + { + assert_stream::, _>(IntoStream::new(self)) + } + + /// Creates a future that attempts to resolve the next item in the stream. + /// If an error is encountered before the next item, the error is returned + /// instead. + /// + /// This is similar to the `Stream::next` combinator, but returns a + /// `Result, E>` rather than an `Option>`, making + /// for easy use with the `?` operator. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryStreamExt}; + /// + /// let mut stream = stream::iter(vec![Ok(()), Err(())]); + /// + /// assert_eq!(stream.try_next().await, Ok(Some(()))); + /// assert_eq!(stream.try_next().await, Err(())); + /// # }) + /// ``` + fn try_next(&mut self) -> TryNext<'_, Self> + where + Self: Unpin, + { + assert_future::, Self::Error>, _>(TryNext::new(self)) + } + + /// Attempts to run this stream to completion, executing the provided + /// asynchronous closure for each element on the stream. + /// + /// The provided closure will be called for each item this stream produces, + /// yielding a future. That future will then be executed to completion + /// before moving on to the next item. + /// + /// The returned value is a [`Future`](futures_core::future::Future) where the + /// [`Output`](futures_core::future::Future::Output) type is + /// `Result<(), Self::Error>`. If any of the intermediate + /// futures or the stream returns an error, this future will return + /// immediately with an error. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, TryStreamExt}; + /// + /// let mut x = 0i32; + /// + /// { + /// let fut = stream::repeat(Ok(1)).try_for_each(|item| { + /// x += item; + /// future::ready(if x == 3 { Err(()) } else { Ok(()) }) + /// }); + /// assert_eq!(fut.await, Err(())); + /// } + /// + /// assert_eq!(x, 3); + /// # }) + /// ``` + fn try_for_each(self, f: F) -> TryForEach + where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_future::, _>(TryForEach::new(self, f)) + } + + /// Skip elements on this stream while the provided asynchronous predicate + /// resolves to `true`. + /// + /// This function is similar to + /// [`StreamExt::skip_while`](crate::stream::StreamExt::skip_while) but exits + /// early if an error occurs. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, TryStreamExt}; + /// + /// let stream = stream::iter(vec![Ok::(1), Ok(3), Ok(2)]); + /// let stream = stream.try_skip_while(|x| future::ready(Ok(*x < 3))); + /// + /// let output: Result, i32> = stream.try_collect().await; + /// assert_eq!(output, Ok(vec![3, 2])); + /// # }) + /// ``` + fn try_skip_while(self, f: F) -> TrySkipWhile + where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_stream::, _>(TrySkipWhile::new(self, f)) + } + + /// Take elements on this stream while the provided asynchronous predicate + /// resolves to `true`. + /// + /// This function is similar to + /// [`StreamExt::take_while`](crate::stream::StreamExt::take_while) but exits + /// early if an error occurs. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, TryStreamExt}; + /// + /// let stream = stream::iter(vec![Ok::(1), Ok(2), Ok(3), Ok(2)]); + /// let stream = stream.try_take_while(|x| future::ready(Ok(*x < 3))); + /// + /// let output: Result, i32> = stream.try_collect().await; + /// assert_eq!(output, Ok(vec![1, 2])); + /// # }) + /// ``` + fn try_take_while(self, f: F) -> TryTakeWhile + where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_stream::, _>(TryTakeWhile::new(self, f)) + } + + /// Attempts to run this stream to completion, executing the provided asynchronous + /// closure for each element on the stream concurrently as elements become + /// available, exiting as soon as an error occurs. + /// + /// This is similar to + /// [`StreamExt::for_each_concurrent`](crate::stream::StreamExt::for_each_concurrent), + /// but will resolve to an error immediately if the underlying stream or the provided + /// closure return an error. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::oneshot; + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// + /// let (tx1, rx1) = oneshot::channel(); + /// let (tx2, rx2) = oneshot::channel(); + /// let (_tx3, rx3) = oneshot::channel(); + /// + /// let stream = stream::iter(vec![rx1, rx2, rx3]); + /// let fut = stream.map(Ok).try_for_each_concurrent( + /// /* limit */ 2, + /// |rx| async move { + /// let res: Result<(), oneshot::Canceled> = rx.await; + /// res + /// } + /// ); + /// + /// tx1.send(()).unwrap(); + /// // Drop the second sender so that `rx2` resolves to `Canceled`. + /// drop(tx2); + /// + /// // The final result is an error because the second future + /// // resulted in an error. + /// assert_eq!(Err(oneshot::Canceled), fut.await); + /// # }) + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn try_for_each_concurrent( + self, + limit: impl Into>, + f: F, + ) -> TryForEachConcurrent + where + F: FnMut(Self::Ok) -> Fut, + Fut: Future>, + Self: Sized, + { + assert_future::, _>(TryForEachConcurrent::new( + self, + limit.into(), + f, + )) + } + + /// Attempt to transform a stream into a collection, + /// returning a future representing the result of that computation. + /// + /// This combinator will collect all successful results of this stream and + /// collect them into the specified collection type. If an error happens then all + /// collected elements will be dropped and the error will be returned. + /// + /// The returned future will be resolved when the stream terminates. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::TryStreamExt; + /// use std::thread; + /// + /// let (tx, rx) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// for i in 1..=5 { + /// tx.unbounded_send(Ok(i)).unwrap(); + /// } + /// tx.unbounded_send(Err(6)).unwrap(); + /// }); + /// + /// let output: Result, i32> = rx.try_collect().await; + /// assert_eq!(output, Err(6)); + /// # }) + /// ``` + fn try_collect>(self) -> TryCollect + where + Self: Sized, + { + assert_future::, _>(TryCollect::new(self)) + } + + /// An adaptor for chunking up successful items of the stream inside a vector. + /// + /// This combinator will attempt to pull successful items from this stream and buffer + /// them into a local vector. At most `capacity` items will get buffered + /// before they're yielded from the returned stream. + /// + /// Note that the vectors returned from this iterator may not always have + /// `capacity` elements. If the underlying stream ended and only a partial + /// vector was created, it'll be returned. Additionally if an error happens + /// from the underlying stream then the currently buffered items will be + /// yielded. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// This function is similar to + /// [`StreamExt::chunks`](crate::stream::StreamExt::chunks) but exits + /// early if an error occurs. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryChunksError, TryStreamExt}; + /// + /// let stream = stream::iter(vec![Ok::(1), Ok(2), Ok(3), Err(4), Ok(5), Ok(6)]); + /// let mut stream = stream.try_chunks(2); + /// + /// assert_eq!(stream.try_next().await, Ok(Some(vec![1, 2]))); + /// assert_eq!(stream.try_next().await, Err(TryChunksError(vec![3], 4))); + /// assert_eq!(stream.try_next().await, Ok(Some(vec![5, 6]))); + /// # }) + /// ``` + /// + /// # Panics + /// + /// This method will panic if `capacity` is zero. + #[cfg(feature = "alloc")] + fn try_chunks(self, capacity: usize) -> TryChunks + where + Self: Sized, + { + assert_stream::, TryChunksError>, _>( + TryChunks::new(self, capacity), + ) + } + + /// An adaptor for chunking up successful, ready items of the stream inside a vector. + /// + /// This combinator will attempt to pull successful items from this stream and buffer + /// them into a local vector. At most `capacity` items will get buffered + /// before they're yielded from the returned stream. If the underlying stream + /// returns `Poll::Pending`, and the collected chunk is not empty, it will + /// be immidiatly returned. + /// + /// Note that the vectors returned from this iterator may not always have + /// `capacity` elements. If the underlying stream ended and only a partial + /// vector was created, it'll be returned. Additionally if an error happens + /// from the underlying stream then the currently buffered items will be + /// yielded. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// This function is similar to + /// [`StreamExt::ready_chunks`](crate::stream::StreamExt::ready_chunks) but exits + /// early if an error occurs. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryReadyChunksError, TryStreamExt}; + /// + /// let stream = stream::iter(vec![Ok::(1), Ok(2), Ok(3), Err(4), Ok(5), Ok(6)]); + /// let mut stream = stream.try_ready_chunks(2); + /// + /// assert_eq!(stream.try_next().await, Ok(Some(vec![1, 2]))); + /// assert_eq!(stream.try_next().await, Err(TryReadyChunksError(vec![3], 4))); + /// assert_eq!(stream.try_next().await, Ok(Some(vec![5, 6]))); + /// # }) + /// ``` + /// + /// # Panics + /// + /// This method will panic if `capacity` is zero. + #[cfg(feature = "alloc")] + fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks + where + Self: Sized, + { + assert_stream::, TryReadyChunksError>, _>( + TryReadyChunks::new(self, capacity), + ) + } + + /// Attempt to filter the values produced by this stream according to the + /// provided asynchronous closure. + /// + /// As values of this stream are made available, the provided predicate `f` + /// will be run on them. If the predicate returns a `Future` which resolves + /// to `true`, then the stream will yield the value, but if the predicate + /// return a `Future` which resolves to `false`, then the value will be + /// discarded and the next value will be produced. + /// + /// All errors are passed through without filtering in this combinator. + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it, similar to the existing `filter` methods in + /// the standard library. + /// + /// # Examples + /// ``` + /// # futures::executor::block_on(async { + /// use futures::future; + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// + /// let stream = stream::iter(vec![Ok(1i32), Ok(2i32), Ok(3i32), Err("error")]); + /// let mut evens = stream.try_filter(|x| { + /// future::ready(x % 2 == 0) + /// }); + /// + /// assert_eq!(evens.next().await, Some(Ok(2))); + /// assert_eq!(evens.next().await, Some(Err("error"))); + /// # }) + /// ``` + fn try_filter(self, f: F) -> TryFilter + where + Fut: Future, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized, + { + assert_stream::, _>(TryFilter::new(self, f)) + } + + /// Attempt to filter the values produced by this stream while + /// simultaneously mapping them to a different type according to the + /// provided asynchronous closure. + /// + /// As values of this stream are made available, the provided function will + /// be run on them. If the future returned by the predicate `f` resolves to + /// [`Some(item)`](Some) then the stream will yield the value `item`, but if + /// it resolves to [`None`] then the next value will be produced. + /// + /// All errors are passed through without filtering in this combinator. + /// + /// Note that this function consumes the stream passed into it and returns a + /// wrapped version of it, similar to the existing `filter_map` methods in + /// the standard library. + /// + /// # Examples + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// use futures::pin_mut; + /// + /// let stream = stream::iter(vec![Ok(1i32), Ok(6i32), Err("error")]); + /// let halves = stream.try_filter_map(|x| async move { + /// let ret = if x % 2 == 0 { Some(x / 2) } else { None }; + /// Ok(ret) + /// }); + /// + /// pin_mut!(halves); + /// assert_eq!(halves.next().await, Some(Ok(3))); + /// assert_eq!(halves.next().await, Some(Err("error"))); + /// # }) + /// ``` + fn try_filter_map(self, f: F) -> TryFilterMap + where + Fut: TryFuture, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized, + { + assert_stream::, _>(TryFilterMap::new(self, f)) + } + + /// Flattens a stream of streams into just one continuous stream. Produced streams + /// will be polled concurrently and any errors will be passed through without looking at them. + /// If the underlying base stream returns an error, it will be **immediately** propagated. + /// + /// The only argument is an optional limit on the number of concurrently + /// polled streams. If this limit is not `None`, no more than `limit` streams + /// will be polled at the same time. The `limit` argument is of type + /// `Into>`, and so can be provided as either `None`, + /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as + /// no limit at all, and will have the same result as passing in `None`. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::{StreamExt, TryStreamExt}; + /// use std::thread; + /// + /// let (tx1, rx1) = mpsc::unbounded(); + /// let (tx2, rx2) = mpsc::unbounded(); + /// let (tx3, rx3) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// tx1.unbounded_send(Ok(1)).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx2.unbounded_send(Ok(2)).unwrap(); + /// tx2.unbounded_send(Err(3)).unwrap(); + /// tx2.unbounded_send(Ok(4)).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx3.unbounded_send(Ok(rx1)).unwrap(); + /// tx3.unbounded_send(Ok(rx2)).unwrap(); + /// tx3.unbounded_send(Err(5)).unwrap(); + /// }); + /// + /// let stream = rx3.try_flatten_unordered(None); + /// let mut values: Vec<_> = stream.collect().await; + /// values.sort(); + /// + /// assert_eq!(values, vec![Ok(1), Ok(2), Ok(4), Err(3), Err(5)]); + /// # }); + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn try_flatten_unordered(self, limit: impl Into>) -> TryFlattenUnordered + where + Self::Ok: TryStream + Unpin, + ::Error: From, + Self: Sized, + { + assert_stream::::Ok, ::Error>, _>( + TryFlattenUnordered::new(self, limit), + ) + } + + /// Flattens a stream of streams into just one continuous stream. + /// + /// If this stream's elements are themselves streams then this combinator + /// will flatten out the entire stream to one long chain of elements. Any + /// errors are passed through without looking at them, but otherwise each + /// individual stream will get exhausted before moving on to the next. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::{StreamExt, TryStreamExt}; + /// use std::thread; + /// + /// let (tx1, rx1) = mpsc::unbounded(); + /// let (tx2, rx2) = mpsc::unbounded(); + /// let (tx3, rx3) = mpsc::unbounded(); + /// + /// thread::spawn(move || { + /// tx1.unbounded_send(Ok(1)).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx2.unbounded_send(Ok(2)).unwrap(); + /// tx2.unbounded_send(Err(3)).unwrap(); + /// tx2.unbounded_send(Ok(4)).unwrap(); + /// }); + /// thread::spawn(move || { + /// tx3.unbounded_send(Ok(rx1)).unwrap(); + /// tx3.unbounded_send(Ok(rx2)).unwrap(); + /// tx3.unbounded_send(Err(5)).unwrap(); + /// }); + /// + /// let mut stream = rx3.try_flatten(); + /// assert_eq!(stream.next().await, Some(Ok(1))); + /// assert_eq!(stream.next().await, Some(Ok(2))); + /// assert_eq!(stream.next().await, Some(Err(3))); + /// assert_eq!(stream.next().await, Some(Ok(4))); + /// assert_eq!(stream.next().await, Some(Err(5))); + /// assert_eq!(stream.next().await, None); + /// # }); + /// ``` + fn try_flatten(self) -> TryFlatten + where + Self::Ok: TryStream, + ::Error: From, + Self: Sized, + { + assert_stream::::Ok, ::Error>, _>( + TryFlatten::new(self), + ) + } + + /// Attempt to execute an accumulating asynchronous computation over a + /// stream, collecting all the values into one final result. + /// + /// This combinator will accumulate all values returned by this stream + /// according to the closure provided. The initial state is also provided to + /// this method and then is returned again by each execution of the closure. + /// Once the entire stream has been exhausted the returned future will + /// resolve to this value. + /// + /// This method is similar to [`fold`](crate::stream::StreamExt::fold), but will + /// exit early if an error is encountered in either the stream or the + /// provided closure. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryStreamExt}; + /// + /// let number_stream = stream::iter(vec![Ok::(1), Ok(2)]); + /// let sum = number_stream.try_fold(0, |acc, x| async move { Ok(acc + x) }); + /// assert_eq!(sum.await, Ok(3)); + /// + /// let number_stream_with_err = stream::iter(vec![Ok::(1), Err(2), Ok(1)]); + /// let sum = number_stream_with_err.try_fold(0, |acc, x| async move { Ok(acc + x) }); + /// assert_eq!(sum.await, Err(2)); + /// # }) + /// ``` + fn try_fold(self, init: T, f: F) -> TryFold + where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture, + Self: Sized, + { + assert_future::, _>(TryFold::new(self, f, init)) + } + + /// Attempt to concatenate all items of a stream into a single + /// extendable destination, returning a future representing the end result. + /// + /// This combinator will extend the first item with the contents of all + /// the subsequent successful results of the stream. If the stream is empty, + /// the default value will be returned. + /// + /// Works with all collections that implement the [`Extend`](std::iter::Extend) trait. + /// + /// This method is similar to [`concat`](crate::stream::StreamExt::concat), but will + /// exit early if an error is encountered in the stream. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::TryStreamExt; + /// use std::thread; + /// + /// let (tx, rx) = mpsc::unbounded::, ()>>(); + /// + /// thread::spawn(move || { + /// for i in (0..3).rev() { + /// let n = i * 3; + /// tx.unbounded_send(Ok(vec![n + 1, n + 2, n + 3])).unwrap(); + /// } + /// }); + /// + /// let result = rx.try_concat().await; + /// + /// assert_eq!(result, Ok(vec![7, 8, 9, 4, 5, 6, 1, 2, 3])); + /// # }); + /// ``` + fn try_concat(self) -> TryConcat + where + Self: Sized, + Self::Ok: Extend<<::Ok as IntoIterator>::Item> + IntoIterator + Default, + { + assert_future::, _>(TryConcat::new(self)) + } + + /// Attempt to execute several futures from a stream concurrently (unordered). + /// + /// This stream's `Ok` type must be a [`TryFuture`](futures_core::future::TryFuture) with an `Error` type + /// that matches the stream's `Error` type. + /// + /// This adaptor will buffer up to `n` futures and then return their + /// outputs in the order in which they complete. If the underlying stream + /// returns an error, it will be immediately propagated. + /// + /// The returned stream will be a stream of results, each containing either + /// an error or a future's output. An error can be produced either by the + /// underlying stream itself or by one of the futures it yielded. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// Results are returned in the order of completion: + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::oneshot; + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// + /// let (send_one, recv_one) = oneshot::channel(); + /// let (send_two, recv_two) = oneshot::channel(); + /// + /// let stream_of_futures = stream::iter(vec![Ok(recv_one), Ok(recv_two)]); + /// + /// let mut buffered = stream_of_futures.try_buffer_unordered(10); + /// + /// send_two.send(2i32)?; + /// assert_eq!(buffered.next().await, Some(Ok(2i32))); + /// + /// send_one.send(1i32)?; + /// assert_eq!(buffered.next().await, Some(Ok(1i32))); + /// + /// assert_eq!(buffered.next().await, None); + /// # Ok::<(), i32>(()) }).unwrap(); + /// ``` + /// + /// Errors from the underlying stream itself are propagated: + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::{StreamExt, TryStreamExt}; + /// + /// let (sink, stream_of_futures) = mpsc::unbounded(); + /// let mut buffered = stream_of_futures.try_buffer_unordered(10); + /// + /// sink.unbounded_send(Ok(async { Ok(7i32) }))?; + /// assert_eq!(buffered.next().await, Some(Ok(7i32))); + /// + /// sink.unbounded_send(Err("error in the stream"))?; + /// assert_eq!(buffered.next().await, Some(Err("error in the stream"))); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered + where + Self::Ok: TryFuture, + Self: Sized, + { + assert_stream::::Ok, Self::Error>, _>( + TryBufferUnordered::new(self, n), + ) + } + + /// Attempt to execute several futures from a stream concurrently. + /// + /// This stream's `Ok` type must be a [`TryFuture`](futures_core::future::TryFuture) with an `Error` type + /// that matches the stream's `Error` type. + /// + /// This adaptor will buffer up to `n` futures and then return their + /// outputs in the same order as the underlying stream. If the underlying stream returns an error, it will + /// be immediately propagated. + /// + /// The returned stream will be a stream of results, each containing either + /// an error or a future's output. An error can be produced either by the + /// underlying stream itself or by one of the futures it yielded. + /// + /// This method is only available when the `std` or `alloc` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// Results are returned in the order of addition: + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::oneshot; + /// use futures::future::lazy; + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// + /// let (send_one, recv_one) = oneshot::channel(); + /// let (send_two, recv_two) = oneshot::channel(); + /// + /// let mut buffered = lazy(move |cx| { + /// let stream_of_futures = stream::iter(vec![Ok(recv_one), Ok(recv_two)]); + /// + /// let mut buffered = stream_of_futures.try_buffered(10); + /// + /// assert!(buffered.try_poll_next_unpin(cx).is_pending()); + /// + /// send_two.send(2i32)?; + /// assert!(buffered.try_poll_next_unpin(cx).is_pending()); + /// Ok::<_, i32>(buffered) + /// }).await?; + /// + /// send_one.send(1i32)?; + /// assert_eq!(buffered.next().await, Some(Ok(1i32))); + /// assert_eq!(buffered.next().await, Some(Ok(2i32))); + /// + /// assert_eq!(buffered.next().await, None); + /// # Ok::<(), i32>(()) }).unwrap(); + /// ``` + /// + /// Errors from the underlying stream itself are propagated: + /// ``` + /// # futures::executor::block_on(async { + /// use futures::channel::mpsc; + /// use futures::stream::{StreamExt, TryStreamExt}; + /// + /// let (sink, stream_of_futures) = mpsc::unbounded(); + /// let mut buffered = stream_of_futures.try_buffered(10); + /// + /// sink.unbounded_send(Ok(async { Ok(7i32) }))?; + /// assert_eq!(buffered.next().await, Some(Ok(7i32))); + /// + /// sink.unbounded_send(Err("error in the stream"))?; + /// assert_eq!(buffered.next().await, Some(Err("error in the stream"))); + /// # Ok::<(), Box>(()) }).unwrap(); + /// ``` + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + #[cfg(feature = "alloc")] + fn try_buffered(self, n: usize) -> TryBuffered + where + Self::Ok: TryFuture, + Self: Sized, + { + assert_stream::::Ok, Self::Error>, _>(TryBuffered::new( + self, n, + )) + } + + // TODO: false positive warning from rustdoc. Verify once #43466 settles + // + /// A convenience method for calling [`TryStream::try_poll_next`] on [`Unpin`] + /// stream types. + fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_>, + ) -> Poll>> + where + Self: Unpin, + { + Pin::new(self).try_poll_next(cx) + } + + /// Wraps a [`TryStream`] into a stream compatible with libraries using + /// futures 0.1 `Stream`. Requires the `compat` feature to be enabled. + /// ``` + /// # if cfg!(miri) { return; } // Miri does not support epoll + /// use futures::future::{FutureExt, TryFutureExt}; + /// # let (tx, rx) = futures::channel::oneshot::channel(); + /// + /// let future03 = async { + /// println!("Running on the pool"); + /// tx.send(42).unwrap(); + /// }; + /// + /// let future01 = future03 + /// .unit_error() // Make it a TryFuture + /// .boxed() // Make it Unpin + /// .compat(); + /// + /// tokio::run(future01); + /// # assert_eq!(42, futures::executor::block_on(rx).unwrap()); + /// ``` + #[cfg(feature = "compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] + fn compat(self) -> Compat + where + Self: Sized + Unpin, + { + Compat::new(self) + } + + /// Adapter that converts this stream into an [`AsyncBufRead`](crate::io::AsyncBufRead). + /// + /// This method is only available when the `std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, TryStreamExt}; + /// use futures::io::AsyncReadExt; + /// + /// let stream = stream::iter([Ok(vec![1, 2, 3]), Ok(vec![4, 5])]); + /// let mut reader = stream.into_async_read(); + /// + /// let mut buf = Vec::new(); + /// reader.read_to_end(&mut buf).await.unwrap(); + /// assert_eq!(buf, [1, 2, 3, 4, 5]); + /// # }) + /// ``` + #[cfg(feature = "io")] + #[cfg_attr(docsrs, doc(cfg(feature = "io")))] + #[cfg(feature = "std")] + fn into_async_read(self) -> IntoAsyncRead + where + Self: Sized + TryStreamExt, + Self::Ok: AsRef<[u8]>, + { + crate::io::assert_read(IntoAsyncRead::new(self)) + } + + /// Attempt to execute a predicate over an asynchronous stream and evaluate if all items + /// satisfy the predicate. Exits early if an `Err` is encountered or if an `Ok` item is found + /// that does not satisfy the predicate. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// use std::convert::Infallible; + /// + /// let number_stream = stream::iter(1..10).map(Ok::<_, Infallible>); + /// let positive = number_stream.try_all(|i| async move { i > 0 }); + /// assert_eq!(positive.await, Ok(true)); + /// + /// let stream_with_errors = stream::iter([Ok(1), Err("err"), Ok(3)]); + /// let positive = stream_with_errors.try_all(|i| async move { i > 0 }); + /// assert_eq!(positive.await, Err("err")); + /// # }); + /// ``` + fn try_all(self, f: F) -> TryAll + where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future, + { + assert_future::, _>(TryAll::new(self, f)) + } + + /// Attempt to execute a predicate over an asynchronous stream and evaluate if any items + /// satisfy the predicate. Exits early if an `Err` is encountered or if an `Ok` item is found + /// that satisfies the predicate. + /// + /// # Examples + /// + /// ``` + /// # futures::executor::block_on(async { + /// use futures::stream::{self, StreamExt, TryStreamExt}; + /// use std::convert::Infallible; + /// + /// let number_stream = stream::iter(0..10).map(Ok::<_, Infallible>); + /// let contain_three = number_stream.try_any(|i| async move { i == 3 }); + /// assert_eq!(contain_three.await, Ok(true)); + /// + /// let stream_with_errors = stream::iter([Ok(1), Err("err"), Ok(3)]); + /// let contain_three = stream_with_errors.try_any(|i| async move { i == 3 }); + /// assert_eq!(contain_three.await, Err("err")); + /// # }); + /// ``` + fn try_any(self, f: F) -> TryAny + where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future, + { + assert_future::, _>(TryAny::new(self, f)) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/or_else.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/or_else.rs new file mode 100644 index 00000000..53aceb8e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/or_else.rs @@ -0,0 +1,109 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`or_else`](super::TryStreamExt::or_else) method. + #[must_use = "streams do nothing unless polled"] + pub struct OrElse { + #[pin] + stream: St, + #[pin] + future: Option, + f: F, + } +} + +impl fmt::Debug for OrElse +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OrElse") + .field("stream", &self.stream) + .field("future", &self.future) + .finish() + } +} + +impl OrElse +where + St: TryStream, + F: FnMut(St::Error) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, future: None, f } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for OrElse +where + St: TryStream, + F: FnMut(St::Error) -> Fut, + Fut: TryFuture, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + let item = ready!(fut.try_poll(cx)); + this.future.set(None); + break Some(item); + } else { + match ready!(this.stream.as_mut().try_poll_next(cx)) { + Some(Ok(item)) => break Some(Ok(item)), + Some(Err(e)) => { + this.future.set(Some((this.f)(e))); + } + None => break None, + } + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let future_len = usize::from(self.future.is_some()); + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(future_len); + let upper = match upper { + Some(x) => x.checked_add(future_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for OrElse +where + St: TryStream + FusedStream, + F: FnMut(St::Error) -> Fut, + Fut: TryFuture, +{ + fn is_terminated(&self) -> bool { + self.future.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for OrElse +where + S: Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_all.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_all.rs new file mode 100644 index 00000000..8179f86a --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_all.rs @@ -0,0 +1,98 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`try_all`](super::TryStreamExt::try_all) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryAll { + #[pin] + stream: St, + f: F, + done: bool, + #[pin] + future: Option, + } +} + +impl fmt::Debug for TryAll +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryAll") + .field("stream", &self.stream) + .field("done", &self.done) + .field("future", &self.future) + .finish() + } +} + +impl TryAll +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, done: false, future: None } + } +} + +impl FusedFuture for TryAll +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.done && self.future.is_none() + } +} + +impl Future for TryAll +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + // we're currently processing a future to produce a new value + let acc = ready!(fut.poll(cx)); + this.future.set(None); + if !acc { + *this.done = true; + break Ok(false); + } // early exit + } else if !*this.done { + // we're waiting on a new item from the stream + match ready!(this.stream.as_mut().try_poll_next(cx)) { + Some(Ok(item)) => { + this.future.set(Some((this.f)(item))); + } + Some(Err(err)) => { + *this.done = true; + break Err(err); + } + None => { + *this.done = true; + break Ok(true); + } + } + } else { + panic!("TryAll polled after completion") + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_any.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_any.rs new file mode 100644 index 00000000..55e876be --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_any.rs @@ -0,0 +1,98 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`try_any`](super::TryStreamExt::try_any) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryAny { + #[pin] + stream: St, + f: F, + done: bool, + #[pin] + future: Option, + } +} + +impl fmt::Debug for TryAny +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryAny") + .field("stream", &self.stream) + .field("done", &self.done) + .field("future", &self.future) + .finish() + } +} + +impl TryAny +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, done: false, future: None } + } +} + +impl FusedFuture for TryAny +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.done && self.future.is_none() + } +} + +impl Future for TryAny +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + // we're currently processing a future to produce a new value + let acc = ready!(fut.poll(cx)); + this.future.set(None); + if acc { + *this.done = true; + break Ok(true); + } // early exit + } else if !*this.done { + // we're waiting on a new item from the stream + match ready!(this.stream.as_mut().try_poll_next(cx)) { + Some(Ok(item)) => { + this.future.set(Some((this.f)(item))); + } + Some(Err(err)) => { + *this.done = true; + break Err(err); + } + None => { + *this.done = true; + break Ok(false); + } + } + } else { + panic!("TryAny polled after completion") + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffer_unordered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffer_unordered.rs new file mode 100644 index 00000000..9a899d4e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffer_unordered.rs @@ -0,0 +1,86 @@ +use crate::future::{IntoFuture, TryFutureExt}; +use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt}; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::stream::{Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the + /// [`try_buffer_unordered`](super::TryStreamExt::try_buffer_unordered) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct TryBufferUnordered + where St: TryStream + { + #[pin] + stream: Fuse>, + in_progress_queue: FuturesUnordered>, + max: usize, + } +} + +impl TryBufferUnordered +where + St: TryStream, + St::Ok: TryFuture, +{ + pub(super) fn new(stream: St, n: usize) -> Self { + Self { + stream: IntoStream::new(stream).fuse(), + in_progress_queue: FuturesUnordered::new(), + max: n, + } + } + + delegate_access_inner!(stream, St, (. .)); +} + +impl Stream for TryBufferUnordered +where + St: TryStream, + St::Ok: TryFuture, +{ + type Item = Result<::Ok, St::Error>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + // First up, try to spawn off as many futures as possible by filling up + // our queue of futures. Propagate errors from the stream immediately. + while this.in_progress_queue.len() < *this.max { + match this.stream.as_mut().poll_next(cx)? { + Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut.into_future()), + Poll::Ready(None) | Poll::Pending => break, + } + } + + // Attempt to pull the next value from the in_progress_queue + match this.in_progress_queue.poll_next_unpin(cx) { + x @ Poll::Pending | x @ Poll::Ready(Some(_)) => return x, + Poll::Ready(None) => {} + } + + // If more values are still coming from the stream, we're not done yet + if this.stream.is_done() { + Poll::Ready(None) + } else { + Poll::Pending + } + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryBufferUnordered +where + S: TryStream + Sink, + S::Ok: TryFuture, +{ + type Error = E; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffered.rs new file mode 100644 index 00000000..9f48e5c0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_buffered.rs @@ -0,0 +1,87 @@ +use crate::future::{IntoFuture, TryFutureExt}; +use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt}; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::stream::{Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_buffered`](super::TryStreamExt::try_buffered) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct TryBuffered + where + St: TryStream, + St::Ok: TryFuture, + { + #[pin] + stream: Fuse>, + in_progress_queue: FuturesOrdered>, + max: usize, + } +} + +impl TryBuffered +where + St: TryStream, + St::Ok: TryFuture, +{ + pub(super) fn new(stream: St, n: usize) -> Self { + Self { + stream: IntoStream::new(stream).fuse(), + in_progress_queue: FuturesOrdered::new(), + max: n, + } + } + + delegate_access_inner!(stream, St, (. .)); +} + +impl Stream for TryBuffered +where + St: TryStream, + St::Ok: TryFuture, +{ + type Item = Result<::Ok, St::Error>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + // First up, try to spawn off as many futures as possible by filling up + // our queue of futures. Propagate errors from the stream immediately. + while this.in_progress_queue.len() < *this.max { + match this.stream.as_mut().poll_next(cx)? { + Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut.into_future()), + Poll::Ready(None) | Poll::Pending => break, + } + } + + // Attempt to pull the next value from the in_progress_queue + match this.in_progress_queue.poll_next_unpin(cx) { + x @ Poll::Pending | x @ Poll::Ready(Some(_)) => return x, + Poll::Ready(None) => {} + } + + // If more values are still coming from the stream, we're not done yet + if this.stream.is_done() { + Poll::Ready(None) + } else { + Poll::Pending + } + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryBuffered +where + S: TryStream + Sink, + S::Ok: TryFuture, +{ + type Error = E; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_chunks.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_chunks.rs new file mode 100644 index 00000000..ec53f4bd --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_chunks.rs @@ -0,0 +1,132 @@ +use crate::stream::{Fuse, IntoStream, StreamExt}; + +use alloc::vec::Vec; +use core::pin::Pin; +use core::{fmt, mem}; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_chunks`](super::TryStreamExt::try_chunks) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct TryChunks { + #[pin] + stream: Fuse>, + items: Vec, + cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 + } +} + +impl TryChunks { + pub(super) fn new(stream: St, capacity: usize) -> Self { + assert!(capacity > 0); + + Self { + stream: IntoStream::new(stream).fuse(), + items: Vec::with_capacity(capacity), + cap: capacity, + } + } + + fn take(self: Pin<&mut Self>) -> Vec { + let cap = self.cap; + mem::replace(self.project().items, Vec::with_capacity(cap)) + } + + delegate_access_inner!(stream, St, (. .)); +} + +type TryChunksStreamError = TryChunksError<::Ok, ::Error>; + +impl Stream for TryChunks { + type Item = Result, TryChunksStreamError>; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.as_mut().project(); + loop { + match ready!(this.stream.as_mut().try_poll_next(cx)) { + // Push the item into the buffer and check whether it is full. + // If so, replace our buffer with a new and empty one and return + // the full one. + Some(item) => match item { + Ok(item) => { + this.items.push(item); + if this.items.len() >= *this.cap { + return Poll::Ready(Some(Ok(self.take()))); + } + } + Err(e) => { + return Poll::Ready(Some(Err(TryChunksError(self.take(), e)))); + } + }, + + // Since the underlying stream ran out of values, return what we + // have buffered, if we have anything. + None => { + let last = if this.items.is_empty() { + None + } else { + let full_buf = mem::take(this.items); + Some(full_buf) + }; + + return Poll::Ready(last.map(Ok)); + } + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let chunk_len = usize::from(!self.items.is_empty()); + let (lower, upper) = self.stream.size_hint(); + let lower = (lower / self.cap).saturating_add(chunk_len); + let upper = match upper { + Some(x) => x.checked_add(chunk_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for TryChunks { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() && self.items.is_empty() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryChunks +where + S: TryStream + Sink, +{ + type Error = >::Error; + + delegate_sink!(stream, Item); +} + +/// Error indicating, that while chunk was collected inner stream produced an error. +/// +/// Contains all items that were collected before an error occurred, and the stream error itself. +#[derive(PartialEq, Eq)] +pub struct TryChunksError(pub Vec, pub E); + +impl fmt::Debug for TryChunksError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.1.fmt(f) + } +} + +impl fmt::Display for TryChunksError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.1.fmt(f) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for TryChunksError {} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_collect.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_collect.rs new file mode 100644 index 00000000..3e5963f0 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_collect.rs @@ -0,0 +1,52 @@ +use core::mem; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::ready; +use futures_core::stream::{FusedStream, TryStream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`try_collect`](super::TryStreamExt::try_collect) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryCollect { + #[pin] + stream: St, + items: C, + } +} + +impl TryCollect { + pub(super) fn new(s: St) -> Self { + Self { stream: s, items: Default::default() } + } +} + +impl FusedFuture for TryCollect +where + St: TryStream + FusedStream, + C: Default + Extend, +{ + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for TryCollect +where + St: TryStream, + C: Default + Extend, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + Poll::Ready(Ok(loop { + match ready!(this.stream.as_mut().try_poll_next(cx)?) { + Some(x) => this.items.extend(Some(x)), + None => break mem::take(this.items), + } + })) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_concat.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_concat.rs new file mode 100644 index 00000000..58fb6a54 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_concat.rs @@ -0,0 +1,51 @@ +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`try_concat`](super::TryStreamExt::try_concat) method. + #[derive(Debug)] + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryConcat { + #[pin] + stream: St, + accum: Option, + } +} + +impl TryConcat +where + St: TryStream, + St::Ok: Extend<::Item> + IntoIterator + Default, +{ + pub(super) fn new(stream: St) -> Self { + Self { stream, accum: None } + } +} + +impl Future for TryConcat +where + St: TryStream, + St::Ok: Extend<::Item> + IntoIterator + Default, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + + Poll::Ready(Ok(loop { + if let Some(x) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + if let Some(a) = this.accum { + a.extend(x) + } else { + *this.accum = Some(x) + } + } else { + break this.accum.take().unwrap_or_default(); + } + })) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter.rs new file mode 100644 index 00000000..11d58243 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter.rs @@ -0,0 +1,112 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_filter`](super::TryStreamExt::try_filter) + /// method. + #[must_use = "streams do nothing unless polled"] + pub struct TryFilter + where St: TryStream + { + #[pin] + stream: St, + f: F, + #[pin] + pending_fut: Option, + pending_item: Option, + } +} + +impl fmt::Debug for TryFilter +where + St: TryStream + fmt::Debug, + St::Ok: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryFilter") + .field("stream", &self.stream) + .field("pending_fut", &self.pending_fut) + .field("pending_item", &self.pending_item) + .finish() + } +} + +impl TryFilter +where + St: TryStream, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending_fut: None, pending_item: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for TryFilter +where + St: TryStream + FusedStream, + F: FnMut(&St::Ok) -> Fut, + Fut: Future, +{ + fn is_terminated(&self) -> bool { + self.pending_fut.is_none() && self.stream.is_terminated() + } +} + +impl Stream for TryFilter +where + St: TryStream, + Fut: Future, + F: FnMut(&St::Ok) -> Fut, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { + let res = ready!(fut.poll(cx)); + this.pending_fut.set(None); + if res { + break this.pending_item.take().map(Ok); + } + *this.pending_item = None; + } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + this.pending_fut.set(Some((this.f)(&item))); + *this.pending_item = Some(item); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let pending_len = usize::from(self.pending_fut.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryFilter +where + S: TryStream + Sink, +{ + type Error = E; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter_map.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter_map.rs new file mode 100644 index 00000000..ed120173 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_filter_map.rs @@ -0,0 +1,106 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_filter_map`](super::TryStreamExt::try_filter_map) + /// method. + #[must_use = "streams do nothing unless polled"] + pub struct TryFilterMap { + #[pin] + stream: St, + f: F, + #[pin] + pending: Option, + } +} + +impl fmt::Debug for TryFilterMap +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryFilterMap") + .field("stream", &self.stream) + .field("pending", &self.pending) + .finish() + } +} + +impl TryFilterMap { + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for TryFilterMap +where + St: TryStream + FusedStream, + Fut: TryFuture, Error = St::Error>, + F: FnMut(St::Ok) -> Fut, +{ + fn is_terminated(&self) -> bool { + self.pending.is_none() && self.stream.is_terminated() + } +} + +impl Stream for TryFilterMap +where + St: TryStream, + Fut: TryFuture, Error = St::Error>, + F: FnMut(St::Ok) -> Fut, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(p) = this.pending.as_mut().as_pin_mut() { + // We have an item in progress, poll that until it's done + let res = ready!(p.try_poll(cx)); + this.pending.set(None); + let item = res?; + if item.is_some() { + break item.map(Ok); + } + } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + // No item in progress, but the stream is still going + this.pending.set(Some((this.f)(item))); + } else { + // The stream is done + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let pending_len = usize::from(self.pending.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryFilterMap +where + S: Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten.rs new file mode 100644 index 00000000..4fc04a07 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten.rs @@ -0,0 +1,84 @@ +use core::pin::Pin; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_flatten`](super::TryStreamExt::try_flatten) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct TryFlatten + where + St: TryStream, + { + #[pin] + stream: St, + #[pin] + next: Option, + } +} + +impl TryFlatten +where + St: TryStream, + St::Ok: TryStream, + ::Error: From, +{ + pub(super) fn new(stream: St) -> Self { + Self { stream, next: None } + } + + delegate_access_inner!(stream, St, ()); +} + +impl FusedStream for TryFlatten +where + St: TryStream + FusedStream, + St::Ok: TryStream, + ::Error: From, +{ + fn is_terminated(&self) -> bool { + self.next.is_none() && self.stream.is_terminated() + } +} + +impl Stream for TryFlatten +where + St: TryStream, + St::Ok: TryStream, + ::Error: From, +{ + type Item = Result<::Ok, ::Error>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(s) = this.next.as_mut().as_pin_mut() { + if let Some(item) = ready!(s.try_poll_next(cx)?) { + break Some(Ok(item)); + } else { + this.next.set(None); + } + } else if let Some(s) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + this.next.set(Some(s)); + } else { + break None; + } + }) + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryFlatten +where + S: TryStream + Sink, +{ + type Error = >::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten_unordered.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten_unordered.rs new file mode 100644 index 00000000..a74dfc45 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_flatten_unordered.rs @@ -0,0 +1,176 @@ +use core::marker::PhantomData; +use core::pin::Pin; + +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; + +use pin_project_lite::pin_project; + +use crate::future::Either; +use crate::stream::stream::flatten_unordered::{ + FlattenUnorderedWithFlowController, FlowController, FlowStep, +}; +use crate::stream::IntoStream; +use crate::TryStreamExt; + +delegate_all!( + /// Stream for the [`try_flatten_unordered`](super::TryStreamExt::try_flatten_unordered) method. + TryFlattenUnordered( + FlattenUnorderedWithFlowController, PropagateBaseStreamError> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + + New[ + |stream: St, limit: impl Into>| + FlattenUnorderedWithFlowController::new( + NestedTryStreamIntoEitherTryStream::new(stream), + limit.into() + ) + ] + where + St: TryStream, + St::Ok: TryStream, + St::Ok: Unpin, + ::Error: From +); + +pin_project! { + /// Emits either successful streams or single-item streams containing the underlying errors. + /// This's a wrapper for `FlattenUnordered` to reuse its logic over `TryStream`. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct NestedTryStreamIntoEitherTryStream + where + St: TryStream, + St::Ok: TryStream, + St::Ok: Unpin, + ::Error: From + { + #[pin] + stream: St + } +} + +impl NestedTryStreamIntoEitherTryStream +where + St: TryStream, + St::Ok: TryStream + Unpin, + ::Error: From, +{ + fn new(stream: St) -> Self { + Self { stream } + } + + delegate_access_inner!(stream, St, ()); +} + +/// Emits a single item immediately, then stream will be terminated. +#[derive(Debug, Clone)] +pub struct Single(Option); + +impl Single { + /// Constructs new `Single` with the given value. + fn new(val: T) -> Self { + Self(Some(val)) + } + + /// Attempts to take inner item immediately. Will always succeed if the stream isn't terminated. + fn next_immediate(&mut self) -> Option { + self.0.take() + } +} + +impl Unpin for Single {} + +impl Stream for Single { + type Item = T; + + fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(self.0.take()) + } + + fn size_hint(&self) -> (usize, Option) { + self.0.as_ref().map_or((0, Some(0)), |_| (1, Some(1))) + } +} + +/// Immediately propagates errors occurred in the base stream. +#[derive(Debug, Clone, Copy)] +pub struct PropagateBaseStreamError(PhantomData); + +type BaseStreamItem = as Stream>::Item; +type InnerStreamItem = as Stream>::Item; + +impl FlowController, InnerStreamItem> for PropagateBaseStreamError +where + St: TryStream, + St::Ok: TryStream + Unpin, + ::Error: From, +{ + fn next_step(item: BaseStreamItem) -> FlowStep, InnerStreamItem> { + match item { + // A new successful inner stream received + st @ Either::Left(_) => FlowStep::Continue(st), + // An error encountered + Either::Right(mut err) => FlowStep::Return(err.next_immediate().unwrap()), + } + } +} + +type SingleStreamResult = Single::Ok, ::Error>>; + +impl Stream for NestedTryStreamIntoEitherTryStream +where + St: TryStream, + St::Ok: TryStream + Unpin, + ::Error: From, +{ + // Item is either an inner stream or a stream containing a single error. + // This will allow using `Either`'s `Stream` implementation as both branches are actually streams of `Result`'s. + type Item = Either, SingleStreamResult>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let item = ready!(self.project().stream.try_poll_next(cx)); + + let out = match item { + Some(res) => match res { + // Emit successful inner stream as is + Ok(stream) => Either::Left(stream.into_stream()), + // Wrap an error into a stream containing a single item + err @ Err(_) => { + let res = err.map(|_: St::Ok| unreachable!()).map_err(Into::into); + + Either::Right(Single::new(res)) + } + }, + None => return Poll::Ready(None), + }; + + Poll::Ready(Some(out)) + } +} + +impl FusedStream for NestedTryStreamIntoEitherTryStream +where + St: TryStream + FusedStream, + St::Ok: TryStream + Unpin, + ::Error: From, +{ + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for NestedTryStreamIntoEitherTryStream +where + St: TryStream + Sink, + St::Ok: TryStream + Unpin, + ::Error: From<::Error>, +{ + type Error = >::Error; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_fold.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_fold.rs new file mode 100644 index 00000000..d344d96e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_fold.rs @@ -0,0 +1,93 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future, TryFuture}; +use futures_core::ready; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`try_fold`](super::TryStreamExt::try_fold) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryFold { + #[pin] + stream: St, + f: F, + accum: Option, + #[pin] + future: Option, + } +} + +impl fmt::Debug for TryFold +where + St: fmt::Debug, + Fut: fmt::Debug, + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryFold") + .field("stream", &self.stream) + .field("accum", &self.accum) + .field("future", &self.future) + .finish() + } +} + +impl TryFold +where + St: TryStream, + F: FnMut(T, St::Ok) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F, t: T) -> Self { + Self { stream, f, accum: Some(t), future: None } + } +} + +impl FusedFuture for TryFold +where + St: TryStream, + F: FnMut(T, St::Ok) -> Fut, + Fut: TryFuture, +{ + fn is_terminated(&self) -> bool { + self.accum.is_none() && self.future.is_none() + } +} + +impl Future for TryFold +where + St: TryStream, + F: FnMut(T, St::Ok) -> Fut, + Fut: TryFuture, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + // we're currently processing a future to produce a new accum value + let res = ready!(fut.try_poll(cx)); + this.future.set(None); + match res { + Ok(a) => *this.accum = Some(a), + Err(e) => break Err(e), + } + } else if this.accum.is_some() { + // we're waiting on a new item from the stream + let res = ready!(this.stream.as_mut().try_poll_next(cx)); + let a = this.accum.take().unwrap(); + match res { + Some(Ok(item)) => this.future.set(Some((this.f)(a, item))), + Some(Err(e)) => break Err(e), + None => break Ok(a), + } + } else { + panic!("Fold polled after completion") + } + }) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each.rs new file mode 100644 index 00000000..6a081d84 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each.rs @@ -0,0 +1,68 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::{Future, TryFuture}; +use futures_core::ready; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [`try_for_each`](super::TryStreamExt::try_for_each) method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryForEach { + #[pin] + stream: St, + f: F, + #[pin] + future: Option, + } +} + +impl fmt::Debug for TryForEach +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryForEach") + .field("stream", &self.stream) + .field("future", &self.future) + .finish() + } +} + +impl TryForEach +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, future: None } + } +} + +impl Future for TryForEach +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: TryFuture, +{ + type Output = Result<(), St::Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + ready!(fut.try_poll(cx))?; + this.future.set(None); + } else { + match ready!(this.stream.as_mut().try_poll_next(cx)?) { + Some(e) => this.future.set(Some((this.f)(e))), + None => break, + } + } + } + Poll::Ready(Ok(())) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each_concurrent.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each_concurrent.rs new file mode 100644 index 00000000..62734c74 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_for_each_concurrent.rs @@ -0,0 +1,133 @@ +use crate::stream::{FuturesUnordered, StreamExt}; +use core::fmt; +use core::mem; +use core::num::NonZeroUsize; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::stream::TryStream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the + /// [`try_for_each_concurrent`](super::TryStreamExt::try_for_each_concurrent) + /// method. + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct TryForEachConcurrent { + #[pin] + stream: Option, + f: F, + futures: FuturesUnordered, + limit: Option, + } +} + +impl fmt::Debug for TryForEachConcurrent +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryForEachConcurrent") + .field("stream", &self.stream) + .field("futures", &self.futures) + .field("limit", &self.limit) + .finish() + } +} + +impl FusedFuture for TryForEachConcurrent +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future>, +{ + fn is_terminated(&self) -> bool { + self.stream.is_none() && self.futures.is_empty() + } +} + +impl TryForEachConcurrent +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future>, +{ + pub(super) fn new(stream: St, limit: Option, f: F) -> Self { + Self { + stream: Some(stream), + // Note: `limit` = 0 gets ignored. + limit: limit.and_then(NonZeroUsize::new), + f, + futures: FuturesUnordered::new(), + } + } +} + +impl Future for TryForEachConcurrent +where + St: TryStream, + F: FnMut(St::Ok) -> Fut, + Fut: Future>, +{ + type Output = Result<(), St::Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let mut this = self.project(); + loop { + let mut made_progress_this_iter = false; + + // Check if we've already created a number of futures greater than `limit` + if this.limit.map(|limit| limit.get() > this.futures.len()).unwrap_or(true) { + let poll_res = match this.stream.as_mut().as_pin_mut() { + Some(stream) => stream.try_poll_next(cx), + None => Poll::Ready(None), + }; + + let elem = match poll_res { + Poll::Ready(Some(Ok(elem))) => { + made_progress_this_iter = true; + Some(elem) + } + Poll::Ready(None) => { + this.stream.set(None); + None + } + Poll::Pending => None, + Poll::Ready(Some(Err(e))) => { + // Empty the stream and futures so that we know + // the future has completed. + this.stream.set(None); + drop(mem::replace(this.futures, FuturesUnordered::new())); + return Poll::Ready(Err(e)); + } + }; + + if let Some(elem) = elem { + this.futures.push((this.f)(elem)); + } + } + + match this.futures.poll_next_unpin(cx) { + Poll::Ready(Some(Ok(()))) => made_progress_this_iter = true, + Poll::Ready(None) => { + if this.stream.is_none() { + return Poll::Ready(Ok(())); + } + } + Poll::Pending => {} + Poll::Ready(Some(Err(e))) => { + // Empty the stream and futures so that we know + // the future has completed. + this.stream.set(None); + drop(mem::replace(this.futures, FuturesUnordered::new())); + return Poll::Ready(Err(e)); + } + } + + if !made_progress_this_iter { + return Poll::Pending; + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_next.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_next.rs new file mode 100644 index 00000000..13fcf80c --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_next.rs @@ -0,0 +1,34 @@ +use crate::stream::TryStreamExt; +use core::pin::Pin; +use futures_core::future::{FusedFuture, Future}; +use futures_core::stream::{FusedStream, TryStream}; +use futures_core::task::{Context, Poll}; + +/// Future for the [`try_next`](super::TryStreamExt::try_next) method. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct TryNext<'a, St: ?Sized> { + stream: &'a mut St, +} + +impl Unpin for TryNext<'_, St> {} + +impl<'a, St: ?Sized + TryStream + Unpin> TryNext<'a, St> { + pub(super) fn new(stream: &'a mut St) -> Self { + Self { stream } + } +} + +impl FusedFuture for TryNext<'_, St> { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +impl Future for TryNext<'_, St> { + type Output = Result, St::Error>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.stream.try_poll_next_unpin(cx)?.map(Ok) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_ready_chunks.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_ready_chunks.rs new file mode 100644 index 00000000..8b1470ea --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_ready_chunks.rs @@ -0,0 +1,126 @@ +use crate::stream::{Fuse, IntoStream, StreamExt}; + +use alloc::vec::Vec; +use core::fmt; +use core::pin::Pin; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_ready_chunks`](super::TryStreamExt::try_ready_chunks) method. + #[derive(Debug)] + #[must_use = "streams do nothing unless polled"] + pub struct TryReadyChunks { + #[pin] + stream: Fuse>, + cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 + } +} + +impl TryReadyChunks { + pub(super) fn new(stream: St, capacity: usize) -> Self { + assert!(capacity > 0); + + Self { stream: IntoStream::new(stream).fuse(), cap: capacity } + } + + delegate_access_inner!(stream, St, (. .)); +} + +type TryReadyChunksStreamError = + TryReadyChunksError<::Ok, ::Error>; + +impl Stream for TryReadyChunks { + type Item = Result, TryReadyChunksStreamError>; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.as_mut().project(); + + let mut items: Vec = Vec::new(); + + loop { + match this.stream.as_mut().poll_next(cx) { + // Flush all the collected data if the underlying stream doesn't + // contain more ready values + Poll::Pending => { + return if items.is_empty() { + Poll::Pending + } else { + Poll::Ready(Some(Ok(items))) + } + } + + // Push the ready item into the buffer and check whether it is full. + // If so, return the buffer. + Poll::Ready(Some(Ok(item))) => { + if items.is_empty() { + items.reserve_exact(*this.cap); + } + items.push(item); + if items.len() >= *this.cap { + return Poll::Ready(Some(Ok(items))); + } + } + + // Return the already collected items and the error. + Poll::Ready(Some(Err(e))) => { + return Poll::Ready(Some(Err(TryReadyChunksError(items, e)))); + } + + // Since the underlying stream ran out of values, return what we + // have buffered, if we have anything. + Poll::Ready(None) => { + let last = if items.is_empty() { None } else { Some(Ok(items)) }; + return Poll::Ready(last); + } + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.stream.size_hint(); + let lower = lower / self.cap; + (lower, upper) + } +} + +impl FusedStream for TryReadyChunks { + fn is_terminated(&self) -> bool { + self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryReadyChunks +where + S: TryStream + Sink, +{ + type Error = >::Error; + + delegate_sink!(stream, Item); +} + +/// Error indicating, that while chunk was collected inner stream produced an error. +/// +/// Contains all items that were collected before an error occurred, and the stream error itself. +#[derive(PartialEq, Eq)] +pub struct TryReadyChunksError(pub Vec, pub E); + +impl fmt::Debug for TryReadyChunksError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.1.fmt(f) + } +} + +impl fmt::Display for TryReadyChunksError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.1.fmt(f) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for TryReadyChunksError {} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_skip_while.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_skip_while.rs new file mode 100644 index 00000000..52aa2d47 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_skip_while.rs @@ -0,0 +1,120 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_skip_while`](super::TryStreamExt::try_skip_while) + /// method. + #[must_use = "streams do nothing unless polled"] + pub struct TrySkipWhile where St: TryStream { + #[pin] + stream: St, + f: F, + #[pin] + pending_fut: Option, + pending_item: Option, + done_skipping: bool, + } +} + +impl fmt::Debug for TrySkipWhile +where + St: TryStream + fmt::Debug, + St::Ok: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TrySkipWhile") + .field("stream", &self.stream) + .field("pending_fut", &self.pending_fut) + .field("pending_item", &self.pending_item) + .field("done_skipping", &self.done_skipping) + .finish() + } +} + +impl TrySkipWhile +where + St: TryStream, + F: FnMut(&St::Ok) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for TrySkipWhile +where + St: TryStream, + F: FnMut(&St::Ok) -> Fut, + Fut: TryFuture, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if *this.done_skipping { + return this.stream.try_poll_next(cx); + } + + Poll::Ready(loop { + if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { + let res = ready!(fut.try_poll(cx)); + this.pending_fut.set(None); + let skipped = res?; + let item = this.pending_item.take(); + if !skipped { + *this.done_skipping = true; + break item.map(Ok); + } + } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + this.pending_fut.set(Some((this.f)(&item))); + *this.pending_item = Some(item); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let pending_len = usize::from(self.pending_item.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +impl FusedStream for TrySkipWhile +where + St: TryStream + FusedStream, + F: FnMut(&St::Ok) -> Fut, + Fut: TryFuture, +{ + fn is_terminated(&self) -> bool { + self.pending_item.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TrySkipWhile +where + S: TryStream + Sink, +{ + type Error = E; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_take_while.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_take_while.rs new file mode 100644 index 00000000..4b5ff1ad --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_take_while.rs @@ -0,0 +1,129 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`try_take_while`](super::TryStreamExt::try_take_while) + /// method. + #[must_use = "streams do nothing unless polled"] + pub struct TryTakeWhile + where + St: TryStream, + { + #[pin] + stream: St, + f: F, + #[pin] + pending_fut: Option, + pending_item: Option, + done_taking: bool, + } +} + +impl fmt::Debug for TryTakeWhile +where + St: TryStream + fmt::Debug, + St::Ok: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryTakeWhile") + .field("stream", &self.stream) + .field("pending_fut", &self.pending_fut) + .field("pending_item", &self.pending_item) + .field("done_taking", &self.done_taking) + .finish() + } +} + +impl TryTakeWhile +where + St: TryStream, + F: FnMut(&St::Ok) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, f, pending_fut: None, pending_item: None, done_taking: false } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for TryTakeWhile +where + St: TryStream, + F: FnMut(&St::Ok) -> Fut, + Fut: TryFuture, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if *this.done_taking { + return Poll::Ready(None); + } + + Poll::Ready(loop { + if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { + let res = ready!(fut.try_poll(cx)); + this.pending_fut.set(None); + let take = res?; + let item = this.pending_item.take(); + if take { + break item.map(Ok); + } else { + *this.done_taking = true; + break None; + } + } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { + this.pending_fut.set(Some((this.f)(&item))); + *this.pending_item = Some(item); + } else { + break None; + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + if self.done_taking { + return (0, Some(0)); + } + + let pending_len = usize::from(self.pending_item.is_some()); + let (_, upper) = self.stream.size_hint(); + let upper = match upper { + Some(x) => x.checked_add(pending_len), + None => None, + }; + (0, upper) // can't know a lower bound, due to the predicate + } +} + +impl FusedStream for TryTakeWhile +where + St: TryStream + FusedStream, + F: FnMut(&St::Ok) -> Fut, + Fut: TryFuture, +{ + fn is_terminated(&self) -> bool { + self.done_taking || self.pending_item.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for TryTakeWhile +where + S: TryStream + Sink, +{ + type Error = E; + + delegate_sink!(stream, Item); +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_unfold.rs b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_unfold.rs new file mode 100644 index 00000000..fd9cdf1d --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/try_stream/try_unfold.rs @@ -0,0 +1,122 @@ +use super::assert_stream; +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::Stream; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +/// Creates a `TryStream` from a seed and a closure returning a `TryFuture`. +/// +/// This function is the dual for the `TryStream::try_fold()` adapter: while +/// `TryStream::try_fold()` reduces a `TryStream` to one single value, +/// `try_unfold()` creates a `TryStream` from a seed value. +/// +/// `try_unfold()` will call the provided closure with the provided seed, then +/// wait for the returned `TryFuture` to complete with `(a, b)`. It will then +/// yield the value `a`, and use `b` as the next internal state. +/// +/// If the closure returns `None` instead of `Some(TryFuture)`, then the +/// `try_unfold()` will stop producing items and return `Poll::Ready(None)` in +/// future calls to `poll()`. +/// +/// In case of error generated by the returned `TryFuture`, the error will be +/// returned by the `TryStream`. The `TryStream` will then yield +/// `Poll::Ready(None)` in future calls to `poll()`. +/// +/// This function can typically be used when wanting to go from the "world of +/// futures" to the "world of streams": the provided closure can build a +/// `TryFuture` using other library functions working on futures, and +/// `try_unfold()` will turn it into a `TryStream` by repeating the operation. +/// +/// # Example +/// +/// ``` +/// # #[derive(Debug, PartialEq)] +/// # struct SomeError; +/// # futures::executor::block_on(async { +/// use futures::stream::{self, TryStreamExt}; +/// +/// let stream = stream::try_unfold(0, |state| async move { +/// if state < 0 { +/// return Err(SomeError); +/// } +/// +/// if state <= 2 { +/// let next_state = state + 1; +/// let yielded = state * 2; +/// Ok(Some((yielded, next_state))) +/// } else { +/// Ok(None) +/// } +/// }); +/// +/// let result: Result, _> = stream.try_collect().await; +/// assert_eq!(result, Ok(vec![0, 2, 4])); +/// # }); +/// ``` +pub fn try_unfold(init: T, f: F) -> TryUnfold +where + F: FnMut(T) -> Fut, + Fut: TryFuture>, +{ + assert_stream::, _>(TryUnfold { f, state: Some(init), fut: None }) +} + +pin_project! { + /// Stream for the [`try_unfold`] function. + #[must_use = "streams do nothing unless polled"] + pub struct TryUnfold { + f: F, + state: Option, + #[pin] + fut: Option, + } +} + +impl fmt::Debug for TryUnfold +where + T: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryUnfold").field("state", &self.state).field("fut", &self.fut).finish() + } +} + +impl Stream for TryUnfold +where + F: FnMut(T) -> Fut, + Fut: TryFuture>, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if let Some(state) = this.state.take() { + this.fut.set(Some((this.f)(state))); + } + + match this.fut.as_mut().as_pin_mut() { + None => { + // The future previously errored + Poll::Ready(None) + } + Some(future) => { + let step = ready!(future.try_poll(cx)); + this.fut.set(None); + + match step { + Ok(Some((item, next_state))) => { + *this.state = Some(next_state); + Poll::Ready(Some(Ok(item))) + } + Ok(None) => Poll::Ready(None), + Err(e) => Poll::Ready(Some(Err(e))), + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/stream/unfold.rs b/utshell-0.5.0/vendor/futures-util/src/stream/unfold.rs new file mode 100644 index 00000000..2f48cccb --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/stream/unfold.rs @@ -0,0 +1,119 @@ +use super::assert_stream; +use crate::unfold_state::UnfoldState; +use core::fmt; +use core::pin::Pin; +use futures_core::future::Future; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream}; +use futures_core::task::{Context, Poll}; +use pin_project_lite::pin_project; + +/// Creates a `Stream` from a seed and a closure returning a `Future`. +/// +/// This function is the dual for the `Stream::fold()` adapter: while +/// `Stream::fold()` reduces a `Stream` to one single value, `unfold()` creates a +/// `Stream` from a seed value. +/// +/// `unfold()` will call the provided closure with the provided seed, then wait +/// for the returned `Future` to complete with `(a, b)`. It will then yield the +/// value `a`, and use `b` as the next internal state. +/// +/// If the closure returns `None` instead of `Some(Future)`, then the `unfold()` +/// will stop producing items and return `Poll::Ready(None)` in future +/// calls to `poll()`. +/// +/// This function can typically be used when wanting to go from the "world of +/// futures" to the "world of streams": the provided closure can build a +/// `Future` using other library functions working on futures, and `unfold()` +/// will turn it into a `Stream` by repeating the operation. +/// +/// # Example +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::stream::{self, StreamExt}; +/// +/// let stream = stream::unfold(0, |state| async move { +/// if state <= 2 { +/// let next_state = state + 1; +/// let yielded = state * 2; +/// Some((yielded, next_state)) +/// } else { +/// None +/// } +/// }); +/// +/// let result = stream.collect::>().await; +/// assert_eq!(result, vec![0, 2, 4]); +/// # }); +/// ``` +pub fn unfold(init: T, f: F) -> Unfold +where + F: FnMut(T) -> Fut, + Fut: Future>, +{ + assert_stream::(Unfold { f, state: UnfoldState::Value { value: init } }) +} + +pin_project! { + /// Stream for the [`unfold`] function. + #[must_use = "streams do nothing unless polled"] + pub struct Unfold { + f: F, + #[pin] + state: UnfoldState, + } +} + +impl fmt::Debug for Unfold +where + T: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Unfold").field("state", &self.state).finish() + } +} + +impl FusedStream for Unfold +where + F: FnMut(T) -> Fut, + Fut: Future>, +{ + fn is_terminated(&self) -> bool { + if let UnfoldState::Empty = self.state { + true + } else { + false + } + } +} + +impl Stream for Unfold +where + F: FnMut(T) -> Fut, + Fut: Future>, +{ + type Item = Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + if let Some(state) = this.state.as_mut().take_value() { + this.state.set(UnfoldState::Future { future: (this.f)(state) }); + } + + let step = match this.state.as_mut().project_future() { + Some(fut) => ready!(fut.poll(cx)), + None => panic!("Unfold must not be polled after it returned `Poll::Ready(None)`"), + }; + + if let Some((item, next_state)) = step { + this.state.set(UnfoldState::Value { value: next_state }); + Poll::Ready(Some(item)) + } else { + this.state.set(UnfoldState::Empty); + Poll::Ready(None) + } + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/task/mod.rs b/utshell-0.5.0/vendor/futures-util/src/task/mod.rs new file mode 100644 index 00000000..7a9e993e --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/task/mod.rs @@ -0,0 +1,40 @@ +//! Tools for working with tasks. +//! +//! This module contains: +//! +//! - [`Spawn`], a trait for spawning new tasks. +//! - [`Context`], a context of an asynchronous task, +//! including a handle for waking up the task. +//! - [`Waker`], a handle for waking up a task. +//! +//! The remaining types and traits in the module are used for implementing +//! executors or dealing with synchronization issues around task wakeup. + +#[doc(no_inline)] +pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; + +pub use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError, UnsafeFutureObj}; + +pub use futures_task::noop_waker; +pub use futures_task::noop_waker_ref; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use futures_task::ArcWake; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use futures_task::waker; + +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] +#[cfg(feature = "alloc")] +pub use futures_task::{waker_ref, WakerRef}; + +#[cfg_attr( + target_os = "none", + cfg(any(target_has_atomic = "ptr", feature = "portable-atomic")) +)] +pub use futures_core::task::__internal::AtomicWaker; + +mod spawn; +pub use self::spawn::{LocalSpawnExt, SpawnExt}; diff --git a/utshell-0.5.0/vendor/futures-util/src/task/spawn.rs b/utshell-0.5.0/vendor/futures-util/src/task/spawn.rs new file mode 100644 index 00000000..d9e99853 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/task/spawn.rs @@ -0,0 +1,169 @@ +use futures_task::{LocalSpawn, Spawn}; + +#[cfg(feature = "compat")] +use crate::compat::Compat; + +#[cfg(feature = "channel")] +#[cfg(feature = "std")] +use crate::future::{FutureExt, RemoteHandle}; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use futures_core::future::Future; +#[cfg(feature = "alloc")] +use futures_task::{FutureObj, LocalFutureObj, SpawnError}; + +impl SpawnExt for Sp where Sp: Spawn {} +impl LocalSpawnExt for Sp where Sp: LocalSpawn {} + +/// Extension trait for `Spawn`. +pub trait SpawnExt: Spawn { + /// Spawns a task that polls the given future with output `()` to + /// completion. + /// + /// This method returns a [`Result`] that contains a [`SpawnError`] if + /// spawning fails. + /// + /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if + /// you want to spawn a future with output other than `()` or if you want + /// to be able to await its completion. + /// + /// Note this method will eventually be replaced with the upcoming + /// `Spawn::spawn` method which will take a `dyn Future` as input. + /// Technical limitations prevent `Spawn::spawn` from being implemented + /// today. Feel free to use this method in the meantime. + /// + /// ``` + /// # { + /// use futures::executor::ThreadPool; + /// use futures::task::SpawnExt; + /// + /// let executor = ThreadPool::new().unwrap(); + /// + /// let future = async { /* ... */ }; + /// executor.spawn(future).unwrap(); + /// # } + /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 + /// ``` + #[cfg(feature = "alloc")] + fn spawn(&self, future: Fut) -> Result<(), SpawnError> + where + Fut: Future + Send + 'static, + { + self.spawn_obj(FutureObj::new(Box::new(future))) + } + + /// Spawns a task that polls the given future to completion and returns a + /// future that resolves to the spawned future's output. + /// + /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if + /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that + /// resolves to the output of the spawned future. + /// + /// ``` + /// # { + /// use futures::executor::{block_on, ThreadPool}; + /// use futures::future; + /// use futures::task::SpawnExt; + /// + /// let executor = ThreadPool::new().unwrap(); + /// + /// let future = future::ready(1); + /// let join_handle_fut = executor.spawn_with_handle(future).unwrap(); + /// assert_eq!(block_on(join_handle_fut), 1); + /// # } + /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 + /// ``` + #[cfg(feature = "channel")] + #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] + #[cfg(feature = "std")] + fn spawn_with_handle(&self, future: Fut) -> Result, SpawnError> + where + Fut: Future + Send + 'static, + Fut::Output: Send, + { + let (future, handle) = future.remote_handle(); + self.spawn(future)?; + Ok(handle) + } + + /// Wraps a [`Spawn`] and makes it usable as a futures 0.1 `Executor`. + /// Requires the `compat` feature to enable. + #[cfg(feature = "compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] + fn compat(self) -> Compat + where + Self: Sized, + { + Compat::new(self) + } +} + +/// Extension trait for `LocalSpawn`. +pub trait LocalSpawnExt: LocalSpawn { + /// Spawns a task that polls the given future with output `()` to + /// completion. + /// + /// This method returns a [`Result`] that contains a [`SpawnError`] if + /// spawning fails. + /// + /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if + /// you want to spawn a future with output other than `()` or if you want + /// to be able to await its completion. + /// + /// Note this method will eventually be replaced with the upcoming + /// `Spawn::spawn` method which will take a `dyn Future` as input. + /// Technical limitations prevent `Spawn::spawn` from being implemented + /// today. Feel free to use this method in the meantime. + /// + /// ``` + /// use futures::executor::LocalPool; + /// use futures::task::LocalSpawnExt; + /// + /// let executor = LocalPool::new(); + /// let spawner = executor.spawner(); + /// + /// let future = async { /* ... */ }; + /// spawner.spawn_local(future).unwrap(); + /// ``` + #[cfg(feature = "alloc")] + fn spawn_local(&self, future: Fut) -> Result<(), SpawnError> + where + Fut: Future + 'static, + { + self.spawn_local_obj(LocalFutureObj::new(Box::new(future))) + } + + /// Spawns a task that polls the given future to completion and returns a + /// future that resolves to the spawned future's output. + /// + /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if + /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that + /// resolves to the output of the spawned future. + /// + /// ``` + /// use futures::executor::LocalPool; + /// use futures::task::LocalSpawnExt; + /// + /// let mut executor = LocalPool::new(); + /// let spawner = executor.spawner(); + /// + /// let future = async { 1 }; + /// let join_handle_fut = spawner.spawn_local_with_handle(future).unwrap(); + /// assert_eq!(executor.run_until(join_handle_fut), 1); + /// ``` + #[cfg(feature = "channel")] + #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] + #[cfg(feature = "std")] + fn spawn_local_with_handle( + &self, + future: Fut, + ) -> Result, SpawnError> + where + Fut: Future + 'static, + { + let (future, handle) = future.remote_handle(); + self.spawn_local(future)?; + Ok(handle) + } +} diff --git a/utshell-0.5.0/vendor/futures-util/src/unfold_state.rs b/utshell-0.5.0/vendor/futures-util/src/unfold_state.rs new file mode 100644 index 00000000..0edc15e4 --- /dev/null +++ b/utshell-0.5.0/vendor/futures-util/src/unfold_state.rs @@ -0,0 +1,39 @@ +use core::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + /// UnfoldState used for stream and sink unfolds + #[project = UnfoldStateProj] + #[project_replace = UnfoldStateProjReplace] + #[derive(Debug)] + pub(crate) enum UnfoldState { + Value { + value: T, + }, + Future { + #[pin] + future: R, + }, + Empty, + } +} + +impl UnfoldState { + pub(crate) fn project_future(self: Pin<&mut Self>) -> Option> { + match self.project() { + UnfoldStateProj::Future { future } => Some(future), + _ => None, + } + } + + pub(crate) fn take_value(self: Pin<&mut Self>) -> Option { + match &*self { + UnfoldState::Value { .. } => match self.project_replace(UnfoldState::Empty) { + UnfoldStateProjReplace::Value { value } => Some(value), + _ => unreachable!(), + }, + _ => None, + } + } +} diff --git a/utshell-0.5.0/vendor/futures/.cargo-checksum.json b/utshell-0.5.0/vendor/futures/.cargo-checksum.json new file mode 100644 index 00000000..af496868 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"e3980e49276114211a72785f2fd7fae0fe08f0849c6aaf8973d8b5ab5c9f9e6c","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","README.md":"842d0b8a539ab13ba2b9863cd8fb27da4fc7e9def1aefeb21db5aa04269b1e34","src/lib.rs":"bb07f533ba89a36c0385b57de17d51bf23ccab9e13e00ec812a74f376df15930","tests/_require_features.rs":"5ad24019430b498addfc1fd853e955c7b646d78d0727a8ca29f586c9aab45cff","tests/async_await_macros.rs":"87863f5b73217d727a4789d69229ab5dd85252b8e76a1aca0220feb98a0922af","tests/auto_traits.rs":"bff7c984267a9ec98d5549c971623e7d658fc6f26fd78cfcb2630838b73e46d0","tests/bilock.rs":"bd0bf617352528f686b3fbb1847f4da9f6fe351e456e0bdce888bc738311fa83","tests/compat.rs":"1449926cc046d2ae9f86a263efd9353ca8e174ea546c083b360136c5a2aef1d1","tests/eager_drop.rs":"dc25d067207c06bbe094752d70bf161e206f00e162ffa3219583c8b4eb0816a1","tests/eventual.rs":"9050809e5196d0870a3ee2a268a5b4b398739b01617e1e317a673ac0660974cf","tests/future_abortable.rs":"4c81607472a85c5d87a5fe8a510a24cf1e8793fedf7f6cd6741ba1efd66615cd","tests/future_basic_combinators.rs":"4508c1250b85a4f749b7261bbd0ba728d3970e7ba277e84a006e76cf068fb54f","tests/future_fuse.rs":"bb63141f1486e755d0cdea1d93e302ad864a2186aa5287f909a0b3a922e82065","tests/future_inspect.rs":"9c03ceb770ce04fe9fd88a3489362642a0e34ae86a7b4958703e89e8b7a1ecf4","tests/future_join.rs":"f59d7b948df7019e52f902ca7aef17f89ad26582bd1902d520ba99f6f61ba508","tests/future_join_all.rs":"6adacfca4d33a769dbe72fd04c54b49580ecd7a9994a185cfe97dd7a2b55c298","tests/future_obj.rs":"a6aae88a194dc7d3bb961c20db78f180a01796cf7ea4bf106da98c40d89ed36d","tests/future_select_all.rs":"4cefc84d6b7ae2cf0007912cd0325fff6b926a4c26310e7b14a21868de61616f","tests/future_select_ok.rs":"1cabd03268641e1ac42b880344528bad73e3aeb6d6a8a141e652f339dd40184b","tests/future_shared.rs":"4f2cba1e74dacc4fc6b92eef04700df832533efe4fe6a392e3fd0f655b5b8450","tests/future_try_flatten_stream.rs":"aa4542b5d88f62522b736fac4567613081df45ad3eb54b0b659cdadc9409c4db","tests/future_try_join_all.rs":"cca2c5a3b42fe4bf9705301cd1450b30a3822736c5c09793eee06b28ce686a19","tests/io_buf_reader.rs":"1d60479224d5aa9378d4aed6246362b08a823ee7c9977f6a5e44fce7c40116be","tests/io_buf_writer.rs":"8f7a78ab2955d2beb69d0881321d4191235540aef6448e875e7f76a2ffc55b89","tests/io_cursor.rs":"cba5a7b968b9f816ac33316ce1e4da67cb320aa5a21332c0f9a45694fa445dd7","tests/io_line_writer.rs":"5b1140de776a721a677911496daa4e7956cc52cc08838d593ab300a93e0d7984","tests/io_lines.rs":"72a310c885591793ed724d0aa2158ac2c9d1af22de417044d96b714f78317586","tests/io_read.rs":"e0a8fa9b27e042f03c9fe14e8f0f329a67e24afad1ce40b906a1ab4d2abef23a","tests/io_read_exact.rs":"42049cd67589992dc09764ffb3836c475115b26dee441fd4cc7e847b2d166667","tests/io_read_line.rs":"f360c30c32fc8c73b371281e86c3f1095da7ef23b702debb30d335046dc77dac","tests/io_read_to_end.rs":"ea3e961e39a0b92930bded05e8ba26e4902461ab53818843d40fae8065b1a803","tests/io_read_to_string.rs":"824921601ac49f15b9a0b349c900f9cc9081cf2646e6a86f443166f841f1320e","tests/io_read_until.rs":"36d9a98149b2410894121ccba49e5134e3209826b2225acfc787016cea2bc92a","tests/io_window.rs":"0d18334b1eb35f5e93099e19c0cab22abe5971d8531176b81345fc89d07692a8","tests/io_write.rs":"701032ff3d5a6e6a3d8cb4e373d1c93e4708f2e5ee0a6742fa626f27b6094b4d","tests/lock_mutex.rs":"eb47121b842096353165b1444bf679a2df0103b181f811b40042f5c3f1d00c73","tests/macro_comma_support.rs":"627024ccadfe95194469d5bae2cc29b897b0118a664d7222408a2e234a10e939","tests/object_safety.rs":"9d047190387ed8334113687003c23407c80c858411f5ec7d5c505500f9639dfc","tests/oneshot.rs":"2109a8b3b524f4b36be9fb100f9b8c0d38bbd38d51716adcafdb65994b4a81d6","tests/ready_queue.rs":"6380025061025c27cb3b521df9520f169c7aa8e1802b881d539023bb4651744a","tests/recurse.rs":"b01b3d73b69ad90a767d297f974dac435817c39e12556fa6a3e6c725dd84f706","tests/sink.rs":"d9b2ddcbbb6af9e36d057db97dbba233547be645a7e4901b2842a4671f9f0212","tests/sink_fanout.rs":"67ab58422040308353955311f75222e55378e4cc34557c7b34140bd20c259132","tests/stream.rs":"6cb49d74e63a6264b2862d1020517251262010441a9f3e1eb0b3a83c908b705b","tests/stream_abortable.rs":"60052b83b5eeb2395b77bc213f35098d2d5880529f0d83884582a8bbff78b139","tests/stream_buffer_unordered.rs":"143ee19056b9ee9e480903cf4a1b00da7d4e528c5804569bf8c40869e6ac6eed","tests/stream_catch_unwind.rs":"5cdaaf70436c49d3a7107bdc5547ddb8757c3d2057635aded70e485d0cb9cbfc","tests/stream_futures_ordered.rs":"f9083bd8cfa86620c51abffc390564432022b5c8d15a7cba15dd5cb53ae99dd6","tests/stream_futures_unordered.rs":"e374b97bed3ceb3f584bfccb37128383e829680c8d679aa44bf93c878a4137e0","tests/stream_into_async_read.rs":"00ecb18289ebc8f46ea0cf43e0dce0631d7698bd1303a7bcd84d0addc9d8b645","tests/stream_peekable.rs":"c0addb0c510e13183ba3d6102633b75a9223651ae80a64542e913c712fe69a30","tests/stream_select_all.rs":"3a9045754939da5b30305e78f0571d79a03aaa77030c6ccf82225f076e9843c9","tests/stream_select_next_some.rs":"871edcee3ffc16c697251b29c9ba500aa4e3e503aa738748d7392e3462c82dce","tests/stream_split.rs":"074e9c9b51b6f7ea83d77347b5a0c8d414ca32b90445fec9b85f7f4cd2a6049f","tests/stream_try_stream.rs":"62ac8242ce3311930d352ad96573208d0df9ea5bc4e37d6edafabc7b3291ef88","tests/stream_unfold.rs":"7c6fbd10c782828793cbe1eb347ec776d99b185dad498e886f7161da76f76880","tests/task_arc_wake.rs":"5a49d074d1d5d9d5ec383dcd9a3868f636c1d7e34662e2573e467948db126206","tests/task_atomic_waker.rs":"8e85b4bc1360788646a52633dfe896d852773d6b482f81626cf534b97b7d937a","tests/test_macro.rs":"a46a946169c342c576936b60909165a50b94350501280ed9bba89d365af69287","tests/try_join.rs":"65f282f8351bd9a74642f2465c7aaf72ee7097002920989f156d60271652549e","tests_disabled/all.rs":"ddcd8fefb0d4a4a91a78328e7e652c35f93dc3669639d76fa0f56452b51abc23","tests_disabled/stream.rs":"8a615a472a35053d12b269d40fe244dfb3ba66fb78d217323aa2be177d5a111e"},"package":"645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/futures/Cargo.toml b/utshell-0.5.0/vendor/futures/Cargo.toml new file mode 100644 index 00000000..5272299b --- /dev/null +++ b/utshell-0.5.0/vendor/futures/Cargo.toml @@ -0,0 +1,147 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "futures" +version = "0.3.30" +description = """ +An implementation of futures and streams featuring zero allocations, +composability, and iterator-like interfaces. +""" +homepage = "https://rust-lang.github.io/futures-rs" +readme = "README.md" +keywords = [ + "futures", + "async", + "future", +] +categories = ["asynchronous"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/futures-rs" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", +] + +[package.metadata.playground] +features = [ + "std", + "async-await", + "compat", + "io-compat", + "executor", + "thread-pool", +] + +[dependencies.futures-channel] +version = "0.3.30" +features = ["sink"] +default-features = false + +[dependencies.futures-core] +version = "0.3.30" +default-features = false + +[dependencies.futures-executor] +version = "0.3.30" +optional = true +default-features = false + +[dependencies.futures-io] +version = "0.3.30" +default-features = false + +[dependencies.futures-sink] +version = "0.3.30" +default-features = false + +[dependencies.futures-task] +version = "0.3.30" +default-features = false + +[dependencies.futures-util] +version = "0.3.30" +features = ["sink"] +default-features = false + +[dev-dependencies.assert_matches] +version = "1.3.0" + +[dev-dependencies.pin-project] +version = "1.0.11" + +[dev-dependencies.pin-utils] +version = "0.1.0" + +[dev-dependencies.static_assertions] +version = "1" + +[dev-dependencies.tokio] +version = "0.1.11" + +[features] +alloc = [ + "futures-core/alloc", + "futures-task/alloc", + "futures-sink/alloc", + "futures-channel/alloc", + "futures-util/alloc", +] +async-await = [ + "futures-util/async-await", + "futures-util/async-await-macro", +] +bilock = ["futures-util/bilock"] +cfg-target-has-atomic = [] +compat = [ + "std", + "futures-util/compat", +] +default = [ + "std", + "async-await", + "executor", +] +executor = [ + "std", + "futures-executor/std", +] +io-compat = [ + "compat", + "futures-util/io-compat", +] +std = [ + "alloc", + "futures-core/std", + "futures-task/std", + "futures-io/std", + "futures-sink/std", + "futures-util/std", + "futures-util/io", + "futures-util/channel", +] +thread-pool = [ + "executor", + "futures-executor/thread-pool", +] +unstable = [ + "futures-core/unstable", + "futures-task/unstable", + "futures-channel/unstable", + "futures-io/unstable", + "futures-util/unstable", +] +write-all-vectored = ["futures-util/write-all-vectored"] diff --git a/utshell-0.5.0/vendor/futures/LICENSE-APACHE b/utshell-0.5.0/vendor/futures/LICENSE-APACHE new file mode 100644 index 00000000..9eb0b097 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/futures/LICENSE-MIT b/utshell-0.5.0/vendor/futures/LICENSE-MIT new file mode 100644 index 00000000..8ad082ec --- /dev/null +++ b/utshell-0.5.0/vendor/futures/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2016 Alex Crichton +Copyright (c) 2017 The Tokio Authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/futures/README.md b/utshell-0.5.0/vendor/futures/README.md new file mode 100644 index 00000000..355d6078 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/README.md @@ -0,0 +1,61 @@ +

+ futures-rs +

+ +

+ Zero-cost asynchronous programming in Rust +

+ +

+ + Build Status + + + + crates.io + +

+ +

+ + Documentation + | + Website + +

+ +`futures-rs` is a library providing the foundations for asynchronous programming in Rust. +It includes key trait definitions like `Stream`, as well as utilities like `join!`, +`select!`, and various futures combinator methods which enable expressive asynchronous +control flow. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +futures = "0.3" +``` + +The current `futures` requires Rust 1.56 or later. + +### Feature `std` + +Futures-rs works without the standard library, such as in bare metal environments. +However, it has a significantly reduced API surface. To use futures-rs in +a `#[no_std]` environment, use: + +```toml +[dependencies] +futures = { version = "0.3", default-features = false } +``` + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/futures/src/lib.rs b/utshell-0.5.0/vendor/futures/src/lib.rs new file mode 100644 index 00000000..b972f517 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/src/lib.rs @@ -0,0 +1,260 @@ +//! Abstractions for asynchronous programming. +//! +//! This crate provides a number of core abstractions for writing asynchronous +//! code: +//! +//! - [Futures](crate::future) are single eventual values produced by +//! asynchronous computations. Some programming languages (e.g. JavaScript) +//! call this concept "promise". +//! - [Streams](crate::stream) represent a series of values +//! produced asynchronously. +//! - [Sinks](crate::sink) provide support for asynchronous writing of +//! data. +//! - [Executors](crate::executor) are responsible for running asynchronous +//! tasks. +//! +//! The crate also contains abstractions for [asynchronous I/O](crate::io) and +//! [cross-task communication](crate::channel). +//! +//! Underlying all of this is the *task system*, which is a form of lightweight +//! threading. Large asynchronous computations are built up using futures, +//! streams and sinks, and then spawned as independent tasks that are run to +//! completion, but *do not block* the thread running them. +//! +//! The following example describes how the task system context is built and used +//! within macros and keywords such as async and await!. +//! +//! ```rust +//! # use futures::channel::mpsc; +//! # use futures::executor; ///standard executors to provide a context for futures and streams +//! # use futures::executor::ThreadPool; +//! # use futures::StreamExt; +//! # +//! fn main() { +//! # { +//! let pool = ThreadPool::new().expect("Failed to build pool"); +//! let (tx, rx) = mpsc::unbounded::(); +//! +//! // Create a future by an async block, where async is responsible for an +//! // implementation of Future. At this point no executor has been provided +//! // to this future, so it will not be running. +//! let fut_values = async { +//! // Create another async block, again where the Future implementation +//! // is generated by async. Since this is inside of a parent async block, +//! // it will be provided with the executor of the parent block when the parent +//! // block is executed. +//! // +//! // This executor chaining is done by Future::poll whose second argument +//! // is a std::task::Context. This represents our executor, and the Future +//! // implemented by this async block can be polled using the parent async +//! // block's executor. +//! let fut_tx_result = async move { +//! (0..100).for_each(|v| { +//! tx.unbounded_send(v).expect("Failed to send"); +//! }) +//! }; +//! +//! // Use the provided thread pool to spawn the generated future +//! // responsible for transmission +//! pool.spawn_ok(fut_tx_result); +//! +//! let fut_values = rx +//! .map(|v| v * 2) +//! .collect(); +//! +//! // Use the executor provided to this async block to wait for the +//! // future to complete. +//! fut_values.await +//! }; +//! +//! // Actually execute the above future, which will invoke Future::poll and +//! // subsequently chain appropriate Future::poll and methods needing executors +//! // to drive all futures. Eventually fut_values will be driven to completion. +//! let values: Vec = executor::block_on(fut_values); +//! +//! println!("Values={:?}", values); +//! # } +//! # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +//! } +//! ``` +//! +//! The majority of examples and code snippets in this crate assume that they are +//! inside an async block as written above. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + single_use_lifetimes, + unreachable_pub +)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] +#![cfg_attr(docsrs, feature(doc_cfg))] + +#[cfg(all(feature = "bilock", not(feature = "unstable")))] +compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); + +#[doc(no_inline)] +pub use futures_core::future::{Future, TryFuture}; +#[doc(no_inline)] +pub use futures_util::future::{FutureExt, TryFutureExt}; + +#[doc(no_inline)] +pub use futures_core::stream::{Stream, TryStream}; +#[doc(no_inline)] +pub use futures_util::stream::{StreamExt, TryStreamExt}; + +#[doc(no_inline)] +pub use futures_sink::Sink; +#[doc(no_inline)] +pub use futures_util::sink::SinkExt; + +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; + +// Macro reexports +pub use futures_core::ready; // Readiness propagation +pub use futures_util::pin_mut; +#[cfg(feature = "std")] +#[cfg(feature = "async-await")] +pub use futures_util::select; +#[cfg(feature = "async-await")] +pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await + +// Module reexports +#[doc(inline)] +pub use futures_util::{future, never, sink, stream, task}; + +#[cfg(feature = "std")] +#[cfg(feature = "async-await")] +pub use futures_util::stream_select; + +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use futures_channel as channel; +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use futures_util::lock; + +#[cfg(feature = "std")] +#[doc(inline)] +pub use futures_util::io; + +#[cfg(feature = "executor")] +#[cfg_attr(docsrs, doc(cfg(feature = "executor")))] +pub mod executor { + //! Built-in executors and related tools. + //! + //! All asynchronous computation occurs within an executor, which is + //! capable of spawning futures as tasks. This module provides several + //! built-in executors, as well as tools for building your own. + //! + //! + //! This module is only available when the `executor` feature of this + //! library is activated. + //! + //! # Using a thread pool (M:N task scheduling) + //! + //! Most of the time tasks should be executed on a [thread pool](ThreadPool). + //! A small set of worker threads can handle a very large set of spawned tasks + //! (which are much lighter weight than threads). Tasks spawned onto the pool + //! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on + //! the created threads. + //! + //! # Spawning additional tasks + //! + //! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method + //! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used + //! instead. + //! + //! # Single-threaded execution + //! + //! In addition to thread pools, it's possible to run a task (and the tasks + //! it spawns) entirely within a single thread via the [`LocalPool`] executor. + //! Aside from cutting down on synchronization costs, this executor also makes + //! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The + //! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively + //! little work between I/O operations. + //! + //! There is also a convenience function [`block_on`] for simply running a + //! future to completion on the current thread. + //! + //! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj + //! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj + + pub use futures_executor::{ + block_on, block_on_stream, enter, BlockingStream, Enter, EnterError, LocalPool, + LocalSpawner, + }; + + #[cfg(feature = "thread-pool")] + #[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] + pub use futures_executor::{ThreadPool, ThreadPoolBuilder}; +} + +#[cfg(feature = "compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "compat")))] +pub mod compat { + //! Interop between `futures` 0.1 and 0.3. + //! + //! This module is only available when the `compat` feature of this + //! library is activated. + + pub use futures_util::compat::{ + Compat, Compat01As03, Compat01As03Sink, CompatSink, Executor01As03, Executor01CompatExt, + Executor01Future, Future01CompatExt, Sink01CompatExt, Stream01CompatExt, + }; + + #[cfg(feature = "io-compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] + pub use futures_util::compat::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; +} + +pub mod prelude { + //! A "prelude" for crates using the `futures` crate. + //! + //! This prelude is similar to the standard library's prelude in that you'll + //! almost always want to import its entire contents, but unlike the + //! standard library's prelude you'll have to do so manually: + //! + //! ``` + //! # #[allow(unused_imports)] + //! use futures::prelude::*; + //! ``` + //! + //! The prelude may grow over time as additional items see ubiquitous use. + + pub use crate::future::{self, Future, TryFuture}; + pub use crate::sink::{self, Sink}; + pub use crate::stream::{self, Stream, TryStream}; + + #[doc(no_inline)] + #[allow(unreachable_pub)] + pub use crate::future::{FutureExt as _, TryFutureExt as _}; + #[doc(no_inline)] + pub use crate::sink::SinkExt as _; + #[doc(no_inline)] + #[allow(unreachable_pub)] + pub use crate::stream::{StreamExt as _, TryStreamExt as _}; + + #[cfg(feature = "std")] + pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; + + #[cfg(feature = "std")] + #[doc(no_inline)] + #[allow(unreachable_pub)] + pub use crate::io::{ + AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, + }; +} diff --git a/utshell-0.5.0/vendor/futures/tests/_require_features.rs b/utshell-0.5.0/vendor/futures/tests/_require_features.rs new file mode 100644 index 00000000..8046cc99 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/_require_features.rs @@ -0,0 +1,13 @@ +#[cfg(not(all( + feature = "std", + feature = "alloc", + feature = "async-await", + feature = "compat", + feature = "io-compat", + feature = "executor", + feature = "thread-pool", +)))] +compile_error!( + "`futures` tests must have all stable features activated: \ + use `--all-features` or `--features default,thread-pool,io-compat`" +); diff --git a/utshell-0.5.0/vendor/futures/tests/async_await_macros.rs b/utshell-0.5.0/vendor/futures/tests/async_await_macros.rs new file mode 100644 index 00000000..82a617f2 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/async_await_macros.rs @@ -0,0 +1,393 @@ +use futures::channel::{mpsc, oneshot}; +use futures::executor::block_on; +use futures::future::{self, poll_fn, FutureExt}; +use futures::sink::SinkExt; +use futures::stream::StreamExt; +use futures::task::{Context, Poll}; +use futures::{ + join, pending, pin_mut, poll, select, select_biased, stream, stream_select, try_join, +}; +use std::mem; + +#[test] +fn poll_and_pending() { + let pending_once = async { pending!() }; + block_on(async { + pin_mut!(pending_once); + assert_eq!(Poll::Pending, poll!(&mut pending_once)); + assert_eq!(Poll::Ready(()), poll!(&mut pending_once)); + }); +} + +#[test] +fn join() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = oneshot::channel::(); + + let fut = async { + let res = join!(rx1, rx2); + assert_eq!((Ok(1), Ok(2)), res); + }; + + block_on(async { + pin_mut!(fut); + assert_eq!(Poll::Pending, poll!(&mut fut)); + tx1.send(1).unwrap(); + assert_eq!(Poll::Pending, poll!(&mut fut)); + tx2.send(2).unwrap(); + assert_eq!(Poll::Ready(()), poll!(&mut fut)); + }); +} + +#[test] +fn select() { + let (tx1, rx1) = oneshot::channel::(); + let (_tx2, rx2) = oneshot::channel::(); + tx1.send(1).unwrap(); + let mut ran = false; + block_on(async { + select! { + res = rx1.fuse() => { + assert_eq!(Ok(1), res); + ran = true; + }, + _ = rx2.fuse() => unreachable!(), + } + }); + assert!(ran); +} + +#[test] +fn select_biased() { + let (tx1, rx1) = oneshot::channel::(); + let (_tx2, rx2) = oneshot::channel::(); + tx1.send(1).unwrap(); + let mut ran = false; + block_on(async { + select_biased! { + res = rx1.fuse() => { + assert_eq!(Ok(1), res); + ran = true; + }, + _ = rx2.fuse() => unreachable!(), + } + }); + assert!(ran); +} + +#[test] +fn select_streams() { + let (mut tx1, rx1) = mpsc::channel::(1); + let (mut tx2, rx2) = mpsc::channel::(1); + let mut rx1 = rx1.fuse(); + let mut rx2 = rx2.fuse(); + let mut ran = false; + let mut total = 0; + block_on(async { + let mut tx1_opt; + let mut tx2_opt; + select! { + _ = rx1.next() => panic!(), + _ = rx2.next() => panic!(), + default => { + tx1.send(2).await.unwrap(); + tx2.send(3).await.unwrap(); + tx1_opt = Some(tx1); + tx2_opt = Some(tx2); + } + complete => panic!(), + } + loop { + select! { + // runs first and again after default + x = rx1.next() => if let Some(x) = x { total += x; }, + // runs second and again after default + x = rx2.next() => if let Some(x) = x { total += x; }, + // runs third + default => { + assert_eq!(total, 5); + ran = true; + drop(tx1_opt.take().unwrap()); + drop(tx2_opt.take().unwrap()); + }, + // runs last + complete => break, + }; + } + }); + assert!(ran); +} + +#[test] +fn select_can_move_uncompleted_futures() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = oneshot::channel::(); + tx1.send(1).unwrap(); + tx2.send(2).unwrap(); + let mut ran = false; + let mut rx1 = rx1.fuse(); + let mut rx2 = rx2.fuse(); + block_on(async { + select! { + res = rx1 => { + assert_eq!(Ok(1), res); + assert_eq!(Ok(2), rx2.await); + ran = true; + }, + res = rx2 => { + assert_eq!(Ok(2), res); + assert_eq!(Ok(1), rx1.await); + ran = true; + }, + } + }); + assert!(ran); +} + +#[test] +fn select_nested() { + let mut outer_fut = future::ready(1); + let mut inner_fut = future::ready(2); + let res = block_on(async { + select! { + x = outer_fut => { + select! { + y = inner_fut => x + y, + } + } + } + }); + assert_eq!(res, 3); +} + +#[cfg_attr(not(target_pointer_width = "64"), ignore)] +#[test] +fn select_size() { + let fut = async { + let mut ready = future::ready(0i32); + select! { + _ = ready => {}, + } + }; + assert_eq!(mem::size_of_val(&fut), 24); + + let fut = async { + let mut ready1 = future::ready(0i32); + let mut ready2 = future::ready(0i32); + select! { + _ = ready1 => {}, + _ = ready2 => {}, + } + }; + assert_eq!(mem::size_of_val(&fut), 40); +} + +#[test] +fn select_on_non_unpin_expressions() { + // The returned Future is !Unpin + let make_non_unpin_fut = || async { 5 }; + + let res = block_on(async { + let select_res; + select! { + value_1 = make_non_unpin_fut().fuse() => select_res = value_1, + value_2 = make_non_unpin_fut().fuse() => select_res = value_2, + }; + select_res + }); + assert_eq!(res, 5); +} + +#[test] +fn select_on_non_unpin_expressions_with_default() { + // The returned Future is !Unpin + let make_non_unpin_fut = || async { 5 }; + + let res = block_on(async { + let select_res; + select! { + value_1 = make_non_unpin_fut().fuse() => select_res = value_1, + value_2 = make_non_unpin_fut().fuse() => select_res = value_2, + default => select_res = 7, + }; + select_res + }); + assert_eq!(res, 5); +} + +#[cfg_attr(not(target_pointer_width = "64"), ignore)] +#[test] +fn select_on_non_unpin_size() { + // The returned Future is !Unpin + let make_non_unpin_fut = || async { 5 }; + + let fut = async { + let select_res; + select! { + value_1 = make_non_unpin_fut().fuse() => select_res = value_1, + value_2 = make_non_unpin_fut().fuse() => select_res = value_2, + }; + select_res + }; + + assert_eq!(32, mem::size_of_val(&fut)); +} + +#[test] +fn select_can_be_used_as_expression() { + block_on(async { + let res = select! { + x = future::ready(7) => x, + y = future::ready(3) => y + 1, + }; + assert!(res == 7 || res == 4); + }); +} + +#[test] +fn select_with_default_can_be_used_as_expression() { + fn poll_always_pending(_cx: &mut Context<'_>) -> Poll { + Poll::Pending + } + + block_on(async { + let res = select! { + x = poll_fn(poll_always_pending::).fuse() => x, + y = poll_fn(poll_always_pending::).fuse() => y + 1, + default => 99, + }; + assert_eq!(res, 99); + }); +} + +#[test] +fn select_with_complete_can_be_used_as_expression() { + block_on(async { + let res = select! { + x = future::pending::() => x, + y = future::pending::() => y + 1, + default => 99, + complete => 237, + }; + assert_eq!(res, 237); + }); +} + +#[test] +#[allow(unused_assignments)] +fn select_on_mutable_borrowing_future_with_same_borrow_in_block() { + async fn require_mutable(_: &mut i32) {} + async fn async_noop() {} + + block_on(async { + let mut value = 234; + select! { + _ = require_mutable(&mut value).fuse() => { }, + _ = async_noop().fuse() => { + value += 5; + }, + } + }); +} + +#[test] +#[allow(unused_assignments)] +fn select_on_mutable_borrowing_future_with_same_borrow_in_block_and_default() { + async fn require_mutable(_: &mut i32) {} + async fn async_noop() {} + + block_on(async { + let mut value = 234; + select! { + _ = require_mutable(&mut value).fuse() => { }, + _ = async_noop().fuse() => { + value += 5; + }, + default => { + value += 27; + }, + } + }); +} + +#[test] +#[allow(unused_assignments)] +fn stream_select() { + // stream_select! macro + block_on(async { + let endless_ints = |i| stream::iter(vec![i].into_iter().cycle()); + + let mut endless_ones = stream_select!(endless_ints(1i32), stream::pending()); + assert_eq!(endless_ones.next().await, Some(1)); + assert_eq!(endless_ones.next().await, Some(1)); + + let mut finite_list = + stream_select!(stream::iter(vec![1].into_iter()), stream::iter(vec![1].into_iter())); + assert_eq!(finite_list.next().await, Some(1)); + assert_eq!(finite_list.next().await, Some(1)); + assert_eq!(finite_list.next().await, None); + + let endless_mixed = stream_select!(endless_ints(1i32), endless_ints(2), endless_ints(3)); + // Take 1000, and assert a somewhat even distribution of values. + // The fairness is randomized, but over 1000 samples we should be pretty close to even. + // This test may be a bit flaky. Feel free to adjust the margins as you see fit. + let mut count = 0; + let results = endless_mixed + .take_while(move |_| { + count += 1; + let ret = count < 1000; + async move { ret } + }) + .collect::>() + .await; + assert!(results.iter().filter(|x| **x == 1).count() >= 299); + assert!(results.iter().filter(|x| **x == 2).count() >= 299); + assert!(results.iter().filter(|x| **x == 3).count() >= 299); + }); +} + +#[cfg_attr(not(target_pointer_width = "64"), ignore)] +#[test] +fn join_size() { + let fut = async { + let ready = future::ready(0i32); + join!(ready) + }; + assert_eq!(mem::size_of_val(&fut), 24); + + let fut = async { + let ready1 = future::ready(0i32); + let ready2 = future::ready(0i32); + join!(ready1, ready2) + }; + assert_eq!(mem::size_of_val(&fut), 40); +} + +#[cfg_attr(not(target_pointer_width = "64"), ignore)] +#[test] +fn try_join_size() { + let fut = async { + let ready = future::ready(Ok::(0)); + try_join!(ready) + }; + assert_eq!(mem::size_of_val(&fut), 24); + + let fut = async { + let ready1 = future::ready(Ok::(0)); + let ready2 = future::ready(Ok::(0)); + try_join!(ready1, ready2) + }; + assert_eq!(mem::size_of_val(&fut), 48); +} + +#[allow(clippy::let_underscore_future)] +#[test] +fn join_doesnt_require_unpin() { + let _ = async { join!(async {}, async {}) }; +} + +#[allow(clippy::let_underscore_future)] +#[test] +fn try_join_doesnt_require_unpin() { + let _ = async { try_join!(async { Ok::<(), ()>(()) }, async { Ok::<(), ()>(()) },) }; +} diff --git a/utshell-0.5.0/vendor/futures/tests/auto_traits.rs b/utshell-0.5.0/vendor/futures/tests/auto_traits.rs new file mode 100644 index 00000000..004fda1e --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/auto_traits.rs @@ -0,0 +1,1898 @@ +#![cfg(feature = "compat")] + +//! Assert Send/Sync/Unpin for all public types. + +use futures::{ + future::Future, + sink::Sink, + stream::Stream, + task::{Context, Poll}, +}; +use static_assertions::{assert_impl_all as assert_impl, assert_not_impl_all as assert_not_impl}; +use std::marker::PhantomPinned; +use std::{marker::PhantomData, pin::Pin}; + +pub type LocalFuture = Pin>>; +pub type LocalTryFuture = LocalFuture>; +pub type SendFuture = Pin + Send>>; +pub type SendTryFuture = SendFuture>; +pub type SyncFuture = Pin + Sync>>; +pub type SyncTryFuture = SyncFuture>; +pub type SendSyncFuture = Pin + Send + Sync>>; +pub type SendSyncTryFuture = SendSyncFuture>; +pub type UnpinFuture = LocalFuture; +pub type UnpinTryFuture = UnpinFuture>; +pub struct PinnedFuture(PhantomPinned, PhantomData); +impl Future for PinnedFuture { + type Output = T; + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + unimplemented!() + } +} +pub type PinnedTryFuture = PinnedFuture>; + +pub type LocalStream = Pin>>; +pub type LocalTryStream = LocalStream>; +pub type SendStream = Pin + Send>>; +pub type SendTryStream = SendStream>; +pub type SyncStream = Pin + Sync>>; +pub type SyncTryStream = SyncStream>; +pub type SendSyncStream = Pin + Send + Sync>>; +pub type SendSyncTryStream = SendSyncStream>; +pub type UnpinStream = LocalStream; +pub type UnpinTryStream = UnpinStream>; +pub struct PinnedStream(PhantomPinned, PhantomData); +impl Stream for PinnedStream { + type Item = T; + fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + unimplemented!() + } +} +pub type PinnedTryStream = PinnedStream>; + +pub type LocalSink = Pin>>; +pub type SendSink = Pin + Send>>; +pub type SyncSink = Pin + Sync>>; +pub type UnpinSink = LocalSink; +pub struct PinnedSink(PhantomPinned, PhantomData<(T, E)>); +impl Sink for PinnedSink { + type Error = E; + fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + unimplemented!() + } + fn start_send(self: Pin<&mut Self>, _: T) -> Result<(), Self::Error> { + unimplemented!() + } + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + unimplemented!() + } + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + unimplemented!() + } +} + +/// Assert Send/Sync/Unpin for all public types in `futures::channel`. +pub mod channel { + use super::*; + use futures::channel::*; + + assert_impl!(mpsc::Receiver<()>: Send); + assert_not_impl!(mpsc::Receiver<*const ()>: Send); + assert_impl!(mpsc::Receiver<()>: Sync); + assert_not_impl!(mpsc::Receiver<*const ()>: Sync); + assert_impl!(mpsc::Receiver: Unpin); + + assert_impl!(mpsc::SendError: Send); + assert_impl!(mpsc::SendError: Sync); + assert_impl!(mpsc::SendError: Unpin); + + assert_impl!(mpsc::Sender<()>: Send); + assert_not_impl!(mpsc::Sender<*const ()>: Send); + assert_impl!(mpsc::Sender<()>: Sync); + assert_not_impl!(mpsc::Sender<*const ()>: Sync); + assert_impl!(mpsc::Sender: Unpin); + + assert_impl!(mpsc::TryRecvError: Send); + assert_impl!(mpsc::TryRecvError: Sync); + assert_impl!(mpsc::TryRecvError: Unpin); + + assert_impl!(mpsc::TrySendError<()>: Send); + assert_not_impl!(mpsc::TrySendError<*const ()>: Send); + assert_impl!(mpsc::TrySendError<()>: Sync); + assert_not_impl!(mpsc::TrySendError<*const ()>: Sync); + assert_impl!(mpsc::TrySendError<()>: Unpin); + assert_not_impl!(mpsc::TrySendError: Unpin); + + assert_impl!(mpsc::UnboundedReceiver<()>: Send); + assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Send); + assert_impl!(mpsc::UnboundedReceiver<()>: Sync); + assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Sync); + assert_impl!(mpsc::UnboundedReceiver: Unpin); + + assert_impl!(mpsc::UnboundedReceiver<()>: Send); + assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Send); + assert_impl!(mpsc::UnboundedReceiver<()>: Sync); + assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Sync); + assert_impl!(mpsc::UnboundedReceiver: Unpin); + + assert_impl!(oneshot::Canceled: Send); + assert_impl!(oneshot::Canceled: Sync); + assert_impl!(oneshot::Canceled: Unpin); + + assert_impl!(oneshot::Cancellation<()>: Send); + assert_not_impl!(oneshot::Cancellation<*const ()>: Send); + assert_impl!(oneshot::Cancellation<()>: Sync); + assert_not_impl!(oneshot::Cancellation<*const ()>: Sync); + assert_impl!(oneshot::Cancellation: Unpin); + + assert_impl!(oneshot::Receiver<()>: Send); + assert_not_impl!(oneshot::Receiver<*const ()>: Send); + assert_impl!(oneshot::Receiver<()>: Sync); + assert_not_impl!(oneshot::Receiver<*const ()>: Sync); + assert_impl!(oneshot::Receiver: Unpin); + + assert_impl!(oneshot::Sender<()>: Send); + assert_not_impl!(oneshot::Sender<*const ()>: Send); + assert_impl!(oneshot::Sender<()>: Sync); + assert_not_impl!(oneshot::Sender<*const ()>: Sync); + assert_impl!(oneshot::Sender: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::compat`. +pub mod compat { + use super::*; + use futures::compat::*; + + assert_impl!(Compat<()>: Send); + assert_not_impl!(Compat<*const ()>: Send); + assert_impl!(Compat<()>: Sync); + assert_not_impl!(Compat<*const ()>: Sync); + assert_impl!(Compat<()>: Unpin); + assert_not_impl!(Compat: Unpin); + + assert_impl!(Compat01As03<()>: Send); + assert_not_impl!(Compat01As03<*const ()>: Send); + assert_not_impl!(Compat01As03<()>: Sync); + assert_impl!(Compat01As03: Unpin); + + assert_impl!(Compat01As03Sink<(), ()>: Send); + assert_not_impl!(Compat01As03Sink<(), *const ()>: Send); + assert_not_impl!(Compat01As03Sink<*const (), ()>: Send); + assert_not_impl!(Compat01As03Sink<(), ()>: Sync); + assert_impl!(Compat01As03Sink: Unpin); + + assert_impl!(CompatSink<(), *const ()>: Send); + assert_not_impl!(CompatSink<*const (), ()>: Send); + assert_impl!(CompatSink<(), *const ()>: Sync); + assert_not_impl!(CompatSink<*const (), ()>: Sync); + assert_impl!(CompatSink<(), PhantomPinned>: Unpin); + assert_not_impl!(CompatSink: Unpin); + + assert_impl!(Executor01As03<()>: Send); + assert_not_impl!(Executor01As03<*const ()>: Send); + assert_impl!(Executor01As03<()>: Sync); + assert_not_impl!(Executor01As03<*const ()>: Sync); + assert_impl!(Executor01As03<()>: Unpin); + assert_not_impl!(Executor01As03: Unpin); + + assert_impl!(Executor01Future: Send); + assert_not_impl!(Executor01Future: Sync); + assert_impl!(Executor01Future: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::executor`. +pub mod executor { + use super::*; + use futures::executor::*; + + assert_impl!(BlockingStream: Send); + assert_not_impl!(BlockingStream: Send); + assert_impl!(BlockingStream: Sync); + assert_not_impl!(BlockingStream: Sync); + assert_impl!(BlockingStream: Unpin); + // BlockingStream requires `S: Unpin` + // assert_not_impl!(BlockingStream: Unpin); + + assert_impl!(Enter: Send); + assert_impl!(Enter: Sync); + assert_impl!(Enter: Unpin); + + assert_impl!(EnterError: Send); + assert_impl!(EnterError: Sync); + assert_impl!(EnterError: Unpin); + + assert_not_impl!(LocalPool: Send); + assert_not_impl!(LocalPool: Sync); + assert_impl!(LocalPool: Unpin); + + assert_not_impl!(LocalSpawner: Send); + assert_not_impl!(LocalSpawner: Sync); + assert_impl!(LocalSpawner: Unpin); + + assert_impl!(ThreadPool: Send); + assert_impl!(ThreadPool: Sync); + assert_impl!(ThreadPool: Unpin); + + assert_impl!(ThreadPoolBuilder: Send); + assert_impl!(ThreadPoolBuilder: Sync); + assert_impl!(ThreadPoolBuilder: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::future`. +pub mod future { + use super::*; + use futures::future::*; + + assert_impl!(AbortHandle: Send); + assert_impl!(AbortHandle: Sync); + assert_impl!(AbortHandle: Unpin); + + assert_impl!(AbortRegistration: Send); + assert_impl!(AbortRegistration: Sync); + assert_impl!(AbortRegistration: Unpin); + + assert_impl!(Abortable: Send); + assert_not_impl!(Abortable: Send); + assert_impl!(Abortable: Sync); + assert_not_impl!(Abortable: Sync); + assert_impl!(Abortable: Unpin); + assert_not_impl!(Abortable: Unpin); + + assert_impl!(Aborted: Send); + assert_impl!(Aborted: Sync); + assert_impl!(Aborted: Unpin); + + assert_impl!(AndThen: Send); + assert_not_impl!(AndThen: Send); + assert_not_impl!(AndThen: Send); + assert_not_impl!(AndThen: Send); + assert_impl!(AndThen: Sync); + assert_not_impl!(AndThen: Sync); + assert_not_impl!(AndThen: Sync); + assert_not_impl!(AndThen: Sync); + assert_impl!(AndThen: Unpin); + assert_not_impl!(AndThen: Unpin); + assert_not_impl!(AndThen: Unpin); + + assert_impl!(CatchUnwind: Send); + assert_not_impl!(CatchUnwind: Send); + assert_impl!(CatchUnwind: Sync); + assert_not_impl!(CatchUnwind: Sync); + assert_impl!(CatchUnwind: Unpin); + assert_not_impl!(CatchUnwind: Unpin); + + assert_impl!(ErrInto: Send); + assert_not_impl!(ErrInto: Send); + assert_impl!(ErrInto: Sync); + assert_not_impl!(ErrInto: Sync); + assert_impl!(ErrInto: Unpin); + assert_not_impl!(ErrInto: Unpin); + + assert_impl!(Flatten>: Send); + assert_not_impl!(Flatten: Send); + assert_not_impl!(Flatten: Send); + assert_impl!(Flatten>: Sync); + assert_not_impl!(Flatten: Sync); + assert_not_impl!(Flatten: Sync); + assert_impl!(Flatten>: Unpin); + assert_not_impl!(Flatten: Unpin); + assert_not_impl!(Flatten: Unpin); + + assert_impl!(FlattenSink: Send); + assert_not_impl!(FlattenSink: Send); + assert_not_impl!(FlattenSink: Send); + assert_impl!(FlattenSink: Sync); + assert_not_impl!(FlattenSink: Sync); + assert_not_impl!(FlattenSink: Sync); + assert_impl!(FlattenSink: Unpin); + assert_not_impl!(FlattenSink: Unpin); + assert_not_impl!(FlattenSink: Unpin); + + assert_impl!(FlattenStream>: Send); + assert_not_impl!(FlattenStream: Send); + assert_not_impl!(FlattenStream: Send); + assert_impl!(FlattenStream>: Sync); + assert_not_impl!(FlattenStream: Sync); + assert_not_impl!(FlattenStream: Sync); + assert_impl!(FlattenStream>: Unpin); + assert_not_impl!(FlattenStream: Unpin); + assert_not_impl!(FlattenStream: Unpin); + + assert_impl!(Fuse: Send); + assert_not_impl!(Fuse: Send); + assert_impl!(Fuse: Sync); + assert_not_impl!(Fuse: Sync); + assert_impl!(Fuse: Unpin); + assert_not_impl!(Fuse: Unpin); + + assert_impl!(FutureObj<*const ()>: Send); + assert_not_impl!(FutureObj<()>: Sync); + assert_impl!(FutureObj: Unpin); + + assert_impl!(Inspect: Send); + assert_not_impl!(Inspect: Send); + assert_not_impl!(Inspect: Send); + assert_impl!(Inspect: Sync); + assert_not_impl!(Inspect: Sync); + assert_not_impl!(Inspect: Sync); + assert_impl!(Inspect: Unpin); + assert_not_impl!(Inspect: Unpin); + + assert_impl!(InspectErr: Send); + assert_not_impl!(InspectErr: Send); + assert_not_impl!(InspectErr: Send); + assert_impl!(InspectErr: Sync); + assert_not_impl!(InspectErr: Sync); + assert_not_impl!(InspectErr: Sync); + assert_impl!(InspectErr: Unpin); + assert_not_impl!(InspectErr: Unpin); + + assert_impl!(InspectOk: Send); + assert_not_impl!(InspectOk: Send); + assert_not_impl!(InspectOk: Send); + assert_impl!(InspectOk: Sync); + assert_not_impl!(InspectOk: Sync); + assert_not_impl!(InspectOk: Sync); + assert_impl!(InspectOk: Unpin); + assert_not_impl!(InspectOk: Unpin); + + assert_impl!(IntoFuture: Send); + assert_not_impl!(IntoFuture: Send); + assert_impl!(IntoFuture: Sync); + assert_not_impl!(IntoFuture: Sync); + assert_impl!(IntoFuture: Unpin); + assert_not_impl!(IntoFuture: Unpin); + + assert_impl!(IntoStream: Send); + assert_not_impl!(IntoStream: Send); + assert_impl!(IntoStream: Sync); + assert_not_impl!(IntoStream: Sync); + assert_impl!(IntoStream: Unpin); + assert_not_impl!(IntoStream: Unpin); + + assert_impl!(Join, SendFuture<()>>: Send); + assert_not_impl!(Join, SendFuture>: Send); + assert_not_impl!(Join>: Send); + assert_not_impl!(Join: Send); + assert_not_impl!(Join: Send); + assert_impl!(Join, SyncFuture<()>>: Sync); + assert_not_impl!(Join, SyncFuture>: Sync); + assert_not_impl!(Join>: Sync); + assert_not_impl!(Join: Sync); + assert_not_impl!(Join: Sync); + assert_impl!(Join: Unpin); + assert_not_impl!(Join: Unpin); + assert_not_impl!(Join: Unpin); + + // Join3, Join4, Join5 are the same as Join + + assert_impl!(JoinAll>: Send); + assert_not_impl!(JoinAll: Send); + assert_not_impl!(JoinAll: Send); + assert_impl!(JoinAll>: Sync); + assert_not_impl!(JoinAll>: Sync); + assert_not_impl!(JoinAll>: Sync); + assert_not_impl!(JoinAll: Sync); + assert_impl!(JoinAll: Unpin); + + assert_impl!(Lazy<()>: Send); + assert_not_impl!(Lazy<*const ()>: Send); + assert_impl!(Lazy<()>: Sync); + assert_not_impl!(Lazy<*const ()>: Sync); + assert_impl!(Lazy: Unpin); + + assert_not_impl!(LocalFutureObj<()>: Send); + assert_not_impl!(LocalFutureObj<()>: Sync); + assert_impl!(LocalFutureObj: Unpin); + + assert_impl!(Map: Send); + assert_not_impl!(Map: Send); + assert_not_impl!(Map: Send); + assert_impl!(Map: Sync); + assert_not_impl!(Map: Sync); + assert_not_impl!(Map: Sync); + assert_impl!(Map: Unpin); + assert_not_impl!(Map: Unpin); + + assert_impl!(MapErr: Send); + assert_not_impl!(MapErr: Send); + assert_not_impl!(MapErr: Send); + assert_impl!(MapErr: Sync); + assert_not_impl!(MapErr: Sync); + assert_not_impl!(MapErr: Sync); + assert_impl!(MapErr: Unpin); + assert_not_impl!(MapErr: Unpin); + + assert_impl!(MapInto: Send); + assert_not_impl!(MapInto: Send); + assert_impl!(MapInto: Sync); + assert_not_impl!(MapInto: Sync); + assert_impl!(MapInto: Unpin); + assert_not_impl!(MapInto: Unpin); + + assert_impl!(MapOk: Send); + assert_not_impl!(MapOk: Send); + assert_not_impl!(MapOk: Send); + assert_impl!(MapOk: Sync); + assert_not_impl!(MapOk: Sync); + assert_not_impl!(MapOk: Sync); + assert_impl!(MapOk: Unpin); + assert_not_impl!(MapOk: Unpin); + + assert_impl!(MapOkOrElse: Send); + assert_not_impl!(MapOkOrElse: Send); + assert_not_impl!(MapOkOrElse: Send); + assert_not_impl!(MapOkOrElse: Send); + assert_impl!(MapOkOrElse: Sync); + assert_not_impl!(MapOkOrElse: Sync); + assert_not_impl!(MapOkOrElse: Sync); + assert_not_impl!(MapOkOrElse: Sync); + assert_impl!(MapOkOrElse: Unpin); + assert_not_impl!(MapOkOrElse: Unpin); + + assert_impl!(NeverError: Send); + assert_not_impl!(NeverError: Send); + assert_impl!(NeverError: Sync); + assert_not_impl!(NeverError: Sync); + assert_impl!(NeverError: Unpin); + assert_not_impl!(NeverError: Unpin); + + assert_impl!(OkInto: Send); + assert_not_impl!(OkInto: Send); + assert_impl!(OkInto: Sync); + assert_not_impl!(OkInto: Sync); + assert_impl!(OkInto: Unpin); + assert_not_impl!(OkInto: Unpin); + + assert_impl!(OptionFuture: Send); + assert_not_impl!(OptionFuture: Send); + assert_impl!(OptionFuture: Sync); + assert_not_impl!(OptionFuture: Sync); + assert_impl!(OptionFuture: Unpin); + assert_not_impl!(OptionFuture: Unpin); + + assert_impl!(OrElse: Send); + assert_not_impl!(OrElse: Send); + assert_not_impl!(OrElse: Send); + assert_not_impl!(OrElse: Send); + assert_impl!(OrElse: Sync); + assert_not_impl!(OrElse: Sync); + assert_not_impl!(OrElse: Sync); + assert_not_impl!(OrElse: Sync); + assert_impl!(OrElse: Unpin); + assert_not_impl!(OrElse: Unpin); + assert_not_impl!(OrElse: Unpin); + + assert_impl!(Pending<()>: Send); + assert_not_impl!(Pending<*const ()>: Send); + assert_impl!(Pending<()>: Sync); + assert_not_impl!(Pending<*const ()>: Sync); + assert_impl!(Pending: Unpin); + + assert_impl!(PollFn<()>: Send); + assert_not_impl!(PollFn<*const ()>: Send); + assert_impl!(PollFn<()>: Sync); + assert_not_impl!(PollFn<*const ()>: Sync); + assert_impl!(PollFn: Unpin); + + assert_impl!(PollImmediate: Send); + assert_not_impl!(PollImmediate>: Send); + assert_impl!(PollImmediate: Sync); + assert_not_impl!(PollImmediate>: Sync); + assert_impl!(PollImmediate: Unpin); + assert_not_impl!(PollImmediate: Unpin); + + assert_impl!(Ready<()>: Send); + assert_not_impl!(Ready<*const ()>: Send); + assert_impl!(Ready<()>: Sync); + assert_not_impl!(Ready<*const ()>: Sync); + assert_impl!(Ready: Unpin); + + assert_impl!(Remote>: Send); + assert_not_impl!(Remote: Send); + assert_not_impl!(Remote: Send); + assert_impl!(Remote>: Sync); + assert_not_impl!(Remote: Sync); + assert_not_impl!(Remote: Sync); + assert_impl!(Remote: Unpin); + assert_not_impl!(Remote: Unpin); + + assert_impl!(RemoteHandle<()>: Send); + assert_not_impl!(RemoteHandle<*const ()>: Send); + assert_impl!(RemoteHandle<()>: Sync); + assert_not_impl!(RemoteHandle<*const ()>: Sync); + assert_impl!(RemoteHandle: Unpin); + + assert_impl!(Select: Send); + assert_not_impl!(Select: Send); + assert_not_impl!(Select: Send); + assert_impl!(Select: Sync); + assert_not_impl!(Select: Sync); + assert_not_impl!(Select: Sync); + assert_impl!(Select: Unpin); + assert_not_impl!(Select: Unpin); + assert_not_impl!(Select: Unpin); + + assert_impl!(SelectAll: Send); + assert_not_impl!(SelectAll: Send); + assert_impl!(SelectAll: Sync); + assert_not_impl!(SelectAll: Sync); + assert_impl!(SelectAll: Unpin); + assert_not_impl!(SelectAll: Unpin); + + assert_impl!(SelectOk: Send); + assert_not_impl!(SelectOk: Send); + assert_impl!(SelectOk: Sync); + assert_not_impl!(SelectOk: Sync); + assert_impl!(SelectOk: Unpin); + assert_not_impl!(SelectOk: Unpin); + + assert_impl!(Shared>: Send); + assert_not_impl!(Shared: Send); + assert_not_impl!(Shared: Send); + assert_not_impl!(Shared>: Sync); + assert_impl!(Shared: Unpin); + + assert_impl!(Then: Send); + assert_not_impl!(Then: Send); + assert_not_impl!(Then: Send); + assert_not_impl!(Then: Send); + assert_impl!(Then: Sync); + assert_not_impl!(Then: Sync); + assert_not_impl!(Then: Sync); + assert_not_impl!(Then: Sync); + assert_impl!(Then: Unpin); + assert_not_impl!(Then: Unpin); + assert_not_impl!(Then: Unpin); + + assert_impl!(TryFlatten, ()>: Send); + assert_not_impl!(TryFlatten: Send); + assert_not_impl!(TryFlatten: Send); + assert_impl!(TryFlatten, ()>: Sync); + assert_not_impl!(TryFlatten: Sync); + assert_not_impl!(TryFlatten: Sync); + assert_impl!(TryFlatten, ()>: Unpin); + assert_not_impl!(TryFlatten: Unpin); + assert_not_impl!(TryFlatten: Unpin); + + assert_impl!(TryFlattenStream>: Send); + assert_not_impl!(TryFlattenStream: Send); + assert_not_impl!(TryFlattenStream: Send); + assert_impl!(TryFlattenStream>: Sync); + assert_not_impl!(TryFlattenStream: Sync); + assert_not_impl!(TryFlattenStream: Sync); + assert_impl!(TryFlattenStream>: Unpin); + assert_not_impl!(TryFlattenStream: Unpin); + assert_not_impl!(TryFlattenStream: Unpin); + + assert_impl!(TryJoin, SendTryFuture<()>>: Send); + assert_not_impl!(TryJoin, SendTryFuture>: Send); + assert_not_impl!(TryJoin>: Send); + assert_not_impl!(TryJoin: Send); + assert_not_impl!(TryJoin: Send); + assert_impl!(TryJoin, SyncTryFuture<()>>: Sync); + assert_not_impl!(TryJoin, SyncTryFuture>: Sync); + assert_not_impl!(TryJoin>: Sync); + assert_not_impl!(TryJoin: Sync); + assert_not_impl!(TryJoin: Sync); + assert_impl!(TryJoin: Unpin); + assert_not_impl!(TryJoin: Unpin); + assert_not_impl!(TryJoin: Unpin); + + // TryJoin3, TryJoin4, TryJoin5 are the same as TryJoin + + assert_impl!(TryJoinAll>: Send); + assert_not_impl!(TryJoinAll: Send); + assert_not_impl!(TryJoinAll: Send); + assert_impl!(TryJoinAll>: Sync); + assert_not_impl!(TryJoinAll>: Sync); + assert_not_impl!(TryJoinAll>: Sync); + assert_not_impl!(TryJoinAll: Sync); + assert_impl!(TryJoinAll: Unpin); + + assert_impl!(TrySelect: Send); + assert_not_impl!(TrySelect: Send); + assert_not_impl!(TrySelect: Send); + assert_impl!(TrySelect: Sync); + assert_not_impl!(TrySelect: Sync); + assert_not_impl!(TrySelect: Sync); + assert_impl!(TrySelect: Unpin); + assert_not_impl!(TrySelect: Unpin); + assert_not_impl!(TrySelect: Unpin); + + assert_impl!(UnitError: Send); + assert_not_impl!(UnitError: Send); + assert_impl!(UnitError: Sync); + assert_not_impl!(UnitError: Sync); + assert_impl!(UnitError: Unpin); + assert_not_impl!(UnitError: Unpin); + + assert_impl!(UnwrapOrElse: Send); + assert_not_impl!(UnwrapOrElse: Send); + assert_not_impl!(UnwrapOrElse: Send); + assert_impl!(UnwrapOrElse: Sync); + assert_not_impl!(UnwrapOrElse: Sync); + assert_not_impl!(UnwrapOrElse: Sync); + assert_impl!(UnwrapOrElse: Unpin); + assert_not_impl!(UnwrapOrElse: Unpin); + + assert_impl!(WeakShared>: Send); + assert_not_impl!(WeakShared: Send); + assert_not_impl!(WeakShared: Send); + assert_not_impl!(WeakShared>: Sync); + assert_impl!(WeakShared: Unpin); + + assert_impl!(Either: Send); + assert_not_impl!(Either: Send); + assert_not_impl!(Either: Send); + assert_impl!(Either: Sync); + assert_not_impl!(Either: Sync); + assert_not_impl!(Either: Sync); + assert_impl!(Either: Unpin); + assert_not_impl!(Either: Unpin); + assert_not_impl!(Either: Unpin); + + assert_impl!(MaybeDone>: Send); + assert_not_impl!(MaybeDone: Send); + assert_not_impl!(MaybeDone: Send); + assert_impl!(MaybeDone>: Sync); + assert_not_impl!(MaybeDone: Sync); + assert_not_impl!(MaybeDone: Sync); + assert_impl!(MaybeDone: Unpin); + assert_not_impl!(MaybeDone: Unpin); + + assert_impl!(TryMaybeDone>: Send); + assert_not_impl!(TryMaybeDone: Send); + assert_not_impl!(TryMaybeDone: Send); + assert_impl!(TryMaybeDone>: Sync); + assert_not_impl!(TryMaybeDone: Sync); + assert_not_impl!(TryMaybeDone: Sync); + assert_impl!(TryMaybeDone: Unpin); + assert_not_impl!(TryMaybeDone: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::io`. +pub mod io { + use super::*; + use futures::io::{Sink, *}; + + assert_impl!(AllowStdIo<()>: Send); + assert_not_impl!(AllowStdIo<*const ()>: Send); + assert_impl!(AllowStdIo<()>: Sync); + assert_not_impl!(AllowStdIo<*const ()>: Sync); + assert_impl!(AllowStdIo: Unpin); + + assert_impl!(BufReader<()>: Send); + assert_not_impl!(BufReader<*const ()>: Send); + assert_impl!(BufReader<()>: Sync); + assert_not_impl!(BufReader<*const ()>: Sync); + assert_impl!(BufReader<()>: Unpin); + assert_not_impl!(BufReader: Unpin); + + assert_impl!(BufWriter<()>: Send); + assert_not_impl!(BufWriter<*const ()>: Send); + assert_impl!(BufWriter<()>: Sync); + assert_not_impl!(BufWriter<*const ()>: Sync); + assert_impl!(BufWriter<()>: Unpin); + assert_not_impl!(BufWriter: Unpin); + + assert_impl!(Chain<(), ()>: Send); + assert_not_impl!(Chain<(), *const ()>: Send); + assert_not_impl!(Chain<*const (), ()>: Send); + assert_impl!(Chain<(), ()>: Sync); + assert_not_impl!(Chain<(), *const ()>: Sync); + assert_not_impl!(Chain<*const (), ()>: Sync); + assert_impl!(Chain<(), ()>: Unpin); + assert_not_impl!(Chain<(), PhantomPinned>: Unpin); + assert_not_impl!(Chain: Unpin); + + assert_impl!(Close<'_, ()>: Send); + assert_not_impl!(Close<'_, *const ()>: Send); + assert_impl!(Close<'_, ()>: Sync); + assert_not_impl!(Close<'_, *const ()>: Sync); + assert_impl!(Close<'_, ()>: Unpin); + assert_not_impl!(Close<'_, PhantomPinned>: Unpin); + + assert_impl!(Copy<(), ()>: Send); + assert_not_impl!(Copy<(), *const ()>: Send); + assert_not_impl!(Copy<*const (), ()>: Send); + assert_impl!(Copy<(), ()>: Sync); + assert_not_impl!(Copy<(), *const ()>: Sync); + assert_not_impl!(Copy<*const (), ()>: Sync); + assert_impl!(Copy<(), PhantomPinned>: Unpin); + assert_not_impl!(Copy: Unpin); + + assert_impl!(CopyBuf<(), ()>: Send); + assert_not_impl!(CopyBuf<(), *const ()>: Send); + assert_not_impl!(CopyBuf<*const (), ()>: Send); + assert_impl!(CopyBuf<(), ()>: Sync); + assert_not_impl!(CopyBuf<(), *const ()>: Sync); + assert_not_impl!(CopyBuf<*const (), ()>: Sync); + assert_impl!(CopyBuf<(), PhantomPinned>: Unpin); + assert_not_impl!(CopyBuf: Unpin); + + assert_impl!(Cursor<()>: Send); + assert_not_impl!(Cursor<*const ()>: Send); + assert_impl!(Cursor<()>: Sync); + assert_not_impl!(Cursor<*const ()>: Sync); + assert_impl!(Cursor<()>: Unpin); + assert_not_impl!(Cursor: Unpin); + + assert_impl!(Empty: Send); + assert_impl!(Empty: Sync); + assert_impl!(Empty: Unpin); + + assert_impl!(FillBuf<'_, ()>: Send); + assert_not_impl!(FillBuf<'_, *const ()>: Send); + assert_impl!(FillBuf<'_, ()>: Sync); + assert_not_impl!(FillBuf<'_, *const ()>: Sync); + assert_impl!(FillBuf<'_, PhantomPinned>: Unpin); + + assert_impl!(Flush<'_, ()>: Send); + assert_not_impl!(Flush<'_, *const ()>: Send); + assert_impl!(Flush<'_, ()>: Sync); + assert_not_impl!(Flush<'_, *const ()>: Sync); + assert_impl!(Flush<'_, ()>: Unpin); + assert_not_impl!(Flush<'_, PhantomPinned>: Unpin); + + assert_impl!(IntoSink<(), ()>: Send); + assert_not_impl!(IntoSink<(), *const ()>: Send); + assert_not_impl!(IntoSink<*const (), ()>: Send); + assert_impl!(IntoSink<(), ()>: Sync); + assert_not_impl!(IntoSink<(), *const ()>: Sync); + assert_not_impl!(IntoSink<*const (), ()>: Sync); + assert_impl!(IntoSink<(), PhantomPinned>: Unpin); + assert_not_impl!(IntoSink: Unpin); + + assert_impl!(Lines<()>: Send); + assert_not_impl!(Lines<*const ()>: Send); + assert_impl!(Lines<()>: Sync); + assert_not_impl!(Lines<*const ()>: Sync); + assert_impl!(Lines<()>: Unpin); + assert_not_impl!(Lines: Unpin); + + assert_impl!(Read<'_, ()>: Send); + assert_not_impl!(Read<'_, *const ()>: Send); + assert_impl!(Read<'_, ()>: Sync); + assert_not_impl!(Read<'_, *const ()>: Sync); + assert_impl!(Read<'_, ()>: Unpin); + assert_not_impl!(Read<'_, PhantomPinned>: Unpin); + + assert_impl!(ReadExact<'_, ()>: Send); + assert_not_impl!(ReadExact<'_, *const ()>: Send); + assert_impl!(ReadExact<'_, ()>: Sync); + assert_not_impl!(ReadExact<'_, *const ()>: Sync); + assert_impl!(ReadExact<'_, ()>: Unpin); + assert_not_impl!(ReadExact<'_, PhantomPinned>: Unpin); + + assert_impl!(ReadHalf<()>: Send); + assert_not_impl!(ReadHalf<*const ()>: Send); + assert_impl!(ReadHalf<()>: Sync); + assert_not_impl!(ReadHalf<*const ()>: Sync); + assert_impl!(ReadHalf: Unpin); + + assert_impl!(ReadLine<'_, ()>: Send); + assert_not_impl!(ReadLine<'_, *const ()>: Send); + assert_impl!(ReadLine<'_, ()>: Sync); + assert_not_impl!(ReadLine<'_, *const ()>: Sync); + assert_impl!(ReadLine<'_, ()>: Unpin); + assert_not_impl!(ReadLine<'_, PhantomPinned>: Unpin); + + assert_impl!(ReadToEnd<'_, ()>: Send); + assert_not_impl!(ReadToEnd<'_, *const ()>: Send); + assert_impl!(ReadToEnd<'_, ()>: Sync); + assert_not_impl!(ReadToEnd<'_, *const ()>: Sync); + assert_impl!(ReadToEnd<'_, ()>: Unpin); + assert_not_impl!(ReadToEnd<'_, PhantomPinned>: Unpin); + + assert_impl!(ReadToString<'_, ()>: Send); + assert_not_impl!(ReadToString<'_, *const ()>: Send); + assert_impl!(ReadToString<'_, ()>: Sync); + assert_not_impl!(ReadToString<'_, *const ()>: Sync); + assert_impl!(ReadToString<'_, ()>: Unpin); + assert_not_impl!(ReadToString<'_, PhantomPinned>: Unpin); + + assert_impl!(ReadUntil<'_, ()>: Send); + assert_not_impl!(ReadUntil<'_, *const ()>: Send); + assert_impl!(ReadUntil<'_, ()>: Sync); + assert_not_impl!(ReadUntil<'_, *const ()>: Sync); + assert_impl!(ReadUntil<'_, ()>: Unpin); + assert_not_impl!(ReadUntil<'_, PhantomPinned>: Unpin); + + assert_impl!(ReadVectored<'_, ()>: Send); + assert_not_impl!(ReadVectored<'_, *const ()>: Send); + assert_impl!(ReadVectored<'_, ()>: Sync); + assert_not_impl!(ReadVectored<'_, *const ()>: Sync); + assert_impl!(ReadVectored<'_, ()>: Unpin); + assert_not_impl!(ReadVectored<'_, PhantomPinned>: Unpin); + + assert_impl!(Repeat: Send); + assert_impl!(Repeat: Sync); + assert_impl!(Repeat: Unpin); + + assert_impl!(ReuniteError<()>: Send); + assert_not_impl!(ReuniteError<*const ()>: Send); + assert_impl!(ReuniteError<()>: Sync); + assert_not_impl!(ReuniteError<*const ()>: Sync); + assert_impl!(ReuniteError: Unpin); + + assert_impl!(Seek<'_, ()>: Send); + assert_not_impl!(Seek<'_, *const ()>: Send); + assert_impl!(Seek<'_, ()>: Sync); + assert_not_impl!(Seek<'_, *const ()>: Sync); + assert_impl!(Seek<'_, ()>: Unpin); + assert_not_impl!(Seek<'_, PhantomPinned>: Unpin); + + assert_impl!(SeeKRelative<'_, ()>: Send); + assert_not_impl!(SeeKRelative<'_, *const ()>: Send); + assert_impl!(SeeKRelative<'_, ()>: Sync); + assert_not_impl!(SeeKRelative<'_, *const ()>: Sync); + assert_impl!(SeeKRelative<'_, PhantomPinned>: Unpin); + + assert_impl!(Sink: Send); + assert_impl!(Sink: Sync); + assert_impl!(Sink: Unpin); + + assert_impl!(Take<()>: Send); + assert_not_impl!(Take<*const ()>: Send); + assert_impl!(Take<()>: Sync); + assert_not_impl!(Take<*const ()>: Sync); + assert_impl!(Take<()>: Unpin); + assert_not_impl!(Take: Unpin); + + assert_impl!(Window<()>: Send); + assert_not_impl!(Window<*const ()>: Send); + assert_impl!(Window<()>: Sync); + assert_not_impl!(Window<*const ()>: Sync); + assert_impl!(Window<()>: Unpin); + assert_not_impl!(Window: Unpin); + + assert_impl!(Write<'_, ()>: Send); + assert_not_impl!(Write<'_, *const ()>: Send); + assert_impl!(Write<'_, ()>: Sync); + assert_not_impl!(Write<'_, *const ()>: Sync); + assert_impl!(Write<'_, ()>: Unpin); + assert_not_impl!(Write<'_, PhantomPinned>: Unpin); + + assert_impl!(WriteAll<'_, ()>: Send); + assert_not_impl!(WriteAll<'_, *const ()>: Send); + assert_impl!(WriteAll<'_, ()>: Sync); + assert_not_impl!(WriteAll<'_, *const ()>: Sync); + assert_impl!(WriteAll<'_, ()>: Unpin); + assert_not_impl!(WriteAll<'_, PhantomPinned>: Unpin); + + #[cfg(feature = "write-all-vectored")] + assert_impl!(WriteAllVectored<'_, ()>: Send); + #[cfg(feature = "write-all-vectored")] + assert_not_impl!(WriteAllVectored<'_, *const ()>: Send); + #[cfg(feature = "write-all-vectored")] + assert_impl!(WriteAllVectored<'_, ()>: Sync); + #[cfg(feature = "write-all-vectored")] + assert_not_impl!(WriteAllVectored<'_, *const ()>: Sync); + #[cfg(feature = "write-all-vectored")] + assert_impl!(WriteAllVectored<'_, ()>: Unpin); + // WriteAllVectored requires `W: Unpin` + // #[cfg(feature = "write-all-vectored")] + // assert_not_impl!(WriteAllVectored<'_, PhantomPinned>: Unpin); + + assert_impl!(WriteHalf<()>: Send); + assert_not_impl!(WriteHalf<*const ()>: Send); + assert_impl!(WriteHalf<()>: Sync); + assert_not_impl!(WriteHalf<*const ()>: Sync); + assert_impl!(WriteHalf: Unpin); + + assert_impl!(WriteVectored<'_, ()>: Send); + assert_not_impl!(WriteVectored<'_, *const ()>: Send); + assert_impl!(WriteVectored<'_, ()>: Sync); + assert_not_impl!(WriteVectored<'_, *const ()>: Sync); + assert_impl!(WriteVectored<'_, ()>: Unpin); + assert_not_impl!(WriteVectored<'_, PhantomPinned>: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::lock`. +pub mod lock { + use super::*; + use futures::lock::*; + + #[cfg(feature = "bilock")] + assert_impl!(BiLock<()>: Send); + #[cfg(feature = "bilock")] + assert_not_impl!(BiLock<*const ()>: Send); + #[cfg(feature = "bilock")] + assert_impl!(BiLock<()>: Sync); + #[cfg(feature = "bilock")] + assert_not_impl!(BiLock<*const ()>: Sync); + #[cfg(feature = "bilock")] + assert_impl!(BiLock: Unpin); + + #[cfg(feature = "bilock")] + assert_impl!(BiLockAcquire<'_, ()>: Send); + #[cfg(feature = "bilock")] + assert_not_impl!(BiLockAcquire<'_, *const ()>: Send); + #[cfg(feature = "bilock")] + assert_impl!(BiLockAcquire<'_, ()>: Sync); + #[cfg(feature = "bilock")] + assert_not_impl!(BiLockAcquire<'_, *const ()>: Sync); + #[cfg(feature = "bilock")] + assert_impl!(BiLockAcquire<'_, PhantomPinned>: Unpin); + + #[cfg(feature = "bilock")] + assert_impl!(BiLockGuard<'_, ()>: Send); + #[cfg(feature = "bilock")] + assert_not_impl!(BiLockGuard<'_, *const ()>: Send); + #[cfg(feature = "bilock")] + assert_impl!(BiLockGuard<'_, ()>: Sync); + #[cfg(feature = "bilock")] + assert_not_impl!(BiLockGuard<'_, *const ()>: Sync); + #[cfg(feature = "bilock")] + assert_impl!(BiLockGuard<'_, PhantomPinned>: Unpin); + + assert_impl!(MappedMutexGuard<'_, (), ()>: Send); + assert_not_impl!(MappedMutexGuard<'_, (), *const ()>: Send); + assert_not_impl!(MappedMutexGuard<'_, *const (), ()>: Send); + assert_impl!(MappedMutexGuard<'_, (), ()>: Sync); + assert_not_impl!(MappedMutexGuard<'_, (), *const ()>: Sync); + assert_not_impl!(MappedMutexGuard<'_, *const (), ()>: Sync); + assert_impl!(MappedMutexGuard<'_, PhantomPinned, PhantomPinned>: Unpin); + + assert_impl!(Mutex<()>: Send); + assert_not_impl!(Mutex<*const ()>: Send); + assert_impl!(Mutex<()>: Sync); + assert_not_impl!(Mutex<*const ()>: Sync); + assert_impl!(Mutex<()>: Unpin); + assert_not_impl!(Mutex: Unpin); + + assert_impl!(MutexGuard<'_, ()>: Send); + assert_not_impl!(MutexGuard<'_, *const ()>: Send); + assert_impl!(MutexGuard<'_, ()>: Sync); + assert_not_impl!(MutexGuard<'_, *const ()>: Sync); + assert_impl!(MutexGuard<'_, PhantomPinned>: Unpin); + + assert_impl!(MutexLockFuture<'_, ()>: Send); + assert_not_impl!(MutexLockFuture<'_, *const ()>: Send); + assert_impl!(MutexLockFuture<'_, *const ()>: Sync); + assert_impl!(MutexLockFuture<'_, PhantomPinned>: Unpin); + + #[cfg(feature = "bilock")] + assert_impl!(ReuniteError<()>: Send); + #[cfg(feature = "bilock")] + assert_not_impl!(ReuniteError<*const ()>: Send); + #[cfg(feature = "bilock")] + assert_impl!(ReuniteError<()>: Sync); + #[cfg(feature = "bilock")] + assert_not_impl!(ReuniteError<*const ()>: Sync); + #[cfg(feature = "bilock")] + assert_impl!(ReuniteError: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::sink`. +pub mod sink { + use super::*; + use futures::sink::{self, *}; + use std::marker::Send; + + assert_impl!(Buffer<(), ()>: Send); + assert_not_impl!(Buffer<(), *const ()>: Send); + assert_not_impl!(Buffer<*const (), ()>: Send); + assert_impl!(Buffer<(), ()>: Sync); + assert_not_impl!(Buffer<(), *const ()>: Sync); + assert_not_impl!(Buffer<*const (), ()>: Sync); + assert_impl!(Buffer<(), PhantomPinned>: Unpin); + assert_not_impl!(Buffer: Unpin); + + assert_impl!(Close<'_, (), *const ()>: Send); + assert_not_impl!(Close<'_, *const (), ()>: Send); + assert_impl!(Close<'_, (), *const ()>: Sync); + assert_not_impl!(Close<'_, *const (), ()>: Sync); + assert_impl!(Close<'_, (), PhantomPinned>: Unpin); + assert_not_impl!(Close<'_, PhantomPinned, ()>: Unpin); + + assert_impl!(Drain<()>: Send); + assert_not_impl!(Drain<*const ()>: Send); + assert_impl!(Drain<()>: Sync); + assert_not_impl!(Drain<*const ()>: Sync); + assert_impl!(Drain: Unpin); + + assert_impl!(Fanout<(), ()>: Send); + assert_not_impl!(Fanout<(), *const ()>: Send); + assert_not_impl!(Fanout<*const (), ()>: Send); + assert_impl!(Fanout<(), ()>: Sync); + assert_not_impl!(Fanout<(), *const ()>: Sync); + assert_not_impl!(Fanout<*const (), ()>: Sync); + assert_impl!(Fanout<(), ()>: Unpin); + assert_not_impl!(Fanout<(), PhantomPinned>: Unpin); + assert_not_impl!(Fanout: Unpin); + + assert_impl!(Feed<'_, (), ()>: Send); + assert_not_impl!(Feed<'_, (), *const ()>: Send); + assert_not_impl!(Feed<'_, *const (), ()>: Send); + assert_impl!(Feed<'_, (), ()>: Sync); + assert_not_impl!(Feed<'_, (), *const ()>: Sync); + assert_not_impl!(Feed<'_, *const (), ()>: Sync); + assert_impl!(Feed<'_, (), PhantomPinned>: Unpin); + assert_not_impl!(Feed<'_, PhantomPinned, ()>: Unpin); + + assert_impl!(Flush<'_, (), *const ()>: Send); + assert_not_impl!(Flush<'_, *const (), ()>: Send); + assert_impl!(Flush<'_, (), *const ()>: Sync); + assert_not_impl!(Flush<'_, *const (), ()>: Sync); + assert_impl!(Flush<'_, (), PhantomPinned>: Unpin); + assert_not_impl!(Flush<'_, PhantomPinned, ()>: Unpin); + + assert_impl!(sink::Send<'_, (), ()>: Send); + assert_not_impl!(sink::Send<'_, (), *const ()>: Send); + assert_not_impl!(sink::Send<'_, *const (), ()>: Send); + assert_impl!(sink::Send<'_, (), ()>: Sync); + assert_not_impl!(sink::Send<'_, (), *const ()>: Sync); + assert_not_impl!(sink::Send<'_, *const (), ()>: Sync); + assert_impl!(sink::Send<'_, (), PhantomPinned>: Unpin); + assert_not_impl!(sink::Send<'_, PhantomPinned, ()>: Unpin); + + assert_impl!(SendAll<'_, (), SendTryStream<()>>: Send); + assert_not_impl!(SendAll<'_, (), SendTryStream>: Send); + assert_not_impl!(SendAll<'_, (), LocalTryStream>: Send); + assert_not_impl!(SendAll<'_, *const (), SendTryStream<()>>: Send); + assert_impl!(SendAll<'_, (), SyncTryStream<()>>: Sync); + assert_not_impl!(SendAll<'_, (), SyncTryStream>: Sync); + assert_not_impl!(SendAll<'_, (), LocalTryStream>: Sync); + assert_not_impl!(SendAll<'_, *const (), SyncTryStream<()>>: Sync); + assert_impl!(SendAll<'_, (), UnpinTryStream>: Unpin); + assert_not_impl!(SendAll<'_, PhantomPinned, UnpinTryStream>: Unpin); + assert_not_impl!(SendAll<'_, (), PinnedTryStream>: Unpin); + + assert_impl!(SinkErrInto: Send); + assert_not_impl!(SinkErrInto, (), ()>: Send); + assert_impl!(SinkErrInto: Sync); + assert_not_impl!(SinkErrInto, (), ()>: Sync); + assert_impl!(SinkErrInto: Unpin); + assert_not_impl!(SinkErrInto, (), ()>: Unpin); + + assert_impl!(SinkMapErr: Send); + assert_not_impl!(SinkMapErr: Send); + assert_not_impl!(SinkMapErr, ()>: Send); + assert_impl!(SinkMapErr: Sync); + assert_not_impl!(SinkMapErr: Sync); + assert_not_impl!(SinkMapErr, ()>: Sync); + assert_impl!(SinkMapErr: Unpin); + assert_not_impl!(SinkMapErr, ()>: Unpin); + + assert_impl!(Unfold<(), (), ()>: Send); + assert_not_impl!(Unfold<*const (), (), ()>: Send); + assert_not_impl!(Unfold<(), *const (), ()>: Send); + assert_not_impl!(Unfold<(), (), *const ()>: Send); + assert_impl!(Unfold<(), (), ()>: Sync); + assert_not_impl!(Unfold<*const (), (), ()>: Sync); + assert_not_impl!(Unfold<(), *const (), ()>: Sync); + assert_not_impl!(Unfold<(), (), *const ()>: Sync); + assert_impl!(Unfold: Unpin); + assert_not_impl!(Unfold, (), PhantomPinned>: Unpin); + + assert_impl!(With<(), *const (), *const (), (), ()>: Send); + assert_not_impl!(With<*const (), (), (), (), ()>: Send); + assert_not_impl!(With<(), (), (), *const (), ()>: Send); + assert_not_impl!(With<(), (), (), (), *const ()>: Send); + assert_impl!(With<(), *const (), *const (), (), ()>: Sync); + assert_not_impl!(With<*const (), (), (), (), ()>: Sync); + assert_not_impl!(With<(), (), (), *const (), ()>: Sync); + assert_not_impl!(With<(), (), (), (), *const ()>: Sync); + assert_impl!(With<(), PhantomPinned, PhantomPinned, (), PhantomPinned>: Unpin); + assert_not_impl!(With: Unpin); + assert_not_impl!(With<(), (), (), PhantomPinned, ()>: Unpin); + + assert_impl!(WithFlatMap<(), (), *const (), (), ()>: Send); + assert_not_impl!(WithFlatMap<*const (), (), (), (), ()>: Send); + assert_not_impl!(WithFlatMap<(), *const (), (), (), ()>: Send); + assert_not_impl!(WithFlatMap<(), (), (), *const (), ()>: Send); + assert_not_impl!(WithFlatMap<(), (), (), (), *const ()>: Send); + assert_impl!(WithFlatMap<(), (), *const (), (), ()>: Sync); + assert_not_impl!(WithFlatMap<*const (), (), (), (), ()>: Sync); + assert_not_impl!(WithFlatMap<(), *const (), (), (), ()>: Sync); + assert_not_impl!(WithFlatMap<(), (), (), *const (), ()>: Sync); + assert_not_impl!(WithFlatMap<(), (), (), (), *const ()>: Sync); + assert_impl!(WithFlatMap<(), PhantomPinned, PhantomPinned, (), PhantomPinned>: Unpin); + assert_not_impl!(WithFlatMap: Unpin); + assert_not_impl!(WithFlatMap<(), (), (), PhantomPinned, ()>: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::stream`. +pub mod stream { + use super::*; + use futures::{io, stream::*}; + + assert_impl!(AndThen<(), (), ()>: Send); + assert_not_impl!(AndThen<*const (), (), ()>: Send); + assert_not_impl!(AndThen<(), *const (), ()>: Send); + assert_not_impl!(AndThen<(), (), *const ()>: Send); + assert_impl!(AndThen<(), (), ()>: Sync); + assert_not_impl!(AndThen<*const (), (), ()>: Sync); + assert_not_impl!(AndThen<(), *const (), ()>: Sync); + assert_not_impl!(AndThen<(), (), *const ()>: Sync); + assert_impl!(AndThen<(), (), PhantomPinned>: Unpin); + assert_not_impl!(AndThen: Unpin); + assert_not_impl!(AndThen<(), PhantomPinned, ()>: Unpin); + + assert_impl!(BufferUnordered>: Send); + assert_not_impl!(BufferUnordered: Send); + assert_not_impl!(BufferUnordered: Send); + assert_impl!(BufferUnordered>: Sync); + assert_not_impl!(BufferUnordered: Sync); + assert_not_impl!(BufferUnordered: Sync); + assert_impl!(BufferUnordered: Unpin); + assert_not_impl!(BufferUnordered: Unpin); + + assert_impl!(Buffered>>: Send); + assert_not_impl!(Buffered>: Send); + assert_not_impl!(Buffered>: Send); + assert_not_impl!(Buffered>>: Send); + assert_impl!(Buffered>>: Sync); + assert_not_impl!(Buffered>>: Sync); + assert_not_impl!(Buffered>>: Sync); + assert_impl!(Buffered>: Unpin); + assert_not_impl!(Buffered>: Unpin); + + assert_impl!(CatchUnwind: Send); + assert_not_impl!(CatchUnwind: Send); + assert_impl!(CatchUnwind: Sync); + assert_not_impl!(CatchUnwind: Sync); + assert_impl!(CatchUnwind: Unpin); + assert_not_impl!(CatchUnwind: Unpin); + + assert_impl!(Chain<(), ()>: Send); + assert_not_impl!(Chain<(), *const ()>: Send); + assert_not_impl!(Chain<*const (), ()>: Send); + assert_impl!(Chain<(), ()>: Sync); + assert_not_impl!(Chain<(), *const ()>: Sync); + assert_not_impl!(Chain<*const (), ()>: Sync); + assert_impl!(Chain<(), ()>: Unpin); + assert_not_impl!(Chain<(), PhantomPinned>: Unpin); + assert_not_impl!(Chain: Unpin); + + assert_impl!(Chunks>: Send); + assert_not_impl!(Chunks: Send); + assert_not_impl!(Chunks: Send); + assert_impl!(Chunks>: Sync); + assert_not_impl!(Chunks: Sync); + assert_not_impl!(Chunks: Sync); + assert_impl!(Chunks: Unpin); + assert_not_impl!(Chunks: Unpin); + + assert_impl!(Collect<(), ()>: Send); + assert_not_impl!(Collect<*const (), ()>: Send); + assert_not_impl!(Collect<(), *const ()>: Send); + assert_impl!(Collect<(), ()>: Sync); + assert_not_impl!(Collect<*const (), ()>: Sync); + assert_not_impl!(Collect<(), *const ()>: Sync); + assert_impl!(Collect<(), PhantomPinned>: Unpin); + assert_not_impl!(Collect: Unpin); + + assert_impl!(Concat>: Send); + assert_not_impl!(Concat: Send); + assert_not_impl!(Concat: Send); + assert_impl!(Concat>: Sync); + assert_not_impl!(Concat: Sync); + assert_not_impl!(Concat: Sync); + assert_impl!(Concat: Unpin); + assert_not_impl!(Concat: Unpin); + + assert_impl!(Cycle<()>: Send); + assert_not_impl!(Cycle<*const ()>: Send); + assert_impl!(Cycle<()>: Sync); + assert_not_impl!(Cycle<*const ()>: Sync); + assert_impl!(Cycle<()>: Unpin); + assert_not_impl!(Cycle: Unpin); + + assert_impl!(Empty<()>: Send); + assert_not_impl!(Empty<*const ()>: Send); + assert_impl!(Empty<()>: Sync); + assert_not_impl!(Empty<*const ()>: Sync); + assert_impl!(Empty: Unpin); + + assert_impl!(Enumerate<()>: Send); + assert_not_impl!(Enumerate<*const ()>: Send); + assert_impl!(Enumerate<()>: Sync); + assert_not_impl!(Enumerate<*const ()>: Sync); + assert_impl!(Enumerate<()>: Unpin); + assert_not_impl!(Enumerate: Unpin); + + assert_impl!(ErrInto<(), *const ()>: Send); + assert_not_impl!(ErrInto<*const (), ()>: Send); + assert_impl!(ErrInto<(), *const ()>: Sync); + assert_not_impl!(ErrInto<*const (), ()>: Sync); + assert_impl!(ErrInto<(), PhantomPinned>: Unpin); + assert_not_impl!(ErrInto: Unpin); + + assert_impl!(Filter, (), ()>: Send); + assert_not_impl!(Filter, (), ()>: Send); + assert_not_impl!(Filter: Send); + assert_not_impl!(Filter, *const (), ()>: Send); + assert_not_impl!(Filter, (), *const ()>: Send); + assert_impl!(Filter, (), ()>: Sync); + assert_not_impl!(Filter, (), ()>: Sync); + assert_not_impl!(Filter: Sync); + assert_not_impl!(Filter, *const (), ()>: Sync); + assert_not_impl!(Filter, (), *const ()>: Sync); + assert_impl!(Filter: Unpin); + assert_not_impl!(Filter: Unpin); + assert_not_impl!(Filter: Unpin); + + assert_impl!(FilterMap<(), (), ()>: Send); + assert_not_impl!(FilterMap<*const (), (), ()>: Send); + assert_not_impl!(FilterMap<(), *const (), ()>: Send); + assert_not_impl!(FilterMap<(), (), *const ()>: Send); + assert_impl!(FilterMap<(), (), ()>: Sync); + assert_not_impl!(FilterMap<*const (), (), ()>: Sync); + assert_not_impl!(FilterMap<(), *const (), ()>: Sync); + assert_not_impl!(FilterMap<(), (), *const ()>: Sync); + assert_impl!(FilterMap<(), (), PhantomPinned>: Unpin); + assert_not_impl!(FilterMap: Unpin); + assert_not_impl!(FilterMap<(), PhantomPinned, ()>: Unpin); + + assert_impl!(FlatMap<(), (), ()>: Send); + assert_not_impl!(FlatMap<*const (), (), ()>: Send); + assert_not_impl!(FlatMap<(), *const (), ()>: Send); + assert_not_impl!(FlatMap<(), (), *const ()>: Send); + assert_impl!(FlatMap<(), (), ()>: Sync); + assert_not_impl!(FlatMap<*const (), (), ()>: Sync); + assert_not_impl!(FlatMap<(), *const (), ()>: Sync); + assert_not_impl!(FlatMap<(), (), *const ()>: Sync); + assert_impl!(FlatMap<(), (), PhantomPinned>: Unpin); + assert_not_impl!(FlatMap: Unpin); + assert_not_impl!(FlatMap<(), PhantomPinned, ()>: Unpin); + + assert_impl!(Flatten>: Send); + assert_not_impl!(Flatten: Send); + assert_not_impl!(Flatten: Send); + assert_impl!(Flatten>: Sync); + assert_not_impl!(Flatten>: Sync); + assert_not_impl!(Flatten>: Sync); + assert_impl!(Flatten>: Unpin); + assert_not_impl!(Flatten: Unpin); + assert_not_impl!(Flatten: Unpin); + + assert_impl!(Fold<(), (), (), ()>: Send); + assert_not_impl!(Fold<*const (), (), (), ()>: Send); + assert_not_impl!(Fold<(), *const (), (), ()>: Send); + assert_not_impl!(Fold<(), (), *const (), ()>: Send); + assert_not_impl!(Fold<(), (), (), *const ()>: Send); + assert_impl!(Fold<(), (), (), ()>: Sync); + assert_not_impl!(Fold<*const (), (), (), ()>: Sync); + assert_not_impl!(Fold<(), *const (), (), ()>: Sync); + assert_not_impl!(Fold<(), (), *const (), ()>: Sync); + assert_not_impl!(Fold<(), (), (), *const ()>: Sync); + assert_impl!(Fold<(), (), PhantomPinned, PhantomPinned>: Unpin); + assert_not_impl!(Fold: Unpin); + assert_not_impl!(Fold<(), PhantomPinned, (), ()>: Unpin); + + assert_impl!(ForEach<(), (), ()>: Send); + assert_not_impl!(ForEach<*const (), (), ()>: Send); + assert_not_impl!(ForEach<(), *const (), ()>: Send); + assert_not_impl!(ForEach<(), (), *const ()>: Send); + assert_impl!(ForEach<(), (), ()>: Sync); + assert_not_impl!(ForEach<*const (), (), ()>: Sync); + assert_not_impl!(ForEach<(), *const (), ()>: Sync); + assert_not_impl!(ForEach<(), (), *const ()>: Sync); + assert_impl!(ForEach<(), (), PhantomPinned>: Unpin); + assert_not_impl!(ForEach: Unpin); + assert_not_impl!(ForEach<(), PhantomPinned, ()>: Unpin); + + assert_impl!(ForEachConcurrent<(), (), ()>: Send); + assert_not_impl!(ForEachConcurrent<*const (), (), ()>: Send); + assert_not_impl!(ForEachConcurrent<(), *const (), ()>: Send); + assert_not_impl!(ForEachConcurrent<(), (), *const ()>: Send); + assert_impl!(ForEachConcurrent<(), (), ()>: Sync); + assert_not_impl!(ForEachConcurrent<*const (), (), ()>: Sync); + assert_not_impl!(ForEachConcurrent<(), *const (), ()>: Sync); + assert_not_impl!(ForEachConcurrent<(), (), *const ()>: Sync); + assert_impl!(ForEachConcurrent<(), PhantomPinned, PhantomPinned>: Unpin); + assert_not_impl!(ForEachConcurrent: Unpin); + + assert_impl!(Forward, ()>: Send); + assert_not_impl!(Forward: Send); + assert_not_impl!(Forward, *const ()>: Send); + assert_not_impl!(Forward: Send); + assert_impl!(Forward, ()>: Sync); + assert_not_impl!(Forward: Sync); + assert_not_impl!(Forward, *const ()>: Sync); + assert_not_impl!(Forward: Sync); + assert_impl!(Forward: Unpin); + assert_not_impl!(Forward: Unpin); + assert_not_impl!(Forward: Unpin); + + assert_impl!(Fuse<()>: Send); + assert_not_impl!(Fuse<*const ()>: Send); + assert_impl!(Fuse<()>: Sync); + assert_not_impl!(Fuse<*const ()>: Sync); + assert_impl!(Fuse<()>: Unpin); + assert_not_impl!(Fuse: Unpin); + + assert_impl!(FuturesOrdered>: Send); + assert_not_impl!(FuturesOrdered: Send); + assert_not_impl!(FuturesOrdered: Send); + assert_impl!(FuturesOrdered>: Sync); + assert_not_impl!(FuturesOrdered>: Sync); + assert_not_impl!(FuturesOrdered>: Sync); + assert_not_impl!(FuturesOrdered: Sync); + assert_impl!(FuturesOrdered: Unpin); + + assert_impl!(FuturesUnordered<()>: Send); + assert_not_impl!(FuturesUnordered<*const ()>: Send); + assert_impl!(FuturesUnordered<()>: Sync); + assert_not_impl!(FuturesUnordered<*const ()>: Sync); + assert_impl!(FuturesUnordered: Unpin); + + assert_impl!(Inspect<(), ()>: Send); + assert_not_impl!(Inspect<*const (), ()>: Send); + assert_not_impl!(Inspect<(), *const ()>: Send); + assert_impl!(Inspect<(), ()>: Sync); + assert_not_impl!(Inspect<*const (), ()>: Sync); + assert_not_impl!(Inspect<(), *const ()>: Sync); + assert_impl!(Inspect<(), PhantomPinned>: Unpin); + assert_not_impl!(Inspect: Unpin); + + assert_impl!(InspectErr<(), ()>: Send); + assert_not_impl!(InspectErr<*const (), ()>: Send); + assert_not_impl!(InspectErr<(), *const ()>: Send); + assert_impl!(InspectErr<(), ()>: Sync); + assert_not_impl!(InspectErr<*const (), ()>: Sync); + assert_not_impl!(InspectErr<(), *const ()>: Sync); + assert_impl!(InspectErr<(), PhantomPinned>: Unpin); + assert_not_impl!(InspectErr: Unpin); + + assert_impl!(InspectOk<(), ()>: Send); + assert_not_impl!(InspectOk<*const (), ()>: Send); + assert_not_impl!(InspectOk<(), *const ()>: Send); + assert_impl!(InspectOk<(), ()>: Sync); + assert_not_impl!(InspectOk<*const (), ()>: Sync); + assert_not_impl!(InspectOk<(), *const ()>: Sync); + assert_impl!(InspectOk<(), PhantomPinned>: Unpin); + assert_not_impl!(InspectOk: Unpin); + + assert_impl!(IntoAsyncRead, io::Error>>: Send); + assert_not_impl!(IntoAsyncRead, io::Error>>: Send); + assert_impl!(IntoAsyncRead, io::Error>>: Sync); + assert_not_impl!(IntoAsyncRead, io::Error>>: Sync); + assert_impl!(IntoAsyncRead, io::Error>>: Unpin); + // IntoAsyncRead requires `St: Unpin` + // assert_not_impl!(IntoAsyncRead, io::Error>>: Unpin); + + assert_impl!(IntoStream<()>: Send); + assert_not_impl!(IntoStream<*const ()>: Send); + assert_impl!(IntoStream<()>: Sync); + assert_not_impl!(IntoStream<*const ()>: Sync); + assert_impl!(IntoStream<()>: Unpin); + assert_not_impl!(IntoStream: Unpin); + + assert_impl!(Iter<()>: Send); + assert_not_impl!(Iter<*const ()>: Send); + assert_impl!(Iter<()>: Sync); + assert_not_impl!(Iter<*const ()>: Sync); + assert_impl!(Iter: Unpin); + + assert_impl!(Map<(), ()>: Send); + assert_not_impl!(Map<*const (), ()>: Send); + assert_not_impl!(Map<(), *const ()>: Send); + assert_impl!(Map<(), ()>: Sync); + assert_not_impl!(Map<*const (), ()>: Sync); + assert_not_impl!(Map<(), *const ()>: Sync); + assert_impl!(Map<(), PhantomPinned>: Unpin); + assert_not_impl!(Map: Unpin); + + assert_impl!(MapErr<(), ()>: Send); + assert_not_impl!(MapErr<*const (), ()>: Send); + assert_not_impl!(MapErr<(), *const ()>: Send); + assert_impl!(MapErr<(), ()>: Sync); + assert_not_impl!(MapErr<*const (), ()>: Sync); + assert_not_impl!(MapErr<(), *const ()>: Sync); + assert_impl!(MapErr<(), PhantomPinned>: Unpin); + assert_not_impl!(MapErr: Unpin); + + assert_impl!(MapOk<(), ()>: Send); + assert_not_impl!(MapOk<*const (), ()>: Send); + assert_not_impl!(MapOk<(), *const ()>: Send); + assert_impl!(MapOk<(), ()>: Sync); + assert_not_impl!(MapOk<*const (), ()>: Sync); + assert_not_impl!(MapOk<(), *const ()>: Sync); + assert_impl!(MapOk<(), PhantomPinned>: Unpin); + assert_not_impl!(MapOk: Unpin); + + assert_impl!(Next<'_, ()>: Send); + assert_not_impl!(Next<'_, *const ()>: Send); + assert_impl!(Next<'_, ()>: Sync); + assert_not_impl!(Next<'_, *const ()>: Sync); + assert_impl!(Next<'_, ()>: Unpin); + assert_not_impl!(Next<'_, PhantomPinned>: Unpin); + + assert_impl!(NextIf<'_, SendStream<()>, ()>: Send); + assert_not_impl!(NextIf<'_, SendStream<()>, *const ()>: Send); + assert_not_impl!(NextIf<'_, SendStream, ()>: Send); + assert_not_impl!(NextIf<'_, LocalStream<()>, ()>: Send); + assert_impl!(NextIf<'_, SyncStream<()>, ()>: Sync); + assert_not_impl!(NextIf<'_, SyncStream<()>, *const ()>: Sync); + assert_not_impl!(NextIf<'_, SyncStream, ()>: Sync); + assert_not_impl!(NextIf<'_, LocalStream<()>, ()>: Send); + assert_impl!(NextIf<'_, PinnedStream, PhantomPinned>: Unpin); + + assert_impl!(NextIfEq<'_, SendStream<()>, ()>: Send); + assert_not_impl!(NextIfEq<'_, SendStream<()>, *const ()>: Send); + assert_not_impl!(NextIfEq<'_, SendStream, ()>: Send); + assert_not_impl!(NextIfEq<'_, LocalStream<()>, ()>: Send); + assert_impl!(NextIfEq<'_, SyncStream<()>, ()>: Sync); + assert_not_impl!(NextIfEq<'_, SyncStream<()>, *const ()>: Sync); + assert_not_impl!(NextIfEq<'_, SyncStream, ()>: Sync); + assert_not_impl!(NextIfEq<'_, LocalStream<()>, ()>: Send); + assert_impl!(NextIfEq<'_, PinnedStream, PhantomPinned>: Unpin); + + assert_impl!(Once<()>: Send); + assert_not_impl!(Once<*const ()>: Send); + assert_impl!(Once<()>: Sync); + assert_not_impl!(Once<*const ()>: Sync); + assert_impl!(Once<()>: Unpin); + assert_not_impl!(Once: Unpin); + + assert_impl!(OrElse<(), (), ()>: Send); + assert_not_impl!(OrElse<*const (), (), ()>: Send); + assert_not_impl!(OrElse<(), *const (), ()>: Send); + assert_not_impl!(OrElse<(), (), *const ()>: Send); + assert_impl!(OrElse<(), (), ()>: Sync); + assert_not_impl!(OrElse<*const (), (), ()>: Sync); + assert_not_impl!(OrElse<(), *const (), ()>: Sync); + assert_not_impl!(OrElse<(), (), *const ()>: Sync); + assert_impl!(OrElse<(), (), PhantomPinned>: Unpin); + assert_not_impl!(OrElse: Unpin); + assert_not_impl!(OrElse<(), PhantomPinned, ()>: Unpin); + + assert_impl!(Peek<'_, SendStream<()>>: Send); + assert_not_impl!(Peek<'_, SendStream>: Send); + assert_not_impl!(Peek<'_, LocalStream<()>>: Send); + assert_impl!(Peek<'_, SyncStream<()>>: Sync); + assert_not_impl!(Peek<'_, SyncStream>: Sync); + assert_not_impl!(Peek<'_, LocalStream<()>>: Sync); + assert_impl!(Peek<'_, PinnedStream>: Unpin); + + assert_impl!(PeekMut<'_, SendStream<()>>: Send); + assert_not_impl!(PeekMut<'_, SendStream>: Send); + assert_not_impl!(PeekMut<'_, LocalStream<()>>: Send); + assert_impl!(PeekMut<'_, SyncStream<()>>: Sync); + assert_not_impl!(PeekMut<'_, SyncStream>: Sync); + assert_not_impl!(PeekMut<'_, LocalStream<()>>: Sync); + assert_impl!(PeekMut<'_, PinnedStream>: Unpin); + + assert_impl!(Peekable>: Send); + assert_not_impl!(Peekable: Send); + assert_not_impl!(Peekable: Send); + assert_impl!(Peekable>: Sync); + assert_not_impl!(Peekable: Sync); + assert_not_impl!(Peekable: Sync); + assert_impl!(Peekable: Unpin); + assert_not_impl!(Peekable: Unpin); + + assert_impl!(Pending<()>: Send); + assert_not_impl!(Pending<*const ()>: Send); + assert_impl!(Pending<()>: Sync); + assert_not_impl!(Pending<*const ()>: Sync); + assert_impl!(Pending: Unpin); + + assert_impl!(PollFn<()>: Send); + assert_not_impl!(PollFn<*const ()>: Send); + assert_impl!(PollFn<()>: Sync); + assert_not_impl!(PollFn<*const ()>: Sync); + assert_impl!(PollFn: Unpin); + + assert_impl!(PollImmediate: Send); + assert_not_impl!(PollImmediate>: Send); + assert_impl!(PollImmediate: Sync); + assert_not_impl!(PollImmediate>: Sync); + assert_impl!(PollImmediate: Unpin); + assert_not_impl!(PollImmediate: Unpin); + + assert_impl!(ReadyChunks>: Send); + assert_impl!(ReadyChunks: Send); + assert_not_impl!(ReadyChunks: Send); + assert_impl!(ReadyChunks>: Sync); + assert_impl!(ReadyChunks: Sync); + assert_not_impl!(ReadyChunks: Sync); + assert_impl!(ReadyChunks: Unpin); + assert_not_impl!(ReadyChunks: Unpin); + + assert_impl!(Repeat<()>: Send); + assert_not_impl!(Repeat<*const ()>: Send); + assert_impl!(Repeat<()>: Sync); + assert_not_impl!(Repeat<*const ()>: Sync); + assert_impl!(Repeat: Unpin); + + assert_impl!(RepeatWith<()>: Send); + assert_not_impl!(RepeatWith<*const ()>: Send); + assert_impl!(RepeatWith<()>: Sync); + assert_not_impl!(RepeatWith<*const ()>: Sync); + // RepeatWith requires `F: FnMut() -> A` + assert_impl!(RepeatWith ()>: Unpin); + // assert_impl!(RepeatWith: Unpin); + + assert_impl!(ReuniteError<(), ()>: Send); + assert_not_impl!(ReuniteError<*const (), ()>: Send); + assert_not_impl!(ReuniteError<(), *const ()>: Send); + assert_impl!(ReuniteError<(), ()>: Sync); + assert_not_impl!(ReuniteError<*const (), ()>: Sync); + assert_not_impl!(ReuniteError<(), *const ()>: Sync); + assert_impl!(ReuniteError: Unpin); + + assert_impl!(Scan: Send); + assert_not_impl!(Scan, (), (), ()>: Send); + assert_not_impl!(Scan, *const (), (), ()>: Send); + assert_not_impl!(Scan, (), *const (), ()>: Send); + assert_not_impl!(Scan, (), (), *const ()>: Send); + assert_impl!(Scan: Sync); + assert_not_impl!(Scan, (), (), ()>: Sync); + assert_not_impl!(Scan, *const (), (), ()>: Sync); + assert_not_impl!(Scan, (), *const (), ()>: Sync); + assert_not_impl!(Scan, (), (), *const ()>: Sync); + assert_impl!(Scan: Unpin); + assert_not_impl!(Scan: Unpin); + assert_not_impl!(Scan: Unpin); + + assert_impl!(Select<(), ()>: Send); + assert_not_impl!(Select<*const (), ()>: Send); + assert_not_impl!(Select<(), *const ()>: Send); + assert_impl!(Select<(), ()>: Sync); + assert_not_impl!(Select<*const (), ()>: Sync); + assert_not_impl!(Select<(), *const ()>: Sync); + assert_impl!(Select<(), ()>: Unpin); + assert_not_impl!(Select: Unpin); + assert_not_impl!(Select<(), PhantomPinned>: Unpin); + + assert_impl!(SelectAll<()>: Send); + assert_not_impl!(SelectAll<*const ()>: Send); + assert_impl!(SelectAll<()>: Sync); + assert_not_impl!(SelectAll<*const ()>: Sync); + assert_impl!(SelectAll: Unpin); + + assert_impl!(SelectNextSome<'_, ()>: Send); + assert_not_impl!(SelectNextSome<'_, *const ()>: Send); + assert_impl!(SelectNextSome<'_, ()>: Sync); + assert_not_impl!(SelectNextSome<'_, *const ()>: Sync); + assert_impl!(SelectNextSome<'_, PhantomPinned>: Unpin); + + assert_impl!(Skip<()>: Send); + assert_not_impl!(Skip<*const ()>: Send); + assert_impl!(Skip<()>: Sync); + assert_not_impl!(Skip<*const ()>: Sync); + assert_impl!(Skip<()>: Unpin); + assert_not_impl!(Skip: Unpin); + + assert_impl!(SkipWhile, (), ()>: Send); + assert_not_impl!(SkipWhile, (), ()>: Send); + assert_not_impl!(SkipWhile: Send); + assert_not_impl!(SkipWhile, *const (), ()>: Send); + assert_not_impl!(SkipWhile, (), *const ()>: Send); + assert_impl!(SkipWhile, (), ()>: Sync); + assert_not_impl!(SkipWhile, (), ()>: Sync); + assert_not_impl!(SkipWhile: Sync); + assert_not_impl!(SkipWhile, *const (), ()>: Sync); + assert_not_impl!(SkipWhile, (), *const ()>: Sync); + assert_impl!(SkipWhile: Unpin); + assert_not_impl!(SkipWhile: Unpin); + assert_not_impl!(SkipWhile: Unpin); + + assert_impl!(SplitSink<(), ()>: Send); + assert_not_impl!(SplitSink<*const (), ()>: Send); + assert_not_impl!(SplitSink<(), *const ()>: Send); + assert_impl!(SplitSink<(), ()>: Sync); + assert_not_impl!(SplitSink<*const (), ()>: Sync); + assert_not_impl!(SplitSink<(), *const ()>: Sync); + assert_impl!(SplitSink: Unpin); + + assert_impl!(SplitStream<()>: Send); + assert_not_impl!(SplitStream<*const ()>: Send); + assert_impl!(SplitStream<()>: Sync); + assert_not_impl!(SplitStream<*const ()>: Sync); + assert_impl!(SplitStream: Unpin); + + assert_impl!(StreamFuture<()>: Send); + assert_not_impl!(StreamFuture<*const ()>: Send); + assert_impl!(StreamFuture<()>: Sync); + assert_not_impl!(StreamFuture<*const ()>: Sync); + assert_impl!(StreamFuture<()>: Unpin); + assert_not_impl!(StreamFuture: Unpin); + + assert_impl!(Take<()>: Send); + assert_not_impl!(Take<*const ()>: Send); + assert_impl!(Take<()>: Sync); + assert_not_impl!(Take<*const ()>: Sync); + assert_impl!(Take<()>: Unpin); + assert_not_impl!(Take: Unpin); + + assert_impl!(TakeUntil>: Send); + assert_not_impl!(TakeUntil: Send); + assert_not_impl!(TakeUntil>: Send); + assert_not_impl!(TakeUntil>: Send); + assert_impl!(TakeUntil>: Sync); + assert_not_impl!(TakeUntil: Sync); + assert_not_impl!(TakeUntil>: Sync); + assert_not_impl!(TakeUntil>: Sync); + assert_impl!(TakeUntil: Unpin); + assert_not_impl!(TakeUntil: Unpin); + assert_not_impl!(TakeUntil: Unpin); + + assert_impl!(TakeWhile, (), ()>: Send); + assert_not_impl!(TakeWhile, (), ()>: Send); + assert_not_impl!(TakeWhile: Send); + assert_not_impl!(TakeWhile, *const (), ()>: Send); + assert_not_impl!(TakeWhile, (), *const ()>: Send); + assert_impl!(TakeWhile, (), ()>: Sync); + assert_not_impl!(TakeWhile, (), ()>: Sync); + assert_not_impl!(TakeWhile: Sync); + assert_not_impl!(TakeWhile, *const (), ()>: Sync); + assert_not_impl!(TakeWhile, (), *const ()>: Sync); + assert_impl!(TakeWhile: Unpin); + assert_not_impl!(TakeWhile: Unpin); + assert_not_impl!(TakeWhile: Unpin); + + assert_impl!(Then: Send); + assert_not_impl!(Then, (), ()>: Send); + assert_not_impl!(Then, *const (), ()>: Send); + assert_not_impl!(Then, (), *const ()>: Send); + assert_impl!(Then: Sync); + assert_not_impl!(Then, (), ()>: Sync); + assert_not_impl!(Then, *const (), ()>: Sync); + assert_not_impl!(Then, (), *const ()>: Sync); + assert_impl!(Then: Unpin); + assert_not_impl!(Then: Unpin); + assert_not_impl!(Then: Unpin); + + assert_impl!(TryBufferUnordered>: Send); + assert_not_impl!(TryBufferUnordered: Send); + assert_not_impl!(TryBufferUnordered: Send); + assert_impl!(TryBufferUnordered>: Sync); + assert_not_impl!(TryBufferUnordered: Sync); + assert_not_impl!(TryBufferUnordered: Sync); + assert_impl!(TryBufferUnordered: Unpin); + assert_not_impl!(TryBufferUnordered: Unpin); + + assert_impl!(TryBuffered>>: Send); + assert_not_impl!(TryBuffered>>: Send); + assert_not_impl!(TryBuffered>>: Send); + assert_not_impl!(TryBuffered>>: Send); + assert_not_impl!(TryBuffered>>: Send); + assert_impl!(TryBuffered>>: Sync); + assert_not_impl!(TryBuffered>>: Sync); + assert_not_impl!(TryBuffered>>: Sync); + assert_not_impl!(TryBuffered>>: Sync); + assert_not_impl!(TryBuffered>>: Sync); + assert_not_impl!(TryBuffered>>: Sync); + assert_impl!(TryBuffered>: Unpin); + assert_not_impl!(TryBuffered>: Unpin); + + assert_impl!(TryCollect<(), ()>: Send); + assert_not_impl!(TryCollect<*const (), ()>: Send); + assert_not_impl!(TryCollect<(), *const ()>: Send); + assert_impl!(TryCollect<(), ()>: Sync); + assert_not_impl!(TryCollect<*const (), ()>: Sync); + assert_not_impl!(TryCollect<(), *const ()>: Sync); + assert_impl!(TryCollect<(), PhantomPinned>: Unpin); + assert_not_impl!(TryCollect: Unpin); + + assert_impl!(TryConcat>: Send); + assert_not_impl!(TryConcat: Send); + assert_not_impl!(TryConcat: Send); + assert_impl!(TryConcat>: Sync); + assert_not_impl!(TryConcat: Sync); + assert_not_impl!(TryConcat: Sync); + assert_impl!(TryConcat: Unpin); + assert_not_impl!(TryConcat: Unpin); + + assert_impl!(TryFilter, (), ()>: Send); + assert_not_impl!(TryFilter, (), ()>: Send); + assert_not_impl!(TryFilter: Send); + assert_not_impl!(TryFilter, *const (), ()>: Send); + assert_not_impl!(TryFilter, (), *const ()>: Send); + assert_impl!(TryFilter, (), ()>: Sync); + assert_not_impl!(TryFilter, (), ()>: Sync); + assert_not_impl!(TryFilter: Sync); + assert_not_impl!(TryFilter, *const (), ()>: Sync); + assert_not_impl!(TryFilter, (), *const ()>: Sync); + assert_impl!(TryFilter: Unpin); + assert_not_impl!(TryFilter: Unpin); + assert_not_impl!(TryFilter: Unpin); + + assert_impl!(TryFilterMap<(), (), ()>: Send); + assert_not_impl!(TryFilterMap<*const (), (), ()>: Send); + assert_not_impl!(TryFilterMap<(), *const (), ()>: Send); + assert_not_impl!(TryFilterMap<(), (), *const ()>: Send); + assert_impl!(TryFilterMap<(), (), ()>: Sync); + assert_not_impl!(TryFilterMap<*const (), (), ()>: Sync); + assert_not_impl!(TryFilterMap<(), *const (), ()>: Sync); + assert_not_impl!(TryFilterMap<(), (), *const ()>: Sync); + assert_impl!(TryFilterMap<(), (), PhantomPinned>: Unpin); + assert_not_impl!(TryFilterMap: Unpin); + assert_not_impl!(TryFilterMap<(), PhantomPinned, ()>: Unpin); + + assert_impl!(TryFlatten>: Send); + assert_not_impl!(TryFlatten: Send); + assert_not_impl!(TryFlatten: Send); + assert_impl!(TryFlatten>: Sync); + assert_not_impl!(TryFlatten>: Sync); + assert_not_impl!(TryFlatten>: Sync); + assert_impl!(TryFlatten>: Unpin); + assert_not_impl!(TryFlatten: Unpin); + assert_not_impl!(TryFlatten: Unpin); + + assert_impl!(TryFold<(), (), (), ()>: Send); + assert_not_impl!(TryFold<*const (), (), (), ()>: Send); + assert_not_impl!(TryFold<(), *const (), (), ()>: Send); + assert_not_impl!(TryFold<(), (), *const (), ()>: Send); + assert_not_impl!(TryFold<(), (), (), *const ()>: Send); + assert_impl!(TryFold<(), (), (), ()>: Sync); + assert_not_impl!(TryFold<*const (), (), (), ()>: Sync); + assert_not_impl!(TryFold<(), *const (), (), ()>: Sync); + assert_not_impl!(TryFold<(), (), *const (), ()>: Sync); + assert_not_impl!(TryFold<(), (), (), *const ()>: Sync); + assert_impl!(TryFold<(), (), PhantomPinned, PhantomPinned>: Unpin); + assert_not_impl!(TryFold: Unpin); + assert_not_impl!(TryFold<(), PhantomPinned, (), ()>: Unpin); + + assert_impl!(TryForEach<(), (), ()>: Send); + assert_not_impl!(TryForEach<*const (), (), ()>: Send); + assert_not_impl!(TryForEach<(), *const (), ()>: Send); + assert_not_impl!(TryForEach<(), (), *const ()>: Send); + assert_impl!(TryForEach<(), (), ()>: Sync); + assert_not_impl!(TryForEach<*const (), (), ()>: Sync); + assert_not_impl!(TryForEach<(), *const (), ()>: Sync); + assert_not_impl!(TryForEach<(), (), *const ()>: Sync); + assert_impl!(TryForEach<(), (), PhantomPinned>: Unpin); + assert_not_impl!(TryForEach: Unpin); + assert_not_impl!(TryForEach<(), PhantomPinned, ()>: Unpin); + + assert_impl!(TryForEachConcurrent<(), (), ()>: Send); + assert_not_impl!(TryForEachConcurrent<*const (), (), ()>: Send); + assert_not_impl!(TryForEachConcurrent<(), *const (), ()>: Send); + assert_not_impl!(TryForEachConcurrent<(), (), *const ()>: Send); + assert_impl!(TryForEachConcurrent<(), (), ()>: Sync); + assert_not_impl!(TryForEachConcurrent<*const (), (), ()>: Sync); + assert_not_impl!(TryForEachConcurrent<(), *const (), ()>: Sync); + assert_not_impl!(TryForEachConcurrent<(), (), *const ()>: Sync); + assert_impl!(TryForEachConcurrent<(), PhantomPinned, PhantomPinned>: Unpin); + assert_not_impl!(TryForEachConcurrent: Unpin); + + assert_impl!(TryNext<'_, ()>: Send); + assert_not_impl!(TryNext<'_, *const ()>: Send); + assert_impl!(TryNext<'_, ()>: Sync); + assert_not_impl!(TryNext<'_, *const ()>: Sync); + assert_impl!(TryNext<'_, ()>: Unpin); + assert_not_impl!(TryNext<'_, PhantomPinned>: Unpin); + + assert_impl!(TrySkipWhile, (), ()>: Send); + assert_not_impl!(TrySkipWhile, (), ()>: Send); + assert_not_impl!(TrySkipWhile: Send); + assert_not_impl!(TrySkipWhile, *const (), ()>: Send); + assert_not_impl!(TrySkipWhile, (), *const ()>: Send); + assert_impl!(TrySkipWhile, (), ()>: Sync); + assert_not_impl!(TrySkipWhile, (), ()>: Sync); + assert_not_impl!(TrySkipWhile: Sync); + assert_not_impl!(TrySkipWhile, *const (), ()>: Sync); + assert_not_impl!(TrySkipWhile, (), *const ()>: Sync); + assert_impl!(TrySkipWhile: Unpin); + assert_not_impl!(TrySkipWhile: Unpin); + assert_not_impl!(TrySkipWhile: Unpin); + + assert_impl!(TryTakeWhile, (), ()>: Send); + assert_not_impl!(TryTakeWhile, (), ()>: Send); + assert_not_impl!(TryTakeWhile: Send); + assert_not_impl!(TryTakeWhile, *const (), ()>: Send); + assert_not_impl!(TryTakeWhile, (), *const ()>: Send); + assert_impl!(TryTakeWhile, (), ()>: Sync); + assert_not_impl!(TryTakeWhile, (), ()>: Sync); + assert_not_impl!(TryTakeWhile: Sync); + assert_not_impl!(TryTakeWhile, *const (), ()>: Sync); + assert_not_impl!(TryTakeWhile, (), *const ()>: Sync); + assert_impl!(TryTakeWhile: Unpin); + assert_not_impl!(TryTakeWhile: Unpin); + assert_not_impl!(TryTakeWhile: Unpin); + + assert_impl!(TryUnfold<(), (), ()>: Send); + assert_not_impl!(TryUnfold<*const (), (), ()>: Send); + assert_not_impl!(TryUnfold<(), *const (), ()>: Send); + assert_not_impl!(TryUnfold<(), (), *const ()>: Send); + assert_impl!(TryUnfold<(), (), ()>: Sync); + assert_not_impl!(TryUnfold<*const (), (), ()>: Sync); + assert_not_impl!(TryUnfold<(), *const (), ()>: Sync); + assert_not_impl!(TryUnfold<(), (), *const ()>: Sync); + assert_impl!(TryUnfold: Unpin); + assert_not_impl!(TryUnfold<(), (), PhantomPinned>: Unpin); + + assert_impl!(Unfold<(), (), ()>: Send); + assert_not_impl!(Unfold<*const (), (), ()>: Send); + assert_not_impl!(Unfold<(), *const (), ()>: Send); + assert_not_impl!(Unfold<(), (), *const ()>: Send); + assert_impl!(Unfold<(), (), ()>: Sync); + assert_not_impl!(Unfold<*const (), (), ()>: Sync); + assert_not_impl!(Unfold<(), *const (), ()>: Sync); + assert_not_impl!(Unfold<(), (), *const ()>: Sync); + assert_impl!(Unfold: Unpin); + assert_not_impl!(Unfold<(), (), PhantomPinned>: Unpin); + + assert_impl!(Unzip<(), (), ()>: Send); + assert_not_impl!(Unzip<*const (), (), ()>: Send); + assert_not_impl!(Unzip<(), *const (), ()>: Send); + assert_not_impl!(Unzip<(), (), *const ()>: Send); + assert_impl!(Unzip<(), (), ()>: Sync); + assert_not_impl!(Unzip<*const (), (), ()>: Sync); + assert_not_impl!(Unzip<(), *const (), ()>: Sync); + assert_not_impl!(Unzip<(), (), *const ()>: Sync); + assert_impl!(Unzip<(), PhantomPinned, PhantomPinned>: Unpin); + assert_not_impl!(Unzip: Unpin); + + assert_impl!(Zip, SendStream<()>>: Send); + assert_not_impl!(Zip>: Send); + assert_not_impl!(Zip, SendStream>: Send); + assert_not_impl!(Zip>: Send); + assert_not_impl!(Zip, LocalStream>: Send); + assert_impl!(Zip, SyncStream<()>>: Sync); + assert_not_impl!(Zip>: Sync); + assert_not_impl!(Zip, SyncStream>: Sync); + assert_not_impl!(Zip>: Sync); + assert_not_impl!(Zip, LocalStream>: Sync); + assert_impl!(Zip: Unpin); + assert_not_impl!(Zip: Unpin); + assert_not_impl!(Zip: Unpin); + + assert_impl!(futures_unordered::Iter<()>: Send); + assert_not_impl!(futures_unordered::Iter<*const ()>: Send); + assert_impl!(futures_unordered::Iter<()>: Sync); + assert_not_impl!(futures_unordered::Iter<*const ()>: Sync); + assert_impl!(futures_unordered::Iter<()>: Unpin); + // The definition of futures_unordered::Iter has `Fut: Unpin` bounds. + // assert_not_impl!(futures_unordered::Iter: Unpin); + + assert_impl!(futures_unordered::IterMut<()>: Send); + assert_not_impl!(futures_unordered::IterMut<*const ()>: Send); + assert_impl!(futures_unordered::IterMut<()>: Sync); + assert_not_impl!(futures_unordered::IterMut<*const ()>: Sync); + assert_impl!(futures_unordered::IterMut<()>: Unpin); + // The definition of futures_unordered::IterMut has `Fut: Unpin` bounds. + // assert_not_impl!(futures_unordered::IterMut: Unpin); + + assert_impl!(futures_unordered::IterPinMut<()>: Send); + assert_not_impl!(futures_unordered::IterPinMut<*const ()>: Send); + assert_impl!(futures_unordered::IterPinMut<()>: Sync); + assert_not_impl!(futures_unordered::IterPinMut<*const ()>: Sync); + assert_impl!(futures_unordered::IterPinMut: Unpin); + + assert_impl!(futures_unordered::IterPinRef<()>: Send); + assert_not_impl!(futures_unordered::IterPinRef<*const ()>: Send); + assert_impl!(futures_unordered::IterPinRef<()>: Sync); + assert_not_impl!(futures_unordered::IterPinRef<*const ()>: Sync); + assert_impl!(futures_unordered::IterPinRef: Unpin); + + assert_impl!(futures_unordered::IntoIter<()>: Send); + assert_not_impl!(futures_unordered::IntoIter<*const ()>: Send); + assert_impl!(futures_unordered::IntoIter<()>: Sync); + assert_not_impl!(futures_unordered::IntoIter<*const ()>: Sync); + // The definition of futures_unordered::IntoIter has `Fut: Unpin` bounds. + // assert_not_impl!(futures_unordered::IntoIter: Unpin); +} + +/// Assert Send/Sync/Unpin for all public types in `futures::task`. +pub mod task { + use super::*; + use futures::task::*; + + assert_impl!(AtomicWaker: Send); + assert_impl!(AtomicWaker: Sync); + assert_impl!(AtomicWaker: Unpin); + + assert_impl!(FutureObj<*const ()>: Send); + assert_not_impl!(FutureObj<()>: Sync); + assert_impl!(FutureObj: Unpin); + + assert_not_impl!(LocalFutureObj<()>: Send); + assert_not_impl!(LocalFutureObj<()>: Sync); + assert_impl!(LocalFutureObj: Unpin); + + assert_impl!(SpawnError: Send); + assert_impl!(SpawnError: Sync); + assert_impl!(SpawnError: Unpin); + + assert_impl!(WakerRef<'_>: Send); + assert_impl!(WakerRef<'_>: Sync); + assert_impl!(WakerRef<'_>: Unpin); +} diff --git a/utshell-0.5.0/vendor/futures/tests/bilock.rs b/utshell-0.5.0/vendor/futures/tests/bilock.rs new file mode 100644 index 00000000..b1034878 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/bilock.rs @@ -0,0 +1,104 @@ +#![cfg(feature = "bilock")] + +use futures::executor::block_on; +use futures::future; +use futures::stream; +use futures::task::{Context, Poll}; +use futures::Future; +use futures::StreamExt; +use futures_test::task::noop_context; +use futures_util::lock::BiLock; +use std::pin::Pin; +use std::thread; + +#[test] +fn smoke() { + let future = future::lazy(|cx| { + let (a, b) = BiLock::new(1); + + { + let mut lock = match a.poll_lock(cx) { + Poll::Ready(l) => l, + Poll::Pending => panic!("poll not ready"), + }; + assert_eq!(*lock, 1); + *lock = 2; + + assert!(b.poll_lock(cx).is_pending()); + assert!(a.poll_lock(cx).is_pending()); + } + + assert!(b.poll_lock(cx).is_ready()); + assert!(a.poll_lock(cx).is_ready()); + + { + let lock = match b.poll_lock(cx) { + Poll::Ready(l) => l, + Poll::Pending => panic!("poll not ready"), + }; + assert_eq!(*lock, 2); + } + + assert_eq!(a.reunite(b).expect("bilock/smoke: reunite error"), 2); + + Ok::<(), ()>(()) + }); + + assert_eq!(block_on(future), Ok(())); +} + +#[test] +fn concurrent() { + const N: usize = 10000; + let mut cx = noop_context(); + let (a, b) = BiLock::new(0); + + let a = Increment { a: Some(a), remaining: N }; + let b = stream::iter(0..N).fold(b, |b, _n| async { + let mut g = b.lock().await; + *g += 1; + drop(g); + b + }); + + let t1 = thread::spawn(move || block_on(a)); + let b = block_on(b); + let a = t1.join().unwrap(); + + match a.poll_lock(&mut cx) { + Poll::Ready(l) => assert_eq!(*l, 2 * N), + Poll::Pending => panic!("poll not ready"), + } + match b.poll_lock(&mut cx) { + Poll::Ready(l) => assert_eq!(*l, 2 * N), + Poll::Pending => panic!("poll not ready"), + } + + assert_eq!(a.reunite(b).expect("bilock/concurrent: reunite error"), 2 * N); + + struct Increment { + remaining: usize, + a: Option>, + } + + impl Future for Increment { + type Output = BiLock; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + loop { + if self.remaining == 0 { + return self.a.take().unwrap().into(); + } + + let a = self.a.as_mut().unwrap(); + let mut a = match a.poll_lock(cx) { + Poll::Ready(l) => l, + Poll::Pending => return Poll::Pending, + }; + *a += 1; + drop(a); + self.remaining -= 1; + } + } + } +} diff --git a/utshell-0.5.0/vendor/futures/tests/compat.rs b/utshell-0.5.0/vendor/futures/tests/compat.rs new file mode 100644 index 00000000..ac04a95e --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/compat.rs @@ -0,0 +1,16 @@ +#![cfg(feature = "compat")] +#![cfg(not(miri))] // Miri does not support epoll + +use futures::compat::Future01CompatExt; +use futures::prelude::*; +use std::time::Instant; +use tokio::runtime::Runtime; +use tokio::timer::Delay; + +#[test] +fn can_use_01_futures_in_a_03_future_running_on_a_01_executor() { + let f = async { Delay::new(Instant::now()).compat().await }; + + let mut runtime = Runtime::new().unwrap(); + runtime.block_on(f.boxed().compat()).unwrap(); +} diff --git a/utshell-0.5.0/vendor/futures/tests/eager_drop.rs b/utshell-0.5.0/vendor/futures/tests/eager_drop.rs new file mode 100644 index 00000000..99250777 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/eager_drop.rs @@ -0,0 +1,121 @@ +use futures::channel::oneshot; +use futures::future::{self, Future, FutureExt, TryFutureExt}; +use futures::task::{Context, Poll}; +use futures_test::future::FutureTestExt; +use pin_project::pin_project; +use std::pin::Pin; +use std::sync::mpsc; + +#[test] +fn map_ok() { + // The closure given to `map_ok` should have been dropped by the time `map` + // runs. + let (tx1, rx1) = mpsc::channel::<()>(); + let (tx2, rx2) = mpsc::channel::<()>(); + + future::ready::>(Err(1)) + .map_ok(move |_| { + let _tx1 = tx1; + panic!("should not run"); + }) + .map(move |_| { + assert!(rx1.recv().is_err()); + tx2.send(()).unwrap() + }) + .run_in_background(); + + rx2.recv().unwrap(); +} + +#[test] +fn map_err() { + // The closure given to `map_err` should have been dropped by the time `map` + // runs. + let (tx1, rx1) = mpsc::channel::<()>(); + let (tx2, rx2) = mpsc::channel::<()>(); + + future::ready::>(Ok(1)) + .map_err(move |_| { + let _tx1 = tx1; + panic!("should not run"); + }) + .map(move |_| { + assert!(rx1.recv().is_err()); + tx2.send(()).unwrap() + }) + .run_in_background(); + + rx2.recv().unwrap(); +} + +#[pin_project] +struct FutureData { + _data: T, + #[pin] + future: F, +} + +impl Future for FutureData { + type Output = F::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.project().future.poll(cx) + } +} + +#[test] +fn then_drops_eagerly() { + let (tx0, rx0) = oneshot::channel::<()>(); + let (tx1, rx1) = mpsc::channel::<()>(); + let (tx2, rx2) = mpsc::channel::<()>(); + + FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) } + .then(move |_| { + assert!(rx1.recv().is_err()); // tx1 should have been dropped + tx2.send(()).unwrap(); + future::ready(()) + }) + .run_in_background(); + + assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv()); + tx0.send(()).unwrap(); + rx2.recv().unwrap(); +} + +#[test] +fn and_then_drops_eagerly() { + let (tx0, rx0) = oneshot::channel::>(); + let (tx1, rx1) = mpsc::channel::<()>(); + let (tx2, rx2) = mpsc::channel::<()>(); + + FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) } + .and_then(move |_| { + assert!(rx1.recv().is_err()); // tx1 should have been dropped + tx2.send(()).unwrap(); + future::ready(Ok(())) + }) + .run_in_background(); + + assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv()); + tx0.send(Ok(())).unwrap(); + rx2.recv().unwrap(); +} + +#[test] +fn or_else_drops_eagerly() { + let (tx0, rx0) = oneshot::channel::>(); + let (tx1, rx1) = mpsc::channel::<()>(); + let (tx2, rx2) = mpsc::channel::<()>(); + + FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) } + .or_else(move |_| { + assert!(rx1.recv().is_err()); // tx1 should have been dropped + tx2.send(()).unwrap(); + future::ready::>(Ok(())) + }) + .run_in_background(); + + assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv()); + tx0.send(Err(())).unwrap(); + rx2.recv().unwrap(); +} diff --git a/utshell-0.5.0/vendor/futures/tests/eventual.rs b/utshell-0.5.0/vendor/futures/tests/eventual.rs new file mode 100644 index 00000000..57a49b24 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/eventual.rs @@ -0,0 +1,179 @@ +use futures::channel::oneshot; +use futures::executor::ThreadPool; +use futures::future::{self, ok, Future, FutureExt, TryFutureExt}; +use futures::task::SpawnExt; +use std::sync::mpsc; +use std::thread; + +fn run(future: F) { + let tp = ThreadPool::new().unwrap(); + tp.spawn(future.map(drop)).unwrap(); +} + +#[test] +fn join1() { + let (tx, rx) = mpsc::channel(); + run(future::try_join(ok::(1), ok(2)).map_ok(move |v| tx.send(v).unwrap())); + assert_eq!(rx.recv(), Ok((1, 2))); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn join2() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_join(p1, p2).map_ok(move |v| tx.send(v).unwrap())); + assert!(rx.try_recv().is_err()); + c1.send(1).unwrap(); + assert!(rx.try_recv().is_err()); + c2.send(2).unwrap(); + assert_eq!(rx.recv(), Ok((1, 2))); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn join3() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_join(p1, p2).map_err(move |_v| tx.send(1).unwrap())); + assert!(rx.try_recv().is_err()); + drop(c1); + assert_eq!(rx.recv(), Ok(1)); + assert!(rx.recv().is_err()); + drop(c2); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn join4() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_join(p1, p2).map_err(move |v| tx.send(v).unwrap())); + assert!(rx.try_recv().is_err()); + drop(c1); + assert!(rx.recv().is_ok()); + drop(c2); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn join5() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (c3, p3) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_join(future::try_join(p1, p2), p3).map_ok(move |v| tx.send(v).unwrap())); + assert!(rx.try_recv().is_err()); + c1.send(1).unwrap(); + assert!(rx.try_recv().is_err()); + c2.send(2).unwrap(); + assert!(rx.try_recv().is_err()); + c3.send(3).unwrap(); + assert_eq!(rx.recv(), Ok(((1, 2), 3))); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn select1() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_select(p1, p2).map_ok(move |v| tx.send(v).unwrap())); + assert!(rx.try_recv().is_err()); + c1.send(1).unwrap(); + let (v, p2) = rx.recv().unwrap().into_inner(); + assert_eq!(v, 1); + assert!(rx.recv().is_err()); + + let (tx, rx) = mpsc::channel(); + run(p2.map_ok(move |v| tx.send(v).unwrap())); + c2.send(2).unwrap(); + assert_eq!(rx.recv(), Ok(2)); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn select2() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_select(p1, p2).map_err(move |v| tx.send((1, v.into_inner().1)).unwrap())); + assert!(rx.try_recv().is_err()); + drop(c1); + let (v, p2) = rx.recv().unwrap(); + assert_eq!(v, 1); + assert!(rx.recv().is_err()); + + let (tx, rx) = mpsc::channel(); + run(p2.map_ok(move |v| tx.send(v).unwrap())); + c2.send(2).unwrap(); + assert_eq!(rx.recv(), Ok(2)); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn select3() { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + let (tx, rx) = mpsc::channel(); + run(future::try_select(p1, p2).map_err(move |v| tx.send((1, v.into_inner().1)).unwrap())); + assert!(rx.try_recv().is_err()); + drop(c1); + let (v, p2) = rx.recv().unwrap(); + assert_eq!(v, 1); + assert!(rx.recv().is_err()); + + let (tx, rx) = mpsc::channel(); + run(p2.map_err(move |_v| tx.send(2).unwrap())); + drop(c2); + assert_eq!(rx.recv(), Ok(2)); + assert!(rx.recv().is_err()); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} + +#[test] +fn select4() { + const N: usize = if cfg!(miri) { 100 } else { 10000 }; + + let (tx, rx) = mpsc::channel::>(); + + let t = thread::spawn(move || { + for c in rx { + c.send(1).unwrap(); + } + }); + + let (tx2, rx2) = mpsc::channel(); + for _ in 0..N { + let (c1, p1) = oneshot::channel::(); + let (c2, p2) = oneshot::channel::(); + + let tx3 = tx2.clone(); + run(future::try_select(p1, p2).map_ok(move |_| tx3.send(()).unwrap())); + tx.send(c1).unwrap(); + rx2.recv().unwrap(); + drop(c2); + } + drop(tx); + + t.join().unwrap(); + + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_abortable.rs b/utshell-0.5.0/vendor/futures/tests/future_abortable.rs new file mode 100644 index 00000000..e119f0b7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_abortable.rs @@ -0,0 +1,44 @@ +use futures::channel::oneshot; +use futures::executor::block_on; +use futures::future::{abortable, Aborted, FutureExt}; +use futures::task::{Context, Poll}; +use futures_test::task::new_count_waker; + +#[test] +fn abortable_works() { + let (_tx, a_rx) = oneshot::channel::<()>(); + let (abortable_rx, abort_handle) = abortable(a_rx); + + abort_handle.abort(); + assert!(abortable_rx.is_aborted()); + assert_eq!(Err(Aborted), block_on(abortable_rx)); +} + +#[test] +fn abortable_awakens() { + let (_tx, a_rx) = oneshot::channel::<()>(); + let (mut abortable_rx, abort_handle) = abortable(a_rx); + + let (waker, counter) = new_count_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(counter, 0); + assert_eq!(Poll::Pending, abortable_rx.poll_unpin(&mut cx)); + assert_eq!(counter, 0); + + abort_handle.abort(); + assert_eq!(counter, 1); + assert!(abortable_rx.is_aborted()); + assert_eq!(Poll::Ready(Err(Aborted)), abortable_rx.poll_unpin(&mut cx)); +} + +#[test] +fn abortable_resolves() { + let (tx, a_rx) = oneshot::channel::<()>(); + let (abortable_rx, _abort_handle) = abortable(a_rx); + + tx.send(()).unwrap(); + + assert!(!abortable_rx.is_aborted()); + assert_eq!(Ok(Ok(())), block_on(abortable_rx)); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_basic_combinators.rs b/utshell-0.5.0/vendor/futures/tests/future_basic_combinators.rs new file mode 100644 index 00000000..372ab48b --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_basic_combinators.rs @@ -0,0 +1,104 @@ +use futures::future::{self, FutureExt, TryFutureExt}; +use futures_test::future::FutureTestExt; +use std::sync::mpsc; + +#[test] +fn basic_future_combinators() { + let (tx1, rx) = mpsc::channel(); + let tx2 = tx1.clone(); + let tx3 = tx1.clone(); + + let fut = future::ready(1) + .then(move |x| { + tx1.send(x).unwrap(); // Send 1 + tx1.send(2).unwrap(); // Send 2 + future::ready(3) + }) + .map(move |x| { + tx2.send(x).unwrap(); // Send 3 + tx2.send(4).unwrap(); // Send 4 + 5 + }) + .map(move |x| { + tx3.send(x).unwrap(); // Send 5 + }); + + assert!(rx.try_recv().is_err()); // Not started yet + fut.run_in_background(); // Start it + for i in 1..=5 { + assert_eq!(rx.recv(), Ok(i)); + } // Check it + assert!(rx.recv().is_err()); // Should be done +} + +#[test] +fn basic_try_future_combinators() { + let (tx1, rx) = mpsc::channel(); + let tx2 = tx1.clone(); + let tx3 = tx1.clone(); + let tx4 = tx1.clone(); + let tx5 = tx1.clone(); + let tx6 = tx1.clone(); + let tx7 = tx1.clone(); + let tx8 = tx1.clone(); + let tx9 = tx1.clone(); + let tx10 = tx1.clone(); + + let fut = future::ready(Ok(1)) + .and_then(move |x: i32| { + tx1.send(x).unwrap(); // Send 1 + tx1.send(2).unwrap(); // Send 2 + future::ready(Ok(3)) + }) + .or_else(move |x: i32| { + tx2.send(x).unwrap(); // Should not run + tx2.send(-1).unwrap(); + future::ready(Ok(-1)) + }) + .map_ok(move |x: i32| { + tx3.send(x).unwrap(); // Send 3 + tx3.send(4).unwrap(); // Send 4 + 5 + }) + .map_err(move |x: i32| { + tx4.send(x).unwrap(); // Should not run + tx4.send(-1).unwrap(); + -1 + }) + .map(move |x: Result| { + tx5.send(x.unwrap()).unwrap(); // Send 5 + tx5.send(6).unwrap(); // Send 6 + Err(7) // Now return errors! + }) + .and_then(move |x: i32| { + tx6.send(x).unwrap(); // Should not run + tx6.send(-1).unwrap(); + future::ready(Err(-1)) + }) + .or_else(move |x: i32| { + tx7.send(x).unwrap(); // Send 7 + tx7.send(8).unwrap(); // Send 8 + future::ready(Err(9)) + }) + .map_ok(move |x: i32| { + tx8.send(x).unwrap(); // Should not run + tx8.send(-1).unwrap(); + -1 + }) + .map_err(move |x: i32| { + tx9.send(x).unwrap(); // Send 9 + tx9.send(10).unwrap(); // Send 10 + 11 + }) + .map(move |x: Result| { + tx10.send(x.err().unwrap()).unwrap(); // Send 11 + tx10.send(12).unwrap(); // Send 12 + }); + + assert!(rx.try_recv().is_err()); // Not started yet + fut.run_in_background(); // Start it + for i in 1..=12 { + assert_eq!(rx.recv(), Ok(i)); + } // Check it + assert!(rx.recv().is_err()); // Should be done +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_fuse.rs b/utshell-0.5.0/vendor/futures/tests/future_fuse.rs new file mode 100644 index 00000000..83f2c1ce --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_fuse.rs @@ -0,0 +1,12 @@ +use futures::future::{self, FutureExt}; +use futures::task::Context; +use futures_test::task::panic_waker; + +#[test] +fn fuse() { + let mut future = future::ready::(2).fuse(); + let waker = panic_waker(); + let mut cx = Context::from_waker(&waker); + assert!(future.poll_unpin(&mut cx).is_ready()); + assert!(future.poll_unpin(&mut cx).is_pending()); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_inspect.rs b/utshell-0.5.0/vendor/futures/tests/future_inspect.rs new file mode 100644 index 00000000..eacd1f78 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_inspect.rs @@ -0,0 +1,16 @@ +use futures::executor::block_on; +use futures::future::{self, FutureExt}; + +#[test] +fn smoke() { + let mut counter = 0; + + { + let work = future::ready::(40).inspect(|val| { + counter += *val; + }); + assert_eq!(block_on(work), 40); + } + + assert_eq!(counter, 40); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_join.rs b/utshell-0.5.0/vendor/futures/tests/future_join.rs new file mode 100644 index 00000000..f5df9d77 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_join.rs @@ -0,0 +1,32 @@ +use futures::executor::block_on; +use futures::future::Future; +use std::task::Poll; + +/// This tests verifies (through miri) that self-referencing +/// futures are not invalidated when joining them. +#[test] +fn futures_join_macro_self_referential() { + block_on(async { futures::join!(yield_now(), trouble()) }); +} + +async fn trouble() { + let lucky_number = 42; + let problematic_variable = &lucky_number; + + yield_now().await; + + // problematic dereference + let _ = { *problematic_variable }; +} + +fn yield_now() -> impl Future { + let mut yielded = false; + std::future::poll_fn(move |cx| { + if core::mem::replace(&mut yielded, true) { + Poll::Ready(()) + } else { + cx.waker().wake_by_ref(); + Poll::Pending + } + }) +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_join_all.rs b/utshell-0.5.0/vendor/futures/tests/future_join_all.rs new file mode 100644 index 00000000..44486e1c --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_join_all.rs @@ -0,0 +1,41 @@ +use futures::executor::block_on; +use futures::future::{join_all, ready, Future, JoinAll}; +use futures::pin_mut; +use std::fmt::Debug; + +#[track_caller] +fn assert_done(actual_fut: impl Future, expected: T) +where + T: PartialEq + Debug, +{ + pin_mut!(actual_fut); + let output = block_on(actual_fut); + assert_eq!(output, expected); +} + +#[test] +fn collect_collects() { + assert_done(join_all(vec![ready(1), ready(2)]), vec![1, 2]); + assert_done(join_all(vec![ready(1)]), vec![1]); + // REVIEW: should this be implemented? + // assert_done(join_all(Vec::::new()), vec![]); + + // TODO: needs more tests +} + +#[test] +fn join_all_iter_lifetime() { + // In futures-rs version 0.1, this function would fail to typecheck due to an overly + // conservative type parameterization of `JoinAll`. + fn sizes(bufs: Vec<&[u8]>) -> impl Future> { + let iter = bufs.into_iter().map(|b| ready::(b.len())); + join_all(iter) + } + + assert_done(sizes(vec![&[1, 2, 3], &[], &[0]]), vec![3_usize, 0, 1]); +} + +#[test] +fn join_all_from_iter() { + assert_done(vec![ready(1), ready(2)].into_iter().collect::>(), vec![1, 2]) +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_obj.rs b/utshell-0.5.0/vendor/futures/tests/future_obj.rs new file mode 100644 index 00000000..0e525346 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_obj.rs @@ -0,0 +1,33 @@ +use futures::future::{Future, FutureExt, FutureObj}; +use futures::task::{Context, Poll}; +use std::pin::Pin; + +#[test] +fn dropping_does_not_segfault() { + FutureObj::new(async { String::new() }.boxed()); +} + +#[test] +fn dropping_drops_the_future() { + let mut times_dropped = 0; + + struct Inc<'a>(&'a mut u32); + + impl Future for Inc<'_> { + type Output = (); + + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<()> { + unimplemented!() + } + } + + impl Drop for Inc<'_> { + fn drop(&mut self) { + *self.0 += 1; + } + } + + FutureObj::new(Inc(&mut times_dropped).boxed()); + + assert_eq!(times_dropped, 1); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_select_all.rs b/utshell-0.5.0/vendor/futures/tests/future_select_all.rs new file mode 100644 index 00000000..299b4790 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_select_all.rs @@ -0,0 +1,25 @@ +use futures::executor::block_on; +use futures::future::{ready, select_all}; +use std::collections::HashSet; + +#[test] +fn smoke() { + let v = vec![ready(1), ready(2), ready(3)]; + + let mut c = vec![1, 2, 3].into_iter().collect::>(); + + let (i, idx, v) = block_on(select_all(v)); + assert!(c.remove(&i)); + assert_eq!(idx, 0); + + let (i, idx, v) = block_on(select_all(v)); + assert!(c.remove(&i)); + assert_eq!(idx, 0); + + let (i, idx, v) = block_on(select_all(v)); + assert!(c.remove(&i)); + assert_eq!(idx, 0); + + assert!(c.is_empty()); + assert!(v.is_empty()); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_select_ok.rs b/utshell-0.5.0/vendor/futures/tests/future_select_ok.rs new file mode 100644 index 00000000..8aec0036 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_select_ok.rs @@ -0,0 +1,30 @@ +use futures::executor::block_on; +use futures::future::{err, ok, select_ok}; + +#[test] +fn ignore_err() { + let v = vec![err(1), err(2), ok(3), ok(4)]; + + let (i, v) = block_on(select_ok(v)).ok().unwrap(); + assert_eq!(i, 3); + + assert_eq!(v.len(), 1); + + let (i, v) = block_on(select_ok(v)).ok().unwrap(); + assert_eq!(i, 4); + + assert!(v.is_empty()); +} + +#[test] +fn last_err() { + let v = vec![ok(1), err(2), err(3)]; + + let (i, v) = block_on(select_ok(v)).ok().unwrap(); + assert_eq!(i, 1); + + assert_eq!(v.len(), 2); + + let i = block_on(select_ok(v)).err().unwrap(); + assert_eq!(i, 3); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_shared.rs b/utshell-0.5.0/vendor/futures/tests/future_shared.rs new file mode 100644 index 00000000..bd69c1d7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_shared.rs @@ -0,0 +1,273 @@ +use futures::channel::oneshot; +use futures::executor::{block_on, LocalPool}; +use futures::future::{self, FutureExt, LocalFutureObj, TryFutureExt}; +use futures::task::LocalSpawn; +use std::cell::{Cell, RefCell}; +use std::panic::AssertUnwindSafe; +use std::rc::Rc; +use std::task::Poll; +use std::thread; + +struct CountClone(Rc>); + +impl Clone for CountClone { + fn clone(&self) -> Self { + self.0.set(self.0.get() + 1); + Self(self.0.clone()) + } +} + +fn send_shared_oneshot_and_wait_on_multiple_threads(threads_number: u32) { + let (tx, rx) = oneshot::channel::(); + let f = rx.shared(); + let join_handles = (0..threads_number) + .map(|_| { + let cloned_future = f.clone(); + thread::spawn(move || { + assert_eq!(block_on(cloned_future).unwrap(), 6); + }) + }) + .collect::>(); + + tx.send(6).unwrap(); + + assert_eq!(block_on(f).unwrap(), 6); + for join_handle in join_handles { + join_handle.join().unwrap(); + } +} + +#[test] +fn one_thread() { + send_shared_oneshot_and_wait_on_multiple_threads(1); +} + +#[test] +fn two_threads() { + send_shared_oneshot_and_wait_on_multiple_threads(2); +} + +#[test] +fn many_threads() { + send_shared_oneshot_and_wait_on_multiple_threads(1000); +} + +#[test] +fn drop_on_one_task_ok() { + let (tx, rx) = oneshot::channel::(); + let f1 = rx.shared(); + let f2 = f1.clone(); + + let (tx2, rx2) = oneshot::channel::(); + + let t1 = thread::spawn(|| { + let f = future::try_select(f1.map_err(|_| ()), rx2.map_err(|_| ())); + drop(block_on(f)); + }); + + let (tx3, rx3) = oneshot::channel::(); + + let t2 = thread::spawn(|| { + let _ = block_on(f2.map_ok(|x| tx3.send(x).unwrap()).map_err(|_| ())); + }); + + tx2.send(11).unwrap(); // cancel `f1` + t1.join().unwrap(); + + tx.send(42).unwrap(); // Should cause `f2` and then `rx3` to get resolved. + let result = block_on(rx3).unwrap(); + assert_eq!(result, 42); + t2.join().unwrap(); +} + +#[test] +fn drop_in_poll() { + let slot1 = Rc::new(RefCell::new(None)); + let slot2 = slot1.clone(); + + let future1 = future::lazy(move |_| { + slot2.replace(None); // Drop future + 1 + }) + .shared(); + + let future2 = LocalFutureObj::new(Box::new(future1.clone())); + slot1.replace(Some(future2)); + + assert_eq!(block_on(future1), 1); +} + +#[test] +fn peek() { + let mut local_pool = LocalPool::new(); + let spawn = &mut local_pool.spawner(); + + let (tx0, rx0) = oneshot::channel::(); + let f1 = rx0.shared(); + let f2 = f1.clone(); + + // Repeated calls on the original or clone do not change the outcome. + for _ in 0..2 { + assert!(f1.peek().is_none()); + assert!(f2.peek().is_none()); + } + + // Completing the underlying future has no effect, because the value has not been `poll`ed in. + tx0.send(42).unwrap(); + for _ in 0..2 { + assert!(f1.peek().is_none()); + assert!(f2.peek().is_none()); + } + + // Once the Shared has been polled, the value is peekable on the clone. + spawn.spawn_local_obj(LocalFutureObj::new(Box::new(f1.map(|_| ())))).unwrap(); + local_pool.run(); + for _ in 0..2 { + assert_eq!(*f2.peek().unwrap(), Ok(42)); + } +} + +#[test] +fn downgrade() { + let (tx, rx) = oneshot::channel::(); + let shared = rx.shared(); + // Since there are outstanding `Shared`s, we can get a `WeakShared`. + let weak = shared.downgrade().unwrap(); + // It should upgrade fine right now. + let mut shared2 = weak.upgrade().unwrap(); + + tx.send(42).unwrap(); + assert_eq!(block_on(shared).unwrap(), 42); + + // We should still be able to get a new `WeakShared` and upgrade it + // because `shared2` is outstanding. + assert!(shared2.downgrade().is_some()); + assert!(weak.upgrade().is_some()); + + assert_eq!(block_on(&mut shared2).unwrap(), 42); + // Now that all `Shared`s have been exhausted, we should not be able + // to get a new `WeakShared` or upgrade an existing one. + assert!(weak.upgrade().is_none()); + assert!(shared2.downgrade().is_none()); +} + +#[test] +fn ptr_eq() { + use future::FusedFuture; + use std::collections::hash_map::DefaultHasher; + use std::hash::Hasher; + + let (tx, rx) = oneshot::channel::(); + let shared = rx.shared(); + let mut shared2 = shared.clone(); + let mut hasher = DefaultHasher::new(); + let mut hasher2 = DefaultHasher::new(); + + // Because these two futures share the same underlying future, + // `ptr_eq` should return true. + assert!(shared.ptr_eq(&shared2)); + // Equivalence relations are symmetric + assert!(shared2.ptr_eq(&shared)); + + // If `ptr_eq` returns true, they should hash to the same value. + shared.ptr_hash(&mut hasher); + shared2.ptr_hash(&mut hasher2); + assert_eq!(hasher.finish(), hasher2.finish()); + + tx.send(42).unwrap(); + assert_eq!(block_on(&mut shared2).unwrap(), 42); + + // Now that `shared2` has completed, `ptr_eq` should return false. + assert!(shared2.is_terminated()); + assert!(!shared.ptr_eq(&shared2)); + + // `ptr_eq` should continue to work for the other `Shared`. + let shared3 = shared.clone(); + let mut hasher3 = DefaultHasher::new(); + assert!(shared.ptr_eq(&shared3)); + + shared3.ptr_hash(&mut hasher3); + assert_eq!(hasher.finish(), hasher3.finish()); + + let (_tx, rx) = oneshot::channel::(); + let shared4 = rx.shared(); + + // And `ptr_eq` should return false for two futures that don't share + // the underlying future. + assert!(!shared.ptr_eq(&shared4)); +} + +#[test] +fn dont_clone_in_single_owner_shared_future() { + let counter = CountClone(Rc::new(Cell::new(0))); + let (tx, rx) = oneshot::channel(); + + let rx = rx.shared(); + + tx.send(counter).ok().unwrap(); + + assert_eq!(block_on(rx).unwrap().0.get(), 0); +} + +#[test] +fn dont_do_unnecessary_clones_on_output() { + let counter = CountClone(Rc::new(Cell::new(0))); + let (tx, rx) = oneshot::channel(); + + let rx = rx.shared(); + + tx.send(counter).ok().unwrap(); + + assert_eq!(block_on(rx.clone()).unwrap().0.get(), 1); + assert_eq!(block_on(rx.clone()).unwrap().0.get(), 2); + assert_eq!(block_on(rx).unwrap().0.get(), 2); +} + +#[test] +fn shared_future_that_wakes_itself_until_pending_is_returned() { + let proceed = Cell::new(false); + let fut = futures::future::poll_fn(|cx| { + if proceed.get() { + Poll::Ready(()) + } else { + cx.waker().wake_by_ref(); + Poll::Pending + } + }) + .shared(); + + // The join future can only complete if the second future gets a chance to run after the first + // has returned pending + assert_eq!(block_on(futures::future::join(fut, async { proceed.set(true) })), ((), ())); +} + +#[test] +#[should_panic(expected = "inner future panicked during poll")] +fn panic_while_poll() { + let fut = futures::future::poll_fn::(|_cx| panic!("test")).shared(); + + let fut_captured = fut.clone(); + std::panic::catch_unwind(AssertUnwindSafe(|| { + block_on(fut_captured); + })) + .unwrap_err(); + + block_on(fut); +} + +#[test] +#[should_panic(expected = "test_marker")] +fn poll_while_panic() { + struct S; + + impl Drop for S { + fn drop(&mut self) { + let fut = futures::future::ready(1).shared(); + assert_eq!(block_on(fut.clone()), 1); + assert_eq!(block_on(fut), 1); + } + } + + let _s = S {}; + panic!("test_marker"); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_try_flatten_stream.rs b/utshell-0.5.0/vendor/futures/tests/future_try_flatten_stream.rs new file mode 100644 index 00000000..82ae1baf --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_try_flatten_stream.rs @@ -0,0 +1,83 @@ +use futures::executor::block_on_stream; +use futures::future::{err, ok, TryFutureExt}; +use futures::sink::Sink; +use futures::stream::Stream; +use futures::stream::{self, StreamExt}; +use futures::task::{Context, Poll}; +use std::marker::PhantomData; +use std::pin::Pin; + +#[test] +fn successful_future() { + let stream_items = vec![17, 19]; + let future_of_a_stream = ok::<_, bool>(stream::iter(stream_items).map(Ok)); + + let stream = future_of_a_stream.try_flatten_stream(); + + let mut iter = block_on_stream(stream); + assert_eq!(Ok(17), iter.next().unwrap()); + assert_eq!(Ok(19), iter.next().unwrap()); + assert_eq!(None, iter.next()); +} + +#[test] +fn failed_future() { + struct PanickingStream { + _marker: PhantomData<(T, E)>, + } + + impl Stream for PanickingStream { + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + panic!() + } + } + + let future_of_a_stream = err::, _>(10); + let stream = future_of_a_stream.try_flatten_stream(); + let mut iter = block_on_stream(stream); + assert_eq!(Err(10), iter.next().unwrap()); + assert_eq!(None, iter.next()); +} + +#[test] +fn assert_impls() { + struct StreamSink(PhantomData<(T, E, Item)>); + + impl Stream for StreamSink { + type Item = Result; + fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + panic!() + } + } + + impl Sink for StreamSink { + type Error = E; + fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + panic!() + } + fn start_send(self: Pin<&mut Self>, _: Item) -> Result<(), Self::Error> { + panic!() + } + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + panic!() + } + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + panic!() + } + } + + fn assert_stream(_: &S) {} + fn assert_sink, Item>(_: &S) {} + fn assert_stream_sink, Item>(_: &S) {} + + let s = ok(StreamSink::<(), (), ()>(PhantomData)).try_flatten_stream(); + assert_stream(&s); + assert_sink(&s); + assert_stream_sink(&s); + let s = ok(StreamSink::<(), (), ()>(PhantomData)).flatten_sink(); + assert_stream(&s); + assert_sink(&s); + assert_stream_sink(&s); +} diff --git a/utshell-0.5.0/vendor/futures/tests/future_try_join_all.rs b/utshell-0.5.0/vendor/futures/tests/future_try_join_all.rs new file mode 100644 index 00000000..9a824872 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/future_try_join_all.rs @@ -0,0 +1,46 @@ +use futures::executor::block_on; +use futures::pin_mut; +use futures_util::future::{err, ok, try_join_all, TryJoinAll}; +use std::fmt::Debug; +use std::future::Future; + +#[track_caller] +fn assert_done(actual_fut: impl Future, expected: T) +where + T: PartialEq + Debug, +{ + pin_mut!(actual_fut); + let output = block_on(actual_fut); + assert_eq!(output, expected); +} + +#[test] +fn collect_collects() { + assert_done(try_join_all(vec![ok(1), ok(2)]), Ok::<_, usize>(vec![1, 2])); + assert_done(try_join_all(vec![ok(1), err(2)]), Err(2)); + assert_done(try_join_all(vec![ok(1)]), Ok::<_, usize>(vec![1])); + // REVIEW: should this be implemented? + // assert_done(try_join_all(Vec::::new()), Ok(vec![])); + + // TODO: needs more tests +} + +#[test] +fn try_join_all_iter_lifetime() { + // In futures-rs version 0.1, this function would fail to typecheck due to an overly + // conservative type parameterization of `TryJoinAll`. + fn sizes(bufs: Vec<&[u8]>) -> impl Future, ()>> { + let iter = bufs.into_iter().map(|b| ok::(b.len())); + try_join_all(iter) + } + + assert_done(sizes(vec![&[1, 2, 3], &[], &[0]]), Ok(vec![3_usize, 0, 1])); +} + +#[test] +fn try_join_all_from_iter() { + assert_done( + vec![ok(1), ok(2)].into_iter().collect::>(), + Ok::<_, usize>(vec![1, 2]), + ) +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_buf_reader.rs b/utshell-0.5.0/vendor/futures/tests/io_buf_reader.rs new file mode 100644 index 00000000..717297cc --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_buf_reader.rs @@ -0,0 +1,432 @@ +use futures::executor::block_on; +use futures::future::{Future, FutureExt}; +use futures::io::{ + AllowStdIo, AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, + BufReader, SeekFrom, +}; +use futures::pin_mut; +use futures::task::{Context, Poll}; +use futures_test::task::noop_context; +use pin_project::pin_project; +use std::cmp; +use std::io; +use std::pin::Pin; + +// helper for maybe_pending_* tests +fn run(mut f: F) -> F::Output { + let mut cx = noop_context(); + loop { + if let Poll::Ready(x) = f.poll_unpin(&mut cx) { + return x; + } + } +} + +// https://github.com/rust-lang/futures-rs/pull/2489#discussion_r697865719 +#[pin_project(!Unpin)] +struct Cursor { + #[pin] + inner: futures::io::Cursor, +} + +impl Cursor { + fn new(inner: T) -> Self { + Self { inner: futures::io::Cursor::new(inner) } + } +} + +impl AsyncRead for Cursor<&[u8]> { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + self.project().inner.poll_read(cx, buf) + } +} + +impl AsyncBufRead for Cursor<&[u8]> { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().inner.poll_fill_buf(cx) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + self.project().inner.consume(amt) + } +} + +impl AsyncSeek for Cursor<&[u8]> { + fn poll_seek( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + self.project().inner.poll_seek(cx, pos) + } +} + +struct MaybePending<'a> { + inner: &'a [u8], + ready_read: bool, + ready_fill_buf: bool, +} + +impl<'a> MaybePending<'a> { + fn new(inner: &'a [u8]) -> Self { + Self { inner, ready_read: false, ready_fill_buf: false } + } +} + +impl AsyncRead for MaybePending<'_> { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + if self.ready_read { + self.ready_read = false; + Pin::new(&mut self.inner).poll_read(cx, buf) + } else { + self.ready_read = true; + Poll::Pending + } + } +} + +impl AsyncBufRead for MaybePending<'_> { + fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + if self.ready_fill_buf { + self.ready_fill_buf = false; + if self.inner.is_empty() { + return Poll::Ready(Ok(&[])); + } + let len = cmp::min(2, self.inner.len()); + Poll::Ready(Ok(&self.inner[0..len])) + } else { + self.ready_fill_buf = true; + Poll::Pending + } + } + + fn consume(mut self: Pin<&mut Self>, amt: usize) { + self.inner = &self.inner[amt..]; + } +} + +#[test] +fn test_buffered_reader() { + block_on(async { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(2, inner); + + let mut buf = [0, 0, 0]; + let nread = reader.read(&mut buf).await.unwrap(); + assert_eq!(nread, 3); + assert_eq!(buf, [5, 6, 7]); + assert_eq!(reader.buffer(), []); + + let mut buf = [0, 0]; + let nread = reader.read(&mut buf).await.unwrap(); + assert_eq!(nread, 2); + assert_eq!(buf, [0, 1]); + assert_eq!(reader.buffer(), []); + + let mut buf = [0]; + let nread = reader.read(&mut buf).await.unwrap(); + assert_eq!(nread, 1); + assert_eq!(buf, [2]); + assert_eq!(reader.buffer(), [3]); + + let mut buf = [0, 0, 0]; + let nread = reader.read(&mut buf).await.unwrap(); + assert_eq!(nread, 1); + assert_eq!(buf, [3, 0, 0]); + assert_eq!(reader.buffer(), []); + + let nread = reader.read(&mut buf).await.unwrap(); + assert_eq!(nread, 1); + assert_eq!(buf, [4, 0, 0]); + assert_eq!(reader.buffer(), []); + + assert_eq!(reader.read(&mut buf).await.unwrap(), 0); + }); +} + +#[test] +fn test_buffered_reader_seek() { + block_on(async { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let reader = BufReader::with_capacity(2, Cursor::new(inner)); + pin_mut!(reader); + + assert_eq!(reader.seek(SeekFrom::Start(3)).await.unwrap(), 3); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[0, 1][..]); + assert!(reader.seek(SeekFrom::Current(i64::MIN)).await.is_err()); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[0, 1][..]); + assert_eq!(reader.seek(SeekFrom::Current(1)).await.unwrap(), 4); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[1, 2][..]); + reader.as_mut().consume(1); + assert_eq!(reader.seek(SeekFrom::Current(-2)).await.unwrap(), 3); + }); +} + +#[test] +fn test_buffered_reader_seek_relative() { + block_on(async { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let reader = BufReader::with_capacity(2, Cursor::new(inner)); + pin_mut!(reader); + + assert!(reader.as_mut().seek_relative(3).await.is_ok()); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[0, 1][..]); + assert!(reader.as_mut().seek_relative(0).await.is_ok()); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[0, 1][..]); + assert!(reader.as_mut().seek_relative(1).await.is_ok()); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[1][..]); + assert!(reader.as_mut().seek_relative(-1).await.is_ok()); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[0, 1][..]); + assert!(reader.as_mut().seek_relative(2).await.is_ok()); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[2, 3][..]); + }); +} + +#[test] +fn test_buffered_reader_invalidated_after_read() { + block_on(async { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let reader = BufReader::with_capacity(3, Cursor::new(inner)); + pin_mut!(reader); + + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[5, 6, 7][..]); + reader.as_mut().consume(3); + + let mut buffer = [0, 0, 0, 0, 0]; + assert_eq!(reader.read(&mut buffer).await.unwrap(), 5); + assert_eq!(buffer, [0, 1, 2, 3, 4]); + + assert!(reader.as_mut().seek_relative(-2).await.is_ok()); + let mut buffer = [0, 0]; + assert_eq!(reader.read(&mut buffer).await.unwrap(), 2); + assert_eq!(buffer, [3, 4]); + }); +} + +#[test] +fn test_buffered_reader_invalidated_after_seek() { + block_on(async { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let reader = BufReader::with_capacity(3, Cursor::new(inner)); + pin_mut!(reader); + + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[5, 6, 7][..]); + reader.as_mut().consume(3); + + assert!(reader.seek(SeekFrom::Current(5)).await.is_ok()); + + assert!(reader.as_mut().seek_relative(-2).await.is_ok()); + let mut buffer = [0, 0]; + assert_eq!(reader.read(&mut buffer).await.unwrap(), 2); + assert_eq!(buffer, [3, 4]); + }); +} + +#[test] +fn test_buffered_reader_seek_underflow() { + // gimmick reader that yields its position modulo 256 for each byte + struct PositionReader { + pos: u64, + } + impl io::Read for PositionReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let len = buf.len(); + for x in buf { + *x = self.pos as u8; + self.pos = self.pos.wrapping_add(1); + } + Ok(len) + } + } + impl io::Seek for PositionReader { + fn seek(&mut self, pos: SeekFrom) -> io::Result { + match pos { + SeekFrom::Start(n) => { + self.pos = n; + } + SeekFrom::Current(n) => { + self.pos = self.pos.wrapping_add(n as u64); + } + SeekFrom::End(n) => { + self.pos = u64::MAX.wrapping_add(n as u64); + } + } + Ok(self.pos) + } + } + + block_on(async { + let reader = BufReader::with_capacity(5, AllowStdIo::new(PositionReader { pos: 0 })); + pin_mut!(reader); + assert_eq!(reader.as_mut().fill_buf().await.unwrap(), &[0, 1, 2, 3, 4][..]); + assert_eq!(reader.seek(SeekFrom::End(-5)).await.unwrap(), u64::MAX - 5); + assert_eq!(reader.as_mut().fill_buf().await.unwrap().len(), 5); + // the following seek will require two underlying seeks + let expected = 9_223_372_036_854_775_802; + assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).await.unwrap(), expected); + assert_eq!(reader.as_mut().fill_buf().await.unwrap().len(), 5); + // seeking to 0 should empty the buffer. + assert_eq!(reader.seek(SeekFrom::Current(0)).await.unwrap(), expected); + assert_eq!(reader.get_ref().get_ref().pos, expected); + }); +} + +#[test] +fn test_short_reads() { + /// A dummy reader intended at testing short-reads propagation. + struct ShortReader { + lengths: Vec, + } + + impl io::Read for ShortReader { + fn read(&mut self, _: &mut [u8]) -> io::Result { + if self.lengths.is_empty() { + Ok(0) + } else { + Ok(self.lengths.remove(0)) + } + } + } + + block_on(async { + let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] }; + let mut reader = BufReader::new(AllowStdIo::new(inner)); + let mut buf = [0, 0]; + assert_eq!(reader.read(&mut buf).await.unwrap(), 0); + assert_eq!(reader.read(&mut buf).await.unwrap(), 1); + assert_eq!(reader.read(&mut buf).await.unwrap(), 2); + assert_eq!(reader.read(&mut buf).await.unwrap(), 0); + assert_eq!(reader.read(&mut buf).await.unwrap(), 1); + assert_eq!(reader.read(&mut buf).await.unwrap(), 0); + assert_eq!(reader.read(&mut buf).await.unwrap(), 0); + }); +} + +#[test] +fn maybe_pending() { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(2, MaybePending::new(inner)); + + let mut buf = [0, 0, 0]; + let nread = run(reader.read(&mut buf)); + assert_eq!(nread.unwrap(), 3); + assert_eq!(buf, [5, 6, 7]); + assert_eq!(reader.buffer(), []); + + let mut buf = [0, 0]; + let nread = run(reader.read(&mut buf)); + assert_eq!(nread.unwrap(), 2); + assert_eq!(buf, [0, 1]); + assert_eq!(reader.buffer(), []); + + let mut buf = [0]; + let nread = run(reader.read(&mut buf)); + assert_eq!(nread.unwrap(), 1); + assert_eq!(buf, [2]); + assert_eq!(reader.buffer(), [3]); + + let mut buf = [0, 0, 0]; + let nread = run(reader.read(&mut buf)); + assert_eq!(nread.unwrap(), 1); + assert_eq!(buf, [3, 0, 0]); + assert_eq!(reader.buffer(), []); + + let nread = run(reader.read(&mut buf)); + assert_eq!(nread.unwrap(), 1); + assert_eq!(buf, [4, 0, 0]); + assert_eq!(reader.buffer(), []); + + assert_eq!(run(reader.read(&mut buf)).unwrap(), 0); +} + +#[test] +fn maybe_pending_buf_read() { + let inner = MaybePending::new(&[0, 1, 2, 3, 1, 0]); + let mut reader = BufReader::with_capacity(2, inner); + let mut v = Vec::new(); + run(reader.read_until(3, &mut v)).unwrap(); + assert_eq!(v, [0, 1, 2, 3]); + v.clear(); + run(reader.read_until(1, &mut v)).unwrap(); + assert_eq!(v, [1]); + v.clear(); + run(reader.read_until(8, &mut v)).unwrap(); + assert_eq!(v, [0]); + v.clear(); + run(reader.read_until(9, &mut v)).unwrap(); + assert_eq!(v, []); +} + +// https://github.com/rust-lang/futures-rs/pull/1573#discussion_r281162309 +#[test] +fn maybe_pending_seek() { + #[pin_project] + struct MaybePendingSeek<'a> { + #[pin] + inner: Cursor<&'a [u8]>, + ready: bool, + } + + impl<'a> MaybePendingSeek<'a> { + fn new(inner: &'a [u8]) -> Self { + Self { inner: Cursor::new(inner), ready: true } + } + } + + impl AsyncRead for MaybePendingSeek<'_> { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + self.project().inner.poll_read(cx, buf) + } + } + + impl AsyncBufRead for MaybePendingSeek<'_> { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().inner.poll_fill_buf(cx) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + self.project().inner.consume(amt) + } + } + + impl AsyncSeek for MaybePendingSeek<'_> { + fn poll_seek( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + if self.ready { + *self.as_mut().project().ready = false; + self.project().inner.poll_seek(cx, pos) + } else { + *self.project().ready = true; + Poll::Pending + } + } + } + + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let reader = BufReader::with_capacity(2, MaybePendingSeek::new(inner)); + pin_mut!(reader); + + assert_eq!(run(reader.seek(SeekFrom::Current(3))).ok(), Some(3)); + assert_eq!(run(reader.as_mut().fill_buf()).ok(), Some(&[0, 1][..])); + assert_eq!(run(reader.seek(SeekFrom::Current(i64::MIN))).ok(), None); + assert_eq!(run(reader.as_mut().fill_buf()).ok(), Some(&[0, 1][..])); + assert_eq!(run(reader.seek(SeekFrom::Current(1))).ok(), Some(4)); + assert_eq!(run(reader.as_mut().fill_buf()).ok(), Some(&[1, 2][..])); + Pin::new(&mut reader).consume(1); + assert_eq!(run(reader.seek(SeekFrom::Current(-2))).ok(), Some(3)); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_buf_writer.rs b/utshell-0.5.0/vendor/futures/tests/io_buf_writer.rs new file mode 100644 index 00000000..b264cd54 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_buf_writer.rs @@ -0,0 +1,239 @@ +use futures::executor::block_on; +use futures::future::{Future, FutureExt}; +use futures::io::{ + AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, BufWriter, Cursor, SeekFrom, +}; +use futures::task::{Context, Poll}; +use futures_test::task::noop_context; +use std::io; +use std::pin::Pin; + +struct MaybePending { + inner: Vec, + ready: bool, +} + +impl MaybePending { + fn new(inner: Vec) -> Self { + Self { inner, ready: false } + } +} + +impl AsyncWrite for MaybePending { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + if self.ready { + self.ready = false; + Pin::new(&mut self.inner).poll_write(cx, buf) + } else { + self.ready = true; + Poll::Pending + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.inner).poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.inner).poll_close(cx) + } +} + +fn run(mut f: F) -> F::Output { + let mut cx = noop_context(); + loop { + if let Poll::Ready(x) = f.poll_unpin(&mut cx) { + return x; + } + } +} + +#[test] +fn buf_writer() { + let mut writer = BufWriter::with_capacity(2, Vec::new()); + + block_on(writer.write(&[0, 1])).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1]); + + block_on(writer.write(&[2])).unwrap(); + assert_eq!(writer.buffer(), [2]); + assert_eq!(*writer.get_ref(), [0, 1]); + + block_on(writer.write(&[3])).unwrap(); + assert_eq!(writer.buffer(), [2, 3]); + assert_eq!(*writer.get_ref(), [0, 1]); + + block_on(writer.flush()).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); + + block_on(writer.write(&[4])).unwrap(); + block_on(writer.write(&[5])).unwrap(); + assert_eq!(writer.buffer(), [4, 5]); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); + + block_on(writer.write(&[6])).unwrap(); + assert_eq!(writer.buffer(), [6]); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]); + + block_on(writer.write(&[7, 8])).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]); + + block_on(writer.write(&[9, 10, 11])).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); + + block_on(writer.flush()).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); +} + +#[test] +fn buf_writer_inner_flushes() { + let mut w = BufWriter::with_capacity(3, Vec::new()); + block_on(w.write(&[0, 1])).unwrap(); + assert_eq!(*w.get_ref(), []); + block_on(w.flush()).unwrap(); + let w = w.into_inner(); + assert_eq!(w, [0, 1]); +} + +#[test] +fn buf_writer_seek() { + // FIXME: when https://github.com/rust-lang/futures-rs/issues/1510 fixed, + // use `Vec::new` instead of `vec![0; 8]`. + let mut w = BufWriter::with_capacity(3, Cursor::new(vec![0; 8])); + block_on(w.write_all(&[0, 1, 2, 3, 4, 5])).unwrap(); + block_on(w.write_all(&[6, 7])).unwrap(); + assert_eq!(block_on(w.seek(SeekFrom::Current(0))).ok(), Some(8)); + assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]); + assert_eq!(block_on(w.seek(SeekFrom::Start(2))).ok(), Some(2)); + block_on(w.write_all(&[8, 9])).unwrap(); + block_on(w.flush()).unwrap(); + assert_eq!(&w.into_inner().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]); +} + +#[test] +fn maybe_pending_buf_writer() { + let mut writer = BufWriter::with_capacity(2, MaybePending::new(Vec::new())); + + run(writer.write(&[0, 1])).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(&writer.get_ref().inner, &[0, 1]); + + run(writer.write(&[2])).unwrap(); + assert_eq!(writer.buffer(), [2]); + assert_eq!(&writer.get_ref().inner, &[0, 1]); + + run(writer.write(&[3])).unwrap(); + assert_eq!(writer.buffer(), [2, 3]); + assert_eq!(&writer.get_ref().inner, &[0, 1]); + + run(writer.flush()).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3]); + + run(writer.write(&[4])).unwrap(); + run(writer.write(&[5])).unwrap(); + assert_eq!(writer.buffer(), [4, 5]); + assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3]); + + run(writer.write(&[6])).unwrap(); + assert_eq!(writer.buffer(), [6]); + assert_eq!(writer.get_ref().inner, &[0, 1, 2, 3, 4, 5]); + + run(writer.write(&[7, 8])).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8]); + + run(writer.write(&[9, 10, 11])).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); + + run(writer.flush()).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); +} + +#[test] +fn maybe_pending_buf_writer_inner_flushes() { + let mut w = BufWriter::with_capacity(3, MaybePending::new(Vec::new())); + run(w.write(&[0, 1])).unwrap(); + assert_eq!(&w.get_ref().inner, &[]); + run(w.flush()).unwrap(); + let w = w.into_inner().inner; + assert_eq!(w, [0, 1]); +} + +#[test] +fn maybe_pending_buf_writer_seek() { + struct MaybePendingSeek { + inner: Cursor>, + ready_write: bool, + ready_seek: bool, + } + + impl MaybePendingSeek { + fn new(inner: Vec) -> Self { + Self { inner: Cursor::new(inner), ready_write: false, ready_seek: false } + } + } + + impl AsyncWrite for MaybePendingSeek { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + if self.ready_write { + self.ready_write = false; + Pin::new(&mut self.inner).poll_write(cx, buf) + } else { + self.ready_write = true; + Poll::Pending + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.inner).poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.inner).poll_close(cx) + } + } + + impl AsyncSeek for MaybePendingSeek { + fn poll_seek( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + pos: SeekFrom, + ) -> Poll> { + if self.ready_seek { + self.ready_seek = false; + Pin::new(&mut self.inner).poll_seek(cx, pos) + } else { + self.ready_seek = true; + Poll::Pending + } + } + } + + // FIXME: when https://github.com/rust-lang/futures-rs/issues/1510 fixed, + // use `Vec::new` instead of `vec![0; 8]`. + let mut w = BufWriter::with_capacity(3, MaybePendingSeek::new(vec![0; 8])); + run(w.write_all(&[0, 1, 2, 3, 4, 5])).unwrap(); + run(w.write_all(&[6, 7])).unwrap(); + assert_eq!(run(w.seek(SeekFrom::Current(0))).ok(), Some(8)); + assert_eq!(&w.get_ref().inner.get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]); + assert_eq!(run(w.seek(SeekFrom::Start(2))).ok(), Some(2)); + run(w.write_all(&[8, 9])).unwrap(); + run(w.flush()).unwrap(); + assert_eq!(&w.into_inner().inner.into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_cursor.rs b/utshell-0.5.0/vendor/futures/tests/io_cursor.rs new file mode 100644 index 00000000..435ea5a1 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_cursor.rs @@ -0,0 +1,30 @@ +use assert_matches::assert_matches; +use futures::executor::block_on; +use futures::future::lazy; +use futures::io::{AsyncWrite, Cursor}; +use futures::task::Poll; +use std::pin::Pin; + +#[test] +fn cursor_asyncwrite_vec() { + let mut cursor = Cursor::new(vec![0; 5]); + block_on(lazy(|cx| { + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[1, 2]), Poll::Ready(Ok(2))); + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[3, 4]), Poll::Ready(Ok(2))); + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[5, 6]), Poll::Ready(Ok(2))); + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[6, 7]), Poll::Ready(Ok(2))); + })); + assert_eq!(cursor.into_inner(), [1, 2, 3, 4, 5, 6, 6, 7]); +} + +#[test] +fn cursor_asyncwrite_box() { + let mut cursor = Cursor::new(vec![0; 5].into_boxed_slice()); + block_on(lazy(|cx| { + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[1, 2]), Poll::Ready(Ok(2))); + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[3, 4]), Poll::Ready(Ok(2))); + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[5, 6]), Poll::Ready(Ok(1))); + assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[6, 7]), Poll::Ready(Ok(0))); + })); + assert_eq!(&*cursor.into_inner(), [1, 2, 3, 4, 5]); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_line_writer.rs b/utshell-0.5.0/vendor/futures/tests/io_line_writer.rs new file mode 100644 index 00000000..b483e0ff --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_line_writer.rs @@ -0,0 +1,73 @@ +use futures::executor::block_on; +use futures::io::{AsyncWriteExt, LineWriter}; +use std::io; + +#[test] +fn line_writer() { + let mut writer = LineWriter::new(Vec::new()); + + block_on(writer.write(&[0])).unwrap(); + assert_eq!(*writer.get_ref(), []); + + block_on(writer.write(&[1])).unwrap(); + assert_eq!(*writer.get_ref(), []); + + block_on(writer.flush()).unwrap(); + assert_eq!(*writer.get_ref(), [0, 1]); + + block_on(writer.write(&[0, b'\n', 1, b'\n', 2])).unwrap(); + assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']); + + block_on(writer.flush()).unwrap(); + assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]); + + block_on(writer.write(&[3, b'\n'])).unwrap(); + assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']); +} + +#[test] +fn line_vectored() { + let mut line_writer = LineWriter::new(Vec::new()); + assert_eq!( + block_on(line_writer.write_vectored(&[ + io::IoSlice::new(&[]), + io::IoSlice::new(b"\n"), + io::IoSlice::new(&[]), + io::IoSlice::new(b"a"), + ])) + .unwrap(), + 2 + ); + assert_eq!(line_writer.get_ref(), b"\n"); + + assert_eq!( + block_on(line_writer.write_vectored(&[ + io::IoSlice::new(&[]), + io::IoSlice::new(b"b"), + io::IoSlice::new(&[]), + io::IoSlice::new(b"a"), + io::IoSlice::new(&[]), + io::IoSlice::new(b"c"), + ])) + .unwrap(), + 3 + ); + assert_eq!(line_writer.get_ref(), b"\n"); + block_on(line_writer.flush()).unwrap(); + assert_eq!(line_writer.get_ref(), b"\nabac"); + assert_eq!(block_on(line_writer.write_vectored(&[])).unwrap(), 0); + + assert_eq!( + block_on(line_writer.write_vectored(&[ + io::IoSlice::new(&[]), + io::IoSlice::new(&[]), + io::IoSlice::new(&[]), + io::IoSlice::new(&[]), + ])) + .unwrap(), + 0 + ); + + assert_eq!(block_on(line_writer.write_vectored(&[io::IoSlice::new(b"a\nb")])).unwrap(), 3); + assert_eq!(line_writer.get_ref(), b"\nabaca\nb"); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_lines.rs b/utshell-0.5.0/vendor/futures/tests/io_lines.rs new file mode 100644 index 00000000..5ce01a69 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_lines.rs @@ -0,0 +1,60 @@ +use futures::executor::block_on; +use futures::future::{Future, FutureExt}; +use futures::io::{AsyncBufReadExt, Cursor}; +use futures::stream::{self, StreamExt, TryStreamExt}; +use futures::task::Poll; +use futures_test::io::AsyncReadTestExt; +use futures_test::task::noop_context; + +fn run(mut f: F) -> F::Output { + let mut cx = noop_context(); + loop { + if let Poll::Ready(x) = f.poll_unpin(&mut cx) { + return x; + } + } +} + +macro_rules! block_on_next { + ($expr:expr) => { + block_on($expr.next()).unwrap().unwrap() + }; +} + +macro_rules! run_next { + ($expr:expr) => { + run($expr.next()).unwrap().unwrap() + }; +} + +#[test] +fn lines() { + let buf = Cursor::new(&b"12\r"[..]); + let mut s = buf.lines(); + assert_eq!(block_on_next!(s), "12\r".to_string()); + assert!(block_on(s.next()).is_none()); + + let buf = Cursor::new(&b"12\r\n\n"[..]); + let mut s = buf.lines(); + assert_eq!(block_on_next!(s), "12".to_string()); + assert_eq!(block_on_next!(s), "".to_string()); + assert!(block_on(s.next()).is_none()); +} + +#[test] +fn maybe_pending() { + let buf = + stream::iter(vec![&b"12"[..], &b"\r"[..]]).map(Ok).into_async_read().interleave_pending(); + let mut s = buf.lines(); + assert_eq!(run_next!(s), "12\r".to_string()); + assert!(run(s.next()).is_none()); + + let buf = stream::iter(vec![&b"12"[..], &b"\r\n"[..], &b"\n"[..]]) + .map(Ok) + .into_async_read() + .interleave_pending(); + let mut s = buf.lines(); + assert_eq!(run_next!(s), "12".to_string()); + assert_eq!(run_next!(s), "".to_string()); + assert!(run(s.next()).is_none()); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_read.rs b/utshell-0.5.0/vendor/futures/tests/io_read.rs new file mode 100644 index 00000000..d39a6ea7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_read.rs @@ -0,0 +1,64 @@ +use futures::io::AsyncRead; +use futures_test::task::panic_context; +use std::io; +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct MockReader { + fun: Box Poll>>, +} + +impl MockReader { + fn new(fun: impl FnMut(&mut [u8]) -> Poll> + 'static) -> Self { + Self { fun: Box::new(fun) } + } +} + +impl AsyncRead for MockReader { + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + (self.get_mut().fun)(buf) + } +} + +/// Verifies that the default implementation of `poll_read_vectored` +/// calls `poll_read` with an empty slice if no buffers are provided. +#[test] +fn read_vectored_no_buffers() { + let mut reader = MockReader::new(|buf| { + assert_eq!(buf, b""); + Err(io::ErrorKind::BrokenPipe.into()).into() + }); + let cx = &mut panic_context(); + let bufs = &mut []; + + let res = Pin::new(&mut reader).poll_read_vectored(cx, bufs); + let res = res.map_err(|e| e.kind()); + assert_eq!(res, Poll::Ready(Err(io::ErrorKind::BrokenPipe))) +} + +/// Verifies that the default implementation of `poll_read_vectored` +/// calls `poll_read` with the first non-empty buffer. +#[test] +fn read_vectored_first_non_empty() { + let mut reader = MockReader::new(|buf| { + assert_eq!(buf.len(), 4); + buf.copy_from_slice(b"four"); + Poll::Ready(Ok(4)) + }); + let cx = &mut panic_context(); + let mut buf = [0; 4]; + let bufs = &mut [ + io::IoSliceMut::new(&mut []), + io::IoSliceMut::new(&mut []), + io::IoSliceMut::new(&mut buf), + ]; + + let res = Pin::new(&mut reader).poll_read_vectored(cx, bufs); + let res = res.map_err(|e| e.kind()); + assert_eq!(res, Poll::Ready(Ok(4))); + assert_eq!(buf, b"four"[..]); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_read_exact.rs b/utshell-0.5.0/vendor/futures/tests/io_read_exact.rs new file mode 100644 index 00000000..6582e50b --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_read_exact.rs @@ -0,0 +1,17 @@ +use futures::executor::block_on; +use futures::io::AsyncReadExt; + +#[test] +fn read_exact() { + let mut reader: &[u8] = &[1, 2, 3, 4, 5]; + let mut out = [0u8; 3]; + + let res = block_on(reader.read_exact(&mut out)); // read 3 bytes out + assert!(res.is_ok()); + assert_eq!(out, [1, 2, 3]); + assert_eq!(reader.len(), 2); + + let res = block_on(reader.read_exact(&mut out)); // read another 3 bytes, but only 2 bytes left + assert!(res.is_err()); + assert_eq!(reader.len(), 0); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_read_line.rs b/utshell-0.5.0/vendor/futures/tests/io_read_line.rs new file mode 100644 index 00000000..88a87792 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_read_line.rs @@ -0,0 +1,58 @@ +use futures::executor::block_on; +use futures::future::{Future, FutureExt}; +use futures::io::{AsyncBufReadExt, Cursor}; +use futures::stream::{self, StreamExt, TryStreamExt}; +use futures::task::Poll; +use futures_test::io::AsyncReadTestExt; +use futures_test::task::noop_context; + +fn run(mut f: F) -> F::Output { + let mut cx = noop_context(); + loop { + if let Poll::Ready(x) = f.poll_unpin(&mut cx) { + return x; + } + } +} + +#[test] +fn read_line() { + let mut buf = Cursor::new(b"12"); + let mut v = String::new(); + assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 2); + assert_eq!(v, "12"); + + let mut buf = Cursor::new(b"12\n\n"); + let mut v = String::new(); + assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 3); + assert_eq!(v, "12\n"); + v.clear(); + assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 1); + assert_eq!(v, "\n"); + v.clear(); + assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 0); + assert_eq!(v, ""); +} + +#[test] +fn maybe_pending() { + let mut buf = b"12".interleave_pending(); + let mut v = String::new(); + assert_eq!(run(buf.read_line(&mut v)).unwrap(), 2); + assert_eq!(v, "12"); + + let mut buf = + stream::iter(vec![&b"12"[..], &b"\n\n"[..]]).map(Ok).into_async_read().interleave_pending(); + let mut v = String::new(); + assert_eq!(run(buf.read_line(&mut v)).unwrap(), 3); + assert_eq!(v, "12\n"); + v.clear(); + assert_eq!(run(buf.read_line(&mut v)).unwrap(), 1); + assert_eq!(v, "\n"); + v.clear(); + assert_eq!(run(buf.read_line(&mut v)).unwrap(), 0); + assert_eq!(v, ""); + v.clear(); + assert_eq!(run(buf.read_line(&mut v)).unwrap(), 0); + assert_eq!(v, ""); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_read_to_end.rs b/utshell-0.5.0/vendor/futures/tests/io_read_to_end.rs new file mode 100644 index 00000000..7122511f --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_read_to_end.rs @@ -0,0 +1,65 @@ +use futures::{ + executor::block_on, + io::{self, AsyncRead, AsyncReadExt}, + task::{Context, Poll}, +}; +use std::pin::Pin; + +#[test] +#[should_panic(expected = "assertion failed: n <= buf.len()")] +fn issue2310() { + struct MyRead { + first: bool, + } + + impl MyRead { + fn new() -> Self { + MyRead { first: false } + } + } + + impl AsyncRead for MyRead { + fn poll_read( + mut self: Pin<&mut Self>, + _cx: &mut Context, + _buf: &mut [u8], + ) -> Poll> { + Poll::Ready(if !self.first { + self.first = true; + // First iteration: return more than the buffer size + Ok(64) + } else { + // Second iteration: indicate that we are done + Ok(0) + }) + } + } + + struct VecWrapper { + inner: Vec, + } + + impl VecWrapper { + fn new() -> Self { + VecWrapper { inner: Vec::new() } + } + } + + impl Drop for VecWrapper { + fn drop(&mut self) { + // Observe uninitialized bytes + println!("{:?}", &self.inner); + // Overwrite heap contents + for b in &mut self.inner { + *b = 0x90; + } + } + } + + block_on(async { + let mut vec = VecWrapper::new(); + let mut read = MyRead::new(); + + read.read_to_end(&mut vec.inner).await.unwrap(); + }) +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_read_to_string.rs b/utshell-0.5.0/vendor/futures/tests/io_read_to_string.rs new file mode 100644 index 00000000..ae6aaa21 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_read_to_string.rs @@ -0,0 +1,44 @@ +use futures::executor::block_on; +use futures::future::{Future, FutureExt}; +use futures::io::{AsyncReadExt, Cursor}; +use futures::stream::{self, StreamExt, TryStreamExt}; +use futures::task::Poll; +use futures_test::io::AsyncReadTestExt; +use futures_test::task::noop_context; + +#[test] +fn read_to_string() { + let mut c = Cursor::new(&b""[..]); + let mut v = String::new(); + assert_eq!(block_on(c.read_to_string(&mut v)).unwrap(), 0); + assert_eq!(v, ""); + + let mut c = Cursor::new(&b"1"[..]); + let mut v = String::new(); + assert_eq!(block_on(c.read_to_string(&mut v)).unwrap(), 1); + assert_eq!(v, "1"); + + let mut c = Cursor::new(&b"\xff"[..]); + let mut v = String::new(); + assert!(block_on(c.read_to_string(&mut v)).is_err()); +} + +#[test] +fn interleave_pending() { + fn run(mut f: F) -> F::Output { + let mut cx = noop_context(); + loop { + if let Poll::Ready(x) = f.poll_unpin(&mut cx) { + return x; + } + } + } + let mut buf = stream::iter(vec![&b"12"[..], &b"33"[..], &b"3"[..]]) + .map(Ok) + .into_async_read() + .interleave_pending(); + + let mut v = String::new(); + assert_eq!(run(buf.read_to_string(&mut v)).unwrap(), 5); + assert_eq!(v, "12333"); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_read_until.rs b/utshell-0.5.0/vendor/futures/tests/io_read_until.rs new file mode 100644 index 00000000..71f857f4 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_read_until.rs @@ -0,0 +1,60 @@ +use futures::executor::block_on; +use futures::future::{Future, FutureExt}; +use futures::io::{AsyncBufReadExt, Cursor}; +use futures::stream::{self, StreamExt, TryStreamExt}; +use futures::task::Poll; +use futures_test::io::AsyncReadTestExt; +use futures_test::task::noop_context; + +fn run(mut f: F) -> F::Output { + let mut cx = noop_context(); + loop { + if let Poll::Ready(x) = f.poll_unpin(&mut cx) { + return x; + } + } +} + +#[test] +fn read_until() { + let mut buf = Cursor::new(b"12"); + let mut v = Vec::new(); + assert_eq!(block_on(buf.read_until(b'3', &mut v)).unwrap(), 2); + assert_eq!(v, b"12"); + + let mut buf = Cursor::new(b"1233"); + let mut v = Vec::new(); + assert_eq!(block_on(buf.read_until(b'3', &mut v)).unwrap(), 3); + assert_eq!(v, b"123"); + v.truncate(0); + assert_eq!(block_on(buf.read_until(b'3', &mut v)).unwrap(), 1); + assert_eq!(v, b"3"); + v.truncate(0); + assert_eq!(block_on(buf.read_until(b'3', &mut v)).unwrap(), 0); + assert_eq!(v, []); +} + +#[test] +fn maybe_pending() { + let mut buf = b"12".interleave_pending(); + let mut v = Vec::new(); + assert_eq!(run(buf.read_until(b'3', &mut v)).unwrap(), 2); + assert_eq!(v, b"12"); + + let mut buf = stream::iter(vec![&b"12"[..], &b"33"[..], &b"3"[..]]) + .map(Ok) + .into_async_read() + .interleave_pending(); + let mut v = Vec::new(); + assert_eq!(run(buf.read_until(b'3', &mut v)).unwrap(), 3); + assert_eq!(v, b"123"); + v.clear(); + assert_eq!(run(buf.read_until(b'3', &mut v)).unwrap(), 1); + assert_eq!(v, b"3"); + v.clear(); + assert_eq!(run(buf.read_until(b'3', &mut v)).unwrap(), 1); + assert_eq!(v, b"3"); + v.clear(); + assert_eq!(run(buf.read_until(b'3', &mut v)).unwrap(), 0); + assert_eq!(v, []); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_window.rs b/utshell-0.5.0/vendor/futures/tests/io_window.rs new file mode 100644 index 00000000..8f0d48bc --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_window.rs @@ -0,0 +1,30 @@ +#![allow(clippy::reversed_empty_ranges)] // This is intentional. + +use futures::io::Window; + +#[test] +fn set() { + let mut buffer = Window::new(&[1, 2, 3]); + buffer.set(..3); + assert_eq!(buffer.as_ref(), &[1, 2, 3]); + buffer.set(3..3); + assert_eq!(buffer.as_ref(), &[]); + buffer.set(3..=2); // == 3..3 + assert_eq!(buffer.as_ref(), &[]); + buffer.set(0..2); + assert_eq!(buffer.as_ref(), &[1, 2]); +} + +#[test] +#[should_panic] +fn set_panic_out_of_bounds() { + let mut buffer = Window::new(&[1, 2, 3]); + buffer.set(2..4); +} + +#[test] +#[should_panic] +fn set_panic_start_is_greater_than_end() { + let mut buffer = Window::new(&[1, 2, 3]); + buffer.set(3..2); +} diff --git a/utshell-0.5.0/vendor/futures/tests/io_write.rs b/utshell-0.5.0/vendor/futures/tests/io_write.rs new file mode 100644 index 00000000..6af27553 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/io_write.rs @@ -0,0 +1,65 @@ +use futures::io::AsyncWrite; +use futures_test::task::panic_context; +use std::io; +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct MockWriter { + fun: Box Poll>>, +} + +impl MockWriter { + fn new(fun: impl FnMut(&[u8]) -> Poll> + 'static) -> Self { + Self { fun: Box::new(fun) } + } +} + +impl AsyncWrite for MockWriter { + fn poll_write( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + (self.get_mut().fun)(buf) + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + panic!() + } + + fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + panic!() + } +} + +/// Verifies that the default implementation of `poll_write_vectored` +/// calls `poll_write` with an empty slice if no buffers are provided. +#[test] +fn write_vectored_no_buffers() { + let mut writer = MockWriter::new(|buf| { + assert_eq!(buf, b""); + Err(io::ErrorKind::BrokenPipe.into()).into() + }); + let cx = &mut panic_context(); + let bufs = &mut []; + + let res = Pin::new(&mut writer).poll_write_vectored(cx, bufs); + let res = res.map_err(|e| e.kind()); + assert_eq!(res, Poll::Ready(Err(io::ErrorKind::BrokenPipe))) +} + +/// Verifies that the default implementation of `poll_write_vectored` +/// calls `poll_write` with the first non-empty buffer. +#[test] +fn write_vectored_first_non_empty() { + let mut writer = MockWriter::new(|buf| { + assert_eq!(buf, b"four"); + Poll::Ready(Ok(4)) + }); + let cx = &mut panic_context(); + let bufs = &mut [io::IoSlice::new(&[]), io::IoSlice::new(&[]), io::IoSlice::new(b"four")]; + + let res = Pin::new(&mut writer).poll_write_vectored(cx, bufs); + let res = res.map_err(|e| e.kind()); + assert_eq!(res, Poll::Ready(Ok(4))); +} diff --git a/utshell-0.5.0/vendor/futures/tests/lock_mutex.rs b/utshell-0.5.0/vendor/futures/tests/lock_mutex.rs new file mode 100644 index 00000000..c15e76bd --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/lock_mutex.rs @@ -0,0 +1,69 @@ +use futures::channel::mpsc; +use futures::executor::{block_on, ThreadPool}; +use futures::future::{ready, FutureExt}; +use futures::lock::Mutex; +use futures::stream::StreamExt; +use futures::task::{Context, SpawnExt}; +use futures_test::future::FutureTestExt; +use futures_test::task::{new_count_waker, panic_context}; +use std::sync::Arc; + +#[test] +fn mutex_acquire_uncontested() { + let mutex = Mutex::new(()); + for _ in 0..10 { + assert!(mutex.lock().poll_unpin(&mut panic_context()).is_ready()); + } +} + +#[test] +fn mutex_wakes_waiters() { + let mutex = Mutex::new(()); + let (waker, counter) = new_count_waker(); + let lock = mutex.lock().poll_unpin(&mut panic_context()); + assert!(lock.is_ready()); + + let mut cx = Context::from_waker(&waker); + let mut waiter = mutex.lock(); + assert!(waiter.poll_unpin(&mut cx).is_pending()); + assert_eq!(counter, 0); + + drop(lock); + + assert_eq!(counter, 1); + assert!(waiter.poll_unpin(&mut panic_context()).is_ready()); +} + +#[test] +fn mutex_contested() { + { + let (tx, mut rx) = mpsc::unbounded(); + let pool = ThreadPool::builder().pool_size(16).create().unwrap(); + + let tx = Arc::new(tx); + let mutex = Arc::new(Mutex::new(0)); + + let num_tasks = 1000; + for _ in 0..num_tasks { + let tx = tx.clone(); + let mutex = mutex.clone(); + pool.spawn(async move { + let mut lock = mutex.lock().await; + ready(()).pending_once().await; + *lock += 1; + tx.unbounded_send(()).unwrap(); + drop(lock); + }) + .unwrap(); + } + + block_on(async { + for _ in 0..num_tasks { + rx.next().await.unwrap(); + } + let lock = mutex.lock().await; + assert_eq!(num_tasks, *lock); + }); + } + std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +} diff --git a/utshell-0.5.0/vendor/futures/tests/macro_comma_support.rs b/utshell-0.5.0/vendor/futures/tests/macro_comma_support.rs new file mode 100644 index 00000000..85871e98 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/macro_comma_support.rs @@ -0,0 +1,43 @@ +use futures::{ + executor::block_on, + future::{self, FutureExt}, + join, ready, + task::Poll, + try_join, +}; + +#[test] +fn ready() { + block_on(future::poll_fn(|_| { + ready!(Poll::Ready(()),); + Poll::Ready(()) + })) +} + +#[test] +fn poll() { + use futures::poll; + + block_on(async { + let _ = poll!(async {}.boxed(),); + }) +} + +#[test] +fn join() { + block_on(async { + let future1 = async { 1 }; + let future2 = async { 2 }; + join!(future1, future2,); + }) +} + +#[test] +fn try_join() { + block_on(async { + let future1 = async { 1 }.never_error(); + let future2 = async { 2 }.never_error(); + try_join!(future1, future2,) + }) + .unwrap(); +} diff --git a/utshell-0.5.0/vendor/futures/tests/object_safety.rs b/utshell-0.5.0/vendor/futures/tests/object_safety.rs new file mode 100644 index 00000000..30c892f5 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/object_safety.rs @@ -0,0 +1,49 @@ +fn assert_is_object_safe() {} + +#[test] +fn future() { + // `FutureExt`, `TryFutureExt` and `UnsafeFutureObj` are not object safe. + use futures::future::{FusedFuture, Future, TryFuture}; + + assert_is_object_safe::<&dyn Future>(); + assert_is_object_safe::<&dyn FusedFuture>(); + assert_is_object_safe::<&dyn TryFuture>>(); +} + +#[test] +fn stream() { + // `StreamExt` and `TryStreamExt` are not object safe. + use futures::stream::{FusedStream, Stream, TryStream}; + + assert_is_object_safe::<&dyn Stream>(); + assert_is_object_safe::<&dyn FusedStream>(); + assert_is_object_safe::<&dyn TryStream>>(); +} + +#[test] +fn sink() { + // `SinkExt` is not object safe. + use futures::sink::Sink; + + assert_is_object_safe::<&dyn Sink<(), Error = ()>>(); +} + +#[test] +fn io() { + // `AsyncReadExt`, `AsyncWriteExt`, `AsyncSeekExt` and `AsyncBufReadExt` are not object safe. + use futures::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; + + assert_is_object_safe::<&dyn AsyncRead>(); + assert_is_object_safe::<&dyn AsyncWrite>(); + assert_is_object_safe::<&dyn AsyncSeek>(); + assert_is_object_safe::<&dyn AsyncBufRead>(); +} + +#[test] +fn task() { + // `ArcWake`, `SpawnExt` and `LocalSpawnExt` are not object safe. + use futures::task::{LocalSpawn, Spawn}; + + assert_is_object_safe::<&dyn Spawn>(); + assert_is_object_safe::<&dyn LocalSpawn>(); +} diff --git a/utshell-0.5.0/vendor/futures/tests/oneshot.rs b/utshell-0.5.0/vendor/futures/tests/oneshot.rs new file mode 100644 index 00000000..34b78a33 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/oneshot.rs @@ -0,0 +1,78 @@ +use futures::channel::oneshot; +use futures::future::{FutureExt, TryFutureExt}; +use futures_test::future::FutureTestExt; +use std::sync::mpsc; +use std::thread; + +#[test] +fn oneshot_send1() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + + let t = thread::spawn(|| tx1.send(1).unwrap()); + rx1.map_ok(move |x| tx2.send(x)).run_in_background(); + assert_eq!(1, rx2.recv().unwrap()); + t.join().unwrap(); +} + +#[test] +fn oneshot_send2() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + + thread::spawn(|| tx1.send(1).unwrap()).join().unwrap(); + rx1.map_ok(move |x| tx2.send(x).unwrap()).run_in_background(); + assert_eq!(1, rx2.recv().unwrap()); +} + +#[test] +fn oneshot_send3() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + + rx1.map_ok(move |x| tx2.send(x).unwrap()).run_in_background(); + thread::spawn(|| tx1.send(1).unwrap()).join().unwrap(); + assert_eq!(1, rx2.recv().unwrap()); +} + +#[test] +fn oneshot_drop_tx1() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + + drop(tx1); + rx1.map(move |result| tx2.send(result).unwrap()).run_in_background(); + + assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap()); +} + +#[test] +fn oneshot_drop_tx2() { + let (tx1, rx1) = oneshot::channel::(); + let (tx2, rx2) = mpsc::channel(); + + let t = thread::spawn(|| drop(tx1)); + rx1.map(move |result| tx2.send(result).unwrap()).run_in_background(); + t.join().unwrap(); + + assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap()); +} + +#[test] +fn oneshot_drop_rx() { + let (tx, rx) = oneshot::channel::(); + drop(rx); + assert_eq!(Err(2), tx.send(2)); +} + +#[test] +fn oneshot_debug() { + let (tx, rx) = oneshot::channel::(); + assert_eq!(format!("{:?}", tx), "Sender { complete: false }"); + assert_eq!(format!("{:?}", rx), "Receiver { complete: false }"); + drop(rx); + assert_eq!(format!("{:?}", tx), "Sender { complete: true }"); + let (tx, rx) = oneshot::channel::(); + drop(tx); + assert_eq!(format!("{:?}", rx), "Receiver { complete: true }"); +} diff --git a/utshell-0.5.0/vendor/futures/tests/ready_queue.rs b/utshell-0.5.0/vendor/futures/tests/ready_queue.rs new file mode 100644 index 00000000..c19d6259 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/ready_queue.rs @@ -0,0 +1,148 @@ +use futures::channel::oneshot; +use futures::executor::{block_on, block_on_stream}; +use futures::future; +use futures::stream::{FuturesUnordered, StreamExt}; +use futures::task::Poll; +use futures_test::task::noop_context; +use std::panic::{self, AssertUnwindSafe}; +use std::sync::{Arc, Barrier}; +use std::thread; + +#[test] +fn basic_usage() { + block_on(future::lazy(move |cx| { + let mut queue = FuturesUnordered::new(); + let (tx1, rx1) = oneshot::channel(); + let (tx2, rx2) = oneshot::channel(); + let (tx3, rx3) = oneshot::channel(); + + queue.push(rx1); + queue.push(rx2); + queue.push(rx3); + + assert!(!queue.poll_next_unpin(cx).is_ready()); + + tx2.send("hello").unwrap(); + + assert_eq!(Poll::Ready(Some(Ok("hello"))), queue.poll_next_unpin(cx)); + assert!(!queue.poll_next_unpin(cx).is_ready()); + + tx1.send("world").unwrap(); + tx3.send("world2").unwrap(); + + assert_eq!(Poll::Ready(Some(Ok("world"))), queue.poll_next_unpin(cx)); + assert_eq!(Poll::Ready(Some(Ok("world2"))), queue.poll_next_unpin(cx)); + assert_eq!(Poll::Ready(None), queue.poll_next_unpin(cx)); + })); +} + +#[test] +fn resolving_errors() { + block_on(future::lazy(move |cx| { + let mut queue = FuturesUnordered::new(); + let (tx1, rx1) = oneshot::channel(); + let (tx2, rx2) = oneshot::channel(); + let (tx3, rx3) = oneshot::channel(); + + queue.push(rx1); + queue.push(rx2); + queue.push(rx3); + + assert!(!queue.poll_next_unpin(cx).is_ready()); + + drop(tx2); + + assert_eq!(Poll::Ready(Some(Err(oneshot::Canceled))), queue.poll_next_unpin(cx)); + assert!(!queue.poll_next_unpin(cx).is_ready()); + + drop(tx1); + tx3.send("world2").unwrap(); + + assert_eq!(Poll::Ready(Some(Err(oneshot::Canceled))), queue.poll_next_unpin(cx)); + assert_eq!(Poll::Ready(Some(Ok("world2"))), queue.poll_next_unpin(cx)); + assert_eq!(Poll::Ready(None), queue.poll_next_unpin(cx)); + })); +} + +#[test] +fn dropping_ready_queue() { + block_on(future::lazy(move |_| { + let queue = FuturesUnordered::new(); + let (mut tx1, rx1) = oneshot::channel::<()>(); + let (mut tx2, rx2) = oneshot::channel::<()>(); + let (mut tx3, rx3) = oneshot::channel::<()>(); + + queue.push(rx1); + queue.push(rx2); + queue.push(rx3); + + { + let cx = &mut noop_context(); + assert!(!tx1.poll_canceled(cx).is_ready()); + assert!(!tx2.poll_canceled(cx).is_ready()); + assert!(!tx3.poll_canceled(cx).is_ready()); + + drop(queue); + + assert!(tx1.poll_canceled(cx).is_ready()); + assert!(tx2.poll_canceled(cx).is_ready()); + assert!(tx3.poll_canceled(cx).is_ready()); + } + })); +} + +#[test] +fn stress() { + const ITER: usize = if cfg!(miri) { 30 } else { 300 }; + + for i in 0..ITER { + let n = (i % 10) + 1; + + let mut queue = FuturesUnordered::new(); + + for _ in 0..5 { + let barrier = Arc::new(Barrier::new(n + 1)); + + for num in 0..n { + let barrier = barrier.clone(); + let (tx, rx) = oneshot::channel(); + + queue.push(rx); + + thread::spawn(move || { + barrier.wait(); + tx.send(num).unwrap(); + }); + } + + barrier.wait(); + + let mut sync = block_on_stream(queue); + + let mut rx: Vec<_> = (&mut sync).take(n).map(|res| res.unwrap()).collect(); + + assert_eq!(rx.len(), n); + + rx.sort_unstable(); + + for (i, x) in rx.into_iter().enumerate() { + assert_eq!(i, x); + } + + queue = sync.into_inner(); + } + } +} + +#[test] +fn panicking_future_dropped() { + block_on(future::lazy(move |cx| { + let mut queue = FuturesUnordered::new(); + queue.push(future::poll_fn(|_| -> Poll> { panic!() })); + + let r = panic::catch_unwind(AssertUnwindSafe(|| queue.poll_next_unpin(cx))); + assert!(r.is_err()); + assert!(queue.is_empty()); + assert_eq!(Poll::Ready(None), queue.poll_next_unpin(cx)); + })); +} diff --git a/utshell-0.5.0/vendor/futures/tests/recurse.rs b/utshell-0.5.0/vendor/futures/tests/recurse.rs new file mode 100644 index 00000000..d81753c9 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/recurse.rs @@ -0,0 +1,25 @@ +use futures::executor::block_on; +use futures::future::{self, BoxFuture, FutureExt}; +use std::sync::mpsc; +use std::thread; + +#[test] +fn lots() { + #[cfg(not(futures_sanitizer))] + const N: i32 = 1_000; + #[cfg(futures_sanitizer)] // If N is many, asan reports stack-overflow: https://gist.github.com/taiki-e/099446d21cbec69d4acbacf7a9646136 + const N: i32 = 100; + + fn do_it(input: (i32, i32)) -> BoxFuture<'static, i32> { + let (n, x) = input; + if n == 0 { + future::ready(x).boxed() + } else { + future::ready((n - 1, x + n)).then(do_it).boxed() + } + } + + let (tx, rx) = mpsc::channel(); + thread::spawn(|| block_on(do_it((N, 0)).map(move |x| tx.send(x).unwrap()))); + assert_eq!((0..=N).sum::(), rx.recv().unwrap()); +} diff --git a/utshell-0.5.0/vendor/futures/tests/sink.rs b/utshell-0.5.0/vendor/futures/tests/sink.rs new file mode 100644 index 00000000..5b691e74 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/sink.rs @@ -0,0 +1,554 @@ +use futures::channel::{mpsc, oneshot}; +use futures::executor::block_on; +use futures::future::{self, poll_fn, Future, FutureExt, TryFutureExt}; +use futures::never::Never; +use futures::ready; +use futures::sink::{self, Sink, SinkErrInto, SinkExt}; +use futures::stream::{self, Stream, StreamExt}; +use futures::task::{self, ArcWake, Context, Poll, Waker}; +use futures_test::task::panic_context; +use std::cell::{Cell, RefCell}; +use std::collections::VecDeque; +use std::fmt; +use std::mem; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + +fn sassert_next(s: &mut S, item: S::Item) +where + S: Stream + Unpin, + S::Item: Eq + fmt::Debug, +{ + match s.poll_next_unpin(&mut panic_context()) { + Poll::Ready(None) => panic!("stream is at its end"), + Poll::Ready(Some(e)) => assert_eq!(e, item), + Poll::Pending => panic!("stream wasn't ready"), + } +} + +fn unwrap(x: Poll>) -> T { + match x { + Poll::Ready(Ok(x)) => x, + Poll::Ready(Err(_)) => panic!("Poll::Ready(Err(_))"), + Poll::Pending => panic!("Poll::Pending"), + } +} + +// An Unpark struct that records unpark events for inspection +struct Flag(AtomicBool); + +impl Flag { + fn new() -> Arc { + Arc::new(Self(AtomicBool::new(false))) + } + + fn take(&self) -> bool { + self.0.swap(false, Ordering::SeqCst) + } + + fn set(&self, v: bool) { + self.0.store(v, Ordering::SeqCst) + } +} + +impl ArcWake for Flag { + fn wake_by_ref(arc_self: &Arc) { + arc_self.set(true) + } +} + +fn flag_cx(f: F) -> R +where + F: FnOnce(Arc, &mut Context<'_>) -> R, +{ + let flag = Flag::new(); + let waker = task::waker_ref(&flag); + let cx = &mut Context::from_waker(&waker); + f(flag.clone(), cx) +} + +// Sends a value on an i32 channel sink +struct StartSendFut + Unpin, Item: Unpin>(Option, Option); + +impl + Unpin, Item: Unpin> StartSendFut { + fn new(sink: S, item: Item) -> Self { + Self(Some(sink), Some(item)) + } +} + +impl + Unpin, Item: Unpin> Future for StartSendFut { + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let Self(inner, item) = self.get_mut(); + { + let mut inner = inner.as_mut().unwrap(); + ready!(Pin::new(&mut inner).poll_ready(cx))?; + Pin::new(&mut inner).start_send(item.take().unwrap())?; + } + Poll::Ready(Ok(inner.take().unwrap())) + } +} + +// Immediately accepts all requests to start pushing, but completion is managed +// by manually flushing +struct ManualFlush { + data: Vec, + waiting_tasks: Vec, +} + +impl Sink> for ManualFlush { + type Error = (); + + fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn start_send(mut self: Pin<&mut Self>, item: Option) -> Result<(), Self::Error> { + if let Some(item) = item { + self.data.push(item); + } else { + self.force_flush(); + } + Ok(()) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.data.is_empty() { + Poll::Ready(Ok(())) + } else { + self.waiting_tasks.push(cx.waker().clone()); + Poll::Pending + } + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.poll_flush(cx) + } +} + +impl ManualFlush { + fn new() -> Self { + Self { data: Vec::new(), waiting_tasks: Vec::new() } + } + + fn force_flush(&mut self) -> Vec { + for task in self.waiting_tasks.drain(..) { + task.wake() + } + mem::take(&mut self.data) + } +} + +struct ManualAllow { + data: Vec, + allow: Rc, +} + +struct Allow { + flag: Cell, + tasks: RefCell>, +} + +impl Allow { + fn new() -> Self { + Self { flag: Cell::new(false), tasks: RefCell::new(Vec::new()) } + } + + fn check(&self, cx: &mut Context<'_>) -> bool { + if self.flag.get() { + true + } else { + self.tasks.borrow_mut().push(cx.waker().clone()); + false + } + } + + fn start(&self) { + self.flag.set(true); + let mut tasks = self.tasks.borrow_mut(); + for task in tasks.drain(..) { + task.wake(); + } + } +} + +impl Sink for ManualAllow { + type Error = (); + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.allow.check(cx) { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + + fn start_send(mut self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> { + self.data.push(item); + Ok(()) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } +} + +fn manual_allow() -> (ManualAllow, Rc) { + let allow = Rc::new(Allow::new()); + let manual_allow = ManualAllow { data: Vec::new(), allow: allow.clone() }; + (manual_allow, allow) +} + +#[test] +fn either_sink() { + let mut s = + if true { Vec::::new().left_sink() } else { VecDeque::::new().right_sink() }; + + Pin::new(&mut s).start_send(0).unwrap(); +} + +#[test] +fn vec_sink() { + let mut v = Vec::new(); + Pin::new(&mut v).start_send(0).unwrap(); + Pin::new(&mut v).start_send(1).unwrap(); + assert_eq!(v, vec![0, 1]); + block_on(v.flush()).unwrap(); + assert_eq!(v, vec![0, 1]); +} + +#[test] +fn vecdeque_sink() { + let mut deque = VecDeque::new(); + Pin::new(&mut deque).start_send(2).unwrap(); + Pin::new(&mut deque).start_send(3).unwrap(); + + assert_eq!(deque.pop_front(), Some(2)); + assert_eq!(deque.pop_front(), Some(3)); + assert_eq!(deque.pop_front(), None); +} + +#[test] +fn send() { + let mut v = Vec::new(); + + block_on(v.send(0)).unwrap(); + assert_eq!(v, vec![0]); + + block_on(v.send(1)).unwrap(); + assert_eq!(v, vec![0, 1]); + + block_on(v.send(2)).unwrap(); + assert_eq!(v, vec![0, 1, 2]); +} + +#[test] +fn send_all() { + let mut v = Vec::new(); + + block_on(v.send_all(&mut stream::iter(vec![0, 1]).map(Ok))).unwrap(); + assert_eq!(v, vec![0, 1]); + + block_on(v.send_all(&mut stream::iter(vec![2, 3]).map(Ok))).unwrap(); + assert_eq!(v, vec![0, 1, 2, 3]); + + block_on(v.send_all(&mut stream::iter(vec![4, 5]).map(Ok))).unwrap(); + assert_eq!(v, vec![0, 1, 2, 3, 4, 5]); +} + +// Test that `start_send` on an `mpsc` channel does indeed block when the +// channel is full +#[test] +fn mpsc_blocking_start_send() { + let (mut tx, mut rx) = mpsc::channel::(0); + + block_on(future::lazy(|_| { + tx.start_send(0).unwrap(); + + flag_cx(|flag, cx| { + let mut task = StartSendFut::new(tx, 1); + + assert!(task.poll_unpin(cx).is_pending()); + assert!(!flag.take()); + sassert_next(&mut rx, 0); + assert!(flag.take()); + unwrap(task.poll_unpin(cx)); + assert!(!flag.take()); + sassert_next(&mut rx, 1); + }) + })); +} + +// test `flush` by using `with` to make the first insertion into a sink block +// until a oneshot is completed +#[test] +fn with_flush() { + let (tx, rx) = oneshot::channel(); + let mut block = rx.boxed(); + let mut sink = Vec::new().with(|elem| { + mem::replace(&mut block, future::ok(()).boxed()) + .map_ok(move |()| elem + 1) + .map_err(|_| -> Never { panic!() }) + }); + + assert_eq!(Pin::new(&mut sink).start_send(0).ok(), Some(())); + + flag_cx(|flag, cx| { + let mut task = sink.flush(); + assert!(task.poll_unpin(cx).is_pending()); + tx.send(()).unwrap(); + assert!(flag.take()); + + unwrap(task.poll_unpin(cx)); + + block_on(sink.send(1)).unwrap(); + assert_eq!(sink.get_ref(), &[1, 2]); + }) +} + +// test simple use of with to change data +#[test] +fn with_as_map() { + let mut sink = Vec::new().with(|item| future::ok::(item * 2)); + block_on(sink.send(0)).unwrap(); + block_on(sink.send(1)).unwrap(); + block_on(sink.send(2)).unwrap(); + assert_eq!(sink.get_ref(), &[0, 2, 4]); +} + +// test simple use of with_flat_map +#[test] +fn with_flat_map() { + let mut sink = Vec::new().with_flat_map(|item| stream::iter(vec![item; item]).map(Ok)); + block_on(sink.send(0)).unwrap(); + block_on(sink.send(1)).unwrap(); + block_on(sink.send(2)).unwrap(); + block_on(sink.send(3)).unwrap(); + assert_eq!(sink.get_ref(), &[1, 2, 2, 3, 3, 3]); +} + +// Check that `with` propagates `poll_ready` to the inner sink. +// Regression test for the issue #1834. +#[test] +fn with_propagates_poll_ready() { + let (tx, mut rx) = mpsc::channel::(0); + let mut tx = tx.with(|item: i32| future::ok::(item + 10)); + + block_on(future::lazy(|_| { + flag_cx(|flag, cx| { + let mut tx = Pin::new(&mut tx); + + // Should be ready for the first item. + assert_eq!(tx.as_mut().poll_ready(cx), Poll::Ready(Ok(()))); + assert_eq!(tx.as_mut().start_send(0), Ok(())); + + // Should be ready for the second item only after the first one is received. + assert_eq!(tx.as_mut().poll_ready(cx), Poll::Pending); + assert!(!flag.take()); + sassert_next(&mut rx, 10); + assert!(flag.take()); + assert_eq!(tx.as_mut().poll_ready(cx), Poll::Ready(Ok(()))); + assert_eq!(tx.as_mut().start_send(1), Ok(())); + }) + })); +} + +// test that the `with` sink doesn't require the underlying sink to flush, +// but doesn't claim to be flushed until the underlying sink is +#[test] +fn with_flush_propagate() { + let mut sink = ManualFlush::new().with(future::ok::, ()>); + flag_cx(|flag, cx| { + unwrap(Pin::new(&mut sink).poll_ready(cx)); + Pin::new(&mut sink).start_send(Some(0)).unwrap(); + unwrap(Pin::new(&mut sink).poll_ready(cx)); + Pin::new(&mut sink).start_send(Some(1)).unwrap(); + + { + let mut task = sink.flush(); + assert!(task.poll_unpin(cx).is_pending()); + assert!(!flag.take()); + } + assert_eq!(sink.get_mut().force_flush(), vec![0, 1]); + assert!(flag.take()); + unwrap(sink.flush().poll_unpin(cx)); + }) +} + +// test that `Clone` is implemented on `with` sinks +#[test] +fn with_implements_clone() { + let (mut tx, rx) = mpsc::channel(5); + + { + let mut is_positive = tx.clone().with(|item| future::ok::(item > 0)); + + let mut is_long = + tx.clone().with(|item: &str| future::ok::(item.len() > 5)); + + block_on(is_positive.clone().send(-1)).unwrap(); + block_on(is_long.clone().send("123456")).unwrap(); + block_on(is_long.send("123")).unwrap(); + block_on(is_positive.send(1)).unwrap(); + } + + block_on(tx.send(false)).unwrap(); + + block_on(tx.close()).unwrap(); + + assert_eq!(block_on(rx.collect::>()), vec![false, true, false, true, false]); +} + +// test that a buffer is a no-nop around a sink that always accepts sends +#[test] +fn buffer_noop() { + let mut sink = Vec::new().buffer(0); + block_on(sink.send(0)).unwrap(); + block_on(sink.send(1)).unwrap(); + assert_eq!(sink.get_ref(), &[0, 1]); + + let mut sink = Vec::new().buffer(1); + block_on(sink.send(0)).unwrap(); + block_on(sink.send(1)).unwrap(); + assert_eq!(sink.get_ref(), &[0, 1]); +} + +// test basic buffer functionality, including both filling up to capacity, +// and writing out when the underlying sink is ready +#[test] +fn buffer() { + let (sink, allow) = manual_allow::(); + let sink = sink.buffer(2); + + let sink = block_on(StartSendFut::new(sink, 0)).unwrap(); + let mut sink = block_on(StartSendFut::new(sink, 1)).unwrap(); + + flag_cx(|flag, cx| { + let mut task = sink.send(2); + assert!(task.poll_unpin(cx).is_pending()); + assert!(!flag.take()); + allow.start(); + assert!(flag.take()); + unwrap(task.poll_unpin(cx)); + assert_eq!(sink.get_ref().data, vec![0, 1, 2]); + }) +} + +#[test] +fn fanout_smoke() { + let sink1 = Vec::new(); + let sink2 = Vec::new(); + let mut sink = sink1.fanout(sink2); + block_on(sink.send_all(&mut stream::iter(vec![1, 2, 3]).map(Ok))).unwrap(); + let (sink1, sink2) = sink.into_inner(); + assert_eq!(sink1, vec![1, 2, 3]); + assert_eq!(sink2, vec![1, 2, 3]); +} + +#[test] +fn fanout_backpressure() { + let (left_send, mut left_recv) = mpsc::channel(0); + let (right_send, mut right_recv) = mpsc::channel(0); + let sink = left_send.fanout(right_send); + + let mut sink = block_on(StartSendFut::new(sink, 0)).unwrap(); + + flag_cx(|flag, cx| { + let mut task = sink.send(2); + assert!(!flag.take()); + assert!(task.poll_unpin(cx).is_pending()); + assert_eq!(block_on(left_recv.next()), Some(0)); + assert!(flag.take()); + assert!(task.poll_unpin(cx).is_pending()); + assert_eq!(block_on(right_recv.next()), Some(0)); + assert!(flag.take()); + + assert!(task.poll_unpin(cx).is_pending()); + assert_eq!(block_on(left_recv.next()), Some(2)); + assert!(flag.take()); + assert!(task.poll_unpin(cx).is_pending()); + assert_eq!(block_on(right_recv.next()), Some(2)); + assert!(flag.take()); + + unwrap(task.poll_unpin(cx)); + // make sure receivers live until end of test to prevent send errors + drop(left_recv); + drop(right_recv); + }) +} + +#[test] +fn sink_map_err() { + { + let cx = &mut panic_context(); + let (tx, _rx) = mpsc::channel(1); + let mut tx = tx.sink_map_err(|_| ()); + assert_eq!(Pin::new(&mut tx).start_send(()), Ok(())); + assert_eq!(Pin::new(&mut tx).poll_flush(cx), Poll::Ready(Ok(()))); + } + + let tx = mpsc::channel(0).0; + assert_eq!(Pin::new(&mut tx.sink_map_err(|_| ())).start_send(()), Err(())); +} + +#[test] +fn sink_unfold() { + block_on(poll_fn(|cx| { + let (tx, mut rx) = mpsc::channel(1); + let unfold = sink::unfold((), |(), i: i32| { + let mut tx = tx.clone(); + async move { + tx.send(i).await.unwrap(); + Ok::<_, String>(()) + } + }); + futures::pin_mut!(unfold); + assert_eq!(unfold.as_mut().start_send(1), Ok(())); + assert_eq!(unfold.as_mut().poll_flush(cx), Poll::Ready(Ok(()))); + assert_eq!(rx.try_next().unwrap(), Some(1)); + + assert_eq!(unfold.as_mut().poll_ready(cx), Poll::Ready(Ok(()))); + assert_eq!(unfold.as_mut().start_send(2), Ok(())); + assert_eq!(unfold.as_mut().poll_ready(cx), Poll::Ready(Ok(()))); + assert_eq!(unfold.as_mut().start_send(3), Ok(())); + assert_eq!(rx.try_next().unwrap(), Some(2)); + assert!(rx.try_next().is_err()); + assert_eq!(unfold.as_mut().poll_ready(cx), Poll::Ready(Ok(()))); + assert_eq!(unfold.as_mut().start_send(4), Ok(())); + assert_eq!(unfold.as_mut().poll_flush(cx), Poll::Pending); // Channel full + assert_eq!(rx.try_next().unwrap(), Some(3)); + assert_eq!(rx.try_next().unwrap(), Some(4)); + + Poll::Ready(()) + })) +} + +#[test] +fn err_into() { + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + struct ErrIntoTest; + + impl From for ErrIntoTest { + fn from(_: mpsc::SendError) -> Self { + Self + } + } + + { + let cx = &mut panic_context(); + let (tx, _rx) = mpsc::channel(1); + let mut tx: SinkErrInto, _, ErrIntoTest> = tx.sink_err_into(); + assert_eq!(Pin::new(&mut tx).start_send(()), Ok(())); + assert_eq!(Pin::new(&mut tx).poll_flush(cx), Poll::Ready(Ok(()))); + } + + let tx = mpsc::channel(0).0; + assert_eq!(Pin::new(&mut tx.sink_err_into()).start_send(()), Err(ErrIntoTest)); +} diff --git a/utshell-0.5.0/vendor/futures/tests/sink_fanout.rs b/utshell-0.5.0/vendor/futures/tests/sink_fanout.rs new file mode 100644 index 00000000..e57b2d8c --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/sink_fanout.rs @@ -0,0 +1,24 @@ +use futures::channel::mpsc; +use futures::executor::block_on; +use futures::future::join3; +use futures::sink::SinkExt; +use futures::stream::{self, StreamExt}; + +#[test] +fn it_works() { + let (tx1, rx1) = mpsc::channel(1); + let (tx2, rx2) = mpsc::channel(2); + let tx = tx1.fanout(tx2).sink_map_err(|_| ()); + + let src = stream::iter((0..10).map(Ok)); + let fwd = src.forward(tx); + + let collect_fut1 = rx1.collect::>(); + let collect_fut2 = rx2.collect::>(); + let (_, vec1, vec2) = block_on(join3(fwd, collect_fut1, collect_fut2)); + + let expected = (0..10).collect::>(); + + assert_eq!(vec1, expected); + assert_eq!(vec2, expected); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream.rs b/utshell-0.5.0/vendor/futures/tests/stream.rs new file mode 100644 index 00000000..6cbef751 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream.rs @@ -0,0 +1,577 @@ +use std::cell::Cell; +use std::iter; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::Arc; +use std::task::Context; + +use futures::channel::mpsc; +use futures::executor::block_on; +use futures::future::{self, Future}; +use futures::lock::Mutex; +use futures::sink::SinkExt; +use futures::stream::{self, StreamExt}; +use futures::task::Poll; +use futures::{ready, FutureExt}; +use futures_core::Stream; +use futures_executor::ThreadPool; +use futures_test::task::noop_context; + +#[test] +fn select() { + fn select_and_compare(a: Vec, b: Vec, expected: Vec) { + let a = stream::iter(a); + let b = stream::iter(b); + let vec = block_on(stream::select(a, b).collect::>()); + assert_eq!(vec, expected); + } + + select_and_compare(vec![1, 2, 3], vec![4, 5, 6], vec![1, 4, 2, 5, 3, 6]); + select_and_compare(vec![1, 2, 3], vec![4, 5], vec![1, 4, 2, 5, 3]); + select_and_compare(vec![1, 2], vec![4, 5, 6], vec![1, 4, 2, 5, 6]); +} + +#[test] +fn flat_map() { + block_on(async { + let st = + stream::iter(vec![stream::iter(0..=4u8), stream::iter(6..=10), stream::iter(0..=2)]); + + let values: Vec<_> = + st.flat_map(|s| s.filter(|v| futures::future::ready(v % 2 == 0))).collect().await; + + assert_eq!(values, vec![0, 2, 4, 6, 8, 10, 0, 2]); + }); +} + +#[test] +fn scan() { + block_on(async { + let values = stream::iter(vec![1u8, 2, 3, 4, 6, 8, 2]) + .scan(1, |state, e| { + *state += 1; + futures::future::ready(if e < *state { Some(e) } else { None }) + }) + .collect::>() + .await; + + assert_eq!(values, vec![1u8, 2, 3, 4]); + }); +} + +#[test] +fn flatten_unordered() { + use futures::executor::block_on; + use futures::stream::*; + use futures::task::*; + use std::convert::identity; + use std::pin::Pin; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::thread; + use std::time::Duration; + + struct DataStream { + data: Vec, + polled: bool, + wake_immediately: bool, + } + + impl Stream for DataStream { + type Item = u8; + + fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { + if !self.polled { + if !self.wake_immediately { + let waker = ctx.waker().clone(); + let sleep_time = + Duration::from_millis(*self.data.first().unwrap_or(&0) as u64 / 10); + thread::spawn(move || { + thread::sleep(sleep_time); + waker.wake_by_ref(); + }); + } else { + ctx.waker().wake_by_ref(); + } + self.polled = true; + Poll::Pending + } else { + self.polled = false; + Poll::Ready(self.data.pop()) + } + } + } + + struct Interchanger { + polled: bool, + base: u8, + wake_immediately: bool, + } + + impl Stream for Interchanger { + type Item = DataStream; + + fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { + if !self.polled { + self.polled = true; + if !self.wake_immediately { + let waker = ctx.waker().clone(); + let sleep_time = Duration::from_millis(self.base as u64); + thread::spawn(move || { + thread::sleep(sleep_time); + waker.wake_by_ref(); + }); + } else { + ctx.waker().wake_by_ref(); + } + Poll::Pending + } else { + let data: Vec<_> = (0..6).rev().map(|v| v + self.base * 6).collect(); + self.base += 1; + self.polled = false; + Poll::Ready(Some(DataStream { + polled: false, + data, + wake_immediately: self.wake_immediately && self.base % 2 == 0, + })) + } + } + } + + // basic behaviour + { + block_on(async { + let st = stream::iter(vec![ + stream::iter(0..=4u8), + stream::iter(6..=10), + stream::iter(10..=12), + ]); + + let fl_unordered = st.flatten_unordered(3).collect::>().await; + + assert_eq!(fl_unordered, vec![0, 6, 10, 1, 7, 11, 2, 8, 12, 3, 9, 4, 10]); + }); + + block_on(async { + let st = stream::iter(vec![ + stream::iter(0..=4u8), + stream::iter(6..=10), + stream::iter(0..=2), + ]); + + let mut fm_unordered = st + .flat_map_unordered(1, |s| s.filter(|v| futures::future::ready(v % 2 == 0))) + .collect::>() + .await; + + fm_unordered.sort_unstable(); + + assert_eq!(fm_unordered, vec![0, 0, 2, 2, 4, 6, 8, 10]); + }); + } + + // wake up immediately + { + block_on(async { + let mut fl_unordered = Interchanger { polled: false, base: 0, wake_immediately: true } + .take(10) + .map(|s| s.map(identity)) + .flatten_unordered(10) + .collect::>() + .await; + + fl_unordered.sort_unstable(); + + assert_eq!(fl_unordered, (0..60).collect::>()); + }); + + block_on(async { + let mut fm_unordered = Interchanger { polled: false, base: 0, wake_immediately: true } + .take(10) + .flat_map_unordered(10, |s| s.map(identity)) + .collect::>() + .await; + + fm_unordered.sort_unstable(); + + assert_eq!(fm_unordered, (0..60).collect::>()); + }); + } + + // wake up after delay + { + block_on(async { + let mut fl_unordered = Interchanger { polled: false, base: 0, wake_immediately: false } + .take(10) + .map(|s| s.map(identity)) + .flatten_unordered(10) + .collect::>() + .await; + + fl_unordered.sort_unstable(); + + assert_eq!(fl_unordered, (0..60).collect::>()); + }); + + block_on(async { + let mut fm_unordered = Interchanger { polled: false, base: 0, wake_immediately: false } + .take(10) + .flat_map_unordered(10, |s| s.map(identity)) + .collect::>() + .await; + + fm_unordered.sort_unstable(); + + assert_eq!(fm_unordered, (0..60).collect::>()); + }); + + block_on(async { + let (mut fm_unordered, mut fl_unordered) = futures_util::join!( + Interchanger { polled: false, base: 0, wake_immediately: false } + .take(10) + .flat_map_unordered(10, |s| s.map(identity)) + .collect::>(), + Interchanger { polled: false, base: 0, wake_immediately: false } + .take(10) + .map(|s| s.map(identity)) + .flatten_unordered(10) + .collect::>() + ); + + fm_unordered.sort_unstable(); + fl_unordered.sort_unstable(); + + assert_eq!(fm_unordered, fl_unordered); + assert_eq!(fm_unordered, (0..60).collect::>()); + }); + } + + // waker panics + { + let stream = Arc::new(Mutex::new( + Interchanger { polled: false, base: 0, wake_immediately: true } + .take(10) + .flat_map_unordered(10, |s| s.map(identity)), + )); + + struct PanicWaker; + + impl ArcWake for PanicWaker { + fn wake_by_ref(_arc_self: &Arc) { + panic!("WAKE UP"); + } + } + + std::thread::spawn({ + let stream = stream.clone(); + move || { + let mut st = poll_fn(|cx| { + let mut lock = ready!(stream.lock().poll_unpin(cx)); + + let panic_waker = waker(Arc::new(PanicWaker)); + let mut panic_cx = Context::from_waker(&panic_waker); + let _ = ready!(lock.poll_next_unpin(&mut panic_cx)); + + Poll::Ready(Some(())) + }); + + block_on(st.next()) + } + }) + .join() + .unwrap_err(); + + block_on(async move { + let mut values: Vec<_> = stream.lock().await.by_ref().collect().await; + values.sort_unstable(); + + assert_eq!(values, (0..60).collect::>()); + }); + } + + // stream panics + { + let st = stream::iter(iter::once( + once(Box::pin(async { panic!("Polled") })).left_stream::(), + )) + .chain( + Interchanger { polled: false, base: 0, wake_immediately: true } + .map(|stream| stream.right_stream()) + .take(10), + ); + + let stream = Arc::new(Mutex::new(st.flatten_unordered(10))); + + std::thread::spawn({ + let stream = stream.clone(); + move || { + let mut st = poll_fn(|cx| { + let mut lock = ready!(stream.lock().poll_unpin(cx)); + let data = ready!(lock.poll_next_unpin(cx)); + + Poll::Ready(data) + }); + + block_on(st.next()) + } + }) + .join() + .unwrap_err(); + + block_on(async move { + let mut values: Vec<_> = stream.lock().await.by_ref().collect().await; + values.sort_unstable(); + + assert_eq!(values, (0..60).collect::>()); + }); + } + + fn timeout(time: Duration, value: I) -> impl Future { + let ready = Arc::new(AtomicBool::new(false)); + let mut spawned = false; + + future::poll_fn(move |cx| { + if !spawned { + let waker = cx.waker().clone(); + let ready = ready.clone(); + + std::thread::spawn(move || { + std::thread::sleep(time); + ready.store(true, Ordering::Release); + + waker.wake_by_ref() + }); + spawned = true; + } + + if ready.load(Ordering::Acquire) { + Poll::Ready(value.clone()) + } else { + Poll::Pending + } + }) + } + + fn build_nested_fu(st: S) -> impl Stream + Unpin + where + S::Item: Clone, + { + let inner = st + .then(|item| timeout(Duration::from_millis(50), item)) + .enumerate() + .map(|(idx, value)| { + stream::once(if idx % 2 == 0 { + future::ready(value).left_future() + } else { + timeout(Duration::from_millis(100), value).right_future() + }) + }) + .flatten_unordered(None); + + stream::once(future::ready(inner)).flatten_unordered(None) + } + + // nested `flatten_unordered` + let te = ThreadPool::new().unwrap(); + let base_handle = te + .spawn_with_handle(async move { + let fu = build_nested_fu(stream::iter(1..=10)); + + assert_eq!(fu.count().await, 10); + }) + .unwrap(); + + block_on(base_handle); + + let empty_state_move_handle = te + .spawn_with_handle(async move { + let mut fu = build_nested_fu(stream::iter(1..10)); + { + let mut cx = noop_context(); + let _ = fu.poll_next_unpin(&mut cx); + let _ = fu.poll_next_unpin(&mut cx); + } + + assert_eq!(fu.count().await, 9); + }) + .unwrap(); + + block_on(empty_state_move_handle); +} + +#[test] +fn take_until() { + fn make_stop_fut(stop_on: u32) -> impl Future { + let mut i = 0; + future::poll_fn(move |_cx| { + i += 1; + if i <= stop_on { + Poll::Pending + } else { + Poll::Ready(()) + } + }) + } + + block_on(async { + // Verify stopping works: + let stream = stream::iter(1u32..=10); + let stop_fut = make_stop_fut(5); + + let stream = stream.take_until(stop_fut); + let last = stream.fold(0, |_, i| async move { i }).await; + assert_eq!(last, 5); + + // Verify take_future() works: + let stream = stream::iter(1..=10); + let stop_fut = make_stop_fut(5); + + let mut stream = stream.take_until(stop_fut); + + assert_eq!(stream.next().await, Some(1)); + assert_eq!(stream.next().await, Some(2)); + + stream.take_future(); + + let last = stream.fold(0, |_, i| async move { i }).await; + assert_eq!(last, 10); + + // Verify take_future() returns None if stream is stopped: + let stream = stream::iter(1u32..=10); + let stop_fut = make_stop_fut(1); + let mut stream = stream.take_until(stop_fut); + assert_eq!(stream.next().await, Some(1)); + assert_eq!(stream.next().await, None); + assert!(stream.take_future().is_none()); + + // Verify TakeUntil is fused: + let mut i = 0; + let stream = stream::poll_fn(move |_cx| { + i += 1; + match i { + 1 => Poll::Ready(Some(1)), + 2 => Poll::Ready(None), + _ => panic!("TakeUntil not fused"), + } + }); + + let stop_fut = make_stop_fut(1); + let mut stream = stream.take_until(stop_fut); + assert_eq!(stream.next().await, Some(1)); + assert_eq!(stream.next().await, None); + assert_eq!(stream.next().await, None); + }); +} + +#[test] +#[should_panic] +fn chunks_panic_on_cap_zero() { + let (_, rx1) = mpsc::channel::<()>(1); + + let _ = rx1.chunks(0); +} + +#[test] +#[should_panic] +fn ready_chunks_panic_on_cap_zero() { + let (_, rx1) = mpsc::channel::<()>(1); + + let _ = rx1.ready_chunks(0); +} + +#[test] +fn ready_chunks() { + let (mut tx, rx1) = mpsc::channel::(16); + + let mut s = rx1.ready_chunks(2); + + let mut cx = noop_context(); + assert!(s.next().poll_unpin(&mut cx).is_pending()); + + block_on(async { + tx.send(1).await.unwrap(); + + assert_eq!(s.next().await.unwrap(), vec![1]); + tx.send(2).await.unwrap(); + tx.send(3).await.unwrap(); + tx.send(4).await.unwrap(); + assert_eq!(s.next().await.unwrap(), vec![2, 3]); + assert_eq!(s.next().await.unwrap(), vec![4]); + }); +} + +struct SlowStream { + times_should_poll: usize, + times_polled: Rc>, +} +impl Stream for SlowStream { + type Item = usize; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.times_polled.set(self.times_polled.get() + 1); + if self.times_polled.get() % 2 == 0 { + cx.waker().wake_by_ref(); + return Poll::Pending; + } + if self.times_polled.get() >= self.times_should_poll { + return Poll::Ready(None); + } + Poll::Ready(Some(self.times_polled.get())) + } +} + +#[test] +fn select_with_strategy_doesnt_terminate_early() { + for side in [stream::PollNext::Left, stream::PollNext::Right] { + let times_should_poll = 10; + let count = Rc::new(Cell::new(0)); + let b = stream::iter([10, 20]); + + let mut selected = stream::select_with_strategy( + SlowStream { times_should_poll, times_polled: count.clone() }, + b, + |_: &mut ()| side, + ); + block_on(async move { while selected.next().await.is_some() {} }); + assert_eq!(count.get(), times_should_poll + 1); + } +} + +async fn is_even(number: u8) -> bool { + number % 2 == 0 +} + +#[test] +fn all() { + block_on(async { + let empty: [u8; 0] = []; + let st = stream::iter(empty); + let all = st.all(is_even).await; + assert!(all); + + let st = stream::iter([2, 4, 6, 8]); + let all = st.all(is_even).await; + assert!(all); + + let st = stream::iter([2, 3, 4]); + let all = st.all(is_even).await; + assert!(!all); + }); +} + +#[test] +fn any() { + block_on(async { + let empty: [u8; 0] = []; + let st = stream::iter(empty); + let any = st.any(is_even).await; + assert!(!any); + + let st = stream::iter([1, 2, 3]); + let any = st.any(is_even).await; + assert!(any); + + let st = stream::iter([1, 3, 5]); + let any = st.any(is_even).await; + assert!(!any); + }); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_abortable.rs b/utshell-0.5.0/vendor/futures/tests/stream_abortable.rs new file mode 100644 index 00000000..2339dd05 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_abortable.rs @@ -0,0 +1,46 @@ +use futures::channel::mpsc; +use futures::executor::block_on; +use futures::stream::{abortable, Stream, StreamExt}; +use futures::task::{Context, Poll}; +use futures::SinkExt; +use futures_test::task::new_count_waker; +use std::pin::Pin; + +#[test] +fn abortable_works() { + let (_tx, a_rx) = mpsc::channel::<()>(1); + let (mut abortable_rx, abort_handle) = abortable(a_rx); + + abort_handle.abort(); + assert!(abortable_rx.is_aborted()); + assert_eq!(None, block_on(abortable_rx.next())); +} + +#[test] +fn abortable_awakens() { + let (_tx, a_rx) = mpsc::channel::<()>(1); + let (mut abortable_rx, abort_handle) = abortable(a_rx); + + let (waker, counter) = new_count_waker(); + let mut cx = Context::from_waker(&waker); + + assert_eq!(counter, 0); + assert_eq!(Poll::Pending, Pin::new(&mut abortable_rx).poll_next(&mut cx)); + assert_eq!(counter, 0); + + abort_handle.abort(); + assert_eq!(counter, 1); + assert!(abortable_rx.is_aborted()); + assert_eq!(Poll::Ready(None), Pin::new(&mut abortable_rx).poll_next(&mut cx)); +} + +#[test] +fn abortable_resolves() { + let (mut tx, a_rx) = mpsc::channel::<()>(1); + let (mut abortable_rx, _abort_handle) = abortable(a_rx); + + block_on(tx.send(())).unwrap(); + + assert!(!abortable_rx.is_aborted()); + assert_eq!(Some(()), block_on(abortable_rx.next())); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_buffer_unordered.rs b/utshell-0.5.0/vendor/futures/tests/stream_buffer_unordered.rs new file mode 100644 index 00000000..9a2ee174 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_buffer_unordered.rs @@ -0,0 +1,73 @@ +use futures::channel::{mpsc, oneshot}; +use futures::executor::{block_on, block_on_stream}; +use futures::sink::SinkExt; +use futures::stream::StreamExt; +use std::sync::mpsc as std_mpsc; +use std::thread; + +#[test] +#[ignore] // FIXME: https://github.com/rust-lang/futures-rs/issues/1790 +fn works() { + const N: usize = 4; + + let (mut tx, rx) = mpsc::channel(1); + + let (tx2, rx2) = std_mpsc::channel(); + let (tx3, rx3) = std_mpsc::channel(); + let t1 = thread::spawn(move || { + for _ in 0..=N { + let (mytx, myrx) = oneshot::channel(); + block_on(tx.send(myrx)).unwrap(); + tx3.send(mytx).unwrap(); + } + rx2.recv().unwrap(); + for _ in 0..N { + let (mytx, myrx) = oneshot::channel(); + block_on(tx.send(myrx)).unwrap(); + tx3.send(mytx).unwrap(); + } + }); + + let (tx4, rx4) = std_mpsc::channel(); + let t2 = thread::spawn(move || { + for item in block_on_stream(rx.buffer_unordered(N)) { + tx4.send(item.unwrap()).unwrap(); + } + }); + + let o1 = rx3.recv().unwrap(); + let o2 = rx3.recv().unwrap(); + let o3 = rx3.recv().unwrap(); + let o4 = rx3.recv().unwrap(); + assert!(rx4.try_recv().is_err()); + + o1.send(1).unwrap(); + assert_eq!(rx4.recv(), Ok(1)); + o3.send(3).unwrap(); + assert_eq!(rx4.recv(), Ok(3)); + tx2.send(()).unwrap(); + o2.send(2).unwrap(); + assert_eq!(rx4.recv(), Ok(2)); + o4.send(4).unwrap(); + assert_eq!(rx4.recv(), Ok(4)); + + let o5 = rx3.recv().unwrap(); + let o6 = rx3.recv().unwrap(); + let o7 = rx3.recv().unwrap(); + let o8 = rx3.recv().unwrap(); + let o9 = rx3.recv().unwrap(); + + o5.send(5).unwrap(); + assert_eq!(rx4.recv(), Ok(5)); + o8.send(8).unwrap(); + assert_eq!(rx4.recv(), Ok(8)); + o9.send(9).unwrap(); + assert_eq!(rx4.recv(), Ok(9)); + o7.send(7).unwrap(); + assert_eq!(rx4.recv(), Ok(7)); + o6.send(6).unwrap(); + assert_eq!(rx4.recv(), Ok(6)); + + t1.join().unwrap(); + t2.join().unwrap(); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_catch_unwind.rs b/utshell-0.5.0/vendor/futures/tests/stream_catch_unwind.rs new file mode 100644 index 00000000..8b23a0a7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_catch_unwind.rs @@ -0,0 +1,27 @@ +use futures::executor::block_on_stream; +use futures::stream::{self, StreamExt}; + +#[test] +fn panic_in_the_middle_of_the_stream() { + let stream = stream::iter(vec![Some(10), None, Some(11)]); + + // panic on second element + let stream_panicking = stream.map(|o| o.unwrap()); + let mut iter = block_on_stream(stream_panicking.catch_unwind()); + + assert_eq!(10, iter.next().unwrap().ok().unwrap()); + assert!(iter.next().unwrap().is_err()); + assert!(iter.next().is_none()); +} + +#[test] +fn no_panic() { + let stream = stream::iter(vec![10, 11, 12]); + + let mut iter = block_on_stream(stream.catch_unwind()); + + assert_eq!(10, iter.next().unwrap().ok().unwrap()); + assert_eq!(11, iter.next().unwrap().ok().unwrap()); + assert_eq!(12, iter.next().unwrap().ok().unwrap()); + assert!(iter.next().is_none()); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_futures_ordered.rs b/utshell-0.5.0/vendor/futures/tests/stream_futures_ordered.rs new file mode 100644 index 00000000..5a4a3e22 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_futures_ordered.rs @@ -0,0 +1,172 @@ +use futures::channel::oneshot; +use futures::executor::{block_on, block_on_stream}; +use futures::future::{self, join, Future, FutureExt, TryFutureExt}; +use futures::stream::{FuturesOrdered, StreamExt}; +use futures::task::Poll; +use futures_test::task::noop_context; +use std::any::Any; + +#[test] +fn works_1() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut stream = vec![a_rx, b_rx, c_rx].into_iter().collect::>(); + + b_tx.send(99).unwrap(); + assert!(stream.poll_next_unpin(&mut noop_context()).is_pending()); + + a_tx.send(33).unwrap(); + c_tx.send(33).unwrap(); + + let mut iter = block_on_stream(stream); + assert_eq!(Some(Ok(33)), iter.next()); + assert_eq!(Some(Ok(99)), iter.next()); + assert_eq!(Some(Ok(33)), iter.next()); + assert_eq!(None, iter.next()); +} + +#[test] +fn works_2() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut stream = vec![a_rx.boxed(), join(b_rx, c_rx).map(|(a, b)| Ok(a? + b?)).boxed()] + .into_iter() + .collect::>(); + + let mut cx = noop_context(); + a_tx.send(33).unwrap(); + b_tx.send(33).unwrap(); + assert!(stream.poll_next_unpin(&mut cx).is_ready()); + assert!(stream.poll_next_unpin(&mut cx).is_pending()); + c_tx.send(33).unwrap(); + assert!(stream.poll_next_unpin(&mut cx).is_ready()); +} + +#[test] +fn test_push_front() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + let (d_tx, d_rx) = oneshot::channel::(); + + let mut stream = FuturesOrdered::new(); + + let mut cx = noop_context(); + + stream.push_back(a_rx); + stream.push_back(b_rx); + stream.push_back(c_rx); + + a_tx.send(1).unwrap(); + b_tx.send(2).unwrap(); + c_tx.send(3).unwrap(); + + // 1 and 2 should be received in order + assert_eq!(Poll::Ready(Some(Ok(1))), stream.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(Ok(2))), stream.poll_next_unpin(&mut cx)); + + stream.push_front(d_rx); + d_tx.send(4).unwrap(); + + // we pushed `d_rx` to the front and sent 4, so we should recieve 4 next + // and then 3 after it + assert_eq!(Poll::Ready(Some(Ok(4))), stream.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(Ok(3))), stream.poll_next_unpin(&mut cx)); +} + +#[test] +fn test_push_back() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + let (d_tx, d_rx) = oneshot::channel::(); + + let mut stream = FuturesOrdered::new(); + + let mut cx = noop_context(); + + stream.push_back(a_rx); + stream.push_back(b_rx); + stream.push_back(c_rx); + + a_tx.send(1).unwrap(); + b_tx.send(2).unwrap(); + c_tx.send(3).unwrap(); + + // All results should be received in order + + assert_eq!(Poll::Ready(Some(Ok(1))), stream.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(Ok(2))), stream.poll_next_unpin(&mut cx)); + + stream.push_back(d_rx); + d_tx.send(4).unwrap(); + + assert_eq!(Poll::Ready(Some(Ok(3))), stream.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(Ok(4))), stream.poll_next_unpin(&mut cx)); +} + +#[test] +fn from_iterator() { + let stream = vec![future::ready::(1), future::ready::(2), future::ready::(3)] + .into_iter() + .collect::>(); + assert_eq!(stream.len(), 3); + assert_eq!(block_on(stream.collect::>()), vec![1, 2, 3]); +} + +#[test] +fn queue_never_unblocked() { + let (_a_tx, a_rx) = oneshot::channel::>(); + let (b_tx, b_rx) = oneshot::channel::>(); + let (c_tx, c_rx) = oneshot::channel::>(); + + let mut stream = vec![ + Box::new(a_rx) as Box + Unpin>, + Box::new( + future::try_select(b_rx, c_rx) + .map_err(|e| e.factor_first().0) + .and_then(|e| future::ok(Box::new(e) as Box)), + ) as _, + ] + .into_iter() + .collect::>(); + + let cx = &mut noop_context(); + for _ in 0..10 { + assert!(stream.poll_next_unpin(cx).is_pending()); + } + + b_tx.send(Box::new(())).unwrap(); + assert!(stream.poll_next_unpin(cx).is_pending()); + c_tx.send(Box::new(())).unwrap(); + assert!(stream.poll_next_unpin(cx).is_pending()); + assert!(stream.poll_next_unpin(cx).is_pending()); +} + +#[test] +fn test_push_front_negative() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut stream = FuturesOrdered::new(); + + let mut cx = noop_context(); + + stream.push_front(a_rx); + stream.push_front(b_rx); + stream.push_front(c_rx); + + a_tx.send(1).unwrap(); + b_tx.send(2).unwrap(); + c_tx.send(3).unwrap(); + + // These should all be recieved in reverse order + assert_eq!(Poll::Ready(Some(Ok(3))), stream.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(Ok(2))), stream.poll_next_unpin(&mut cx)); + assert_eq!(Poll::Ready(Some(Ok(1))), stream.poll_next_unpin(&mut cx)); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_futures_unordered.rs b/utshell-0.5.0/vendor/futures/tests/stream_futures_unordered.rs new file mode 100644 index 00000000..7bdf5432 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_futures_unordered.rs @@ -0,0 +1,408 @@ +use futures::channel::oneshot; +use futures::executor::{block_on, block_on_stream}; +use futures::future::{self, join, Future, FutureExt}; +use futures::stream::{FusedStream, FuturesUnordered, StreamExt}; +use futures::task::{Context, Poll}; +use futures_test::future::FutureTestExt; +use futures_test::task::noop_context; +use futures_test::{assert_stream_done, assert_stream_next, assert_stream_pending}; +use std::iter::FromIterator; +use std::pin::Pin; +use std::sync::atomic::{AtomicBool, Ordering}; + +#[test] +fn is_terminated() { + let mut cx = noop_context(); + let mut tasks = FuturesUnordered::new(); + + assert_eq!(tasks.is_terminated(), false); + assert_eq!(tasks.poll_next_unpin(&mut cx), Poll::Ready(None)); + assert_eq!(tasks.is_terminated(), true); + + // Test that the sentinel value doesn't leak + assert_eq!(tasks.is_empty(), true); + assert_eq!(tasks.len(), 0); + assert_eq!(tasks.iter_mut().len(), 0); + + tasks.push(future::ready(1)); + + assert_eq!(tasks.is_empty(), false); + assert_eq!(tasks.len(), 1); + assert_eq!(tasks.iter_mut().len(), 1); + + assert_eq!(tasks.is_terminated(), false); + assert_eq!(tasks.poll_next_unpin(&mut cx), Poll::Ready(Some(1))); + assert_eq!(tasks.is_terminated(), false); + assert_eq!(tasks.poll_next_unpin(&mut cx), Poll::Ready(None)); + assert_eq!(tasks.is_terminated(), true); +} + +#[test] +fn works_1() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut iter = + block_on_stream(vec![a_rx, b_rx, c_rx].into_iter().collect::>()); + + b_tx.send(99).unwrap(); + assert_eq!(Some(Ok(99)), iter.next()); + + a_tx.send(33).unwrap(); + c_tx.send(33).unwrap(); + assert_eq!(Some(Ok(33)), iter.next()); + assert_eq!(Some(Ok(33)), iter.next()); + assert_eq!(None, iter.next()); +} + +#[test] +fn works_2() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut stream = vec![a_rx.boxed(), join(b_rx, c_rx).map(|(a, b)| Ok(a? + b?)).boxed()] + .into_iter() + .collect::>(); + + a_tx.send(9).unwrap(); + b_tx.send(10).unwrap(); + + let mut cx = noop_context(); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(9)))); + c_tx.send(20).unwrap(); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(30)))); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(None)); +} + +#[test] +fn from_iterator() { + let stream = vec![future::ready::(1), future::ready::(2), future::ready::(3)] + .into_iter() + .collect::>(); + assert_eq!(stream.len(), 3); + assert_eq!(block_on(stream.collect::>()), vec![1, 2, 3]); +} + +#[test] +fn finished_future() { + let (_a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut stream = vec![ + Box::new(a_rx) as Box> + Unpin>, + Box::new(future::select(b_rx, c_rx).map(|e| e.factor_first().0)) as _, + ] + .into_iter() + .collect::>(); + + let cx = &mut noop_context(); + for _ in 0..10 { + assert!(stream.poll_next_unpin(cx).is_pending()); + } + + b_tx.send(12).unwrap(); + c_tx.send(3).unwrap(); + assert!(stream.poll_next_unpin(cx).is_ready()); + assert!(stream.poll_next_unpin(cx).is_pending()); + assert!(stream.poll_next_unpin(cx).is_pending()); +} + +#[test] +fn iter_mut_cancel() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let mut stream = vec![a_rx, b_rx, c_rx].into_iter().collect::>(); + + for rx in stream.iter_mut() { + rx.close(); + } + + let mut iter = block_on_stream(stream); + + assert!(a_tx.is_canceled()); + assert!(b_tx.is_canceled()); + assert!(c_tx.is_canceled()); + + assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled))); + assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled))); + assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled))); + assert_eq!(iter.next(), None); +} + +#[test] +fn iter_mut_len() { + let mut stream = + vec![future::pending::<()>(), future::pending::<()>(), future::pending::<()>()] + .into_iter() + .collect::>(); + + let mut iter_mut = stream.iter_mut(); + assert_eq!(iter_mut.len(), 3); + assert!(iter_mut.next().is_some()); + assert_eq!(iter_mut.len(), 2); + assert!(iter_mut.next().is_some()); + assert_eq!(iter_mut.len(), 1); + assert!(iter_mut.next().is_some()); + assert_eq!(iter_mut.len(), 0); + assert!(iter_mut.next().is_none()); +} + +#[test] +fn iter_cancel() { + struct AtomicCancel { + future: F, + cancel: AtomicBool, + } + + impl Future for AtomicCancel { + type Output = Option<::Output>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if self.cancel.load(Ordering::Relaxed) { + Poll::Ready(None) + } else { + self.future.poll_unpin(cx).map(Some) + } + } + } + + impl AtomicCancel { + fn new(future: F) -> Self { + Self { future, cancel: AtomicBool::new(false) } + } + } + + let stream = vec![ + AtomicCancel::new(future::pending::<()>()), + AtomicCancel::new(future::pending::<()>()), + AtomicCancel::new(future::pending::<()>()), + ] + .into_iter() + .collect::>(); + + for f in stream.iter() { + f.cancel.store(true, Ordering::Relaxed); + } + + let mut iter = block_on_stream(stream); + + assert_eq!(iter.next(), Some(None)); + assert_eq!(iter.next(), Some(None)); + assert_eq!(iter.next(), Some(None)); + assert_eq!(iter.next(), None); +} + +#[test] +fn iter_len() { + let stream = vec![future::pending::<()>(), future::pending::<()>(), future::pending::<()>()] + .into_iter() + .collect::>(); + + let mut iter = stream.iter(); + assert_eq!(iter.len(), 3); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 2); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 1); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); +} + +#[test] +fn into_iter_cancel() { + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + + let stream = vec![a_rx, b_rx, c_rx].into_iter().collect::>(); + + let stream = stream + .into_iter() + .map(|mut rx| { + rx.close(); + rx + }) + .collect::>(); + + let mut iter = block_on_stream(stream); + + assert!(a_tx.is_canceled()); + assert!(b_tx.is_canceled()); + assert!(c_tx.is_canceled()); + + assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled))); + assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled))); + assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled))); + assert_eq!(iter.next(), None); +} + +#[test] +fn into_iter_len() { + let stream = vec![future::pending::<()>(), future::pending::<()>(), future::pending::<()>()] + .into_iter() + .collect::>(); + + let mut into_iter = stream.into_iter(); + assert_eq!(into_iter.len(), 3); + assert!(into_iter.next().is_some()); + assert_eq!(into_iter.len(), 2); + assert!(into_iter.next().is_some()); + assert_eq!(into_iter.len(), 1); + assert!(into_iter.next().is_some()); + assert_eq!(into_iter.len(), 0); + assert!(into_iter.next().is_none()); +} + +#[test] +fn into_iter_partial() { + let stream = vec![future::ready(1), future::ready(2), future::ready(3), future::ready(4)] + .into_iter() + .collect::>(); + + let mut into_iter = stream.into_iter(); + assert!(into_iter.next().is_some()); + assert!(into_iter.next().is_some()); + assert!(into_iter.next().is_some()); + assert_eq!(into_iter.len(), 1); + // don't panic when iterator is dropped before completing +} + +#[test] +fn futures_not_moved_after_poll() { + // Future that will be ready after being polled twice, + // asserting that it does not move. + let fut = future::ready(()).pending_once().assert_unmoved(); + let mut stream = vec![fut; 3].into_iter().collect::>(); + assert_stream_pending!(stream); + assert_stream_next!(stream, ()); + assert_stream_next!(stream, ()); + assert_stream_next!(stream, ()); + assert_stream_done!(stream); +} + +#[test] +fn len_valid_during_out_of_order_completion() { + // Complete futures out-of-order and add new futures afterwards to ensure + // length values remain correct. + let (a_tx, a_rx) = oneshot::channel::(); + let (b_tx, b_rx) = oneshot::channel::(); + let (c_tx, c_rx) = oneshot::channel::(); + let (d_tx, d_rx) = oneshot::channel::(); + + let mut cx = noop_context(); + let mut stream = FuturesUnordered::new(); + assert_eq!(stream.len(), 0); + + stream.push(a_rx); + assert_eq!(stream.len(), 1); + stream.push(b_rx); + assert_eq!(stream.len(), 2); + stream.push(c_rx); + assert_eq!(stream.len(), 3); + + b_tx.send(4).unwrap(); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(4)))); + assert_eq!(stream.len(), 2); + + stream.push(d_rx); + assert_eq!(stream.len(), 3); + + c_tx.send(5).unwrap(); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(5)))); + assert_eq!(stream.len(), 2); + + d_tx.send(6).unwrap(); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(6)))); + assert_eq!(stream.len(), 1); + + a_tx.send(7).unwrap(); + assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(7)))); + assert_eq!(stream.len(), 0); +} + +#[test] +fn polled_only_once_at_most_per_iteration() { + #[derive(Debug, Clone, Copy, Default)] + struct F { + polled: bool, + } + + impl Future for F { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, _: &mut Context) -> Poll { + if self.polled { + panic!("polled twice") + } else { + self.polled = true; + Poll::Pending + } + } + } + + let cx = &mut noop_context(); + + let mut tasks = FuturesUnordered::from_iter(vec![F::default(); 10]); + assert!(tasks.poll_next_unpin(cx).is_pending()); + assert_eq!(10, tasks.iter().filter(|f| f.polled).count()); + + let mut tasks = FuturesUnordered::from_iter(vec![F::default(); 33]); + assert!(tasks.poll_next_unpin(cx).is_pending()); + assert_eq!(33, tasks.iter().filter(|f| f.polled).count()); + + let mut tasks = FuturesUnordered::::new(); + assert_eq!(Poll::Ready(None), tasks.poll_next_unpin(cx)); +} + +#[test] +fn clear() { + let mut tasks = FuturesUnordered::from_iter(vec![future::ready(1), future::ready(2)]); + + assert_eq!(block_on(tasks.next()), Some(1)); + assert!(!tasks.is_empty()); + + tasks.clear(); + assert!(tasks.is_empty()); + + tasks.push(future::ready(3)); + assert!(!tasks.is_empty()); + + tasks.clear(); + assert!(tasks.is_empty()); + + assert_eq!(block_on(tasks.next()), None); + assert!(tasks.is_terminated()); + tasks.clear(); + assert!(!tasks.is_terminated()); +} + +// https://github.com/rust-lang/futures-rs/issues/2529#issuecomment-997290279 +#[test] +fn clear_in_loop() { + const N: usize = + if cfg!(miri) || option_env!("QEMU_LD_PREFIX").is_some() { 100 } else { 10_000 }; + futures::executor::block_on(async { + async fn task() { + let (s, r) = oneshot::channel(); + std::thread::spawn(|| { + std::thread::sleep(std::time::Duration::from_micros(100)); + let _ = s.send(()); + }); + r.await.unwrap() + } + let mut futures = FuturesUnordered::new(); + for _ in 0..N { + for _ in 0..24 { + futures.push(task()); + } + let _ = futures.next().await; + futures.clear(); + } + }); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_into_async_read.rs b/utshell-0.5.0/vendor/futures/tests/stream_into_async_read.rs new file mode 100644 index 00000000..60188d3e --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_into_async_read.rs @@ -0,0 +1,94 @@ +use core::pin::Pin; +use futures::io::{AsyncBufRead, AsyncRead}; +use futures::stream::{self, TryStreamExt}; +use futures::task::Poll; +use futures_test::{stream::StreamTestExt, task::noop_context}; + +macro_rules! assert_read { + ($reader:expr, $buf:expr, $item:expr) => { + let mut cx = noop_context(); + loop { + match Pin::new(&mut $reader).poll_read(&mut cx, $buf) { + Poll::Ready(Ok(x)) => { + assert_eq!(x, $item); + break; + } + Poll::Ready(Err(err)) => { + panic!("assertion failed: expected value but got {}", err); + } + Poll::Pending => { + continue; + } + } + } + }; +} + +macro_rules! assert_fill_buf { + ($reader:expr, $buf:expr) => { + let mut cx = noop_context(); + loop { + match Pin::new(&mut $reader).poll_fill_buf(&mut cx) { + Poll::Ready(Ok(x)) => { + assert_eq!(x, $buf); + break; + } + Poll::Ready(Err(err)) => { + panic!("assertion failed: expected value but got {}", err); + } + Poll::Pending => { + continue; + } + } + } + }; +} + +#[test] +fn test_into_async_read() { + let stream = stream::iter((1..=3).flat_map(|_| vec![Ok(vec![]), Ok(vec![1, 2, 3, 4, 5])])); + let mut reader = stream.interleave_pending().into_async_read(); + let mut buf = vec![0; 3]; + + assert_read!(reader, &mut buf, 3); + assert_eq!(&buf, &[1, 2, 3]); + + assert_read!(reader, &mut buf, 2); + assert_eq!(&buf[..2], &[4, 5]); + + assert_read!(reader, &mut buf, 3); + assert_eq!(&buf, &[1, 2, 3]); + + assert_read!(reader, &mut buf, 2); + assert_eq!(&buf[..2], &[4, 5]); + + assert_read!(reader, &mut buf, 3); + assert_eq!(&buf, &[1, 2, 3]); + + assert_read!(reader, &mut buf, 2); + assert_eq!(&buf[..2], &[4, 5]); + + assert_read!(reader, &mut buf, 0); +} + +#[test] +fn test_into_async_bufread() { + let stream = stream::iter((1..=2).flat_map(|_| vec![Ok(vec![]), Ok(vec![1, 2, 3, 4, 5])])); + let mut reader = stream.interleave_pending().into_async_read(); + + let mut reader = Pin::new(&mut reader); + + assert_fill_buf!(reader, &[1, 2, 3, 4, 5][..]); + reader.as_mut().consume(3); + + assert_fill_buf!(reader, &[4, 5][..]); + reader.as_mut().consume(2); + + assert_fill_buf!(reader, &[1, 2, 3, 4, 5][..]); + reader.as_mut().consume(2); + + assert_fill_buf!(reader, &[3, 4, 5][..]); + reader.as_mut().consume(3); + + assert_fill_buf!(reader, &[][..]); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_peekable.rs b/utshell-0.5.0/vendor/futures/tests/stream_peekable.rs new file mode 100644 index 00000000..153fcc25 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_peekable.rs @@ -0,0 +1,58 @@ +use futures::executor::block_on; +use futures::pin_mut; +use futures::stream::{self, Peekable, StreamExt}; + +#[test] +fn peekable() { + block_on(async { + let peekable: Peekable<_> = stream::iter(vec![1u8, 2, 3]).peekable(); + pin_mut!(peekable); + assert_eq!(peekable.as_mut().peek().await, Some(&1u8)); + assert_eq!(peekable.collect::>().await, vec![1, 2, 3]); + + let s = stream::once(async { 1 }).peekable(); + pin_mut!(s); + assert_eq!(s.as_mut().peek().await, Some(&1u8)); + assert_eq!(s.collect::>().await, vec![1]); + }); +} + +#[test] +fn peekable_mut() { + block_on(async { + let s = stream::iter(vec![1u8, 2, 3]).peekable(); + pin_mut!(s); + if let Some(p) = s.as_mut().peek_mut().await { + if *p == 1 { + *p = 5; + } + } + assert_eq!(s.collect::>().await, vec![5, 2, 3]); + }); +} + +#[test] +fn peekable_next_if_eq() { + block_on(async { + // first, try on references + let s = stream::iter(vec!["Heart", "of", "Gold"]).peekable(); + pin_mut!(s); + // try before `peek()` + assert_eq!(s.as_mut().next_if_eq(&"trillian").await, None); + assert_eq!(s.as_mut().next_if_eq(&"Heart").await, Some("Heart")); + // try after peek() + assert_eq!(s.as_mut().peek().await, Some(&"of")); + assert_eq!(s.as_mut().next_if_eq(&"of").await, Some("of")); + assert_eq!(s.as_mut().next_if_eq(&"zaphod").await, None); + // make sure `next()` still behaves + assert_eq!(s.next().await, Some("Gold")); + + // make sure comparison works for owned values + let s = stream::iter(vec![String::from("Ludicrous"), "speed".into()]).peekable(); + pin_mut!(s); + // make sure basic functionality works + assert_eq!(s.as_mut().next_if_eq("Ludicrous").await, Some("Ludicrous".into())); + assert_eq!(s.as_mut().next_if_eq("speed").await, Some("speed".into())); + assert_eq!(s.as_mut().next_if_eq("").await, None); + }); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_select_all.rs b/utshell-0.5.0/vendor/futures/tests/stream_select_all.rs new file mode 100644 index 00000000..4ae07357 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_select_all.rs @@ -0,0 +1,197 @@ +use futures::channel::mpsc; +use futures::executor::{block_on, block_on_stream}; +use futures::future::{self, FutureExt}; +use futures::stream::{self, select_all, FusedStream, SelectAll, StreamExt}; +use futures::task::Poll; +use futures_test::task::noop_context; + +#[test] +fn is_terminated() { + let mut cx = noop_context(); + let mut tasks = SelectAll::new(); + + assert_eq!(tasks.is_terminated(), false); + assert_eq!(tasks.poll_next_unpin(&mut cx), Poll::Ready(None)); + assert_eq!(tasks.is_terminated(), true); + + // Test that the sentinel value doesn't leak + assert_eq!(tasks.is_empty(), true); + assert_eq!(tasks.len(), 0); + + tasks.push(future::ready(1).into_stream()); + + assert_eq!(tasks.is_empty(), false); + assert_eq!(tasks.len(), 1); + + assert_eq!(tasks.is_terminated(), false); + assert_eq!(tasks.poll_next_unpin(&mut cx), Poll::Ready(Some(1))); + assert_eq!(tasks.is_terminated(), false); + assert_eq!(tasks.poll_next_unpin(&mut cx), Poll::Ready(None)); + assert_eq!(tasks.is_terminated(), true); +} + +#[test] +fn issue_1626() { + let a = stream::iter(0..=2); + let b = stream::iter(10..=14); + + let mut s = block_on_stream(stream::select_all(vec![a, b])); + + assert_eq!(s.next(), Some(0)); + assert_eq!(s.next(), Some(10)); + assert_eq!(s.next(), Some(1)); + assert_eq!(s.next(), Some(11)); + assert_eq!(s.next(), Some(2)); + assert_eq!(s.next(), Some(12)); + assert_eq!(s.next(), Some(13)); + assert_eq!(s.next(), Some(14)); + assert_eq!(s.next(), None); +} + +#[test] +fn works_1() { + let (a_tx, a_rx) = mpsc::unbounded::(); + let (b_tx, b_rx) = mpsc::unbounded::(); + let (c_tx, c_rx) = mpsc::unbounded::(); + + let streams = vec![a_rx, b_rx, c_rx]; + + let mut stream = block_on_stream(select_all(streams)); + + b_tx.unbounded_send(99).unwrap(); + a_tx.unbounded_send(33).unwrap(); + assert_eq!(Some(33), stream.next()); + assert_eq!(Some(99), stream.next()); + + b_tx.unbounded_send(99).unwrap(); + a_tx.unbounded_send(33).unwrap(); + assert_eq!(Some(33), stream.next()); + assert_eq!(Some(99), stream.next()); + + c_tx.unbounded_send(42).unwrap(); + assert_eq!(Some(42), stream.next()); + a_tx.unbounded_send(43).unwrap(); + assert_eq!(Some(43), stream.next()); + + drop((a_tx, b_tx, c_tx)); + assert_eq!(None, stream.next()); +} + +#[test] +fn clear() { + let mut tasks = + select_all(vec![stream::iter(vec![1].into_iter()), stream::iter(vec![2].into_iter())]); + + assert_eq!(block_on(tasks.next()), Some(1)); + assert!(!tasks.is_empty()); + + tasks.clear(); + assert!(tasks.is_empty()); + + tasks.push(stream::iter(vec![3].into_iter())); + assert!(!tasks.is_empty()); + + tasks.clear(); + assert!(tasks.is_empty()); + + assert_eq!(block_on(tasks.next()), None); + assert!(tasks.is_terminated()); + tasks.clear(); + assert!(!tasks.is_terminated()); +} + +#[test] +fn iter_mut() { + let mut stream = + vec![stream::pending::<()>(), stream::pending::<()>(), stream::pending::<()>()] + .into_iter() + .collect::>(); + + let mut iter = stream.iter_mut(); + assert_eq!(iter.len(), 3); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 2); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 1); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); + + let mut stream = vec![stream::iter(vec![]), stream::iter(vec![1]), stream::iter(vec![2])] + .into_iter() + .collect::>(); + + assert_eq!(stream.len(), 3); + assert_eq!(block_on(stream.next()), Some(1)); + assert_eq!(stream.len(), 2); + let mut iter = stream.iter_mut(); + assert_eq!(iter.len(), 2); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 1); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); + + assert_eq!(block_on(stream.next()), Some(2)); + assert_eq!(stream.len(), 2); + assert_eq!(block_on(stream.next()), None); + let mut iter = stream.iter_mut(); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); +} + +#[test] +fn iter() { + let stream = vec![stream::pending::<()>(), stream::pending::<()>(), stream::pending::<()>()] + .into_iter() + .collect::>(); + + let mut iter = stream.iter(); + assert_eq!(iter.len(), 3); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 2); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 1); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); + + let mut stream = vec![stream::iter(vec![]), stream::iter(vec![1]), stream::iter(vec![2])] + .into_iter() + .collect::>(); + + assert_eq!(stream.len(), 3); + assert_eq!(block_on(stream.next()), Some(1)); + assert_eq!(stream.len(), 2); + let mut iter = stream.iter(); + assert_eq!(iter.len(), 2); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 1); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); + + assert_eq!(block_on(stream.next()), Some(2)); + assert_eq!(stream.len(), 2); + assert_eq!(block_on(stream.next()), None); + let mut iter = stream.iter(); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); +} + +#[test] +fn into_iter() { + let stream = vec![stream::pending::<()>(), stream::pending::<()>(), stream::pending::<()>()] + .into_iter() + .collect::>(); + + let mut iter = stream.into_iter(); + assert_eq!(iter.len(), 3); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 2); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 1); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 0); + assert!(iter.next().is_none()); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_select_next_some.rs b/utshell-0.5.0/vendor/futures/tests/stream_select_next_some.rs new file mode 100644 index 00000000..8252ad7b --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_select_next_some.rs @@ -0,0 +1,86 @@ +use futures::executor::block_on; +use futures::future::{self, FusedFuture, FutureExt}; +use futures::select; +use futures::stream::{FuturesUnordered, StreamExt}; +use futures::task::{Context, Poll}; +use futures_test::future::FutureTestExt; +use futures_test::task::new_count_waker; + +#[test] +fn is_terminated() { + let (waker, counter) = new_count_waker(); + let mut cx = Context::from_waker(&waker); + + let mut tasks = FuturesUnordered::new(); + + let mut select_next_some = tasks.select_next_some(); + assert_eq!(select_next_some.is_terminated(), false); + assert_eq!(select_next_some.poll_unpin(&mut cx), Poll::Pending); + assert_eq!(counter, 1); + assert_eq!(select_next_some.is_terminated(), true); + drop(select_next_some); + + tasks.push(future::ready(1)); + + let mut select_next_some = tasks.select_next_some(); + assert_eq!(select_next_some.is_terminated(), false); + assert_eq!(select_next_some.poll_unpin(&mut cx), Poll::Ready(1)); + assert_eq!(select_next_some.is_terminated(), false); + assert_eq!(select_next_some.poll_unpin(&mut cx), Poll::Pending); + assert_eq!(select_next_some.is_terminated(), true); +} + +#[test] +fn select() { + // Checks that even though `async_tasks` will yield a `None` and return + // `is_terminated() == true` during the first poll, it manages to toggle + // back to having items after a future is pushed into it during the second + // poll (after pending_once completes). + block_on(async { + let mut fut = future::ready(1).pending_once(); + let mut async_tasks = FuturesUnordered::new(); + let mut total = 0; + loop { + select! { + num = fut => { + total += num; + async_tasks.push(async { 5 }); + }, + num = async_tasks.select_next_some() => { + total += num; + } + complete => break, + } + } + assert_eq!(total, 6); + }); +} + +// Check that `select!` macro does not fail when importing from `futures_util`. +#[test] +fn futures_util_select() { + use futures_util::select; + + // Checks that even though `async_tasks` will yield a `None` and return + // `is_terminated() == true` during the first poll, it manages to toggle + // back to having items after a future is pushed into it during the second + // poll (after pending_once completes). + block_on(async { + let mut fut = future::ready(1).pending_once(); + let mut async_tasks = FuturesUnordered::new(); + let mut total = 0; + loop { + select! { + num = fut => { + total += num; + async_tasks.push(async { 5 }); + }, + num = async_tasks.select_next_some() => { + total += num; + } + complete => break, + } + } + assert_eq!(total, 6); + }); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_split.rs b/utshell-0.5.0/vendor/futures/tests/stream_split.rs new file mode 100644 index 00000000..694c1518 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_split.rs @@ -0,0 +1,57 @@ +use futures::executor::block_on; +use futures::sink::{Sink, SinkExt}; +use futures::stream::{self, Stream, StreamExt}; +use futures::task::{Context, Poll}; +use pin_project::pin_project; +use std::pin::Pin; + +#[test] +fn test_split() { + #[pin_project] + struct Join { + #[pin] + stream: T, + #[pin] + sink: U, + } + + impl Stream for Join { + type Item = T::Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().stream.poll_next(cx) + } + } + + impl, Item> Sink for Join { + type Error = U::Error; + + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().sink.poll_ready(cx) + } + + fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { + self.project().sink.start_send(item) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().sink.poll_flush(cx) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().sink.poll_close(cx) + } + } + + let mut dest: Vec = Vec::new(); + { + let join = Join { stream: stream::iter(vec![10, 20, 30]), sink: &mut dest }; + + let (sink, stream) = join.split(); + let join = sink.reunite(stream).expect("test_split: reunite error"); + let (mut sink, stream) = join.split(); + let mut stream = stream.map(Ok); + block_on(sink.send_all(&mut stream)).unwrap(); + } + assert_eq!(dest, vec![10, 20, 30]); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_try_stream.rs b/utshell-0.5.0/vendor/futures/tests/stream_try_stream.rs new file mode 100644 index 00000000..ef38c510 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_try_stream.rs @@ -0,0 +1,183 @@ +use core::pin::Pin; +use std::convert::Infallible; + +use futures::{ + stream::{self, repeat, Repeat, StreamExt, TryStreamExt}, + task::Poll, + Stream, +}; +use futures_executor::block_on; +use futures_task::Context; +use futures_test::task::noop_context; + +#[test] +fn try_filter_map_after_err() { + let cx = &mut noop_context(); + let mut s = stream::iter(1..=3) + .map(Ok) + .try_filter_map(|v| async move { Err::, _>(v) }) + .filter_map(|r| async move { r.ok() }) + .boxed(); + assert_eq!(Poll::Ready(None), s.poll_next_unpin(cx)); +} + +#[test] +fn try_skip_while_after_err() { + let cx = &mut noop_context(); + let mut s = stream::iter(1..=3) + .map(Ok) + .try_skip_while(|_| async move { Err::<_, ()>(()) }) + .filter_map(|r| async move { r.ok() }) + .boxed(); + assert_eq!(Poll::Ready(None), s.poll_next_unpin(cx)); +} + +#[test] +fn try_take_while_after_err() { + let cx = &mut noop_context(); + let mut s = stream::iter(1..=3) + .map(Ok) + .try_take_while(|_| async move { Err::<_, ()>(()) }) + .filter_map(|r| async move { r.ok() }) + .boxed(); + assert_eq!(Poll::Ready(None), s.poll_next_unpin(cx)); +} + +#[test] +fn try_flatten_unordered() { + let test_st = stream::iter(1..7) + .map(|val: u32| { + if val % 2 == 0 { + Ok(stream::unfold((val, 1), |(val, pow)| async move { + Some((val.pow(pow), (val, pow + 1))) + }) + .take(3) + .map(move |val| if val % 16 != 0 { Ok(val) } else { Err(val) })) + } else { + Err(val) + } + }) + .map_ok(Box::pin) + .try_flatten_unordered(None); + + block_on(async move { + assert_eq!( + // All numbers can be divided by 16 and odds must be `Err` + // For all basic evens we must have powers from 1 to 3 + vec![ + Err(1), + Err(3), + Err(5), + Ok(2), + Ok(4), + Ok(6), + Ok(4), + Err(16), + Ok(36), + Ok(8), + Err(64), + Ok(216) + ], + test_st.collect::>().await + ) + }); + + #[derive(Clone, Debug)] + struct ErrorStream { + error_after: usize, + polled: usize, + } + + impl Stream for ErrorStream { + type Item = Result>, ()>; + + fn poll_next(mut self: Pin<&mut Self>, _: &mut Context) -> Poll> { + if self.polled > self.error_after { + panic!("Polled after error"); + } else { + let out = + if self.polled == self.error_after { Err(()) } else { Ok(repeat(Ok(()))) }; + self.polled += 1; + Poll::Ready(Some(out)) + } + } + } + + block_on(async move { + let mut st = ErrorStream { error_after: 3, polled: 0 }.try_flatten_unordered(None); + let mut ctr = 0; + while (st.try_next().await).is_ok() { + ctr += 1; + } + assert_eq!(ctr, 0); + + assert_eq!( + ErrorStream { error_after: 10, polled: 0 } + .try_flatten_unordered(None) + .inspect_ok(|_| panic!("Unexpected `Ok`")) + .try_collect::>() + .await, + Err(()) + ); + + let mut taken = 0; + assert_eq!( + ErrorStream { error_after: 10, polled: 0 } + .map_ok(|st| st.take(3)) + .try_flatten_unordered(1) + .inspect(|_| taken += 1) + .try_fold((), |(), res| async move { Ok(res) }) + .await, + Err(()) + ); + assert_eq!(taken, 31); + }) +} + +async fn is_even(number: u8) -> bool { + number % 2 == 0 +} + +#[test] +fn try_all() { + block_on(async { + let empty: [Result; 0] = []; + let st = stream::iter(empty); + let all = st.try_all(is_even).await; + assert_eq!(Ok(true), all); + + let st = stream::iter([Ok::<_, Infallible>(2), Ok(4), Ok(6), Ok(8)]); + let all = st.try_all(is_even).await; + assert_eq!(Ok(true), all); + + let st = stream::iter([Ok::<_, Infallible>(2), Ok(3), Ok(4)]); + let all = st.try_all(is_even).await; + assert_eq!(Ok(false), all); + + let st = stream::iter([Ok(2), Ok(4), Err("err"), Ok(8)]); + let all = st.try_all(is_even).await; + assert_eq!(Err("err"), all); + }); +} + +#[test] +fn try_any() { + block_on(async { + let empty: [Result; 0] = []; + let st = stream::iter(empty); + let any = st.try_any(is_even).await; + assert_eq!(Ok(false), any); + + let st = stream::iter([Ok::<_, Infallible>(1), Ok(2), Ok(3)]); + let any = st.try_any(is_even).await; + assert_eq!(Ok(true), any); + + let st = stream::iter([Ok::<_, Infallible>(1), Ok(3), Ok(5)]); + let any = st.try_any(is_even).await; + assert_eq!(Ok(false), any); + + let st = stream::iter([Ok(1), Ok(3), Err("err"), Ok(8)]); + let any = st.try_any(is_even).await; + assert_eq!(Err("err"), any); + }); +} diff --git a/utshell-0.5.0/vendor/futures/tests/stream_unfold.rs b/utshell-0.5.0/vendor/futures/tests/stream_unfold.rs new file mode 100644 index 00000000..16b10813 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/stream_unfold.rs @@ -0,0 +1,32 @@ +use futures::future; +use futures::stream; +use futures_test::future::FutureTestExt; +use futures_test::{assert_stream_done, assert_stream_next, assert_stream_pending}; + +#[test] +fn unfold1() { + let mut stream = stream::unfold(0, |state| { + if state <= 2 { + future::ready(Some((state * 2, state + 1))).pending_once() + } else { + future::ready(None).pending_once() + } + }); + + // Creates the future with the closure + // Not ready (delayed future) + assert_stream_pending!(stream); + // Future is ready, yields the item + assert_stream_next!(stream, 0); + + // Repeat + assert_stream_pending!(stream); + assert_stream_next!(stream, 2); + + assert_stream_pending!(stream); + assert_stream_next!(stream, 4); + + // No more items + assert_stream_pending!(stream); + assert_stream_done!(stream); +} diff --git a/utshell-0.5.0/vendor/futures/tests/task_arc_wake.rs b/utshell-0.5.0/vendor/futures/tests/task_arc_wake.rs new file mode 100644 index 00000000..aedc15bc --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/task_arc_wake.rs @@ -0,0 +1,79 @@ +use futures::task::{self, ArcWake, Waker}; +use std::panic; +use std::sync::{Arc, Mutex}; + +struct CountingWaker { + nr_wake: Mutex, +} + +impl CountingWaker { + fn new() -> Self { + Self { nr_wake: Mutex::new(0) } + } + + fn wakes(&self) -> i32 { + *self.nr_wake.lock().unwrap() + } +} + +impl ArcWake for CountingWaker { + fn wake_by_ref(arc_self: &Arc) { + let mut lock = arc_self.nr_wake.lock().unwrap(); + *lock += 1; + } +} + +#[test] +fn create_from_arc() { + let some_w = Arc::new(CountingWaker::new()); + + let w1: Waker = task::waker(some_w.clone()); + assert_eq!(2, Arc::strong_count(&some_w)); + w1.wake_by_ref(); + assert_eq!(1, some_w.wakes()); + + let w2 = w1.clone(); + assert_eq!(3, Arc::strong_count(&some_w)); + + w2.wake_by_ref(); + assert_eq!(2, some_w.wakes()); + + drop(w2); + assert_eq!(2, Arc::strong_count(&some_w)); + drop(w1); + assert_eq!(1, Arc::strong_count(&some_w)); +} + +#[test] +fn ref_wake_same() { + let some_w = Arc::new(CountingWaker::new()); + + let w1: Waker = task::waker(some_w.clone()); + let w2 = task::waker_ref(&some_w); + let w3 = w2.clone(); + + assert!(w1.will_wake(&w2)); + assert!(w2.will_wake(&w3)); +} + +#[test] +fn proper_refcount_on_wake_panic() { + struct PanicWaker; + + impl ArcWake for PanicWaker { + fn wake_by_ref(_arc_self: &Arc) { + panic!("WAKE UP"); + } + } + + let some_w = Arc::new(PanicWaker); + + let w1: Waker = task::waker(some_w.clone()); + assert_eq!( + "WAKE UP", + *panic::catch_unwind(|| w1.wake_by_ref()).unwrap_err().downcast::<&str>().unwrap() + ); + assert_eq!(2, Arc::strong_count(&some_w)); // some_w + w1 + drop(w1); + assert_eq!(1, Arc::strong_count(&some_w)); // some_w +} diff --git a/utshell-0.5.0/vendor/futures/tests/task_atomic_waker.rs b/utshell-0.5.0/vendor/futures/tests/task_atomic_waker.rs new file mode 100644 index 00000000..cec3db28 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/task_atomic_waker.rs @@ -0,0 +1,48 @@ +use futures::executor::block_on; +use futures::future::poll_fn; +use futures::task::{AtomicWaker, Poll}; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; +use std::sync::Arc; +use std::thread; + +#[test] +fn basic() { + let atomic_waker = Arc::new(AtomicWaker::new()); + let atomic_waker_copy = atomic_waker.clone(); + + let returned_pending = Arc::new(AtomicUsize::new(0)); + let returned_pending_copy = returned_pending.clone(); + + let woken = Arc::new(AtomicUsize::new(0)); + let woken_copy = woken.clone(); + + let t = thread::spawn(move || { + let mut pending_count = 0; + + block_on(poll_fn(move |cx| { + if woken_copy.load(Ordering::Relaxed) == 1 { + Poll::Ready(()) + } else { + // Assert we return pending exactly once + assert_eq!(0, pending_count); + pending_count += 1; + atomic_waker_copy.register(cx.waker()); + + returned_pending_copy.store(1, Ordering::Relaxed); + + Poll::Pending + } + })) + }); + + while returned_pending.load(Ordering::Relaxed) == 0 {} + + // give spawned thread some time to sleep in `block_on` + thread::yield_now(); + + woken.store(1, Ordering::Relaxed); + atomic_waker.wake(); + + t.join().unwrap(); +} diff --git a/utshell-0.5.0/vendor/futures/tests/test_macro.rs b/utshell-0.5.0/vendor/futures/tests/test_macro.rs new file mode 100644 index 00000000..6adf51d8 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/test_macro.rs @@ -0,0 +1,20 @@ +#[futures_test::test] +async fn it_works() { + let fut = async { true }; + assert!(fut.await); + + let fut = async { false }; + assert!(!fut.await); +} + +#[should_panic] +#[futures_test::test] +async fn it_is_being_run() { + let fut = async { false }; + assert!(fut.await); +} + +#[futures_test::test] +async fn return_ty() -> Result<(), ()> { + Ok(()) +} diff --git a/utshell-0.5.0/vendor/futures/tests/try_join.rs b/utshell-0.5.0/vendor/futures/tests/try_join.rs new file mode 100644 index 00000000..0281ab89 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests/try_join.rs @@ -0,0 +1,35 @@ +#![deny(unreachable_code)] + +use futures::{executor::block_on, try_join}; + +// TODO: This abuses https://github.com/rust-lang/rust/issues/58733 in order to +// test behavior of the `try_join!` macro with the never type before it is +// stabilized. Once `!` is again stabilized this can be removed and replaced +// with direct use of `!` below where `Never` is used. +trait MyTrait { + type Output; +} +impl MyTrait for fn() -> T { + type Output = T; +} +type Never = ! as MyTrait>::Output; + +#[test] +fn try_join_never_error() { + block_on(async { + let future1 = async { Ok::<(), Never>(()) }; + let future2 = async { Ok::<(), Never>(()) }; + try_join!(future1, future2) + }) + .unwrap(); +} + +#[test] +fn try_join_never_ok() { + block_on(async { + let future1 = async { Err::(()) }; + let future2 = async { Err::(()) }; + try_join!(future1, future2) + }) + .unwrap_err(); +} diff --git a/utshell-0.5.0/vendor/futures/tests_disabled/all.rs b/utshell-0.5.0/vendor/futures/tests_disabled/all.rs new file mode 100644 index 00000000..a7a57104 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests_disabled/all.rs @@ -0,0 +1,400 @@ +use futures::channel::oneshot::{self, Canceled}; +use futures::executor::block_on; +use futures::future; +use std::sync::mpsc::{channel, TryRecvError}; + +// mod support; +// use support::*; + +fn unselect(r: Result, Either<(E, B), (E, A)>>) -> Result { + match r { + Ok(Either::Left((t, _))) | Ok(Either::Right((t, _))) => Ok(t), + Err(Either::Left((e, _))) | Err(Either::Right((e, _))) => Err(e), + } +} + +#[test] +fn result_smoke() { + fn is_future_v(_: C) + where + A: Send + 'static, + B: Send + 'static, + C: Future, + { + } + + is_future_v::(f_ok(1).map(|a| a + 1)); + is_future_v::(f_ok(1).map_err(|a| a + 1)); + is_future_v::(f_ok(1).and_then(Ok)); + is_future_v::(f_ok(1).or_else(Err)); + is_future_v::<(i32, i32), u32, _>(f_ok(1).join(Err(3))); + is_future_v::(f_ok(1).map(f_ok).flatten()); + + assert_done(|| f_ok(1), r_ok(1)); + assert_done(|| f_err(1), r_err(1)); + assert_done(|| result(Ok(1)), r_ok(1)); + assert_done(|| result(Err(1)), r_err(1)); + assert_done(|| ok(1), r_ok(1)); + assert_done(|| err(1), r_err(1)); + assert_done(|| f_ok(1).map(|a| a + 2), r_ok(3)); + assert_done(|| f_err(1).map(|a| a + 2), r_err(1)); + assert_done(|| f_ok(1).map_err(|a| a + 2), r_ok(1)); + assert_done(|| f_err(1).map_err(|a| a + 2), r_err(3)); + assert_done(|| f_ok(1).and_then(|a| Ok(a + 2)), r_ok(3)); + assert_done(|| f_err(1).and_then(|a| Ok(a + 2)), r_err(1)); + assert_done(|| f_ok(1).and_then(|a| Err(a as u32 + 3)), r_err(4)); + assert_done(|| f_err(1).and_then(|a| Err(a as u32 + 4)), r_err(1)); + assert_done(|| f_ok(1).or_else(|a| Ok(a as i32 + 2)), r_ok(1)); + assert_done(|| f_err(1).or_else(|a| Ok(a as i32 + 2)), r_ok(3)); + assert_done(|| f_ok(1).or_else(|a| Err(a + 3)), r_ok(1)); + assert_done(|| f_err(1).or_else(|a| Err(a + 4)), r_err(5)); + assert_done(|| f_ok(1).select(f_err(2)).then(unselect), r_ok(1)); + assert_done(|| f_ok(1).select(Ok(2)).then(unselect), r_ok(1)); + assert_done(|| f_err(1).select(f_ok(1)).then(unselect), r_err(1)); + assert_done(|| f_ok(1).select(empty()).then(unselect), Ok(1)); + assert_done(|| empty().select(f_ok(1)).then(unselect), Ok(1)); + assert_done(|| f_ok(1).join(f_err(1)), Err(1)); + assert_done(|| f_ok(1).join(Ok(2)), Ok((1, 2))); + assert_done(|| f_err(1).join(f_ok(1)), Err(1)); + assert_done(|| f_ok(1).then(|_| Ok(2)), r_ok(2)); + assert_done(|| f_ok(1).then(|_| Err(2)), r_err(2)); + assert_done(|| f_err(1).then(|_| Ok(2)), r_ok(2)); + assert_done(|| f_err(1).then(|_| Err(2)), r_err(2)); +} + +#[test] +fn test_empty() { + fn empty() -> Empty { + future::empty() + } + + assert_empty(|| empty()); + assert_empty(|| empty().select(empty())); + assert_empty(|| empty().join(empty())); + assert_empty(|| empty().join(f_ok(1))); + assert_empty(|| f_ok(1).join(empty())); + assert_empty(|| empty().or_else(move |_| empty())); + assert_empty(|| empty().and_then(move |_| empty())); + assert_empty(|| f_err(1).or_else(move |_| empty())); + assert_empty(|| f_ok(1).and_then(move |_| empty())); + assert_empty(|| empty().map(|a| a + 1)); + assert_empty(|| empty().map_err(|a| a + 1)); + assert_empty(|| empty().then(|a| a)); +} + +#[test] +fn test_ok() { + assert_done(|| ok(1), r_ok(1)); + assert_done(|| err(1), r_err(1)); +} + +#[test] +fn flatten() { + fn ok(a: T) -> FutureResult { + future::ok(a) + } + fn err(b: E) -> FutureResult { + future::err(b) + } + + assert_done(|| ok(ok(1)).flatten(), r_ok(1)); + assert_done(|| ok(err(1)).flatten(), r_err(1)); + assert_done(|| err(1u32).map(ok).flatten(), r_err(1)); + assert_done(|| future::ok(future::ok(1)).flatten(), r_ok(1)); + assert_empty(|| ok(empty::()).flatten()); + assert_empty(|| empty::().map(ok).flatten()); +} + +#[test] +fn smoke_oneshot() { + assert_done( + || { + let (c, p) = oneshot::channel(); + c.send(1).unwrap(); + p + }, + Ok(1), + ); + assert_done( + || { + let (c, p) = oneshot::channel::(); + drop(c); + p + }, + Err(Canceled), + ); + let mut completes = Vec::new(); + assert_empty(|| { + let (a, b) = oneshot::channel::(); + completes.push(a); + b + }); + + let (c, mut p) = oneshot::channel::(); + drop(c); + let res = panic_waker_lw(|lw| p.poll(lw)); + assert!(res.is_err()); + let (c, p) = oneshot::channel::(); + drop(c); + let (tx, rx) = channel(); + p.then(move |_| tx.send(())).forget(); + rx.recv().unwrap(); +} + +#[test] +fn select_cancels() { + let ((a, b), (c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |b| { + btx.send(b).unwrap(); + b + }); + let d = d.map(move |d| { + dtx.send(d).unwrap(); + d + }); + + let mut f = b.select(d).then(unselect); + // assert!(f.poll(&mut Task::new()).is_pending()); + assert!(brx.try_recv().is_err()); + assert!(drx.try_recv().is_err()); + a.send(1).unwrap(); + noop_waker_lw(|lw| { + let res = f.poll(lw); + assert!(res.ok().unwrap().is_ready()); + assert_eq!(brx.recv().unwrap(), 1); + drop(c); + assert!(drx.recv().is_err()); + + let ((a, b), (c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, _brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |b| { + btx.send(b).unwrap(); + b + }); + let d = d.map(move |d| { + dtx.send(d).unwrap(); + d + }); + + let mut f = b.select(d).then(unselect); + assert!(f.poll(lw).ok().unwrap().is_pending()); + assert!(f.poll(lw).ok().unwrap().is_pending()); + a.send(1).unwrap(); + assert!(f.poll(lw).ok().unwrap().is_ready()); + drop((c, f)); + assert!(drx.recv().is_err()); + }) +} + +#[test] +fn join_cancels() { + let ((a, b), (c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, _brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |b| { + btx.send(b).unwrap(); + b + }); + let d = d.map(move |d| { + dtx.send(d).unwrap(); + d + }); + + let mut f = b.join(d); + drop(a); + let res = panic_waker_lw(|lw| f.poll(lw)); + assert!(res.is_err()); + drop(c); + assert!(drx.recv().is_err()); + + let ((a, b), (c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, _brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |b| { + btx.send(b).unwrap(); + b + }); + let d = d.map(move |d| { + dtx.send(d).unwrap(); + d + }); + + let (tx, rx) = channel(); + let f = b.join(d); + f.then(move |_| { + tx.send(()).unwrap(); + let res: Result<(), ()> = Ok(()); + res + }) + .forget(); + assert!(rx.try_recv().is_err()); + drop(a); + rx.recv().unwrap(); + drop(c); + assert!(drx.recv().is_err()); +} + +#[test] +fn join_incomplete() { + let (a, b) = oneshot::channel::(); + let (tx, rx) = channel(); + noop_waker_lw(|lw| { + let mut f = ok(1).join(b).map(move |r| tx.send(r).unwrap()); + assert!(f.poll(lw).ok().unwrap().is_pending()); + assert!(rx.try_recv().is_err()); + a.send(2).unwrap(); + assert!(f.poll(lw).ok().unwrap().is_ready()); + assert_eq!(rx.recv().unwrap(), (1, 2)); + + let (a, b) = oneshot::channel::(); + let (tx, rx) = channel(); + let mut f = b.join(Ok(2)).map(move |r| tx.send(r).unwrap()); + assert!(f.poll(lw).ok().unwrap().is_pending()); + assert!(rx.try_recv().is_err()); + a.send(1).unwrap(); + assert!(f.poll(lw).ok().unwrap().is_ready()); + assert_eq!(rx.recv().unwrap(), (1, 2)); + + let (a, b) = oneshot::channel::(); + let (tx, rx) = channel(); + let mut f = ok(1).join(b).map_err(move |_r| tx.send(2).unwrap()); + assert!(f.poll(lw).ok().unwrap().is_pending()); + assert!(rx.try_recv().is_err()); + drop(a); + assert!(f.poll(lw).is_err()); + assert_eq!(rx.recv().unwrap(), 2); + + let (a, b) = oneshot::channel::(); + let (tx, rx) = channel(); + let mut f = b.join(Ok(2)).map_err(move |_r| tx.send(1).unwrap()); + assert!(f.poll(lw).ok().unwrap().is_pending()); + assert!(rx.try_recv().is_err()); + drop(a); + assert!(f.poll(lw).is_err()); + assert_eq!(rx.recv().unwrap(), 1); + }) +} + +#[test] +fn select2() { + assert_done(|| f_ok(2).select(empty()).then(unselect), Ok(2)); + assert_done(|| empty().select(f_ok(2)).then(unselect), Ok(2)); + assert_done(|| f_err(2).select(empty()).then(unselect), Err(2)); + assert_done(|| empty().select(f_err(2)).then(unselect), Err(2)); + + assert_done( + || { + f_ok(1).select(f_ok(2)).map_err(|_| 0).and_then(|either_tup| { + let (a, b) = either_tup.into_inner(); + b.map(move |b| a + b) + }) + }, + Ok(3), + ); + + // Finish one half of a select and then fail the second, ensuring that we + // get the notification of the second one. + { + let ((a, b), (c, d)) = (oneshot::channel::(), oneshot::channel::()); + let f = b.select(d); + let (tx, rx) = channel(); + f.map(move |r| tx.send(r).unwrap()).forget(); + a.send(1).unwrap(); + let (val, next) = rx.recv().unwrap().into_inner(); + assert_eq!(val, 1); + let (tx, rx) = channel(); + next.map_err(move |_r| tx.send(2).unwrap()).forget(); + assert_eq!(rx.try_recv().err().unwrap(), TryRecvError::Empty); + drop(c); + assert_eq!(rx.recv().unwrap(), 2); + } + + // Fail the second half and ensure that we see the first one finish + { + let ((a, b), (c, d)) = (oneshot::channel::(), oneshot::channel::()); + let f = b.select(d); + let (tx, rx) = channel(); + f.map_err(move |r| tx.send((1, r.into_inner().1)).unwrap()).forget(); + drop(c); + let (val, next) = rx.recv().unwrap(); + assert_eq!(val, 1); + let (tx, rx) = channel(); + next.map(move |r| tx.send(r).unwrap()).forget(); + assert_eq!(rx.try_recv().err().unwrap(), TryRecvError::Empty); + a.send(2).unwrap(); + assert_eq!(rx.recv().unwrap(), 2); + } + + // Cancelling the first half should cancel the second + { + let ((_a, b), (_c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |v| { + btx.send(v).unwrap(); + v + }); + let d = d.map(move |v| { + dtx.send(v).unwrap(); + v + }); + let f = b.select(d); + drop(f); + assert!(drx.recv().is_err()); + assert!(brx.recv().is_err()); + } + + // Cancel after a schedule + { + let ((_a, b), (_c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |v| { + btx.send(v).unwrap(); + v + }); + let d = d.map(move |v| { + dtx.send(v).unwrap(); + v + }); + let mut f = b.select(d); + let _res = noop_waker_lw(|lw| f.poll(lw)); + drop(f); + assert!(drx.recv().is_err()); + assert!(brx.recv().is_err()); + } + + // Cancel propagates + { + let ((a, b), (_c, d)) = (oneshot::channel::(), oneshot::channel::()); + let ((btx, brx), (dtx, drx)) = (channel(), channel()); + let b = b.map(move |v| { + btx.send(v).unwrap(); + v + }); + let d = d.map(move |v| { + dtx.send(v).unwrap(); + v + }); + let (tx, rx) = channel(); + b.select(d).map(move |_| tx.send(()).unwrap()).forget(); + drop(a); + assert!(drx.recv().is_err()); + assert!(brx.recv().is_err()); + assert!(rx.recv().is_err()); + } + + // Cancel on early drop + { + let (tx, rx) = channel(); + let f = f_ok(1).select(empty::<_, ()>().map(move |()| { + tx.send(()).unwrap(); + 1 + })); + drop(f); + assert!(rx.recv().is_err()); + } +} + +#[test] +fn option() { + assert_eq!(Ok(Some(())), block_on(Some(ok::<(), ()>(())).into_future())); + assert_eq!(Ok::<_, ()>(None::<()>), block_on(None::>.into_future())); +} diff --git a/utshell-0.5.0/vendor/futures/tests_disabled/stream.rs b/utshell-0.5.0/vendor/futures/tests_disabled/stream.rs new file mode 100644 index 00000000..a4eec2c7 --- /dev/null +++ b/utshell-0.5.0/vendor/futures/tests_disabled/stream.rs @@ -0,0 +1,368 @@ +use futures::channel::mpsc; +use futures::channel::oneshot; +use futures::executor::{block_on, block_on_stream}; +use futures::future::{err, ok}; +use futures::stream::{empty, iter_ok, poll_fn, Peekable}; + +// mod support; +// use support::*; + +pub struct Iter { + iter: I, +} + +pub fn iter(i: J) -> Iter +where + J: IntoIterator>, +{ + Iter { iter: i.into_iter() } +} + +impl Stream for Iter +where + I: Iterator>, +{ + type Item = T; + type Error = E; + + fn poll_next(&mut self, _: &mut Context<'_>) -> Poll, E> { + match self.iter.next() { + Some(Ok(e)) => Ok(Poll::Ready(Some(e))), + Some(Err(e)) => Err(e), + None => Ok(Poll::Ready(None)), + } + } +} + +fn list() -> Box + Send> { + let (tx, rx) = mpsc::channel(1); + tx.send(Ok(1)).and_then(|tx| tx.send(Ok(2))).and_then(|tx| tx.send(Ok(3))).forget(); + Box::new(rx.then(|r| r.unwrap())) +} + +fn err_list() -> Box + Send> { + let (tx, rx) = mpsc::channel(1); + tx.send(Ok(1)).and_then(|tx| tx.send(Ok(2))).and_then(|tx| tx.send(Err(3))).forget(); + Box::new(rx.then(|r| r.unwrap())) +} + +#[test] +fn map() { + assert_done(|| list().map(|a| a + 1).collect(), Ok(vec![2, 3, 4])); +} + +#[test] +fn map_err() { + assert_done(|| err_list().map_err(|a| a + 1).collect::>(), Err(4)); +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +struct FromErrTest(u32); + +impl From for FromErrTest { + fn from(i: u32) -> Self { + Self(i) + } +} + +#[test] +fn from_err() { + assert_done(|| err_list().err_into().collect::>(), Err(FromErrTest(3))); +} + +#[test] +fn fold() { + assert_done(|| list().fold(0, |a, b| ok::(a + b)), Ok(6)); + assert_done(|| err_list().fold(0, |a, b| ok::(a + b)), Err(3)); +} + +#[test] +fn filter() { + assert_done(|| list().filter(|a| ok(*a % 2 == 0)).collect(), Ok(vec![2])); +} + +#[test] +fn filter_map() { + assert_done( + || list().filter_map(|x| ok(if x % 2 == 0 { Some(x + 10) } else { None })).collect(), + Ok(vec![12]), + ); +} + +#[test] +fn and_then() { + assert_done(|| list().and_then(|a| Ok(a + 1)).collect(), Ok(vec![2, 3, 4])); + assert_done(|| list().and_then(|a| err::(a as u32)).collect::>(), Err(1)); +} + +#[test] +fn then() { + assert_done(|| list().then(|a| a.map(|e| e + 1)).collect(), Ok(vec![2, 3, 4])); +} + +#[test] +fn or_else() { + assert_done(|| err_list().or_else(|a| ok::(a as i32)).collect(), Ok(vec![1, 2, 3])); +} + +#[test] +fn flatten() { + assert_done(|| list().map(|_| list()).flatten().collect(), Ok(vec![1, 2, 3, 1, 2, 3, 1, 2, 3])); +} + +#[test] +fn skip() { + assert_done(|| list().skip(2).collect(), Ok(vec![3])); +} + +#[test] +fn skip_passes_errors_through() { + let mut s = block_on_stream(iter(vec![Err(1), Err(2), Ok(3), Ok(4), Ok(5)]).skip(1)); + assert_eq!(s.next(), Some(Err(1))); + assert_eq!(s.next(), Some(Err(2))); + assert_eq!(s.next(), Some(Ok(4))); + assert_eq!(s.next(), Some(Ok(5))); + assert_eq!(s.next(), None); +} + +#[test] +fn skip_while() { + assert_done(|| list().skip_while(|e| Ok(*e % 2 == 1)).collect(), Ok(vec![2, 3])); +} +#[test] +fn take() { + assert_done(|| list().take(2).collect(), Ok(vec![1, 2])); +} + +#[test] +fn take_while() { + assert_done(|| list().take_while(|e| Ok(*e < 3)).collect(), Ok(vec![1, 2])); +} + +#[test] +fn take_passes_errors_through() { + let mut s = block_on_stream(iter(vec![Err(1), Err(2), Ok(3), Ok(4), Err(4)]).take(1)); + assert_eq!(s.next(), Some(Err(1))); + assert_eq!(s.next(), Some(Err(2))); + assert_eq!(s.next(), Some(Ok(3))); + assert_eq!(s.next(), None); + + let mut s = block_on_stream(iter(vec![Ok(1), Err(2)]).take(1)); + assert_eq!(s.next(), Some(Ok(1))); + assert_eq!(s.next(), None); +} + +#[test] +fn peekable() { + assert_done(|| list().peekable().collect(), Ok(vec![1, 2, 3])); +} + +#[test] +fn fuse() { + let mut stream = block_on_stream(list().fuse()); + assert_eq!(stream.next(), Some(Ok(1))); + assert_eq!(stream.next(), Some(Ok(2))); + assert_eq!(stream.next(), Some(Ok(3))); + assert_eq!(stream.next(), None); + assert_eq!(stream.next(), None); + assert_eq!(stream.next(), None); +} + +#[test] +fn buffered() { + let (tx, rx) = mpsc::channel(1); + let (a, b) = oneshot::channel::(); + let (c, d) = oneshot::channel::(); + + tx.send(Box::new(b.recover(|_| panic!())) as Box + Send>) + .and_then(|tx| tx.send(Box::new(d.map_err(|_| panic!())))) + .forget(); + + let mut rx = rx.buffered(2); + sassert_empty(&mut rx); + c.send(3).unwrap(); + sassert_empty(&mut rx); + a.send(5).unwrap(); + let mut rx = block_on_stream(rx); + assert_eq!(rx.next(), Some(Ok(5))); + assert_eq!(rx.next(), Some(Ok(3))); + assert_eq!(rx.next(), None); + + let (tx, rx) = mpsc::channel(1); + let (a, b) = oneshot::channel::(); + let (c, d) = oneshot::channel::(); + + tx.send(Box::new(b.recover(|_| panic!())) as Box + Send>) + .and_then(|tx| tx.send(Box::new(d.map_err(|_| panic!())))) + .forget(); + + let mut rx = rx.buffered(1); + sassert_empty(&mut rx); + c.send(3).unwrap(); + sassert_empty(&mut rx); + a.send(5).unwrap(); + let mut rx = block_on_stream(rx); + assert_eq!(rx.next(), Some(Ok(5))); + assert_eq!(rx.next(), Some(Ok(3))); + assert_eq!(rx.next(), None); +} + +#[test] +fn unordered() { + let (tx, rx) = mpsc::channel(1); + let (a, b) = oneshot::channel::(); + let (c, d) = oneshot::channel::(); + + tx.send(Box::new(b.recover(|_| panic!())) as Box + Send>) + .and_then(|tx| tx.send(Box::new(d.recover(|_| panic!())))) + .forget(); + + let mut rx = rx.buffer_unordered(2); + sassert_empty(&mut rx); + let mut rx = block_on_stream(rx); + c.send(3).unwrap(); + assert_eq!(rx.next(), Some(Ok(3))); + a.send(5).unwrap(); + assert_eq!(rx.next(), Some(Ok(5))); + assert_eq!(rx.next(), None); + + let (tx, rx) = mpsc::channel(1); + let (a, b) = oneshot::channel::(); + let (c, d) = oneshot::channel::(); + + tx.send(Box::new(b.recover(|_| panic!())) as Box + Send>) + .and_then(|tx| tx.send(Box::new(d.recover(|_| panic!())))) + .forget(); + + // We don't even get to see `c` until `a` completes. + let mut rx = rx.buffer_unordered(1); + sassert_empty(&mut rx); + c.send(3).unwrap(); + sassert_empty(&mut rx); + a.send(5).unwrap(); + let mut rx = block_on_stream(rx); + assert_eq!(rx.next(), Some(Ok(5))); + assert_eq!(rx.next(), Some(Ok(3))); + assert_eq!(rx.next(), None); +} + +#[test] +fn zip() { + assert_done(|| list().zip(list()).collect(), Ok(vec![(1, 1), (2, 2), (3, 3)])); + assert_done(|| list().zip(list().take(2)).collect(), Ok(vec![(1, 1), (2, 2)])); + assert_done(|| list().take(2).zip(list()).collect(), Ok(vec![(1, 1), (2, 2)])); + assert_done(|| err_list().zip(list()).collect::>(), Err(3)); + assert_done(|| list().zip(list().map(|x| x + 1)).collect(), Ok(vec![(1, 2), (2, 3), (3, 4)])); +} + +#[test] +fn peek() { + struct Peek { + inner: Peekable + Send>>, + } + + impl Future for Peek { + type Item = (); + type Error = u32; + + fn poll(&mut self, cx: &mut Context<'_>) -> Poll<(), u32> { + { + let res = ready!(self.inner.peek(cx))?; + assert_eq!(res, Some(&1)); + } + assert_eq!(self.inner.peek(cx).unwrap(), Some(&1).into()); + assert_eq!(self.inner.poll_next(cx).unwrap(), Some(1).into()); + Ok(Poll::Ready(())) + } + } + + block_on(Peek { inner: list().peekable() }).unwrap() +} + +#[test] +fn wait() { + assert_eq!(block_on_stream(list()).collect::, _>>(), Ok(vec![1, 2, 3])); +} + +#[test] +fn chunks() { + assert_done(|| list().chunks(3).collect(), Ok(vec![vec![1, 2, 3]])); + assert_done(|| list().chunks(1).collect(), Ok(vec![vec![1], vec![2], vec![3]])); + assert_done(|| list().chunks(2).collect(), Ok(vec![vec![1, 2], vec![3]])); + let mut list = block_on_stream(err_list().chunks(3)); + let i = list.next().unwrap().unwrap(); + assert_eq!(i, vec![1, 2]); + let i = list.next().unwrap().unwrap_err(); + assert_eq!(i, 3); +} + +#[test] +#[should_panic] +fn chunks_panic_on_cap_zero() { + let _ = list().chunks(0); +} + +#[test] +fn forward() { + let v = Vec::new(); + let v = block_on(iter_ok::<_, Never>(vec![0, 1]).forward(v)).unwrap().1; + assert_eq!(v, vec![0, 1]); + + let v = block_on(iter_ok::<_, Never>(vec![2, 3]).forward(v)).unwrap().1; + assert_eq!(v, vec![0, 1, 2, 3]); + + assert_done( + move || iter_ok::<_, Never>(vec![4, 5]).forward(v).map(|(_, s)| s), + Ok(vec![0, 1, 2, 3, 4, 5]), + ); +} + +#[test] +fn concat() { + let a = iter_ok::<_, ()>(vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]); + assert_done(move || a.concat(), Ok(vec![1, 2, 3, 4, 5, 6, 7, 8, 9])); + + let b = iter(vec![Ok::<_, ()>(vec![1, 2, 3]), Err(()), Ok(vec![7, 8, 9])]); + assert_done(move || b.concat(), Err(())); +} + +#[test] +fn concat2() { + let a = iter_ok::<_, ()>(vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]); + assert_done(move || a.concat(), Ok(vec![1, 2, 3, 4, 5, 6, 7, 8, 9])); + + let b = iter(vec![Ok::<_, ()>(vec![1, 2, 3]), Err(()), Ok(vec![7, 8, 9])]); + assert_done(move || b.concat(), Err(())); + + let c = empty::, ()>(); + assert_done(move || c.concat(), Ok(vec![])) +} + +#[test] +fn stream_poll_fn() { + let mut counter = 5usize; + + let read_stream = poll_fn(move |_| -> Poll, std::io::Error> { + if counter == 0 { + return Ok(Poll::Ready(None)); + } + counter -= 1; + Ok(Poll::Ready(Some(counter))) + }); + + assert_eq!(block_on_stream(read_stream).count(), 5); +} + +#[test] +fn inspect() { + let mut seen = vec![]; + assert_done(|| list().inspect(|&a| seen.push(a)).collect(), Ok(vec![1, 2, 3])); + assert_eq!(seen, [1, 2, 3]); +} + +#[test] +fn inspect_err() { + let mut seen = vec![]; + assert_done(|| err_list().inspect_err(|&a| seen.push(a)).collect::>(), Err(3)); + assert_eq!(seen, [3]); +} diff --git a/utshell-0.5.0/vendor/intl-memoizer/.cargo-checksum.json b/utshell-0.5.0/vendor/intl-memoizer/.cargo-checksum.json new file mode 100644 index 00000000..60715863 --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"8f28af47927c54fd8ff3adbfcc4b0e9ea849a3b2a544289dd6be64a7aafb8ca6","LICENSE-APACHE":"5db2b182453ff32ed40f7da63589c9667a3f8bd8b16b1471b152caae56f77e45","LICENSE-MIT":"49c0b000c03731d9e3970dc059ad4ca345d773681f4a612b0024435b663e0220","README.md":"c7084646fb85a4a7031e31e917ba510a942f6ec9958b440c29754765e8f417b4","src/concurrent.rs":"d52dc59d705f1177b311a32032daef09637867c9cae80718fc5d06c5e0a8463e","src/lib.rs":"9cb0ed0f06699ead0416a70868021c32087c7fe085f64cc73dbac395f4b08fc5"},"package":"c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/intl-memoizer/Cargo.toml b/utshell-0.5.0/vendor/intl-memoizer/Cargo.toml new file mode 100644 index 00000000..1833e3f7 --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/Cargo.toml @@ -0,0 +1,35 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "intl-memoizer" +version = "0.5.1" +authors = ["Zibi Braniecki ", "Manish Goregaokar "] +include = ["src/**/*", "benches/*.rs", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +description = "A memoizer specifically tailored for storing lazy-initialized\nintl formatters.\n" +homepage = "http://www.projectfluent.org" +readme = "README.md" +keywords = ["localization", "l10n", "i18n", "intl", "internationalization"] +categories = ["localization", "internationalization"] +license = "Apache-2.0/MIT" +repository = "https://github.com/projectfluent/fluent-rs" +[dependencies.type-map] +version = "0.4" + +[dependencies.unic-langid] +version = "0.9" +[dev-dependencies.fluent-langneg] +version = "0.13" + +[dev-dependencies.intl_pluralrules] +version = "7.0.1" diff --git a/utshell-0.5.0/vendor/intl-memoizer/LICENSE-APACHE b/utshell-0.5.0/vendor/intl-memoizer/LICENSE-APACHE new file mode 100644 index 00000000..35582f16 --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Mozilla + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/intl-memoizer/LICENSE-MIT b/utshell-0.5.0/vendor/intl-memoizer/LICENSE-MIT new file mode 100644 index 00000000..5655fa31 --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright 2017 Mozilla + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/utshell-0.5.0/vendor/intl-memoizer/README.md b/utshell-0.5.0/vendor/intl-memoizer/README.md new file mode 100644 index 00000000..98e00928 --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/README.md @@ -0,0 +1,65 @@ +# IntlMemoizer + +`intl-memoizer` is a crate designed to handle lazy-initialized references +to intl formatters. + +The assumption is that allocating a new formatter instance is costly, and such +instance is read-only during its life time, with constructor being expensive, and +`format`/`select` calls being cheap. + +In result it pays off to use a singleton to manage memoization of all instances of intl +APIs such as `PluralRules`, DateTimeFormat` etc. between all `FluentBundle` instances. + +Usage +----- + +```rust +use intl_memoizer::{IntlMemoizer, Memoizable}; +use unic_langid::langid; + +use intl_pluralrules::{PluralRules, PluralRuleType, PluralCategory}; + +impl Memoizable for PluralRules { + type Args = (PluralRulesType,); + fn construct(lang: LanguageIdentifier, args: Self::Args) -> Self { + Self::new(lang, args.0) + } +} + +fn main() { + let lang = langid!("en-US"); + + // A single memoizer for all languages + let mut memoizer = IntlMemoizer::new(); + + // A RefCell for a particular language to be used in all `FluentBundle` + // instances. + let mut en_us_memoizer = memoizer.get_for_lang(lang.clone()); + + // Per-call borrow + let mut en_us_memoizer_borrow = en_us_memoizer.borrow_mut(); + let cb = en_us_memoizer_borrow.get::((PluralRulesType::Cardinal,)); + assert_eq!(cb.select(1), PluralCategory::One); +} + +``` + +Get Involved +------------ + +`fluent-rs` is open-source, licensed under the Apache License, Version 2.0. We +encourage everyone to take a look at our code and we'll listen to your +feedback. + + +Discuss +------- + +We'd love to hear your thoughts on Project Fluent! Whether you're a localizer +looking for a better way to express yourself in your language, or a developer +trying to make your app localizable and multilingual, or a hacker looking for +a project to contribute to, please do get in touch on the mailing list and the +IRC channel. + + - Discourse: https://discourse.mozilla.org/c/fluent + - IRC channel: [irc://irc.mozilla.org/l20n](irc://irc.mozilla.org/l20n) diff --git a/utshell-0.5.0/vendor/intl-memoizer/src/concurrent.rs b/utshell-0.5.0/vendor/intl-memoizer/src/concurrent.rs new file mode 100644 index 00000000..95553281 --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/src/concurrent.rs @@ -0,0 +1,39 @@ +use super::*; +use std::sync::Mutex; + +#[derive(Debug)] +pub struct IntlLangMemoizer { + lang: LanguageIdentifier, + map: Mutex, +} + +impl IntlLangMemoizer { + pub fn new(lang: LanguageIdentifier) -> Self { + Self { + lang, + map: Mutex::new(type_map::concurrent::TypeMap::new()), + } + } + + pub fn with_try_get(&self, args: I::Args, cb: U) -> Result + where + Self: Sized, + I: Memoizable + Sync + Send + 'static, + I::Args: Send + Sync + 'static, + U: FnOnce(&I) -> R, + { + let mut map = self.map.lock().unwrap(); + let cache = map + .entry::>() + .or_insert_with(HashMap::new); + + let e = match cache.entry(args.clone()) { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => { + let val = I::construct(self.lang.clone(), args)?; + entry.insert(val) + } + }; + Ok(cb(&e)) + } +} diff --git a/utshell-0.5.0/vendor/intl-memoizer/src/lib.rs b/utshell-0.5.0/vendor/intl-memoizer/src/lib.rs new file mode 100644 index 00000000..8205616a --- /dev/null +++ b/utshell-0.5.0/vendor/intl-memoizer/src/lib.rs @@ -0,0 +1,140 @@ +use std::cell::RefCell; +use std::collections::hash_map::Entry; +use std::collections::HashMap; +use std::hash::Hash; +use std::rc::{Rc, Weak}; +use unic_langid::LanguageIdentifier; + +pub mod concurrent; + +pub trait Memoizable { + type Args: 'static + Eq + Hash + Clone; + type Error; + fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result + where + Self: std::marker::Sized; +} + +#[derive(Debug)] +pub struct IntlLangMemoizer { + lang: LanguageIdentifier, + map: RefCell, +} + +impl IntlLangMemoizer { + pub fn new(lang: LanguageIdentifier) -> Self { + Self { + lang, + map: RefCell::new(type_map::TypeMap::new()), + } + } + + pub fn with_try_get(&self, args: I::Args, cb: U) -> Result + where + Self: Sized, + I: Memoizable + 'static, + U: FnOnce(&I) -> R, + { + let mut map = self + .map + .try_borrow_mut() + .expect("Cannot use memoizer reentrantly"); + let cache = map + .entry::>() + .or_insert_with(HashMap::new); + + let e = match cache.entry(args.clone()) { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => { + let val = I::construct(self.lang.clone(), args)?; + entry.insert(val) + } + }; + Ok(cb(&e)) + } +} + +#[derive(Default)] +pub struct IntlMemoizer { + map: HashMap>, +} + +impl IntlMemoizer { + pub fn get_for_lang(&mut self, lang: LanguageIdentifier) -> Rc { + match self.map.entry(lang.clone()) { + Entry::Vacant(empty) => { + let entry = Rc::new(IntlLangMemoizer::new(lang)); + empty.insert(Rc::downgrade(&entry)); + entry + } + Entry::Occupied(mut entry) => { + if let Some(entry) = entry.get().upgrade() { + entry + } else { + let e = Rc::new(IntlLangMemoizer::new(lang)); + entry.insert(Rc::downgrade(&e)); + e + } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use fluent_langneg::{negotiate_languages, NegotiationStrategy}; + use intl_pluralrules::{PluralCategory, PluralRuleType, PluralRules as IntlPluralRules}; + + struct PluralRules(pub IntlPluralRules); + + impl PluralRules { + pub fn new( + lang: LanguageIdentifier, + pr_type: PluralRuleType, + ) -> Result { + let default_lang: LanguageIdentifier = "en".parse().unwrap(); + let pr_lang = negotiate_languages( + &[lang], + &IntlPluralRules::get_locales(pr_type), + Some(&default_lang), + NegotiationStrategy::Lookup, + )[0] + .clone(); + + Ok(Self(IntlPluralRules::create(pr_lang, pr_type)?)) + } + } + + impl Memoizable for PluralRules { + type Args = (PluralRuleType,); + type Error = &'static str; + fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result { + Self::new(lang, args.0) + } + } + + #[test] + fn it_works() { + let lang: LanguageIdentifier = "en".parse().unwrap(); + + let mut memoizer = IntlMemoizer::default(); + { + let en_memoizer = memoizer.get_for_lang(lang.clone()); + + let result = en_memoizer + .with_try_get::((PluralRuleType::CARDINAL,), |cb| cb.0.select(5)) + .unwrap(); + assert_eq!(result, Ok(PluralCategory::OTHER)); + } + + { + let en_memoizer = memoizer.get_for_lang(lang.clone()); + + let result = en_memoizer + .with_try_get::((PluralRuleType::CARDINAL,), |cb| cb.0.select(5)) + .unwrap(); + assert_eq!(result, Ok(PluralCategory::OTHER)); + } + } +} diff --git a/utshell-0.5.0/vendor/intl_pluralrules/.cargo-checksum.json b/utshell-0.5.0/vendor/intl_pluralrules/.cargo-checksum.json new file mode 100644 index 00000000..e72c5920 --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"595634ece6249e274c389db766170aa88f78df41e8887d333a7cac8dad6b0bed","README.md":"7516007e35aa847bf81b8b94f45181f532bdc0aad3e389efd14691fa3aace3f0","benches/pluralrules.rs":"9c80009fa94a8dbf31bdba489f320d92a40f482c37149030fbba53cd62b5435f","src/lib.rs":"054fd83f1e8b42ef7866ec681c59617952cad48f578ca338e945d2a99178ea7d","src/operands.rs":"68d920f66ed67f361b3b0387844dbb8db57fad660f84cfcb361d8f4f5157832a","src/rules.rs":"7b3f0c12e0722401efbdb54873e8545f943bf4a34cba9f894ead9dc955112aaf"},"package":"078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/intl_pluralrules/Cargo.toml b/utshell-0.5.0/vendor/intl_pluralrules/Cargo.toml new file mode 100644 index 00000000..b5db6e60 --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/Cargo.toml @@ -0,0 +1,66 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "intl_pluralrules" +version = "7.0.2" +authors = [ + "Kekoa Riggin ", + "Zibi Braniecki ", +] +include = [ + "src/**/*", + "benches/*.rs", + "Cargo.toml", + "README.md", +] +description = "Unicode Plural Rules categorizer for numeric input." +readme = "README.md" +keywords = [ + "localization", + "l10n", + "i18n", + "intl", + "internationalization", +] +categories = [ + "localization", + "internationalization", +] +license = "Apache-2.0/MIT" +repository = "https://github.com/zbraniecki/pluralrules" + +[[bench]] +name = "pluralrules" +harness = false + +[dependencies.unic-langid] +version = "0.9" + +[dev-dependencies.criterion] +version = "0.3" + +[dev-dependencies.unic-langid] +version = "0.9" +features = ["macros"] + +[badges.coveralls] +branch = "master" +repository = "zbraniecki/pluralrules" +service = "github" + +[badges.maintenance] +status = "actively-developed" + +[badges.travis-ci] +branch = "master" +repository = "zbraniecki/pluralrules" diff --git a/utshell-0.5.0/vendor/intl_pluralrules/README.md b/utshell-0.5.0/vendor/intl_pluralrules/README.md new file mode 100644 index 00000000..50191d96 --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/README.md @@ -0,0 +1,42 @@ +# INTL Plural Rules + +`intl_pluralrules` categorizes numbers by plural operands. See [Unicode Plural Rules](https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules) + + +[![crates.io](https://img.shields.io/crates/v/intl_pluralrules.svg)](https://crates.io/crates/intl_pluralrules) +[![Build Status](https://travis-ci.org/zbraniecki/pluralrules.svg?branch=master)](https://travis-ci.org/zbraniecki/pluralrules) +[![Coverage Status](https://coveralls.io/repos/github/zbraniecki/pluralrules/badge.svg?branch=master)](https://coveralls.io/github/zbraniecki/pluralrules?branch=master) + +This library is intended to be used to find the plural category of numeric input. + +Status +------ + +Currently produces operands compliant with CLDR 36 into Rust 1.31 and above. + +**Updating CLDR Data** + +If you would like to update rules.rs with plural rules that are not the specified version above (e.g. future versions of CLDR or external CLDR-compliant rules), you can regenerate the logic in rules.rs with the command: + + cargo regenerate-data + +You will need to replace the JSON files under `/cldr_data/` with your new CLDR JSON files. + +Local Development +----------------- + + cargo build + cargo test + +When submitting a PR please use `cargo fmt`. + +Contributors +------------ + +* [manishearth](https://github.com/manishearth) + +Thank you to all contributors! + +[CLDR]: https://cldr.unicode.org/ +[PluralRules]: https://cldr.unicode.org/index/cldr-spec/plural-rules +[LDML Language Plural Rules Syntax]: https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules diff --git a/utshell-0.5.0/vendor/intl_pluralrules/benches/pluralrules.rs b/utshell-0.5.0/vendor/intl_pluralrules/benches/pluralrules.rs new file mode 100644 index 00000000..c1e673aa --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/benches/pluralrules.rs @@ -0,0 +1,69 @@ +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::BenchmarkId; +use criterion::Criterion; + +use intl_pluralrules::{PluralRuleType, PluralRules}; +use unic_langid::{langid, LanguageIdentifier}; + +fn plural_rules(c: &mut Criterion) { + let langs = &["uk", "de", "sk", "ar", "fr", "it", "en", "cs", "es", "zh"]; + let langs: Vec = langs + .iter() + .map(|l| l.parse().expect("Parsing failed")) + .collect(); + + c.bench_with_input( + BenchmarkId::new("construct", langs.len()), + &langs, + |b, langs| { + b.iter(|| { + for lang in langs { + PluralRules::create(lang.clone(), PluralRuleType::ORDINAL).unwrap(); + PluralRules::create(lang.clone(), PluralRuleType::CARDINAL).unwrap(); + } + }); + }, + ); + + let samples = &[ + 1, 2, 3, 4, 5, 25, 134, 910293019, 12, 1412, -12, 15, 2931, 31231, 3123, 13231, 91, 0, 231, + -2, -45, 33, 728, 2, 291, 24, 479, 291, 778, 919, 93, + ]; + + let langid_pl = langid!("pl"); + let ipr = PluralRules::create(langid_pl.clone(), PluralRuleType::CARDINAL).unwrap(); + + c.bench_with_input( + BenchmarkId::new("select", samples.len()), + samples, + |b, samples| { + b.iter(|| { + for value in samples { + ipr.select(*value).unwrap(); + } + }); + }, + ); + + c.bench_function("total", |b| { + b.iter(|| { + let ipr = PluralRules::create(langid_pl.clone(), PluralRuleType::CARDINAL).unwrap(); + ipr.select(1).unwrap(); + ipr.select(2).unwrap(); + ipr.select(3).unwrap(); + ipr.select(4).unwrap(); + ipr.select(5).unwrap(); + ipr.select(25).unwrap(); + ipr.select(134).unwrap(); + ipr.select(5090).unwrap(); + ipr.select(910293019).unwrap(); + ipr.select(5.2).unwrap(); + ipr.select(-0.2).unwrap(); + ipr.select("12.06").unwrap(); + }) + }); +} + +criterion_group!(benches, plural_rules,); +criterion_main!(benches); diff --git a/utshell-0.5.0/vendor/intl_pluralrules/src/lib.rs b/utshell-0.5.0/vendor/intl_pluralrules/src/lib.rs new file mode 100644 index 00000000..84a2fd63 --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/src/lib.rs @@ -0,0 +1,225 @@ +//! A crate for generating plural rule operands from numberical input. +//! +//! This crate generates plural operands according to the specifications outlined at [Unicode's website](https://unicode.org/reports/tr35/tr35-numbers.html#Operands). +//! +//! Input is supported for int, float, and &str. +//! +//! # Examples +//! +//! Plural rules example for Polish +//! +//! ``` +//! use intl_pluralrules::{PluralRules, PluralRuleType, PluralCategory}; +//! use unic_langid::LanguageIdentifier; +//! +//! let langid: LanguageIdentifier = "pl".parse().expect("Parsing failed."); +//! +//! assert!(PluralRules::get_locales(PluralRuleType::CARDINAL).contains(&langid)); +//! +//! let pr = PluralRules::create(langid.clone(), PluralRuleType::CARDINAL).unwrap(); +//! assert_eq!(pr.select(1), Ok(PluralCategory::ONE)); +//! assert_eq!(pr.select("3"), Ok(PluralCategory::FEW)); +//! assert_eq!(pr.select(12), Ok(PluralCategory::MANY)); +//! assert_eq!(pr.select("5.0"), Ok(PluralCategory::OTHER)); +//! +//! assert_eq!(pr.get_locale(), &langid); +//! ``` + +/// A public AST module for plural rule representations. +pub mod operands; +#[cfg(not(tarpaulin_include))] +mod rules; + +use std::convert::TryInto; + +use unic_langid::LanguageIdentifier; + +use crate::operands::PluralOperands; +use crate::rules::*; + +/// A public enum for handling the plural category. +/// Each plural category will vary, depending on the language that is being used and whether that language has that plural category. +#[derive(Debug, Eq, PartialEq)] +pub enum PluralCategory { + ZERO, + ONE, + TWO, + FEW, + MANY, + OTHER, +} + +/// A public enum for handling plural type. +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum PluralRuleType { + /// Ordinal numbers express position or rank in a sequence. [More about oridinal numbers](https://en.wikipedia.org/wiki/Ordinal_number_(linguistics)) + ORDINAL, + /// Cardinal numbers are natural numbers. [More about cardinal numbers](https://en.wikipedia.org/wiki/Cardinal_number) + CARDINAL, +} + +// pub use rules::PluralRuleType; +/// CLDR_VERSION is the version of CLDR extracted from the file used to generate rules.rs. +pub use crate::rules::CLDR_VERSION; + +/// The main structure for selecting plural rules. +/// +/// # Examples +/// +/// ``` +/// use intl_pluralrules::{PluralRules, PluralRuleType, PluralCategory}; +/// use unic_langid::LanguageIdentifier; +/// +/// let langid: LanguageIdentifier = "naq".parse().expect("Parsing failed."); +/// let pr_naq = PluralRules::create(langid, PluralRuleType::CARDINAL).unwrap(); +/// assert_eq!(pr_naq.select(1), Ok(PluralCategory::ONE)); +/// assert_eq!(pr_naq.select("2"), Ok(PluralCategory::TWO)); +/// assert_eq!(pr_naq.select(5.0), Ok(PluralCategory::OTHER)); +/// ``` +#[derive(Clone)] +pub struct PluralRules { + locale: LanguageIdentifier, + function: PluralRule, +} + +impl PluralRules { + /// Returns an instance of PluralRules. + /// + /// # Examples + /// ``` + /// use intl_pluralrules::{PluralRules, PluralRuleType, PluralCategory}; + /// use unic_langid::LanguageIdentifier; + /// + /// let langid: LanguageIdentifier = "naq".parse().expect("Parsing failed."); + /// let pr_naq = PluralRules::create(langid, PluralRuleType::CARDINAL); + /// assert_eq!(pr_naq.is_ok(), !pr_naq.is_err()); + /// + /// let langid: LanguageIdentifier = "xx".parse().expect("Parsing failed."); + /// let pr_broken = PluralRules::create(langid, PluralRuleType::CARDINAL); + /// assert_eq!(pr_broken.is_err(), !pr_broken.is_ok()); + /// ``` + pub fn create>( + langid: L, + prt: PluralRuleType, + ) -> Result { + let langid = langid.into(); + let returned_rule = match prt { + PluralRuleType::CARDINAL => { + let idx = rules::PRS_CARDINAL.binary_search_by_key(&&langid, |(l, _)| l); + idx.map(|idx| rules::PRS_CARDINAL[idx].1) + } + PluralRuleType::ORDINAL => { + let idx = rules::PRS_ORDINAL.binary_search_by_key(&&langid, |(l, _)| l); + idx.map(|idx| rules::PRS_ORDINAL[idx].1) + } + }; + match returned_rule { + Ok(returned_rule) => Ok(Self { + locale: langid, + function: returned_rule, + }), + Err(_) => Err("unknown locale"), + } + } + + /// Returns a result of the plural category for the given input. + /// + /// If the input is not numeric. + /// + /// # Examples + /// ``` + /// use intl_pluralrules::{PluralRules, PluralRuleType, PluralCategory}; + /// use unic_langid::LanguageIdentifier; + /// + /// let langid: LanguageIdentifier = "naq".parse().expect("Parsing failed."); + /// let pr_naq = PluralRules::create(langid, PluralRuleType::CARDINAL).unwrap(); + /// assert_eq!(pr_naq.select(1), Ok(PluralCategory::ONE)); + /// assert_eq!(pr_naq.select(2), Ok(PluralCategory::TWO)); + /// assert_eq!(pr_naq.select(5), Ok(PluralCategory::OTHER)); + /// ``` + pub fn select>( + &self, + number: N, + ) -> Result { + let ops = number.try_into(); + let pr = self.function; + match ops { + Ok(ops) => Ok(pr(&ops)), + Err(_) => Err("Argument can not be parsed to operands."), + } + } + + /// Returns a list of the available locales. + /// + /// # Examples + /// ``` + /// use intl_pluralrules::{PluralRules, PluralRuleType}; + /// + /// assert_eq!( + /// PluralRules::get_locales(PluralRuleType::CARDINAL).is_empty(), + /// false + /// ); + /// ``` + pub fn get_locales(prt: PluralRuleType) -> Vec { + let prs = match prt { + PluralRuleType::CARDINAL => rules::PRS_CARDINAL, + PluralRuleType::ORDINAL => rules::PRS_ORDINAL, + }; + prs.iter().map(|(l, _)| l.clone()).collect() + } + + /// Returns the locale name for this PluralRule instance. + /// + /// # Examples + /// ``` + /// use intl_pluralrules::{PluralRules, PluralRuleType}; + /// use unic_langid::LanguageIdentifier; + /// + /// let langid: LanguageIdentifier = "naq".parse().expect("Parsing failed."); + /// let pr_naq = PluralRules::create(langid.clone(), PluralRuleType::CARDINAL).unwrap(); + /// assert_eq!(pr_naq.get_locale(), &langid); + /// ``` + pub fn get_locale(&self) -> &LanguageIdentifier { + &self.locale + } +} + +#[cfg(test)] +mod tests { + use super::{PluralCategory, PluralRuleType, PluralRules, CLDR_VERSION}; + use unic_langid::LanguageIdentifier; + + #[test] + fn cardinals_test() { + let langid: LanguageIdentifier = "naq".parse().expect("Parsing failed."); + let pr_naq = PluralRules::create(langid, PluralRuleType::CARDINAL).unwrap(); + assert_eq!(pr_naq.select(1), Ok(PluralCategory::ONE)); + assert_eq!(pr_naq.select(2), Ok(PluralCategory::TWO)); + assert_eq!(pr_naq.select(5), Ok(PluralCategory::OTHER)); + + let langid: LanguageIdentifier = "xx".parse().expect("Parsing failed."); + let pr_broken = PluralRules::create(langid, PluralRuleType::CARDINAL); + assert_eq!(pr_broken.is_err(), !pr_broken.is_ok()); + } + + #[test] + fn ordinals_rules() { + let langid: LanguageIdentifier = "uk".parse().expect("Parsing failed."); + let pr_naq = PluralRules::create(langid, PluralRuleType::ORDINAL).unwrap(); + assert_eq!(pr_naq.select(33), Ok(PluralCategory::FEW)); + assert_eq!(pr_naq.select(113), Ok(PluralCategory::OTHER)); + } + + #[test] + fn version_test() { + assert_eq!(CLDR_VERSION, 37); + } + + #[test] + fn locale_test() { + assert_eq!( + PluralRules::get_locales(PluralRuleType::CARDINAL).is_empty(), + false + ); + } +} diff --git a/utshell-0.5.0/vendor/intl_pluralrules/src/operands.rs b/utshell-0.5.0/vendor/intl_pluralrules/src/operands.rs new file mode 100644 index 00000000..102ae874 --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/src/operands.rs @@ -0,0 +1,186 @@ +//! Plural operands in compliance with [CLDR Plural Rules](https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules). +//! +//! See [full operands description](https://unicode.org/reports/tr35/tr35-numbers.html#Operands). +//! +//! # Examples +//! +//! From int +//! +//! ``` +//! use std::convert::TryFrom; +//! use intl_pluralrules::operands::*; +//! assert_eq!(Ok(PluralOperands { +//! n: 2_f64, +//! i: 2, +//! v: 0, +//! w: 0, +//! f: 0, +//! t: 0, +//! }), PluralOperands::try_from(2)) +//! ``` +//! +//! From float +//! +//! ``` +//! use std::convert::TryFrom; +//! use intl_pluralrules::operands::*; +//! assert_eq!(Ok(PluralOperands { +//! n: 1234.567_f64, +//! i: 1234, +//! v: 3, +//! w: 3, +//! f: 567, +//! t: 567, +//! }), PluralOperands::try_from("-1234.567")) +//! ``` +//! +//! From &str +//! +//! ``` +//! use std::convert::TryFrom; +//! use intl_pluralrules::operands::*; +//! assert_eq!(Ok(PluralOperands { +//! n: 123.45_f64, +//! i: 123, +//! v: 2, +//! w: 2, +//! f: 45, +//! t: 45, +//! }), PluralOperands::try_from(123.45)) +//! ``` +#![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] +use std::convert::TryFrom; +use std::isize; +use std::str::FromStr; + +/// A full plural operands representation of a number. See [CLDR Plural Rules](https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules) for complete operands description. +#[derive(Debug, PartialEq)] +pub struct PluralOperands { + /// Absolute value of input + pub n: f64, + /// Integer value of input + pub i: u64, + /// Number of visible fraction digits with trailing zeros + pub v: usize, + /// Number of visible fraction digits without trailing zeros + pub w: usize, + /// Visible fraction digits with trailing zeros + pub f: u64, + /// Visible fraction digits without trailing zeros + pub t: u64, +} + +impl<'a> TryFrom<&'a str> for PluralOperands { + type Error = &'static str; + + fn try_from(input: &'a str) -> Result { + let abs_str = if input.starts_with('-') { + &input[1..] + } else { + &input + }; + + let absolute_value = f64::from_str(&abs_str).map_err(|_| "Incorrect number passed!")?; + + let integer_digits; + let num_fraction_digits0; + let num_fraction_digits; + let fraction_digits0; + let fraction_digits; + + if let Some(dec_pos) = abs_str.find('.') { + let int_str = &abs_str[..dec_pos]; + let dec_str = &abs_str[(dec_pos + 1)..]; + + integer_digits = + u64::from_str(&int_str).map_err(|_| "Could not convert string to integer!")?; + + let backtrace = dec_str.trim_end_matches('0'); + + num_fraction_digits0 = dec_str.len() as usize; + num_fraction_digits = backtrace.len() as usize; + fraction_digits0 = + u64::from_str(dec_str).map_err(|_| "Could not convert string to integer!")?; + fraction_digits = u64::from_str(backtrace).unwrap_or(0); + } else { + integer_digits = absolute_value as u64; + num_fraction_digits0 = 0; + num_fraction_digits = 0; + fraction_digits0 = 0; + fraction_digits = 0; + } + + Ok(PluralOperands { + n: absolute_value, + i: integer_digits, + v: num_fraction_digits0, + w: num_fraction_digits, + f: fraction_digits0, + t: fraction_digits, + }) + } +} + +macro_rules! impl_integer_type { + ($ty:ident) => { + impl From<$ty> for PluralOperands { + fn from(input: $ty) -> Self { + // XXXManishearth converting from u32 or u64 to isize may wrap + PluralOperands { + n: input as f64, + i: input as u64, + v: 0, + w: 0, + f: 0, + t: 0, + } + } + } + }; + ($($ty:ident)+) => { + $(impl_integer_type!($ty);)+ + }; +} + +macro_rules! impl_signed_integer_type { + ($ty:ident) => { + impl TryFrom<$ty> for PluralOperands { + type Error = &'static str; + fn try_from(input: $ty) -> Result { + // XXXManishearth converting from i64 to isize may wrap + let x = (input as isize).checked_abs().ok_or("Number too big")?; + Ok(PluralOperands { + n: x as f64, + i: x as u64, + v: 0, + w: 0, + f: 0, + t: 0, + }) + } + } + }; + ($($ty:ident)+) => { + $(impl_signed_integer_type!($ty);)+ + }; +} + +macro_rules! impl_convert_type { + ($ty:ident) => { + impl TryFrom<$ty> for PluralOperands { + type Error = &'static str; + fn try_from(input: $ty) -> Result { + let as_str: &str = &input.to_string(); + PluralOperands::try_from(as_str) + } + } + }; + ($($ty:ident)+) => { + $(impl_convert_type!($ty);)+ + }; +} + +impl_integer_type!(u8 u16 u32 u64 usize); +impl_signed_integer_type!(i8 i16 i32 i64 isize); +// XXXManishearth we can likely have dedicated float impls here +impl_convert_type!(f32 f64 String); diff --git a/utshell-0.5.0/vendor/intl_pluralrules/src/rules.rs b/utshell-0.5.0/vendor/intl_pluralrules/src/rules.rs new file mode 100644 index 00000000..35984b64 --- /dev/null +++ b/utshell-0.5.0/vendor/intl_pluralrules/src/rules.rs @@ -0,0 +1,3187 @@ +#![allow(unused_variables, unused_parens)] +#![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp))] +#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))] +#![cfg_attr(feature = "cargo-clippy", allow(clippy::nonminimal_bool))] +use super::operands::PluralOperands; +use super::PluralCategory; +use unic_langid::subtags; +use unic_langid::LanguageIdentifier; +pub type PluralRule = fn(&PluralOperands) -> PluralCategory; +pub static CLDR_VERSION: usize = 37; +macro_rules! langid { + ( $ lang : expr , $ script : expr , $ region : expr ) => {{ + unsafe { LanguageIdentifier::from_raw_parts_unchecked($lang, $script, $region, None) } + }}; +} +pub const PRS_CARDINAL: &[(LanguageIdentifier, PluralRule)] = &[ + ( + langid!(subtags::Language::from_raw_unchecked(26209u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27489u64), None, None), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28001u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28257u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29281u64), None, None), + |po| { + if ((3..=10).contains(&(po.i))) { + PluralCategory::FEW + } else if ((11..=99).contains(&(po.i))) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else if (po.n == 0.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7565921u64), + None, + None + ), + |po| { + if ((3..=10).contains(&(po.i))) { + PluralCategory::FEW + } else if ((11..=99).contains(&(po.i))) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else if (po.n == 0.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29537u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6386529u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7631713u64), + None, + None + ), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31329u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25954u64), None, None), + |po| { + if ((2..=4).contains(&(po.i)) && !(12..=14).contains(&(po.i))) { + PluralCategory::FEW + } else if (po.i % 10 == 0) + || ((5..=9).contains(&(po.i))) + || ((11..=14).contains(&(po.i))) + { + PluralCategory::MANY + } else if (po.i % 10 == 1 && po.i % 100 != 11) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7169378u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(8021346u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26466u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7301218u64), + None, + None + ), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28002u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28258u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28514u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29282u64), None, None), + |po| { + if ((po.i % 10 == 9 || (3..=4).contains(&(po.i))) + && !(10..=19).contains(&(po.i)) + && !(70..=79).contains(&(po.i)) + && !(90..=99).contains(&(po.i))) + { + PluralCategory::FEW + } else if (po.n != 0.0 && po.i % 1000000 == 0) { + PluralCategory::MANY + } else if (po.i % 10 == 1 && po.i % 100 != 11 && po.i % 100 != 71 && po.i % 100 != 91) { + PluralCategory::ONE + } else if (po.i % 10 == 2 && po.i % 100 != 12 && po.i % 100 != 72 && po.i % 100 != 92) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7893602u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29538u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) + || ((2..=4).contains(&(po.f % 10)) && !(12..=14).contains(&(po.f % 100))) + { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) + || (po.f % 10 == 1 && po.f % 100 != 11) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24931u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25955u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6448483u64), + None, + None + ), + |po| { + if (po.v == 0 && (po.i == 1 || po.i == 2 || po.i == 3)) + || (po.v == 0 && po.i % 10 != 4 && po.i % 10 != 6 && po.i % 10 != 9) + || (po.v != 0 && po.f % 10 != 4 && po.f % 10 != 6 && po.f % 10 != 9) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6776675u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7497827u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6450019u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29539u64), None, None), + |po| { + if ((2..=4).contains(&(po.i)) && po.v == 0) { + PluralCategory::FEW + } else if (po.v != 0) { + PluralCategory::MANY + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31075u64), None, None), + |po| { + if (po.n == 3.0) { + PluralCategory::FEW + } else if (po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else if (po.n == 0.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24932u64), None, None), + |po| { + if (po.n == 1.0) || (po.t != 0 && (po.i == 0 || po.i == 1)) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25956u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6452068u64), + None, + None + ), + |po| { + if (po.v == 0 && (3..=4).contains(&(po.i % 100))) || ((3..=4).contains(&(po.f % 100))) { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 100 == 1) || (po.f % 100 == 1) { + PluralCategory::ONE + } else if (po.v == 0 && po.i % 100 == 2) || (po.f % 100 == 2) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30308u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31332u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25957u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27749u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28261u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28517u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29541u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29797u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30053u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24934u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26214u64), None, None), + |po| { + if (po.i == 0 || po.i == 1) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26982u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7104870u64), + None, + None + ), + |po| { + if (po.v == 0 && (po.i == 1 || po.i == 2 || po.i == 3)) + || (po.v == 0 && po.i % 10 != 4 && po.i % 10 != 6 && po.i % 10 != 9) + || (po.v != 0 && po.f % 10 != 4 && po.f % 10 != 6 && po.f % 10 != 9) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28518u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29286u64), None, None), + |po| { + if (po.i == 0 || po.i == 1) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7501158u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31078u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24935u64), None, None), + |po| { + if ((3..=6).contains(&(po.i)) && po.f == 0) { + PluralCategory::FEW + } else if ((7..=10).contains(&(po.i)) && po.f == 0) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25703u64), None, None), + |po| { + if ((3..=10).contains(&(po.i)) && po.f == 0 || (13..=19).contains(&(po.i)) && po.f == 0) + { + PluralCategory::FEW + } else if (po.n == 1.0 || po.n == 11.0) { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 12.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27751u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7828327u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30055u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7828839u64), + None, + None + ), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30311u64), None, None), + |po| { + if (po.v == 0 + && (po.i % 100 == 0 + || po.i % 100 == 20 + || po.i % 100 == 40 + || po.i % 100 == 60 + || po.i % 100 == 80)) + { + PluralCategory::FEW + } else if (po.v != 0) { + PluralCategory::MANY + } else if (po.v == 0 && po.i % 10 == 1) { + PluralCategory::ONE + } else if (po.v == 0 && po.i % 10 == 2) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24936u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7823720u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25960u64), None, None), + |po| { + if (po.v == 0 && !(0..=10).contains(&(po.i)) && po.f == 0 && po.i % 10 == 0) { + PluralCategory::MANY + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else if (po.i == 2 && po.v == 0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26984u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29288u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) + || ((2..=4).contains(&(po.f % 10)) && !(12..=14).contains(&(po.f % 100))) + { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) + || (po.f % 10 == 1 && po.f % 100 != 11) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6452072u64), + None, + None + ), + |po| { + if (po.v == 0 && (3..=4).contains(&(po.i % 100))) || ((3..=4).contains(&(po.f % 100))) { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 100 == 1) || (po.f % 100 == 1) { + PluralCategory::ONE + } else if (po.v == 0 && po.i % 100 == 2) || (po.f % 100 == 2) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30056u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31080u64), None, None), + |po| { + if (po.i == 0 || po.i == 1) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24937u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25705u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26473u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26985u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28265u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28521u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29545u64), None, None), + |po| { + if (po.t == 0 && po.i % 10 == 1 && po.i % 100 != 11) || (po.t != 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29801u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30057u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30569u64), None, None), + |po| { + if (po.v == 0 && !(0..=10).contains(&(po.i)) && po.f == 0 && po.i % 10 == 0) { + PluralCategory::MANY + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else if (po.i == 2 && po.v == 0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24938u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7299690u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7300970u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26986u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6516074u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30314u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30570u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24939u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6447467u64), + None, + None + ), + |po| { + if (po.i == 0 || po.i == 1) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6971755u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6775659u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6644843u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6382955u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27499u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6974315u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27755u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28011u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28267u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28523u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29547u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6452075u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6845291u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 0.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30059u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30571u64), None, None), + |po| { + if (po.i % 100 == 3 + || po.i % 100 == 23 + || po.i % 100 == 43 + || po.i % 100 == 63 + || po.i % 100 == 83) + { + PluralCategory::FEW + } else if (po.n != 1.0 + && (po.i % 100 == 1 + || po.i % 100 == 21 + || po.i % 100 == 41 + || po.i % 100 == 61 + || po.i % 100 == 81)) + { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.i % 100 == 2 + || po.i % 100 == 22 + || po.i % 100 == 42 + || po.i % 100 == 62 + || po.i % 100 == 82) + || (po.i % 1000 == 0 + && (po.i % 100000 == 40000 + || po.i % 100000 == 60000 + || po.i % 100000 == 80000 + || (1000..=20000).contains(&(po.i)))) + || (po.n != 0.0 && po.i % 1000000 == 100000) + { + PluralCategory::TWO + } else if (po.n == 0.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31083u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6775148u64), + None, + None + ), + |po| { + if ((po.i == 0 || po.i == 1) && po.n != 0.0) { + PluralCategory::ONE + } else if (po.n == 0.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25196u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26476u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7629676u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28268u64), None, None), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28524u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29804u64), None, None), + |po| { + if ((2..=9).contains(&(po.i)) && !(11..=19).contains(&(po.i))) { + PluralCategory::FEW + } else if (po.f != 0) { + PluralCategory::MANY + } else if (po.i % 10 == 1 && !(11..=19).contains(&(po.i))) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30316u64), None, None), + |po| { + if (po.i % 10 == 1 && po.i % 100 != 11) + || (po.v == 2 && po.f % 10 == 1 && po.f % 100 != 11) + || (po.v != 2 && po.f % 10 == 1) + { + PluralCategory::ONE + } else if (po.i % 10 == 0) + || ((11..=19).contains(&(po.i))) + || (po.v == 2 && (11..=19).contains(&(po.f % 100))) + { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7561581u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26477u64), None, None), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7300973u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27501u64), None, None), + |po| { + if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) + || (po.f % 10 == 1 && po.f % 100 != 11) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27757u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28269u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28525u64), None, None), + |po| { + if (po.v != 0) || (po.n == 0.0) || ((2..=19).contains(&(po.i))) { + PluralCategory::FEW + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29293u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29549u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29805u64), None, None), + |po| { + if (po.n == 0.0) || ((2..=10).contains(&(po.i))) { + PluralCategory::FEW + } else if ((11..=19).contains(&(po.i))) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31085u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6840686u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7430510u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25198u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25710u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25966u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27758u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28270u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6844014u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28526u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7303534u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29294u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7304046u64), + None, + None + ), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31086u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7240046u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28015u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29295u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29551u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6386543u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24944u64), None, None), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7364976u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7168880u64), + None, + None + ), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27760u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) { + PluralCategory::FEW + } else if (po.v == 0 && po.i != 1 && (0..=1).contains(&(po.i % 10))) + || (po.v == 0 && (5..=9).contains(&(po.i % 10))) + || (po.v == 0 && (12..=14).contains(&(po.i % 100))) + { + PluralCategory::MANY + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6779504u64), + None, + None + ), + |po| { + if (po.i % 10 == 1 && po.i % 100 != 11) + || (po.v == 2 && po.f % 10 == 1 && po.f % 100 != 11) + || (po.v != 2 && po.f % 10 == 1) + { + PluralCategory::ONE + } else if (po.i % 10 == 0) + || ((11..=19).contains(&(po.i))) + || (po.v == 2 && (11..=19).contains(&(po.f % 100))) + { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29552u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29808u64), None, None), + |po| { + if ((0..=1).contains(&(po.i))) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(29808u64), + None, + Some(subtags::Region::from_raw_unchecked(21584u32)) + ), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28018u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28530u64), None, None), + |po| { + if (po.v != 0) || (po.n == 0.0) || ((2..=19).contains(&(po.i))) { + PluralCategory::FEW + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6713202u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30066u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 10 == 0) + || (po.v == 0 && (5..=9).contains(&(po.i % 10))) + || (po.v == 0 && (11..=14).contains(&(po.i % 100))) + { + PluralCategory::MANY + } else if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7042930u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6840691u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7430515u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7627123u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25459u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7234419u64), + None, + None + ), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25715u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6841459u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25971u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6841715u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7562611u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26483u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26739u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) + || ((2..=4).contains(&(po.f % 10)) && !(12..=14).contains(&(po.f % 100))) + { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) + || (po.f % 10 == 1 && po.f % 100 != 11) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6908019u64), + None, + None + ), + |po| { + if ((2..=10).contains(&(po.i)) && po.f == 0) { + PluralCategory::FEW + } else if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26995u64), None, None), + |po| { + if (po.n == 0.0 || po.n == 1.0) || (po.i == 0 && po.f == 1) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27507u64), None, None), + |po| { + if ((2..=4).contains(&(po.i)) && po.v == 0) { + PluralCategory::FEW + } else if (po.v != 0) { + PluralCategory::MANY + } else if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27763u64), None, None), + |po| { + if (po.v == 0 && (3..=4).contains(&(po.i % 100))) || (po.v != 0) { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 100 == 1) { + PluralCategory::ONE + } else if (po.v == 0 && po.i % 100 == 2) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6385011u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6909299u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6974835u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7236979u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7564659u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28275u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28531u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29043u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29299u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) + || ((2..=4).contains(&(po.f % 10)) && !(12..=14).contains(&(po.f % 100))) + { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) + || (po.f % 10 == 1 && po.f % 100 != 11) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29555u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7959411u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29811u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30067u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30323u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30579u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7502195u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24948u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25972u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7300468u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26740u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26996u64), None, None), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6777204u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27508u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27764u64), None, None), + |po| { + if (po.v == 0 && (po.i == 1 || po.i == 2 || po.i == 3)) + || (po.v == 0 && po.i % 10 != 4 && po.i % 10 != 6 && po.i % 10 != 9) + || (po.v != 0 && po.f % 10 != 4 && po.f % 10 != 6 && po.f % 10 != 9) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28276u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28532u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29300u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29556u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7174772u64), + None, + None + ), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) + || ((11..=99).contains(&(po.i)) && po.f == 0) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26485u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27509u64), None, None), + |po| { + if (po.v == 0 && (2..=4).contains(&(po.i % 10)) && !(12..=14).contains(&(po.i % 100))) { + PluralCategory::FEW + } else if (po.v == 0 && po.i % 10 == 0) + || (po.v == 0 && (5..=9).contains(&(po.i % 10))) + || (po.v == 0 && (11..=14).contains(&(po.i % 100))) + { + PluralCategory::MANY + } else if (po.v == 0 && po.i % 10 == 1 && po.i % 100 != 11) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29301u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31349u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25974u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26998u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28534u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7239030u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24951u64), None, None), + |po| { + if ((0..=1).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6644087u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28535u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26744u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6778744u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27001u64), None, None), + |po| { + if (po.i == 1 && po.v == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28537u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6649209u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26746u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30074u64), None, None), + |po| { + if (po.i == 0) || (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), +]; +pub const PRS_ORDINAL: &[(LanguageIdentifier, PluralRule)] = &[ + ( + langid!(subtags::Language::from_raw_unchecked(26209u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28001u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28257u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29281u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29537u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0 + || po.n == 5.0 + || po.n == 7.0 + || po.n == 8.0 + || po.n == 9.0 + || po.n == 10.0) + { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 3.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31329u64), None, None), + |po| { + if (po.i % 10 == 3 || po.i % 10 == 4) + || (po.i % 1000 == 100 + || po.i % 1000 == 200 + || po.i % 1000 == 300 + || po.i % 1000 == 400 + || po.i % 1000 == 500 + || po.i % 1000 == 600 + || po.i % 1000 == 700 + || po.i % 1000 == 800 + || po.i % 1000 == 900) + { + PluralCategory::FEW + } else if (po.i == 0) + || (po.i % 10 == 6) + || (po.i % 100 == 40 || po.i % 100 == 60 || po.i % 100 == 90) + { + PluralCategory::MANY + } else if (po.i % 10 == 1 + || po.i % 10 == 2 + || po.i % 10 == 5 + || po.i % 10 == 7 + || po.i % 10 == 8) + || (po.i % 100 == 20 || po.i % 100 == 50 || po.i % 100 == 70 || po.i % 100 == 80) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25954u64), None, None), + |po| { + if ((po.i % 10 == 2 || po.i % 10 == 3) && po.i % 100 != 12 && po.i % 100 != 13) { + PluralCategory::FEW + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26466u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28258u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0 + || po.n == 5.0 + || po.n == 7.0 + || po.n == 8.0 + || po.n == 9.0 + || po.n == 10.0) + { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 3.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29538u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24931u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 1.0 || po.n == 3.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25955u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29539u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31075u64), None, None), + |po| { + if (po.n == 3.0 || po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 5.0 || po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0) { + PluralCategory::TWO + } else if (po.n == 0.0 || po.n == 7.0 || po.n == 8.0 || po.n == 9.0) { + PluralCategory::ZERO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24932u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25956u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6452068u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27749u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28261u64), None, None), + |po| { + if (po.i % 10 == 3 && po.i % 100 != 13) { + PluralCategory::FEW + } else if (po.i % 10 == 1 && po.i % 100 != 11) { + PluralCategory::ONE + } else if (po.i % 10 == 2 && po.i % 100 != 12) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29541u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29797u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30053u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24934u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26982u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7104870u64), + None, + None + ), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29286u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31078u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24935u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25703u64), None, None), + |po| { + if (po.n == 3.0 || po.n == 13.0) { + PluralCategory::FEW + } else if (po.n == 1.0 || po.n == 11.0) { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 12.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27751u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7828327u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30055u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 3.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25960u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26984u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 3.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29288u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6452072u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30056u64), None, None), + |po| { + if (po.n == 1.0 || po.n == 5.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31080u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24937u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25705u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28265u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29545u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29801u64), None, None), + |po| { + if (po.n == 11.0 || po.n == 8.0 || po.n == 80.0 || po.n == 800.0) { + PluralCategory::MANY + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30569u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24938u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24939u64), None, None), + |po| { + if (po.i == 0) + || (po.i % 100 == 40 + || po.i % 100 == 60 + || po.i % 100 == 80 + || (2..=20).contains(&(po.i % 100))) + { + PluralCategory::MANY + } else if (po.i == 1) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27499u64), None, None), + |po| { + if (po.i % 10 == 6) || (po.i % 10 == 9) || (po.i % 10 == 0 && po.n != 0.0) { + PluralCategory::MANY + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28011u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28267u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28523u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30571u64), None, None), + |po| { + if (po.n == 5.0) || (po.i % 100 == 5) { + PluralCategory::MANY + } else if ((1..=4).contains(&(po.i)) && po.f == 0) + || ((1..=4).contains(&(po.i)) + || (21..=24).contains(&(po.i)) + || (41..=44).contains(&(po.i)) + || (61..=64).contains(&(po.i)) + || (81..=84).contains(&(po.i))) + { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31083u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28524u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29804u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30316u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27501u64), None, None), + |po| { + if ((po.i % 10 == 7 || po.i % 10 == 8) && po.i % 100 != 17 && po.i % 100 != 18) { + PluralCategory::MANY + } else if (po.i % 10 == 1 && po.i % 100 != 11) { + PluralCategory::ONE + } else if (po.i % 10 == 2 && po.i % 100 != 12) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27757u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28269u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28525u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29293u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 1.0) { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 3.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29549u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31085u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25198u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25966u64), None, None), + |po| { + if ((1..=4).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27758u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29295u64), None, None), + |po| { + if (po.n == 4.0) { + PluralCategory::FEW + } else if (po.n == 6.0) { + PluralCategory::MANY + } else if (po.n == 1.0 || po.n == 5.0 || (7..=9).contains(&(po.i)) && po.f == 0) { + PluralCategory::ONE + } else if (po.n == 2.0 || po.n == 3.0) { + PluralCategory::TWO + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24944u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27760u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6779504u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29552u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29808u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(28530u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30066u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25459u64), None, None), + |po| { + if (po.n == 11.0 || po.n == 8.0 || po.n == 80.0 || po.n == 800.0) { + PluralCategory::MANY + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(7234419u64), + None, + None + ), + |po| { + if (po.n == 11.0 || po.n == 8.0 || po.n == 80.0 || po.n == 800.0) { + PluralCategory::MANY + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25715u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26739u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26995u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27507u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27763u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29043u64), None, None), + |po| { + if (po.i % 10 == 4 && po.i % 100 != 14) { + PluralCategory::MANY + } else if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29299u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30323u64), None, None), + |po| { + if ((po.i % 10 == 1 || po.i % 10 == 2) && po.i % 100 != 11 && po.i % 100 != 12) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30579u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(24948u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(25972u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26740u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27508u64), None, None), + |po| { + if (po.i % 10 == 6 || po.i % 10 == 9) || (po.n == 10.0) { + PluralCategory::FEW + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27764u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29300u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(27509u64), None, None), + |po| { + if (po.i % 10 == 3 && po.i % 100 != 13) { + PluralCategory::FEW + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!(subtags::Language::from_raw_unchecked(29301u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(31349u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26998u64), None, None), + |po| { + if (po.n == 1.0) { + PluralCategory::ONE + } else { + PluralCategory::OTHER + } + }, + ), + ( + langid!( + subtags::Language::from_raw_unchecked(6649209u64), + None, + None + ), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(26746u64), None, None), + |po| PluralCategory::OTHER, + ), + ( + langid!(subtags::Language::from_raw_unchecked(30074u64), None, None), + |po| PluralCategory::OTHER, + ), +]; diff --git a/utshell-0.5.0/vendor/lazy_static/.cargo-checksum.json b/utshell-0.5.0/vendor/lazy_static/.cargo-checksum.json new file mode 100644 index 00000000..fa241ed8 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"05e37a4e63dc4a495998bb5133252a51d671c4e99061a6342089ed6eab43978a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"e2effacb5bbd7c01523f9a9e4a6a59c0f9b8698753b210fec5742408498197df","src/core_lazy.rs":"6b9fb6a4f553058e240756125b6b9ca43a83ed1fb72964343038ea0ea2e1af10","src/inline_lazy.rs":"f6184afbca4b477616f270790edc180263be806aa92ef0a9de681b4aac9e88c4","src/lib.rs":"99096a5d3089c0d86646f0805d1455befe2cb09683704af29c5c9d99ecab2683","tests/no_std.rs":"d68b149ee51ef5ae2b2906c0c94f5a9812d3b02811b13365c5a35e2ef90d25cf","tests/test.rs":"b3f7d805375dc5af7a2aa4b869944ad2ab4fc982b35ad718ea58f6914dc0a698"},"package":"e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/lazy_static/Cargo.toml b/utshell-0.5.0/vendor/lazy_static/Cargo.toml new file mode 100644 index 00000000..7f930c5e --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/Cargo.toml @@ -0,0 +1,46 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "lazy_static" +version = "1.4.0" +authors = ["Marvin Löbel "] +exclude = ["/.travis.yml", "/appveyor.yml"] +description = "A macro for declaring lazily evaluated statics in Rust." +documentation = "https://docs.rs/lazy_static" +readme = "README.md" +keywords = ["macro", "lazy", "static"] +categories = ["no-std", "rust-patterns", "memory-management"] +license = "MIT/Apache-2.0" +repository = "https://github.com/rust-lang-nursery/lazy-static.rs" +[dependencies.spin] +version = "0.5.0" +optional = true +[dev-dependencies.doc-comment] +version = "0.3.1" + +[features] +spin_no_std = ["spin"] +[badges.appveyor] +repository = "rust-lang-nursery/lazy-static.rs" + +[badges.is-it-maintained-issue-resolution] +repository = "rust-lang-nursery/lazy-static.rs" + +[badges.is-it-maintained-open-issues] +repository = "rust-lang-nursery/lazy-static.rs" + +[badges.maintenance] +status = "passively-maintained" + +[badges.travis-ci] +repository = "rust-lang-nursery/lazy-static.rs" diff --git a/utshell-0.5.0/vendor/lazy_static/LICENSE-APACHE b/utshell-0.5.0/vendor/lazy_static/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/lazy_static/LICENSE-MIT b/utshell-0.5.0/vendor/lazy_static/LICENSE-MIT new file mode 100644 index 00000000..25597d58 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2010 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/lazy_static/README.md b/utshell-0.5.0/vendor/lazy_static/README.md new file mode 100644 index 00000000..aa9f8283 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/README.md @@ -0,0 +1,79 @@ +lazy-static.rs +============== + +A macro for declaring lazily evaluated statics in Rust. + +Using this macro, it is possible to have `static`s that require code to be +executed at runtime in order to be initialized. +This includes anything requiring heap allocations, like vectors or hash maps, +as well as anything that requires non-const function calls to be computed. + +[![Travis-CI Status](https://travis-ci.com/rust-lang-nursery/lazy-static.rs.svg?branch=master)](https://travis-ci.com/rust-lang-nursery/lazy-static.rs) +[![Latest version](https://img.shields.io/crates/v/lazy_static.svg)](https://crates.io/crates/lazy_static) +[![Documentation](https://docs.rs/lazy_static/badge.svg)](https://docs.rs/lazy_static) +[![License](https://img.shields.io/crates/l/lazy_static.svg)](https://github.com/rust-lang-nursery/lazy-static.rs#license) + +## Minimum supported `rustc` + +`1.27.2+` + +This version is explicitly tested in CI and may only be bumped in new minor versions. Any changes to the supported minimum version will be called out in the release notes. + + +# Getting Started + +[lazy-static.rs is available on crates.io](https://crates.io/crates/lazy_static). +It is recommended to look there for the newest released version, as well as links to the newest builds of the docs. + +At the point of the last update of this README, the latest published version could be used like this: + +Add the following dependency to your Cargo manifest... + +```toml +[dependencies] +lazy_static = "1.4.0" +``` + +...and see the [docs](https://docs.rs/lazy_static) for how to use it. + +# Example + +```rust +#[macro_use] +extern crate lazy_static; + +use std::collections::HashMap; + +lazy_static! { + static ref HASHMAP: HashMap = { + let mut m = HashMap::new(); + m.insert(0, "foo"); + m.insert(1, "bar"); + m.insert(2, "baz"); + m + }; +} + +fn main() { + // First access to `HASHMAP` initializes it + println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap()); + + // Any further access to `HASHMAP` just returns the computed value + println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap()); +} +``` + +## License + +Licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. diff --git a/utshell-0.5.0/vendor/lazy_static/src/core_lazy.rs b/utshell-0.5.0/vendor/lazy_static/src/core_lazy.rs new file mode 100644 index 00000000..b66c3e0d --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/src/core_lazy.rs @@ -0,0 +1,31 @@ +// Copyright 2016 lazy-static.rs Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +extern crate spin; + +use self::spin::Once; + +pub struct Lazy(Once); + +impl Lazy { + pub const INIT: Self = Lazy(Once::INIT); + + #[inline(always)] + pub fn get(&'static self, builder: F) -> &T + where F: FnOnce() -> T + { + self.0.call_once(builder) + } +} + +#[macro_export] +#[doc(hidden)] +macro_rules! __lazy_static_create { + ($NAME:ident, $T:ty) => { + static $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::INIT; + } +} diff --git a/utshell-0.5.0/vendor/lazy_static/src/inline_lazy.rs b/utshell-0.5.0/vendor/lazy_static/src/inline_lazy.rs new file mode 100644 index 00000000..219ce9c6 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/src/inline_lazy.rs @@ -0,0 +1,57 @@ +// Copyright 2016 lazy-static.rs Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +extern crate core; +extern crate std; + +use self::std::prelude::v1::*; +use self::std::cell::Cell; +use self::std::hint::unreachable_unchecked; +use self::std::sync::Once; +#[allow(deprecated)] +pub use self::std::sync::ONCE_INIT; + +// FIXME: Replace Option with MaybeUninit (stable since 1.36.0) +pub struct Lazy(Cell>, Once); + +impl Lazy { + #[allow(deprecated)] + pub const INIT: Self = Lazy(Cell::new(None), ONCE_INIT); + + #[inline(always)] + pub fn get(&'static self, f: F) -> &T + where + F: FnOnce() -> T, + { + self.1.call_once(|| { + self.0.set(Some(f())); + }); + + // `self.0` is guaranteed to be `Some` by this point + // The `Once` will catch and propagate panics + unsafe { + match *self.0.as_ptr() { + Some(ref x) => x, + None => { + debug_assert!(false, "attempted to derefence an uninitialized lazy static. This is a bug"); + + unreachable_unchecked() + }, + } + } + } +} + +unsafe impl Sync for Lazy {} + +#[macro_export] +#[doc(hidden)] +macro_rules! __lazy_static_create { + ($NAME:ident, $T:ty) => { + static $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::INIT; + }; +} diff --git a/utshell-0.5.0/vendor/lazy_static/src/lib.rs b/utshell-0.5.0/vendor/lazy_static/src/lib.rs new file mode 100644 index 00000000..cada0dc6 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/src/lib.rs @@ -0,0 +1,215 @@ +// Copyright 2016 lazy-static.rs Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +/*! +A macro for declaring lazily evaluated statics. + +Using this macro, it is possible to have `static`s that require code to be +executed at runtime in order to be initialized. +This includes anything requiring heap allocations, like vectors or hash maps, +as well as anything that requires function calls to be computed. + +# Syntax + +```ignore +lazy_static! { + [pub] static ref NAME_1: TYPE_1 = EXPR_1; + [pub] static ref NAME_2: TYPE_2 = EXPR_2; + ... + [pub] static ref NAME_N: TYPE_N = EXPR_N; +} +``` + +Attributes (including doc comments) are supported as well: + +```rust +# #[macro_use] +# extern crate lazy_static; +# fn main() { +lazy_static! { + /// This is an example for using doc comment attributes + static ref EXAMPLE: u8 = 42; +} +# } +``` + +# Semantics + +For a given `static ref NAME: TYPE = EXPR;`, the macro generates a unique type that +implements `Deref` and stores it in a static with name `NAME`. (Attributes end up +attaching to this type.) + +On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs +can return a reference to the same object. Note that this can lead to deadlocks +if you have multiple lazy statics that depend on each other in their initialization. + +Apart from the lazy initialization, the resulting "static ref" variables +have generally the same properties as regular "static" variables: + +- Any type in them needs to fulfill the `Sync` trait. +- If the type has a destructor, then it will not run when the process exits. + +# Example + +Using the macro: + +```rust +#[macro_use] +extern crate lazy_static; + +use std::collections::HashMap; + +lazy_static! { + static ref HASHMAP: HashMap = { + let mut m = HashMap::new(); + m.insert(0, "foo"); + m.insert(1, "bar"); + m.insert(2, "baz"); + m + }; + static ref COUNT: usize = HASHMAP.len(); + static ref NUMBER: u32 = times_two(21); +} + +fn times_two(n: u32) -> u32 { n * 2 } + +fn main() { + println!("The map has {} entries.", *COUNT); + println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap()); + println!("A expensive calculation on a static results in: {}.", *NUMBER); +} +``` + +# Implementation details + +The `Deref` implementation uses a hidden static variable that is guarded by an atomic check on each access. + +# Cargo features + +This crate provides one cargo feature: + +- `spin_no_std`: This allows using this crate in a no-std environment, by depending on the standalone `spin` crate. + +*/ + +#![doc(html_root_url = "https://docs.rs/lazy_static/1.4.0")] +#![no_std] + +#[cfg(not(feature = "spin_no_std"))] +#[path="inline_lazy.rs"] +#[doc(hidden)] +pub mod lazy; + +#[cfg(test)] +#[macro_use] +extern crate doc_comment; + +#[cfg(test)] +doctest!("../README.md"); + +#[cfg(feature = "spin_no_std")] +#[path="core_lazy.rs"] +#[doc(hidden)] +pub mod lazy; + +#[doc(hidden)] +pub use core::ops::Deref as __Deref; + +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! __lazy_static_internal { + // optional visibility restrictions are wrapped in `()` to allow for + // explicitly passing otherwise implicit information about private items + ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { + __lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N); + __lazy_static_internal!(@TAIL, $N : $T = $e); + lazy_static!($($t)*); + }; + (@TAIL, $N:ident : $T:ty = $e:expr) => { + impl $crate::__Deref for $N { + type Target = $T; + fn deref(&self) -> &$T { + #[inline(always)] + fn __static_ref_initialize() -> $T { $e } + + #[inline(always)] + fn __stability() -> &'static $T { + __lazy_static_create!(LAZY, $T); + LAZY.get(__static_ref_initialize) + } + __stability() + } + } + impl $crate::LazyStatic for $N { + fn initialize(lazy: &Self) { + let _ = &**lazy; + } + } + }; + // `vis` is wrapped in `()` to prevent parsing ambiguity + (@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => { + #[allow(missing_copy_implementations)] + #[allow(non_camel_case_types)] + #[allow(dead_code)] + $(#[$attr])* + $($vis)* struct $N {__private_field: ()} + #[doc(hidden)] + $($vis)* static $N: $N = $N {__private_field: ()}; + }; + () => () +} + +#[macro_export(local_inner_macros)] +macro_rules! lazy_static { + ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { + // use `()` to explicitly forward the information about private items + __lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*); + }; + ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { + __lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*); + }; + ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { + __lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*); + }; + () => () +} + +/// Support trait for enabling a few common operation on lazy static values. +/// +/// This is implemented by each defined lazy static, and +/// used by the free functions in this crate. +pub trait LazyStatic { + #[doc(hidden)] + fn initialize(lazy: &Self); +} + +/// Takes a shared reference to a lazy static and initializes +/// it if it has not been already. +/// +/// This can be used to control the initialization point of a lazy static. +/// +/// Example: +/// +/// ```rust +/// #[macro_use] +/// extern crate lazy_static; +/// +/// lazy_static! { +/// static ref BUFFER: Vec = (0..255).collect(); +/// } +/// +/// fn main() { +/// lazy_static::initialize(&BUFFER); +/// +/// // ... +/// work_with_initialized_data(&BUFFER); +/// } +/// # fn work_with_initialized_data(_: &[u8]) {} +/// ``` +pub fn initialize(lazy: &T) { + LazyStatic::initialize(lazy); +} diff --git a/utshell-0.5.0/vendor/lazy_static/tests/no_std.rs b/utshell-0.5.0/vendor/lazy_static/tests/no_std.rs new file mode 100644 index 00000000..f94a1aaa --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/tests/no_std.rs @@ -0,0 +1,20 @@ +#![cfg(feature="spin_no_std")] + +#![no_std] + +#[macro_use] +extern crate lazy_static; + +lazy_static! { + /// Documentation! + pub static ref NUMBER: u32 = times_two(3); +} + +fn times_two(n: u32) -> u32 { + n * 2 +} + +#[test] +fn test_basic() { + assert_eq!(*NUMBER, 6); +} diff --git a/utshell-0.5.0/vendor/lazy_static/tests/test.rs b/utshell-0.5.0/vendor/lazy_static/tests/test.rs new file mode 100644 index 00000000..03d0ab68 --- /dev/null +++ b/utshell-0.5.0/vendor/lazy_static/tests/test.rs @@ -0,0 +1,164 @@ +#[macro_use] +extern crate lazy_static; +use std::collections::HashMap; + +lazy_static! { + /// Documentation! + pub static ref NUMBER: u32 = times_two(3); + + static ref ARRAY_BOXES: [Box; 3] = [Box::new(1), Box::new(2), Box::new(3)]; + + /// More documentation! + #[allow(unused_variables)] + #[derive(Copy, Clone, Debug)] + pub static ref STRING: String = "hello".to_string(); + + static ref HASHMAP: HashMap = { + let mut m = HashMap::new(); + m.insert(0, "abc"); + m.insert(1, "def"); + m.insert(2, "ghi"); + m + }; + + // This should not compile if the unsafe is removed. + static ref UNSAFE: u32 = unsafe { + std::mem::transmute::(-1) + }; +} + +lazy_static! { + static ref S1: &'static str = "a"; + static ref S2: &'static str = "b"; +} +lazy_static! { + static ref S3: String = [*S1, *S2].join(""); +} + +#[test] +fn s3() { + assert_eq!(&*S3, "ab"); +} + +fn times_two(n: u32) -> u32 { + n * 2 +} + +#[test] +fn test_basic() { + assert_eq!(&**STRING, "hello"); + assert_eq!(*NUMBER, 6); + assert!(HASHMAP.get(&1).is_some()); + assert!(HASHMAP.get(&3).is_none()); + assert_eq!(&*ARRAY_BOXES, &[Box::new(1), Box::new(2), Box::new(3)]); + assert_eq!(*UNSAFE, std::u32::MAX); +} + +#[test] +fn test_repeat() { + assert_eq!(*NUMBER, 6); + assert_eq!(*NUMBER, 6); + assert_eq!(*NUMBER, 6); +} + +#[test] +fn test_meta() { + // this would not compile if STRING were not marked #[derive(Copy, Clone)] + let copy_of_string = STRING; + // just to make sure it was copied + assert!(&STRING as *const _ != ©_of_string as *const _); + + // this would not compile if STRING were not marked #[derive(Debug)] + assert_eq!(format!("{:?}", STRING), "STRING { __private_field: () }".to_string()); +} + +mod visibility { + lazy_static! { + pub static ref FOO: Box = Box::new(0); + static ref BAR: Box = Box::new(98); + } + + pub mod inner { + lazy_static! { + pub(in visibility) static ref BAZ: Box = Box::new(42); + pub(crate) static ref BAG: Box = Box::new(37); + } + } + + #[test] + fn sub_test() { + assert_eq!(**FOO, 0); + assert_eq!(**BAR, 98); + assert_eq!(**inner::BAZ, 42); + assert_eq!(**inner::BAG, 37); + } +} + +#[test] +fn test_visibility() { + assert_eq!(*visibility::FOO, Box::new(0)); + assert_eq!(*visibility::inner::BAG, Box::new(37)); +} + +// This should not cause a warning about a missing Copy implementation +lazy_static! { + pub static ref VAR: i32 = { 0 }; +} + +#[derive(Copy, Clone, Debug, PartialEq)] +struct X; +struct Once(X); +const ONCE_INIT: Once = Once(X); +static DATA: X = X; +static ONCE: X = X; +fn require_sync() -> X { X } +fn transmute() -> X { X } +fn __static_ref_initialize() -> X { X } +fn test(_: Vec) -> X { X } + +// All these names should not be shadowed +lazy_static! { + static ref ITEM_NAME_TEST: X = { + test(vec![X, Once(X).0, ONCE_INIT.0, DATA, ONCE, + require_sync(), transmute(), + // Except this, which will sadly be shadowed by internals: + // __static_ref_initialize() + ]) + }; +} + +#[test] +fn item_name_shadowing() { + assert_eq!(*ITEM_NAME_TEST, X); +} + +use std::sync::atomic::AtomicBool; +#[allow(deprecated)] +use std::sync::atomic::ATOMIC_BOOL_INIT; +use std::sync::atomic::Ordering::SeqCst; + +#[allow(deprecated)] +static PRE_INIT_FLAG: AtomicBool = ATOMIC_BOOL_INIT; + +lazy_static! { + static ref PRE_INIT: () = { + PRE_INIT_FLAG.store(true, SeqCst); + () + }; +} + +#[test] +fn pre_init() { + assert_eq!(PRE_INIT_FLAG.load(SeqCst), false); + lazy_static::initialize(&PRE_INIT); + assert_eq!(PRE_INIT_FLAG.load(SeqCst), true); +} + +lazy_static! { + static ref LIFETIME_NAME: for<'a> fn(&'a u8) = { fn f(_: &u8) {} f }; +} + +#[test] +fn lifetime_name() { + let _ = LIFETIME_NAME; +} diff --git a/utshell-0.5.0/vendor/libc/.cargo-checksum.json b/utshell-0.5.0/vendor/libc/.cargo-checksum.json new file mode 100644 index 00000000..f2b65051 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CONTRIBUTING.md":"a93fcda0a76e1975fcfb0aa2ba00c9b1864f9ae6062704a294d81a3688898e10","Cargo.toml":"c7d137b327d60cad5b7bd3ef97ec93f57fdde1101b14250b56fe1a1d3afc98ef","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"4da2919bb509f3f06163778478494f780ca6627cb79ccab5d2c828c8d88dc133","build.rs":"01bc1b8934bb80982a36f46c61508f32cb05c4deab15cb9afb5bf9da285d5c1b","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"893fcec48142d273063ffd814dca33fbec92205fd39ada97075f85201d803996","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"07410f511835da540e5bdc55f7384c71cd7836fe63bbca6be547de825f823c03","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/riscv64.rs":"617cd75e79e0e20f664db764a4dc2a396d9fd11a4d95371acd91ed4811293b11","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"2d04cfa0d55dc0a2e36fdc4a45819b9d3722af19bb1932778b44feb4c2f81036","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"9d7030ba3e21064a0f3a8e79927c70d5a95a0026be61be084f3ab021e243e503","src/macros.rs":"5f985b3de7b18833f866bf832b8ffb0430f0f70aa9a468b6a2c855c1bf9d33e4","src/psp.rs":"0a7d5121a8cc2903009f586c00e4ae2d6126d24eb90531dafaba6f59823aa6b2","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/teeos/mod.rs":"eb664b3e94bcd44d8c8147b56c2187139d01bf8402ee0bb81967a5a50a3e927f","src/unix/aix/mod.rs":"d4ed2a4eff43c60a251bba150868d0249bf79dd6fb835d5287c352577452712b","src/unix/aix/powerpc64.rs":"cf374d81139d45f9d77c6a764f640bfbf7e0a5903689652c8296f8e10d55169b","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"2eaf0f561a32bdcbf4e0477c8895d5e7bcb5cdebd5fef7b4df2ca8e38e144d94","src/unix/bsd/apple/b64/aarch64/mod.rs":"44c217a4f263afe7a97435de9323d20a96c37836f899ca0925306d4b7e073c27","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/long_array.rs":"3cf1f19b812e6d093c819dc65ce55b13491963e0780eda0d0bd1577603e81948","src/unix/bsd/apple/mod.rs":"1da404688e9d67171403f2486456aac9d36a2db31ee7ebc308f14d6277754eef","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"2777f94909a798df1b8030fb86d02e2118d0ac3e49e9a542df54a569ca5ae2f9","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"6c8e216385f53a4bf5f171749b57602fc34a4e4b160a44ca31c058cb0c8a2126","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"e243ae0e89623d4fa9f85afe14369cc5fd5f2028ea715773dbec722ba80dac1f","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"bef9fae288a4f29e941ea369be1cd20b170040e60665a4d49a4a9e79009b72d8","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"88be47524b28b6635ccb1e85ea511bf17337be0af7e9baa740c341ac9e83a6f7","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"6ddc6abf6d5ccaea0d8cccf521e8ca6457efcad3086af4155628d5d06d672346","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"e7b5863e222d6cc416b6b0fbe71690fad909e899b4c4ae810bbca117e4fcb650","src/unix/bsd/freebsdlike/freebsd/freebsd15/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs":"93115c1a9faa43ebf58b7dee3582aed5a54291b284764e370e7f649b2e6a9565","src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs":"e7b5863e222d6cc416b6b0fbe71690fad909e899b4c4ae810bbca117e4fcb650","src/unix/bsd/freebsdlike/freebsd/mod.rs":"5669c341804bccf27eb03965f11bd640a762a9898a5baa18b5a319fb1d8abddf","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"fa4bed4c58cad24ba3395941c7fa6b11e089551a04714f9561078e400f5b2b62","src/unix/bsd/freebsdlike/freebsd/x86.rs":"6766e2ce85e187b306cd3b0b8d7e15b8f4042c5cff81d89b3af69ecc99c70ab0","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"29f5ae7c8bcd64219e77f99ba9b26527299cf4908b20f7d1ec4f625b5194a44c","src/unix/bsd/mod.rs":"f5974098ef3d1a29774bc0bde27dc9c89c3880f9ed7b4d7ea334b595dc39ff94","src/unix/bsd/netbsdlike/mod.rs":"ea60540aa4edd4e43136749d5df497b1dc072b9912b6030dd1ab794a6d1c3c3c","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"057ee877db7193ba0dc10801b9a6563ac6dbdb78376d6851a84cb12b30841759","src/unix/bsd/netbsdlike/netbsd/arm.rs":"949b55e4dee1c8c511f4f061a6a57ac876a6c0eabfaf5cc20e9ab40d8f41b2e0","src/unix/bsd/netbsdlike/netbsd/mips.rs":"88be18ac43ba224c77e78e4179b6761debc5e6c30a258fac56263809c7af4fbc","src/unix/bsd/netbsdlike/netbsd/mod.rs":"b8d6f089fc8eb2cb59e45335a26c9ce871b846216c9859b553c6b91982f8de33","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/riscv64.rs":"1cbe2e5ed681cb1054b699da37daaf6c714267df7d332c90fc2a589b11579625","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"532b76199d6c71ff996eade9f906c55a72c9aff489595d25a21e21878cfd740b","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"7b93b5b24b3c72a79b2de19b47ac2f56b29d87e9fc8f4c721a63d1e87ec83fcc","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1fe3332dc705a13e6242219970f5449d6d7a73e2e6c8537ab8e421d8a6f2e3ff","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"ad70cc42ed83ac38664941418b0b9bfe1ead7a0ff82b121ea8df65483e3b7e1c","src/unix/haiku/native.rs":"3bbf42c3e3e437e8b626be67c72b6adcec60646eb5dd4bf8471a603cbbb5e5a4","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hurd/align.rs":"03c79b2cd8270ebd0cf93cb475a8f1ff85b28175ea0de007ede17cad94a89b03","src/unix/hurd/b32.rs":"2ba90ed973f90366c36a6387833a3df42abfee9622d4a0352635937d4a89eaf4","src/unix/hurd/b64.rs":"d919b4aec9b3080ad24c125c57b2c8b2e483d72045f1554c429d14560355846f","src/unix/hurd/mod.rs":"6a2f0db80a3cd34b55ef82e357da4d453d5d190a2dd4501bfa5d0bb9bca0de4f","src/unix/hurd/no_align.rs":"03c79b2cd8270ebd0cf93cb475a8f1ff85b28175ea0de007ede17cad94a89b03","src/unix/linux_like/android/b32/arm.rs":"ce582de7e983a33d3bfad13075c53aac9016cee35f06ad8653ee9072c3ec2564","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"e6d107efbcd37b5b85dfa18f683300cbf768ffa0237997a9fa52b184a53323ac","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"10e963e29ff209703de6336c99cca96fd79789438d34c82a693eae56e8916c3c","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"19d4bf2237c47127eba9144e0b82e995bc079315e719179a91813b0ae7b0e49d","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"4ec2de11a9b65c4325b7b991f0b99a414975e0e61ba8668caca5d921e9b314d1","src/unix/linux_like/android/mod.rs":"5f923c89c8fd6a672d695ddd690aeac6a025c947f565acbd829c0e69d72ca049","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/lfs64.rs":"3776af30a758d765a88920ec4fde442ab89040da13d3b3625c7fbcb8a958559f","src/unix/linux_like/emscripten/mod.rs":"70d4591730a731ee32788a9d8d2de379592844ec36b7d1723514179605587713","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"bc5abcd38e2320171e0981e773c9c5fe3e0d5a66fdff049228f6a1acad80ef8b","src/unix/linux_like/linux/arch/generic/mod.rs":"feff53cb116f60c302121f9a5701adf1e2a16ff7d52a6de161fe58a28553f870","src/unix/linux_like/linux/arch/mips/mod.rs":"18dade308bf04717630fd6467b92c23560c83ac5274a8469569f260aa4671239","src/unix/linux_like/linux/arch/mod.rs":"5bd5361f8a6ab4e18bbba6da9f92c164ae252b15a0ed10064812544aa1fdf198","src/unix/linux_like/linux/arch/powerpc/mod.rs":"0bc2d2667a00eca81f4abeb6d613a90848a947f51224103f83268928b8197629","src/unix/linux_like/linux/arch/sparc/mod.rs":"5e6777863e74a9e2aa9dc487f1059783dd211babc2b32d6bf676f311e49c55d6","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"f68ec59b6407f9d4e326f3e71a41ec21f19ecfc703edf9a93e496f661fed5506","src/unix/linux_like/linux/gnu/b32/csky/align.rs":"3fed009dc9af3cc81be7087da9d2d7d1f39845e4497e290259c5cdbae25f039d","src/unix/linux_like/linux/gnu/b32/csky/mod.rs":"8729b68e433e94c2128e51a7db4fd555938e4be4dc64584c352b24a20d9c8e91","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"80956d3fef163ecf248828a6f38782dd8ae856d86b1bb5aac2de36032dbd8ea0","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"96e22350d5d132d917c743d6560464500652c67b52c3d0e8474494487df3365d","src/unix/linux_like/linux/gnu/b32/mod.rs":"b56625dd20dd48a8699034d349ef089c540c0ddcbf8a3481d598d101f8b40b78","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"20fc3cc4fe1ef6617b63b61b897f782ceb9c2842fc718f504a1840537229bf47","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"887288a0a1cfff319d0e15edcdc4fcb31fd643ff41715ec5244c8f2413624169","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"cc4342b949e4d796f304acd9dfe3f721a1c2f37fec16b42d3bb27dc94723af37","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"06d4db4ee8352f62a0a5ead0c4d6ea0a78feff522f19b9bc5772f6dd920ffd80","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"fdf1c72375a2167699157e0dd825422690bb6719f7bc69515a2e5846d0431d7c","src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs":"832e7487249c1c0bb6e9911ce3f7d32ca22378e42392ab83c56915cbc59d8be3","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"bf4611b737813deef6787babf6c01698605f3b75482269b8546318667bc68e29","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"11a950697fdda0258c6e37c6b13993348c8de4134105ed4faa79358e53175072","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"8202614484da36c388d2ffdd2554c56bb4f9db8e5bd621f8c36114cdcfeec644","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"060aa33cc737966c691aab8511c5c5729e551458ce18d0e284e0d45f39beeb60","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"dc29dfdadd754ec355b82a7ca6636de7ed97f7ba98f132b71cb49f39d6bd8e3f","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"73532be4b5775acf9524c77feeefe1f6d1936ceffef908d01dd2586986520f2d","src/unix/linux_like/linux/gnu/b64/mod.rs":"6a160ef25439c4fecdb0e3bd0b818742263c791364da874d4febd3aa644ec8e2","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"a90c2641616c620e9d1fea87695ce046e14f9da2282bb93f761eeb4077c74741","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"68a2a20fa4ef92cdf382d8095168eb88875b7aa8c9c47ee5f1e527393b6c16fa","src/unix/linux_like/linux/gnu/b64/s390x.rs":"1ea9e39432ce6bf68779d33546dacd7d39477a9f8fc3da4f4f339e4538cb74c3","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"bed381c44cec2a5b50125f7e548ab487d4c829006c971d152a611b7141760052","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"332846e4a5920d7e6b05df0448a2333c5dd00fb27cb33654648f507ee89dbec5","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"38f74ce15d9662ce4818815a2b87be1618d5e45f190f7e4db84ff3285b4421fb","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"b20218a11364a6dec87f96d6c0d8b19e660697ab09ad5ee0e9b3a9dafedaaebb","src/unix/linux_like/linux/gnu/mod.rs":"583d04f92435da76fd3f87182ab67b5e6dd8c35a63b240d8c4555fb1ab70f3f8","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"099ae3b59e379cad0e57df710a81a3f8f208a5993051e6e0fcfb61595889ce18","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"af10147d7c3661751750a58ffad089d5d18d180cd18303c653aef126c07ccd91","src/unix/linux_like/linux/musl/b32/hexagon.rs":"d079cab42529f7dab699334d43168c74ff4aa0282f11040a8b7d274b65767a7a","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"e44043766f7cd26de7ffa4232654afb6feb03e58dbd5890717970887bd003151","src/unix/linux_like/linux/musl/b32/mod.rs":"31677597fd9544c4b1ec1477628288f6273fabbc06e38f33da862ad55f019ce1","src/unix/linux_like/linux/musl/b32/powerpc.rs":"3dae56a4e7789bcc5314e419fea5e4b2495367b4f1a49d1c9477c60225d65eef","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"3ee845d272f91a1908d5f421d7c353e1f14681bbdfef64410e408f4c14365a91","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"f2b53ae0034c833244b7cdb8c670349bf8272a03abf04152eba65cf62810484d","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"45ce6897afcc960267bb7505702b639daf94dc69428a213bf1aefd367ca32adc","src/unix/linux_like/linux/musl/b64/mips64.rs":"a968ef9c54fa22293085f318c8472c1754482df92cc500568dc33bd807d71ea6","src/unix/linux_like/linux/musl/b64/mod.rs":"1a8391febf3e750185ffc5c69c9f9e411f4e8c53b5d994cb231df24480169686","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"140e579800a67315f4cb8a42b22aa8157eae34ffe626e77e421b43c53c23b34d","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"c5944526d7e19cd43e9d14d119a1d98f8780db7ecbcc79e69d7b9348e596b520","src/unix/linux_like/linux/musl/b64/s390x.rs":"8557b3477ca8cefef7fce764a3c25441929a54e50ead4091f6f7823c427cd728","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"a91c4f18027c9958037f78ae48f6352d23cb4e6f2995b2cc8de7dce0e5759470","src/unix/linux_like/linux/musl/lfs64.rs":"3e4fb381f3a0756520bde0f1692d4fa45e4ae8133bf7d7c64b0e3fdd512f235f","src/unix/linux_like/linux/musl/mod.rs":"f0a23b77e5465c05a5dd95c3c6b7959c597010416226503ff3719796367ba98e","src/unix/linux_like/linux/no_align.rs":"62cdca0e011937aaf09a51ca86d9f0ee0fdb05f61ec3c058e6a5d5fa6357d784","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"50288ff9e411ab0966da24838f2c2a5618021bc19c422a04f577b2979ef4081e","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"d0c4434e2bf813372c418a8f516c706cdccc9f7be2f0921b2207b0afdb66fe81","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"3f38ee6a4690b9d7594be20d216467a34d955f7653c2c8ce1e6147daeb53f1e0","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"a048fce1c2d9b1ad57305642e8ad05ca0f0c7e4753267a2e2d6b4fee5db3b072","src/unix/linux_like/linux/uclibc/mod.rs":"193a03fa4aa5345394e39d2115c9427e806c9f28b0fde685719119e1c90ca08a","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"8485b9182b7c67f7344fab377e7cc2a72afefd9ab63837c860514abba9728d76","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"196d03affbefb85716937c15904831e731eb222ee906e05e42102d639a8152ea","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"86dbbd81484df25ad7c6a82d2d3b5eab2f8e7751853c1dd4308b7eee57b5fbca","src/unix/mod.rs":"923a32e8fd9e462eda4e90ae7ee501da1d12aaadc1bf2e9722f02581a5d3fc6c","src/unix/newlib/aarch64/mod.rs":"964c096288da836b53c0c71d7f3a97048d177da220a69314c5ce93ba330d72af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cf754f8b1197489fca01e881a4b4b146e814998e4b365f116fa1a102c00e6a4e","src/unix/newlib/espidf/mod.rs":"29969da41f0042197b21cfa7c0ad2244b4519ecab0fb7de3d0a7655b4f3937e1","src/unix/newlib/generic.rs":"5f0b5d07ddb5a5d60580f9561fdb05e9218d9751d4068c4aadad2ba6b950aabf","src/unix/newlib/horizon/mod.rs":"3a521d22bf932fc01c1d26d1f9bff20f11b1855b03c8236a8eb18310f6cab5a8","src/unix/newlib/mod.rs":"e5d5faf27a6336b9f1c02b8726427801d906a14dae766852b4e85c1a92df06c8","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"cc9e188711b9bf614323ad6c48e0d2e1a1ecc5d3bc64961ba451f29c6c22d2d8","src/unix/newlib/vita/mod.rs":"ff1caf74bb0696fe15d60dbac598db4520cd538aa0f5989713d97d008eee6ad8","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/nto/aarch64.rs":"4709c9afdc8d583be876598e7c238499ee3e8da5bd2baa614d9c7dd414851555","src/unix/nto/mod.rs":"07268897fc8810f2fed22ab56f87757f71c73ba401abd848bccca6b183a13b02","src/unix/nto/neutrino.rs":"799bff4ab01a6424db6c5a2b76aa5679826d41495f9d13c63485bf13bc80026b","src/unix/nto/x86_64.rs":"a3e18e93c2999da1cd7a6f748a4b60c07aefb73d8ea2aafec19a84cfb040bc8e","src/unix/redox/mod.rs":"a9f54687307883beb4a410216dc8e36b85d72b0463bc6b1520bd91edf3947d23","src/unix/solarish/compat.rs":"00f1ee3faec9da69204e42f025f6735dd13d894071a154425dcc43ecbdd06e7f","src/unix/solarish/illumos.rs":"cd93c2d84722bbf9933a92842a8998eb0b2afc962f50bc2546ad127b82809fa7","src/unix/solarish/mod.rs":"10b2369edc027fcb2e41e5342f24946aa01ee1549a6d7f06b9a3956ff84518bc","src/unix/solarish/solaris.rs":"41b350a89ddf01cd12a10f93640f92be53be0b0d976021cdc08da17bf3e72edf","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"ec2b01f194eb8a6a27133c57681da195a949e03098f3ea1e847227a9c09ef5fc","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"4105a2e6a6c9908fc1f2a770ede052bb0d6a5d9d49e32d815f557081efc49860","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"d4147353537d7556076ff1a1c4cb96cc2dae9416a5d176ba8a077ad55ab7ec18","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"9fdc5e1c62c441abef7bc62a7343efb2041edc24db9ac0efc0f74df55b69e249","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","src/xous.rs":"eb0675f25ba01f73072d2b70907fb8abb1148facefe5a20756c49250f3d65fae","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/libc/CONTRIBUTING.md b/utshell-0.5.0/vendor/libc/CONTRIBUTING.md new file mode 100644 index 00000000..b6f41cc6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/CONTRIBUTING.md @@ -0,0 +1,100 @@ +# Contributing to `libc` + +Welcome! If you are reading this document, it means you are interested in contributing +to the `libc` crate. + +## v0.2 changes + +If you want to add your changes to v0.2, please submit them to the `libc-0.2` branch. +If you want to add any breaking changes, it should be submitted to the main branch, +which has changes for v0.3. +We will support and make a new release for v0.2 until we make the first release of v0.3. + +## Adding an API + +Want to use an API which currently isn't bound in `libc`? It's quite easy to add +one! + +The internal structure of this crate is designed to minimize the number of +`#[cfg]` attributes in order to easily be able to add new items which apply +to all platforms in the future. As a result, the crate is organized +hierarchically based on platform. Each module has a number of `#[cfg]`'d +children, but only one is ever actually compiled. Each module then reexports all +the contents of its children. + +This means that for each platform that libc supports, the path from a +leaf module to the root will contain all bindings for the platform in question. +Consequently, this indicates where an API should be added! Adding an API at a +particular level in the hierarchy means that it is supported on all the child +platforms of that level. For example, when adding a Unix API it should be added +to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to +`src/unix/linux_like/linux/mod.rs`. + +If you're not 100% sure at what level of the hierarchy an API should be added +at, fear not! This crate has CI support which tests any binding against all +platforms supported, so you'll see failures if an API is added at the wrong +level or has different signatures across platforms. + +New symbol(s) (i.e. functions, constants etc.) should also be added to the +symbols list(s) found in the `libc-test/semver` directory. These lists keep +track of what symbols are public in the libc crate and ensures they remain +available between changes to the crate. If the new symbol(s) are available on +all supported Unixes it should be added to `unix.txt` list1, +otherwise they should be added to the OS specific list(s). + +With that in mind, the steps for adding a new API are: + +1. Determine where in the module hierarchy your API should be added. +2. Add the API, including adding new symbol(s) to the semver lists. +3. Send a PR to this repo. +4. Wait for CI to pass, fixing errors. +5. Wait for a merge! + +1: Note that this list has nothing to do with any Unix or Posix +standard, it's just a list shared between all OSs that declare `#[cfg(unix)]`. + +## Test before you commit + +We have two automated tests running on [GitHub Actions](https://github.com/rust-lang/libc/actions): + +1. [`libc-test`](https://github.com/gnzlbg/ctest) + - `cd libc-test && cargo test` + - Use the `skip_*()` functions in `build.rs` if you really need a workaround. +2. Style checker + - [`sh ci/style.sh`](https://github.com/rust-lang/libc/blob/main/ci/style.sh) + +## Breaking change policy + +Sometimes an upstream adds a breaking change to their API e.g. removing outdated items, +changing the type signature, etc. And we probably should follow that change to build the +`libc` crate successfully. It's annoying to do the equivalent of semver-major versioning +for each such change. Instead, we mark the item as deprecated and do the actual change +after a certain period. The steps are: + +1. Add `#[deprecated(since = "", note="")]` attribute to the item. + - The `since` field should have a next version of `libc` + (e.g., if the current version is `0.2.1`, it should be `0.2.2`). + - The `note` field should have a reason to deprecate and a tracking issue to call for comments + (e.g., "We consider removing this as the upstream removed it. + If you're using it, please comment on #XXX"). +2. If we don't see any concerns for a while, do the change actually. + +## Supported target policy + +When Rust removes a support for a target, the libc crate also may remove the support anytime. + +## Releasing your change to crates.io + +Now that you've done the amazing job of landing your new API or your new +platform in this crate, the next step is to get that sweet, sweet usage from +crates.io! The only next step is to bump the version of libc and then publish +it. If you'd like to get a release out ASAP you can follow these steps: + +1. Increment the patch version number in `Cargo.toml` and `libc-test/Cargo.toml`. +1. Send a PR to this repository. It should [look like this][example-pr], but it'd + also be nice to fill out the description with a small rationale for the + release (any rationale is ok though!). +1. Once merged, the release will be tagged and published by one of the libc crate + maintainers. + +[example-pr]: https://github.com/rust-lang/libc/pull/2120 diff --git a/utshell-0.5.0/vendor/libc/Cargo.toml b/utshell-0.5.0/vendor/libc/Cargo.toml new file mode 100644 index 00000000..46ec3b40 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/Cargo.toml @@ -0,0 +1,175 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +name = "libc" +version = "0.2.153" +authors = ["The Rust Project Developers"] +build = "build.rs" +exclude = [ + "/ci/*", + "/.github/*", + "/.cirrus.yml", + "/triagebot.toml", +] +description = """ +Raw FFI bindings to platform libraries like libc. +""" +homepage = "https://github.com/rust-lang/libc" +documentation = "https://docs.rs/libc/" +readme = "README.md" +keywords = [ + "libc", + "ffi", + "bindings", + "operating", + "system", +] +categories = [ + "external-ffi-bindings", + "no-std", + "os", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/libc" + +[package.metadata.docs.rs] +cargo-args = ["-Zbuild-std=core"] +default-target = "x86_64-unknown-linux-gnu" +features = [ + "const-extern-fn", + "extra_traits", +] +targets = [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-linux-android", + "aarch64-pc-windows-msvc", + "aarch64-unknown-freebsd", + "aarch64-unknown-fuchsia", + "aarch64-unknown-hermit", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "aarch64-unknown-netbsd", + "aarch64-unknown-openbsd", + "aarch64-wrs-vxworks", + "arm-linux-androideabi", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "arm-unknown-linux-musleabi", + "arm-unknown-linux-musleabihf", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv7-linux-androideabi", + "armv7-unknown-linux-gnueabihf", + "armv7-unknown-linux-musleabihf", + "armv7-wrs-vxworks-eabihf", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "hexagon-unknown-linux-musl", + "i586-pc-windows-msvc", + "i586-unknown-linux-gnu", + "i586-unknown-linux-musl", + "i686-linux-android", + "i686-pc-windows-gnu", + "i686-pc-windows-msvc", + "i686-pc-windows-msvc", + "i686-unknown-freebsd", + "i686-unknown-haiku", + "i686-unknown-linux-gnu", + "i686-unknown-linux-musl", + "i686-unknown-netbsd", + "i686-unknown-openbsd", + "i686-wrs-vxworks", + "mips-unknown-linux-gnu", + "mips-unknown-linux-musl", + "mips64-unknown-linux-gnuabi64", + "mips64-unknown-linux-muslabi64", + "mips64el-unknown-linux-gnuabi64", + "mips64el-unknown-linux-muslabi64", + "mipsel-sony-psp", + "mipsel-unknown-linux-gnu", + "mipsel-unknown-linux-musl", + "nvptx64-nvidia-cuda", + "powerpc-unknown-linux-gnu", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-netbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "powerpc64-unknown-freebsd", + "powerpc64-unknown-linux-gnu", + "powerpc64-wrs-vxworks", + "powerpc64le-unknown-linux-gnu", + "riscv32gc-unknown-linux-gnu", + "riscv32i-unknown-none-elf", + "riscv32imac-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "riscv64gc-unknown-freebsd", + "riscv64gc-unknown-hermit", + "riscv64gc-unknown-linux-gnu", + "riscv64gc-unknown-linux-musl", + "riscv64gc-unknown-none-elf", + "riscv64imac-unknown-none-elf", + "s390x-unknown-linux-gnu", + "s390x-unknown-linux-musl", + "sparc-unknown-linux-gnu", + "sparc64-unknown-linux-gnu", + "sparc64-unknown-netbsd", + "sparcv9-sun-solaris", + "thumbv6m-none-eabi", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "thumbv7neon-linux-androideabi", + "thumbv7neon-unknown-linux-gnueabihf", + "wasm32-unknown-emscripten", + "wasm32-unknown-unknown", + "wasm32-wasi", + "x86_64-apple-darwin", + "x86_64-apple-ios", + "x86_64-fortanix-unknown-sgx", + "x86_64-linux-android", + "x86_64-pc-solaris", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-dragonfly", + "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", + "x86_64-unknown-haiku", + "x86_64-unknown-hermit", + "x86_64-unknown-illumos", + "x86_64-unknown-l4re-uclibc", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-gnux32", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd", + "x86_64-unknown-openbsd", + "x86_64-unknown-redox", + "x86_64-wrs-vxworks", +] + +[dependencies.rustc-std-workspace-core] +version = "1.0.0" +optional = true + +[features] +align = [] +const-extern-fn = [] +default = ["std"] +extra_traits = [] +rustc-dep-of-std = [ + "align", + "rustc-std-workspace-core", +] +std = [] +use_std = ["std"] diff --git a/utshell-0.5.0/vendor/libc/LICENSE-APACHE b/utshell-0.5.0/vendor/libc/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/utshell-0.5.0/vendor/libc/LICENSE-MIT b/utshell-0.5.0/vendor/libc/LICENSE-MIT new file mode 100644 index 00000000..78061811 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014-2020 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/libc/README.md b/utshell-0.5.0/vendor/libc/README.md new file mode 100644 index 00000000..395b94ce --- /dev/null +++ b/utshell-0.5.0/vendor/libc/README.md @@ -0,0 +1,118 @@ +# libc - Raw FFI bindings to platforms' system libraries + +[![GHA Status]][GitHub Actions] [![Cirrus CI Status]][Cirrus CI] [![Latest Version]][crates.io] [![Documentation]][docs.rs] ![License] + +`libc` provides all of the definitions necessary to easily interoperate with C +code (or "C-like" code) on each of the platforms that Rust supports. This +includes type definitions (e.g. `c_int`), constants (e.g. `EINVAL`) as well as +function headers (e.g. `malloc`). + +This crate exports all underlying platform types, functions, and constants under +the crate root, so all items are accessible as `libc::foo`. The types and values +of all the exported APIs match the platform that libc is compiled for. + +More detailed information about the design of this library can be found in its +[associated RFC][rfc]. + +[rfc]: https://github.com/rust-lang/rfcs/blob/HEAD/text/1291-promote-libc.md + +## v0.3 Roadmap + +The main branch is now for v0.3 which has some breaking changes. + +For v0.2, please submit PRs to the `libc-0.2` branch instead. +We will stop making new v0.2 releases once we release v0.3 on crates.io. + +See the [tracking issue](https://github.com/rust-lang/libc/issues/3248) for details. + +## Usage + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +libc = "0.2" +``` + +## Features + +* `std`: by default `libc` links to the standard library. Disable this + feature to remove this dependency and be able to use `libc` in `#![no_std]` + crates. + +* `extra_traits`: all `struct`s implemented in `libc` are `Copy` and `Clone`. + This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`. + +* `const-extern-fn`: Changes some `extern fn`s into `const extern fn`s. + If you use Rust >= 1.62, this feature is implicitly enabled. + Otherwise it requires a nightly rustc. + +* **deprecated**: `use_std` is deprecated, and is equivalent to `std`. + +## Rust version support + +The minimum supported Rust toolchain version is currently **Rust 1.13.0**. +(libc does not currently have any policy regarding changes to the minimum +supported Rust version; such policy is a work in progress.) APIs requiring +newer Rust features are only available on newer Rust toolchains: + +| Feature | Version | +|----------------------|---------| +| `union` | 1.19.0 | +| `const mem::size_of` | 1.24.0 | +| `repr(align)` | 1.25.0 | +| `extra_traits` | 1.25.0 | +| `core::ffi::c_void` | 1.30.0 | +| `repr(packed(N))` | 1.33.0 | +| `cfg(target_vendor)` | 1.33.0 | +| `const-extern-fn` | 1.62.0 | + +## Platform support + +You can see the platform(target)-specific docs on [docs.rs], select a platform you want to see. + +See +[`ci/build.sh`](https://github.com/rust-lang/libc/blob/HEAD/ci/build.sh) +for the platforms on which `libc` is guaranteed to build for each Rust +toolchain. The test-matrix at [GitHub Actions] and [Cirrus CI] show the +platforms in which `libc` tests are run. + +
+ +## License + +This project is licensed under either of + +* [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) + ([LICENSE-APACHE](https://github.com/rust-lang/libc/blob/HEAD/LICENSE-APACHE)) + +* [MIT License](https://opensource.org/licenses/MIT) + ([LICENSE-MIT](https://github.com/rust-lang/libc/blob/HEAD/LICENSE-MIT)) + +at your option. + +## Contributing + +We welcome all people who want to contribute. Please see the [contributing +instructions] for more information. + +[contributing instructions]: https://github.com/rust-lang/libc/blob/HEAD/CONTRIBUTING.md + +Contributions in any form (issues, pull requests, etc.) to this project +must adhere to Rust's [Code of Conduct]. + +[Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `libc` by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[GitHub Actions]: https://github.com/rust-lang/libc/actions +[GHA Status]: https://github.com/rust-lang/libc/workflows/CI/badge.svg +[Cirrus CI]: https://cirrus-ci.com/github/rust-lang/libc +[Cirrus CI Status]: https://api.cirrus-ci.com/github/rust-lang/libc.svg +[crates.io]: https://crates.io/crates/libc +[Latest Version]: https://img.shields.io/crates/v/libc.svg +[Documentation]: https://docs.rs/libc/badge.svg +[docs.rs]: https://docs.rs/libc +[License]: https://img.shields.io/crates/l/libc.svg diff --git a/utshell-0.5.0/vendor/libc/build.rs b/utshell-0.5.0/vendor/libc/build.rs new file mode 100644 index 00000000..ec932007 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/build.rs @@ -0,0 +1,297 @@ +use std::env; +use std::process::Command; +use std::str; +use std::string::String; + +// List of cfgs this build script is allowed to set. The list is needed to support check-cfg, as we +// need to know all the possible cfgs that this script will set. If you need to set another cfg +// make sure to add it to this list as well. +const ALLOWED_CFGS: &'static [&'static str] = &[ + "emscripten_new_stat_abi", + "freebsd10", + "freebsd11", + "freebsd12", + "freebsd13", + "freebsd14", + "freebsd15", + "libc_align", + "libc_cfg_target_vendor", + "libc_const_extern_fn", + "libc_const_extern_fn_unstable", + "libc_const_size_of", + "libc_core_cvoid", + "libc_deny_warnings", + "libc_int128", + "libc_long_array", + "libc_non_exhaustive", + "libc_packedN", + "libc_priv_mod_use", + "libc_ptr_addr_of", + "libc_thread_local", + "libc_underscore_const_names", + "libc_union", +]; + +// Extra values to allow for check-cfg. +const CHECK_CFG_EXTRA: &'static [(&'static str, &'static [&'static str])] = &[ + ("target_os", &["switch", "aix", "ohos", "hurd"]), + ("target_env", &["illumos", "wasi", "aix", "ohos"]), + ( + "target_arch", + &["loongarch64", "mips32r6", "mips64r6", "csky"], + ), +]; + +fn main() { + // Avoid unnecessary re-building. + println!("cargo:rerun-if-changed=build.rs"); + + let (rustc_minor_ver, is_nightly) = rustc_minor_nightly(); + let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok(); + let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok(); + let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok(); + let libc_ci = env::var("LIBC_CI").is_ok(); + let libc_check_cfg = env::var("LIBC_CHECK_CFG").is_ok(); + + if env::var("CARGO_FEATURE_USE_STD").is_ok() { + println!( + "cargo:warning=\"libc's use_std cargo feature is deprecated since libc 0.2.55; \ + please consider using the `std` cargo feature instead\"" + ); + } + + // The ABI of libc used by std is backward compatible with FreeBSD 12. + // The ABI of libc from crates.io is backward compatible with FreeBSD 11. + // + // On CI, we detect the actual FreeBSD version and match its ABI exactly, + // running tests to ensure that the ABI is correct. + match which_freebsd() { + Some(10) if libc_ci => set_cfg("freebsd10"), + Some(11) if libc_ci => set_cfg("freebsd11"), + Some(12) if libc_ci || rustc_dep_of_std => set_cfg("freebsd12"), + Some(13) if libc_ci => set_cfg("freebsd13"), + Some(14) if libc_ci => set_cfg("freebsd14"), + Some(15) if libc_ci => set_cfg("freebsd15"), + Some(_) | None => set_cfg("freebsd11"), + } + + match emcc_version_code() { + Some(v) if (v >= 30142) => set_cfg("emscripten_new_stat_abi"), + // Non-Emscripten or version < 3.1.42. + Some(_) | None => (), + } + + // On CI: deny all warnings + if libc_ci { + set_cfg("libc_deny_warnings"); + } + + // Rust >= 1.15 supports private module use: + if rustc_minor_ver >= 15 || rustc_dep_of_std { + set_cfg("libc_priv_mod_use"); + } + + // Rust >= 1.19 supports unions: + if rustc_minor_ver >= 19 || rustc_dep_of_std { + set_cfg("libc_union"); + } + + // Rust >= 1.24 supports const mem::size_of: + if rustc_minor_ver >= 24 || rustc_dep_of_std { + set_cfg("libc_const_size_of"); + } + + // Rust >= 1.25 supports repr(align): + if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature { + set_cfg("libc_align"); + } + + // Rust >= 1.26 supports i128 and u128: + if rustc_minor_ver >= 26 || rustc_dep_of_std { + set_cfg("libc_int128"); + } + + // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it. + // Otherwise, it defines an incompatible type to retaining + // backwards-compatibility. + if rustc_minor_ver >= 30 || rustc_dep_of_std { + set_cfg("libc_core_cvoid"); + } + + // Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor). + if rustc_minor_ver >= 33 || rustc_dep_of_std { + set_cfg("libc_packedN"); + set_cfg("libc_cfg_target_vendor"); + } + + // Rust >= 1.40 supports #[non_exhaustive]. + if rustc_minor_ver >= 40 || rustc_dep_of_std { + set_cfg("libc_non_exhaustive"); + } + + // Rust >= 1.47 supports long array: + if rustc_minor_ver >= 47 || rustc_dep_of_std { + set_cfg("libc_long_array"); + } + + if rustc_minor_ver >= 51 || rustc_dep_of_std { + set_cfg("libc_ptr_addr_of"); + } + + // Rust >= 1.37.0 allows underscores as anonymous constant names. + if rustc_minor_ver >= 37 || rustc_dep_of_std { + set_cfg("libc_underscore_const_names"); + } + + // #[thread_local] is currently unstable + if rustc_dep_of_std { + set_cfg("libc_thread_local"); + } + + // Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C". + if rustc_minor_ver >= 62 { + set_cfg("libc_const_extern_fn"); + } else { + // Rust < 1.62.0 requires a crate feature and feature gate. + if const_extern_fn_cargo_feature { + if !is_nightly || rustc_minor_ver < 40 { + panic!("const-extern-fn requires a nightly compiler >= 1.40"); + } + set_cfg("libc_const_extern_fn_unstable"); + set_cfg("libc_const_extern_fn"); + } + } + + // check-cfg is a nightly cargo/rustc feature to warn when unknown cfgs are used across the + // codebase. libc can configure it if the appropriate environment variable is passed. Since + // rust-lang/rust enforces it, this is useful when using a custom libc fork there. + // + // https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg + if libc_check_cfg { + for cfg in ALLOWED_CFGS { + if rustc_minor_ver >= 75 { + println!("cargo:rustc-check-cfg=cfg({})", cfg); + } else { + println!("cargo:rustc-check-cfg=values({})", cfg); + } + } + for &(name, values) in CHECK_CFG_EXTRA { + let values = values.join("\",\""); + if rustc_minor_ver >= 75 { + println!("cargo:rustc-check-cfg=cfg({},values(\"{}\"))", name, values); + } else { + println!("cargo:rustc-check-cfg=values({},\"{}\")", name, values); + } + } + } +} + +fn rustc_minor_nightly() -> (u32, bool) { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, + None => panic!("Failed to get rustc version"), + } + }; + } + + let rustc = otry!(env::var_os("RUSTC")); + let output = Command::new(rustc) + .arg("--version") + .output() + .ok() + .expect("Failed to get rustc version"); + if !output.status.success() { + panic!( + "failed to run rustc: {}", + String::from_utf8_lossy(output.stderr.as_slice()) + ); + } + + let version = otry!(str::from_utf8(&output.stdout).ok()); + let mut pieces = version.split('.'); + + if pieces.next() != Some("rustc 1") { + panic!("Failed to get rustc version"); + } + + let minor = pieces.next(); + + // If `rustc` was built from a tarball, its version string + // will have neither a git hash nor a commit date + // (e.g. "rustc 1.39.0"). Treat this case as non-nightly, + // since a nightly build should either come from CI + // or a git checkout + let nightly_raw = otry!(pieces.next()).split('-').nth(1); + let nightly = nightly_raw + .map(|raw| raw.starts_with("dev") || raw.starts_with("nightly")) + .unwrap_or(false); + let minor = otry!(otry!(minor).parse().ok()); + + (minor, nightly) +} + +fn which_freebsd() -> Option { + let output = std::process::Command::new("freebsd-version").output().ok(); + if output.is_none() { + return None; + } + let output = output.unwrap(); + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok(); + if stdout.is_none() { + return None; + } + let stdout = stdout.unwrap(); + + match &stdout { + s if s.starts_with("10") => Some(10), + s if s.starts_with("11") => Some(11), + s if s.starts_with("12") => Some(12), + s if s.starts_with("13") => Some(13), + s if s.starts_with("14") => Some(14), + s if s.starts_with("15") => Some(15), + _ => None, + } +} + +fn emcc_version_code() -> Option { + let output = std::process::Command::new("emcc") + .arg("-dumpversion") + .output() + .ok(); + if output.is_none() { + return None; + } + let output = output.unwrap(); + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok(); + if stdout.is_none() { + return None; + } + let version = stdout.unwrap(); + + // Some Emscripten versions come with `-git` attached, so split the + // version string also on the `-` char. + let mut pieces = version.trim().split(|c| c == '.' || c == '-'); + + let major = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let minor = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let patch = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + + Some(major * 10000 + minor * 100 + patch) +} + +fn set_cfg(cfg: &str) { + if !ALLOWED_CFGS.contains(&cfg) { + panic!("trying to set cfg {}, but it is not in ALLOWED_CFGS", cfg); + } + println!("cargo:rustc-cfg={}", cfg); +} diff --git a/utshell-0.5.0/vendor/libc/rustfmt.toml b/utshell-0.5.0/vendor/libc/rustfmt.toml new file mode 100644 index 00000000..dc85c994 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/rustfmt.toml @@ -0,0 +1 @@ +error_on_line_overflow = true diff --git a/utshell-0.5.0/vendor/libc/src/fixed_width_ints.rs b/utshell-0.5.0/vendor/libc/src/fixed_width_ints.rs new file mode 100644 index 00000000..999de8f5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fixed_width_ints.rs @@ -0,0 +1,99 @@ +//! This module contains type aliases for C's fixed-width integer types . +//! +//! These aliases are deprecated: use the Rust types instead. + +#[deprecated(since = "0.2.55", note = "Use i8 instead.")] +pub type int8_t = i8; +#[deprecated(since = "0.2.55", note = "Use i16 instead.")] +pub type int16_t = i16; +#[deprecated(since = "0.2.55", note = "Use i32 instead.")] +pub type int32_t = i32; +#[deprecated(since = "0.2.55", note = "Use i64 instead.")] +pub type int64_t = i64; +#[deprecated(since = "0.2.55", note = "Use u8 instead.")] +pub type uint8_t = u8; +#[deprecated(since = "0.2.55", note = "Use u16 instead.")] +pub type uint16_t = u16; +#[deprecated(since = "0.2.55", note = "Use u32 instead.")] +pub type uint32_t = u32; +#[deprecated(since = "0.2.55", note = "Use u64 instead.")] +pub type uint64_t = u64; + +cfg_if! { + if #[cfg(all(libc_int128, target_arch = "aarch64", not(target_os = "windows")))] { + // This introduces partial support for FFI with __int128 and + // equivalent types on platforms where Rust's definition is validated + // to match the standard C ABI of that platform. + // + // Rust does not guarantee u128/i128 are sound for FFI, and its + // definitions are in fact known to be incompatible. [0] + // + // However these problems aren't fundamental, and are just platform + // inconsistencies. Specifically at the time of this writing: + // + // * For x64 SysV ABIs (everything but Windows), the types are underaligned. + // * For all Windows ABIs, Microsoft doesn't actually officially define __int128, + // and as a result different implementations don't actually agree on its ABI. + // + // But on the other major aarch64 platforms (android, linux, ios, macos) we have + // validated that rustc has the right ABI for these types. This is important because + // aarch64 uses these types in some fundamental OS types like user_fpsimd_struct, + // which represents saved simd registers. + // + // Any API which uses these types will need to `#[ignore(improper_ctypes)]` + // until the upstream rust issue is resolved, but this at least lets us make + // progress on platforms where this type is important. + // + // The list of supported architectures and OSes is intentionally very restricted, + // as careful work needs to be done to verify that a particular platform + // has a conformant ABI. + // + // [0]: https://github.com/rust-lang/rust/issues/54341 + + /// C `__int128` (a GCC extension that's part of many ABIs) + pub type __int128 = i128; + /// C `unsigned __int128` (a GCC extension that's part of many ABIs) + pub type __uint128 = u128; + /// C __int128_t (alternate name for [__int128][]) + pub type __int128_t = i128; + /// C __uint128_t (alternate name for [__uint128][]) + pub type __uint128_t = u128; + + cfg_if! { + if #[cfg(libc_underscore_const_names)] { + macro_rules! static_assert_eq { + ($a:expr, $b:expr) => { + const _: [(); $a] = [(); $b]; + }; + } + + // NOTE: if you add more platforms to here, you may need to cfg + // these consts. They should always match the platform's values + // for `sizeof(__int128)` and `_Alignof(__int128)`. + const _SIZE_128: usize = 16; + const _ALIGN_128: usize = 16; + + // Since Rust doesn't officially guarantee that these types + // have compatible ABIs, we const assert that these values have the + // known size/align of the target platform's libc. If rustc ever + // tries to regress things, it will cause a compilation error. + // + // This isn't a bullet-proof solution because e.g. it doesn't + // catch the fact that llvm and gcc disagree on how x64 __int128 + // is actually *passed* on the stack (clang underaligns it for + // the same reason that rustc *never* properly aligns it). + static_assert_eq!(core::mem::size_of::<__int128>(), _SIZE_128); + static_assert_eq!(core::mem::align_of::<__int128>(), _ALIGN_128); + + static_assert_eq!(core::mem::size_of::<__uint128>(), _SIZE_128); + static_assert_eq!(core::mem::align_of::<__uint128>(), _ALIGN_128); + + static_assert_eq!(core::mem::size_of::<__int128_t>(), _SIZE_128); + static_assert_eq!(core::mem::align_of::<__int128_t>(), _ALIGN_128); + + static_assert_eq!(core::mem::size_of::<__uint128_t>(), _SIZE_128); + static_assert_eq!(core::mem::align_of::<__uint128_t>(), _ALIGN_128); + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/fuchsia/aarch64.rs b/utshell-0.5.0/vendor/libc/src/fuchsia/aarch64.rs new file mode 100644 index 00000000..33e3934d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fuchsia/aarch64.rs @@ -0,0 +1,67 @@ +pub type c_char = u8; +pub type __u64 = ::c_ulonglong; +pub type wchar_t = u32; +pub type nlink_t = ::c_ulong; +pub type blksize_t = ::c_long; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_uint; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_uint; 2], + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } +} + +// From https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/third_party/ulib/musl/include/bits/signal.h;l=20-21;drc=0827b18ab9540c46f8037f407d17ea15a79e9ba7 +pub const MINSIGSTKSZ: ::size_t = 6144; +pub const SIGSTKSZ: ::size_t = 12288; diff --git a/utshell-0.5.0/vendor/libc/src/fuchsia/align.rs b/utshell-0.5.0/vendor/libc/src/fuchsia/align.rs new file mode 100644 index 00000000..3409bf0c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fuchsia/align.rs @@ -0,0 +1,142 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr( + any( + target_pointer_width = "32", + target_arch = "x86_64" + ), + repr(align(4)))] + #[cfg_attr( + not(any( + target_pointer_width = "32", + target_arch = "x86_64" + )), + repr(align(8)))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct pthread_rwlockattr_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "arm", + target_arch = "x86_64")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "arm", + target_arch = "x86_64"))), + repr(align(8)))] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "arm", + target_arch = "x86_64")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "arm", + target_arch = "x86_64"))), + repr(align(8)))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + #[cfg_attr(target_arch = "x86", + repr(align(4)))] + #[cfg_attr(not(target_arch = "x86"), + repr(align(8)))] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_mutex_t {} + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/fuchsia/mod.rs b/utshell-0.5.0/vendor/libc/src/fuchsia/mod.rs new file mode 100644 index 00000000..4e028ff6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fuchsia/mod.rs @@ -0,0 +1,4393 @@ +//! Definitions found commonly among almost all Unix derivatives +//! +//! More functions and definitions can be found in the more specific modules +//! according to the platform in question. + +// PUB_TYPE + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type locale_t = *mut ::c_void; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type pid_t = i32; +pub type uid_t = u32; +pub type gid_t = u32; +pub type in_addr_t = u32; +pub type in_port_t = u16; +pub type sighandler_t = ::size_t; +pub type cc_t = ::c_uchar; +pub type sa_family_t = u16; +pub type pthread_key_t = ::c_uint; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type clockid_t = ::c_int; +pub type key_t = ::c_int; +pub type id_t = ::c_uint; +pub type useconds_t = u32; +pub type dev_t = u64; +pub type socklen_t = u32; +pub type pthread_t = c_ulong; +pub type mode_t = u32; +pub type ino64_t = u64; +pub type off64_t = i64; +pub type blkcnt64_t = i64; +pub type rlim64_t = u64; +pub type mqd_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type idtype_t = ::c_uint; +pub type loff_t = ::c_longlong; + +pub type __u8 = ::c_uchar; +pub type __u16 = ::c_ushort; +pub type __s16 = ::c_short; +pub type __u32 = ::c_uint; +pub type __s32 = ::c_int; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; + +pub type Elf64_Half = u16; +pub type Elf64_Word = u32; +pub type Elf64_Off = u64; +pub type Elf64_Addr = u64; +pub type Elf64_Xword = u64; + +pub type clock_t = c_long; +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i64; + +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulonglong; +pub type fsfilcnt_t = ::c_ulonglong; +pub type rlim_t = ::c_ulonglong; + +pub type c_long = i64; +pub type c_ulong = u64; + +// FIXME: why are these uninhabited types? that seems... wrong? +// Presumably these should be `()` or an `extern type` (when that stabilizes). +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +impl ::Copy for DIR {} +impl ::Clone for DIR { + fn clone(&self) -> DIR { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { + *self + } +} + +// PUB_STRUCT + +s! { + pub struct group { + pub gr_name: *mut ::c_char, + pub gr_passwd: *mut ::c_char, + pub gr_gid: ::gid_t, + pub gr_mem: *mut *mut ::c_char, + } + + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: ::c_long, + } + + // FIXME: the rlimit and rusage related functions and types don't exist + // within zircon. Are there reasons for keeping them around? + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad1: u32, + pub ru_ixrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad2: u32, + pub ru_idrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad3: u32, + pub ru_isrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad4: u32, + pub ru_minflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad5: u32, + pub ru_majflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad6: u32, + pub ru_nswap: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad7: u32, + pub ru_inblock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad8: u32, + pub ru_oublock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad9: u32, + pub ru_msgsnd: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad10: u32, + pub ru_msgrcv: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad11: u32, + pub ru_nsignals: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad12: u32, + pub ru_nvcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad13: u32, + pub ru_nivcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: u32, + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::c_int, + } + + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: ::c_uint, + } + + pub struct hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: ::c_int, + pub h_length: ::c_int, + pub h_addr_list: *mut *mut ::c_char, + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: ::size_t, + } + + pub struct pollfd { + pub fd: ::c_int, + pub events: ::c_short, + pub revents: ::c_short, + } + + pub struct winsize { + pub ws_row: ::c_ushort, + pub ws_col: ::c_ushort, + pub ws_xpixel: ::c_ushort, + pub ws_ypixel: ::c_ushort, + } + + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct sigval { + // Actually a union of an int and a void* + pub sival_ptr: *mut ::c_void + } + + // + pub struct itimerval { + pub it_interval: ::timeval, + pub it_value: ::timeval, + } + + // + pub struct tms { + pub tms_utime: ::clock_t, + pub tms_stime: ::clock_t, + pub tms_cutime: ::clock_t, + pub tms_cstime: ::clock_t, + } + + pub struct servent { + pub s_name: *mut ::c_char, + pub s_aliases: *mut *mut ::c_char, + pub s_port: ::c_int, + pub s_proto: *mut ::c_char, + } + + pub struct protoent { + pub p_name: *mut ::c_char, + pub p_aliases: *mut *mut ::c_char, + pub p_proto: ::c_int, + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + #[cfg(target_pointer_width = "32")] + __dummy4: [::c_char; 24], + #[cfg(target_pointer_width = "64")] + __dummy4: [::c_char; 16], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + + pub ai_addr: *mut ::sockaddr, + + pub ai_canonname: *mut c_char, + + pub ai_next: *mut addrinfo, + } + + pub struct sockaddr_ll { + pub sll_family: ::c_ushort, + pub sll_protocol: ::c_ushort, + pub sll_ifindex: ::c_int, + pub sll_hatype: ::c_ushort, + pub sll_pkttype: ::c_uchar, + pub sll_halen: ::c_uchar, + pub sll_addr: [::c_uchar; 8] + } + + pub struct fd_set { + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_long, + pub tm_zone: *const ::c_char, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + pub sched_ss_low_priority: ::c_int, + pub sched_ss_repl_period: ::timespec, + pub sched_ss_init_budget: ::timespec, + pub sched_ss_max_repl: ::c_int, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct epoll_event { + pub events: u32, + pub u64: u64, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut c_char, + pub ifa_flags: ::c_uint, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_ifu: *mut ::sockaddr, // FIXME This should be a union + pub ifa_data: *mut ::c_void + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curspace: u64, + pub dqb_ihardlimit: u64, + pub dqb_isoftlimit: u64, + pub dqb_curinodes: u64, + pub dqb_btime: u64, + pub dqb_itime: u64, + pub dqb_valid: u32, + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct cpu_set_t { + #[cfg(all(target_pointer_width = "32", + not(target_arch = "x86_64")))] + bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + bits: [u64; 16], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct input_event { + pub time: ::timeval, + pub type_: ::__u16, + pub code: ::__u16, + pub value: ::__s32, + } + + pub struct input_id { + pub bustype: ::__u16, + pub vendor: ::__u16, + pub product: ::__u16, + pub version: ::__u16, + } + + pub struct input_absinfo { + pub value: ::__s32, + pub minimum: ::__s32, + pub maximum: ::__s32, + pub fuzz: ::__s32, + pub flat: ::__s32, + pub resolution: ::__s32, + } + + pub struct input_keymap_entry { + pub flags: ::__u8, + pub len: ::__u8, + pub index: ::__u16, + pub keycode: ::__u32, + pub scancode: [::__u8; 32], + } + + pub struct input_mask { + pub type_: ::__u32, + pub codes_size: ::__u32, + pub codes_ptr: ::__u64, + } + + pub struct ff_replay { + pub length: ::__u16, + pub delay: ::__u16, + } + + pub struct ff_trigger { + pub button: ::__u16, + pub interval: ::__u16, + } + + pub struct ff_envelope { + pub attack_length: ::__u16, + pub attack_level: ::__u16, + pub fade_length: ::__u16, + pub fade_level: ::__u16, + } + + pub struct ff_constant_effect { + pub level: ::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_ramp_effect { + pub start_level: ::__s16, + pub end_level: ::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_condition_effect { + pub right_saturation: ::__u16, + pub left_saturation: ::__u16, + + pub right_coeff: ::__s16, + pub left_coeff: ::__s16, + + pub deadband: ::__u16, + pub center: ::__s16, + } + + pub struct ff_periodic_effect { + pub waveform: ::__u16, + pub period: ::__u16, + pub magnitude: ::__s16, + pub offset: ::__s16, + pub phase: ::__u16, + + pub envelope: ff_envelope, + + pub custom_len: ::__u32, + pub custom_data: *mut ::__s16, + } + + pub struct ff_rumble_effect { + pub strong_magnitude: ::__u16, + pub weak_magnitude: ::__u16, + } + + pub struct ff_effect { + pub type_: ::__u16, + pub id: ::__s16, + pub direction: ::__u16, + pub trigger: ff_trigger, + pub replay: ff_replay, + // FIXME this is actually a union + #[cfg(target_pointer_width = "64")] + pub u: [u64; 4], + #[cfg(target_pointer_width = "32")] + pub u: [u32; 7], + } + + pub struct dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct pthread_attr_t { + __size: [u64; 7] + } + + pub struct sigset_t { + __val: [::c_ulong; 16], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + __pad1: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + __pad2: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub __pad1: ::c_int, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 8], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct termios2 { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; 19], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } +} + +s_no_extra_traits! { + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_pad2: [u8; 128 - 2 - 8], + __ss_align: ::size_t, + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + // x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=21279 + pub struct mq_attr { + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_flags: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_maxmsg: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_msgsize: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_curmsgs: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pad: [i64; 4], + + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_flags: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_maxmsg: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_msgsize: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_curmsgs: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pad: [::c_long; 4], + } + + pub struct sockaddr_nl { + pub nl_family: ::sa_family_t, + nl_pad: ::c_ushort, + pub nl_pid: u32, + pub nl_groups: u32 + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + pub sigev_notify_function: fn(::sigval), + pub sigev_notify_attributes: *mut pthread_attr_t, + pub __pad: [::c_char; 56 - 3 * 8 /* 8 == sizeof(long) */], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sysinfo {} + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a,b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a,b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a,b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a,b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for utsname {} + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent64 {} + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for mq_attr { + fn eq(&self, other: &mq_attr) -> bool { + self.mq_flags == other.mq_flags && + self.mq_maxmsg == other.mq_maxmsg && + self.mq_msgsize == other.mq_msgsize && + self.mq_curmsgs == other.mq_curmsgs + } + } + impl Eq for mq_attr {} + impl ::fmt::Debug for mq_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mq_attr") + .field("mq_flags", &self.mq_flags) + .field("mq_maxmsg", &self.mq_maxmsg) + .field("mq_msgsize", &self.mq_msgsize) + .field("mq_curmsgs", &self.mq_curmsgs) + .finish() + } + } + impl ::hash::Hash for mq_attr { + fn hash(&self, state: &mut H) { + self.mq_flags.hash(state); + self.mq_maxmsg.hash(state); + self.mq_msgsize.hash(state); + self.mq_curmsgs.hash(state); + } + } + + impl PartialEq for sockaddr_nl { + fn eq(&self, other: &sockaddr_nl) -> bool { + self.nl_family == other.nl_family && + self.nl_pid == other.nl_pid && + self.nl_groups == other.nl_groups + } + } + impl Eq for sockaddr_nl {} + impl ::fmt::Debug for sockaddr_nl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_nl") + .field("nl_family", &self.nl_family) + .field("nl_pid", &self.nl_pid) + .field("nl_groups", &self.nl_groups) + .finish() + } + } + impl ::hash::Hash for sockaddr_nl { + fn hash(&self, state: &mut H) { + self.nl_family.hash(state); + self.nl_pid.hash(state); + self.nl_groups.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_value == other.sigev_value + && self.sigev_signo == other.sigev_signo + && self.sigev_notify == other.sigev_notify + && self.sigev_notify_function + == other.sigev_notify_function + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_value", &self.sigev_value) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_notify", &self.sigev_notify) + .field("sigev_notify_function", &self.sigev_notify_function) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_value.hash(state); + self.sigev_signo.hash(state); + self.sigev_notify.hash(state); + self.sigev_notify_function.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + } +} + +// PUB_CONST + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +pub const SIG_DFL: sighandler_t = 0 as sighandler_t; +pub const SIG_IGN: sighandler_t = 1 as sighandler_t; +pub const SIG_ERR: sighandler_t = !0 as sighandler_t; + +pub const DT_UNKNOWN: u8 = 0; +pub const DT_FIFO: u8 = 1; +pub const DT_CHR: u8 = 2; +pub const DT_DIR: u8 = 4; +pub const DT_BLK: u8 = 6; +pub const DT_REG: u8 = 8; +pub const DT_LNK: u8 = 10; +pub const DT_SOCK: u8 = 12; + +pub const FD_CLOEXEC: ::c_int = 0x1; + +pub const USRQUOTA: ::c_int = 0; +pub const GRPQUOTA: ::c_int = 1; + +pub const SIGIOT: ::c_int = 6; + +pub const S_ISUID: ::c_int = 0x800; +pub const S_ISGID: ::c_int = 0x400; +pub const S_ISVTX: ::c_int = 0x200; + +pub const IF_NAMESIZE: ::size_t = 16; +pub const IFNAMSIZ: ::size_t = IF_NAMESIZE; + +pub const LOG_EMERG: ::c_int = 0; +pub const LOG_ALERT: ::c_int = 1; +pub const LOG_CRIT: ::c_int = 2; +pub const LOG_ERR: ::c_int = 3; +pub const LOG_WARNING: ::c_int = 4; +pub const LOG_NOTICE: ::c_int = 5; +pub const LOG_INFO: ::c_int = 6; +pub const LOG_DEBUG: ::c_int = 7; + +pub const LOG_KERN: ::c_int = 0; +pub const LOG_USER: ::c_int = 1 << 3; +pub const LOG_MAIL: ::c_int = 2 << 3; +pub const LOG_DAEMON: ::c_int = 3 << 3; +pub const LOG_AUTH: ::c_int = 4 << 3; +pub const LOG_SYSLOG: ::c_int = 5 << 3; +pub const LOG_LPR: ::c_int = 6 << 3; +pub const LOG_NEWS: ::c_int = 7 << 3; +pub const LOG_UUCP: ::c_int = 8 << 3; +pub const LOG_LOCAL0: ::c_int = 16 << 3; +pub const LOG_LOCAL1: ::c_int = 17 << 3; +pub const LOG_LOCAL2: ::c_int = 18 << 3; +pub const LOG_LOCAL3: ::c_int = 19 << 3; +pub const LOG_LOCAL4: ::c_int = 20 << 3; +pub const LOG_LOCAL5: ::c_int = 21 << 3; +pub const LOG_LOCAL6: ::c_int = 22 << 3; +pub const LOG_LOCAL7: ::c_int = 23 << 3; + +pub const LOG_PID: ::c_int = 0x01; +pub const LOG_CONS: ::c_int = 0x02; +pub const LOG_ODELAY: ::c_int = 0x04; +pub const LOG_NDELAY: ::c_int = 0x08; +pub const LOG_NOWAIT: ::c_int = 0x10; + +pub const LOG_PRIMASK: ::c_int = 7; +pub const LOG_FACMASK: ::c_int = 0x3f8; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const PRIO_MIN: ::c_int = -20; +pub const PRIO_MAX: ::c_int = 20; + +pub const IPPROTO_ICMP: ::c_int = 1; +pub const IPPROTO_ICMPV6: ::c_int = 58; +pub const IPPROTO_TCP: ::c_int = 6; +pub const IPPROTO_UDP: ::c_int = 17; +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const INADDR_LOOPBACK: in_addr_t = 2130706433; +pub const INADDR_ANY: in_addr_t = 0; +pub const INADDR_BROADCAST: in_addr_t = 4294967295; +pub const INADDR_NONE: in_addr_t = 4294967295; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; + +// Linux-specific fcntls +pub const F_SETLEASE: ::c_int = 1024; +pub const F_GETLEASE: ::c_int = 1025; +pub const F_NOTIFY: ::c_int = 1026; +pub const F_CANCELLK: ::c_int = 1029; +pub const F_DUPFD_CLOEXEC: ::c_int = 1030; +pub const F_SETPIPE_SZ: ::c_int = 1031; +pub const F_GETPIPE_SZ: ::c_int = 1032; +pub const F_ADD_SEALS: ::c_int = 1033; +pub const F_GET_SEALS: ::c_int = 1034; + +pub const F_SEAL_SEAL: ::c_int = 0x0001; +pub const F_SEAL_SHRINK: ::c_int = 0x0002; +pub const F_SEAL_GROW: ::c_int = 0x0004; +pub const F_SEAL_WRITE: ::c_int = 0x0008; + +// FIXME(#235): Include file sealing fcntls once we have a way to verify them. + +pub const SIGTRAP: ::c_int = 5; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6; +pub const CLOCK_BOOTTIME: ::clockid_t = 7; +pub const CLOCK_REALTIME_ALARM: ::clockid_t = 8; +pub const CLOCK_BOOTTIME_ALARM: ::clockid_t = 9; +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; +pub const CLOCK_TAI: ::clockid_t = 11; +pub const TIMER_ABSTIME: ::c_int = 1; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_LOCKS: ::c_int = 10; +pub const RLIMIT_SIGPENDING: ::c_int = 11; +pub const RLIMIT_MSGQUEUE: ::c_int = 12; +pub const RLIMIT_NICE: ::c_int = 13; +pub const RLIMIT_RTPRIO: ::c_int = 14; + +pub const RUSAGE_SELF: ::c_int = 0; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; + +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_IFMT: ::mode_t = 61440; +pub const S_IRWXU: ::mode_t = 448; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IRWXG: ::mode_t = 56; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IRWXO: ::mode_t = 7; +pub const S_IXOTH: ::mode_t = 1; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IROTH: ::mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const LC_CTYPE: ::c_int = 0; +pub const LC_NUMERIC: ::c_int = 1; +pub const LC_TIME: ::c_int = 2; +pub const LC_COLLATE: ::c_int = 3; +pub const LC_MONETARY: ::c_int = 4; +pub const LC_MESSAGES: ::c_int = 5; +pub const LC_ALL: ::c_int = 6; +pub const LC_CTYPE_MASK: ::c_int = 1 << LC_CTYPE; +pub const LC_NUMERIC_MASK: ::c_int = 1 << LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << LC_TIME; +pub const LC_COLLATE_MASK: ::c_int = 1 << LC_COLLATE; +pub const LC_MONETARY_MASK: ::c_int = 1 << LC_MONETARY; +pub const LC_MESSAGES_MASK: ::c_int = 1 << LC_MESSAGES; +// LC_ALL_MASK defined per platform + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +// MS_ flags for msync(2) +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0004; + +// MS_ flags for mount(2) +pub const MS_RDONLY: ::c_ulong = 0x01; +pub const MS_NOSUID: ::c_ulong = 0x02; +pub const MS_NODEV: ::c_ulong = 0x04; +pub const MS_NOEXEC: ::c_ulong = 0x08; +pub const MS_SYNCHRONOUS: ::c_ulong = 0x10; +pub const MS_REMOUNT: ::c_ulong = 0x20; +pub const MS_MANDLOCK: ::c_ulong = 0x40; +pub const MS_DIRSYNC: ::c_ulong = 0x80; +pub const MS_NOATIME: ::c_ulong = 0x0400; +pub const MS_NODIRATIME: ::c_ulong = 0x0800; +pub const MS_BIND: ::c_ulong = 0x1000; +pub const MS_MOVE: ::c_ulong = 0x2000; +pub const MS_REC: ::c_ulong = 0x4000; +pub const MS_SILENT: ::c_ulong = 0x8000; +pub const MS_POSIXACL: ::c_ulong = 0x010000; +pub const MS_UNBINDABLE: ::c_ulong = 0x020000; +pub const MS_PRIVATE: ::c_ulong = 0x040000; +pub const MS_SLAVE: ::c_ulong = 0x080000; +pub const MS_SHARED: ::c_ulong = 0x100000; +pub const MS_RELATIME: ::c_ulong = 0x200000; +pub const MS_KERNMOUNT: ::c_ulong = 0x400000; +pub const MS_I_VERSION: ::c_ulong = 0x800000; +pub const MS_STRICTATIME: ::c_ulong = 0x1000000; +pub const MS_ACTIVE: ::c_ulong = 0x40000000; +pub const MS_NOUSER: ::c_ulong = 0x80000000; +pub const MS_MGC_VAL: ::c_ulong = 0xc0ed0000; +pub const MS_MGC_MSK: ::c_ulong = 0xffff0000; +pub const MS_RMT_MASK: ::c_ulong = 0x800051; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EWOULDBLOCK: ::c_int = EAGAIN; + +pub const SCM_RIGHTS: ::c_int = 0x01; +pub const SCM_CREDENTIALS: ::c_int = 0x02; + +pub const PROT_GROWSDOWN: ::c_int = 0x1000000; +pub const PROT_GROWSUP: ::c_int = 0x2000000; + +pub const MAP_TYPE: ::c_int = 0x000f; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 8; +pub const MADV_REMOVE: ::c_int = 9; +pub const MADV_DONTFORK: ::c_int = 10; +pub const MADV_DOFORK: ::c_int = 11; +pub const MADV_MERGEABLE: ::c_int = 12; +pub const MADV_UNMERGEABLE: ::c_int = 13; +pub const MADV_HUGEPAGE: ::c_int = 14; +pub const MADV_NOHUGEPAGE: ::c_int = 15; +pub const MADV_DONTDUMP: ::c_int = 16; +pub const MADV_DODUMP: ::c_int = 17; +pub const MADV_HWPOISON: ::c_int = 100; +pub const MADV_SOFT_OFFLINE: ::c_int = 101; + +pub const IFF_UP: ::c_int = 0x1; +pub const IFF_BROADCAST: ::c_int = 0x2; +pub const IFF_DEBUG: ::c_int = 0x4; +pub const IFF_LOOPBACK: ::c_int = 0x8; +pub const IFF_POINTOPOINT: ::c_int = 0x10; +pub const IFF_NOTRAILERS: ::c_int = 0x20; +pub const IFF_RUNNING: ::c_int = 0x40; +pub const IFF_NOARP: ::c_int = 0x80; +pub const IFF_PROMISC: ::c_int = 0x100; +pub const IFF_ALLMULTI: ::c_int = 0x200; +pub const IFF_MASTER: ::c_int = 0x400; +pub const IFF_SLAVE: ::c_int = 0x800; +pub const IFF_MULTICAST: ::c_int = 0x1000; +pub const IFF_PORTSEL: ::c_int = 0x2000; +pub const IFF_AUTOMEDIA: ::c_int = 0x4000; +pub const IFF_DYNAMIC: ::c_int = 0x8000; +pub const IFF_TUN: ::c_int = 0x0001; +pub const IFF_TAP: ::c_int = 0x0002; +pub const IFF_NO_PI: ::c_int = 0x1000; + +pub const SOL_IP: ::c_int = 0; +pub const SOL_TCP: ::c_int = 6; +pub const SOL_UDP: ::c_int = 17; +pub const SOL_IPV6: ::c_int = 41; +pub const SOL_ICMPV6: ::c_int = 58; +pub const SOL_RAW: ::c_int = 255; +pub const SOL_DECNET: ::c_int = 261; +pub const SOL_X25: ::c_int = 262; +pub const SOL_PACKET: ::c_int = 263; +pub const SOL_ATM: ::c_int = 264; +pub const SOL_AAL: ::c_int = 265; +pub const SOL_IRDA: ::c_int = 266; +pub const SOL_NETBEUI: ::c_int = 267; +pub const SOL_LLC: ::c_int = 268; +pub const SOL_DCCP: ::c_int = 269; +pub const SOL_NETLINK: ::c_int = 270; +pub const SOL_TIPC: ::c_int = 271; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_AX25: ::c_int = 3; +pub const AF_IPX: ::c_int = 4; +pub const AF_APPLETALK: ::c_int = 5; +pub const AF_NETROM: ::c_int = 6; +pub const AF_BRIDGE: ::c_int = 7; +pub const AF_ATMPVC: ::c_int = 8; +pub const AF_X25: ::c_int = 9; +pub const AF_INET6: ::c_int = 10; +pub const AF_ROSE: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_NETBEUI: ::c_int = 13; +pub const AF_SECURITY: ::c_int = 14; +pub const AF_KEY: ::c_int = 15; +pub const AF_NETLINK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = AF_NETLINK; +pub const AF_PACKET: ::c_int = 17; +pub const AF_ASH: ::c_int = 18; +pub const AF_ECONET: ::c_int = 19; +pub const AF_ATMSVC: ::c_int = 20; +pub const AF_RDS: ::c_int = 21; +pub const AF_SNA: ::c_int = 22; +pub const AF_IRDA: ::c_int = 23; +pub const AF_PPPOX: ::c_int = 24; +pub const AF_WANPIPE: ::c_int = 25; +pub const AF_LLC: ::c_int = 26; +pub const AF_CAN: ::c_int = 29; +pub const AF_TIPC: ::c_int = 30; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_IUCV: ::c_int = 32; +pub const AF_RXRPC: ::c_int = 33; +pub const AF_ISDN: ::c_int = 34; +pub const AF_PHONET: ::c_int = 35; +pub const AF_IEEE802154: ::c_int = 36; +pub const AF_CAIF: ::c_int = 37; +pub const AF_ALG: ::c_int = 38; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_AX25: ::c_int = AF_AX25; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_NETROM: ::c_int = AF_NETROM; +pub const PF_BRIDGE: ::c_int = AF_BRIDGE; +pub const PF_ATMPVC: ::c_int = AF_ATMPVC; +pub const PF_X25: ::c_int = AF_X25; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_ROSE: ::c_int = AF_ROSE; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_NETBEUI: ::c_int = AF_NETBEUI; +pub const PF_SECURITY: ::c_int = AF_SECURITY; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_NETLINK: ::c_int = AF_NETLINK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_PACKET: ::c_int = AF_PACKET; +pub const PF_ASH: ::c_int = AF_ASH; +pub const PF_ECONET: ::c_int = AF_ECONET; +pub const PF_ATMSVC: ::c_int = AF_ATMSVC; +pub const PF_RDS: ::c_int = AF_RDS; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_IRDA: ::c_int = AF_IRDA; +pub const PF_PPPOX: ::c_int = AF_PPPOX; +pub const PF_WANPIPE: ::c_int = AF_WANPIPE; +pub const PF_LLC: ::c_int = AF_LLC; +pub const PF_CAN: ::c_int = AF_CAN; +pub const PF_TIPC: ::c_int = AF_TIPC; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_IUCV: ::c_int = AF_IUCV; +pub const PF_RXRPC: ::c_int = AF_RXRPC; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_PHONET: ::c_int = AF_PHONET; +pub const PF_IEEE802154: ::c_int = AF_IEEE802154; +pub const PF_CAIF: ::c_int = AF_CAIF; +pub const PF_ALG: ::c_int = AF_ALG; + +pub const SOMAXCONN: ::c_int = 128; + +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTROUTE: ::c_int = 4; +pub const MSG_CTRUNC: ::c_int = 8; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_DONTWAIT: ::c_int = 0x40; +pub const MSG_EOR: ::c_int = 0x80; +pub const MSG_WAITALL: ::c_int = 0x100; +pub const MSG_FIN: ::c_int = 0x200; +pub const MSG_SYN: ::c_int = 0x400; +pub const MSG_CONFIRM: ::c_int = 0x800; +pub const MSG_RST: ::c_int = 0x1000; +pub const MSG_ERRQUEUE: ::c_int = 0x2000; +pub const MSG_NOSIGNAL: ::c_int = 0x4000; +pub const MSG_MORE: ::c_int = 0x8000; +pub const MSG_WAITFORONE: ::c_int = 0x10000; +pub const MSG_FASTOPEN: ::c_int = 0x20000000; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x40000000; + +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; + +pub const IP_TOS: ::c_int = 1; +pub const IP_TTL: ::c_int = 2; +pub const IP_HDRINCL: ::c_int = 3; +pub const IP_RECVTOS: ::c_int = 13; +pub const IP_FREEBIND: ::c_int = 15; +pub const IP_TRANSPARENT: ::c_int = 19; +pub const IP_MULTICAST_IF: ::c_int = 32; +pub const IP_MULTICAST_TTL: ::c_int = 33; +pub const IP_MULTICAST_LOOP: ::c_int = 34; +pub const IP_ADD_MEMBERSHIP: ::c_int = 35; +pub const IP_DROP_MEMBERSHIP: ::c_int = 36; + +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +pub const IPV6_MULTICAST_LOOP: ::c_int = 19; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21; +pub const IPV6_V6ONLY: ::c_int = 26; +pub const IPV6_RECVPKTINFO: ::c_int = 49; +pub const IPV6_RECVTCLASS: ::c_int = 66; +pub const IPV6_TCLASS: ::c_int = 67; + +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; +pub const TCP_CORK: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_SYNCNT: ::c_int = 7; +pub const TCP_LINGER2: ::c_int = 8; +pub const TCP_DEFER_ACCEPT: ::c_int = 9; +pub const TCP_WINDOW_CLAMP: ::c_int = 10; +pub const TCP_INFO: ::c_int = 11; +pub const TCP_QUICKACK: ::c_int = 12; +pub const TCP_CONGESTION: ::c_int = 13; + +pub const SO_DEBUG: ::c_int = 1; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const PATH_MAX: ::c_int = 4096; + +pub const FD_SETSIZE: usize = 1024; + +pub const EPOLLIN: ::c_int = 0x1; +pub const EPOLLPRI: ::c_int = 0x2; +pub const EPOLLOUT: ::c_int = 0x4; +pub const EPOLLRDNORM: ::c_int = 0x40; +pub const EPOLLRDBAND: ::c_int = 0x80; +pub const EPOLLWRNORM: ::c_int = 0x100; +pub const EPOLLWRBAND: ::c_int = 0x200; +pub const EPOLLMSG: ::c_int = 0x400; +pub const EPOLLERR: ::c_int = 0x8; +pub const EPOLLHUP: ::c_int = 0x10; +pub const EPOLLET: ::c_int = 0x80000000; + +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLL_CTL_DEL: ::c_int = 2; + +pub const MNT_DETACH: ::c_int = 0x2; +pub const MNT_EXPIRE: ::c_int = 0x4; + +pub const Q_GETFMT: ::c_int = 0x800004; +pub const Q_GETINFO: ::c_int = 0x800005; +pub const Q_SETINFO: ::c_int = 0x800006; +pub const QIF_BLIMITS: u32 = 1; +pub const QIF_SPACE: u32 = 2; +pub const QIF_ILIMITS: u32 = 4; +pub const QIF_INODES: u32 = 8; +pub const QIF_BTIME: u32 = 16; +pub const QIF_ITIME: u32 = 32; +pub const QIF_LIMITS: u32 = 5; +pub const QIF_USAGE: u32 = 10; +pub const QIF_TIMES: u32 = 48; +pub const QIF_ALL: u32 = 63; + +pub const MNT_FORCE: ::c_int = 0x1; + +pub const Q_SYNC: ::c_int = 0x800001; +pub const Q_QUOTAON: ::c_int = 0x800002; +pub const Q_QUOTAOFF: ::c_int = 0x800003; +pub const Q_GETQUOTA: ::c_int = 0x800007; +pub const Q_SETQUOTA: ::c_int = 0x800008; + +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const NL0: ::c_int = 0x00000000; +pub const NL1: ::c_int = 0x00000100; +pub const TAB0: ::c_int = 0x00000000; +pub const CR0: ::c_int = 0x00000000; +pub const FF0: ::c_int = 0x00000000; +pub const BS0: ::c_int = 0x00000000; +pub const VT0: ::c_int = 0x00000000; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VLNEXT: usize = 15; +pub const IGNBRK: ::tcflag_t = 0x00000001; +pub const BRKINT: ::tcflag_t = 0x00000002; +pub const IGNPAR: ::tcflag_t = 0x00000004; +pub const PARMRK: ::tcflag_t = 0x00000008; +pub const INPCK: ::tcflag_t = 0x00000010; +pub const ISTRIP: ::tcflag_t = 0x00000020; +pub const INLCR: ::tcflag_t = 0x00000040; +pub const IGNCR: ::tcflag_t = 0x00000080; +pub const ICRNL: ::tcflag_t = 0x00000100; +pub const IXANY: ::tcflag_t = 0x00000800; +pub const IMAXBEL: ::tcflag_t = 0x00002000; +pub const OPOST: ::tcflag_t = 0x1; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CRTSCTS: ::tcflag_t = 0x80000000; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const OCRNL: ::tcflag_t = 0o000010; +pub const ONOCR: ::tcflag_t = 0o000020; +pub const ONLRET: ::tcflag_t = 0o000040; +pub const OFILL: ::tcflag_t = 0o000100; +pub const OFDEL: ::tcflag_t = 0o000200; + +pub const CLONE_VM: ::c_int = 0x100; +pub const CLONE_FS: ::c_int = 0x200; +pub const CLONE_FILES: ::c_int = 0x400; +pub const CLONE_SIGHAND: ::c_int = 0x800; +pub const CLONE_PTRACE: ::c_int = 0x2000; +pub const CLONE_VFORK: ::c_int = 0x4000; +pub const CLONE_PARENT: ::c_int = 0x8000; +pub const CLONE_THREAD: ::c_int = 0x10000; +pub const CLONE_NEWNS: ::c_int = 0x20000; +pub const CLONE_SYSVSEM: ::c_int = 0x40000; +pub const CLONE_SETTLS: ::c_int = 0x80000; +pub const CLONE_PARENT_SETTID: ::c_int = 0x100000; +pub const CLONE_CHILD_CLEARTID: ::c_int = 0x200000; +pub const CLONE_DETACHED: ::c_int = 0x400000; +pub const CLONE_UNTRACED: ::c_int = 0x800000; +pub const CLONE_CHILD_SETTID: ::c_int = 0x01000000; +pub const CLONE_NEWUTS: ::c_int = 0x04000000; +pub const CLONE_NEWIPC: ::c_int = 0x08000000; +pub const CLONE_NEWUSER: ::c_int = 0x10000000; +pub const CLONE_NEWPID: ::c_int = 0x20000000; +pub const CLONE_NEWNET: ::c_int = 0x40000000; +pub const CLONE_IO: ::c_int = 0x80000000; +pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; + +pub const WNOHANG: ::c_int = 0x00000001; +pub const WUNTRACED: ::c_int = 0x00000002; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WEXITED: ::c_int = 0x00000004; +pub const WCONTINUED: ::c_int = 0x00000008; +pub const WNOWAIT: ::c_int = 0x01000000; + +// ::Options set using PTRACE_SETOPTIONS. +pub const PTRACE_O_TRACESYSGOOD: ::c_int = 0x00000001; +pub const PTRACE_O_TRACEFORK: ::c_int = 0x00000002; +pub const PTRACE_O_TRACEVFORK: ::c_int = 0x00000004; +pub const PTRACE_O_TRACECLONE: ::c_int = 0x00000008; +pub const PTRACE_O_TRACEEXEC: ::c_int = 0x00000010; +pub const PTRACE_O_TRACEVFORKDONE: ::c_int = 0x00000020; +pub const PTRACE_O_TRACEEXIT: ::c_int = 0x00000040; +pub const PTRACE_O_TRACESECCOMP: ::c_int = 0x00000080; +pub const PTRACE_O_EXITKILL: ::c_int = 0x00100000; +pub const PTRACE_O_SUSPEND_SECCOMP: ::c_int = 0x00200000; +pub const PTRACE_O_MASK: ::c_int = 0x003000ff; + +// Wait extended result codes for the above trace options. +pub const PTRACE_EVENT_FORK: ::c_int = 1; +pub const PTRACE_EVENT_VFORK: ::c_int = 2; +pub const PTRACE_EVENT_CLONE: ::c_int = 3; +pub const PTRACE_EVENT_EXEC: ::c_int = 4; +pub const PTRACE_EVENT_VFORK_DONE: ::c_int = 5; +pub const PTRACE_EVENT_EXIT: ::c_int = 6; +pub const PTRACE_EVENT_SECCOMP: ::c_int = 7; +// PTRACE_EVENT_STOP was added to glibc in 2.26 +// pub const PTRACE_EVENT_STOP: ::c_int = 128; + +pub const __WNOTHREAD: ::c_int = 0x20000000; +pub const __WALL: ::c_int = 0x40000000; +pub const __WCLONE: ::c_int = 0x80000000; + +pub const SPLICE_F_MOVE: ::c_uint = 0x01; +pub const SPLICE_F_NONBLOCK: ::c_uint = 0x02; +pub const SPLICE_F_MORE: ::c_uint = 0x04; +pub const SPLICE_F_GIFT: ::c_uint = 0x08; + +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_LAZY: ::c_int = 1; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x100; +pub const AT_REMOVEDIR: ::c_int = 0x200; +pub const AT_EACCESS: ::c_int = 0x200; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; +pub const AT_NO_AUTOMOUNT: ::c_int = 0x800; +pub const AT_EMPTY_PATH: ::c_int = 0x1000; + +pub const LOG_CRON: ::c_int = 9 << 3; +pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +pub const LOG_FTP: ::c_int = 11 << 3; +pub const LOG_PERROR: ::c_int = 0x20; + +pub const PIPE_BUF: usize = 4096; + +pub const SI_LOAD_SHIFT: ::c_uint = 16; + +pub const CLD_EXITED: ::c_int = 1; +pub const CLD_KILLED: ::c_int = 2; +pub const CLD_DUMPED: ::c_int = 3; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const SIGEV_SIGNAL: ::c_int = 0; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const UTIME_OMIT: c_long = 1073741822; +pub const UTIME_NOW: c_long = 1073741823; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLRDBAND: ::c_short = 0x080; + +pub const ABDAY_1: ::nl_item = 0x20000; +pub const ABDAY_2: ::nl_item = 0x20001; +pub const ABDAY_3: ::nl_item = 0x20002; +pub const ABDAY_4: ::nl_item = 0x20003; +pub const ABDAY_5: ::nl_item = 0x20004; +pub const ABDAY_6: ::nl_item = 0x20005; +pub const ABDAY_7: ::nl_item = 0x20006; + +pub const DAY_1: ::nl_item = 0x20007; +pub const DAY_2: ::nl_item = 0x20008; +pub const DAY_3: ::nl_item = 0x20009; +pub const DAY_4: ::nl_item = 0x2000A; +pub const DAY_5: ::nl_item = 0x2000B; +pub const DAY_6: ::nl_item = 0x2000C; +pub const DAY_7: ::nl_item = 0x2000D; + +pub const ABMON_1: ::nl_item = 0x2000E; +pub const ABMON_2: ::nl_item = 0x2000F; +pub const ABMON_3: ::nl_item = 0x20010; +pub const ABMON_4: ::nl_item = 0x20011; +pub const ABMON_5: ::nl_item = 0x20012; +pub const ABMON_6: ::nl_item = 0x20013; +pub const ABMON_7: ::nl_item = 0x20014; +pub const ABMON_8: ::nl_item = 0x20015; +pub const ABMON_9: ::nl_item = 0x20016; +pub const ABMON_10: ::nl_item = 0x20017; +pub const ABMON_11: ::nl_item = 0x20018; +pub const ABMON_12: ::nl_item = 0x20019; + +pub const MON_1: ::nl_item = 0x2001A; +pub const MON_2: ::nl_item = 0x2001B; +pub const MON_3: ::nl_item = 0x2001C; +pub const MON_4: ::nl_item = 0x2001D; +pub const MON_5: ::nl_item = 0x2001E; +pub const MON_6: ::nl_item = 0x2001F; +pub const MON_7: ::nl_item = 0x20020; +pub const MON_8: ::nl_item = 0x20021; +pub const MON_9: ::nl_item = 0x20022; +pub const MON_10: ::nl_item = 0x20023; +pub const MON_11: ::nl_item = 0x20024; +pub const MON_12: ::nl_item = 0x20025; + +pub const AM_STR: ::nl_item = 0x20026; +pub const PM_STR: ::nl_item = 0x20027; + +pub const D_T_FMT: ::nl_item = 0x20028; +pub const D_FMT: ::nl_item = 0x20029; +pub const T_FMT: ::nl_item = 0x2002A; +pub const T_FMT_AMPM: ::nl_item = 0x2002B; + +pub const ERA: ::nl_item = 0x2002C; +pub const ERA_D_FMT: ::nl_item = 0x2002E; +pub const ALT_DIGITS: ::nl_item = 0x2002F; +pub const ERA_D_T_FMT: ::nl_item = 0x20030; +pub const ERA_T_FMT: ::nl_item = 0x20031; + +pub const CODESET: ::nl_item = 14; + +pub const CRNCYSTR: ::nl_item = 0x4000F; + +pub const RUSAGE_THREAD: ::c_int = 1; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const RADIXCHAR: ::nl_item = 0x10000; +pub const THOUSEP: ::nl_item = 0x10001; + +pub const YESEXPR: ::nl_item = 0x50000; +pub const NOEXPR: ::nl_item = 0x50001; +pub const YESSTR: ::nl_item = 0x50002; +pub const NOSTR: ::nl_item = 0x50003; + +pub const FILENAME_MAX: ::c_uint = 4096; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; + +pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; + +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; + +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +pub const IFF_LOWER_UP: ::c_int = 0x10000; +pub const IFF_DORMANT: ::c_int = 0x20000; +pub const IFF_ECHO: ::c_int = 0x40000; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x2; + +pub const TCP_MD5SIG: ::c_int = 14; + +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const RENAME_NOREPLACE: ::c_int = 1; +pub const RENAME_EXCHANGE: ::c_int = 2; +pub const RENAME_WHITEOUT: ::c_int = 4; + +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; + +// netinet/in.h +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// DCCP +pub const IPPROTO_DCCP: ::c_int = 33; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_MTP: ::c_int = 92; +pub const IPPROTO_BEETPH: ::c_int = 94; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_COMP: ::c_int = 108; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_MH: ::c_int = 135; +pub const IPPROTO_UDPLITE: ::c_int = 136; +pub const IPPROTO_MPLS: ::c_int = 137; +/// raw IP packet +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MAX: ::c_int = 256; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +// System V IPC +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_CREAT: ::c_int = 0o1000; +pub const IPC_EXCL: ::c_int = 0o2000; +pub const IPC_NOWAIT: ::c_int = 0o4000; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; +pub const IPC_INFO: ::c_int = 3; +pub const MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; +pub const MSG_COPY: ::c_int = 0o40000; + +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_REMAP: ::c_int = 0o40000; +pub const SHM_EXEC: ::c_int = 0o100000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; + +pub const SHM_HUGETLB: ::c_int = 0o4000; +pub const SHM_NORESERVE: ::c_int = 0o10000; + +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +pub const EPOLLONESHOT: ::c_int = 0x40000000; + +pub const QFMT_VFS_OLD: ::c_int = 1; +pub const QFMT_VFS_V0: ::c_int = 2; +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +pub const EAI_SYSTEM: ::c_int = -11; + +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; + +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +pub const PR_GET_TIMING: ::c_int = 13; +pub const PR_SET_TIMING: ::c_int = 14; +pub const PR_TIMING_STATISTICAL: ::c_int = 0; +pub const PR_TIMING_TIMESTAMP: ::c_int = 1; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +pub const PR_SET_MM_MAP: ::c_int = 14; +pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + +pub const PR_SET_PTRACER: ::c_int = 0x59616d61; +pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff; + +pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; +pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2; +pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3; +pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const TFD_NONBLOCK: ::c_int = O_NONBLOCK; +pub const TFD_TIMER_ABSTIME: ::c_int = 1; + +pub const XATTR_CREATE: ::c_int = 0x1; +pub const XATTR_REPLACE: ::c_int = 0x2; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +// On Linux, libc doesn't define this constant, libattr does instead. +// We still define it for Linux as it's defined by libc on other platforms, +// and it's mentioned in the man pages for getxattr and setxattr. +pub const ENOATTR: ::c_int = ::ENODATA; + +pub const SO_ORIGINAL_DST: ::c_int = 80; +pub const IUTF8: ::tcflag_t = 0x00004000; +pub const CMSPAR: ::tcflag_t = 0o10000000000; + +pub const MFD_CLOEXEC: ::c_uint = 0x0001; +pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; + +// these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has +// the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 +// so we can use that type here to avoid having to cast. +pub const PT_NULL: u32 = 0; +pub const PT_LOAD: u32 = 1; +pub const PT_DYNAMIC: u32 = 2; +pub const PT_INTERP: u32 = 3; +pub const PT_NOTE: u32 = 4; +pub const PT_SHLIB: u32 = 5; +pub const PT_PHDR: u32 = 6; +pub const PT_TLS: u32 = 7; +pub const PT_NUM: u32 = 8; +pub const PT_LOOS: u32 = 0x60000000; +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_STACK: u32 = 0x6474e551; +pub const PT_GNU_RELRO: u32 = 0x6474e552; + +// Ethernet protocol IDs. +pub const ETH_P_LOOP: ::c_int = 0x0060; +pub const ETH_P_PUP: ::c_int = 0x0200; +pub const ETH_P_PUPAT: ::c_int = 0x0201; +pub const ETH_P_IP: ::c_int = 0x0800; +pub const ETH_P_X25: ::c_int = 0x0805; +pub const ETH_P_ARP: ::c_int = 0x0806; +pub const ETH_P_BPQ: ::c_int = 0x08FF; +pub const ETH_P_IEEEPUP: ::c_int = 0x0a00; +pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01; +pub const ETH_P_BATMAN: ::c_int = 0x4305; +pub const ETH_P_DEC: ::c_int = 0x6000; +pub const ETH_P_DNA_DL: ::c_int = 0x6001; +pub const ETH_P_DNA_RC: ::c_int = 0x6002; +pub const ETH_P_DNA_RT: ::c_int = 0x6003; +pub const ETH_P_LAT: ::c_int = 0x6004; +pub const ETH_P_DIAG: ::c_int = 0x6005; +pub const ETH_P_CUST: ::c_int = 0x6006; +pub const ETH_P_SCA: ::c_int = 0x6007; +pub const ETH_P_TEB: ::c_int = 0x6558; +pub const ETH_P_RARP: ::c_int = 0x8035; +pub const ETH_P_ATALK: ::c_int = 0x809B; +pub const ETH_P_AARP: ::c_int = 0x80F3; +pub const ETH_P_8021Q: ::c_int = 0x8100; +pub const ETH_P_IPX: ::c_int = 0x8137; +pub const ETH_P_IPV6: ::c_int = 0x86DD; +pub const ETH_P_PAUSE: ::c_int = 0x8808; +pub const ETH_P_SLOW: ::c_int = 0x8809; +pub const ETH_P_WCCP: ::c_int = 0x883E; +pub const ETH_P_MPLS_UC: ::c_int = 0x8847; +pub const ETH_P_MPLS_MC: ::c_int = 0x8848; +pub const ETH_P_ATMMPOA: ::c_int = 0x884c; +pub const ETH_P_PPP_DISC: ::c_int = 0x8863; +pub const ETH_P_PPP_SES: ::c_int = 0x8864; +pub const ETH_P_LINK_CTL: ::c_int = 0x886c; +pub const ETH_P_ATMFATE: ::c_int = 0x8884; +pub const ETH_P_PAE: ::c_int = 0x888E; +pub const ETH_P_AOE: ::c_int = 0x88A2; +pub const ETH_P_8021AD: ::c_int = 0x88A8; +pub const ETH_P_802_EX1: ::c_int = 0x88B5; +pub const ETH_P_TIPC: ::c_int = 0x88CA; +pub const ETH_P_8021AH: ::c_int = 0x88E7; +pub const ETH_P_MVRP: ::c_int = 0x88F5; +pub const ETH_P_1588: ::c_int = 0x88F7; +pub const ETH_P_PRP: ::c_int = 0x88FB; +pub const ETH_P_FCOE: ::c_int = 0x8906; +pub const ETH_P_TDLS: ::c_int = 0x890D; +pub const ETH_P_FIP: ::c_int = 0x8914; +pub const ETH_P_80221: ::c_int = 0x8917; +pub const ETH_P_LOOPBACK: ::c_int = 0x9000; +pub const ETH_P_QINQ1: ::c_int = 0x9100; +pub const ETH_P_QINQ2: ::c_int = 0x9200; +pub const ETH_P_QINQ3: ::c_int = 0x9300; +pub const ETH_P_EDSA: ::c_int = 0xDADA; +pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB; + +pub const ETH_P_802_3_MIN: ::c_int = 0x0600; + +pub const ETH_P_802_3: ::c_int = 0x0001; +pub const ETH_P_AX25: ::c_int = 0x0002; +pub const ETH_P_ALL: ::c_int = 0x0003; +pub const ETH_P_802_2: ::c_int = 0x0004; +pub const ETH_P_SNAP: ::c_int = 0x0005; +pub const ETH_P_DDCMP: ::c_int = 0x0006; +pub const ETH_P_WAN_PPP: ::c_int = 0x0007; +pub const ETH_P_PPP_MP: ::c_int = 0x0008; +pub const ETH_P_LOCALTALK: ::c_int = 0x0009; +pub const ETH_P_CAN: ::c_int = 0x000C; +pub const ETH_P_CANFD: ::c_int = 0x000D; +pub const ETH_P_PPPTALK: ::c_int = 0x0010; +pub const ETH_P_TR_802_2: ::c_int = 0x0011; +pub const ETH_P_MOBITEX: ::c_int = 0x0015; +pub const ETH_P_CONTROL: ::c_int = 0x0016; +pub const ETH_P_IRDA: ::c_int = 0x0017; +pub const ETH_P_ECONET: ::c_int = 0x0018; +pub const ETH_P_HDLC: ::c_int = 0x0019; +pub const ETH_P_ARCNET: ::c_int = 0x001A; +pub const ETH_P_DSA: ::c_int = 0x001B; +pub const ETH_P_TRAILER: ::c_int = 0x001C; +pub const ETH_P_PHONET: ::c_int = 0x00F5; +pub const ETH_P_IEEE802154: ::c_int = 0x00F6; +pub const ETH_P_CAIF: ::c_int = 0x00F7; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 0x00040000; +pub const O_NOATIME: ::c_int = 0x00002000; +pub const O_CLOEXEC: ::c_int = 0x00000100; +pub const O_TMPFILE: ::c_int = 0x00004000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const O_PATH: ::c_int = 0x00400000; +pub const O_EXEC: ::c_int = O_PATH; +pub const O_SEARCH: ::c_int = O_PATH; +pub const O_ACCMODE: ::c_int = 03 | O_SEARCH; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const RLIM_INFINITY: ::rlim_t = !0; +pub const RLIMIT_RTTIME: ::c_int = 15; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIMIT_NLIMITS: ::c_int = 16; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; + +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; + +pub const SIGUNUSED: ::c_int = ::SIGSYS; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + +pub const CPU_SETSIZE: ::c_int = 128; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_GETREGS: ::c_int = 12; +pub const PTRACE_SETREGS: ::c_int = 13; +pub const PTRACE_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_GETFPXREGS: ::c_int = 18; +pub const PTRACE_SETFPXREGS: ::c_int = 19; +pub const PTRACE_SYSCALL: ::c_int = 24; +pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; +pub const PTRACE_GETREGSET: ::c_int = 0x4204; +pub const PTRACE_SETREGSET: ::c_int = 0x4205; +pub const PTRACE_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; + +pub const EPOLLWAKEUP: ::c_int = 0x20000000; + +pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const TIOCINQ: ::c_int = ::FIONREAD; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + +pub const O_ASYNC: ::c_int = 0x00000400; + +pub const FIOCLEX: ::c_int = 0x5451; +pub const FIONBIO: ::c_int = 0x5421; + +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_NOFILE: ::c_int = 7; +pub const RLIMIT_AS: ::c_int = 9; +pub const RLIMIT_NPROC: ::c_int = 6; +pub const RLIMIT_MEMLOCK: ::c_int = 8; + +pub const O_APPEND: ::c_int = 0x00100000; +pub const O_CREAT: ::c_int = 0x00010000; +pub const O_EXCL: ::c_int = 0x00020000; +pub const O_NOCTTY: ::c_int = 0x00000200; +pub const O_NONBLOCK: ::c_int = 0x00000010; +pub const O_SYNC: ::c_int = 0x00000040 | O_DSYNC; +pub const O_RSYNC: ::c_int = O_SYNC; +pub const O_DSYNC: ::c_int = 0x00000020; + +pub const SOCK_CLOEXEC: ::c_int = 0o2000000; +pub const SOCK_NONBLOCK: ::c_int = 0o4000; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOL_SOCKET: ::c_int = 1; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const TCGETS: ::c_int = 0x5401; +pub const TCSETS: ::c_int = 0x5402; +pub const TCSETSW: ::c_int = 0x5403; +pub const TCSETSF: ::c_int = 0x5404; +pub const TCGETA: ::c_int = 0x5405; +pub const TCSETA: ::c_int = 0x5406; +pub const TCSETAW: ::c_int = 0x5407; +pub const TCSETAF: ::c_int = 0x5408; +pub const TCSBRK: ::c_int = 0x5409; +pub const TCXONC: ::c_int = 0x540A; +pub const TCFLSH: ::c_int = 0x540B; +pub const TIOCGSOFTCAR: ::c_int = 0x5419; +pub const TIOCSSOFTCAR: ::c_int = 0x541A; +pub const TIOCLINUX: ::c_int = 0x541C; +pub const TIOCGSERIAL: ::c_int = 0x541E; +pub const TIOCEXCL: ::c_int = 0x540C; +pub const TIOCNXCL: ::c_int = 0x540D; +pub const TIOCSCTTY: ::c_int = 0x540E; +pub const TIOCGPGRP: ::c_int = 0x540F; +pub const TIOCSPGRP: ::c_int = 0x5410; +pub const TIOCOUTQ: ::c_int = 0x5411; +pub const TIOCSTI: ::c_int = 0x5412; +pub const TIOCGWINSZ: ::c_int = 0x5413; +pub const TIOCSWINSZ: ::c_int = 0x5414; +pub const TIOCMGET: ::c_int = 0x5415; +pub const TIOCMBIS: ::c_int = 0x5416; +pub const TIOCMBIC: ::c_int = 0x5417; +pub const TIOCMSET: ::c_int = 0x5418; +pub const FIONREAD: ::c_int = 0x541B; +pub const TIOCCONS: ::c_int = 0x541D; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +pub const O_DIRECTORY: ::c_int = 0x00080000; +pub const O_DIRECT: ::c_int = 0x00000800; +pub const O_LARGEFILE: ::c_int = 0x00001000; +pub const O_NOFOLLOW: ::c_int = 0x00000080; + +pub const HUGETLB_FLAG_ENCODE_SHIFT: u32 = 26; +pub const MAP_HUGE_SHIFT: u32 = 26; + +// intentionally not public, only used for fd_set +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + const ULONG_SIZE: usize = 32; + } else if #[cfg(target_pointer_width = "64")] { + const ULONG_SIZE: usize = 64; + } else { + // Unknown target_pointer_width + } +} + +// END_PUB_CONST + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; + major |= (dev & 0xfffff00000000000) >> 32; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as ::c_uint + } + + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + cmsg.offset(1) as *mut c_uchar + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) + -> *mut cmsghdr + { + if ((*cmsg).cmsg_len as ::size_t) < ::mem::size_of::() { + 0 as *mut cmsghdr + } else if __CMSG_NEXT(cmsg).add(::mem::size_of::()) + >= __MHDR_END(mhdr) { + 0 as *mut cmsghdr + } else { + __CMSG_NEXT(cmsg).cast() + } + } + + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as ::size_t >= ::mem::size_of::() { + (*mhdr).msg_control.cast() + } else { + 0 as *mut cmsghdr + } + } + + pub {const} fn CMSG_ALIGN(len: ::size_t) -> ::size_t { + (len + ::mem::size_of::<::size_t>() - 1) + & !(::mem::size_of::<::size_t>() - 1) + } + + pub {const} fn CMSG_SPACE(len: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(len as ::size_t) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(len: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(::mem::size_of::()) + len as ::size_t) as ::c_uint + } +} + +safe_f! { + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0x7f) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0x00000fff) << 8; + dev |= (major & 0xfffff000) << 32; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } +} + +fn __CMSG_LEN(cmsg: *const cmsghdr) -> ::ssize_t { + ((unsafe { (*cmsg).cmsg_len as ::size_t } + ::mem::size_of::<::c_long>() - 1) + & !(::mem::size_of::<::c_long>() - 1)) as ::ssize_t +} + +fn __CMSG_NEXT(cmsg: *const cmsghdr) -> *mut c_uchar { + (unsafe { cmsg.offset(__CMSG_LEN(cmsg)) }) as *mut c_uchar +} + +fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar { + unsafe { (*mhdr).msg_control.offset((*mhdr).msg_controllen as isize) }.cast() +} + +// EXTERN_FN + +#[link(name = "c")] +#[link(name = "fdio")] +extern "C" {} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +extern "C" { + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn isblank(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); + pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; + pub fn atol(s: *const c_char) -> c_long; + pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; + pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; + pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; + pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; + pub fn atexit(cb: extern "C" fn()) -> c_int; + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn abs(i: c_int) -> c_int; + pub fn labs(i: c_long) -> c_long; + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); + + pub fn getpwnam(name: *const ::c_char) -> *mut passwd; + pub fn getpwuid(uid: ::uid_t) -> *mut passwd; + + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int; + pub fn connect(socket: ::c_int, address: *const sockaddr, len: socklen_t) -> ::c_int; + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + pub fn accept(socket: ::c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> ::c_int; + pub fn getpeername( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + pub fn getsockname( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + pub fn setsockopt( + socket: ::c_int, + level: ::c_int, + name: ::c_int, + value: *const ::c_void, + option_len: socklen_t, + ) -> ::c_int; + pub fn socketpair( + domain: ::c_int, + type_: ::c_int, + protocol: ::c_int, + socket_vector: *mut ::c_int, + ) -> ::c_int; + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + + pub fn chmod(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fchmod(fd: ::c_int, mode: mode_t) -> ::c_int; + + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn pclose(stream: *mut ::FILE) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) + -> ::c_int; + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int, ...) -> ::c_int; + pub fn fchmodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fchown(fd: ::c_int, owner: ::uid_t, group: ::gid_t) -> ::c_int; + pub fn fchownat( + dirfd: ::c_int, + pathname: *const ::c_char, + owner: ::uid_t, + group: ::gid_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn readlinkat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t, + ) -> ::ssize_t; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn alarm(seconds: ::c_uint) -> ::c_uint; + pub fn chdir(dir: *const c_char) -> ::c_int; + pub fn chown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + pub fn lchown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + pub fn close(fd: ::c_int) -> ::c_int; + pub fn dup(fd: ::c_int) -> ::c_int; + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> ::c_int; + pub fn execle(path: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execlp(file: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execve( + prog: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn fork() -> pid_t; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; + pub fn getegid() -> gid_t; + pub fn geteuid() -> uid_t; + pub fn getgid() -> gid_t; + pub fn getgroups(ngroups_max: ::c_int, groups: *mut gid_t) -> ::c_int; + pub fn getlogin() -> *mut c_char; + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn getpgid(pid: pid_t) -> pid_t; + pub fn getpgrp() -> pid_t; + pub fn getpid() -> pid_t; + pub fn getppid() -> pid_t; + pub fn getuid() -> uid_t; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pause() -> ::c_int; + pub fn pipe(fds: *mut ::c_int) -> ::c_int; + pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int; + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t) -> ::ssize_t; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn seteuid(uid: uid_t) -> ::c_int; + pub fn setegid(gid: gid_t) -> ::c_int; + pub fn setgid(gid: gid_t) -> ::c_int; + pub fn setpgid(pid: pid_t, pgid: pid_t) -> ::c_int; + pub fn setsid() -> pid_t; + pub fn setuid(uid: uid_t) -> ::c_int; + pub fn sleep(secs: ::c_uint) -> ::c_uint; + pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> ::c_int; + pub fn tcgetpgrp(fd: ::c_int) -> pid_t; + pub fn tcsetpgrp(fd: ::c_int, pgrp: ::pid_t) -> ::c_int; + pub fn ttyname(fd: ::c_int) -> *mut c_char; + pub fn unlink(c: *const c_char) -> ::c_int; + pub fn wait(status: *mut ::c_int) -> pid_t; + pub fn waitpid(pid: pid_t, status: *mut ::c_int, options: ::c_int) -> pid_t; + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t; + pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn umask(mask: mode_t) -> mode_t; + + pub fn utime(file: *const c_char, buf: *const utimbuf) -> ::c_int; + + pub fn kill(pid: pid_t, sig: ::c_int) -> ::c_int; + + pub fn mlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn munlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn mlockall(flags: ::c_int) -> ::c_int; + pub fn munlockall() -> ::c_int; + + pub fn mmap( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off_t, + ) -> *mut ::c_void; + pub fn munmap(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + + pub fn if_nametoindex(ifname: *const c_char) -> ::c_uint; + pub fn if_indextoname(ifindex: ::c_uint, ifname: *mut ::c_char) -> *mut ::c_char; + + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn fsync(fd: ::c_int) -> ::c_int; + + pub fn setenv(name: *const c_char, val: *const c_char, overwrite: ::c_int) -> ::c_int; + pub fn unsetenv(name: *const c_char) -> ::c_int; + + pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int; + + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t; + + pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char; + + pub fn flock(fd: ::c_int, operation: ::c_int) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn pthread_self() -> ::pthread_t; + pub fn pthread_join(native: ::pthread_t, value: *mut *mut ::c_void) -> ::c_int; + pub fn pthread_exit(value: *mut ::c_void) -> !; + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_destroy(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstacksize( + attr: *const ::pthread_attr_t, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stack_size: ::size_t) -> ::c_int; + pub fn pthread_attr_setdetachstate(attr: *mut ::pthread_attr_t, state: ::c_int) -> ::c_int; + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + pub fn sched_yield() -> ::c_int; + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: ::Option, + ) -> ::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ::c_void) -> ::c_int; + pub fn pthread_mutex_init( + lock: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> ::c_int; + pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> ::c_int; + + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> ::c_int; + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> ::c_int; + pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: ::c_int) -> ::c_int; + + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) + -> ::c_int; + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_condattr_init(attr: *mut pthread_condattr_t) -> ::c_int; + pub fn pthread_condattr_destroy(attr: *mut pthread_condattr_t) -> ::c_int; + pub fn pthread_rwlock_init( + lock: *mut pthread_rwlock_t, + attr: *const pthread_rwlockattr_t, + ) -> ::c_int; + pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_rdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_tryrdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_wrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_trywrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> ::c_int; + pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> ::c_int; + pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + pub fn raise(signum: ::c_int) -> ::c_int; + pub fn sigaction(signum: ::c_int, act: *const sigaction, oldact: *mut sigaction) -> ::c_int; + + pub fn utimes(filename: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn dlopen(filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + pub fn dlerror() -> *mut ::c_char; + pub fn dlsym(handle: *mut ::c_void, symbol: *const ::c_char) -> *mut ::c_void; + pub fn dlclose(handle: *mut ::c_void) -> ::c_int; + pub fn dladdr(addr: *const ::c_void, info: *mut Dl_info) -> ::c_int; + + pub fn getaddrinfo( + node: *const c_char, + service: *const c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + pub fn freeaddrinfo(res: *mut addrinfo); + pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char; + pub fn res_init() -> ::c_int; + + pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn localtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn mktime(tm: *mut tm) -> time_t; + pub fn time(time: *mut time_t) -> time_t; + pub fn gmtime(time_p: *const time_t) -> *mut tm; + pub fn localtime(time_p: *const time_t) -> *mut tm; + + pub fn mknod(pathname: *const ::c_char, mode: ::mode_t, dev: ::dev_t) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn getservbyname(name: *const ::c_char, proto: *const ::c_char) -> *mut servent; + pub fn getprotobyname(name: *const ::c_char) -> *mut protoent; + pub fn getprotobynumber(proto: ::c_int) -> *mut protoent; + pub fn usleep(secs: ::c_uint) -> ::c_int; + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn putenv(string: *mut c_char) -> ::c_int; + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + pub fn select( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval, + ) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_wait(sem: *mut sem_t) -> ::c_int; + pub fn sem_trywait(sem: *mut sem_t) -> ::c_int; + pub fn sem_post(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int; + + pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; + + pub fn sigemptyset(set: *mut sigset_t) -> ::c_int; + pub fn sigaddset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + pub fn sigfillset(set: *mut sigset_t) -> ::c_int; + pub fn sigdelset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + pub fn sigismember(set: *const sigset_t, signum: ::c_int) -> ::c_int; + + pub fn sigprocmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sigpending(set: *mut sigset_t) -> ::c_int; + + pub fn timegm(tm: *mut ::tm) -> time_t; + + pub fn getsid(pid: pid_t) -> pid_t; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn mkfifo(path: *const c_char, mode: mode_t) -> ::c_int; + + pub fn pselect( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + pub fn tcdrain(fd: ::c_int) -> ::c_int; + pub fn cfgetispeed(termios: *const ::termios) -> ::speed_t; + pub fn cfgetospeed(termios: *const ::termios) -> ::speed_t; + pub fn cfmakeraw(termios: *mut ::termios); + pub fn cfsetispeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn cfsetospeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn tcgetattr(fd: ::c_int, termios: *mut ::termios) -> ::c_int; + pub fn tcsetattr(fd: ::c_int, optional_actions: ::c_int, termios: *const ::termios) -> ::c_int; + pub fn tcflow(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcflush(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcgetsid(fd: ::c_int) -> ::pid_t; + pub fn tcsendbreak(fd: ::c_int, duration: ::c_int) -> ::c_int; + pub fn mkstemp(template: *mut ::c_char) -> ::c_int; + pub fn mkdtemp(template: *mut ::c_char) -> *mut ::c_char; + + pub fn tmpnam(ptr: *mut ::c_char) -> *mut ::c_char; + + pub fn openlog(ident: *const ::c_char, logopt: ::c_int, facility: ::c_int); + pub fn closelog(); + pub fn setlogmask(maskpri: ::c_int) -> ::c_int; + pub fn syslog(priority: ::c_int, message: *const ::c_char, ...); + + pub fn grantpt(fd: ::c_int) -> ::c_int; + pub fn posix_openpt(flags: ::c_int) -> ::c_int; + pub fn ptsname(fd: ::c_int) -> *mut ::c_char; + pub fn unlockpt(fd: ::c_int) -> ::c_int; + + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn setgroups(ngroups: ::size_t, ptr: *const ::gid_t) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + + pub fn fdopendir(fd: ::c_int) -> *mut ::DIR; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + pub fn clearenv() -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + pub fn setreuid(ruid: ::uid_t, euid: ::uid_t) -> ::c_int; + pub fn setregid(rgid: ::gid_t, egid: ::gid_t) -> ::c_int; + pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + + // System V IPC + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + pub fn semget(key: ::key_t, nsems: ::c_int, semflag: ::c_int) -> ::c_int; + pub fn semop(semid: ::c_int, sops: *mut ::sembuf, nsops: ::size_t) -> ::c_int; + pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int; + pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + pub fn msgsnd( + msqid: ::c_int, + msgp: *const ::c_void, + msgsz: ::size_t, + msgflg: ::c_int, + ) -> ::c_int; + + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t; + pub fn signalfd(fd: ::c_int, mask: *const ::sigset_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_create(clockid: ::c_int, flags: ::c_int) -> ::c_int; + pub fn timerfd_gettime(fd: ::c_int, curr_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn quotactl( + cmd: ::c_int, + special: *const ::c_char, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn reboot(how_to: ::c_int) -> ::c_int; + pub fn setfsgid(gid: ::gid_t) -> ::c_int; + pub fn setfsuid(uid: ::uid_t) -> ::c_int; + + // Not available now on Android + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + pub fn sync_file_range( + fd: ::c_int, + offset: ::off64_t, + nbytes: ::off64_t, + flags: ::c_uint, + ) -> ::c_int; + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + pub fn glob( + pattern: *const c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn futimes(fd: ::c_int, times: *const ::timeval) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn vhangup() -> ::c_int; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + pub fn sync(); + pub fn syscall(num: ::c_long, ...) -> ::c_long; + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t) + -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsize: ::size_t, + cpuset: *const cpu_set_t, + ) -> ::c_int; + pub fn umount(target: *const ::c_char) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn splice( + fd_in: ::c_int, + off_in: *mut ::loff_t, + fd_out: ::c_int, + off_out: *mut ::loff_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn swapoff(puath: *const ::c_char) -> ::c_int; + pub fn vmsplice( + fd: ::c_int, + iov: *const ::iovec, + nr_segs: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + fstype: *const ::c_char, + flags: ::c_ulong, + data: *const ::c_void, + ) -> ::c_int; + pub fn personality(persona: ::c_ulong) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn clone( + cb: extern "C" fn(*mut ::c_void) -> ::c_int, + child_stack: *mut ::c_void, + flags: ::c_int, + arg: *mut ::c_void, + ... + ) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(any(target_arch = "x86_64"))] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(any(target_arch = "riscv64"))] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/fuchsia/no_align.rs b/utshell-0.5.0/vendor/libc/src/fuchsia/no_align.rs new file mode 100644 index 00000000..7ca90e0e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fuchsia/no_align.rs @@ -0,0 +1,129 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutexattr_t { + #[cfg(target_arch = "x86_64")] + __align: [::c_int; 0], + #[cfg(not(target_arch = "x86_64"))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "arm", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "arm", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + __align: [::c_long; 0], + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_cond_t { + __align: [*const ::c_void; 0], + #[cfg(not(target_env = "musl"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_mutex_t {} + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/fuchsia/riscv64.rs b/utshell-0.5.0/vendor/libc/src/fuchsia/riscv64.rs new file mode 100644 index 00000000..de2b7197 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fuchsia/riscv64.rs @@ -0,0 +1,44 @@ +// From psABI Calling Convention for RV64 +pub type c_char = u8; +pub type __u64 = ::c_ulonglong; +pub type wchar_t = i32; + +pub type nlink_t = ::c_ulong; +pub type blksize_t = ::c_long; + +pub type stat64 = stat; +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + // Not actually used, IPC calls just return ENOSYS + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/fuchsia/x86_64.rs b/utshell-0.5.0/vendor/libc/src/fuchsia/x86_64.rs new file mode 100644 index 00000000..dca3c247 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/fuchsia/x86_64.rs @@ -0,0 +1,152 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = ::c_long; +pub type __u64 = ::c_ulonglong; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 3], + } + + pub struct mcontext_t { + __private: [u64; 32], + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } +} + +s_no_extra_traits! { + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // FIXME: .field("__private", &self.__private) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +pub const MAP_32BIT: ::c_int = 0x0040; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; diff --git a/utshell-0.5.0/vendor/libc/src/hermit/aarch64.rs b/utshell-0.5.0/vendor/libc/src/hermit/aarch64.rs new file mode 100644 index 00000000..1a92e3b4 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/hermit/aarch64.rs @@ -0,0 +1,2 @@ +pub type c_char = u8; +pub type wchar_t = u32; diff --git a/utshell-0.5.0/vendor/libc/src/hermit/mod.rs b/utshell-0.5.0/vendor/libc/src/hermit/mod.rs new file mode 100644 index 00000000..7543c825 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/hermit/mod.rs @@ -0,0 +1,61 @@ +//! Hermit C types definition + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type c_long = i64; +pub type c_ulong = u64; + +pub type wint_t = u32; +pub type wctype_t = i64; + +pub type regoff_t = size_t; +pub type off_t = c_long; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/hermit/x86_64.rs b/utshell-0.5.0/vendor/libc/src/hermit/x86_64.rs new file mode 100644 index 00000000..76ec3ce8 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/hermit/x86_64.rs @@ -0,0 +1,2 @@ +pub type c_char = i8; +pub type wchar_t = i32; diff --git a/utshell-0.5.0/vendor/libc/src/lib.rs b/utshell-0.5.0/vendor/libc/src/lib.rs new file mode 100644 index 00000000..1b6f0c07 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/lib.rs @@ -0,0 +1,165 @@ +//! libc - Raw FFI bindings to platforms' system libraries +#![crate_name = "libc"] +#![crate_type = "rlib"] +#![allow( + renamed_and_removed_lints, // Keep this order. + unknown_lints, // Keep this order. + bad_style, + overflowing_literals, + improper_ctypes, + // This lint is renamed but we run CI for old stable rustc so should be here. + redundant_semicolon, + redundant_semicolons, + unused_macros, + unused_macro_rules, +)] +#![cfg_attr(libc_deny_warnings, deny(warnings))] +// Attributes needed when building as part of the standard library +#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg, no_core))] +#![cfg_attr(libc_thread_local, feature(thread_local))] +// Enable extra lints: +#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))] +#![deny(missing_copy_implementations, safe_packed_borrows)] +#![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)] +#![cfg_attr(feature = "rustc-dep-of-std", no_core)] +#![cfg_attr(libc_const_extern_fn_unstable, feature(const_extern_fn))] + +#[macro_use] +mod macros; + +cfg_if! { + if #[cfg(feature = "rustc-dep-of-std")] { + extern crate rustc_std_workspace_core as core; + #[allow(unused_imports)] + use core::iter; + #[allow(unused_imports)] + use core::ops; + #[allow(unused_imports)] + use core::option; + } +} + +cfg_if! { + if #[cfg(libc_priv_mod_use)] { + #[cfg(libc_core_cvoid)] + #[allow(unused_imports)] + use core::ffi; + #[allow(unused_imports)] + use core::fmt; + #[allow(unused_imports)] + use core::hash; + #[allow(unused_imports)] + use core::num; + #[allow(unused_imports)] + use core::mem; + #[doc(hidden)] + #[allow(unused_imports)] + use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] + use core::marker::{Copy, Send, Sync}; + #[doc(hidden)] + #[allow(unused_imports)] + use core::option::Option; + } else { + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::fmt; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::hash; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::num; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::mem; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::marker::{Copy, Send, Sync}; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::option::Option; + } +} + +cfg_if! { + if #[cfg(windows)] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod windows; + pub use windows::*; + } else if #[cfg(target_os = "fuchsia")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod fuchsia; + pub use fuchsia::*; + } else if #[cfg(target_os = "switch")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod switch; + pub use switch::*; + } else if #[cfg(target_os = "psp")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod psp; + pub use psp::*; + } else if #[cfg(target_os = "vxworks")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod vxworks; + pub use vxworks::*; + } else if #[cfg(target_os = "solid_asp3")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod solid; + pub use solid::*; + } else if #[cfg(unix)] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod unix; + pub use unix::*; + } else if #[cfg(target_os = "hermit")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod hermit; + pub use hermit::*; + } else if #[cfg(target_os = "teeos")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod teeos; + pub use teeos::*; + } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod sgx; + pub use sgx::*; + } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod wasi; + pub use wasi::*; + } else if #[cfg(target_os = "xous")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod xous; + pub use xous::*; + } else { + // non-supported targets: empty... + } +} diff --git a/utshell-0.5.0/vendor/libc/src/macros.rs b/utshell-0.5.0/vendor/libc/src/macros.rs new file mode 100644 index 00000000..beb80024 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/macros.rs @@ -0,0 +1,349 @@ +/// A macro for defining #[cfg] if-else statements. +/// +/// This is similar to the `if/elif` C preprocessor macro by allowing definition +/// of a cascade of `#[cfg]` cases, emitting the implementation which matches +/// first. +/// +/// This allows you to conveniently provide a long list #[cfg]'d blocks of code +/// without having to rewrite each clause multiple times. +macro_rules! cfg_if { + // match if/else chains with a final `else` + ($( + if #[cfg($($meta:meta),*)] { $($it:item)* } + ) else * else { + $($it2:item)* + }) => { + cfg_if! { + @__items + () ; + $( ( ($($meta),*) ($($it)*) ), )* + ( () ($($it2)*) ), + } + }; + + // match if/else chains lacking a final `else` + ( + if #[cfg($($i_met:meta),*)] { $($i_it:item)* } + $( + else if #[cfg($($e_met:meta),*)] { $($e_it:item)* } + )* + ) => { + cfg_if! { + @__items + () ; + ( ($($i_met),*) ($($i_it)*) ), + $( ( ($($e_met),*) ($($e_it)*) ), )* + ( () () ), + } + }; + + // Internal and recursive macro to emit all the items + // + // Collects all the negated `cfg`s in a list at the beginning and after the + // semicolon is all the remaining items + (@__items ($($not:meta,)*) ; ) => {}; + (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), + $($rest:tt)*) => { + // Emit all items within one block, applying an appropriate #[cfg]. The + // #[cfg] will require all `$m` matchers specified and must also negate + // all previous matchers. + cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* } + + // Recurse to emit all other items in `$rest`, and when we do so add all + // our `$m` matchers to the list of `$not` matchers as future emissions + // will have to negate everything we just matched as well. + cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } + }; + + // Internal macro to Apply a cfg attribute to a list of items + (@__apply $m:meta, $($it:item)*) => { + $(#[$m] $it)* + }; +} + +macro_rules! s { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s!(it: $(#[$attr])* pub $t $i { $($field)* }); + )*); + (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( + compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead"); + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] + #[allow(deprecated)] + $(#[$attr])* + pub struct $i { $($field)* } + } + #[allow(deprecated)] + impl ::Copy for $i {} + #[allow(deprecated)] + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + ); +} + +macro_rules! s_no_extra_traits { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* }); + )*); + (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( + cfg_if! { + if #[cfg(libc_union)] { + __item! { + #[repr(C)] + $(#[$attr])* + pub union $i { $($field)* } + } + + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + } + } + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + $(#[$attr])* + pub struct $i { $($field)* } + } + #[allow(deprecated)] + impl ::Copy for $i {} + #[allow(deprecated)] + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + ); +} + +macro_rules! missing { + ($($(#[$attr:meta])* pub enum $i:ident {})*) => ($( + $(#[$attr])* #[allow(missing_copy_implementations)] pub enum $i { } + )*); +} + +macro_rules! e { + ($($(#[$attr:meta])* pub enum $i:ident { $($field:tt)* })*) => ($( + __item! { + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] + $(#[$attr])* + pub enum $i { $($field)* } + } + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + )*); +} + +macro_rules! s_paren { + ($($(#[$attr:meta])* pub struct $i:ident ( $($field:tt)* ); )* ) => ($( + __item! { + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] + $(#[$attr])* + pub struct $i ( $($field)* ); + } + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + )*); +} + +// This is a pretty horrible hack to allow us to conditionally mark +// some functions as 'const', without requiring users of this macro +// to care about the "const-extern-fn" feature. +// +// When 'const-extern-fn' is enabled, we emit the captured 'const' keyword +// in the expanded function. +// +// When 'const-extern-fn' is disabled, we always emit a plain 'pub unsafe extern fn'. +// Note that the expression matched by the macro is exactly the same - this allows +// users of this macro to work whether or not 'const-extern-fn' is enabled +// +// Unfortunately, we need to duplicate most of this macro between the 'cfg_if' blocks. +// This is because 'const unsafe extern fn' won't even parse on older compilers, +// so we need to avoid emitting it at all of 'const-extern-fn'. +// +// Specifically, moving the 'cfg_if' into the macro body will *not* work. +// Doing so would cause the '#[cfg(feature = "const-extern-fn")]' to be emitted +// into user code. The 'cfg' gate will not stop Rust from trying to parse the +// 'pub const unsafe extern fn', so users would get a compiler error even when +// the 'const-extern-fn' feature is disabled +// +// Note that users of this macro need to place 'const' in a weird position +// (after the closing ')' for the arguments, but before the return type). +// This was the only way I could satisfy the following two requirements: +// 1. Avoid ambiguity errors from 'macro_rules!' (which happen when writing '$foo:ident fn' +// 2. Allow users of this macro to mix 'pub fn foo' and 'pub const fn bar' within the same +// 'f!' block +cfg_if! { + if #[cfg(libc_const_extern_fn)] { + macro_rules! f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub $($constness)* unsafe extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! safe_f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub $($constness)* extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! const_fn { + ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + $($constness)* fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + } else { + macro_rules! f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub unsafe extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! safe_f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! const_fn { + ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + } +} + +macro_rules! __item { + ($i:item) => { + $i + }; +} + +macro_rules! align_const { + ($($(#[$attr:meta])* + pub const $name:ident : $t1:ty + = $t2:ident { $($field:tt)* };)*) => ($( + #[cfg(libc_align)] + $(#[$attr])* + pub const $name : $t1 = $t2 { + $($field)* + }; + #[cfg(not(libc_align))] + $(#[$attr])* + pub const $name : $t1 = $t2 { + $($field)* + __align: [], + }; + )*) +} + +// This macro is used to deprecate items that should be accessed via the mach2 crate +macro_rules! deprecated_mach { + (pub const $id:ident: $ty:ty = $expr:expr;) => { + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + #[allow(deprecated)] + pub const $id: $ty = $expr; + }; + ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => { + $( + deprecated_mach!( + pub const $id: $ty = $expr; + ); + )* + }; + (pub type $id:ident = $ty:ty;) => { + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + #[allow(deprecated)] + pub type $id = $ty; + }; + ($(pub type $id:ident = $ty:ty;)*) => { + $( + deprecated_mach!( + pub type $id = $ty; + ); + )* + } +} + +#[cfg(not(libc_ptr_addr_of))] +macro_rules! ptr_addr_of { + ($place:expr) => { + &$place + }; +} + +#[cfg(libc_ptr_addr_of)] +macro_rules! ptr_addr_of { + ($place:expr) => { + ::core::ptr::addr_of!($place) + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/psp.rs b/utshell-0.5.0/vendor/libc/src/psp.rs new file mode 100644 index 00000000..a4ca029b --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/psp.rs @@ -0,0 +1,4177 @@ +//! PSP C type definitions +//! +//! These type declarations are not enough, as they must be ultimately resolved +//! by the linker. Crates that use these definitions must, somewhere in the +//! crate graph, include a stub provider crate such as the `psp` crate. + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} + +pub type SceKernelVTimerHandler = unsafe extern "C" fn( + uid: SceUid, + arg1: *mut SceKernelSysClock, + arg2: *mut SceKernelSysClock, + arg3: *mut c_void, +) -> u32; + +pub type SceKernelVTimerHandlerWide = + unsafe extern "C" fn(uid: SceUid, arg1: i64, arg2: i64, arg3: *mut c_void) -> u32; + +pub type SceKernelThreadEventHandler = + unsafe extern "C" fn(mask: i32, thid: SceUid, common: *mut c_void) -> i32; + +pub type SceKernelAlarmHandler = unsafe extern "C" fn(common: *mut c_void) -> u32; + +pub type SceKernelCallbackFunction = + unsafe extern "C" fn(arg1: i32, arg2: i32, arg: *mut c_void) -> i32; + +pub type SceKernelThreadEntry = unsafe extern "C" fn(args: usize, argp: *mut c_void) -> i32; + +pub type PowerCallback = extern "C" fn(unknown: i32, power_info: i32); + +pub type IoPermissions = i32; + +pub type UmdCallback = fn(unknown: i32, event: i32) -> i32; + +pub type SceMpegRingbufferCb = + ::Option i32>; + +pub type GuCallback = ::Option; +pub type GuSwapBuffersCallback = + ::Option; + +pub type SceNetAdhocctlHandler = + ::Option; + +pub type AdhocMatchingCallback = ::Option< + unsafe extern "C" fn( + matching_id: i32, + event: i32, + mac: *mut u8, + opt_len: i32, + opt_data: *mut c_void, + ), +>; + +pub type SceNetApctlHandler = ::Option< + unsafe extern "C" fn(oldState: i32, newState: i32, event: i32, error: i32, pArg: *mut c_void), +>; + +pub type HttpMallocFunction = ::Option *mut c_void>; +pub type HttpReallocFunction = + ::Option *mut c_void>; +pub type HttpFreeFunction = ::Option; +pub type HttpPasswordCB = ::Option< + unsafe extern "C" fn( + request: i32, + auth_type: HttpAuthType, + realm: *const u8, + username: *mut u8, + password: *mut u8, + need_entity: i32, + entity_body: *mut *mut u8, + entity_size: *mut usize, + save: *mut i32, + ) -> i32, +>; + +pub type socklen_t = u32; + +e! { + #[repr(u32)] + pub enum AudioFormat { + Stereo = 0, + Mono = 0x10, + } + + #[repr(u32)] + pub enum DisplayMode { + Lcd = 0, + } + + #[repr(u32)] + pub enum DisplayPixelFormat { + Psm5650 = 0, + Psm5551 = 1, + Psm4444 = 2, + Psm8888 = 3, + } + + #[repr(u32)] + pub enum DisplaySetBufSync { + Immediate = 0, + NextFrame = 1, + } + + #[repr(i32)] + pub enum AudioOutputFrequency { + Khz48 = 48000, + Khz44_1 = 44100, + Khz32 = 32000, + Khz24 = 24000, + Khz22_05 = 22050, + Khz16 = 16000, + Khz12 = 12000, + Khz11_025 = 11025, + Khz8 = 8000, + } + + #[repr(i32)] + pub enum AudioInputFrequency { + Khz44_1 = 44100, + Khz22_05 = 22050, + Khz11_025 = 11025, + } + + #[repr(u32)] + pub enum CtrlMode { + Digital = 0, + Analog, + } + + #[repr(i32)] + pub enum GeMatrixType { + Bone0 = 0, + Bone1, + Bone2, + Bone3, + Bone4, + Bone5, + Bone6, + Bone7, + World, + View, + Projection, + TexGen, + } + + #[repr(i32)] + pub enum GeListState { + Done = 0, + Queued, + DrawingDone, + StallReached, + CancelDone, + } + + #[repr(u8)] + pub enum GeCommand { + Nop = 0, + Vaddr = 0x1, + Iaddr = 0x2, + Prim = 0x4, + Bezier = 0x5, + Spline = 0x6, + BoundingBox = 0x7, + Jump = 0x8, + BJump = 0x9, + Call = 0xa, + Ret = 0xb, + End = 0xc, + Signal = 0xe, + Finish = 0xf, + Base = 0x10, + VertexType = 0x12, + OffsetAddr = 0x13, + Origin = 0x14, + Region1 = 0x15, + Region2 = 0x16, + LightingEnable = 0x17, + LightEnable0 = 0x18, + LightEnable1 = 0x19, + LightEnable2 = 0x1a, + LightEnable3 = 0x1b, + DepthClampEnable = 0x1c, + CullFaceEnable = 0x1d, + TextureMapEnable = 0x1e, + FogEnable = 0x1f, + DitherEnable = 0x20, + AlphaBlendEnable = 0x21, + AlphaTestEnable = 0x22, + ZTestEnable = 0x23, + StencilTestEnable = 0x24, + AntiAliasEnable = 0x25, + PatchCullEnable = 0x26, + ColorTestEnable = 0x27, + LogicOpEnable = 0x28, + BoneMatrixNumber = 0x2a, + BoneMatrixData = 0x2b, + MorphWeight0 = 0x2c, + MorphWeight1 = 0x2d, + MorphWeight2 = 0x2e, + MorphWeight3 = 0x2f, + MorphWeight4 = 0x30, + MorphWeight5 = 0x31, + MorphWeight6 = 0x32, + MorphWeight7 = 0x33, + PatchDivision = 0x36, + PatchPrimitive = 0x37, + PatchFacing = 0x38, + WorldMatrixNumber = 0x3a, + WorldMatrixData = 0x3b, + ViewMatrixNumber = 0x3c, + ViewMatrixData = 0x3d, + ProjMatrixNumber = 0x3e, + ProjMatrixData = 0x3f, + TGenMatrixNumber = 0x40, + TGenMatrixData = 0x41, + ViewportXScale = 0x42, + ViewportYScale = 0x43, + ViewportZScale = 0x44, + ViewportXCenter = 0x45, + ViewportYCenter = 0x46, + ViewportZCenter = 0x47, + TexScaleU = 0x48, + TexScaleV = 0x49, + TexOffsetU = 0x4a, + TexOffsetV = 0x4b, + OffsetX = 0x4c, + OffsetY = 0x4d, + ShadeMode = 0x50, + ReverseNormal = 0x51, + MaterialUpdate = 0x53, + MaterialEmissive = 0x54, + MaterialAmbient = 0x55, + MaterialDiffuse = 0x56, + MaterialSpecular = 0x57, + MaterialAlpha = 0x58, + MaterialSpecularCoef = 0x5b, + AmbientColor = 0x5c, + AmbientAlpha = 0x5d, + LightMode = 0x5e, + LightType0 = 0x5f, + LightType1 = 0x60, + LightType2 = 0x61, + LightType3 = 0x62, + Light0X = 0x63, + Light0Y, + Light0Z, + Light1X, + Light1Y, + Light1Z, + Light2X, + Light2Y, + Light2Z, + Light3X, + Light3Y, + Light3Z, + Light0DirectionX = 0x6f, + Light0DirectionY, + Light0DirectionZ, + Light1DirectionX, + Light1DirectionY, + Light1DirectionZ, + Light2DirectionX, + Light2DirectionY, + Light2DirectionZ, + Light3DirectionX, + Light3DirectionY, + Light3DirectionZ, + Light0ConstantAtten = 0x7b, + Light0LinearAtten, + Light0QuadtraticAtten, + Light1ConstantAtten, + Light1LinearAtten, + Light1QuadtraticAtten, + Light2ConstantAtten, + Light2LinearAtten, + Light2QuadtraticAtten, + Light3ConstantAtten, + Light3LinearAtten, + Light3QuadtraticAtten, + Light0ExponentAtten = 0x87, + Light1ExponentAtten, + Light2ExponentAtten, + Light3ExponentAtten, + Light0CutoffAtten = 0x8b, + Light1CutoffAtten, + Light2CutoffAtten, + Light3CutoffAtten, + Light0Ambient = 0x8f, + Light0Diffuse, + Light0Specular, + Light1Ambient, + Light1Diffuse, + Light1Specular, + Light2Ambient, + Light2Diffuse, + Light2Specular, + Light3Ambient, + Light3Diffuse, + Light3Specular, + Cull = 0x9b, + FrameBufPtr = 0x9c, + FrameBufWidth = 0x9d, + ZBufPtr = 0x9e, + ZBufWidth = 0x9f, + TexAddr0 = 0xa0, + TexAddr1, + TexAddr2, + TexAddr3, + TexAddr4, + TexAddr5, + TexAddr6, + TexAddr7, + TexBufWidth0 = 0xa8, + TexBufWidth1, + TexBufWidth2, + TexBufWidth3, + TexBufWidth4, + TexBufWidth5, + TexBufWidth6, + TexBufWidth7, + ClutAddr = 0xb0, + ClutAddrUpper = 0xb1, + TransferSrc, + TransferSrcW, + TransferDst, + TransferDstW, + TexSize0 = 0xb8, + TexSize1, + TexSize2, + TexSize3, + TexSize4, + TexSize5, + TexSize6, + TexSize7, + TexMapMode = 0xc0, + TexShadeLs = 0xc1, + TexMode = 0xc2, + TexFormat = 0xc3, + LoadClut = 0xc4, + ClutFormat = 0xc5, + TexFilter = 0xc6, + TexWrap = 0xc7, + TexLevel = 0xc8, + TexFunc = 0xc9, + TexEnvColor = 0xca, + TexFlush = 0xcb, + TexSync = 0xcc, + Fog1 = 0xcd, + Fog2 = 0xce, + FogColor = 0xcf, + TexLodSlope = 0xd0, + FramebufPixFormat = 0xd2, + ClearMode = 0xd3, + Scissor1 = 0xd4, + Scissor2 = 0xd5, + MinZ = 0xd6, + MaxZ = 0xd7, + ColorTest = 0xd8, + ColorRef = 0xd9, + ColorTestmask = 0xda, + AlphaTest = 0xdb, + StencilTest = 0xdc, + StencilOp = 0xdd, + ZTest = 0xde, + BlendMode = 0xdf, + BlendFixedA = 0xe0, + BlendFixedB = 0xe1, + Dith0 = 0xe2, + Dith1, + Dith2, + Dith3, + LogicOp = 0xe6, + ZWriteDisable = 0xe7, + MaskRgb = 0xe8, + MaskAlpha = 0xe9, + TransferStart = 0xea, + TransferSrcPos = 0xeb, + TransferDstPos = 0xec, + TransferSize = 0xee, + Vscx = 0xf0, + Vscy = 0xf1, + Vscz = 0xf2, + Vtcs = 0xf3, + Vtct = 0xf4, + Vtcq = 0xf5, + Vcv = 0xf6, + Vap = 0xf7, + Vfc = 0xf8, + Vscv = 0xf9, + + Unknown03 = 0x03, + Unknown0D = 0x0d, + Unknown11 = 0x11, + Unknown29 = 0x29, + Unknown34 = 0x34, + Unknown35 = 0x35, + Unknown39 = 0x39, + Unknown4E = 0x4e, + Unknown4F = 0x4f, + Unknown52 = 0x52, + Unknown59 = 0x59, + Unknown5A = 0x5a, + UnknownB6 = 0xb6, + UnknownB7 = 0xb7, + UnknownD1 = 0xd1, + UnknownED = 0xed, + UnknownEF = 0xef, + UnknownFA = 0xfa, + UnknownFB = 0xfb, + UnknownFC = 0xfc, + UnknownFD = 0xfd, + UnknownFE = 0xfe, + NopFF = 0xff, + } + + #[repr(i32)] + pub enum SceSysMemPartitionId { + SceKernelUnknownPartition = 0, + SceKernelPrimaryKernelPartition = 1, + SceKernelPrimaryUserPartition = 2, + SceKernelOtherKernelPartition1 = 3, + SceKernelOtherKernelPartition2 = 4, + SceKernelVshellPARTITION = 5, + SceKernelScUserPartition = 6, + SceKernelMeUserPartition = 7, + SceKernelExtendedScKernelPartition = 8, + SceKernelExtendedSc2KernelPartition = 9, + SceKernelExtendedMeKernelPartition = 10, + SceKernelVshellKernelPartition = 11, + SceKernelExtendedKernelPartition = 12, + } + + #[repr(i32)] + pub enum SceSysMemBlockTypes { + Low = 0, + High, + Addr, + } + + #[repr(u32)] + pub enum Interrupt { + Gpio = 4, + Ata = 5, + Umd = 6, + Mscm0 = 7, + Wlan = 8, + Audio = 10, + I2c = 12, + Sircs = 14, + Systimer0 = 15, + Systimer1 = 16, + Systimer2 = 17, + Systimer3 = 18, + Thread0 = 19, + Nand = 20, + Dmacplus = 21, + Dma0 = 22, + Dma1 = 23, + Memlmd = 24, + Ge = 25, + Vblank = 30, + Mecodec = 31, + Hpremote = 36, + Mscm1 = 60, + Mscm2 = 61, + Thread1 = 65, + Interrupt = 66, + } + + #[repr(u32)] + pub enum SubInterrupt { + Gpio = Interrupt::Gpio as u32, + Ata = Interrupt::Ata as u32, + Umd = Interrupt::Umd as u32, + Dmacplus = Interrupt::Dmacplus as u32, + Ge = Interrupt::Ge as u32, + Display = Interrupt::Vblank as u32, + } + + #[repr(u32)] + pub enum SceKernelIdListType { + Thread = 1, + Semaphore = 2, + EventFlag = 3, + Mbox = 4, + Vpl = 5, + Fpl = 6, + Mpipe = 7, + Callback = 8, + ThreadEventHandler = 9, + Alarm = 10, + VTimer = 11, + SleepThread = 64, + DelayThread = 65, + SuspendThread = 66, + DormantThread = 67, + } + + #[repr(i32)] + pub enum UsbCamResolution { + Px160_120 = 0, + Px176_144 = 1, + Px320_240 = 2, + Px352_288 = 3, + Px640_480 = 4, + Px1024_768 = 5, + Px1280_960 = 6, + Px480_272 = 7, + Px360_272 = 8, + } + + #[repr(i32)] + pub enum UsbCamResolutionEx { + Px160_120 = 0, + Px176_144 = 1, + Px320_240 = 2, + Px352_288 = 3, + Px360_272 = 4, + Px480_272 = 5, + Px640_480 = 6, + Px1024_768 = 7, + Px1280_960 = 8, + } + + #[repr(i32)] + pub enum UsbCamDelay { + NoDelay = 0, + Delay10Sec = 1, + Delay20Sec = 2, + Delay30Sec = 3, + } + + #[repr(i32)] + pub enum UsbCamFrameRate { + Fps3_75 = 0, + Fps5 = 1, + Fps7_5 = 2, + Fps10 = 3, + Fps15 = 4, + Fps20 = 5, + Fps30 = 6, + Fps60 = 7, + } + + #[repr(i32)] + pub enum UsbCamWb { + Auto = 0, + Daylight = 1, + Fluorescent = 2, + Incadescent = 3, + } + + #[repr(i32)] + pub enum UsbCamEffectMode { + Normal = 0, + Negative = 1, + Blackwhite = 2, + Sepia = 3, + Blue = 4, + Red = 5, + Green = 6, + } + + #[repr(i32)] + pub enum UsbCamEvLevel { + Pos2_0 = 0, + Pos1_7 = 1, + Pos1_5 = 2, + Pos1_3 = 3, + Pos1_0 = 4, + Pos0_7 = 5, + Pos0_5 = 6, + Pos0_3 = 7, + Zero = 8, + Neg0_3, + Neg0_5, + Neg0_7, + Neg1_0, + Neg1_3, + Neg1_5, + Neg1_7, + Neg2_0, + } + + #[repr(i32)] + pub enum RtcCheckValidError { + InvalidYear = -1, + InvalidMonth = -2, + InvalidDay = -3, + InvalidHour = -4, + InvalidMinutes = -5, + InvalidSeconds = -6, + InvalidMicroseconds = -7, + } + + #[repr(u32)] + pub enum PowerTick { + All = 0, + Suspend = 1, + Display = 6, + } + + #[repr(u32)] + pub enum IoAssignPerms { + RdWr = 0, + RdOnly = 1, + } + + #[repr(u32)] + pub enum IoWhence { + Set = 0, + Cur = 1, + End = 2, + } + + #[repr(u32)] + pub enum UmdType { + Game = 0x10, + Video = 0x20, + Audio = 0x40, + } + + #[repr(u32)] + pub enum GuPrimitive { + Points = 0, + Lines = 1, + LineStrip = 2, + Triangles = 3, + TriangleStrip = 4, + TriangleFan = 5, + Sprites = 6, + } + + #[repr(u32)] + pub enum PatchPrimitive { + Points = 0, + LineStrip = 2, + TriangleStrip = 4, + } + + #[repr(u32)] + pub enum GuState { + AlphaTest = 0, + DepthTest = 1, + ScissorTest = 2, + StencilTest = 3, + Blend = 4, + CullFace = 5, + Dither = 6, + Fog = 7, + ClipPlanes = 8, + Texture2D = 9, + Lighting = 10, + Light0 = 11, + Light1 = 12, + Light2 = 13, + Light3 = 14, + LineSmooth = 15, + PatchCullFace = 16, + ColorTest = 17, + ColorLogicOp = 18, + FaceNormalReverse = 19, + PatchFace = 20, + Fragment2X = 21, + } + + #[repr(u32)] + pub enum MatrixMode { + Projection = 0, + View = 1, + Model = 2, + Texture = 3, + } + + #[repr(u32)] + pub enum TexturePixelFormat { + Psm5650 = 0, + Psm5551 = 1, + Psm4444 = 2, + Psm8888 = 3, + PsmT4 = 4, + PsmT8 = 5, + PsmT16 = 6, + PsmT32 = 7, + PsmDxt1 = 8, + PsmDxt3 = 9, + PsmDxt5 = 10, + } + + #[repr(u32)] + pub enum SplineMode { + FillFill = 0, + OpenFill = 1, + FillOpen = 2, + OpenOpen = 3, + } + + #[repr(u32)] + pub enum ShadingModel { + Flat = 0, + Smooth = 1, + } + + #[repr(u32)] + pub enum LogicalOperation { + Clear = 0, + And = 1, + AndReverse = 2, + Copy = 3, + AndInverted = 4, + Noop = 5, + Xor = 6, + Or = 7, + Nor = 8, + Equiv = 9, + Inverted = 10, + OrReverse = 11, + CopyInverted = 12, + OrInverted = 13, + Nand = 14, + Set = 15, + } + + #[repr(u32)] + pub enum TextureFilter { + Nearest = 0, + Linear = 1, + NearestMipmapNearest = 4, + LinearMipmapNearest = 5, + NearestMipmapLinear = 6, + LinearMipmapLinear = 7, + } + + #[repr(u32)] + pub enum TextureMapMode { + TextureCoords = 0, + TextureMatrix = 1, + EnvironmentMap = 2, + } + + #[repr(u32)] + pub enum TextureLevelMode { + Auto = 0, + Const = 1, + Slope = 2, + } + + #[repr(u32)] + pub enum TextureProjectionMapMode { + Position = 0, + Uv = 1, + NormalizedNormal = 2, + Normal = 3, + } + + #[repr(u32)] + pub enum GuTexWrapMode { + Repeat = 0, + Clamp = 1, + } + + #[repr(u32)] + pub enum FrontFaceDirection { + Clockwise = 0, + CounterClockwise = 1, + } + + #[repr(u32)] + pub enum AlphaFunc { + Never = 0, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, + } + + #[repr(u32)] + pub enum StencilFunc { + Never = 0, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, + } + + #[repr(u32)] + pub enum ColorFunc { + Never = 0, + Always, + Equal, + NotEqual, + } + + #[repr(u32)] + pub enum DepthFunc { + Never = 0, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, + } + + #[repr(u32)] + pub enum TextureEffect { + Modulate = 0, + Decal = 1, + Blend = 2, + Replace = 3, + Add = 4, + } + + #[repr(u32)] + pub enum TextureColorComponent { + Rgb = 0, + Rgba = 1, + } + + #[repr(u32)] + pub enum MipmapLevel { + None = 0, + Level1, + Level2, + Level3, + Level4, + Level5, + Level6, + Level7, + } + + #[repr(u32)] + pub enum BlendOp { + Add = 0, + Subtract = 1, + ReverseSubtract = 2, + Min = 3, + Max = 4, + Abs = 5, + } + + #[repr(u32)] + pub enum BlendSrc { + SrcColor = 0, + OneMinusSrcColor = 1, + SrcAlpha = 2, + OneMinusSrcAlpha = 3, + Fix = 10, + } + + #[repr(u32)] + pub enum BlendDst { + DstColor = 0, + OneMinusDstColor = 1, + DstAlpha = 4, + OneMinusDstAlpha = 5, + Fix = 10, + } + + #[repr(u32)] + pub enum StencilOperation { + Keep = 0, + Zero = 1, + Replace = 2, + Invert = 3, + Incr = 4, + Decr = 5, + } + + #[repr(u32)] + pub enum LightMode { + SingleColor = 0, + SeparateSpecularColor = 1, + } + + #[repr(u32)] + pub enum LightType { + Directional = 0, + Pointlight = 1, + Spotlight = 2, + } + + #[repr(u32)] + pub enum GuContextType { + Direct = 0, + Call = 1, + Send = 2, + } + + #[repr(u32)] + pub enum GuQueueMode { + Tail = 0, + Head = 1, + } + + #[repr(u32)] + pub enum GuSyncMode { + Finish = 0, + Signal = 1, + Done = 2, + List = 3, + Send = 4, + } + + #[repr(u32)] + pub enum GuSyncBehavior { + Wait = 0, + NoWait = 1, + } + + #[repr(u32)] + pub enum GuCallbackId { + Signal = 1, + Finish = 4, + } + + #[repr(u32)] + pub enum SignalBehavior { + Suspend = 1, + Continue = 2, + } + + #[repr(u32)] + pub enum ClutPixelFormat { + Psm5650 = 0, + Psm5551 = 1, + Psm4444 = 2, + Psm8888 = 3, + } + + #[repr(C)] + pub enum KeyType { + Directory = 1, + Integer = 2, + String = 3, + Bytes = 4, + } + + #[repr(u32)] + pub enum UtilityMsgDialogMode { + Error, + Text, + } + + #[repr(u32)] + pub enum UtilityMsgDialogPressed { + Unknown1, + Yes, + No, + Back, + } + + #[repr(u32)] + pub enum UtilityDialogButtonAccept { + Circle, + Cross, + } + + #[repr(u32)] + pub enum SceUtilityOskInputLanguage { + Default, + Japanese, + English, + French, + Spanish, + German, + Italian, + Dutch, + Portugese, + Russian, + Korean, + } + + #[repr(u32)] + pub enum SceUtilityOskInputType { + All, + LatinDigit, + LatinSymbol, + LatinLowercase = 4, + LatinUppercase = 8, + JapaneseDigit = 0x100, + JapaneseSymbol = 0x200, + JapaneseLowercase = 0x400, + JapaneseUppercase = 0x800, + JapaneseHiragana = 0x1000, + JapaneseHalfWidthKatakana = 0x2000, + JapaneseKatakana = 0x4000, + JapaneseKanji = 0x8000, + RussianLowercase = 0x10000, + RussianUppercase = 0x20000, + Korean = 0x40000, + Url = 0x80000, + } + + #[repr(u32)] + pub enum SceUtilityOskState { + None, + Initializing, + Initialized, + Visible, + Quit, + Finished, + } + + #[repr(u32)] + pub enum SceUtilityOskResult { + Unchanged, + Cancelled, + Changed, + } + + #[repr(u32)] + pub enum SystemParamLanguage { + Japanese, + English, + French, + Spanish, + German, + Italian, + Dutch, + Portugese, + Russian, + Korean, + ChineseTraditional, + ChineseSimplified, + } + + #[repr(u32)] + pub enum SystemParamId { + StringNickname = 1, + AdhocChannel, + WlanPowerSave, + DateFormat, + TimeFormat, + Timezone, + DaylightSavings, + Language, + Unknown, + } + + #[repr(u32)] + pub enum SystemParamAdhocChannel { + ChannelAutomatic = 0, + Channel1 = 1, + Channel6 = 6, + Channel11 = 11, + } + + #[repr(u32)] + pub enum SystemParamWlanPowerSaveState { + Off, + On, + } + + #[repr(u32)] + pub enum SystemParamDateFormat { + YYYYMMDD, + MMDDYYYY, + DDMMYYYY, + } + + #[repr(u32)] + pub enum SystemParamTimeFormat { + Hour24, + Hour12, + } + + #[repr(u32)] + pub enum SystemParamDaylightSavings { + Std, + Dst, + } + + #[repr(u32)] + pub enum AvModule { + AvCodec, + SasCore, + Atrac3Plus, + MpegBase, + Mp3, + Vaudio, + Aac, + G729, + } + + #[repr(u32)] + pub enum Module { + NetCommon = 0x100, + NetAdhoc, + NetInet, + NetParseUri, + NetHttp, + NetSsl, + + UsbPspCm = 0x200, + UsbMic, + UsbCam, + UsbGps, + + AvCodec = 0x300, + AvSascore, + AvAtrac3Plus, + AvMpegBase, + AvMp3, + AvVaudio, + AvAac, + AvG729, + + NpCommon = 0x400, + NpService, + NpMatching2, + NpDrm = 0x500, + + Irda = 0x600, + } + + #[repr(u32)] + pub enum NetModule { + NetCommon = 1, + NetAdhoc, + NetInet, + NetParseUri, + NetHttp, + NetSsl, + } + + #[repr(u32)] + pub enum UsbModule { + UsbPspCm = 1, + UsbAcc, + UsbMic, + UsbCam, + UsbGps, + } + + #[repr(u32)] + pub enum NetParam { + Name, + Ssid, + Secure, + WepKey, + IsStaticIp, + Ip, + NetMask, + Route, + ManualDns, + PrimaryDns, + SecondaryDns, + ProxyUser, + ProxyPass, + UseProxy, + ProxyServer, + ProxyPort, + Unknown1, + Unknown2, + } + + #[repr(u32)] + pub enum UtilityNetconfAction { + ConnectAP, + DisplayStatus, + ConnectAdhoc, + } + + #[repr(u32)] + pub enum UtilitySavedataMode { + AutoLoad, + AutoSave, + Load, + Save, + ListLoad, + ListSave, + ListDelete, + Delete, + } + + #[repr(u32)] + pub enum UtilitySavedataFocus { + Unknown1, + FirstList, + LastList, + Latest, + Oldest, + Unknown2, + Unknown3, + FirstEmpty, + LastEmpty, + } + + #[repr(u32)] + pub enum UtilityGameSharingMode { + Single = 1, + Multiple, + } + + #[repr(u32)] + pub enum UtilityGameSharingDataType { + File = 1, + Memory, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerInterfaceMode { + Full, + Limited, + None, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerCookieMode { + Disabled = 0, + Enabled, + Confirm, + Default, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerTextSize { + Large, + Normal, + Small, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerDisplayMode { + Normal, + Fit, + SmartFit, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerConnectMode { + Last, + ManualOnce, + ManualAll, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerDisconnectMode { + Enable, + Disable, + Confirm, + } + + #[repr(u32)] + pub enum ScePspnetAdhocPtpState { + Closed, + Listen, + SynSent, + SynReceived, + Established, + } + + #[repr(u32)] + pub enum AdhocMatchingMode { + Host = 1, + Client, + Ptp, + } + + #[repr(u32)] + pub enum ApctlState { + Disconnected, + Scanning, + Joining, + GettingIp, + GotIp, + EapAuth, + KeyExchange, + } + + #[repr(u32)] + pub enum ApctlEvent { + ConnectRequest, + ScanRequest, + ScanComplete, + Established, + GetIp, + DisconnectRequest, + Error, + Info, + EapAuth, + KeyExchange, + Reconnect, + } + + #[repr(u32)] + pub enum ApctlInfo { + ProfileName, + Bssid, + Ssid, + SsidLength, + SecurityType, + Strength, + Channel, + PowerSave, + Ip, + SubnetMask, + Gateway, + PrimaryDns, + SecondaryDns, + UseProxy, + ProxyUrl, + ProxyPort, + EapType, + StartBrowser, + Wifisp, + } + + #[repr(u32)] + pub enum ApctlInfoSecurityType { + None, + Wep, + Wpa, + } + + #[repr(u32)] + pub enum HttpMethod { + Get, + Post, + Head, + } + + #[repr(u32)] + pub enum HttpAuthType { + Basic, + Digest, + } +} + +s_paren! { + #[repr(transparent)] + pub struct SceUid(pub i32); + + #[repr(transparent)] + #[allow(dead_code)] + pub struct SceMpeg(*mut *mut c_void); + + #[repr(transparent)] + #[allow(dead_code)] + pub struct SceMpegStream(*mut c_void); + + #[repr(transparent)] + pub struct Mp3Handle(pub i32); + + #[repr(transparent)] + #[allow(dead_code)] + pub struct RegHandle(u32); +} + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: u8, + pub sa_data: [u8;14], + } + + pub struct in_addr { + pub s_addr: u32, + } + + pub struct AudioInputParams { + pub unknown1: i32, + pub gain: i32, + pub unknown2: i32, + pub unknown3: i32, + pub unknown4: i32, + pub unknown5: i32, + } + + pub struct Atrac3BufferInfo { + pub puc_write_position_first_buf: *mut u8, + pub ui_writable_byte_first_buf: u32, + pub ui_min_write_byte_first_buf: u32, + pub ui_read_position_first_buf: u32, + pub puc_write_position_second_buf: *mut u8, + pub ui_writable_byte_second_buf: u32, + pub ui_min_write_byte_second_buf: u32, + pub ui_read_position_second_buf: u32, + } + + pub struct SceCtrlData { + pub timestamp: u32, + pub buttons: i32, + pub lx: u8, + pub ly: u8, + pub rsrv: [u8; 6], + } + + pub struct SceCtrlLatch { + pub ui_make: u32, + pub ui_break: u32, + pub ui_press: u32, + pub ui_release: u32, + } + + pub struct GeStack { + pub stack: [u32; 8], + } + + pub struct GeCallbackData { + pub signal_func: ::Option, + pub signal_arg: *mut c_void, + pub finish_func: ::Option, + pub finish_arg: *mut c_void, + } + + pub struct GeListArgs { + pub size: u32, + pub context: *mut GeContext, + pub num_stacks: u32, + pub stacks: *mut GeStack, + } + + pub struct GeBreakParam { + pub buf: [u32; 4], + } + + pub struct SceKernelLoadExecParam { + pub size: usize, + pub args: usize, + pub argp: *mut c_void, + pub key: *const u8, + } + + pub struct timeval { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct timezone { + pub tz_minutes_west: i32, + pub tz_dst_time: i32, + } + + pub struct IntrHandlerOptionParam { + size: i32, + entry: u32, + common: u32, + gp: u32, + intr_code: u16, + sub_count: u16, + intr_level: u16, + enabled: u16, + calls: u32, + field_1c: u32, + total_clock_lo: u32, + total_clock_hi: u32, + min_clock_lo: u32, + min_clock_hi: u32, + max_clock_lo: u32, + max_clock_hi: u32, + } + + pub struct SceKernelLMOption { + pub size: usize, + pub m_pid_text: SceUid, + pub m_pid_data: SceUid, + pub flags: u32, + pub position: u8, + pub access: u8, + pub c_reserved: [u8; 2usize], + } + + pub struct SceKernelSMOption { + pub size: usize, + pub m_pid_stack: SceUid, + pub stack_size: usize, + pub priority: i32, + pub attribute: u32, + } + + pub struct SceKernelModuleInfo { + pub size: usize, + pub n_segment: u8, + pub reserved: [u8; 3usize], + pub segment_addr: [i32; 4usize], + pub segment_size: [i32; 4usize], + pub entry_addr: u32, + pub gp_value: u32, + pub text_addr: u32, + pub text_size: u32, + pub data_size: u32, + pub bss_size: u32, + pub attribute: u16, + pub version: [u8; 2usize], + pub name: [u8; 28usize], + } + + pub struct DebugProfilerRegs { + pub enable: u32, + pub systemck: u32, + pub cpuck: u32, + pub internal: u32, + pub memory: u32, + pub copz: u32, + pub vfpu: u32, + pub sleep: u32, + pub bus_access: u32, + pub uncached_load: u32, + pub uncached_store: u32, + pub cached_load: u32, + pub cached_store: u32, + pub i_miss: u32, + pub d_miss: u32, + pub d_writeback: u32, + pub cop0_inst: u32, + pub fpu_inst: u32, + pub vfpu_inst: u32, + pub local_bus: u32, + } + + pub struct SceKernelSysClock { + pub low: u32, + pub hi: u32, + } + + pub struct SceKernelThreadOptParam { + pub size: usize, + pub stack_mpid: SceUid, + } + + pub struct SceKernelThreadInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub status: i32, + pub entry: SceKernelThreadEntry, + pub stack: *mut c_void, + pub stack_size: i32, + pub gp_reg: *mut c_void, + pub init_priority: i32, + pub current_priority: i32, + pub wait_type: i32, + pub wait_id: SceUid, + pub wakeup_count: i32, + pub exit_status: i32, + pub run_clocks: SceKernelSysClock, + pub intr_preempt_count: u32, + pub thread_preempt_count: u32, + pub release_count: u32, + } + + pub struct SceKernelThreadRunStatus { + pub size: usize, + pub status: i32, + pub current_priority: i32, + pub wait_type: i32, + pub wait_id: i32, + pub wakeup_count: i32, + pub run_clocks: SceKernelSysClock, + pub intr_preempt_count: u32, + pub thread_preempt_count: u32, + pub release_count: u32, + } + + pub struct SceKernelSemaOptParam { + pub size: usize, + } + + pub struct SceKernelSemaInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub init_count: i32, + pub current_count: i32, + pub max_count: i32, + pub num_wait_threads: i32, + } + + pub struct SceKernelEventFlagInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub init_pattern: u32, + pub current_pattern: u32, + pub num_wait_threads: i32, + } + + pub struct SceKernelEventFlagOptParam { + pub size: usize, + } + + pub struct SceKernelMbxOptParam { + pub size: usize, + } + + pub struct SceKernelMbxInfo { + pub size: usize, + pub name: [u8; 32usize], + pub attr: u32, + pub num_wait_threads: i32, + pub num_messages: i32, + pub first_message: *mut c_void, + } + + pub struct SceKernelVTimerInfo { + pub size: usize, + pub name: [u8; 32], + pub active: i32, + pub base: SceKernelSysClock, + pub current: SceKernelSysClock, + pub schedule: SceKernelSysClock, + pub handler: SceKernelVTimerHandler, + pub common: *mut c_void, + } + + pub struct SceKernelThreadEventHandlerInfo { + pub size: usize, + pub name: [u8; 32], + pub thread_id: SceUid, + pub mask: i32, + pub handler: SceKernelThreadEventHandler, + pub common: *mut c_void, + } + + pub struct SceKernelAlarmInfo { + pub size: usize, + pub schedule: SceKernelSysClock, + pub handler: SceKernelAlarmHandler, + pub common: *mut c_void, + } + + pub struct SceKernelSystemStatus { + pub size: usize, + pub status: u32, + pub idle_clocks: SceKernelSysClock, + pub comes_out_of_idle_count: u32, + pub thread_switch_count: u32, + pub vfpu_switch_count: u32, + } + + pub struct SceKernelMppInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub buf_size: i32, + pub free_size: i32, + pub num_send_wait_threads: i32, + pub num_receive_wait_threads: i32, + } + + pub struct SceKernelVplOptParam { + pub size: usize, + } + + pub struct SceKernelVplInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub pool_size: i32, + pub free_size: i32, + pub num_wait_threads: i32, + } + + pub struct SceKernelFplOptParam { + pub size: usize, + } + + pub struct SceKernelFplInfo { + pub size: usize, + pub name: [u8; 32usize], + pub attr: u32, + pub block_size: i32, + pub num_blocks: i32, + pub free_blocks: i32, + pub num_wait_threads: i32, + } + + pub struct SceKernelVTimerOptParam { + pub size: usize, + } + + pub struct SceKernelCallbackInfo { + pub size: usize, + pub name: [u8; 32usize], + pub thread_id: SceUid, + pub callback: SceKernelCallbackFunction, + pub common: *mut c_void, + pub notify_count: i32, + pub notify_arg: i32, + } + + pub struct UsbCamSetupStillParam { + pub size: i32, + pub resolution: UsbCamResolution, + pub jpeg_size: i32, + pub reverse_flags: i32, + pub delay: UsbCamDelay, + pub comp_level: i32, + } + + pub struct UsbCamSetupStillExParam { + pub size: i32, + pub unk: u32, + pub resolution: UsbCamResolutionEx, + pub jpeg_size: i32, + pub comp_level: i32, + pub unk2: u32, + pub unk3: u32, + pub flip: i32, + pub mirror: i32, + pub delay: UsbCamDelay, + pub unk4: [u32; 5usize], + } + + pub struct UsbCamSetupVideoParam { + pub size: i32, + pub resolution: UsbCamResolution, + pub framerate: UsbCamFrameRate, + pub white_balance: UsbCamWb, + pub saturation: i32, + pub brightness: i32, + pub contrast: i32, + pub sharpness: i32, + pub effect_mode: UsbCamEffectMode, + pub frame_size: i32, + pub unk: u32, + pub evl_evel: UsbCamEvLevel, + } + + pub struct UsbCamSetupVideoExParam { + pub size: i32, + pub unk: u32, + pub resolution: UsbCamResolutionEx, + pub framerate: UsbCamFrameRate, + pub unk2: u32, + pub unk3: u32, + pub white_balance: UsbCamWb, + pub saturation: i32, + pub brightness: i32, + pub contrast: i32, + pub sharpness: i32, + pub unk4: u32, + pub unk5: u32, + pub unk6: [u32; 3usize], + pub effect_mode: UsbCamEffectMode, + pub unk7: u32, + pub unk8: u32, + pub unk9: u32, + pub unk10: u32, + pub unk11: u32, + pub frame_size: i32, + pub unk12: u32, + pub ev_level: UsbCamEvLevel, + } + + pub struct ScePspDateTime { + pub year: u16, + pub month: u16, + pub day: u16, + pub hour: u16, + pub minutes: u16, + pub seconds: u16, + pub microseconds: u32, + } + + pub struct SceIoStat { + pub st_mode: i32, + pub st_attr: i32, + pub st_size: i64, + pub st_ctime: ScePspDateTime, + pub st_atime: ScePspDateTime, + pub st_mtime: ScePspDateTime, + pub st_private: [u32; 6usize], + } + + pub struct UmdInfo { + pub size: u32, + pub type_: UmdType, + } + + pub struct SceMpegRingbuffer { + pub packets: i32, + pub unk0: u32, + pub unk1: u32, + pub unk2: u32, + pub unk3: u32, + pub data: *mut c_void, + pub callback: SceMpegRingbufferCb, + pub cb_param: *mut c_void, + pub unk4: u32, + pub unk5: u32, + pub sce_mpeg: *mut c_void, + } + + pub struct SceMpegAu { + pub pts_msb: u32, + pub pts: u32, + pub dts_msb: u32, + pub dts: u32, + pub es_buffer: u32, + pub au_size: u32, + } + + pub struct SceMpegAvcMode { + pub unk0: i32, + pub pixel_format: super::DisplayPixelFormat, + } + + #[repr(align(64))] + pub struct SceMpegLLI { + pub src: *mut c_void, + pub dst: *mut c_void, + pub next: *mut c_void, + pub size: i32, + } + + #[repr(align(64))] + pub struct SceMpegYCrCbBuffer { + pub frame_buffer_height16: i32, + pub frame_buffer_width16: i32, + pub unknown: i32, + pub unknown2: i32, + pub y_buffer: *mut c_void, + pub y_buffer2: *mut c_void, + pub cr_buffer: *mut c_void, + pub cb_buffer: *mut c_void, + pub cr_buffer2: *mut c_void, + pub cb_buffer2: *mut c_void, + + pub frame_height: i32, + pub frame_width: i32, + pub frame_buffer_width: i32, + pub unknown3: [i32; 11usize], + } + + pub struct ScePspSRect { + pub x: i16, + pub y: i16, + pub w: i16, + pub h: i16, + } + + pub struct ScePspIRect { + pub x: i32, + pub y: i32, + pub w: i32, + pub h: i32, + } + + pub struct ScePspL64Rect { + pub x: u64, + pub y: u64, + pub w: u64, + pub h: u64, + } + + pub struct ScePspSVector2 { + pub x: i16, + pub y: i16, + } + + pub struct ScePspIVector2 { + pub x: i32, + pub y: i32, + } + + pub struct ScePspL64Vector2 { + pub x: u64, + pub y: u64, + } + + pub struct ScePspSVector3 { + pub x: i16, + pub y: i16, + pub z: i16, + } + + pub struct ScePspIVector3 { + pub x: i32, + pub y: i32, + pub z: i32, + } + + pub struct ScePspL64Vector3 { + pub x: u64, + pub y: u64, + pub z: u64, + } + + pub struct ScePspSVector4 { + pub x: i16, + pub y: i16, + pub z: i16, + pub w: i16, + } + + pub struct ScePspIVector4 { + pub x: i32, + pub y: i32, + pub z: i32, + pub w: i32, + } + + pub struct ScePspL64Vector4 { + pub x: u64, + pub y: u64, + pub z: u64, + pub w: u64, + } + + pub struct ScePspIMatrix2 { + pub x: ScePspIVector2, + pub y: ScePspIVector2, + } + + pub struct ScePspIMatrix3 { + pub x: ScePspIVector3, + pub y: ScePspIVector3, + pub z: ScePspIVector3, + } + + #[repr(align(16))] + pub struct ScePspIMatrix4 { + pub x: ScePspIVector4, + pub y: ScePspIVector4, + pub z: ScePspIVector4, + pub w: ScePspIVector4, + } + + pub struct ScePspIMatrix4Unaligned { + pub x: ScePspIVector4, + pub y: ScePspIVector4, + pub z: ScePspIVector4, + pub w: ScePspIVector4, + } + + pub struct SceMp3InitArg { + pub mp3_stream_start: u32, + pub unk1: u32, + pub mp3_stream_end: u32, + pub unk2: u32, + pub mp3_buf: *mut c_void, + pub mp3_buf_size: i32, + pub pcm_buf: *mut c_void, + pub pcm_buf_size: i32, + } + + pub struct OpenPSID { + pub data: [u8; 16usize], + } + + pub struct UtilityDialogCommon { + pub size: u32, + pub language: SystemParamLanguage, + pub button_accept: UtilityDialogButtonAccept, + pub graphics_thread: i32, + pub access_thread: i32, + pub font_thread: i32, + pub sound_thread: i32, + pub result: i32, + pub reserved: [i32; 4usize], + } + + pub struct UtilityNetconfAdhoc { + pub name: [u8; 8usize], + pub timeout: u32, + } + + pub struct UtilityNetconfData { + pub base: UtilityDialogCommon, + pub action: UtilityNetconfAction, + pub adhocparam: *mut UtilityNetconfAdhoc, + pub hotspot: i32, + pub hotspot_connected: i32, + pub wifisp: i32, + } + + pub struct UtilitySavedataFileData { + pub buf: *mut c_void, + pub buf_size: usize, + pub size: usize, + pub unknown: i32, + } + + pub struct UtilitySavedataListSaveNewData { + pub icon0: UtilitySavedataFileData, + pub title: *mut u8, + } + + pub struct UtilityGameSharingParams { + pub base: UtilityDialogCommon, + pub unknown1: i32, + pub unknown2: i32, + pub name: [u8; 8usize], + pub unknown3: i32, + pub unknown4: i32, + pub unknown5: i32, + pub result: i32, + pub filepath: *mut u8, + pub mode: UtilityGameSharingMode, + pub datatype: UtilityGameSharingDataType, + pub data: *mut c_void, + pub datasize: u32, + } + + pub struct UtilityHtmlViewerParam { + pub base: UtilityDialogCommon, + pub memaddr: *mut c_void, + pub memsize: u32, + pub unknown1: i32, + pub unknown2: i32, + pub initialurl: *mut u8, + pub numtabs: u32, + pub interfacemode: UtilityHtmlViewerInterfaceMode, + pub options: i32, + pub dldirname: *mut u8, + pub dlfilename: *mut u8, + pub uldirname: *mut u8, + pub ulfilename: *mut u8, + pub cookiemode: UtilityHtmlViewerCookieMode, + pub unknown3: u32, + pub homeurl: *mut u8, + pub textsize: UtilityHtmlViewerTextSize, + pub displaymode: UtilityHtmlViewerDisplayMode, + pub connectmode: UtilityHtmlViewerConnectMode, + pub disconnectmode: UtilityHtmlViewerDisconnectMode, + pub memused: u32, + pub unknown4: [i32; 10usize], + } + + pub struct SceUtilityOskData { + pub unk_00: i32, + pub unk_04: i32, + pub language: SceUtilityOskInputLanguage, + pub unk_12: i32, + pub inputtype: SceUtilityOskInputType, + pub lines: i32, + pub unk_24: i32, + pub desc: *mut u16, + pub intext: *mut u16, + pub outtextlength: i32, + pub outtext: *mut u16, + pub result: SceUtilityOskResult, + pub outtextlimit: i32, + } + + pub struct SceUtilityOskParams { + pub base: UtilityDialogCommon, + pub datacount: i32, + pub data: *mut SceUtilityOskData, + pub state: SceUtilityOskState, + pub unk_60: i32, + } + + pub struct SceNetMallocStat { + pub pool: i32, + pub maximum: i32, + pub free: i32, + } + + pub struct SceNetAdhocctlAdhocId { + pub unknown: i32, + pub adhoc_id: [u8; 9usize], + pub unk: [u8; 3usize], + } + + pub struct SceNetAdhocctlScanInfo { + pub next: *mut SceNetAdhocctlScanInfo, + pub channel: i32, + pub name: [u8; 8usize], + pub bssid: [u8; 6usize], + pub unknown: [u8; 2usize], + pub unknown2: i32, + } + + pub struct SceNetAdhocctlGameModeInfo { + pub count: i32, + pub macs: [[u8; 6usize]; 16usize], + } + + pub struct SceNetAdhocPtpStat { + pub next: *mut SceNetAdhocPtpStat, + pub ptp_id: i32, + pub mac: [u8; 6usize], + pub peermac: [u8; 6usize], + pub port: u16, + pub peerport: u16, + pub sent_data: u32, + pub rcvd_data: u32, + pub state: ScePspnetAdhocPtpState, + } + + pub struct SceNetAdhocPdpStat { + pub next: *mut SceNetAdhocPdpStat, + pub pdp_id: i32, + pub mac: [u8; 6usize], + pub port: u16, + pub rcvd_data: u32, + } + + pub struct AdhocPoolStat { + pub size: i32, + pub maxsize: i32, + pub freesize: i32, + } +} + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct GeContext { + pub context: [u32; 512], + } + + #[allow(missing_debug_implementations)] + pub struct SceKernelUtilsSha1Context { + pub h: [u32; 5usize], + pub us_remains: u16, + pub us_computed: u16, + pub ull_total_len: u64, + pub buf: [u8; 64usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceKernelUtilsMt19937Context { + pub count: u32, + pub state: [u32; 624usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceKernelUtilsMd5Context { + pub h: [u32; 4usize], + pub pad: u32, + pub us_remains: u16, + pub us_computed: u16, + pub ull_total_len: u64, + pub buf: [u8; 64usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceIoDirent { + pub d_stat: SceIoStat, + pub d_name: [u8; 256usize], + pub d_private: *mut c_void, + pub dummy: i32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFRect { + pub x: f32, + pub y: f32, + pub w: f32, + pub h: f32, + } + + #[repr(align(16))] + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector3 { + pub x: f32, + pub y: f32, + pub z: f32, + } + + #[repr(align(16))] + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector4 { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector4Unaligned { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector2 { + pub x: f32, + pub y: f32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFMatrix2 { + pub x: ScePspFVector2, + pub y: ScePspFVector2, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFMatrix3 { + pub x: ScePspFVector3, + pub y: ScePspFVector3, + pub z: ScePspFVector3, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + #[repr(align(16))] + pub struct ScePspFMatrix4 { + pub x: ScePspFVector4, + pub y: ScePspFVector4, + pub z: ScePspFVector4, + pub w: ScePspFVector4, + } + + #[allow(missing_debug_implementations)] + pub struct ScePspFMatrix4Unaligned { + pub x: ScePspFVector4, + pub y: ScePspFVector4, + pub z: ScePspFVector4, + pub w: ScePspFVector4, + } + + #[allow(missing_debug_implementations)] + pub union ScePspVector3 { + pub fv: ScePspFVector3, + pub iv: ScePspIVector3, + pub f: [f32; 3usize], + pub i: [i32; 3usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspVector4 { + pub fv: ScePspFVector4, + pub iv: ScePspIVector4, + pub qw: u128, + pub f: [f32; 4usize], + pub i: [i32; 4usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspMatrix2 { + pub fm: ScePspFMatrix2, + pub im: ScePspIMatrix2, + pub fv: [ScePspFVector2; 2usize], + pub iv: [ScePspIVector2; 2usize], + pub v: [ScePspVector2; 2usize], + pub f: [[f32; 2usize]; 2usize], + pub i: [[i32; 2usize]; 2usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspMatrix3 { + pub fm: ScePspFMatrix3, + pub im: ScePspIMatrix3, + pub fv: [ScePspFVector3; 3usize], + pub iv: [ScePspIVector3; 3usize], + pub v: [ScePspVector3; 3usize], + pub f: [[f32; 3usize]; 3usize], + pub i: [[i32; 3usize]; 3usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspVector2 { + pub fv: ScePspFVector2, + pub iv: ScePspIVector2, + pub f: [f32; 2usize], + pub i: [i32; 2usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspMatrix4 { + pub fm: ScePspFMatrix4, + pub im: ScePspIMatrix4, + pub fv: [ScePspFVector4; 4usize], + pub iv: [ScePspIVector4; 4usize], + pub v: [ScePspVector4; 4usize], + pub f: [[f32; 4usize]; 4usize], + pub i: [[i32; 4usize]; 4usize], + } + + #[allow(missing_debug_implementations)] + pub struct Key { + pub key_type: KeyType, + pub name: [u8; 256usize], + pub name_len: u32, + pub unk2: u32, + pub unk3: u32, + } + + #[allow(missing_debug_implementations)] + pub struct UtilityMsgDialogParams { + pub base: UtilityDialogCommon, + pub unknown: i32, + pub mode: UtilityMsgDialogMode, + pub error_value: u32, + pub message: [u8; 512usize], + pub options: i32, + pub button_pressed: UtilityMsgDialogPressed, + } + + #[allow(missing_debug_implementations)] + pub union UtilityNetData { + pub as_uint: u32, + pub as_string: [u8; 128usize], + } + + #[allow(missing_debug_implementations)] + pub struct UtilitySavedataSFOParam { + pub title: [u8; 128usize], + pub savedata_title: [u8; 128usize], + pub detail: [u8; 1024usize], + pub parental_level: u8, + pub unknown: [u8; 3usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceUtilitySavedataParam { + pub base: UtilityDialogCommon, + pub mode: UtilitySavedataMode, + pub unknown1: i32, + pub overwrite: i32, + pub game_name: [u8; 13usize], + pub reserved: [u8; 3usize], + pub save_name: [u8; 20usize], + pub save_name_list: *mut [u8; 20usize], + pub file_name: [u8; 13usize], + pub reserved1: [u8; 3usize], + pub data_buf: *mut c_void, + pub data_buf_size: usize, + pub data_size: usize, + pub sfo_param: UtilitySavedataSFOParam, + pub icon0_file_data: UtilitySavedataFileData, + pub icon1_file_data: UtilitySavedataFileData, + pub pic1_file_data: UtilitySavedataFileData, + pub snd0_file_data: UtilitySavedataFileData, + pub new_data: *mut UtilitySavedataListSaveNewData, + pub focus: UtilitySavedataFocus, + pub unknown2: [i32; 4usize], + pub key: [u8; 16], + pub unknown3: [u8; 20], + } + + #[allow(missing_debug_implementations)] + pub struct SceNetAdhocctlPeerInfo { + pub next: *mut SceNetAdhocctlPeerInfo, + pub nickname: [u8; 128usize], + pub mac: [u8; 6usize], + pub unknown: [u8; 6usize], + pub timestamp: u32, + } + + #[allow(missing_debug_implementations)] + pub struct SceNetAdhocctlParams { + pub channel: i32, + pub name: [u8; 8usize], + pub bssid: [u8; 6usize], + pub nickname: [u8; 128usize], + } + + #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] + pub union SceNetApctlInfo { + pub name: [u8; 64usize], + pub bssid: [u8; 6usize], + pub ssid: [u8; 32usize], + pub ssid_length: u32, + pub security_type: u32, + pub strength: u8, + pub channel: u8, + pub power_save: u8, + pub ip: [u8; 16usize], + pub sub_net_mask: [u8; 16usize], + pub gateway: [u8; 16usize], + pub primary_dns: [u8; 16usize], + pub secondary_dns: [u8; 16usize], + pub use_proxy: u32, + pub proxy_url: [u8; 128usize], + pub proxy_port: u16, + pub eap_type: u32, + pub start_browser: u32, + pub wifisp: u32, + } +} + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +pub const AUDIO_VOLUME_MAX: u32 = 0x8000; +pub const AUDIO_CHANNEL_MAX: u32 = 8; +pub const AUDIO_NEXT_CHANNEL: i32 = -1; +pub const AUDIO_SAMPLE_MIN: u32 = 64; +pub const AUDIO_SAMPLE_MAX: u32 = 65472; + +pub const PSP_CTRL_SELECT: i32 = 0x000001; +pub const PSP_CTRL_START: i32 = 0x000008; +pub const PSP_CTRL_UP: i32 = 0x000010; +pub const PSP_CTRL_RIGHT: i32 = 0x000020; +pub const PSP_CTRL_DOWN: i32 = 0x000040; +pub const PSP_CTRL_LEFT: i32 = 0x000080; +pub const PSP_CTRL_LTRIGGER: i32 = 0x000100; +pub const PSP_CTRL_RTRIGGER: i32 = 0x000200; +pub const PSP_CTRL_TRIANGLE: i32 = 0x001000; +pub const PSP_CTRL_CIRCLE: i32 = 0x002000; +pub const PSP_CTRL_CROSS: i32 = 0x004000; +pub const PSP_CTRL_SQUARE: i32 = 0x008000; +pub const PSP_CTRL_HOME: i32 = 0x010000; +pub const PSP_CTRL_HOLD: i32 = 0x020000; +pub const PSP_CTRL_NOTE: i32 = 0x800000; +pub const PSP_CTRL_SCREEN: i32 = 0x400000; +pub const PSP_CTRL_VOLUP: i32 = 0x100000; +pub const PSP_CTRL_VOLDOWN: i32 = 0x200000; +pub const PSP_CTRL_WLAN_UP: i32 = 0x040000; +pub const PSP_CTRL_REMOTE: i32 = 0x080000; +pub const PSP_CTRL_DISC: i32 = 0x1000000; +pub const PSP_CTRL_MS: i32 = 0x2000000; + +pub const USB_CAM_PID: i32 = 0x282; +pub const USB_BUS_DRIVER_NAME: &str = "USBBusDriver"; +pub const USB_CAM_DRIVER_NAME: &str = "USBCamDriver"; +pub const USB_CAM_MIC_DRIVER_NAME: &str = "USBCamMicDriver"; +pub const USB_STOR_DRIVER_NAME: &str = "USBStor_Driver"; + +pub const ACTIVATED: i32 = 0x200; +pub const CONNECTED: i32 = 0x020; +pub const ESTABLISHED: i32 = 0x002; + +pub const USB_CAM_FLIP: i32 = 1; +pub const USB_CAM_MIRROR: i32 = 0x100; + +pub const THREAD_ATTR_VFPU: i32 = 0x00004000; +pub const THREAD_ATTR_USER: i32 = 0x80000000; +pub const THREAD_ATTR_USBWLAN: i32 = 0xa0000000; +pub const THREAD_ATTR_VSH: i32 = 0xc0000000; +pub const THREAD_ATTR_SCRATCH_SRAM: i32 = 0x00008000; +pub const THREAD_ATTR_NO_FILLSTACK: i32 = 0x00100000; +pub const THREAD_ATTR_CLEAR_STACK: i32 = 0x00200000; + +pub const EVENT_WAIT_MULTIPLE: i32 = 0x200; + +pub const EVENT_WAIT_AND: i32 = 0; +pub const EVENT_WAIT_OR: i32 = 1; +pub const EVENT_WAIT_CLEAR: i32 = 0x20; + +pub const POWER_INFO_POWER_SWITCH: i32 = 0x80000000; +pub const POWER_INFO_HOLD_SWITCH: i32 = 0x40000000; +pub const POWER_INFO_STANDBY: i32 = 0x00080000; +pub const POWER_INFO_RESUME_COMPLETE: i32 = 0x00040000; +pub const POWER_INFO_RESUMING: i32 = 0x00020000; +pub const POWER_INFO_SUSPENDING: i32 = 0x00010000; +pub const POWER_INFO_AC_POWER: i32 = 0x00001000; +pub const POWER_INFO_BATTERY_LOW: i32 = 0x00000100; +pub const POWER_INFO_BATTERY_EXIST: i32 = 0x00000080; +pub const POWER_INFO_BATTERY_POWER: i32 = 0x0000007; + +pub const FIO_S_IFLNK: i32 = 0x4000; +pub const FIO_S_IFDIR: i32 = 0x1000; +pub const FIO_S_IFREG: i32 = 0x2000; +pub const FIO_S_ISUID: i32 = 0x0800; +pub const FIO_S_ISGID: i32 = 0x0400; +pub const FIO_S_ISVTX: i32 = 0x0200; +pub const FIO_S_IRUSR: i32 = 0x0100; +pub const FIO_S_IWUSR: i32 = 0x0080; +pub const FIO_S_IXUSR: i32 = 0x0040; +pub const FIO_S_IRGRP: i32 = 0x0020; +pub const FIO_S_IWGRP: i32 = 0x0010; +pub const FIO_S_IXGRP: i32 = 0x0008; +pub const FIO_S_IROTH: i32 = 0x0004; +pub const FIO_S_IWOTH: i32 = 0x0002; +pub const FIO_S_IXOTH: i32 = 0x0001; + +pub const FIO_SO_IFLNK: i32 = 0x0008; +pub const FIO_SO_IFDIR: i32 = 0x0010; +pub const FIO_SO_IFREG: i32 = 0x0020; +pub const FIO_SO_IROTH: i32 = 0x0004; +pub const FIO_SO_IWOTH: i32 = 0x0002; +pub const FIO_SO_IXOTH: i32 = 0x0001; + +pub const PSP_O_RD_ONLY: i32 = 0x0001; +pub const PSP_O_WR_ONLY: i32 = 0x0002; +pub const PSP_O_RD_WR: i32 = 0x0003; +pub const PSP_O_NBLOCK: i32 = 0x0004; +pub const PSP_O_DIR: i32 = 0x0008; +pub const PSP_O_APPEND: i32 = 0x0100; +pub const PSP_O_CREAT: i32 = 0x0200; +pub const PSP_O_TRUNC: i32 = 0x0400; +pub const PSP_O_EXCL: i32 = 0x0800; +pub const PSP_O_NO_WAIT: i32 = 0x8000; + +pub const UMD_NOT_PRESENT: i32 = 0x01; +pub const UMD_PRESENT: i32 = 0x02; +pub const UMD_CHANGED: i32 = 0x04; +pub const UMD_INITING: i32 = 0x08; +pub const UMD_INITED: i32 = 0x10; +pub const UMD_READY: i32 = 0x20; + +pub const PLAY_PAUSE: i32 = 0x1; +pub const FORWARD: i32 = 0x4; +pub const BACK: i32 = 0x8; +pub const VOL_UP: i32 = 0x10; +pub const VOL_DOWN: i32 = 0x20; +pub const HOLD: i32 = 0x80; + +pub const GU_PI: f32 = 3.141593; + +pub const GU_TEXTURE_8BIT: i32 = 1; +pub const GU_TEXTURE_16BIT: i32 = 2; +pub const GU_TEXTURE_32BITF: i32 = 3; +pub const GU_COLOR_5650: i32 = 4 << 2; +pub const GU_COLOR_5551: i32 = 5 << 2; +pub const GU_COLOR_4444: i32 = 6 << 2; +pub const GU_COLOR_8888: i32 = 7 << 2; +pub const GU_NORMAL_8BIT: i32 = 1 << 5; +pub const GU_NORMAL_16BIT: i32 = 2 << 5; +pub const GU_NORMAL_32BITF: i32 = 3 << 5; +pub const GU_VERTEX_8BIT: i32 = 1 << 7; +pub const GU_VERTEX_16BIT: i32 = 2 << 7; +pub const GU_VERTEX_32BITF: i32 = 3 << 7; +pub const GU_WEIGHT_8BIT: i32 = 1 << 9; +pub const GU_WEIGHT_16BIT: i32 = 2 << 9; +pub const GU_WEIGHT_32BITF: i32 = 3 << 9; +pub const GU_INDEX_8BIT: i32 = 1 << 11; +pub const GU_INDEX_16BIT: i32 = 2 << 11; +pub const GU_WEIGHTS1: i32 = (((1 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS2: i32 = (((2 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS3: i32 = (((3 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS4: i32 = (((4 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS5: i32 = (((5 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS6: i32 = (((6 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS7: i32 = (((7 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS8: i32 = (((8 - 1) & 7) << 14) as i32; +pub const GU_VERTICES1: i32 = (((1 - 1) & 7) << 18) as i32; +pub const GU_VERTICES2: i32 = (((2 - 1) & 7) << 18) as i32; +pub const GU_VERTICES3: i32 = (((3 - 1) & 7) << 18) as i32; +pub const GU_VERTICES4: i32 = (((4 - 1) & 7) << 18) as i32; +pub const GU_VERTICES5: i32 = (((5 - 1) & 7) << 18) as i32; +pub const GU_VERTICES6: i32 = (((6 - 1) & 7) << 18) as i32; +pub const GU_VERTICES7: i32 = (((7 - 1) & 7) << 18) as i32; +pub const GU_VERTICES8: i32 = (((8 - 1) & 7) << 18) as i32; +pub const GU_TRANSFORM_2D: i32 = 1 << 23; +pub const GU_TRANSFORM_3D: i32 = 0; + +pub const GU_COLOR_BUFFER_BIT: i32 = 1; +pub const GU_STENCIL_BUFFER_BIT: i32 = 2; +pub const GU_DEPTH_BUFFER_BIT: i32 = 4; +pub const GU_FAST_CLEAR_BIT: i32 = 16; + +pub const GU_AMBIENT: i32 = 1; +pub const GU_DIFFUSE: i32 = 2; +pub const GU_SPECULAR: i32 = 4; +pub const GU_UNKNOWN_LIGHT_COMPONENT: i32 = 8; + +pub const SYSTEM_REGISTRY: [u8; 7] = *b"/system"; +pub const REG_KEYNAME_SIZE: u32 = 27; + +pub const UTILITY_MSGDIALOG_ERROR: i32 = 0; +pub const UTILITY_MSGDIALOG_TEXT: i32 = 1; +pub const UTILITY_MSGDIALOG_YES_NO_BUTTONS: i32 = 0x10; +pub const UTILITY_MSGDIALOG_DEFAULT_NO: i32 = 0x100; + +pub const UTILITY_HTMLVIEWER_OPEN_SCE_START_PAGE: i32 = 0x000001; +pub const UTILITY_HTMLVIEWER_DISABLE_STARTUP_LIMITS: i32 = 0x000002; +pub const UTILITY_HTMLVIEWER_DISABLE_EXIT_DIALOG: i32 = 0x000004; +pub const UTILITY_HTMLVIEWER_DISABLE_CURSOR: i32 = 0x000008; +pub const UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_COMPLETE_DIALOG: i32 = 0x000010; +pub const UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_START_DIALOG: i32 = 0x000020; +pub const UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_DESTINATION_DIALOG: i32 = 0x000040; +pub const UTILITY_HTMLVIEWER_LOCK_DOWNLOAD_DESTINATION_DIALOG: i32 = 0x000080; +pub const UTILITY_HTMLVIEWER_DISABLE_TAB_DISPLAY: i32 = 0x000100; +pub const UTILITY_HTMLVIEWER_ENABLE_ANALOG_HOLD: i32 = 0x000200; +pub const UTILITY_HTMLVIEWER_ENABLE_FLASH: i32 = 0x000400; +pub const UTILITY_HTMLVIEWER_DISABLE_LRTRIGGER: i32 = 0x000800; + +extern "C" { + pub fn sceAudioChReserve(channel: i32, sample_count: i32, format: AudioFormat) -> i32; + pub fn sceAudioChRelease(channel: i32) -> i32; + pub fn sceAudioOutput(channel: i32, vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioOutputBlocking(channel: i32, vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioOutputPanned( + channel: i32, + left_vol: i32, + right_vol: i32, + buf: *mut c_void, + ) -> i32; + pub fn sceAudioOutputPannedBlocking( + channel: i32, + left_vol: i32, + right_vol: i32, + buf: *mut c_void, + ) -> i32; + pub fn sceAudioGetChannelRestLen(channel: i32) -> i32; + pub fn sceAudioGetChannelRestLength(channel: i32) -> i32; + pub fn sceAudioSetChannelDataLen(channel: i32, sample_count: i32) -> i32; + pub fn sceAudioChangeChannelConfig(channel: i32, format: AudioFormat) -> i32; + pub fn sceAudioChangeChannelVolume(channel: i32, left_vol: i32, right_vol: i32) -> i32; + pub fn sceAudioOutput2Reserve(sample_count: i32) -> i32; + pub fn sceAudioOutput2Release() -> i32; + pub fn sceAudioOutput2ChangeLength(sample_count: i32) -> i32; + pub fn sceAudioOutput2OutputBlocking(vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioOutput2GetRestSample() -> i32; + pub fn sceAudioSRCChReserve( + sample_count: i32, + freq: AudioOutputFrequency, + channels: i32, + ) -> i32; + pub fn sceAudioSRCChRelease() -> i32; + pub fn sceAudioSRCOutputBlocking(vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioInputInit(unknown1: i32, gain: i32, unknown2: i32) -> i32; + pub fn sceAudioInputInitEx(params: *mut AudioInputParams) -> i32; + pub fn sceAudioInputBlocking(sample_count: i32, freq: AudioInputFrequency, buf: *mut c_void); + pub fn sceAudioInput(sample_count: i32, freq: AudioInputFrequency, buf: *mut c_void); + pub fn sceAudioGetInputLength() -> i32; + pub fn sceAudioWaitInputEnd() -> i32; + pub fn sceAudioPollInputEnd() -> i32; + + pub fn sceAtracGetAtracID(ui_codec_type: u32) -> i32; + pub fn sceAtracSetDataAndGetID(buf: *mut c_void, bufsize: usize) -> i32; + pub fn sceAtracDecodeData( + atrac_id: i32, + out_samples: *mut u16, + out_n: *mut i32, + out_end: *mut i32, + out_remain_frame: *mut i32, + ) -> i32; + pub fn sceAtracGetRemainFrame(atrac_id: i32, out_remain_frame: *mut i32) -> i32; + pub fn sceAtracGetStreamDataInfo( + atrac_id: i32, + write_pointer: *mut *mut u8, + available_bytes: *mut u32, + read_offset: *mut u32, + ) -> i32; + pub fn sceAtracAddStreamData(atrac_id: i32, bytes_to_add: u32) -> i32; + pub fn sceAtracGetBitrate(atrac_id: i32, out_bitrate: *mut i32) -> i32; + pub fn sceAtracSetLoopNum(atrac_id: i32, nloops: i32) -> i32; + pub fn sceAtracReleaseAtracID(atrac_id: i32) -> i32; + pub fn sceAtracGetNextSample(atrac_id: i32, out_n: *mut i32) -> i32; + pub fn sceAtracGetMaxSample(atrac_id: i32, out_max: *mut i32) -> i32; + pub fn sceAtracGetBufferInfoForReseting( + atrac_id: i32, + ui_sample: u32, + pbuffer_info: *mut Atrac3BufferInfo, + ) -> i32; + pub fn sceAtracGetChannel(atrac_id: i32, pui_channel: *mut u32) -> i32; + pub fn sceAtracGetInternalErrorInfo(atrac_id: i32, pi_result: *mut i32) -> i32; + pub fn sceAtracGetLoopStatus( + atrac_id: i32, + pi_loop_num: *mut i32, + pui_loop_status: *mut u32, + ) -> i32; + pub fn sceAtracGetNextDecodePosition(atrac_id: i32, pui_sample_position: *mut u32) -> i32; + pub fn sceAtracGetSecondBufferInfo( + atrac_id: i32, + pui_position: *mut u32, + pui_data_byte: *mut u32, + ) -> i32; + pub fn sceAtracGetSoundSample( + atrac_id: i32, + pi_end_sample: *mut i32, + pi_loop_start_sample: *mut i32, + pi_loop_end_sample: *mut i32, + ) -> i32; + pub fn sceAtracResetPlayPosition( + atrac_id: i32, + ui_sample: u32, + ui_write_byte_first_buf: u32, + ui_write_byte_second_buf: u32, + ) -> i32; + pub fn sceAtracSetData(atrac_id: i32, puc_buffer_addr: *mut u8, ui_buffer_byte: u32) -> i32; + pub fn sceAtracSetHalfwayBuffer( + atrac_id: i32, + puc_buffer_addr: *mut u8, + ui_read_byte: u32, + ui_buffer_byte: u32, + ) -> i32; + pub fn sceAtracSetHalfwayBufferAndGetID( + puc_buffer_addr: *mut u8, + ui_read_byte: u32, + ui_buffer_byte: u32, + ) -> i32; + pub fn sceAtracSetSecondBuffer( + atrac_id: i32, + puc_second_buffer_addr: *mut u8, + ui_second_buffer_byte: u32, + ) -> i32; + + pub fn sceCtrlSetSamplingCycle(cycle: i32) -> i32; + pub fn sceCtrlGetSamplingCycle(pcycle: *mut i32) -> i32; + pub fn sceCtrlSetSamplingMode(mode: CtrlMode) -> i32; + pub fn sceCtrlGetSamplingMode(pmode: *mut i32) -> i32; + pub fn sceCtrlPeekBufferPositive(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlPeekBufferNegative(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlReadBufferPositive(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlReadBufferNegative(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlPeekLatch(latch_data: *mut SceCtrlLatch) -> i32; + pub fn sceCtrlReadLatch(latch_data: *mut SceCtrlLatch) -> i32; + pub fn sceCtrlSetIdleCancelThreshold(idlereset: i32, idleback: i32) -> i32; + pub fn sceCtrlGetIdleCancelThreshold(idlereset: *mut i32, idleback: *mut i32) -> i32; + + pub fn sceDisplaySetMode(mode: DisplayMode, width: usize, height: usize) -> u32; + pub fn sceDisplayGetMode(pmode: *mut i32, pwidth: *mut i32, pheight: *mut i32) -> i32; + pub fn sceDisplaySetFrameBuf( + top_addr: *const u8, + buffer_width: usize, + pixel_format: DisplayPixelFormat, + sync: DisplaySetBufSync, + ) -> u32; + pub fn sceDisplayGetFrameBuf( + top_addr: *mut *mut c_void, + buffer_width: *mut usize, + pixel_format: *mut DisplayPixelFormat, + sync: DisplaySetBufSync, + ) -> i32; + pub fn sceDisplayGetVcount() -> u32; + pub fn sceDisplayWaitVblank() -> i32; + pub fn sceDisplayWaitVblankCB() -> i32; + pub fn sceDisplayWaitVblankStart() -> i32; + pub fn sceDisplayWaitVblankStartCB() -> i32; + pub fn sceDisplayGetAccumulatedHcount() -> i32; + pub fn sceDisplayGetCurrentHcount() -> i32; + pub fn sceDisplayGetFramePerSec() -> f32; + pub fn sceDisplayIsForeground() -> i32; + pub fn sceDisplayIsVblank() -> i32; + + pub fn sceGeEdramGetSize() -> u32; + pub fn sceGeEdramGetAddr() -> *mut u8; + pub fn sceGeEdramSetAddrTranslation(width: i32) -> i32; + pub fn sceGeGetCmd(cmd: i32) -> u32; + pub fn sceGeGetMtx(type_: GeMatrixType, matrix: *mut c_void) -> i32; + pub fn sceGeGetStack(stack_id: i32, stack: *mut GeStack) -> i32; + pub fn sceGeSaveContext(context: *mut GeContext) -> i32; + pub fn sceGeRestoreContext(context: *const GeContext) -> i32; + pub fn sceGeListEnQueue( + list: *const c_void, + stall: *mut c_void, + cbid: i32, + arg: *mut GeListArgs, + ) -> i32; + pub fn sceGeListEnQueueHead( + list: *const c_void, + stall: *mut c_void, + cbid: i32, + arg: *mut GeListArgs, + ) -> i32; + pub fn sceGeListDeQueue(qid: i32) -> i32; + pub fn sceGeListUpdateStallAddr(qid: i32, stall: *mut c_void) -> i32; + pub fn sceGeListSync(qid: i32, sync_type: i32) -> GeListState; + pub fn sceGeDrawSync(sync_type: i32) -> GeListState; + pub fn sceGeBreak(mode: i32, p_param: *mut GeBreakParam) -> i32; + pub fn sceGeContinue() -> i32; + pub fn sceGeSetCallback(cb: *mut GeCallbackData) -> i32; + pub fn sceGeUnsetCallback(cbid: i32) -> i32; + + pub fn sceKernelExitGame(); + pub fn sceKernelRegisterExitCallback(id: SceUid) -> i32; + pub fn sceKernelLoadExec(file: *const u8, param: *mut SceKernelLoadExecParam) -> i32; + + pub fn sceKernelAllocPartitionMemory( + partition: SceSysMemPartitionId, + name: *const u8, + type_: SceSysMemBlockTypes, + size: u32, + addr: *mut c_void, + ) -> SceUid; + pub fn sceKernelGetBlockHeadAddr(blockid: SceUid) -> *mut c_void; + pub fn sceKernelFreePartitionMemory(blockid: SceUid) -> i32; + pub fn sceKernelTotalFreeMemSize() -> usize; + pub fn sceKernelMaxFreeMemSize() -> usize; + pub fn sceKernelDevkitVersion() -> u32; + pub fn sceKernelSetCompiledSdkVersion(version: u32) -> i32; + pub fn sceKernelGetCompiledSdkVersion() -> u32; + + pub fn sceKernelLibcTime(t: *mut i32) -> i32; + pub fn sceKernelLibcClock() -> u32; + pub fn sceKernelLibcGettimeofday(tp: *mut timeval, tzp: *mut timezone) -> i32; + pub fn sceKernelDcacheWritebackAll(); + pub fn sceKernelDcacheWritebackInvalidateAll(); + pub fn sceKernelDcacheWritebackRange(p: *const c_void, size: u32); + pub fn sceKernelDcacheWritebackInvalidateRange(p: *const c_void, size: u32); + pub fn sceKernelDcacheInvalidateRange(p: *const c_void, size: u32); + pub fn sceKernelIcacheInvalidateAll(); + pub fn sceKernelIcacheInvalidateRange(p: *const c_void, size: u32); + pub fn sceKernelUtilsMt19937Init(ctx: *mut SceKernelUtilsMt19937Context, seed: u32) -> i32; + pub fn sceKernelUtilsMt19937UInt(ctx: *mut SceKernelUtilsMt19937Context) -> u32; + pub fn sceKernelUtilsMd5Digest(data: *mut u8, size: u32, digest: *mut u8) -> i32; + pub fn sceKernelUtilsMd5BlockInit(ctx: *mut SceKernelUtilsMd5Context) -> i32; + pub fn sceKernelUtilsMd5BlockUpdate( + ctx: *mut SceKernelUtilsMd5Context, + data: *mut u8, + size: u32, + ) -> i32; + pub fn sceKernelUtilsMd5BlockResult(ctx: *mut SceKernelUtilsMd5Context, digest: *mut u8) + -> i32; + pub fn sceKernelUtilsSha1Digest(data: *mut u8, size: u32, digest: *mut u8) -> i32; + pub fn sceKernelUtilsSha1BlockInit(ctx: *mut SceKernelUtilsSha1Context) -> i32; + pub fn sceKernelUtilsSha1BlockUpdate( + ctx: *mut SceKernelUtilsSha1Context, + data: *mut u8, + size: u32, + ) -> i32; + pub fn sceKernelUtilsSha1BlockResult( + ctx: *mut SceKernelUtilsSha1Context, + digest: *mut u8, + ) -> i32; + + pub fn sceKernelRegisterSubIntrHandler( + int_no: i32, + no: i32, + handler: *mut c_void, + arg: *mut c_void, + ) -> i32; + pub fn sceKernelReleaseSubIntrHandler(int_no: i32, no: i32) -> i32; + pub fn sceKernelEnableSubIntr(int_no: i32, no: i32) -> i32; + pub fn sceKernelDisableSubIntr(int_no: i32, no: i32) -> i32; + pub fn QueryIntrHandlerInfo( + intr_code: SceUid, + sub_intr_code: SceUid, + data: *mut IntrHandlerOptionParam, + ) -> i32; + + pub fn sceKernelCpuSuspendIntr() -> u32; + pub fn sceKernelCpuResumeIntr(flags: u32); + pub fn sceKernelCpuResumeIntrWithSync(flags: u32); + pub fn sceKernelIsCpuIntrSuspended(flags: u32) -> i32; + pub fn sceKernelIsCpuIntrEnable() -> i32; + + pub fn sceKernelLoadModule( + path: *const u8, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelLoadModuleMs( + path: *const u8, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelLoadModuleByID( + fid: SceUid, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelLoadModuleBufferUsbWlan( + buf_size: usize, + buf: *mut c_void, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelStartModule( + mod_id: SceUid, + arg_size: usize, + argp: *mut c_void, + status: *mut i32, + option: *mut SceKernelSMOption, + ) -> i32; + pub fn sceKernelStopModule( + mod_id: SceUid, + arg_size: usize, + argp: *mut c_void, + status: *mut i32, + option: *mut SceKernelSMOption, + ) -> i32; + pub fn sceKernelUnloadModule(mod_id: SceUid) -> i32; + pub fn sceKernelSelfStopUnloadModule(unknown: i32, arg_size: usize, argp: *mut c_void) -> i32; + pub fn sceKernelStopUnloadSelfModule( + arg_size: usize, + argp: *mut c_void, + status: *mut i32, + option: *mut SceKernelSMOption, + ) -> i32; + pub fn sceKernelQueryModuleInfo(mod_id: SceUid, info: *mut SceKernelModuleInfo) -> i32; + pub fn sceKernelGetModuleIdList( + read_buf: *mut SceUid, + read_buf_size: i32, + id_count: *mut i32, + ) -> i32; + + pub fn sceKernelVolatileMemLock(unk: i32, ptr: *mut *mut c_void, size: *mut i32) -> i32; + pub fn sceKernelVolatileMemTryLock(unk: i32, ptr: *mut *mut c_void, size: *mut i32) -> i32; + pub fn sceKernelVolatileMemUnlock(unk: i32) -> i32; + + pub fn sceKernelStdin() -> SceUid; + pub fn sceKernelStdout() -> SceUid; + pub fn sceKernelStderr() -> SceUid; + + pub fn sceKernelGetThreadmanIdType(uid: SceUid) -> SceKernelIdListType; + pub fn sceKernelCreateThread( + name: *const u8, + entry: SceKernelThreadEntry, + init_priority: i32, + stack_size: i32, + attr: i32, + option: *mut SceKernelThreadOptParam, + ) -> SceUid; + pub fn sceKernelDeleteThread(thid: SceUid) -> i32; + pub fn sceKernelStartThread(id: SceUid, arg_len: usize, arg_p: *mut c_void) -> i32; + pub fn sceKernelExitThread(status: i32) -> i32; + pub fn sceKernelExitDeleteThread(status: i32) -> i32; + pub fn sceKernelTerminateThread(thid: SceUid) -> i32; + pub fn sceKernelTerminateDeleteThread(thid: SceUid) -> i32; + pub fn sceKernelSuspendDispatchThread() -> i32; + pub fn sceKernelResumeDispatchThread(state: i32) -> i32; + pub fn sceKernelSleepThread() -> i32; + pub fn sceKernelSleepThreadCB() -> i32; + pub fn sceKernelWakeupThread(thid: SceUid) -> i32; + pub fn sceKernelCancelWakeupThread(thid: SceUid) -> i32; + pub fn sceKernelSuspendThread(thid: SceUid) -> i32; + pub fn sceKernelResumeThread(thid: SceUid) -> i32; + pub fn sceKernelWaitThreadEnd(thid: SceUid, timeout: *mut u32) -> i32; + pub fn sceKernelWaitThreadEndCB(thid: SceUid, timeout: *mut u32) -> i32; + pub fn sceKernelDelayThread(delay: u32) -> i32; + pub fn sceKernelDelayThreadCB(delay: u32) -> i32; + pub fn sceKernelDelaySysClockThread(delay: *mut SceKernelSysClock) -> i32; + pub fn sceKernelDelaySysClockThreadCB(delay: *mut SceKernelSysClock) -> i32; + pub fn sceKernelChangeCurrentThreadAttr(unknown: i32, attr: i32) -> i32; + pub fn sceKernelChangeThreadPriority(thid: SceUid, priority: i32) -> i32; + pub fn sceKernelRotateThreadReadyQueue(priority: i32) -> i32; + pub fn sceKernelReleaseWaitThread(thid: SceUid) -> i32; + pub fn sceKernelGetThreadId() -> i32; + pub fn sceKernelGetThreadCurrentPriority() -> i32; + pub fn sceKernelGetThreadExitStatus(thid: SceUid) -> i32; + pub fn sceKernelCheckThreadStack() -> i32; + pub fn sceKernelGetThreadStackFreeSize(thid: SceUid) -> i32; + pub fn sceKernelReferThreadStatus(thid: SceUid, info: *mut SceKernelThreadInfo) -> i32; + pub fn sceKernelReferThreadRunStatus( + thid: SceUid, + status: *mut SceKernelThreadRunStatus, + ) -> i32; + pub fn sceKernelCreateSema( + name: *const u8, + attr: u32, + init_val: i32, + max_val: i32, + option: *mut SceKernelSemaOptParam, + ) -> SceUid; + pub fn sceKernelDeleteSema(sema_id: SceUid) -> i32; + pub fn sceKernelSignalSema(sema_id: SceUid, signal: i32) -> i32; + pub fn sceKernelWaitSema(sema_id: SceUid, signal: i32, timeout: *mut u32) -> i32; + pub fn sceKernelWaitSemaCB(sema_id: SceUid, signal: i32, timeout: *mut u32) -> i32; + pub fn sceKernelPollSema(sema_id: SceUid, signal: i32) -> i32; + pub fn sceKernelReferSemaStatus(sema_id: SceUid, info: *mut SceKernelSemaInfo) -> i32; + pub fn sceKernelCreateEventFlag( + name: *const u8, + attr: i32, + bits: i32, + opt: *mut SceKernelEventFlagOptParam, + ) -> SceUid; + pub fn sceKernelSetEventFlag(ev_id: SceUid, bits: u32) -> i32; + pub fn sceKernelClearEventFlag(ev_id: SceUid, bits: u32) -> i32; + pub fn sceKernelPollEventFlag(ev_id: SceUid, bits: u32, wait: i32, out_bits: *mut u32) -> i32; + pub fn sceKernelWaitEventFlag( + ev_id: SceUid, + bits: u32, + wait: i32, + out_bits: *mut u32, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelWaitEventFlagCB( + ev_id: SceUid, + bits: u32, + wait: i32, + out_bits: *mut u32, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelDeleteEventFlag(ev_id: SceUid) -> i32; + pub fn sceKernelReferEventFlagStatus(event: SceUid, status: *mut SceKernelEventFlagInfo) + -> i32; + pub fn sceKernelCreateMbx( + name: *const u8, + attr: u32, + option: *mut SceKernelMbxOptParam, + ) -> SceUid; + pub fn sceKernelDeleteMbx(mbx_id: SceUid) -> i32; + pub fn sceKernelSendMbx(mbx_id: SceUid, message: *mut c_void) -> i32; + pub fn sceKernelReceiveMbx(mbx_id: SceUid, message: *mut *mut c_void, timeout: *mut u32) + -> i32; + pub fn sceKernelReceiveMbxCB( + mbx_id: SceUid, + message: *mut *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelPollMbx(mbx_id: SceUid, pmessage: *mut *mut c_void) -> i32; + pub fn sceKernelCancelReceiveMbx(mbx_id: SceUid, num: *mut i32) -> i32; + pub fn sceKernelReferMbxStatus(mbx_id: SceUid, info: *mut SceKernelMbxInfo) -> i32; + pub fn sceKernelSetAlarm( + clock: u32, + handler: SceKernelAlarmHandler, + common: *mut c_void, + ) -> SceUid; + pub fn sceKernelSetSysClockAlarm( + clock: *mut SceKernelSysClock, + handler: *mut SceKernelAlarmHandler, + common: *mut c_void, + ) -> SceUid; + pub fn sceKernelCancelAlarm(alarm_id: SceUid) -> i32; + pub fn sceKernelReferAlarmStatus(alarm_id: SceUid, info: *mut SceKernelAlarmInfo) -> i32; + pub fn sceKernelCreateCallback( + name: *const u8, + func: SceKernelCallbackFunction, + arg: *mut c_void, + ) -> SceUid; + pub fn sceKernelReferCallbackStatus(cb: SceUid, status: *mut SceKernelCallbackInfo) -> i32; + pub fn sceKernelDeleteCallback(cb: SceUid) -> i32; + pub fn sceKernelNotifyCallback(cb: SceUid, arg2: i32) -> i32; + pub fn sceKernelCancelCallback(cb: SceUid) -> i32; + pub fn sceKernelGetCallbackCount(cb: SceUid) -> i32; + pub fn sceKernelCheckCallback() -> i32; + pub fn sceKernelGetThreadmanIdList( + type_: SceKernelIdListType, + read_buf: *mut SceUid, + read_buf_size: i32, + id_count: *mut i32, + ) -> i32; + pub fn sceKernelReferSystemStatus(status: *mut SceKernelSystemStatus) -> i32; + pub fn sceKernelCreateMsgPipe( + name: *const u8, + part: i32, + attr: i32, + unk1: *mut c_void, + opt: *mut c_void, + ) -> SceUid; + pub fn sceKernelDeleteMsgPipe(uid: SceUid) -> i32; + pub fn sceKernelSendMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelSendMsgPipeCB( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelTrySendMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + ) -> i32; + pub fn sceKernelReceiveMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelReceiveMsgPipeCB( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelTryReceiveMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + ) -> i32; + pub fn sceKernelCancelMsgPipe(uid: SceUid, send: *mut i32, recv: *mut i32) -> i32; + pub fn sceKernelReferMsgPipeStatus(uid: SceUid, info: *mut SceKernelMppInfo) -> i32; + pub fn sceKernelCreateVpl( + name: *const u8, + part: i32, + attr: i32, + size: u32, + opt: *mut SceKernelVplOptParam, + ) -> SceUid; + pub fn sceKernelDeleteVpl(uid: SceUid) -> i32; + pub fn sceKernelAllocateVpl( + uid: SceUid, + size: u32, + data: *mut *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelAllocateVplCB( + uid: SceUid, + size: u32, + data: *mut *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelTryAllocateVpl(uid: SceUid, size: u32, data: *mut *mut c_void) -> i32; + pub fn sceKernelFreeVpl(uid: SceUid, data: *mut c_void) -> i32; + pub fn sceKernelCancelVpl(uid: SceUid, num: *mut i32) -> i32; + pub fn sceKernelReferVplStatus(uid: SceUid, info: *mut SceKernelVplInfo) -> i32; + pub fn sceKernelCreateFpl( + name: *const u8, + part: i32, + attr: i32, + size: u32, + blocks: u32, + opt: *mut SceKernelFplOptParam, + ) -> i32; + pub fn sceKernelDeleteFpl(uid: SceUid) -> i32; + pub fn sceKernelAllocateFpl(uid: SceUid, data: *mut *mut c_void, timeout: *mut u32) -> i32; + pub fn sceKernelAllocateFplCB(uid: SceUid, data: *mut *mut c_void, timeout: *mut u32) -> i32; + pub fn sceKernelTryAllocateFpl(uid: SceUid, data: *mut *mut c_void) -> i32; + pub fn sceKernelFreeFpl(uid: SceUid, data: *mut c_void) -> i32; + pub fn sceKernelCancelFpl(uid: SceUid, pnum: *mut i32) -> i32; + pub fn sceKernelReferFplStatus(uid: SceUid, info: *mut SceKernelFplInfo) -> i32; + pub fn sceKernelUSec2SysClock(usec: u32, clock: *mut SceKernelSysClock) -> i32; + pub fn sceKernelUSec2SysClockWide(usec: u32) -> i64; + pub fn sceKernelSysClock2USec( + clock: *mut SceKernelSysClock, + low: *mut u32, + high: *mut u32, + ) -> i32; + pub fn sceKernelSysClock2USecWide(clock: i64, low: *mut u32, high: *mut u32) -> i32; + pub fn sceKernelGetSystemTime(time: *mut SceKernelSysClock) -> i32; + pub fn sceKernelGetSystemTimeWide() -> i64; + pub fn sceKernelGetSystemTimeLow() -> u32; + pub fn sceKernelCreateVTimer(name: *const u8, opt: *mut SceKernelVTimerOptParam) -> SceUid; + pub fn sceKernelDeleteVTimer(uid: SceUid) -> i32; + pub fn sceKernelGetVTimerBase(uid: SceUid, base: *mut SceKernelSysClock) -> i32; + pub fn sceKernelGetVTimerBaseWide(uid: SceUid) -> i64; + pub fn sceKernelGetVTimerTime(uid: SceUid, time: *mut SceKernelSysClock) -> i32; + pub fn sceKernelGetVTimerTimeWide(uid: SceUid) -> i64; + pub fn sceKernelSetVTimerTime(uid: SceUid, time: *mut SceKernelSysClock) -> i32; + pub fn sceKernelSetVTimerTimeWide(uid: SceUid, time: i64) -> i64; + pub fn sceKernelStartVTimer(uid: SceUid) -> i32; + pub fn sceKernelStopVTimer(uid: SceUid) -> i32; + pub fn sceKernelSetVTimerHandler( + uid: SceUid, + time: *mut SceKernelSysClock, + handler: SceKernelVTimerHandler, + common: *mut c_void, + ) -> i32; + pub fn sceKernelSetVTimerHandlerWide( + uid: SceUid, + time: i64, + handler: SceKernelVTimerHandlerWide, + common: *mut c_void, + ) -> i32; + pub fn sceKernelCancelVTimerHandler(uid: SceUid) -> i32; + pub fn sceKernelReferVTimerStatus(uid: SceUid, info: *mut SceKernelVTimerInfo) -> i32; + pub fn sceKernelRegisterThreadEventHandler( + name: *const u8, + thread_id: SceUid, + mask: i32, + handler: SceKernelThreadEventHandler, + common: *mut c_void, + ) -> SceUid; + pub fn sceKernelReleaseThreadEventHandler(uid: SceUid) -> i32; + pub fn sceKernelReferThreadEventHandlerStatus( + uid: SceUid, + info: *mut SceKernelThreadEventHandlerInfo, + ) -> i32; + pub fn sceKernelReferThreadProfiler() -> *mut DebugProfilerRegs; + pub fn sceKernelReferGlobalProfiler() -> *mut DebugProfilerRegs; + + pub fn sceUsbStart(driver_name: *const u8, size: i32, args: *mut c_void) -> i32; + pub fn sceUsbStop(driver_name: *const u8, size: i32, args: *mut c_void) -> i32; + pub fn sceUsbActivate(pid: u32) -> i32; + pub fn sceUsbDeactivate(pid: u32) -> i32; + pub fn sceUsbGetState() -> i32; + pub fn sceUsbGetDrvState(driver_name: *const u8) -> i32; +} + +extern "C" { + pub fn sceUsbCamSetupStill(param: *mut UsbCamSetupStillParam) -> i32; + pub fn sceUsbCamSetupStillEx(param: *mut UsbCamSetupStillExParam) -> i32; + pub fn sceUsbCamStillInputBlocking(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamStillInput(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamStillWaitInputEnd() -> i32; + pub fn sceUsbCamStillPollInputEnd() -> i32; + pub fn sceUsbCamStillCancelInput() -> i32; + pub fn sceUsbCamStillGetInputLength() -> i32; + pub fn sceUsbCamSetupVideo( + param: *mut UsbCamSetupVideoParam, + work_area: *mut c_void, + work_area_size: i32, + ) -> i32; + pub fn sceUsbCamSetupVideoEx( + param: *mut UsbCamSetupVideoExParam, + work_area: *mut c_void, + work_area_size: i32, + ) -> i32; + pub fn sceUsbCamStartVideo() -> i32; + pub fn sceUsbCamStopVideo() -> i32; + pub fn sceUsbCamReadVideoFrameBlocking(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamReadVideoFrame(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamWaitReadVideoFrameEnd() -> i32; + pub fn sceUsbCamPollReadVideoFrameEnd() -> i32; + pub fn sceUsbCamGetReadVideoFrameSize() -> i32; + pub fn sceUsbCamSetSaturation(saturation: i32) -> i32; + pub fn sceUsbCamSetBrightness(brightness: i32) -> i32; + pub fn sceUsbCamSetContrast(contrast: i32) -> i32; + pub fn sceUsbCamSetSharpness(sharpness: i32) -> i32; + pub fn sceUsbCamSetImageEffectMode(effect_mode: UsbCamEffectMode) -> i32; + pub fn sceUsbCamSetEvLevel(exposure_level: UsbCamEvLevel) -> i32; + pub fn sceUsbCamSetReverseMode(reverse_flags: i32) -> i32; + pub fn sceUsbCamSetZoom(zoom: i32) -> i32; + pub fn sceUsbCamGetSaturation(saturation: *mut i32) -> i32; + pub fn sceUsbCamGetBrightness(brightness: *mut i32) -> i32; + pub fn sceUsbCamGetContrast(contrast: *mut i32) -> i32; + pub fn sceUsbCamGetSharpness(sharpness: *mut i32) -> i32; + pub fn sceUsbCamGetImageEffectMode(effect_mode: *mut UsbCamEffectMode) -> i32; + pub fn sceUsbCamGetEvLevel(exposure_level: *mut UsbCamEvLevel) -> i32; + pub fn sceUsbCamGetReverseMode(reverse_flags: *mut i32) -> i32; + pub fn sceUsbCamGetZoom(zoom: *mut i32) -> i32; + pub fn sceUsbCamAutoImageReverseSW(on: i32) -> i32; + pub fn sceUsbCamGetAutoImageReverseState() -> i32; + pub fn sceUsbCamGetLensDirection() -> i32; + + pub fn sceUsbstorBootRegisterNotify(event_flag: SceUid) -> i32; + pub fn sceUsbstorBootUnregisterNotify(event_flag: u32) -> i32; + pub fn sceUsbstorBootSetCapacity(size: u32) -> i32; + + pub fn scePowerRegisterCallback(slot: i32, cbid: SceUid) -> i32; + pub fn scePowerUnregisterCallback(slot: i32) -> i32; + pub fn scePowerIsPowerOnline() -> i32; + pub fn scePowerIsBatteryExist() -> i32; + pub fn scePowerIsBatteryCharging() -> i32; + pub fn scePowerGetBatteryChargingStatus() -> i32; + pub fn scePowerIsLowBattery() -> i32; + pub fn scePowerGetBatteryLifePercent() -> i32; + pub fn scePowerGetBatteryLifeTime() -> i32; + pub fn scePowerGetBatteryTemp() -> i32; + pub fn scePowerGetBatteryElec() -> i32; + pub fn scePowerGetBatteryVolt() -> i32; + pub fn scePowerSetCpuClockFrequency(cpufreq: i32) -> i32; + pub fn scePowerSetBusClockFrequency(busfreq: i32) -> i32; + pub fn scePowerGetCpuClockFrequency() -> i32; + pub fn scePowerGetCpuClockFrequencyInt() -> i32; + pub fn scePowerGetCpuClockFrequencyFloat() -> f32; + pub fn scePowerGetBusClockFrequency() -> i32; + pub fn scePowerGetBusClockFrequencyInt() -> i32; + pub fn scePowerGetBusClockFrequencyFloat() -> f32; + pub fn scePowerSetClockFrequency(pllfreq: i32, cpufreq: i32, busfreq: i32) -> i32; + pub fn scePowerLock(unknown: i32) -> i32; + pub fn scePowerUnlock(unknown: i32) -> i32; + pub fn scePowerTick(t: PowerTick) -> i32; + pub fn scePowerGetIdleTimer() -> i32; + pub fn scePowerIdleTimerEnable(unknown: i32) -> i32; + pub fn scePowerIdleTimerDisable(unknown: i32) -> i32; + pub fn scePowerRequestStandby() -> i32; + pub fn scePowerRequestSuspend() -> i32; + + pub fn sceWlanDevIsPowerOn() -> i32; + pub fn sceWlanGetSwitchState() -> i32; + pub fn sceWlanGetEtherAddr(ether_addr: *mut u8) -> i32; + + pub fn sceWlanDevAttach() -> i32; + pub fn sceWlanDevDetach() -> i32; + + pub fn sceRtcGetTickResolution() -> u32; + pub fn sceRtcGetCurrentTick(tick: *mut u64) -> i32; + pub fn sceRtcGetCurrentClock(tm: *mut ScePspDateTime, tz: i32) -> i32; + pub fn sceRtcGetCurrentClockLocalTime(tm: *mut ScePspDateTime) -> i32; + pub fn sceRtcConvertUtcToLocalTime(tick_utc: *const u64, tick_local: *mut u64) -> i32; + pub fn sceRtcConvertLocalTimeToUTC(tick_local: *const u64, tick_utc: *mut u64) -> i32; + pub fn sceRtcIsLeapYear(year: i32) -> i32; + pub fn sceRtcGetDaysInMonth(year: i32, month: i32) -> i32; + pub fn sceRtcGetDayOfWeek(year: i32, month: i32, day: i32) -> i32; + pub fn sceRtcCheckValid(date: *const ScePspDateTime) -> i32; + pub fn sceRtcSetTick(date: *mut ScePspDateTime, tick: *const u64) -> i32; + pub fn sceRtcGetTick(date: *const ScePspDateTime, tick: *mut u64) -> i32; + pub fn sceRtcCompareTick(tick1: *const u64, tick2: *const u64) -> i32; + pub fn sceRtcTickAddTicks(dest_tick: *mut u64, src_tick: *const u64, num_ticks: u64) -> i32; + pub fn sceRtcTickAddMicroseconds(dest_tick: *mut u64, src_tick: *const u64, num_ms: u64) + -> i32; + pub fn sceRtcTickAddSeconds(dest_tick: *mut u64, src_tick: *const u64, num_seconds: u64) + -> i32; + pub fn sceRtcTickAddMinutes(dest_tick: *mut u64, src_tick: *const u64, num_minutes: u64) + -> i32; + pub fn sceRtcTickAddHours(dest_tick: *mut u64, src_tick: *const u64, num_hours: u64) -> i32; + pub fn sceRtcTickAddDays(dest_tick: *mut u64, src_tick: *const u64, num_days: u64) -> i32; + pub fn sceRtcTickAddWeeks(dest_tick: *mut u64, src_tick: *const u64, num_weeks: u64) -> i32; + pub fn sceRtcTickAddMonths(dest_tick: *mut u64, src_tick: *const u64, num_months: u64) -> i32; + pub fn sceRtcTickAddYears(dest_tick: *mut u64, src_tick: *const u64, num_years: u64) -> i32; + pub fn sceRtcSetTime_t(date: *mut ScePspDateTime, time: u32) -> i32; + pub fn sceRtcGetTime_t(date: *const ScePspDateTime, time: *mut u32) -> i32; + pub fn sceRtcSetTime64_t(date: *mut ScePspDateTime, time: u64) -> i32; + pub fn sceRtcGetTime64_t(date: *const ScePspDateTime, time: *mut u64) -> i32; + pub fn sceRtcSetDosTime(date: *mut ScePspDateTime, dos_time: u32) -> i32; + pub fn sceRtcGetDosTime(date: *mut ScePspDateTime, dos_time: u32) -> i32; + pub fn sceRtcSetWin32FileTime(date: *mut ScePspDateTime, time: *mut u64) -> i32; + pub fn sceRtcGetWin32FileTime(date: *mut ScePspDateTime, time: *mut u64) -> i32; + pub fn sceRtcParseDateTime(dest_tick: *mut u64, date_string: *const u8) -> i32; + pub fn sceRtcFormatRFC3339( + psz_date_time: *mut char, + p_utc: *const u64, + time_zone_minutes: i32, + ) -> i32; + pub fn sceRtcFormatRFC3339LocalTime(psz_date_time: *mut char, p_utc: *const u64) -> i32; + pub fn sceRtcParseRFC3339(p_utc: *mut u64, psz_date_time: *const u8) -> i32; + pub fn sceRtcFormatRFC2822( + psz_date_time: *mut char, + p_utc: *const u64, + time_zone_minutes: i32, + ) -> i32; + pub fn sceRtcFormatRFC2822LocalTime(psz_date_time: *mut char, p_utc: *const u64) -> i32; + + pub fn sceIoOpen(file: *const u8, flags: i32, permissions: IoPermissions) -> SceUid; + pub fn sceIoOpenAsync(file: *const u8, flags: i32, permissions: IoPermissions) -> SceUid; + pub fn sceIoClose(fd: SceUid) -> i32; + pub fn sceIoCloseAsync(fd: SceUid) -> i32; + pub fn sceIoRead(fd: SceUid, data: *mut c_void, size: u32) -> i32; + pub fn sceIoReadAsync(fd: SceUid, data: *mut c_void, size: u32) -> i32; + pub fn sceIoWrite(fd: SceUid, data: *const c_void, size: usize) -> i32; + pub fn sceIoWriteAsync(fd: SceUid, data: *const c_void, size: u32) -> i32; + pub fn sceIoLseek(fd: SceUid, offset: i64, whence: IoWhence) -> i64; + pub fn sceIoLseekAsync(fd: SceUid, offset: i64, whence: IoWhence) -> i32; + pub fn sceIoLseek32(fd: SceUid, offset: i32, whence: IoWhence) -> i32; + pub fn sceIoLseek32Async(fd: SceUid, offset: i32, whence: IoWhence) -> i32; + pub fn sceIoRemove(file: *const u8) -> i32; + pub fn sceIoMkdir(dir: *const u8, mode: IoPermissions) -> i32; + pub fn sceIoRmdir(path: *const u8) -> i32; + pub fn sceIoChdir(path: *const u8) -> i32; + pub fn sceIoRename(oldname: *const u8, newname: *const u8) -> i32; + pub fn sceIoDopen(dirname: *const u8) -> SceUid; + pub fn sceIoDread(fd: SceUid, dir: *mut SceIoDirent) -> i32; + pub fn sceIoDclose(fd: SceUid) -> i32; + pub fn sceIoDevctl( + dev: *const u8, + cmd: u32, + indata: *mut c_void, + inlen: i32, + outdata: *mut c_void, + outlen: i32, + ) -> i32; + pub fn sceIoAssign( + dev1: *const u8, + dev2: *const u8, + dev3: *const u8, + mode: IoAssignPerms, + unk1: *mut c_void, + unk2: i32, + ) -> i32; + pub fn sceIoUnassign(dev: *const u8) -> i32; + pub fn sceIoGetstat(file: *const u8, stat: *mut SceIoStat) -> i32; + pub fn sceIoChstat(file: *const u8, stat: *mut SceIoStat, bits: i32) -> i32; + pub fn sceIoIoctl( + fd: SceUid, + cmd: u32, + indata: *mut c_void, + inlen: i32, + outdata: *mut c_void, + outlen: i32, + ) -> i32; + pub fn sceIoIoctlAsync( + fd: SceUid, + cmd: u32, + indata: *mut c_void, + inlen: i32, + outdata: *mut c_void, + outlen: i32, + ) -> i32; + pub fn sceIoSync(device: *const u8, unk: u32) -> i32; + pub fn sceIoWaitAsync(fd: SceUid, res: *mut i64) -> i32; + pub fn sceIoWaitAsyncCB(fd: SceUid, res: *mut i64) -> i32; + pub fn sceIoPollAsync(fd: SceUid, res: *mut i64) -> i32; + pub fn sceIoGetAsyncStat(fd: SceUid, poll: i32, res: *mut i64) -> i32; + pub fn sceIoCancel(fd: SceUid) -> i32; + pub fn sceIoGetDevType(fd: SceUid) -> i32; + pub fn sceIoChangeAsyncPriority(fd: SceUid, pri: i32) -> i32; + pub fn sceIoSetAsyncCallback(fd: SceUid, cb: SceUid, argp: *mut c_void) -> i32; + + pub fn sceJpegInitMJpeg() -> i32; + pub fn sceJpegFinishMJpeg() -> i32; + pub fn sceJpegCreateMJpeg(width: i32, height: i32) -> i32; + pub fn sceJpegDeleteMJpeg() -> i32; + pub fn sceJpegDecodeMJpeg(jpeg_buf: *mut u8, size: usize, rgba: *mut c_void, unk: u32) -> i32; + + pub fn sceUmdCheckMedium() -> i32; + pub fn sceUmdGetDiscInfo(info: *mut UmdInfo) -> i32; + pub fn sceUmdActivate(unit: i32, drive: *const u8) -> i32; + pub fn sceUmdDeactivate(unit: i32, drive: *const u8) -> i32; + pub fn sceUmdWaitDriveStat(state: i32) -> i32; + pub fn sceUmdWaitDriveStatWithTimer(state: i32, timeout: u32) -> i32; + pub fn sceUmdWaitDriveStatCB(state: i32, timeout: u32) -> i32; + pub fn sceUmdCancelWaitDriveStat() -> i32; + pub fn sceUmdGetDriveStat() -> i32; + pub fn sceUmdGetErrorStat() -> i32; + pub fn sceUmdRegisterUMDCallBack(cbid: i32) -> i32; + pub fn sceUmdUnRegisterUMDCallBack(cbid: i32) -> i32; + pub fn sceUmdReplacePermit() -> i32; + pub fn sceUmdReplaceProhibit() -> i32; + + pub fn sceMpegInit() -> i32; + pub fn sceMpegFinish(); + pub fn sceMpegRingbufferQueryMemSize(packets: i32) -> i32; + pub fn sceMpegRingbufferConstruct( + ringbuffer: *mut SceMpegRingbuffer, + packets: i32, + data: *mut c_void, + size: i32, + callback: SceMpegRingbufferCb, + cb_param: *mut c_void, + ) -> i32; + pub fn sceMpegRingbufferDestruct(ringbuffer: *mut SceMpegRingbuffer); + pub fn sceMpegRingbufferAvailableSize(ringbuffer: *mut SceMpegRingbuffer) -> i32; + pub fn sceMpegRingbufferPut( + ringbuffer: *mut SceMpegRingbuffer, + num_packets: i32, + available: i32, + ) -> i32; + pub fn sceMpegQueryMemSize(unk: i32) -> i32; + pub fn sceMpegCreate( + handle: SceMpeg, + data: *mut c_void, + size: i32, + ringbuffer: *mut SceMpegRingbuffer, + frame_width: i32, + unk1: i32, + unk2: i32, + ) -> i32; + pub fn sceMpegDelete(handle: SceMpeg); + pub fn sceMpegQueryStreamOffset(handle: SceMpeg, buffer: *mut c_void, offset: *mut i32) -> i32; + pub fn sceMpegQueryStreamSize(buffer: *mut c_void, size: *mut i32) -> i32; + pub fn sceMpegRegistStream(handle: SceMpeg, stream_id: i32, unk: i32) -> SceMpegStream; + pub fn sceMpegUnRegistStream(handle: SceMpeg, stream: SceMpegStream); + pub fn sceMpegFlushAllStream(handle: SceMpeg) -> i32; + pub fn sceMpegMallocAvcEsBuf(handle: SceMpeg) -> *mut c_void; + pub fn sceMpegFreeAvcEsBuf(handle: SceMpeg, buf: *mut c_void); + pub fn sceMpegQueryAtracEsSize(handle: SceMpeg, es_size: *mut i32, out_size: *mut i32) -> i32; + pub fn sceMpegInitAu(handle: SceMpeg, es_buffer: *mut c_void, au: *mut SceMpegAu) -> i32; + pub fn sceMpegGetAvcAu( + handle: SceMpeg, + stream: SceMpegStream, + au: *mut SceMpegAu, + unk: *mut i32, + ) -> i32; + pub fn sceMpegAvcDecodeMode(handle: SceMpeg, mode: *mut SceMpegAvcMode) -> i32; + pub fn sceMpegAvcDecode( + handle: SceMpeg, + au: *mut SceMpegAu, + iframe_width: i32, + buffer: *mut c_void, + init: *mut i32, + ) -> i32; + pub fn sceMpegAvcDecodeStop( + handle: SceMpeg, + frame_width: i32, + buffer: *mut c_void, + status: *mut i32, + ) -> i32; + pub fn sceMpegGetAtracAu( + handle: SceMpeg, + stream: SceMpegStream, + au: *mut SceMpegAu, + unk: *mut c_void, + ) -> i32; + pub fn sceMpegAtracDecode( + handle: SceMpeg, + au: *mut SceMpegAu, + buffer: *mut c_void, + init: i32, + ) -> i32; + + pub fn sceMpegBaseYCrCbCopyVme(yuv_buffer: *mut c_void, buffer: *mut i32, type_: i32) -> i32; + pub fn sceMpegBaseCscInit(width: i32) -> i32; + pub fn sceMpegBaseCscVme( + rgb_buffer: *mut c_void, + rgb_buffer2: *mut c_void, + width: i32, + y_cr_cb_buffer: *mut SceMpegYCrCbBuffer, + ) -> i32; + pub fn sceMpegbase_BEA18F91(lli: *mut SceMpegLLI) -> i32; + + pub fn sceHprmPeekCurrentKey(key: *mut i32) -> i32; + pub fn sceHprmPeekLatch(latch: *mut [u32; 4]) -> i32; + pub fn sceHprmReadLatch(latch: *mut [u32; 4]) -> i32; + pub fn sceHprmIsHeadphoneExist() -> i32; + pub fn sceHprmIsRemoteExist() -> i32; + pub fn sceHprmIsMicrophoneExist() -> i32; + + pub fn sceGuDepthBuffer(zbp: *mut c_void, zbw: i32); + pub fn sceGuDispBuffer(width: i32, height: i32, dispbp: *mut c_void, dispbw: i32); + pub fn sceGuDrawBuffer(psm: DisplayPixelFormat, fbp: *mut c_void, fbw: i32); + pub fn sceGuDrawBufferList(psm: DisplayPixelFormat, fbp: *mut c_void, fbw: i32); + pub fn sceGuDisplay(state: bool) -> bool; + pub fn sceGuDepthFunc(function: DepthFunc); + pub fn sceGuDepthMask(mask: i32); + pub fn sceGuDepthOffset(offset: i32); + pub fn sceGuDepthRange(near: i32, far: i32); + pub fn sceGuFog(near: f32, far: f32, color: u32); + pub fn sceGuInit(); + pub fn sceGuTerm(); + pub fn sceGuBreak(mode: i32); + pub fn sceGuContinue(); + pub fn sceGuSetCallback(signal: GuCallbackId, callback: GuCallback) -> GuCallback; + pub fn sceGuSignal(behavior: SignalBehavior, signal: i32); + pub fn sceGuSendCommandf(cmd: GeCommand, argument: f32); + pub fn sceGuSendCommandi(cmd: GeCommand, argument: i32); + pub fn sceGuGetMemory(size: i32) -> *mut c_void; + pub fn sceGuStart(context_type: GuContextType, list: *mut c_void); + pub fn sceGuFinish() -> i32; + pub fn sceGuFinishId(id: u32) -> i32; + pub fn sceGuCallList(list: *const c_void); + pub fn sceGuCallMode(mode: i32); + pub fn sceGuCheckList() -> i32; + pub fn sceGuSendList(mode: GuQueueMode, list: *const c_void, context: *mut GeContext); + pub fn sceGuSwapBuffers() -> *mut c_void; + pub fn sceGuSync(mode: GuSyncMode, behavior: GuSyncBehavior) -> GeListState; + pub fn sceGuDrawArray( + prim: GuPrimitive, + vtype: i32, + count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuBeginObject( + vtype: i32, + count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuEndObject(); + pub fn sceGuSetStatus(state: GuState, status: i32); + pub fn sceGuGetStatus(state: GuState) -> bool; + pub fn sceGuSetAllStatus(status: i32); + pub fn sceGuGetAllStatus() -> i32; + pub fn sceGuEnable(state: GuState); + pub fn sceGuDisable(state: GuState); + pub fn sceGuLight(light: i32, type_: LightType, components: i32, position: &ScePspFVector3); + pub fn sceGuLightAtt(light: i32, atten0: f32, atten1: f32, atten2: f32); + pub fn sceGuLightColor(light: i32, component: i32, color: u32); + pub fn sceGuLightMode(mode: LightMode); + pub fn sceGuLightSpot(light: i32, direction: &ScePspFVector3, exponent: f32, cutoff: f32); + pub fn sceGuClear(flags: i32); + pub fn sceGuClearColor(color: u32); + pub fn sceGuClearDepth(depth: u32); + pub fn sceGuClearStencil(stencil: u32); + pub fn sceGuPixelMask(mask: u32); + pub fn sceGuColor(color: u32); + pub fn sceGuColorFunc(func: ColorFunc, color: u32, mask: u32); + pub fn sceGuColorMaterial(components: i32); + pub fn sceGuAlphaFunc(func: AlphaFunc, value: i32, mask: i32); + pub fn sceGuAmbient(color: u32); + pub fn sceGuAmbientColor(color: u32); + pub fn sceGuBlendFunc(op: BlendOp, src: BlendSrc, dest: BlendDst, src_fix: u32, dest_fix: u32); + pub fn sceGuMaterial(components: i32, color: u32); + pub fn sceGuModelColor(emissive: u32, ambient: u32, diffuse: u32, specular: u32); + pub fn sceGuStencilFunc(func: StencilFunc, ref_: i32, mask: i32); + pub fn sceGuStencilOp(fail: StencilOperation, zfail: StencilOperation, zpass: StencilOperation); + pub fn sceGuSpecular(power: f32); + pub fn sceGuFrontFace(order: FrontFaceDirection); + pub fn sceGuLogicalOp(op: LogicalOperation); + pub fn sceGuSetDither(matrix: &ScePspIMatrix4); + pub fn sceGuShadeModel(mode: ShadingModel); + pub fn sceGuCopyImage( + psm: DisplayPixelFormat, + sx: i32, + sy: i32, + width: i32, + height: i32, + srcw: i32, + src: *mut c_void, + dx: i32, + dy: i32, + destw: i32, + dest: *mut c_void, + ); + pub fn sceGuTexEnvColor(color: u32); + pub fn sceGuTexFilter(min: TextureFilter, mag: TextureFilter); + pub fn sceGuTexFlush(); + pub fn sceGuTexFunc(tfx: TextureEffect, tcc: TextureColorComponent); + pub fn sceGuTexImage( + mipmap: MipmapLevel, + width: i32, + height: i32, + tbw: i32, + tbp: *const c_void, + ); + pub fn sceGuTexLevelMode(mode: TextureLevelMode, bias: f32); + pub fn sceGuTexMapMode(mode: TextureMapMode, a1: u32, a2: u32); + pub fn sceGuTexMode(tpsm: TexturePixelFormat, maxmips: i32, a2: i32, swizzle: i32); + pub fn sceGuTexOffset(u: f32, v: f32); + pub fn sceGuTexProjMapMode(mode: TextureProjectionMapMode); + pub fn sceGuTexScale(u: f32, v: f32); + pub fn sceGuTexSlope(slope: f32); + pub fn sceGuTexSync(); + pub fn sceGuTexWrap(u: GuTexWrapMode, v: GuTexWrapMode); + pub fn sceGuClutLoad(num_blocks: i32, cbp: *const c_void); + pub fn sceGuClutMode(cpsm: ClutPixelFormat, shift: u32, mask: u32, a3: u32); + pub fn sceGuOffset(x: u32, y: u32); + pub fn sceGuScissor(x: i32, y: i32, w: i32, h: i32); + pub fn sceGuViewport(cx: i32, cy: i32, width: i32, height: i32); + pub fn sceGuDrawBezier( + v_type: i32, + u_count: i32, + v_count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuPatchDivide(ulevel: u32, vlevel: u32); + pub fn sceGuPatchFrontFace(a0: u32); + pub fn sceGuPatchPrim(prim: PatchPrimitive); + pub fn sceGuDrawSpline( + v_type: i32, + u_count: i32, + v_count: i32, + u_edge: i32, + v_edge: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuSetMatrix(type_: MatrixMode, matrix: &ScePspFMatrix4); + pub fn sceGuBoneMatrix(index: u32, matrix: &ScePspFMatrix4); + pub fn sceGuMorphWeight(index: i32, weight: f32); + pub fn sceGuDrawArrayN( + primitive_type: GuPrimitive, + v_type: i32, + count: i32, + a3: i32, + indices: *const c_void, + vertices: *const c_void, + ); + + pub fn sceGumDrawArray( + prim: GuPrimitive, + v_type: i32, + count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumDrawArrayN( + prim: GuPrimitive, + v_type: i32, + count: i32, + a3: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumDrawBezier( + v_type: i32, + u_count: i32, + v_count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumDrawSpline( + v_type: i32, + u_count: i32, + v_count: i32, + u_edge: i32, + v_edge: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumFastInverse(); + pub fn sceGumFullInverse(); + pub fn sceGumLoadIdentity(); + pub fn sceGumLoadMatrix(m: &ScePspFMatrix4); + pub fn sceGumLookAt(eye: &ScePspFVector3, center: &ScePspFVector3, up: &ScePspFVector3); + pub fn sceGumMatrixMode(mode: MatrixMode); + pub fn sceGumMultMatrix(m: &ScePspFMatrix4); + pub fn sceGumOrtho(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32); + pub fn sceGumPerspective(fovy: f32, aspect: f32, near: f32, far: f32); + pub fn sceGumPopMatrix(); + pub fn sceGumPushMatrix(); + pub fn sceGumRotateX(angle: f32); + pub fn sceGumRotateY(angle: f32); + pub fn sceGumRotateZ(angle: f32); + pub fn sceGumRotateXYZ(v: &ScePspFVector3); + pub fn sceGumRotateZYX(v: &ScePspFVector3); + pub fn sceGumScale(v: &ScePspFVector3); + pub fn sceGumStoreMatrix(m: &mut ScePspFMatrix4); + pub fn sceGumTranslate(v: &ScePspFVector3); + pub fn sceGumUpdateMatrix(); + + pub fn sceMp3ReserveMp3Handle(args: *mut SceMp3InitArg) -> i32; + pub fn sceMp3ReleaseMp3Handle(handle: Mp3Handle) -> i32; + pub fn sceMp3InitResource() -> i32; + pub fn sceMp3TermResource() -> i32; + pub fn sceMp3Init(handle: Mp3Handle) -> i32; + pub fn sceMp3Decode(handle: Mp3Handle, dst: *mut *mut i16) -> i32; + pub fn sceMp3GetInfoToAddStreamData( + handle: Mp3Handle, + dst: *mut *mut u8, + to_write: *mut i32, + src_pos: *mut i32, + ) -> i32; + pub fn sceMp3NotifyAddStreamData(handle: Mp3Handle, size: i32) -> i32; + pub fn sceMp3CheckStreamDataNeeded(handle: Mp3Handle) -> i32; + pub fn sceMp3SetLoopNum(handle: Mp3Handle, loop_: i32) -> i32; + pub fn sceMp3GetLoopNum(handle: Mp3Handle) -> i32; + pub fn sceMp3GetSumDecodedSample(handle: Mp3Handle) -> i32; + pub fn sceMp3GetMaxOutputSample(handle: Mp3Handle) -> i32; + pub fn sceMp3GetSamplingRate(handle: Mp3Handle) -> i32; + pub fn sceMp3GetBitRate(handle: Mp3Handle) -> i32; + pub fn sceMp3GetMp3ChannelNum(handle: Mp3Handle) -> i32; + pub fn sceMp3ResetPlayPosition(handle: Mp3Handle) -> i32; + + pub fn sceRegOpenRegistry(reg: *mut Key, mode: i32, handle: *mut RegHandle) -> i32; + pub fn sceRegFlushRegistry(handle: RegHandle) -> i32; + pub fn sceRegCloseRegistry(handle: RegHandle) -> i32; + pub fn sceRegOpenCategory( + handle: RegHandle, + name: *const u8, + mode: i32, + dir_handle: *mut RegHandle, + ) -> i32; + pub fn sceRegRemoveCategory(handle: RegHandle, name: *const u8) -> i32; + pub fn sceRegCloseCategory(dir_handle: RegHandle) -> i32; + pub fn sceRegFlushCategory(dir_handle: RegHandle) -> i32; + pub fn sceRegGetKeyInfo( + dir_handle: RegHandle, + name: *const u8, + key_handle: *mut RegHandle, + type_: *mut KeyType, + size: *mut usize, + ) -> i32; + pub fn sceRegGetKeyInfoByName( + dir_handle: RegHandle, + name: *const u8, + type_: *mut KeyType, + size: *mut usize, + ) -> i32; + pub fn sceRegGetKeyValue( + dir_handle: RegHandle, + key_handle: RegHandle, + buf: *mut c_void, + size: usize, + ) -> i32; + pub fn sceRegGetKeyValueByName( + dir_handle: RegHandle, + name: *const u8, + buf: *mut c_void, + size: usize, + ) -> i32; + pub fn sceRegSetKeyValue( + dir_handle: RegHandle, + name: *const u8, + buf: *const c_void, + size: usize, + ) -> i32; + pub fn sceRegGetKeysNum(dir_handle: RegHandle, num: *mut i32) -> i32; + pub fn sceRegGetKeys(dir_handle: RegHandle, buf: *mut u8, num: i32) -> i32; + pub fn sceRegCreateKey(dir_handle: RegHandle, name: *const u8, type_: i32, size: usize) -> i32; + pub fn sceRegRemoveRegistry(key: *mut Key) -> i32; + + pub fn sceOpenPSIDGetOpenPSID(openpsid: *mut OpenPSID) -> i32; + + pub fn sceUtilityMsgDialogInitStart(params: *mut UtilityMsgDialogParams) -> i32; + pub fn sceUtilityMsgDialogShutdownStart(); + pub fn sceUtilityMsgDialogGetStatus() -> i32; + pub fn sceUtilityMsgDialogUpdate(n: i32); + pub fn sceUtilityMsgDialogAbort() -> i32; + pub fn sceUtilityNetconfInitStart(data: *mut UtilityNetconfData) -> i32; + pub fn sceUtilityNetconfShutdownStart() -> i32; + pub fn sceUtilityNetconfUpdate(unknown: i32) -> i32; + pub fn sceUtilityNetconfGetStatus() -> i32; + pub fn sceUtilityCheckNetParam(id: i32) -> i32; + pub fn sceUtilityGetNetParam(conf: i32, param: NetParam, data: *mut UtilityNetData) -> i32; + pub fn sceUtilitySavedataInitStart(params: *mut SceUtilitySavedataParam) -> i32; + pub fn sceUtilitySavedataGetStatus() -> i32; + pub fn sceUtilitySavedataShutdownStart() -> i32; + pub fn sceUtilitySavedataUpdate(unknown: i32); + pub fn sceUtilityGameSharingInitStart(params: *mut UtilityGameSharingParams) -> i32; + pub fn sceUtilityGameSharingShutdownStart(); + pub fn sceUtilityGameSharingGetStatus() -> i32; + pub fn sceUtilityGameSharingUpdate(n: i32); + pub fn sceUtilityHtmlViewerInitStart(params: *mut UtilityHtmlViewerParam) -> i32; + pub fn sceUtilityHtmlViewerShutdownStart() -> i32; + pub fn sceUtilityHtmlViewerUpdate(n: i32) -> i32; + pub fn sceUtilityHtmlViewerGetStatus() -> i32; + pub fn sceUtilitySetSystemParamInt(id: SystemParamId, value: i32) -> i32; + pub fn sceUtilitySetSystemParamString(id: SystemParamId, str: *const u8) -> i32; + pub fn sceUtilityGetSystemParamInt(id: SystemParamId, value: *mut i32) -> i32; + pub fn sceUtilityGetSystemParamString(id: SystemParamId, str: *mut u8, len: i32) -> i32; + pub fn sceUtilityOskInitStart(params: *mut SceUtilityOskParams) -> i32; + pub fn sceUtilityOskShutdownStart() -> i32; + pub fn sceUtilityOskUpdate(n: i32) -> i32; + pub fn sceUtilityOskGetStatus() -> i32; + pub fn sceUtilityLoadNetModule(module: NetModule) -> i32; + pub fn sceUtilityUnloadNetModule(module: NetModule) -> i32; + pub fn sceUtilityLoadAvModule(module: AvModule) -> i32; + pub fn sceUtilityUnloadAvModule(module: AvModule) -> i32; + pub fn sceUtilityLoadUsbModule(module: UsbModule) -> i32; + pub fn sceUtilityUnloadUsbModule(module: UsbModule) -> i32; + pub fn sceUtilityLoadModule(module: Module) -> i32; + pub fn sceUtilityUnloadModule(module: Module) -> i32; + pub fn sceUtilityCreateNetParam(conf: i32) -> i32; + pub fn sceUtilitySetNetParam(param: NetParam, val: *const c_void) -> i32; + pub fn sceUtilityCopyNetParam(src: i32, dest: i32) -> i32; + pub fn sceUtilityDeleteNetParam(conf: i32) -> i32; + + pub fn sceNetInit( + poolsize: i32, + calloutprio: i32, + calloutstack: i32, + netintrprio: i32, + netintrstack: i32, + ) -> i32; + pub fn sceNetTerm() -> i32; + pub fn sceNetFreeThreadinfo(thid: i32) -> i32; + pub fn sceNetThreadAbort(thid: i32) -> i32; + pub fn sceNetEtherStrton(name: *mut u8, mac: *mut u8); + pub fn sceNetEtherNtostr(mac: *mut u8, name: *mut u8); + pub fn sceNetGetLocalEtherAddr(mac: *mut u8) -> i32; + pub fn sceNetGetMallocStat(stat: *mut SceNetMallocStat) -> i32; + + pub fn sceNetAdhocctlInit( + stacksize: i32, + priority: i32, + adhoc_id: *mut SceNetAdhocctlAdhocId, + ) -> i32; + pub fn sceNetAdhocctlTerm() -> i32; + pub fn sceNetAdhocctlConnect(name: *const u8) -> i32; + pub fn sceNetAdhocctlDisconnect() -> i32; + pub fn sceNetAdhocctlGetState(event: *mut i32) -> i32; + pub fn sceNetAdhocctlCreate(name: *const u8) -> i32; + pub fn sceNetAdhocctlJoin(scaninfo: *mut SceNetAdhocctlScanInfo) -> i32; + pub fn sceNetAdhocctlGetAdhocId(id: *mut SceNetAdhocctlAdhocId) -> i32; + pub fn sceNetAdhocctlCreateEnterGameMode( + name: *const u8, + unknown: i32, + num: i32, + macs: *mut u8, + timeout: u32, + unknown2: i32, + ) -> i32; + pub fn sceNetAdhocctlJoinEnterGameMode( + name: *const u8, + hostmac: *mut u8, + timeout: u32, + unknown: i32, + ) -> i32; + pub fn sceNetAdhocctlGetGameModeInfo(gamemodeinfo: *mut SceNetAdhocctlGameModeInfo) -> i32; + pub fn sceNetAdhocctlExitGameMode() -> i32; + pub fn sceNetAdhocctlGetPeerList(length: *mut i32, buf: *mut c_void) -> i32; + pub fn sceNetAdhocctlGetPeerInfo( + mac: *mut u8, + size: i32, + peerinfo: *mut SceNetAdhocctlPeerInfo, + ) -> i32; + pub fn sceNetAdhocctlScan() -> i32; + pub fn sceNetAdhocctlGetScanInfo(length: *mut i32, buf: *mut c_void) -> i32; + pub fn sceNetAdhocctlAddHandler(handler: SceNetAdhocctlHandler, unknown: *mut c_void) -> i32; + pub fn sceNetAdhocctlDelHandler(id: i32) -> i32; + pub fn sceNetAdhocctlGetNameByAddr(mac: *mut u8, nickname: *mut u8) -> i32; + pub fn sceNetAdhocctlGetAddrByName( + nickname: *mut u8, + length: *mut i32, + buf: *mut c_void, + ) -> i32; + pub fn sceNetAdhocctlGetParameter(params: *mut SceNetAdhocctlParams) -> i32; + + pub fn sceNetAdhocInit() -> i32; + pub fn sceNetAdhocTerm() -> i32; + pub fn sceNetAdhocPdpCreate(mac: *mut u8, port: u16, buf_size: u32, unk1: i32) -> i32; + pub fn sceNetAdhocPdpDelete(id: i32, unk1: i32) -> i32; + pub fn sceNetAdhocPdpSend( + id: i32, + dest_mac_addr: *mut u8, + port: u16, + data: *mut c_void, + len: u32, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPdpRecv( + id: i32, + src_mac_addr: *mut u8, + port: *mut u16, + data: *mut c_void, + data_length: *mut c_void, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocGetPdpStat(size: *mut i32, stat: *mut SceNetAdhocPdpStat) -> i32; + pub fn sceNetAdhocGameModeCreateMaster(data: *mut c_void, size: i32) -> i32; + pub fn sceNetAdhocGameModeCreateReplica(mac: *mut u8, data: *mut c_void, size: i32) -> i32; + pub fn sceNetAdhocGameModeUpdateMaster() -> i32; + pub fn sceNetAdhocGameModeUpdateReplica(id: i32, unk1: i32) -> i32; + pub fn sceNetAdhocGameModeDeleteMaster() -> i32; + pub fn sceNetAdhocGameModeDeleteReplica(id: i32) -> i32; + pub fn sceNetAdhocPtpOpen( + srcmac: *mut u8, + srcport: u16, + destmac: *mut u8, + destport: u16, + buf_size: u32, + delay: u32, + count: i32, + unk1: i32, + ) -> i32; + pub fn sceNetAdhocPtpConnect(id: i32, timeout: u32, nonblock: i32) -> i32; + pub fn sceNetAdhocPtpListen( + srcmac: *mut u8, + srcport: u16, + buf_size: u32, + delay: u32, + count: i32, + queue: i32, + unk1: i32, + ) -> i32; + pub fn sceNetAdhocPtpAccept( + id: i32, + mac: *mut u8, + port: *mut u16, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPtpSend( + id: i32, + data: *mut c_void, + data_size: *mut i32, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPtpRecv( + id: i32, + data: *mut c_void, + data_size: *mut i32, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPtpFlush(id: i32, timeout: u32, nonblock: i32) -> i32; + pub fn sceNetAdhocPtpClose(id: i32, unk1: i32) -> i32; + pub fn sceNetAdhocGetPtpStat(size: *mut i32, stat: *mut SceNetAdhocPtpStat) -> i32; +} + +extern "C" { + pub fn sceNetAdhocMatchingInit(memsize: i32) -> i32; + pub fn sceNetAdhocMatchingTerm() -> i32; + pub fn sceNetAdhocMatchingCreate( + mode: AdhocMatchingMode, + max_peers: i32, + port: u16, + buf_size: i32, + hello_delay: u32, + ping_delay: u32, + init_count: i32, + msg_delay: u32, + callback: AdhocMatchingCallback, + ) -> i32; + pub fn sceNetAdhocMatchingDelete(matching_id: i32) -> i32; + pub fn sceNetAdhocMatchingStart( + matching_id: i32, + evth_pri: i32, + evth_stack: i32, + inth_pri: i32, + inth_stack: i32, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingStop(matching_id: i32) -> i32; + pub fn sceNetAdhocMatchingSelectTarget( + matching_id: i32, + mac: *mut u8, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingCancelTarget(matching_id: i32, mac: *mut u8) -> i32; + pub fn sceNetAdhocMatchingCancelTargetWithOpt( + matching_id: i32, + mac: *mut u8, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingSendData( + matching_id: i32, + mac: *mut u8, + data_len: i32, + data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingAbortSendData(matching_id: i32, mac: *mut u8) -> i32; + pub fn sceNetAdhocMatchingSetHelloOpt( + matching_id: i32, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingGetHelloOpt( + matching_id: i32, + opt_len: *mut i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingGetMembers( + matching_id: i32, + length: *mut i32, + buf: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingGetPoolMaxAlloc() -> i32; + pub fn sceNetAdhocMatchingGetPoolStat(poolstat: *mut AdhocPoolStat) -> i32; +} + +extern "C" { + pub fn sceNetApctlInit(stack_size: i32, init_priority: i32) -> i32; + pub fn sceNetApctlTerm() -> i32; + pub fn sceNetApctlGetInfo(code: ApctlInfo, pinfo: *mut SceNetApctlInfo) -> i32; + pub fn sceNetApctlAddHandler(handler: SceNetApctlHandler, parg: *mut c_void) -> i32; + pub fn sceNetApctlDelHandler(handler_id: i32) -> i32; + pub fn sceNetApctlConnect(conn_index: i32) -> i32; + pub fn sceNetApctlDisconnect() -> i32; + pub fn sceNetApctlGetState(pstate: *mut ApctlState) -> i32; + + pub fn sceNetInetInit() -> i32; + pub fn sceNetInetTerm() -> i32; + pub fn sceNetInetAccept(s: i32, addr: *mut sockaddr, addr_len: *mut socklen_t) -> i32; + pub fn sceNetInetBind(s: i32, my_addr: *const sockaddr, addr_len: socklen_t) -> i32; + pub fn sceNetInetConnect(s: i32, serv_addr: *const sockaddr, addr_len: socklen_t) -> i32; + pub fn sceNetInetGetsockopt( + s: i32, + level: i32, + opt_name: i32, + opt_val: *mut c_void, + optl_en: *mut socklen_t, + ) -> i32; + pub fn sceNetInetListen(s: i32, backlog: i32) -> i32; + pub fn sceNetInetRecv(s: i32, buf: *mut c_void, len: usize, flags: i32) -> usize; + pub fn sceNetInetRecvfrom( + s: i32, + buf: *mut c_void, + flags: usize, + arg1: i32, + from: *mut sockaddr, + from_len: *mut socklen_t, + ) -> usize; + pub fn sceNetInetSend(s: i32, buf: *const c_void, len: usize, flags: i32) -> usize; + pub fn sceNetInetSendto( + s: i32, + buf: *const c_void, + len: usize, + flags: i32, + to: *const sockaddr, + to_len: socklen_t, + ) -> usize; + pub fn sceNetInetSetsockopt( + s: i32, + level: i32, + opt_name: i32, + opt_val: *const c_void, + opt_len: socklen_t, + ) -> i32; + pub fn sceNetInetShutdown(s: i32, how: i32) -> i32; + pub fn sceNetInetSocket(domain: i32, type_: i32, protocol: i32) -> i32; + pub fn sceNetInetClose(s: i32) -> i32; + pub fn sceNetInetGetErrno() -> i32; + + pub fn sceSslInit(unknown1: i32) -> i32; + pub fn sceSslEnd() -> i32; + pub fn sceSslGetUsedMemoryMax(memory: *mut u32) -> i32; + pub fn sceSslGetUsedMemoryCurrent(memory: *mut u32) -> i32; + + pub fn sceHttpInit(unknown1: u32) -> i32; + pub fn sceHttpEnd() -> i32; + pub fn sceHttpCreateTemplate(agent: *mut u8, unknown1: i32, unknown2: i32) -> i32; + pub fn sceHttpDeleteTemplate(templateid: i32) -> i32; + pub fn sceHttpCreateConnection( + templateid: i32, + host: *mut u8, + unknown1: *mut u8, + port: u16, + unknown2: i32, + ) -> i32; + pub fn sceHttpCreateConnectionWithURL(templateid: i32, url: *const u8, unknown1: i32) -> i32; + pub fn sceHttpDeleteConnection(connection_id: i32) -> i32; + pub fn sceHttpCreateRequest( + connection_id: i32, + method: HttpMethod, + path: *mut u8, + content_length: u64, + ) -> i32; + pub fn sceHttpCreateRequestWithURL( + connection_id: i32, + method: HttpMethod, + url: *mut u8, + content_length: u64, + ) -> i32; + pub fn sceHttpDeleteRequest(request_id: i32) -> i32; + pub fn sceHttpSendRequest(request_id: i32, data: *mut c_void, data_size: u32) -> i32; + pub fn sceHttpAbortRequest(request_id: i32) -> i32; + pub fn sceHttpReadData(request_id: i32, data: *mut c_void, data_size: u32) -> i32; + pub fn sceHttpGetContentLength(request_id: i32, content_length: *mut u64) -> i32; + pub fn sceHttpGetStatusCode(request_id: i32, status_code: *mut i32) -> i32; + pub fn sceHttpSetResolveTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpSetResolveRetry(id: i32, count: i32) -> i32; + pub fn sceHttpSetConnectTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpSetSendTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpSetRecvTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpEnableKeepAlive(id: i32) -> i32; + pub fn sceHttpDisableKeepAlive(id: i32) -> i32; + pub fn sceHttpEnableRedirect(id: i32) -> i32; + pub fn sceHttpDisableRedirect(id: i32) -> i32; + pub fn sceHttpEnableCookie(id: i32) -> i32; + pub fn sceHttpDisableCookie(id: i32) -> i32; + pub fn sceHttpSaveSystemCookie() -> i32; + pub fn sceHttpLoadSystemCookie() -> i32; + pub fn sceHttpAddExtraHeader(id: i32, name: *mut u8, value: *mut u8, unknown1: i32) -> i32; + pub fn sceHttpDeleteHeader(id: i32, name: *const u8) -> i32; + pub fn sceHttpsInit(unknown1: i32, unknown2: i32, unknown3: i32, unknown4: i32) -> i32; + pub fn sceHttpsEnd() -> i32; + pub fn sceHttpsLoadDefaultCert(unknown1: i32, unknown2: i32) -> i32; + pub fn sceHttpDisableAuth(id: i32) -> i32; + pub fn sceHttpDisableCache(id: i32) -> i32; + pub fn sceHttpEnableAuth(id: i32) -> i32; + pub fn sceHttpEnableCache(id: i32) -> i32; + pub fn sceHttpEndCache() -> i32; + pub fn sceHttpGetAllHeader(request: i32, header: *mut *mut u8, header_size: *mut u32) -> i32; + pub fn sceHttpGetNetworkErrno(request: i32, err_num: *mut i32) -> i32; + pub fn sceHttpGetProxy( + id: i32, + activate_flag: *mut i32, + mode: *mut i32, + proxy_host: *mut u8, + len: usize, + proxy_port: *mut u16, + ) -> i32; + pub fn sceHttpInitCache(max_size: usize) -> i32; + pub fn sceHttpSetAuthInfoCB(id: i32, cbfunc: HttpPasswordCB) -> i32; + pub fn sceHttpSetProxy( + id: i32, + activate_flag: i32, + mode: i32, + new_proxy_host: *const u8, + new_proxy_port: u16, + ) -> i32; + pub fn sceHttpSetResHeaderMaxSize(id: i32, header_size: u32) -> i32; + pub fn sceHttpSetMallocFunction( + malloc_func: HttpMallocFunction, + free_func: HttpFreeFunction, + realloc_func: HttpReallocFunction, + ) -> i32; + + pub fn sceNetResolverInit() -> i32; + pub fn sceNetResolverCreate(rid: *mut i32, buf: *mut c_void, buf_length: u32) -> i32; + pub fn sceNetResolverDelete(rid: i32) -> i32; + pub fn sceNetResolverStartNtoA( + rid: i32, + hostname: *const u8, + addr: *mut in_addr, + timeout: u32, + retry: i32, + ) -> i32; + pub fn sceNetResolverStartAtoN( + rid: i32, + addr: *const in_addr, + hostname: *mut u8, + hostname_len: u32, + timeout: u32, + retry: i32, + ) -> i32; + pub fn sceNetResolverStop(rid: i32) -> i32; + pub fn sceNetResolverTerm() -> i32; +} diff --git a/utshell-0.5.0/vendor/libc/src/sgx.rs b/utshell-0.5.0/vendor/libc/src/sgx.rs new file mode 100644 index 00000000..7da62693 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/sgx.rs @@ -0,0 +1,47 @@ +//! SGX C types definition + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/solid/aarch64.rs b/utshell-0.5.0/vendor/libc/src/solid/aarch64.rs new file mode 100644 index 00000000..ceabea39 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/solid/aarch64.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/utshell-0.5.0/vendor/libc/src/solid/arm.rs b/utshell-0.5.0/vendor/libc/src/solid/arm.rs new file mode 100644 index 00000000..04cc1542 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/solid/arm.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = u32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/utshell-0.5.0/vendor/libc/src/solid/mod.rs b/utshell-0.5.0/vendor/libc/src/solid/mod.rs new file mode 100644 index 00000000..f0f2ae89 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/solid/mod.rs @@ -0,0 +1,904 @@ +//! Interface to the [SOLID] C library +//! +//! [SOLID]: https://solid.kmckk.com/ + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type uintptr_t = usize; +pub type intptr_t = isize; +pub type ptrdiff_t = isize; +pub type size_t = ::uintptr_t; +pub type ssize_t = ::intptr_t; + +pub type clock_t = c_uint; +pub type time_t = i64; +pub type clockid_t = c_int; +pub type timer_t = c_int; +pub type suseconds_t = c_int; +pub type useconds_t = c_uint; + +pub type sighandler_t = size_t; + +// sys/ansi.h +pub type __caddr_t = *mut c_char; +pub type __gid_t = u32; +pub type __in_addr_t = u32; +pub type __in_port_t = u16; +pub type __mode_t = u32; +pub type __off_t = i64; +pub type __pid_t = i32; +pub type __sa_family_t = u8; +pub type __socklen_t = c_uint; +pub type __uid_t = u32; +pub type __fsblkcnt_t = u64; +pub type __fsfilcnt_t = u64; + +// locale.h +pub type locale_t = usize; + +// nl_types.h +pub type nl_item = c_long; + +// sys/types.h +pub type __va_list = *mut c_char; +pub type u_int8_t = u8; +pub type u_int16_t = u16; +pub type u_int32_t = u32; +pub type u_int64_t = u64; +pub type u_char = c_uchar; +pub type u_short = c_ushort; +pub type u_int = c_uint; +pub type u_long = c_ulong; +pub type unchar = c_uchar; +pub type ushort = c_ushort; +pub type uint = c_uint; +pub type ulong = c_ulong; +pub type u_quad_t = u64; +pub type quad_t = i64; +pub type qaddr_t = *mut quad_t; +pub type longlong_t = i64; +pub type u_longlong_t = u64; +pub type blkcnt_t = i64; +pub type blksize_t = i32; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +pub type caddr_t = __caddr_t; +pub type daddr_t = i64; +pub type dev_t = u64; +pub type fixpt_t = u32; +pub type gid_t = __gid_t; +pub type idtype_t = c_int; +pub type id_t = u32; +pub type ino_t = u64; +pub type key_t = c_long; +pub type mode_t = __mode_t; +pub type nlink_t = u32; +pub type off_t = __off_t; +pub type pid_t = __pid_t; +pub type lwpid_t = i32; +pub type rlim_t = u64; +pub type segsz_t = i32; +pub type swblk_t = i32; +pub type mqd_t = c_int; +pub type cpuid_t = c_ulong; +pub type psetid_t = c_int; + +s! { + // stat.h + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: c_short, + pub st_nlink: c_short, + pub st_uid: c_short, + pub st_gid: c_short, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_atime: time_t, + pub st_mtime: time_t, + pub st_ctime: time_t, + pub st_blksize: blksize_t, + } + + // time.h + pub struct tm { + pub tm_sec: c_int, + pub tm_min: c_int, + pub tm_hour: c_int, + pub tm_mday: c_int, + pub tm_mon: c_int, + pub tm_year: c_int, + pub tm_wday: c_int, + pub tm_yday: c_int, + pub tm_isdst: c_int, + pub tm_gmtoff: c_long, + pub tm_zone: *mut c_char, + } + + // stdlib.h + pub struct qdiv_t { + pub quot: quad_t, + pub rem: quad_t, + } + pub struct lldiv_t { + pub quot: c_longlong, + pub rem: c_longlong, + } + pub struct div_t { + pub quot: c_int, + pub rem: c_int, + } + pub struct ldiv_t { + pub quot: c_long, + pub rem: c_long, + } + + // locale.h + pub struct lconv { + pub decimal_point: *mut c_char, + pub thousands_sep: *mut c_char, + pub grouping: *mut c_char, + pub int_curr_symbol: *mut c_char, + pub currency_symbol: *mut c_char, + pub mon_decimal_point: *mut c_char, + pub mon_thousands_sep: *mut c_char, + pub mon_grouping: *mut c_char, + pub positive_sign: *mut c_char, + pub negative_sign: *mut c_char, + pub int_frac_digits: c_char, + pub frac_digits: c_char, + pub p_cs_precedes: c_char, + pub p_sep_by_space: c_char, + pub n_cs_precedes: c_char, + pub n_sep_by_space: c_char, + pub p_sign_posn: c_char, + pub n_sign_posn: c_char, + pub int_p_cs_precedes: c_char, + pub int_n_cs_precedes: c_char, + pub int_p_sep_by_space: c_char, + pub int_n_sep_by_space: c_char, + pub int_p_sign_posn: c_char, + pub int_n_sign_posn: c_char, + } + + pub struct iovec { + pub iov_base: *mut c_void, + pub iov_len: size_t, + } + + pub struct timeval { + pub tv_sec: c_long, + pub tv_usec: c_long, + } +} + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +pub const EXIT_FAILURE: c_int = 1; +pub const EXIT_SUCCESS: c_int = 0; +pub const RAND_MAX: c_int = 0x7fffffff; +pub const EOF: c_int = -1; +pub const SEEK_SET: c_int = 0; +pub const SEEK_CUR: c_int = 1; +pub const SEEK_END: c_int = 2; +pub const _IOFBF: c_int = 0; +pub const _IONBF: c_int = 2; +pub const _IOLBF: c_int = 1; +pub const BUFSIZ: c_uint = 1024; +pub const FOPEN_MAX: c_uint = 20; +pub const FILENAME_MAX: c_uint = 1024; + +pub const O_RDONLY: c_int = 1; +pub const O_WRONLY: c_int = 2; +pub const O_RDWR: c_int = 4; +pub const O_APPEND: c_int = 8; +pub const O_CREAT: c_int = 0x10; +pub const O_EXCL: c_int = 0x400; +pub const O_TEXT: c_int = 0x100; +pub const O_BINARY: c_int = 0x200; +pub const O_TRUNC: c_int = 0x20; +pub const S_IEXEC: c_short = 0x0040; +pub const S_IWRITE: c_short = 0x0080; +pub const S_IREAD: c_short = 0x0100; +pub const S_IFCHR: c_short = 0x2000; +pub const S_IFDIR: c_short = 0x4000; +pub const S_IFMT: c_short = 0o160000; +pub const S_IFIFO: c_short = 0o0010000; +pub const S_IFBLK: c_short = 0o0060000; +pub const S_IFREG: c_short = 0o0100000; + +pub const LC_ALL: c_int = 0; +pub const LC_COLLATE: c_int = 1; +pub const LC_CTYPE: c_int = 2; +pub const LC_MONETARY: c_int = 3; +pub const LC_NUMERIC: c_int = 4; +pub const LC_TIME: c_int = 5; +pub const LC_MESSAGES: c_int = 6; +pub const _LC_LAST: c_int = 7; + +pub const EPERM: c_int = 1; +pub const ENOENT: c_int = 2; +pub const ESRCH: c_int = 3; +pub const EINTR: c_int = 4; +pub const EIO: c_int = 5; +pub const ENXIO: c_int = 6; +pub const E2BIG: c_int = 7; +pub const ENOEXEC: c_int = 8; +pub const EBADF: c_int = 9; +pub const ECHILD: c_int = 10; +pub const EAGAIN: c_int = 11; +pub const ENOMEM: c_int = 12; +pub const EACCES: c_int = 13; +pub const EFAULT: c_int = 14; +pub const ENOTBLK: c_int = 15; +pub const EBUSY: c_int = 16; +pub const EEXIST: c_int = 17; +pub const EXDEV: c_int = 18; +pub const ENODEV: c_int = 19; +pub const ENOTDIR: c_int = 20; +pub const EISDIR: c_int = 21; +pub const EINVAL: c_int = 22; +pub const ENFILE: c_int = 23; +pub const EMFILE: c_int = 24; +pub const ENOTTY: c_int = 25; +pub const ETXTBSY: c_int = 26; +pub const EFBIG: c_int = 27; +pub const ENOSPC: c_int = 28; +pub const ESPIPE: c_int = 29; +pub const EROFS: c_int = 30; +pub const EMLINK: c_int = 31; +pub const EPIPE: c_int = 32; +pub const EDOM: c_int = 33; +pub const ERANGE: c_int = 34; + +pub const EDEADLK: c_int = 35; +pub const ENAMETOOLONG: c_int = 36; +pub const ENOLCK: c_int = 37; +pub const ENOSYS: c_int = 38; +pub const ENOTEMPTY: c_int = 39; +pub const ELOOP: c_int = 40; +pub const EWOULDBLOCK: c_int = EAGAIN; +pub const ENOMSG: c_int = 42; +pub const EIDRM: c_int = 43; +pub const ECHRNG: c_int = 44; +pub const EL2NSYNC: c_int = 45; +pub const EL3HLT: c_int = 46; +pub const EL3RST: c_int = 47; +pub const ELNRNG: c_int = 48; +pub const EUNATCH: c_int = 49; +pub const ENOCSI: c_int = 50; +pub const EL2HLT: c_int = 51; +pub const EBADE: c_int = 52; +pub const EBADR: c_int = 53; +pub const EXFULL: c_int = 54; +pub const ENOANO: c_int = 55; +pub const EBADRQC: c_int = 56; +pub const EBADSLT: c_int = 57; + +pub const EDEADLOCK: c_int = EDEADLK; + +pub const EBFONT: c_int = 59; +pub const ENOSTR: c_int = 60; +pub const ENODATA: c_int = 61; +pub const ETIME: c_int = 62; +pub const ENOSR: c_int = 63; +pub const ENONET: c_int = 64; +pub const ENOPKG: c_int = 65; +pub const EREMOTE: c_int = 66; +pub const ENOLINK: c_int = 67; +pub const EADV: c_int = 68; +pub const ESRMNT: c_int = 69; +pub const ECOMM: c_int = 70; +pub const EPROTO: c_int = 71; +pub const EMULTIHOP: c_int = 72; +pub const EDOTDOT: c_int = 73; +pub const EBADMSG: c_int = 74; +pub const EOVERFLOW: c_int = 75; +pub const ENOTUNIQ: c_int = 76; +pub const EBADFD: c_int = 77; +pub const EREMCHG: c_int = 78; +pub const ELIBACC: c_int = 79; +pub const ELIBBAD: c_int = 80; +pub const ELIBSCN: c_int = 81; +pub const ELIBMAX: c_int = 82; +pub const ELIBEXEC: c_int = 83; +pub const EILSEQ: c_int = 84; +pub const ERESTART: c_int = 85; +pub const ESTRPIPE: c_int = 86; +pub const EUSERS: c_int = 87; +pub const ENOTSOCK: c_int = 88; +pub const EDESTADDRREQ: c_int = 89; +pub const EMSGSIZE: c_int = 90; +pub const EPROTOTYPE: c_int = 91; +pub const ENOPROTOOPT: c_int = 92; +pub const EPROTONOSUPPORT: c_int = 93; +pub const ESOCKTNOSUPPORT: c_int = 94; +pub const EOPNOTSUPP: c_int = 95; +pub const EPFNOSUPPORT: c_int = 96; +pub const EAFNOSUPPORT: c_int = 97; +pub const EADDRINUSE: c_int = 98; +pub const EADDRNOTAVAIL: c_int = 99; +pub const ENETDOWN: c_int = 100; +pub const ENETUNREACH: c_int = 101; +pub const ENETRESET: c_int = 102; +pub const ECONNABORTED: c_int = 103; +pub const ECONNRESET: c_int = 104; +pub const ENOBUFS: c_int = 105; +pub const EISCONN: c_int = 106; +pub const ENOTCONN: c_int = 107; +pub const ESHUTDOWN: c_int = 108; +pub const ETOOMANYREFS: c_int = 109; +pub const ETIMEDOUT: c_int = 110; +pub const ECONNREFUSED: c_int = 111; +pub const EHOSTDOWN: c_int = 112; +pub const EHOSTUNREACH: c_int = 113; +pub const EALREADY: c_int = 114; +pub const EINPROGRESS: c_int = 115; +pub const ESTALE: c_int = 116; +pub const EUCLEAN: c_int = 117; +pub const ENOTNAM: c_int = 118; +pub const ENAVAIL: c_int = 119; +pub const EISNAM: c_int = 120; +pub const EREMOTEIO: c_int = 121; +pub const EDQUOT: c_int = 122; + +pub const ENOMEDIUM: c_int = 123; +pub const EMEDIUMTYPE: c_int = 124; +pub const ECANCELED: c_int = 125; +pub const ENOKEY: c_int = 126; +pub const EKEYEXPIRED: c_int = 127; +pub const EKEYREVOKED: c_int = 128; +pub const EKEYREJECTED: c_int = 129; + +pub const EOWNERDEAD: c_int = 130; +pub const ENOTRECOVERABLE: c_int = 131; + +pub const ENOTSUP: c_int = 132; +pub const EFTYPE: c_int = 133; + +// signal codes +pub const SIGHUP: c_int = 1; +pub const SIGINT: c_int = 2; +pub const SIGQUIT: c_int = 3; +pub const SIGILL: c_int = 4; +pub const SIGTRAP: c_int = 5; +pub const SIGABRT: c_int = 6; +pub const SIGIOT: c_int = SIGABRT; +pub const SIGEMT: c_int = 7; +pub const SIGFPE: c_int = 8; +pub const SIGKILL: c_int = 9; +pub const SIGBUS: c_int = 10; +pub const SIGSEGV: c_int = 11; +pub const SIGSYS: c_int = 12; +pub const SIGPIPE: c_int = 13; +pub const SIGALRM: c_int = 14; +pub const SIGTERM: c_int = 15; +pub const SIGURG: c_int = 16; +pub const SIGSTOP: c_int = 17; +pub const SIGTSTP: c_int = 18; +pub const SIGCONT: c_int = 19; +pub const SIGCHLD: c_int = 20; +pub const SIGTTIN: c_int = 21; +pub const SIGTTOU: c_int = 22; +pub const SIGIO: c_int = 23; +pub const SIGXCPU: c_int = 24; +pub const SIGXFSZ: c_int = 25; +pub const SIGVTALRM: c_int = 26; +pub const SIGPROF: c_int = 27; +pub const SIGWINCH: c_int = 28; +pub const SIGINFO: c_int = 29; +pub const SIGUSR1: c_int = 30; +pub const SIGUSR2: c_int = 31; +pub const SIGPWR: c_int = 32; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos_t {} +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +extern "C" { + // ctype.h + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn isblank(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + + // stdio.h + pub fn __get_stdio_file(fileno: c_int) -> *mut FILE; + pub fn clearerr(arg1: *mut FILE); + pub fn fclose(arg1: *mut FILE) -> c_int; + pub fn feof(arg1: *mut FILE) -> c_int; + pub fn ferror(arg1: *mut FILE) -> c_int; + pub fn fflush(arg1: *mut FILE) -> c_int; + pub fn fgetc(arg1: *mut FILE) -> c_int; + pub fn fgets(arg1: *mut c_char, arg2: c_int, arg3: *mut FILE) -> *mut c_char; + pub fn fopen(arg1: *const c_char, arg2: *const c_char) -> *mut FILE; + pub fn fprintf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; + pub fn fputc(arg1: c_int, arg2: *mut FILE) -> c_int; + pub fn fputs(arg1: *const c_char, arg2: *mut FILE) -> c_int; + pub fn fread(arg1: *mut c_void, arg2: size_t, arg3: size_t, arg4: *mut FILE) -> size_t; + pub fn freopen(arg1: *const c_char, arg2: *const c_char, arg3: *mut FILE) -> *mut FILE; + pub fn fscanf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; + pub fn fseek(arg1: *mut FILE, arg2: c_long, arg3: c_int) -> c_int; + pub fn ftell(arg1: *mut FILE) -> c_long; + pub fn fwrite(arg1: *const c_void, arg2: size_t, arg3: size_t, arg4: *mut FILE) -> size_t; + pub fn getc(arg1: *mut FILE) -> c_int; + pub fn getchar() -> c_int; + pub fn perror(arg1: *const c_char); + pub fn printf(arg1: *const c_char, ...) -> c_int; + pub fn putc(arg1: c_int, arg2: *mut FILE) -> c_int; + pub fn putchar(arg1: c_int) -> c_int; + pub fn puts(arg1: *const c_char) -> c_int; + pub fn remove(arg1: *const c_char) -> c_int; + pub fn rewind(arg1: *mut FILE); + pub fn scanf(arg1: *const c_char, ...) -> c_int; + pub fn setbuf(arg1: *mut FILE, arg2: *mut c_char); + pub fn setvbuf(arg1: *mut FILE, arg2: *mut c_char, arg3: c_int, arg4: size_t) -> c_int; + pub fn sscanf(arg1: *const c_char, arg2: *const c_char, ...) -> c_int; + pub fn tmpfile() -> *mut FILE; + pub fn ungetc(arg1: c_int, arg2: *mut FILE) -> c_int; + pub fn vfprintf(arg1: *mut FILE, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn vprintf(arg1: *const c_char, arg2: __va_list) -> c_int; + pub fn gets(arg1: *mut c_char) -> *mut c_char; + pub fn sprintf(arg1: *mut c_char, arg2: *const c_char, ...) -> c_int; + pub fn tmpnam(arg1: *const c_char) -> *mut c_char; + pub fn vsprintf(arg1: *mut c_char, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn rename(arg1: *const c_char, arg2: *const c_char) -> c_int; + pub fn asiprintf(arg1: *mut *mut c_char, arg2: *const c_char, ...) -> c_int; + pub fn fiprintf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; + pub fn fiscanf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; + pub fn iprintf(arg1: *const c_char, ...) -> c_int; + pub fn iscanf(arg1: *const c_char, ...) -> c_int; + pub fn siprintf(arg1: *mut c_char, arg2: *const c_char, ...) -> c_int; + pub fn siscanf(arg1: *mut c_char, arg2: *const c_char, ...) -> c_int; + pub fn sniprintf(arg1: *mut c_char, arg2: size_t, arg3: *const c_char, ...) -> c_int; + pub fn vasiprintf(arg1: *mut *mut c_char, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn vfiprintf(arg1: *mut FILE, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn vfiscanf(arg1: *mut FILE, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn viprintf(arg1: *const c_char, arg2: __va_list) -> c_int; + pub fn viscanf(arg1: *const c_char, arg2: __va_list) -> c_int; + pub fn vsiprintf(arg1: *mut c_char, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn vsiscanf(arg1: *const c_char, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn vsniprintf( + arg1: *mut c_char, + arg2: size_t, + arg3: *const c_char, + arg4: __va_list, + ) -> c_int; + pub fn vdiprintf(arg1: c_int, arg2: *const c_char, arg3: __va_list) -> c_int; + pub fn diprintf(arg1: c_int, arg2: *const c_char, ...) -> c_int; + pub fn fgetpos(arg1: *mut FILE, arg2: *mut fpos_t) -> c_int; + pub fn fsetpos(arg1: *mut FILE, arg2: *const fpos_t) -> c_int; + pub fn fdopen(arg1: c_int, arg2: *const c_char) -> *mut FILE; + pub fn fileno(arg1: *mut FILE) -> c_int; + pub fn flockfile(arg1: *mut FILE); + pub fn ftrylockfile(arg1: *mut FILE) -> c_int; + pub fn funlockfile(arg1: *mut FILE); + pub fn getc_unlocked(arg1: *mut FILE) -> c_int; + pub fn getchar_unlocked() -> c_int; + pub fn putc_unlocked(arg1: c_int, arg2: *mut FILE) -> c_int; + pub fn putchar_unlocked(arg1: c_int) -> c_int; + pub fn snprintf(arg1: *mut c_char, arg2: size_t, arg3: *const c_char, ...) -> c_int; + pub fn vsnprintf( + arg1: *mut c_char, + arg2: size_t, + arg3: *const c_char, + arg4: __va_list, + ) -> c_int; + pub fn getw(arg1: *mut FILE) -> c_int; + pub fn putw(arg1: c_int, arg2: *mut FILE) -> c_int; + pub fn tempnam(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; + pub fn fseeko(stream: *mut FILE, offset: off_t, whence: c_int) -> c_int; + pub fn ftello(stream: *mut FILE) -> off_t; + + // stdlib.h + pub fn atof(arg1: *const c_char) -> f64; + pub fn strtod(arg1: *const c_char, arg2: *mut *mut c_char) -> f64; + pub fn drand48() -> f64; + pub fn erand48(arg1: *mut c_ushort) -> f64; + pub fn strtof(arg1: *const c_char, arg2: *mut *mut c_char) -> f32; + pub fn strtold(arg1: *const c_char, arg2: *mut *mut c_char) -> f64; + pub fn strtod_l(arg1: *const c_char, arg2: *mut *mut c_char, arg3: locale_t) -> f64; + pub fn strtof_l(arg1: *const c_char, arg2: *mut *mut c_char, arg3: locale_t) -> f32; + pub fn strtold_l(arg1: *const c_char, arg2: *mut *mut c_char, arg3: locale_t) -> f64; + pub fn _Exit(arg1: c_int) -> !; + pub fn abort() -> !; + pub fn abs(arg1: c_int) -> c_int; + pub fn atexit(arg1: ::Option) -> c_int; + pub fn atoi(arg1: *const c_char) -> c_int; + pub fn atol(arg1: *const c_char) -> c_long; + pub fn itoa(arg1: c_int, arg2: *mut c_char, arg3: c_int) -> *mut c_char; + pub fn ltoa(arg1: c_long, arg2: *mut c_char, arg3: c_int) -> *mut c_char; + pub fn ultoa(arg1: c_ulong, arg2: *mut c_char, arg3: c_int) -> *mut c_char; + pub fn bsearch( + arg1: *const c_void, + arg2: *const c_void, + arg3: size_t, + arg4: size_t, + arg5: ::Option c_int>, + ) -> *mut c_void; + pub fn calloc(arg1: size_t, arg2: size_t) -> *mut c_void; + pub fn div(arg1: c_int, arg2: c_int) -> div_t; + pub fn exit(arg1: c_int) -> !; + pub fn free(arg1: *mut c_void); + pub fn getenv(arg1: *const c_char) -> *mut c_char; + pub fn labs(arg1: c_long) -> c_long; + pub fn ldiv(arg1: c_long, arg2: c_long) -> ldiv_t; + pub fn malloc(arg1: size_t) -> *mut c_void; + pub fn qsort( + arg1: *mut c_void, + arg2: size_t, + arg3: size_t, + arg4: ::Option c_int>, + ); + pub fn rand() -> c_int; + pub fn realloc(arg1: *mut c_void, arg2: size_t) -> *mut c_void; + pub fn srand(arg1: c_uint); + pub fn strtol(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_long; + pub fn strtoul(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulong; + pub fn mblen(arg1: *const c_char, arg2: size_t) -> c_int; + pub fn mbstowcs(arg1: *mut wchar_t, arg2: *const c_char, arg3: size_t) -> size_t; + pub fn wctomb(arg1: *mut c_char, arg2: wchar_t) -> c_int; + pub fn mbtowc(arg1: *mut wchar_t, arg2: *const c_char, arg3: size_t) -> c_int; + pub fn wcstombs(arg1: *mut c_char, arg2: *const wchar_t, arg3: size_t) -> size_t; + pub fn rand_r(arg1: *mut c_uint) -> c_int; + pub fn jrand48(arg1: *mut c_ushort) -> c_long; + pub fn lcong48(arg1: *mut c_ushort); + pub fn lrand48() -> c_long; + pub fn mrand48() -> c_long; + pub fn nrand48(arg1: *mut c_ushort) -> c_long; + pub fn seed48(arg1: *mut c_ushort) -> *mut c_ushort; + pub fn srand48(arg1: c_long); + pub fn putenv(arg1: *mut c_char) -> c_int; + pub fn a64l(arg1: *const c_char) -> c_long; + pub fn l64a(arg1: c_long) -> *mut c_char; + pub fn random() -> c_long; + pub fn setstate(arg1: *mut c_char) -> *mut c_char; + pub fn initstate(arg1: c_uint, arg2: *mut c_char, arg3: size_t) -> *mut c_char; + pub fn srandom(arg1: c_uint); + pub fn mkostemp(arg1: *mut c_char, arg2: c_int) -> c_int; + pub fn mkostemps(arg1: *mut c_char, arg2: c_int, arg3: c_int) -> c_int; + pub fn mkdtemp(arg1: *mut c_char) -> *mut c_char; + pub fn mkstemp(arg1: *mut c_char) -> c_int; + pub fn mktemp(arg1: *mut c_char) -> *mut c_char; + pub fn atoll(arg1: *const c_char) -> c_longlong; + pub fn llabs(arg1: c_longlong) -> c_longlong; + pub fn lldiv(arg1: c_longlong, arg2: c_longlong) -> lldiv_t; + pub fn strtoll(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_longlong; + pub fn strtoull(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulonglong; + pub fn aligned_alloc(arg1: size_t, arg2: size_t) -> *mut c_void; + pub fn at_quick_exit(arg1: ::Option) -> c_int; + pub fn quick_exit(arg1: c_int); + pub fn setenv(arg1: *const c_char, arg2: *const c_char, arg3: c_int) -> c_int; + pub fn unsetenv(arg1: *const c_char) -> c_int; + pub fn humanize_number( + arg1: *mut c_char, + arg2: size_t, + arg3: i64, + arg4: *const c_char, + arg5: c_int, + arg6: c_int, + ) -> c_int; + pub fn dehumanize_number(arg1: *const c_char, arg2: *mut i64) -> c_int; + pub fn getenv_r(arg1: *const c_char, arg2: *mut c_char, arg3: size_t) -> c_int; + pub fn heapsort( + arg1: *mut c_void, + arg2: size_t, + arg3: size_t, + arg4: ::Option c_int>, + ) -> c_int; + pub fn mergesort( + arg1: *mut c_void, + arg2: size_t, + arg3: size_t, + arg4: ::Option c_int>, + ) -> c_int; + pub fn radixsort( + arg1: *mut *const c_uchar, + arg2: c_int, + arg3: *const c_uchar, + arg4: c_uint, + ) -> c_int; + pub fn sradixsort( + arg1: *mut *const c_uchar, + arg2: c_int, + arg3: *const c_uchar, + arg4: c_uint, + ) -> c_int; + pub fn getprogname() -> *const c_char; + pub fn setprogname(arg1: *const c_char); + pub fn qabs(arg1: quad_t) -> quad_t; + pub fn strtoq(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> quad_t; + pub fn strtouq(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> u_quad_t; + pub fn strsuftoll( + arg1: *const c_char, + arg2: *const c_char, + arg3: c_longlong, + arg4: c_longlong, + ) -> c_longlong; + pub fn strsuftollx( + arg1: *const c_char, + arg2: *const c_char, + arg3: c_longlong, + arg4: c_longlong, + arg5: *mut c_char, + arg6: size_t, + ) -> c_longlong; + pub fn l64a_r(arg1: c_long, arg2: *mut c_char, arg3: c_int) -> c_int; + pub fn qdiv(arg1: quad_t, arg2: quad_t) -> qdiv_t; + pub fn strtol_l( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + arg4: locale_t, + ) -> c_long; + pub fn strtoul_l( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + arg4: locale_t, + ) -> c_ulong; + pub fn strtoll_l( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + arg4: locale_t, + ) -> c_longlong; + pub fn strtoull_l( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + arg4: locale_t, + ) -> c_ulonglong; + pub fn strtoq_l( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + arg4: locale_t, + ) -> quad_t; + pub fn strtouq_l( + arg1: *const c_char, + arg2: *mut *mut c_char, + arg3: c_int, + arg4: locale_t, + ) -> u_quad_t; + pub fn _mb_cur_max_l(arg1: locale_t) -> size_t; + pub fn mblen_l(arg1: *const c_char, arg2: size_t, arg3: locale_t) -> c_int; + pub fn mbstowcs_l( + arg1: *mut wchar_t, + arg2: *const c_char, + arg3: size_t, + arg4: locale_t, + ) -> size_t; + pub fn wctomb_l(arg1: *mut c_char, arg2: wchar_t, arg3: locale_t) -> c_int; + pub fn mbtowc_l(arg1: *mut wchar_t, arg2: *const c_char, arg3: size_t, arg4: locale_t) + -> c_int; + pub fn wcstombs_l( + arg1: *mut c_char, + arg2: *const wchar_t, + arg3: size_t, + arg4: locale_t, + ) -> size_t; + + // string.h + pub fn memchr(arg1: *const c_void, arg2: c_int, arg3: size_t) -> *mut c_void; + pub fn memcmp(arg1: *const c_void, arg2: *const c_void, arg3: size_t) -> c_int; + pub fn memcpy(arg1: *mut c_void, arg2: *const c_void, arg3: size_t) -> *mut c_void; + pub fn memmove(arg1: *mut c_void, arg2: *const c_void, arg3: size_t) -> *mut c_void; + pub fn memset(arg1: *mut c_void, arg2: c_int, arg3: size_t) -> *mut c_void; + pub fn strcat(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; + pub fn strchr(arg1: *const c_char, arg2: c_int) -> *mut c_char; + pub fn strcmp(arg1: *const c_char, arg2: *const c_char) -> c_int; + pub fn strcoll(arg1: *const c_char, arg2: *const c_char) -> c_int; + pub fn strcpy(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; + pub fn strcspn(arg1: *const c_char, arg2: *const c_char) -> size_t; + pub fn strerror(arg1: c_int) -> *mut c_char; + pub fn strlen(arg1: *const c_char) -> size_t; + pub fn strncat(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> *mut c_char; + pub fn strncmp(arg1: *const c_char, arg2: *const c_char, arg3: size_t) -> c_int; + pub fn strncpy(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> *mut c_char; + pub fn strpbrk(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; + pub fn strrchr(arg1: *const c_char, arg2: c_int) -> *mut c_char; + pub fn strspn(arg1: *const c_char, arg2: *const c_char) -> size_t; + pub fn strstr(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; + pub fn strtok(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; + pub fn strtok_r(arg1: *mut c_char, arg2: *const c_char, arg3: *mut *mut c_char) -> *mut c_char; + pub fn strerror_r(arg1: c_int, arg2: *mut c_char, arg3: size_t) -> c_int; + pub fn strxfrm(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> size_t; + pub fn memccpy( + arg1: *mut c_void, + arg2: *const c_void, + arg3: c_int, + arg4: size_t, + ) -> *mut c_void; + pub fn strdup(arg1: *const c_char) -> *mut c_char; + pub fn stpcpy(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; + pub fn stpncpy(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> *mut c_char; + pub fn strnlen(arg1: *const c_char, arg2: size_t) -> size_t; + pub fn memmem( + arg1: *const c_void, + arg2: size_t, + arg3: *const c_void, + arg4: size_t, + ) -> *mut c_void; + pub fn strcasestr(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; + pub fn strlcat(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> size_t; + pub fn strlcpy(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> size_t; + pub fn strsep(arg1: *mut *mut c_char, arg2: *const c_char) -> *mut c_char; + pub fn stresep(arg1: *mut *mut c_char, arg2: *const c_char, arg3: c_int) -> *mut c_char; + pub fn strndup(arg1: *const c_char, arg2: size_t) -> *mut c_char; + pub fn memrchr(arg1: *const c_void, arg2: c_int, arg3: size_t) -> *mut c_void; + pub fn explicit_memset(arg1: *mut c_void, arg2: c_int, arg3: size_t) -> *mut c_void; + pub fn consttime_memequal(arg1: *const c_void, arg2: *const c_void, arg3: size_t) -> c_int; + pub fn strcoll_l(arg1: *const c_char, arg2: *const c_char, arg3: locale_t) -> c_int; + pub fn strxfrm_l( + arg1: *mut c_char, + arg2: *const c_char, + arg3: size_t, + arg4: locale_t, + ) -> size_t; + pub fn strerror_l(arg1: c_int, arg2: locale_t) -> *mut c_char; + + // strings.h + pub fn bcmp(arg1: *const c_void, arg2: *const c_void, arg3: size_t) -> c_int; + pub fn bcopy(arg1: *const c_void, arg2: *mut c_void, arg3: size_t); + pub fn bzero(arg1: *mut c_void, arg2: size_t); + pub fn ffs(arg1: c_int) -> c_int; + pub fn popcount(arg1: c_uint) -> c_uint; + pub fn popcountl(arg1: c_ulong) -> c_uint; + pub fn popcountll(arg1: c_ulonglong) -> c_uint; + pub fn popcount32(arg1: u32) -> c_uint; + pub fn popcount64(arg1: u64) -> c_uint; + pub fn rindex(arg1: *const c_char, arg2: c_int) -> *mut c_char; + pub fn strcasecmp(arg1: *const c_char, arg2: *const c_char) -> c_int; + pub fn strncasecmp(arg1: *const c_char, arg2: *const c_char, arg3: size_t) -> c_int; + + // signal.h + pub fn signal(arg1: c_int, arg2: sighandler_t) -> sighandler_t; + pub fn raise(arg1: c_int) -> c_int; + + // time.h + pub fn asctime(arg1: *const tm) -> *mut c_char; + pub fn clock() -> clock_t; + pub fn ctime(arg1: *const time_t) -> *mut c_char; + pub fn difftime(arg1: time_t, arg2: time_t) -> f64; + pub fn gmtime(arg1: *const time_t) -> *mut tm; + pub fn localtime(arg1: *const time_t) -> *mut tm; + pub fn time(arg1: *mut time_t) -> time_t; + pub fn mktime(arg1: *mut tm) -> time_t; + pub fn strftime( + arg1: *mut c_char, + arg2: size_t, + arg3: *const c_char, + arg4: *const tm, + ) -> size_t; + pub fn utime(arg1: *const c_char, arg2: *mut time_t) -> c_int; + pub fn asctime_r(arg1: *const tm, arg2: *mut c_char) -> *mut c_char; + pub fn ctime_r(arg1: *const time_t, arg2: *mut c_char) -> *mut c_char; + pub fn gmtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm; + pub fn localtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm; + + // sys/stat.h + pub fn stat(arg1: *const c_char, arg2: *mut stat) -> c_int; + pub fn lstat(arg1: *const c_char, arg2: *mut stat) -> c_int; + pub fn fstat(arg1: c_int, arg2: *mut stat) -> c_int; + pub fn chmod(arg1: *const c_char, arg2: __mode_t) -> c_int; + pub fn mkdir(arg1: *const c_char, arg2: __mode_t) -> c_int; + + // fcntl.h + pub fn open(arg1: *const c_char, arg2: c_int, ...) -> c_int; + pub fn creat(arg1: *const c_char, arg2: c_int) -> c_int; + pub fn close(arg1: c_int) -> c_int; + pub fn read(arg1: c_int, arg2: *mut c_void, arg3: c_int) -> c_int; + pub fn write(arg1: c_int, arg2: *const c_void, arg3: c_int) -> c_int; + pub fn unlink(arg1: *const c_char) -> c_int; + pub fn tell(arg1: c_int) -> c_long; + pub fn dup(arg1: c_int) -> c_int; + pub fn dup2(arg1: c_int, arg2: c_int) -> c_int; + pub fn access(arg1: *const c_char, arg2: c_int) -> c_int; + pub fn rmdir(arg1: *const c_char) -> c_int; + pub fn chdir(arg1: *const c_char) -> c_int; + pub fn _exit(arg1: c_int); + pub fn getwd(arg1: *mut c_char) -> *mut c_char; + pub fn getcwd(arg1: *mut c_char, arg2: size_t) -> *mut c_char; + pub static mut optarg: *mut c_char; + pub static mut opterr: c_int; + pub static mut optind: c_int; + pub static mut optopt: c_int; + pub static mut optreset: c_int; + pub fn getopt(arg1: c_int, arg2: *mut *mut c_char, arg3: *const c_char) -> c_int; + pub static mut suboptarg: *mut c_char; + pub fn getsubopt( + arg1: *mut *mut c_char, + arg2: *const *mut c_char, + arg3: *mut *mut c_char, + ) -> c_int; + pub fn fcntl(arg1: c_int, arg2: c_int, ...) -> c_int; + pub fn getpid() -> pid_t; + pub fn sleep(arg1: c_uint) -> c_uint; + pub fn usleep(arg1: useconds_t) -> c_int; + + // locale.h + pub fn localeconv() -> *mut lconv; + pub fn setlocale(arg1: c_int, arg2: *const c_char) -> *mut c_char; + pub fn duplocale(arg1: locale_t) -> locale_t; + pub fn freelocale(arg1: locale_t); + pub fn localeconv_l(arg1: locale_t) -> *mut lconv; + pub fn newlocale(arg1: c_int, arg2: *const c_char, arg3: locale_t) -> locale_t; + + // langinfo.h + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + pub fn nl_langinfo_l(item: ::nl_item, locale: locale_t) -> *mut ::c_char; + + // malloc.h + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + + // sys/types.h + pub fn lseek(arg1: c_int, arg2: __off_t, arg3: c_int) -> __off_t; +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(any(target_arch = "arm"))] { + mod arm; + pub use self::arm::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/switch.rs b/utshell-0.5.0/vendor/libc/src/switch.rs new file mode 100644 index 00000000..030ab20d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/switch.rs @@ -0,0 +1,49 @@ +//! Switch C type definitions + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type off_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = u32; + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/teeos/mod.rs b/utshell-0.5.0/vendor/libc/src/teeos/mod.rs new file mode 100644 index 00000000..25e06ffa --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/teeos/mod.rs @@ -0,0 +1,1385 @@ +//! Libc bindings for teeos +//! +//! Apparently the loader just dynamically links it anyway, but fails +//! when linking is explicitly requested. +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +// only supported on Rust > 1.59, so we can directly reexport c_void from core. +pub use core::ffi::c_void; + +use Option; + +pub type c_schar = i8; + +pub type c_uchar = u8; + +pub type c_short = i16; + +pub type c_ushort = u16; + +pub type c_int = i32; + +pub type c_uint = u32; + +pub type c_bool = i32; + +pub type c_float = f32; + +pub type c_double = f64; + +pub type c_longlong = i64; + +pub type c_ulonglong = u64; + +pub type intmax_t = i64; + +pub type uintmax_t = u64; + +pub type size_t = usize; + +pub type ptrdiff_t = isize; + +pub type intptr_t = isize; + +pub type uintptr_t = usize; + +pub type ssize_t = isize; + +pub type pid_t = c_int; + +// aarch64 specifc +pub type c_char = u8; + +pub type wchar_t = u32; + +pub type c_long = i64; + +pub type c_ulong = u64; + +#[repr(align(16))] +pub struct _CLongDouble(pub u128); + +// long double in C means A float point value, which has 128bit length. +// but some bit maybe not used, so the really length of long double could be 80(x86) or 128(power pc/IEEE) +// this is different from f128(not stable and not included default) in Rust, so we use u128 for FFI(Rust to C). +// this is unstable and will couse to memfault/data abort. +pub type c_longdouble = _CLongDouble; + +pub type pthread_t = c_ulong; + +pub type pthread_key_t = c_uint; + +pub type pthread_spinlock_t = c_int; + +pub type off_t = i64; + +pub type time_t = c_long; + +pub type clock_t = c_long; + +pub type clockid_t = c_int; + +pub type suseconds_t = c_long; + +pub type once_fn = extern "C" fn() -> c_void; + +pub type pthread_once_t = c_int; + +pub type va_list = *mut c_char; + +pub type wint_t = c_uint; + +pub type wctype_t = c_ulong; + +pub type cmpfunc = extern "C" fn(x: *const c_void, y: *const c_void) -> c_int; + +#[repr(align(8))] +#[repr(C)] +pub struct pthread_cond_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_COND_T], +} + +#[repr(align(8))] +#[repr(C)] +pub struct pthread_mutex_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_MUTEX_T], +} + +#[repr(align(4))] +#[repr(C)] +pub struct pthread_mutexattr_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], +} + +#[repr(align(4))] +#[repr(C)] +pub struct pthread_condattr_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], +} + +#[repr(C)] +pub struct pthread_attr_t { + __size: [u64; 7], +} + +#[repr(C)] +pub struct cpu_set_t { + bits: [c_ulong; 128 / core::mem::size_of::()], +} + +#[repr(C)] +pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, +} + +#[repr(C)] +pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, +} + +#[repr(C)] +pub struct tm { + pub tm_sec: c_int, + pub tm_min: c_int, + pub tm_hour: c_int, + pub tm_mday: c_int, + pub tm_mon: c_int, + pub tm_year: c_int, + pub tm_wday: c_int, + pub tm_yday: c_int, + pub tm_isdst: c_int, + pub __tm_gmtoff: c_long, + pub __tm_zone: *const c_char, +} + +#[repr(C)] +pub struct mbstate_t { + pub __opaque1: c_uint, + pub __opaque2: c_uint, +} + +#[repr(C)] +pub struct sem_t { + pub __val: [c_int; 4 * core::mem::size_of::() / core::mem::size_of::()], +} + +#[repr(C)] +pub struct div_t { + pub quot: c_int, + pub rem: c_int, +} + +// fcntl +pub const O_CREAT: u32 = 0100; + +pub const O_EXCL: u32 = 0200; + +pub const O_NOCTTY: u32 = 0400; + +pub const O_TRUNC: u32 = 01000; + +pub const O_APPEND: u32 = 02000; + +pub const O_NONBLOCK: u32 = 04000; + +pub const O_DSYNC: u32 = 010000; + +pub const O_SYNC: u32 = 04010000; + +pub const O_RSYNC: u32 = 04010000; + +pub const O_DIRECTORY: u32 = 0200000; + +pub const O_NOFOLLOW: u32 = 0400000; + +pub const O_CLOEXEC: u32 = 02000000; + +pub const O_ASYNC: u32 = 020000; + +pub const O_DIRECT: u32 = 040000; + +pub const O_LARGEFILE: u32 = 0100000; + +pub const O_NOATIME: u32 = 01000000; + +pub const O_PATH: u32 = 010000000; + +pub const O_TMPFILE: u32 = 020200000; + +pub const O_NDELAY: u32 = O_NONBLOCK; + +pub const F_DUPFD: u32 = 0; + +pub const F_GETFD: u32 = 1; + +pub const F_SETFD: u32 = 2; + +pub const F_GETFL: u32 = 3; + +pub const F_SETFL: u32 = 4; + +pub const F_SETOWN: u32 = 8; + +pub const F_GETOWN: u32 = 9; + +pub const F_SETSIG: u32 = 10; + +pub const F_GETSIG: u32 = 11; + +pub const F_GETLK: u32 = 12; + +pub const F_SETLK: u32 = 13; + +pub const F_SETLKW: u32 = 14; + +pub const F_SETOWN_EX: u32 = 15; + +pub const F_GETOWN_EX: u32 = 16; + +pub const F_GETOWNER_UIDS: u32 = 17; + +// mman +pub const MAP_FAILED: u64 = 0xffffffffffffffff; + +pub const MAP_FIXED_NOREPLACE: u32 = 0x100000; + +pub const MAP_SHARED_VALIDATE: u32 = 0x03; + +pub const MAP_SHARED: u32 = 0x01; + +pub const MAP_PRIVATE: u32 = 0x02; + +pub const MAP_TYPE: u32 = 0x0f; + +pub const MAP_FIXED: u32 = 0x10; + +pub const MAP_ANON: u32 = 0x20; + +pub const MAP_ANONYMOUS: u32 = MAP_ANON; + +pub const MAP_NORESERVE: u32 = 0x4000; + +pub const MAP_GROWSDOWN: u32 = 0x0100; + +pub const MAP_DENYWRITE: u32 = 0x0800; + +pub const MAP_EXECUTABLE: u32 = 0x1000; + +pub const MAP_LOCKED: u32 = 0x2000; + +pub const MAP_POPULATE: u32 = 0x8000; + +pub const MAP_NONBLOCK: u32 = 0x10000; + +pub const MAP_STACK: u32 = 0x20000; + +pub const MAP_HUGETLB: u32 = 0x40000; + +pub const MAP_SYNC: u32 = 0x80000; + +pub const MAP_FILE: u32 = 0; + +pub const MAP_HUGE_SHIFT: u32 = 26; + +pub const MAP_HUGE_MASK: u32 = 0x3f; + +pub const MAP_HUGE_16KB: u32 = 14 << 26; + +pub const MAP_HUGE_64KB: u32 = 16 << 26; + +pub const MAP_HUGE_512KB: u32 = 19 << 26; + +pub const MAP_HUGE_1MB: u32 = 20 << 26; + +pub const MAP_HUGE_2MB: u32 = 21 << 26; + +pub const MAP_HUGE_8MB: u32 = 23 << 26; + +pub const MAP_HUGE_16MB: u32 = 24 << 26; + +pub const MAP_HUGE_32MB: u32 = 25 << 26; + +pub const MAP_HUGE_256MB: u32 = 28 << 26; + +pub const MAP_HUGE_512MB: u32 = 29 << 26; + +pub const MAP_HUGE_1GB: u32 = 30 << 26; + +pub const MAP_HUGE_2GB: u32 = 31 << 26; + +pub const MAP_HUGE_16GB: u32 = 34u32 << 26; + +pub const PROT_NONE: u32 = 0; + +pub const PROT_READ: u32 = 1; + +pub const PROT_WRITE: u32 = 2; + +pub const PROT_EXEC: u32 = 4; + +pub const PROT_GROWSDOWN: u32 = 0x01000000; + +pub const PROT_GROWSUP: u32 = 0x02000000; + +pub const MS_ASYNC: u32 = 1; + +pub const MS_INVALIDATE: u32 = 2; + +pub const MS_SYNC: u32 = 4; + +pub const MCL_CURRENT: u32 = 1; + +pub const MCL_FUTURE: u32 = 2; + +pub const MCL_ONFAULT: u32 = 4; + +pub const POSIX_MADV_NORMAL: u32 = 0; + +pub const POSIX_MADV_RANDOM: u32 = 1; + +pub const POSIX_MADV_SEQUENTIAL: u32 = 2; + +pub const POSIX_MADV_WILLNEED: u32 = 3; + +pub const POSIX_MADV_DONTNEED: u32 = 4; + +// wctype +pub const WCTYPE_ALNUM: u64 = 1; + +pub const WCTYPE_ALPHA: u64 = 2; + +pub const WCTYPE_BLANK: u64 = 3; + +pub const WCTYPE_CNTRL: u64 = 4; + +pub const WCTYPE_DIGIT: u64 = 5; + +pub const WCTYPE_GRAPH: u64 = 6; + +pub const WCTYPE_LOWER: u64 = 7; + +pub const WCTYPE_PRINT: u64 = 8; + +pub const WCTYPE_PUNCT: u64 = 9; + +pub const WCTYPE_SPACE: u64 = 10; + +pub const WCTYPE_UPPER: u64 = 11; + +pub const WCTYPE_XDIGIT: u64 = 12; + +// locale +pub const LC_CTYPE: i32 = 0; + +pub const LC_NUMERIC: i32 = 1; + +pub const LC_TIME: i32 = 2; + +pub const LC_COLLATE: i32 = 3; + +pub const LC_MONETARY: i32 = 4; + +pub const LC_MESSAGES: i32 = 5; + +pub const LC_ALL: i32 = 6; + +// pthread +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + +// errno.h +pub const EPERM: c_int = 1; + +pub const ENOENT: c_int = 2; + +pub const ESRCH: c_int = 3; + +pub const EINTR: c_int = 4; + +pub const EIO: c_int = 5; + +pub const ENXIO: c_int = 6; + +pub const E2BIG: c_int = 7; + +pub const ENOEXEC: c_int = 8; + +pub const EBADF: c_int = 9; + +pub const ECHILD: c_int = 10; + +pub const EAGAIN: c_int = 11; + +pub const ENOMEM: c_int = 12; + +pub const EACCES: c_int = 13; + +pub const EFAULT: c_int = 14; + +pub const ENOTBLK: c_int = 15; + +pub const EBUSY: c_int = 16; + +pub const EEXIST: c_int = 17; + +pub const EXDEV: c_int = 18; + +pub const ENODEV: c_int = 19; + +pub const ENOTDIR: c_int = 20; + +pub const EISDIR: c_int = 21; + +pub const EINVAL: c_int = 22; + +pub const ENFILE: c_int = 23; + +pub const EMFILE: c_int = 24; + +pub const ENOTTY: c_int = 25; + +pub const ETXTBSY: c_int = 26; + +pub const EFBIG: c_int = 27; + +pub const ENOSPC: c_int = 28; + +pub const ESPIPE: c_int = 29; + +pub const EROFS: c_int = 30; + +pub const EMLINK: c_int = 31; + +pub const EPIPE: c_int = 32; + +pub const EDOM: c_int = 33; + +pub const ERANGE: c_int = 34; + +pub const EDEADLK: c_int = 35; + +pub const ENAMETOOLONG: c_int = 36; + +pub const ENOLCK: c_int = 37; + +pub const ENOSYS: c_int = 38; + +pub const ENOTEMPTY: c_int = 39; + +pub const ELOOP: c_int = 40; + +pub const EWOULDBLOCK: c_int = EAGAIN; + +pub const ENOMSG: c_int = 42; + +pub const EIDRM: c_int = 43; + +pub const ECHRNG: c_int = 44; + +pub const EL2NSYNC: c_int = 45; + +pub const EL3HLT: c_int = 46; + +pub const EL3RST: c_int = 47; + +pub const ELNRNG: c_int = 48; + +pub const EUNATCH: c_int = 49; + +pub const ENOCSI: c_int = 50; + +pub const EL2HLT: c_int = 51; + +pub const EBADE: c_int = 52; + +pub const EBADR: c_int = 53; + +pub const EXFULL: c_int = 54; + +pub const ENOANO: c_int = 55; + +pub const EBADRQC: c_int = 56; + +pub const EBADSLT: c_int = 57; + +pub const EDEADLOCK: c_int = EDEADLK; + +pub const EBFONT: c_int = 59; + +pub const ENOSTR: c_int = 60; + +pub const ENODATA: c_int = 61; + +pub const ETIME: c_int = 62; + +pub const ENOSR: c_int = 63; + +pub const ENONET: c_int = 64; + +pub const ENOPKG: c_int = 65; + +pub const EREMOTE: c_int = 66; + +pub const ENOLINK: c_int = 67; + +pub const EADV: c_int = 68; + +pub const ESRMNT: c_int = 69; + +pub const ECOMM: c_int = 70; + +pub const EPROTO: c_int = 71; + +pub const EMULTIHOP: c_int = 72; + +pub const EDOTDOT: c_int = 73; + +pub const EBADMSG: c_int = 74; + +pub const EOVERFLOW: c_int = 75; + +pub const ENOTUNIQ: c_int = 76; + +pub const EBADFD: c_int = 77; + +pub const EREMCHG: c_int = 78; + +pub const ELIBACC: c_int = 79; + +pub const ELIBBAD: c_int = 80; + +pub const ELIBSCN: c_int = 81; + +pub const ELIBMAX: c_int = 82; + +pub const ELIBEXEC: c_int = 83; + +pub const EILSEQ: c_int = 84; + +pub const ERESTART: c_int = 85; + +pub const ESTRPIPE: c_int = 86; + +pub const EUSERS: c_int = 87; + +pub const ENOTSOCK: c_int = 88; + +pub const EDESTADDRREQ: c_int = 89; + +pub const EMSGSIZE: c_int = 90; + +pub const EPROTOTYPE: c_int = 91; + +pub const ENOPROTOOPT: c_int = 92; + +pub const EPROTONOSUPPOR: c_int = 93; + +pub const ESOCKTNOSUPPOR: c_int = 94; + +pub const EOPNOTSUPP: c_int = 95; + +pub const ENOTSUP: c_int = EOPNOTSUPP; + +pub const EPFNOSUPPORT: c_int = 96; + +pub const EAFNOSUPPORT: c_int = 97; + +pub const EADDRINUSE: c_int = 98; + +pub const EADDRNOTAVAIL: c_int = 99; + +pub const ENETDOWN: c_int = 100; + +pub const ENETUNREACH: c_int = 101; + +pub const ENETRESET: c_int = 102; + +pub const ECONNABORTED: c_int = 103; + +pub const ECONNRESET: c_int = 104; + +pub const ENOBUFS: c_int = 105; + +pub const EISCONN: c_int = 106; + +pub const ENOTCONN: c_int = 107; + +pub const ESHUTDOWN: c_int = 108; + +pub const ETOOMANYREFS: c_int = 109; + +pub const ETIMEDOUT: c_int = 110; + +pub const ECONNREFUSED: c_int = 111; + +pub const EHOSTDOWN: c_int = 112; + +pub const EHOSTUNREACH: c_int = 113; + +pub const EALREADY: c_int = 114; + +pub const EINPROGRESS: c_int = 115; + +pub const ESTALE: c_int = 116; + +pub const EUCLEAN: c_int = 117; + +pub const ENOTNAM: c_int = 118; + +pub const ENAVAIL: c_int = 119; + +pub const EISNAM: c_int = 120; + +pub const EREMOTEIO: c_int = 121; + +pub const EDQUOT: c_int = 122; + +pub const ENOMEDIUM: c_int = 123; + +pub const EMEDIUMTYPE: c_int = 124; + +pub const ECANCELED: c_int = 125; + +pub const ENOKEY: c_int = 126; + +pub const EKEYEXPIRED: c_int = 127; + +pub const EKEYREVOKED: c_int = 128; + +pub const EKEYREJECTED: c_int = 129; + +pub const EOWNERDEAD: c_int = 130; + +pub const ENOTRECOVERABLE: c_int = 131; + +pub const ERFKILL: c_int = 132; + +pub const EHWPOISON: c_int = 133; + +// pthread_attr.h +pub const TEESMP_THREAD_ATTR_CA_WILDCARD: c_int = 0; + +pub const TEESMP_THREAD_ATTR_CA_INHERIT: c_int = -1; + +pub const TEESMP_THREAD_ATTR_TASK_ID_INHERIT: c_int = -1; + +pub const TEESMP_THREAD_ATTR_HAS_SHADOW: c_int = 0x1; + +pub const TEESMP_THREAD_ATTR_NO_SHADOW: c_int = 0x0; + +// unistd.h +pub const _SC_ARG_MAX: c_int = 0; + +pub const _SC_CHILD_MAX: c_int = 1; + +pub const _SC_CLK_TCK: c_int = 2; + +pub const _SC_NGROUPS_MAX: c_int = 3; + +pub const _SC_OPEN_MAX: c_int = 4; + +pub const _SC_STREAM_MAX: c_int = 5; + +pub const _SC_TZNAME_MAX: c_int = 6; + +pub const _SC_JOB_CONTROL: c_int = 7; + +pub const _SC_SAVED_IDS: c_int = 8; + +pub const _SC_REALTIME_SIGNALS: c_int = 9; + +pub const _SC_PRIORITY_SCHEDULING: c_int = 10; + +pub const _SC_TIMERS: c_int = 11; + +pub const _SC_ASYNCHRONOUS_IO: c_int = 12; + +pub const _SC_PRIORITIZED_IO: c_int = 13; + +pub const _SC_SYNCHRONIZED_IO: c_int = 14; + +pub const _SC_FSYNC: c_int = 15; + +pub const _SC_MAPPED_FILES: c_int = 16; + +pub const _SC_MEMLOCK: c_int = 17; + +pub const _SC_MEMLOCK_RANGE: c_int = 18; + +pub const _SC_MEMORY_PROTECTION: c_int = 19; + +pub const _SC_MESSAGE_PASSING: c_int = 20; + +pub const _SC_SEMAPHORES: c_int = 21; + +pub const _SC_SHARED_MEMORY_OBJECTS: c_int = 22; + +pub const _SC_AIO_LISTIO_MAX: c_int = 23; + +pub const _SC_AIO_MAX: c_int = 24; + +pub const _SC_AIO_PRIO_DELTA_MAX: c_int = 25; + +pub const _SC_DELAYTIMER_MAX: c_int = 26; + +pub const _SC_MQ_OPEN_MAX: c_int = 27; + +pub const _SC_MQ_PRIO_MAX: c_int = 28; + +pub const _SC_VERSION: c_int = 29; + +pub const _SC_PAGE_SIZE: c_int = 30; + +pub const _SC_PAGESIZE: c_int = 30; /* !! */ + +pub const _SC_RTSIG_MAX: c_int = 31; + +pub const _SC_SEM_NSEMS_MAX: c_int = 32; + +pub const _SC_SEM_VALUE_MAX: c_int = 33; + +pub const _SC_SIGQUEUE_MAX: c_int = 34; + +pub const _SC_TIMER_MAX: c_int = 35; + +pub const _SC_BC_BASE_MAX: c_int = 36; + +pub const _SC_BC_DIM_MAX: c_int = 37; + +pub const _SC_BC_SCALE_MAX: c_int = 38; + +pub const _SC_BC_STRING_MAX: c_int = 39; + +pub const _SC_COLL_WEIGHTS_MAX: c_int = 40; + +pub const _SC_EXPR_NEST_MAX: c_int = 42; + +pub const _SC_LINE_MAX: c_int = 43; + +pub const _SC_RE_DUP_MAX: c_int = 44; + +pub const _SC_2_VERSION: c_int = 46; + +pub const _SC_2_C_BIND: c_int = 47; + +pub const _SC_2_C_DEV: c_int = 48; + +pub const _SC_2_FORT_DEV: c_int = 49; + +pub const _SC_2_FORT_RUN: c_int = 50; + +pub const _SC_2_SW_DEV: c_int = 51; + +pub const _SC_2_LOCALEDEF: c_int = 52; + +pub const _SC_UIO_MAXIOV: c_int = 60; /* !! */ + +pub const _SC_IOV_MAX: c_int = 60; + +pub const _SC_THREADS: c_int = 67; + +pub const _SC_THREAD_SAFE_FUNCTIONS: c_int = 68; + +pub const _SC_GETGR_R_SIZE_MAX: c_int = 69; + +pub const _SC_GETPW_R_SIZE_MAX: c_int = 70; + +pub const _SC_LOGIN_NAME_MAX: c_int = 71; + +pub const _SC_TTY_NAME_MAX: c_int = 72; + +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: c_int = 73; + +pub const _SC_THREAD_KEYS_MAX: c_int = 74; + +pub const _SC_THREAD_STACK_MIN: c_int = 75; + +pub const _SC_THREAD_THREADS_MAX: c_int = 76; + +pub const _SC_THREAD_ATTR_STACKADDR: c_int = 77; + +pub const _SC_THREAD_ATTR_STACKSIZE: c_int = 78; + +pub const _SC_THREAD_PRIORITY_SCHEDULING: c_int = 79; + +pub const _SC_THREAD_PRIO_INHERIT: c_int = 80; + +pub const _SC_THREAD_PRIO_PROTECT: c_int = 81; + +pub const _SC_THREAD_PROCESS_SHARED: c_int = 82; + +pub const _SC_NPROCESSORS_CONF: c_int = 83; + +pub const _SC_NPROCESSORS_ONLN: c_int = 84; + +pub const _SC_PHYS_PAGES: c_int = 85; + +pub const _SC_AVPHYS_PAGES: c_int = 86; + +pub const _SC_ATEXIT_MAX: c_int = 87; + +pub const _SC_PASS_MAX: c_int = 88; + +pub const _SC_XOPEN_VERSION: c_int = 89; + +pub const _SC_XOPEN_XCU_VERSION: c_int = 90; + +pub const _SC_XOPEN_UNIX: c_int = 91; + +pub const _SC_XOPEN_CRYPT: c_int = 92; + +pub const _SC_XOPEN_ENH_I18N: c_int = 93; + +pub const _SC_XOPEN_SHM: c_int = 94; + +pub const _SC_2_CHAR_TERM: c_int = 95; + +pub const _SC_2_UPE: c_int = 97; + +pub const _SC_XOPEN_XPG2: c_int = 98; + +pub const _SC_XOPEN_XPG3: c_int = 99; + +pub const _SC_XOPEN_XPG4: c_int = 100; + +pub const _SC_NZERO: c_int = 109; + +pub const _SC_XBS5_ILP32_OFF32: c_int = 125; + +pub const _SC_XBS5_ILP32_OFFBIG: c_int = 126; + +pub const _SC_XBS5_LP64_OFF64: c_int = 127; + +pub const _SC_XBS5_LPBIG_OFFBIG: c_int = 128; + +pub const _SC_XOPEN_LEGACY: c_int = 129; + +pub const _SC_XOPEN_REALTIME: c_int = 130; + +pub const _SC_XOPEN_REALTIME_THREADS: c_int = 131; + +pub const _SC_ADVISORY_INFO: c_int = 132; + +pub const _SC_BARRIERS: c_int = 133; + +pub const _SC_CLOCK_SELECTION: c_int = 137; + +pub const _SC_CPUTIME: c_int = 138; + +pub const _SC_THREAD_CPUTIME: c_int = 139; + +pub const _SC_MONOTONIC_CLOCK: c_int = 149; + +pub const _SC_READER_WRITER_LOCKS: c_int = 153; + +pub const _SC_SPIN_LOCKS: c_int = 154; + +pub const _SC_REGEXP: c_int = 155; + +pub const _SC_SHELL: c_int = 157; + +pub const _SC_SPAWN: c_int = 159; + +pub const _SC_SPORADIC_SERVER: c_int = 160; + +pub const _SC_THREAD_SPORADIC_SERVER: c_int = 161; + +pub const _SC_TIMEOUTS: c_int = 164; + +pub const _SC_TYPED_MEMORY_OBJECTS: c_int = 165; + +pub const _SC_2_PBS: c_int = 168; + +pub const _SC_2_PBS_ACCOUNTING: c_int = 169; + +pub const _SC_2_PBS_LOCATE: c_int = 170; + +pub const _SC_2_PBS_MESSAGE: c_int = 171; + +pub const _SC_2_PBS_TRACK: c_int = 172; + +pub const _SC_SYMLOOP_MAX: c_int = 173; + +pub const _SC_STREAMS: c_int = 174; + +pub const _SC_2_PBS_CHECKPOINT: c_int = 175; + +pub const _SC_V6_ILP32_OFF32: c_int = 176; + +pub const _SC_V6_ILP32_OFFBIG: c_int = 177; + +pub const _SC_V6_LP64_OFF64: c_int = 178; + +pub const _SC_V6_LPBIG_OFFBIG: c_int = 179; + +pub const _SC_HOST_NAME_MAX: c_int = 180; + +pub const _SC_TRACE: c_int = 181; + +pub const _SC_TRACE_EVENT_FILTER: c_int = 182; + +pub const _SC_TRACE_INHERIT: c_int = 183; + +pub const _SC_TRACE_LOG: c_int = 184; + +pub const _SC_IPV6: c_int = 235; + +pub const _SC_RAW_SOCKETS: c_int = 236; + +pub const _SC_V7_ILP32_OFF32: c_int = 237; + +pub const _SC_V7_ILP32_OFFBIG: c_int = 238; + +pub const _SC_V7_LP64_OFF64: c_int = 239; + +pub const _SC_V7_LPBIG_OFFBIG: c_int = 240; + +pub const _SC_SS_REPL_MAX: c_int = 241; + +pub const _SC_TRACE_EVENT_NAME_MAX: c_int = 242; + +pub const _SC_TRACE_NAME_MAX: c_int = 243; + +pub const _SC_TRACE_SYS_MAX: c_int = 244; + +pub const _SC_TRACE_USER_EVENT_MAX: c_int = 245; + +pub const _SC_XOPEN_STREAMS: c_int = 246; + +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: c_int = 247; + +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: c_int = 248; + +// limits.h +pub const PTHREAD_KEYS_MAX: c_int = 128; + +pub const PTHREAD_STACK_MIN: c_int = 2048; + +pub const PTHREAD_DESTRUCTOR_ITERATIONS: c_int = 4; + +pub const SEM_VALUE_MAX: c_int = 0x7fffffff; + +pub const SEM_NSEMS_MAX: c_int = 256; + +pub const DELAYTIMER_MAX: c_int = 0x7fffffff; + +pub const MQ_PRIO_MAX: c_int = 32768; + +pub const LOGIN_NAME_MAX: c_int = 256; + +// time.h +pub const CLOCK_REALTIME: clockid_t = 0; + +pub const CLOCK_MONOTONIC: clockid_t = 1; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], +}; + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], +}; + +pub const PTHREAD_MUTEX_NORMAL: c_int = 0; + +pub const PTHREAD_MUTEX_RECURSIVE: c_int = 1; + +pub const PTHREAD_MUTEX_ERRORCHECK: c_int = 2; + +pub const PTHREAD_MUTEX_DEFAULT: c_int = PTHREAD_MUTEX_NORMAL; + +pub const PTHREAD_MUTEX_STALLED: c_int = 0; + +pub const PTHREAD_MUTEX_ROBUST: c_int = 1; + +extern "C" { + // ---- ALLOC ----------------------------------------------------------------------------- + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + + pub fn malloc(size: size_t) -> *mut c_void; + + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + + pub fn aligned_alloc(align: size_t, len: size_t) -> *mut c_void; + + pub fn free(p: *mut c_void); + + pub fn posix_memalign(memptr: *mut *mut c_void, align: size_t, size: size_t) -> c_int; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + // ----- PTHREAD --------------------------------------------------------------------------- + pub fn pthread_self() -> pthread_t; + + pub fn pthread_join(native: pthread_t, value: *mut *mut c_void) -> c_int; + + // detach or pthread_attr_setdetachstate must not be called! + //pub fn pthread_detach(thread: pthread_t) -> c_int; + + pub fn pthread_exit(value: *mut c_void) -> !; + + pub fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int; + + pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> c_int; + + pub fn pthread_attr_getstack( + attr: *const pthread_attr_t, + stackaddr: *mut *mut c_void, + stacksize: *mut size_t, + ) -> c_int; + + pub fn pthread_attr_setstacksize(attr: *mut pthread_attr_t, stack_size: size_t) -> c_int; + + pub fn pthread_attr_getstacksize(attr: *const pthread_attr_t, size: *mut size_t) -> c_int; + + pub fn pthread_attr_settee( + attr: *mut pthread_attr_t, + ca: c_int, + task_id: c_int, + shadow: c_int, + ) -> c_int; + + // C-TA API do not include this interface, but TA can use. + pub fn sched_yield() -> c_int; + + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: Option, + ) -> c_int; + + pub fn pthread_key_delete(key: pthread_key_t) -> c_int; + + pub fn pthread_getspecific(key: pthread_key_t) -> *mut c_void; + + pub fn pthread_setspecific(key: pthread_key_t, value: *const c_void) -> c_int; + + pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_init( + lock: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> c_int; + + pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> c_int; + + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int; + + pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: c_int) -> c_int; + + pub fn pthread_mutexattr_setpshared(attr: *mut pthread_mutexattr_t, pshared: c_int) -> c_int; + + pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int; + + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int; + + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) -> c_int; + + pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int; + + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + + pub fn pthread_mutexattr_setrobust(attr: *mut pthread_mutexattr_t, robustness: c_int) -> c_int; + + pub fn pthread_create( + native: *mut pthread_t, + attr: *const pthread_attr_t, + f: extern "C" fn(*mut c_void) -> *mut c_void, + value: *mut c_void, + ) -> c_int; + + pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: c_int) -> c_int; + + pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> c_int; + + pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> c_int; + + pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> c_int; + + pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> c_int; + + pub fn pthread_setschedprio(native: pthread_t, priority: c_int) -> c_int; + + pub fn pthread_once(pot: *mut pthread_once_t, f: Option) -> c_int; + + pub fn pthread_equal(p1: pthread_t, p2: pthread_t) -> c_int; + + pub fn pthread_mutexattr_setprotocol(a: *mut pthread_mutexattr_t, protocol: c_int) -> c_int; + + pub fn pthread_attr_setstack( + attr: *mut pthread_attr_t, + stack: *mut c_void, + size: size_t, + ) -> c_int; + + pub fn pthread_setaffinity_np(td: pthread_t, size: size_t, set: *const cpu_set_t) -> c_int; + + pub fn pthread_getaffinity_np(td: pthread_t, size: size_t, set: *mut cpu_set_t) -> c_int; + + // stdio.h + pub fn printf(fmt: *const c_char, ...) -> c_int; + + pub fn scanf(fmt: *const c_char, ...) -> c_int; + + pub fn snprintf(s: *mut c_char, n: size_t, fmt: *const c_char, ...) -> c_int; + + pub fn sprintf(s: *mut c_char, fmt: *const c_char, ...) -> c_int; + + pub fn vsnprintf(s: *mut c_char, n: size_t, fmt: *const c_char, ap: va_list) -> c_int; + + pub fn vsprintf(s: *mut c_char, fmt: *const c_char, ap: va_list) -> c_int; + + // Not available. + //pub fn pthread_setname_np(thread: pthread_t, name: *const c_char) -> c_int; + + pub fn abort() -> !; + + // Not available. + //pub fn prctl(op: c_int, ...) -> c_int; + + pub fn sched_getaffinity(pid: pid_t, cpusetsize: size_t, cpuset: *mut cpu_set_t) -> c_int; + + pub fn sched_setaffinity(pid: pid_t, cpusetsize: size_t, cpuset: *const cpu_set_t) -> c_int; + + // sysconf is currently only implemented as a stub. + pub fn sysconf(name: c_int) -> c_long; + + // mman.h + pub fn mmap( + addr: *mut c_void, + len: size_t, + prot: c_int, + flags: c_int, + fd: c_int, + offset: off_t, + ) -> *mut c_void; + pub fn munmap(addr: *mut c_void, len: size_t) -> c_int; + + // errno.h + pub fn __errno_location() -> *mut c_int; + + pub fn strerror(e: c_int) -> *mut c_char; + + // time.h + pub fn clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> c_int; + + // unistd + pub fn getpid() -> pid_t; + + // time + pub fn gettimeofday(tv: *mut timeval, tz: *mut c_void) -> c_int; + + pub fn strftime( + restrict: *mut c_char, + sz: size_t, + _restrict: *const c_char, + __restrict: *const tm, + ) -> size_t; + + pub fn time(t: *mut time_t) -> time_t; + + // sem + pub fn sem_close(sem: *mut sem_t) -> c_int; + + pub fn sem_destroy(sem: *mut sem_t) -> c_int; + + pub fn sem_getvalue(sem: *mut sem_t, valp: *mut c_int) -> c_int; + + pub fn sem_init(sem: *mut sem_t, pshared: c_int, value: c_uint) -> c_int; + + pub fn sem_open(name: *const c_char, flags: c_int, ...) -> *mut sem_t; + + pub fn sem_post(sem: *mut sem_t) -> c_int; + + pub fn sem_unlink(name: *const c_char) -> c_int; + + pub fn sem_wait(sem: *mut sem_t) -> c_int; + + // locale + pub fn setlocale(cat: c_int, name: *const c_char) -> *mut c_char; + + pub fn strcoll(l: *const c_char, r: *const c_char) -> c_int; + + pub fn strxfrm(dest: *mut c_char, src: *const c_char, n: size_t) -> size_t; + + pub fn strtod(s: *const c_char, p: *mut *mut c_char) -> c_double; + + // multibyte + pub fn mbrtowc(wc: *mut wchar_t, src: *const c_char, n: size_t, st: *mut mbstate_t) -> size_t; + + pub fn wcrtomb(s: *mut c_char, wc: wchar_t, st: *mut mbstate_t) -> size_t; + + pub fn wctob(c: wint_t) -> c_int; + + // prng + pub fn srandom(seed: c_uint); + + pub fn initstate(seed: c_uint, state: *mut c_char, size: size_t) -> *mut c_char; + + pub fn setstate(state: *mut c_char) -> *mut c_char; + + pub fn random() -> c_long; + + // string + pub fn strchr(s: *const c_char, c: c_int) -> *mut c_char; + + pub fn strlen(cs: *const c_char) -> size_t; + + pub fn strcmp(l: *const c_char, r: *const c_char) -> c_int; + + pub fn strcpy(dest: *mut c_char, src: *const c_char) -> *mut c_char; + + pub fn strncmp(_l: *const c_char, r: *const c_char, n: size_t) -> c_int; + + pub fn strncpy(dest: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + + pub fn strnlen(cs: *const c_char, n: size_t) -> size_t; + + pub fn strrchr(s: *const c_char, c: c_int) -> *mut c_char; + + pub fn strstr(h: *const c_char, n: *const c_char) -> *mut c_char; + + pub fn wcschr(s: *const wchar_t, c: wchar_t) -> *mut wchar_t; + + pub fn wcslen(s: *const wchar_t) -> size_t; + + // ctype + pub fn isalpha(c: c_int) -> c_int; + + pub fn isascii(c: c_int) -> c_int; + + pub fn isdigit(c: c_int) -> c_int; + + pub fn islower(c: c_int) -> c_int; + + pub fn isprint(c: c_int) -> c_int; + + pub fn isspace(c: c_int) -> c_int; + + pub fn iswctype(wc: wint_t, ttype: wctype_t) -> c_int; + + pub fn iswdigit(wc: wint_t) -> c_int; + + pub fn iswlower(wc: wint_t) -> c_int; + + pub fn iswspace(wc: wint_t) -> c_int; + + pub fn iswupper(wc: wint_t) -> c_int; + + pub fn towupper(wc: wint_t) -> wint_t; + + pub fn towlower(wc: wint_t) -> wint_t; + + // cmath + pub fn atan(x: c_double) -> c_double; + + pub fn ceil(x: c_double) -> c_double; + + pub fn ceilf(x: c_float) -> c_float; + + pub fn exp(x: c_double) -> c_double; + + pub fn fabs(x: c_double) -> c_double; + + pub fn floor(x: c_double) -> c_double; + + pub fn frexp(x: c_double, e: *mut c_int) -> c_double; + + pub fn log(x: c_double) -> c_double; + + pub fn log2(x: c_double) -> c_double; + + pub fn pow(x: c_double, y: c_double) -> c_double; + + pub fn roundf(x: c_float) -> c_float; + + pub fn scalbn(x: c_double, n: c_int) -> c_double; + + pub fn sqrt(x: c_double) -> c_double; + + // stdlib + pub fn abs(x: c_int) -> c_int; + + pub fn atof(s: *const c_char) -> c_double; + + pub fn atoi(s: *const c_char) -> c_int; + + pub fn atol(s: *const c_char) -> c_long; + + pub fn atoll(s: *const c_char) -> c_longlong; + + pub fn bsearch( + key: *const c_void, + base: *const c_void, + nel: size_t, + width: size_t, + cmp: cmpfunc, + ) -> *mut c_void; + + pub fn div(num: c_int, den: c_int) -> div_t; + + pub fn ecvt(x: c_double, n: c_int, dp: *mut c_int, sign: *mut c_int) -> *mut c_char; + + pub fn imaxabs(a: intmax_t) -> intmax_t; + + pub fn llabs(a: c_longlong) -> c_longlong; + + pub fn qsort(base: *mut c_void, nel: size_t, width: size_t, cmp: cmpfunc); + + pub fn strtoul(s: *const c_char, p: *mut *mut c_char, base: c_int) -> c_ulong; + + pub fn strtol(s: *const c_char, p: *mut *mut c_char, base: c_int) -> c_long; + + pub fn wcstod(s: *const wchar_t, p: *mut *mut wchar_t) -> c_double; +} + +pub fn errno() -> c_int { + unsafe { *__errno_location() } +} + +pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> c_int { + let mut s: u32 = 0; + let size_of_mask = core::mem::size_of_val(&cpuset.bits[0]); + + for i in cpuset.bits[..(size / size_of_mask)].iter() { + s += i.count_ones(); + } + s as c_int +} + +pub fn CPU_COUNT(cpuset: &cpu_set_t) -> c_int { + CPU_COUNT_S(core::mem::size_of::(), cpuset) +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/aix/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/aix/mod.rs new file mode 100644 index 00000000..0fc923d6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/aix/mod.rs @@ -0,0 +1,3362 @@ +pub type c_char = i8; +pub type caddr_t = *mut ::c_char; +pub type clockid_t = ::c_longlong; +pub type blkcnt_t = ::c_long; +pub type clock_t = ::c_int; +pub type daddr_t = ::c_long; +pub type dev_t = ::c_ulong; +pub type fpos64_t = ::c_longlong; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type idtype_t = ::c_int; +pub type ino_t = ::c_ulong; +pub type key_t = ::c_int; +pub type mode_t = ::c_uint; +pub type nlink_t = ::c_short; +pub type rlim_t = ::c_ulong; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type time_t = ::c_long; +pub type time64_t = ::int64_t; +pub type timer_t = ::c_long; +pub type wchar_t = ::c_uint; +pub type nfds_t = ::c_int; +pub type projid_t = ::c_int; +pub type id_t = ::c_uint; +pub type blksize64_t = ::c_ulonglong; +pub type blkcnt64_t = ::c_ulonglong; +pub type sctp_assoc_t = ::uint32_t; + +pub type suseconds_t = ::c_int; +pub type useconds_t = ::c_uint; +pub type off_t = ::c_long; +pub type off64_t = ::c_longlong; + +pub type socklen_t = ::c_uint; +pub type sa_family_t = ::c_uchar; +pub type in_port_t = ::c_ushort; +pub type in_addr_t = ::c_uint; + +pub type signal_t = ::c_int; +pub type pthread_t = ::c_uint; +pub type pthread_key_t = ::c_uint; +pub type thread_t = pthread_t; +pub type blksize_t = ::c_long; +pub type nl_item = ::c_int; +pub type mqd_t = ::c_int; +pub type shmatt_t = ::c_ulong; +pub type regoff_t = ::c_long; +pub type rlim64_t = ::c_ulonglong; + +pub type sem_t = ::c_int; +pub type pollset_t = ::c_int; + +pub type pthread_rwlockattr_t = *mut ::c_void; +pub type pthread_condattr_t = *mut ::c_void; +pub type pthread_mutexattr_t = *mut ::c_void; +pub type pthread_attr_t = *mut ::c_void; +pub type pthread_barrierattr_t = *mut ::c_void; +pub type posix_spawn_file_actions_t = *mut ::c_char; +pub type iconv_t = *mut ::c_void; + +e! { + pub enum uio_rw { + UIO_READ = 0, + UIO_WRITE, + UIO_READ_NO_MOVE, + UIO_WRITE_NO_MOVE, + UIO_PWRITE, + } +} + +s! { + pub struct fsid_t { + pub val: [::c_uint; 2], + } + + pub struct fsid64_t { + pub val: [::uint64_t; 2], + } + + pub struct timezone { + pub tz_minuteswest: ::c_int, + pub tz_dsttime: ::c_int, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct dirent { + pub d_offset: ::c_ulong, + pub d_ino: ::ino_t, + pub d_reclen: ::c_ushort, + pub d_namlen: ::c_ushort, + pub d_name: [::c_char; 256] + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS] + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_sysid: ::c_uint, + pub l_pid: ::pid_t, + pub l_vfs: ::c_int, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: socklen_t, + pub msg_flags: ::c_int, + } + + pub struct statvfs64 { + pub f_bsize: ::blksize64_t, + pub f_frsize: ::blksize64_t, + pub f_blocks: ::blkcnt64_t, + pub f_bfree: ::blkcnt64_t, + pub f_bavail: ::blkcnt64_t, + pub f_files: ::blkcnt64_t, + pub f_ffree: ::blkcnt64_t, + pub f_favail: ::blkcnt64_t, + pub f_fsid: fsid64_t, + pub f_basetype: [::c_char; 16], + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_fstr: [::c_char; 32], + pub f_filler: [::c_ulong; 16] + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub left_parenthesis: *mut ::c_char, + pub right_parenthesis: *mut ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::c_ulong, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + pub ai_eflags: ::c_int, + } + + pub struct in_addr { + pub s_addr: in_addr_t + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_sourceaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr { + pub sa_len: ::c_uchar, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 120], + } + + pub struct sockaddr_in { + pub sin_len: ::c_uchar, + pub sin_family: sa_family_t, + pub sin_port: in_port_t, + pub sin_addr: in_addr, + pub sin_zero: [::c_char; 8] + } + + pub struct sockaddr_in6 { + pub sin6_len: ::c_uchar, + pub sin6_family: ::c_uchar, + pub sin6_port: ::uint16_t, + pub sin6_flowinfo: ::uint32_t, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: ::uint32_t + } + + pub struct sockaddr_storage { + pub __ss_len: ::c_uchar, + pub ss_family: sa_family_t, + __ss_pad1: [::c_char; 6], + __ss_align: ::int64_t, + __ss_pad2: [::c_char; 1265], + } + + pub struct sockaddr_un { + pub sun_len: ::c_uchar, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 1023] + } + + pub struct st_timespec { + pub tv_sec: ::time_t, + pub tv_nsec: ::c_int, + } + + pub struct statfs64 { + pub f_version: ::c_int, + pub f_type: ::c_int, + pub f_bsize: blksize64_t, + pub f_blocks: blkcnt64_t, + pub f_bfree: blkcnt64_t, + pub f_bavail: blkcnt64_t, + pub f_files: ::uint64_t, + pub f_ffree: ::uint64_t, + pub f_fsid: fsid64_t, + pub f_vfstype: ::c_int, + pub f_fsize: blksize64_t, + pub f_vfsnumber: ::c_int, + pub f_vfsoff: ::c_int, + pub f_vfslen: ::c_int, + pub f_vfsvers: ::c_int, + pub f_fname: [::c_char; 32], + pub f_fpack: [::c_char; 32], + pub f_name_max: ::c_int, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char + } + + pub struct utsname { + pub sysname: [::c_char; 32], + pub nodename: [::c_char; 32], + pub release: [::c_char; 32], + pub version: [::c_char; 32], + pub machine: [::c_char; 32], + } + + pub struct xutsname { + pub nid: ::c_uint, + pub reserved: ::c_int, + pub longnid: ::c_ulonglong, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + pub sigev_notify_function: extern fn(val: ::sigval), + pub sigev_notify_attributes: *mut pthread_attr_t, + } + + // Should be union with another 'sival_int' + pub struct sigval64 { + pub sival_ptr: ::c_ulonglong, + } + + pub struct sigevent64 { + pub sigev_value: sigval64, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + pub sigev_notify_function: ::c_ulonglong, + pub sigev_notify_attributes: ::c_ulonglong, + } + + pub struct osigevent { + pub sevt_value: *mut ::c_void, + pub sevt_signo: signal_t, + } + + pub struct poll_ctl { + pub cmd: ::c_short, + pub events: ::c_short, + pub fd: ::c_int, + } + + pub struct sf_parms { + pub header_data: *mut ::c_void, + pub header_length: ::c_uint, + pub file_descriptor: ::c_int, + pub file_size: ::uint64_t, + pub file_offset: ::uint64_t, + pub file_bytes: ::int64_t, + pub trailer_data: *mut ::c_void, + pub trailer_length: ::c_uint, + pub bytes_sent: ::uint64_t, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + pub sched_policy: ::c_int, + pub sched_reserved: [::c_int; 6], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + pub __pad: [::c_int; 4], + } + + pub struct posix_spawnattr_t { + pub posix_attr_flags: ::c_short, + pub posix_attr_pgroup: ::pid_t, + pub posix_attr_sigmask: ::sigset_t, + pub posix_attr_sigdefault: ::sigset_t, + pub posix_attr_schedpolicy: ::c_int, + pub posix_attr_schedparam: sched_param, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_padr: *mut ::c_void, + pub gl_ptx: *mut ::c_void, + } + + pub struct mallinfo { + pub arena: ::c_ulong, + pub ordblks: ::c_int, + pub smblks: ::c_int, + pub hblks: ::c_int, + pub hblkhd: ::c_int, + pub usmblks: ::c_ulong, + pub fsmblks: ::c_ulong, + pub uordblks: ::c_ulong, + pub fordblks: ::c_ulong, + pub keepcost: ::c_int, + } + + pub struct utmp_exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + pub struct utmp { + pub ut_user: [::c_char; 256], + pub ut_id: [::c_char; 14], + pub ut_line: [::c_char; 64], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_time: time64_t, + pub ut_exit: utmp_exit_status, + pub ut_host: [::c_char; 256], + pub __dbl_word_pad: ::c_int, + pub __reservedA: [::c_int; 2], + pub __reservedV: [::c_int; 6], + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct regex_t { + pub re_nsub: ::size_t, + pub re_comp: *mut ::c_void, + pub re_cflags: ::c_int, + pub re_erroff: ::size_t, + pub re_len: ::size_t, + pub re_ucoll: [::wchar_t; 2], + pub re_lsub: [*mut ::c_void; 24], + pub re_esub: [*mut ::c_void; 24], + pub re_map: *mut ::c_uchar, + pub __maxsub: ::c_int, + pub __unused: [*mut ::c_void; 34], + } + + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct shmid_ds { + pub shm_perm: ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: shmatt_t, + pub shm_cnattch: shmatt_t, + pub shm_atime: time_t, + pub shm_dtime: time_t, + pub shm_ctime: time_t, + pub shm_handle: ::uint32_t, + pub shm_extshm: ::c_int, + pub shm_pagesize: ::int64_t, + pub shm_lba: ::uint64_t, + pub shm_reserved: ::int64_t, + pub shm_reserved1: ::int64_t, + } + + pub struct stat64 { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: mode_t, + pub st_nlink: nlink_t, + pub st_flag: ::c_ushort, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: dev_t, + pub st_ssize: ::c_int, + pub st_atim: st_timespec, + pub st_mtim: st_timespec, + pub st_ctim: st_timespec, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_vfstype: ::c_int, + pub st_vfs: ::c_uint, + pub st_type: ::c_uint, + pub st_gen: ::c_uint, + pub st_reserved: [::c_uint; 10], + pub st_size: off64_t, + } + + pub struct mntent { + pub mnt_fsname: *mut ::c_char, + pub mnt_dir: *mut ::c_char, + pub mnt_type: *mut ::c_char, + pub mnt_opts: *mut ::c_char, + pub mnt_freq: ::c_int, + pub mnt_passno: ::c_int, + } + + pub struct ipc_perm { + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: mode_t, + pub seq: ::c_ushort, + pub __reserved: ::c_ushort, + pub key: key_t, + } + + pub struct entry { + pub key: *mut ::c_char, + pub data: *mut ::c_void, + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } +} + +s_no_extra_traits! { + #[cfg(libc_union)] + pub union __sigaction_sa_union { + pub __su_handler: extern fn(c: ::c_int), + pub __su_sigaction: extern fn(c: ::c_int, info: *mut siginfo_t, ptr: *mut ::c_void), + } + + pub struct sigaction { + #[cfg(libc_union)] + pub sa_union: __sigaction_sa_union, + pub sa_mask: sigset_t, + pub sa_flags: ::c_int, + } + + #[cfg(libc_union)] + pub union __poll_ctl_ext_u { + pub addr: *mut ::c_void, + pub data32: u32, + pub data: u64, + } + + pub struct poll_ctl_ext { + pub version: u8, + pub command: u8, + pub events: ::c_short, + pub fd: ::c_int, + #[cfg(libc_union)] + pub u: __poll_ctl_ext_u, + pub reversed64: [u64; 6], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[cfg(libc_union)] + impl PartialEq for __sigaction_sa_union { + fn eq(&self, other: &__sigaction_sa_union) -> bool { + unsafe { + self.__su_handler == other.__su_handler + && self.__su_sigaction == other.__su_sigaction + } + } + } + #[cfg(libc_union)] + impl Eq for __sigaction_sa_union {} + #[cfg(libc_union)] + impl ::fmt::Debug for __sigaction_sa_union { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__sigaction_sa_union") + .field("__su_handler", unsafe { &self.__su_handler }) + .field("__su_sigaction", unsafe { &self.__su_sigaction }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __sigaction_sa_union { + fn hash(&self, state: &mut H) { + unsafe { + self.__su_handler.hash(state); + self.__su_sigaction.hash(state); + } + } + } + + impl PartialEq for sigaction { + fn eq(&self, other: &sigaction) -> bool { + #[cfg(libc_union)] + let union_eq = self.sa_union == other.sa_union; + #[cfg(not(libc_union))] + let union_eq = true; + self.sa_mask == other.sa_mask + && self.sa_flags == other.sa_flags + && union_eq + } + } + impl Eq for sigaction {} + impl ::fmt::Debug for sigaction { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("sigaction"); + #[cfg(libc_union)] + struct_formatter.field("sa_union", &self.sa_union); + struct_formatter.field("sa_mask", &self.sa_mask); + struct_formatter.field("sa_flags", &self.sa_flags); + struct_formatter.finish() + } + } + impl ::hash::Hash for sigaction { + fn hash(&self, state: &mut H) { + #[cfg(libc_union)] + self.sa_union.hash(state); + self.sa_mask.hash(state); + self.sa_flags.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __poll_ctl_ext_u { + fn eq(&self, other: &__poll_ctl_ext_u) -> bool { + unsafe { + self.addr == other.addr + && self.data32 == other.data32 + && self.data == other.data + } + } + } + #[cfg(libc_union)] + impl Eq for __poll_ctl_ext_u {} + #[cfg(libc_union)] + impl ::fmt::Debug for __poll_ctl_ext_u { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__poll_ctl_ext_u") + .field("addr", unsafe { &self.addr }) + .field("data32", unsafe { &self.data32 }) + .field("data", unsafe { &self.data }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __poll_ctl_ext_u { + fn hash(&self, state: &mut H) { + unsafe { + self.addr.hash(state); + self.data32.hash(state); + self.data.hash(state); + } + } + } + + impl PartialEq for poll_ctl_ext { + fn eq(&self, other: &poll_ctl_ext) -> bool { + #[cfg(libc_union)] + let union_eq = self.u == other.u; + #[cfg(not(libc_union))] + let union_eq = true; + self.version == other.version + && self.command == other.command + && self.events == other.events + && self.fd == other.fd + && self.reversed64 == other.reversed64 + && union_eq + } + } + impl Eq for poll_ctl_ext {} + impl ::fmt::Debug for poll_ctl_ext { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("poll_ctl_ext"); + struct_formatter.field("version", &self.version); + struct_formatter.field("command", &self.command); + struct_formatter.field("events", &self.events); + struct_formatter.field("fd", &self.fd); + #[cfg(libc_union)] + struct_formatter.field("u", &self.u); + struct_formatter.field("reversed64", &self.reversed64); + struct_formatter.finish() + } + } + impl ::hash::Hash for poll_ctl_ext { + fn hash(&self, state: &mut H) { + self.version.hash(state); + self.command.hash(state); + self.events.hash(state); + self.fd.hash(state); + #[cfg(libc_union)] + self.u.hash(state); + self.reversed64.hash(state); + } + } + } +} + +// dlfcn.h +pub const RTLD_LAZY: ::c_int = 0x4; +pub const RTLD_NOW: ::c_int = 0x2; +pub const RTLD_GLOBAL: ::c_int = 0x10000; +pub const RTLD_LOCAL: ::c_int = 0x80000; +pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void; +pub const RTLD_MYSELF: *mut ::c_void = -2isize as *mut ::c_void; +pub const RTLD_NEXT: *mut ::c_void = -3isize as *mut ::c_void; + +// fcntl.h +pub const O_RDONLY: ::c_int = 0x0; +pub const O_WRONLY: ::c_int = 0x1; +pub const O_RDWR: ::c_int = 0x2; +pub const O_NDELAY: ::c_int = 0x8000; +pub const O_APPEND: ::c_int = 0x8; +pub const O_DSYNC: ::c_int = 0x400000; +pub const O_CREAT: ::c_int = 0x100; +pub const O_EXCL: ::c_int = 0x400; +pub const O_NOCTTY: ::c_int = 0x800; +pub const O_TRUNC: ::c_int = 0x200; +pub const O_NOFOLLOW: ::c_int = 0x1000000; +pub const O_DIRECTORY: ::c_int = 0x80000; +pub const O_SEARCH: ::c_int = 0x20; +pub const O_EXEC: ::c_int = 0x20; +pub const O_CLOEXEC: ::c_int = 0x800000; +pub const O_ACCMODE: ::c_int = O_RDONLY | O_WRONLY | O_RDWR; +pub const O_DIRECT: ::c_int = 0x8000000; +pub const O_TTY_INIT: ::c_int = 0; +pub const O_RSYNC: ::c_int = 0x200000; +pub const O_LARGEFILE: ::c_int = 0x4000000; +pub const F_CLOSEM: ::c_int = 10; +pub const F_DUPFD_CLOEXEC: ::c_int = 16; +pub const F_GETLK64: ::c_int = 11; +pub const F_SETLK64: ::c_int = 12; +pub const F_SETLKW64: ::c_int = 13; +pub const F_DUP2FD: ::c_int = 14; +pub const F_TSTLK: ::c_int = 15; +pub const F_GETLK: ::c_int = F_GETLK64; +pub const F_SETLK: ::c_int = F_SETLK64; +pub const F_SETLKW: ::c_int = F_SETLKW64; +pub const F_GETOWN: ::c_int = 8; +pub const F_SETOWN: ::c_int = 9; +pub const AT_FDCWD: ::c_int = -2; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 1; +pub const AT_SYMLINK_FOLLOW: ::c_int = 2; +pub const AT_REMOVEDIR: ::c_int = 1; +pub const AT_EACCESS: ::c_int = 1; +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +pub const O_SYNC: ::c_int = 16; +pub const O_NONBLOCK: ::c_int = 4; +pub const FASYNC: ::c_int = 0x20000; +pub const POSIX_FADV_NORMAL: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_RANDOM: ::c_int = 3; +pub const POSIX_FADV_WILLNEED: ::c_int = 4; +pub const POSIX_FADV_DONTNEED: ::c_int = 5; +pub const POSIX_FADV_NOREUSE: ::c_int = 6; + +// glob.h +pub const GLOB_APPEND: ::c_int = 0x1; +pub const GLOB_DOOFFS: ::c_int = 0x2; +pub const GLOB_ERR: ::c_int = 0x4; +pub const GLOB_MARK: ::c_int = 0x8; +pub const GLOB_NOCHECK: ::c_int = 0x10; +pub const GLOB_NOSORT: ::c_int = 0x20; +pub const GLOB_NOESCAPE: ::c_int = 0x80; +pub const GLOB_NOSPACE: ::c_int = 0x2000; +pub const GLOB_ABORTED: ::c_int = 0x1000; +pub const GLOB_NOMATCH: ::c_int = 0x4000; +pub const GLOB_NOSYS: ::c_int = 0x8000; + +// langinfo.h +pub const DAY_1: ::nl_item = 13; +pub const DAY_2: ::nl_item = 14; +pub const DAY_3: ::nl_item = 15; +pub const DAY_4: ::nl_item = 16; +pub const DAY_5: ::nl_item = 17; +pub const DAY_6: ::nl_item = 18; +pub const DAY_7: ::nl_item = 19; +pub const ABDAY_1: ::nl_item = 6; +pub const ABDAY_2: ::nl_item = 7; +pub const ABDAY_3: ::nl_item = 8; +pub const ABDAY_4: ::nl_item = 9; +pub const ABDAY_5: ::nl_item = 10; +pub const ABDAY_6: ::nl_item = 11; +pub const ABDAY_7: ::nl_item = 12; +pub const MON_1: ::nl_item = 32; +pub const MON_2: ::nl_item = 33; +pub const MON_3: ::nl_item = 34; +pub const MON_4: ::nl_item = 35; +pub const MON_5: ::nl_item = 36; +pub const MON_6: ::nl_item = 37; +pub const MON_7: ::nl_item = 38; +pub const MON_8: ::nl_item = 39; +pub const MON_9: ::nl_item = 40; +pub const MON_10: ::nl_item = 41; +pub const MON_11: ::nl_item = 42; +pub const MON_12: ::nl_item = 43; +pub const ABMON_1: ::nl_item = 20; +pub const ABMON_2: ::nl_item = 21; +pub const ABMON_3: ::nl_item = 22; +pub const ABMON_4: ::nl_item = 23; +pub const ABMON_5: ::nl_item = 24; +pub const ABMON_6: ::nl_item = 25; +pub const ABMON_7: ::nl_item = 26; +pub const ABMON_8: ::nl_item = 27; +pub const ABMON_9: ::nl_item = 28; +pub const ABMON_10: ::nl_item = 29; +pub const ABMON_11: ::nl_item = 30; +pub const ABMON_12: ::nl_item = 31; +pub const RADIXCHAR: ::nl_item = 44; +pub const THOUSEP: ::nl_item = 45; +pub const YESSTR: ::nl_item = 46; +pub const NOSTR: ::nl_item = 47; +pub const CRNCYSTR: ::nl_item = 48; +pub const D_T_FMT: ::nl_item = 1; +pub const D_FMT: ::nl_item = 2; +pub const T_FMT: ::nl_item = 3; +pub const AM_STR: ::nl_item = 4; +pub const PM_STR: ::nl_item = 5; +pub const CODESET: ::nl_item = 49; +pub const T_FMT_AMPM: ::nl_item = 55; +pub const ERA: ::nl_item = 56; +pub const ERA_D_FMT: ::nl_item = 57; +pub const ERA_D_T_FMT: ::nl_item = 58; +pub const ERA_T_FMT: ::nl_item = 59; +pub const ALT_DIGITS: ::nl_item = 60; +pub const YESEXPR: ::nl_item = 61; +pub const NOEXPR: ::nl_item = 62; + +// locale.h +pub const LC_GLOBAL_LOCALE: ::locale_t = -1isize as ::locale_t; +pub const LC_CTYPE: ::c_int = 1; +pub const LC_NUMERIC: ::c_int = 3; +pub const LC_TIME: ::c_int = 4; +pub const LC_COLLATE: ::c_int = 0; +pub const LC_MONETARY: ::c_int = 2; +pub const LC_MESSAGES: ::c_int = 4; +pub const LC_ALL: ::c_int = -1; +pub const LC_CTYPE_MASK: ::c_int = 2; +pub const LC_NUMERIC_MASK: ::c_int = 16; +pub const LC_TIME_MASK: ::c_int = 32; +pub const LC_COLLATE_MASK: ::c_int = 1; +pub const LC_MONETARY_MASK: ::c_int = 8; +pub const LC_MESSAGES_MASK: ::c_int = 4; +pub const LC_ALL_MASK: ::c_int = LC_CTYPE_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK + | LC_COLLATE_MASK + | LC_MONETARY_MASK + | LC_MESSAGES_MASK; + +// netdb.h +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const NI_MAXSERV: ::socklen_t = 32; +pub const NI_NOFQDN: ::socklen_t = 0x1; +pub const NI_NUMERICHOST: ::socklen_t = 0x2; +pub const NI_NAMEREQD: ::socklen_t = 0x4; +pub const NI_NUMERICSERV: ::socklen_t = 0x8; +pub const NI_DGRAM: ::socklen_t = 0x10; +pub const NI_NUMERICSCOPE: ::socklen_t = 0x40; +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 13; +pub const AI_CANONNAME: ::c_int = 0x01; +pub const AI_PASSIVE: ::c_int = 0x02; +pub const AI_NUMERICHOST: ::c_int = 0x04; +pub const AI_ADDRCONFIG: ::c_int = 0x08; +pub const AI_V4MAPPED: ::c_int = 0x10; +pub const AI_ALL: ::c_int = 0x20; +pub const AI_NUMERICSERV: ::c_int = 0x40; +pub const AI_EXTFLAGS: ::c_int = 0x80; +pub const AI_DEFAULT: ::c_int = AI_V4MAPPED | AI_ADDRCONFIG; +pub const IPV6_ADDRFORM: ::c_int = 22; +pub const IPV6_ADDR_PREFERENCES: ::c_int = 74; +pub const IPV6_CHECKSUM: ::c_int = 39; +pub const IPV6_DONTFRAG: ::c_int = 45; +pub const IPV6_DSTOPTS: ::c_int = 54; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 16777215; +pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 251658240; +pub const IPV6_HOPLIMIT: ::c_int = 40; +pub const IPV6_HOPOPTS: ::c_int = 52; +pub const IPV6_NEXTHOP: ::c_int = 48; +pub const IPV6_PATHMTU: ::c_int = 46; +pub const IPV6_PKTINFO: ::c_int = 33; +pub const IPV6_PREFER_SRC_CGA: ::c_int = 16; +pub const IPV6_PREFER_SRC_COA: ::c_int = 2; +pub const IPV6_PREFER_SRC_HOME: ::c_int = 1; +pub const IPV6_PREFER_SRC_NONCGA: ::c_int = 32; +pub const IPV6_PREFER_SRC_PUBLIC: ::c_int = 4; +pub const IPV6_PREFER_SRC_TMP: ::c_int = 8; +pub const IPV6_RECVDSTOPTS: ::c_int = 56; +pub const IPV6_RECVHOPLIMIT: ::c_int = 41; +pub const IPV6_RECVHOPOPTS: ::c_int = 53; +pub const IPV6_RECVPATHMTU: ::c_int = 47; +pub const IPV6_RECVRTHDR: ::c_int = 51; +pub const IPV6_RECVTCLASS: ::c_int = 42; +pub const IPV6_RTHDR: ::c_int = 50; +pub const IPV6_RTHDRDSTOPTS: ::c_int = 55; +pub const IPV6_TCLASS: ::c_int = 43; + +// net/bpf.h +pub const DLT_NULL: ::c_int = 0x18; +pub const DLT_EN10MB: ::c_int = 0x6; +pub const DLT_EN3MB: ::c_int = 0x1a; +pub const DLT_AX25: ::c_int = 0x5; +pub const DLT_PRONET: ::c_int = 0xd; +pub const DLT_IEEE802: ::c_int = 0x7; +pub const DLT_ARCNET: ::c_int = 0x23; +pub const DLT_SLIP: ::c_int = 0x1c; +pub const DLT_PPP: ::c_int = 0x17; +pub const DLT_FDDI: ::c_int = 0xf; +pub const DLT_ATM: ::c_int = 0x25; +pub const DLT_IPOIB: ::c_int = 0xc7; +pub const BIOCSETF: ::c_ulong = 0x80104267; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; +pub const BIOCGBLEN: ::c_int = 0x40044266; +pub const BIOCSBLEN: ::c_int = 0xc0044266; +pub const BIOCFLUSH: ::c_int = 0x20004268; +pub const BIOCPROMISC: ::c_int = 0x20004269; +pub const BIOCGDLT: ::c_int = 0x4004426a; +pub const BIOCSRTIMEOUT: ::c_int = 0x8010426d; +pub const BIOCGSTATS: ::c_int = 0x4008426f; +pub const BIOCIMMEDIATE: ::c_int = 0x80044270; +pub const BIOCVERSION: ::c_int = 0x40044271; +pub const BIOCSDEVNO: ::c_int = 0x20004272; +pub const BIOCGETIF: ::c_ulong = 0x4020426b; +pub const BIOCSETIF: ::c_ulong = 0xffffffff8020426c; +pub const BPF_ABS: ::c_int = 32; +pub const BPF_ADD: ::c_int = 0; +pub const BPF_ALIGNMENT: ::c_ulong = 4; +pub const BPF_ALU: ::c_int = 4; +pub const BPF_AND: ::c_int = 80; +pub const BPF_B: ::c_int = 16; +pub const BPF_DIV: ::c_int = 48; +pub const BPF_H: ::c_int = 8; +pub const BPF_IMM: ::c_int = 0; +pub const BPF_IND: ::c_int = 64; +pub const BPF_JA: ::c_int = 0; +pub const BPF_JEQ: ::c_int = 16; +pub const BPF_JGE: ::c_int = 48; +pub const BPF_JGT: ::c_int = 32; +pub const BPF_JMP: ::c_int = 5; +pub const BPF_JSET: ::c_int = 64; +pub const BPF_K: ::c_int = 0; +pub const BPF_LD: ::c_int = 0; +pub const BPF_LDX: ::c_int = 1; +pub const BPF_LEN: ::c_int = 128; +pub const BPF_LSH: ::c_int = 96; +pub const BPF_MAXINSNS: ::c_int = 512; +pub const BPF_MEM: ::c_int = 96; +pub const BPF_MEMWORDS: ::c_int = 16; +pub const BPF_MISC: ::c_int = 7; +pub const BPF_MSH: ::c_int = 160; +pub const BPF_MUL: ::c_int = 32; +pub const BPF_NEG: ::c_int = 128; +pub const BPF_OR: ::c_int = 64; +pub const BPF_RET: ::c_int = 6; +pub const BPF_RSH: ::c_int = 112; +pub const BPF_ST: ::c_int = 2; +pub const BPF_STX: ::c_int = 3; +pub const BPF_SUB: ::c_int = 16; +pub const BPF_W: ::c_int = 0; +pub const BPF_X: ::c_int = 8; + +// net/if.h +pub const IFNET_SLOWHZ: ::c_int = 1; +pub const IFQ_MAXLEN: ::c_int = 50; +pub const IF_NAMESIZE: ::c_int = 16; +pub const IFNAMSIZ: ::c_int = 16; +pub const IFF_UP: ::c_int = 0x1; +pub const IFF_BROADCAST: ::c_int = 0x2; +pub const IFF_DEBUG: ::c_int = 0x4; +pub const IFF_LOOPBACK: ::c_int = 0x8; +pub const IFF_POINTOPOINT: ::c_int = 0x10; +pub const IFF_NOTRAILERS: ::c_int = 0x20; +pub const IFF_RUNNING: ::c_int = 0x40; +pub const IFF_NOARP: ::c_int = 0x80; +pub const IFF_PROMISC: ::c_int = 0x100; +pub const IFF_ALLMULTI: ::c_int = 0x200; +pub const IFF_MULTICAST: ::c_int = 0x80000; +pub const IFF_LINK0: ::c_int = 0x100000; +pub const IFF_LINK1: ::c_int = 0x200000; +pub const IFF_LINK2: ::c_int = 0x400000; +pub const IFF_OACTIVE: ::c_int = 0x400; +pub const IFF_SIMPLEX: ::c_int = 0x800; + +// net/if_arp.h +pub const ARPHRD_ETHER: ::c_int = 1; +pub const ARPHRD_802_5: ::c_int = 6; +pub const ARPHRD_802_3: ::c_int = 6; +pub const ARPHRD_FDDI: ::c_int = 1; +pub const ARPOP_REQUEST: ::c_int = 1; +pub const ARPOP_REPLY: ::c_int = 2; + +// net/route.h +pub const RTM_ADD: ::c_int = 0x1; +pub const RTM_DELETE: ::c_int = 0x2; +pub const RTM_CHANGE: ::c_int = 0x3; +pub const RTM_GET: ::c_int = 0x4; +pub const RTM_LOSING: ::c_int = 0x5; +pub const RTM_REDIRECT: ::c_int = 0x6; +pub const RTM_MISS: ::c_int = 0x7; +pub const RTM_LOCK: ::c_int = 0x8; +pub const RTM_OLDADD: ::c_int = 0x9; +pub const RTM_OLDDEL: ::c_int = 0xa; +pub const RTM_RESOLVE: ::c_int = 0xb; +pub const RTM_NEWADDR: ::c_int = 0xc; +pub const RTM_DELADDR: ::c_int = 0xd; +pub const RTM_IFINFO: ::c_int = 0xe; +pub const RTM_EXPIRE: ::c_int = 0xf; +pub const RTM_RTLOST: ::c_int = 0x10; +pub const RTM_GETNEXT: ::c_int = 0x11; +pub const RTM_SAMEADDR: ::c_int = 0x12; +pub const RTM_SET: ::c_int = 0x13; +pub const RTV_MTU: ::c_int = 0x1; +pub const RTV_HOPCOUNT: ::c_int = 0x2; +pub const RTV_EXPIRE: ::c_int = 0x4; +pub const RTV_RPIPE: ::c_int = 0x8; +pub const RTV_SPIPE: ::c_int = 0x10; +pub const RTV_SSTHRESH: ::c_int = 0x20; +pub const RTV_RTT: ::c_int = 0x40; +pub const RTV_RTTVAR: ::c_int = 0x80; +pub const RTA_DST: ::c_int = 0x1; +pub const RTA_GATEWAY: ::c_int = 0x2; +pub const RTA_NETMASK: ::c_int = 0x4; +pub const RTA_GENMASK: ::c_int = 0x8; +pub const RTA_IFP: ::c_int = 0x10; +pub const RTA_IFA: ::c_int = 0x20; +pub const RTA_AUTHOR: ::c_int = 0x40; +pub const RTA_BRD: ::c_int = 0x80; +pub const RTA_DOWNSTREAM: ::c_int = 0x100; +pub const RTAX_DST: ::c_int = 0; +pub const RTAX_GATEWAY: ::c_int = 1; +pub const RTAX_NETMASK: ::c_int = 2; +pub const RTAX_GENMASK: ::c_int = 3; +pub const RTAX_IFP: ::c_int = 4; +pub const RTAX_IFA: ::c_int = 5; +pub const RTAX_AUTHOR: ::c_int = 6; +pub const RTAX_BRD: ::c_int = 7; +pub const RTAX_MAX: ::c_int = 8; +pub const RTF_UP: ::c_int = 0x1; +pub const RTF_GATEWAY: ::c_int = 0x2; +pub const RTF_HOST: ::c_int = 0x4; +pub const RTF_REJECT: ::c_int = 0x8; +pub const RTF_DYNAMIC: ::c_int = 0x10; +pub const RTF_MODIFIED: ::c_int = 0x20; +pub const RTF_DONE: ::c_int = 0x40; +pub const RTF_MASK: ::c_int = 0x80; +pub const RTF_CLONING: ::c_int = 0x100; +pub const RTF_XRESOLVE: ::c_int = 0x200; +pub const RTF_LLINFO: ::c_int = 0x400; +pub const RTF_STATIC: ::c_int = 0x800; +pub const RTF_BLACKHOLE: ::c_int = 0x1000; +pub const RTF_BUL: ::c_int = 0x2000; +pub const RTF_PROTO2: ::c_int = 0x4000; +pub const RTF_PROTO1: ::c_int = 0x8000; +pub const RTF_CLONE: ::c_int = 0x10000; +pub const RTF_CLONED: ::c_int = 0x20000; +pub const RTF_PROTO3: ::c_int = 0x40000; +pub const RTF_BCE: ::c_int = 0x80000; +pub const RTF_PINNED: ::c_int = 0x100000; +pub const RTF_LOCAL: ::c_int = 0x200000; +pub const RTF_BROADCAST: ::c_int = 0x400000; +pub const RTF_MULTICAST: ::c_int = 0x800000; +pub const RTF_ACTIVE_DGD: ::c_int = 0x1000000; +pub const RTF_STOPSRCH: ::c_int = 0x2000000; +pub const RTF_FREE_IN_PROG: ::c_int = 0x4000000; +pub const RTF_PERMANENT6: ::c_int = 0x8000000; +pub const RTF_UNREACHABLE: ::c_int = 0x10000000; +pub const RTF_CACHED: ::c_int = 0x20000000; +pub const RTF_SMALLMTU: ::c_int = 0x40000; + +// netinet/in.h +pub const IPPROTO_HOPOPTS: ::c_int = 0; +pub const IPPROTO_IGMP: ::c_int = 2; +pub const IPPROTO_GGP: ::c_int = 3; +pub const IPPROTO_IPIP: ::c_int = 4; +pub const IPPROTO_EGP: ::c_int = 8; +pub const IPPROTO_PUP: ::c_int = 12; +pub const IPPROTO_IDP: ::c_int = 22; +pub const IPPROTO_TP: ::c_int = 29; +pub const IPPROTO_ROUTING: ::c_int = 43; +pub const IPPROTO_FRAGMENT: ::c_int = 44; +pub const IPPROTO_QOS: ::c_int = 45; +pub const IPPROTO_RSVP: ::c_int = 46; +pub const IPPROTO_GRE: ::c_int = 47; +pub const IPPROTO_ESP: ::c_int = 50; +pub const IPPROTO_AH: ::c_int = 51; +pub const IPPROTO_NONE: ::c_int = 59; +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_LOCAL: ::c_int = 63; +pub const IPPROTO_EON: ::c_int = 80; +pub const IPPROTO_BIP: ::c_int = 0x53; +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_MH: ::c_int = 135; +pub const IPPROTO_GIF: ::c_int = 140; +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MAX: ::c_int = 256; +pub const IP_OPTIONS: ::c_int = 1; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_TOS: ::c_int = 3; +pub const IP_TTL: ::c_int = 4; +pub const IP_UNICAST_HOPS: ::c_int = 4; +pub const IP_RECVOPTS: ::c_int = 5; +pub const IP_RECVRETOPTS: ::c_int = 6; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_RETOPTS: ::c_int = 8; +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_HOPS: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_RECVMACHDR: ::c_int = 14; +pub const IP_RECVIFINFO: ::c_int = 15; +pub const IP_BROADCAST_IF: ::c_int = 16; +pub const IP_DHCPMODE: ::c_int = 17; +pub const IP_RECVIF: ::c_int = 20; +pub const IP_ADDRFORM: ::c_int = 22; +pub const IP_DONTFRAG: ::c_int = 25; +pub const IP_FINDPMTU: ::c_int = 26; +pub const IP_PMTUAGE: ::c_int = 27; +pub const IP_RECVINTERFACE: ::c_int = 32; +pub const IP_RECVTTL: ::c_int = 34; +pub const IP_BLOCK_SOURCE: ::c_int = 58; +pub const IP_UNBLOCK_SOURCE: ::c_int = 59; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 60; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 61; +pub const IP_DEFAULT_MULTICAST_TTL: ::c_int = 1; +pub const IP_DEFAULT_MULTICAST_LOOP: ::c_int = 1; +pub const IP_INC_MEMBERSHIPS: ::c_int = 20; +pub const IP_INIT_MEMBERSHIP: ::c_int = 20; +pub const IPV6_UNICAST_HOPS: ::c_int = IP_TTL; +pub const IPV6_MULTICAST_IF: ::c_int = IP_MULTICAST_IF; +pub const IPV6_MULTICAST_HOPS: ::c_int = IP_MULTICAST_TTL; +pub const IPV6_MULTICAST_LOOP: ::c_int = IP_MULTICAST_LOOP; +pub const IPV6_RECVPKTINFO: ::c_int = 35; +pub const IPV6_V6ONLY: ::c_int = 37; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = IP_ADD_MEMBERSHIP; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = IP_DROP_MEMBERSHIP; +pub const IPV6_JOIN_GROUP: ::c_int = IP_ADD_MEMBERSHIP; +pub const IPV6_LEAVE_GROUP: ::c_int = IP_DROP_MEMBERSHIP; +pub const MCAST_BLOCK_SOURCE: ::c_int = 64; +pub const MCAST_EXCLUDE: ::c_int = 2; +pub const MCAST_INCLUDE: ::c_int = 1; +pub const MCAST_JOIN_GROUP: ::c_int = 62; +pub const MCAST_JOIN_SOURCE_GROUP: ::c_int = 66; +pub const MCAST_LEAVE_GROUP: ::c_int = 63; +pub const MCAST_LEAVE_SOURCE_GROUP: ::c_int = 67; +pub const MCAST_UNBLOCK_SOURCE: ::c_int = 65; + +// netinet/ip.h +pub const MAXTTL: ::c_int = 255; +pub const IPDEFTTL: ::c_int = 64; +pub const IPOPT_CONTROL: ::c_int = 0; +pub const IPOPT_EOL: ::c_int = 0; +pub const IPOPT_LSRR: ::c_int = 131; +pub const IPOPT_MINOFF: ::c_int = 4; +pub const IPOPT_NOP: ::c_int = 1; +pub const IPOPT_OFFSET: ::c_int = 2; +pub const IPOPT_OLEN: ::c_int = 1; +pub const IPOPT_OPTVAL: ::c_int = 0; +pub const IPOPT_RESERVED1: ::c_int = 0x20; +pub const IPOPT_RESERVED2: ::c_int = 0x60; +pub const IPOPT_RR: ::c_int = 7; +pub const IPOPT_SSRR: ::c_int = 137; +pub const IPOPT_TS: ::c_int = 68; +pub const IPOPT_TS_PRESPEC: ::c_int = 3; +pub const IPOPT_TS_TSANDADDR: ::c_int = 1; +pub const IPOPT_TS_TSONLY: ::c_int = 0; +pub const IPTOS_LOWDELAY: ::c_int = 16; +pub const IPTOS_PREC_CRITIC_ECP: ::c_int = 160; +pub const IPTOS_PREC_FLASH: ::c_int = 96; +pub const IPTOS_PREC_FLASHOVERRIDE: ::c_int = 128; +pub const IPTOS_PREC_IMMEDIATE: ::c_int = 64; +pub const IPTOS_PREC_INTERNETCONTROL: ::c_int = 192; +pub const IPTOS_PREC_NETCONTROL: ::c_int = 224; +pub const IPTOS_PREC_PRIORITY: ::c_int = 32; +pub const IPTOS_PREC_ROUTINE: ::c_int = 16; +pub const IPTOS_RELIABILITY: ::c_int = 4; +pub const IPTOS_THROUGHPUT: ::c_int = 8; +pub const IPVERSION: ::c_int = 4; + +// netinet/tcp.h +pub const TCP_NODELAY: ::c_int = 0x1; +pub const TCP_MAXSEG: ::c_int = 0x2; +pub const TCP_RFC1323: ::c_int = 0x4; +pub const TCP_KEEPALIVE: ::c_int = 0x8; +pub const TCP_KEEPIDLE: ::c_int = 0x11; +pub const TCP_KEEPINTVL: ::c_int = 0x12; +pub const TCP_KEEPCNT: ::c_int = 0x13; +pub const TCP_NODELAYACK: ::c_int = 0x14; + +// pthread.h +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 0; +pub const PTHREAD_PROCESS_PRIVATE: ::c_ushort = 1; +pub const PTHREAD_STACK_MIN: ::size_t = PAGESIZE as ::size_t * 4; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 5; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 3; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 4; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1; +pub const PTHREAD_MUTEX_STALLED: ::c_int = 0; +pub const PTHREAD_PRIO_INHERIT: ::c_int = 3; +pub const PTHREAD_PRIO_NONE: ::c_int = 1; +pub const PTHREAD_PRIO_PROTECT: ::c_int = 2; + +// regex.h +pub const REG_EXTENDED: ::c_int = 1; +pub const REG_ICASE: ::c_int = 2; +pub const REG_NEWLINE: ::c_int = 4; +pub const REG_NOSUB: ::c_int = 8; +pub const REG_NOTBOL: ::c_int = 0x100; +pub const REG_NOTEOL: ::c_int = 0x200; +pub const REG_NOMATCH: ::c_int = 1; +pub const REG_BADPAT: ::c_int = 2; +pub const REG_ECOLLATE: ::c_int = 3; +pub const REG_ECTYPE: ::c_int = 4; +pub const REG_EESCAPE: ::c_int = 5; +pub const REG_ESUBREG: ::c_int = 6; +pub const REG_EBRACK: ::c_int = 7; +pub const REG_EPAREN: ::c_int = 8; +pub const REG_EBRACE: ::c_int = 9; +pub const REG_BADBR: ::c_int = 10; +pub const REG_ERANGE: ::c_int = 11; +pub const REG_ESPACE: ::c_int = 12; +pub const REG_BADRPT: ::c_int = 13; +pub const REG_ECHAR: ::c_int = 14; +pub const REG_EBOL: ::c_int = 15; +pub const REG_EEOL: ::c_int = 16; +pub const REG_ENOSYS: ::c_int = 17; + +// rpcsvc/mount.h +pub const NFSMNT_ACDIRMAX: ::c_int = 2048; +pub const NFSMNT_ACDIRMIN: ::c_int = 1024; +pub const NFSMNT_ACREGMAX: ::c_int = 512; +pub const NFSMNT_ACREGMIN: ::c_int = 256; +pub const NFSMNT_INT: ::c_int = 64; +pub const NFSMNT_NOAC: ::c_int = 128; +pub const NFSMNT_RETRANS: ::c_int = 16; +pub const NFSMNT_RSIZE: ::c_int = 4; +pub const NFSMNT_SOFT: ::c_int = 1; +pub const NFSMNT_TIMEO: ::c_int = 8; +pub const NFSMNT_WSIZE: ::c_int = 2; + +// rpcsvc/rstat.h +pub const CPUSTATES: ::c_int = 4; + +// search.h +pub const FIND: ::c_int = 0; +pub const ENTER: ::c_int = 1; + +// semaphore.h +pub const SEM_FAILED: *mut sem_t = -1isize as *mut ::sem_t; + +// spawn.h +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x1; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x2; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x4; +pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x8; +pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x10; +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x20; +pub const POSIX_SPAWN_FORK_HANDLERS: ::c_int = 0x1000; + +// stdio.h +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0o000; +pub const _IONBF: ::c_int = 0o004; +pub const _IOLBF: ::c_int = 0o100; +pub const BUFSIZ: ::c_uint = 4096; +pub const FOPEN_MAX: ::c_uint = 32767; +pub const FILENAME_MAX: ::c_uint = 255; +pub const L_tmpnam: ::c_uint = 21; +pub const TMP_MAX: ::c_uint = 16384; + +// stdlib.h +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 32767; + +// sys/access.h +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; + +// sys/aio.h +pub const LIO_NOP: ::c_int = 0; +pub const LIO_READ: ::c_int = 1; +pub const LIO_WRITE: ::c_int = 2; +pub const LIO_NOWAIT: ::c_int = 0; +pub const LIO_WAIT: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; + +// sys/errno.h +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EDEADLK: ::c_int = 45; +pub const ENOLCK: ::c_int = 49; +pub const ECANCELED: ::c_int = 117; +pub const ENOTSUP: ::c_int = 124; +pub const EPROCLIM: ::c_int = 83; +pub const EDQUOT: ::c_int = 88; +pub const EOWNERDEAD: ::c_int = 95; +pub const ENOTRECOVERABLE: ::c_int = 94; +pub const ENOSTR: ::c_int = 123; +pub const ENODATA: ::c_int = 122; +pub const ETIME: ::c_int = 119; +pub const ENOSR: ::c_int = 118; +pub const EREMOTE: ::c_int = 93; +pub const ENOATTR: ::c_int = 112; +pub const ESAD: ::c_int = 113; +pub const ENOTRUST: ::c_int = 114; +pub const ENOLINK: ::c_int = 126; +pub const EPROTO: ::c_int = 121; +pub const EMULTIHOP: ::c_int = 125; +pub const EBADMSG: ::c_int = 120; +pub const ENAMETOOLONG: ::c_int = 86; +pub const EOVERFLOW: ::c_int = 127; +pub const EILSEQ: ::c_int = 116; +pub const ENOSYS: ::c_int = 109; +pub const ELOOP: ::c_int = 85; +pub const ERESTART: ::c_int = 82; +pub const ENOTEMPTY: ::c_int = 87; +pub const EUSERS: ::c_int = 84; +pub const ENOTSOCK: ::c_int = 57; +pub const EDESTADDRREQ: ::c_int = 58; +pub const EMSGSIZE: ::c_int = 59; +pub const EPROTOTYPE: ::c_int = 60; +pub const ENOPROTOOPT: ::c_int = 61; +pub const EPROTONOSUPPORT: ::c_int = 62; +pub const ESOCKTNOSUPPORT: ::c_int = 63; +pub const EOPNOTSUPP: ::c_int = 64; +pub const EPFNOSUPPORT: ::c_int = 65; +pub const EAFNOSUPPORT: ::c_int = 66; +pub const EADDRINUSE: ::c_int = 67; +pub const EADDRNOTAVAIL: ::c_int = 68; +pub const ENETDOWN: ::c_int = 69; +pub const ENETUNREACH: ::c_int = 70; +pub const ENETRESET: ::c_int = 71; +pub const ECONNABORTED: ::c_int = 72; +pub const ECONNRESET: ::c_int = 73; +pub const ENOBUFS: ::c_int = 74; +pub const EISCONN: ::c_int = 75; +pub const ENOTCONN: ::c_int = 76; +pub const ESHUTDOWN: ::c_int = 77; +pub const ETOOMANYREFS: ::c_int = 115; +pub const ETIMEDOUT: ::c_int = 78; +pub const ECONNREFUSED: ::c_int = 79; +pub const EHOSTDOWN: ::c_int = 80; +pub const EHOSTUNREACH: ::c_int = 81; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EALREADY: ::c_int = 56; +pub const EINPROGRESS: ::c_int = 55; +pub const ESTALE: ::c_int = 52; + +// sys/dr.h +pub const LPAR_INFO_FORMAT1: ::c_int = 1; +pub const LPAR_INFO_FORMAT2: ::c_int = 2; +pub const WPAR_INFO_FORMAT: ::c_int = 3; +pub const PROC_MODULE_INFO: ::c_int = 4; +pub const NUM_PROC_MODULE_TYPES: ::c_int = 5; +pub const LPAR_INFO_VRME_NUM_POOLS: ::c_int = 6; +pub const LPAR_INFO_VRME_POOLS: ::c_int = 7; +pub const LPAR_INFO_VRME_LPAR: ::c_int = 8; +pub const LPAR_INFO_VRME_RESET_HWMARKS: ::c_int = 9; +pub const LPAR_INFO_VRME_ALLOW_DESIRED: ::c_int = 10; +pub const EMTP_INFO_FORMAT: ::c_int = 11; +pub const LPAR_INFO_LPM_CAPABILITY: ::c_int = 12; +pub const ENERGYSCALE_INFO: ::c_int = 13; + +// sys/file.h +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +// sys/flock.h +pub const F_RDLCK: ::c_short = 0o01; +pub const F_WRLCK: ::c_short = 0o02; +pub const F_UNLCK: ::c_short = 0o03; + +// sys/fs/quota_common.h +pub const Q_QUOTAON: ::c_int = 0x100; +pub const Q_QUOTAOFF: ::c_int = 0x200; +pub const Q_SETUSE: ::c_int = 0x500; +pub const Q_SYNC: ::c_int = 0x600; +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQLIM: ::c_int = 0x400; +pub const Q_SETQUOTA: ::c_int = 0x400; + +// sys/ioctl.h +pub const IOCPARM_MASK: ::c_int = 0x7f; +pub const IOC_VOID: ::c_int = 0x20000000; +pub const IOC_OUT: ::c_int = 0x40000000; +pub const IOC_IN: ::c_int = 0x40000000 << 1; +pub const IOC_INOUT: ::c_int = IOC_IN | IOC_OUT; +pub const FIOCLEX: ::c_int = 536897025; +pub const FIONCLEX: ::c_int = 536897026; +pub const FIONREAD: ::c_int = 1074030207; +pub const FIONBIO: ::c_int = -2147195266; +pub const FIOASYNC: ::c_int = -2147195267; +pub const FIOSETOWN: ::c_int = -2147195268; +pub const FIOGETOWN: ::c_int = 1074030203; +pub const TIOCGETD: ::c_int = 0x40047400; +pub const TIOCSETD: ::c_int = 0x80047401; +pub const TIOCHPCL: ::c_int = 0x20007402; +pub const TIOCMODG: ::c_int = 0x40047403; +pub const TIOCMODS: ::c_int = 0x80047404; +pub const TIOCM_LE: ::c_int = 0x1; +pub const TIOCM_DTR: ::c_int = 0x2; +pub const TIOCM_RTS: ::c_int = 0x4; +pub const TIOCM_ST: ::c_int = 0x8; +pub const TIOCM_SR: ::c_int = 0x10; +pub const TIOCM_CTS: ::c_int = 0x20; +pub const TIOCM_CAR: ::c_int = 0x40; +pub const TIOCM_CD: ::c_int = 0x40; +pub const TIOCM_RNG: ::c_int = 0x80; +pub const TIOCM_RI: ::c_int = 0x80; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCGETP: ::c_int = 0x40067408; +pub const TIOCSETP: ::c_int = 0x80067409; +pub const TIOCSETN: ::c_int = 0x8006740a; +pub const TIOCEXCL: ::c_int = 0x2000740d; +pub const TIOCNXCL: ::c_int = 0x2000740e; +pub const TIOCFLUSH: ::c_int = 0x80047410; +pub const TIOCSETC: ::c_int = 0x80067411; +pub const TIOCGETC: ::c_int = 0x40067412; +pub const TANDEM: ::c_int = 0x1; +pub const CBREAK: ::c_int = 0x2; +pub const LCASE: ::c_int = 0x4; +pub const MDMBUF: ::c_int = 0x800000; +pub const XTABS: ::c_int = 0xc00; +pub const SIOCADDMULTI: ::c_int = -2145359567; +pub const SIOCADDRT: ::c_int = -2143784438; +pub const SIOCDARP: ::c_int = -2142476000; +pub const SIOCDELMULTI: ::c_int = -2145359566; +pub const SIOCDELRT: ::c_int = -2143784437; +pub const SIOCDIFADDR: ::c_int = -2144835303; +pub const SIOCGARP: ::c_int = -1068734170; +pub const SIOCGIFADDR: ::c_int = -1071093471; +pub const SIOCGIFBRDADDR: ::c_int = -1071093469; +pub const SIOCGIFCONF: ::c_int = -1072666299; +pub const SIOCGIFDSTADDR: ::c_int = -1071093470; +pub const SIOCGIFFLAGS: ::c_int = -1071093487; +pub const SIOCGIFHWADDR: ::c_int = -1068209771; +pub const SIOCGIFMETRIC: ::c_int = -1071093481; +pub const SIOCGIFMTU: ::c_int = -1071093418; +pub const SIOCGIFNETMASK: ::c_int = -1071093467; +pub const SIOCSARP: ::c_int = -2142476002; +pub const SIOCSIFADDR: ::c_int = -2144835316; +pub const SIOCSIFBRDADDR: ::c_int = -2144835309; +pub const SIOCSIFDSTADDR: ::c_int = -2144835314; +pub const SIOCSIFFLAGS: ::c_int = -2144835312; +pub const SIOCSIFMETRIC: ::c_int = -2144835304; +pub const SIOCSIFMTU: ::c_int = -2144835240; +pub const SIOCSIFNETMASK: ::c_int = -2144835306; +pub const TIOCUCNTL: ::c_int = -2147191706; +pub const TIOCCONS: ::c_int = -2147191710; +pub const TIOCPKT: ::c_int = -2147191696; +pub const TIOCPKT_DATA: ::c_int = 0; +pub const TIOCPKT_FLUSHREAD: ::c_int = 1; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 2; +pub const TIOCPKT_NOSTOP: ::c_int = 0x10; +pub const TIOCPKT_DOSTOP: ::c_int = 0x20; +pub const TIOCPKT_START: ::c_int = 8; +pub const TIOCPKT_STOP: ::c_int = 4; + +// sys/ipc.h +pub const IPC_ALLOC: ::c_int = 0o100000; +pub const IPC_CREAT: ::c_int = 0o020000; +pub const IPC_EXCL: ::c_int = 0o002000; +pub const IPC_NOWAIT: ::c_int = 0o004000; +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 101; +pub const IPC_R: ::c_int = 0o0400; +pub const IPC_W: ::c_int = 0o0200; +pub const IPC_O: ::c_int = 0o1000; +pub const IPC_NOERROR: ::c_int = 0o10000; +pub const IPC_STAT: ::c_int = 102; +pub const IPC_PRIVATE: ::key_t = -1; +pub const SHM_LOCK: ::c_int = 201; +pub const SHM_UNLOCK: ::c_int = 202; + +// sys/ldr.h +pub const L_GETINFO: ::c_int = 2; +pub const L_GETMESSAGE: ::c_int = 1; +pub const L_GETLIBPATH: ::c_int = 3; +pub const L_GETXINFO: ::c_int = 8; + +// sys/limits.h +pub const PATH_MAX: ::c_int = 1023; +pub const PAGESIZE: ::c_int = 4096; +pub const IOV_MAX: ::c_int = 16; +pub const AIO_LISTIO_MAX: ::c_int = 4096; +pub const PIPE_BUF: usize = 32768; +pub const OPEN_MAX: ::c_int = 65534; +pub const MAX_INPUT: ::c_int = 512; +pub const MAX_CANON: ::c_int = 256; +pub const ARG_MAX: ::c_int = 1048576; +pub const BC_BASE_MAX: ::c_int = 99; +pub const BC_DIM_MAX: ::c_int = 0x800; +pub const BC_SCALE_MAX: ::c_int = 99; +pub const BC_STRING_MAX: ::c_int = 0x800; +pub const CHARCLASS_NAME_MAX: ::c_int = 14; +pub const CHILD_MAX: ::c_int = 128; +pub const COLL_WEIGHTS_MAX: ::c_int = 4; +pub const EXPR_NEST_MAX: ::c_int = 32; +pub const NZERO: ::c_int = 20; + +// sys/lockf.h +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +// sys/machine.h +pub const BIG_ENDIAN: ::c_int = 4321; +pub const LITTLE_ENDIAN: ::c_int = 1234; +pub const PDP_ENDIAN: ::c_int = 3412; + +// sys/mman.h +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; +pub const MAP_FILE: ::c_int = 0; +pub const MAP_SHARED: ::c_int = 1; +pub const MAP_PRIVATE: ::c_int = 2; +pub const MAP_FIXED: ::c_int = 0x100; +pub const MAP_ANON: ::c_int = 0x10; +pub const MAP_ANONYMOUS: ::c_int = 0x10; +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; +pub const MAP_TYPE: ::c_int = 0xf0; +pub const MCL_CURRENT: ::c_int = 0x100; +pub const MCL_FUTURE: ::c_int = 0x200; +pub const MS_SYNC: ::c_int = 0x20; +pub const MS_ASYNC: ::c_int = 0x10; +pub const MS_INVALIDATE: ::c_int = 0x40; +pub const POSIX_MADV_NORMAL: ::c_int = 1; +pub const POSIX_MADV_RANDOM: ::c_int = 3; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 4; +pub const POSIX_MADV_DONTNEED: ::c_int = 5; +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; + +// sys/mode.h +pub const S_IFMT: mode_t = 0o170000; +pub const S_IFREG: mode_t = 0o100000; +pub const S_IFDIR: mode_t = 0o40000; +pub const S_IFBLK: mode_t = 0o60000; +pub const S_IFCHR: mode_t = 0o20000; +pub const S_IFIFO: mode_t = 0o10000; +pub const S_IRWXU: mode_t = 0o700; +pub const S_IRUSR: mode_t = 0o400; +pub const S_IWUSR: mode_t = 0o200; +pub const S_IXUSR: mode_t = 0o100; +pub const S_IRWXG: mode_t = 0o70; +pub const S_IRGRP: mode_t = 0o40; +pub const S_IWGRP: mode_t = 0o20; +pub const S_IXGRP: mode_t = 0o10; +pub const S_IRWXO: mode_t = 7; +pub const S_IROTH: mode_t = 4; +pub const S_IWOTH: mode_t = 2; +pub const S_IXOTH: mode_t = 1; +pub const S_IFLNK: mode_t = 0o120000; +pub const S_IFSOCK: mode_t = 0o140000; +pub const S_IEXEC: mode_t = 0o100; +pub const S_IWRITE: mode_t = 0o200; +pub const S_IREAD: mode_t = 0o400; + +// sys/msg.h +pub const MSG_NOERROR: ::c_int = 0o10000; + +// sys/m_signal.h +pub const SIGSTKSZ: ::size_t = 4096; +pub const MINSIGSTKSZ: ::size_t = 1200; + +// sys/params.h +pub const MAXPATHLEN: ::c_int = PATH_MAX + 1; +pub const MAXSYMLINKS: ::c_int = 20; +pub const MAXHOSTNAMELEN: ::c_int = 256; +pub const MAXUPRC: ::c_int = 128; +pub const NGROUPS_MAX: ::c_ulong = 2048; +pub const NGROUPS: ::c_ulong = NGROUPS_MAX; +pub const NOFILE: ::c_int = OPEN_MAX; + +// sys/poll.h +pub const POLLIN: ::c_short = 0x0001; +pub const POLLPRI: ::c_short = 0x0004; +pub const POLLOUT: ::c_short = 0x0002; +pub const POLLERR: ::c_short = 0x4000; +pub const POLLHUP: ::c_short = 0x2000; +pub const POLLMSG: ::c_short = 0x0080; +pub const POLLSYNC: ::c_short = 0x8000; +pub const POLLNVAL: ::c_short = POLLSYNC; +pub const POLLNORM: ::c_short = POLLIN; +pub const POLLRDNORM: ::c_short = 0x0010; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLRDBAND: ::c_short = 0x0020; +pub const POLLWRBAND: ::c_short = 0x0040; + +// sys/pollset.h +pub const PS_ADD: ::c_uchar = 0; +pub const PS_MOD: ::c_uchar = 1; +pub const PS_DELETE: ::c_uchar = 2; +pub const PS_REPLACE: ::c_uchar = 3; + +// sys/ptrace.h +pub const PT_TRACE_ME: ::c_int = 0; +pub const PT_READ_I: ::c_int = 1; +pub const PT_READ_D: ::c_int = 2; +pub const PT_WRITE_I: ::c_int = 4; +pub const PT_WRITE_D: ::c_int = 5; +pub const PT_CONTINUE: ::c_int = 7; +pub const PT_KILL: ::c_int = 8; +pub const PT_STEP: ::c_int = 9; +pub const PT_READ_GPR: ::c_int = 11; +pub const PT_READ_FPR: ::c_int = 12; +pub const PT_WRITE_GPR: ::c_int = 14; +pub const PT_WRITE_FPR: ::c_int = 15; +pub const PT_READ_BLOCK: ::c_int = 17; +pub const PT_WRITE_BLOCK: ::c_int = 19; +pub const PT_ATTACH: ::c_int = 30; +pub const PT_DETACH: ::c_int = 31; +pub const PT_REGSET: ::c_int = 32; +pub const PT_REATT: ::c_int = 33; +pub const PT_LDINFO: ::c_int = 34; +pub const PT_MULTI: ::c_int = 35; +pub const PT_NEXT: ::c_int = 36; +pub const PT_SET: ::c_int = 37; +pub const PT_CLEAR: ::c_int = 38; +pub const PT_LDXINFO: ::c_int = 39; +pub const PT_QUERY: ::c_int = 40; +pub const PT_WATCH: ::c_int = 41; +pub const PTT_CONTINUE: ::c_int = 50; +pub const PTT_STEP: ::c_int = 51; +pub const PTT_READ_SPRS: ::c_int = 52; +pub const PTT_WRITE_SPRS: ::c_int = 53; +pub const PTT_READ_GPRS: ::c_int = 54; +pub const PTT_WRITE_GPRS: ::c_int = 55; +pub const PTT_READ_FPRS: ::c_int = 56; +pub const PTT_WRITE_FPRS: ::c_int = 57; +pub const PTT_READ_VEC: ::c_int = 58; +pub const PTT_WRITE_VEC: ::c_int = 59; +pub const PTT_WATCH: ::c_int = 60; +pub const PTT_SET_TRAP: ::c_int = 61; +pub const PTT_CLEAR_TRAP: ::c_int = 62; +pub const PTT_READ_UKEYSET: ::c_int = 63; +pub const PT_GET_UKEY: ::c_int = 64; +pub const PTT_READ_FPSCR_HI: ::c_int = 65; +pub const PTT_WRITE_FPSCR_HI: ::c_int = 66; +pub const PTT_READ_VSX: ::c_int = 67; +pub const PTT_WRITE_VSX: ::c_int = 68; +pub const PTT_READ_TM: ::c_int = 69; +pub const PTRACE_ATTACH: ::c_int = 14; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_DETACH: ::c_int = 15; +pub const PTRACE_GETFPREGS: ::c_int = 12; +pub const PTRACE_GETREGS: ::c_int = 10; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_SETFPREGS: ::c_int = 13; +pub const PTRACE_SETREGS: ::c_int = 11; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_SYSCALL: ::c_int = 16; +pub const PTRACE_TRACEME: ::c_int = 0; + +// sys/resource.h +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_AS: ::c_int = 6; +pub const RLIMIT_NOFILE: ::c_int = 7; +pub const RLIMIT_THREADS: ::c_int = 8; +pub const RLIMIT_NPROC: ::c_int = 9; +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; +pub const RUSAGE_THREAD: ::c_int = 1; +pub const RLIM_SAVED_MAX: ::c_ulong = RLIM_INFINITY - 1; +pub const RLIM_SAVED_CUR: ::c_ulong = RLIM_INFINITY - 2; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 10; + +// sys/sched.h +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_LOCAL: ::c_int = 3; +pub const SCHED_GLOBAL: ::c_int = 4; +pub const SCHED_FIFO2: ::c_int = 5; +pub const SCHED_FIFO3: ::c_int = 6; +pub const SCHED_FIFO4: ::c_int = 7; + +// sys/sem.h +pub const SEM_UNDO: ::c_int = 0o10000; +pub const GETNCNT: ::c_int = 3; +pub const GETPID: ::c_int = 4; +pub const GETVAL: ::c_int = 5; +pub const GETALL: ::c_int = 6; +pub const GETZCNT: ::c_int = 7; +pub const SETVAL: ::c_int = 8; +pub const SETALL: ::c_int = 9; + +// sys/shm.h +pub const SHMLBA: ::c_int = 0x10000000; +pub const SHMLBA_EXTSHM: ::c_int = 0x1000; +pub const SHM_SHMAT: ::c_int = 0x80000000; +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_PIN: ::c_int = 0o4000; +pub const SHM_LGPAGE: ::c_int = 0o20000000000; +pub const SHM_MAP: ::c_int = 0o4000; +pub const SHM_FMAP: ::c_int = 0o2000; +pub const SHM_COPY: ::c_int = 0o40000; +pub const SHM_CLEAR: ::c_int = 0; +pub const SHM_HGSEG: ::c_int = 0o10000000000; +pub const SHM_R: ::c_int = IPC_R; +pub const SHM_W: ::c_int = IPC_W; +pub const SHM_DEST: ::c_int = 0o2000; + +// sys/signal.h +pub const SA_ONSTACK: ::c_int = 0x00000001; +pub const SA_RESETHAND: ::c_int = 0x00000002; +pub const SA_RESTART: ::c_int = 0x00000008; +pub const SA_SIGINFO: ::c_int = 0x00000100; +pub const SA_NODEFER: ::c_int = 0x00000200; +pub const SA_NOCLDWAIT: ::c_int = 0x00000400; +pub const SA_NOCLDSTOP: ::c_int = 0x00000004; +pub const SS_ONSTACK: ::c_int = 0x00000001; +pub const SS_DISABLE: ::c_int = 0x00000002; +pub const SIGCHLD: ::c_int = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_SIGNAL: ::c_int = 2; +pub const SIGEV_THREAD: ::c_int = 3; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGSYS: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGPWR: ::c_int = 29; +pub const SIGWINCH: ::c_int = 28; +pub const SIGURG: ::c_int = 16; +pub const SIGPOLL: ::c_int = SIGIO; +pub const SIGIO: ::c_int = 23; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGCONT: ::c_int = 19; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGVTALRM: ::c_int = 34; +pub const SIGPROF: ::c_int = 32; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGTRAP: ::c_int = 5; +pub const SIGCLD: ::c_int = 20; +pub const SIGRTMAX: ::c_int = 57; +pub const SIGRTMIN: ::c_int = 50; +pub const SI_USER: ::c_int = 0; +pub const SI_UNDEFINED: ::c_int = 8; +pub const SI_EMPTY: ::c_int = 9; +pub const BUS_ADRALN: ::c_int = 1; +pub const BUS_ADRERR: ::c_int = 2; +pub const BUS_OBJERR: ::c_int = 3; +pub const BUS_UEGARD: ::c_int = 4; +pub const CLD_EXITED: ::c_int = 10; +pub const CLD_KILLED: ::c_int = 11; +pub const CLD_DUMPED: ::c_int = 12; +pub const CLD_TRAPPED: ::c_int = 13; +pub const CLD_STOPPED: ::c_int = 14; +pub const CLD_CONTINUED: ::c_int = 15; +pub const FPE_INTDIV: ::c_int = 20; +pub const FPE_INTOVF: ::c_int = 21; +pub const FPE_FLTDIV: ::c_int = 22; +pub const FPE_FLTOVF: ::c_int = 23; +pub const FPE_FLTUND: ::c_int = 24; +pub const FPE_FLTRES: ::c_int = 25; +pub const FPE_FLTINV: ::c_int = 26; +pub const FPE_FLTSUB: ::c_int = 27; +pub const ILL_ILLOPC: ::c_int = 30; +pub const ILL_ILLOPN: ::c_int = 31; +pub const ILL_ILLADR: ::c_int = 32; +pub const ILL_ILLTRP: ::c_int = 33; +pub const ILL_PRVOPC: ::c_int = 34; +pub const ILL_PRVREG: ::c_int = 35; +pub const ILL_COPROC: ::c_int = 36; +pub const ILL_BADSTK: ::c_int = 37; +pub const ILL_TMBADTHING: ::c_int = 38; +pub const POLL_IN: ::c_int = 40; +pub const POLL_OUT: ::c_int = 41; +pub const POLL_MSG: ::c_int = -3; +pub const POLL_ERR: ::c_int = 43; +pub const POLL_PRI: ::c_int = 44; +pub const POLL_HUP: ::c_int = 45; +pub const SEGV_MAPERR: ::c_int = 50; +pub const SEGV_ACCERR: ::c_int = 51; +pub const SEGV_KEYERR: ::c_int = 52; +pub const TRAP_BRKPT: ::c_int = 60; +pub const TRAP_TRACE: ::c_int = 61; +pub const SI_QUEUE: ::c_int = 71; +pub const SI_TIMER: ::c_int = 72; +pub const SI_ASYNCIO: ::c_int = 73; +pub const SI_MESGQ: ::c_int = 74; + +// sys/socket.h +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NS: ::c_int = 6; +pub const AF_ECMA: ::c_int = 8; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const SO_TIMESTAMPNS: ::c_int = 0x100a; +pub const SOMAXCONN: ::c_int = 1024; +pub const AF_LOCAL: ::c_int = AF_UNIX; +pub const UIO_MAXIOV: ::c_int = 1024; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const AF_INET6: ::c_int = 24; +pub const AF_INTF: ::c_int = 20; +pub const AF_RIF: ::c_int = 21; +pub const AF_NDD: ::c_int = 23; +pub const AF_MAX: ::c_int = 30; +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_IMPLINK: ::c_int = AF_IMPLINK; +pub const PF_PUP: ::c_int = AF_PUP; +pub const PF_CHAOS: ::c_int = AF_CHAOS; +pub const PF_NS: ::c_int = AF_NS; +pub const PF_ISO: ::c_int = AF_ISO; +pub const PF_OSI: ::c_int = AF_ISO; +pub const PF_ECMA: ::c_int = AF_ECMA; +pub const PF_DATAKIT: ::c_int = AF_DATAKIT; +pub const PF_CCITT: ::c_int = AF_CCITT; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_DLI: ::c_int = AF_DLI; +pub const PF_LAT: ::c_int = AF_LAT; +pub const PF_HYLINK: ::c_int = AF_HYLINK; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_LINK: ::c_int = AF_LINK; +pub const PF_XTP: ::c_int = 19; +pub const PF_RIF: ::c_int = AF_RIF; +pub const PF_INTF: ::c_int = AF_INTF; +pub const PF_NDD: ::c_int = AF_NDD; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_MAX: ::c_int = AF_MAX; +pub const SF_CLOSE: ::c_int = 1; +pub const SF_REUSE: ::c_int = 2; +pub const SF_DONT_CACHE: ::c_int = 4; +pub const SF_SYNC_CACHE: ::c_int = 8; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_USE_IFBUFS: ::c_int = 0x0400; +pub const SO_CKSUMRECV: ::c_int = 0x0800; +pub const SO_NOREUSEADDR: ::c_int = 0x1000; +pub const SO_KERNACCEPT: ::c_int = 0x2000; +pub const SO_NOMULTIPATH: ::c_int = 0x4000; +pub const SO_AUDIT: ::c_int = 0x8000; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SCM_RIGHTS: ::c_int = 0x01; +pub const MSG_OOB: ::c_int = 0x1; +pub const MSG_PEEK: ::c_int = 0x2; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_EOR: ::c_int = 0x8; +pub const MSG_TRUNC: ::c_int = 0x10; +pub const MSG_CTRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_MPEG2: ::c_int = 0x80; +pub const MSG_NOSIGNAL: ::c_int = 0x100; +pub const MSG_WAITFORONE: ::c_int = 0x200; +pub const MSG_ARGEXT: ::c_int = 0x400; +pub const MSG_NONBLOCK: ::c_int = 0x4000; +pub const MSG_COMPAT: ::c_int = 0x8000; +pub const MSG_MAXIOVLEN: ::c_int = 16; +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +// sys/stat.h +pub const UTIME_NOW: ::c_int = -2; +pub const UTIME_OMIT: ::c_int = -3; + +// sys/statvfs.h +pub const ST_RDONLY: ::c_ulong = 0x0001; +pub const ST_NOSUID: ::c_ulong = 0x0040; +pub const ST_NODEV: ::c_ulong = 0x0080; + +// sys/stropts.h +pub const I_NREAD: ::c_int = 0x20005301; +pub const I_PUSH: ::c_int = 0x20005302; +pub const I_POP: ::c_int = 0x20005303; +pub const I_LOOK: ::c_int = 0x20005304; +pub const I_FLUSH: ::c_int = 0x20005305; +pub const I_SRDOPT: ::c_int = 0x20005306; +pub const I_GRDOPT: ::c_int = 0x20005307; +pub const I_STR: ::c_int = 0x20005308; +pub const I_SETSIG: ::c_int = 0x20005309; +pub const I_GETSIG: ::c_int = 0x2000530a; +pub const I_FIND: ::c_int = 0x2000530b; +pub const I_LINK: ::c_int = 0x2000530c; +pub const I_UNLINK: ::c_int = 0x2000530d; +pub const I_PEEK: ::c_int = 0x2000530f; +pub const I_FDINSERT: ::c_int = 0x20005310; +pub const I_SENDFD: ::c_int = 0x20005311; +pub const I_RECVFD: ::c_int = 0x20005312; +pub const I_SWROPT: ::c_int = 0x20005314; +pub const I_GWROPT: ::c_int = 0x20005315; +pub const I_LIST: ::c_int = 0x20005316; +pub const I_PLINK: ::c_int = 0x2000531d; +pub const I_PUNLINK: ::c_int = 0x2000531e; +pub const I_FLUSHBAND: ::c_int = 0x20005313; +pub const I_CKBAND: ::c_int = 0x20005318; +pub const I_GETBAND: ::c_int = 0x20005319; +pub const I_ATMARK: ::c_int = 0x20005317; +pub const I_SETCLTIME: ::c_int = 0x2000531b; +pub const I_GETCLTIME: ::c_int = 0x2000531c; +pub const I_CANPUT: ::c_int = 0x2000531a; + +// sys/syslog.h +pub const LOG_CRON: ::c_int = 9 << 3; +pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +pub const LOG_NFACILITIES: ::c_int = 24; +pub const LOG_PERROR: ::c_int = 0x20; + +// sys/systemcfg.h +pub const SC_ARCH: ::c_int = 1; +pub const SC_IMPL: ::c_int = 2; +pub const SC_VERS: ::c_int = 3; +pub const SC_WIDTH: ::c_int = 4; +pub const SC_NCPUS: ::c_int = 5; +pub const SC_L1C_ATTR: ::c_int = 6; +pub const SC_L1C_ISZ: ::c_int = 7; +pub const SC_L1C_DSZ: ::c_int = 8; +pub const SC_L1C_ICA: ::c_int = 9; +pub const SC_L1C_DCA: ::c_int = 10; +pub const SC_L1C_IBS: ::c_int = 11; +pub const SC_L1C_DBS: ::c_int = 12; +pub const SC_L1C_ILS: ::c_int = 13; +pub const SC_L1C_DLS: ::c_int = 14; +pub const SC_L2C_SZ: ::c_int = 15; +pub const SC_L2C_AS: ::c_int = 16; +pub const SC_TLB_ATTR: ::c_int = 17; +pub const SC_ITLB_SZ: ::c_int = 18; +pub const SC_DTLB_SZ: ::c_int = 19; +pub const SC_ITLB_ATT: ::c_int = 20; +pub const SC_DTLB_ATT: ::c_int = 21; +pub const SC_RESRV_SZ: ::c_int = 22; +pub const SC_PRI_LC: ::c_int = 23; +pub const SC_PRO_LC: ::c_int = 24; +pub const SC_RTC_TYPE: ::c_int = 25; +pub const SC_VIRT_AL: ::c_int = 26; +pub const SC_CAC_CONG: ::c_int = 27; +pub const SC_MOD_ARCH: ::c_int = 28; +pub const SC_MOD_IMPL: ::c_int = 29; +pub const SC_XINT: ::c_int = 30; +pub const SC_XFRAC: ::c_int = 31; +pub const SC_KRN_ATTR: ::c_int = 32; +pub const SC_PHYSMEM: ::c_int = 33; +pub const SC_SLB_ATTR: ::c_int = 34; +pub const SC_SLB_SZ: ::c_int = 35; +pub const SC_MAX_NCPUS: ::c_int = 37; +pub const SC_MAX_REALADDR: ::c_int = 38; +pub const SC_ORIG_ENT_CAP: ::c_int = 39; +pub const SC_ENT_CAP: ::c_int = 40; +pub const SC_DISP_WHE: ::c_int = 41; +pub const SC_CAPINC: ::c_int = 42; +pub const SC_VCAPW: ::c_int = 43; +pub const SC_SPLP_STAT: ::c_int = 44; +pub const SC_SMT_STAT: ::c_int = 45; +pub const SC_SMT_TC: ::c_int = 46; +pub const SC_VMX_VER: ::c_int = 47; +pub const SC_LMB_SZ: ::c_int = 48; +pub const SC_MAX_XCPU: ::c_int = 49; +pub const SC_EC_LVL: ::c_int = 50; +pub const SC_AME_STAT: ::c_int = 51; +pub const SC_ECO_STAT: ::c_int = 52; +pub const SC_DFP_VER: ::c_int = 53; +pub const SC_VRM_STAT: ::c_int = 54; +pub const SC_PHYS_IMP: ::c_int = 55; +pub const SC_PHYS_VER: ::c_int = 56; +pub const SC_SPCM_STATUS: ::c_int = 57; +pub const SC_SPCM_MAX: ::c_int = 58; +pub const SC_TM_VER: ::c_int = 59; +pub const SC_NX_CAP: ::c_int = 60; +pub const SC_PKS_STATE: ::c_int = 61; +pub const SC_MMA_VER: ::c_int = 62; +pub const POWER_RS: ::c_int = 1; +pub const POWER_PC: ::c_int = 2; +pub const IA64: ::c_int = 3; +pub const POWER_RS1: ::c_int = 0x1; +pub const POWER_RSC: ::c_int = 0x2; +pub const POWER_RS2: ::c_int = 0x4; +pub const POWER_601: ::c_int = 0x8; +pub const POWER_604: ::c_int = 0x10; +pub const POWER_603: ::c_int = 0x20; +pub const POWER_620: ::c_int = 0x40; +pub const POWER_630: ::c_int = 0x80; +pub const POWER_A35: ::c_int = 0x100; +pub const POWER_RS64II: ::c_int = 0x200; +pub const POWER_RS64III: ::c_int = 0x400; +pub const POWER_4: ::c_int = 0x800; +pub const POWER_RS64IV: ::c_int = POWER_4; +pub const POWER_MPC7450: ::c_int = 0x1000; +pub const POWER_5: ::c_int = 0x2000; +pub const POWER_6: ::c_int = 0x4000; +pub const POWER_7: ::c_int = 0x8000; +pub const POWER_8: ::c_int = 0x10000; +pub const POWER_9: ::c_int = 0x20000; + +// sys/time.h +pub const FD_SETSIZE: usize = 65534; +pub const TIMEOFDAY: ::c_int = 9; +pub const CLOCK_REALTIME: ::clockid_t = TIMEOFDAY as clockid_t; +pub const CLOCK_MONOTONIC: ::clockid_t = 10; +pub const TIMER_ABSTIME: ::c_int = 999; +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; +pub const ITIMER_VIRT: ::c_int = 3; +pub const ITIMER_REAL1: ::c_int = 20; +pub const ITIMER_REAL_TH: ::c_int = ITIMER_REAL1; +pub const DST_AUST: ::c_int = 2; +pub const DST_CAN: ::c_int = 6; +pub const DST_EET: ::c_int = 5; +pub const DST_MET: ::c_int = 4; +pub const DST_NONE: ::c_int = 0; +pub const DST_USA: ::c_int = 1; +pub const DST_WET: ::c_int = 3; + +// sys/termio.h +pub const CSTART: ::tcflag_t = 0o21; +pub const CSTOP: ::tcflag_t = 0o23; +pub const TCGETA: ::c_int = TIOC | 5; +pub const TCSETA: ::c_int = TIOC | 6; +pub const TCSETAW: ::c_int = TIOC | 7; +pub const TCSETAF: ::c_int = TIOC | 8; +pub const TCSBRK: ::c_int = TIOC | 9; +pub const TCXONC: ::c_int = TIOC | 11; +pub const TCFLSH: ::c_int = TIOC | 12; +pub const TCGETS: ::c_int = TIOC | 1; +pub const TCSETS: ::c_int = TIOC | 2; +pub const TCSANOW: ::c_int = 0; +pub const TCSETSW: ::c_int = TIOC | 3; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSETSF: ::c_int = TIOC | 4; +pub const TCSAFLUSH: ::c_int = 2; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TIOC: ::c_int = 0x5400; +pub const TIOCGWINSZ: ::c_int = 0x40087468; +pub const TIOCSWINSZ: ::c_int = 0x80087467; +pub const TIOCLBIS: ::c_int = 0x8004747f; +pub const TIOCLBIC: ::c_int = 0x8004747e; +pub const TIOCLSET: ::c_int = 0x8004747d; +pub const TIOCLGET: ::c_int = 0x4004747c; +pub const TIOCSBRK: ::c_int = 0x2000747b; +pub const TIOCCBRK: ::c_int = 0x2000747a; +pub const TIOCSDTR: ::c_int = 0x20007479; +pub const TIOCCDTR: ::c_int = 0x20007478; +pub const TIOCSLTC: ::c_int = 0x80067475; +pub const TIOCGLTC: ::c_int = 0x40067474; +pub const TIOCOUTQ: ::c_int = 0x40047473; +pub const TIOCNOTTY: ::c_int = 0x20007471; +pub const TIOCSTOP: ::c_int = 0x2000746f; +pub const TIOCSTART: ::c_int = 0x2000746e; +pub const TIOCGPGRP: ::c_int = 0x40047477; +pub const TIOCSPGRP: ::c_int = 0x80047476; +pub const TIOCGSID: ::c_int = 0x40047448; +pub const TIOCSTI: ::c_int = 0x80017472; +pub const TIOCMSET: ::c_int = 0x8004746d; +pub const TIOCMBIS: ::c_int = 0x8004746c; +pub const TIOCMBIC: ::c_int = 0x8004746b; +pub const TIOCMGET: ::c_int = 0x4004746a; +pub const TIOCREMOTE: ::c_int = 0x80047469; + +// sys/user.h +pub const MAXCOMLEN: ::c_int = 32; +pub const UF_SYSTEM: ::c_int = 0x1000; + +// sys/vattr.h +pub const AT_FLAGS: ::c_int = 0x80; +pub const AT_GID: ::c_int = 8; +pub const AT_UID: ::c_int = 4; + +// sys/wait.h +pub const P_ALL: ::c_int = 0; +pub const P_PID: ::c_int = 1; +pub const P_PGID: ::c_int = 2; +pub const WNOHANG: ::c_int = 0x1; +pub const WUNTRACED: ::c_int = 0x2; +pub const WEXITED: ::c_int = 0x04; +pub const WCONTINUED: ::c_int = 0x01000000; +pub const WNOWAIT: ::c_int = 0x10; +pub const WSTOPPED: ::c_int = _W_STOPPED; +pub const _W_STOPPED: ::c_int = 0x00000040; +pub const _W_SLWTED: ::c_int = 0x0000007c; +pub const _W_SEWTED: ::c_int = 0x0000007d; +pub const _W_SFWTED: ::c_int = 0x0000007e; +pub const _W_STRC: ::c_int = 0x0000007f; + +// termios.h +pub const NCCS: usize = 16; +pub const OLCUC: ::tcflag_t = 2; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const ECHO: ::tcflag_t = 0x20000; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOCTL: ::tcflag_t = 0x00020000; +pub const ECHOPRT: ::tcflag_t = 0x00040000; +pub const ECHOKE: ::tcflag_t = 0x00080000; +pub const IGNBRK: ::tcflag_t = 0x00000001; +pub const BRKINT: ::tcflag_t = 0x00000002; +pub const IGNPAR: ::tcflag_t = 0x00000004; +pub const PARMRK: ::tcflag_t = 0x00000008; +pub const INPCK: ::tcflag_t = 0x00000010; +pub const ISTRIP: ::tcflag_t = 0x00000020; +pub const INLCR: ::tcflag_t = 0x00000040; +pub const IGNCR: ::tcflag_t = 0x00000080; +pub const ICRNL: ::tcflag_t = 0x00000100; +pub const IXON: ::tcflag_t = 0x0001; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const IXANY: ::tcflag_t = 0x00001000; +pub const IMAXBEL: ::tcflag_t = 0x00010000; +pub const OPOST: ::tcflag_t = 0x00000001; +pub const ONLCR: ::tcflag_t = 0x00000004; +pub const OCRNL: ::tcflag_t = 0x00000008; +pub const ONOCR: ::tcflag_t = 0x00000010; +pub const ONLRET: ::tcflag_t = 0x00000020; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const IEXTEN: ::tcflag_t = 0x00200000; +pub const TOSTOP: ::tcflag_t = 0x00010000; +pub const FLUSHO: ::tcflag_t = 0x00100000; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VEOF: usize = 4; +pub const VEOL: usize = 5; +pub const VSTART: usize = 7; +pub const VSTOP: usize = 8; +pub const VSUSP: usize = 9; +pub const VMIN: usize = 4; +pub const VTIME: usize = 5; +pub const VEOL2: usize = 6; +pub const VDSUSP: usize = 10; +pub const VREPRINT: usize = 11; +pub const VDISCRD: usize = 12; +pub const VWERSE: usize = 13; +pub const VLNEXT: usize = 14; +pub const B0: ::speed_t = 0x0; +pub const B50: ::speed_t = 0x1; +pub const B75: ::speed_t = 0x2; +pub const B110: ::speed_t = 0x3; +pub const B134: ::speed_t = 0x4; +pub const B150: ::speed_t = 0x5; +pub const B200: ::speed_t = 0x6; +pub const B300: ::speed_t = 0x7; +pub const B600: ::speed_t = 0x8; +pub const B1200: ::speed_t = 0x9; +pub const B1800: ::speed_t = 0xa; +pub const B2400: ::speed_t = 0xb; +pub const B4800: ::speed_t = 0xc; +pub const B9600: ::speed_t = 0xd; +pub const B19200: ::speed_t = 0xe; +pub const B38400: ::speed_t = 0xf; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const IUCLC: ::tcflag_t = 0x00000800; +pub const OFILL: ::tcflag_t = 0x00000040; +pub const OFDEL: ::tcflag_t = 0x00000080; +pub const CRDLY: ::tcflag_t = 0x00000300; +pub const CR0: ::tcflag_t = 0x00000000; +pub const CR1: ::tcflag_t = 0x00000100; +pub const CR2: ::tcflag_t = 0x00000200; +pub const CR3: ::tcflag_t = 0x00000300; +pub const TABDLY: ::tcflag_t = 0x00000c00; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB1: ::tcflag_t = 0x00000400; +pub const TAB2: ::tcflag_t = 0x00000800; +pub const TAB3: ::tcflag_t = 0x00000c00; +pub const BSDLY: ::tcflag_t = 0x00001000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const BS1: ::tcflag_t = 0x00001000; +pub const FFDLY: ::tcflag_t = 0x00002000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const FF1: ::tcflag_t = 0x00002000; +pub const NLDLY: ::tcflag_t = 0x00004000; +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00004000; +pub const VTDLY: ::tcflag_t = 0x00008000; +pub const VT0: ::tcflag_t = 0x00000000; +pub const VT1: ::tcflag_t = 0x00008000; +pub const OXTABS: ::tcflag_t = 0x00040000; +pub const ONOEOT: ::tcflag_t = 0x00080000; +pub const CBAUD: ::tcflag_t = 0x0000000f; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const CIBAUD: ::tcflag_t = 0x000f0000; +pub const IBSHIFT: ::tcflag_t = 16; +pub const PAREXT: ::tcflag_t = 0x00100000; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const XCASE: ::tcflag_t = 0x00000004; +pub const ALTWERASE: ::tcflag_t = 0x00400000; + +// time.h +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 11; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 12; + +// unistd.h +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const _POSIX_VDISABLE: ::c_int = 0xff; +pub const _PC_LINK_MAX: ::c_int = 11; +pub const _PC_MAX_CANON: ::c_int = 12; +pub const _PC_MAX_INPUT: ::c_int = 13; +pub const _PC_NAME_MAX: ::c_int = 14; +pub const _PC_PATH_MAX: ::c_int = 16; +pub const _PC_PIPE_BUF: ::c_int = 17; +pub const _PC_NO_TRUNC: ::c_int = 15; +pub const _PC_VDISABLE: ::c_int = 18; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 10; +pub const _PC_ASYNC_IO: ::c_int = 19; +pub const _PC_PRIO_IO: ::c_int = 21; +pub const _PC_SYNC_IO: ::c_int = 20; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 26; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 27; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 28; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 29; +pub const _PC_REC_XFER_ALIGN: ::c_int = 30; +pub const _PC_SYMLINK_MAX: ::c_int = 25; +pub const _PC_2_SYMLINKS: ::c_int = 31; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 32; +pub const _PC_FILESIZEBITS: ::c_int = 22; +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_VERSION: ::c_int = 9; +pub const _SC_PASS_MAX: ::c_int = 45; +pub const _SC_PAGESIZE: ::c_int = _SC_PAGE_SIZE; +pub const _SC_PAGE_SIZE: ::c_int = 48; +pub const _SC_XOPEN_VERSION: ::c_int = 46; +pub const _SC_NPROCESSORS_CONF: ::c_int = 71; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 72; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 75; +pub const _SC_AIO_MAX: ::c_int = 76; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 77; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 78; +pub const _SC_DELAYTIMER_MAX: ::c_int = 79; +pub const _SC_FSYNC: ::c_int = 80; +pub const _SC_MAPPED_FILES: ::c_int = 84; +pub const _SC_MEMLOCK: ::c_int = 85; +pub const _SC_MEMLOCK_RANGE: ::c_int = 86; +pub const _SC_MEMORY_PROTECTION: ::c_int = 87; +pub const _SC_MESSAGE_PASSING: ::c_int = 88; +pub const _SC_MQ_OPEN_MAX: ::c_int = 89; +pub const _SC_MQ_PRIO_MAX: ::c_int = 90; +pub const _SC_PRIORITIZED_IO: ::c_int = 91; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 92; +pub const _SC_REALTIME_SIGNALS: ::c_int = 93; +pub const _SC_RTSIG_MAX: ::c_int = 94; +pub const _SC_SEMAPHORES: ::c_int = 95; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 96; +pub const _SC_SEM_VALUE_MAX: ::c_int = 97; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 98; +pub const _SC_SIGQUEUE_MAX: ::c_int = 99; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 100; +pub const _SC_TIMERS: ::c_int = 102; +pub const _SC_TIMER_MAX: ::c_int = 103; +pub const _SC_2_C_BIND: ::c_int = 51; +pub const _SC_2_C_DEV: ::c_int = 32; +pub const _SC_2_C_VERSION: ::c_int = 52; +pub const _SC_2_FORT_DEV: ::c_int = 33; +pub const _SC_2_FORT_RUN: ::c_int = 34; +pub const _SC_2_LOCALEDEF: ::c_int = 35; +pub const _SC_2_SW_DEV: ::c_int = 36; +pub const _SC_2_UPE: ::c_int = 53; +pub const _SC_2_VERSION: ::c_int = 31; +pub const _SC_BC_BASE_MAX: ::c_int = 23; +pub const _SC_BC_DIM_MAX: ::c_int = 24; +pub const _SC_BC_SCALE_MAX: ::c_int = 25; +pub const _SC_BC_STRING_MAX: ::c_int = 26; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 50; +pub const _SC_EXPR_NEST_MAX: ::c_int = 28; +pub const _SC_LINE_MAX: ::c_int = 29; +pub const _SC_RE_DUP_MAX: ::c_int = 30; +pub const _SC_XOPEN_CRYPT: ::c_int = 56; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 57; +pub const _SC_XOPEN_SHM: ::c_int = 55; +pub const _SC_2_CHAR_TERM: ::c_int = 54; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 109; +pub const _SC_ATEXIT_MAX: ::c_int = 47; +pub const _SC_IOV_MAX: ::c_int = 58; +pub const _SC_XOPEN_UNIX: ::c_int = 73; +pub const _SC_T_IOV_MAX: ::c_int = 0; +pub const _SC_PHYS_PAGES: ::c_int = 113; +pub const _SC_AVPHYS_PAGES: ::c_int = 114; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 101; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 81; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 82; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 83; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 68; +pub const _SC_THREAD_STACK_MIN: ::c_int = 69; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 70; +pub const _SC_TTY_NAME_MAX: ::c_int = 104; +pub const _SC_THREADS: ::c_int = 60; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 61; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 62; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 64; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 65; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 66; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 59; +pub const _SC_XOPEN_LEGACY: ::c_int = 112; +pub const _SC_XOPEN_REALTIME: ::c_int = 110; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 111; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 105; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 106; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 107; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 108; +pub const _SC_2_PBS: ::c_int = 132; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 133; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 134; +pub const _SC_2_PBS_LOCATE: ::c_int = 135; +pub const _SC_2_PBS_MESSAGE: ::c_int = 136; +pub const _SC_2_PBS_TRACK: ::c_int = 137; +pub const _SC_ADVISORY_INFO: ::c_int = 130; +pub const _SC_BARRIERS: ::c_int = 138; +pub const _SC_CLOCK_SELECTION: ::c_int = 139; +pub const _SC_CPUTIME: ::c_int = 140; +pub const _SC_HOST_NAME_MAX: ::c_int = 126; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 141; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 142; +pub const _SC_REGEXP: ::c_int = 127; +pub const _SC_SHELL: ::c_int = 128; +pub const _SC_SPAWN: ::c_int = 143; +pub const _SC_SPIN_LOCKS: ::c_int = 144; +pub const _SC_SPORADIC_SERVER: ::c_int = 145; +pub const _SC_SS_REPL_MAX: ::c_int = 156; +pub const _SC_SYMLOOP_MAX: ::c_int = 129; +pub const _SC_THREAD_CPUTIME: ::c_int = 146; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 147; +pub const _SC_TIMEOUTS: ::c_int = 148; +pub const _SC_TRACE: ::c_int = 149; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 150; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 157; +pub const _SC_TRACE_INHERIT: ::c_int = 151; +pub const _SC_TRACE_LOG: ::c_int = 152; +pub const _SC_TRACE_NAME_MAX: ::c_int = 158; +pub const _SC_TRACE_SYS_MAX: ::c_int = 159; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 160; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 153; +pub const _SC_V6_ILP32_OFF32: ::c_int = 121; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 122; +pub const _SC_V6_LP64_OFF64: ::c_int = 123; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 124; +pub const _SC_XOPEN_STREAMS: ::c_int = 125; +pub const _SC_IPV6: ::c_int = 154; +pub const _SC_RAW_SOCKETS: ::c_int = 155; + +// utmp.h +pub const EMPTY: ::c_short = -1; +pub const RUN_LVL: ::c_short = 1; +pub const BOOT_TIME: ::c_short = 2; +pub const OLD_TIME: ::c_short = 3; +pub const NEW_TIME: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const USER_PROCESS: ::c_short = 7; +pub const DEAD_PROCESS: ::c_short = 8; +pub const ACCOUNTING: ::c_short = 9; + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + CMSG_FIRSTHDR(mhdr) + } else { + if (cmsg as usize + (*cmsg).cmsg_len as usize + ::mem::size_of::<::cmsghdr>()) > + ((*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize) { + 0 as *mut ::cmsghdr + } else { + // AIX does not have any alignment/padding for ancillary data, so we don't need _CMSG_ALIGN here. + (cmsg as usize + (*cmsg).cmsg_len as usize) as *mut cmsghdr + } + } + } + + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar).offset(::mem::size_of::<::cmsghdr>() as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + ::mem::size_of::<::cmsghdr>() as ::c_uint + length + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + ::mem::size_of::<::cmsghdr>() as ::c_uint + length + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of::<::c_long>() * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of::<::c_long>() * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of::<::c_long>() * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + let x = dev >> 16; + x as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let y = dev & 0xFFFF; + y as ::c_uint + } + + pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= major << 16; + dev |= minor; + dev + } +} + +safe_f! { + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & _W_STOPPED) != 0 + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + if WIFSTOPPED(status) { + (((status as ::c_uint) >> 8) & 0xff) as ::c_int + } else { + -1 + } + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xFF) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + if WIFEXITED(status) { + (((status as ::c_uint) >> 8) & 0xff) as ::c_int + } else { + -1 + } + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + !WIFEXITED(status) && !WIFSTOPPED(status) + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + if WIFSIGNALED(status) { + (((status as ::c_uint) >> 16) & 0xff) as ::c_int + } else { + -1 + } + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & WCONTINUED) != 0 + } + + // AIX doesn't have native WCOREDUMP. + pub {const} fn WCOREDUMP(_status: ::c_int) -> bool { + false + } +} + +#[link(name = "thread")] +extern "C" { + pub fn thr_kill(id: thread_t, sig: ::c_int) -> ::c_int; + pub fn thr_self() -> thread_t; +} + +#[link(name = "pthread")] +extern "C" { + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getschedparam( + attr: *const ::pthread_attr_t, + param: *mut sched_param, + ) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setschedparam( + attr: *mut ::pthread_attr_t, + param: *const sched_param, + ) -> ::c_int; + pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const ::pthread_barrierattr_t, + count: ::c_uint, + ) -> ::c_int; + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const ::pthread_barrierattr_t, + shared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut ::pthread_barrierattr_t, + shared: ::c_int, + ) -> ::c_int; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + pub fn pthread_getschedparam( + thread: ::pthread_t, + policy: *mut ::c_int, + param: *mut sched_param, + ) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, signal: ::c_int) -> ::c_int; + pub fn pthread_mutex_consistent(mutex: *mut ::pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_mutexattr_getprotocol( + attr: *const pthread_mutexattr_t, + protocol: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_getrobust( + attr: *mut ::pthread_mutexattr_t, + robust: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setprotocol( + attr: *mut pthread_mutexattr_t, + protocol: ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setrobust( + attr: *mut ::pthread_mutexattr_t, + robust: ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; + pub fn pthread_setschedparam( + thread: ::pthread_t, + policy: ::c_int, + param: *const sched_param, + ) -> ::c_int; + pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; +} + +#[link(name = "iconv")] +extern "C" { + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; +} + +extern "C" { + pub fn acct(filename: *const ::c_char) -> ::c_int; + pub fn aio_cancel(fildes: ::c_int, aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *mut ::aiocb) -> ::c_int; + #[link_name = "_posix_aio_fsync"] + pub fn aio_fsync(op: ::c_int, aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_read(aiocbp: *mut ::aiocb) -> ::c_int; + // pub fn aio_suspend + // pub fn aio_write + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn clearenv() -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn drand48() -> ::c_double; + pub fn duplocale(arg1: ::locale_t) -> ::locale_t; + pub fn endgrent(); + pub fn endmntent(streamp: *mut ::FILE) -> ::c_int; + pub fn endpwent(); + pub fn endutent(); + pub fn endutxent(); + pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn fattach(fildes: ::c_int, path: *const ::c_char) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn ffs(value: ::c_int) -> ::c_int; + pub fn ffsl(value: ::c_long) -> ::c_int; + pub fn ffsll(value: ::c_longlong) -> ::c_int; + pub fn fgetgrent(file: *mut ::FILE) -> *mut ::group; + pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; + pub fn fgetpwent(file: *mut ::FILE) -> *mut ::passwd; + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn freelocale(loc: ::locale_t); + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut ::FILE, + ) -> *mut ::FILE; + pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int; + pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int; + pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int; + pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int; + pub fn ftello64(stream: *mut ::FILE) -> ::off64_t; + pub fn ftok(path: *const ::c_char, id: ::c_int) -> ::key_t; + pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrent() -> *mut ::group; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getgrset(user: *mut ::c_char) -> *mut ::c_char; + pub fn gethostid() -> ::c_long; + pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::size_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + servlen: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getpagesize() -> ::c_int; + pub fn getpeereid(socket: ::c_int, euid: *mut ::uid_t, egid: *mut ::gid_t) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn getpwent() -> *mut ::passwd; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn getrlimit64(resource: ::c_int, rlim: *mut rlimit64) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; + pub fn getutent() -> *mut utmp; + pub fn getutid(u: *const utmp) -> *mut utmp; + pub fn getutline(u: *const utmp) -> *mut utmp; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn glob( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char; + pub fn hcreate(nelt: ::size_t) -> ::c_int; + pub fn hdestroy(); + pub fn hsearch(entry: entry, action: ::c_int) -> *mut entry; + pub fn if_freenameindex(ptr: *mut if_nameindex); + pub fn if_nameindex() -> *mut if_nameindex; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn lcong48(p: *mut ::c_ushort); + pub fn lfind( + key: *const ::c_void, + base: *const ::c_void, + nelp: *mut ::size_t, + width: ::size_t, + compar: ::Option ::c_int>, + ) -> *mut ::c_void; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; + pub fn loadquery(flags: ::c_int, buf: *mut ::c_char, buflen: ::c_uint) -> ::c_int; + pub fn lpar_get_info(command: ::c_int, buf: *mut ::c_void, bufsize: ::size_t) -> ::c_int; + pub fn lpar_set_resources(id: ::c_int, resource: *mut ::c_void) -> ::c_int; + pub fn lrand48() -> c_long; + pub fn lsearch( + key: *const ::c_void, + base: *mut ::c_void, + nelp: *mut ::size_t, + width: ::size_t, + compar: ::Option ::c_int>, + ) -> *mut ::c_void; + pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t; + pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn makecontext(ucp: *mut ::ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); + pub fn mallinfo() -> ::mallinfo; + pub fn mallopt(param: ::c_int, value: ::c_int) -> ::c_int; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn mount(device: *const ::c_char, path: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_notify(mqd: ::mqd_t, notification: *const ::sigevent) -> ::c_int; + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn mrand48() -> c_long; + pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int; + pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + pub fn msgsnd( + msqid: ::c_int, + msgp: *const ::c_void, + msgsz: ::size_t, + msgflg: ::c_int, + ) -> ::c_int; + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + pub fn nl_langinfo_l(item: ::nl_item, loc: ::locale_t) -> *mut ::c_char; + pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn pollset_create(maxfd: ::c_int) -> pollset_t; + pub fn pollset_ctl( + ps: pollset_t, + pollctl_array: *mut poll_ctl, + array_length: ::c_int, + ) -> ::c_int; + pub fn pollset_destroy(ps: pollset_t) -> ::c_int; + pub fn pollset_poll( + ps: pollset_t, + polldata_array: *mut ::pollfd, + array_length: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn pollset_query(ps: pollset_t, pollfd_query: *mut ::pollfd) -> ::c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advise: ::c_int, + ) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + flags: *mut ::c_int, + ) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn ptrace64( + request: ::c_int, + id: ::c_longlong, + addr: ::c_longlong, + data: ::c_int, + buff: *mut ::c_int, + ) -> ::c_int; + pub fn pututline(u: *const utmp) -> *mut utmp; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: off64_t, + ) -> ::ssize_t; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + #[link_name = "__linux_quotactl"] + pub fn quotactl( + cmd: ::c_int, + special: *const ::c_char, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn rand() -> ::c_int; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + pub fn recvmsg(sockfd: ::c_int, msg: *mut msghdr, flags: ::c_int) -> ::ssize_t; + pub fn regcomp(preg: *mut regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; + pub fn regerror( + errcode: ::c_int, + preg: *const ::regex_t, + errbuf: *mut ::c_char, + errbuf_size: ::size_t, + ) -> ::size_t; + pub fn regexec( + preg: *const regex_t, + input: *const ::c_char, + nmatch: ::size_t, + pmatch: *mut regmatch_t, + eflags: ::c_int, + ) -> ::c_int; + pub fn regfree(preg: *mut regex_t); + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + pub fn sched_getparam(pid: ::pid_t, param: *mut sched_param) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sctp_opt_info( + sd: ::c_int, + id: ::sctp_assoc_t, + opt: ::c_int, + arg_size: *mut ::c_void, + size: *mut ::size_t, + ) -> ::c_int; + pub fn sctp_peeloff(s: ::c_int, id: ::sctp_assoc_t) -> ::c_int; + pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn semget(key: ::key_t, nsems: ::c_int, semflag: ::c_int) -> ::c_int; + pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; + pub fn send_file(socket: *mut ::c_int, iobuf: *mut sf_parms, flags: ::c_uint) -> ::ssize_t; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn sendmsg(sockfd: ::c_int, msg: *const msghdr, flags: ::c_int) -> ::ssize_t; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + pub fn setgrent(); + pub fn sethostid(hostid: ::c_int) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE; + pub fn setpriority(which: ::c_int, who: id_t, priority: ::c_int) -> ::c_int; + pub fn setpwent(); + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn setrlimit64(resource: ::c_int, rlim: *const rlimit64) -> ::c_int; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn setitimer( + which: ::c_int, + new_value: *const ::itimerval, + old_value: *mut ::itimerval, + ) -> ::c_int; + pub fn setutent(); + pub fn setutxent(); + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn shmget(key: key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + pub fn splice(socket1: ::c_int, socket2: ::c_int, flags: ::c_int) -> ::c_int; + pub fn srand(seed: ::c_uint); + pub fn srand48(seed: ::c_long); + pub fn stat64(path: *const ::c_char, buf: *mut stat64) -> ::c_int; + pub fn stat64at( + dirfd: ::c_int, + path: *const ::c_char, + buf: *mut stat64, + flags: ::c_int, + ) -> ::c_int; + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int; + pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int; + pub fn statx( + path: *const ::c_char, + buf: *mut stat, + length: ::c_int, + command: ::c_int, + ) -> ::c_int; + pub fn strcasecmp_l( + string1: *const ::c_char, + string2: *const ::c_char, + locale: ::locale_t, + ) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn strftime( + arg1: *mut c_char, + arg2: ::size_t, + arg3: *const c_char, + arg4: *const tm, + ) -> ::size_t; + pub fn strncasecmp_l( + string1: *const ::c_char, + string2: *const ::c_char, + length: ::size_t, + locale: ::locale_t, + ) -> ::c_int; + pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; + pub fn strsep(string: *mut *mut ::c_char, delim: *const ::c_char) -> *mut ::c_char; + pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int; + pub fn swapoff(puath: *const ::c_char) -> ::c_int; + pub fn swapon(path: *const ::c_char) -> ::c_int; + pub fn sync(); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn timer_create( + clockid: ::clockid_t, + sevp: *mut ::sigevent, + timerid: *mut ::timer_t, + ) -> ::c_int; + pub fn timer_delete(timerid: timer_t) -> ::c_int; + pub fn timer_getoverrun(timerid: timer_t) -> ::c_int; + pub fn timer_gettime(timerid: timer_t, value: *mut itimerspec) -> ::c_int; + pub fn timer_settime( + timerid: ::timer_t, + flags: ::c_int, + new_value: *const ::itimerspec, + old_value: *mut ::itimerspec, + ) -> ::c_int; + pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn updwtmp(file: *const ::c_char, u: *mut utmp); + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn utmpname(file: *const ::c_char) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + // Use AIX thread-safe version errno. + pub fn _Errno() -> *mut ::c_int; +} + +cfg_if! { + if #[cfg(target_arch = "powerpc64")] { + mod powerpc64; + pub use self::powerpc64::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/aix/powerpc64.rs b/utshell-0.5.0/vendor/libc/src/unix/aix/powerpc64.rs new file mode 100644 index 00000000..2cacf29f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/aix/powerpc64.rs @@ -0,0 +1,644 @@ +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + pub struct sigset_t { + pub ss_set: [c_ulong; 4], + } + + pub struct fd_set { + pub fds_bits: [c_long; 1024], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_sysid: ::c_uint, + pub l_pid: ::pid_t, + pub l_vfs: ::c_int, + pub l_start: ::off_t, + pub l_len: ::off_t, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_basetype: [::c_char; 16], + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_fstr: [::c_char; 32], + pub f_filler: [::c_ulong; 16] + } + + pub struct pthread_rwlock_t { + __rw_word: [::c_long; 10], + } + + pub struct pthread_cond_t { + __cv_word: [::c_long; 6], + } + + pub struct pthread_mutex_t { + __mt_word: [::c_long; 8], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_flag: ::c_ushort, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_ssize: ::c_int, + pub st_atime: ::st_timespec, + pub st_mtime: ::st_timespec, + pub st_ctime: ::st_timespec, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_vfstype: ::c_int, + pub st_vfs: ::c_uint, + pub st_type: ::c_uint, + pub st_gen: ::c_uint, + pub st_reserved: [::c_uint; 9], + pub st_padto_ll: ::c_uint, + pub st_size: ::off_t, + } + + pub struct statfs { + pub f_version: ::c_int, + pub f_type: ::c_int, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_fsid: ::fsid64_t, + pub f_vfstype: ::c_int, + pub f_fsize: ::c_ulong, + pub f_vfsnumber: ::c_int, + pub f_vfsoff: ::c_int, + pub f_vfslen: ::c_int, + pub f_vfsvers: ::c_int, + pub f_fname: [::c_char; 32], + pub f_fpack: [::c_char; 32], + pub f_name_max: ::c_int, + } + + pub struct aiocb { + pub aio_lio_opcode: ::c_int, + pub aio_fildes: ::c_int, + pub aio_word1: ::c_int, + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_return: ::ssize_t, + pub aio_errno: ::c_int, + pub aio_nbytes: ::size_t, + pub aio_reqprio: ::c_int, + pub aio_sigevent: ::sigevent, + pub aio_word2: ::c_int, + pub aio_fp: ::c_int, + pub aio_handle: *mut aiocb, + pub aio_reserved: [::c_uint; 2], + pub aio_sigev_tid: c_long, + } + + pub struct ucontext_t { + pub __sc_onstack: ::c_int, + pub uc_sigmask: ::sigset_t, + pub __sc_uerror: ::c_int, + pub uc_mcontext: ::mcontext_t, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + // Should be pointer to __extctx_t + pub __extctx: *mut ::c_void, + pub __extctx_magic: ::c_int, + pub __pad: [::c_int; 1], + } + + pub struct mcontext_t { + pub gpr: [::c_ulonglong; 32], + pub msr: ::c_ulonglong, + pub iar: ::c_ulonglong, + pub lr: ::c_ulonglong, + pub ctr: ::c_ulonglong, + pub cr: ::c_uint, + pub xer: ::c_uint, + pub fpscr: ::c_uint, + pub fpscrx: ::c_uint, + pub except: [::c_ulonglong; 1], + // Should be array of double type + pub fpr: [::uint64_t; 32], + pub fpeu: ::c_char, + pub fpinfo: ::c_char, + pub fpscr24_31: ::c_char, + pub pad: [::c_char; 1], + pub excp_type: ::c_int, + } + + pub struct utmpx { + pub ut_user: [::c_char; 256], + pub ut_id: [::c_char; 14], + pub ut_line: [::c_char; 64], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_host: [::c_char; 256], + pub __dbl_word_pad: ::c_int, + pub __reservedA: [::c_int; 2], + pub __reservedV: [::c_int; 6], + } + + pub struct pthread_spinlock_t { + pub __sp_word: [::c_long; 3], + } + + pub struct pthread_barrier_t { + pub __br_word: [::c_long; 5], + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_first: ::c_uint, + pub msg_last: ::c_uint, + pub msg_cbytes: ::c_uint, + pub msg_qnum: ::c_uint, + pub msg_qbytes: ::c_ulong, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + pub msg_rwait: ::c_int, + pub msg_wwait: ::c_int, + pub msg_reqevents: ::c_ushort, + } +} + +s_no_extra_traits! { + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub si_pid: ::pid_t, + pub si_uid: ::uid_t, + pub si_status: ::c_int, + pub si_addr: *mut ::c_void, + pub si_band: ::c_long, + pub si_value: ::sigval, + pub __si_flags: ::c_int, + pub __pad: [::c_int; 3], + } + + #[cfg(libc_union)] + pub union _kernel_simple_lock { + pub _slock: ::c_long, + // Should be pointer to 'lock_data_instrumented' + pub _slockp: *mut ::c_void, + } + + pub struct fileops_t { + pub fo_rw: extern fn(file: *mut file, rw: ::uio_rw, io: *mut ::c_void, ext: ::c_long, + secattr: *mut ::c_void) -> ::c_int, + pub fo_ioctl: extern fn(file: *mut file, a: ::c_long, b: ::caddr_t, c: ::c_long, + d: ::c_long) -> ::c_int, + pub fo_select: extern fn(file: *mut file, a: ::c_int, b: *mut ::c_ushort, + c: extern fn()) -> ::c_int, + pub fo_close: extern fn(file: *mut file) -> ::c_int, + pub fo_fstat: extern fn(file: *mut file, sstat: *mut ::stat) -> ::c_int, + } + + pub struct file { + pub f_flag: ::c_long, + pub f_count: ::c_int, + pub f_options: ::c_short, + pub f_type: ::c_short, + // Should be pointer to 'vnode' + pub f_data: *mut ::c_void, + pub f_offset: ::c_longlong, + pub f_dir_off: ::c_long, + // Should be pointer to 'cred' + pub f_cred: *mut ::c_void, + #[cfg(libc_union)] + pub f_lock: _kernel_simple_lock, + #[cfg(libc_union)] + pub f_offset_lock: _kernel_simple_lock, + pub f_vinfo: ::caddr_t, + pub f_ops: *mut fileops_t, + pub f_parentp: ::caddr_t, + pub f_fnamep: ::caddr_t, + pub f_fdata: [::c_char; 160], + } + + #[cfg(libc_union)] + pub union __ld_info_file { + pub _ldinfo_fd: ::c_int, + pub _ldinfo_fp: *mut file, + pub _core_offset: ::c_long, + } + + pub struct ld_info { + pub ldinfo_next: ::c_uint, + pub ldinfo_flags: ::c_uint, + #[cfg(libc_union)] + pub _file: __ld_info_file, + pub ldinfo_textorg: *mut ::c_void, + pub ldinfo_textsize: ::c_ulong, + pub ldinfo_dataorg: *mut ::c_void, + pub ldinfo_datasize: ::c_ulong, + pub ldinfo_filename: [::c_char; 2], + } + + #[cfg(libc_union)] + pub union __pollfd_ext_u { + pub addr: *mut ::c_void, + pub data32: u32, + pub data: u64, + } + + pub struct pollfd_ext { + pub fd: ::c_int, + pub events: ::c_ushort, + pub revents: ::c_ushort, + #[cfg(libc_union)] + pub data: __pollfd_ext_u, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.si_status + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + #[cfg(libc_union)] + let value_eq = self.si_value == other.si_value; + #[cfg(not(libc_union))] + let value_eq = true; + self.si_signo == other.si_signo + && self.si_errno == other.si_errno + && self.si_code == other.si_code + && self.si_pid == other.si_pid + && self.si_uid == other.si_uid + && self.si_status == other.si_status + && self.si_addr == other.si_addr + && self.si_band == other.si_band + && self.__si_flags == other.__si_flags + && value_eq + } + } + impl Eq for siginfo_t {} + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("siginfo_t"); + struct_formatter.field("si_signo", &self.si_signo); + struct_formatter.field("si_errno", &self.si_errno); + struct_formatter.field("si_code", &self.si_code); + struct_formatter.field("si_pid", &self.si_pid); + struct_formatter.field("si_uid", &self.si_uid); + struct_formatter.field("si_status", &self.si_status); + struct_formatter.field("si_addr", &self.si_addr); + struct_formatter.field("si_band", &self.si_band); + #[cfg(libc_union)] + struct_formatter.field("si_value", &self.si_value); + struct_formatter.field("__si_flags", &self.__si_flags); + struct_formatter.finish() + } + } + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_errno.hash(state); + self.si_code.hash(state); + self.si_pid.hash(state); + self.si_uid.hash(state); + self.si_status.hash(state); + self.si_addr.hash(state); + self.si_band.hash(state); + #[cfg(libc_union)] + self.si_value.hash(state); + self.__si_flags.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for _kernel_simple_lock { + fn eq(&self, other: &_kernel_simple_lock) -> bool { + unsafe { + self._slock == other._slock + && self._slockp == other._slockp + } + } + } + #[cfg(libc_union)] + impl Eq for _kernel_simple_lock {} + #[cfg(libc_union)] + impl ::fmt::Debug for _kernel_simple_lock { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("_kernel_simple_lock") + .field("_slock", unsafe { &self._slock }) + .field("_slockp", unsafe { &self._slockp }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for _kernel_simple_lock { + fn hash(&self, state: &mut H) { + unsafe { + self._slock.hash(state); + self._slockp.hash(state); + } + } + } + + impl PartialEq for fileops_t { + fn eq(&self, other: &fileops_t) -> bool { + self.fo_rw == other.fo_rw + && self.fo_ioctl == other.fo_ioctl + && self.fo_select == other.fo_select + && self.fo_close == other.fo_close + && self.fo_fstat == other.fo_fstat + } + } + impl Eq for fileops_t {} + impl ::fmt::Debug for fileops_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("fileops_t"); + struct_formatter.field("fo_rw", &self.fo_rw); + struct_formatter.field("fo_ioctl", &self.fo_ioctl); + struct_formatter.field("fo_select", &self.fo_select); + struct_formatter.field("fo_close", &self.fo_close); + struct_formatter.field("fo_fstat", &self.fo_fstat); + struct_formatter.finish() + } + } + impl ::hash::Hash for fileops_t { + fn hash(&self, state: &mut H) { + self.fo_rw.hash(state); + self.fo_ioctl.hash(state); + self.fo_select.hash(state); + self.fo_close.hash(state); + self.fo_fstat.hash(state); + } + } + + impl PartialEq for file { + fn eq(&self, other: &file) -> bool { + #[cfg(libc_union)] + let lock_eq = self.f_lock == other.f_lock + && self.f_offset_lock == other.f_offset_lock; + #[cfg(not(libc_union))] + let lock_eq = true; + self.f_flag == other.f_flag + && self.f_count == other.f_count + && self.f_options == other.f_options + && self.f_type == other.f_type + && self.f_data == other.f_data + && self.f_offset == other.f_offset + && self.f_dir_off == other.f_dir_off + && self.f_cred == other.f_cred + && self.f_vinfo == other.f_vinfo + && self.f_ops == other.f_ops + && self.f_parentp == other.f_parentp + && self.f_fnamep == other.f_fnamep + && self.f_fdata == other.f_fdata + && lock_eq + } + } + impl Eq for file {} + impl ::fmt::Debug for file { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("file"); + struct_formatter.field("f_flag", &self.f_flag); + struct_formatter.field("f_count", &self.f_count); + struct_formatter.field("f_options", &self.f_options); + struct_formatter.field("f_type", &self.f_type); + struct_formatter.field("f_data", &self.f_data); + struct_formatter.field("f_offset", &self.f_offset); + struct_formatter.field("f_dir_off", &self.f_dir_off); + struct_formatter.field("f_cred", &self.f_cred); + #[cfg(libc_union)] + struct_formatter.field("f_lock", &self.f_lock); + #[cfg(libc_union)] + struct_formatter.field("f_offset_lock", &self.f_offset_lock); + struct_formatter.field("f_vinfo", &self.f_vinfo); + struct_formatter.field("f_ops", &self.f_ops); + struct_formatter.field("f_parentp", &self.f_parentp); + struct_formatter.field("f_fnamep", &self.f_fnamep); + struct_formatter.field("f_fdata", &self.f_fdata); + struct_formatter.finish() + } + } + impl ::hash::Hash for file { + fn hash(&self, state: &mut H) { + self.f_flag.hash(state); + self.f_count.hash(state); + self.f_options.hash(state); + self.f_type.hash(state); + self.f_data.hash(state); + self.f_offset.hash(state); + self.f_dir_off.hash(state); + self.f_cred.hash(state); + #[cfg(libc_union)] + self.f_lock.hash(state); + #[cfg(libc_union)] + self.f_offset_lock.hash(state); + self.f_vinfo.hash(state); + self.f_ops.hash(state); + self.f_parentp.hash(state); + self.f_fnamep.hash(state); + self.f_fdata.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __ld_info_file { + fn eq(&self, other: &__ld_info_file) -> bool { + unsafe { + self._ldinfo_fd == other._ldinfo_fd + && self._ldinfo_fp == other._ldinfo_fp + && self._core_offset == other._core_offset + } + } + } + #[cfg(libc_union)] + impl Eq for __ld_info_file {} + #[cfg(libc_union)] + impl ::fmt::Debug for __ld_info_file { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__ld_info_file") + .field("_ldinfo_fd", unsafe { &self._ldinfo_fd }) + .field("_ldinfo_fp", unsafe { &self._ldinfo_fp }) + .field("_core_offset", unsafe { &self._core_offset }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __ld_info_file { + fn hash(&self, state: &mut H) { + unsafe { + self._ldinfo_fd.hash(state); + self._ldinfo_fp.hash(state); + self._core_offset.hash(state); + } + } + } + + impl PartialEq for ld_info { + fn eq(&self, other: &ld_info) -> bool { + #[cfg(libc_union)] + let file_eq = self._file == other._file; + #[cfg(not(libc_union))] + let file_eq = true; + self.ldinfo_next == other.ldinfo_next + && self.ldinfo_flags == other.ldinfo_flags + && self.ldinfo_textorg == other.ldinfo_textorg + && self.ldinfo_textsize == other.ldinfo_textsize + && self.ldinfo_dataorg == other.ldinfo_dataorg + && self.ldinfo_datasize == other.ldinfo_datasize + && self.ldinfo_filename == other.ldinfo_filename + && file_eq + } + } + impl Eq for ld_info {} + impl ::fmt::Debug for ld_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("ld_info"); + struct_formatter.field("ldinfo_next", &self.ldinfo_next); + struct_formatter.field("ldinfo_flags", &self.ldinfo_flags); + struct_formatter.field("ldinfo_textorg", &self.ldinfo_textorg); + struct_formatter.field("ldinfo_textsize", &self.ldinfo_textsize); + struct_formatter.field("ldinfo_dataorg", &self.ldinfo_dataorg); + struct_formatter.field("ldinfo_datasize", &self.ldinfo_datasize); + struct_formatter.field("ldinfo_filename", &self.ldinfo_filename); + #[cfg(libc_union)] + struct_formatter.field("_file", &self._file); + struct_formatter.finish() + } + } + impl ::hash::Hash for ld_info { + fn hash(&self, state: &mut H) { + self.ldinfo_next.hash(state); + self.ldinfo_flags.hash(state); + self.ldinfo_textorg.hash(state); + self.ldinfo_textsize.hash(state); + self.ldinfo_dataorg.hash(state); + self.ldinfo_datasize.hash(state); + self.ldinfo_filename.hash(state); + #[cfg(libc_union)] + self._file.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __pollfd_ext_u { + fn eq(&self, other: &__pollfd_ext_u) -> bool { + unsafe { + self.addr == other.addr + && self.data32 == other.data32 + && self.data == other.data + } + } + } + #[cfg(libc_union)] + impl Eq for __pollfd_ext_u {} + #[cfg(libc_union)] + impl ::fmt::Debug for __pollfd_ext_u { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__pollfd_ext_u") + .field("addr", unsafe { &self.addr }) + .field("data32", unsafe { &self.data32 }) + .field("data", unsafe { &self.data }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __pollfd_ext_u { + fn hash(&self, state: &mut H) { + unsafe { + self.addr.hash(state); + self.data.hash(state); + self.data32.hash(state); + } + } + } + + impl PartialEq for pollfd_ext { + fn eq(&self, other: &pollfd_ext) -> bool { + #[cfg(libc_union)] + let data_eq = self.data == other.data; + #[cfg(not(libc_union))] + let data_eq = true; + self.fd == other.fd + && self.events == other.events + && self.revents == other.revents + && data_eq + } + } + impl Eq for pollfd_ext {} + impl ::fmt::Debug for pollfd_ext { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("pollfd_ext"); + struct_formatter.field("fd", &self.fd); + struct_formatter.field("events", &self.events); + struct_formatter.field("revents", &self.revents); + #[cfg(libc_union)] + struct_formatter.field("data", &self.data); + struct_formatter.finish() + } + } + impl ::hash::Hash for pollfd_ext { + fn hash(&self, state: &mut H) { + self.fd.hash(state); + self.events.hash(state); + self.revents.hash(state); + #[cfg(libc_union)] + self.data.hash(state); + } + } + } +} + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __mt_word: [0, 2, 0, 0, 0, 0, 0, 0], +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __cv_word: [0, 0, 0, 0, 2, 0], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __rw_word: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0], +}; +pub const RLIM_INFINITY: ::c_ulong = 0x7fffffffffffffff; + +extern "C" { + pub fn getsystemcfg(label: ::c_int) -> ::c_ulong; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/align.rs b/utshell-0.5.0/vendor/libc/src/unix/align.rs new file mode 100644 index 00000000..4fdba9a6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/align.rs @@ -0,0 +1,6 @@ +s! { + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/align.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/align.rs new file mode 100644 index 00000000..ca1fe1ce --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/mod.rs new file mode 100644 index 00000000..0f1722f9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b32/mod.rs @@ -0,0 +1,119 @@ +//! 32-bit specific Apple (ios/darwin) definitions + +pub type c_long = i32; +pub type c_ulong = u32; +pub type boolean_t = ::c_int; + +s! { + pub struct if_data { + pub ifi_type: ::c_uchar, + pub ifi_typelen: ::c_uchar, + pub ifi_physical: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_recvquota: ::c_uchar, + pub ifi_xmitquota: ::c_uchar, + pub ifi_unused1: ::c_uchar, + pub ifi_mtu: u32, + pub ifi_metric: u32, + pub ifi_baudrate: u32, + pub ifi_ipackets: u32, + pub ifi_ierrors: u32, + pub ifi_opackets: u32, + pub ifi_oerrors: u32, + pub ifi_collisions: u32, + pub ifi_ibytes: u32, + pub ifi_obytes: u32, + pub ifi_imcasts: u32, + pub ifi_omcasts: u32, + pub ifi_iqdrops: u32, + pub ifi_noproto: u32, + pub ifi_recvtiming: u32, + pub ifi_xmittiming: u32, + pub ifi_lastchange: ::timeval, + pub ifi_unused2: u32, + pub ifi_hwassist: u32, + pub ifi_reserved1: u32, + pub ifi_reserved2: u32, + } + + pub struct bpf_hdr { + pub bh_tstamp: ::timeval, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: ::c_ushort, + } + + pub struct malloc_zone_t { + __private: [::uintptr_t; 18], // FIXME: keeping private for now + } +} + +s_no_extra_traits! { + pub struct pthread_attr_t { + __sig: c_long, + __opaque: [::c_char; 36] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_attr_t { + fn eq(&self, other: &pthread_attr_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_attr_t {} + impl ::fmt::Debug for pthread_attr_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_attr_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_attr_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + } +} + +#[doc(hidden)] +#[deprecated(since = "0.2.55")] +pub const NET_RT_MAXID: ::c_int = 10; + +pub const __PTHREAD_MUTEX_SIZE__: usize = 40; +pub const __PTHREAD_COND_SIZE__: usize = 24; +pub const __PTHREAD_CONDATTR_SIZE__: usize = 4; +pub const __PTHREAD_RWLOCK_SIZE__: usize = 124; +pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 12; + +pub const TIOCTIMESTAMP: ::c_ulong = 0x40087459; +pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40087458; + +pub const BIOCSETF: ::c_ulong = 0x80084267; +pub const BIOCSRTIMEOUT: ::c_ulong = 0x8008426d; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4008426e; +pub const BIOCSETFNR: ::c_ulong = 0x8008427e; + +extern "C" { + pub fn exchangedata( + path1: *const ::c_char, + path2: *const ::c_char, + options: ::c_ulong, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs new file mode 100644 index 00000000..131e15b6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs @@ -0,0 +1,55 @@ +pub type mcontext_t = *mut __darwin_mcontext64; + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct max_align_t { + priv_: f64 + } +} + +s! { + pub struct ucontext_t { + pub uc_onstack: ::c_int, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_link: *mut ::ucontext_t, + pub uc_mcsize: usize, + pub uc_mcontext: mcontext_t, + } + + pub struct __darwin_mcontext64 { + pub __es: __darwin_arm_exception_state64, + pub __ss: __darwin_arm_thread_state64, + pub __ns: __darwin_arm_neon_state64, + } + + pub struct __darwin_arm_exception_state64 { + pub __far: u64, + pub __esr: u32, + pub __exception: u32, + } + + pub struct __darwin_arm_thread_state64 { + pub __x: [u64; 29], + pub __fp: u64, + pub __lr: u64, + pub __sp: u64, + pub __pc: u64, + pub __cpsr: u32, + pub __pad: u32, + } + + // This type natively uses a uint128, but for a while we hacked + // it in with repr(align) and `[u64; 2]`. uint128 isn't available + // all the way back to our earliest supported versions so we + // preserver the old shim. + #[cfg_attr(not(libc_int128), repr(align(16)))] + pub struct __darwin_arm_neon_state64 { + #[cfg(libc_int128)] + pub __v: [::__uint128_t; 32], + #[cfg(not(libc_int128))] + pub __v: [[u64; 2]; 32], + pub __fpsr: u32, + pub __fpcr: u32, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs new file mode 100644 index 00000000..79e9ac84 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs @@ -0,0 +1,14 @@ +pub type boolean_t = ::c_int; + +s! { + pub struct malloc_zone_t { + __private: [::uintptr_t; 18], // FIXME: needs arm64 auth pointers support + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/align.rs new file mode 100644 index 00000000..ca1fe1ce --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/mod.rs new file mode 100644 index 00000000..48d94bcd --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/mod.rs @@ -0,0 +1,124 @@ +//! 64-bit specific Apple (ios/darwin) definitions + +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + pub struct timeval32 { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct if_data { + pub ifi_type: ::c_uchar, + pub ifi_typelen: ::c_uchar, + pub ifi_physical: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_recvquota: ::c_uchar, + pub ifi_xmitquota: ::c_uchar, + pub ifi_unused1: ::c_uchar, + pub ifi_mtu: u32, + pub ifi_metric: u32, + pub ifi_baudrate: u32, + pub ifi_ipackets: u32, + pub ifi_ierrors: u32, + pub ifi_opackets: u32, + pub ifi_oerrors: u32, + pub ifi_collisions: u32, + pub ifi_ibytes: u32, + pub ifi_obytes: u32, + pub ifi_imcasts: u32, + pub ifi_omcasts: u32, + pub ifi_iqdrops: u32, + pub ifi_noproto: u32, + pub ifi_recvtiming: u32, + pub ifi_xmittiming: u32, + pub ifi_lastchange: timeval32, + pub ifi_unused2: u32, + pub ifi_hwassist: u32, + pub ifi_reserved1: u32, + pub ifi_reserved2: u32, + } + + pub struct bpf_hdr { + pub bh_tstamp: ::timeval32, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: ::c_ushort, + } +} + +s_no_extra_traits! { + pub struct pthread_attr_t { + __sig: c_long, + __opaque: [::c_char; 56] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_attr_t { + fn eq(&self, other: &pthread_attr_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_attr_t {} + impl ::fmt::Debug for pthread_attr_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_attr_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_attr_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + } +} + +#[doc(hidden)] +#[deprecated(since = "0.2.55")] +pub const NET_RT_MAXID: ::c_int = 11; + +pub const __PTHREAD_MUTEX_SIZE__: usize = 56; +pub const __PTHREAD_COND_SIZE__: usize = 40; +pub const __PTHREAD_CONDATTR_SIZE__: usize = 8; +pub const __PTHREAD_RWLOCK_SIZE__: usize = 192; +pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 16; + +pub const TIOCTIMESTAMP: ::c_ulong = 0x40107459; +pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40107458; + +pub const BIOCSETF: ::c_ulong = 0x80104267; +pub const BIOCSRTIMEOUT: ::c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; +pub const BIOCSETFNR: ::c_ulong = 0x8010427e; + +extern "C" { + pub fn exchangedata( + path1: *const ::c_char, + path2: *const ::c_char, + options: ::c_uint, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs new file mode 100644 index 00000000..ca1fe1ce --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs new file mode 100644 index 00000000..653650c2 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs @@ -0,0 +1,180 @@ +pub type boolean_t = ::c_uint; +pub type mcontext_t = *mut __darwin_mcontext64; + +s! { + pub struct ucontext_t { + pub uc_onstack: ::c_int, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_link: *mut ::ucontext_t, + pub uc_mcsize: usize, + pub uc_mcontext: mcontext_t, + } + + pub struct __darwin_mcontext64 { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_state64, + pub __fs: __darwin_x86_float_state64, + } + + pub struct __darwin_x86_exception_state64 { + pub __trapno: u16, + pub __cpu: u16, + pub __err: u32, + pub __faultvaddr: u64, + } + + pub struct __darwin_x86_thread_state64 { + pub __rax: u64, + pub __rbx: u64, + pub __rcx: u64, + pub __rdx: u64, + pub __rdi: u64, + pub __rsi: u64, + pub __rbp: u64, + pub __rsp: u64, + pub __r8: u64, + pub __r9: u64, + pub __r10: u64, + pub __r11: u64, + pub __r12: u64, + pub __r13: u64, + pub __r14: u64, + pub __r15: u64, + pub __rip: u64, + pub __rflags: u64, + pub __cs: u64, + pub __fs: u64, + pub __gs: u64, + } + + pub struct __darwin_x86_float_state64 { + pub __fpu_reserved: [::c_int; 2], + __fpu_fcw: ::c_short, + __fpu_fsw: ::c_short, + pub __fpu_ftw: u8, + pub __fpu_rsrv1: u8, + pub __fpu_fop: u16, + pub __fpu_ip: u32, + pub __fpu_cs: u16, + pub __fpu_rsrv2: u16, + pub __fpu_dp: u32, + pub __fpu_ds: u16, + pub __fpu_rsrv3: u16, + pub __fpu_mxcsr: u32, + pub __fpu_mxcsrmask: u32, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_xmm8: __darwin_xmm_reg, + pub __fpu_xmm9: __darwin_xmm_reg, + pub __fpu_xmm10: __darwin_xmm_reg, + pub __fpu_xmm11: __darwin_xmm_reg, + pub __fpu_xmm12: __darwin_xmm_reg, + pub __fpu_xmm13: __darwin_xmm_reg, + pub __fpu_xmm14: __darwin_xmm_reg, + pub __fpu_xmm15: __darwin_xmm_reg, + // this field is actually [u8; 96], but defining it with a bigger type + // allows us to auto-implement traits for it since the length of the + // array is less than 32 + __fpu_rsrv4: [u32; 24], + pub __fpu_reserved1: ::c_int, + } + + pub struct __darwin_mmst_reg { + pub __mmst_reg: [::c_char; 10], + pub __mmst_rsrv: [::c_char; 6], + } + + pub struct __darwin_xmm_reg { + pub __xmm_reg: [::c_char; 16], + } + + pub struct malloc_introspection_t { + _private: [::uintptr_t; 16], // FIXME: keeping private for now + } + + pub struct malloc_zone_t { + _reserved1: *mut ::c_void, + _reserved2: *mut ::c_void, + pub size: ::Option ::size_t>, + pub malloc: ::Option *mut ::c_void>, + pub calloc: ::Option *mut ::c_void>, + pub valloc: ::Option *mut ::c_void>, + pub free: ::Option, + pub realloc: ::Option *mut ::c_void>, + pub destroy: ::Option, + pub zone_name: *const ::c_char, + pub batch_malloc: ::Option ::c_uint>, + pub batch_free: ::Option, + pub introspect: *mut malloc_introspection_t, + pub version: ::c_uint, + pub memalign: ::Option *mut ::c_void>, + pub free_definite_size: ::Option, + pub pressure_relief: ::Option ::size_t>, + pub claimed_address: ::Option ::boolean_t>, + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/long_array.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/long_array.rs new file mode 100644 index 00000000..4c56a275 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/long_array.rs @@ -0,0 +1,8 @@ +s! { + pub struct ctl_info { + pub ctl_id: u32, + pub ctl_name: [::c_char; MAX_KCTL_NAME], + } +} + +pub const MAX_KCTL_NAME: usize = 96; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/mod.rs new file mode 100644 index 00000000..2e782723 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/apple/mod.rs @@ -0,0 +1,6528 @@ +//! Apple (ios/darwin)-specific definitions +//! +//! This covers *-apple-* triples currently +pub type c_char = i8; +pub type wchar_t = i32; +pub type clock_t = c_ulong; +pub type time_t = c_long; +pub type suseconds_t = i32; +pub type dev_t = i32; +pub type ino_t = u64; +pub type mode_t = u16; +pub type nlink_t = u16; +pub type blksize_t = i32; +pub type rlim_t = u64; +pub type pthread_key_t = c_ulong; +pub type sigset_t = u32; +pub type clockid_t = ::c_uint; +pub type fsblkcnt_t = ::c_uint; +pub type fsfilcnt_t = ::c_uint; +pub type speed_t = ::c_ulong; +pub type tcflag_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type id_t = ::c_uint; +pub type sem_t = ::c_int; +pub type idtype_t = ::c_uint; +pub type integer_t = ::c_int; +pub type cpu_type_t = integer_t; +pub type cpu_subtype_t = integer_t; +pub type natural_t = u32; +pub type mach_msg_type_number_t = natural_t; +pub type kern_return_t = ::c_int; +pub type uuid_t = [u8; 16]; +pub type task_info_t = *mut integer_t; +pub type host_info_t = *mut integer_t; +pub type task_flavor_t = natural_t; +pub type rusage_info_t = *mut ::c_void; +pub type vm_offset_t = ::uintptr_t; +pub type vm_size_t = ::uintptr_t; +pub type vm_address_t = vm_offset_t; + +pub type posix_spawnattr_t = *mut ::c_void; +pub type posix_spawn_file_actions_t = *mut ::c_void; +pub type key_t = ::c_int; +pub type shmatt_t = ::c_ushort; + +pub type sae_associd_t = u32; +pub type sae_connid_t = u32; + +pub type mach_port_t = ::c_uint; +pub type host_t = ::c_uint; +pub type host_flavor_t = integer_t; +pub type host_info64_t = *mut integer_t; +pub type processor_flavor_t = ::c_int; +pub type thread_flavor_t = natural_t; +pub type thread_inspect_t = ::mach_port_t; +pub type thread_act_t = ::mach_port_t; +pub type thread_act_array_t = *mut ::thread_act_t; +pub type policy_t = ::c_int; +pub type mach_vm_address_t = u64; +pub type mach_vm_offset_t = u64; +pub type mach_vm_size_t = u64; +pub type vm_map_t = ::mach_port_t; +pub type mem_entry_name_port_t = ::mach_port_t; +pub type memory_object_t = ::mach_port_t; +pub type memory_object_offset_t = ::c_ulonglong; +pub type vm_inherit_t = ::c_uint; +pub type vm_prot_t = ::c_int; + +pub type ledger_t = ::mach_port_t; +pub type ledger_array_t = *mut ::ledger_t; + +pub type iconv_t = *mut ::c_void; + +pub type processor_cpu_load_info_t = *mut processor_cpu_load_info; +pub type processor_cpu_load_info_data_t = processor_cpu_load_info; +pub type processor_basic_info_t = *mut processor_basic_info; +pub type processor_basic_info_data_t = processor_basic_info; +pub type processor_set_basic_info_data_t = processor_set_basic_info; +pub type processor_set_basic_info_t = *mut processor_set_basic_info; +pub type processor_set_load_info_data_t = processor_set_load_info; +pub type processor_set_load_info_t = *mut processor_set_load_info; +pub type processor_info_t = *mut integer_t; +pub type processor_info_array_t = *mut integer_t; + +pub type mach_task_basic_info_data_t = mach_task_basic_info; +pub type mach_task_basic_info_t = *mut mach_task_basic_info; +pub type task_thread_times_info_data_t = task_thread_times_info; +pub type task_thread_times_info_t = *mut task_thread_times_info; + +pub type thread_info_t = *mut integer_t; +pub type thread_basic_info_t = *mut thread_basic_info; +pub type thread_basic_info_data_t = thread_basic_info; +pub type thread_identifier_info_t = *mut thread_identifier_info; +pub type thread_identifier_info_data_t = thread_identifier_info; +pub type thread_extended_info_t = *mut thread_extended_info; +pub type thread_extended_info_data_t = thread_extended_info; + +pub type thread_t = ::mach_port_t; +pub type thread_policy_flavor_t = natural_t; +pub type thread_policy_t = *mut integer_t; +pub type thread_latency_qos_t = integer_t; +pub type thread_throughput_qos_t = integer_t; +pub type thread_standard_policy_data_t = thread_standard_policy; +pub type thread_standard_policy_t = *mut thread_standard_policy; +pub type thread_extended_policy_data_t = thread_extended_policy; +pub type thread_extended_policy_t = *mut thread_extended_policy; +pub type thread_time_constraint_policy_data_t = thread_time_constraint_policy; +pub type thread_time_constraint_policy_t = *mut thread_time_constraint_policy; +pub type thread_precedence_policy_data_t = thread_precedence_policy; +pub type thread_precedence_policy_t = *mut thread_precedence_policy; +pub type thread_affinity_policy_data_t = thread_affinity_policy; +pub type thread_affinity_policy_t = *mut thread_affinity_policy; +pub type thread_background_policy_data_t = thread_background_policy; +pub type thread_background_policy_t = *mut thread_background_policy; +pub type thread_latency_qos_policy_data_t = thread_latency_qos_policy; +pub type thread_latency_qos_policy_t = *mut thread_latency_qos_policy; +pub type thread_throughput_qos_policy_data_t = thread_throughput_qos_policy; +pub type thread_throughput_qos_policy_t = *mut thread_throughput_qos_policy; + +pub type pthread_introspection_hook_t = + extern "C" fn(event: ::c_uint, thread: ::pthread_t, addr: *mut ::c_void, size: ::size_t); +pub type pthread_jit_write_callback_t = ::Option ::c_int>; + +pub type os_unfair_lock = os_unfair_lock_s; +pub type os_unfair_lock_t = *mut os_unfair_lock; + +pub type os_log_t = *mut ::c_void; +pub type os_log_type_t = u8; +pub type os_signpost_id_t = u64; +pub type os_signpost_type_t = u8; + +pub type vm_statistics_t = *mut vm_statistics; +pub type vm_statistics_data_t = vm_statistics; +pub type vm_statistics64_t = *mut vm_statistics64; +pub type vm_statistics64_data_t = vm_statistics64; + +pub type task_t = ::mach_port_t; +pub type task_inspect_t = ::mach_port_t; + +pub type sysdir_search_path_enumeration_state = ::c_uint; + +pub type CCStatus = i32; +pub type CCCryptorStatus = i32; +pub type CCRNGStatus = ::CCCryptorStatus; + +pub type copyfile_state_t = *mut ::c_void; +pub type copyfile_flags_t = u32; +pub type copyfile_callback_t = ::Option< + extern "C" fn( + ::c_int, + ::c_int, + copyfile_state_t, + *const ::c_char, + *const ::c_char, + *mut ::c_void, + ) -> ::c_int, +>; + +pub type attrgroup_t = u32; +pub type vol_capabilities_set_t = [u32; 4]; + +deprecated_mach! { + pub type mach_timebase_info_data_t = mach_timebase_info; +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +#[repr(u32)] +pub enum qos_class_t { + QOS_CLASS_USER_INTERACTIVE = 0x21, + QOS_CLASS_USER_INITIATED = 0x19, + QOS_CLASS_DEFAULT = 0x15, + QOS_CLASS_UTILITY = 0x11, + QOS_CLASS_BACKGROUND = 0x09, + QOS_CLASS_UNSPECIFIED = 0x00, +} +impl ::Copy for qos_class_t {} +impl ::Clone for qos_class_t { + fn clone(&self) -> qos_class_t { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +#[repr(u32)] +pub enum sysdir_search_path_directory_t { + SYSDIR_DIRECTORY_APPLICATION = 1, + SYSDIR_DIRECTORY_DEMO_APPLICATION = 2, + SYSDIR_DIRECTORY_DEVELOPER_APPLICATION = 3, + SYSDIR_DIRECTORY_ADMIN_APPLICATION = 4, + SYSDIR_DIRECTORY_LIBRARY = 5, + SYSDIR_DIRECTORY_DEVELOPER = 6, + SYSDIR_DIRECTORY_USER = 7, + SYSDIR_DIRECTORY_DOCUMENTATION = 8, + SYSDIR_DIRECTORY_DOCUMENT = 9, + SYSDIR_DIRECTORY_CORESERVICE = 10, + SYSDIR_DIRECTORY_AUTOSAVED_INFORMATION = 11, + SYSDIR_DIRECTORY_DESKTOP = 12, + SYSDIR_DIRECTORY_CACHES = 13, + SYSDIR_DIRECTORY_APPLICATION_SUPPORT = 14, + SYSDIR_DIRECTORY_DOWNLOADS = 15, + SYSDIR_DIRECTORY_INPUT_METHODS = 16, + SYSDIR_DIRECTORY_MOVIES = 17, + SYSDIR_DIRECTORY_MUSIC = 18, + SYSDIR_DIRECTORY_PICTURES = 19, + SYSDIR_DIRECTORY_PRINTER_DESCRIPTION = 20, + SYSDIR_DIRECTORY_SHARED_PUBLIC = 21, + SYSDIR_DIRECTORY_PREFERENCE_PANES = 22, + SYSDIR_DIRECTORY_ALL_APPLICATIONS = 100, + SYSDIR_DIRECTORY_ALL_LIBRARIES = 101, +} +impl ::Copy for sysdir_search_path_directory_t {} +impl ::Clone for sysdir_search_path_directory_t { + fn clone(&self) -> sysdir_search_path_directory_t { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +#[repr(u32)] +pub enum sysdir_search_path_domain_mask_t { + SYSDIR_DOMAIN_MASK_USER = (1 << 0), + SYSDIR_DOMAIN_MASK_LOCAL = (1 << 1), + SYSDIR_DOMAIN_MASK_NETWORK = (1 << 2), + SYSDIR_DOMAIN_MASK_SYSTEM = (1 << 3), + SYSDIR_DOMAIN_MASK_ALL = 0x0ffff, +} +impl ::Copy for sysdir_search_path_domain_mask_t {} +impl ::Clone for sysdir_search_path_domain_mask_t { + fn clone(&self) -> sysdir_search_path_domain_mask_t { + *self + } +} + +s! { + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::c_int, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_sourceaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_reqprio: ::c_int, + pub aio_sigevent: sigevent, + pub aio_lio_opcode: ::c_int + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + __unused1: ::c_int, + pub gl_offs: ::size_t, + __unused2: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + + __unused3: *mut ::c_void, + + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + } + + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + pub struct mach_timebase_info { + pub numer: u32, + pub denom: u32, + } + + pub struct stat { + pub st_dev: dev_t, + pub st_mode: mode_t, + pub st_nlink: nlink_t, + pub st_ino: ino_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: dev_t, + pub st_atime: time_t, + pub st_atime_nsec: c_long, + pub st_mtime: time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: time_t, + pub st_ctime_nsec: c_long, + pub st_birthtime: time_t, + pub st_birthtime_nsec: c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: blksize_t, + pub st_flags: u32, + pub st_gen: u32, + pub st_lspare: i32, + pub st_qspare: [i64; 2], + } + + pub struct pthread_mutexattr_t { + __sig: ::c_long, + __opaque: [u8; 8], + } + + pub struct pthread_condattr_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_CONDATTR_SIZE__], + } + + pub struct pthread_rwlockattr_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_RWLOCKATTR_SIZE__], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub si_pid: ::pid_t, + pub si_uid: ::uid_t, + pub si_status: ::c_int, + pub si_addr: *mut ::c_void, + //Requires it to be union for tests + //pub si_value: ::sigval, + _pad: [usize; 9], + } + + pub struct sigaction { + // FIXME: this field is actually a union + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + pub sa_flags: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct fstore_t { + pub fst_flags: ::c_uint, + pub fst_posmode: ::c_int, + pub fst_offset: ::off_t, + pub fst_length: ::off_t, + pub fst_bytesalloc: ::off_t, + } + + pub struct fpunchhole_t { + pub fp_flags: ::c_uint, /* unused */ + pub reserved: ::c_uint, /* (to maintain 8-byte alignment) */ + pub fp_offset: ::off_t, /* IN: start of the region */ + pub fp_length: ::off_t, /* IN: size of the region */ + } + + pub struct ftrimactivefile_t { + pub fta_offset: ::off_t, + pub fta_length: ::off_t, + } + + pub struct fspecread_t { + pub fsr_flags: ::c_uint, + pub reserved: ::c_uint, + pub fsr_offset: ::off_t, + pub fsr_length: ::off_t, + } + + pub struct radvisory { + pub ra_offset: ::off_t, + pub ra_count: ::c_int, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } + + pub struct kevent64_s { + pub ident: u64, + pub filter: i16, + pub flags: u16, + pub fflags: u32, + pub data: i64, + pub udata: u64, + pub ext: [u64; 2], + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curbytes: u64, + pub dqb_ihardlimit: u32, + pub dqb_isoftlimit: u32, + pub dqb_curinodes: u32, + pub dqb_btime: u32, + pub dqb_itime: u32, + pub dqb_id: u32, + pub dqb_spare: [u32; 4], + } + + pub struct if_msghdr { + pub ifm_msglen: ::c_ushort, + pub ifm_version: ::c_uchar, + pub ifm_type: ::c_uchar, + pub ifm_addrs: ::c_int, + pub ifm_flags: ::c_int, + pub ifm_index: ::c_ushort, + pub ifm_data: if_data, + } + + pub struct ifa_msghdr { + pub ifam_msglen: ::c_ushort, + pub ifam_version: ::c_uchar, + pub ifam_type: ::c_uchar, + pub ifam_addrs: ::c_int, + pub ifam_flags: ::c_int, + pub ifam_index: ::c_ushort, + pub ifam_metric: ::c_int, + } + + pub struct ifma_msghdr { + pub ifmam_msglen: ::c_ushort, + pub ifmam_version: ::c_uchar, + pub ifmam_type: ::c_uchar, + pub ifmam_addrs: ::c_int, + pub ifmam_flags: ::c_int, + pub ifmam_index: ::c_ushort, + } + + pub struct ifma_msghdr2 { + pub ifmam_msglen: ::c_ushort, + pub ifmam_version: ::c_uchar, + pub ifmam_type: ::c_uchar, + pub ifmam_addrs: ::c_int, + pub ifmam_flags: ::c_int, + pub ifmam_index: ::c_ushort, + pub ifmam_refcount: i32, + } + + pub struct rt_metrics { + pub rmx_locks: u32, + pub rmx_mtu: u32, + pub rmx_hopcount: u32, + pub rmx_expire: i32, + pub rmx_recvpipe: u32, + pub rmx_sendpipe: u32, + pub rmx_ssthresh: u32, + pub rmx_rtt: u32, + pub rmx_rttvar: u32, + pub rmx_pksent: u32, + pub rmx_state: u32, + pub rmx_filler: [u32; 3], + } + + pub struct rt_msghdr { + pub rtm_msglen: ::c_ushort, + pub rtm_version: ::c_uchar, + pub rtm_type: ::c_uchar, + pub rtm_index: ::c_ushort, + pub rtm_flags: ::c_int, + pub rtm_addrs: ::c_int, + pub rtm_pid: ::pid_t, + pub rtm_seq: ::c_int, + pub rtm_errno: ::c_int, + pub rtm_use: ::c_int, + pub rtm_inits: u32, + pub rtm_rmx: rt_metrics, + } + + pub struct rt_msghdr2 { + pub rtm_msglen: ::c_ushort, + pub rtm_version: ::c_uchar, + pub rtm_type: ::c_uchar, + pub rtm_index: ::c_ushort, + pub rtm_flags: ::c_int, + pub rtm_addrs: ::c_int, + pub rtm_refcnt: i32, + pub rtm_parentflags: ::c_int, + pub rtm_reserved: ::c_int, + pub rtm_use: ::c_int, + pub rtm_inits: u32, + pub rtm_rmx: rt_metrics, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_type: ::c_short, + pub l_whence: ::c_short, + } + + pub struct sf_hdtr { + pub headers: *mut ::iovec, + pub hdr_cnt: ::c_int, + pub trailers: *mut ::iovec, + pub trl_cnt: ::c_int, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct proc_taskinfo { + pub pti_virtual_size: u64, + pub pti_resident_size: u64, + pub pti_total_user: u64, + pub pti_total_system: u64, + pub pti_threads_user: u64, + pub pti_threads_system: u64, + pub pti_policy: i32, + pub pti_faults: i32, + pub pti_pageins: i32, + pub pti_cow_faults: i32, + pub pti_messages_sent: i32, + pub pti_messages_received: i32, + pub pti_syscalls_mach: i32, + pub pti_syscalls_unix: i32, + pub pti_csw: i32, + pub pti_threadnum: i32, + pub pti_numrunning: i32, + pub pti_priority: i32, + } + + pub struct proc_bsdinfo { + pub pbi_flags: u32, + pub pbi_status: u32, + pub pbi_xstatus: u32, + pub pbi_pid: u32, + pub pbi_ppid: u32, + pub pbi_uid: ::uid_t, + pub pbi_gid: ::gid_t, + pub pbi_ruid: ::uid_t, + pub pbi_rgid: ::gid_t, + pub pbi_svuid: ::uid_t, + pub pbi_svgid: ::gid_t, + pub rfu_1: u32, + pub pbi_comm: [::c_char; MAXCOMLEN], + pub pbi_name: [::c_char; 32], // MAXCOMLEN * 2, but macro isn't happy... + pub pbi_nfiles: u32, + pub pbi_pgid: u32, + pub pbi_pjobc: u32, + pub e_tdev: u32, + pub e_tpgid: u32, + pub pbi_nice: i32, + pub pbi_start_tvsec: u64, + pub pbi_start_tvusec: u64, + } + + pub struct proc_taskallinfo { + pub pbsd: proc_bsdinfo, + pub ptinfo: proc_taskinfo, + } + + pub struct xsw_usage { + pub xsu_total: u64, + pub xsu_avail: u64, + pub xsu_used: u64, + pub xsu_pagesize: u32, + pub xsu_encrypted: ::boolean_t, + } + + pub struct xucred { + pub cr_version: ::c_uint, + pub cr_uid: ::uid_t, + pub cr_ngroups: ::c_short, + pub cr_groups: [::gid_t;16] + } + + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + pub struct mach_header { + pub magic: u32, + pub cputype: cpu_type_t, + pub cpusubtype: cpu_subtype_t, + pub filetype: u32, + pub ncmds: u32, + pub sizeofcmds: u32, + pub flags: u32, + } + + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + pub struct mach_header_64 { + pub magic: u32, + pub cputype: cpu_type_t, + pub cpusubtype: cpu_subtype_t, + pub filetype: u32, + pub ncmds: u32, + pub sizeofcmds: u32, + pub flags: u32, + pub reserved: u32, + } + + pub struct segment_command { + pub cmd: u32, + pub cmdsize: u32, + pub segname: [::c_char; 16], + pub vmaddr: u32, + pub vmsize: u32, + pub fileoff: u32, + pub filesize: u32, + pub maxprot: vm_prot_t, + pub initprot: vm_prot_t, + pub nsects: u32, + pub flags: u32, + } + + pub struct segment_command_64 { + pub cmd: u32, + pub cmdsize: u32, + pub segname: [::c_char; 16], + pub vmaddr: u64, + pub vmsize: u64, + pub fileoff: u64, + pub filesize: u64, + pub maxprot: vm_prot_t, + pub initprot: vm_prot_t, + pub nsects: u32, + pub flags: u32, + } + + pub struct load_command { + pub cmd: u32, + pub cmdsize: u32, + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 12], + } + + pub struct sockaddr_inarp { + pub sin_len: ::c_uchar, + pub sin_family: ::c_uchar, + pub sin_port: ::c_ushort, + pub sin_addr: ::in_addr, + pub sin_srcaddr: ::in_addr, + pub sin_tos: ::c_ushort, + pub sin_other: ::c_ushort, + } + + pub struct sockaddr_ctl { + pub sc_len: ::c_uchar, + pub sc_family: ::c_uchar, + pub ss_sysaddr: u16, + pub sc_id: u32, + pub sc_unit: u32, + pub sc_reserved: [u32; 5], + } + + pub struct in_pktinfo { + pub ipi_ifindex: ::c_uint, + pub ipi_spec_dst: ::in_addr, + pub ipi_addr: ::in_addr, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + // sys/ipc.h: + + pub struct ipc_perm { + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub _seq: ::c_ushort, + pub _key: ::key_t, + } + + // sys/sem.h + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + // sys/shm.h + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + // net/ndrv.h + pub struct sockaddr_ndrv { + pub snd_len: ::c_uchar, + pub snd_family: ::c_uchar, + pub snd_name: [::c_uchar; ::IFNAMSIZ], + } + + // sys/socket.h + + pub struct sa_endpoints_t { + pub sae_srcif: ::c_uint, // optional source interface + pub sae_srcaddr: *const ::sockaddr, // optional source address + pub sae_srcaddrlen: ::socklen_t, // size of source address + pub sae_dstaddr: *const ::sockaddr, // destination address + pub sae_dstaddrlen: ::socklen_t, // size of destination address + } + + pub struct timex { + pub modes: ::c_uint, + pub offset: ::c_long, + pub freq: ::c_long, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub status: ::c_int, + pub constant: ::c_long, + pub precision: ::c_long, + pub tolerance: ::c_long, + pub ppsfreq: ::c_long, + pub jitter: ::c_long, + pub shift: ::c_int, + pub stabil: ::c_long, + pub jitcnt: ::c_long, + pub calcnt: ::c_long, + pub errcnt: ::c_long, + pub stbcnt: ::c_long, + } + + pub struct ntptimeval { + pub time: ::timespec, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub time_state: ::c_int, + } + + pub struct thread_standard_policy { + pub no_data: natural_t, + } + + pub struct thread_extended_policy { + pub timeshare: boolean_t, + } + + pub struct thread_time_constraint_policy { + pub period: u32, + pub computation: u32, + pub constraint: u32, + pub preemptible: boolean_t, + } + + pub struct thread_precedence_policy { + pub importance: integer_t, + } + + pub struct thread_affinity_policy { + pub affinity_tag: integer_t, + } + + pub struct thread_background_policy { + pub priority: integer_t, + } + + pub struct thread_latency_qos_policy { + pub thread_latency_qos_tier: thread_latency_qos_t, + } + + pub struct thread_throughput_qos_policy { + pub thread_throughput_qos_tier: thread_throughput_qos_t, + } + + // malloc/malloc.h + pub struct malloc_statistics_t { + pub blocks_in_use: ::c_uint, + pub size_in_use: ::size_t, + pub max_size_in_use: ::size_t, + pub size_allocated: ::size_t, + } + + pub struct mstats { + pub bytes_total: ::size_t, + pub chunks_used: ::size_t, + pub bytes_used: ::size_t, + pub chunks_free: ::size_t, + pub bytes_free: ::size_t, + } + + pub struct vm_range_t { + pub address: ::vm_address_t, + pub size: ::vm_size_t, + } + + // sched.h + pub struct sched_param { + pub sched_priority: ::c_int, + __opaque: [::c_char; 4], + } + + pub struct vinfo_stat { + pub vst_dev: u32, + pub vst_mode: u16, + pub vst_nlink: u16, + pub vst_ino: u64, + pub vst_uid: ::uid_t, + pub vst_gid: ::gid_t, + pub vst_atime: i64, + pub vst_atimensec: i64, + pub vst_mtime: i64, + pub vst_mtimensec: i64, + pub vst_ctime: i64, + pub vst_ctimensec: i64, + pub vst_birthtime: i64, + pub vst_birthtimensec: i64, + pub vst_size: ::off_t, + pub vst_blocks: i64, + pub vst_blksize: i32, + pub vst_flags: u32, + pub vst_gen: u32, + pub vst_rdev: u32, + pub vst_qspare: [i64; 2], + } + + pub struct vnode_info { + pub vi_stat: vinfo_stat, + pub vi_type: ::c_int, + pub vi_pad: ::c_int, + pub vi_fsid: ::fsid_t, + } + + pub struct vnode_info_path { + pub vip_vi: vnode_info, + // Normally it's `vip_path: [::c_char; MAXPATHLEN]` but because libc supports an old rustc + // version, we go around this limitation like this. + pub vip_path: [[::c_char; 32]; 32], + } + + pub struct proc_vnodepathinfo { + pub pvi_cdir: vnode_info_path, + pub pvi_rdir: vnode_info_path, + } + + pub struct vm_statistics { + pub free_count: natural_t, + pub active_count: natural_t, + pub inactive_count: natural_t, + pub wire_count: natural_t, + pub zero_fill_count: natural_t, + pub reactivations: natural_t, + pub pageins: natural_t, + pub pageouts: natural_t, + pub faults: natural_t, + pub cow_faults: natural_t, + pub lookups: natural_t, + pub hits: natural_t, + pub purgeable_count: natural_t, + pub purges: natural_t, + pub speculative_count: natural_t, + } + + pub struct task_thread_times_info { + pub user_time: time_value_t, + pub system_time: time_value_t, + } + + pub struct rusage_info_v0 { + pub ri_uuid: [u8; 16], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + } + + pub struct rusage_info_v1 { + pub ri_uuid: [u8; 16], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + } + + pub struct rusage_info_v2 { + pub ri_uuid: [u8; 16], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, + } + + pub struct rusage_info_v3 { + pub ri_uuid: [u8; 16], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, + pub ri_cpu_time_qos_default: u64, + pub ri_cpu_time_qos_maintenance: u64, + pub ri_cpu_time_qos_background: u64, + pub ri_cpu_time_qos_utility: u64, + pub ri_cpu_time_qos_legacy: u64, + pub ri_cpu_time_qos_user_initiated: u64, + pub ri_cpu_time_qos_user_interactive: u64, + pub ri_billed_system_time: u64, + pub ri_serviced_system_time: u64, + } + + pub struct rusage_info_v4 { + pub ri_uuid: [u8; 16], + pub ri_user_time: u64, + pub ri_system_time: u64, + pub ri_pkg_idle_wkups: u64, + pub ri_interrupt_wkups: u64, + pub ri_pageins: u64, + pub ri_wired_size: u64, + pub ri_resident_size: u64, + pub ri_phys_footprint: u64, + pub ri_proc_start_abstime: u64, + pub ri_proc_exit_abstime: u64, + pub ri_child_user_time: u64, + pub ri_child_system_time: u64, + pub ri_child_pkg_idle_wkups: u64, + pub ri_child_interrupt_wkups: u64, + pub ri_child_pageins: u64, + pub ri_child_elapsed_abstime: u64, + pub ri_diskio_bytesread: u64, + pub ri_diskio_byteswritten: u64, + pub ri_cpu_time_qos_default: u64, + pub ri_cpu_time_qos_maintenance: u64, + pub ri_cpu_time_qos_background: u64, + pub ri_cpu_time_qos_utility: u64, + pub ri_cpu_time_qos_legacy: u64, + pub ri_cpu_time_qos_user_initiated: u64, + pub ri_cpu_time_qos_user_interactive: u64, + pub ri_billed_system_time: u64, + pub ri_serviced_system_time: u64, + pub ri_logical_writes: u64, + pub ri_lifetime_max_phys_footprint: u64, + pub ri_instructions: u64, + pub ri_cycles: u64, + pub ri_billed_energy: u64, + pub ri_serviced_energy: u64, + pub ri_interval_max_phys_footprint: u64, + pub ri_runnable_time: u64, + } + + pub struct image_offset { + pub uuid: ::uuid_t, + pub offset: u32, + } + + pub struct attrlist { + pub bitmapcount: ::c_ushort, + pub reserved: u16, + pub commonattr: attrgroup_t, + pub volattr: attrgroup_t, + pub dirattr: attrgroup_t, + pub fileattr: attrgroup_t, + pub forkattr: attrgroup_t, + } + + pub struct attrreference_t { + pub attr_dataoffset: i32, + pub attr_length: u32, + } + + pub struct vol_capabilities_attr_t { + pub capabilities: vol_capabilities_set_t, + pub valid: vol_capabilities_set_t, + } + + pub struct attribute_set_t { + pub commonattr: attrgroup_t, + pub volattr: attrgroup_t, + pub dirattr: attrgroup_t, + pub fileattr: attrgroup_t, + pub forkattr: attrgroup_t, + } + + pub struct vol_attributes_attr_t { + pub validattr: attribute_set_t, + pub nativeattr: attribute_set_t, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct ifconf { + pub ifc_len: ::c_int, + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ifreq, + } + + #[cfg_attr(libc_align, repr(align(8)))] + pub struct tcp_connection_info { + pub tcpi_state: u8, + pub tcpi_snd_wscale: u8, + pub tcpi_rcv_wscale: u8, + __pad1: u8, + pub tcpi_options: u32, + pub tcpi_flags: u32, + pub tcpi_rto: u32, + pub tcpi_maxseg: u32, + pub tcpi_snd_ssthresh: u32, + pub tcpi_snd_cwnd: u32, + pub tcpi_snd_wnd: u32, + pub tcpi_snd_sbbytes: u32, + pub tcpi_rcv_wnd: u32, + pub tcpi_rttcur: u32, + pub tcpi_srtt: u32, + pub tcpi_rttvar: u32, + pub tcpi_tfo_cookie_req: u32, + pub tcpi_tfo_cookie_rcv: u32, + pub tcpi_tfo_syn_loss: u32, + pub tcpi_tfo_syn_data_sent: u32, + pub tcpi_tfo_syn_data_acked: u32, + pub tcpi_tfo_syn_data_rcv: u32, + pub tcpi_tfo_cookie_req_rcv: u32, + pub tcpi_tfo_cookie_sent: u32, + pub tcpi_tfo_cookie_invalid: u32, + pub tcpi_tfo_cookie_wrong: u32, + pub tcpi_tfo_no_cookie_rcv: u32, + pub tcpi_tfo_heuristics_disable: u32, + pub tcpi_tfo_send_blackhole: u32, + pub tcpi_tfo_recv_blackhole: u32, + pub tcpi_tfo_onebyte_proxy: u32, + __pad2: u32, + pub tcpi_txpackets: u64, + pub tcpi_txbytes: u64, + pub tcpi_txretransmitbytes: u64, + pub tcpi_rxpackets: u64, + pub tcpi_rxbytes: u64, + pub tcpi_rxoutoforderbytes: u64, + pub tcpi_rxretransmitpackets: u64, + } +} + +s_no_extra_traits! { + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: i16, + pub flags: u16, + pub fflags: u32, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct semid_ds { + // Note the manpage shows different types than the system header. + pub sem_perm: ipc_perm, + pub sem_base: i32, + pub sem_nsems: ::c_ushort, + pub sem_otime: ::time_t, + pub sem_pad1: i32, + pub sem_ctime: ::time_t, + pub sem_pad2: i32, + pub sem_pad3: [i32; 4], + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct shmid_ds { + pub shm_perm: ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, // FIXME: 64-bit wrong align => wrong offset + pub shm_dtime: ::time_t, // FIXME: 64-bit wrong align => wrong offset + pub shm_ctime: ::time_t, // FIXME: 64-bit wrong align => wrong offset + // FIXME: 64-bit wrong align => wrong offset: + pub shm_internal: *mut ::c_void, + } + + pub struct proc_threadinfo { + pub pth_user_time: u64, + pub pth_system_time: u64, + pub pth_cpu_usage: i32, + pub pth_policy: i32, + pub pth_run_state: i32, + pub pth_flags: i32, + pub pth_sleep_time: i32, + pub pth_curpri: i32, + pub pth_priority: i32, + pub pth_maxpriority: i32, + pub pth_name: [::c_char; MAXTHREADNAMESIZE], + } + + pub struct statfs { + pub f_bsize: u32, + pub f_iosize: i32, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_owner: ::uid_t, + pub f_type: u32, + pub f_flags: u32, + pub f_fssubtype: u32, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], + pub f_flags_ext: u32, + pub f_reserved: [u32; 7], + } + + pub struct dirent { + pub d_ino: u64, + pub d_seekoff: u64, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [::c_char; 1024], + } + + pub struct pthread_rwlock_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_RWLOCK_SIZE__], + } + + pub struct pthread_mutex_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_MUTEX_SIZE__], + } + + pub struct pthread_cond_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_COND_SIZE__], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } + + pub struct utmpx { + pub ut_user: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_host: [::c_char; _UTX_HOSTSIZE], + ut_pad: [u32; 16], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + __unused1: *mut ::c_void, //actually a function pointer + pub sigev_notify_attributes: *mut ::pthread_attr_t + } + + pub struct processor_cpu_load_info { + pub cpu_ticks: [::c_uint; CPU_STATE_MAX as usize], + } + + pub struct processor_basic_info { + pub cpu_type: cpu_type_t, + pub cpu_subtype: cpu_subtype_t, + pub running: ::boolean_t, + pub slot_num: ::c_int, + pub is_master: ::boolean_t, + } + + pub struct processor_set_basic_info { + pub processor_count: ::c_int, + pub default_policy: ::c_int, + } + + pub struct processor_set_load_info { + pub task_count: ::c_int, + pub thread_count: ::c_int, + pub load_average: integer_t, + pub mach_factor: integer_t, + } + + pub struct time_value_t { + pub seconds: integer_t, + pub microseconds: integer_t, + } + + pub struct thread_basic_info { + pub user_time: time_value_t, + pub system_time: time_value_t, + pub cpu_usage: ::integer_t, + pub policy: ::policy_t, + pub run_state: ::integer_t, + pub flags: ::integer_t, + pub suspend_count: ::integer_t, + pub sleep_time: ::integer_t, + } + + pub struct thread_identifier_info { + pub thread_id: u64, + pub thread_handle: u64, + pub dispatch_qaddr: u64, + } + + pub struct thread_extended_info { + pub pth_user_time: u64, + pub pth_system_time: u64, + pub pth_cpu_usage: i32, + pub pth_policy: i32, + pub pth_run_state: i32, + pub pth_flags: i32, + pub pth_sleep_time: i32, + pub pth_curpri: i32, + pub pth_priority: i32, + pub pth_maxpriority: i32, + pub pth_name: [::c_char; MAXTHREADNAMESIZE], + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct if_data64 { + pub ifi_type: ::c_uchar, + pub ifi_typelen: ::c_uchar, + pub ifi_physical: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_recvquota: ::c_uchar, + pub ifi_xmitquota: ::c_uchar, + pub ifi_unused1: ::c_uchar, + pub ifi_mtu: u32, + pub ifi_metric: u32, + pub ifi_baudrate: u64, + pub ifi_ipackets: u64, + pub ifi_ierrors: u64, + pub ifi_opackets: u64, + pub ifi_oerrors: u64, + pub ifi_collisions: u64, + pub ifi_ibytes: u64, + pub ifi_obytes: u64, + pub ifi_imcasts: u64, + pub ifi_omcasts: u64, + pub ifi_iqdrops: u64, + pub ifi_noproto: u64, + pub ifi_recvtiming: u32, + pub ifi_xmittiming: u32, + #[cfg(target_pointer_width = "32")] + pub ifi_lastchange: ::timeval, + #[cfg(not(target_pointer_width = "32"))] + pub ifi_lastchange: timeval32, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct if_msghdr2 { + pub ifm_msglen: ::c_ushort, + pub ifm_version: ::c_uchar, + pub ifm_type: ::c_uchar, + pub ifm_addrs: ::c_int, + pub ifm_flags: ::c_int, + pub ifm_index: ::c_ushort, + pub ifm_snd_len: ::c_int, + pub ifm_snd_maxlen: ::c_int, + pub ifm_snd_drops: ::c_int, + pub ifm_timer: ::c_int, + pub ifm_data: if_data64, + } + + #[cfg_attr(libc_packedN, repr(packed(8)))] + pub struct vm_statistics64 { + pub free_count: natural_t, + pub active_count: natural_t, + pub inactive_count: natural_t, + pub wire_count: natural_t, + pub zero_fill_count: u64, + pub reactivations: u64, + pub pageins: u64, + pub pageouts: u64, + pub faults: u64, + pub cow_faults: u64, + pub lookups: u64, + pub hits: u64, + pub purges: u64, + pub purgeable_count: natural_t, + pub speculative_count: natural_t, + pub decompressions: u64, + pub compressions: u64, + pub swapins: u64, + pub swapouts: u64, + pub compressor_page_count: natural_t, + pub throttled_count: natural_t, + pub external_page_count: natural_t, + pub internal_page_count: natural_t, + pub total_uncompressed_pages_in_compressor: u64, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct mach_task_basic_info { + pub virtual_size: mach_vm_size_t, + pub resident_size: mach_vm_size_t, + pub resident_size_max: mach_vm_size_t, + pub user_time: time_value_t, + pub system_time: time_value_t, + pub policy: ::policy_t, + pub suspend_count: integer_t, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct log2phys { + pub l2p_flags: ::c_uint, + pub l2p_contigbytes: ::off_t, + pub l2p_devoffset: ::off_t, + } + + pub struct os_unfair_lock_s { + _os_unfair_lock_opaque: u32, + } + + #[cfg_attr(libc_packedN, repr(packed(1)))] + pub struct sockaddr_vm { + pub svm_len: ::c_uchar, + pub svm_family: ::sa_family_t, + pub svm_reserved1: ::c_ushort, + pub svm_port: ::c_uint, + pub svm_cid: ::c_uint, + } + + pub struct ifdevmtu { + pub ifdm_current: ::c_int, + pub ifdm_min: ::c_int, + pub ifdm_max: ::c_int, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifk_data { + pub ifk_ptr: *mut ::c_void, + pub ifk_value: ::c_int, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct ifkpi { + pub ifk_module_id: ::c_uint, + pub ifk_type: ::c_uint, + #[cfg(libc_union)] + pub ifk_data: __c_anonymous_ifk_data, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_flags: ::c_short, + pub ifru_metrics: ::c_int, + pub ifru_mtu: ::c_int, + pub ifru_phys: ::c_int, + pub ifru_media: ::c_int, + pub ifru_intval: ::c_int, + pub ifru_data: *mut ::c_char, + pub ifru_devmtu: ifdevmtu, + pub ifru_kpi: ifkpi, + pub ifru_wake_flags: u32, + pub ifru_route_refcnt: u32, + pub ifru_cap: [::c_int; 2], + pub ifru_functional_type: u32, + } + + pub struct ifreq { + pub ifr_name: [::c_char; ::IFNAMSIZ], + #[cfg(libc_union)] + pub ifr_ifru: __c_anonymous_ifr_ifru, + #[cfg(not(libc_union))] + pub ifr_ifru: ::sockaddr, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut ::c_char, + pub ifcu_req: *mut ifreq, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_pid: ::pid_t, + _si_uid: ::uid_t, + _si_status: ::c_int, + _si_addr: *mut ::c_void, + si_value: ::sigval, + } + + (*(self as *const siginfo_t as *const siginfo_timer)).si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.si_status + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub union semun { + pub val: ::c_int, + pub buf: *mut semid_ds, + pub array: *mut ::c_ushort, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for semun { + fn eq(&self, other: &semun) -> bool { + unsafe { self.val == other.val } + } + } + impl Eq for semun {} + impl ::fmt::Debug for semun { + fn fmt(&self, f: &mut ::fmt::Formatter) + -> ::fmt::Result { + f.debug_struct("semun") + .field("val", unsafe { &self.val }) + .finish() + } + } + impl ::hash::Hash for semun { + fn hash(&self, state: &mut H) { + unsafe { self.val.hash(state) }; + } + } + } + } + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for kevent { + fn eq(&self, other: &kevent) -> bool { + self.ident == other.ident + && self.filter == other.filter + && self.flags == other.flags + && self.fflags == other.fflags + && self.data == other.data + && self.udata == other.udata + } + } + impl Eq for kevent {} + impl ::fmt::Debug for kevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ident = self.ident; + let filter = self.filter; + let flags = self.flags; + let fflags = self.fflags; + let data = self.data; + let udata = self.udata; + f.debug_struct("kevent") + .field("ident", &ident) + .field("filter", &filter) + .field("flags", &flags) + .field("fflags", &fflags) + .field("data", &data) + .field("udata", &udata) + .finish() + } + } + impl ::hash::Hash for kevent { + fn hash(&self, state: &mut H) { + let ident = self.ident; + let filter = self.filter; + let flags = self.flags; + let fflags = self.fflags; + let data = self.data; + let udata = self.udata; + ident.hash(state); + filter.hash(state); + flags.hash(state); + fflags.hash(state); + data.hash(state); + udata.hash(state); + } + } + + impl PartialEq for semid_ds { + fn eq(&self, other: &semid_ds) -> bool { + let sem_perm = self.sem_perm; + let sem_pad3 = self.sem_pad3; + let other_sem_perm = other.sem_perm; + let other_sem_pad3 = other.sem_pad3; + sem_perm == other_sem_perm + && self.sem_base == other.sem_base + && self.sem_nsems == other.sem_nsems + && self.sem_otime == other.sem_otime + && self.sem_pad1 == other.sem_pad1 + && self.sem_ctime == other.sem_ctime + && self.sem_pad2 == other.sem_pad2 + && sem_pad3 == other_sem_pad3 + } + } + impl Eq for semid_ds {} + impl ::fmt::Debug for semid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let sem_perm = self.sem_perm; + let sem_base = self.sem_base; + let sem_nsems = self.sem_nsems; + let sem_otime = self.sem_otime; + let sem_pad1 = self.sem_pad1; + let sem_ctime = self.sem_ctime; + let sem_pad2 = self.sem_pad2; + let sem_pad3 = self.sem_pad3; + f.debug_struct("semid_ds") + .field("sem_perm", &sem_perm) + .field("sem_base", &sem_base) + .field("sem_nsems", &sem_nsems) + .field("sem_otime", &sem_otime) + .field("sem_pad1", &sem_pad1) + .field("sem_ctime", &sem_ctime) + .field("sem_pad2", &sem_pad2) + .field("sem_pad3", &sem_pad3) + .finish() + } + } + impl ::hash::Hash for semid_ds { + fn hash(&self, state: &mut H) { + let sem_perm = self.sem_perm; + let sem_base = self.sem_base; + let sem_nsems = self.sem_nsems; + let sem_otime = self.sem_otime; + let sem_pad1 = self.sem_pad1; + let sem_ctime = self.sem_ctime; + let sem_pad2 = self.sem_pad2; + let sem_pad3 = self.sem_pad3; + sem_perm.hash(state); + sem_base.hash(state); + sem_nsems.hash(state); + sem_otime.hash(state); + sem_pad1.hash(state); + sem_ctime.hash(state); + sem_pad2.hash(state); + sem_pad3.hash(state); + } + } + + impl PartialEq for shmid_ds { + fn eq(&self, other: &shmid_ds) -> bool { + let shm_perm = self.shm_perm; + let other_shm_perm = other.shm_perm; + shm_perm == other_shm_perm + && self.shm_segsz == other.shm_segsz + && self.shm_lpid == other.shm_lpid + && self.shm_cpid == other.shm_cpid + && self.shm_nattch == other.shm_nattch + && self.shm_atime == other.shm_atime + && self.shm_dtime == other.shm_dtime + && self.shm_ctime == other.shm_ctime + && self.shm_internal == other.shm_internal + } + } + impl Eq for shmid_ds {} + impl ::fmt::Debug for shmid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let shm_perm = self.shm_perm; + let shm_segsz = self.shm_segsz; + let shm_lpid = self.shm_lpid; + let shm_cpid = self.shm_cpid; + let shm_nattch = self.shm_nattch; + let shm_atime = self.shm_atime; + let shm_dtime = self.shm_dtime; + let shm_ctime = self.shm_ctime; + let shm_internal = self.shm_internal; + f.debug_struct("shmid_ds") + .field("shm_perm", &shm_perm) + .field("shm_segsz", &shm_segsz) + .field("shm_lpid", &shm_lpid) + .field("shm_cpid", &shm_cpid) + .field("shm_nattch", &shm_nattch) + .field("shm_atime", &shm_atime) + .field("shm_dtime", &shm_dtime) + .field("shm_ctime", &shm_ctime) + .field("shm_internal", &shm_internal) + .finish() + } + } + impl ::hash::Hash for shmid_ds { + fn hash(&self, state: &mut H) { + let shm_perm = self.shm_perm; + let shm_segsz = self.shm_segsz; + let shm_lpid = self.shm_lpid; + let shm_cpid = self.shm_cpid; + let shm_nattch = self.shm_nattch; + let shm_atime = self.shm_atime; + let shm_dtime = self.shm_dtime; + let shm_ctime = self.shm_ctime; + let shm_internal = self.shm_internal; + shm_perm.hash(state); + shm_segsz.hash(state); + shm_lpid.hash(state); + shm_cpid.hash(state); + shm_nattch.hash(state); + shm_atime.hash(state); + shm_dtime.hash(state); + shm_ctime.hash(state); + shm_internal.hash(state); + } + } + + impl PartialEq for proc_threadinfo { + fn eq(&self, other: &proc_threadinfo) -> bool { + self.pth_user_time == other.pth_user_time + && self.pth_system_time == other.pth_system_time + && self.pth_cpu_usage == other.pth_cpu_usage + && self.pth_policy == other.pth_policy + && self.pth_run_state == other.pth_run_state + && self.pth_flags == other.pth_flags + && self.pth_sleep_time == other.pth_sleep_time + && self.pth_curpri == other.pth_curpri + && self.pth_priority == other.pth_priority + && self.pth_maxpriority == other.pth_maxpriority + && self.pth_name + .iter() + .zip(other.pth_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for proc_threadinfo {} + impl ::fmt::Debug for proc_threadinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("proc_threadinfo") + .field("pth_user_time", &self.pth_user_time) + .field("pth_system_time", &self.pth_system_time) + .field("pth_cpu_usage", &self.pth_cpu_usage) + .field("pth_policy", &self.pth_policy) + .field("pth_run_state", &self.pth_run_state) + .field("pth_flags", &self.pth_flags) + .field("pth_sleep_time", &self.pth_sleep_time) + .field("pth_curpri", &self.pth_curpri) + .field("pth_priority", &self.pth_priority) + .field("pth_maxpriority", &self.pth_maxpriority) + // FIXME: .field("pth_name", &self.pth_name) + .finish() + } + } + impl ::hash::Hash for proc_threadinfo { + fn hash(&self, state: &mut H) { + self.pth_user_time.hash(state); + self.pth_system_time.hash(state); + self.pth_cpu_usage.hash(state); + self.pth_policy.hash(state); + self.pth_run_state.hash(state); + self.pth_flags.hash(state); + self.pth_sleep_time.hash(state); + self.pth_curpri.hash(state); + self.pth_priority.hash(state); + self.pth_maxpriority.hash(state); + self.pth_name.hash(state); + } + } + + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_fsid == other.f_fsid + && self.f_owner == other.f_owner + && self.f_flags == other.f_flags + && self.f_fssubtype == other.f_fssubtype + && self.f_fstypename == other.f_fstypename + && self.f_type == other.f_type + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self.f_reserved == other.f_reserved + } + } + + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_fsid", &self.f_fsid) + .field("f_owner", &self.f_owner) + .field("f_flags", &self.f_flags) + .field("f_fssubtype", &self.f_fssubtype) + .field("f_fstypename", &self.f_fstypename) + .field("f_type", &self.f_type) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .field("f_reserved", &self.f_reserved) + .finish() + } + } + + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_fsid.hash(state); + self.f_owner.hash(state); + self.f_flags.hash(state); + self.f_fssubtype.hash(state); + self.f_fstypename.hash(state); + self.f_type.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + self.f_reserved.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_seekoff == other.d_seekoff + && self.d_reclen == other.d_reclen + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_seekoff", &self.d_seekoff) + .field("d_reclen", &self.d_reclen) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_seekoff.hash(state); + self.d_reclen.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self + .__ss_pad1 + .iter() + .zip(other.__ss_pad1.iter()) + .all(|(a, b)| a == b) + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_user + .iter() + .zip(other.ut_user.iter()) + .all(|(a,b)| a == b) + && self.ut_id == other.ut_id + && self.ut_line == other.ut_line + && self.ut_pid == other.ut_pid + && self.ut_type == other.ut_type + && self.ut_tv == other.ut_tv + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_pad == other.ut_pad + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + // FIXME: .field("ut_user", &self.ut_user) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + .field("ut_pid", &self.ut_pid) + .field("ut_type", &self.ut_type) + .field("ut_tv", &self.ut_tv) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_pad", &self.ut_pad) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_user.hash(state); + self.ut_id.hash(state); + self.ut_line.hash(state); + self.ut_pid.hash(state); + self.ut_type.hash(state); + self.ut_tv.hash(state); + self.ut_host.hash(state); + self.ut_pad.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + + impl Eq for sigevent {} + + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .finish() + } + } + + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + + impl PartialEq for processor_cpu_load_info { + fn eq(&self, other: &processor_cpu_load_info) -> bool { + self.cpu_ticks == other.cpu_ticks + } + } + impl Eq for processor_cpu_load_info {} + impl ::fmt::Debug for processor_cpu_load_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_cpu_load_info") + .field("cpu_ticks", &self.cpu_ticks) + .finish() + } + } + impl ::hash::Hash for processor_cpu_load_info { + fn hash(&self, state: &mut H) { + self.cpu_ticks.hash(state); + } + } + + impl PartialEq for processor_basic_info { + fn eq(&self, other: &processor_basic_info) -> bool { + self.cpu_type == other.cpu_type + && self.cpu_subtype == other.cpu_subtype + && self.running == other.running + && self.slot_num == other.slot_num + && self.is_master == other.is_master + } + } + impl Eq for processor_basic_info {} + impl ::fmt::Debug for processor_basic_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_basic_info") + .field("cpu_type", &self.cpu_type) + .field("cpu_subtype", &self.cpu_subtype) + .field("running", &self.running) + .field("slot_num", &self.slot_num) + .field("is_master", &self.is_master) + .finish() + } + } + impl ::hash::Hash for processor_basic_info { + fn hash(&self, state: &mut H) { + self.cpu_type.hash(state); + self.cpu_subtype.hash(state); + self.running.hash(state); + self.slot_num.hash(state); + self.is_master.hash(state); + } + } + + impl PartialEq for processor_set_basic_info { + fn eq(&self, other: &processor_set_basic_info) -> bool { + self.processor_count == other.processor_count + && self.default_policy == other.default_policy + } + } + impl Eq for processor_set_basic_info {} + impl ::fmt::Debug for processor_set_basic_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_set_basic_info") + .field("processor_count", &self.processor_count) + .field("default_policy", &self.default_policy) + .finish() + } + } + impl ::hash::Hash for processor_set_basic_info { + fn hash(&self, state: &mut H) { + self.processor_count.hash(state); + self.default_policy.hash(state); + } + } + + impl PartialEq for processor_set_load_info { + fn eq(&self, other: &processor_set_load_info) -> bool { + self.task_count == other.task_count + && self.thread_count == other.thread_count + && self.load_average == other.load_average + && self.mach_factor == other.mach_factor + } + } + impl Eq for processor_set_load_info {} + impl ::fmt::Debug for processor_set_load_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_set_load_info") + .field("task_count", &self.task_count) + .field("thread_count", &self.thread_count) + .field("load_average", &self.load_average) + .field("mach_factor", &self.mach_factor) + .finish() + } + } + impl ::hash::Hash for processor_set_load_info { + fn hash(&self, state: &mut H) { + self.task_count.hash(state); + self.thread_count.hash(state); + self.load_average.hash(state); + self.mach_factor.hash(state); + } + } + + impl PartialEq for time_value_t { + fn eq(&self, other: &time_value_t) -> bool { + self.seconds == other.seconds + && self.microseconds == other.microseconds + } + } + impl Eq for time_value_t {} + impl ::fmt::Debug for time_value_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("time_value_t") + .field("seconds", &self.seconds) + .field("microseconds", &self.microseconds) + .finish() + } + } + impl ::hash::Hash for time_value_t { + fn hash(&self, state: &mut H) { + self.seconds.hash(state); + self.microseconds.hash(state); + } + } + impl PartialEq for thread_basic_info { + fn eq(&self, other: &thread_basic_info) -> bool { + self.user_time == other.user_time + && self.system_time == other.system_time + && self.cpu_usage == other.cpu_usage + && self.policy == other.policy + && self.run_state == other.run_state + && self.flags == other.flags + && self.suspend_count == other.suspend_count + && self.sleep_time == other.sleep_time + } + } + impl Eq for thread_basic_info {} + impl ::fmt::Debug for thread_basic_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("thread_basic_info") + .field("user_time", &self.user_time) + .field("system_time", &self.system_time) + .field("cpu_usage", &self.cpu_usage) + .field("policy", &self.policy) + .field("run_state", &self.run_state) + .field("flags", &self.flags) + .field("suspend_count", &self.suspend_count) + .field("sleep_time", &self.sleep_time) + .finish() + } + } + impl ::hash::Hash for thread_basic_info { + fn hash(&self, state: &mut H) { + self.user_time.hash(state); + self.system_time.hash(state); + self.cpu_usage.hash(state); + self.policy.hash(state); + self.run_state.hash(state); + self.flags.hash(state); + self.suspend_count.hash(state); + self.sleep_time.hash(state); + } + } + impl PartialEq for thread_extended_info { + fn eq(&self, other: &thread_extended_info) -> bool { + self.pth_user_time == other.pth_user_time + && self.pth_system_time == other.pth_system_time + && self.pth_cpu_usage == other.pth_cpu_usage + && self.pth_policy == other.pth_policy + && self.pth_run_state == other.pth_run_state + && self.pth_flags == other.pth_flags + && self.pth_sleep_time == other.pth_sleep_time + && self.pth_curpri == other.pth_curpri + && self.pth_priority == other.pth_priority + && self.pth_maxpriority == other.pth_maxpriority + && self.pth_name + .iter() + .zip(other.pth_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for thread_extended_info {} + impl ::fmt::Debug for thread_extended_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("proc_threadinfo") + .field("pth_user_time", &self.pth_user_time) + .field("pth_system_time", &self.pth_system_time) + .field("pth_cpu_usage", &self.pth_cpu_usage) + .field("pth_policy", &self.pth_policy) + .field("pth_run_state", &self.pth_run_state) + .field("pth_flags", &self.pth_flags) + .field("pth_sleep_time", &self.pth_sleep_time) + .field("pth_curpri", &self.pth_curpri) + .field("pth_priority", &self.pth_priority) + .field("pth_maxpriority", &self.pth_maxpriority) + // FIXME: .field("pth_name", &self.pth_name) + .finish() + } + } + impl ::hash::Hash for thread_extended_info { + fn hash(&self, state: &mut H) { + self.pth_user_time.hash(state); + self.pth_system_time.hash(state); + self.pth_cpu_usage.hash(state); + self.pth_policy.hash(state); + self.pth_run_state.hash(state); + self.pth_flags.hash(state); + self.pth_sleep_time.hash(state); + self.pth_curpri.hash(state); + self.pth_priority.hash(state); + self.pth_maxpriority.hash(state); + self.pth_name.hash(state); + } + } + impl PartialEq for thread_identifier_info { + fn eq(&self, other: &thread_identifier_info) -> bool { + self.thread_id == other.thread_id + && self.thread_handle == other.thread_handle + && self.dispatch_qaddr == other.dispatch_qaddr + } + } + impl Eq for thread_identifier_info {} + impl ::fmt::Debug for thread_identifier_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("thread_identifier_info") + .field("thread_id", &self.thread_id) + .field("thread_handle", &self.thread_handle) + .field("dispatch_qaddr", &self.dispatch_qaddr) + .finish() + } + } + impl ::hash::Hash for thread_identifier_info { + fn hash(&self, state: &mut H) { + self.thread_id.hash(state); + self.thread_handle.hash(state); + self.dispatch_qaddr.hash(state); + } + } + impl PartialEq for if_data64 { + fn eq(&self, other: &if_data64) -> bool { + self.ifi_type == other.ifi_type && + self.ifi_typelen == other.ifi_typelen && + self.ifi_physical == other.ifi_physical && + self.ifi_addrlen == other.ifi_addrlen && + self.ifi_hdrlen == other.ifi_hdrlen && + self.ifi_recvquota == other.ifi_recvquota && + self.ifi_xmitquota == other.ifi_xmitquota && + self.ifi_unused1 == other.ifi_unused1 && + self.ifi_mtu == other.ifi_mtu && + self.ifi_metric == other.ifi_metric && + self.ifi_baudrate == other.ifi_baudrate && + self.ifi_ipackets == other.ifi_ipackets && + self.ifi_ierrors == other.ifi_ierrors && + self.ifi_opackets == other.ifi_opackets && + self.ifi_oerrors == other.ifi_oerrors && + self.ifi_collisions == other.ifi_collisions && + self.ifi_ibytes == other.ifi_ibytes && + self.ifi_obytes == other.ifi_obytes && + self.ifi_imcasts == other.ifi_imcasts && + self.ifi_omcasts == other.ifi_omcasts && + self.ifi_iqdrops == other.ifi_iqdrops && + self.ifi_noproto == other.ifi_noproto && + self.ifi_recvtiming == other.ifi_recvtiming && + self.ifi_xmittiming == other.ifi_xmittiming && + self.ifi_lastchange == other.ifi_lastchange + } + } + impl Eq for if_data64 {} + impl ::fmt::Debug for if_data64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ifi_type = self.ifi_type; + let ifi_typelen = self.ifi_typelen; + let ifi_physical = self.ifi_physical; + let ifi_addrlen = self.ifi_addrlen; + let ifi_hdrlen = self.ifi_hdrlen; + let ifi_recvquota = self.ifi_recvquota; + let ifi_xmitquota = self.ifi_xmitquota; + let ifi_unused1 = self.ifi_unused1; + let ifi_mtu = self.ifi_mtu; + let ifi_metric = self.ifi_metric; + let ifi_baudrate = self.ifi_baudrate; + let ifi_ipackets = self.ifi_ipackets; + let ifi_ierrors = self.ifi_ierrors; + let ifi_opackets = self.ifi_opackets; + let ifi_oerrors = self.ifi_oerrors; + let ifi_collisions = self.ifi_collisions; + let ifi_ibytes = self.ifi_ibytes; + let ifi_obytes = self.ifi_obytes; + let ifi_imcasts = self.ifi_imcasts; + let ifi_omcasts = self.ifi_omcasts; + let ifi_iqdrops = self.ifi_iqdrops; + let ifi_noproto = self.ifi_noproto; + let ifi_recvtiming = self.ifi_recvtiming; + let ifi_xmittiming = self.ifi_xmittiming; + let ifi_lastchange = self.ifi_lastchange; + f.debug_struct("if_data64") + .field("ifi_type", &ifi_type) + .field("ifi_typelen", &ifi_typelen) + .field("ifi_physical", &ifi_physical) + .field("ifi_addrlen", &ifi_addrlen) + .field("ifi_hdrlen", &ifi_hdrlen) + .field("ifi_recvquota", &ifi_recvquota) + .field("ifi_xmitquota", &ifi_xmitquota) + .field("ifi_unused1", &ifi_unused1) + .field("ifi_mtu", &ifi_mtu) + .field("ifi_metric", &ifi_metric) + .field("ifi_baudrate", &ifi_baudrate) + .field("ifi_ipackets", &ifi_ipackets) + .field("ifi_ierrors", &ifi_ierrors) + .field("ifi_opackets", &ifi_opackets) + .field("ifi_oerrors", &ifi_oerrors) + .field("ifi_collisions", &ifi_collisions) + .field("ifi_ibytes", &ifi_ibytes) + .field("ifi_obytes", &ifi_obytes) + .field("ifi_imcasts", &ifi_imcasts) + .field("ifi_omcasts", &ifi_omcasts) + .field("ifi_iqdrops", &ifi_iqdrops) + .field("ifi_noproto", &ifi_noproto) + .field("ifi_recvtiming", &ifi_recvtiming) + .field("ifi_xmittiming", &ifi_xmittiming) + .field("ifi_lastchange", &ifi_lastchange) + .finish() + } + } + impl ::hash::Hash for if_data64 { + fn hash(&self, state: &mut H) { + let ifi_type = self.ifi_type; + let ifi_typelen = self.ifi_typelen; + let ifi_physical = self.ifi_physical; + let ifi_addrlen = self.ifi_addrlen; + let ifi_hdrlen = self.ifi_hdrlen; + let ifi_recvquota = self.ifi_recvquota; + let ifi_xmitquota = self.ifi_xmitquota; + let ifi_unused1 = self.ifi_unused1; + let ifi_mtu = self.ifi_mtu; + let ifi_metric = self.ifi_metric; + let ifi_baudrate = self.ifi_baudrate; + let ifi_ipackets = self.ifi_ipackets; + let ifi_ierrors = self.ifi_ierrors; + let ifi_opackets = self.ifi_opackets; + let ifi_oerrors = self.ifi_oerrors; + let ifi_collisions = self.ifi_collisions; + let ifi_ibytes = self.ifi_ibytes; + let ifi_obytes = self.ifi_obytes; + let ifi_imcasts = self.ifi_imcasts; + let ifi_omcasts = self.ifi_omcasts; + let ifi_iqdrops = self.ifi_iqdrops; + let ifi_noproto = self.ifi_noproto; + let ifi_recvtiming = self.ifi_recvtiming; + let ifi_xmittiming = self.ifi_xmittiming; + let ifi_lastchange = self.ifi_lastchange; + ifi_type.hash(state); + ifi_typelen.hash(state); + ifi_physical.hash(state); + ifi_addrlen.hash(state); + ifi_hdrlen.hash(state); + ifi_recvquota.hash(state); + ifi_xmitquota.hash(state); + ifi_unused1.hash(state); + ifi_mtu.hash(state); + ifi_metric.hash(state); + ifi_baudrate.hash(state); + ifi_ipackets.hash(state); + ifi_ierrors.hash(state); + ifi_opackets.hash(state); + ifi_oerrors.hash(state); + ifi_collisions.hash(state); + ifi_ibytes.hash(state); + ifi_obytes.hash(state); + ifi_imcasts.hash(state); + ifi_omcasts.hash(state); + ifi_iqdrops.hash(state); + ifi_noproto.hash(state); + ifi_recvtiming.hash(state); + ifi_xmittiming.hash(state); + ifi_lastchange.hash(state); + } + } + impl PartialEq for if_msghdr2 { + fn eq(&self, other: &if_msghdr2) -> bool { + self.ifm_msglen == other.ifm_msglen && + self.ifm_version == other.ifm_version && + self.ifm_type == other.ifm_type && + self.ifm_addrs == other.ifm_addrs && + self.ifm_flags == other.ifm_flags && + self.ifm_index == other.ifm_index && + self.ifm_snd_len == other.ifm_snd_len && + self.ifm_snd_maxlen == other.ifm_snd_maxlen && + self.ifm_snd_drops == other.ifm_snd_drops && + self.ifm_timer == other.ifm_timer && + self.ifm_data == other.ifm_data + } + } + impl Eq for if_msghdr2 {} + impl ::fmt::Debug for if_msghdr2 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ifm_msglen = self.ifm_msglen; + let ifm_version = self.ifm_version; + let ifm_type = self.ifm_type; + let ifm_addrs = self.ifm_addrs; + let ifm_flags = self.ifm_flags; + let ifm_index = self.ifm_index; + let ifm_snd_len = self.ifm_snd_len; + let ifm_snd_maxlen = self.ifm_snd_maxlen; + let ifm_snd_drops = self.ifm_snd_drops; + let ifm_timer = self.ifm_timer; + let ifm_data = self.ifm_data; + f.debug_struct("if_msghdr2") + .field("ifm_msglen", &ifm_msglen) + .field("ifm_version", &ifm_version) + .field("ifm_type", &ifm_type) + .field("ifm_addrs", &ifm_addrs) + .field("ifm_flags", &ifm_flags) + .field("ifm_index", &ifm_index) + .field("ifm_snd_len", &ifm_snd_len) + .field("ifm_snd_maxlen", &ifm_snd_maxlen) + .field("ifm_snd_drops", &ifm_snd_drops) + .field("ifm_timer", &ifm_timer) + .field("ifm_data", &ifm_data) + .finish() + } + } + impl ::hash::Hash for if_msghdr2 { + fn hash(&self, state: &mut H) { + let ifm_msglen = self.ifm_msglen; + let ifm_version = self.ifm_version; + let ifm_type = self.ifm_type; + let ifm_addrs = self.ifm_addrs; + let ifm_flags = self.ifm_flags; + let ifm_index = self.ifm_index; + let ifm_snd_len = self.ifm_snd_len; + let ifm_snd_maxlen = self.ifm_snd_maxlen; + let ifm_snd_drops = self.ifm_snd_drops; + let ifm_timer = self.ifm_timer; + let ifm_data = self.ifm_data; + ifm_msglen.hash(state); + ifm_version.hash(state); + ifm_type.hash(state); + ifm_addrs.hash(state); + ifm_flags.hash(state); + ifm_index.hash(state); + ifm_snd_len.hash(state); + ifm_snd_maxlen.hash(state); + ifm_snd_drops.hash(state); + ifm_timer.hash(state); + ifm_data.hash(state); + } + } + impl PartialEq for vm_statistics64 { + fn eq(&self, other: &vm_statistics64) -> bool { + // Otherwise rustfmt crashes... + let total_uncompressed = self.total_uncompressed_pages_in_compressor; + self.free_count == other.free_count && + self.active_count == other.active_count && + self.inactive_count == other.inactive_count && + self.wire_count == other.wire_count && + self.zero_fill_count == other.zero_fill_count && + self.reactivations == other.reactivations && + self.pageins == other.pageins && + self.pageouts == other.pageouts && + self.faults == other.faults && + self.cow_faults == other.cow_faults && + self.lookups == other.lookups && + self.hits == other.hits && + self.purges == other.purges && + self.purgeable_count == other.purgeable_count && + self.speculative_count == other.speculative_count && + self.decompressions == other.decompressions && + self.compressions == other.compressions && + self.swapins == other.swapins && + self.swapouts == other.swapouts && + self.compressor_page_count == other.compressor_page_count && + self.throttled_count == other.throttled_count && + self.external_page_count == other.external_page_count && + self.internal_page_count == other.internal_page_count && + total_uncompressed == other.total_uncompressed_pages_in_compressor + } + } + impl Eq for vm_statistics64 {} + impl ::fmt::Debug for vm_statistics64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let free_count = self.free_count; + let active_count = self.active_count; + let inactive_count = self.inactive_count; + let wire_count = self.wire_count; + let zero_fill_count = self.zero_fill_count; + let reactivations = self.reactivations; + let pageins = self.pageins; + let pageouts = self.pageouts; + let faults = self.faults; + let cow_faults = self.cow_faults; + let lookups = self.lookups; + let hits = self.hits; + let purges = self.purges; + let purgeable_count = self.purgeable_count; + let speculative_count = self.speculative_count; + let decompressions = self.decompressions; + let compressions = self.compressions; + let swapins = self.swapins; + let swapouts = self.swapouts; + let compressor_page_count = self.compressor_page_count; + let throttled_count = self.throttled_count; + let external_page_count = self.external_page_count; + let internal_page_count = self.internal_page_count; + // Otherwise rustfmt crashes... + let total_uncompressed = self.total_uncompressed_pages_in_compressor; + f.debug_struct("vm_statistics64") + .field("free_count", &free_count) + .field("active_count", &active_count) + .field("inactive_count", &inactive_count) + .field("wire_count", &wire_count) + .field("zero_fill_count", &zero_fill_count) + .field("reactivations", &reactivations) + .field("pageins", &pageins) + .field("pageouts", &pageouts) + .field("faults", &faults) + .field("cow_faults", &cow_faults) + .field("lookups", &lookups) + .field("hits", &hits) + .field("purges", &purges) + .field("purgeable_count", &purgeable_count) + .field("speculative_count", &speculative_count) + .field("decompressions", &decompressions) + .field("compressions", &compressions) + .field("swapins", &swapins) + .field("swapouts", &swapouts) + .field("compressor_page_count", &compressor_page_count) + .field("throttled_count", &throttled_count) + .field("external_page_count", &external_page_count) + .field("internal_page_count", &internal_page_count) + .field("total_uncompressed_pages_in_compressor", &total_uncompressed) + .finish() + } + } + impl ::hash::Hash for vm_statistics64 { + fn hash(&self, state: &mut H) { + let free_count = self.free_count; + let active_count = self.active_count; + let inactive_count = self.inactive_count; + let wire_count = self.wire_count; + let zero_fill_count = self.zero_fill_count; + let reactivations = self.reactivations; + let pageins = self.pageins; + let pageouts = self.pageouts; + let faults = self.faults; + let cow_faults = self.cow_faults; + let lookups = self.lookups; + let hits = self.hits; + let purges = self.purges; + let purgeable_count = self.purgeable_count; + let speculative_count = self.speculative_count; + let decompressions = self.decompressions; + let compressions = self.compressions; + let swapins = self.swapins; + let swapouts = self.swapouts; + let compressor_page_count = self.compressor_page_count; + let throttled_count = self.throttled_count; + let external_page_count = self.external_page_count; + let internal_page_count = self.internal_page_count; + // Otherwise rustfmt crashes... + let total_uncompressed = self.total_uncompressed_pages_in_compressor; + free_count.hash(state); + active_count.hash(state); + inactive_count.hash(state); + wire_count.hash(state); + zero_fill_count.hash(state); + reactivations.hash(state); + pageins.hash(state); + pageouts.hash(state); + faults.hash(state); + cow_faults.hash(state); + lookups.hash(state); + hits.hash(state); + purges.hash(state); + purgeable_count.hash(state); + speculative_count.hash(state); + decompressions.hash(state); + compressions.hash(state); + swapins.hash(state); + swapouts.hash(state); + compressor_page_count.hash(state); + throttled_count.hash(state); + external_page_count.hash(state); + internal_page_count.hash(state); + total_uncompressed.hash(state); + } + } + + impl PartialEq for mach_task_basic_info { + fn eq(&self, other: &mach_task_basic_info) -> bool { + self.virtual_size == other.virtual_size + && self.resident_size == other.resident_size + && self.resident_size_max == other.resident_size_max + && self.user_time == other.user_time + && self.system_time == other.system_time + && self.policy == other.policy + && self.suspend_count == other.suspend_count + } + } + impl Eq for mach_task_basic_info {} + impl ::fmt::Debug for mach_task_basic_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let virtual_size = self.virtual_size; + let resident_size = self.resident_size; + let resident_size_max = self.resident_size_max; + let user_time = self.user_time; + let system_time = self.system_time; + let policy = self.policy; + let suspend_count = self.suspend_count; + f.debug_struct("mach_task_basic_info") + .field("virtual_size", &virtual_size) + .field("resident_size", &resident_size) + .field("resident_size_max", &resident_size_max) + .field("user_time", &user_time) + .field("system_time", &system_time) + .field("policy", &policy) + .field("suspend_count", &suspend_count) + .finish() + } + } + impl ::hash::Hash for mach_task_basic_info { + fn hash(&self, state: &mut H) { + let virtual_size = self.virtual_size; + let resident_size = self.resident_size; + let resident_size_max = self.resident_size_max; + let user_time = self.user_time; + let system_time = self.system_time; + let policy = self.policy; + let suspend_count = self.suspend_count; + virtual_size.hash(state); + resident_size.hash(state); + resident_size_max.hash(state); + user_time.hash(state); + system_time.hash(state); + policy.hash(state); + suspend_count.hash(state); + } + } + + impl PartialEq for log2phys { + fn eq(&self, other: &log2phys) -> bool { + self.l2p_flags == other.l2p_flags + && self.l2p_contigbytes == other.l2p_contigbytes + && self.l2p_devoffset == other.l2p_devoffset + } + } + impl Eq for log2phys {} + impl ::fmt::Debug for log2phys { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let l2p_flags = self.l2p_flags; + let l2p_contigbytes = self.l2p_contigbytes; + let l2p_devoffset = self.l2p_devoffset; + f.debug_struct("log2phys") + .field("l2p_flags", &l2p_flags) + .field("l2p_contigbytes", &l2p_contigbytes) + .field("l2p_devoffset", &l2p_devoffset) + .finish() + } + } + impl ::hash::Hash for log2phys { + fn hash(&self, state: &mut H) { + let l2p_flags = self.l2p_flags; + let l2p_contigbytes = self.l2p_contigbytes; + let l2p_devoffset = self.l2p_devoffset; + l2p_flags.hash(state); + l2p_contigbytes.hash(state); + l2p_devoffset.hash(state); + } + } + impl PartialEq for os_unfair_lock { + fn eq(&self, other: &os_unfair_lock) -> bool { + self._os_unfair_lock_opaque == other._os_unfair_lock_opaque + } + } + + impl Eq for os_unfair_lock {} + + impl ::fmt::Debug for os_unfair_lock { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("os_unfair_lock") + .field("_os_unfair_lock_opaque", &self._os_unfair_lock_opaque) + .finish() + } + } + + impl ::hash::Hash for os_unfair_lock { + fn hash(&self, state: &mut H) { + self._os_unfair_lock_opaque.hash(state); + } + } + + impl PartialEq for sockaddr_vm { + fn eq(&self, other: &sockaddr_vm) -> bool { + self.svm_len == other.svm_len + && self.svm_family == other.svm_family + && self.svm_reserved1 == other.svm_reserved1 + && self.svm_port == other.svm_port + && self.svm_cid == other.svm_cid + } + } + + impl Eq for sockaddr_vm {} + + impl ::fmt::Debug for sockaddr_vm { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let svm_len = self.svm_len; + let svm_family = self.svm_family; + let svm_reserved1 = self.svm_reserved1; + let svm_port = self.svm_port; + let svm_cid = self.svm_cid; + + f.debug_struct("sockaddr_vm") + .field("svm_len",&svm_len) + .field("svm_family",&svm_family) + .field("svm_reserved1",&svm_reserved1) + .field("svm_port",&svm_port) + .field("svm_cid",&svm_cid) + .finish() + } + } + + impl ::hash::Hash for sockaddr_vm { + fn hash(&self, state: &mut H) { + let svm_len = self.svm_len; + let svm_family = self.svm_family; + let svm_reserved1 = self.svm_reserved1; + let svm_port = self.svm_port; + let svm_cid = self.svm_cid; + + svm_len.hash(state); + svm_family.hash(state); + svm_reserved1.hash(state); + svm_port.hash(state); + svm_cid.hash(state); + } + } + + impl PartialEq for ifdevmtu { + fn eq(&self, other: &ifdevmtu) -> bool { + self.ifdm_current == other.ifdm_current + && self.ifdm_min == other.ifdm_min + && self.ifdm_max == other.ifdm_max + } + } + + impl Eq for ifdevmtu {} + + impl ::fmt::Debug for ifdevmtu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifdevmtu") + .field("ifdm_current", &self.ifdm_current) + .field("ifdm_min", &self.ifdm_min) + .field("ifdm_max", &self.ifdm_max) + .finish() + } + } + + impl ::hash::Hash for ifdevmtu { + fn hash(&self, state: &mut H) { + self.ifdm_current.hash(state); + self.ifdm_min.hash(state); + self.ifdm_max.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifk_data { + fn eq(&self, other: &__c_anonymous_ifk_data) -> bool { + unsafe { + self.ifk_ptr == other.ifk_ptr + && self.ifk_value == other.ifk_value + } + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifk_data {} + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifk_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__c_anonymous_ifk_data") + .field("ifk_ptr", unsafe { &self.ifk_ptr }) + .field("ifk_value", unsafe { &self.ifk_value }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifk_data { + fn hash(&self, state: &mut H) { + unsafe { + self.ifk_ptr.hash(state); + self.ifk_value.hash(state); + } + } + } + + impl PartialEq for ifkpi { + fn eq(&self, other: &ifkpi) -> bool { + self.ifk_module_id == other.ifk_module_id + && self.ifk_type == other.ifk_type + } + } + + impl Eq for ifkpi {} + + impl ::fmt::Debug for ifkpi { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifkpi") + .field("ifk_module_id", &self.ifk_module_id) + .field("ifk_type", &self.ifk_type) + .finish() + } + } + + impl ::hash::Hash for ifkpi { + fn hash(&self, state: &mut H) { + self.ifk_module_id.hash(state); + self.ifk_type.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifr_ifru { + fn eq(&self, other: &__c_anonymous_ifr_ifru) -> bool { + unsafe { + self.ifru_addr == other.ifru_addr + && self.ifru_dstaddr == other.ifru_dstaddr + && self.ifru_broadaddr == other.ifru_broadaddr + && self.ifru_flags == other.ifru_flags + && self.ifru_metrics == other.ifru_metrics + && self.ifru_mtu == other.ifru_mtu + && self.ifru_phys == other.ifru_phys + && self.ifru_media == other.ifru_media + && self.ifru_intval == other.ifru_intval + && self.ifru_data == other.ifru_data + && self.ifru_devmtu == other.ifru_devmtu + && self.ifru_kpi == other.ifru_kpi + && self.ifru_wake_flags == other.ifru_wake_flags + && self.ifru_route_refcnt == other.ifru_route_refcnt + && self.ifru_cap.iter().zip(other.ifru_cap.iter()).all(|(a,b)| a == b) + && self.ifru_functional_type == other.ifru_functional_type + } + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifr_ifru {} + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifr_ifru { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__c_anonymous_ifr_ifru") + .field("ifru_addr", unsafe { &self.ifru_addr }) + .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) + .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) + .field("ifru_flags", unsafe { &self.ifru_flags }) + .field("ifru_metrics", unsafe { &self.ifru_metrics }) + .field("ifru_mtu", unsafe { &self.ifru_mtu }) + .field("ifru_phys", unsafe { &self.ifru_phys }) + .field("ifru_media", unsafe { &self.ifru_media }) + .field("ifru_intval", unsafe { &self.ifru_intval }) + .field("ifru_data", unsafe { &self.ifru_data }) + .field("ifru_devmtu", unsafe { &self.ifru_devmtu }) + .field("ifru_kpi", unsafe { &self.ifru_kpi }) + .field("ifru_wake_flags", unsafe { &self.ifru_wake_flags }) + .field("ifru_route_refcnt", unsafe { &self.ifru_route_refcnt }) + .field("ifru_cap", unsafe { &self.ifru_cap }) + .field("ifru_functional_type", unsafe { &self.ifru_functional_type }) + .finish() + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifr_ifru { + fn hash(&self, state: &mut H) { + unsafe { + self.ifru_addr.hash(state); + self.ifru_dstaddr.hash(state); + self.ifru_broadaddr.hash(state); + self.ifru_flags.hash(state); + self.ifru_metrics.hash(state); + self.ifru_mtu.hash(state); + self.ifru_phys.hash(state); + self.ifru_media.hash(state); + self.ifru_intval.hash(state); + self.ifru_data.hash(state); + self.ifru_devmtu.hash(state); + self.ifru_kpi.hash(state); + self.ifru_wake_flags.hash(state); + self.ifru_route_refcnt.hash(state); + self.ifru_cap.hash(state); + self.ifru_functional_type.hash(state); + } + } + } + + impl PartialEq for ifreq { + fn eq(&self, other: &ifreq) -> bool { + self.ifr_name == other.ifr_name + && self.ifr_ifru == other.ifr_ifru + } + } + + impl Eq for ifreq {} + + impl ::fmt::Debug for ifreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifreq") + .field("ifr_name", &self.ifr_name) + .field("ifr_ifru", &self.ifr_ifru) + .finish() + } + } + + impl ::hash::Hash for ifreq { + fn hash(&self, state: &mut H) { + self.ifr_name.hash(state); + self.ifr_ifru.hash(state); + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifc_ifcu {} + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifc_ifcu { + fn eq(&self, other: &__c_anonymous_ifc_ifcu) -> bool { + unsafe { + self.ifcu_buf == other.ifcu_buf && + self.ifcu_req == other.ifcu_req + } + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifc_ifcu") + .field("ifcu_buf", unsafe { &self.ifcu_buf }) + .field("ifcu_req", unsafe { &self.ifcu_req }) + .finish() + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifc_ifcu { + fn hash(&self, state: &mut H) { + unsafe { self.ifcu_buf.hash(state) }; + unsafe { self.ifcu_req.hash(state) }; + } + } + } +} + +pub const _UTX_USERSIZE: usize = 256; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 256; + +pub const EMPTY: ::c_short = 0; +pub const RUN_LVL: ::c_short = 1; +pub const BOOT_TIME: ::c_short = 2; +pub const OLD_TIME: ::c_short = 3; +pub const NEW_TIME: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const USER_PROCESS: ::c_short = 7; +pub const DEAD_PROCESS: ::c_short = 8; +pub const ACCOUNTING: ::c_short = 9; +pub const SIGNATURE: ::c_short = 10; +pub const SHUTDOWN_TIME: ::c_short = 11; + +pub const LC_COLLATE_MASK: ::c_int = 1 << 0; +pub const LC_CTYPE_MASK: ::c_int = 1 << 1; +pub const LC_MESSAGES_MASK: ::c_int = 1 << 2; +pub const LC_MONETARY_MASK: ::c_int = 1 << 3; +pub const LC_NUMERIC_MASK: ::c_int = 1 << 4; +pub const LC_TIME_MASK: ::c_int = 1 << 5; +pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_CTYPE_MASK + | LC_MESSAGES_MASK + | LC_MONETARY_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +pub const CODESET: ::nl_item = 0; +pub const D_T_FMT: ::nl_item = 1; +pub const D_FMT: ::nl_item = 2; +pub const T_FMT: ::nl_item = 3; +pub const T_FMT_AMPM: ::nl_item = 4; +pub const AM_STR: ::nl_item = 5; +pub const PM_STR: ::nl_item = 6; + +pub const DAY_1: ::nl_item = 7; +pub const DAY_2: ::nl_item = 8; +pub const DAY_3: ::nl_item = 9; +pub const DAY_4: ::nl_item = 10; +pub const DAY_5: ::nl_item = 11; +pub const DAY_6: ::nl_item = 12; +pub const DAY_7: ::nl_item = 13; + +pub const ABDAY_1: ::nl_item = 14; +pub const ABDAY_2: ::nl_item = 15; +pub const ABDAY_3: ::nl_item = 16; +pub const ABDAY_4: ::nl_item = 17; +pub const ABDAY_5: ::nl_item = 18; +pub const ABDAY_6: ::nl_item = 19; +pub const ABDAY_7: ::nl_item = 20; + +pub const MON_1: ::nl_item = 21; +pub const MON_2: ::nl_item = 22; +pub const MON_3: ::nl_item = 23; +pub const MON_4: ::nl_item = 24; +pub const MON_5: ::nl_item = 25; +pub const MON_6: ::nl_item = 26; +pub const MON_7: ::nl_item = 27; +pub const MON_8: ::nl_item = 28; +pub const MON_9: ::nl_item = 29; +pub const MON_10: ::nl_item = 30; +pub const MON_11: ::nl_item = 31; +pub const MON_12: ::nl_item = 32; + +pub const ABMON_1: ::nl_item = 33; +pub const ABMON_2: ::nl_item = 34; +pub const ABMON_3: ::nl_item = 35; +pub const ABMON_4: ::nl_item = 36; +pub const ABMON_5: ::nl_item = 37; +pub const ABMON_6: ::nl_item = 38; +pub const ABMON_7: ::nl_item = 39; +pub const ABMON_8: ::nl_item = 40; +pub const ABMON_9: ::nl_item = 41; +pub const ABMON_10: ::nl_item = 42; +pub const ABMON_11: ::nl_item = 43; +pub const ABMON_12: ::nl_item = 44; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_MONOTONIC_RAW_APPROX: ::clockid_t = 5; +pub const CLOCK_MONOTONIC: ::clockid_t = 6; +pub const CLOCK_UPTIME_RAW: ::clockid_t = 8; +pub const CLOCK_UPTIME_RAW_APPROX: ::clockid_t = 9; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 12; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 16; + +pub const ERA: ::nl_item = 45; +pub const ERA_D_FMT: ::nl_item = 46; +pub const ERA_D_T_FMT: ::nl_item = 47; +pub const ERA_T_FMT: ::nl_item = 48; +pub const ALT_DIGITS: ::nl_item = 49; + +pub const RADIXCHAR: ::nl_item = 50; +pub const THOUSEP: ::nl_item = 51; + +pub const YESEXPR: ::nl_item = 52; +pub const NOEXPR: ::nl_item = 53; + +pub const YESSTR: ::nl_item = 54; +pub const NOSTR: ::nl_item = 55; + +pub const CRNCYSTR: ::nl_item = 56; + +pub const D_MD_ORDER: ::nl_item = 57; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const SEEK_HOLE: ::c_int = 3; +pub const SEEK_DATA: ::c_int = 4; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 308915776; +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const O_EVTONLY: ::c_int = 0x00008000; +pub const O_NOCTTY: ::c_int = 0x00020000; +pub const O_DIRECTORY: ::c_int = 0x00100000; +pub const O_SYMLINK: ::c_int = 0x00200000; +pub const O_DSYNC: ::c_int = 0x00400000; +pub const O_CLOEXEC: ::c_int = 0x01000000; +pub const O_NOFOLLOW_ANY: ::c_int = 0x20000000; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +pub const S_IFREG: mode_t = 32768; +pub const S_IFLNK: mode_t = 40960; +pub const S_IFSOCK: mode_t = 49152; +pub const S_IFMT: mode_t = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const PT_TRACE_ME: ::c_int = 0; +pub const PT_READ_I: ::c_int = 1; +pub const PT_READ_D: ::c_int = 2; +pub const PT_READ_U: ::c_int = 3; +pub const PT_WRITE_I: ::c_int = 4; +pub const PT_WRITE_D: ::c_int = 5; +pub const PT_WRITE_U: ::c_int = 6; +pub const PT_CONTINUE: ::c_int = 7; +pub const PT_KILL: ::c_int = 8; +pub const PT_STEP: ::c_int = 9; +pub const PT_ATTACH: ::c_int = 10; +pub const PT_DETACH: ::c_int = 11; +pub const PT_SIGEXC: ::c_int = 12; +pub const PT_THUPDATE: ::c_int = 13; +pub const PT_ATTACHEXC: ::c_int = 14; + +pub const PT_FORCEQUOTA: ::c_int = 30; +pub const PT_DENY_ATTACH: ::c_int = 31; +pub const PT_FIRSTMACH: ::c_int = 32; + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_ANON: ::c_int = 0x1000; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const CPU_STATE_USER: ::c_int = 0; +pub const CPU_STATE_SYSTEM: ::c_int = 1; +pub const CPU_STATE_IDLE: ::c_int = 2; +pub const CPU_STATE_NICE: ::c_int = 3; +pub const CPU_STATE_MAX: ::c_int = 4; + +pub const PROCESSOR_BASIC_INFO: ::c_int = 1; +pub const PROCESSOR_CPU_LOAD_INFO: ::c_int = 2; +pub const PROCESSOR_PM_REGS_INFO: ::c_int = 0x10000001; +pub const PROCESSOR_TEMPERATURE: ::c_int = 0x10000002; +pub const PROCESSOR_SET_LOAD_INFO: ::c_int = 4; +pub const PROCESSOR_SET_BASIC_INFO: ::c_int = 5; + +deprecated_mach! { + pub const VM_FLAGS_FIXED: ::c_int = 0x0000; + pub const VM_FLAGS_ANYWHERE: ::c_int = 0x0001; + pub const VM_FLAGS_PURGABLE: ::c_int = 0x0002; + pub const VM_FLAGS_RANDOM_ADDR: ::c_int = 0x0008; + pub const VM_FLAGS_NO_CACHE: ::c_int = 0x0010; + pub const VM_FLAGS_RESILIENT_CODESIGN: ::c_int = 0x0020; + pub const VM_FLAGS_RESILIENT_MEDIA: ::c_int = 0x0040; + pub const VM_FLAGS_OVERWRITE: ::c_int = 0x4000; + pub const VM_FLAGS_SUPERPAGE_MASK: ::c_int = 0x70000; + pub const VM_FLAGS_RETURN_DATA_ADDR: ::c_int = 0x100000; + pub const VM_FLAGS_RETURN_4K_DATA_ADDR: ::c_int = 0x800000; + pub const VM_FLAGS_ALIAS_MASK: ::c_int = 0xFF000000; + pub const VM_FLAGS_USER_ALLOCATE: ::c_int = 0xff07401f; + pub const VM_FLAGS_USER_MAP: ::c_int = 0xff97401f; + pub const VM_FLAGS_USER_REMAP: ::c_int = VM_FLAGS_FIXED | + VM_FLAGS_ANYWHERE | + VM_FLAGS_RANDOM_ADDR | + VM_FLAGS_OVERWRITE | + VM_FLAGS_RETURN_DATA_ADDR | + VM_FLAGS_RESILIENT_CODESIGN; + + pub const VM_FLAGS_SUPERPAGE_SHIFT: ::c_int = 16; + pub const SUPERPAGE_NONE: ::c_int = 0; + pub const SUPERPAGE_SIZE_ANY: ::c_int = 1; + pub const VM_FLAGS_SUPERPAGE_NONE: ::c_int = SUPERPAGE_NONE << + VM_FLAGS_SUPERPAGE_SHIFT; + pub const VM_FLAGS_SUPERPAGE_SIZE_ANY: ::c_int = SUPERPAGE_SIZE_ANY << + VM_FLAGS_SUPERPAGE_SHIFT; + pub const SUPERPAGE_SIZE_2MB: ::c_int = 2; + pub const VM_FLAGS_SUPERPAGE_SIZE_2MB: ::c_int = SUPERPAGE_SIZE_2MB << + VM_FLAGS_SUPERPAGE_SHIFT; + + pub const VM_MEMORY_MALLOC: ::c_int = 1; + pub const VM_MEMORY_MALLOC_SMALL: ::c_int = 2; + pub const VM_MEMORY_MALLOC_LARGE: ::c_int = 3; + pub const VM_MEMORY_MALLOC_HUGE: ::c_int = 4; + pub const VM_MEMORY_SBRK: ::c_int = 5; + pub const VM_MEMORY_REALLOC: ::c_int = 6; + pub const VM_MEMORY_MALLOC_TINY: ::c_int = 7; + pub const VM_MEMORY_MALLOC_LARGE_REUSABLE: ::c_int = 8; + pub const VM_MEMORY_MALLOC_LARGE_REUSED: ::c_int = 9; + pub const VM_MEMORY_ANALYSIS_TOOL: ::c_int = 10; + pub const VM_MEMORY_MALLOC_NANO: ::c_int = 11; + pub const VM_MEMORY_MACH_MSG: ::c_int = 20; + pub const VM_MEMORY_IOKIT: ::c_int = 21; + pub const VM_MEMORY_STACK: ::c_int = 30; + pub const VM_MEMORY_GUARD: ::c_int = 31; + pub const VM_MEMORY_SHARED_PMAP: ::c_int = 32; + pub const VM_MEMORY_DYLIB: ::c_int = 33; + pub const VM_MEMORY_OBJC_DISPATCHERS: ::c_int = 34; + pub const VM_MEMORY_UNSHARED_PMAP: ::c_int = 35; + pub const VM_MEMORY_APPKIT: ::c_int = 40; + pub const VM_MEMORY_FOUNDATION: ::c_int = 41; + pub const VM_MEMORY_COREGRAPHICS: ::c_int = 42; + pub const VM_MEMORY_CORESERVICES: ::c_int = 43; + pub const VM_MEMORY_CARBON: ::c_int = VM_MEMORY_CORESERVICES; + pub const VM_MEMORY_JAVA: ::c_int = 44; + pub const VM_MEMORY_COREDATA: ::c_int = 45; + pub const VM_MEMORY_COREDATA_OBJECTIDS: ::c_int = 46; + pub const VM_MEMORY_ATS: ::c_int = 50; + pub const VM_MEMORY_LAYERKIT: ::c_int = 51; + pub const VM_MEMORY_CGIMAGE: ::c_int = 52; + pub const VM_MEMORY_TCMALLOC: ::c_int = 53; + pub const VM_MEMORY_COREGRAPHICS_DATA: ::c_int = 54; + pub const VM_MEMORY_COREGRAPHICS_SHARED: ::c_int = 55; + pub const VM_MEMORY_COREGRAPHICS_FRAMEBUFFERS: ::c_int = 56; + pub const VM_MEMORY_COREGRAPHICS_BACKINGSTORES: ::c_int = 57; + pub const VM_MEMORY_COREGRAPHICS_XALLOC: ::c_int = 58; + pub const VM_MEMORY_COREGRAPHICS_MISC: ::c_int = VM_MEMORY_COREGRAPHICS; + pub const VM_MEMORY_DYLD: ::c_int = 60; + pub const VM_MEMORY_DYLD_MALLOC: ::c_int = 61; + pub const VM_MEMORY_SQLITE: ::c_int = 62; + pub const VM_MEMORY_JAVASCRIPT_CORE: ::c_int = 63; + pub const VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR: ::c_int = 64; + pub const VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE: ::c_int = 65; + pub const VM_MEMORY_GLSL: ::c_int = 66; + pub const VM_MEMORY_OPENCL: ::c_int = 67; + pub const VM_MEMORY_COREIMAGE: ::c_int = 68; + pub const VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS: ::c_int = 69; + pub const VM_MEMORY_IMAGEIO: ::c_int = 70; + pub const VM_MEMORY_COREPROFILE: ::c_int = 71; + pub const VM_MEMORY_ASSETSD: ::c_int = 72; + pub const VM_MEMORY_OS_ALLOC_ONCE: ::c_int = 73; + pub const VM_MEMORY_LIBDISPATCH: ::c_int = 74; + pub const VM_MEMORY_ACCELERATE: ::c_int = 75; + pub const VM_MEMORY_COREUI: ::c_int = 76; + pub const VM_MEMORY_COREUIFILE: ::c_int = 77; + pub const VM_MEMORY_GENEALOGY: ::c_int = 78; + pub const VM_MEMORY_RAWCAMERA: ::c_int = 79; + pub const VM_MEMORY_CORPSEINFO: ::c_int = 80; + pub const VM_MEMORY_ASL: ::c_int = 81; + pub const VM_MEMORY_SWIFT_RUNTIME: ::c_int = 82; + pub const VM_MEMORY_SWIFT_METADATA: ::c_int = 83; + pub const VM_MEMORY_DHMM: ::c_int = 84; + pub const VM_MEMORY_SCENEKIT: ::c_int = 86; + pub const VM_MEMORY_SKYWALK: ::c_int = 87; + pub const VM_MEMORY_APPLICATION_SPECIFIC_1: ::c_int = 240; + pub const VM_MEMORY_APPLICATION_SPECIFIC_16: ::c_int = 255; +} + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0010; + +pub const MS_KILLPAGES: ::c_int = 0x0004; +pub const MS_DEACTIVATE: ::c_int = 0x0008; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EDEADLK: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EAGAIN: ::c_int = 35; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EINPROGRESS: ::c_int = 36; +pub const EALREADY: ::c_int = 37; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const ENOTSUP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +pub const ESHUTDOWN: ::c_int = 58; +pub const ETOOMANYREFS: ::c_int = 59; +pub const ETIMEDOUT: ::c_int = 60; +pub const ECONNREFUSED: ::c_int = 61; +pub const ELOOP: ::c_int = 62; +pub const ENAMETOOLONG: ::c_int = 63; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const ENOTEMPTY: ::c_int = 66; +pub const EPROCLIM: ::c_int = 67; +pub const EUSERS: ::c_int = 68; +pub const EDQUOT: ::c_int = 69; +pub const ESTALE: ::c_int = 70; +pub const EREMOTE: ::c_int = 71; +pub const EBADRPC: ::c_int = 72; +pub const ERPCMISMATCH: ::c_int = 73; +pub const EPROGUNAVAIL: ::c_int = 74; +pub const EPROGMISMATCH: ::c_int = 75; +pub const EPROCUNAVAIL: ::c_int = 76; +pub const ENOLCK: ::c_int = 77; +pub const ENOSYS: ::c_int = 78; +pub const EFTYPE: ::c_int = 79; +pub const EAUTH: ::c_int = 80; +pub const ENEEDAUTH: ::c_int = 81; +pub const EPWROFF: ::c_int = 82; +pub const EDEVERR: ::c_int = 83; +pub const EOVERFLOW: ::c_int = 84; +pub const EBADEXEC: ::c_int = 85; +pub const EBADARCH: ::c_int = 86; +pub const ESHLIBVERS: ::c_int = 87; +pub const EBADMACHO: ::c_int = 88; +pub const ECANCELED: ::c_int = 89; +pub const EIDRM: ::c_int = 90; +pub const ENOMSG: ::c_int = 91; +pub const EILSEQ: ::c_int = 92; +pub const ENOATTR: ::c_int = 93; +pub const EBADMSG: ::c_int = 94; +pub const EMULTIHOP: ::c_int = 95; +pub const ENODATA: ::c_int = 96; +pub const ENOLINK: ::c_int = 97; +pub const ENOSR: ::c_int = 98; +pub const ENOSTR: ::c_int = 99; +pub const EPROTO: ::c_int = 100; +pub const ETIME: ::c_int = 101; +pub const EOPNOTSUPP: ::c_int = 102; +pub const ENOPOLICY: ::c_int = 103; +pub const ENOTRECOVERABLE: ::c_int = 104; +pub const EOWNERDEAD: ::c_int = 105; +pub const EQFULL: ::c_int = 106; +pub const ELAST: ::c_int = 106; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 14; + +pub const F_DUPFD: ::c_int = 0; +pub const F_DUPFD_CLOEXEC: ::c_int = 67; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +pub const F_PREALLOCATE: ::c_int = 42; +pub const F_RDADVISE: ::c_int = 44; +pub const F_RDAHEAD: ::c_int = 45; +pub const F_NOCACHE: ::c_int = 48; +pub const F_LOG2PHYS: ::c_int = 49; +pub const F_GETPATH: ::c_int = 50; +pub const F_FULLFSYNC: ::c_int = 51; +pub const F_FREEZE_FS: ::c_int = 53; +pub const F_THAW_FS: ::c_int = 54; +pub const F_GLOBAL_NOCACHE: ::c_int = 55; +pub const F_NODIRECT: ::c_int = 62; +pub const F_LOG2PHYS_EXT: ::c_int = 65; +pub const F_BARRIERFSYNC: ::c_int = 85; +pub const F_PUNCHHOLE: ::c_int = 99; +pub const F_TRIM_ACTIVE_FILE: ::c_int = 100; +pub const F_SPECULATIVE_READ: ::c_int = 101; +pub const F_GETPATH_NOFIRMLINK: ::c_int = 102; + +pub const F_ALLOCATECONTIG: ::c_uint = 0x02; +pub const F_ALLOCATEALL: ::c_uint = 0x04; + +pub const F_PEOFPOSMODE: ::c_int = 3; +pub const F_VOLPOSMODE: ::c_int = 4; + +pub const AT_FDCWD: ::c_int = -2; +pub const AT_EACCESS: ::c_int = 0x0010; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x0020; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x0040; +pub const AT_REMOVEDIR: ::c_int = 0x0080; + +pub const PTHREAD_INTROSPECTION_THREAD_CREATE: ::c_uint = 1; +pub const PTHREAD_INTROSPECTION_THREAD_START: ::c_uint = 2; +pub const PTHREAD_INTROSPECTION_THREAD_TERMINATE: ::c_uint = 3; +pub const PTHREAD_INTROSPECTION_THREAD_DESTROY: ::c_uint = 4; + +pub const TIOCMODG: ::c_ulong = 0x40047403; +pub const TIOCMODS: ::c_ulong = 0x80047404; +pub const TIOCM_LE: ::c_int = 0x1; +pub const TIOCM_DTR: ::c_int = 0x2; +pub const TIOCM_RTS: ::c_int = 0x4; +pub const TIOCM_ST: ::c_int = 0x8; +pub const TIOCM_SR: ::c_int = 0x10; +pub const TIOCM_CTS: ::c_int = 0x20; +pub const TIOCM_CAR: ::c_int = 0x40; +pub const TIOCM_CD: ::c_int = 0x40; +pub const TIOCM_RNG: ::c_int = 0x80; +pub const TIOCM_RI: ::c_int = 0x80; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCEXCL: ::c_int = 0x2000740d; +pub const TIOCNXCL: ::c_int = 0x2000740e; +pub const TIOCFLUSH: ::c_ulong = 0x80047410; +pub const TIOCGETD: ::c_ulong = 0x4004741a; +pub const TIOCSETD: ::c_ulong = 0x8004741b; +pub const TIOCIXON: ::c_uint = 0x20007481; +pub const TIOCIXOFF: ::c_uint = 0x20007480; +pub const TIOCSDTR: ::c_uint = 0x20007479; +pub const TIOCCDTR: ::c_uint = 0x20007478; +pub const TIOCGPGRP: ::c_ulong = 0x40047477; +pub const TIOCSPGRP: ::c_ulong = 0x80047476; +pub const TIOCOUTQ: ::c_ulong = 0x40047473; +pub const TIOCSTI: ::c_ulong = 0x80017472; +pub const TIOCNOTTY: ::c_uint = 0x20007471; +pub const TIOCPKT: ::c_ulong = 0x80047470; +pub const TIOCPKT_DATA: ::c_int = 0x0; +pub const TIOCPKT_FLUSHREAD: ::c_int = 0x1; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 0x2; +pub const TIOCPKT_STOP: ::c_int = 0x4; +pub const TIOCPKT_START: ::c_int = 0x8; +pub const TIOCPKT_NOSTOP: ::c_int = 0x10; +pub const TIOCPKT_DOSTOP: ::c_int = 0x20; +pub const TIOCPKT_IOCTL: ::c_int = 0x40; +pub const TIOCSTOP: ::c_uint = 0x2000746f; +pub const TIOCSTART: ::c_uint = 0x2000746e; +pub const TIOCMSET: ::c_ulong = 0x8004746d; +pub const TIOCMBIS: ::c_ulong = 0x8004746c; +pub const TIOCMBIC: ::c_ulong = 0x8004746b; +pub const TIOCMGET: ::c_ulong = 0x4004746a; +pub const TIOCREMOTE: ::c_ulong = 0x80047469; +pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +pub const TIOCUCNTL: ::c_ulong = 0x80047466; +pub const TIOCSTAT: ::c_uint = 0x20007465; +pub const TIOCSCONS: ::c_uint = 0x20007463; +pub const TIOCCONS: ::c_ulong = 0x80047462; +pub const TIOCSCTTY: ::c_uint = 0x20007461; +pub const TIOCEXT: ::c_ulong = 0x80047460; +pub const TIOCSIG: ::c_uint = 0x2000745f; +pub const TIOCDRAIN: ::c_uint = 0x2000745e; +pub const TIOCMSDTRWAIT: ::c_ulong = 0x8004745b; +pub const TIOCMGDTRWAIT: ::c_ulong = 0x4004745a; +pub const TIOCSDRAINWAIT: ::c_ulong = 0x80047457; +pub const TIOCGDRAINWAIT: ::c_ulong = 0x40047456; +pub const TIOCDSIMICROCODE: ::c_uint = 0x20007455; +pub const TIOCPTYGRANT: ::c_uint = 0x20007454; +pub const TIOCPTYGNAME: ::c_uint = 0x40807453; +pub const TIOCPTYUNLK: ::c_uint = 0x20007452; + +pub const BIOCGRSIG: ::c_ulong = 0x40044272; +pub const BIOCSRSIG: ::c_ulong = 0x80044273; +pub const BIOCSDLT: ::c_ulong = 0x80044278; +pub const BIOCGSEESENT: ::c_ulong = 0x40044276; +pub const BIOCSSEESENT: ::c_ulong = 0x80044277; +pub const BIOCGDLTLIST: ::c_ulong = 0xc00c4279; + +pub const FIODTYPE: ::c_ulong = 0x4004667a; + +pub const B0: speed_t = 0; +pub const B50: speed_t = 50; +pub const B75: speed_t = 75; +pub const B110: speed_t = 110; +pub const B134: speed_t = 134; +pub const B150: speed_t = 150; +pub const B200: speed_t = 200; +pub const B300: speed_t = 300; +pub const B600: speed_t = 600; +pub const B1200: speed_t = 1200; +pub const B1800: speed_t = 1800; +pub const B2400: speed_t = 2400; +pub const B4800: speed_t = 4800; +pub const B9600: speed_t = 9600; +pub const B19200: speed_t = 19200; +pub const B38400: speed_t = 38400; +pub const B7200: speed_t = 7200; +pub const B14400: speed_t = 14400; +pub const B28800: speed_t = 28800; +pub const B57600: speed_t = 57600; +pub const B76800: speed_t = 76800; +pub const B115200: speed_t = 115200; +pub const B230400: speed_t = 230400; +pub const EXTA: speed_t = 19200; +pub const EXTB: speed_t = 38400; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 0x0001; +pub const GLOB_DOOFFS: ::c_int = 0x0002; +pub const GLOB_ERR: ::c_int = 0x0004; +pub const GLOB_MARK: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_NOSORT: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x2000; + +pub const GLOB_NOSPACE: ::c_int = -1; +pub const GLOB_ABORTED: ::c_int = -2; +pub const GLOB_NOMATCH: ::c_int = -3; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const _SC_IOV_MAX: ::c_int = 56; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 70; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 71; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 73; +pub const _SC_MQ_PRIO_MAX: ::c_int = 75; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 82; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 83; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 85; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 86; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 87; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 88; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 89; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 90; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 91; +pub const _SC_THREAD_STACK_MIN: ::c_int = 93; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 94; +pub const _SC_THREADS: ::c_int = 96; +pub const _SC_TTY_NAME_MAX: ::c_int = 101; +pub const _SC_ATEXIT_MAX: ::c_int = 107; +pub const _SC_XOPEN_CRYPT: ::c_int = 108; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 109; +pub const _SC_XOPEN_LEGACY: ::c_int = 110; +pub const _SC_XOPEN_REALTIME: ::c_int = 111; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 112; +pub const _SC_XOPEN_SHM: ::c_int = 113; +pub const _SC_XOPEN_UNIX: ::c_int = 115; +pub const _SC_XOPEN_VERSION: ::c_int = 116; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 121; +pub const _SC_PHYS_PAGES: ::c_int = 200; + +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 2; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 1; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 2; +#[cfg(target_arch = "aarch64")] +pub const PTHREAD_STACK_MIN: ::size_t = 16384; +#[cfg(not(target_arch = "aarch64"))] +pub const PTHREAD_STACK_MIN: ::size_t = 8192; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_AS: ::c_int = 5; +pub const RLIMIT_RSS: ::c_int = RLIMIT_AS; +pub const RLIMIT_MEMLOCK: ::c_int = 6; +pub const RLIMIT_NPROC: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 8; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 9; +pub const _RLIMIT_POSIX_FLAG: ::c_int = 0x1000; + +pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 5; +pub const MADV_ZERO_WIRED_PAGES: ::c_int = 6; +pub const MADV_FREE_REUSABLE: ::c_int = 7; +pub const MADV_FREE_REUSE: ::c_int = 8; +pub const MADV_CAN_REUSE: ::c_int = 9; + +pub const MINCORE_INCORE: ::c_int = 0x1; +pub const MINCORE_REFERENCED: ::c_int = 0x2; +pub const MINCORE_MODIFIED: ::c_int = 0x4; +pub const MINCORE_REFERENCED_OTHER: ::c_int = 0x8; +pub const MINCORE_MODIFIED_OTHER: ::c_int = 0x10; + +pub const CTLIOCGINFO: c_ulong = 0xc0644e03; + +// +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// Stream protocol II. +pub const IPPROTO_ST: ::c_int = 7; +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// private interior gateway +pub const IPPROTO_PIGP: ::c_int = 9; +/// BBN RCC Monitoring +pub const IPPROTO_RCCMON: ::c_int = 10; +/// network voice protocol +pub const IPPROTO_NVPII: ::c_int = 11; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +/// Argus +pub const IPPROTO_ARGUS: ::c_int = 13; +/// EMCON +pub const IPPROTO_EMCON: ::c_int = 14; +/// Cross Net Debugger +pub const IPPROTO_XNET: ::c_int = 15; +/// Chaos +pub const IPPROTO_CHAOS: ::c_int = 16; +// IPPROTO_UDP defined in src/unix/mod.rs +/// Multiplexing +pub const IPPROTO_MUX: ::c_int = 18; +/// DCN Measurement Subsystems +pub const IPPROTO_MEAS: ::c_int = 19; +/// Host Monitoring +pub const IPPROTO_HMP: ::c_int = 20; +/// Packet Radio Measurement +pub const IPPROTO_PRM: ::c_int = 21; +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// Trunk-1 +pub const IPPROTO_TRUNK1: ::c_int = 23; +/// Trunk-2 +pub const IPPROTO_TRUNK2: ::c_int = 24; +/// Leaf-1 +pub const IPPROTO_LEAF1: ::c_int = 25; +/// Leaf-2 +pub const IPPROTO_LEAF2: ::c_int = 26; +/// Reliable Data +pub const IPPROTO_RDP: ::c_int = 27; +/// Reliable Transaction +pub const IPPROTO_IRTP: ::c_int = 28; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// Bulk Data Transfer +pub const IPPROTO_BLT: ::c_int = 30; +/// Network Services +pub const IPPROTO_NSP: ::c_int = 31; +/// Merit Internodal +pub const IPPROTO_INP: ::c_int = 32; +/// Sequential Exchange +pub const IPPROTO_SEP: ::c_int = 33; +/// Third Party Connect +pub const IPPROTO_3PC: ::c_int = 34; +/// InterDomain Policy Routing +pub const IPPROTO_IDPR: ::c_int = 35; +/// XTP +pub const IPPROTO_XTP: ::c_int = 36; +/// Datagram Delivery +pub const IPPROTO_DDP: ::c_int = 37; +/// Control Message Transport +pub const IPPROTO_CMTP: ::c_int = 38; +/// TP++ Transport +pub const IPPROTO_TPXX: ::c_int = 39; +/// IL transport protocol +pub const IPPROTO_IL: ::c_int = 40; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// Source Demand Routing +pub const IPPROTO_SDRP: ::c_int = 42; +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// InterDomain Routing +pub const IPPROTO_IDRP: ::c_int = 45; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// Mobile Host Routing +pub const IPPROTO_MHRP: ::c_int = 48; +/// BHA +pub const IPPROTO_BHA: ::c_int = 49; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// Integ. Net Layer Security +pub const IPPROTO_INLSP: ::c_int = 52; +/// IP with encryption +pub const IPPROTO_SWIPE: ::c_int = 53; +/// Next Hop Resolution +pub const IPPROTO_NHRP: ::c_int = 54; +/* 55-57: Unassigned */ +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// any host internal protocol +pub const IPPROTO_AHIP: ::c_int = 61; +/// CFTP +pub const IPPROTO_CFTP: ::c_int = 62; +/// "hello" routing protocol +pub const IPPROTO_HELLO: ::c_int = 63; +/// SATNET/Backroom EXPAK +pub const IPPROTO_SATEXPAK: ::c_int = 64; +/// Kryptolan +pub const IPPROTO_KRYPTOLAN: ::c_int = 65; +/// Remote Virtual Disk +pub const IPPROTO_RVD: ::c_int = 66; +/// Pluribus Packet Core +pub const IPPROTO_IPPC: ::c_int = 67; +/// Any distributed FS +pub const IPPROTO_ADFS: ::c_int = 68; +/// Satnet Monitoring +pub const IPPROTO_SATMON: ::c_int = 69; +/// VISA Protocol +pub const IPPROTO_VISA: ::c_int = 70; +/// Packet Core Utility +pub const IPPROTO_IPCV: ::c_int = 71; +/// Comp. Prot. Net. Executive +pub const IPPROTO_CPNX: ::c_int = 72; +/// Comp. Prot. HeartBeat +pub const IPPROTO_CPHB: ::c_int = 73; +/// Wang Span Network +pub const IPPROTO_WSN: ::c_int = 74; +/// Packet Video Protocol +pub const IPPROTO_PVP: ::c_int = 75; +/// BackRoom SATNET Monitoring +pub const IPPROTO_BRSATMON: ::c_int = 76; +/// Sun net disk proto (temp.) +pub const IPPROTO_ND: ::c_int = 77; +/// WIDEBAND Monitoring +pub const IPPROTO_WBMON: ::c_int = 78; +/// WIDEBAND EXPAK +pub const IPPROTO_WBEXPAK: ::c_int = 79; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// VMTP +pub const IPPROTO_VMTP: ::c_int = 81; +/// Secure VMTP +pub const IPPROTO_SVMTP: ::c_int = 82; +/// Banyon VINES +pub const IPPROTO_VINES: ::c_int = 83; +/// TTP +pub const IPPROTO_TTP: ::c_int = 84; +/// NSFNET-IGP +pub const IPPROTO_IGP: ::c_int = 85; +/// dissimilar gateway prot. +pub const IPPROTO_DGP: ::c_int = 86; +/// TCF +pub const IPPROTO_TCF: ::c_int = 87; +/// Cisco/GXS IGRP +pub const IPPROTO_IGRP: ::c_int = 88; +/// OSPFIGP +pub const IPPROTO_OSPFIGP: ::c_int = 89; +/// Strite RPC protocol +pub const IPPROTO_SRPC: ::c_int = 90; +/// Locus Address Resoloution +pub const IPPROTO_LARP: ::c_int = 91; +/// Multicast Transport +pub const IPPROTO_MTP: ::c_int = 92; +/// AX.25 Frames +pub const IPPROTO_AX25: ::c_int = 93; +/// IP encapsulated in IP +pub const IPPROTO_IPEIP: ::c_int = 94; +/// Mobile Int.ing control +pub const IPPROTO_MICP: ::c_int = 95; +/// Semaphore Comm. security +pub const IPPROTO_SCCSP: ::c_int = 96; +/// Ethernet IP encapsulation +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// any private encr. scheme +pub const IPPROTO_APES: ::c_int = 99; +/// GMTP +pub const IPPROTO_GMTP: ::c_int = 100; + +/* 101-254: Partly Unassigned */ +/// Protocol Independent Mcast +pub const IPPROTO_PIM: ::c_int = 103; +/// payload compression (IPComp) +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// PGM +pub const IPPROTO_PGM: ::c_int = 113; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; + +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion */ +/// divert pseudo-protocol +pub const IPPROTO_DIVERT: ::c_int = 254; +/// raw IP packet +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MAX: ::c_int = 256; +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NS: ::c_int = 6; +pub const AF_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +pub const AF_ECMA: ::c_int = 8; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +pub const pseudo_AF_RTIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_SIP: ::c_int = 24; +pub const pseudo_AF_PIP: ::c_int = 25; +pub const AF_NDRV: ::c_int = 27; +pub const AF_ISDN: ::c_int = 28; +pub const AF_E164: ::c_int = AF_ISDN; +pub const pseudo_AF_KEY: ::c_int = 29; +pub const AF_INET6: ::c_int = 30; +pub const AF_NATM: ::c_int = 31; +pub const AF_SYSTEM: ::c_int = 32; +pub const AF_NETBIOS: ::c_int = 33; +pub const AF_PPP: ::c_int = 34; +pub const pseudo_AF_HDRCMPLT: ::c_int = 35; +pub const AF_IEEE80211: ::c_int = 37; +pub const AF_UTUN: ::c_int = 38; +pub const AF_VSOCK: ::c_int = 40; +pub const AF_SYS_CONTROL: ::c_int = 2; + +pub const SYSPROTO_EVENT: ::c_int = 1; +pub const SYSPROTO_CONTROL: ::c_int = 2; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = PF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_IMPLINK: ::c_int = AF_IMPLINK; +pub const PF_PUP: ::c_int = AF_PUP; +pub const PF_CHAOS: ::c_int = AF_CHAOS; +pub const PF_NS: ::c_int = AF_NS; +pub const PF_ISO: ::c_int = AF_ISO; +pub const PF_OSI: ::c_int = AF_ISO; +pub const PF_ECMA: ::c_int = AF_ECMA; +pub const PF_DATAKIT: ::c_int = AF_DATAKIT; +pub const PF_CCITT: ::c_int = AF_CCITT; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_DLI: ::c_int = AF_DLI; +pub const PF_LAT: ::c_int = AF_LAT; +pub const PF_HYLINK: ::c_int = AF_HYLINK; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_LINK: ::c_int = AF_LINK; +pub const PF_XTP: ::c_int = pseudo_AF_XTP; +pub const PF_COIP: ::c_int = AF_COIP; +pub const PF_CNT: ::c_int = AF_CNT; +pub const PF_SIP: ::c_int = AF_SIP; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_RTIP: ::c_int = pseudo_AF_RTIP; +pub const PF_PIP: ::c_int = pseudo_AF_PIP; +pub const PF_NDRV: ::c_int = AF_NDRV; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_KEY: ::c_int = pseudo_AF_KEY; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_NATM: ::c_int = AF_NATM; +pub const PF_SYSTEM: ::c_int = AF_SYSTEM; +pub const PF_NETBIOS: ::c_int = AF_NETBIOS; +pub const PF_PPP: ::c_int = AF_PPP; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; + +pub const SOMAXCONN: ::c_int = 128; + +pub const SOCK_MAXADDRLEN: ::c_int = 255; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_RECVIF: ::c_int = 20; +pub const IP_RECVTTL: ::c_int = 24; +pub const IP_BOUND_IF: ::c_int = 25; +pub const IP_PKTINFO: ::c_int = 26; +pub const IP_RECVTOS: ::c_int = 27; +pub const IP_DONTFRAG: ::c_int = 28; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; +pub const IPV6_CHECKSUM: ::c_int = 26; +pub const IPV6_RECVTCLASS: ::c_int = 35; +pub const IPV6_TCLASS: ::c_int = 36; +pub const IPV6_RECVHOPLIMIT: ::c_int = 37; +pub const IPV6_PKTINFO: ::c_int = 46; +pub const IPV6_HOPLIMIT: ::c_int = 47; +pub const IPV6_RECVPKTINFO: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 70; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 71; +pub const IP_BLOCK_SOURCE: ::c_int = 72; +pub const IP_UNBLOCK_SOURCE: ::c_int = 73; +pub const IPV6_BOUND_IF: ::c_int = 125; + +pub const TCP_NOPUSH: ::c_int = 4; +pub const TCP_NOOPT: ::c_int = 8; +pub const TCP_KEEPALIVE: ::c_int = 0x10; +pub const TCP_KEEPINTVL: ::c_int = 0x101; +pub const TCP_KEEPCNT: ::c_int = 0x102; +/// Enable/Disable TCP Fastopen on this socket +pub const TCP_FASTOPEN: ::c_int = 0x105; +pub const TCP_CONNECTION_INFO: ::c_int = 0x106; + +pub const SOL_LOCAL: ::c_int = 0; + +pub const LOCAL_PEERCRED: ::c_int = 0x001; +pub const LOCAL_PEERPID: ::c_int = 0x002; +pub const LOCAL_PEEREPID: ::c_int = 0x003; +pub const LOCAL_PEERUUID: ::c_int = 0x004; +pub const LOCAL_PEEREUUID: ::c_int = 0x005; + +pub const SOL_SOCKET: ::c_int = 0xffff; + +pub const SO_DEBUG: ::c_int = 0x01; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_TIMESTAMP: ::c_int = 0x0400; +pub const SO_TIMESTAMP_MONOTONIC: ::c_int = 0x0800; +pub const SO_DONTTRUNC: ::c_int = 0x2000; +pub const SO_WANTMORE: ::c_int = 0x4000; +pub const SO_WANTOOBFLAG: ::c_int = 0x8000; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_LABEL: ::c_int = 0x1010; +pub const SO_PEERLABEL: ::c_int = 0x1011; +pub const SO_NREAD: ::c_int = 0x1020; +pub const SO_NKE: ::c_int = 0x1021; +pub const SO_NOSIGPIPE: ::c_int = 0x1022; +pub const SO_NOADDRERR: ::c_int = 0x1023; +pub const SO_NWRITE: ::c_int = 0x1024; +pub const SO_REUSESHAREUID: ::c_int = 0x1025; +pub const SO_NOTIFYCONFLICT: ::c_int = 0x1026; +pub const SO_LINGER_SEC: ::c_int = 0x1080; +pub const SO_RANDOMPORT: ::c_int = 0x1082; +pub const SO_NP_EXTENSIONS: ::c_int = 0x1083; + +pub const MSG_OOB: ::c_int = 0x1; +pub const MSG_PEEK: ::c_int = 0x2; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_EOR: ::c_int = 0x8; +pub const MSG_TRUNC: ::c_int = 0x10; +pub const MSG_CTRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_DONTWAIT: ::c_int = 0x80; +pub const MSG_EOF: ::c_int = 0x100; +pub const MSG_FLUSH: ::c_int = 0x400; +pub const MSG_HOLD: ::c_int = 0x800; +pub const MSG_SEND: ::c_int = 0x1000; +pub const MSG_HAVEMORE: ::c_int = 0x2000; +pub const MSG_RCVMORE: ::c_int = 0x4000; +pub const MSG_NEEDSA: ::c_int = 0x10000; +pub const MSG_NOSIGNAL: ::c_int = 0x80000; + +pub const SCM_TIMESTAMP: ::c_int = 0x02; +pub const SCM_CREDS: ::c_int = 0x03; + +// https://github.com/aosm/xnu/blob/HEAD/bsd/net/if.h#L140-L156 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_NOTRAILERS: ::c_int = 0x20; // obsolete: avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions +pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit +pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit +pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit +pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; // use alternate physical connection +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const SAE_ASSOCID_ANY: ::sae_associd_t = 0; +/// ((sae_associd_t)(-1ULL)) +pub const SAE_ASSOCID_ALL: ::sae_associd_t = 0xffffffff; + +pub const SAE_CONNID_ANY: ::sae_connid_t = 0; +/// ((sae_connid_t)(-1ULL)) +pub const SAE_CONNID_ALL: ::sae_connid_t = 0xffffffff; + +// connectx() flag parameters + +/// resume connect() on read/write +pub const CONNECT_RESUME_ON_READ_WRITE: ::c_uint = 0x1; +/// data is idempotent +pub const CONNECT_DATA_IDEMPOTENT: ::c_uint = 0x2; +/// data includes security that replaces the TFO-cookie +pub const CONNECT_DATA_AUTHENTICATED: ::c_uint = 0x4; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const MAP_COPY: ::c_int = 0x0002; +pub const MAP_RENAME: ::c_int = 0x0020; +pub const MAP_NORESERVE: ::c_int = 0x0040; +pub const MAP_NOEXTEND: ::c_int = 0x0100; +pub const MAP_HASSEMAPHORE: ::c_int = 0x0200; +pub const MAP_NOCACHE: ::c_int = 0x0400; +pub const MAP_JIT: ::c_int = 0x0800; + +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_NGROUPS_MAX: ::c_int = 4; +pub const _SC_OPEN_MAX: ::c_int = 5; +pub const _SC_JOB_CONTROL: ::c_int = 6; +pub const _SC_SAVED_IDS: ::c_int = 7; +pub const _SC_VERSION: ::c_int = 8; +pub const _SC_BC_BASE_MAX: ::c_int = 9; +pub const _SC_BC_DIM_MAX: ::c_int = 10; +pub const _SC_BC_SCALE_MAX: ::c_int = 11; +pub const _SC_BC_STRING_MAX: ::c_int = 12; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 13; +pub const _SC_EXPR_NEST_MAX: ::c_int = 14; +pub const _SC_LINE_MAX: ::c_int = 15; +pub const _SC_RE_DUP_MAX: ::c_int = 16; +pub const _SC_2_VERSION: ::c_int = 17; +pub const _SC_2_C_BIND: ::c_int = 18; +pub const _SC_2_C_DEV: ::c_int = 19; +pub const _SC_2_CHAR_TERM: ::c_int = 20; +pub const _SC_2_FORT_DEV: ::c_int = 21; +pub const _SC_2_FORT_RUN: ::c_int = 22; +pub const _SC_2_LOCALEDEF: ::c_int = 23; +pub const _SC_2_SW_DEV: ::c_int = 24; +pub const _SC_2_UPE: ::c_int = 25; +pub const _SC_STREAM_MAX: ::c_int = 26; +pub const _SC_TZNAME_MAX: ::c_int = 27; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 28; +pub const _SC_PAGESIZE: ::c_int = 29; +pub const _SC_MEMLOCK: ::c_int = 30; +pub const _SC_MEMLOCK_RANGE: ::c_int = 31; +pub const _SC_MEMORY_PROTECTION: ::c_int = 32; +pub const _SC_MESSAGE_PASSING: ::c_int = 33; +pub const _SC_PRIORITIZED_IO: ::c_int = 34; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 35; +pub const _SC_REALTIME_SIGNALS: ::c_int = 36; +pub const _SC_SEMAPHORES: ::c_int = 37; +pub const _SC_FSYNC: ::c_int = 38; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 39; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 40; +pub const _SC_TIMERS: ::c_int = 41; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 42; +pub const _SC_AIO_MAX: ::c_int = 43; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 44; +pub const _SC_DELAYTIMER_MAX: ::c_int = 45; +pub const _SC_MQ_OPEN_MAX: ::c_int = 46; +pub const _SC_MAPPED_FILES: ::c_int = 47; +pub const _SC_RTSIG_MAX: ::c_int = 48; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 49; +pub const _SC_SEM_VALUE_MAX: ::c_int = 50; +pub const _SC_SIGQUEUE_MAX: ::c_int = 51; +pub const _SC_TIMER_MAX: ::c_int = 52; +pub const _SC_NPROCESSORS_CONF: ::c_int = 57; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 58; +pub const _SC_2_PBS: ::c_int = 59; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 60; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 61; +pub const _SC_2_PBS_LOCATE: ::c_int = 62; +pub const _SC_2_PBS_MESSAGE: ::c_int = 63; +pub const _SC_2_PBS_TRACK: ::c_int = 64; +pub const _SC_ADVISORY_INFO: ::c_int = 65; +pub const _SC_BARRIERS: ::c_int = 66; +pub const _SC_CLOCK_SELECTION: ::c_int = 67; +pub const _SC_CPUTIME: ::c_int = 68; +pub const _SC_FILE_LOCKING: ::c_int = 69; +pub const _SC_HOST_NAME_MAX: ::c_int = 72; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 74; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 76; +pub const _SC_REGEXP: ::c_int = 77; +pub const _SC_SHELL: ::c_int = 78; +pub const _SC_SPAWN: ::c_int = 79; +pub const _SC_SPIN_LOCKS: ::c_int = 80; +pub const _SC_SPORADIC_SERVER: ::c_int = 81; +pub const _SC_THREAD_CPUTIME: ::c_int = 84; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 92; +pub const _SC_TIMEOUTS: ::c_int = 95; +pub const _SC_TRACE: ::c_int = 97; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 98; +pub const _SC_TRACE_INHERIT: ::c_int = 99; +pub const _SC_TRACE_LOG: ::c_int = 100; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 102; +pub const _SC_V6_ILP32_OFF32: ::c_int = 103; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 104; +pub const _SC_V6_LP64_OFF64: ::c_int = 105; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 106; +pub const _SC_IPV6: ::c_int = 118; +pub const _SC_RAW_SOCKETS: ::c_int = 119; +pub const _SC_SYMLOOP_MAX: ::c_int = 120; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_XOPEN_STREAMS: ::c_int = 114; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 122; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 123; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 124; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 125; +pub const _SC_SS_REPL_MAX: ::c_int = 126; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 127; +pub const _SC_TRACE_NAME_MAX: ::c_int = 128; +pub const _SC_TRACE_SYS_MAX: ::c_int = 129; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 130; +pub const _SC_PASS_MAX: ::c_int = 131; +// `confstr` keys (only the values guaranteed by `man confstr`). +pub const _CS_PATH: ::c_int = 1; +pub const _CS_DARWIN_USER_DIR: ::c_int = 65536; +pub const _CS_DARWIN_USER_TEMP_DIR: ::c_int = 65537; +pub const _CS_DARWIN_USER_CACHE_DIR: ::c_int = 65538; + +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const _PTHREAD_MUTEX_SIG_init: ::c_long = 0x32AAABA7; +pub const _PTHREAD_COND_SIG_init: ::c_long = 0x3CB0B1BB; +pub const _PTHREAD_RWLOCK_SIG_init: ::c_long = 0x2DA8B3B4; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __sig: _PTHREAD_MUTEX_SIG_init, + __opaque: [0; __PTHREAD_MUTEX_SIZE__], +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __sig: _PTHREAD_COND_SIG_init, + __opaque: [0; __PTHREAD_COND_SIZE__], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __sig: _PTHREAD_RWLOCK_SIG_init, + __opaque: [0; __PTHREAD_RWLOCK_SIZE__], +}; + +pub const OS_UNFAIR_LOCK_INIT: os_unfair_lock = os_unfair_lock { + _os_unfair_lock_opaque: 0, +}; + +pub const OS_LOG_TYPE_DEFAULT: ::os_log_type_t = 0x00; +pub const OS_LOG_TYPE_INFO: ::os_log_type_t = 0x01; +pub const OS_LOG_TYPE_DEBUG: ::os_log_type_t = 0x02; +pub const OS_LOG_TYPE_ERROR: ::os_log_type_t = 0x10; +pub const OS_LOG_TYPE_FAULT: ::os_log_type_t = 0x11; + +pub const OS_SIGNPOST_EVENT: ::os_signpost_type_t = 0x00; +pub const OS_SIGNPOST_INTERVAL_BEGIN: ::os_signpost_type_t = 0x01; +pub const OS_SIGNPOST_INTERVAL_END: ::os_signpost_type_t = 0x02; + +pub const MINSIGSTKSZ: ::size_t = 32768; +pub const SIGSTKSZ: ::size_t = 131072; + +pub const FD_SETSIZE: usize = 1024; + +pub const ST_NOSUID: ::c_ulong = 2; + +pub const SCHED_OTHER: ::c_int = 1; +pub const SCHED_FIFO: ::c_int = 4; +pub const SCHED_RR: ::c_int = 2; + +pub const EVFILT_READ: i16 = -1; +pub const EVFILT_WRITE: i16 = -2; +pub const EVFILT_AIO: i16 = -3; +pub const EVFILT_VNODE: i16 = -4; +pub const EVFILT_PROC: i16 = -5; +pub const EVFILT_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_MACHPORT: i16 = -8; +pub const EVFILT_FS: i16 = -9; +pub const EVFILT_USER: i16 = -10; +pub const EVFILT_VM: i16 = -12; + +pub const EV_ADD: u16 = 0x1; +pub const EV_DELETE: u16 = 0x2; +pub const EV_ENABLE: u16 = 0x4; +pub const EV_DISABLE: u16 = 0x8; +pub const EV_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +pub const EV_FLAG0: u16 = 0x1000; +pub const EV_POLL: u16 = 0x1000; +pub const EV_FLAG1: u16 = 0x2000; +pub const EV_OOBAND: u16 = 0x2000; +pub const EV_ERROR: u16 = 0x4000; +pub const EV_EOF: u16 = 0x8000; +pub const EV_SYSFLAGS: u16 = 0xf000; + +pub const NOTE_TRIGGER: u32 = 0x01000000; +pub const NOTE_FFNOP: u32 = 0x00000000; +pub const NOTE_FFAND: u32 = 0x40000000; +pub const NOTE_FFOR: u32 = 0x80000000; +pub const NOTE_FFCOPY: u32 = 0xc0000000; +pub const NOTE_FFCTRLMASK: u32 = 0xc0000000; +pub const NOTE_FFLAGSMASK: u32 = 0x00ffffff; +pub const NOTE_LOWAT: u32 = 0x00000001; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +pub const NOTE_ATTRIB: u32 = 0x00000008; +pub const NOTE_LINK: u32 = 0x00000010; +pub const NOTE_RENAME: u32 = 0x00000020; +pub const NOTE_REVOKE: u32 = 0x00000040; +pub const NOTE_NONE: u32 = 0x00000080; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Deprecated since MacOSX 10.9")] +pub const NOTE_REAP: u32 = 0x10000000; +pub const NOTE_SIGNAL: u32 = 0x08000000; +pub const NOTE_EXITSTATUS: u32 = 0x04000000; +pub const NOTE_EXIT_DETAIL: u32 = 0x02000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +pub const NOTE_PCTRLMASK: u32 = 0xfff00000; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Deprecated since MacOSX 10.9")] +pub const NOTE_EXIT_REPARENTED: u32 = 0x00080000; +pub const NOTE_EXIT_DETAIL_MASK: u32 = 0x00070000; +pub const NOTE_EXIT_DECRYPTFAIL: u32 = 0x00010000; +pub const NOTE_EXIT_MEMORY: u32 = 0x00020000; +pub const NOTE_EXIT_CSERROR: u32 = 0x00040000; +pub const NOTE_VM_PRESSURE: u32 = 0x80000000; +pub const NOTE_VM_PRESSURE_TERMINATE: u32 = 0x40000000; +pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE: u32 = 0x20000000; +pub const NOTE_VM_ERROR: u32 = 0x10000000; +pub const NOTE_SECONDS: u32 = 0x00000001; +pub const NOTE_USECONDS: u32 = 0x00000002; +pub const NOTE_NSECONDS: u32 = 0x00000004; +pub const NOTE_ABSOLUTE: u32 = 0x00000008; +pub const NOTE_LEEWAY: u32 = 0x00000010; +pub const NOTE_CRITICAL: u32 = 0x00000020; +pub const NOTE_BACKGROUND: u32 = 0x00000040; +pub const NOTE_TRACK: u32 = 0x00000001; +pub const NOTE_TRACKERR: u32 = 0x00000002; +pub const NOTE_CHILD: u32 = 0x00000004; + +pub const OCRNL: ::tcflag_t = 0x00000010; +pub const ONOCR: ::tcflag_t = 0x00000020; +pub const ONLRET: ::tcflag_t = 0x00000040; +pub const OFILL: ::tcflag_t = 0x00000080; +pub const NLDLY: ::tcflag_t = 0x00000300; +pub const TABDLY: ::tcflag_t = 0x00000c04; +pub const CRDLY: ::tcflag_t = 0x00003000; +pub const FFDLY: ::tcflag_t = 0x00004000; +pub const BSDLY: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0x00010000; +pub const OFDEL: ::tcflag_t = 0x00020000; + +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00000100; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB1: ::tcflag_t = 0x00000400; +pub const TAB2: ::tcflag_t = 0x00000800; +pub const CR0: ::tcflag_t = 0x00000000; +pub const CR1: ::tcflag_t = 0x00001000; +pub const CR2: ::tcflag_t = 0x00002000; +pub const CR3: ::tcflag_t = 0x00003000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const FF1: ::tcflag_t = 0x00004000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const BS1: ::tcflag_t = 0x00008000; +pub const TAB3: ::tcflag_t = 0x00000004; +pub const VT0: ::tcflag_t = 0x00000000; +pub const VT1: ::tcflag_t = 0x00010000; +pub const IUTF8: ::tcflag_t = 0x00004000; +pub const CRTSCTS: ::tcflag_t = 0x00030000; + +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const NI_MAXSERV: ::socklen_t = 32; +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x00000002; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +pub const NI_NUMERICSERV: ::c_int = 0x00000008; +pub const NI_NUMERICSCOPE: ::c_int = 0x00000100; +pub const NI_DGRAM: ::c_int = 0x00000010; + +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQUOTA: ::c_int = 0x400; + +pub const RENAME_SWAP: ::c_uint = 0x00000002; +pub const RENAME_EXCL: ::c_uint = 0x00000004; + +pub const RTLD_LOCAL: ::c_int = 0x4; +pub const RTLD_FIRST: ::c_int = 0x100; +pub const RTLD_NODELETE: ::c_int = 0x80; +pub const RTLD_NOLOAD: ::c_int = 0x10; +pub const RTLD_GLOBAL: ::c_int = 0x8; +pub const RTLD_MAIN_ONLY: *mut ::c_void = -5isize as *mut ::c_void; + +pub const _WSTOPPED: ::c_int = 0o177; + +pub const LOG_NETINFO: ::c_int = 12 << 3; +pub const LOG_REMOTEAUTH: ::c_int = 13 << 3; +pub const LOG_INSTALL: ::c_int = 14 << 3; +pub const LOG_RAS: ::c_int = 15 << 3; +pub const LOG_LAUNCHD: ::c_int = 24 << 3; +pub const LOG_NFACILITIES: ::c_int = 25; + +pub const CTLTYPE: ::c_int = 0xf; +pub const CTLTYPE_NODE: ::c_int = 1; +pub const CTLTYPE_INT: ::c_int = 2; +pub const CTLTYPE_STRING: ::c_int = 3; +pub const CTLTYPE_QUAD: ::c_int = 4; +pub const CTLTYPE_OPAQUE: ::c_int = 5; +pub const CTLTYPE_STRUCT: ::c_int = CTLTYPE_OPAQUE; +pub const CTLFLAG_RD: ::c_int = 0x80000000; +pub const CTLFLAG_WR: ::c_int = 0x40000000; +pub const CTLFLAG_RW: ::c_int = CTLFLAG_RD | CTLFLAG_WR; +pub const CTLFLAG_NOLOCK: ::c_int = 0x20000000; +pub const CTLFLAG_ANYBODY: ::c_int = 0x10000000; +pub const CTLFLAG_SECURE: ::c_int = 0x08000000; +pub const CTLFLAG_MASKED: ::c_int = 0x04000000; +pub const CTLFLAG_NOAUTO: ::c_int = 0x02000000; +pub const CTLFLAG_KERN: ::c_int = 0x01000000; +pub const CTLFLAG_LOCKED: ::c_int = 0x00800000; +pub const CTLFLAG_OID2: ::c_int = 0x00400000; +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_VFS: ::c_int = 3; +pub const CTL_NET: ::c_int = 4; +pub const CTL_DEBUG: ::c_int = 5; +pub const CTL_HW: ::c_int = 6; +pub const CTL_MACHDEP: ::c_int = 7; +pub const CTL_USER: ::c_int = 8; +pub const CTL_MAXID: ::c_int = 9; +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_NISDOMAINNAME: ::c_int = 22; +pub const KERN_DOMAINNAME: ::c_int = KERN_NISDOMAINNAME; +pub const KERN_MAXPARTITIONS: ::c_int = 23; +pub const KERN_KDEBUG: ::c_int = 24; +pub const KERN_UPDATEINTERVAL: ::c_int = 25; +pub const KERN_OSRELDATE: ::c_int = 26; +pub const KERN_NTP_PLL: ::c_int = 27; +pub const KERN_BOOTFILE: ::c_int = 28; +pub const KERN_MAXFILESPERPROC: ::c_int = 29; +pub const KERN_MAXPROCPERUID: ::c_int = 30; +pub const KERN_DUMPDEV: ::c_int = 31; +pub const KERN_IPC: ::c_int = 32; +pub const KERN_DUMMY: ::c_int = 33; +pub const KERN_PS_STRINGS: ::c_int = 34; +pub const KERN_USRSTACK32: ::c_int = 35; +pub const KERN_LOGSIGEXIT: ::c_int = 36; +pub const KERN_SYMFILE: ::c_int = 37; +pub const KERN_PROCARGS: ::c_int = 38; +pub const KERN_NETBOOT: ::c_int = 40; +pub const KERN_SYSV: ::c_int = 42; +pub const KERN_AFFINITY: ::c_int = 43; +pub const KERN_TRANSLATE: ::c_int = 44; +pub const KERN_CLASSIC: ::c_int = KERN_TRANSLATE; +pub const KERN_EXEC: ::c_int = 45; +pub const KERN_CLASSICHANDLER: ::c_int = KERN_EXEC; +pub const KERN_AIOMAX: ::c_int = 46; +pub const KERN_AIOPROCMAX: ::c_int = 47; +pub const KERN_AIOTHREADS: ::c_int = 48; +pub const KERN_COREFILE: ::c_int = 50; +pub const KERN_COREDUMP: ::c_int = 51; +pub const KERN_SUGID_COREDUMP: ::c_int = 52; +pub const KERN_PROCDELAYTERM: ::c_int = 53; +pub const KERN_SHREG_PRIVATIZABLE: ::c_int = 54; +pub const KERN_LOW_PRI_WINDOW: ::c_int = 56; +pub const KERN_LOW_PRI_DELAY: ::c_int = 57; +pub const KERN_POSIX: ::c_int = 58; +pub const KERN_USRSTACK64: ::c_int = 59; +pub const KERN_NX_PROTECTION: ::c_int = 60; +pub const KERN_TFP: ::c_int = 61; +pub const KERN_PROCNAME: ::c_int = 62; +pub const KERN_THALTSTACK: ::c_int = 63; +pub const KERN_SPECULATIVE_READS: ::c_int = 64; +pub const KERN_OSVERSION: ::c_int = 65; +pub const KERN_SAFEBOOT: ::c_int = 66; +pub const KERN_RAGEVNODE: ::c_int = 68; +pub const KERN_TTY: ::c_int = 69; +pub const KERN_CHECKOPENEVT: ::c_int = 70; +pub const KERN_THREADNAME: ::c_int = 71; +pub const KERN_MAXID: ::c_int = 72; +pub const KERN_RAGE_PROC: ::c_int = 1; +pub const KERN_RAGE_THREAD: ::c_int = 2; +pub const KERN_UNRAGE_PROC: ::c_int = 3; +pub const KERN_UNRAGE_THREAD: ::c_int = 4; +pub const KERN_OPENEVT_PROC: ::c_int = 1; +pub const KERN_UNOPENEVT_PROC: ::c_int = 2; +pub const KERN_TFP_POLICY: ::c_int = 1; +pub const KERN_TFP_POLICY_DENY: ::c_int = 0; +pub const KERN_TFP_POLICY_DEFAULT: ::c_int = 2; +pub const KERN_KDEFLAGS: ::c_int = 1; +pub const KERN_KDDFLAGS: ::c_int = 2; +pub const KERN_KDENABLE: ::c_int = 3; +pub const KERN_KDSETBUF: ::c_int = 4; +pub const KERN_KDGETBUF: ::c_int = 5; +pub const KERN_KDSETUP: ::c_int = 6; +pub const KERN_KDREMOVE: ::c_int = 7; +pub const KERN_KDSETREG: ::c_int = 8; +pub const KERN_KDGETREG: ::c_int = 9; +pub const KERN_KDREADTR: ::c_int = 10; +pub const KERN_KDPIDTR: ::c_int = 11; +pub const KERN_KDTHRMAP: ::c_int = 12; +pub const KERN_KDPIDEX: ::c_int = 14; +pub const KERN_KDSETRTCDEC: ::c_int = 15; +pub const KERN_KDGETENTROPY: ::c_int = 16; +pub const KERN_KDWRITETR: ::c_int = 17; +pub const KERN_KDWRITEMAP: ::c_int = 18; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Removed in MacOSX 10.12")] +pub const KERN_KDENABLE_BG_TRACE: ::c_int = 19; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Removed in MacOSX 10.12")] +pub const KERN_KDDISABLE_BG_TRACE: ::c_int = 20; +pub const KERN_KDREADCURTHRMAP: ::c_int = 21; +pub const KERN_KDSET_TYPEFILTER: ::c_int = 22; +pub const KERN_KDBUFWAIT: ::c_int = 23; +pub const KERN_KDCPUMAP: ::c_int = 24; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +pub const KERN_PROC_SESSION: ::c_int = 3; +pub const KERN_PROC_TTY: ::c_int = 4; +pub const KERN_PROC_UID: ::c_int = 5; +pub const KERN_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_LCID: ::c_int = 7; +pub const KERN_SUCCESS: ::c_int = 0; +pub const KERN_INVALID_ADDRESS: ::c_int = 1; +pub const KERN_PROTECTION_FAILURE: ::c_int = 2; +pub const KERN_NO_SPACE: ::c_int = 3; +pub const KERN_INVALID_ARGUMENT: ::c_int = 4; +pub const KERN_FAILURE: ::c_int = 5; +pub const KERN_RESOURCE_SHORTAGE: ::c_int = 6; +pub const KERN_NOT_RECEIVER: ::c_int = 7; +pub const KERN_NO_ACCESS: ::c_int = 8; +pub const KERN_MEMORY_FAILURE: ::c_int = 9; +pub const KERN_MEMORY_ERROR: ::c_int = 10; +pub const KERN_ALREADY_IN_SET: ::c_int = 11; +pub const KERN_NOT_IN_SET: ::c_int = 12; +pub const KERN_NAME_EXISTS: ::c_int = 13; +pub const KERN_ABORTED: ::c_int = 14; +pub const KERN_INVALID_NAME: ::c_int = 15; +pub const KERN_INVALID_TASK: ::c_int = 16; +pub const KERN_INVALID_RIGHT: ::c_int = 17; +pub const KERN_INVALID_VALUE: ::c_int = 18; +pub const KERN_UREFS_OVERFLOW: ::c_int = 19; +pub const KERN_INVALID_CAPABILITY: ::c_int = 20; +pub const KERN_RIGHT_EXISTS: ::c_int = 21; +pub const KERN_INVALID_HOST: ::c_int = 22; +pub const KERN_MEMORY_PRESENT: ::c_int = 23; +pub const KERN_MEMORY_DATA_MOVED: ::c_int = 24; +pub const KERN_MEMORY_RESTART_COPY: ::c_int = 25; +pub const KERN_INVALID_PROCESSOR_SET: ::c_int = 26; +pub const KERN_POLICY_LIMIT: ::c_int = 27; +pub const KERN_INVALID_POLICY: ::c_int = 28; +pub const KERN_INVALID_OBJECT: ::c_int = 29; +pub const KERN_ALREADY_WAITING: ::c_int = 30; +pub const KERN_DEFAULT_SET: ::c_int = 31; +pub const KERN_EXCEPTION_PROTECTED: ::c_int = 32; +pub const KERN_INVALID_LEDGER: ::c_int = 33; +pub const KERN_INVALID_MEMORY_CONTROL: ::c_int = 34; +pub const KERN_INVALID_SECURITY: ::c_int = 35; +pub const KERN_NOT_DEPRESSED: ::c_int = 36; +pub const KERN_TERMINATED: ::c_int = 37; +pub const KERN_LOCK_SET_DESTROYED: ::c_int = 38; +pub const KERN_LOCK_UNSTABLE: ::c_int = 39; +pub const KERN_LOCK_OWNED: ::c_int = 40; +pub const KERN_LOCK_OWNED_SELF: ::c_int = 41; +pub const KERN_SEMAPHORE_DESTROYED: ::c_int = 42; +pub const KERN_RPC_SERVER_TERMINATED: ::c_int = 43; +pub const KERN_RPC_TERMINATE_ORPHAN: ::c_int = 44; +pub const KERN_RPC_CONTINUE_ORPHAN: ::c_int = 45; +pub const KERN_NOT_SUPPORTED: ::c_int = 46; +pub const KERN_NODE_DOWN: ::c_int = 47; +pub const KERN_NOT_WAITING: ::c_int = 48; +pub const KERN_OPERATION_TIMED_OUT: ::c_int = 49; +pub const KERN_CODESIGN_ERROR: ::c_int = 50; +pub const KERN_POLICY_STATIC: ::c_int = 51; +pub const KERN_INSUFFICIENT_BUFFER_SIZE: ::c_int = 52; +pub const KIPC_MAXSOCKBUF: ::c_int = 1; +pub const KIPC_SOCKBUF_WASTE: ::c_int = 2; +pub const KIPC_SOMAXCONN: ::c_int = 3; +pub const KIPC_MAX_LINKHDR: ::c_int = 4; +pub const KIPC_MAX_PROTOHDR: ::c_int = 5; +pub const KIPC_MAX_HDR: ::c_int = 6; +pub const KIPC_MAX_DATALEN: ::c_int = 7; +pub const KIPC_MBSTAT: ::c_int = 8; +pub const KIPC_NMBCLUSTERS: ::c_int = 9; +pub const KIPC_SOQLIMITCOMPAT: ::c_int = 10; +pub const VM_METER: ::c_int = 1; +pub const VM_LOADAVG: ::c_int = 2; +pub const VM_MACHFACTOR: ::c_int = 4; +pub const VM_SWAPUSAGE: ::c_int = 5; +pub const VM_MAXID: ::c_int = 6; +pub const VM_PROT_NONE: ::vm_prot_t = 0x00; +pub const VM_PROT_READ: ::vm_prot_t = 0x01; +pub const VM_PROT_WRITE: ::vm_prot_t = 0x02; +pub const VM_PROT_EXECUTE: ::vm_prot_t = 0x04; +pub const MEMORY_OBJECT_NULL: ::memory_object_t = 0; +pub const HW_MACHINE: ::c_int = 1; +pub const HW_MODEL: ::c_int = 2; +pub const HW_NCPU: ::c_int = 3; +pub const HW_BYTEORDER: ::c_int = 4; +pub const HW_PHYSMEM: ::c_int = 5; +pub const HW_USERMEM: ::c_int = 6; +pub const HW_PAGESIZE: ::c_int = 7; +pub const HW_DISKNAMES: ::c_int = 8; +pub const HW_DISKSTATS: ::c_int = 9; +pub const HW_EPOCH: ::c_int = 10; +pub const HW_FLOATINGPT: ::c_int = 11; +pub const HW_MACHINE_ARCH: ::c_int = 12; +pub const HW_VECTORUNIT: ::c_int = 13; +pub const HW_BUS_FREQ: ::c_int = 14; +pub const HW_CPU_FREQ: ::c_int = 15; +pub const HW_CACHELINE: ::c_int = 16; +pub const HW_L1ICACHESIZE: ::c_int = 17; +pub const HW_L1DCACHESIZE: ::c_int = 18; +pub const HW_L2SETTINGS: ::c_int = 19; +pub const HW_L2CACHESIZE: ::c_int = 20; +pub const HW_L3SETTINGS: ::c_int = 21; +pub const HW_L3CACHESIZE: ::c_int = 22; +pub const HW_TB_FREQ: ::c_int = 23; +pub const HW_MEMSIZE: ::c_int = 24; +pub const HW_AVAILCPU: ::c_int = 25; +pub const HW_TARGET: ::c_int = 26; +pub const HW_PRODUCT: ::c_int = 27; +pub const HW_MAXID: ::c_int = 28; +pub const USER_CS_PATH: ::c_int = 1; +pub const USER_BC_BASE_MAX: ::c_int = 2; +pub const USER_BC_DIM_MAX: ::c_int = 3; +pub const USER_BC_SCALE_MAX: ::c_int = 4; +pub const USER_BC_STRING_MAX: ::c_int = 5; +pub const USER_COLL_WEIGHTS_MAX: ::c_int = 6; +pub const USER_EXPR_NEST_MAX: ::c_int = 7; +pub const USER_LINE_MAX: ::c_int = 8; +pub const USER_RE_DUP_MAX: ::c_int = 9; +pub const USER_POSIX2_VERSION: ::c_int = 10; +pub const USER_POSIX2_C_BIND: ::c_int = 11; +pub const USER_POSIX2_C_DEV: ::c_int = 12; +pub const USER_POSIX2_CHAR_TERM: ::c_int = 13; +pub const USER_POSIX2_FORT_DEV: ::c_int = 14; +pub const USER_POSIX2_FORT_RUN: ::c_int = 15; +pub const USER_POSIX2_LOCALEDEF: ::c_int = 16; +pub const USER_POSIX2_SW_DEV: ::c_int = 17; +pub const USER_POSIX2_UPE: ::c_int = 18; +pub const USER_STREAM_MAX: ::c_int = 19; +pub const USER_TZNAME_MAX: ::c_int = 20; +pub const USER_MAXID: ::c_int = 21; +pub const CTL_DEBUG_NAME: ::c_int = 0; +pub const CTL_DEBUG_VALUE: ::c_int = 1; +pub const CTL_DEBUG_MAXID: ::c_int = 20; + +pub const PRIO_DARWIN_THREAD: ::c_int = 3; +pub const PRIO_DARWIN_PROCESS: ::c_int = 4; +pub const PRIO_DARWIN_BG: ::c_int = 0x1000; +pub const PRIO_DARWIN_NONUI: ::c_int = 0x1001; + +pub const SEM_FAILED: *mut sem_t = -1isize as *mut ::sem_t; + +pub const AI_PASSIVE: ::c_int = 0x00000001; +pub const AI_CANONNAME: ::c_int = 0x00000002; +pub const AI_NUMERICHOST: ::c_int = 0x00000004; +pub const AI_NUMERICSERV: ::c_int = 0x00001000; +pub const AI_MASK: ::c_int = + AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG; +pub const AI_ALL: ::c_int = 0x00000100; +pub const AI_V4MAPPED_CFG: ::c_int = 0x00000200; +pub const AI_ADDRCONFIG: ::c_int = 0x00000400; +pub const AI_V4MAPPED: ::c_int = 0x00000800; +pub const AI_DEFAULT: ::c_int = AI_V4MAPPED_CFG | AI_ADDRCONFIG; +pub const AI_UNUSABLE: ::c_int = 0x10000000; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 3; + +pub const AIO_CANCELED: ::c_int = 2; +pub const AIO_NOTCANCELED: ::c_int = 4; +pub const AIO_ALLDONE: ::c_int = 1; +#[deprecated( + since = "0.2.64", + note = "Can vary at runtime. Use sysconf(3) instead" +)] +pub const AIO_LISTIO_MAX: ::c_int = 16; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 2; +pub const LIO_READ: ::c_int = 1; +pub const LIO_WAIT: ::c_int = 2; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const WEXITED: ::c_int = 0x00000004; +pub const WSTOPPED: ::c_int = 0x00000008; +pub const WCONTINUED: ::c_int = 0x00000010; +pub const WNOWAIT: ::c_int = 0x00000020; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const UTIME_OMIT: c_long = -2; +pub const UTIME_NOW: c_long = -1; + +pub const XATTR_NOFOLLOW: ::c_int = 0x0001; +pub const XATTR_CREATE: ::c_int = 0x0002; +pub const XATTR_REPLACE: ::c_int = 0x0004; +pub const XATTR_NOSECURITY: ::c_int = 0x0008; +pub const XATTR_NODEFAULT: ::c_int = 0x0010; +pub const XATTR_SHOWCOMPRESSION: ::c_int = 0x0020; + +pub const NET_RT_IFLIST2: ::c_int = 0x0006; + +// net/route.h +pub const RTF_UP: ::c_int = 0x1; +pub const RTF_GATEWAY: ::c_int = 0x2; +pub const RTF_HOST: ::c_int = 0x4; +pub const RTF_REJECT: ::c_int = 0x8; +pub const RTF_DYNAMIC: ::c_int = 0x10; +pub const RTF_MODIFIED: ::c_int = 0x20; +pub const RTF_DONE: ::c_int = 0x40; +pub const RTF_DELCLONE: ::c_int = 0x80; +pub const RTF_CLONING: ::c_int = 0x100; +pub const RTF_XRESOLVE: ::c_int = 0x200; +pub const RTF_LLINFO: ::c_int = 0x400; +pub const RTF_STATIC: ::c_int = 0x800; +pub const RTF_BLACKHOLE: ::c_int = 0x1000; +pub const RTF_NOIFREF: ::c_int = 0x2000; +pub const RTF_PROTO2: ::c_int = 0x4000; +pub const RTF_PROTO1: ::c_int = 0x8000; +pub const RTF_PRCLONING: ::c_int = 0x10000; +pub const RTF_WASCLONED: ::c_int = 0x20000; +pub const RTF_PROTO3: ::c_int = 0x40000; +pub const RTF_PINNED: ::c_int = 0x100000; +pub const RTF_LOCAL: ::c_int = 0x200000; +pub const RTF_BROADCAST: ::c_int = 0x400000; +pub const RTF_MULTICAST: ::c_int = 0x800000; +pub const RTF_IFSCOPE: ::c_int = 0x1000000; +pub const RTF_CONDEMNED: ::c_int = 0x2000000; +pub const RTF_IFREF: ::c_int = 0x4000000; +pub const RTF_PROXY: ::c_int = 0x8000000; +pub const RTF_ROUTER: ::c_int = 0x10000000; +pub const RTF_DEAD: ::c_int = 0x20000000; +pub const RTF_GLOBAL: ::c_int = 0x40000000; + +pub const RTM_VERSION: ::c_int = 5; + +// Message types +pub const RTM_ADD: ::c_int = 0x1; +pub const RTM_DELETE: ::c_int = 0x2; +pub const RTM_CHANGE: ::c_int = 0x3; +pub const RTM_GET: ::c_int = 0x4; +pub const RTM_LOSING: ::c_int = 0x5; +pub const RTM_REDIRECT: ::c_int = 0x6; +pub const RTM_MISS: ::c_int = 0x7; +pub const RTM_LOCK: ::c_int = 0x8; +pub const RTM_OLDADD: ::c_int = 0x9; +pub const RTM_OLDDEL: ::c_int = 0xa; +pub const RTM_RESOLVE: ::c_int = 0xb; +pub const RTM_NEWADDR: ::c_int = 0xc; +pub const RTM_DELADDR: ::c_int = 0xd; +pub const RTM_IFINFO: ::c_int = 0xe; +pub const RTM_NEWMADDR: ::c_int = 0xf; +pub const RTM_DELMADDR: ::c_int = 0x10; +pub const RTM_IFINFO2: ::c_int = 0x12; +pub const RTM_NEWMADDR2: ::c_int = 0x13; +pub const RTM_GET2: ::c_int = 0x14; + +// Bitmask values for rtm_inits and rmx_locks. +pub const RTV_MTU: ::c_int = 0x1; +pub const RTV_HOPCOUNT: ::c_int = 0x2; +pub const RTV_EXPIRE: ::c_int = 0x4; +pub const RTV_RPIPE: ::c_int = 0x8; +pub const RTV_SPIPE: ::c_int = 0x10; +pub const RTV_SSTHRESH: ::c_int = 0x20; +pub const RTV_RTT: ::c_int = 0x40; +pub const RTV_RTTVAR: ::c_int = 0x80; + +// Bitmask values for rtm_addrs. +pub const RTA_DST: ::c_int = 0x1; +pub const RTA_GATEWAY: ::c_int = 0x2; +pub const RTA_NETMASK: ::c_int = 0x4; +pub const RTA_GENMASK: ::c_int = 0x8; +pub const RTA_IFP: ::c_int = 0x10; +pub const RTA_IFA: ::c_int = 0x20; +pub const RTA_AUTHOR: ::c_int = 0x40; +pub const RTA_BRD: ::c_int = 0x80; + +// Index offsets for sockaddr array for alternate internal encoding. +pub const RTAX_DST: ::c_int = 0; +pub const RTAX_GATEWAY: ::c_int = 1; +pub const RTAX_NETMASK: ::c_int = 2; +pub const RTAX_GENMASK: ::c_int = 3; +pub const RTAX_IFP: ::c_int = 4; +pub const RTAX_IFA: ::c_int = 5; +pub const RTAX_AUTHOR: ::c_int = 6; +pub const RTAX_BRD: ::c_int = 7; +pub const RTAX_MAX: ::c_int = 8; + +pub const KERN_PROCARGS2: ::c_int = 49; + +pub const PROC_PIDTASKALLINFO: ::c_int = 2; +pub const PROC_PIDTBSDINFO: ::c_int = 3; +pub const PROC_PIDTASKINFO: ::c_int = 4; +pub const PROC_PIDTHREADINFO: ::c_int = 5; +pub const PROC_PIDVNODEPATHINFO: ::c_int = 9; +pub const PROC_PIDPATHINFO_MAXSIZE: ::c_int = 4096; +pub const PROC_CSM_ALL: ::c_uint = 0x0001; +pub const PROC_CSM_NOSMT: ::c_uint = 0x0002; +pub const PROC_CSM_TECS: ::c_uint = 0x0004; +pub const MAXCOMLEN: usize = 16; +pub const MAXTHREADNAMESIZE: usize = 64; + +pub const XUCRED_VERSION: ::c_uint = 0; + +pub const LC_SEGMENT: u32 = 0x1; +pub const LC_SEGMENT_64: u32 = 0x19; + +pub const MH_MAGIC: u32 = 0xfeedface; +pub const MH_MAGIC_64: u32 = 0xfeedfacf; + +// net/if_utun.h +pub const UTUN_OPT_FLAGS: ::c_int = 1; +pub const UTUN_OPT_IFNAME: ::c_int = 2; + +// net/bpf.h +pub const DLT_NULL: ::c_uint = 0; // no link-layer encapsulation +pub const DLT_EN10MB: ::c_uint = 1; // Ethernet (10Mb) +pub const DLT_EN3MB: ::c_uint = 2; // Experimental Ethernet (3Mb) +pub const DLT_AX25: ::c_uint = 3; // Amateur Radio AX.25 +pub const DLT_PRONET: ::c_uint = 4; // Proteon ProNET Token Ring +pub const DLT_CHAOS: ::c_uint = 5; // Chaos +pub const DLT_IEEE802: ::c_uint = 6; // IEEE 802 Networks +pub const DLT_ARCNET: ::c_uint = 7; // ARCNET +pub const DLT_SLIP: ::c_uint = 8; // Serial Line IP +pub const DLT_PPP: ::c_uint = 9; // Point-to-point Protocol +pub const DLT_FDDI: ::c_uint = 10; // FDDI +pub const DLT_ATM_RFC1483: ::c_uint = 11; // LLC/SNAP encapsulated atm +pub const DLT_RAW: ::c_uint = 12; // raw IP +pub const DLT_LOOP: ::c_uint = 108; + +// https://github.com/apple/darwin-xnu/blob/HEAD/bsd/net/bpf.h#L100 +// sizeof(i32) +pub const BPF_ALIGNMENT: ::c_int = 4; + +// sys/mount.h +pub const MNT_NODEV: ::c_int = 0x00000010; +pub const MNT_UNION: ::c_int = 0x00000020; +pub const MNT_CPROTECT: ::c_int = 0x00000080; + +// MAC labeled / "quarantined" flag +pub const MNT_QUARANTINE: ::c_int = 0x00000400; + +// Flags set by internal operations. +pub const MNT_LOCAL: ::c_int = 0x00001000; +pub const MNT_QUOTA: ::c_int = 0x00002000; +pub const MNT_ROOTFS: ::c_int = 0x00004000; +pub const MNT_DOVOLFS: ::c_int = 0x00008000; + +pub const MNT_DONTBROWSE: ::c_int = 0x00100000; +pub const MNT_IGNORE_OWNERSHIP: ::c_int = 0x00200000; +pub const MNT_AUTOMOUNTED: ::c_int = 0x00400000; +pub const MNT_JOURNALED: ::c_int = 0x00800000; +pub const MNT_NOUSERXATTR: ::c_int = 0x01000000; +pub const MNT_DEFWRITE: ::c_int = 0x02000000; +pub const MNT_MULTILABEL: ::c_int = 0x04000000; +pub const MNT_NOATIME: ::c_int = 0x10000000; +pub const MNT_SNAPSHOT: ::c_int = 0x40000000; + +// External filesystem command modifier flags. +pub const MNT_NOBLOCK: ::c_int = 0x00020000; + +// sys/spawn.h: +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x0001; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x0002; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x0004; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x0008; +pub const POSIX_SPAWN_SETEXEC: ::c_int = 0x0040; +pub const POSIX_SPAWN_START_SUSPENDED: ::c_int = 0x0080; +pub const POSIX_SPAWN_CLOEXEC_DEFAULT: ::c_int = 0x4000; + +// sys/ipc.h: +pub const IPC_CREAT: ::c_int = 0x200; +pub const IPC_EXCL: ::c_int = 0x400; +pub const IPC_NOWAIT: ::c_int = 0x800; +pub const IPC_PRIVATE: key_t = 0; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; + +pub const IPC_R: ::c_int = 0x100; +pub const IPC_W: ::c_int = 0x80; +pub const IPC_M: ::c_int = 0x1000; + +// sys/sem.h +pub const SEM_UNDO: ::c_int = 0o10000; + +pub const GETNCNT: ::c_int = 3; +pub const GETPID: ::c_int = 4; +pub const GETVAL: ::c_int = 5; +pub const GETALL: ::c_int = 6; +pub const GETZCNT: ::c_int = 7; +pub const SETVAL: ::c_int = 8; +pub const SETALL: ::c_int = 9; + +// sys/shm.h +pub const SHM_RDONLY: ::c_int = 0x1000; +pub const SHM_RND: ::c_int = 0x2000; +#[cfg(target_arch = "aarch64")] +pub const SHMLBA: ::c_int = 16 * 1024; +#[cfg(not(target_arch = "aarch64"))] +pub const SHMLBA: ::c_int = 4096; +pub const SHM_R: ::c_int = IPC_R; +pub const SHM_W: ::c_int = IPC_W; + +// Flags for chflags(2) +pub const UF_SETTABLE: ::c_uint = 0x0000ffff; +pub const UF_NODUMP: ::c_uint = 0x00000001; +pub const UF_IMMUTABLE: ::c_uint = 0x00000002; +pub const UF_APPEND: ::c_uint = 0x00000004; +pub const UF_OPAQUE: ::c_uint = 0x00000008; +pub const UF_COMPRESSED: ::c_uint = 0x00000020; +pub const UF_TRACKED: ::c_uint = 0x00000040; +pub const SF_SETTABLE: ::c_uint = 0xffff0000; +pub const SF_ARCHIVED: ::c_uint = 0x00010000; +pub const SF_IMMUTABLE: ::c_uint = 0x00020000; +pub const SF_APPEND: ::c_uint = 0x00040000; +pub const UF_HIDDEN: ::c_uint = 0x00008000; + +// +pub const NTP_API: ::c_int = 4; +pub const MAXPHASE: ::c_long = 500000000; +pub const MAXFREQ: ::c_long = 500000; +pub const MINSEC: ::c_int = 256; +pub const MAXSEC: ::c_int = 2048; +pub const NANOSECOND: ::c_long = 1000000000; +pub const SCALE_PPM: ::c_int = 65; +pub const MAXTC: ::c_int = 10; +pub const MOD_OFFSET: ::c_uint = 0x0001; +pub const MOD_FREQUENCY: ::c_uint = 0x0002; +pub const MOD_MAXERROR: ::c_uint = 0x0004; +pub const MOD_ESTERROR: ::c_uint = 0x0008; +pub const MOD_STATUS: ::c_uint = 0x0010; +pub const MOD_TIMECONST: ::c_uint = 0x0020; +pub const MOD_PPSMAX: ::c_uint = 0x0040; +pub const MOD_TAI: ::c_uint = 0x0080; +pub const MOD_MICRO: ::c_uint = 0x1000; +pub const MOD_NANO: ::c_uint = 0x2000; +pub const MOD_CLKB: ::c_uint = 0x4000; +pub const MOD_CLKA: ::c_uint = 0x8000; +pub const STA_PLL: ::c_int = 0x0001; +pub const STA_PPSFREQ: ::c_int = 0x0002; +pub const STA_PPSTIME: ::c_int = 0x0004; +pub const STA_FLL: ::c_int = 0x0008; +pub const STA_INS: ::c_int = 0x0010; +pub const STA_DEL: ::c_int = 0x0020; +pub const STA_UNSYNC: ::c_int = 0x0040; +pub const STA_FREQHOLD: ::c_int = 0x0080; +pub const STA_PPSSIGNAL: ::c_int = 0x0100; +pub const STA_PPSJITTER: ::c_int = 0x0200; +pub const STA_PPSWANDER: ::c_int = 0x0400; +pub const STA_PPSERROR: ::c_int = 0x0800; +pub const STA_CLOCKERR: ::c_int = 0x1000; +pub const STA_NANO: ::c_int = 0x2000; +pub const STA_MODE: ::c_int = 0x4000; +pub const STA_CLK: ::c_int = 0x8000; +pub const STA_RONLY: ::c_int = STA_PPSSIGNAL + | STA_PPSJITTER + | STA_PPSWANDER + | STA_PPSERROR + | STA_CLOCKERR + | STA_NANO + | STA_MODE + | STA_CLK; +pub const TIME_OK: ::c_int = 0; +pub const TIME_INS: ::c_int = 1; +pub const TIME_DEL: ::c_int = 2; +pub const TIME_OOP: ::c_int = 3; +pub const TIME_WAIT: ::c_int = 4; +pub const TIME_ERROR: ::c_int = 5; + +// +pub const MNT_WAIT: ::c_int = 1; +pub const MNT_NOWAIT: ::c_int = 2; + +// +pub const THREAD_STANDARD_POLICY: ::c_int = 1; +pub const THREAD_STANDARD_POLICY_COUNT: ::c_int = 0; +pub const THREAD_EXTENDED_POLICY: ::c_int = 1; +pub const THREAD_TIME_CONSTRAINT_POLICY: ::c_int = 2; +pub const THREAD_PRECEDENCE_POLICY: ::c_int = 3; +pub const THREAD_AFFINITY_POLICY: ::c_int = 4; +pub const THREAD_AFFINITY_TAG_NULL: ::c_int = 0; +pub const THREAD_BACKGROUND_POLICY: ::c_int = 5; +pub const THREAD_BACKGROUND_POLICY_DARWIN_BG: ::c_int = 0x1000; +pub const THREAD_LATENCY_QOS_POLICY: ::c_int = 7; +pub const THREAD_THROUGHPUT_QOS_POLICY: ::c_int = 8; + +// +pub const TH_STATE_RUNNING: ::c_int = 1; +pub const TH_STATE_STOPPED: ::c_int = 2; +pub const TH_STATE_WAITING: ::c_int = 3; +pub const TH_STATE_UNINTERRUPTIBLE: ::c_int = 4; +pub const TH_STATE_HALTED: ::c_int = 5; +pub const TH_FLAGS_SWAPPED: ::c_int = 0x1; +pub const TH_FLAGS_IDLE: ::c_int = 0x2; +pub const TH_FLAGS_GLOBAL_FORCED_IDLE: ::c_int = 0x4; +pub const THREAD_BASIC_INFO: ::c_int = 3; +pub const THREAD_IDENTIFIER_INFO: ::c_int = 4; +pub const THREAD_EXTENDED_INFO: ::c_int = 5; + +// CommonCrypto/CommonCryptoError.h +pub const kCCSuccess: i32 = 0; +pub const kCCParamError: i32 = -4300; +pub const kCCBufferTooSmall: i32 = -4301; +pub const kCCMemoryFailure: i32 = -4302; +pub const kCCAlignmentError: i32 = -4303; +pub const kCCDecodeError: i32 = -4304; +pub const kCCUnimplemented: i32 = -4305; +pub const kCCOverflow: i32 = -4306; +pub const kCCRNGFailure: i32 = -4307; +pub const kCCUnspecifiedError: i32 = -4308; +pub const kCCCallSequenceError: i32 = -4309; +pub const kCCKeySizeError: i32 = -4310; +pub const kCCInvalidKey: i32 = -4311; + +// mach/host_info.h +pub const HOST_LOAD_INFO: i32 = 1; +pub const HOST_VM_INFO: i32 = 2; +pub const HOST_CPU_LOAD_INFO: i32 = 3; +pub const HOST_VM_INFO64: i32 = 4; +pub const HOST_EXTMOD_INFO64: i32 = 5; +pub const HOST_EXPIRED_TASK_INFO: i32 = 6; + +// mach/vm_statistics.h +pub const VM_PAGE_QUERY_PAGE_PRESENT: i32 = 0x1; +pub const VM_PAGE_QUERY_PAGE_FICTITIOUS: i32 = 0x2; +pub const VM_PAGE_QUERY_PAGE_REF: i32 = 0x4; +pub const VM_PAGE_QUERY_PAGE_DIRTY: i32 = 0x8; +pub const VM_PAGE_QUERY_PAGE_PAGED_OUT: i32 = 0x10; +pub const VM_PAGE_QUERY_PAGE_COPIED: i32 = 0x20; +pub const VM_PAGE_QUERY_PAGE_SPECULATIVE: i32 = 0x40; +pub const VM_PAGE_QUERY_PAGE_EXTERNAL: i32 = 0x80; +pub const VM_PAGE_QUERY_PAGE_CS_VALIDATED: i32 = 0x100; +pub const VM_PAGE_QUERY_PAGE_CS_TAINTED: i32 = 0x200; +pub const VM_PAGE_QUERY_PAGE_CS_NX: i32 = 0x400; + +// mach/task_info.h +pub const TASK_THREAD_TIMES_INFO: u32 = 3; +pub const HOST_CPU_LOAD_INFO_COUNT: u32 = 4; +pub const MACH_TASK_BASIC_INFO: u32 = 20; + +pub const MACH_PORT_NULL: i32 = 0; + +pub const RUSAGE_INFO_V0: ::c_int = 0; +pub const RUSAGE_INFO_V1: ::c_int = 1; +pub const RUSAGE_INFO_V2: ::c_int = 2; +pub const RUSAGE_INFO_V3: ::c_int = 3; +pub const RUSAGE_INFO_V4: ::c_int = 4; + +// copyfile.h +pub const COPYFILE_ACL: ::copyfile_flags_t = 1 << 0; +pub const COPYFILE_STAT: ::copyfile_flags_t = 1 << 1; +pub const COPYFILE_XATTR: ::copyfile_flags_t = 1 << 2; +pub const COPYFILE_DATA: ::copyfile_flags_t = 1 << 3; +pub const COPYFILE_SECURITY: ::copyfile_flags_t = COPYFILE_STAT | COPYFILE_ACL; +pub const COPYFILE_METADATA: ::copyfile_flags_t = COPYFILE_SECURITY | COPYFILE_XATTR; +pub const COPYFILE_RECURSIVE: ::copyfile_flags_t = 1 << 15; +pub const COPYFILE_CHECK: ::copyfile_flags_t = 1 << 16; +pub const COPYFILE_EXCL: ::copyfile_flags_t = 1 << 17; +pub const COPYFILE_NOFOLLOW_SRC: ::copyfile_flags_t = 1 << 18; +pub const COPYFILE_NOFOLLOW_DST: ::copyfile_flags_t = 1 << 19; +pub const COPYFILE_MOVE: ::copyfile_flags_t = 1 << 20; +pub const COPYFILE_UNLINK: ::copyfile_flags_t = 1 << 21; +pub const COPYFILE_NOFOLLOW: ::copyfile_flags_t = COPYFILE_NOFOLLOW_SRC | COPYFILE_NOFOLLOW_DST; +pub const COPYFILE_PACK: ::copyfile_flags_t = 1 << 22; +pub const COPYFILE_UNPACK: ::copyfile_flags_t = 1 << 23; +pub const COPYFILE_CLONE: ::copyfile_flags_t = 1 << 24; +pub const COPYFILE_CLONE_FORCE: ::copyfile_flags_t = 1 << 25; +pub const COPYFILE_RUN_IN_PLACE: ::copyfile_flags_t = 1 << 26; +pub const COPYFILE_DATA_SPARSE: ::copyfile_flags_t = 1 << 27; +pub const COPYFILE_PRESERVE_DST_TRACKED: ::copyfile_flags_t = 1 << 28; +pub const COPYFILE_VERBOSE: ::copyfile_flags_t = 1 << 30; +pub const COPYFILE_RECURSE_ERROR: ::c_int = 0; +pub const COPYFILE_RECURSE_FILE: ::c_int = 1; +pub const COPYFILE_RECURSE_DIR: ::c_int = 2; +pub const COPYFILE_RECURSE_DIR_CLEANUP: ::c_int = 3; +pub const COPYFILE_COPY_DATA: ::c_int = 4; +pub const COPYFILE_COPY_XATTR: ::c_int = 5; +pub const COPYFILE_START: ::c_int = 1; +pub const COPYFILE_FINISH: ::c_int = 2; +pub const COPYFILE_ERR: ::c_int = 3; +pub const COPYFILE_PROGRESS: ::c_int = 4; +pub const COPYFILE_CONTINUE: ::c_int = 0; +pub const COPYFILE_SKIP: ::c_int = 1; +pub const COPYFILE_QUIT: ::c_int = 2; +pub const COPYFILE_STATE_SRC_FD: ::c_int = 1; +pub const COPYFILE_STATE_SRC_FILENAME: ::c_int = 2; +pub const COPYFILE_STATE_DST_FD: ::c_int = 3; +pub const COPYFILE_STATE_DST_FILENAME: ::c_int = 4; +pub const COPYFILE_STATE_QUARANTINE: ::c_int = 5; +pub const COPYFILE_STATE_STATUS_CB: ::c_int = 6; +pub const COPYFILE_STATE_STATUS_CTX: ::c_int = 7; +pub const COPYFILE_STATE_COPIED: ::c_int = 8; +pub const COPYFILE_STATE_XATTRNAME: ::c_int = 9; +pub const COPYFILE_STATE_WAS_CLONED: ::c_int = 10; +pub const COPYFILE_STATE_SRC_BSIZE: ::c_int = 11; +pub const COPYFILE_STATE_DST_BSIZE: ::c_int = 12; +pub const COPYFILE_STATE_BSIZE: ::c_int = 13; + +// +pub const ATTR_BIT_MAP_COUNT: ::c_ushort = 5; +pub const FSOPT_NOFOLLOW: u32 = 0x1; +pub const FSOPT_NOFOLLOW_ANY: u32 = 0x800; +pub const FSOPT_REPORT_FULLSIZE: u32 = 0x4; +pub const FSOPT_PACK_INVAL_ATTRS: u32 = 0x8; +pub const FSOPT_ATTR_CMN_EXTENDED: u32 = 0x20; +pub const FSOPT_RETURN_REALDEV: u32 = 0x200; +pub const ATTR_CMN_NAME: attrgroup_t = 0x00000001; +pub const ATTR_CMN_DEVID: attrgroup_t = 0x00000002; +pub const ATTR_CMN_FSID: attrgroup_t = 0x00000004; +pub const ATTR_CMN_OBJTYPE: attrgroup_t = 0x00000008; +pub const ATTR_CMN_OBJTAG: attrgroup_t = 0x00000010; +pub const ATTR_CMN_OBJID: attrgroup_t = 0x00000020; +pub const ATTR_CMN_OBJPERMANENTID: attrgroup_t = 0x00000040; +pub const ATTR_CMN_PAROBJID: attrgroup_t = 0x00000080; +pub const ATTR_CMN_SCRIPT: attrgroup_t = 0x00000100; +pub const ATTR_CMN_CRTIME: attrgroup_t = 0x00000200; +pub const ATTR_CMN_MODTIME: attrgroup_t = 0x00000400; +pub const ATTR_CMN_CHGTIME: attrgroup_t = 0x00000800; +pub const ATTR_CMN_ACCTIME: attrgroup_t = 0x00001000; +pub const ATTR_CMN_BKUPTIME: attrgroup_t = 0x00002000; +pub const ATTR_CMN_FNDRINFO: attrgroup_t = 0x00004000; +pub const ATTR_CMN_OWNERID: attrgroup_t = 0x00008000; +pub const ATTR_CMN_GRPID: attrgroup_t = 0x00010000; +pub const ATTR_CMN_ACCESSMASK: attrgroup_t = 0x00020000; +pub const ATTR_CMN_FLAGS: attrgroup_t = 0x00040000; +pub const ATTR_CMN_GEN_COUNT: attrgroup_t = 0x00080000; +pub const ATTR_CMN_DOCUMENT_ID: attrgroup_t = 0x00100000; +pub const ATTR_CMN_USERACCESS: attrgroup_t = 0x00200000; +pub const ATTR_CMN_EXTENDED_SECURITY: attrgroup_t = 0x00400000; +pub const ATTR_CMN_UUID: attrgroup_t = 0x00800000; +pub const ATTR_CMN_GRPUUID: attrgroup_t = 0x01000000; +pub const ATTR_CMN_FILEID: attrgroup_t = 0x02000000; +pub const ATTR_CMN_PARENTID: attrgroup_t = 0x04000000; +pub const ATTR_CMN_FULLPATH: attrgroup_t = 0x08000000; +pub const ATTR_CMN_ADDEDTIME: attrgroup_t = 0x10000000; +pub const ATTR_CMN_DATA_PROTECT_FLAGS: attrgroup_t = 0x40000000; +pub const ATTR_CMN_RETURNED_ATTRS: attrgroup_t = 0x80000000; +pub const ATTR_VOL_FSTYPE: attrgroup_t = 0x00000001; +pub const ATTR_VOL_SIGNATURE: attrgroup_t = 0x00000002; +pub const ATTR_VOL_SIZE: attrgroup_t = 0x00000004; +pub const ATTR_VOL_SPACEFREE: attrgroup_t = 0x00000008; +pub const ATTR_VOL_SPACEAVAIL: attrgroup_t = 0x00000010; +pub const ATTR_VOL_MINALLOCATION: attrgroup_t = 0x00000020; +pub const ATTR_VOL_ALLOCATIONCLUMP: attrgroup_t = 0x00000040; +pub const ATTR_VOL_IOBLOCKSIZE: attrgroup_t = 0x00000080; +pub const ATTR_VOL_OBJCOUNT: attrgroup_t = 0x00000100; +pub const ATTR_VOL_FILECOUNT: attrgroup_t = 0x00000200; +pub const ATTR_VOL_DIRCOUNT: attrgroup_t = 0x00000400; +pub const ATTR_VOL_MAXOBJCOUNT: attrgroup_t = 0x00000800; +pub const ATTR_VOL_MOUNTPOINT: attrgroup_t = 0x00001000; +pub const ATTR_VOL_NAME: attrgroup_t = 0x00002000; +pub const ATTR_VOL_MOUNTFLAGS: attrgroup_t = 0x00004000; +pub const ATTR_VOL_MOUNTEDDEVICE: attrgroup_t = 0x00008000; +pub const ATTR_VOL_ENCODINGSUSED: attrgroup_t = 0x00010000; +pub const ATTR_VOL_CAPABILITIES: attrgroup_t = 0x00020000; +pub const ATTR_VOL_UUID: attrgroup_t = 0x00040000; +pub const ATTR_VOL_SPACEUSED: attrgroup_t = 0x00800000; +pub const ATTR_VOL_QUOTA_SIZE: attrgroup_t = 0x10000000; +pub const ATTR_VOL_RESERVED_SIZE: attrgroup_t = 0x20000000; +pub const ATTR_VOL_ATTRIBUTES: attrgroup_t = 0x40000000; +pub const ATTR_VOL_INFO: attrgroup_t = 0x80000000; +pub const ATTR_DIR_LINKCOUNT: attrgroup_t = 0x00000001; +pub const ATTR_DIR_ENTRYCOUNT: attrgroup_t = 0x00000002; +pub const ATTR_DIR_MOUNTSTATUS: attrgroup_t = 0x00000004; +pub const ATTR_DIR_ALLOCSIZE: attrgroup_t = 0x00000008; +pub const ATTR_DIR_IOBLOCKSIZE: attrgroup_t = 0x00000010; +pub const ATTR_DIR_DATALENGTH: attrgroup_t = 0x00000020; +pub const ATTR_FILE_LINKCOUNT: attrgroup_t = 0x00000001; +pub const ATTR_FILE_TOTALSIZE: attrgroup_t = 0x00000002; +pub const ATTR_FILE_ALLOCSIZE: attrgroup_t = 0x00000004; +pub const ATTR_FILE_IOBLOCKSIZE: attrgroup_t = 0x00000008; +pub const ATTR_FILE_DEVTYPE: attrgroup_t = 0x00000020; +pub const ATTR_FILE_FORKCOUNT: attrgroup_t = 0x00000080; +pub const ATTR_FILE_FORKLIST: attrgroup_t = 0x00000100; +pub const ATTR_FILE_DATALENGTH: attrgroup_t = 0x00000200; +pub const ATTR_FILE_DATAALLOCSIZE: attrgroup_t = 0x00000400; +pub const ATTR_FILE_RSRCLENGTH: attrgroup_t = 0x00001000; +pub const ATTR_FILE_RSRCALLOCSIZE: attrgroup_t = 0x00002000; +pub const ATTR_CMNEXT_RELPATH: attrgroup_t = 0x00000004; +pub const ATTR_CMNEXT_PRIVATESIZE: attrgroup_t = 0x00000008; +pub const ATTR_CMNEXT_LINKID: attrgroup_t = 0x00000010; +pub const ATTR_CMNEXT_NOFIRMLINKPATH: attrgroup_t = 0x00000020; +pub const ATTR_CMNEXT_REALDEVID: attrgroup_t = 0x00000040; +pub const ATTR_CMNEXT_REALFSID: attrgroup_t = 0x00000080; +pub const ATTR_CMNEXT_CLONEID: attrgroup_t = 0x00000100; +pub const ATTR_CMNEXT_EXT_FLAGS: attrgroup_t = 0x00000200; +pub const ATTR_CMNEXT_RECURSIVE_GENCOUNT: attrgroup_t = 0x00000400; +pub const DIR_MNTSTATUS_MNTPOINT: u32 = 0x1; +pub const VOL_CAPABILITIES_FORMAT: usize = 0; +pub const VOL_CAPABILITIES_INTERFACES: usize = 1; +pub const VOL_CAP_FMT_PERSISTENTOBJECTIDS: attrgroup_t = 0x00000001; +pub const VOL_CAP_FMT_SYMBOLICLINKS: attrgroup_t = 0x00000002; +pub const VOL_CAP_FMT_HARDLINKS: attrgroup_t = 0x00000004; +pub const VOL_CAP_FMT_JOURNAL: attrgroup_t = 0x00000008; +pub const VOL_CAP_FMT_JOURNAL_ACTIVE: attrgroup_t = 0x00000010; +pub const VOL_CAP_FMT_NO_ROOT_TIMES: attrgroup_t = 0x00000020; +pub const VOL_CAP_FMT_SPARSE_FILES: attrgroup_t = 0x00000040; +pub const VOL_CAP_FMT_ZERO_RUNS: attrgroup_t = 0x00000080; +pub const VOL_CAP_FMT_CASE_SENSITIVE: attrgroup_t = 0x00000100; +pub const VOL_CAP_FMT_CASE_PRESERVING: attrgroup_t = 0x00000200; +pub const VOL_CAP_FMT_FAST_STATFS: attrgroup_t = 0x00000400; +pub const VOL_CAP_FMT_2TB_FILESIZE: attrgroup_t = 0x00000800; +pub const VOL_CAP_FMT_OPENDENYMODES: attrgroup_t = 0x00001000; +pub const VOL_CAP_FMT_HIDDEN_FILES: attrgroup_t = 0x00002000; +pub const VOL_CAP_FMT_PATH_FROM_ID: attrgroup_t = 0x00004000; +pub const VOL_CAP_FMT_NO_VOLUME_SIZES: attrgroup_t = 0x00008000; +pub const VOL_CAP_FMT_DECMPFS_COMPRESSION: attrgroup_t = 0x00010000; +pub const VOL_CAP_FMT_64BIT_OBJECT_IDS: attrgroup_t = 0x00020000; +pub const VOL_CAP_FMT_DIR_HARDLINKS: attrgroup_t = 0x00040000; +pub const VOL_CAP_FMT_DOCUMENT_ID: attrgroup_t = 0x00080000; +pub const VOL_CAP_FMT_WRITE_GENERATION_COUNT: attrgroup_t = 0x00100000; +pub const VOL_CAP_FMT_NO_IMMUTABLE_FILES: attrgroup_t = 0x00200000; +pub const VOL_CAP_FMT_NO_PERMISSIONS: attrgroup_t = 0x00400000; +pub const VOL_CAP_FMT_SHARED_SPACE: attrgroup_t = 0x00800000; +pub const VOL_CAP_FMT_VOL_GROUPS: attrgroup_t = 0x01000000; +pub const VOL_CAP_FMT_SEALED: attrgroup_t = 0x02000000; +pub const VOL_CAP_INT_SEARCHFS: attrgroup_t = 0x00000001; +pub const VOL_CAP_INT_ATTRLIST: attrgroup_t = 0x00000002; +pub const VOL_CAP_INT_NFSEXPORT: attrgroup_t = 0x00000004; +pub const VOL_CAP_INT_READDIRATTR: attrgroup_t = 0x00000008; +pub const VOL_CAP_INT_EXCHANGEDATA: attrgroup_t = 0x00000010; +pub const VOL_CAP_INT_COPYFILE: attrgroup_t = 0x00000020; +pub const VOL_CAP_INT_ALLOCATE: attrgroup_t = 0x00000040; +pub const VOL_CAP_INT_VOL_RENAME: attrgroup_t = 0x00000080; +pub const VOL_CAP_INT_ADVLOCK: attrgroup_t = 0x00000100; +pub const VOL_CAP_INT_FLOCK: attrgroup_t = 0x00000200; +pub const VOL_CAP_INT_EXTENDED_SECURITY: attrgroup_t = 0x00000400; +pub const VOL_CAP_INT_USERACCESS: attrgroup_t = 0x00000800; +pub const VOL_CAP_INT_MANLOCK: attrgroup_t = 0x00001000; +pub const VOL_CAP_INT_NAMEDSTREAMS: attrgroup_t = 0x00002000; +pub const VOL_CAP_INT_EXTENDED_ATTR: attrgroup_t = 0x00004000; +pub const VOL_CAP_INT_CLONE: attrgroup_t = 0x00010000; +pub const VOL_CAP_INT_SNAPSHOT: attrgroup_t = 0x00020000; +pub const VOL_CAP_INT_RENAME_SWAP: attrgroup_t = 0x00040000; +pub const VOL_CAP_INT_RENAME_EXCL: attrgroup_t = 0x00080000; +pub const VOL_CAP_INT_RENAME_OPENFAIL: attrgroup_t = 0x00100000; + +// +/// Process being created by fork. +pub const SIDL: u32 = 1; +/// Currently runnable. +pub const SRUN: u32 = 2; +/// Sleeping on an address. +pub const SSLEEP: u32 = 3; +/// Process debugging or suspension. +pub const SSTOP: u32 = 4; +/// Awaiting collection by parent. +pub const SZOMB: u32 = 5; + +// sys/vsock.h +pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF; +pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0; +pub const VMADDR_CID_RESERVED: ::c_uint = 1; +pub const VMADDR_CID_HOST: ::c_uint = 2; +pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF; + +cfg_if! { + if #[cfg(libc_const_extern_fn)] { + const fn __DARWIN_ALIGN32(p: usize) -> usize { + const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } + } else if #[cfg(libc_const_size_of)] { + fn __DARWIN_ALIGN32(p: usize) -> usize { + const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } + } else { + fn __DARWIN_ALIGN32(p: usize) -> usize { + let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } + } +} + +cfg_if! { + if #[cfg(libc_const_size_of)] { + pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_TIME_CONSTRAINT_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / + ::mem::size_of::()) as mach_msg_type_number_t; + pub const THREAD_PRECEDENCE_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_AFFINITY_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_BACKGROUND_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_LATENCY_QOS_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_THROUGHPUT_QOS_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / + ::mem::size_of::()) as mach_msg_type_number_t; + pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_EXTENDED_INFO_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + + pub const TASK_THREAD_TIMES_INFO_COUNT: u32 = + (::mem::size_of::() + / ::mem::size_of::()) as u32; + pub const MACH_TASK_BASIC_INFO_COUNT: u32 = (::mem::size_of::() + / ::mem::size_of::()) as u32; + pub const HOST_VM_INFO64_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + } else { + pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_TIME_CONSTRAINT_POLICY_COUNT: mach_msg_type_number_t = 4; + pub const THREAD_PRECEDENCE_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_AFFINITY_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_BACKGROUND_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_LATENCY_QOS_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_THROUGHPUT_QOS_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = 10; + pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = 6; + pub const THREAD_EXTENDED_INFO_COUNT: mach_msg_type_number_t = 28; + pub const TASK_THREAD_TIMES_INFO_COUNT: u32 = 4; + pub const MACH_TASK_BASIC_INFO_COUNT: u32 = 12; + pub const HOST_VM_INFO64_COUNT: mach_msg_type_number_t = 38; + } +} + +f! { + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, + cmsg: *const ::cmsghdr) -> *mut ::cmsghdr { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let cmsg_len = (*cmsg).cmsg_len as usize; + let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next + __DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) > max { + 0 as *mut ::cmsghdr + } else { + next as *mut ::cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + + __DARWIN_ALIGN32(length as usize)) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + length as usize) + as ::c_uint + } + + pub {const} fn VM_MAKE_TAG(id: u8) -> u32 { + (id as u32) << 24u32 + } + + pub fn major(dev: dev_t) -> i32 { + (dev >> 24) & 0xff + } + + pub fn minor(dev: dev_t) -> i32 { + dev & 0xffffff + } + + pub fn makedev(major: i32, minor: i32) -> dev_t { + (major << 24) | minor + } +} + +safe_f! { + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn _WSTATUS(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + _WSTATUS(status) == _WSTOPPED && WSTOPSIG(status) == 0x13 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + _WSTATUS(status) == _WSTOPPED && WSTOPSIG(status) != 0x13 + } +} + +extern "C" { + pub fn setgrent(); + #[doc(hidden)] + #[deprecated(since = "0.2.49", note = "Deprecated in MacOSX 10.5")] + #[cfg_attr(not(target_arch = "aarch64"), link_name = "daemon$1050")] + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + #[doc(hidden)] + #[deprecated(since = "0.2.49", note = "Deprecated in MacOSX 10.10")] + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + #[doc(hidden)] + #[deprecated(since = "0.2.49", note = "Deprecated in MacOSX 10.10")] + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "aio_suspend$UNIX2003" + )] + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn chflags(path: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn fchflags(fd: ::c_int, flags: ::c_uint) -> ::c_int; + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "confstr$UNIX2003" + )] + pub fn confstr(name: ::c_int, buf: *mut ::c_char, len: ::size_t) -> ::size_t; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; + + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + + pub fn asctime(tm: *const ::tm) -> *mut ::c_char; + pub fn ctime(clock: *const time_t) -> *mut ::c_char; + pub fn getdate(datestr: *const ::c_char) -> *mut ::tm; + pub fn strptime( + buf: *const ::c_char, + format: *const ::c_char, + timeptr: *mut ::tm, + ) -> *mut ::c_char; + pub fn asctime_r(tm: *const ::tm, result: *mut ::c_char) -> *mut ::c_char; + pub fn ctime_r(clock: *const time_t, result: *mut ::c_char) -> *mut ::c_char; + + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + pub fn sysctlnametomib( + name: *const ::c_char, + mibp: *mut ::c_int, + sizep: *mut ::size_t, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "mprotect$UNIX2003" + )] + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn semget(key: key_t, nsems: ::c_int, semflg: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "semctl$UNIX2003" + )] + pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn ftok(pathname: *const c_char, proj_id: ::c_int) -> key_t; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "shmctl$UNIX2003" + )] + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn shmget(key: key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlbyname( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn mach_absolute_time() -> u64; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + #[allow(deprecated)] + pub fn mach_timebase_info(info: *mut ::mach_timebase_info) -> ::c_int; + pub fn mach_host_self() -> mach_port_t; + pub fn mach_thread_self() -> mach_port_t; + pub fn pthread_setname_np(name: *const ::c_char) -> ::c_int; + pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_mach_thread_np(thread: ::pthread_t) -> ::mach_port_t; + pub fn pthread_from_mach_thread_np(port: ::mach_port_t) -> ::pthread_t; + pub fn pthread_create_from_mach_thread( + thread: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_stack_frame_decode_np( + frame_addr: ::uintptr_t, + return_addr: *mut ::uintptr_t, + ) -> ::uintptr_t; + pub fn pthread_get_stackaddr_np(thread: ::pthread_t) -> *mut ::c_void; + pub fn pthread_get_stacksize_np(thread: ::pthread_t) -> ::size_t; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_main_np() -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; + pub fn pthread_threadid_np(thread: ::pthread_t, thread_id: *mut u64) -> ::c_int; + pub fn pthread_attr_set_qos_class_np( + attr: *mut pthread_attr_t, + class: qos_class_t, + priority: ::c_int, + ) -> ::c_int; + pub fn pthread_attr_get_qos_class_np( + attr: *mut pthread_attr_t, + class: *mut qos_class_t, + priority: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_set_qos_class_self_np(class: qos_class_t, priority: ::c_int) -> ::c_int; + pub fn pthread_get_qos_class_np( + thread: ::pthread_t, + class: *mut qos_class_t, + priority: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_getschedparam( + attr: *const ::pthread_attr_t, + param: *mut sched_param, + ) -> ::c_int; + pub fn pthread_attr_setschedparam( + attr: *mut ::pthread_attr_t, + param: *const sched_param, + ) -> ::c_int; + pub fn pthread_getschedparam( + thread: ::pthread_t, + policy: *mut ::c_int, + param: *mut sched_param, + ) -> ::c_int; + pub fn pthread_setschedparam( + thread: ::pthread_t, + policy: ::c_int, + param: *const sched_param, + ) -> ::c_int; + + // Available from Big Sur + pub fn pthread_introspection_hook_install( + hook: ::pthread_introspection_hook_t, + ) -> ::pthread_introspection_hook_t; + pub fn pthread_introspection_setspecific_np( + thread: ::pthread_t, + key: ::pthread_key_t, + value: *const ::c_void, + ) -> ::c_int; + pub fn pthread_introspection_getspecific_np( + thread: ::pthread_t, + key: ::pthread_key_t, + ) -> *mut ::c_void; + pub fn pthread_jit_write_protect_np(enabled: ::c_int); + pub fn pthread_jit_write_protect_supported_np() -> ::c_int; + // An array of pthread_jit_write_with_callback_np must declare + // the list of callbacks e.g. + // #[link_section = "__DATA_CONST,__pth_jit_func"] + // static callbacks: [libc::pthread_jit_write_callback_t; 2] = [native_jit_write_cb, + // std::mem::transmute::(std::ptr::null())]; + // (a handy PTHREAD_JIT_WRITE_CALLBACK_NP macro for other languages). + pub fn pthread_jit_write_with_callback_np( + callback: ::pthread_jit_write_callback_t, + ctx: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_jit_write_freeze_callbacks_np(); + pub fn pthread_cpu_number_np(cpu_number_out: *mut ::size_t) -> ::c_int; + + pub fn os_unfair_lock_lock(lock: os_unfair_lock_t); + pub fn os_unfair_lock_trylock(lock: os_unfair_lock_t) -> bool; + pub fn os_unfair_lock_unlock(lock: os_unfair_lock_t); + pub fn os_unfair_lock_assert_owner(lock: os_unfair_lock_t); + pub fn os_unfair_lock_assert_not_owner(lock: os_unfair_lock_t); + + pub fn os_log_create(subsystem: *const ::c_char, category: *const ::c_char) -> ::os_log_t; + pub fn os_log_type_enabled(oslog: ::os_log_t, tpe: ::os_log_type_t) -> bool; + pub fn os_signpost_id_make_with_pointer( + log: ::os_log_t, + ptr: *const ::c_void, + ) -> ::os_signpost_id_t; + pub fn os_signpost_id_generate(log: ::os_log_t) -> ::os_signpost_id_t; + pub fn os_signpost_enabled(log: ::os_log_t) -> bool; + + pub fn thread_policy_set( + thread: thread_t, + flavor: thread_policy_flavor_t, + policy_info: thread_policy_t, + count: mach_msg_type_number_t, + ) -> kern_return_t; + pub fn thread_policy_get( + thread: thread_t, + flavor: thread_policy_flavor_t, + policy_info: thread_policy_t, + count: *mut mach_msg_type_number_t, + get_default: *mut boolean_t, + ) -> kern_return_t; + pub fn thread_info( + target_act: thread_inspect_t, + flavor: thread_flavor_t, + thread_info_out: thread_info_t, + thread_info_outCnt: *mut mach_msg_type_number_t, + ) -> kern_return_t; + #[cfg_attr(doc, doc(alias = "__errno_location"))] + #[cfg_attr(doc, doc(alias = "errno"))] + pub fn __error() -> *mut ::c_int; + pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int; + pub fn backtrace_symbols(addrs: *const *mut ::c_void, sz: ::c_int) -> *mut *mut ::c_char; + pub fn backtrace_symbols_fd(addrs: *const *mut ::c_void, sz: ::c_int, fd: ::c_int); + pub fn backtrace_from_fp( + startfp: *mut ::c_void, + array: *mut *mut ::c_void, + size: ::c_int, + ) -> ::c_int; + pub fn backtrace_image_offsets( + array: *const *mut ::c_void, + image_offsets: *mut image_offset, + size: ::c_int, + ); + pub fn backtrace_async( + array: *mut *mut ::c_void, + length: ::size_t, + task_id: *mut u32, + ) -> ::size_t; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "statfs$INODE64" + )] + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "fstatfs$INODE64" + )] + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::c_int, + eventlist: *mut ::kevent, + nevents: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn kevent64( + kq: ::c_int, + changelist: *const ::kevent64_s, + nchanges: ::c_int, + eventlist: *mut ::kevent64_s, + nevents: ::c_int, + flags: ::c_uint, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + flags: ::c_int, + data: *mut ::c_void, + ) -> ::c_int; + pub fn fmount( + src: *const ::c_char, + fd: ::c_int, + flags: ::c_int, + data: *mut ::c_void, + ) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_char, data: ::c_int) -> ::c_int; + pub fn quotactl( + special: *const ::c_char, + cmd: ::c_int, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn sendfile( + fd: ::c_int, + s: ::c_int, + offset: ::off_t, + len: *mut ::off_t, + hdtr: *mut ::sf_hdtr, + flags: ::c_int, + ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t) -> ::c_int; + pub fn localeconv_l(loc: ::locale_t) -> *mut lconv; + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn querylocale(mask: ::c_int, loc: ::locale_t) -> *const ::c_char; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn getxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::ssize_t; + pub fn fgetxattr( + filedes: ::c_int, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::ssize_t; + pub fn setxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::c_int; + pub fn fsetxattr( + filedes: ::c_int, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::c_int; + pub fn listxattr( + path: *const ::c_char, + list: *mut ::c_char, + size: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn flistxattr( + filedes: ::c_int, + list: *mut ::c_char, + size: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn removexattr(path: *const ::c_char, name: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn renamex_np(from: *const ::c_char, to: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn renameatx_np( + fromfd: ::c_int, + from: *const ::c_char, + tofd: ::c_int, + to: *const ::c_char, + flags: ::c_uint, + ) -> ::c_int; + pub fn fremovexattr(filedes: ::c_int, name: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn getgrouplist( + name: *const ::c_char, + basegid: ::c_int, + groups: *mut ::c_int, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn initgroups(user: *const ::c_char, basegroup: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "waitid$UNIX2003" + )] + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + pub fn brk(addr: *const ::c_void) -> *mut ::c_void; + pub fn sbrk(increment: ::c_int) -> *mut ::c_void; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn _dyld_image_count() -> u32; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + #[allow(deprecated)] + pub fn _dyld_get_image_header(image_index: u32) -> *const mach_header; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn _dyld_get_image_vmaddr_slide(image_index: u32) -> ::intptr_t; + #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn _dyld_get_image_name(image_index: u32) -> *const ::c_char; + + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_setarchpref_np( + attr: *mut posix_spawnattr_t, + count: ::size_t, + pref: *mut ::cpu_type_t, + subpref: *mut ::cpu_subtype_t, + ocount: *mut ::size_t, + ) -> ::c_int; + pub fn posix_spawnattr_getarchpref_np( + attr: *const posix_spawnattr_t, + count: ::size_t, + pref: *mut ::cpu_type_t, + subpref: *mut ::cpu_subtype_t, + ocount: *mut ::size_t, + ) -> ::c_int; + pub fn posix_spawnattr_getbinpref_np( + attr: *const posix_spawnattr_t, + count: ::size_t, + pref: *mut ::cpu_type_t, + ocount: *mut ::size_t, + ) -> ::c_int; + pub fn posix_spawnattr_setbinpref_np( + attr: *mut posix_spawnattr_t, + count: ::size_t, + pref: *mut ::cpu_type_t, + ocount: *mut ::size_t, + ) -> ::c_int; + pub fn posix_spawnattr_set_qos_class_np( + attr: *mut posix_spawnattr_t, + qos_class: ::qos_class_t, + ) -> ::c_int; + pub fn posix_spawnattr_get_qos_class_np( + attr: *const posix_spawnattr_t, + qos_class: *mut ::qos_class_t, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + pub fn connectx( + socket: ::c_int, + endpoints: *const sa_endpoints_t, + associd: sae_associd_t, + flags: ::c_uint, + iov: *const ::iovec, + iovcnt: ::c_uint, + len: *mut ::size_t, + connid: *mut sae_connid_t, + ) -> ::c_int; + pub fn disconnectx(socket: ::c_int, associd: sae_associd_t, connid: sae_connid_t) -> ::c_int; + + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "getmntinfo$INODE64" + )] + pub fn getmntinfo(mntbufp: *mut *mut statfs, flags: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "getfsstat$INODE64" + )] + pub fn getfsstat(mntbufp: *mut statfs, bufsize: ::c_int, flags: ::c_int) -> ::c_int; + + // Copy-on-write functions. + // According to the man page `flags` is an `int` but in the header + // this is a `uint32_t`. + pub fn clonefile(src: *const ::c_char, dst: *const ::c_char, flags: u32) -> ::c_int; + pub fn clonefileat( + src_dirfd: ::c_int, + src: *const ::c_char, + dst_dirfd: ::c_int, + dst: *const ::c_char, + flags: u32, + ) -> ::c_int; + pub fn fclonefileat( + srcfd: ::c_int, + dst_dirfd: ::c_int, + dst: *const ::c_char, + flags: u32, + ) -> ::c_int; + + pub fn copyfile( + from: *const ::c_char, + to: *const ::c_char, + state: copyfile_state_t, + flags: copyfile_flags_t, + ) -> ::c_int; + pub fn fcopyfile( + from: ::c_int, + to: ::c_int, + state: copyfile_state_t, + flags: copyfile_flags_t, + ) -> ::c_int; + pub fn copyfile_state_free(s: copyfile_state_t) -> ::c_int; + pub fn copyfile_state_alloc() -> copyfile_state_t; + pub fn copyfile_state_get(s: copyfile_state_t, flags: u32, dst: *mut ::c_void) -> ::c_int; + pub fn copyfile_state_set(s: copyfile_state_t, flags: u32, src: *const ::c_void) -> ::c_int; + + // Added in macOS 10.13 + // ISO/IEC 9899:2011 ("ISO C11") K.3.7.4.1 + pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; + // Added in macOS 10.5 + pub fn memset_pattern4(b: *mut ::c_void, pattern4: *const ::c_void, len: ::size_t); + pub fn memset_pattern8(b: *mut ::c_void, pattern8: *const ::c_void, len: ::size_t); + pub fn memset_pattern16(b: *mut ::c_void, pattern16: *const ::c_void, len: ::size_t); + + // Inherited from BSD but available from Big Sur only + pub fn strtonum( + __numstr: *const ::c_char, + __minval: ::c_longlong, + __maxval: ::c_longlong, + errstrp: *mut *const ::c_char, + ) -> ::c_longlong; + + pub fn mstats() -> mstats; + pub fn malloc_printf(format: *const ::c_char, ...); + pub fn malloc_zone_check(zone: *mut ::malloc_zone_t) -> ::boolean_t; + pub fn malloc_zone_print(zone: *mut ::malloc_zone_t, verbose: ::boolean_t); + pub fn malloc_zone_statistics(zone: *mut ::malloc_zone_t, stats: *mut malloc_statistics_t); + pub fn malloc_zone_log(zone: *mut ::malloc_zone_t, address: *mut ::c_void); + pub fn malloc_zone_print_ptr_info(ptr: *mut ::c_void); + pub fn malloc_default_zone() -> *mut ::malloc_zone_t; + pub fn malloc_zone_from_ptr(ptr: *const ::c_void) -> *mut ::malloc_zone_t; + pub fn malloc_zone_malloc(zone: *mut ::malloc_zone_t, size: ::size_t) -> *mut ::c_void; + pub fn malloc_zone_valloc(zone: *mut ::malloc_zone_t, size: ::size_t) -> *mut ::c_void; + pub fn malloc_zone_calloc( + zone: *mut ::malloc_zone_t, + num_items: ::size_t, + size: ::size_t, + ) -> *mut ::c_void; + pub fn malloc_zone_realloc( + zone: *mut ::malloc_zone_t, + ptr: *mut ::c_void, + size: ::size_t, + ) -> *mut ::c_void; + pub fn malloc_zone_free(zone: *mut ::malloc_zone_t, ptr: *mut ::c_void); + + pub fn proc_listpids( + t: u32, + typeinfo: u32, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_listallpids(buffer: *mut ::c_void, buffersize: ::c_int) -> ::c_int; + pub fn proc_listpgrppids( + pgrpid: ::pid_t, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_listchildpids(ppid: ::pid_t, buffer: *mut ::c_void, buffersize: ::c_int) + -> ::c_int; + pub fn proc_pidinfo( + pid: ::c_int, + flavor: ::c_int, + arg: u64, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_pidfdinfo( + pid: ::c_int, + fd: ::c_int, + flavor: ::c_int, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_pidfileportinfo( + pid: ::c_int, + fileport: u32, + flavor: ::c_int, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_pidpath(pid: ::c_int, buffer: *mut ::c_void, buffersize: u32) -> ::c_int; + pub fn proc_name(pid: ::c_int, buffer: *mut ::c_void, buffersize: u32) -> ::c_int; + pub fn proc_regionfilename( + pid: ::c_int, + address: u64, + buffer: *mut ::c_void, + buffersize: u32, + ) -> ::c_int; + pub fn proc_kmsgbuf(buffer: *mut ::c_void, buffersize: u32) -> ::c_int; + pub fn proc_libversion(major: *mut ::c_int, minor: *mut ::c_int) -> ::c_int; + pub fn proc_pid_rusage(pid: ::c_int, flavor: ::c_int, buffer: *mut rusage_info_t) -> ::c_int; + + // Available from Big Sur + pub fn proc_set_no_smt() -> ::c_int; + pub fn proc_setthread_no_smt() -> ::c_int; + pub fn proc_set_csm(flags: u32) -> ::c_int; + pub fn proc_setthread_csm(flags: u32) -> ::c_int; + /// # Notes + /// + /// `id` is of type [`uuid_t`]. + pub fn gethostuuid(id: *mut u8, timeout: *const ::timespec) -> ::c_int; + + pub fn gethostid() -> ::c_long; + pub fn sethostid(hostid: ::c_long); + + pub fn CCRandomGenerateBytes(bytes: *mut ::c_void, size: ::size_t) -> ::CCRNGStatus; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + + pub fn _NSGetExecutablePath(buf: *mut ::c_char, bufsize: *mut u32) -> ::c_int; + pub fn _NSGetEnviron() -> *mut *mut *mut ::c_char; + + pub fn mach_vm_map( + target_task: ::vm_map_t, + address: *mut ::mach_vm_address_t, + size: ::mach_vm_size_t, + mask: ::mach_vm_offset_t, + flags: ::c_int, + object: ::mem_entry_name_port_t, + offset: ::memory_object_offset_t, + copy: ::boolean_t, + cur_protection: ::vm_prot_t, + max_protection: ::vm_prot_t, + inheritance: ::vm_inherit_t, + ) -> ::kern_return_t; + + pub fn vm_allocate( + target_task: vm_map_t, + address: *mut vm_address_t, + size: vm_size_t, + flags: ::c_int, + ) -> ::kern_return_t; + + pub fn vm_deallocate( + target_task: vm_map_t, + address: vm_address_t, + size: vm_size_t, + ) -> ::kern_return_t; + + pub fn host_statistics64( + host_priv: host_t, + flavor: host_flavor_t, + host_info64_out: host_info64_t, + host_info64_outCnt: *mut mach_msg_type_number_t, + ) -> ::kern_return_t; + pub fn host_processor_info( + host: host_t, + flavor: processor_flavor_t, + out_processor_count: *mut natural_t, + out_processor_info: *mut processor_info_array_t, + out_processor_infoCnt: *mut mach_msg_type_number_t, + ) -> ::kern_return_t; + + pub static mut mach_task_self_: ::mach_port_t; + pub fn task_for_pid( + host: ::mach_port_t, + pid: ::pid_t, + task: *mut ::mach_port_t, + ) -> ::kern_return_t; + pub fn task_info( + host: ::mach_port_t, + flavor: task_flavor_t, + task_info_out: task_info_t, + task_info_count: *mut mach_msg_type_number_t, + ) -> ::kern_return_t; + pub fn task_create( + target_task: ::task_t, + ledgers: ::ledger_array_t, + ledgersCnt: ::mach_msg_type_number_t, + inherit_memory: ::boolean_t, + child_task: *mut ::task_t, + ) -> ::kern_return_t; + pub fn task_terminate(target_task: ::task_t) -> ::kern_return_t; + pub fn task_threads( + target_task: ::task_inspect_t, + act_list: *mut ::thread_act_array_t, + act_listCnt: *mut ::mach_msg_type_number_t, + ) -> ::kern_return_t; + pub fn host_statistics( + host_priv: host_t, + flavor: host_flavor_t, + host_info_out: host_info_t, + host_info_outCnt: *mut mach_msg_type_number_t, + ) -> ::kern_return_t; + + // sysdir.h + pub fn sysdir_start_search_path_enumeration( + dir: sysdir_search_path_directory_t, + domainMask: sysdir_search_path_domain_mask_t, + ) -> ::sysdir_search_path_enumeration_state; + pub fn sysdir_get_next_search_path_enumeration( + state: ::sysdir_search_path_enumeration_state, + path: *mut ::c_char, + ) -> ::sysdir_search_path_enumeration_state; + + pub static vm_page_size: vm_size_t; + + pub fn getattrlist( + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn fgetattrlist( + fd: ::c_int, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn getattrlistat( + fd: ::c_int, + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: ::c_ulong, + ) -> ::c_int; + pub fn setattrlist( + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn fsetattrlist( + fd: ::c_int, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn setattrlistat( + dir_fd: ::c_int, + path: *const ::c_char, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u32, + ) -> ::c_int; + pub fn getattrlistbulk( + dirfd: ::c_int, + attrList: *mut ::c_void, + attrBuf: *mut ::c_void, + attrBufSize: ::size_t, + options: u64, + ) -> ::c_int; + + pub fn malloc_size(ptr: *const ::c_void) -> ::size_t; + pub fn malloc_good_size(size: ::size_t) -> ::size_t; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn freadlink(fd: ::c_int, buf: *mut ::c_char, size: ::size_t) -> ::c_int; + pub fn execvP( + file: *const ::c_char, + search_path: *const ::c_char, + argv: *const *mut ::c_char, + ) -> ::c_int; +} + +pub unsafe fn mach_task_self() -> ::mach_port_t { + mach_task_self_ +} + +cfg_if! { + if #[cfg(target_os = "macos")] { + extern "C" { + pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + } + } +} +cfg_if! { + if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))] { + extern "C" { + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn task_set_info(target_task: ::task_t, + flavor: ::task_flavor_t, + task_info_in: ::task_info_t, + task_info_inCnt: ::mach_msg_type_number_t + ) -> ::kern_return_t; + } + } +} + +// These require a dependency on `libiconv`, and including this when built as +// part of `std` means every Rust program gets it. Ideally we would have a link +// modifier to only include these if they are used, but we do not. +#[cfg_attr(not(feature = "rustc-dep-of-std"), link(name = "iconv"))] +extern "C" { + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod b32; + pub use self::b32::*; + } else if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_long_array)] { + mod long_array; + pub use self::long_array::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs new file mode 100644 index 00000000..5fe6bb89 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs @@ -0,0 +1,13 @@ +// DragonFlyBSD's __error function is declared with "static inline", so it must +// be implemented in the libc crate, as a pointer to a static thread_local. +f! { + #[deprecated(since = "0.2.77", note = "Use `__errno_location()` instead")] + pub fn __error() -> *mut ::c_int { + &mut errno + } +} + +extern "C" { + #[thread_local] + pub static mut errno: ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs new file mode 100644 index 00000000..6ade7949 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -0,0 +1,1732 @@ +pub type dev_t = u32; +pub type c_char = i8; +pub type wchar_t = i32; +pub type clock_t = u64; +pub type ino_t = u64; +pub type lwpid_t = i32; +pub type nlink_t = u32; +pub type blksize_t = i64; +pub type clockid_t = ::c_ulong; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type time_t = i64; +pub type suseconds_t = i64; + +pub type uuid_t = ::uuid; + +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type idtype_t = ::c_uint; +pub type shmatt_t = ::c_uint; + +pub type mqd_t = ::c_int; +pub type sem_t = *mut sem; + +pub type cpuset_t = cpumask_t; +pub type cpu_set_t = cpumask_t; + +pub type register_t = ::c_long; +pub type umtx_t = ::c_int; +pub type pthread_barrierattr_t = ::c_int; +pub type pthread_barrier_t = ::uintptr_t; +pub type pthread_spinlock_t = ::uintptr_t; + +pub type segsz_t = usize; + +pub type vm_prot_t = u8; +pub type vm_maptype_t = u8; +pub type vm_inherit_t = i8; +pub type vm_subsys_t = ::c_int; +pub type vm_eflags_t = ::c_uint; + +pub type vm_map_t = *mut __c_anonymous_vm_map; +pub type vm_map_entry_t = *mut vm_map_entry; + +pub type pmap = __c_anonymous_pmap; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum sem {} +impl ::Copy for sem {} +impl ::Clone for sem { + fn clone(&self) -> sem { + *self + } +} + +e! { + #[repr(u32)] + pub enum lwpstat { + LSRUN = 1, + LSSTOP = 2, + LSSLEEP = 3, + } + + #[repr(u32)] + pub enum procstat { + SIDL = 1, + SACTIVE = 2, + SSTOP = 3, + SZOMB = 4, + SCORE = 5, + } +} + +s! { + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + pub struct exit_status { + pub e_termination: u16, + pub e_exit: u16 + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: sigevent, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + _aio_val: ::c_int, + _aio_err: ::c_int + } + + pub struct uuid { + pub time_low: u32, + pub time_mid: u16, + pub time_hi_and_version: u16, + pub clock_seq_hi_and_reserved: u8, + pub clock_seq_low: u8, + pub node: [u8; 6], + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_owner: ::uid_t, + pub f_type: ::c_uint, + pub f_syncreads: u64, + pub f_syncwrites: u64, + pub f_asyncreads: u64, + pub f_asyncwrites: u64, + pub f_fsid_uuid: ::uuid_t, + pub f_uid_uuid: ::uuid_t, + } + + pub struct stat { + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_dev: ::dev_t, + pub st_mode: ::mode_t, + pub st_padding1: u16, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: i64, + pub __old_st_blksize: u32, + pub st_flags: u32, + pub st_gen: u32, + pub st_lspare: i32, + pub st_blksize: i64, + pub st_qspare2: i64, + } + + pub struct if_data { + pub ifi_type: ::c_uchar, + pub ifi_physical: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_recvquota: ::c_uchar, + pub ifi_xmitquota: ::c_uchar, + pub ifi_mtu: ::c_ulong, + pub ifi_metric: ::c_ulong, + pub ifi_link_state: ::c_ulong, + pub ifi_baudrate: u64, + pub ifi_ipackets: ::c_ulong, + pub ifi_ierrors: ::c_ulong, + pub ifi_opackets: ::c_ulong, + pub ifi_oerrors: ::c_ulong, + pub ifi_collisions: ::c_ulong, + pub ifi_ibytes: ::c_ulong, + pub ifi_obytes: ::c_ulong, + pub ifi_imcasts: ::c_ulong, + pub ifi_omcasts: ::c_ulong, + pub ifi_iqdrops: ::c_ulong, + pub ifi_noproto: ::c_ulong, + pub ifi_hwassist: ::c_ulong, + pub ifi_oqdrops: ::c_ulong, + pub ifi_lastchange: ::timeval, + } + + pub struct if_msghdr { + pub ifm_msglen: ::c_ushort, + pub ifm_version: ::c_uchar, + pub ifm_type: ::c_uchar, + pub ifm_addrs: ::c_int, + pub ifm_flags: ::c_int, + pub ifm_index: ::c_ushort, + pub ifm_data: if_data, + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 12], + pub sdl_rcf: ::c_ushort, + pub sdl_route: [::c_ushort; 16], + } + + pub struct xucred { + pub cr_version: ::c_uint, + pub cr_uid: ::uid_t, + pub cr_ngroups: ::c_short, + pub cr_groups: [::gid_t; 16], + __cr_unused1: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct cpumask_t { + ary: [u64; 4], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + shm_internal: *mut ::c_void, + } + + pub struct kinfo_file { + pub f_size: ::size_t, + pub f_pid: ::pid_t, + pub f_uid: ::uid_t, + pub f_fd: ::c_int, + pub f_file: *mut ::c_void, + pub f_type: ::c_short, + pub f_count: ::c_int, + pub f_msgcount: ::c_int, + pub f_offset: ::off_t, + pub f_data: *mut ::c_void, + pub f_flag: ::c_uint, + } + + pub struct kinfo_cputime { + pub cp_user: u64, + pub cp_nice: u64, + pub cp_sys: u64, + pub cp_intr: u64, + pub cp_idel: u64, + cp_unused01: u64, + cp_unused02: u64, + pub cp_sample_pc: u64, + pub cp_sample_sp: u64, + pub cp_msg: [::c_char; 32], + } + + pub struct kinfo_lwp { + pub kl_pid: ::pid_t, + pub kl_tid: ::lwpid_t, + pub kl_flags: ::c_int, + pub kl_stat: ::lwpstat, + pub kl_lock: ::c_int, + pub kl_tdflags: ::c_int, + pub kl_mpcount: ::c_int, + pub kl_prio: ::c_int, + pub kl_tdprio: ::c_int, + pub kl_rtprio: ::rtprio, + pub kl_uticks: u64, + pub kl_sticks: u64, + pub kl_iticks: u64, + pub kl_cpticks: u64, + pub kl_pctcpu: ::c_uint, + pub kl_slptime: ::c_uint, + pub kl_origcpu: ::c_int, + pub kl_estcpu: ::c_int, + pub kl_cpuid: ::c_int, + pub kl_ru: ::rusage, + pub kl_siglist: ::sigset_t, + pub kl_sigmask: ::sigset_t, + pub kl_wchan: ::uintptr_t, + pub kl_wmesg: [::c_char; 9], + pub kl_comm: [::c_char; MAXCOMLEN+1], + } + + pub struct kinfo_proc { + pub kp_paddr: ::uintptr_t, + pub kp_flags: ::c_int, + pub kp_stat: ::procstat, + pub kp_lock: ::c_int, + pub kp_acflag: ::c_int, + pub kp_traceflag: ::c_int, + pub kp_fd: ::uintptr_t, + pub kp_siglist: ::sigset_t, + pub kp_sigignore: ::sigset_t, + pub kp_sigcatch: ::sigset_t, + pub kp_sigflag: ::c_int, + pub kp_start: ::timeval, + pub kp_comm: [::c_char; MAXCOMLEN+1], + pub kp_uid: ::uid_t, + pub kp_ngroups: ::c_short, + pub kp_groups: [::gid_t; NGROUPS], + pub kp_ruid: ::uid_t, + pub kp_svuid: ::uid_t, + pub kp_rgid: ::gid_t, + pub kp_svgid: ::gid_t, + pub kp_pid: ::pid_t, + pub kp_ppid: ::pid_t, + pub kp_pgid: ::pid_t, + pub kp_jobc: ::c_int, + pub kp_sid: ::pid_t, + pub kp_login: [::c_char; 40], // MAXNAMELEN rounded up to the nearest sizeof(long) + pub kp_tdev: ::dev_t, + pub kp_tpgid: ::pid_t, + pub kp_tsid: ::pid_t, + pub kp_exitstat: ::c_ushort, + pub kp_nthreads: ::c_int, + pub kp_nice: ::c_int, + pub kp_swtime: ::c_uint, + pub kp_vm_map_size: ::size_t, + pub kp_vm_rssize: ::segsz_t, + pub kp_vm_swrss: ::segsz_t, + pub kp_vm_tsize: ::segsz_t, + pub kp_vm_dsize: ::segsz_t, + pub kp_vm_ssize: ::segsz_t, + pub kp_vm_prssize: ::c_uint, + pub kp_jailid: ::c_int, + pub kp_ru: ::rusage, + pub kp_cru: ::rusage, + pub kp_auxflags: ::c_int, + pub kp_lwp: ::kinfo_lwp, + pub kp_ktaddr: ::uintptr_t, + kp_spare: [::c_int; 2], + } + + pub struct __c_anonymous_vm_map { + _priv: [::uintptr_t; 36], + } + + pub struct vm_map_entry { + _priv: [::uintptr_t; 15], + pub eflags: ::vm_eflags_t, + pub maptype: ::vm_maptype_t, + pub protection: ::vm_prot_t, + pub max_protection: ::vm_prot_t, + pub inheritance: ::vm_inherit_t, + pub wired_count: ::c_int, + pub id: ::vm_subsys_t, + } + + pub struct __c_anonymous_pmap { + _priv1: [::uintptr_t; 32], + _priv2: [::uintptr_t; 32], + _priv3: [::uintptr_t; 32], + _priv4: [::uintptr_t; 32], + _priv5: [::uintptr_t; 8], + } + + pub struct vmspace { + vm_map: __c_anonymous_vm_map, + vm_pmap: __c_anonymous_pmap, + pub vm_flags: ::c_int, + pub vm_shm: *mut ::c_char, + pub vm_rssize: ::segsz_t, + pub vm_swrss: ::segsz_t, + pub vm_tsize: ::segsz_t, + pub vm_dsize: ::segsz_t, + pub vm_ssize: ::segsz_t, + pub vm_taddr: *mut ::c_char, + pub vm_daddr: *mut ::c_char, + pub vm_maxsaddr: *mut ::c_char, + pub vm_minsaddr: *mut ::c_char, + _unused1: ::c_int, + _unused2: ::c_int, + pub vm_pagesupply: ::c_int, + pub vm_holdcnt: ::c_uint, + pub vm_refcnt: ::c_uint, + } + + pub struct cpuctl_msr_args_t { + pub msr: ::c_int, + pub data: u64, + } + + pub struct cpuctl_cpuid_args_t { + pub level: ::c_int, + pub data: [u32; 4], + } + + pub struct cpuctl_cpuid_count_args_t { + pub level: ::c_int, + pub level_type: ::c_int, + pub data: [u32; 4], + } + + pub struct cpuctl_update_args_t { + pub data: *mut ::c_void, + pub size: ::size_t, + } +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_name: [::c_char; 32], + pub ut_id: [::c_char; 4], + + pub ut_line: [::c_char; 32], + pub ut_host: [::c_char; 256], + + pub ut_unused: [u8; 16], + pub ut_session: u16, + pub ut_type: u16, + pub ut_pid: ::pid_t, + ut_exit: exit_status, + ut_ss: ::sockaddr_storage, + pub ut_tv: ::timeval, + pub ut_unused2: [u8; 16], + } + + pub struct lastlogx { + pub ll_tv: ::timeval, + pub ll_line: [::c_char; _UTX_LINESIZE], + pub ll_host: [::c_char; _UTX_HOSTSIZE], + pub ll_ss: ::sockaddr_storage, + } + + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_namlen: u16, + pub d_type: u8, + __unused1: u8, + __unused2: u32, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + __spare2: ::c_long, + pub f_bsize: ::c_long, + pub f_iosize: ::c_long, + pub f_blocks: ::c_long, + pub f_bfree: ::c_long, + pub f_bavail: ::c_long, + pub f_files: ::c_long, + pub f_ffree: ::c_long, + pub f_fsid: ::fsid_t, + pub f_owner: ::uid_t, + pub f_type: ::c_int, + pub f_flags: ::c_int, + pub f_syncwrites: ::c_long, + pub f_asyncwrites: ::c_long, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 80], + pub f_syncreads: ::c_long, + pub f_asyncreads: ::c_long, + __spares1: ::c_short, + pub f_mntfromname: [::c_char; 80], + __spares2: ::c_short, + __spare: [::c_long; 2], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + // The union is 8-byte in size, so it is aligned at a 8-byte offset. + #[cfg(target_pointer_width = "64")] + __unused1: ::c_int, + pub sigev_signo: ::c_int, //actually a union + // pad the union + #[cfg(target_pointer_width = "64")] + __unused2: ::c_int, + pub sigev_value: ::sigval, + __unused3: *mut ::c_void //actually a function pointer + } + + pub struct mcontext_t { + pub mc_onstack: register_t, + pub mc_rdi: register_t, + pub mc_rsi: register_t, + pub mc_rdx: register_t, + pub mc_rcx: register_t, + pub mc_r8: register_t, + pub mc_r9: register_t, + pub mc_rax: register_t, + pub mc_rbx: register_t, + pub mc_rbp: register_t, + pub mc_r10: register_t, + pub mc_r11: register_t, + pub mc_r12: register_t, + pub mc_r13: register_t, + pub mc_r14: register_t, + pub mc_r15: register_t, + pub mc_xflags: register_t, + pub mc_trapno: register_t, + pub mc_addr: register_t, + pub mc_flags: register_t, + pub mc_err: register_t, + pub mc_rip: register_t, + pub mc_cs: register_t, + pub mc_rflags: register_t, + pub mc_rsp: register_t, + pub mc_ss: register_t, + pub mc_len: ::c_uint, + pub mc_fpformat: ::c_uint, + pub mc_ownedfp: ::c_uint, + __reserved: ::c_uint, + __unused: [::c_uint; 8], + pub mc_fpregs: [[::c_uint; 8]; 32], + } + + pub struct ucontext_t { + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + pub uc_link: *mut ucontext_t, + pub uc_stack: stack_t, + pub uc_cofunc: ::Option, + pub uc_arg: *mut ::c_void, + __pad: [::c_int; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_name == other.ut_name + && self.ut_id == other.ut_id + && self.ut_line == other.ut_line + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_unused == other.ut_unused + && self.ut_session == other.ut_session + && self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_exit == other.ut_exit + && self.ut_ss == other.ut_ss + && self.ut_tv == other.ut_tv + && self.ut_unused2 == other.ut_unused2 + } + } + impl Eq for utmpx {} + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_name", &self.ut_name) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_unused", &self.ut_unused) + .field("ut_session", &self.ut_session) + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_exit", &self.ut_exit) + .field("ut_ss", &self.ut_ss) + .field("ut_tv", &self.ut_tv) + .field("ut_unused2", &self.ut_unused2) + .finish() + } + } + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_name.hash(state); + self.ut_id.hash(state); + self.ut_line.hash(state); + self.ut_host.hash(state); + self.ut_unused.hash(state); + self.ut_session.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_exit.hash(state); + self.ut_ss.hash(state); + self.ut_tv.hash(state); + self.ut_unused2.hash(state); + } + } + impl PartialEq for lastlogx { + fn eq(&self, other: &lastlogx) -> bool { + self.ll_tv == other.ll_tv + && self.ll_line == other.ll_line + && self.ll_host == other.ll_host + && self.ll_ss == other.ll_ss + } + } + impl Eq for lastlogx {} + impl ::fmt::Debug for lastlogx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlogx") + .field("ll_tv", &self.ll_tv) + .field("ll_line", &self.ll_line) + .field("ll_host", &self.ll_host) + .field("ll_ss", &self.ll_ss) + .finish() + } + } + impl ::hash::Hash for lastlogx { + fn hash(&self, state: &mut H) { + self.ll_tv.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + self.ll_ss.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + // Ignore __unused1 + // Ignore __unused2 + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // Ignore __unused1 + // Ignore __unused2 + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + // Ignore __unused1 + // Ignore __unused2 + self.d_name.hash(state); + } + } + + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_fsid == other.f_fsid + && self.f_owner == other.f_owner + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_fstypename == other.f_fstypename + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_fsid", &self.f_fsid) + .field("f_owner", &self.f_owner) + .field("f_type", &self.f_type) + .field("f_flags", &self.f_flags) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + // FIXME: .field("f_mntonname", &self.f_mntonname) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_fsid.hash(state); + self.f_owner.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_mntfromname.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + } + } + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.mc_onstack == other.mc_onstack && + self.mc_rdi == other.mc_rdi && + self.mc_rsi == other.mc_rsi && + self.mc_rdx == other.mc_rdx && + self.mc_rcx == other.mc_rcx && + self.mc_r8 == other.mc_r8 && + self.mc_r9 == other.mc_r9 && + self.mc_rax == other.mc_rax && + self.mc_rbx == other.mc_rbx && + self.mc_rbp == other.mc_rbp && + self.mc_r10 == other.mc_r10 && + self.mc_r11 == other.mc_r11 && + self.mc_r12 == other.mc_r12 && + self.mc_r13 == other.mc_r13 && + self.mc_r14 == other.mc_r14 && + self.mc_r15 == other.mc_r15 && + self.mc_xflags == other.mc_xflags && + self.mc_trapno == other.mc_trapno && + self.mc_addr == other.mc_addr && + self.mc_flags == other.mc_flags && + self.mc_err == other.mc_err && + self.mc_rip == other.mc_rip && + self.mc_cs == other.mc_cs && + self.mc_rflags == other.mc_rflags && + self.mc_rsp == other.mc_rsp && + self.mc_ss == other.mc_ss && + self.mc_len == other.mc_len && + self.mc_fpformat == other.mc_fpformat && + self.mc_ownedfp == other.mc_ownedfp && + self.mc_fpregs.iter().zip(other.mc_fpregs.iter()). + all(|(a, b)| a == b) + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("mc_onstack", &self.mc_onstack) + .field("mc_rdi", &self.mc_rdi) + .field("mc_rsi", &self.mc_rsi) + .field("mc_rdx", &self.mc_rdx) + .field("mc_rcx", &self.mc_rcx) + .field("mc_r8", &self.mc_r8) + .field("mc_r9", &self.mc_r9) + .field("mc_rax", &self.mc_rax) + .field("mc_rbx", &self.mc_rbx) + .field("mc_rbp", &self.mc_rbp) + .field("mc_r10", &self.mc_r10) + .field("mc_r11", &self.mc_r11) + .field("mc_r12", &self.mc_r12) + .field("mc_r13", &self.mc_r13) + .field("mc_r14", &self.mc_r14) + .field("mc_r15", &self.mc_r15) + .field("mc_xflags", &self.mc_xflags) + .field("mc_trapno", &self.mc_trapno) + .field("mc_addr", &self.mc_addr) + .field("mc_flags", &self.mc_flags) + .field("mc_err", &self.mc_err) + .field("mc_rip", &self.mc_rip) + .field("mc_cs", &self.mc_cs) + .field("mc_rflags", &self.mc_rflags) + .field("mc_rsp", &self.mc_rsp) + .field("mc_ss", &self.mc_ss) + .field("mc_len", &self.mc_len) + .field("mc_fpformat", &self.mc_fpformat) + .field("mc_ownedfp", &self.mc_ownedfp) + .field("mc_fpregs", &self.mc_fpregs) + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.mc_onstack.hash(state); + self.mc_rdi.hash(state); + self.mc_rsi.hash(state); + self.mc_rdx.hash(state); + self.mc_rcx.hash(state); + self.mc_r8.hash(state); + self.mc_r9.hash(state); + self.mc_rax.hash(state); + self.mc_rbx.hash(state); + self.mc_rbp.hash(state); + self.mc_r10.hash(state); + self.mc_r11.hash(state); + self.mc_r10.hash(state); + self.mc_r11.hash(state); + self.mc_r12.hash(state); + self.mc_r13.hash(state); + self.mc_r14.hash(state); + self.mc_r15.hash(state); + self.mc_xflags.hash(state); + self.mc_trapno.hash(state); + self.mc_addr.hash(state); + self.mc_flags.hash(state); + self.mc_err.hash(state); + self.mc_rip.hash(state); + self.mc_cs.hash(state); + self.mc_rflags.hash(state); + self.mc_rsp.hash(state); + self.mc_ss.hash(state); + self.mc_len.hash(state); + self.mc_fpformat.hash(state); + self.mc_ownedfp.hash(state); + self.mc_fpregs.hash(state); + } + } + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_sigmask == other.uc_sigmask + && self.uc_mcontext == other.uc_mcontext + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_cofunc == other.uc_cofunc + && self.uc_arg == other.uc_arg + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_sigmask", &self.uc_sigmask) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_cofunc", &self.uc_cofunc) + .field("uc_arg", &self.uc_arg) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_sigmask.hash(state); + self.uc_mcontext.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_cofunc.hash(state); + self.uc_arg.hash(state); + } + } + } +} + +pub const RAND_MAX: ::c_int = 0x7fff_ffff; +pub const PTHREAD_STACK_MIN: ::size_t = 16384; +pub const SIGSTKSZ: ::size_t = 40960; +pub const SIGCKPT: ::c_int = 33; +pub const SIGCKPTEXIT: ::c_int = 34; +pub const CKPT_FREEZE: ::c_int = 0x1; +pub const CKPT_THAW: ::c_int = 0x2; +pub const MADV_INVAL: ::c_int = 10; +pub const MADV_SETMAP: ::c_int = 11; +pub const O_CLOEXEC: ::c_int = 0x00020000; +pub const O_DIRECTORY: ::c_int = 0x08000000; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_GETPATH: ::c_int = 19; +pub const ENOMEDIUM: ::c_int = 93; +pub const ENOTRECOVERABLE: ::c_int = 94; +pub const EOWNERDEAD: ::c_int = 95; +pub const EASYNC: ::c_int = 99; +pub const ELAST: ::c_int = 99; +pub const RLIMIT_POSIXLOCKS: ::c_int = 11; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::rlim_t = 12; + +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQUOTA: ::c_int = 0x400; + +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_VFS: ::c_int = 3; +pub const CTL_NET: ::c_int = 4; +pub const CTL_DEBUG: ::c_int = 5; +pub const CTL_HW: ::c_int = 6; +pub const CTL_MACHDEP: ::c_int = 7; +pub const CTL_USER: ::c_int = 8; +pub const CTL_P1003_1B: ::c_int = 9; +pub const CTL_LWKT: ::c_int = 10; +pub const CTL_MAXID: ::c_int = 11; +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_NISDOMAINNAME: ::c_int = 22; +pub const KERN_UPDATEINTERVAL: ::c_int = 23; +pub const KERN_OSRELDATE: ::c_int = 24; +pub const KERN_NTP_PLL: ::c_int = 25; +pub const KERN_BOOTFILE: ::c_int = 26; +pub const KERN_MAXFILESPERPROC: ::c_int = 27; +pub const KERN_MAXPROCPERUID: ::c_int = 28; +pub const KERN_DUMPDEV: ::c_int = 29; +pub const KERN_IPC: ::c_int = 30; +pub const KERN_DUMMY: ::c_int = 31; +pub const KERN_PS_STRINGS: ::c_int = 32; +pub const KERN_USRSTACK: ::c_int = 33; +pub const KERN_LOGSIGEXIT: ::c_int = 34; +pub const KERN_IOV_MAX: ::c_int = 35; +pub const KERN_MAXPOSIXLOCKSPERUID: ::c_int = 36; +pub const KERN_MAXID: ::c_int = 37; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +pub const KERN_PROC_SESSION: ::c_int = 3; +pub const KERN_PROC_TTY: ::c_int = 4; +pub const KERN_PROC_UID: ::c_int = 5; +pub const KERN_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_ARGS: ::c_int = 7; +pub const KERN_PROC_CWD: ::c_int = 8; +pub const KERN_PROC_PATHNAME: ::c_int = 9; +pub const KERN_PROC_FLAGMASK: ::c_int = 0x10; +pub const KERN_PROC_FLAG_LWP: ::c_int = 0x10; +pub const KIPC_MAXSOCKBUF: ::c_int = 1; +pub const KIPC_SOCKBUF_WASTE: ::c_int = 2; +pub const KIPC_SOMAXCONN: ::c_int = 3; +pub const KIPC_MAX_LINKHDR: ::c_int = 4; +pub const KIPC_MAX_PROTOHDR: ::c_int = 5; +pub const KIPC_MAX_HDR: ::c_int = 6; +pub const KIPC_MAX_DATALEN: ::c_int = 7; +pub const KIPC_MBSTAT: ::c_int = 8; +pub const KIPC_NMBCLUSTERS: ::c_int = 9; +pub const HW_MACHINE: ::c_int = 1; +pub const HW_MODEL: ::c_int = 2; +pub const HW_NCPU: ::c_int = 3; +pub const HW_BYTEORDER: ::c_int = 4; +pub const HW_PHYSMEM: ::c_int = 5; +pub const HW_USERMEM: ::c_int = 6; +pub const HW_PAGESIZE: ::c_int = 7; +pub const HW_DISKNAMES: ::c_int = 8; +pub const HW_DISKSTATS: ::c_int = 9; +pub const HW_FLOATINGPT: ::c_int = 10; +pub const HW_MACHINE_ARCH: ::c_int = 11; +pub const HW_MACHINE_PLATFORM: ::c_int = 12; +pub const HW_SENSORS: ::c_int = 13; +pub const HW_MAXID: ::c_int = 14; +pub const USER_CS_PATH: ::c_int = 1; +pub const USER_BC_BASE_MAX: ::c_int = 2; +pub const USER_BC_DIM_MAX: ::c_int = 3; +pub const USER_BC_SCALE_MAX: ::c_int = 4; +pub const USER_BC_STRING_MAX: ::c_int = 5; +pub const USER_COLL_WEIGHTS_MAX: ::c_int = 6; +pub const USER_EXPR_NEST_MAX: ::c_int = 7; +pub const USER_LINE_MAX: ::c_int = 8; +pub const USER_RE_DUP_MAX: ::c_int = 9; +pub const USER_POSIX2_VERSION: ::c_int = 10; +pub const USER_POSIX2_C_BIND: ::c_int = 11; +pub const USER_POSIX2_C_DEV: ::c_int = 12; +pub const USER_POSIX2_CHAR_TERM: ::c_int = 13; +pub const USER_POSIX2_FORT_DEV: ::c_int = 14; +pub const USER_POSIX2_FORT_RUN: ::c_int = 15; +pub const USER_POSIX2_LOCALEDEF: ::c_int = 16; +pub const USER_POSIX2_SW_DEV: ::c_int = 17; +pub const USER_POSIX2_UPE: ::c_int = 18; +pub const USER_STREAM_MAX: ::c_int = 19; +pub const USER_TZNAME_MAX: ::c_int = 20; +pub const USER_MAXID: ::c_int = 21; +pub const CTL_P1003_1B_ASYNCHRONOUS_IO: ::c_int = 1; +pub const CTL_P1003_1B_MAPPED_FILES: ::c_int = 2; +pub const CTL_P1003_1B_MEMLOCK: ::c_int = 3; +pub const CTL_P1003_1B_MEMLOCK_RANGE: ::c_int = 4; +pub const CTL_P1003_1B_MEMORY_PROTECTION: ::c_int = 5; +pub const CTL_P1003_1B_MESSAGE_PASSING: ::c_int = 6; +pub const CTL_P1003_1B_PRIORITIZED_IO: ::c_int = 7; +pub const CTL_P1003_1B_PRIORITY_SCHEDULING: ::c_int = 8; +pub const CTL_P1003_1B_REALTIME_SIGNALS: ::c_int = 9; +pub const CTL_P1003_1B_SEMAPHORES: ::c_int = 10; +pub const CTL_P1003_1B_FSYNC: ::c_int = 11; +pub const CTL_P1003_1B_SHARED_MEMORY_OBJECTS: ::c_int = 12; +pub const CTL_P1003_1B_SYNCHRONIZED_IO: ::c_int = 13; +pub const CTL_P1003_1B_TIMERS: ::c_int = 14; +pub const CTL_P1003_1B_AIO_LISTIO_MAX: ::c_int = 15; +pub const CTL_P1003_1B_AIO_MAX: ::c_int = 16; +pub const CTL_P1003_1B_AIO_PRIO_DELTA_MAX: ::c_int = 17; +pub const CTL_P1003_1B_DELAYTIMER_MAX: ::c_int = 18; +pub const CTL_P1003_1B_UNUSED1: ::c_int = 19; +pub const CTL_P1003_1B_PAGESIZE: ::c_int = 20; +pub const CTL_P1003_1B_RTSIG_MAX: ::c_int = 21; +pub const CTL_P1003_1B_SEM_NSEMS_MAX: ::c_int = 22; +pub const CTL_P1003_1B_SEM_VALUE_MAX: ::c_int = 23; +pub const CTL_P1003_1B_SIGQUEUE_MAX: ::c_int = 24; +pub const CTL_P1003_1B_TIMER_MAX: ::c_int = 25; +pub const CTL_P1003_1B_MAXID: ::c_int = 26; + +pub const CPUCTL_RSMSR: ::c_int = 0xc0106301; +pub const CPUCTL_WRMSR: ::c_int = 0xc0106302; +pub const CPUCTL_CPUID: ::c_int = 0xc0106303; +pub const CPUCTL_UPDATE: ::c_int = 0xc0106304; +pub const CPUCTL_MSRSBIT: ::c_int = 0xc0106305; +pub const CPUCTL_MSRCBIT: ::c_int = 0xc0106306; +pub const CPUCTL_CPUID_COUNT: ::c_int = 0xc0106307; + +pub const CPU_SETSIZE: ::size_t = ::mem::size_of::<::cpumask_t>() * 8; + +pub const EVFILT_READ: i16 = -1; +pub const EVFILT_WRITE: i16 = -2; +pub const EVFILT_AIO: i16 = -3; +pub const EVFILT_VNODE: i16 = -4; +pub const EVFILT_PROC: i16 = -5; +pub const EVFILT_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_EXCEPT: i16 = -8; +pub const EVFILT_USER: i16 = -9; +pub const EVFILT_FS: i16 = -10; + +pub const EV_ADD: u16 = 0x1; +pub const EV_DELETE: u16 = 0x2; +pub const EV_ENABLE: u16 = 0x4; +pub const EV_DISABLE: u16 = 0x8; +pub const EV_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +pub const EV_NODATA: u16 = 0x1000; +pub const EV_FLAG1: u16 = 0x2000; +pub const EV_ERROR: u16 = 0x4000; +pub const EV_EOF: u16 = 0x8000; +pub const EV_HUP: u16 = 0x8000; +pub const EV_SYSFLAGS: u16 = 0xf000; + +pub const FIODNAME: ::c_ulong = 0x80106678; + +pub const NOTE_TRIGGER: u32 = 0x01000000; +pub const NOTE_FFNOP: u32 = 0x00000000; +pub const NOTE_FFAND: u32 = 0x40000000; +pub const NOTE_FFOR: u32 = 0x80000000; +pub const NOTE_FFCOPY: u32 = 0xc0000000; +pub const NOTE_FFCTRLMASK: u32 = 0xc0000000; +pub const NOTE_FFLAGSMASK: u32 = 0x00ffffff; +pub const NOTE_LOWAT: u32 = 0x00000001; +pub const NOTE_OOB: u32 = 0x00000002; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +pub const NOTE_ATTRIB: u32 = 0x00000008; +pub const NOTE_LINK: u32 = 0x00000010; +pub const NOTE_RENAME: u32 = 0x00000020; +pub const NOTE_REVOKE: u32 = 0x00000040; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +pub const NOTE_PCTRLMASK: u32 = 0xf0000000; +pub const NOTE_TRACK: u32 = 0x00000001; +pub const NOTE_TRACKERR: u32 = 0x00000002; +pub const NOTE_CHILD: u32 = 0x00000004; + +pub const SO_SNDSPACE: ::c_int = 0x100a; +pub const SO_CPUHINT: ::c_int = 0x1030; +pub const SO_PASSCRED: ::c_int = 0x4000; + +pub const PT_FIRSTMACH: ::c_int = 32; + +pub const PROC_REAP_ACQUIRE: ::c_int = 0x0001; +pub const PROC_REAP_RELEASE: ::c_int = 0x0002; +pub const PROC_REAP_STATUS: ::c_int = 0x0003; +pub const PROC_PDEATHSIG_CTL: ::c_int = 0x0004; +pub const PROC_PDEATHSIG_STATUS: ::c_int = 0x0005; + +// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/HEAD/sys/net/if.h#L101 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_SMART: ::c_int = 0x20; // interface manages own routes +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE_COMPAT: ::c_int = 0x400; // was transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions +pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit +pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit +pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit +pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; // use alternate physical connection +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + // was interface is in polling mode +pub const IFF_POLLING_COMPAT: ::c_int = 0x10000; +pub const IFF_PPROMISC: ::c_int = 0x20000; // user-requested promisc mode +pub const IFF_MONITOR: ::c_int = 0x40000; // user-requested monitor mode +pub const IFF_STATICARP: ::c_int = 0x80000; // static ARP +pub const IFF_NPOLLING: ::c_int = 0x100000; // interface is in polling mode +pub const IFF_IDIRECT: ::c_int = 0x200000; // direct input + +// +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// Stream protocol II. +pub const IPPROTO_ST: ::c_int = 7; +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// private interior gateway +pub const IPPROTO_PIGP: ::c_int = 9; +/// BBN RCC Monitoring +pub const IPPROTO_RCCMON: ::c_int = 10; +/// network voice protocol +pub const IPPROTO_NVPII: ::c_int = 11; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +/// Argus +pub const IPPROTO_ARGUS: ::c_int = 13; +/// EMCON +pub const IPPROTO_EMCON: ::c_int = 14; +/// Cross Net Debugger +pub const IPPROTO_XNET: ::c_int = 15; +/// Chaos +pub const IPPROTO_CHAOS: ::c_int = 16; +// IPPROTO_UDP defined in src/unix/mod.rs +/// Multiplexing +pub const IPPROTO_MUX: ::c_int = 18; +/// DCN Measurement Subsystems +pub const IPPROTO_MEAS: ::c_int = 19; +/// Host Monitoring +pub const IPPROTO_HMP: ::c_int = 20; +/// Packet Radio Measurement +pub const IPPROTO_PRM: ::c_int = 21; +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// Trunk-1 +pub const IPPROTO_TRUNK1: ::c_int = 23; +/// Trunk-2 +pub const IPPROTO_TRUNK2: ::c_int = 24; +/// Leaf-1 +pub const IPPROTO_LEAF1: ::c_int = 25; +/// Leaf-2 +pub const IPPROTO_LEAF2: ::c_int = 26; +/// Reliable Data +pub const IPPROTO_RDP: ::c_int = 27; +/// Reliable Transaction +pub const IPPROTO_IRTP: ::c_int = 28; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// Bulk Data Transfer +pub const IPPROTO_BLT: ::c_int = 30; +/// Network Services +pub const IPPROTO_NSP: ::c_int = 31; +/// Merit Internodal +pub const IPPROTO_INP: ::c_int = 32; +/// Sequential Exchange +pub const IPPROTO_SEP: ::c_int = 33; +/// Third Party Connect +pub const IPPROTO_3PC: ::c_int = 34; +/// InterDomain Policy Routing +pub const IPPROTO_IDPR: ::c_int = 35; +/// XTP +pub const IPPROTO_XTP: ::c_int = 36; +/// Datagram Delivery +pub const IPPROTO_DDP: ::c_int = 37; +/// Control Message Transport +pub const IPPROTO_CMTP: ::c_int = 38; +/// TP++ Transport +pub const IPPROTO_TPXX: ::c_int = 39; +/// IL transport protocol +pub const IPPROTO_IL: ::c_int = 40; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// Source Demand Routing +pub const IPPROTO_SDRP: ::c_int = 42; +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// InterDomain Routing +pub const IPPROTO_IDRP: ::c_int = 45; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// Mobile Host Routing +pub const IPPROTO_MHRP: ::c_int = 48; +/// BHA +pub const IPPROTO_BHA: ::c_int = 49; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// Integ. Net Layer Security +pub const IPPROTO_INLSP: ::c_int = 52; +/// IP with encryption +pub const IPPROTO_SWIPE: ::c_int = 53; +/// Next Hop Resolution +pub const IPPROTO_NHRP: ::c_int = 54; +/// IP Mobility +pub const IPPROTO_MOBILE: ::c_int = 55; +/// Transport Layer Security +pub const IPPROTO_TLSP: ::c_int = 56; +/// SKIP +pub const IPPROTO_SKIP: ::c_int = 57; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// any host internal protocol +pub const IPPROTO_AHIP: ::c_int = 61; +/// CFTP +pub const IPPROTO_CFTP: ::c_int = 62; +/// "hello" routing protocol +pub const IPPROTO_HELLO: ::c_int = 63; +/// SATNET/Backroom EXPAK +pub const IPPROTO_SATEXPAK: ::c_int = 64; +/// Kryptolan +pub const IPPROTO_KRYPTOLAN: ::c_int = 65; +/// Remote Virtual Disk +pub const IPPROTO_RVD: ::c_int = 66; +/// Pluribus Packet Core +pub const IPPROTO_IPPC: ::c_int = 67; +/// Any distributed FS +pub const IPPROTO_ADFS: ::c_int = 68; +/// Satnet Monitoring +pub const IPPROTO_SATMON: ::c_int = 69; +/// VISA Protocol +pub const IPPROTO_VISA: ::c_int = 70; +/// Packet Core Utility +pub const IPPROTO_IPCV: ::c_int = 71; +/// Comp. Prot. Net. Executive +pub const IPPROTO_CPNX: ::c_int = 72; +/// Comp. Prot. HeartBeat +pub const IPPROTO_CPHB: ::c_int = 73; +/// Wang Span Network +pub const IPPROTO_WSN: ::c_int = 74; +/// Packet Video Protocol +pub const IPPROTO_PVP: ::c_int = 75; +/// BackRoom SATNET Monitoring +pub const IPPROTO_BRSATMON: ::c_int = 76; +/// Sun net disk proto (temp.) +pub const IPPROTO_ND: ::c_int = 77; +/// WIDEBAND Monitoring +pub const IPPROTO_WBMON: ::c_int = 78; +/// WIDEBAND EXPAK +pub const IPPROTO_WBEXPAK: ::c_int = 79; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// VMTP +pub const IPPROTO_VMTP: ::c_int = 81; +/// Secure VMTP +pub const IPPROTO_SVMTP: ::c_int = 82; +/// Banyon VINES +pub const IPPROTO_VINES: ::c_int = 83; +/// TTP +pub const IPPROTO_TTP: ::c_int = 84; +/// NSFNET-IGP +pub const IPPROTO_IGP: ::c_int = 85; +/// dissimilar gateway prot. +pub const IPPROTO_DGP: ::c_int = 86; +/// TCF +pub const IPPROTO_TCF: ::c_int = 87; +/// Cisco/GXS IGRP +pub const IPPROTO_IGRP: ::c_int = 88; +/// OSPFIGP +pub const IPPROTO_OSPFIGP: ::c_int = 89; +/// Strite RPC protocol +pub const IPPROTO_SRPC: ::c_int = 90; +/// Locus Address Resoloution +pub const IPPROTO_LARP: ::c_int = 91; +/// Multicast Transport +pub const IPPROTO_MTP: ::c_int = 92; +/// AX.25 Frames +pub const IPPROTO_AX25: ::c_int = 93; +/// IP encapsulated in IP +pub const IPPROTO_IPEIP: ::c_int = 94; +/// Mobile Int.ing control +pub const IPPROTO_MICP: ::c_int = 95; +/// Semaphore Comm. security +pub const IPPROTO_SCCSP: ::c_int = 96; +/// Ethernet IP encapsulation +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// any private encr. scheme +pub const IPPROTO_APES: ::c_int = 99; +/// GMTP +pub const IPPROTO_GMTP: ::c_int = 100; +/// payload compression (IPComp) +pub const IPPROTO_IPCOMP: ::c_int = 108; + +/* 101-254: Partly Unassigned */ +/// Protocol Independent Mcast +pub const IPPROTO_PIM: ::c_int = 103; +/// CARP +pub const IPPROTO_CARP: ::c_int = 112; +/// PGM +pub const IPPROTO_PGM: ::c_int = 113; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; + +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion, no longer used */ +/// divert pseudo-protocol +pub const IPPROTO_DIVERT: ::c_int = 254; +pub const IPPROTO_MAX: ::c_int = 256; +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +/// Used by RSS: the layer3 protocol is unknown +pub const IPPROTO_UNKNOWN: ::c_int = 258; + +// sys/netinet/tcp.h +pub const TCP_SIGNATURE_ENABLE: ::c_int = 16; +pub const TCP_KEEPINIT: ::c_int = 32; +pub const TCP_FASTKEEP: ::c_int = 128; + +pub const AF_BLUETOOTH: ::c_int = 33; +pub const AF_MPLS: ::c_int = 34; +pub const AF_IEEE80211: ::c_int = 35; + +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; +pub const NET_RT_MAXID: ::c_int = 4; + +pub const SOMAXOPT_SIZE: ::c_int = 65536; + +pub const MSG_UNUSED09: ::c_int = 0x00000200; +pub const MSG_NOSIGNAL: ::c_int = 0x00000400; +pub const MSG_SYNC: ::c_int = 0x00000800; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x00001000; +pub const MSG_FBLOCKING: ::c_int = 0x00010000; +pub const MSG_FNONBLOCKING: ::c_int = 0x00020000; +pub const MSG_FMASK: ::c_int = 0xFFFF0000; + +// sys/mount.h +pub const MNT_NODEV: ::c_int = 0x00000010; +pub const MNT_AUTOMOUNTED: ::c_int = 0x00000020; +pub const MNT_TRIM: ::c_int = 0x01000000; +pub const MNT_LOCAL: ::c_int = 0x00001000; +pub const MNT_QUOTA: ::c_int = 0x00002000; +pub const MNT_ROOTFS: ::c_int = 0x00004000; +pub const MNT_USER: ::c_int = 0x00008000; +pub const MNT_IGNORE: ::c_int = 0x00800000; + +// utmpx entry types +pub const EMPTY: ::c_short = 0; +pub const RUN_LVL: ::c_short = 1; +pub const BOOT_TIME: ::c_short = 2; +pub const OLD_TIME: ::c_short = 3; +pub const NEW_TIME: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const USER_PROCESS: ::c_short = 7; +pub const DEAD_PROCESS: ::c_short = 8; +pub const ACCOUNTING: ::c_short = 9; +pub const SIGNATURE: ::c_short = 10; +pub const DOWNTIME: ::c_short = 11; +// utmpx database types +pub const UTX_DB_UTMPX: ::c_uint = 0; +pub const UTX_DB_WTMPX: ::c_uint = 1; +pub const UTX_DB_LASTLOG: ::c_uint = 2; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_USERSIZE: usize = 32; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 256; + +pub const LC_COLLATE_MASK: ::c_int = 1 << 0; +pub const LC_CTYPE_MASK: ::c_int = 1 << 1; +pub const LC_MONETARY_MASK: ::c_int = 1 << 2; +pub const LC_NUMERIC_MASK: ::c_int = 1 << 3; +pub const LC_TIME_MASK: ::c_int = 1 << 4; +pub const LC_MESSAGES_MASK: ::c_int = 1 << 5; +pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_CTYPE_MASK + | LC_MESSAGES_MASK + | LC_MONETARY_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +pub const TIOCSIG: ::c_ulong = 0x2000745f; +pub const BTUARTDISC: ::c_int = 0x7; +pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40107458; +pub const TIOCISPTMASTER: ::c_ulong = 0x20007455; +pub const TIOCMODG: ::c_ulong = 0x40047403; +pub const TIOCMODS: ::c_ulong = 0x80047404; +pub const TIOCREMOTE: ::c_ulong = 0x80047469; + +// Constants used by "at" family of system calls. +pub const AT_FDCWD: ::c_int = 0xFFFAFDCD; // invalid file descriptor +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 1; +pub const AT_REMOVEDIR: ::c_int = 2; +pub const AT_EACCESS: ::c_int = 4; +pub const AT_SYMLINK_FOLLOW: ::c_int = 8; + +pub const VCHECKPT: usize = 19; + +pub const _PC_2_SYMLINKS: ::c_int = 22; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 23; + +pub const _SC_V7_ILP32_OFF32: ::c_int = 122; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 123; +pub const _SC_V7_LP64_OFF64: ::c_int = 124; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 125; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 126; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 127; + +pub const WCONTINUED: ::c_int = 0x4; +pub const WSTOPPED: ::c_int = 0x2; +pub const WNOWAIT: ::c_int = 0x8; +pub const WEXITED: ::c_int = 0x10; +pub const WTRAPPED: ::c_int = 0x20; + +// Similar to FreeBSD, only the standardized ones are exposed. +// There are more. +pub const P_PID: idtype_t = 0; +pub const P_PGID: idtype_t = 2; +pub const P_ALL: idtype_t = 7; + +// Values for struct rtprio (type_ field) +pub const RTP_PRIO_REALTIME: ::c_ushort = 0; +pub const RTP_PRIO_NORMAL: ::c_ushort = 1; +pub const RTP_PRIO_IDLE: ::c_ushort = 2; +pub const RTP_PRIO_THREAD: ::c_ushort = 3; + +// Flags for chflags(2) +pub const UF_NOHISTORY: ::c_ulong = 0x00000040; +pub const UF_CACHE: ::c_ulong = 0x00000080; +pub const UF_XLINK: ::c_ulong = 0x00000100; +pub const SF_NOHISTORY: ::c_ulong = 0x00400000; +pub const SF_CACHE: ::c_ulong = 0x00800000; +pub const SF_XLINK: ::c_ulong = 0x01000000; + +// timespec constants +pub const UTIME_OMIT: c_long = -2; +pub const UTIME_NOW: c_long = -1; + +pub const MINCORE_SUPER: ::c_int = 0x20; + +// kinfo_proc constants +pub const MAXCOMLEN: usize = 16; +pub const MAXLOGNAME: usize = 33; +pub const NGROUPS: usize = 16; + +pub const RB_PAUSE: ::c_int = 0x40000; +pub const RB_VIDEO: ::c_int = 0x20000000; + +const_fn! { + {const} fn _CMSG_ALIGN(n: usize) -> usize { + (n + (::mem::size_of::<::c_long>() - 1)) & !(::mem::size_of::<::c_long>() - 1) + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + length as usize) + as ::c_uint + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize) + + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next <= max { + (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } else { + 0 as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + + _CMSG_ALIGN(length as usize)) as ::c_uint + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.ary.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + cpuset.ary[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + cpuset.ary[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + 0 != cpuset.ary[idx] & (1 << offset) + } + + pub fn major(dev: ::dev_t) -> ::c_int { + ((dev >> 8) & 0xff) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (dev & 0xffff00ff) as ::c_int + } +} + +safe_f! { + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= major << 8; + dev |= minor; + dev + } +} + +extern "C" { + pub fn __errno_location() -> *mut ::c_int; + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + + pub fn setutxdb(_type: ::c_uint, file: *mut ::c_char) -> ::c_int; + + pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, timeout: *mut ::timespec) -> ::c_int; + + pub fn devname_r( + dev: ::dev_t, + mode: ::mode_t, + buf: *mut ::c_char, + len: ::size_t, + ) -> *mut ::c_char; + + pub fn waitid( + idtype: idtype_t, + id: ::id_t, + infop: *mut ::siginfo_t, + options: ::c_int, + ) -> ::c_int; + + pub fn freelocale(loc: ::locale_t); + + pub fn lwp_rtprio( + function: ::c_int, + pid: ::pid_t, + lwpid: lwpid_t, + rtp: *mut super::rtprio, + ) -> ::c_int; + + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; + + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, mask: *mut cpu_set_t) -> ::c_int; + pub fn sched_setaffinity(pid: ::pid_t, cpusetsize: ::size_t, mask: *const cpu_set_t) + -> ::c_int; + pub fn sched_getcpu() -> ::c_int; + pub fn setproctitle(fmt: *const ::c_char, ...); + + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int; + + pub fn updwtmpx(file: *const ::c_char, ut: *const utmpx) -> ::c_int; + pub fn getlastlogx(fname: *const ::c_char, uid: ::uid_t, ll: *mut lastlogx) -> *mut lastlogx; + pub fn updlastlogx(fname: *const ::c_char, uid: ::uid_t, ll: *mut lastlogx) -> ::c_int; + pub fn getutxuser(name: *const ::c_char) -> utmpx; + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + + pub fn sys_checkpoint(tpe: ::c_int, fd: ::c_int, pid: ::pid_t, retval: ::c_int) -> ::c_int; + + pub fn umtx_sleep(ptr: *const ::c_int, value: ::c_int, timeout: ::c_int) -> ::c_int; + pub fn umtx_wakeup(ptr: *const ::c_int, count: ::c_int) -> ::c_int; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + pub fn getmntinfo(mntbufp: *mut *mut ::statfs, flags: ::c_int) -> ::c_int; + pub fn getmntvinfo( + mntbufp: *mut *mut ::statfs, + mntvbufp: *mut *mut ::statvfs, + flags: ::c_int, + ) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; + + pub fn reallocf(ptr: *mut ::c_void, size: ::size_t) -> *mut ::c_void; + pub fn freezero(ptr: *mut ::c_void, size: ::size_t); +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_vm_map_entry_first( + kvm: *mut ::kvm_t, + map: vm_map_t, + entry: vm_map_entry_t, + ) -> vm_map_entry_t; + pub fn kvm_vm_map_entry_next( + kvm: *mut ::kvm_t, + map: vm_map_entry_t, + entry: vm_map_entry_t, + ) -> vm_map_entry_t; +} + +cfg_if! { + if #[cfg(libc_thread_local)] { + mod errno; + pub use self::errno::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs new file mode 100644 index 00000000..e8be8815 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs @@ -0,0 +1,146 @@ +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = u32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +s_no_extra_traits! { + pub struct gpregs { + pub gp_x: [::register_t; 30], + pub gp_lr: ::register_t, + pub gp_sp: ::register_t, + pub gp_elr: ::register_t, + pub gp_spsr: u32, + pub gp_pad: ::c_int, + } + + pub struct fpregs { + pub fp_q: u128, + pub fp_sr: u32, + pub fp_cr: u32, + pub fp_flags: ::c_int, + pub fp_pad: ::c_int, + } + + pub struct mcontext_t { + pub mc_gpregs: gpregs, + pub mc_fpregs: fpregs, + pub mc_flags: ::c_int, + pub mc_pad: ::c_int, + pub mc_spare: [u64; 8], + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for gpregs { + fn eq(&self, other: &gpregs) -> bool { + self.gp_x.iter().zip(other.gp_x.iter()).all(|(a, b)| a == b) && + self.gp_lr == other.gp_lr && + self.gp_sp == other.gp_sp && + self.gp_elr == other.gp_elr && + self.gp_spsr == other.gp_spsr && + self.gp_pad == other.gp_pad + } + } + impl Eq for gpregs {} + impl ::fmt::Debug for gpregs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("gpregs") + .field("gp_x", &self.gp_x) + .field("gp_lr", &self.gp_lr) + .field("gp_sp", &self.gp_sp) + .field("gp_elr", &self.gp_elr) + .field("gp_spsr", &self.gp_spsr) + .field("gp_pad", &self.gp_pad) + .finish() + } + } + impl ::hash::Hash for gpregs { + fn hash(&self, state: &mut H) { + self.gp_x.hash(state); + self.gp_lr.hash(state); + self.gp_sp.hash(state); + self.gp_elr.hash(state); + self.gp_spsr.hash(state); + self.gp_pad.hash(state); + } + } + impl PartialEq for fpregs { + fn eq(&self, other: &fpregs) -> bool { + self.fp_q == other.fp_q && + self.fp_sr == other.fp_sr && + self.fp_cr == other.fp_cr && + self.fp_flags == other.fp_flags && + self.fp_pad == other.fp_pad + } + } + impl Eq for fpregs {} + impl ::fmt::Debug for fpregs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpregs") + .field("fp_q", &self.fp_q) + .field("fp_sr", &self.fp_sr) + .field("fp_cr", &self.fp_cr) + .field("fp_flags", &self.fp_flags) + .field("fp_pad", &self.fp_pad) + .finish() + } + } + impl ::hash::Hash for fpregs { + fn hash(&self, state: &mut H) { + self.fp_q.hash(state); + self.fp_sr.hash(state); + self.fp_cr.hash(state); + self.fp_flags.hash(state); + self.fp_pad.hash(state); + } + } + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.mc_gpregs == other.mc_gpregs && + self.mc_fpregs == other.mc_fpregs && + self.mc_flags == other.mc_flags && + self.mc_pad == other.mc_pad && + self.mc_spare.iter().zip(other.mc_spare.iter()).all(|(a, b)| a == b) + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("mc_gpregs", &self.mc_gpregs) + .field("mc_fpregs", &self.mc_fpregs) + .field("mc_flags", &self.mc_flags) + .field("mc_pad", &self.mc_pad) + .field("mc_spare", &self.mc_spare) + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.mc_gpregs.hash(state); + self.mc_fpregs.hash(state); + self.mc_flags.hash(state); + self.mc_pad.hash(state); + self.mc_spare.hash(state); + } + } + } +} + +pub const MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 4096; // 1024 * 4 diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs new file mode 100644 index 00000000..300b3dd4 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs @@ -0,0 +1,50 @@ +pub type c_char = u8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = u32; +pub type time_t = i64; +pub type suseconds_t = i32; +pub type register_t = i32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_atime_pad: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_mtime_pad: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ctime_pad: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_birthtime_pad: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} +pub const MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 4096; // 1024 * 4 diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs new file mode 100644 index 00000000..f32128f7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs @@ -0,0 +1,32 @@ +#[repr(C)] +#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] +pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs new file mode 100644 index 00000000..de34069e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs @@ -0,0 +1,488 @@ +// APIs that were changed after FreeBSD 11 + +// The type of `nlink_t` changed from `u16` to `u64` in FreeBSD 12: +pub type nlink_t = u16; +// Type of `dev_t` changed from `u32` to `u64` in FreeBSD 12: +pub type dev_t = u32; +// Type of `ino_t` changed from `unsigned int` to `unsigned long` in FreeBSD 12: +pub type ino_t = u32; + +s! { + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + // Type of shm_nattc changed from `int` to `shmatt_t` (aka `unsigned + // int`) in FreeBSD 12: + pub shm_nattch: ::c_int, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + } + + pub struct kinfo_proc { + /// Size of this structure. + pub ki_structsize: ::c_int, + /// Reserved: layout identifier. + pub ki_layout: ::c_int, + /// Address of command arguments. + pub ki_args: *mut ::pargs, + // This is normally "struct proc". + /// Address of proc. + pub ki_paddr: *mut ::c_void, + // This is normally "struct user". + /// Kernel virtual address of u-area. + pub ki_addr: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to trace file. + pub ki_tracep: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to executable file. + pub ki_textvp: *mut ::c_void, + // This is normally "struct filedesc". + /// Pointer to open file info. + pub ki_fd: *mut ::c_void, + // This is normally "struct vmspace". + /// Pointer to kernel vmspace struct. + pub ki_vmspace: *mut ::c_void, + /// Sleep address. + pub ki_wchan: *mut ::c_void, + /// Process identifier. + pub ki_pid: ::pid_t, + /// Parent process ID. + pub ki_ppid: ::pid_t, + /// Process group ID. + pub ki_pgid: ::pid_t, + /// tty process group ID. + pub ki_tpgid: ::pid_t, + /// Process session ID. + pub ki_sid: ::pid_t, + /// Terminal session ID. + pub ki_tsid: ::pid_t, + /// Job control counter. + pub ki_jobc: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short1: ::c_short, + /// Controlling tty dev. + pub ki_tdev: ::dev_t, + /// Signals arrived but not delivered. + pub ki_siglist: ::sigset_t, + /// Current signal mask. + pub ki_sigmask: ::sigset_t, + /// Signals being ignored. + pub ki_sigignore: ::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: ::sigset_t, + /// Effective user ID. + pub ki_uid: ::uid_t, + /// Real user ID. + pub ki_ruid: ::uid_t, + /// Saved effective user ID. + pub ki_svuid: ::uid_t, + /// Real group ID. + pub ki_rgid: ::gid_t, + /// Saved effective group ID. + pub ki_svgid: ::gid_t, + /// Number of groups. + pub ki_ngroups: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short2: ::c_short, + /// Groups. + pub ki_groups: [::gid_t; ::KI_NGROUPS], + /// Virtual size. + pub ki_size: ::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: ::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: ::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: ::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: ::segsz_t, + /// Stack size (pages). + pub ki_ssize: ::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: ::u_short, + /// Accounting flags. + pub ki_acflag: ::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: ::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: ::u_int, + /// Time since last blocked. + pub ki_slptime: ::u_int, + /// Time swapped in or out. + pub ki_swtime: ::u_int, + /// Number of copy-on-write faults. + pub ki_cow: ::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: ::timeval, + /// Time used by process children. + pub ki_childtime: ::timeval, + /// P_* flags. + pub ki_flag: ::c_long, + /// KI_* flags (below). + pub ki_kiflag: ::c_long, + /// Kernel trace points. + pub ki_traceflag: ::c_int, + /// S* process status. + pub ki_stat: ::c_char, + /// Process "nice" value. + pub ki_nice: i8, // signed char + /// Process lock (prevent swap) count. + pub ki_lock: ::c_char, + /// Run queue index. + pub ki_rqindex: ::c_char, + /// Which cpu we are on. + pub ki_oncpu_old: ::c_uchar, + /// Last cpu we were on. + pub ki_lastcpu_old: ::c_uchar, + /// Thread name. + pub ki_tdname: [::c_char; ::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [::c_char; ::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [::c_char; ::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [::c_char; ::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], + /// Spare string space. + pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq + /// Spare room for growth. + pub ki_spareints: [::c_int; ::KI_NSPARE_INT], + /// Which cpu we are on. + pub ki_oncpu: ::c_int, + /// Last cpu we were on. + pub ki_lastcpu: ::c_int, + /// PID of tracing process. + pub ki_tracer: ::c_int, + /// P2_* flags. + pub ki_flag2: ::c_int, + /// Default FIB number. + pub ki_fibnum: ::c_int, + /// Credential flags. + pub ki_cr_flags: ::u_int, + /// Process jail ID. + pub ki_jid: ::c_int, + /// Number of threads in total. + pub ki_numthreads: ::c_int, + /// Thread ID. + pub ki_tid: ::lwpid_t, + /// Process priority. + pub ki_pri: ::priority, + /// Process rusage statistics. + pub ki_rusage: ::rusage, + /// rusage of children processes. + pub ki_rusage_ch: ::rusage, + // This is normally "struct pcb". + /// Kernel virtual addr of pcb. + pub ki_pcb: *mut ::c_void, + /// Kernel virtual addr of stack. + pub ki_kstack: *mut ::c_void, + /// User convenience pointer. + pub ki_udata: *mut ::c_void, + // This is normally "struct thread". + pub ki_tdaddr: *mut ::c_void, + pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], + pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: ::c_long, + /// kthread flag. + pub ki_tdflags: ::c_long, + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_reclen: u16, + pub d_type: u8, + // Type of `d_namlen` changed from `char` to `u16` in FreeBSD 12: + pub d_namlen: u8, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_version: u32, + pub f_type: u32, + pub f_flags: u64, + pub f_bsize: u64, + pub f_iosize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: i64, + pub f_syncwrites: u64, + pub f_asyncwrites: u64, + pub f_syncreads: u64, + pub f_asyncreads: u64, + f_spare: [u64; 10], + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_fsid: ::fsid_t, + f_charspare: [::c_char; 80], + pub f_fstypename: [::c_char; 16], + // Array length changed from 88 to 1024 in FreeBSD 12: + pub f_mntfromname: [::c_char; 88], + // Array length changed from 88 to 1024 in FreeBSD 12: + pub f_mntonname: [::c_char; 88], + } + + pub struct vnstat { + pub vn_fileid: u64, + pub vn_size: u64, + pub vn_mntdir: *mut ::c_char, + pub vn_dev: u32, + pub vn_fsid: u32, + pub vn_type: ::c_int, + pub vn_mode: u16, + pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_version == other.f_version + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_fsid == other.f_fsid + && self.f_fstypename == other.f_fstypename + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_fsid", &self.f_fsid) + .field("f_fstypename", &self.f_fstypename) + .field("f_mntfromname", &&self.f_mntfromname[..]) + .field("f_mntonname", &&self.f_mntonname[..]) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_version.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_fsid.hash(state); + self.f_fstypename.hash(state); + self.f_mntfromname.hash(state); + self.f_mntonname.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name[..self.d_namlen as _] + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + .field("d_name", &&self.d_name[..self.d_namlen as _]) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name[..self.d_namlen as _].hash(state); + } + } + + impl PartialEq for vnstat { + fn eq(&self, other: &vnstat) -> bool { + let self_vn_devname: &[::c_char] = &self.vn_devname; + let other_vn_devname: &[::c_char] = &other.vn_devname; + + self.vn_fileid == other.vn_fileid && + self.vn_size == other.vn_size && + self.vn_mntdir == other.vn_mntdir && + self.vn_dev == other.vn_dev && + self.vn_fsid == other.vn_fsid && + self.vn_type == other.vn_type && + self.vn_mode == other.vn_mode && + self_vn_devname == other_vn_devname + } + } + impl Eq for vnstat {} + impl ::fmt::Debug for vnstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + f.debug_struct("vnstat") + .field("vn_fileid", &self.vn_fileid) + .field("vn_size", &self.vn_size) + .field("vn_mntdir", &self.vn_mntdir) + .field("vn_dev", &self.vn_dev) + .field("vn_fsid", &self.vn_fsid) + .field("vn_type", &self.vn_type) + .field("vn_mode", &self.vn_mode) + .field("vn_devname", &self_vn_devname) + .finish() + } + } + impl ::hash::Hash for vnstat { + fn hash(&self, state: &mut H) { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + self.vn_fileid.hash(state); + self.vn_size.hash(state); + self.vn_mntdir.hash(state); + self.vn_dev.hash(state); + self.vn_fsid.hash(state); + self.vn_type.hash(state); + self.vn_mode.hash(state); + self_vn_devname.hash(state); + } + } + } +} + +pub const ELAST: ::c_int = 96; +pub const RAND_MAX: ::c_int = 0x7fff_fffd; +pub const KI_NSPARE_PTR: usize = 6; +pub const MINCORE_SUPER: ::c_int = 0x20; +/// max length of devicename +pub const SPECNAMELEN: ::c_int = 63; + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + (major << 8) | minor + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + ((dev >> 8) & 0xff) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (dev & 0xffff00ff) as ::c_int + } +} + +extern "C" { + // Return type ::c_int was removed in FreeBSD 12 + pub fn setgrent() -> ::c_int; + + // Type of `addr` argument changed from `const void*` to `void*` + // in FreeBSD 12 + pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + + // Return type ::c_int was removed in FreeBSD 12 + pub fn freelocale(loc: ::locale_t) -> ::c_int; + + // Return type ::c_int changed to ::ssize_t in FreeBSD 12: + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::c_int; + + // Type of `path` argument changed from `const void*` to `void*` + // in FreeBSD 12 + pub fn dirname(path: *const ::c_char) -> *mut ::c_char; + pub fn basename(path: *const ::c_char) -> *mut ::c_char; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs new file mode 100644 index 00000000..80c6fa16 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs @@ -0,0 +1,34 @@ +#[repr(C)] +#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] +pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + st_padding0: i16, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_padding1: i32, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u64, + pub st_spare: [u64; 10], +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs new file mode 100644 index 00000000..10fcaa03 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs @@ -0,0 +1,505 @@ +// APIs in FreeBSD 12 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = ::c_ulong; +pub type shmatt_t = ::c_uint; + +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: i64, + pub udata: *mut ::c_void, + pub ext: [u64; 4], + } + + pub struct kvm_page { + pub version: ::c_uint, + pub paddr: ::c_ulong, + pub kmap_vaddr: ::c_ulong, + pub dmap_vaddr: ::c_ulong, + pub prot: ::vm_prot_t, + pub offset: ::u_long, + pub len: ::size_t, + } + + pub struct kinfo_proc { + /// Size of this structure. + pub ki_structsize: ::c_int, + /// Reserved: layout identifier. + pub ki_layout: ::c_int, + /// Address of command arguments. + pub ki_args: *mut ::pargs, + // This is normally "struct proc". + /// Address of proc. + pub ki_paddr: *mut ::c_void, + // This is normally "struct user". + /// Kernel virtual address of u-area. + pub ki_addr: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to trace file. + pub ki_tracep: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to executable file. + pub ki_textvp: *mut ::c_void, + // This is normally "struct filedesc". + /// Pointer to open file info. + pub ki_fd: *mut ::c_void, + // This is normally "struct vmspace". + /// Pointer to kernel vmspace struct. + pub ki_vmspace: *mut ::c_void, + /// Sleep address. + pub ki_wchan: *mut ::c_void, + /// Process identifier. + pub ki_pid: ::pid_t, + /// Parent process ID. + pub ki_ppid: ::pid_t, + /// Process group ID. + pub ki_pgid: ::pid_t, + /// tty process group ID. + pub ki_tpgid: ::pid_t, + /// Process session ID. + pub ki_sid: ::pid_t, + /// Terminal session ID. + pub ki_tsid: ::pid_t, + /// Job control counter. + pub ki_jobc: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short1: ::c_short, + /// Controlling tty dev. + pub ki_tdev_freebsd11: u32, + /// Signals arrived but not delivered. + pub ki_siglist: ::sigset_t, + /// Current signal mask. + pub ki_sigmask: ::sigset_t, + /// Signals being ignored. + pub ki_sigignore: ::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: ::sigset_t, + /// Effective user ID. + pub ki_uid: ::uid_t, + /// Real user ID. + pub ki_ruid: ::uid_t, + /// Saved effective user ID. + pub ki_svuid: ::uid_t, + /// Real group ID. + pub ki_rgid: ::gid_t, + /// Saved effective group ID. + pub ki_svgid: ::gid_t, + /// Number of groups. + pub ki_ngroups: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short2: ::c_short, + /// Groups. + pub ki_groups: [::gid_t; ::KI_NGROUPS], + /// Virtual size. + pub ki_size: ::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: ::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: ::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: ::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: ::segsz_t, + /// Stack size (pages). + pub ki_ssize: ::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: ::u_short, + /// Accounting flags. + pub ki_acflag: ::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: ::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: ::u_int, + /// Time since last blocked. + pub ki_slptime: ::u_int, + /// Time swapped in or out. + pub ki_swtime: ::u_int, + /// Number of copy-on-write faults. + pub ki_cow: ::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: ::timeval, + /// Time used by process children. + pub ki_childtime: ::timeval, + /// P_* flags. + pub ki_flag: ::c_long, + /// KI_* flags (below). + pub ki_kiflag: ::c_long, + /// Kernel trace points. + pub ki_traceflag: ::c_int, + /// S* process status. + pub ki_stat: ::c_char, + /// Process "nice" value. + pub ki_nice: i8, // signed char + /// Process lock (prevent swap) count. + pub ki_lock: ::c_char, + /// Run queue index. + pub ki_rqindex: ::c_char, + /// Which cpu we are on. + pub ki_oncpu_old: ::c_uchar, + /// Last cpu we were on. + pub ki_lastcpu_old: ::c_uchar, + /// Thread name. + pub ki_tdname: [::c_char; ::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [::c_char; ::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [::c_char; ::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [::c_char; ::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], + /// Spare string space. + pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq + /// Spare room for growth. + pub ki_spareints: [::c_int; ::KI_NSPARE_INT], + /// Controlling tty dev. + pub ki_tdev: ::dev_t, + /// Which cpu we are on. + pub ki_oncpu: ::c_int, + /// Last cpu we were on. + pub ki_lastcpu: ::c_int, + /// PID of tracing process. + pub ki_tracer: ::c_int, + /// P2_* flags. + pub ki_flag2: ::c_int, + /// Default FIB number. + pub ki_fibnum: ::c_int, + /// Credential flags. + pub ki_cr_flags: ::u_int, + /// Process jail ID. + pub ki_jid: ::c_int, + /// Number of threads in total. + pub ki_numthreads: ::c_int, + /// Thread ID. + pub ki_tid: ::lwpid_t, + /// Process priority. + pub ki_pri: ::priority, + /// Process rusage statistics. + pub ki_rusage: ::rusage, + /// rusage of children processes. + pub ki_rusage_ch: ::rusage, + // This is normally "struct pcb". + /// Kernel virtual addr of pcb. + pub ki_pcb: *mut ::c_void, + /// Kernel virtual addr of stack. + pub ki_kstack: *mut ::c_void, + /// User convenience pointer. + pub ki_udata: *mut ::c_void, + // This is normally "struct thread". + pub ki_tdaddr: *mut ::c_void, + pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], + pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: ::c_long, + /// kthread flag. + pub ki_tdflags: ::c_long, + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: u8, + pub d_namlen: u16, + d_pad1: u16, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_version: u32, + pub f_type: u32, + pub f_flags: u64, + pub f_bsize: u64, + pub f_iosize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: i64, + pub f_syncwrites: u64, + pub f_asyncwrites: u64, + pub f_syncreads: u64, + pub f_asyncreads: u64, + f_spare: [u64; 10], + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_fsid: ::fsid_t, + f_charspare: [::c_char; 80], + pub f_fstypename: [::c_char; 16], + pub f_mntfromname: [::c_char; 1024], + pub f_mntonname: [::c_char; 1024], + } + + pub struct vnstat { + pub vn_fileid: u64, + pub vn_size: u64, + pub vn_dev: u64, + pub vn_fsid: u64, + pub vn_mntdir: *mut ::c_char, + pub vn_type: ::c_int, + pub vn_mode: u16, + pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_version == other.f_version + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_fsid == other.f_fsid + && self.f_fstypename == other.f_fstypename + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_fsid", &self.f_fsid) + .field("f_fstypename", &self.f_fstypename) + .field("f_mntfromname", &&self.f_mntfromname[..]) + .field("f_mntonname", &&self.f_mntonname[..]) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_version.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_fsid.hash(state); + self.f_charspare.hash(state); + self.f_fstypename.hash(state); + self.f_mntfromname.hash(state); + self.f_mntonname.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name[..self.d_namlen as _] + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + .field("d_name", &&self.d_name[..self.d_namlen as _]) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name[..self.d_namlen as _].hash(state); + } + } + + impl PartialEq for vnstat { + fn eq(&self, other: &vnstat) -> bool { + let self_vn_devname: &[::c_char] = &self.vn_devname; + let other_vn_devname: &[::c_char] = &other.vn_devname; + + self.vn_fileid == other.vn_fileid && + self.vn_size == other.vn_size && + self.vn_dev == other.vn_dev && + self.vn_fsid == other.vn_fsid && + self.vn_mntdir == other.vn_mntdir && + self.vn_type == other.vn_type && + self.vn_mode == other.vn_mode && + self_vn_devname == other_vn_devname + } + } + impl Eq for vnstat {} + impl ::fmt::Debug for vnstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + f.debug_struct("vnstat") + .field("vn_fileid", &self.vn_fileid) + .field("vn_size", &self.vn_size) + .field("vn_dev", &self.vn_dev) + .field("vn_fsid", &self.vn_fsid) + .field("vn_mntdir", &self.vn_mntdir) + .field("vn_type", &self.vn_type) + .field("vn_mode", &self.vn_mode) + .field("vn_devname", &self_vn_devname) + .finish() + } + } + impl ::hash::Hash for vnstat { + fn hash(&self, state: &mut H) { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + self.vn_fileid.hash(state); + self.vn_size.hash(state); + self.vn_dev.hash(state); + self.vn_fsid.hash(state); + self.vn_mntdir.hash(state); + self.vn_type.hash(state); + self.vn_mode.hash(state); + self_vn_devname.hash(state); + } + } + } +} + +pub const RAND_MAX: ::c_int = 0x7fff_fffd; +pub const ELAST: ::c_int = 97; + +/// max length of devicename +pub const SPECNAMELEN: ::c_int = 63; +pub const KI_NSPARE_PTR: usize = 6; + +pub const MINCORE_SUPER: ::c_int = 0x20; + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +extern "C" { + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn freelocale(loc: ::locale_t); + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs new file mode 100644 index 00000000..7bf25344 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs @@ -0,0 +1,5 @@ +pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; +pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; +pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; +pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs new file mode 100644 index 00000000..80c6fa16 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs @@ -0,0 +1,34 @@ +#[repr(C)] +#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] +pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + st_padding0: i16, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_padding1: i32, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u64, + pub st_spare: [u64; 10], +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs new file mode 100644 index 00000000..ec6bce2a --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs @@ -0,0 +1,546 @@ +// APIs in FreeBSD 13 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = ::c_ulong; +pub type shmatt_t = ::c_uint; +pub type kpaddr_t = u64; +pub type kssize_t = i64; +pub type domainset_t = __c_anonymous_domainset; + +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: i64, + pub udata: *mut ::c_void, + pub ext: [u64; 4], + } + + pub struct kvm_page { + pub kp_version: ::u_int, + pub kp_paddr: ::kpaddr_t, + pub kp_kmap_vaddr: ::kvaddr_t, + pub kp_dmap_vaddr: ::kvaddr_t, + pub kp_prot: ::vm_prot_t, + pub kp_offset: ::off_t, + pub kp_len: ::size_t, + } + + pub struct __c_anonymous_domainset { + _priv: [::uintptr_t; 4], + } + + pub struct kinfo_proc { + /// Size of this structure. + pub ki_structsize: ::c_int, + /// Reserved: layout identifier. + pub ki_layout: ::c_int, + /// Address of command arguments. + pub ki_args: *mut ::pargs, + // This is normally "struct proc". + /// Address of proc. + pub ki_paddr: *mut ::c_void, + // This is normally "struct user". + /// Kernel virtual address of u-area. + pub ki_addr: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to trace file. + pub ki_tracep: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to executable file. + pub ki_textvp: *mut ::c_void, + // This is normally "struct filedesc". + /// Pointer to open file info. + pub ki_fd: *mut ::c_void, + // This is normally "struct vmspace". + /// Pointer to kernel vmspace struct. + pub ki_vmspace: *mut ::c_void, + /// Sleep address. + pub ki_wchan: *const ::c_void, + /// Process identifier. + pub ki_pid: ::pid_t, + /// Parent process ID. + pub ki_ppid: ::pid_t, + /// Process group ID. + pub ki_pgid: ::pid_t, + /// tty process group ID. + pub ki_tpgid: ::pid_t, + /// Process session ID. + pub ki_sid: ::pid_t, + /// Terminal session ID. + pub ki_tsid: ::pid_t, + /// Job control counter. + pub ki_jobc: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short1: ::c_short, + /// Controlling tty dev. + pub ki_tdev_freebsd11: u32, + /// Signals arrived but not delivered. + pub ki_siglist: ::sigset_t, + /// Current signal mask. + pub ki_sigmask: ::sigset_t, + /// Signals being ignored. + pub ki_sigignore: ::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: ::sigset_t, + /// Effective user ID. + pub ki_uid: ::uid_t, + /// Real user ID. + pub ki_ruid: ::uid_t, + /// Saved effective user ID. + pub ki_svuid: ::uid_t, + /// Real group ID. + pub ki_rgid: ::gid_t, + /// Saved effective group ID. + pub ki_svgid: ::gid_t, + /// Number of groups. + pub ki_ngroups: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short2: ::c_short, + /// Groups. + pub ki_groups: [::gid_t; ::KI_NGROUPS], + /// Virtual size. + pub ki_size: ::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: ::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: ::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: ::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: ::segsz_t, + /// Stack size (pages). + pub ki_ssize: ::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: ::u_short, + /// Accounting flags. + pub ki_acflag: ::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: ::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: ::u_int, + /// Time since last blocked. + pub ki_slptime: ::u_int, + /// Time swapped in or out. + pub ki_swtime: ::u_int, + /// Number of copy-on-write faults. + pub ki_cow: ::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: ::timeval, + /// Time used by process children. + pub ki_childtime: ::timeval, + /// P_* flags. + pub ki_flag: ::c_long, + /// KI_* flags (below). + pub ki_kiflag: ::c_long, + /// Kernel trace points. + pub ki_traceflag: ::c_int, + /// S* process status. + pub ki_stat: ::c_char, + /// Process "nice" value. + pub ki_nice: i8, // signed char + /// Process lock (prevent swap) count. + pub ki_lock: ::c_char, + /// Run queue index. + pub ki_rqindex: ::c_char, + /// Which cpu we are on. + pub ki_oncpu_old: ::c_uchar, + /// Last cpu we were on. + pub ki_lastcpu_old: ::c_uchar, + /// Thread name. + pub ki_tdname: [::c_char; ::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [::c_char; ::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [::c_char; ::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [::c_char; ::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], + /// Spare string space. + pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq + /// Spare room for growth. + pub ki_spareints: [::c_int; ::KI_NSPARE_INT], + /// Controlling tty dev. + pub ki_tdev: u64, + /// Which cpu we are on. + pub ki_oncpu: ::c_int, + /// Last cpu we were on. + pub ki_lastcpu: ::c_int, + /// PID of tracing process. + pub ki_tracer: ::c_int, + /// P2_* flags. + pub ki_flag2: ::c_int, + /// Default FIB number. + pub ki_fibnum: ::c_int, + /// Credential flags. + pub ki_cr_flags: ::u_int, + /// Process jail ID. + pub ki_jid: ::c_int, + /// Number of threads in total. + pub ki_numthreads: ::c_int, + /// Thread ID. + pub ki_tid: ::lwpid_t, + /// Process priority. + pub ki_pri: ::priority, + /// Process rusage statistics. + pub ki_rusage: ::rusage, + /// rusage of children processes. + pub ki_rusage_ch: ::rusage, + // This is normally "struct pcb". + /// Kernel virtual addr of pcb. + pub ki_pcb: *mut ::c_void, + /// Kernel virtual addr of stack. + pub ki_kstack: *mut ::c_void, + /// User convenience pointer. + pub ki_udata: *mut ::c_void, + // This is normally "struct thread". + pub ki_tdaddr: *mut ::c_void, + // This is normally "struct pwddesc". + /// Pointer to process paths info. + pub ki_pd: *mut ::c_void, + pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], + pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: ::c_long, + /// kthread flag. + pub ki_tdflags: ::c_long, + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: u8, + pub d_namlen: u16, + d_pad1: u16, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_version: u32, + pub f_type: u32, + pub f_flags: u64, + pub f_bsize: u64, + pub f_iosize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: i64, + pub f_syncwrites: u64, + pub f_asyncwrites: u64, + pub f_syncreads: u64, + pub f_asyncreads: u64, + f_spare: [u64; 10], + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_fsid: ::fsid_t, + f_charspare: [::c_char; 80], + pub f_fstypename: [::c_char; 16], + pub f_mntfromname: [::c_char; 1024], + pub f_mntonname: [::c_char; 1024], + } + + pub struct vnstat { + pub vn_fileid: u64, + pub vn_size: u64, + pub vn_dev: u64, + pub vn_fsid: u64, + pub vn_mntdir: *mut ::c_char, + pub vn_type: ::c_int, + pub vn_mode: u16, + pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_version == other.f_version + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_fsid == other.f_fsid + && self.f_fstypename == other.f_fstypename + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_fsid", &self.f_fsid) + .field("f_fstypename", &self.f_fstypename) + .field("f_mntfromname", &&self.f_mntfromname[..]) + .field("f_mntonname", &&self.f_mntonname[..]) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_version.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_fsid.hash(state); + self.f_charspare.hash(state); + self.f_fstypename.hash(state); + self.f_mntfromname.hash(state); + self.f_mntonname.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name[..self.d_namlen as _] + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + .field("d_name", &&self.d_name[..self.d_namlen as _]) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name[..self.d_namlen as _].hash(state); + } + } + + impl PartialEq for vnstat { + fn eq(&self, other: &vnstat) -> bool { + let self_vn_devname: &[::c_char] = &self.vn_devname; + let other_vn_devname: &[::c_char] = &other.vn_devname; + + self.vn_fileid == other.vn_fileid && + self.vn_size == other.vn_size && + self.vn_dev == other.vn_dev && + self.vn_fsid == other.vn_fsid && + self.vn_mntdir == other.vn_mntdir && + self.vn_type == other.vn_type && + self.vn_mode == other.vn_mode && + self_vn_devname == other_vn_devname + } + } + impl Eq for vnstat {} + impl ::fmt::Debug for vnstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + f.debug_struct("vnstat") + .field("vn_fileid", &self.vn_fileid) + .field("vn_size", &self.vn_size) + .field("vn_dev", &self.vn_dev) + .field("vn_fsid", &self.vn_fsid) + .field("vn_mntdir", &self.vn_mntdir) + .field("vn_type", &self.vn_type) + .field("vn_mode", &self.vn_mode) + .field("vn_devname", &self_vn_devname) + .finish() + } + } + impl ::hash::Hash for vnstat { + fn hash(&self, state: &mut H) { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + self.vn_fileid.hash(state); + self.vn_size.hash(state); + self.vn_dev.hash(state); + self.vn_fsid.hash(state); + self.vn_mntdir.hash(state); + self.vn_type.hash(state); + self.vn_mode.hash(state); + self_vn_devname.hash(state); + } + } + } +} + +pub const RAND_MAX: ::c_int = 0x7fff_ffff; +pub const ELAST: ::c_int = 97; + +pub const KF_TYPE_EVENTFD: ::c_int = 13; + +/// max length of devicename +pub const SPECNAMELEN: ::c_int = 255; +pub const KI_NSPARE_PTR: usize = 5; + +/// domainset policies +pub const DOMAINSET_POLICY_INVALID: ::c_int = 0; +pub const DOMAINSET_POLICY_ROUNDROBIN: ::c_int = 1; +pub const DOMAINSET_POLICY_FIRSTTOUCH: ::c_int = 2; +pub const DOMAINSET_POLICY_PREFER: ::c_int = 3; +pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; + +pub const MINCORE_SUPER: ::c_int = 0x20; + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +extern "C" { + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn freelocale(loc: ::locale_t); + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + + pub fn cpuset_getdomain( + level: ::cpulevel_t, + which: ::cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *mut ::domainset_t, + policy: *mut ::c_int, + ) -> ::c_int; + pub fn cpuset_setdomain( + level: ::cpulevel_t, + which: ::cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *const ::domainset_t, + policy: ::c_int, + ) -> ::c_int; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_kerndisp(kd: *mut ::kvm_t) -> ::kssize_t; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs new file mode 100644 index 00000000..7bf25344 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs @@ -0,0 +1,5 @@ +pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; +pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; +pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; +pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs new file mode 100644 index 00000000..80c6fa16 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs @@ -0,0 +1,34 @@ +#[repr(C)] +#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] +pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + st_padding0: i16, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_padding1: i32, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u64, + pub st_spare: [u64; 10], +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs new file mode 100644 index 00000000..160a4baa --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs @@ -0,0 +1,546 @@ +// APIs in FreeBSD 14 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = ::c_ulong; +pub type shmatt_t = ::c_uint; +pub type kpaddr_t = u64; +pub type kssize_t = i64; +pub type domainset_t = __c_anonymous_domainset; + +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: i64, + pub udata: *mut ::c_void, + pub ext: [u64; 4], + } + + pub struct kvm_page { + pub kp_version: ::u_int, + pub kp_paddr: ::kpaddr_t, + pub kp_kmap_vaddr: ::kvaddr_t, + pub kp_dmap_vaddr: ::kvaddr_t, + pub kp_prot: ::vm_prot_t, + pub kp_offset: ::off_t, + pub kp_len: ::size_t, + } + + pub struct __c_anonymous_domainset { + _priv: [::uintptr_t; 4], + } + + pub struct kinfo_proc { + /// Size of this structure. + pub ki_structsize: ::c_int, + /// Reserved: layout identifier. + pub ki_layout: ::c_int, + /// Address of command arguments. + pub ki_args: *mut ::pargs, + // This is normally "struct proc". + /// Address of proc. + pub ki_paddr: *mut ::c_void, + // This is normally "struct user". + /// Kernel virtual address of u-area. + pub ki_addr: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to trace file. + pub ki_tracep: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to executable file. + pub ki_textvp: *mut ::c_void, + // This is normally "struct filedesc". + /// Pointer to open file info. + pub ki_fd: *mut ::c_void, + // This is normally "struct vmspace". + /// Pointer to kernel vmspace struct. + pub ki_vmspace: *mut ::c_void, + /// Sleep address. + pub ki_wchan: *const ::c_void, + /// Process identifier. + pub ki_pid: ::pid_t, + /// Parent process ID. + pub ki_ppid: ::pid_t, + /// Process group ID. + pub ki_pgid: ::pid_t, + /// tty process group ID. + pub ki_tpgid: ::pid_t, + /// Process session ID. + pub ki_sid: ::pid_t, + /// Terminal session ID. + pub ki_tsid: ::pid_t, + /// Job control counter. + pub ki_jobc: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short1: ::c_short, + /// Controlling tty dev. + pub ki_tdev_freebsd11: u32, + /// Signals arrived but not delivered. + pub ki_siglist: ::sigset_t, + /// Current signal mask. + pub ki_sigmask: ::sigset_t, + /// Signals being ignored. + pub ki_sigignore: ::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: ::sigset_t, + /// Effective user ID. + pub ki_uid: ::uid_t, + /// Real user ID. + pub ki_ruid: ::uid_t, + /// Saved effective user ID. + pub ki_svuid: ::uid_t, + /// Real group ID. + pub ki_rgid: ::gid_t, + /// Saved effective group ID. + pub ki_svgid: ::gid_t, + /// Number of groups. + pub ki_ngroups: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short2: ::c_short, + /// Groups. + pub ki_groups: [::gid_t; ::KI_NGROUPS], + /// Virtual size. + pub ki_size: ::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: ::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: ::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: ::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: ::segsz_t, + /// Stack size (pages). + pub ki_ssize: ::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: ::u_short, + /// Accounting flags. + pub ki_acflag: ::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: ::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: ::u_int, + /// Time since last blocked. + pub ki_slptime: ::u_int, + /// Time swapped in or out. + pub ki_swtime: ::u_int, + /// Number of copy-on-write faults. + pub ki_cow: ::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: ::timeval, + /// Time used by process children. + pub ki_childtime: ::timeval, + /// P_* flags. + pub ki_flag: ::c_long, + /// KI_* flags (below). + pub ki_kiflag: ::c_long, + /// Kernel trace points. + pub ki_traceflag: ::c_int, + /// S* process status. + pub ki_stat: ::c_char, + /// Process "nice" value. + pub ki_nice: i8, // signed char + /// Process lock (prevent swap) count. + pub ki_lock: ::c_char, + /// Run queue index. + pub ki_rqindex: ::c_char, + /// Which cpu we are on. + pub ki_oncpu_old: ::c_uchar, + /// Last cpu we were on. + pub ki_lastcpu_old: ::c_uchar, + /// Thread name. + pub ki_tdname: [::c_char; ::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [::c_char; ::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [::c_char; ::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [::c_char; ::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], + /// Spare string space. + pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq + /// Spare room for growth. + pub ki_spareints: [::c_int; ::KI_NSPARE_INT], + /// Controlling tty dev. + pub ki_tdev: u64, + /// Which cpu we are on. + pub ki_oncpu: ::c_int, + /// Last cpu we were on. + pub ki_lastcpu: ::c_int, + /// PID of tracing process. + pub ki_tracer: ::c_int, + /// P2_* flags. + pub ki_flag2: ::c_int, + /// Default FIB number. + pub ki_fibnum: ::c_int, + /// Credential flags. + pub ki_cr_flags: ::u_int, + /// Process jail ID. + pub ki_jid: ::c_int, + /// Number of threads in total. + pub ki_numthreads: ::c_int, + /// Thread ID. + pub ki_tid: ::lwpid_t, + /// Process priority. + pub ki_pri: ::priority, + /// Process rusage statistics. + pub ki_rusage: ::rusage, + /// rusage of children processes. + pub ki_rusage_ch: ::rusage, + // This is normally "struct pcb". + /// Kernel virtual addr of pcb. + pub ki_pcb: *mut ::c_void, + /// Kernel virtual addr of stack. + pub ki_kstack: *mut ::c_void, + /// User convenience pointer. + pub ki_udata: *mut ::c_void, + // This is normally "struct thread". + pub ki_tdaddr: *mut ::c_void, + // This is normally "struct pwddesc". + /// Pointer to process paths info. + pub ki_pd: *mut ::c_void, + pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], + pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: ::c_long, + /// kthread flag. + pub ki_tdflags: ::c_long, + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: u8, + pub d_namlen: u16, + d_pad1: u16, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_version: u32, + pub f_type: u32, + pub f_flags: u64, + pub f_bsize: u64, + pub f_iosize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: i64, + pub f_syncwrites: u64, + pub f_asyncwrites: u64, + pub f_syncreads: u64, + pub f_asyncreads: u64, + f_spare: [u64; 10], + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_fsid: ::fsid_t, + f_charspare: [::c_char; 80], + pub f_fstypename: [::c_char; 16], + pub f_mntfromname: [::c_char; 1024], + pub f_mntonname: [::c_char; 1024], + } + + pub struct vnstat { + pub vn_fileid: u64, + pub vn_size: u64, + pub vn_dev: u64, + pub vn_fsid: u64, + pub vn_mntdir: *mut ::c_char, + pub vn_type: ::c_int, + pub vn_mode: u16, + pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_version == other.f_version + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_fsid == other.f_fsid + && self.f_fstypename == other.f_fstypename + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_fsid", &self.f_fsid) + .field("f_fstypename", &self.f_fstypename) + .field("f_mntfromname", &&self.f_mntfromname[..]) + .field("f_mntonname", &&self.f_mntonname[..]) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_version.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_fsid.hash(state); + self.f_charspare.hash(state); + self.f_fstypename.hash(state); + self.f_mntfromname.hash(state); + self.f_mntonname.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name[..self.d_namlen as _] + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + .field("d_name", &&self.d_name[..self.d_namlen as _]) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name[..self.d_namlen as _].hash(state); + } + } + + impl PartialEq for vnstat { + fn eq(&self, other: &vnstat) -> bool { + let self_vn_devname: &[::c_char] = &self.vn_devname; + let other_vn_devname: &[::c_char] = &other.vn_devname; + + self.vn_fileid == other.vn_fileid && + self.vn_size == other.vn_size && + self.vn_dev == other.vn_dev && + self.vn_fsid == other.vn_fsid && + self.vn_mntdir == other.vn_mntdir && + self.vn_type == other.vn_type && + self.vn_mode == other.vn_mode && + self_vn_devname == other_vn_devname + } + } + impl Eq for vnstat {} + impl ::fmt::Debug for vnstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + f.debug_struct("vnstat") + .field("vn_fileid", &self.vn_fileid) + .field("vn_size", &self.vn_size) + .field("vn_dev", &self.vn_dev) + .field("vn_fsid", &self.vn_fsid) + .field("vn_mntdir", &self.vn_mntdir) + .field("vn_type", &self.vn_type) + .field("vn_mode", &self.vn_mode) + .field("vn_devname", &self_vn_devname) + .finish() + } + } + impl ::hash::Hash for vnstat { + fn hash(&self, state: &mut H) { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + self.vn_fileid.hash(state); + self.vn_size.hash(state); + self.vn_dev.hash(state); + self.vn_fsid.hash(state); + self.vn_mntdir.hash(state); + self.vn_type.hash(state); + self.vn_mode.hash(state); + self_vn_devname.hash(state); + } + } + } +} + +pub const RAND_MAX: ::c_int = 0x7fff_ffff; +pub const ELAST: ::c_int = 97; + +pub const KF_TYPE_EVENTFD: ::c_int = 13; + +/// max length of devicename +pub const SPECNAMELEN: ::c_int = 255; +pub const KI_NSPARE_PTR: usize = 5; + +/// domainset policies +pub const DOMAINSET_POLICY_INVALID: ::c_int = 0; +pub const DOMAINSET_POLICY_ROUNDROBIN: ::c_int = 1; +pub const DOMAINSET_POLICY_FIRSTTOUCH: ::c_int = 2; +pub const DOMAINSET_POLICY_PREFER: ::c_int = 3; +pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; + +pub const MINCORE_SUPER: ::c_int = 0x60; + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +extern "C" { + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn freelocale(loc: ::locale_t); + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + + pub fn cpuset_getdomain( + level: ::cpulevel_t, + which: ::cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *mut ::domainset_t, + policy: *mut ::c_int, + ) -> ::c_int; + pub fn cpuset_setdomain( + level: ::cpulevel_t, + which: ::cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *const ::domainset_t, + policy: ::c_int, + ) -> ::c_int; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_kerndisp(kd: *mut ::kvm_t) -> ::kssize_t; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs new file mode 100644 index 00000000..01d0b432 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs @@ -0,0 +1,12 @@ +pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; +pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; +pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; +pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; +pub const PROC_LA_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN + 2; +pub const PROC_LA_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 3; +pub const PROC_LA_CTL_LA48_ON_EXEC: ::c_int = 1; +pub const PROC_LA_CTL_LA57_ON_EXEC: ::c_int = 2; +pub const PROC_LA_CTL_DEFAULT_ON_EXEC: ::c_int = 3; +pub const PROC_LA_STATUS_LA48: ::c_int = 0x01000000; +pub const PROC_LA_STATUS_LA57: ::c_int = 0x02000000; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/b64.rs new file mode 100644 index 00000000..80c6fa16 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/b64.rs @@ -0,0 +1,34 @@ +#[repr(C)] +#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] +pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + st_padding0: i16, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_padding1: i32, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u64, + pub st_spare: [u64; 10], +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs new file mode 100644 index 00000000..d73215a6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs @@ -0,0 +1,546 @@ +// APIs in FreeBSD 15 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = ::c_ulong; +pub type shmatt_t = ::c_uint; +pub type kpaddr_t = u64; +pub type kssize_t = i64; +pub type domainset_t = __c_anonymous_domainset; + +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: i64, + pub udata: *mut ::c_void, + pub ext: [u64; 4], + } + + pub struct kvm_page { + pub kp_version: ::u_int, + pub kp_paddr: ::kpaddr_t, + pub kp_kmap_vaddr: ::kvaddr_t, + pub kp_dmap_vaddr: ::kvaddr_t, + pub kp_prot: ::vm_prot_t, + pub kp_offset: ::off_t, + pub kp_len: ::size_t, + } + + pub struct __c_anonymous_domainset { + _priv: [::uintptr_t; 4], + } + + pub struct kinfo_proc { + /// Size of this structure. + pub ki_structsize: ::c_int, + /// Reserved: layout identifier. + pub ki_layout: ::c_int, + /// Address of command arguments. + pub ki_args: *mut ::pargs, + // This is normally "struct proc". + /// Address of proc. + pub ki_paddr: *mut ::c_void, + // This is normally "struct user". + /// Kernel virtual address of u-area. + pub ki_addr: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to trace file. + pub ki_tracep: *mut ::c_void, + // This is normally "struct vnode". + /// Pointer to executable file. + pub ki_textvp: *mut ::c_void, + // This is normally "struct filedesc". + /// Pointer to open file info. + pub ki_fd: *mut ::c_void, + // This is normally "struct vmspace". + /// Pointer to kernel vmspace struct. + pub ki_vmspace: *mut ::c_void, + /// Sleep address. + pub ki_wchan: *const ::c_void, + /// Process identifier. + pub ki_pid: ::pid_t, + /// Parent process ID. + pub ki_ppid: ::pid_t, + /// Process group ID. + pub ki_pgid: ::pid_t, + /// tty process group ID. + pub ki_tpgid: ::pid_t, + /// Process session ID. + pub ki_sid: ::pid_t, + /// Terminal session ID. + pub ki_tsid: ::pid_t, + /// Job control counter. + pub ki_jobc: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short1: ::c_short, + /// Controlling tty dev. + pub ki_tdev_freebsd11: u32, + /// Signals arrived but not delivered. + pub ki_siglist: ::sigset_t, + /// Current signal mask. + pub ki_sigmask: ::sigset_t, + /// Signals being ignored. + pub ki_sigignore: ::sigset_t, + /// Signals being caught by user. + pub ki_sigcatch: ::sigset_t, + /// Effective user ID. + pub ki_uid: ::uid_t, + /// Real user ID. + pub ki_ruid: ::uid_t, + /// Saved effective user ID. + pub ki_svuid: ::uid_t, + /// Real group ID. + pub ki_rgid: ::gid_t, + /// Saved effective group ID. + pub ki_svgid: ::gid_t, + /// Number of groups. + pub ki_ngroups: ::c_short, + /// Unused (just here for alignment). + pub ki_spare_short2: ::c_short, + /// Groups. + pub ki_groups: [::gid_t; ::KI_NGROUPS], + /// Virtual size. + pub ki_size: ::vm_size_t, + /// Current resident set size in pages. + pub ki_rssize: ::segsz_t, + /// Resident set size before last swap. + pub ki_swrss: ::segsz_t, + /// Text size (pages) XXX. + pub ki_tsize: ::segsz_t, + /// Data size (pages) XXX. + pub ki_dsize: ::segsz_t, + /// Stack size (pages). + pub ki_ssize: ::segsz_t, + /// Exit status for wait & stop signal. + pub ki_xstat: ::u_short, + /// Accounting flags. + pub ki_acflag: ::u_short, + /// %cpu for process during `ki_swtime`. + pub ki_pctcpu: ::fixpt_t, + /// Time averaged value of `ki_cpticks`. + pub ki_estcpu: ::u_int, + /// Time since last blocked. + pub ki_slptime: ::u_int, + /// Time swapped in or out. + pub ki_swtime: ::u_int, + /// Number of copy-on-write faults. + pub ki_cow: ::u_int, + /// Real time in microsec. + pub ki_runtime: u64, + /// Starting time. + pub ki_start: ::timeval, + /// Time used by process children. + pub ki_childtime: ::timeval, + /// P_* flags. + pub ki_flag: ::c_long, + /// KI_* flags (below). + pub ki_kiflag: ::c_long, + /// Kernel trace points. + pub ki_traceflag: ::c_int, + /// S* process status. + pub ki_stat: ::c_char, + /// Process "nice" value. + pub ki_nice: i8, // signed char + /// Process lock (prevent swap) count. + pub ki_lock: ::c_char, + /// Run queue index. + pub ki_rqindex: ::c_char, + /// Which cpu we are on. + pub ki_oncpu_old: ::c_uchar, + /// Last cpu we were on. + pub ki_lastcpu_old: ::c_uchar, + /// Thread name. + pub ki_tdname: [::c_char; ::TDNAMLEN + 1], + /// Wchan message. + pub ki_wmesg: [::c_char; ::WMESGLEN + 1], + /// Setlogin name. + pub ki_login: [::c_char; ::LOGNAMELEN + 1], + /// Lock name. + pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], + /// Command name. + pub ki_comm: [::c_char; ::COMMLEN + 1], + /// Emulation name. + pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], + /// Login class. + pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], + /// More thread name. + pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], + /// Spare string space. + pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq + /// Spare room for growth. + pub ki_spareints: [::c_int; ::KI_NSPARE_INT], + /// Controlling tty dev. + pub ki_tdev: u64, + /// Which cpu we are on. + pub ki_oncpu: ::c_int, + /// Last cpu we were on. + pub ki_lastcpu: ::c_int, + /// PID of tracing process. + pub ki_tracer: ::c_int, + /// P2_* flags. + pub ki_flag2: ::c_int, + /// Default FIB number. + pub ki_fibnum: ::c_int, + /// Credential flags. + pub ki_cr_flags: ::u_int, + /// Process jail ID. + pub ki_jid: ::c_int, + /// Number of threads in total. + pub ki_numthreads: ::c_int, + /// Thread ID. + pub ki_tid: ::lwpid_t, + /// Process priority. + pub ki_pri: ::priority, + /// Process rusage statistics. + pub ki_rusage: ::rusage, + /// rusage of children processes. + pub ki_rusage_ch: ::rusage, + // This is normally "struct pcb". + /// Kernel virtual addr of pcb. + pub ki_pcb: *mut ::c_void, + /// Kernel virtual addr of stack. + pub ki_kstack: *mut ::c_void, + /// User convenience pointer. + pub ki_udata: *mut ::c_void, + // This is normally "struct thread". + pub ki_tdaddr: *mut ::c_void, + // This is normally "struct pwddesc". + /// Pointer to process paths info. + pub ki_pd: *mut ::c_void, + pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], + pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], + /// PS_* flags. + pub ki_sflag: ::c_long, + /// kthread flag. + pub ki_tdflags: ::c_long, + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_type: u8, + d_pad0: u8, + pub d_namlen: u16, + d_pad1: u16, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_version: u32, + pub f_type: u32, + pub f_flags: u64, + pub f_bsize: u64, + pub f_iosize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: i64, + pub f_syncwrites: u64, + pub f_asyncwrites: u64, + pub f_syncreads: u64, + pub f_asyncreads: u64, + f_spare: [u64; 10], + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_fsid: ::fsid_t, + f_charspare: [::c_char; 80], + pub f_fstypename: [::c_char; 16], + pub f_mntfromname: [::c_char; 1024], + pub f_mntonname: [::c_char; 1024], + } + + pub struct vnstat { + pub vn_fileid: u64, + pub vn_size: u64, + pub vn_dev: u64, + pub vn_fsid: u64, + pub vn_mntdir: *mut ::c_char, + pub vn_type: ::c_int, + pub vn_mode: u16, + pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_version == other.f_version + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_fsid == other.f_fsid + && self.f_fstypename == other.f_fstypename + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_fsid", &self.f_fsid) + .field("f_fstypename", &self.f_fstypename) + .field("f_mntfromname", &&self.f_mntfromname[..]) + .field("f_mntonname", &&self.f_mntonname[..]) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_version.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_fsid.hash(state); + self.f_charspare.hash(state); + self.f_fstypename.hash(state); + self.f_mntfromname.hash(state); + self.f_mntonname.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name[..self.d_namlen as _] + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + .field("d_name", &&self.d_name[..self.d_namlen as _]) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name[..self.d_namlen as _].hash(state); + } + } + + impl PartialEq for vnstat { + fn eq(&self, other: &vnstat) -> bool { + let self_vn_devname: &[::c_char] = &self.vn_devname; + let other_vn_devname: &[::c_char] = &other.vn_devname; + + self.vn_fileid == other.vn_fileid && + self.vn_size == other.vn_size && + self.vn_dev == other.vn_dev && + self.vn_fsid == other.vn_fsid && + self.vn_mntdir == other.vn_mntdir && + self.vn_type == other.vn_type && + self.vn_mode == other.vn_mode && + self_vn_devname == other_vn_devname + } + } + impl Eq for vnstat {} + impl ::fmt::Debug for vnstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + f.debug_struct("vnstat") + .field("vn_fileid", &self.vn_fileid) + .field("vn_size", &self.vn_size) + .field("vn_dev", &self.vn_dev) + .field("vn_fsid", &self.vn_fsid) + .field("vn_mntdir", &self.vn_mntdir) + .field("vn_type", &self.vn_type) + .field("vn_mode", &self.vn_mode) + .field("vn_devname", &self_vn_devname) + .finish() + } + } + impl ::hash::Hash for vnstat { + fn hash(&self, state: &mut H) { + let self_vn_devname: &[::c_char] = &self.vn_devname; + + self.vn_fileid.hash(state); + self.vn_size.hash(state); + self.vn_dev.hash(state); + self.vn_fsid.hash(state); + self.vn_mntdir.hash(state); + self.vn_type.hash(state); + self.vn_mode.hash(state); + self_vn_devname.hash(state); + } + } + } +} + +pub const RAND_MAX: ::c_int = 0x7fff_ffff; +pub const ELAST: ::c_int = 97; + +pub const KF_TYPE_EVENTFD: ::c_int = 13; + +/// max length of devicename +pub const SPECNAMELEN: ::c_int = 255; +pub const KI_NSPARE_PTR: usize = 5; + +/// domainset policies +pub const DOMAINSET_POLICY_INVALID: ::c_int = 0; +pub const DOMAINSET_POLICY_ROUNDROBIN: ::c_int = 1; +pub const DOMAINSET_POLICY_FIRSTTOUCH: ::c_int = 2; +pub const DOMAINSET_POLICY_PREFER: ::c_int = 3; +pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; + +pub const MINCORE_SUPER: ::c_int = 0x60; + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= ((major & 0xffffff00) as dev_t) << 32; + dev |= ((major & 0x000000ff) as dev_t) << 8; + dev |= ((minor & 0x0000ff00) as dev_t) << 24; + dev |= ((minor & 0xffff00ff) as dev_t) << 0; + dev + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +extern "C" { + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn freelocale(loc: ::locale_t); + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + + pub fn cpuset_getdomain( + level: ::cpulevel_t, + which: ::cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *mut ::domainset_t, + policy: *mut ::c_int, + ) -> ::c_int; + pub fn cpuset_setdomain( + level: ::cpulevel_t, + which: ::cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *const ::domainset_t, + policy: ::c_int, + ) -> ::c_int; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_kerndisp(kd: *mut ::kvm_t) -> ::kssize_t; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs new file mode 100644 index 00000000..01d0b432 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs @@ -0,0 +1,12 @@ +pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; +pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; +pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; +pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; +pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; +pub const PROC_LA_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN + 2; +pub const PROC_LA_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 3; +pub const PROC_LA_CTL_LA48_ON_EXEC: ::c_int = 1; +pub const PROC_LA_CTL_LA57_ON_EXEC: ::c_int = 2; +pub const PROC_LA_CTL_DEFAULT_ON_EXEC: ::c_int = 3; +pub const PROC_LA_STATUS_LA48: ::c_int = 0x01000000; +pub const PROC_LA_STATUS_LA57: ::c_int = 0x02000000; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs new file mode 100644 index 00000000..78314084 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -0,0 +1,5758 @@ +pub type fflags_t = u32; +pub type clock_t = i32; + +pub type vm_prot_t = u_char; +pub type kvaddr_t = u64; +pub type segsz_t = isize; +pub type __fixpt_t = u32; +pub type fixpt_t = __fixpt_t; +pub type __lwpid_t = i32; +pub type lwpid_t = __lwpid_t; +pub type blksize_t = i32; +pub type clockid_t = ::c_int; +pub type sem_t = _sem; +pub type timer_t = *mut __c_anonymous__timer; + +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type idtype_t = ::c_uint; + +pub type msglen_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; + +pub type cpulevel_t = ::c_int; +pub type cpuwhich_t = ::c_int; + +pub type mqd_t = *mut ::c_void; +pub type posix_spawnattr_t = *mut ::c_void; +pub type posix_spawn_file_actions_t = *mut ::c_void; + +pub type pthread_spinlock_t = *mut __c_anonymous_pthread_spinlock; +pub type pthread_barrierattr_t = *mut __c_anonymous_pthread_barrierattr; +pub type pthread_barrier_t = *mut __c_anonymous_pthread_barrier; + +pub type uuid_t = ::uuid; +pub type u_int = ::c_uint; +pub type u_char = ::c_uchar; +pub type u_long = ::c_ulong; +pub type u_short = ::c_ushort; + +pub type caddr_t = *mut ::c_char; + +pub type fhandle_t = fhandle; + +pub type au_id_t = ::uid_t; +pub type au_asid_t = ::pid_t; + +pub type cpusetid_t = ::c_int; + +pub type sctp_assoc_t = u32; + +pub type eventfd_t = u64; + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_support_flags { + DEVSTAT_ALL_SUPPORTED = 0x00, + DEVSTAT_NO_BLOCKSIZE = 0x01, + DEVSTAT_NO_ORDERED_TAGS = 0x02, + DEVSTAT_BS_UNAVAILABLE = 0x04, +} +impl ::Copy for devstat_support_flags {} +impl ::Clone for devstat_support_flags { + fn clone(&self) -> devstat_support_flags { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_trans_flags { + DEVSTAT_NO_DATA = 0x00, + DEVSTAT_READ = 0x01, + DEVSTAT_WRITE = 0x02, + DEVSTAT_FREE = 0x03, +} + +impl ::Copy for devstat_trans_flags {} +impl ::Clone for devstat_trans_flags { + fn clone(&self) -> devstat_trans_flags { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_tag_type { + DEVSTAT_TAG_SIMPLE = 0x00, + DEVSTAT_TAG_HEAD = 0x01, + DEVSTAT_TAG_ORDERED = 0x02, + DEVSTAT_TAG_NONE = 0x03, +} +impl ::Copy for devstat_tag_type {} +impl ::Clone for devstat_tag_type { + fn clone(&self) -> devstat_tag_type { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_match_flags { + DEVSTAT_MATCH_NONE = 0x00, + DEVSTAT_MATCH_TYPE = 0x01, + DEVSTAT_MATCH_IF = 0x02, + DEVSTAT_MATCH_PASS = 0x04, +} +impl ::Copy for devstat_match_flags {} +impl ::Clone for devstat_match_flags { + fn clone(&self) -> devstat_match_flags { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_priority { + DEVSTAT_PRIORITY_MIN = 0x000, + DEVSTAT_PRIORITY_OTHER = 0x020, + DEVSTAT_PRIORITY_PASS = 0x030, + DEVSTAT_PRIORITY_FD = 0x040, + DEVSTAT_PRIORITY_WFD = 0x050, + DEVSTAT_PRIORITY_TAPE = 0x060, + DEVSTAT_PRIORITY_CD = 0x090, + DEVSTAT_PRIORITY_DISK = 0x110, + DEVSTAT_PRIORITY_ARRAY = 0x120, + DEVSTAT_PRIORITY_MAX = 0xfff, +} +impl ::Copy for devstat_priority {} +impl ::Clone for devstat_priority { + fn clone(&self) -> devstat_priority { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_type_flags { + DEVSTAT_TYPE_DIRECT = 0x000, + DEVSTAT_TYPE_SEQUENTIAL = 0x001, + DEVSTAT_TYPE_PRINTER = 0x002, + DEVSTAT_TYPE_PROCESSOR = 0x003, + DEVSTAT_TYPE_WORM = 0x004, + DEVSTAT_TYPE_CDROM = 0x005, + DEVSTAT_TYPE_SCANNER = 0x006, + DEVSTAT_TYPE_OPTICAL = 0x007, + DEVSTAT_TYPE_CHANGER = 0x008, + DEVSTAT_TYPE_COMM = 0x009, + DEVSTAT_TYPE_ASC0 = 0x00a, + DEVSTAT_TYPE_ASC1 = 0x00b, + DEVSTAT_TYPE_STORARRAY = 0x00c, + DEVSTAT_TYPE_ENCLOSURE = 0x00d, + DEVSTAT_TYPE_FLOPPY = 0x00e, + DEVSTAT_TYPE_MASK = 0x00f, + DEVSTAT_TYPE_IF_SCSI = 0x010, + DEVSTAT_TYPE_IF_IDE = 0x020, + DEVSTAT_TYPE_IF_OTHER = 0x030, + DEVSTAT_TYPE_IF_MASK = 0x0f0, + DEVSTAT_TYPE_PASS = 0x100, +} +impl ::Copy for devstat_type_flags {} +impl ::Clone for devstat_type_flags { + fn clone(&self) -> devstat_type_flags { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_metric { + DSM_NONE, + DSM_TOTAL_BYTES, + DSM_TOTAL_BYTES_READ, + DSM_TOTAL_BYTES_WRITE, + DSM_TOTAL_TRANSFERS, + DSM_TOTAL_TRANSFERS_READ, + DSM_TOTAL_TRANSFERS_WRITE, + DSM_TOTAL_TRANSFERS_OTHER, + DSM_TOTAL_BLOCKS, + DSM_TOTAL_BLOCKS_READ, + DSM_TOTAL_BLOCKS_WRITE, + DSM_KB_PER_TRANSFER, + DSM_KB_PER_TRANSFER_READ, + DSM_KB_PER_TRANSFER_WRITE, + DSM_TRANSFERS_PER_SECOND, + DSM_TRANSFERS_PER_SECOND_READ, + DSM_TRANSFERS_PER_SECOND_WRITE, + DSM_TRANSFERS_PER_SECOND_OTHER, + DSM_MB_PER_SECOND, + DSM_MB_PER_SECOND_READ, + DSM_MB_PER_SECOND_WRITE, + DSM_BLOCKS_PER_SECOND, + DSM_BLOCKS_PER_SECOND_READ, + DSM_BLOCKS_PER_SECOND_WRITE, + DSM_MS_PER_TRANSACTION, + DSM_MS_PER_TRANSACTION_READ, + DSM_MS_PER_TRANSACTION_WRITE, + DSM_SKIP, + DSM_TOTAL_BYTES_FREE, + DSM_TOTAL_TRANSFERS_FREE, + DSM_TOTAL_BLOCKS_FREE, + DSM_KB_PER_TRANSFER_FREE, + DSM_MB_PER_SECOND_FREE, + DSM_TRANSFERS_PER_SECOND_FREE, + DSM_BLOCKS_PER_SECOND_FREE, + DSM_MS_PER_TRANSACTION_OTHER, + DSM_MS_PER_TRANSACTION_FREE, + DSM_BUSY_PCT, + DSM_QUEUE_LENGTH, + DSM_TOTAL_DURATION, + DSM_TOTAL_DURATION_READ, + DSM_TOTAL_DURATION_WRITE, + DSM_TOTAL_DURATION_FREE, + DSM_TOTAL_DURATION_OTHER, + DSM_TOTAL_BUSY_TIME, + DSM_MAX, +} +impl ::Copy for devstat_metric {} +impl ::Clone for devstat_metric { + fn clone(&self) -> devstat_metric { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] +#[repr(u32)] +pub enum devstat_select_mode { + DS_SELECT_ADD, + DS_SELECT_ONLY, + DS_SELECT_REMOVE, + DS_SELECT_ADDONLY, +} +impl ::Copy for devstat_select_mode {} +impl ::Clone for devstat_select_mode { + fn clone(&self) -> devstat_select_mode { + *self + } +} + +s! { + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + __unused1: [::c_int; 2], + __unused2: *mut ::c_void, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + // unused 3 through 5 are the __aiocb_private structure + __unused3: ::c_long, + __unused4: ::c_long, + __unused5: *mut ::c_void, + pub aio_sigevent: sigevent + } + + pub struct jail { + pub version: u32, + pub path: *mut ::c_char, + pub hostname: *mut ::c_char, + pub jailname: *mut ::c_char, + pub ip4s: ::c_uint, + pub ip6s: ::c_uint, + pub ip4: *mut ::in_addr, + pub ip6: *mut ::in6_addr, + } + + pub struct statvfs { + pub f_bavail: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_blocks: ::fsblkcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_bsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_fsid: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + // internal structure has changed over time + pub struct _sem { + data: [u32; 4], + } + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + pub msg_cbytes: ::msglen_t, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::ssize_t, + } + + pub struct sockcred { + pub sc_uid: ::uid_t, + pub sc_euid: ::uid_t, + pub sc_gid: ::gid_t, + pub sc_egid: ::gid_t, + pub sc_ngroups: ::c_int, + pub sc_groups: [::gid_t; 1], + } + + pub struct ptrace_vm_entry { + pub pve_entry: ::c_int, + pub pve_timestamp: ::c_int, + pub pve_start: ::c_ulong, + pub pve_end: ::c_ulong, + pub pve_offset: ::c_ulong, + pub pve_prot: ::c_uint, + pub pve_pathlen: ::c_uint, + pub pve_fileid: ::c_long, + pub pve_fsid: u32, + pub pve_path: *mut ::c_char, + } + + pub struct ptrace_lwpinfo { + pub pl_lwpid: lwpid_t, + pub pl_event: ::c_int, + pub pl_flags: ::c_int, + pub pl_sigmask: ::sigset_t, + pub pl_siglist: ::sigset_t, + pub pl_siginfo: ::siginfo_t, + pub pl_tdname: [::c_char; ::MAXCOMLEN as usize + 1], + pub pl_child_pid: ::pid_t, + pub pl_syscall_code: ::c_uint, + pub pl_syscall_narg: ::c_uint, + } + + pub struct ptrace_sc_ret { + pub sr_retval: [::register_t; 2], + pub sr_error: ::c_int, + } + + pub struct ptrace_coredump { + pub pc_fd: ::c_int, + pub pc_flags: u32, + pub pc_limit: ::off_t, + } + + pub struct ptrace_sc_remote { + pub pscr_ret: ptrace_sc_ret, + pub pscr_syscall: ::c_uint, + pub pscr_nargs: ::c_uint, + pub pscr_args: *mut ::register_t, + } + + pub struct cpuset_t { + #[cfg(all(any(freebsd15, freebsd14), target_pointer_width = "64"))] + __bits: [::c_long; 16], + #[cfg(all(any(freebsd15, freebsd14), target_pointer_width = "32"))] + __bits: [::c_long; 32], + #[cfg(all(not(any(freebsd15, freebsd14)), target_pointer_width = "64"))] + __bits: [::c_long; 4], + #[cfg(all(not(any(freebsd15, freebsd14)), target_pointer_width = "32"))] + __bits: [::c_long; 8], + } + + pub struct cap_rights_t { + cr_rights: [u64; 2], + } + + pub struct umutex { + m_owner: ::lwpid_t, + m_flags: u32, + m_ceilings: [u32; 2], + m_rb_link: ::uintptr_t, + #[cfg(target_pointer_width = "32")] + m_pad: u32, + m_spare: [u32; 2], + + } + + pub struct ucond { + c_has_waiters: u32, + c_flags: u32, + c_clockid: u32, + c_spare: [u32; 1], + } + + pub struct uuid { + pub time_low: u32, + pub time_mid: u16, + pub time_hi_and_version: u16, + pub clock_seq_hi_and_reserved: u8, + pub clock_seq_low: u8, + pub node: [u8; _UUID_NODE_LEN], + } + + pub struct __c_anonymous_pthread_spinlock { + s_clock: umutex, + } + + pub struct __c_anonymous_pthread_barrierattr { + pshared: ::c_int, + } + + pub struct __c_anonymous_pthread_barrier { + b_lock: umutex, + b_cv: ucond, + b_cycle: i64, + b_count: ::c_int, + b_waiters: ::c_int, + b_refcount: ::c_int, + b_destroying: ::c_int, + } + + pub struct kinfo_vmentry { + pub kve_structsize: ::c_int, + pub kve_type: ::c_int, + pub kve_start: u64, + pub kve_end: u64, + pub kve_offset: u64, + pub kve_vn_fileid: u64, + #[cfg(not(freebsd11))] + pub kve_vn_fsid_freebsd11: u32, + #[cfg(freebsd11)] + pub kve_vn_fsid: u32, + pub kve_flags: ::c_int, + pub kve_resident: ::c_int, + pub kve_private_resident: ::c_int, + pub kve_protection: ::c_int, + pub kve_ref_count: ::c_int, + pub kve_shadow_count: ::c_int, + pub kve_vn_type: ::c_int, + pub kve_vn_size: u64, + #[cfg(not(freebsd11))] + pub kve_vn_rdev_freebsd11: u32, + #[cfg(freebsd11)] + pub kve_vn_rdev: u32, + pub kve_vn_mode: u16, + pub kve_status: u16, + #[cfg(not(freebsd11))] + pub kve_vn_fsid: u64, + #[cfg(not(freebsd11))] + pub kve_vn_rdev: u64, + #[cfg(not(freebsd11))] + _kve_is_spare: [::c_int; 8], + #[cfg(freebsd11)] + _kve_is_spare: [::c_int; 12], + pub kve_path: [[::c_char; 32]; 32], + } + + pub struct __c_anonymous_filestat { + pub stqe_next: *mut filestat, + } + + pub struct filestat { + pub fs_type: ::c_int, + pub fs_flags: ::c_int, + pub fs_fflags: ::c_int, + pub fs_uflags: ::c_int, + pub fs_fd: ::c_int, + pub fs_ref_count: ::c_int, + pub fs_offset: ::off_t, + pub fs_typedep: *mut ::c_void, + pub fs_path: *mut ::c_char, + pub next: __c_anonymous_filestat, + pub fs_cap_rights: cap_rights_t, + } + + pub struct filestat_list { + pub stqh_first: *mut filestat, + pub stqh_last: *mut *mut filestat, + } + + pub struct procstat { + pub tpe: ::c_int, + pub kd: ::uintptr_t, + pub vmentries: *mut ::c_void, + pub files: *mut ::c_void, + pub argv: *mut ::c_void, + pub envv: *mut ::c_void, + pub core: ::uintptr_t, + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct __c_anonymous__timer { + _priv: [::c_int; 3], + } + + /// Used to hold a copy of the command line, if it had a sane length. + pub struct pargs { + /// Reference count. + pub ar_ref: u_int, + /// Length. + pub ar_length: u_int, + /// Arguments. + pub ar_args: [::c_uchar; 1], + } + + pub struct priority { + /// Scheduling class. + pub pri_class: u_char, + /// Normal priority level. + pub pri_level: u_char, + /// Priority before propagation. + pub pri_native: u_char, + /// User priority based on p_cpu and p_nice. + pub pri_user: u_char, + } + + pub struct kvm_swap { + pub ksw_devname: [::c_char; 32], + pub ksw_used: u_int, + pub ksw_total: u_int, + pub ksw_flags: ::c_int, + pub ksw_reserved1: u_int, + pub ksw_reserved2: u_int, + } + + pub struct nlist { + /// symbol name (in memory) + pub n_name: *const ::c_char, + /// type defines + pub n_type: ::c_uchar, + /// "type" and binding information + pub n_other: ::c_char, + /// used by stab entries + pub n_desc: ::c_short, + pub n_value: ::c_ulong, + } + + pub struct kvm_nlist { + pub n_name: *const ::c_char, + pub n_type: ::c_uchar, + pub n_value: ::kvaddr_t, + } + + pub struct __c_anonymous_sem { + _priv: ::uintptr_t, + } + + pub struct semid_ds { + pub sem_perm: ::ipc_perm, + pub __sem_base: *mut __c_anonymous_sem, + pub sem_nsems: ::c_ushort, + pub sem_otime: ::time_t, + pub sem_ctime: ::time_t, + } + + pub struct vmtotal { + pub t_vm: u64, + pub t_avm: u64, + pub t_rm: u64, + pub t_arm: u64, + pub t_vmshr: u64, + pub t_avmshr: u64, + pub t_rmshr: u64, + pub t_armshr: u64, + pub t_free: u64, + pub t_rq: i16, + pub t_dw: i16, + pub t_pw: i16, + pub t_sl: i16, + pub t_sw: i16, + pub t_pad: [u16; 3], + } + + pub struct sockstat { + pub inp_ppcb: u64, + pub so_addr: u64, + pub so_pcb: u64, + pub unp_conn: u64, + pub dom_family: ::c_int, + pub proto: ::c_int, + pub so_rcv_sb_state: ::c_int, + pub so_snd_sb_state: ::c_int, + /// Socket address. + pub sa_local: ::sockaddr_storage, + /// Peer address. + pub sa_peer: ::sockaddr_storage, + pub type_: ::c_int, + pub dname: [::c_char; 32], + #[cfg(any(freebsd12, freebsd13, freebsd14, freebsd15))] + pub sendq: ::c_uint, + #[cfg(any(freebsd12, freebsd13, freebsd14, freebsd15))] + pub recvq: ::c_uint, + } + + pub struct shmstat { + pub size: u64, + pub mode: u16, + } + + pub struct spacectl_range { + pub r_offset: ::off_t, + pub r_len: ::off_t + } + + pub struct rusage_ext { + pub rux_runtime: u64, + pub rux_uticks: u64, + pub rux_sticks: u64, + pub rux_iticks: u64, + pub rux_uu: u64, + pub rux_su: u64, + pub rux_tu: u64, + } + + pub struct if_clonereq { + pub ifcr_total: ::c_int, + pub ifcr_count: ::c_int, + pub ifcr_buffer: *mut ::c_char, + } + + pub struct if_msghdr { + /// to skip over non-understood messages + pub ifm_msglen: ::c_ushort, + /// future binary compatibility + pub ifm_version: ::c_uchar, + /// message type + pub ifm_type: ::c_uchar, + /// like rtm_addrs + pub ifm_addrs: ::c_int, + /// value of if_flags + pub ifm_flags: ::c_int, + /// index for associated ifp + pub ifm_index: ::c_ushort, + pub _ifm_spare1: ::c_ushort, + /// statistics and other data about if + pub ifm_data: if_data, + } + + pub struct if_msghdrl { + /// to skip over non-understood messages + pub ifm_msglen: ::c_ushort, + /// future binary compatibility + pub ifm_version: ::c_uchar, + /// message type + pub ifm_type: ::c_uchar, + /// like rtm_addrs + pub ifm_addrs: ::c_int, + /// value of if_flags + pub ifm_flags: ::c_int, + /// index for associated ifp + pub ifm_index: ::c_ushort, + /// spare space to grow if_index, see if_var.h + pub _ifm_spare1: ::c_ushort, + /// length of if_msghdrl incl. if_data + pub ifm_len: ::c_ushort, + /// offset of if_data from beginning + pub ifm_data_off: ::c_ushort, + pub _ifm_spare2: ::c_int, + /// statistics and other data about if + pub ifm_data: if_data, + } + + pub struct ifa_msghdr { + /// to skip over non-understood messages + pub ifam_msglen: ::c_ushort, + /// future binary compatibility + pub ifam_version: ::c_uchar, + /// message type + pub ifam_type: ::c_uchar, + /// like rtm_addrs + pub ifam_addrs: ::c_int, + /// value of ifa_flags + pub ifam_flags: ::c_int, + /// index for associated ifp + pub ifam_index: ::c_ushort, + pub _ifam_spare1: ::c_ushort, + /// value of ifa_ifp->if_metric + pub ifam_metric: ::c_int, + } + + pub struct ifa_msghdrl { + /// to skip over non-understood messages + pub ifam_msglen: ::c_ushort, + /// future binary compatibility + pub ifam_version: ::c_uchar, + /// message type + pub ifam_type: ::c_uchar, + /// like rtm_addrs + pub ifam_addrs: ::c_int, + /// value of ifa_flags + pub ifam_flags: ::c_int, + /// index for associated ifp + pub ifam_index: ::c_ushort, + /// spare space to grow if_index, see if_var.h + pub _ifam_spare1: ::c_ushort, + /// length of ifa_msghdrl incl. if_data + pub ifam_len: ::c_ushort, + /// offset of if_data from beginning + pub ifam_data_off: ::c_ushort, + /// value of ifa_ifp->if_metric + pub ifam_metric: ::c_int, + /// statistics and other data about if or address + pub ifam_data: if_data, + } + + pub struct ifma_msghdr { + /// to skip over non-understood messages + pub ifmam_msglen: ::c_ushort, + /// future binary compatibility + pub ifmam_version: ::c_uchar, + /// message type + pub ifmam_type: ::c_uchar, + /// like rtm_addrs + pub ifmam_addrs: ::c_int, + /// value of ifa_flags + pub ifmam_flags: ::c_int, + /// index for associated ifp + pub ifmam_index: ::c_ushort, + pub _ifmam_spare1: ::c_ushort, + } + + pub struct if_announcemsghdr { + /// to skip over non-understood messages + pub ifan_msglen: ::c_ushort, + /// future binary compatibility + pub ifan_version: ::c_uchar, + /// message type + pub ifan_type: ::c_uchar, + /// index for associated ifp + pub ifan_index: ::c_ushort, + /// if name, e.g. "en0" + pub ifan_name: [::c_char; ::IFNAMSIZ as usize], + /// what type of announcement + pub ifan_what: ::c_ushort, + } + + pub struct ifreq_buffer { + pub length: ::size_t, + pub buffer: *mut ::c_void, + } + + pub struct ifaliasreq { + /// if name, e.g. "en0" + pub ifra_name: [::c_char; ::IFNAMSIZ as usize], + pub ifra_addr: ::sockaddr, + pub ifra_broadaddr: ::sockaddr, + pub ifra_mask: ::sockaddr, + pub ifra_vhid: ::c_int, + } + + /// 9.x compat + pub struct oifaliasreq { + /// if name, e.g. "en0" + pub ifra_name: [::c_char; ::IFNAMSIZ as usize], + pub ifra_addr: ::sockaddr, + pub ifra_broadaddr: ::sockaddr, + pub ifra_mask: ::sockaddr, + } + + pub struct ifmediareq { + /// if name, e.g. "en0" + pub ifm_name: [::c_char; ::IFNAMSIZ as usize], + /// current media options + pub ifm_current: ::c_int, + /// don't care mask + pub ifm_mask: ::c_int, + /// media status + pub ifm_status: ::c_int, + /// active options + pub ifm_active: ::c_int, + /// # entries in ifm_ulist array + pub ifm_count: ::c_int, + /// media words + pub ifm_ulist: *mut ::c_int, + } + + pub struct ifdrv { + /// if name, e.g. "en0" + pub ifd_name: [::c_char; ::IFNAMSIZ as usize], + pub ifd_cmd: ::c_ulong, + pub ifd_len: ::size_t, + pub ifd_data: *mut ::c_void, + } + + pub struct ifi2creq { + /// i2c address (0xA0, 0xA2) + pub dev_addr: u8, + /// read offset + pub offset: u8, + /// read length + pub len: u8, + pub spare0: u8, + pub spare1: u32, + /// read buffer + pub data: [u8; 8], + } + + pub struct ifrsshash { + /// if name, e.g. "en0" + pub ifrh_name: [::c_char; ::IFNAMSIZ as usize], + /// RSS_FUNC_ + pub ifrh_func: u8, + pub ifrh_spare0: u8, + pub ifrh_spare1: u16, + /// RSS_TYPE_ + pub ifrh_types: u32, + } + + pub struct ifmibdata { + /// name of interface + pub ifmd_name: [::c_char; ::IFNAMSIZ as usize], + /// number of promiscuous listeners + pub ifmd_pcount: ::c_int, + /// interface flags + pub ifmd_flags: ::c_int, + /// instantaneous length of send queue + pub ifmd_snd_len: ::c_int, + /// maximum length of send queue + pub ifmd_snd_maxlen: ::c_int, + /// number of drops in send queue + pub ifmd_snd_drops: ::c_int, + /// for future expansion + pub ifmd_filler: [::c_int; 4], + /// generic information and statistics + pub ifmd_data: if_data, + } + + pub struct ifmib_iso_8802_3 { + pub dot3StatsAlignmentErrors: u32, + pub dot3StatsFCSErrors: u32, + pub dot3StatsSingleCollisionFrames: u32, + pub dot3StatsMultipleCollisionFrames: u32, + pub dot3StatsSQETestErrors: u32, + pub dot3StatsDeferredTransmissions: u32, + pub dot3StatsLateCollisions: u32, + pub dot3StatsExcessiveCollisions: u32, + pub dot3StatsInternalMacTransmitErrors: u32, + pub dot3StatsCarrierSenseErrors: u32, + pub dot3StatsFrameTooLongs: u32, + pub dot3StatsInternalMacReceiveErrors: u32, + pub dot3StatsEtherChipSet: u32, + pub dot3StatsMissedFrames: u32, + pub dot3StatsCollFrequencies: [u32; 16], + pub dot3Compliance: u32, + } + + pub struct __c_anonymous_ph { + pub ph1: u64, + pub ph2: u64, + } + + pub struct fid { + pub fid_len: ::c_ushort, + pub fid_data0: ::c_ushort, + pub fid_data: [::c_char; ::MAXFIDSZ as usize], + } + + pub struct fhandle { + pub fh_fsid: ::fsid_t, + pub fh_fid: fid, + } + + pub struct bintime { + pub sec: ::time_t, + pub frac: u64, + } + + pub struct clockinfo { + /// clock frequency + pub hz: ::c_int, + /// micro-seconds per hz tick + pub tick: ::c_int, + pub spare: ::c_int, + /// statistics clock frequency + pub stathz: ::c_int, + /// profiling clock frequency + pub profhz: ::c_int, + } + + pub struct __c_anonymous_stailq_entry_devstat { + pub stqe_next: *mut devstat, + } + + pub struct devstat { + /// Update sequence + pub sequence0: ::u_int, + /// Allocated entry + pub allocated: ::c_int, + /// started ops + pub start_count: ::u_int, + /// completed ops + pub end_count: ::u_int, + /// busy time unaccounted for since this time + pub busy_from: bintime, + pub dev_links: __c_anonymous_stailq_entry_devstat, + /// Devstat device number. + pub device_number: u32, + pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize], + pub unit_number: ::c_int, + pub bytes: [u64; DEVSTAT_N_TRANS_FLAGS as usize], + pub operations: [u64; DEVSTAT_N_TRANS_FLAGS as usize], + pub duration: [bintime; DEVSTAT_N_TRANS_FLAGS as usize], + pub busy_time: bintime, + /// Time the device was created. + pub creation_time: bintime, + /// Block size, bytes + pub block_size: u32, + /// The number of simple, ordered, and head of queue tags sent. + pub tag_types: [u64; 3], + /// Which statistics are supported by a given device. + pub flags: devstat_support_flags, + /// Device type + pub device_type: devstat_type_flags, + /// Controls list pos. + pub priority: devstat_priority, + /// Identification for GEOM nodes + pub id: *const ::c_void, + /// Update sequence + pub sequence1: ::u_int, + } + + pub struct devstat_match { + pub match_fields: devstat_match_flags, + pub device_type: devstat_type_flags, + pub num_match_categories: ::c_int, + } + + pub struct devstat_match_table { + pub match_str: *const ::c_char, + pub type_: devstat_type_flags, + pub match_field: devstat_match_flags, + } + + pub struct device_selection { + pub device_number: u32, + pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize], + pub unit_number: ::c_int, + pub selected: ::c_int, + pub bytes: u64, + pub position: ::c_int, + } + + pub struct devinfo { + pub devices: *mut devstat, + pub mem_ptr: *mut u8, + pub generation: ::c_long, + pub numdevs: ::c_int, + } + + pub struct sockcred2 { + pub sc_version: ::c_int, + pub sc_pid: ::pid_t, + pub sc_uid: ::uid_t, + pub sc_euid: ::uid_t, + pub sc_gid: ::gid_t, + pub sc_egid: ::gid_t, + pub sc_ngroups: ::c_int, + pub sc_groups: [::gid_t; 1], + } + + pub struct ifconf { + pub ifc_len: ::c_int, + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ifreq, + } + + pub struct au_mask_t { + pub am_success: ::c_uint, + pub am_failure: ::c_uint, + } + + pub struct au_tid_t { + pub port: u32, + pub machine: u32, + } + + pub struct auditinfo_t { + pub ai_auid: ::au_id_t, + pub ai_mask: ::au_mask_t, + pub ai_termid: au_tid_t, + pub ai_asid: ::au_asid_t, + } + + pub struct tcp_fastopen { + pub enable: ::c_int, + pub psk: [u8; ::TCP_FASTOPEN_PSK_LEN as usize], + } + + pub struct tcp_function_set { + pub function_set_name: [::c_char; ::TCP_FUNCTION_NAME_LEN_MAX as usize], + pub pcbcnt: u32, + } + + // Note: this structure will change in a backwards-incompatible way in + // FreeBSD 15. + pub struct tcp_info { + pub tcpi_state: u8, + pub __tcpi_ca_state: u8, + pub __tcpi_retransmits: u8, + pub __tcpi_probes: u8, + pub __tcpi_backoff: u8, + pub tcpi_options: u8, + pub tcp_snd_wscale: u8, + pub tcp_rcv_wscale: u8, + pub tcpi_rto: u32, + pub __tcpi_ato: u32, + pub tcpi_snd_mss: u32, + pub tcpi_rcv_mss: u32, + pub __tcpi_unacked: u32, + pub __tcpi_sacked: u32, + pub __tcpi_lost: u32, + pub __tcpi_retrans: u32, + pub __tcpi_fackets: u32, + pub __tcpi_last_data_sent: u32, + pub __tcpi_last_ack_sent: u32, + pub tcpi_last_data_recv: u32, + pub __tcpi_last_ack_recv: u32, + pub __tcpi_pmtu: u32, + pub __tcpi_rcv_ssthresh: u32, + pub tcpi_rtt: u32, + pub tcpi_rttvar: u32, + pub tcpi_snd_ssthresh: u32, + pub tcpi_snd_cwnd: u32, + pub __tcpi_advmss: u32, + pub __tcpi_reordering: u32, + pub __tcpi_rcv_rtt: u32, + pub tcpi_rcv_space: u32, + pub tcpi_snd_wnd: u32, + pub tcpi_snd_bwnd: u32, + pub tcpi_snd_nxt: u32, + pub tcpi_rcv_nxt: u32, + pub tcpi_toe_tid: u32, + pub tcpi_snd_rexmitpack: u32, + pub tcpi_rcv_ooopack: u32, + pub tcpi_snd_zerowin: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_delivered_ce: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_received_ce: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_delivered_e1_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_delivered_e0_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_delivered_ce_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_received_e1_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_received_e0_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_received_ce_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_total_tlp: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_total_tlp_bytes: u64, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_snd_una: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_snd_max: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_rcv_numsacks: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_rcv_adv: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_dupacks: u32, + #[cfg(freebsd14)] + pub __tcpi_pad: [u32; 10], + #[cfg(freebsd15)] + pub __tcpi_pad: [u32; 14], + #[cfg(not(any(freebsd15, freebsd14)))] + pub __tcpi_pad: [u32; 26], + } + + pub struct _umtx_time { + pub _timeout: ::timespec, + pub _flags: u32, + pub _clockid: u32, + } + + pub struct shm_largepage_conf { + pub psind: ::c_int, + pub alloc_policy: ::c_int, + __pad: [::c_int; 10], + } + + pub struct memory_type { + __priva: [::uintptr_t; 32], + __privb: [::uintptr_t; 26], + } + + pub struct memory_type_list { + __priv: [::uintptr_t; 2], + } + + pub struct pidfh { + __priva: [[::uintptr_t; 32]; 8], + __privb: [::uintptr_t; 2], + } + + pub struct sctp_event { + pub se_assoc_id: ::sctp_assoc_t, + pub se_type: u16, + pub se_on: u8, + } + + pub struct sctp_event_subscribe { + pub sctp_data_io_event: u8, + pub sctp_association_event: u8, + pub sctp_address_event: u8, + pub sctp_send_failure_event: u8, + pub sctp_peer_error_event: u8, + pub sctp_shutdown_event: u8, + pub sctp_partial_delivery_event: u8, + pub sctp_adaptation_layer_event: u8, + pub sctp_authentication_event: u8, + pub sctp_sender_dry_event: u8, + pub sctp_stream_reset_event: u8, + } + + pub struct sctp_initmsg { + pub sinit_num_ostreams: u16, + pub sinit_max_instreams: u16, + pub sinit_max_attempts: u16, + pub sinit_max_init_timeo: u16, + } + + pub struct sctp_sndrcvinfo { + pub sinfo_stream: u16, + pub sinfo_ssn: u16, + pub sinfo_flags: u16, + pub sinfo_ppid: u32, + pub sinfo_context: u32, + pub sinfo_timetolive: u32, + pub sinfo_tsn: u32, + pub sinfo_cumtsn: u32, + pub sinfo_assoc_id: ::sctp_assoc_t, + pub sinfo_keynumber: u16, + pub sinfo_keynumber_valid: u16, + pub __reserve_pad: [[u8; 23]; 4], + } + + pub struct sctp_extrcvinfo { + pub sinfo_stream: u16, + pub sinfo_ssn: u16, + pub sinfo_flags: u16, + pub sinfo_ppid: u32, + pub sinfo_context: u32, + pub sinfo_timetolive: u32, + pub sinfo_tsn: u32, + pub sinfo_cumtsn: u32, + pub sinfo_assoc_id: ::sctp_assoc_t, + pub serinfo_next_flags: u16, + pub serinfo_next_stream: u16, + pub serinfo_next_aid: u32, + pub serinfo_next_length: u32, + pub serinfo_next_ppid: u32, + pub sinfo_keynumber: u16, + pub sinfo_keynumber_valid: u16, + pub __reserve_pad: [[u8; 19]; 4], + } + + pub struct sctp_sndinfo { + pub snd_sid: u16, + pub snd_flags: u16, + pub snd_ppid: u32, + pub snd_context: u32, + pub snd_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_prinfo { + pub pr_policy: u16, + pub pr_value: u32, + } + + pub struct sctp_default_prinfo { + pub pr_policy: u16, + pub pr_value: u32, + pub pr_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_authinfo { + pub auth_keynumber: u16, + } + + pub struct sctp_rcvinfo { + pub rcv_sid: u16, + pub rcv_ssn: u16, + pub rcv_flags: u16, + pub rcv_ppid: u32, + pub rcv_tsn: u32, + pub rcv_cumtsn: u32, + pub rcv_context: u32, + pub rcv_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_nxtinfo { + pub nxt_sid: u16, + pub nxt_flags: u16, + pub nxt_ppid: u32, + pub nxt_length: u32, + pub nxt_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_recvv_rn { + pub recvv_rcvinfo: sctp_rcvinfo, + pub recvv_nxtinfo: sctp_nxtinfo, + } + + pub struct sctp_sendv_spa { + pub sendv_flags: u32, + pub sendv_sndinfo: sctp_sndinfo, + pub sendv_prinfo: sctp_prinfo, + pub sendv_authinfo: sctp_authinfo, + } + + pub struct sctp_snd_all_completes { + pub sall_stream: u16, + pub sall_flags: u16, + pub sall_ppid: u32, + pub sall_context: u32, + pub sall_num_sent: u32, + pub sall_num_failed: u32, + } + + pub struct sctp_pcbinfo { + pub ep_count: u32, + pub asoc_count: u32, + pub laddr_count: u32, + pub raddr_count: u32, + pub chk_count: u32, + pub readq_count: u32, + pub free_chunks: u32, + pub stream_oque: u32, + } + + pub struct sctp_sockstat { + pub ss_assoc_id: ::sctp_assoc_t, + pub ss_total_sndbuf: u32, + pub ss_total_recv_buf: u32, + } + + pub struct sctp_assoc_change { + pub sac_type: u16, + pub sac_flags: u16, + pub sac_length: u32, + pub sac_state: u16, + pub sac_error: u16, + pub sac_outbound_streams: u16, + pub sac_inbound_streams: u16, + pub sac_assoc_id: ::sctp_assoc_t, + pub sac_info: [u8; 0], + } + + pub struct sctp_paddr_change { + pub spc_type: u16, + pub spc_flags: u16, + pub spc_length: u32, + pub spc_aaddr: ::sockaddr_storage, + pub spc_state: u32, + pub spc_error: u32, + pub spc_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_remote_error { + pub sre_type: u16, + pub sre_flags: u16, + pub sre_length: u32, + pub sre_error: u16, + pub sre_assoc_id: ::sctp_assoc_t, + pub sre_data: [u8; 0], + } + + pub struct sctp_send_failed_event { + pub ssfe_type: u16, + pub ssfe_flags: u16, + pub ssfe_length: u32, + pub ssfe_error: u32, + pub ssfe_info: sctp_sndinfo, + pub ssfe_assoc_id: ::sctp_assoc_t, + pub ssfe_data: [u8; 0], + } + + pub struct sctp_shutdown_event { + pub sse_type: u16, + pub sse_flags: u16, + pub sse_length: u32, + pub sse_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_adaptation_event { + pub sai_type: u16, + pub sai_flags: u16, + pub sai_length: u32, + pub sai_adaptation_ind: u32, + pub sai_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_setadaptation { + pub ssb_adaptation_ind: u32, + } + + pub struct sctp_pdapi_event { + pub pdapi_type: u16, + pub pdapi_flags: u16, + pub pdapi_length: u32, + pub pdapi_indication: u32, + pub pdapi_stream: u16, + pub pdapi_seq: u16, + pub pdapi_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_sender_dry_event { + pub sender_dry_type: u16, + pub sender_dry_flags: u16, + pub sender_dry_length: u32, + pub sender_dry_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_stream_reset_event { + pub strreset_type: u16, + pub strreset_flags: u16, + pub strreset_length: u32, + pub strreset_assoc_id: ::sctp_assoc_t, + pub strreset_stream_list: [u16; 0], + } + + pub struct sctp_stream_change_event { + pub strchange_type: u16, + pub strchange_flags: u16, + pub strchange_length: u32, + pub strchange_assoc_id: ::sctp_assoc_t, + pub strchange_instrms: u16, + pub strchange_outstrms: u16, + } +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_id: [::c_char; 8], + pub ut_pid: ::pid_t, + pub ut_user: [::c_char; 32], + pub ut_line: [::c_char; 16], + pub ut_host: [::c_char; 128], + pub __ut_spare: [::c_char; 64], + } + + #[cfg(libc_union)] + pub union __c_anonymous_cr_pid { + __cr_unused: *mut ::c_void, + pub cr_pid: ::pid_t, + } + + pub struct xucred { + pub cr_version: ::c_uint, + pub cr_uid: ::uid_t, + pub cr_ngroups: ::c_short, + pub cr_groups: [::gid_t; 16], + #[cfg(libc_union)] + pub cr_pid__c_anonymous_union: __c_anonymous_cr_pid, + #[cfg(not(libc_union))] + __cr_unused1: *mut ::c_void, + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 46], + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + __reserved: [::c_long; 4] + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + //The rest of the structure is actually a union. We expose only + //sigev_notify_thread_id because it's the most useful union member. + pub sigev_notify_thread_id: ::lwpid_t, + #[cfg(target_pointer_width = "64")] + __unused1: ::c_int, + __unused2: [::c_long; 7] + } + + pub struct ptsstat { + #[cfg(any(freebsd12, freebsd13, freebsd14, freebsd15))] + pub dev: u64, + #[cfg(not(any(freebsd12, freebsd13, freebsd14, freebsd15)))] + pub dev: u32, + pub devname: [::c_char; SPECNAMELEN as usize + 1], + } + + #[cfg(libc_union)] + pub union __c_anonymous_elf32_auxv_union { + pub a_val: ::c_int, + } + + pub struct Elf32_Auxinfo { + pub a_type: ::c_int, + #[cfg(libc_union)] + pub a_un: __c_anonymous_elf32_auxv_union, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifi_epoch { + pub tt: ::time_t, + pub ph: u64, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifi_lastchange { + pub tv: ::timeval, + pub ph: __c_anonymous_ph, + } + + pub struct if_data { + /// ethernet, tokenring, etc + pub ifi_type: u8, + /// e.g., AUI, Thinnet, 10base-T, etc + pub ifi_physical: u8, + /// media address length + pub ifi_addrlen: u8, + /// media header length + pub ifi_hdrlen: u8, + /// current link state + pub ifi_link_state: u8, + /// carp vhid + pub ifi_vhid: u8, + /// length of this data struct + pub ifi_datalen: u16, + /// maximum transmission unit + pub ifi_mtu: u32, + /// routing metric (external only) + pub ifi_metric: u32, + /// linespeed + pub ifi_baudrate: u64, + /// packets received on interface + pub ifi_ipackets: u64, + /// input errors on interface + pub ifi_ierrors: u64, + /// packets sent on interface + pub ifi_opackets: u64, + /// output errors on interface + pub ifi_oerrors: u64, + /// collisions on csma interfaces + pub ifi_collisions: u64, + /// total number of octets received + pub ifi_ibytes: u64, + /// total number of octets sent + pub ifi_obytes: u64, + /// packets received via multicast + pub ifi_imcasts: u64, + /// packets sent via multicast + pub ifi_omcasts: u64, + /// dropped on input + pub ifi_iqdrops: u64, + /// dropped on output + pub ifi_oqdrops: u64, + /// destined for unsupported protocol + pub ifi_noproto: u64, + /// HW offload capabilities, see IFCAP + pub ifi_hwassist: u64, + /// uptime at attach or stat reset + #[cfg(libc_union)] + pub __ifi_epoch: __c_anonymous_ifi_epoch, + /// uptime at attach or stat reset + #[cfg(not(libc_union))] + pub __ifi_epoch: u64, + /// time of last administrative change + #[cfg(libc_union)] + pub __ifi_lastchange: __c_anonymous_ifi_lastchange, + /// time of last administrative change + #[cfg(not(libc_union))] + pub __ifi_lastchange: ::timeval, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_buffer: ifreq_buffer, + pub ifru_flags: [::c_short; 2], + pub ifru_index: ::c_short, + pub ifru_jid: ::c_int, + pub ifru_metric: ::c_int, + pub ifru_mtu: ::c_int, + pub ifru_phys: ::c_int, + pub ifru_media: ::c_int, + pub ifru_data: ::caddr_t, + pub ifru_cap: [::c_int; 2], + pub ifru_fib: ::c_uint, + pub ifru_vlan_pcp: ::c_uchar, + } + + pub struct ifreq { + /// if name, e.g. "en0" + pub ifr_name: [::c_char; ::IFNAMSIZ], + #[cfg(libc_union)] + pub ifr_ifru: __c_anonymous_ifr_ifru, + #[cfg(not(libc_union))] + pub ifr_ifru: ::sockaddr, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: ::caddr_t, + pub ifcu_req: *mut ifreq, + } + + pub struct ifstat { + /// if name, e.g. "en0" + pub ifs_name: [::c_char; ::IFNAMSIZ as usize], + pub ascii: [::c_char; ::IFSTATMAX as usize + 1], + } + + pub struct ifrsskey { + /// if name, e.g. "en0" + pub ifrk_name: [::c_char; ::IFNAMSIZ as usize], + /// RSS_FUNC_ + pub ifrk_func: u8, + pub ifrk_spare0: u8, + pub ifrk_keylen: u16, + pub ifrk_key: [u8; ::RSS_KEYLEN as usize], + } + + pub struct ifdownreason { + pub ifdr_name: [::c_char; ::IFNAMSIZ as usize], + pub ifdr_reason: u32, + pub ifdr_vendor: u32, + pub ifdr_msg: [::c_char; ::IFDR_MSG_SIZE as usize], + } + + #[repr(packed)] + pub struct sctphdr { + pub src_port: u16, + pub dest_port: u16, + pub v_tag: u32, + pub checksum: u32, + } + + #[repr(packed)] + pub struct sctp_chunkhdr { + pub chunk_type: u8, + pub chunk_flags: u8, + pub chunk_length: u16, + } + + #[repr(packed)] + pub struct sctp_paramhdr { + pub param_type: u16, + pub param_length: u16, + } + + #[repr(packed)] + pub struct sctp_gen_error_cause { + pub code: u16, + pub length: u16, + pub info: [u8; 0], + } + + #[repr(packed)] + pub struct sctp_error_cause { + pub code: u16, + pub length: u16, + } + + #[repr(packed)] + pub struct sctp_error_invalid_stream { + pub cause: sctp_error_cause, + pub stream_id: u16, + __reserved: u16, + } + + #[repr(packed)] + pub struct sctp_error_missing_param { + pub cause: sctp_error_cause, + pub num_missing_params: u32, + pub tpe: [u8; 0], + } + + #[repr(packed)] + pub struct sctp_error_stale_cookie { + pub cause: sctp_error_cause, + pub stale_time: u32, + } + + #[repr(packed)] + pub struct sctp_error_out_of_resource { + pub cause: sctp_error_cause, + } + + #[repr(packed)] + pub struct sctp_error_unresolv_addr { + pub cause: sctp_error_cause, + } + + #[repr(packed)] + pub struct sctp_error_unrecognized_chunk { + pub cause: sctp_error_cause, + pub ch: sctp_chunkhdr, + } + + #[repr(packed)] + pub struct sctp_error_no_user_data { + pub cause: sctp_error_cause, + pub tsn: u32, + } + + #[repr(packed)] + pub struct sctp_error_auth_invalid_hmac { + pub cause: sctp_error_cause, + pub hmac_id: u16, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_tv == other.ut_tv + && self.ut_id == other.ut_id + && self.ut_pid == other.ut_pid + && self.ut_user == other.ut_user + && self.ut_line == other.ut_line + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self + .__ut_spare + .iter() + .zip(other.__ut_spare.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for utmpx {} + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + .field("ut_tv", &self.ut_tv) + .field("ut_id", &self.ut_id) + .field("ut_pid", &self.ut_pid) + .field("ut_user", &self.ut_user) + .field("ut_line", &self.ut_line) + // FIXME: .field("ut_host", &self.ut_host) + // FIXME: .field("__ut_spare", &self.__ut_spare) + .finish() + } + } + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_tv.hash(state); + self.ut_id.hash(state); + self.ut_pid.hash(state); + self.ut_user.hash(state); + self.ut_line.hash(state); + self.ut_host.hash(state); + self.__ut_spare.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_cr_pid { + fn eq(&self, other: &__c_anonymous_cr_pid) -> bool { + unsafe { self.cr_pid == other.cr_pid} + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_cr_pid {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_cr_pid { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("cr_pid") + .field("cr_pid", unsafe { &self.cr_pid }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_cr_pid { + fn hash(&self, state: &mut H) { + unsafe { self.cr_pid.hash(state) }; + } + } + + impl PartialEq for xucred { + fn eq(&self, other: &xucred) -> bool { + #[cfg(libc_union)] + let equal_cr_pid = self.cr_pid__c_anonymous_union + == other.cr_pid__c_anonymous_union; + #[cfg(not(libc_union))] + let equal_cr_pid = self.__cr_unused1 == other.__cr_unused1; + + self.cr_version == other.cr_version + && self.cr_uid == other.cr_uid + && self.cr_ngroups == other.cr_ngroups + && self.cr_groups == other.cr_groups + && equal_cr_pid + } + } + impl Eq for xucred {} + impl ::fmt::Debug for xucred { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let mut struct_formatter = f.debug_struct("xucred"); + struct_formatter.field("cr_version", &self.cr_version); + struct_formatter.field("cr_uid", &self.cr_uid); + struct_formatter.field("cr_ngroups", &self.cr_ngroups); + struct_formatter.field("cr_groups", &self.cr_groups); + #[cfg(libc_union)] + struct_formatter.field( + "cr_pid__c_anonymous_union", + &self.cr_pid__c_anonymous_union + ); + struct_formatter.finish() + } + } + impl ::hash::Hash for xucred { + fn hash(&self, state: &mut H) { + self.cr_version.hash(state); + self.cr_uid.hash(state); + self.cr_ngroups.hash(state); + self.cr_groups.hash(state); + #[cfg(libc_union)] + self.cr_pid__c_anonymous_union.hash(state); + #[cfg(not(libc_union))] + self.__cr_unused1.hash(state); + } + } + + impl PartialEq for sockaddr_dl { + fn eq(&self, other: &sockaddr_dl) -> bool { + self.sdl_len == other.sdl_len + && self.sdl_family == other.sdl_family + && self.sdl_index == other.sdl_index + && self.sdl_type == other.sdl_type + && self.sdl_nlen == other.sdl_nlen + && self.sdl_alen == other.sdl_alen + && self.sdl_slen == other.sdl_slen + && self + .sdl_data + .iter() + .zip(other.sdl_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_dl {} + impl ::fmt::Debug for sockaddr_dl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_dl") + .field("sdl_len", &self.sdl_len) + .field("sdl_family", &self.sdl_family) + .field("sdl_index", &self.sdl_index) + .field("sdl_type", &self.sdl_type) + .field("sdl_nlen", &self.sdl_nlen) + .field("sdl_alen", &self.sdl_alen) + .field("sdl_slen", &self.sdl_slen) + // FIXME: .field("sdl_data", &self.sdl_data) + .finish() + } + } + impl ::hash::Hash for sockaddr_dl { + fn hash(&self, state: &mut H) { + self.sdl_len.hash(state); + self.sdl_family.hash(state); + self.sdl_index.hash(state); + self.sdl_type.hash(state); + self.sdl_nlen.hash(state); + self.sdl_alen.hash(state); + self.sdl_slen.hash(state); + self.sdl_data.hash(state); + } + } + + impl PartialEq for mq_attr { + fn eq(&self, other: &mq_attr) -> bool { + self.mq_flags == other.mq_flags && + self.mq_maxmsg == other.mq_maxmsg && + self.mq_msgsize == other.mq_msgsize && + self.mq_curmsgs == other.mq_curmsgs + } + } + impl Eq for mq_attr {} + impl ::fmt::Debug for mq_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mq_attr") + .field("mq_flags", &self.mq_flags) + .field("mq_maxmsg", &self.mq_maxmsg) + .field("mq_msgsize", &self.mq_msgsize) + .field("mq_curmsgs", &self.mq_curmsgs) + .finish() + } + } + impl ::hash::Hash for mq_attr { + fn hash(&self, state: &mut H) { + self.mq_flags.hash(state); + self.mq_maxmsg.hash(state); + self.mq_msgsize.hash(state); + self.mq_curmsgs.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + && self.sigev_notify_thread_id + == other.sigev_notify_thread_id + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .field("sigev_notify_thread_id", + &self.sigev_notify_thread_id) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + self.sigev_notify_thread_id.hash(state); + } + } + + impl PartialEq for ptsstat { + fn eq(&self, other: &ptsstat) -> bool { + let self_devname: &[::c_char] = &self.devname; + let other_devname: &[::c_char] = &other.devname; + + self.dev == other.dev && self_devname == other_devname + } + } + impl Eq for ptsstat {} + impl ::fmt::Debug for ptsstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let self_devname: &[::c_char] = &self.devname; + + f.debug_struct("ptsstat") + .field("dev", &self.dev) + .field("devname", &self_devname) + .finish() + } + } + impl ::hash::Hash for ptsstat { + fn hash(&self, state: &mut H) { + let self_devname: &[::c_char] = &self.devname; + + self.dev.hash(state); + self_devname.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_elf32_auxv_union { + fn eq(&self, other: &__c_anonymous_elf32_auxv_union) -> bool { + unsafe { self.a_val == other.a_val} + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_elf32_auxv_union {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_elf32_auxv_union { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("a_val") + .field("a_val", unsafe { &self.a_val }) + .finish() + } + } + #[cfg(not(libc_union))] + impl PartialEq for Elf32_Auxinfo { + fn eq(&self, other: &Elf32_Auxinfo) -> bool { + self.a_type == other.a_type + } + } + #[cfg(libc_union)] + impl PartialEq for Elf32_Auxinfo { + fn eq(&self, other: &Elf32_Auxinfo) -> bool { + self.a_type == other.a_type + && self.a_un == other.a_un + } + } + impl Eq for Elf32_Auxinfo {} + #[cfg(not(libc_union))] + impl ::fmt::Debug for Elf32_Auxinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("Elf32_Auxinfo") + .field("a_type", &self.a_type) + .finish() + } + } + #[cfg(libc_union)] + impl ::fmt::Debug for Elf32_Auxinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("Elf32_Auxinfo") + .field("a_type", &self.a_type) + .field("a_un", &self.a_un) + .finish() + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifr_ifru { + fn eq(&self, other: &__c_anonymous_ifr_ifru) -> bool { + unsafe { + self.ifru_addr == other.ifru_addr && + self.ifru_dstaddr == other.ifru_dstaddr && + self.ifru_broadaddr == other.ifru_broadaddr && + self.ifru_buffer == other.ifru_buffer && + self.ifru_flags == other.ifru_flags && + self.ifru_index == other.ifru_index && + self.ifru_jid == other.ifru_jid && + self.ifru_metric == other.ifru_metric && + self.ifru_mtu == other.ifru_mtu && + self.ifru_phys == other.ifru_phys && + self.ifru_media == other.ifru_media && + self.ifru_data == other.ifru_data && + self.ifru_cap == other.ifru_cap && + self.ifru_fib == other.ifru_fib && + self.ifru_vlan_pcp == other.ifru_vlan_pcp + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifr_ifru {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifr_ifru { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifru_addr", unsafe { &self.ifru_addr }) + .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) + .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) + .field("ifru_buffer", unsafe { &self.ifru_buffer }) + .field("ifru_flags", unsafe { &self.ifru_flags }) + .field("ifru_index", unsafe { &self.ifru_index }) + .field("ifru_jid", unsafe { &self.ifru_jid }) + .field("ifru_metric", unsafe { &self.ifru_metric }) + .field("ifru_mtu", unsafe { &self.ifru_mtu }) + .field("ifru_phys", unsafe { &self.ifru_phys }) + .field("ifru_media", unsafe { &self.ifru_media }) + .field("ifru_data", unsafe { &self.ifru_data }) + .field("ifru_cap", unsafe { &self.ifru_cap }) + .field("ifru_fib", unsafe { &self.ifru_fib }) + .field("ifru_vlan_pcp", unsafe { &self.ifru_vlan_pcp }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifr_ifru { + fn hash(&self, state: &mut H) { + unsafe { self.ifru_addr.hash(state) }; + unsafe { self.ifru_dstaddr.hash(state) }; + unsafe { self.ifru_broadaddr.hash(state) }; + unsafe { self.ifru_buffer.hash(state) }; + unsafe { self.ifru_flags.hash(state) }; + unsafe { self.ifru_index.hash(state) }; + unsafe { self.ifru_jid.hash(state) }; + unsafe { self.ifru_metric.hash(state) }; + unsafe { self.ifru_mtu.hash(state) }; + unsafe { self.ifru_phys.hash(state) }; + unsafe { self.ifru_media.hash(state) }; + unsafe { self.ifru_data.hash(state) }; + unsafe { self.ifru_cap.hash(state) }; + unsafe { self.ifru_fib.hash(state) }; + unsafe { self.ifru_vlan_pcp.hash(state) }; + } + } + + impl PartialEq for ifreq { + fn eq(&self, other: &ifreq) -> bool { + self.ifr_name == other.ifr_name && self.ifr_ifru == other.ifr_ifru + } + } + impl Eq for ifreq {} + impl ::fmt::Debug for ifreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifreq") + .field("ifr_name", &self.ifr_name) + .field("ifr_ifru", &self.ifr_ifru) + .finish() + } + } + impl ::hash::Hash for ifreq { + fn hash(&self, state: &mut H) { + self.ifr_name.hash(state); + self.ifr_ifru.hash(state); + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifc_ifcu {} + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifc_ifcu { + fn eq(&self, other: &__c_anonymous_ifc_ifcu) -> bool { + unsafe { + self.ifcu_buf == other.ifcu_buf && + self.ifcu_req == other.ifcu_req + } + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifc_ifcu") + .field("ifcu_buf", unsafe { &self.ifcu_buf }) + .field("ifcu_req", unsafe { &self.ifcu_req }) + .finish() + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifc_ifcu { + fn hash(&self, state: &mut H) { + unsafe { self.ifcu_buf.hash(state) }; + unsafe { self.ifcu_req.hash(state) }; + } + } + + impl PartialEq for ifstat { + fn eq(&self, other: &ifstat) -> bool { + let self_ascii: &[::c_char] = &self.ascii; + let other_ascii: &[::c_char] = &other.ascii; + + self.ifs_name == other.ifs_name && self_ascii == other_ascii + } + } + impl Eq for ifstat {} + impl ::fmt::Debug for ifstat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ascii: &[::c_char] = &self.ascii; + + f.debug_struct("ifstat") + .field("ifs_name", &self.ifs_name) + .field("ascii", &ascii) + .finish() + } + } + impl ::hash::Hash for ifstat { + fn hash(&self, state: &mut H) { + self.ifs_name.hash(state); + self.ascii.hash(state); + } + } + + impl PartialEq for ifrsskey { + fn eq(&self, other: &ifrsskey) -> bool { + let self_ifrk_key: &[u8] = &self.ifrk_key; + let other_ifrk_key: &[u8] = &other.ifrk_key; + + self.ifrk_name == other.ifrk_name && + self.ifrk_func == other.ifrk_func && + self.ifrk_spare0 == other.ifrk_spare0 && + self.ifrk_keylen == other.ifrk_keylen && + self_ifrk_key == other_ifrk_key + } + } + impl Eq for ifrsskey {} + impl ::fmt::Debug for ifrsskey { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ifrk_key: &[u8] = &self.ifrk_key; + + f.debug_struct("ifrsskey") + .field("ifrk_name", &self.ifrk_name) + .field("ifrk_func", &self.ifrk_func) + .field("ifrk_spare0", &self.ifrk_spare0) + .field("ifrk_keylen", &self.ifrk_keylen) + .field("ifrk_key", &ifrk_key) + .finish() + } + } + impl ::hash::Hash for ifrsskey { + fn hash(&self, state: &mut H) { + self.ifrk_name.hash(state); + self.ifrk_func.hash(state); + self.ifrk_spare0.hash(state); + self.ifrk_keylen.hash(state); + self.ifrk_key.hash(state); + } + } + + impl PartialEq for ifdownreason { + fn eq(&self, other: &ifdownreason) -> bool { + let self_ifdr_msg: &[::c_char] = &self.ifdr_msg; + let other_ifdr_msg: &[::c_char] = &other.ifdr_msg; + + self.ifdr_name == other.ifdr_name && + self.ifdr_reason == other.ifdr_reason && + self.ifdr_vendor == other.ifdr_vendor && + self_ifdr_msg == other_ifdr_msg + } + } + impl Eq for ifdownreason {} + impl ::fmt::Debug for ifdownreason { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ifdr_msg: &[::c_char] = &self.ifdr_msg; + + f.debug_struct("ifdownreason") + .field("ifdr_name", &self.ifdr_name) + .field("ifdr_reason", &self.ifdr_reason) + .field("ifdr_vendor", &self.ifdr_vendor) + .field("ifdr_msg", &ifdr_msg) + .finish() + } + } + impl ::hash::Hash for ifdownreason { + fn hash(&self, state: &mut H) { + self.ifdr_name.hash(state); + self.ifdr_reason.hash(state); + self.ifdr_vendor.hash(state); + self.ifdr_msg.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifi_epoch { + fn eq(&self, other: &__c_anonymous_ifi_epoch) -> bool { + unsafe { + self.tt == other.tt && + self.ph == other.ph + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifi_epoch {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifi_epoch { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__c_anonymous_ifi_epoch") + .field("tt", unsafe { &self.tt }) + .field("ph", unsafe { &self.ph }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifi_epoch { + fn hash(&self, state: &mut H) { + unsafe { + self.tt.hash(state); + self.ph.hash(state); + } + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifi_lastchange { + fn eq(&self, other: &__c_anonymous_ifi_lastchange) -> bool { + unsafe { + self.tv == other.tv && + self.ph == other.ph + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifi_lastchange {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifi_lastchange { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__c_anonymous_ifi_lastchange") + .field("tv", unsafe { &self.tv }) + .field("ph", unsafe { &self.ph }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifi_lastchange { + fn hash(&self, state: &mut H) { + unsafe { + self.tv.hash(state); + self.ph.hash(state); + } + } + } + + impl PartialEq for if_data { + fn eq(&self, other: &if_data) -> bool { + self.ifi_type == other.ifi_type && + self.ifi_physical == other.ifi_physical && + self.ifi_addrlen == other.ifi_addrlen && + self.ifi_hdrlen == other.ifi_hdrlen && + self.ifi_link_state == other.ifi_link_state && + self.ifi_vhid == other.ifi_vhid && + self.ifi_datalen == other.ifi_datalen && + self.ifi_mtu == other.ifi_mtu && + self.ifi_metric == other.ifi_metric && + self.ifi_baudrate == other.ifi_baudrate && + self.ifi_ipackets == other.ifi_ipackets && + self.ifi_ierrors == other.ifi_ierrors && + self.ifi_opackets == other.ifi_opackets && + self.ifi_oerrors == other.ifi_oerrors && + self.ifi_collisions == other.ifi_collisions && + self.ifi_ibytes == other.ifi_ibytes && + self.ifi_obytes == other.ifi_obytes && + self.ifi_imcasts == other.ifi_imcasts && + self.ifi_omcasts == other.ifi_omcasts && + self.ifi_iqdrops == other.ifi_iqdrops && + self.ifi_oqdrops == other.ifi_oqdrops && + self.ifi_noproto == other.ifi_noproto && + self.ifi_hwassist == other.ifi_hwassist && + self.__ifi_epoch == other.__ifi_epoch && + self.__ifi_lastchange == other.__ifi_lastchange + } + } + impl Eq for if_data {} + impl ::fmt::Debug for if_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("if_data") + .field("ifi_type", &self.ifi_type) + .field("ifi_physical", &self.ifi_physical) + .field("ifi_addrlen", &self.ifi_addrlen) + .field("ifi_hdrlen", &self.ifi_hdrlen) + .field("ifi_link_state", &self.ifi_link_state) + .field("ifi_vhid", &self.ifi_vhid) + .field("ifi_datalen", &self.ifi_datalen) + .field("ifi_mtu", &self.ifi_mtu) + .field("ifi_metric", &self.ifi_metric) + .field("ifi_baudrate", &self.ifi_baudrate) + .field("ifi_ipackets", &self.ifi_ipackets) + .field("ifi_ierrors", &self.ifi_ierrors) + .field("ifi_opackets", &self.ifi_opackets) + .field("ifi_oerrors", &self.ifi_oerrors) + .field("ifi_collisions", &self.ifi_collisions) + .field("ifi_ibytes", &self.ifi_ibytes) + .field("ifi_obytes", &self.ifi_obytes) + .field("ifi_imcasts", &self.ifi_imcasts) + .field("ifi_omcasts", &self.ifi_omcasts) + .field("ifi_iqdrops", &self.ifi_iqdrops) + .field("ifi_oqdrops", &self.ifi_oqdrops) + .field("ifi_noproto", &self.ifi_noproto) + .field("ifi_hwassist", &self.ifi_hwassist) + .field("__ifi_epoch", &self.__ifi_epoch) + .field("__ifi_lastchange", &self.__ifi_lastchange) + .finish() + } + } + impl ::hash::Hash for if_data { + fn hash(&self, state: &mut H) { + self.ifi_type.hash(state); + self.ifi_physical.hash(state); + self.ifi_addrlen.hash(state); + self.ifi_hdrlen.hash(state); + self.ifi_link_state.hash(state); + self.ifi_vhid.hash(state); + self.ifi_datalen.hash(state); + self.ifi_mtu.hash(state); + self.ifi_metric.hash(state); + self.ifi_baudrate.hash(state); + self.ifi_ipackets.hash(state); + self.ifi_ierrors.hash(state); + self.ifi_opackets.hash(state); + self.ifi_oerrors.hash(state); + self.ifi_collisions.hash(state); + self.ifi_ibytes.hash(state); + self.ifi_obytes.hash(state); + self.ifi_imcasts.hash(state); + self.ifi_omcasts.hash(state); + self.ifi_iqdrops.hash(state); + self.ifi_oqdrops.hash(state); + self.ifi_noproto.hash(state); + self.ifi_hwassist.hash(state); + self.__ifi_epoch.hash(state); + self.__ifi_lastchange.hash(state); + } + } + + impl PartialEq for sctphdr { + fn eq(&self, other: &sctphdr) -> bool { + return {self.src_port} == {other.src_port} && + {self.dest_port} == {other.dest_port} && + {self.v_tag} == {other.v_tag} && + {self.checksum} == {other.checksum} + } + } + impl Eq for sctphdr {} + impl ::fmt::Debug for sctphdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctphdr") + .field("src_port", &{self.src_port}) + .field("dest_port", &{self.dest_port}) + .field("v_tag", &{self.v_tag}) + .field("checksum", &{self.checksum}) + .finish() + } + } + impl ::hash::Hash for sctphdr { + fn hash(&self, state: &mut H) { + {self.src_port}.hash(state); + {self.dest_port}.hash(state); + {self.v_tag}.hash(state); + {self.checksum}.hash(state); + } + } + + impl PartialEq for sctp_chunkhdr { + fn eq(&self, other: &sctp_chunkhdr) -> bool { + return {self.chunk_type} == {other.chunk_type} && + {self.chunk_flags} == {other.chunk_flags} && + {self.chunk_length} == {other.chunk_length} + } + } + impl Eq for sctp_chunkhdr {} + impl ::fmt::Debug for sctp_chunkhdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_chunkhdr") + .field("chunk_type", &{self.chunk_type}) + .field("chunk_flags", &{self.chunk_flags}) + .field("chunk_length", &{self.chunk_length}) + .finish() + } + } + impl ::hash::Hash for sctp_chunkhdr { + fn hash(&self, state: &mut H) { + {self.chunk_type}.hash(state); + {self.chunk_flags}.hash(state); + {self.chunk_length}.hash(state); + } + } + + impl PartialEq for sctp_paramhdr { + fn eq(&self, other: &sctp_paramhdr) -> bool { + return {self.param_type} == {other.param_type} && + {self.param_length} == {other.param_length} + } + } + impl Eq for sctp_paramhdr {} + impl ::fmt::Debug for sctp_paramhdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_paramhdr") + .field("param_type", &{self.param_type}) + .field("param_length", &{self.param_length}) + .finish() + } + } + impl ::hash::Hash for sctp_paramhdr { + fn hash(&self, state: &mut H) { + {self.param_type}.hash(state); + {self.param_length}.hash(state); + } + } + + impl PartialEq for sctp_gen_error_cause { + fn eq(&self, other: &sctp_gen_error_cause) -> bool { + return {self.code} == {other.code} && + {self.length} == {other.length} && + {self.info}.iter().zip({other.info}.iter()).all(|(a,b)| a == b) + } + } + impl Eq for sctp_gen_error_cause {} + impl ::fmt::Debug for sctp_gen_error_cause { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_gen_error_cause") + .field("code", &{self.code}) + .field("length", &{self.length}) + // FIXME: .field("info", &{self.info}) + .finish() + } + } + impl ::hash::Hash for sctp_gen_error_cause { + fn hash(&self, state: &mut H) { + {self.code}.hash(state); + {self.length}.hash(state); + {self.info}.hash(state); + } + } + + impl PartialEq for sctp_error_cause { + fn eq(&self, other: &sctp_error_cause) -> bool { + return {self.code} == {other.code} && + {self.length} == {other.length} + } + } + impl Eq for sctp_error_cause {} + impl ::fmt::Debug for sctp_error_cause { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_cause") + .field("code", &{self.code}) + .field("length", &{self.length}) + .finish() + } + } + impl ::hash::Hash for sctp_error_cause { + fn hash(&self, state: &mut H) { + {self.code}.hash(state); + {self.length}.hash(state); + } + } + + impl PartialEq for sctp_error_invalid_stream { + fn eq(&self, other: &sctp_error_invalid_stream) -> bool { + return {self.cause} == {other.cause} && + {self.stream_id} == {other.stream_id} + } + } + impl Eq for sctp_error_invalid_stream {} + impl ::fmt::Debug for sctp_error_invalid_stream { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_invalid_stream") + .field("cause", &{self.cause}) + .field("stream_id", &{self.stream_id}) + .finish() + } + } + impl ::hash::Hash for sctp_error_invalid_stream { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.stream_id}.hash(state); + } + } + + impl PartialEq for sctp_error_missing_param { + fn eq(&self, other: &sctp_error_missing_param) -> bool { + return {self.cause} == {other.cause} && + {self.num_missing_params} == {other.num_missing_params} && + {self.tpe}.iter().zip({other.tpe}.iter()).all(|(a,b)| a == b) + } + } + impl Eq for sctp_error_missing_param {} + impl ::fmt::Debug for sctp_error_missing_param { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_missing_param") + .field("cause", &{self.cause}) + .field("num_missing_params", &{self.num_missing_params}) + // FIXME: .field("tpe", &{self.tpe}) + .finish() + } + } + impl ::hash::Hash for sctp_error_missing_param { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.num_missing_params}.hash(state); + {self.tpe}.hash(state); + } + } + + impl PartialEq for sctp_error_stale_cookie { + fn eq(&self, other: &sctp_error_stale_cookie) -> bool { + return {self.cause} == {other.cause} && + {self.stale_time} == {other.stale_time} + } + } + impl Eq for sctp_error_stale_cookie {} + impl ::fmt::Debug for sctp_error_stale_cookie { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_stale_cookie") + .field("cause", &{self.cause}) + .field("stale_time", &{self.stale_time}) + .finish() + } + } + impl ::hash::Hash for sctp_error_stale_cookie { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.stale_time}.hash(state); + } + } + + impl PartialEq for sctp_error_out_of_resource { + fn eq(&self, other: &sctp_error_out_of_resource) -> bool { + return {self.cause} == {other.cause} + } + } + impl Eq for sctp_error_out_of_resource {} + impl ::fmt::Debug for sctp_error_out_of_resource { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_out_of_resource") + .field("cause", &{self.cause}) + .finish() + } + } + impl ::hash::Hash for sctp_error_out_of_resource { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + } + } + + impl PartialEq for sctp_error_unresolv_addr { + fn eq(&self, other: &sctp_error_unresolv_addr) -> bool { + return {self.cause} == {other.cause} + } + } + impl Eq for sctp_error_unresolv_addr {} + impl ::fmt::Debug for sctp_error_unresolv_addr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_unresolv_addr") + .field("cause", &{self.cause}) + .finish() + } + } + impl ::hash::Hash for sctp_error_unresolv_addr { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + } + } + + impl PartialEq for sctp_error_unrecognized_chunk { + fn eq(&self, other: &sctp_error_unrecognized_chunk) -> bool { + return {self.cause} == {other.cause} && + {self.ch} == {other.ch} + } + } + impl Eq for sctp_error_unrecognized_chunk {} + impl ::fmt::Debug for sctp_error_unrecognized_chunk { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_unrecognized_chunk") + .field("cause", &{self.cause}) + .field("ch", &{self.ch}) + .finish() + } + } + impl ::hash::Hash for sctp_error_unrecognized_chunk { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.ch}.hash(state); + } + } + + impl PartialEq for sctp_error_no_user_data { + fn eq(&self, other: &sctp_error_no_user_data) -> bool { + return {self.cause} == {other.cause} && + {self.tsn} == {other.tsn} + } + } + impl Eq for sctp_error_no_user_data {} + impl ::fmt::Debug for sctp_error_no_user_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_no_user_data") + .field("cause", &{self.cause}) + .field("tsn", &{self.tsn}) + .finish() + } + } + impl ::hash::Hash for sctp_error_no_user_data { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.tsn}.hash(state); + } + } + + impl PartialEq for sctp_error_auth_invalid_hmac { + fn eq(&self, other: &sctp_error_auth_invalid_hmac) -> bool { + return {self.cause} == {other.cause} && + {self.hmac_id} == {other.hmac_id} + } + } + impl Eq for sctp_error_auth_invalid_hmac {} + impl ::fmt::Debug for sctp_error_auth_invalid_hmac { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_invalid_hmac") + .field("cause", &{self.cause}) + .field("hmac_id", &{self.hmac_id}) + .finish() + } + } + impl ::hash::Hash for sctp_error_auth_invalid_hmac { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.hmac_id}.hash(state); + } + } + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +#[repr(u32)] +pub enum dot3Vendors { + dot3VendorAMD = 1, + dot3VendorIntel = 2, + dot3VendorNational = 4, + dot3VendorFujitsu = 5, + dot3VendorDigital = 6, + dot3VendorWesternDigital = 7, +} +impl ::Copy for dot3Vendors {} +impl ::Clone for dot3Vendors { + fn clone(&self) -> dot3Vendors { + *self + } +} + +// aio.h +pub const LIO_VECTORED: ::c_int = 4; +pub const LIO_WRITEV: ::c_int = 5; +pub const LIO_READV: ::c_int = 6; + +// sys/devicestat.h +pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4; +pub const DEVSTAT_NAME_LEN: ::c_int = 16; + +// sys/cpuset.h +cfg_if! { + if #[cfg(any(freebsd15, freebsd14))] { + pub const CPU_SETSIZE: ::c_int = 1024; + } else { + pub const CPU_SETSIZE: ::c_int = 256; + } +} + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; +pub const EXTATTR_NAMESPACE_USER: ::c_int = 1; +pub const EXTATTR_NAMESPACE_SYSTEM: ::c_int = 2; + +pub const PTHREAD_STACK_MIN: ::size_t = MINSIGSTKSZ; +pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 4; +pub const PTHREAD_MUTEX_STALLED: ::c_int = 0; +pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1; +pub const SIGSTKSZ: ::size_t = MINSIGSTKSZ + 32768; +pub const SF_NODISKIO: ::c_int = 0x00000001; +pub const SF_MNOWAIT: ::c_int = 0x00000002; +pub const SF_SYNC: ::c_int = 0x00000004; +pub const SF_USER_READAHEAD: ::c_int = 0x00000008; +pub const SF_NOCACHE: ::c_int = 0x00000010; +pub const O_CLOEXEC: ::c_int = 0x00100000; +pub const O_DIRECTORY: ::c_int = 0x00020000; +pub const O_DSYNC: ::c_int = 0x01000000; +pub const O_EMPTY_PATH: ::c_int = 0x02000000; +pub const O_EXEC: ::c_int = 0x00040000; +pub const O_PATH: ::c_int = 0x00400000; +pub const O_RESOLVE_BENEATH: ::c_int = 0x00800000; +pub const O_SEARCH: ::c_int = O_EXEC; +pub const O_TTY_INIT: ::c_int = 0x00080000; +pub const O_VERIFY: ::c_int = 0x00200000; +pub const F_GETLK: ::c_int = 11; +pub const F_SETLK: ::c_int = 12; +pub const F_SETLKW: ::c_int = 13; +pub const ENOTCAPABLE: ::c_int = 93; +pub const ECAPMODE: ::c_int = 94; +pub const ENOTRECOVERABLE: ::c_int = 95; +pub const EOWNERDEAD: ::c_int = 96; +pub const EINTEGRITY: ::c_int = 97; +pub const RLIMIT_NPTS: ::c_int = 11; +pub const RLIMIT_SWAP: ::c_int = 12; +pub const RLIMIT_KQUEUES: ::c_int = 13; +pub const RLIMIT_UMTXP: ::c_int = 14; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::rlim_t = 15; +pub const RLIM_SAVED_MAX: ::rlim_t = ::RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = ::RLIM_INFINITY; + +pub const CP_USER: ::c_int = 0; +pub const CP_NICE: ::c_int = 1; +pub const CP_SYS: ::c_int = 2; +pub const CP_INTR: ::c_int = 3; +pub const CP_IDLE: ::c_int = 4; +pub const CPUSTATES: ::c_int = 5; + +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x00000002; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +pub const NI_NUMERICSERV: ::c_int = 0x00000008; +pub const NI_DGRAM: ::c_int = 0x00000010; +pub const NI_NUMERICSCOPE: ::c_int = 0x00000020; + +pub const XU_NGROUPS: ::c_int = 16; + +pub const Q_GETQUOTA: ::c_int = 0x700; +pub const Q_SETQUOTA: ::c_int = 0x800; + +pub const MAP_GUARD: ::c_int = 0x00002000; +pub const MAP_EXCL: ::c_int = 0x00004000; +pub const MAP_PREFAULT_READ: ::c_int = 0x00040000; +pub const MAP_ALIGNMENT_SHIFT: ::c_int = 24; +pub const MAP_ALIGNMENT_MASK: ::c_int = 0xff << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNED_SUPER: ::c_int = 1 << MAP_ALIGNMENT_SHIFT; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POLLINIGNEOF: ::c_short = 0x2000; + +pub const EVFILT_READ: i16 = -1; +pub const EVFILT_WRITE: i16 = -2; +pub const EVFILT_AIO: i16 = -3; +pub const EVFILT_VNODE: i16 = -4; +pub const EVFILT_PROC: i16 = -5; +pub const EVFILT_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_PROCDESC: i16 = -8; +pub const EVFILT_FS: i16 = -9; +pub const EVFILT_LIO: i16 = -10; +pub const EVFILT_USER: i16 = -11; +pub const EVFILT_SENDFILE: i16 = -12; +pub const EVFILT_EMPTY: i16 = -13; + +pub const EV_ADD: u16 = 0x1; +pub const EV_DELETE: u16 = 0x2; +pub const EV_ENABLE: u16 = 0x4; +pub const EV_DISABLE: u16 = 0x8; +pub const EV_FORCEONESHOT: u16 = 0x100; +pub const EV_KEEPUDATA: u16 = 0x200; + +pub const EV_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +pub const EV_SYSFLAGS: u16 = 0xf000; +pub const EV_DROP: u16 = 0x1000; +pub const EV_FLAG1: u16 = 0x2000; +pub const EV_FLAG2: u16 = 0x4000; + +pub const EV_EOF: u16 = 0x8000; +pub const EV_ERROR: u16 = 0x4000; + +pub const NOTE_TRIGGER: u32 = 0x01000000; +pub const NOTE_FFNOP: u32 = 0x00000000; +pub const NOTE_FFAND: u32 = 0x40000000; +pub const NOTE_FFOR: u32 = 0x80000000; +pub const NOTE_FFCOPY: u32 = 0xc0000000; +pub const NOTE_FFCTRLMASK: u32 = 0xc0000000; +pub const NOTE_FFLAGSMASK: u32 = 0x00ffffff; +pub const NOTE_LOWAT: u32 = 0x00000001; +pub const NOTE_FILE_POLL: u32 = 0x00000002; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +pub const NOTE_ATTRIB: u32 = 0x00000008; +pub const NOTE_LINK: u32 = 0x00000010; +pub const NOTE_RENAME: u32 = 0x00000020; +pub const NOTE_REVOKE: u32 = 0x00000040; +pub const NOTE_OPEN: u32 = 0x00000080; +pub const NOTE_CLOSE: u32 = 0x00000100; +pub const NOTE_CLOSE_WRITE: u32 = 0x00000200; +pub const NOTE_READ: u32 = 0x00000400; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +pub const NOTE_PCTRLMASK: u32 = 0xf0000000; +pub const NOTE_TRACK: u32 = 0x00000001; +pub const NOTE_TRACKERR: u32 = 0x00000002; +pub const NOTE_CHILD: u32 = 0x00000004; +pub const NOTE_SECONDS: u32 = 0x00000001; +pub const NOTE_MSECONDS: u32 = 0x00000002; +pub const NOTE_USECONDS: u32 = 0x00000004; +pub const NOTE_NSECONDS: u32 = 0x00000008; +pub const NOTE_ABSTIME: u32 = 0x00000010; + +pub const MADV_PROTECT: ::c_int = 10; + +#[doc(hidden)] +#[deprecated( + since = "0.2.72", + note = "CTL_UNSPEC is deprecated. Use CTL_SYSCTL instead" +)] +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_SYSCTL: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_VFS: ::c_int = 3; +pub const CTL_NET: ::c_int = 4; +pub const CTL_DEBUG: ::c_int = 5; +pub const CTL_HW: ::c_int = 6; +pub const CTL_MACHDEP: ::c_int = 7; +pub const CTL_USER: ::c_int = 8; +pub const CTL_P1003_1B: ::c_int = 9; + +// sys/sysctl.h +pub const CTL_MAXNAME: ::c_int = 24; + +pub const CTLTYPE: ::c_int = 0xf; +pub const CTLTYPE_NODE: ::c_int = 1; +pub const CTLTYPE_INT: ::c_int = 2; +pub const CTLTYPE_STRING: ::c_int = 3; +pub const CTLTYPE_S64: ::c_int = 4; +pub const CTLTYPE_OPAQUE: ::c_int = 5; +pub const CTLTYPE_STRUCT: ::c_int = CTLTYPE_OPAQUE; +pub const CTLTYPE_UINT: ::c_int = 6; +pub const CTLTYPE_LONG: ::c_int = 7; +pub const CTLTYPE_ULONG: ::c_int = 8; +pub const CTLTYPE_U64: ::c_int = 9; +pub const CTLTYPE_U8: ::c_int = 0xa; +pub const CTLTYPE_U16: ::c_int = 0xb; +pub const CTLTYPE_S8: ::c_int = 0xc; +pub const CTLTYPE_S16: ::c_int = 0xd; +pub const CTLTYPE_S32: ::c_int = 0xe; +pub const CTLTYPE_U32: ::c_int = 0xf; + +pub const CTLFLAG_RD: ::c_int = 0x80000000; +pub const CTLFLAG_WR: ::c_int = 0x40000000; +pub const CTLFLAG_RW: ::c_int = CTLFLAG_RD | CTLFLAG_WR; +pub const CTLFLAG_DORMANT: ::c_int = 0x20000000; +pub const CTLFLAG_ANYBODY: ::c_int = 0x10000000; +pub const CTLFLAG_SECURE: ::c_int = 0x08000000; +pub const CTLFLAG_PRISON: ::c_int = 0x04000000; +pub const CTLFLAG_DYN: ::c_int = 0x02000000; +pub const CTLFLAG_SKIP: ::c_int = 0x01000000; +pub const CTLMASK_SECURE: ::c_int = 0x00F00000; +pub const CTLFLAG_TUN: ::c_int = 0x00080000; +pub const CTLFLAG_RDTUN: ::c_int = CTLFLAG_RD | CTLFLAG_TUN; +pub const CTLFLAG_RWTUN: ::c_int = CTLFLAG_RW | CTLFLAG_TUN; +pub const CTLFLAG_MPSAFE: ::c_int = 0x00040000; +pub const CTLFLAG_VNET: ::c_int = 0x00020000; +pub const CTLFLAG_DYING: ::c_int = 0x00010000; +pub const CTLFLAG_CAPRD: ::c_int = 0x00008000; +pub const CTLFLAG_CAPWR: ::c_int = 0x00004000; +pub const CTLFLAG_STATS: ::c_int = 0x00002000; +pub const CTLFLAG_NOFETCH: ::c_int = 0x00001000; +pub const CTLFLAG_CAPRW: ::c_int = CTLFLAG_CAPRD | CTLFLAG_CAPWR; +pub const CTLFLAG_NEEDGIANT: ::c_int = 0x00000800; + +pub const CTLSHIFT_SECURE: ::c_int = 20; +pub const CTLFLAG_SECURE1: ::c_int = CTLFLAG_SECURE | (0 << CTLSHIFT_SECURE); +pub const CTLFLAG_SECURE2: ::c_int = CTLFLAG_SECURE | (1 << CTLSHIFT_SECURE); +pub const CTLFLAG_SECURE3: ::c_int = CTLFLAG_SECURE | (2 << CTLSHIFT_SECURE); + +pub const OID_AUTO: ::c_int = -1; + +pub const CTL_SYSCTL_DEBUG: ::c_int = 0; +pub const CTL_SYSCTL_NAME: ::c_int = 1; +pub const CTL_SYSCTL_NEXT: ::c_int = 2; +pub const CTL_SYSCTL_NAME2OID: ::c_int = 3; +pub const CTL_SYSCTL_OIDFMT: ::c_int = 4; +pub const CTL_SYSCTL_OIDDESCR: ::c_int = 5; +pub const CTL_SYSCTL_OIDLABEL: ::c_int = 6; +pub const CTL_SYSCTL_NEXTNOSKIP: ::c_int = 7; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_NISDOMAINNAME: ::c_int = 22; +pub const KERN_UPDATEINTERVAL: ::c_int = 23; +pub const KERN_OSRELDATE: ::c_int = 24; +pub const KERN_NTP_PLL: ::c_int = 25; +pub const KERN_BOOTFILE: ::c_int = 26; +pub const KERN_MAXFILESPERPROC: ::c_int = 27; +pub const KERN_MAXPROCPERUID: ::c_int = 28; +pub const KERN_DUMPDEV: ::c_int = 29; +pub const KERN_IPC: ::c_int = 30; +pub const KERN_DUMMY: ::c_int = 31; +pub const KERN_PS_STRINGS: ::c_int = 32; +pub const KERN_USRSTACK: ::c_int = 33; +pub const KERN_LOGSIGEXIT: ::c_int = 34; +pub const KERN_IOV_MAX: ::c_int = 35; +pub const KERN_HOSTUUID: ::c_int = 36; +pub const KERN_ARND: ::c_int = 37; +pub const KERN_MAXPHYS: ::c_int = 38; + +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +pub const KERN_PROC_SESSION: ::c_int = 3; +pub const KERN_PROC_TTY: ::c_int = 4; +pub const KERN_PROC_UID: ::c_int = 5; +pub const KERN_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_ARGS: ::c_int = 7; +pub const KERN_PROC_PROC: ::c_int = 8; +pub const KERN_PROC_SV_NAME: ::c_int = 9; +pub const KERN_PROC_RGID: ::c_int = 10; +pub const KERN_PROC_GID: ::c_int = 11; +pub const KERN_PROC_PATHNAME: ::c_int = 12; +pub const KERN_PROC_OVMMAP: ::c_int = 13; +pub const KERN_PROC_OFILEDESC: ::c_int = 14; +pub const KERN_PROC_KSTACK: ::c_int = 15; +pub const KERN_PROC_INC_THREAD: ::c_int = 0x10; +pub const KERN_PROC_VMMAP: ::c_int = 32; +pub const KERN_PROC_FILEDESC: ::c_int = 33; +pub const KERN_PROC_GROUPS: ::c_int = 34; +pub const KERN_PROC_ENV: ::c_int = 35; +pub const KERN_PROC_AUXV: ::c_int = 36; +pub const KERN_PROC_RLIMIT: ::c_int = 37; +pub const KERN_PROC_PS_STRINGS: ::c_int = 38; +pub const KERN_PROC_UMASK: ::c_int = 39; +pub const KERN_PROC_OSREL: ::c_int = 40; +pub const KERN_PROC_SIGTRAMP: ::c_int = 41; +pub const KERN_PROC_CWD: ::c_int = 42; +pub const KERN_PROC_NFDS: ::c_int = 43; +pub const KERN_PROC_SIGFASTBLK: ::c_int = 44; + +pub const KIPC_MAXSOCKBUF: ::c_int = 1; +pub const KIPC_SOCKBUF_WASTE: ::c_int = 2; +pub const KIPC_SOMAXCONN: ::c_int = 3; +pub const KIPC_MAX_LINKHDR: ::c_int = 4; +pub const KIPC_MAX_PROTOHDR: ::c_int = 5; +pub const KIPC_MAX_HDR: ::c_int = 6; +pub const KIPC_MAX_DATALEN: ::c_int = 7; + +pub const HW_MACHINE: ::c_int = 1; +pub const HW_MODEL: ::c_int = 2; +pub const HW_NCPU: ::c_int = 3; +pub const HW_BYTEORDER: ::c_int = 4; +pub const HW_PHYSMEM: ::c_int = 5; +pub const HW_USERMEM: ::c_int = 6; +pub const HW_PAGESIZE: ::c_int = 7; +pub const HW_DISKNAMES: ::c_int = 8; +pub const HW_DISKSTATS: ::c_int = 9; +pub const HW_FLOATINGPT: ::c_int = 10; +pub const HW_MACHINE_ARCH: ::c_int = 11; +pub const HW_REALMEM: ::c_int = 12; + +pub const USER_CS_PATH: ::c_int = 1; +pub const USER_BC_BASE_MAX: ::c_int = 2; +pub const USER_BC_DIM_MAX: ::c_int = 3; +pub const USER_BC_SCALE_MAX: ::c_int = 4; +pub const USER_BC_STRING_MAX: ::c_int = 5; +pub const USER_COLL_WEIGHTS_MAX: ::c_int = 6; +pub const USER_EXPR_NEST_MAX: ::c_int = 7; +pub const USER_LINE_MAX: ::c_int = 8; +pub const USER_RE_DUP_MAX: ::c_int = 9; +pub const USER_POSIX2_VERSION: ::c_int = 10; +pub const USER_POSIX2_C_BIND: ::c_int = 11; +pub const USER_POSIX2_C_DEV: ::c_int = 12; +pub const USER_POSIX2_CHAR_TERM: ::c_int = 13; +pub const USER_POSIX2_FORT_DEV: ::c_int = 14; +pub const USER_POSIX2_FORT_RUN: ::c_int = 15; +pub const USER_POSIX2_LOCALEDEF: ::c_int = 16; +pub const USER_POSIX2_SW_DEV: ::c_int = 17; +pub const USER_POSIX2_UPE: ::c_int = 18; +pub const USER_STREAM_MAX: ::c_int = 19; +pub const USER_TZNAME_MAX: ::c_int = 20; +pub const USER_LOCALBASE: ::c_int = 21; + +pub const CTL_P1003_1B_ASYNCHRONOUS_IO: ::c_int = 1; +pub const CTL_P1003_1B_MAPPED_FILES: ::c_int = 2; +pub const CTL_P1003_1B_MEMLOCK: ::c_int = 3; +pub const CTL_P1003_1B_MEMLOCK_RANGE: ::c_int = 4; +pub const CTL_P1003_1B_MEMORY_PROTECTION: ::c_int = 5; +pub const CTL_P1003_1B_MESSAGE_PASSING: ::c_int = 6; +pub const CTL_P1003_1B_PRIORITIZED_IO: ::c_int = 7; +pub const CTL_P1003_1B_PRIORITY_SCHEDULING: ::c_int = 8; +pub const CTL_P1003_1B_REALTIME_SIGNALS: ::c_int = 9; +pub const CTL_P1003_1B_SEMAPHORES: ::c_int = 10; +pub const CTL_P1003_1B_FSYNC: ::c_int = 11; +pub const CTL_P1003_1B_SHARED_MEMORY_OBJECTS: ::c_int = 12; +pub const CTL_P1003_1B_SYNCHRONIZED_IO: ::c_int = 13; +pub const CTL_P1003_1B_TIMERS: ::c_int = 14; +pub const CTL_P1003_1B_AIO_LISTIO_MAX: ::c_int = 15; +pub const CTL_P1003_1B_AIO_MAX: ::c_int = 16; +pub const CTL_P1003_1B_AIO_PRIO_DELTA_MAX: ::c_int = 17; +pub const CTL_P1003_1B_DELAYTIMER_MAX: ::c_int = 18; +pub const CTL_P1003_1B_MQ_OPEN_MAX: ::c_int = 19; +pub const CTL_P1003_1B_PAGESIZE: ::c_int = 20; +pub const CTL_P1003_1B_RTSIG_MAX: ::c_int = 21; +pub const CTL_P1003_1B_SEM_NSEMS_MAX: ::c_int = 22; +pub const CTL_P1003_1B_SEM_VALUE_MAX: ::c_int = 23; +pub const CTL_P1003_1B_SIGQUEUE_MAX: ::c_int = 24; +pub const CTL_P1003_1B_TIMER_MAX: ::c_int = 25; + +pub const TIOCGPTN: ::c_ulong = 0x4004740f; +pub const TIOCPTMASTER: ::c_ulong = 0x2000741c; +pub const TIOCSIG: ::c_ulong = 0x2004745f; +pub const TIOCM_DCD: ::c_int = 0x40; +pub const H4DISC: ::c_int = 0x7; + +pub const VM_TOTAL: ::c_int = 1; + +pub const BIOCSETFNR: ::c_ulong = 0x80104282; + +pub const FIODGNAME: ::c_ulong = 0x80106678; +pub const FIONWRITE: ::c_ulong = 0x40046677; +pub const FIONSPACE: ::c_ulong = 0x40046676; +pub const FIOSEEKDATA: ::c_ulong = 0xc0086661; +pub const FIOSEEKHOLE: ::c_ulong = 0xc0086662; +pub const FIOSSHMLPGCNF: ::c_ulong = 0x80306664; + +pub const JAIL_API_VERSION: u32 = 2; +pub const JAIL_CREATE: ::c_int = 0x01; +pub const JAIL_UPDATE: ::c_int = 0x02; +pub const JAIL_ATTACH: ::c_int = 0x04; +pub const JAIL_DYING: ::c_int = 0x08; +pub const JAIL_SET_MASK: ::c_int = 0x0f; +pub const JAIL_GET_MASK: ::c_int = 0x08; +pub const JAIL_SYS_DISABLE: ::c_int = 0; +pub const JAIL_SYS_NEW: ::c_int = 1; +pub const JAIL_SYS_INHERIT: ::c_int = 2; + +pub const MNT_ACLS: ::c_int = 0x08000000; +pub const MNT_BYFSID: ::c_int = 0x08000000; +pub const MNT_GJOURNAL: ::c_int = 0x02000000; +pub const MNT_MULTILABEL: ::c_int = 0x04000000; +pub const MNT_NFS4ACLS: ::c_int = 0x00000010; +pub const MNT_SNAPSHOT: ::c_int = 0x01000000; +pub const MNT_UNION: ::c_int = 0x00000020; +pub const MNT_NONBUSY: ::c_int = 0x04000000; + +pub const SCM_BINTIME: ::c_int = 0x04; +pub const SCM_REALTIME: ::c_int = 0x05; +pub const SCM_MONOTONIC: ::c_int = 0x06; +pub const SCM_TIME_INFO: ::c_int = 0x07; +pub const SCM_CREDS2: ::c_int = 0x08; + +pub const SO_BINTIME: ::c_int = 0x2000; +pub const SO_NO_OFFLOAD: ::c_int = 0x4000; +pub const SO_NO_DDP: ::c_int = 0x8000; +pub const SO_REUSEPORT_LB: ::c_int = 0x10000; +pub const SO_LABEL: ::c_int = 0x1009; +pub const SO_PEERLABEL: ::c_int = 0x1010; +pub const SO_LISTENQLIMIT: ::c_int = 0x1011; +pub const SO_LISTENQLEN: ::c_int = 0x1012; +pub const SO_LISTENINCQLEN: ::c_int = 0x1013; +pub const SO_SETFIB: ::c_int = 0x1014; +pub const SO_USER_COOKIE: ::c_int = 0x1015; +pub const SO_PROTOCOL: ::c_int = 0x1016; +pub const SO_PROTOTYPE: ::c_int = SO_PROTOCOL; +pub const SO_TS_CLOCK: ::c_int = 0x1017; +pub const SO_DOMAIN: ::c_int = 0x1019; +pub const SO_VENDOR: ::c_int = 0x80000000; + +pub const SO_TS_REALTIME_MICRO: ::c_int = 0; +pub const SO_TS_BINTIME: ::c_int = 1; +pub const SO_TS_REALTIME: ::c_int = 2; +pub const SO_TS_MONOTONIC: ::c_int = 3; +pub const SO_TS_DEFAULT: ::c_int = SO_TS_REALTIME_MICRO; +pub const SO_TS_CLOCK_MAX: ::c_int = SO_TS_MONOTONIC; + +pub const LOCAL_CREDS: ::c_int = 2; +pub const LOCAL_CREDS_PERSISTENT: ::c_int = 3; +pub const LOCAL_CONNWAIT: ::c_int = 4; +pub const LOCAL_VENDOR: ::c_int = SO_VENDOR; + +pub const PL_EVENT_NONE: ::c_int = 0; +pub const PL_EVENT_SIGNAL: ::c_int = 1; +pub const PL_FLAG_SA: ::c_int = 0x01; +pub const PL_FLAG_BOUND: ::c_int = 0x02; +pub const PL_FLAG_SCE: ::c_int = 0x04; +pub const PL_FLAG_SCX: ::c_int = 0x08; +pub const PL_FLAG_EXEC: ::c_int = 0x10; +pub const PL_FLAG_SI: ::c_int = 0x20; +pub const PL_FLAG_FORKED: ::c_int = 0x40; +pub const PL_FLAG_CHILD: ::c_int = 0x80; +pub const PL_FLAG_BORN: ::c_int = 0x100; +pub const PL_FLAG_EXITED: ::c_int = 0x200; +pub const PL_FLAG_VFORKED: ::c_int = 0x400; +pub const PL_FLAG_VFORK_DONE: ::c_int = 0x800; + +pub const PT_LWPINFO: ::c_int = 13; +pub const PT_GETNUMLWPS: ::c_int = 14; +pub const PT_GETLWPLIST: ::c_int = 15; +pub const PT_CLEARSTEP: ::c_int = 16; +pub const PT_SETSTEP: ::c_int = 17; +pub const PT_SUSPEND: ::c_int = 18; +pub const PT_RESUME: ::c_int = 19; +pub const PT_TO_SCE: ::c_int = 20; +pub const PT_TO_SCX: ::c_int = 21; +pub const PT_SYSCALL: ::c_int = 22; +pub const PT_FOLLOW_FORK: ::c_int = 23; +pub const PT_LWP_EVENTS: ::c_int = 24; +pub const PT_GET_EVENT_MASK: ::c_int = 25; +pub const PT_SET_EVENT_MASK: ::c_int = 26; +pub const PT_GET_SC_ARGS: ::c_int = 27; +pub const PT_GET_SC_RET: ::c_int = 28; +pub const PT_COREDUMP: ::c_int = 29; +pub const PT_GETREGS: ::c_int = 33; +pub const PT_SETREGS: ::c_int = 34; +pub const PT_GETFPREGS: ::c_int = 35; +pub const PT_SETFPREGS: ::c_int = 36; +pub const PT_GETDBREGS: ::c_int = 37; +pub const PT_SETDBREGS: ::c_int = 38; +pub const PT_VM_TIMESTAMP: ::c_int = 40; +pub const PT_VM_ENTRY: ::c_int = 41; +pub const PT_GETREGSET: ::c_int = 42; +pub const PT_SETREGSET: ::c_int = 43; +pub const PT_SC_REMOTE: ::c_int = 44; +pub const PT_FIRSTMACH: ::c_int = 64; + +pub const PTRACE_EXEC: ::c_int = 0x0001; +pub const PTRACE_SCE: ::c_int = 0x0002; +pub const PTRACE_SCX: ::c_int = 0x0004; +pub const PTRACE_SYSCALL: ::c_int = PTRACE_SCE | PTRACE_SCX; +pub const PTRACE_FORK: ::c_int = 0x0008; +pub const PTRACE_LWP: ::c_int = 0x0010; +pub const PTRACE_VFORK: ::c_int = 0x0020; +pub const PTRACE_DEFAULT: ::c_int = PTRACE_EXEC; + +pub const PC_COMPRESS: u32 = 0x00000001; +pub const PC_ALL: u32 = 0x00000002; + +pub const PROC_SPROTECT: ::c_int = 1; +pub const PROC_REAP_ACQUIRE: ::c_int = 2; +pub const PROC_REAP_RELEASE: ::c_int = 3; +pub const PROC_REAP_STATUS: ::c_int = 4; +pub const PROC_REAP_GETPIDS: ::c_int = 5; +pub const PROC_REAP_KILL: ::c_int = 6; +pub const PROC_TRACE_CTL: ::c_int = 7; +pub const PROC_TRACE_STATUS: ::c_int = 8; +pub const PROC_TRAPCAP_CTL: ::c_int = 9; +pub const PROC_TRAPCAP_STATUS: ::c_int = 10; +pub const PROC_PDEATHSIG_CTL: ::c_int = 11; +pub const PROC_PDEATHSIG_STATUS: ::c_int = 12; +pub const PROC_ASLR_CTL: ::c_int = 13; +pub const PROC_ASLR_STATUS: ::c_int = 14; +pub const PROC_PROTMAX_CTL: ::c_int = 15; +pub const PROC_PROTMAX_STATUS: ::c_int = 16; +pub const PROC_STACKGAP_CTL: ::c_int = 17; +pub const PROC_STACKGAP_STATUS: ::c_int = 18; +pub const PROC_NO_NEW_PRIVS_CTL: ::c_int = 19; +pub const PROC_NO_NEW_PRIVS_STATUS: ::c_int = 20; +pub const PROC_WXMAP_CTL: ::c_int = 21; +pub const PROC_WXMAP_STATUS: ::c_int = 22; +pub const PROC_PROCCTL_MD_MIN: ::c_int = 0x10000000; + +pub const PPROT_SET: ::c_int = 1; +pub const PPROT_CLEAR: ::c_int = 2; +pub const PPROT_DESCEND: ::c_int = 0x10; +pub const PPROT_INHERIT: ::c_int = 0x20; + +pub const PROC_TRACE_CTL_ENABLE: ::c_int = 1; +pub const PROC_TRACE_CTL_DISABLE: ::c_int = 2; +pub const PROC_TRACE_CTL_DISABLE_EXEC: ::c_int = 3; + +pub const PROC_TRAPCAP_CTL_ENABLE: ::c_int = 1; +pub const PROC_TRAPCAP_CTL_DISABLE: ::c_int = 2; + +pub const PROC_ASLR_FORCE_ENABLE: ::c_int = 1; +pub const PROC_ASLR_FORCE_DISABLE: ::c_int = 2; +pub const PROC_ASLR_NOFORCE: ::c_int = 3; +pub const PROC_ASLR_ACTIVE: ::c_int = 0x80000000; + +pub const PROC_PROTMAX_FORCE_ENABLE: ::c_int = 1; +pub const PROC_PROTMAX_FORCE_DISABLE: ::c_int = 2; +pub const PROC_PROTMAX_NOFORCE: ::c_int = 3; +pub const PROC_PROTMAX_ACTIVE: ::c_int = 0x80000000; + +pub const PROC_STACKGAP_ENABLE: ::c_int = 0x0001; +pub const PROC_STACKGAP_DISABLE: ::c_int = 0x0002; +pub const PROC_STACKGAP_ENABLE_EXEC: ::c_int = 0x0004; +pub const PROC_STACKGAP_DISABLE_EXEC: ::c_int = 0x0008; + +pub const PROC_NO_NEW_PRIVS_ENABLE: ::c_int = 1; +pub const PROC_NO_NEW_PRIVS_DISABLE: ::c_int = 2; + +pub const PROC_WX_MAPPINGS_PERMIT: ::c_int = 0x0001; +pub const PROC_WX_MAPPINGS_DISALLOW_EXEC: ::c_int = 0x0002; +pub const PROC_WXORX_ENFORCE: ::c_int = 0x80000000; + +pub const AF_SLOW: ::c_int = 33; +pub const AF_SCLUSTER: ::c_int = 34; +pub const AF_ARP: ::c_int = 35; +pub const AF_BLUETOOTH: ::c_int = 36; +pub const AF_IEEE80211: ::c_int = 37; +pub const AF_INET_SDP: ::c_int = 40; +pub const AF_INET6_SDP: ::c_int = 42; + +// sys/net/if.h +pub const IF_MAXUNIT: ::c_int = 0x7fff; +/// (n) interface is up +pub const IFF_UP: ::c_int = 0x1; +/// (i) broadcast address valid +pub const IFF_BROADCAST: ::c_int = 0x2; +/// (n) turn on debugging +pub const IFF_DEBUG: ::c_int = 0x4; +/// (i) is a loopback net +pub const IFF_LOOPBACK: ::c_int = 0x8; +/// (i) is a point-to-point link +pub const IFF_POINTOPOINT: ::c_int = 0x10; +/// (i) calls if_input in net epoch +#[deprecated(since = "0.2.149", note = "Removed in FreeBSD 14")] +pub const IFF_KNOWSEPOCH: ::c_int = 0x20; +/// (d) resources allocated +pub const IFF_RUNNING: ::c_int = 0x40; +#[doc(hidden)] +#[deprecated( + since = "0.2.54", + note = "IFF_DRV_RUNNING is deprecated. Use the portable IFF_RUNNING instead" +)] +/// (d) resources allocate +pub const IFF_DRV_RUNNING: ::c_int = 0x40; +/// (n) no address resolution protocol +pub const IFF_NOARP: ::c_int = 0x80; +/// (n) receive all packets +pub const IFF_PROMISC: ::c_int = 0x100; +/// (n) receive all multicast packets +pub const IFF_ALLMULTI: ::c_int = 0x200; +/// (d) tx hardware queue is full +pub const IFF_OACTIVE: ::c_int = 0x400; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Use the portable `IFF_OACTIVE` instead")] +/// (d) tx hardware queue is full +pub const IFF_DRV_OACTIVE: ::c_int = 0x400; +/// (i) can't hear own transmissions +pub const IFF_SIMPLEX: ::c_int = 0x800; +/// per link layer defined bit +pub const IFF_LINK0: ::c_int = 0x1000; +/// per link layer defined bit +pub const IFF_LINK1: ::c_int = 0x2000; +/// per link layer defined bit +pub const IFF_LINK2: ::c_int = 0x4000; +/// use alternate physical connection +pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; +/// (i) supports multicast +pub const IFF_MULTICAST: ::c_int = 0x8000; +/// (i) unconfigurable using ioctl(2) +pub const IFF_CANTCONFIG: ::c_int = 0x10000; +/// (n) user-requested promisc mode +pub const IFF_PPROMISC: ::c_int = 0x20000; +/// (n) user-requested monitor mode +pub const IFF_MONITOR: ::c_int = 0x40000; +/// (n) static ARP +pub const IFF_STATICARP: ::c_int = 0x80000; +/// (n) interface is winding down +pub const IFF_DYING: ::c_int = 0x200000; +/// (n) interface is being renamed +pub const IFF_RENAMING: ::c_int = 0x400000; +/// interface is not part of any groups +#[deprecated(since = "0.2.149", note = "Removed in FreeBSD 14")] +pub const IFF_NOGROUP: ::c_int = 0x800000; + +/// link invalid/unknown +pub const LINK_STATE_UNKNOWN: ::c_int = 0; +/// link is down +pub const LINK_STATE_DOWN: ::c_int = 1; +/// link is up +pub const LINK_STATE_UP: ::c_int = 2; + +/// can offload checksum on RX +pub const IFCAP_RXCSUM: ::c_int = 0x00001; +/// can offload checksum on TX +pub const IFCAP_TXCSUM: ::c_int = 0x00002; +/// can be a network console +pub const IFCAP_NETCONS: ::c_int = 0x00004; +/// VLAN-compatible MTU +pub const IFCAP_VLAN_MTU: ::c_int = 0x00008; +/// hardware VLAN tag support +pub const IFCAP_VLAN_HWTAGGING: ::c_int = 0x00010; +/// 9000 byte MTU supported +pub const IFCAP_JUMBO_MTU: ::c_int = 0x00020; +/// driver supports polling +pub const IFCAP_POLLING: ::c_int = 0x00040; +/// can do IFCAP_HWCSUM on VLANs +pub const IFCAP_VLAN_HWCSUM: ::c_int = 0x00080; +/// can do TCP Segmentation Offload +pub const IFCAP_TSO4: ::c_int = 0x00100; +/// can do TCP6 Segmentation Offload +pub const IFCAP_TSO6: ::c_int = 0x00200; +/// can do Large Receive Offload +pub const IFCAP_LRO: ::c_int = 0x00400; +/// wake on any unicast frame +pub const IFCAP_WOL_UCAST: ::c_int = 0x00800; +/// wake on any multicast frame +pub const IFCAP_WOL_MCAST: ::c_int = 0x01000; +/// wake on any Magic Packet +pub const IFCAP_WOL_MAGIC: ::c_int = 0x02000; +/// interface can offload TCP +pub const IFCAP_TOE4: ::c_int = 0x04000; +/// interface can offload TCP6 +pub const IFCAP_TOE6: ::c_int = 0x08000; +/// interface hw can filter vlan tag +pub const IFCAP_VLAN_HWFILTER: ::c_int = 0x10000; +/// can do SIOCGIFCAPNV/SIOCSIFCAPNV +pub const IFCAP_NV: ::c_int = 0x20000; +/// can do IFCAP_TSO on VLANs +pub const IFCAP_VLAN_HWTSO: ::c_int = 0x40000; +/// the runtime link state is dynamic +pub const IFCAP_LINKSTATE: ::c_int = 0x80000; +/// netmap mode supported/enabled +pub const IFCAP_NETMAP: ::c_int = 0x100000; +/// can offload checksum on IPv6 RX +pub const IFCAP_RXCSUM_IPV6: ::c_int = 0x200000; +/// can offload checksum on IPv6 TX +pub const IFCAP_TXCSUM_IPV6: ::c_int = 0x400000; +/// manages counters internally +pub const IFCAP_HWSTATS: ::c_int = 0x800000; +/// hardware supports TX rate limiting +pub const IFCAP_TXRTLMT: ::c_int = 0x1000000; +/// hardware rx timestamping +pub const IFCAP_HWRXTSTMP: ::c_int = 0x2000000; +/// understands M_EXTPG mbufs +pub const IFCAP_MEXTPG: ::c_int = 0x4000000; +/// can do TLS encryption and segmentation for TCP +pub const IFCAP_TXTLS4: ::c_int = 0x8000000; +/// can do TLS encryption and segmentation for TCP6 +pub const IFCAP_TXTLS6: ::c_int = 0x10000000; +/// can do IFCAN_HWCSUM on VXLANs +pub const IFCAP_VXLAN_HWCSUM: ::c_int = 0x20000000; +/// can do IFCAP_TSO on VXLANs +pub const IFCAP_VXLAN_HWTSO: ::c_int = 0x40000000; +/// can do TLS with rate limiting +pub const IFCAP_TXTLS_RTLMT: ::c_int = 0x80000000; + +pub const IFCAP_HWCSUM_IPV6: ::c_int = IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6; +pub const IFCAP_HWCSUM: ::c_int = IFCAP_RXCSUM | IFCAP_TXCSUM; +pub const IFCAP_TSO: ::c_int = IFCAP_TSO4 | IFCAP_TSO6; +pub const IFCAP_WOL: ::c_int = IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC; +pub const IFCAP_TOE: ::c_int = IFCAP_TOE4 | IFCAP_TOE6; +pub const IFCAP_TXTLS: ::c_int = IFCAP_TXTLS4 | IFCAP_TXTLS6; +pub const IFCAP_CANTCHANGE: ::c_int = IFCAP_NETMAP | IFCAP_NV; + +pub const IFQ_MAXLEN: ::c_int = 50; +pub const IFNET_SLOWHZ: ::c_int = 1; + +pub const IFAN_ARRIVAL: ::c_int = 0; +pub const IFAN_DEPARTURE: ::c_int = 1; + +pub const IFSTATMAX: ::c_int = 800; + +pub const RSS_FUNC_NONE: ::c_int = 0; +pub const RSS_FUNC_PRIVATE: ::c_int = 1; +pub const RSS_FUNC_TOEPLITZ: ::c_int = 2; + +pub const RSS_TYPE_IPV4: ::c_int = 0x00000001; +pub const RSS_TYPE_TCP_IPV4: ::c_int = 0x00000002; +pub const RSS_TYPE_IPV6: ::c_int = 0x00000004; +pub const RSS_TYPE_IPV6_EX: ::c_int = 0x00000008; +pub const RSS_TYPE_TCP_IPV6: ::c_int = 0x00000010; +pub const RSS_TYPE_TCP_IPV6_EX: ::c_int = 0x00000020; +pub const RSS_TYPE_UDP_IPV4: ::c_int = 0x00000040; +pub const RSS_TYPE_UDP_IPV6: ::c_int = 0x00000080; +pub const RSS_TYPE_UDP_IPV6_EX: ::c_int = 0x00000100; +pub const RSS_KEYLEN: ::c_int = 128; + +pub const IFNET_PCP_NONE: ::c_int = 0xff; +pub const IFDR_MSG_SIZE: ::c_int = 64; +pub const IFDR_REASON_MSG: ::c_int = 1; +pub const IFDR_REASON_VENDOR: ::c_int = 2; + +// sys/net/if_mib.h + +/// non-interface-specific +pub const IFMIB_SYSTEM: ::c_int = 1; +/// per-interface data table +pub const IFMIB_IFDATA: ::c_int = 2; + +/// generic stats for all kinds of ifaces +pub const IFDATA_GENERAL: ::c_int = 1; +/// specific to the type of interface +pub const IFDATA_LINKSPECIFIC: ::c_int = 2; +/// driver name and unit +pub const IFDATA_DRIVERNAME: ::c_int = 3; + +/// number of interfaces configured +pub const IFMIB_IFCOUNT: ::c_int = 1; + +/// functions not specific to a type of iface +pub const NETLINK_GENERIC: ::c_int = 0; + +pub const DOT3COMPLIANCE_STATS: ::c_int = 1; +pub const DOT3COMPLIANCE_COLLS: ::c_int = 2; + +pub const dot3ChipSetAMD7990: ::c_int = 1; +pub const dot3ChipSetAMD79900: ::c_int = 2; +pub const dot3ChipSetAMD79C940: ::c_int = 3; + +pub const dot3ChipSetIntel82586: ::c_int = 1; +pub const dot3ChipSetIntel82596: ::c_int = 2; +pub const dot3ChipSetIntel82557: ::c_int = 3; + +pub const dot3ChipSetNational8390: ::c_int = 1; +pub const dot3ChipSetNationalSonic: ::c_int = 2; + +pub const dot3ChipSetFujitsu86950: ::c_int = 1; + +pub const dot3ChipSetDigitalDC21040: ::c_int = 1; +pub const dot3ChipSetDigitalDC21140: ::c_int = 2; +pub const dot3ChipSetDigitalDC21041: ::c_int = 3; +pub const dot3ChipSetDigitalDC21140A: ::c_int = 4; +pub const dot3ChipSetDigitalDC21142: ::c_int = 5; + +pub const dot3ChipSetWesternDigital83C690: ::c_int = 1; +pub const dot3ChipSetWesternDigital83C790: ::c_int = 2; + +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// Stream protocol II. +pub const IPPROTO_ST: ::c_int = 7; +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// private interior gateway +pub const IPPROTO_PIGP: ::c_int = 9; +/// BBN RCC Monitoring +pub const IPPROTO_RCCMON: ::c_int = 10; +/// network voice protocol +pub const IPPROTO_NVPII: ::c_int = 11; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +/// Argus +pub const IPPROTO_ARGUS: ::c_int = 13; +/// EMCON +pub const IPPROTO_EMCON: ::c_int = 14; +/// Cross Net Debugger +pub const IPPROTO_XNET: ::c_int = 15; +/// Chaos +pub const IPPROTO_CHAOS: ::c_int = 16; +// IPPROTO_UDP defined in src/unix/mod.rs +/// Multiplexing +pub const IPPROTO_MUX: ::c_int = 18; +/// DCN Measurement Subsystems +pub const IPPROTO_MEAS: ::c_int = 19; +/// Host Monitoring +pub const IPPROTO_HMP: ::c_int = 20; +/// Packet Radio Measurement +pub const IPPROTO_PRM: ::c_int = 21; +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// Trunk-1 +pub const IPPROTO_TRUNK1: ::c_int = 23; +/// Trunk-2 +pub const IPPROTO_TRUNK2: ::c_int = 24; +/// Leaf-1 +pub const IPPROTO_LEAF1: ::c_int = 25; +/// Leaf-2 +pub const IPPROTO_LEAF2: ::c_int = 26; +/// Reliable Data +pub const IPPROTO_RDP: ::c_int = 27; +/// Reliable Transaction +pub const IPPROTO_IRTP: ::c_int = 28; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// Bulk Data Transfer +pub const IPPROTO_BLT: ::c_int = 30; +/// Network Services +pub const IPPROTO_NSP: ::c_int = 31; +/// Merit Internodal +pub const IPPROTO_INP: ::c_int = 32; +#[doc(hidden)] +#[deprecated( + since = "0.2.72", + note = "IPPROTO_SEP is deprecated. Use IPPROTO_DCCP instead" +)] +pub const IPPROTO_SEP: ::c_int = 33; +/// Datagram Congestion Control Protocol +pub const IPPROTO_DCCP: ::c_int = 33; +/// Third Party Connect +pub const IPPROTO_3PC: ::c_int = 34; +/// InterDomain Policy Routing +pub const IPPROTO_IDPR: ::c_int = 35; +/// XTP +pub const IPPROTO_XTP: ::c_int = 36; +/// Datagram Delivery +pub const IPPROTO_DDP: ::c_int = 37; +/// Control Message Transport +pub const IPPROTO_CMTP: ::c_int = 38; +/// TP++ Transport +pub const IPPROTO_TPXX: ::c_int = 39; +/// IL transport protocol +pub const IPPROTO_IL: ::c_int = 40; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// Source Demand Routing +pub const IPPROTO_SDRP: ::c_int = 42; +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// InterDomain Routing +pub const IPPROTO_IDRP: ::c_int = 45; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// Mobile Host Routing +pub const IPPROTO_MHRP: ::c_int = 48; +/// BHA +pub const IPPROTO_BHA: ::c_int = 49; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// Integ. Net Layer Security +pub const IPPROTO_INLSP: ::c_int = 52; +/// IP with encryption +pub const IPPROTO_SWIPE: ::c_int = 53; +/// Next Hop Resolution +pub const IPPROTO_NHRP: ::c_int = 54; +/// IP Mobility +pub const IPPROTO_MOBILE: ::c_int = 55; +/// Transport Layer Security +pub const IPPROTO_TLSP: ::c_int = 56; +/// SKIP +pub const IPPROTO_SKIP: ::c_int = 57; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// any host internal protocol +pub const IPPROTO_AHIP: ::c_int = 61; +/// CFTP +pub const IPPROTO_CFTP: ::c_int = 62; +/// "hello" routing protocol +pub const IPPROTO_HELLO: ::c_int = 63; +/// SATNET/Backroom EXPAK +pub const IPPROTO_SATEXPAK: ::c_int = 64; +/// Kryptolan +pub const IPPROTO_KRYPTOLAN: ::c_int = 65; +/// Remote Virtual Disk +pub const IPPROTO_RVD: ::c_int = 66; +/// Pluribus Packet Core +pub const IPPROTO_IPPC: ::c_int = 67; +/// Any distributed FS +pub const IPPROTO_ADFS: ::c_int = 68; +/// Satnet Monitoring +pub const IPPROTO_SATMON: ::c_int = 69; +/// VISA Protocol +pub const IPPROTO_VISA: ::c_int = 70; +/// Packet Core Utility +pub const IPPROTO_IPCV: ::c_int = 71; +/// Comp. Prot. Net. Executive +pub const IPPROTO_CPNX: ::c_int = 72; +/// Comp. Prot. HeartBeat +pub const IPPROTO_CPHB: ::c_int = 73; +/// Wang Span Network +pub const IPPROTO_WSN: ::c_int = 74; +/// Packet Video Protocol +pub const IPPROTO_PVP: ::c_int = 75; +/// BackRoom SATNET Monitoring +pub const IPPROTO_BRSATMON: ::c_int = 76; +/// Sun net disk proto (temp.) +pub const IPPROTO_ND: ::c_int = 77; +/// WIDEBAND Monitoring +pub const IPPROTO_WBMON: ::c_int = 78; +/// WIDEBAND EXPAK +pub const IPPROTO_WBEXPAK: ::c_int = 79; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// VMTP +pub const IPPROTO_VMTP: ::c_int = 81; +/// Secure VMTP +pub const IPPROTO_SVMTP: ::c_int = 82; +/// Banyon VINES +pub const IPPROTO_VINES: ::c_int = 83; +/// TTP +pub const IPPROTO_TTP: ::c_int = 84; +/// NSFNET-IGP +pub const IPPROTO_IGP: ::c_int = 85; +/// dissimilar gateway prot. +pub const IPPROTO_DGP: ::c_int = 86; +/// TCF +pub const IPPROTO_TCF: ::c_int = 87; +/// Cisco/GXS IGRP +pub const IPPROTO_IGRP: ::c_int = 88; +/// OSPFIGP +pub const IPPROTO_OSPFIGP: ::c_int = 89; +/// Strite RPC protocol +pub const IPPROTO_SRPC: ::c_int = 90; +/// Locus Address Resoloution +pub const IPPROTO_LARP: ::c_int = 91; +/// Multicast Transport +pub const IPPROTO_MTP: ::c_int = 92; +/// AX.25 Frames +pub const IPPROTO_AX25: ::c_int = 93; +/// IP encapsulated in IP +pub const IPPROTO_IPEIP: ::c_int = 94; +/// Mobile Int.ing control +pub const IPPROTO_MICP: ::c_int = 95; +/// Semaphore Comm. security +pub const IPPROTO_SCCSP: ::c_int = 96; +/// Ethernet IP encapsulation +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// any private encr. scheme +pub const IPPROTO_APES: ::c_int = 99; +/// GMTP +pub const IPPROTO_GMTP: ::c_int = 100; +/// payload compression (IPComp) +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +/// IPv6 Mobility Header +pub const IPPROTO_MH: ::c_int = 135; +/// UDP-Lite +pub const IPPROTO_UDPLITE: ::c_int = 136; +/// IP6 Host Identity Protocol +pub const IPPROTO_HIP: ::c_int = 139; +/// IP6 Shim6 Protocol +pub const IPPROTO_SHIM6: ::c_int = 140; + +/* 101-254: Partly Unassigned */ +/// Protocol Independent Mcast +pub const IPPROTO_PIM: ::c_int = 103; +/// CARP +pub const IPPROTO_CARP: ::c_int = 112; +/// PGM +pub const IPPROTO_PGM: ::c_int = 113; +/// MPLS-in-IP +pub const IPPROTO_MPLS: ::c_int = 137; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; + +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion, no longer used */ +/// OLD divert pseudo-proto +pub const IPPROTO_OLD_DIVERT: ::c_int = 254; +pub const IPPROTO_MAX: ::c_int = 256; +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +/* Only used internally, so can be outside the range of valid IP protocols. */ +/// divert pseudo-protocol +pub const IPPROTO_DIVERT: ::c_int = 258; +/// SeND pseudo-protocol +pub const IPPROTO_SEND: ::c_int = 259; + +// sys/netinet/TCP.h +pub const TCP_MD5SIG: ::c_int = 16; +pub const TCP_INFO: ::c_int = 32; +pub const TCP_CONGESTION: ::c_int = 64; +pub const TCP_CCALGOOPT: ::c_int = 65; +pub const TCP_MAXUNACKTIME: ::c_int = 68; +pub const TCP_MAXPEAKRATE: ::c_int = 69; +pub const TCP_IDLE_REDUCE: ::c_int = 70; +pub const TCP_REMOTE_UDP_ENCAPS_PORT: ::c_int = 71; +pub const TCP_DELACK: ::c_int = 72; +pub const TCP_FIN_IS_RST: ::c_int = 73; +pub const TCP_LOG_LIMIT: ::c_int = 74; +pub const TCP_SHARED_CWND_ALLOWED: ::c_int = 75; +pub const TCP_PROC_ACCOUNTING: ::c_int = 76; +pub const TCP_USE_CMP_ACKS: ::c_int = 77; +pub const TCP_PERF_INFO: ::c_int = 78; +pub const TCP_LRD: ::c_int = 79; +pub const TCP_KEEPINIT: ::c_int = 128; +pub const TCP_FASTOPEN: ::c_int = 1025; +pub const TCP_PCAP_OUT: ::c_int = 2048; +pub const TCP_PCAP_IN: ::c_int = 4096; +pub const TCP_FASTOPEN_PSK_LEN: ::c_int = 16; +pub const TCP_FUNCTION_NAME_LEN_MAX: ::c_int = 32; + +pub const IP_BINDANY: ::c_int = 24; +pub const IP_BINDMULTI: ::c_int = 25; +pub const IP_RSS_LISTEN_BUCKET: ::c_int = 26; +pub const IP_ORIGDSTADDR: ::c_int = 27; +pub const IP_RECVORIGDSTADDR: ::c_int = IP_ORIGDSTADDR; + +pub const IP_DONTFRAG: ::c_int = 67; +pub const IP_RECVTOS: ::c_int = 68; + +pub const IPV6_BINDANY: ::c_int = 64; +pub const IPV6_ORIGDSTADDR: ::c_int = 72; +pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; + +pub const PF_SLOW: ::c_int = AF_SLOW; +pub const PF_SCLUSTER: ::c_int = AF_SCLUSTER; +pub const PF_ARP: ::c_int = AF_ARP; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_IEEE80211: ::c_int = AF_IEEE80211; +pub const PF_INET_SDP: ::c_int = AF_INET_SDP; +pub const PF_INET6_SDP: ::c_int = AF_INET6_SDP; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; +pub const NET_RT_IFMALIST: ::c_int = 4; +pub const NET_RT_IFLISTL: ::c_int = 5; + +// System V IPC +pub const IPC_INFO: ::c_int = 3; +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; +pub const SHM_STAT: ::c_int = 13; +pub const SHM_INFO: ::c_int = 14; +pub const SHM_ANON: *mut ::c_char = 1 as *mut ::c_char; + +// The *_MAXID constants never should've been used outside of the +// FreeBSD base system. And with the exception of CTL_P1003_1B_MAXID, +// they were all removed in svn r262489. They remain here for backwards +// compatibility only, and are scheduled to be removed in libc 1.0.0. +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const CTL_MAXID: ::c_int = 10; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const KERN_MAXID: ::c_int = 38; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const HW_MAXID: ::c_int = 13; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const USER_MAXID: ::c_int = 21; +#[doc(hidden)] +#[deprecated(since = "0.2.74", note = "Removed in FreeBSD 13")] +pub const CTL_P1003_1B_MAXID: ::c_int = 26; + +pub const MSG_NOTIFICATION: ::c_int = 0x00002000; +pub const MSG_NBIO: ::c_int = 0x00004000; +pub const MSG_COMPAT: ::c_int = 0x00008000; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x00040000; +pub const MSG_NOSIGNAL: ::c_int = 0x20000; +pub const MSG_WAITFORONE: ::c_int = 0x00080000; + +// utmpx entry types +pub const EMPTY: ::c_short = 0; +pub const BOOT_TIME: ::c_short = 1; +pub const OLD_TIME: ::c_short = 2; +pub const NEW_TIME: ::c_short = 3; +pub const USER_PROCESS: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const DEAD_PROCESS: ::c_short = 7; +pub const SHUTDOWN_TIME: ::c_short = 8; +// utmp database types +pub const UTXDB_ACTIVE: ::c_int = 0; +pub const UTXDB_LASTLOGIN: ::c_int = 1; +pub const UTXDB_LOG: ::c_int = 2; + +pub const LC_COLLATE_MASK: ::c_int = 1 << 0; +pub const LC_CTYPE_MASK: ::c_int = 1 << 1; +pub const LC_MONETARY_MASK: ::c_int = 1 << 2; +pub const LC_NUMERIC_MASK: ::c_int = 1 << 3; +pub const LC_TIME_MASK: ::c_int = 1 << 4; +pub const LC_MESSAGES_MASK: ::c_int = 1 << 5; +pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_CTYPE_MASK + | LC_MESSAGES_MASK + | LC_MONETARY_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +pub const WSTOPPED: ::c_int = 2; // same as WUNTRACED +pub const WCONTINUED: ::c_int = 4; +pub const WNOWAIT: ::c_int = 8; +pub const WEXITED: ::c_int = 16; +pub const WTRAPPED: ::c_int = 32; + +// FreeBSD defines a great many more of these, we only expose the +// standardized ones. +pub const P_PID: idtype_t = 0; +pub const P_PGID: idtype_t = 2; +pub const P_ALL: idtype_t = 7; + +pub const UTIME_OMIT: c_long = -2; +pub const UTIME_NOW: c_long = -1; + +pub const B460800: ::speed_t = 460800; +pub const B921600: ::speed_t = 921600; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_EACCESS: ::c_int = 0x100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x200; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; +pub const AT_REMOVEDIR: ::c_int = 0x800; +pub const AT_RESOLVE_BENEATH: ::c_int = 0x2000; +pub const AT_EMPTY_PATH: ::c_int = 0x4000; + +pub const AT_NULL: ::c_int = 0; +pub const AT_IGNORE: ::c_int = 1; +pub const AT_EXECFD: ::c_int = 2; +pub const AT_PHDR: ::c_int = 3; +pub const AT_PHENT: ::c_int = 4; +pub const AT_PHNUM: ::c_int = 5; +pub const AT_PAGESZ: ::c_int = 6; +pub const AT_BASE: ::c_int = 7; +pub const AT_FLAGS: ::c_int = 8; +pub const AT_ENTRY: ::c_int = 9; +pub const AT_NOTELF: ::c_int = 10; +pub const AT_UID: ::c_int = 11; +pub const AT_EUID: ::c_int = 12; +pub const AT_GID: ::c_int = 13; +pub const AT_EGID: ::c_int = 14; +pub const AT_EXECPATH: ::c_int = 15; +pub const AT_CANARY: ::c_int = 16; +pub const AT_OSRELDATE: ::c_int = 18; +pub const AT_NCPUS: ::c_int = 19; +pub const AT_PAGESIZES: ::c_int = 20; +pub const AT_TIMEKEEP: ::c_int = 22; +pub const AT_HWCAP: ::c_int = 25; +pub const AT_HWCAP2: ::c_int = 26; +pub const AT_USRSTACKBASE: ::c_int = 35; +pub const AT_USRSTACKLIM: ::c_int = 36; + +pub const TABDLY: ::tcflag_t = 0x00000004; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB3: ::tcflag_t = 0x00000004; + +pub const _PC_ACL_NFS4: ::c_int = 64; + +pub const _SC_CPUSET_SIZE: ::c_int = 122; + +pub const _UUID_NODE_LEN: usize = 6; + +// Flags which can be passed to pdfork(2) +pub const PD_DAEMON: ::c_int = 0x00000001; +pub const PD_CLOEXEC: ::c_int = 0x00000002; +pub const PD_ALLOWED_AT_FORK: ::c_int = PD_DAEMON | PD_CLOEXEC; + +// Values for struct rtprio (type_ field) +pub const RTP_PRIO_REALTIME: ::c_ushort = 2; +pub const RTP_PRIO_NORMAL: ::c_ushort = 3; +pub const RTP_PRIO_IDLE: ::c_ushort = 4; + +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; +pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x04; +pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x08; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x10; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20; + +// Flags for chflags(2) +pub const UF_SYSTEM: ::c_ulong = 0x00000080; +pub const UF_SPARSE: ::c_ulong = 0x00000100; +pub const UF_OFFLINE: ::c_ulong = 0x00000200; +pub const UF_REPARSE: ::c_ulong = 0x00000400; +pub const UF_ARCHIVE: ::c_ulong = 0x00000800; +pub const UF_READONLY: ::c_ulong = 0x00001000; +pub const UF_HIDDEN: ::c_ulong = 0x00008000; +pub const SF_SNAPSHOT: ::c_ulong = 0x00200000; + +// fcntl commands +pub const F_ADD_SEALS: ::c_int = 19; +pub const F_GET_SEALS: ::c_int = 20; +pub const F_OGETLK: ::c_int = 7; +pub const F_OSETLK: ::c_int = 8; +pub const F_OSETLKW: ::c_int = 9; +pub const F_RDAHEAD: ::c_int = 16; +pub const F_READAHEAD: ::c_int = 15; +pub const F_SETLK_REMOTE: ::c_int = 14; +pub const F_KINFO: ::c_int = 22; + +// for use with F_ADD_SEALS +pub const F_SEAL_GROW: ::c_int = 4; +pub const F_SEAL_SEAL: ::c_int = 1; +pub const F_SEAL_SHRINK: ::c_int = 2; +pub const F_SEAL_WRITE: ::c_int = 8; + +// for use with fspacectl +pub const SPACECTL_DEALLOC: ::c_int = 1; + +// For getrandom() +pub const GRND_NONBLOCK: ::c_uint = 0x1; +pub const GRND_RANDOM: ::c_uint = 0x2; +pub const GRND_INSECURE: ::c_uint = 0x4; + +// For realhostname* api +pub const HOSTNAME_FOUND: ::c_int = 0; +pub const HOSTNAME_INCORRECTNAME: ::c_int = 1; +pub const HOSTNAME_INVALIDADDR: ::c_int = 2; +pub const HOSTNAME_INVALIDNAME: ::c_int = 3; + +// For rfork +pub const RFFDG: ::c_int = 4; +pub const RFPROC: ::c_int = 16; +pub const RFMEM: ::c_int = 32; +pub const RFNOWAIT: ::c_int = 64; +pub const RFCFDG: ::c_int = 4096; +pub const RFTHREAD: ::c_int = 8192; +pub const RFSIGSHARE: ::c_int = 16384; +pub const RFLINUXTHPN: ::c_int = 65536; +pub const RFTSIGZMB: ::c_int = 524288; +pub const RFSPAWN: ::c_int = 2147483648; + +// For eventfd +pub const EFD_SEMAPHORE: ::c_int = 0x1; +pub const EFD_NONBLOCK: ::c_int = 0x4; +pub const EFD_CLOEXEC: ::c_int = 0x100000; + +pub const MALLOCX_ZERO: ::c_int = 0x40; + +/// size of returned wchan message +pub const WMESGLEN: usize = 8; +/// size of returned lock name +pub const LOCKNAMELEN: usize = 8; +/// size of returned thread name +pub const TDNAMLEN: usize = 16; +/// size of returned ki_comm name +pub const COMMLEN: usize = 19; +/// size of returned ki_emul +pub const KI_EMULNAMELEN: usize = 16; +/// number of groups in ki_groups +pub const KI_NGROUPS: usize = 16; +cfg_if! { + if #[cfg(freebsd11)] { + pub const KI_NSPARE_INT: usize = 4; + } else { + pub const KI_NSPARE_INT: usize = 2; + } +} +pub const KI_NSPARE_LONG: usize = 12; +/// Flags for the process credential. +pub const KI_CRF_CAPABILITY_MODE: usize = 0x00000001; +/// Steal a bit from ki_cr_flags to indicate that the cred had more than +/// KI_NGROUPS groups. +pub const KI_CRF_GRP_OVERFLOW: usize = 0x80000000; +/// controlling tty vnode active +pub const KI_CTTY: usize = 0x00000001; +/// session leader +pub const KI_SLEADER: usize = 0x00000002; +/// proc blocked on lock ki_lockname +pub const KI_LOCKBLOCK: usize = 0x00000004; +/// size of returned ki_login +pub const LOGNAMELEN: usize = 17; +/// size of returned ki_loginclass +pub const LOGINCLASSLEN: usize = 17; + +pub const KF_ATTR_VALID: ::c_int = 0x0001; +pub const KF_TYPE_NONE: ::c_int = 0; +pub const KF_TYPE_VNODE: ::c_int = 1; +pub const KF_TYPE_SOCKET: ::c_int = 2; +pub const KF_TYPE_PIPE: ::c_int = 3; +pub const KF_TYPE_FIFO: ::c_int = 4; +pub const KF_TYPE_KQUEUE: ::c_int = 5; +pub const KF_TYPE_MQUEUE: ::c_int = 7; +pub const KF_TYPE_SHM: ::c_int = 8; +pub const KF_TYPE_SEM: ::c_int = 9; +pub const KF_TYPE_PTS: ::c_int = 10; +pub const KF_TYPE_PROCDESC: ::c_int = 11; +pub const KF_TYPE_DEV: ::c_int = 12; +pub const KF_TYPE_UNKNOWN: ::c_int = 255; + +pub const KF_VTYPE_VNON: ::c_int = 0; +pub const KF_VTYPE_VREG: ::c_int = 1; +pub const KF_VTYPE_VDIR: ::c_int = 2; +pub const KF_VTYPE_VBLK: ::c_int = 3; +pub const KF_VTYPE_VCHR: ::c_int = 4; +pub const KF_VTYPE_VLNK: ::c_int = 5; +pub const KF_VTYPE_VSOCK: ::c_int = 6; +pub const KF_VTYPE_VFIFO: ::c_int = 7; +pub const KF_VTYPE_VBAD: ::c_int = 8; +pub const KF_VTYPE_UNKNOWN: ::c_int = 255; + +/// Current working directory +pub const KF_FD_TYPE_CWD: ::c_int = -1; +/// Root directory +pub const KF_FD_TYPE_ROOT: ::c_int = -2; +/// Jail directory +pub const KF_FD_TYPE_JAIL: ::c_int = -3; +/// Ktrace vnode +pub const KF_FD_TYPE_TRACE: ::c_int = -4; +pub const KF_FD_TYPE_TEXT: ::c_int = -5; +/// Controlling terminal +pub const KF_FD_TYPE_CTTY: ::c_int = -6; +pub const KF_FLAG_READ: ::c_int = 0x00000001; +pub const KF_FLAG_WRITE: ::c_int = 0x00000002; +pub const KF_FLAG_APPEND: ::c_int = 0x00000004; +pub const KF_FLAG_ASYNC: ::c_int = 0x00000008; +pub const KF_FLAG_FSYNC: ::c_int = 0x00000010; +pub const KF_FLAG_NONBLOCK: ::c_int = 0x00000020; +pub const KF_FLAG_DIRECT: ::c_int = 0x00000040; +pub const KF_FLAG_HASLOCK: ::c_int = 0x00000080; +pub const KF_FLAG_SHLOCK: ::c_int = 0x00000100; +pub const KF_FLAG_EXLOCK: ::c_int = 0x00000200; +pub const KF_FLAG_NOFOLLOW: ::c_int = 0x00000400; +pub const KF_FLAG_CREAT: ::c_int = 0x00000800; +pub const KF_FLAG_TRUNC: ::c_int = 0x00001000; +pub const KF_FLAG_EXCL: ::c_int = 0x00002000; +pub const KF_FLAG_EXEC: ::c_int = 0x00004000; + +pub const KVME_TYPE_NONE: ::c_int = 0; +pub const KVME_TYPE_DEFAULT: ::c_int = 1; +pub const KVME_TYPE_VNODE: ::c_int = 2; +pub const KVME_TYPE_SWAP: ::c_int = 3; +pub const KVME_TYPE_DEVICE: ::c_int = 4; +pub const KVME_TYPE_PHYS: ::c_int = 5; +pub const KVME_TYPE_DEAD: ::c_int = 6; +pub const KVME_TYPE_SG: ::c_int = 7; +pub const KVME_TYPE_MGTDEVICE: ::c_int = 8; +// Present in `sys/user.h` but is undefined for whatever reason... +// pub const KVME_TYPE_GUARD: ::c_int = 9; +pub const KVME_TYPE_UNKNOWN: ::c_int = 255; +pub const KVME_PROT_READ: ::c_int = 0x00000001; +pub const KVME_PROT_WRITE: ::c_int = 0x00000002; +pub const KVME_PROT_EXEC: ::c_int = 0x00000004; +pub const KVME_FLAG_COW: ::c_int = 0x00000001; +pub const KVME_FLAG_NEEDS_COPY: ::c_int = 0x00000002; +pub const KVME_FLAG_NOCOREDUMP: ::c_int = 0x00000004; +pub const KVME_FLAG_SUPER: ::c_int = 0x00000008; +pub const KVME_FLAG_GROWS_UP: ::c_int = 0x00000010; +pub const KVME_FLAG_GROWS_DOWN: ::c_int = 0x00000020; +pub const KVME_FLAG_USER_WIRED: ::c_int = 0x00000040; + +pub const KKST_MAXLEN: ::c_int = 1024; +/// Stack is valid. +pub const KKST_STATE_STACKOK: ::c_int = 0; +/// Stack swapped out. +pub const KKST_STATE_SWAPPED: ::c_int = 1; +pub const KKST_STATE_RUNNING: ::c_int = 2; + +// Constants about priority. +pub const PRI_MIN: ::c_int = 0; +pub const PRI_MAX: ::c_int = 255; +pub const PRI_MIN_ITHD: ::c_int = PRI_MIN; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PRI_MAX_ITHD: ::c_int = PRI_MIN_REALTIME - 1; +pub const PI_REALTIME: ::c_int = PRI_MIN_ITHD + 0; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PI_AV: ::c_int = PRI_MIN_ITHD + 4; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PI_NET: ::c_int = PRI_MIN_ITHD + 8; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PI_DISK: ::c_int = PRI_MIN_ITHD + 12; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PI_TTY: ::c_int = PRI_MIN_ITHD + 16; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PI_DULL: ::c_int = PRI_MIN_ITHD + 20; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PI_SOFT: ::c_int = PRI_MIN_ITHD + 24; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PRI_MIN_REALTIME: ::c_int = 48; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PRI_MAX_REALTIME: ::c_int = PRI_MIN_KERN - 1; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PRI_MIN_KERN: ::c_int = 80; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PRI_MAX_KERN: ::c_int = PRI_MIN_TIMESHARE - 1; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PSWP: ::c_int = PRI_MIN_KERN + 0; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PVM: ::c_int = PRI_MIN_KERN + 4; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PINOD: ::c_int = PRI_MIN_KERN + 8; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PRIBIO: ::c_int = PRI_MIN_KERN + 12; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PVFS: ::c_int = PRI_MIN_KERN + 16; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PZERO: ::c_int = PRI_MIN_KERN + 20; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PSOCK: ::c_int = PRI_MIN_KERN + 24; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PWAIT: ::c_int = PRI_MIN_KERN + 28; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PLOCK: ::c_int = PRI_MIN_KERN + 32; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PPAUSE: ::c_int = PRI_MIN_KERN + 36; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const PRI_MIN_TIMESHARE: ::c_int = 120; +pub const PRI_MAX_TIMESHARE: ::c_int = PRI_MIN_IDLE - 1; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +#[allow(deprecated)] +pub const PUSER: ::c_int = PRI_MIN_TIMESHARE; +pub const PRI_MIN_IDLE: ::c_int = 224; +pub const PRI_MAX_IDLE: ::c_int = PRI_MAX; + +pub const NZERO: ::c_int = 0; + +// Resource utilization information. +pub const RUSAGE_THREAD: ::c_int = 1; + +cfg_if! { + if #[cfg(any(freebsd11, target_pointer_width = "32"))] { + pub const ARG_MAX: ::c_int = 256 * 1024; + } else { + pub const ARG_MAX: ::c_int = 2 * 256 * 1024; + } +} +pub const CHILD_MAX: ::c_int = 40; +/// max command name remembered +pub const MAXCOMLEN: usize = 19; +/// max interpreter file name length +pub const MAXINTERP: ::c_int = ::PATH_MAX; +/// max login name length (incl. NUL) +pub const MAXLOGNAME: ::c_int = 33; +/// max simultaneous processes +pub const MAXUPRC: ::c_int = CHILD_MAX; +/// max bytes for an exec function +pub const NCARGS: ::c_int = ARG_MAX; +/// /* max number groups +pub const NGROUPS: ::c_int = NGROUPS_MAX + 1; +/// max open files per process +pub const NOFILE: ::c_int = OPEN_MAX; +/// marker for empty group set member +pub const NOGROUP: ::c_int = 65535; +/// max hostname size +pub const MAXHOSTNAMELEN: ::c_int = 256; +/// max bytes in term canon input line +pub const MAX_CANON: ::c_int = 255; +/// max bytes in terminal input +pub const MAX_INPUT: ::c_int = 255; +/// max bytes in a file name +pub const NAME_MAX: ::c_int = 255; +pub const MAXSYMLINKS: ::c_int = 32; +/// max supplemental group id's +pub const NGROUPS_MAX: ::c_int = 1023; +/// max open files per process +pub const OPEN_MAX: ::c_int = 64; + +pub const _POSIX_ARG_MAX: ::c_int = 4096; +pub const _POSIX_LINK_MAX: ::c_int = 8; +pub const _POSIX_MAX_CANON: ::c_int = 255; +pub const _POSIX_MAX_INPUT: ::c_int = 255; +pub const _POSIX_NAME_MAX: ::c_int = 14; +pub const _POSIX_PIPE_BUF: ::c_int = 512; +pub const _POSIX_SSIZE_MAX: ::c_int = 32767; +pub const _POSIX_STREAM_MAX: ::c_int = 8; + +/// max ibase/obase values in bc(1) +pub const BC_BASE_MAX: ::c_int = 99; +/// max array elements in bc(1) +pub const BC_DIM_MAX: ::c_int = 2048; +/// max scale value in bc(1) +pub const BC_SCALE_MAX: ::c_int = 99; +/// max const string length in bc(1) +pub const BC_STRING_MAX: ::c_int = 1000; +/// max character class name size +pub const CHARCLASS_NAME_MAX: ::c_int = 14; +/// max weights for order keyword +pub const COLL_WEIGHTS_MAX: ::c_int = 10; +/// max expressions nested in expr(1) +pub const EXPR_NEST_MAX: ::c_int = 32; +/// max bytes in an input line +pub const LINE_MAX: ::c_int = 2048; +/// max RE's in interval notation +pub const RE_DUP_MAX: ::c_int = 255; + +pub const _POSIX2_BC_BASE_MAX: ::c_int = 99; +pub const _POSIX2_BC_DIM_MAX: ::c_int = 2048; +pub const _POSIX2_BC_SCALE_MAX: ::c_int = 99; +pub const _POSIX2_BC_STRING_MAX: ::c_int = 1000; +pub const _POSIX2_CHARCLASS_NAME_MAX: ::c_int = 14; +pub const _POSIX2_COLL_WEIGHTS_MAX: ::c_int = 2; +pub const _POSIX2_EQUIV_CLASS_MAX: ::c_int = 2; +pub const _POSIX2_EXPR_NEST_MAX: ::c_int = 32; +pub const _POSIX2_LINE_MAX: ::c_int = 2048; +pub const _POSIX2_RE_DUP_MAX: ::c_int = 255; + +// sys/proc.h +pub const TDF_BORROWING: ::c_int = 0x00000001; +pub const TDF_INPANIC: ::c_int = 0x00000002; +pub const TDF_INMEM: ::c_int = 0x00000004; +pub const TDF_SINTR: ::c_int = 0x00000008; +pub const TDF_TIMEOUT: ::c_int = 0x00000010; +pub const TDF_IDLETD: ::c_int = 0x00000020; +pub const TDF_CANSWAP: ::c_int = 0x00000040; +pub const TDF_KTH_SUSP: ::c_int = 0x00000100; +pub const TDF_ALLPROCSUSP: ::c_int = 0x00000200; +pub const TDF_BOUNDARY: ::c_int = 0x00000400; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_ASTPENDING: ::c_int = 0x00000800; +pub const TDF_SBDRY: ::c_int = 0x00002000; +pub const TDF_UPIBLOCKED: ::c_int = 0x00004000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_NEEDSUSPCHK: ::c_int = 0x00008000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_NEEDRESCHED: ::c_int = 0x00010000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_NEEDSIGCHK: ::c_int = 0x00020000; +pub const TDF_NOLOAD: ::c_int = 0x00040000; +pub const TDF_SERESTART: ::c_int = 0x00080000; +pub const TDF_THRWAKEUP: ::c_int = 0x00100000; +pub const TDF_SEINTR: ::c_int = 0x00200000; +pub const TDF_SWAPINREQ: ::c_int = 0x00400000; +#[deprecated(since = "0.2.133", note = "Removed in FreeBSD 14")] +pub const TDF_UNUSED23: ::c_int = 0x00800000; +pub const TDF_SCHED0: ::c_int = 0x01000000; +pub const TDF_SCHED1: ::c_int = 0x02000000; +pub const TDF_SCHED2: ::c_int = 0x04000000; +pub const TDF_SCHED3: ::c_int = 0x08000000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_ALRMPEND: ::c_int = 0x10000000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_PROFPEND: ::c_int = 0x20000000; +#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] +pub const TDF_MACPEND: ::c_int = 0x40000000; + +pub const TDB_SUSPEND: ::c_int = 0x00000001; +pub const TDB_XSIG: ::c_int = 0x00000002; +pub const TDB_USERWR: ::c_int = 0x00000004; +pub const TDB_SCE: ::c_int = 0x00000008; +pub const TDB_SCX: ::c_int = 0x00000010; +pub const TDB_EXEC: ::c_int = 0x00000020; +pub const TDB_FORK: ::c_int = 0x00000040; +pub const TDB_STOPATFORK: ::c_int = 0x00000080; +pub const TDB_CHILD: ::c_int = 0x00000100; +pub const TDB_BORN: ::c_int = 0x00000200; +pub const TDB_EXIT: ::c_int = 0x00000400; +pub const TDB_VFORK: ::c_int = 0x00000800; +pub const TDB_FSTP: ::c_int = 0x00001000; +pub const TDB_STEP: ::c_int = 0x00002000; + +pub const TDP_OLDMASK: ::c_int = 0x00000001; +pub const TDP_INKTR: ::c_int = 0x00000002; +pub const TDP_INKTRACE: ::c_int = 0x00000004; +pub const TDP_BUFNEED: ::c_int = 0x00000008; +pub const TDP_COWINPROGRESS: ::c_int = 0x00000010; +pub const TDP_ALTSTACK: ::c_int = 0x00000020; +pub const TDP_DEADLKTREAT: ::c_int = 0x00000040; +pub const TDP_NOFAULTING: ::c_int = 0x00000080; +pub const TDP_OWEUPC: ::c_int = 0x00000200; +pub const TDP_ITHREAD: ::c_int = 0x00000400; +pub const TDP_SYNCIO: ::c_int = 0x00000800; +pub const TDP_SCHED1: ::c_int = 0x00001000; +pub const TDP_SCHED2: ::c_int = 0x00002000; +pub const TDP_SCHED3: ::c_int = 0x00004000; +pub const TDP_SCHED4: ::c_int = 0x00008000; +pub const TDP_GEOM: ::c_int = 0x00010000; +pub const TDP_SOFTDEP: ::c_int = 0x00020000; +pub const TDP_NORUNNINGBUF: ::c_int = 0x00040000; +pub const TDP_WAKEUP: ::c_int = 0x00080000; +pub const TDP_INBDFLUSH: ::c_int = 0x00100000; +pub const TDP_KTHREAD: ::c_int = 0x00200000; +pub const TDP_CALLCHAIN: ::c_int = 0x00400000; +pub const TDP_IGNSUSP: ::c_int = 0x00800000; +pub const TDP_AUDITREC: ::c_int = 0x01000000; +pub const TDP_RFPPWAIT: ::c_int = 0x02000000; +pub const TDP_RESETSPUR: ::c_int = 0x04000000; +pub const TDP_NERRNO: ::c_int = 0x08000000; +pub const TDP_EXECVMSPC: ::c_int = 0x40000000; + +pub const TDI_SUSPENDED: ::c_int = 0x0001; +pub const TDI_SLEEPING: ::c_int = 0x0002; +pub const TDI_SWAPPED: ::c_int = 0x0004; +pub const TDI_LOCK: ::c_int = 0x0008; +pub const TDI_IWAIT: ::c_int = 0x0010; + +pub const P_ADVLOCK: ::c_int = 0x00000001; +pub const P_CONTROLT: ::c_int = 0x00000002; +pub const P_KPROC: ::c_int = 0x00000004; +pub const P_UNUSED3: ::c_int = 0x00000008; +pub const P_PPWAIT: ::c_int = 0x00000010; +pub const P_PROFIL: ::c_int = 0x00000020; +pub const P_STOPPROF: ::c_int = 0x00000040; +pub const P_HADTHREADS: ::c_int = 0x00000080; +pub const P_SUGID: ::c_int = 0x00000100; +pub const P_SYSTEM: ::c_int = 0x00000200; +pub const P_SINGLE_EXIT: ::c_int = 0x00000400; +pub const P_TRACED: ::c_int = 0x00000800; +pub const P_WAITED: ::c_int = 0x00001000; +pub const P_WEXIT: ::c_int = 0x00002000; +pub const P_EXEC: ::c_int = 0x00004000; +pub const P_WKILLED: ::c_int = 0x00008000; +pub const P_CONTINUED: ::c_int = 0x00010000; +pub const P_STOPPED_SIG: ::c_int = 0x00020000; +pub const P_STOPPED_TRACE: ::c_int = 0x00040000; +pub const P_STOPPED_SINGLE: ::c_int = 0x00080000; +pub const P_PROTECTED: ::c_int = 0x00100000; +pub const P_SIGEVENT: ::c_int = 0x00200000; +pub const P_SINGLE_BOUNDARY: ::c_int = 0x00400000; +pub const P_HWPMC: ::c_int = 0x00800000; +pub const P_JAILED: ::c_int = 0x01000000; +pub const P_TOTAL_STOP: ::c_int = 0x02000000; +pub const P_INEXEC: ::c_int = 0x04000000; +pub const P_STATCHILD: ::c_int = 0x08000000; +pub const P_INMEM: ::c_int = 0x10000000; +pub const P_SWAPPINGOUT: ::c_int = 0x20000000; +pub const P_SWAPPINGIN: ::c_int = 0x40000000; +pub const P_PPTRACE: ::c_int = 0x80000000; +pub const P_STOPPED: ::c_int = P_STOPPED_SIG | P_STOPPED_SINGLE | P_STOPPED_TRACE; + +pub const P2_INHERIT_PROTECTED: ::c_int = 0x00000001; +pub const P2_NOTRACE: ::c_int = 0x00000002; +pub const P2_NOTRACE_EXEC: ::c_int = 0x00000004; +pub const P2_AST_SU: ::c_int = 0x00000008; +pub const P2_PTRACE_FSTP: ::c_int = 0x00000010; +pub const P2_TRAPCAP: ::c_int = 0x00000020; +pub const P2_STKGAP_DISABLE: ::c_int = 0x00000800; +pub const P2_STKGAP_DISABLE_EXEC: ::c_int = 0x00001000; + +pub const P_TREE_ORPHANED: ::c_int = 0x00000001; +pub const P_TREE_FIRST_ORPHAN: ::c_int = 0x00000002; +pub const P_TREE_REAPER: ::c_int = 0x00000004; + +pub const SIDL: ::c_char = 1; +pub const SRUN: ::c_char = 2; +pub const SSLEEP: ::c_char = 3; +pub const SSTOP: ::c_char = 4; +pub const SZOMB: ::c_char = 5; +pub const SWAIT: ::c_char = 6; +pub const SLOCK: ::c_char = 7; + +pub const P_MAGIC: ::c_int = 0xbeefface; + +pub const TDP_SIGFASTBLOCK: ::c_int = 0x00000100; +pub const TDP_UIOHELD: ::c_int = 0x10000000; +pub const TDP_SIGFASTPENDING: ::c_int = 0x80000000; +pub const TDP2_COMPAT32RB: ::c_int = 0x00000002; +pub const P2_PROTMAX_ENABLE: ::c_int = 0x00000200; +pub const P2_PROTMAX_DISABLE: ::c_int = 0x00000400; +pub const TDP2_SBPAGES: ::c_int = 0x00000001; +pub const P2_ASLR_ENABLE: ::c_int = 0x00000040; +pub const P2_ASLR_DISABLE: ::c_int = 0x00000080; +pub const P2_ASLR_IGNSTART: ::c_int = 0x00000100; +pub const P_TREE_GRPEXITED: ::c_int = 0x00000008; + +// libprocstat.h +pub const PS_FST_VTYPE_VNON: ::c_int = 1; +pub const PS_FST_VTYPE_VREG: ::c_int = 2; +pub const PS_FST_VTYPE_VDIR: ::c_int = 3; +pub const PS_FST_VTYPE_VBLK: ::c_int = 4; +pub const PS_FST_VTYPE_VCHR: ::c_int = 5; +pub const PS_FST_VTYPE_VLNK: ::c_int = 6; +pub const PS_FST_VTYPE_VSOCK: ::c_int = 7; +pub const PS_FST_VTYPE_VFIFO: ::c_int = 8; +pub const PS_FST_VTYPE_VBAD: ::c_int = 9; +pub const PS_FST_VTYPE_UNKNOWN: ::c_int = 255; + +pub const PS_FST_TYPE_VNODE: ::c_int = 1; +pub const PS_FST_TYPE_FIFO: ::c_int = 2; +pub const PS_FST_TYPE_SOCKET: ::c_int = 3; +pub const PS_FST_TYPE_PIPE: ::c_int = 4; +pub const PS_FST_TYPE_PTS: ::c_int = 5; +pub const PS_FST_TYPE_KQUEUE: ::c_int = 6; +pub const PS_FST_TYPE_MQUEUE: ::c_int = 8; +pub const PS_FST_TYPE_SHM: ::c_int = 9; +pub const PS_FST_TYPE_SEM: ::c_int = 10; +pub const PS_FST_TYPE_UNKNOWN: ::c_int = 11; +pub const PS_FST_TYPE_NONE: ::c_int = 12; +pub const PS_FST_TYPE_PROCDESC: ::c_int = 13; +pub const PS_FST_TYPE_DEV: ::c_int = 14; +pub const PS_FST_TYPE_EVENTFD: ::c_int = 15; + +pub const PS_FST_UFLAG_RDIR: ::c_int = 0x0001; +pub const PS_FST_UFLAG_CDIR: ::c_int = 0x0002; +pub const PS_FST_UFLAG_JAIL: ::c_int = 0x0004; +pub const PS_FST_UFLAG_TRACE: ::c_int = 0x0008; +pub const PS_FST_UFLAG_TEXT: ::c_int = 0x0010; +pub const PS_FST_UFLAG_MMAP: ::c_int = 0x0020; +pub const PS_FST_UFLAG_CTTY: ::c_int = 0x0040; + +pub const PS_FST_FFLAG_READ: ::c_int = 0x0001; +pub const PS_FST_FFLAG_WRITE: ::c_int = 0x0002; +pub const PS_FST_FFLAG_NONBLOCK: ::c_int = 0x0004; +pub const PS_FST_FFLAG_APPEND: ::c_int = 0x0008; +pub const PS_FST_FFLAG_SHLOCK: ::c_int = 0x0010; +pub const PS_FST_FFLAG_EXLOCK: ::c_int = 0x0020; +pub const PS_FST_FFLAG_ASYNC: ::c_int = 0x0040; +pub const PS_FST_FFLAG_SYNC: ::c_int = 0x0080; +pub const PS_FST_FFLAG_NOFOLLOW: ::c_int = 0x0100; +pub const PS_FST_FFLAG_CREAT: ::c_int = 0x0200; +pub const PS_FST_FFLAG_TRUNC: ::c_int = 0x0400; +pub const PS_FST_FFLAG_EXCL: ::c_int = 0x0800; +pub const PS_FST_FFLAG_DIRECT: ::c_int = 0x1000; +pub const PS_FST_FFLAG_EXEC: ::c_int = 0x2000; +pub const PS_FST_FFLAG_HASLOCK: ::c_int = 0x4000; + +// sys/mount.h + +/// File identifier. +/// These are unique per filesystem on a single machine. +/// +/// Note that the offset of fid_data is 4 bytes, so care must be taken to avoid +/// undefined behavior accessing unaligned fields within an embedded struct. +pub const MAXFIDSZ: ::c_int = 16; +/// Length of type name including null. +pub const MFSNAMELEN: ::c_int = 16; +cfg_if! { + if #[cfg(any(freebsd10, freebsd11))] { + /// Size of on/from name bufs. + pub const MNAMELEN: ::c_int = 88; + } else { + /// Size of on/from name bufs. + pub const MNAMELEN: ::c_int = 1024; + } +} + +/// Using journaled soft updates. +pub const MNT_SUJ: u64 = 0x100000000; +/// Mounted by automountd(8). +pub const MNT_AUTOMOUNTED: u64 = 0x200000000; +/// Filesys metadata untrusted. +pub const MNT_UNTRUSTED: u64 = 0x800000000; + +/// Require TLS. +pub const MNT_EXTLS: u64 = 0x4000000000; +/// Require TLS with client cert. +pub const MNT_EXTLSCERT: u64 = 0x8000000000; +/// Require TLS with user cert. +pub const MNT_EXTLSCERTUSER: u64 = 0x10000000000; + +/// Filesystem is stored locally. +pub const MNT_LOCAL: u64 = 0x000001000; +/// Quotas are enabled on fs. +pub const MNT_QUOTA: u64 = 0x000002000; +/// Identifies the root fs. +pub const MNT_ROOTFS: u64 = 0x000004000; +/// Mounted by a user. +pub const MNT_USER: u64 = 0x000008000; +/// Do not show entry in df. +pub const MNT_IGNORE: u64 = 0x000800000; +/// Filesystem is verified. +pub const MNT_VERIFIED: u64 = 0x400000000; + +/// Do not cover a mount point. +pub const MNT_NOCOVER: u64 = 0x001000000000; +/// Only mount on empty dir. +pub const MNT_EMPTYDIR: u64 = 0x002000000000; +/// Recursively unmount uppers. +pub const MNT_RECURSE: u64 = 0x100000000000; +/// Unmount in async context. +pub const MNT_DEFERRED: u64 = 0x200000000000; + +/// Get configured filesystems. +pub const VFS_VFSCONF: ::c_int = 0; +/// Generic filesystem information. +pub const VFS_GENERIC: ::c_int = 0; + +/// int: highest defined filesystem type. +pub const VFS_MAXTYPENUM: ::c_int = 1; +/// struct: vfsconf for filesystem given as next argument. +pub const VFS_CONF: ::c_int = 2; + +/// Synchronously wait for I/O to complete. +pub const MNT_WAIT: ::c_int = 1; +/// Start all I/O, but do not wait for it. +pub const MNT_NOWAIT: ::c_int = 2; +/// Push data not written by filesystem syncer. +pub const MNT_LAZY: ::c_int = 3; +/// Suspend file system after sync. +pub const MNT_SUSPEND: ::c_int = 4; + +pub const MAXSECFLAVORS: ::c_int = 5; + +/// Statically compiled into kernel. +pub const VFCF_STATIC: ::c_int = 0x00010000; +/// May get data over the network. +pub const VFCF_NETWORK: ::c_int = 0x00020000; +/// Writes are not implemented. +pub const VFCF_READONLY: ::c_int = 0x00040000; +/// Data does not represent real files. +pub const VFCF_SYNTHETIC: ::c_int = 0x00080000; +/// Aliases some other mounted FS. +pub const VFCF_LOOPBACK: ::c_int = 0x00100000; +/// Stores file names as Unicode. +pub const VFCF_UNICODE: ::c_int = 0x00200000; +/// Can be mounted from within a jail. +pub const VFCF_JAIL: ::c_int = 0x00400000; +/// Supports delegated administration. +pub const VFCF_DELEGADMIN: ::c_int = 0x00800000; +/// Stop at Boundary: defer stop requests to kernel->user (AST) transition. +pub const VFCF_SBDRY: ::c_int = 0x01000000; + +// time.h + +/// not on dst +pub const DST_NONE: ::c_int = 0; +/// USA style dst +pub const DST_USA: ::c_int = 1; +/// Australian style dst +pub const DST_AUST: ::c_int = 2; +/// Western European dst +pub const DST_WET: ::c_int = 3; +/// Middle European dst +pub const DST_MET: ::c_int = 4; +/// Eastern European dst +pub const DST_EET: ::c_int = 5; +/// Canada +pub const DST_CAN: ::c_int = 6; + +pub const CPUCLOCK_WHICH_PID: ::c_int = 0; +pub const CPUCLOCK_WHICH_TID: ::c_int = 1; + +pub const MFD_CLOEXEC: ::c_uint = 0x00000001; +pub const MFD_ALLOW_SEALING: ::c_uint = 0x00000002; +pub const MFD_HUGETLB: ::c_uint = 0x00000004; +pub const MFD_HUGE_MASK: ::c_uint = 0xFC000000; +pub const MFD_HUGE_64KB: ::c_uint = 16 << 26; +pub const MFD_HUGE_512KB: ::c_uint = 19 << 26; +pub const MFD_HUGE_1MB: ::c_uint = 20 << 26; +pub const MFD_HUGE_2MB: ::c_uint = 21 << 26; +pub const MFD_HUGE_8MB: ::c_uint = 23 << 26; +pub const MFD_HUGE_16MB: ::c_uint = 24 << 26; +pub const MFD_HUGE_32MB: ::c_uint = 25 << 26; +pub const MFD_HUGE_256MB: ::c_uint = 28 << 26; +pub const MFD_HUGE_512MB: ::c_uint = 29 << 26; +pub const MFD_HUGE_1GB: ::c_uint = 30 << 26; +pub const MFD_HUGE_2GB: ::c_uint = 31 << 26; +pub const MFD_HUGE_16GB: ::c_uint = 34 << 26; + +pub const SHM_LARGEPAGE_ALLOC_DEFAULT: ::c_int = 0; +pub const SHM_LARGEPAGE_ALLOC_NOWAIT: ::c_int = 1; +pub const SHM_LARGEPAGE_ALLOC_HARD: ::c_int = 2; +pub const SHM_RENAME_NOREPLACE: ::c_int = 1 << 0; +pub const SHM_RENAME_EXCHANGE: ::c_int = 1 << 1; + +// sys/umtx.h + +pub const UMTX_OP_WAIT: ::c_int = 2; +pub const UMTX_OP_WAKE: ::c_int = 3; +pub const UMTX_OP_MUTEX_TRYLOCK: ::c_int = 4; +pub const UMTX_OP_MUTEX_LOCK: ::c_int = 5; +pub const UMTX_OP_MUTEX_UNLOCK: ::c_int = 6; +pub const UMTX_OP_SET_CEILING: ::c_int = 7; +pub const UMTX_OP_CV_WAIT: ::c_int = 8; +pub const UMTX_OP_CV_SIGNAL: ::c_int = 9; +pub const UMTX_OP_CV_BROADCAST: ::c_int = 10; +pub const UMTX_OP_WAIT_UINT: ::c_int = 11; +pub const UMTX_OP_RW_RDLOCK: ::c_int = 12; +pub const UMTX_OP_RW_WRLOCK: ::c_int = 13; +pub const UMTX_OP_RW_UNLOCK: ::c_int = 14; +pub const UMTX_OP_WAIT_UINT_PRIVATE: ::c_int = 15; +pub const UMTX_OP_WAKE_PRIVATE: ::c_int = 16; +pub const UMTX_OP_MUTEX_WAIT: ::c_int = 17; +pub const UMTX_OP_NWAKE_PRIVATE: ::c_int = 21; +pub const UMTX_OP_MUTEX_WAKE2: ::c_int = 22; +pub const UMTX_OP_SEM2_WAIT: ::c_int = 23; +pub const UMTX_OP_SEM2_WAKE: ::c_int = 24; +pub const UMTX_OP_SHM: ::c_int = 25; +pub const UMTX_OP_ROBUST_LISTS: ::c_int = 26; + +pub const UMTX_ABSTIME: u32 = 1; + +pub const CPU_LEVEL_ROOT: ::c_int = 1; +pub const CPU_LEVEL_CPUSET: ::c_int = 2; +pub const CPU_LEVEL_WHICH: ::c_int = 3; + +pub const CPU_WHICH_TID: ::c_int = 1; +pub const CPU_WHICH_PID: ::c_int = 2; +pub const CPU_WHICH_CPUSET: ::c_int = 3; +pub const CPU_WHICH_IRQ: ::c_int = 4; +pub const CPU_WHICH_JAIL: ::c_int = 5; + +// sys/signal.h +pub const SIGTHR: ::c_int = 32; +pub const SIGLWP: ::c_int = SIGTHR; +pub const SIGLIBRT: ::c_int = 33; + +// netinet/sctp.h +pub const SCTP_FUTURE_ASSOC: ::c_int = 0; +pub const SCTP_CURRENT_ASSOC: ::c_int = 1; +pub const SCTP_ALL_ASSOC: ::c_int = 2; + +pub const SCTP_NO_NEXT_MSG: ::c_int = 0x0000; +pub const SCTP_NEXT_MSG_AVAIL: ::c_int = 0x0001; +pub const SCTP_NEXT_MSG_ISCOMPLETE: ::c_int = 0x0002; +pub const SCTP_NEXT_MSG_IS_UNORDERED: ::c_int = 0x0004; +pub const SCTP_NEXT_MSG_IS_NOTIFICATION: ::c_int = 0x0008; + +pub const SCTP_RECVV_NOINFO: ::c_int = 0; +pub const SCTP_RECVV_RCVINFO: ::c_int = 1; +pub const SCTP_RECVV_NXTINFO: ::c_int = 2; +pub const SCTP_RECVV_RN: ::c_int = 3; + +pub const SCTP_SENDV_NOINFO: ::c_int = 0; +pub const SCTP_SENDV_SNDINFO: ::c_int = 1; +pub const SCTP_SENDV_PRINFO: ::c_int = 2; +pub const SCTP_SENDV_AUTHINFO: ::c_int = 3; +pub const SCTP_SENDV_SPA: ::c_int = 4; + +pub const SCTP_SEND_SNDINFO_VALID: ::c_int = 0x00000001; +pub const SCTP_SEND_PRINFO_VALID: ::c_int = 0x00000002; +pub const SCTP_SEND_AUTHINFO_VALID: ::c_int = 0x00000004; + +pub const SCTP_NOTIFICATION: ::c_int = 0x0010; +pub const SCTP_COMPLETE: ::c_int = 0x0020; +pub const SCTP_EOF: ::c_int = 0x0100; +pub const SCTP_ABORT: ::c_int = 0x0200; +pub const SCTP_UNORDERED: ::c_int = 0x0400; +pub const SCTP_ADDR_OVER: ::c_int = 0x0800; +pub const SCTP_SENDALL: ::c_int = 0x1000; +pub const SCTP_EOR: ::c_int = 0x2000; +pub const SCTP_SACK_IMMEDIATELY: ::c_int = 0x4000; +pub const SCTP_PR_SCTP_NONE: ::c_int = 0x0000; +pub const SCTP_PR_SCTP_TTL: ::c_int = 0x0001; +pub const SCTP_PR_SCTP_PRIO: ::c_int = 0x0002; +pub const SCTP_PR_SCTP_BUF: ::c_int = SCTP_PR_SCTP_PRIO; +pub const SCTP_PR_SCTP_RTX: ::c_int = 0x0003; +pub const SCTP_PR_SCTP_MAX: ::c_int = SCTP_PR_SCTP_RTX; +pub const SCTP_PR_SCTP_ALL: ::c_int = 0x000f; + +pub const SCTP_INIT: ::c_int = 0x0001; +pub const SCTP_SNDRCV: ::c_int = 0x0002; +pub const SCTP_EXTRCV: ::c_int = 0x0003; +pub const SCTP_SNDINFO: ::c_int = 0x0004; +pub const SCTP_RCVINFO: ::c_int = 0x0005; +pub const SCTP_NXTINFO: ::c_int = 0x0006; +pub const SCTP_PRINFO: ::c_int = 0x0007; +pub const SCTP_AUTHINFO: ::c_int = 0x0008; +pub const SCTP_DSTADDRV4: ::c_int = 0x0009; +pub const SCTP_DSTADDRV6: ::c_int = 0x000a; + +pub const SCTP_RTOINFO: ::c_int = 0x00000001; +pub const SCTP_ASSOCINFO: ::c_int = 0x00000002; +pub const SCTP_INITMSG: ::c_int = 0x00000003; +pub const SCTP_NODELAY: ::c_int = 0x00000004; +pub const SCTP_AUTOCLOSE: ::c_int = 0x00000005; +pub const SCTP_SET_PEER_PRIMARY_ADDR: ::c_int = 0x00000006; +pub const SCTP_PRIMARY_ADDR: ::c_int = 0x00000007; +pub const SCTP_ADAPTATION_LAYER: ::c_int = 0x00000008; +pub const SCTP_ADAPTION_LAYER: ::c_int = 0x00000008; +pub const SCTP_DISABLE_FRAGMENTS: ::c_int = 0x00000009; +pub const SCTP_PEER_ADDR_PARAMS: ::c_int = 0x0000000a; +pub const SCTP_DEFAULT_SEND_PARAM: ::c_int = 0x0000000b; +pub const SCTP_EVENTS: ::c_int = 0x0000000c; +pub const SCTP_I_WANT_MAPPED_V4_ADDR: ::c_int = 0x0000000d; +pub const SCTP_MAXSEG: ::c_int = 0x0000000e; +pub const SCTP_DELAYED_SACK: ::c_int = 0x0000000f; +pub const SCTP_FRAGMENT_INTERLEAVE: ::c_int = 0x00000010; +pub const SCTP_PARTIAL_DELIVERY_POINT: ::c_int = 0x00000011; +pub const SCTP_AUTH_CHUNK: ::c_int = 0x00000012; +pub const SCTP_AUTH_KEY: ::c_int = 0x00000013; +pub const SCTP_HMAC_IDENT: ::c_int = 0x00000014; +pub const SCTP_AUTH_ACTIVE_KEY: ::c_int = 0x00000015; +pub const SCTP_AUTH_DELETE_KEY: ::c_int = 0x00000016; +pub const SCTP_USE_EXT_RCVINFO: ::c_int = 0x00000017; +pub const SCTP_AUTO_ASCONF: ::c_int = 0x00000018; +pub const SCTP_MAXBURST: ::c_int = 0x00000019; +pub const SCTP_MAX_BURST: ::c_int = 0x00000019; +pub const SCTP_CONTEXT: ::c_int = 0x0000001a; +pub const SCTP_EXPLICIT_EOR: ::c_int = 0x00000001b; +pub const SCTP_REUSE_PORT: ::c_int = 0x00000001c; +pub const SCTP_AUTH_DEACTIVATE_KEY: ::c_int = 0x00000001d; +pub const SCTP_EVENT: ::c_int = 0x0000001e; +pub const SCTP_RECVRCVINFO: ::c_int = 0x0000001f; +pub const SCTP_RECVNXTINFO: ::c_int = 0x00000020; +pub const SCTP_DEFAULT_SNDINFO: ::c_int = 0x00000021; +pub const SCTP_DEFAULT_PRINFO: ::c_int = 0x00000022; +pub const SCTP_PEER_ADDR_THLDS: ::c_int = 0x00000023; +pub const SCTP_REMOTE_UDP_ENCAPS_PORT: ::c_int = 0x00000024; +pub const SCTP_ECN_SUPPORTED: ::c_int = 0x00000025; +pub const SCTP_AUTH_SUPPORTED: ::c_int = 0x00000027; +pub const SCTP_ASCONF_SUPPORTED: ::c_int = 0x00000028; +pub const SCTP_RECONFIG_SUPPORTED: ::c_int = 0x00000029; +pub const SCTP_NRSACK_SUPPORTED: ::c_int = 0x00000030; +pub const SCTP_PKTDROP_SUPPORTED: ::c_int = 0x00000031; +pub const SCTP_MAX_CWND: ::c_int = 0x00000032; + +pub const SCTP_STATUS: ::c_int = 0x00000100; +pub const SCTP_GET_PEER_ADDR_INFO: ::c_int = 0x00000101; +pub const SCTP_PEER_AUTH_CHUNKS: ::c_int = 0x00000102; +pub const SCTP_LOCAL_AUTH_CHUNKS: ::c_int = 0x00000103; +pub const SCTP_GET_ASSOC_NUMBER: ::c_int = 0x00000104; +pub const SCTP_GET_ASSOC_ID_LIST: ::c_int = 0x00000105; +pub const SCTP_TIMEOUTS: ::c_int = 0x00000106; +pub const SCTP_PR_STREAM_STATUS: ::c_int = 0x00000107; +pub const SCTP_PR_ASSOC_STATUS: ::c_int = 0x00000108; + +pub const SCTP_COMM_UP: ::c_int = 0x0001; +pub const SCTP_COMM_LOST: ::c_int = 0x0002; +pub const SCTP_RESTART: ::c_int = 0x0003; +pub const SCTP_SHUTDOWN_COMP: ::c_int = 0x0004; +pub const SCTP_CANT_STR_ASSOC: ::c_int = 0x0005; + +pub const SCTP_ASSOC_SUPPORTS_PR: ::c_int = 0x01; +pub const SCTP_ASSOC_SUPPORTS_AUTH: ::c_int = 0x02; +pub const SCTP_ASSOC_SUPPORTS_ASCONF: ::c_int = 0x03; +pub const SCTP_ASSOC_SUPPORTS_MULTIBUF: ::c_int = 0x04; +pub const SCTP_ASSOC_SUPPORTS_RE_CONFIG: ::c_int = 0x05; +pub const SCTP_ASSOC_SUPPORTS_INTERLEAVING: ::c_int = 0x06; +pub const SCTP_ASSOC_SUPPORTS_MAX: ::c_int = 0x06; + +pub const SCTP_ADDR_AVAILABLE: ::c_int = 0x0001; +pub const SCTP_ADDR_UNREACHABLE: ::c_int = 0x0002; +pub const SCTP_ADDR_REMOVED: ::c_int = 0x0003; +pub const SCTP_ADDR_ADDED: ::c_int = 0x0004; +pub const SCTP_ADDR_MADE_PRIM: ::c_int = 0x0005; +pub const SCTP_ADDR_CONFIRMED: ::c_int = 0x0006; + +pub const SCTP_ACTIVE: ::c_int = 0x0001; +pub const SCTP_INACTIVE: ::c_int = 0x0002; +pub const SCTP_UNCONFIRMED: ::c_int = 0x0200; + +pub const SCTP_DATA_UNSENT: ::c_int = 0x0001; +pub const SCTP_DATA_SENT: ::c_int = 0x0002; + +pub const SCTP_PARTIAL_DELIVERY_ABORTED: ::c_int = 0x0001; + +pub const SCTP_AUTH_NEW_KEY: ::c_int = 0x0001; +pub const SCTP_AUTH_NEWKEY: ::c_int = SCTP_AUTH_NEW_KEY; +pub const SCTP_AUTH_NO_AUTH: ::c_int = 0x0002; +pub const SCTP_AUTH_FREE_KEY: ::c_int = 0x0003; + +pub const SCTP_STREAM_RESET_INCOMING_SSN: ::c_int = 0x0001; +pub const SCTP_STREAM_RESET_OUTGOING_SSN: ::c_int = 0x0002; +pub const SCTP_STREAM_RESET_DENIED: ::c_int = 0x0004; +pub const SCTP_STREAM_RESET_FAILED: ::c_int = 0x0008; + +pub const SCTP_ASSOC_RESET_DENIED: ::c_int = 0x0004; +pub const SCTP_ASSOC_RESET_FAILED: ::c_int = 0x0008; + +pub const SCTP_STREAM_CHANGE_DENIED: ::c_int = 0x0004; +pub const SCTP_STREAM_CHANGE_FAILED: ::c_int = 0x0008; + +pub const KENV_DUMP_LOADER: ::c_int = 4; +pub const KENV_DUMP_STATIC: ::c_int = 5; + +pub const RB_PAUSE: ::c_int = 0x100000; +pub const RB_REROOT: ::c_int = 0x200000; +pub const RB_POWERCYCLE: ::c_int = 0x400000; +pub const RB_PROBE: ::c_int = 0x10000000; +pub const RB_MULTIPLE: ::c_int = 0x20000000; + +// sys/time.h +pub const CLOCK_BOOTTIME: ::clockid_t = ::CLOCK_UPTIME; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = ::CLOCK_REALTIME_FAST; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = ::CLOCK_MONOTONIC_FAST; + +// sys/timerfd.h + +pub const TFD_NONBLOCK: ::c_int = ::O_NONBLOCK; +pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const TFD_TIMER_ABSTIME: ::c_int = 0x01; +pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 0x02; + +cfg_if! { + if #[cfg(libc_const_extern_fn)] { + pub const fn MAP_ALIGNED(a: ::c_int) -> ::c_int { + a << 24 + } + } else { + pub fn MAP_ALIGNED(a: ::c_int) -> ::c_int { + a << 24 + } + } +} + +const_fn! { + {const} fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + pub fn MALLOCX_ALIGN(lg: ::c_uint) -> ::c_int { + ffsl(lg as ::c_long - 1) + } + + pub {const} fn MALLOCX_TCACHE(tc: ::c_int) -> ::c_int { + (tc + 2) << 8 as ::c_int + } + + pub {const} fn MALLOCX_ARENA(a: ::c_int) -> ::c_int { + (a + 1) << 20 as ::c_int + } + + pub fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { + ngrps - 1 + } else { + 0 + }; + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps + } + + pub fn uname(buf: *mut ::utsname) -> ::c_int { + __xuname(256, buf as *mut ::c_void) + } + + pub fn CPU_ZERO(cpuset: &mut cpuset_t) -> () { + for slot in cpuset.__bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_FILL(cpuset: &mut cpuset_t) -> () { + for slot in cpuset.__bits.iter_mut() { + *slot = !0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpuset_t) -> () { + let bitset_bits = 8 * ::mem::size_of::<::c_long>(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + cpuset.__bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpuset_t) -> () { + let bitset_bits = 8 * ::mem::size_of::<::c_long>(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + cpuset.__bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpuset_t) -> bool { + let bitset_bits = 8 * ::mem::size_of::<::c_long>(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + 0 != cpuset.__bits[idx] & (1 << offset) + } + + pub fn CPU_COUNT(cpuset: &cpuset_t) -> ::c_int { + let mut s: u32 = 0; + let cpuset_size = ::mem::size_of::(); + let bitset_size = ::mem::size_of::<::c_long>(); + + for i in cpuset.__bits[..(cpuset_size / bitset_size)].iter() { + s += i.count_ones(); + }; + s as ::c_int + } + + pub fn SOCKCRED2SIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { + ngrps - 1 + } else { + 0 + }; + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps + } + + pub fn PROT_MAX(x: ::c_int) -> ::c_int { + x << 16 + } + + pub fn PROT_MAX_EXTRACT(x: ::c_int) -> ::c_int { + (x >> 16) & (::PROT_READ | ::PROT_WRITE | ::PROT_EXEC) + } +} + +safe_f! { + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 && status != 0x13 + } + + pub {const} fn INVALID_SINFO_FLAG(x: ::c_int) -> bool { + (x) & 0xfffffff0 & !(SCTP_EOF | SCTP_ABORT | SCTP_UNORDERED | + SCTP_ADDR_OVER | SCTP_SENDALL | SCTP_EOR | SCTP_SACK_IMMEDIATELY) != 0 + } + + pub {const} fn PR_SCTP_POLICY(x: ::c_int) -> ::c_int { + x & 0x0f + } + + pub {const} fn PR_SCTP_ENABLED(x: ::c_int) -> bool { + PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE && PR_SCTP_POLICY(x) != SCTP_PR_SCTP_ALL + } + + pub {const} fn PR_SCTP_TTL_ENABLED(x: ::c_int) -> bool { + PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL + } + + pub {const} fn PR_SCTP_BUF_ENABLED(x: ::c_int) -> bool { + PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF + } + + pub {const} fn PR_SCTP_RTX_ENABLED(x: ::c_int) -> bool { + PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX + } + + pub {const} fn PR_SCTP_INVALID_POLICY(x: ::c_int) -> bool { + PR_SCTP_POLICY(x) > SCTP_PR_SCTP_MAX + } + + pub {const} fn PR_SCTP_VALID_POLICY(x: ::c_int) -> bool { + PR_SCTP_POLICY(x) <= SCTP_PR_SCTP_MAX + } +} + +cfg_if! { + if #[cfg(not(any(freebsd10, freebsd11)))] { + extern "C" { + pub fn fhlink(fhp: *mut fhandle_t, to: *const ::c_char) -> ::c_int; + pub fn fhlinkat(fhp: *mut fhandle_t, tofd: ::c_int, to: *const ::c_char) -> ::c_int; + pub fn fhreadlink( + fhp: *mut fhandle_t, + buf: *mut ::c_char, + bufsize: ::size_t, + ) -> ::c_int; + pub fn getfhat( + fd: ::c_int, + path: *mut ::c_char, + fhp: *mut fhandle, + flag: ::c_int, + ) -> ::c_int; + } + } +} + +extern "C" { + #[cfg_attr(doc, doc(alias = "__errno_location"))] + #[cfg_attr(doc, doc(alias = "errno"))] + pub fn __error() -> *mut ::c_int; + + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_readv(aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_writev(aiocbp: *mut ::aiocb) -> ::c_int; + + pub fn copy_file_range( + infd: ::c_int, + inoffp: *mut ::off_t, + outfd: ::c_int, + outoffp: *mut ::off_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + + pub fn devname_r( + dev: ::dev_t, + mode: ::mode_t, + buf: *mut ::c_char, + len: ::c_int, + ) -> *mut ::c_char; + + pub fn extattr_delete_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_get_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_list_fd( + fd: ::c_int, + attrnamespace: ::c_int, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_list_file( + path: *const ::c_char, + attrnamespace: ::c_int, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_list_link( + path: *const ::c_char, + attrnamespace: ::c_int, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_set_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_set_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_set_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + + pub fn fspacectl( + fd: ::c_int, + cmd: ::c_int, + rqsr: *const spacectl_range, + flags: ::c_int, + rmsr: *mut spacectl_range, + ) -> ::c_int; + + pub fn jail(jail: *mut ::jail) -> ::c_int; + pub fn jail_attach(jid: ::c_int) -> ::c_int; + pub fn jail_remove(jid: ::c_int) -> ::c_int; + pub fn jail_get(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn jail_set(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; + + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + + pub fn getutxuser(user: *const ::c_char) -> *mut utmpx; + pub fn setutxdb(_type: ::c_int, file: *const ::c_char) -> ::c_int; + + pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, timeout: *mut ::timespec) -> ::ssize_t; + pub fn mq_getfd_np(mqd: ::mqd_t) -> ::c_int; + + pub fn waitid( + idtype: idtype_t, + id: ::id_t, + infop: *mut ::siginfo_t, + options: ::c_int, + ) -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + + pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn semget(key: ::key_t, nsems: ::c_int, semflg: ::c_int) -> ::c_int; + pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; + pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut ::msqid_ds) -> ::c_int; + pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; + pub fn msgsnd( + msqid: ::c_int, + msgp: *const ::c_void, + msgsz: ::size_t, + msgflg: ::c_int, + ) -> ::c_int; + pub fn cfmakesane(termios: *mut ::termios); + + pub fn pdfork(fdp: *mut ::c_int, flags: ::c_int) -> ::pid_t; + pub fn pdgetpid(fd: ::c_int, pidp: *mut ::pid_t) -> ::c_int; + pub fn pdkill(fd: ::c_int, signum: ::c_int) -> ::c_int; + + pub fn rtprio_thread(function: ::c_int, lwpid: ::lwpid_t, rtp: *mut super::rtprio) -> ::c_int; + + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + flags: *mut ::c_int, + ) -> ::c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; + + pub fn uuidgen(store: *mut uuid, count: ::c_int) -> ::c_int; + + pub fn thr_kill(id: ::c_long, sig: ::c_int) -> ::c_int; + pub fn thr_kill2(pid: ::pid_t, id: ::c_long, sig: ::c_int) -> ::c_int; + pub fn thr_self(tid: *mut ::c_long) -> ::c_int; + pub fn pthread_getthreadid_np() -> ::c_int; + pub fn pthread_getaffinity_np( + td: ::pthread_t, + cpusetsize: ::size_t, + cpusetp: *mut cpuset_t, + ) -> ::c_int; + pub fn pthread_setaffinity_np( + td: ::pthread_t, + cpusetsize: ::size_t, + cpusetp: *const cpuset_t, + ) -> ::c_int; + + // sched.h linux compatibility api + pub fn sched_getaffinity(pid: ::pid_t, cpusetsz: ::size_t, cpuset: *mut ::cpuset_t) -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsz: ::size_t, + cpuset: *const ::cpuset_t, + ) -> ::c_int; + pub fn sched_getcpu() -> ::c_int; + + pub fn pthread_mutex_consistent(mutex: *mut ::pthread_mutex_t) -> ::c_int; + + pub fn pthread_mutexattr_getrobust( + attr: *mut ::pthread_mutexattr_t, + robust: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setrobust( + attr: *mut ::pthread_mutexattr_t, + robust: ::c_int, + ) -> ::c_int; + + pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; + + #[cfg_attr(all(target_os = "freebsd", freebsd11), link_name = "statfs@FBSD_1.0")] + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + #[cfg_attr(all(target_os = "freebsd", freebsd11), link_name = "fstatfs@FBSD_1.0")] + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn __xuname(nmln: ::c_int, buf: *mut ::c_void) -> ::c_int; + + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::size_t, + flags: ::c_int, + timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + + pub fn fhopen(fhp: *const fhandle_t, flags: ::c_int) -> ::c_int; + pub fn fhstat(fhp: *const fhandle, buf: *mut ::stat) -> ::c_int; + pub fn fhstatfs(fhp: *const fhandle_t, buf: *mut ::statfs) -> ::c_int; + pub fn getfh(path: *const ::c_char, fhp: *mut fhandle_t) -> ::c_int; + pub fn lgetfh(path: *const ::c_char, fhp: *mut fhandle_t) -> ::c_int; + pub fn getfsstat(buf: *mut ::statfs, bufsize: ::c_long, mode: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", freebsd11), + link_name = "getmntinfo@FBSD_1.0" + )] + pub fn getmntinfo(mntbufp: *mut *mut ::statfs, mode: ::c_int) -> ::c_int; + pub fn mount( + type_: *const ::c_char, + dir: *const ::c_char, + flags: ::c_int, + data: *mut ::c_void, + ) -> ::c_int; + pub fn nmount(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn setproctitle(fmt: *const ::c_char, ...); + pub fn rfork(flags: ::c_int) -> ::c_int; + pub fn cpuset_getaffinity( + level: cpulevel_t, + which: cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *mut cpuset_t, + ) -> ::c_int; + pub fn cpuset_setaffinity( + level: cpulevel_t, + which: cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *const cpuset_t, + ) -> ::c_int; + pub fn cpuset(setid: *mut ::cpusetid_t) -> ::c_int; + pub fn cpuset_getid( + level: cpulevel_t, + which: cpuwhich_t, + id: ::id_t, + setid: *mut ::cpusetid_t, + ) -> ::c_int; + pub fn cpuset_setid(which: cpuwhich_t, id: ::id_t, setid: ::cpusetid_t) -> ::c_int; + pub fn cap_enter() -> ::c_int; + pub fn cap_getmode(modep: *mut ::c_uint) -> ::c_int; + pub fn cap_fcntls_get(fd: ::c_int, fcntlrightsp: *mut u32) -> ::c_int; + pub fn cap_fcntls_limit(fd: ::c_int, fcntlrights: u32) -> ::c_int; + pub fn cap_ioctls_get(fd: ::c_int, cmds: *mut u_long, maxcmds: usize) -> isize; + pub fn cap_ioctls_limit(fd: ::c_int, cmds: *const u_long, ncmds: usize) -> ::c_int; + pub fn __cap_rights_init(version: ::c_int, rights: *mut cap_rights_t, ...) + -> *mut cap_rights_t; + pub fn __cap_rights_get(version: ::c_int, fd: ::c_int, rightsp: *mut cap_rights_t) -> ::c_int; + pub fn __cap_rights_set(rights: *mut cap_rights_t, ...) -> *mut cap_rights_t; + pub fn __cap_rights_clear(rights: *mut cap_rights_t, ...) -> *mut cap_rights_t; + pub fn __cap_rights_is_set(rights: *const cap_rights_t, ...) -> bool; + pub fn cap_rights_is_valid(rights: *const cap_rights_t) -> bool; + pub fn cap_rights_limit(fd: ::c_int, rights: *const cap_rights_t) -> ::c_int; + pub fn cap_rights_merge(dst: *mut cap_rights_t, src: *const cap_rights_t) -> *mut cap_rights_t; + pub fn cap_rights_remove(dst: *mut cap_rights_t, src: *const cap_rights_t) + -> *mut cap_rights_t; + pub fn cap_rights_contains(big: *const cap_rights_t, little: *const cap_rights_t) -> bool; + pub fn cap_sandboxed() -> bool; + + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn ffs(value: ::c_int) -> ::c_int; + pub fn ffsl(value: ::c_long) -> ::c_int; + pub fn ffsll(value: ::c_longlong) -> ::c_int; + pub fn fls(value: ::c_int) -> ::c_int; + pub fn flsl(value: ::c_long) -> ::c_int; + pub fn flsll(value: ::c_longlong) -> ::c_int; + pub fn malloc_stats_print( + write_cb: unsafe extern "C" fn(*mut ::c_void, *const ::c_char), + cbopaque: *mut ::c_void, + opt: *const ::c_char, + ); + pub fn mallctl( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn mallctlnametomib( + name: *const ::c_char, + mibp: *mut ::size_t, + miplen: *mut ::size_t, + ) -> ::c_int; + pub fn mallctlbymib( + mib: *const ::size_t, + mible: ::size_t, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn mallocx(size: ::size_t, flags: ::c_int) -> *mut ::c_void; + pub fn rallocx(ptr: *mut ::c_void, size: ::size_t, flags: ::c_int) -> *mut ::c_void; + pub fn xallocx(ptr: *mut ::c_void, size: ::size_t, extra: ::size_t, flags: ::c_int) + -> ::size_t; + pub fn sallocx(ptr: *const ::c_void, flags: ::c_int) -> ::size_t; + pub fn dallocx(ptr: *mut ::c_void, flags: ::c_int); + pub fn sdallocx(ptr: *mut ::c_void, size: ::size_t, flags: ::c_int); + pub fn nallocx(size: ::size_t, flags: ::c_int) -> ::size_t; + + pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int; + + pub fn getpagesize() -> ::c_int; + pub fn getpagesizes(pagesize: *mut ::size_t, nelem: ::c_int) -> ::c_int; + + pub fn clock_getcpuclockid2(arg1: ::id_t, arg2: ::c_int, arg3: *mut clockid_t) -> ::c_int; + pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; + + pub fn shm_create_largepage( + path: *const ::c_char, + flags: ::c_int, + psind: ::c_int, + alloc_policy: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn shm_rename( + path_from: *const ::c_char, + path_to: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn setaudit(auditinfo: *const auditinfo_t) -> ::c_int; + + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int; + pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::c_int; + + pub fn fdatasync(fd: ::c_int) -> ::c_int; + + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn elf_aux_info(aux: ::c_int, buf: *mut ::c_void, buflen: ::c_int) -> ::c_int; + pub fn setproctitle_fast(fmt: *const ::c_char, ...); + pub fn timingsafe_bcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn timingsafe_memcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; + + pub fn _umtx_op( + obj: *mut ::c_void, + op: ::c_int, + val: ::c_ulong, + uaddr: *mut ::c_void, + uaddr2: *mut ::c_void, + ) -> ::c_int; + + pub fn sctp_peeloff(s: ::c_int, id: ::sctp_assoc_t) -> ::c_int; + pub fn sctp_bindx(s: ::c_int, addrs: *mut ::sockaddr, num: ::c_int, tpe: ::c_int) -> ::c_int; + pub fn sctp_connectx( + s: ::c_int, + addrs: *const ::sockaddr, + addrcnt: ::c_int, + id: *mut ::sctp_assoc_t, + ) -> ::c_int; + pub fn sctp_getaddrlen(family: ::sa_family_t) -> ::c_int; + pub fn sctp_getpaddrs( + s: ::c_int, + asocid: ::sctp_assoc_t, + addrs: *mut *mut ::sockaddr, + ) -> ::c_int; + pub fn sctp_freepaddrs(addrs: *mut ::sockaddr); + pub fn sctp_getladdrs( + s: ::c_int, + asocid: ::sctp_assoc_t, + addrs: *mut *mut ::sockaddr, + ) -> ::c_int; + pub fn sctp_freeladdrs(addrs: *mut ::sockaddr); + pub fn sctp_opt_info( + s: ::c_int, + id: ::sctp_assoc_t, + opt: ::c_int, + arg: *mut ::c_void, + size: *mut ::socklen_t, + ) -> ::c_int; + pub fn sctp_sendv( + sd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + addrs: *mut ::sockaddr, + addrcnt: ::c_int, + info: *mut ::c_void, + infolen: ::socklen_t, + infotype: ::c_uint, + flags: ::c_int, + ) -> ::ssize_t; + pub fn sctp_recvv( + sd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + from: *mut ::sockaddr, + fromlen: *mut ::socklen_t, + info: *mut ::c_void, + infolen: *mut ::socklen_t, + infotype: *mut ::c_uint, + flags: *mut ::c_int, + ) -> ::ssize_t; + + pub fn timerfd_create(clockid: ::c_int, flags: ::c_int) -> ::c_int; + pub fn timerfd_gettime(fd: ::c_int, curr_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn closefrom(lowfd: ::c_int); + pub fn close_range(lowfd: ::c_uint, highfd: ::c_uint, flags: ::c_int) -> ::c_int; +} + +#[link(name = "memstat")] +extern "C" { + pub fn memstat_strerror(error: ::c_int) -> *const ::c_char; + pub fn memstat_mtl_alloc() -> *mut memory_type_list; + pub fn memstat_mtl_first(list: *mut memory_type_list) -> *mut memory_type; + pub fn memstat_mtl_next(mtp: *mut memory_type) -> *mut memory_type; + pub fn memstat_mtl_find( + list: *mut memory_type_list, + allocator: ::c_int, + name: *const ::c_char, + ) -> *mut memory_type; + pub fn memstat_mtl_free(list: *mut memory_type_list); + pub fn memstat_mtl_geterror(list: *mut memory_type_list) -> ::c_int; + pub fn memstat_get_name(mtp: *const memory_type) -> *const ::c_char; +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_dpcpu_setcpu(kd: *mut ::kvm_t, cpu: ::c_uint) -> ::c_int; + pub fn kvm_getargv(kd: *mut ::kvm_t, p: *const kinfo_proc, nchr: ::c_int) + -> *mut *mut ::c_char; + pub fn kvm_getcptime(kd: *mut ::kvm_t, cp_time: *mut ::c_long) -> ::c_int; + pub fn kvm_getenvv(kd: *mut ::kvm_t, p: *const kinfo_proc, nchr: ::c_int) + -> *mut *mut ::c_char; + pub fn kvm_geterr(kd: *mut ::kvm_t) -> *mut ::c_char; + pub fn kvm_getmaxcpu(kd: *mut ::kvm_t) -> ::c_int; + pub fn kvm_getncpus(kd: *mut ::kvm_t) -> ::c_int; + pub fn kvm_getpcpu(kd: *mut ::kvm_t, cpu: ::c_int) -> *mut ::c_void; + pub fn kvm_counter_u64_fetch(kd: *mut ::kvm_t, base: ::c_ulong) -> u64; + pub fn kvm_getswapinfo( + kd: *mut ::kvm_t, + info: *mut kvm_swap, + maxswap: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn kvm_native(kd: *mut ::kvm_t) -> ::c_int; + pub fn kvm_nlist(kd: *mut ::kvm_t, nl: *mut nlist) -> ::c_int; + pub fn kvm_nlist2(kd: *mut ::kvm_t, nl: *mut kvm_nlist) -> ::c_int; + pub fn kvm_read_zpcpu( + kd: *mut ::kvm_t, + base: ::c_ulong, + buf: *mut ::c_void, + size: ::size_t, + cpu: ::c_int, + ) -> ::ssize_t; + pub fn kvm_read2( + kd: *mut ::kvm_t, + addr: kvaddr_t, + buf: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; +} + +#[link(name = "util")] +extern "C" { + pub fn extattr_namespace_to_string( + attrnamespace: ::c_int, + string: *mut *mut ::c_char, + ) -> ::c_int; + pub fn extattr_string_to_namespace( + string: *const ::c_char, + attrnamespace: *mut ::c_int, + ) -> ::c_int; + pub fn realhostname(host: *mut ::c_char, hsize: ::size_t, ip: *const ::in_addr) -> ::c_int; + pub fn realhostname_sa( + host: *mut ::c_char, + hsize: ::size_t, + addr: *mut ::sockaddr, + addrlen: ::c_int, + ) -> ::c_int; + + pub fn kld_isloaded(name: *const ::c_char) -> ::c_int; + pub fn kld_load(name: *const ::c_char) -> ::c_int; + + pub fn kinfo_getvmmap(pid: ::pid_t, cntp: *mut ::c_int) -> *mut kinfo_vmentry; + + pub fn hexdump(ptr: *const ::c_void, length: ::c_int, hdr: *const ::c_char, flags: ::c_int); + pub fn humanize_number( + buf: *mut ::c_char, + len: ::size_t, + number: i64, + suffix: *const ::c_char, + scale: ::c_int, + flags: ::c_int, + ) -> ::c_int; + + pub fn flopen(path: *const ::c_char, flags: ::c_int, ...) -> ::c_int; + pub fn flopenat(fd: ::c_int, path: *const ::c_char, flags: ::c_int, ...) -> ::c_int; + + pub fn getlocalbase() -> *const ::c_char; + + pub fn pidfile_open( + path: *const ::c_char, + mode: ::mode_t, + pidptr: *mut ::pid_t, + ) -> *mut ::pidfh; + pub fn pidfile_write(path: *mut ::pidfh) -> ::c_int; + pub fn pidfile_close(path: *mut ::pidfh) -> ::c_int; + pub fn pidfile_remove(path: *mut ::pidfh) -> ::c_int; + pub fn pidfile_fileno(path: *const ::pidfh) -> ::c_int; + // FIXME: pidfile_signal in due time (both manpage present and updated image snapshot) +} + +#[link(name = "procstat")] +extern "C" { + pub fn procstat_open_sysctl() -> *mut procstat; + pub fn procstat_getfiles( + procstat: *mut procstat, + kp: *mut kinfo_proc, + mmapped: ::c_int, + ) -> *mut filestat_list; + pub fn procstat_freefiles(procstat: *mut procstat, head: *mut filestat_list); + pub fn procstat_getprocs( + procstat: *mut procstat, + what: ::c_int, + arg: ::c_int, + count: *mut ::c_uint, + ) -> *mut kinfo_proc; + pub fn procstat_freeprocs(procstat: *mut procstat, p: *mut kinfo_proc); + pub fn procstat_getvmmap( + procstat: *mut procstat, + kp: *mut kinfo_proc, + count: *mut ::c_uint, + ) -> *mut kinfo_vmentry; + pub fn procstat_freevmmap(procstat: *mut procstat, vmmap: *mut kinfo_vmentry); + pub fn procstat_close(procstat: *mut procstat); + pub fn procstat_freeargv(procstat: *mut procstat); + pub fn procstat_freeenvv(procstat: *mut procstat); + pub fn procstat_freegroups(procstat: *mut procstat, groups: *mut ::gid_t); + pub fn procstat_freeptlwpinfo(procstat: *mut procstat, pl: *mut ptrace_lwpinfo); + pub fn procstat_getargv( + procstat: *mut procstat, + kp: *mut kinfo_proc, + nchr: ::size_t, + ) -> *mut *mut ::c_char; + pub fn procstat_getenvv( + procstat: *mut procstat, + kp: *mut kinfo_proc, + nchr: ::size_t, + ) -> *mut *mut ::c_char; + pub fn procstat_getgroups( + procstat: *mut procstat, + kp: *mut kinfo_proc, + count: *mut ::c_uint, + ) -> *mut ::gid_t; + pub fn procstat_getosrel( + procstat: *mut procstat, + kp: *mut kinfo_proc, + osrelp: *mut ::c_int, + ) -> ::c_int; + pub fn procstat_getpathname( + procstat: *mut procstat, + kp: *mut kinfo_proc, + pathname: *mut ::c_char, + maxlen: ::size_t, + ) -> ::c_int; + pub fn procstat_getrlimit( + procstat: *mut procstat, + kp: *mut kinfo_proc, + which: ::c_int, + rlimit: *mut ::rlimit, + ) -> ::c_int; + pub fn procstat_getumask( + procstat: *mut procstat, + kp: *mut kinfo_proc, + maskp: *mut ::c_ushort, + ) -> ::c_int; + pub fn procstat_open_core(filename: *const ::c_char) -> *mut procstat; + pub fn procstat_open_kvm(nlistf: *const ::c_char, memf: *const ::c_char) -> *mut procstat; + pub fn procstat_get_socket_info( + proc_: *mut procstat, + fst: *mut filestat, + sock: *mut sockstat, + errbuf: *mut ::c_char, + ) -> ::c_int; + pub fn procstat_get_vnode_info( + proc_: *mut procstat, + fst: *mut filestat, + vn: *mut vnstat, + errbuf: *mut ::c_char, + ) -> ::c_int; + pub fn procstat_get_pts_info( + proc_: *mut procstat, + fst: *mut filestat, + pts: *mut ptsstat, + errbuf: *mut ::c_char, + ) -> ::c_int; + pub fn procstat_get_shm_info( + proc_: *mut procstat, + fst: *mut filestat, + shm: *mut shmstat, + errbuf: *mut ::c_char, + ) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + pub fn timer_create(clock_id: clockid_t, evp: *mut sigevent, timerid: *mut timer_t) -> ::c_int; + pub fn timer_delete(timerid: timer_t) -> ::c_int; + pub fn timer_getoverrun(timerid: timer_t) -> ::c_int; + pub fn timer_gettime(timerid: timer_t, value: *mut itimerspec) -> ::c_int; + pub fn timer_settime( + timerid: timer_t, + flags: ::c_int, + value: *const itimerspec, + ovalue: *mut itimerspec, + ) -> ::c_int; +} + +#[link(name = "devstat")] +extern "C" { + pub fn devstat_getnumdevs(kd: *mut ::kvm_t) -> ::c_int; + pub fn devstat_getgeneration(kd: *mut ::kvm_t) -> ::c_long; + pub fn devstat_getversion(kd: *mut ::kvm_t) -> ::c_int; + pub fn devstat_checkversion(kd: *mut ::kvm_t) -> ::c_int; + pub fn devstat_selectdevs( + dev_select: *mut *mut device_selection, + num_selected: *mut ::c_int, + num_selections: *mut ::c_int, + select_generation: *mut ::c_long, + current_generation: ::c_long, + devices: *mut devstat, + numdevs: ::c_int, + matches: *mut devstat_match, + num_matches: ::c_int, + dev_selections: *mut *mut ::c_char, + num_dev_selections: ::c_int, + select_mode: devstat_select_mode, + maxshowdevs: ::c_int, + perf_select: ::c_int, + ) -> ::c_int; + pub fn devstat_buildmatch( + match_str: *mut ::c_char, + matches: *mut *mut devstat_match, + num_matches: *mut ::c_int, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(freebsd15)] { + mod freebsd15; + pub use self::freebsd15::*; + } else if #[cfg(freebsd14)] { + mod freebsd14; + pub use self::freebsd14::*; + } else if #[cfg(freebsd13)] { + mod freebsd13; + pub use self::freebsd13::*; + } else if #[cfg(freebsd12)] { + mod freebsd12; + pub use self::freebsd12::*; + } else if #[cfg(any(freebsd10, freebsd11))] { + mod freebsd11; + pub use self::freebsd11::*; + } else { + // Unknown freebsd version + } +} + +cfg_if! { + if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc64; + pub use self::powerpc64::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(target_arch = "riscv64")] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs new file mode 100644 index 00000000..a0120c33 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs @@ -0,0 +1,47 @@ +pub type c_char = u8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i32; +pub type register_t = i32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} + +pub const MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs new file mode 100644 index 00000000..7f5b9752 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs @@ -0,0 +1,47 @@ +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs new file mode 100644 index 00000000..f9fa1c27 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs @@ -0,0 +1,154 @@ +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = ::c_int; +pub type time_t = i64; +pub type suseconds_t = ::c_long; +pub type register_t = i64; + +s_no_extra_traits! { + pub struct gpregs { + pub gp_ra: ::register_t, + pub gp_sp: ::register_t, + pub gp_gp: ::register_t, + pub gp_tp: ::register_t, + pub gp_t: [::register_t; 7], + pub gp_s: [::register_t; 12], + pub gp_a: [::register_t; 8], + pub gp_sepc: ::register_t, + pub gp_sstatus: ::register_t, + } + + pub struct fpregs { + pub fp_x: [[::register_t; 2]; 32], + pub fp_fcsr: ::register_t, + pub fp_flags: ::c_int, + pub fp_pad: ::c_int, + } + + pub struct mcontext_t { + pub mc_gpregs: gpregs, + pub mc_fpregs: fpregs, + pub mc_flags: ::c_int, + pub mc_pad: ::c_int, + pub mc_spare: [u64; 8], + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for gpregs { + fn eq(&self, other: &gpregs) -> bool { + self.gp_ra == other.gp_ra && + self.gp_sp == other.gp_sp && + self.gp_gp == other.gp_gp && + self.gp_tp == other.gp_tp && + self.gp_t.iter().zip(other.gp_t.iter()).all(|(a, b)| a == b) && + self.gp_s.iter().zip(other.gp_s.iter()).all(|(a, b)| a == b) && + self.gp_a.iter().zip(other.gp_a.iter()).all(|(a, b)| a == b) && + self.gp_sepc == other.gp_sepc && + self.gp_sstatus == other.gp_sstatus + } + } + impl Eq for gpregs {} + impl ::fmt::Debug for gpregs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("gpregs") + .field("gp_ra", &self.gp_ra) + .field("gp_sp", &self.gp_sp) + .field("gp_gp", &self.gp_gp) + .field("gp_tp", &self.gp_tp) + .field("gp_t", &self.gp_t) + .field("gp_s", &self.gp_s) + .field("gp_a", &self.gp_a) + .field("gp_sepc", &self.gp_sepc) + .field("gp_sstatus", &self.gp_sstatus) + .finish() + } + } + impl ::hash::Hash for gpregs { + fn hash(&self, state: &mut H) { + self.gp_ra.hash(state); + self.gp_sp.hash(state); + self.gp_gp.hash(state); + self.gp_tp.hash(state); + self.gp_t.hash(state); + self.gp_s.hash(state); + self.gp_a.hash(state); + self.gp_sepc.hash(state); + self.gp_sstatus.hash(state); + } + } + impl PartialEq for fpregs { + fn eq(&self, other: &fpregs) -> bool { + self.fp_x == other.fp_x && + self.fp_fcsr == other.fp_fcsr && + self.fp_flags == other.fp_flags && + self.fp_pad == other.fp_pad + } + } + impl Eq for fpregs {} + impl ::fmt::Debug for fpregs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpregs") + .field("fp_x", &self.fp_x) + .field("fp_fcsr", &self.fp_fcsr) + .field("fp_flags", &self.fp_flags) + .field("fp_pad", &self.fp_pad) + .finish() + } + } + impl ::hash::Hash for fpregs { + fn hash(&self, state: &mut H) { + self.fp_x.hash(state); + self.fp_fcsr.hash(state); + self.fp_flags.hash(state); + self.fp_pad.hash(state); + } + } + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.mc_gpregs == other.mc_gpregs && + self.mc_fpregs == other.mc_fpregs && + self.mc_flags == other.mc_flags && + self.mc_pad == other.mc_pad && + self.mc_spare.iter().zip(other.mc_spare.iter()).all(|(a, b)| a == b) + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("mc_gpregs", &self.mc_gpregs) + .field("mc_fpregs", &self.mc_fpregs) + .field("mc_flags", &self.mc_flags) + .field("mc_pad", &self.mc_pad) + .field("mc_spare", &self.mc_spare) + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.mc_gpregs.hash(state); + self.mc_fpregs.hash(state); + self.mc_flags.hash(state); + self.mc_pad.hash(state); + self.mc_spare.hash(state); + } + } + } +} + +pub const MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 4096; // 1024 * 4 diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs new file mode 100644 index 00000000..4046ec31 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs @@ -0,0 +1,201 @@ +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = i32; +pub type time_t = i32; +pub type suseconds_t = i32; +pub type register_t = i32; + +s_no_extra_traits! { + pub struct mcontext_t { + pub mc_onstack: register_t, + pub mc_gs: register_t, + pub mc_fs: register_t, + pub mc_es: register_t, + pub mc_ds: register_t, + pub mc_edi: register_t, + pub mc_esi: register_t, + pub mc_ebp: register_t, + pub mc_isp: register_t, + pub mc_ebx: register_t, + pub mc_edx: register_t, + pub mc_ecx: register_t, + pub mc_eax: register_t, + pub mc_trapno: register_t, + pub mc_err: register_t, + pub mc_eip: register_t, + pub mc_cs: register_t, + pub mc_eflags: register_t, + pub mc_esp: register_t, + pub mc_ss: register_t, + pub mc_len: ::c_int, + pub mc_fpformat: ::c_int, + pub mc_ownedfp: ::c_int, + pub mc_flags: register_t, + pub mc_fpstate: [[::c_int; 32]; 4], + pub mc_fsbase: register_t, + pub mc_gsbase: register_t, + pub mc_xfpustate: register_t, + pub mc_xfpustate_len: register_t, + pub mc_spare2: [::c_int; 4], + } +} + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: u32, + pub st_lspare: i32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + __unused: [u8; 8], + } + + pub struct ucontext_t { + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: ::mcontext_t, + pub uc_link: *mut ::ucontext_t, + pub uc_stack: ::stack_t, + pub uc_flags: ::c_int, + __spare__: [::c_int; 4], + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.mc_onstack == other.mc_onstack && + self.mc_gs == other.mc_gs && + self.mc_fs == other.mc_fs && + self.mc_es == other.mc_es && + self.mc_ds == other.mc_ds && + self.mc_edi == other.mc_edi && + self.mc_esi == other.mc_esi && + self.mc_ebp == other.mc_ebp && + self.mc_isp == other.mc_isp && + self.mc_ebx == other.mc_ebx && + self.mc_edx == other.mc_edx && + self.mc_ecx == other.mc_ecx && + self.mc_eax == other.mc_eax && + self.mc_trapno == other.mc_trapno && + self.mc_err == other.mc_err && + self.mc_eip == other.mc_eip && + self.mc_cs == other.mc_cs && + self.mc_eflags == other.mc_eflags && + self.mc_esp == other.mc_esp && + self.mc_ss == other.mc_ss && + self.mc_len == other.mc_len && + self.mc_fpformat == other.mc_fpformat && + self.mc_ownedfp == other.mc_ownedfp && + self.mc_flags == other.mc_flags && + self.mc_fpstate.iter().zip(other.mc_fpstate.iter()).all(|(a, b)| a == b) && + self.mc_fsbase == other.mc_fsbase && + self.mc_gsbase == other.mc_gsbase && + self.mc_xfpustate == other.mc_xfpustate && + self.mc_xfpustate_len == other.mc_xfpustate_len && + self.mc_spare2.iter().zip(other.mc_spare2.iter()).all(|(a, b)| a == b) + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("mc_onstack", &self.mc_onstack) + .field("mc_gs", &self.mc_gs) + .field("mc_fs", &self.mc_fs) + .field("mc_es", &self.mc_es) + .field("mc_ds", &self.mc_ds) + .field("mc_edi", &self.mc_edi) + .field("mc_esi", &self.mc_esi) + .field("mc_ebp", &self.mc_ebp) + .field("mc_isp", &self.mc_isp) + .field("mc_ebx", &self.mc_ebx) + .field("mc_edx", &self.mc_edx) + .field("mc_ecx", &self.mc_ecx) + .field("mc_eax", &self.mc_eax) + .field("mc_trapno", &self.mc_trapno) + .field("mc_err", &self.mc_err) + .field("mc_eip", &self.mc_eip) + .field("mc_cs", &self.mc_cs) + .field("mc_eflags", &self.mc_eflags) + .field("mc_esp", &self.mc_esp) + .field("mc_ss", &self.mc_ss) + .field("mc_len", &self.mc_len) + .field("mc_fpformat", &self.mc_fpformat) + .field("mc_ownedfp", &self.mc_ownedfp) + .field("mc_flags", &self.mc_flags) + .field("mc_fpstate", &self.mc_fpstate) + .field("mc_fsbase", &self.mc_fsbase) + .field("mc_gsbase", &self.mc_gsbase) + .field("mc_xfpustate", &self.mc_xfpustate) + .field("mc_xfpustate_len", &self.mc_xfpustate_len) + .field("mc_spare2", &self.mc_spare2) + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.mc_onstack.hash(state); + self.mc_gs.hash(state); + self.mc_fs.hash(state); + self.mc_es.hash(state); + self.mc_ds.hash(state); + self.mc_edi.hash(state); + self.mc_esi.hash(state); + self.mc_ebp.hash(state); + self.mc_isp.hash(state); + self.mc_ebx.hash(state); + self.mc_edx.hash(state); + self.mc_ecx.hash(state); + self.mc_eax.hash(state); + self.mc_trapno.hash(state); + self.mc_err.hash(state); + self.mc_eip.hash(state); + self.mc_cs.hash(state); + self.mc_eflags.hash(state); + self.mc_esp.hash(state); + self.mc_ss.hash(state); + self.mc_len.hash(state); + self.mc_fpformat.hash(state); + self.mc_ownedfp.hash(state); + self.mc_flags.hash(state); + self.mc_fpstate.hash(state); + self.mc_fsbase.hash(state); + self.mc_gsbase.hash(state); + self.mc_xfpustate.hash(state); + self.mc_xfpustate_len.hash(state); + self.mc_spare2.hash(state); + } + } + } +} + +pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs new file mode 100644 index 00000000..3a016a05 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs @@ -0,0 +1,197 @@ +use {c_long, register_t}; + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + + #[repr(align(16))] + pub struct mcontext_t { + pub mc_onstack: register_t, + pub mc_rdi: register_t, + pub mc_rsi: register_t, + pub mc_rdx: register_t, + pub mc_rcx: register_t, + pub mc_r8: register_t, + pub mc_r9: register_t, + pub mc_rax: register_t, + pub mc_rbx: register_t, + pub mc_rbp: register_t, + pub mc_r10: register_t, + pub mc_r11: register_t, + pub mc_r12: register_t, + pub mc_r13: register_t, + pub mc_r14: register_t, + pub mc_r15: register_t, + pub mc_trapno: u32, + pub mc_fs: u16, + pub mc_gs: u16, + pub mc_addr: register_t, + pub mc_flags: u32, + pub mc_es: u16, + pub mc_ds: u16, + pub mc_err: register_t, + pub mc_rip: register_t, + pub mc_cs: register_t, + pub mc_rflags: register_t, + pub mc_rsp: register_t, + pub mc_ss: register_t, + pub mc_len: c_long, + pub mc_fpformat: c_long, + pub mc_ownedfp: c_long, + pub mc_fpstate: [c_long; 64], + pub mc_fsbase: register_t, + pub mc_gsbase: register_t, + pub mc_xfpustate: register_t, + pub mc_xfpustate_len: register_t, + pub mc_spare: [c_long; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.mc_onstack == other.mc_onstack && + self.mc_rdi == other.mc_rdi && + self.mc_rsi == other.mc_rsi && + self.mc_rdx == other.mc_rdx && + self.mc_rcx == other.mc_rcx && + self.mc_r8 == other.mc_r8 && + self.mc_r9 == other.mc_r9 && + self.mc_rax == other.mc_rax && + self.mc_rbx == other.mc_rbx && + self.mc_rbp == other.mc_rbp && + self.mc_r10 == other.mc_r10 && + self.mc_r11 == other.mc_r11 && + self.mc_r12 == other.mc_r12 && + self.mc_r13 == other.mc_r13 && + self.mc_r14 == other.mc_r14 && + self.mc_r15 == other.mc_r15 && + self.mc_trapno == other.mc_trapno && + self.mc_fs == other.mc_fs && + self.mc_gs == other.mc_gs && + self.mc_addr == other.mc_addr && + self.mc_flags == other.mc_flags && + self.mc_es == other.mc_es && + self.mc_ds == other.mc_ds && + self.mc_err == other.mc_err && + self.mc_rip == other.mc_rip && + self.mc_cs == other.mc_cs && + self.mc_rflags == other.mc_rflags && + self.mc_rsp == other.mc_rsp && + self.mc_ss == other.mc_ss && + self.mc_len == other.mc_len && + self.mc_fpformat == other.mc_fpformat && + self.mc_ownedfp == other.mc_ownedfp && + self.mc_fpstate.iter().zip(other.mc_fpstate.iter()) + .all(|(a, b)| a == b) && + self.mc_fsbase == other.mc_fsbase && + self.mc_gsbase == other.mc_gsbase && + self.mc_xfpustate == other.mc_xfpustate && + self.mc_xfpustate_len == other.mc_xfpustate_len && + self.mc_spare == other.mc_spare + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("mc_onstack", &self.mc_onstack) + .field("mc_rdi", &self.mc_rdi) + .field("mc_rsi", &self.mc_rsi) + .field("mc_rdx", &self.mc_rdx) + .field("mc_rcx", &self.mc_rcx) + .field("mc_r8", &self.mc_r8) + .field("mc_r9", &self.mc_r9) + .field("mc_rax", &self.mc_rax) + .field("mc_rbx", &self.mc_rbx) + .field("mc_rbp", &self.mc_rbp) + .field("mc_r10", &self.mc_r10) + .field("mc_r11", &self.mc_r11) + .field("mc_r12", &self.mc_r12) + .field("mc_r13", &self.mc_r13) + .field("mc_r14", &self.mc_r14) + .field("mc_r15", &self.mc_r15) + .field("mc_trapno", &self.mc_trapno) + .field("mc_fs", &self.mc_fs) + .field("mc_gs", &self.mc_gs) + .field("mc_addr", &self.mc_addr) + .field("mc_flags", &self.mc_flags) + .field("mc_es", &self.mc_es) + .field("mc_ds", &self.mc_ds) + .field("mc_err", &self.mc_err) + .field("mc_rip", &self.mc_rip) + .field("mc_cs", &self.mc_cs) + .field("mc_rflags", &self.mc_rflags) + .field("mc_rsp", &self.mc_rsp) + .field("mc_ss", &self.mc_ss) + .field("mc_len", &self.mc_len) + .field("mc_fpformat", &self.mc_fpformat) + .field("mc_ownedfp", &self.mc_ownedfp) + // FIXME: .field("mc_fpstate", &self.mc_fpstate) + .field("mc_fsbase", &self.mc_fsbase) + .field("mc_gsbase", &self.mc_gsbase) + .field("mc_xfpustate", &self.mc_xfpustate) + .field("mc_xfpustate_len", &self.mc_xfpustate_len) + .field("mc_spare", &self.mc_spare) + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.mc_onstack.hash(state); + self.mc_rdi.hash(state); + self.mc_rsi.hash(state); + self.mc_rdx.hash(state); + self.mc_rcx.hash(state); + self.mc_r8.hash(state); + self.mc_r9.hash(state); + self.mc_rax.hash(state); + self.mc_rbx.hash(state); + self.mc_rbp.hash(state); + self.mc_r10.hash(state); + self.mc_r11.hash(state); + self.mc_r12.hash(state); + self.mc_r13.hash(state); + self.mc_r14.hash(state); + self.mc_r15.hash(state); + self.mc_trapno.hash(state); + self.mc_fs.hash(state); + self.mc_gs.hash(state); + self.mc_addr.hash(state); + self.mc_flags.hash(state); + self.mc_es.hash(state); + self.mc_ds.hash(state); + self.mc_err.hash(state); + self.mc_rip.hash(state); + self.mc_cs.hash(state); + self.mc_rflags.hash(state); + self.mc_rsp.hash(state); + self.mc_ss.hash(state); + self.mc_len.hash(state); + self.mc_fpformat.hash(state); + self.mc_ownedfp.hash(state); + self.mc_fpstate.hash(state); + self.mc_fsbase.hash(state); + self.mc_gsbase.hash(state); + self.mc_xfpustate.hash(state); + self.mc_xfpustate_len.hash(state); + self.mc_spare.hash(state); + } + } + } +} + +s! { + pub struct ucontext_t { + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: ::mcontext_t, + pub uc_link: *mut ::ucontext_t, + pub uc_stack: ::stack_t, + pub uc_flags: ::c_int, + __spare__: [::c_int; 4], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs new file mode 100644 index 00000000..ae1fcf78 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs @@ -0,0 +1,334 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +s! { + pub struct reg32 { + pub r_fs: u32, + pub r_es: u32, + pub r_ds: u32, + pub r_edi: u32, + pub r_esi: u32, + pub r_ebp: u32, + pub r_isp: u32, + pub r_ebx: u32, + pub r_edx: u32, + pub r_ecx: u32, + pub r_eax: u32, + pub r_trapno: u32, + pub r_err: u32, + pub r_eip: u32, + pub r_cs: u32, + pub r_eflags: u32, + pub r_esp: u32, + pub r_ss: u32, + pub r_gs: u32, + } + + pub struct reg { + pub r_r15: i64, + pub r_r14: i64, + pub r_r13: i64, + pub r_r12: i64, + pub r_r11: i64, + pub r_r10: i64, + pub r_r9: i64, + pub r_r8: i64, + pub r_rdi: i64, + pub r_rsi: i64, + pub r_rbp: i64, + pub r_rbx: i64, + pub r_rdx: i64, + pub r_rcx: i64, + pub r_rax: i64, + pub r_trapno: u32, + pub r_fs: u16, + pub r_gs: u16, + pub r_err: u32, + pub r_es: u16, + pub r_ds: u16, + pub r_rip: i64, + pub r_cs: i64, + pub r_rflags: i64, + pub r_rsp: i64, + pub r_ss: i64, + } +} + +s_no_extra_traits! { + pub struct fpreg32 { + pub fpr_env: [u32; 7], + pub fpr_acc: [[u8; 10]; 8], + pub fpr_ex_sw: u32, + pub fpr_pad: [u8; 64], + } + + pub struct fpreg { + pub fpr_env: [u64; 4], + pub fpr_acc: [[u8; 16]; 8], + pub fpr_xacc: [[u8; 16]; 16], + pub fpr_spare: [u64; 12], + } + + pub struct xmmreg { + pub xmm_env: [u32; 8], + pub xmm_acc: [[u8; 16]; 8], + pub xmm_reg: [[u8; 16]; 8], + pub xmm_pad: [u8; 224], + } + + #[cfg(libc_union)] + pub union __c_anonymous_elf64_auxv_union { + pub a_val: ::c_long, + pub a_ptr: *mut ::c_void, + pub a_fcn: extern "C" fn(), + } + + pub struct Elf64_Auxinfo { + pub a_type: ::c_long, + #[cfg(libc_union)] + pub a_un: __c_anonymous_elf64_auxv_union, + } + + pub struct kinfo_file { + pub kf_structsize: ::c_int, + pub kf_type: ::c_int, + pub kf_fd: ::c_int, + pub kf_ref_count: ::c_int, + pub kf_flags: ::c_int, + _kf_pad0: ::c_int, + pub kf_offset: i64, + _priv: [::uintptr_t; 38], // FIXME if needed + pub kf_status: u16, + _kf_pad1: u16, + _kf_ispare0: ::c_int, + pub kf_cap_rights: ::cap_rights_t, + _kf_cap_spare: u64, + pub kf_path: [::c_char; ::PATH_MAX as usize], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg32 { + fn eq(&self, other: &fpreg32) -> bool { + self.fpr_env == other.fpr_env && + self.fpr_acc == other.fpr_acc && + self.fpr_ex_sw == other.fpr_ex_sw && + self.fpr_pad + .iter() + .zip(other.fpr_pad.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for fpreg32 {} + impl ::fmt::Debug for fpreg32 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg32") + .field("fpr_env", &&self.fpr_env[..]) + .field("fpr_acc", &self.fpr_acc) + .field("fpr_ex_sw", &self.fpr_ex_sw) + .field("fpr_pad", &&self.fpr_pad[..]) + .finish() + } + } + impl ::hash::Hash for fpreg32 { + fn hash(&self, state: &mut H) { + self.fpr_env.hash(state); + self.fpr_acc.hash(state); + self.fpr_ex_sw.hash(state); + self.fpr_pad.hash(state); + } + } + + impl PartialEq for fpreg { + fn eq(&self, other: &fpreg) -> bool { + self.fpr_env == other.fpr_env && + self.fpr_acc == other.fpr_acc && + self.fpr_xacc == other.fpr_xacc && + self.fpr_spare == other.fpr_spare + } + } + impl Eq for fpreg {} + impl ::fmt::Debug for fpreg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg") + .field("fpr_env", &self.fpr_env) + .field("fpr_acc", &self.fpr_acc) + .field("fpr_xacc", &self.fpr_xacc) + .field("fpr_spare", &self.fpr_spare) + .finish() + } + } + impl ::hash::Hash for fpreg { + fn hash(&self, state: &mut H) { + self.fpr_env.hash(state); + self.fpr_acc.hash(state); + self.fpr_xacc.hash(state); + self.fpr_spare.hash(state); + } + } + + impl PartialEq for xmmreg { + fn eq(&self, other: &xmmreg) -> bool { + self.xmm_env == other.xmm_env && + self.xmm_acc == other.xmm_acc && + self.xmm_reg == other.xmm_reg && + self.xmm_pad + .iter() + .zip(other.xmm_pad.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for xmmreg {} + impl ::fmt::Debug for xmmreg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("xmmreg") + .field("xmm_env", &self.xmm_env) + .field("xmm_acc", &self.xmm_acc) + .field("xmm_reg", &self.xmm_reg) + .field("xmm_pad", &&self.xmm_pad[..]) + .finish() + } + } + impl ::hash::Hash for xmmreg { + fn hash(&self, state: &mut H) { + self.xmm_env.hash(state); + self.xmm_acc.hash(state); + self.xmm_reg.hash(state); + self.xmm_pad.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_elf64_auxv_union { + fn eq(&self, other: &__c_anonymous_elf64_auxv_union) -> bool { + unsafe { self.a_val == other.a_val + || self.a_ptr == other.a_ptr + || self.a_fcn == other.a_fcn } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_elf64_auxv_union {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_elf64_auxv_union { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("a_val") + .field("a_val", unsafe { &self.a_val }) + .finish() + } + } + #[cfg(not(libc_union))] + impl PartialEq for Elf64_Auxinfo { + fn eq(&self, other: &Elf64_Auxinfo) -> bool { + self.a_type == other.a_type + } + } + #[cfg(libc_union)] + impl PartialEq for Elf64_Auxinfo { + fn eq(&self, other: &Elf64_Auxinfo) -> bool { + self.a_type == other.a_type + && self.a_un == other.a_un + } + } + impl Eq for Elf64_Auxinfo {} + #[cfg(not(libc_union))] + impl ::fmt::Debug for Elf64_Auxinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("Elf64_Auxinfo") + .field("a_type", &self.a_type) + .finish() + } + } + #[cfg(libc_union)] + impl ::fmt::Debug for Elf64_Auxinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("Elf64_Auxinfo") + .field("a_type", &self.a_type) + .field("a_un", &self.a_un) + .finish() + } + } + + impl PartialEq for kinfo_file { + fn eq(&self, other: &kinfo_file) -> bool { + self.kf_structsize == other.kf_structsize && + self.kf_type == other.kf_type && + self.kf_fd == other.kf_fd && + self.kf_ref_count == other.kf_ref_count && + self.kf_flags == other.kf_flags && + self.kf_offset == other.kf_offset && + self.kf_status == other.kf_status && + self.kf_cap_rights == other.kf_cap_rights && + self.kf_path + .iter() + .zip(other.kf_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for kinfo_file {} + impl ::fmt::Debug for kinfo_file { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("kinfo_file") + .field("kf_structsize", &self.kf_structsize) + .field("kf_type", &self.kf_type) + .field("kf_fd", &self.kf_fd) + .field("kf_ref_count", &self.kf_ref_count) + .field("kf_flags", &self.kf_flags) + .field("kf_offset", &self.kf_offset) + .field("kf_status", &self.kf_status) + .field("kf_cap_rights", &self.kf_cap_rights) + .field("kf_path", &&self.kf_path[..]) + .finish() + } + } + impl ::hash::Hash for kinfo_file { + fn hash(&self, state: &mut H) { + self.kf_structsize.hash(state); + self.kf_type.hash(state); + self.kf_fd.hash(state); + self.kf_ref_count.hash(state); + self.kf_flags.hash(state); + self.kf_offset.hash(state); + self.kf_status.hash(state); + self.kf_cap_rights.hash(state); + self.kf_path.hash(state); + } + } + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} +pub const MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 + +pub const _MC_HASSEGS: u32 = 0x1; +pub const _MC_HASBASES: u32 = 0x2; +pub const _MC_HASFPXSTATE: u32 = 0x4; +pub const _MC_FLAG_MASK: u32 = _MC_HASSEGS | _MC_HASBASES | _MC_HASFPXSTATE; + +pub const _MC_FPFMT_NODEV: c_long = 0x10000; +pub const _MC_FPFMT_XMM: c_long = 0x10002; +pub const _MC_FPOWNED_NONE: c_long = 0x20000; +pub const _MC_FPOWNED_FPU: c_long = 0x20001; +pub const _MC_FPOWNED_PCB: c_long = 0x20002; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs new file mode 100644 index 00000000..00a944e4 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs @@ -0,0 +1,1918 @@ +pub type mode_t = u16; +pub type pthread_attr_t = *mut ::c_void; +pub type rlim_t = i64; +pub type pthread_mutex_t = *mut ::c_void; +pub type pthread_mutexattr_t = *mut ::c_void; +pub type pthread_cond_t = *mut ::c_void; +pub type pthread_condattr_t = *mut ::c_void; +pub type pthread_rwlock_t = *mut ::c_void; +pub type pthread_rwlockattr_t = *mut ::c_void; +pub type pthread_key_t = ::c_int; +pub type tcflag_t = ::c_uint; +pub type speed_t = ::c_uint; +pub type nl_item = ::c_int; +pub type id_t = i64; +pub type vm_size_t = ::uintptr_t; +pub type key_t = ::c_long; + +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Lword = u64; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +pub type iconv_t = *mut ::c_void; + +// It's an alias over "struct __kvm_t". However, its fields aren't supposed to be used directly, +// making the type definition system dependent. Better not bind it exactly. +pub type kvm_t = ::c_void; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +// link.h + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.si_status + } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::c_int, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_sourceaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct sigset_t { + bits: [u32; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub si_pid: ::pid_t, + pub si_uid: ::uid_t, + pub si_status: ::c_int, + pub si_addr: *mut ::c_void, + pub si_value: ::sigval, + _pad1: ::c_long, + _pad2: [::c_int; 7], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_int, + pub sa_mask: sigset_t, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_type: ::c_short, + pub l_whence: ::c_short, + #[cfg(not(target_os = "dragonfly"))] + pub l_sysid: ::c_int, + } + + pub struct sf_hdtr { + pub headers: *mut ::iovec, + pub hdr_cnt: ::c_int, + pub trailers: *mut ::iovec, + pub trl_cnt: ::c_int, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct cmsgcred { + pub cmcred_pid: ::pid_t, + pub cmcred_uid: ::uid_t, + pub cmcred_euid: ::uid_t, + pub cmcred_gid: ::gid_t, + pub cmcred_ngroups: ::c_short, + pub cmcred_groups: [::gid_t; CMGROUP_MAX], + } + + pub struct rtprio { + pub type_: ::c_ushort, + pub prio: ::c_ushort, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct timex { + pub modes: ::c_uint, + pub offset: ::c_long, + pub freq: ::c_long, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub status: ::c_int, + pub constant: ::c_long, + pub precision: ::c_long, + pub tolerance: ::c_long, + pub ppsfreq: ::c_long, + pub jitter: ::c_long, + pub shift: ::c_int, + pub stabil: ::c_long, + pub jitcnt: ::c_long, + pub calcnt: ::c_long, + pub errcnt: ::c_long, + pub stbcnt: ::c_long, + } + + pub struct ntptimeval { + pub time: ::timespec, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub time_state: ::c_int, + } + + pub struct accept_filter_arg { + pub af_name: [::c_char; 16], + af_arg: [[::c_char; 10]; 24], + } + + pub struct ptrace_io_desc { + pub piod_op: ::c_int, + pub piod_offs: *mut ::c_void, + pub piod_addr: *mut ::c_void, + pub piod_len: ::size_t, + } + + // bpf.h + + pub struct bpf_program { + pub bf_len: ::c_uint, + pub bf_insns: *mut bpf_insn, + } + + pub struct bpf_stat { + pub bs_recv: ::c_uint, + pub bs_drop: ::c_uint, + } + + pub struct bpf_version { + pub bv_major: ::c_ushort, + pub bv_minor: ::c_ushort, + } + + pub struct bpf_hdr { + pub bh_tstamp: ::timeval, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: ::c_ushort, + } + + pub struct bpf_insn { + pub code: ::c_ushort, + pub jt: ::c_uchar, + pub jf: ::c_uchar, + pub k: u32, + } + + pub struct bpf_dltlist { + bfl_len: ::c_uint, + bfl_list: *mut ::c_uint, + } + + // elf.h + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: usize, + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct ipc_perm { + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mode: ::mode_t, + pub seq: ::c_ushort, + pub key: ::key_t, + } + + pub struct eui64 { + pub octet: [u8; EUI64_LEN], + } +} + +s_no_extra_traits! { + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + } +} + +// Non-public helper constant +cfg_if! { + if #[cfg(all(not(libc_const_size_of), target_pointer_width = "32"))] { + const SIZEOF_LONG: usize = 4; + } else if #[cfg(all(not(libc_const_size_of), target_pointer_width = "64"))] { + const SIZEOF_LONG: usize = 8; + } else if #[cfg(libc_const_size_of)] { + const SIZEOF_LONG: usize = ::mem::size_of::<::c_long>(); + } +} + +#[deprecated( + since = "0.2.64", + note = "Can vary at runtime. Use sysconf(3) instead" +)] +pub const AIO_LISTIO_MAX: ::c_int = 16; +pub const AIO_CANCELED: ::c_int = 1; +pub const AIO_NOTCANCELED: ::c_int = 2; +pub const AIO_ALLDONE: ::c_int = 3; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_READ: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 1; +pub const LIO_NOWAIT: ::c_int = 0; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; +pub const SIGEV_KEVENT: ::c_int = 3; + +pub const CODESET: ::nl_item = 0; +pub const D_T_FMT: ::nl_item = 1; +pub const D_FMT: ::nl_item = 2; +pub const T_FMT: ::nl_item = 3; +pub const T_FMT_AMPM: ::nl_item = 4; +pub const AM_STR: ::nl_item = 5; +pub const PM_STR: ::nl_item = 6; + +pub const DAY_1: ::nl_item = 7; +pub const DAY_2: ::nl_item = 8; +pub const DAY_3: ::nl_item = 9; +pub const DAY_4: ::nl_item = 10; +pub const DAY_5: ::nl_item = 11; +pub const DAY_6: ::nl_item = 12; +pub const DAY_7: ::nl_item = 13; + +pub const ABDAY_1: ::nl_item = 14; +pub const ABDAY_2: ::nl_item = 15; +pub const ABDAY_3: ::nl_item = 16; +pub const ABDAY_4: ::nl_item = 17; +pub const ABDAY_5: ::nl_item = 18; +pub const ABDAY_6: ::nl_item = 19; +pub const ABDAY_7: ::nl_item = 20; + +pub const MON_1: ::nl_item = 21; +pub const MON_2: ::nl_item = 22; +pub const MON_3: ::nl_item = 23; +pub const MON_4: ::nl_item = 24; +pub const MON_5: ::nl_item = 25; +pub const MON_6: ::nl_item = 26; +pub const MON_7: ::nl_item = 27; +pub const MON_8: ::nl_item = 28; +pub const MON_9: ::nl_item = 29; +pub const MON_10: ::nl_item = 30; +pub const MON_11: ::nl_item = 31; +pub const MON_12: ::nl_item = 32; + +pub const ABMON_1: ::nl_item = 33; +pub const ABMON_2: ::nl_item = 34; +pub const ABMON_3: ::nl_item = 35; +pub const ABMON_4: ::nl_item = 36; +pub const ABMON_5: ::nl_item = 37; +pub const ABMON_6: ::nl_item = 38; +pub const ABMON_7: ::nl_item = 39; +pub const ABMON_8: ::nl_item = 40; +pub const ABMON_9: ::nl_item = 41; +pub const ABMON_10: ::nl_item = 42; +pub const ABMON_11: ::nl_item = 43; +pub const ABMON_12: ::nl_item = 44; + +pub const ERA: ::nl_item = 45; +pub const ERA_D_FMT: ::nl_item = 46; +pub const ERA_D_T_FMT: ::nl_item = 47; +pub const ERA_T_FMT: ::nl_item = 48; +pub const ALT_DIGITS: ::nl_item = 49; + +pub const RADIXCHAR: ::nl_item = 50; +pub const THOUSEP: ::nl_item = 51; + +pub const YESEXPR: ::nl_item = 52; +pub const NOEXPR: ::nl_item = 53; + +pub const YESSTR: ::nl_item = 54; +pub const NOSTR: ::nl_item = 55; + +pub const CRNCYSTR: ::nl_item = 56; + +pub const D_MD_ORDER: ::nl_item = 57; + +pub const ALTMON_1: ::nl_item = 58; +pub const ALTMON_2: ::nl_item = 59; +pub const ALTMON_3: ::nl_item = 60; +pub const ALTMON_4: ::nl_item = 61; +pub const ALTMON_5: ::nl_item = 62; +pub const ALTMON_6: ::nl_item = 63; +pub const ALTMON_7: ::nl_item = 64; +pub const ALTMON_8: ::nl_item = 65; +pub const ALTMON_9: ::nl_item = 66; +pub const ALTMON_10: ::nl_item = 67; +pub const ALTMON_11: ::nl_item = 68; +pub const ALTMON_12: ::nl_item = 69; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 308915776; + +pub const O_NOCTTY: ::c_int = 32768; +pub const O_DIRECT: ::c_int = 0x00010000; + +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +pub const S_IFREG: mode_t = 32768; +pub const S_IFLNK: mode_t = 40960; +pub const S_IFSOCK: mode_t = 49152; +pub const S_IFMT: mode_t = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_DUPFD_CLOEXEC: ::c_int = 17; +pub const F_DUP2FD: ::c_int = 10; +pub const F_DUP2FD_CLOEXEC: ::c_int = 18; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_ANON: ::c_int = 0x1000; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const MNT_EXPUBLIC: ::c_int = 0x20000000; +pub const MNT_NOATIME: ::c_int = 0x10000000; +pub const MNT_NOCLUSTERR: ::c_int = 0x40000000; +pub const MNT_NOCLUSTERW: ::c_int = 0x80000000; +pub const MNT_NOSYMFOLLOW: ::c_int = 0x00400000; +pub const MNT_SOFTDEP: ::c_int = 0x00200000; +pub const MNT_SUIDDIR: ::c_int = 0x00100000; +pub const MNT_EXRDONLY: ::c_int = 0x00000080; +pub const MNT_DEFEXPORTED: ::c_int = 0x00000200; +pub const MNT_EXPORTANON: ::c_int = 0x00000400; +pub const MNT_EXKERB: ::c_int = 0x00000800; +pub const MNT_DELEXPORT: ::c_int = 0x00020000; + +pub const MS_SYNC: ::c_int = 0x0000; +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EDEADLK: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EAGAIN: ::c_int = 35; +pub const EWOULDBLOCK: ::c_int = 35; +pub const EINPROGRESS: ::c_int = 36; +pub const EALREADY: ::c_int = 37; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +pub const ESHUTDOWN: ::c_int = 58; +pub const ETOOMANYREFS: ::c_int = 59; +pub const ETIMEDOUT: ::c_int = 60; +pub const ECONNREFUSED: ::c_int = 61; +pub const ELOOP: ::c_int = 62; +pub const ENAMETOOLONG: ::c_int = 63; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const ENOTEMPTY: ::c_int = 66; +pub const EPROCLIM: ::c_int = 67; +pub const EUSERS: ::c_int = 68; +pub const EDQUOT: ::c_int = 69; +pub const ESTALE: ::c_int = 70; +pub const EREMOTE: ::c_int = 71; +pub const EBADRPC: ::c_int = 72; +pub const ERPCMISMATCH: ::c_int = 73; +pub const EPROGUNAVAIL: ::c_int = 74; +pub const EPROGMISMATCH: ::c_int = 75; +pub const EPROCUNAVAIL: ::c_int = 76; +pub const ENOLCK: ::c_int = 77; +pub const ENOSYS: ::c_int = 78; +pub const EFTYPE: ::c_int = 79; +pub const EAUTH: ::c_int = 80; +pub const ENEEDAUTH: ::c_int = 81; +pub const EIDRM: ::c_int = 82; +pub const ENOMSG: ::c_int = 83; +pub const EOVERFLOW: ::c_int = 84; +pub const ECANCELED: ::c_int = 85; +pub const EILSEQ: ::c_int = 86; +pub const ENOATTR: ::c_int = 87; +pub const EDOOFUS: ::c_int = 88; +pub const EBADMSG: ::c_int = 89; +pub const EMULTIHOP: ::c_int = 90; +pub const ENOLINK: ::c_int = 91; +pub const EPROTO: ::c_int = 92; + +pub const POLLSTANDARD: ::c_short = ::POLLIN + | ::POLLPRI + | ::POLLOUT + | ::POLLRDNORM + | ::POLLRDBAND + | ::POLLWRBAND + | ::POLLERR + | ::POLLHUP + | ::POLLNVAL; + +pub const AI_PASSIVE: ::c_int = 0x00000001; +pub const AI_CANONNAME: ::c_int = 0x00000002; +pub const AI_NUMERICHOST: ::c_int = 0x00000004; +pub const AI_NUMERICSERV: ::c_int = 0x00000008; +pub const AI_ALL: ::c_int = 0x00000100; +pub const AI_ADDRCONFIG: ::c_int = 0x00000400; +pub const AI_V4MAPPED: ::c_int = 0x00000800; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 14; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 0x0001; +pub const GLOB_DOOFFS: ::c_int = 0x0002; +pub const GLOB_ERR: ::c_int = 0x0004; +pub const GLOB_MARK: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_NOSORT: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x2000; + +pub const GLOB_NOSPACE: ::c_int = -1; +pub const GLOB_ABORTED: ::c_int = -2; +pub const GLOB_NOMATCH: ::c_int = -3; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_MEMLOCK: ::c_int = 6; +pub const RLIMIT_NPROC: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 8; +pub const RLIMIT_SBSIZE: ::c_int = 9; +pub const RLIMIT_VMEM: ::c_int = 10; +pub const RLIMIT_AS: ::c_int = RLIMIT_VMEM; +pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_VIRTUAL: ::clockid_t = 1; +pub const CLOCK_PROF: ::clockid_t = 2; +pub const CLOCK_MONOTONIC: ::clockid_t = 4; +pub const CLOCK_UPTIME: ::clockid_t = 5; +pub const CLOCK_UPTIME_PRECISE: ::clockid_t = 7; +pub const CLOCK_UPTIME_FAST: ::clockid_t = 8; +pub const CLOCK_REALTIME_PRECISE: ::clockid_t = 9; +pub const CLOCK_REALTIME_FAST: ::clockid_t = 10; +pub const CLOCK_MONOTONIC_PRECISE: ::clockid_t = 11; +pub const CLOCK_MONOTONIC_FAST: ::clockid_t = 12; +pub const CLOCK_SECOND: ::clockid_t = 13; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 14; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 15; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 5; +pub const MADV_NOSYNC: ::c_int = 6; +pub const MADV_AUTOSYNC: ::c_int = 7; +pub const MADV_NOCORE: ::c_int = 8; +pub const MADV_CORE: ::c_int = 9; + +pub const MINCORE_INCORE: ::c_int = 0x1; +pub const MINCORE_REFERENCED: ::c_int = 0x2; +pub const MINCORE_MODIFIED: ::c_int = 0x4; +pub const MINCORE_REFERENCED_OTHER: ::c_int = 0x8; +pub const MINCORE_MODIFIED_OTHER: ::c_int = 0x10; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NETBIOS: ::c_int = 6; +pub const AF_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +pub const AF_ECMA: ::c_int = 8; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +pub const pseudo_AF_RTIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_SIP: ::c_int = 24; +pub const pseudo_AF_PIP: ::c_int = 25; +pub const AF_ISDN: ::c_int = 26; +pub const AF_E164: ::c_int = AF_ISDN; +pub const pseudo_AF_KEY: ::c_int = 27; +pub const AF_INET6: ::c_int = 28; +pub const AF_NATM: ::c_int = 29; +pub const AF_ATM: ::c_int = 30; +pub const pseudo_AF_HDRCMPLT: ::c_int = 31; +pub const AF_NETGRAPH: ::c_int = 32; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = PF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_IMPLINK: ::c_int = AF_IMPLINK; +pub const PF_PUP: ::c_int = AF_PUP; +pub const PF_CHAOS: ::c_int = AF_CHAOS; +pub const PF_NETBIOS: ::c_int = AF_NETBIOS; +pub const PF_ISO: ::c_int = AF_ISO; +pub const PF_OSI: ::c_int = AF_ISO; +pub const PF_ECMA: ::c_int = AF_ECMA; +pub const PF_DATAKIT: ::c_int = AF_DATAKIT; +pub const PF_CCITT: ::c_int = AF_CCITT; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_DLI: ::c_int = AF_DLI; +pub const PF_LAT: ::c_int = AF_LAT; +pub const PF_HYLINK: ::c_int = AF_HYLINK; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_LINK: ::c_int = AF_LINK; +pub const PF_XTP: ::c_int = pseudo_AF_XTP; +pub const PF_COIP: ::c_int = AF_COIP; +pub const PF_CNT: ::c_int = AF_CNT; +pub const PF_SIP: ::c_int = AF_SIP; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_RTIP: ::c_int = pseudo_AF_RTIP; +pub const PF_PIP: ::c_int = pseudo_AF_PIP; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_KEY: ::c_int = pseudo_AF_KEY; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_NATM: ::c_int = AF_NATM; +pub const PF_ATM: ::c_int = AF_ATM; +pub const PF_NETGRAPH: ::c_int = AF_NETGRAPH; + +pub const PIOD_READ_D: ::c_int = 1; +pub const PIOD_WRITE_D: ::c_int = 2; +pub const PIOD_READ_I: ::c_int = 3; +pub const PIOD_WRITE_I: ::c_int = 4; + +pub const PT_TRACE_ME: ::c_int = 0; +pub const PT_READ_I: ::c_int = 1; +pub const PT_READ_D: ::c_int = 2; +pub const PT_WRITE_I: ::c_int = 4; +pub const PT_WRITE_D: ::c_int = 5; +pub const PT_CONTINUE: ::c_int = 7; +pub const PT_KILL: ::c_int = 8; +pub const PT_STEP: ::c_int = 9; +pub const PT_ATTACH: ::c_int = 10; +pub const PT_DETACH: ::c_int = 11; +pub const PT_IO: ::c_int = 12; + +pub const SOMAXCONN: ::c_int = 128; + +pub const MSG_OOB: ::c_int = 0x00000001; +pub const MSG_PEEK: ::c_int = 0x00000002; +pub const MSG_DONTROUTE: ::c_int = 0x00000004; +pub const MSG_EOR: ::c_int = 0x00000008; +pub const MSG_TRUNC: ::c_int = 0x00000010; +pub const MSG_CTRUNC: ::c_int = 0x00000020; +pub const MSG_WAITALL: ::c_int = 0x00000040; +pub const MSG_DONTWAIT: ::c_int = 0x00000080; +pub const MSG_EOF: ::c_int = 0x00000100; + +pub const SCM_TIMESTAMP: ::c_int = 0x02; +pub const SCM_CREDS: ::c_int = 0x03; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_CLOEXEC: ::c_int = 0x10000000; +pub const SOCK_NONBLOCK: ::c_int = 0x20000000; +pub const SOCK_MAXADDRLEN: ::c_int = 255; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_SENDSRCADDR: ::c_int = IP_RECVDSTADDR; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_RECVIF: ::c_int = 20; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; +pub const IPV6_CHECKSUM: ::c_int = 26; +pub const IPV6_RECVPKTINFO: ::c_int = 36; +pub const IPV6_PKTINFO: ::c_int = 46; +pub const IPV6_HOPLIMIT: ::c_int = 47; +pub const IPV6_RECVTCLASS: ::c_int = 57; +pub const IPV6_TCLASS: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 70; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 71; +pub const IP_BLOCK_SOURCE: ::c_int = 72; +pub const IP_UNBLOCK_SOURCE: ::c_int = 73; + +pub const TCP_NOPUSH: ::c_int = 4; +pub const TCP_NOOPT: ::c_int = 8; +pub const TCP_KEEPIDLE: ::c_int = 256; +pub const TCP_KEEPINTVL: ::c_int = 512; +pub const TCP_KEEPCNT: ::c_int = 1024; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x01; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_TIMESTAMP: ::c_int = 0x0400; +pub const SO_NOSIGPIPE: ::c_int = 0x0800; +pub const SO_ACCEPTFILTER: ::c_int = 0x1000; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; + +pub const LOCAL_PEERCRED: ::c_int = 1; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const MAP_COPY: ::c_int = 0x0002; +#[doc(hidden)] +#[deprecated( + since = "0.2.54", + note = "Removed in FreeBSD 11, unused in DragonFlyBSD" +)] +pub const MAP_RENAME: ::c_int = 0x0020; +#[doc(hidden)] +#[deprecated( + since = "0.2.54", + note = "Removed in FreeBSD 11, unused in DragonFlyBSD" +)] +pub const MAP_NORESERVE: ::c_int = 0x0040; +pub const MAP_HASSEMAPHORE: ::c_int = 0x0200; +pub const MAP_STACK: ::c_int = 0x0400; +pub const MAP_NOSYNC: ::c_int = 0x0800; +pub const MAP_NOCORE: ::c_int = 0x020000; + +pub const IPPROTO_RAW: ::c_int = 255; + +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 10; +pub const _PC_FILESIZEBITS: ::c_int = 12; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_SYMLINK_MAX: ::c_int = 18; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 21; +pub const _PC_ASYNC_IO: ::c_int = 53; +pub const _PC_PRIO_IO: ::c_int = 54; +pub const _PC_SYNC_IO: ::c_int = 55; +pub const _PC_ACL_EXTENDED: ::c_int = 59; +pub const _PC_ACL_PATH_MAX: ::c_int = 60; +pub const _PC_CAP_PRESENT: ::c_int = 61; +pub const _PC_INF_PRESENT: ::c_int = 62; +pub const _PC_MAC_PRESENT: ::c_int = 63; + +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_NGROUPS_MAX: ::c_int = 4; +pub const _SC_OPEN_MAX: ::c_int = 5; +pub const _SC_JOB_CONTROL: ::c_int = 6; +pub const _SC_SAVED_IDS: ::c_int = 7; +pub const _SC_VERSION: ::c_int = 8; +pub const _SC_BC_BASE_MAX: ::c_int = 9; +pub const _SC_BC_DIM_MAX: ::c_int = 10; +pub const _SC_BC_SCALE_MAX: ::c_int = 11; +pub const _SC_BC_STRING_MAX: ::c_int = 12; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 13; +pub const _SC_EXPR_NEST_MAX: ::c_int = 14; +pub const _SC_LINE_MAX: ::c_int = 15; +pub const _SC_RE_DUP_MAX: ::c_int = 16; +pub const _SC_2_VERSION: ::c_int = 17; +pub const _SC_2_C_BIND: ::c_int = 18; +pub const _SC_2_C_DEV: ::c_int = 19; +pub const _SC_2_CHAR_TERM: ::c_int = 20; +pub const _SC_2_FORT_DEV: ::c_int = 21; +pub const _SC_2_FORT_RUN: ::c_int = 22; +pub const _SC_2_LOCALEDEF: ::c_int = 23; +pub const _SC_2_SW_DEV: ::c_int = 24; +pub const _SC_2_UPE: ::c_int = 25; +pub const _SC_STREAM_MAX: ::c_int = 26; +pub const _SC_TZNAME_MAX: ::c_int = 27; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 28; +pub const _SC_MAPPED_FILES: ::c_int = 29; +pub const _SC_MEMLOCK: ::c_int = 30; +pub const _SC_MEMLOCK_RANGE: ::c_int = 31; +pub const _SC_MEMORY_PROTECTION: ::c_int = 32; +pub const _SC_MESSAGE_PASSING: ::c_int = 33; +pub const _SC_PRIORITIZED_IO: ::c_int = 34; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 35; +pub const _SC_REALTIME_SIGNALS: ::c_int = 36; +pub const _SC_SEMAPHORES: ::c_int = 37; +pub const _SC_FSYNC: ::c_int = 38; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 39; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 40; +pub const _SC_TIMERS: ::c_int = 41; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 42; +pub const _SC_AIO_MAX: ::c_int = 43; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 44; +pub const _SC_DELAYTIMER_MAX: ::c_int = 45; +pub const _SC_MQ_OPEN_MAX: ::c_int = 46; +pub const _SC_PAGESIZE: ::c_int = 47; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 48; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 49; +pub const _SC_SEM_VALUE_MAX: ::c_int = 50; +pub const _SC_SIGQUEUE_MAX: ::c_int = 51; +pub const _SC_TIMER_MAX: ::c_int = 52; +pub const _SC_IOV_MAX: ::c_int = 56; +pub const _SC_NPROCESSORS_CONF: ::c_int = 57; +pub const _SC_2_PBS: ::c_int = 59; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 60; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 61; +pub const _SC_2_PBS_LOCATE: ::c_int = 62; +pub const _SC_2_PBS_MESSAGE: ::c_int = 63; +pub const _SC_2_PBS_TRACK: ::c_int = 64; +pub const _SC_ADVISORY_INFO: ::c_int = 65; +pub const _SC_BARRIERS: ::c_int = 66; +pub const _SC_CLOCK_SELECTION: ::c_int = 67; +pub const _SC_CPUTIME: ::c_int = 68; +pub const _SC_FILE_LOCKING: ::c_int = 69; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 58; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 70; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 71; +pub const _SC_HOST_NAME_MAX: ::c_int = 72; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 73; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 74; +pub const _SC_MQ_PRIO_MAX: ::c_int = 75; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 76; +pub const _SC_REGEXP: ::c_int = 77; +pub const _SC_SHELL: ::c_int = 78; +pub const _SC_SPAWN: ::c_int = 79; +pub const _SC_SPIN_LOCKS: ::c_int = 80; +pub const _SC_SPORADIC_SERVER: ::c_int = 81; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 82; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 83; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 85; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 86; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 87; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 88; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 89; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 90; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 91; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 92; +pub const _SC_THREAD_STACK_MIN: ::c_int = 93; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 94; +pub const _SC_TIMEOUTS: ::c_int = 95; +pub const _SC_THREADS: ::c_int = 96; +pub const _SC_TRACE: ::c_int = 97; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 98; +pub const _SC_TRACE_INHERIT: ::c_int = 99; +pub const _SC_TRACE_LOG: ::c_int = 100; +pub const _SC_TTY_NAME_MAX: ::c_int = 101; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 102; +pub const _SC_V6_ILP32_OFF32: ::c_int = 103; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 104; +pub const _SC_V6_LP64_OFF64: ::c_int = 105; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 106; +pub const _SC_ATEXIT_MAX: ::c_int = 107; +pub const _SC_XOPEN_CRYPT: ::c_int = 108; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 109; +pub const _SC_XOPEN_LEGACY: ::c_int = 110; +pub const _SC_XOPEN_REALTIME: ::c_int = 111; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 112; +pub const _SC_XOPEN_SHM: ::c_int = 113; +pub const _SC_XOPEN_STREAMS: ::c_int = 114; +pub const _SC_XOPEN_UNIX: ::c_int = 115; +pub const _SC_XOPEN_VERSION: ::c_int = 116; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 117; +pub const _SC_IPV6: ::c_int = 118; +pub const _SC_RAW_SOCKETS: ::c_int = 119; +pub const _SC_SYMLOOP_MAX: ::c_int = 120; +pub const _SC_PHYS_PAGES: ::c_int = 121; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0 as *mut _; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 3; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_ERRORCHECK; + +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_OTHER: ::c_int = 2; +pub const SCHED_RR: ::c_int = 3; + +pub const FD_SETSIZE: usize = 1024; + +pub const ST_NOSUID: ::c_ulong = 2; + +pub const NI_MAXHOST: ::size_t = 1025; + +pub const XUCRED_VERSION: ::c_uint = 0; + +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOLOAD: ::c_int = 0x2000; +pub const RTLD_GLOBAL: ::c_int = 0x100; + +pub const LOG_NTP: ::c_int = 12 << 3; +pub const LOG_SECURITY: ::c_int = 13 << 3; +pub const LOG_CONSOLE: ::c_int = 14 << 3; +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const TIOCEXCL: ::c_ulong = 0x2000740d; +pub const TIOCNXCL: ::c_ulong = 0x2000740e; +pub const TIOCFLUSH: ::c_ulong = 0x80047410; +pub const TIOCGETA: ::c_ulong = 0x402c7413; +pub const TIOCSETA: ::c_ulong = 0x802c7414; +pub const TIOCSETAW: ::c_ulong = 0x802c7415; +pub const TIOCSETAF: ::c_ulong = 0x802c7416; +pub const TIOCGETD: ::c_ulong = 0x4004741a; +pub const TIOCSETD: ::c_ulong = 0x8004741b; +pub const TIOCGDRAINWAIT: ::c_ulong = 0x40047456; +pub const TIOCSDRAINWAIT: ::c_ulong = 0x80047457; +pub const TIOCTIMESTAMP: ::c_ulong = 0x40107459; +pub const TIOCMGDTRWAIT: ::c_ulong = 0x4004745a; +pub const TIOCMSDTRWAIT: ::c_ulong = 0x8004745b; +pub const TIOCDRAIN: ::c_ulong = 0x2000745e; +pub const TIOCEXT: ::c_ulong = 0x80047460; +pub const TIOCSCTTY: ::c_ulong = 0x20007461; +pub const TIOCCONS: ::c_ulong = 0x80047462; +pub const TIOCGSID: ::c_ulong = 0x40047463; +pub const TIOCSTAT: ::c_ulong = 0x20007465; +pub const TIOCUCNTL: ::c_ulong = 0x80047466; +pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +pub const TIOCMGET: ::c_ulong = 0x4004746a; +pub const TIOCM_LE: ::c_int = 0x1; +pub const TIOCM_DTR: ::c_int = 0x2; +pub const TIOCM_RTS: ::c_int = 0x4; +pub const TIOCM_ST: ::c_int = 0x8; +pub const TIOCM_SR: ::c_int = 0x10; +pub const TIOCM_CTS: ::c_int = 0x20; +pub const TIOCM_RI: ::c_int = 0x80; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = 0x40; +pub const TIOCM_CAR: ::c_int = 0x40; +pub const TIOCM_RNG: ::c_int = 0x80; +pub const TIOCMBIC: ::c_ulong = 0x8004746b; +pub const TIOCMBIS: ::c_ulong = 0x8004746c; +pub const TIOCMSET: ::c_ulong = 0x8004746d; +pub const TIOCSTART: ::c_ulong = 0x2000746e; +pub const TIOCSTOP: ::c_ulong = 0x2000746f; +pub const TIOCPKT: ::c_ulong = 0x80047470; +pub const TIOCPKT_DATA: ::c_int = 0x0; +pub const TIOCPKT_FLUSHREAD: ::c_int = 0x1; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 0x2; +pub const TIOCPKT_STOP: ::c_int = 0x4; +pub const TIOCPKT_START: ::c_int = 0x8; +pub const TIOCPKT_NOSTOP: ::c_int = 0x10; +pub const TIOCPKT_DOSTOP: ::c_int = 0x20; +pub const TIOCPKT_IOCTL: ::c_int = 0x40; +pub const TIOCNOTTY: ::c_ulong = 0x20007471; +pub const TIOCSTI: ::c_ulong = 0x80017472; +pub const TIOCOUTQ: ::c_ulong = 0x40047473; +pub const TIOCSPGRP: ::c_ulong = 0x80047476; +pub const TIOCGPGRP: ::c_ulong = 0x40047477; +pub const TIOCCDTR: ::c_ulong = 0x20007478; +pub const TIOCSDTR: ::c_ulong = 0x20007479; +pub const TTYDISC: ::c_int = 0x0; +pub const SLIPDISC: ::c_int = 0x4; +pub const PPPDISC: ::c_int = 0x5; +pub const NETGRAPHDISC: ::c_int = 0x6; + +pub const BIOCGRSIG: ::c_ulong = 0x40044272; +pub const BIOCSRSIG: ::c_ulong = 0x80044273; +pub const BIOCSDLT: ::c_ulong = 0x80044278; +pub const BIOCGSEESENT: ::c_ulong = 0x40044276; +pub const BIOCSSEESENT: ::c_ulong = 0x80044277; +pub const BIOCSETF: ::c_ulong = 0x80104267; +pub const BIOCGDLTLIST: ::c_ulong = 0xc0104279; +pub const BIOCSRTIMEOUT: ::c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; + +pub const FIODTYPE: ::c_ulong = 0x4004667a; +pub const FIOGETLBA: ::c_ulong = 0x40046679; + +pub const B0: speed_t = 0; +pub const B50: speed_t = 50; +pub const B75: speed_t = 75; +pub const B110: speed_t = 110; +pub const B134: speed_t = 134; +pub const B150: speed_t = 150; +pub const B200: speed_t = 200; +pub const B300: speed_t = 300; +pub const B600: speed_t = 600; +pub const B1200: speed_t = 1200; +pub const B1800: speed_t = 1800; +pub const B2400: speed_t = 2400; +pub const B4800: speed_t = 4800; +pub const B9600: speed_t = 9600; +pub const B19200: speed_t = 19200; +pub const B38400: speed_t = 38400; +pub const B7200: speed_t = 7200; +pub const B14400: speed_t = 14400; +pub const B28800: speed_t = 28800; +pub const B57600: speed_t = 57600; +pub const B76800: speed_t = 76800; +pub const B115200: speed_t = 115200; +pub const B230400: speed_t = 230400; +pub const EXTA: speed_t = 19200; +pub const EXTB: speed_t = 38400; + +pub const SEM_FAILED: *mut sem_t = 0 as *mut sem_t; + +pub const CRTSCTS: ::tcflag_t = 0x00030000; +pub const CCTS_OFLOW: ::tcflag_t = 0x00010000; +pub const CRTS_IFLOW: ::tcflag_t = 0x00020000; +pub const CDTR_IFLOW: ::tcflag_t = 0x00040000; +pub const CDSR_OFLOW: ::tcflag_t = 0x00080000; +pub const CCAR_OFLOW: ::tcflag_t = 0x00100000; +pub const VERASE2: usize = 7; +pub const OCRNL: ::tcflag_t = 0x10; +pub const ONOCR: ::tcflag_t = 0x20; +pub const ONLRET: ::tcflag_t = 0x40; + +pub const CMGROUP_MAX: usize = 16; + +pub const EUI64_LEN: usize = 8; + +// https://github.com/freebsd/freebsd/blob/HEAD/sys/net/bpf.h +pub const BPF_ALIGNMENT: usize = SIZEOF_LONG; + +// Values for rtprio struct (prio field) and syscall (function argument) +pub const RTP_PRIO_MIN: ::c_ushort = 0; +pub const RTP_PRIO_MAX: ::c_ushort = 31; +pub const RTP_LOOKUP: ::c_int = 0; +pub const RTP_SET: ::c_int = 1; + +// Flags for chflags(2) +pub const UF_SETTABLE: ::c_ulong = 0x0000ffff; +pub const UF_NODUMP: ::c_ulong = 0x00000001; +pub const UF_IMMUTABLE: ::c_ulong = 0x00000002; +pub const UF_APPEND: ::c_ulong = 0x00000004; +pub const UF_OPAQUE: ::c_ulong = 0x00000008; +pub const UF_NOUNLINK: ::c_ulong = 0x00000010; +pub const SF_SETTABLE: ::c_ulong = 0xffff0000; +pub const SF_ARCHIVED: ::c_ulong = 0x00010000; +pub const SF_IMMUTABLE: ::c_ulong = 0x00020000; +pub const SF_APPEND: ::c_ulong = 0x00040000; +pub const SF_NOUNLINK: ::c_ulong = 0x00100000; + +pub const TIMER_ABSTIME: ::c_int = 1; + +// +pub const NTP_API: ::c_int = 4; +pub const MAXPHASE: ::c_long = 500000000; +pub const MAXFREQ: ::c_long = 500000; +pub const MINSEC: ::c_int = 256; +pub const MAXSEC: ::c_int = 2048; +pub const NANOSECOND: ::c_long = 1000000000; +pub const SCALE_PPM: ::c_int = 65; +pub const MAXTC: ::c_int = 10; +pub const MOD_OFFSET: ::c_uint = 0x0001; +pub const MOD_FREQUENCY: ::c_uint = 0x0002; +pub const MOD_MAXERROR: ::c_uint = 0x0004; +pub const MOD_ESTERROR: ::c_uint = 0x0008; +pub const MOD_STATUS: ::c_uint = 0x0010; +pub const MOD_TIMECONST: ::c_uint = 0x0020; +pub const MOD_PPSMAX: ::c_uint = 0x0040; +pub const MOD_TAI: ::c_uint = 0x0080; +pub const MOD_MICRO: ::c_uint = 0x1000; +pub const MOD_NANO: ::c_uint = 0x2000; +pub const MOD_CLKB: ::c_uint = 0x4000; +pub const MOD_CLKA: ::c_uint = 0x8000; +pub const STA_PLL: ::c_int = 0x0001; +pub const STA_PPSFREQ: ::c_int = 0x0002; +pub const STA_PPSTIME: ::c_int = 0x0004; +pub const STA_FLL: ::c_int = 0x0008; +pub const STA_INS: ::c_int = 0x0010; +pub const STA_DEL: ::c_int = 0x0020; +pub const STA_UNSYNC: ::c_int = 0x0040; +pub const STA_FREQHOLD: ::c_int = 0x0080; +pub const STA_PPSSIGNAL: ::c_int = 0x0100; +pub const STA_PPSJITTER: ::c_int = 0x0200; +pub const STA_PPSWANDER: ::c_int = 0x0400; +pub const STA_PPSERROR: ::c_int = 0x0800; +pub const STA_CLOCKERR: ::c_int = 0x1000; +pub const STA_NANO: ::c_int = 0x2000; +pub const STA_MODE: ::c_int = 0x4000; +pub const STA_CLK: ::c_int = 0x8000; +pub const STA_RONLY: ::c_int = STA_PPSSIGNAL + | STA_PPSJITTER + | STA_PPSWANDER + | STA_PPSERROR + | STA_CLOCKERR + | STA_NANO + | STA_MODE + | STA_CLK; +pub const TIME_OK: ::c_int = 0; +pub const TIME_INS: ::c_int = 1; +pub const TIME_DEL: ::c_int = 2; +pub const TIME_OOP: ::c_int = 3; +pub const TIME_WAIT: ::c_int = 4; +pub const TIME_ERROR: ::c_int = 5; + +pub const REG_ENOSYS: ::c_int = -1; +pub const REG_ILLSEQ: ::c_int = 17; + +pub const IPC_PRIVATE: ::key_t = 0; +pub const IPC_CREAT: ::c_int = 0o1000; +pub const IPC_EXCL: ::c_int = 0o2000; +pub const IPC_NOWAIT: ::c_int = 0o4000; +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; +pub const IPC_R: ::c_int = 0o400; +pub const IPC_W: ::c_int = 0o200; +pub const IPC_M: ::c_int = 0o10000; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; + +pub const KENV_GET: ::c_int = 0; +pub const KENV_SET: ::c_int = 1; +pub const KENV_UNSET: ::c_int = 2; +pub const KENV_DUMP: ::c_int = 3; +pub const KENV_MNAMELEN: ::c_int = 128; +pub const KENV_MVALLEN: ::c_int = 128; + +pub const RB_ASKNAME: ::c_int = 0x001; +pub const RB_SINGLE: ::c_int = 0x002; +pub const RB_NOSYNC: ::c_int = 0x004; +pub const RB_HALT: ::c_int = 0x008; +pub const RB_INITNAME: ::c_int = 0x010; +pub const RB_DFLTROOT: ::c_int = 0x020; +pub const RB_KDB: ::c_int = 0x040; +pub const RB_RDONLY: ::c_int = 0x080; +pub const RB_DUMP: ::c_int = 0x100; +pub const RB_MINIROOT: ::c_int = 0x200; +pub const RB_VERBOSE: ::c_int = 0x800; +pub const RB_SERIAL: ::c_int = 0x1000; +pub const RB_CDROM: ::c_int = 0x2000; +pub const RB_POWEROFF: ::c_int = 0x4000; +pub const RB_GDB: ::c_int = 0x8000; +pub const RB_MUTE: ::c_int = 0x10000; +pub const RB_SELFTEST: ::c_int = 0x20000; + +safe_f! { + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0x13 + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0o177) == 0o177 + } +} + +extern "C" { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn accept4( + s: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn chflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + pub fn chflagsat( + fd: ::c_int, + path: *const ::c_char, + flags: ::c_ulong, + atflag: ::c_int, + ) -> ::c_int; + + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn endutxent(); + pub fn fchflags(fd: ::c_int, flags: ::c_ulong) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrouplist( + name: *const ::c_char, + basegid: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + servlen: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int; + pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; + pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "kevent@FBSD_1.0" + )] + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::c_int, + eventlist: *mut ::kevent, + nevents: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn lchflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "mknodat@FBSD_1.1" + )] + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn malloc_usable_size(ptr: *const ::c_void) -> ::size_t; + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: ::nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn pthread_attr_get_np(tid: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_main_np() -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; + pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const ::pthread_barrierattr_t, + shared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut ::pthread_barrierattr_t, + shared: ::c_int, + ) -> ::c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const ::pthread_barrierattr_t, + count: ::c_uint, + ) -> ::c_int; + pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_get_name_np(tid: ::pthread_t, name: *mut ::c_char, len: ::size_t); + pub fn pthread_set_name_np(tid: ::pthread_t, name: *const ::c_char); + pub fn pthread_getname_np( + thread: ::pthread_t, + buffer: *mut ::c_char, + length: ::size_t, + ) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const sched_param, + ) -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut sched_param, + ) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_char, data: ::c_int) -> ::c_int; + pub fn utrace(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn querylocale(mask: ::c_int, loc: ::locale_t) -> *const ::c_char; + pub fn rtprio(function: ::c_int, pid: ::pid_t, rtp: *mut rtprio) -> ::c_int; + pub fn sched_rr_get_interval(pid: ::pid_t, t: *mut ::timespec) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut sched_param) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const sched_param) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sendfile( + fd: ::c_int, + s: ::c_int, + offset: ::off_t, + nbytes: ::size_t, + hdtr: *mut ::sf_hdtr, + sbytes: *mut ::off_t, + flags: ::c_int, + ) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn setutxent(); + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + pub fn sysctl( + name: *const ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlbyname( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlnametomib( + name: *const ::c_char, + mibp: *mut ::c_int, + sizep: *mut ::size_t, + ) -> ::c_int; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + // #include + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; + + // Added in `FreeBSD` 11.0 + // Added in `DragonFly BSD` 5.4 + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); + // ISO/IEC 9899:2011 ("ISO C11") K.3.7.4.1 + pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; + pub fn gethostid() -> ::c_long; + pub fn sethostid(hostid: ::c_long); + + pub fn eui64_aton(a: *const ::c_char, e: *mut eui64) -> ::c_int; + pub fn eui64_ntoa(id: *const eui64, a: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn eui64_ntohost(hostname: *mut ::c_char, len: ::size_t, id: *const eui64) -> ::c_int; + pub fn eui64_hostton(hostname: *const ::c_char, id: *mut eui64) -> ::c_int; + + pub fn eaccess(path: *const ::c_char, mode: ::c_int) -> ::c_int; + + pub fn kenv( + action: ::c_int, + name: *const ::c_char, + value: *mut ::c_char, + len: ::c_int, + ) -> ::c_int; + pub fn reboot(howto: ::c_int) -> ::c_int; + + pub fn exect( + path: *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn execvP( + file: *const ::c_char, + search_path: *const ::c_char, + argv: *const *mut ::c_char, + ) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_notify(mqd: ::mqd_t, notification: *const ::sigevent) -> ::c_int; + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; +} + +#[link(name = "util")] +extern "C" { + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; + pub fn fparseln( + stream: *mut ::FILE, + len: *mut ::size_t, + lineno: *mut ::size_t, + delim: *const ::c_char, + flags: ::c_int, + ) -> *mut ::c_char; +} + +#[link(name = "execinfo")] +extern "C" { + pub fn backtrace(addrlist: *mut *mut ::c_void, len: ::size_t) -> ::size_t; + pub fn backtrace_symbols(addrlist: *const *mut ::c_void, len: ::size_t) -> *mut *mut ::c_char; + pub fn backtrace_symbols_fd( + addrlist: *const *mut ::c_void, + len: ::size_t, + fd: ::c_int, + ) -> ::c_int; +} + +#[link(name = "kvm")] +extern "C" { + pub fn kvm_open( + execfile: *const ::c_char, + corefile: *const ::c_char, + swapfile: *const ::c_char, + flags: ::c_int, + errstr: *const ::c_char, + ) -> *mut ::kvm_t; + pub fn kvm_close(kd: *mut ::kvm_t) -> ::c_int; + pub fn kvm_getprocs( + kd: *mut ::kvm_t, + op: ::c_int, + arg: ::c_int, + cnt: *mut ::c_int, + ) -> *mut ::kinfo_proc; + pub fn kvm_getloadavg(kd: *mut kvm_t, loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + pub fn kvm_openfiles( + execfile: *const ::c_char, + corefile: *const ::c_char, + swapfile: *const ::c_char, + flags: ::c_int, + errbuf: *mut ::c_char, + ) -> *mut ::kvm_t; + pub fn kvm_read( + kd: *mut ::kvm_t, + addr: ::c_ulong, + buf: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn kvm_write( + kd: *mut ::kvm_t, + addr: ::c_ulong, + buf: *const ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(target_os = "freebsd")] { + mod freebsd; + pub use self::freebsd::*; + } else if #[cfg(target_os = "dragonfly")] { + mod dragonfly; + pub use self::dragonfly::*; + } else { + // ... + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/mod.rs new file mode 100644 index 00000000..9a2e6c46 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/mod.rs @@ -0,0 +1,932 @@ +pub type off_t = i64; +pub type useconds_t = u32; +pub type blkcnt_t = i64; +pub type socklen_t = u32; +pub type sa_family_t = u8; +pub type pthread_t = ::uintptr_t; +pub type nfds_t = ::c_uint; +pub type regoff_t = off_t; + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_change: ::time_t, + pub pw_class: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + pub pw_expire: ::time_t, + + #[cfg(not(any(target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "netbsd", + target_os = "openbsd")))] + pub pw_fields: ::c_int, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut ::c_char, + pub ifa_flags: ::c_uint, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_dstaddr: *mut ::sockaddr, + pub ifa_data: *mut ::c_void, + #[cfg(target_os = "netbsd")] + pub ifa_addrflags: ::c_uint + } + + pub struct fd_set { + #[cfg(all(target_pointer_width = "64", + any(target_os = "freebsd", target_os = "dragonfly")))] + fds_bits: [i64; FD_SETSIZE / 64], + #[cfg(not(all(target_pointer_width = "64", + any(target_os = "freebsd", target_os = "dragonfly"))))] + fds_bits: [i32; FD_SETSIZE / 32], + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_long, + pub tm_zone: *mut ::c_char, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct fsid_t { + __fsid_val: [i32; 2], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct regex_t { + __re_magic: ::c_int, + __re_nsub: ::size_t, + __re_endp: *const ::c_char, + __re_g: *mut ::c_void, + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct option { + pub name: *const ::c_char, + pub has_arg: ::c_int, + pub flag: *mut ::c_int, + pub val: ::c_int, + } +} + +s_no_extra_traits! { + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [c_char; 104] + } + + pub struct utsname { + #[cfg(not(target_os = "dragonfly"))] + pub sysname: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub sysname: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub nodename: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub nodename: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub release: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub release: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub version: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub version: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub machine: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub machine: [::c_char; 32], + } + +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_len == other.sun_len + && self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sockaddr_un {} + + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_len", &self.sun_len) + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_len.hash(state); + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a,b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a,b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a,b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a,b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utsname {} + + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + } +} + +pub const LC_ALL: ::c_int = 0; +pub const LC_COLLATE: ::c_int = 1; +pub const LC_CTYPE: ::c_int = 2; +pub const LC_MONETARY: ::c_int = 3; +pub const LC_NUMERIC: ::c_int = 4; +pub const LC_TIME: ::c_int = 5; +pub const LC_MESSAGES: ::c_int = 6; + +pub const FIOCLEX: ::c_ulong = 0x20006601; +pub const FIONCLEX: ::c_ulong = 0x20006602; +pub const FIONREAD: ::c_ulong = 0x4004667f; +pub const FIONBIO: ::c_ulong = 0x8004667e; +pub const FIOASYNC: ::c_ulong = 0x8004667d; +pub const FIOSETOWN: ::c_ulong = 0x8004667c; +pub const FIOGETOWN: ::c_ulong = 0x4004667b; + +pub const PATH_MAX: ::c_int = 1024; +pub const MAXPATHLEN: ::c_int = PATH_MAX; + +pub const IOV_MAX: ::c_int = 1024; + +pub const SA_ONSTACK: ::c_int = 0x0001; +pub const SA_SIGINFO: ::c_int = 0x0040; +pub const SA_RESTART: ::c_int = 0x0002; +pub const SA_RESETHAND: ::c_int = 0x0004; +pub const SA_NOCLDSTOP: ::c_int = 0x0008; +pub const SA_NODEFER: ::c_int = 0x0010; +pub const SA_NOCLDWAIT: ::c_int = 0x0020; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 4; + +pub const SIGCHLD: ::c_int = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGCONT: ::c_int = 19; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGURG: ::c_int = 16; +pub const SIGIO: ::c_int = 23; +pub const SIGSYS: ::c_int = 12; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGINFO: ::c_int = 29; + +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const IP_TOS: ::c_int = 3; +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; + +pub const IPV6_UNICAST_HOPS: ::c_int = 4; +pub const IPV6_MULTICAST_IF: ::c_int = 9; +pub const IPV6_MULTICAST_HOPS: ::c_int = 10; +pub const IPV6_MULTICAST_LOOP: ::c_int = 11; +pub const IPV6_V6ONLY: ::c_int = 27; + +pub const IPTOS_ECN_NOTECT: u8 = 0x00; +pub const IPTOS_ECN_MASK: u8 = 0x03; +pub const IPTOS_ECN_ECT1: u8 = 0x01; +pub const IPTOS_ECN_ECT0: u8 = 0x02; +pub const IPTOS_ECN_CE: u8 = 0x03; + +pub const ST_RDONLY: ::c_ulong = 1; + +pub const SCM_RIGHTS: ::c_int = 0x01; + +pub const NCCS: usize = 20; + +pub const O_ACCMODE: ::c_int = 0x3; +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 512; +pub const O_TRUNC: ::c_int = 1024; +pub const O_EXCL: ::c_int = 2048; +pub const O_ASYNC: ::c_int = 0x40; +pub const O_SYNC: ::c_int = 0x80; +pub const O_NONBLOCK: ::c_int = 0x4; +pub const O_NOFOLLOW: ::c_int = 0x100; +pub const O_SHLOCK: ::c_int = 0x10; +pub const O_EXLOCK: ::c_int = 0x20; +pub const O_FSYNC: ::c_int = O_SYNC; +pub const O_NDELAY: ::c_int = O_NONBLOCK; + +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; + +pub const F_RDLCK: ::c_short = 1; +pub const F_UNLCK: ::c_short = 2; +pub const F_WRLCK: ::c_short = 3; + +pub const MNT_RDONLY: ::c_int = 0x00000001; +pub const MNT_SYNCHRONOUS: ::c_int = 0x00000002; +pub const MNT_NOEXEC: ::c_int = 0x00000004; +pub const MNT_NOSUID: ::c_int = 0x00000008; +pub const MNT_ASYNC: ::c_int = 0x00000040; +pub const MNT_EXPORTED: ::c_int = 0x00000100; +pub const MNT_UPDATE: ::c_int = 0x00010000; +pub const MNT_RELOAD: ::c_int = 0x00040000; +pub const MNT_FORCE: ::c_int = 0x00080000; + +pub const Q_SYNC: ::c_int = 0x600; +pub const Q_QUOTAON: ::c_int = 0x100; +pub const Q_QUOTAOFF: ::c_int = 0x200; + +pub const TCIOFF: ::c_int = 3; +pub const TCION: ::c_int = 4; +pub const TCOOFF: ::c_int = 1; +pub const TCOON: ::c_int = 2; +pub const TCIFLUSH: ::c_int = 1; +pub const TCOFLUSH: ::c_int = 2; +pub const TCIOFLUSH: ::c_int = 3; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +pub const VEOF: usize = 0; +pub const VEOL: usize = 1; +pub const VEOL2: usize = 2; +pub const VERASE: usize = 3; +pub const VWERASE: usize = 4; +pub const VKILL: usize = 5; +pub const VREPRINT: usize = 6; +pub const VINTR: usize = 8; +pub const VQUIT: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +pub const VSTART: usize = 12; +pub const VSTOP: usize = 13; +pub const VLNEXT: usize = 14; +pub const VDISCARD: usize = 15; +pub const VMIN: usize = 16; +pub const VTIME: usize = 17; +pub const VSTATUS: usize = 18; +pub const _POSIX_VDISABLE: ::cc_t = 0xff; +pub const IGNBRK: ::tcflag_t = 0x00000001; +pub const BRKINT: ::tcflag_t = 0x00000002; +pub const IGNPAR: ::tcflag_t = 0x00000004; +pub const PARMRK: ::tcflag_t = 0x00000008; +pub const INPCK: ::tcflag_t = 0x00000010; +pub const ISTRIP: ::tcflag_t = 0x00000020; +pub const INLCR: ::tcflag_t = 0x00000040; +pub const IGNCR: ::tcflag_t = 0x00000080; +pub const ICRNL: ::tcflag_t = 0x00000100; +pub const IXON: ::tcflag_t = 0x00000200; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const IXANY: ::tcflag_t = 0x00000800; +pub const IMAXBEL: ::tcflag_t = 0x00002000; +pub const OPOST: ::tcflag_t = 0x1; +pub const ONLCR: ::tcflag_t = 0x2; +pub const OXTABS: ::tcflag_t = 0x4; +pub const ONOEOT: ::tcflag_t = 0x8; +pub const CIGNORE: ::tcflag_t = 0x00000001; +pub const CSIZE: ::tcflag_t = 0x00000300; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CS6: ::tcflag_t = 0x00000100; +pub const CS7: ::tcflag_t = 0x00000200; +pub const CS8: ::tcflag_t = 0x00000300; +pub const CSTOPB: ::tcflag_t = 0x00000400; +pub const CREAD: ::tcflag_t = 0x00000800; +pub const PARENB: ::tcflag_t = 0x00001000; +pub const PARODD: ::tcflag_t = 0x00002000; +pub const HUPCL: ::tcflag_t = 0x00004000; +pub const CLOCAL: ::tcflag_t = 0x00008000; +pub const ECHOKE: ::tcflag_t = 0x00000001; +pub const ECHOE: ::tcflag_t = 0x00000002; +pub const ECHOK: ::tcflag_t = 0x00000004; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const ECHONL: ::tcflag_t = 0x00000010; +pub const ECHOPRT: ::tcflag_t = 0x00000020; +pub const ECHOCTL: ::tcflag_t = 0x00000040; +pub const ISIG: ::tcflag_t = 0x00000080; +pub const ICANON: ::tcflag_t = 0x00000100; +pub const ALTWERASE: ::tcflag_t = 0x00000200; +pub const IEXTEN: ::tcflag_t = 0x00000400; +pub const EXTPROC: ::tcflag_t = 0x00000800; +pub const TOSTOP: ::tcflag_t = 0x00400000; +pub const FLUSHO: ::tcflag_t = 0x00800000; +pub const NOKERNINFO: ::tcflag_t = 0x02000000; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const MDMBUF: ::tcflag_t = 0x00100000; + +pub const WNOHANG: ::c_int = 0x00000001; +pub const WUNTRACED: ::c_int = 0x00000002; + +pub const RTLD_LAZY: ::c_int = 0x1; +pub const RTLD_NOW: ::c_int = 0x2; +pub const RTLD_NEXT: *mut ::c_void = -1isize as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; +pub const RTLD_SELF: *mut ::c_void = -3isize as *mut ::c_void; + +pub const LOG_CRON: ::c_int = 9 << 3; +pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +pub const LOG_FTP: ::c_int = 11 << 3; +pub const LOG_PERROR: ::c_int = 0x20; + +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; + +pub const PIPE_BUF: usize = 512; + +// si_code values for SIGBUS signal +pub const BUS_ADRALN: ::c_int = 1; +pub const BUS_ADRERR: ::c_int = 2; +pub const BUS_OBJERR: ::c_int = 3; + +// si_code values for SIGCHLD signal +pub const CLD_EXITED: ::c_int = 1; +pub const CLD_KILLED: ::c_int = 2; +pub const CLD_DUMPED: ::c_int = 3; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLRDBAND: ::c_short = 0x080; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const BIOCGBLEN: ::c_ulong = 0x40044266; +pub const BIOCSBLEN: ::c_ulong = 0xc0044266; +pub const BIOCFLUSH: ::c_uint = 0x20004268; +pub const BIOCPROMISC: ::c_uint = 0x20004269; +pub const BIOCGDLT: ::c_ulong = 0x4004426a; +pub const BIOCGETIF: ::c_ulong = 0x4020426b; +pub const BIOCSETIF: ::c_ulong = 0x8020426c; +pub const BIOCGSTATS: ::c_ulong = 0x4008426f; +pub const BIOCIMMEDIATE: ::c_ulong = 0x80044270; +pub const BIOCVERSION: ::c_ulong = 0x40044271; +pub const BIOCGHDRCMPLT: ::c_ulong = 0x40044274; +pub const BIOCSHDRCMPLT: ::c_ulong = 0x80044275; +pub const SIOCGIFADDR: ::c_ulong = 0xc0206921; + +pub const REG_BASIC: ::c_int = 0o0000; +pub const REG_EXTENDED: ::c_int = 0o0001; +pub const REG_ICASE: ::c_int = 0o0002; +pub const REG_NOSUB: ::c_int = 0o0004; +pub const REG_NEWLINE: ::c_int = 0o0010; +pub const REG_NOSPEC: ::c_int = 0o0020; +pub const REG_PEND: ::c_int = 0o0040; +pub const REG_DUMP: ::c_int = 0o0200; + +pub const REG_NOMATCH: ::c_int = 1; +pub const REG_BADPAT: ::c_int = 2; +pub const REG_ECOLLATE: ::c_int = 3; +pub const REG_ECTYPE: ::c_int = 4; +pub const REG_EESCAPE: ::c_int = 5; +pub const REG_ESUBREG: ::c_int = 6; +pub const REG_EBRACK: ::c_int = 7; +pub const REG_EPAREN: ::c_int = 8; +pub const REG_EBRACE: ::c_int = 9; +pub const REG_BADBR: ::c_int = 10; +pub const REG_ERANGE: ::c_int = 11; +pub const REG_ESPACE: ::c_int = 12; +pub const REG_BADRPT: ::c_int = 13; +pub const REG_EMPTY: ::c_int = 14; +pub const REG_ASSERT: ::c_int = 15; +pub const REG_INVARG: ::c_int = 16; +pub const REG_ATOI: ::c_int = 255; +pub const REG_ITOA: ::c_int = 0o0400; + +pub const REG_NOTBOL: ::c_int = 0o00001; +pub const REG_NOTEOL: ::c_int = 0o00002; +pub const REG_STARTEND: ::c_int = 0o00004; +pub const REG_TRACE: ::c_int = 0o00400; +pub const REG_LARGE: ::c_int = 0o01000; +pub const REG_BACKR: ::c_int = 0o02000; + +pub const TIOCCBRK: ::c_uint = 0x2000747a; +pub const TIOCSBRK: ::c_uint = 0x2000747b; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::<::cmsghdr>() { + (*mhdr).msg_control as *mut ::cmsghdr + } else { + 0 as *mut ::cmsghdr + } + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0o177 + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0o177) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0o200) != 0 + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } +} + +extern "C" { + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getrlimit$UNIX2003" + )] + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setrlimit$UNIX2003" + )] + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), + link_name = "rand@FBSD_1.0" + )] + pub fn rand() -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), + link_name = "srand@FBSD_1.0" + )] + pub fn srand(seed: ::c_uint); + + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + pub fn setlogin(name: *const ::c_char) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn kqueue() -> ::c_int; + pub fn unmount(target: *const ::c_char, arg: ::c_int) -> ::c_int; + pub fn syscall(num: ::c_int, ...) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwent50")] + pub fn getpwent() -> *mut passwd; + pub fn setpwent(); + pub fn endpwent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + + pub fn getprogname() -> *const ::c_char; + pub fn setprogname(name: *const ::c_char); + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn getpeereid(socket: ::c_int, euid: *mut ::uid_t, egid: *mut ::gid_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "glob$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__glob30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "glob@FBSD_1.0" + )] + pub fn glob( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__globfree30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "globfree@FBSD_1.0" + )] + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "seekdir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "seekdir$INODE64$UNIX2003" + )] + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "telldir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "telldir$INODE64$UNIX2003" + )] + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "msync$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__msync13")] + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "recvfrom$UNIX2003" + )] + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__futimes50")] + pub fn futimes(fd: ::c_int, times: *const ::timeval) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "bind$UNIX2003" + )] + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "writev$UNIX2003" + )] + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "readv$UNIX2003" + )] + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sendmsg$UNIX2003" + )] + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "recvmsg$UNIX2003" + )] + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + pub fn sync(); + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sigaltstack$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__sigaltstack14")] + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_sigmask$UNIX2003" + )] + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cancel$UNIX2003" + )] + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwnam_r50")] + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwuid_r50")] + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sigwait$UNIX2003" + )] + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "popen$UNIX2003" + )] + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "wait4$UNIX2003" + )] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), + link_name = "wait4@FBSD_1.0" + )] + pub fn wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getitimer$UNIX2003" + )] + pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setitimer$UNIX2003" + )] + pub fn setitimer( + which: ::c_int, + new_value: *const ::itimerval, + old_value: *mut ::itimerval, + ) -> ::c_int; + + pub fn regcomp(preg: *mut regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; + + pub fn regexec( + preg: *const regex_t, + input: *const ::c_char, + nmatch: ::size_t, + pmatch: *mut regmatch_t, + eflags: ::c_int, + ) -> ::c_int; + + pub fn regerror( + errcode: ::c_int, + preg: *const regex_t, + errbuf: *mut ::c_char, + errbuf_size: ::size_t, + ) -> ::size_t; + + pub fn regfree(preg: *mut regex_t); + + pub fn arc4random() -> u32; + pub fn arc4random_buf(buf: *mut ::c_void, size: ::size_t); + pub fn arc4random_uniform(l: u32) -> u32; + + pub fn drand48() -> ::c_double; + pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; + pub fn lrand48() -> ::c_long; + pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn mrand48() -> ::c_long; + pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn srand48(seed: ::c_long); + pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; + pub fn lcong48(p: *mut ::c_ushort); + pub fn getopt_long( + argc: ::c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut ::c_int, + ) -> ::c_int; + + pub fn strftime( + buf: *mut ::c_char, + maxsize: ::size_t, + format: *const ::c_char, + timeptr: *const ::tm, + ) -> ::size_t; + pub fn strftime_l( + buf: *mut ::c_char, + maxsize: ::size_t, + format: *const ::c_char, + timeptr: *const ::tm, + locale: ::locale_t, + ) -> ::size_t; +} + +cfg_if! { + if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] { + mod apple; + pub use self::apple::*; + } else if #[cfg(any(target_os = "openbsd", target_os = "netbsd"))] { + mod netbsdlike; + pub use self::netbsdlike::*; + } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] { + mod freebsdlike; + pub use self::freebsdlike::*; + } else { + // Unknown target_os + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs new file mode 100644 index 00000000..e92cf659 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs @@ -0,0 +1,863 @@ +pub type wchar_t = i32; +pub type time_t = i64; +pub type mode_t = u32; +pub type nlink_t = u32; +pub type ino_t = u64; +pub type pthread_key_t = ::c_int; +pub type rlim_t = u64; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type nl_item = c_long; +pub type clockid_t = ::c_int; +pub type id_t = u32; +pub type sem_t = *mut sem; +pub type key_t = c_long; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum sem {} +impl ::Copy for sem {} +impl ::Clone for sem { + fn clone(&self) -> sem { + *self + } +} + +s! { + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::c_int, + pub c_ospeed: ::c_int, + } + + pub struct flock { + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_type: ::c_short, + pub l_whence: ::c_short, + } + + pub struct ipc_perm { + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mode: ::mode_t, + #[cfg(target_os = "openbsd")] + pub seq: ::c_ushort, + #[cfg(target_os = "netbsd")] + pub _seq: ::c_ushort, + #[cfg(target_os = "openbsd")] + pub key: ::key_t, + #[cfg(target_os = "netbsd")] + pub _key: ::key_t, + } + + pub struct ptrace_io_desc { + pub piod_op: ::c_int, + pub piod_offs: *mut ::c_void, + pub piod_addr: *mut ::c_void, + pub piod_len: ::size_t, + } +} + +pub const D_T_FMT: ::nl_item = 0; +pub const D_FMT: ::nl_item = 1; +pub const T_FMT: ::nl_item = 2; +pub const T_FMT_AMPM: ::nl_item = 3; +pub const AM_STR: ::nl_item = 4; +pub const PM_STR: ::nl_item = 5; + +pub const DAY_1: ::nl_item = 6; +pub const DAY_2: ::nl_item = 7; +pub const DAY_3: ::nl_item = 8; +pub const DAY_4: ::nl_item = 9; +pub const DAY_5: ::nl_item = 10; +pub const DAY_6: ::nl_item = 11; +pub const DAY_7: ::nl_item = 12; + +pub const ABDAY_1: ::nl_item = 13; +pub const ABDAY_2: ::nl_item = 14; +pub const ABDAY_3: ::nl_item = 15; +pub const ABDAY_4: ::nl_item = 16; +pub const ABDAY_5: ::nl_item = 17; +pub const ABDAY_6: ::nl_item = 18; +pub const ABDAY_7: ::nl_item = 19; + +pub const MON_1: ::nl_item = 20; +pub const MON_2: ::nl_item = 21; +pub const MON_3: ::nl_item = 22; +pub const MON_4: ::nl_item = 23; +pub const MON_5: ::nl_item = 24; +pub const MON_6: ::nl_item = 25; +pub const MON_7: ::nl_item = 26; +pub const MON_8: ::nl_item = 27; +pub const MON_9: ::nl_item = 28; +pub const MON_10: ::nl_item = 29; +pub const MON_11: ::nl_item = 30; +pub const MON_12: ::nl_item = 31; + +pub const ABMON_1: ::nl_item = 32; +pub const ABMON_2: ::nl_item = 33; +pub const ABMON_3: ::nl_item = 34; +pub const ABMON_4: ::nl_item = 35; +pub const ABMON_5: ::nl_item = 36; +pub const ABMON_6: ::nl_item = 37; +pub const ABMON_7: ::nl_item = 38; +pub const ABMON_8: ::nl_item = 39; +pub const ABMON_9: ::nl_item = 40; +pub const ABMON_10: ::nl_item = 41; +pub const ABMON_11: ::nl_item = 42; +pub const ABMON_12: ::nl_item = 43; + +pub const RADIXCHAR: ::nl_item = 44; +pub const THOUSEP: ::nl_item = 45; +pub const YESSTR: ::nl_item = 46; +pub const YESEXPR: ::nl_item = 47; +pub const NOSTR: ::nl_item = 48; +pub const NOEXPR: ::nl_item = 49; +pub const CRNCYSTR: ::nl_item = 50; + +pub const CODESET: ::nl_item = 51; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 1024; +pub const O_NOCTTY: ::c_int = 32768; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +pub const S_IFREG: mode_t = 32768; +pub const S_IFLNK: mode_t = 40960; +pub const S_IFSOCK: mode_t = 49152; +pub const S_IFMT: mode_t = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_ANON: ::c_int = 0x1000; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const IPC_CREAT: ::c_int = 0o001000; +pub const IPC_EXCL: ::c_int = 0o002000; +pub const IPC_NOWAIT: ::c_int = 0o004000; + +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; + +pub const IPC_R: ::c_int = 0o000400; +pub const IPC_W: ::c_int = 0o000200; +pub const IPC_M: ::c_int = 0o010000; + +pub const SHM_R: ::c_int = IPC_R; +pub const SHM_W: ::c_int = IPC_W; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const MS_ASYNC: ::c_int = 0x0001; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EDEADLK: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EAGAIN: ::c_int = 35; +pub const EWOULDBLOCK: ::c_int = 35; +pub const EINPROGRESS: ::c_int = 36; +pub const EALREADY: ::c_int = 37; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +pub const ESHUTDOWN: ::c_int = 58; +pub const ETOOMANYREFS: ::c_int = 59; +pub const ETIMEDOUT: ::c_int = 60; +pub const ECONNREFUSED: ::c_int = 61; +pub const ELOOP: ::c_int = 62; +pub const ENAMETOOLONG: ::c_int = 63; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const ENOTEMPTY: ::c_int = 66; +pub const EPROCLIM: ::c_int = 67; +pub const EUSERS: ::c_int = 68; +pub const EDQUOT: ::c_int = 69; +pub const ESTALE: ::c_int = 70; +pub const EREMOTE: ::c_int = 71; +pub const EBADRPC: ::c_int = 72; +pub const ERPCMISMATCH: ::c_int = 73; +pub const EPROGUNAVAIL: ::c_int = 74; +pub const EPROGMISMATCH: ::c_int = 75; +pub const EPROCUNAVAIL: ::c_int = 76; +pub const ENOLCK: ::c_int = 77; +pub const ENOSYS: ::c_int = 78; +pub const EFTYPE: ::c_int = 79; +pub const EAUTH: ::c_int = 80; +pub const ENEEDAUTH: ::c_int = 81; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 0x0001; +pub const GLOB_DOOFFS: ::c_int = 0x0002; +pub const GLOB_ERR: ::c_int = 0x0004; +pub const GLOB_MARK: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_NOSORT: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x1000; + +pub const GLOB_NOSPACE: ::c_int = -1; +pub const GLOB_ABORTED: ::c_int = -2; +pub const GLOB_NOMATCH: ::c_int = -3; +pub const GLOB_NOSYS: ::c_int = -4; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; +pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x04; +pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x08; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x10; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const PIOD_READ_D: ::c_int = 1; +pub const PIOD_WRITE_D: ::c_int = 2; +pub const PIOD_READ_I: ::c_int = 3; +pub const PIOD_WRITE_I: ::c_int = 4; +pub const PIOD_READ_AUXV: ::c_int = 5; + +pub const PT_TRACE_ME: ::c_int = 0; +pub const PT_READ_I: ::c_int = 1; +pub const PT_READ_D: ::c_int = 2; +pub const PT_WRITE_I: ::c_int = 4; +pub const PT_WRITE_D: ::c_int = 5; +pub const PT_CONTINUE: ::c_int = 7; +pub const PT_KILL: ::c_int = 8; +pub const PT_ATTACH: ::c_int = 9; +pub const PT_DETACH: ::c_int = 10; +pub const PT_IO: ::c_int = 11; + +// http://man.openbsd.org/OpenBSD-current/man2/clock_getres.2 +// The man page says clock_gettime(3) can accept various values as clockid_t but +// http://fxr.watson.org/fxr/source/kern/kern_time.c?v=OPENBSD;im=excerpts#L161 +// the implementation rejects anything other than the below two +// +// http://netbsd.gw.com/cgi-bin/man-cgi?clock_gettime +// https://github.com/jsonn/src/blob/HEAD/sys/kern/subr_time.c#L222 +// Basically the same goes for NetBSD +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 3; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_MEMLOCK: ::c_int = 6; +pub const RLIMIT_NPROC: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 8; + +pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; +pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 6; + +// sys/fstypes.h in NetBSD, or sys/mount.h in OpenBSD +pub const MNT_NODEV: ::c_int = 0x00000010; +pub const MNT_LOCAL: ::c_int = 0x00001000; +pub const MNT_QUOTA: ::c_int = 0x00002000; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NS: ::c_int = 6; +pub const AF_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_LINK: ::c_int = 18; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +pub const pseudo_AF_RTIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_INET6: ::c_int = 24; +pub const pseudo_AF_PIP: ::c_int = 25; +pub const AF_ISDN: ::c_int = 26; +pub const AF_E164: ::c_int = AF_ISDN; +pub const AF_NATM: ::c_int = 27; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = PF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_IMPLINK: ::c_int = AF_IMPLINK; +pub const PF_PUP: ::c_int = AF_PUP; +pub const PF_CHAOS: ::c_int = AF_CHAOS; +pub const PF_NS: ::c_int = AF_NS; +pub const PF_ISO: ::c_int = AF_ISO; +pub const PF_OSI: ::c_int = AF_ISO; +pub const PF_DATAKIT: ::c_int = AF_DATAKIT; +pub const PF_CCITT: ::c_int = AF_CCITT; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_DLI: ::c_int = AF_DLI; +pub const PF_LAT: ::c_int = AF_LAT; +pub const PF_HYLINK: ::c_int = AF_HYLINK; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_LINK: ::c_int = AF_LINK; +pub const PF_XTP: ::c_int = pseudo_AF_XTP; +pub const PF_COIP: ::c_int = AF_COIP; +pub const PF_CNT: ::c_int = AF_CNT; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_RTIP: ::c_int = pseudo_AF_RTIP; +pub const PF_PIP: ::c_int = pseudo_AF_PIP; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_NATM: ::c_int = AF_NATM; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IPV6_RECVPKTINFO: ::c_int = 36; +pub const IPV6_PKTINFO: ::c_int = 46; +pub const IPV6_RECVTCLASS: ::c_int = 57; +pub const IPV6_TCLASS: ::c_int = 61; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x01; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; + +pub const SOMAXCONN: ::c_int = 128; + +pub const MSG_OOB: ::c_int = 0x1; +pub const MSG_PEEK: ::c_int = 0x2; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_EOR: ::c_int = 0x8; +pub const MSG_TRUNC: ::c_int = 0x10; +pub const MSG_CTRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_DONTWAIT: ::c_int = 0x80; +pub const MSG_BCAST: ::c_int = 0x100; +pub const MSG_MCAST: ::c_int = 0x200; +pub const MSG_NOSIGNAL: ::c_int = 0x400; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x800; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const IPPROTO_RAW: ::c_int = 255; + +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 4; +pub const _SC_OPEN_MAX: ::c_int = 5; +pub const _SC_JOB_CONTROL: ::c_int = 6; +pub const _SC_SAVED_IDS: ::c_int = 7; +pub const _SC_VERSION: ::c_int = 8; +pub const _SC_BC_BASE_MAX: ::c_int = 9; +pub const _SC_BC_DIM_MAX: ::c_int = 10; +pub const _SC_BC_SCALE_MAX: ::c_int = 11; +pub const _SC_BC_STRING_MAX: ::c_int = 12; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 13; +pub const _SC_EXPR_NEST_MAX: ::c_int = 14; +pub const _SC_LINE_MAX: ::c_int = 15; +pub const _SC_RE_DUP_MAX: ::c_int = 16; +pub const _SC_2_VERSION: ::c_int = 17; +pub const _SC_2_C_BIND: ::c_int = 18; +pub const _SC_2_C_DEV: ::c_int = 19; +pub const _SC_2_CHAR_TERM: ::c_int = 20; +pub const _SC_2_FORT_DEV: ::c_int = 21; +pub const _SC_2_FORT_RUN: ::c_int = 22; +pub const _SC_2_LOCALEDEF: ::c_int = 23; +pub const _SC_2_SW_DEV: ::c_int = 24; +pub const _SC_2_UPE: ::c_int = 25; +pub const _SC_STREAM_MAX: ::c_int = 26; +pub const _SC_TZNAME_MAX: ::c_int = 27; +pub const _SC_PAGESIZE: ::c_int = 28; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_FSYNC: ::c_int = 29; +pub const _SC_XOPEN_SHM: ::c_int = 30; + +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQUOTA: ::c_int = 0x400; + +pub const RTLD_GLOBAL: ::c_int = 0x100; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const HW_NCPU: ::c_int = 3; + +pub const B0: speed_t = 0; +pub const B50: speed_t = 50; +pub const B75: speed_t = 75; +pub const B110: speed_t = 110; +pub const B134: speed_t = 134; +pub const B150: speed_t = 150; +pub const B200: speed_t = 200; +pub const B300: speed_t = 300; +pub const B600: speed_t = 600; +pub const B1200: speed_t = 1200; +pub const B1800: speed_t = 1800; +pub const B2400: speed_t = 2400; +pub const B4800: speed_t = 4800; +pub const B9600: speed_t = 9600; +pub const B19200: speed_t = 19200; +pub const B38400: speed_t = 38400; +pub const B7200: speed_t = 7200; +pub const B14400: speed_t = 14400; +pub const B28800: speed_t = 28800; +pub const B57600: speed_t = 57600; +pub const B76800: speed_t = 76800; +pub const B115200: speed_t = 115200; +pub const B230400: speed_t = 230400; +pub const EXTA: speed_t = 19200; +pub const EXTB: speed_t = 38400; + +pub const SEM_FAILED: *mut sem_t = 0 as *mut sem_t; + +pub const CRTSCTS: ::tcflag_t = 0x00010000; +pub const CRTS_IFLOW: ::tcflag_t = CRTSCTS; +pub const CCTS_OFLOW: ::tcflag_t = CRTSCTS; +pub const OCRNL: ::tcflag_t = 0x10; + +pub const TIOCEXCL: ::c_ulong = 0x2000740d; +pub const TIOCNXCL: ::c_ulong = 0x2000740e; +pub const TIOCFLUSH: ::c_ulong = 0x80047410; +pub const TIOCGETA: ::c_ulong = 0x402c7413; +pub const TIOCSETA: ::c_ulong = 0x802c7414; +pub const TIOCSETAW: ::c_ulong = 0x802c7415; +pub const TIOCSETAF: ::c_ulong = 0x802c7416; +pub const TIOCGETD: ::c_ulong = 0x4004741a; +pub const TIOCSETD: ::c_ulong = 0x8004741b; +pub const TIOCMGET: ::c_ulong = 0x4004746a; +pub const TIOCMBIC: ::c_ulong = 0x8004746b; +pub const TIOCMBIS: ::c_ulong = 0x8004746c; +pub const TIOCMSET: ::c_ulong = 0x8004746d; +pub const TIOCSTART: ::c_ulong = 0x2000746e; +pub const TIOCSTOP: ::c_ulong = 0x2000746f; +pub const TIOCSCTTY: ::c_ulong = 0x20007461; +pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +pub const TIOCM_LE: ::c_int = 0o0001; +pub const TIOCM_DTR: ::c_int = 0o0002; +pub const TIOCM_RTS: ::c_int = 0o0004; +pub const TIOCM_ST: ::c_int = 0o0010; +pub const TIOCM_SR: ::c_int = 0o0020; +pub const TIOCM_CTS: ::c_int = 0o0040; +pub const TIOCM_CAR: ::c_int = 0o0100; +pub const TIOCM_RNG: ::c_int = 0o0200; +pub const TIOCM_DSR: ::c_int = 0o0400; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +pub const TIMER_ABSTIME: ::c_int = 1; + +// sys/reboot.h + +pub const RB_AUTOBOOT: ::c_int = 0; + +pub const TCP_INFO: ::c_int = 9; + +#[link(name = "util")] +extern "C" { + pub fn setgrent(); + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn accept4( + s: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn mincore(addr: *mut ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_getres50")] + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")] + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_settime50")] + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn __errno() -> *mut ::c_int; + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn login_tty(fd: ::c_int) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const sched_param, + ) -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut sched_param, + ) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + + pub fn getgrouplist( + name: *const ::c_char, + basegid: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn waitid( + idtype: idtype_t, + id: ::id_t, + infop: *mut ::siginfo_t, + options: ::c_int, + ) -> ::c_int; + + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + flags: *mut ::c_int, + ) -> ::c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; +} + +extern "C" { + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn gethostid() -> ::c_long; + pub fn sethostid(hostid: ::c_long) -> ::c_int; + pub fn ftok(path: *const ::c_char, id: ::c_int) -> ::key_t; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_os = "netbsd")] { + mod netbsd; + pub use self::netbsd::*; + } else if #[cfg(target_os = "openbsd")] { + mod openbsd; + pub use self::openbsd::*; + } else { + // Unknown target_os + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs new file mode 100644 index 00000000..45bca477 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs @@ -0,0 +1,162 @@ +use PT_FIRSTMACH; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type greg_t = u64; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +s! { + pub struct __fregset { + #[cfg(libc_union)] + pub __qregs: [__c_anonymous__freg; 32], + pub __fpcr: u32, + pub __fpsr: u32, + } + + pub struct mcontext_t { + pub __gregs: [::greg_t; 32], + pub __fregs: __fregset, + __spare: [::greg_t; 8], + } + + pub struct ucontext_t { + pub uc_flags: ::c_uint, + pub uc_link: *mut ucontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + } +} + +s_no_extra_traits! { + #[cfg(libc_union)] + #[repr(align(16))] + pub union __c_anonymous__freg { + pub __b8: [u8; 16], + pub __h16: [u16; 8], + pub __s32: [u32; 4], + pub __d64: [u64; 2], + pub __q128: [u128; 1], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[cfg(libc_union)] + impl PartialEq for __c_anonymous__freg { + fn eq(&self, other: &__c_anonymous__freg) -> bool { + unsafe { + self.__b8 == other.__b8 + || self.__h16 == other.__h16 + || self.__s32 == other.__s32 + || self.__d64 == other.__d64 + || self.__q128 == other.__q128 + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous__freg {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous__freg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous__freg") + .field("__b8", &self.__b8) + .field("__h16", &self.__h16) + .field("__s32", &self.__s32) + .field("__d64", &self.__d64) + .field("__q128", &self.__q128) + .finish() + } + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous__freg { + fn hash(&self, state: &mut H) { + unsafe { + self.__b8.hash(state); + self.__h16.hash(state); + self.__s32.hash(state); + self.__d64.hash(state); + self.__q128.hash(state); + } + } + } + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 3; + +pub const _REG_R0: ::c_int = 0; +pub const _REG_R1: ::c_int = 1; +pub const _REG_R2: ::c_int = 2; +pub const _REG_R3: ::c_int = 3; +pub const _REG_R4: ::c_int = 4; +pub const _REG_R5: ::c_int = 5; +pub const _REG_R6: ::c_int = 6; +pub const _REG_R7: ::c_int = 7; +pub const _REG_R8: ::c_int = 8; +pub const _REG_R9: ::c_int = 9; +pub const _REG_R10: ::c_int = 10; +pub const _REG_R11: ::c_int = 11; +pub const _REG_R12: ::c_int = 12; +pub const _REG_R13: ::c_int = 13; +pub const _REG_R14: ::c_int = 14; +pub const _REG_R15: ::c_int = 15; +pub const _REG_CPSR: ::c_int = 16; +pub const _REG_X0: ::c_int = 0; +pub const _REG_X1: ::c_int = 1; +pub const _REG_X2: ::c_int = 2; +pub const _REG_X3: ::c_int = 3; +pub const _REG_X4: ::c_int = 4; +pub const _REG_X5: ::c_int = 5; +pub const _REG_X6: ::c_int = 6; +pub const _REG_X7: ::c_int = 7; +pub const _REG_X8: ::c_int = 8; +pub const _REG_X9: ::c_int = 9; +pub const _REG_X10: ::c_int = 10; +pub const _REG_X11: ::c_int = 11; +pub const _REG_X12: ::c_int = 12; +pub const _REG_X13: ::c_int = 13; +pub const _REG_X14: ::c_int = 14; +pub const _REG_X15: ::c_int = 15; +pub const _REG_X16: ::c_int = 16; +pub const _REG_X17: ::c_int = 17; +pub const _REG_X18: ::c_int = 18; +pub const _REG_X19: ::c_int = 19; +pub const _REG_X20: ::c_int = 20; +pub const _REG_X21: ::c_int = 21; +pub const _REG_X22: ::c_int = 22; +pub const _REG_X23: ::c_int = 23; +pub const _REG_X24: ::c_int = 24; +pub const _REG_X25: ::c_int = 25; +pub const _REG_X26: ::c_int = 26; +pub const _REG_X27: ::c_int = 27; +pub const _REG_X28: ::c_int = 28; +pub const _REG_X29: ::c_int = 29; +pub const _REG_X30: ::c_int = 30; +pub const _REG_X31: ::c_int = 31; +pub const _REG_ELR: ::c_int = 32; +pub const _REG_SPSR: ::c_int = 33; +pub const _REG_TIPDR: ::c_int = 34; + +pub const _REG_RV: ::c_int = _REG_X0; +pub const _REG_FP: ::c_int = _REG_X29; +pub const _REG_LR: ::c_int = _REG_X30; +pub const _REG_SP: ::c_int = _REG_X31; +pub const _REG_PC: ::c_int = _REG_ELR; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs new file mode 100644 index 00000000..b5000d34 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs @@ -0,0 +1,81 @@ +use PT_FIRSTMACH; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = u8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; + +pub const _REG_R0: ::c_int = 0; +pub const _REG_R1: ::c_int = 1; +pub const _REG_R2: ::c_int = 2; +pub const _REG_R3: ::c_int = 3; +pub const _REG_R4: ::c_int = 4; +pub const _REG_R5: ::c_int = 5; +pub const _REG_R6: ::c_int = 6; +pub const _REG_R7: ::c_int = 7; +pub const _REG_R8: ::c_int = 8; +pub const _REG_R9: ::c_int = 9; +pub const _REG_R10: ::c_int = 10; +pub const _REG_R11: ::c_int = 11; +pub const _REG_R12: ::c_int = 12; +pub const _REG_R13: ::c_int = 13; +pub const _REG_R14: ::c_int = 14; +pub const _REG_R15: ::c_int = 15; +pub const _REG_CPSR: ::c_int = 16; +pub const _REG_X0: ::c_int = 0; +pub const _REG_X1: ::c_int = 1; +pub const _REG_X2: ::c_int = 2; +pub const _REG_X3: ::c_int = 3; +pub const _REG_X4: ::c_int = 4; +pub const _REG_X5: ::c_int = 5; +pub const _REG_X6: ::c_int = 6; +pub const _REG_X7: ::c_int = 7; +pub const _REG_X8: ::c_int = 8; +pub const _REG_X9: ::c_int = 9; +pub const _REG_X10: ::c_int = 10; +pub const _REG_X11: ::c_int = 11; +pub const _REG_X12: ::c_int = 12; +pub const _REG_X13: ::c_int = 13; +pub const _REG_X14: ::c_int = 14; +pub const _REG_X15: ::c_int = 15; +pub const _REG_X16: ::c_int = 16; +pub const _REG_X17: ::c_int = 17; +pub const _REG_X18: ::c_int = 18; +pub const _REG_X19: ::c_int = 19; +pub const _REG_X20: ::c_int = 20; +pub const _REG_X21: ::c_int = 21; +pub const _REG_X22: ::c_int = 22; +pub const _REG_X23: ::c_int = 23; +pub const _REG_X24: ::c_int = 24; +pub const _REG_X25: ::c_int = 25; +pub const _REG_X26: ::c_int = 26; +pub const _REG_X27: ::c_int = 27; +pub const _REG_X28: ::c_int = 28; +pub const _REG_X29: ::c_int = 29; +pub const _REG_X30: ::c_int = 30; +pub const _REG_X31: ::c_int = 31; +pub const _REG_ELR: ::c_int = 32; +pub const _REG_SPSR: ::c_int = 33; +pub const _REG_TIPDR: ::c_int = 34; + +pub const _REG_RV: ::c_int = _REG_R0; +pub const _REG_FP: ::c_int = _REG_R11; +pub const _REG_LR: ::c_int = _REG_R13; +pub const _REG_SP: ::c_int = _REG_R14; +pub const _REG_PC: ::c_int = _REG_R15; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs new file mode 100644 index 00000000..a536254c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs @@ -0,0 +1,21 @@ +use PT_FIRSTMACH; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = i8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs new file mode 100644 index 00000000..7c63db8e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -0,0 +1,3148 @@ +pub type clock_t = ::c_uint; +pub type suseconds_t = ::c_int; +pub type dev_t = u64; +pub type blksize_t = i32; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type idtype_t = ::c_int; +pub type mqd_t = ::c_int; +type __pthread_spin_t = __cpu_simple_lock_nv_t; +pub type vm_size_t = ::uintptr_t; // FIXME: deprecated since long time +pub type lwpid_t = ::c_uint; +pub type shmatt_t = ::c_uint; +pub type cpuid_t = ::c_ulong; +pub type cpuset_t = _cpuset; +pub type pthread_spin_t = ::c_uchar; +pub type timer_t = ::c_int; + +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Lword = u64; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +pub type iconv_t = *mut ::c_void; + +e! { + pub enum fae_action { + FAE_OPEN, + FAE_DUP2, + FAE_CLOSE, + } +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_code(&self) -> ::c_int { + self.si_code + } + + pub unsafe fn si_errno(&self) -> ::c_int { + self.si_errno + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + __pad1: ::c_int, + _pid: ::pid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + __pad1: ::c_int, + _pid: ::pid_t, + _uid: ::uid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._uid + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + __pad1: ::c_int, + _pid: ::pid_t, + _uid: ::uid_t, + value: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).value + } + + pub unsafe fn si_status(&self) -> ::c_int { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + __pad1: ::c_int, + _pid: ::pid_t, + _uid: ::uid_t, + _value: ::sigval, + _cpid: ::pid_t, + _cuid: ::uid_t, + status: ::c_int, + } + (*(self as *const siginfo_t as *const siginfo_timer)).status + } +} + +s! { + pub struct aiocb { + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_sigevent: ::sigevent, + _state: ::c_int, + _errno: ::c_int, + _retval: ::ssize_t + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + + __unused3: *mut ::c_void, + + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct sigset_t { + __bits: [u32; 4], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_mode: ::mode_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atimensec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtimensec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctimensec: ::c_long, + pub st_birthtime: ::time_t, + pub st_birthtimensec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: u32, + pub st_gen: u32, + pub st_spare: [u32; 2], + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut ::addrinfo, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + __pad1: ::c_int, + pub si_addr: *mut ::c_void, + __pad2: [u64; 13], + } + + pub struct pthread_attr_t { + pta_magic: ::c_uint, + pta_flags: ::c_int, + pta_private: *mut ::c_void, + } + + pub struct pthread_mutex_t { + ptm_magic: ::c_uint, + ptm_errorcheck: __pthread_spin_t, + #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] + ptm_pad1: [u8; 3], + // actually a union with a non-unused, 0-initialized field + ptm_unused: __pthread_spin_t, + #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] + ptm_pad2: [u8; 3], + ptm_owner: ::pthread_t, + ptm_waiters: *mut u8, + ptm_recursed: ::c_uint, + ptm_spare2: *mut ::c_void, + } + + pub struct pthread_mutexattr_t { + ptma_magic: ::c_uint, + ptma_private: *mut ::c_void, + } + + pub struct pthread_rwlockattr_t { + ptra_magic: ::c_uint, + ptra_private: *mut ::c_void, + } + + pub struct pthread_cond_t { + ptc_magic: ::c_uint, + ptc_lock: __pthread_spin_t, + ptc_waiters_first: *mut u8, + ptc_waiters_last: *mut u8, + ptc_mutex: *mut ::pthread_mutex_t, + ptc_private: *mut ::c_void, + } + + pub struct pthread_condattr_t { + ptca_magic: ::c_uint, + ptca_private: *mut ::c_void, + } + + pub struct pthread_rwlock_t { + ptr_magic: ::c_uint, + ptr_interlock: __pthread_spin_t, + ptr_rblocked_first: *mut u8, + ptr_rblocked_last: *mut u8, + ptr_wblocked_first: *mut u8, + ptr_wblocked_last: *mut u8, + ptr_nreaders: ::c_uint, + ptr_owner: ::pthread_t, + ptr_private: *mut ::c_void, + } + + pub struct pthread_spinlock_t { + pts_magic: ::c_uint, + pts_spin: ::pthread_spin_t, + pts_flags: ::c_int, + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: u32, + pub flags: u32, + pub fflags: u32, + pub data: i64, + pub udata: ::intptr_t, /* FIXME: NetBSD 10.0 will finally have same layout as other BSD */ + } + + pub struct dqblk { + pub dqb_bhardlimit: u32, + pub dqb_bsoftlimit: u32, + pub dqb_curblocks: u32, + pub dqb_ihardlimit: u32, + pub dqb_isoftlimit: u32, + pub dqb_curinodes: u32, + pub dqb_btime: i32, + pub dqb_itime: i32, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *const ::c_void, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct if_data { + pub ifi_type: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_link_state: ::c_int, + pub ifi_mtu: u64, + pub ifi_metric: u64, + pub ifi_baudrate: u64, + pub ifi_ipackets: u64, + pub ifi_ierrors: u64, + pub ifi_opackets: u64, + pub ifi_oerrors: u64, + pub ifi_collisions: u64, + pub ifi_ibytes: u64, + pub ifi_obytes: u64, + pub ifi_imcasts: u64, + pub ifi_omcasts: u64, + pub ifi_iqdrops: u64, + pub ifi_noproto: u64, + pub ifi_lastchange: ::timespec, + } + + pub struct if_msghdr { + pub ifm_msglen: ::c_ushort, + pub ifm_version: ::c_uchar, + pub ifm_type: ::c_uchar, + pub ifm_addrs: ::c_int, + pub ifm_flags: ::c_int, + pub ifm_index: ::c_ushort, + pub ifm_data: if_data, + } + + pub struct sockcred { + pub sc_pid: ::pid_t, + pub sc_uid: ::uid_t, + pub sc_euid: ::uid_t, + pub sc_gid: ::gid_t, + pub sc_egid: ::gid_t, + pub sc_ngroups: ::c_int, + pub sc_groups: [::gid_t; 1], + } + + pub struct uucred { + pub cr_unused: ::c_ushort, + pub cr_uid: ::uid_t, + pub cr_gid: ::gid_t, + pub cr_ngroups: ::c_int, + pub cr_groups: [::gid_t; NGROUPS_MAX as usize], + } + + pub struct unpcbid { + pub unp_pid: ::pid_t, + pub unp_euid: ::uid_t, + pub unp_egid: ::gid_t, + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: u8, + pub sdl_nlen: u8, + pub sdl_alen: u8, + pub sdl_slen: u8, + pub sdl_data: [::c_char; 12], + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + pub struct __exit_status { + pub e_termination: u16, + pub e_exit: u16, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + _shm_internal: *mut ::c_void, + } + + pub struct utmp { + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_name: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_time: ::time_t + } + + pub struct lastlog { + pub ll_line: [::c_char; UT_LINESIZE], + pub ll_host: [::c_char; UT_HOSTSIZE], + pub ll_time: ::time_t + } + + pub struct timex { + pub modes: ::c_uint, + pub offset: ::c_long, + pub freq: ::c_long, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub status: ::c_int, + pub constant: ::c_long, + pub precision: ::c_long, + pub tolerance: ::c_long, + pub ppsfreq: ::c_long, + pub jitter: ::c_long, + pub shift: ::c_int, + pub stabil: ::c_long, + pub jitcnt: ::c_long, + pub calcnt: ::c_long, + pub errcnt: ::c_long, + pub stbcnt: ::c_long, + } + + pub struct ntptimeval { + pub time: ::timespec, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub time_state: ::c_int, + } + + // elf.h + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + pub struct Aux32Info { + pub a_type: Elf32_Word, + pub a_v: Elf32_Word, + } + + pub struct Aux64Info { + pub a_type: Elf64_Word, + pub a_v: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: usize, + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct _cpuset { + bits: [u32; 0] + } + + pub struct accept_filter_arg { + pub af_name: [::c_char; 16], + af_arg: [[::c_char; 10]; 24], + } + + pub struct ki_sigset_t { + pub __bits: [u32; 4], + } + + pub struct kinfo_proc2 { + pub p_forw: u64, + pub p_back: u64, + pub p_paddr: u64, + pub p_addr: u64, + pub p_fd: u64, + pub p_cwdi: u64, + pub p_stats: u64, + pub p_limit: u64, + pub p_vmspace: u64, + pub p_sigacts: u64, + pub p_sess: u64, + pub p_tsess: u64, + pub p_ru: u64, + pub p_eflag: i32, + pub p_exitsig: i32, + pub p_flag: i32, + pub p_pid: i32, + pub p_ppid: i32, + pub p_sid: i32, + pub p__pgid: i32, + pub p_tpgid: i32, + pub p_uid: u32, + pub p_ruid: u32, + pub p_gid: u32, + pub p_rgid: u32, + pub p_groups: [u32; KI_NGROUPS as usize], + pub p_ngroups: i16, + pub p_jobc: i16, + pub p_tdev: u32, + pub p_estcpu: u32, + pub p_rtime_sec: u32, + pub p_rtime_usec: u32, + pub p_cpticks: i32, + pub p_pctcpu: u32, + pub p_swtime: u32, + pub p_slptime: u32, + pub p_schedflags: i32, + pub p_uticks: u64, + pub p_sticks: u64, + pub p_iticks: u64, + pub p_tracep: u64, + pub p_traceflag: i32, + pub p_holdcnt: i32, + pub p_siglist: ki_sigset_t, + pub p_sigmask: ki_sigset_t, + pub p_sigignore: ki_sigset_t, + pub p_sigcatch: ki_sigset_t, + pub p_stat: i8, + pub p_priority: u8, + pub p_usrpri: u8, + pub p_nice: u8, + pub p_xstat: u16, + pub p_acflag: u16, + pub p_comm: [::c_char; KI_MAXCOMLEN as usize], + pub p_wmesg: [::c_char; KI_WMESGLEN as usize], + pub p_wchan: u64, + pub p_login: [::c_char; KI_MAXLOGNAME as usize], + pub p_vm_rssize: i32, + pub p_vm_tsize: i32, + pub p_vm_dsize: i32, + pub p_vm_ssize: i32, + pub p_uvalid: i64, + pub p_ustart_sec: u32, + pub p_ustart_usec: u32, + pub p_uutime_sec: u32, + pub p_uutime_usec: u32, + pub p_ustime_sec: u32, + pub p_ustime_usec: u32, + pub p_uru_maxrss: u64, + pub p_uru_ixrss: u64, + pub p_uru_idrss: u64, + pub p_uru_isrss: u64, + pub p_uru_minflt: u64, + pub p_uru_majflt: u64, + pub p_uru_nswap: u64, + pub p_uru_inblock: u64, + pub p_uru_oublock: u64, + pub p_uru_msgsnd: u64, + pub p_uru_msgrcv: u64, + pub p_uru_nsignals: u64, + pub p_uru_nvcsw: u64, + pub p_uru_nivcsw: u64, + pub p_uctime_sec: u32, + pub p_uctime_usec: u32, + pub p_cpuid: u64, + pub p_realflag: u64, + pub p_nlwps: u64, + pub p_nrlwps: u64, + pub p_realstat: u64, + pub p_svuid: u32, + pub p_svgid: u32, + pub p_ename: [::c_char; KI_MAXEMULLEN as usize], + pub p_vm_vsize: i64, + pub p_vm_msize: i64, + } + + pub struct kinfo_lwp { + pub l_forw: u64, + pub l_back: u64, + pub l_laddr: u64, + pub l_addr: u64, + pub l_lid: i32, + pub l_flag: i32, + pub l_swtime: u32, + pub l_slptime: u32, + pub l_schedflags: i32, + pub l_holdcnt: i32, + pub l_priority: u8, + pub l_usrpri: u8, + pub l_stat: i8, + l_pad1: i8, + l_pad2: i32, + pub l_wmesg: [::c_char; KI_WMESGLEN as usize], + pub l_wchan: u64, + pub l_cpuid: u64, + pub l_rtime_sec: u32, + pub l_rtime_usec: u32, + pub l_cpticks: u32, + pub l_pctcpu: u32, + pub l_pid: u32, + pub l_name: [::c_char; KI_LNAMELEN as usize], + } + + pub struct kinfo_vmentry { + pub kve_start: u64, + pub kve_end: u64, + pub kve_offset: u64, + pub kve_type: u32, + pub kve_flags: u32, + pub kve_count: u32, + pub kve_wired_count: u32, + pub kve_advice: u32, + pub kve_attributes: u32, + pub kve_protection: u32, + pub kve_max_protection: u32, + pub kve_ref_count: u32, + pub kve_inheritance: u32, + pub kve_vn_fileid: u64, + pub kve_vn_size: u64, + pub kve_vn_fsid: u64, + pub kve_vn_rdev: u64, + pub kve_vn_type: u32, + pub kve_vn_mode: u32, + pub kve_path: [[::c_char; 32]; 32], + } + + pub struct __c_anonymous_posix_spawn_fae_open { + pub path: *mut ::c_char, + pub oflag: ::c_int, + pub mode: ::mode_t, + } + + pub struct __c_anonymous_posix_spawn_fae_dup2 { + pub newfildes: ::c_int, + } + + pub struct posix_spawnattr_t { + pub sa_flags: ::c_short, + pub sa_pgroup: ::pid_t, + pub sa_schedparam: ::sched_param, + pub sa_schedpolicy: ::c_int, + pub sa_sigdefault: sigset_t, + pub sa_sigmask: sigset_t, + } + + pub struct posix_spawn_file_actions_entry_t { + pub fae_action: fae_action, + pub fae_fildes: ::c_int, + #[cfg(libc_union)] + pub fae_data: __c_anonymous_posix_spawn_fae, + } + + pub struct posix_spawn_file_actions_t { + pub size: ::c_uint, + pub len: ::c_uint, + #[cfg(libc_union)] + pub fae: *mut posix_spawn_file_actions_entry_t, + } + + pub struct ptrace_lwpinfo { + pub pl_lwpid: lwpid_t, + pub pl_event: ::c_int, + } + + pub struct ptrace_lwpstatus { + pub pl_lwpid: lwpid_t, + pub pl_sigpend: sigset_t, + pub pl_sigmask: sigset_t, + pub pl_name: [::c_char; 20], + pub pl_private: *mut ::c_void, + } + + pub struct ptrace_siginfo { + pub psi_siginfo: siginfo_t, + pub psi_lwpid: lwpid_t, + } + + pub struct ptrace_event { + pub pe_set_event: ::c_int, + } + + pub struct sysctldesc { + pub descr_num: i32, + pub descr_ver: u32, + pub descr_len: u32, + pub descr_str: [::c_char; 1], + } + + pub struct ifreq { + pub _priv: [[::c_char; 6]; 24], + } + + pub struct ifconf { + pub ifc_len: ::c_int, + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + } + + pub struct tcp_info { + pub tcpi_state: u8, + pub __tcpi_ca_state: u8, + pub __tcpi_retransmits: u8, + pub __tcpi_probes: u8, + pub __tcpi_backoff: u8, + pub tcpi_options: u8, + pub tcp_snd_wscale: u8, + pub tcp_rcv_wscale: u8, + pub tcpi_rto: u32, + pub __tcpi_ato: u32, + pub tcpi_snd_mss: u32, + pub tcpi_rcv_mss: u32, + pub __tcpi_unacked: u32, + pub __tcpi_sacked: u32, + pub __tcpi_lost: u32, + pub __tcpi_retrans: u32, + pub __tcpi_fackets: u32, + pub __tcpi_last_data_sent: u32, + pub __tcpi_last_ack_sent: u32, + pub tcpi_last_data_recv: u32, + pub __tcpi_last_ack_recv: u32, + pub __tcpi_pmtu: u32, + pub __tcpi_rcv_ssthresh: u32, + pub tcpi_rtt: u32, + pub tcpi_rttvar: u32, + pub tcpi_snd_ssthresh: u32, + pub tcpi_snd_cwnd: u32, + pub __tcpi_advmss: u32, + pub __tcpi_reordering: u32, + pub __tcpi_rcv_rtt: u32, + pub tcpi_rcv_space: u32, + pub tcpi_snd_wnd: u32, + pub tcpi_snd_bwnd: u32, + pub tcpi_snd_nxt: u32, + pub tcpi_rcv_nxt: u32, + pub tcpi_toe_tid: u32, + pub tcpi_snd_rexmitpack: u32, + pub tcpi_rcv_ooopack: u32, + pub tcpi_snd_zerowin: u32, + pub __tcpi_pad: [u32; 26], + } +} + +s_no_extra_traits! { + + pub struct utmpx { + pub ut_name: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_host: [::c_char; _UTX_HOSTSIZE], + pub ut_session: u16, + pub ut_type: u16, + pub ut_pid: ::pid_t, + pub ut_exit: __exit_status, // FIXME: when anonymous struct are supported + pub ut_ss: sockaddr_storage, + pub ut_tv: ::timeval, + pub ut_pad: [u8; _UTX_PADSIZE], + } + + pub struct lastlogx { + pub ll_tv: ::timeval, + pub ll_line: [::c_char; _UTX_LINESIZE], + pub ll_host: [::c_char; _UTX_HOSTSIZE], + pub ll_ss: sockaddr_storage, + } + + pub struct in_pktinfo { + pub ipi_addr: ::in_addr, + pub ipi_ifindex: ::c_uint, + } + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [i8; 8], + } + + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [::c_char; 512], + } + + pub struct statvfs { + pub f_flag: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_iosize: ::c_ulong, + + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_bresvd: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fresvd: ::fsfilcnt_t, + + pub f_syncreads: u64, + pub f_syncwrites: u64, + + pub f_asyncreads: u64, + pub f_asyncwrites: u64, + + pub f_fsidx: ::fsid_t, + pub f_fsid: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_owner: ::uid_t, + + pub f_spare: [u32; 4], + + pub f_fstypename: [::c_char; 32], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: i64, + __ss_pad3: [u8; 112], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + __unused1: *mut ::c_void, //actually a function pointer + pub sigev_notify_attributes: *mut ::c_void + } + + #[cfg(libc_union)] + pub union __c_anonymous_posix_spawn_fae { + pub open: __c_anonymous_posix_spawn_fae_open, + pub dup2: __c_anonymous_posix_spawn_fae_dup2, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut ::c_void, + pub ifcu_req: *mut ifreq, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_name == other.ut_name + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_ss == other.ut_ss + && self + .ut_pad + .iter() + .zip(other.ut_pad.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_name", &self.ut_name) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + // FIXME .field("ut_host", &self.ut_host) + .field("ut_session", &self.ut_session) + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_exit", &self.ut_exit) + .field("ut_ss", &self.ut_ss) + .field("ut_tv", &self.ut_tv) + // FIXME .field("ut_pad", &self.ut_pad) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_name.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_ss.hash(state); + self.ut_pad.hash(state); + } + } + + impl PartialEq for lastlogx { + fn eq(&self, other: &lastlogx) -> bool { + self.ll_tv == other.ll_tv + && self.ll_line == other.ll_line + && self.ll_ss == other.ll_ss + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlogx {} + + impl ::fmt::Debug for lastlogx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlogx") + .field("ll_tv", &self.ll_tv) + .field("ll_line", &self.ll_line) + // FIXME.field("ll_host", &self.ll_host) + .field("ll_ss", &self.ll_ss) + .finish() + } + } + + impl ::hash::Hash for lastlogx { + fn hash(&self, state: &mut H) { + self.ll_tv.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + self.ll_ss.hash(state); + } + } + + impl PartialEq for in_pktinfo { + fn eq(&self, other: &in_pktinfo) -> bool { + self.ipi_addr == other.ipi_addr + && self.ipi_ifindex == other.ipi_ifindex + } + } + impl Eq for in_pktinfo {} + impl ::fmt::Debug for in_pktinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("in_pktinfo") + .field("ipi_addr", &self.ipi_addr) + .field("ipi_ifindex", &self.ipi_ifindex) + .finish() + } + } + impl ::hash::Hash for in_pktinfo { + fn hash(&self, state: &mut H) { + self.ipi_addr.hash(state); + self.ipi_ifindex.hash(state); + } + } + + impl PartialEq for arphdr { + fn eq(&self, other: &arphdr) -> bool { + self.ar_hrd == other.ar_hrd + && self.ar_pro == other.ar_pro + && self.ar_hln == other.ar_hln + && self.ar_pln == other.ar_pln + && self.ar_op == other.ar_op + } + } + impl Eq for arphdr {} + impl ::fmt::Debug for arphdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ar_hrd = self.ar_hrd; + let ar_pro = self.ar_pro; + let ar_op = self.ar_op; + f.debug_struct("arphdr") + .field("ar_hrd", &ar_hrd) + .field("ar_pro", &ar_pro) + .field("ar_hln", &self.ar_hln) + .field("ar_pln", &self.ar_pln) + .field("ar_op", &ar_op) + .finish() + } + } + impl ::hash::Hash for arphdr { + fn hash(&self, state: &mut H) { + let ar_hrd = self.ar_hrd; + let ar_pro = self.ar_pro; + let ar_op = self.ar_op; + ar_hrd.hash(state); + ar_pro.hash(state); + self.ar_hln.hash(state); + self.ar_pln.hash(state); + ar_op.hash(state); + } + } + + impl PartialEq for in_addr { + fn eq(&self, other: &in_addr) -> bool { + self.s_addr == other.s_addr + } + } + impl Eq for in_addr {} + impl ::fmt::Debug for in_addr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let s_addr = self.s_addr; + f.debug_struct("in_addr") + .field("s_addr", &s_addr) + .finish() + } + } + impl ::hash::Hash for in_addr { + fn hash(&self, state: &mut H) { + let s_addr = self.s_addr; + s_addr.hash(state); + } + } + + impl PartialEq for ip_mreq { + fn eq(&self, other: &ip_mreq) -> bool { + self.imr_multiaddr == other.imr_multiaddr + && self.imr_interface == other.imr_interface + } + } + impl Eq for ip_mreq {} + impl ::fmt::Debug for ip_mreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ip_mreq") + .field("imr_multiaddr", &self.imr_multiaddr) + .field("imr_interface", &self.imr_interface) + .finish() + } + } + impl ::hash::Hash for ip_mreq { + fn hash(&self, state: &mut H) { + self.imr_multiaddr.hash(state); + self.imr_interface.hash(state); + } + } + + impl PartialEq for sockaddr_in { + fn eq(&self, other: &sockaddr_in) -> bool { + self.sin_len == other.sin_len + && self.sin_family == other.sin_family + && self.sin_port == other.sin_port + && self.sin_addr == other.sin_addr + && self.sin_zero == other.sin_zero + } + } + impl Eq for sockaddr_in {} + impl ::fmt::Debug for sockaddr_in { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_in") + .field("sin_len", &self.sin_len) + .field("sin_family", &self.sin_family) + .field("sin_port", &self.sin_port) + .field("sin_addr", &self.sin_addr) + .field("sin_zero", &self.sin_zero) + .finish() + } + } + impl ::hash::Hash for sockaddr_in { + fn hash(&self, state: &mut H) { + self.sin_len.hash(state); + self.sin_family.hash(state); + self.sin_port.hash(state); + self.sin_addr.hash(state); + self.sin_zero.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_reclen == other.d_reclen + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_reclen", &self.d_reclen) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_reclen.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for statvfs { + fn eq(&self, other: &statvfs) -> bool { + self.f_flag == other.f_flag + && self.f_bsize == other.f_bsize + && self.f_frsize == other.f_frsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_bresvd == other.f_bresvd + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_favail == other.f_favail + && self.f_fresvd == other.f_fresvd + && self.f_syncreads == other.f_syncreads + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncreads == other.f_asyncreads + && self.f_asyncwrites == other.f_asyncwrites + && self.f_fsidx == other.f_fsidx + && self.f_fsid == other.f_fsid + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_spare == other.f_spare + && self.f_fstypename == other.f_fstypename + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statvfs {} + impl ::fmt::Debug for statvfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statvfs") + .field("f_flag", &self.f_flag) + .field("f_bsize", &self.f_bsize) + .field("f_frsize", &self.f_frsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_bresvd", &self.f_bresvd) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_favail", &self.f_favail) + .field("f_fresvd", &self.f_fresvd) + .field("f_syncreads", &self.f_syncreads) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_fsidx", &self.f_fsidx) + .field("f_fsid", &self.f_fsid) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_spare", &self.f_spare) + .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .finish() + } + } + impl ::hash::Hash for statvfs { + fn hash(&self, state: &mut H) { + self.f_flag.hash(state); + self.f_bsize.hash(state); + self.f_frsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_bresvd.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_favail.hash(state); + self.f_fresvd.hash(state); + self.f_syncreads.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncreads.hash(state); + self.f_asyncwrites.hash(state); + self.f_fsidx.hash(state); + self.f_fsid.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_spare.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_pad2 == other.__ss_pad2 + && self + .__ss_pad3 + .iter() + .zip(other.__ss_pad3.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_pad2", &self.__ss_pad2) + // FIXME: .field("__ss_pad3", &self.__ss_pad3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_pad2.hash(state); + self.__ss_pad3.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_posix_spawn_fae {} + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_posix_spawn_fae { + fn eq(&self, other: &__c_anonymous_posix_spawn_fae) -> bool { + unsafe { + self.open == other.open + || self.dup2 == other.dup2 + } + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_posix_spawn_fae { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous_posix_fae") + .field("open", &self.open) + .field("dup2", &self.dup2) + .finish() + } + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_posix_spawn_fae { + fn hash(&self, state: &mut H) { + unsafe { + self.open.hash(state); + self.dup2.hash(state); + } + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifc_ifcu {} + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifc_ifcu { + fn eq(&self, other: &__c_anonymous_ifc_ifcu) -> bool { + unsafe { + self.ifcu_buf == other.ifcu_buf + || self.ifcu_req == other.ifcu_req + } + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous_ifc_ifcu") + .field("ifcu_buf", &self.ifcu_buf) + .field("ifcu_req", &self.ifcu_req) + .finish() + } + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifc_ifcu { + fn hash(&self, state: &mut H) { + unsafe { + self.ifcu_buf.hash(state); + self.ifcu_req.hash(state); + } + } + } + } +} + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_EACCESS: ::c_int = 0x100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x200; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; +pub const AT_REMOVEDIR: ::c_int = 0x800; + +pub const AT_NULL: ::c_int = 0; +pub const AT_IGNORE: ::c_int = 1; +pub const AT_EXECFD: ::c_int = 2; +pub const AT_PHDR: ::c_int = 3; +pub const AT_PHENT: ::c_int = 4; +pub const AT_PHNUM: ::c_int = 5; +pub const AT_PAGESZ: ::c_int = 6; +pub const AT_BASE: ::c_int = 7; +pub const AT_FLAGS: ::c_int = 8; +pub const AT_ENTRY: ::c_int = 9; +pub const AT_DCACHEBSIZE: ::c_int = 10; +pub const AT_ICACHEBSIZE: ::c_int = 11; +pub const AT_UCACHEBSIZE: ::c_int = 12; +pub const AT_STACKBASE: ::c_int = 13; +pub const AT_EUID: ::c_int = 2000; +pub const AT_RUID: ::c_int = 2001; +pub const AT_EGID: ::c_int = 2002; +pub const AT_RGID: ::c_int = 2003; +pub const AT_SUN_LDELF: ::c_int = 2004; +pub const AT_SUN_LDSHDR: ::c_int = 2005; +pub const AT_SUN_LDNAME: ::c_int = 2006; +pub const AT_SUN_LDPGSIZE: ::c_int = 2007; +pub const AT_SUN_PLATFORM: ::c_int = 2008; +pub const AT_SUN_HWCAP: ::c_int = 2009; +pub const AT_SUN_IFLUSH: ::c_int = 2010; +pub const AT_SUN_CPU: ::c_int = 2011; +pub const AT_SUN_EMUL_ENTRY: ::c_int = 2012; +pub const AT_SUN_EMUL_EXECFD: ::c_int = 2013; +pub const AT_SUN_EXECNAME: ::c_int = 2014; + +pub const EXTATTR_NAMESPACE_USER: ::c_int = 1; +pub const EXTATTR_NAMESPACE_SYSTEM: ::c_int = 2; + +pub const LC_COLLATE_MASK: ::c_int = 1 << ::LC_COLLATE; +pub const LC_CTYPE_MASK: ::c_int = 1 << ::LC_CTYPE; +pub const LC_MONETARY_MASK: ::c_int = 1 << ::LC_MONETARY; +pub const LC_NUMERIC_MASK: ::c_int = 1 << ::LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << ::LC_TIME; +pub const LC_MESSAGES_MASK: ::c_int = 1 << ::LC_MESSAGES; +pub const LC_ALL_MASK: ::c_int = !0; + +pub const ERA: ::nl_item = 52; +pub const ERA_D_FMT: ::nl_item = 53; +pub const ERA_D_T_FMT: ::nl_item = 54; +pub const ERA_T_FMT: ::nl_item = 55; +pub const ALT_DIGITS: ::nl_item = 56; + +pub const O_CLOEXEC: ::c_int = 0x400000; +pub const O_ALT_IO: ::c_int = 0x40000; +pub const O_NOSIGPIPE: ::c_int = 0x1000000; +pub const O_SEARCH: ::c_int = 0x800000; +pub const O_DIRECTORY: ::c_int = 0x200000; +pub const O_DIRECT: ::c_int = 0x00080000; +pub const O_RSYNC: ::c_int = 0x00020000; + +pub const MS_SYNC: ::c_int = 0x4; +pub const MS_INVALIDATE: ::c_int = 0x2; + +// Here because they are not present on OpenBSD +// (https://github.com/openbsd/src/blob/HEAD/sys/sys/resource.h) +pub const RLIMIT_SBSIZE: ::c_int = 9; +pub const RLIMIT_AS: ::c_int = 10; +pub const RLIMIT_NTHR: ::c_int = 11; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 12; + +pub const EIDRM: ::c_int = 82; +pub const ENOMSG: ::c_int = 83; +pub const EOVERFLOW: ::c_int = 84; +pub const EILSEQ: ::c_int = 85; +pub const ENOTSUP: ::c_int = 86; +pub const ECANCELED: ::c_int = 87; +pub const EBADMSG: ::c_int = 88; +pub const ENODATA: ::c_int = 89; +pub const ENOSR: ::c_int = 90; +pub const ENOSTR: ::c_int = 91; +pub const ETIME: ::c_int = 92; +pub const ENOATTR: ::c_int = 93; +pub const EMULTIHOP: ::c_int = 94; +pub const ENOLINK: ::c_int = 95; +pub const EPROTO: ::c_int = 96; +pub const EOWNERDEAD: ::c_int = 97; +pub const ENOTRECOVERABLE: ::c_int = 98; +#[deprecated( + since = "0.2.143", + note = "This value will always match the highest defined error number \ + and thus is not stable. \ + See #3040 for more info." +)] +pub const ELAST: ::c_int = 98; + +pub const F_DUPFD_CLOEXEC: ::c_int = 12; +pub const F_CLOSEM: ::c_int = 10; +pub const F_GETNOSIGPIPE: ::c_int = 13; +pub const F_SETNOSIGPIPE: ::c_int = 14; +pub const F_MAXFD: ::c_int = 11; +pub const F_GETPATH: ::c_int = 15; + +pub const FUTEX_WAIT: ::c_int = 0; +pub const FUTEX_WAKE: ::c_int = 1; +pub const FUTEX_FD: ::c_int = 2; +pub const FUTEX_REQUEUE: ::c_int = 3; +pub const FUTEX_CMP_REQUEUE: ::c_int = 4; +pub const FUTEX_WAKE_OP: ::c_int = 5; +pub const FUTEX_LOCK_PI: ::c_int = 6; +pub const FUTEX_UNLOCK_PI: ::c_int = 7; +pub const FUTEX_TRYLOCK_PI: ::c_int = 8; +pub const FUTEX_WAIT_BITSET: ::c_int = 9; +pub const FUTEX_WAKE_BITSET: ::c_int = 10; +pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11; +pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12; +pub const FUTEX_PRIVATE_FLAG: ::c_int = 1 << 7; +pub const FUTEX_CLOCK_REALTIME: ::c_int = 1 << 8; +pub const FUTEX_CMD_MASK: ::c_int = !(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME); +pub const FUTEX_WAITERS: u32 = 1 << 31; +pub const FUTEX_OWNER_DIED: u32 = 1 << 30; +pub const FUTEX_SYNCOBJ_1: u32 = 1 << 29; +pub const FUTEX_SYNCOBJ_0: u32 = 1 << 28; +pub const FUTEX_TID_MASK: u32 = (1 << 28) - 1; +pub const FUTEX_BITSET_MATCH_ANY: u32 = !0; + +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_SENDSRCADDR: ::c_int = IP_RECVDSTADDR; +pub const IP_RECVIF: ::c_int = 20; +pub const IP_PKTINFO: ::c_int = 25; +pub const IP_RECVPKTINFO: ::c_int = 26; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; + +pub const TCP_KEEPIDLE: ::c_int = 3; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_KEEPINIT: ::c_int = 7; +pub const TCP_MD5SIG: ::c_int = 0x10; +pub const TCP_CONGCTL: ::c_int = 0x20; + +pub const SOCK_CONN_DGRAM: ::c_int = 6; +pub const SOCK_DCCP: ::c_int = SOCK_CONN_DGRAM; +pub const SOCK_NOSIGPIPE: ::c_int = 0x40000000; +pub const SOCK_FLAGS_MASK: ::c_int = 0xf0000000; + +pub const SO_SNDTIMEO: ::c_int = 0x100b; +pub const SO_RCVTIMEO: ::c_int = 0x100c; +pub const SO_NOSIGPIPE: ::c_int = 0x0800; +pub const SO_ACCEPTFILTER: ::c_int = 0x1000; +pub const SO_TIMESTAMP: ::c_int = 0x2000; +pub const SO_OVERFLOWED: ::c_int = 0x1009; +pub const SO_NOHEADER: ::c_int = 0x100a; + +// http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/un.h?annotate +pub const LOCAL_OCREDS: ::c_int = 0x0001; // pass credentials to receiver +pub const LOCAL_CONNWAIT: ::c_int = 0x0002; // connects block until accepted +pub const LOCAL_PEEREID: ::c_int = 0x0003; // get peer identification +pub const LOCAL_CREDS: ::c_int = 0x0004; // pass credentials to receiver + +// https://github.com/NetBSD/src/blob/trunk/sys/net/if.h#L373 +pub const IFF_UP: ::c_int = 0x0001; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x0002; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x0004; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x0008; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x0010; // interface is point-to-point link +pub const IFF_NOTRAILERS: ::c_int = 0x0020; // avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x0040; // resources allocated +pub const IFF_NOARP: ::c_int = 0x0080; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x0100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x0400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x0800; // can't hear own transmissions +pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit +pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit +pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// DCCP +pub const IPPROTO_DCCP: ::c_int = 33; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// IP Mobility RFC 2004 +pub const IPPROTO_MOBILE: ::c_int = 55; +/// IPv6 ICMP +pub const IPPROTO_IPV6_ICMP: ::c_int = 58; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// Ethernet-in-IP +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// VRRP RFC 2338 +pub const IPPROTO_VRRP: ::c_int = 112; +/// Common Address Resolution Protocol +pub const IPPROTO_CARP: ::c_int = 112; +/// L2TPv3 +pub const IPPROTO_L2TP: ::c_int = 115; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; +pub const IPPROTO_MAX: ::c_int = 256; + +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +/// sysctl placeholder for (FAST_)IPSEC +pub const CTL_IPPROTO_IPSEC: ::c_int = 258; + +pub const AF_OROUTE: ::c_int = 17; +pub const AF_ARP: ::c_int = 28; +pub const pseudo_AF_KEY: ::c_int = 29; +pub const pseudo_AF_HDRCMPLT: ::c_int = 30; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_IEEE80211: ::c_int = 32; +pub const AF_MPLS: ::c_int = 33; +pub const AF_ROUTE: ::c_int = 34; +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_OOOIFLIST: ::c_int = 3; +pub const NET_RT_OOIFLIST: ::c_int = 4; +pub const NET_RT_OIFLIST: ::c_int = 5; +pub const NET_RT_IFLIST: ::c_int = 6; +pub const NET_RT_MAXID: ::c_int = 7; + +pub const PF_OROUTE: ::c_int = AF_OROUTE; +pub const PF_ARP: ::c_int = AF_ARP; +pub const PF_KEY: ::c_int = pseudo_AF_KEY; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_ROUTE: ::c_int = AF_ROUTE; + +pub const MSG_NBIO: ::c_int = 0x1000; +pub const MSG_WAITFORONE: ::c_int = 0x2000; +pub const MSG_NOTIFICATION: ::c_int = 0x4000; + +pub const SCM_TIMESTAMP: ::c_int = 0x08; +pub const SCM_CREDS: ::c_int = 0x10; + +pub const O_DSYNC: ::c_int = 0x10000; + +pub const MAP_RENAME: ::c_int = 0x20; +pub const MAP_NORESERVE: ::c_int = 0x40; +pub const MAP_HASSEMAPHORE: ::c_int = 0x200; +pub const MAP_TRYFIXED: ::c_int = 0x400; +pub const MAP_WIRED: ::c_int = 0x800; +pub const MAP_STACK: ::c_int = 0x2000; +// map alignment aliases for MAP_ALIGNED +pub const MAP_ALIGNMENT_SHIFT: ::c_int = 24; +pub const MAP_ALIGNMENT_MASK: ::c_int = 0xff << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNMENT_64KB: ::c_int = 16 << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNMENT_16MB: ::c_int = 24 << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNMENT_4GB: ::c_int = 32 << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNMENT_1TB: ::c_int = 40 << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNMENT_256TB: ::c_int = 48 << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNMENT_64PB: ::c_int = 56 << MAP_ALIGNMENT_SHIFT; +// mremap flag +pub const MAP_REMAPDUP: ::c_int = 0x004; + +pub const DCCP_TYPE_REQUEST: ::c_int = 0; +pub const DCCP_TYPE_RESPONSE: ::c_int = 1; +pub const DCCP_TYPE_DATA: ::c_int = 2; +pub const DCCP_TYPE_ACK: ::c_int = 3; +pub const DCCP_TYPE_DATAACK: ::c_int = 4; +pub const DCCP_TYPE_CLOSEREQ: ::c_int = 5; +pub const DCCP_TYPE_CLOSE: ::c_int = 6; +pub const DCCP_TYPE_RESET: ::c_int = 7; +pub const DCCP_TYPE_MOVE: ::c_int = 8; + +pub const DCCP_FEATURE_CC: ::c_int = 1; +pub const DCCP_FEATURE_ECN: ::c_int = 2; +pub const DCCP_FEATURE_ACKRATIO: ::c_int = 3; +pub const DCCP_FEATURE_ACKVECTOR: ::c_int = 4; +pub const DCCP_FEATURE_MOBILITY: ::c_int = 5; +pub const DCCP_FEATURE_LOSSWINDOW: ::c_int = 6; +pub const DCCP_FEATURE_CONN_NONCE: ::c_int = 8; +pub const DCCP_FEATURE_IDENTREG: ::c_int = 7; + +pub const DCCP_OPT_PADDING: ::c_int = 0; +pub const DCCP_OPT_DATA_DISCARD: ::c_int = 1; +pub const DCCP_OPT_SLOW_RECV: ::c_int = 2; +pub const DCCP_OPT_BUF_CLOSED: ::c_int = 3; +pub const DCCP_OPT_CHANGE_L: ::c_int = 32; +pub const DCCP_OPT_CONFIRM_L: ::c_int = 33; +pub const DCCP_OPT_CHANGE_R: ::c_int = 34; +pub const DCCP_OPT_CONFIRM_R: ::c_int = 35; +pub const DCCP_OPT_INIT_COOKIE: ::c_int = 36; +pub const DCCP_OPT_NDP_COUNT: ::c_int = 37; +pub const DCCP_OPT_ACK_VECTOR0: ::c_int = 38; +pub const DCCP_OPT_ACK_VECTOR1: ::c_int = 39; +pub const DCCP_OPT_RECV_BUF_DROPS: ::c_int = 40; +pub const DCCP_OPT_TIMESTAMP: ::c_int = 41; +pub const DCCP_OPT_TIMESTAMP_ECHO: ::c_int = 42; +pub const DCCP_OPT_ELAPSEDTIME: ::c_int = 43; +pub const DCCP_OPT_DATACHECKSUM: ::c_int = 44; + +pub const DCCP_REASON_UNSPEC: ::c_int = 0; +pub const DCCP_REASON_CLOSED: ::c_int = 1; +pub const DCCP_REASON_INVALID: ::c_int = 2; +pub const DCCP_REASON_OPTION_ERR: ::c_int = 3; +pub const DCCP_REASON_FEA_ERR: ::c_int = 4; +pub const DCCP_REASON_CONN_REF: ::c_int = 5; +pub const DCCP_REASON_BAD_SNAME: ::c_int = 6; +pub const DCCP_REASON_BAD_COOKIE: ::c_int = 7; +pub const DCCP_REASON_INV_MOVE: ::c_int = 8; +pub const DCCP_REASON_UNANSW_CH: ::c_int = 10; +pub const DCCP_REASON_FRUITLESS_NEG: ::c_int = 11; + +pub const DCCP_CCID: ::c_int = 1; +pub const DCCP_CSLEN: ::c_int = 2; +pub const DCCP_MAXSEG: ::c_int = 4; +pub const DCCP_SERVICE: ::c_int = 8; + +pub const DCCP_NDP_LIMIT: ::c_int = 16; +pub const DCCP_SEQ_NUM_LIMIT: ::c_int = 16777216; +pub const DCCP_MAX_OPTIONS: ::c_int = 32; +pub const DCCP_MAX_PKTS: ::c_int = 100; + +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_SYNC_IO: ::c_int = 10; +pub const _PC_FILESIZEBITS: ::c_int = 11; +pub const _PC_SYMLINK_MAX: ::c_int = 12; +pub const _PC_2_SYMLINKS: ::c_int = 13; +pub const _PC_ACL_EXTENDED: ::c_int = 14; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 15; + +pub const _SC_SYNCHRONIZED_IO: ::c_int = 31; +pub const _SC_IOV_MAX: ::c_int = 32; +pub const _SC_MAPPED_FILES: ::c_int = 33; +pub const _SC_MEMLOCK: ::c_int = 34; +pub const _SC_MEMLOCK_RANGE: ::c_int = 35; +pub const _SC_MEMORY_PROTECTION: ::c_int = 36; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 37; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 38; +pub const _SC_CLK_TCK: ::c_int = 39; +pub const _SC_ATEXIT_MAX: ::c_int = 40; +pub const _SC_THREADS: ::c_int = 41; +pub const _SC_SEMAPHORES: ::c_int = 42; +pub const _SC_BARRIERS: ::c_int = 43; +pub const _SC_TIMERS: ::c_int = 44; +pub const _SC_SPIN_LOCKS: ::c_int = 45; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 46; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 47; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 48; +pub const _SC_CLOCK_SELECTION: ::c_int = 49; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 50; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 51; +pub const _SC_AIO_MAX: ::c_int = 52; +pub const _SC_MESSAGE_PASSING: ::c_int = 53; +pub const _SC_MQ_OPEN_MAX: ::c_int = 54; +pub const _SC_MQ_PRIO_MAX: ::c_int = 55; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 56; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 57; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 58; +pub const _SC_THREAD_STACK_MIN: ::c_int = 59; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 60; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 61; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 62; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 63; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 64; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 65; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 66; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 67; +pub const _SC_TTY_NAME_MAX: ::c_int = 68; +pub const _SC_HOST_NAME_MAX: ::c_int = 69; +pub const _SC_PASS_MAX: ::c_int = 70; +pub const _SC_REGEXP: ::c_int = 71; +pub const _SC_SHELL: ::c_int = 72; +pub const _SC_SYMLOOP_MAX: ::c_int = 73; +pub const _SC_V6_ILP32_OFF32: ::c_int = 74; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 75; +pub const _SC_V6_LP64_OFF64: ::c_int = 76; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 77; +pub const _SC_2_PBS: ::c_int = 80; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 81; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 82; +pub const _SC_2_PBS_LOCATE: ::c_int = 83; +pub const _SC_2_PBS_MESSAGE: ::c_int = 84; +pub const _SC_2_PBS_TRACK: ::c_int = 85; +pub const _SC_SPAWN: ::c_int = 86; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 87; +pub const _SC_TIMER_MAX: ::c_int = 88; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 89; +pub const _SC_CPUTIME: ::c_int = 90; +pub const _SC_THREAD_CPUTIME: ::c_int = 91; +pub const _SC_DELAYTIMER_MAX: ::c_int = 92; +// These two variables will be supported in NetBSD 8.0 +// pub const _SC_SIGQUEUE_MAX : ::c_int = 93; +// pub const _SC_REALTIME_SIGNALS : ::c_int = 94; +pub const _SC_PHYS_PAGES: ::c_int = 121; +pub const _SC_NPROCESSORS_CONF: ::c_int = 1001; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 1002; +pub const _SC_SCHED_RT_TS: ::c_int = 2001; +pub const _SC_SCHED_PRI_MIN: ::c_int = 2002; +pub const _SC_SCHED_PRI_MAX: ::c_int = 2003; + +pub const FD_SETSIZE: usize = 0x100; + +pub const ST_NOSUID: ::c_ulong = 8; + +pub const BIOCGRSIG: ::c_ulong = 0x40044272; +pub const BIOCSRSIG: ::c_ulong = 0x80044273; +pub const BIOCSDLT: ::c_ulong = 0x80044278; +pub const BIOCGSEESENT: ::c_ulong = 0x40044276; +pub const BIOCSSEESENT: ::c_ulong = 0x80044277; + +// +pub const MNT_UNION: ::c_int = 0x00000020; +pub const MNT_NOCOREDUMP: ::c_int = 0x00008000; +pub const MNT_RELATIME: ::c_int = 0x00020000; +pub const MNT_IGNORE: ::c_int = 0x00100000; +pub const MNT_NFS4ACLS: ::c_int = 0x00200000; +pub const MNT_DISCARD: ::c_int = 0x00800000; +pub const MNT_EXTATTR: ::c_int = 0x01000000; +pub const MNT_LOG: ::c_int = 0x02000000; +pub const MNT_NOATIME: ::c_int = 0x04000000; +pub const MNT_AUTOMOUNTED: ::c_int = 0x10000000; +pub const MNT_SYMPERM: ::c_int = 0x20000000; +pub const MNT_NODEVMTIME: ::c_int = 0x40000000; +pub const MNT_SOFTDEP: ::c_int = 0x80000000; +pub const MNT_POSIX1EACLS: ::c_int = 0x00000800; +pub const MNT_ACLS: ::c_int = MNT_POSIX1EACLS; +pub const MNT_WAIT: ::c_int = 1; +pub const MNT_NOWAIT: ::c_int = 2; +pub const MNT_LAZY: ::c_int = 3; + +// +pub const NTP_API: ::c_int = 4; +pub const MAXPHASE: ::c_long = 500000000; +pub const MAXFREQ: ::c_long = 500000; +pub const MINSEC: ::c_int = 256; +pub const MAXSEC: ::c_int = 2048; +pub const NANOSECOND: ::c_long = 1000000000; +pub const SCALE_PPM: ::c_int = 65; +pub const MAXTC: ::c_int = 10; +pub const MOD_OFFSET: ::c_uint = 0x0001; +pub const MOD_FREQUENCY: ::c_uint = 0x0002; +pub const MOD_MAXERROR: ::c_uint = 0x0004; +pub const MOD_ESTERROR: ::c_uint = 0x0008; +pub const MOD_STATUS: ::c_uint = 0x0010; +pub const MOD_TIMECONST: ::c_uint = 0x0020; +pub const MOD_PPSMAX: ::c_uint = 0x0040; +pub const MOD_TAI: ::c_uint = 0x0080; +pub const MOD_MICRO: ::c_uint = 0x1000; +pub const MOD_NANO: ::c_uint = 0x2000; +pub const MOD_CLKB: ::c_uint = 0x4000; +pub const MOD_CLKA: ::c_uint = 0x8000; +pub const STA_PLL: ::c_int = 0x0001; +pub const STA_PPSFREQ: ::c_int = 0x0002; +pub const STA_PPSTIME: ::c_int = 0x0004; +pub const STA_FLL: ::c_int = 0x0008; +pub const STA_INS: ::c_int = 0x0010; +pub const STA_DEL: ::c_int = 0x0020; +pub const STA_UNSYNC: ::c_int = 0x0040; +pub const STA_FREQHOLD: ::c_int = 0x0080; +pub const STA_PPSSIGNAL: ::c_int = 0x0100; +pub const STA_PPSJITTER: ::c_int = 0x0200; +pub const STA_PPSWANDER: ::c_int = 0x0400; +pub const STA_PPSERROR: ::c_int = 0x0800; +pub const STA_CLOCKERR: ::c_int = 0x1000; +pub const STA_NANO: ::c_int = 0x2000; +pub const STA_MODE: ::c_int = 0x4000; +pub const STA_CLK: ::c_int = 0x8000; +pub const STA_RONLY: ::c_int = STA_PPSSIGNAL + | STA_PPSJITTER + | STA_PPSWANDER + | STA_PPSERROR + | STA_CLOCKERR + | STA_NANO + | STA_MODE + | STA_CLK; +pub const TIME_OK: ::c_int = 0; +pub const TIME_INS: ::c_int = 1; +pub const TIME_DEL: ::c_int = 2; +pub const TIME_OOP: ::c_int = 3; +pub const TIME_WAIT: ::c_int = 4; +pub const TIME_ERROR: ::c_int = 5; + +pub const LITTLE_ENDIAN: ::c_int = 1234; +pub const BIG_ENDIAN: ::c_int = 4321; + +pub const PL_EVENT_NONE: ::c_int = 0; +pub const PL_EVENT_SIGNAL: ::c_int = 1; +pub const PL_EVENT_SUSPENDED: ::c_int = 2; + +cfg_if! { + if #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t + = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_pad1: [0; 3], + ptm_unused: 0, + ptm_pad2: [0; 3], + ptm_waiters: 0 as *mut _, + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: 0 as *mut _, + }; + } else { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t + = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_unused: 0, + ptm_waiters: 0 as *mut _, + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: 0 as *mut _, + }; + } +} + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + ptc_magic: 0x55550005, + ptc_lock: 0, + ptc_waiters_first: 0 as *mut _, + ptc_waiters_last: 0 as *mut _, + ptc_mutex: 0 as *mut _, + ptc_private: 0 as *mut _, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + ptr_magic: 0x99990009, + ptr_interlock: 0, + ptr_rblocked_first: 0 as *mut _, + ptr_rblocked_last: 0 as *mut _, + ptr_wblocked_first: 0 as *mut _, + ptr_wblocked_last: 0 as *mut _, + ptr_nreaders: 0, + ptr_owner: 0, + ptr_private: 0 as *mut _, +}; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; + +pub const SCHED_NONE: ::c_int = -1; +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; + +pub const EVFILT_AIO: u32 = 2; +pub const EVFILT_PROC: u32 = 4; +pub const EVFILT_READ: u32 = 0; +pub const EVFILT_SIGNAL: u32 = 5; +pub const EVFILT_TIMER: u32 = 6; +pub const EVFILT_VNODE: u32 = 3; +pub const EVFILT_WRITE: u32 = 1; +pub const EVFILT_FS: u32 = 7; +pub const EVFILT_USER: u32 = 8; +pub const EVFILT_EMPTY: u32 = 9; + +pub const EV_ADD: u32 = 0x1; +pub const EV_DELETE: u32 = 0x2; +pub const EV_ENABLE: u32 = 0x4; +pub const EV_DISABLE: u32 = 0x8; +pub const EV_ONESHOT: u32 = 0x10; +pub const EV_CLEAR: u32 = 0x20; +pub const EV_RECEIPT: u32 = 0x40; +pub const EV_DISPATCH: u32 = 0x80; +pub const EV_FLAG1: u32 = 0x2000; +pub const EV_ERROR: u32 = 0x4000; +pub const EV_EOF: u32 = 0x8000; +pub const EV_SYSFLAGS: u32 = 0xf000; + +pub const NOTE_TRIGGER: u32 = 0x01000000; +pub const NOTE_FFNOP: u32 = 0x00000000; +pub const NOTE_FFAND: u32 = 0x40000000; +pub const NOTE_FFOR: u32 = 0x80000000; +pub const NOTE_FFCOPY: u32 = 0xc0000000; +pub const NOTE_FFCTRLMASK: u32 = 0xc0000000; +pub const NOTE_FFLAGSMASK: u32 = 0x00ffffff; +pub const NOTE_LOWAT: u32 = 0x00000001; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +pub const NOTE_ATTRIB: u32 = 0x00000008; +pub const NOTE_LINK: u32 = 0x00000010; +pub const NOTE_RENAME: u32 = 0x00000020; +pub const NOTE_REVOKE: u32 = 0x00000040; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +pub const NOTE_PCTRLMASK: u32 = 0xf0000000; +pub const NOTE_TRACK: u32 = 0x00000001; +pub const NOTE_TRACKERR: u32 = 0x00000002; +pub const NOTE_CHILD: u32 = 0x00000004; +pub const NOTE_MSECONDS: u32 = 0x00000000; +pub const NOTE_SECONDS: u32 = 0x00000001; +pub const NOTE_USECONDS: u32 = 0x00000002; +pub const NOTE_NSECONDS: u32 = 0x00000003; +pub const NOTE_ABSTIME: u32 = 0x000000010; + +pub const TMP_MAX: ::c_uint = 308915776; + +pub const AI_PASSIVE: ::c_int = 0x00000001; +pub const AI_CANONNAME: ::c_int = 0x00000002; +pub const AI_NUMERICHOST: ::c_int = 0x00000004; +pub const AI_NUMERICSERV: ::c_int = 0x00000008; +pub const AI_ADDRCONFIG: ::c_int = 0x00000400; +pub const AI_SRV: ::c_int = 0x00000800; + +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const NI_MAXSERV: ::socklen_t = 32; + +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x000000002; +pub const NI_NAMEREQD: ::c_int = 0x000000004; +pub const NI_NUMERICSERV: ::c_int = 0x000000008; +pub const NI_DGRAM: ::c_int = 0x00000010; +pub const NI_WITHSCOPEID: ::c_int = 0x00000020; +pub const NI_NUMERICSCOPE: ::c_int = 0x00000040; + +pub const RTLD_NOLOAD: ::c_int = 0x2000; +pub const RTLD_LOCAL: ::c_int = 0x200; + +pub const CTL_MAXNAME: ::c_int = 12; +pub const SYSCTL_NAMELEN: ::c_int = 32; +pub const SYSCTL_DEFSIZE: ::c_int = 8; +pub const CTLTYPE_NODE: ::c_int = 1; +pub const CTLTYPE_INT: ::c_int = 2; +pub const CTLTYPE_STRING: ::c_int = 3; +pub const CTLTYPE_QUAD: ::c_int = 4; +pub const CTLTYPE_STRUCT: ::c_int = 5; +pub const CTLTYPE_BOOL: ::c_int = 6; +pub const CTLFLAG_READONLY: ::c_int = 0x00000000; +pub const CTLFLAG_READWRITE: ::c_int = 0x00000070; +pub const CTLFLAG_ANYWRITE: ::c_int = 0x00000080; +pub const CTLFLAG_PRIVATE: ::c_int = 0x00000100; +pub const CTLFLAG_PERMANENT: ::c_int = 0x00000200; +pub const CTLFLAG_OWNDATA: ::c_int = 0x00000400; +pub const CTLFLAG_IMMEDIATE: ::c_int = 0x00000800; +pub const CTLFLAG_HEX: ::c_int = 0x00001000; +pub const CTLFLAG_ROOT: ::c_int = 0x00002000; +pub const CTLFLAG_ANYNUMBER: ::c_int = 0x00004000; +pub const CTLFLAG_HIDDEN: ::c_int = 0x00008000; +pub const CTLFLAG_ALIAS: ::c_int = 0x00010000; +pub const CTLFLAG_MMAP: ::c_int = 0x00020000; +pub const CTLFLAG_OWNDESC: ::c_int = 0x00040000; +pub const CTLFLAG_UNSIGNED: ::c_int = 0x00080000; +pub const SYSCTL_VERS_MASK: ::c_int = 0xff000000; +pub const SYSCTL_VERS_0: ::c_int = 0x00000000; +pub const SYSCTL_VERS_1: ::c_int = 0x01000000; +pub const SYSCTL_VERSION: ::c_int = SYSCTL_VERS_1; +pub const CTL_EOL: ::c_int = -1; +pub const CTL_QUERY: ::c_int = -2; +pub const CTL_CREATE: ::c_int = -3; +pub const CTL_CREATESYM: ::c_int = -4; +pub const CTL_DESTROY: ::c_int = -5; +pub const CTL_MMAP: ::c_int = -6; +pub const CTL_DESCRIBE: ::c_int = -7; +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_VFS: ::c_int = 3; +pub const CTL_NET: ::c_int = 4; +pub const CTL_DEBUG: ::c_int = 5; +pub const CTL_HW: ::c_int = 6; +pub const CTL_MACHDEP: ::c_int = 7; +pub const CTL_USER: ::c_int = 8; +pub const CTL_DDB: ::c_int = 9; +pub const CTL_PROC: ::c_int = 10; +pub const CTL_VENDOR: ::c_int = 11; +pub const CTL_EMUL: ::c_int = 12; +pub const CTL_SECURITY: ::c_int = 13; +pub const CTL_MAXID: ::c_int = 14; +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_OBOOTTIME: ::c_int = 21; +pub const KERN_DOMAINNAME: ::c_int = 22; +pub const KERN_MAXPARTITIONS: ::c_int = 23; +pub const KERN_RAWPARTITION: ::c_int = 24; +pub const KERN_NTPTIME: ::c_int = 25; +pub const KERN_TIMEX: ::c_int = 26; +pub const KERN_AUTONICETIME: ::c_int = 27; +pub const KERN_AUTONICEVAL: ::c_int = 28; +pub const KERN_RTC_OFFSET: ::c_int = 29; +pub const KERN_ROOT_DEVICE: ::c_int = 30; +pub const KERN_MSGBUFSIZE: ::c_int = 31; +pub const KERN_FSYNC: ::c_int = 32; +pub const KERN_OLDSYSVMSG: ::c_int = 33; +pub const KERN_OLDSYSVSEM: ::c_int = 34; +pub const KERN_OLDSYSVSHM: ::c_int = 35; +pub const KERN_OLDSHORTCORENAME: ::c_int = 36; +pub const KERN_SYNCHRONIZED_IO: ::c_int = 37; +pub const KERN_IOV_MAX: ::c_int = 38; +pub const KERN_MBUF: ::c_int = 39; +pub const KERN_MAPPED_FILES: ::c_int = 40; +pub const KERN_MEMLOCK: ::c_int = 41; +pub const KERN_MEMLOCK_RANGE: ::c_int = 42; +pub const KERN_MEMORY_PROTECTION: ::c_int = 43; +pub const KERN_LOGIN_NAME_MAX: ::c_int = 44; +pub const KERN_DEFCORENAME: ::c_int = 45; +pub const KERN_LOGSIGEXIT: ::c_int = 46; +pub const KERN_PROC2: ::c_int = 47; +pub const KERN_PROC_ARGS: ::c_int = 48; +pub const KERN_FSCALE: ::c_int = 49; +pub const KERN_CCPU: ::c_int = 50; +pub const KERN_CP_TIME: ::c_int = 51; +pub const KERN_OLDSYSVIPC_INFO: ::c_int = 52; +pub const KERN_MSGBUF: ::c_int = 53; +pub const KERN_CONSDEV: ::c_int = 54; +pub const KERN_MAXPTYS: ::c_int = 55; +pub const KERN_PIPE: ::c_int = 56; +pub const KERN_MAXPHYS: ::c_int = 57; +pub const KERN_SBMAX: ::c_int = 58; +pub const KERN_TKSTAT: ::c_int = 59; +pub const KERN_MONOTONIC_CLOCK: ::c_int = 60; +pub const KERN_URND: ::c_int = 61; +pub const KERN_LABELSECTOR: ::c_int = 62; +pub const KERN_LABELOFFSET: ::c_int = 63; +pub const KERN_LWP: ::c_int = 64; +pub const KERN_FORKFSLEEP: ::c_int = 65; +pub const KERN_POSIX_THREADS: ::c_int = 66; +pub const KERN_POSIX_SEMAPHORES: ::c_int = 67; +pub const KERN_POSIX_BARRIERS: ::c_int = 68; +pub const KERN_POSIX_TIMERS: ::c_int = 69; +pub const KERN_POSIX_SPIN_LOCKS: ::c_int = 70; +pub const KERN_POSIX_READER_WRITER_LOCKS: ::c_int = 71; +pub const KERN_DUMP_ON_PANIC: ::c_int = 72; +pub const KERN_SOMAXKVA: ::c_int = 73; +pub const KERN_ROOT_PARTITION: ::c_int = 74; +pub const KERN_DRIVERS: ::c_int = 75; +pub const KERN_BUF: ::c_int = 76; +pub const KERN_FILE2: ::c_int = 77; +pub const KERN_VERIEXEC: ::c_int = 78; +pub const KERN_CP_ID: ::c_int = 79; +pub const KERN_HARDCLOCK_TICKS: ::c_int = 80; +pub const KERN_ARND: ::c_int = 81; +pub const KERN_SYSVIPC: ::c_int = 82; +pub const KERN_BOOTTIME: ::c_int = 83; +pub const KERN_EVCNT: ::c_int = 84; +pub const KERN_MAXID: ::c_int = 85; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +pub const KERN_PROC_SESSION: ::c_int = 3; +pub const KERN_PROC_TTY: ::c_int = 4; +pub const KERN_PROC_UID: ::c_int = 5; +pub const KERN_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_GID: ::c_int = 7; +pub const KERN_PROC_RGID: ::c_int = 8; +pub const KERN_PROC_ARGV: ::c_int = 1; +pub const KERN_PROC_NARGV: ::c_int = 2; +pub const KERN_PROC_ENV: ::c_int = 3; +pub const KERN_PROC_NENV: ::c_int = 4; +pub const KERN_PROC_PATHNAME: ::c_int = 5; +pub const VM_PROC: ::c_int = 16; +pub const VM_PROC_MAP: ::c_int = 1; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 14; + +pub const AIO_CANCELED: ::c_int = 1; +pub const AIO_NOTCANCELED: ::c_int = 2; +pub const AIO_ALLDONE: ::c_int = 3; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_READ: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 1; +pub const LIO_NOWAIT: ::c_int = 0; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const WSTOPPED: ::c_int = 0x00000002; // same as WUNTRACED +pub const WCONTINUED: ::c_int = 0x00000010; +pub const WEXITED: ::c_int = 0x000000020; +pub const WNOWAIT: ::c_int = 0x00010000; + +pub const WALTSIG: ::c_int = 0x00000004; +pub const WALLSIG: ::c_int = 0x00000008; +pub const WTRAPPED: ::c_int = 0x00000040; +pub const WNOZOMBIE: ::c_int = 0x00020000; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 4; + +pub const UTIME_OMIT: c_long = 1073741822; +pub const UTIME_NOW: c_long = 1073741823; + +pub const B460800: ::speed_t = 460800; +pub const B921600: ::speed_t = 921600; + +pub const ONOCR: ::tcflag_t = 0x20; +pub const ONLRET: ::tcflag_t = 0x40; +pub const CDTRCTS: ::tcflag_t = 0x00020000; +pub const CHWFLOW: ::tcflag_t = ::MDMBUF | ::CRTSCTS | ::CDTRCTS; + +// pub const _PATH_UTMPX: &[::c_char; 14] = b"/var/run/utmpx"; +// pub const _PATH_WTMPX: &[::c_char; 14] = b"/var/log/wtmpx"; +// pub const _PATH_LASTLOGX: &[::c_char; 17] = b"/var/log/lastlogx"; +// pub const _PATH_UTMP_UPDATE: &[::c_char; 24] = b"/usr/libexec/utmp_update"; +pub const UT_NAMESIZE: usize = 8; +pub const UT_LINESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 16; +pub const _UTX_USERSIZE: usize = 32; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_PADSIZE: usize = 40; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 256; +pub const EMPTY: u16 = 0; +pub const RUN_LVL: u16 = 1; +pub const BOOT_TIME: u16 = 2; +pub const OLD_TIME: u16 = 3; +pub const NEW_TIME: u16 = 4; +pub const INIT_PROCESS: u16 = 5; +pub const LOGIN_PROCESS: u16 = 6; +pub const USER_PROCESS: u16 = 7; +pub const DEAD_PROCESS: u16 = 8; +pub const ACCOUNTING: u16 = 9; +pub const SIGNATURE: u16 = 10; +pub const DOWN_TIME: u16 = 11; + +pub const SOCK_CLOEXEC: ::c_int = 0x10000000; +pub const SOCK_NONBLOCK: ::c_int = 0x20000000; + +// Uncomment on next NetBSD release +// pub const FIOSEEKDATA: ::c_ulong = 0xc0086661; +// pub const FIOSEEKHOLE: ::c_ulong = 0xc0086662; +pub const OFIOGETBMAP: ::c_ulong = 0xc004667a; +pub const FIOGETBMAP: ::c_ulong = 0xc008667a; +pub const FIONWRITE: ::c_ulong = 0x40046679; +pub const FIONSPACE: ::c_ulong = 0x40046678; +pub const FIBMAP: ::c_ulong = 0xc008667a; + +pub const SIGSTKSZ: ::size_t = 40960; + +pub const REG_ENOSYS: ::c_int = 17; + +pub const PT_DUMPCORE: ::c_int = 12; +pub const PT_LWPINFO: ::c_int = 13; +pub const PT_SYSCALL: ::c_int = 14; +pub const PT_SYSCALLEMU: ::c_int = 15; +pub const PT_SET_EVENT_MASK: ::c_int = 16; +pub const PT_GET_EVENT_MASK: ::c_int = 17; +pub const PT_GET_PROCESS_STATE: ::c_int = 18; +pub const PT_SET_SIGINFO: ::c_int = 19; +pub const PT_GET_SIGINFO: ::c_int = 20; +pub const PT_RESUME: ::c_int = 21; +pub const PT_SUSPEND: ::c_int = 23; +pub const PT_STOP: ::c_int = 23; +pub const PT_LWPSTATUS: ::c_int = 24; +pub const PT_LWPNEXT: ::c_int = 25; +pub const PT_SET_SIGPASS: ::c_int = 26; +pub const PT_GET_SIGPASS: ::c_int = 27; +pub const PT_FIRSTMACH: ::c_int = 32; +pub const POSIX_SPAWN_RETURNERROR: ::c_int = 0x40; + +// Flags for chflags(2) +pub const SF_APPEND: ::c_ulong = 0x00040000; +pub const SF_ARCHIVED: ::c_ulong = 0x00010000; +pub const SF_IMMUTABLE: ::c_ulong = 0x00020000; +pub const SF_LOG: ::c_ulong = 0x00400000; +pub const SF_SETTABLE: ::c_ulong = 0xffff0000; +pub const SF_SNAPINVAL: ::c_ulong = 0x00800000; +pub const SF_SNAPSHOT: ::c_ulong = 0x00200000; +pub const UF_APPEND: ::c_ulong = 0x00000004; +pub const UF_IMMUTABLE: ::c_ulong = 0x00000002; +pub const UF_NODUMP: ::c_ulong = 0x00000001; +pub const UF_OPAQUE: ::c_ulong = 0x00000008; +pub const UF_SETTABLE: ::c_ulong = 0x0000ffff; + +// sys/sysctl.h +pub const KVME_PROT_READ: ::c_int = 0x00000001; +pub const KVME_PROT_WRITE: ::c_int = 0x00000002; +pub const KVME_PROT_EXEC: ::c_int = 0x00000004; + +pub const KVME_FLAG_COW: ::c_int = 0x00000001; +pub const KVME_FLAG_NEEDS_COPY: ::c_int = 0x00000002; +pub const KVME_FLAG_NOCOREDUMP: ::c_int = 0x000000004; +pub const KVME_FLAG_PAGEABLE: ::c_int = 0x000000008; +pub const KVME_FLAG_GROWS_UP: ::c_int = 0x000000010; +pub const KVME_FLAG_GROWS_DOWN: ::c_int = 0x000000020; + +pub const NGROUPS_MAX: ::c_int = 16; + +pub const KI_NGROUPS: ::c_int = 16; +pub const KI_MAXCOMLEN: ::c_int = 24; +pub const KI_WMESGLEN: ::c_int = 8; +pub const KI_MAXLOGNAME: ::c_int = 24; +pub const KI_MAXEMULLEN: ::c_int = 16; +pub const KI_LNAMELEN: ::c_int = 20; + +// sys/lwp.h +pub const LSIDL: ::c_int = 1; +pub const LSRUN: ::c_int = 2; +pub const LSSLEEP: ::c_int = 3; +pub const LSSTOP: ::c_int = 4; +pub const LSZOMB: ::c_int = 5; +pub const LSONPROC: ::c_int = 7; +pub const LSSUSPENDED: ::c_int = 8; + +// sys/xattr.h +pub const XATTR_CREATE: ::c_int = 0x01; +pub const XATTR_REPLACE: ::c_int = 0x02; +// sys/extattr.h +pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; + +// For getrandom() +pub const GRND_NONBLOCK: ::c_uint = 0x1; +pub const GRND_RANDOM: ::c_uint = 0x2; +pub const GRND_INSECURE: ::c_uint = 0x4; + +// sys/reboot.h +pub const RB_ASKNAME: ::c_int = 0x000000001; +pub const RB_SINGLE: ::c_int = 0x000000002; +pub const RB_NOSYNC: ::c_int = 0x000000004; +pub const RB_HALT: ::c_int = 0x000000008; +pub const RB_INITNAME: ::c_int = 0x000000010; +pub const RB_KDB: ::c_int = 0x000000040; +pub const RB_RDONLY: ::c_int = 0x000000080; +pub const RB_DUMP: ::c_int = 0x000000100; +pub const RB_MINIROOT: ::c_int = 0x000000200; +pub const RB_STRING: ::c_int = 0x000000400; +pub const RB_POWERDOWN: ::c_int = RB_HALT | 0x000000800; +pub const RB_USERCONF: ::c_int = 0x000001000; + +cfg_if! { + + if #[cfg(libc_const_extern_fn)] { + pub const fn MAP_ALIGNED(alignment: ::c_int) -> ::c_int { + alignment << MAP_ALIGNMENT_SHIFT + } + } else { + pub fn MAP_ALIGNED(alignment: ::c_int) -> ::c_int { + alignment << MAP_ALIGNMENT_SHIFT + } + } +} + +const_fn! { + {const} fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + // dirfd() is a macro on netbsd to access + // the first field of the struct where dirp points to: + // http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36 + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int { + *(dirp as *const ::c_int) + } + + pub fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { + ngrps - 1 + } else { + 0 + }; + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps + } + + pub fn PROT_MPROTECT(x: ::c_int) -> ::c_int { + x << 3 + } + + pub fn PROT_MPROTECT_EXTRACT(x: ::c_int) -> ::c_int { + (x >> 3) & 0x7 + } + + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev as u32) & 0x000fff00) >> 8) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + let mut res = 0; + res |= ((dev as u32) & 0xfff00000) >> 12; + res |= (dev as u32) & 0x000000ff; + res as ::c_int + } +} + +safe_f! { + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0o177) == 0o177 + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major << 8) & 0x000ff00; + dev |= (minor << 12) & 0xfff00000; + dev |= minor & 0xff; + dev + } +} + +extern "C" { + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + + pub fn reallocarr(ptr: *mut ::c_void, number: ::size_t, size: ::size_t) -> ::c_int; + + pub fn chflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + pub fn fchflags(fd: ::c_int, flags: ::c_ulong) -> ::c_int; + pub fn lchflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + + pub fn extattr_list_fd( + fd: ::c_int, + attrnamespace: ::c_int, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_list_file( + path: *const ::c_char, + attrnamespace: ::c_int, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_list_link( + path: *const ::c_char, + attrnamespace: ::c_int, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_delete_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_get_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_namespace_to_string( + attrnamespace: ::c_int, + string: *mut *mut ::c_char, + ) -> ::c_int; + pub fn extattr_set_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::c_int; + pub fn extattr_set_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::c_int; + pub fn extattr_set_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::c_int; + pub fn extattr_string_to_namespace( + string: *const ::c_char, + attrnamespace: *mut ::c_int, + ) -> ::c_int; + + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut ::termios, + winp: *mut ::winsize, + ) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *mut ::termios, + winp: *mut ::winsize, + ) -> ::pid_t; + + #[link_name = "__lutimes50"] + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + #[link_name = "__gettimeofday50"] + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn sysctl( + name: *const ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlbyname( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + #[link_name = "__kevent50"] + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::size_t, + eventlist: *mut ::kevent, + nevents: ::size_t, + timeout: *const ::timespec, + ) -> ::c_int; + #[link_name = "__mount50"] + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + flags: ::c_int, + data: *mut ::c_void, + size: ::size_t, + ) -> ::c_int; + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_notify(mqd: ::mqd_t, notification: *const ::sigevent) -> ::c_int; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; + #[link_name = "__mq_timedreceive50"] + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + #[link_name = "__mq_timedsend50"] + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_void, data: ::c_int) -> ::c_int; + pub fn utrace(label: *const ::c_char, addr: *mut ::c_void, len: ::size_t) -> ::c_int; + pub fn pthread_getname_np(t: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_setname_np( + t: ::pthread_t, + name: *const ::c_char, + arg: *const ::c_void, + ) -> ::c_int; + pub fn pthread_attr_get_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_getaffinity_np( + thread: ::pthread_t, + size: ::size_t, + set: *mut cpuset_t, + ) -> ::c_int; + pub fn pthread_setaffinity_np( + thread: ::pthread_t, + size: ::size_t, + set: *mut cpuset_t, + ) -> ::c_int; + + pub fn _cpuset_create() -> *mut cpuset_t; + pub fn _cpuset_destroy(set: *mut cpuset_t); + pub fn _cpuset_clr(cpu: cpuid_t, set: *mut cpuset_t) -> ::c_int; + pub fn _cpuset_set(cpu: cpuid_t, set: *mut cpuset_t) -> ::c_int; + pub fn _cpuset_isset(cpu: cpuid_t, set: *const cpuset_t) -> ::c_int; + pub fn _cpuset_size(set: *const cpuset_t) -> ::size_t; + pub fn _cpuset_zero(set: *mut cpuset_t); + #[link_name = "__sigtimedwait50"] + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn localeconv_l(loc: ::locale_t) -> *mut lconv; + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + #[link_name = "__settimeofday50"] + pub fn settimeofday(tv: *const ::timeval, tz: *const ::c_void) -> ::c_int; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + + pub fn kqueue1(flags: ::c_int) -> ::c_int; + + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + + pub fn _lwp_self() -> lwpid_t; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + + // link.h + + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + // dlfcn.h + + pub fn _dlauxinfo() -> *mut ::c_void; + + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; + + pub fn timer_create( + clockid: ::clockid_t, + sevp: *mut ::sigevent, + timerid: *mut ::timer_t, + ) -> ::c_int; + pub fn timer_delete(timerid: ::timer_t) -> ::c_int; + pub fn timer_getoverrun(timerid: ::timer_t) -> ::c_int; + pub fn timer_gettime(timerid: ::timer_t, curr_value: *mut ::itimerspec) -> ::c_int; + pub fn timer_settime( + timerid: ::timer_t, + flags: ::c_int, + new_value: *const ::itimerspec, + old_value: *mut ::itimerspec, + ) -> ::c_int; + + // Added in `NetBSD` 7.0 + pub fn explicit_memset(b: *mut ::c_void, c: ::c_int, len: ::size_t); + pub fn consttime_memequal(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; + + pub fn setproctitle(fmt: *const ::c_char, ...); + pub fn mremap( + oldp: *mut ::c_void, + oldsize: ::size_t, + newp: *mut ::c_void, + newsize: ::size_t, + flags: ::c_int, + ) -> *mut ::c_void; + + pub fn sched_rr_get_interval(pid: ::pid_t, t: *mut ::timespec) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + + #[link_name = "__pollts50"] + pub fn pollts( + fds: *mut ::pollfd, + nfds: ::nfds_t, + ts: *const ::timespec, + sigmask: *const ::sigset_t, + ) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: ::nfds_t, + ts: *const ::timespec, + sigmask: *const ::sigset_t, + ) -> ::c_int; + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + + pub fn reboot(mode: ::c_int, bootstr: *mut ::c_char) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + #[link_name = "__aio_suspend50"] + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; +} + +#[link(name = "util")] +extern "C" { + #[cfg_attr(target_os = "netbsd", link_name = "__getpwent_r50")] + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + + pub fn updwtmpx(file: *const ::c_char, ut: *const utmpx) -> ::c_int; + pub fn getlastlogx(fname: *const ::c_char, uid: ::uid_t, ll: *mut lastlogx) -> *mut lastlogx; + pub fn updlastlogx(fname: *const ::c_char, uid: ::uid_t, ll: *mut lastlogx) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); + + pub fn getutmp(ux: *const utmpx, u: *mut utmp); + pub fn getutmpx(u: *const utmp, ux: *mut utmpx); + + pub fn utpname(file: *const ::c_char) -> ::c_int; + pub fn setutent(); + pub fn endutent(); + pub fn getutent() -> *mut utmp; + + pub fn efopen(p: *const ::c_char, m: *const ::c_char) -> ::FILE; + pub fn emalloc(n: ::size_t) -> *mut ::c_void; + pub fn ecalloc(n: ::size_t, c: ::size_t) -> *mut ::c_void; + pub fn erealloc(p: *mut ::c_void, n: ::size_t) -> *mut ::c_void; + pub fn ereallocarr(p: *mut ::c_void, n: ::size_t, s: ::size_t); + pub fn estrdup(s: *const ::c_char) -> *mut ::c_char; + pub fn estrndup(s: *const ::c_char, len: ::size_t) -> *mut ::c_char; + pub fn estrlcpy(dst: *mut ::c_char, src: *const ::c_char, len: ::size_t) -> ::size_t; + pub fn estrlcat(dst: *mut ::c_char, src: *const ::c_char, len: ::size_t) -> ::size_t; + pub fn estrtoi( + nptr: *const ::c_char, + base: ::c_int, + lo: ::intmax_t, + hi: ::intmax_t, + ) -> ::intmax_t; + pub fn estrtou( + nptr: *const ::c_char, + base: ::c_int, + lo: ::uintmax_t, + hi: ::uintmax_t, + ) -> ::uintmax_t; + pub fn easprintf(string: *mut *mut ::c_char, fmt: *const ::c_char, ...) -> ::c_int; + pub fn evasprintf(string: *mut *mut ::c_char, fmt: *const ::c_char, ...) -> ::c_int; + pub fn esetfunc( + cb: ::Option, + ) -> ::Option; + pub fn secure_path(path: *const ::c_char) -> ::c_int; + pub fn snprintb( + buf: *mut ::c_char, + buflen: ::size_t, + fmt: *const ::c_char, + val: u64, + ) -> ::c_int; + pub fn snprintb_m( + buf: *mut ::c_char, + buflen: ::size_t, + fmt: *const ::c_char, + val: u64, + max: ::size_t, + ) -> ::c_int; + + pub fn getbootfile() -> *const ::c_char; + pub fn getbyteorder() -> ::c_int; + pub fn getdiskrawname( + buf: *mut ::c_char, + buflen: ::size_t, + name: *const ::c_char, + ) -> *const ::c_char; + pub fn getdiskcookedname( + buf: *mut ::c_char, + buflen: ::size_t, + name: *const ::c_char, + ) -> *const ::c_char; + pub fn getfsspecname( + buf: *mut ::c_char, + buflen: ::size_t, + spec: *const ::c_char, + ) -> *const ::c_char; + + pub fn strpct( + buf: *mut ::c_char, + bufsiz: ::size_t, + numerator: ::uintmax_t, + denominator: ::uintmax_t, + precision: ::size_t, + ) -> *mut ::c_char; + pub fn strspct( + buf: *mut ::c_char, + bufsiz: ::size_t, + numerator: ::intmax_t, + denominator: ::intmax_t, + precision: ::size_t, + ) -> *mut ::c_char; + #[link_name = "__login50"] + pub fn login(ut: *const utmp); + #[link_name = "__loginx50"] + pub fn loginx(ut: *const utmpx); + pub fn logout(line: *const ::c_char); + pub fn logoutx(line: *const ::c_char, status: ::c_int, tpe: ::c_int); + pub fn logwtmp(line: *const ::c_char, name: *const ::c_char, host: *const ::c_char); + pub fn logwtmpx( + line: *const ::c_char, + name: *const ::c_char, + host: *const ::c_char, + status: ::c_int, + tpe: ::c_int, + ); + + pub fn getxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn lgetxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn fgetxattr( + filedes: ::c_int, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn setxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + ) -> ::c_int; + pub fn lsetxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + ) -> ::c_int; + pub fn fsetxattr( + filedes: ::c_int, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn listxattr(path: *const ::c_char, list: *mut ::c_char, size: ::size_t) -> ::ssize_t; + pub fn llistxattr(path: *const ::c_char, list: *mut ::c_char, size: ::size_t) -> ::ssize_t; + pub fn flistxattr(filedes: ::c_int, list: *mut ::c_char, size: ::size_t) -> ::ssize_t; + pub fn removexattr(path: *const ::c_char, name: *const ::c_char) -> ::c_int; + pub fn lremovexattr(path: *const ::c_char, name: *const ::c_char) -> ::c_int; + pub fn fremovexattr(fd: ::c_int, path: *const ::c_char, name: *const ::c_char) -> ::c_int; + + pub fn string_to_flags( + string_p: *mut *mut ::c_char, + setp: *mut ::c_ulong, + clrp: *mut ::c_ulong, + ) -> ::c_int; + pub fn flags_to_string(flags: ::c_ulong, def: *const ::c_char) -> ::c_int; + + pub fn kinfo_getvmmap(pid: ::pid_t, cntp: *mut ::size_t) -> *mut kinfo_vmentry; +} + +#[link(name = "execinfo")] +extern "C" { + pub fn backtrace(addrlist: *mut *mut ::c_void, len: ::size_t) -> ::size_t; + pub fn backtrace_symbols(addrlist: *const *mut ::c_void, len: ::size_t) -> *mut *mut ::c_char; + pub fn backtrace_symbols_fd( + addrlist: *const *mut ::c_void, + len: ::size_t, + fd: ::c_int, + ) -> ::c_int; + pub fn backtrace_symbols_fmt( + addrlist: *const *mut ::c_void, + len: ::size_t, + fmt: *const ::c_char, + ) -> *mut *mut ::c_char; + pub fn backtrace_symbols_fd_fmt( + addrlist: *const *mut ::c_void, + len: ::size_t, + fd: ::c_int, + fmt: *const ::c_char, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_union)] { + extern { + // these functions use statvfs: + pub fn getmntinfo(mntbufp: *mut *mut ::statvfs, flags: ::c_int) -> ::c_int; + pub fn getvfsstat(buf: *mut statvfs, bufsize: ::size_t, flags: ::c_int) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(target_arch = "sparc64")] { + mod sparc64; + pub use self::sparc64::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "mips")] { + mod mips; + pub use self::mips::*; + } else if #[cfg(target_arch = "riscv64")] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs new file mode 100644 index 00000000..e12fd5e1 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs @@ -0,0 +1,21 @@ +use PT_FIRSTMACH; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = u8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs new file mode 100644 index 00000000..bc09149e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs @@ -0,0 +1,21 @@ +use PT_FIRSTMACH; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 3; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs new file mode 100644 index 00000000..6a86759e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs @@ -0,0 +1,8 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +// should be pub(crate), but that requires Rust 1.18.0 +#[doc(hidden)] +pub const _ALIGNBYTES: usize = 0xf; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs new file mode 100644 index 00000000..daa89a11 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs @@ -0,0 +1,15 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = i8; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs new file mode 100644 index 00000000..ba259074 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs @@ -0,0 +1,67 @@ +use PT_FIRSTMACH; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type c___greg_t = u64; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +s! { + pub struct mcontext_t { + pub __gregs: [c___greg_t; 26], + pub _mc_tlsbase: c___greg_t, + pub __fpregs: [[::c_char;32]; 16], + } + + pub struct ucontext_t { + pub uc_flags: ::c_uint, + pub uc_link: *mut ::ucontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: ::mcontext_t, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; + +pub const _REG_RDI: ::c_int = 0; +pub const _REG_RSI: ::c_int = 1; +pub const _REG_RDX: ::c_int = 2; +pub const _REG_RCX: ::c_int = 3; +pub const _REG_R8: ::c_int = 4; +pub const _REG_R9: ::c_int = 5; +pub const _REG_R10: ::c_int = 6; +pub const _REG_R11: ::c_int = 7; +pub const _REG_R12: ::c_int = 8; +pub const _REG_R13: ::c_int = 9; +pub const _REG_R14: ::c_int = 10; +pub const _REG_R15: ::c_int = 11; +pub const _REG_RBP: ::c_int = 12; +pub const _REG_RBX: ::c_int = 13; +pub const _REG_RAX: ::c_int = 14; +pub const _REG_GS: ::c_int = 15; +pub const _REG_FS: ::c_int = 16; +pub const _REG_ES: ::c_int = 17; +pub const _REG_DS: ::c_int = 18; +pub const _REG_TRAPNO: ::c_int = 19; +pub const _REG_ERR: ::c_int = 20; +pub const _REG_RIP: ::c_int = 21; +pub const _REG_CS: ::c_int = 22; +pub const _REG_RFLAGS: ::c_int = 23; +pub const _REG_RSP: ::c_int = 24; +pub const _REG_SS: ::c_int = 25; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs new file mode 100644 index 00000000..2bc82e48 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs @@ -0,0 +1,30 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type ucontext_t = sigcontext; + +s! { + pub struct sigcontext { + __sc_unused: ::c_int, + pub sc_mask: ::c_int, + pub sc_sp: ::c_ulong, + pub sc_lr: ::c_ulong, + pub sc_elr: ::c_ulong, + pub sc_spsr: ::c_ulong, + pub sc_x: [::c_ulong; 30], + pub sc_cookie: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs new file mode 100644 index 00000000..f1ab365d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs @@ -0,0 +1,16 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = u8; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs new file mode 100644 index 00000000..15803ced --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs @@ -0,0 +1,8 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; + +#[doc(hidden)] +pub const _ALIGNBYTES: usize = 7; + +pub const _MAX_PAGE_SHIFT: u32 = 14; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs new file mode 100644 index 00000000..8f470aff --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs @@ -0,0 +1,2209 @@ +use unix::bsd::O_SYNC; + +pub type clock_t = i64; +pub type suseconds_t = ::c_long; +pub type dev_t = i32; +pub type sigset_t = ::c_uint; +pub type blksize_t = i32; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type idtype_t = ::c_uint; +pub type pthread_attr_t = *mut ::c_void; +pub type pthread_mutex_t = *mut ::c_void; +pub type pthread_mutexattr_t = *mut ::c_void; +pub type pthread_cond_t = *mut ::c_void; +pub type pthread_condattr_t = *mut ::c_void; +pub type pthread_rwlock_t = *mut ::c_void; +pub type pthread_rwlockattr_t = *mut ::c_void; +pub type pthread_spinlock_t = ::uintptr_t; +pub type caddr_t = *mut ::c_char; + +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Lword = u64; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +// search.h + +pub type ENTRY = entry; +pub type ACTION = ::c_uint; + +// spawn.h +pub type posix_spawnattr_t = *mut ::c_void; +pub type posix_spawn_file_actions_t = *mut ::c_void; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +s! { + pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::c_int, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct ufs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + } + + pub struct mfs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + // https://github.com/openbsd/src/blob/HEAD/sys/sys/types.h#L134 + pub base: *mut ::c_char, + pub size: ::c_ulong, + } + + pub struct iso_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + pub flags: ::c_int, + pub sess: ::c_int, + } + + pub struct nfs_args { + pub version: ::c_int, + pub addr: *mut ::sockaddr, + pub addrlen: ::c_int, + pub sotype: ::c_int, + pub proto: ::c_int, + pub fh: *mut ::c_uchar, + pub fhsize: ::c_int, + pub flags: ::c_int, + pub wsize: ::c_int, + pub rsize: ::c_int, + pub readdirsize: ::c_int, + pub timeo: ::c_int, + pub retrans: ::c_int, + pub maxgrouplist: ::c_int, + pub readahead: ::c_int, + pub leaseterm: ::c_int, + pub deadthresh: ::c_int, + pub hostname: *mut ::c_char, + pub acregmin: ::c_int, + pub acregmax: ::c_int, + pub acdirmin: ::c_int, + pub acdirmax: ::c_int, + } + + pub struct msdosfs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mask: ::mode_t, + pub flags: ::c_int, + } + + pub struct ntfs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mode: ::mode_t, + pub flag: ::c_ulong, + } + + pub struct udf_args { + pub fspec: *mut ::c_char, + pub lastblock: u32, + } + + pub struct tmpfs_args { + pub ta_version: ::c_int, + pub ta_nodes_max: ::ino_t, + pub ta_size_max: ::off_t, + pub ta_root_uid: ::uid_t, + pub ta_root_gid: ::gid_t, + pub ta_root_mode: ::mode_t, + } + + pub struct fusefs_args { + pub name: *mut ::c_char, + pub fd: ::c_int, + pub max_read: ::c_int, + pub allow_other: ::c_int, + } + + pub struct xucred { + pub cr_uid: ::uid_t, + pub cr_gid: ::gid_t, + pub cr_ngroups: ::c_short, + //https://github.com/openbsd/src/blob/HEAD/sys/sys/syslimits.h#L44 + pub cr_groups: [::gid_t; 16], + } + + pub struct export_args { + pub ex_flags: ::c_int, + pub ex_root: ::uid_t, + pub ex_anon: xucred, + pub ex_addr: *mut ::sockaddr, + pub ex_addrlen: ::c_int, + pub ex_mask: *mut ::sockaddr, + pub ex_masklen: ::c_int, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [i8; 8], + } + + pub struct splice { + pub sp_fd: ::c_int, + pub sp_max: ::off_t, + pub sp_idle: ::timeval, + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: i64, + pub udata: *mut ::c_void, + } + + pub struct stat { + pub st_mode: ::mode_t, + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: u32, + pub st_gen: u32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_addr: *mut ::sockaddr, + pub ai_canonname: *mut ::c_char, + pub ai_next: *mut ::addrinfo, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct if_data { + pub ifi_type: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_link_state: ::c_uchar, + pub ifi_mtu: u32, + pub ifi_metric: u32, + pub ifi_rdomain: u32, + pub ifi_baudrate: u64, + pub ifi_ipackets: u64, + pub ifi_ierrors: u64, + pub ifi_opackets: u64, + pub ifi_oerrors: u64, + pub ifi_collisions: u64, + pub ifi_ibytes: u64, + pub ifi_obytes: u64, + pub ifi_imcasts: u64, + pub ifi_omcasts: u64, + pub ifi_iqdrops: u64, + pub ifi_oqdrops: u64, + pub ifi_noproto: u64, + pub ifi_capabilities: u32, + pub ifi_lastchange: ::timeval, + } + + pub struct if_msghdr { + pub ifm_msglen: ::c_ushort, + pub ifm_version: ::c_uchar, + pub ifm_type: ::c_uchar, + pub ifm_hdrlen: ::c_ushort, + pub ifm_index: ::c_ushort, + pub ifm_tableid: ::c_ushort, + pub ifm_pad1: ::c_uchar, + pub ifm_pad2: ::c_uchar, + pub ifm_addrs: ::c_int, + pub ifm_flags: ::c_int, + pub ifm_xflags: ::c_int, + pub ifm_data: if_data, + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 24], + } + + pub struct sockpeercred { + pub uid: ::uid_t, + pub gid: ::gid_t, + pub pid: ::pid_t, + } + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::c_int, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::c_short, + pub shm_atime: ::time_t, + __shm_atimensec: c_long, + pub shm_dtime: ::time_t, + __shm_dtimensec: c_long, + pub shm_ctime: ::time_t, + __shm_ctimensec: c_long, + pub shm_internal: *mut ::c_void, + } + + // elf.h + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + } + + // sys/sysctl.h + pub struct kinfo_proc { + pub p_forw: u64, + pub p_back: u64, + pub p_paddr: u64, + pub p_addr: u64, + pub p_fd: u64, + pub p_stats: u64, + pub p_limit: u64, + pub p_vmspace: u64, + pub p_sigacts: u64, + pub p_sess: u64, + pub p_tsess: u64, + pub p_ru: u64, + pub p_eflag: i32, + pub p_exitsig: i32, + pub p_flag: i32, + pub p_pid: i32, + pub p_ppid: i32, + pub p_sid: i32, + pub p__pgid: i32, + pub p_tpgid: i32, + pub p_uid: u32, + pub p_ruid: u32, + pub p_gid: u32, + pub p_rgid: u32, + pub p_groups: [u32; KI_NGROUPS as usize], + pub p_ngroups: i16, + pub p_jobc: i16, + pub p_tdev: u32, + pub p_estcpu: u32, + pub p_rtime_sec: u32, + pub p_rtime_usec: u32, + pub p_cpticks: i32, + pub p_pctcpu: u32, + pub p_swtime: u32, + pub p_slptime: u32, + pub p_schedflags: i32, + pub p_uticks: u64, + pub p_sticks: u64, + pub p_iticks: u64, + pub p_tracep: u64, + pub p_traceflag: i32, + pub p_holdcnt: i32, + pub p_siglist: i32, + pub p_sigmask: u32, + pub p_sigignore: u32, + pub p_sigcatch: u32, + pub p_stat: i8, + pub p_priority: u8, + pub p_usrpri: u8, + pub p_nice: u8, + pub p_xstat: u16, + pub p_spare: u16, + pub p_comm: [::c_char; KI_MAXCOMLEN as usize], + pub p_wmesg: [::c_char; KI_WMESGLEN as usize], + pub p_wchan: u64, + pub p_login: [::c_char; KI_MAXLOGNAME as usize], + pub p_vm_rssize: i32, + pub p_vm_tsize: i32, + pub p_vm_dsize: i32, + pub p_vm_ssize: i32, + pub p_uvalid: i64, + pub p_ustart_sec: u64, + pub p_ustart_usec: u32, + pub p_uutime_sec: u32, + pub p_uutime_usec: u32, + pub p_ustime_sec: u32, + pub p_ustime_usec: u32, + pub p_uru_maxrss: u64, + pub p_uru_ixrss: u64, + pub p_uru_idrss: u64, + pub p_uru_isrss: u64, + pub p_uru_minflt: u64, + pub p_uru_majflt: u64, + pub p_uru_nswap: u64, + pub p_uru_inblock: u64, + pub p_uru_oublock: u64, + pub p_uru_msgsnd: u64, + pub p_uru_msgrcv: u64, + pub p_uru_nsignals: u64, + pub p_uru_nvcsw: u64, + pub p_uru_nivcsw: u64, + pub p_uctime_sec: u32, + pub p_uctime_usec: u32, + pub p_psflags: u32, + pub p_acflag: u32, + pub p_svuid: u32, + pub p_svgid: u32, + pub p_emul: [::c_char; KI_EMULNAMELEN as usize], + pub p_rlim_rss_cur: u64, + pub p_cpuid: u64, + pub p_vm_map_size: u64, + pub p_tid: i32, + pub p_rtableid: u32, + pub p_pledge: u64, + pub p_name: [::c_char; KI_MAXCOMLEN as usize], + } + + pub struct kinfo_vmentry { + pub kve_start: ::c_ulong, + pub kve_end: ::c_ulong, + pub kve_guard: ::c_ulong, + pub kve_fspace: ::c_ulong, + pub kve_fspace_augment: ::c_ulong, + pub kve_offset: u64, + pub kve_wired_count: ::c_int, + pub kve_etype: ::c_int, + pub kve_protection: ::c_int, + pub kve_max_protection: ::c_int, + pub kve_advice: ::c_int, + pub kve_inheritance: ::c_int, + pub kve_flags: u8, + } + + pub struct ptrace_state { + pub pe_report_event: ::c_int, + pub pe_other_pid: ::pid_t, + pub pe_tid: ::pid_t, + } + + pub struct ptrace_thread_state { + pub pts_tid: ::pid_t, + } + + // search.h + pub struct entry { + pub key: *mut ::c_char, + pub data: *mut ::c_void, + } + + pub struct ifreq { + pub ifr_name: [::c_char; ::IFNAMSIZ], + #[cfg(libc_union)] + pub ifr_ifru: __c_anonymous_ifr_ifru, + #[cfg(not(libc_union))] + pub ifr_ifru: ::sockaddr, + } + + pub struct tcp_info { + pub tcpi_state: u8, + pub __tcpi_ca_state: u8, + pub __tcpi_retransmits: u8, + pub __tcpi_probes: u8, + pub __tcpi_backoff: u8, + pub tcpi_options: u8, + pub tcpi_snd_wscale: u8, + pub tcpi_rcv_wscale: u8, + pub tcpi_rto: u32, + pub __tcpi_ato: u32, + pub tcpi_snd_mss: u32, + pub tcpi_rcv_mss: u32, + pub __tcpi_unacked: u32, + pub __tcpi_sacked: u32, + pub __tcpi_lost: u32, + pub __tcpi_retrans: u32, + pub __tcpi_fackets: u32, + pub tcpi_last_data_sent: u32, + pub tcpi_last_ack_sent: u32, + pub tcpi_last_data_recv: u32, + pub tcpi_last_ack_recv: u32, + pub __tcpi_pmtu: u32, + pub __tcpi_rcv_ssthresh: u32, + pub tcpi_rtt: u32, + pub tcpi_rttvar: u32, + pub tcpi_snd_ssthresh: u32, + pub tcpi_snd_cwnd: u32, + pub __tcpi_advmss: u32, + pub __tcpi_reordering: u32, + pub __tcpi_rcv_rtt: u32, + pub tcpi_rcv_space: u32, + pub tcpi_snd_wnd: u32, + pub tcpi_snd_nxt: u32, + pub tcpi_rcv_nxt: u32, + pub tcpi_toe_tid: u32, + pub tcpi_snd_rexmitpack: u32, + pub tcpi_rcv_ooopack: u32, + pub tcpi_snd_zerowin: u32, + pub tcpi_rttmin: u32, + pub tcpi_max_sndwnd: u32, + pub tcpi_rcv_adv: u32, + pub tcpi_rcv_up: u32, + pub tcpi_snd_una: u32, + pub tcpi_snd_up: u32, + pub tcpi_snd_wl1: u32, + pub tcpi_snd_wl2: u32, + pub tcpi_snd_max: u32, + pub tcpi_ts_recent: u32, + pub tcpi_ts_recent_age: u32, + pub tcpi_rfbuf_cnt: u32, + pub tcpi_rfbuf_ts: u32, + pub tcpi_so_rcv_sb_cc: u32, + pub tcpi_so_rcv_sb_hiwat: u32, + pub tcpi_so_rcv_sb_lowat: u32, + pub tcpi_so_rcv_sb_wat: u32, + pub tcpi_so_snd_sb_cc: u32, + pub tcpi_so_snd_sb_hiwat: u32, + pub tcpi_so_snd_sb_lowat: u32, + pub tcpi_so_snd_sb_wat: u32, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_char { + self.si_addr + } + + pub unsafe fn si_code(&self) -> ::c_int { + self.si_code + } + + pub unsafe fn si_errno(&self) -> ::c_int { + self.si_errno + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_code: ::c_int, + _si_errno: ::c_int, + _pad: [::c_int; SI_PAD], + _pid: ::pid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_code: ::c_int, + _si_errno: ::c_int, + _pad: [::c_int; SI_PAD], + _pid: ::pid_t, + _uid: ::uid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._uid + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_code: ::c_int, + _si_errno: ::c_int, + _pad: [::c_int; SI_PAD], + _pid: ::pid_t, + _uid: ::uid_t, + value: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).value + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_namlen: u8, + __d_padding: [u8; 4], + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: i64, + __ss_pad3: [u8; 240], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub si_addr: *mut ::c_char, + #[cfg(target_pointer_width = "32")] + __pad: [u8; 112], + #[cfg(target_pointer_width = "64")] + __pad: [u8; 108], + } + + pub struct lastlog { + ll_time: ::time_t, + ll_line: [::c_char; UT_LINESIZE], + ll_host: [::c_char; UT_HOSTSIZE], + } + + pub struct utmp { + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_name: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_time: ::time_t, + } + + pub union mount_info { + pub ufs_args: ufs_args, + pub mfs_args: mfs_args, + pub nfs_args: nfs_args, + pub iso_args: iso_args, + pub msdosfs_args: msdosfs_args, + pub ntfs_args: ntfs_args, + pub tmpfs_args: tmpfs_args, + align: [::c_char; 160], + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_flags: ::c_short, + pub ifru_metric: ::c_int, + pub ifru_vnetid: i64, + pub ifru_media: u64, + pub ifru_data: ::caddr_t, + pub ifru_index: ::c_uint, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_code == other.si_code + && self.si_errno == other.si_errno + && self.si_addr == other.si_addr + } + } + + impl Eq for siginfo_t {} + + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) + .field("si_addr", &self.si_addr) + .finish() + } + } + + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.hash(state); + self.si_addr.hash(state); + } + } + + impl PartialEq for lastlog { + fn eq(&self, other: &lastlog) -> bool { + self.ll_time == other.ll_time + && self + .ll_line + .iter() + .zip(other.ll_line.iter()) + .all(|(a,b)| a == b) + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlog {} + + impl ::fmt::Debug for lastlog { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlog") + .field("ll_time", &self.ll_time) + // FIXME: .field("ll_line", &self.ll_line) + // FIXME: .field("ll_host", &self.ll_host) + .finish() + } + } + + impl ::hash::Hash for lastlog { + fn hash(&self, state: &mut H) { + self.ll_time.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + } + } + + impl PartialEq for utmp { + fn eq(&self, other: &utmp) -> bool { + self.ut_time == other.ut_time + && self + .ut_line + .iter() + .zip(other.ut_line.iter()) + .all(|(a,b)| a == b) + && self + .ut_name + .iter() + .zip(other.ut_name.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utmp {} + + impl ::fmt::Debug for utmp { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmp") + // FIXME: .field("ut_line", &self.ut_line) + // FIXME: .field("ut_name", &self.ut_name) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_time", &self.ut_time) + .finish() + } + } + + impl ::hash::Hash for utmp { + fn hash(&self, state: &mut H) { + self.ut_line.hash(state); + self.ut_name.hash(state); + self.ut_host.hash(state); + self.ut_time.hash(state); + } + } + + impl PartialEq for mount_info { + fn eq(&self, other: &mount_info) -> bool { + unsafe { + self.align + .iter() + .zip(other.align.iter()) + .all(|(a,b)| a == b) + } + } + } + + impl Eq for mount_info { } + + impl ::fmt::Debug for mount_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mount_info") + // FIXME: .field("align", &self.align) + .finish() + } + } + + impl ::hash::Hash for mount_info { + fn hash(&self, state: &mut H) { + unsafe { self.align.hash(state) }; + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifr_ifru { + fn eq(&self, other: &__c_anonymous_ifr_ifru) -> bool { + unsafe { + self.ifru_addr == other.ifru_addr + && self.ifru_dstaddr == other.ifru_dstaddr + && self.ifru_broadaddr == other.ifru_broadaddr + && self.ifru_flags == other.ifru_flags + && self.ifru_metric == other.ifru_metric + && self.ifru_vnetid == other.ifru_vnetid + && self.ifru_media == other.ifru_media + && self.ifru_data == other.ifru_data + && self.ifru_index == other.ifru_index + } + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifr_ifru {} + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifr_ifru { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__c_anonymous_ifr_ifru") + .field("ifru_addr", unsafe { &self.ifru_addr }) + .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) + .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) + .field("ifru_flags", unsafe { &self.ifru_flags }) + .field("ifru_metric", unsafe { &self.ifru_metric }) + .field("ifru_vnetid", unsafe { &self.ifru_vnetid }) + .field("ifru_media", unsafe { &self.ifru_media }) + .field("ifru_data", unsafe { &self.ifru_data }) + .field("ifru_index", unsafe { &self.ifru_index }) + .finish() + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifr_ifru { + fn hash(&self, state: &mut H) { + unsafe { + self.ifru_addr.hash(state); + self.ifru_dstaddr.hash(state); + self.ifru_broadaddr.hash(state); + self.ifru_flags.hash(state); + self.ifru_metric.hash(state); + self.ifru_vnetid.hash(state); + self.ifru_media.hash(state); + self.ifru_data.hash(state); + self.ifru_index.hash(state); + } + } + } + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + // This type uses the union mount_info: + pub struct statfs { + pub f_flags: u32, + pub f_bsize: u32, + pub f_iosize: u32, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: i64, + pub f_syncwrites: u64, + pub f_syncreads: u64, + pub f_asyncwrites: u64, + pub f_asyncreads: u64, + pub f_fsid: ::fsid_t, + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_ctime: u64, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 90], + pub f_mntfromname: [::c_char; 90], + pub f_mntfromspec: [::c_char; 90], + pub mount_info: mount_info, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_favail == other.f_favail + && self.f_syncwrites == other.f_syncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncwrites == other.f_asyncwrites + && self.f_asyncreads == other.f_asyncreads + && self.f_fsid == other.f_fsid + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_ctime == other.f_ctime + && self.f_fstypename + .iter() + .zip(other.f_fstypename.iter()) + .all(|(a,b)| a == b) + && self.f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self.f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self.f_mntfromspec + .iter() + .zip(other.f_mntfromspec.iter()) + .all(|(a,b)| a == b) + && self.mount_info == other.mount_info + } + } + + impl Eq for statfs { } + + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) + -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_flags", &self.f_flags) + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_favail", &self.f_favail) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_fsid", &self.f_fsid) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_ctime", &self.f_ctime) + // FIXME: .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + // FIXME: .field("f_mntfromspec", &self.f_mntfromspec) + .field("mount_info", &self.mount_info) + .finish() + } + } + + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_favail.hash(state); + self.f_syncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncwrites.hash(state); + self.f_asyncreads.hash(state); + self.f_fsid.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_ctime.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + self.f_mntfromspec.hash(state); + self.mount_info.hash(state); + } + } + } + } + } +} + +pub const UT_NAMESIZE: usize = 32; +pub const UT_LINESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 256; + +pub const O_CLOEXEC: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x20000; +pub const O_RSYNC: ::c_int = O_SYNC; + +pub const MS_SYNC: ::c_int = 0x0002; +pub const MS_INVALIDATE: ::c_int = 0x0004; + +pub const POLLNORM: ::c_short = ::POLLRDNORM; + +pub const ENOATTR: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const EOVERFLOW: ::c_int = 87; +pub const ECANCELED: ::c_int = 88; +pub const EIDRM: ::c_int = 89; +pub const ENOMSG: ::c_int = 90; +pub const ENOTSUP: ::c_int = 91; +pub const EBADMSG: ::c_int = 92; +pub const ENOTRECOVERABLE: ::c_int = 93; +pub const EOWNERDEAD: ::c_int = 94; +pub const EPROTO: ::c_int = 95; +pub const ELAST: ::c_int = 95; + +pub const F_DUPFD_CLOEXEC: ::c_int = 10; + +pub const UTIME_OMIT: c_long = -1; +pub const UTIME_NOW: c_long = -2; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_EACCESS: ::c_int = 0x01; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x02; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x04; +pub const AT_REMOVEDIR: ::c_int = 0x08; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 9; + +pub const SO_TIMESTAMP: ::c_int = 0x0800; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_BINDANY: ::c_int = 0x1000; +pub const SO_NETPROC: ::c_int = 0x1020; +pub const SO_RTABLE: ::c_int = 0x1021; +pub const SO_PEERCRED: ::c_int = 0x1022; +pub const SO_SPLICE: ::c_int = 0x1023; +pub const SO_DOMAIN: ::c_int = 0x1024; +pub const SO_PROTOCOL: ::c_int = 0x1025; + +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// IP Mobility RFC 2004 +pub const IPPROTO_MOBILE: ::c_int = 55; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// Ethernet-in-IP +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// CARP +pub const IPPROTO_CARP: ::c_int = 112; +/// unicast MPLS packet +pub const IPPROTO_MPLS: ::c_int = 137; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; +pub const IPPROTO_MAX: ::c_int = 256; + +// Only used internally, so it can be outside the range of valid IP protocols +pub const IPPROTO_DIVERT: ::c_int = 258; + +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_SENDSRCADDR: ::c_int = IP_RECVDSTADDR; +pub const IP_RECVIF: ::c_int = 30; + +// sys/netinet/in.h +pub const TCP_MD5SIG: ::c_int = 0x04; +pub const TCP_NOPUSH: ::c_int = 0x10; + +pub const MSG_WAITFORONE: ::c_int = 0x1000; + +pub const AF_ECMA: ::c_int = 8; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_ENCAP: ::c_int = 28; +pub const AF_SIP: ::c_int = 29; +pub const AF_KEY: ::c_int = 30; +pub const pseudo_AF_HDRCMPLT: ::c_int = 31; +pub const AF_BLUETOOTH: ::c_int = 32; +pub const AF_MPLS: ::c_int = 33; +pub const pseudo_AF_PFLOW: ::c_int = 34; +pub const pseudo_AF_PIPEX: ::c_int = 35; +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; +pub const NET_RT_STATS: ::c_int = 4; +pub const NET_RT_TABLE: ::c_int = 5; +pub const NET_RT_IFNAMES: ::c_int = 6; +#[doc(hidden)] +#[deprecated( + since = "0.2.95", + note = "Possibly increasing over the releases and might not be so used in the field" +)] +pub const NET_RT_MAXID: ::c_int = 7; + +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; + +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_ECMA: ::c_int = AF_ECMA; +pub const PF_ENCAP: ::c_int = AF_ENCAP; +pub const PF_SIP: ::c_int = AF_SIP; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_BPF: ::c_int = pseudo_AF_HDRCMPLT; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_PFLOW: ::c_int = pseudo_AF_PFLOW; +pub const PF_PIPEX: ::c_int = pseudo_AF_PIPEX; + +pub const SCM_TIMESTAMP: ::c_int = 0x04; + +pub const O_DSYNC: ::c_int = 128; + +pub const MAP_RENAME: ::c_int = 0x0000; +pub const MAP_NORESERVE: ::c_int = 0x0000; +pub const MAP_HASSEMAPHORE: ::c_int = 0x0000; +pub const MAP_TRYFIXED: ::c_int = 0; + +pub const EIPSEC: ::c_int = 82; +pub const ENOMEDIUM: ::c_int = 85; +pub const EMEDIUMTYPE: ::c_int = 86; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -14; + +pub const RUSAGE_THREAD: ::c_int = 1; + +pub const MAP_COPY: ::c_int = 0x0002; +pub const MAP_NOEXTEND: ::c_int = 0x0000; + +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_2_SYMLINKS: ::c_int = 10; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 11; +pub const _PC_ASYNC_IO: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_PRIO_IO: ::c_int = 14; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 17; +pub const _PC_REC_XFER_ALIGN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_SYNC_IO: ::c_int = 20; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 21; + +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 31; +pub const _SC_SEM_VALUE_MAX: ::c_int = 32; +pub const _SC_HOST_NAME_MAX: ::c_int = 33; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 34; +pub const _SC_2_PBS: ::c_int = 35; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 36; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 37; +pub const _SC_2_PBS_LOCATE: ::c_int = 38; +pub const _SC_2_PBS_MESSAGE: ::c_int = 39; +pub const _SC_2_PBS_TRACK: ::c_int = 40; +pub const _SC_ADVISORY_INFO: ::c_int = 41; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 42; +pub const _SC_AIO_MAX: ::c_int = 43; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 44; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 45; +pub const _SC_ATEXIT_MAX: ::c_int = 46; +pub const _SC_BARRIERS: ::c_int = 47; +pub const _SC_CLOCK_SELECTION: ::c_int = 48; +pub const _SC_CPUTIME: ::c_int = 49; +pub const _SC_DELAYTIMER_MAX: ::c_int = 50; +pub const _SC_IOV_MAX: ::c_int = 51; +pub const _SC_IPV6: ::c_int = 52; +pub const _SC_MAPPED_FILES: ::c_int = 53; +pub const _SC_MEMLOCK: ::c_int = 54; +pub const _SC_MEMLOCK_RANGE: ::c_int = 55; +pub const _SC_MEMORY_PROTECTION: ::c_int = 56; +pub const _SC_MESSAGE_PASSING: ::c_int = 57; +pub const _SC_MQ_OPEN_MAX: ::c_int = 58; +pub const _SC_MQ_PRIO_MAX: ::c_int = 59; +pub const _SC_PRIORITIZED_IO: ::c_int = 60; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 61; +pub const _SC_RAW_SOCKETS: ::c_int = 62; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 63; +pub const _SC_REALTIME_SIGNALS: ::c_int = 64; +pub const _SC_REGEXP: ::c_int = 65; +pub const _SC_RTSIG_MAX: ::c_int = 66; +pub const _SC_SEMAPHORES: ::c_int = 67; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 68; +pub const _SC_SHELL: ::c_int = 69; +pub const _SC_SIGQUEUE_MAX: ::c_int = 70; +pub const _SC_SPAWN: ::c_int = 71; +pub const _SC_SPIN_LOCKS: ::c_int = 72; +pub const _SC_SPORADIC_SERVER: ::c_int = 73; +pub const _SC_SS_REPL_MAX: ::c_int = 74; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 75; +pub const _SC_SYMLOOP_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_CPUTIME: ::c_int = 79; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 80; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 81; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 82; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 83; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 84; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 85; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 86; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 87; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 88; +pub const _SC_THREAD_STACK_MIN: ::c_int = 89; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 90; +pub const _SC_THREADS: ::c_int = 91; +pub const _SC_TIMEOUTS: ::c_int = 92; +pub const _SC_TIMER_MAX: ::c_int = 93; +pub const _SC_TIMERS: ::c_int = 94; +pub const _SC_TRACE: ::c_int = 95; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 96; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 97; +pub const _SC_TRACE_INHERIT: ::c_int = 98; +pub const _SC_TRACE_LOG: ::c_int = 99; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 100; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 101; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 102; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 103; +pub const _SC_TRACE_NAME_MAX: ::c_int = 104; +pub const _SC_TRACE_SYS_MAX: ::c_int = 105; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 106; +pub const _SC_TTY_NAME_MAX: ::c_int = 107; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 108; +pub const _SC_V6_ILP32_OFF32: ::c_int = 109; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 110; +pub const _SC_V6_LP64_OFF64: ::c_int = 111; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 112; +pub const _SC_V7_ILP32_OFF32: ::c_int = 113; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 114; +pub const _SC_V7_LP64_OFF64: ::c_int = 115; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 116; +pub const _SC_XOPEN_CRYPT: ::c_int = 117; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 118; +pub const _SC_XOPEN_LEGACY: ::c_int = 119; +pub const _SC_XOPEN_REALTIME: ::c_int = 120; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 121; +pub const _SC_XOPEN_STREAMS: ::c_int = 122; +pub const _SC_XOPEN_UNIX: ::c_int = 123; +pub const _SC_XOPEN_UUCP: ::c_int = 124; +pub const _SC_XOPEN_VERSION: ::c_int = 125; +pub const _SC_PHYS_PAGES: ::c_int = 500; +pub const _SC_AVPHYS_PAGES: ::c_int = 501; +pub const _SC_NPROCESSORS_CONF: ::c_int = 502; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 503; + +pub const FD_SETSIZE: usize = 1024; + +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_OTHER: ::c_int = 2; +pub const SCHED_RR: ::c_int = 3; + +pub const ST_NOSUID: ::c_ulong = 2; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0 as *mut _; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _; + +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 3; +pub const PTHREAD_MUTEX_STRICT_NP: ::c_int = 4; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_STRICT_NP; + +pub const EVFILT_READ: i16 = -1; +pub const EVFILT_WRITE: i16 = -2; +pub const EVFILT_AIO: i16 = -3; +pub const EVFILT_VNODE: i16 = -4; +pub const EVFILT_PROC: i16 = -5; +pub const EVFILT_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_DEVICE: i16 = -8; +pub const EVFILT_EXCEPT: i16 = -9; + +pub const EV_ADD: u16 = 0x1; +pub const EV_DELETE: u16 = 0x2; +pub const EV_ENABLE: u16 = 0x4; +pub const EV_DISABLE: u16 = 0x8; +pub const EV_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +pub const EV_FLAG1: u16 = 0x2000; +pub const EV_ERROR: u16 = 0x4000; +pub const EV_EOF: u16 = 0x8000; + +#[deprecated(since = "0.2.113", note = "Not stable across OS versions")] +pub const EV_SYSFLAGS: u16 = 0xf800; + +pub const NOTE_LOWAT: u32 = 0x00000001; +pub const NOTE_EOF: u32 = 0x00000002; +pub const NOTE_OOB: u32 = 0x00000004; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +pub const NOTE_ATTRIB: u32 = 0x00000008; +pub const NOTE_LINK: u32 = 0x00000010; +pub const NOTE_RENAME: u32 = 0x00000020; +pub const NOTE_REVOKE: u32 = 0x00000040; +pub const NOTE_TRUNCATE: u32 = 0x00000080; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +pub const NOTE_PCTRLMASK: u32 = 0xf0000000; +pub const NOTE_TRACK: u32 = 0x00000001; +pub const NOTE_TRACKERR: u32 = 0x00000002; +pub const NOTE_CHILD: u32 = 0x00000004; +pub const NOTE_CHANGE: u32 = 0x00000001; + +pub const TMP_MAX: ::c_uint = 0x7fffffff; + +pub const AI_PASSIVE: ::c_int = 1; +pub const AI_CANONNAME: ::c_int = 2; +pub const AI_NUMERICHOST: ::c_int = 4; +pub const AI_EXT: ::c_int = 8; +pub const AI_NUMERICSERV: ::c_int = 16; +pub const AI_FQDN: ::c_int = 32; +pub const AI_ADDRCONFIG: ::c_int = 64; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const NI_MAXHOST: ::size_t = 256; + +pub const RTLD_LOCAL: ::c_int = 0; + +pub const CTL_MAXNAME: ::c_int = 12; + +pub const CTLTYPE_NODE: ::c_int = 1; +pub const CTLTYPE_INT: ::c_int = 2; +pub const CTLTYPE_STRING: ::c_int = 3; +pub const CTLTYPE_QUAD: ::c_int = 4; +pub const CTLTYPE_STRUCT: ::c_int = 5; + +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_FS: ::c_int = 3; +pub const CTL_NET: ::c_int = 4; +pub const CTL_DEBUG: ::c_int = 5; +pub const CTL_HW: ::c_int = 6; +pub const CTL_MACHDEP: ::c_int = 7; +pub const CTL_DDB: ::c_int = 9; +pub const CTL_VFS: ::c_int = 10; +pub const CTL_MAXID: ::c_int = 11; + +pub const HW_NCPUONLINE: ::c_int = 25; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_DOMAINNAME: ::c_int = 22; +pub const KERN_MAXPARTITIONS: ::c_int = 23; +pub const KERN_RAWPARTITION: ::c_int = 24; +pub const KERN_MAXTHREAD: ::c_int = 25; +pub const KERN_NTHREADS: ::c_int = 26; +pub const KERN_OSVERSION: ::c_int = 27; +pub const KERN_SOMAXCONN: ::c_int = 28; +pub const KERN_SOMINCONN: ::c_int = 29; +#[deprecated(since = "0.2.71", note = "Removed in OpenBSD 6.0")] +pub const KERN_USERMOUNT: ::c_int = 30; +pub const KERN_NOSUIDCOREDUMP: ::c_int = 32; +pub const KERN_FSYNC: ::c_int = 33; +pub const KERN_SYSVMSG: ::c_int = 34; +pub const KERN_SYSVSEM: ::c_int = 35; +pub const KERN_SYSVSHM: ::c_int = 36; +#[deprecated(since = "0.2.71", note = "Removed in OpenBSD 6.0")] +pub const KERN_ARND: ::c_int = 37; +pub const KERN_MSGBUFSIZE: ::c_int = 38; +pub const KERN_MALLOCSTATS: ::c_int = 39; +pub const KERN_CPTIME: ::c_int = 40; +pub const KERN_NCHSTATS: ::c_int = 41; +pub const KERN_FORKSTAT: ::c_int = 42; +pub const KERN_NSELCOLL: ::c_int = 43; +pub const KERN_TTY: ::c_int = 44; +pub const KERN_CCPU: ::c_int = 45; +pub const KERN_FSCALE: ::c_int = 46; +pub const KERN_NPROCS: ::c_int = 47; +pub const KERN_MSGBUF: ::c_int = 48; +pub const KERN_POOL: ::c_int = 49; +pub const KERN_STACKGAPRANDOM: ::c_int = 50; +pub const KERN_SYSVIPC_INFO: ::c_int = 51; +pub const KERN_SPLASSERT: ::c_int = 54; +pub const KERN_PROC_ARGS: ::c_int = 55; +pub const KERN_NFILES: ::c_int = 56; +pub const KERN_TTYCOUNT: ::c_int = 57; +pub const KERN_NUMVNODES: ::c_int = 58; +pub const KERN_MBSTAT: ::c_int = 59; +pub const KERN_SEMINFO: ::c_int = 61; +pub const KERN_SHMINFO: ::c_int = 62; +pub const KERN_INTRCNT: ::c_int = 63; +pub const KERN_WATCHDOG: ::c_int = 64; +pub const KERN_PROC: ::c_int = 66; +pub const KERN_MAXCLUSTERS: ::c_int = 67; +pub const KERN_EVCOUNT: ::c_int = 68; +pub const KERN_TIMECOUNTER: ::c_int = 69; +pub const KERN_MAXLOCKSPERUID: ::c_int = 70; +pub const KERN_CPTIME2: ::c_int = 71; +pub const KERN_CACHEPCT: ::c_int = 72; +pub const KERN_FILE: ::c_int = 73; +pub const KERN_CONSDEV: ::c_int = 75; +pub const KERN_NETLIVELOCKS: ::c_int = 76; +pub const KERN_POOL_DEBUG: ::c_int = 77; +pub const KERN_PROC_CWD: ::c_int = 78; +pub const KERN_PROC_NOBROADCASTKILL: ::c_int = 79; +pub const KERN_PROC_VMMAP: ::c_int = 80; +pub const KERN_GLOBAL_PTRACE: ::c_int = 81; +pub const KERN_CONSBUFSIZE: ::c_int = 82; +pub const KERN_CONSBUF: ::c_int = 83; +pub const KERN_AUDIO: ::c_int = 84; +pub const KERN_CPUSTATS: ::c_int = 85; +pub const KERN_PFSTATUS: ::c_int = 86; +pub const KERN_TIMEOUT_STATS: ::c_int = 87; +#[deprecated( + since = "0.2.95", + note = "Possibly increasing over the releases and might not be so used in the field" +)] +pub const KERN_MAXID: ::c_int = 88; + +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +pub const KERN_PROC_SESSION: ::c_int = 3; +pub const KERN_PROC_TTY: ::c_int = 4; +pub const KERN_PROC_UID: ::c_int = 5; +pub const KERN_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_KTHREAD: ::c_int = 7; +pub const KERN_PROC_SHOW_THREADS: ::c_int = 0x40000000; + +pub const KERN_SYSVIPC_MSG_INFO: ::c_int = 1; +pub const KERN_SYSVIPC_SEM_INFO: ::c_int = 2; +pub const KERN_SYSVIPC_SHM_INFO: ::c_int = 3; + +pub const KERN_PROC_ARGV: ::c_int = 1; +pub const KERN_PROC_NARGV: ::c_int = 2; +pub const KERN_PROC_ENV: ::c_int = 3; +pub const KERN_PROC_NENV: ::c_int = 4; + +pub const KI_NGROUPS: ::c_int = 16; +pub const KI_MAXCOMLEN: ::c_int = 24; +pub const KI_WMESGLEN: ::c_int = 8; +pub const KI_MAXLOGNAME: ::c_int = 32; +pub const KI_EMULNAMELEN: ::c_int = 8; + +pub const KVE_ET_OBJ: ::c_int = 0x00000001; +pub const KVE_ET_SUBMAP: ::c_int = 0x00000002; +pub const KVE_ET_COPYONWRITE: ::c_int = 0x00000004; +pub const KVE_ET_NEEDSCOPY: ::c_int = 0x00000008; +pub const KVE_ET_HOLE: ::c_int = 0x00000010; +pub const KVE_ET_NOFAULT: ::c_int = 0x00000020; +pub const KVE_ET_STACK: ::c_int = 0x00000040; +pub const KVE_ET_WC: ::c_int = 0x000000080; +pub const KVE_ET_CONCEAL: ::c_int = 0x000000100; +pub const KVE_ET_SYSCALL: ::c_int = 0x000000200; +pub const KVE_ET_FREEMAPPED: ::c_int = 0x000000800; + +pub const KVE_PROT_NONE: ::c_int = 0x00000000; +pub const KVE_PROT_READ: ::c_int = 0x00000001; +pub const KVE_PROT_WRITE: ::c_int = 0x00000002; +pub const KVE_PROT_EXEC: ::c_int = 0x00000004; + +pub const KVE_ADV_NORMAL: ::c_int = 0x00000000; +pub const KVE_ADV_RANDOM: ::c_int = 0x00000001; +pub const KVE_ADV_SEQUENTIAL: ::c_int = 0x00000002; + +pub const KVE_INH_SHARE: ::c_int = 0x00000000; +pub const KVE_INH_COPY: ::c_int = 0x00000010; +pub const KVE_INH_NONE: ::c_int = 0x00000020; +pub const KVE_INH_ZERO: ::c_int = 0x00000030; + +pub const KVE_F_STATIC: ::c_int = 0x1; +pub const KVE_F_KMEM: ::c_int = 0x2; + +pub const CHWFLOW: ::tcflag_t = ::MDMBUF | ::CRTSCTS; +pub const OLCUC: ::tcflag_t = 0x20; +pub const ONOCR: ::tcflag_t = 0x40; +pub const ONLRET: ::tcflag_t = 0x80; + +//https://github.com/openbsd/src/blob/HEAD/sys/sys/mount.h +pub const ISOFSMNT_NORRIP: ::c_int = 0x1; // disable Rock Ridge Ext +pub const ISOFSMNT_GENS: ::c_int = 0x2; // enable generation numbers +pub const ISOFSMNT_EXTATT: ::c_int = 0x4; // enable extended attr +pub const ISOFSMNT_NOJOLIET: ::c_int = 0x8; // disable Joliet Ext +pub const ISOFSMNT_SESS: ::c_int = 0x10; // use iso_args.sess + +pub const NFS_ARGSVERSION: ::c_int = 4; // change when nfs_args changes + +pub const NFSMNT_RESVPORT: ::c_int = 0; // always use reserved ports +pub const NFSMNT_SOFT: ::c_int = 0x1; // soft mount (hard is default) +pub const NFSMNT_WSIZE: ::c_int = 0x2; // set write size +pub const NFSMNT_RSIZE: ::c_int = 0x4; // set read size +pub const NFSMNT_TIMEO: ::c_int = 0x8; // set initial timeout +pub const NFSMNT_RETRANS: ::c_int = 0x10; // set number of request retries +pub const NFSMNT_MAXGRPS: ::c_int = 0x20; // set maximum grouplist size +pub const NFSMNT_INT: ::c_int = 0x40; // allow interrupts on hard mount +pub const NFSMNT_NOCONN: ::c_int = 0x80; // Don't Connect the socket +pub const NFSMNT_NQNFS: ::c_int = 0x100; // Use Nqnfs protocol +pub const NFSMNT_NFSV3: ::c_int = 0x200; // Use NFS Version 3 protocol +pub const NFSMNT_KERB: ::c_int = 0x400; // Use Kerberos authentication +pub const NFSMNT_DUMBTIMR: ::c_int = 0x800; // Don't estimate rtt dynamically +pub const NFSMNT_LEASETERM: ::c_int = 0x1000; // set lease term (nqnfs) +pub const NFSMNT_READAHEAD: ::c_int = 0x2000; // set read ahead +pub const NFSMNT_DEADTHRESH: ::c_int = 0x4000; // set dead server retry thresh +pub const NFSMNT_NOAC: ::c_int = 0x8000; // disable attribute cache +pub const NFSMNT_RDIRPLUS: ::c_int = 0x10000; // Use Readdirplus for V3 +pub const NFSMNT_READDIRSIZE: ::c_int = 0x20000; // Set readdir size + +/* Flags valid only in mount syscall arguments */ +pub const NFSMNT_ACREGMIN: ::c_int = 0x40000; // acregmin field valid +pub const NFSMNT_ACREGMAX: ::c_int = 0x80000; // acregmax field valid +pub const NFSMNT_ACDIRMIN: ::c_int = 0x100000; // acdirmin field valid +pub const NFSMNT_ACDIRMAX: ::c_int = 0x200000; // acdirmax field valid + +/* Flags valid only in kernel */ +pub const NFSMNT_INTERNAL: ::c_int = 0xfffc0000; // Bits set internally +pub const NFSMNT_HASWRITEVERF: ::c_int = 0x40000; // Has write verifier for V3 +pub const NFSMNT_GOTPATHCONF: ::c_int = 0x80000; // Got the V3 pathconf info +pub const NFSMNT_GOTFSINFO: ::c_int = 0x100000; // Got the V3 fsinfo +pub const NFSMNT_MNTD: ::c_int = 0x200000; // Mnt server for mnt point +pub const NFSMNT_DISMINPROG: ::c_int = 0x400000; // Dismount in progress +pub const NFSMNT_DISMNT: ::c_int = 0x800000; // Dismounted +pub const NFSMNT_SNDLOCK: ::c_int = 0x1000000; // Send socket lock +pub const NFSMNT_WANTSND: ::c_int = 0x2000000; // Want above +pub const NFSMNT_RCVLOCK: ::c_int = 0x4000000; // Rcv socket lock +pub const NFSMNT_WANTRCV: ::c_int = 0x8000000; // Want above +pub const NFSMNT_WAITAUTH: ::c_int = 0x10000000; // Wait for authentication +pub const NFSMNT_HASAUTH: ::c_int = 0x20000000; // Has authenticator +pub const NFSMNT_WANTAUTH: ::c_int = 0x40000000; // Wants an authenticator +pub const NFSMNT_AUTHERR: ::c_int = 0x80000000; // Authentication error + +pub const MSDOSFSMNT_SHORTNAME: ::c_int = 0x1; // Force old DOS short names only +pub const MSDOSFSMNT_LONGNAME: ::c_int = 0x2; // Force Win'95 long names +pub const MSDOSFSMNT_NOWIN95: ::c_int = 0x4; // Completely ignore Win95 entries + +pub const NTFS_MFLAG_CASEINS: ::c_int = 0x1; +pub const NTFS_MFLAG_ALLNAMES: ::c_int = 0x2; + +pub const TMPFS_ARGS_VERSION: ::c_int = 1; + +const SI_MAXSZ: ::size_t = 128; +const SI_PAD: ::size_t = (SI_MAXSZ / ::mem::size_of::<::c_int>()) - 3; + +pub const MAP_STACK: ::c_int = 0x4000; +pub const MAP_CONCEAL: ::c_int = 0x8000; + +// https://github.com/openbsd/src/blob/HEAD/sys/net/if.h#L187 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_STATICARP: ::c_int = 0x20; // only static ARP +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions +pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit +pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit +pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + +pub const PTHREAD_STACK_MIN: ::size_t = 1_usize << _MAX_PAGE_SHIFT; +pub const MINSIGSTKSZ: ::size_t = 3_usize << _MAX_PAGE_SHIFT; +pub const SIGSTKSZ: ::size_t = MINSIGSTKSZ + (1_usize << _MAX_PAGE_SHIFT) * 4; + +pub const PT_SET_EVENT_MASK: ::c_int = 12; +pub const PT_GET_EVENT_MASK: ::c_int = 13; +pub const PT_GET_PROCESS_STATE: ::c_int = 14; +pub const PT_GET_THREAD_FIRST: ::c_int = 15; +pub const PT_GET_THREAD_NEXT: ::c_int = 16; +pub const PT_FIRSTMACH: ::c_int = 32; + +pub const SOCK_CLOEXEC: ::c_int = 0x8000; +pub const SOCK_NONBLOCK: ::c_int = 0x4000; +pub const SOCK_DNS: ::c_int = 0x1000; + +pub const BIOCGRSIG: ::c_ulong = 0x40044273; +pub const BIOCSRSIG: ::c_ulong = 0x80044272; +pub const BIOCSDLT: ::c_ulong = 0x8004427a; + +pub const PTRACE_FORK: ::c_int = 0x0002; + +pub const WCONTINUED: ::c_int = 0x08; +pub const WEXITED: ::c_int = 0x04; +pub const WSTOPPED: ::c_int = 0x02; // same as WUNTRACED +pub const WNOWAIT: ::c_int = 0x10; +pub const WTRAPPED: ::c_int = 0x20; + +pub const P_ALL: ::idtype_t = 0; +pub const P_PGID: ::idtype_t = 1; +pub const P_PID: ::idtype_t = 2; + +// search.h +pub const FIND: ::ACTION = 0; +pub const ENTER: ::ACTION = 1; + +// futex.h +pub const FUTEX_WAIT: ::c_int = 1; +pub const FUTEX_WAKE: ::c_int = 2; +pub const FUTEX_REQUEUE: ::c_int = 3; +pub const FUTEX_PRIVATE_FLAG: ::c_int = 128; + +// sysctl.h, kinfo_proc p_eflag constants +pub const EPROC_CTTY: i32 = 0x01; // controlling tty vnode active +pub const EPROC_SLEADER: i32 = 0x02; // session leader +pub const EPROC_UNVEIL: i32 = 0x04; // has unveil settings +pub const EPROC_LKUNVEIL: i32 = 0x08; // unveil is locked + +// Flags for chflags(2) +pub const UF_SETTABLE: ::c_uint = 0x0000ffff; +pub const UF_NODUMP: ::c_uint = 0x00000001; +pub const UF_IMMUTABLE: ::c_uint = 0x00000002; +pub const UF_APPEND: ::c_uint = 0x00000004; +pub const UF_OPAQUE: ::c_uint = 0x00000008; +pub const SF_SETTABLE: ::c_uint = 0xffff0000; +pub const SF_ARCHIVED: ::c_uint = 0x00010000; +pub const SF_IMMUTABLE: ::c_uint = 0x00020000; +pub const SF_APPEND: ::c_uint = 0x00040000; + +// sys/exec_elf.h - Legal values for p_type (segment type). +pub const PT_NULL: u32 = 0; +pub const PT_LOAD: u32 = 1; +pub const PT_DYNAMIC: u32 = 2; +pub const PT_INTERP: u32 = 3; +pub const PT_NOTE: u32 = 4; +pub const PT_SHLIB: u32 = 5; +pub const PT_PHDR: u32 = 6; +pub const PT_TLS: u32 = 7; +pub const PT_LOOS: u32 = 0x60000000; +pub const PT_HIOS: u32 = 0x6fffffff; +pub const PT_LOPROC: u32 = 0x70000000; +pub const PT_HIPROC: u32 = 0x7fffffff; + +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_RELRO: u32 = 0x6474e552; + +// sys/exec_elf.h - Legal values for p_flags (segment flags). +pub const PF_X: u32 = 0x1; +pub const PF_W: u32 = 0x2; +pub const PF_R: u32 = 0x4; +pub const PF_MASKOS: u32 = 0x0ff00000; +pub const PF_MASKPROC: u32 = 0xf0000000; + +// sys/mount.h +pub const MNT_NOPERM: ::c_int = 0x00000020; +pub const MNT_WXALLOWED: ::c_int = 0x00000800; +pub const MNT_EXRDONLY: ::c_int = 0x00000080; +pub const MNT_DEFEXPORTED: ::c_int = 0x00000200; +pub const MNT_EXPORTANON: ::c_int = 0x00000400; +pub const MNT_ROOTFS: ::c_int = 0x00004000; +pub const MNT_NOATIME: ::c_int = 0x00008000; +pub const MNT_DELEXPORT: ::c_int = 0x00020000; +pub const MNT_STALLED: ::c_int = 0x00100000; +pub const MNT_SWAPPABLE: ::c_int = 0x00200000; +pub const MNT_WANTRDWR: ::c_int = 0x02000000; +pub const MNT_SOFTDEP: ::c_int = 0x04000000; +pub const MNT_DOOMED: ::c_int = 0x08000000; + +// For use with vfs_fsync and getfsstat +pub const MNT_WAIT: ::c_int = 1; +pub const MNT_NOWAIT: ::c_int = 2; +pub const MNT_LAZY: ::c_int = 3; + +// sys/_time.h +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 4; +pub const CLOCK_UPTIME: ::clockid_t = 5; +pub const CLOCK_BOOTTIME: ::clockid_t = 6; + +pub const LC_COLLATE_MASK: ::c_int = 1 << ::LC_COLLATE; +pub const LC_CTYPE_MASK: ::c_int = 1 << ::LC_CTYPE; +pub const LC_MONETARY_MASK: ::c_int = 1 << ::LC_MONETARY; +pub const LC_NUMERIC_MASK: ::c_int = 1 << ::LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << ::LC_TIME; +pub const LC_MESSAGES_MASK: ::c_int = 1 << ::LC_MESSAGES; + +const _LC_LAST: ::c_int = 7; +pub const LC_ALL_MASK: ::c_int = (1 << _LC_LAST) - 2; + +pub const LC_GLOBAL_LOCALE: ::locale_t = -1isize as ::locale_t; + +// sys/reboot.h +pub const RB_ASKNAME: ::c_int = 0x00001; +pub const RB_SINGLE: ::c_int = 0x00002; +pub const RB_NOSYNC: ::c_int = 0x00004; +pub const RB_HALT: ::c_int = 0x00008; +pub const RB_INITNAME: ::c_int = 0x00010; +pub const RB_KDB: ::c_int = 0x00040; +pub const RB_RDONLY: ::c_int = 0x00080; +pub const RB_DUMP: ::c_int = 0x00100; +pub const RB_MINIROOT: ::c_int = 0x00200; +pub const RB_CONFIG: ::c_int = 0x00400; +pub const RB_TIMEBAD: ::c_int = 0x00800; +pub const RB_POWERDOWN: ::c_int = 0x01000; +pub const RB_SERCONS: ::c_int = 0x02000; +pub const RB_USERREQ: ::c_int = 0x04000; +pub const RB_RESET: ::c_int = 0x08000; +pub const RB_GOODRANDOM: ::c_int = 0x10000; +pub const RB_UNHIBERNATE: ::c_int = 0x20000; + +const_fn! { + {const} fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + pub fn major(dev: ::dev_t) -> ::c_uint{ + ((dev as ::c_uint) >> 8) & 0xff + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let dev = dev as ::c_uint; + let mut res = 0; + res |= (dev) & 0xff; + res |= ((dev) & 0xffff0000) >> 8; + + res + } +} + +safe_f! { + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0o177 + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0o177777) == 0o177777 + } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0xff) << 8; + dev |= minor & 0xff; + dev |= (minor & 0xffff00) << 8; + dev + } +} + +extern "C" { + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn settimeofday(tp: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn pledge(promises: *const ::c_char, execpromises: *const ::c_char) -> ::c_int; + pub fn unveil(path: *const ::c_char, permissions: *const ::c_char) -> ::c_int; + pub fn strtonum( + nptr: *const ::c_char, + minval: ::c_longlong, + maxval: ::c_longlong, + errstr: *mut *const ::c_char, + ) -> ::c_longlong; + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn chflags(path: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn fchflags(fd: ::c_int, flags: ::c_uint) -> ::c_int; + pub fn chflagsat( + fd: ::c_int, + path: *const ::c_char, + flags: ::c_uint, + atflag: ::c_int, + ) -> ::c_int; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + servlen: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; + pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::c_int, + eventlist: *mut ::kevent, + nevents: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn getthrid() -> ::pid_t; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_main_np() -> ::c_int; + pub fn pthread_get_name_np(tid: ::pthread_t, name: *mut ::c_char, len: ::size_t); + pub fn pthread_set_name_np(tid: ::pthread_t, name: *const ::c_char); + pub fn pthread_stackseg_np(thread: ::pthread_t, sinfo: *mut ::stack_t) -> ::c_int; + + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const ::termios, + winp: *const ::winsize, + ) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *const ::termios, + winp: *const ::winsize, + ) -> ::pid_t; + + pub fn sysctl( + name: *const ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: caddr_t, data: ::c_int) -> ::c_int; + pub fn utrace(label: *const ::c_char, addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + // #include + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + + // Added in `OpenBSD` 5.5 + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); + + pub fn setproctitle(fmt: *const ::c_char, ...); + + pub fn freezero(ptr: *mut ::c_void, size: ::size_t); + pub fn malloc_conceal(size: ::size_t) -> *mut ::c_void; + pub fn calloc_conceal(nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn srand48_deterministic(seed: ::c_long); + pub fn seed48_deterministic(xseed: *mut ::c_ushort) -> *mut ::c_ushort; + pub fn lcong48_deterministic(p: *mut ::c_ushort); + + pub fn lsearch( + key: *const ::c_void, + base: *mut ::c_void, + nelp: *mut ::size_t, + width: ::size_t, + compar: ::Option ::c_int>, + ) -> *mut ::c_void; + pub fn lfind( + key: *const ::c_void, + base: *const ::c_void, + nelp: *mut ::size_t, + width: ::size_t, + compar: ::Option ::c_int>, + ) -> *mut ::c_void; + pub fn hcreate(nelt: ::size_t) -> ::c_int; + pub fn hdestroy(); + pub fn hsearch(entry: ::ENTRY, action: ::ACTION) -> *mut ::ENTRY; + + // futex.h + pub fn futex( + uaddr: *mut u32, + op: ::c_int, + val: ::c_int, + timeout: *const ::timespec, + uaddr2: *mut u32, + ) -> ::c_int; + + pub fn mimmutable(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + + pub fn reboot(mode: ::c_int) -> ::c_int; +} + +#[link(name = "execinfo")] +extern "C" { + pub fn backtrace(addrlist: *mut *mut ::c_void, len: ::size_t) -> ::size_t; + pub fn backtrace_symbols(addrlist: *const *mut ::c_void, len: ::size_t) -> *mut *mut ::c_char; + pub fn backtrace_symbols_fd( + addrlist: *const *mut ::c_void, + len: ::size_t, + fd: ::c_int, + ) -> ::c_int; + pub fn backtrace_symbols_fmt( + addrlist: *const *mut ::c_void, + len: ::size_t, + fmt: *const ::c_char, + ) -> *mut *mut ::c_char; +} + +cfg_if! { + if #[cfg(libc_union)] { + extern { + // these functions use statfs which uses the union mount_info: + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn getmntinfo(mntbufp: *mut *mut ::statfs, flags: ::c_int) -> ::c_int; + pub fn getfsstat(buf: *mut statfs, bufsize: ::size_t, flags: ::c_int) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "mips64")] { + mod mips64; + pub use self::mips64::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc64; + pub use self::powerpc64::*; + } else if #[cfg(target_arch = "riscv64")] { + mod riscv64; + pub use self::riscv64::*; + } else if #[cfg(target_arch = "sparc64")] { + mod sparc64; + pub use self::sparc64::*; + } else if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs new file mode 100644 index 00000000..f1ab365d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs @@ -0,0 +1,16 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = u8; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs new file mode 100644 index 00000000..99350ec8 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs @@ -0,0 +1,16 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs new file mode 100644 index 00000000..35f1672b --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs @@ -0,0 +1,35 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type ucontext_t = sigcontext; + +s! { + pub struct sigcontext { + __sc_unused: ::c_int, + pub sc_mask: ::c_int, + pub sc_ra: ::c_long, + pub sc_sp: ::c_long, + pub sc_gp: ::c_long, + pub sc_tp: ::c_long, + pub sc_t: [::c_long; 7], + pub sc_s: [::c_long; 12], + pub sc_a: [::c_long; 8], + pub sc_sepc: ::c_long, + pub sc_f: [::c_long; 32], + pub sc_fcsr: ::c_long, + pub sc_cookie: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.rs new file mode 100644 index 00000000..070fc938 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.rs @@ -0,0 +1,8 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; + +#[doc(hidden)] +pub const _ALIGNBYTES: usize = 0xf; + +pub const _MAX_PAGE_SHIFT: u32 = 13; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs new file mode 100644 index 00000000..e87d0ff1 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs @@ -0,0 +1,16 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = i8; + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; diff --git a/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs new file mode 100644 index 00000000..60dab004 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs @@ -0,0 +1,130 @@ +use PT_FIRSTMACH; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type ucontext_t = sigcontext; + +s! { + pub struct sigcontext { + pub sc_rdi: ::c_long, + pub sc_rsi: ::c_long, + pub sc_rdx: ::c_long, + pub sc_rcx: ::c_long, + pub sc_r8: ::c_long, + pub sc_r9: ::c_long, + pub sc_r10: ::c_long, + pub sc_r11: ::c_long, + pub sc_r12: ::c_long, + pub sc_r13: ::c_long, + pub sc_r14: ::c_long, + pub sc_r15: ::c_long, + pub sc_rbp: ::c_long, + pub sc_rbx: ::c_long, + pub sc_rax: ::c_long, + pub sc_gs: ::c_long, + pub sc_fs: ::c_long, + pub sc_es: ::c_long, + pub sc_ds: ::c_long, + pub sc_trapno: ::c_long, + pub sc_err: ::c_long, + pub sc_rip: ::c_long, + pub sc_cs: ::c_long, + pub sc_rflags: ::c_long, + pub sc_rsp: ::c_long, + pub sc_ss: ::c_long, + pub sc_fpstate: *mut fxsave64, + __sc_unused: ::c_int, + pub sc_mask: ::c_int, + pub sc_cookie: ::c_long, + } +} + +s_no_extra_traits! { + #[repr(packed)] + pub struct fxsave64 { + pub fx_fcw: u16, + pub fx_fsw: u16, + pub fx_ftw: u8, + __fx_unused1: u8, + pub fx_fop: u16, + pub fx_rip: u64, + pub fx_rdp: u64, + pub fx_mxcsr: u32, + pub fx_mxcsr_mask: u32, + pub fx_st: [[u64; 2]; 8], + pub fx_xmm: [[u64; 2]; 16], + __fx_unused3: [u8; 96], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + // `fxsave64` is packed, so field access is unaligned. + // use {x} to create temporary storage, copy field to it, and do aligned access. + impl PartialEq for fxsave64 { + fn eq(&self, other: &fxsave64) -> bool { + return {self.fx_fcw} == {other.fx_fcw} && + {self.fx_fsw} == {other.fx_fsw} && + {self.fx_ftw} == {other.fx_ftw} && + {self.fx_fop} == {other.fx_fop} && + {self.fx_rip} == {other.fx_rip} && + {self.fx_rdp} == {other.fx_rdp} && + {self.fx_mxcsr} == {other.fx_mxcsr} && + {self.fx_mxcsr_mask} == {other.fx_mxcsr_mask} && + {self.fx_st}.iter().zip({other.fx_st}.iter()).all(|(a,b)| a == b) && + {self.fx_xmm}.iter().zip({other.fx_xmm}.iter()).all(|(a,b)| a == b) + } + } + impl Eq for fxsave64 {} + impl ::fmt::Debug for fxsave64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fxsave64") + .field("fx_fcw", &{self.fx_fcw}) + .field("fx_fsw", &{self.fx_fsw}) + .field("fx_ftw", &{self.fx_ftw}) + .field("fx_fop", &{self.fx_fop}) + .field("fx_rip", &{self.fx_rip}) + .field("fx_rdp", &{self.fx_rdp}) + .field("fx_mxcsr", &{self.fx_mxcsr}) + .field("fx_mxcsr_mask", &{self.fx_mxcsr_mask}) + // FIXME: .field("fx_st", &{self.fx_st}) + // FIXME: .field("fx_xmm", &{self.fx_xmm}) + .finish() + } + } + impl ::hash::Hash for fxsave64 { + fn hash(&self, state: &mut H) { + {self.fx_fcw}.hash(state); + {self.fx_fsw}.hash(state); + {self.fx_ftw}.hash(state); + {self.fx_fop}.hash(state); + {self.fx_rip}.hash(state); + {self.fx_rdp}.hash(state); + {self.fx_mxcsr}.hash(state); + {self.fx_mxcsr_mask}.hash(state); + {self.fx_st}.hash(state); + {self.fx_xmm}.hash(state); + } + } + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const _MAX_PAGE_SHIFT: u32 = 12; + +pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; diff --git a/utshell-0.5.0/vendor/libc/src/unix/haiku/b32.rs b/utshell-0.5.0/vendor/libc/src/unix/haiku/b32.rs new file mode 100644 index 00000000..073ae9d4 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/haiku/b32.rs @@ -0,0 +1,20 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type time_t = i32; + +pub type Elf_Addr = ::Elf32_Addr; +pub type Elf_Half = ::Elf32_Half; +pub type Elf_Phdr = ::Elf32_Phdr; + +s! { + pub struct Elf32_Phdr { + pub p_type: ::Elf32_Word, + pub p_offset: ::Elf32_Off, + pub p_vaddr: ::Elf32_Addr, + pub p_paddr: ::Elf32_Addr, + pub p_filesz: ::Elf32_Word, + pub p_memsz: ::Elf32_Word, + pub p_flags: ::Elf32_Word, + pub p_align: ::Elf32_Word, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/haiku/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/haiku/b64.rs new file mode 100644 index 00000000..45691805 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/haiku/b64.rs @@ -0,0 +1,20 @@ +pub type c_ulong = u64; +pub type c_long = i64; +pub type time_t = i64; + +pub type Elf_Addr = ::Elf64_Addr; +pub type Elf_Half = ::Elf64_Half; +pub type Elf_Phdr = ::Elf64_Phdr; + +s! { + pub struct Elf64_Phdr { + pub p_type: ::Elf64_Word, + pub p_flags: ::Elf64_Word, + pub p_offset: ::Elf64_Off, + pub p_vaddr: ::Elf64_Addr, + pub p_paddr: ::Elf64_Addr, + pub p_filesz: ::Elf64_Xword, + pub p_memsz: ::Elf64_Xword, + pub p_align: ::Elf64_Xword, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/haiku/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/haiku/mod.rs new file mode 100644 index 00000000..e7b0f34d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/haiku/mod.rs @@ -0,0 +1,2105 @@ +pub type rlim_t = ::uintptr_t; +pub type sa_family_t = u8; +pub type pthread_key_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type tcflag_t = ::c_uint; +pub type speed_t = ::c_uchar; +pub type c_char = i8; +pub type clock_t = i32; +pub type clockid_t = i32; +pub type suseconds_t = i32; +pub type wchar_t = i32; +pub type off_t = i64; +pub type ino_t = i64; +pub type blkcnt_t = i64; +pub type blksize_t = i32; +pub type dev_t = i32; +pub type mode_t = u32; +pub type nlink_t = i32; +pub type useconds_t = u32; +pub type socklen_t = u32; +pub type pthread_t = ::uintptr_t; +pub type pthread_condattr_t = ::uintptr_t; +pub type pthread_mutexattr_t = ::uintptr_t; +pub type pthread_rwlockattr_t = ::uintptr_t; +pub type sigset_t = u64; +pub type fsblkcnt_t = i64; +pub type fsfilcnt_t = i64; +pub type pthread_attr_t = *mut ::c_void; +pub type nl_item = ::c_int; +pub type id_t = i32; +pub type idtype_t = ::c_int; +pub type fd_mask = u32; +pub type regoff_t = ::c_int; +pub type key_t = i32; +pub type msgqnum_t = u32; +pub type msglen_t = u32; + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Off = u32; +pub type Elf32_Sword = i32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Off = u64; +pub type Elf64_Sword = i32; +pub type Elf64_Sxword = i64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +pub type ENTRY = entry; +pub type ACTION = ::c_int; + +pub type posix_spawnattr_t = *mut ::c_void; +pub type posix_spawn_file_actions_t = *mut ::c_void; + +pub type StringList = _stringlist; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.si_status + } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [u8; 30], + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [i8; 24], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: u8, + pub sin6_port: u16, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *const ::c_char, + pub ifa_flags: ::c_uint, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_dstaddr: *mut ::sockaddr, + pub ifa_data: *mut ::c_void, + } + + pub struct fd_set { + // size for 1024 bits, and a fd_mask with size u32 + fds_bits: [fd_mask; 32], + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_int, + pub tm_zone: *mut ::c_char, + } + + pub struct utsname { + pub sysname: [::c_char; 32], + pub nodename: [::c_char; 32], + pub release: [::c_char; 32], + pub version: [::c_char; 32], + pub machine: [::c_char; 32], + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::c_char, + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: mode_t, + pub st_nlink: nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_size: off_t, + pub st_rdev: dev_t, + pub st_blksize: blksize_t, + pub st_atime: time_t, + pub st_atime_nsec: c_long, + pub st_mtime: time_t, + pub st_mtime_nsec: c_long, + pub st_ctime: time_t, + pub st_ctime_nsec: c_long, + pub st_crtime: time_t, + pub st_crtime_nsec: c_long, + pub st_type: u32, + pub st_blocks: blkcnt_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + __unused1: ::size_t, + pub gl_offs: ::size_t, + __unused2: ::size_t, + pub gl_pathv: *mut *mut c_char, + + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + pub struct pthread_mutex_t { + flags: u32, + lock: i32, + unused: i32, + owner: i32, + owner_count: i32, + } + + pub struct pthread_cond_t { + flags: u32, + unused: i32, + mutex: *mut ::c_void, + waiter_count: i32, + lock: i32, + } + + pub struct pthread_rwlock_t { + flags: u32, + owner: i32, + lock_sem: i32, // this is actually a union + lock_count: i32, + reader_count: i32, + writer_count: i32, + waiters: [*mut ::c_void; 2], + } + + pub struct pthread_spinlock_t { + lock: u32, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub si_pid: ::pid_t, + pub si_uid: ::uid_t, + pub si_addr: *mut ::c_void, + pub si_status: ::c_int, + pub si_band: c_long, + pub sigval: *mut ::c_void, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, //actually a union with sa_handler + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + sa_userdata: *mut ::c_void, + } + + pub struct sem_t { + pub type_: i32, + pub named_sem_id: i32, // actually a union with unnamed_sem (i32) + pub padding: [i32; 2], + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + + pub struct sockaddr_dl { + pub sdl_len: u8, + pub sdl_family: u8, + pub sdl_e_type: u16, + pub sdl_index: u32, + pub sdl_type: u8, + pub sdl_nlen: u8, + pub sdl_alen: u8, + pub sdl_slen: u8, + pub sdl_data: [u8; 46], + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_int, + pub sp_min: ::c_int, + pub sp_max: ::c_int, + pub sp_warn: ::c_int, + pub sp_inact: ::c_int, + pub sp_expire: ::c_int, + pub sp_flag: ::c_int, + } + + pub struct regex_t { + __buffer: *mut ::c_void, + __allocated: ::size_t, + __used: ::size_t, + __syntax: ::c_ulong, + __fastmap: *mut ::c_char, + __translate: *mut ::c_char, + __re_nsub: ::size_t, + __bitfield: u8, + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + } + + pub struct ipc_perm { + pub key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct entry { + pub key: *mut ::c_char, + pub data: *mut ::c_void, + } + + pub struct option { + pub name: *const ::c_char, + pub has_arg: ::c_int, + pub flag: *mut ::c_int, + pub val: ::c_int, + } + + pub struct _stringlist { + pub sl_str: *mut *mut ::c_char, + pub sl_max: ::size_t, + pub sl_cur: ::size_t, + } + + pub struct dl_phdr_info { + pub dlpi_addr: ::Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const ::Elf_Phdr, + pub dlpi_phnum: ::Elf_Half, + } +} + +s_no_extra_traits! { + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 126] + } + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: u64, + __ss_pad3: [u8; 112], + } + pub struct dirent { + pub d_dev: dev_t, + pub d_pdev: dev_t, + pub d_ino: ino_t, + pub d_pino: i64, + pub d_reclen: ::c_ushort, + pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + __unused1: *mut ::c_void, // actually a function pointer + pub sigev_notify_attributes: *mut ::pthread_attr_t, + } + + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_id: [::c_char; 8], + pub ut_pid: ::pid_t, + pub ut_user: [::c_char; 32], + pub ut_line: [::c_char; 16], + pub ut_host: [::c_char; 128], + __ut_reserved: [::c_char; 64], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_tv == other.ut_tv + && self.ut_id == other.ut_id + && self.ut_pid == other.ut_pid + && self.ut_user == other.ut_user + && self.ut_line == other.ut_line + && self.ut_host.iter().zip(other.ut_host.iter()).all(|(a,b)| a == b) + && self.__ut_reserved == other.__ut_reserved + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + .field("ut_tv", &self.ut_tv) + .field("ut_id", &self.ut_id) + .field("ut_pid", &self.ut_pid) + .field("ut_user", &self.ut_user) + .field("ut_line", &self.ut_line) + .field("ut_host", &self.ut_host) + .field("__ut_reserved", &self.__ut_reserved) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_tv.hash(state); + self.ut_id.hash(state); + self.ut_pid.hash(state); + self.ut_user.hash(state); + self.ut_line.hash(state); + self.ut_host.hash(state); + self.__ut_reserved.hash(state); + } + } + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_len == other.sun_len + && self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_len", &self.sun_len) + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_len.hash(state); + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self + .__ss_pad1 + .iter() + .zip(other.__ss_pad1.iter()) + .all(|(a, b)| a == b) + && self.__ss_pad2 == other.__ss_pad2 + && self + .__ss_pad3 + .iter() + .zip(other.__ss_pad3.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_pad2", &self.__ss_pad2) + // FIXME: .field("__ss_pad3", &self.__ss_pad3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_pad2.hash(state); + self.__ss_pad3.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_dev == other.d_dev + && self.d_pdev == other.d_pdev + && self.d_ino == other.d_ino + && self.d_pino == other.d_pino + && self.d_reclen == other.d_reclen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_dev", &self.d_dev) + .field("d_pdev", &self.d_pdev) + .field("d_ino", &self.d_ino) + .field("d_pino", &self.d_pino) + .field("d_reclen", &self.d_reclen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_dev.hash(state); + self.d_pdev.hash(state); + self.d_ino.hash(state); + self.d_pino.hash(state); + self.d_reclen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + } +} + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const L_SET: ::c_int = SEEK_SET; +pub const L_INCR: ::c_int = SEEK_CUR; +pub const L_XTND: ::c_int = SEEK_END; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; + +pub const F_DUPFD: ::c_int = 0x0001; +pub const F_GETFD: ::c_int = 0x0002; +pub const F_SETFD: ::c_int = 0x0004; +pub const F_GETFL: ::c_int = 0x0008; +pub const F_SETFL: ::c_int = 0x0010; +pub const F_GETLK: ::c_int = 0x0020; +pub const F_SETLK: ::c_int = 0x0080; +pub const F_SETLKW: ::c_int = 0x0100; +pub const F_DUPFD_CLOEXEC: ::c_int = 0x0200; + +pub const F_RDLCK: ::c_int = 0x0040; +pub const F_UNLCK: ::c_int = 0x0200; +pub const F_WRLCK: ::c_int = 0x0400; + +pub const AT_FDCWD: ::c_int = -1; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x01; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x02; +pub const AT_REMOVEDIR: ::c_int = 0x04; +pub const AT_EACCESS: ::c_int = 0x08; + +pub const POLLIN: ::c_short = 0x0001; +pub const POLLOUT: ::c_short = 0x0002; +pub const POLLRDNORM: ::c_short = POLLIN; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLRDBAND: ::c_short = 0x0008; +pub const POLLWRBAND: ::c_short = 0x0010; +pub const POLLPRI: ::c_short = 0x0020; +pub const POLLERR: ::c_short = 0x0004; +pub const POLLHUP: ::c_short = 0x0080; +pub const POLLNVAL: ::c_short = 0x1000; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const CLOCK_REALTIME: ::c_int = -1; +pub const CLOCK_MONOTONIC: ::c_int = 0; +pub const CLOCK_PROCESS_CPUTIME_ID: ::c_int = -2; +pub const CLOCK_THREAD_CPUTIME_ID: ::c_int = -3; + +pub const RLIMIT_CORE: ::c_int = 0; +pub const RLIMIT_CPU: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_FSIZE: ::c_int = 3; +pub const RLIMIT_NOFILE: ::c_int = 4; +pub const RLIMIT_STACK: ::c_int = 5; +pub const RLIMIT_AS: ::c_int = 6; +pub const RLIM_INFINITY: ::rlim_t = 0xffffffff; +// Haiku specific +pub const RLIMIT_NOVMON: ::c_int = 7; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 8; + +pub const RUSAGE_SELF: ::c_int = 0; + +pub const RTLD_LAZY: ::c_int = 0; + +pub const NCCS: usize = 11; + +pub const O_RDONLY: ::c_int = 0x0000; +pub const O_WRONLY: ::c_int = 0x0001; +pub const O_RDWR: ::c_int = 0x0002; +pub const O_ACCMODE: ::c_int = 0x0003; + +pub const O_EXCL: ::c_int = 0x0100; +pub const O_CREAT: ::c_int = 0x0200; +pub const O_TRUNC: ::c_int = 0x0400; +pub const O_NOCTTY: ::c_int = 0x1000; +pub const O_NOTRAVERSE: ::c_int = 0x2000; + +pub const O_CLOEXEC: ::c_int = 0x00000040; +pub const O_NONBLOCK: ::c_int = 0x00000080; +pub const O_APPEND: ::c_int = 0x00000800; +pub const O_SYNC: ::c_int = 0x00010000; +pub const O_RSYNC: ::c_int = 0x00020000; +pub const O_DSYNC: ::c_int = 0x00040000; +pub const O_NOFOLLOW: ::c_int = 0x00080000; +pub const O_NOCACHE: ::c_int = 0x00100000; +pub const O_DIRECTORY: ::c_int = 0x00200000; + +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_IFMT: ::mode_t = 61440; + +pub const S_IRWXU: ::mode_t = 0o00700; +pub const S_IRUSR: ::mode_t = 0o00400; +pub const S_IWUSR: ::mode_t = 0o00200; +pub const S_IXUSR: ::mode_t = 0o00100; +pub const S_IRWXG: ::mode_t = 0o00070; +pub const S_IRGRP: ::mode_t = 0o00040; +pub const S_IWGRP: ::mode_t = 0o00020; +pub const S_IXGRP: ::mode_t = 0o00010; +pub const S_IRWXO: ::mode_t = 0o00007; +pub const S_IROTH: ::mode_t = 0o00004; +pub const S_IWOTH: ::mode_t = 0o00002; +pub const S_IXOTH: ::mode_t = 0o00001; + +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGCHLD: ::c_int = 5; +pub const SIGABRT: ::c_int = 6; +pub const SIGPIPE: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSTOP: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGCONT: ::c_int = 12; +pub const SIGTSTP: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGTTIN: ::c_int = 16; +pub const SIGTTOU: ::c_int = 17; +pub const SIGUSR1: ::c_int = 18; +pub const SIGUSR2: ::c_int = 19; +pub const SIGWINCH: ::c_int = 20; +pub const SIGKILLTHR: ::c_int = 21; +pub const SIGTRAP: ::c_int = 22; +pub const SIGPOLL: ::c_int = 23; +pub const SIGPROF: ::c_int = 24; +pub const SIGSYS: ::c_int = 25; +pub const SIGURG: ::c_int = 26; +pub const SIGVTALRM: ::c_int = 27; +pub const SIGXCPU: ::c_int = 28; +pub const SIGXFSZ: ::c_int = 29; +pub const SIGBUS: ::c_int = 30; + +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 14; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const LC_ALL: ::c_int = 0; +pub const LC_COLLATE: ::c_int = 1; +pub const LC_CTYPE: ::c_int = 2; +pub const LC_MONETARY: ::c_int = 3; +pub const LC_NUMERIC: ::c_int = 4; +pub const LC_TIME: ::c_int = 5; +pub const LC_MESSAGES: ::c_int = 6; + +// FIXME: Haiku does not have MAP_FILE, but library/std/os.rs requires it +pub const MAP_FILE: ::c_int = 0x00; +pub const MAP_SHARED: ::c_int = 0x01; +pub const MAP_PRIVATE: ::c_int = 0x02; +pub const MAP_FIXED: ::c_int = 0x04; +pub const MAP_ANONYMOUS: ::c_int = 0x08; +pub const MAP_NORESERVE: ::c_int = 0x10; +pub const MAP_ANON: ::c_int = MAP_ANONYMOUS; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const MS_ASYNC: ::c_int = 0x01; +pub const MS_INVALIDATE: ::c_int = 0x04; +pub const MS_SYNC: ::c_int = 0x02; + +pub const E2BIG: ::c_int = -2147454975; +pub const ECHILD: ::c_int = -2147454974; +pub const EDEADLK: ::c_int = -2147454973; +pub const EFBIG: ::c_int = -2147454972; +pub const EMLINK: ::c_int = -2147454971; +pub const ENFILE: ::c_int = -2147454970; +pub const ENODEV: ::c_int = -2147454969; +pub const ENOLCK: ::c_int = -2147454968; +pub const ENOSYS: ::c_int = -2147454967; +pub const ENOTTY: ::c_int = -2147454966; +pub const ENXIO: ::c_int = -2147454965; +pub const ESPIPE: ::c_int = -2147454964; +pub const ESRCH: ::c_int = -2147454963; +pub const EFPOS: ::c_int = -2147454962; +pub const ESIGPARM: ::c_int = -2147454961; +pub const EDOM: ::c_int = -2147454960; +pub const ERANGE: ::c_int = -2147454959; +pub const EPROTOTYPE: ::c_int = -2147454958; +pub const EPROTONOSUPPORT: ::c_int = -2147454957; +pub const EPFNOSUPPORT: ::c_int = -2147454956; +pub const EAFNOSUPPORT: ::c_int = -2147454955; +pub const EADDRINUSE: ::c_int = -2147454954; +pub const EADDRNOTAVAIL: ::c_int = -2147454953; +pub const ENETDOWN: ::c_int = -2147454952; +pub const ENETUNREACH: ::c_int = -2147454951; +pub const ENETRESET: ::c_int = -2147454950; +pub const ECONNABORTED: ::c_int = -2147454949; +pub const ECONNRESET: ::c_int = -2147454948; +pub const EISCONN: ::c_int = -2147454947; +pub const ENOTCONN: ::c_int = -2147454946; +pub const ESHUTDOWN: ::c_int = -2147454945; +pub const ECONNREFUSED: ::c_int = -2147454944; +pub const EHOSTUNREACH: ::c_int = -2147454943; +pub const ENOPROTOOPT: ::c_int = -2147454942; +pub const ENOBUFS: ::c_int = -2147454941; +pub const EINPROGRESS: ::c_int = -2147454940; +pub const EALREADY: ::c_int = -2147454939; +pub const EILSEQ: ::c_int = -2147454938; +pub const ENOMSG: ::c_int = -2147454937; +pub const ESTALE: ::c_int = -2147454936; +pub const EOVERFLOW: ::c_int = -2147454935; +pub const EMSGSIZE: ::c_int = -2147454934; +pub const EOPNOTSUPP: ::c_int = -2147454933; +pub const ENOTSOCK: ::c_int = -2147454932; +pub const EHOSTDOWN: ::c_int = -2147454931; +pub const EBADMSG: ::c_int = -2147454930; +pub const ECANCELED: ::c_int = -2147454929; +pub const EDESTADDRREQ: ::c_int = -2147454928; +pub const EDQUOT: ::c_int = -2147454927; +pub const EIDRM: ::c_int = -2147454926; +pub const EMULTIHOP: ::c_int = -2147454925; +pub const ENODATA: ::c_int = -2147454924; +pub const ENOLINK: ::c_int = -2147454923; +pub const ENOSR: ::c_int = -2147454922; +pub const ENOSTR: ::c_int = -2147454921; +pub const ENOTSUP: ::c_int = -2147454920; +pub const EPROTO: ::c_int = -2147454919; +pub const ETIME: ::c_int = -2147454918; +pub const ETXTBSY: ::c_int = -2147454917; +pub const ENOATTR: ::c_int = -2147454916; + +// INT_MIN +pub const ENOMEM: ::c_int = -2147483648; + +// POSIX errors that can be mapped to BeOS error codes +pub const EACCES: ::c_int = -2147483646; +pub const EINTR: ::c_int = -2147483638; +pub const EIO: ::c_int = -2147483647; +pub const EBUSY: ::c_int = -2147483634; +pub const EFAULT: ::c_int = -2147478783; +pub const ETIMEDOUT: ::c_int = -2147483639; +pub const EAGAIN: ::c_int = -2147483637; +pub const EWOULDBLOCK: ::c_int = -2147483637; +pub const EBADF: ::c_int = -2147459072; +pub const EEXIST: ::c_int = -2147459070; +pub const EINVAL: ::c_int = -2147483643; +pub const ENAMETOOLONG: ::c_int = -2147459068; +pub const ENOENT: ::c_int = -2147459069; +pub const EPERM: ::c_int = -2147483633; +pub const ENOTDIR: ::c_int = -2147459067; +pub const EISDIR: ::c_int = -2147459063; +pub const ENOTEMPTY: ::c_int = -2147459066; +pub const ENOSPC: ::c_int = -2147459065; +pub const EROFS: ::c_int = -2147459064; +pub const EMFILE: ::c_int = -2147459062; +pub const EXDEV: ::c_int = -2147459061; +pub const ELOOP: ::c_int = -2147459060; +pub const ENOEXEC: ::c_int = -2147478782; +pub const EPIPE: ::c_int = -2147459059; + +pub const IPPROTO_RAW: ::c_int = 255; + +// These are prefixed with POSIX_ on Haiku +pub const MADV_NORMAL: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_RANDOM: ::c_int = 3; +pub const MADV_WILLNEED: ::c_int = 4; +pub const MADV_DONTNEED: ::c_int = 5; +pub const MADV_FREE: ::c_int = 6; + +// https://github.com/haiku/haiku/blob/HEAD/headers/posix/net/if.h#L80 +pub const IFF_UP: ::c_int = 0x0001; +pub const IFF_BROADCAST: ::c_int = 0x0002; // valid broadcast address +pub const IFF_LOOPBACK: ::c_int = 0x0008; +pub const IFF_POINTOPOINT: ::c_int = 0x0010; // point-to-point link +pub const IFF_NOARP: ::c_int = 0x0040; // no address resolution +pub const IFF_AUTOUP: ::c_int = 0x0080; // auto dial +pub const IFF_PROMISC: ::c_int = 0x0100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0200; // receive all multicast packets +pub const IFF_SIMPLEX: ::c_int = 0x0800; // doesn't receive own transmissions +pub const IFF_LINK: ::c_int = 0x1000; // has link +pub const IFF_AUTO_CONFIGURED: ::c_int = 0x2000; +pub const IFF_CONFIGURING: ::c_int = 0x4000; +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_INET: ::c_int = 1; +pub const AF_APPLETALK: ::c_int = 2; +pub const AF_ROUTE: ::c_int = 3; +pub const AF_LINK: ::c_int = 4; +pub const AF_INET6: ::c_int = 5; +pub const AF_DLI: ::c_int = 6; +pub const AF_IPX: ::c_int = 7; +pub const AF_NOTIFY: ::c_int = 8; +pub const AF_LOCAL: ::c_int = 9; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_BLUETOOTH: ::c_int = 10; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_LINK: ::c_int = AF_LINK; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; + +pub const IP_OPTIONS: ::c_int = 1; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_TOS: ::c_int = 3; +pub const IP_TTL: ::c_int = 4; +pub const IP_RECVOPTS: ::c_int = 5; +pub const IP_RECVRETOPTS: ::c_int = 6; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_RETOPTS: ::c_int = 8; +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_BLOCK_SOURCE: ::c_int = 14; +pub const IP_UNBLOCK_SOURCE: ::c_int = 15; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 16; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 17; + +pub const TCP_NODELAY: ::c_int = 0x01; +pub const TCP_MAXSEG: ::c_int = 0x02; +pub const TCP_NOPUSH: ::c_int = 0x04; +pub const TCP_NOOPT: ::c_int = 0x08; + +pub const IF_NAMESIZE: ::size_t = 32; +pub const IFNAMSIZ: ::size_t = IF_NAMESIZE; + +pub const IPV6_MULTICAST_IF: ::c_int = 24; +pub const IPV6_MULTICAST_HOPS: ::c_int = 25; +pub const IPV6_MULTICAST_LOOP: ::c_int = 26; +pub const IPV6_UNICAST_HOPS: ::c_int = 27; +pub const IPV6_JOIN_GROUP: ::c_int = 28; +pub const IPV6_LEAVE_GROUP: ::c_int = 29; +pub const IPV6_V6ONLY: ::c_int = 30; +pub const IPV6_PKTINFO: ::c_int = 31; +pub const IPV6_RECVPKTINFO: ::c_int = 32; +pub const IPV6_HOPLIMIT: ::c_int = 33; +pub const IPV6_RECVHOPLIMIT: ::c_int = 34; +pub const IPV6_HOPOPTS: ::c_int = 35; +pub const IPV6_DSTOPTS: ::c_int = 36; +pub const IPV6_RTHDR: ::c_int = 37; + +pub const MSG_OOB: ::c_int = 0x0001; +pub const MSG_PEEK: ::c_int = 0x0002; +pub const MSG_DONTROUTE: ::c_int = 0x0004; +pub const MSG_EOR: ::c_int = 0x0008; +pub const MSG_TRUNC: ::c_int = 0x0010; +pub const MSG_CTRUNC: ::c_int = 0x0020; +pub const MSG_WAITALL: ::c_int = 0x0040; +pub const MSG_DONTWAIT: ::c_int = 0x0080; +pub const MSG_BCAST: ::c_int = 0x0100; +pub const MSG_MCAST: ::c_int = 0x0200; +pub const MSG_EOF: ::c_int = 0x0400; +pub const MSG_NOSIGNAL: ::c_int = 0x0800; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 0x01; +pub const LOCK_EX: ::c_int = 0x02; +pub const LOCK_NB: ::c_int = 0x04; +pub const LOCK_UN: ::c_int = 0x08; + +pub const MINSIGSTKSZ: ::size_t = 8192; +pub const SIGSTKSZ: ::size_t = 16384; + +pub const IOV_MAX: ::c_int = 1024; +pub const PATH_MAX: ::c_int = 1024; + +pub const SA_NOCLDSTOP: ::c_int = 0x01; +pub const SA_NOCLDWAIT: ::c_int = 0x02; +pub const SA_RESETHAND: ::c_int = 0x04; +pub const SA_NODEFER: ::c_int = 0x08; +pub const SA_RESTART: ::c_int = 0x10; +pub const SA_ONSTACK: ::c_int = 0x20; +pub const SA_SIGINFO: ::c_int = 0x40; +pub const SA_NOMASK: ::c_int = SA_NODEFER; +pub const SA_STACK: ::c_int = SA_ONSTACK; +pub const SA_ONESHOT: ::c_int = SA_RESETHAND; + +pub const SS_ONSTACK: ::c_int = 0x1; +pub const SS_DISABLE: ::c_int = 0x2; + +pub const FD_SETSIZE: usize = 1024; + +pub const RTLD_LOCAL: ::c_int = 0x0; +pub const RTLD_NOW: ::c_int = 0x1; +pub const RTLD_GLOBAL: ::c_int = 0x2; +pub const RTLD_DEFAULT: *mut ::c_void = 0isize as *mut ::c_void; + +pub const BUFSIZ: ::c_uint = 8192; +pub const FILENAME_MAX: ::c_uint = 256; +pub const FOPEN_MAX: ::c_uint = 128; +pub const L_tmpnam: ::c_uint = 512; +pub const TMP_MAX: ::c_uint = 32768; + +pub const _PC_CHOWN_RESTRICTED: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_NO_TRUNC: ::c_int = 5; +pub const _PC_PATH_MAX: ::c_int = 6; +pub const _PC_PIPE_BUF: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_LINK_MAX: ::c_int = 25; +pub const _PC_SYNC_IO: ::c_int = 26; +pub const _PC_ASYNC_IO: ::c_int = 27; +pub const _PC_PRIO_IO: ::c_int = 28; +pub const _PC_SOCK_MAXBUF: ::c_int = 29; +pub const _PC_FILESIZEBITS: ::c_int = 30; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 31; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 32; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 33; +pub const _PC_REC_XFER_ALIGN: ::c_int = 34; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 35; +pub const _PC_SYMLINK_MAX: ::c_int = 36; +pub const _PC_2_SYMLINKS: ::c_int = 37; +pub const _PC_XATTR_EXISTS: ::c_int = 38; +pub const _PC_XATTR_ENABLED: ::c_int = 39; + +pub const FIONBIO: ::c_ulong = 0xbe000000; +pub const FIONREAD: ::c_ulong = 0xbe000001; +pub const FIOSEEKDATA: ::c_ulong = 0xbe000002; +pub const FIOSEEKHOLE: ::c_ulong = 0xbe000003; + +pub const _SC_ARG_MAX: ::c_int = 15; +pub const _SC_CHILD_MAX: ::c_int = 16; +pub const _SC_CLK_TCK: ::c_int = 17; +pub const _SC_JOB_CONTROL: ::c_int = 18; +pub const _SC_NGROUPS_MAX: ::c_int = 19; +pub const _SC_OPEN_MAX: ::c_int = 20; +pub const _SC_SAVED_IDS: ::c_int = 21; +pub const _SC_STREAM_MAX: ::c_int = 22; +pub const _SC_TZNAME_MAX: ::c_int = 23; +pub const _SC_VERSION: ::c_int = 24; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 25; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 26; +pub const _SC_PAGESIZE: ::c_int = 27; +pub const _SC_PAGE_SIZE: ::c_int = 27; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 28; +pub const _SC_SEM_VALUE_MAX: ::c_int = 29; +pub const _SC_SEMAPHORES: ::c_int = 30; +pub const _SC_THREADS: ::c_int = 31; +pub const _SC_IOV_MAX: ::c_int = 32; +pub const _SC_UIO_MAXIOV: ::c_int = 32; +pub const _SC_NPROCESSORS_CONF: ::c_int = 34; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 35; +pub const _SC_ATEXIT_MAX: ::c_int = 37; +pub const _SC_PASS_MAX: ::c_int = 39; +pub const _SC_PHYS_PAGES: ::c_int = 40; +pub const _SC_AVPHYS_PAGES: ::c_int = 41; +pub const _SC_PIPE: ::c_int = 42; +pub const _SC_SELECT: ::c_int = 43; +pub const _SC_POLL: ::c_int = 44; +pub const _SC_MAPPED_FILES: ::c_int = 45; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 46; +pub const _SC_THREAD_STACK_MIN: ::c_int = 47; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 48; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 49; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 50; +pub const _SC_REALTIME_SIGNALS: ::c_int = 51; +pub const _SC_MEMORY_PROTECTION: ::c_int = 52; +pub const _SC_SIGQUEUE_MAX: ::c_int = 53; +pub const _SC_RTSIG_MAX: ::c_int = 54; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 55; +pub const _SC_DELAYTIMER_MAX: ::c_int = 56; +pub const _SC_TIMER_MAX: ::c_int = 57; +pub const _SC_TIMERS: ::c_int = 58; +pub const _SC_CPUTIME: ::c_int = 59; +pub const _SC_THREAD_CPUTIME: ::c_int = 60; +pub const _SC_HOST_NAME_MAX: ::c_int = 61; +pub const _SC_REGEXP: ::c_int = 62; +pub const _SC_SYMLOOP_MAX: ::c_int = 63; +pub const _SC_SHELL: ::c_int = 64; +pub const _SC_TTY_NAME_MAX: ::c_int = 65; + +pub const PTHREAD_STACK_MIN: ::size_t = 8192; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + flags: 0, + lock: 0, + unused: -42, + owner: -1, + owner_count: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + flags: 0, + unused: -42, + mutex: 0 as *mut _, + waiter_count: 0, + lock: 0, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + flags: 0, + owner: -1, + lock_sem: 0, + lock_count: 0, + reader_count: 0, + writer_count: 0, + waiters: [0 as *mut _; 2], +}; + +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = 0; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 3; + +pub const FIOCLEX: c_ulong = 0; // FIXME: does not exist on Haiku! + +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOL_SOCKET: ::c_int = -1; +pub const SO_ACCEPTCONN: ::c_int = 0x00000001; +pub const SO_BROADCAST: ::c_int = 0x00000002; +pub const SO_DEBUG: ::c_int = 0x00000004; +pub const SO_DONTROUTE: ::c_int = 0x00000008; +pub const SO_KEEPALIVE: ::c_int = 0x00000010; +pub const SO_OOBINLINE: ::c_int = 0x00000020; +pub const SO_REUSEADDR: ::c_int = 0x00000040; +pub const SO_REUSEPORT: ::c_int = 0x00000080; +pub const SO_USELOOPBACK: ::c_int = 0x00000100; +pub const SO_LINGER: ::c_int = 0x00000200; +pub const SO_SNDBUF: ::c_int = 0x40000001; +pub const SO_SNDLOWAT: ::c_int = 0x40000002; +pub const SO_SNDTIMEO: ::c_int = 0x40000003; +pub const SO_RCVBUF: ::c_int = 0x40000004; +pub const SO_RCVLOWAT: ::c_int = 0x40000005; +pub const SO_RCVTIMEO: ::c_int = 0x40000006; +pub const SO_ERROR: ::c_int = 0x40000007; +pub const SO_TYPE: ::c_int = 0x40000008; +pub const SO_NONBLOCK: ::c_int = 0x40000009; +pub const SO_BINDTODEVICE: ::c_int = 0x4000000a; +pub const SO_PEERCRED: ::c_int = 0x4000000b; + +pub const SCM_RIGHTS: ::c_int = 0x01; + +pub const SOMAXCONN: ::c_int = 32; + +pub const NI_MAXHOST: ::size_t = 1025; + +pub const WNOHANG: ::c_int = 0x01; +pub const WUNTRACED: ::c_int = 0x02; +pub const WCONTINUED: ::c_int = 0x04; +pub const WEXITED: ::c_int = 0x08; +pub const WSTOPPED: ::c_int = 0x10; +pub const WNOWAIT: ::c_int = 0x20; + +// si_code values for SIGBUS signal +pub const BUS_ADRALN: ::c_int = 40; +pub const BUS_ADRERR: ::c_int = 41; +pub const BUS_OBJERR: ::c_int = 42; + +// si_code values for SIGCHLD signal +pub const CLD_EXITED: ::c_int = 60; +pub const CLD_KILLED: ::c_int = 61; +pub const CLD_DUMPED: ::c_int = 62; +pub const CLD_TRAPPED: ::c_int = 63; +pub const CLD_STOPPED: ::c_int = 64; +pub const CLD_CONTINUED: ::c_int = 65; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const UTIME_OMIT: c_long = 1000000001; +pub const UTIME_NOW: c_long = 1000000000; + +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VEOF: usize = 4; +pub const VEOL: usize = 5; +pub const VMIN: usize = 4; +pub const VTIME: usize = 5; +pub const VEOL2: usize = 6; +pub const VSWTCH: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; + +pub const IGNBRK: ::tcflag_t = 0x01; +pub const BRKINT: ::tcflag_t = 0x02; +pub const IGNPAR: ::tcflag_t = 0x04; +pub const PARMRK: ::tcflag_t = 0x08; +pub const INPCK: ::tcflag_t = 0x10; +pub const ISTRIP: ::tcflag_t = 0x20; +pub const INLCR: ::tcflag_t = 0x40; +pub const IGNCR: ::tcflag_t = 0x80; +pub const ICRNL: ::tcflag_t = 0x100; +pub const IUCLC: ::tcflag_t = 0x200; +pub const IXON: ::tcflag_t = 0x400; +pub const IXANY: ::tcflag_t = 0x800; +pub const IXOFF: ::tcflag_t = 0x1000; + +pub const OPOST: ::tcflag_t = 0x00000001; +pub const OLCUC: ::tcflag_t = 0x00000002; +pub const ONLCR: ::tcflag_t = 0x00000004; +pub const OCRNL: ::tcflag_t = 0x00000008; +pub const ONOCR: ::tcflag_t = 0x00000010; +pub const ONLRET: ::tcflag_t = 0x00000020; +pub const OFILL: ::tcflag_t = 0x00000040; +pub const OFDEL: ::tcflag_t = 0x00000080; +pub const NLDLY: ::tcflag_t = 0x00000100; +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00000100; +pub const CRDLY: ::tcflag_t = 0x00000600; +pub const CR0: ::tcflag_t = 0x00000000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0x00001800; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0x00002000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VTDLY: ::tcflag_t = 0x00004000; +pub const VT0: ::tcflag_t = 0x00000000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const FFDLY: ::tcflag_t = 0x00008000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const FF1: ::tcflag_t = 0x00008000; + +pub const CSIZE: ::tcflag_t = 0x00000020; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CS6: ::tcflag_t = 0x00000000; +pub const CS7: ::tcflag_t = 0x00000000; +pub const CS8: ::tcflag_t = 0x00000020; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const XLOBLK: ::tcflag_t = 0x00001000; +pub const CTSFLOW: ::tcflag_t = 0x00002000; +pub const RTSFLOW: ::tcflag_t = 0x00004000; +pub const CRTSCTS: ::tcflag_t = RTSFLOW | CTSFLOW; + +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const XCASE: ::tcflag_t = 0x00000004; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const IEXTEN: ::tcflag_t = 0x00000200; +pub const ECHOCTL: ::tcflag_t = 0x00000400; +pub const ECHOPRT: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00001000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const PENDIN: ::tcflag_t = 0x00004000; + +pub const TCGB_CTS: ::c_int = 0x01; +pub const TCGB_DSR: ::c_int = 0x02; +pub const TCGB_RI: ::c_int = 0x04; +pub const TCGB_DCD: ::c_int = 0x08; +pub const TIOCM_CTS: ::c_int = TCGB_CTS; +pub const TIOCM_CD: ::c_int = TCGB_DCD; +pub const TIOCM_CAR: ::c_int = TIOCM_CD; +pub const TIOCM_RI: ::c_int = TCGB_RI; +pub const TIOCM_DSR: ::c_int = TCGB_DSR; +pub const TIOCM_DTR: ::c_int = 0x10; +pub const TIOCM_RTS: ::c_int = 0x20; + +pub const B0: speed_t = 0x00; +pub const B50: speed_t = 0x01; +pub const B75: speed_t = 0x02; +pub const B110: speed_t = 0x03; +pub const B134: speed_t = 0x04; +pub const B150: speed_t = 0x05; +pub const B200: speed_t = 0x06; +pub const B300: speed_t = 0x07; +pub const B600: speed_t = 0x08; +pub const B1200: speed_t = 0x09; +pub const B1800: speed_t = 0x0A; +pub const B2400: speed_t = 0x0B; +pub const B4800: speed_t = 0x0C; +pub const B9600: speed_t = 0x0D; +pub const B19200: speed_t = 0x0E; +pub const B38400: speed_t = 0x0F; +pub const B57600: speed_t = 0x10; +pub const B115200: speed_t = 0x11; +pub const B230400: speed_t = 0x12; +pub const B31250: speed_t = 0x13; + +pub const TCSANOW: ::c_int = 0x01; +pub const TCSADRAIN: ::c_int = 0x02; +pub const TCSAFLUSH: ::c_int = 0x04; + +pub const TCOOFF: ::c_int = 0x01; +pub const TCOON: ::c_int = 0x02; +pub const TCIOFF: ::c_int = 0x04; +pub const TCION: ::c_int = 0x08; + +pub const TCIFLUSH: ::c_int = 0x01; +pub const TCOFLUSH: ::c_int = 0x02; +pub const TCIOFLUSH: ::c_int = 0x03; + +pub const TCGETA: ::c_ulong = 0x8000; +pub const TCSETA: ::c_ulong = TCGETA + 1; +pub const TCSETAF: ::c_ulong = TCGETA + 2; +pub const TCSETAW: ::c_ulong = TCGETA + 3; +pub const TCWAITEVENT: ::c_ulong = TCGETA + 4; +pub const TCSBRK: ::c_ulong = TCGETA + 5; +pub const TCFLSH: ::c_ulong = TCGETA + 6; +pub const TCXONC: ::c_ulong = TCGETA + 7; +pub const TCQUERYCONNECTED: ::c_ulong = TCGETA + 8; +pub const TCGETBITS: ::c_ulong = TCGETA + 9; +pub const TCSETDTR: ::c_ulong = TCGETA + 10; +pub const TCSETRTS: ::c_ulong = TCGETA + 11; +pub const TIOCGWINSZ: ::c_ulong = TCGETA + 12; +pub const TIOCSWINSZ: ::c_ulong = TCGETA + 13; +pub const TCVTIME: ::c_ulong = TCGETA + 14; +pub const TIOCGPGRP: ::c_ulong = TCGETA + 15; +pub const TIOCSPGRP: ::c_ulong = TCGETA + 16; +pub const TIOCSCTTY: ::c_ulong = TCGETA + 17; +pub const TIOCMGET: ::c_ulong = TCGETA + 18; +pub const TIOCMSET: ::c_ulong = TCGETA + 19; +pub const TIOCSBRK: ::c_ulong = TCGETA + 20; +pub const TIOCCBRK: ::c_ulong = TCGETA + 21; +pub const TIOCMBIS: ::c_ulong = TCGETA + 22; +pub const TIOCMBIC: ::c_ulong = TCGETA + 23; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +// utmpx entry types +pub const EMPTY: ::c_short = 0; +pub const BOOT_TIME: ::c_short = 1; +pub const OLD_TIME: ::c_short = 2; +pub const NEW_TIME: ::c_short = 3; +pub const USER_PROCESS: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const DEAD_PROCESS: ::c_short = 7; + +pub const LOG_PID: ::c_int = 1 << 12; +pub const LOG_CONS: ::c_int = 2 << 12; +pub const LOG_ODELAY: ::c_int = 4 << 12; +pub const LOG_NDELAY: ::c_int = 8 << 12; +pub const LOG_SERIAL: ::c_int = 16 << 12; +pub const LOG_PERROR: ::c_int = 32 << 12; +pub const LOG_NOWAIT: ::c_int = 64 << 12; + +// spawn.h +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x10; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20; +pub const POSIX_SPAWN_SETSID: ::c_int = 0x40; + +const_fn! { + {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } +} + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize) + + CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & !0xff) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status & 0xff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status >> 8) & 0xff) != 0 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + ((status >> 16) & 0xff) != 0 + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 16) & 0xff + } + + // actually WIFCORED, but this is used everywhere else + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x10000) != 0 + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0x20000) != 0 + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn getpriority(which: ::c_int, who: id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: id_t, priority: ::c_int) -> ::c_int; + + pub fn endusershell(); + pub fn getpass(prompt: *const ::c_char) -> *mut ::c_char; + pub fn getusershell() -> *mut ::c_char; + pub fn issetugid() -> ::c_int; + pub fn setusershell(); + + pub fn utimensat( + fd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn _errnop() -> *mut ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + pub fn ppoll( + fds: *mut ::pollfd, + numfds: ::nfds_t, + timeout: *const ::timespec, + sigMask: *const sigset_t, + ) -> ::c_int; + + pub fn getspent() -> *mut spwd; + pub fn getspent_r( + pwd: *mut spwd, + buf: *mut ::c_char, + bufferSize: ::size_t, + res: *mut *mut spwd, + ) -> ::c_int; + pub fn setspent(); + pub fn endspent(); + pub fn getspnam(name: *const ::c_char) -> *mut spwd; + pub fn getspnam_r( + name: *const ::c_char, + spwd: *mut spwd, + buffer: *mut ::c_char, + bufferSize: ::size_t, + res: *mut *mut spwd, + ) -> ::c_int; + pub fn sgetspent(line: *const ::c_char) -> *mut spwd; + pub fn sgetspent_r( + line: *const ::c_char, + spwd: *mut spwd, + buffer: *mut ::c_char, + bufferSize: ::size_t, + res: *mut *mut spwd, + ) -> ::c_int; + pub fn fgetspent(file: *mut ::FILE) -> *mut spwd; + pub fn fgetspent_r( + file: *mut ::FILE, + spwd: *mut spwd, + buffer: *mut ::c_char, + bufferSize: ::size_t, + res: *mut *mut spwd, + ) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + pub fn pthread_create( + thread: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn valloc(numBytes: ::size_t) -> *mut ::c_void; + pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + + pub fn glob( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advice: ::c_int) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, count: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, count: ::c_int) -> ::ssize_t; + + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + environment: *const *const ::c_char, + ) -> ::c_int; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getgrouplist( + user: *const ::c_char, + basegroup: ::gid_t, + grouplist: *mut ::gid_t, + groupcount: *mut ::c_int, + ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwent() -> *mut passwd; + pub fn setpwent(); + pub fn endpwent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn setgrent(); + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + + pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; + pub fn setitimer( + which: ::c_int, + new_value: *const ::itimerval, + old_value: *mut ::itimerval, + ) -> ::c_int; + + pub fn regcomp(preg: *mut regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; + + pub fn regexec( + preg: *const regex_t, + input: *const ::c_char, + nmatch: ::size_t, + pmatch: *mut regmatch_t, + eflags: ::c_int, + ) -> ::c_int; + + pub fn regerror( + errcode: ::c_int, + preg: *const regex_t, + errbuf: *mut ::c_char, + errbuf_size: ::size_t, + ) -> ::size_t; + + pub fn regfree(preg: *mut regex_t); + + pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int; + pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtype: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + pub fn msgsnd( + msqid: ::c_int, + msgp: *const ::c_void, + msgsz: ::size_t, + msgflg: ::c_int, + ) -> ::c_int; + pub fn semget(key: ::key_t, nsems: ::c_int, semflg: ::c_int) -> ::c_int; + pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; + pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + + pub fn lsearch( + key: *const ::c_void, + base: *mut ::c_void, + nelp: *mut ::size_t, + width: ::size_t, + compar: ::Option ::c_int>, + ) -> *mut ::c_void; + pub fn lfind( + key: *const ::c_void, + base: *const ::c_void, + nelp: *mut ::size_t, + width: ::size_t, + compar: ::Option ::c_int>, + ) -> *mut ::c_void; + pub fn hcreate(nelt: ::size_t) -> ::c_int; + pub fn hdestroy(); + pub fn hsearch(entry: ::ENTRY, action: ::ACTION) -> *mut ::ENTRY; + + pub fn drand48() -> ::c_double; + pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; + pub fn lrand48() -> ::c_long; + pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn mrand48() -> ::c_long; + pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn srand48(seed: ::c_long); + pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; + pub fn lcong48(p: *mut ::c_ushort); + + pub fn clearenv() -> ::c_int; + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + + pub fn sync(); + pub fn getpagesize() -> ::c_int; + + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(file_actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy( + file_actions: *mut posix_spawn_file_actions_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + file_actions: *mut posix_spawn_file_actions_t, + fildes: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + file_actions: *mut posix_spawn_file_actions_t, + fildes: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + file_actions: *mut posix_spawn_file_actions_t, + fildes: ::c_int, + newfildes: ::c_int, + ) -> ::c_int; + + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + _flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + _pgroup: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, pgroup: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + sigdefault: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + sigdefault: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + _sigmask: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + sigmask: *const ::sigset_t, + ) -> ::c_int; + pub fn getopt_long( + argc: ::c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut ::c_int, + ) -> ::c_int; + pub fn strcasecmp_l( + string1: *const ::c_char, + string2: *const ::c_char, + locale: ::locale_t, + ) -> ::c_int; + pub fn strncasecmp_l( + string1: *const ::c_char, + string2: *const ::c_char, + length: ::size_t, + locale: ::locale_t, + ) -> ::c_int; +} + +#[link(name = "bsd")] +extern "C" { + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::pid_t; + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::c_int; + pub fn strsep(string: *mut *mut ::c_char, delimiters: *const ::c_char) -> *mut ::c_char; + pub fn explicit_bzero(buf: *mut ::c_void, len: ::size_t); + pub fn login_tty(_fd: ::c_int) -> ::c_int; + + pub fn sl_init() -> *mut StringList; + pub fn sl_add(sl: *mut StringList, n: *mut ::c_char) -> ::c_int; + pub fn sl_free(sl: *mut StringList, i: ::c_int); + pub fn sl_find(sl: *mut StringList, n: *mut ::c_char) -> *mut ::c_char; + + pub fn getprogname() -> *const ::c_char; + pub fn setprogname(progname: *const ::c_char); + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; +} + +#[link(name = "gnu")] +extern "C" { + pub fn memmem( + source: *const ::c_void, + sourceLength: ::size_t, + search: *const ::c_void, + searchLength: ::size_t, + ) -> *mut ::c_void; + + pub fn pthread_getattr_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_getname_np( + thread: ::pthread_t, + buffer: *mut ::c_char, + length: ::size_t, + ) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + mod b32; + pub use self::b32::*; + } +} + +cfg_if! { + if #[cfg(target_arch = "x86")] { + // TODO + // mod x86; + // pub use self::x86::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "aarch64")] { + // TODO + // mod aarch64; + // pub use self::aarch64::*; + } +} + +mod native; +pub use self::native::*; diff --git a/utshell-0.5.0/vendor/libc/src/unix/haiku/native.rs b/utshell-0.5.0/vendor/libc/src/unix/haiku/native.rs new file mode 100644 index 00000000..62d6392f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/haiku/native.rs @@ -0,0 +1,1488 @@ +// This module contains bindings to the native Haiku API. The Haiku API +// originates from BeOS, and it was the original way to perform low level +// system and IO operations. The POSIX API was in that era was like a +// compatibility layer. In current Haiku development, both the POSIX API and +// the Haiku API are considered to be co-equal status. However, they are not +// integrated like they are on other UNIX platforms, which means that for many +// low level concepts there are two versions, like processes (POSIX) and +// teams (Haiku), or pthreads and native threads. +// +// Both the POSIX API and the Haiku API live in libroot.so, the library that is +// linked to any binary by default. +// +// This file follows the Haiku API for Haiku R1 beta 2. It is organized by the +// C/C++ header files in which the concepts can be found, while adhering to the +// style guide for this crate. + +// Helper macro to generate u32 constants. The Haiku API uses (non-standard) +// multi-character constants (like 'UPDA' or 'MSGM') to represent 32 bit +// integer constants. + +macro_rules! haiku_constant { + ($a:tt, $b:tt, $c:tt, $d:tt) => { + (($a as u32) << 24) + (($b as u32) << 16) + (($c as u32) << 8) + ($d as u32) + }; +} + +// support/SupportDefs.h +pub type status_t = i32; +pub type bigtime_t = i64; +pub type nanotime_t = i64; +pub type type_code = u32; +pub type perform_code = u32; + +// kernel/OS.h +pub type area_id = i32; +pub type port_id = i32; +pub type sem_id = i32; +pub type team_id = i32; +pub type thread_id = i32; + +pub type thread_func = extern "C" fn(*mut ::c_void) -> status_t; + +// kernel/image.h +pub type image_id = i32; + +e! { + // kernel/OS.h + pub enum thread_state { + B_THREAD_RUNNING = 1, + B_THREAD_READY, + B_THREAD_RECEIVING, + B_THREAD_ASLEEP, + B_THREAD_SUSPENDED, + B_THREAD_WAITING + } + + // kernel/image.h + pub enum image_type { + B_APP_IMAGE = 1, + B_LIBRARY_IMAGE, + B_ADD_ON_IMAGE, + B_SYSTEM_IMAGE + } + + // kernel/scheduler.h + + pub enum be_task_flags { + B_DEFAULT_MEDIA_PRIORITY = 0x000, + B_OFFLINE_PROCESSING = 0x001, + B_STATUS_RENDERING = 0x002, + B_USER_INPUT_HANDLING = 0x004, + B_LIVE_VIDEO_MANIPULATION = 0x008, + B_VIDEO_PLAYBACK = 0x010, + B_VIDEO_RECORDING = 0x020, + B_LIVE_AUDIO_MANIPULATION = 0x040, + B_AUDIO_PLAYBACK = 0x080, + B_AUDIO_RECORDING = 0x100, + B_LIVE_3D_RENDERING = 0x200, + B_NUMBER_CRUNCHING = 0x400, + B_MIDI_PROCESSING = 0x800, + } + + pub enum schduler_mode { + SCHEDULER_MODE_LOW_LATENCY, + SCHEDULER_MODE_POWER_SAVING, + } + + // FindDirectory.h + pub enum path_base_directory { + B_FIND_PATH_INSTALLATION_LOCATION_DIRECTORY, + B_FIND_PATH_ADD_ONS_DIRECTORY, + B_FIND_PATH_APPS_DIRECTORY, + B_FIND_PATH_BIN_DIRECTORY, + B_FIND_PATH_BOOT_DIRECTORY, + B_FIND_PATH_CACHE_DIRECTORY, + B_FIND_PATH_DATA_DIRECTORY, + B_FIND_PATH_DEVELOP_DIRECTORY, + B_FIND_PATH_DEVELOP_LIB_DIRECTORY, + B_FIND_PATH_DOCUMENTATION_DIRECTORY, + B_FIND_PATH_ETC_DIRECTORY, + B_FIND_PATH_FONTS_DIRECTORY, + B_FIND_PATH_HEADERS_DIRECTORY, + B_FIND_PATH_LIB_DIRECTORY, + B_FIND_PATH_LOG_DIRECTORY, + B_FIND_PATH_MEDIA_NODES_DIRECTORY, + B_FIND_PATH_PACKAGES_DIRECTORY, + B_FIND_PATH_PREFERENCES_DIRECTORY, + B_FIND_PATH_SERVERS_DIRECTORY, + B_FIND_PATH_SETTINGS_DIRECTORY, + B_FIND_PATH_SOUNDS_DIRECTORY, + B_FIND_PATH_SPOOL_DIRECTORY, + B_FIND_PATH_TRANSLATORS_DIRECTORY, + B_FIND_PATH_VAR_DIRECTORY, + B_FIND_PATH_IMAGE_PATH = 1000, + B_FIND_PATH_PACKAGE_PATH, + } + + pub enum directory_which { + B_DESKTOP_DIRECTORY = 0, + B_TRASH_DIRECTORY, + B_SYSTEM_DIRECTORY = 1000, + B_SYSTEM_ADDONS_DIRECTORY = 1002, + B_SYSTEM_BOOT_DIRECTORY, + B_SYSTEM_FONTS_DIRECTORY, + B_SYSTEM_LIB_DIRECTORY, + B_SYSTEM_SERVERS_DIRECTORY, + B_SYSTEM_APPS_DIRECTORY, + B_SYSTEM_BIN_DIRECTORY, + B_SYSTEM_DOCUMENTATION_DIRECTORY = 1010, + B_SYSTEM_PREFERENCES_DIRECTORY, + B_SYSTEM_TRANSLATORS_DIRECTORY, + B_SYSTEM_MEDIA_NODES_DIRECTORY, + B_SYSTEM_SOUNDS_DIRECTORY, + B_SYSTEM_DATA_DIRECTORY, + B_SYSTEM_DEVELOP_DIRECTORY, + B_SYSTEM_PACKAGES_DIRECTORY, + B_SYSTEM_HEADERS_DIRECTORY, + B_SYSTEM_ETC_DIRECTORY = 2008, + B_SYSTEM_SETTINGS_DIRECTORY = 2010, + B_SYSTEM_LOG_DIRECTORY = 2012, + B_SYSTEM_SPOOL_DIRECTORY, + B_SYSTEM_TEMP_DIRECTORY, + B_SYSTEM_VAR_DIRECTORY, + B_SYSTEM_CACHE_DIRECTORY = 2020, + B_SYSTEM_NONPACKAGED_DIRECTORY = 2023, + B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, + B_SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY, + B_SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY, + B_SYSTEM_NONPACKAGED_BIN_DIRECTORY, + B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, + B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY, + B_SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY, + B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY, + B_SYSTEM_NONPACKAGED_LIB_DIRECTORY, + B_SYSTEM_NONPACKAGED_HEADERS_DIRECTORY, + B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY, + B_USER_DIRECTORY = 3000, + B_USER_CONFIG_DIRECTORY, + B_USER_ADDONS_DIRECTORY, + B_USER_BOOT_DIRECTORY, + B_USER_FONTS_DIRECTORY, + B_USER_LIB_DIRECTORY, + B_USER_SETTINGS_DIRECTORY, + B_USER_DESKBAR_DIRECTORY, + B_USER_PRINTERS_DIRECTORY, + B_USER_TRANSLATORS_DIRECTORY, + B_USER_MEDIA_NODES_DIRECTORY, + B_USER_SOUNDS_DIRECTORY, + B_USER_DATA_DIRECTORY, + B_USER_CACHE_DIRECTORY, + B_USER_PACKAGES_DIRECTORY, + B_USER_HEADERS_DIRECTORY, + B_USER_NONPACKAGED_DIRECTORY, + B_USER_NONPACKAGED_ADDONS_DIRECTORY, + B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY, + B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY, + B_USER_NONPACKAGED_BIN_DIRECTORY, + B_USER_NONPACKAGED_DATA_DIRECTORY, + B_USER_NONPACKAGED_FONTS_DIRECTORY, + B_USER_NONPACKAGED_SOUNDS_DIRECTORY, + B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY, + B_USER_NONPACKAGED_LIB_DIRECTORY, + B_USER_NONPACKAGED_HEADERS_DIRECTORY, + B_USER_NONPACKAGED_DEVELOP_DIRECTORY, + B_USER_DEVELOP_DIRECTORY, + B_USER_DOCUMENTATION_DIRECTORY, + B_USER_SERVERS_DIRECTORY, + B_USER_APPS_DIRECTORY, + B_USER_BIN_DIRECTORY, + B_USER_PREFERENCES_DIRECTORY, + B_USER_ETC_DIRECTORY, + B_USER_LOG_DIRECTORY, + B_USER_SPOOL_DIRECTORY, + B_USER_VAR_DIRECTORY, + B_APPS_DIRECTORY = 4000, + B_PREFERENCES_DIRECTORY, + B_UTILITIES_DIRECTORY, + B_PACKAGE_LINKS_DIRECTORY, + } + + // kernel/OS.h + + pub enum topology_level_type { + B_TOPOLOGY_UNKNOWN, + B_TOPOLOGY_ROOT, + B_TOPOLOGY_SMT, + B_TOPOLOGY_CORE, + B_TOPOLOGY_PACKAGE, + } + + pub enum cpu_platform { + B_CPU_UNKNOWN, + B_CPU_x86, + B_CPU_x86_64, + B_CPU_PPC, + B_CPU_PPC_64, + B_CPU_M68K, + B_CPU_ARM, + B_CPU_ARM_64, + B_CPU_ALPHA, + B_CPU_MIPS, + B_CPU_SH, + B_CPU_SPARC, + B_CPU_RISC_V + } + + pub enum cpu_vendor { + B_CPU_VENDOR_UNKNOWN, + B_CPU_VENDOR_AMD, + B_CPU_VENDOR_CYRIX, + B_CPU_VENDOR_IDT, + B_CPU_VENDOR_INTEL, + B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR, + B_CPU_VENDOR_RISE, + B_CPU_VENDOR_TRANSMETA, + B_CPU_VENDOR_VIA, + B_CPU_VENDOR_IBM, + B_CPU_VENDOR_MOTOROLA, + B_CPU_VENDOR_NEC, + B_CPU_VENDOR_HYGON, + B_CPU_VENDOR_SUN, + B_CPU_VENDOR_FUJITSU + } +} + +s! { + // kernel/OS.h + pub struct area_info { + pub area: area_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub size: usize, + pub lock: u32, + pub protection: u32, + pub team: team_id, + pub ram_size: u32, + pub copy_count: u32, + pub in_count: u32, + pub out_count: u32, + pub address: *mut ::c_void + } + + pub struct port_info { + pub port: port_id, + pub team: team_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub capacity: i32, + pub queue_count: i32, + pub total_count: i32, + } + + pub struct port_message_info { + pub size: ::size_t, + pub sender: ::uid_t, + pub sender_group: ::gid_t, + pub sender_team: ::team_id + } + + pub struct team_info { + pub team: team_id, + pub thread_count: i32, + pub image_count: i32, + pub area_count: i32, + pub debugger_nub_thread: thread_id, + pub debugger_nub_port: port_id, + pub argc: i32, + pub args: [::c_char; 64], + pub uid: ::uid_t, + pub gid: ::gid_t + } + + pub struct sem_info { + pub sem: sem_id, + pub team: team_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub count: i32, + pub latest_holder: thread_id + } + + pub struct team_usage_info { + pub user_time: bigtime_t, + pub kernel_time: bigtime_t + } + + pub struct thread_info { + pub thread: thread_id, + pub team: team_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub state: thread_state, + pub priority: i32, + pub sem: sem_id, + pub user_time: bigtime_t, + pub kernel_time: bigtime_t, + pub stack_base: *mut ::c_void, + pub stack_end: *mut ::c_void + } + + pub struct cpu_info { + pub active_time: bigtime_t, + pub enabled: bool, + pub current_frequency: u64 + } + + pub struct system_info { + pub boot_time: bigtime_t, + pub cpu_count: u32, + pub max_pages: u64, + pub used_pages: u64, + pub cached_pages: u64, + pub block_cache_pages: u64, + pub ignored_pages: u64, + pub needed_memory: u64, + pub free_memory: u64, + pub max_swap_pages: u64, + pub free_swap_pages: u64, + pub page_faults: u32, + pub max_sems: u32, + pub used_sems: u32, + pub max_ports: u32, + pub used_ports: u32, + pub max_threads: u32, + pub used_threads: u32, + pub max_teams: u32, + pub used_teams: u32, + pub kernel_name: [::c_char; B_FILE_NAME_LENGTH], + pub kernel_build_date: [::c_char; B_OS_NAME_LENGTH], + pub kernel_build_time: [::c_char; B_OS_NAME_LENGTH], + pub kernel_version: i64, + pub abi: u32 + } + + pub struct object_wait_info { + pub object: i32, + pub type_: u16, + pub events: u16 + } + + pub struct cpu_topology_root_info { + pub platform: cpu_platform, + } + + pub struct cpu_topology_package_info { + pub vendor: cpu_vendor, + pub cache_line_size: u32, + } + + pub struct cpu_topology_core_info { + pub model: u32, + pub default_frequency: u64, + } + // kernel/fs_attr.h + pub struct attr_info { + pub type_: u32, + pub size: ::off_t + } + + // kernel/fs_index.h + pub struct index_info { + pub type_: u32, + pub size: ::off_t, + pub modification_time: ::time_t, + pub creation_time: ::time_t, + pub uid: ::uid_t, + pub gid: ::gid_t + } + + //kernel/fs_info.h + pub struct fs_info { + pub dev: ::dev_t, + pub root: ::ino_t, + pub flags: u32, + pub block_size: ::off_t, + pub io_size: ::off_t, + pub total_blocks: ::off_t, + pub free_blocks: ::off_t, + pub total_nodes: ::off_t, + pub free_nodes: ::off_t, + pub device_name: [::c_char; 128], + pub volume_name: [::c_char; B_FILE_NAME_LENGTH], + pub fsh_name: [::c_char; B_OS_NAME_LENGTH] + } + + // kernel/image.h + pub struct image_info { + pub id: image_id, + pub image_type: ::c_int, + pub sequence: i32, + pub init_order: i32, + pub init_routine: extern "C" fn(), + pub term_routine: extern "C" fn(), + pub device: ::dev_t, + pub node: ::ino_t, + pub name: [::c_char; ::PATH_MAX as usize], + pub text: *mut ::c_void, + pub data: *mut ::c_void, + pub text_size: i32, + pub data_size: i32, + pub api_version: i32, + pub abi: i32 + } + + pub struct __c_anonymous_eax_0 { + pub max_eax: u32, + pub vendor_id: [::c_char; 12], + } + + pub struct __c_anonymous_eax_1 { + pub stepping: u32, + pub model: u32, + pub family: u32, + pub tpe: u32, + __reserved_0: u32, + pub extended_model: u32, + pub extended_family: u32, + __reserved_1: u32, + pub brand_index: u32, + pub clflush: u32, + pub logical_cpus: u32, + pub apic_id: u32, + pub features: u32, + pub extended_features: u32, + } + + pub struct __c_anonymous_eax_2 { + pub call_num: u8, + pub cache_descriptors: [u8; 15], + } + + pub struct __c_anonymous_eax_3 { + __reserved: [u32; 2], + pub serial_number_high: u32, + pub serial_number_low: u32, + } + + pub struct __c_anonymous_regs { + pub eax: u32, + pub ebx: u32, + pub edx: u32, + pub ecx: u32, + } +} + +s_no_extra_traits! { + #[cfg(libc_union)] + pub union cpuid_info { + pub eax_0: __c_anonymous_eax_0, + pub eax_1: __c_anonymous_eax_1, + pub eax_2: __c_anonymous_eax_2, + pub eax_3: __c_anonymous_eax_3, + pub as_chars: [::c_char; 16], + pub regs: __c_anonymous_regs, + } + + #[cfg(libc_union)] + pub union __c_anonymous_cpu_topology_info_data { + pub root: cpu_topology_root_info, + pub package: cpu_topology_package_info, + pub core: cpu_topology_core_info, + } + + pub struct cpu_topology_node_info { + pub id: u32, + pub type_: topology_level_type, + pub level: u32, + #[cfg(libc_union)] + pub data: __c_anonymous_cpu_topology_info_data, + #[cfg(not(libc_union))] + pub data: cpu_topology_core_info, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[cfg(libc_union)] + impl PartialEq for cpuid_info { + fn eq(&self, other: &cpuid_info) -> bool { + unsafe { + self.eax_0 == other.eax_0 + || self.eax_1 == other.eax_1 + || self.eax_2 == other.eax_2 + || self.eax_3 == other.eax_3 + || self.as_chars == other.as_chars + || self.regs == other.regs + } + } + } + #[cfg(libc_union)] + impl Eq for cpuid_info {} + #[cfg(libc_union)] + impl ::fmt::Debug for cpuid_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("cpuid_info") + .field("eax_0", &self.eax_0) + .field("eax_1", &self.eax_1) + .field("eax_2", &self.eax_2) + .field("eax_3", &self.eax_3) + .field("as_chars", &self.as_chars) + .field("regs", &self.regs) + .finish() + } + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_cpu_topology_info_data { + fn eq(&self, other: &__c_anonymous_cpu_topology_info_data) -> bool { + unsafe { + self.root == other.root + || self.package == other.package + || self.core == other.core + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_cpu_topology_info_data {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_cpu_topology_info_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous_cpu_topology_info_data") + .field("root", &self.root) + .field("package", &self.package) + .field("core", &self.core) + .finish() + } + } + } + + impl PartialEq for cpu_topology_node_info { + fn eq(&self, other: &cpu_topology_node_info) -> bool { + self.id == other.id + && self.type_ == other.type_ + && self.level == other.level + } + } + + impl Eq for cpu_topology_node_info {} + impl ::fmt::Debug for cpu_topology_node_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("cpu_topology_node_info") + .field("id", &self.id) + .field("type", &self.type_) + .field("level", &self.level) + .finish() + } + } + } +} + +// kernel/OS.h +pub const B_OS_NAME_LENGTH: usize = 32; +pub const B_PAGE_SIZE: usize = 4096; +pub const B_INFINITE_TIMEOUT: usize = 9223372036854775807; + +pub const B_RELATIVE_TIMEOUT: u32 = 0x8; +pub const B_ABSOLUTE_TIMEOUT: u32 = 0x10; +pub const B_TIMEOUT_REAL_TIME_BASE: u32 = 0x40; +pub const B_ABSOLUTE_REAL_TIME_TIMEOUT: u32 = B_ABSOLUTE_TIMEOUT | B_TIMEOUT_REAL_TIME_BASE; + +pub const B_NO_LOCK: u32 = 0; +pub const B_LAZY_LOCK: u32 = 1; +pub const B_FULL_LOCK: u32 = 2; +pub const B_CONTIGUOUS: u32 = 3; +pub const B_LOMEM: u32 = 4; +pub const B_32_BIT_FULL_LOCK: u32 = 5; +pub const B_32_BIT_CONTIGUOUS: u32 = 6; + +pub const B_ANY_ADDRESS: u32 = 0; +pub const B_EXACT_ADDRESS: u32 = 1; +pub const B_BASE_ADDRESS: u32 = 2; +pub const B_CLONE_ADDRESS: u32 = 3; +pub const B_ANY_KERNEL_ADDRESS: u32 = 4; +pub const B_RANDOMIZED_ANY_ADDRESS: u32 = 6; +pub const B_RANDOMIZED_BASE_ADDRESS: u32 = 7; + +pub const B_READ_AREA: u32 = 1 << 0; +pub const B_WRITE_AREA: u32 = 1 << 1; +pub const B_EXECUTE_AREA: u32 = 1 << 2; +pub const B_STACK_AREA: u32 = 1 << 3; +pub const B_CLONEABLE_AREA: u32 = 1 << 8; + +pub const B_CAN_INTERRUPT: u32 = 0x01; +pub const B_CHECK_PERMISSION: u32 = 0x04; +pub const B_KILL_CAN_INTERRUPT: u32 = 0x20; +pub const B_DO_NOT_RESCHEDULE: u32 = 0x02; +pub const B_RELEASE_ALL: u32 = 0x08; +pub const B_RELEASE_IF_WAITING_ONLY: u32 = 0x10; + +pub const B_CURRENT_TEAM: team_id = 0; +pub const B_SYSTEM_TEAM: team_id = 1; + +pub const B_TEAM_USAGE_SELF: i32 = 0; +pub const B_TEAM_USAGE_CHILDREN: i32 = -1; + +pub const B_IDLE_PRIORITY: i32 = 0; +pub const B_LOWEST_ACTIVE_PRIORITY: i32 = 1; +pub const B_LOW_PRIORITY: i32 = 5; +pub const B_NORMAL_PRIORITY: i32 = 10; +pub const B_DISPLAY_PRIORITY: i32 = 15; +pub const B_URGENT_DISPLAY_PRIORITY: i32 = 20; +pub const B_REAL_TIME_DISPLAY_PRIORITY: i32 = 100; +pub const B_URGENT_PRIORITY: i32 = 110; +pub const B_REAL_TIME_PRIORITY: i32 = 120; + +pub const B_SYSTEM_TIMEBASE: i32 = 0; +pub const B_FIRST_REAL_TIME_PRIORITY: i32 = B_REAL_TIME_DISPLAY_PRIORITY; + +pub const B_ONE_SHOT_ABSOLUTE_ALARM: u32 = 1; +pub const B_ONE_SHOT_RELATIVE_ALARM: u32 = 2; +pub const B_PERIODIC_ALARM: u32 = 3; + +pub const B_OBJECT_TYPE_FD: u16 = 0; +pub const B_OBJECT_TYPE_SEMAPHORE: u16 = 1; +pub const B_OBJECT_TYPE_PORT: u16 = 2; +pub const B_OBJECT_TYPE_THREAD: u16 = 3; + +pub const B_EVENT_READ: u16 = 0x0001; +pub const B_EVENT_WRITE: u16 = 0x0002; +pub const B_EVENT_ERROR: u16 = 0x0004; +pub const B_EVENT_PRIORITY_READ: u16 = 0x0008; +pub const B_EVENT_PRIORITY_WRITE: u16 = 0x0010; +pub const B_EVENT_HIGH_PRIORITY_READ: u16 = 0x0020; +pub const B_EVENT_HIGH_PRIORITY_WRITE: u16 = 0x0040; +pub const B_EVENT_DISCONNECTED: u16 = 0x0080; +pub const B_EVENT_ACQUIRE_SEMAPHORE: u16 = 0x0001; +pub const B_EVENT_INVALID: u16 = 0x1000; + +// kernel/fs_info.h +pub const B_FS_IS_READONLY: u32 = 0x00000001; +pub const B_FS_IS_REMOVABLE: u32 = 0x00000002; +pub const B_FS_IS_PERSISTENT: u32 = 0x00000004; +pub const B_FS_IS_SHARED: u32 = 0x00000008; +pub const B_FS_HAS_MIME: u32 = 0x00010000; +pub const B_FS_HAS_ATTR: u32 = 0x00020000; +pub const B_FS_HAS_QUERY: u32 = 0x00040000; +pub const B_FS_HAS_SELF_HEALING_LINKS: u32 = 0x00080000; +pub const B_FS_HAS_ALIASES: u32 = 0x00100000; +pub const B_FS_SUPPORTS_NODE_MONITORING: u32 = 0x00200000; +pub const B_FS_SUPPORTS_MONITOR_CHILDREN: u32 = 0x00400000; + +// kernel/fs_query.h +pub const B_LIVE_QUERY: u32 = 0x00000001; +pub const B_QUERY_NON_INDEXED: u32 = 0x00000002; + +// kernel/fs_volume.h +pub const B_MOUNT_READ_ONLY: u32 = 1; +pub const B_MOUNT_VIRTUAL_DEVICE: u32 = 2; +pub const B_FORCE_UNMOUNT: u32 = 1; + +// kernel/image.h +pub const B_FLUSH_DCACHE: u32 = 0x0001; +pub const B_FLUSH_ICACHE: u32 = 0x0004; +pub const B_INVALIDATE_DCACHE: u32 = 0x0002; +pub const B_INVALIDATE_ICACHE: u32 = 0x0008; + +pub const B_SYMBOL_TYPE_DATA: i32 = 0x1; +pub const B_SYMBOL_TYPE_TEXT: i32 = 0x2; +pub const B_SYMBOL_TYPE_ANY: i32 = 0x5; + +// storage/StorageDefs.h +pub const B_DEV_NAME_LENGTH: usize = 128; +pub const B_FILE_NAME_LENGTH: usize = ::FILENAME_MAX as usize; +pub const B_PATH_NAME_LENGTH: usize = ::PATH_MAX as usize; +pub const B_ATTR_NAME_LENGTH: usize = B_FILE_NAME_LENGTH - 1; +pub const B_MIME_TYPE_LENGTH: usize = B_ATTR_NAME_LENGTH - 15; +pub const B_MAX_SYMLINKS: usize = 16; + +// Haiku open modes in BFile are passed as u32 +pub const B_READ_ONLY: u32 = ::O_RDONLY as u32; +pub const B_WRITE_ONLY: u32 = ::O_WRONLY as u32; +pub const B_READ_WRITE: u32 = ::O_RDWR as u32; + +pub const B_FAIL_IF_EXISTS: u32 = ::O_EXCL as u32; +pub const B_CREATE_FILE: u32 = ::O_CREAT as u32; +pub const B_ERASE_FILE: u32 = ::O_TRUNC as u32; +pub const B_OPEN_AT_END: u32 = ::O_APPEND as u32; + +pub const B_FILE_NODE: u32 = 0x01; +pub const B_SYMLINK_NODE: u32 = 0x02; +pub const B_DIRECTORY_NODE: u32 = 0x04; +pub const B_ANY_NODE: u32 = 0x07; + +// support/Errors.h +pub const B_GENERAL_ERROR_BASE: status_t = core::i32::MIN; +pub const B_OS_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x1000; +pub const B_APP_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x2000; +pub const B_INTERFACE_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x3000; +pub const B_MEDIA_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x4000; +pub const B_TRANSLATION_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x4800; +pub const B_MIDI_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x5000; +pub const B_STORAGE_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x6000; +pub const B_POSIX_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x7000; +pub const B_MAIL_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x8000; +pub const B_PRINT_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x9000; +pub const B_DEVICE_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0xa000; +pub const B_ERRORS_END: status_t = B_GENERAL_ERROR_BASE + 0xffff; + +// General errors +pub const B_NO_MEMORY: status_t = B_GENERAL_ERROR_BASE + 0; +pub const B_IO_ERROR: status_t = B_GENERAL_ERROR_BASE + 1; +pub const B_PERMISSION_DENIED: status_t = B_GENERAL_ERROR_BASE + 2; +pub const B_BAD_INDEX: status_t = B_GENERAL_ERROR_BASE + 3; +pub const B_BAD_TYPE: status_t = B_GENERAL_ERROR_BASE + 4; +pub const B_BAD_VALUE: status_t = B_GENERAL_ERROR_BASE + 5; +pub const B_MISMATCHED_VALUES: status_t = B_GENERAL_ERROR_BASE + 6; +pub const B_NAME_NOT_FOUND: status_t = B_GENERAL_ERROR_BASE + 7; +pub const B_NAME_IN_USE: status_t = B_GENERAL_ERROR_BASE + 8; +pub const B_TIMED_OUT: status_t = B_GENERAL_ERROR_BASE + 9; +pub const B_INTERRUPTED: status_t = B_GENERAL_ERROR_BASE + 10; +pub const B_WOULD_BLOCK: status_t = B_GENERAL_ERROR_BASE + 11; +pub const B_CANCELED: status_t = B_GENERAL_ERROR_BASE + 12; +pub const B_NO_INIT: status_t = B_GENERAL_ERROR_BASE + 13; +pub const B_NOT_INITIALIZED: status_t = B_GENERAL_ERROR_BASE + 13; +pub const B_BUSY: status_t = B_GENERAL_ERROR_BASE + 14; +pub const B_NOT_ALLOWED: status_t = B_GENERAL_ERROR_BASE + 15; +pub const B_BAD_DATA: status_t = B_GENERAL_ERROR_BASE + 16; +pub const B_DONT_DO_THAT: status_t = B_GENERAL_ERROR_BASE + 17; + +pub const B_ERROR: status_t = -1; +pub const B_OK: status_t = 0; +pub const B_NO_ERROR: status_t = 0; + +// Kernel kit errors +pub const B_BAD_SEM_ID: status_t = B_OS_ERROR_BASE + 0; +pub const B_NO_MORE_SEMS: status_t = B_OS_ERROR_BASE + 1; + +pub const B_BAD_THREAD_ID: status_t = B_OS_ERROR_BASE + 0x100; +pub const B_NO_MORE_THREADS: status_t = B_OS_ERROR_BASE + 0x101; +pub const B_BAD_THREAD_STATE: status_t = B_OS_ERROR_BASE + 0x102; +pub const B_BAD_TEAM_ID: status_t = B_OS_ERROR_BASE + 0x103; +pub const B_NO_MORE_TEAMS: status_t = B_OS_ERROR_BASE + 0x104; + +pub const B_BAD_PORT_ID: status_t = B_OS_ERROR_BASE + 0x200; +pub const B_NO_MORE_PORTS: status_t = B_OS_ERROR_BASE + 0x201; + +pub const B_BAD_IMAGE_ID: status_t = B_OS_ERROR_BASE + 0x300; +pub const B_BAD_ADDRESS: status_t = B_OS_ERROR_BASE + 0x301; +pub const B_NOT_AN_EXECUTABLE: status_t = B_OS_ERROR_BASE + 0x302; +pub const B_MISSING_LIBRARY: status_t = B_OS_ERROR_BASE + 0x303; +pub const B_MISSING_SYMBOL: status_t = B_OS_ERROR_BASE + 0x304; +pub const B_UNKNOWN_EXECUTABLE: status_t = B_OS_ERROR_BASE + 0x305; +pub const B_LEGACY_EXECUTABLE: status_t = B_OS_ERROR_BASE + 0x306; + +pub const B_DEBUGGER_ALREADY_INSTALLED: status_t = B_OS_ERROR_BASE + 0x400; + +// Application kit errors +pub const B_BAD_REPLY: status_t = B_APP_ERROR_BASE + 0; +pub const B_DUPLICATE_REPLY: status_t = B_APP_ERROR_BASE + 1; +pub const B_MESSAGE_TO_SELF: status_t = B_APP_ERROR_BASE + 2; +pub const B_BAD_HANDLER: status_t = B_APP_ERROR_BASE + 3; +pub const B_ALREADY_RUNNING: status_t = B_APP_ERROR_BASE + 4; +pub const B_LAUNCH_FAILED: status_t = B_APP_ERROR_BASE + 5; +pub const B_AMBIGUOUS_APP_LAUNCH: status_t = B_APP_ERROR_BASE + 6; +pub const B_UNKNOWN_MIME_TYPE: status_t = B_APP_ERROR_BASE + 7; +pub const B_BAD_SCRIPT_SYNTAX: status_t = B_APP_ERROR_BASE + 8; +pub const B_LAUNCH_FAILED_NO_RESOLVE_LINK: status_t = B_APP_ERROR_BASE + 9; +pub const B_LAUNCH_FAILED_EXECUTABLE: status_t = B_APP_ERROR_BASE + 10; +pub const B_LAUNCH_FAILED_APP_NOT_FOUND: status_t = B_APP_ERROR_BASE + 11; +pub const B_LAUNCH_FAILED_APP_IN_TRASH: status_t = B_APP_ERROR_BASE + 12; +pub const B_LAUNCH_FAILED_NO_PREFERRED_APP: status_t = B_APP_ERROR_BASE + 13; +pub const B_LAUNCH_FAILED_FILES_APP_NOT_FOUND: status_t = B_APP_ERROR_BASE + 14; +pub const B_BAD_MIME_SNIFFER_RULE: status_t = B_APP_ERROR_BASE + 15; +pub const B_NOT_A_MESSAGE: status_t = B_APP_ERROR_BASE + 16; +pub const B_SHUTDOWN_CANCELLED: status_t = B_APP_ERROR_BASE + 17; +pub const B_SHUTTING_DOWN: status_t = B_APP_ERROR_BASE + 18; + +// Storage kit errors +pub const B_FILE_ERROR: status_t = B_STORAGE_ERROR_BASE + 0; +pub const B_FILE_EXISTS: status_t = B_STORAGE_ERROR_BASE + 2; +pub const B_ENTRY_NOT_FOUND: status_t = B_STORAGE_ERROR_BASE + 3; +pub const B_NAME_TOO_LONG: status_t = B_STORAGE_ERROR_BASE + 4; +pub const B_NOT_A_DIRECTORY: status_t = B_STORAGE_ERROR_BASE + 5; +pub const B_DIRECTORY_NOT_EMPTY: status_t = B_STORAGE_ERROR_BASE + 6; +pub const B_DEVICE_FULL: status_t = B_STORAGE_ERROR_BASE + 7; +pub const B_READ_ONLY_DEVICE: status_t = B_STORAGE_ERROR_BASE + 8; +pub const B_IS_A_DIRECTORY: status_t = B_STORAGE_ERROR_BASE + 9; +pub const B_NO_MORE_FDS: status_t = B_STORAGE_ERROR_BASE + 10; +pub const B_CROSS_DEVICE_LINK: status_t = B_STORAGE_ERROR_BASE + 11; +pub const B_LINK_LIMIT: status_t = B_STORAGE_ERROR_BASE + 12; +pub const B_BUSTED_PIPE: status_t = B_STORAGE_ERROR_BASE + 13; +pub const B_UNSUPPORTED: status_t = B_STORAGE_ERROR_BASE + 14; +pub const B_PARTITION_TOO_SMALL: status_t = B_STORAGE_ERROR_BASE + 15; +pub const B_PARTIAL_READ: status_t = B_STORAGE_ERROR_BASE + 16; +pub const B_PARTIAL_WRITE: status_t = B_STORAGE_ERROR_BASE + 17; + +// Mapped posix errors +pub const B_BUFFER_OVERFLOW: status_t = ::EOVERFLOW; +pub const B_TOO_MANY_ARGS: status_t = ::E2BIG; +pub const B_FILE_TOO_LARGE: status_t = ::EFBIG; +pub const B_RESULT_NOT_REPRESENTABLE: status_t = ::ERANGE; +pub const B_DEVICE_NOT_FOUND: status_t = ::ENODEV; +pub const B_NOT_SUPPORTED: status_t = ::EOPNOTSUPP; + +// Media kit errors +pub const B_STREAM_NOT_FOUND: status_t = B_MEDIA_ERROR_BASE + 0; +pub const B_SERVER_NOT_FOUND: status_t = B_MEDIA_ERROR_BASE + 1; +pub const B_RESOURCE_NOT_FOUND: status_t = B_MEDIA_ERROR_BASE + 2; +pub const B_RESOURCE_UNAVAILABLE: status_t = B_MEDIA_ERROR_BASE + 3; +pub const B_BAD_SUBSCRIBER: status_t = B_MEDIA_ERROR_BASE + 4; +pub const B_SUBSCRIBER_NOT_ENTERED: status_t = B_MEDIA_ERROR_BASE + 5; +pub const B_BUFFER_NOT_AVAILABLE: status_t = B_MEDIA_ERROR_BASE + 6; +pub const B_LAST_BUFFER_ERROR: status_t = B_MEDIA_ERROR_BASE + 7; + +pub const B_MEDIA_SYSTEM_FAILURE: status_t = B_MEDIA_ERROR_BASE + 100; +pub const B_MEDIA_BAD_NODE: status_t = B_MEDIA_ERROR_BASE + 101; +pub const B_MEDIA_NODE_BUSY: status_t = B_MEDIA_ERROR_BASE + 102; +pub const B_MEDIA_BAD_FORMAT: status_t = B_MEDIA_ERROR_BASE + 103; +pub const B_MEDIA_BAD_BUFFER: status_t = B_MEDIA_ERROR_BASE + 104; +pub const B_MEDIA_TOO_MANY_NODES: status_t = B_MEDIA_ERROR_BASE + 105; +pub const B_MEDIA_TOO_MANY_BUFFERS: status_t = B_MEDIA_ERROR_BASE + 106; +pub const B_MEDIA_NODE_ALREADY_EXISTS: status_t = B_MEDIA_ERROR_BASE + 107; +pub const B_MEDIA_BUFFER_ALREADY_EXISTS: status_t = B_MEDIA_ERROR_BASE + 108; +pub const B_MEDIA_CANNOT_SEEK: status_t = B_MEDIA_ERROR_BASE + 109; +pub const B_MEDIA_CANNOT_CHANGE_RUN_MODE: status_t = B_MEDIA_ERROR_BASE + 110; +pub const B_MEDIA_APP_ALREADY_REGISTERED: status_t = B_MEDIA_ERROR_BASE + 111; +pub const B_MEDIA_APP_NOT_REGISTERED: status_t = B_MEDIA_ERROR_BASE + 112; +pub const B_MEDIA_CANNOT_RECLAIM_BUFFERS: status_t = B_MEDIA_ERROR_BASE + 113; +pub const B_MEDIA_BUFFERS_NOT_RECLAIMED: status_t = B_MEDIA_ERROR_BASE + 114; +pub const B_MEDIA_TIME_SOURCE_STOPPED: status_t = B_MEDIA_ERROR_BASE + 115; +pub const B_MEDIA_TIME_SOURCE_BUSY: status_t = B_MEDIA_ERROR_BASE + 116; +pub const B_MEDIA_BAD_SOURCE: status_t = B_MEDIA_ERROR_BASE + 117; +pub const B_MEDIA_BAD_DESTINATION: status_t = B_MEDIA_ERROR_BASE + 118; +pub const B_MEDIA_ALREADY_CONNECTED: status_t = B_MEDIA_ERROR_BASE + 119; +pub const B_MEDIA_NOT_CONNECTED: status_t = B_MEDIA_ERROR_BASE + 120; +pub const B_MEDIA_BAD_CLIP_FORMAT: status_t = B_MEDIA_ERROR_BASE + 121; +pub const B_MEDIA_ADDON_FAILED: status_t = B_MEDIA_ERROR_BASE + 122; +pub const B_MEDIA_ADDON_DISABLED: status_t = B_MEDIA_ERROR_BASE + 123; +pub const B_MEDIA_CHANGE_IN_PROGRESS: status_t = B_MEDIA_ERROR_BASE + 124; +pub const B_MEDIA_STALE_CHANGE_COUNT: status_t = B_MEDIA_ERROR_BASE + 125; +pub const B_MEDIA_ADDON_RESTRICTED: status_t = B_MEDIA_ERROR_BASE + 126; +pub const B_MEDIA_NO_HANDLER: status_t = B_MEDIA_ERROR_BASE + 127; +pub const B_MEDIA_DUPLICATE_FORMAT: status_t = B_MEDIA_ERROR_BASE + 128; +pub const B_MEDIA_REALTIME_DISABLED: status_t = B_MEDIA_ERROR_BASE + 129; +pub const B_MEDIA_REALTIME_UNAVAILABLE: status_t = B_MEDIA_ERROR_BASE + 130; + +// Mail kit errors +pub const B_MAIL_NO_DAEMON: status_t = B_MAIL_ERROR_BASE + 0; +pub const B_MAIL_UNKNOWN_USER: status_t = B_MAIL_ERROR_BASE + 1; +pub const B_MAIL_WRONG_PASSWORD: status_t = B_MAIL_ERROR_BASE + 2; +pub const B_MAIL_UNKNOWN_HOST: status_t = B_MAIL_ERROR_BASE + 3; +pub const B_MAIL_ACCESS_ERROR: status_t = B_MAIL_ERROR_BASE + 4; +pub const B_MAIL_UNKNOWN_FIELD: status_t = B_MAIL_ERROR_BASE + 5; +pub const B_MAIL_NO_RECIPIENT: status_t = B_MAIL_ERROR_BASE + 6; +pub const B_MAIL_INVALID_MAIL: status_t = B_MAIL_ERROR_BASE + 7; + +// Print kit errors +pub const B_NO_PRINT_SERVER: status_t = B_PRINT_ERROR_BASE + 0; + +// Device kit errors +pub const B_DEV_INVALID_IOCTL: status_t = B_DEVICE_ERROR_BASE + 0; +pub const B_DEV_NO_MEMORY: status_t = B_DEVICE_ERROR_BASE + 1; +pub const B_DEV_BAD_DRIVE_NUM: status_t = B_DEVICE_ERROR_BASE + 2; +pub const B_DEV_NO_MEDIA: status_t = B_DEVICE_ERROR_BASE + 3; +pub const B_DEV_UNREADABLE: status_t = B_DEVICE_ERROR_BASE + 4; +pub const B_DEV_FORMAT_ERROR: status_t = B_DEVICE_ERROR_BASE + 5; +pub const B_DEV_TIMEOUT: status_t = B_DEVICE_ERROR_BASE + 6; +pub const B_DEV_RECALIBRATE_ERROR: status_t = B_DEVICE_ERROR_BASE + 7; +pub const B_DEV_SEEK_ERROR: status_t = B_DEVICE_ERROR_BASE + 8; +pub const B_DEV_ID_ERROR: status_t = B_DEVICE_ERROR_BASE + 9; +pub const B_DEV_READ_ERROR: status_t = B_DEVICE_ERROR_BASE + 10; +pub const B_DEV_WRITE_ERROR: status_t = B_DEVICE_ERROR_BASE + 11; +pub const B_DEV_NOT_READY: status_t = B_DEVICE_ERROR_BASE + 12; +pub const B_DEV_MEDIA_CHANGED: status_t = B_DEVICE_ERROR_BASE + 13; +pub const B_DEV_MEDIA_CHANGE_REQUESTED: status_t = B_DEVICE_ERROR_BASE + 14; +pub const B_DEV_RESOURCE_CONFLICT: status_t = B_DEVICE_ERROR_BASE + 15; +pub const B_DEV_CONFIGURATION_ERROR: status_t = B_DEVICE_ERROR_BASE + 16; +pub const B_DEV_DISABLED_BY_USER: status_t = B_DEVICE_ERROR_BASE + 17; +pub const B_DEV_DOOR_OPEN: status_t = B_DEVICE_ERROR_BASE + 18; + +pub const B_DEV_INVALID_PIPE: status_t = B_DEVICE_ERROR_BASE + 19; +pub const B_DEV_CRC_ERROR: status_t = B_DEVICE_ERROR_BASE + 20; +pub const B_DEV_STALLED: status_t = B_DEVICE_ERROR_BASE + 21; +pub const B_DEV_BAD_PID: status_t = B_DEVICE_ERROR_BASE + 22; +pub const B_DEV_UNEXPECTED_PID: status_t = B_DEVICE_ERROR_BASE + 23; +pub const B_DEV_DATA_OVERRUN: status_t = B_DEVICE_ERROR_BASE + 24; +pub const B_DEV_DATA_UNDERRUN: status_t = B_DEVICE_ERROR_BASE + 25; +pub const B_DEV_FIFO_OVERRUN: status_t = B_DEVICE_ERROR_BASE + 26; +pub const B_DEV_FIFO_UNDERRUN: status_t = B_DEVICE_ERROR_BASE + 27; +pub const B_DEV_PENDING: status_t = B_DEVICE_ERROR_BASE + 28; +pub const B_DEV_MULTIPLE_ERRORS: status_t = B_DEVICE_ERROR_BASE + 29; +pub const B_DEV_TOO_LATE: status_t = B_DEVICE_ERROR_BASE + 30; + +// translation kit errors +pub const B_TRANSLATION_BASE_ERROR: status_t = B_TRANSLATION_ERROR_BASE + 0; +pub const B_NO_TRANSLATOR: status_t = B_TRANSLATION_ERROR_BASE + 1; +pub const B_ILLEGAL_DATA: status_t = B_TRANSLATION_ERROR_BASE + 2; + +// support/TypeConstants.h +pub const B_AFFINE_TRANSFORM_TYPE: u32 = haiku_constant!('A', 'M', 'T', 'X'); +pub const B_ALIGNMENT_TYPE: u32 = haiku_constant!('A', 'L', 'G', 'N'); +pub const B_ANY_TYPE: u32 = haiku_constant!('A', 'N', 'Y', 'T'); +pub const B_ATOM_TYPE: u32 = haiku_constant!('A', 'T', 'O', 'M'); +pub const B_ATOMREF_TYPE: u32 = haiku_constant!('A', 'T', 'M', 'R'); +pub const B_BOOL_TYPE: u32 = haiku_constant!('B', 'O', 'O', 'L'); +pub const B_CHAR_TYPE: u32 = haiku_constant!('C', 'H', 'A', 'R'); +pub const B_COLOR_8_BIT_TYPE: u32 = haiku_constant!('C', 'L', 'R', 'B'); +pub const B_DOUBLE_TYPE: u32 = haiku_constant!('D', 'B', 'L', 'E'); +pub const B_FLOAT_TYPE: u32 = haiku_constant!('F', 'L', 'O', 'T'); +pub const B_GRAYSCALE_8_BIT_TYPE: u32 = haiku_constant!('G', 'R', 'Y', 'B'); +pub const B_INT16_TYPE: u32 = haiku_constant!('S', 'H', 'R', 'T'); +pub const B_INT32_TYPE: u32 = haiku_constant!('L', 'O', 'N', 'G'); +pub const B_INT64_TYPE: u32 = haiku_constant!('L', 'L', 'N', 'G'); +pub const B_INT8_TYPE: u32 = haiku_constant!('B', 'Y', 'T', 'E'); +pub const B_LARGE_ICON_TYPE: u32 = haiku_constant!('I', 'C', 'O', 'N'); +pub const B_MEDIA_PARAMETER_GROUP_TYPE: u32 = haiku_constant!('B', 'M', 'C', 'G'); +pub const B_MEDIA_PARAMETER_TYPE: u32 = haiku_constant!('B', 'M', 'C', 'T'); +pub const B_MEDIA_PARAMETER_WEB_TYPE: u32 = haiku_constant!('B', 'M', 'C', 'W'); +pub const B_MESSAGE_TYPE: u32 = haiku_constant!('M', 'S', 'G', 'G'); +pub const B_MESSENGER_TYPE: u32 = haiku_constant!('M', 'S', 'N', 'G'); +pub const B_MIME_TYPE: u32 = haiku_constant!('M', 'I', 'M', 'E'); +pub const B_MINI_ICON_TYPE: u32 = haiku_constant!('M', 'I', 'C', 'N'); +pub const B_MONOCHROME_1_BIT_TYPE: u32 = haiku_constant!('M', 'N', 'O', 'B'); +pub const B_OBJECT_TYPE: u32 = haiku_constant!('O', 'P', 'T', 'R'); +pub const B_OFF_T_TYPE: u32 = haiku_constant!('O', 'F', 'F', 'T'); +pub const B_PATTERN_TYPE: u32 = haiku_constant!('P', 'A', 'T', 'N'); +pub const B_POINTER_TYPE: u32 = haiku_constant!('P', 'N', 'T', 'R'); +pub const B_POINT_TYPE: u32 = haiku_constant!('B', 'P', 'N', 'T'); +pub const B_PROPERTY_INFO_TYPE: u32 = haiku_constant!('S', 'C', 'T', 'D'); +pub const B_RAW_TYPE: u32 = haiku_constant!('R', 'A', 'W', 'T'); +pub const B_RECT_TYPE: u32 = haiku_constant!('R', 'E', 'C', 'T'); +pub const B_REF_TYPE: u32 = haiku_constant!('R', 'R', 'E', 'F'); +pub const B_RGB_32_BIT_TYPE: u32 = haiku_constant!('R', 'G', 'B', 'B'); +pub const B_RGB_COLOR_TYPE: u32 = haiku_constant!('R', 'G', 'B', 'C'); +pub const B_SIZE_TYPE: u32 = haiku_constant!('S', 'I', 'Z', 'E'); +pub const B_SIZE_T_TYPE: u32 = haiku_constant!('S', 'I', 'Z', 'T'); +pub const B_SSIZE_T_TYPE: u32 = haiku_constant!('S', 'S', 'Z', 'T'); +pub const B_STRING_TYPE: u32 = haiku_constant!('C', 'S', 'T', 'R'); +pub const B_STRING_LIST_TYPE: u32 = haiku_constant!('S', 'T', 'R', 'L'); +pub const B_TIME_TYPE: u32 = haiku_constant!('T', 'I', 'M', 'E'); +pub const B_UINT16_TYPE: u32 = haiku_constant!('U', 'S', 'H', 'T'); +pub const B_UINT32_TYPE: u32 = haiku_constant!('U', 'L', 'N', 'G'); +pub const B_UINT64_TYPE: u32 = haiku_constant!('U', 'L', 'L', 'G'); +pub const B_UINT8_TYPE: u32 = haiku_constant!('U', 'B', 'Y', 'T'); +pub const B_VECTOR_ICON_TYPE: u32 = haiku_constant!('V', 'I', 'C', 'N'); +pub const B_XATTR_TYPE: u32 = haiku_constant!('X', 'A', 'T', 'R'); +pub const B_NETWORK_ADDRESS_TYPE: u32 = haiku_constant!('N', 'W', 'A', 'D'); +pub const B_MIME_STRING_TYPE: u32 = haiku_constant!('M', 'I', 'M', 'S'); +pub const B_ASCII_TYPE: u32 = haiku_constant!('T', 'E', 'X', 'T'); + +extern "C" { + // kernel/OS.h + pub fn create_area( + name: *const ::c_char, + startAddress: *mut *mut ::c_void, + addressSpec: u32, + size: usize, + lock: u32, + protection: u32, + ) -> area_id; + pub fn clone_area( + name: *const ::c_char, + destAddress: *mut *mut ::c_void, + addressSpec: u32, + protection: u32, + source: area_id, + ) -> area_id; + pub fn find_area(name: *const ::c_char) -> area_id; + pub fn area_for(address: *mut ::c_void) -> area_id; + pub fn delete_area(id: area_id) -> status_t; + pub fn resize_area(id: area_id, newSize: usize) -> status_t; + pub fn set_area_protection(id: area_id, newProtection: u32) -> status_t; + pub fn _get_area_info(id: area_id, areaInfo: *mut area_info, size: usize) -> status_t; + pub fn _get_next_area_info( + team: team_id, + cookie: *mut isize, + areaInfo: *mut area_info, + size: usize, + ) -> status_t; + + pub fn create_port(capacity: i32, name: *const ::c_char) -> port_id; + pub fn find_port(name: *const ::c_char) -> port_id; + pub fn read_port( + port: port_id, + code: *mut i32, + buffer: *mut ::c_void, + bufferSize: ::size_t, + ) -> ::ssize_t; + pub fn read_port_etc( + port: port_id, + code: *mut i32, + buffer: *mut ::c_void, + bufferSize: ::size_t, + flags: u32, + timeout: bigtime_t, + ) -> ::ssize_t; + pub fn write_port( + port: port_id, + code: i32, + buffer: *const ::c_void, + bufferSize: ::size_t, + ) -> status_t; + pub fn write_port_etc( + port: port_id, + code: i32, + buffer: *const ::c_void, + bufferSize: ::size_t, + flags: u32, + timeout: bigtime_t, + ) -> status_t; + pub fn close_port(port: port_id) -> status_t; + pub fn delete_port(port: port_id) -> status_t; + pub fn port_buffer_size(port: port_id) -> ::ssize_t; + pub fn port_buffer_size_etc(port: port_id, flags: u32, timeout: bigtime_t) -> ::ssize_t; + pub fn port_count(port: port_id) -> ::ssize_t; + pub fn set_port_owner(port: port_id, team: team_id) -> status_t; + + pub fn _get_port_info(port: port_id, buf: *mut port_info, portInfoSize: ::size_t) -> status_t; + pub fn _get_next_port_info( + port: port_id, + cookie: *mut i32, + portInfo: *mut port_info, + portInfoSize: ::size_t, + ) -> status_t; + pub fn _get_port_message_info_etc( + port: port_id, + info: *mut port_message_info, + infoSize: ::size_t, + flags: u32, + timeout: bigtime_t, + ) -> status_t; + + pub fn create_sem(count: i32, name: *const ::c_char) -> sem_id; + pub fn delete_sem(id: sem_id) -> status_t; + pub fn acquire_sem(id: sem_id) -> status_t; + pub fn acquire_sem_etc(id: sem_id, count: i32, flags: u32, timeout: bigtime_t) -> status_t; + pub fn release_sem(id: sem_id) -> status_t; + pub fn release_sem_etc(id: sem_id, count: i32, flags: u32) -> status_t; + pub fn switch_sem(semToBeReleased: sem_id, id: sem_id) -> status_t; + pub fn switch_sem_etc( + semToBeReleased: sem_id, + id: sem_id, + count: i32, + flags: u32, + timeout: bigtime_t, + ) -> status_t; + pub fn get_sem_count(id: sem_id, threadCount: *mut i32) -> status_t; + pub fn set_sem_owner(id: sem_id, team: team_id) -> status_t; + pub fn _get_sem_info(id: sem_id, info: *mut sem_info, infoSize: ::size_t) -> status_t; + pub fn _get_next_sem_info( + team: team_id, + cookie: *mut i32, + info: *mut sem_info, + infoSize: ::size_t, + ) -> status_t; + + pub fn kill_team(team: team_id) -> status_t; + pub fn _get_team_info(team: team_id, info: *mut team_info, size: ::size_t) -> status_t; + pub fn _get_next_team_info(cookie: *mut i32, info: *mut team_info, size: ::size_t) -> status_t; + + pub fn spawn_thread( + func: thread_func, + name: *const ::c_char, + priority: i32, + data: *mut ::c_void, + ) -> thread_id; + pub fn kill_thread(thread: thread_id) -> status_t; + pub fn resume_thread(thread: thread_id) -> status_t; + pub fn suspend_thread(thread: thread_id) -> status_t; + + pub fn rename_thread(thread: thread_id, newName: *const ::c_char) -> status_t; + pub fn set_thread_priority(thread: thread_id, newPriority: i32) -> status_t; + pub fn suggest_thread_priority( + what: u32, + period: i32, + jitter: ::bigtime_t, + length: ::bigtime_t, + ) -> i32; + pub fn estimate_max_scheduling_latency(th: ::thread_id) -> ::bigtime_t; + pub fn exit_thread(status: status_t); + pub fn wait_for_thread(thread: thread_id, returnValue: *mut status_t) -> status_t; + pub fn on_exit_thread(callback: extern "C" fn(*mut ::c_void), data: *mut ::c_void) -> status_t; + + pub fn find_thread(name: *const ::c_char) -> thread_id; + + pub fn get_scheduler_mode() -> i32; + pub fn set_scheduler_mode(mode: i32) -> status_t; + + pub fn send_data( + thread: thread_id, + code: i32, + buffer: *const ::c_void, + bufferSize: ::size_t, + ) -> status_t; + pub fn receive_data(sender: *mut thread_id, buffer: *mut ::c_void, bufferSize: ::size_t) + -> i32; + pub fn has_data(thread: thread_id) -> bool; + + pub fn snooze(amount: bigtime_t) -> status_t; + pub fn snooze_etc(amount: bigtime_t, timeBase: ::c_int, flags: u32) -> status_t; + pub fn snooze_until(time: bigtime_t, timeBase: ::c_int) -> status_t; + + pub fn _get_thread_info(id: thread_id, info: *mut thread_info, size: ::size_t) -> status_t; + pub fn _get_next_thread_info( + team: team_id, + cookie: *mut i32, + info: *mut thread_info, + size: ::size_t, + ) -> status_t; + + pub fn get_pthread_thread_id(thread: ::pthread_t) -> thread_id; + + pub fn _get_team_usage_info( + team: team_id, + who: i32, + info: *mut team_usage_info, + size: ::size_t, + ) -> status_t; + + pub fn real_time_clock() -> ::c_ulong; + pub fn set_real_time_clock(secsSinceJan1st1970: ::c_ulong); + pub fn real_time_clock_usecs() -> bigtime_t; + pub fn system_time() -> bigtime_t; + pub fn system_time_nsecs() -> nanotime_t; + // set_timezone() is deprecated and a no-op + + pub fn set_alarm(when: bigtime_t, flags: u32) -> bigtime_t; + pub fn debugger(message: *const ::c_char); + pub fn disable_debugger(state: ::c_int) -> ::c_int; + + pub fn get_system_info(info: *mut system_info) -> status_t; + pub fn _get_cpu_info_etc( + firstCPU: u32, + cpuCount: u32, + info: *mut cpu_info, + size: ::size_t, + ) -> status_t; + pub fn get_cpu_topology_info( + topologyInfos: *mut cpu_topology_node_info, + topologyInfoCount: *mut u32, + ) -> status_t; + pub fn is_computer_on() -> i32; + pub fn is_computer_on_fire() -> ::c_double; + pub fn send_signal(threadID: thread_id, signal: ::c_uint) -> ::c_int; + pub fn set_signal_stack(base: *mut ::c_void, size: ::size_t); + + pub fn wait_for_objects(infos: *mut object_wait_info, numInfos: ::c_int) -> ::ssize_t; + pub fn wait_for_objects_etc( + infos: *mut object_wait_info, + numInfos: ::c_int, + flags: u32, + timeout: bigtime_t, + ) -> ::ssize_t; + + // kernel/fs_attr.h + pub fn fs_read_attr( + fd: ::c_int, + attribute: *const ::c_char, + type_: u32, + pos: ::off_t, + buffer: *mut ::c_void, + readBytes: ::size_t, + ) -> ::ssize_t; + pub fn fs_write_attr( + fd: ::c_int, + attribute: *const ::c_char, + type_: u32, + pos: ::off_t, + buffer: *const ::c_void, + writeBytes: ::size_t, + ) -> ::ssize_t; + pub fn fs_remove_attr(fd: ::c_int, attribute: *const ::c_char) -> ::c_int; + pub fn fs_stat_attr( + fd: ::c_int, + attribute: *const ::c_char, + attrInfo: *mut attr_info, + ) -> ::c_int; + + pub fn fs_open_attr( + path: *const ::c_char, + attribute: *const ::c_char, + type_: u32, + openMode: ::c_int, + ) -> ::c_int; + pub fn fs_fopen_attr( + fd: ::c_int, + attribute: *const ::c_char, + type_: u32, + openMode: ::c_int, + ) -> ::c_int; + pub fn fs_close_attr(fd: ::c_int) -> ::c_int; + + pub fn fs_open_attr_dir(path: *const ::c_char) -> *mut ::DIR; + pub fn fs_lopen_attr_dir(path: *const ::c_char) -> *mut ::DIR; + pub fn fs_fopen_attr_dir(fd: ::c_int) -> *mut ::DIR; + pub fn fs_close_attr_dir(dir: *mut ::DIR) -> ::c_int; + pub fn fs_read_attr_dir(dir: *mut ::DIR) -> *mut ::dirent; + pub fn fs_rewind_attr_dir(dir: *mut ::DIR); + + // kernel/fs_image.h + pub fn fs_create_index( + device: ::dev_t, + name: *const ::c_char, + type_: u32, + flags: u32, + ) -> ::c_int; + pub fn fs_remove_index(device: ::dev_t, name: *const ::c_char) -> ::c_int; + pub fn fs_stat_index( + device: ::dev_t, + name: *const ::c_char, + indexInfo: *mut index_info, + ) -> ::c_int; + + pub fn fs_open_index_dir(device: ::dev_t) -> *mut ::DIR; + pub fn fs_close_index_dir(indexDirectory: *mut ::DIR) -> ::c_int; + pub fn fs_read_index_dir(indexDirectory: *mut ::DIR) -> *mut ::dirent; + pub fn fs_rewind_index_dir(indexDirectory: *mut ::DIR); + + // kernel/fs_info.h + pub fn dev_for_path(path: *const ::c_char) -> ::dev_t; + pub fn next_dev(pos: *mut i32) -> ::dev_t; + pub fn fs_stat_dev(dev: ::dev_t, info: *mut fs_info) -> ::c_int; + + // kernel/fs_query.h + pub fn fs_open_query(device: ::dev_t, query: *const ::c_char, flags: u32) -> *mut ::DIR; + pub fn fs_open_live_query( + device: ::dev_t, + query: *const ::c_char, + flags: u32, + port: port_id, + token: i32, + ) -> *mut ::DIR; + pub fn fs_close_query(d: *mut ::DIR) -> ::c_int; + pub fn fs_read_query(d: *mut ::DIR) -> *mut ::dirent; + pub fn get_path_for_dirent(dent: *mut ::dirent, buf: *mut ::c_char, len: ::size_t) -> status_t; + + // kernel/fs_volume.h + pub fn fs_mount_volume( + where_: *const ::c_char, + device: *const ::c_char, + filesystem: *const ::c_char, + flags: u32, + parameters: *const ::c_char, + ) -> ::dev_t; + pub fn fs_unmount_volume(path: *const ::c_char, flags: u32) -> status_t; + + // kernel/image.h + pub fn load_image( + argc: i32, + argv: *mut *const ::c_char, + environ: *mut *const ::c_char, + ) -> thread_id; + pub fn load_add_on(path: *const ::c_char) -> image_id; + pub fn unload_add_on(image: image_id) -> status_t; + pub fn get_image_symbol( + image: image_id, + name: *const ::c_char, + symbolType: i32, + symbolLocation: *mut *mut ::c_void, + ) -> status_t; + pub fn get_nth_image_symbol( + image: image_id, + n: i32, + nameBuffer: *mut ::c_char, + nameLength: *mut i32, + symbolType: *mut i32, + symbolLocation: *mut *mut ::c_void, + ) -> status_t; + pub fn clear_caches(address: *mut ::c_void, length: ::size_t, flags: u32); + pub fn _get_image_info(image: image_id, info: *mut image_info, size: ::size_t) -> status_t; + pub fn _get_next_image_info( + team: team_id, + cookie: *mut i32, + info: *mut image_info, + size: ::size_t, + ) -> status_t; + pub fn find_path( + codePointer: *const ::c_void, + baseDirectory: path_base_directory, + subPath: *const ::c_char, + pathBuffer: *mut ::c_char, + bufferSize: usize, + ) -> status_t; + pub fn find_path_etc( + codePointer: *const ::c_void, + dependency: *const ::c_char, + architecture: *const ::c_char, + baseDirectory: path_base_directory, + subPath: *const ::c_char, + flags: u32, + pathBuffer: *mut ::c_char, + bufferSize: ::size_t, + ) -> status_t; + pub fn find_path_for_path( + path: *const ::c_char, + baseDirectory: path_base_directory, + subPath: *const ::c_char, + pathBuffer: *mut ::c_char, + bufferSize: ::size_t, + ) -> status_t; + pub fn find_path_for_path_etc( + path: *const ::c_char, + dependency: *const ::c_char, + architectur: *const ::c_char, + baseDirectory: path_base_directory, + subPath: *const ::c_char, + flags: u32, + pathBuffer: *mut ::c_char, + bufferSize: ::size_t, + ) -> status_t; + pub fn find_paths( + baseDirectory: path_base_directory, + subPath: *const ::c_char, + _paths: *mut *mut *mut ::c_char, + pathCount: *mut ::size_t, + ) -> status_t; + pub fn find_paths_etc( + architecture: *const ::c_char, + baseDirectory: path_base_directory, + subPath: *const ::c_char, + flags: u32, + _paths: *mut *mut *mut ::c_char, + pathCount: *mut ::size_t, + ) -> status_t; + pub fn find_directory( + which: directory_which, + volume: ::dev_t, + createIt: bool, + pathString: *mut ::c_char, + length: i32, + ) -> status_t; +} + +cfg_if! { + if #[cfg(libc_union)] { + extern "C" { + pub fn get_cpuid(info: *mut cpuid_info, eaxRegister: u32, cpuNum: u32) -> status_t; + } + } +} + +// The following functions are defined as macros in C/C++ +#[inline] +pub unsafe fn get_cpu_info(firstCPU: u32, cpuCount: u32, info: *mut cpu_info) -> status_t { + _get_cpu_info_etc( + firstCPU, + cpuCount, + info, + core::mem::size_of::() as ::size_t, + ) +} + +#[inline] +pub unsafe fn get_area_info(id: area_id, info: *mut area_info) -> status_t { + _get_area_info(id, info, core::mem::size_of::() as usize) +} + +#[inline] +pub unsafe fn get_next_area_info( + team: team_id, + cookie: *mut isize, + info: *mut area_info, +) -> status_t { + _get_next_area_info( + team, + cookie, + info, + core::mem::size_of::() as usize, + ) +} + +#[inline] +pub unsafe fn get_port_info(port: port_id, buf: *mut port_info) -> status_t { + _get_port_info(port, buf, core::mem::size_of::() as ::size_t) +} + +#[inline] +pub unsafe fn get_next_port_info( + port: port_id, + cookie: *mut i32, + portInfo: *mut port_info, +) -> status_t { + _get_next_port_info( + port, + cookie, + portInfo, + core::mem::size_of::() as ::size_t, + ) +} + +#[inline] +pub unsafe fn get_port_message_info_etc( + port: port_id, + info: *mut port_message_info, + flags: u32, + timeout: bigtime_t, +) -> status_t { + _get_port_message_info_etc( + port, + info, + core::mem::size_of::() as ::size_t, + flags, + timeout, + ) +} + +#[inline] +pub unsafe fn get_sem_info(id: sem_id, info: *mut sem_info) -> status_t { + _get_sem_info(id, info, core::mem::size_of::() as ::size_t) +} + +#[inline] +pub unsafe fn get_next_sem_info(team: team_id, cookie: *mut i32, info: *mut sem_info) -> status_t { + _get_next_sem_info( + team, + cookie, + info, + core::mem::size_of::() as ::size_t, + ) +} + +#[inline] +pub unsafe fn get_team_info(team: team_id, info: *mut team_info) -> status_t { + _get_team_info(team, info, core::mem::size_of::() as ::size_t) +} + +#[inline] +pub unsafe fn get_next_team_info(cookie: *mut i32, info: *mut team_info) -> status_t { + _get_next_team_info(cookie, info, core::mem::size_of::() as ::size_t) +} + +#[inline] +pub unsafe fn get_team_usage_info(team: team_id, who: i32, info: *mut team_usage_info) -> status_t { + _get_team_usage_info( + team, + who, + info, + core::mem::size_of::() as ::size_t, + ) +} + +#[inline] +pub unsafe fn get_thread_info(id: thread_id, info: *mut thread_info) -> status_t { + _get_thread_info(id, info, core::mem::size_of::() as ::size_t) +} + +#[inline] +pub unsafe fn get_next_thread_info( + team: team_id, + cookie: *mut i32, + info: *mut thread_info, +) -> status_t { + _get_next_thread_info( + team, + cookie, + info, + core::mem::size_of::() as ::size_t, + ) +} + +// kernel/image.h +#[inline] +pub unsafe fn get_image_info(image: image_id, info: *mut image_info) -> status_t { + _get_image_info(image, info, core::mem::size_of::() as ::size_t) +} + +#[inline] +pub unsafe fn get_next_image_info( + team: team_id, + cookie: *mut i32, + info: *mut image_info, +) -> status_t { + _get_next_image_info( + team, + cookie, + info, + core::mem::size_of::() as ::size_t, + ) +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/haiku/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/haiku/x86_64.rs new file mode 100644 index 00000000..1b0462f2 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/haiku/x86_64.rs @@ -0,0 +1,264 @@ +s_no_extra_traits! { + pub struct fpu_state { + pub control: ::c_ushort, + pub status: ::c_ushort, + pub tag: ::c_ushort, + pub opcode: ::c_ushort, + pub rip: ::c_ulong, + pub rdp: ::c_ulong, + pub mxcsr: ::c_uint, + pub mscsr_mask: ::c_uint, + pub _fpreg: [[::c_uchar; 8]; 16], + pub _xmm: [[::c_uchar; 16]; 16], + pub _reserved_416_511: [::c_uchar; 96], + } + + pub struct xstate_hdr { + pub bv: ::c_ulong, + pub xcomp_bv: ::c_ulong, + pub _reserved: [::c_uchar; 48], + } + + pub struct savefpu { + pub fp_fxsave: fpu_state, + pub fp_xstate: xstate_hdr, + pub _fp_ymm: [[::c_uchar; 16]; 16], + } + + pub struct mcontext_t { + pub rax: ::c_ulong, + pub rbx: ::c_ulong, + pub rcx: ::c_ulong, + pub rdx: ::c_ulong, + pub rdi: ::c_ulong, + pub rsi: ::c_ulong, + pub rbp: ::c_ulong, + pub r8: ::c_ulong, + pub r9: ::c_ulong, + pub r10: ::c_ulong, + pub r11: ::c_ulong, + pub r12: ::c_ulong, + pub r13: ::c_ulong, + pub r14: ::c_ulong, + pub r15: ::c_ulong, + pub rsp: ::c_ulong, + pub rip: ::c_ulong, + pub rflags: ::c_ulong, + pub fpu: savefpu, + } + + pub struct ucontext_t { + pub uc_link: *mut ucontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpu_state { + fn eq(&self, other: &fpu_state) -> bool { + self.control == other.control + && self.status == other.status + && self.tag == other.tag + && self.opcode == other.opcode + && self.rip == other.rip + && self.rdp == other.rdp + && self.mxcsr == other.mxcsr + && self.mscsr_mask == other.mscsr_mask + && self._fpreg.iter().zip(other._fpreg.iter()).all(|(a, b)| a == b) + && self._xmm.iter().zip(other._xmm.iter()).all(|(a, b)| a == b) + && self._reserved_416_511. + iter(). + zip(other._reserved_416_511.iter()). + all(|(a, b)| a == b) + } + } + impl Eq for fpu_state {} + impl ::fmt::Debug for fpu_state { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpu_state") + .field("control", &self.control) + .field("status", &self.status) + .field("tag", &self.tag) + .field("opcode", &self.opcode) + .field("rip", &self.rip) + .field("rdp", &self.rdp) + .field("mxcsr", &self.mxcsr) + .field("mscsr_mask", &self.mscsr_mask) + // FIXME: .field("_fpreg", &self._fpreg) + // FIXME: .field("_xmm", &self._xmm) + // FIXME: .field("_reserved_416_511", &self._reserved_416_511) + .finish() + } + } + impl ::hash::Hash for fpu_state { + fn hash(&self, state: &mut H) { + self.control.hash(state); + self.status.hash(state); + self.tag.hash(state); + self.opcode.hash(state); + self.rip.hash(state); + self.rdp.hash(state); + self.mxcsr.hash(state); + self.mscsr_mask.hash(state); + self._fpreg.hash(state); + self._xmm.hash(state); + self._reserved_416_511.hash(state); + } + } + + impl PartialEq for xstate_hdr { + fn eq(&self, other: &xstate_hdr) -> bool { + self.bv == other.bv + && self.xcomp_bv == other.xcomp_bv + && self._reserved.iter().zip(other._reserved.iter()).all(|(a, b)| a == b) + } + } + impl Eq for xstate_hdr {} + impl ::fmt::Debug for xstate_hdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("xstate_hdr") + .field("bv", &self.bv) + .field("xcomp_bv", &self.xcomp_bv) + // FIXME: .field("_reserved", &field._reserved) + .finish() + } + } + impl ::hash::Hash for xstate_hdr { + fn hash(&self, state: &mut H) { + self.bv.hash(state); + self.xcomp_bv.hash(state); + self._reserved.hash(state); + } + } + + impl PartialEq for savefpu { + fn eq(&self, other: &savefpu) -> bool { + self.fp_fxsave == other.fp_fxsave + && self.fp_xstate == other.fp_xstate + && self._fp_ymm.iter().zip(other._fp_ymm.iter()).all(|(a, b)| a == b) + } + } + impl Eq for savefpu {} + impl ::fmt::Debug for savefpu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("savefpu") + .field("fp_fxsave", &self.fp_fxsave) + .field("fp_xstate", &self.fp_xstate) + // FIXME: .field("_fp_ymm", &field._fp_ymm) + .finish() + } + } + impl ::hash::Hash for savefpu { + fn hash(&self, state: &mut H) { + self.fp_fxsave.hash(state); + self.fp_xstate.hash(state); + self._fp_ymm.hash(state); + } + } + + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.rax == other.rax + && self.rbx == other.rbx + && self.rbx == other.rbx + && self.rcx == other.rcx + && self.rdx == other.rdx + && self.rdi == other.rdi + && self.rsi == other.rsi + && self.r8 == other.r8 + && self.r9 == other.r9 + && self.r10 == other.r10 + && self.r11 == other.r11 + && self.r12 == other.r12 + && self.r13 == other.r13 + && self.r14 == other.r14 + && self.r15 == other.r15 + && self.rsp == other.rsp + && self.rip == other.rip + && self.rflags == other.rflags + && self.fpu == other.fpu + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("rax", &self.rax) + .field("rbx", &self.rbx) + .field("rcx", &self.rcx) + .field("rdx", &self.rdx) + .field("rdi", &self.rdi) + .field("rsi", &self.rsi) + .field("rbp", &self.rbp) + .field("r8", &self.r8) + .field("r9", &self.r9) + .field("r10", &self.r10) + .field("r11", &self.r11) + .field("r12", &self.r12) + .field("r13", &self.r13) + .field("r14", &self.r14) + .field("r15", &self.r15) + .field("rsp", &self.rsp) + .field("rip", &self.rip) + .field("rflags", &self.rflags) + .field("fpu", &self.fpu) + .finish() + + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.rax.hash(state); + self.rbx.hash(state); + self.rcx.hash(state); + self.rdx.hash(state); + self.rdi.hash(state); + self.rsi.hash(state); + self.rbp.hash(state); + self.r8.hash(state); + self.r9.hash(state); + self.r10.hash(state); + self.r11.hash(state); + self.r12.hash(state); + self.r13.hash(state); + self.r14.hash(state); + self.r15.hash(state); + self.rsp.hash(state); + self.rip.hash(state); + self.rflags.hash(state); + self.fpu.hash(state); + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_link == other.uc_link + && self.uc_sigmask == other.uc_sigmask + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_link", &self.uc_link) + .field("uc_sigmask", &self.uc_sigmask) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_link.hash(state); + self.uc_sigmask.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/hurd/align.rs b/utshell-0.5.0/vendor/libc/src/unix/hurd/align.rs new file mode 100644 index 00000000..1dd7d8e5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/hurd/align.rs @@ -0,0 +1 @@ +// Placeholder file diff --git a/utshell-0.5.0/vendor/libc/src/unix/hurd/b32.rs b/utshell-0.5.0/vendor/libc/src/unix/hurd/b32.rs new file mode 100644 index 00000000..7e82a91d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/hurd/b32.rs @@ -0,0 +1,93 @@ +pub type c_long = i32; +pub type c_ulong = u32; + +pub type __int64_t = ::c_longlong; +pub type __uint64_t = ::c_ulonglong; + +pub type int_fast16_t = ::c_int; +pub type int_fast32_t = ::c_int; +pub type int_fast64_t = ::c_longlong; +pub type uint_fast16_t = ::c_uint; +pub type uint_fast32_t = ::c_uint; +pub type uint_fast64_t = ::c_ulonglong; + +pub type __quad_t = ::c_longlong; +pub type __u_quad_t = ::c_ulonglong; +pub type __intmax_t = ::c_longlong; +pub type __uintmax_t = ::c_ulonglong; + +pub type __squad_type = ::__int64_t; +pub type __uquad_type = ::__uint64_t; +pub type __sword_type = ::c_int; +pub type __uword_type = ::c_uint; +pub type __slong32_type = ::c_long; +pub type __ulong32_type = ::c_ulong; +pub type __s64_type = ::__int64_t; +pub type __u64_type = ::__uint64_t; + +pub type __ipc_pid_t = ::c_ushort; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; +pub type Elf32_Section = u16; + +pub type Elf_Addr = ::Elf32_Addr; +pub type Elf_Half = ::Elf32_Half; +pub type Elf_Ehdr = ::Elf32_Ehdr; +pub type Elf_Phdr = ::Elf32_Phdr; +pub type Elf_Shdr = ::Elf32_Shdr; +pub type Elf_Sym = ::Elf32_Sym; + +s! { + pub struct Elf32_Ehdr { + pub e_ident: [::c_uchar; 16], + pub e_type: Elf32_Half, + pub e_machine: Elf32_Half, + pub e_version: Elf32_Word, + pub e_entry: Elf32_Addr, + pub e_phoff: Elf32_Off, + pub e_shoff: Elf32_Off, + pub e_flags: Elf32_Word, + pub e_ehsize: Elf32_Half, + pub e_phentsize: Elf32_Half, + pub e_phnum: Elf32_Half, + pub e_shentsize: Elf32_Half, + pub e_shnum: Elf32_Half, + pub e_shstrndx: Elf32_Half, + } + + pub struct Elf32_Shdr { + pub sh_name: Elf32_Word, + pub sh_type: Elf32_Word, + pub sh_flags: Elf32_Word, + pub sh_addr: Elf32_Addr, + pub sh_offset: Elf32_Off, + pub sh_size: Elf32_Word, + pub sh_link: Elf32_Word, + pub sh_info: Elf32_Word, + pub sh_addralign: Elf32_Word, + pub sh_entsize: Elf32_Word, + } + + pub struct Elf32_Sym { + pub st_name: Elf32_Word, + pub st_value: Elf32_Addr, + pub st_size: Elf32_Word, + pub st_info: ::c_uchar, + pub st_other: ::c_uchar, + pub st_shndx: Elf32_Section, + } + + pub struct Elf32_Phdr { + pub p_type: ::Elf32_Word, + pub p_offset: ::Elf32_Off, + pub p_vaddr: ::Elf32_Addr, + pub p_paddr: ::Elf32_Addr, + pub p_filesz: ::Elf32_Word, + pub p_memsz: ::Elf32_Word, + pub p_flags: ::Elf32_Word, + pub p_align: ::Elf32_Word, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/hurd/b64.rs b/utshell-0.5.0/vendor/libc/src/unix/hurd/b64.rs new file mode 100644 index 00000000..e2e502af --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/hurd/b64.rs @@ -0,0 +1,95 @@ +pub type c_long = i64; +pub type c_ulong = u64; + +pub type __int64_t = ::c_long; +pub type __uint64_t = ::c_ulong; + +pub type int_fast16_t = ::c_long; +pub type int_fast32_t = ::c_long; +pub type int_fast64_t = ::c_long; +pub type uint_fast16_t = ::c_ulong; +pub type uint_fast32_t = ::c_ulong; +pub type uint_fast64_t = ::c_ulong; + +pub type __quad_t = ::c_long; +pub type __u_quad_t = ::c_ulong; +pub type __intmax_t = ::c_long; +pub type __uintmax_t = ::c_ulong; + +pub type __squad_type = ::c_long; +pub type __uquad_type = ::c_ulong; +pub type __sword_type = ::c_long; +pub type __uword_type = ::c_ulong; +pub type __slong32_type = ::c_int; +pub type __ulong32_type = ::c_uint; +pub type __s64_type = ::c_long; +pub type __u64_type = ::c_ulong; + +pub type __ipc_pid_t = ::c_int; + +pub type Elf64_Half = u16; +pub type Elf64_Word = u32; +pub type Elf64_Off = u64; +pub type Elf64_Addr = u64; +pub type Elf64_Xword = u64; +pub type Elf64_Sxword = i64; +pub type Elf64_Section = u16; + +pub type Elf_Addr = ::Elf64_Addr; +pub type Elf_Half = ::Elf64_Half; +pub type Elf_Ehdr = ::Elf64_Ehdr; +pub type Elf_Phdr = ::Elf64_Phdr; +pub type Elf_Shdr = ::Elf64_Shdr; +pub type Elf_Sym = ::Elf64_Sym; + +s! { + pub struct Elf64_Ehdr { + pub e_ident: [::c_uchar; 16], + pub e_type: Elf64_Half, + pub e_machine: Elf64_Half, + pub e_version: Elf64_Word, + pub e_entry: Elf64_Addr, + pub e_phoff: Elf64_Off, + pub e_shoff: Elf64_Off, + pub e_flags: Elf64_Word, + pub e_ehsize: Elf64_Half, + pub e_phentsize: Elf64_Half, + pub e_phnum: Elf64_Half, + pub e_shentsize: Elf64_Half, + pub e_shnum: Elf64_Half, + pub e_shstrndx: Elf64_Half, + } + + pub struct Elf64_Shdr { + pub sh_name: Elf64_Word, + pub sh_type: Elf64_Word, + pub sh_flags: Elf64_Xword, + pub sh_addr: Elf64_Addr, + pub sh_offset: Elf64_Off, + pub sh_size: Elf64_Xword, + pub sh_link: Elf64_Word, + pub sh_info: Elf64_Word, + pub sh_addralign: Elf64_Xword, + pub sh_entsize: Elf64_Xword, + } + + pub struct Elf64_Sym { + pub st_name: Elf64_Word, + pub st_info: ::c_uchar, + pub st_other: ::c_uchar, + pub st_shndx: Elf64_Section, + pub st_value: Elf64_Addr, + pub st_size: Elf64_Xword, + } + + pub struct Elf64_Phdr { + pub p_type: ::Elf64_Word, + pub p_flags: ::Elf64_Word, + pub p_offset: ::Elf64_Off, + pub p_vaddr: ::Elf64_Addr, + pub p_paddr: ::Elf64_Addr, + pub p_filesz: ::Elf64_Xword, + pub p_memsz: ::Elf64_Xword, + pub p_align: ::Elf64_Xword, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/hurd/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/hurd/mod.rs new file mode 100644 index 00000000..2701649f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/hurd/mod.rs @@ -0,0 +1,4687 @@ +#![allow(dead_code)] + +// types +pub type c_char = i8; + +pub type __s16_type = ::c_short; +pub type __u16_type = ::c_ushort; +pub type __s32_type = ::c_int; +pub type __u32_type = ::c_uint; +pub type __slongword_type = ::c_long; +pub type __ulongword_type = ::c_ulong; + +pub type __u_char = ::c_uchar; +pub type __u_short = ::c_ushort; +pub type __u_int = ::c_uint; +pub type __u_long = ::c_ulong; +pub type __int8_t = ::c_schar; +pub type __uint8_t = ::c_uchar; +pub type __int16_t = ::c_short; +pub type __uint16_t = ::c_ushort; +pub type __int32_t = ::c_int; +pub type __uint32_t = ::c_uint; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; + +pub type __dev_t = __uword_type; +pub type __uid_t = __u32_type; +pub type __gid_t = __u32_type; +pub type __ino_t = __ulongword_type; +pub type __ino64_t = __uquad_type; +pub type __mode_t = __u32_type; +pub type __nlink_t = __uword_type; +pub type __off_t = __slongword_type; +pub type __off64_t = __squad_type; +pub type __pid_t = __s32_type; +pub type __rlim_t = __ulongword_type; +pub type __rlim64_t = __uquad_type; +pub type __blkcnt_t = __slongword_type; +pub type __blkcnt64_t = __squad_type; +pub type __fsblkcnt_t = __ulongword_type; +pub type __fsblkcnt64_t = __uquad_type; +pub type __fsfilcnt_t = __ulongword_type; +pub type __fsfilcnt64_t = __uquad_type; +pub type __fsword_t = __sword_type; +pub type __id_t = __u32_type; +pub type __clock_t = __slongword_type; +pub type __time_t = __slongword_type; +pub type __useconds_t = __u32_type; +pub type __suseconds_t = __slongword_type; +pub type __suseconds64_t = __squad_type; +pub type __daddr_t = __s32_type; +pub type __key_t = __s32_type; +pub type __clockid_t = __s32_type; +pub type __timer_t = __uword_type; +pub type __blksize_t = __slongword_type; +pub type __fsid_t = __uquad_type; +pub type __ssize_t = __sword_type; +pub type __syscall_slong_t = __slongword_type; +pub type __syscall_ulong_t = __ulongword_type; +pub type __cpu_mask = __ulongword_type; + +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::c_char; +pub type __intptr_t = __sword_type; +pub type __ptrdiff_t = __sword_type; +pub type __socklen_t = __u32_type; +pub type __sig_atomic_t = ::c_int; +pub type __time64_t = __int64_t; +pub type ssize_t = __ssize_t; +pub type size_t = ::c_ulong; +pub type wchar_t = ::c_int; +pub type wint_t = ::c_uint; +pub type gid_t = __gid_t; +pub type uid_t = __uid_t; +pub type off_t = __off_t; +pub type off64_t = __off64_t; +pub type useconds_t = __useconds_t; +pub type pid_t = __pid_t; +pub type socklen_t = __socklen_t; + +pub type in_addr_t = u32; + +pub type _Float32 = f32; +pub type _Float64 = f64; +pub type _Float32x = f64; +pub type _Float64x = f64; + +pub type __locale_t = *mut __locale_struct; +pub type locale_t = __locale_t; + +pub type u_char = __u_char; +pub type u_short = __u_short; +pub type u_int = __u_int; +pub type u_long = __u_long; +pub type quad_t = __quad_t; +pub type u_quad_t = __u_quad_t; +pub type fsid_t = __fsid_t; +pub type loff_t = __loff_t; +pub type ino_t = __ino_t; +pub type ino64_t = __ino64_t; +pub type dev_t = __dev_t; +pub type mode_t = __mode_t; +pub type nlink_t = __nlink_t; +pub type id_t = __id_t; +pub type daddr_t = __daddr_t; +pub type caddr_t = __caddr_t; +pub type key_t = __key_t; +pub type clock_t = __clock_t; +pub type clockid_t = __clockid_t; +pub type time_t = __time_t; +pub type timer_t = __timer_t; +pub type suseconds_t = __suseconds_t; +pub type ulong = ::c_ulong; +pub type ushort = ::c_ushort; +pub type uint = ::c_uint; +pub type u_int8_t = __uint8_t; +pub type u_int16_t = __uint16_t; +pub type u_int32_t = __uint32_t; +pub type u_int64_t = __uint64_t; +pub type register_t = ::c_int; +pub type __sigset_t = ::c_ulong; +pub type sigset_t = __sigset_t; + +pub type __fd_mask = ::c_long; +pub type fd_mask = __fd_mask; +pub type blksize_t = __blksize_t; +pub type blkcnt_t = __blkcnt_t; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +pub type blkcnt64_t = __blkcnt64_t; +pub type fsblkcnt64_t = __fsblkcnt64_t; +pub type fsfilcnt64_t = __fsfilcnt64_t; + +pub type __pthread_spinlock_t = ::c_int; +pub type __tss_t = ::c_int; +pub type __thrd_t = ::c_long; +pub type __pthread_t = ::c_long; +pub type pthread_t = __pthread_t; +pub type __pthread_process_shared = ::c_uint; +pub type __pthread_inheritsched = ::c_uint; +pub type __pthread_contentionscope = ::c_uint; +pub type __pthread_detachstate = ::c_uint; +pub type pthread_attr_t = __pthread_attr; +pub type __pthread_mutex_protocol = ::c_uint; +pub type __pthread_mutex_type = ::c_uint; +pub type __pthread_mutex_robustness = ::c_uint; +pub type pthread_mutexattr_t = __pthread_mutexattr; +pub type pthread_mutex_t = __pthread_mutex; +pub type pthread_condattr_t = __pthread_condattr; +pub type pthread_cond_t = __pthread_cond; +pub type pthread_spinlock_t = __pthread_spinlock_t; +pub type pthread_rwlockattr_t = __pthread_rwlockattr; +pub type pthread_rwlock_t = __pthread_rwlock; +pub type pthread_barrierattr_t = __pthread_barrierattr; +pub type pthread_barrier_t = __pthread_barrier; +pub type __pthread_key = ::c_int; +pub type pthread_key_t = __pthread_key; +pub type pthread_once_t = __pthread_once; + +pub type __rlimit_resource = ::c_uint; +pub type __rlimit_resource_t = __rlimit_resource; +pub type rlim_t = __rlim_t; +pub type rlim64_t = __rlim64_t; + +pub type __rusage_who = ::c_int; + +pub type __priority_which = ::c_uint; + +pub type sa_family_t = ::c_uchar; + +pub type in_port_t = u16; + +pub type __sigval_t = ::sigval; + +pub type sigevent_t = sigevent; + +pub type nfds_t = ::c_ulong; + +pub type tcflag_t = ::c_uint; +pub type cc_t = ::c_uchar; +pub type speed_t = ::c_int; + +pub type sigval_t = ::sigval; + +pub type greg_t = ::c_int; +pub type gregset_t = [greg_t; 19usize]; + +pub type __ioctl_dir = ::c_uint; + +pub type __ioctl_datum = ::c_uint; + +pub type __error_t_codes = ::c_int; + +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::c_schar; +pub type uint_fast8_t = ::c_uchar; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; + +pub type tcp_seq = u32; + +pub type tcp_ca_state = ::c_uint; + +pub type idtype_t = ::c_uint; + +pub type mqd_t = ::c_int; + +pub type Lmid_t = ::c_long; + +pub type regoff_t = ::c_int; + +pub type nl_item = ::c_int; + +pub type iconv_t = *mut ::c_void; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +// structs +s! { + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::c_int, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + pub imr_sourceaddr: in_addr, + } + + pub struct sockaddr { + pub sa_len: ::c_uchar, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14usize], + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct sockaddr_in { + pub sin_len: ::c_uchar, + pub sin_family: sa_family_t, + pub sin_port: in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_uchar; 8usize], + } + + pub struct sockaddr_in6 { + pub sin6_len: ::c_uchar, + pub sin6_family: sa_family_t, + pub sin6_port: in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_un { + pub sun_len: ::c_uchar, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108usize], + } + + pub struct sockaddr_storage { + pub ss_len: ::c_uchar, + pub ss_family: sa_family_t, + pub __ss_padding: [::c_char; 122usize], + pub __ss_align: __uint32_t, + } + + pub struct sockaddr_at { + pub _address: u8, + } + + pub struct sockaddr_ax25 { + pub _address: u8, + } + + pub struct sockaddr_x25 { + pub _address: u8, + } + + pub struct sockaddr_dl { + pub _address: u8, + } + pub struct sockaddr_eon { + pub _address: u8, + } + pub struct sockaddr_inarp { + pub _address: u8, + } + + pub struct sockaddr_ipx { + pub _address: u8, + } + pub struct sockaddr_iso { + pub _address: u8, + } + + pub struct sockaddr_ns { + pub _address: u8, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + pub ai_addr: *mut sockaddr, + pub ai_canonname: *mut ::c_char, + pub ai_next: *mut addrinfo, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct dirent { + pub d_ino: __ino_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_namlen: ::c_uchar, + pub d_name: [::c_char; 1usize], + } + + pub struct dirent64 { + pub d_ino: __ino64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_namlen: ::c_uchar, + pub d_name: [::c_char; 1usize], + } + + pub struct fd_set { + pub fds_bits: [__fd_mask; 8usize], + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; 20usize], + pub __ispeed: ::speed_t, + pub __ospeed: ::speed_t, + } + + pub struct mallinfo { + pub arena: ::c_int, + pub ordblks: ::c_int, + pub smblks: ::c_int, + pub hblks: ::c_int, + pub hblkhd: ::c_int, + pub usmblks: ::c_int, + pub fsmblks: ::c_int, + pub uordblks: ::c_int, + pub fordblks: ::c_int, + pub keepcost: ::c_int, + } + + pub struct mallinfo2 { + pub arena: ::size_t, + pub ordblks: ::size_t, + pub smblks: ::size_t, + pub hblks: ::size_t, + pub hblkhd: ::size_t, + pub usmblks: ::size_t, + pub fsmblks: ::size_t, + pub uordblks: ::size_t, + pub fordblks: ::size_t, + pub keepcost: ::size_t, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: __sigset_t, + pub sa_flags: ::c_int, + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + __unused1: *mut ::c_void, //actually a function pointer + pub sigev_notify_attributes: *mut pthread_attr_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub si_pid: __pid_t, + pub si_uid: __uid_t, + pub si_addr: *mut ::c_void, + pub si_status: ::c_int, + pub si_band: ::c_long, + pub si_value: ::sigval, + } + + pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, + } + + pub struct __locale_data { + pub _address: u8, + } + + pub struct stat { + pub st_fstype: ::c_int, + pub st_dev: __fsid_t, /* Actually st_fsid */ + pub st_ino: __ino_t, + pub st_gen: ::c_uint, + pub st_rdev: __dev_t, + pub st_mode: __mode_t, + pub st_nlink: __nlink_t, + pub st_uid: __uid_t, + pub st_gid: __gid_t, + pub st_size: __off_t, + pub st_atim: ::timespec, + pub st_mtim: ::timespec, + pub st_ctim: ::timespec, + pub st_blksize: __blksize_t, + pub st_blocks: __blkcnt_t, + pub st_author: __uid_t, + pub st_flags: ::c_uint, + pub st_spare: [::c_int; 11usize], + } + + pub struct stat64 { + pub st_fstype: ::c_int, + pub st_fsid: __fsid_t, + pub st_ino: __ino64_t, + pub st_gen: ::c_uint, + pub st_rdev: __dev_t, + pub st_mode: __mode_t, + pub st_nlink: __nlink_t, + pub st_uid: __uid_t, + pub st_gid: __gid_t, + pub st_size: __off64_t, + pub st_atim: ::timespec, + pub st_mtim: ::timespec, + pub st_ctim: ::timespec, + pub st_blksize: __blksize_t, + pub st_blocks: __blkcnt64_t, + pub st_author: __uid_t, + pub st_flags: ::c_uint, + pub st_spare: [::c_int; 8usize], + } + + pub struct statx { + pub stx_mask: u32, + pub stx_blksize: u32, + pub stx_attributes: u64, + pub stx_nlink: u32, + pub stx_uid: u32, + pub stx_gid: u32, + pub stx_mode: u16, + __statx_pad1: [u16; 1], + pub stx_ino: u64, + pub stx_size: u64, + pub stx_blocks: u64, + pub stx_attributes_mask: u64, + pub stx_atime: ::statx_timestamp, + pub stx_btime: ::statx_timestamp, + pub stx_ctime: ::statx_timestamp, + pub stx_mtime: ::statx_timestamp, + pub stx_rdev_major: u32, + pub stx_rdev_minor: u32, + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + __statx_pad2: [u64; 14], + } + + pub struct statx_timestamp { + pub tv_sec: i64, + pub tv_nsec: u32, + pub __statx_timestamp_pad1: [i32; 1], + } + + pub struct statfs { + pub f_type: ::c_uint, + pub f_bsize: ::c_ulong, + pub f_blocks: __fsblkcnt_t, + pub f_bfree: __fsblkcnt_t, + pub f_bavail: __fsblkcnt_t, + pub f_files: __fsblkcnt_t, + pub f_ffree: __fsblkcnt_t, + pub f_fsid: __fsid_t, + pub f_namelen: ::c_ulong, + pub f_favail: __fsfilcnt_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint; 3usize], + } + + pub struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::c_ulong, + pub f_blocks: __fsblkcnt64_t, + pub f_bfree: __fsblkcnt64_t, + pub f_bavail: __fsblkcnt64_t, + pub f_files: __fsblkcnt64_t, + pub f_ffree: __fsblkcnt64_t, + pub f_fsid: __fsid_t, + pub f_namelen: ::c_ulong, + pub f_favail: __fsfilcnt64_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint ; 3usize], + } + + pub struct statvfs { + pub __f_type: ::c_uint, + pub f_bsize: ::c_ulong, + pub f_blocks: __fsblkcnt_t, + pub f_bfree: __fsblkcnt_t, + pub f_bavail: __fsblkcnt_t, + pub f_files: __fsfilcnt_t, + pub f_ffree: __fsfilcnt_t, + pub f_fsid: __fsid_t, + pub f_namemax: ::c_ulong, + pub f_favail: __fsfilcnt_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint; 3usize], + } + + pub struct statvfs64 { + pub __f_type: ::c_uint, + pub f_bsize: ::c_ulong, + pub f_blocks: __fsblkcnt64_t, + pub f_bfree: __fsblkcnt64_t, + pub f_bavail: __fsblkcnt64_t, + pub f_files: __fsfilcnt64_t, + pub f_ffree: __fsfilcnt64_t, + pub f_fsid: __fsid_t, + pub f_namemax: ::c_ulong, + pub f_favail: __fsfilcnt64_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint; 3usize], + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __next_prio: *mut aiocb, + __abs_prio: ::c_int, + __policy: ::c_int, + __error_code: ::c_int, + __return_value: ::ssize_t, + pub aio_offset: off_t, + #[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))] + __unused1: [::c_char; 4], + __glibc_reserved: [::c_char; 32] + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + } + + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + __size: [::c_char; 20usize], + } + + pub struct __pthread { + pub _address: u8, + } + + pub struct __pthread_mutexattr { + pub __prioceiling: ::c_int, + pub __protocol: __pthread_mutex_protocol, + pub __pshared: __pthread_process_shared, + pub __mutex_type: __pthread_mutex_type, + } + pub struct __pthread_mutex { + pub __lock: ::c_uint, + pub __owner_id: ::c_uint, + pub __cnt: ::c_uint, + pub __shpid: ::c_int, + pub __type: ::c_int, + pub __flags: ::c_int, + pub __reserved1: ::c_uint, + pub __reserved2: ::c_uint, + } + + pub struct __pthread_condattr { + pub __pshared: __pthread_process_shared, + pub __clock: __clockid_t, + } + + pub struct __pthread_rwlockattr { + pub __pshared: __pthread_process_shared, + } + + pub struct __pthread_barrierattr { + pub __pshared: __pthread_process_shared, + } + + pub struct __pthread_once { + pub __run: ::c_int, + pub __lock: __pthread_spinlock_t, + } + + pub struct __pthread_cond { + pub __lock: __pthread_spinlock_t, + pub __queue: *mut __pthread, + pub __attr: *mut __pthread_condattr, + pub __wrefs: ::c_uint, + pub __data: *mut ::c_void, + } + + pub struct __pthread_attr { + pub __schedparam: sched_param, + pub __stackaddr: *mut ::c_void, + pub __stacksize: size_t, + pub __guardsize: size_t, + pub __detachstate: __pthread_detachstate, + pub __inheritsched: __pthread_inheritsched, + pub __contentionscope: __pthread_contentionscope, + pub __schedpolicy: ::c_int, + } + + pub struct __pthread_rwlock { + pub __held: __pthread_spinlock_t, + pub __lock: __pthread_spinlock_t, + pub __readers: ::c_int, + pub __readerqueue: *mut __pthread, + pub __writerqueue: *mut __pthread, + pub __attr: *mut __pthread_rwlockattr, + pub __data: *mut ::c_void, + } + + pub struct __pthread_barrier { + pub __lock: __pthread_spinlock_t, + pub __queue: *mut __pthread, + pub __pending: ::c_uint, + pub __count: ::c_uint, + pub __attr: *mut __pthread_barrierattr, + pub __data: *mut ::c_void, + } + + pub struct seminfo { + pub semmap: ::c_int, + pub semmni: ::c_int, + pub semmns: ::c_int, + pub semmnu: ::c_int, + pub semmsl: ::c_int, + pub semopm: ::c_int, + pub semume: ::c_int, + pub semusz: ::c_int, + pub semvmx: ::c_int, + pub semaem: ::c_int, + } + + pub struct _IO_FILE { + _unused: [u8; 0], + } + + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: size_t, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: __uid_t, + pub pw_gid: __gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_long, + pub tm_zone: *const ::c_char, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut c_char, + pub ifa_flags: ::c_uint, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_ifu: *mut ::sockaddr, // FIXME This should be a union + pub ifa_data: *mut ::c_void + } + + pub struct arpreq { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + pub arp_dev: [::c_char; 16], + } + + pub struct arpreq_old { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + } + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [::c_char; ::IFNAMSIZ], + pub ifr_ifru: ::sockaddr, + } + + pub struct __locale_struct { + pub __locales: [*mut __locale_data; 13usize], + pub __ctype_b: *const ::c_ushort, + pub __ctype_tolower: *const ::c_int, + pub __ctype_toupper: *const ::c_int, + pub __names: [*const ::c_char; 13usize], + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct stack_t { + pub ss_sp: * mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct dl_phdr_info { + pub dlpi_addr: Elf_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct flock { + #[cfg(target_pointer_width = "32")] + pub l_type : ::c_int, + #[cfg(target_pointer_width = "32")] + pub l_whence : ::c_int, + #[cfg(target_pointer_width = "64")] + pub l_type : ::c_short, + #[cfg(target_pointer_width = "64")] + pub l_whence : ::c_short, + pub l_start : __off_t, + pub l_len : __off_t, + pub l_pid : __pid_t, + } + + pub struct flock64 { + #[cfg(target_pointer_width = "32")] + pub l_type : ::c_int, + #[cfg(target_pointer_width = "32")] + pub l_whence : ::c_int, + #[cfg(target_pointer_width = "64")] + pub l_type : ::c_short, + #[cfg(target_pointer_width = "64")] + pub l_whence : ::c_short, + pub l_start : __off_t, + pub l_len : __off64_t, + pub l_pid : __pid_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct regex_t { + __buffer: *mut ::c_void, + __allocated: ::size_t, + __used: ::size_t, + __syntax: ::c_ulong, + __fastmap: *mut ::c_char, + __translate: *mut ::c_char, + __re_nsub: ::size_t, + __bitfield: u8, + } + + pub struct cpu_set_t { + #[cfg(all(target_pointer_width = "32", + not(target_arch = "x86_64")))] + bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + bits: [u64; 16], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct mntent { + pub mnt_fsname: *mut ::c_char, + pub mnt_dir: *mut ::c_char, + pub mnt_type: *mut ::c_char, + pub mnt_opts: *mut ::c_char, + pub mnt_freq: ::c_int, + pub mnt_passno: ::c_int, + } + + pub struct posix_spawn_file_actions_t { + __allocated: ::c_int, + __used: ::c_int, + __actions: *mut ::c_int, + __pad: [::c_int; 16], + } + + pub struct posix_spawnattr_t { + __flags: ::c_short, + __pgrp: ::pid_t, + __sd: ::sigset_t, + __ss: ::sigset_t, + __sp: ::sched_param, + __policy: ::c_int, + __pad: [::c_int; 16], + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct option { + pub name: *const ::c_char, + pub has_arg: ::c_int, + pub flag: *mut ::c_int, + pub val: ::c_int, + } + +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; __UT_LINESIZE], + pub ut_id: [::c_char; 4], + + pub ut_user: [::c_char; __UT_NAMESIZE], + pub ut_host: [::c_char; __UT_HOSTSIZE], + pub ut_exit: __exit_status, + + #[cfg(any( all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_session: ::c_long, + #[cfg(any(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_tv: ::timeval, + + #[cfg(not(any(all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_session: i32, + #[cfg(not(any(all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_tv: __timeval, + + pub ut_addr_v6: [i32; 4], + __glibc_reserved: [::c_char; 20], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__glibc_reserved == other.__glibc_reserved + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__glibc_reserved", &self.__glibc_reserved) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__glibc_reserved.hash(state); + } + } + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.si_status + } +} + +// const + +// aio.h +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +// glob.h +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const GLOB_PERIOD: ::c_int = 1 << 7; +pub const GLOB_ALTDIRFUNC: ::c_int = 1 << 9; +pub const GLOB_BRACE: ::c_int = 1 << 10; +pub const GLOB_NOMAGIC: ::c_int = 1 << 11; +pub const GLOB_TILDE: ::c_int = 1 << 12; +pub const GLOB_ONLYDIR: ::c_int = 1 << 13; +pub const GLOB_TILDE_CHECK: ::c_int = 1 << 14; + +// ipc.h +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_CREAT: ::c_int = 0o1000; +pub const IPC_EXCL: ::c_int = 0o2000; +pub const IPC_NOWAIT: ::c_int = 0o4000; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; +pub const IPC_INFO: ::c_int = 3; +pub const MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; + +// shm.h +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_REMAP: ::c_int = 0o40000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; +// unistd.h +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const __FD_SETSIZE: usize = 256; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const F_OK: ::c_int = 0; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; +pub const L_SET: ::c_int = 0; +pub const L_INCR: ::c_int = 1; +pub const L_XTND: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_LOCK: ::c_int = 1; +pub const F_TLOCK: ::c_int = 2; +pub const F_TEST: ::c_int = 3; +pub const CLOSE_RANGE_CLOEXEC: ::c_int = 4; + +// stdio.h +pub const EOF: ::c_int = -1; + +// stdlib.h +pub const WNOHANG: ::c_int = 1; +pub const WUNTRACED: ::c_int = 2; +pub const WSTOPPED: ::c_int = 2; +pub const WCONTINUED: ::c_int = 4; +pub const WNOWAIT: ::c_int = 8; +pub const WEXITED: ::c_int = 16; +pub const __W_CONTINUED: ::c_int = 65535; +pub const __WCOREFLAG: ::c_int = 128; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const __LITTLE_ENDIAN: usize = 1234; +pub const __BIG_ENDIAN: usize = 4321; +pub const __PDP_ENDIAN: usize = 3412; +pub const __BYTE_ORDER: usize = 1234; +pub const __FLOAT_WORD_ORDER: usize = 1234; +pub const LITTLE_ENDIAN: usize = 1234; +pub const BIG_ENDIAN: usize = 4321; +pub const PDP_ENDIAN: usize = 3412; +pub const BYTE_ORDER: usize = 1234; + +// sys/select.h +pub const FD_SETSIZE: usize = 256; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 32; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 28; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 16; +pub const __SIZEOF_PTHREAD_COND_T: usize = 20; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_ONCE_T: usize = 8; +pub const __PTHREAD_SPIN_LOCK_INITIALIZER: ::c_int = 0; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; + +// sys/resource.h +pub const RLIM_INFINITY: ::rlim_t = 2147483647; +pub const RLIM64_INFINITY: ::rlim64_t = 9223372036854775807; +pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; +pub const PRIO_MIN: ::c_int = -20; +pub const PRIO_MAX: ::c_int = 20; + +// pwd.h +pub const NSS_BUFLEN_PASSWD: usize = 1024; + +// sys/socket.h +pub const SOCK_TYPE_MASK: usize = 15; +pub const PF_UNSPEC: ::c_int = 0; +pub const PF_LOCAL: ::c_int = 1; +pub const PF_UNIX: ::c_int = 1; +pub const PF_FILE: ::c_int = 1; +pub const PF_INET: ::c_int = 2; +pub const PF_IMPLINK: ::c_int = 3; +pub const PF_PUP: ::c_int = 4; +pub const PF_CHAOS: ::c_int = 5; +pub const PF_NS: ::c_int = 6; +pub const PF_ISO: ::c_int = 7; +pub const PF_OSI: ::c_int = 7; +pub const PF_ECMA: ::c_int = 8; +pub const PF_DATAKIT: ::c_int = 9; +pub const PF_CCITT: ::c_int = 10; +pub const PF_SNA: ::c_int = 11; +pub const PF_DECnet: ::c_int = 12; +pub const PF_DLI: ::c_int = 13; +pub const PF_LAT: ::c_int = 14; +pub const PF_HYLINK: ::c_int = 15; +pub const PF_APPLETALK: ::c_int = 16; +pub const PF_ROUTE: ::c_int = 17; +pub const PF_XTP: ::c_int = 19; +pub const PF_COIP: ::c_int = 20; +pub const PF_CNT: ::c_int = 21; +pub const PF_RTIP: ::c_int = 22; +pub const PF_IPX: ::c_int = 23; +pub const PF_SIP: ::c_int = 24; +pub const PF_PIP: ::c_int = 25; +pub const PF_INET6: ::c_int = 26; +pub const PF_MAX: ::c_int = 27; +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = 1; +pub const AF_FILE: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NS: ::c_int = 6; +pub const AF_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = 7; +pub const AF_ECMA: ::c_int = 8; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +pub const pseudo_AF_RTIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_SIP: ::c_int = 24; +pub const pseudo_AF_PIP: ::c_int = 25; +pub const AF_INET6: ::c_int = 26; +pub const AF_MAX: ::c_int = 27; +pub const SOMAXCONN: ::c_int = 4096; +pub const _SS_SIZE: usize = 128; +pub const CMGROUP_MAX: usize = 16; +pub const SOL_SOCKET: ::c_int = 65535; + +// sys/time.h +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +// netinet/in.h +pub const SOL_IP: ::c_int = 0; +pub const SOL_TCP: ::c_int = 6; +pub const SOL_UDP: ::c_int = 17; +pub const SOL_IPV6: ::c_int = 41; +pub const SOL_ICMPV6: ::c_int = 58; +pub const IP_OPTIONS: ::c_int = 1; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_TOS: ::c_int = 3; +pub const IP_TTL: ::c_int = 4; +pub const IP_RECVOPTS: ::c_int = 5; +pub const IP_RECVRETOPTS: ::c_int = 6; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_RETOPTS: ::c_int = 8; +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IPV6_ADDRFORM: ::c_int = 1; +pub const IPV6_2292PKTINFO: ::c_int = 2; +pub const IPV6_2292HOPOPTS: ::c_int = 3; +pub const IPV6_2292DSTOPTS: ::c_int = 4; +pub const IPV6_2292RTHDR: ::c_int = 5; +pub const IPV6_2292PKTOPTIONS: ::c_int = 6; +pub const IPV6_CHECKSUM: ::c_int = 7; +pub const IPV6_2292HOPLIMIT: ::c_int = 8; +pub const IPV6_RXINFO: ::c_int = 2; +pub const IPV6_TXINFO: ::c_int = 2; +pub const SCM_SRCINFO: ::c_int = 2; +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +pub const IPV6_MULTICAST_LOOP: ::c_int = 19; +pub const IPV6_JOIN_GROUP: ::c_int = 20; +pub const IPV6_LEAVE_GROUP: ::c_int = 21; +pub const IPV6_ROUTER_ALERT: ::c_int = 22; +pub const IPV6_MTU_DISCOVER: ::c_int = 23; +pub const IPV6_MTU: ::c_int = 24; +pub const IPV6_RECVERR: ::c_int = 25; +pub const IPV6_V6ONLY: ::c_int = 26; +pub const IPV6_JOIN_ANYCAST: ::c_int = 27; +pub const IPV6_LEAVE_ANYCAST: ::c_int = 28; +pub const IPV6_RECVPKTINFO: ::c_int = 49; +pub const IPV6_PKTINFO: ::c_int = 50; +pub const IPV6_RECVHOPLIMIT: ::c_int = 51; +pub const IPV6_HOPLIMIT: ::c_int = 52; +pub const IPV6_RECVHOPOPTS: ::c_int = 53; +pub const IPV6_HOPOPTS: ::c_int = 54; +pub const IPV6_RTHDRDSTOPTS: ::c_int = 55; +pub const IPV6_RECVRTHDR: ::c_int = 56; +pub const IPV6_RTHDR: ::c_int = 57; +pub const IPV6_RECVDSTOPTS: ::c_int = 58; +pub const IPV6_DSTOPTS: ::c_int = 59; +pub const IPV6_RECVPATHMTU: ::c_int = 60; +pub const IPV6_PATHMTU: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; +pub const IPV6_RECVTCLASS: ::c_int = 66; +pub const IPV6_TCLASS: ::c_int = 67; +pub const IPV6_ADDR_PREFERENCES: ::c_int = 72; +pub const IPV6_MINHOPCOUNT: ::c_int = 73; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21; +pub const IPV6_RXHOPOPTS: ::c_int = 3; +pub const IPV6_RXDSTOPTS: ::c_int = 4; +pub const IPV6_RTHDR_LOOSE: ::c_int = 0; +pub const IPV6_RTHDR_STRICT: ::c_int = 1; +pub const IPV6_RTHDR_TYPE_0: ::c_int = 0; +pub const IN_CLASSA_NET: u32 = 4278190080; +pub const IN_CLASSA_NSHIFT: usize = 24; +pub const IN_CLASSA_HOST: u32 = 16777215; +pub const IN_CLASSA_MAX: u32 = 128; +pub const IN_CLASSB_NET: u32 = 4294901760; +pub const IN_CLASSB_NSHIFT: usize = 16; +pub const IN_CLASSB_HOST: u32 = 65535; +pub const IN_CLASSB_MAX: u32 = 65536; +pub const IN_CLASSC_NET: u32 = 4294967040; +pub const IN_CLASSC_NSHIFT: usize = 8; +pub const IN_CLASSC_HOST: u32 = 255; +pub const IN_LOOPBACKNET: u32 = 127; +pub const INET_ADDRSTRLEN: usize = 16; +pub const INET6_ADDRSTRLEN: usize = 46; + +// netinet/ip.h +pub const IPTOS_TOS_MASK: u8 = 0x1E; +pub const IPTOS_PREC_MASK: u8 = 0xE0; + +pub const IPTOS_ECN_NOT_ECT: u8 = 0x00; + +pub const IPTOS_LOWDELAY: u8 = 0x10; +pub const IPTOS_THROUGHPUT: u8 = 0x08; +pub const IPTOS_RELIABILITY: u8 = 0x04; +pub const IPTOS_MINCOST: u8 = 0x02; + +pub const IPTOS_PREC_NETCONTROL: u8 = 0xe0; +pub const IPTOS_PREC_INTERNETCONTROL: u8 = 0xc0; +pub const IPTOS_PREC_CRITIC_ECP: u8 = 0xa0; +pub const IPTOS_PREC_FLASHOVERRIDE: u8 = 0x80; +pub const IPTOS_PREC_FLASH: u8 = 0x60; +pub const IPTOS_PREC_IMMEDIATE: u8 = 0x40; +pub const IPTOS_PREC_PRIORITY: u8 = 0x20; +pub const IPTOS_PREC_ROUTINE: u8 = 0x00; + +pub const IPTOS_ECN_MASK: u8 = 0x03; +pub const IPTOS_ECN_ECT1: u8 = 0x01; +pub const IPTOS_ECN_ECT0: u8 = 0x02; +pub const IPTOS_ECN_CE: u8 = 0x03; + +pub const IPOPT_COPY: u8 = 0x80; +pub const IPOPT_CLASS_MASK: u8 = 0x60; +pub const IPOPT_NUMBER_MASK: u8 = 0x1f; + +pub const IPOPT_CONTROL: u8 = 0x00; +pub const IPOPT_RESERVED1: u8 = 0x20; +pub const IPOPT_MEASUREMENT: u8 = 0x40; +pub const IPOPT_RESERVED2: u8 = 0x60; +pub const IPOPT_END: u8 = 0 | IPOPT_CONTROL; +pub const IPOPT_NOOP: u8 = 1 | IPOPT_CONTROL; +pub const IPOPT_SEC: u8 = 2 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_LSRR: u8 = 3 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_TIMESTAMP: u8 = 4 | IPOPT_MEASUREMENT; +pub const IPOPT_RR: u8 = 7 | IPOPT_CONTROL; +pub const IPOPT_SID: u8 = 8 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_SSRR: u8 = 9 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_RA: u8 = 20 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPVERSION: u8 = 4; +pub const MAXTTL: u8 = 255; +pub const IPDEFTTL: u8 = 64; +pub const IPOPT_OPTVAL: u8 = 0; +pub const IPOPT_OLEN: u8 = 1; +pub const IPOPT_OFFSET: u8 = 2; +pub const IPOPT_MINOFF: u8 = 4; +pub const MAX_IPOPTLEN: u8 = 40; +pub const IPOPT_NOP: u8 = IPOPT_NOOP; +pub const IPOPT_EOL: u8 = IPOPT_END; +pub const IPOPT_TS: u8 = IPOPT_TIMESTAMP; +pub const IPOPT_TS_TSONLY: u8 = 0; +pub const IPOPT_TS_TSANDADDR: u8 = 1; +pub const IPOPT_TS_PRESPEC: u8 = 3; + +// net/if_arp.h +pub const ARPOP_REQUEST: u16 = 1; +pub const ARPOP_REPLY: u16 = 2; +pub const ARPOP_RREQUEST: u16 = 3; +pub const ARPOP_RREPLY: u16 = 4; +pub const ARPOP_InREQUEST: u16 = 8; +pub const ARPOP_InREPLY: u16 = 9; +pub const ARPOP_NAK: u16 = 10; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +pub const ARPD_LOOKUP: ::c_ushort = 0x02; +pub const ARPD_FLUSH: ::c_ushort = 0x03; +pub const ATF_MAGIC: ::c_int = 0x80; + +pub const ATF_NETMASK: ::c_int = 0x20; +pub const ATF_DONTPUB: ::c_int = 0x40; + +pub const ARPHRD_NETROM: u16 = 0; +pub const ARPHRD_ETHER: u16 = 1; +pub const ARPHRD_EETHER: u16 = 2; +pub const ARPHRD_AX25: u16 = 3; +pub const ARPHRD_PRONET: u16 = 4; +pub const ARPHRD_CHAOS: u16 = 5; +pub const ARPHRD_IEEE802: u16 = 6; +pub const ARPHRD_ARCNET: u16 = 7; +pub const ARPHRD_APPLETLK: u16 = 8; +pub const ARPHRD_DLCI: u16 = 15; +pub const ARPHRD_ATM: u16 = 19; +pub const ARPHRD_METRICOM: u16 = 23; +pub const ARPHRD_IEEE1394: u16 = 24; +pub const ARPHRD_EUI64: u16 = 27; +pub const ARPHRD_INFINIBAND: u16 = 32; + +pub const ARPHRD_SLIP: u16 = 256; +pub const ARPHRD_CSLIP: u16 = 257; +pub const ARPHRD_SLIP6: u16 = 258; +pub const ARPHRD_CSLIP6: u16 = 259; +pub const ARPHRD_RSRVD: u16 = 260; +pub const ARPHRD_ADAPT: u16 = 264; +pub const ARPHRD_ROSE: u16 = 270; +pub const ARPHRD_X25: u16 = 271; +pub const ARPHRD_HWX25: u16 = 272; +pub const ARPHRD_CAN: u16 = 280; +pub const ARPHRD_PPP: u16 = 512; +pub const ARPHRD_CISCO: u16 = 513; +pub const ARPHRD_HDLC: u16 = ARPHRD_CISCO; +pub const ARPHRD_LAPB: u16 = 516; +pub const ARPHRD_DDCMP: u16 = 517; +pub const ARPHRD_RAWHDLC: u16 = 518; + +pub const ARPHRD_TUNNEL: u16 = 768; +pub const ARPHRD_TUNNEL6: u16 = 769; +pub const ARPHRD_FRAD: u16 = 770; +pub const ARPHRD_SKIP: u16 = 771; +pub const ARPHRD_LOOPBACK: u16 = 772; +pub const ARPHRD_LOCALTLK: u16 = 773; +pub const ARPHRD_FDDI: u16 = 774; +pub const ARPHRD_BIF: u16 = 775; +pub const ARPHRD_SIT: u16 = 776; +pub const ARPHRD_IPDDP: u16 = 777; +pub const ARPHRD_IPGRE: u16 = 778; +pub const ARPHRD_PIMREG: u16 = 779; +pub const ARPHRD_HIPPI: u16 = 780; +pub const ARPHRD_ASH: u16 = 781; +pub const ARPHRD_ECONET: u16 = 782; +pub const ARPHRD_IRDA: u16 = 783; +pub const ARPHRD_FCPP: u16 = 784; +pub const ARPHRD_FCAL: u16 = 785; +pub const ARPHRD_FCPL: u16 = 786; +pub const ARPHRD_FCFABRIC: u16 = 787; +pub const ARPHRD_IEEE802_TR: u16 = 800; +pub const ARPHRD_IEEE80211: u16 = 801; +pub const ARPHRD_IEEE80211_PRISM: u16 = 802; +pub const ARPHRD_IEEE80211_RADIOTAP: u16 = 803; +pub const ARPHRD_IEEE802154: u16 = 804; + +pub const ARPHRD_VOID: u16 = 0xFFFF; +pub const ARPHRD_NONE: u16 = 0xFFFE; + +// bits/posix1_lim.h +pub const _POSIX_AIO_LISTIO_MAX: usize = 2; +pub const _POSIX_AIO_MAX: usize = 1; +pub const _POSIX_ARG_MAX: usize = 4096; +pub const _POSIX_CHILD_MAX: usize = 25; +pub const _POSIX_DELAYTIMER_MAX: usize = 32; +pub const _POSIX_HOST_NAME_MAX: usize = 255; +pub const _POSIX_LINK_MAX: usize = 8; +pub const _POSIX_LOGIN_NAME_MAX: usize = 9; +pub const _POSIX_MAX_CANON: usize = 255; +pub const _POSIX_MAX_INPUT: usize = 255; +pub const _POSIX_MQ_OPEN_MAX: usize = 8; +pub const _POSIX_MQ_PRIO_MAX: usize = 32; +pub const _POSIX_NAME_MAX: usize = 14; +pub const _POSIX_NGROUPS_MAX: usize = 8; +pub const _POSIX_OPEN_MAX: usize = 20; +pub const _POSIX_FD_SETSIZE: usize = 20; +pub const _POSIX_PATH_MAX: usize = 256; +pub const _POSIX_PIPE_BUF: usize = 512; +pub const _POSIX_RE_DUP_MAX: usize = 255; +pub const _POSIX_RTSIG_MAX: usize = 8; +pub const _POSIX_SEM_NSEMS_MAX: usize = 256; +pub const _POSIX_SEM_VALUE_MAX: usize = 32767; +pub const _POSIX_SIGQUEUE_MAX: usize = 32; +pub const _POSIX_SSIZE_MAX: usize = 32767; +pub const _POSIX_STREAM_MAX: usize = 8; +pub const _POSIX_SYMLINK_MAX: usize = 255; +pub const _POSIX_SYMLOOP_MAX: usize = 8; +pub const _POSIX_TIMER_MAX: usize = 32; +pub const _POSIX_TTY_NAME_MAX: usize = 9; +pub const _POSIX_TZNAME_MAX: usize = 6; +pub const _POSIX_QLIMIT: usize = 1; +pub const _POSIX_HIWAT: usize = 512; +pub const _POSIX_UIO_MAXIOV: usize = 16; +pub const _POSIX_CLOCKRES_MIN: usize = 20000000; +pub const NAME_MAX: usize = 255; +pub const NGROUPS_MAX: usize = 256; +pub const _POSIX_THREAD_KEYS_MAX: usize = 128; +pub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: usize = 4; +pub const _POSIX_THREAD_THREADS_MAX: usize = 64; +pub const SEM_VALUE_MAX: ::c_int = 2147483647; +pub const MAXNAMLEN: usize = 255; + +// netdb.h +pub const _PATH_HEQUIV: &'static [u8; 17usize] = b"/etc/hosts.equiv\0"; +pub const _PATH_HOSTS: &'static [u8; 11usize] = b"/etc/hosts\0"; +pub const _PATH_NETWORKS: &'static [u8; 14usize] = b"/etc/networks\0"; +pub const _PATH_NSSWITCH_CONF: &'static [u8; 19usize] = b"/etc/nsswitch.conf\0"; +pub const _PATH_PROTOCOLS: &'static [u8; 15usize] = b"/etc/protocols\0"; +pub const _PATH_SERVICES: &'static [u8; 14usize] = b"/etc/services\0"; +pub const HOST_NOT_FOUND: ::c_int = 1; +pub const TRY_AGAIN: ::c_int = 2; +pub const NO_RECOVERY: ::c_int = 3; +pub const NO_DATA: ::c_int = 4; +pub const NETDB_INTERNAL: ::c_int = -1; +pub const NETDB_SUCCESS: ::c_int = 0; +pub const NO_ADDRESS: ::c_int = 4; +pub const IPPORT_RESERVED: ::c_int = 1024; +pub const SCOPE_DELIMITER: u8 = 37u8; +pub const GAI_WAIT: ::c_int = 0; +pub const GAI_NOWAIT: ::c_int = 1; +pub const AI_PASSIVE: ::c_int = 1; +pub const AI_CANONNAME: ::c_int = 2; +pub const AI_NUMERICHOST: ::c_int = 4; +pub const AI_V4MAPPED: ::c_int = 8; +pub const AI_ALL: ::c_int = 16; +pub const AI_ADDRCONFIG: ::c_int = 32; +pub const AI_IDN: ::c_int = 64; +pub const AI_CANONIDN: ::c_int = 128; +pub const AI_NUMERICSERV: ::c_int = 1024; +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_ADDRFAMILY: ::c_int = -9; +pub const EAI_INPROGRESS: ::c_int = -100; +pub const EAI_CANCELED: ::c_int = -101; +pub const EAI_NOTCANCELED: ::c_int = -102; +pub const EAI_ALLDONE: ::c_int = -103; +pub const EAI_INTR: ::c_int = -104; +pub const EAI_IDN_ENCODE: ::c_int = -105; +pub const NI_MAXHOST: usize = 1025; +pub const NI_MAXSERV: usize = 32; +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; +pub const NI_IDN: ::c_int = 32; + +// time.h +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6; +pub const TIMER_ABSTIME: ::c_int = 1; +pub const TIME_UTC: ::c_int = 1; + +// sys/poll.h +pub const POLLIN: i16 = 1; +pub const POLLPRI: i16 = 2; +pub const POLLOUT: i16 = 4; +pub const POLLRDNORM: i16 = 1; +pub const POLLRDBAND: i16 = 2; +pub const POLLWRNORM: i16 = 4; +pub const POLLWRBAND: i16 = 4; +pub const POLLERR: i16 = 8; +pub const POLLHUP: i16 = 16; +pub const POLLNVAL: i16 = 32; + +// locale.h +pub const __LC_CTYPE: usize = 0; +pub const __LC_NUMERIC: usize = 1; +pub const __LC_TIME: usize = 2; +pub const __LC_COLLATE: usize = 3; +pub const __LC_MONETARY: usize = 4; +pub const __LC_MESSAGES: usize = 5; +pub const __LC_ALL: usize = 6; +pub const __LC_PAPER: usize = 7; +pub const __LC_NAME: usize = 8; +pub const __LC_ADDRESS: usize = 9; +pub const __LC_TELEPHONE: usize = 10; +pub const __LC_MEASUREMENT: usize = 11; +pub const __LC_IDENTIFICATION: usize = 12; +pub const LC_CTYPE: ::c_int = 0; +pub const LC_NUMERIC: ::c_int = 1; +pub const LC_TIME: ::c_int = 2; +pub const LC_COLLATE: ::c_int = 3; +pub const LC_MONETARY: ::c_int = 4; +pub const LC_MESSAGES: ::c_int = 5; +pub const LC_ALL: ::c_int = 6; +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_CTYPE_MASK: ::c_int = 1; +pub const LC_NUMERIC_MASK: ::c_int = 2; +pub const LC_TIME_MASK: ::c_int = 4; +pub const LC_COLLATE_MASK: ::c_int = 8; +pub const LC_MONETARY_MASK: ::c_int = 16; +pub const LC_MESSAGES_MASK: ::c_int = 32; +pub const LC_PAPER_MASK: ::c_int = 128; +pub const LC_NAME_MASK: ::c_int = 256; +pub const LC_ADDRESS_MASK: ::c_int = 512; +pub const LC_TELEPHONE_MASK: ::c_int = 1024; +pub const LC_MEASUREMENT_MASK: ::c_int = 2048; +pub const LC_IDENTIFICATION_MASK: ::c_int = 4096; +pub const LC_ALL_MASK: ::c_int = 8127; + +pub const ABDAY_1: ::nl_item = 0x20000; +pub const ABDAY_2: ::nl_item = 0x20001; +pub const ABDAY_3: ::nl_item = 0x20002; +pub const ABDAY_4: ::nl_item = 0x20003; +pub const ABDAY_5: ::nl_item = 0x20004; +pub const ABDAY_6: ::nl_item = 0x20005; +pub const ABDAY_7: ::nl_item = 0x20006; + +pub const DAY_1: ::nl_item = 0x20007; +pub const DAY_2: ::nl_item = 0x20008; +pub const DAY_3: ::nl_item = 0x20009; +pub const DAY_4: ::nl_item = 0x2000A; +pub const DAY_5: ::nl_item = 0x2000B; +pub const DAY_6: ::nl_item = 0x2000C; +pub const DAY_7: ::nl_item = 0x2000D; + +pub const ABMON_1: ::nl_item = 0x2000E; +pub const ABMON_2: ::nl_item = 0x2000F; +pub const ABMON_3: ::nl_item = 0x20010; +pub const ABMON_4: ::nl_item = 0x20011; +pub const ABMON_5: ::nl_item = 0x20012; +pub const ABMON_6: ::nl_item = 0x20013; +pub const ABMON_7: ::nl_item = 0x20014; +pub const ABMON_8: ::nl_item = 0x20015; +pub const ABMON_9: ::nl_item = 0x20016; +pub const ABMON_10: ::nl_item = 0x20017; +pub const ABMON_11: ::nl_item = 0x20018; +pub const ABMON_12: ::nl_item = 0x20019; + +pub const MON_1: ::nl_item = 0x2001A; +pub const MON_2: ::nl_item = 0x2001B; +pub const MON_3: ::nl_item = 0x2001C; +pub const MON_4: ::nl_item = 0x2001D; +pub const MON_5: ::nl_item = 0x2001E; +pub const MON_6: ::nl_item = 0x2001F; +pub const MON_7: ::nl_item = 0x20020; +pub const MON_8: ::nl_item = 0x20021; +pub const MON_9: ::nl_item = 0x20022; +pub const MON_10: ::nl_item = 0x20023; +pub const MON_11: ::nl_item = 0x20024; +pub const MON_12: ::nl_item = 0x20025; + +pub const AM_STR: ::nl_item = 0x20026; +pub const PM_STR: ::nl_item = 0x20027; + +pub const D_T_FMT: ::nl_item = 0x20028; +pub const D_FMT: ::nl_item = 0x20029; +pub const T_FMT: ::nl_item = 0x2002A; +pub const T_FMT_AMPM: ::nl_item = 0x2002B; + +pub const ERA: ::nl_item = 0x2002C; +pub const ERA_D_FMT: ::nl_item = 0x2002E; +pub const ALT_DIGITS: ::nl_item = 0x2002F; +pub const ERA_D_T_FMT: ::nl_item = 0x20030; +pub const ERA_T_FMT: ::nl_item = 0x20031; + +pub const CODESET: ::nl_item = 14; +pub const CRNCYSTR: ::nl_item = 0x4000F; +pub const RADIXCHAR: ::nl_item = 0x10000; +pub const THOUSEP: ::nl_item = 0x10001; +pub const YESEXPR: ::nl_item = 0x50000; +pub const NOEXPR: ::nl_item = 0x50001; +pub const YESSTR: ::nl_item = 0x50002; +pub const NOSTR: ::nl_item = 0x50003; + +// reboot.h +pub const RB_AUTOBOOT: ::c_int = 0x0; +pub const RB_ASKNAME: ::c_int = 0x1; +pub const RB_SINGLE: ::c_int = 0x2; +pub const RB_KBD: ::c_int = 0x4; +pub const RB_HALT: ::c_int = 0x8; +pub const RB_INITNAME: ::c_int = 0x10; +pub const RB_DFLTROOT: ::c_int = 0x20; +pub const RB_NOBOOTRC: ::c_int = 0x20; +pub const RB_ALTBOOT: ::c_int = 0x40; +pub const RB_UNIPROC: ::c_int = 0x80; +pub const RB_DEBUGGER: ::c_int = 0x1000; + +// semaphore.h +pub const __SIZEOF_SEM_T: usize = 20; +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +// termios.h +pub const IGNBRK: ::tcflag_t = 1; +pub const BRKINT: ::tcflag_t = 2; +pub const IGNPAR: ::tcflag_t = 4; +pub const PARMRK: ::tcflag_t = 8; +pub const INPCK: ::tcflag_t = 16; +pub const ISTRIP: ::tcflag_t = 32; +pub const INLCR: ::tcflag_t = 64; +pub const IGNCR: ::tcflag_t = 128; +pub const ICRNL: ::tcflag_t = 256; +pub const IXON: ::tcflag_t = 512; +pub const IXOFF: ::tcflag_t = 1024; +pub const IXANY: ::tcflag_t = 2048; +pub const IMAXBEL: ::tcflag_t = 8192; +pub const IUCLC: ::tcflag_t = 16384; +pub const OPOST: ::tcflag_t = 1; +pub const ONLCR: ::tcflag_t = 2; +pub const ONOEOT: ::tcflag_t = 8; +pub const OCRNL: ::tcflag_t = 16; +pub const ONOCR: ::tcflag_t = 32; +pub const ONLRET: ::tcflag_t = 64; +pub const NLDLY: ::tcflag_t = 768; +pub const NL0: ::tcflag_t = 0; +pub const NL1: ::tcflag_t = 256; +pub const TABDLY: ::tcflag_t = 3076; +pub const TAB0: ::tcflag_t = 0; +pub const TAB1: ::tcflag_t = 1024; +pub const TAB2: ::tcflag_t = 2048; +pub const TAB3: ::tcflag_t = 4; +pub const CRDLY: ::tcflag_t = 12288; +pub const CR0: ::tcflag_t = 0; +pub const CR1: ::tcflag_t = 4096; +pub const CR2: ::tcflag_t = 8192; +pub const CR3: ::tcflag_t = 12288; +pub const FFDLY: ::tcflag_t = 16384; +pub const FF0: ::tcflag_t = 0; +pub const FF1: ::tcflag_t = 16384; +pub const BSDLY: ::tcflag_t = 32768; +pub const BS0: ::tcflag_t = 0; +pub const BS1: ::tcflag_t = 32768; +pub const VTDLY: ::tcflag_t = 65536; +pub const VT0: ::tcflag_t = 0; +pub const VT1: ::tcflag_t = 65536; +pub const OLCUC: ::tcflag_t = 131072; +pub const OFILL: ::tcflag_t = 262144; +pub const OFDEL: ::tcflag_t = 524288; +pub const CIGNORE: ::tcflag_t = 1; +pub const CSIZE: ::tcflag_t = 768; +pub const CS5: ::tcflag_t = 0; +pub const CS6: ::tcflag_t = 256; +pub const CS7: ::tcflag_t = 512; +pub const CS8: ::tcflag_t = 768; +pub const CSTOPB: ::tcflag_t = 1024; +pub const CREAD: ::tcflag_t = 2048; +pub const PARENB: ::tcflag_t = 4096; +pub const PARODD: ::tcflag_t = 8192; +pub const HUPCL: ::tcflag_t = 16384; +pub const CLOCAL: ::tcflag_t = 32768; +pub const CRTSCTS: ::tcflag_t = 65536; +pub const CRTS_IFLOW: ::tcflag_t = 65536; +pub const CCTS_OFLOW: ::tcflag_t = 65536; +pub const CDTRCTS: ::tcflag_t = 131072; +pub const MDMBUF: ::tcflag_t = 1048576; +pub const CHWFLOW: ::tcflag_t = 1245184; +pub const ECHOKE: ::tcflag_t = 1; +pub const _ECHOE: ::tcflag_t = 2; +pub const ECHOE: ::tcflag_t = 2; +pub const _ECHOK: ::tcflag_t = 4; +pub const ECHOK: ::tcflag_t = 4; +pub const _ECHO: ::tcflag_t = 8; +pub const ECHO: ::tcflag_t = 8; +pub const _ECHONL: ::tcflag_t = 16; +pub const ECHONL: ::tcflag_t = 16; +pub const ECHOPRT: ::tcflag_t = 32; +pub const ECHOCTL: ::tcflag_t = 64; +pub const _ISIG: ::tcflag_t = 128; +pub const ISIG: ::tcflag_t = 128; +pub const _ICANON: ::tcflag_t = 256; +pub const ICANON: ::tcflag_t = 256; +pub const ALTWERASE: ::tcflag_t = 512; +pub const _IEXTEN: ::tcflag_t = 1024; +pub const IEXTEN: ::tcflag_t = 1024; +pub const EXTPROC: ::tcflag_t = 2048; +pub const _TOSTOP: ::tcflag_t = 4194304; +pub const TOSTOP: ::tcflag_t = 4194304; +pub const FLUSHO: ::tcflag_t = 8388608; +pub const NOKERNINFO: ::tcflag_t = 33554432; +pub const PENDIN: ::tcflag_t = 536870912; +pub const _NOFLSH: ::tcflag_t = 2147483648; +pub const NOFLSH: ::tcflag_t = 2147483648; +pub const VEOF: usize = 0; +pub const VEOL: usize = 1; +pub const VEOL2: usize = 2; +pub const VERASE: usize = 3; +pub const VWERASE: usize = 4; +pub const VKILL: usize = 5; +pub const VREPRINT: usize = 6; +pub const VINTR: usize = 8; +pub const VQUIT: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +pub const VSTART: usize = 12; +pub const VSTOP: usize = 13; +pub const VLNEXT: usize = 14; +pub const VDISCARD: usize = 15; +pub const VMIN: usize = 16; +pub const VTIME: usize = 17; +pub const VSTATUS: usize = 18; +pub const NCCS: usize = 20; +pub const B0: ::speed_t = 0; +pub const B50: ::speed_t = 50; +pub const B75: ::speed_t = 75; +pub const B110: ::speed_t = 110; +pub const B134: ::speed_t = 134; +pub const B150: ::speed_t = 150; +pub const B200: ::speed_t = 200; +pub const B300: ::speed_t = 300; +pub const B600: ::speed_t = 600; +pub const B1200: ::speed_t = 1200; +pub const B1800: ::speed_t = 1800; +pub const B2400: ::speed_t = 2400; +pub const B4800: ::speed_t = 4800; +pub const B9600: ::speed_t = 9600; +pub const B7200: ::speed_t = 7200; +pub const B14400: ::speed_t = 14400; +pub const B19200: ::speed_t = 19200; +pub const B28800: ::speed_t = 28800; +pub const B38400: ::speed_t = 38400; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 57600; +pub const B76800: ::speed_t = 76800; +pub const B115200: ::speed_t = 115200; +pub const B230400: ::speed_t = 230400; +pub const B460800: ::speed_t = 460800; +pub const B500000: ::speed_t = 500000; +pub const B576000: ::speed_t = 576000; +pub const B921600: ::speed_t = 921600; +pub const B1000000: ::speed_t = 1000000; +pub const B1152000: ::speed_t = 1152000; +pub const B1500000: ::speed_t = 1500000; +pub const B2000000: ::speed_t = 2000000; +pub const B2500000: ::speed_t = 2500000; +pub const B3000000: ::speed_t = 3000000; +pub const B3500000: ::speed_t = 3500000; +pub const B4000000: ::speed_t = 4000000; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +pub const TCSASOFT: ::c_int = 16; +pub const TCIFLUSH: ::c_int = 1; +pub const TCOFLUSH: ::c_int = 2; +pub const TCIOFLUSH: ::c_int = 3; +pub const TCOOFF: ::c_int = 1; +pub const TCOON: ::c_int = 2; +pub const TCIOFF: ::c_int = 3; +pub const TCION: ::c_int = 4; +pub const TTYDEF_IFLAG: ::tcflag_t = 11042; +pub const TTYDEF_LFLAG: ::tcflag_t = 1483; +pub const TTYDEF_CFLAG: ::tcflag_t = 23040; +pub const TTYDEF_SPEED: ::tcflag_t = 9600; +pub const CEOL: u8 = 0u8; +pub const CERASE: u8 = 127; +pub const CMIN: u8 = 1; +pub const CQUIT: u8 = 28; +pub const CTIME: u8 = 0; +pub const CBRK: u8 = 0u8; + +// dlfcn.h +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_LAZY: ::c_int = 1; +pub const RTLD_NOW: ::c_int = 2; +pub const RTLD_BINDING_MASK: ::c_int = 3; +pub const RTLD_NOLOAD: ::c_int = 4; +pub const RTLD_DEEPBIND: ::c_int = 8; +pub const RTLD_GLOBAL: ::c_int = 256; +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_NODELETE: ::c_int = 4096; +pub const DLFO_STRUCT_HAS_EH_DBASE: usize = 1; +pub const DLFO_STRUCT_HAS_EH_COUNT: usize = 0; +pub const LM_ID_BASE: c_long = 0; +pub const LM_ID_NEWLM: c_long = -1; + +// bits/signum_generic.h +pub const SIGINT: ::c_int = 2; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGFPE: ::c_int = 8; +pub const SIGSEGV: ::c_int = 11; +pub const SIGTERM: ::c_int = 15; +pub const SIGHUP: ::c_int = 1; +pub const SIGQUIT: ::c_int = 3; +pub const SIGTRAP: ::c_int = 5; +pub const SIGKILL: ::c_int = 9; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGIOT: ::c_int = 6; +pub const SIGBUS: ::c_int = 10; +pub const SIGSYS: ::c_int = 12; +pub const SIGEMT: ::c_int = 7; +pub const SIGINFO: ::c_int = 29; +pub const SIGLOST: ::c_int = 32; +pub const SIGURG: ::c_int = 16; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGCONT: ::c_int = 19; +pub const SIGCHLD: ::c_int = 20; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGPOLL: ::c_int = 23; +pub const SIGXCPU: ::c_int = 24; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGWINCH: ::c_int = 28; +pub const SIGIO: ::c_int = 23; +pub const SIGCLD: ::c_int = 20; +pub const __SIGRTMIN: usize = 32; +pub const __SIGRTMAX: usize = 32; +pub const _NSIG: usize = 33; +pub const NSIG: usize = 33; + +// bits/sigaction.h +pub const SA_ONSTACK: ::c_int = 1; +pub const SA_RESTART: ::c_int = 2; +pub const SA_NODEFER: ::c_int = 16; +pub const SA_RESETHAND: ::c_int = 4; +pub const SA_NOCLDSTOP: ::c_int = 8; +pub const SA_SIGINFO: ::c_int = 64; +pub const SA_INTERRUPT: ::c_int = 0; +pub const SA_NOMASK: ::c_int = 16; +pub const SA_ONESHOT: ::c_int = 4; +pub const SA_STACK: ::c_int = 1; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +// bits/sigcontext.h +pub const FPC_IE: u16 = 1; +pub const FPC_IM: u16 = 1; +pub const FPC_DE: u16 = 2; +pub const FPC_DM: u16 = 2; +pub const FPC_ZE: u16 = 4; +pub const FPC_ZM: u16 = 4; +pub const FPC_OE: u16 = 8; +pub const FPC_OM: u16 = 8; +pub const FPC_UE: u16 = 16; +pub const FPC_PE: u16 = 32; +pub const FPC_PC: u16 = 768; +pub const FPC_PC_24: u16 = 0; +pub const FPC_PC_53: u16 = 512; +pub const FPC_PC_64: u16 = 768; +pub const FPC_RC: u16 = 3072; +pub const FPC_RC_RN: u16 = 0; +pub const FPC_RC_RD: u16 = 1024; +pub const FPC_RC_RU: u16 = 2048; +pub const FPC_RC_CHOP: u16 = 3072; +pub const FPC_IC: u16 = 4096; +pub const FPC_IC_PROJ: u16 = 0; +pub const FPC_IC_AFF: u16 = 4096; +pub const FPS_IE: u16 = 1; +pub const FPS_DE: u16 = 2; +pub const FPS_ZE: u16 = 4; +pub const FPS_OE: u16 = 8; +pub const FPS_UE: u16 = 16; +pub const FPS_PE: u16 = 32; +pub const FPS_SF: u16 = 64; +pub const FPS_ES: u16 = 128; +pub const FPS_C0: u16 = 256; +pub const FPS_C1: u16 = 512; +pub const FPS_C2: u16 = 1024; +pub const FPS_TOS: u16 = 14336; +pub const FPS_TOS_SHIFT: u16 = 11; +pub const FPS_C3: u16 = 16384; +pub const FPS_BUSY: u16 = 32768; +pub const FPE_INTOVF_TRAP: ::c_int = 1; +pub const FPE_INTDIV_FAULT: ::c_int = 2; +pub const FPE_FLTOVF_FAULT: ::c_int = 3; +pub const FPE_FLTDIV_FAULT: ::c_int = 4; +pub const FPE_FLTUND_FAULT: ::c_int = 5; +pub const FPE_SUBRNG_FAULT: ::c_int = 7; +pub const FPE_FLTDNR_FAULT: ::c_int = 8; +pub const FPE_FLTINX_FAULT: ::c_int = 9; +pub const FPE_EMERR_FAULT: ::c_int = 10; +pub const FPE_EMBND_FAULT: ::c_int = 11; +pub const ILL_INVOPR_FAULT: ::c_int = 1; +pub const ILL_STACK_FAULT: ::c_int = 2; +pub const ILL_FPEOPR_FAULT: ::c_int = 3; +pub const DBG_SINGLE_TRAP: ::c_int = 1; +pub const DBG_BRKPNT_FAULT: ::c_int = 2; +pub const __NGREG: usize = 19; +pub const NGREG: usize = 19; + +// bits/sigstack.h +pub const MINSIGSTKSZ: usize = 8192; +pub const SIGSTKSZ: usize = 40960; + +// sys/stat.h +pub const __S_IFMT: mode_t = 61440; +pub const __S_IFDIR: mode_t = 16384; +pub const __S_IFCHR: mode_t = 8192; +pub const __S_IFBLK: mode_t = 24576; +pub const __S_IFREG: mode_t = 32768; +pub const __S_IFLNK: mode_t = 40960; +pub const __S_IFSOCK: mode_t = 49152; +pub const __S_IFIFO: mode_t = 4096; +pub const __S_ISUID: mode_t = 2048; +pub const __S_ISGID: mode_t = 1024; +pub const __S_ISVTX: mode_t = 512; +pub const __S_IREAD: mode_t = 256; +pub const __S_IWRITE: mode_t = 128; +pub const __S_IEXEC: mode_t = 64; +pub const S_INOCACHE: mode_t = 65536; +pub const S_IUSEUNK: mode_t = 131072; +pub const S_IUNKNOWN: mode_t = 1835008; +pub const S_IUNKSHIFT: mode_t = 12; +pub const S_IPTRANS: mode_t = 2097152; +pub const S_IATRANS: mode_t = 4194304; +pub const S_IROOT: mode_t = 8388608; +pub const S_ITRANS: mode_t = 14680064; +pub const S_IMMAP0: mode_t = 16777216; +pub const CMASK: mode_t = 18; +pub const UF_SETTABLE: ::c_uint = 65535; +pub const UF_NODUMP: ::c_uint = 1; +pub const UF_IMMUTABLE: ::c_uint = 2; +pub const UF_APPEND: ::c_uint = 4; +pub const UF_OPAQUE: ::c_uint = 8; +pub const UF_NOUNLINK: ::c_uint = 16; +pub const SF_SETTABLE: ::c_uint = 4294901760; +pub const SF_ARCHIVED: ::c_uint = 65536; +pub const SF_IMMUTABLE: ::c_uint = 131072; +pub const SF_APPEND: ::c_uint = 262144; +pub const SF_NOUNLINK: ::c_uint = 1048576; +pub const SF_SNAPSHOT: ::c_uint = 2097152; +pub const UTIME_NOW: ::c_long = -1; +pub const UTIME_OMIT: ::c_long = -2; +pub const S_IFMT: ::mode_t = 61440; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_ISUID: ::mode_t = 2048; +pub const S_ISGID: ::mode_t = 1024; +pub const S_ISVTX: ::mode_t = 512; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IRWXU: ::mode_t = 448; +pub const S_IREAD: ::mode_t = 256; +pub const S_IWRITE: ::mode_t = 128; +pub const S_IEXEC: ::mode_t = 64; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IRWXG: ::mode_t = 56; +pub const S_IROTH: ::mode_t = 4; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IXOTH: ::mode_t = 1; +pub const S_IRWXO: ::mode_t = 7; +pub const ACCESSPERMS: ::mode_t = 511; +pub const ALLPERMS: ::mode_t = 4095; +pub const DEFFILEMODE: ::mode_t = 438; +pub const S_BLKSIZE: usize = 512; +pub const STATX_TYPE: ::c_uint = 1; +pub const STATX_MODE: ::c_uint = 2; +pub const STATX_NLINK: ::c_uint = 4; +pub const STATX_UID: ::c_uint = 8; +pub const STATX_GID: ::c_uint = 16; +pub const STATX_ATIME: ::c_uint = 32; +pub const STATX_MTIME: ::c_uint = 64; +pub const STATX_CTIME: ::c_uint = 128; +pub const STATX_INO: ::c_uint = 256; +pub const STATX_SIZE: ::c_uint = 512; +pub const STATX_BLOCKS: ::c_uint = 1024; +pub const STATX_BASIC_STATS: ::c_uint = 2047; +pub const STATX_ALL: ::c_uint = 4095; +pub const STATX_BTIME: ::c_uint = 2048; +pub const STATX_MNT_ID: ::c_uint = 4096; +pub const STATX_DIOALIGN: ::c_uint = 8192; +pub const STATX__RESERVED: ::c_uint = 2147483648; +pub const STATX_ATTR_COMPRESSED: ::c_uint = 4; +pub const STATX_ATTR_IMMUTABLE: ::c_uint = 16; +pub const STATX_ATTR_APPEND: ::c_uint = 32; +pub const STATX_ATTR_NODUMP: ::c_uint = 64; +pub const STATX_ATTR_ENCRYPTED: ::c_uint = 2048; +pub const STATX_ATTR_AUTOMOUNT: ::c_uint = 4096; +pub const STATX_ATTR_MOUNT_ROOT: ::c_uint = 8192; +pub const STATX_ATTR_VERITY: ::c_uint = 1048576; +pub const STATX_ATTR_DAX: ::c_uint = 2097152; + +// sys/ioctl.h +pub const TIOCM_LE: ::c_int = 1; +pub const TIOCM_DTR: ::c_int = 2; +pub const TIOCM_RTS: ::c_int = 4; +pub const TIOCM_ST: ::c_int = 8; +pub const TIOCM_SR: ::c_int = 16; +pub const TIOCM_CTS: ::c_int = 32; +pub const TIOCM_CAR: ::c_int = 64; +pub const TIOCM_CD: ::c_int = 64; +pub const TIOCM_RNG: ::c_int = 128; +pub const TIOCM_RI: ::c_int = 128; +pub const TIOCM_DSR: ::c_int = 256; +pub const TIOCPKT_DATA: ::c_int = 0; +pub const TIOCPKT_FLUSHREAD: ::c_int = 1; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 2; +pub const TIOCPKT_STOP: ::c_int = 4; +pub const TIOCPKT_START: ::c_int = 8; +pub const TIOCPKT_NOSTOP: ::c_int = 16; +pub const TIOCPKT_DOSTOP: ::c_int = 32; +pub const TIOCPKT_IOCTL: ::c_int = 64; +pub const TTYDISC: ::c_int = 0; +pub const TABLDISC: ::c_int = 3; +pub const SLIPDISC: ::c_int = 4; +pub const TANDEM: ::tcflag_t = 1; +pub const CBREAK: ::tcflag_t = 2; +pub const LCASE: ::tcflag_t = 4; +pub const CRMOD: ::tcflag_t = 16; +pub const RAW: ::tcflag_t = 32; +pub const ODDP: ::tcflag_t = 64; +pub const EVENP: ::tcflag_t = 128; +pub const ANYP: ::tcflag_t = 192; +pub const NLDELAY: ::tcflag_t = 768; +pub const NL2: ::tcflag_t = 512; +pub const NL3: ::tcflag_t = 768; +pub const TBDELAY: ::tcflag_t = 3072; +pub const XTABS: ::tcflag_t = 3072; +pub const CRDELAY: ::tcflag_t = 12288; +pub const VTDELAY: ::tcflag_t = 16384; +pub const BSDELAY: ::tcflag_t = 32768; +pub const ALLDELAY: ::tcflag_t = 65280; +pub const CRTBS: ::tcflag_t = 65536; +pub const PRTERA: ::tcflag_t = 131072; +pub const CRTERA: ::tcflag_t = 262144; +pub const TILDE: ::tcflag_t = 524288; +pub const LITOUT: ::tcflag_t = 2097152; +pub const NOHANG: ::tcflag_t = 16777216; +pub const L001000: ::tcflag_t = 33554432; +pub const CRTKIL: ::tcflag_t = 67108864; +pub const PASS8: ::tcflag_t = 134217728; +pub const CTLECH: ::tcflag_t = 268435456; +pub const DECCTQ: ::tcflag_t = 1073741824; + +pub const FIONBIO: ::c_ulong = 0xa008007e; +pub const FIONREAD: ::c_ulong = 0x6008007f; +pub const TIOCSWINSZ: ::c_ulong = 0x90200767; +pub const TIOCGWINSZ: ::c_ulong = 0x50200768; +pub const TIOCEXCL: ::c_ulong = 0x70d; +pub const TIOCNXCL: ::c_ulong = 0x70e; +pub const TIOCSCTTY: ::c_ulong = 0x761; + +pub const FIOCLEX: ::c_ulong = 1; + +// fcntl.h +pub const O_EXEC: ::c_int = 4; +pub const O_NORW: ::c_int = 0; +pub const O_RDONLY: ::c_int = 1; +pub const O_WRONLY: ::c_int = 2; +pub const O_RDWR: ::c_int = 3; +pub const O_ACCMODE: ::c_int = 3; +pub const O_LARGEFILE: ::c_int = 0; +pub const O_CREAT: ::c_int = 16; +pub const O_EXCL: ::c_int = 32; +pub const O_NOLINK: ::c_int = 64; +pub const O_NOTRANS: ::c_int = 128; +pub const O_NOFOLLOW: ::c_int = 1048576; +pub const O_DIRECTORY: ::c_int = 2097152; +pub const O_APPEND: ::c_int = 256; +pub const O_ASYNC: ::c_int = 512; +pub const O_FSYNC: ::c_int = 1024; +pub const O_SYNC: ::c_int = 1024; +pub const O_NOATIME: ::c_int = 2048; +pub const O_SHLOCK: ::c_int = 131072; +pub const O_EXLOCK: ::c_int = 262144; +pub const O_DSYNC: ::c_int = 1024; +pub const O_RSYNC: ::c_int = 1024; +pub const O_NONBLOCK: ::c_int = 8; +pub const O_NDELAY: ::c_int = 8; +pub const O_HURD: ::c_int = 458751; +pub const O_TRUNC: ::c_int = 65536; +pub const O_CLOEXEC: ::c_int = 4194304; +pub const O_IGNORE_CTTY: ::c_int = 524288; +pub const O_TMPFILE: ::c_int = 8388608; +pub const O_NOCTTY: ::c_int = 0; +pub const FREAD: ::c_int = 1; +pub const FWRITE: ::c_int = 2; +pub const FASYNC: ::c_int = 512; +pub const FCREAT: ::c_int = 16; +pub const FEXCL: ::c_int = 32; +pub const FTRUNC: ::c_int = 65536; +pub const FNOCTTY: ::c_int = 0; +pub const FFSYNC: ::c_int = 1024; +pub const FSYNC: ::c_int = 1024; +pub const FAPPEND: ::c_int = 256; +pub const FNONBLOCK: ::c_int = 8; +pub const FNDELAY: ::c_int = 8; +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_GETLK64: ::c_int = 10; +pub const F_SETLK64: ::c_int = 11; +pub const F_SETLKW64: ::c_int = 12; +pub const F_DUPFD_CLOEXEC: ::c_int = 1030; +pub const FD_CLOEXEC: ::c_int = 1; +pub const F_RDLCK: ::c_int = 1; +pub const F_WRLCK: ::c_int = 2; +pub const F_UNLCK: ::c_int = 3; +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 256; +pub const AT_REMOVEDIR: ::c_int = 512; +pub const AT_SYMLINK_FOLLOW: ::c_int = 1024; +pub const AT_NO_AUTOMOUNT: ::c_int = 2048; +pub const AT_EMPTY_PATH: ::c_int = 4096; +pub const AT_STATX_SYNC_TYPE: ::c_int = 24576; +pub const AT_STATX_SYNC_AS_STAT: ::c_int = 0; +pub const AT_STATX_FORCE_SYNC: ::c_int = 8192; +pub const AT_STATX_DONT_SYNC: ::c_int = 16384; +pub const AT_RECURSIVE: ::c_int = 32768; +pub const AT_EACCESS: ::c_int = 512; + +// sys/uio.h +pub const RWF_HIPRI: ::c_int = 1; +pub const RWF_DSYNC: ::c_int = 2; +pub const RWF_SYNC: ::c_int = 4; +pub const RWF_NOWAIT: ::c_int = 8; +pub const RWF_APPEND: ::c_int = 16; + +// errno.h +pub const EPERM: ::c_int = 1073741825; +pub const ENOENT: ::c_int = 1073741826; +pub const ESRCH: ::c_int = 1073741827; +pub const EINTR: ::c_int = 1073741828; +pub const EIO: ::c_int = 1073741829; +pub const ENXIO: ::c_int = 1073741830; +pub const E2BIG: ::c_int = 1073741831; +pub const ENOEXEC: ::c_int = 1073741832; +pub const EBADF: ::c_int = 1073741833; +pub const ECHILD: ::c_int = 1073741834; +pub const EDEADLK: ::c_int = 1073741835; +pub const ENOMEM: ::c_int = 1073741836; +pub const EACCES: ::c_int = 1073741837; +pub const EFAULT: ::c_int = 1073741838; +pub const ENOTBLK: ::c_int = 1073741839; +pub const EBUSY: ::c_int = 1073741840; +pub const EEXIST: ::c_int = 1073741841; +pub const EXDEV: ::c_int = 1073741842; +pub const ENODEV: ::c_int = 1073741843; +pub const ENOTDIR: ::c_int = 1073741844; +pub const EISDIR: ::c_int = 1073741845; +pub const EINVAL: ::c_int = 1073741846; +pub const EMFILE: ::c_int = 1073741848; +pub const ENFILE: ::c_int = 1073741847; +pub const ENOTTY: ::c_int = 1073741849; +pub const ETXTBSY: ::c_int = 1073741850; +pub const EFBIG: ::c_int = 1073741851; +pub const ENOSPC: ::c_int = 1073741852; +pub const ESPIPE: ::c_int = 1073741853; +pub const EROFS: ::c_int = 1073741854; +pub const EMLINK: ::c_int = 1073741855; +pub const EPIPE: ::c_int = 1073741856; +pub const EDOM: ::c_int = 1073741857; +pub const ERANGE: ::c_int = 1073741858; +pub const EAGAIN: ::c_int = 1073741859; +pub const EWOULDBLOCK: ::c_int = 1073741859; +pub const EINPROGRESS: ::c_int = 1073741860; +pub const EALREADY: ::c_int = 1073741861; +pub const ENOTSOCK: ::c_int = 1073741862; +pub const EMSGSIZE: ::c_int = 1073741864; +pub const EPROTOTYPE: ::c_int = 1073741865; +pub const ENOPROTOOPT: ::c_int = 1073741866; +pub const EPROTONOSUPPORT: ::c_int = 1073741867; +pub const ESOCKTNOSUPPORT: ::c_int = 1073741868; +pub const EOPNOTSUPP: ::c_int = 1073741869; +pub const EPFNOSUPPORT: ::c_int = 1073741870; +pub const EAFNOSUPPORT: ::c_int = 1073741871; +pub const EADDRINUSE: ::c_int = 1073741872; +pub const EADDRNOTAVAIL: ::c_int = 1073741873; +pub const ENETDOWN: ::c_int = 1073741874; +pub const ENETUNREACH: ::c_int = 1073741875; +pub const ENETRESET: ::c_int = 1073741876; +pub const ECONNABORTED: ::c_int = 1073741877; +pub const ECONNRESET: ::c_int = 1073741878; +pub const ENOBUFS: ::c_int = 1073741879; +pub const EISCONN: ::c_int = 1073741880; +pub const ENOTCONN: ::c_int = 1073741881; +pub const EDESTADDRREQ: ::c_int = 1073741863; +pub const ESHUTDOWN: ::c_int = 1073741882; +pub const ETOOMANYREFS: ::c_int = 1073741883; +pub const ETIMEDOUT: ::c_int = 1073741884; +pub const ECONNREFUSED: ::c_int = 1073741885; +pub const ELOOP: ::c_int = 1073741886; +pub const ENAMETOOLONG: ::c_int = 1073741887; +pub const EHOSTDOWN: ::c_int = 1073741888; +pub const EHOSTUNREACH: ::c_int = 1073741889; +pub const ENOTEMPTY: ::c_int = 1073741890; +pub const EPROCLIM: ::c_int = 1073741891; +pub const EUSERS: ::c_int = 1073741892; +pub const EDQUOT: ::c_int = 1073741893; +pub const ESTALE: ::c_int = 1073741894; +pub const EREMOTE: ::c_int = 1073741895; +pub const EBADRPC: ::c_int = 1073741896; +pub const ERPCMISMATCH: ::c_int = 1073741897; +pub const EPROGUNAVAIL: ::c_int = 1073741898; +pub const EPROGMISMATCH: ::c_int = 1073741899; +pub const EPROCUNAVAIL: ::c_int = 1073741900; +pub const ENOLCK: ::c_int = 1073741901; +pub const EFTYPE: ::c_int = 1073741903; +pub const EAUTH: ::c_int = 1073741904; +pub const ENEEDAUTH: ::c_int = 1073741905; +pub const ENOSYS: ::c_int = 1073741902; +pub const ELIBEXEC: ::c_int = 1073741907; +pub const ENOTSUP: ::c_int = 1073741942; +pub const EILSEQ: ::c_int = 1073741930; +pub const EBACKGROUND: ::c_int = 1073741924; +pub const EDIED: ::c_int = 1073741925; +pub const EGREGIOUS: ::c_int = 1073741927; +pub const EIEIO: ::c_int = 1073741928; +pub const EGRATUITOUS: ::c_int = 1073741929; +pub const EBADMSG: ::c_int = 1073741931; +pub const EIDRM: ::c_int = 1073741932; +pub const EMULTIHOP: ::c_int = 1073741933; +pub const ENODATA: ::c_int = 1073741934; +pub const ENOLINK: ::c_int = 1073741935; +pub const ENOMSG: ::c_int = 1073741936; +pub const ENOSR: ::c_int = 1073741937; +pub const ENOSTR: ::c_int = 1073741938; +pub const EOVERFLOW: ::c_int = 1073741939; +pub const EPROTO: ::c_int = 1073741940; +pub const ETIME: ::c_int = 1073741941; +pub const ECANCELED: ::c_int = 1073741943; +pub const EOWNERDEAD: ::c_int = 1073741944; +pub const ENOTRECOVERABLE: ::c_int = 1073741945; +pub const EMACH_SEND_IN_PROGRESS: ::c_int = 268435457; +pub const EMACH_SEND_INVALID_DATA: ::c_int = 268435458; +pub const EMACH_SEND_INVALID_DEST: ::c_int = 268435459; +pub const EMACH_SEND_TIMED_OUT: ::c_int = 268435460; +pub const EMACH_SEND_WILL_NOTIFY: ::c_int = 268435461; +pub const EMACH_SEND_NOTIFY_IN_PROGRESS: ::c_int = 268435462; +pub const EMACH_SEND_INTERRUPTED: ::c_int = 268435463; +pub const EMACH_SEND_MSG_TOO_SMALL: ::c_int = 268435464; +pub const EMACH_SEND_INVALID_REPLY: ::c_int = 268435465; +pub const EMACH_SEND_INVALID_RIGHT: ::c_int = 268435466; +pub const EMACH_SEND_INVALID_NOTIFY: ::c_int = 268435467; +pub const EMACH_SEND_INVALID_MEMORY: ::c_int = 268435468; +pub const EMACH_SEND_NO_BUFFER: ::c_int = 268435469; +pub const EMACH_SEND_NO_NOTIFY: ::c_int = 268435470; +pub const EMACH_SEND_INVALID_TYPE: ::c_int = 268435471; +pub const EMACH_SEND_INVALID_HEADER: ::c_int = 268435472; +pub const EMACH_RCV_IN_PROGRESS: ::c_int = 268451841; +pub const EMACH_RCV_INVALID_NAME: ::c_int = 268451842; +pub const EMACH_RCV_TIMED_OUT: ::c_int = 268451843; +pub const EMACH_RCV_TOO_LARGE: ::c_int = 268451844; +pub const EMACH_RCV_INTERRUPTED: ::c_int = 268451845; +pub const EMACH_RCV_PORT_CHANGED: ::c_int = 268451846; +pub const EMACH_RCV_INVALID_NOTIFY: ::c_int = 268451847; +pub const EMACH_RCV_INVALID_DATA: ::c_int = 268451848; +pub const EMACH_RCV_PORT_DIED: ::c_int = 268451849; +pub const EMACH_RCV_IN_SET: ::c_int = 268451850; +pub const EMACH_RCV_HEADER_ERROR: ::c_int = 268451851; +pub const EMACH_RCV_BODY_ERROR: ::c_int = 268451852; +pub const EKERN_INVALID_ADDRESS: ::c_int = 1; +pub const EKERN_PROTECTION_FAILURE: ::c_int = 2; +pub const EKERN_NO_SPACE: ::c_int = 3; +pub const EKERN_INVALID_ARGUMENT: ::c_int = 4; +pub const EKERN_FAILURE: ::c_int = 5; +pub const EKERN_RESOURCE_SHORTAGE: ::c_int = 6; +pub const EKERN_NOT_RECEIVER: ::c_int = 7; +pub const EKERN_NO_ACCESS: ::c_int = 8; +pub const EKERN_MEMORY_FAILURE: ::c_int = 9; +pub const EKERN_MEMORY_ERROR: ::c_int = 10; +pub const EKERN_NOT_IN_SET: ::c_int = 12; +pub const EKERN_NAME_EXISTS: ::c_int = 13; +pub const EKERN_ABORTED: ::c_int = 14; +pub const EKERN_INVALID_NAME: ::c_int = 15; +pub const EKERN_INVALID_TASK: ::c_int = 16; +pub const EKERN_INVALID_RIGHT: ::c_int = 17; +pub const EKERN_INVALID_VALUE: ::c_int = 18; +pub const EKERN_UREFS_OVERFLOW: ::c_int = 19; +pub const EKERN_INVALID_CAPABILITY: ::c_int = 20; +pub const EKERN_RIGHT_EXISTS: ::c_int = 21; +pub const EKERN_INVALID_HOST: ::c_int = 22; +pub const EKERN_MEMORY_PRESENT: ::c_int = 23; +pub const EKERN_WRITE_PROTECTION_FAILURE: ::c_int = 24; +pub const EKERN_TERMINATED: ::c_int = 26; +pub const EKERN_TIMEDOUT: ::c_int = 27; +pub const EKERN_INTERRUPTED: ::c_int = 28; +pub const EMIG_TYPE_ERROR: ::c_int = -300; +pub const EMIG_REPLY_MISMATCH: ::c_int = -301; +pub const EMIG_REMOTE_ERROR: ::c_int = -302; +pub const EMIG_BAD_ID: ::c_int = -303; +pub const EMIG_BAD_ARGUMENTS: ::c_int = -304; +pub const EMIG_NO_REPLY: ::c_int = -305; +pub const EMIG_EXCEPTION: ::c_int = -306; +pub const EMIG_ARRAY_TOO_LARGE: ::c_int = -307; +pub const EMIG_SERVER_DIED: ::c_int = -308; +pub const EMIG_DESTROY_REQUEST: ::c_int = -309; +pub const ED_IO_ERROR: ::c_int = 2500; +pub const ED_WOULD_BLOCK: ::c_int = 2501; +pub const ED_NO_SUCH_DEVICE: ::c_int = 2502; +pub const ED_ALREADY_OPEN: ::c_int = 2503; +pub const ED_DEVICE_DOWN: ::c_int = 2504; +pub const ED_INVALID_OPERATION: ::c_int = 2505; +pub const ED_INVALID_RECNUM: ::c_int = 2506; +pub const ED_INVALID_SIZE: ::c_int = 2507; +pub const ED_NO_MEMORY: ::c_int = 2508; +pub const ED_READ_ONLY: ::c_int = 2509; +pub const _HURD_ERRNOS: usize = 122; + +// sched.h +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const _BITS_TYPES_STRUCT_SCHED_PARAM: usize = 1; +pub const __CPU_SETSIZE: usize = 1024; +pub const CPU_SETSIZE: usize = 1024; + +// pthread.h +pub const PTHREAD_SPINLOCK_INITIALIZER: ::c_int = 0; +pub const PTHREAD_CANCEL_DISABLE: ::c_int = 0; +pub const PTHREAD_CANCEL_ENABLE: ::c_int = 1; +pub const PTHREAD_CANCEL_DEFERRED: ::c_int = 0; +pub const PTHREAD_CANCEL_ASYNCHRONOUS: ::c_int = 1; +pub const PTHREAD_BARRIER_SERIAL_THREAD: ::c_int = -1; + +// netinet/tcp.h +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; +pub const TCP_CORK: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_SYNCNT: ::c_int = 7; +pub const TCP_LINGER2: ::c_int = 8; +pub const TCP_DEFER_ACCEPT: ::c_int = 9; +pub const TCP_WINDOW_CLAMP: ::c_int = 10; +pub const TCP_INFO: ::c_int = 11; +pub const TCP_QUICKACK: ::c_int = 12; +pub const TCP_CONGESTION: ::c_int = 13; +pub const TCP_MD5SIG: ::c_int = 14; +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; +pub const TCP_NOTSENT_LOWAT: ::c_int = 25; +pub const TCP_CC_INFO: ::c_int = 26; +pub const TCP_SAVE_SYN: ::c_int = 27; +pub const TCP_SAVED_SYN: ::c_int = 28; +pub const TCP_REPAIR_WINDOW: ::c_int = 29; +pub const TCP_FASTOPEN_CONNECT: ::c_int = 30; +pub const TCP_ULP: ::c_int = 31; +pub const TCP_MD5SIG_EXT: ::c_int = 32; +pub const TCP_FASTOPEN_KEY: ::c_int = 33; +pub const TCP_FASTOPEN_NO_COOKIE: ::c_int = 34; +pub const TCP_ZEROCOPY_RECEIVE: ::c_int = 35; +pub const TCP_INQ: ::c_int = 36; +pub const TCP_CM_INQ: ::c_int = 36; +pub const TCP_TX_DELAY: ::c_int = 37; +pub const TCP_REPAIR_ON: ::c_int = 1; +pub const TCP_REPAIR_OFF: ::c_int = 0; +pub const TCP_REPAIR_OFF_NO_WP: ::c_int = -1; + +// stdint.h +pub const INT8_MIN: i8 = -128; +pub const INT16_MIN: i16 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: i8 = 127; +pub const INT16_MAX: i16 = 32767; +pub const INT32_MAX: i32 = 2147483647; +pub const UINT8_MAX: u8 = 255; +pub const UINT16_MAX: u16 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: int_least8_t = -128; +pub const INT_LEAST16_MIN: int_least16_t = -32768; +pub const INT_LEAST32_MIN: int_least32_t = -2147483648; +pub const INT_LEAST8_MAX: int_least8_t = 127; +pub const INT_LEAST16_MAX: int_least16_t = 32767; +pub const INT_LEAST32_MAX: int_least32_t = 2147483647; +pub const UINT_LEAST8_MAX: uint_least8_t = 255; +pub const UINT_LEAST16_MAX: uint_least16_t = 65535; +pub const UINT_LEAST32_MAX: uint_least32_t = 4294967295; +pub const INT_FAST8_MIN: int_fast8_t = -128; +pub const INT_FAST16_MIN: int_fast16_t = -2147483648; +pub const INT_FAST32_MIN: int_fast32_t = -2147483648; +pub const INT_FAST8_MAX: int_fast8_t = 127; +pub const INT_FAST16_MAX: int_fast16_t = 2147483647; +pub const INT_FAST32_MAX: int_fast32_t = 2147483647; +pub const UINT_FAST8_MAX: uint_fast8_t = 255; +pub const UINT_FAST16_MAX: uint_fast16_t = 4294967295; +pub const UINT_FAST32_MAX: uint_fast32_t = 4294967295; +pub const INTPTR_MIN: __intptr_t = -2147483648; +pub const INTPTR_MAX: __intptr_t = 2147483647; +pub const UINTPTR_MAX: usize = 4294967295; +pub const PTRDIFF_MIN: __ptrdiff_t = -2147483648; +pub const PTRDIFF_MAX: __ptrdiff_t = 2147483647; +pub const SIG_ATOMIC_MIN: __sig_atomic_t = -2147483648; +pub const SIG_ATOMIC_MAX: __sig_atomic_t = 2147483647; +pub const SIZE_MAX: usize = 4294967295; +pub const WINT_MIN: wint_t = 0; +pub const WINT_MAX: wint_t = 4294967295; +pub const INT8_WIDTH: usize = 8; +pub const UINT8_WIDTH: usize = 8; +pub const INT16_WIDTH: usize = 16; +pub const UINT16_WIDTH: usize = 16; +pub const INT32_WIDTH: usize = 32; +pub const UINT32_WIDTH: usize = 32; +pub const INT64_WIDTH: usize = 64; +pub const UINT64_WIDTH: usize = 64; +pub const INT_LEAST8_WIDTH: usize = 8; +pub const UINT_LEAST8_WIDTH: usize = 8; +pub const INT_LEAST16_WIDTH: usize = 16; +pub const UINT_LEAST16_WIDTH: usize = 16; +pub const INT_LEAST32_WIDTH: usize = 32; +pub const UINT_LEAST32_WIDTH: usize = 32; +pub const INT_LEAST64_WIDTH: usize = 64; +pub const UINT_LEAST64_WIDTH: usize = 64; +pub const INT_FAST8_WIDTH: usize = 8; +pub const UINT_FAST8_WIDTH: usize = 8; +pub const INT_FAST16_WIDTH: usize = 32; +pub const UINT_FAST16_WIDTH: usize = 32; +pub const INT_FAST32_WIDTH: usize = 32; +pub const UINT_FAST32_WIDTH: usize = 32; +pub const INT_FAST64_WIDTH: usize = 64; +pub const UINT_FAST64_WIDTH: usize = 64; +pub const INTPTR_WIDTH: usize = 32; +pub const UINTPTR_WIDTH: usize = 32; +pub const INTMAX_WIDTH: usize = 64; +pub const UINTMAX_WIDTH: usize = 64; +pub const PTRDIFF_WIDTH: usize = 32; +pub const SIG_ATOMIC_WIDTH: usize = 32; +pub const SIZE_WIDTH: usize = 32; +pub const WCHAR_WIDTH: usize = 32; +pub const WINT_WIDTH: usize = 32; + +pub const TH_FIN: u8 = 1; +pub const TH_SYN: u8 = 2; +pub const TH_RST: u8 = 4; +pub const TH_PUSH: u8 = 8; +pub const TH_ACK: u8 = 16; +pub const TH_URG: u8 = 32; +pub const TCPOPT_EOL: u8 = 0; +pub const TCPOPT_NOP: u8 = 1; +pub const TCPOPT_MAXSEG: u8 = 2; +pub const TCPOLEN_MAXSEG: u8 = 4; +pub const TCPOPT_WINDOW: u8 = 3; +pub const TCPOLEN_WINDOW: u8 = 3; +pub const TCPOPT_SACK_PERMITTED: u8 = 4; +pub const TCPOLEN_SACK_PERMITTED: u8 = 2; +pub const TCPOPT_SACK: u8 = 5; +pub const TCPOPT_TIMESTAMP: u8 = 8; +pub const TCPOLEN_TIMESTAMP: u8 = 10; +pub const TCPOLEN_TSTAMP_APPA: u8 = 12; +pub const TCPOPT_TSTAMP_HDR: u32 = 16844810; +pub const TCP_MSS: usize = 512; +pub const TCP_MAXWIN: usize = 65535; +pub const TCP_MAX_WINSHIFT: usize = 14; +pub const TCPI_OPT_TIMESTAMPS: u8 = 1; +pub const TCPI_OPT_SACK: u8 = 2; +pub const TCPI_OPT_WSCALE: u8 = 4; +pub const TCPI_OPT_ECN: u8 = 8; +pub const TCPI_OPT_ECN_SEEN: u8 = 16; +pub const TCPI_OPT_SYN_DATA: u8 = 32; +pub const TCP_MD5SIG_MAXKEYLEN: usize = 80; +pub const TCP_MD5SIG_FLAG_PREFIX: usize = 1; +pub const TCP_COOKIE_MIN: usize = 8; +pub const TCP_COOKIE_MAX: usize = 16; +pub const TCP_COOKIE_PAIR_SIZE: usize = 32; +pub const TCP_COOKIE_IN_ALWAYS: ::c_int = 1; +pub const TCP_COOKIE_OUT_NEVER: ::c_int = 2; +pub const TCP_S_DATA_IN: ::c_int = 4; +pub const TCP_S_DATA_OUT: ::c_int = 8; +pub const TCP_MSS_DEFAULT: usize = 536; +pub const TCP_MSS_DESIRED: usize = 1220; + +// sys/wait.h +pub const WCOREFLAG: ::c_int = 128; +pub const WAIT_ANY: pid_t = -1; +pub const WAIT_MYPGRP: pid_t = 0; + +// sys/file.h +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_UN: ::c_int = 8; +pub const LOCK_NB: ::c_int = 4; + +// sys/mman.h +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 4; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 1; +pub const MAP_FILE: ::c_int = 1; +pub const MAP_ANON: ::c_int = 2; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; +pub const MAP_TYPE: ::c_int = 15; +pub const MAP_COPY: ::c_int = 32; +pub const MAP_SHARED: ::c_int = 16; +pub const MAP_PRIVATE: ::c_int = 0; +pub const MAP_FIXED: ::c_int = 256; +pub const MAP_NOEXTEND: ::c_int = 512; +pub const MAP_HASSEMPHORE: ::c_int = 1024; +pub const MAP_INHERIT: ::c_int = 2048; +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_MADV_WONTNEED: ::c_int = 4; + +pub const MS_ASYNC: ::c_int = 1; +pub const MS_SYNC: ::c_int = 0; +pub const MS_INVALIDATE: ::c_int = 2; +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +// spawn.h +pub const POSIX_SPAWN_USEVFORK: ::c_int = 64; +pub const POSIX_SPAWN_SETSID: ::c_int = 128; + +// sys/syslog.h +pub const LOG_CRON: ::c_int = 9 << 3; +pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +pub const LOG_FTP: ::c_int = 11 << 3; +pub const LOG_PERROR: ::c_int = 0x20; + +// net/if.h +pub const IFF_UP: ::c_int = 0x1; +pub const IFF_BROADCAST: ::c_int = 0x2; +pub const IFF_DEBUG: ::c_int = 0x4; +pub const IFF_LOOPBACK: ::c_int = 0x8; +pub const IFF_POINTOPOINT: ::c_int = 0x10; +pub const IFF_NOTRAILERS: ::c_int = 0x20; +pub const IFF_RUNNING: ::c_int = 0x40; +pub const IFF_NOARP: ::c_int = 0x80; +pub const IFF_PROMISC: ::c_int = 0x100; +pub const IFF_ALLMULTI: ::c_int = 0x200; +pub const IFF_MASTER: ::c_int = 0x400; +pub const IFF_SLAVE: ::c_int = 0x800; +pub const IFF_MULTICAST: ::c_int = 0x1000; +pub const IFF_PORTSEL: ::c_int = 0x2000; +pub const IFF_AUTOMEDIA: ::c_int = 0x4000; +pub const IFF_DYNAMIC: ::c_int = 0x8000; + +// random.h +pub const GRND_NONBLOCK: ::c_uint = 1; +pub const GRND_RANDOM: ::c_uint = 2; +pub const GRND_INSECURE: ::c_uint = 4; + +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = 30; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_PII: ::c_int = 53; +pub const _SC_PII_XTI: ::c_int = 54; +pub const _SC_PII_SOCKET: ::c_int = 55; +pub const _SC_PII_INTERNET: ::c_int = 56; +pub const _SC_PII_OSI: ::c_int = 57; +pub const _SC_POLL: ::c_int = 58; +pub const _SC_SELECT: ::c_int = 59; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_PII_INTERNET_STREAM: ::c_int = 61; +pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62; +pub const _SC_PII_OSI_COTS: ::c_int = 63; +pub const _SC_PII_OSI_CLTS: ::c_int = 64; +pub const _SC_PII_OSI_M: ::c_int = 65; +pub const _SC_T_IOV_MAX: ::c_int = 66; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_C_VERSION: ::c_int = 96; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_CHAR_BIT: ::c_int = 101; +pub const _SC_CHAR_MAX: ::c_int = 102; +pub const _SC_CHAR_MIN: ::c_int = 103; +pub const _SC_INT_MAX: ::c_int = 104; +pub const _SC_INT_MIN: ::c_int = 105; +pub const _SC_LONG_BIT: ::c_int = 106; +pub const _SC_WORD_BIT: ::c_int = 107; +pub const _SC_MB_LEN_MAX: ::c_int = 108; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_SSIZE_MAX: ::c_int = 110; +pub const _SC_SCHAR_MAX: ::c_int = 111; +pub const _SC_SCHAR_MIN: ::c_int = 112; +pub const _SC_SHRT_MAX: ::c_int = 113; +pub const _SC_SHRT_MIN: ::c_int = 114; +pub const _SC_UCHAR_MAX: ::c_int = 115; +pub const _SC_UINT_MAX: ::c_int = 116; +pub const _SC_ULONG_MAX: ::c_int = 117; +pub const _SC_USHRT_MAX: ::c_int = 118; +pub const _SC_NL_ARGMAX: ::c_int = 119; +pub const _SC_NL_LANGMAX: ::c_int = 120; +pub const _SC_NL_MSGMAX: ::c_int = 121; +pub const _SC_NL_NMAX: ::c_int = 122; +pub const _SC_NL_SETMAX: ::c_int = 123; +pub const _SC_NL_TEXTMAX: ::c_int = 124; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_BASE: ::c_int = 134; +pub const _SC_C_LANG_SUPPORT: ::c_int = 135; +pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_DEVICE_IO: ::c_int = 140; +pub const _SC_DEVICE_SPECIFIC: ::c_int = 141; +pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142; +pub const _SC_FD_MGMT: ::c_int = 143; +pub const _SC_FIFO: ::c_int = 144; +pub const _SC_PIPE: ::c_int = 145; +pub const _SC_FILE_ATTRIBUTES: ::c_int = 146; +pub const _SC_FILE_LOCKING: ::c_int = 147; +pub const _SC_FILE_SYSTEM: ::c_int = 148; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_MULTI_PROCESS: ::c_int = 150; +pub const _SC_SINGLE_PROCESS: ::c_int = 151; +pub const _SC_NETWORKING: ::c_int = 152; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_REGEX_VERSION: ::c_int = 156; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SIGNALS: ::c_int = 158; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_SYSTEM_DATABASE: ::c_int = 162; +pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_USER_GROUPS: ::c_int = 166; +pub const _SC_USER_GROUPS_R: ::c_int = 167; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185; +pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186; +pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187; +pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188; +pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189; +pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190; +pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191; +pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192; +pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193; +pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194; +pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195; +pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196; +pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197; +pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198; +pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; +pub const _SC_MINSIGSTKSZ: ::c_int = 249; +pub const _SC_SIGSTKSZ: ::c_int = 250; + +pub const _CS_PATH: ::c_int = 0; +pub const _CS_V6_WIDTH_RESTRICTED_ENVS: ::c_int = 1; +pub const _CS_GNU_LIBC_VERSION: ::c_int = 2; +pub const _CS_GNU_LIBPTHREAD_VERSION: ::c_int = 3; +pub const _CS_V5_WIDTH_RESTRICTED_ENVS: ::c_int = 4; +pub const _CS_V7_WIDTH_RESTRICTED_ENVS: ::c_int = 5; +pub const _CS_LFS_CFLAGS: ::c_int = 1000; +pub const _CS_LFS_LDFLAGS: ::c_int = 1001; +pub const _CS_LFS_LIBS: ::c_int = 1002; +pub const _CS_LFS_LINTFLAGS: ::c_int = 1003; +pub const _CS_LFS64_CFLAGS: ::c_int = 1004; +pub const _CS_LFS64_LDFLAGS: ::c_int = 1005; +pub const _CS_LFS64_LIBS: ::c_int = 1006; +pub const _CS_LFS64_LINTFLAGS: ::c_int = 1007; +pub const _CS_XBS5_ILP32_OFF32_CFLAGS: ::c_int = 1100; +pub const _CS_XBS5_ILP32_OFF32_LDFLAGS: ::c_int = 1101; +pub const _CS_XBS5_ILP32_OFF32_LIBS: ::c_int = 1102; +pub const _CS_XBS5_ILP32_OFF32_LINTFLAGS: ::c_int = 1103; +pub const _CS_XBS5_ILP32_OFFBIG_CFLAGS: ::c_int = 1104; +pub const _CS_XBS5_ILP32_OFFBIG_LDFLAGS: ::c_int = 1105; +pub const _CS_XBS5_ILP32_OFFBIG_LIBS: ::c_int = 1106; +pub const _CS_XBS5_ILP32_OFFBIG_LINTFLAGS: ::c_int = 1107; +pub const _CS_XBS5_LP64_OFF64_CFLAGS: ::c_int = 1108; +pub const _CS_XBS5_LP64_OFF64_LDFLAGS: ::c_int = 1109; +pub const _CS_XBS5_LP64_OFF64_LIBS: ::c_int = 1110; +pub const _CS_XBS5_LP64_OFF64_LINTFLAGS: ::c_int = 1111; +pub const _CS_XBS5_LPBIG_OFFBIG_CFLAGS: ::c_int = 1112; +pub const _CS_XBS5_LPBIG_OFFBIG_LDFLAGS: ::c_int = 1113; +pub const _CS_XBS5_LPBIG_OFFBIG_LIBS: ::c_int = 1114; +pub const _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS: ::c_int = 1115; +pub const _CS_POSIX_V6_ILP32_OFF32_CFLAGS: ::c_int = 1116; +pub const _CS_POSIX_V6_ILP32_OFF32_LDFLAGS: ::c_int = 1117; +pub const _CS_POSIX_V6_ILP32_OFF32_LIBS: ::c_int = 1118; +pub const _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS: ::c_int = 1119; +pub const _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS: ::c_int = 1120; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS: ::c_int = 1121; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LIBS: ::c_int = 1122; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS: ::c_int = 1123; +pub const _CS_POSIX_V6_LP64_OFF64_CFLAGS: ::c_int = 1124; +pub const _CS_POSIX_V6_LP64_OFF64_LDFLAGS: ::c_int = 1125; +pub const _CS_POSIX_V6_LP64_OFF64_LIBS: ::c_int = 1126; +pub const _CS_POSIX_V6_LP64_OFF64_LINTFLAGS: ::c_int = 1127; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS: ::c_int = 1128; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS: ::c_int = 1129; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LIBS: ::c_int = 1130; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS: ::c_int = 1131; +pub const _CS_POSIX_V7_ILP32_OFF32_CFLAGS: ::c_int = 1132; +pub const _CS_POSIX_V7_ILP32_OFF32_LDFLAGS: ::c_int = 1133; +pub const _CS_POSIX_V7_ILP32_OFF32_LIBS: ::c_int = 1134; +pub const _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS: ::c_int = 1135; +pub const _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS: ::c_int = 1136; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS: ::c_int = 1137; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LIBS: ::c_int = 1138; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS: ::c_int = 1139; +pub const _CS_POSIX_V7_LP64_OFF64_CFLAGS: ::c_int = 1140; +pub const _CS_POSIX_V7_LP64_OFF64_LDFLAGS: ::c_int = 1141; +pub const _CS_POSIX_V7_LP64_OFF64_LIBS: ::c_int = 1142; +pub const _CS_POSIX_V7_LP64_OFF64_LINTFLAGS: ::c_int = 1143; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS: ::c_int = 1144; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS: ::c_int = 1145; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LIBS: ::c_int = 1146; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS: ::c_int = 1147; +pub const _CS_V6_ENV: ::c_int = 1148; +pub const _CS_V7_ENV: ::c_int = 1149; + +pub const PTHREAD_PROCESS_PRIVATE: __pthread_process_shared = 0; +pub const PTHREAD_PROCESS_SHARED: __pthread_process_shared = 1; + +pub const PTHREAD_EXPLICIT_SCHED: __pthread_inheritsched = 0; +pub const PTHREAD_INHERIT_SCHED: __pthread_inheritsched = 1; + +pub const PTHREAD_SCOPE_SYSTEM: __pthread_contentionscope = 0; +pub const PTHREAD_SCOPE_PROCESS: __pthread_contentionscope = 1; + +pub const PTHREAD_CREATE_JOINABLE: __pthread_detachstate = 0; +pub const PTHREAD_CREATE_DETACHED: __pthread_detachstate = 1; + +pub const PTHREAD_PRIO_NONE: __pthread_mutex_protocol = 0; +pub const PTHREAD_PRIO_INHERIT: __pthread_mutex_protocol = 1; +pub const PTHREAD_PRIO_PROTECT: __pthread_mutex_protocol = 2; + +pub const PTHREAD_MUTEX_TIMED: __pthread_mutex_type = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: __pthread_mutex_type = 1; +pub const PTHREAD_MUTEX_RECURSIVE: __pthread_mutex_type = 2; + +pub const PTHREAD_MUTEX_STALLED: __pthread_mutex_robustness = 0; +pub const PTHREAD_MUTEX_ROBUST: __pthread_mutex_robustness = 256; + +pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; +pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; +pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; +pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; +pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; +pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 6; +pub const RLIMIT_NPROC: ::__rlimit_resource_t = 7; +pub const RLIMIT_OFILE: ::__rlimit_resource_t = 8; +pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 8; +pub const RLIMIT_SBSIZE: ::__rlimit_resource_t = 9; +pub const RLIMIT_AS: ::__rlimit_resource_t = 10; +pub const RLIMIT_VMEM: ::__rlimit_resource_t = 10; +pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = 11; +pub const RLIM_NLIMITS: ::__rlimit_resource_t = 11; + +pub const RUSAGE_SELF: __rusage_who = 0; +pub const RUSAGE_CHILDREN: __rusage_who = -1; + +pub const PRIO_PROCESS: __priority_which = 0; +pub const PRIO_PGRP: __priority_which = 1; +pub const PRIO_USER: __priority_which = 2; + +pub const __UT_LINESIZE: usize = 32; +pub const __UT_NAMESIZE: usize = 32; +pub const __UT_HOSTSIZE: usize = 256; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_CLOEXEC: ::c_int = 4194304; +pub const SOCK_NONBLOCK: ::c_int = 2048; + +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTROUTE: ::c_int = 4; +pub const MSG_EOR: ::c_int = 8; +pub const MSG_TRUNC: ::c_int = 16; +pub const MSG_CTRUNC: ::c_int = 32; +pub const MSG_WAITALL: ::c_int = 64; +pub const MSG_DONTWAIT: ::c_int = 128; +pub const MSG_NOSIGNAL: ::c_int = 1024; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x40000000; + +pub const SCM_RIGHTS: ::c_int = 1; +pub const SCM_TIMESTAMP: ::c_int = 2; +pub const SCM_CREDS: ::c_int = 3; + +pub const SO_DEBUG: ::c_int = 1; +pub const SO_ACCEPTCONN: ::c_int = 2; +pub const SO_REUSEADDR: ::c_int = 4; +pub const SO_KEEPALIVE: ::c_int = 8; +pub const SO_DONTROUTE: ::c_int = 16; +pub const SO_BROADCAST: ::c_int = 32; +pub const SO_USELOOPBACK: ::c_int = 64; +pub const SO_LINGER: ::c_int = 128; +pub const SO_OOBINLINE: ::c_int = 256; +pub const SO_REUSEPORT: ::c_int = 512; +pub const SO_SNDBUF: ::c_int = 4097; +pub const SO_RCVBUF: ::c_int = 4098; +pub const SO_SNDLOWAT: ::c_int = 4099; +pub const SO_RCVLOWAT: ::c_int = 4100; +pub const SO_SNDTIMEO: ::c_int = 4101; +pub const SO_RCVTIMEO: ::c_int = 4102; +pub const SO_ERROR: ::c_int = 4103; +pub const SO_STYLE: ::c_int = 4104; +pub const SO_TYPE: ::c_int = 4104; + +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_ICMP: ::c_int = 1; +pub const IPPROTO_IGMP: ::c_int = 2; +pub const IPPROTO_IPIP: ::c_int = 4; +pub const IPPROTO_TCP: ::c_int = 6; +pub const IPPROTO_EGP: ::c_int = 8; +pub const IPPROTO_PUP: ::c_int = 12; +pub const IPPROTO_UDP: ::c_int = 17; +pub const IPPROTO_IDP: ::c_int = 22; +pub const IPPROTO_TP: ::c_int = 29; +pub const IPPROTO_DCCP: ::c_int = 33; +pub const IPPROTO_IPV6: ::c_int = 41; +pub const IPPROTO_RSVP: ::c_int = 46; +pub const IPPROTO_GRE: ::c_int = 47; +pub const IPPROTO_ESP: ::c_int = 50; +pub const IPPROTO_AH: ::c_int = 51; +pub const IPPROTO_MTP: ::c_int = 92; +pub const IPPROTO_BEETPH: ::c_int = 94; +pub const IPPROTO_ENCAP: ::c_int = 98; +pub const IPPROTO_PIM: ::c_int = 103; +pub const IPPROTO_COMP: ::c_int = 108; +pub const IPPROTO_L2TP: ::c_int = 115; +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_UDPLITE: ::c_int = 136; +pub const IPPROTO_MPLS: ::c_int = 137; +pub const IPPROTO_ETHERNET: ::c_int = 143; +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MPTCP: ::c_int = 262; +pub const IPPROTO_MAX: ::c_int = 263; + +pub const IPPROTO_HOPOPTS: ::c_int = 0; +pub const IPPROTO_ROUTING: ::c_int = 43; +pub const IPPROTO_FRAGMENT: ::c_int = 44; +pub const IPPROTO_ICMPV6: ::c_int = 58; +pub const IPPROTO_NONE: ::c_int = 59; +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_MH: ::c_int = 135; + +pub const IPPORT_ECHO: in_port_t = 7; +pub const IPPORT_DISCARD: in_port_t = 9; +pub const IPPORT_SYSTAT: in_port_t = 11; +pub const IPPORT_DAYTIME: in_port_t = 13; +pub const IPPORT_NETSTAT: in_port_t = 15; +pub const IPPORT_FTP: in_port_t = 21; +pub const IPPORT_TELNET: in_port_t = 23; +pub const IPPORT_SMTP: in_port_t = 25; +pub const IPPORT_TIMESERVER: in_port_t = 37; +pub const IPPORT_NAMESERVER: in_port_t = 42; +pub const IPPORT_WHOIS: in_port_t = 43; +pub const IPPORT_MTP: in_port_t = 57; +pub const IPPORT_TFTP: in_port_t = 69; +pub const IPPORT_RJE: in_port_t = 77; +pub const IPPORT_FINGER: in_port_t = 79; +pub const IPPORT_TTYLINK: in_port_t = 87; +pub const IPPORT_SUPDUP: in_port_t = 95; +pub const IPPORT_EXECSERVER: in_port_t = 512; +pub const IPPORT_LOGINSERVER: in_port_t = 513; +pub const IPPORT_CMDSERVER: in_port_t = 514; +pub const IPPORT_EFSSERVER: in_port_t = 520; +pub const IPPORT_BIFFUDP: in_port_t = 512; +pub const IPPORT_WHOSERVER: in_port_t = 513; +pub const IPPORT_ROUTESERVER: in_port_t = 520; +pub const IPPORT_USERRESERVED: in_port_t = 5000; + +pub const DT_UNKNOWN: ::c_uchar = 0; +pub const DT_FIFO: ::c_uchar = 1; +pub const DT_CHR: ::c_uchar = 2; +pub const DT_DIR: ::c_uchar = 4; +pub const DT_BLK: ::c_uchar = 6; +pub const DT_REG: ::c_uchar = 8; +pub const DT_LNK: ::c_uchar = 10; +pub const DT_SOCK: ::c_uchar = 12; +pub const DT_WHT: ::c_uchar = 14; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_NOATIME: ::c_ulong = 32; +pub const ST_RELATIME: ::c_ulong = 64; + +pub const RTLD_DI_LMID: ::c_int = 1; +pub const RTLD_DI_LINKMAP: ::c_int = 2; +pub const RTLD_DI_CONFIGADDR: ::c_int = 3; +pub const RTLD_DI_SERINFO: ::c_int = 4; +pub const RTLD_DI_SERINFOSIZE: ::c_int = 5; +pub const RTLD_DI_ORIGIN: ::c_int = 6; +pub const RTLD_DI_PROFILENAME: ::c_int = 7; +pub const RTLD_DI_PROFILEOUT: ::c_int = 8; +pub const RTLD_DI_TLS_MODID: ::c_int = 9; +pub const RTLD_DI_TLS_DATA: ::c_int = 10; +pub const RTLD_DI_PHDR: ::c_int = 11; +pub const RTLD_DI_MAX: ::c_int = 11; + +pub const SI_ASYNCIO: ::c_int = -4; +pub const SI_MESGQ: ::c_int = -3; +pub const SI_TIMER: ::c_int = -2; +pub const SI_QUEUE: ::c_int = -1; +pub const SI_USER: ::c_int = 0; + +pub const ILL_ILLOPC: ::c_int = 1; +pub const ILL_ILLOPN: ::c_int = 2; +pub const ILL_ILLADR: ::c_int = 3; +pub const ILL_ILLTRP: ::c_int = 4; +pub const ILL_PRVOPC: ::c_int = 5; +pub const ILL_PRVREG: ::c_int = 6; +pub const ILL_COPROC: ::c_int = 7; +pub const ILL_BADSTK: ::c_int = 8; + +pub const FPE_INTDIV: ::c_int = 1; +pub const FPE_INTOVF: ::c_int = 2; +pub const FPE_FLTDIV: ::c_int = 3; +pub const FPE_FLTOVF: ::c_int = 4; +pub const FPE_FLTUND: ::c_int = 5; +pub const FPE_FLTRES: ::c_int = 6; +pub const FPE_FLTINV: ::c_int = 7; +pub const FPE_FLTSUB: ::c_int = 8; + +pub const SEGV_MAPERR: ::c_int = 1; +pub const SEGV_ACCERR: ::c_int = 2; + +pub const BUS_ADRALN: ::c_int = 1; +pub const BUS_ADRERR: ::c_int = 2; +pub const BUS_OBJERR: ::c_int = 3; + +pub const TRAP_BRKPT: ::c_int = 1; +pub const TRAP_TRACE: ::c_int = 2; + +pub const CLD_EXITED: ::c_int = 1; +pub const CLD_KILLED: ::c_int = 2; +pub const CLD_DUMPED: ::c_int = 3; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const POLL_IN: ::c_int = 1; +pub const POLL_OUT: ::c_int = 2; +pub const POLL_MSG: ::c_int = 3; +pub const POLL_ERR: ::c_int = 4; +pub const POLL_PRI: ::c_int = 5; +pub const POLL_HUP: ::c_int = 6; + +pub const SIGEV_SIGNAL: ::c_int = 0; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const REG_GS: ::c_uint = 0; +pub const REG_FS: ::c_uint = 1; +pub const REG_ES: ::c_uint = 2; +pub const REG_DS: ::c_uint = 3; +pub const REG_EDI: ::c_uint = 4; +pub const REG_ESI: ::c_uint = 5; +pub const REG_EBP: ::c_uint = 6; +pub const REG_ESP: ::c_uint = 7; +pub const REG_EBX: ::c_uint = 8; +pub const REG_EDX: ::c_uint = 9; +pub const REG_ECX: ::c_uint = 10; +pub const REG_EAX: ::c_uint = 11; +pub const REG_TRAPNO: ::c_uint = 12; +pub const REG_ERR: ::c_uint = 13; +pub const REG_EIP: ::c_uint = 14; +pub const REG_CS: ::c_uint = 15; +pub const REG_EFL: ::c_uint = 16; +pub const REG_UESP: ::c_uint = 17; +pub const REG_SS: ::c_uint = 18; + +pub const IOC_VOID: __ioctl_dir = 0; +pub const IOC_OUT: __ioctl_dir = 1; +pub const IOC_IN: __ioctl_dir = 2; +pub const IOC_INOUT: __ioctl_dir = 3; + +pub const IOC_8: __ioctl_datum = 0; +pub const IOC_16: __ioctl_datum = 1; +pub const IOC_32: __ioctl_datum = 2; +pub const IOC_64: __ioctl_datum = 3; + +pub const TCP_ESTABLISHED: ::c_uint = 1; +pub const TCP_SYN_SENT: ::c_uint = 2; +pub const TCP_SYN_RECV: ::c_uint = 3; +pub const TCP_FIN_WAIT1: ::c_uint = 4; +pub const TCP_FIN_WAIT2: ::c_uint = 5; +pub const TCP_TIME_WAIT: ::c_uint = 6; +pub const TCP_CLOSE: ::c_uint = 7; +pub const TCP_CLOSE_WAIT: ::c_uint = 8; +pub const TCP_LAST_ACK: ::c_uint = 9; +pub const TCP_LISTEN: ::c_uint = 10; +pub const TCP_CLOSING: ::c_uint = 11; + +pub const TCP_CA_Open: tcp_ca_state = 0; +pub const TCP_CA_Disorder: tcp_ca_state = 1; +pub const TCP_CA_CWR: tcp_ca_state = 2; +pub const TCP_CA_Recovery: tcp_ca_state = 3; +pub const TCP_CA_Loss: tcp_ca_state = 4; + +pub const TCP_NO_QUEUE: ::c_uint = 0; +pub const TCP_RECV_QUEUE: ::c_uint = 1; +pub const TCP_SEND_QUEUE: ::c_uint = 2; +pub const TCP_QUEUES_NR: ::c_uint = 3; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 4; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __lock: 0, + __owner_id: 0, + __cnt: 0, + __shpid: 0, + __type: PTHREAD_MUTEX_TIMED as ::c_int, + __flags: 0, + __reserved1: 0, + __reserved2: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __lock: __PTHREAD_SPIN_LOCK_INITIALIZER, + __queue: 0i64 as *mut __pthread, + __attr: 0i64 as *mut __pthread_condattr, + __wrefs: 0, + __data: 0i64 as *mut ::c_void, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __held: __PTHREAD_SPIN_LOCK_INITIALIZER, + __lock: __PTHREAD_SPIN_LOCK_INITIALIZER, + __readers: 0, + __readerqueue: 0i64 as *mut __pthread, + __writerqueue: 0i64 as *mut __pthread, + __attr: 0i64 as *mut __pthread_rwlockattr, + __data: 0i64 as *mut ::c_void, +}; +pub const PTHREAD_STACK_MIN: ::size_t = 0; + +const_fn! { + {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } +} + +// functions +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { + cmsg.offset(1) as *mut ::c_uchar + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max || + next as usize + CMSG_ALIGN((*next).cmsg_len as usize) > max + { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + pub fn CPU_ALLOC_SIZE(count: ::c_int) -> ::size_t { + let _dummy: cpu_set_t = ::mem::zeroed(); + let size_in_bits = 8 * ::mem::size_of_val(&_dummy.bits[0]); + ((count as ::size_t + size_in_bits - 1) / 8) as ::size_t + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> ::c_int { + let mut s: u32 = 0; + let size_of_mask = ::mem::size_of_val(&cpuset.bits[0]); + for i in cpuset.bits[..(size / size_of_mask)].iter() { + s += i.count_ones(); + }; + s as ::c_int + } + + pub fn CPU_COUNT(cpuset: &cpu_set_t) -> ::c_int { + CPU_COUNT_S(::mem::size_of::(), cpuset) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + ((dev >> 8) & 0xff) as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + (dev & 0xffff00ff) as ::c_uint + } + + pub fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } + + pub fn IPTOS_PREC(tos: u8) -> u8 { + tos & IPTOS_PREC_MASK + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +extern "C" { + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn futimes(fd: ::c_int, times: *const ::timeval) -> ::c_int; + pub fn futimens(__fd: ::c_int, __times: *const ::timespec) -> ::c_int; + + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + + pub fn mkfifoat(__fd: ::c_int, __path: *const ::c_char, __mode: __mode_t) -> ::c_int; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + + pub fn __libc_current_sigrtmin() -> ::c_int; + + pub fn __libc_current_sigrtmax() -> ::c_int; + + pub fn wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + + pub fn sigwait(__set: *const sigset_t, __sig: *mut ::c_int) -> ::c_int; + + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + + pub fn ioctl(__fd: ::c_int, __request: ::c_ulong, ...) -> ::c_int; + + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; + + pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t; + pub fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: off64_t, + ) -> ::ssize_t; + + pub fn readv(__fd: ::c_int, __iovec: *const ::iovec, __count: ::c_int) -> ::ssize_t; + pub fn writev(__fd: ::c_int, __iovec: *const ::iovec, __count: ::c_int) -> ::ssize_t; + + pub fn preadv( + __fd: ::c_int, + __iovec: *const ::iovec, + __count: ::c_int, + __offset: __off_t, + ) -> ssize_t; + pub fn pwritev( + __fd: ::c_int, + __iovec: *const ::iovec, + __count: ::c_int, + __offset: __off_t, + ) -> ssize_t; + + pub fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + pub fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + + pub fn fread_unlocked( + buf: *mut ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut ::sigevent, + ) -> ::c_int; + + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; + + pub fn lseek64(__fd: ::c_int, __offset: __off64_t, __whence: ::c_int) -> __off64_t; + + pub fn lseek(__fd: ::c_int, __offset: __off_t, __whence: ::c_int) -> __off_t; + + pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; + pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int; + pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int; + pub fn ftello64(stream: *mut ::FILE) -> ::off64_t; + + pub fn bind(__fd: ::c_int, __addr: *const sockaddr, __len: socklen_t) -> ::c_int; + + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + + pub fn recvmsg(__fd: ::c_int, __message: *mut msghdr, __flags: ::c_int) -> ::ssize_t; + + pub fn sendmsg(__fd: ::c_int, __message: *const msghdr, __flags: ::c_int) -> ssize_t; + + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + + pub fn sendfile( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off64_t, + count: ::size_t, + ) -> ::ssize_t; + + pub fn shutdown(__fd: ::c_int, __how: ::c_int) -> ::c_int; + + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + pub fn gethostid() -> ::c_long; + pub fn sethostid(hostid: ::c_long) -> ::c_int; + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn setspent(); + pub fn endspent(); + pub fn getspent() -> *mut spwd; + + pub fn getspnam(name: *const ::c_char) -> *mut spwd; + + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn fgetpwent_r( + stream: *mut ::FILE, + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn fgetgrent_r( + stream: *mut ::FILE, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + + pub fn putpwent(p: *const ::passwd, stream: *mut ::FILE) -> ::c_int; + pub fn putgrent(grp: *const ::group, stream: *mut ::FILE) -> ::c_int; + + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + + pub fn fgetspent_r( + fp: *mut ::FILE, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn sgetspent_r( + s: *const ::c_char, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn getspent_r( + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + + pub fn getspnam_r( + name: *const ::c_char, + spbuf: *mut spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut spwd, + ) -> ::c_int; + + // mntent.h + pub fn getmntent_r( + stream: *mut ::FILE, + mntbuf: *mut ::mntent, + buf: *mut ::c_char, + buflen: ::c_int, + ) -> *mut ::mntent; + + pub fn utmpname(file: *const ::c_char) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); + + pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; + pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + + pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + + pub fn setgroups(ngroups: ::size_t, ptr: *const ::gid_t) -> ::c_int; + + pub fn acct(filename: *const ::c_char) -> ::c_int; + + pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE; + pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent; + pub fn addmntent(stream: *mut ::FILE, mnt: *const ::mntent) -> ::c_int; + pub fn endmntent(streamp: *mut ::FILE) -> ::c_int; + pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char; + + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_kill(__threadid: ::pthread_t, __signo: ::c_int) -> ::c_int; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn __pthread_equal(__t1: __pthread_t, __t2: __pthread_t) -> ::c_int; + + pub fn pthread_getattr_np(__thr: ::pthread_t, __attr: *mut pthread_attr_t) -> ::c_int; + + pub fn pthread_attr_getguardsize( + __attr: *const pthread_attr_t, + __guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + + pub fn pthread_attr_getstack( + __attr: *const pthread_attr_t, + __stackaddr: *mut *mut ::c_void, + __stacksize: *mut ::size_t, + ) -> ::c_int; + + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; + + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + __attr: *mut pthread_condattr_t, + __clock_id: __clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + + pub fn pthread_once(control: *mut pthread_once_t, routine: extern "C" fn()) -> ::c_int; + + pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const ::pthread_barrierattr_t, + shared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut ::pthread_barrierattr_t, + shared: ::c_int, + ) -> ::c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const ::pthread_barrierattr_t, + count: ::c_uint, + ) -> ::c_int; + pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + + pub fn pthread_sigmask( + __how: ::c_int, + __newmask: *const __sigset_t, + __oldmask: *mut __sigset_t, + ) -> ::c_int; + + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + + pub fn clock_getres(__clock_id: clockid_t, __res: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(__clock_id: clockid_t, __tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + + pub fn asctime_r(tm: *const ::tm, buf: *mut ::c_char) -> *mut ::c_char; + pub fn ctime_r(timep: *const time_t, buf: *mut ::c_char) -> *mut ::c_char; + + pub fn strftime( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + ) -> ::size_t; + pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; + + pub fn timer_create( + clockid: ::clockid_t, + sevp: *mut ::sigevent, + timerid: *mut ::timer_t, + ) -> ::c_int; + pub fn timer_delete(timerid: ::timer_t) -> ::c_int; + pub fn timer_getoverrun(timerid: ::timer_t) -> ::c_int; + pub fn timer_gettime(timerid: ::timer_t, curr_value: *mut ::itimerspec) -> ::c_int; + pub fn timer_settime( + timerid: ::timer_t, + flags: ::c_int, + new_value: *const ::itimerspec, + old_value: *mut ::itimerspec, + ) -> ::c_int; + + pub fn fstat(__fd: ::c_int, __buf: *mut stat) -> ::c_int; + pub fn fstat64(__fd: ::c_int, __buf: *mut stat64) -> ::c_int; + + pub fn fstatat( + __fd: ::c_int, + __file: *const ::c_char, + __buf: *mut stat, + __flag: ::c_int, + ) -> ::c_int; + pub fn fstatat64( + __fd: ::c_int, + __file: *const ::c_char, + __buf: *mut stat64, + __flag: ::c_int, + ) -> ::c_int; + + pub fn statx( + dirfd: ::c_int, + pathname: *const c_char, + flags: ::c_int, + mask: ::c_uint, + statxbuf: *mut statx, + ) -> ::c_int; + + pub fn ftruncate(__fd: ::c_int, __length: __off_t) -> ::c_int; + pub fn ftruncate64(__fd: ::c_int, __length: __off64_t) -> ::c_int; + pub fn truncate64(__file: *const ::c_char, __length: __off64_t) -> ::c_int; + + pub fn lstat(__file: *const ::c_char, __buf: *mut stat) -> ::c_int; + pub fn lstat64(__file: *const ::c_char, __buf: *mut stat64) -> ::c_int; + + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn statfs64(__file: *const ::c_char, __buf: *mut statfs64) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn fstatfs64(__fildes: ::c_int, __buf: *mut statfs64) -> ::c_int; + + pub fn statvfs(__file: *const ::c_char, __buf: *mut statvfs) -> ::c_int; + pub fn statvfs64(__file: *const ::c_char, __buf: *mut statvfs64) -> ::c_int; + pub fn fstatvfs(__fildes: ::c_int, __buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs64(__fildes: ::c_int, __buf: *mut statvfs64) -> ::c_int; + + pub fn open(__file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + pub fn open64(__file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + + pub fn openat(__fd: ::c_int, __file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + pub fn openat64(__fd: ::c_int, __file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut ::FILE, + ) -> *mut ::FILE; + + pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int; + + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn tmpfile64() -> *mut ::FILE; + + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + + pub fn getdtablesize() -> ::c_int; + + // Added in `glibc` 2.34 + pub fn close_range(first: ::c_uint, last: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn openpty( + __amaster: *mut ::c_int, + __aslave: *mut ::c_int, + __name: *mut ::c_char, + __termp: *const termios, + __winp: *const ::winsize, + ) -> ::c_int; + + pub fn forkpty( + __amaster: *mut ::c_int, + __name: *mut ::c_char, + __termp: *const termios, + __winp: *const ::winsize, + ) -> ::pid_t; + + pub fn getpt() -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + pub fn login_tty(fd: ::c_int) -> ::c_int; + + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + + pub fn clearenv() -> ::c_int; + + pub fn execveat( + dirfd: ::c_int, + pathname: *const ::c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + + // posix/spawn.h + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + flags: *mut ::c_int, + ) -> ::c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; + + // Added in `glibc` 2.29 + pub fn posix_spawn_file_actions_addchdir_np( + actions: *mut ::posix_spawn_file_actions_t, + path: *const ::c_char, + ) -> ::c_int; + // Added in `glibc` 2.29 + pub fn posix_spawn_file_actions_addfchdir_np( + actions: *mut ::posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + // Added in `glibc` 2.34 + pub fn posix_spawn_file_actions_addclosefrom_np( + actions: *mut ::posix_spawn_file_actions_t, + from: ::c_int, + ) -> ::c_int; + // Added in `glibc` 2.35 + pub fn posix_spawn_file_actions_addtcsetpgrp_np( + actions: *mut ::posix_spawn_file_actions_t, + tcfd: ::c_int, + ) -> ::c_int; + + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + + pub fn stat(__file: *const ::c_char, __buf: *mut stat) -> ::c_int; + pub fn stat64(__file: *const ::c_char, __buf: *mut stat64) -> ::c_int; + + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64; + pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) + -> ::c_int; + pub fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, + ) -> ::c_int; + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + + #[link_name = "__xpg_strerror_r"] + pub fn strerror_r(__errnum: ::c_int, __buf: *mut ::c_char, __buflen: ::size_t) -> ::c_int; + + pub fn __errno_location() -> *mut ::c_int; + + pub fn mmap64( + __addr: *mut ::c_void, + __len: size_t, + __prot: ::c_int, + __flags: ::c_int, + __fd: ::c_int, + __offset: __off64_t, + ) -> *mut ::c_void; + + pub fn mremap( + addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ... + ) -> *mut ::c_void; + + pub fn mprotect(__addr: *mut ::c_void, __len: ::size_t, __prot: ::c_int) -> ::c_int; + + pub fn msync(__addr: *mut ::c_void, __len: ::size_t, __flags: ::c_int) -> ::c_int; + pub fn sync(); + pub fn syncfs(fd: ::c_int) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + + pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + + pub fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advise: ::c_int, + ) -> ::c_int; + + pub fn madvise(__addr: *mut ::c_void, __len: ::size_t, __advice: ::c_int) -> ::c_int; + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn getrlimit(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit) -> ::c_int; + pub fn getrlimit64(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit64) -> ::c_int; + pub fn setrlimit(resource: ::__rlimit_resource_t, rlim: *const ::rlimit) -> ::c_int; + pub fn setrlimit64(resource: ::__rlimit_resource_t, rlim: *const ::rlimit64) -> ::c_int; + + pub fn getpriority(which: ::__priority_which, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::__priority_which, who: ::id_t, prio: ::c_int) -> ::c_int; + + pub fn getrandom(__buffer: *mut ::c_void, __length: ::size_t, __flags: ::c_uint) -> ::ssize_t; + pub fn getentropy(__buffer: *mut ::c_void, __length: ::size_t) -> ::c_int; + + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + pub fn drand48() -> ::c_double; + pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; + pub fn lrand48() -> ::c_long; + pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn mrand48() -> ::c_long; + pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn srand48(seed: ::c_long); + pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; + pub fn lcong48(p: *mut ::c_ushort); + + pub fn qsort_r( + base: *mut ::c_void, + num: ::size_t, + size: ::size_t, + compar: ::Option< + unsafe extern "C" fn(*const ::c_void, *const ::c_void, *mut ::c_void) -> ::c_int, + >, + arg: *mut ::c_void, + ); + + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn mallopt(param: ::c_int, value: ::c_int) -> ::c_int; + + pub fn mallinfo() -> ::mallinfo; + pub fn mallinfo2() -> ::mallinfo2; + pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int; + pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + pub fn malloc_trim(__pad: ::size_t) -> ::c_int; + + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; + + pub fn getopt_long( + argc: ::c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut ::c_int, + ) -> ::c_int; + + pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int; + + pub fn reboot(how_to: ::c_int) -> ::c_int; + + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + + pub fn regexec( + preg: *const ::regex_t, + input: *const ::c_char, + nmatch: ::size_t, + pmatch: *mut regmatch_t, + eflags: ::c_int, + ) -> ::c_int; + + pub fn regerror( + errcode: ::c_int, + preg: *const ::regex_t, + errbuf: *mut ::c_char, + errbuf_size: ::size_t, + ) -> ::size_t; + + pub fn regfree(preg: *mut ::regex_t); + + pub fn glob( + pattern: *const c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + + pub fn glob64( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t, + ) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + + pub fn getxattr( + path: *const c_char, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn lgetxattr( + path: *const c_char, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn fgetxattr( + filedes: ::c_int, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn setxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn lsetxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fsetxattr( + filedes: ::c_int, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn listxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn llistxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn flistxattr(filedes: ::c_int, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn removexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn lremovexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn fremovexattr(filedes: ::c_int, name: *const c_char) -> ::c_int; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + /// POSIX version of `basename(3)`, defined in `libgen.h`. + #[link_name = "__xpg_basename"] + pub fn posix_basename(path: *mut ::c_char) -> *mut ::c_char; + /// GNU version of `basename(3)`, defined in `string.h`. + #[link_name = "basename"] + pub fn gnu_basename(path: *const ::c_char) -> *mut ::c_char; + + pub fn dlmopen(lmid: Lmid_t, filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + pub fn dlinfo(handle: *mut ::c_void, request: ::c_int, info: *mut ::c_void) -> ::c_int; + pub fn dladdr1( + addr: *const ::c_void, + info: *mut ::Dl_info, + extra_info: *mut *mut ::c_void, + flags: ::c_int, + ) -> ::c_int; + + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn gnu_get_libc_release() -> *const ::c_char; + pub fn gnu_get_libc_version() -> *const ::c_char; +} + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= major << 8; + dev |= minor; + dev + } + + pub fn SIGRTMAX() -> ::c_int { + unsafe { __libc_current_sigrtmax() } + } + + pub fn SIGRTMIN() -> ::c_int { + unsafe { __libc_current_sigrtmin() } + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0x7f) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } + + pub {const} fn W_EXITCODE(ret: ::c_int, sig: ::c_int) -> ::c_int { + (ret << 8) | sig + } + + pub {const} fn W_STOPCODE(sig: ::c_int) -> ::c_int { + (sig << 8) | 0x7f + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub {const} fn IPOPT_COPIED(o: u8) -> u8 { + o & IPOPT_COPY + } + + pub {const} fn IPOPT_CLASS(o: u8) -> u8 { + o & IPOPT_CLASS_MASK + } + + pub {const} fn IPOPT_NUMBER(o: u8) -> u8 { + o & IPOPT_NUMBER_MASK + } + + pub {const} fn IPTOS_ECN(x: u8) -> u8 { + x & ::IPTOS_ECN_MASK + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + mod b32; + pub use self::b32::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/hurd/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/hurd/no_align.rs new file mode 100644 index 00000000..1dd7d8e5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/hurd/no_align.rs @@ -0,0 +1 @@ +// Placeholder file diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/arm.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/arm.rs new file mode 100644 index 00000000..a062175e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/arm.rs @@ -0,0 +1,550 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type greg_t = i32; +pub type mcontext_t = sigcontext; + +s! { + pub struct sigcontext { + pub trap_no: ::c_ulong, + pub error_code: ::c_ulong, + pub oldmask: ::c_ulong, + pub arm_r0: ::c_ulong, + pub arm_r1: ::c_ulong, + pub arm_r2: ::c_ulong, + pub arm_r3: ::c_ulong, + pub arm_r4: ::c_ulong, + pub arm_r5: ::c_ulong, + pub arm_r6: ::c_ulong, + pub arm_r7: ::c_ulong, + pub arm_r8: ::c_ulong, + pub arm_r9: ::c_ulong, + pub arm_r10: ::c_ulong, + pub arm_fp: ::c_ulong, + pub arm_ip: ::c_ulong, + pub arm_sp: ::c_ulong, + pub arm_lr: ::c_ulong, + pub arm_pc: ::c_ulong, + pub arm_cpsr: ::c_ulong, + pub fault_address: ::c_ulong, + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub struct __c_anonymous_uc_sigmask_with_padding { + pub uc_sigmask: ::sigset_t, + /* Android has a wrong (smaller) sigset_t on x86. */ + __padding_rt_sigset: u32, + } + + pub union __c_anonymous_uc_sigmask { + uc_sigmask: __c_anonymous_uc_sigmask_with_padding, + uc_sigmask64: ::sigset64_t, + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask, + /* The kernel adds extra padding after uc_sigmask to match + * glibc sigset_t on ARM. */ + __padding: [c_char; 120], + __align: [::c_longlong; 0], + uc_regspace: [::c_ulong; 128], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_uc_sigmask_with_padding { + fn eq( + &self, other: &__c_anonymous_uc_sigmask_with_padding + ) -> bool { + self.uc_sigmask == other.uc_sigmask + // Ignore padding + } + } + impl Eq for __c_anonymous_uc_sigmask_with_padding {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask_with_padding") + .field("uc_sigmask_with_padding", &self.uc_sigmask) + // Ignore padding + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding { + fn hash(&self, state: &mut H) { + self.uc_sigmask.hash(state) + // Ignore padding + } + } + + impl PartialEq for __c_anonymous_uc_sigmask { + fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { + unsafe { self.uc_sigmask == other.uc_sigmask } + } + } + impl Eq for __c_anonymous_uc_sigmask {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask") + .field("uc_sigmask", unsafe { &self.uc_sigmask }) + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &Self) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask__c_anonymous_union + == other.uc_sigmask__c_anonymous_union + && &self.uc_regspace[..] == &other.uc_regspace[..] + // Ignore padding field + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field( + "uc_sigmask__c_anonymous_union", + &self.uc_sigmask__c_anonymous_union + ) + .field("uc_regspace", &&self.uc_regspace[..]) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask__c_anonymous_union.hash(state); + self.uc_regspace[..].hash(state); + // Ignore padding field + } + } + } + } + } +} + +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_LARGEFILE: ::c_int = 0o400000; + +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS_getdents: ::c_long = 141; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_arm_fadvise64_64: ::c_long = 270; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_arm_sync_file_range: ::c_long = 341; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +pub const SYS_pwritev2: ::c_long = 393; +pub const SYS_pkey_mprotect: ::c_long = 394; +pub const SYS_pkey_alloc: ::c_long = 395; +pub const SYS_pkey_free: ::c_long = 396; +pub const SYS_statx: ::c_long = 397; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_R0: ::c_int = 0; +pub const REG_R1: ::c_int = 1; +pub const REG_R2: ::c_int = 2; +pub const REG_R3: ::c_int = 3; +pub const REG_R4: ::c_int = 4; +pub const REG_R5: ::c_int = 5; +pub const REG_R6: ::c_int = 6; +pub const REG_R7: ::c_int = 7; +pub const REG_R8: ::c_int = 8; +pub const REG_R9: ::c_int = 9; +pub const REG_R10: ::c_int = 10; +pub const REG_R11: ::c_int = 11; +pub const REG_R12: ::c_int = 12; +pub const REG_R13: ::c_int = 13; +pub const REG_R14: ::c_int = 14; +pub const REG_R15: ::c_int = 15; + +pub const NGREG: ::c_int = 18; + +f! { + // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not + // exposed by the libc. As work-around, we implement it through `syscall` + // directly. This workaround can be removed if the minimum version of + // Android is bumped. When the workaround is removed, `accept4` can be + // moved back to `linux_like/mod.rs` + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int + ) -> ::c_int { + ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/mod.rs new file mode 100644 index 00000000..1f4f796f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/mod.rs @@ -0,0 +1,244 @@ +// The following definitions are correct for arm and i686, +// but may be wrong for mips + +pub type c_long = i32; +pub type c_ulong = u32; +pub type mode_t = u16; +pub type off64_t = ::c_longlong; +pub type sigset_t = ::c_ulong; +pub type socklen_t = i32; +pub type time64_t = i64; +pub type __u64 = ::c_ulonglong; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct rlimit64 { + pub rlim_cur: u64, + pub rlim_max: u64, + } + + pub struct stat { + pub st_dev: ::c_ulonglong, + __pad0: [::c_uchar; 4], + __st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + __pad3: [::c_uchar; 4], + pub st_size: ::c_longlong, + pub st_blksize: ::blksize_t, + pub st_blocks: ::c_ulonglong, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::c_ulonglong, + } + + pub struct stat64 { + pub st_dev: ::c_ulonglong, + __pad0: [::c_uchar; 4], + __st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + __pad3: [::c_uchar; 4], + pub st_size: ::c_longlong, + pub st_blksize: ::blksize_t, + pub st_blocks: ::c_ulonglong, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::c_ulonglong, + } + + pub struct statfs64 { + pub f_type: u32, + pub f_bsize: u32, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::__fsid_t, + pub f_namelen: u32, + pub f_frsize: u32, + pub f_flags: u32, + pub f_spare: [u32; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::c_ulong, + pub f_bfree: ::c_ulong, + pub f_bavail: ::c_ulong, + pub f_files: ::c_ulong, + pub f_ffree: ::c_ulong, + pub f_favail: ::c_ulong, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct pthread_attr_t { + pub flags: u32, + pub stack_base: *mut ::c_void, + pub stack_size: ::size_t, + pub guard_size: ::size_t, + pub sched_policy: i32, + pub sched_priority: i32, + } + + pub struct pthread_mutex_t { value: ::c_int } + + pub struct pthread_cond_t { value: ::c_int } + + pub struct pthread_rwlock_t { + lock: pthread_mutex_t, + cond: pthread_cond_t, + numLocks: ::c_int, + writerThreadId: ::c_int, + pendingReaders: ::c_int, + pendingWriters: ::c_int, + attr: i32, + __reserved: [::c_char; 12], + } + + pub struct pthread_barrier_t { + __private: [i32; 8], + } + + pub struct pthread_spinlock_t { + __private: [i32; 2], + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct statfs { + pub f_type: u32, + pub f_bsize: u32, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::__fsid_t, + pub f_namelen: u32, + pub f_frsize: u32, + pub f_flags: u32, + pub f_spare: [u32; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } +} + +s_no_extra_traits! { + pub struct sigset64_t { + __bits: [::c_ulong; 2] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl ::fmt::Debug for sigset64_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigset64_t") + .field("__bits", &self.__bits) + .finish() + } + } + } +} + +// These constants must be of the same type of sigaction.sa_flags +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; + +pub const RTLD_GLOBAL: ::c_int = 2; +pub const RTLD_NOW: ::c_int = 0; +pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void; + +pub const PTRACE_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { value: 0 }; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { value: 0 }; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + lock: PTHREAD_MUTEX_INITIALIZER, + cond: PTHREAD_COND_INITIALIZER, + numLocks: 0, + writerThreadId: 0, + pendingReaders: 0, + pendingWriters: 0, + attr: 0, + __reserved: [0; 12], +}; +pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 2; +pub const CPU_SETSIZE: ::size_t = 32; +pub const __CPU_BITS: ::size_t = 32; + +pub const UT_LINESIZE: usize = 8; +pub const UT_NAMESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 16; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +extern "C" { + pub fn timegm64(tm: *const ::tm) -> ::time64_t; +} + +cfg_if! { + if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs new file mode 100644 index 00000000..04df4a05 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 2] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs new file mode 100644 index 00000000..e549f3b5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs @@ -0,0 +1,622 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type greg_t = i32; + +s! { + pub struct _libc_fpreg { + pub significand: [u16; 4], + pub exponent: u16, + } + + pub struct _libc_fpstate { + pub cw: ::c_ulong, + pub sw: ::c_ulong, + pub tag: ::c_ulong, + pub ipoff: ::c_ulong, + pub cssel: ::c_ulong, + pub dataoff: ::c_ulong, + pub datasel: ::c_ulong, + pub _st: [_libc_fpreg; 8], + pub status: ::c_ulong, + } + + pub struct mcontext_t { + pub gregs: [greg_t; 19], + pub fpregs: *mut _libc_fpstate, + pub oldmask: ::c_ulong, + pub cr2: ::c_ulong, + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub struct __c_anonymous_uc_sigmask_with_padding { + pub uc_sigmask: ::sigset_t, + /* Android has a wrong (smaller) sigset_t on x86. */ + __padding_rt_sigset: u32, + } + + pub union __c_anonymous_uc_sigmask { + uc_sigmask: __c_anonymous_uc_sigmask_with_padding, + uc_sigmask64: ::sigset64_t, + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask__c_anonymous_union: __c_anonymous_uc_sigmask, + __padding_rt_sigset: u32, + __fpregs_mem: _libc_fpstate, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_uc_sigmask_with_padding { + fn eq( + &self, other: &__c_anonymous_uc_sigmask_with_padding + ) -> bool { + self.uc_sigmask == other.uc_sigmask + // Ignore padding + } + } + impl Eq for __c_anonymous_uc_sigmask_with_padding {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask_with_padding") + .field("uc_sigmask_with_padding", &self.uc_sigmask) + // Ignore padding + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding { + fn hash(&self, state: &mut H) { + self.uc_sigmask.hash(state) + // Ignore padding + } + } + + impl PartialEq for __c_anonymous_uc_sigmask { + fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { + unsafe { self.uc_sigmask == other.uc_sigmask } + } + } + impl Eq for __c_anonymous_uc_sigmask {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask") + .field("uc_sigmask", unsafe { &self.uc_sigmask }) + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &Self) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask__c_anonymous_union + == other.uc_sigmask__c_anonymous_union + // Ignore padding field + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field( + "uc_sigmask__c_anonymous_union", + &self.uc_sigmask__c_anonymous_union + ) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask__c_anonymous_union.hash(state); + // Ignore padding field + } + } + } + } + } +} + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +pub const MAP_32BIT: ::c_int = 0x40; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86old: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +// FIXME: SYS__llseek is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +// FIXME: SYS__newselect is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +// FIXME: SYS__llseek is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_vm86: ::c_long = 166; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_set_thread_area: ::c_long = 243; +pub const SYS_get_thread_area: ::c_long = 244; +pub const SYS_io_setup: ::c_long = 245; +pub const SYS_io_destroy: ::c_long = 246; +pub const SYS_io_getevents: ::c_long = 247; +pub const SYS_io_submit: ::c_long = 248; +pub const SYS_io_cancel: ::c_long = 249; +pub const SYS_fadvise64: ::c_long = 250; +pub const SYS_exit_group: ::c_long = 252; +pub const SYS_lookup_dcookie: ::c_long = 253; +pub const SYS_epoll_create: ::c_long = 254; +pub const SYS_epoll_ctl: ::c_long = 255; +pub const SYS_epoll_wait: ::c_long = 256; +pub const SYS_remap_file_pages: ::c_long = 257; +pub const SYS_set_tid_address: ::c_long = 258; +pub const SYS_timer_create: ::c_long = 259; +pub const SYS_timer_settime: ::c_long = 260; +pub const SYS_timer_gettime: ::c_long = 261; +pub const SYS_timer_getoverrun: ::c_long = 262; +pub const SYS_timer_delete: ::c_long = 263; +pub const SYS_clock_settime: ::c_long = 264; +pub const SYS_clock_gettime: ::c_long = 265; +pub const SYS_clock_getres: ::c_long = 266; +pub const SYS_clock_nanosleep: ::c_long = 267; +pub const SYS_statfs64: ::c_long = 268; +pub const SYS_fstatfs64: ::c_long = 269; +pub const SYS_tgkill: ::c_long = 270; +pub const SYS_utimes: ::c_long = 271; +pub const SYS_fadvise64_64: ::c_long = 272; +pub const SYS_vserver: ::c_long = 273; +pub const SYS_mbind: ::c_long = 274; +pub const SYS_get_mempolicy: ::c_long = 275; +pub const SYS_set_mempolicy: ::c_long = 276; +pub const SYS_mq_open: ::c_long = 277; +pub const SYS_mq_unlink: ::c_long = 278; +pub const SYS_mq_timedsend: ::c_long = 279; +pub const SYS_mq_timedreceive: ::c_long = 280; +pub const SYS_mq_notify: ::c_long = 281; +pub const SYS_mq_getsetattr: ::c_long = 282; +pub const SYS_kexec_load: ::c_long = 283; +pub const SYS_waitid: ::c_long = 284; +pub const SYS_add_key: ::c_long = 286; +pub const SYS_request_key: ::c_long = 287; +pub const SYS_keyctl: ::c_long = 288; +pub const SYS_ioprio_set: ::c_long = 289; +pub const SYS_ioprio_get: ::c_long = 290; +pub const SYS_inotify_init: ::c_long = 291; +pub const SYS_inotify_add_watch: ::c_long = 292; +pub const SYS_inotify_rm_watch: ::c_long = 293; +pub const SYS_migrate_pages: ::c_long = 294; +pub const SYS_openat: ::c_long = 295; +pub const SYS_mkdirat: ::c_long = 296; +pub const SYS_mknodat: ::c_long = 297; +pub const SYS_fchownat: ::c_long = 298; +pub const SYS_futimesat: ::c_long = 299; +pub const SYS_fstatat64: ::c_long = 300; +pub const SYS_unlinkat: ::c_long = 301; +pub const SYS_renameat: ::c_long = 302; +pub const SYS_linkat: ::c_long = 303; +pub const SYS_symlinkat: ::c_long = 304; +pub const SYS_readlinkat: ::c_long = 305; +pub const SYS_fchmodat: ::c_long = 306; +pub const SYS_faccessat: ::c_long = 307; +pub const SYS_pselect6: ::c_long = 308; +pub const SYS_ppoll: ::c_long = 309; +pub const SYS_unshare: ::c_long = 310; +pub const SYS_set_robust_list: ::c_long = 311; +pub const SYS_get_robust_list: ::c_long = 312; +pub const SYS_splice: ::c_long = 313; +pub const SYS_sync_file_range: ::c_long = 314; +pub const SYS_tee: ::c_long = 315; +pub const SYS_vmsplice: ::c_long = 316; +pub const SYS_move_pages: ::c_long = 317; +pub const SYS_getcpu: ::c_long = 318; +pub const SYS_epoll_pwait: ::c_long = 319; +pub const SYS_utimensat: ::c_long = 320; +pub const SYS_signalfd: ::c_long = 321; +pub const SYS_timerfd_create: ::c_long = 322; +pub const SYS_eventfd: ::c_long = 323; +pub const SYS_fallocate: ::c_long = 324; +pub const SYS_timerfd_settime: ::c_long = 325; +pub const SYS_timerfd_gettime: ::c_long = 326; +pub const SYS_signalfd4: ::c_long = 327; +pub const SYS_eventfd2: ::c_long = 328; +pub const SYS_epoll_create1: ::c_long = 329; +pub const SYS_dup3: ::c_long = 330; +pub const SYS_pipe2: ::c_long = 331; +pub const SYS_inotify_init1: ::c_long = 332; +pub const SYS_preadv: ::c_long = 333; +pub const SYS_pwritev: ::c_long = 334; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 335; +pub const SYS_perf_event_open: ::c_long = 336; +pub const SYS_recvmmsg: ::c_long = 337; +pub const SYS_fanotify_init: ::c_long = 338; +pub const SYS_fanotify_mark: ::c_long = 339; +pub const SYS_prlimit64: ::c_long = 340; +pub const SYS_name_to_handle_at: ::c_long = 341; +pub const SYS_open_by_handle_at: ::c_long = 342; +pub const SYS_clock_adjtime: ::c_long = 343; +pub const SYS_syncfs: ::c_long = 344; +pub const SYS_sendmmsg: ::c_long = 345; +pub const SYS_setns: ::c_long = 346; +pub const SYS_process_vm_readv: ::c_long = 347; +pub const SYS_process_vm_writev: ::c_long = 348; +pub const SYS_kcmp: ::c_long = 349; +pub const SYS_finit_module: ::c_long = 350; +pub const SYS_sched_setattr: ::c_long = 351; +pub const SYS_sched_getattr: ::c_long = 352; +pub const SYS_renameat2: ::c_long = 353; +pub const SYS_seccomp: ::c_long = 354; +pub const SYS_getrandom: ::c_long = 355; +pub const SYS_memfd_create: ::c_long = 356; +pub const SYS_bpf: ::c_long = 357; +pub const SYS_execveat: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_userfaultfd: ::c_long = 374; +pub const SYS_membarrier: ::c_long = 375; +pub const SYS_mlock2: ::c_long = 376; +pub const SYS_copy_file_range: ::c_long = 377; +pub const SYS_preadv2: ::c_long = 378; +pub const SYS_pwritev2: ::c_long = 379; +pub const SYS_pkey_mprotect: ::c_long = 380; +pub const SYS_pkey_alloc: ::c_long = 381; +pub const SYS_pkey_free: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; + +// offsets in user_regs_structs, from sys/reg.h +pub const EBX: ::c_int = 0; +pub const ECX: ::c_int = 1; +pub const EDX: ::c_int = 2; +pub const ESI: ::c_int = 3; +pub const EDI: ::c_int = 4; +pub const EBP: ::c_int = 5; +pub const EAX: ::c_int = 6; +pub const DS: ::c_int = 7; +pub const ES: ::c_int = 8; +pub const FS: ::c_int = 9; +pub const GS: ::c_int = 10; +pub const ORIG_EAX: ::c_int = 11; +pub const EIP: ::c_int = 12; +pub const CS: ::c_int = 13; +pub const EFL: ::c_int = 14; +pub const UESP: ::c_int = 15; +pub const SS: ::c_int = 16; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_GS: ::c_int = 0; +pub const REG_FS: ::c_int = 1; +pub const REG_ES: ::c_int = 2; +pub const REG_DS: ::c_int = 3; +pub const REG_EDI: ::c_int = 4; +pub const REG_ESI: ::c_int = 5; +pub const REG_EBP: ::c_int = 6; +pub const REG_ESP: ::c_int = 7; +pub const REG_EBX: ::c_int = 8; +pub const REG_EDX: ::c_int = 9; +pub const REG_ECX: ::c_int = 10; +pub const REG_EAX: ::c_int = 11; +pub const REG_TRAPNO: ::c_int = 12; +pub const REG_ERR: ::c_int = 13; +pub const REG_EIP: ::c_int = 14; +pub const REG_CS: ::c_int = 15; +pub const REG_EFL: ::c_int = 16; +pub const REG_UESP: ::c_int = 17; +pub const REG_SS: ::c_int = 18; + +// socketcall values from linux/net.h (only the needed ones, and not public) +const SYS_ACCEPT4: ::c_int = 18; + +f! { + // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not + // exposed by the libc. As work-around, we implement it as raw syscall. + // Note that for x86, the `accept4` syscall is not available either, + // and we must use the `socketcall` syscall instead. + // This workaround can be removed if the minimum Android version is bumped. + // When the workaround is removed, `accept4` can be moved back + // to `linux_like/mod.rs` + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int + ) -> ::c_int { + // Arguments are passed as array of `long int` + // (which is big enough on x86 for a pointer). + let mut args = [ + fd as ::c_long, + addr as ::c_long, + len as ::c_long, + flg as ::c_long, + ]; + ::syscall(SYS_socketcall, SYS_ACCEPT4, args[..].as_mut_ptr()) + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs new file mode 100644 index 00000000..154c2c54 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs @@ -0,0 +1,29 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} + +s! { + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub fault_address: ::c_ulonglong, + pub regs: [::c_ulonglong; 31], + pub sp: ::c_ulonglong, + pub pc: ::c_ulonglong, + pub pstate: ::c_ulonglong, + // nested arrays to get the right size/length while being able to + // auto-derive traits like Debug + __reserved: [[u64; 32]; 16], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs new file mode 100644 index 00000000..4535e73e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs @@ -0,0 +1,7 @@ +s! { + pub struct user_fpsimd_struct { + pub vregs: [::__uint128_t; 32], + pub fpsr: u32, + pub fpcr: u32, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs new file mode 100644 index 00000000..ac67fdda --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs @@ -0,0 +1,430 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type __u64 = ::c_ulonglong; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::c_ulong, + pub st_size: ::off64_t, + pub st_blksize: ::c_int, + __pad2: ::c_int, + pub st_blocks: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused4: ::c_uint, + __unused5: ::c_uint, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::c_ulong, + pub st_size: ::off64_t, + pub st_blksize: ::c_int, + __pad2: ::c_int, + pub st_blocks: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused4: ::c_uint, + __unused5: ::c_uint, + } + + pub struct user_regs_struct { + pub regs: [u64; 31], + pub sp: u64, + pub pc: u64, + pub pstate: u64, + } +} + +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_LARGEFILE: ::c_int = 0o400000; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 5120; + +// From NDK's asm/hwcap.h +pub const HWCAP_FP: ::c_ulong = 1 << 0; +pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +pub const HWCAP_EVTSTRM: ::c_ulong = 1 << 2; +pub const HWCAP_AES: ::c_ulong = 1 << 3; +pub const HWCAP_PMULL: ::c_ulong = 1 << 4; +pub const HWCAP_SHA1: ::c_ulong = 1 << 5; +pub const HWCAP_SHA2: ::c_ulong = 1 << 6; +pub const HWCAP_CRC32: ::c_ulong = 1 << 7; +pub const HWCAP_ATOMICS: ::c_ulong = 1 << 8; +pub const HWCAP_FPHP: ::c_ulong = 1 << 9; +pub const HWCAP_ASIMDHP: ::c_ulong = 1 << 10; +pub const HWCAP_CPUID: ::c_ulong = 1 << 11; +pub const HWCAP_ASIMDRDM: ::c_ulong = 1 << 12; +pub const HWCAP_JSCVT: ::c_ulong = 1 << 13; +pub const HWCAP_FCMA: ::c_ulong = 1 << 14; +pub const HWCAP_LRCPC: ::c_ulong = 1 << 15; +pub const HWCAP_DCPOP: ::c_ulong = 1 << 16; +pub const HWCAP_SHA3: ::c_ulong = 1 << 17; +pub const HWCAP_SM3: ::c_ulong = 1 << 18; +pub const HWCAP_SM4: ::c_ulong = 1 << 19; +pub const HWCAP_ASIMDDP: ::c_ulong = 1 << 20; +pub const HWCAP_SHA512: ::c_ulong = 1 << 21; +pub const HWCAP_SVE: ::c_ulong = 1 << 22; +pub const HWCAP_ASIMDFHM: ::c_ulong = 1 << 23; +pub const HWCAP_DIT: ::c_ulong = 1 << 24; +pub const HWCAP_USCAT: ::c_ulong = 1 << 25; +pub const HWCAP_ILRCPC: ::c_ulong = 1 << 26; +pub const HWCAP_FLAGM: ::c_ulong = 1 << 27; +pub const HWCAP_SSBS: ::c_ulong = 1 << 28; +pub const HWCAP_SB: ::c_ulong = 1 << 29; +pub const HWCAP_PACA: ::c_ulong = 1 << 30; +pub const HWCAP_PACG: ::c_ulong = 1 << 31; +pub const HWCAP2_DCPODP: ::c_ulong = 1 << 0; +pub const HWCAP2_SVE2: ::c_ulong = 1 << 1; +pub const HWCAP2_SVEAES: ::c_ulong = 1 << 2; +pub const HWCAP2_SVEPMULL: ::c_ulong = 1 << 3; +pub const HWCAP2_SVEBITPERM: ::c_ulong = 1 << 4; +pub const HWCAP2_SVESHA3: ::c_ulong = 1 << 5; +pub const HWCAP2_SVESM4: ::c_ulong = 1 << 6; +pub const HWCAP2_FLAGM2: ::c_ulong = 1 << 7; +pub const HWCAP2_FRINT: ::c_ulong = 1 << 8; +pub const HWCAP2_SVEI8MM: ::c_ulong = 1 << 9; +pub const HWCAP2_SVEF32MM: ::c_ulong = 1 << 10; +pub const HWCAP2_SVEF64MM: ::c_ulong = 1 << 11; +pub const HWCAP2_SVEBF16: ::c_ulong = 1 << 12; +pub const HWCAP2_I8MM: ::c_ulong = 1 << 13; +pub const HWCAP2_BF16: ::c_ulong = 1 << 14; +pub const HWCAP2_DGH: ::c_ulong = 1 << 15; +pub const HWCAP2_RNG: ::c_ulong = 1 << 16; +pub const HWCAP2_BTI: ::c_ulong = 1 << 17; +pub const HWCAP2_MTE: ::c_ulong = 1 << 18; +pub const HWCAP2_ECV: ::c_ulong = 1 << 19; +pub const HWCAP2_AFP: ::c_ulong = 1 << 20; +pub const HWCAP2_RPRES: ::c_ulong = 1 << 21; +pub const HWCAP2_MTE3: ::c_ulong = 1 << 22; +pub const HWCAP2_SME: ::c_ulong = 1 << 23; +pub const HWCAP2_SME_I16I64: ::c_ulong = 1 << 24; +pub const HWCAP2_SME_F64F64: ::c_ulong = 1 << 25; +pub const HWCAP2_SME_I8I32: ::c_ulong = 1 << 26; +pub const HWCAP2_SME_F16F32: ::c_ulong = 1 << 27; +pub const HWCAP2_SME_B16F32: ::c_ulong = 1 << 28; +pub const HWCAP2_SME_F32F32: ::c_ulong = 1 << 29; +pub const HWCAP2_SME_FA64: ::c_ulong = 1 << 30; +pub const HWCAP2_WFXT: ::c_ulong = 1 << 31; +pub const HWCAP2_EBF16: ::c_ulong = 1 << 32; +pub const HWCAP2_SVE_EBF16: ::c_ulong = 1 << 33; + +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_dup: ::c_long = 23; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_flock: ::c_long = 32; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_renameat: ::c_long = 38; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_mount: ::c_long = 40; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_openat: ::c_long = 56; +pub const SYS_close: ::c_long = 57; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_sync: ::c_long = 81; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_acct: ::c_long = 89; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_personality: ::c_long = 92; +pub const SYS_exit: ::c_long = 93; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_futex: ::c_long = 98; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_kill: ::c_long = 129; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_times: ::c_long = 153; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_uname: ::c_long = 160; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_umask: ::c_long = 166; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_semop: ::c_long = 193; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_socket: ::c_long = 198; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_accept: ::c_long = 202; +pub const SYS_connect: ::c_long = 203; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_brk: ::c_long = 214; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_arch_specific_syscall: ::c_long = 244; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_setns: ::c_long = 268; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_syscalls: ::c_long = 436; + +pub const PROT_BTI: ::c_int = 0x10; +pub const PROT_MTE: ::c_int = 0x20; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} + +cfg_if! { + if #[cfg(libc_int128)] { + mod int128; + pub use self::int128::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/mod.rs new file mode 100644 index 00000000..67d0dacf --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/mod.rs @@ -0,0 +1,355 @@ +// The following definitions are correct for aarch64 and x86_64, +// but may be wrong for mips64 + +pub type c_long = i64; +pub type c_ulong = u64; +pub type mode_t = u32; +pub type off64_t = i64; +pub type socklen_t = u32; + +s! { + pub struct sigset_t { + __val: [::c_ulong; 1], + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_restorer: ::Option, + } + + pub struct rlimit64 { + pub rlim_cur: ::c_ulonglong, + pub rlim_max: ::c_ulonglong, + } + + pub struct pthread_attr_t { + pub flags: u32, + pub stack_base: *mut ::c_void, + pub stack_size: ::size_t, + pub guard_size: ::size_t, + pub sched_policy: i32, + pub sched_priority: i32, + __reserved: [::c_char; 16], + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct statfs { + pub f_type: u64, + pub f_bsize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::__fsid_t, + pub f_namelen: u64, + pub f_frsize: u64, + pub f_flags: u64, + pub f_spare: [u64; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct statfs64 { + pub f_type: u64, + pub f_bsize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::__fsid_t, + pub f_namelen: u64, + pub f_frsize: u64, + pub f_flags: u64, + pub f_spare: [u64; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_barrier_t { + __private: [i64; 4], + } + + pub struct pthread_spinlock_t { + __private: i64, + } +} + +s_no_extra_traits! { + pub struct pthread_mutex_t { + value: ::c_int, + __reserved: [::c_char; 36], + } + + pub struct pthread_cond_t { + value: ::c_int, + __reserved: [::c_char; 44], + } + + pub struct pthread_rwlock_t { + numLocks: ::c_int, + writerThreadId: ::c_int, + pendingReaders: ::c_int, + pendingWriters: ::c_int, + attr: i32, + __reserved: [::c_char; 36], + } + + pub struct sigset64_t { + __bits: [::c_ulong; 1] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.value == other.value + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + .field("value", &self.value) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.value.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.value == other.value + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + .field("value", &self.value) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.value.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.numLocks == other.numLocks + && self.writerThreadId == other.writerThreadId + && self.pendingReaders == other.pendingReaders + && self.pendingWriters == other.pendingWriters + && self.attr == other.attr + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_rwlock_t {} + + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("numLocks", &self.numLocks) + .field("writerThreadId", &self.writerThreadId) + .field("pendingReaders", &self.pendingReaders) + .field("pendingWriters", &self.pendingWriters) + .field("attr", &self.attr) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.numLocks.hash(state); + self.writerThreadId.hash(state); + self.pendingReaders.hash(state); + self.pendingWriters.hash(state); + self.attr.hash(state); + self.__reserved.hash(state); + } + } + + impl ::fmt::Debug for sigset64_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigset64_t") + .field("__bits", &self.__bits) + .finish() + } + } + } +} + +// These constants must be of the same type of sigaction.sa_flags +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; + +pub const RTLD_GLOBAL: ::c_int = 0x00100; +pub const RTLD_NOW: ::c_int = 2; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; + +// From NDK's linux/auxvec.h +pub const AT_NULL: ::c_ulong = 0; +pub const AT_IGNORE: ::c_ulong = 1; +pub const AT_EXECFD: ::c_ulong = 2; +pub const AT_PHDR: ::c_ulong = 3; +pub const AT_PHENT: ::c_ulong = 4; +pub const AT_PHNUM: ::c_ulong = 5; +pub const AT_PAGESZ: ::c_ulong = 6; +pub const AT_BASE: ::c_ulong = 7; +pub const AT_FLAGS: ::c_ulong = 8; +pub const AT_ENTRY: ::c_ulong = 9; +pub const AT_NOTELF: ::c_ulong = 10; +pub const AT_UID: ::c_ulong = 11; +pub const AT_EUID: ::c_ulong = 12; +pub const AT_GID: ::c_ulong = 13; +pub const AT_EGID: ::c_ulong = 14; +pub const AT_PLATFORM: ::c_ulong = 15; +pub const AT_HWCAP: ::c_ulong = 16; +pub const AT_CLKTCK: ::c_ulong = 17; +pub const AT_SECURE: ::c_ulong = 23; +pub const AT_BASE_PLATFORM: ::c_ulong = 24; +pub const AT_RANDOM: ::c_ulong = 25; +pub const AT_HWCAP2: ::c_ulong = 26; +pub const AT_EXECFN: ::c_ulong = 31; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + value: 0, + __reserved: [0; 36], +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + value: 0, + __reserved: [0; 44], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + numLocks: 0, + writerThreadId: 0, + pendingReaders: 0, + pendingWriters: 0, + attr: 0, + __reserved: [0; 36], +}; +pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 4; +pub const CPU_SETSIZE: ::size_t = 1024; +pub const __CPU_BITS: ::size_t = 64; + +pub const UT_LINESIZE: usize = 32; +pub const UT_NAMESIZE: usize = 32; +pub const UT_HOSTSIZE: usize = 256; + +f! { + // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not + // exposed by the libc. As work-around, we implement it through `syscall` + // directly. This workaround can be removed if the minimum version of + // Android is bumped. When the workaround is removed, `accept4` can be + // moved back to `linux_like/mod.rs` + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int + ) -> ::c_int { + ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int + } +} + +extern "C" { + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; + pub fn __system_property_wait( + pi: *const ::prop_info, + __old_serial: u32, + __new_serial_ptr: *mut u32, + __relative_timeout: *const ::timespec, + ) -> bool; +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "riscv64")] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs new file mode 100644 index 00000000..8e949963 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs new file mode 100644 index 00000000..9d414dc1 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs @@ -0,0 +1,353 @@ +pub type c_char = i8; +pub type wchar_t = u32; +pub type greg_t = i64; +pub type __u64 = ::c_ulonglong; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::c_uint, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::c_ulong, + pub st_size: ::off64_t, + pub st_blksize: ::c_int, + __pad2: ::c_int, + pub st_blocks: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused4: ::c_uint, + __unused5: ::c_uint, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::c_uint, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::c_ulong, + pub st_size: ::off64_t, + pub st_blksize: ::c_int, + __pad2: ::c_int, + pub st_blocks: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused4: ::c_uint, + __unused5: ::c_uint, + } +} + +pub const O_DIRECT: ::c_int = 0x40000; +pub const O_DIRECTORY: ::c_int = 0x200000; +pub const O_NOFOLLOW: ::c_int = 0x400000; +pub const O_LARGEFILE: ::c_int = 0x100000; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +// From NDK's asm/hwcap.h +pub const COMPAT_HWCAP_ISA_I: ::c_ulong = 1 << (b'I' - b'A'); +pub const COMPAT_HWCAP_ISA_M: ::c_ulong = 1 << (b'M' - b'A'); +pub const COMPAT_HWCAP_ISA_A: ::c_ulong = 1 << (b'A' - b'A'); +pub const COMPAT_HWCAP_ISA_F: ::c_ulong = 1 << (b'F' - b'A'); +pub const COMPAT_HWCAP_ISA_D: ::c_ulong = 1 << (b'D' - b'A'); +pub const COMPAT_HWCAP_ISA_C: ::c_ulong = 1 << (b'C' - b'A'); + +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_dup: ::c_long = 23; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_flock: ::c_long = 32; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_renameat: ::c_long = 38; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_mount: ::c_long = 40; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_openat: ::c_long = 56; +pub const SYS_close: ::c_long = 57; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_sync: ::c_long = 81; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_acct: ::c_long = 89; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_personality: ::c_long = 92; +pub const SYS_exit: ::c_long = 93; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_futex: ::c_long = 98; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_kill: ::c_long = 129; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_times: ::c_long = 153; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_uname: ::c_long = 160; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_umask: ::c_long = 166; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_semop: ::c_long = 193; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_socket: ::c_long = 198; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_accept: ::c_long = 202; +pub const SYS_connect: ::c_long = 203; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_brk: ::c_long = 214; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_arch_specific_syscall: ::c_long = 244; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_setns: ::c_long = 268; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_syscalls: ::c_long = 436; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/align.rs new file mode 100644 index 00000000..7ca870fd --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs new file mode 100644 index 00000000..be6b5011 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs @@ -0,0 +1,802 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type greg_t = i64; +pub type __u64 = ::c_ulonglong; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::c_ulong, + pub st_mode: ::c_uint, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::c_long, + pub st_blocks: ::c_long, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::c_ulong, + pub st_mode: ::c_uint, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::c_long, + pub st_blocks: ::c_long, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct _libc_xmmreg { + pub element: [u32; 4], + } + + pub struct user_regs_struct { + pub r15: ::c_ulong, + pub r14: ::c_ulong, + pub r13: ::c_ulong, + pub r12: ::c_ulong, + pub rbp: ::c_ulong, + pub rbx: ::c_ulong, + pub r11: ::c_ulong, + pub r10: ::c_ulong, + pub r9: ::c_ulong, + pub r8: ::c_ulong, + pub rax: ::c_ulong, + pub rcx: ::c_ulong, + pub rdx: ::c_ulong, + pub rsi: ::c_ulong, + pub rdi: ::c_ulong, + pub orig_rax: ::c_ulong, + pub rip: ::c_ulong, + pub cs: ::c_ulong, + pub eflags: ::c_ulong, + pub rsp: ::c_ulong, + pub ss: ::c_ulong, + pub fs_base: ::c_ulong, + pub gs_base: ::c_ulong, + pub ds: ::c_ulong, + pub es: ::c_ulong, + pub fs: ::c_ulong, + pub gs: ::c_ulong, + } + + pub struct user { + pub regs: user_regs_struct, + pub u_fpvalid: ::c_int, + pub i387: user_fpregs_struct, + pub u_tsize: ::c_ulong, + pub u_dsize: ::c_ulong, + pub u_ssize: ::c_ulong, + pub start_code: ::c_ulong, + pub start_stack: ::c_ulong, + pub signal: ::c_long, + __reserved: ::c_int, + #[cfg(target_pointer_width = "32")] + __pad1: u32, + pub u_ar0: *mut user_regs_struct, + #[cfg(target_pointer_width = "32")] + __pad2: u32, + pub u_fpstate: *mut user_fpregs_struct, + pub magic: ::c_ulong, + pub u_comm: [::c_char; 32], + pub u_debugreg: [::c_ulong; 8], + pub error_code: ::c_ulong, + pub fault_address: ::c_ulong, + } + +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub union __c_anonymous_uc_sigmask { + uc_sigmask: ::sigset_t, + uc_sigmask64: ::sigset64_t, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_uc_sigmask { + fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { + unsafe { self.uc_sigmask == other.uc_sigmask } + } + } + impl Eq for __c_anonymous_uc_sigmask {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask") + .field("uc_sigmask", unsafe { &self.uc_sigmask }) + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + } + } + } +} + +s_no_extra_traits! { + pub struct _libc_fpxreg { + pub significand: [u16; 4], + pub exponent: u16, + __padding: [u16; 3], + } + + pub struct _libc_fpstate { + pub cwd: u16, + pub swd: u16, + pub ftw: u16, + pub fop: u16, + pub rip: u64, + pub rdp: u64, + pub mxcsr: u32, + pub mxcr_mask: u32, + pub _st: [_libc_fpxreg; 8], + pub _xmm: [_libc_xmmreg; 16], + __private: [u32; 24], + } + + pub struct mcontext_t { + pub gregs: [greg_t; 23], + pub fpregs: *mut _libc_fpstate, + __private: [u64; 8], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask64: __c_anonymous_uc_sigmask, + __fpregs_mem: _libc_fpstate, + } + + pub struct user_fpregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub ftw: ::c_ushort, + pub fop: ::c_ushort, + pub rip: ::c_ulong, + pub rdp: ::c_ulong, + pub mxcsr: ::c_uint, + pub mxcr_mask: ::c_uint, + pub st_space: [::c_uint; 32], + pub xmm_space: [::c_uint; 64], + padding: [::c_uint; 24], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for _libc_fpxreg { + fn eq(&self, other: &Self) -> bool { + self.significand == other.significand + && self.exponent == other.exponent + // Ignore padding field + } + } + impl Eq for _libc_fpxreg {} + impl ::fmt::Debug for _libc_fpxreg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("_libc_fpxreg") + .field("significand", &self.significand) + .field("exponent", &self.exponent) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for _libc_fpxreg { + fn hash(&self, state: &mut H) { + self.significand.hash(state); + self.exponent.hash(state); + // Ignore padding field + } + } + + impl PartialEq for _libc_fpstate { + fn eq(&self, other: &Self) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.ftw == other.ftw + && self.fop == other.fop + && self.rip == other.rip + && self.rdp == other.rdp + && self.mxcsr == other.mxcsr + && self.mxcr_mask == other.mxcr_mask + && self._st == other._st + && self._xmm == other._xmm + // Ignore padding field + } + } + impl Eq for _libc_fpstate {} + impl ::fmt::Debug for _libc_fpstate { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("_libc_fpstate") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("ftw", &self.ftw) + .field("fop", &self.fop) + .field("rip", &self.rip) + .field("rdp", &self.rdp) + .field("mxcsr", &self.mxcsr) + .field("mxcr_mask", &self.mxcr_mask) + .field("_st", &self._st) + .field("_xmm", &self._xmm) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for _libc_fpstate { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.ftw.hash(state); + self.fop.hash(state); + self.rip.hash(state); + self.rdp.hash(state); + self.mxcsr.hash(state); + self.mxcr_mask.hash(state); + self._st.hash(state); + self._xmm.hash(state); + // Ignore padding field + } + } + + impl PartialEq for mcontext_t { + fn eq(&self, other: &Self) -> bool { + self.gregs == other.gregs + && self.fpregs == other.fpregs + // Ignore padding field + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("gregs", &self.gregs) + .field("fpregs", &self.fpregs) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.gregs.hash(state); + self.fpregs.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &Self) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask64 == other.uc_sigmask64 + // Ignore padding field + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask64", &self.uc_sigmask64) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask64.hash(state); + // Ignore padding field + } + } + + impl PartialEq for user_fpregs_struct { + fn eq(&self, other: &user_fpregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.ftw == other.ftw + && self.fop == other.fop + && self.rip == other.rip + && self.rdp == other.rdp + && self.mxcsr == other.mxcsr + && self.mxcr_mask == other.mxcr_mask + && self.st_space == other.st_space + && self + .xmm_space + .iter() + .zip(other.xmm_space.iter()) + .all(|(a,b)| a == b) + // Ignore padding field + } + } + + impl Eq for user_fpregs_struct {} + + impl ::fmt::Debug for user_fpregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpregs_struct") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("ftw", &self.ftw) + .field("fop", &self.fop) + .field("rip", &self.rip) + .field("rdp", &self.rdp) + .field("mxcsr", &self.mxcsr) + .field("mxcr_mask", &self.mxcr_mask) + .field("st_space", &self.st_space) + // FIXME: .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.ftw.hash(state); + self.fop.hash(state); + self.rip.hash(state); + self.rdp.hash(state); + self.mxcsr.hash(state); + self.mxcr_mask.hash(state); + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + } +} + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const MAP_32BIT: ::c_int = 0x40; + +// Syscall table + +pub const SYS_read: ::c_long = 0; +pub const SYS_write: ::c_long = 1; +pub const SYS_open: ::c_long = 2; +pub const SYS_close: ::c_long = 3; +pub const SYS_stat: ::c_long = 4; +pub const SYS_fstat: ::c_long = 5; +pub const SYS_lstat: ::c_long = 6; +pub const SYS_poll: ::c_long = 7; +pub const SYS_lseek: ::c_long = 8; +pub const SYS_mmap: ::c_long = 9; +pub const SYS_mprotect: ::c_long = 10; +pub const SYS_munmap: ::c_long = 11; +pub const SYS_brk: ::c_long = 12; +pub const SYS_rt_sigaction: ::c_long = 13; +pub const SYS_rt_sigprocmask: ::c_long = 14; +pub const SYS_rt_sigreturn: ::c_long = 15; +pub const SYS_ioctl: ::c_long = 16; +pub const SYS_pread64: ::c_long = 17; +pub const SYS_pwrite64: ::c_long = 18; +pub const SYS_readv: ::c_long = 19; +pub const SYS_writev: ::c_long = 20; +pub const SYS_access: ::c_long = 21; +pub const SYS_pipe: ::c_long = 22; +pub const SYS_select: ::c_long = 23; +pub const SYS_sched_yield: ::c_long = 24; +pub const SYS_mremap: ::c_long = 25; +pub const SYS_msync: ::c_long = 26; +pub const SYS_mincore: ::c_long = 27; +pub const SYS_madvise: ::c_long = 28; +pub const SYS_shmget: ::c_long = 29; +pub const SYS_shmat: ::c_long = 30; +pub const SYS_shmctl: ::c_long = 31; +pub const SYS_dup: ::c_long = 32; +pub const SYS_dup2: ::c_long = 33; +pub const SYS_pause: ::c_long = 34; +pub const SYS_nanosleep: ::c_long = 35; +pub const SYS_getitimer: ::c_long = 36; +pub const SYS_alarm: ::c_long = 37; +pub const SYS_setitimer: ::c_long = 38; +pub const SYS_getpid: ::c_long = 39; +pub const SYS_sendfile: ::c_long = 40; +pub const SYS_socket: ::c_long = 41; +pub const SYS_connect: ::c_long = 42; +pub const SYS_accept: ::c_long = 43; +pub const SYS_sendto: ::c_long = 44; +pub const SYS_recvfrom: ::c_long = 45; +pub const SYS_sendmsg: ::c_long = 46; +pub const SYS_recvmsg: ::c_long = 47; +pub const SYS_shutdown: ::c_long = 48; +pub const SYS_bind: ::c_long = 49; +pub const SYS_listen: ::c_long = 50; +pub const SYS_getsockname: ::c_long = 51; +pub const SYS_getpeername: ::c_long = 52; +pub const SYS_socketpair: ::c_long = 53; +pub const SYS_setsockopt: ::c_long = 54; +pub const SYS_getsockopt: ::c_long = 55; +pub const SYS_clone: ::c_long = 56; +pub const SYS_fork: ::c_long = 57; +pub const SYS_vfork: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_exit: ::c_long = 60; +pub const SYS_wait4: ::c_long = 61; +pub const SYS_kill: ::c_long = 62; +pub const SYS_uname: ::c_long = 63; +pub const SYS_semget: ::c_long = 64; +pub const SYS_semop: ::c_long = 65; +pub const SYS_semctl: ::c_long = 66; +pub const SYS_shmdt: ::c_long = 67; +pub const SYS_msgget: ::c_long = 68; +pub const SYS_msgsnd: ::c_long = 69; +pub const SYS_msgrcv: ::c_long = 70; +pub const SYS_msgctl: ::c_long = 71; +pub const SYS_fcntl: ::c_long = 72; +pub const SYS_flock: ::c_long = 73; +pub const SYS_fsync: ::c_long = 74; +pub const SYS_fdatasync: ::c_long = 75; +pub const SYS_truncate: ::c_long = 76; +pub const SYS_ftruncate: ::c_long = 77; +pub const SYS_getdents: ::c_long = 78; +pub const SYS_getcwd: ::c_long = 79; +pub const SYS_chdir: ::c_long = 80; +pub const SYS_fchdir: ::c_long = 81; +pub const SYS_rename: ::c_long = 82; +pub const SYS_mkdir: ::c_long = 83; +pub const SYS_rmdir: ::c_long = 84; +pub const SYS_creat: ::c_long = 85; +pub const SYS_link: ::c_long = 86; +pub const SYS_unlink: ::c_long = 87; +pub const SYS_symlink: ::c_long = 88; +pub const SYS_readlink: ::c_long = 89; +pub const SYS_chmod: ::c_long = 90; +pub const SYS_fchmod: ::c_long = 91; +pub const SYS_chown: ::c_long = 92; +pub const SYS_fchown: ::c_long = 93; +pub const SYS_lchown: ::c_long = 94; +pub const SYS_umask: ::c_long = 95; +pub const SYS_gettimeofday: ::c_long = 96; +pub const SYS_getrlimit: ::c_long = 97; +pub const SYS_getrusage: ::c_long = 98; +pub const SYS_sysinfo: ::c_long = 99; +pub const SYS_times: ::c_long = 100; +pub const SYS_ptrace: ::c_long = 101; +pub const SYS_getuid: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_getgid: ::c_long = 104; +pub const SYS_setuid: ::c_long = 105; +pub const SYS_setgid: ::c_long = 106; +pub const SYS_geteuid: ::c_long = 107; +pub const SYS_getegid: ::c_long = 108; +pub const SYS_setpgid: ::c_long = 109; +pub const SYS_getppid: ::c_long = 110; +pub const SYS_getpgrp: ::c_long = 111; +pub const SYS_setsid: ::c_long = 112; +pub const SYS_setreuid: ::c_long = 113; +pub const SYS_setregid: ::c_long = 114; +pub const SYS_getgroups: ::c_long = 115; +pub const SYS_setgroups: ::c_long = 116; +pub const SYS_setresuid: ::c_long = 117; +pub const SYS_getresuid: ::c_long = 118; +pub const SYS_setresgid: ::c_long = 119; +pub const SYS_getresgid: ::c_long = 120; +pub const SYS_getpgid: ::c_long = 121; +pub const SYS_setfsuid: ::c_long = 122; +pub const SYS_setfsgid: ::c_long = 123; +pub const SYS_getsid: ::c_long = 124; +pub const SYS_capget: ::c_long = 125; +pub const SYS_capset: ::c_long = 126; +pub const SYS_rt_sigpending: ::c_long = 127; +pub const SYS_rt_sigtimedwait: ::c_long = 128; +pub const SYS_rt_sigqueueinfo: ::c_long = 129; +pub const SYS_rt_sigsuspend: ::c_long = 130; +pub const SYS_sigaltstack: ::c_long = 131; +pub const SYS_utime: ::c_long = 132; +pub const SYS_mknod: ::c_long = 133; +pub const SYS_uselib: ::c_long = 134; +pub const SYS_personality: ::c_long = 135; +pub const SYS_ustat: ::c_long = 136; +pub const SYS_statfs: ::c_long = 137; +pub const SYS_fstatfs: ::c_long = 138; +pub const SYS_sysfs: ::c_long = 139; +pub const SYS_getpriority: ::c_long = 140; +pub const SYS_setpriority: ::c_long = 141; +pub const SYS_sched_setparam: ::c_long = 142; +pub const SYS_sched_getparam: ::c_long = 143; +pub const SYS_sched_setscheduler: ::c_long = 144; +pub const SYS_sched_getscheduler: ::c_long = 145; +pub const SYS_sched_get_priority_max: ::c_long = 146; +pub const SYS_sched_get_priority_min: ::c_long = 147; +pub const SYS_sched_rr_get_interval: ::c_long = 148; +pub const SYS_mlock: ::c_long = 149; +pub const SYS_munlock: ::c_long = 150; +pub const SYS_mlockall: ::c_long = 151; +pub const SYS_munlockall: ::c_long = 152; +pub const SYS_vhangup: ::c_long = 153; +pub const SYS_modify_ldt: ::c_long = 154; +pub const SYS_pivot_root: ::c_long = 155; +// FIXME: SYS__sysctl is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__sysctl: ::c_long = 156; +pub const SYS_prctl: ::c_long = 157; +pub const SYS_arch_prctl: ::c_long = 158; +pub const SYS_adjtimex: ::c_long = 159; +pub const SYS_setrlimit: ::c_long = 160; +pub const SYS_chroot: ::c_long = 161; +pub const SYS_sync: ::c_long = 162; +pub const SYS_acct: ::c_long = 163; +pub const SYS_settimeofday: ::c_long = 164; +pub const SYS_mount: ::c_long = 165; +pub const SYS_umount2: ::c_long = 166; +pub const SYS_swapon: ::c_long = 167; +pub const SYS_swapoff: ::c_long = 168; +pub const SYS_reboot: ::c_long = 169; +pub const SYS_sethostname: ::c_long = 170; +pub const SYS_setdomainname: ::c_long = 171; +pub const SYS_iopl: ::c_long = 172; +pub const SYS_ioperm: ::c_long = 173; +pub const SYS_create_module: ::c_long = 174; +pub const SYS_init_module: ::c_long = 175; +pub const SYS_delete_module: ::c_long = 176; +pub const SYS_get_kernel_syms: ::c_long = 177; +pub const SYS_query_module: ::c_long = 178; +pub const SYS_quotactl: ::c_long = 179; +pub const SYS_nfsservctl: ::c_long = 180; +pub const SYS_getpmsg: ::c_long = 181; +pub const SYS_putpmsg: ::c_long = 182; +pub const SYS_afs_syscall: ::c_long = 183; +pub const SYS_tuxcall: ::c_long = 184; +pub const SYS_security: ::c_long = 185; +pub const SYS_gettid: ::c_long = 186; +pub const SYS_readahead: ::c_long = 187; +pub const SYS_setxattr: ::c_long = 188; +pub const SYS_lsetxattr: ::c_long = 189; +pub const SYS_fsetxattr: ::c_long = 190; +pub const SYS_getxattr: ::c_long = 191; +pub const SYS_lgetxattr: ::c_long = 192; +pub const SYS_fgetxattr: ::c_long = 193; +pub const SYS_listxattr: ::c_long = 194; +pub const SYS_llistxattr: ::c_long = 195; +pub const SYS_flistxattr: ::c_long = 196; +pub const SYS_removexattr: ::c_long = 197; +pub const SYS_lremovexattr: ::c_long = 198; +pub const SYS_fremovexattr: ::c_long = 199; +pub const SYS_tkill: ::c_long = 200; +pub const SYS_time: ::c_long = 201; +pub const SYS_futex: ::c_long = 202; +pub const SYS_sched_setaffinity: ::c_long = 203; +pub const SYS_sched_getaffinity: ::c_long = 204; +pub const SYS_set_thread_area: ::c_long = 205; +pub const SYS_io_setup: ::c_long = 206; +pub const SYS_io_destroy: ::c_long = 207; +pub const SYS_io_getevents: ::c_long = 208; +pub const SYS_io_submit: ::c_long = 209; +pub const SYS_io_cancel: ::c_long = 210; +pub const SYS_get_thread_area: ::c_long = 211; +pub const SYS_lookup_dcookie: ::c_long = 212; +pub const SYS_epoll_create: ::c_long = 213; +pub const SYS_epoll_ctl_old: ::c_long = 214; +pub const SYS_epoll_wait_old: ::c_long = 215; +pub const SYS_remap_file_pages: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_set_tid_address: ::c_long = 218; +pub const SYS_restart_syscall: ::c_long = 219; +pub const SYS_semtimedop: ::c_long = 220; +pub const SYS_fadvise64: ::c_long = 221; +pub const SYS_timer_create: ::c_long = 222; +pub const SYS_timer_settime: ::c_long = 223; +pub const SYS_timer_gettime: ::c_long = 224; +pub const SYS_timer_getoverrun: ::c_long = 225; +pub const SYS_timer_delete: ::c_long = 226; +pub const SYS_clock_settime: ::c_long = 227; +pub const SYS_clock_gettime: ::c_long = 228; +pub const SYS_clock_getres: ::c_long = 229; +pub const SYS_clock_nanosleep: ::c_long = 230; +pub const SYS_exit_group: ::c_long = 231; +pub const SYS_epoll_wait: ::c_long = 232; +pub const SYS_epoll_ctl: ::c_long = 233; +pub const SYS_tgkill: ::c_long = 234; +pub const SYS_utimes: ::c_long = 235; +pub const SYS_vserver: ::c_long = 236; +pub const SYS_mbind: ::c_long = 237; +pub const SYS_set_mempolicy: ::c_long = 238; +pub const SYS_get_mempolicy: ::c_long = 239; +pub const SYS_mq_open: ::c_long = 240; +pub const SYS_mq_unlink: ::c_long = 241; +pub const SYS_mq_timedsend: ::c_long = 242; +pub const SYS_mq_timedreceive: ::c_long = 243; +pub const SYS_mq_notify: ::c_long = 244; +pub const SYS_mq_getsetattr: ::c_long = 245; +pub const SYS_kexec_load: ::c_long = 246; +pub const SYS_waitid: ::c_long = 247; +pub const SYS_add_key: ::c_long = 248; +pub const SYS_request_key: ::c_long = 249; +pub const SYS_keyctl: ::c_long = 250; +pub const SYS_ioprio_set: ::c_long = 251; +pub const SYS_ioprio_get: ::c_long = 252; +pub const SYS_inotify_init: ::c_long = 253; +pub const SYS_inotify_add_watch: ::c_long = 254; +pub const SYS_inotify_rm_watch: ::c_long = 255; +pub const SYS_migrate_pages: ::c_long = 256; +pub const SYS_openat: ::c_long = 257; +pub const SYS_mkdirat: ::c_long = 258; +pub const SYS_mknodat: ::c_long = 259; +pub const SYS_fchownat: ::c_long = 260; +pub const SYS_futimesat: ::c_long = 261; +pub const SYS_newfstatat: ::c_long = 262; +pub const SYS_unlinkat: ::c_long = 263; +pub const SYS_renameat: ::c_long = 264; +pub const SYS_linkat: ::c_long = 265; +pub const SYS_symlinkat: ::c_long = 266; +pub const SYS_readlinkat: ::c_long = 267; +pub const SYS_fchmodat: ::c_long = 268; +pub const SYS_faccessat: ::c_long = 269; +pub const SYS_pselect6: ::c_long = 270; +pub const SYS_ppoll: ::c_long = 271; +pub const SYS_unshare: ::c_long = 272; +pub const SYS_set_robust_list: ::c_long = 273; +pub const SYS_get_robust_list: ::c_long = 274; +pub const SYS_splice: ::c_long = 275; +pub const SYS_tee: ::c_long = 276; +pub const SYS_sync_file_range: ::c_long = 277; +pub const SYS_vmsplice: ::c_long = 278; +pub const SYS_move_pages: ::c_long = 279; +pub const SYS_utimensat: ::c_long = 280; +pub const SYS_epoll_pwait: ::c_long = 281; +pub const SYS_signalfd: ::c_long = 282; +pub const SYS_timerfd_create: ::c_long = 283; +pub const SYS_eventfd: ::c_long = 284; +pub const SYS_fallocate: ::c_long = 285; +pub const SYS_timerfd_settime: ::c_long = 286; +pub const SYS_timerfd_gettime: ::c_long = 287; +pub const SYS_accept4: ::c_long = 288; +pub const SYS_signalfd4: ::c_long = 289; +pub const SYS_eventfd2: ::c_long = 290; +pub const SYS_epoll_create1: ::c_long = 291; +pub const SYS_dup3: ::c_long = 292; +pub const SYS_pipe2: ::c_long = 293; +pub const SYS_inotify_init1: ::c_long = 294; +pub const SYS_preadv: ::c_long = 295; +pub const SYS_pwritev: ::c_long = 296; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 297; +pub const SYS_perf_event_open: ::c_long = 298; +pub const SYS_recvmmsg: ::c_long = 299; +pub const SYS_fanotify_init: ::c_long = 300; +pub const SYS_fanotify_mark: ::c_long = 301; +pub const SYS_prlimit64: ::c_long = 302; +pub const SYS_name_to_handle_at: ::c_long = 303; +pub const SYS_open_by_handle_at: ::c_long = 304; +pub const SYS_clock_adjtime: ::c_long = 305; +pub const SYS_syncfs: ::c_long = 306; +pub const SYS_sendmmsg: ::c_long = 307; +pub const SYS_setns: ::c_long = 308; +pub const SYS_getcpu: ::c_long = 309; +pub const SYS_process_vm_readv: ::c_long = 310; +pub const SYS_process_vm_writev: ::c_long = 311; +pub const SYS_kcmp: ::c_long = 312; +pub const SYS_finit_module: ::c_long = 313; +pub const SYS_sched_setattr: ::c_long = 314; +pub const SYS_sched_getattr: ::c_long = 315; +pub const SYS_renameat2: ::c_long = 316; +pub const SYS_seccomp: ::c_long = 317; +pub const SYS_getrandom: ::c_long = 318; +pub const SYS_memfd_create: ::c_long = 319; +pub const SYS_kexec_file_load: ::c_long = 320; +pub const SYS_bpf: ::c_long = 321; +pub const SYS_execveat: ::c_long = 322; +pub const SYS_userfaultfd: ::c_long = 323; +pub const SYS_membarrier: ::c_long = 324; +pub const SYS_mlock2: ::c_long = 325; +pub const SYS_copy_file_range: ::c_long = 326; +pub const SYS_preadv2: ::c_long = 327; +pub const SYS_pwritev2: ::c_long = 328; +pub const SYS_pkey_mprotect: ::c_long = 329; +pub const SYS_pkey_alloc: ::c_long = 330; +pub const SYS_pkey_free: ::c_long = 331; +pub const SYS_statx: ::c_long = 332; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_R8: ::c_int = 0; +pub const REG_R9: ::c_int = 1; +pub const REG_R10: ::c_int = 2; +pub const REG_R11: ::c_int = 3; +pub const REG_R12: ::c_int = 4; +pub const REG_R13: ::c_int = 5; +pub const REG_R14: ::c_int = 6; +pub const REG_R15: ::c_int = 7; +pub const REG_RDI: ::c_int = 8; +pub const REG_RSI: ::c_int = 9; +pub const REG_RBP: ::c_int = 10; +pub const REG_RBX: ::c_int = 11; +pub const REG_RDX: ::c_int = 12; +pub const REG_RAX: ::c_int = 13; +pub const REG_RCX: ::c_int = 14; +pub const REG_RSP: ::c_int = 15; +pub const REG_RIP: ::c_int = 16; +pub const REG_EFL: ::c_int = 17; +pub const REG_CSGSFS: ::c_int = 18; +pub const REG_ERR: ::c_int = 19; +pub const REG_TRAPNO: ::c_int = 20; +pub const REG_OLDMASK: ::c_int = 21; +pub const REG_CR2: ::c_int = 22; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/mod.rs new file mode 100644 index 00000000..2c1c1e9b --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/android/mod.rs @@ -0,0 +1,4176 @@ +//! Android-specific definitions for linux-like values + +pub type clock_t = ::c_long; +pub type time_t = ::c_long; +pub type suseconds_t = ::c_long; +pub type off_t = ::c_long; +pub type blkcnt_t = ::c_ulong; +pub type blksize_t = ::c_ulong; +pub type nlink_t = u32; +pub type useconds_t = u32; +pub type pthread_t = ::c_long; +pub type pthread_mutexattr_t = ::c_long; +pub type pthread_rwlockattr_t = ::c_long; +pub type pthread_barrierattr_t = ::c_int; +pub type pthread_condattr_t = ::c_long; +pub type pthread_key_t = ::c_int; +pub type fsfilcnt_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulong; +pub type nfds_t = ::c_uint; +pub type rlim_t = ::c_ulong; +pub type dev_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type ino64_t = u64; +pub type __CPU_BITTYPE = ::c_ulong; +pub type idtype_t = ::c_int; +pub type loff_t = ::c_longlong; +pub type __kernel_loff_t = ::c_longlong; +pub type __kernel_pid_t = ::c_int; + +pub type __u8 = ::c_uchar; +pub type __u16 = ::c_ushort; +pub type __s16 = ::c_short; +pub type __u32 = ::c_uint; +pub type __s32 = ::c_int; + +// linux/elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Off = u32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Off = u64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +pub type eventfd_t = u64; + +s! { + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct __fsid_t { + __val: [::c_int; 2], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct termios2 { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; 19], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct mallinfo { + pub arena: ::size_t, + pub ordblks: ::size_t, + pub smblks: ::size_t, + pub hblks: ::size_t, + pub hblkhd: ::size_t, + pub usmblks: ::size_t, + pub fsmblks: ::size_t, + pub uordblks: ::size_t, + pub fordblks: ::size_t, + pub keepcost: ::size_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::__kernel_loff_t, + pub l_len: ::__kernel_loff_t, + pub l_pid: ::__kernel_pid_t, + } + + pub struct cpu_set_t { + #[cfg(target_pointer_width = "64")] + __bits: [__CPU_BITTYPE; 16], + #[cfg(target_pointer_width = "32")] + __bits: [__CPU_BITTYPE; 1], + } + + pub struct sem_t { + count: ::c_uint, + #[cfg(target_pointer_width = "64")] + __reserved: [::c_int; 3], + } + + pub struct exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + #[cfg(target_pointer_width = "64")] + __f_reserved: [u32; 6], + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: ::c_ulonglong, + pub ssi_utime: ::c_ulonglong, + pub ssi_stime: ::c_ulonglong, + pub ssi_addr: ::c_ulonglong, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + + pub struct genlmsghdr { + pub cmd: u8, + pub version: u8, + pub reserved: u16, + } + + pub struct nlmsghdr { + pub nlmsg_len: u32, + pub nlmsg_type: u16, + pub nlmsg_flags: u16, + pub nlmsg_seq: u32, + pub nlmsg_pid: u32, + } + + pub struct nlmsgerr { + pub error: ::c_int, + pub msg: nlmsghdr, + } + + pub struct nl_pktinfo { + pub group: u32, + } + + pub struct nl_mmap_req { + pub nm_block_size: ::c_uint, + pub nm_block_nr: ::c_uint, + pub nm_frame_size: ::c_uint, + pub nm_frame_nr: ::c_uint, + } + + pub struct nl_mmap_hdr { + pub nm_status: ::c_uint, + pub nm_len: ::c_uint, + pub nm_group: u32, + pub nm_pid: u32, + pub nm_uid: u32, + pub nm_gid: u32, + } + + pub struct nlattr { + pub nla_len: u16, + pub nla_type: u16, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_int, + } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: u32, + pub cookie: u32, + pub len: u32 + } + + pub struct sock_extended_err { + pub ee_errno: u32, + pub ee_origin: u8, + pub ee_type: u8, + pub ee_code: u8, + pub ee_pad: u8, + pub ee_info: u32, + pub ee_data: u32, + } + + pub struct regex_t { + re_magic: ::c_int, + re_nsub: ::size_t, + re_endp: *const ::c_char, + re_guts: *mut ::c_void, + } + + pub struct regmatch_t { + pub rm_so: ::ssize_t, + pub rm_eo: ::ssize_t, + } + + pub struct sockaddr_vm { + pub svm_family: ::sa_family_t, + pub svm_reserved1: ::c_ushort, + pub svm_port: ::c_uint, + pub svm_cid: ::c_uint, + pub svm_zero: [u8; 4] + } + + // linux/elf.h + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + // link.h + + pub struct dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + // These fields were added in Android R + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } + + // linux/filter.h + pub struct sock_filter { + pub code: ::__u16, + pub jt: ::__u8, + pub jf: ::__u8, + pub k: ::__u32, + } + + pub struct sock_fprog { + pub len: ::c_ushort, + pub filter: *mut sock_filter, + } + + // linux/seccomp.h + pub struct seccomp_data { + pub nr: ::c_int, + pub arch: ::__u32, + pub instruction_pointer: ::__u64, + pub args: [::__u64; 6], + } + + pub struct seccomp_metadata { + pub filter_off: ::__u64, + pub flags: ::__u64, + } + + pub struct ptrace_peeksiginfo_args { + pub off: ::__u64, + pub flags: ::__u32, + pub nr: ::__s32, + } + + // linux/input.h + pub struct input_event { + pub time: ::timeval, + pub type_: ::__u16, + pub code: ::__u16, + pub value: ::__s32, + } + + pub struct input_id { + pub bustype: ::__u16, + pub vendor: ::__u16, + pub product: ::__u16, + pub version: ::__u16, + } + + pub struct input_absinfo { + pub value: ::__s32, + pub minimum: ::__s32, + pub maximum: ::__s32, + pub fuzz: ::__s32, + pub flat: ::__s32, + pub resolution: ::__s32, + } + + pub struct input_keymap_entry { + pub flags: ::__u8, + pub len: ::__u8, + pub index: ::__u16, + pub keycode: ::__u32, + pub scancode: [::__u8; 32], + } + + pub struct input_mask { + pub type_: ::__u32, + pub codes_size: ::__u32, + pub codes_ptr: ::__u64, + } + + pub struct ff_replay { + pub length: ::__u16, + pub delay: ::__u16, + } + + pub struct ff_trigger { + pub button: ::__u16, + pub interval: ::__u16, + } + + pub struct ff_envelope { + pub attack_length: ::__u16, + pub attack_level: ::__u16, + pub fade_length: ::__u16, + pub fade_level: ::__u16, + } + + pub struct ff_constant_effect { + pub level: ::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_ramp_effect { + pub start_level: ::__s16, + pub end_level: ::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_condition_effect { + pub right_saturation: ::__u16, + pub left_saturation: ::__u16, + + pub right_coeff: ::__s16, + pub left_coeff: ::__s16, + + pub deadband: ::__u16, + pub center: ::__s16, + } + + pub struct ff_periodic_effect { + pub waveform: ::__u16, + pub period: ::__u16, + pub magnitude: ::__s16, + pub offset: ::__s16, + pub phase: ::__u16, + + pub envelope: ff_envelope, + + pub custom_len: ::__u32, + pub custom_data: *mut ::__s16, + } + + pub struct ff_rumble_effect { + pub strong_magnitude: ::__u16, + pub weak_magnitude: ::__u16, + } + + pub struct ff_effect { + pub type_: ::__u16, + pub id: ::__s16, + pub direction: ::__u16, + pub trigger: ff_trigger, + pub replay: ff_replay, + // FIXME this is actually a union + #[cfg(target_pointer_width = "64")] + pub u: [u64; 4], + #[cfg(target_pointer_width = "32")] + pub u: [u32; 7], + } + + // linux/uinput.h + pub struct uinput_ff_upload { + pub request_id: ::__u32, + pub retval: ::__s32, + pub effect: ff_effect, + pub old: ff_effect, + } + + pub struct uinput_ff_erase { + pub request_id: ::__u32, + pub retval: ::__s32, + pub effect_id: ::__u32, + } + + pub struct uinput_abs_setup { + pub code: ::__u16, + pub absinfo: input_absinfo, + } + + pub struct option { + pub name: *const ::c_char, + pub has_arg: ::c_int, + pub flag: *mut ::c_int, + pub val: ::c_int, + } + + pub struct __c_anonymous_ifru_map { + pub mem_start: ::c_ulong, + pub mem_end: ::c_ulong, + pub base_addr: ::c_ushort, + pub irq: ::c_uchar, + pub dma: ::c_uchar, + pub port: ::c_uchar, + } + + pub struct in6_ifreq { + pub ifr6_addr: ::in6_addr, + pub ifr6_prefixlen: u32, + pub ifr6_ifindex: ::c_int, + } + +} + +s_no_extra_traits! { + pub struct sockaddr_nl { + pub nl_family: ::sa_family_t, + nl_pad: ::c_ushort, + pub nl_pid: u32, + pub nl_groups: u32 + } + + pub struct dirent { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct lastlog { + ll_time: ::time_t, + ll_line: [::c_char; UT_LINESIZE], + ll_host: [::c_char; UT_HOSTSIZE], + } + + pub struct utmp { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_id: [::c_char; 4], + pub ut_user: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_exit: exit_status, + pub ut_session: ::c_long, + pub ut_tv: ::timeval, + pub ut_addr_v6: [i32; 4], + unused: [::c_char; 20], + } + + pub struct sockaddr_alg { + pub salg_family: ::sa_family_t, + pub salg_type: [::c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [::c_uchar; 64], + } + + pub struct uinput_setup { + pub id: input_id, + pub name: [::c_char; UINPUT_MAX_NAME_SIZE], + pub ff_effects_max: ::__u32, + } + + pub struct uinput_user_dev { + pub name: [::c_char; UINPUT_MAX_NAME_SIZE], + pub id: input_id, + pub ff_effects_max: ::__u32, + pub absmax: [::__s32; ABS_CNT], + pub absmin: [::__s32; ABS_CNT], + pub absfuzz: [::__s32; ABS_CNT], + pub absflat: [::__s32; ABS_CNT], + } + + /// WARNING: The `PartialEq`, `Eq` and `Hash` implementations of this + /// type are unsound and will be removed in the future. + #[deprecated( + note = "this struct has unsafe trait implementations that will be \ + removed in the future", + since = "0.2.80" + )] + pub struct af_alg_iv { + pub ivlen: u32, + pub iv: [::c_uchar; 0], + } + + pub struct prop_info { + __name: [::c_char; 32], + __serial: ::c_uint, + __value: [[::c_char; 4]; 23], + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_netmask: ::sockaddr, + pub ifru_hwaddr: ::sockaddr, + pub ifru_flags: ::c_short, + pub ifru_ifindex: ::c_int, + pub ifru_metric: ::c_int, + pub ifru_mtu: ::c_int, + pub ifru_map: __c_anonymous_ifru_map, + pub ifru_slave: [::c_char; ::IFNAMSIZ], + pub ifru_newname: [::c_char; ::IFNAMSIZ], + pub ifru_data: *mut ::c_char, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [::c_char; ::IFNAMSIZ], + #[cfg(libc_union)] + pub ifr_ifru: __c_anonymous_ifr_ifru, + #[cfg(not(libc_union))] + pub ifr_ifru: ::sockaddr, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut ::c_char, + pub ifcu_req: *mut ::ifreq, + } + + /* Structure used in SIOCGIFCONF request. Used to retrieve interface + configuration for machine (useful for programs which must know all + networks accessible). */ + pub struct ifconf { + pub ifc_len: ::c_int, /* Size of buffer. */ + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ::ifreq, + } + +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_nl { + fn eq(&self, other: &sockaddr_nl) -> bool { + self.nl_family == other.nl_family && + self.nl_pid == other.nl_pid && + self.nl_groups == other.nl_groups + } + } + impl Eq for sockaddr_nl {} + impl ::fmt::Debug for sockaddr_nl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_nl") + .field("nl_family", &self.nl_family) + .field("nl_pid", &self.nl_pid) + .field("nl_groups", &self.nl_groups) + .finish() + } + } + impl ::hash::Hash for sockaddr_nl { + fn hash(&self, state: &mut H) { + self.nl_family.hash(state); + self.nl_pid.hash(state); + self.nl_groups.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent64 {} + + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_errno == other.si_errno + && self.si_code == other.si_code + // Ignore _pad + // Ignore _align + } + } + + impl Eq for siginfo_t {} + + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_errno", &self.si_errno) + .field("si_code", &self.si_code) + // Ignore _pad + // Ignore _align + .finish() + } + } + + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_errno.hash(state); + self.si_code.hash(state); + // Ignore _pad + // Ignore _align + } + } + + impl PartialEq for lastlog { + fn eq(&self, other: &lastlog) -> bool { + self.ll_time == other.ll_time + && self + .ll_line + .iter() + .zip(other.ll_line.iter()) + .all(|(a,b)| a == b) + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlog {} + + impl ::fmt::Debug for lastlog { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlog") + .field("ll_time", &self.ll_time) + .field("ll_line", &self.ll_line) + // FIXME: .field("ll_host", &self.ll_host) + .finish() + } + } + + impl ::hash::Hash for lastlog { + fn hash(&self, state: &mut H) { + self.ll_time.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + } + } + + impl PartialEq for utmp { + fn eq(&self, other: &utmp) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self + .ut_line + .iter() + .zip(other.ut_line.iter()) + .all(|(a,b)| a == b) + && self.ut_id == other.ut_id + && self + .ut_user + .iter() + .zip(other.ut_user.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.unused == other.unused + } + } + + impl Eq for utmp {} + + impl ::fmt::Debug for utmp { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmp") + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("unused", &self.unused) + .finish() + } + } + + impl ::hash::Hash for utmp { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.unused.hash(state); + } + } + + impl PartialEq for sockaddr_alg { + fn eq(&self, other: &sockaddr_alg) -> bool { + self.salg_family == other.salg_family + && self + .salg_type + .iter() + .zip(other.salg_type.iter()) + .all(|(a, b)| a == b) + && self.salg_feat == other.salg_feat + && self.salg_mask == other.salg_mask + && self + .salg_name + .iter() + .zip(other.salg_name.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_alg {} + + impl ::fmt::Debug for sockaddr_alg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_alg") + .field("salg_family", &self.salg_family) + .field("salg_type", &self.salg_type) + .field("salg_feat", &self.salg_feat) + .field("salg_mask", &self.salg_mask) + .field("salg_name", &&self.salg_name[..]) + .finish() + } + } + + impl ::hash::Hash for sockaddr_alg { + fn hash(&self, state: &mut H) { + self.salg_family.hash(state); + self.salg_type.hash(state); + self.salg_feat.hash(state); + self.salg_mask.hash(state); + self.salg_name.hash(state); + } + } + + impl PartialEq for uinput_setup { + fn eq(&self, other: &uinput_setup) -> bool { + self.id == other.id + && self.name[..] == other.name[..] + && self.ff_effects_max == other.ff_effects_max + } + } + impl Eq for uinput_setup {} + + impl ::fmt::Debug for uinput_setup { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uinput_setup") + .field("id", &self.id) + .field("name", &&self.name[..]) + .field("ff_effects_max", &self.ff_effects_max) + .finish() + } + } + + impl ::hash::Hash for uinput_setup { + fn hash(&self, state: &mut H) { + self.id.hash(state); + self.name.hash(state); + self.ff_effects_max.hash(state); + } + } + + impl PartialEq for uinput_user_dev { + fn eq(&self, other: &uinput_user_dev) -> bool { + self.name[..] == other.name[..] + && self.id == other.id + && self.ff_effects_max == other.ff_effects_max + && self.absmax[..] == other.absmax[..] + && self.absmin[..] == other.absmin[..] + && self.absfuzz[..] == other.absfuzz[..] + && self.absflat[..] == other.absflat[..] + } + } + impl Eq for uinput_user_dev {} + + impl ::fmt::Debug for uinput_user_dev { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uinput_setup") + .field("name", &&self.name[..]) + .field("id", &self.id) + .field("ff_effects_max", &self.ff_effects_max) + .field("absmax", &&self.absmax[..]) + .field("absmin", &&self.absmin[..]) + .field("absfuzz", &&self.absfuzz[..]) + .field("absflat", &&self.absflat[..]) + .finish() + } + } + + impl ::hash::Hash for uinput_user_dev { + fn hash(&self, state: &mut H) { + self.name.hash(state); + self.id.hash(state); + self.ff_effects_max.hash(state); + self.absmax.hash(state); + self.absmin.hash(state); + self.absfuzz.hash(state); + self.absflat.hash(state); + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifr_ifru { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifru_addr", unsafe { &self.ifru_addr }) + .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) + .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) + .field("ifru_netmask", unsafe { &self.ifru_netmask }) + .field("ifru_hwaddr", unsafe { &self.ifru_hwaddr }) + .field("ifru_flags", unsafe { &self.ifru_flags }) + .field("ifru_ifindex", unsafe { &self.ifru_ifindex }) + .field("ifru_metric", unsafe { &self.ifru_metric }) + .field("ifru_mtu", unsafe { &self.ifru_mtu }) + .field("ifru_map", unsafe { &self.ifru_map }) + .field("ifru_slave", unsafe { &self.ifru_slave }) + .field("ifru_newname", unsafe { &self.ifru_newname }) + .field("ifru_data", unsafe { &self.ifru_data }) + .finish() + } + } + impl ::fmt::Debug for ifreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifreq") + .field("ifr_name", &self.ifr_name) + .field("ifr_ifru", &self.ifr_ifru) + .finish() + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifcu_buf", unsafe { &self.ifcu_buf }) + .field("ifcu_req", unsafe { &self.ifcu_req }) + .finish() + } + } + impl ::fmt::Debug for ifconf { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifconf") + .field("ifc_len", &self.ifc_len) + .field("ifc_ifcu", &self.ifc_ifcu) + .finish() + } + } + + #[allow(deprecated)] + impl af_alg_iv { + fn as_slice(&self) -> &[u8] { + unsafe { + ::core::slice::from_raw_parts( + self.iv.as_ptr(), + self.ivlen as usize + ) + } + } + } + + #[allow(deprecated)] + impl PartialEq for af_alg_iv { + fn eq(&self, other: &af_alg_iv) -> bool { + *self.as_slice() == *other.as_slice() + } + } + + #[allow(deprecated)] + impl Eq for af_alg_iv {} + + #[allow(deprecated)] + impl ::fmt::Debug for af_alg_iv { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("af_alg_iv") + .field("ivlen", &self.ivlen) + .finish() + } + } + + #[allow(deprecated)] + impl ::hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } + } + + impl PartialEq for prop_info { + fn eq(&self, other: &prop_info) -> bool { + self.__name == other.__name && + self.__serial == other.__serial && + self.__value == other.__value + } + } + impl Eq for prop_info {} + impl ::fmt::Debug for prop_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("prop_info") + .field("__name", &self.__name) + .field("__serial", &self.__serial) + .field("__value", &self.__value) + .finish() + } + } + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MS_NOUSER: ::c_ulong = 0xffffffff80000000; +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +pub const O_TRUNC: ::c_int = 512; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_NOATIME: ::c_int = 0o1000000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +// sys/eventfd.h +pub const EFD_SEMAPHORE: ::c_int = 0x1; +pub const EFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const EFD_NONBLOCK: ::c_int = O_NONBLOCK; + +// sys/timerfd.h +pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const TFD_NONBLOCK: ::c_int = O_NONBLOCK; +pub const TFD_TIMER_ABSTIME: ::c_int = 1; +pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 2; + +pub const USER_PROCESS: ::c_short = 7; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +// linux/falloc.h +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +pub const FALLOC_FL_NO_HIDE_STALE: ::c_int = 0x04; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +pub const BUFSIZ: ::c_uint = 1024; +pub const FILENAME_MAX: ::c_uint = 4096; +pub const FOPEN_MAX: ::c_uint = 20; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +pub const L_tmpnam: ::c_uint = 4096; +pub const TMP_MAX: ::c_uint = 308915776; +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_2_SYMLINKS: ::c_int = 7; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 8; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 9; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 10; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 11; +pub const _PC_REC_XFER_ALIGN: ::c_int = 12; +pub const _PC_SYMLINK_MAX: ::c_int = 13; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 14; +pub const _PC_NO_TRUNC: ::c_int = 15; +pub const _PC_VDISABLE: ::c_int = 16; +pub const _PC_ASYNC_IO: ::c_int = 17; +pub const _PC_PRIO_IO: ::c_int = 18; +pub const _PC_SYNC_IO: ::c_int = 19; + +pub const FIONBIO: ::c_int = 0x5421; + +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_BC_BASE_MAX: ::c_int = 1; +pub const _SC_BC_DIM_MAX: ::c_int = 2; +pub const _SC_BC_SCALE_MAX: ::c_int = 3; +pub const _SC_BC_STRING_MAX: ::c_int = 4; +pub const _SC_CHILD_MAX: ::c_int = 5; +pub const _SC_CLK_TCK: ::c_int = 6; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 7; +pub const _SC_EXPR_NEST_MAX: ::c_int = 8; +pub const _SC_LINE_MAX: ::c_int = 9; +pub const _SC_NGROUPS_MAX: ::c_int = 10; +pub const _SC_OPEN_MAX: ::c_int = 11; +pub const _SC_PASS_MAX: ::c_int = 12; +pub const _SC_2_C_BIND: ::c_int = 13; +pub const _SC_2_C_DEV: ::c_int = 14; +pub const _SC_2_C_VERSION: ::c_int = 15; +pub const _SC_2_CHAR_TERM: ::c_int = 16; +pub const _SC_2_FORT_DEV: ::c_int = 17; +pub const _SC_2_FORT_RUN: ::c_int = 18; +pub const _SC_2_LOCALEDEF: ::c_int = 19; +pub const _SC_2_SW_DEV: ::c_int = 20; +pub const _SC_2_UPE: ::c_int = 21; +pub const _SC_2_VERSION: ::c_int = 22; +pub const _SC_JOB_CONTROL: ::c_int = 23; +pub const _SC_SAVED_IDS: ::c_int = 24; +pub const _SC_VERSION: ::c_int = 25; +pub const _SC_RE_DUP_MAX: ::c_int = 26; +pub const _SC_STREAM_MAX: ::c_int = 27; +pub const _SC_TZNAME_MAX: ::c_int = 28; +pub const _SC_XOPEN_CRYPT: ::c_int = 29; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 30; +pub const _SC_XOPEN_SHM: ::c_int = 31; +pub const _SC_XOPEN_VERSION: ::c_int = 32; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 33; +pub const _SC_XOPEN_REALTIME: ::c_int = 34; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 35; +pub const _SC_XOPEN_LEGACY: ::c_int = 36; +pub const _SC_ATEXIT_MAX: ::c_int = 37; +pub const _SC_IOV_MAX: ::c_int = 38; +pub const _SC_PAGESIZE: ::c_int = 39; +pub const _SC_PAGE_SIZE: ::c_int = 40; +pub const _SC_XOPEN_UNIX: ::c_int = 41; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 42; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 43; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 44; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 45; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 46; +pub const _SC_AIO_MAX: ::c_int = 47; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 48; +pub const _SC_DELAYTIMER_MAX: ::c_int = 49; +pub const _SC_MQ_OPEN_MAX: ::c_int = 50; +pub const _SC_MQ_PRIO_MAX: ::c_int = 51; +pub const _SC_RTSIG_MAX: ::c_int = 52; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 53; +pub const _SC_SEM_VALUE_MAX: ::c_int = 54; +pub const _SC_SIGQUEUE_MAX: ::c_int = 55; +pub const _SC_TIMER_MAX: ::c_int = 56; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 57; +pub const _SC_FSYNC: ::c_int = 58; +pub const _SC_MAPPED_FILES: ::c_int = 59; +pub const _SC_MEMLOCK: ::c_int = 60; +pub const _SC_MEMLOCK_RANGE: ::c_int = 61; +pub const _SC_MEMORY_PROTECTION: ::c_int = 62; +pub const _SC_MESSAGE_PASSING: ::c_int = 63; +pub const _SC_PRIORITIZED_IO: ::c_int = 64; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 65; +pub const _SC_REALTIME_SIGNALS: ::c_int = 66; +pub const _SC_SEMAPHORES: ::c_int = 67; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 68; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 69; +pub const _SC_TIMERS: ::c_int = 70; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 71; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 72; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 73; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 74; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 75; +pub const _SC_THREAD_STACK_MIN: ::c_int = 76; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 77; +pub const _SC_TTY_NAME_MAX: ::c_int = 78; +pub const _SC_THREADS: ::c_int = 79; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 80; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 81; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 82; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 83; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 84; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 85; +pub const _SC_NPROCESSORS_CONF: ::c_int = 96; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 97; +pub const _SC_PHYS_PAGES: ::c_int = 98; +pub const _SC_AVPHYS_PAGES: ::c_int = 99; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 100; + +pub const _SC_2_PBS: ::c_int = 101; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 102; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 103; +pub const _SC_2_PBS_LOCATE: ::c_int = 104; +pub const _SC_2_PBS_MESSAGE: ::c_int = 105; +pub const _SC_2_PBS_TRACK: ::c_int = 106; +pub const _SC_ADVISORY_INFO: ::c_int = 107; +pub const _SC_BARRIERS: ::c_int = 108; +pub const _SC_CLOCK_SELECTION: ::c_int = 109; +pub const _SC_CPUTIME: ::c_int = 110; +pub const _SC_HOST_NAME_MAX: ::c_int = 111; +pub const _SC_IPV6: ::c_int = 112; +pub const _SC_RAW_SOCKETS: ::c_int = 113; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 114; +pub const _SC_REGEXP: ::c_int = 115; +pub const _SC_SHELL: ::c_int = 116; +pub const _SC_SPAWN: ::c_int = 117; +pub const _SC_SPIN_LOCKS: ::c_int = 118; +pub const _SC_SPORADIC_SERVER: ::c_int = 119; +pub const _SC_SS_REPL_MAX: ::c_int = 120; +pub const _SC_SYMLOOP_MAX: ::c_int = 121; +pub const _SC_THREAD_CPUTIME: ::c_int = 122; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 123; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 124; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 125; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 126; +pub const _SC_TIMEOUTS: ::c_int = 127; +pub const _SC_TRACE: ::c_int = 128; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 129; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 130; +pub const _SC_TRACE_INHERIT: ::c_int = 131; +pub const _SC_TRACE_LOG: ::c_int = 132; +pub const _SC_TRACE_NAME_MAX: ::c_int = 133; +pub const _SC_TRACE_SYS_MAX: ::c_int = 134; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 135; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 136; +pub const _SC_V7_ILP32_OFF32: ::c_int = 137; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 138; +pub const _SC_V7_LP64_OFF64: ::c_int = 139; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 140; +pub const _SC_XOPEN_STREAMS: ::c_int = 141; +pub const _SC_XOPEN_UUCP: ::c_int = 142; + +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +pub const F_SEAL_FUTURE_WRITE: ::c_int = 0x0010; + +pub const IFF_LOWER_UP: ::c_int = 0x10000; +pub const IFF_DORMANT: ::c_int = 0x20000; +pub const IFF_ECHO: ::c_int = 0x40000; + +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; + +pub const PTHREAD_EXPLICIT_SCHED: ::c_int = 0; +pub const PTHREAD_INHERIT_SCHED: ::c_int = 1; + +// stdio.h +pub const RENAME_NOREPLACE: ::c_int = 1; +pub const RENAME_EXCHANGE: ::c_int = 2; +pub const RENAME_WHITEOUT: ::c_int = 4; + +pub const FIOCLEX: ::c_int = 0x5451; +pub const FIONCLEX: ::c_int = 0x5450; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_PAPER_MASK: ::c_int = 1 << LC_PAPER; +pub const LC_NAME_MASK: ::c_int = 1 << LC_NAME; +pub const LC_ADDRESS_MASK: ::c_int = 1 << LC_ADDRESS; +pub const LC_TELEPHONE_MASK: ::c_int = 1 << LC_TELEPHONE; +pub const LC_MEASUREMENT_MASK: ::c_int = 1 << LC_MEASUREMENT; +pub const LC_IDENTIFICATION_MASK: ::c_int = 1 << LC_IDENTIFICATION; +pub const LC_ALL_MASK: ::c_int = ::LC_CTYPE_MASK + | ::LC_NUMERIC_MASK + | ::LC_TIME_MASK + | ::LC_COLLATE_MASK + | ::LC_MONETARY_MASK + | ::LC_MESSAGES_MASK + | LC_PAPER_MASK + | LC_NAME_MASK + | LC_ADDRESS_MASK + | LC_TELEPHONE_MASK + | LC_MEASUREMENT_MASK + | LC_IDENTIFICATION_MASK; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; + +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; + +pub const IPPROTO_MAX: ::c_int = 256; + +pub const SOL_SOCKET: ::c_int = 1; +pub const SOL_SCTP: ::c_int = 132; +pub const SOL_IPX: ::c_int = 256; +pub const SOL_AX25: ::c_int = 257; +pub const SOL_ATALK: ::c_int = 258; +pub const SOL_NETROM: ::c_int = 259; +pub const SOL_ROSE: ::c_int = 260; + +/* DCCP socket options */ +pub const DCCP_SOCKOPT_PACKET_SIZE: ::c_int = 1; +pub const DCCP_SOCKOPT_SERVICE: ::c_int = 2; +pub const DCCP_SOCKOPT_CHANGE_L: ::c_int = 3; +pub const DCCP_SOCKOPT_CHANGE_R: ::c_int = 4; +pub const DCCP_SOCKOPT_GET_CUR_MPS: ::c_int = 5; +pub const DCCP_SOCKOPT_SERVER_TIMEWAIT: ::c_int = 6; +pub const DCCP_SOCKOPT_SEND_CSCOV: ::c_int = 10; +pub const DCCP_SOCKOPT_RECV_CSCOV: ::c_int = 11; +pub const DCCP_SOCKOPT_AVAILABLE_CCIDS: ::c_int = 12; +pub const DCCP_SOCKOPT_CCID: ::c_int = 13; +pub const DCCP_SOCKOPT_TX_CCID: ::c_int = 14; +pub const DCCP_SOCKOPT_RX_CCID: ::c_int = 15; +pub const DCCP_SOCKOPT_QPOLICY_ID: ::c_int = 16; +pub const DCCP_SOCKOPT_QPOLICY_TXQLEN: ::c_int = 17; +pub const DCCP_SOCKOPT_CCID_RX_INFO: ::c_int = 128; +pub const DCCP_SOCKOPT_CCID_TX_INFO: ::c_int = 192; + +/// maximum number of services provided on the same listening port +pub const DCCP_SERVICE_LIST_MAX_LEN: ::c_int = 32; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_ATTACH_FILTER: ::c_int = 26; +pub const SO_DETACH_FILTER: ::c_int = 27; +pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_TIMESTAMPNS: ::c_int = 35; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +pub const SO_MARK: ::c_int = 36; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_TIMESTAMP_NEW: ::c_int = 63; +pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; +pub const SO_TIMESTAMPING_NEW: ::c_int = 65; + +// Defined in unix/linux_like/mod.rs +// pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; +pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; +pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; + +pub const IPTOS_ECN_NOTECT: u8 = 0x00; + +pub const O_ACCMODE: ::c_int = 3; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; +pub const O_DSYNC: ::c_int = 4096; +pub const O_RSYNC: ::c_int = O_SYNC; + +pub const NI_MAXHOST: ::size_t = 1025; +pub const NI_MAXSERV: ::size_t = 32; + +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x00000002; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +pub const NI_NUMERICSERV: ::c_int = 0x00000008; +pub const NI_DGRAM: ::c_int = 0x00000010; + +pub const NCCS: usize = 19; +pub const TCSBRKP: ::c_int = 0x5425; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 0x1; +pub const TCSAFLUSH: ::c_int = 0x2; +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0o200000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_GETREGS: ::c_int = 12; +pub const PTRACE_SETREGS: ::c_int = 13; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_SYSCALL: ::c_int = 24; +pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; +pub const PTRACE_GETREGSET: ::c_int = 0x4204; +pub const PTRACE_SETREGSET: ::c_int = 0x4205; +pub const PTRACE_SECCOMP_GET_METADATA: ::c_int = 0x420d; + +pub const PTRACE_EVENT_STOP: ::c_int = 128; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_NPROC: ::c_int = 6; +pub const RLIMIT_NOFILE: ::c_int = 7; +pub const RLIMIT_MEMLOCK: ::c_int = 8; +pub const RLIMIT_AS: ::c_int = 9; +pub const RLIMIT_LOCKS: ::c_int = 10; +pub const RLIMIT_SIGPENDING: ::c_int = 11; +pub const RLIMIT_MSGQUEUE: ::c_int = 12; +pub const RLIMIT_NICE: ::c_int = 13; +pub const RLIMIT_RTPRIO: ::c_int = 14; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 16; +pub const RLIM_INFINITY: ::rlim_t = !0; + +pub const TCGETS: ::c_int = 0x5401; +pub const TCSETS: ::c_int = 0x5402; +pub const TCSETSW: ::c_int = 0x5403; +pub const TCSETSF: ::c_int = 0x5404; +pub const TCGETS2: ::c_int = 0x802c542a; +pub const TCSETS2: ::c_int = 0x402c542b; +pub const TCSETSW2: ::c_int = 0x402c542c; +pub const TCSETSF2: ::c_int = 0x402c542d; +pub const TCGETA: ::c_int = 0x5405; +pub const TCSETA: ::c_int = 0x5406; +pub const TCSETAW: ::c_int = 0x5407; +pub const TCSETAF: ::c_int = 0x5408; +pub const TCSBRK: ::c_int = 0x5409; +pub const TCXONC: ::c_int = 0x540A; +pub const TCFLSH: ::c_int = 0x540B; +pub const TIOCGSOFTCAR: ::c_int = 0x5419; +pub const TIOCSSOFTCAR: ::c_int = 0x541A; +pub const TIOCINQ: ::c_int = 0x541B; +pub const TIOCLINUX: ::c_int = 0x541C; +pub const TIOCGSERIAL: ::c_int = 0x541E; +pub const TIOCEXCL: ::c_int = 0x540C; +pub const TIOCNXCL: ::c_int = 0x540D; +pub const TIOCSCTTY: ::c_int = 0x540E; +pub const TIOCGPGRP: ::c_int = 0x540F; +pub const TIOCSPGRP: ::c_int = 0x5410; +pub const TIOCOUTQ: ::c_int = 0x5411; +pub const TIOCSTI: ::c_int = 0x5412; +pub const TIOCGWINSZ: ::c_int = 0x5413; +pub const TIOCSWINSZ: ::c_int = 0x5414; +pub const TIOCMGET: ::c_int = 0x5415; +pub const TIOCMBIS: ::c_int = 0x5416; +pub const TIOCMBIC: ::c_int = 0x5417; +pub const TIOCMSET: ::c_int = 0x5418; +pub const FIONREAD: ::c_int = 0x541B; +pub const TIOCCONS: ::c_int = 0x541D; +pub const TIOCSBRK: ::c_int = 0x5427; +pub const TIOCCBRK: ::c_int = 0x5428; +cfg_if! { + if #[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "s390x"))] { + pub const FICLONE: ::c_int = 0x40049409; + pub const FICLONERANGE: ::c_int = 0x4020940D; + } else if #[cfg(any(target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc", + target_arch = "powerpc64"))] { + pub const FICLONE: ::c_int = 0x80049409; + pub const FICLONERANGE: ::c_int = 0x8020940D; + } +} + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; +pub const ST_RELATIME: ::c_ulong = 4096; + +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const SEM_FAILED: *mut sem_t = 0 as *mut sem_t; + +pub const AI_PASSIVE: ::c_int = 0x00000001; +pub const AI_CANONNAME: ::c_int = 0x00000002; +pub const AI_NUMERICHOST: ::c_int = 0x00000004; +pub const AI_NUMERICSERV: ::c_int = 0x00000008; +pub const AI_MASK: ::c_int = + AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG; +pub const AI_ALL: ::c_int = 0x00000100; +pub const AI_V4MAPPED_CFG: ::c_int = 0x00000200; +pub const AI_ADDRCONFIG: ::c_int = 0x00000400; +pub const AI_V4MAPPED: ::c_int = 0x00000800; +pub const AI_DEFAULT: ::c_int = AI_V4MAPPED_CFG | AI_ADDRCONFIG; + +// linux/kexec.h +pub const KEXEC_ON_CRASH: ::c_int = 0x00000001; +pub const KEXEC_PRESERVE_CONTEXT: ::c_int = 0x00000002; +pub const KEXEC_ARCH_MASK: ::c_int = 0xffff0000; +pub const KEXEC_FILE_UNLOAD: ::c_int = 0x00000001; +pub const KEXEC_FILE_ON_CRASH: ::c_int = 0x00000002; +pub const KEXEC_FILE_NO_INITRAMFS: ::c_int = 0x00000004; + +pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead; +pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793; +pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278; +pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448; +pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216; + +pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567; +pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123; +pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF; +pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000; +pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC; +pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4; +pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2; +pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543; + +pub const REG_BASIC: ::c_int = 0; +pub const REG_EXTENDED: ::c_int = 1; +pub const REG_ICASE: ::c_int = 2; +pub const REG_NOSUB: ::c_int = 4; +pub const REG_NEWLINE: ::c_int = 8; +pub const REG_NOSPEC: ::c_int = 16; +pub const REG_PEND: ::c_int = 32; +pub const REG_DUMP: ::c_int = 128; + +pub const REG_NOMATCH: ::c_int = 1; +pub const REG_BADPAT: ::c_int = 2; +pub const REG_ECOLLATE: ::c_int = 3; +pub const REG_ECTYPE: ::c_int = 4; +pub const REG_EESCAPE: ::c_int = 5; +pub const REG_ESUBREG: ::c_int = 6; +pub const REG_EBRACK: ::c_int = 7; +pub const REG_EPAREN: ::c_int = 8; +pub const REG_EBRACE: ::c_int = 9; +pub const REG_BADBR: ::c_int = 10; +pub const REG_ERANGE: ::c_int = 11; +pub const REG_ESPACE: ::c_int = 12; +pub const REG_BADRPT: ::c_int = 13; +pub const REG_EMPTY: ::c_int = 14; +pub const REG_ASSERT: ::c_int = 15; +pub const REG_INVARG: ::c_int = 16; +pub const REG_ATOI: ::c_int = 255; +pub const REG_ITOA: ::c_int = 256; + +pub const REG_NOTBOL: ::c_int = 1; +pub const REG_NOTEOL: ::c_int = 2; +pub const REG_STARTEND: ::c_int = 4; +pub const REG_TRACE: ::c_int = 256; +pub const REG_LARGE: ::c_int = 512; +pub const REG_BACKR: ::c_int = 1024; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const BOTHER: ::speed_t = 0o010000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; +pub const IBSHIFT: ::tcflag_t = 16; + +pub const BLKIOMIN: ::c_int = 0x1278; +pub const BLKIOOPT: ::c_int = 0x1279; +pub const BLKSSZGET: ::c_int = 0x1268; +pub const BLKPBSZGET: ::c_int = 0x127B; + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(any(target_arch = "x86", target_arch = "arm"))] { + pub const FS_IOC_GETFLAGS: ::c_int = 0x80046601; + pub const FS_IOC_SETFLAGS: ::c_int = 0x40046602; + pub const FS_IOC_GETVERSION: ::c_int = 0x80047601; + pub const FS_IOC_SETVERSION: ::c_int = 0x40047602; + pub const FS_IOC32_GETFLAGS: ::c_int = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::c_int = 0x40046602; + pub const FS_IOC32_GETVERSION: ::c_int = 0x80047601; + pub const FS_IOC32_SETVERSION: ::c_int = 0x40047602; + } else if #[cfg(any(target_arch = "x86_64", target_arch = "riscv64", target_arch = "aarch64"))] { + pub const FS_IOC_GETFLAGS: ::c_int = 0x80086601; + pub const FS_IOC_SETFLAGS: ::c_int = 0x40086602; + pub const FS_IOC_GETVERSION: ::c_int = 0x80087601; + pub const FS_IOC_SETVERSION: ::c_int = 0x40087602; + pub const FS_IOC32_GETFLAGS: ::c_int = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::c_int = 0x40046602; + pub const FS_IOC32_GETVERSION: ::c_int = 0x80047601; + pub const FS_IOC32_SETVERSION: ::c_int = 0x40047602; + } +} + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 14; + +pub const NETLINK_ROUTE: ::c_int = 0; +pub const NETLINK_UNUSED: ::c_int = 1; +pub const NETLINK_USERSOCK: ::c_int = 2; +pub const NETLINK_FIREWALL: ::c_int = 3; +pub const NETLINK_SOCK_DIAG: ::c_int = 4; +pub const NETLINK_NFLOG: ::c_int = 5; +pub const NETLINK_XFRM: ::c_int = 6; +pub const NETLINK_SELINUX: ::c_int = 7; +pub const NETLINK_ISCSI: ::c_int = 8; +pub const NETLINK_AUDIT: ::c_int = 9; +pub const NETLINK_FIB_LOOKUP: ::c_int = 10; +pub const NETLINK_CONNECTOR: ::c_int = 11; +pub const NETLINK_NETFILTER: ::c_int = 12; +pub const NETLINK_IP6_FW: ::c_int = 13; +pub const NETLINK_DNRTMSG: ::c_int = 14; +pub const NETLINK_KOBJECT_UEVENT: ::c_int = 15; +pub const NETLINK_GENERIC: ::c_int = 16; +pub const NETLINK_SCSITRANSPORT: ::c_int = 18; +pub const NETLINK_ECRYPTFS: ::c_int = 19; +pub const NETLINK_RDMA: ::c_int = 20; +pub const NETLINK_CRYPTO: ::c_int = 21; +pub const NETLINK_INET_DIAG: ::c_int = NETLINK_SOCK_DIAG; + +pub const MAX_LINKS: ::c_int = 32; + +pub const NLM_F_REQUEST: ::c_int = 1; +pub const NLM_F_MULTI: ::c_int = 2; +pub const NLM_F_ACK: ::c_int = 4; +pub const NLM_F_ECHO: ::c_int = 8; +pub const NLM_F_DUMP_INTR: ::c_int = 16; +pub const NLM_F_DUMP_FILTERED: ::c_int = 32; + +pub const NLM_F_ROOT: ::c_int = 0x100; +pub const NLM_F_MATCH: ::c_int = 0x200; +pub const NLM_F_ATOMIC: ::c_int = 0x400; +pub const NLM_F_DUMP: ::c_int = NLM_F_ROOT | NLM_F_MATCH; + +pub const NLM_F_REPLACE: ::c_int = 0x100; +pub const NLM_F_EXCL: ::c_int = 0x200; +pub const NLM_F_CREATE: ::c_int = 0x400; +pub const NLM_F_APPEND: ::c_int = 0x800; + +pub const NLMSG_NOOP: ::c_int = 0x1; +pub const NLMSG_ERROR: ::c_int = 0x2; +pub const NLMSG_DONE: ::c_int = 0x3; +pub const NLMSG_OVERRUN: ::c_int = 0x4; +pub const NLMSG_MIN_TYPE: ::c_int = 0x10; + +// linux/netfilter/nfnetlink.h +pub const NFNLGRP_NONE: ::c_int = 0; +pub const NFNLGRP_CONNTRACK_NEW: ::c_int = 1; +pub const NFNLGRP_CONNTRACK_UPDATE: ::c_int = 2; +pub const NFNLGRP_CONNTRACK_DESTROY: ::c_int = 3; +pub const NFNLGRP_CONNTRACK_EXP_NEW: ::c_int = 4; +pub const NFNLGRP_CONNTRACK_EXP_UPDATE: ::c_int = 5; +pub const NFNLGRP_CONNTRACK_EXP_DESTROY: ::c_int = 6; +pub const NFNLGRP_NFTABLES: ::c_int = 7; +pub const NFNLGRP_ACCT_QUOTA: ::c_int = 8; + +pub const NFNETLINK_V0: ::c_int = 0; + +pub const NFNL_SUBSYS_NONE: ::c_int = 0; +pub const NFNL_SUBSYS_CTNETLINK: ::c_int = 1; +pub const NFNL_SUBSYS_CTNETLINK_EXP: ::c_int = 2; +pub const NFNL_SUBSYS_QUEUE: ::c_int = 3; +pub const NFNL_SUBSYS_ULOG: ::c_int = 4; +pub const NFNL_SUBSYS_OSF: ::c_int = 5; +pub const NFNL_SUBSYS_IPSET: ::c_int = 6; +pub const NFNL_SUBSYS_ACCT: ::c_int = 7; +pub const NFNL_SUBSYS_CTNETLINK_TIMEOUT: ::c_int = 8; +pub const NFNL_SUBSYS_CTHELPER: ::c_int = 9; +pub const NFNL_SUBSYS_NFTABLES: ::c_int = 10; +pub const NFNL_SUBSYS_NFT_COMPAT: ::c_int = 11; +pub const NFNL_SUBSYS_COUNT: ::c_int = 12; + +pub const NFNL_MSG_BATCH_BEGIN: ::c_int = NLMSG_MIN_TYPE; +pub const NFNL_MSG_BATCH_END: ::c_int = NLMSG_MIN_TYPE + 1; + +// linux/netfilter/nfnetlink_log.h +pub const NFULNL_MSG_PACKET: ::c_int = 0; +pub const NFULNL_MSG_CONFIG: ::c_int = 1; + +pub const NFULA_UNSPEC: ::c_int = 0; +pub const NFULA_PACKET_HDR: ::c_int = 1; +pub const NFULA_MARK: ::c_int = 2; +pub const NFULA_TIMESTAMP: ::c_int = 3; +pub const NFULA_IFINDEX_INDEV: ::c_int = 4; +pub const NFULA_IFINDEX_OUTDEV: ::c_int = 5; +pub const NFULA_IFINDEX_PHYSINDEV: ::c_int = 6; +pub const NFULA_IFINDEX_PHYSOUTDEV: ::c_int = 7; +pub const NFULA_HWADDR: ::c_int = 8; +pub const NFULA_PAYLOAD: ::c_int = 9; +pub const NFULA_PREFIX: ::c_int = 10; +pub const NFULA_UID: ::c_int = 11; +pub const NFULA_SEQ: ::c_int = 12; +pub const NFULA_SEQ_GLOBAL: ::c_int = 13; +pub const NFULA_GID: ::c_int = 14; +pub const NFULA_HWTYPE: ::c_int = 15; +pub const NFULA_HWHEADER: ::c_int = 16; +pub const NFULA_HWLEN: ::c_int = 17; +pub const NFULA_CT: ::c_int = 18; +pub const NFULA_CT_INFO: ::c_int = 19; + +pub const NFULNL_CFG_CMD_NONE: ::c_int = 0; +pub const NFULNL_CFG_CMD_BIND: ::c_int = 1; +pub const NFULNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFULNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFULNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFULA_CFG_UNSPEC: ::c_int = 0; +pub const NFULA_CFG_CMD: ::c_int = 1; +pub const NFULA_CFG_MODE: ::c_int = 2; +pub const NFULA_CFG_NLBUFSIZ: ::c_int = 3; +pub const NFULA_CFG_TIMEOUT: ::c_int = 4; +pub const NFULA_CFG_QTHRESH: ::c_int = 5; +pub const NFULA_CFG_FLAGS: ::c_int = 6; + +pub const NFULNL_COPY_NONE: ::c_int = 0x00; +pub const NFULNL_COPY_META: ::c_int = 0x01; +pub const NFULNL_COPY_PACKET: ::c_int = 0x02; + +pub const NFULNL_CFG_F_SEQ: ::c_int = 0x0001; +pub const NFULNL_CFG_F_SEQ_GLOBAL: ::c_int = 0x0002; +pub const NFULNL_CFG_F_CONNTRACK: ::c_int = 0x0004; + +// linux/netfilter/nfnetlink_log.h +pub const NFQNL_MSG_PACKET: ::c_int = 0; +pub const NFQNL_MSG_VERDICT: ::c_int = 1; +pub const NFQNL_MSG_CONFIG: ::c_int = 2; +pub const NFQNL_MSG_VERDICT_BATCH: ::c_int = 3; + +pub const NFQA_UNSPEC: ::c_int = 0; +pub const NFQA_PACKET_HDR: ::c_int = 1; +pub const NFQA_VERDICT_HDR: ::c_int = 2; +pub const NFQA_MARK: ::c_int = 3; +pub const NFQA_TIMESTAMP: ::c_int = 4; +pub const NFQA_IFINDEX_INDEV: ::c_int = 5; +pub const NFQA_IFINDEX_OUTDEV: ::c_int = 6; +pub const NFQA_IFINDEX_PHYSINDEV: ::c_int = 7; +pub const NFQA_IFINDEX_PHYSOUTDEV: ::c_int = 8; +pub const NFQA_HWADDR: ::c_int = 9; +pub const NFQA_PAYLOAD: ::c_int = 10; +pub const NFQA_CT: ::c_int = 11; +pub const NFQA_CT_INFO: ::c_int = 12; +pub const NFQA_CAP_LEN: ::c_int = 13; +pub const NFQA_SKB_INFO: ::c_int = 14; +pub const NFQA_EXP: ::c_int = 15; +pub const NFQA_UID: ::c_int = 16; +pub const NFQA_GID: ::c_int = 17; +pub const NFQA_SECCTX: ::c_int = 18; +/* + FIXME: These are not yet available in musl sanitized kernel headers and + make the tests fail. Enable them once musl has them. + + See https://github.com/rust-lang/libc/pull/1628 for more details. +pub const NFQA_VLAN: ::c_int = 19; +pub const NFQA_L2HDR: ::c_int = 20; + +pub const NFQA_VLAN_UNSPEC: ::c_int = 0; +pub const NFQA_VLAN_PROTO: ::c_int = 1; +pub const NFQA_VLAN_TCI: ::c_int = 2; +*/ + +pub const NFQNL_CFG_CMD_NONE: ::c_int = 0; +pub const NFQNL_CFG_CMD_BIND: ::c_int = 1; +pub const NFQNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFQNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFQNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFQNL_COPY_NONE: ::c_int = 0; +pub const NFQNL_COPY_META: ::c_int = 1; +pub const NFQNL_COPY_PACKET: ::c_int = 2; + +pub const NFQA_CFG_UNSPEC: ::c_int = 0; +pub const NFQA_CFG_CMD: ::c_int = 1; +pub const NFQA_CFG_PARAMS: ::c_int = 2; +pub const NFQA_CFG_QUEUE_MAXLEN: ::c_int = 3; +pub const NFQA_CFG_MASK: ::c_int = 4; +pub const NFQA_CFG_FLAGS: ::c_int = 5; + +pub const NFQA_CFG_F_FAIL_OPEN: ::c_int = 0x0001; +pub const NFQA_CFG_F_CONNTRACK: ::c_int = 0x0002; +pub const NFQA_CFG_F_GSO: ::c_int = 0x0004; +pub const NFQA_CFG_F_UID_GID: ::c_int = 0x0008; +pub const NFQA_CFG_F_SECCTX: ::c_int = 0x0010; +pub const NFQA_CFG_F_MAX: ::c_int = 0x0020; + +pub const NFQA_SKB_CSUMNOTREADY: ::c_int = 0x0001; +pub const NFQA_SKB_GSO: ::c_int = 0x0002; +pub const NFQA_SKB_CSUM_NOTVERIFIED: ::c_int = 0x0004; + +pub const GENL_NAMSIZ: ::c_int = 16; + +pub const GENL_MIN_ID: ::c_int = NLMSG_MIN_TYPE; +pub const GENL_MAX_ID: ::c_int = 1023; + +pub const GENL_ADMIN_PERM: ::c_int = 0x01; +pub const GENL_CMD_CAP_DO: ::c_int = 0x02; +pub const GENL_CMD_CAP_DUMP: ::c_int = 0x04; +pub const GENL_CMD_CAP_HASPOL: ::c_int = 0x08; +pub const GENL_UNS_ADMIN_PERM: ::c_int = 0x10; + +pub const GENL_ID_CTRL: ::c_int = NLMSG_MIN_TYPE; +pub const GENL_ID_VFS_DQUOT: ::c_int = NLMSG_MIN_TYPE + 1; +pub const GENL_ID_PMCRAID: ::c_int = NLMSG_MIN_TYPE + 2; + +pub const CTRL_CMD_UNSPEC: ::c_int = 0; +pub const CTRL_CMD_NEWFAMILY: ::c_int = 1; +pub const CTRL_CMD_DELFAMILY: ::c_int = 2; +pub const CTRL_CMD_GETFAMILY: ::c_int = 3; +pub const CTRL_CMD_NEWOPS: ::c_int = 4; +pub const CTRL_CMD_DELOPS: ::c_int = 5; +pub const CTRL_CMD_GETOPS: ::c_int = 6; +pub const CTRL_CMD_NEWMCAST_GRP: ::c_int = 7; +pub const CTRL_CMD_DELMCAST_GRP: ::c_int = 8; +pub const CTRL_CMD_GETMCAST_GRP: ::c_int = 9; + +pub const CTRL_ATTR_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_FAMILY_ID: ::c_int = 1; +pub const CTRL_ATTR_FAMILY_NAME: ::c_int = 2; +pub const CTRL_ATTR_VERSION: ::c_int = 3; +pub const CTRL_ATTR_HDRSIZE: ::c_int = 4; +pub const CTRL_ATTR_MAXATTR: ::c_int = 5; +pub const CTRL_ATTR_OPS: ::c_int = 6; +pub const CTRL_ATTR_MCAST_GROUPS: ::c_int = 7; + +pub const CTRL_ATTR_OP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_OP_ID: ::c_int = 1; +pub const CTRL_ATTR_OP_FLAGS: ::c_int = 2; + +pub const CTRL_ATTR_MCAST_GRP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_MCAST_GRP_NAME: ::c_int = 1; +pub const CTRL_ATTR_MCAST_GRP_ID: ::c_int = 2; + +pub const NETLINK_ADD_MEMBERSHIP: ::c_int = 1; +pub const NETLINK_DROP_MEMBERSHIP: ::c_int = 2; +pub const NETLINK_PKTINFO: ::c_int = 3; +pub const NETLINK_BROADCAST_ERROR: ::c_int = 4; +pub const NETLINK_NO_ENOBUFS: ::c_int = 5; +pub const NETLINK_RX_RING: ::c_int = 6; +pub const NETLINK_TX_RING: ::c_int = 7; +pub const NETLINK_LISTEN_ALL_NSID: ::c_int = 8; +pub const NETLINK_LIST_MEMBERSHIPS: ::c_int = 9; +pub const NETLINK_CAP_ACK: ::c_int = 10; +pub const NETLINK_EXT_ACK: ::c_int = 11; +pub const NETLINK_GET_STRICT_CHK: ::c_int = 12; + +pub const GRND_NONBLOCK: ::c_uint = 0x0001; +pub const GRND_RANDOM: ::c_uint = 0x0002; +pub const GRND_INSECURE: ::c_uint = 0x0004; + +pub const SECCOMP_MODE_DISABLED: ::c_uint = 0; +pub const SECCOMP_MODE_STRICT: ::c_uint = 1; +pub const SECCOMP_MODE_FILTER: ::c_uint = 2; + +pub const SECCOMP_FILTER_FLAG_TSYNC: ::c_ulong = 1; +pub const SECCOMP_FILTER_FLAG_LOG: ::c_ulong = 2; +pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: ::c_ulong = 4; +pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: ::c_ulong = 8; + +pub const SECCOMP_RET_ACTION_FULL: ::c_uint = 0xffff0000; +pub const SECCOMP_RET_ACTION: ::c_uint = 0x7fff0000; +pub const SECCOMP_RET_DATA: ::c_uint = 0x0000ffff; + +pub const SECCOMP_RET_KILL_PROCESS: ::c_uint = 0x80000000; +pub const SECCOMP_RET_KILL_THREAD: ::c_uint = 0x00000000; +pub const SECCOMP_RET_KILL: ::c_uint = SECCOMP_RET_KILL_THREAD; +pub const SECCOMP_RET_TRAP: ::c_uint = 0x00030000; +pub const SECCOMP_RET_ERRNO: ::c_uint = 0x00050000; +pub const SECCOMP_RET_USER_NOTIF: ::c_uint = 0x7fc00000; +pub const SECCOMP_RET_TRACE: ::c_uint = 0x7ff00000; +pub const SECCOMP_RET_LOG: ::c_uint = 0x7ffc0000; +pub const SECCOMP_RET_ALLOW: ::c_uint = 0x7fff0000; + +pub const NLA_F_NESTED: ::c_int = 1 << 15; +pub const NLA_F_NET_BYTEORDER: ::c_int = 1 << 14; +pub const NLA_TYPE_MASK: ::c_int = !(NLA_F_NESTED | NLA_F_NET_BYTEORDER); + +pub const NLA_ALIGNTO: ::c_int = 4; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const SFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const SFD_NONBLOCK: ::c_int = O_NONBLOCK; + +pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; + +pub const SO_ORIGINAL_DST: ::c_int = 80; + +pub const IP_RECVFRAGSIZE: ::c_int = 25; + +pub const IPV6_FLOWINFO: ::c_int = 11; +pub const IPV6_MULTICAST_ALL: ::c_int = 29; +pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30; +pub const IPV6_FLOWLABEL_MGR: ::c_int = 32; +pub const IPV6_FLOWINFO_SEND: ::c_int = 33; +pub const IPV6_RECVFRAGSIZE: ::c_int = 77; +pub const IPV6_FREEBIND: ::c_int = 78; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff; +pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000; + +pub const IUTF8: ::tcflag_t = 0x00004000; +pub const CMSPAR: ::tcflag_t = 0o10000000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MFD_CLOEXEC: ::c_uint = 0x0001; +pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; +pub const MFD_HUGETLB: ::c_uint = 0x0004; +pub const MFD_NOEXEC_SEAL: ::c_uint = 0x0008; +pub const MFD_EXEC: ::c_uint = 0x0010; +pub const MFD_HUGE_64KB: ::c_uint = 0x40000000; +pub const MFD_HUGE_512KB: ::c_uint = 0x4c000000; +pub const MFD_HUGE_1MB: ::c_uint = 0x50000000; +pub const MFD_HUGE_2MB: ::c_uint = 0x54000000; +pub const MFD_HUGE_8MB: ::c_uint = 0x5c000000; +pub const MFD_HUGE_16MB: ::c_uint = 0x60000000; +pub const MFD_HUGE_32MB: ::c_uint = 0x64000000; +pub const MFD_HUGE_256MB: ::c_uint = 0x70000000; +pub const MFD_HUGE_512MB: ::c_uint = 0x74000000; +pub const MFD_HUGE_1GB: ::c_uint = 0x78000000; +pub const MFD_HUGE_2GB: ::c_uint = 0x7c000000; +pub const MFD_HUGE_16GB: ::c_uint = 0x88000000; +pub const MFD_HUGE_MASK: ::c_uint = 63; +pub const MFD_HUGE_SHIFT: ::c_uint = 26; + +// these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has +// the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 +// so we can use that type here to avoid having to cast. +pub const PT_NULL: u32 = 0; +pub const PT_LOAD: u32 = 1; +pub const PT_DYNAMIC: u32 = 2; +pub const PT_INTERP: u32 = 3; +pub const PT_NOTE: u32 = 4; +pub const PT_SHLIB: u32 = 5; +pub const PT_PHDR: u32 = 6; +pub const PT_TLS: u32 = 7; +pub const PT_LOOS: u32 = 0x60000000; +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_STACK: u32 = 0x6474e551; +pub const PT_GNU_RELRO: u32 = 0x6474e552; +pub const PT_HIOS: u32 = 0x6fffffff; +pub const PT_LOPROC: u32 = 0x70000000; +pub const PT_HIPROC: u32 = 0x7fffffff; + +// uapi/linux/mount.h +pub const OPEN_TREE_CLONE: ::c_uint = 0x01; +pub const OPEN_TREE_CLOEXEC: ::c_uint = O_CLOEXEC as ::c_uint; + +// linux/netfilter.h +pub const NF_DROP: ::c_int = 0; +pub const NF_ACCEPT: ::c_int = 1; +pub const NF_STOLEN: ::c_int = 2; +pub const NF_QUEUE: ::c_int = 3; +pub const NF_REPEAT: ::c_int = 4; +pub const NF_STOP: ::c_int = 5; +pub const NF_MAX_VERDICT: ::c_int = NF_STOP; + +pub const NF_VERDICT_MASK: ::c_int = 0x000000ff; +pub const NF_VERDICT_FLAG_QUEUE_BYPASS: ::c_int = 0x00008000; + +pub const NF_VERDICT_QMASK: ::c_int = 0xffff0000; +pub const NF_VERDICT_QBITS: ::c_int = 16; + +pub const NF_VERDICT_BITS: ::c_int = 16; + +pub const NF_INET_PRE_ROUTING: ::c_int = 0; +pub const NF_INET_LOCAL_IN: ::c_int = 1; +pub const NF_INET_FORWARD: ::c_int = 2; +pub const NF_INET_LOCAL_OUT: ::c_int = 3; +pub const NF_INET_POST_ROUTING: ::c_int = 4; +pub const NF_INET_NUMHOOKS: ::c_int = 5; + +pub const NF_NETDEV_INGRESS: ::c_int = 0; +pub const NF_NETDEV_NUMHOOKS: ::c_int = 1; + +pub const NFPROTO_UNSPEC: ::c_int = 0; +pub const NFPROTO_INET: ::c_int = 1; +pub const NFPROTO_IPV4: ::c_int = 2; +pub const NFPROTO_ARP: ::c_int = 3; +pub const NFPROTO_NETDEV: ::c_int = 5; +pub const NFPROTO_BRIDGE: ::c_int = 7; +pub const NFPROTO_IPV6: ::c_int = 10; +pub const NFPROTO_DECNET: ::c_int = 12; +pub const NFPROTO_NUMPROTO: ::c_int = 13; + +// linux/netfilter_ipv4.h +pub const NF_IP_PRE_ROUTING: ::c_int = 0; +pub const NF_IP_LOCAL_IN: ::c_int = 1; +pub const NF_IP_FORWARD: ::c_int = 2; +pub const NF_IP_LOCAL_OUT: ::c_int = 3; +pub const NF_IP_POST_ROUTING: ::c_int = 4; +pub const NF_IP_NUMHOOKS: ::c_int = 5; + +pub const NF_IP_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP_PRI_RAW: ::c_int = -300; +pub const NF_IP_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP_PRI_MANGLE: ::c_int = -150; +pub const NF_IP_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP_PRI_FILTER: ::c_int = 0; +pub const NF_IP_PRI_SECURITY: ::c_int = 50; +pub const NF_IP_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP_PRI_CONNTRACK_CONFIRM: ::c_int = ::INT_MAX; +pub const NF_IP_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6.h +pub const NF_IP6_PRE_ROUTING: ::c_int = 0; +pub const NF_IP6_LOCAL_IN: ::c_int = 1; +pub const NF_IP6_FORWARD: ::c_int = 2; +pub const NF_IP6_LOCAL_OUT: ::c_int = 3; +pub const NF_IP6_POST_ROUTING: ::c_int = 4; +pub const NF_IP6_NUMHOOKS: ::c_int = 5; + +pub const NF_IP6_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP6_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP6_PRI_RAW: ::c_int = -300; +pub const NF_IP6_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP6_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP6_PRI_MANGLE: ::c_int = -150; +pub const NF_IP6_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP6_PRI_FILTER: ::c_int = 0; +pub const NF_IP6_PRI_SECURITY: ::c_int = 50; +pub const NF_IP6_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP6_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP6_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP6_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6/ip6_tables.h +pub const IP6T_SO_ORIGINAL_DST: ::c_int = 80; + +// linux/netfilter/nf_tables.h +pub const NFT_TABLE_MAXNAMELEN: ::c_int = 256; +pub const NFT_CHAIN_MAXNAMELEN: ::c_int = 256; +pub const NFT_SET_MAXNAMELEN: ::c_int = 256; +pub const NFT_OBJ_MAXNAMELEN: ::c_int = 256; +pub const NFT_USERDATA_MAXLEN: ::c_int = 256; + +pub const NFT_REG_VERDICT: ::c_int = 0; +pub const NFT_REG_1: ::c_int = 1; +pub const NFT_REG_2: ::c_int = 2; +pub const NFT_REG_3: ::c_int = 3; +pub const NFT_REG_4: ::c_int = 4; +pub const __NFT_REG_MAX: ::c_int = 5; +pub const NFT_REG32_00: ::c_int = 8; +pub const NFT_REG32_01: ::c_int = 9; +pub const NFT_REG32_02: ::c_int = 10; +pub const NFT_REG32_03: ::c_int = 11; +pub const NFT_REG32_04: ::c_int = 12; +pub const NFT_REG32_05: ::c_int = 13; +pub const NFT_REG32_06: ::c_int = 14; +pub const NFT_REG32_07: ::c_int = 15; +pub const NFT_REG32_08: ::c_int = 16; +pub const NFT_REG32_09: ::c_int = 17; +pub const NFT_REG32_10: ::c_int = 18; +pub const NFT_REG32_11: ::c_int = 19; +pub const NFT_REG32_12: ::c_int = 20; +pub const NFT_REG32_13: ::c_int = 21; +pub const NFT_REG32_14: ::c_int = 22; +pub const NFT_REG32_15: ::c_int = 23; + +pub const NFT_REG_SIZE: ::c_int = 16; +pub const NFT_REG32_SIZE: ::c_int = 4; + +pub const NFT_CONTINUE: ::c_int = -1; +pub const NFT_BREAK: ::c_int = -2; +pub const NFT_JUMP: ::c_int = -3; +pub const NFT_GOTO: ::c_int = -4; +pub const NFT_RETURN: ::c_int = -5; + +pub const NFT_MSG_NEWTABLE: ::c_int = 0; +pub const NFT_MSG_GETTABLE: ::c_int = 1; +pub const NFT_MSG_DELTABLE: ::c_int = 2; +pub const NFT_MSG_NEWCHAIN: ::c_int = 3; +pub const NFT_MSG_GETCHAIN: ::c_int = 4; +pub const NFT_MSG_DELCHAIN: ::c_int = 5; +pub const NFT_MSG_NEWRULE: ::c_int = 6; +pub const NFT_MSG_GETRULE: ::c_int = 7; +pub const NFT_MSG_DELRULE: ::c_int = 8; +pub const NFT_MSG_NEWSET: ::c_int = 9; +pub const NFT_MSG_GETSET: ::c_int = 10; +pub const NFT_MSG_DELSET: ::c_int = 11; +pub const NFT_MSG_NEWSETELEM: ::c_int = 12; +pub const NFT_MSG_GETSETELEM: ::c_int = 13; +pub const NFT_MSG_DELSETELEM: ::c_int = 14; +pub const NFT_MSG_NEWGEN: ::c_int = 15; +pub const NFT_MSG_GETGEN: ::c_int = 16; +pub const NFT_MSG_TRACE: ::c_int = 17; +pub const NFT_MSG_NEWOBJ: ::c_int = 18; +pub const NFT_MSG_GETOBJ: ::c_int = 19; +pub const NFT_MSG_DELOBJ: ::c_int = 20; +pub const NFT_MSG_GETOBJ_RESET: ::c_int = 21; +pub const NFT_MSG_MAX: ::c_int = 25; + +pub const NFT_SET_ANONYMOUS: ::c_int = 0x1; +pub const NFT_SET_CONSTANT: ::c_int = 0x2; +pub const NFT_SET_INTERVAL: ::c_int = 0x4; +pub const NFT_SET_MAP: ::c_int = 0x8; +pub const NFT_SET_TIMEOUT: ::c_int = 0x10; +pub const NFT_SET_EVAL: ::c_int = 0x20; + +pub const NFT_SET_POL_PERFORMANCE: ::c_int = 0; +pub const NFT_SET_POL_MEMORY: ::c_int = 1; + +pub const NFT_SET_ELEM_INTERVAL_END: ::c_int = 0x1; + +pub const NFT_DATA_VALUE: ::c_uint = 0; +pub const NFT_DATA_VERDICT: ::c_uint = 0xffffff00; + +pub const NFT_DATA_RESERVED_MASK: ::c_uint = 0xffffff00; + +pub const NFT_DATA_VALUE_MAXLEN: ::c_int = 64; + +pub const NFT_BYTEORDER_NTOH: ::c_int = 0; +pub const NFT_BYTEORDER_HTON: ::c_int = 1; + +pub const NFT_CMP_EQ: ::c_int = 0; +pub const NFT_CMP_NEQ: ::c_int = 1; +pub const NFT_CMP_LT: ::c_int = 2; +pub const NFT_CMP_LTE: ::c_int = 3; +pub const NFT_CMP_GT: ::c_int = 4; +pub const NFT_CMP_GTE: ::c_int = 5; + +pub const NFT_RANGE_EQ: ::c_int = 0; +pub const NFT_RANGE_NEQ: ::c_int = 1; + +pub const NFT_LOOKUP_F_INV: ::c_int = 1 << 0; + +pub const NFT_DYNSET_OP_ADD: ::c_int = 0; +pub const NFT_DYNSET_OP_UPDATE: ::c_int = 1; + +pub const NFT_DYNSET_F_INV: ::c_int = 1 << 0; + +pub const NFT_PAYLOAD_LL_HEADER: ::c_int = 0; +pub const NFT_PAYLOAD_NETWORK_HEADER: ::c_int = 1; +pub const NFT_PAYLOAD_TRANSPORT_HEADER: ::c_int = 2; + +pub const NFT_PAYLOAD_CSUM_NONE: ::c_int = 0; +pub const NFT_PAYLOAD_CSUM_INET: ::c_int = 1; + +pub const NFT_META_LEN: ::c_int = 0; +pub const NFT_META_PROTOCOL: ::c_int = 1; +pub const NFT_META_PRIORITY: ::c_int = 2; +pub const NFT_META_MARK: ::c_int = 3; +pub const NFT_META_IIF: ::c_int = 4; +pub const NFT_META_OIF: ::c_int = 5; +pub const NFT_META_IIFNAME: ::c_int = 6; +pub const NFT_META_OIFNAME: ::c_int = 7; +pub const NFT_META_IIFTYPE: ::c_int = 8; +pub const NFT_META_OIFTYPE: ::c_int = 9; +pub const NFT_META_SKUID: ::c_int = 10; +pub const NFT_META_SKGID: ::c_int = 11; +pub const NFT_META_NFTRACE: ::c_int = 12; +pub const NFT_META_RTCLASSID: ::c_int = 13; +pub const NFT_META_SECMARK: ::c_int = 14; +pub const NFT_META_NFPROTO: ::c_int = 15; +pub const NFT_META_L4PROTO: ::c_int = 16; +pub const NFT_META_BRI_IIFNAME: ::c_int = 17; +pub const NFT_META_BRI_OIFNAME: ::c_int = 18; +pub const NFT_META_PKTTYPE: ::c_int = 19; +pub const NFT_META_CPU: ::c_int = 20; +pub const NFT_META_IIFGROUP: ::c_int = 21; +pub const NFT_META_OIFGROUP: ::c_int = 22; +pub const NFT_META_CGROUP: ::c_int = 23; +pub const NFT_META_PRANDOM: ::c_int = 24; + +pub const NFT_CT_STATE: ::c_int = 0; +pub const NFT_CT_DIRECTION: ::c_int = 1; +pub const NFT_CT_STATUS: ::c_int = 2; +pub const NFT_CT_MARK: ::c_int = 3; +pub const NFT_CT_SECMARK: ::c_int = 4; +pub const NFT_CT_EXPIRATION: ::c_int = 5; +pub const NFT_CT_HELPER: ::c_int = 6; +pub const NFT_CT_L3PROTOCOL: ::c_int = 7; +pub const NFT_CT_SRC: ::c_int = 8; +pub const NFT_CT_DST: ::c_int = 9; +pub const NFT_CT_PROTOCOL: ::c_int = 10; +pub const NFT_CT_PROTO_SRC: ::c_int = 11; +pub const NFT_CT_PROTO_DST: ::c_int = 12; +pub const NFT_CT_LABELS: ::c_int = 13; +pub const NFT_CT_PKTS: ::c_int = 14; +pub const NFT_CT_BYTES: ::c_int = 15; + +pub const NFT_LIMIT_PKTS: ::c_int = 0; +pub const NFT_LIMIT_PKT_BYTES: ::c_int = 1; + +pub const NFT_LIMIT_F_INV: ::c_int = 1 << 0; + +pub const NFT_QUEUE_FLAG_BYPASS: ::c_int = 0x01; +pub const NFT_QUEUE_FLAG_CPU_FANOUT: ::c_int = 0x02; +pub const NFT_QUEUE_FLAG_MASK: ::c_int = 0x03; + +pub const NFT_QUOTA_F_INV: ::c_int = 1 << 0; + +pub const NFT_REJECT_ICMP_UNREACH: ::c_int = 0; +pub const NFT_REJECT_TCP_RST: ::c_int = 1; +pub const NFT_REJECT_ICMPX_UNREACH: ::c_int = 2; + +pub const NFT_REJECT_ICMPX_NO_ROUTE: ::c_int = 0; +pub const NFT_REJECT_ICMPX_PORT_UNREACH: ::c_int = 1; +pub const NFT_REJECT_ICMPX_HOST_UNREACH: ::c_int = 2; +pub const NFT_REJECT_ICMPX_ADMIN_PROHIBITED: ::c_int = 3; + +pub const NFT_NAT_SNAT: ::c_int = 0; +pub const NFT_NAT_DNAT: ::c_int = 1; + +pub const NFT_TRACETYPE_UNSPEC: ::c_int = 0; +pub const NFT_TRACETYPE_POLICY: ::c_int = 1; +pub const NFT_TRACETYPE_RETURN: ::c_int = 2; +pub const NFT_TRACETYPE_RULE: ::c_int = 3; + +pub const NFT_NG_INCREMENTAL: ::c_int = 0; +pub const NFT_NG_RANDOM: ::c_int = 1; + +// linux/input.h +pub const FF_MAX: ::__u16 = 0x7f; +pub const FF_CNT: usize = FF_MAX as usize + 1; + +// linux/input-event-codes.h +pub const INPUT_PROP_MAX: ::__u16 = 0x1f; +pub const INPUT_PROP_CNT: usize = INPUT_PROP_MAX as usize + 1; +pub const EV_MAX: ::__u16 = 0x1f; +pub const EV_CNT: usize = EV_MAX as usize + 1; +pub const SYN_MAX: ::__u16 = 0xf; +pub const SYN_CNT: usize = SYN_MAX as usize + 1; +pub const KEY_MAX: ::__u16 = 0x2ff; +pub const KEY_CNT: usize = KEY_MAX as usize + 1; +pub const REL_MAX: ::__u16 = 0x0f; +pub const REL_CNT: usize = REL_MAX as usize + 1; +pub const ABS_MAX: ::__u16 = 0x3f; +pub const ABS_CNT: usize = ABS_MAX as usize + 1; +pub const SW_MAX: ::__u16 = 0x0f; +pub const SW_CNT: usize = SW_MAX as usize + 1; +pub const MSC_MAX: ::__u16 = 0x07; +pub const MSC_CNT: usize = MSC_MAX as usize + 1; +pub const LED_MAX: ::__u16 = 0x0f; +pub const LED_CNT: usize = LED_MAX as usize + 1; +pub const REP_MAX: ::__u16 = 0x01; +pub const REP_CNT: usize = REP_MAX as usize + 1; +pub const SND_MAX: ::__u16 = 0x07; +pub const SND_CNT: usize = SND_MAX as usize + 1; + +// linux/uinput.h +pub const UINPUT_VERSION: ::c_uint = 5; +pub const UINPUT_MAX_NAME_SIZE: usize = 80; + +// bionic/libc/kernel/uapi/linux/if_tun.h +pub const IFF_TUN: ::c_int = 0x0001; +pub const IFF_TAP: ::c_int = 0x0002; +pub const IFF_NAPI: ::c_int = 0x0010; +pub const IFF_NAPI_FRAGS: ::c_int = 0x0020; +pub const IFF_NO_CARRIER: ::c_int = 0x0040; +pub const IFF_NO_PI: ::c_int = 0x1000; +pub const IFF_ONE_QUEUE: ::c_int = 0x2000; +pub const IFF_VNET_HDR: ::c_int = 0x4000; +pub const IFF_TUN_EXCL: ::c_int = 0x8000; +pub const IFF_MULTI_QUEUE: ::c_int = 0x0100; +pub const IFF_ATTACH_QUEUE: ::c_int = 0x0200; +pub const IFF_DETACH_QUEUE: ::c_int = 0x0400; +pub const IFF_PERSIST: ::c_int = 0x0800; +pub const IFF_NOFILTER: ::c_int = 0x1000; +// Features for GSO (TUNSETOFFLOAD) +pub const TUN_F_CSUM: ::c_uint = 0x01; +pub const TUN_F_TSO4: ::c_uint = 0x02; +pub const TUN_F_TSO6: ::c_uint = 0x04; +pub const TUN_F_TSO_ECN: ::c_uint = 0x08; +pub const TUN_F_UFO: ::c_uint = 0x10; +pub const TUN_F_USO4: ::c_uint = 0x20; +pub const TUN_F_USO6: ::c_uint = 0x40; + +// start android/platform/bionic/libc/kernel/uapi/linux/if_ether.h +// from https://android.googlesource.com/platform/bionic/+/HEAD/libc/kernel/uapi/linux/if_ether.h +pub const ETH_ALEN: ::c_int = 6; +pub const ETH_HLEN: ::c_int = 14; +pub const ETH_ZLEN: ::c_int = 60; +pub const ETH_DATA_LEN: ::c_int = 1500; +pub const ETH_FRAME_LEN: ::c_int = 1514; +pub const ETH_FCS_LEN: ::c_int = 4; +pub const ETH_MIN_MTU: ::c_int = 68; +pub const ETH_MAX_MTU: ::c_int = 0xFFFF; +pub const ETH_P_LOOP: ::c_int = 0x0060; +pub const ETH_P_PUP: ::c_int = 0x0200; +pub const ETH_P_PUPAT: ::c_int = 0x0201; +pub const ETH_P_TSN: ::c_int = 0x22F0; +pub const ETH_P_IP: ::c_int = 0x0800; +pub const ETH_P_X25: ::c_int = 0x0805; +pub const ETH_P_ARP: ::c_int = 0x0806; +pub const ETH_P_BPQ: ::c_int = 0x08FF; +pub const ETH_P_IEEEPUP: ::c_int = 0x0a00; +pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01; +pub const ETH_P_BATMAN: ::c_int = 0x4305; +pub const ETH_P_DEC: ::c_int = 0x6000; +pub const ETH_P_DNA_DL: ::c_int = 0x6001; +pub const ETH_P_DNA_RC: ::c_int = 0x6002; +pub const ETH_P_DNA_RT: ::c_int = 0x6003; +pub const ETH_P_LAT: ::c_int = 0x6004; +pub const ETH_P_DIAG: ::c_int = 0x6005; +pub const ETH_P_CUST: ::c_int = 0x6006; +pub const ETH_P_SCA: ::c_int = 0x6007; +pub const ETH_P_TEB: ::c_int = 0x6558; +pub const ETH_P_RARP: ::c_int = 0x8035; +pub const ETH_P_ATALK: ::c_int = 0x809B; +pub const ETH_P_AARP: ::c_int = 0x80F3; +pub const ETH_P_8021Q: ::c_int = 0x8100; +/* see rust-lang/libc#924 pub const ETH_P_ERSPAN: ::c_int = 0x88BE;*/ +pub const ETH_P_IPX: ::c_int = 0x8137; +pub const ETH_P_IPV6: ::c_int = 0x86DD; +pub const ETH_P_PAUSE: ::c_int = 0x8808; +pub const ETH_P_SLOW: ::c_int = 0x8809; +pub const ETH_P_WCCP: ::c_int = 0x883E; +pub const ETH_P_MPLS_UC: ::c_int = 0x8847; +pub const ETH_P_MPLS_MC: ::c_int = 0x8848; +pub const ETH_P_ATMMPOA: ::c_int = 0x884c; +pub const ETH_P_PPP_DISC: ::c_int = 0x8863; +pub const ETH_P_PPP_SES: ::c_int = 0x8864; +pub const ETH_P_LINK_CTL: ::c_int = 0x886c; +pub const ETH_P_ATMFATE: ::c_int = 0x8884; +pub const ETH_P_PAE: ::c_int = 0x888E; +pub const ETH_P_AOE: ::c_int = 0x88A2; +pub const ETH_P_8021AD: ::c_int = 0x88A8; +pub const ETH_P_802_EX1: ::c_int = 0x88B5; +pub const ETH_P_TIPC: ::c_int = 0x88CA; +pub const ETH_P_MACSEC: ::c_int = 0x88E5; +pub const ETH_P_8021AH: ::c_int = 0x88E7; +pub const ETH_P_MVRP: ::c_int = 0x88F5; +pub const ETH_P_1588: ::c_int = 0x88F7; +pub const ETH_P_NCSI: ::c_int = 0x88F8; +pub const ETH_P_PRP: ::c_int = 0x88FB; +pub const ETH_P_FCOE: ::c_int = 0x8906; +/* see rust-lang/libc#924 pub const ETH_P_IBOE: ::c_int = 0x8915;*/ +pub const ETH_P_TDLS: ::c_int = 0x890D; +pub const ETH_P_FIP: ::c_int = 0x8914; +pub const ETH_P_80221: ::c_int = 0x8917; +pub const ETH_P_HSR: ::c_int = 0x892F; +/* see rust-lang/libc#924 pub const ETH_P_NSH: ::c_int = 0x894F;*/ +pub const ETH_P_LOOPBACK: ::c_int = 0x9000; +pub const ETH_P_QINQ1: ::c_int = 0x9100; +pub const ETH_P_QINQ2: ::c_int = 0x9200; +pub const ETH_P_QINQ3: ::c_int = 0x9300; +pub const ETH_P_EDSA: ::c_int = 0xDADA; +/* see rust-lang/libc#924 pub const ETH_P_IFE: ::c_int = 0xED3E;*/ +pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB; +pub const ETH_P_802_3_MIN: ::c_int = 0x0600; +pub const ETH_P_802_3: ::c_int = 0x0001; +pub const ETH_P_AX25: ::c_int = 0x0002; +pub const ETH_P_ALL: ::c_int = 0x0003; +pub const ETH_P_802_2: ::c_int = 0x0004; +pub const ETH_P_SNAP: ::c_int = 0x0005; +pub const ETH_P_DDCMP: ::c_int = 0x0006; +pub const ETH_P_WAN_PPP: ::c_int = 0x0007; +pub const ETH_P_PPP_MP: ::c_int = 0x0008; +pub const ETH_P_LOCALTALK: ::c_int = 0x0009; +pub const ETH_P_CAN: ::c_int = 0x000C; +pub const ETH_P_CANFD: ::c_int = 0x000D; +pub const ETH_P_PPPTALK: ::c_int = 0x0010; +pub const ETH_P_TR_802_2: ::c_int = 0x0011; +pub const ETH_P_MOBITEX: ::c_int = 0x0015; +pub const ETH_P_CONTROL: ::c_int = 0x0016; +pub const ETH_P_IRDA: ::c_int = 0x0017; +pub const ETH_P_ECONET: ::c_int = 0x0018; +pub const ETH_P_HDLC: ::c_int = 0x0019; +pub const ETH_P_ARCNET: ::c_int = 0x001A; +pub const ETH_P_DSA: ::c_int = 0x001B; +pub const ETH_P_TRAILER: ::c_int = 0x001C; +pub const ETH_P_PHONET: ::c_int = 0x00F5; +pub const ETH_P_IEEE802154: ::c_int = 0x00F6; +pub const ETH_P_CAIF: ::c_int = 0x00F7; +pub const ETH_P_XDSA: ::c_int = 0x00F8; +/* see rust-lang/libc#924 pub const ETH_P_MAP: ::c_int = 0x00F9;*/ +// end android/platform/bionic/libc/kernel/uapi/linux/if_ether.h + +// start android/platform/bionic/libc/kernel/uapi/linux/neighbour.h +pub const NDA_UNSPEC: ::c_ushort = 0; +pub const NDA_DST: ::c_ushort = 1; +pub const NDA_LLADDR: ::c_ushort = 2; +pub const NDA_CACHEINFO: ::c_ushort = 3; +pub const NDA_PROBES: ::c_ushort = 4; +pub const NDA_VLAN: ::c_ushort = 5; +pub const NDA_PORT: ::c_ushort = 6; +pub const NDA_VNI: ::c_ushort = 7; +pub const NDA_IFINDEX: ::c_ushort = 8; +pub const NDA_MASTER: ::c_ushort = 9; +pub const NDA_LINK_NETNSID: ::c_ushort = 10; +pub const NDA_SRC_VNI: ::c_ushort = 11; +pub const NDA_PROTOCOL: ::c_ushort = 12; +pub const NDA_NH_ID: ::c_ushort = 13; +pub const NDA_FDB_EXT_ATTRS: ::c_ushort = 14; +pub const NDA_FLAGS_EXT: ::c_ushort = 15; +pub const NDA_NDM_STATE_MASK: ::c_ushort = 16; +pub const NDA_NDM_FLAGS_MASK: ::c_ushort = 17; + +pub const NTF_USE: u8 = 0x01; +pub const NTF_SELF: u8 = 0x02; +pub const NTF_MASTER: u8 = 0x04; +pub const NTF_PROXY: u8 = 0x08; +pub const NTF_EXT_LEARNED: u8 = 0x10; +pub const NTF_OFFLOADED: u8 = 0x20; +pub const NTF_STICKY: u8 = 0x40; +pub const NTF_ROUTER: u8 = 0x80; + +pub const NTF_EXT_MANAGED: u8 = 0x01; +pub const NTF_EXT_LOCKED: u8 = 0x02; + +pub const NUD_NONE: u16 = 0x00; +pub const NUD_INCOMPLETE: u16 = 0x01; +pub const NUD_REACHABLE: u16 = 0x02; +pub const NUD_STALE: u16 = 0x04; +pub const NUD_DELAY: u16 = 0x08; +pub const NUD_PROBE: u16 = 0x10; +pub const NUD_FAILED: u16 = 0x20; +pub const NUD_NOARP: u16 = 0x40; +pub const NUD_PERMANENT: u16 = 0x80; + +pub const NDTPA_UNSPEC: ::c_ushort = 0; +pub const NDTPA_IFINDEX: ::c_ushort = 1; +pub const NDTPA_REFCNT: ::c_ushort = 2; +pub const NDTPA_REACHABLE_TIME: ::c_ushort = 3; +pub const NDTPA_BASE_REACHABLE_TIME: ::c_ushort = 4; +pub const NDTPA_RETRANS_TIME: ::c_ushort = 5; +pub const NDTPA_GC_STALETIME: ::c_ushort = 6; +pub const NDTPA_DELAY_PROBE_TIME: ::c_ushort = 7; +pub const NDTPA_QUEUE_LEN: ::c_ushort = 8; +pub const NDTPA_APP_PROBES: ::c_ushort = 9; +pub const NDTPA_UCAST_PROBES: ::c_ushort = 10; +pub const NDTPA_MCAST_PROBES: ::c_ushort = 11; +pub const NDTPA_ANYCAST_DELAY: ::c_ushort = 12; +pub const NDTPA_PROXY_DELAY: ::c_ushort = 13; +pub const NDTPA_PROXY_QLEN: ::c_ushort = 14; +pub const NDTPA_LOCKTIME: ::c_ushort = 15; +pub const NDTPA_QUEUE_LENBYTES: ::c_ushort = 16; +pub const NDTPA_MCAST_REPROBES: ::c_ushort = 17; +pub const NDTPA_PAD: ::c_ushort = 18; +pub const NDTPA_INTERVAL_PROBE_TIME_MS: ::c_ushort = 19; + +pub const NDTA_UNSPEC: ::c_ushort = 0; +pub const NDTA_NAME: ::c_ushort = 1; +pub const NDTA_THRESH1: ::c_ushort = 2; +pub const NDTA_THRESH2: ::c_ushort = 3; +pub const NDTA_THRESH3: ::c_ushort = 4; +pub const NDTA_CONFIG: ::c_ushort = 5; +pub const NDTA_PARMS: ::c_ushort = 6; +pub const NDTA_STATS: ::c_ushort = 7; +pub const NDTA_GC_INTERVAL: ::c_ushort = 8; +pub const NDTA_PAD: ::c_ushort = 9; + +pub const FDB_NOTIFY_BIT: u16 = 0x01; +pub const FDB_NOTIFY_INACTIVE_BIT: u16 = 0x02; + +pub const NFEA_UNSPEC: ::c_ushort = 0; +pub const NFEA_ACTIVITY_NOTIFY: ::c_ushort = 1; +pub const NFEA_DONT_REFRESH: ::c_ushort = 2; +// end android/platform/bionic/libc/kernel/uapi/linux/neighbour.h + +pub const SIOCADDRT: ::c_ulong = 0x0000890B; +pub const SIOCDELRT: ::c_ulong = 0x0000890C; +pub const SIOCRTMSG: ::c_ulong = 0x0000890D; +pub const SIOCGIFNAME: ::c_ulong = 0x00008910; +pub const SIOCSIFLINK: ::c_ulong = 0x00008911; +pub const SIOCGIFCONF: ::c_ulong = 0x00008912; +pub const SIOCGIFFLAGS: ::c_ulong = 0x00008913; +pub const SIOCSIFFLAGS: ::c_ulong = 0x00008914; +pub const SIOCGIFADDR: ::c_ulong = 0x00008915; +pub const SIOCSIFADDR: ::c_ulong = 0x00008916; +pub const SIOCGIFDSTADDR: ::c_ulong = 0x00008917; +pub const SIOCSIFDSTADDR: ::c_ulong = 0x00008918; +pub const SIOCGIFBRDADDR: ::c_ulong = 0x00008919; +pub const SIOCSIFBRDADDR: ::c_ulong = 0x0000891A; +pub const SIOCGIFNETMASK: ::c_ulong = 0x0000891B; +pub const SIOCSIFNETMASK: ::c_ulong = 0x0000891C; +pub const SIOCGIFMETRIC: ::c_ulong = 0x0000891D; +pub const SIOCSIFMETRIC: ::c_ulong = 0x0000891E; +pub const SIOCGIFMEM: ::c_ulong = 0x0000891F; +pub const SIOCSIFMEM: ::c_ulong = 0x00008920; +pub const SIOCGIFMTU: ::c_ulong = 0x00008921; +pub const SIOCSIFMTU: ::c_ulong = 0x00008922; +pub const SIOCSIFNAME: ::c_ulong = 0x00008923; +pub const SIOCSIFHWADDR: ::c_ulong = 0x00008924; +pub const SIOCGIFENCAP: ::c_ulong = 0x00008925; +pub const SIOCSIFENCAP: ::c_ulong = 0x00008926; +pub const SIOCGIFHWADDR: ::c_ulong = 0x00008927; +pub const SIOCGIFSLAVE: ::c_ulong = 0x00008929; +pub const SIOCSIFSLAVE: ::c_ulong = 0x00008930; +pub const SIOCADDMULTI: ::c_ulong = 0x00008931; +pub const SIOCDELMULTI: ::c_ulong = 0x00008932; +pub const SIOCGIFINDEX: ::c_ulong = 0x00008933; +pub const SIOGIFINDEX: ::c_ulong = SIOCGIFINDEX; +pub const SIOCSIFPFLAGS: ::c_ulong = 0x00008934; +pub const SIOCGIFPFLAGS: ::c_ulong = 0x00008935; +pub const SIOCDIFADDR: ::c_ulong = 0x00008936; +pub const SIOCSIFHWBROADCAST: ::c_ulong = 0x00008937; +pub const SIOCGIFCOUNT: ::c_ulong = 0x00008938; +pub const SIOCGIFBR: ::c_ulong = 0x00008940; +pub const SIOCSIFBR: ::c_ulong = 0x00008941; +pub const SIOCGIFTXQLEN: ::c_ulong = 0x00008942; +pub const SIOCSIFTXQLEN: ::c_ulong = 0x00008943; +pub const SIOCETHTOOL: ::c_ulong = 0x00008946; +pub const SIOCGMIIPHY: ::c_ulong = 0x00008947; +pub const SIOCGMIIREG: ::c_ulong = 0x00008948; +pub const SIOCSMIIREG: ::c_ulong = 0x00008949; +pub const SIOCWANDEV: ::c_ulong = 0x0000894A; +pub const SIOCOUTQNSD: ::c_ulong = 0x0000894B; +pub const SIOCGSKNS: ::c_ulong = 0x0000894C; +pub const SIOCDARP: ::c_ulong = 0x00008953; +pub const SIOCGARP: ::c_ulong = 0x00008954; +pub const SIOCSARP: ::c_ulong = 0x00008955; +pub const SIOCDRARP: ::c_ulong = 0x00008960; +pub const SIOCGRARP: ::c_ulong = 0x00008961; +pub const SIOCSRARP: ::c_ulong = 0x00008962; +pub const SIOCGIFMAP: ::c_ulong = 0x00008970; +pub const SIOCSIFMAP: ::c_ulong = 0x00008971; +pub const SIOCADDDLCI: ::c_ulong = 0x00008980; +pub const SIOCDELDLCI: ::c_ulong = 0x00008981; +pub const SIOCGIFVLAN: ::c_ulong = 0x00008982; +pub const SIOCSIFVLAN: ::c_ulong = 0x00008983; +pub const SIOCBONDENSLAVE: ::c_ulong = 0x00008990; +pub const SIOCBONDRELEASE: ::c_ulong = 0x00008991; +pub const SIOCBONDSETHWADDR: ::c_ulong = 0x00008992; +pub const SIOCBONDSLAVEINFOQUERY: ::c_ulong = 0x00008993; +pub const SIOCBONDINFOQUERY: ::c_ulong = 0x00008994; +pub const SIOCBONDCHANGEACTIVE: ::c_ulong = 0x00008995; +pub const SIOCBRADDBR: ::c_ulong = 0x000089a0; +pub const SIOCBRDELBR: ::c_ulong = 0x000089a1; +pub const SIOCBRADDIF: ::c_ulong = 0x000089a2; +pub const SIOCBRDELIF: ::c_ulong = 0x000089a3; +pub const SIOCSHWTSTAMP: ::c_ulong = 0x000089b0; +pub const SIOCGHWTSTAMP: ::c_ulong = 0x000089b1; +pub const SIOCDEVPRIVATE: ::c_ulong = 0x000089F0; +pub const SIOCPROTOPRIVATE: ::c_ulong = 0x000089E0; + +// linux/module.h +pub const MODULE_INIT_IGNORE_MODVERSIONS: ::c_uint = 0x0001; +pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002; + +// linux/net_tstamp.h +pub const SOF_TIMESTAMPING_TX_HARDWARE: ::c_uint = 1 << 0; +pub const SOF_TIMESTAMPING_TX_SOFTWARE: ::c_uint = 1 << 1; +pub const SOF_TIMESTAMPING_RX_HARDWARE: ::c_uint = 1 << 2; +pub const SOF_TIMESTAMPING_RX_SOFTWARE: ::c_uint = 1 << 3; +pub const SOF_TIMESTAMPING_SOFTWARE: ::c_uint = 1 << 4; +pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5; +pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6; +pub const SOF_TIMESTAMPING_OPT_ID: ::c_uint = 1 << 7; +pub const SOF_TIMESTAMPING_TX_SCHED: ::c_uint = 1 << 8; +pub const SOF_TIMESTAMPING_TX_ACK: ::c_uint = 1 << 9; +pub const SOF_TIMESTAMPING_OPT_CMSG: ::c_uint = 1 << 10; +pub const SOF_TIMESTAMPING_OPT_TSONLY: ::c_uint = 1 << 11; +pub const SOF_TIMESTAMPING_OPT_STATS: ::c_uint = 1 << 12; +pub const SOF_TIMESTAMPING_OPT_PKTINFO: ::c_uint = 1 << 13; +pub const SOF_TIMESTAMPING_OPT_TX_SWHW: ::c_uint = 1 << 14; + +#[deprecated( + since = "0.2.55", + note = "ENOATTR is not available on Android; use ENODATA instead" +)] +pub const ENOATTR: ::c_int = ::ENODATA; + +// linux/if_alg.h +pub const ALG_SET_KEY: ::c_int = 1; +pub const ALG_SET_IV: ::c_int = 2; +pub const ALG_SET_OP: ::c_int = 3; +pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4; +pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; +pub const ALG_SET_DRBG_ENTROPY: ::c_int = 6; + +pub const ALG_OP_DECRYPT: ::c_int = 0; +pub const ALG_OP_ENCRYPT: ::c_int = 1; + +// sys/mman.h +pub const MLOCK_ONFAULT: ::c_int = 0x01; + +// uapi/linux/vm_sockets.h +pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF; +pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0; +pub const VMADDR_CID_LOCAL: ::c_uint = 1; +pub const VMADDR_CID_HOST: ::c_uint = 2; +pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF; + +// uapi/linux/inotify.h +pub const IN_ACCESS: u32 = 0x0000_0001; +pub const IN_MODIFY: u32 = 0x0000_0002; +pub const IN_ATTRIB: u32 = 0x0000_0004; +pub const IN_CLOSE_WRITE: u32 = 0x0000_0008; +pub const IN_CLOSE_NOWRITE: u32 = 0x0000_0010; +pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE; +pub const IN_OPEN: u32 = 0x0000_0020; +pub const IN_MOVED_FROM: u32 = 0x0000_0040; +pub const IN_MOVED_TO: u32 = 0x0000_0080; +pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO; +pub const IN_CREATE: u32 = 0x0000_0100; +pub const IN_DELETE: u32 = 0x0000_0200; +pub const IN_DELETE_SELF: u32 = 0x0000_0400; +pub const IN_MOVE_SELF: u32 = 0x0000_0800; +pub const IN_UNMOUNT: u32 = 0x0000_2000; +pub const IN_Q_OVERFLOW: u32 = 0x0000_4000; +pub const IN_IGNORED: u32 = 0x0000_8000; +pub const IN_ONLYDIR: u32 = 0x0100_0000; +pub const IN_DONT_FOLLOW: u32 = 0x0200_0000; +pub const IN_EXCL_UNLINK: u32 = 0x0400_0000; + +pub const IN_MASK_CREATE: u32 = 0x1000_0000; +pub const IN_MASK_ADD: u32 = 0x2000_0000; +pub const IN_ISDIR: u32 = 0x4000_0000; +pub const IN_ONESHOT: u32 = 0x8000_0000; + +pub const IN_ALL_EVENTS: u32 = IN_ACCESS + | IN_MODIFY + | IN_ATTRIB + | IN_CLOSE_WRITE + | IN_CLOSE_NOWRITE + | IN_OPEN + | IN_MOVED_FROM + | IN_MOVED_TO + | IN_DELETE + | IN_CREATE + | IN_DELETE_SELF + | IN_MOVE_SELF; + +pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; +pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + +pub const FUTEX_WAIT: ::c_int = 0; +pub const FUTEX_WAKE: ::c_int = 1; +pub const FUTEX_FD: ::c_int = 2; +pub const FUTEX_REQUEUE: ::c_int = 3; +pub const FUTEX_CMP_REQUEUE: ::c_int = 4; +pub const FUTEX_WAKE_OP: ::c_int = 5; +pub const FUTEX_LOCK_PI: ::c_int = 6; +pub const FUTEX_UNLOCK_PI: ::c_int = 7; +pub const FUTEX_TRYLOCK_PI: ::c_int = 8; +pub const FUTEX_WAIT_BITSET: ::c_int = 9; +pub const FUTEX_WAKE_BITSET: ::c_int = 10; +pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11; +pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12; + +pub const FUTEX_PRIVATE_FLAG: ::c_int = 128; +pub const FUTEX_CLOCK_REALTIME: ::c_int = 256; +pub const FUTEX_CMD_MASK: ::c_int = !(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME); + +// linux/errqueue.h +pub const SO_EE_ORIGIN_NONE: u8 = 0; +pub const SO_EE_ORIGIN_LOCAL: u8 = 1; +pub const SO_EE_ORIGIN_ICMP: u8 = 2; +pub const SO_EE_ORIGIN_ICMP6: u8 = 3; +pub const SO_EE_ORIGIN_TXSTATUS: u8 = 4; +pub const SO_EE_ORIGIN_TIMESTAMPING: u8 = SO_EE_ORIGIN_TXSTATUS; + +// errno.h +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EWOULDBLOCK: ::c_int = EAGAIN; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +// linux/sched.h +pub const SCHED_NORMAL: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; +pub const SCHED_DEADLINE: ::c_int = 6; + +pub const SCHED_RESET_ON_FORK: ::c_int = 0x40000000; + +pub const CLONE_PIDFD: ::c_int = 0x1000; + +// linux/membarrier.h +pub const MEMBARRIER_CMD_QUERY: ::c_int = 0; +pub const MEMBARRIER_CMD_GLOBAL: ::c_int = 1 << 0; +pub const MEMBARRIER_CMD_GLOBAL_EXPEDITED: ::c_int = 1 << 1; +pub const MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: ::c_int = 1 << 2; +pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED: ::c_int = 1 << 3; +pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: ::c_int = 1 << 4; +pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 5; +pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 6; +pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 7; +pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 8; + +// linux/mempolicy.h +pub const MPOL_DEFAULT: ::c_int = 0; +pub const MPOL_PREFERRED: ::c_int = 1; +pub const MPOL_BIND: ::c_int = 2; +pub const MPOL_INTERLEAVE: ::c_int = 3; +pub const MPOL_LOCAL: ::c_int = 4; +pub const MPOL_F_NUMA_BALANCING: ::c_int = 1 << 13; +pub const MPOL_F_RELATIVE_NODES: ::c_int = 1 << 14; +pub const MPOL_F_STATIC_NODES: ::c_int = 1 << 15; + +// bits/seek_constants.h +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; + +// sys/socket.h +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +pub const SOMAXCONN: ::c_int = 128; + +// sys/prctl.h +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +// sys/system_properties.h +pub const PROP_VALUE_MAX: ::c_int = 92; +pub const PROP_NAME_MAX: ::c_int = 32; + +// sys/prctl.h +pub const PR_SET_VMA: ::c_int = 0x53564d41; +pub const PR_SET_VMA_ANON_NAME: ::c_int = 0; +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; +pub const PR_GET_TIMING: ::c_int = 13; +pub const PR_SET_TIMING: ::c_int = 14; +pub const PR_TIMING_STATISTICAL: ::c_int = 0; +pub const PR_TIMING_TIMESTAMP: ::c_int = 1; + +// linux/if_addr.h +pub const IFA_UNSPEC: ::c_ushort = 0; +pub const IFA_ADDRESS: ::c_ushort = 1; +pub const IFA_LOCAL: ::c_ushort = 2; +pub const IFA_LABEL: ::c_ushort = 3; +pub const IFA_BROADCAST: ::c_ushort = 4; +pub const IFA_ANYCAST: ::c_ushort = 5; +pub const IFA_CACHEINFO: ::c_ushort = 6; +pub const IFA_MULTICAST: ::c_ushort = 7; + +pub const IFA_F_SECONDARY: u32 = 0x01; +pub const IFA_F_TEMPORARY: u32 = 0x01; +pub const IFA_F_NODAD: u32 = 0x02; +pub const IFA_F_OPTIMISTIC: u32 = 0x04; +pub const IFA_F_DADFAILED: u32 = 0x08; +pub const IFA_F_HOMEADDRESS: u32 = 0x10; +pub const IFA_F_DEPRECATED: u32 = 0x20; +pub const IFA_F_TENTATIVE: u32 = 0x40; +pub const IFA_F_PERMANENT: u32 = 0x80; + +// linux/if_link.h +pub const IFLA_UNSPEC: ::c_ushort = 0; +pub const IFLA_ADDRESS: ::c_ushort = 1; +pub const IFLA_BROADCAST: ::c_ushort = 2; +pub const IFLA_IFNAME: ::c_ushort = 3; +pub const IFLA_MTU: ::c_ushort = 4; +pub const IFLA_LINK: ::c_ushort = 5; +pub const IFLA_QDISC: ::c_ushort = 6; +pub const IFLA_STATS: ::c_ushort = 7; +pub const IFLA_COST: ::c_ushort = 8; +pub const IFLA_PRIORITY: ::c_ushort = 9; +pub const IFLA_MASTER: ::c_ushort = 10; +pub const IFLA_WIRELESS: ::c_ushort = 11; +pub const IFLA_PROTINFO: ::c_ushort = 12; +pub const IFLA_TXQLEN: ::c_ushort = 13; +pub const IFLA_MAP: ::c_ushort = 14; +pub const IFLA_WEIGHT: ::c_ushort = 15; +pub const IFLA_OPERSTATE: ::c_ushort = 16; +pub const IFLA_LINKMODE: ::c_ushort = 17; +pub const IFLA_LINKINFO: ::c_ushort = 18; +pub const IFLA_NET_NS_PID: ::c_ushort = 19; +pub const IFLA_IFALIAS: ::c_ushort = 20; +pub const IFLA_NUM_VF: ::c_ushort = 21; +pub const IFLA_VFINFO_LIST: ::c_ushort = 22; +pub const IFLA_STATS64: ::c_ushort = 23; +pub const IFLA_VF_PORTS: ::c_ushort = 24; +pub const IFLA_PORT_SELF: ::c_ushort = 25; +pub const IFLA_AF_SPEC: ::c_ushort = 26; +pub const IFLA_GROUP: ::c_ushort = 27; +pub const IFLA_NET_NS_FD: ::c_ushort = 28; +pub const IFLA_EXT_MASK: ::c_ushort = 29; +pub const IFLA_PROMISCUITY: ::c_ushort = 30; +pub const IFLA_NUM_TX_QUEUES: ::c_ushort = 31; +pub const IFLA_NUM_RX_QUEUES: ::c_ushort = 32; +pub const IFLA_CARRIER: ::c_ushort = 33; +pub const IFLA_PHYS_PORT_ID: ::c_ushort = 34; +pub const IFLA_CARRIER_CHANGES: ::c_ushort = 35; +pub const IFLA_PHYS_SWITCH_ID: ::c_ushort = 36; +pub const IFLA_LINK_NETNSID: ::c_ushort = 37; +pub const IFLA_PHYS_PORT_NAME: ::c_ushort = 38; +pub const IFLA_PROTO_DOWN: ::c_ushort = 39; +pub const IFLA_GSO_MAX_SEGS: ::c_ushort = 40; +pub const IFLA_GSO_MAX_SIZE: ::c_ushort = 41; +pub const IFLA_PAD: ::c_ushort = 42; +pub const IFLA_XDP: ::c_ushort = 43; +pub const IFLA_EVENT: ::c_ushort = 44; +pub const IFLA_NEW_NETNSID: ::c_ushort = 45; +pub const IFLA_IF_NETNSID: ::c_ushort = 46; +pub const IFLA_TARGET_NETNSID: ::c_ushort = IFLA_IF_NETNSID; +pub const IFLA_CARRIER_UP_COUNT: ::c_ushort = 47; +pub const IFLA_CARRIER_DOWN_COUNT: ::c_ushort = 48; +pub const IFLA_NEW_IFINDEX: ::c_ushort = 49; +pub const IFLA_MIN_MTU: ::c_ushort = 50; +pub const IFLA_MAX_MTU: ::c_ushort = 51; +pub const IFLA_PROP_LIST: ::c_ushort = 52; +pub const IFLA_ALT_IFNAME: ::c_ushort = 53; +pub const IFLA_PERM_ADDRESS: ::c_ushort = 54; +pub const IFLA_PROTO_DOWN_REASON: ::c_ushort = 55; +pub const IFLA_PARENT_DEV_NAME: ::c_ushort = 56; +pub const IFLA_PARENT_DEV_BUS_NAME: ::c_ushort = 57; +pub const IFLA_GRO_MAX_SIZE: ::c_ushort = 58; +pub const IFLA_TSO_MAX_SIZE: ::c_ushort = 59; +pub const IFLA_TSO_MAX_SEGS: ::c_ushort = 60; +pub const IFLA_ALLMULTI: ::c_ushort = 61; +pub const IFLA_DEVLINK_PORT: ::c_ushort = 62; +pub const IFLA_GSO_IPV4_MAX_SIZE: ::c_ushort = 63; +pub const IFLA_GRO_IPV4_MAX_SIZE: ::c_ushort = 64; + +pub const IFLA_INFO_UNSPEC: ::c_ushort = 0; +pub const IFLA_INFO_KIND: ::c_ushort = 1; +pub const IFLA_INFO_DATA: ::c_ushort = 2; +pub const IFLA_INFO_XSTATS: ::c_ushort = 3; +pub const IFLA_INFO_SLAVE_KIND: ::c_ushort = 4; +pub const IFLA_INFO_SLAVE_DATA: ::c_ushort = 5; + +// linux/rtnetlink.h +pub const TCA_UNSPEC: ::c_ushort = 0; +pub const TCA_KIND: ::c_ushort = 1; +pub const TCA_OPTIONS: ::c_ushort = 2; +pub const TCA_STATS: ::c_ushort = 3; +pub const TCA_XSTATS: ::c_ushort = 4; +pub const TCA_RATE: ::c_ushort = 5; +pub const TCA_FCNT: ::c_ushort = 6; +pub const TCA_STATS2: ::c_ushort = 7; +pub const TCA_STAB: ::c_ushort = 8; + +pub const RTM_NEWLINK: u16 = 16; +pub const RTM_DELLINK: u16 = 17; +pub const RTM_GETLINK: u16 = 18; +pub const RTM_SETLINK: u16 = 19; +pub const RTM_NEWADDR: u16 = 20; +pub const RTM_DELADDR: u16 = 21; +pub const RTM_GETADDR: u16 = 22; +pub const RTM_NEWROUTE: u16 = 24; +pub const RTM_DELROUTE: u16 = 25; +pub const RTM_GETROUTE: u16 = 26; +pub const RTM_NEWNEIGH: u16 = 28; +pub const RTM_DELNEIGH: u16 = 29; +pub const RTM_GETNEIGH: u16 = 30; +pub const RTM_NEWRULE: u16 = 32; +pub const RTM_DELRULE: u16 = 33; +pub const RTM_GETRULE: u16 = 34; +pub const RTM_NEWQDISC: u16 = 36; +pub const RTM_DELQDISC: u16 = 37; +pub const RTM_GETQDISC: u16 = 38; +pub const RTM_NEWTCLASS: u16 = 40; +pub const RTM_DELTCLASS: u16 = 41; +pub const RTM_GETTCLASS: u16 = 42; +pub const RTM_NEWTFILTER: u16 = 44; +pub const RTM_DELTFILTER: u16 = 45; +pub const RTM_GETTFILTER: u16 = 46; +pub const RTM_NEWACTION: u16 = 48; +pub const RTM_DELACTION: u16 = 49; +pub const RTM_GETACTION: u16 = 50; +pub const RTM_NEWPREFIX: u16 = 52; +pub const RTM_GETMULTICAST: u16 = 58; +pub const RTM_GETANYCAST: u16 = 62; +pub const RTM_NEWNEIGHTBL: u16 = 64; +pub const RTM_GETNEIGHTBL: u16 = 66; +pub const RTM_SETNEIGHTBL: u16 = 67; +pub const RTM_NEWNDUSEROPT: u16 = 68; +pub const RTM_NEWADDRLABEL: u16 = 72; +pub const RTM_DELADDRLABEL: u16 = 73; +pub const RTM_GETADDRLABEL: u16 = 74; +pub const RTM_GETDCB: u16 = 78; +pub const RTM_SETDCB: u16 = 79; +pub const RTM_NEWNETCONF: u16 = 80; +pub const RTM_GETNETCONF: u16 = 82; +pub const RTM_NEWMDB: u16 = 84; +pub const RTM_DELMDB: u16 = 85; +pub const RTM_GETMDB: u16 = 86; +pub const RTM_NEWNSID: u16 = 88; +pub const RTM_DELNSID: u16 = 89; +pub const RTM_GETNSID: u16 = 90; + +pub const RTM_F_NOTIFY: ::c_uint = 0x100; +pub const RTM_F_CLONED: ::c_uint = 0x200; +pub const RTM_F_EQUALIZE: ::c_uint = 0x400; +pub const RTM_F_PREFIX: ::c_uint = 0x800; + +pub const RTA_UNSPEC: ::c_ushort = 0; +pub const RTA_DST: ::c_ushort = 1; +pub const RTA_SRC: ::c_ushort = 2; +pub const RTA_IIF: ::c_ushort = 3; +pub const RTA_OIF: ::c_ushort = 4; +pub const RTA_GATEWAY: ::c_ushort = 5; +pub const RTA_PRIORITY: ::c_ushort = 6; +pub const RTA_PREFSRC: ::c_ushort = 7; +pub const RTA_METRICS: ::c_ushort = 8; +pub const RTA_MULTIPATH: ::c_ushort = 9; +pub const RTA_PROTOINFO: ::c_ushort = 10; // No longer used +pub const RTA_FLOW: ::c_ushort = 11; +pub const RTA_CACHEINFO: ::c_ushort = 12; +pub const RTA_SESSION: ::c_ushort = 13; // No longer used +pub const RTA_MP_ALGO: ::c_ushort = 14; // No longer used +pub const RTA_TABLE: ::c_ushort = 15; +pub const RTA_MARK: ::c_ushort = 16; +pub const RTA_MFC_STATS: ::c_ushort = 17; + +pub const RTN_UNSPEC: ::c_uchar = 0; +pub const RTN_UNICAST: ::c_uchar = 1; +pub const RTN_LOCAL: ::c_uchar = 2; +pub const RTN_BROADCAST: ::c_uchar = 3; +pub const RTN_ANYCAST: ::c_uchar = 4; +pub const RTN_MULTICAST: ::c_uchar = 5; +pub const RTN_BLACKHOLE: ::c_uchar = 6; +pub const RTN_UNREACHABLE: ::c_uchar = 7; +pub const RTN_PROHIBIT: ::c_uchar = 8; +pub const RTN_THROW: ::c_uchar = 9; +pub const RTN_NAT: ::c_uchar = 10; +pub const RTN_XRESOLVE: ::c_uchar = 11; + +pub const RTPROT_UNSPEC: ::c_uchar = 0; +pub const RTPROT_REDIRECT: ::c_uchar = 1; +pub const RTPROT_KERNEL: ::c_uchar = 2; +pub const RTPROT_BOOT: ::c_uchar = 3; +pub const RTPROT_STATIC: ::c_uchar = 4; + +pub const RT_SCOPE_UNIVERSE: ::c_uchar = 0; +pub const RT_SCOPE_SITE: ::c_uchar = 200; +pub const RT_SCOPE_LINK: ::c_uchar = 253; +pub const RT_SCOPE_HOST: ::c_uchar = 254; +pub const RT_SCOPE_NOWHERE: ::c_uchar = 255; + +pub const RT_TABLE_UNSPEC: ::c_uchar = 0; +pub const RT_TABLE_COMPAT: ::c_uchar = 252; +pub const RT_TABLE_DEFAULT: ::c_uchar = 253; +pub const RT_TABLE_MAIN: ::c_uchar = 254; +pub const RT_TABLE_LOCAL: ::c_uchar = 255; + +pub const RTMSG_NEWDEVICE: u32 = 0x11; +pub const RTMSG_DELDEVICE: u32 = 0x12; +pub const RTMSG_NEWROUTE: u32 = 0x21; +pub const RTMSG_DELROUTE: u32 = 0x22; + +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_NET: ::c_int = 3; +pub const CTL_FS: ::c_int = 5; +pub const CTL_DEBUG: ::c_int = 6; +pub const CTL_DEV: ::c_int = 7; +pub const CTL_BUS: ::c_int = 8; +pub const CTL_ABI: ::c_int = 9; +pub const CTL_CPU: ::c_int = 10; + +pub const CTL_BUS_ISA: ::c_int = 1; + +pub const INOTIFY_MAX_USER_INSTANCES: ::c_int = 1; +pub const INOTIFY_MAX_USER_WATCHES: ::c_int = 2; +pub const INOTIFY_MAX_QUEUED_EVENTS: ::c_int = 3; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_SECUREMASK: ::c_int = 5; +pub const KERN_PROF: ::c_int = 6; +pub const KERN_NODENAME: ::c_int = 7; +pub const KERN_DOMAINNAME: ::c_int = 8; +pub const KERN_PANIC: ::c_int = 15; +pub const KERN_REALROOTDEV: ::c_int = 16; +pub const KERN_SPARC_REBOOT: ::c_int = 21; +pub const KERN_CTLALTDEL: ::c_int = 22; +pub const KERN_PRINTK: ::c_int = 23; +pub const KERN_NAMETRANS: ::c_int = 24; +pub const KERN_PPC_HTABRECLAIM: ::c_int = 25; +pub const KERN_PPC_ZEROPAGED: ::c_int = 26; +pub const KERN_PPC_POWERSAVE_NAP: ::c_int = 27; +pub const KERN_MODPROBE: ::c_int = 28; +pub const KERN_SG_BIG_BUFF: ::c_int = 29; +pub const KERN_ACCT: ::c_int = 30; +pub const KERN_PPC_L2CR: ::c_int = 31; +pub const KERN_RTSIGNR: ::c_int = 32; +pub const KERN_RTSIGMAX: ::c_int = 33; +pub const KERN_SHMMAX: ::c_int = 34; +pub const KERN_MSGMAX: ::c_int = 35; +pub const KERN_MSGMNB: ::c_int = 36; +pub const KERN_MSGPOOL: ::c_int = 37; +pub const KERN_SYSRQ: ::c_int = 38; +pub const KERN_MAX_THREADS: ::c_int = 39; +pub const KERN_RANDOM: ::c_int = 40; +pub const KERN_SHMALL: ::c_int = 41; +pub const KERN_MSGMNI: ::c_int = 42; +pub const KERN_SEM: ::c_int = 43; +pub const KERN_SPARC_STOP_A: ::c_int = 44; +pub const KERN_SHMMNI: ::c_int = 45; +pub const KERN_OVERFLOWUID: ::c_int = 46; +pub const KERN_OVERFLOWGID: ::c_int = 47; +pub const KERN_SHMPATH: ::c_int = 48; +pub const KERN_HOTPLUG: ::c_int = 49; +pub const KERN_IEEE_EMULATION_WARNINGS: ::c_int = 50; +pub const KERN_S390_USER_DEBUG_LOGGING: ::c_int = 51; +pub const KERN_CORE_USES_PID: ::c_int = 52; +pub const KERN_TAINTED: ::c_int = 53; +pub const KERN_CADPID: ::c_int = 54; +pub const KERN_PIDMAX: ::c_int = 55; +pub const KERN_CORE_PATTERN: ::c_int = 56; +pub const KERN_PANIC_ON_OOPS: ::c_int = 57; +pub const KERN_HPPA_PWRSW: ::c_int = 58; +pub const KERN_HPPA_UNALIGNED: ::c_int = 59; +pub const KERN_PRINTK_RATELIMIT: ::c_int = 60; +pub const KERN_PRINTK_RATELIMIT_BURST: ::c_int = 61; +pub const KERN_PTY: ::c_int = 62; +pub const KERN_NGROUPS_MAX: ::c_int = 63; +pub const KERN_SPARC_SCONS_PWROFF: ::c_int = 64; +pub const KERN_HZ_TIMER: ::c_int = 65; +pub const KERN_UNKNOWN_NMI_PANIC: ::c_int = 66; +pub const KERN_BOOTLOADER_TYPE: ::c_int = 67; +pub const KERN_RANDOMIZE: ::c_int = 68; +pub const KERN_SETUID_DUMPABLE: ::c_int = 69; +pub const KERN_SPIN_RETRY: ::c_int = 70; +pub const KERN_ACPI_VIDEO_FLAGS: ::c_int = 71; +pub const KERN_IA64_UNALIGNED: ::c_int = 72; +pub const KERN_COMPAT_LOG: ::c_int = 73; +pub const KERN_MAX_LOCK_DEPTH: ::c_int = 74; + +pub const VM_OVERCOMMIT_MEMORY: ::c_int = 5; +pub const VM_PAGE_CLUSTER: ::c_int = 10; +pub const VM_DIRTY_BACKGROUND: ::c_int = 11; +pub const VM_DIRTY_RATIO: ::c_int = 12; +pub const VM_DIRTY_WB_CS: ::c_int = 13; +pub const VM_DIRTY_EXPIRE_CS: ::c_int = 14; +pub const VM_NR_PDFLUSH_THREADS: ::c_int = 15; +pub const VM_OVERCOMMIT_RATIO: ::c_int = 16; +pub const VM_PAGEBUF: ::c_int = 17; +pub const VM_HUGETLB_PAGES: ::c_int = 18; +pub const VM_SWAPPINESS: ::c_int = 19; +pub const VM_LOWMEM_RESERVE_RATIO: ::c_int = 20; +pub const VM_MIN_FREE_KBYTES: ::c_int = 21; +pub const VM_MAX_MAP_COUNT: ::c_int = 22; +pub const VM_LAPTOP_MODE: ::c_int = 23; +pub const VM_BLOCK_DUMP: ::c_int = 24; +pub const VM_HUGETLB_GROUP: ::c_int = 25; +pub const VM_VFS_CACHE_PRESSURE: ::c_int = 26; +pub const VM_LEGACY_VA_LAYOUT: ::c_int = 27; +pub const VM_SWAP_TOKEN_TIMEOUT: ::c_int = 28; +pub const VM_DROP_PAGECACHE: ::c_int = 29; +pub const VM_PERCPU_PAGELIST_FRACTION: ::c_int = 30; +pub const VM_ZONE_RECLAIM_MODE: ::c_int = 31; +pub const VM_MIN_UNMAPPED: ::c_int = 32; +pub const VM_PANIC_ON_OOM: ::c_int = 33; +pub const VM_VDSO_ENABLED: ::c_int = 34; + +pub const NET_CORE: ::c_int = 1; +pub const NET_ETHER: ::c_int = 2; +pub const NET_802: ::c_int = 3; +pub const NET_UNIX: ::c_int = 4; +pub const NET_IPV4: ::c_int = 5; +pub const NET_IPX: ::c_int = 6; +pub const NET_ATALK: ::c_int = 7; +pub const NET_NETROM: ::c_int = 8; +pub const NET_AX25: ::c_int = 9; +pub const NET_BRIDGE: ::c_int = 10; +pub const NET_ROSE: ::c_int = 11; +pub const NET_IPV6: ::c_int = 12; +pub const NET_X25: ::c_int = 13; +pub const NET_TR: ::c_int = 14; +pub const NET_DECNET: ::c_int = 15; +pub const NET_ECONET: ::c_int = 16; +pub const NET_SCTP: ::c_int = 17; +pub const NET_LLC: ::c_int = 18; +pub const NET_NETFILTER: ::c_int = 19; +pub const NET_DCCP: ::c_int = 20; +pub const HUGETLB_FLAG_ENCODE_SHIFT: ::c_int = 26; +pub const MAP_HUGE_SHIFT: ::c_int = HUGETLB_FLAG_ENCODE_SHIFT; + +// include/linux/sched.h +pub const PF_VCPU: ::c_int = 0x00000001; +pub const PF_IDLE: ::c_int = 0x00000002; +pub const PF_EXITING: ::c_int = 0x00000004; +pub const PF_POSTCOREDUMP: ::c_int = 0x00000008; +pub const PF_IO_WORKER: ::c_int = 0x00000010; +pub const PF_WQ_WORKER: ::c_int = 0x00000020; +pub const PF_FORKNOEXEC: ::c_int = 0x00000040; +pub const PF_MCE_PROCESS: ::c_int = 0x00000080; +pub const PF_SUPERPRIV: ::c_int = 0x00000100; +pub const PF_DUMPCORE: ::c_int = 0x00000200; +pub const PF_SIGNALED: ::c_int = 0x00000400; +pub const PF_MEMALLOC: ::c_int = 0x00000800; +pub const PF_NPROC_EXCEEDED: ::c_int = 0x00001000; +pub const PF_USED_MATH: ::c_int = 0x00002000; +pub const PF_USER_WORKER: ::c_int = 0x00004000; +pub const PF_NOFREEZE: ::c_int = 0x00008000; + +pub const PF_KSWAPD: ::c_int = 0x00020000; +pub const PF_MEMALLOC_NOFS: ::c_int = 0x00040000; +pub const PF_MEMALLOC_NOIO: ::c_int = 0x00080000; +pub const PF_LOCAL_THROTTLE: ::c_int = 0x00100000; +pub const PF_KTHREAD: ::c_int = 0x00200000; +pub const PF_RANDOMIZE: ::c_int = 0x00400000; + +pub const PF_NO_SETAFFINITY: ::c_int = 0x04000000; +pub const PF_MCE_EARLY: ::c_int = 0x08000000; +pub const PF_MEMALLOC_PIN: ::c_int = 0x10000000; + +pub const PF_SUSPEND_TASK: ::c_int = 0x80000000; + +// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the +// following are only available on newer Linux versions than the versions +// currently used in CI in some configurations, so we define them here. +cfg_if! { + if #[cfg(not(target_arch = "s390x"))] { + pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + } else if #[cfg(target_arch = "s390x")] { + pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342; + } +} + +f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + pub fn CPU_ALLOC_SIZE(count: ::c_int) -> ::size_t { + let _dummy: cpu_set_t = ::mem::zeroed(); + let size_in_bits = 8 * ::mem::size_of_val(&_dummy.__bits[0]); + ((count as ::size_t + size_in_bits - 1) / 8) as ::size_t + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.__bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.__bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.__bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.__bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.__bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.__bits[idx] & (1 << offset)) + } + + pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> ::c_int { + let mut s: u32 = 0; + let size_of_mask = ::mem::size_of_val(&cpuset.__bits[0]); + for i in cpuset.__bits[..(size / size_of_mask)].iter() { + s += i.count_ones(); + }; + s as ::c_int + } + + pub fn CPU_COUNT(cpuset: &cpu_set_t) -> ::c_int { + CPU_COUNT_S(::mem::size_of::(), cpuset) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.__bits == set2.__bits + } + + pub fn major(dev: ::dev_t) -> ::c_int { + ((dev >> 8) & 0xfff) as ::c_int + } + pub fn minor(dev: ::dev_t) -> ::c_int { + ((dev & 0xff) | ((dev >> 12) & 0xfff00)) as ::c_int + } + pub fn NLA_ALIGN(len: ::c_int) -> ::c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) + } + + pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr { + ee.offset(1) as *mut ::sockaddr + } +} + +safe_f! { + pub {const} fn makedev(ma: ::c_uint, mi: ::c_uint) -> ::dev_t { + let ma = ma as ::dev_t; + let mi = mi as ::dev_t; + ((ma & 0xfff) << 8) | (mi & 0xff) | ((mi & 0xfff00) << 12) + } + +} + +extern "C" { + pub fn getrlimit64(resource: ::c_int, rlim: *mut rlimit64) -> ::c_int; + pub fn setrlimit64(resource: ::c_int, rlim: *const rlimit64) -> ::c_int; + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn prlimit( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit, + old_limit: *mut ::rlimit, + ) -> ::c_int; + pub fn prlimit64( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit64, + old_limit: *mut ::rlimit64, + ) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + servlen: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, count: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, count: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn process_vm_readv( + pid: ::pid_t, + local_iov: *const ::iovec, + local_iov_count: ::c_ulong, + remote_iov: *const ::iovec, + remote_iov_count: ::c_ulong, + flags: ::c_ulong, + ) -> ::ssize_t; + pub fn process_vm_writev( + pid: ::pid_t, + local_iov: *const ::iovec, + local_iov_count: ::c_ulong, + remote_iov: *const ::iovec, + remote_iov_count: ::c_ulong, + flags: ::c_ulong, + ) -> ::ssize_t; + pub fn ptrace(request: ::c_int, ...) -> ::c_long; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn __sched_cpualloc(count: ::size_t) -> *mut ::cpu_set_t; + pub fn __sched_cpufree(set: *mut ::cpu_set_t); + pub fn __sched_cpucount(setsize: ::size_t, set: *const cpu_set_t) -> ::c_int; + pub fn sched_getcpu() -> ::c_int; + pub fn mallinfo() -> ::mallinfo; + // available from API 23 + pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int; + + pub fn malloc_usable_size(ptr: *const ::c_void) -> ::size_t; + + pub fn utmpname(name: *const ::c_char) -> ::c_int; + pub fn setutent(); + pub fn getutent() -> *mut utmp; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + pub fn getxattr( + path: *const c_char, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn lgetxattr( + path: *const c_char, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn fgetxattr( + filedes: ::c_int, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn setxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn lsetxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fsetxattr( + filedes: ::c_int, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn listxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn llistxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn flistxattr(filedes: ::c_int, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn removexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn lremovexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn fremovexattr(filedes: ::c_int, name: *const c_char) -> ::c_int; + pub fn signalfd(fd: ::c_int, mask: *const ::sigset_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_create(clock: ::clockid_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_gettime(fd: ::c_int, current_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn syscall(num: ::c_long, ...) -> ::c_long; + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t) + -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsize: ::size_t, + cpuset: *const cpu_set_t, + ) -> ::c_int; + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn unshare(flags: ::c_int) -> ::c_int; + pub fn umount(target: *const ::c_char) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn splice( + fd_in: ::c_int, + off_in: *mut ::loff_t, + fd_out: ::c_int, + off_out: *mut ::loff_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int; + pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::c_int; + pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn setns(fd: ::c_int, nstype: ::c_int) -> ::c_int; + pub fn swapoff(puath: *const ::c_char) -> ::c_int; + pub fn vmsplice( + fd: ::c_int, + iov: *const ::iovec, + nr_segs: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + fstype: *const ::c_char, + flags: ::c_ulong, + data: *const ::c_void, + ) -> ::c_int; + pub fn personality(persona: ::c_uint) -> ::c_int; + pub fn prctl(option: ::c_int, ...) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const ::pthread_barrierattr_t, + shared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut ::pthread_barrierattr_t, + shared: ::c_int, + ) -> ::c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const ::pthread_barrierattr_t, + count: ::c_uint, + ) -> ::c_int; + pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn clone( + cb: extern "C" fn(*mut ::c_void) -> ::c_int, + child_stack: *mut ::c_void, + flags: ::c_int, + arg: *mut ::c_void, + ... + ) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getinheritsched( + attr: *const ::pthread_attr_t, + flag: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setinheritsched(attr: *mut ::pthread_attr_t, flag: ::c_int) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn sysinfo(info: *mut ::sysinfo) -> ::c_int; + pub fn umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sendfile( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut ::off_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut ::off64_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn setfsgid(gid: ::gid_t) -> ::c_int; + pub fn setfsuid(uid: ::uid_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn __errno() -> *mut ::c_int; + pub fn inotify_rm_watch(fd: ::c_int, wd: u32) -> ::c_int; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *const ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_init1(flags: ::c_int) -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::c_int; + + pub fn regcomp(preg: *mut ::regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; + + pub fn regexec( + preg: *const ::regex_t, + input: *const ::c_char, + nmatch: ::size_t, + pmatch: *mut regmatch_t, + eflags: ::c_int, + ) -> ::c_int; + + pub fn regerror( + errcode: ::c_int, + preg: *const ::regex_t, + errbuf: *mut ::c_char, + errbuf_size: ::size_t, + ) -> ::size_t; + + pub fn regfree(preg: *mut ::regex_t); + + pub fn android_set_abort_message(msg: *const ::c_char); + + pub fn gettid() -> ::pid_t; + + /// Only available in API Version 28+ + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; + + pub fn __system_property_set(__name: *const ::c_char, __value: *const ::c_char) -> ::c_int; + pub fn __system_property_get(__name: *const ::c_char, __value: *mut ::c_char) -> ::c_int; + pub fn __system_property_find(__name: *const ::c_char) -> *const prop_info; + pub fn __system_property_find_nth(__n: ::c_uint) -> *const prop_info; + pub fn __system_property_foreach( + __callback: unsafe extern "C" fn(__pi: *const prop_info, __cookie: *mut ::c_void), + __cookie: *mut ::c_void, + ) -> ::c_int; + + // #include + /// Only available in API Version 21+ + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn arc4random() -> u32; + pub fn arc4random_uniform(__upper_bound: u32) -> u32; + pub fn arc4random_buf(__buf: *mut ::c_void, __n: ::size_t); + + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn dirname(path: *const ::c_char) -> *mut ::c_char; + pub fn basename(path: *const ::c_char) -> *mut ::c_char; + pub fn getopt_long( + argc: ::c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut ::c_int, + ) -> ::c_int; + + pub fn sync(); + pub fn syncfs(fd: ::c_int) -> ::c_int; + + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn fread_unlocked( + buf: *mut ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + pub fn fwrite_unlocked( + buf: *const ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + pub fn fflush_unlocked(stream: *mut ::FILE) -> ::c_int; + pub fn fgets_unlocked(buf: *mut ::c_char, size: ::c_int, stream: *mut ::FILE) -> *mut ::c_char; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod b32; + pub use self::b32::*; + } else if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + // Unknown target_pointer_width + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_sigfault { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + si_addr: *mut ::c_void, + } + (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_tid: ::c_int, + _si_overrun: ::c_int, + si_sigval: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).si_sigval + } +} + +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, + } + impl ::Copy for sifields_sigchld {} + impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + self.sifields().sigchld.si_stime + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/align.rs new file mode 100644 index 00000000..b9ea3f39 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/align.rs @@ -0,0 +1,74 @@ +macro_rules! expand_align { + () => { + s! { + #[allow(missing_debug_implementations)] + #[repr(align(4))] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[repr(align(4))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[repr(align(4))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_rwlockattr_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs new file mode 100644 index 00000000..1616cc90 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs @@ -0,0 +1,213 @@ +// In-sync with ../linux/musl/lfs64.rs except for fallocate64, prlimit64 and sendfile64 + +#[inline] +pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int { + ::creat(path, mode) +} + +#[inline] +pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int { + ::fgetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE { + ::fopen(pathname, mode) +} + +#[inline] +pub unsafe extern "C" fn freopen64( + pathname: *const ::c_char, + mode: *const ::c_char, + stream: *mut ::FILE, +) -> *mut ::FILE { + ::freopen(pathname, mode, stream) +} + +#[inline] +pub unsafe extern "C" fn fseeko64( + stream: *mut ::FILE, + offset: ::off64_t, + whence: ::c_int, +) -> ::c_int { + ::fseeko(stream, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int { + ::fsetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int { + ::fstat(fildes, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatat64( + fd: ::c_int, + path: *const ::c_char, + buf: *mut ::stat64, + flag: ::c_int, +) -> ::c_int { + ::fstatat(fd, path, buf as *mut _, flag) +} + +#[inline] +pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int { + ::fstatfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int { + ::fstatvfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t { + ::ftello(stream) +} + +#[inline] +pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int { + ::ftruncate(fd, length) +} + +#[inline] +pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int { + ::getrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t { + ::lseek(fd, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int { + ::lstat(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn mmap64( + addr: *mut ::c_void, + length: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: ::off64_t, +) -> *mut ::c_void { + ::mmap(addr, length, prot, flags, fd, offset) +} + +// These functions are variadic in the C ABI since the `mode` argument is "optional". Variadic +// `extern "C"` functions are unstable in Rust so we cannot write a shim function for these +// entrypoints. See https://github.com/rust-lang/rust/issues/44930. +// +// These aliases are mostly fine though, neither function takes a LFS64-namespaced type as an +// argument, nor do their names clash with any declared types. +pub use open as open64; +pub use openat as openat64; + +#[inline] +pub unsafe extern "C" fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advice: ::c_int, +) -> ::c_int { + ::posix_fadvise(fd, offset, len, advice) +} + +#[inline] +pub unsafe extern "C" fn posix_fallocate64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, +) -> ::c_int { + ::posix_fallocate(fd, offset, len) +} + +#[inline] +pub unsafe extern "C" fn pread64( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pread(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::preadv(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pwrite(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::pwritev(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 { + ::readdir(dirp) as *mut _ +} + +#[inline] +pub unsafe extern "C" fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, +) -> ::c_int { + ::readdir_r(dirp, entry as *mut _, result as *mut _) +} + +#[inline] +pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int { + ::setrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int { + ::stat(pathname, statbuf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int { + ::statfs(pathname, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int { + ::statvfs(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE { + ::tmpfile() +} + +#[inline] +pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int { + ::truncate(path, length) +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/mod.rs new file mode 100644 index 00000000..1dc60749 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/mod.rs @@ -0,0 +1,1794 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type useconds_t = u32; +pub type dev_t = u32; +pub type socklen_t = u32; +pub type pthread_t = c_ulong; +pub type mode_t = u32; +pub type shmatt_t = ::c_ulong; +pub type mqd_t = ::c_int; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type nfds_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type idtype_t = ::c_uint; +pub type loff_t = i64; +pub type pthread_key_t = ::c_uint; + +pub type clock_t = c_long; +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i32; + +pub type blksize_t = c_long; +pub type fsblkcnt_t = u32; +pub type fsfilcnt_t = u32; +pub type rlim_t = u64; +pub type c_long = i32; +pub type c_ulong = u32; +pub type nlink_t = u32; + +pub type ino64_t = ::ino_t; +pub type off64_t = ::off_t; +pub type blkcnt64_t = ::blkcnt_t; +pub type rlim64_t = ::rlim_t; + +pub type rlimit64 = ::rlimit; +pub type flock64 = ::flock; +pub type stat64 = ::stat; +pub type statfs64 = ::statfs; +pub type statvfs64 = ::statvfs; +pub type dirent64 = ::dirent; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { + *self + } +} + +s! { + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curspace: u64, + pub dqb_ihardlimit: u64, + pub dqb_isoftlimit: u64, + pub dqb_curinodes: u64, + pub dqb_btime: u64, + pub dqb_itime: u64, + pub dqb_valid: u32, + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct cpu_set_t { + bits: [u32; 32], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + __dummy4: [::c_char; 24], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct pthread_attr_t { + __size: [u32; 11] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 4], + } + pub struct stat { + pub st_dev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] + __st_dev_padding: ::c_int, + #[cfg(not(emscripten_new_stat_abi))] + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_int, + pub msg_rtime: ::time_t, + __unused2: ::c_int, + pub msg_ctime: ::time_t, + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + pad: [::c_long; 4] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sysinfo {} + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for mq_attr { + fn eq(&self, other: &mq_attr) -> bool { + self.mq_flags == other.mq_flags && + self.mq_maxmsg == other.mq_maxmsg && + self.mq_msgsize == other.mq_msgsize && + self.mq_curmsgs == other.mq_curmsgs + } + } + impl Eq for mq_attr {} + impl ::fmt::Debug for mq_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mq_attr") + .field("mq_flags", &self.mq_flags) + .field("mq_maxmsg", &self.mq_maxmsg) + .field("mq_msgsize", &self.mq_msgsize) + .field("mq_curmsgs", &self.mq_curmsgs) + .finish() + } + } + impl ::hash::Hash for mq_attr { + fn hash(&self, state: &mut H) { + self.mq_flags.hash(state); + self.mq_maxmsg.hash(state); + self.mq_msgsize.hash(state); + self.mq_curmsgs.hash(state); + } + } + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MS_NOUSER: ::c_ulong = 0x80000000; +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +pub const ABDAY_1: ::nl_item = 0x20000; +pub const ABDAY_2: ::nl_item = 0x20001; +pub const ABDAY_3: ::nl_item = 0x20002; +pub const ABDAY_4: ::nl_item = 0x20003; +pub const ABDAY_5: ::nl_item = 0x20004; +pub const ABDAY_6: ::nl_item = 0x20005; +pub const ABDAY_7: ::nl_item = 0x20006; + +pub const DAY_1: ::nl_item = 0x20007; +pub const DAY_2: ::nl_item = 0x20008; +pub const DAY_3: ::nl_item = 0x20009; +pub const DAY_4: ::nl_item = 0x2000A; +pub const DAY_5: ::nl_item = 0x2000B; +pub const DAY_6: ::nl_item = 0x2000C; +pub const DAY_7: ::nl_item = 0x2000D; + +pub const ABMON_1: ::nl_item = 0x2000E; +pub const ABMON_2: ::nl_item = 0x2000F; +pub const ABMON_3: ::nl_item = 0x20010; +pub const ABMON_4: ::nl_item = 0x20011; +pub const ABMON_5: ::nl_item = 0x20012; +pub const ABMON_6: ::nl_item = 0x20013; +pub const ABMON_7: ::nl_item = 0x20014; +pub const ABMON_8: ::nl_item = 0x20015; +pub const ABMON_9: ::nl_item = 0x20016; +pub const ABMON_10: ::nl_item = 0x20017; +pub const ABMON_11: ::nl_item = 0x20018; +pub const ABMON_12: ::nl_item = 0x20019; + +pub const MON_1: ::nl_item = 0x2001A; +pub const MON_2: ::nl_item = 0x2001B; +pub const MON_3: ::nl_item = 0x2001C; +pub const MON_4: ::nl_item = 0x2001D; +pub const MON_5: ::nl_item = 0x2001E; +pub const MON_6: ::nl_item = 0x2001F; +pub const MON_7: ::nl_item = 0x20020; +pub const MON_8: ::nl_item = 0x20021; +pub const MON_9: ::nl_item = 0x20022; +pub const MON_10: ::nl_item = 0x20023; +pub const MON_11: ::nl_item = 0x20024; +pub const MON_12: ::nl_item = 0x20025; + +pub const AM_STR: ::nl_item = 0x20026; +pub const PM_STR: ::nl_item = 0x20027; + +pub const D_T_FMT: ::nl_item = 0x20028; +pub const D_FMT: ::nl_item = 0x20029; +pub const T_FMT: ::nl_item = 0x2002A; +pub const T_FMT_AMPM: ::nl_item = 0x2002B; + +pub const ERA: ::nl_item = 0x2002C; +pub const ERA_D_FMT: ::nl_item = 0x2002E; +pub const ALT_DIGITS: ::nl_item = 0x2002F; +pub const ERA_D_T_FMT: ::nl_item = 0x20030; +pub const ERA_T_FMT: ::nl_item = 0x20031; + +pub const CODESET: ::nl_item = 14; + +pub const CRNCYSTR: ::nl_item = 0x4000F; + +pub const RUSAGE_THREAD: ::c_int = 1; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const RADIXCHAR: ::nl_item = 0x10000; +pub const THOUSEP: ::nl_item = 0x10001; + +pub const YESEXPR: ::nl_item = 0x50000; +pub const NOEXPR: ::nl_item = 0x50001; +pub const YESSTR: ::nl_item = 0x50002; +pub const NOSTR: ::nl_item = 0x50003; + +pub const FILENAME_MAX: ::c_uint = 4096; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; + +pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; + +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; + +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x2; + +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} + +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +// System V IPC +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_CREAT: ::c_int = 0o1000; +pub const IPC_EXCL: ::c_int = 0o2000; +pub const IPC_NOWAIT: ::c_int = 0o4000; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; +pub const IPC_INFO: ::c_int = 3; +pub const MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; + +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_REMAP: ::c_int = 0o40000; +pub const SHM_EXEC: ::c_int = 0o100000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; + +pub const SHM_HUGETLB: ::c_int = 0o4000; +pub const SHM_NORESERVE: ::c_int = 0o10000; + +pub const QFMT_VFS_OLD: ::c_int = 1; +pub const QFMT_VFS_V0: ::c_int = 2; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +pub const EAI_SYSTEM: ::c_int = -11; + +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; + +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +pub const PR_GET_TIMING: ::c_int = 13; +pub const PR_SET_TIMING: ::c_int = 14; +pub const PR_TIMING_STATISTICAL: ::c_int = 0; +pub const PR_TIMING_TIMESTAMP: ::c_int = 1; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +pub const PR_SET_MM_MAP: ::c_int = 14; +pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + +pub const PR_SET_PTRACER: ::c_int = 0x59616d61; +pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff; + +pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; +pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2; +pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3; +pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; + +// On Linux, libc doesn't define this constant, libattr does instead. +// We still define it for Linux as it's defined by libc on other platforms, +// and it's mentioned in the man pages for getxattr and setxattr. +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; + +// Defined as wasi value. +pub const EPERM: ::c_int = 63; +pub const ENOENT: ::c_int = 44; +pub const ESRCH: ::c_int = 71; +pub const EINTR: ::c_int = 27; +pub const EIO: ::c_int = 29; +pub const ENXIO: ::c_int = 60; +pub const E2BIG: ::c_int = 1; +pub const ENOEXEC: ::c_int = 45; +pub const EBADF: ::c_int = 8; +pub const ECHILD: ::c_int = 12; +pub const EAGAIN: ::c_int = 6; +pub const ENOMEM: ::c_int = 48; +pub const EACCES: ::c_int = 2; +pub const EFAULT: ::c_int = 21; +pub const ENOTBLK: ::c_int = 105; +pub const EBUSY: ::c_int = 10; +pub const EEXIST: ::c_int = 20; +pub const EXDEV: ::c_int = 75; +pub const ENODEV: ::c_int = 43; +pub const ENOTDIR: ::c_int = 54; +pub const EISDIR: ::c_int = 31; +pub const EINVAL: ::c_int = 28; +pub const ENFILE: ::c_int = 41; +pub const EMFILE: ::c_int = 33; +pub const ENOTTY: ::c_int = 59; +pub const ETXTBSY: ::c_int = 74; +pub const EFBIG: ::c_int = 22; +pub const ENOSPC: ::c_int = 51; +pub const ESPIPE: ::c_int = 70; +pub const EROFS: ::c_int = 69; +pub const EMLINK: ::c_int = 34; +pub const EPIPE: ::c_int = 64; +pub const EDOM: ::c_int = 18; +pub const ERANGE: ::c_int = 68; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const ENOLINK: ::c_int = 47; +pub const EPROTO: ::c_int = 65; +pub const EDEADLK: ::c_int = 16; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const ENAMETOOLONG: ::c_int = 37; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 52; +pub const ENOTEMPTY: ::c_int = 55; +pub const ELOOP: ::c_int = 32; +pub const ENOMSG: ::c_int = 49; +pub const EIDRM: ::c_int = 24; +pub const EMULTIHOP: ::c_int = 36; +pub const EBADMSG: ::c_int = 9; +pub const EOVERFLOW: ::c_int = 61; +pub const EILSEQ: ::c_int = 25; +pub const ENOTSOCK: ::c_int = 57; +pub const EDESTADDRREQ: ::c_int = 17; +pub const EMSGSIZE: ::c_int = 35; +pub const EPROTOTYPE: ::c_int = 67; +pub const ENOPROTOOPT: ::c_int = 50; +pub const EPROTONOSUPPORT: ::c_int = 66; +pub const EAFNOSUPPORT: ::c_int = 5; +pub const EADDRINUSE: ::c_int = 3; +pub const EADDRNOTAVAIL: ::c_int = 4; +pub const ENETDOWN: ::c_int = 38; +pub const ENETUNREACH: ::c_int = 40; +pub const ENETRESET: ::c_int = 39; +pub const ECONNABORTED: ::c_int = 13; +pub const ECONNRESET: ::c_int = 15; +pub const ENOBUFS: ::c_int = 42; +pub const EISCONN: ::c_int = 30; +pub const ENOTCONN: ::c_int = 53; +pub const ETIMEDOUT: ::c_int = 73; +pub const ECONNREFUSED: ::c_int = 14; +pub const EHOSTUNREACH: ::c_int = 23; +pub const EALREADY: ::c_int = 7; +pub const EINPROGRESS: ::c_int = 26; +pub const ESTALE: ::c_int = 72; +pub const EDQUOT: ::c_int = 19; +pub const ECANCELED: ::c_int = 11; +pub const EOWNERDEAD: ::c_int = 62; +pub const ENOTRECOVERABLE: ::c_int = 56; + +pub const ENOSTR: ::c_int = 100; +pub const EBFONT: ::c_int = 101; +pub const EBADSLT: ::c_int = 102; +pub const EBADRQC: ::c_int = 103; +pub const ENOANO: ::c_int = 104; +pub const ECHRNG: ::c_int = 106; +pub const EL3HLT: ::c_int = 107; +pub const EL3RST: ::c_int = 108; +pub const ELNRNG: ::c_int = 109; +pub const EUNATCH: ::c_int = 110; +pub const ENOCSI: ::c_int = 111; +pub const EL2HLT: ::c_int = 112; +pub const EBADE: ::c_int = 113; +pub const EBADR: ::c_int = 114; +pub const EXFULL: ::c_int = 115; +pub const ENODATA: ::c_int = 116; +pub const ETIME: ::c_int = 117; +pub const ENOSR: ::c_int = 118; +pub const ENONET: ::c_int = 119; +pub const ENOPKG: ::c_int = 120; +pub const EREMOTE: ::c_int = 121; +pub const EADV: ::c_int = 122; +pub const ESRMNT: ::c_int = 123; +pub const ECOMM: ::c_int = 124; +pub const EDOTDOT: ::c_int = 125; +pub const ENOTUNIQ: ::c_int = 126; +pub const EBADFD: ::c_int = 127; +pub const EREMCHG: ::c_int = 128; +pub const ELIBACC: ::c_int = 129; +pub const ELIBBAD: ::c_int = 130; +pub const ELIBSCN: ::c_int = 131; +pub const ELIBMAX: ::c_int = 132; +pub const ELIBEXEC: ::c_int = 133; +pub const ERESTART: ::c_int = 134; +pub const ESTRPIPE: ::c_int = 135; +pub const EUSERS: ::c_int = 136; +pub const ESOCKTNOSUPPORT: ::c_int = 137; +pub const EOPNOTSUPP: ::c_int = 138; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 139; +pub const ESHUTDOWN: ::c_int = 140; +pub const ETOOMANYREFS: ::c_int = 141; +pub const EHOSTDOWN: ::c_int = 142; +pub const EUCLEAN: ::c_int = 143; +pub const ENOTNAM: ::c_int = 144; +pub const ENAVAIL: ::c_int = 145; +pub const EISNAM: ::c_int = 146; +pub const EREMOTEIO: ::c_int = 147; +pub const ENOMEDIUM: ::c_int = 148; +pub const EMEDIUMTYPE: ::c_int = 149; +pub const ENOKEY: ::c_int = 150; +pub const EKEYEXPIRED: ::c_int = 151; +pub const EKEYREVOKED: ::c_int = 152; +pub const EKEYREJECTED: ::c_int = 153; +pub const ERFKILL: ::c_int = 154; +pub const EHWPOISON: ::c_int = 155; +pub const EL2NSYNC: ::c_int = 156; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_EXEC: ::c_int = 0o10000000; +pub const O_SEARCH: ::c_int = 0o10000000; +pub const O_ACCMODE: ::c_int = 0o10000003; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POSIX_MADV_DONTNEED: ::c_int = 0; + +pub const RLIM_INFINITY: ::rlim_t = !0; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIMIT_NLIMITS: ::c_int = 15; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +#[doc(hidden)] +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = ::SIGSYS; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + +pub const CPU_SETSIZE: ::c_int = 128; + +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_SYSCALL: ::c_int = 24; +pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; +pub const PTRACE_GETREGSET: ::c_int = 0x4204; +pub const PTRACE_SETREGSET: ::c_int = 0x4205; +pub const PTRACE_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; + +pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const TIOCINQ: ::c_int = ::FIONREAD; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 28; + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const FIOCLEX: ::c_int = 0x5451; +pub const FIONBIO: ::c_int = 0x5421; + +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_NOFILE: ::c_int = 7; +pub const RLIMIT_AS: ::c_int = 9; +pub const RLIMIT_NPROC: ::c_int = 6; +pub const RLIMIT_MEMLOCK: ::c_int = 8; +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_LOCKS: ::c_int = 10; +pub const RLIMIT_SIGPENDING: ::c_int = 11; +pub const RLIMIT_MSGQUEUE: ::c_int = 12; +pub const RLIMIT_NICE: ::c_int = 13; +pub const RLIMIT_RTPRIO: ::c_int = 14; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; + +pub const SOCK_NONBLOCK: ::c_int = 2048; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const IPPROTO_MAX: ::c_int = 256; + +pub const SOL_SOCKET: ::c_int = 1; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_LINGER: ::c_int = 13; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; + +pub const IPV6_RTHDR_LOOSE: ::c_int = 0; +pub const IPV6_RTHDR_STRICT: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const TCGETS: ::c_int = 0x5401; +pub const TCSETS: ::c_int = 0x5402; +pub const TCSETSW: ::c_int = 0x5403; +pub const TCSETSF: ::c_int = 0x5404; +pub const TCGETA: ::c_int = 0x5405; +pub const TCSETA: ::c_int = 0x5406; +pub const TCSETAW: ::c_int = 0x5407; +pub const TCSETAF: ::c_int = 0x5408; +pub const TCSBRK: ::c_int = 0x5409; +pub const TCXONC: ::c_int = 0x540A; +pub const TCFLSH: ::c_int = 0x540B; +pub const TIOCGSOFTCAR: ::c_int = 0x5419; +pub const TIOCSSOFTCAR: ::c_int = 0x541A; +pub const TIOCLINUX: ::c_int = 0x541C; +pub const TIOCGSERIAL: ::c_int = 0x541E; +pub const TIOCEXCL: ::c_int = 0x540C; +pub const TIOCNXCL: ::c_int = 0x540D; +pub const TIOCSCTTY: ::c_int = 0x540E; +pub const TIOCGPGRP: ::c_int = 0x540F; +pub const TIOCSPGRP: ::c_int = 0x5410; +pub const TIOCOUTQ: ::c_int = 0x5411; +pub const TIOCSTI: ::c_int = 0x5412; +pub const TIOCGWINSZ: ::c_int = 0x5413; +pub const TIOCSWINSZ: ::c_int = 0x5414; +pub const TIOCMGET: ::c_int = 0x5415; +pub const TIOCMBIS: ::c_int = 0x5416; +pub const TIOCMBIC: ::c_int = 0x5417; +pub const TIOCMSET: ::c_int = 0x5418; +pub const FIONREAD: ::c_int = 0x541B; +pub const TIOCCONS: ::c_int = 0x541D; + +pub const SYS_gettid: ::c_long = 224; // Valid for arm (32-bit) and x86 (32-bit) + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const O_TMPFILE: ::c_int = 0x400000; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +pub const ARPD_LOOKUP: ::c_ushort = 0x02; +pub const ARPD_FLUSH: ::c_ushort = 0x03; +pub const ATF_MAGIC: ::c_int = 0x80; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const SOMAXCONN: ::c_int = 128; + +f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/emscripten-core/emscripten/blob/ + // main/system/lib/libc/musl/include/sys/sysmacros.h + let mut major = 0; + major |= (dev & 0x00000fff) >> 8; + major |= (dev & 0xfffff000) >> 31 >> 1; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/emscripten-core/emscripten/blob/ + // main/system/lib/libc/musl/include/sys/sysmacros.h + let mut minor = 0; + minor |= (dev & 0x000000ff) >> 0; + minor |= (dev & 0xffffff00) >> 12; + minor as ::c_uint + } +} + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0x00000fff) << 8; + dev |= (major & 0xfffff000) << 31 << 1; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn mremap( + addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ... + ) -> *mut ::c_void; + + pub fn glob( + pattern: *const c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_uint, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_uint, + timeout: *mut ::timespec, + ) -> ::c_int; + pub fn sync(); + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; +} + +// Alias to 64 to mimic glibc's LFS64 support +mod lfs64; +pub use self::lfs64::*; + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/no_align.rs new file mode 100644 index 00000000..768dc73a --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/emscripten/no_align.rs @@ -0,0 +1,63 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_cond_t { + __align: [*const ::c_void; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/align.rs new file mode 100644 index 00000000..1036e23d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/align.rs @@ -0,0 +1,205 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[cfg_attr(any(target_env = "musl", target_env = "ohos", target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(not(target_env = "musl"), + not(target_env = "ohos"), + target_pointer_width = "64"), + repr(align(8)))] + pub struct pthread_rwlockattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + + #[repr(align(4))] + pub struct pthread_barrierattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_BARRIERATTR_T], + } + + #[repr(align(8))] + pub struct fanotify_event_metadata { + pub event_len: __u32, + pub vers: __u8, + pub reserved: __u8, + pub metadata_len: __u16, + pub mask: __u64, + pub fd: ::c_int, + pub pid: ::c_int, + } + } + + s_no_extra_traits! { + #[cfg_attr(all(any(target_env = "musl", target_env = "ohos"), + target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(any(target_env = "musl", target_env = "ohos"), + target_pointer_width = "64"), + repr(align(8)))] + #[cfg_attr(all(not(any(target_env = "musl", target_env = "ohos")), + target_arch = "x86"), + repr(align(4)))] + #[cfg_attr(all(not(any(target_env = "musl", target_env = "ohos")), + not(target_arch = "x86")), + repr(align(8)))] + pub struct pthread_cond_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86"))), + repr(align(8)))] + pub struct pthread_mutex_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86"))), + repr(align(8)))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86"))), + repr(align(8)))] + pub struct pthread_barrier_t { + size: [u8; ::__SIZEOF_PTHREAD_BARRIER_T], + } + + // linux/can.h + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct can_frame { + pub can_id: canid_t, + pub can_dlc: u8, + __pad: u8, + __res0: u8, + __res1: u8, + pub data: [u8; CAN_MAX_DLEN], + } + + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct canfd_frame { + pub can_id: canid_t, + pub len: u8, + pub flags: u8, + __res0: u8, + __res1: u8, + pub data: [u8; CANFD_MAX_DLEN], + } + + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct canxl_frame { + pub prio: canid_t, + pub flags: u8, + pub sdt: u8, + pub len: u16, + pub af: u32, + pub data: [u8; CANXL_MAX_DLEN], + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs new file mode 100644 index 00000000..83f97fbd --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs @@ -0,0 +1,333 @@ +s! { + pub struct termios2 { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; 19], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } +} + +// include/uapi/asm-generic/socket.h +// arch/alpha/include/uapi/asm/socket.h +// tools/include/uapi/asm-generic/socket.h +// arch/mips/include/uapi/asm/socket.h +pub const SOL_SOCKET: ::c_int = 1; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 1; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +// pub const SO_RCVTIMEO_OLD: ::c_int = 20; +// pub const SO_SNDTIMEO_OLD: ::c_int = 21; +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24; +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_ATTACH_FILTER: ::c_int = 26; +pub const SO_DETACH_FILTER: ::c_int = 27; +pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; +pub const SO_PEERNAME: ::c_int = 28; +pub const SO_TIMESTAMP: ::c_int = 29; +// pub const SO_TIMESTAMP_OLD: ::c_int = 29; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_TIMESTAMPNS: ::c_int = 35; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +pub const SO_MARK: ::c_int = 36; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_WIFI_STATUS: ::c_int = 41; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_NOFCS: ::c_int = 43; +pub const SO_LOCK_FILTER: ::c_int = 44; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 45; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_MAX_PACING_RATE: ::c_int = 47; +pub const SO_BPF_EXTENSIONS: ::c_int = 48; +pub const SO_INCOMING_CPU: ::c_int = 49; +pub const SO_ATTACH_BPF: ::c_int = 50; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 52; +pub const SO_CNX_ADVICE: ::c_int = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SO_MEMINFO: ::c_int = 55; +pub const SO_INCOMING_NAPI_ID: ::c_int = 56; +pub const SO_COOKIE: ::c_int = 57; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_PEERGROUPS: ::c_int = 59; +pub const SO_ZEROCOPY: ::c_int = 60; +pub const SO_TXTIME: ::c_int = 61; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 62; +cfg_if! { + // Some of these platforms in CI already have these constants. + // But they may still not have those _OLD ones. + if #[cfg(all(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "csky", + target_arch = "loongarch64"), + not(any(target_env = "musl", target_env = "ohos"))))] { + pub const SO_TIMESTAMP_NEW: ::c_int = 63; + pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; + pub const SO_TIMESTAMPING_NEW: ::c_int = 65; + pub const SO_RCVTIMEO_NEW: ::c_int = 66; + pub const SO_SNDTIMEO_NEW: ::c_int = 67; + pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; + } +} +// pub const SO_PREFER_BUSY_POLL: ::c_int = 69; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +cfg_if! { + if #[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "csky", + target_arch = "loongarch64"))] { + pub const FICLONE: ::c_ulong = 0x40049409; + pub const FICLONERANGE: ::c_ulong = 0x4020940D; + } +} + +// Defined in unix/linux_like/mod.rs +// pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; +pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; +pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; + +// Ioctl Constants + +pub const TCGETS: ::Ioctl = 0x5401; +pub const TCSETS: ::Ioctl = 0x5402; +pub const TCSETSW: ::Ioctl = 0x5403; +pub const TCSETSF: ::Ioctl = 0x5404; +pub const TCGETA: ::Ioctl = 0x5405; +pub const TCSETA: ::Ioctl = 0x5406; +pub const TCSETAW: ::Ioctl = 0x5407; +pub const TCSETAF: ::Ioctl = 0x5408; +pub const TCSBRK: ::Ioctl = 0x5409; +pub const TCXONC: ::Ioctl = 0x540A; +pub const TCFLSH: ::Ioctl = 0x540B; +pub const TIOCEXCL: ::Ioctl = 0x540C; +pub const TIOCNXCL: ::Ioctl = 0x540D; +pub const TIOCSCTTY: ::Ioctl = 0x540E; +pub const TIOCGPGRP: ::Ioctl = 0x540F; +pub const TIOCSPGRP: ::Ioctl = 0x5410; +pub const TIOCOUTQ: ::Ioctl = 0x5411; +pub const TIOCSTI: ::Ioctl = 0x5412; +pub const TIOCGWINSZ: ::Ioctl = 0x5413; +pub const TIOCSWINSZ: ::Ioctl = 0x5414; +pub const TIOCMGET: ::Ioctl = 0x5415; +pub const TIOCMBIS: ::Ioctl = 0x5416; +pub const TIOCMBIC: ::Ioctl = 0x5417; +pub const TIOCMSET: ::Ioctl = 0x5418; +pub const TIOCGSOFTCAR: ::Ioctl = 0x5419; +pub const TIOCSSOFTCAR: ::Ioctl = 0x541A; +pub const FIONREAD: ::Ioctl = 0x541B; +pub const TIOCINQ: ::Ioctl = FIONREAD; +pub const TIOCLINUX: ::Ioctl = 0x541C; +pub const TIOCCONS: ::Ioctl = 0x541D; +pub const TIOCGSERIAL: ::Ioctl = 0x541E; +pub const TIOCSSERIAL: ::Ioctl = 0x541F; +pub const TIOCPKT: ::Ioctl = 0x5420; +pub const FIONBIO: ::Ioctl = 0x5421; +pub const TIOCNOTTY: ::Ioctl = 0x5422; +pub const TIOCSETD: ::Ioctl = 0x5423; +pub const TIOCGETD: ::Ioctl = 0x5424; +pub const TCSBRKP: ::Ioctl = 0x5425; +pub const TIOCSBRK: ::Ioctl = 0x5427; +pub const TIOCCBRK: ::Ioctl = 0x5428; +pub const TIOCGSID: ::Ioctl = 0x5429; +pub const TCGETS2: ::Ioctl = 0x802c542a; +pub const TCSETS2: ::Ioctl = 0x402c542b; +pub const TCSETSW2: ::Ioctl = 0x402c542c; +pub const TCSETSF2: ::Ioctl = 0x402c542d; +pub const TIOCGRS485: ::Ioctl = 0x542E; +pub const TIOCSRS485: ::Ioctl = 0x542F; +pub const TIOCGPTN: ::Ioctl = 0x80045430; +pub const TIOCSPTLCK: ::Ioctl = 0x40045431; +pub const TIOCGDEV: ::Ioctl = 0x80045432; +pub const TCGETX: ::Ioctl = 0x5432; +pub const TCSETX: ::Ioctl = 0x5433; +pub const TCSETXF: ::Ioctl = 0x5434; +pub const TCSETXW: ::Ioctl = 0x5435; +pub const TIOCSIG: ::Ioctl = 0x40045436; +pub const TIOCVHANGUP: ::Ioctl = 0x5437; +pub const TIOCGPKT: ::Ioctl = 0x80045438; +pub const TIOCGPTLCK: ::Ioctl = 0x80045439; +pub const TIOCGEXCL: ::Ioctl = 0x80045440; +pub const TIOCGPTPEER: ::Ioctl = 0x5441; +// pub const TIOCGISO7816: ::Ioctl = 0x80285442; +// pub const TIOCSISO7816: ::Ioctl = 0xc0285443; +pub const FIONCLEX: ::Ioctl = 0x5450; +pub const FIOCLEX: ::Ioctl = 0x5451; +pub const FIOASYNC: ::Ioctl = 0x5452; +pub const TIOCSERCONFIG: ::Ioctl = 0x5453; +pub const TIOCSERGWILD: ::Ioctl = 0x5454; +pub const TIOCSERSWILD: ::Ioctl = 0x5455; +pub const TIOCGLCKTRMIOS: ::Ioctl = 0x5456; +pub const TIOCSLCKTRMIOS: ::Ioctl = 0x5457; +pub const TIOCSERGSTRUCT: ::Ioctl = 0x5458; +pub const TIOCSERGETLSR: ::Ioctl = 0x5459; +pub const TIOCSERGETMULTI: ::Ioctl = 0x545A; +pub const TIOCSERSETMULTI: ::Ioctl = 0x545B; +pub const TIOCMIWAIT: ::Ioctl = 0x545C; +pub const TIOCGICOUNT: ::Ioctl = 0x545D; +pub const BLKIOMIN: ::Ioctl = 0x1278; +pub const BLKIOOPT: ::Ioctl = 0x1279; +pub const BLKSSZGET: ::Ioctl = 0x1268; +pub const BLKPBSZGET: ::Ioctl = 0x127B; + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(any(target_arch = "x86", target_arch = "arm"))] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x80046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x40046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x80047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x40047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x40046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x80047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x40047602; + } else if #[cfg(any(target_arch = "x86_64", + target_arch = "riscv64", + target_arch = "aarch64", + target_arch = "s390x", + target_arch = "loongarch64"))] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x80086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x40086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x80087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x40087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x40046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x80047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x40047602; + } +} + +cfg_if! { + if #[cfg(any(target_arch = "arm", + target_arch = "s390x"))] { + pub const FIOQSIZE: ::Ioctl = 0x545E; + } else { + pub const FIOQSIZE: ::Ioctl = 0x5460; + } +} + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const TIOCM_DSR: ::c_int = 0x100; + +pub const BOTHER: ::speed_t = 0o010000; +pub const IBSHIFT: ::tcflag_t = 16; + +// RLIMIT Constants + +cfg_if! { + if #[cfg(any(target_env = "gnu", + target_env = "uclibc"))] { + + pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; + pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; + pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; + pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; + pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; + pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; + pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; + pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; + pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; + pub const RLIMIT_AS: ::__rlimit_resource_t = 9; + pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; + pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; + pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; + pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; + pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; + pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; + + } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + + pub const RLIMIT_CPU: ::c_int = 0; + pub const RLIMIT_FSIZE: ::c_int = 1; + pub const RLIMIT_DATA: ::c_int = 2; + pub const RLIMIT_STACK: ::c_int = 3; + pub const RLIMIT_CORE: ::c_int = 4; + pub const RLIMIT_RSS: ::c_int = 5; + pub const RLIMIT_NPROC: ::c_int = 6; + pub const RLIMIT_NOFILE: ::c_int = 7; + pub const RLIMIT_MEMLOCK: ::c_int = 8; + pub const RLIMIT_AS: ::c_int = 9; + pub const RLIMIT_LOCKS: ::c_int = 10; + pub const RLIMIT_SIGPENDING: ::c_int = 11; + pub const RLIMIT_MSGQUEUE: ::c_int = 12; + pub const RLIMIT_NICE: ::c_int = 13; + pub const RLIMIT_RTPRIO: ::c_int = 14; + pub const RLIMIT_RTTIME: ::c_int = 15; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::c_int = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; + } +} + +cfg_if! { + if #[cfg(target_env = "gnu")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; + } + else if #[cfg(target_env = "uclibc")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 15; + } +} + +pub const RLIM_INFINITY: ::rlim_t = !0; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs new file mode 100644 index 00000000..76996770 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs @@ -0,0 +1,323 @@ +s! { + pub struct termios2 { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; 23], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } +} + +// arch/mips/include/uapi/asm/socket.h +pub const SOL_SOCKET: ::c_int = 0xffff; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_TYPE: ::c_int = 0x1008; +// pub const SO_STYLE: ::c_int = SO_TYPE; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +// NOTE: These definitions are now being renamed with _OLD postfix, +// but CI haven't support them yet. +// Some related consts could be found in b32.rs and b64.rs +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +// pub const SO_SNDTIMEO_OLD: ::c_int = 0x1005; +// pub const SO_RCVTIMEO_OLD: ::c_int = 0x1006; +pub const SO_ACCEPTCONN: ::c_int = 0x1009; +pub const SO_PROTOCOL: ::c_int = 0x1028; +pub const SO_DOMAIN: ::c_int = 0x1029; + +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_PASSCRED: ::c_int = 17; +pub const SO_PEERCRED: ::c_int = 18; +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24; +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_ATTACH_FILTER: ::c_int = 26; +pub const SO_DETACH_FILTER: ::c_int = 27; +pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; +pub const SO_PEERNAME: ::c_int = 28; +pub const SO_PEERSEC: ::c_int = 30; +pub const SO_SNDBUFFORCE: ::c_int = 31; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_WIFI_STATUS: ::c_int = 41; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_NOFCS: ::c_int = 43; +pub const SO_LOCK_FILTER: ::c_int = 44; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 45; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_MAX_PACING_RATE: ::c_int = 47; +pub const SO_BPF_EXTENSIONS: ::c_int = 48; +pub const SO_INCOMING_CPU: ::c_int = 49; +pub const SO_ATTACH_BPF: ::c_int = 50; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 52; +pub const SO_CNX_ADVICE: ::c_int = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SO_MEMINFO: ::c_int = 55; +pub const SO_INCOMING_NAPI_ID: ::c_int = 56; +pub const SO_COOKIE: ::c_int = 57; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_PEERGROUPS: ::c_int = 59; +pub const SO_ZEROCOPY: ::c_int = 60; +pub const SO_TXTIME: ::c_int = 61; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 62; +// NOTE: These definitions are now being renamed with _OLD postfix, +// but CI haven't support them yet. +// Some related consts could be found in b32.rs and b64.rs +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_TIMESTAMPNS: ::c_int = 35; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMP_OLD: ::c_int = 29; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +// pub const SO_TIMESTAMP_NEW: ::c_int = 63; +// pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; +// pub const SO_TIMESTAMPING_NEW: ::c_int = 65; +// pub const SO_RCVTIMEO_NEW: ::c_int = 66; +// pub const SO_SNDTIMEO_NEW: ::c_int = 67; +// pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; +// pub const SO_PREFER_BUSY_POLL: ::c_int = 69; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +pub const FICLONE: ::c_ulong = 0x80049409; +pub const FICLONERANGE: ::c_ulong = 0x8020940D; + +// Defined in unix/linux_like/mod.rs +// pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; +pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; +pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; + +// Ioctl Constants + +pub const TCGETS: ::Ioctl = 0x540d; +pub const TCSETS: ::Ioctl = 0x540e; +pub const TCSETSW: ::Ioctl = 0x540f; +pub const TCSETSF: ::Ioctl = 0x5410; +pub const TCGETA: ::Ioctl = 0x5401; +pub const TCSETA: ::Ioctl = 0x5402; +pub const TCSETAW: ::Ioctl = 0x5403; +pub const TCSETAF: ::Ioctl = 0x5404; +pub const TCSBRK: ::Ioctl = 0x5405; +pub const TCXONC: ::Ioctl = 0x5406; +pub const TCFLSH: ::Ioctl = 0x5407; +pub const TIOCEXCL: ::Ioctl = 0x740d; +pub const TIOCNXCL: ::Ioctl = 0x740e; +pub const TIOCSCTTY: ::Ioctl = 0x5480; +pub const TIOCGPGRP: ::Ioctl = 0x40047477; +pub const TIOCSPGRP: ::Ioctl = 0x80047476; +pub const TIOCOUTQ: ::Ioctl = 0x7472; +pub const TIOCSTI: ::Ioctl = 0x5472; +pub const TIOCGWINSZ: ::Ioctl = 0x40087468; +pub const TIOCSWINSZ: ::Ioctl = 0x80087467; +pub const TIOCMGET: ::Ioctl = 0x741d; +pub const TIOCMBIS: ::Ioctl = 0x741b; +pub const TIOCMBIC: ::Ioctl = 0x741c; +pub const TIOCMSET: ::Ioctl = 0x741a; +pub const TIOCGSOFTCAR: ::Ioctl = 0x5481; +pub const TIOCSSOFTCAR: ::Ioctl = 0x5482; +pub const FIONREAD: ::Ioctl = 0x467f; +pub const TIOCINQ: ::Ioctl = FIONREAD; +pub const TIOCLINUX: ::Ioctl = 0x5483; +pub const TIOCCONS: ::Ioctl = 0x80047478; +pub const TIOCGSERIAL: ::Ioctl = 0x5484; +pub const TIOCSSERIAL: ::Ioctl = 0x5485; +pub const TIOCPKT: ::Ioctl = 0x5470; +pub const FIONBIO: ::Ioctl = 0x667e; +pub const TIOCNOTTY: ::Ioctl = 0x5471; +pub const TIOCSETD: ::Ioctl = 0x7401; +pub const TIOCGETD: ::Ioctl = 0x7400; +pub const TCSBRKP: ::Ioctl = 0x5486; +pub const TIOCSBRK: ::Ioctl = 0x5427; +pub const TIOCCBRK: ::Ioctl = 0x5428; +pub const TIOCGSID: ::Ioctl = 0x7416; +pub const TCGETS2: ::Ioctl = 0x4030542a; +pub const TCSETS2: ::Ioctl = 0x8030542b; +pub const TCSETSW2: ::Ioctl = 0x8030542c; +pub const TCSETSF2: ::Ioctl = 0x8030542d; +pub const TIOCGPTN: ::Ioctl = 0x40045430; +pub const TIOCSPTLCK: ::Ioctl = 0x80045431; +pub const TIOCGDEV: ::Ioctl = 0x40045432; +pub const TIOCSIG: ::Ioctl = 0x80045436; +pub const TIOCVHANGUP: ::Ioctl = 0x5437; +pub const TIOCGPKT: ::Ioctl = 0x40045438; +pub const TIOCGPTLCK: ::Ioctl = 0x40045439; +pub const TIOCGEXCL: ::Ioctl = 0x40045440; +pub const TIOCGPTPEER: ::Ioctl = 0x20005441; +//pub const TIOCGISO7816: ::Ioctl = 0x40285442; +//pub const TIOCSISO7816: ::Ioctl = 0xc0285443; +pub const FIONCLEX: ::Ioctl = 0x6602; +pub const FIOCLEX: ::Ioctl = 0x6601; +pub const FIOASYNC: ::Ioctl = 0x667d; +pub const TIOCSERCONFIG: ::Ioctl = 0x5488; +pub const TIOCSERGWILD: ::Ioctl = 0x5489; +pub const TIOCSERSWILD: ::Ioctl = 0x548a; +pub const TIOCGLCKTRMIOS: ::Ioctl = 0x548b; +pub const TIOCSLCKTRMIOS: ::Ioctl = 0x548c; +pub const TIOCSERGSTRUCT: ::Ioctl = 0x548d; +pub const TIOCSERGETLSR: ::Ioctl = 0x548e; +pub const TIOCSERGETMULTI: ::Ioctl = 0x548f; +pub const TIOCSERSETMULTI: ::Ioctl = 0x5490; +pub const TIOCMIWAIT: ::Ioctl = 0x5491; +pub const TIOCGICOUNT: ::Ioctl = 0x5492; +pub const FIOQSIZE: ::Ioctl = 0x667f; +pub const TIOCSLTC: ::Ioctl = 0x7475; +pub const TIOCGETP: ::Ioctl = 0x7408; +pub const TIOCSETP: ::Ioctl = 0x7409; +pub const TIOCSETN: ::Ioctl = 0x740a; +pub const BLKIOMIN: ::Ioctl = 0x20001278; +pub const BLKIOOPT: ::Ioctl = 0x20001279; +pub const BLKSSZGET: ::Ioctl = 0x20001268; +pub const BLKPBSZGET: ::Ioctl = 0x2000127B; + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(target_arch = "mips")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } else if #[cfg(target_arch = "mips64")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } +} + +cfg_if! { + if #[cfg(target_env = "musl")] { + pub const TIOCGRS485: ::Ioctl = 0x4020542e; + pub const TIOCSRS485: ::Ioctl = 0xc020542f; + } +} + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x010; +pub const TIOCM_SR: ::c_int = 0x020; +pub const TIOCM_CTS: ::c_int = 0x040; +pub const TIOCM_CAR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RNG: ::c_int = 0x200; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const TIOCM_DSR: ::c_int = 0x400; + +pub const BOTHER: ::speed_t = 0o010000; +pub const IBSHIFT: ::tcflag_t = 16; + +// RLIMIT Constants + +cfg_if! { + if #[cfg(any(target_env = "gnu", + target_env = "uclibc"))] { + + pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; + pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; + pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; + pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; + pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; + pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 5; + pub const RLIMIT_AS: ::__rlimit_resource_t = 6; + pub const RLIMIT_RSS: ::__rlimit_resource_t = 7; + pub const RLIMIT_NPROC: ::__rlimit_resource_t = 8; + pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 9; + pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; + pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; + pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; + pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; + pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; + pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; + + } else if #[cfg(target_env = "musl")] { + + pub const RLIMIT_CPU: ::c_int = 0; + pub const RLIMIT_FSIZE: ::c_int = 1; + pub const RLIMIT_DATA: ::c_int = 2; + pub const RLIMIT_STACK: ::c_int = 3; + pub const RLIMIT_CORE: ::c_int = 4; + pub const RLIMIT_NOFILE: ::c_int = 5; + pub const RLIMIT_AS: ::c_int = 6; + pub const RLIMIT_RSS: ::c_int = 7; + pub const RLIMIT_NPROC: ::c_int = 8; + pub const RLIMIT_MEMLOCK: ::c_int = 9; + pub const RLIMIT_LOCKS: ::c_int = 10; + pub const RLIMIT_SIGPENDING: ::c_int = 11; + pub const RLIMIT_MSGQUEUE: ::c_int = 12; + pub const RLIMIT_NICE: ::c_int = 13; + pub const RLIMIT_RTPRIO: ::c_int = 14; + pub const RLIMIT_RTTIME: ::c_int = 15; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::c_int = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; + pub const RLIM_INFINITY: ::rlim_t = !0; + } +} + +cfg_if! { + if #[cfg(target_env = "gnu")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; + } else if #[cfg(target_env = "uclibc")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 15; + } +} + +cfg_if! { + if #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"), + any(target_env = "gnu", + target_env = "uclibc"))] { + pub const RLIM_INFINITY: ::rlim_t = !0; + } +} + +cfg_if! { + if #[cfg(any(target_arch = "mips", target_arch = "mips32r6"), + any(target_env = "gnu", + target_env = "uclibc"))] { + pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mod.rs new file mode 100644 index 00000000..7f6ddc5a --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/mod.rs @@ -0,0 +1,18 @@ +cfg_if! { + if #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] { + mod sparc; + pub use self::sparc::*; + } else { + mod generic; + pub use self::generic::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs new file mode 100644 index 00000000..27834dbf --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs @@ -0,0 +1,277 @@ +// arch/powerpc/include/uapi/asm/socket.h + +pub const SOL_SOCKET: ::c_int = 1; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 1; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +// powerpc only differs in these +pub const SO_RCVLOWAT: ::c_int = 16; +pub const SO_SNDLOWAT: ::c_int = 17; +pub const SO_RCVTIMEO: ::c_int = 18; +pub const SO_SNDTIMEO: ::c_int = 19; +// pub const SO_RCVTIMEO_OLD: ::c_int = 18; +// pub const SO_SNDTIMEO_OLD: ::c_int = 19; +pub const SO_PASSCRED: ::c_int = 20; +pub const SO_PEERCRED: ::c_int = 21; +// end +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24; +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_ATTACH_FILTER: ::c_int = 26; +pub const SO_DETACH_FILTER: ::c_int = 27; +pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; +pub const SO_PEERNAME: ::c_int = 28; +pub const SO_TIMESTAMP: ::c_int = 29; +// pub const SO_TIMESTAMP_OLD: ::c_int = 29; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_TIMESTAMPNS: ::c_int = 35; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +pub const SO_MARK: ::c_int = 36; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_WIFI_STATUS: ::c_int = 41; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_NOFCS: ::c_int = 43; +pub const SO_LOCK_FILTER: ::c_int = 44; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 45; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_MAX_PACING_RATE: ::c_int = 47; +pub const SO_BPF_EXTENSIONS: ::c_int = 48; +pub const SO_INCOMING_CPU: ::c_int = 49; +pub const SO_ATTACH_BPF: ::c_int = 50; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 52; +pub const SO_CNX_ADVICE: ::c_int = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SO_MEMINFO: ::c_int = 55; +pub const SO_INCOMING_NAPI_ID: ::c_int = 56; +pub const SO_COOKIE: ::c_int = 57; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_PEERGROUPS: ::c_int = 59; +pub const SO_ZEROCOPY: ::c_int = 60; +pub const SO_TXTIME: ::c_int = 61; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 62; +// pub const SO_TIMESTAMP_NEW: ::c_int = 63; +// pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; +// pub const SO_TIMESTAMPING_NEW: ::c_int = 65; +// pub const SO_RCVTIMEO_NEW: ::c_int = 66; +// pub const SO_SNDTIMEO_NEW: ::c_int = 67; +// pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; +// pub const SO_PREFER_BUSY_POLL: ::c_int = 69; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +pub const FICLONE: ::c_ulong = 0x80049409; +pub const FICLONERANGE: ::c_ulong = 0x8020940D; + +// Defined in unix/linux_like/mod.rs +// pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; +pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; +pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; + +// Ioctl Constants + +cfg_if! { + if #[cfg(target_env = "gnu")] { + pub const TCGETS: ::Ioctl = 0x403c7413; + pub const TCSETS: ::Ioctl = 0x803c7414; + pub const TCSETSW: ::Ioctl = 0x803c7415; + pub const TCSETSF: ::Ioctl = 0x803c7416; + } else if #[cfg(target_env = "musl")] { + pub const TCGETS: ::Ioctl = 0x402c7413; + pub const TCSETS: ::Ioctl = 0x802c7414; + pub const TCSETSW: ::Ioctl = 0x802c7415; + pub const TCSETSF: ::Ioctl = 0x802c7416; + } +} + +pub const TCGETA: ::Ioctl = 0x40147417; +pub const TCSETA: ::Ioctl = 0x80147418; +pub const TCSETAW: ::Ioctl = 0x80147419; +pub const TCSETAF: ::Ioctl = 0x8014741C; +pub const TCSBRK: ::Ioctl = 0x2000741D; +pub const TCXONC: ::Ioctl = 0x2000741E; +pub const TCFLSH: ::Ioctl = 0x2000741F; +pub const TIOCEXCL: ::Ioctl = 0x540C; +pub const TIOCNXCL: ::Ioctl = 0x540D; +pub const TIOCSCTTY: ::Ioctl = 0x540E; +pub const TIOCGPGRP: ::Ioctl = 0x40047477; +pub const TIOCSPGRP: ::Ioctl = 0x80047476; +pub const TIOCOUTQ: ::Ioctl = 0x40047473; +pub const TIOCSTI: ::Ioctl = 0x5412; +pub const TIOCGWINSZ: ::Ioctl = 0x40087468; +pub const TIOCSWINSZ: ::Ioctl = 0x80087467; +pub const TIOCMGET: ::Ioctl = 0x5415; +pub const TIOCMBIS: ::Ioctl = 0x5416; +pub const TIOCMBIC: ::Ioctl = 0x5417; +pub const TIOCMSET: ::Ioctl = 0x5418; +pub const TIOCGSOFTCAR: ::Ioctl = 0x5419; +pub const TIOCSSOFTCAR: ::Ioctl = 0x541A; +pub const FIONREAD: ::Ioctl = 0x4004667F; +pub const TIOCINQ: ::Ioctl = FIONREAD; +pub const TIOCLINUX: ::Ioctl = 0x541C; +pub const TIOCCONS: ::Ioctl = 0x541D; +pub const TIOCGSERIAL: ::Ioctl = 0x541E; +pub const TIOCSSERIAL: ::Ioctl = 0x541F; +pub const TIOCPKT: ::Ioctl = 0x5420; +pub const FIONBIO: ::Ioctl = 0x8004667e; +pub const TIOCNOTTY: ::Ioctl = 0x5422; +pub const TIOCSETD: ::Ioctl = 0x5423; +pub const TIOCGETD: ::Ioctl = 0x5424; +pub const TCSBRKP: ::Ioctl = 0x5425; +pub const TIOCSBRK: ::Ioctl = 0x5427; +pub const TIOCCBRK: ::Ioctl = 0x5428; +pub const TIOCGSID: ::Ioctl = 0x5429; +pub const TIOCGRS485: ::Ioctl = 0x542e; +pub const TIOCSRS485: ::Ioctl = 0x542f; +pub const TIOCGPTN: ::Ioctl = 0x40045430; +pub const TIOCSPTLCK: ::Ioctl = 0x80045431; +pub const TIOCGDEV: ::Ioctl = 0x40045432; +pub const TIOCSIG: ::Ioctl = 0x80045436; +pub const TIOCVHANGUP: ::Ioctl = 0x5437; +pub const TIOCGPKT: ::Ioctl = 0x40045438; +pub const TIOCGPTLCK: ::Ioctl = 0x40045439; +pub const TIOCGEXCL: ::Ioctl = 0x40045440; +pub const TIOCGPTPEER: ::Ioctl = 0x20005441; +//pub const TIOCGISO7816: ::Ioctl = 0x40285442; +//pub const TIOCSISO7816: ::Ioctl = 0xc0285443; +pub const FIONCLEX: ::Ioctl = 0x20006602; +pub const FIOCLEX: ::Ioctl = 0x20006601; +pub const FIOASYNC: ::Ioctl = 0x8004667d; +pub const TIOCSERCONFIG: ::Ioctl = 0x5453; +pub const TIOCSERGWILD: ::Ioctl = 0x5454; +pub const TIOCSERSWILD: ::Ioctl = 0x5455; +pub const TIOCGLCKTRMIOS: ::Ioctl = 0x5456; +pub const TIOCSLCKTRMIOS: ::Ioctl = 0x5457; +pub const TIOCSERGSTRUCT: ::Ioctl = 0x5458; +pub const TIOCSERGETLSR: ::Ioctl = 0x5459; +pub const TIOCSERGETMULTI: ::Ioctl = 0x545A; +pub const TIOCSERSETMULTI: ::Ioctl = 0x545B; +pub const TIOCMIWAIT: ::Ioctl = 0x545C; +pub const TIOCGICOUNT: ::Ioctl = 0x545D; +pub const BLKIOMIN: ::Ioctl = 0x20001278; +pub const BLKIOOPT: ::Ioctl = 0x20001279; +pub const BLKSSZGET: ::Ioctl = 0x20001268; +pub const BLKPBSZGET: ::Ioctl = 0x2000127B; +//pub const FIOQSIZE: ::Ioctl = 0x40086680; + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(target_arch = "powerpc")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } else if #[cfg(target_arch = "powerpc64")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } +} + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const TIOCM_DSR: ::c_int = 0x100; + +pub const BOTHER: ::speed_t = 0o0037; +pub const IBSHIFT: ::tcflag_t = 16; + +// RLIMIT Constants + +cfg_if! { + if #[cfg(target_env = "gnu")] { + + pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; + pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; + pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; + pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; + pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; + pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; + pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; + pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; + pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; + pub const RLIMIT_AS: ::__rlimit_resource_t = 9; + pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; + pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; + pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; + pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; + pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; + pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; + + } else if #[cfg(target_env = "musl")] { + + pub const RLIMIT_CPU: ::c_int = 0; + pub const RLIMIT_FSIZE: ::c_int = 1; + pub const RLIMIT_DATA: ::c_int = 2; + pub const RLIMIT_STACK: ::c_int = 3; + pub const RLIMIT_CORE: ::c_int = 4; + pub const RLIMIT_RSS: ::c_int = 5; + pub const RLIMIT_NPROC: ::c_int = 6; + pub const RLIMIT_NOFILE: ::c_int = 7; + pub const RLIMIT_MEMLOCK: ::c_int = 8; + pub const RLIMIT_AS: ::c_int = 9; + pub const RLIMIT_LOCKS: ::c_int = 10; + pub const RLIMIT_SIGPENDING: ::c_int = 11; + pub const RLIMIT_MSGQUEUE: ::c_int = 12; + pub const RLIMIT_NICE: ::c_int = 13; + pub const RLIMIT_RTPRIO: ::c_int = 14; + pub const RLIMIT_RTTIME: ::c_int = 15; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::c_int = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; + } +} +pub const RLIM_INFINITY: ::rlim_t = !0; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs new file mode 100644 index 00000000..fce466c7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs @@ -0,0 +1,259 @@ +s! { + pub struct termios2 { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; 19], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } +} + +// arch/sparc/include/uapi/asm/socket.h +pub const SOL_SOCKET: ::c_int = 0xffff; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_PASSCRED: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_PEERCRED: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_BSDCOMPAT: ::c_int = 0x0400; +pub const SO_RCVLOWAT: ::c_int = 0x0800; +pub const SO_SNDLOWAT: ::c_int = 0x1000; +pub const SO_RCVTIMEO: ::c_int = 0x2000; +pub const SO_SNDTIMEO: ::c_int = 0x4000; +// pub const SO_RCVTIMEO_OLD: ::c_int = 0x2000; +// pub const SO_SNDTIMEO_OLD: ::c_int = 0x4000; +pub const SO_ACCEPTCONN: ::c_int = 0x8000; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDBUFFORCE: ::c_int = 0x100a; +pub const SO_RCVBUFFORCE: ::c_int = 0x100b; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_PROTOCOL: ::c_int = 0x1028; +pub const SO_DOMAIN: ::c_int = 0x1029; +pub const SO_NO_CHECK: ::c_int = 0x000b; +pub const SO_PRIORITY: ::c_int = 0x000c; +pub const SO_BINDTODEVICE: ::c_int = 0x000d; +pub const SO_ATTACH_FILTER: ::c_int = 0x001a; +pub const SO_DETACH_FILTER: ::c_int = 0x001b; +pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; +pub const SO_PEERNAME: ::c_int = 0x001c; +pub const SO_PEERSEC: ::c_int = 0x001e; +pub const SO_PASSSEC: ::c_int = 0x001f; +pub const SO_MARK: ::c_int = 0x0022; +pub const SO_RXQ_OVFL: ::c_int = 0x0024; +pub const SO_WIFI_STATUS: ::c_int = 0x0025; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 0x0026; +pub const SO_NOFCS: ::c_int = 0x0027; +pub const SO_LOCK_FILTER: ::c_int = 0x0028; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 0x0029; +pub const SO_BUSY_POLL: ::c_int = 0x0030; +pub const SO_MAX_PACING_RATE: ::c_int = 0x0031; +pub const SO_BPF_EXTENSIONS: ::c_int = 0x0032; +pub const SO_INCOMING_CPU: ::c_int = 0x0033; +pub const SO_ATTACH_BPF: ::c_int = 0x0034; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 0x0035; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 0x0036; +pub const SO_CNX_ADVICE: ::c_int = 0x0037; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 0x0038; +pub const SO_MEMINFO: ::c_int = 0x0039; +pub const SO_INCOMING_NAPI_ID: ::c_int = 0x003a; +pub const SO_COOKIE: ::c_int = 0x003b; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 0x003c; +pub const SO_PEERGROUPS: ::c_int = 0x003d; +pub const SO_ZEROCOPY: ::c_int = 0x003e; +pub const SO_TXTIME: ::c_int = 0x003f; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 0x0041; +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 0x5001; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 0x5002; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 0x5004; +pub const SO_TIMESTAMP: ::c_int = 0x001d; +pub const SO_TIMESTAMPNS: ::c_int = 0x0021; +pub const SO_TIMESTAMPING: ::c_int = 0x0023; +// pub const SO_TIMESTAMP_OLD: ::c_int = 0x001d; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 0x0021; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 0x0023; +// pub const SO_TIMESTAMP_NEW: ::c_int = 0x0046; +// pub const SO_TIMESTAMPNS_NEW: ::c_int = 0x0042; +// pub const SO_TIMESTAMPING_NEW: ::c_int = 0x0043; +// pub const SO_RCVTIMEO_NEW: ::c_int = 0x0044; +// pub const SO_SNDTIMEO_NEW: ::c_int = 0x0045; +// pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 0x0047; +// pub const SO_PREFER_BUSY_POLL: ::c_int = 0x0048; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 0x0049; + +// Defined in unix/linux_like/mod.rs +// pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; +pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; +pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; + +// Ioctl Constants + +pub const TCGETS: ::Ioctl = 0x40245408; +pub const TCSETS: ::Ioctl = 0x80245409; +pub const TCSETSW: ::Ioctl = 0x8024540a; +pub const TCSETSF: ::Ioctl = 0x8024540b; +pub const TCGETA: ::Ioctl = 0x40125401; +pub const TCSETA: ::Ioctl = 0x80125402; +pub const TCSETAW: ::Ioctl = 0x80125403; +pub const TCSETAF: ::Ioctl = 0x80125404; +pub const TCSBRK: ::Ioctl = 0x20005405; +pub const TCXONC: ::Ioctl = 0x20005406; +pub const TCFLSH: ::Ioctl = 0x20005407; +pub const TIOCEXCL: ::Ioctl = 0x2000740d; +pub const TIOCNXCL: ::Ioctl = 0x2000740e; +pub const TIOCSCTTY: ::Ioctl = 0x20007484; +pub const TIOCGPGRP: ::Ioctl = 0x40047483; +pub const TIOCSPGRP: ::Ioctl = 0x80047482; +pub const TIOCOUTQ: ::Ioctl = 0x40047473; +pub const TIOCSTI: ::Ioctl = 0x80017472; +pub const TIOCGWINSZ: ::Ioctl = 0x40087468; +pub const TIOCSWINSZ: ::Ioctl = 0x80087467; +pub const TIOCMGET: ::Ioctl = 0x4004746a; +pub const TIOCMBIS: ::Ioctl = 0x8004746c; +pub const TIOCMBIC: ::Ioctl = 0x8004746b; +pub const TIOCMSET: ::Ioctl = 0x8004746d; +pub const TIOCGSOFTCAR: ::Ioctl = 0x40047464; +pub const TIOCSSOFTCAR: ::Ioctl = 0x80047465; +pub const FIONREAD: ::Ioctl = 0x4004667f; +pub const TIOCINQ: ::Ioctl = FIONREAD; +pub const TIOCLINUX: ::Ioctl = 0x541C; +pub const TIOCCONS: ::Ioctl = 0x20007424; +pub const TIOCGSERIAL: ::Ioctl = 0x541E; +pub const TIOCSSERIAL: ::Ioctl = 0x541F; +pub const TIOCPKT: ::Ioctl = 0x80047470; +pub const FIONBIO: ::Ioctl = 0x8004667e; +pub const TIOCNOTTY: ::Ioctl = 0x20007471; +pub const TIOCSETD: ::Ioctl = 0x80047401; +pub const TIOCGETD: ::Ioctl = 0x40047400; +pub const TCSBRKP: ::Ioctl = 0x5425; +pub const TIOCSBRK: ::Ioctl = 0x2000747b; +pub const TIOCCBRK: ::Ioctl = 0x2000747a; +pub const TIOCGSID: ::Ioctl = 0x40047485; +pub const TCGETS2: ::Ioctl = 0x402c540c; +pub const TCSETS2: ::Ioctl = 0x802c540d; +pub const TCSETSW2: ::Ioctl = 0x802c540e; +pub const TCSETSF2: ::Ioctl = 0x802c540f; +pub const TIOCGPTN: ::Ioctl = 0x40047486; +pub const TIOCSPTLCK: ::Ioctl = 0x80047487; +pub const TIOCGDEV: ::Ioctl = 0x40045432; +pub const TIOCSIG: ::Ioctl = 0x80047488; +pub const TIOCVHANGUP: ::Ioctl = 0x20005437; +pub const TIOCGPKT: ::Ioctl = 0x40045438; +pub const TIOCGPTLCK: ::Ioctl = 0x40045439; +pub const TIOCGEXCL: ::Ioctl = 0x40045440; +pub const TIOCGPTPEER: ::Ioctl = 0x20007489; +pub const FIONCLEX: ::Ioctl = 0x20006602; +pub const FIOCLEX: ::Ioctl = 0x20006601; +pub const TIOCSERCONFIG: ::Ioctl = 0x5453; +pub const TIOCSERGWILD: ::Ioctl = 0x5454; +pub const TIOCSERSWILD: ::Ioctl = 0x5455; +pub const TIOCGLCKTRMIOS: ::Ioctl = 0x5456; +pub const TIOCSLCKTRMIOS: ::Ioctl = 0x5457; +pub const TIOCSERGSTRUCT: ::Ioctl = 0x5458; +pub const TIOCSERGETLSR: ::Ioctl = 0x5459; +pub const TIOCSERGETMULTI: ::Ioctl = 0x545A; +pub const TIOCSERSETMULTI: ::Ioctl = 0x545B; +pub const TIOCMIWAIT: ::Ioctl = 0x545C; +pub const TIOCGICOUNT: ::Ioctl = 0x545D; +pub const TIOCSTART: ::Ioctl = 0x2000746e; +pub const TIOCSTOP: ::Ioctl = 0x2000746f; +pub const BLKIOMIN: ::Ioctl = 0x20001278; +pub const BLKIOOPT: ::Ioctl = 0x20001279; +pub const BLKSSZGET: ::Ioctl = 0x20001268; +pub const BLKPBSZGET: ::Ioctl = 0x2000127B; + +//pub const FIOASYNC: ::Ioctl = 0x4004667d; +//pub const FIOQSIZE: ::Ioctl = ; +//pub const TIOCGISO7816: ::Ioctl = 0x40285443; +//pub const TIOCSISO7816: ::Ioctl = 0xc0285444; +//pub const TIOCGRS485: ::Ioctl = 0x40205441; +//pub const TIOCSRS485: ::Ioctl = 0xc0205442; + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const TIOCM_DSR: ::c_int = 0x100; + +pub const BOTHER: ::speed_t = 0x1000; +pub const IBSHIFT: ::tcflag_t = 16; + +// RLIMIT Constants + +pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; +pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; +pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; +pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; +pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; +pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 6; +pub const RLIMIT_NPROC: ::__rlimit_resource_t = 7; +pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; +pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; +pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; +pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; +pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; +pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; + +cfg_if! { + if #[cfg(target_arch = "sparc64")] { + pub const RLIM_INFINITY: ::rlim_t = !0; + } else if #[cfg(target_arch = "sparc")] { + pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; + } +} + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(target_arch = "sparc")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } else if #[cfg(target_arch = "sparc64")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/align.rs new file mode 100644 index 00000000..4a0e0746 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/align.rs @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs new file mode 100644 index 00000000..2645ec4c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs @@ -0,0 +1,53 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 2] + } + + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: ::mcontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_regspace: [::c_ulong; 128], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_link) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs new file mode 100644 index 00000000..89c93aba --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs @@ -0,0 +1,864 @@ +pub type c_char = u8; +pub type wchar_t = u32; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_uint, + __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_uint, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino64_t, + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_ulong, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_ulong, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct mcontext_t { + pub trap_no: ::c_ulong, + pub error_code: ::c_ulong, + pub oldmask: ::c_ulong, + pub arm_r0: ::c_ulong, + pub arm_r1: ::c_ulong, + pub arm_r2: ::c_ulong, + pub arm_r3: ::c_ulong, + pub arm_r4: ::c_ulong, + pub arm_r5: ::c_ulong, + pub arm_r6: ::c_ulong, + pub arm_r7: ::c_ulong, + pub arm_r8: ::c_ulong, + pub arm_r9: ::c_ulong, + pub arm_r10: ::c_ulong, + pub arm_fp: ::c_ulong, + pub arm_ip: ::c_ulong, + pub arm_sp: ::c_ulong, + pub arm_lr: ::c_ulong, + pub arm_pc: ::c_ulong, + pub arm_cpsr: ::c_ulong, + pub fault_address: ::c_ulong, + } + + pub struct user_regs { + pub arm_r0: ::c_ulong, + pub arm_r1: ::c_ulong, + pub arm_r2: ::c_ulong, + pub arm_r3: ::c_ulong, + pub arm_r4: ::c_ulong, + pub arm_r5: ::c_ulong, + pub arm_r6: ::c_ulong, + pub arm_r7: ::c_ulong, + pub arm_r8: ::c_ulong, + pub arm_r9: ::c_ulong, + pub arm_r10: ::c_ulong, + pub arm_fp: ::c_ulong, + pub arm_ip: ::c_ulong, + pub arm_sp: ::c_ulong, + pub arm_lr: ::c_ulong, + pub arm_pc: ::c_ulong, + pub arm_cpsr: ::c_ulong, + pub arm_orig_r0: ::c_ulong, + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_LARGEFILE: ::c_int = 0o400000; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_arm_fadvise64_64: ::c_long = 270; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_arm_sync_file_range: ::c_long = 341; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +pub const SYS_pwritev2: ::c_long = 393; +pub const SYS_pkey_mprotect: ::c_long = 394; +pub const SYS_pkey_alloc: ::c_long = 395; +pub const SYS_pkey_free: ::c_long = 396; +pub const SYS_statx: ::c_long = 397; +pub const SYS_rseq: ::c_long = 398; +pub const SYS_kexec_file_load: ::c_long = 401; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs new file mode 100644 index 00000000..825546be --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 2] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs new file mode 100644 index 00000000..5e92e300 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs @@ -0,0 +1,741 @@ +pub type c_char = u8; +pub type wchar_t = u32; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_uint, + __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_uint, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino64_t, + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_ulong, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_ulong, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o100000; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +// Syscall table +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_close: ::c_long = 57; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_brk: ::c_long = 214; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_dup: ::c_long = 23; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_sendfile: ::c_long = 71; +pub const SYS_socket: ::c_long = 198; +pub const SYS_connect: ::c_long = 203; +pub const SYS_accept: ::c_long = 202; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_exit: ::c_long = 93; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_kill: ::c_long = 129; +pub const SYS_uname: ::c_long = 160; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semop: ::c_long = 193; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_flock: ::c_long = 32; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_umask: ::c_long = 166; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_times: ::c_long = 153; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_personality: ::c_long = 92; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_sync: ::c_long = 81; +pub const SYS_acct: ::c_long = 89; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_mount: ::c_long = 40; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_futex: ::c_long = 98; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_fadvise64: ::c_long = 223; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_openat: ::c_long = 56; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_setns: ::c_long = 268; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_rseq: ::c_long = 293; +pub const SYS_syscall: ::c_long = 294; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs new file mode 100644 index 00000000..639394a3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(2))] + pub struct max_align_t { + priv_: [i8; 20] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs new file mode 100644 index 00000000..8ca7d3d2 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs @@ -0,0 +1,850 @@ +pub type c_char = i8; +pub type wchar_t = i32; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + f_spare: [::__fsword_t; 4], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct ipc_perm { + __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + __seq: ::c_ushort, + __pad1: ::c_ushort, + __glibc_reserved1: ::c_ulong, + __glibc_reserved2: ::c_ulong, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_ushort, + pub __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_ushort, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_ulong, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_ulong, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_ulong, + pub st_ino: ::ino64_t, + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsblkcnt64_t, + pub f_ffree: ::fsblkcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsblkcnt64_t, + pub f_ffree: ::fsblkcnt64_t, + pub f_favail: ::fsblkcnt64_t, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __glibc_reserved1: ::c_long, + pub shm_dtime: ::time_t, + __glibc_reserved2: ::c_long, + pub shm_ctime: ::time_t, + __glibc_reserved3: ::c_long, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __glibc_reserved5: ::c_ulong, + __glibc_reserved6: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_uint, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_uint, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::c_uint, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_LARGEFILE: ::c_int = 0x20000; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_32BIT: ::c_int = 0x0040; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_SYSEMU: ::c_uint = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time32: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_chown16: ::c_long = 16; +pub const SYS_stat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_oldumount: ::c_long = 22; +pub const SYS_setuid16: ::c_long = 23; +pub const SYS_getuid16: ::c_long = 24; +pub const SYS_stime32: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_fstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime32: ::c_long = 30; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid16: ::c_long = 46; +pub const SYS_getgid16: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid16: ::c_long = 49; +pub const SYS_getegid16: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid16: ::c_long = 70; +pub const SYS_setregid16: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_old_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups16: ::c_long = 80; +pub const SYS_setgroups16: ::c_long = 81; +pub const SYS_old_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_lstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_old_readdir: ::c_long = 89; +pub const SYS_old_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown16: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_newstat: ::c_long = 106; +pub const SYS_newlstat: ::c_long = 107; +pub const SYS_newfstat: ::c_long = 108; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_newuname: ::c_long = 122; +pub const SYS_cacheflush: ::c_long = 123; +pub const SYS_adjtimex_time32: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_setfsuid16: ::c_long = 138; +pub const SYS_setfsgid16: ::c_long = 139; +pub const SYS_llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS_select: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval_time32: ::c_long = 161; +pub const SYS_nanosleep_time32: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid16: ::c_long = 164; +pub const SYS_getresuid16: ::c_long = 165; +pub const SYS_getpagesize: ::c_long = 166; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid16: ::c_long = 170; +pub const SYS_getresgid16: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait_time32: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_lchown16: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_getrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_chown: ::c_long = 198; +pub const SYS_getuid: ::c_long = 199; +pub const SYS_getgid: ::c_long = 200; +pub const SYS_geteuid: ::c_long = 201; +pub const SYS_getegid: ::c_long = 202; +pub const SYS_setreuid: ::c_long = 203; +pub const SYS_setregid: ::c_long = 204; +pub const SYS_getgroups: ::c_long = 205; +pub const SYS_setgroups: ::c_long = 206; +pub const SYS_fchown: ::c_long = 207; +pub const SYS_setresuid: ::c_long = 208; +pub const SYS_getresuid: ::c_long = 209; +pub const SYS_setresgid: ::c_long = 210; +pub const SYS_getresgid: ::c_long = 211; +pub const SYS_lchown: ::c_long = 212; +pub const SYS_setuid: ::c_long = 213; +pub const SYS_setgid: ::c_long = 214; +pub const SYS_setfsuid: ::c_long = 215; +pub const SYS_setfsgid: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_gettid: ::c_long = 221; +pub const SYS_tkill: ::c_long = 222; +pub const SYS_setxattr: ::c_long = 223; +pub const SYS_lsetxattr: ::c_long = 224; +pub const SYS_fsetxattr: ::c_long = 225; +pub const SYS_getxattr: ::c_long = 226; +pub const SYS_lgetxattr: ::c_long = 227; +pub const SYS_fgetxattr: ::c_long = 228; +pub const SYS_listxattr: ::c_long = 229; +pub const SYS_llistxattr: ::c_long = 230; +pub const SYS_flistxattr: ::c_long = 231; +pub const SYS_removexattr: ::c_long = 232; +pub const SYS_lremovexattr: ::c_long = 233; +pub const SYS_fremovexattr: ::c_long = 234; +pub const SYS_futex_time32: ::c_long = 235; +pub const SYS_sendfile64: ::c_long = 236; +pub const SYS_mincore: ::c_long = 237; +pub const SYS_madvise: ::c_long = 238; +pub const SYS_fcntl64: ::c_long = 239; +pub const SYS_readahead: ::c_long = 240; +pub const SYS_io_setup: ::c_long = 241; +pub const SYS_io_destroy: ::c_long = 242; +pub const SYS_io_getevents_time32: ::c_long = 243; +pub const SYS_io_submit: ::c_long = 244; +pub const SYS_io_cancel: ::c_long = 245; +pub const SYS_fadvise64: ::c_long = 246; +pub const SYS_exit_group: ::c_long = 247; +pub const SYS_lookup_dcookie: ::c_long = 248; +pub const SYS_epoll_create: ::c_long = 249; +pub const SYS_epoll_ctl: ::c_long = 250; +pub const SYS_epoll_wait: ::c_long = 251; +pub const SYS_remap_file_pages: ::c_long = 252; +pub const SYS_set_tid_address: ::c_long = 253; +pub const SYS_timer_create: ::c_long = 254; +pub const SYS_timer_settime32: ::c_long = 255; +pub const SYS_timer_gettime32: ::c_long = 256; +pub const SYS_timer_getoverrun: ::c_long = 257; +pub const SYS_timer_delete: ::c_long = 258; +pub const SYS_clock_settime32: ::c_long = 259; +pub const SYS_clock_gettime32: ::c_long = 260; +pub const SYS_clock_getres_time32: ::c_long = 261; +pub const SYS_clock_nanosleep_time32: ::c_long = 262; +pub const SYS_statfs64: ::c_long = 263; +pub const SYS_fstatfs64: ::c_long = 264; +pub const SYS_tgkill: ::c_long = 265; +pub const SYS_utimes_time32: ::c_long = 266; +pub const SYS_fadvise64_64: ::c_long = 267; +pub const SYS_mbind: ::c_long = 268; +pub const SYS_get_mempolicy: ::c_long = 269; +pub const SYS_set_mempolicy: ::c_long = 270; +pub const SYS_mq_open: ::c_long = 271; +pub const SYS_mq_unlink: ::c_long = 272; +pub const SYS_mq_timedsend_time32: ::c_long = 273; +pub const SYS_mq_timedreceive_time32: ::c_long = 274; +pub const SYS_mq_notify: ::c_long = 275; +pub const SYS_mq_getsetattr: ::c_long = 276; +pub const SYS_waitid: ::c_long = 277; +pub const SYS_add_key: ::c_long = 279; +pub const SYS_request_key: ::c_long = 280; +pub const SYS_keyctl: ::c_long = 281; +pub const SYS_ioprio_set: ::c_long = 282; +pub const SYS_ioprio_get: ::c_long = 283; +pub const SYS_inotify_init: ::c_long = 284; +pub const SYS_inotify_add_watch: ::c_long = 285; +pub const SYS_inotify_rm_watch: ::c_long = 286; +pub const SYS_migrate_pages: ::c_long = 287; +pub const SYS_openat: ::c_long = 288; +pub const SYS_mkdirat: ::c_long = 289; +pub const SYS_mknodat: ::c_long = 290; +pub const SYS_fchownat: ::c_long = 291; +pub const SYS_futimesat_time32: ::c_long = 292; +pub const SYS_fstatat64: ::c_long = 293; +pub const SYS_unlinkat: ::c_long = 294; +pub const SYS_renameat: ::c_long = 295; +pub const SYS_linkat: ::c_long = 296; +pub const SYS_symlinkat: ::c_long = 297; +pub const SYS_readlinkat: ::c_long = 298; +pub const SYS_fchmodat: ::c_long = 299; +pub const SYS_faccessat: ::c_long = 300; +pub const SYS_pselect6_time32: ::c_long = 301; +pub const SYS_ppoll_time32: ::c_long = 302; +pub const SYS_unshare: ::c_long = 303; +pub const SYS_set_robust_list: ::c_long = 304; +pub const SYS_get_robust_list: ::c_long = 305; +pub const SYS_splice: ::c_long = 306; +pub const SYS_sync_file_range: ::c_long = 307; +pub const SYS_tee: ::c_long = 308; +pub const SYS_vmsplice: ::c_long = 309; +pub const SYS_move_pages: ::c_long = 310; +pub const SYS_sched_setaffinity: ::c_long = 311; +pub const SYS_sched_getaffinity: ::c_long = 312; +pub const SYS_kexec_load: ::c_long = 313; +pub const SYS_getcpu: ::c_long = 314; +pub const SYS_epoll_pwait: ::c_long = 315; +pub const SYS_utimensat_time32: ::c_long = 316; +pub const SYS_signalfd: ::c_long = 317; +pub const SYS_timerfd_create: ::c_long = 318; +pub const SYS_eventfd: ::c_long = 319; +pub const SYS_fallocate: ::c_long = 320; +pub const SYS_timerfd_settime32: ::c_long = 321; +pub const SYS_timerfd_gettime32: ::c_long = 322; +pub const SYS_signalfd4: ::c_long = 323; +pub const SYS_eventfd2: ::c_long = 324; +pub const SYS_epoll_create1: ::c_long = 325; +pub const SYS_dup3: ::c_long = 326; +pub const SYS_pipe2: ::c_long = 327; +pub const SYS_inotify_init1: ::c_long = 328; +pub const SYS_preadv: ::c_long = 329; +pub const SYS_pwritev: ::c_long = 330; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 331; +pub const SYS_perf_event_open: ::c_long = 332; +pub const SYS_get_thread_area: ::c_long = 333; +pub const SYS_set_thread_area: ::c_long = 334; +pub const SYS_atomic_cmpxchg_32: ::c_long = 335; +pub const SYS_atomic_barrier: ::c_long = 336; +pub const SYS_fanotify_init: ::c_long = 337; +pub const SYS_fanotify_mark: ::c_long = 338; +pub const SYS_prlimit64: ::c_long = 339; +pub const SYS_name_to_handle_at: ::c_long = 340; +pub const SYS_open_by_handle_at: ::c_long = 341; +pub const SYS_clock_adjtime32: ::c_long = 342; +pub const SYS_syncfs: ::c_long = 343; +pub const SYS_setns: ::c_long = 344; +pub const SYS_process_vm_readv: ::c_long = 345; +pub const SYS_process_vm_writev: ::c_long = 346; +pub const SYS_kcmp: ::c_long = 347; +pub const SYS_finit_module: ::c_long = 348; +pub const SYS_sched_setattr: ::c_long = 349; +pub const SYS_sched_getattr: ::c_long = 350; +pub const SYS_renameat2: ::c_long = 351; +pub const SYS_getrandom: ::c_long = 352; +pub const SYS_memfd_create: ::c_long = 353; +pub const SYS_bpf: ::c_long = 354; +pub const SYS_execveat: ::c_long = 355; +pub const SYS_socket: ::c_long = 356; +pub const SYS_socketpair: ::c_long = 357; +pub const SYS_bind: ::c_long = 358; +pub const SYS_connect: ::c_long = 359; +pub const SYS_listen: ::c_long = 360; +pub const SYS_accept4: ::c_long = 361; +pub const SYS_getsockopt: ::c_long = 362; +pub const SYS_setsockopt: ::c_long = 363; +pub const SYS_getsockname: ::c_long = 364; +pub const SYS_getpeername: ::c_long = 365; +pub const SYS_sendto: ::c_long = 366; +pub const SYS_sendmsg: ::c_long = 367; +pub const SYS_recvfrom: ::c_long = 368; +pub const SYS_recvmsg: ::c_long = 369; +pub const SYS_shutdown: ::c_long = 370; +pub const SYS_recvmmsg_time32: ::c_long = 371; +pub const SYS_sendmmsg: ::c_long = 372; +pub const SYS_userfaultfd: ::c_long = 373; +pub const SYS_membarrier: ::c_long = 374; +pub const SYS_mlock2: ::c_long = 375; +pub const SYS_copy_file_range: ::c_long = 376; +pub const SYS_preadv2: ::c_long = 377; +pub const SYS_pwritev2: ::c_long = 378; +pub const SYS_statx: ::c_long = 379; +pub const SYS_seccomp: ::c_long = 380; +pub const SYS_pkey_mprotect: ::c_long = 381; +pub const SYS_pkey_alloc: ::c_long = 382; +pub const SYS_pkey_free: ::c_long = 383; +pub const SYS_rseq: ::c_long = 384; +pub const SYS_semget: ::c_long = 393; +pub const SYS_semctl: ::c_long = 394; +pub const SYS_shmget: ::c_long = 395; +pub const SYS_shmctl: ::c_long = 396; +pub const SYS_shmat: ::c_long = 397; +pub const SYS_shmdt: ::c_long = 398; +pub const SYS_msgget: ::c_long = 399; +pub const SYS_msgsnd: ::c_long = 400; +pub const SYS_msgrcv: ::c_long = 401; +pub const SYS_msgctl: ::c_long = 402; +pub const SYS_clock_gettime: ::c_long = 403; +pub const SYS_clock_settime: ::c_long = 404; +pub const SYS_clock_adjtime: ::c_long = 405; +pub const SYS_clock_getres: ::c_long = 406; +pub const SYS_clock_nanosleep: ::c_long = 407; +pub const SYS_timer_gettime: ::c_long = 408; +pub const SYS_timer_settime: ::c_long = 409; +pub const SYS_timerfd_gettime: ::c_long = 410; +pub const SYS_timerfd_settime: ::c_long = 411; +pub const SYS_utimensat: ::c_long = 412; +pub const SYS_pselect6: ::c_long = 413; +pub const SYS_ppoll: ::c_long = 414; +pub const SYS_io_pgetevents: ::c_long = 416; +pub const SYS_recvmmsg: ::c_long = 417; +pub const SYS_mq_timedsend: ::c_long = 418; +pub const SYS_mq_timedreceive: ::c_long = 419; +pub const SYS_semtimedop: ::c_long = 420; +pub const SYS_rt_sigtimedwait: ::c_long = 421; +pub const SYS_futex: ::c_long = 422; +pub const SYS_sched_rr_get_interval: ::c_long = 423; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/align.rs new file mode 100644 index 00000000..8c228eba --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f32; 4] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs new file mode 100644 index 00000000..fa270750 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs @@ -0,0 +1,819 @@ +pub type c_char = i8; +pub type wchar_t = i32; + +s! { + pub struct stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 3], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 14], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_bavail: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 5], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_restorer: ::Option, + _resv: [::c_int; 1], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __glibc_reserved1: ::c_ulong, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved1: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved2: ::c_ulong, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved2: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved3: ::c_ulong, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_sysid: ::c_long, + pub l_pid: ::pid_t, + pad: [::c_long; 4], + } +} + +pub const O_LARGEFILE: ::c_int = 0x2000; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS__newselect: ::c_long = 4000 + 142; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_pread64: ::c_long = 4000 + 200; +pub const SYS_pwrite64: ::c_long = 4000 + 201; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_fadvise64: ::c_long = 4000 + 254; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_fstatat64: ::c_long = 4000 + 293; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +pub const SYS_pwritev2: ::c_long = 4000 + 362; +pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; +pub const SYS_pkey_alloc: ::c_long = 4000 + 364; +pub const SYS_pkey_free: ::c_long = 4000 + 365; +pub const SYS_statx: ::c_long = 4000 + 366; +pub const SYS_rseq: ::c_long = 4000 + 367; +pub const SYS_pidfd_send_signal: ::c_long = 4000 + 424; +pub const SYS_io_uring_setup: ::c_long = 4000 + 425; +pub const SYS_io_uring_enter: ::c_long = 4000 + 426; +pub const SYS_io_uring_register: ::c_long = 4000 + 427; +pub const SYS_open_tree: ::c_long = 4000 + 428; +pub const SYS_move_mount: ::c_long = 4000 + 429; +pub const SYS_fsopen: ::c_long = 4000 + 430; +pub const SYS_fsconfig: ::c_long = 4000 + 431; +pub const SYS_fsmount: ::c_long = 4000 + 432; +pub const SYS_fspick: ::c_long = 4000 + 433; +pub const SYS_pidfd_open: ::c_long = 4000 + 434; +pub const SYS_clone3: ::c_long = 4000 + 435; +pub const SYS_close_range: ::c_long = 4000 + 436; +pub const SYS_openat2: ::c_long = 4000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 4000 + 438; +pub const SYS_faccessat2: ::c_long = 4000 + 439; +pub const SYS_process_madvise: ::c_long = 4000 + 440; +pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; +pub const SYS_mount_setattr: ::c_long = 4000 + 442; +pub const SYS_quotactl_fd: ::c_long = 4000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; +pub const SYS_memfd_secret: ::c_long = 4000 + 447; +pub const SYS_process_mrelease: ::c_long = 4000 + 448; +pub const SYS_futex_waitv: ::c_long = 4000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; + +pub const O_DIRECT: ::c_int = 0x8000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x4010; +pub const O_RSYNC: ::c_int = 0x4010; +pub const O_DSYNC: ::c_int = 0x10; +pub const O_FSYNC: ::c_int = 0x4010; +pub const O_ASYNC: ::c_int = 0x1000; +pub const O_NDELAY: ::c_int = 0x80; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_ANONYMOUS: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_POPULATE: ::c_int = 0x10000; +pub const MAP_NONBLOCK: ::c_int = 0x20000; +pub const MAP_STACK: ::c_int = 0x40000; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGWINCH: ::c_int = 20; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGCONT: ::c_int = 25; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGURG: ::c_int = 21; +pub const SIGIO: ::c_int = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 22; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const TCSANOW: ::c_int = 0x540e; +pub const TCSADRAIN: ::c_int = 0x540f; +pub const TCSAFLUSH: ::c_int = 0x5410; + +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; + +pub const MAP_HUGETLB: ::c_int = 0x080000; + +pub const EFD_NONBLOCK: ::c_int = 0x80; + +pub const F_GETLK: ::c_int = 14; +pub const F_GETOWN: ::c_int = 23; +pub const F_SETOWN: ::c_int = 24; + +pub const SFD_NONBLOCK: ::c_int = 0x80; + +pub const RTLD_DEEPBIND: ::c_int = 0x10; +pub const RTLD_GLOBAL: ::c_int = 0x4; +pub const RTLD_NOLOAD: ::c_int = 0x8; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const EHWPOISON: ::c_int = 168; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs new file mode 100644 index 00000000..d5b11347 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs @@ -0,0 +1,361 @@ +//! 32-bit specific definitions for linux-like values + +use pthread_mutex_t; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type clock_t = i32; + +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type nlink_t = u32; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; +pub type __fsword_t = i32; +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; +pub type __syscall_ulong_t = ::c_ulong; + +cfg_if! { + if #[cfg(target_arch = "riscv32")] { + pub type time_t = i64; + pub type suseconds_t = i64; + pub type ino_t = u64; + pub type off_t = i64; + pub type blkcnt_t = i64; + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u64; + pub type rlim_t = u64; + pub type blksize_t = i64; + } else { + pub type time_t = i32; + pub type suseconds_t = i32; + pub type ino_t = u32; + pub type off_t = i32; + pub type blkcnt_t = i32; + pub type fsblkcnt_t = ::c_ulong; + pub type fsfilcnt_t = ::c_ulong; + pub type rlim_t = c_ulong; + pub type blksize_t = i32; + } +} + +s! { + pub struct stat { + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_dev: ::dev_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_dev: ::c_ulong, + + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __pad1: ::c_short, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad1: [::c_long; 3], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_rdev: ::dev_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_rdev: ::c_ulong, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __pad2: ::c_short, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad2: [::c_long; 2], + pub st_size: ::off_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad3: ::c_long, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_blksize: ::blksize_t, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __unused4: ::c_long, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __unused5: ::c_long, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_blksize: ::blksize_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_blocks: ::blkcnt_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad5: [::c_long; 14], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + #[deprecated( + since = "0.2.58", + note = "This padding field might become private in the future" + )] + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } + + pub struct semid_ds { + pub sem_perm: ipc_perm, + #[cfg(target_arch = "powerpc")] + __reserved: ::__syscall_ulong_t, + pub sem_otime: ::time_t, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6", target_arch = "powerpc")))] + __reserved: ::__syscall_ulong_t, + #[cfg(target_arch = "powerpc")] + __reserved2: ::__syscall_ulong_t, + pub sem_ctime: ::time_t, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6", target_arch = "powerpc")))] + __reserved2: ::__syscall_ulong_t, + pub sem_nsems: ::__syscall_ulong_t, + __glibc_reserved3: ::__syscall_ulong_t, + __glibc_reserved4: ::__syscall_ulong_t, + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +cfg_if! { + if #[cfg(target_arch = "sparc")] { + pub const O_NOATIME: ::c_int = 0x200000; + pub const O_PATH: ::c_int = 0x1000000; + pub const O_TMPFILE: ::c_int = 0x2000000 | O_DIRECTORY; + + pub const SA_ONSTACK: ::c_int = 1; + + pub const PTRACE_DETACH: ::c_uint = 11; + + pub const F_SETLK: ::c_int = 8; + pub const F_SETLKW: ::c_int = 9; + + pub const F_RDLCK: ::c_int = 1; + pub const F_WRLCK: ::c_int = 2; + pub const F_UNLCK: ::c_int = 3; + + pub const SFD_CLOEXEC: ::c_int = 0x400000; + + pub const NCCS: usize = 17; + + pub const O_TRUNC: ::c_int = 0x400; + pub const O_CLOEXEC: ::c_int = 0x400000; + + pub const EBFONT: ::c_int = 109; + pub const ENOSTR: ::c_int = 72; + pub const ENODATA: ::c_int = 111; + pub const ETIME: ::c_int = 73; + pub const ENOSR: ::c_int = 74; + pub const ENONET: ::c_int = 80; + pub const ENOPKG: ::c_int = 113; + pub const EREMOTE: ::c_int = 71; + pub const ENOLINK: ::c_int = 82; + pub const EADV: ::c_int = 83; + pub const ESRMNT: ::c_int = 84; + pub const ECOMM: ::c_int = 85; + pub const EPROTO: ::c_int = 86; + pub const EDOTDOT: ::c_int = 88; + + pub const SA_NODEFER: ::c_int = 0x20; + pub const SA_RESETHAND: ::c_int = 0x4; + pub const SA_RESTART: ::c_int = 0x2; + pub const SA_NOCLDSTOP: ::c_int = 0x00000008; + + pub const EPOLL_CLOEXEC: ::c_int = 0x400000; + + pub const EFD_CLOEXEC: ::c_int = 0x400000; + } else { + pub const O_NOATIME: ::c_int = 0o1000000; + pub const O_PATH: ::c_int = 0o10000000; + pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + + pub const SA_ONSTACK: ::c_int = 0x08000000; + + pub const PTRACE_DETACH: ::c_uint = 17; + + pub const F_SETLK: ::c_int = 6; + pub const F_SETLKW: ::c_int = 7; + + pub const F_RDLCK: ::c_int = 0; + pub const F_WRLCK: ::c_int = 1; + pub const F_UNLCK: ::c_int = 2; + + pub const SFD_CLOEXEC: ::c_int = 0x080000; + + pub const NCCS: usize = 32; + + pub const O_TRUNC: ::c_int = 512; + pub const O_CLOEXEC: ::c_int = 0x80000; + pub const EBFONT: ::c_int = 59; + pub const ENOSTR: ::c_int = 60; + pub const ENODATA: ::c_int = 61; + pub const ETIME: ::c_int = 62; + pub const ENOSR: ::c_int = 63; + pub const ENONET: ::c_int = 64; + pub const ENOPKG: ::c_int = 65; + pub const EREMOTE: ::c_int = 66; + pub const ENOLINK: ::c_int = 67; + pub const EADV: ::c_int = 68; + pub const ESRMNT: ::c_int = 69; + pub const ECOMM: ::c_int = 70; + pub const EPROTO: ::c_int = 71; + pub const EDOTDOT: ::c_int = 73; + + pub const SA_NODEFER: ::c_int = 0x40000000; + pub const SA_RESETHAND: ::c_int = 0x80000000; + pub const SA_RESTART: ::c_int = 0x10000000; + pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + + pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + + pub const EFD_CLOEXEC: ::c_int = 0x80000; + } +} + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; +} + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(target_arch = "m68k")] { + mod m68k; + pub use self::m68k::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(target_arch = "sparc")] { + mod sparc; + pub use self::sparc::*; + } else if #[cfg(target_arch = "riscv32")] { + mod riscv32; + pub use self::riscv32::*; + } else if #[cfg(target_arch = "csky")] { + mod csky; + pub use self::csky::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs new file mode 100644 index 00000000..dd5732e0 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs @@ -0,0 +1,825 @@ +pub type c_char = u8; +pub type wchar_t = i32; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct ipc_perm { + __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + __seq: u32, + __pad1: u32, + __glibc_reserved1: u64, + __glibc_reserved2: u64, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_ushort, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + __glibc_reserved1: ::c_uint, + pub shm_atime: ::time_t, + __glibc_reserved2: ::c_uint, + pub shm_dtime: ::time_t, + __glibc_reserved3: ::c_uint, + pub shm_ctime: ::time_t, + __glibc_reserved4: ::c_uint, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __glibc_reserved5: ::c_ulong, + __glibc_reserved6: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __glibc_reserved1: ::c_uint, + pub msg_stime: ::time_t, + __glibc_reserved2: ::c_uint, + pub msg_rtime: ::time_t, + __glibc_reserved3: ::c_uint, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_DIRECT: ::c_int = 0x20000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_LARGEFILE: ::c_int = 0o200000; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_LOCKED: ::c_int = 0x00080; +pub const MAP_NORESERVE: ::c_int = 0x00040; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 58; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGSTKSZ: ::size_t = 0x4000; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0xff; +pub const TAB1: ::tcflag_t = 0x400; +pub const TAB2: ::tcflag_t = 0x800; +pub const TAB3: ::tcflag_t = 0xc00; +pub const CR1: ::tcflag_t = 0x1000; +pub const CR2: ::tcflag_t = 0x2000; +pub const CR3: ::tcflag_t = 0x3000; +pub const FF1: ::tcflag_t = 0x4000; +pub const BS1: ::tcflag_t = 0x8000; +pub const VT1: ::tcflag_t = 0x10000; +pub const VWERASE: usize = 0xa; +pub const VREPRINT: usize = 0xb; +pub const VSUSP: usize = 0xc; +pub const VSTART: usize = 0xd; +pub const VSTOP: usize = 0xe; +pub const VDISCARD: usize = 0x10; +pub const VTIME: usize = 0x7; +pub const IXON: ::tcflag_t = 0x200; +pub const IXOFF: ::tcflag_t = 0x400; +pub const ONLCR: ::tcflag_t = 0x2; +pub const CSIZE: ::tcflag_t = 0x300; +pub const CS6: ::tcflag_t = 0x100; +pub const CS7: ::tcflag_t = 0x200; +pub const CS8: ::tcflag_t = 0x300; +pub const CSTOPB: ::tcflag_t = 0x400; +pub const CREAD: ::tcflag_t = 0x800; +pub const PARENB: ::tcflag_t = 0x1000; +pub const PARODD: ::tcflag_t = 0x2000; +pub const HUPCL: ::tcflag_t = 0x4000; +pub const CLOCAL: ::tcflag_t = 0x8000; +pub const ECHOKE: ::tcflag_t = 0x1; +pub const ECHOE: ::tcflag_t = 0x2; +pub const ECHOK: ::tcflag_t = 0x4; +pub const ECHONL: ::tcflag_t = 0x10; +pub const ECHOPRT: ::tcflag_t = 0x20; +pub const ECHOCTL: ::tcflag_t = 0x40; +pub const ISIG: ::tcflag_t = 0x80; +pub const ICANON: ::tcflag_t = 0x100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o001400; +pub const CRDLY: ::tcflag_t = 0o030000; +pub const TABDLY: ::tcflag_t = 0o006000; +pub const BSDLY: ::tcflag_t = 0o100000; +pub const FFDLY: ::tcflag_t = 0o040000; +pub const VTDLY: ::tcflag_t = 0o200000; +pub const XTABS: ::tcflag_t = 0o006000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const CBAUDEX: ::speed_t = 0o000020; +pub const B57600: ::speed_t = 0o0020; +pub const B115200: ::speed_t = 0o0021; +pub const B230400: ::speed_t = 0o0022; +pub const B460800: ::speed_t = 0o0023; +pub const B500000: ::speed_t = 0o0024; +pub const B576000: ::speed_t = 0o0025; +pub const B921600: ::speed_t = 0o0026; +pub const B1000000: ::speed_t = 0o0027; +pub const B1152000: ::speed_t = 0o0030; +pub const B1500000: ::speed_t = 0o0031; +pub const B2000000: ::speed_t = 0o0032; +pub const B2500000: ::speed_t = 0o0033; +pub const B3000000: ::speed_t = 0o0034; +pub const B3500000: ::speed_t = 0o0035; +pub const B4000000: ::speed_t = 0o0036; + +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: ::tcflag_t = 0x400; +pub const TOSTOP: ::tcflag_t = 0x400000; +pub const FLUSHO: ::tcflag_t = 0x800000; +pub const EXTPROC: ::tcflag_t = 0x10000000; + +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; /* some people actually want streams */ +pub const SYS_putpmsg: ::c_long = 188; /* some people actually want streams */ +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; /* SuS compliant getrlimit */ +pub const SYS_readahead: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_fcntl64: ::c_long = 204; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_sendfile64: ::c_long = 226; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_fadvise64: ::c_long = 233; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_fadvise64_64: ::c_long = 254; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_fstatat64: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +pub const SYS_preadv2: ::c_long = 380; +pub const SYS_pwritev2: ::c_long = 381; +pub const SYS_kexec_file_load: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_rseq: ::c_long = 387; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs new file mode 100644 index 00000000..48d152a5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs @@ -0,0 +1,44 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct ucontext_t { + pub __uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct mcontext_t { + pub __gregs: [::c_ulong; 32], + pub __fpregs: __riscv_mc_fp_state, + } + + #[allow(missing_debug_implementations)] + pub union __riscv_mc_fp_state { + pub __f: __riscv_mc_f_ext_state, + pub __d: __riscv_mc_d_ext_state, + pub __q: __riscv_mc_q_ext_state, + } + + #[allow(missing_debug_implementations)] + pub struct __riscv_mc_f_ext_state { + pub __f: [::c_uint; 32], + pub __fcsr: ::c_uint, + } + + #[allow(missing_debug_implementations)] + pub struct __riscv_mc_d_ext_state { + pub __f: [::c_ulonglong; 32], + pub __fcsr: ::c_uint, + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct __riscv_mc_q_ext_state { + pub __f: [::c_ulonglong; 64], + pub __fcsr: ::c_uint, + pub __glibc_reserved: [::c_uint; 3], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs new file mode 100644 index 00000000..65b7aaa7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs @@ -0,0 +1,813 @@ +//! RISC-V-specific definitions for 32-bit linux-like values + +pub type c_char = u8; +pub type wchar_t = ::c_int; + +s! { + pub struct pthread_attr_t { + __size: [::c_ulong; 7], + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2usize], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_favail: ::fsfilcnt64_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [u64; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused5: ::c_ulong, + __unused6: ::c_ulong, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct user_regs_struct { + pub pc: ::c_ulong, + pub ra: ::c_ulong, + pub sp: ::c_ulong, + pub gp: ::c_ulong, + pub tp: ::c_ulong, + pub t0: ::c_ulong, + pub t1: ::c_ulong, + pub t2: ::c_ulong, + pub s0: ::c_ulong, + pub s1: ::c_ulong, + pub a0: ::c_ulong, + pub a1: ::c_ulong, + pub a2: ::c_ulong, + pub a3: ::c_ulong, + pub a4: ::c_ulong, + pub a5: ::c_ulong, + pub a6: ::c_ulong, + pub a7: ::c_ulong, + pub s2: ::c_ulong, + pub s3: ::c_ulong, + pub s4: ::c_ulong, + pub s5: ::c_ulong, + pub s6: ::c_ulong, + pub s7: ::c_ulong, + pub s8: ::c_ulong, + pub s9: ::c_ulong, + pub s10: ::c_ulong, + pub s11: ::c_ulong, + pub t3: ::c_ulong, + pub t4: ::c_ulong, + pub t5: ::c_ulong, + pub t6: ::c_ulong, + } +} + +pub const O_LARGEFILE: ::c_int = 0; +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 1052672; +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 256; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SA_SIGINFO: ::c_int = 4; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const POLLWRNORM: ::c_short = 256; +pub const POLLWRBAND: ::c_short = 512; +pub const O_ASYNC: ::c_int = 8192; +pub const O_NDELAY: ::c_int = 2048; +pub const EFD_NONBLOCK: ::c_int = 2048; +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const SFD_NONBLOCK: ::c_int = 2048; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const O_DIRECT: ::c_int = 16384; +pub const O_DIRECTORY: ::c_int = 65536; +pub const O_NOFOLLOW: ::c_int = 131072; +pub const MAP_HUGETLB: ::c_int = 262144; +pub const MAP_LOCKED: ::c_int = 8192; +pub const MAP_NORESERVE: ::c_int = 16384; +pub const MAP_ANON: ::c_int = 32; +pub const MAP_ANONYMOUS: ::c_int = 32; +pub const MAP_DENYWRITE: ::c_int = 2048; +pub const MAP_EXECUTABLE: ::c_int = 4096; +pub const MAP_POPULATE: ::c_int = 32768; +pub const MAP_NONBLOCK: ::c_int = 65536; +pub const MAP_STACK: ::c_int = 131072; +pub const MAP_SYNC: ::c_int = 0x080000; +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const MCL_CURRENT: ::c_int = 1; +pub const MCL_FUTURE: ::c_int = 2; +pub const MCL_ONFAULT: ::c_int = 4; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 4111; +pub const TAB1: ::tcflag_t = 2048; +pub const TAB2: ::tcflag_t = 4096; +pub const TAB3: ::tcflag_t = 6144; +pub const CR1: ::tcflag_t = 512; +pub const CR2: ::tcflag_t = 1024; +pub const CR3: ::tcflag_t = 1536; +pub const FF1: ::tcflag_t = 32768; +pub const BS1: ::tcflag_t = 8192; +pub const VT1: ::tcflag_t = 16384; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 1024; +pub const IXOFF: ::tcflag_t = 4096; +pub const ONLCR: ::tcflag_t = 4; +pub const CSIZE: ::tcflag_t = 48; +pub const CS6: ::tcflag_t = 16; +pub const CS7: ::tcflag_t = 32; +pub const CS8: ::tcflag_t = 48; +pub const CSTOPB: ::tcflag_t = 64; +pub const CREAD: ::tcflag_t = 128; +pub const PARENB: ::tcflag_t = 256; +pub const PARODD: ::tcflag_t = 512; +pub const HUPCL: ::tcflag_t = 1024; +pub const CLOCAL: ::tcflag_t = 2048; +pub const ECHOKE: ::tcflag_t = 2048; +pub const ECHOE: ::tcflag_t = 16; +pub const ECHOK: ::tcflag_t = 32; +pub const ECHONL: ::tcflag_t = 64; +pub const ECHOPRT: ::tcflag_t = 1024; +pub const ECHOCTL: ::tcflag_t = 512; +pub const ISIG: ::tcflag_t = 1; +pub const ICANON: ::tcflag_t = 2; +pub const PENDIN: ::tcflag_t = 16384; +pub const NOFLSH: ::tcflag_t = 128; +pub const CIBAUD: ::tcflag_t = 269418496; +pub const CBAUDEX: ::tcflag_t = 4096; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 2; +pub const NLDLY: ::tcflag_t = 256; +pub const CRDLY: ::tcflag_t = 1536; +pub const TABDLY: ::tcflag_t = 6144; +pub const BSDLY: ::tcflag_t = 8192; +pub const FFDLY: ::tcflag_t = 32768; +pub const VTDLY: ::tcflag_t = 16384; +pub const XTABS: ::tcflag_t = 6144; +pub const B0: ::speed_t = 0; +pub const B50: ::speed_t = 1; +pub const B75: ::speed_t = 2; +pub const B110: ::speed_t = 3; +pub const B134: ::speed_t = 4; +pub const B150: ::speed_t = 5; +pub const B200: ::speed_t = 6; +pub const B300: ::speed_t = 7; +pub const B600: ::speed_t = 8; +pub const B1200: ::speed_t = 9; +pub const B1800: ::speed_t = 10; +pub const B2400: ::speed_t = 11; +pub const B4800: ::speed_t = 12; +pub const B9600: ::speed_t = 13; +pub const B19200: ::speed_t = 14; +pub const B38400: ::speed_t = 15; +pub const EXTA: ::speed_t = 14; +pub const EXTB: ::speed_t = 15; +pub const B57600: ::speed_t = 4097; +pub const B115200: ::speed_t = 4098; +pub const B230400: ::speed_t = 4099; +pub const B460800: ::speed_t = 4100; +pub const B500000: ::speed_t = 4101; +pub const B576000: ::speed_t = 4102; +pub const B921600: ::speed_t = 4103; +pub const B1000000: ::speed_t = 4104; +pub const B1152000: ::speed_t = 4105; +pub const B1500000: ::speed_t = 4106; +pub const B2000000: ::speed_t = 4107; +pub const B2500000: ::speed_t = 4108; +pub const B3000000: ::speed_t = 4109; +pub const B3500000: ::speed_t = 4110; +pub const B4000000: ::speed_t = 4111; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 32768; +pub const TOSTOP: ::tcflag_t = 256; +pub const FLUSHO: ::tcflag_t = 4096; +pub const EXTPROC: ::tcflag_t = 65536; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; +pub const NGREG: usize = 32; +pub const REG_PC: usize = 0; +pub const REG_RA: usize = 1; +pub const REG_SP: usize = 2; +pub const REG_TP: usize = 4; +pub const REG_S0: usize = 8; +pub const REG_S1: usize = 9; +pub const REG_A0: usize = 10; +pub const REG_S2: usize = 18; +pub const REG_NARGS: usize = 8; + +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_close: ::c_long = 57; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_brk: ::c_long = 214; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_dup: ::c_long = 23; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_sendfile: ::c_long = 71; +pub const SYS_socket: ::c_long = 198; +pub const SYS_connect: ::c_long = 203; +pub const SYS_accept: ::c_long = 202; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_exit: ::c_long = 93; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_kill: ::c_long = 129; +pub const SYS_uname: ::c_long = 160; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semop: ::c_long = 193; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_flock: ::c_long = 32; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_umask: ::c_long = 166; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_times: ::c_long = 153; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_personality: ::c_long = 92; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_sync: ::c_long = 81; +pub const SYS_acct: ::c_long = 89; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_mount: ::c_long = 40; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_futex: ::c_long = 98; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_fadvise64: ::c_long = 223; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_openat: ::c_long = 56; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_setns: ::c_long = 268; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_rseq: ::c_long = 293; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs new file mode 100644 index 00000000..98fda883 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 3] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs new file mode 100644 index 00000000..da9cf29c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs @@ -0,0 +1,857 @@ +//! SPARC-specific definitions for 32-bit linux-like values + +pub type c_char = i8; +pub type wchar_t = i32; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + __reserved: ::c_short, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_ushort, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_ushort, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 2], + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + __pad1: ::c_ushort, + pub mode: ::c_ushort, + __pad2: ::c_ushort, + pub __seq: ::c_ushort, + __unused1: ::c_ulonglong, + __unused2: ::c_ulonglong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + __pad1: ::c_uint, + pub shm_atime: ::time_t, + __pad2: ::c_uint, + pub shm_dtime: ::time_t, + __pad3: ::c_uint, + pub shm_ctime: ::time_t, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __reserved1: ::c_ulong, + __reserved2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __pad1: ::c_uint, + pub msg_stime: ::time_t, + __pad2: ::c_uint, + pub msg_rtime: ::time_t, + __pad3: ::c_uint, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ushort, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved1: ::c_ulong, + __glibc_reserved2: ::c_ulong, + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const O_APPEND: ::c_int = 0x8; +pub const O_CREAT: ::c_int = 0x200; +pub const O_EXCL: ::c_int = 0x800; +pub const O_NOCTTY: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x4000; +pub const O_SYNC: ::c_int = 0x802000; +pub const O_RSYNC: ::c_int = 0x802000; +pub const O_DSYNC: ::c_int = 0x2000; +pub const O_FSYNC: ::c_int = 0x802000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0200; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLK: ::c_int = 78; +pub const ENAMETOOLONG: ::c_int = 63; +pub const ENOLCK: ::c_int = 79; +pub const ENOSYS: ::c_int = 90; +pub const ENOTEMPTY: ::c_int = 66; +pub const ELOOP: ::c_int = 62; +pub const ENOMSG: ::c_int = 75; +pub const EIDRM: ::c_int = 77; +pub const ECHRNG: ::c_int = 94; +pub const EL2NSYNC: ::c_int = 95; +pub const EL3HLT: ::c_int = 96; +pub const EL3RST: ::c_int = 97; +pub const ELNRNG: ::c_int = 98; +pub const EUNATCH: ::c_int = 99; +pub const ENOCSI: ::c_int = 100; +pub const EL2HLT: ::c_int = 101; +pub const EBADE: ::c_int = 102; +pub const EBADR: ::c_int = 103; +pub const EXFULL: ::c_int = 104; +pub const ENOANO: ::c_int = 105; +pub const EBADRQC: ::c_int = 106; +pub const EBADSLT: ::c_int = 107; +pub const EMULTIHOP: ::c_int = 87; +pub const EOVERFLOW: ::c_int = 92; +pub const ENOTUNIQ: ::c_int = 115; +pub const EBADFD: ::c_int = 93; +pub const EBADMSG: ::c_int = 76; +pub const EREMCHG: ::c_int = 89; +pub const ELIBACC: ::c_int = 114; +pub const ELIBBAD: ::c_int = 112; +pub const ELIBSCN: ::c_int = 124; +pub const ELIBMAX: ::c_int = 123; +pub const ELIBEXEC: ::c_int = 110; +pub const EILSEQ: ::c_int = 122; +pub const ERESTART: ::c_int = 116; +pub const ESTRPIPE: ::c_int = 91; +pub const EUSERS: ::c_int = 68; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +pub const ESHUTDOWN: ::c_int = 58; +pub const ETOOMANYREFS: ::c_int = 59; +pub const ETIMEDOUT: ::c_int = 60; +pub const ECONNREFUSED: ::c_int = 61; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const EALREADY: ::c_int = 37; +pub const EINPROGRESS: ::c_int = 36; +pub const ESTALE: ::c_int = 70; +pub const EDQUOT: ::c_int = 69; +pub const ENOMEDIUM: ::c_int = 125; +pub const EMEDIUMTYPE: ::c_int = 126; +pub const ECANCELED: ::c_int = 127; +pub const ENOKEY: ::c_int = 128; +pub const EKEYEXPIRED: ::c_int = 129; +pub const EKEYREVOKED: ::c_int = 130; +pub const EKEYREJECTED: ::c_int = 131; +pub const EOWNERDEAD: ::c_int = 132; +pub const ENOTRECOVERABLE: ::c_int = 133; +pub const EHWPOISON: ::c_int = 135; +pub const ERFKILL: ::c_int = 134; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_SIGINFO: ::c_int = 0x200; +pub const SA_NOCLDWAIT: ::c_int = 0x100; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGCONT: ::c_int = 19; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGURG: ::c_int = 16; +pub const SIGIO: ::c_int = 23; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 23; +pub const SIGPWR: ::c_int = 29; +pub const SIG_SETMASK: ::c_int = 4; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; + +pub const POLLWRNORM: ::c_short = 4; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const O_ASYNC: ::c_int = 0x40; +pub const O_NDELAY: ::c_int = 0x4004; + +pub const EFD_NONBLOCK: ::c_int = 0x4000; + +pub const F_GETLK: ::c_int = 7; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; + +pub const SFD_NONBLOCK: ::c_int = 0x4000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const O_DIRECTORY: ::c_int = 0o200000; +pub const O_NOFOLLOW: ::c_int = 0o400000; +pub const O_LARGEFILE: ::c_int = 0x40000; +pub const O_DIRECT: ::c_int = 0x100000; + +pub const MAP_LOCKED: ::c_int = 0x0100; +pub const MAP_NORESERVE: ::c_int = 0x00040; + +pub const EDEADLOCK: ::c_int = 108; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0x0000100f; +pub const TAB1: ::tcflag_t = 0x800; +pub const TAB2: ::tcflag_t = 0x1000; +pub const TAB3: ::tcflag_t = 0x1800; +pub const CR1: ::tcflag_t = 0x200; +pub const CR2: ::tcflag_t = 0x400; +pub const CR3: ::tcflag_t = 0x600; +pub const FF1: ::tcflag_t = 0x8000; +pub const BS1: ::tcflag_t = 0x2000; +pub const VT1: ::tcflag_t = 0x4000; +pub const VWERASE: usize = 0xe; +pub const VREPRINT: usize = 0xc; +pub const VSUSP: usize = 0xa; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VDISCARD: usize = 0xd; +pub const VTIME: usize = 0x5; +pub const IXON: ::tcflag_t = 0x400; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const CREAD: ::tcflag_t = 0x80; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const HUPCL: ::tcflag_t = 0x400; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ISIG: ::tcflag_t = 0x1; +pub const ICANON: ::tcflag_t = 0x2; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0x00001000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0x1001; +pub const B115200: ::speed_t = 0x1002; +pub const B230400: ::speed_t = 0x1003; +pub const B460800: ::speed_t = 0x1004; +pub const B76800: ::speed_t = 0x1005; +pub const B153600: ::speed_t = 0x1006; +pub const B307200: ::speed_t = 0x1007; +pub const B614400: ::speed_t = 0x1008; +pub const B921600: ::speed_t = 0x1009; +pub const B500000: ::speed_t = 0x100a; +pub const B576000: ::speed_t = 0x100b; +pub const B1000000: ::speed_t = 0x100c; +pub const B1152000: ::speed_t = 0x100d; +pub const B1500000: ::speed_t = 0x100e; +pub const B2000000: ::speed_t = 0x100f; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x8000; +pub const TOSTOP: ::tcflag_t = 0x100; +pub const FLUSHO: ::tcflag_t = 0x1000; +pub const EXTPROC: ::tcflag_t = 0x10000; + +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_wait4: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execv: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_chown: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_brk: ::c_long = 17; +pub const SYS_perfctr: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_capget: ::c_long = 21; +pub const SYS_capset: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_vmsplice: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_sigaltstack: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_lchown32: ::c_long = 31; +pub const SYS_fchown32: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_chown32: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_stat: ::c_long = 38; +pub const SYS_sendfile: ::c_long = 39; +pub const SYS_lstat: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_getuid32: ::c_long = 44; +pub const SYS_umount2: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_getgid32: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_reboot: ::c_long = 55; +pub const SYS_mmap2: ::c_long = 56; +pub const SYS_symlink: ::c_long = 57; +pub const SYS_readlink: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_fstat: ::c_long = 62; +pub const SYS_fstat64: ::c_long = 63; +pub const SYS_getpagesize: ::c_long = 64; +pub const SYS_msync: ::c_long = 65; +pub const SYS_vfork: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_geteuid32: ::c_long = 69; +pub const SYS_getegid32: ::c_long = 70; +pub const SYS_mmap: ::c_long = 71; +pub const SYS_setreuid32: ::c_long = 72; +pub const SYS_munmap: ::c_long = 73; +pub const SYS_mprotect: ::c_long = 74; +pub const SYS_madvise: ::c_long = 75; +pub const SYS_vhangup: ::c_long = 76; +pub const SYS_truncate64: ::c_long = 77; +pub const SYS_mincore: ::c_long = 78; +pub const SYS_getgroups: ::c_long = 79; +pub const SYS_setgroups: ::c_long = 80; +pub const SYS_getpgrp: ::c_long = 81; +pub const SYS_setgroups32: ::c_long = 82; +pub const SYS_setitimer: ::c_long = 83; +pub const SYS_ftruncate64: ::c_long = 84; +pub const SYS_swapon: ::c_long = 85; +pub const SYS_getitimer: ::c_long = 86; +pub const SYS_setuid32: ::c_long = 87; +pub const SYS_sethostname: ::c_long = 88; +pub const SYS_setgid32: ::c_long = 89; +pub const SYS_dup2: ::c_long = 90; +pub const SYS_setfsuid32: ::c_long = 91; +pub const SYS_fcntl: ::c_long = 92; +pub const SYS_select: ::c_long = 93; +pub const SYS_setfsgid32: ::c_long = 94; +pub const SYS_fsync: ::c_long = 95; +pub const SYS_setpriority: ::c_long = 96; +pub const SYS_socket: ::c_long = 97; +pub const SYS_connect: ::c_long = 98; +pub const SYS_accept: ::c_long = 99; +pub const SYS_getpriority: ::c_long = 100; +pub const SYS_rt_sigreturn: ::c_long = 101; +pub const SYS_rt_sigaction: ::c_long = 102; +pub const SYS_rt_sigprocmask: ::c_long = 103; +pub const SYS_rt_sigpending: ::c_long = 104; +pub const SYS_rt_sigtimedwait: ::c_long = 105; +pub const SYS_rt_sigqueueinfo: ::c_long = 106; +pub const SYS_rt_sigsuspend: ::c_long = 107; +pub const SYS_setresuid32: ::c_long = 108; +pub const SYS_getresuid32: ::c_long = 109; +pub const SYS_setresgid32: ::c_long = 110; +pub const SYS_getresgid32: ::c_long = 111; +pub const SYS_setregid32: ::c_long = 112; +pub const SYS_recvmsg: ::c_long = 113; +pub const SYS_sendmsg: ::c_long = 114; +pub const SYS_getgroups32: ::c_long = 115; +pub const SYS_gettimeofday: ::c_long = 116; +pub const SYS_getrusage: ::c_long = 117; +pub const SYS_getsockopt: ::c_long = 118; +pub const SYS_getcwd: ::c_long = 119; +pub const SYS_readv: ::c_long = 120; +pub const SYS_writev: ::c_long = 121; +pub const SYS_settimeofday: ::c_long = 122; +pub const SYS_fchown: ::c_long = 123; +pub const SYS_fchmod: ::c_long = 124; +pub const SYS_recvfrom: ::c_long = 125; +pub const SYS_setreuid: ::c_long = 126; +pub const SYS_setregid: ::c_long = 127; +pub const SYS_rename: ::c_long = 128; +pub const SYS_truncate: ::c_long = 129; +pub const SYS_ftruncate: ::c_long = 130; +pub const SYS_flock: ::c_long = 131; +pub const SYS_lstat64: ::c_long = 132; +pub const SYS_sendto: ::c_long = 133; +pub const SYS_shutdown: ::c_long = 134; +pub const SYS_socketpair: ::c_long = 135; +pub const SYS_mkdir: ::c_long = 136; +pub const SYS_rmdir: ::c_long = 137; +pub const SYS_utimes: ::c_long = 138; +pub const SYS_stat64: ::c_long = 139; +pub const SYS_sendfile64: ::c_long = 140; +pub const SYS_getpeername: ::c_long = 141; +pub const SYS_futex: ::c_long = 142; +pub const SYS_gettid: ::c_long = 143; +pub const SYS_getrlimit: ::c_long = 144; +pub const SYS_setrlimit: ::c_long = 145; +pub const SYS_pivot_root: ::c_long = 146; +pub const SYS_prctl: ::c_long = 147; +pub const SYS_pciconfig_read: ::c_long = 148; +pub const SYS_pciconfig_write: ::c_long = 149; +pub const SYS_getsockname: ::c_long = 150; +pub const SYS_inotify_init: ::c_long = 151; +pub const SYS_inotify_add_watch: ::c_long = 152; +pub const SYS_poll: ::c_long = 153; +pub const SYS_getdents64: ::c_long = 154; +pub const SYS_fcntl64: ::c_long = 155; +pub const SYS_inotify_rm_watch: ::c_long = 156; +pub const SYS_statfs: ::c_long = 157; +pub const SYS_fstatfs: ::c_long = 158; +pub const SYS_umount: ::c_long = 159; +pub const SYS_sched_set_affinity: ::c_long = 160; +pub const SYS_sched_get_affinity: ::c_long = 161; +pub const SYS_getdomainname: ::c_long = 162; +pub const SYS_setdomainname: ::c_long = 163; +pub const SYS_quotactl: ::c_long = 165; +pub const SYS_set_tid_address: ::c_long = 166; +pub const SYS_mount: ::c_long = 167; +pub const SYS_ustat: ::c_long = 168; +pub const SYS_setxattr: ::c_long = 169; +pub const SYS_lsetxattr: ::c_long = 170; +pub const SYS_fsetxattr: ::c_long = 171; +pub const SYS_getxattr: ::c_long = 172; +pub const SYS_lgetxattr: ::c_long = 173; +pub const SYS_getdents: ::c_long = 174; +pub const SYS_setsid: ::c_long = 175; +pub const SYS_fchdir: ::c_long = 176; +pub const SYS_fgetxattr: ::c_long = 177; +pub const SYS_listxattr: ::c_long = 178; +pub const SYS_llistxattr: ::c_long = 179; +pub const SYS_flistxattr: ::c_long = 180; +pub const SYS_removexattr: ::c_long = 181; +pub const SYS_lremovexattr: ::c_long = 182; +pub const SYS_sigpending: ::c_long = 183; +pub const SYS_query_module: ::c_long = 184; +pub const SYS_setpgid: ::c_long = 185; +pub const SYS_fremovexattr: ::c_long = 186; +pub const SYS_tkill: ::c_long = 187; +pub const SYS_exit_group: ::c_long = 188; +pub const SYS_uname: ::c_long = 189; +pub const SYS_init_module: ::c_long = 190; +pub const SYS_personality: ::c_long = 191; +pub const SYS_remap_file_pages: ::c_long = 192; +pub const SYS_epoll_create: ::c_long = 193; +pub const SYS_epoll_ctl: ::c_long = 194; +pub const SYS_epoll_wait: ::c_long = 195; +pub const SYS_ioprio_set: ::c_long = 196; +pub const SYS_getppid: ::c_long = 197; +pub const SYS_sigaction: ::c_long = 198; +pub const SYS_sgetmask: ::c_long = 199; +pub const SYS_ssetmask: ::c_long = 200; +pub const SYS_sigsuspend: ::c_long = 201; +pub const SYS_oldlstat: ::c_long = 202; +pub const SYS_uselib: ::c_long = 203; +pub const SYS_readdir: ::c_long = 204; +pub const SYS_readahead: ::c_long = 205; +pub const SYS_socketcall: ::c_long = 206; +pub const SYS_syslog: ::c_long = 207; +pub const SYS_lookup_dcookie: ::c_long = 208; +pub const SYS_fadvise64: ::c_long = 209; +pub const SYS_fadvise64_64: ::c_long = 210; +pub const SYS_tgkill: ::c_long = 211; +pub const SYS_waitpid: ::c_long = 212; +pub const SYS_swapoff: ::c_long = 213; +pub const SYS_sysinfo: ::c_long = 214; +pub const SYS_ipc: ::c_long = 215; +pub const SYS_sigreturn: ::c_long = 216; +pub const SYS_clone: ::c_long = 217; +pub const SYS_ioprio_get: ::c_long = 218; +pub const SYS_adjtimex: ::c_long = 219; +pub const SYS_sigprocmask: ::c_long = 220; +pub const SYS_create_module: ::c_long = 221; +pub const SYS_delete_module: ::c_long = 222; +pub const SYS_get_kernel_syms: ::c_long = 223; +pub const SYS_getpgid: ::c_long = 224; +pub const SYS_bdflush: ::c_long = 225; +pub const SYS_sysfs: ::c_long = 226; +pub const SYS_afs_syscall: ::c_long = 227; +pub const SYS_setfsuid: ::c_long = 228; +pub const SYS_setfsgid: ::c_long = 229; +pub const SYS__newselect: ::c_long = 230; +pub const SYS_time: ::c_long = 231; +pub const SYS_splice: ::c_long = 232; +pub const SYS_stime: ::c_long = 233; +pub const SYS_statfs64: ::c_long = 234; +pub const SYS_fstatfs64: ::c_long = 235; +pub const SYS__llseek: ::c_long = 236; +pub const SYS_mlock: ::c_long = 237; +pub const SYS_munlock: ::c_long = 238; +pub const SYS_mlockall: ::c_long = 239; +pub const SYS_munlockall: ::c_long = 240; +pub const SYS_sched_setparam: ::c_long = 241; +pub const SYS_sched_getparam: ::c_long = 242; +pub const SYS_sched_setscheduler: ::c_long = 243; +pub const SYS_sched_getscheduler: ::c_long = 244; +pub const SYS_sched_yield: ::c_long = 245; +pub const SYS_sched_get_priority_max: ::c_long = 246; +pub const SYS_sched_get_priority_min: ::c_long = 247; +pub const SYS_sched_rr_get_interval: ::c_long = 248; +pub const SYS_nanosleep: ::c_long = 249; +pub const SYS_mremap: ::c_long = 250; +pub const SYS__sysctl: ::c_long = 251; +pub const SYS_getsid: ::c_long = 252; +pub const SYS_fdatasync: ::c_long = 253; +pub const SYS_nfsservctl: ::c_long = 254; +pub const SYS_sync_file_range: ::c_long = 255; +pub const SYS_clock_settime: ::c_long = 256; +pub const SYS_clock_gettime: ::c_long = 257; +pub const SYS_clock_getres: ::c_long = 258; +pub const SYS_clock_nanosleep: ::c_long = 259; +pub const SYS_sched_getaffinity: ::c_long = 260; +pub const SYS_sched_setaffinity: ::c_long = 261; +pub const SYS_timer_settime: ::c_long = 262; +pub const SYS_timer_gettime: ::c_long = 263; +pub const SYS_timer_getoverrun: ::c_long = 264; +pub const SYS_timer_delete: ::c_long = 265; +pub const SYS_timer_create: ::c_long = 266; +pub const SYS_io_setup: ::c_long = 268; +pub const SYS_io_destroy: ::c_long = 269; +pub const SYS_io_submit: ::c_long = 270; +pub const SYS_io_cancel: ::c_long = 271; +pub const SYS_io_getevents: ::c_long = 272; +pub const SYS_mq_open: ::c_long = 273; +pub const SYS_mq_unlink: ::c_long = 274; +pub const SYS_mq_timedsend: ::c_long = 275; +pub const SYS_mq_timedreceive: ::c_long = 276; +pub const SYS_mq_notify: ::c_long = 277; +pub const SYS_mq_getsetattr: ::c_long = 278; +pub const SYS_waitid: ::c_long = 279; +pub const SYS_tee: ::c_long = 280; +pub const SYS_add_key: ::c_long = 281; +pub const SYS_request_key: ::c_long = 282; +pub const SYS_keyctl: ::c_long = 283; +pub const SYS_openat: ::c_long = 284; +pub const SYS_mkdirat: ::c_long = 285; +pub const SYS_mknodat: ::c_long = 286; +pub const SYS_fchownat: ::c_long = 287; +pub const SYS_futimesat: ::c_long = 288; +pub const SYS_fstatat64: ::c_long = 289; +pub const SYS_unlinkat: ::c_long = 290; +pub const SYS_renameat: ::c_long = 291; +pub const SYS_linkat: ::c_long = 292; +pub const SYS_symlinkat: ::c_long = 293; +pub const SYS_readlinkat: ::c_long = 294; +pub const SYS_fchmodat: ::c_long = 295; +pub const SYS_faccessat: ::c_long = 296; +pub const SYS_pselect6: ::c_long = 297; +pub const SYS_ppoll: ::c_long = 298; +pub const SYS_unshare: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_get_robust_list: ::c_long = 301; +pub const SYS_migrate_pages: ::c_long = 302; +pub const SYS_mbind: ::c_long = 303; +pub const SYS_get_mempolicy: ::c_long = 304; +pub const SYS_set_mempolicy: ::c_long = 305; +pub const SYS_kexec_load: ::c_long = 306; +pub const SYS_move_pages: ::c_long = 307; +pub const SYS_getcpu: ::c_long = 308; +pub const SYS_epoll_pwait: ::c_long = 309; +pub const SYS_utimensat: ::c_long = 310; +pub const SYS_signalfd: ::c_long = 311; +pub const SYS_timerfd_create: ::c_long = 312; +pub const SYS_eventfd: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_timerfd_settime: ::c_long = 315; +pub const SYS_timerfd_gettime: ::c_long = 316; +pub const SYS_signalfd4: ::c_long = 317; +pub const SYS_eventfd2: ::c_long = 318; +pub const SYS_epoll_create1: ::c_long = 319; +pub const SYS_dup3: ::c_long = 320; +pub const SYS_pipe2: ::c_long = 321; +pub const SYS_inotify_init1: ::c_long = 322; +pub const SYS_accept4: ::c_long = 323; +pub const SYS_preadv: ::c_long = 324; +pub const SYS_pwritev: ::c_long = 325; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 326; +pub const SYS_perf_event_open: ::c_long = 327; +pub const SYS_recvmmsg: ::c_long = 328; +pub const SYS_fanotify_init: ::c_long = 329; +pub const SYS_fanotify_mark: ::c_long = 330; +pub const SYS_prlimit64: ::c_long = 331; +pub const SYS_name_to_handle_at: ::c_long = 332; +pub const SYS_open_by_handle_at: ::c_long = 333; +pub const SYS_clock_adjtime: ::c_long = 334; +pub const SYS_syncfs: ::c_long = 335; +pub const SYS_sendmmsg: ::c_long = 336; +pub const SYS_setns: ::c_long = 337; +pub const SYS_process_vm_readv: ::c_long = 338; +pub const SYS_process_vm_writev: ::c_long = 339; +pub const SYS_kern_features: ::c_long = 340; +pub const SYS_kcmp: ::c_long = 341; +pub const SYS_finit_module: ::c_long = 342; +pub const SYS_sched_setattr: ::c_long = 343; +pub const SYS_sched_getattr: ::c_long = 344; +pub const SYS_renameat2: ::c_long = 345; +pub const SYS_seccomp: ::c_long = 346; +pub const SYS_getrandom: ::c_long = 347; +pub const SYS_memfd_create: ::c_long = 348; +pub const SYS_bpf: ::c_long = 349; +pub const SYS_execveat: ::c_long = 350; +pub const SYS_membarrier: ::c_long = 351; +pub const SYS_userfaultfd: ::c_long = 352; +pub const SYS_bind: ::c_long = 353; +pub const SYS_listen: ::c_long = 354; +pub const SYS_setsockopt: ::c_long = 355; +pub const SYS_mlock2: ::c_long = 356; +pub const SYS_copy_file_range: ::c_long = 357; +pub const SYS_preadv2: ::c_long = 358; +pub const SYS_pwritev2: ::c_long = 359; +pub const SYS_statx: ::c_long = 360; +pub const SYS_rseq: ::c_long = 365; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +// Reserved in the kernel, but not actually implemented yet +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs new file mode 100644 index 00000000..96634749 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 6] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs new file mode 100644 index 00000000..27f477bb --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs @@ -0,0 +1,1100 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type greg_t = i32; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct _libc_fpreg { + pub significand: [u16; 4], + pub exponent: u16, + } + + pub struct _libc_fpstate { + pub cw: ::c_ulong, + pub sw: ::c_ulong, + pub tag: ::c_ulong, + pub ipoff: ::c_ulong, + pub cssel: ::c_ulong, + pub dataoff: ::c_ulong, + pub datasel: ::c_ulong, + pub _st: [_libc_fpreg; 8], + pub status: ::c_ulong, + } + + pub struct user_fpregs_struct { + pub cwd: ::c_long, + pub swd: ::c_long, + pub twd: ::c_long, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub st_space: [::c_long; 20], + } + + pub struct user_regs_struct { + pub ebx: ::c_long, + pub ecx: ::c_long, + pub edx: ::c_long, + pub esi: ::c_long, + pub edi: ::c_long, + pub ebp: ::c_long, + pub eax: ::c_long, + pub xds: ::c_long, + pub xes: ::c_long, + pub xfs: ::c_long, + pub xgs: ::c_long, + pub orig_eax: ::c_long, + pub eip: ::c_long, + pub xcs: ::c_long, + pub eflags: ::c_long, + pub esp: ::c_long, + pub xss: ::c_long, + } + + pub struct user { + pub regs: user_regs_struct, + pub u_fpvalid: ::c_int, + pub i387: user_fpregs_struct, + pub u_tsize: ::c_ulong, + pub u_dsize: ::c_ulong, + pub u_ssize: ::c_ulong, + pub start_code: ::c_ulong, + pub start_stack: ::c_ulong, + pub signal: ::c_long, + __reserved: ::c_int, + pub u_ar0: *mut user_regs_struct, + pub u_fpstate: *mut user_fpregs_struct, + pub magic: ::c_ulong, + pub u_comm: [c_char; 32], + pub u_debugreg: [::c_int; 8], + } + + pub struct mcontext_t { + pub gregs: [greg_t; 19], + pub fpregs: *mut _libc_fpstate, + pub oldmask: ::c_ulong, + pub cr2: ::c_ulong, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_uint, + __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_uint, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino64_t, + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_ulong, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_ulong, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + +} + +s_no_extra_traits! { + pub struct user_fpxregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub twd: ::c_ushort, + pub fop: ::c_ushort, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub mxcsr: ::c_long, + __reserved: ::c_long, + pub st_space: [::c_long; 32], + pub xmm_space: [::c_long; 32], + padding: [::c_long; 56], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 112], + __ssp: [::c_ulong; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpxregs_struct { + fn eq(&self, other: &user_fpxregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.twd == other.twd + && self.fop == other.fop + && self.fip == other.fip + && self.fcs == other.fcs + && self.foo == other.foo + && self.fos == other.fos + && self.mxcsr == other.mxcsr + // Ignore __reserved field + && self.st_space == other.st_space + && self.xmm_space == other.xmm_space + // Ignore padding field + } + } + + impl Eq for user_fpxregs_struct {} + + impl ::fmt::Debug for user_fpxregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpxregs_struct") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("twd", &self.twd) + .field("fop", &self.fop) + .field("fip", &self.fip) + .field("fcs", &self.fcs) + .field("foo", &self.foo) + .field("fos", &self.fos) + .field("mxcsr", &self.mxcsr) + // Ignore __reserved field + .field("st_space", &self.st_space) + .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpxregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.twd.hash(state); + self.fop.hash(state); + self.fip.hash(state); + self.fcs.hash(state); + self.foo.hash(state); + self.fos.hash(state); + self.mxcsr.hash(state); + // Ignore __reserved field + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + // Ignore __private field + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + // Ignore __private field + } + } + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o0100000; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_32BIT: ::c_int = 0x0040; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_SYSEMU: ::c_uint = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86old: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_vm86: ::c_long = 166; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_set_thread_area: ::c_long = 243; +pub const SYS_get_thread_area: ::c_long = 244; +pub const SYS_io_setup: ::c_long = 245; +pub const SYS_io_destroy: ::c_long = 246; +pub const SYS_io_getevents: ::c_long = 247; +pub const SYS_io_submit: ::c_long = 248; +pub const SYS_io_cancel: ::c_long = 249; +pub const SYS_fadvise64: ::c_long = 250; +pub const SYS_exit_group: ::c_long = 252; +pub const SYS_lookup_dcookie: ::c_long = 253; +pub const SYS_epoll_create: ::c_long = 254; +pub const SYS_epoll_ctl: ::c_long = 255; +pub const SYS_epoll_wait: ::c_long = 256; +pub const SYS_remap_file_pages: ::c_long = 257; +pub const SYS_set_tid_address: ::c_long = 258; +pub const SYS_timer_create: ::c_long = 259; +pub const SYS_timer_settime: ::c_long = 260; +pub const SYS_timer_gettime: ::c_long = 261; +pub const SYS_timer_getoverrun: ::c_long = 262; +pub const SYS_timer_delete: ::c_long = 263; +pub const SYS_clock_settime: ::c_long = 264; +pub const SYS_clock_gettime: ::c_long = 265; +pub const SYS_clock_getres: ::c_long = 266; +pub const SYS_clock_nanosleep: ::c_long = 267; +pub const SYS_statfs64: ::c_long = 268; +pub const SYS_fstatfs64: ::c_long = 269; +pub const SYS_tgkill: ::c_long = 270; +pub const SYS_utimes: ::c_long = 271; +pub const SYS_fadvise64_64: ::c_long = 272; +pub const SYS_vserver: ::c_long = 273; +pub const SYS_mbind: ::c_long = 274; +pub const SYS_get_mempolicy: ::c_long = 275; +pub const SYS_set_mempolicy: ::c_long = 276; +pub const SYS_mq_open: ::c_long = 277; +pub const SYS_mq_unlink: ::c_long = 278; +pub const SYS_mq_timedsend: ::c_long = 279; +pub const SYS_mq_timedreceive: ::c_long = 280; +pub const SYS_mq_notify: ::c_long = 281; +pub const SYS_mq_getsetattr: ::c_long = 282; +pub const SYS_kexec_load: ::c_long = 283; +pub const SYS_waitid: ::c_long = 284; +pub const SYS_add_key: ::c_long = 286; +pub const SYS_request_key: ::c_long = 287; +pub const SYS_keyctl: ::c_long = 288; +pub const SYS_ioprio_set: ::c_long = 289; +pub const SYS_ioprio_get: ::c_long = 290; +pub const SYS_inotify_init: ::c_long = 291; +pub const SYS_inotify_add_watch: ::c_long = 292; +pub const SYS_inotify_rm_watch: ::c_long = 293; +pub const SYS_migrate_pages: ::c_long = 294; +pub const SYS_openat: ::c_long = 295; +pub const SYS_mkdirat: ::c_long = 296; +pub const SYS_mknodat: ::c_long = 297; +pub const SYS_fchownat: ::c_long = 298; +pub const SYS_futimesat: ::c_long = 299; +pub const SYS_fstatat64: ::c_long = 300; +pub const SYS_unlinkat: ::c_long = 301; +pub const SYS_renameat: ::c_long = 302; +pub const SYS_linkat: ::c_long = 303; +pub const SYS_symlinkat: ::c_long = 304; +pub const SYS_readlinkat: ::c_long = 305; +pub const SYS_fchmodat: ::c_long = 306; +pub const SYS_faccessat: ::c_long = 307; +pub const SYS_pselect6: ::c_long = 308; +pub const SYS_ppoll: ::c_long = 309; +pub const SYS_unshare: ::c_long = 310; +pub const SYS_set_robust_list: ::c_long = 311; +pub const SYS_get_robust_list: ::c_long = 312; +pub const SYS_splice: ::c_long = 313; +pub const SYS_sync_file_range: ::c_long = 314; +pub const SYS_tee: ::c_long = 315; +pub const SYS_vmsplice: ::c_long = 316; +pub const SYS_move_pages: ::c_long = 317; +pub const SYS_getcpu: ::c_long = 318; +pub const SYS_epoll_pwait: ::c_long = 319; +pub const SYS_utimensat: ::c_long = 320; +pub const SYS_signalfd: ::c_long = 321; +pub const SYS_timerfd_create: ::c_long = 322; +pub const SYS_eventfd: ::c_long = 323; +pub const SYS_fallocate: ::c_long = 324; +pub const SYS_timerfd_settime: ::c_long = 325; +pub const SYS_timerfd_gettime: ::c_long = 326; +pub const SYS_signalfd4: ::c_long = 327; +pub const SYS_eventfd2: ::c_long = 328; +pub const SYS_epoll_create1: ::c_long = 329; +pub const SYS_dup3: ::c_long = 330; +pub const SYS_pipe2: ::c_long = 331; +pub const SYS_inotify_init1: ::c_long = 332; +pub const SYS_preadv: ::c_long = 333; +pub const SYS_pwritev: ::c_long = 334; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 335; +pub const SYS_perf_event_open: ::c_long = 336; +pub const SYS_recvmmsg: ::c_long = 337; +pub const SYS_fanotify_init: ::c_long = 338; +pub const SYS_fanotify_mark: ::c_long = 339; +pub const SYS_prlimit64: ::c_long = 340; +pub const SYS_name_to_handle_at: ::c_long = 341; +pub const SYS_open_by_handle_at: ::c_long = 342; +pub const SYS_clock_adjtime: ::c_long = 343; +pub const SYS_syncfs: ::c_long = 344; +pub const SYS_sendmmsg: ::c_long = 345; +pub const SYS_setns: ::c_long = 346; +pub const SYS_process_vm_readv: ::c_long = 347; +pub const SYS_process_vm_writev: ::c_long = 348; +pub const SYS_kcmp: ::c_long = 349; +pub const SYS_finit_module: ::c_long = 350; +pub const SYS_sched_setattr: ::c_long = 351; +pub const SYS_sched_getattr: ::c_long = 352; +pub const SYS_renameat2: ::c_long = 353; +pub const SYS_seccomp: ::c_long = 354; +pub const SYS_getrandom: ::c_long = 355; +pub const SYS_memfd_create: ::c_long = 356; +pub const SYS_bpf: ::c_long = 357; +pub const SYS_execveat: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_userfaultfd: ::c_long = 374; +pub const SYS_membarrier: ::c_long = 375; +pub const SYS_mlock2: ::c_long = 376; +pub const SYS_copy_file_range: ::c_long = 377; +pub const SYS_preadv2: ::c_long = 378; +pub const SYS_pwritev2: ::c_long = 379; +pub const SYS_pkey_mprotect: ::c_long = 380; +pub const SYS_pkey_alloc: ::c_long = 381; +pub const SYS_pkey_free: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_rseq: ::c_long = 386; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +// offsets in user_regs_structs, from sys/reg.h +pub const EBX: ::c_int = 0; +pub const ECX: ::c_int = 1; +pub const EDX: ::c_int = 2; +pub const ESI: ::c_int = 3; +pub const EDI: ::c_int = 4; +pub const EBP: ::c_int = 5; +pub const EAX: ::c_int = 6; +pub const DS: ::c_int = 7; +pub const ES: ::c_int = 8; +pub const FS: ::c_int = 9; +pub const GS: ::c_int = 10; +pub const ORIG_EAX: ::c_int = 11; +pub const EIP: ::c_int = 12; +pub const CS: ::c_int = 13; +pub const EFL: ::c_int = 14; +pub const UESP: ::c_int = 15; +pub const SS: ::c_int = 16; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_GS: ::c_int = 0; +pub const REG_FS: ::c_int = 1; +pub const REG_ES: ::c_int = 2; +pub const REG_DS: ::c_int = 3; +pub const REG_EDI: ::c_int = 4; +pub const REG_ESI: ::c_int = 5; +pub const REG_EBP: ::c_int = 6; +pub const REG_ESP: ::c_int = 7; +pub const REG_EBX: ::c_int = 8; +pub const REG_EDX: ::c_int = 9; +pub const REG_ECX: ::c_int = 10; +pub const REG_EAX: ::c_int = 11; +pub const REG_TRAPNO: ::c_int = 12; +pub const REG_ERR: ::c_int = 13; +pub const REG_EIP: ::c_int = 14; +pub const REG_CS: ::c_int = 15; +pub const REG_EFL: ::c_int = 16; +pub const REG_UESP: ::c_int = 17; +pub const REG_SS: ::c_int = 18; + +extern "C" { + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; + pub fn makecontext(ucp: *mut ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); + pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs new file mode 100644 index 00000000..a035773c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs @@ -0,0 +1,51 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} + +s! { + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub fault_address: ::c_ulonglong, + pub regs: [::c_ulonglong; 31], + pub sp: ::c_ulonglong, + pub pc: ::c_ulonglong, + pub pstate: ::c_ulonglong, + // nested arrays to get the right size/length while being able to + // auto-derive traits like Debug + __reserved: [[u64; 32]; 16], + } + + #[repr(align(8))] + pub struct clone_args { + pub flags: ::c_ulonglong, + pub pidfd: ::c_ulonglong, + pub child_tid: ::c_ulonglong, + pub parent_tid: ::c_ulonglong, + pub exit_signal: ::c_ulonglong, + pub stack: ::c_ulonglong, + pub stack_size: ::c_ulonglong, + pub tls: ::c_ulonglong, + pub set_tid: ::c_ulonglong, + pub set_tid_size: ::c_ulonglong, + pub cgroup: ::c_ulonglong, + } +} + +extern "C" { + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; + pub fn makecontext(ucp: *mut ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); + pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs new file mode 100644 index 00000000..398fbb53 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs @@ -0,0 +1,8 @@ +s! { + #[repr(align(16))] + pub struct user_fpsimd_struct { + pub vregs: [[u64; 2]; 32], + pub fpsr: ::c_uint, + pub fpcr: ::c_uint, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs new file mode 100644 index 00000000..0848fb58 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs @@ -0,0 +1,64 @@ +use pthread_mutex_t; + +pub type c_long = i32; +pub type c_ulong = u32; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 48; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const SYS_sync_file_range2: ::c_long = 84; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs new file mode 100644 index 00000000..4535e73e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs @@ -0,0 +1,7 @@ +s! { + pub struct user_fpsimd_struct { + pub vregs: [::__uint128_t; 32], + pub fpsr: u32, + pub fpcr: u32, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs new file mode 100644 index 00000000..3802caf6 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs @@ -0,0 +1,73 @@ +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 48; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const SYS_renameat: ::c_long = 38; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_setrlimit: ::c_long = 164; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs new file mode 100644 index 00000000..284a1788 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs @@ -0,0 +1,937 @@ +//! AArch64-specific definitions for 64-bit linux-like values + +pub type c_char = u8; +pub type wchar_t = u32; +pub type nlink_t = u32; +pub type blksize_t = i32; +pub type suseconds_t = i64; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + __pad2: ::c_int, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [usize; 8] + } + + pub struct user_regs_struct { + pub regs: [::c_ulonglong; 31], + pub sp: ::c_ulonglong, + pub pc: ::c_ulonglong, + pub pstate: ::c_ulonglong, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + +} + +pub const VEOF: usize = 4; + +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; + +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const PTRACE_DETACH: ::c_uint = 17; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; + +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 5120; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +// sys/auxv.h +pub const HWCAP_FP: ::c_ulong = 1 << 0; +pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +pub const HWCAP_EVTSTRM: ::c_ulong = 1 << 2; +pub const HWCAP_AES: ::c_ulong = 1 << 3; +pub const HWCAP_PMULL: ::c_ulong = 1 << 4; +pub const HWCAP_SHA1: ::c_ulong = 1 << 5; +pub const HWCAP_SHA2: ::c_ulong = 1 << 6; +pub const HWCAP_CRC32: ::c_ulong = 1 << 7; +pub const HWCAP_ATOMICS: ::c_ulong = 1 << 8; +pub const HWCAP_FPHP: ::c_ulong = 1 << 9; +pub const HWCAP_ASIMDHP: ::c_ulong = 1 << 10; +pub const HWCAP_CPUID: ::c_ulong = 1 << 11; +pub const HWCAP_ASIMDRDM: ::c_ulong = 1 << 12; +pub const HWCAP_JSCVT: ::c_ulong = 1 << 13; +pub const HWCAP_FCMA: ::c_ulong = 1 << 14; +pub const HWCAP_LRCPC: ::c_ulong = 1 << 15; +pub const HWCAP_DCPOP: ::c_ulong = 1 << 16; +pub const HWCAP_SHA3: ::c_ulong = 1 << 17; +pub const HWCAP_SM3: ::c_ulong = 1 << 18; +pub const HWCAP_SM4: ::c_ulong = 1 << 19; +pub const HWCAP_ASIMDDP: ::c_ulong = 1 << 20; +pub const HWCAP_SHA512: ::c_ulong = 1 << 21; +pub const HWCAP_SVE: ::c_ulong = 1 << 22; +pub const HWCAP_ASIMDFHM: ::c_ulong = 1 << 23; +pub const HWCAP_DIT: ::c_ulong = 1 << 24; +pub const HWCAP_USCAT: ::c_ulong = 1 << 25; +pub const HWCAP_ILRCPC: ::c_ulong = 1 << 26; +pub const HWCAP_FLAGM: ::c_ulong = 1 << 27; +pub const HWCAP_SSBS: ::c_ulong = 1 << 28; +pub const HWCAP_SB: ::c_ulong = 1 << 29; +pub const HWCAP_PACA: ::c_ulong = 1 << 30; +pub const HWCAP_PACG: ::c_ulong = 1 << 31; +// FIXME: enable these again once linux-api-headers are up to date enough on CI. +// See discussion in https://github.com/rust-lang/libc/pull/1638 +//pub const HWCAP2_DCPODP: ::c_ulong = 1 << 0; +//pub const HWCAP2_SVE2: ::c_ulong = 1 << 1; +//pub const HWCAP2_SVEAES: ::c_ulong = 1 << 2; +//pub const HWCAP2_SVEPMULL: ::c_ulong = 1 << 3; +//pub const HWCAP2_SVEBITPERM: ::c_ulong = 1 << 4; +//pub const HWCAP2_SVESHA3: ::c_ulong = 1 << 5; +//pub const HWCAP2_SVESM4: ::c_ulong = 1 << 6; +//pub const HWCAP2_FLAGM2: ::c_ulong = 1 << 7; +//pub const HWCAP2_FRINT: ::c_ulong = 1 << 8; +//pub const HWCAP2_MTE: ::c_ulong = 1 << 18; + +// linux/prctl.h +pub const PR_PAC_RESET_KEYS: ::c_int = 54; +pub const PR_SET_TAGGED_ADDR_CTRL: ::c_int = 55; +pub const PR_GET_TAGGED_ADDR_CTRL: ::c_int = 56; +pub const PR_PAC_SET_ENABLED_KEYS: ::c_int = 60; +pub const PR_PAC_GET_ENABLED_KEYS: ::c_int = 61; + +pub const PR_TAGGED_ADDR_ENABLE: ::c_ulong = 1; + +pub const PR_PAC_APIAKEY: ::c_ulong = 1 << 0; +pub const PR_PAC_APIBKEY: ::c_ulong = 1 << 1; +pub const PR_PAC_APDAKEY: ::c_ulong = 1 << 2; +pub const PR_PAC_APDBKEY: ::c_ulong = 1 << 3; +pub const PR_PAC_APGAKEY: ::c_ulong = 1 << 4; + +pub const PR_SME_SET_VL: ::c_int = 63; +pub const PR_SME_GET_VL: ::c_int = 64; +pub const PR_SME_VL_LEN_MAX: ::c_int = 0xffff; + +pub const PR_SME_SET_VL_INHERIT: ::c_ulong = 1 << 17; +pub const PR_SME_SET_VL_ONE_EXEC: ::c_ulong = 1 << 18; + +// Syscall table +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_dup: ::c_long = 23; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_flock: ::c_long = 32; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_linkat: ::c_long = 37; +// 38 is renameat only on LP64 +pub const SYS_umount2: ::c_long = 39; +pub const SYS_mount: ::c_long = 40; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_openat: ::c_long = 56; +pub const SYS_close: ::c_long = 57; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_sync: ::c_long = 81; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +// 84 sync_file_range on LP64 and sync_file_range2 on ILP32 +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_acct: ::c_long = 89; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_personality: ::c_long = 92; +pub const SYS_exit: ::c_long = 93; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_futex: ::c_long = 98; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_kill: ::c_long = 129; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_times: ::c_long = 153; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_uname: ::c_long = 160; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +// 163 is getrlimit only on LP64 +// 164 is setrlimit only on LP64 +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_umask: ::c_long = 166; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_semop: ::c_long = 193; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_socket: ::c_long = 198; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_accept: ::c_long = 202; +pub const SYS_connect: ::c_long = 203; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_brk: ::c_long = 214; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_setns: ::c_long = 268; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_rseq: ::c_long = 293; +pub const SYS_kexec_file_load: ::c_long = 294; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +pub const PROT_BTI: ::c_int = 0x10; +pub const PROT_MTE: ::c_int = 0x20; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod ilp32; + pub use self::ilp32::*; + } else { + mod lp64; + pub use self::lp64::*; + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } + + +} + +cfg_if! { + if #[cfg(libc_int128)] { + mod int128; + pub use self::int128::*; + } else if #[cfg(libc_align)] { + mod fallback; + pub use self::fallback::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs new file mode 100644 index 00000000..dc191f51 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs @@ -0,0 +1,40 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } +} + +s! { + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub __pc: ::c_ulonglong, + pub __gregs: [::c_ulonglong; 32], + pub __flags: ::c_uint, + pub __extcontext: [::c_ulonglong; 0], + } + + #[repr(align(8))] + pub struct clone_args { + pub flags: ::c_ulonglong, + pub pidfd: ::c_ulonglong, + pub child_tid: ::c_ulonglong, + pub parent_tid: ::c_ulonglong, + pub exit_signal: ::c_ulonglong, + pub stack: ::c_ulonglong, + pub stack_size: ::c_ulonglong, + pub tls: ::c_ulonglong, + pub set_tid: ::c_ulonglong, + pub set_tid_size: ::c_ulonglong, + pub cgroup: ::c_ulonglong, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs new file mode 100644 index 00000000..3e1719a7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs @@ -0,0 +1,900 @@ +use pthread_mutex_t; + +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = i32; + +pub type blksize_t = i32; +pub type nlink_t = u32; +pub type suseconds_t = i64; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [u64; 0], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct user_regs_struct { + pub regs: [u64; 32], + pub orig_a0: u64, + pub csr_era: u64, + pub csr_badv: u64, + pub reserved: [u64; 10], + + } + + pub struct user_fp_struct { + pub fpr: [u64; 32], + pub fcc: u64, + pub fcsr: u32, + } +} + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const HWCAP_CPUCFG: ::c_ulong = 1 << 0; +pub const HWCAP_LAM: ::c_ulong = 1 << 1; +pub const HWCAP_UAL: ::c_ulong = 1 << 2; +pub const HWCAP_FPU: ::c_ulong = 1 << 3; +pub const HWCAP_LSX: ::c_ulong = 1 << 4; +pub const HWCAP_LASX: ::c_ulong = 1 << 5; +pub const HWCAP_CRC32: ::c_ulong = 1 << 6; +pub const HWCAP_COMPLEX: ::c_ulong = 1 << 7; +pub const HWCAP_CRYPTO: ::c_ulong = 1 << 8; +pub const HWCAP_LVZ: ::c_ulong = 1 << 9; +pub const HWCAP_LBT_X86: ::c_ulong = 1 << 10; +pub const HWCAP_LBT_ARM: ::c_ulong = 1 << 11; +pub const HWCAP_LBT_MIPS: ::c_ulong = 1 << 12; +pub const HWCAP_PTW: ::c_ulong = 1 << 13; + +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_dup: ::c_long = 23; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_flock: ::c_long = 32; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_mount: ::c_long = 40; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_openat: ::c_long = 56; +pub const SYS_close: ::c_long = 57; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_sendfile: ::c_long = 71; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_sync: ::c_long = 81; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_acct: ::c_long = 89; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_personality: ::c_long = 92; +pub const SYS_exit: ::c_long = 93; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_futex: ::c_long = 98; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_kill: ::c_long = 129; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_times: ::c_long = 153; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_uname: ::c_long = 160; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_umask: ::c_long = 166; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_semop: ::c_long = 193; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_socket: ::c_long = 198; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_accept: ::c_long = 202; +pub const SYS_connect: ::c_long = 203; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_brk: ::c_long = 214; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_fadvise64: ::c_long = 223; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_recvmmsg: ::c_long = 243; +//pub const SYS_arch_specific_syscall: ::c_long = 244; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_setns: ::c_long = 268; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_io_pgetevents: ::c_long = 292; +pub const SYS_rseq: ::c_long = 293; +pub const SYS_kexec_file_load: ::c_long = 294; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +pub const O_DIRECT: ::c_int = 0o00040000; +pub const O_DIRECTORY: ::c_int = 0o00200000; +pub const O_NOFOLLOW: ::c_int = 0o00400000; +pub const O_TRUNC: ::c_int = 0o00001000; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0o02000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; +pub const O_APPEND: ::c_int = 0o00002000; +pub const O_CREAT: ::c_int = 0o00000100; +pub const O_EXCL: ::c_int = 0o00000200; +pub const O_NOCTTY: ::c_int = 0o00000400; +pub const O_NONBLOCK: ::c_int = 0o00004000; +pub const FASYNC: ::c_int = 0o00020000; +pub const O_SYNC: ::c_int = 0o04010000; +pub const O_RSYNC: ::c_int = 0o04010000; +pub const O_FSYNC: ::c_int = O_SYNC; +pub const O_ASYNC: ::c_int = 0o00020000; +pub const O_DSYNC: ::c_int = 0o00010000; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +pub const F_GETLK: ::c_int = 5; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_SETOWN: ::c_int = 8; +pub const F_GETOWN: ::c_int = 9; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const EDEADLK: ::c_int = 35; +pub const EDEADLOCK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; + +pub const MAP_NORESERVE: ::c_int = 0x4000; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x1000; +pub const MAP_LOCKED: ::c_int = 0x2000; +pub const MAP_POPULATE: ::c_int = 0x8000; +pub const MAP_NONBLOCK: ::c_int = 0x10000; +pub const MAP_STACK: ::c_int = 0x20000; +pub const MAP_HUGETLB: ::c_int = 0x40000; +pub const MAP_SYNC: ::c_int = 0x080000; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x800; +pub const SFD_CLOEXEC: ::c_int = 0x080000; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGCHLD: ::c_int = 17; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGURG: ::c_int = 23; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGIO: ::c_int = 29; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIGSYS: ::c_int = 31; +pub const SIGUNUSED: ::c_int = 31; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_DETACH: ::c_uint = 17; +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; +pub const PTRACE_SYSEMU: ::c_uint = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; + +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const VEOF: usize = 4; +pub const VTIME: usize = 5; +pub const VMIN: usize = 6; +pub const VSWTC: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VEOL: usize = 11; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const VEOL2: usize = 16; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const XCASE: ::tcflag_t = 0x00000004; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; + +pub const NCCS: usize = 32; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; +pub const EFD_NONBLOCK: ::c_int = 0x800; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/align.rs new file mode 100644 index 00000000..7ca870fd --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs new file mode 100644 index 00000000..f7b52be8 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs @@ -0,0 +1,934 @@ +use pthread_mutex_t; + +pub type blksize_t = i64; +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type nlink_t = u64; +pub type suseconds_t = i64; +pub type wchar_t = i32; +pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; + +s! { + pub struct stat { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_ulong; 1], + pub st_size: ::off_t, + st_pad3: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad4: ::c_long, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 7], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 7], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_bavail: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 5], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_restorer: ::Option, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } +} + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const SYS_read: ::c_long = 5000 + 0; +pub const SYS_write: ::c_long = 5000 + 1; +pub const SYS_open: ::c_long = 5000 + 2; +pub const SYS_close: ::c_long = 5000 + 3; +pub const SYS_stat: ::c_long = 5000 + 4; +pub const SYS_fstat: ::c_long = 5000 + 5; +pub const SYS_lstat: ::c_long = 5000 + 6; +pub const SYS_poll: ::c_long = 5000 + 7; +pub const SYS_lseek: ::c_long = 5000 + 8; +pub const SYS_mmap: ::c_long = 5000 + 9; +pub const SYS_mprotect: ::c_long = 5000 + 10; +pub const SYS_munmap: ::c_long = 5000 + 11; +pub const SYS_brk: ::c_long = 5000 + 12; +pub const SYS_rt_sigaction: ::c_long = 5000 + 13; +pub const SYS_rt_sigprocmask: ::c_long = 5000 + 14; +pub const SYS_ioctl: ::c_long = 5000 + 15; +pub const SYS_pread64: ::c_long = 5000 + 16; +pub const SYS_pwrite64: ::c_long = 5000 + 17; +pub const SYS_readv: ::c_long = 5000 + 18; +pub const SYS_writev: ::c_long = 5000 + 19; +pub const SYS_access: ::c_long = 5000 + 20; +pub const SYS_pipe: ::c_long = 5000 + 21; +pub const SYS__newselect: ::c_long = 5000 + 22; +pub const SYS_sched_yield: ::c_long = 5000 + 23; +pub const SYS_mremap: ::c_long = 5000 + 24; +pub const SYS_msync: ::c_long = 5000 + 25; +pub const SYS_mincore: ::c_long = 5000 + 26; +pub const SYS_madvise: ::c_long = 5000 + 27; +pub const SYS_shmget: ::c_long = 5000 + 28; +pub const SYS_shmat: ::c_long = 5000 + 29; +pub const SYS_shmctl: ::c_long = 5000 + 30; +pub const SYS_dup: ::c_long = 5000 + 31; +pub const SYS_dup2: ::c_long = 5000 + 32; +pub const SYS_pause: ::c_long = 5000 + 33; +pub const SYS_nanosleep: ::c_long = 5000 + 34; +pub const SYS_getitimer: ::c_long = 5000 + 35; +pub const SYS_setitimer: ::c_long = 5000 + 36; +pub const SYS_alarm: ::c_long = 5000 + 37; +pub const SYS_getpid: ::c_long = 5000 + 38; +pub const SYS_sendfile: ::c_long = 5000 + 39; +pub const SYS_socket: ::c_long = 5000 + 40; +pub const SYS_connect: ::c_long = 5000 + 41; +pub const SYS_accept: ::c_long = 5000 + 42; +pub const SYS_sendto: ::c_long = 5000 + 43; +pub const SYS_recvfrom: ::c_long = 5000 + 44; +pub const SYS_sendmsg: ::c_long = 5000 + 45; +pub const SYS_recvmsg: ::c_long = 5000 + 46; +pub const SYS_shutdown: ::c_long = 5000 + 47; +pub const SYS_bind: ::c_long = 5000 + 48; +pub const SYS_listen: ::c_long = 5000 + 49; +pub const SYS_getsockname: ::c_long = 5000 + 50; +pub const SYS_getpeername: ::c_long = 5000 + 51; +pub const SYS_socketpair: ::c_long = 5000 + 52; +pub const SYS_setsockopt: ::c_long = 5000 + 53; +pub const SYS_getsockopt: ::c_long = 5000 + 54; +pub const SYS_clone: ::c_long = 5000 + 55; +pub const SYS_fork: ::c_long = 5000 + 56; +pub const SYS_execve: ::c_long = 5000 + 57; +pub const SYS_exit: ::c_long = 5000 + 58; +pub const SYS_wait4: ::c_long = 5000 + 59; +pub const SYS_kill: ::c_long = 5000 + 60; +pub const SYS_uname: ::c_long = 5000 + 61; +pub const SYS_semget: ::c_long = 5000 + 62; +pub const SYS_semop: ::c_long = 5000 + 63; +pub const SYS_semctl: ::c_long = 5000 + 64; +pub const SYS_shmdt: ::c_long = 5000 + 65; +pub const SYS_msgget: ::c_long = 5000 + 66; +pub const SYS_msgsnd: ::c_long = 5000 + 67; +pub const SYS_msgrcv: ::c_long = 5000 + 68; +pub const SYS_msgctl: ::c_long = 5000 + 69; +pub const SYS_fcntl: ::c_long = 5000 + 70; +pub const SYS_flock: ::c_long = 5000 + 71; +pub const SYS_fsync: ::c_long = 5000 + 72; +pub const SYS_fdatasync: ::c_long = 5000 + 73; +pub const SYS_truncate: ::c_long = 5000 + 74; +pub const SYS_ftruncate: ::c_long = 5000 + 75; +pub const SYS_getdents: ::c_long = 5000 + 76; +pub const SYS_getcwd: ::c_long = 5000 + 77; +pub const SYS_chdir: ::c_long = 5000 + 78; +pub const SYS_fchdir: ::c_long = 5000 + 79; +pub const SYS_rename: ::c_long = 5000 + 80; +pub const SYS_mkdir: ::c_long = 5000 + 81; +pub const SYS_rmdir: ::c_long = 5000 + 82; +pub const SYS_creat: ::c_long = 5000 + 83; +pub const SYS_link: ::c_long = 5000 + 84; +pub const SYS_unlink: ::c_long = 5000 + 85; +pub const SYS_symlink: ::c_long = 5000 + 86; +pub const SYS_readlink: ::c_long = 5000 + 87; +pub const SYS_chmod: ::c_long = 5000 + 88; +pub const SYS_fchmod: ::c_long = 5000 + 89; +pub const SYS_chown: ::c_long = 5000 + 90; +pub const SYS_fchown: ::c_long = 5000 + 91; +pub const SYS_lchown: ::c_long = 5000 + 92; +pub const SYS_umask: ::c_long = 5000 + 93; +pub const SYS_gettimeofday: ::c_long = 5000 + 94; +pub const SYS_getrlimit: ::c_long = 5000 + 95; +pub const SYS_getrusage: ::c_long = 5000 + 96; +pub const SYS_sysinfo: ::c_long = 5000 + 97; +pub const SYS_times: ::c_long = 5000 + 98; +pub const SYS_ptrace: ::c_long = 5000 + 99; +pub const SYS_getuid: ::c_long = 5000 + 100; +pub const SYS_syslog: ::c_long = 5000 + 101; +pub const SYS_getgid: ::c_long = 5000 + 102; +pub const SYS_setuid: ::c_long = 5000 + 103; +pub const SYS_setgid: ::c_long = 5000 + 104; +pub const SYS_geteuid: ::c_long = 5000 + 105; +pub const SYS_getegid: ::c_long = 5000 + 106; +pub const SYS_setpgid: ::c_long = 5000 + 107; +pub const SYS_getppid: ::c_long = 5000 + 108; +pub const SYS_getpgrp: ::c_long = 5000 + 109; +pub const SYS_setsid: ::c_long = 5000 + 110; +pub const SYS_setreuid: ::c_long = 5000 + 111; +pub const SYS_setregid: ::c_long = 5000 + 112; +pub const SYS_getgroups: ::c_long = 5000 + 113; +pub const SYS_setgroups: ::c_long = 5000 + 114; +pub const SYS_setresuid: ::c_long = 5000 + 115; +pub const SYS_getresuid: ::c_long = 5000 + 116; +pub const SYS_setresgid: ::c_long = 5000 + 117; +pub const SYS_getresgid: ::c_long = 5000 + 118; +pub const SYS_getpgid: ::c_long = 5000 + 119; +pub const SYS_setfsuid: ::c_long = 5000 + 120; +pub const SYS_setfsgid: ::c_long = 5000 + 121; +pub const SYS_getsid: ::c_long = 5000 + 122; +pub const SYS_capget: ::c_long = 5000 + 123; +pub const SYS_capset: ::c_long = 5000 + 124; +pub const SYS_rt_sigpending: ::c_long = 5000 + 125; +pub const SYS_rt_sigtimedwait: ::c_long = 5000 + 126; +pub const SYS_rt_sigqueueinfo: ::c_long = 5000 + 127; +pub const SYS_rt_sigsuspend: ::c_long = 5000 + 128; +pub const SYS_sigaltstack: ::c_long = 5000 + 129; +pub const SYS_utime: ::c_long = 5000 + 130; +pub const SYS_mknod: ::c_long = 5000 + 131; +pub const SYS_personality: ::c_long = 5000 + 132; +pub const SYS_ustat: ::c_long = 5000 + 133; +pub const SYS_statfs: ::c_long = 5000 + 134; +pub const SYS_fstatfs: ::c_long = 5000 + 135; +pub const SYS_sysfs: ::c_long = 5000 + 136; +pub const SYS_getpriority: ::c_long = 5000 + 137; +pub const SYS_setpriority: ::c_long = 5000 + 138; +pub const SYS_sched_setparam: ::c_long = 5000 + 139; +pub const SYS_sched_getparam: ::c_long = 5000 + 140; +pub const SYS_sched_setscheduler: ::c_long = 5000 + 141; +pub const SYS_sched_getscheduler: ::c_long = 5000 + 142; +pub const SYS_sched_get_priority_max: ::c_long = 5000 + 143; +pub const SYS_sched_get_priority_min: ::c_long = 5000 + 144; +pub const SYS_sched_rr_get_interval: ::c_long = 5000 + 145; +pub const SYS_mlock: ::c_long = 5000 + 146; +pub const SYS_munlock: ::c_long = 5000 + 147; +pub const SYS_mlockall: ::c_long = 5000 + 148; +pub const SYS_munlockall: ::c_long = 5000 + 149; +pub const SYS_vhangup: ::c_long = 5000 + 150; +pub const SYS_pivot_root: ::c_long = 5000 + 151; +pub const SYS__sysctl: ::c_long = 5000 + 152; +pub const SYS_prctl: ::c_long = 5000 + 153; +pub const SYS_adjtimex: ::c_long = 5000 + 154; +pub const SYS_setrlimit: ::c_long = 5000 + 155; +pub const SYS_chroot: ::c_long = 5000 + 156; +pub const SYS_sync: ::c_long = 5000 + 157; +pub const SYS_acct: ::c_long = 5000 + 158; +pub const SYS_settimeofday: ::c_long = 5000 + 159; +pub const SYS_mount: ::c_long = 5000 + 160; +pub const SYS_umount2: ::c_long = 5000 + 161; +pub const SYS_swapon: ::c_long = 5000 + 162; +pub const SYS_swapoff: ::c_long = 5000 + 163; +pub const SYS_reboot: ::c_long = 5000 + 164; +pub const SYS_sethostname: ::c_long = 5000 + 165; +pub const SYS_setdomainname: ::c_long = 5000 + 166; +pub const SYS_create_module: ::c_long = 5000 + 167; +pub const SYS_init_module: ::c_long = 5000 + 168; +pub const SYS_delete_module: ::c_long = 5000 + 169; +pub const SYS_get_kernel_syms: ::c_long = 5000 + 170; +pub const SYS_query_module: ::c_long = 5000 + 171; +pub const SYS_quotactl: ::c_long = 5000 + 172; +pub const SYS_nfsservctl: ::c_long = 5000 + 173; +pub const SYS_getpmsg: ::c_long = 5000 + 174; +pub const SYS_putpmsg: ::c_long = 5000 + 175; +pub const SYS_afs_syscall: ::c_long = 5000 + 176; +pub const SYS_gettid: ::c_long = 5000 + 178; +pub const SYS_readahead: ::c_long = 5000 + 179; +pub const SYS_setxattr: ::c_long = 5000 + 180; +pub const SYS_lsetxattr: ::c_long = 5000 + 181; +pub const SYS_fsetxattr: ::c_long = 5000 + 182; +pub const SYS_getxattr: ::c_long = 5000 + 183; +pub const SYS_lgetxattr: ::c_long = 5000 + 184; +pub const SYS_fgetxattr: ::c_long = 5000 + 185; +pub const SYS_listxattr: ::c_long = 5000 + 186; +pub const SYS_llistxattr: ::c_long = 5000 + 187; +pub const SYS_flistxattr: ::c_long = 5000 + 188; +pub const SYS_removexattr: ::c_long = 5000 + 189; +pub const SYS_lremovexattr: ::c_long = 5000 + 190; +pub const SYS_fremovexattr: ::c_long = 5000 + 191; +pub const SYS_tkill: ::c_long = 5000 + 192; +pub const SYS_futex: ::c_long = 5000 + 194; +pub const SYS_sched_setaffinity: ::c_long = 5000 + 195; +pub const SYS_sched_getaffinity: ::c_long = 5000 + 196; +pub const SYS_cacheflush: ::c_long = 5000 + 197; +pub const SYS_cachectl: ::c_long = 5000 + 198; +pub const SYS_sysmips: ::c_long = 5000 + 199; +pub const SYS_io_setup: ::c_long = 5000 + 200; +pub const SYS_io_destroy: ::c_long = 5000 + 201; +pub const SYS_io_getevents: ::c_long = 5000 + 202; +pub const SYS_io_submit: ::c_long = 5000 + 203; +pub const SYS_io_cancel: ::c_long = 5000 + 204; +pub const SYS_exit_group: ::c_long = 5000 + 205; +pub const SYS_lookup_dcookie: ::c_long = 5000 + 206; +pub const SYS_epoll_create: ::c_long = 5000 + 207; +pub const SYS_epoll_ctl: ::c_long = 5000 + 208; +pub const SYS_epoll_wait: ::c_long = 5000 + 209; +pub const SYS_remap_file_pages: ::c_long = 5000 + 210; +pub const SYS_rt_sigreturn: ::c_long = 5000 + 211; +pub const SYS_set_tid_address: ::c_long = 5000 + 212; +pub const SYS_restart_syscall: ::c_long = 5000 + 213; +pub const SYS_semtimedop: ::c_long = 5000 + 214; +pub const SYS_fadvise64: ::c_long = 5000 + 215; +pub const SYS_timer_create: ::c_long = 5000 + 216; +pub const SYS_timer_settime: ::c_long = 5000 + 217; +pub const SYS_timer_gettime: ::c_long = 5000 + 218; +pub const SYS_timer_getoverrun: ::c_long = 5000 + 219; +pub const SYS_timer_delete: ::c_long = 5000 + 220; +pub const SYS_clock_settime: ::c_long = 5000 + 221; +pub const SYS_clock_gettime: ::c_long = 5000 + 222; +pub const SYS_clock_getres: ::c_long = 5000 + 223; +pub const SYS_clock_nanosleep: ::c_long = 5000 + 224; +pub const SYS_tgkill: ::c_long = 5000 + 225; +pub const SYS_utimes: ::c_long = 5000 + 226; +pub const SYS_mbind: ::c_long = 5000 + 227; +pub const SYS_get_mempolicy: ::c_long = 5000 + 228; +pub const SYS_set_mempolicy: ::c_long = 5000 + 229; +pub const SYS_mq_open: ::c_long = 5000 + 230; +pub const SYS_mq_unlink: ::c_long = 5000 + 231; +pub const SYS_mq_timedsend: ::c_long = 5000 + 232; +pub const SYS_mq_timedreceive: ::c_long = 5000 + 233; +pub const SYS_mq_notify: ::c_long = 5000 + 234; +pub const SYS_mq_getsetattr: ::c_long = 5000 + 235; +pub const SYS_vserver: ::c_long = 5000 + 236; +pub const SYS_waitid: ::c_long = 5000 + 237; +/* pub const SYS_sys_setaltroot: ::c_long = 5000 + 238; */ +pub const SYS_add_key: ::c_long = 5000 + 239; +pub const SYS_request_key: ::c_long = 5000 + 240; +pub const SYS_keyctl: ::c_long = 5000 + 241; +pub const SYS_set_thread_area: ::c_long = 5000 + 242; +pub const SYS_inotify_init: ::c_long = 5000 + 243; +pub const SYS_inotify_add_watch: ::c_long = 5000 + 244; +pub const SYS_inotify_rm_watch: ::c_long = 5000 + 245; +pub const SYS_migrate_pages: ::c_long = 5000 + 246; +pub const SYS_openat: ::c_long = 5000 + 247; +pub const SYS_mkdirat: ::c_long = 5000 + 248; +pub const SYS_mknodat: ::c_long = 5000 + 249; +pub const SYS_fchownat: ::c_long = 5000 + 250; +pub const SYS_futimesat: ::c_long = 5000 + 251; +pub const SYS_newfstatat: ::c_long = 5000 + 252; +pub const SYS_unlinkat: ::c_long = 5000 + 253; +pub const SYS_renameat: ::c_long = 5000 + 254; +pub const SYS_linkat: ::c_long = 5000 + 255; +pub const SYS_symlinkat: ::c_long = 5000 + 256; +pub const SYS_readlinkat: ::c_long = 5000 + 257; +pub const SYS_fchmodat: ::c_long = 5000 + 258; +pub const SYS_faccessat: ::c_long = 5000 + 259; +pub const SYS_pselect6: ::c_long = 5000 + 260; +pub const SYS_ppoll: ::c_long = 5000 + 261; +pub const SYS_unshare: ::c_long = 5000 + 262; +pub const SYS_splice: ::c_long = 5000 + 263; +pub const SYS_sync_file_range: ::c_long = 5000 + 264; +pub const SYS_tee: ::c_long = 5000 + 265; +pub const SYS_vmsplice: ::c_long = 5000 + 266; +pub const SYS_move_pages: ::c_long = 5000 + 267; +pub const SYS_set_robust_list: ::c_long = 5000 + 268; +pub const SYS_get_robust_list: ::c_long = 5000 + 269; +pub const SYS_kexec_load: ::c_long = 5000 + 270; +pub const SYS_getcpu: ::c_long = 5000 + 271; +pub const SYS_epoll_pwait: ::c_long = 5000 + 272; +pub const SYS_ioprio_set: ::c_long = 5000 + 273; +pub const SYS_ioprio_get: ::c_long = 5000 + 274; +pub const SYS_utimensat: ::c_long = 5000 + 275; +pub const SYS_signalfd: ::c_long = 5000 + 276; +pub const SYS_timerfd: ::c_long = 5000 + 277; +pub const SYS_eventfd: ::c_long = 5000 + 278; +pub const SYS_fallocate: ::c_long = 5000 + 279; +pub const SYS_timerfd_create: ::c_long = 5000 + 280; +pub const SYS_timerfd_gettime: ::c_long = 5000 + 281; +pub const SYS_timerfd_settime: ::c_long = 5000 + 282; +pub const SYS_signalfd4: ::c_long = 5000 + 283; +pub const SYS_eventfd2: ::c_long = 5000 + 284; +pub const SYS_epoll_create1: ::c_long = 5000 + 285; +pub const SYS_dup3: ::c_long = 5000 + 286; +pub const SYS_pipe2: ::c_long = 5000 + 287; +pub const SYS_inotify_init1: ::c_long = 5000 + 288; +pub const SYS_preadv: ::c_long = 5000 + 289; +pub const SYS_pwritev: ::c_long = 5000 + 290; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 5000 + 291; +pub const SYS_perf_event_open: ::c_long = 5000 + 292; +pub const SYS_accept4: ::c_long = 5000 + 293; +pub const SYS_recvmmsg: ::c_long = 5000 + 294; +pub const SYS_fanotify_init: ::c_long = 5000 + 295; +pub const SYS_fanotify_mark: ::c_long = 5000 + 296; +pub const SYS_prlimit64: ::c_long = 5000 + 297; +pub const SYS_name_to_handle_at: ::c_long = 5000 + 298; +pub const SYS_open_by_handle_at: ::c_long = 5000 + 299; +pub const SYS_clock_adjtime: ::c_long = 5000 + 300; +pub const SYS_syncfs: ::c_long = 5000 + 301; +pub const SYS_sendmmsg: ::c_long = 5000 + 302; +pub const SYS_setns: ::c_long = 5000 + 303; +pub const SYS_process_vm_readv: ::c_long = 5000 + 304; +pub const SYS_process_vm_writev: ::c_long = 5000 + 305; +pub const SYS_kcmp: ::c_long = 5000 + 306; +pub const SYS_finit_module: ::c_long = 5000 + 307; +pub const SYS_getdents64: ::c_long = 5000 + 308; +pub const SYS_sched_setattr: ::c_long = 5000 + 309; +pub const SYS_sched_getattr: ::c_long = 5000 + 310; +pub const SYS_renameat2: ::c_long = 5000 + 311; +pub const SYS_seccomp: ::c_long = 5000 + 312; +pub const SYS_getrandom: ::c_long = 5000 + 313; +pub const SYS_memfd_create: ::c_long = 5000 + 314; +pub const SYS_bpf: ::c_long = 5000 + 315; +pub const SYS_execveat: ::c_long = 5000 + 316; +pub const SYS_userfaultfd: ::c_long = 5000 + 317; +pub const SYS_membarrier: ::c_long = 5000 + 318; +pub const SYS_mlock2: ::c_long = 5000 + 319; +pub const SYS_copy_file_range: ::c_long = 5000 + 320; +pub const SYS_preadv2: ::c_long = 5000 + 321; +pub const SYS_pwritev2: ::c_long = 5000 + 322; +pub const SYS_pkey_mprotect: ::c_long = 5000 + 323; +pub const SYS_pkey_alloc: ::c_long = 5000 + 324; +pub const SYS_pkey_free: ::c_long = 5000 + 325; +pub const SYS_statx: ::c_long = 5000 + 326; +pub const SYS_rseq: ::c_long = 5000 + 327; +pub const SYS_pidfd_send_signal: ::c_long = 5000 + 424; +pub const SYS_io_uring_setup: ::c_long = 5000 + 425; +pub const SYS_io_uring_enter: ::c_long = 5000 + 426; +pub const SYS_io_uring_register: ::c_long = 5000 + 427; +pub const SYS_open_tree: ::c_long = 5000 + 428; +pub const SYS_move_mount: ::c_long = 5000 + 429; +pub const SYS_fsopen: ::c_long = 5000 + 430; +pub const SYS_fsconfig: ::c_long = 5000 + 431; +pub const SYS_fsmount: ::c_long = 5000 + 432; +pub const SYS_fspick: ::c_long = 5000 + 433; +pub const SYS_pidfd_open: ::c_long = 5000 + 434; +pub const SYS_clone3: ::c_long = 5000 + 435; +pub const SYS_close_range: ::c_long = 5000 + 436; +pub const SYS_openat2: ::c_long = 5000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 5000 + 438; +pub const SYS_faccessat2: ::c_long = 5000 + 439; +pub const SYS_process_madvise: ::c_long = 5000 + 440; +pub const SYS_epoll_pwait2: ::c_long = 5000 + 441; +pub const SYS_mount_setattr: ::c_long = 5000 + 442; +pub const SYS_quotactl_fd: ::c_long = 5000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 5000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 5000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 5000 + 446; +pub const SYS_memfd_secret: ::c_long = 5000 + 447; +pub const SYS_process_mrelease: ::c_long = 5000 + 448; +pub const SYS_futex_waitv: ::c_long = 5000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 5000 + 450; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const O_DIRECT: ::c_int = 0x8000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x4010; +pub const O_RSYNC: ::c_int = 0x4010; +pub const O_DSYNC: ::c_int = 0x10; +pub const O_FSYNC: ::c_int = 0x4010; +pub const O_ASYNC: ::c_int = 0x1000; +pub const O_NDELAY: ::c_int = 0x80; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_ANONYMOUS: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_POPULATE: ::c_int = 0x10000; +pub const MAP_NONBLOCK: ::c_int = 0x20000; +pub const MAP_STACK: ::c_int = 0x40000; +pub const MAP_HUGETLB: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGWINCH: ::c_int = 20; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGCONT: ::c_int = 25; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGURG: ::c_int = 21; +pub const SIGIO: ::c_int = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 22; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const TCSANOW: ::c_int = 0x540e; +pub const TCSADRAIN: ::c_int = 0x540f; +pub const TCSAFLUSH: ::c_int = 0x5410; + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_DETACH: ::c_uint = 17; +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; + +pub const EFD_NONBLOCK: ::c_int = 0x80; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +pub const F_GETLK: ::c_int = 14; +pub const F_GETOWN: ::c_int = 23; +pub const F_SETOWN: ::c_int = 24; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const SFD_NONBLOCK: ::c_int = 0x80; + +pub const RTLD_DEEPBIND: ::c_int = 0x10; +pub const RTLD_GLOBAL: ::c_int = 0x4; +pub const RTLD_NOLOAD: ::c_int = 0x8; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const EHWPOISON: ::c_int = 168; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs new file mode 100644 index 00000000..ff394e33 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs @@ -0,0 +1,128 @@ +//! 64-bit specific definitions for linux-like values + +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i64; +pub type shmatt_t = u64; +pub type msgqnum_t = u64; +pub type msglen_t = u64; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type rlim_t = u64; +#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] +pub type __syscall_ulong_t = ::c_ulonglong; +#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] +pub type __syscall_ulong_t = ::c_ulong; + +cfg_if! { + if #[cfg(all(target_arch = "aarch64", target_pointer_width = "32"))] { + pub type clock_t = i32; + pub type time_t = i32; + pub type __fsword_t = i32; + } else { + pub type __fsword_t = i64; + pub type clock_t = i64; + pub type time_t = i64; + } +} + +s! { + pub struct sigset_t { + #[cfg(target_pointer_width = "32")] + __val: [u32; 32], + #[cfg(target_pointer_width = "64")] + __val: [u64; 16], + } + + pub struct sysinfo { + pub uptime: i64, + pub loads: [u64; 3], + pub totalram: u64, + pub freeram: u64, + pub sharedram: u64, + pub bufferram: u64, + pub totalswap: u64, + pub freeswap: u64, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: u64, + pub freehigh: u64, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: u64, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: u64, + __glibc_reserved5: u64, + } + + pub struct semid_ds { + pub sem_perm: ipc_perm, + pub sem_otime: ::time_t, + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "sparc64")))] + __reserved: ::__syscall_ulong_t, + pub sem_ctime: ::time_t, + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "sparc64")))] + __reserved2: ::__syscall_ulong_t, + pub sem_nsems: ::__syscall_ulong_t, + __glibc_reserved3: ::__syscall_ulong_t, + __glibc_reserved4: ::__syscall_ulong_t, + } +} + +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + +pub const O_LARGEFILE: ::c_int = 0; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(any(target_arch = "powerpc64"))] { + mod powerpc64; + pub use self::powerpc64::*; + } else if #[cfg(any(target_arch = "sparc64"))] { + mod sparc64; + pub use self::sparc64::*; + } else if #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] { + mod mips64; + pub use self::mips64::*; + } else if #[cfg(any(target_arch = "s390x"))] { + mod s390x; + pub use self::s390x::*; + } else if #[cfg(any(target_arch = "x86_64"))] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(any(target_arch = "riscv64"))] { + mod riscv64; + pub use self::riscv64::*; + } else if #[cfg(any(target_arch = "loongarch64"))] { + mod loongarch64; + pub use self::loongarch64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs new file mode 100644 index 00000000..29d1e1c7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 4] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs new file mode 100644 index 00000000..3088c25a --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs @@ -0,0 +1,979 @@ +//! PowerPC64-specific definitions for 64-bit linux-like values + +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = i64; +pub type suseconds_t = i64; +pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 3], + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [u64; 7] + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: u32, + __pad1: u32, + __unused1: u64, + __unused2: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const VEOF: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const PTRACE_DETACH: ::c_uint = 17; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_DIRECT: ::c_int = 0x20000; + +pub const MAP_LOCKED: ::c_int = 0x00080; +pub const MAP_NORESERVE: ::c_int = 0x00040; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 58; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const SIGSTKSZ: ::size_t = 0x4000; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0xff; +pub const TAB1: ::tcflag_t = 0x400; +pub const TAB2: ::tcflag_t = 0x800; +pub const TAB3: ::tcflag_t = 0xc00; +pub const CR1: ::tcflag_t = 0x1000; +pub const CR2: ::tcflag_t = 0x2000; +pub const CR3: ::tcflag_t = 0x3000; +pub const FF1: ::tcflag_t = 0x4000; +pub const BS1: ::tcflag_t = 0x8000; +pub const VT1: ::tcflag_t = 0x10000; +pub const VWERASE: usize = 0xa; +pub const VREPRINT: usize = 0xb; +pub const VSUSP: usize = 0xc; +pub const VSTART: usize = 0xd; +pub const VSTOP: usize = 0xe; +pub const VDISCARD: usize = 0x10; +pub const VTIME: usize = 0x7; +pub const IXON: ::tcflag_t = 0x200; +pub const IXOFF: ::tcflag_t = 0x400; +pub const ONLCR: ::tcflag_t = 0x2; +pub const CSIZE: ::tcflag_t = 0x300; +pub const CS6: ::tcflag_t = 0x100; +pub const CS7: ::tcflag_t = 0x200; +pub const CS8: ::tcflag_t = 0x300; +pub const CSTOPB: ::tcflag_t = 0x400; +pub const CREAD: ::tcflag_t = 0x800; +pub const PARENB: ::tcflag_t = 0x1000; +pub const PARODD: ::tcflag_t = 0x2000; +pub const HUPCL: ::tcflag_t = 0x4000; +pub const CLOCAL: ::tcflag_t = 0x8000; +pub const ECHOKE: ::tcflag_t = 0x1; +pub const ECHOE: ::tcflag_t = 0x2; +pub const ECHOK: ::tcflag_t = 0x4; +pub const ECHONL: ::tcflag_t = 0x10; +pub const ECHOPRT: ::tcflag_t = 0x20; +pub const ECHOCTL: ::tcflag_t = 0x40; +pub const ISIG: ::tcflag_t = 0x80; +pub const ICANON: ::tcflag_t = 0x100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o001400; +pub const CRDLY: ::tcflag_t = 0o030000; +pub const TABDLY: ::tcflag_t = 0o006000; +pub const BSDLY: ::tcflag_t = 0o100000; +pub const FFDLY: ::tcflag_t = 0o040000; +pub const VTDLY: ::tcflag_t = 0o200000; +pub const XTABS: ::tcflag_t = 0o006000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const CBAUDEX: ::speed_t = 0o000020; +pub const B57600: ::speed_t = 0o0020; +pub const B115200: ::speed_t = 0o0021; +pub const B230400: ::speed_t = 0o0022; +pub const B460800: ::speed_t = 0o0023; +pub const B500000: ::speed_t = 0o0024; +pub const B576000: ::speed_t = 0o0025; +pub const B921600: ::speed_t = 0o0026; +pub const B1000000: ::speed_t = 0o0027; +pub const B1152000: ::speed_t = 0o0030; +pub const B1500000: ::speed_t = 0o0031; +pub const B2000000: ::speed_t = 0o0032; +pub const B2500000: ::speed_t = 0o0033; +pub const B3000000: ::speed_t = 0o0034; +pub const B3500000: ::speed_t = 0o0035; +pub const B4000000: ::speed_t = 0o0036; + +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: ::tcflag_t = 0x400; +pub const TOSTOP: ::tcflag_t = 0x400000; +pub const FLUSHO: ::tcflag_t = 0x800000; +pub const EXTPROC: ::tcflag_t = 0x10000000; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; /* some people actually want streams */ +pub const SYS_putpmsg: ::c_long = 188; /* some people actually want streams */ +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; /* SuS compliant getrlimit */ +pub const SYS_readahead: ::c_long = 191; +pub const SYS_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_newfstatat: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +pub const SYS_preadv2: ::c_long = 380; +pub const SYS_pwritev2: ::c_long = 381; +pub const SYS_kexec_file_load: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_rseq: ::c_long = 387; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs new file mode 100644 index 00000000..48d152a5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs @@ -0,0 +1,44 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct ucontext_t { + pub __uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct mcontext_t { + pub __gregs: [::c_ulong; 32], + pub __fpregs: __riscv_mc_fp_state, + } + + #[allow(missing_debug_implementations)] + pub union __riscv_mc_fp_state { + pub __f: __riscv_mc_f_ext_state, + pub __d: __riscv_mc_d_ext_state, + pub __q: __riscv_mc_q_ext_state, + } + + #[allow(missing_debug_implementations)] + pub struct __riscv_mc_f_ext_state { + pub __f: [::c_uint; 32], + pub __fcsr: ::c_uint, + } + + #[allow(missing_debug_implementations)] + pub struct __riscv_mc_d_ext_state { + pub __f: [::c_ulonglong; 32], + pub __fcsr: ::c_uint, + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct __riscv_mc_q_ext_state { + pub __f: [::c_ulonglong; 64], + pub __fcsr: ::c_uint, + pub __glibc_reserved: [::c_uint; 3], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs new file mode 100644 index 00000000..8e06a135 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs @@ -0,0 +1,852 @@ +//! RISC-V-specific definitions for 64-bit linux-like values + +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = ::c_int; + +pub type nlink_t = ::c_uint; +pub type blksize_t = ::c_int; +pub type fsblkcnt64_t = ::c_ulong; +pub type fsfilcnt64_t = ::c_ulong; +pub type suseconds_t = i64; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct pthread_attr_t { + __size: [::c_ulong; 7], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2usize], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_favail: ::fsfilcnt64_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [u64; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused5: ::c_ulong, + __unused6: ::c_ulong, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct user_regs_struct { + pub pc: ::c_ulong, + pub ra: ::c_ulong, + pub sp: ::c_ulong, + pub gp: ::c_ulong, + pub tp: ::c_ulong, + pub t0: ::c_ulong, + pub t1: ::c_ulong, + pub t2: ::c_ulong, + pub s0: ::c_ulong, + pub s1: ::c_ulong, + pub a0: ::c_ulong, + pub a1: ::c_ulong, + pub a2: ::c_ulong, + pub a3: ::c_ulong, + pub a4: ::c_ulong, + pub a5: ::c_ulong, + pub a6: ::c_ulong, + pub a7: ::c_ulong, + pub s2: ::c_ulong, + pub s3: ::c_ulong, + pub s4: ::c_ulong, + pub s5: ::c_ulong, + pub s6: ::c_ulong, + pub s7: ::c_ulong, + pub s8: ::c_ulong, + pub s9: ::c_ulong, + pub s10: ::c_ulong, + pub s11: ::c_ulong, + pub t3: ::c_ulong, + pub t4: ::c_ulong, + pub t5: ::c_ulong, + pub t6: ::c_ulong, + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 1052672; +pub const O_NOATIME: ::c_int = 262144; +pub const O_PATH: ::c_int = 2097152; +pub const O_TMPFILE: ::c_int = 4259840; +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 256; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 134217728; +pub const SA_SIGINFO: ::c_int = 4; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const POLLWRNORM: ::c_short = 256; +pub const POLLWRBAND: ::c_short = 512; +pub const O_ASYNC: ::c_int = 8192; +pub const O_NDELAY: ::c_int = 2048; +pub const PTRACE_DETACH: ::c_uint = 17; +pub const EFD_NONBLOCK: ::c_int = 2048; +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; +pub const SFD_NONBLOCK: ::c_int = 2048; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +pub const SFD_CLOEXEC: ::c_int = 524288; +pub const NCCS: usize = 32; +pub const O_TRUNC: ::c_int = 512; +pub const O_CLOEXEC: ::c_int = 524288; +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; +pub const SA_NODEFER: ::c_int = 1073741824; +pub const SA_RESETHAND: ::c_int = -2147483648; +pub const SA_RESTART: ::c_int = 268435456; +pub const SA_NOCLDSTOP: ::c_int = 1; +pub const EPOLL_CLOEXEC: ::c_int = 524288; +pub const EFD_CLOEXEC: ::c_int = 524288; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const O_DIRECT: ::c_int = 16384; +pub const O_DIRECTORY: ::c_int = 65536; +pub const O_NOFOLLOW: ::c_int = 131072; +pub const MAP_HUGETLB: ::c_int = 262144; +pub const MAP_LOCKED: ::c_int = 8192; +pub const MAP_NORESERVE: ::c_int = 16384; +pub const MAP_ANON: ::c_int = 32; +pub const MAP_ANONYMOUS: ::c_int = 32; +pub const MAP_DENYWRITE: ::c_int = 2048; +pub const MAP_EXECUTABLE: ::c_int = 4096; +pub const MAP_POPULATE: ::c_int = 32768; +pub const MAP_NONBLOCK: ::c_int = 65536; +pub const MAP_STACK: ::c_int = 131072; +pub const MAP_SYNC: ::c_int = 0x080000; +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; +pub const MCL_CURRENT: ::c_int = 1; +pub const MCL_FUTURE: ::c_int = 2; +pub const MCL_ONFAULT: ::c_int = 4; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 4111; +pub const TAB1: ::tcflag_t = 2048; +pub const TAB2: ::tcflag_t = 4096; +pub const TAB3: ::tcflag_t = 6144; +pub const CR1: ::tcflag_t = 512; +pub const CR2: ::tcflag_t = 1024; +pub const CR3: ::tcflag_t = 1536; +pub const FF1: ::tcflag_t = 32768; +pub const BS1: ::tcflag_t = 8192; +pub const VT1: ::tcflag_t = 16384; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 1024; +pub const IXOFF: ::tcflag_t = 4096; +pub const ONLCR: ::tcflag_t = 4; +pub const CSIZE: ::tcflag_t = 48; +pub const CS6: ::tcflag_t = 16; +pub const CS7: ::tcflag_t = 32; +pub const CS8: ::tcflag_t = 48; +pub const CSTOPB: ::tcflag_t = 64; +pub const CREAD: ::tcflag_t = 128; +pub const PARENB: ::tcflag_t = 256; +pub const PARODD: ::tcflag_t = 512; +pub const HUPCL: ::tcflag_t = 1024; +pub const CLOCAL: ::tcflag_t = 2048; +pub const ECHOKE: ::tcflag_t = 2048; +pub const ECHOE: ::tcflag_t = 16; +pub const ECHOK: ::tcflag_t = 32; +pub const ECHONL: ::tcflag_t = 64; +pub const ECHOPRT: ::tcflag_t = 1024; +pub const ECHOCTL: ::tcflag_t = 512; +pub const ISIG: ::tcflag_t = 1; +pub const ICANON: ::tcflag_t = 2; +pub const PENDIN: ::tcflag_t = 16384; +pub const NOFLSH: ::tcflag_t = 128; +pub const CIBAUD: ::tcflag_t = 269418496; +pub const CBAUDEX: ::tcflag_t = 4096; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 2; +pub const NLDLY: ::tcflag_t = 256; +pub const CRDLY: ::tcflag_t = 1536; +pub const TABDLY: ::tcflag_t = 6144; +pub const BSDLY: ::tcflag_t = 8192; +pub const FFDLY: ::tcflag_t = 32768; +pub const VTDLY: ::tcflag_t = 16384; +pub const XTABS: ::tcflag_t = 6144; +pub const B0: ::speed_t = 0; +pub const B50: ::speed_t = 1; +pub const B75: ::speed_t = 2; +pub const B110: ::speed_t = 3; +pub const B134: ::speed_t = 4; +pub const B150: ::speed_t = 5; +pub const B200: ::speed_t = 6; +pub const B300: ::speed_t = 7; +pub const B600: ::speed_t = 8; +pub const B1200: ::speed_t = 9; +pub const B1800: ::speed_t = 10; +pub const B2400: ::speed_t = 11; +pub const B4800: ::speed_t = 12; +pub const B9600: ::speed_t = 13; +pub const B19200: ::speed_t = 14; +pub const B38400: ::speed_t = 15; +pub const EXTA: ::speed_t = 14; +pub const EXTB: ::speed_t = 15; +pub const B57600: ::speed_t = 4097; +pub const B115200: ::speed_t = 4098; +pub const B230400: ::speed_t = 4099; +pub const B460800: ::speed_t = 4100; +pub const B500000: ::speed_t = 4101; +pub const B576000: ::speed_t = 4102; +pub const B921600: ::speed_t = 4103; +pub const B1000000: ::speed_t = 4104; +pub const B1152000: ::speed_t = 4105; +pub const B1500000: ::speed_t = 4106; +pub const B2000000: ::speed_t = 4107; +pub const B2500000: ::speed_t = 4108; +pub const B3000000: ::speed_t = 4109; +pub const B3500000: ::speed_t = 4110; +pub const B4000000: ::speed_t = 4111; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 32768; +pub const TOSTOP: ::tcflag_t = 256; +pub const FLUSHO: ::tcflag_t = 4096; +pub const EXTPROC: ::tcflag_t = 65536; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; +pub const NGREG: usize = 32; +pub const REG_PC: usize = 0; +pub const REG_RA: usize = 1; +pub const REG_SP: usize = 2; +pub const REG_TP: usize = 4; +pub const REG_S0: usize = 8; +pub const REG_S1: usize = 9; +pub const REG_A0: usize = 10; +pub const REG_S2: usize = 18; +pub const REG_NARGS: usize = 8; + +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_close: ::c_long = 57; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_brk: ::c_long = 214; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_dup: ::c_long = 23; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_sendfile: ::c_long = 71; +pub const SYS_socket: ::c_long = 198; +pub const SYS_connect: ::c_long = 203; +pub const SYS_accept: ::c_long = 202; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_exit: ::c_long = 93; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_kill: ::c_long = 129; +pub const SYS_uname: ::c_long = 160; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semop: ::c_long = 193; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_flock: ::c_long = 32; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_umask: ::c_long = 166; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_times: ::c_long = 153; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_personality: ::c_long = 92; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_sync: ::c_long = 81; +pub const SYS_acct: ::c_long = 89; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_mount: ::c_long = 40; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_futex: ::c_long = 98; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_fadvise64: ::c_long = 223; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_openat: ::c_long = 56; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_setns: ::c_long = 268; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_rseq: ::c_long = 293; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs new file mode 100644 index 00000000..61ee2dcc --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs @@ -0,0 +1,964 @@ +//! s390x + +use pthread_mutex_t; + +pub type blksize_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type nlink_t = u64; +pub type suseconds_t = i64; +pub type wchar_t = i32; +pub type greg_t = u64; +pub type __u64 = u64; +pub type __s64 = i64; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + __glibc_reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + pub sa_mask: ::sigset_t, + } + + pub struct statfs { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + f_spare: [::c_uint; 4], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __glibc_reserved: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + __glibc_reserved: [::c_long; 3], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct __psw_t { + pub mask: u64, + pub addr: u64, + } + + pub struct fpregset_t { + pub fpc: u32, + __pad: u32, + pub fprs: [fpreg_t; 16], + } + + pub struct mcontext_t { + pub psw: __psw_t, + pub gregs: [u64; 16], + pub aregs: [u32; 16], + pub fpregs: fpregset_t, + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + } + + pub struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +s_no_extra_traits! { + // FIXME: This is actually a union. + pub struct fpreg_t { + pub d: ::c_double, + // f: ::c_float, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg_t { + fn eq(&self, other: &fpreg_t) -> bool { + self.d == other.d + } + } + + impl Eq for fpreg_t {} + + impl ::fmt::Debug for fpreg_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg_t") + .field("d", &self.d) + .finish() + } + } + + impl ::hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = unsafe { ::mem::transmute(self.d) }; + d.hash(state); + } + } + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 6; +pub const POSIX_FADV_NOREUSE: ::c_int = 7; + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +pub const EDEADLK: ::c_int = 35; +pub const ENOSYS: ::c_int = 38; +pub const ENOTCONN: ::c_int = 107; +pub const ETIMEDOUT: ::c_int = 110; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NONBLOCK: ::c_int = 2048; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 4; +pub const SIGBUS: ::c_int = 7; +pub const SIGSTKSZ: ::size_t = 0x2000; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIG_SETMASK: ::c_int = 2; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const O_NOCTTY: ::c_int = 256; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const PTRACE_DETACH: ::c_uint = 17; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const VTIME: usize = 5; +pub const VSWTC: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const FF1: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const CBAUD: ::speed_t = 0o010017; +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const CSIZE: ::tcflag_t = 0o000060; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +pub const CREAD: ::tcflag_t = 0o000200; +pub const PARENB: ::tcflag_t = 0o000400; +pub const PARODD: ::tcflag_t = 0o001000; +pub const HUPCL: ::tcflag_t = 0o002000; +pub const CLOCAL: ::tcflag_t = 0o004000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; +pub const CIBAUD: ::tcflag_t = 0o02003600000; + +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const XCASE: ::tcflag_t = 0o000004; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const PENDIN: ::tcflag_t = 0o040000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; + +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_restart_syscall: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_signal: ::c_long = 48; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_lookup_dcookie: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_getdents: ::c_long = 141; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_readahead: ::c_long = 222; +pub const SYS_setxattr: ::c_long = 224; +pub const SYS_lsetxattr: ::c_long = 225; +pub const SYS_fsetxattr: ::c_long = 226; +pub const SYS_getxattr: ::c_long = 227; +pub const SYS_lgetxattr: ::c_long = 228; +pub const SYS_fgetxattr: ::c_long = 229; +pub const SYS_listxattr: ::c_long = 230; +pub const SYS_llistxattr: ::c_long = 231; +pub const SYS_flistxattr: ::c_long = 232; +pub const SYS_removexattr: ::c_long = 233; +pub const SYS_lremovexattr: ::c_long = 234; +pub const SYS_fremovexattr: ::c_long = 235; +pub const SYS_gettid: ::c_long = 236; +pub const SYS_tkill: ::c_long = 237; +pub const SYS_futex: ::c_long = 238; +pub const SYS_sched_setaffinity: ::c_long = 239; +pub const SYS_sched_getaffinity: ::c_long = 240; +pub const SYS_tgkill: ::c_long = 241; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_epoll_create: ::c_long = 249; +pub const SYS_epoll_ctl: ::c_long = 250; +pub const SYS_epoll_wait: ::c_long = 251; +pub const SYS_set_tid_address: ::c_long = 252; +pub const SYS_fadvise64: ::c_long = 253; +pub const SYS_timer_create: ::c_long = 254; +pub const SYS_timer_settime: ::c_long = 255; +pub const SYS_timer_gettime: ::c_long = 256; +pub const SYS_timer_getoverrun: ::c_long = 257; +pub const SYS_timer_delete: ::c_long = 258; +pub const SYS_clock_settime: ::c_long = 259; +pub const SYS_clock_gettime: ::c_long = 260; +pub const SYS_clock_getres: ::c_long = 261; +pub const SYS_clock_nanosleep: ::c_long = 262; +pub const SYS_statfs64: ::c_long = 265; +pub const SYS_fstatfs64: ::c_long = 266; +pub const SYS_remap_file_pages: ::c_long = 267; +pub const SYS_mbind: ::c_long = 268; +pub const SYS_get_mempolicy: ::c_long = 269; +pub const SYS_set_mempolicy: ::c_long = 270; +pub const SYS_mq_open: ::c_long = 271; +pub const SYS_mq_unlink: ::c_long = 272; +pub const SYS_mq_timedsend: ::c_long = 273; +pub const SYS_mq_timedreceive: ::c_long = 274; +pub const SYS_mq_notify: ::c_long = 275; +pub const SYS_mq_getsetattr: ::c_long = 276; +pub const SYS_kexec_load: ::c_long = 277; +pub const SYS_add_key: ::c_long = 278; +pub const SYS_request_key: ::c_long = 279; +pub const SYS_keyctl: ::c_long = 280; +pub const SYS_waitid: ::c_long = 281; +pub const SYS_ioprio_set: ::c_long = 282; +pub const SYS_ioprio_get: ::c_long = 283; +pub const SYS_inotify_init: ::c_long = 284; +pub const SYS_inotify_add_watch: ::c_long = 285; +pub const SYS_inotify_rm_watch: ::c_long = 286; +pub const SYS_migrate_pages: ::c_long = 287; +pub const SYS_openat: ::c_long = 288; +pub const SYS_mkdirat: ::c_long = 289; +pub const SYS_mknodat: ::c_long = 290; +pub const SYS_fchownat: ::c_long = 291; +pub const SYS_futimesat: ::c_long = 292; +pub const SYS_unlinkat: ::c_long = 294; +pub const SYS_renameat: ::c_long = 295; +pub const SYS_linkat: ::c_long = 296; +pub const SYS_symlinkat: ::c_long = 297; +pub const SYS_readlinkat: ::c_long = 298; +pub const SYS_fchmodat: ::c_long = 299; +pub const SYS_faccessat: ::c_long = 300; +pub const SYS_pselect6: ::c_long = 301; +pub const SYS_ppoll: ::c_long = 302; +pub const SYS_unshare: ::c_long = 303; +pub const SYS_set_robust_list: ::c_long = 304; +pub const SYS_get_robust_list: ::c_long = 305; +pub const SYS_splice: ::c_long = 306; +pub const SYS_sync_file_range: ::c_long = 307; +pub const SYS_tee: ::c_long = 308; +pub const SYS_vmsplice: ::c_long = 309; +pub const SYS_move_pages: ::c_long = 310; +pub const SYS_getcpu: ::c_long = 311; +pub const SYS_epoll_pwait: ::c_long = 312; +pub const SYS_utimes: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_utimensat: ::c_long = 315; +pub const SYS_signalfd: ::c_long = 316; +pub const SYS_timerfd: ::c_long = 317; +pub const SYS_eventfd: ::c_long = 318; +pub const SYS_timerfd_create: ::c_long = 319; +pub const SYS_timerfd_settime: ::c_long = 320; +pub const SYS_timerfd_gettime: ::c_long = 321; +pub const SYS_signalfd4: ::c_long = 322; +pub const SYS_eventfd2: ::c_long = 323; +pub const SYS_inotify_init1: ::c_long = 324; +pub const SYS_pipe2: ::c_long = 325; +pub const SYS_dup3: ::c_long = 326; +pub const SYS_epoll_create1: ::c_long = 327; +pub const SYS_preadv: ::c_long = 328; +pub const SYS_pwritev: ::c_long = 329; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 330; +pub const SYS_perf_event_open: ::c_long = 331; +pub const SYS_fanotify_init: ::c_long = 332; +pub const SYS_fanotify_mark: ::c_long = 333; +pub const SYS_prlimit64: ::c_long = 334; +pub const SYS_name_to_handle_at: ::c_long = 335; +pub const SYS_open_by_handle_at: ::c_long = 336; +pub const SYS_clock_adjtime: ::c_long = 337; +pub const SYS_syncfs: ::c_long = 338; +pub const SYS_setns: ::c_long = 339; +pub const SYS_process_vm_readv: ::c_long = 340; +pub const SYS_process_vm_writev: ::c_long = 341; +pub const SYS_s390_runtime_instr: ::c_long = 342; +pub const SYS_kcmp: ::c_long = 343; +pub const SYS_finit_module: ::c_long = 344; +pub const SYS_sched_setattr: ::c_long = 345; +pub const SYS_sched_getattr: ::c_long = 346; +pub const SYS_renameat2: ::c_long = 347; +pub const SYS_seccomp: ::c_long = 348; +pub const SYS_getrandom: ::c_long = 349; +pub const SYS_memfd_create: ::c_long = 350; +pub const SYS_bpf: ::c_long = 351; +pub const SYS_s390_pci_mmio_write: ::c_long = 352; +pub const SYS_s390_pci_mmio_read: ::c_long = 353; +pub const SYS_execveat: ::c_long = 354; +pub const SYS_userfaultfd: ::c_long = 355; +pub const SYS_membarrier: ::c_long = 356; +pub const SYS_recvmmsg: ::c_long = 357; +pub const SYS_sendmmsg: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_mlock2: ::c_long = 374; +pub const SYS_copy_file_range: ::c_long = 375; +pub const SYS_preadv2: ::c_long = 376; +pub const SYS_pwritev2: ::c_long = 377; +pub const SYS_lchown: ::c_long = 198; +pub const SYS_setuid: ::c_long = 213; +pub const SYS_getuid: ::c_long = 199; +pub const SYS_setgid: ::c_long = 214; +pub const SYS_getgid: ::c_long = 200; +pub const SYS_geteuid: ::c_long = 201; +pub const SYS_setreuid: ::c_long = 203; +pub const SYS_setregid: ::c_long = 204; +pub const SYS_getrlimit: ::c_long = 191; +pub const SYS_getgroups: ::c_long = 205; +pub const SYS_fchown: ::c_long = 207; +pub const SYS_setresuid: ::c_long = 208; +pub const SYS_setresgid: ::c_long = 210; +pub const SYS_getresgid: ::c_long = 211; +pub const SYS_select: ::c_long = 142; +pub const SYS_getegid: ::c_long = 202; +pub const SYS_setgroups: ::c_long = 206; +pub const SYS_getresuid: ::c_long = 209; +pub const SYS_chown: ::c_long = 212; +pub const SYS_setfsuid: ::c_long = 215; +pub const SYS_setfsgid: ::c_long = 216; +pub const SYS_newfstatat: ::c_long = 293; +pub const SYS_statx: ::c_long = 379; +pub const SYS_rseq: ::c_long = 383; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +extern "C" { + + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn getcontext(ucp: *mut ::ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ::ucontext_t) -> ::c_int; + pub fn makecontext(ucp: *mut ::ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); + pub fn swapcontext(uocp: *mut ::ucontext_t, ucp: *const ::ucontext_t) -> ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/align.rs new file mode 100644 index 00000000..29d1e1c7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 4] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs new file mode 100644 index 00000000..de2f0d6e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs @@ -0,0 +1,931 @@ +//! SPARC64-specific definitions for 64-bit linux-like values + +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type wchar_t = i32; +pub type nlink_t = u32; +pub type blksize_t = i64; +pub type suseconds_t = i32; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + __reserved: ::c_short, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct stat { + pub st_dev: ::dev_t, + __pad0: u64, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad1: u64, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad0: u64, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: ::c_int, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 2], + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [u64; 7] + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + __pad0: u16, + pub __seq: ::c_ushort, + __unused1: ::c_ulonglong, + __unused2: ::c_ulonglong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __reserved1: ::c_ulong, + __reserved2: ::c_ulong + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +pub const O_APPEND: ::c_int = 0x8; +pub const O_CREAT: ::c_int = 0x200; +pub const O_EXCL: ::c_int = 0x800; +pub const O_NOCTTY: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x4000; +pub const O_SYNC: ::c_int = 0x802000; +pub const O_RSYNC: ::c_int = 0x802000; +pub const O_DSYNC: ::c_int = 0x2000; +pub const O_FSYNC: ::c_int = 0x802000; +pub const O_NOATIME: ::c_int = 0x200000; +pub const O_PATH: ::c_int = 0x1000000; +pub const O_TMPFILE: ::c_int = 0x2000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0200; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLK: ::c_int = 78; +pub const ENAMETOOLONG: ::c_int = 63; +pub const ENOLCK: ::c_int = 79; +pub const ENOSYS: ::c_int = 90; +pub const ENOTEMPTY: ::c_int = 66; +pub const ELOOP: ::c_int = 62; +pub const ENOMSG: ::c_int = 75; +pub const EIDRM: ::c_int = 77; +pub const ECHRNG: ::c_int = 94; +pub const EL2NSYNC: ::c_int = 95; +pub const EL3HLT: ::c_int = 96; +pub const EL3RST: ::c_int = 97; +pub const ELNRNG: ::c_int = 98; +pub const EUNATCH: ::c_int = 99; +pub const ENOCSI: ::c_int = 100; +pub const EL2HLT: ::c_int = 101; +pub const EBADE: ::c_int = 102; +pub const EBADR: ::c_int = 103; +pub const EXFULL: ::c_int = 104; +pub const ENOANO: ::c_int = 105; +pub const EBADRQC: ::c_int = 106; +pub const EBADSLT: ::c_int = 107; +pub const EMULTIHOP: ::c_int = 87; +pub const EOVERFLOW: ::c_int = 92; +pub const ENOTUNIQ: ::c_int = 115; +pub const EBADFD: ::c_int = 93; +pub const EBADMSG: ::c_int = 76; +pub const EREMCHG: ::c_int = 89; +pub const ELIBACC: ::c_int = 114; +pub const ELIBBAD: ::c_int = 112; +pub const ELIBSCN: ::c_int = 124; +pub const ELIBMAX: ::c_int = 123; +pub const ELIBEXEC: ::c_int = 110; +pub const EILSEQ: ::c_int = 122; +pub const ERESTART: ::c_int = 116; +pub const ESTRPIPE: ::c_int = 91; +pub const EUSERS: ::c_int = 68; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +pub const ESHUTDOWN: ::c_int = 58; +pub const ETOOMANYREFS: ::c_int = 59; +pub const ETIMEDOUT: ::c_int = 60; +pub const ECONNREFUSED: ::c_int = 61; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const EALREADY: ::c_int = 37; +pub const EINPROGRESS: ::c_int = 36; +pub const ESTALE: ::c_int = 70; +pub const EDQUOT: ::c_int = 69; +pub const ENOMEDIUM: ::c_int = 125; +pub const EMEDIUMTYPE: ::c_int = 126; +pub const ECANCELED: ::c_int = 127; +pub const ENOKEY: ::c_int = 128; +pub const EKEYEXPIRED: ::c_int = 129; +pub const EKEYREVOKED: ::c_int = 130; +pub const EKEYREJECTED: ::c_int = 131; +pub const EOWNERDEAD: ::c_int = 132; +pub const ENOTRECOVERABLE: ::c_int = 133; +pub const EHWPOISON: ::c_int = 135; +pub const ERFKILL: ::c_int = 134; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 1; +pub const SA_SIGINFO: ::c_int = 0x200; +pub const SA_NOCLDWAIT: ::c_int = 0x100; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGCONT: ::c_int = 19; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGURG: ::c_int = 16; +pub const SIGIO: ::c_int = 23; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 23; +pub const SIGPWR: ::c_int = 29; +pub const SIG_SETMASK: ::c_int = 4; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; + +pub const POLLWRNORM: ::c_short = 4; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const O_ASYNC: ::c_int = 0x40; +pub const O_NDELAY: ::c_int = 0x4004; + +pub const PTRACE_DETACH: ::c_uint = 17; + +pub const EFD_NONBLOCK: ::c_int = 0x4000; + +pub const F_GETLK: ::c_int = 7; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const F_RDLCK: ::c_int = 1; +pub const F_WRLCK: ::c_int = 2; +pub const F_UNLCK: ::c_int = 3; + +pub const SFD_NONBLOCK: ::c_int = 0x4000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SFD_CLOEXEC: ::c_int = 0x400000; + +pub const NCCS: usize = 17; +pub const O_TRUNC: ::c_int = 0x400; + +pub const O_CLOEXEC: ::c_int = 0x400000; + +pub const EBFONT: ::c_int = 109; +pub const ENOSTR: ::c_int = 72; +pub const ENODATA: ::c_int = 111; +pub const ETIME: ::c_int = 73; +pub const ENOSR: ::c_int = 74; +pub const ENONET: ::c_int = 80; +pub const ENOPKG: ::c_int = 113; +pub const EREMOTE: ::c_int = 71; +pub const ENOLINK: ::c_int = 82; +pub const EADV: ::c_int = 83; +pub const ESRMNT: ::c_int = 84; +pub const ECOMM: ::c_int = 85; +pub const EPROTO: ::c_int = 86; +pub const EDOTDOT: ::c_int = 88; + +pub const SA_NODEFER: ::c_int = 0x20; +pub const SA_RESETHAND: ::c_int = 0x4; +pub const SA_RESTART: ::c_int = 0x2; +pub const SA_NOCLDSTOP: ::c_int = 0x00000008; + +pub const EPOLL_CLOEXEC: ::c_int = 0x400000; + +pub const EFD_CLOEXEC: ::c_int = 0x400000; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const O_DIRECTORY: ::c_int = 0o200000; +pub const O_NOFOLLOW: ::c_int = 0o400000; +pub const O_DIRECT: ::c_int = 0x100000; + +pub const MAP_LOCKED: ::c_int = 0x0100; +pub const MAP_NORESERVE: ::c_int = 0x00040; + +pub const EDEADLOCK: ::c_int = 108; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0x0000100f; +pub const TAB1: ::tcflag_t = 0x800; +pub const TAB2: ::tcflag_t = 0x1000; +pub const TAB3: ::tcflag_t = 0x1800; +pub const CR1: ::tcflag_t = 0x200; +pub const CR2: ::tcflag_t = 0x400; +pub const CR3: ::tcflag_t = 0x600; +pub const FF1: ::tcflag_t = 0x8000; +pub const BS1: ::tcflag_t = 0x2000; +pub const VT1: ::tcflag_t = 0x4000; +pub const VWERASE: usize = 0xe; +pub const VREPRINT: usize = 0xc; +pub const VSUSP: usize = 0xa; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VDISCARD: usize = 0xd; +pub const VTIME: usize = 0x5; +pub const IXON: ::tcflag_t = 0x400; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const CREAD: ::tcflag_t = 0x80; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const HUPCL: ::tcflag_t = 0x400; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ISIG: ::tcflag_t = 0x1; +pub const ICANON: ::tcflag_t = 0x2; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0x00001000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0x1001; +pub const B115200: ::speed_t = 0x1002; +pub const B230400: ::speed_t = 0x1003; +pub const B460800: ::speed_t = 0x1004; +pub const B76800: ::speed_t = 0x1005; +pub const B153600: ::speed_t = 0x1006; +pub const B307200: ::speed_t = 0x1007; +pub const B614400: ::speed_t = 0x1008; +pub const B921600: ::speed_t = 0x1009; +pub const B500000: ::speed_t = 0x100a; +pub const B576000: ::speed_t = 0x100b; +pub const B1000000: ::speed_t = 0x100c; +pub const B1152000: ::speed_t = 0x100d; +pub const B1500000: ::speed_t = 0x100e; +pub const B2000000: ::speed_t = 0x100f; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x8000; +pub const TOSTOP: ::tcflag_t = 0x100; +pub const FLUSHO: ::tcflag_t = 0x1000; +pub const EXTPROC: ::tcflag_t = 0x10000; + +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_wait4: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execv: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_chown: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_brk: ::c_long = 17; +pub const SYS_perfctr: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_capget: ::c_long = 21; +pub const SYS_capset: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_vmsplice: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_sigaltstack: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_stat: ::c_long = 38; +pub const SYS_sendfile: ::c_long = 39; +pub const SYS_lstat: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_umount2: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_memory_ordering: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_reboot: ::c_long = 55; +pub const SYS_symlink: ::c_long = 57; +pub const SYS_readlink: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_fstat: ::c_long = 62; +pub const SYS_fstat64: ::c_long = 63; +pub const SYS_getpagesize: ::c_long = 64; +pub const SYS_msync: ::c_long = 65; +pub const SYS_vfork: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_mmap: ::c_long = 71; +pub const SYS_munmap: ::c_long = 73; +pub const SYS_mprotect: ::c_long = 74; +pub const SYS_madvise: ::c_long = 75; +pub const SYS_vhangup: ::c_long = 76; +pub const SYS_mincore: ::c_long = 78; +pub const SYS_getgroups: ::c_long = 79; +pub const SYS_setgroups: ::c_long = 80; +pub const SYS_getpgrp: ::c_long = 81; +pub const SYS_setitimer: ::c_long = 83; +pub const SYS_swapon: ::c_long = 85; +pub const SYS_getitimer: ::c_long = 86; +pub const SYS_sethostname: ::c_long = 88; +pub const SYS_dup2: ::c_long = 90; +pub const SYS_fcntl: ::c_long = 92; +pub const SYS_select: ::c_long = 93; +pub const SYS_fsync: ::c_long = 95; +pub const SYS_setpriority: ::c_long = 96; +pub const SYS_socket: ::c_long = 97; +pub const SYS_connect: ::c_long = 98; +pub const SYS_accept: ::c_long = 99; +pub const SYS_getpriority: ::c_long = 100; +pub const SYS_rt_sigreturn: ::c_long = 101; +pub const SYS_rt_sigaction: ::c_long = 102; +pub const SYS_rt_sigprocmask: ::c_long = 103; +pub const SYS_rt_sigpending: ::c_long = 104; +pub const SYS_rt_sigtimedwait: ::c_long = 105; +pub const SYS_rt_sigqueueinfo: ::c_long = 106; +pub const SYS_rt_sigsuspend: ::c_long = 107; +pub const SYS_setresuid: ::c_long = 108; +pub const SYS_getresuid: ::c_long = 109; +pub const SYS_setresgid: ::c_long = 110; +pub const SYS_getresgid: ::c_long = 111; +pub const SYS_recvmsg: ::c_long = 113; +pub const SYS_sendmsg: ::c_long = 114; +pub const SYS_gettimeofday: ::c_long = 116; +pub const SYS_getrusage: ::c_long = 117; +pub const SYS_getsockopt: ::c_long = 118; +pub const SYS_getcwd: ::c_long = 119; +pub const SYS_readv: ::c_long = 120; +pub const SYS_writev: ::c_long = 121; +pub const SYS_settimeofday: ::c_long = 122; +pub const SYS_fchown: ::c_long = 123; +pub const SYS_fchmod: ::c_long = 124; +pub const SYS_recvfrom: ::c_long = 125; +pub const SYS_setreuid: ::c_long = 126; +pub const SYS_setregid: ::c_long = 127; +pub const SYS_rename: ::c_long = 128; +pub const SYS_truncate: ::c_long = 129; +pub const SYS_ftruncate: ::c_long = 130; +pub const SYS_flock: ::c_long = 131; +pub const SYS_lstat64: ::c_long = 132; +pub const SYS_sendto: ::c_long = 133; +pub const SYS_shutdown: ::c_long = 134; +pub const SYS_socketpair: ::c_long = 135; +pub const SYS_mkdir: ::c_long = 136; +pub const SYS_rmdir: ::c_long = 137; +pub const SYS_utimes: ::c_long = 138; +pub const SYS_stat64: ::c_long = 139; +pub const SYS_sendfile64: ::c_long = 140; +pub const SYS_getpeername: ::c_long = 141; +pub const SYS_futex: ::c_long = 142; +pub const SYS_gettid: ::c_long = 143; +pub const SYS_getrlimit: ::c_long = 144; +pub const SYS_setrlimit: ::c_long = 145; +pub const SYS_pivot_root: ::c_long = 146; +pub const SYS_prctl: ::c_long = 147; +pub const SYS_pciconfig_read: ::c_long = 148; +pub const SYS_pciconfig_write: ::c_long = 149; +pub const SYS_getsockname: ::c_long = 150; +pub const SYS_inotify_init: ::c_long = 151; +pub const SYS_inotify_add_watch: ::c_long = 152; +pub const SYS_poll: ::c_long = 153; +pub const SYS_getdents64: ::c_long = 154; +pub const SYS_inotify_rm_watch: ::c_long = 156; +pub const SYS_statfs: ::c_long = 157; +pub const SYS_fstatfs: ::c_long = 158; +pub const SYS_umount: ::c_long = 159; +pub const SYS_sched_set_affinity: ::c_long = 160; +pub const SYS_sched_get_affinity: ::c_long = 161; +pub const SYS_getdomainname: ::c_long = 162; +pub const SYS_setdomainname: ::c_long = 163; +pub const SYS_utrap_install: ::c_long = 164; +pub const SYS_quotactl: ::c_long = 165; +pub const SYS_set_tid_address: ::c_long = 166; +pub const SYS_mount: ::c_long = 167; +pub const SYS_ustat: ::c_long = 168; +pub const SYS_setxattr: ::c_long = 169; +pub const SYS_lsetxattr: ::c_long = 170; +pub const SYS_fsetxattr: ::c_long = 171; +pub const SYS_getxattr: ::c_long = 172; +pub const SYS_lgetxattr: ::c_long = 173; +pub const SYS_getdents: ::c_long = 174; +pub const SYS_setsid: ::c_long = 175; +pub const SYS_fchdir: ::c_long = 176; +pub const SYS_fgetxattr: ::c_long = 177; +pub const SYS_listxattr: ::c_long = 178; +pub const SYS_llistxattr: ::c_long = 179; +pub const SYS_flistxattr: ::c_long = 180; +pub const SYS_removexattr: ::c_long = 181; +pub const SYS_lremovexattr: ::c_long = 182; +pub const SYS_sigpending: ::c_long = 183; +pub const SYS_query_module: ::c_long = 184; +pub const SYS_setpgid: ::c_long = 185; +pub const SYS_fremovexattr: ::c_long = 186; +pub const SYS_tkill: ::c_long = 187; +pub const SYS_exit_group: ::c_long = 188; +pub const SYS_uname: ::c_long = 189; +pub const SYS_init_module: ::c_long = 190; +pub const SYS_personality: ::c_long = 191; +pub const SYS_remap_file_pages: ::c_long = 192; +pub const SYS_epoll_create: ::c_long = 193; +pub const SYS_epoll_ctl: ::c_long = 194; +pub const SYS_epoll_wait: ::c_long = 195; +pub const SYS_ioprio_set: ::c_long = 196; +pub const SYS_getppid: ::c_long = 197; +pub const SYS_sigaction: ::c_long = 198; +pub const SYS_sgetmask: ::c_long = 199; +pub const SYS_ssetmask: ::c_long = 200; +pub const SYS_sigsuspend: ::c_long = 201; +pub const SYS_oldlstat: ::c_long = 202; +pub const SYS_uselib: ::c_long = 203; +pub const SYS_readdir: ::c_long = 204; +pub const SYS_readahead: ::c_long = 205; +pub const SYS_socketcall: ::c_long = 206; +pub const SYS_syslog: ::c_long = 207; +pub const SYS_lookup_dcookie: ::c_long = 208; +pub const SYS_fadvise64: ::c_long = 209; +pub const SYS_fadvise64_64: ::c_long = 210; +pub const SYS_tgkill: ::c_long = 211; +pub const SYS_waitpid: ::c_long = 212; +pub const SYS_swapoff: ::c_long = 213; +pub const SYS_sysinfo: ::c_long = 214; +pub const SYS_ipc: ::c_long = 215; +pub const SYS_sigreturn: ::c_long = 216; +pub const SYS_clone: ::c_long = 217; +pub const SYS_ioprio_get: ::c_long = 218; +pub const SYS_adjtimex: ::c_long = 219; +pub const SYS_sigprocmask: ::c_long = 220; +pub const SYS_create_module: ::c_long = 221; +pub const SYS_delete_module: ::c_long = 222; +pub const SYS_get_kernel_syms: ::c_long = 223; +pub const SYS_getpgid: ::c_long = 224; +pub const SYS_bdflush: ::c_long = 225; +pub const SYS_sysfs: ::c_long = 226; +pub const SYS_afs_syscall: ::c_long = 227; +pub const SYS_setfsuid: ::c_long = 228; +pub const SYS_setfsgid: ::c_long = 229; +pub const SYS__newselect: ::c_long = 230; +pub const SYS_splice: ::c_long = 232; +pub const SYS_stime: ::c_long = 233; +pub const SYS_statfs64: ::c_long = 234; +pub const SYS_fstatfs64: ::c_long = 235; +pub const SYS__llseek: ::c_long = 236; +pub const SYS_mlock: ::c_long = 237; +pub const SYS_munlock: ::c_long = 238; +pub const SYS_mlockall: ::c_long = 239; +pub const SYS_munlockall: ::c_long = 240; +pub const SYS_sched_setparam: ::c_long = 241; +pub const SYS_sched_getparam: ::c_long = 242; +pub const SYS_sched_setscheduler: ::c_long = 243; +pub const SYS_sched_getscheduler: ::c_long = 244; +pub const SYS_sched_yield: ::c_long = 245; +pub const SYS_sched_get_priority_max: ::c_long = 246; +pub const SYS_sched_get_priority_min: ::c_long = 247; +pub const SYS_sched_rr_get_interval: ::c_long = 248; +pub const SYS_nanosleep: ::c_long = 249; +pub const SYS_mremap: ::c_long = 250; +pub const SYS__sysctl: ::c_long = 251; +pub const SYS_getsid: ::c_long = 252; +pub const SYS_fdatasync: ::c_long = 253; +pub const SYS_nfsservctl: ::c_long = 254; +pub const SYS_sync_file_range: ::c_long = 255; +pub const SYS_clock_settime: ::c_long = 256; +pub const SYS_clock_gettime: ::c_long = 257; +pub const SYS_clock_getres: ::c_long = 258; +pub const SYS_clock_nanosleep: ::c_long = 259; +pub const SYS_sched_getaffinity: ::c_long = 260; +pub const SYS_sched_setaffinity: ::c_long = 261; +pub const SYS_timer_settime: ::c_long = 262; +pub const SYS_timer_gettime: ::c_long = 263; +pub const SYS_timer_getoverrun: ::c_long = 264; +pub const SYS_timer_delete: ::c_long = 265; +pub const SYS_timer_create: ::c_long = 266; +pub const SYS_io_setup: ::c_long = 268; +pub const SYS_io_destroy: ::c_long = 269; +pub const SYS_io_submit: ::c_long = 270; +pub const SYS_io_cancel: ::c_long = 271; +pub const SYS_io_getevents: ::c_long = 272; +pub const SYS_mq_open: ::c_long = 273; +pub const SYS_mq_unlink: ::c_long = 274; +pub const SYS_mq_timedsend: ::c_long = 275; +pub const SYS_mq_timedreceive: ::c_long = 276; +pub const SYS_mq_notify: ::c_long = 277; +pub const SYS_mq_getsetattr: ::c_long = 278; +pub const SYS_waitid: ::c_long = 279; +pub const SYS_tee: ::c_long = 280; +pub const SYS_add_key: ::c_long = 281; +pub const SYS_request_key: ::c_long = 282; +pub const SYS_keyctl: ::c_long = 283; +pub const SYS_openat: ::c_long = 284; +pub const SYS_mkdirat: ::c_long = 285; +pub const SYS_mknodat: ::c_long = 286; +pub const SYS_fchownat: ::c_long = 287; +pub const SYS_futimesat: ::c_long = 288; +pub const SYS_fstatat64: ::c_long = 289; +pub const SYS_unlinkat: ::c_long = 290; +pub const SYS_renameat: ::c_long = 291; +pub const SYS_linkat: ::c_long = 292; +pub const SYS_symlinkat: ::c_long = 293; +pub const SYS_readlinkat: ::c_long = 294; +pub const SYS_fchmodat: ::c_long = 295; +pub const SYS_faccessat: ::c_long = 296; +pub const SYS_pselect6: ::c_long = 297; +pub const SYS_ppoll: ::c_long = 298; +pub const SYS_unshare: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_get_robust_list: ::c_long = 301; +pub const SYS_migrate_pages: ::c_long = 302; +pub const SYS_mbind: ::c_long = 303; +pub const SYS_get_mempolicy: ::c_long = 304; +pub const SYS_set_mempolicy: ::c_long = 305; +pub const SYS_kexec_load: ::c_long = 306; +pub const SYS_move_pages: ::c_long = 307; +pub const SYS_getcpu: ::c_long = 308; +pub const SYS_epoll_pwait: ::c_long = 309; +pub const SYS_utimensat: ::c_long = 310; +pub const SYS_signalfd: ::c_long = 311; +pub const SYS_timerfd_create: ::c_long = 312; +pub const SYS_eventfd: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_timerfd_settime: ::c_long = 315; +pub const SYS_timerfd_gettime: ::c_long = 316; +pub const SYS_signalfd4: ::c_long = 317; +pub const SYS_eventfd2: ::c_long = 318; +pub const SYS_epoll_create1: ::c_long = 319; +pub const SYS_dup3: ::c_long = 320; +pub const SYS_pipe2: ::c_long = 321; +pub const SYS_inotify_init1: ::c_long = 322; +pub const SYS_accept4: ::c_long = 323; +pub const SYS_preadv: ::c_long = 324; +pub const SYS_pwritev: ::c_long = 325; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 326; +pub const SYS_perf_event_open: ::c_long = 327; +pub const SYS_recvmmsg: ::c_long = 328; +pub const SYS_fanotify_init: ::c_long = 329; +pub const SYS_fanotify_mark: ::c_long = 330; +pub const SYS_prlimit64: ::c_long = 331; +pub const SYS_name_to_handle_at: ::c_long = 332; +pub const SYS_open_by_handle_at: ::c_long = 333; +pub const SYS_clock_adjtime: ::c_long = 334; +pub const SYS_syncfs: ::c_long = 335; +pub const SYS_sendmmsg: ::c_long = 336; +pub const SYS_setns: ::c_long = 337; +pub const SYS_process_vm_readv: ::c_long = 338; +pub const SYS_process_vm_writev: ::c_long = 339; +pub const SYS_kern_features: ::c_long = 340; +pub const SYS_kcmp: ::c_long = 341; +pub const SYS_finit_module: ::c_long = 342; +pub const SYS_sched_setattr: ::c_long = 343; +pub const SYS_sched_getattr: ::c_long = 344; +pub const SYS_renameat2: ::c_long = 345; +pub const SYS_seccomp: ::c_long = 346; +pub const SYS_getrandom: ::c_long = 347; +pub const SYS_memfd_create: ::c_long = 348; +pub const SYS_bpf: ::c_long = 349; +pub const SYS_execveat: ::c_long = 350; +pub const SYS_membarrier: ::c_long = 351; +pub const SYS_userfaultfd: ::c_long = 352; +pub const SYS_bind: ::c_long = 353; +pub const SYS_listen: ::c_long = 354; +pub const SYS_setsockopt: ::c_long = 355; +pub const SYS_mlock2: ::c_long = 356; +pub const SYS_copy_file_range: ::c_long = 357; +pub const SYS_preadv2: ::c_long = 358; +pub const SYS_pwritev2: ::c_long = 359; +pub const SYS_statx: ::c_long = 360; +pub const SYS_rseq: ::c_long = 365; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +// Reserved in the kernel, but not actually implemented yet +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs new file mode 100644 index 00000000..ba3075ed --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs @@ -0,0 +1,24 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } +} + +s! { + #[repr(align(8))] + pub struct clone_args { + pub flags: ::c_ulonglong, + pub pidfd: ::c_ulonglong, + pub child_tid: ::c_ulonglong, + pub parent_tid: ::c_ulonglong, + pub exit_signal: ::c_ulonglong, + pub stack: ::c_ulonglong, + pub stack_size: ::c_ulonglong, + pub tls: ::c_ulonglong, + pub set_tid: ::c_ulonglong, + pub set_tid_size: ::c_ulonglong, + pub cgroup: ::c_ulonglong, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs new file mode 100644 index 00000000..609c7442 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs @@ -0,0 +1,824 @@ +//! x86_64-specific definitions for 64-bit linux-like values + +pub type c_char = i8; +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = i64; +pub type greg_t = i64; +pub type suseconds_t = i64; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statfs { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + f_spare: [::__fsword_t; 5], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [u64; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: i64, + pub st_mtime: ::time_t, + pub st_mtime_nsec: i64, + pub st_ctime: ::time_t, + pub st_ctime_nsec: i64, + __unused: [i64; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: i64, + pub st_mtime: ::time_t, + pub st_mtime_nsec: i64, + pub st_ctime: ::time_t, + pub st_ctime_nsec: i64, + __reserved: [i64; 3], + } + + pub struct statfs64 { + pub f_type: ::__fsword_t, + pub f_bsize: ::__fsword_t, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::__fsword_t, + pub f_frsize: ::__fsword_t, + pub f_flags: ::__fsword_t, + pub f_spare: [::__fsword_t; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + #[cfg(target_pointer_width = "32")] + __size: [u32; 8], + #[cfg(target_pointer_width = "64")] + __size: [u64; 7] + } + + pub struct _libc_fpxreg { + pub significand: [u16; 4], + pub exponent: u16, + __private: [u16; 3], + } + + pub struct _libc_xmmreg { + pub element: [u32; 4], + } + + pub struct _libc_fpstate { + pub cwd: u16, + pub swd: u16, + pub ftw: u16, + pub fop: u16, + pub rip: u64, + pub rdp: u64, + pub mxcsr: u32, + pub mxcr_mask: u32, + pub _st: [_libc_fpxreg; 8], + pub _xmm: [_libc_xmmreg; 16], + __private: [u64; 12], + } + + pub struct user_regs_struct { + pub r15: ::c_ulonglong, + pub r14: ::c_ulonglong, + pub r13: ::c_ulonglong, + pub r12: ::c_ulonglong, + pub rbp: ::c_ulonglong, + pub rbx: ::c_ulonglong, + pub r11: ::c_ulonglong, + pub r10: ::c_ulonglong, + pub r9: ::c_ulonglong, + pub r8: ::c_ulonglong, + pub rax: ::c_ulonglong, + pub rcx: ::c_ulonglong, + pub rdx: ::c_ulonglong, + pub rsi: ::c_ulonglong, + pub rdi: ::c_ulonglong, + pub orig_rax: ::c_ulonglong, + pub rip: ::c_ulonglong, + pub cs: ::c_ulonglong, + pub eflags: ::c_ulonglong, + pub rsp: ::c_ulonglong, + pub ss: ::c_ulonglong, + pub fs_base: ::c_ulonglong, + pub gs_base: ::c_ulonglong, + pub ds: ::c_ulonglong, + pub es: ::c_ulonglong, + pub fs: ::c_ulonglong, + pub gs: ::c_ulonglong, + } + + pub struct user { + pub regs: user_regs_struct, + pub u_fpvalid: ::c_int, + pub i387: user_fpregs_struct, + pub u_tsize: ::c_ulonglong, + pub u_dsize: ::c_ulonglong, + pub u_ssize: ::c_ulonglong, + pub start_code: ::c_ulonglong, + pub start_stack: ::c_ulonglong, + pub signal: ::c_longlong, + __reserved: ::c_int, + #[cfg(target_pointer_width = "32")] + __pad1: u32, + pub u_ar0: *mut user_regs_struct, + #[cfg(target_pointer_width = "32")] + __pad2: u32, + pub u_fpstate: *mut user_fpregs_struct, + pub magic: ::c_ulonglong, + pub u_comm: [::c_char; 32], + pub u_debugreg: [::c_ulonglong; 8], + } + + pub struct mcontext_t { + pub gregs: [greg_t; 23], + pub fpregs: *mut _libc_fpstate, + __private: [u64; 8], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: u64, + __unused2: u64 + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: u64, + __unused5: u64 + } + + pub struct ptrace_rseq_configuration { + pub rseq_abi_pointer: ::__u64, + pub rseq_abi_size: ::__u32, + pub signature: ::__u32, + pub flags: ::__u32, + pub pad: ::__u32, + } +} + +s_no_extra_traits! { + pub struct user_fpregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub ftw: ::c_ushort, + pub fop: ::c_ushort, + pub rip: ::c_ulonglong, + pub rdp: ::c_ulonglong, + pub mxcsr: ::c_uint, + pub mxcr_mask: ::c_uint, + pub st_space: [::c_uint; 32], + pub xmm_space: [::c_uint; 64], + padding: [::c_uint; 24], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + // FIXME: the shadow stack field requires glibc >= 2.28. + // Re-add once we drop compatibility with glibc versions older than + // 2.28. + // + // __ssp: [::c_ulonglong; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpregs_struct { + fn eq(&self, other: &user_fpregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.ftw == other.ftw + && self.fop == other.fop + && self.rip == other.rip + && self.rdp == other.rdp + && self.mxcsr == other.mxcsr + && self.mxcr_mask == other.mxcr_mask + && self.st_space == other.st_space + && self + .xmm_space + .iter() + .zip(other.xmm_space.iter()) + .all(|(a,b)| a == b) + // Ignore padding field + } + } + + impl Eq for user_fpregs_struct {} + + impl ::fmt::Debug for user_fpregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpregs_struct") + .field("cwd", &self.cwd) + .field("ftw", &self.ftw) + .field("fop", &self.fop) + .field("rip", &self.rip) + .field("rdp", &self.rdp) + .field("mxcsr", &self.mxcsr) + .field("mxcr_mask", &self.mxcr_mask) + .field("st_space", &self.st_space) + // FIXME: .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.ftw.hash(state); + self.fop.hash(state); + self.rip.hash(state); + self.rdp.hash(state); + self.mxcsr.hash(state); + self.mxcr_mask.hash(state); + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + // Ignore __private field + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + // Ignore __private field + } + } + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = 31; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const PTRACE_DETACH: ::c_uint = 17; +pub const PTRACE_GET_RSEQ_CONFIGURATION: ::c_uint = 0x420f; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_32BIT: ::c_int = 0x0040; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; +pub const PTRACE_PEEKSIGINFO_SHARED: ::c_uint = 1; +pub const PTRACE_SYSEMU: ::c_uint = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; + +pub const PR_GET_SPECULATION_CTRL: ::c_int = 52; +pub const PR_SET_SPECULATION_CTRL: ::c_int = 53; +pub const PR_SPEC_NOT_AFFECTED: ::c_uint = 0; +pub const PR_SPEC_PRCTL: ::c_uint = 1 << 0; +pub const PR_SPEC_ENABLE: ::c_uint = 1 << 1; +pub const PR_SPEC_DISABLE: ::c_uint = 1 << 2; +pub const PR_SPEC_FORCE_DISABLE: ::c_uint = 1 << 3; +pub const PR_SPEC_DISABLE_NOEXEC: ::c_uint = 1 << 4; +pub const PR_SPEC_STORE_BYPASS: ::c_int = 0; +pub const PR_SPEC_INDIRECT_BRANCH: ::c_int = 1; +// FIXME: perharps for later +//pub const PR_SPEC_L1D_FLUSH: ::c_int = 2; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; +pub const EXTPROC: ::tcflag_t = 0x00010000; + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_R8: ::c_int = 0; +pub const REG_R9: ::c_int = 1; +pub const REG_R10: ::c_int = 2; +pub const REG_R11: ::c_int = 3; +pub const REG_R12: ::c_int = 4; +pub const REG_R13: ::c_int = 5; +pub const REG_R14: ::c_int = 6; +pub const REG_R15: ::c_int = 7; +pub const REG_RDI: ::c_int = 8; +pub const REG_RSI: ::c_int = 9; +pub const REG_RBP: ::c_int = 10; +pub const REG_RBX: ::c_int = 11; +pub const REG_RDX: ::c_int = 12; +pub const REG_RAX: ::c_int = 13; +pub const REG_RCX: ::c_int = 14; +pub const REG_RSP: ::c_int = 15; +pub const REG_RIP: ::c_int = 16; +pub const REG_EFL: ::c_int = 17; +pub const REG_CSGSFS: ::c_int = 18; +pub const REG_ERR: ::c_int = 19; +pub const REG_TRAPNO: ::c_int = 20; +pub const REG_OLDMASK: ::c_int = 21; +pub const REG_CR2: ::c_int = 22; + +extern "C" { + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; + pub fn makecontext(ucp: *mut ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); + pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int; + pub fn iopl(level: ::c_int) -> ::c_int; + pub fn ioperm(from: ::c_ulong, num: ::c_ulong, turn_on: ::c_int) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod x32; + pub use self::x32::*; + } else { + mod not_x32; + pub use self::not_x32::*; + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs new file mode 100644 index 00000000..3831dfad --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs @@ -0,0 +1,451 @@ +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +align_const! { + #[cfg(target_endian = "little")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "little")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + #[cfg(target_endian = "big")] + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +// Syscall table + +pub const SYS_read: ::c_long = 0; +pub const SYS_write: ::c_long = 1; +pub const SYS_open: ::c_long = 2; +pub const SYS_close: ::c_long = 3; +pub const SYS_stat: ::c_long = 4; +pub const SYS_fstat: ::c_long = 5; +pub const SYS_lstat: ::c_long = 6; +pub const SYS_poll: ::c_long = 7; +pub const SYS_lseek: ::c_long = 8; +pub const SYS_mmap: ::c_long = 9; +pub const SYS_mprotect: ::c_long = 10; +pub const SYS_munmap: ::c_long = 11; +pub const SYS_brk: ::c_long = 12; +pub const SYS_rt_sigaction: ::c_long = 13; +pub const SYS_rt_sigprocmask: ::c_long = 14; +pub const SYS_rt_sigreturn: ::c_long = 15; +pub const SYS_ioctl: ::c_long = 16; +pub const SYS_pread64: ::c_long = 17; +pub const SYS_pwrite64: ::c_long = 18; +pub const SYS_readv: ::c_long = 19; +pub const SYS_writev: ::c_long = 20; +pub const SYS_access: ::c_long = 21; +pub const SYS_pipe: ::c_long = 22; +pub const SYS_select: ::c_long = 23; +pub const SYS_sched_yield: ::c_long = 24; +pub const SYS_mremap: ::c_long = 25; +pub const SYS_msync: ::c_long = 26; +pub const SYS_mincore: ::c_long = 27; +pub const SYS_madvise: ::c_long = 28; +pub const SYS_shmget: ::c_long = 29; +pub const SYS_shmat: ::c_long = 30; +pub const SYS_shmctl: ::c_long = 31; +pub const SYS_dup: ::c_long = 32; +pub const SYS_dup2: ::c_long = 33; +pub const SYS_pause: ::c_long = 34; +pub const SYS_nanosleep: ::c_long = 35; +pub const SYS_getitimer: ::c_long = 36; +pub const SYS_alarm: ::c_long = 37; +pub const SYS_setitimer: ::c_long = 38; +pub const SYS_getpid: ::c_long = 39; +pub const SYS_sendfile: ::c_long = 40; +pub const SYS_socket: ::c_long = 41; +pub const SYS_connect: ::c_long = 42; +pub const SYS_accept: ::c_long = 43; +pub const SYS_sendto: ::c_long = 44; +pub const SYS_recvfrom: ::c_long = 45; +pub const SYS_sendmsg: ::c_long = 46; +pub const SYS_recvmsg: ::c_long = 47; +pub const SYS_shutdown: ::c_long = 48; +pub const SYS_bind: ::c_long = 49; +pub const SYS_listen: ::c_long = 50; +pub const SYS_getsockname: ::c_long = 51; +pub const SYS_getpeername: ::c_long = 52; +pub const SYS_socketpair: ::c_long = 53; +pub const SYS_setsockopt: ::c_long = 54; +pub const SYS_getsockopt: ::c_long = 55; +pub const SYS_clone: ::c_long = 56; +pub const SYS_fork: ::c_long = 57; +pub const SYS_vfork: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_exit: ::c_long = 60; +pub const SYS_wait4: ::c_long = 61; +pub const SYS_kill: ::c_long = 62; +pub const SYS_uname: ::c_long = 63; +pub const SYS_semget: ::c_long = 64; +pub const SYS_semop: ::c_long = 65; +pub const SYS_semctl: ::c_long = 66; +pub const SYS_shmdt: ::c_long = 67; +pub const SYS_msgget: ::c_long = 68; +pub const SYS_msgsnd: ::c_long = 69; +pub const SYS_msgrcv: ::c_long = 70; +pub const SYS_msgctl: ::c_long = 71; +pub const SYS_fcntl: ::c_long = 72; +pub const SYS_flock: ::c_long = 73; +pub const SYS_fsync: ::c_long = 74; +pub const SYS_fdatasync: ::c_long = 75; +pub const SYS_truncate: ::c_long = 76; +pub const SYS_ftruncate: ::c_long = 77; +pub const SYS_getdents: ::c_long = 78; +pub const SYS_getcwd: ::c_long = 79; +pub const SYS_chdir: ::c_long = 80; +pub const SYS_fchdir: ::c_long = 81; +pub const SYS_rename: ::c_long = 82; +pub const SYS_mkdir: ::c_long = 83; +pub const SYS_rmdir: ::c_long = 84; +pub const SYS_creat: ::c_long = 85; +pub const SYS_link: ::c_long = 86; +pub const SYS_unlink: ::c_long = 87; +pub const SYS_symlink: ::c_long = 88; +pub const SYS_readlink: ::c_long = 89; +pub const SYS_chmod: ::c_long = 90; +pub const SYS_fchmod: ::c_long = 91; +pub const SYS_chown: ::c_long = 92; +pub const SYS_fchown: ::c_long = 93; +pub const SYS_lchown: ::c_long = 94; +pub const SYS_umask: ::c_long = 95; +pub const SYS_gettimeofday: ::c_long = 96; +pub const SYS_getrlimit: ::c_long = 97; +pub const SYS_getrusage: ::c_long = 98; +pub const SYS_sysinfo: ::c_long = 99; +pub const SYS_times: ::c_long = 100; +pub const SYS_ptrace: ::c_long = 101; +pub const SYS_getuid: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_getgid: ::c_long = 104; +pub const SYS_setuid: ::c_long = 105; +pub const SYS_setgid: ::c_long = 106; +pub const SYS_geteuid: ::c_long = 107; +pub const SYS_getegid: ::c_long = 108; +pub const SYS_setpgid: ::c_long = 109; +pub const SYS_getppid: ::c_long = 110; +pub const SYS_getpgrp: ::c_long = 111; +pub const SYS_setsid: ::c_long = 112; +pub const SYS_setreuid: ::c_long = 113; +pub const SYS_setregid: ::c_long = 114; +pub const SYS_getgroups: ::c_long = 115; +pub const SYS_setgroups: ::c_long = 116; +pub const SYS_setresuid: ::c_long = 117; +pub const SYS_getresuid: ::c_long = 118; +pub const SYS_setresgid: ::c_long = 119; +pub const SYS_getresgid: ::c_long = 120; +pub const SYS_getpgid: ::c_long = 121; +pub const SYS_setfsuid: ::c_long = 122; +pub const SYS_setfsgid: ::c_long = 123; +pub const SYS_getsid: ::c_long = 124; +pub const SYS_capget: ::c_long = 125; +pub const SYS_capset: ::c_long = 126; +pub const SYS_rt_sigpending: ::c_long = 127; +pub const SYS_rt_sigtimedwait: ::c_long = 128; +pub const SYS_rt_sigqueueinfo: ::c_long = 129; +pub const SYS_rt_sigsuspend: ::c_long = 130; +pub const SYS_sigaltstack: ::c_long = 131; +pub const SYS_utime: ::c_long = 132; +pub const SYS_mknod: ::c_long = 133; +pub const SYS_uselib: ::c_long = 134; +pub const SYS_personality: ::c_long = 135; +pub const SYS_ustat: ::c_long = 136; +pub const SYS_statfs: ::c_long = 137; +pub const SYS_fstatfs: ::c_long = 138; +pub const SYS_sysfs: ::c_long = 139; +pub const SYS_getpriority: ::c_long = 140; +pub const SYS_setpriority: ::c_long = 141; +pub const SYS_sched_setparam: ::c_long = 142; +pub const SYS_sched_getparam: ::c_long = 143; +pub const SYS_sched_setscheduler: ::c_long = 144; +pub const SYS_sched_getscheduler: ::c_long = 145; +pub const SYS_sched_get_priority_max: ::c_long = 146; +pub const SYS_sched_get_priority_min: ::c_long = 147; +pub const SYS_sched_rr_get_interval: ::c_long = 148; +pub const SYS_mlock: ::c_long = 149; +pub const SYS_munlock: ::c_long = 150; +pub const SYS_mlockall: ::c_long = 151; +pub const SYS_munlockall: ::c_long = 152; +pub const SYS_vhangup: ::c_long = 153; +pub const SYS_modify_ldt: ::c_long = 154; +pub const SYS_pivot_root: ::c_long = 155; +pub const SYS__sysctl: ::c_long = 156; +pub const SYS_prctl: ::c_long = 157; +pub const SYS_arch_prctl: ::c_long = 158; +pub const SYS_adjtimex: ::c_long = 159; +pub const SYS_setrlimit: ::c_long = 160; +pub const SYS_chroot: ::c_long = 161; +pub const SYS_sync: ::c_long = 162; +pub const SYS_acct: ::c_long = 163; +pub const SYS_settimeofday: ::c_long = 164; +pub const SYS_mount: ::c_long = 165; +pub const SYS_umount2: ::c_long = 166; +pub const SYS_swapon: ::c_long = 167; +pub const SYS_swapoff: ::c_long = 168; +pub const SYS_reboot: ::c_long = 169; +pub const SYS_sethostname: ::c_long = 170; +pub const SYS_setdomainname: ::c_long = 171; +pub const SYS_iopl: ::c_long = 172; +pub const SYS_ioperm: ::c_long = 173; +pub const SYS_create_module: ::c_long = 174; +pub const SYS_init_module: ::c_long = 175; +pub const SYS_delete_module: ::c_long = 176; +pub const SYS_get_kernel_syms: ::c_long = 177; +pub const SYS_query_module: ::c_long = 178; +pub const SYS_quotactl: ::c_long = 179; +pub const SYS_nfsservctl: ::c_long = 180; +pub const SYS_getpmsg: ::c_long = 181; +pub const SYS_putpmsg: ::c_long = 182; +pub const SYS_afs_syscall: ::c_long = 183; +pub const SYS_tuxcall: ::c_long = 184; +pub const SYS_security: ::c_long = 185; +pub const SYS_gettid: ::c_long = 186; +pub const SYS_readahead: ::c_long = 187; +pub const SYS_setxattr: ::c_long = 188; +pub const SYS_lsetxattr: ::c_long = 189; +pub const SYS_fsetxattr: ::c_long = 190; +pub const SYS_getxattr: ::c_long = 191; +pub const SYS_lgetxattr: ::c_long = 192; +pub const SYS_fgetxattr: ::c_long = 193; +pub const SYS_listxattr: ::c_long = 194; +pub const SYS_llistxattr: ::c_long = 195; +pub const SYS_flistxattr: ::c_long = 196; +pub const SYS_removexattr: ::c_long = 197; +pub const SYS_lremovexattr: ::c_long = 198; +pub const SYS_fremovexattr: ::c_long = 199; +pub const SYS_tkill: ::c_long = 200; +pub const SYS_time: ::c_long = 201; +pub const SYS_futex: ::c_long = 202; +pub const SYS_sched_setaffinity: ::c_long = 203; +pub const SYS_sched_getaffinity: ::c_long = 204; +pub const SYS_set_thread_area: ::c_long = 205; +pub const SYS_io_setup: ::c_long = 206; +pub const SYS_io_destroy: ::c_long = 207; +pub const SYS_io_getevents: ::c_long = 208; +pub const SYS_io_submit: ::c_long = 209; +pub const SYS_io_cancel: ::c_long = 210; +pub const SYS_get_thread_area: ::c_long = 211; +pub const SYS_lookup_dcookie: ::c_long = 212; +pub const SYS_epoll_create: ::c_long = 213; +pub const SYS_epoll_ctl_old: ::c_long = 214; +pub const SYS_epoll_wait_old: ::c_long = 215; +pub const SYS_remap_file_pages: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_set_tid_address: ::c_long = 218; +pub const SYS_restart_syscall: ::c_long = 219; +pub const SYS_semtimedop: ::c_long = 220; +pub const SYS_fadvise64: ::c_long = 221; +pub const SYS_timer_create: ::c_long = 222; +pub const SYS_timer_settime: ::c_long = 223; +pub const SYS_timer_gettime: ::c_long = 224; +pub const SYS_timer_getoverrun: ::c_long = 225; +pub const SYS_timer_delete: ::c_long = 226; +pub const SYS_clock_settime: ::c_long = 227; +pub const SYS_clock_gettime: ::c_long = 228; +pub const SYS_clock_getres: ::c_long = 229; +pub const SYS_clock_nanosleep: ::c_long = 230; +pub const SYS_exit_group: ::c_long = 231; +pub const SYS_epoll_wait: ::c_long = 232; +pub const SYS_epoll_ctl: ::c_long = 233; +pub const SYS_tgkill: ::c_long = 234; +pub const SYS_utimes: ::c_long = 235; +pub const SYS_vserver: ::c_long = 236; +pub const SYS_mbind: ::c_long = 237; +pub const SYS_set_mempolicy: ::c_long = 238; +pub const SYS_get_mempolicy: ::c_long = 239; +pub const SYS_mq_open: ::c_long = 240; +pub const SYS_mq_unlink: ::c_long = 241; +pub const SYS_mq_timedsend: ::c_long = 242; +pub const SYS_mq_timedreceive: ::c_long = 243; +pub const SYS_mq_notify: ::c_long = 244; +pub const SYS_mq_getsetattr: ::c_long = 245; +pub const SYS_kexec_load: ::c_long = 246; +pub const SYS_waitid: ::c_long = 247; +pub const SYS_add_key: ::c_long = 248; +pub const SYS_request_key: ::c_long = 249; +pub const SYS_keyctl: ::c_long = 250; +pub const SYS_ioprio_set: ::c_long = 251; +pub const SYS_ioprio_get: ::c_long = 252; +pub const SYS_inotify_init: ::c_long = 253; +pub const SYS_inotify_add_watch: ::c_long = 254; +pub const SYS_inotify_rm_watch: ::c_long = 255; +pub const SYS_migrate_pages: ::c_long = 256; +pub const SYS_openat: ::c_long = 257; +pub const SYS_mkdirat: ::c_long = 258; +pub const SYS_mknodat: ::c_long = 259; +pub const SYS_fchownat: ::c_long = 260; +pub const SYS_futimesat: ::c_long = 261; +pub const SYS_newfstatat: ::c_long = 262; +pub const SYS_unlinkat: ::c_long = 263; +pub const SYS_renameat: ::c_long = 264; +pub const SYS_linkat: ::c_long = 265; +pub const SYS_symlinkat: ::c_long = 266; +pub const SYS_readlinkat: ::c_long = 267; +pub const SYS_fchmodat: ::c_long = 268; +pub const SYS_faccessat: ::c_long = 269; +pub const SYS_pselect6: ::c_long = 270; +pub const SYS_ppoll: ::c_long = 271; +pub const SYS_unshare: ::c_long = 272; +pub const SYS_set_robust_list: ::c_long = 273; +pub const SYS_get_robust_list: ::c_long = 274; +pub const SYS_splice: ::c_long = 275; +pub const SYS_tee: ::c_long = 276; +pub const SYS_sync_file_range: ::c_long = 277; +pub const SYS_vmsplice: ::c_long = 278; +pub const SYS_move_pages: ::c_long = 279; +pub const SYS_utimensat: ::c_long = 280; +pub const SYS_epoll_pwait: ::c_long = 281; +pub const SYS_signalfd: ::c_long = 282; +pub const SYS_timerfd_create: ::c_long = 283; +pub const SYS_eventfd: ::c_long = 284; +pub const SYS_fallocate: ::c_long = 285; +pub const SYS_timerfd_settime: ::c_long = 286; +pub const SYS_timerfd_gettime: ::c_long = 287; +pub const SYS_accept4: ::c_long = 288; +pub const SYS_signalfd4: ::c_long = 289; +pub const SYS_eventfd2: ::c_long = 290; +pub const SYS_epoll_create1: ::c_long = 291; +pub const SYS_dup3: ::c_long = 292; +pub const SYS_pipe2: ::c_long = 293; +pub const SYS_inotify_init1: ::c_long = 294; +pub const SYS_preadv: ::c_long = 295; +pub const SYS_pwritev: ::c_long = 296; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 297; +pub const SYS_perf_event_open: ::c_long = 298; +pub const SYS_recvmmsg: ::c_long = 299; +pub const SYS_fanotify_init: ::c_long = 300; +pub const SYS_fanotify_mark: ::c_long = 301; +pub const SYS_prlimit64: ::c_long = 302; +pub const SYS_name_to_handle_at: ::c_long = 303; +pub const SYS_open_by_handle_at: ::c_long = 304; +pub const SYS_clock_adjtime: ::c_long = 305; +pub const SYS_syncfs: ::c_long = 306; +pub const SYS_sendmmsg: ::c_long = 307; +pub const SYS_setns: ::c_long = 308; +pub const SYS_getcpu: ::c_long = 309; +pub const SYS_process_vm_readv: ::c_long = 310; +pub const SYS_process_vm_writev: ::c_long = 311; +pub const SYS_kcmp: ::c_long = 312; +pub const SYS_finit_module: ::c_long = 313; +pub const SYS_sched_setattr: ::c_long = 314; +pub const SYS_sched_getattr: ::c_long = 315; +pub const SYS_renameat2: ::c_long = 316; +pub const SYS_seccomp: ::c_long = 317; +pub const SYS_getrandom: ::c_long = 318; +pub const SYS_memfd_create: ::c_long = 319; +pub const SYS_kexec_file_load: ::c_long = 320; +pub const SYS_bpf: ::c_long = 321; +pub const SYS_execveat: ::c_long = 322; +pub const SYS_userfaultfd: ::c_long = 323; +pub const SYS_membarrier: ::c_long = 324; +pub const SYS_mlock2: ::c_long = 325; +pub const SYS_copy_file_range: ::c_long = 326; +pub const SYS_preadv2: ::c_long = 327; +pub const SYS_pwritev2: ::c_long = 328; +pub const SYS_pkey_mprotect: ::c_long = 329; +pub const SYS_pkey_alloc: ::c_long = 330; +pub const SYS_pkey_free: ::c_long = 331; +pub const SYS_statx: ::c_long = 332; +pub const SYS_rseq: ::c_long = 334; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs new file mode 100644 index 00000000..06aa0da2 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs @@ -0,0 +1,404 @@ +use pthread_mutex_t; + +pub type c_long = i32; +pub type c_ulong = u32; + +s! { + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 44; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + +align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +// Syscall table + +pub const __X32_SYSCALL_BIT: ::c_long = 0x40000000; + +pub const SYS_read: ::c_long = __X32_SYSCALL_BIT + 0; +pub const SYS_write: ::c_long = __X32_SYSCALL_BIT + 1; +pub const SYS_open: ::c_long = __X32_SYSCALL_BIT + 2; +pub const SYS_close: ::c_long = __X32_SYSCALL_BIT + 3; +pub const SYS_stat: ::c_long = __X32_SYSCALL_BIT + 4; +pub const SYS_fstat: ::c_long = __X32_SYSCALL_BIT + 5; +pub const SYS_lstat: ::c_long = __X32_SYSCALL_BIT + 6; +pub const SYS_poll: ::c_long = __X32_SYSCALL_BIT + 7; +pub const SYS_lseek: ::c_long = __X32_SYSCALL_BIT + 8; +pub const SYS_mmap: ::c_long = __X32_SYSCALL_BIT + 9; +pub const SYS_mprotect: ::c_long = __X32_SYSCALL_BIT + 10; +pub const SYS_munmap: ::c_long = __X32_SYSCALL_BIT + 11; +pub const SYS_brk: ::c_long = __X32_SYSCALL_BIT + 12; +pub const SYS_rt_sigprocmask: ::c_long = __X32_SYSCALL_BIT + 14; +pub const SYS_pread64: ::c_long = __X32_SYSCALL_BIT + 17; +pub const SYS_pwrite64: ::c_long = __X32_SYSCALL_BIT + 18; +pub const SYS_access: ::c_long = __X32_SYSCALL_BIT + 21; +pub const SYS_pipe: ::c_long = __X32_SYSCALL_BIT + 22; +pub const SYS_select: ::c_long = __X32_SYSCALL_BIT + 23; +pub const SYS_sched_yield: ::c_long = __X32_SYSCALL_BIT + 24; +pub const SYS_mremap: ::c_long = __X32_SYSCALL_BIT + 25; +pub const SYS_msync: ::c_long = __X32_SYSCALL_BIT + 26; +pub const SYS_mincore: ::c_long = __X32_SYSCALL_BIT + 27; +pub const SYS_madvise: ::c_long = __X32_SYSCALL_BIT + 28; +pub const SYS_shmget: ::c_long = __X32_SYSCALL_BIT + 29; +pub const SYS_shmat: ::c_long = __X32_SYSCALL_BIT + 30; +pub const SYS_shmctl: ::c_long = __X32_SYSCALL_BIT + 31; +pub const SYS_dup: ::c_long = __X32_SYSCALL_BIT + 32; +pub const SYS_dup2: ::c_long = __X32_SYSCALL_BIT + 33; +pub const SYS_pause: ::c_long = __X32_SYSCALL_BIT + 34; +pub const SYS_nanosleep: ::c_long = __X32_SYSCALL_BIT + 35; +pub const SYS_getitimer: ::c_long = __X32_SYSCALL_BIT + 36; +pub const SYS_alarm: ::c_long = __X32_SYSCALL_BIT + 37; +pub const SYS_setitimer: ::c_long = __X32_SYSCALL_BIT + 38; +pub const SYS_getpid: ::c_long = __X32_SYSCALL_BIT + 39; +pub const SYS_sendfile: ::c_long = __X32_SYSCALL_BIT + 40; +pub const SYS_socket: ::c_long = __X32_SYSCALL_BIT + 41; +pub const SYS_connect: ::c_long = __X32_SYSCALL_BIT + 42; +pub const SYS_accept: ::c_long = __X32_SYSCALL_BIT + 43; +pub const SYS_sendto: ::c_long = __X32_SYSCALL_BIT + 44; +pub const SYS_shutdown: ::c_long = __X32_SYSCALL_BIT + 48; +pub const SYS_bind: ::c_long = __X32_SYSCALL_BIT + 49; +pub const SYS_listen: ::c_long = __X32_SYSCALL_BIT + 50; +pub const SYS_getsockname: ::c_long = __X32_SYSCALL_BIT + 51; +pub const SYS_getpeername: ::c_long = __X32_SYSCALL_BIT + 52; +pub const SYS_socketpair: ::c_long = __X32_SYSCALL_BIT + 53; +pub const SYS_clone: ::c_long = __X32_SYSCALL_BIT + 56; +pub const SYS_fork: ::c_long = __X32_SYSCALL_BIT + 57; +pub const SYS_vfork: ::c_long = __X32_SYSCALL_BIT + 58; +pub const SYS_exit: ::c_long = __X32_SYSCALL_BIT + 60; +pub const SYS_wait4: ::c_long = __X32_SYSCALL_BIT + 61; +pub const SYS_kill: ::c_long = __X32_SYSCALL_BIT + 62; +pub const SYS_uname: ::c_long = __X32_SYSCALL_BIT + 63; +pub const SYS_semget: ::c_long = __X32_SYSCALL_BIT + 64; +pub const SYS_semop: ::c_long = __X32_SYSCALL_BIT + 65; +pub const SYS_semctl: ::c_long = __X32_SYSCALL_BIT + 66; +pub const SYS_shmdt: ::c_long = __X32_SYSCALL_BIT + 67; +pub const SYS_msgget: ::c_long = __X32_SYSCALL_BIT + 68; +pub const SYS_msgsnd: ::c_long = __X32_SYSCALL_BIT + 69; +pub const SYS_msgrcv: ::c_long = __X32_SYSCALL_BIT + 70; +pub const SYS_msgctl: ::c_long = __X32_SYSCALL_BIT + 71; +pub const SYS_fcntl: ::c_long = __X32_SYSCALL_BIT + 72; +pub const SYS_flock: ::c_long = __X32_SYSCALL_BIT + 73; +pub const SYS_fsync: ::c_long = __X32_SYSCALL_BIT + 74; +pub const SYS_fdatasync: ::c_long = __X32_SYSCALL_BIT + 75; +pub const SYS_truncate: ::c_long = __X32_SYSCALL_BIT + 76; +pub const SYS_ftruncate: ::c_long = __X32_SYSCALL_BIT + 77; +pub const SYS_getdents: ::c_long = __X32_SYSCALL_BIT + 78; +pub const SYS_getcwd: ::c_long = __X32_SYSCALL_BIT + 79; +pub const SYS_chdir: ::c_long = __X32_SYSCALL_BIT + 80; +pub const SYS_fchdir: ::c_long = __X32_SYSCALL_BIT + 81; +pub const SYS_rename: ::c_long = __X32_SYSCALL_BIT + 82; +pub const SYS_mkdir: ::c_long = __X32_SYSCALL_BIT + 83; +pub const SYS_rmdir: ::c_long = __X32_SYSCALL_BIT + 84; +pub const SYS_creat: ::c_long = __X32_SYSCALL_BIT + 85; +pub const SYS_link: ::c_long = __X32_SYSCALL_BIT + 86; +pub const SYS_unlink: ::c_long = __X32_SYSCALL_BIT + 87; +pub const SYS_symlink: ::c_long = __X32_SYSCALL_BIT + 88; +pub const SYS_readlink: ::c_long = __X32_SYSCALL_BIT + 89; +pub const SYS_chmod: ::c_long = __X32_SYSCALL_BIT + 90; +pub const SYS_fchmod: ::c_long = __X32_SYSCALL_BIT + 91; +pub const SYS_chown: ::c_long = __X32_SYSCALL_BIT + 92; +pub const SYS_fchown: ::c_long = __X32_SYSCALL_BIT + 93; +pub const SYS_lchown: ::c_long = __X32_SYSCALL_BIT + 94; +pub const SYS_umask: ::c_long = __X32_SYSCALL_BIT + 95; +pub const SYS_gettimeofday: ::c_long = __X32_SYSCALL_BIT + 96; +pub const SYS_getrlimit: ::c_long = __X32_SYSCALL_BIT + 97; +pub const SYS_getrusage: ::c_long = __X32_SYSCALL_BIT + 98; +pub const SYS_sysinfo: ::c_long = __X32_SYSCALL_BIT + 99; +pub const SYS_times: ::c_long = __X32_SYSCALL_BIT + 100; +pub const SYS_getuid: ::c_long = __X32_SYSCALL_BIT + 102; +pub const SYS_syslog: ::c_long = __X32_SYSCALL_BIT + 103; +pub const SYS_getgid: ::c_long = __X32_SYSCALL_BIT + 104; +pub const SYS_setuid: ::c_long = __X32_SYSCALL_BIT + 105; +pub const SYS_setgid: ::c_long = __X32_SYSCALL_BIT + 106; +pub const SYS_geteuid: ::c_long = __X32_SYSCALL_BIT + 107; +pub const SYS_getegid: ::c_long = __X32_SYSCALL_BIT + 108; +pub const SYS_setpgid: ::c_long = __X32_SYSCALL_BIT + 109; +pub const SYS_getppid: ::c_long = __X32_SYSCALL_BIT + 110; +pub const SYS_getpgrp: ::c_long = __X32_SYSCALL_BIT + 111; +pub const SYS_setsid: ::c_long = __X32_SYSCALL_BIT + 112; +pub const SYS_setreuid: ::c_long = __X32_SYSCALL_BIT + 113; +pub const SYS_setregid: ::c_long = __X32_SYSCALL_BIT + 114; +pub const SYS_getgroups: ::c_long = __X32_SYSCALL_BIT + 115; +pub const SYS_setgroups: ::c_long = __X32_SYSCALL_BIT + 116; +pub const SYS_setresuid: ::c_long = __X32_SYSCALL_BIT + 117; +pub const SYS_getresuid: ::c_long = __X32_SYSCALL_BIT + 118; +pub const SYS_setresgid: ::c_long = __X32_SYSCALL_BIT + 119; +pub const SYS_getresgid: ::c_long = __X32_SYSCALL_BIT + 120; +pub const SYS_getpgid: ::c_long = __X32_SYSCALL_BIT + 121; +pub const SYS_setfsuid: ::c_long = __X32_SYSCALL_BIT + 122; +pub const SYS_setfsgid: ::c_long = __X32_SYSCALL_BIT + 123; +pub const SYS_getsid: ::c_long = __X32_SYSCALL_BIT + 124; +pub const SYS_capget: ::c_long = __X32_SYSCALL_BIT + 125; +pub const SYS_capset: ::c_long = __X32_SYSCALL_BIT + 126; +pub const SYS_rt_sigsuspend: ::c_long = __X32_SYSCALL_BIT + 130; +pub const SYS_utime: ::c_long = __X32_SYSCALL_BIT + 132; +pub const SYS_mknod: ::c_long = __X32_SYSCALL_BIT + 133; +pub const SYS_personality: ::c_long = __X32_SYSCALL_BIT + 135; +pub const SYS_ustat: ::c_long = __X32_SYSCALL_BIT + 136; +pub const SYS_statfs: ::c_long = __X32_SYSCALL_BIT + 137; +pub const SYS_fstatfs: ::c_long = __X32_SYSCALL_BIT + 138; +pub const SYS_sysfs: ::c_long = __X32_SYSCALL_BIT + 139; +pub const SYS_getpriority: ::c_long = __X32_SYSCALL_BIT + 140; +pub const SYS_setpriority: ::c_long = __X32_SYSCALL_BIT + 141; +pub const SYS_sched_setparam: ::c_long = __X32_SYSCALL_BIT + 142; +pub const SYS_sched_getparam: ::c_long = __X32_SYSCALL_BIT + 143; +pub const SYS_sched_setscheduler: ::c_long = __X32_SYSCALL_BIT + 144; +pub const SYS_sched_getscheduler: ::c_long = __X32_SYSCALL_BIT + 145; +pub const SYS_sched_get_priority_max: ::c_long = __X32_SYSCALL_BIT + 146; +pub const SYS_sched_get_priority_min: ::c_long = __X32_SYSCALL_BIT + 147; +pub const SYS_sched_rr_get_interval: ::c_long = __X32_SYSCALL_BIT + 148; +pub const SYS_mlock: ::c_long = __X32_SYSCALL_BIT + 149; +pub const SYS_munlock: ::c_long = __X32_SYSCALL_BIT + 150; +pub const SYS_mlockall: ::c_long = __X32_SYSCALL_BIT + 151; +pub const SYS_munlockall: ::c_long = __X32_SYSCALL_BIT + 152; +pub const SYS_vhangup: ::c_long = __X32_SYSCALL_BIT + 153; +pub const SYS_modify_ldt: ::c_long = __X32_SYSCALL_BIT + 154; +pub const SYS_pivot_root: ::c_long = __X32_SYSCALL_BIT + 155; +pub const SYS_prctl: ::c_long = __X32_SYSCALL_BIT + 157; +pub const SYS_arch_prctl: ::c_long = __X32_SYSCALL_BIT + 158; +pub const SYS_adjtimex: ::c_long = __X32_SYSCALL_BIT + 159; +pub const SYS_setrlimit: ::c_long = __X32_SYSCALL_BIT + 160; +pub const SYS_chroot: ::c_long = __X32_SYSCALL_BIT + 161; +pub const SYS_sync: ::c_long = __X32_SYSCALL_BIT + 162; +pub const SYS_acct: ::c_long = __X32_SYSCALL_BIT + 163; +pub const SYS_settimeofday: ::c_long = __X32_SYSCALL_BIT + 164; +pub const SYS_mount: ::c_long = __X32_SYSCALL_BIT + 165; +pub const SYS_umount2: ::c_long = __X32_SYSCALL_BIT + 166; +pub const SYS_swapon: ::c_long = __X32_SYSCALL_BIT + 167; +pub const SYS_swapoff: ::c_long = __X32_SYSCALL_BIT + 168; +pub const SYS_reboot: ::c_long = __X32_SYSCALL_BIT + 169; +pub const SYS_sethostname: ::c_long = __X32_SYSCALL_BIT + 170; +pub const SYS_setdomainname: ::c_long = __X32_SYSCALL_BIT + 171; +pub const SYS_iopl: ::c_long = __X32_SYSCALL_BIT + 172; +pub const SYS_ioperm: ::c_long = __X32_SYSCALL_BIT + 173; +pub const SYS_init_module: ::c_long = __X32_SYSCALL_BIT + 175; +pub const SYS_delete_module: ::c_long = __X32_SYSCALL_BIT + 176; +pub const SYS_quotactl: ::c_long = __X32_SYSCALL_BIT + 179; +pub const SYS_getpmsg: ::c_long = __X32_SYSCALL_BIT + 181; +pub const SYS_putpmsg: ::c_long = __X32_SYSCALL_BIT + 182; +pub const SYS_afs_syscall: ::c_long = __X32_SYSCALL_BIT + 183; +pub const SYS_tuxcall: ::c_long = __X32_SYSCALL_BIT + 184; +pub const SYS_security: ::c_long = __X32_SYSCALL_BIT + 185; +pub const SYS_gettid: ::c_long = __X32_SYSCALL_BIT + 186; +pub const SYS_readahead: ::c_long = __X32_SYSCALL_BIT + 187; +pub const SYS_setxattr: ::c_long = __X32_SYSCALL_BIT + 188; +pub const SYS_lsetxattr: ::c_long = __X32_SYSCALL_BIT + 189; +pub const SYS_fsetxattr: ::c_long = __X32_SYSCALL_BIT + 190; +pub const SYS_getxattr: ::c_long = __X32_SYSCALL_BIT + 191; +pub const SYS_lgetxattr: ::c_long = __X32_SYSCALL_BIT + 192; +pub const SYS_fgetxattr: ::c_long = __X32_SYSCALL_BIT + 193; +pub const SYS_listxattr: ::c_long = __X32_SYSCALL_BIT + 194; +pub const SYS_llistxattr: ::c_long = __X32_SYSCALL_BIT + 195; +pub const SYS_flistxattr: ::c_long = __X32_SYSCALL_BIT + 196; +pub const SYS_removexattr: ::c_long = __X32_SYSCALL_BIT + 197; +pub const SYS_lremovexattr: ::c_long = __X32_SYSCALL_BIT + 198; +pub const SYS_fremovexattr: ::c_long = __X32_SYSCALL_BIT + 199; +pub const SYS_tkill: ::c_long = __X32_SYSCALL_BIT + 200; +pub const SYS_time: ::c_long = __X32_SYSCALL_BIT + 201; +pub const SYS_futex: ::c_long = __X32_SYSCALL_BIT + 202; +pub const SYS_sched_setaffinity: ::c_long = __X32_SYSCALL_BIT + 203; +pub const SYS_sched_getaffinity: ::c_long = __X32_SYSCALL_BIT + 204; +pub const SYS_io_destroy: ::c_long = __X32_SYSCALL_BIT + 207; +pub const SYS_io_getevents: ::c_long = __X32_SYSCALL_BIT + 208; +pub const SYS_io_cancel: ::c_long = __X32_SYSCALL_BIT + 210; +pub const SYS_lookup_dcookie: ::c_long = __X32_SYSCALL_BIT + 212; +pub const SYS_epoll_create: ::c_long = __X32_SYSCALL_BIT + 213; +pub const SYS_remap_file_pages: ::c_long = __X32_SYSCALL_BIT + 216; +pub const SYS_getdents64: ::c_long = __X32_SYSCALL_BIT + 217; +pub const SYS_set_tid_address: ::c_long = __X32_SYSCALL_BIT + 218; +pub const SYS_restart_syscall: ::c_long = __X32_SYSCALL_BIT + 219; +pub const SYS_semtimedop: ::c_long = __X32_SYSCALL_BIT + 220; +pub const SYS_fadvise64: ::c_long = __X32_SYSCALL_BIT + 221; +pub const SYS_timer_settime: ::c_long = __X32_SYSCALL_BIT + 223; +pub const SYS_timer_gettime: ::c_long = __X32_SYSCALL_BIT + 224; +pub const SYS_timer_getoverrun: ::c_long = __X32_SYSCALL_BIT + 225; +pub const SYS_timer_delete: ::c_long = __X32_SYSCALL_BIT + 226; +pub const SYS_clock_settime: ::c_long = __X32_SYSCALL_BIT + 227; +pub const SYS_clock_gettime: ::c_long = __X32_SYSCALL_BIT + 228; +pub const SYS_clock_getres: ::c_long = __X32_SYSCALL_BIT + 229; +pub const SYS_clock_nanosleep: ::c_long = __X32_SYSCALL_BIT + 230; +pub const SYS_exit_group: ::c_long = __X32_SYSCALL_BIT + 231; +pub const SYS_epoll_wait: ::c_long = __X32_SYSCALL_BIT + 232; +pub const SYS_epoll_ctl: ::c_long = __X32_SYSCALL_BIT + 233; +pub const SYS_tgkill: ::c_long = __X32_SYSCALL_BIT + 234; +pub const SYS_utimes: ::c_long = __X32_SYSCALL_BIT + 235; +pub const SYS_mbind: ::c_long = __X32_SYSCALL_BIT + 237; +pub const SYS_set_mempolicy: ::c_long = __X32_SYSCALL_BIT + 238; +pub const SYS_get_mempolicy: ::c_long = __X32_SYSCALL_BIT + 239; +pub const SYS_mq_open: ::c_long = __X32_SYSCALL_BIT + 240; +pub const SYS_mq_unlink: ::c_long = __X32_SYSCALL_BIT + 241; +pub const SYS_mq_timedsend: ::c_long = __X32_SYSCALL_BIT + 242; +pub const SYS_mq_timedreceive: ::c_long = __X32_SYSCALL_BIT + 243; +pub const SYS_mq_getsetattr: ::c_long = __X32_SYSCALL_BIT + 245; +pub const SYS_add_key: ::c_long = __X32_SYSCALL_BIT + 248; +pub const SYS_request_key: ::c_long = __X32_SYSCALL_BIT + 249; +pub const SYS_keyctl: ::c_long = __X32_SYSCALL_BIT + 250; +pub const SYS_ioprio_set: ::c_long = __X32_SYSCALL_BIT + 251; +pub const SYS_ioprio_get: ::c_long = __X32_SYSCALL_BIT + 252; +pub const SYS_inotify_init: ::c_long = __X32_SYSCALL_BIT + 253; +pub const SYS_inotify_add_watch: ::c_long = __X32_SYSCALL_BIT + 254; +pub const SYS_inotify_rm_watch: ::c_long = __X32_SYSCALL_BIT + 255; +pub const SYS_migrate_pages: ::c_long = __X32_SYSCALL_BIT + 256; +pub const SYS_openat: ::c_long = __X32_SYSCALL_BIT + 257; +pub const SYS_mkdirat: ::c_long = __X32_SYSCALL_BIT + 258; +pub const SYS_mknodat: ::c_long = __X32_SYSCALL_BIT + 259; +pub const SYS_fchownat: ::c_long = __X32_SYSCALL_BIT + 260; +pub const SYS_futimesat: ::c_long = __X32_SYSCALL_BIT + 261; +pub const SYS_newfstatat: ::c_long = __X32_SYSCALL_BIT + 262; +pub const SYS_unlinkat: ::c_long = __X32_SYSCALL_BIT + 263; +pub const SYS_renameat: ::c_long = __X32_SYSCALL_BIT + 264; +pub const SYS_linkat: ::c_long = __X32_SYSCALL_BIT + 265; +pub const SYS_symlinkat: ::c_long = __X32_SYSCALL_BIT + 266; +pub const SYS_readlinkat: ::c_long = __X32_SYSCALL_BIT + 267; +pub const SYS_fchmodat: ::c_long = __X32_SYSCALL_BIT + 268; +pub const SYS_faccessat: ::c_long = __X32_SYSCALL_BIT + 269; +pub const SYS_pselect6: ::c_long = __X32_SYSCALL_BIT + 270; +pub const SYS_ppoll: ::c_long = __X32_SYSCALL_BIT + 271; +pub const SYS_unshare: ::c_long = __X32_SYSCALL_BIT + 272; +pub const SYS_splice: ::c_long = __X32_SYSCALL_BIT + 275; +pub const SYS_tee: ::c_long = __X32_SYSCALL_BIT + 276; +pub const SYS_sync_file_range: ::c_long = __X32_SYSCALL_BIT + 277; +pub const SYS_utimensat: ::c_long = __X32_SYSCALL_BIT + 280; +pub const SYS_epoll_pwait: ::c_long = __X32_SYSCALL_BIT + 281; +pub const SYS_signalfd: ::c_long = __X32_SYSCALL_BIT + 282; +pub const SYS_timerfd_create: ::c_long = __X32_SYSCALL_BIT + 283; +pub const SYS_eventfd: ::c_long = __X32_SYSCALL_BIT + 284; +pub const SYS_fallocate: ::c_long = __X32_SYSCALL_BIT + 285; +pub const SYS_timerfd_settime: ::c_long = __X32_SYSCALL_BIT + 286; +pub const SYS_timerfd_gettime: ::c_long = __X32_SYSCALL_BIT + 287; +pub const SYS_accept4: ::c_long = __X32_SYSCALL_BIT + 288; +pub const SYS_signalfd4: ::c_long = __X32_SYSCALL_BIT + 289; +pub const SYS_eventfd2: ::c_long = __X32_SYSCALL_BIT + 290; +pub const SYS_epoll_create1: ::c_long = __X32_SYSCALL_BIT + 291; +pub const SYS_dup3: ::c_long = __X32_SYSCALL_BIT + 292; +pub const SYS_pipe2: ::c_long = __X32_SYSCALL_BIT + 293; +pub const SYS_inotify_init1: ::c_long = __X32_SYSCALL_BIT + 294; +pub const SYS_perf_event_open: ::c_long = __X32_SYSCALL_BIT + 298; +pub const SYS_fanotify_init: ::c_long = __X32_SYSCALL_BIT + 300; +pub const SYS_fanotify_mark: ::c_long = __X32_SYSCALL_BIT + 301; +pub const SYS_prlimit64: ::c_long = __X32_SYSCALL_BIT + 302; +pub const SYS_name_to_handle_at: ::c_long = __X32_SYSCALL_BIT + 303; +pub const SYS_open_by_handle_at: ::c_long = __X32_SYSCALL_BIT + 304; +pub const SYS_clock_adjtime: ::c_long = __X32_SYSCALL_BIT + 305; +pub const SYS_syncfs: ::c_long = __X32_SYSCALL_BIT + 306; +pub const SYS_setns: ::c_long = __X32_SYSCALL_BIT + 308; +pub const SYS_getcpu: ::c_long = __X32_SYSCALL_BIT + 309; +pub const SYS_kcmp: ::c_long = __X32_SYSCALL_BIT + 312; +pub const SYS_finit_module: ::c_long = __X32_SYSCALL_BIT + 313; +pub const SYS_sched_setattr: ::c_long = __X32_SYSCALL_BIT + 314; +pub const SYS_sched_getattr: ::c_long = __X32_SYSCALL_BIT + 315; +pub const SYS_renameat2: ::c_long = __X32_SYSCALL_BIT + 316; +pub const SYS_seccomp: ::c_long = __X32_SYSCALL_BIT + 317; +pub const SYS_getrandom: ::c_long = __X32_SYSCALL_BIT + 318; +pub const SYS_memfd_create: ::c_long = __X32_SYSCALL_BIT + 319; +pub const SYS_kexec_file_load: ::c_long = __X32_SYSCALL_BIT + 320; +pub const SYS_bpf: ::c_long = __X32_SYSCALL_BIT + 321; +pub const SYS_userfaultfd: ::c_long = __X32_SYSCALL_BIT + 323; +pub const SYS_membarrier: ::c_long = __X32_SYSCALL_BIT + 324; +pub const SYS_mlock2: ::c_long = __X32_SYSCALL_BIT + 325; +pub const SYS_copy_file_range: ::c_long = __X32_SYSCALL_BIT + 326; +pub const SYS_pkey_mprotect: ::c_long = __X32_SYSCALL_BIT + 329; +pub const SYS_pkey_alloc: ::c_long = __X32_SYSCALL_BIT + 330; +pub const SYS_pkey_free: ::c_long = __X32_SYSCALL_BIT + 331; +pub const SYS_statx: ::c_long = __X32_SYSCALL_BIT + 332; +pub const SYS_rseq: ::c_long = __X32_SYSCALL_BIT + 334; +pub const SYS_pidfd_send_signal: ::c_long = __X32_SYSCALL_BIT + 424; +pub const SYS_io_uring_setup: ::c_long = __X32_SYSCALL_BIT + 425; +pub const SYS_io_uring_enter: ::c_long = __X32_SYSCALL_BIT + 426; +pub const SYS_io_uring_register: ::c_long = __X32_SYSCALL_BIT + 427; +pub const SYS_open_tree: ::c_long = __X32_SYSCALL_BIT + 428; +pub const SYS_move_mount: ::c_long = __X32_SYSCALL_BIT + 429; +pub const SYS_fsopen: ::c_long = __X32_SYSCALL_BIT + 430; +pub const SYS_fsconfig: ::c_long = __X32_SYSCALL_BIT + 431; +pub const SYS_fsmount: ::c_long = __X32_SYSCALL_BIT + 432; +pub const SYS_fspick: ::c_long = __X32_SYSCALL_BIT + 433; +pub const SYS_pidfd_open: ::c_long = __X32_SYSCALL_BIT + 434; +pub const SYS_clone3: ::c_long = __X32_SYSCALL_BIT + 435; +pub const SYS_close_range: ::c_long = __X32_SYSCALL_BIT + 436; +pub const SYS_openat2: ::c_long = __X32_SYSCALL_BIT + 437; +pub const SYS_pidfd_getfd: ::c_long = __X32_SYSCALL_BIT + 438; +pub const SYS_faccessat2: ::c_long = __X32_SYSCALL_BIT + 439; +pub const SYS_process_madvise: ::c_long = __X32_SYSCALL_BIT + 440; +pub const SYS_epoll_pwait2: ::c_long = __X32_SYSCALL_BIT + 441; +pub const SYS_mount_setattr: ::c_long = __X32_SYSCALL_BIT + 442; +pub const SYS_quotactl_fd: ::c_long = __X32_SYSCALL_BIT + 443; +pub const SYS_landlock_create_ruleset: ::c_long = __X32_SYSCALL_BIT + 444; +pub const SYS_landlock_add_rule: ::c_long = __X32_SYSCALL_BIT + 445; +pub const SYS_landlock_restrict_self: ::c_long = __X32_SYSCALL_BIT + 446; +pub const SYS_memfd_secret: ::c_long = __X32_SYSCALL_BIT + 447; +pub const SYS_process_mrelease: ::c_long = __X32_SYSCALL_BIT + 448; +pub const SYS_futex_waitv: ::c_long = __X32_SYSCALL_BIT + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = __X32_SYSCALL_BIT + 450; +pub const SYS_rt_sigaction: ::c_long = __X32_SYSCALL_BIT + 512; +pub const SYS_rt_sigreturn: ::c_long = __X32_SYSCALL_BIT + 513; +pub const SYS_ioctl: ::c_long = __X32_SYSCALL_BIT + 514; +pub const SYS_readv: ::c_long = __X32_SYSCALL_BIT + 515; +pub const SYS_writev: ::c_long = __X32_SYSCALL_BIT + 516; +pub const SYS_recvfrom: ::c_long = __X32_SYSCALL_BIT + 517; +pub const SYS_sendmsg: ::c_long = __X32_SYSCALL_BIT + 518; +pub const SYS_recvmsg: ::c_long = __X32_SYSCALL_BIT + 519; +pub const SYS_execve: ::c_long = __X32_SYSCALL_BIT + 520; +pub const SYS_ptrace: ::c_long = __X32_SYSCALL_BIT + 521; +pub const SYS_rt_sigpending: ::c_long = __X32_SYSCALL_BIT + 522; +pub const SYS_rt_sigtimedwait: ::c_long = __X32_SYSCALL_BIT + 523; +pub const SYS_rt_sigqueueinfo: ::c_long = __X32_SYSCALL_BIT + 524; +pub const SYS_sigaltstack: ::c_long = __X32_SYSCALL_BIT + 525; +pub const SYS_timer_create: ::c_long = __X32_SYSCALL_BIT + 526; +pub const SYS_mq_notify: ::c_long = __X32_SYSCALL_BIT + 527; +pub const SYS_kexec_load: ::c_long = __X32_SYSCALL_BIT + 528; +pub const SYS_waitid: ::c_long = __X32_SYSCALL_BIT + 529; +pub const SYS_set_robust_list: ::c_long = __X32_SYSCALL_BIT + 530; +pub const SYS_get_robust_list: ::c_long = __X32_SYSCALL_BIT + 531; +pub const SYS_vmsplice: ::c_long = __X32_SYSCALL_BIT + 532; +pub const SYS_move_pages: ::c_long = __X32_SYSCALL_BIT + 533; +pub const SYS_preadv: ::c_long = __X32_SYSCALL_BIT + 534; +pub const SYS_pwritev: ::c_long = __X32_SYSCALL_BIT + 535; +pub const SYS_rt_tgsigqueueinfo: ::c_long = __X32_SYSCALL_BIT + 536; +pub const SYS_recvmmsg: ::c_long = __X32_SYSCALL_BIT + 537; +pub const SYS_sendmmsg: ::c_long = __X32_SYSCALL_BIT + 538; +pub const SYS_process_vm_readv: ::c_long = __X32_SYSCALL_BIT + 539; +pub const SYS_process_vm_writev: ::c_long = __X32_SYSCALL_BIT + 540; +pub const SYS_setsockopt: ::c_long = __X32_SYSCALL_BIT + 541; +pub const SYS_getsockopt: ::c_long = __X32_SYSCALL_BIT + 542; +pub const SYS_io_setup: ::c_long = __X32_SYSCALL_BIT + 543; +pub const SYS_io_submit: ::c_long = __X32_SYSCALL_BIT + 544; +pub const SYS_execveat: ::c_long = __X32_SYSCALL_BIT + 545; +pub const SYS_preadv2: ::c_long = __X32_SYSCALL_BIT + 546; +pub const SYS_pwritev2: ::c_long = __X32_SYSCALL_BIT + 547; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs new file mode 100644 index 00000000..9af519e9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs @@ -0,0 +1,1593 @@ +pub type pthread_t = c_ulong; +pub type __priority_which_t = ::c_uint; +pub type __rlimit_resource_t = ::c_uint; +pub type Lmid_t = ::c_long; +pub type regoff_t = ::c_int; +pub type __kernel_rwf_t = ::c_int; + +cfg_if! { + if #[cfg(doc)] { + // Used in `linux::arch` to define ioctl constants. + pub(crate) type Ioctl = ::c_ulong; + } else { + #[doc(hidden)] + pub type Ioctl = ::c_ulong; + } +} + +s! { + pub struct statx { + pub stx_mask: u32, + pub stx_blksize: u32, + pub stx_attributes: u64, + pub stx_nlink: u32, + pub stx_uid: u32, + pub stx_gid: u32, + pub stx_mode: u16, + __statx_pad1: [u16; 1], + pub stx_ino: u64, + pub stx_size: u64, + pub stx_blocks: u64, + pub stx_attributes_mask: u64, + pub stx_atime: ::statx_timestamp, + pub stx_btime: ::statx_timestamp, + pub stx_ctime: ::statx_timestamp, + pub stx_mtime: ::statx_timestamp, + pub stx_rdev_major: u32, + pub stx_rdev_minor: u32, + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + pub stx_mnt_id: u64, + pub stx_dio_mem_align: u32, + pub stx_dio_offset_align: u32, + __statx_pad3: [u64; 12], + } + + pub struct statx_timestamp { + pub tv_sec: i64, + pub tv_nsec: u32, + pub __statx_timestamp_pad1: [i32; 1], + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __next_prio: *mut aiocb, + __abs_prio: ::c_int, + __policy: ::c_int, + __error_code: ::c_int, + __return_value: ::ssize_t, + pub aio_offset: off_t, + #[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))] + __unused1: [::c_char; 4], + __glibc_reserved: [::c_char; 32] + } + + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + pub struct __timeval { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6")))] + pub c_ispeed: ::speed_t, + #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6")))] + pub c_ospeed: ::speed_t, + } + + pub struct mallinfo { + pub arena: ::c_int, + pub ordblks: ::c_int, + pub smblks: ::c_int, + pub hblks: ::c_int, + pub hblkhd: ::c_int, + pub usmblks: ::c_int, + pub fsmblks: ::c_int, + pub uordblks: ::c_int, + pub fordblks: ::c_int, + pub keepcost: ::c_int, + } + + pub struct mallinfo2 { + pub arena: ::size_t, + pub ordblks: ::size_t, + pub smblks: ::size_t, + pub hblks: ::size_t, + pub hblkhd: ::size_t, + pub usmblks: ::size_t, + pub fsmblks: ::size_t, + pub uordblks: ::size_t, + pub fordblks: ::size_t, + pub keepcost: ::size_t, + } + + pub struct nl_pktinfo { + pub group: u32, + } + + pub struct nl_mmap_req { + pub nm_block_size: ::c_uint, + pub nm_block_nr: ::c_uint, + pub nm_frame_size: ::c_uint, + pub nm_frame_nr: ::c_uint, + } + + pub struct nl_mmap_hdr { + pub nm_status: ::c_uint, + pub nm_len: ::c_uint, + pub nm_group: u32, + pub nm_pid: u32, + pub nm_uid: u32, + pub nm_gid: u32, + } + + pub struct rtentry { + pub rt_pad1: ::c_ulong, + pub rt_dst: ::sockaddr, + pub rt_gateway: ::sockaddr, + pub rt_genmask: ::sockaddr, + pub rt_flags: ::c_ushort, + pub rt_pad2: ::c_short, + pub rt_pad3: ::c_ulong, + pub rt_tos: ::c_uchar, + pub rt_class: ::c_uchar, + #[cfg(target_pointer_width = "64")] + pub rt_pad4: [::c_short; 3usize], + #[cfg(not(target_pointer_width = "64"))] + pub rt_pad4: ::c_short, + pub rt_metric: ::c_short, + pub rt_dev: *mut ::c_char, + pub rt_mtu: ::c_ulong, + pub rt_window: ::c_ulong, + pub rt_irtt: ::c_ushort, + } + + pub struct timex { + pub modes: ::c_uint, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub offset: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub offset: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub freq: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub freq: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub maxerror: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub maxerror: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub esterror: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub esterror: ::c_long, + pub status: ::c_int, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub constant: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub constant: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub precision: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub precision: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tolerance: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tolerance: ::c_long, + pub time: ::timeval, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tick: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tick: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub ppsfreq: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub ppsfreq: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub jitter: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub jitter: ::c_long, + pub shift: ::c_int, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub stabil: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub stabil: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub jitcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub jitcnt: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub calcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub calcnt: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub errcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub errcnt: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub stbcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub stbcnt: ::c_long, + pub tai: ::c_int, + pub __unused1: i32, + pub __unused2: i32, + pub __unused3: i32, + pub __unused4: i32, + pub __unused5: i32, + pub __unused6: i32, + pub __unused7: i32, + pub __unused8: i32, + pub __unused9: i32, + pub __unused10: i32, + pub __unused11: i32, + } + + pub struct ntptimeval { + pub time: ::timeval, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub __glibc_reserved1: ::c_long, + pub __glibc_reserved2: ::c_long, + pub __glibc_reserved3: ::c_long, + pub __glibc_reserved4: ::c_long, + } + + pub struct regex_t { + __buffer: *mut ::c_void, + __allocated: ::size_t, + __used: ::size_t, + __syntax: ::c_ulong, + __fastmap: *mut ::c_char, + __translate: *mut ::c_char, + __re_nsub: ::size_t, + __bitfield: u8, + } + + pub struct Elf64_Chdr { + pub ch_type: ::Elf64_Word, + pub ch_reserved: ::Elf64_Word, + pub ch_size: ::Elf64_Xword, + pub ch_addralign: ::Elf64_Xword, + } + + pub struct Elf32_Chdr { + pub ch_type: ::Elf32_Word, + pub ch_size: ::Elf32_Word, + pub ch_addralign: ::Elf32_Word, + } + + pub struct seminfo { + pub semmap: ::c_int, + pub semmni: ::c_int, + pub semmns: ::c_int, + pub semmnu: ::c_int, + pub semmsl: ::c_int, + pub semopm: ::c_int, + pub semume: ::c_int, + pub semusz: ::c_int, + pub semvmx: ::c_int, + pub semaem: ::c_int, + } + + pub struct ptrace_peeksiginfo_args { + pub off: ::__u64, + pub flags: ::__u32, + pub nr: ::__s32, + } + + pub struct __c_anonymous_ptrace_syscall_info_entry { + pub nr: ::__u64, + pub args: [::__u64; 6], + } + + pub struct __c_anonymous_ptrace_syscall_info_exit { + pub sval: ::__s64, + pub is_error: ::__u8, + } + + pub struct __c_anonymous_ptrace_syscall_info_seccomp { + pub nr: ::__u64, + pub args: [::__u64; 6], + pub ret_data: ::__u32, + } + + pub struct ptrace_syscall_info { + pub op: ::__u8, + pub pad: [::__u8; 3], + pub arch: ::__u32, + pub instruction_pointer: ::__u64, + pub stack_pointer: ::__u64, + #[cfg(libc_union)] + pub u: __c_anonymous_ptrace_syscall_info_data, + } + + // linux/if_xdp.h + + pub struct sockaddr_xdp { + pub sxdp_family: ::__u16, + pub sxdp_flags: ::__u16, + pub sxdp_ifindex: ::__u32, + pub sxdp_queue_id: ::__u32, + pub sxdp_shared_umem_fd: ::__u32, + } + + pub struct xdp_ring_offset { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + pub flags: ::__u64, + } + + pub struct xdp_mmap_offsets { + pub rx: xdp_ring_offset, + pub tx: xdp_ring_offset, + pub fr: xdp_ring_offset, + pub cr: xdp_ring_offset, + } + + pub struct xdp_ring_offset_v1 { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + } + + pub struct xdp_mmap_offsets_v1 { + pub rx: xdp_ring_offset_v1, + pub tx: xdp_ring_offset_v1, + pub fr: xdp_ring_offset_v1, + pub cr: xdp_ring_offset_v1, + } + + pub struct xdp_umem_reg { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + pub flags: ::__u32, + } + + pub struct xdp_umem_reg_v1 { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + } + + pub struct xdp_statistics { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + pub rx_ring_full: ::__u64, + pub rx_fill_ring_empty_descs: ::__u64, + pub tx_ring_empty_descs: ::__u64, + } + + pub struct xdp_statistics_v1 { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + } + + pub struct xdp_options { + pub flags: ::__u32, + } + + pub struct xdp_desc { + pub addr: ::__u64, + pub len: ::__u32, + pub options: ::__u32, + } + + pub struct iocb { + pub aio_data: ::__u64, + #[cfg(target_endian = "little")] + pub aio_key: ::__u32, + #[cfg(target_endian = "little")] + pub aio_rw_flags: ::__kernel_rwf_t, + #[cfg(target_endian = "big")] + pub aio_rw_flags: ::__kernel_rwf_t, + #[cfg(target_endian = "big")] + pub aio_key: ::__u32, + pub aio_lio_opcode: ::__u16, + pub aio_reqprio: ::__s16, + pub aio_fildes: ::__u32, + pub aio_buf: ::__u64, + pub aio_nbytes: ::__u64, + pub aio_offset: ::__s64, + aio_reserved2: ::__u64, + pub aio_flags: ::__u32, + pub aio_resfd: ::__u32, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_sigfault { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + si_addr: *mut ::c_void, + } + (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_tid: ::c_int, + _si_overrun: ::c_int, + si_sigval: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).si_sigval + } +} + +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, + } + impl ::Copy for sifields_sigchld {} + impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + self.sifields().sigchld.si_stime + } + } + + pub union __c_anonymous_ptrace_syscall_info_data { + pub entry: __c_anonymous_ptrace_syscall_info_entry, + pub exit: __c_anonymous_ptrace_syscall_info_exit, + pub seccomp: __c_anonymous_ptrace_syscall_info_seccomp, + } + impl ::Copy for __c_anonymous_ptrace_syscall_info_data {} + impl ::Clone for __c_anonymous_ptrace_syscall_info_data { + fn clone(&self) -> __c_anonymous_ptrace_syscall_info_data { + *self + } + } + } +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; __UT_LINESIZE], + pub ut_id: [::c_char; 4], + + pub ut_user: [::c_char; __UT_NAMESIZE], + pub ut_host: [::c_char; __UT_HOSTSIZE], + pub ut_exit: __exit_status, + + #[cfg(any(target_arch = "aarch64", + target_arch = "s390x", + target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_session: ::c_long, + #[cfg(any(target_arch = "aarch64", + target_arch = "s390x", + target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_tv: ::timeval, + + #[cfg(not(any(target_arch = "aarch64", + target_arch = "s390x", + target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_session: i32, + #[cfg(not(any(target_arch = "aarch64", + target_arch = "s390x", + target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_tv: __timeval, + + pub ut_addr_v6: [i32; 4], + __glibc_reserved: [::c_char; 20], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__glibc_reserved == other.__glibc_reserved + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__glibc_reserved", &self.__glibc_reserved) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__glibc_reserved.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ptrace_syscall_info_data { + fn eq(&self, other: &__c_anonymous_ptrace_syscall_info_data) -> bool { + unsafe { + self.entry == other.entry || + self.exit == other.exit || + self.seccomp == other.seccomp + } + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ptrace_syscall_info_data {} + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ptrace_syscall_info_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous_ptrace_syscall_info_data") + .field("entry", &self.entry) + .field("exit", &self.exit) + .field("seccomp", &self.seccomp) + .finish() + } + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ptrace_syscall_info_data { + fn hash(&self, state: &mut H) { + unsafe { + self.entry.hash(state); + self.exit.hash(state); + self.seccomp.hash(state); + } + } + } + } +} + +// include/uapi/asm-generic/hugetlb_encode.h +pub const HUGETLB_FLAG_ENCODE_SHIFT: ::c_int = 26; +pub const HUGETLB_FLAG_ENCODE_MASK: ::c_int = 0x3f; + +pub const HUGETLB_FLAG_ENCODE_64KB: ::c_int = 16 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_512KB: ::c_int = 19 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_1MB: ::c_int = 20 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_2MB: ::c_int = 21 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_8MB: ::c_int = 23 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_16MB: ::c_int = 24 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_32MB: ::c_int = 25 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_256MB: ::c_int = 28 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_512MB: ::c_int = 29 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_1GB: ::c_int = 30 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_2GB: ::c_int = 31 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_16GB: ::c_int = 34 << HUGETLB_FLAG_ENCODE_SHIFT; + +// include/uapi/linux/mman.h +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +pub const MAP_HUGE_SHIFT: ::c_int = HUGETLB_FLAG_ENCODE_SHIFT; +pub const MAP_HUGE_MASK: ::c_int = HUGETLB_FLAG_ENCODE_MASK; + +pub const MAP_HUGE_64KB: ::c_int = HUGETLB_FLAG_ENCODE_64KB; +pub const MAP_HUGE_512KB: ::c_int = HUGETLB_FLAG_ENCODE_512KB; +pub const MAP_HUGE_1MB: ::c_int = HUGETLB_FLAG_ENCODE_1MB; +pub const MAP_HUGE_2MB: ::c_int = HUGETLB_FLAG_ENCODE_2MB; +pub const MAP_HUGE_8MB: ::c_int = HUGETLB_FLAG_ENCODE_8MB; +pub const MAP_HUGE_16MB: ::c_int = HUGETLB_FLAG_ENCODE_16MB; +pub const MAP_HUGE_32MB: ::c_int = HUGETLB_FLAG_ENCODE_32MB; +pub const MAP_HUGE_256MB: ::c_int = HUGETLB_FLAG_ENCODE_256MB; +pub const MAP_HUGE_512MB: ::c_int = HUGETLB_FLAG_ENCODE_512MB; +pub const MAP_HUGE_1GB: ::c_int = HUGETLB_FLAG_ENCODE_1GB; +pub const MAP_HUGE_2GB: ::c_int = HUGETLB_FLAG_ENCODE_2GB; +pub const MAP_HUGE_16GB: ::c_int = HUGETLB_FLAG_ENCODE_16GB; + +pub const PRIO_PROCESS: ::__priority_which_t = 0; +pub const PRIO_PGRP: ::__priority_which_t = 1; +pub const PRIO_USER: ::__priority_which_t = 2; + +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +pub const __UT_LINESIZE: usize = 32; +pub const __UT_NAMESIZE: usize = 32; +pub const __UT_HOSTSIZE: usize = 256; +pub const EMPTY: ::c_short = 0; +pub const RUN_LVL: ::c_short = 1; +pub const BOOT_TIME: ::c_short = 2; +pub const NEW_TIME: ::c_short = 3; +pub const OLD_TIME: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const USER_PROCESS: ::c_short = 7; +pub const DEAD_PROCESS: ::c_short = 8; +pub const ACCOUNTING: ::c_short = 9; + +// dlfcn.h +pub const LM_ID_BASE: ::c_long = 0; +pub const LM_ID_NEWLM: ::c_long = -1; + +pub const RTLD_DI_LMID: ::c_int = 1; +pub const RTLD_DI_LINKMAP: ::c_int = 2; +pub const RTLD_DI_CONFIGADDR: ::c_int = 3; +pub const RTLD_DI_SERINFO: ::c_int = 4; +pub const RTLD_DI_SERINFOSIZE: ::c_int = 5; +pub const RTLD_DI_ORIGIN: ::c_int = 6; +pub const RTLD_DI_PROFILENAME: ::c_int = 7; +pub const RTLD_DI_PROFILEOUT: ::c_int = 8; +pub const RTLD_DI_TLS_MODID: ::c_int = 9; +pub const RTLD_DI_TLS_DATA: ::c_int = 10; + +pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; +pub const PIDFD_NONBLOCK: ::c_uint = O_NONBLOCK as ::c_uint; + +pub const SOL_RXRPC: ::c_int = 272; +pub const SOL_PPPOL2TP: ::c_int = 273; +pub const SOL_PNPIPE: ::c_int = 275; +pub const SOL_RDS: ::c_int = 276; +pub const SOL_IUCV: ::c_int = 277; +pub const SOL_CAIF: ::c_int = 278; +pub const SOL_NFC: ::c_int = 280; +pub const SOL_XDP: ::c_int = 283; + +pub const MSG_TRYHARD: ::c_int = 4; + +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_PAPER_MASK: ::c_int = 1 << LC_PAPER; +pub const LC_NAME_MASK: ::c_int = 1 << LC_NAME; +pub const LC_ADDRESS_MASK: ::c_int = 1 << LC_ADDRESS; +pub const LC_TELEPHONE_MASK: ::c_int = 1 << LC_TELEPHONE; +pub const LC_MEASUREMENT_MASK: ::c_int = 1 << LC_MEASUREMENT; +pub const LC_IDENTIFICATION_MASK: ::c_int = 1 << LC_IDENTIFICATION; +pub const LC_ALL_MASK: ::c_int = ::LC_CTYPE_MASK + | ::LC_NUMERIC_MASK + | ::LC_TIME_MASK + | ::LC_COLLATE_MASK + | ::LC_MONETARY_MASK + | ::LC_MESSAGES_MASK + | LC_PAPER_MASK + | LC_NAME_MASK + | LC_ADDRESS_MASK + | LC_TELEPHONE_MASK + | LC_MEASUREMENT_MASK + | LC_IDENTIFICATION_MASK; + +pub const ENOTSUP: ::c_int = EOPNOTSUPP; + +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const AF_XDP: ::c_int = 44; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; +pub const PF_XDP: ::c_int = AF_XDP; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const BUFSIZ: ::c_uint = 8192; +pub const TMP_MAX: ::c_uint = 238328; +pub const FOPEN_MAX: ::c_uint = 16; +pub const FILENAME_MAX: ::c_uint = 4096; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; +pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41; +pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45; +pub const _SC_PII: ::c_int = 53; +pub const _SC_PII_XTI: ::c_int = 54; +pub const _SC_PII_SOCKET: ::c_int = 55; +pub const _SC_PII_INTERNET: ::c_int = 56; +pub const _SC_PII_OSI: ::c_int = 57; +pub const _SC_POLL: ::c_int = 58; +pub const _SC_SELECT: ::c_int = 59; +pub const _SC_PII_INTERNET_STREAM: ::c_int = 61; +pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62; +pub const _SC_PII_OSI_COTS: ::c_int = 63; +pub const _SC_PII_OSI_CLTS: ::c_int = 64; +pub const _SC_PII_OSI_M: ::c_int = 65; +pub const _SC_T_IOV_MAX: ::c_int = 66; +pub const _SC_2_C_VERSION: ::c_int = 96; +pub const _SC_CHAR_BIT: ::c_int = 101; +pub const _SC_CHAR_MAX: ::c_int = 102; +pub const _SC_CHAR_MIN: ::c_int = 103; +pub const _SC_INT_MAX: ::c_int = 104; +pub const _SC_INT_MIN: ::c_int = 105; +pub const _SC_LONG_BIT: ::c_int = 106; +pub const _SC_WORD_BIT: ::c_int = 107; +pub const _SC_MB_LEN_MAX: ::c_int = 108; +pub const _SC_SSIZE_MAX: ::c_int = 110; +pub const _SC_SCHAR_MAX: ::c_int = 111; +pub const _SC_SCHAR_MIN: ::c_int = 112; +pub const _SC_SHRT_MAX: ::c_int = 113; +pub const _SC_SHRT_MIN: ::c_int = 114; +pub const _SC_UCHAR_MAX: ::c_int = 115; +pub const _SC_UINT_MAX: ::c_int = 116; +pub const _SC_ULONG_MAX: ::c_int = 117; +pub const _SC_USHRT_MAX: ::c_int = 118; +pub const _SC_NL_ARGMAX: ::c_int = 119; +pub const _SC_NL_LANGMAX: ::c_int = 120; +pub const _SC_NL_MSGMAX: ::c_int = 121; +pub const _SC_NL_NMAX: ::c_int = 122; +pub const _SC_NL_SETMAX: ::c_int = 123; +pub const _SC_NL_TEXTMAX: ::c_int = 124; +pub const _SC_BASE: ::c_int = 134; +pub const _SC_C_LANG_SUPPORT: ::c_int = 135; +pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136; +pub const _SC_DEVICE_IO: ::c_int = 140; +pub const _SC_DEVICE_SPECIFIC: ::c_int = 141; +pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142; +pub const _SC_FD_MGMT: ::c_int = 143; +pub const _SC_FIFO: ::c_int = 144; +pub const _SC_PIPE: ::c_int = 145; +pub const _SC_FILE_ATTRIBUTES: ::c_int = 146; +pub const _SC_FILE_LOCKING: ::c_int = 147; +pub const _SC_FILE_SYSTEM: ::c_int = 148; +pub const _SC_MULTI_PROCESS: ::c_int = 150; +pub const _SC_SINGLE_PROCESS: ::c_int = 151; +pub const _SC_NETWORKING: ::c_int = 152; +pub const _SC_REGEX_VERSION: ::c_int = 156; +pub const _SC_SIGNALS: ::c_int = 158; +pub const _SC_SYSTEM_DATABASE: ::c_int = 162; +pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163; +pub const _SC_USER_GROUPS: ::c_int = 166; +pub const _SC_USER_GROUPS_R: ::c_int = 167; +pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185; +pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186; +pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187; +pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188; +pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189; +pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190; +pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191; +pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192; +pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193; +pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194; +pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195; +pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196; +pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197; +pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198; +pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199; +pub const O_ACCMODE: ::c_int = 3; +pub const ST_RELATIME: ::c_ulong = 4096; +pub const NI_MAXHOST: ::socklen_t = 1025; + +// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the +// following are only available on newer Linux versions than the versions +// currently used in CI in some configurations, so we define them here. +cfg_if! { + if #[cfg(not(target_arch = "s390x"))] { + pub const BINDERFS_SUPER_MAGIC: ::c_long = 0x6c6f6f70; + pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + } else if #[cfg(target_arch = "s390x")] { + pub const BINDERFS_SUPER_MAGIC: ::c_uint = 0x6c6f6f70; + pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342; + } +} + +pub const CPU_SETSIZE: ::c_int = 0x400; + +pub const PTRACE_TRACEME: ::c_uint = 0; +pub const PTRACE_PEEKTEXT: ::c_uint = 1; +pub const PTRACE_PEEKDATA: ::c_uint = 2; +pub const PTRACE_PEEKUSER: ::c_uint = 3; +pub const PTRACE_POKETEXT: ::c_uint = 4; +pub const PTRACE_POKEDATA: ::c_uint = 5; +pub const PTRACE_POKEUSER: ::c_uint = 6; +pub const PTRACE_CONT: ::c_uint = 7; +pub const PTRACE_KILL: ::c_uint = 8; +pub const PTRACE_SINGLESTEP: ::c_uint = 9; +pub const PTRACE_ATTACH: ::c_uint = 16; +pub const PTRACE_SYSCALL: ::c_uint = 24; +pub const PTRACE_SETOPTIONS: ::c_uint = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_uint = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_uint = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_uint = 0x4203; +pub const PTRACE_GETREGSET: ::c_uint = 0x4204; +pub const PTRACE_SETREGSET: ::c_uint = 0x4205; +pub const PTRACE_SEIZE: ::c_uint = 0x4206; +pub const PTRACE_INTERRUPT: ::c_uint = 0x4207; +pub const PTRACE_LISTEN: ::c_uint = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_uint = 0x4209; +pub const PTRACE_GETSIGMASK: ::c_uint = 0x420a; +pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b; +pub const PTRACE_GET_SYSCALL_INFO: ::c_uint = 0x420e; +pub const PTRACE_SYSCALL_INFO_NONE: ::__u8 = 0; +pub const PTRACE_SYSCALL_INFO_ENTRY: ::__u8 = 1; +pub const PTRACE_SYSCALL_INFO_EXIT: ::__u8 = 2; +pub const PTRACE_SYSCALL_INFO_SECCOMP: ::__u8 = 3; + +// linux/fs.h + +// Flags for preadv2/pwritev2 +pub const RWF_HIPRI: ::c_int = 0x00000001; +pub const RWF_DSYNC: ::c_int = 0x00000002; +pub const RWF_SYNC: ::c_int = 0x00000004; +pub const RWF_NOWAIT: ::c_int = 0x00000008; +pub const RWF_APPEND: ::c_int = 0x00000010; + +// linux/rtnetlink.h +pub const TCA_PAD: ::c_ushort = 9; +pub const TCA_DUMP_INVISIBLE: ::c_ushort = 10; +pub const TCA_CHAIN: ::c_ushort = 11; +pub const TCA_HW_OFFLOAD: ::c_ushort = 12; + +pub const RTM_DELNETCONF: u16 = 81; +pub const RTM_NEWSTATS: u16 = 92; +pub const RTM_GETSTATS: u16 = 94; +pub const RTM_NEWCACHEREPORT: u16 = 96; + +pub const RTM_F_LOOKUP_TABLE: ::c_uint = 0x1000; +pub const RTM_F_FIB_MATCH: ::c_uint = 0x2000; + +pub const RTA_VIA: ::c_ushort = 18; +pub const RTA_NEWDST: ::c_ushort = 19; +pub const RTA_PREF: ::c_ushort = 20; +pub const RTA_ENCAP_TYPE: ::c_ushort = 21; +pub const RTA_ENCAP: ::c_ushort = 22; +pub const RTA_EXPIRES: ::c_ushort = 23; +pub const RTA_PAD: ::c_ushort = 24; +pub const RTA_UID: ::c_ushort = 25; +pub const RTA_TTL_PROPAGATE: ::c_ushort = 26; + +// linux/neighbor.h +pub const NTF_EXT_LEARNED: u8 = 0x10; +pub const NTF_OFFLOADED: u8 = 0x20; + +pub const NDA_MASTER: ::c_ushort = 9; +pub const NDA_LINK_NETNSID: ::c_ushort = 10; +pub const NDA_SRC_VNI: ::c_ushort = 11; + +// linux/personality.h +pub const UNAME26: ::c_int = 0x0020000; +pub const FDPIC_FUNCPTRS: ::c_int = 0x0080000; + +// linux/if_addr.h +pub const IFA_FLAGS: ::c_ushort = 8; + +pub const IFA_F_MANAGETEMPADDR: u32 = 0x100; +pub const IFA_F_NOPREFIXROUTE: u32 = 0x200; +pub const IFA_F_MCAUTOJOIN: u32 = 0x400; +pub const IFA_F_STABLE_PRIVACY: u32 = 0x800; + +pub const MAX_LINKS: ::c_int = 32; + +pub const GENL_UNS_ADMIN_PERM: ::c_int = 0x10; + +pub const GENL_ID_VFS_DQUOT: ::c_int = ::NLMSG_MIN_TYPE + 1; +pub const GENL_ID_PMCRAID: ::c_int = ::NLMSG_MIN_TYPE + 2; + +// linux/if_xdp.h +pub const XDP_SHARED_UMEM: ::__u16 = 1 << 0; +pub const XDP_COPY: ::__u16 = 1 << 1; +pub const XDP_ZEROCOPY: ::__u16 = 1 << 2; +pub const XDP_USE_NEED_WAKEUP: ::__u16 = 1 << 3; +pub const XDP_USE_SG: ::__u16 = 1 << 4; + +pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG: ::__u32 = 1 << 0; + +pub const XDP_RING_NEED_WAKEUP: ::__u32 = 1 << 0; + +pub const XDP_MMAP_OFFSETS: ::c_int = 1; +pub const XDP_RX_RING: ::c_int = 2; +pub const XDP_TX_RING: ::c_int = 3; +pub const XDP_UMEM_REG: ::c_int = 4; +pub const XDP_UMEM_FILL_RING: ::c_int = 5; +pub const XDP_UMEM_COMPLETION_RING: ::c_int = 6; +pub const XDP_STATISTICS: ::c_int = 7; +pub const XDP_OPTIONS: ::c_int = 8; + +pub const XDP_OPTIONS_ZEROCOPY: ::__u32 = 1 << 0; + +pub const XDP_PGOFF_RX_RING: ::off_t = 0; +pub const XDP_PGOFF_TX_RING: ::off_t = 0x80000000; +pub const XDP_UMEM_PGOFF_FILL_RING: ::c_ulonglong = 0x100000000; +pub const XDP_UMEM_PGOFF_COMPLETION_RING: ::c_ulonglong = 0x180000000; + +pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: ::c_int = 48; +pub const XSK_UNALIGNED_BUF_ADDR_MASK: ::c_ulonglong = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1; + +pub const XDP_PKT_CONTD: ::__u32 = 1 << 0; + +// elf.h +pub const NT_PRSTATUS: ::c_int = 1; +pub const NT_PRFPREG: ::c_int = 2; +pub const NT_FPREGSET: ::c_int = 2; +pub const NT_PRPSINFO: ::c_int = 3; +pub const NT_PRXREG: ::c_int = 4; +pub const NT_TASKSTRUCT: ::c_int = 4; +pub const NT_PLATFORM: ::c_int = 5; +pub const NT_AUXV: ::c_int = 6; +pub const NT_GWINDOWS: ::c_int = 7; +pub const NT_ASRS: ::c_int = 8; +pub const NT_PSTATUS: ::c_int = 10; +pub const NT_PSINFO: ::c_int = 13; +pub const NT_PRCRED: ::c_int = 14; +pub const NT_UTSNAME: ::c_int = 15; +pub const NT_LWPSTATUS: ::c_int = 16; +pub const NT_LWPSINFO: ::c_int = 17; +pub const NT_PRFPXREG: ::c_int = 20; + +pub const ELFOSABI_ARM_AEABI: u8 = 64; + +// linux/sched.h +pub const CLONE_NEWTIME: ::c_int = 0x80; +pub const CLONE_CLEAR_SIGHAND: ::c_int = 0x100000000; +pub const CLONE_INTO_CGROUP: ::c_int = 0x200000000; + +// linux/keyctl.h +pub const KEYCTL_DH_COMPUTE: u32 = 23; +pub const KEYCTL_PKEY_QUERY: u32 = 24; +pub const KEYCTL_PKEY_ENCRYPT: u32 = 25; +pub const KEYCTL_PKEY_DECRYPT: u32 = 26; +pub const KEYCTL_PKEY_SIGN: u32 = 27; +pub const KEYCTL_PKEY_VERIFY: u32 = 28; +pub const KEYCTL_RESTRICT_KEYRING: u32 = 29; + +pub const KEYCTL_SUPPORTS_ENCRYPT: u32 = 0x01; +pub const KEYCTL_SUPPORTS_DECRYPT: u32 = 0x02; +pub const KEYCTL_SUPPORTS_SIGN: u32 = 0x04; +pub const KEYCTL_SUPPORTS_VERIFY: u32 = 0x08; +cfg_if! { + if #[cfg(not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6")))] { + pub const KEYCTL_MOVE: u32 = 30; + pub const KEYCTL_CAPABILITIES: u32 = 31; + + pub const KEYCTL_CAPS0_CAPABILITIES: u32 = 0x01; + pub const KEYCTL_CAPS0_PERSISTENT_KEYRINGS: u32 = 0x02; + pub const KEYCTL_CAPS0_DIFFIE_HELLMAN: u32 = 0x04; + pub const KEYCTL_CAPS0_PUBLIC_KEY: u32 = 0x08; + pub const KEYCTL_CAPS0_BIG_KEY: u32 = 0x10; + pub const KEYCTL_CAPS0_INVALIDATE: u32 = 0x20; + pub const KEYCTL_CAPS0_RESTRICT_KEYRING: u32 = 0x40; + pub const KEYCTL_CAPS0_MOVE: u32 = 0x80; + pub const KEYCTL_CAPS1_NS_KEYRING_NAME: u32 = 0x01; + pub const KEYCTL_CAPS1_NS_KEY_TAG: u32 = 0x02; + } +} + +pub const M_MXFAST: ::c_int = 1; +pub const M_NLBLKS: ::c_int = 2; +pub const M_GRAIN: ::c_int = 3; +pub const M_KEEP: ::c_int = 4; +pub const M_TRIM_THRESHOLD: ::c_int = -1; +pub const M_TOP_PAD: ::c_int = -2; +pub const M_MMAP_THRESHOLD: ::c_int = -3; +pub const M_MMAP_MAX: ::c_int = -4; +pub const M_CHECK_ACTION: ::c_int = -5; +pub const M_PERTURB: ::c_int = -6; +pub const M_ARENA_TEST: ::c_int = -7; +pub const M_ARENA_MAX: ::c_int = -8; + +pub const AT_STATX_SYNC_TYPE: ::c_int = 0x6000; +pub const AT_STATX_SYNC_AS_STAT: ::c_int = 0x0000; +pub const AT_STATX_FORCE_SYNC: ::c_int = 0x2000; +pub const AT_STATX_DONT_SYNC: ::c_int = 0x4000; +pub const STATX_TYPE: ::c_uint = 0x0001; +pub const STATX_MODE: ::c_uint = 0x0002; +pub const STATX_NLINK: ::c_uint = 0x0004; +pub const STATX_UID: ::c_uint = 0x0008; +pub const STATX_GID: ::c_uint = 0x0010; +pub const STATX_ATIME: ::c_uint = 0x0020; +pub const STATX_MTIME: ::c_uint = 0x0040; +pub const STATX_CTIME: ::c_uint = 0x0080; +pub const STATX_INO: ::c_uint = 0x0100; +pub const STATX_SIZE: ::c_uint = 0x0200; +pub const STATX_BLOCKS: ::c_uint = 0x0400; +pub const STATX_BASIC_STATS: ::c_uint = 0x07ff; +pub const STATX_BTIME: ::c_uint = 0x0800; +pub const STATX_MNT_ID: ::c_uint = 0x1000; +pub const STATX_DIOALIGN: ::c_uint = 0x2000; +pub const STATX_ALL: ::c_uint = 0x0fff; +pub const STATX__RESERVED: ::c_int = 0x80000000; +pub const STATX_ATTR_COMPRESSED: ::c_int = 0x0004; +pub const STATX_ATTR_IMMUTABLE: ::c_int = 0x0010; +pub const STATX_ATTR_APPEND: ::c_int = 0x0020; +pub const STATX_ATTR_NODUMP: ::c_int = 0x0040; +pub const STATX_ATTR_ENCRYPTED: ::c_int = 0x0800; +pub const STATX_ATTR_AUTOMOUNT: ::c_int = 0x1000; +pub const STATX_ATTR_MOUNT_ROOT: ::c_int = 0x2000; +pub const STATX_ATTR_VERITY: ::c_int = 0x00100000; +pub const STATX_ATTR_DAX: ::c_int = 0x00200000; + +pub const SOMAXCONN: ::c_int = 4096; + +// linux/mount.h +pub const MOVE_MOUNT_F_SYMLINKS: ::c_uint = 0x00000001; +pub const MOVE_MOUNT_F_AUTOMOUNTS: ::c_uint = 0x00000002; +pub const MOVE_MOUNT_F_EMPTY_PATH: ::c_uint = 0x00000004; +pub const MOVE_MOUNT_T_SYMLINKS: ::c_uint = 0x00000010; +pub const MOVE_MOUNT_T_AUTOMOUNTS: ::c_uint = 0x00000020; +pub const MOVE_MOUNT_T_EMPTY_PATH: ::c_uint = 0x00000040; +pub const MOVE_MOUNT_SET_GROUP: ::c_uint = 0x00000100; +pub const MOVE_MOUNT_BENEATH: ::c_uint = 0x00000200; + +// sys/timex.h +pub const ADJ_OFFSET: ::c_uint = 0x0001; +pub const ADJ_FREQUENCY: ::c_uint = 0x0002; +pub const ADJ_MAXERROR: ::c_uint = 0x0004; +pub const ADJ_ESTERROR: ::c_uint = 0x0008; +pub const ADJ_STATUS: ::c_uint = 0x0010; +pub const ADJ_TIMECONST: ::c_uint = 0x0020; +pub const ADJ_TAI: ::c_uint = 0x0080; +pub const ADJ_SETOFFSET: ::c_uint = 0x0100; +pub const ADJ_MICRO: ::c_uint = 0x1000; +pub const ADJ_NANO: ::c_uint = 0x2000; +pub const ADJ_TICK: ::c_uint = 0x4000; +pub const ADJ_OFFSET_SINGLESHOT: ::c_uint = 0x8001; +pub const ADJ_OFFSET_SS_READ: ::c_uint = 0xa001; +pub const MOD_OFFSET: ::c_uint = ADJ_OFFSET; +pub const MOD_FREQUENCY: ::c_uint = ADJ_FREQUENCY; +pub const MOD_MAXERROR: ::c_uint = ADJ_MAXERROR; +pub const MOD_ESTERROR: ::c_uint = ADJ_ESTERROR; +pub const MOD_STATUS: ::c_uint = ADJ_STATUS; +pub const MOD_TIMECONST: ::c_uint = ADJ_TIMECONST; +pub const MOD_CLKB: ::c_uint = ADJ_TICK; +pub const MOD_CLKA: ::c_uint = ADJ_OFFSET_SINGLESHOT; +pub const MOD_TAI: ::c_uint = ADJ_TAI; +pub const MOD_MICRO: ::c_uint = ADJ_MICRO; +pub const MOD_NANO: ::c_uint = ADJ_NANO; +pub const STA_PLL: ::c_int = 0x0001; +pub const STA_PPSFREQ: ::c_int = 0x0002; +pub const STA_PPSTIME: ::c_int = 0x0004; +pub const STA_FLL: ::c_int = 0x0008; +pub const STA_INS: ::c_int = 0x0010; +pub const STA_DEL: ::c_int = 0x0020; +pub const STA_UNSYNC: ::c_int = 0x0040; +pub const STA_FREQHOLD: ::c_int = 0x0080; +pub const STA_PPSSIGNAL: ::c_int = 0x0100; +pub const STA_PPSJITTER: ::c_int = 0x0200; +pub const STA_PPSWANDER: ::c_int = 0x0400; +pub const STA_PPSERROR: ::c_int = 0x0800; +pub const STA_CLOCKERR: ::c_int = 0x1000; +pub const STA_NANO: ::c_int = 0x2000; +pub const STA_MODE: ::c_int = 0x4000; +pub const STA_CLK: ::c_int = 0x8000; +pub const STA_RONLY: ::c_int = STA_PPSSIGNAL + | STA_PPSJITTER + | STA_PPSWANDER + | STA_PPSERROR + | STA_CLOCKERR + | STA_NANO + | STA_MODE + | STA_CLK; +pub const NTP_API: ::c_int = 4; +pub const TIME_OK: ::c_int = 0; +pub const TIME_INS: ::c_int = 1; +pub const TIME_DEL: ::c_int = 2; +pub const TIME_OOP: ::c_int = 3; +pub const TIME_WAIT: ::c_int = 4; +pub const TIME_ERROR: ::c_int = 5; +pub const TIME_BAD: ::c_int = TIME_ERROR; +pub const MAXTC: ::c_long = 6; + +// Portable GLOB_* flags are defined at the `linux_like` level. +// The following are GNU extensions. +pub const GLOB_PERIOD: ::c_int = 1 << 7; +pub const GLOB_ALTDIRFUNC: ::c_int = 1 << 9; +pub const GLOB_BRACE: ::c_int = 1 << 10; +pub const GLOB_NOMAGIC: ::c_int = 1 << 11; +pub const GLOB_TILDE: ::c_int = 1 << 12; +pub const GLOB_ONLYDIR: ::c_int = 1 << 13; +pub const GLOB_TILDE_CHECK: ::c_int = 1 << 14; + +pub const MADV_COLLAPSE: ::c_int = 25; + +cfg_if! { + if #[cfg(any( + target_arch = "arm", + target_arch = "x86", + target_arch = "x86_64", + target_arch = "s390x", + target_arch = "riscv64", + target_arch = "riscv32" + ))] { + pub const PTHREAD_STACK_MIN: ::size_t = 16384; + } else if #[cfg(any( + target_arch = "sparc", + target_arch = "sparc64" + ))] { + pub const PTHREAD_STACK_MIN: ::size_t = 0x6000; + } else { + pub const PTHREAD_STACK_MIN: ::size_t = 131072; + } +} +pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 3; + +pub const REG_STARTEND: ::c_int = 4; + +pub const REG_EEND: ::c_int = 14; +pub const REG_ESIZE: ::c_int = 15; +pub const REG_ERPAREN: ::c_int = 16; + +extern "C" { + pub fn fgetspent_r( + fp: *mut ::FILE, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn sgetspent_r( + s: *const ::c_char, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn getspent_r( + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn qsort_r( + base: *mut ::c_void, + num: ::size_t, + size: ::size_t, + compar: ::Option< + unsafe extern "C" fn(*const ::c_void, *const ::c_void, *mut ::c_void) -> ::c_int, + >, + arg: *mut ::c_void, + ); + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + + pub fn getrlimit64(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit64) -> ::c_int; + pub fn setrlimit64(resource: ::__rlimit_resource_t, rlim: *const ::rlimit64) -> ::c_int; + pub fn getrlimit(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::__rlimit_resource_t, rlim: *const ::rlimit) -> ::c_int; + pub fn prlimit( + pid: ::pid_t, + resource: ::__rlimit_resource_t, + new_limit: *const ::rlimit, + old_limit: *mut ::rlimit, + ) -> ::c_int; + pub fn prlimit64( + pid: ::pid_t, + resource: ::__rlimit_resource_t, + new_limit: *const ::rlimit64, + old_limit: *mut ::rlimit64, + ) -> ::c_int; + pub fn utmpname(file: *const ::c_char) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); + pub fn getpt() -> ::c_int; + pub fn mallopt(param: ::c_int, value: ::c_int) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn statx( + dirfd: ::c_int, + pathname: *const c_char, + flags: ::c_int, + mask: ::c_uint, + statxbuf: *mut statx, + ) -> ::c_int; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; + + pub fn adjtimex(buf: *mut timex) -> ::c_int; + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + #[link_name = "ntp_gettimex"] + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + pub fn clock_adjtime(clk_id: ::clockid_t, buf: *mut ::timex) -> ::c_int; + + pub fn fanotify_mark( + fd: ::c_int, + flags: ::c_uint, + mask: u64, + dirfd: ::c_int, + path: *const ::c_char, + ) -> ::c_int; + pub fn preadv2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn pwritev2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn preadv64v2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn pwritev64v2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn renameat2( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_uint, + ) -> ::c_int; + + // Added in `glibc` 2.25 + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); + // Added in `glibc` 2.29 + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int; + pub fn glob64( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t, + ) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + pub fn ptrace(request: ::c_uint, ...) -> ::c_long; + pub fn pthread_attr_getaffinity_np( + attr: *const ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t, + ) -> ::c_int; + pub fn pthread_attr_setaffinity_np( + attr: *mut ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t, + ) -> ::c_int; + pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::__priority_which_t, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn pthread_rwlockattr_getkind_np( + attr: *const ::pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut ::pthread_rwlockattr_t, + val: ::c_int, + ) -> ::c_int; + pub fn pthread_sigqueue(thread: ::pthread_t, sig: ::c_int, value: ::sigval) -> ::c_int; + pub fn mallinfo() -> ::mallinfo; + pub fn mallinfo2() -> ::mallinfo2; + pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int; + pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn fgetpwent_r( + stream: *mut ::FILE, + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn fgetgrent_r( + stream: *mut ::FILE, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + + pub fn putpwent(p: *const ::passwd, stream: *mut ::FILE) -> ::c_int; + pub fn putgrent(grp: *const ::group, stream: *mut ::FILE) -> ::c_int; + + pub fn sethostid(hostid: ::c_long) -> ::c_int; + + pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int; + + pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + + pub fn asctime_r(tm: *const ::tm, buf: *mut ::c_char) -> *mut ::c_char; + pub fn ctime_r(timep: *const time_t, buf: *mut ::c_char) -> *mut ::c_char; + + pub fn strftime( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + ) -> ::size_t; + pub fn strftime_l( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + locale: ::locale_t, + ) -> ::size_t; + pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + /// POSIX version of `basename(3)`, defined in `libgen.h`. + #[link_name = "__xpg_basename"] + pub fn posix_basename(path: *mut ::c_char) -> *mut ::c_char; + /// GNU version of `basename(3)`, defined in `string.h`. + #[link_name = "basename"] + pub fn gnu_basename(path: *const ::c_char) -> *mut ::c_char; + pub fn dlmopen(lmid: Lmid_t, filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + pub fn dlinfo(handle: *mut ::c_void, request: ::c_int, info: *mut ::c_void) -> ::c_int; + pub fn dladdr1( + addr: *const ::c_void, + info: *mut ::Dl_info, + extra_info: *mut *mut ::c_void, + flags: ::c_int, + ) -> ::c_int; + pub fn malloc_trim(__pad: ::size_t) -> ::c_int; + pub fn gnu_get_libc_release() -> *const ::c_char; + pub fn gnu_get_libc_version() -> *const ::c_char; + + // posix/spawn.h + // Added in `glibc` 2.29 + pub fn posix_spawn_file_actions_addchdir_np( + actions: *mut ::posix_spawn_file_actions_t, + path: *const ::c_char, + ) -> ::c_int; + // Added in `glibc` 2.29 + pub fn posix_spawn_file_actions_addfchdir_np( + actions: *mut ::posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + // Added in `glibc` 2.34 + pub fn posix_spawn_file_actions_addclosefrom_np( + actions: *mut ::posix_spawn_file_actions_t, + from: ::c_int, + ) -> ::c_int; + // Added in `glibc` 2.35 + pub fn posix_spawn_file_actions_addtcsetpgrp_np( + actions: *mut ::posix_spawn_file_actions_t, + tcfd: ::c_int, + ) -> ::c_int; + + // mntent.h + pub fn getmntent_r( + stream: *mut ::FILE, + mntbuf: *mut ::mntent, + buf: *mut ::c_char, + buflen: ::c_int, + ) -> *mut ::mntent; + + pub fn execveat( + dirfd: ::c_int, + pathname: *const ::c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, + flags: ::c_int, + ) -> ::c_int; + + // Added in `glibc` 2.34 + pub fn close_range(first: ::c_uint, last: ::c_uint, flags: ::c_int) -> ::c_int; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "riscv32"))] { + mod b32; + pub use self::b32::*; + } else if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "loongarch64"))] { + mod b64; + pub use self::b64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs new file mode 100644 index 00000000..e32bf673 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/mod.rs new file mode 100644 index 00000000..cbb3f7bd --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/mod.rs @@ -0,0 +1,5689 @@ +//! Linux-specific definitions for linux-like values + +pub type useconds_t = u32; +pub type dev_t = u64; +pub type socklen_t = u32; +pub type mode_t = u32; +pub type ino64_t = u64; +pub type off64_t = i64; +pub type blkcnt64_t = i64; +pub type rlim64_t = u64; +pub type mqd_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type idtype_t = ::c_uint; +pub type loff_t = ::c_longlong; +pub type pthread_key_t = ::c_uint; +pub type pthread_once_t = ::c_int; +pub type pthread_spinlock_t = ::c_int; + +pub type __u8 = ::c_uchar; +pub type __u16 = ::c_ushort; +pub type __s16 = ::c_short; +pub type __u32 = ::c_uint; +pub type __s32 = ::c_int; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; + +pub type Elf64_Half = u16; +pub type Elf64_Word = u32; +pub type Elf64_Off = u64; +pub type Elf64_Addr = u64; +pub type Elf64_Xword = u64; +pub type Elf64_Sxword = i64; + +pub type Elf32_Section = u16; +pub type Elf64_Section = u16; + +// linux/can.h +pub type canid_t = u32; + +// linux/can/j1939.h +pub type can_err_mask_t = u32; +pub type pgn_t = u32; +pub type priority_t = u8; +pub type name_t = u64; + +pub type iconv_t = *mut ::c_void; + +// linux/sctp.h +pub type sctp_assoc_t = ::__s32; + +pub type eventfd_t = u64; +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum fpos64_t {} // FIXME: fill this out with a struct +} + +s! { + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curspace: u64, + pub dqb_ihardlimit: u64, + pub dqb_isoftlimit: u64, + pub dqb_curinodes: u64, + pub dqb_btime: u64, + pub dqb_itime: u64, + pub dqb_valid: u32, + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct packet_mreq { + pub mr_ifindex: ::c_int, + pub mr_type: ::c_ushort, + pub mr_alen: ::c_ushort, + pub mr_address: [::c_uchar; 8], + } + + pub struct cpu_set_t { + #[cfg(all(target_pointer_width = "32", + not(target_arch = "x86_64")))] + bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + bits: [u64; 16], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct input_event { + pub time: ::timeval, + pub type_: ::__u16, + pub code: ::__u16, + pub value: ::__s32, + } + + pub struct input_id { + pub bustype: ::__u16, + pub vendor: ::__u16, + pub product: ::__u16, + pub version: ::__u16, + } + + pub struct input_absinfo { + pub value: ::__s32, + pub minimum: ::__s32, + pub maximum: ::__s32, + pub fuzz: ::__s32, + pub flat: ::__s32, + pub resolution: ::__s32, + } + + pub struct input_keymap_entry { + pub flags: ::__u8, + pub len: ::__u8, + pub index: ::__u16, + pub keycode: ::__u32, + pub scancode: [::__u8; 32], + } + + pub struct input_mask { + pub type_: ::__u32, + pub codes_size: ::__u32, + pub codes_ptr: ::__u64, + } + + pub struct ff_replay { + pub length: ::__u16, + pub delay: ::__u16, + } + + pub struct ff_trigger { + pub button: ::__u16, + pub interval: ::__u16, + } + + pub struct ff_envelope { + pub attack_length: ::__u16, + pub attack_level: ::__u16, + pub fade_length: ::__u16, + pub fade_level: ::__u16, + } + + pub struct ff_constant_effect { + pub level: ::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_ramp_effect { + pub start_level: ::__s16, + pub end_level: ::__s16, + pub envelope: ff_envelope, + } + + pub struct ff_condition_effect { + pub right_saturation: ::__u16, + pub left_saturation: ::__u16, + + pub right_coeff: ::__s16, + pub left_coeff: ::__s16, + + pub deadband: ::__u16, + pub center: ::__s16, + } + + pub struct ff_periodic_effect { + pub waveform: ::__u16, + pub period: ::__u16, + pub magnitude: ::__s16, + pub offset: ::__s16, + pub phase: ::__u16, + + pub envelope: ff_envelope, + + pub custom_len: ::__u32, + pub custom_data: *mut ::__s16, + } + + pub struct ff_rumble_effect { + pub strong_magnitude: ::__u16, + pub weak_magnitude: ::__u16, + } + + pub struct ff_effect { + pub type_: ::__u16, + pub id: ::__s16, + pub direction: ::__u16, + pub trigger: ff_trigger, + pub replay: ff_replay, + // FIXME this is actually a union + #[cfg(target_pointer_width = "64")] + pub u: [u64; 4], + #[cfg(target_pointer_width = "32")] + pub u: [u32; 7], + } + + pub struct uinput_ff_upload { + pub request_id: ::__u32, + pub retval: ::__s32, + pub effect: ff_effect, + pub old: ff_effect, + } + + pub struct uinput_ff_erase { + pub request_id: ::__u32, + pub retval: ::__s32, + pub effect_id: ::__u32, + } + + pub struct uinput_abs_setup { + pub code: ::__u16, + pub absinfo: input_absinfo, + } + + pub struct dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + // As of uClibc 1.0.36, the following fields are + // gated behind a "#if 0" block which always evaluates + // to false. So I'm just removing these, and if uClibc changes + // the #if block in the future to include the following fields, these + // will probably need including here. tsidea, skrap + #[cfg(not(target_env = "uclibc"))] + pub dlpi_adds: ::c_ulonglong, + #[cfg(not(target_env = "uclibc"))] + pub dlpi_subs: ::c_ulonglong, + #[cfg(not(target_env = "uclibc"))] + pub dlpi_tls_modid: ::size_t, + #[cfg(not(target_env = "uclibc"))] + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct Elf32_Ehdr { + pub e_ident: [::c_uchar; 16], + pub e_type: Elf32_Half, + pub e_machine: Elf32_Half, + pub e_version: Elf32_Word, + pub e_entry: Elf32_Addr, + pub e_phoff: Elf32_Off, + pub e_shoff: Elf32_Off, + pub e_flags: Elf32_Word, + pub e_ehsize: Elf32_Half, + pub e_phentsize: Elf32_Half, + pub e_phnum: Elf32_Half, + pub e_shentsize: Elf32_Half, + pub e_shnum: Elf32_Half, + pub e_shstrndx: Elf32_Half, + } + + pub struct Elf64_Ehdr { + pub e_ident: [::c_uchar; 16], + pub e_type: Elf64_Half, + pub e_machine: Elf64_Half, + pub e_version: Elf64_Word, + pub e_entry: Elf64_Addr, + pub e_phoff: Elf64_Off, + pub e_shoff: Elf64_Off, + pub e_flags: Elf64_Word, + pub e_ehsize: Elf64_Half, + pub e_phentsize: Elf64_Half, + pub e_phnum: Elf64_Half, + pub e_shentsize: Elf64_Half, + pub e_shnum: Elf64_Half, + pub e_shstrndx: Elf64_Half, + } + + pub struct Elf32_Sym { + pub st_name: Elf32_Word, + pub st_value: Elf32_Addr, + pub st_size: Elf32_Word, + pub st_info: ::c_uchar, + pub st_other: ::c_uchar, + pub st_shndx: Elf32_Section, + } + + pub struct Elf64_Sym { + pub st_name: Elf64_Word, + pub st_info: ::c_uchar, + pub st_other: ::c_uchar, + pub st_shndx: Elf64_Section, + pub st_value: Elf64_Addr, + pub st_size: Elf64_Xword, + } + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + pub struct Elf32_Shdr { + pub sh_name: Elf32_Word, + pub sh_type: Elf32_Word, + pub sh_flags: Elf32_Word, + pub sh_addr: Elf32_Addr, + pub sh_offset: Elf32_Off, + pub sh_size: Elf32_Word, + pub sh_link: Elf32_Word, + pub sh_info: Elf32_Word, + pub sh_addralign: Elf32_Word, + pub sh_entsize: Elf32_Word, + } + + pub struct Elf64_Shdr { + pub sh_name: Elf64_Word, + pub sh_type: Elf64_Word, + pub sh_flags: Elf64_Xword, + pub sh_addr: Elf64_Addr, + pub sh_offset: Elf64_Off, + pub sh_size: Elf64_Xword, + pub sh_link: Elf64_Word, + pub sh_info: Elf64_Word, + pub sh_addralign: Elf64_Xword, + pub sh_entsize: Elf64_Xword, + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + + pub struct mntent { + pub mnt_fsname: *mut ::c_char, + pub mnt_dir: *mut ::c_char, + pub mnt_type: *mut ::c_char, + pub mnt_opts: *mut ::c_char, + pub mnt_freq: ::c_int, + pub mnt_passno: ::c_int, + } + + pub struct posix_spawn_file_actions_t { + __allocated: ::c_int, + __used: ::c_int, + __actions: *mut ::c_int, + __pad: [::c_int; 16], + } + + pub struct posix_spawnattr_t { + __flags: ::c_short, + __pgrp: ::pid_t, + __sd: ::sigset_t, + __ss: ::sigset_t, + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __prio: ::c_int, + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __sp: ::sched_param, + __policy: ::c_int, + __pad: [::c_int; 16], + } + + pub struct genlmsghdr { + pub cmd: u8, + pub version: u8, + pub reserved: u16, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + pub struct arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: u32, + pub cookie: u32, + pub len: u32 + } + + pub struct fanotify_response { + pub fd: ::c_int, + pub response: __u32, + } + + pub struct sockaddr_vm { + pub svm_family: ::sa_family_t, + pub svm_reserved1: ::c_ushort, + pub svm_port: ::c_uint, + pub svm_cid: ::c_uint, + pub svm_zero: [u8; 4] + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct sock_extended_err { + pub ee_errno: u32, + pub ee_origin: u8, + pub ee_type: u8, + pub ee_code: u8, + pub ee_pad: u8, + pub ee_info: u32, + pub ee_data: u32, + } + + // linux/can.h + pub struct __c_anonymous_sockaddr_can_tp { + pub rx_id: canid_t, + pub tx_id: canid_t, + } + + pub struct __c_anonymous_sockaddr_can_j1939 { + pub name: u64, + pub pgn: u32, + pub addr: u8, + } + + pub struct can_filter { + pub can_id: canid_t, + pub can_mask: canid_t, + } + + // linux/can/j1939.h + pub struct j1939_filter { + pub name: name_t, + pub name_mask: name_t, + pub pgn: pgn_t, + pub pgn_mask: pgn_t, + pub addr: u8, + pub addr_mask: u8, + } + + // linux/filter.h + pub struct sock_filter { + pub code: ::__u16, + pub jt: ::__u8, + pub jf: ::__u8, + pub k: ::__u32, + } + + pub struct sock_fprog { + pub len: ::c_ushort, + pub filter: *mut sock_filter, + } + + // linux/seccomp.h + pub struct seccomp_data { + pub nr: ::c_int, + pub arch: ::__u32, + pub instruction_pointer: ::__u64, + pub args: [::__u64; 6], + } + + pub struct seccomp_notif_sizes { + pub seccomp_notif: ::__u16, + pub seccomp_notif_resp: ::__u16, + pub seccomp_data: ::__u16, + } + + pub struct seccomp_notif { + pub id: ::__u64, + pub pid: ::__u32, + pub flags: ::__u32, + pub data: seccomp_data, + } + + pub struct seccomp_notif_resp { + pub id: ::__u64, + pub val: ::__s64, + pub error: ::__s32, + pub flags: ::__u32, + } + + pub struct seccomp_notif_addfd { + pub id: ::__u64, + pub flags: ::__u32, + pub srcfd: ::__u32, + pub newfd: ::__u32, + pub newfd_flags: ::__u32, + } + + pub struct nlmsghdr { + pub nlmsg_len: u32, + pub nlmsg_type: u16, + pub nlmsg_flags: u16, + pub nlmsg_seq: u32, + pub nlmsg_pid: u32, + } + + pub struct nlmsgerr { + pub error: ::c_int, + pub msg: nlmsghdr, + } + + pub struct nlattr { + pub nla_len: u16, + pub nla_type: u16, + } + + pub struct file_clone_range { + pub src_fd: ::__s64, + pub src_offset: ::__u64, + pub src_length: ::__u64, + pub dest_offset: ::__u64, + } + + pub struct __c_anonymous_ifru_map { + pub mem_start: ::c_ulong, + pub mem_end: ::c_ulong, + pub base_addr: ::c_ushort, + pub irq: ::c_uchar, + pub dma: ::c_uchar, + pub port: ::c_uchar, + } + + pub struct in6_ifreq { + pub ifr6_addr: ::in6_addr, + pub ifr6_prefixlen: u32, + pub ifr6_ifindex: ::c_int, + } + + pub struct option { + pub name: *const ::c_char, + pub has_arg: ::c_int, + pub flag: *mut ::c_int, + pub val: ::c_int, + } + + // linux/sctp.h + + pub struct sctp_initmsg { + pub sinit_num_ostreams: ::__u16, + pub sinit_max_instreams: ::__u16, + pub sinit_max_attempts: ::__u16, + pub sinit_max_init_timeo: ::__u16, + } + + pub struct sctp_sndrcvinfo { + pub sinfo_stream: ::__u16, + pub sinfo_ssn: ::__u16, + pub sinfo_flags: ::__u16, + pub sinfo_ppid: ::__u32, + pub sinfo_context: ::__u32, + pub sinfo_timetolive: ::__u32, + pub sinfo_tsn: ::__u32, + pub sinfo_cumtsn: ::__u32, + pub sinfo_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_sndinfo { + pub snd_sid: ::__u16, + pub snd_flags: ::__u16, + pub snd_ppid: ::__u32, + pub snd_context: ::__u32, + pub snd_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_rcvinfo { + pub rcv_sid: ::__u16, + pub rcv_ssn: ::__u16, + pub rcv_flags: ::__u16, + pub rcv_ppid: ::__u32, + pub rcv_tsn: ::__u32, + pub rcv_cumtsn: ::__u32, + pub rcv_context: ::__u32, + pub rcv_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_nxtinfo { + pub nxt_sid: ::__u16, + pub nxt_flags: ::__u16, + pub nxt_ppid: ::__u32, + pub nxt_length: ::__u32, + pub nxt_assoc_id: ::sctp_assoc_t, + } + + pub struct sctp_prinfo { + pub pr_policy: ::__u16, + pub pr_value: ::__u32, + } + + pub struct sctp_authinfo { + pub auth_keynumber: ::__u16, + } + + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + // linux/tls.h + + pub struct tls_crypto_info { + pub version: ::__u16, + pub cipher_type: ::__u16, + } + + pub struct tls12_crypto_info_aes_gcm_128 { + pub info: tls_crypto_info, + pub iv: [::c_uchar; TLS_CIPHER_AES_GCM_128_IV_SIZE], + pub key: [::c_uchar; TLS_CIPHER_AES_GCM_128_KEY_SIZE], + pub salt: [::c_uchar; TLS_CIPHER_AES_GCM_128_SALT_SIZE], + pub rec_seq: [::c_uchar; TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_aes_gcm_256 { + pub info: tls_crypto_info, + pub iv: [::c_uchar; TLS_CIPHER_AES_GCM_256_IV_SIZE], + pub key: [::c_uchar; TLS_CIPHER_AES_GCM_256_KEY_SIZE], + pub salt: [::c_uchar; TLS_CIPHER_AES_GCM_256_SALT_SIZE], + pub rec_seq: [::c_uchar; TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_chacha20_poly1305 { + pub info: tls_crypto_info, + pub iv: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE], + pub key: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE], + pub salt: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE], + pub rec_seq: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE], + } +} + +s_no_extra_traits! { + pub struct sockaddr_nl { + pub nl_family: ::sa_family_t, + nl_pad: ::c_ushort, + pub nl_pid: u32, + pub nl_groups: u32 + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_alg { + pub salg_family: ::sa_family_t, + pub salg_type: [::c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [::c_uchar; 64], + } + + pub struct uinput_setup { + pub id: input_id, + pub name: [::c_char; UINPUT_MAX_NAME_SIZE], + pub ff_effects_max: ::__u32, + } + + pub struct uinput_user_dev { + pub name: [::c_char; UINPUT_MAX_NAME_SIZE], + pub id: input_id, + pub ff_effects_max: ::__u32, + pub absmax: [::__s32; ABS_CNT], + pub absmin: [::__s32; ABS_CNT], + pub absfuzz: [::__s32; ABS_CNT], + pub absflat: [::__s32; ABS_CNT], + } + + /// WARNING: The `PartialEq`, `Eq` and `Hash` implementations of this + /// type are unsound and will be removed in the future. + #[deprecated( + note = "this struct has unsafe trait implementations that will be \ + removed in the future", + since = "0.2.80" + )] + pub struct af_alg_iv { + pub ivlen: u32, + pub iv: [::c_uchar; 0], + } + + // x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=21279 + pub struct mq_attr { + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_flags: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_maxmsg: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_msgsize: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_curmsgs: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pad: [i64; 4], + + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_flags: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_maxmsg: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_msgsize: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_curmsgs: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pad: [::c_long; 4], + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_netmask: ::sockaddr, + pub ifru_hwaddr: ::sockaddr, + pub ifru_flags: ::c_short, + pub ifru_ifindex: ::c_int, + pub ifru_metric: ::c_int, + pub ifru_mtu: ::c_int, + pub ifru_map: __c_anonymous_ifru_map, + pub ifru_slave: [::c_char; ::IFNAMSIZ], + pub ifru_newname: [::c_char; ::IFNAMSIZ], + pub ifru_data: *mut ::c_char, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [::c_char; ::IFNAMSIZ], + #[cfg(libc_union)] + pub ifr_ifru: __c_anonymous_ifr_ifru, + #[cfg(not(libc_union))] + pub ifr_ifru: ::sockaddr, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut ::c_char, + pub ifcu_req: *mut ::ifreq, + } + + /* Structure used in SIOCGIFCONF request. Used to retrieve interface + configuration for machine (useful for programs which must know all + networks accessible). */ + pub struct ifconf { + pub ifc_len: ::c_int, /* Size of buffer. */ + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ::ifreq, + } + + pub struct hwtstamp_config { + pub flags: ::c_int, + pub tx_type: ::c_int, + pub rx_filter: ::c_int, + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sched_attr { + pub size: ::__u32, + pub sched_policy: ::__u32, + pub sched_flags: ::__u64, + pub sched_nice: ::__s32, + pub sched_priority: ::__u32, + pub sched_runtime: ::__u64, + pub sched_deadline: ::__u64, + pub sched_period: ::__u64, + } +} + +s_no_extra_traits! { + // linux/net_tstamp.h + #[allow(missing_debug_implementations)] + pub struct sock_txtime { + pub clockid: ::clockid_t, + pub flags: ::__u32, + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + // linux/can.h + #[allow(missing_debug_implementations)] + pub union __c_anonymous_sockaddr_can_can_addr { + pub tp: __c_anonymous_sockaddr_can_tp, + pub j1939: __c_anonymous_sockaddr_can_j1939, + } + + #[allow(missing_debug_implementations)] + pub struct sockaddr_can { + pub can_family: ::sa_family_t, + pub can_ifindex: ::c_int, + pub can_addr: __c_anonymous_sockaddr_can_can_addr, + } + } + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_nl { + fn eq(&self, other: &sockaddr_nl) -> bool { + self.nl_family == other.nl_family && + self.nl_pid == other.nl_pid && + self.nl_groups == other.nl_groups + } + } + impl Eq for sockaddr_nl {} + impl ::fmt::Debug for sockaddr_nl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_nl") + .field("nl_family", &self.nl_family) + .field("nl_pid", &self.nl_pid) + .field("nl_groups", &self.nl_groups) + .finish() + } + } + impl ::hash::Hash for sockaddr_nl { + fn hash(&self, state: &mut H) { + self.nl_family.hash(state); + self.nl_pid.hash(state); + self.nl_groups.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent64 {} + + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_rwlock_t {} + + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_barrier_t { + fn eq(&self, other: &pthread_barrier_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_barrier_t {} + + impl ::fmt::Debug for pthread_barrier_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_barrier_t") + .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_barrier_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for sockaddr_alg { + fn eq(&self, other: &sockaddr_alg) -> bool { + self.salg_family == other.salg_family + && self + .salg_type + .iter() + .zip(other.salg_type.iter()) + .all(|(a, b)| a == b) + && self.salg_feat == other.salg_feat + && self.salg_mask == other.salg_mask + && self + .salg_name + .iter() + .zip(other.salg_name.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_alg {} + + impl ::fmt::Debug for sockaddr_alg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_alg") + .field("salg_family", &self.salg_family) + .field("salg_type", &self.salg_type) + .field("salg_feat", &self.salg_feat) + .field("salg_mask", &self.salg_mask) + .field("salg_name", &&self.salg_name[..]) + .finish() + } + } + + impl ::hash::Hash for sockaddr_alg { + fn hash(&self, state: &mut H) { + self.salg_family.hash(state); + self.salg_type.hash(state); + self.salg_feat.hash(state); + self.salg_mask.hash(state); + self.salg_name.hash(state); + } + } + + impl PartialEq for uinput_setup { + fn eq(&self, other: &uinput_setup) -> bool { + self.id == other.id + && self.name[..] == other.name[..] + && self.ff_effects_max == other.ff_effects_max + } + } + impl Eq for uinput_setup {} + + impl ::fmt::Debug for uinput_setup { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uinput_setup") + .field("id", &self.id) + .field("name", &&self.name[..]) + .field("ff_effects_max", &self.ff_effects_max) + .finish() + } + } + + impl ::hash::Hash for uinput_setup { + fn hash(&self, state: &mut H) { + self.id.hash(state); + self.name.hash(state); + self.ff_effects_max.hash(state); + } + } + + impl PartialEq for uinput_user_dev { + fn eq(&self, other: &uinput_user_dev) -> bool { + self.name[..] == other.name[..] + && self.id == other.id + && self.ff_effects_max == other.ff_effects_max + && self.absmax[..] == other.absmax[..] + && self.absmin[..] == other.absmin[..] + && self.absfuzz[..] == other.absfuzz[..] + && self.absflat[..] == other.absflat[..] + } + } + impl Eq for uinput_user_dev {} + + impl ::fmt::Debug for uinput_user_dev { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uinput_setup") + .field("name", &&self.name[..]) + .field("id", &self.id) + .field("ff_effects_max", &self.ff_effects_max) + .field("absmax", &&self.absmax[..]) + .field("absmin", &&self.absmin[..]) + .field("absfuzz", &&self.absfuzz[..]) + .field("absflat", &&self.absflat[..]) + .finish() + } + } + + impl ::hash::Hash for uinput_user_dev { + fn hash(&self, state: &mut H) { + self.name.hash(state); + self.id.hash(state); + self.ff_effects_max.hash(state); + self.absmax.hash(state); + self.absmin.hash(state); + self.absfuzz.hash(state); + self.absflat.hash(state); + } + } + + #[allow(deprecated)] + impl af_alg_iv { + fn as_slice(&self) -> &[u8] { + unsafe { + ::core::slice::from_raw_parts( + self.iv.as_ptr(), + self.ivlen as usize + ) + } + } + } + + #[allow(deprecated)] + impl PartialEq for af_alg_iv { + fn eq(&self, other: &af_alg_iv) -> bool { + *self.as_slice() == *other.as_slice() + } + } + + #[allow(deprecated)] + impl Eq for af_alg_iv {} + + #[allow(deprecated)] + impl ::fmt::Debug for af_alg_iv { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("af_alg_iv") + .field("ivlen", &self.ivlen) + .finish() + } + } + + #[allow(deprecated)] + impl ::hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } + } + + impl PartialEq for mq_attr { + fn eq(&self, other: &mq_attr) -> bool { + self.mq_flags == other.mq_flags && + self.mq_maxmsg == other.mq_maxmsg && + self.mq_msgsize == other.mq_msgsize && + self.mq_curmsgs == other.mq_curmsgs + } + } + impl Eq for mq_attr {} + impl ::fmt::Debug for mq_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mq_attr") + .field("mq_flags", &self.mq_flags) + .field("mq_maxmsg", &self.mq_maxmsg) + .field("mq_msgsize", &self.mq_msgsize) + .field("mq_curmsgs", &self.mq_curmsgs) + .finish() + } + } + impl ::hash::Hash for mq_attr { + fn hash(&self, state: &mut H) { + self.mq_flags.hash(state); + self.mq_maxmsg.hash(state); + self.mq_msgsize.hash(state); + self.mq_curmsgs.hash(state); + } + } + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifr_ifru { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifru_addr", unsafe { &self.ifru_addr }) + .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) + .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) + .field("ifru_netmask", unsafe { &self.ifru_netmask }) + .field("ifru_hwaddr", unsafe { &self.ifru_hwaddr }) + .field("ifru_flags", unsafe { &self.ifru_flags }) + .field("ifru_ifindex", unsafe { &self.ifru_ifindex }) + .field("ifru_metric", unsafe { &self.ifru_metric }) + .field("ifru_mtu", unsafe { &self.ifru_mtu }) + .field("ifru_map", unsafe { &self.ifru_map }) + .field("ifru_slave", unsafe { &self.ifru_slave }) + .field("ifru_newname", unsafe { &self.ifru_newname }) + .field("ifru_data", unsafe { &self.ifru_data }) + .finish() + } + } + impl ::fmt::Debug for ifreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifreq") + .field("ifr_name", &self.ifr_name) + .field("ifr_ifru", &self.ifr_ifru) + .finish() + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifcu_buf", unsafe { &self.ifcu_buf }) + .field("ifcu_req", unsafe { &self.ifcu_req }) + .finish() + } + } + impl ::fmt::Debug for ifconf { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifconf") + .field("ifc_len", &self.ifc_len) + .field("ifc_ifcu", &self.ifc_ifcu) + .finish() + } + } + impl ::fmt::Debug for hwtstamp_config { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("hwtstamp_config") + .field("flags", &self.flags) + .field("tx_type", &self.tx_type) + .field("rx_filter", &self.rx_filter) + .finish() + } + } + impl PartialEq for hwtstamp_config { + fn eq(&self, other: &hwtstamp_config) -> bool { + self.flags == other.flags && + self.tx_type == other.tx_type && + self.rx_filter == other.rx_filter + } + } + impl Eq for hwtstamp_config {} + impl ::hash::Hash for hwtstamp_config { + fn hash(&self, state: &mut H) { + self.flags.hash(state); + self.tx_type.hash(state); + self.rx_filter.hash(state); + } + } + + impl ::fmt::Debug for sched_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sched_attr") + .field("size", &self.size) + .field("sched_policy", &self.sched_policy) + .field("sched_flags", &self.sched_flags) + .field("sched_nice", &self.sched_nice) + .field("sched_priority", &self.sched_priority) + .field("sched_runtime", &self.sched_runtime) + .field("sched_deadline", &self.sched_deadline) + .field("sched_period", &self.sched_period) + .finish() + } + } + impl PartialEq for sched_attr { + fn eq(&self, other: &sched_attr) -> bool { + self.size == other.size && + self.sched_policy == other.sched_policy && + self.sched_flags == other.sched_flags && + self.sched_nice == other.sched_nice && + self.sched_priority == other.sched_priority && + self.sched_runtime == other.sched_runtime && + self.sched_deadline == other.sched_deadline && + self.sched_period == other.sched_period + } + } + impl Eq for sched_attr {} + impl ::hash::Hash for sched_attr { + fn hash(&self, state: &mut H) { + self.size.hash(state); + self.sched_policy.hash(state); + self.sched_flags.hash(state); + self.sched_nice.hash(state); + self.sched_priority.hash(state); + self.sched_runtime.hash(state); + self.sched_deadline.hash(state); + self.sched_period.hash(state); + } + } + } +} + +cfg_if! { + if #[cfg(any(target_env = "gnu", target_env = "musl", target_env = "ohos"))] { + pub const ABDAY_1: ::nl_item = 0x20000; + pub const ABDAY_2: ::nl_item = 0x20001; + pub const ABDAY_3: ::nl_item = 0x20002; + pub const ABDAY_4: ::nl_item = 0x20003; + pub const ABDAY_5: ::nl_item = 0x20004; + pub const ABDAY_6: ::nl_item = 0x20005; + pub const ABDAY_7: ::nl_item = 0x20006; + + pub const DAY_1: ::nl_item = 0x20007; + pub const DAY_2: ::nl_item = 0x20008; + pub const DAY_3: ::nl_item = 0x20009; + pub const DAY_4: ::nl_item = 0x2000A; + pub const DAY_5: ::nl_item = 0x2000B; + pub const DAY_6: ::nl_item = 0x2000C; + pub const DAY_7: ::nl_item = 0x2000D; + + pub const ABMON_1: ::nl_item = 0x2000E; + pub const ABMON_2: ::nl_item = 0x2000F; + pub const ABMON_3: ::nl_item = 0x20010; + pub const ABMON_4: ::nl_item = 0x20011; + pub const ABMON_5: ::nl_item = 0x20012; + pub const ABMON_6: ::nl_item = 0x20013; + pub const ABMON_7: ::nl_item = 0x20014; + pub const ABMON_8: ::nl_item = 0x20015; + pub const ABMON_9: ::nl_item = 0x20016; + pub const ABMON_10: ::nl_item = 0x20017; + pub const ABMON_11: ::nl_item = 0x20018; + pub const ABMON_12: ::nl_item = 0x20019; + + pub const MON_1: ::nl_item = 0x2001A; + pub const MON_2: ::nl_item = 0x2001B; + pub const MON_3: ::nl_item = 0x2001C; + pub const MON_4: ::nl_item = 0x2001D; + pub const MON_5: ::nl_item = 0x2001E; + pub const MON_6: ::nl_item = 0x2001F; + pub const MON_7: ::nl_item = 0x20020; + pub const MON_8: ::nl_item = 0x20021; + pub const MON_9: ::nl_item = 0x20022; + pub const MON_10: ::nl_item = 0x20023; + pub const MON_11: ::nl_item = 0x20024; + pub const MON_12: ::nl_item = 0x20025; + + pub const AM_STR: ::nl_item = 0x20026; + pub const PM_STR: ::nl_item = 0x20027; + + pub const D_T_FMT: ::nl_item = 0x20028; + pub const D_FMT: ::nl_item = 0x20029; + pub const T_FMT: ::nl_item = 0x2002A; + pub const T_FMT_AMPM: ::nl_item = 0x2002B; + + pub const ERA: ::nl_item = 0x2002C; + pub const ERA_D_FMT: ::nl_item = 0x2002E; + pub const ALT_DIGITS: ::nl_item = 0x2002F; + pub const ERA_D_T_FMT: ::nl_item = 0x20030; + pub const ERA_T_FMT: ::nl_item = 0x20031; + + pub const CODESET: ::nl_item = 14; + pub const CRNCYSTR: ::nl_item = 0x4000F; + pub const RADIXCHAR: ::nl_item = 0x10000; + pub const THOUSEP: ::nl_item = 0x10001; + pub const YESEXPR: ::nl_item = 0x50000; + pub const NOEXPR: ::nl_item = 0x50001; + pub const YESSTR: ::nl_item = 0x50002; + pub const NOSTR: ::nl_item = 0x50003; + } +} + +pub const RUSAGE_CHILDREN: ::c_int = -1; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const MS_NOUSER: ::c_ulong = 0xffffffff80000000; + +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; + +pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; + +// elf.h - Fields in the e_ident array. +pub const EI_NIDENT: usize = 16; + +pub const EI_MAG0: usize = 0; +pub const ELFMAG0: u8 = 0x7f; +pub const EI_MAG1: usize = 1; +pub const ELFMAG1: u8 = b'E'; +pub const EI_MAG2: usize = 2; +pub const ELFMAG2: u8 = b'L'; +pub const EI_MAG3: usize = 3; +pub const ELFMAG3: u8 = b'F'; +pub const SELFMAG: usize = 4; + +pub const EI_CLASS: usize = 4; +pub const ELFCLASSNONE: u8 = 0; +pub const ELFCLASS32: u8 = 1; +pub const ELFCLASS64: u8 = 2; +pub const ELFCLASSNUM: usize = 3; + +pub const EI_DATA: usize = 5; +pub const ELFDATANONE: u8 = 0; +pub const ELFDATA2LSB: u8 = 1; +pub const ELFDATA2MSB: u8 = 2; +pub const ELFDATANUM: usize = 3; + +pub const EI_VERSION: usize = 6; + +pub const EI_OSABI: usize = 7; +pub const ELFOSABI_NONE: u8 = 0; +pub const ELFOSABI_SYSV: u8 = 0; +pub const ELFOSABI_HPUX: u8 = 1; +pub const ELFOSABI_NETBSD: u8 = 2; +pub const ELFOSABI_GNU: u8 = 3; +pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU; +pub const ELFOSABI_SOLARIS: u8 = 6; +pub const ELFOSABI_AIX: u8 = 7; +pub const ELFOSABI_IRIX: u8 = 8; +pub const ELFOSABI_FREEBSD: u8 = 9; +pub const ELFOSABI_TRU64: u8 = 10; +pub const ELFOSABI_MODESTO: u8 = 11; +pub const ELFOSABI_OPENBSD: u8 = 12; +pub const ELFOSABI_ARM: u8 = 97; +pub const ELFOSABI_STANDALONE: u8 = 255; + +pub const EI_ABIVERSION: usize = 8; + +pub const EI_PAD: usize = 9; + +// elf.h - Legal values for e_type (object file type). +pub const ET_NONE: u16 = 0; +pub const ET_REL: u16 = 1; +pub const ET_EXEC: u16 = 2; +pub const ET_DYN: u16 = 3; +pub const ET_CORE: u16 = 4; +pub const ET_NUM: u16 = 5; +pub const ET_LOOS: u16 = 0xfe00; +pub const ET_HIOS: u16 = 0xfeff; +pub const ET_LOPROC: u16 = 0xff00; +pub const ET_HIPROC: u16 = 0xffff; + +// elf.h - Legal values for e_machine (architecture). +pub const EM_NONE: u16 = 0; +pub const EM_M32: u16 = 1; +pub const EM_SPARC: u16 = 2; +pub const EM_386: u16 = 3; +pub const EM_68K: u16 = 4; +pub const EM_88K: u16 = 5; +pub const EM_860: u16 = 7; +pub const EM_MIPS: u16 = 8; +pub const EM_S370: u16 = 9; +pub const EM_MIPS_RS3_LE: u16 = 10; +pub const EM_PARISC: u16 = 15; +pub const EM_VPP500: u16 = 17; +pub const EM_SPARC32PLUS: u16 = 18; +pub const EM_960: u16 = 19; +pub const EM_PPC: u16 = 20; +pub const EM_PPC64: u16 = 21; +pub const EM_S390: u16 = 22; +pub const EM_V800: u16 = 36; +pub const EM_FR20: u16 = 37; +pub const EM_RH32: u16 = 38; +pub const EM_RCE: u16 = 39; +pub const EM_ARM: u16 = 40; +pub const EM_FAKE_ALPHA: u16 = 41; +pub const EM_SH: u16 = 42; +pub const EM_SPARCV9: u16 = 43; +pub const EM_TRICORE: u16 = 44; +pub const EM_ARC: u16 = 45; +pub const EM_H8_300: u16 = 46; +pub const EM_H8_300H: u16 = 47; +pub const EM_H8S: u16 = 48; +pub const EM_H8_500: u16 = 49; +pub const EM_IA_64: u16 = 50; +pub const EM_MIPS_X: u16 = 51; +pub const EM_COLDFIRE: u16 = 52; +pub const EM_68HC12: u16 = 53; +pub const EM_MMA: u16 = 54; +pub const EM_PCP: u16 = 55; +pub const EM_NCPU: u16 = 56; +pub const EM_NDR1: u16 = 57; +pub const EM_STARCORE: u16 = 58; +pub const EM_ME16: u16 = 59; +pub const EM_ST100: u16 = 60; +pub const EM_TINYJ: u16 = 61; +pub const EM_X86_64: u16 = 62; +pub const EM_PDSP: u16 = 63; +pub const EM_FX66: u16 = 66; +pub const EM_ST9PLUS: u16 = 67; +pub const EM_ST7: u16 = 68; +pub const EM_68HC16: u16 = 69; +pub const EM_68HC11: u16 = 70; +pub const EM_68HC08: u16 = 71; +pub const EM_68HC05: u16 = 72; +pub const EM_SVX: u16 = 73; +pub const EM_ST19: u16 = 74; +pub const EM_VAX: u16 = 75; +pub const EM_CRIS: u16 = 76; +pub const EM_JAVELIN: u16 = 77; +pub const EM_FIREPATH: u16 = 78; +pub const EM_ZSP: u16 = 79; +pub const EM_MMIX: u16 = 80; +pub const EM_HUANY: u16 = 81; +pub const EM_PRISM: u16 = 82; +pub const EM_AVR: u16 = 83; +pub const EM_FR30: u16 = 84; +pub const EM_D10V: u16 = 85; +pub const EM_D30V: u16 = 86; +pub const EM_V850: u16 = 87; +pub const EM_M32R: u16 = 88; +pub const EM_MN10300: u16 = 89; +pub const EM_MN10200: u16 = 90; +pub const EM_PJ: u16 = 91; +pub const EM_OPENRISC: u16 = 92; +pub const EM_ARC_A5: u16 = 93; +pub const EM_XTENSA: u16 = 94; +pub const EM_AARCH64: u16 = 183; +pub const EM_TILEPRO: u16 = 188; +pub const EM_TILEGX: u16 = 191; +pub const EM_ALPHA: u16 = 0x9026; + +// elf.h - Legal values for e_version (version). +pub const EV_NONE: u32 = 0; +pub const EV_CURRENT: u32 = 1; +pub const EV_NUM: u32 = 2; + +// elf.h - Legal values for p_type (segment type). +pub const PT_NULL: u32 = 0; +pub const PT_LOAD: u32 = 1; +pub const PT_DYNAMIC: u32 = 2; +pub const PT_INTERP: u32 = 3; +pub const PT_NOTE: u32 = 4; +pub const PT_SHLIB: u32 = 5; +pub const PT_PHDR: u32 = 6; +pub const PT_TLS: u32 = 7; +pub const PT_NUM: u32 = 8; +pub const PT_LOOS: u32 = 0x60000000; +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_STACK: u32 = 0x6474e551; +pub const PT_GNU_RELRO: u32 = 0x6474e552; +pub const PT_LOSUNW: u32 = 0x6ffffffa; +pub const PT_SUNWBSS: u32 = 0x6ffffffa; +pub const PT_SUNWSTACK: u32 = 0x6ffffffb; +pub const PT_HISUNW: u32 = 0x6fffffff; +pub const PT_HIOS: u32 = 0x6fffffff; +pub const PT_LOPROC: u32 = 0x70000000; +pub const PT_HIPROC: u32 = 0x7fffffff; + +// Legal values for p_flags (segment flags). +pub const PF_X: u32 = 1 << 0; +pub const PF_W: u32 = 1 << 1; +pub const PF_R: u32 = 1 << 2; +pub const PF_MASKOS: u32 = 0x0ff00000; +pub const PF_MASKPROC: u32 = 0xf0000000; + +// elf.h - Legal values for a_type (entry type). +pub const AT_NULL: ::c_ulong = 0; +pub const AT_IGNORE: ::c_ulong = 1; +pub const AT_EXECFD: ::c_ulong = 2; +pub const AT_PHDR: ::c_ulong = 3; +pub const AT_PHENT: ::c_ulong = 4; +pub const AT_PHNUM: ::c_ulong = 5; +pub const AT_PAGESZ: ::c_ulong = 6; +pub const AT_BASE: ::c_ulong = 7; +pub const AT_FLAGS: ::c_ulong = 8; +pub const AT_ENTRY: ::c_ulong = 9; +pub const AT_NOTELF: ::c_ulong = 10; +pub const AT_UID: ::c_ulong = 11; +pub const AT_EUID: ::c_ulong = 12; +pub const AT_GID: ::c_ulong = 13; +pub const AT_EGID: ::c_ulong = 14; +pub const AT_PLATFORM: ::c_ulong = 15; +pub const AT_HWCAP: ::c_ulong = 16; +pub const AT_CLKTCK: ::c_ulong = 17; + +pub const AT_SECURE: ::c_ulong = 23; +pub const AT_BASE_PLATFORM: ::c_ulong = 24; +pub const AT_RANDOM: ::c_ulong = 25; +pub const AT_HWCAP2: ::c_ulong = 26; + +pub const AT_EXECFN: ::c_ulong = 31; + +// defined in arch//include/uapi/asm/auxvec.h but has the same value +// wherever it is defined. +pub const AT_SYSINFO_EHDR: ::c_ulong = 33; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_SPAWN_USEVFORK: ::c_int = 64; +pub const POSIX_SPAWN_SETSID: ::c_int = 128; + +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; + +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +pub const F_SEAL_FUTURE_WRITE: ::c_int = 0x0010; + +pub const IFF_LOWER_UP: ::c_int = 0x10000; +pub const IFF_DORMANT: ::c_int = 0x20000; +pub const IFF_ECHO: ::c_int = 0x40000; + +// linux/if_addr.h +pub const IFA_UNSPEC: ::c_ushort = 0; +pub const IFA_ADDRESS: ::c_ushort = 1; +pub const IFA_LOCAL: ::c_ushort = 2; +pub const IFA_LABEL: ::c_ushort = 3; +pub const IFA_BROADCAST: ::c_ushort = 4; +pub const IFA_ANYCAST: ::c_ushort = 5; +pub const IFA_CACHEINFO: ::c_ushort = 6; +pub const IFA_MULTICAST: ::c_ushort = 7; + +pub const IFA_F_SECONDARY: u32 = 0x01; +pub const IFA_F_TEMPORARY: u32 = 0x01; +pub const IFA_F_NODAD: u32 = 0x02; +pub const IFA_F_OPTIMISTIC: u32 = 0x04; +pub const IFA_F_DADFAILED: u32 = 0x08; +pub const IFA_F_HOMEADDRESS: u32 = 0x10; +pub const IFA_F_DEPRECATED: u32 = 0x20; +pub const IFA_F_TENTATIVE: u32 = 0x40; +pub const IFA_F_PERMANENT: u32 = 0x80; + +// linux/if_link.h +pub const IFLA_UNSPEC: ::c_ushort = 0; +pub const IFLA_ADDRESS: ::c_ushort = 1; +pub const IFLA_BROADCAST: ::c_ushort = 2; +pub const IFLA_IFNAME: ::c_ushort = 3; +pub const IFLA_MTU: ::c_ushort = 4; +pub const IFLA_LINK: ::c_ushort = 5; +pub const IFLA_QDISC: ::c_ushort = 6; +pub const IFLA_STATS: ::c_ushort = 7; +pub const IFLA_COST: ::c_ushort = 8; +pub const IFLA_PRIORITY: ::c_ushort = 9; +pub const IFLA_MASTER: ::c_ushort = 10; +pub const IFLA_WIRELESS: ::c_ushort = 11; +pub const IFLA_PROTINFO: ::c_ushort = 12; +pub const IFLA_TXQLEN: ::c_ushort = 13; +pub const IFLA_MAP: ::c_ushort = 14; +pub const IFLA_WEIGHT: ::c_ushort = 15; +pub const IFLA_OPERSTATE: ::c_ushort = 16; +pub const IFLA_LINKMODE: ::c_ushort = 17; +pub const IFLA_LINKINFO: ::c_ushort = 18; +pub const IFLA_NET_NS_PID: ::c_ushort = 19; +pub const IFLA_IFALIAS: ::c_ushort = 20; +pub const IFLA_NUM_VF: ::c_ushort = 21; +pub const IFLA_VFINFO_LIST: ::c_ushort = 22; +pub const IFLA_STATS64: ::c_ushort = 23; +pub const IFLA_VF_PORTS: ::c_ushort = 24; +pub const IFLA_PORT_SELF: ::c_ushort = 25; +pub const IFLA_AF_SPEC: ::c_ushort = 26; +pub const IFLA_GROUP: ::c_ushort = 27; +pub const IFLA_NET_NS_FD: ::c_ushort = 28; +pub const IFLA_EXT_MASK: ::c_ushort = 29; +pub const IFLA_PROMISCUITY: ::c_ushort = 30; +pub const IFLA_NUM_TX_QUEUES: ::c_ushort = 31; +pub const IFLA_NUM_RX_QUEUES: ::c_ushort = 32; +pub const IFLA_CARRIER: ::c_ushort = 33; +pub const IFLA_PHYS_PORT_ID: ::c_ushort = 34; +pub const IFLA_CARRIER_CHANGES: ::c_ushort = 35; +pub const IFLA_PHYS_SWITCH_ID: ::c_ushort = 36; +pub const IFLA_LINK_NETNSID: ::c_ushort = 37; +pub const IFLA_PHYS_PORT_NAME: ::c_ushort = 38; +pub const IFLA_PROTO_DOWN: ::c_ushort = 39; +pub const IFLA_GSO_MAX_SEGS: ::c_ushort = 40; +pub const IFLA_GSO_MAX_SIZE: ::c_ushort = 41; +pub const IFLA_PAD: ::c_ushort = 42; +pub const IFLA_XDP: ::c_ushort = 43; +pub const IFLA_EVENT: ::c_ushort = 44; +pub const IFLA_NEW_NETNSID: ::c_ushort = 45; +pub const IFLA_IF_NETNSID: ::c_ushort = 46; +pub const IFLA_TARGET_NETNSID: ::c_ushort = IFLA_IF_NETNSID; +pub const IFLA_CARRIER_UP_COUNT: ::c_ushort = 47; +pub const IFLA_CARRIER_DOWN_COUNT: ::c_ushort = 48; +pub const IFLA_NEW_IFINDEX: ::c_ushort = 49; +pub const IFLA_MIN_MTU: ::c_ushort = 50; +pub const IFLA_MAX_MTU: ::c_ushort = 51; +pub const IFLA_PROP_LIST: ::c_ushort = 52; +pub const IFLA_ALT_IFNAME: ::c_ushort = 53; +pub const IFLA_PERM_ADDRESS: ::c_ushort = 54; +pub const IFLA_PROTO_DOWN_REASON: ::c_ushort = 55; +pub const IFLA_PARENT_DEV_NAME: ::c_ushort = 56; +pub const IFLA_PARENT_DEV_BUS_NAME: ::c_ushort = 57; +pub const IFLA_GRO_MAX_SIZE: ::c_ushort = 58; +pub const IFLA_TSO_MAX_SIZE: ::c_ushort = 59; +pub const IFLA_TSO_MAX_SEGS: ::c_ushort = 60; +pub const IFLA_ALLMULTI: ::c_ushort = 61; + +pub const IFLA_INFO_UNSPEC: ::c_ushort = 0; +pub const IFLA_INFO_KIND: ::c_ushort = 1; +pub const IFLA_INFO_DATA: ::c_ushort = 2; +pub const IFLA_INFO_XSTATS: ::c_ushort = 3; +pub const IFLA_INFO_SLAVE_KIND: ::c_ushort = 4; +pub const IFLA_INFO_SLAVE_DATA: ::c_ushort = 5; + +// linux/if_tun.h +pub const IFF_TUN: ::c_int = 0x0001; +pub const IFF_TAP: ::c_int = 0x0002; +pub const IFF_NAPI: ::c_int = 0x0010; +pub const IFF_NAPI_FRAGS: ::c_int = 0x0020; +// Used in TUNSETIFF to bring up tun/tap without carrier +pub const IFF_NO_CARRIER: ::c_int = 0x0040; +pub const IFF_NO_PI: ::c_int = 0x1000; +// Read queue size +pub const TUN_READQ_SIZE: ::c_short = 500; +// TUN device type flags: deprecated. Use IFF_TUN/IFF_TAP instead. +pub const TUN_TUN_DEV: ::c_short = ::IFF_TUN as ::c_short; +pub const TUN_TAP_DEV: ::c_short = ::IFF_TAP as ::c_short; +pub const TUN_TYPE_MASK: ::c_short = 0x000f; +// This flag has no real effect +pub const IFF_ONE_QUEUE: ::c_int = 0x2000; +pub const IFF_VNET_HDR: ::c_int = 0x4000; +pub const IFF_TUN_EXCL: ::c_int = 0x8000; +pub const IFF_MULTI_QUEUE: ::c_int = 0x0100; +pub const IFF_ATTACH_QUEUE: ::c_int = 0x0200; +pub const IFF_DETACH_QUEUE: ::c_int = 0x0400; +// read-only flag +pub const IFF_PERSIST: ::c_int = 0x0800; +pub const IFF_NOFILTER: ::c_int = 0x1000; +// Socket options +pub const TUN_TX_TIMESTAMP: ::c_int = 1; +// Features for GSO (TUNSETOFFLOAD) +pub const TUN_F_CSUM: ::c_uint = 0x01; +pub const TUN_F_TSO4: ::c_uint = 0x02; +pub const TUN_F_TSO6: ::c_uint = 0x04; +pub const TUN_F_TSO_ECN: ::c_uint = 0x08; +pub const TUN_F_UFO: ::c_uint = 0x10; +pub const TUN_F_USO4: ::c_uint = 0x20; +pub const TUN_F_USO6: ::c_uint = 0x40; +// Protocol info prepended to the packets (when IFF_NO_PI is not set) +pub const TUN_PKT_STRIP: ::c_int = 0x0001; +// Accept all multicast packets +pub const TUN_FLT_ALLMULTI: ::c_int = 0x0001; + +// Since Linux 3.1 +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x2; + +pub const AT_EACCESS: ::c_int = 0x200; + +// linux/mempolicy.h +pub const MPOL_DEFAULT: ::c_int = 0; +pub const MPOL_PREFERRED: ::c_int = 1; +pub const MPOL_BIND: ::c_int = 2; +pub const MPOL_INTERLEAVE: ::c_int = 3; +pub const MPOL_LOCAL: ::c_int = 4; +pub const MPOL_F_NUMA_BALANCING: ::c_int = 1 << 13; +pub const MPOL_F_RELATIVE_NODES: ::c_int = 1 << 14; +pub const MPOL_F_STATIC_NODES: ::c_int = 1 << 15; + +// linux/membarrier.h +pub const MEMBARRIER_CMD_QUERY: ::c_int = 0; +pub const MEMBARRIER_CMD_GLOBAL: ::c_int = 1 << 0; +pub const MEMBARRIER_CMD_GLOBAL_EXPEDITED: ::c_int = 1 << 1; +pub const MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: ::c_int = 1 << 2; +pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED: ::c_int = 1 << 3; +pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: ::c_int = 1 << 4; +pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 5; +pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 6; +pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 7; +pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 8; + +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} +pub const PTHREAD_ONCE_INIT: pthread_once_t = 0; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_MUTEX_STALLED: ::c_int = 0; +pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1; +pub const PTHREAD_PRIO_NONE: ::c_int = 0; +pub const PTHREAD_PRIO_INHERIT: ::c_int = 1; +pub const PTHREAD_PRIO_PROTECT: ::c_int = 2; +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_INHERIT_SCHED: ::c_int = 0; +pub const PTHREAD_EXPLICIT_SCHED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const RENAME_NOREPLACE: ::c_uint = 1; +pub const RENAME_EXCHANGE: ::c_uint = 2; +pub const RENAME_WHITEOUT: ::c_uint = 4; + +// netinet/in.h +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +#[deprecated( + since = "0.2.80", + note = "This value was increased in the newer kernel \ + and we'll change this following upstream in the future release. \ + See #1896 for more info." +)] +pub const IPPROTO_MAX: ::c_int = 256; + +// System V IPC +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_CREAT: ::c_int = 0o1000; +pub const IPC_EXCL: ::c_int = 0o2000; +pub const IPC_NOWAIT: ::c_int = 0o4000; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; +pub const IPC_INFO: ::c_int = 3; +pub const MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; +pub const MSG_NOTIFICATION: ::c_int = 0x8000; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; +pub const MSG_ZEROCOPY: ::c_int = 0x4000000; + +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_REMAP: ::c_int = 0o40000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; + +pub const SHM_HUGETLB: ::c_int = 0o4000; +#[cfg(not(all(target_env = "uclibc", target_arch = "mips")))] +pub const SHM_NORESERVE: ::c_int = 0o10000; + +pub const QFMT_VFS_OLD: ::c_int = 1; +pub const QFMT_VFS_V0: ::c_int = 2; +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; +pub const NI_IDN: ::c_int = 32; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + pub const AIO_CANCELED: ::c_int = 0; + pub const AIO_NOTCANCELED: ::c_int = 1; + pub const AIO_ALLDONE: ::c_int = 2; + pub const LIO_READ: ::c_int = 0; + pub const LIO_WRITE: ::c_int = 1; + pub const LIO_NOP: ::c_int = 2; + pub const LIO_WAIT: ::c_int = 0; + pub const LIO_NOWAIT: ::c_int = 1; + pub const RUSAGE_THREAD: ::c_int = 1; + pub const MSG_COPY: ::c_int = 0o40000; + pub const SHM_EXEC: ::c_int = 0o100000; + pub const IPV6_MULTICAST_ALL: ::c_int = 29; + pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30; + pub const PACKET_MR_UNICAST: ::c_int = 3; + pub const PTRACE_EVENT_STOP: ::c_int = 128; + pub const UDP_SEGMENT: ::c_int = 103; + pub const UDP_GRO: ::c_int = 104; + } +} + +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; +pub const MREMAP_DONTUNMAP: ::c_int = 4; + +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +pub const PR_GET_TIMING: ::c_int = 13; +pub const PR_SET_TIMING: ::c_int = 14; +pub const PR_TIMING_STATISTICAL: ::c_int = 0; +pub const PR_TIMING_TIMESTAMP: ::c_int = 1; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +pub const PR_SET_MM_MAP: ::c_int = 14; +pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + +pub const PR_SET_PTRACER: ::c_int = 0x59616d61; +pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff; + +pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; +pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2; +pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3; +pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4; + +pub const PR_SET_VMA: ::c_int = 0x53564d41; +pub const PR_SET_VMA_ANON_NAME: ::c_int = 0; + +pub const PR_SCHED_CORE: ::c_int = 62; +pub const PR_SCHED_CORE_GET: ::c_int = 0; +pub const PR_SCHED_CORE_CREATE: ::c_int = 1; +pub const PR_SCHED_CORE_SHARE_TO: ::c_int = 2; +pub const PR_SCHED_CORE_SHARE_FROM: ::c_int = 3; +pub const PR_SCHED_CORE_MAX: ::c_int = 4; +pub const PR_SCHED_CORE_SCOPE_THREAD: ::c_int = 0; +pub const PR_SCHED_CORE_SCOPE_THREAD_GROUP: ::c_int = 1; +pub const PR_SCHED_CORE_SCOPE_PROCESS_GROUP: ::c_int = 2; + +pub const GRND_NONBLOCK: ::c_uint = 0x0001; +pub const GRND_RANDOM: ::c_uint = 0x0002; +pub const GRND_INSECURE: ::c_uint = 0x0004; + +// +pub const SECCOMP_MODE_DISABLED: ::c_uint = 0; +pub const SECCOMP_MODE_STRICT: ::c_uint = 1; +pub const SECCOMP_MODE_FILTER: ::c_uint = 2; + +pub const SECCOMP_SET_MODE_STRICT: ::c_uint = 0; +pub const SECCOMP_SET_MODE_FILTER: ::c_uint = 1; +pub const SECCOMP_GET_ACTION_AVAIL: ::c_uint = 2; +pub const SECCOMP_GET_NOTIF_SIZES: ::c_uint = 3; + +pub const SECCOMP_FILTER_FLAG_TSYNC: ::c_ulong = 1; +pub const SECCOMP_FILTER_FLAG_LOG: ::c_ulong = 2; +pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: ::c_ulong = 4; +pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: ::c_ulong = 8; +pub const SECCOMP_FILTER_FLAG_TSYNC_ESRCH: ::c_ulong = 16; +pub const SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV: ::c_ulong = 32; + +pub const SECCOMP_RET_KILL_PROCESS: ::c_uint = 0x80000000; +pub const SECCOMP_RET_KILL_THREAD: ::c_uint = 0x00000000; +pub const SECCOMP_RET_KILL: ::c_uint = SECCOMP_RET_KILL_THREAD; +pub const SECCOMP_RET_TRAP: ::c_uint = 0x00030000; +pub const SECCOMP_RET_ERRNO: ::c_uint = 0x00050000; +pub const SECCOMP_RET_TRACE: ::c_uint = 0x7ff00000; +pub const SECCOMP_RET_LOG: ::c_uint = 0x7ffc0000; +pub const SECCOMP_RET_ALLOW: ::c_uint = 0x7fff0000; + +pub const SECCOMP_RET_ACTION_FULL: ::c_uint = 0xffff0000; +pub const SECCOMP_RET_ACTION: ::c_uint = 0x7fff0000; +pub const SECCOMP_RET_DATA: ::c_uint = 0x0000ffff; + +pub const SECCOMP_USER_NOTIF_FLAG_CONTINUE: ::c_ulong = 1; + +pub const SECCOMP_ADDFD_FLAG_SETFD: ::c_ulong = 1; +pub const SECCOMP_ADDFD_FLAG_SEND: ::c_ulong = 2; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const TFD_NONBLOCK: ::c_int = O_NONBLOCK; +pub const TFD_TIMER_ABSTIME: ::c_int = 1; +pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 2; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +#[deprecated( + since = "0.2.55", + note = "ENOATTR is not available on Linux; use ENODATA instead" +)] +pub const ENOATTR: ::c_int = ::ENODATA; + +pub const SO_ORIGINAL_DST: ::c_int = 80; + +pub const IP_RECVFRAGSIZE: ::c_int = 25; + +pub const IPV6_FLOWINFO: ::c_int = 11; +pub const IPV6_FLOWLABEL_MGR: ::c_int = 32; +pub const IPV6_FLOWINFO_SEND: ::c_int = 33; +pub const IPV6_RECVFRAGSIZE: ::c_int = 77; +pub const IPV6_FREEBIND: ::c_int = 78; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff; +pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000; + +pub const IPV6_RTHDR_LOOSE: ::c_int = 0; +pub const IPV6_RTHDR_STRICT: ::c_int = 1; + +// SO_MEMINFO offsets +pub const SK_MEMINFO_RMEM_ALLOC: ::c_int = 0; +pub const SK_MEMINFO_RCVBUF: ::c_int = 1; +pub const SK_MEMINFO_WMEM_ALLOC: ::c_int = 2; +pub const SK_MEMINFO_SNDBUF: ::c_int = 3; +pub const SK_MEMINFO_FWD_ALLOC: ::c_int = 4; +pub const SK_MEMINFO_WMEM_QUEUED: ::c_int = 5; +pub const SK_MEMINFO_OPTMEM: ::c_int = 6; +pub const SK_MEMINFO_BACKLOG: ::c_int = 7; +pub const SK_MEMINFO_DROPS: ::c_int = 8; + +pub const IUTF8: ::tcflag_t = 0x00004000; +#[cfg(not(all(target_env = "uclibc", target_arch = "mips")))] +pub const CMSPAR: ::tcflag_t = 0o10000000000; + +pub const MFD_CLOEXEC: ::c_uint = 0x0001; +pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; +pub const MFD_HUGETLB: ::c_uint = 0x0004; +pub const MFD_NOEXEC_SEAL: ::c_uint = 0x0008; +pub const MFD_EXEC: ::c_uint = 0x0010; +pub const MFD_HUGE_64KB: ::c_uint = 0x40000000; +pub const MFD_HUGE_512KB: ::c_uint = 0x4c000000; +pub const MFD_HUGE_1MB: ::c_uint = 0x50000000; +pub const MFD_HUGE_2MB: ::c_uint = 0x54000000; +pub const MFD_HUGE_8MB: ::c_uint = 0x5c000000; +pub const MFD_HUGE_16MB: ::c_uint = 0x60000000; +pub const MFD_HUGE_32MB: ::c_uint = 0x64000000; +pub const MFD_HUGE_256MB: ::c_uint = 0x70000000; +pub const MFD_HUGE_512MB: ::c_uint = 0x74000000; +pub const MFD_HUGE_1GB: ::c_uint = 0x78000000; +pub const MFD_HUGE_2GB: ::c_uint = 0x7c000000; +pub const MFD_HUGE_16GB: ::c_uint = 0x88000000; +pub const MFD_HUGE_MASK: ::c_uint = 63; +pub const MFD_HUGE_SHIFT: ::c_uint = 26; + +// linux/close_range.h +pub const CLOSE_RANGE_UNSHARE: ::c_uint = 1 << 1; +pub const CLOSE_RANGE_CLOEXEC: ::c_uint = 1 << 2; + +// linux/filter.h +pub const SKF_AD_OFF: ::c_int = -0x1000; +pub const SKF_AD_PROTOCOL: ::c_int = 0; +pub const SKF_AD_PKTTYPE: ::c_int = 4; +pub const SKF_AD_IFINDEX: ::c_int = 8; +pub const SKF_AD_NLATTR: ::c_int = 12; +pub const SKF_AD_NLATTR_NEST: ::c_int = 16; +pub const SKF_AD_MARK: ::c_int = 20; +pub const SKF_AD_QUEUE: ::c_int = 24; +pub const SKF_AD_HATYPE: ::c_int = 28; +pub const SKF_AD_RXHASH: ::c_int = 32; +pub const SKF_AD_CPU: ::c_int = 36; +pub const SKF_AD_ALU_XOR_X: ::c_int = 40; +pub const SKF_AD_VLAN_TAG: ::c_int = 44; +pub const SKF_AD_VLAN_TAG_PRESENT: ::c_int = 48; +pub const SKF_AD_PAY_OFFSET: ::c_int = 52; +pub const SKF_AD_RANDOM: ::c_int = 56; +pub const SKF_AD_VLAN_TPID: ::c_int = 60; +pub const SKF_AD_MAX: ::c_int = 64; +pub const SKF_NET_OFF: ::c_int = -0x100000; +pub const SKF_LL_OFF: ::c_int = -0x200000; +pub const BPF_NET_OFF: ::c_int = SKF_NET_OFF; +pub const BPF_LL_OFF: ::c_int = SKF_LL_OFF; +pub const BPF_MEMWORDS: ::c_int = 16; +pub const BPF_MAXINSNS: ::c_int = 4096; + +// linux/bpf_common.h +pub const BPF_LD: ::__u32 = 0x00; +pub const BPF_LDX: ::__u32 = 0x01; +pub const BPF_ST: ::__u32 = 0x02; +pub const BPF_STX: ::__u32 = 0x03; +pub const BPF_ALU: ::__u32 = 0x04; +pub const BPF_JMP: ::__u32 = 0x05; +pub const BPF_RET: ::__u32 = 0x06; +pub const BPF_MISC: ::__u32 = 0x07; +pub const BPF_W: ::__u32 = 0x00; +pub const BPF_H: ::__u32 = 0x08; +pub const BPF_B: ::__u32 = 0x10; +pub const BPF_IMM: ::__u32 = 0x00; +pub const BPF_ABS: ::__u32 = 0x20; +pub const BPF_IND: ::__u32 = 0x40; +pub const BPF_MEM: ::__u32 = 0x60; +pub const BPF_LEN: ::__u32 = 0x80; +pub const BPF_MSH: ::__u32 = 0xa0; +pub const BPF_ADD: ::__u32 = 0x00; +pub const BPF_SUB: ::__u32 = 0x10; +pub const BPF_MUL: ::__u32 = 0x20; +pub const BPF_DIV: ::__u32 = 0x30; +pub const BPF_OR: ::__u32 = 0x40; +pub const BPF_AND: ::__u32 = 0x50; +pub const BPF_LSH: ::__u32 = 0x60; +pub const BPF_RSH: ::__u32 = 0x70; +pub const BPF_NEG: ::__u32 = 0x80; +pub const BPF_MOD: ::__u32 = 0x90; +pub const BPF_XOR: ::__u32 = 0xa0; +pub const BPF_JA: ::__u32 = 0x00; +pub const BPF_JEQ: ::__u32 = 0x10; +pub const BPF_JGT: ::__u32 = 0x20; +pub const BPF_JGE: ::__u32 = 0x30; +pub const BPF_JSET: ::__u32 = 0x40; +pub const BPF_K: ::__u32 = 0x00; +pub const BPF_X: ::__u32 = 0x08; + +// linux/openat2.h +pub const RESOLVE_NO_XDEV: ::__u64 = 0x01; +pub const RESOLVE_NO_MAGICLINKS: ::__u64 = 0x02; +pub const RESOLVE_NO_SYMLINKS: ::__u64 = 0x04; +pub const RESOLVE_BENEATH: ::__u64 = 0x08; +pub const RESOLVE_IN_ROOT: ::__u64 = 0x10; +pub const RESOLVE_CACHED: ::__u64 = 0x20; + +// linux/if_ether.h +pub const ETH_ALEN: ::c_int = 6; +pub const ETH_HLEN: ::c_int = 14; +pub const ETH_ZLEN: ::c_int = 60; +pub const ETH_DATA_LEN: ::c_int = 1500; +pub const ETH_FRAME_LEN: ::c_int = 1514; +pub const ETH_FCS_LEN: ::c_int = 4; + +// These are the defined Ethernet Protocol ID's. +pub const ETH_P_LOOP: ::c_int = 0x0060; +pub const ETH_P_PUP: ::c_int = 0x0200; +pub const ETH_P_PUPAT: ::c_int = 0x0201; +pub const ETH_P_IP: ::c_int = 0x0800; +pub const ETH_P_X25: ::c_int = 0x0805; +pub const ETH_P_ARP: ::c_int = 0x0806; +pub const ETH_P_BPQ: ::c_int = 0x08FF; +pub const ETH_P_IEEEPUP: ::c_int = 0x0a00; +pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01; +pub const ETH_P_BATMAN: ::c_int = 0x4305; +pub const ETH_P_DEC: ::c_int = 0x6000; +pub const ETH_P_DNA_DL: ::c_int = 0x6001; +pub const ETH_P_DNA_RC: ::c_int = 0x6002; +pub const ETH_P_DNA_RT: ::c_int = 0x6003; +pub const ETH_P_LAT: ::c_int = 0x6004; +pub const ETH_P_DIAG: ::c_int = 0x6005; +pub const ETH_P_CUST: ::c_int = 0x6006; +pub const ETH_P_SCA: ::c_int = 0x6007; +pub const ETH_P_TEB: ::c_int = 0x6558; +pub const ETH_P_RARP: ::c_int = 0x8035; +pub const ETH_P_ATALK: ::c_int = 0x809B; +pub const ETH_P_AARP: ::c_int = 0x80F3; +pub const ETH_P_8021Q: ::c_int = 0x8100; +pub const ETH_P_IPX: ::c_int = 0x8137; +pub const ETH_P_IPV6: ::c_int = 0x86DD; +pub const ETH_P_PAUSE: ::c_int = 0x8808; +pub const ETH_P_SLOW: ::c_int = 0x8809; +pub const ETH_P_WCCP: ::c_int = 0x883E; +pub const ETH_P_MPLS_UC: ::c_int = 0x8847; +pub const ETH_P_MPLS_MC: ::c_int = 0x8848; +pub const ETH_P_ATMMPOA: ::c_int = 0x884c; +pub const ETH_P_PPP_DISC: ::c_int = 0x8863; +pub const ETH_P_PPP_SES: ::c_int = 0x8864; +pub const ETH_P_LINK_CTL: ::c_int = 0x886c; +pub const ETH_P_ATMFATE: ::c_int = 0x8884; +pub const ETH_P_PAE: ::c_int = 0x888E; +pub const ETH_P_AOE: ::c_int = 0x88A2; +pub const ETH_P_8021AD: ::c_int = 0x88A8; +pub const ETH_P_802_EX1: ::c_int = 0x88B5; +pub const ETH_P_TIPC: ::c_int = 0x88CA; +pub const ETH_P_MACSEC: ::c_int = 0x88E5; +pub const ETH_P_8021AH: ::c_int = 0x88E7; +pub const ETH_P_MVRP: ::c_int = 0x88F5; +pub const ETH_P_1588: ::c_int = 0x88F7; +pub const ETH_P_PRP: ::c_int = 0x88FB; +pub const ETH_P_FCOE: ::c_int = 0x8906; +pub const ETH_P_TDLS: ::c_int = 0x890D; +pub const ETH_P_FIP: ::c_int = 0x8914; +pub const ETH_P_80221: ::c_int = 0x8917; +pub const ETH_P_LOOPBACK: ::c_int = 0x9000; +pub const ETH_P_QINQ1: ::c_int = 0x9100; +pub const ETH_P_QINQ2: ::c_int = 0x9200; +pub const ETH_P_QINQ3: ::c_int = 0x9300; +pub const ETH_P_EDSA: ::c_int = 0xDADA; +pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB; + +pub const ETH_P_802_3_MIN: ::c_int = 0x0600; + +// Non DIX types. Won't clash for 1500 types. +pub const ETH_P_802_3: ::c_int = 0x0001; +pub const ETH_P_AX25: ::c_int = 0x0002; +pub const ETH_P_ALL: ::c_int = 0x0003; +pub const ETH_P_802_2: ::c_int = 0x0004; +pub const ETH_P_SNAP: ::c_int = 0x0005; +pub const ETH_P_DDCMP: ::c_int = 0x0006; +pub const ETH_P_WAN_PPP: ::c_int = 0x0007; +pub const ETH_P_PPP_MP: ::c_int = 0x0008; +pub const ETH_P_LOCALTALK: ::c_int = 0x0009; +pub const ETH_P_CANFD: ::c_int = 0x000D; +pub const ETH_P_PPPTALK: ::c_int = 0x0010; +pub const ETH_P_TR_802_2: ::c_int = 0x0011; +pub const ETH_P_MOBITEX: ::c_int = 0x0015; +pub const ETH_P_CONTROL: ::c_int = 0x0016; +pub const ETH_P_IRDA: ::c_int = 0x0017; +pub const ETH_P_ECONET: ::c_int = 0x0018; +pub const ETH_P_HDLC: ::c_int = 0x0019; +pub const ETH_P_ARCNET: ::c_int = 0x001A; +pub const ETH_P_DSA: ::c_int = 0x001B; +pub const ETH_P_TRAILER: ::c_int = 0x001C; +pub const ETH_P_PHONET: ::c_int = 0x00F5; +pub const ETH_P_IEEE802154: ::c_int = 0x00F6; +pub const ETH_P_CAIF: ::c_int = 0x00F7; + +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x04; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x08; +pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x10; +pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x20; + +pub const NLMSG_NOOP: ::c_int = 0x1; +pub const NLMSG_ERROR: ::c_int = 0x2; +pub const NLMSG_DONE: ::c_int = 0x3; +pub const NLMSG_OVERRUN: ::c_int = 0x4; +pub const NLMSG_MIN_TYPE: ::c_int = 0x10; + +// linux/netfilter/nfnetlink.h +pub const NFNLGRP_NONE: ::c_int = 0; +pub const NFNLGRP_CONNTRACK_NEW: ::c_int = 1; +pub const NFNLGRP_CONNTRACK_UPDATE: ::c_int = 2; +pub const NFNLGRP_CONNTRACK_DESTROY: ::c_int = 3; +pub const NFNLGRP_CONNTRACK_EXP_NEW: ::c_int = 4; +pub const NFNLGRP_CONNTRACK_EXP_UPDATE: ::c_int = 5; +pub const NFNLGRP_CONNTRACK_EXP_DESTROY: ::c_int = 6; +pub const NFNLGRP_NFTABLES: ::c_int = 7; +pub const NFNLGRP_ACCT_QUOTA: ::c_int = 8; +pub const NFNLGRP_NFTRACE: ::c_int = 9; + +pub const NFNETLINK_V0: ::c_int = 0; + +pub const NFNL_SUBSYS_NONE: ::c_int = 0; +pub const NFNL_SUBSYS_CTNETLINK: ::c_int = 1; +pub const NFNL_SUBSYS_CTNETLINK_EXP: ::c_int = 2; +pub const NFNL_SUBSYS_QUEUE: ::c_int = 3; +pub const NFNL_SUBSYS_ULOG: ::c_int = 4; +pub const NFNL_SUBSYS_OSF: ::c_int = 5; +pub const NFNL_SUBSYS_IPSET: ::c_int = 6; +pub const NFNL_SUBSYS_ACCT: ::c_int = 7; +pub const NFNL_SUBSYS_CTNETLINK_TIMEOUT: ::c_int = 8; +pub const NFNL_SUBSYS_CTHELPER: ::c_int = 9; +pub const NFNL_SUBSYS_NFTABLES: ::c_int = 10; +pub const NFNL_SUBSYS_NFT_COMPAT: ::c_int = 11; +pub const NFNL_SUBSYS_HOOK: ::c_int = 12; +pub const NFNL_SUBSYS_COUNT: ::c_int = 13; + +pub const NFNL_MSG_BATCH_BEGIN: ::c_int = NLMSG_MIN_TYPE; +pub const NFNL_MSG_BATCH_END: ::c_int = NLMSG_MIN_TYPE + 1; + +pub const NFNL_BATCH_UNSPEC: ::c_int = 0; +pub const NFNL_BATCH_GENID: ::c_int = 1; + +// linux/netfilter/nfnetlink_log.h +pub const NFULNL_MSG_PACKET: ::c_int = 0; +pub const NFULNL_MSG_CONFIG: ::c_int = 1; + +pub const NFULA_VLAN_UNSPEC: ::c_int = 0; +pub const NFULA_VLAN_PROTO: ::c_int = 1; +pub const NFULA_VLAN_TCI: ::c_int = 2; + +pub const NFULA_UNSPEC: ::c_int = 0; +pub const NFULA_PACKET_HDR: ::c_int = 1; +pub const NFULA_MARK: ::c_int = 2; +pub const NFULA_TIMESTAMP: ::c_int = 3; +pub const NFULA_IFINDEX_INDEV: ::c_int = 4; +pub const NFULA_IFINDEX_OUTDEV: ::c_int = 5; +pub const NFULA_IFINDEX_PHYSINDEV: ::c_int = 6; +pub const NFULA_IFINDEX_PHYSOUTDEV: ::c_int = 7; +pub const NFULA_HWADDR: ::c_int = 8; +pub const NFULA_PAYLOAD: ::c_int = 9; +pub const NFULA_PREFIX: ::c_int = 10; +pub const NFULA_UID: ::c_int = 11; +pub const NFULA_SEQ: ::c_int = 12; +pub const NFULA_SEQ_GLOBAL: ::c_int = 13; +pub const NFULA_GID: ::c_int = 14; +pub const NFULA_HWTYPE: ::c_int = 15; +pub const NFULA_HWHEADER: ::c_int = 16; +pub const NFULA_HWLEN: ::c_int = 17; +pub const NFULA_CT: ::c_int = 18; +pub const NFULA_CT_INFO: ::c_int = 19; +pub const NFULA_VLAN: ::c_int = 20; +pub const NFULA_L2HDR: ::c_int = 21; + +pub const NFULNL_CFG_CMD_NONE: ::c_int = 0; +pub const NFULNL_CFG_CMD_BIND: ::c_int = 1; +pub const NFULNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFULNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFULNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFULA_CFG_UNSPEC: ::c_int = 0; +pub const NFULA_CFG_CMD: ::c_int = 1; +pub const NFULA_CFG_MODE: ::c_int = 2; +pub const NFULA_CFG_NLBUFSIZ: ::c_int = 3; +pub const NFULA_CFG_TIMEOUT: ::c_int = 4; +pub const NFULA_CFG_QTHRESH: ::c_int = 5; +pub const NFULA_CFG_FLAGS: ::c_int = 6; + +pub const NFULNL_COPY_NONE: ::c_int = 0x00; +pub const NFULNL_COPY_META: ::c_int = 0x01; +pub const NFULNL_COPY_PACKET: ::c_int = 0x02; + +pub const NFULNL_CFG_F_SEQ: ::c_int = 0x0001; +pub const NFULNL_CFG_F_SEQ_GLOBAL: ::c_int = 0x0002; +pub const NFULNL_CFG_F_CONNTRACK: ::c_int = 0x0004; + +// linux/netfilter/nfnetlink_queue.h +pub const NFQNL_MSG_PACKET: ::c_int = 0; +pub const NFQNL_MSG_VERDICT: ::c_int = 1; +pub const NFQNL_MSG_CONFIG: ::c_int = 2; +pub const NFQNL_MSG_VERDICT_BATCH: ::c_int = 3; + +pub const NFQA_UNSPEC: ::c_int = 0; +pub const NFQA_PACKET_HDR: ::c_int = 1; +pub const NFQA_VERDICT_HDR: ::c_int = 2; +pub const NFQA_MARK: ::c_int = 3; +pub const NFQA_TIMESTAMP: ::c_int = 4; +pub const NFQA_IFINDEX_INDEV: ::c_int = 5; +pub const NFQA_IFINDEX_OUTDEV: ::c_int = 6; +pub const NFQA_IFINDEX_PHYSINDEV: ::c_int = 7; +pub const NFQA_IFINDEX_PHYSOUTDEV: ::c_int = 8; +pub const NFQA_HWADDR: ::c_int = 9; +pub const NFQA_PAYLOAD: ::c_int = 10; +pub const NFQA_CT: ::c_int = 11; +pub const NFQA_CT_INFO: ::c_int = 12; +pub const NFQA_CAP_LEN: ::c_int = 13; +pub const NFQA_SKB_INFO: ::c_int = 14; +pub const NFQA_EXP: ::c_int = 15; +pub const NFQA_UID: ::c_int = 16; +pub const NFQA_GID: ::c_int = 17; +pub const NFQA_SECCTX: ::c_int = 18; +pub const NFQA_VLAN: ::c_int = 19; +pub const NFQA_L2HDR: ::c_int = 20; +pub const NFQA_PRIORITY: ::c_int = 21; + +pub const NFQA_VLAN_UNSPEC: ::c_int = 0; +pub const NFQA_VLAN_PROTO: ::c_int = 1; +pub const NFQA_VLAN_TCI: ::c_int = 2; + +pub const NFQNL_CFG_CMD_NONE: ::c_int = 0; +pub const NFQNL_CFG_CMD_BIND: ::c_int = 1; +pub const NFQNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFQNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFQNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFQNL_COPY_NONE: ::c_int = 0; +pub const NFQNL_COPY_META: ::c_int = 1; +pub const NFQNL_COPY_PACKET: ::c_int = 2; + +pub const NFQA_CFG_UNSPEC: ::c_int = 0; +pub const NFQA_CFG_CMD: ::c_int = 1; +pub const NFQA_CFG_PARAMS: ::c_int = 2; +pub const NFQA_CFG_QUEUE_MAXLEN: ::c_int = 3; +pub const NFQA_CFG_MASK: ::c_int = 4; +pub const NFQA_CFG_FLAGS: ::c_int = 5; + +pub const NFQA_CFG_F_FAIL_OPEN: ::c_int = 0x0001; +pub const NFQA_CFG_F_CONNTRACK: ::c_int = 0x0002; +pub const NFQA_CFG_F_GSO: ::c_int = 0x0004; +pub const NFQA_CFG_F_UID_GID: ::c_int = 0x0008; +pub const NFQA_CFG_F_SECCTX: ::c_int = 0x0010; +pub const NFQA_CFG_F_MAX: ::c_int = 0x0020; + +pub const NFQA_SKB_CSUMNOTREADY: ::c_int = 0x0001; +pub const NFQA_SKB_GSO: ::c_int = 0x0002; +pub const NFQA_SKB_CSUM_NOTVERIFIED: ::c_int = 0x0004; + +// linux/genetlink.h + +pub const GENL_NAMSIZ: ::c_int = 16; + +pub const GENL_MIN_ID: ::c_int = NLMSG_MIN_TYPE; +pub const GENL_MAX_ID: ::c_int = 1023; + +pub const GENL_ADMIN_PERM: ::c_int = 0x01; +pub const GENL_CMD_CAP_DO: ::c_int = 0x02; +pub const GENL_CMD_CAP_DUMP: ::c_int = 0x04; +pub const GENL_CMD_CAP_HASPOL: ::c_int = 0x08; + +pub const GENL_ID_CTRL: ::c_int = NLMSG_MIN_TYPE; + +pub const CTRL_CMD_UNSPEC: ::c_int = 0; +pub const CTRL_CMD_NEWFAMILY: ::c_int = 1; +pub const CTRL_CMD_DELFAMILY: ::c_int = 2; +pub const CTRL_CMD_GETFAMILY: ::c_int = 3; +pub const CTRL_CMD_NEWOPS: ::c_int = 4; +pub const CTRL_CMD_DELOPS: ::c_int = 5; +pub const CTRL_CMD_GETOPS: ::c_int = 6; +pub const CTRL_CMD_NEWMCAST_GRP: ::c_int = 7; +pub const CTRL_CMD_DELMCAST_GRP: ::c_int = 8; +pub const CTRL_CMD_GETMCAST_GRP: ::c_int = 9; + +pub const CTRL_ATTR_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_FAMILY_ID: ::c_int = 1; +pub const CTRL_ATTR_FAMILY_NAME: ::c_int = 2; +pub const CTRL_ATTR_VERSION: ::c_int = 3; +pub const CTRL_ATTR_HDRSIZE: ::c_int = 4; +pub const CTRL_ATTR_MAXATTR: ::c_int = 5; +pub const CTRL_ATTR_OPS: ::c_int = 6; +pub const CTRL_ATTR_MCAST_GROUPS: ::c_int = 7; + +pub const CTRL_ATTR_OP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_OP_ID: ::c_int = 1; +pub const CTRL_ATTR_OP_FLAGS: ::c_int = 2; + +pub const CTRL_ATTR_MCAST_GRP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_MCAST_GRP_NAME: ::c_int = 1; +pub const CTRL_ATTR_MCAST_GRP_ID: ::c_int = 2; + +// linux/if_packet.h +pub const PACKET_ADD_MEMBERSHIP: ::c_int = 1; +pub const PACKET_DROP_MEMBERSHIP: ::c_int = 2; + +pub const PACKET_MR_MULTICAST: ::c_int = 0; +pub const PACKET_MR_PROMISC: ::c_int = 1; +pub const PACKET_MR_ALLMULTI: ::c_int = 2; + +// linux/netfilter.h +pub const NF_DROP: ::c_int = 0; +pub const NF_ACCEPT: ::c_int = 1; +pub const NF_STOLEN: ::c_int = 2; +pub const NF_QUEUE: ::c_int = 3; +pub const NF_REPEAT: ::c_int = 4; +pub const NF_STOP: ::c_int = 5; +pub const NF_MAX_VERDICT: ::c_int = NF_STOP; + +pub const NF_VERDICT_MASK: ::c_int = 0x000000ff; +pub const NF_VERDICT_FLAG_QUEUE_BYPASS: ::c_int = 0x00008000; + +pub const NF_VERDICT_QMASK: ::c_int = 0xffff0000; +pub const NF_VERDICT_QBITS: ::c_int = 16; + +pub const NF_VERDICT_BITS: ::c_int = 16; + +pub const NF_INET_PRE_ROUTING: ::c_int = 0; +pub const NF_INET_LOCAL_IN: ::c_int = 1; +pub const NF_INET_FORWARD: ::c_int = 2; +pub const NF_INET_LOCAL_OUT: ::c_int = 3; +pub const NF_INET_POST_ROUTING: ::c_int = 4; +pub const NF_INET_NUMHOOKS: ::c_int = 5; + +// Some NFPROTO are not compatible with musl and are defined in submodules. +pub const NFPROTO_UNSPEC: ::c_int = 0; +pub const NFPROTO_IPV4: ::c_int = 2; +pub const NFPROTO_ARP: ::c_int = 3; +pub const NFPROTO_BRIDGE: ::c_int = 7; +pub const NFPROTO_IPV6: ::c_int = 10; +pub const NFPROTO_DECNET: ::c_int = 12; +pub const NFPROTO_NUMPROTO: ::c_int = 13; +pub const NFPROTO_INET: ::c_int = 1; +pub const NFPROTO_NETDEV: ::c_int = 5; + +pub const NF_NETDEV_INGRESS: ::c_int = 0; +pub const NF_NETDEV_NUMHOOKS: ::c_int = 1; + +// linux/netfilter_ipv4.h +pub const NF_IP_PRE_ROUTING: ::c_int = 0; +pub const NF_IP_LOCAL_IN: ::c_int = 1; +pub const NF_IP_FORWARD: ::c_int = 2; +pub const NF_IP_LOCAL_OUT: ::c_int = 3; +pub const NF_IP_POST_ROUTING: ::c_int = 4; +pub const NF_IP_NUMHOOKS: ::c_int = 5; + +pub const NF_IP_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP_PRI_RAW: ::c_int = -300; +pub const NF_IP_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP_PRI_MANGLE: ::c_int = -150; +pub const NF_IP_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP_PRI_FILTER: ::c_int = 0; +pub const NF_IP_PRI_SECURITY: ::c_int = 50; +pub const NF_IP_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP_PRI_CONNTRACK_CONFIRM: ::c_int = ::INT_MAX; +pub const NF_IP_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6.h +pub const NF_IP6_PRE_ROUTING: ::c_int = 0; +pub const NF_IP6_LOCAL_IN: ::c_int = 1; +pub const NF_IP6_FORWARD: ::c_int = 2; +pub const NF_IP6_LOCAL_OUT: ::c_int = 3; +pub const NF_IP6_POST_ROUTING: ::c_int = 4; +pub const NF_IP6_NUMHOOKS: ::c_int = 5; + +pub const NF_IP6_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP6_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP6_PRI_RAW: ::c_int = -300; +pub const NF_IP6_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP6_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP6_PRI_MANGLE: ::c_int = -150; +pub const NF_IP6_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP6_PRI_FILTER: ::c_int = 0; +pub const NF_IP6_PRI_SECURITY: ::c_int = 50; +pub const NF_IP6_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP6_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP6_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP6_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6/ip6_tables.h +pub const IP6T_SO_ORIGINAL_DST: ::c_int = 80; + +pub const SIOCADDRT: ::c_ulong = 0x0000890B; +pub const SIOCDELRT: ::c_ulong = 0x0000890C; +pub const SIOCGIFNAME: ::c_ulong = 0x00008910; +pub const SIOCSIFLINK: ::c_ulong = 0x00008911; +pub const SIOCGIFCONF: ::c_ulong = 0x00008912; +pub const SIOCGIFFLAGS: ::c_ulong = 0x00008913; +pub const SIOCSIFFLAGS: ::c_ulong = 0x00008914; +pub const SIOCGIFADDR: ::c_ulong = 0x00008915; +pub const SIOCSIFADDR: ::c_ulong = 0x00008916; +pub const SIOCGIFDSTADDR: ::c_ulong = 0x00008917; +pub const SIOCSIFDSTADDR: ::c_ulong = 0x00008918; +pub const SIOCGIFBRDADDR: ::c_ulong = 0x00008919; +pub const SIOCSIFBRDADDR: ::c_ulong = 0x0000891A; +pub const SIOCGIFNETMASK: ::c_ulong = 0x0000891B; +pub const SIOCSIFNETMASK: ::c_ulong = 0x0000891C; +pub const SIOCGIFMETRIC: ::c_ulong = 0x0000891D; +pub const SIOCSIFMETRIC: ::c_ulong = 0x0000891E; +pub const SIOCGIFMEM: ::c_ulong = 0x0000891F; +pub const SIOCSIFMEM: ::c_ulong = 0x00008920; +pub const SIOCGIFMTU: ::c_ulong = 0x00008921; +pub const SIOCSIFMTU: ::c_ulong = 0x00008922; +pub const SIOCSIFNAME: ::c_ulong = 0x00008923; +pub const SIOCSIFHWADDR: ::c_ulong = 0x00008924; +pub const SIOCGIFENCAP: ::c_ulong = 0x00008925; +pub const SIOCSIFENCAP: ::c_ulong = 0x00008926; +pub const SIOCGIFHWADDR: ::c_ulong = 0x00008927; +pub const SIOCGIFSLAVE: ::c_ulong = 0x00008929; +pub const SIOCSIFSLAVE: ::c_ulong = 0x00008930; +pub const SIOCADDMULTI: ::c_ulong = 0x00008931; +pub const SIOCDELMULTI: ::c_ulong = 0x00008932; +pub const SIOCGIFINDEX: ::c_ulong = 0x00008933; +pub const SIOGIFINDEX: ::c_ulong = SIOCGIFINDEX; +pub const SIOCSIFPFLAGS: ::c_ulong = 0x00008934; +pub const SIOCGIFPFLAGS: ::c_ulong = 0x00008935; +pub const SIOCDIFADDR: ::c_ulong = 0x00008936; +pub const SIOCSIFHWBROADCAST: ::c_ulong = 0x00008937; +pub const SIOCGIFCOUNT: ::c_ulong = 0x00008938; +pub const SIOCGIFBR: ::c_ulong = 0x00008940; +pub const SIOCSIFBR: ::c_ulong = 0x00008941; +pub const SIOCGIFTXQLEN: ::c_ulong = 0x00008942; +pub const SIOCSIFTXQLEN: ::c_ulong = 0x00008943; +pub const SIOCETHTOOL: ::c_ulong = 0x00008946; +pub const SIOCGMIIPHY: ::c_ulong = 0x00008947; +pub const SIOCGMIIREG: ::c_ulong = 0x00008948; +pub const SIOCSMIIREG: ::c_ulong = 0x00008949; +pub const SIOCWANDEV: ::c_ulong = 0x0000894A; +pub const SIOCOUTQNSD: ::c_ulong = 0x0000894B; +pub const SIOCGSKNS: ::c_ulong = 0x0000894C; +pub const SIOCDARP: ::c_ulong = 0x00008953; +pub const SIOCGARP: ::c_ulong = 0x00008954; +pub const SIOCSARP: ::c_ulong = 0x00008955; +pub const SIOCDRARP: ::c_ulong = 0x00008960; +pub const SIOCGRARP: ::c_ulong = 0x00008961; +pub const SIOCSRARP: ::c_ulong = 0x00008962; +pub const SIOCGIFMAP: ::c_ulong = 0x00008970; +pub const SIOCSIFMAP: ::c_ulong = 0x00008971; +pub const SIOCSHWTSTAMP: ::c_ulong = 0x000089b0; +pub const SIOCGHWTSTAMP: ::c_ulong = 0x000089b1; + +// wireless.h +pub const WIRELESS_EXT: ::c_ulong = 0x16; + +pub const SIOCSIWCOMMIT: ::c_ulong = 0x8B00; +pub const SIOCGIWNAME: ::c_ulong = 0x8B01; + +pub const SIOCSIWNWID: ::c_ulong = 0x8B02; +pub const SIOCGIWNWID: ::c_ulong = 0x8B03; +pub const SIOCSIWFREQ: ::c_ulong = 0x8B04; +pub const SIOCGIWFREQ: ::c_ulong = 0x8B05; +pub const SIOCSIWMODE: ::c_ulong = 0x8B06; +pub const SIOCGIWMODE: ::c_ulong = 0x8B07; +pub const SIOCSIWSENS: ::c_ulong = 0x8B08; +pub const SIOCGIWSENS: ::c_ulong = 0x8B09; + +pub const SIOCSIWRANGE: ::c_ulong = 0x8B0A; +pub const SIOCGIWRANGE: ::c_ulong = 0x8B0B; +pub const SIOCSIWPRIV: ::c_ulong = 0x8B0C; +pub const SIOCGIWPRIV: ::c_ulong = 0x8B0D; +pub const SIOCSIWSTATS: ::c_ulong = 0x8B0E; +pub const SIOCGIWSTATS: ::c_ulong = 0x8B0F; + +pub const SIOCSIWSPY: ::c_ulong = 0x8B10; +pub const SIOCGIWSPY: ::c_ulong = 0x8B11; +pub const SIOCSIWTHRSPY: ::c_ulong = 0x8B12; +pub const SIOCGIWTHRSPY: ::c_ulong = 0x8B13; + +pub const SIOCSIWAP: ::c_ulong = 0x8B14; +pub const SIOCGIWAP: ::c_ulong = 0x8B15; +pub const SIOCGIWAPLIST: ::c_ulong = 0x8B17; +pub const SIOCSIWSCAN: ::c_ulong = 0x8B18; +pub const SIOCGIWSCAN: ::c_ulong = 0x8B19; + +pub const SIOCSIWESSID: ::c_ulong = 0x8B1A; +pub const SIOCGIWESSID: ::c_ulong = 0x8B1B; +pub const SIOCSIWNICKN: ::c_ulong = 0x8B1C; +pub const SIOCGIWNICKN: ::c_ulong = 0x8B1D; + +pub const SIOCSIWRATE: ::c_ulong = 0x8B20; +pub const SIOCGIWRATE: ::c_ulong = 0x8B21; +pub const SIOCSIWRTS: ::c_ulong = 0x8B22; +pub const SIOCGIWRTS: ::c_ulong = 0x8B23; +pub const SIOCSIWFRAG: ::c_ulong = 0x8B24; +pub const SIOCGIWFRAG: ::c_ulong = 0x8B25; +pub const SIOCSIWTXPOW: ::c_ulong = 0x8B26; +pub const SIOCGIWTXPOW: ::c_ulong = 0x8B27; +pub const SIOCSIWRETRY: ::c_ulong = 0x8B28; +pub const SIOCGIWRETRY: ::c_ulong = 0x8B29; + +pub const SIOCSIWENCODE: ::c_ulong = 0x8B2A; +pub const SIOCGIWENCODE: ::c_ulong = 0x8B2B; + +pub const SIOCSIWPOWER: ::c_ulong = 0x8B2C; +pub const SIOCGIWPOWER: ::c_ulong = 0x8B2D; + +pub const SIOCSIWGENIE: ::c_ulong = 0x8B30; +pub const SIOCGIWGENIE: ::c_ulong = 0x8B31; + +pub const SIOCSIWMLME: ::c_ulong = 0x8B16; + +pub const SIOCSIWAUTH: ::c_ulong = 0x8B32; +pub const SIOCGIWAUTH: ::c_ulong = 0x8B33; + +pub const SIOCSIWENCODEEXT: ::c_ulong = 0x8B34; +pub const SIOCGIWENCODEEXT: ::c_ulong = 0x8B35; + +pub const SIOCSIWPMKSA: ::c_ulong = 0x8B36; + +pub const SIOCIWFIRSTPRIV: ::c_ulong = 0x8BE0; +pub const SIOCIWLASTPRIV: ::c_ulong = 0x8BFF; + +pub const SIOCIWFIRST: ::c_ulong = 0x8B00; +pub const SIOCIWLAST: ::c_ulong = SIOCIWLASTPRIV; + +pub const IWEVTXDROP: ::c_ulong = 0x8C00; +pub const IWEVQUAL: ::c_ulong = 0x8C01; +pub const IWEVCUSTOM: ::c_ulong = 0x8C02; +pub const IWEVREGISTERED: ::c_ulong = 0x8C03; +pub const IWEVEXPIRED: ::c_ulong = 0x8C04; +pub const IWEVGENIE: ::c_ulong = 0x8C05; +pub const IWEVMICHAELMICFAILURE: ::c_ulong = 0x8C06; +pub const IWEVASSOCREQIE: ::c_ulong = 0x8C07; +pub const IWEVASSOCRESPIE: ::c_ulong = 0x8C08; +pub const IWEVPMKIDCAND: ::c_ulong = 0x8C09; +pub const IWEVFIRST: ::c_ulong = 0x8C00; + +pub const IW_PRIV_TYPE_MASK: ::c_ulong = 0x7000; +pub const IW_PRIV_TYPE_NONE: ::c_ulong = 0x0000; +pub const IW_PRIV_TYPE_BYTE: ::c_ulong = 0x1000; +pub const IW_PRIV_TYPE_CHAR: ::c_ulong = 0x2000; +pub const IW_PRIV_TYPE_INT: ::c_ulong = 0x4000; +pub const IW_PRIV_TYPE_FLOAT: ::c_ulong = 0x5000; +pub const IW_PRIV_TYPE_ADDR: ::c_ulong = 0x6000; + +pub const IW_PRIV_SIZE_FIXED: ::c_ulong = 0x0800; + +pub const IW_PRIV_SIZE_MASK: ::c_ulong = 0x07FF; + +pub const IW_MAX_FREQUENCIES: usize = 32; +pub const IW_MAX_BITRATES: usize = 32; +pub const IW_MAX_TXPOWER: usize = 8; +pub const IW_MAX_SPY: usize = 8; +pub const IW_MAX_AP: usize = 64; +pub const IW_ESSID_MAX_SIZE: usize = 32; + +pub const IW_MODE_AUTO: usize = 0; +pub const IW_MODE_ADHOC: usize = 1; +pub const IW_MODE_INFRA: usize = 2; +pub const IW_MODE_MASTER: usize = 3; +pub const IW_MODE_REPEAT: usize = 4; +pub const IW_MODE_SECOND: usize = 5; +pub const IW_MODE_MONITOR: usize = 6; +pub const IW_MODE_MESH: usize = 7; + +pub const IW_QUAL_QUAL_UPDATED: ::c_ulong = 0x01; +pub const IW_QUAL_LEVEL_UPDATED: ::c_ulong = 0x02; +pub const IW_QUAL_NOISE_UPDATED: ::c_ulong = 0x04; +pub const IW_QUAL_ALL_UPDATED: ::c_ulong = 0x07; +pub const IW_QUAL_DBM: ::c_ulong = 0x08; +pub const IW_QUAL_QUAL_INVALID: ::c_ulong = 0x10; +pub const IW_QUAL_LEVEL_INVALID: ::c_ulong = 0x20; +pub const IW_QUAL_NOISE_INVALID: ::c_ulong = 0x40; +pub const IW_QUAL_RCPI: ::c_ulong = 0x80; +pub const IW_QUAL_ALL_INVALID: ::c_ulong = 0x70; + +pub const IW_FREQ_AUTO: ::c_ulong = 0x00; +pub const IW_FREQ_FIXED: ::c_ulong = 0x01; + +pub const IW_MAX_ENCODING_SIZES: usize = 8; +pub const IW_ENCODING_TOKEN_MAX: usize = 64; + +pub const IW_ENCODE_INDEX: ::c_ulong = 0x00FF; +pub const IW_ENCODE_FLAGS: ::c_ulong = 0xFF00; +pub const IW_ENCODE_MODE: ::c_ulong = 0xF000; +pub const IW_ENCODE_DISABLED: ::c_ulong = 0x8000; +pub const IW_ENCODE_ENABLED: ::c_ulong = 0x0000; +pub const IW_ENCODE_RESTRICTED: ::c_ulong = 0x4000; +pub const IW_ENCODE_OPEN: ::c_ulong = 0x2000; +pub const IW_ENCODE_NOKEY: ::c_ulong = 0x0800; +pub const IW_ENCODE_TEMP: ::c_ulong = 0x0400; + +pub const IW_POWER_ON: ::c_ulong = 0x0000; +pub const IW_POWER_TYPE: ::c_ulong = 0xF000; +pub const IW_POWER_PERIOD: ::c_ulong = 0x1000; +pub const IW_POWER_TIMEOUT: ::c_ulong = 0x2000; +pub const IW_POWER_MODE: ::c_ulong = 0x0F00; +pub const IW_POWER_UNICAST_R: ::c_ulong = 0x0100; +pub const IW_POWER_MULTICAST_R: ::c_ulong = 0x0200; +pub const IW_POWER_ALL_R: ::c_ulong = 0x0300; +pub const IW_POWER_FORCE_S: ::c_ulong = 0x0400; +pub const IW_POWER_REPEATER: ::c_ulong = 0x0800; +pub const IW_POWER_MODIFIER: ::c_ulong = 0x000F; +pub const IW_POWER_MIN: ::c_ulong = 0x0001; +pub const IW_POWER_MAX: ::c_ulong = 0x0002; +pub const IW_POWER_RELATIVE: ::c_ulong = 0x0004; + +pub const IW_TXPOW_TYPE: ::c_ulong = 0x00FF; +pub const IW_TXPOW_DBM: ::c_ulong = 0x0000; +pub const IW_TXPOW_MWATT: ::c_ulong = 0x0001; +pub const IW_TXPOW_RELATIVE: ::c_ulong = 0x0002; +pub const IW_TXPOW_RANGE: ::c_ulong = 0x1000; + +pub const IW_RETRY_ON: ::c_ulong = 0x0000; +pub const IW_RETRY_TYPE: ::c_ulong = 0xF000; +pub const IW_RETRY_LIMIT: ::c_ulong = 0x1000; +pub const IW_RETRY_LIFETIME: ::c_ulong = 0x2000; +pub const IW_RETRY_MODIFIER: ::c_ulong = 0x00FF; +pub const IW_RETRY_MIN: ::c_ulong = 0x0001; +pub const IW_RETRY_MAX: ::c_ulong = 0x0002; +pub const IW_RETRY_RELATIVE: ::c_ulong = 0x0004; +pub const IW_RETRY_SHORT: ::c_ulong = 0x0010; +pub const IW_RETRY_LONG: ::c_ulong = 0x0020; + +pub const IW_SCAN_DEFAULT: ::c_ulong = 0x0000; +pub const IW_SCAN_ALL_ESSID: ::c_ulong = 0x0001; +pub const IW_SCAN_THIS_ESSID: ::c_ulong = 0x0002; +pub const IW_SCAN_ALL_FREQ: ::c_ulong = 0x0004; +pub const IW_SCAN_THIS_FREQ: ::c_ulong = 0x0008; +pub const IW_SCAN_ALL_MODE: ::c_ulong = 0x0010; +pub const IW_SCAN_THIS_MODE: ::c_ulong = 0x0020; +pub const IW_SCAN_ALL_RATE: ::c_ulong = 0x0040; +pub const IW_SCAN_THIS_RATE: ::c_ulong = 0x0080; + +pub const IW_SCAN_TYPE_ACTIVE: usize = 0; +pub const IW_SCAN_TYPE_PASSIVE: usize = 1; + +pub const IW_SCAN_MAX_DATA: usize = 4096; + +pub const IW_SCAN_CAPA_NONE: ::c_ulong = 0x00; +pub const IW_SCAN_CAPA_ESSID: ::c_ulong = 0x01; +pub const IW_SCAN_CAPA_BSSID: ::c_ulong = 0x02; +pub const IW_SCAN_CAPA_CHANNEL: ::c_ulong = 0x04; +pub const IW_SCAN_CAPA_MODE: ::c_ulong = 0x08; +pub const IW_SCAN_CAPA_RATE: ::c_ulong = 0x10; +pub const IW_SCAN_CAPA_TYPE: ::c_ulong = 0x20; +pub const IW_SCAN_CAPA_TIME: ::c_ulong = 0x40; + +pub const IW_CUSTOM_MAX: ::c_ulong = 256; + +pub const IW_GENERIC_IE_MAX: ::c_ulong = 1024; + +pub const IW_MLME_DEAUTH: ::c_ulong = 0; +pub const IW_MLME_DISASSOC: ::c_ulong = 1; +pub const IW_MLME_AUTH: ::c_ulong = 2; +pub const IW_MLME_ASSOC: ::c_ulong = 3; + +pub const IW_AUTH_INDEX: ::c_ulong = 0x0FFF; +pub const IW_AUTH_FLAGS: ::c_ulong = 0xF000; + +pub const IW_AUTH_WPA_VERSION: usize = 0; +pub const IW_AUTH_CIPHER_PAIRWISE: usize = 1; +pub const IW_AUTH_CIPHER_GROUP: usize = 2; +pub const IW_AUTH_KEY_MGMT: usize = 3; +pub const IW_AUTH_TKIP_COUNTERMEASURES: usize = 4; +pub const IW_AUTH_DROP_UNENCRYPTED: usize = 5; +pub const IW_AUTH_80211_AUTH_ALG: usize = 6; +pub const IW_AUTH_WPA_ENABLED: usize = 7; +pub const IW_AUTH_RX_UNENCRYPTED_EAPOL: usize = 8; +pub const IW_AUTH_ROAMING_CONTROL: usize = 9; +pub const IW_AUTH_PRIVACY_INVOKED: usize = 10; +pub const IW_AUTH_CIPHER_GROUP_MGMT: usize = 11; +pub const IW_AUTH_MFP: usize = 12; + +pub const IW_AUTH_WPA_VERSION_DISABLED: ::c_ulong = 0x00000001; +pub const IW_AUTH_WPA_VERSION_WPA: ::c_ulong = 0x00000002; +pub const IW_AUTH_WPA_VERSION_WPA2: ::c_ulong = 0x00000004; + +pub const IW_AUTH_CIPHER_NONE: ::c_ulong = 0x00000001; +pub const IW_AUTH_CIPHER_WEP40: ::c_ulong = 0x00000002; +pub const IW_AUTH_CIPHER_TKIP: ::c_ulong = 0x00000004; +pub const IW_AUTH_CIPHER_CCMP: ::c_ulong = 0x00000008; +pub const IW_AUTH_CIPHER_WEP104: ::c_ulong = 0x00000010; +pub const IW_AUTH_CIPHER_AES_CMAC: ::c_ulong = 0x00000020; + +pub const IW_AUTH_KEY_MGMT_802_1X: usize = 1; +pub const IW_AUTH_KEY_MGMT_PSK: usize = 2; + +pub const IW_AUTH_ALG_OPEN_SYSTEM: ::c_ulong = 0x00000001; +pub const IW_AUTH_ALG_SHARED_KEY: ::c_ulong = 0x00000002; +pub const IW_AUTH_ALG_LEAP: ::c_ulong = 0x00000004; + +pub const IW_AUTH_ROAMING_ENABLE: usize = 0; +pub const IW_AUTH_ROAMING_DISABLE: usize = 1; + +pub const IW_AUTH_MFP_DISABLED: usize = 0; +pub const IW_AUTH_MFP_OPTIONAL: usize = 1; +pub const IW_AUTH_MFP_REQUIRED: usize = 2; + +pub const IW_ENCODE_SEQ_MAX_SIZE: usize = 8; + +pub const IW_ENCODE_ALG_NONE: usize = 0; +pub const IW_ENCODE_ALG_WEP: usize = 1; +pub const IW_ENCODE_ALG_TKIP: usize = 2; +pub const IW_ENCODE_ALG_CCMP: usize = 3; +pub const IW_ENCODE_ALG_PMK: usize = 4; +pub const IW_ENCODE_ALG_AES_CMAC: usize = 5; + +pub const IW_ENCODE_EXT_TX_SEQ_VALID: ::c_ulong = 0x00000001; +pub const IW_ENCODE_EXT_RX_SEQ_VALID: ::c_ulong = 0x00000002; +pub const IW_ENCODE_EXT_GROUP_KEY: ::c_ulong = 0x00000004; +pub const IW_ENCODE_EXT_SET_TX_KEY: ::c_ulong = 0x00000008; + +pub const IW_MICFAILURE_KEY_ID: ::c_ulong = 0x00000003; +pub const IW_MICFAILURE_GROUP: ::c_ulong = 0x00000004; +pub const IW_MICFAILURE_PAIRWISE: ::c_ulong = 0x00000008; +pub const IW_MICFAILURE_STAKEY: ::c_ulong = 0x00000010; +pub const IW_MICFAILURE_COUNT: ::c_ulong = 0x00000060; + +pub const IW_ENC_CAPA_WPA: ::c_ulong = 0x00000001; +pub const IW_ENC_CAPA_WPA2: ::c_ulong = 0x00000002; +pub const IW_ENC_CAPA_CIPHER_TKIP: ::c_ulong = 0x00000004; +pub const IW_ENC_CAPA_CIPHER_CCMP: ::c_ulong = 0x00000008; +pub const IW_ENC_CAPA_4WAY_HANDSHAKE: ::c_ulong = 0x00000010; + +pub const IW_PMKSA_ADD: usize = 1; +pub const IW_PMKSA_REMOVE: usize = 2; +pub const IW_PMKSA_FLUSH: usize = 3; + +pub const IW_PMKID_LEN: usize = 16; + +pub const IW_PMKID_CAND_PREAUTH: ::c_ulong = 0x00000001; + +pub const IW_EV_LCP_PK_LEN: usize = 4; + +pub const IW_EV_CHAR_PK_LEN: usize = IW_EV_LCP_PK_LEN + ::IFNAMSIZ; +pub const IW_EV_POINT_PK_LEN: usize = IW_EV_LCP_PK_LEN + 4; + +pub const IPTOS_TOS_MASK: u8 = 0x1E; +pub const IPTOS_PREC_MASK: u8 = 0xE0; + +pub const IPTOS_ECN_NOT_ECT: u8 = 0x00; + +pub const RTF_UP: ::c_ushort = 0x0001; +pub const RTF_GATEWAY: ::c_ushort = 0x0002; + +pub const RTF_HOST: ::c_ushort = 0x0004; +pub const RTF_REINSTATE: ::c_ushort = 0x0008; +pub const RTF_DYNAMIC: ::c_ushort = 0x0010; +pub const RTF_MODIFIED: ::c_ushort = 0x0020; +pub const RTF_MTU: ::c_ushort = 0x0040; +pub const RTF_MSS: ::c_ushort = RTF_MTU; +pub const RTF_WINDOW: ::c_ushort = 0x0080; +pub const RTF_IRTT: ::c_ushort = 0x0100; +pub const RTF_REJECT: ::c_ushort = 0x0200; +pub const RTF_STATIC: ::c_ushort = 0x0400; +pub const RTF_XRESOLVE: ::c_ushort = 0x0800; +pub const RTF_NOFORWARD: ::c_ushort = 0x1000; +pub const RTF_THROW: ::c_ushort = 0x2000; +pub const RTF_NOPMTUDISC: ::c_ushort = 0x4000; + +pub const RTF_DEFAULT: u32 = 0x00010000; +pub const RTF_ALLONLINK: u32 = 0x00020000; +pub const RTF_ADDRCONF: u32 = 0x00040000; +pub const RTF_LINKRT: u32 = 0x00100000; +pub const RTF_NONEXTHOP: u32 = 0x00200000; +pub const RTF_CACHE: u32 = 0x01000000; +pub const RTF_FLOW: u32 = 0x02000000; +pub const RTF_POLICY: u32 = 0x04000000; + +pub const RTCF_VALVE: u32 = 0x00200000; +pub const RTCF_MASQ: u32 = 0x00400000; +pub const RTCF_NAT: u32 = 0x00800000; +pub const RTCF_DOREDIRECT: u32 = 0x01000000; +pub const RTCF_LOG: u32 = 0x02000000; +pub const RTCF_DIRECTSRC: u32 = 0x04000000; + +pub const RTF_LOCAL: u32 = 0x80000000; +pub const RTF_INTERFACE: u32 = 0x40000000; +pub const RTF_MULTICAST: u32 = 0x20000000; +pub const RTF_BROADCAST: u32 = 0x10000000; +pub const RTF_NAT: u32 = 0x08000000; +pub const RTF_ADDRCLASSMASK: u32 = 0xF8000000; + +pub const RT_CLASS_UNSPEC: u8 = 0; +pub const RT_CLASS_DEFAULT: u8 = 253; +pub const RT_CLASS_MAIN: u8 = 254; +pub const RT_CLASS_LOCAL: u8 = 255; +pub const RT_CLASS_MAX: u8 = 255; + +// linux/neighbor.h +pub const NUD_NONE: u16 = 0x00; +pub const NUD_INCOMPLETE: u16 = 0x01; +pub const NUD_REACHABLE: u16 = 0x02; +pub const NUD_STALE: u16 = 0x04; +pub const NUD_DELAY: u16 = 0x08; +pub const NUD_PROBE: u16 = 0x10; +pub const NUD_FAILED: u16 = 0x20; +pub const NUD_NOARP: u16 = 0x40; +pub const NUD_PERMANENT: u16 = 0x80; + +pub const NTF_USE: u8 = 0x01; +pub const NTF_SELF: u8 = 0x02; +pub const NTF_MASTER: u8 = 0x04; +pub const NTF_PROXY: u8 = 0x08; +pub const NTF_ROUTER: u8 = 0x80; + +pub const NDA_UNSPEC: ::c_ushort = 0; +pub const NDA_DST: ::c_ushort = 1; +pub const NDA_LLADDR: ::c_ushort = 2; +pub const NDA_CACHEINFO: ::c_ushort = 3; +pub const NDA_PROBES: ::c_ushort = 4; +pub const NDA_VLAN: ::c_ushort = 5; +pub const NDA_PORT: ::c_ushort = 6; +pub const NDA_VNI: ::c_ushort = 7; +pub const NDA_IFINDEX: ::c_ushort = 8; + +// linux/netlink.h +pub const NLA_ALIGNTO: ::c_int = 4; + +pub const NETLINK_ROUTE: ::c_int = 0; +pub const NETLINK_UNUSED: ::c_int = 1; +pub const NETLINK_USERSOCK: ::c_int = 2; +pub const NETLINK_FIREWALL: ::c_int = 3; +pub const NETLINK_SOCK_DIAG: ::c_int = 4; +pub const NETLINK_NFLOG: ::c_int = 5; +pub const NETLINK_XFRM: ::c_int = 6; +pub const NETLINK_SELINUX: ::c_int = 7; +pub const NETLINK_ISCSI: ::c_int = 8; +pub const NETLINK_AUDIT: ::c_int = 9; +pub const NETLINK_FIB_LOOKUP: ::c_int = 10; +pub const NETLINK_CONNECTOR: ::c_int = 11; +pub const NETLINK_NETFILTER: ::c_int = 12; +pub const NETLINK_IP6_FW: ::c_int = 13; +pub const NETLINK_DNRTMSG: ::c_int = 14; +pub const NETLINK_KOBJECT_UEVENT: ::c_int = 15; +pub const NETLINK_GENERIC: ::c_int = 16; +pub const NETLINK_SCSITRANSPORT: ::c_int = 18; +pub const NETLINK_ECRYPTFS: ::c_int = 19; +pub const NETLINK_RDMA: ::c_int = 20; +pub const NETLINK_CRYPTO: ::c_int = 21; +pub const NETLINK_INET_DIAG: ::c_int = NETLINK_SOCK_DIAG; + +pub const NLM_F_REQUEST: ::c_int = 1; +pub const NLM_F_MULTI: ::c_int = 2; +pub const NLM_F_ACK: ::c_int = 4; +pub const NLM_F_ECHO: ::c_int = 8; +pub const NLM_F_DUMP_INTR: ::c_int = 16; +pub const NLM_F_DUMP_FILTERED: ::c_int = 32; + +pub const NLM_F_ROOT: ::c_int = 0x100; +pub const NLM_F_MATCH: ::c_int = 0x200; +pub const NLM_F_ATOMIC: ::c_int = 0x400; +pub const NLM_F_DUMP: ::c_int = NLM_F_ROOT | NLM_F_MATCH; + +pub const NLM_F_REPLACE: ::c_int = 0x100; +pub const NLM_F_EXCL: ::c_int = 0x200; +pub const NLM_F_CREATE: ::c_int = 0x400; +pub const NLM_F_APPEND: ::c_int = 0x800; + +pub const NETLINK_ADD_MEMBERSHIP: ::c_int = 1; +pub const NETLINK_DROP_MEMBERSHIP: ::c_int = 2; +pub const NETLINK_PKTINFO: ::c_int = 3; +pub const NETLINK_BROADCAST_ERROR: ::c_int = 4; +pub const NETLINK_NO_ENOBUFS: ::c_int = 5; +pub const NETLINK_RX_RING: ::c_int = 6; +pub const NETLINK_TX_RING: ::c_int = 7; +pub const NETLINK_LISTEN_ALL_NSID: ::c_int = 8; +pub const NETLINK_LIST_MEMBERSHIPS: ::c_int = 9; +pub const NETLINK_CAP_ACK: ::c_int = 10; +pub const NETLINK_EXT_ACK: ::c_int = 11; +pub const NETLINK_GET_STRICT_CHK: ::c_int = 12; + +pub const NLA_F_NESTED: ::c_int = 1 << 15; +pub const NLA_F_NET_BYTEORDER: ::c_int = 1 << 14; +pub const NLA_TYPE_MASK: ::c_int = !(NLA_F_NESTED | NLA_F_NET_BYTEORDER); + +// linux/rtnetlink.h +pub const TCA_UNSPEC: ::c_ushort = 0; +pub const TCA_KIND: ::c_ushort = 1; +pub const TCA_OPTIONS: ::c_ushort = 2; +pub const TCA_STATS: ::c_ushort = 3; +pub const TCA_XSTATS: ::c_ushort = 4; +pub const TCA_RATE: ::c_ushort = 5; +pub const TCA_FCNT: ::c_ushort = 6; +pub const TCA_STATS2: ::c_ushort = 7; +pub const TCA_STAB: ::c_ushort = 8; + +pub const RTM_NEWLINK: u16 = 16; +pub const RTM_DELLINK: u16 = 17; +pub const RTM_GETLINK: u16 = 18; +pub const RTM_SETLINK: u16 = 19; +pub const RTM_NEWADDR: u16 = 20; +pub const RTM_DELADDR: u16 = 21; +pub const RTM_GETADDR: u16 = 22; +pub const RTM_NEWROUTE: u16 = 24; +pub const RTM_DELROUTE: u16 = 25; +pub const RTM_GETROUTE: u16 = 26; +pub const RTM_NEWNEIGH: u16 = 28; +pub const RTM_DELNEIGH: u16 = 29; +pub const RTM_GETNEIGH: u16 = 30; +pub const RTM_NEWRULE: u16 = 32; +pub const RTM_DELRULE: u16 = 33; +pub const RTM_GETRULE: u16 = 34; +pub const RTM_NEWQDISC: u16 = 36; +pub const RTM_DELQDISC: u16 = 37; +pub const RTM_GETQDISC: u16 = 38; +pub const RTM_NEWTCLASS: u16 = 40; +pub const RTM_DELTCLASS: u16 = 41; +pub const RTM_GETTCLASS: u16 = 42; +pub const RTM_NEWTFILTER: u16 = 44; +pub const RTM_DELTFILTER: u16 = 45; +pub const RTM_GETTFILTER: u16 = 46; +pub const RTM_NEWACTION: u16 = 48; +pub const RTM_DELACTION: u16 = 49; +pub const RTM_GETACTION: u16 = 50; +pub const RTM_NEWPREFIX: u16 = 52; +pub const RTM_GETMULTICAST: u16 = 58; +pub const RTM_GETANYCAST: u16 = 62; +pub const RTM_NEWNEIGHTBL: u16 = 64; +pub const RTM_GETNEIGHTBL: u16 = 66; +pub const RTM_SETNEIGHTBL: u16 = 67; +pub const RTM_NEWNDUSEROPT: u16 = 68; +pub const RTM_NEWADDRLABEL: u16 = 72; +pub const RTM_DELADDRLABEL: u16 = 73; +pub const RTM_GETADDRLABEL: u16 = 74; +pub const RTM_GETDCB: u16 = 78; +pub const RTM_SETDCB: u16 = 79; +pub const RTM_NEWNETCONF: u16 = 80; +pub const RTM_GETNETCONF: u16 = 82; +pub const RTM_NEWMDB: u16 = 84; +pub const RTM_DELMDB: u16 = 85; +pub const RTM_GETMDB: u16 = 86; +pub const RTM_NEWNSID: u16 = 88; +pub const RTM_DELNSID: u16 = 89; +pub const RTM_GETNSID: u16 = 90; + +pub const RTM_F_NOTIFY: ::c_uint = 0x100; +pub const RTM_F_CLONED: ::c_uint = 0x200; +pub const RTM_F_EQUALIZE: ::c_uint = 0x400; +pub const RTM_F_PREFIX: ::c_uint = 0x800; + +pub const RTA_UNSPEC: ::c_ushort = 0; +pub const RTA_DST: ::c_ushort = 1; +pub const RTA_SRC: ::c_ushort = 2; +pub const RTA_IIF: ::c_ushort = 3; +pub const RTA_OIF: ::c_ushort = 4; +pub const RTA_GATEWAY: ::c_ushort = 5; +pub const RTA_PRIORITY: ::c_ushort = 6; +pub const RTA_PREFSRC: ::c_ushort = 7; +pub const RTA_METRICS: ::c_ushort = 8; +pub const RTA_MULTIPATH: ::c_ushort = 9; +pub const RTA_PROTOINFO: ::c_ushort = 10; // No longer used +pub const RTA_FLOW: ::c_ushort = 11; +pub const RTA_CACHEINFO: ::c_ushort = 12; +pub const RTA_SESSION: ::c_ushort = 13; // No longer used +pub const RTA_MP_ALGO: ::c_ushort = 14; // No longer used +pub const RTA_TABLE: ::c_ushort = 15; +pub const RTA_MARK: ::c_ushort = 16; +pub const RTA_MFC_STATS: ::c_ushort = 17; + +pub const RTN_UNSPEC: ::c_uchar = 0; +pub const RTN_UNICAST: ::c_uchar = 1; +pub const RTN_LOCAL: ::c_uchar = 2; +pub const RTN_BROADCAST: ::c_uchar = 3; +pub const RTN_ANYCAST: ::c_uchar = 4; +pub const RTN_MULTICAST: ::c_uchar = 5; +pub const RTN_BLACKHOLE: ::c_uchar = 6; +pub const RTN_UNREACHABLE: ::c_uchar = 7; +pub const RTN_PROHIBIT: ::c_uchar = 8; +pub const RTN_THROW: ::c_uchar = 9; +pub const RTN_NAT: ::c_uchar = 10; +pub const RTN_XRESOLVE: ::c_uchar = 11; + +pub const RTPROT_UNSPEC: ::c_uchar = 0; +pub const RTPROT_REDIRECT: ::c_uchar = 1; +pub const RTPROT_KERNEL: ::c_uchar = 2; +pub const RTPROT_BOOT: ::c_uchar = 3; +pub const RTPROT_STATIC: ::c_uchar = 4; + +pub const RT_SCOPE_UNIVERSE: ::c_uchar = 0; +pub const RT_SCOPE_SITE: ::c_uchar = 200; +pub const RT_SCOPE_LINK: ::c_uchar = 253; +pub const RT_SCOPE_HOST: ::c_uchar = 254; +pub const RT_SCOPE_NOWHERE: ::c_uchar = 255; + +pub const RT_TABLE_UNSPEC: ::c_uchar = 0; +pub const RT_TABLE_COMPAT: ::c_uchar = 252; +pub const RT_TABLE_DEFAULT: ::c_uchar = 253; +pub const RT_TABLE_MAIN: ::c_uchar = 254; +pub const RT_TABLE_LOCAL: ::c_uchar = 255; + +pub const RTMSG_OVERRUN: u32 = ::NLMSG_OVERRUN as u32; +pub const RTMSG_NEWDEVICE: u32 = 0x11; +pub const RTMSG_DELDEVICE: u32 = 0x12; +pub const RTMSG_NEWROUTE: u32 = 0x21; +pub const RTMSG_DELROUTE: u32 = 0x22; +pub const RTMSG_NEWRULE: u32 = 0x31; +pub const RTMSG_DELRULE: u32 = 0x32; +pub const RTMSG_CONTROL: u32 = 0x40; +pub const RTMSG_AR_FAILED: u32 = 0x51; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +pub const ARPD_LOOKUP: ::c_ushort = 0x02; +pub const ARPD_FLUSH: ::c_ushort = 0x03; +pub const ATF_MAGIC: ::c_int = 0x80; + +pub const RTEXT_FILTER_VF: ::c_int = 1 << 0; +pub const RTEXT_FILTER_BRVLAN: ::c_int = 1 << 1; +pub const RTEXT_FILTER_BRVLAN_COMPRESSED: ::c_int = 1 << 2; +pub const RTEXT_FILTER_SKIP_STATS: ::c_int = 1 << 3; +pub const RTEXT_FILTER_MRP: ::c_int = 1 << 4; +pub const RTEXT_FILTER_CFM_CONFIG: ::c_int = 1 << 5; +pub const RTEXT_FILTER_CFM_STATUS: ::c_int = 1 << 6; + +// userspace compat definitions for RTNLGRP_* +pub const RTMGRP_LINK: ::c_int = 0x00001; +pub const RTMGRP_NOTIFY: ::c_int = 0x00002; +pub const RTMGRP_NEIGH: ::c_int = 0x00004; +pub const RTMGRP_TC: ::c_int = 0x00008; +pub const RTMGRP_IPV4_IFADDR: ::c_int = 0x00010; +pub const RTMGRP_IPV4_MROUTE: ::c_int = 0x00020; +pub const RTMGRP_IPV4_ROUTE: ::c_int = 0x00040; +pub const RTMGRP_IPV4_RULE: ::c_int = 0x00080; +pub const RTMGRP_IPV6_IFADDR: ::c_int = 0x00100; +pub const RTMGRP_IPV6_MROUTE: ::c_int = 0x00200; +pub const RTMGRP_IPV6_ROUTE: ::c_int = 0x00400; +pub const RTMGRP_IPV6_IFINFO: ::c_int = 0x00800; +pub const RTMGRP_DECnet_IFADDR: ::c_int = 0x01000; +pub const RTMGRP_DECnet_ROUTE: ::c_int = 0x04000; +pub const RTMGRP_IPV6_PREFIX: ::c_int = 0x20000; + +// enum rtnetlink_groups +pub const RTNLGRP_NONE: ::c_uint = 0x00; +pub const RTNLGRP_LINK: ::c_uint = 0x01; +pub const RTNLGRP_NOTIFY: ::c_uint = 0x02; +pub const RTNLGRP_NEIGH: ::c_uint = 0x03; +pub const RTNLGRP_TC: ::c_uint = 0x04; +pub const RTNLGRP_IPV4_IFADDR: ::c_uint = 0x05; +pub const RTNLGRP_IPV4_MROUTE: ::c_uint = 0x06; +pub const RTNLGRP_IPV4_ROUTE: ::c_uint = 0x07; +pub const RTNLGRP_IPV4_RULE: ::c_uint = 0x08; +pub const RTNLGRP_IPV6_IFADDR: ::c_uint = 0x09; +pub const RTNLGRP_IPV6_MROUTE: ::c_uint = 0x0a; +pub const RTNLGRP_IPV6_ROUTE: ::c_uint = 0x0b; +pub const RTNLGRP_IPV6_IFINFO: ::c_uint = 0x0c; +pub const RTNLGRP_DECnet_IFADDR: ::c_uint = 0x0d; +pub const RTNLGRP_NOP2: ::c_uint = 0x0e; +pub const RTNLGRP_DECnet_ROUTE: ::c_uint = 0x0f; +pub const RTNLGRP_DECnet_RULE: ::c_uint = 0x10; +pub const RTNLGRP_NOP4: ::c_uint = 0x11; +pub const RTNLGRP_IPV6_PREFIX: ::c_uint = 0x12; +pub const RTNLGRP_IPV6_RULE: ::c_uint = 0x13; +pub const RTNLGRP_ND_USEROPT: ::c_uint = 0x14; +pub const RTNLGRP_PHONET_IFADDR: ::c_uint = 0x15; +pub const RTNLGRP_PHONET_ROUTE: ::c_uint = 0x16; +pub const RTNLGRP_DCB: ::c_uint = 0x17; +pub const RTNLGRP_IPV4_NETCONF: ::c_uint = 0x18; +pub const RTNLGRP_IPV6_NETCONF: ::c_uint = 0x19; +pub const RTNLGRP_MDB: ::c_uint = 0x1a; +pub const RTNLGRP_MPLS_ROUTE: ::c_uint = 0x1b; +pub const RTNLGRP_NSID: ::c_uint = 0x1c; +pub const RTNLGRP_MPLS_NETCONF: ::c_uint = 0x1d; +pub const RTNLGRP_IPV4_MROUTE_R: ::c_uint = 0x1e; +pub const RTNLGRP_IPV6_MROUTE_R: ::c_uint = 0x1f; +pub const RTNLGRP_NEXTHOP: ::c_uint = 0x20; +pub const RTNLGRP_BRVLAN: ::c_uint = 0x21; +pub const RTNLGRP_MCTP_IFADDR: ::c_uint = 0x22; +pub const RTNLGRP_TUNNEL: ::c_uint = 0x23; +pub const RTNLGRP_STATS: ::c_uint = 0x24; + +// linux/module.h +pub const MODULE_INIT_IGNORE_MODVERSIONS: ::c_uint = 0x0001; +pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002; + +// linux/net_tstamp.h +pub const SOF_TIMESTAMPING_TX_HARDWARE: ::c_uint = 1 << 0; +pub const SOF_TIMESTAMPING_TX_SOFTWARE: ::c_uint = 1 << 1; +pub const SOF_TIMESTAMPING_RX_HARDWARE: ::c_uint = 1 << 2; +pub const SOF_TIMESTAMPING_RX_SOFTWARE: ::c_uint = 1 << 3; +pub const SOF_TIMESTAMPING_SOFTWARE: ::c_uint = 1 << 4; +pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5; +pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6; +pub const SOF_TIMESTAMPING_OPT_ID: ::c_uint = 1 << 7; +pub const SOF_TIMESTAMPING_TX_SCHED: ::c_uint = 1 << 8; +pub const SOF_TIMESTAMPING_TX_ACK: ::c_uint = 1 << 9; +pub const SOF_TIMESTAMPING_OPT_CMSG: ::c_uint = 1 << 10; +pub const SOF_TIMESTAMPING_OPT_TSONLY: ::c_uint = 1 << 11; +pub const SOF_TIMESTAMPING_OPT_STATS: ::c_uint = 1 << 12; +pub const SOF_TIMESTAMPING_OPT_PKTINFO: ::c_uint = 1 << 13; +pub const SOF_TIMESTAMPING_OPT_TX_SWHW: ::c_uint = 1 << 14; +pub const SOF_TXTIME_DEADLINE_MODE: u32 = 1 << 0; +pub const SOF_TXTIME_REPORT_ERRORS: u32 = 1 << 1; + +pub const HWTSTAMP_TX_OFF: ::c_uint = 0; +pub const HWTSTAMP_TX_ON: ::c_uint = 1; +pub const HWTSTAMP_TX_ONESTEP_SYNC: ::c_uint = 2; +pub const HWTSTAMP_TX_ONESTEP_P2P: ::c_uint = 3; + +pub const HWTSTAMP_FILTER_NONE: ::c_uint = 0; +pub const HWTSTAMP_FILTER_ALL: ::c_uint = 1; +pub const HWTSTAMP_FILTER_SOME: ::c_uint = 2; +pub const HWTSTAMP_FILTER_PTP_V1_L4_EVENT: ::c_uint = 3; +pub const HWTSTAMP_FILTER_PTP_V1_L4_SYNC: ::c_uint = 4; +pub const HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: ::c_uint = 5; +pub const HWTSTAMP_FILTER_PTP_V2_L4_EVENT: ::c_uint = 6; +pub const HWTSTAMP_FILTER_PTP_V2_L4_SYNC: ::c_uint = 7; +pub const HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: ::c_uint = 8; +pub const HWTSTAMP_FILTER_PTP_V2_L2_EVENT: ::c_uint = 9; +pub const HWTSTAMP_FILTER_PTP_V2_L2_SYNC: ::c_uint = 10; +pub const HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: ::c_uint = 11; +pub const HWTSTAMP_FILTER_PTP_V2_EVENT: ::c_uint = 12; +pub const HWTSTAMP_FILTER_PTP_V2_SYNC: ::c_uint = 13; +pub const HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: ::c_uint = 14; +pub const HWTSTAMP_FILTER_NTP_ALL: ::c_uint = 15; + +// linux/tls.h +pub const TLS_TX: ::c_int = 1; +pub const TLS_RX: ::c_int = 2; + +pub const TLS_1_2_VERSION_MAJOR: ::__u8 = 0x3; +pub const TLS_1_2_VERSION_MINOR: ::__u8 = 0x3; +pub const TLS_1_2_VERSION: ::__u16 = + ((TLS_1_2_VERSION_MAJOR as ::__u16) << 8) | (TLS_1_2_VERSION_MINOR as ::__u16); + +pub const TLS_1_3_VERSION_MAJOR: ::__u8 = 0x3; +pub const TLS_1_3_VERSION_MINOR: ::__u8 = 0x4; +pub const TLS_1_3_VERSION: ::__u16 = + ((TLS_1_3_VERSION_MAJOR as ::__u16) << 8) | (TLS_1_3_VERSION_MINOR as ::__u16); + +pub const TLS_CIPHER_AES_GCM_128: ::__u16 = 51; +pub const TLS_CIPHER_AES_GCM_128_IV_SIZE: usize = 8; +pub const TLS_CIPHER_AES_GCM_128_KEY_SIZE: usize = 16; +pub const TLS_CIPHER_AES_GCM_128_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_AES_GCM_128_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_AES_GCM_256: ::__u16 = 52; +pub const TLS_CIPHER_AES_GCM_256_IV_SIZE: usize = 8; +pub const TLS_CIPHER_AES_GCM_256_KEY_SIZE: usize = 32; +pub const TLS_CIPHER_AES_GCM_256_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_AES_GCM_256_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_CHACHA20_POLY1305: ::__u16 = 54; +pub const TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE: usize = 12; +pub const TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE: usize = 32; +pub const TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE: usize = 0; +pub const TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE: usize = 8; + +pub const TLS_SET_RECORD_TYPE: ::c_int = 1; +pub const TLS_GET_RECORD_TYPE: ::c_int = 2; + +pub const SOL_TLS: ::c_int = 282; + +// linux/if_alg.h +pub const ALG_SET_KEY: ::c_int = 1; +pub const ALG_SET_IV: ::c_int = 2; +pub const ALG_SET_OP: ::c_int = 3; +pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4; +pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; +pub const ALG_SET_DRBG_ENTROPY: ::c_int = 6; +pub const ALG_SET_KEY_BY_KEY_SERIAL: ::c_int = 7; + +pub const ALG_OP_DECRYPT: ::c_int = 0; +pub const ALG_OP_ENCRYPT: ::c_int = 1; + +// include/uapi/linux/if.h +pub const IF_OPER_UNKNOWN: ::c_int = 0; +pub const IF_OPER_NOTPRESENT: ::c_int = 1; +pub const IF_OPER_DOWN: ::c_int = 2; +pub const IF_OPER_LOWERLAYERDOWN: ::c_int = 3; +pub const IF_OPER_TESTING: ::c_int = 4; +pub const IF_OPER_DORMANT: ::c_int = 5; +pub const IF_OPER_UP: ::c_int = 6; + +pub const IF_LINK_MODE_DEFAULT: ::c_int = 0; +pub const IF_LINK_MODE_DORMANT: ::c_int = 1; +pub const IF_LINK_MODE_TESTING: ::c_int = 2; + +// include/uapi/linux/udp.h +pub const UDP_CORK: ::c_int = 1; +pub const UDP_ENCAP: ::c_int = 100; +pub const UDP_NO_CHECK6_TX: ::c_int = 101; +pub const UDP_NO_CHECK6_RX: ::c_int = 102; + +// include/uapi/linux/mman.h +pub const MAP_SHARED_VALIDATE: ::c_int = 0x3; + +// include/uapi/asm-generic/mman-common.h +pub const MAP_FIXED_NOREPLACE: ::c_int = 0x100000; +pub const MLOCK_ONFAULT: ::c_uint = 0x01; + +// uapi/linux/vm_sockets.h +pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF; +pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0; +#[deprecated( + since = "0.2.74", + note = "VMADDR_CID_RESERVED is removed since Linux v5.6 and \ + replaced with VMADDR_CID_LOCAL" +)] +pub const VMADDR_CID_RESERVED: ::c_uint = 1; +pub const VMADDR_CID_LOCAL: ::c_uint = 1; +pub const VMADDR_CID_HOST: ::c_uint = 2; +pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF; + +// uapi/linux/inotify.h +pub const IN_ACCESS: u32 = 0x0000_0001; +pub const IN_MODIFY: u32 = 0x0000_0002; +pub const IN_ATTRIB: u32 = 0x0000_0004; +pub const IN_CLOSE_WRITE: u32 = 0x0000_0008; +pub const IN_CLOSE_NOWRITE: u32 = 0x0000_0010; +pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE; +pub const IN_OPEN: u32 = 0x0000_0020; +pub const IN_MOVED_FROM: u32 = 0x0000_0040; +pub const IN_MOVED_TO: u32 = 0x0000_0080; +pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO; +pub const IN_CREATE: u32 = 0x0000_0100; +pub const IN_DELETE: u32 = 0x0000_0200; +pub const IN_DELETE_SELF: u32 = 0x0000_0400; +pub const IN_MOVE_SELF: u32 = 0x0000_0800; +pub const IN_UNMOUNT: u32 = 0x0000_2000; +pub const IN_Q_OVERFLOW: u32 = 0x0000_4000; +pub const IN_IGNORED: u32 = 0x0000_8000; +pub const IN_ONLYDIR: u32 = 0x0100_0000; +pub const IN_DONT_FOLLOW: u32 = 0x0200_0000; +pub const IN_EXCL_UNLINK: u32 = 0x0400_0000; + +// linux/keyctl.h +pub const KEY_SPEC_THREAD_KEYRING: i32 = -1; +pub const KEY_SPEC_PROCESS_KEYRING: i32 = -2; +pub const KEY_SPEC_SESSION_KEYRING: i32 = -3; +pub const KEY_SPEC_USER_KEYRING: i32 = -4; +pub const KEY_SPEC_USER_SESSION_KEYRING: i32 = -5; +pub const KEY_SPEC_GROUP_KEYRING: i32 = -6; +pub const KEY_SPEC_REQKEY_AUTH_KEY: i32 = -7; +pub const KEY_SPEC_REQUESTOR_KEYRING: i32 = -8; + +pub const KEY_REQKEY_DEFL_NO_CHANGE: i32 = -1; +pub const KEY_REQKEY_DEFL_DEFAULT: i32 = 0; +pub const KEY_REQKEY_DEFL_THREAD_KEYRING: i32 = 1; +pub const KEY_REQKEY_DEFL_PROCESS_KEYRING: i32 = 2; +pub const KEY_REQKEY_DEFL_SESSION_KEYRING: i32 = 3; +pub const KEY_REQKEY_DEFL_USER_KEYRING: i32 = 4; +pub const KEY_REQKEY_DEFL_USER_SESSION_KEYRING: i32 = 5; +pub const KEY_REQKEY_DEFL_GROUP_KEYRING: i32 = 6; +pub const KEY_REQKEY_DEFL_REQUESTOR_KEYRING: i32 = 7; + +pub const KEYCTL_GET_KEYRING_ID: u32 = 0; +pub const KEYCTL_JOIN_SESSION_KEYRING: u32 = 1; +pub const KEYCTL_UPDATE: u32 = 2; +pub const KEYCTL_REVOKE: u32 = 3; +pub const KEYCTL_CHOWN: u32 = 4; +pub const KEYCTL_SETPERM: u32 = 5; +pub const KEYCTL_DESCRIBE: u32 = 6; +pub const KEYCTL_CLEAR: u32 = 7; +pub const KEYCTL_LINK: u32 = 8; +pub const KEYCTL_UNLINK: u32 = 9; +pub const KEYCTL_SEARCH: u32 = 10; +pub const KEYCTL_READ: u32 = 11; +pub const KEYCTL_INSTANTIATE: u32 = 12; +pub const KEYCTL_NEGATE: u32 = 13; +pub const KEYCTL_SET_REQKEY_KEYRING: u32 = 14; +pub const KEYCTL_SET_TIMEOUT: u32 = 15; +pub const KEYCTL_ASSUME_AUTHORITY: u32 = 16; +pub const KEYCTL_GET_SECURITY: u32 = 17; +pub const KEYCTL_SESSION_TO_PARENT: u32 = 18; +pub const KEYCTL_REJECT: u32 = 19; +pub const KEYCTL_INSTANTIATE_IOV: u32 = 20; +pub const KEYCTL_INVALIDATE: u32 = 21; +pub const KEYCTL_GET_PERSISTENT: u32 = 22; + +pub const IN_MASK_CREATE: u32 = 0x1000_0000; +pub const IN_MASK_ADD: u32 = 0x2000_0000; +pub const IN_ISDIR: u32 = 0x4000_0000; +pub const IN_ONESHOT: u32 = 0x8000_0000; + +pub const IN_ALL_EVENTS: u32 = IN_ACCESS + | IN_MODIFY + | IN_ATTRIB + | IN_CLOSE_WRITE + | IN_CLOSE_NOWRITE + | IN_OPEN + | IN_MOVED_FROM + | IN_MOVED_TO + | IN_DELETE + | IN_CREATE + | IN_DELETE_SELF + | IN_MOVE_SELF; + +pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; +pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + +// uapi/linux/mount.h +pub const OPEN_TREE_CLONE: ::c_uint = 0x01; +pub const OPEN_TREE_CLOEXEC: ::c_uint = O_CLOEXEC as ::c_uint; + +// uapi/linux/netfilter/nf_tables.h +pub const NFT_TABLE_MAXNAMELEN: ::c_int = 256; +pub const NFT_CHAIN_MAXNAMELEN: ::c_int = 256; +pub const NFT_SET_MAXNAMELEN: ::c_int = 256; +pub const NFT_OBJ_MAXNAMELEN: ::c_int = 256; +pub const NFT_USERDATA_MAXLEN: ::c_int = 256; + +pub const NFT_REG_VERDICT: ::c_int = 0; +pub const NFT_REG_1: ::c_int = 1; +pub const NFT_REG_2: ::c_int = 2; +pub const NFT_REG_3: ::c_int = 3; +pub const NFT_REG_4: ::c_int = 4; +pub const __NFT_REG_MAX: ::c_int = 5; +pub const NFT_REG32_00: ::c_int = 8; +pub const NFT_REG32_01: ::c_int = 9; +pub const NFT_REG32_02: ::c_int = 10; +pub const NFT_REG32_03: ::c_int = 11; +pub const NFT_REG32_04: ::c_int = 12; +pub const NFT_REG32_05: ::c_int = 13; +pub const NFT_REG32_06: ::c_int = 14; +pub const NFT_REG32_07: ::c_int = 15; +pub const NFT_REG32_08: ::c_int = 16; +pub const NFT_REG32_09: ::c_int = 17; +pub const NFT_REG32_10: ::c_int = 18; +pub const NFT_REG32_11: ::c_int = 19; +pub const NFT_REG32_12: ::c_int = 20; +pub const NFT_REG32_13: ::c_int = 21; +pub const NFT_REG32_14: ::c_int = 22; +pub const NFT_REG32_15: ::c_int = 23; + +pub const NFT_REG_SIZE: ::c_int = 16; +pub const NFT_REG32_SIZE: ::c_int = 4; + +pub const NFT_CONTINUE: ::c_int = -1; +pub const NFT_BREAK: ::c_int = -2; +pub const NFT_JUMP: ::c_int = -3; +pub const NFT_GOTO: ::c_int = -4; +pub const NFT_RETURN: ::c_int = -5; + +pub const NFT_MSG_NEWTABLE: ::c_int = 0; +pub const NFT_MSG_GETTABLE: ::c_int = 1; +pub const NFT_MSG_DELTABLE: ::c_int = 2; +pub const NFT_MSG_NEWCHAIN: ::c_int = 3; +pub const NFT_MSG_GETCHAIN: ::c_int = 4; +pub const NFT_MSG_DELCHAIN: ::c_int = 5; +pub const NFT_MSG_NEWRULE: ::c_int = 6; +pub const NFT_MSG_GETRULE: ::c_int = 7; +pub const NFT_MSG_DELRULE: ::c_int = 8; +pub const NFT_MSG_NEWSET: ::c_int = 9; +pub const NFT_MSG_GETSET: ::c_int = 10; +pub const NFT_MSG_DELSET: ::c_int = 11; +pub const NFT_MSG_NEWSETELEM: ::c_int = 12; +pub const NFT_MSG_GETSETELEM: ::c_int = 13; +pub const NFT_MSG_DELSETELEM: ::c_int = 14; +pub const NFT_MSG_NEWGEN: ::c_int = 15; +pub const NFT_MSG_GETGEN: ::c_int = 16; +pub const NFT_MSG_TRACE: ::c_int = 17; +cfg_if! { + if #[cfg(not(target_arch = "sparc64"))] { + pub const NFT_MSG_NEWOBJ: ::c_int = 18; + pub const NFT_MSG_GETOBJ: ::c_int = 19; + pub const NFT_MSG_DELOBJ: ::c_int = 20; + pub const NFT_MSG_GETOBJ_RESET: ::c_int = 21; + } +} +pub const NFT_MSG_MAX: ::c_int = 25; + +pub const NFT_SET_ANONYMOUS: ::c_int = 0x1; +pub const NFT_SET_CONSTANT: ::c_int = 0x2; +pub const NFT_SET_INTERVAL: ::c_int = 0x4; +pub const NFT_SET_MAP: ::c_int = 0x8; +pub const NFT_SET_TIMEOUT: ::c_int = 0x10; +pub const NFT_SET_EVAL: ::c_int = 0x20; + +pub const NFT_SET_POL_PERFORMANCE: ::c_int = 0; +pub const NFT_SET_POL_MEMORY: ::c_int = 1; + +pub const NFT_SET_ELEM_INTERVAL_END: ::c_int = 0x1; + +pub const NFT_DATA_VALUE: ::c_uint = 0; +pub const NFT_DATA_VERDICT: ::c_uint = 0xffffff00; + +pub const NFT_DATA_RESERVED_MASK: ::c_uint = 0xffffff00; + +pub const NFT_DATA_VALUE_MAXLEN: ::c_int = 64; + +pub const NFT_BYTEORDER_NTOH: ::c_int = 0; +pub const NFT_BYTEORDER_HTON: ::c_int = 1; + +pub const NFT_CMP_EQ: ::c_int = 0; +pub const NFT_CMP_NEQ: ::c_int = 1; +pub const NFT_CMP_LT: ::c_int = 2; +pub const NFT_CMP_LTE: ::c_int = 3; +pub const NFT_CMP_GT: ::c_int = 4; +pub const NFT_CMP_GTE: ::c_int = 5; + +pub const NFT_RANGE_EQ: ::c_int = 0; +pub const NFT_RANGE_NEQ: ::c_int = 1; + +pub const NFT_LOOKUP_F_INV: ::c_int = 1 << 0; + +pub const NFT_DYNSET_OP_ADD: ::c_int = 0; +pub const NFT_DYNSET_OP_UPDATE: ::c_int = 1; + +pub const NFT_DYNSET_F_INV: ::c_int = 1 << 0; + +pub const NFT_PAYLOAD_LL_HEADER: ::c_int = 0; +pub const NFT_PAYLOAD_NETWORK_HEADER: ::c_int = 1; +pub const NFT_PAYLOAD_TRANSPORT_HEADER: ::c_int = 2; + +pub const NFT_PAYLOAD_CSUM_NONE: ::c_int = 0; +pub const NFT_PAYLOAD_CSUM_INET: ::c_int = 1; + +pub const NFT_META_LEN: ::c_int = 0; +pub const NFT_META_PROTOCOL: ::c_int = 1; +pub const NFT_META_PRIORITY: ::c_int = 2; +pub const NFT_META_MARK: ::c_int = 3; +pub const NFT_META_IIF: ::c_int = 4; +pub const NFT_META_OIF: ::c_int = 5; +pub const NFT_META_IIFNAME: ::c_int = 6; +pub const NFT_META_OIFNAME: ::c_int = 7; +pub const NFT_META_IIFTYPE: ::c_int = 8; +pub const NFT_META_OIFTYPE: ::c_int = 9; +pub const NFT_META_SKUID: ::c_int = 10; +pub const NFT_META_SKGID: ::c_int = 11; +pub const NFT_META_NFTRACE: ::c_int = 12; +pub const NFT_META_RTCLASSID: ::c_int = 13; +pub const NFT_META_SECMARK: ::c_int = 14; +pub const NFT_META_NFPROTO: ::c_int = 15; +pub const NFT_META_L4PROTO: ::c_int = 16; +pub const NFT_META_BRI_IIFNAME: ::c_int = 17; +pub const NFT_META_BRI_OIFNAME: ::c_int = 18; +pub const NFT_META_PKTTYPE: ::c_int = 19; +pub const NFT_META_CPU: ::c_int = 20; +pub const NFT_META_IIFGROUP: ::c_int = 21; +pub const NFT_META_OIFGROUP: ::c_int = 22; +pub const NFT_META_CGROUP: ::c_int = 23; +pub const NFT_META_PRANDOM: ::c_int = 24; + +pub const NFT_CT_STATE: ::c_int = 0; +pub const NFT_CT_DIRECTION: ::c_int = 1; +pub const NFT_CT_STATUS: ::c_int = 2; +pub const NFT_CT_MARK: ::c_int = 3; +pub const NFT_CT_SECMARK: ::c_int = 4; +pub const NFT_CT_EXPIRATION: ::c_int = 5; +pub const NFT_CT_HELPER: ::c_int = 6; +pub const NFT_CT_L3PROTOCOL: ::c_int = 7; +pub const NFT_CT_SRC: ::c_int = 8; +pub const NFT_CT_DST: ::c_int = 9; +pub const NFT_CT_PROTOCOL: ::c_int = 10; +pub const NFT_CT_PROTO_SRC: ::c_int = 11; +pub const NFT_CT_PROTO_DST: ::c_int = 12; +pub const NFT_CT_LABELS: ::c_int = 13; +pub const NFT_CT_PKTS: ::c_int = 14; +pub const NFT_CT_BYTES: ::c_int = 15; + +pub const NFT_LIMIT_PKTS: ::c_int = 0; +pub const NFT_LIMIT_PKT_BYTES: ::c_int = 1; + +pub const NFT_LIMIT_F_INV: ::c_int = 1 << 0; + +pub const NFT_QUEUE_FLAG_BYPASS: ::c_int = 0x01; +pub const NFT_QUEUE_FLAG_CPU_FANOUT: ::c_int = 0x02; +pub const NFT_QUEUE_FLAG_MASK: ::c_int = 0x03; + +pub const NFT_QUOTA_F_INV: ::c_int = 1 << 0; + +pub const NFT_REJECT_ICMP_UNREACH: ::c_int = 0; +pub const NFT_REJECT_TCP_RST: ::c_int = 1; +pub const NFT_REJECT_ICMPX_UNREACH: ::c_int = 2; + +pub const NFT_REJECT_ICMPX_NO_ROUTE: ::c_int = 0; +pub const NFT_REJECT_ICMPX_PORT_UNREACH: ::c_int = 1; +pub const NFT_REJECT_ICMPX_HOST_UNREACH: ::c_int = 2; +pub const NFT_REJECT_ICMPX_ADMIN_PROHIBITED: ::c_int = 3; + +pub const NFT_NAT_SNAT: ::c_int = 0; +pub const NFT_NAT_DNAT: ::c_int = 1; + +pub const NFT_TRACETYPE_UNSPEC: ::c_int = 0; +pub const NFT_TRACETYPE_POLICY: ::c_int = 1; +pub const NFT_TRACETYPE_RETURN: ::c_int = 2; +pub const NFT_TRACETYPE_RULE: ::c_int = 3; + +pub const NFT_NG_INCREMENTAL: ::c_int = 0; +pub const NFT_NG_RANDOM: ::c_int = 1; + +// linux/input.h +pub const FF_MAX: ::__u16 = 0x7f; +pub const FF_CNT: usize = FF_MAX as usize + 1; + +// linux/input-event-codes.h +pub const INPUT_PROP_MAX: ::__u16 = 0x1f; +pub const INPUT_PROP_CNT: usize = INPUT_PROP_MAX as usize + 1; +pub const EV_MAX: ::__u16 = 0x1f; +pub const EV_CNT: usize = EV_MAX as usize + 1; +pub const SYN_MAX: ::__u16 = 0xf; +pub const SYN_CNT: usize = SYN_MAX as usize + 1; +pub const KEY_MAX: ::__u16 = 0x2ff; +pub const KEY_CNT: usize = KEY_MAX as usize + 1; +pub const REL_MAX: ::__u16 = 0x0f; +pub const REL_CNT: usize = REL_MAX as usize + 1; +pub const ABS_MAX: ::__u16 = 0x3f; +pub const ABS_CNT: usize = ABS_MAX as usize + 1; +pub const SW_MAX: ::__u16 = 0x10; +pub const SW_CNT: usize = SW_MAX as usize + 1; +pub const MSC_MAX: ::__u16 = 0x07; +pub const MSC_CNT: usize = MSC_MAX as usize + 1; +pub const LED_MAX: ::__u16 = 0x0f; +pub const LED_CNT: usize = LED_MAX as usize + 1; +pub const REP_MAX: ::__u16 = 0x01; +pub const REP_CNT: usize = REP_MAX as usize + 1; +pub const SND_MAX: ::__u16 = 0x07; +pub const SND_CNT: usize = SND_MAX as usize + 1; + +// linux/uinput.h +pub const UINPUT_VERSION: ::c_uint = 5; +pub const UINPUT_MAX_NAME_SIZE: usize = 80; + +// uapi/linux/fanotify.h +pub const FAN_ACCESS: u64 = 0x0000_0001; +pub const FAN_MODIFY: u64 = 0x0000_0002; +pub const FAN_ATTRIB: u64 = 0x0000_0004; +pub const FAN_CLOSE_WRITE: u64 = 0x0000_0008; +pub const FAN_CLOSE_NOWRITE: u64 = 0x0000_0010; +pub const FAN_OPEN: u64 = 0x0000_0020; +pub const FAN_MOVED_FROM: u64 = 0x0000_0040; +pub const FAN_MOVED_TO: u64 = 0x0000_0080; +pub const FAN_CREATE: u64 = 0x0000_0100; +pub const FAN_DELETE: u64 = 0x0000_0200; +pub const FAN_DELETE_SELF: u64 = 0x0000_0400; +pub const FAN_MOVE_SELF: u64 = 0x0000_0800; +pub const FAN_OPEN_EXEC: u64 = 0x0000_1000; + +pub const FAN_Q_OVERFLOW: u64 = 0x0000_4000; +pub const FAN_FS_ERROR: u64 = 0x0000_8000; + +pub const FAN_OPEN_PERM: u64 = 0x0001_0000; +pub const FAN_ACCESS_PERM: u64 = 0x0002_0000; +pub const FAN_OPEN_EXEC_PERM: u64 = 0x0004_0000; + +pub const FAN_EVENT_ON_CHILD: u64 = 0x0800_0000; + +pub const FAN_RENAME: u64 = 0x1000_0000; + +pub const FAN_ONDIR: u64 = 0x4000_0000; + +pub const FAN_CLOSE: u64 = FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE; +pub const FAN_MOVE: u64 = FAN_MOVED_FROM | FAN_MOVED_TO; + +pub const FAN_CLOEXEC: ::c_uint = 0x0000_0001; +pub const FAN_NONBLOCK: ::c_uint = 0x0000_0002; + +pub const FAN_CLASS_NOTIF: ::c_uint = 0x0000_0000; +pub const FAN_CLASS_CONTENT: ::c_uint = 0x0000_0004; +pub const FAN_CLASS_PRE_CONTENT: ::c_uint = 0x0000_0008; + +pub const FAN_UNLIMITED_QUEUE: ::c_uint = 0x0000_0010; +pub const FAN_UNLIMITED_MARKS: ::c_uint = 0x0000_0020; +pub const FAN_ENABLE_AUDIT: ::c_uint = 0x0000_0040; + +pub const FAN_REPORT_PIDFD: ::c_uint = 0x0000_0080; +pub const FAN_REPORT_TID: ::c_uint = 0x0000_0100; +pub const FAN_REPORT_FID: ::c_uint = 0x0000_0200; +pub const FAN_REPORT_DIR_FID: ::c_uint = 0x0000_0400; +pub const FAN_REPORT_NAME: ::c_uint = 0x0000_0800; +pub const FAN_REPORT_TARGET_FID: ::c_uint = 0x0000_1000; + +pub const FAN_REPORT_DFID_NAME: ::c_uint = FAN_REPORT_DIR_FID | FAN_REPORT_NAME; +pub const FAN_REPORT_DFID_NAME_TARGET: ::c_uint = + FAN_REPORT_DFID_NAME | FAN_REPORT_FID | FAN_REPORT_TARGET_FID; + +pub const FAN_MARK_ADD: ::c_uint = 0x0000_0001; +pub const FAN_MARK_REMOVE: ::c_uint = 0x0000_0002; +pub const FAN_MARK_DONT_FOLLOW: ::c_uint = 0x0000_0004; +pub const FAN_MARK_ONLYDIR: ::c_uint = 0x0000_0008; +pub const FAN_MARK_IGNORED_MASK: ::c_uint = 0x0000_0020; +pub const FAN_MARK_IGNORED_SURV_MODIFY: ::c_uint = 0x0000_0040; +pub const FAN_MARK_FLUSH: ::c_uint = 0x0000_0080; +pub const FAN_MARK_EVICTABLE: ::c_uint = 0x0000_0200; +pub const FAN_MARK_IGNORE: ::c_uint = 0x0000_0100; + +pub const FAN_MARK_INODE: ::c_uint = 0x0000_0000; +pub const FAN_MARK_MOUNT: ::c_uint = 0x0000_0010; +pub const FAN_MARK_FILESYSTEM: ::c_uint = 0x0000_0100; + +pub const FAN_MARK_IGNORE_SURV: ::c_uint = FAN_MARK_IGNORE | FAN_MARK_IGNORED_SURV_MODIFY; + +pub const FANOTIFY_METADATA_VERSION: u8 = 3; + +pub const FAN_EVENT_INFO_TYPE_FID: u8 = 1; +pub const FAN_EVENT_INFO_TYPE_DFID_NAME: u8 = 2; +pub const FAN_EVENT_INFO_TYPE_DFID: u8 = 3; +pub const FAN_EVENT_INFO_TYPE_PIDFD: u8 = 4; +pub const FAN_EVENT_INFO_TYPE_ERROR: u8 = 5; + +pub const FAN_EVENT_INFO_TYPE_OLD_DFID_NAME: u8 = 10; +pub const FAN_EVENT_INFO_TYPE_NEW_DFID_NAME: u8 = 12; + +pub const FAN_RESPONSE_INFO_NONE: u8 = 0; +pub const FAN_RESPONSE_INFO_AUDIT_RULE: u8 = 1; + +pub const FAN_ALLOW: u32 = 0x01; +pub const FAN_DENY: u32 = 0x02; +pub const FAN_AUDIT: u32 = 0x10; +pub const FAN_INFO: u32 = 0x20; + +pub const FAN_NOFD: ::c_int = -1; +pub const FAN_NOPIDFD: ::c_int = FAN_NOFD; +pub const FAN_EPIDFD: ::c_int = -2; + +pub const FUTEX_WAIT: ::c_int = 0; +pub const FUTEX_WAKE: ::c_int = 1; +pub const FUTEX_FD: ::c_int = 2; +pub const FUTEX_REQUEUE: ::c_int = 3; +pub const FUTEX_CMP_REQUEUE: ::c_int = 4; +pub const FUTEX_WAKE_OP: ::c_int = 5; +pub const FUTEX_LOCK_PI: ::c_int = 6; +pub const FUTEX_UNLOCK_PI: ::c_int = 7; +pub const FUTEX_TRYLOCK_PI: ::c_int = 8; +pub const FUTEX_WAIT_BITSET: ::c_int = 9; +pub const FUTEX_WAKE_BITSET: ::c_int = 10; +pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11; +pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12; +pub const FUTEX_LOCK_PI2: ::c_int = 13; + +pub const FUTEX_PRIVATE_FLAG: ::c_int = 128; +pub const FUTEX_CLOCK_REALTIME: ::c_int = 256; +pub const FUTEX_CMD_MASK: ::c_int = !(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME); + +pub const FUTEX_BITSET_MATCH_ANY: ::c_int = 0xffffffff; + +pub const FUTEX_OP_SET: ::c_int = 0; +pub const FUTEX_OP_ADD: ::c_int = 1; +pub const FUTEX_OP_OR: ::c_int = 2; +pub const FUTEX_OP_ANDN: ::c_int = 3; +pub const FUTEX_OP_XOR: ::c_int = 4; + +pub const FUTEX_OP_OPARG_SHIFT: ::c_int = 8; + +pub const FUTEX_OP_CMP_EQ: ::c_int = 0; +pub const FUTEX_OP_CMP_NE: ::c_int = 1; +pub const FUTEX_OP_CMP_LT: ::c_int = 2; +pub const FUTEX_OP_CMP_LE: ::c_int = 3; +pub const FUTEX_OP_CMP_GT: ::c_int = 4; +pub const FUTEX_OP_CMP_GE: ::c_int = 5; + +pub fn FUTEX_OP(op: ::c_int, oparg: ::c_int, cmp: ::c_int, cmparg: ::c_int) -> ::c_int { + ((op & 0xf) << 28) | ((cmp & 0xf) << 24) | ((oparg & 0xfff) << 12) | (cmparg & 0xfff) +} + +// linux/kexec.h +pub const KEXEC_ON_CRASH: ::c_int = 0x00000001; +pub const KEXEC_PRESERVE_CONTEXT: ::c_int = 0x00000002; +pub const KEXEC_ARCH_MASK: ::c_int = 0xffff0000; +pub const KEXEC_FILE_UNLOAD: ::c_int = 0x00000001; +pub const KEXEC_FILE_ON_CRASH: ::c_int = 0x00000002; +pub const KEXEC_FILE_NO_INITRAMFS: ::c_int = 0x00000004; + +// linux/reboot.h +pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead; +pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793; +pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278; +pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448; +pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216; + +pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567; +pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123; +pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF; +pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000; +pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC; +pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4; +pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2; +pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543; + +pub const REG_EXTENDED: ::c_int = 1; +pub const REG_ICASE: ::c_int = 2; +pub const REG_NEWLINE: ::c_int = 4; +pub const REG_NOSUB: ::c_int = 8; + +pub const REG_NOTBOL: ::c_int = 1; +pub const REG_NOTEOL: ::c_int = 2; + +pub const REG_ENOSYS: ::c_int = -1; +pub const REG_NOMATCH: ::c_int = 1; +pub const REG_BADPAT: ::c_int = 2; +pub const REG_ECOLLATE: ::c_int = 3; +pub const REG_ECTYPE: ::c_int = 4; +pub const REG_EESCAPE: ::c_int = 5; +pub const REG_ESUBREG: ::c_int = 6; +pub const REG_EBRACK: ::c_int = 7; +pub const REG_EPAREN: ::c_int = 8; +pub const REG_EBRACE: ::c_int = 9; +pub const REG_BADBR: ::c_int = 10; +pub const REG_ERANGE: ::c_int = 11; +pub const REG_ESPACE: ::c_int = 12; +pub const REG_BADRPT: ::c_int = 13; + +// linux/errqueue.h +pub const SO_EE_ORIGIN_NONE: u8 = 0; +pub const SO_EE_ORIGIN_LOCAL: u8 = 1; +pub const SO_EE_ORIGIN_ICMP: u8 = 2; +pub const SO_EE_ORIGIN_ICMP6: u8 = 3; +pub const SO_EE_ORIGIN_TXSTATUS: u8 = 4; +pub const SO_EE_ORIGIN_TIMESTAMPING: u8 = SO_EE_ORIGIN_TXSTATUS; + +// errno.h +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EWOULDBLOCK: ::c_int = EAGAIN; + +// linux/can.h +pub const CAN_EFF_FLAG: canid_t = 0x80000000; +pub const CAN_RTR_FLAG: canid_t = 0x40000000; +pub const CAN_ERR_FLAG: canid_t = 0x20000000; +pub const CAN_SFF_MASK: canid_t = 0x000007FF; +pub const CAN_EFF_MASK: canid_t = 0x1FFFFFFF; +pub const CAN_ERR_MASK: canid_t = 0x1FFFFFFF; +pub const CANXL_PRIO_MASK: ::canid_t = CAN_SFF_MASK; + +pub const CAN_SFF_ID_BITS: ::c_int = 11; +pub const CAN_EFF_ID_BITS: ::c_int = 29; +pub const CANXL_PRIO_BITS: ::c_int = CAN_SFF_ID_BITS; + +pub const CAN_MAX_DLC: ::c_int = 8; +pub const CAN_MAX_DLEN: usize = 8; +pub const CANFD_MAX_DLC: ::c_int = 15; +pub const CANFD_MAX_DLEN: usize = 64; + +pub const CANFD_BRS: ::c_int = 0x01; +pub const CANFD_ESI: ::c_int = 0x02; + +pub const CANXL_MIN_DLC: ::c_int = 0; +pub const CANXL_MAX_DLC: ::c_int = 2047; +pub const CANXL_MAX_DLC_MASK: ::c_int = 0x07FF; +pub const CANXL_MIN_DLEN: usize = 1; +pub const CANXL_MAX_DLEN: usize = 2048; + +pub const CANXL_XLF: ::c_int = 0x80; +pub const CANXL_SEC: ::c_int = 0x01; + +cfg_if! { + if #[cfg(libc_align)] { + pub const CAN_MTU: usize = ::mem::size_of::(); + pub const CANFD_MTU: usize = ::mem::size_of::(); + pub const CANXL_MTU: usize = ::mem::size_of::(); + // FIXME: use `core::mem::offset_of!` once that is available + // https://github.com/rust-lang/rfcs/pull/3308 + // pub const CANXL_HDR_SIZE: usize = core::mem::offset_of!(canxl_frame, data); + pub const CANXL_HDR_SIZE: usize = 12; + pub const CANXL_MIN_MTU: usize = CANXL_HDR_SIZE + 64; + pub const CANXL_MAX_MTU: usize = CANXL_MTU; + } +} + +pub const CAN_RAW: ::c_int = 1; +pub const CAN_BCM: ::c_int = 2; +pub const CAN_TP16: ::c_int = 3; +pub const CAN_TP20: ::c_int = 4; +pub const CAN_MCNET: ::c_int = 5; +pub const CAN_ISOTP: ::c_int = 6; +pub const CAN_J1939: ::c_int = 7; +pub const CAN_NPROTO: ::c_int = 8; + +pub const SOL_CAN_BASE: ::c_int = 100; + +pub const CAN_INV_FILTER: canid_t = 0x20000000; +pub const CAN_RAW_FILTER_MAX: ::c_int = 512; + +// linux/can/raw.h +pub const SOL_CAN_RAW: ::c_int = SOL_CAN_BASE + CAN_RAW; +pub const CAN_RAW_FILTER: ::c_int = 1; +pub const CAN_RAW_ERR_FILTER: ::c_int = 2; +pub const CAN_RAW_LOOPBACK: ::c_int = 3; +pub const CAN_RAW_RECV_OWN_MSGS: ::c_int = 4; +pub const CAN_RAW_FD_FRAMES: ::c_int = 5; +pub const CAN_RAW_JOIN_FILTERS: ::c_int = 6; +pub const CAN_RAW_XL_FRAMES: ::c_int = 7; + +// linux/can/j1939.h +pub const SOL_CAN_J1939: ::c_int = SOL_CAN_BASE + CAN_J1939; + +pub const J1939_MAX_UNICAST_ADDR: ::c_uchar = 0xfd; +pub const J1939_IDLE_ADDR: ::c_uchar = 0xfe; +pub const J1939_NO_ADDR: ::c_uchar = 0xff; +pub const J1939_NO_NAME: ::c_ulong = 0; +pub const J1939_PGN_REQUEST: ::c_uint = 0x0ea00; +pub const J1939_PGN_ADDRESS_CLAIMED: ::c_uint = 0x0ee00; +pub const J1939_PGN_ADDRESS_COMMANDED: ::c_uint = 0x0fed8; +pub const J1939_PGN_PDU1_MAX: ::c_uint = 0x3ff00; +pub const J1939_PGN_MAX: ::c_uint = 0x3ffff; +pub const J1939_NO_PGN: ::c_uint = 0x40000; + +pub const SO_J1939_FILTER: ::c_int = 1; +pub const SO_J1939_PROMISC: ::c_int = 2; +pub const SO_J1939_SEND_PRIO: ::c_int = 3; +pub const SO_J1939_ERRQUEUE: ::c_int = 4; + +pub const SCM_J1939_DEST_ADDR: ::c_int = 1; +pub const SCM_J1939_DEST_NAME: ::c_int = 2; +pub const SCM_J1939_PRIO: ::c_int = 3; +pub const SCM_J1939_ERRQUEUE: ::c_int = 4; + +pub const J1939_NLA_PAD: ::c_int = 0; +pub const J1939_NLA_BYTES_ACKED: ::c_int = 1; +pub const J1939_NLA_TOTAL_SIZE: ::c_int = 2; +pub const J1939_NLA_PGN: ::c_int = 3; +pub const J1939_NLA_SRC_NAME: ::c_int = 4; +pub const J1939_NLA_DEST_NAME: ::c_int = 5; +pub const J1939_NLA_SRC_ADDR: ::c_int = 6; +pub const J1939_NLA_DEST_ADDR: ::c_int = 7; + +pub const J1939_EE_INFO_NONE: ::c_int = 0; +pub const J1939_EE_INFO_TX_ABORT: ::c_int = 1; +pub const J1939_EE_INFO_RX_RTS: ::c_int = 2; +pub const J1939_EE_INFO_RX_DPO: ::c_int = 3; +pub const J1939_EE_INFO_RX_ABORT: ::c_int = 4; + +pub const J1939_FILTER_MAX: ::c_int = 512; + +// linux/sctp.h +pub const SCTP_FUTURE_ASSOC: ::c_int = 0; +pub const SCTP_CURRENT_ASSOC: ::c_int = 1; +pub const SCTP_ALL_ASSOC: ::c_int = 2; +pub const SCTP_RTOINFO: ::c_int = 0; +pub const SCTP_ASSOCINFO: ::c_int = 1; +pub const SCTP_INITMSG: ::c_int = 2; +pub const SCTP_NODELAY: ::c_int = 3; +pub const SCTP_AUTOCLOSE: ::c_int = 4; +pub const SCTP_SET_PEER_PRIMARY_ADDR: ::c_int = 5; +pub const SCTP_PRIMARY_ADDR: ::c_int = 6; +pub const SCTP_ADAPTATION_LAYER: ::c_int = 7; +pub const SCTP_DISABLE_FRAGMENTS: ::c_int = 8; +pub const SCTP_PEER_ADDR_PARAMS: ::c_int = 9; +pub const SCTP_DEFAULT_SEND_PARAM: ::c_int = 10; +pub const SCTP_EVENTS: ::c_int = 11; +pub const SCTP_I_WANT_MAPPED_V4_ADDR: ::c_int = 12; +pub const SCTP_MAXSEG: ::c_int = 13; +pub const SCTP_STATUS: ::c_int = 14; +pub const SCTP_GET_PEER_ADDR_INFO: ::c_int = 15; +pub const SCTP_DELAYED_ACK_TIME: ::c_int = 16; +pub const SCTP_DELAYED_ACK: ::c_int = SCTP_DELAYED_ACK_TIME; +pub const SCTP_DELAYED_SACK: ::c_int = SCTP_DELAYED_ACK_TIME; +pub const SCTP_CONTEXT: ::c_int = 17; +pub const SCTP_FRAGMENT_INTERLEAVE: ::c_int = 18; +pub const SCTP_PARTIAL_DELIVERY_POINT: ::c_int = 19; +pub const SCTP_MAX_BURST: ::c_int = 20; +pub const SCTP_AUTH_CHUNK: ::c_int = 21; +pub const SCTP_HMAC_IDENT: ::c_int = 22; +pub const SCTP_AUTH_KEY: ::c_int = 23; +pub const SCTP_AUTH_ACTIVE_KEY: ::c_int = 24; +pub const SCTP_AUTH_DELETE_KEY: ::c_int = 25; +pub const SCTP_PEER_AUTH_CHUNKS: ::c_int = 26; +pub const SCTP_LOCAL_AUTH_CHUNKS: ::c_int = 27; +pub const SCTP_GET_ASSOC_NUMBER: ::c_int = 28; +pub const SCTP_GET_ASSOC_ID_LIST: ::c_int = 29; +pub const SCTP_AUTO_ASCONF: ::c_int = 30; +pub const SCTP_PEER_ADDR_THLDS: ::c_int = 31; +pub const SCTP_RECVRCVINFO: ::c_int = 32; +pub const SCTP_RECVNXTINFO: ::c_int = 33; +pub const SCTP_DEFAULT_SNDINFO: ::c_int = 34; +pub const SCTP_AUTH_DEACTIVATE_KEY: ::c_int = 35; +pub const SCTP_REUSE_PORT: ::c_int = 36; +pub const SCTP_PEER_ADDR_THLDS_V2: ::c_int = 37; +pub const SCTP_PR_SCTP_NONE: ::c_int = 0x0000; +pub const SCTP_PR_SCTP_TTL: ::c_int = 0x0010; +pub const SCTP_PR_SCTP_RTX: ::c_int = 0x0020; +pub const SCTP_PR_SCTP_PRIO: ::c_int = 0x0030; +pub const SCTP_PR_SCTP_MAX: ::c_int = SCTP_PR_SCTP_PRIO; +pub const SCTP_PR_SCTP_MASK: ::c_int = 0x0030; +pub const SCTP_ENABLE_RESET_STREAM_REQ: ::c_int = 0x01; +pub const SCTP_ENABLE_RESET_ASSOC_REQ: ::c_int = 0x02; +pub const SCTP_ENABLE_CHANGE_ASSOC_REQ: ::c_int = 0x04; +pub const SCTP_ENABLE_STRRESET_MASK: ::c_int = 0x07; +pub const SCTP_STREAM_RESET_INCOMING: ::c_int = 0x01; +pub const SCTP_STREAM_RESET_OUTGOING: ::c_int = 0x02; + +pub const SCTP_INIT: ::c_int = 0; +pub const SCTP_SNDRCV: ::c_int = 1; +pub const SCTP_SNDINFO: ::c_int = 2; +pub const SCTP_RCVINFO: ::c_int = 3; +pub const SCTP_NXTINFO: ::c_int = 4; +pub const SCTP_PRINFO: ::c_int = 5; +pub const SCTP_AUTHINFO: ::c_int = 6; +pub const SCTP_DSTADDRV4: ::c_int = 7; +pub const SCTP_DSTADDRV6: ::c_int = 8; + +pub const SCTP_UNORDERED: ::c_int = 1 << 0; +pub const SCTP_ADDR_OVER: ::c_int = 1 << 1; +pub const SCTP_ABORT: ::c_int = 1 << 2; +pub const SCTP_SACK_IMMEDIATELY: ::c_int = 1 << 3; +pub const SCTP_SENDALL: ::c_int = 1 << 6; +pub const SCTP_PR_SCTP_ALL: ::c_int = 1 << 7; +pub const SCTP_NOTIFICATION: ::c_int = MSG_NOTIFICATION; +pub const SCTP_EOF: ::c_int = ::MSG_FIN; + +/* DCCP socket options */ +pub const DCCP_SOCKOPT_PACKET_SIZE: ::c_int = 1; +pub const DCCP_SOCKOPT_SERVICE: ::c_int = 2; +pub const DCCP_SOCKOPT_CHANGE_L: ::c_int = 3; +pub const DCCP_SOCKOPT_CHANGE_R: ::c_int = 4; +pub const DCCP_SOCKOPT_GET_CUR_MPS: ::c_int = 5; +pub const DCCP_SOCKOPT_SERVER_TIMEWAIT: ::c_int = 6; +pub const DCCP_SOCKOPT_SEND_CSCOV: ::c_int = 10; +pub const DCCP_SOCKOPT_RECV_CSCOV: ::c_int = 11; +pub const DCCP_SOCKOPT_AVAILABLE_CCIDS: ::c_int = 12; +pub const DCCP_SOCKOPT_CCID: ::c_int = 13; +pub const DCCP_SOCKOPT_TX_CCID: ::c_int = 14; +pub const DCCP_SOCKOPT_RX_CCID: ::c_int = 15; +pub const DCCP_SOCKOPT_QPOLICY_ID: ::c_int = 16; +pub const DCCP_SOCKOPT_QPOLICY_TXQLEN: ::c_int = 17; +pub const DCCP_SOCKOPT_CCID_RX_INFO: ::c_int = 128; +pub const DCCP_SOCKOPT_CCID_TX_INFO: ::c_int = 192; + +/// maximum number of services provided on the same listening port +pub const DCCP_SERVICE_LIST_MAX_LEN: ::c_int = 32; + +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_NET: ::c_int = 3; +pub const CTL_FS: ::c_int = 5; +pub const CTL_DEBUG: ::c_int = 6; +pub const CTL_DEV: ::c_int = 7; +pub const CTL_BUS: ::c_int = 8; +pub const CTL_ABI: ::c_int = 9; +pub const CTL_CPU: ::c_int = 10; + +pub const CTL_BUS_ISA: ::c_int = 1; + +pub const INOTIFY_MAX_USER_INSTANCES: ::c_int = 1; +pub const INOTIFY_MAX_USER_WATCHES: ::c_int = 2; +pub const INOTIFY_MAX_QUEUED_EVENTS: ::c_int = 3; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_SECUREMASK: ::c_int = 5; +pub const KERN_PROF: ::c_int = 6; +pub const KERN_NODENAME: ::c_int = 7; +pub const KERN_DOMAINNAME: ::c_int = 8; +pub const KERN_PANIC: ::c_int = 15; +pub const KERN_REALROOTDEV: ::c_int = 16; +pub const KERN_SPARC_REBOOT: ::c_int = 21; +pub const KERN_CTLALTDEL: ::c_int = 22; +pub const KERN_PRINTK: ::c_int = 23; +pub const KERN_NAMETRANS: ::c_int = 24; +pub const KERN_PPC_HTABRECLAIM: ::c_int = 25; +pub const KERN_PPC_ZEROPAGED: ::c_int = 26; +pub const KERN_PPC_POWERSAVE_NAP: ::c_int = 27; +pub const KERN_MODPROBE: ::c_int = 28; +pub const KERN_SG_BIG_BUFF: ::c_int = 29; +pub const KERN_ACCT: ::c_int = 30; +pub const KERN_PPC_L2CR: ::c_int = 31; +pub const KERN_RTSIGNR: ::c_int = 32; +pub const KERN_RTSIGMAX: ::c_int = 33; +pub const KERN_SHMMAX: ::c_int = 34; +pub const KERN_MSGMAX: ::c_int = 35; +pub const KERN_MSGMNB: ::c_int = 36; +pub const KERN_MSGPOOL: ::c_int = 37; +pub const KERN_SYSRQ: ::c_int = 38; +pub const KERN_MAX_THREADS: ::c_int = 39; +pub const KERN_RANDOM: ::c_int = 40; +pub const KERN_SHMALL: ::c_int = 41; +pub const KERN_MSGMNI: ::c_int = 42; +pub const KERN_SEM: ::c_int = 43; +pub const KERN_SPARC_STOP_A: ::c_int = 44; +pub const KERN_SHMMNI: ::c_int = 45; +pub const KERN_OVERFLOWUID: ::c_int = 46; +pub const KERN_OVERFLOWGID: ::c_int = 47; +pub const KERN_SHMPATH: ::c_int = 48; +pub const KERN_HOTPLUG: ::c_int = 49; +pub const KERN_IEEE_EMULATION_WARNINGS: ::c_int = 50; +pub const KERN_S390_USER_DEBUG_LOGGING: ::c_int = 51; +pub const KERN_CORE_USES_PID: ::c_int = 52; +pub const KERN_TAINTED: ::c_int = 53; +pub const KERN_CADPID: ::c_int = 54; +pub const KERN_PIDMAX: ::c_int = 55; +pub const KERN_CORE_PATTERN: ::c_int = 56; +pub const KERN_PANIC_ON_OOPS: ::c_int = 57; +pub const KERN_HPPA_PWRSW: ::c_int = 58; +pub const KERN_HPPA_UNALIGNED: ::c_int = 59; +pub const KERN_PRINTK_RATELIMIT: ::c_int = 60; +pub const KERN_PRINTK_RATELIMIT_BURST: ::c_int = 61; +pub const KERN_PTY: ::c_int = 62; +pub const KERN_NGROUPS_MAX: ::c_int = 63; +pub const KERN_SPARC_SCONS_PWROFF: ::c_int = 64; +pub const KERN_HZ_TIMER: ::c_int = 65; +pub const KERN_UNKNOWN_NMI_PANIC: ::c_int = 66; +pub const KERN_BOOTLOADER_TYPE: ::c_int = 67; +pub const KERN_RANDOMIZE: ::c_int = 68; +pub const KERN_SETUID_DUMPABLE: ::c_int = 69; +pub const KERN_SPIN_RETRY: ::c_int = 70; +pub const KERN_ACPI_VIDEO_FLAGS: ::c_int = 71; +pub const KERN_IA64_UNALIGNED: ::c_int = 72; +pub const KERN_COMPAT_LOG: ::c_int = 73; +pub const KERN_MAX_LOCK_DEPTH: ::c_int = 74; +pub const KERN_NMI_WATCHDOG: ::c_int = 75; +pub const KERN_PANIC_ON_NMI: ::c_int = 76; + +pub const VM_OVERCOMMIT_MEMORY: ::c_int = 5; +pub const VM_PAGE_CLUSTER: ::c_int = 10; +pub const VM_DIRTY_BACKGROUND: ::c_int = 11; +pub const VM_DIRTY_RATIO: ::c_int = 12; +pub const VM_DIRTY_WB_CS: ::c_int = 13; +pub const VM_DIRTY_EXPIRE_CS: ::c_int = 14; +pub const VM_NR_PDFLUSH_THREADS: ::c_int = 15; +pub const VM_OVERCOMMIT_RATIO: ::c_int = 16; +pub const VM_PAGEBUF: ::c_int = 17; +pub const VM_HUGETLB_PAGES: ::c_int = 18; +pub const VM_SWAPPINESS: ::c_int = 19; +pub const VM_LOWMEM_RESERVE_RATIO: ::c_int = 20; +pub const VM_MIN_FREE_KBYTES: ::c_int = 21; +pub const VM_MAX_MAP_COUNT: ::c_int = 22; +pub const VM_LAPTOP_MODE: ::c_int = 23; +pub const VM_BLOCK_DUMP: ::c_int = 24; +pub const VM_HUGETLB_GROUP: ::c_int = 25; +pub const VM_VFS_CACHE_PRESSURE: ::c_int = 26; +pub const VM_LEGACY_VA_LAYOUT: ::c_int = 27; +pub const VM_SWAP_TOKEN_TIMEOUT: ::c_int = 28; +pub const VM_DROP_PAGECACHE: ::c_int = 29; +pub const VM_PERCPU_PAGELIST_FRACTION: ::c_int = 30; +pub const VM_ZONE_RECLAIM_MODE: ::c_int = 31; +pub const VM_MIN_UNMAPPED: ::c_int = 32; +pub const VM_PANIC_ON_OOM: ::c_int = 33; +pub const VM_VDSO_ENABLED: ::c_int = 34; +pub const VM_MIN_SLAB: ::c_int = 35; + +pub const NET_CORE: ::c_int = 1; +pub const NET_ETHER: ::c_int = 2; +pub const NET_802: ::c_int = 3; +pub const NET_UNIX: ::c_int = 4; +pub const NET_IPV4: ::c_int = 5; +pub const NET_IPX: ::c_int = 6; +pub const NET_ATALK: ::c_int = 7; +pub const NET_NETROM: ::c_int = 8; +pub const NET_AX25: ::c_int = 9; +pub const NET_BRIDGE: ::c_int = 10; +pub const NET_ROSE: ::c_int = 11; +pub const NET_IPV6: ::c_int = 12; +pub const NET_X25: ::c_int = 13; +pub const NET_TR: ::c_int = 14; +pub const NET_DECNET: ::c_int = 15; +pub const NET_ECONET: ::c_int = 16; +pub const NET_SCTP: ::c_int = 17; +pub const NET_LLC: ::c_int = 18; +pub const NET_NETFILTER: ::c_int = 19; +pub const NET_DCCP: ::c_int = 20; +pub const NET_IRDA: ::c_int = 412; + +// include/linux/sched.h +pub const PF_VCPU: ::c_int = 0x00000001; +pub const PF_IDLE: ::c_int = 0x00000002; +pub const PF_EXITING: ::c_int = 0x00000004; +pub const PF_POSTCOREDUMP: ::c_int = 0x00000008; +pub const PF_IO_WORKER: ::c_int = 0x00000010; +pub const PF_WQ_WORKER: ::c_int = 0x00000020; +pub const PF_FORKNOEXEC: ::c_int = 0x00000040; +pub const PF_MCE_PROCESS: ::c_int = 0x00000080; +pub const PF_SUPERPRIV: ::c_int = 0x00000100; +pub const PF_DUMPCORE: ::c_int = 0x00000200; +pub const PF_SIGNALED: ::c_int = 0x00000400; +pub const PF_MEMALLOC: ::c_int = 0x00000800; +pub const PF_NPROC_EXCEEDED: ::c_int = 0x00001000; +pub const PF_USED_MATH: ::c_int = 0x00002000; +pub const PF_USER_WORKER: ::c_int = 0x00004000; +pub const PF_NOFREEZE: ::c_int = 0x00008000; +pub const PF_KSWAPD: ::c_int = 0x00020000; +pub const PF_MEMALLOC_NOFS: ::c_int = 0x00040000; +pub const PF_MEMALLOC_NOIO: ::c_int = 0x00080000; +pub const PF_LOCAL_THROTTLE: ::c_int = 0x00100000; +pub const PF_KTHREAD: ::c_int = 0x00200000; +pub const PF_RANDOMIZE: ::c_int = 0x00400000; +pub const PF_NO_SETAFFINITY: ::c_int = 0x04000000; +pub const PF_MCE_EARLY: ::c_int = 0x08000000; +pub const PF_MEMALLOC_PIN: ::c_int = 0x10000000; + +pub const CSIGNAL: ::c_int = 0x000000ff; + +pub const SCHED_NORMAL: ::c_int = 0; +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; +pub const SCHED_DEADLINE: ::c_int = 6; + +pub const SCHED_RESET_ON_FORK: ::c_int = 0x40000000; + +pub const CLONE_PIDFD: ::c_int = 0x1000; + +pub const SCHED_FLAG_RESET_ON_FORK: ::c_int = 0x01; +pub const SCHED_FLAG_RECLAIM: ::c_int = 0x02; +pub const SCHED_FLAG_DL_OVERRUN: ::c_int = 0x04; +pub const SCHED_FLAG_KEEP_POLICY: ::c_int = 0x08; +pub const SCHED_FLAG_KEEP_PARAMS: ::c_int = 0x10; +pub const SCHED_FLAG_UTIL_CLAMP_MIN: ::c_int = 0x20; +pub const SCHED_FLAG_UTIL_CLAMP_MAX: ::c_int = 0x40; + +pub const SCHED_FLAG_KEEP_ALL: ::c_int = SCHED_FLAG_KEEP_POLICY | SCHED_FLAG_KEEP_PARAMS; + +pub const SCHED_FLAG_UTIL_CLAMP: ::c_int = SCHED_FLAG_UTIL_CLAMP_MIN | SCHED_FLAG_UTIL_CLAMP_MAX; + +pub const SCHED_FLAG_ALL: ::c_int = SCHED_FLAG_RESET_ON_FORK + | SCHED_FLAG_RECLAIM + | SCHED_FLAG_DL_OVERRUN + | SCHED_FLAG_KEEP_ALL + | SCHED_FLAG_UTIL_CLAMP; + +f! { + pub fn NLA_ALIGN(len: ::c_int) -> ::c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max || + next as usize + super::CMSG_ALIGN((*next).cmsg_len as usize) > max + { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + pub fn CPU_ALLOC_SIZE(count: ::c_int) -> ::size_t { + let _dummy: cpu_set_t = ::mem::zeroed(); + let size_in_bits = 8 * ::mem::size_of_val(&_dummy.bits[0]); + ((count as ::size_t + size_in_bits - 1) / 8) as ::size_t + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> ::c_int { + let mut s: u32 = 0; + let size_of_mask = ::mem::size_of_val(&cpuset.bits[0]); + for i in cpuset.bits[..(size / size_of_mask)].iter() { + s += i.count_ones(); + }; + s as ::c_int + } + + pub fn CPU_COUNT(cpuset: &cpu_set_t) -> ::c_int { + CPU_COUNT_S(::mem::size_of::(), cpuset) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn SCTP_PR_INDEX(policy: ::c_int) -> ::c_int { + policy >> 4 - 1 + } + + pub fn SCTP_PR_POLICY(policy: ::c_int) -> ::c_int { + policy & SCTP_PR_SCTP_MASK + } + + pub fn SCTP_PR_SET_POLICY(flags: &mut ::c_int, policy: ::c_int) -> () { + *flags &= !SCTP_PR_SCTP_MASK; + *flags |= policy; + () + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; + major |= (dev & 0xfffff00000000000) >> 32; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as ::c_uint + } + + pub fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } + + pub fn IPTOS_PREC(tos: u8) -> u8 { + tos & IPTOS_PREC_MASK + } + + pub fn RT_TOS(tos: u8) -> u8 { + tos & ::IPTOS_TOS_MASK + } + + pub fn RT_ADDRCLASS(flags: u32) -> u32 { + flags >> 23 + } + + pub fn RT_LOCALADDR(flags: u32) -> bool { + (flags & RTF_ADDRCLASSMASK) == (RTF_LOCAL | RTF_INTERFACE) + } + + pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr { + ee.offset(1) as *mut ::sockaddr + } + + pub fn BPF_RVAL(code: ::__u32) -> ::__u32 { + code & 0x18 + } + + pub fn BPF_MISCOP(code: ::__u32) -> ::__u32 { + code & 0xf8 + } + + pub fn BPF_STMT(code: ::__u16, k: ::__u32) -> sock_filter { + sock_filter{code: code, jt: 0, jf: 0, k: k} + } + + pub fn BPF_JUMP(code: ::__u16, k: ::__u32, jt: ::__u8, jf: ::__u8) -> sock_filter { + sock_filter{code: code, jt: jt, jf: jf, k: k} + } +} + +safe_f! { + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0x00000fff) << 8; + dev |= (major & 0xfffff000) << 32; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } + + pub {const} fn SCTP_PR_TTL_ENABLED(policy: ::c_int) -> bool { + policy == SCTP_PR_SCTP_TTL + } + + pub {const} fn SCTP_PR_RTX_ENABLED(policy: ::c_int) -> bool { + policy == SCTP_PR_SCTP_RTX + } + + pub {const} fn SCTP_PR_PRIO_ENABLED(policy: ::c_int) -> bool { + policy == SCTP_PR_SCTP_PRIO + } +} + +cfg_if! { + if #[cfg(all(not(target_env = "uclibc"), not(target_env = "ohos")))] { + extern "C" { + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut ::sigevent, + ) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + extern "C" { + pub fn pwritev( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + ) -> ::ssize_t; + pub fn preadv( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + ) -> ::ssize_t; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getloadavg( + loadavg: *mut ::c_double, + nelem: ::c_int + ) -> ::c_int; + pub fn process_vm_readv( + pid: ::pid_t, + local_iov: *const ::iovec, + liovcnt: ::c_ulong, + remote_iov: *const ::iovec, + riovcnt: ::c_ulong, + flags: ::c_ulong, + ) -> isize; + pub fn process_vm_writev( + pid: ::pid_t, + local_iov: *const ::iovec, + liovcnt: ::c_ulong, + remote_iov: *const ::iovec, + riovcnt: ::c_ulong, + flags: ::c_ulong, + ) -> isize; + pub fn futimes( + fd: ::c_int, + times: *const ::timeval + ) -> ::c_int; + } + } +} + +// These functions are not available on OpenHarmony +cfg_if! { + if #[cfg(not(target_env = "ohos"))] { + extern "C" { + // Only `getspnam_r` is implemented for musl, out of all of the reenterant + // functions from `shadow.h`. + // https://git.musl-libc.org/cgit/musl/tree/include/shadow.h + pub fn getspnam_r( + name: *const ::c_char, + spbuf: *mut spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut spwd, + ) -> ::c_int; + + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_setattr( + mqd: ::mqd_t, + newattr: *const ::mq_attr, + oldattr: *mut ::mq_attr + ) -> ::c_int; + + pub fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_mutexattr_getrobust( + attr: *const pthread_mutexattr_t, + robustness: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setrobust( + attr: *mut pthread_mutexattr_t, + robustness: ::c_int, + ) -> ::c_int; + } + } +} + +extern "C" { + #[cfg_attr( + not(any(target_env = "musl", target_env = "ohos")), + link_name = "__xpg_strerror_r" + )] + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + pub fn drand48() -> ::c_double; + pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; + pub fn lrand48() -> ::c_long; + pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn mrand48() -> ::c_long; + pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; + pub fn srand48(seed: ::c_long); + pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; + pub fn lcong48(p: *mut ::c_ushort); + + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn setspent(); + pub fn endspent(); + pub fn getspent() -> *mut spwd; + + pub fn getspnam(name: *const ::c_char) -> *mut spwd; + + // System V IPC + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + pub fn semget(key: ::key_t, nsems: ::c_int, semflag: ::c_int) -> ::c_int; + pub fn semop(semid: ::c_int, sops: *mut ::sembuf, nsops: ::size_t) -> ::c_int; + pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int; + pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; + pub fn msgsnd( + msqid: ::c_int, + msgp: *const ::c_void, + msgsz: ::size_t, + msgflg: ::c_int, + ) -> ::c_int; + + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t; + pub fn getxattr( + path: *const c_char, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn lgetxattr( + path: *const c_char, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn fgetxattr( + filedes: ::c_int, + name: *const c_char, + value: *mut ::c_void, + size: ::size_t, + ) -> ::ssize_t; + pub fn setxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn lsetxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fsetxattr( + filedes: ::c_int, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn listxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn llistxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn flistxattr(filedes: ::c_int, list: *mut c_char, size: ::size_t) -> ::ssize_t; + pub fn removexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn lremovexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn fremovexattr(filedes: ::c_int, name: *const c_char) -> ::c_int; + pub fn signalfd(fd: ::c_int, mask: *const ::sigset_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_create(clockid: ::clockid_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_gettime(fd: ::c_int, curr_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn quotactl( + cmd: ::c_int, + special: *const ::c_char, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn epoll_pwait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + sigmask: *const ::sigset_t, + ) -> ::c_int; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + pub fn pthread_getaffinity_np( + thread: ::pthread_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t, + ) -> ::c_int; + pub fn pthread_setaffinity_np( + thread: ::pthread_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t, + ) -> ::c_int; + pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int; + pub fn reboot(how_to: ::c_int) -> ::c_int; + pub fn setfsgid(gid: ::gid_t) -> ::c_int; + pub fn setfsuid(uid: ::uid_t) -> ::c_int; + + // Not available now on Android + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + pub fn sync_file_range( + fd: ::c_int, + offset: ::off64_t, + nbytes: ::off64_t, + flags: ::c_uint, + ) -> ::c_int; + pub fn mremap( + addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ... + ) -> *mut ::c_void; + + pub fn glob( + pattern: *const c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn remap_file_pages( + addr: *mut ::c_void, + size: ::size_t, + prot: ::c_int, + pgoff: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn vhangup() -> ::c_int; + pub fn sync(); + pub fn syncfs(fd: ::c_int) -> ::c_int; + pub fn syscall(num: ::c_long, ...) -> ::c_long; + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t) + -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsize: ::size_t, + cpuset: *const cpu_set_t, + ) -> ::c_int; + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn unshare(flags: ::c_int) -> ::c_int; + pub fn umount(target: *const ::c_char) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn splice( + fd_in: ::c_int, + off_in: *mut ::loff_t, + fd_out: ::c_int, + off_out: *mut ::loff_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int; + pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::c_int; + + pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn setns(fd: ::c_int, nstype: ::c_int) -> ::c_int; + pub fn swapoff(path: *const ::c_char) -> ::c_int; + pub fn vmsplice( + fd: ::c_int, + iov: *const ::iovec, + nr_segs: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + fstype: *const ::c_char, + flags: ::c_ulong, + data: *const ::c_void, + ) -> ::c_int; + pub fn personality(persona: ::c_ulong) -> ::c_int; + pub fn prctl(option: ::c_int, ...) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn pthread_mutexattr_getprotocol( + attr: *const pthread_mutexattr_t, + protocol: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setprotocol( + attr: *mut pthread_mutexattr_t, + protocol: ::c_int, + ) -> ::c_int; + + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_getpshared( + attr: *const ::pthread_barrierattr_t, + shared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_barrierattr_setpshared( + attr: *mut ::pthread_barrierattr_t, + shared: ::c_int, + ) -> ::c_int; + pub fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const ::pthread_barrierattr_t, + count: ::c_uint, + ) -> ::c_int; + pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; + pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn clone( + cb: extern "C" fn(*mut ::c_void) -> ::c_int, + child_stack: *mut ::c_void, + flags: ::c_int, + arg: *mut ::c_void, + ... + ) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getinheritsched( + attr: *const ::pthread_attr_t, + inheritsched: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setinheritsched( + attr: *mut ::pthread_attr_t, + inheritsched: ::c_int, + ) -> ::c_int; + pub fn pthread_attr_getschedpolicy( + attr: *const ::pthread_attr_t, + policy: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setschedpolicy(attr: *mut ::pthread_attr_t, policy: ::c_int) -> ::c_int; + pub fn pthread_attr_getschedparam( + attr: *const ::pthread_attr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn pthread_attr_setschedparam( + attr: *mut ::pthread_attr_t, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn sysinfo(info: *mut ::sysinfo) -> ::c_int; + pub fn umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sendfile( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE; + pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent; + pub fn addmntent(stream: *mut ::FILE, mnt: *const ::mntent) -> ::c_int; + pub fn endmntent(streamp: *mut ::FILE) -> ::c_int; + pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char; + + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + flags: *mut ::c_int, + ) -> ::c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; + pub fn fread_unlocked( + buf: *mut ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_init1(flags: ::c_int) -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::c_int; + pub fn fanotify_init(flags: ::c_uint, event_f_flags: ::c_uint) -> ::c_int; + + pub fn regcomp(preg: *mut ::regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; + + pub fn regexec( + preg: *const ::regex_t, + input: *const ::c_char, + nmatch: ::size_t, + pmatch: *mut regmatch_t, + eflags: ::c_int, + ) -> ::c_int; + + pub fn regerror( + errcode: ::c_int, + preg: *const ::regex_t, + errbuf: *mut ::c_char, + errbuf_size: ::size_t, + ) -> ::size_t; + + pub fn regfree(preg: *mut ::regex_t); + + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; + + pub fn gettid() -> ::pid_t; + + pub fn timer_create( + clockid: ::clockid_t, + sevp: *mut ::sigevent, + timerid: *mut ::timer_t, + ) -> ::c_int; + pub fn timer_delete(timerid: ::timer_t) -> ::c_int; + pub fn timer_getoverrun(timerid: ::timer_t) -> ::c_int; + pub fn timer_gettime(timerid: ::timer_t, curr_value: *mut ::itimerspec) -> ::c_int; + pub fn timer_settime( + timerid: ::timer_t, + flags: ::c_int, + new_value: *const ::itimerspec, + old_value: *mut ::itimerspec, + ) -> ::c_int; + + pub fn gethostid() -> ::c_long; + + pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn sched_getcpu() -> ::c_int; + + pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; + pub fn getopt_long( + argc: ::c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut ::c_int, + ) -> ::c_int; + + pub fn pthread_once(control: *mut pthread_once_t, routine: extern "C" fn()) -> ::c_int; + + pub fn copy_file_range( + fd_in: ::c_int, + off_in: *mut ::off64_t, + fd_out: ::c_int, + off_out: *mut ::off64_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; +} + +// LFS64 extensions +// +// * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones +cfg_if! { + if #[cfg(not(target_env = "musl"))] { + extern "C" { + pub fn fallocate64( + fd: ::c_int, + mode: ::c_int, + offset: ::off64_t, + len: ::off64_t + ) -> ::c_int; + pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut ::FILE, + ) -> *mut ::FILE; + pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int; + pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int; + pub fn ftello64(stream: *mut ::FILE) -> ::off64_t; + pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + pub fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off64_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn tmpfile64() -> *mut ::FILE; + } + } +} + +cfg_if! { + if #[cfg(target_env = "uclibc")] { + mod uclibc; + pub use self::uclibc::*; + } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + mod musl; + pub use self::musl::*; + } else if #[cfg(target_env = "gnu")] { + mod gnu; + pub use self::gnu::*; + } +} + +mod arch; +pub use self::arch::*; + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); + +cfg_if! { + if #[cfg(libc_non_exhaustive)] { + mod non_exhaustive; + pub use self::non_exhaustive::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/align.rs new file mode 100644 index 00000000..aedbf7a9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: (i64, i64) + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs new file mode 100644 index 00000000..8225f26a --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs @@ -0,0 +1,853 @@ +pub type c_char = u8; +pub type wchar_t = u32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_int, + pub msg_rtime: ::time_t, + __unused2: ::c_int, + pub msg_ctime: ::time_t, + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct mcontext_t { + pub trap_no: ::c_ulong, + pub error_code: ::c_ulong, + pub oldmask: ::c_ulong, + pub arm_r0: ::c_ulong, + pub arm_r1: ::c_ulong, + pub arm_r2: ::c_ulong, + pub arm_r3: ::c_ulong, + pub arm_r4: ::c_ulong, + pub arm_r5: ::c_ulong, + pub arm_r6: ::c_ulong, + pub arm_r7: ::c_ulong, + pub arm_r8: ::c_ulong, + pub arm_r9: ::c_ulong, + pub arm_r10: ::c_ulong, + pub arm_fp: ::c_ulong, + pub arm_ip: ::c_ulong, + pub arm_sp: ::c_ulong, + pub arm_lr: ::c_ulong, + pub arm_pc: ::c_ulong, + pub arm_cpsr: ::c_ulong, + pub fault_address: ::c_ulong, + } +} + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_regspace: [::c_ulonglong; 64], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_link) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + } + } + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_LARGEFILE: ::c_int = 0o400000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +pub const SYS_pwritev2: ::c_long = 393; +pub const SYS_pkey_mprotect: ::c_long = 394; +pub const SYS_pkey_alloc: ::c_long = 395; +pub const SYS_pkey_free: ::c_long = 396; +pub const SYS_statx: ::c_long = 397; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs new file mode 100644 index 00000000..089c06f8 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs @@ -0,0 +1,667 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type stat64 = ::stat; + +s! { + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::c_ulonglong, + pub st_mode: ::c_uint, + pub st_nlink: ::c_uint, + pub st_uid: ::c_uint, + pub st_gid: ::c_uint, + pub st_rdev: ::c_ulonglong, + __st_rdev_padding: ::c_ulong, + pub st_size: ::c_longlong, + pub st_blksize: ::blksize_t, + __st_blksize_padding: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + + __unused: [::c_int;2], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_ushort, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_int, + pub msg_rtime: ::time_t, + __unused2: ::c_int, + pub msg_ctime: ::time_t, + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const AF_FILE: ::c_int = 1; +pub const AF_KCM: ::c_int = 41; +pub const AF_MAX: ::c_int = 43; +pub const AF_QIPCRTR: ::c_int = 42; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EALREADY: ::c_int = 114; +pub const EBADE: ::c_int = 52; +pub const EBADMSG: ::c_int = 74; +pub const EBADR: ::c_int = 53; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const ECANCELED: ::c_int = 125; +pub const ECHRNG: ::c_int = 44; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +pub const EDEADLK: ::c_int = 35; +pub const EDEADLOCK: ::c_int = 35; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EDQUOT: ::c_int = 122; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EHWPOISON: ::c_int = 133; +pub const EIDRM: ::c_int = 43; +pub const EILSEQ: ::c_int = 84; +pub const EINPROGRESS: ::c_int = 115; +pub const EISCONN: ::c_int = 106; +pub const EISNAM: ::c_int = 120; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREJECTED: ::c_int = 129; +pub const EKEYREVOKED: ::c_int = 128; +pub const EL2HLT: ::c_int = 51; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBEXEC: ::c_int = 83; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBSCN: ::c_int = 81; +pub const ELNRNG: ::c_int = 48; +pub const ELOOP: ::c_int = 40; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const EMSGSIZE: ::c_int = 90; +pub const EMULTIHOP: ::c_int = 72; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENAVAIL: ::c_int = 119; +pub const ENETDOWN: ::c_int = 100; +pub const ENETRESET: ::c_int = 102; +pub const ENETUNREACH: ::c_int = 101; +pub const ENOANO: ::c_int = 55; +pub const ENOBUFS: ::c_int = 105; +pub const ENOCSI: ::c_int = 50; +pub const ENOKEY: ::c_int = 126; +pub const ENOLCK: ::c_int = 37; +pub const ENOMEDIUM: ::c_int = 123; +pub const ENOMSG: ::c_int = 42; +pub const ENOPROTOOPT: ::c_int = 92; +pub const ENOSYS: ::c_int = 38; +pub const ENOTCONN: ::c_int = 107; +pub const ENOTEMPTY: ::c_int = 39; +pub const ENOTNAM: ::c_int = 118; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ENOTSOCK: ::c_int = 88; +pub const ENOTSUP: ::c_int = 95; +pub const ENOTUNIQ: ::c_int = 76; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EOVERFLOW: ::c_int = 75; +pub const EOWNERDEAD: ::c_int = 130; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EREMCHG: ::c_int = 78; +pub const ERESTART: ::c_int = 85; +pub const ERFKILL: ::c_int = 132; +pub const ESHUTDOWN: ::c_int = 108; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const ESTALE: ::c_int = 116; +pub const ESTRPIPE: ::c_int = 86; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const EUCLEAN: ::c_int = 117; +pub const EUNATCH: ::c_int = 49; +pub const EUSERS: ::c_int = 87; +pub const EXFULL: ::c_int = 54; +pub const EXTPROC: ::c_int = 65536; +pub const F_EXLCK: ::c_int = 4; +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_GETOWNER_UIDS: ::c_int = 17; +pub const F_GETOWN_EX: ::c_int = 16; +pub const F_GETSIG: ::c_int = 11; +pub const F_LINUX_SPECIFIC_BASE: ::c_int = 1024; +pub const FLUSHO: ::c_int = 4096; +pub const F_OWNER_PGRP: ::c_int = 2; +pub const F_OWNER_PID: ::c_int = 1; +pub const F_OWNER_TID: ::c_int = 0; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETOWN_EX: ::c_int = 15; +pub const F_SETSIG: ::c_int = 10; +pub const F_SHLCK: ::c_int = 8; +pub const IEXTEN: ::c_int = 32768; +pub const MAP_ANON: ::c_int = 32; +pub const MAP_DENYWRITE: ::c_int = 2048; +pub const MAP_EXECUTABLE: ::c_int = 4096; +pub const MAP_GROWSDOWN: ::c_int = 256; +pub const MAP_HUGETLB: ::c_int = 262144; +pub const MAP_LOCKED: ::c_int = 8192; +pub const MAP_NONBLOCK: ::c_int = 65536; +pub const MAP_NORESERVE: ::c_int = 16384; +pub const MAP_POPULATE: ::c_int = 32768; +pub const MAP_STACK: ::c_int = 131072; +pub const MAP_UNINITIALIZED: ::c_int = 0; +pub const O_APPEND: ::c_int = 1024; +pub const O_ASYNC: ::c_int = 8192; +pub const O_CREAT: ::c_int = 64; +pub const O_DIRECT: ::c_int = 16384; +pub const O_DIRECTORY: ::c_int = 65536; +pub const O_DSYNC: ::c_int = 4096; +pub const O_EXCL: ::c_int = 128; +pub const O_LARGEFILE: ::c_int = 32768; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NOFOLLOW: ::c_int = 131072; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const PF_FILE: ::c_int = 1; +pub const PF_KCM: ::c_int = 41; +pub const PF_MAX: ::c_int = 43; +pub const PF_QIPCRTR: ::c_int = 42; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SIGBUS: ::c_int = 7; +pub const SIGCHLD: ::c_int = 17; +pub const SIGCONT: ::c_int = 18; +pub const SIGIO: ::c_int = 29; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPROF: ::c_int = 27; +pub const SIGPWR: ::c_int = 30; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIGSTOP: ::c_int = 19; +pub const SIGSYS: ::c_int = 31; +pub const SIGTSTP: ::c_int = 20; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGURG: ::c_int = 23; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGWINCH: ::c_int = 28; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIG_SETMASK: ::c_int = 2; // FIXME check these +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOL_CAIF: ::c_int = 278; +pub const SOL_IUCV: ::c_int = 277; +pub const SOL_KCM: ::c_int = 281; +pub const SOL_NFC: ::c_int = 280; +pub const SOL_PNPIPE: ::c_int = 275; +pub const SOL_PPPOL2TP: ::c_int = 273; +pub const SOL_RDS: ::c_int = 276; +pub const SOL_RXRPC: ::c_int = 272; + +pub const SYS3264_fadvise64: ::c_int = 223; +pub const SYS3264_fcntl: ::c_int = 25; +pub const SYS3264_fstatat: ::c_int = 79; +pub const SYS3264_fstat: ::c_int = 80; +pub const SYS3264_fstatfs: ::c_int = 44; +pub const SYS3264_ftruncate: ::c_int = 46; +pub const SYS3264_lseek: ::c_int = 62; +pub const SYS3264_lstat: ::c_int = 1039; +pub const SYS3264_mmap: ::c_int = 222; +pub const SYS3264_sendfile: ::c_int = 71; +pub const SYS3264_stat: ::c_int = 1038; +pub const SYS3264_statfs: ::c_int = 43; +pub const SYS3264_truncate: ::c_int = 45; +pub const SYS_accept4: ::c_int = 242; +pub const SYS_accept: ::c_int = 202; +pub const SYS_access: ::c_int = 1033; +pub const SYS_acct: ::c_int = 89; +pub const SYS_add_key: ::c_int = 217; +pub const SYS_adjtimex: ::c_int = 171; +pub const SYS_alarm: ::c_int = 1059; +pub const SYS_arch_specific_syscall: ::c_int = 244; +pub const SYS_bdflush: ::c_int = 1075; +pub const SYS_bind: ::c_int = 200; +pub const SYS_bpf: ::c_int = 280; +pub const SYS_brk: ::c_int = 214; +pub const SYS_capget: ::c_int = 90; +pub const SYS_capset: ::c_int = 91; +pub const SYS_chdir: ::c_int = 49; +pub const SYS_chmod: ::c_int = 1028; +pub const SYS_chown: ::c_int = 1029; +pub const SYS_chroot: ::c_int = 51; +pub const SYS_clock_adjtime: ::c_int = 266; +pub const SYS_clock_getres: ::c_int = 114; +pub const SYS_clock_gettime: ::c_int = 113; +pub const SYS_clock_nanosleep: ::c_int = 115; +pub const SYS_clock_settime: ::c_int = 112; +pub const SYS_clone: ::c_int = 220; +pub const SYS_close: ::c_int = 57; +pub const SYS_connect: ::c_int = 203; +pub const SYS_copy_file_range: ::c_int = -1; // FIXME +pub const SYS_creat: ::c_int = 1064; +pub const SYS_delete_module: ::c_int = 106; +pub const SYS_dup2: ::c_int = 1041; +pub const SYS_dup3: ::c_int = 24; +pub const SYS_dup: ::c_int = 23; +pub const SYS_epoll_create1: ::c_int = 20; +pub const SYS_epoll_create: ::c_int = 1042; +pub const SYS_epoll_ctl: ::c_int = 21; +pub const SYS_epoll_pwait: ::c_int = 22; +pub const SYS_epoll_wait: ::c_int = 1069; +pub const SYS_eventfd2: ::c_int = 19; +pub const SYS_eventfd: ::c_int = 1044; +pub const SYS_execveat: ::c_int = 281; +pub const SYS_execve: ::c_int = 221; +pub const SYS_exit: ::c_int = 93; +pub const SYS_exit_group: ::c_int = 94; +pub const SYS_faccessat: ::c_int = 48; +pub const SYS_fadvise64_64: ::c_int = 223; +pub const SYS_fallocate: ::c_int = 47; +pub const SYS_fanotify_init: ::c_int = 262; +pub const SYS_fanotify_mark: ::c_int = 263; +pub const SYS_fchdir: ::c_int = 50; +pub const SYS_fchmodat: ::c_int = 53; +pub const SYS_fchmod: ::c_int = 52; +pub const SYS_fchownat: ::c_int = 54; +pub const SYS_fchown: ::c_int = 55; +pub const SYS_fcntl64: ::c_int = 25; +pub const SYS_fcntl: ::c_int = 25; +pub const SYS_fdatasync: ::c_int = 83; +pub const SYS_fgetxattr: ::c_int = 10; +pub const SYS_finit_module: ::c_int = 273; +pub const SYS_flistxattr: ::c_int = 13; +pub const SYS_flock: ::c_int = 32; +pub const SYS_fork: ::c_int = 1079; +pub const SYS_fremovexattr: ::c_int = 16; +pub const SYS_fsetxattr: ::c_int = 7; +pub const SYS_fstat64: ::c_int = 80; +pub const SYS_fstatat64: ::c_int = 79; +pub const SYS_fstatfs64: ::c_int = 44; +pub const SYS_fstatfs: ::c_int = 44; +pub const SYS_fsync: ::c_int = 82; +pub const SYS_ftruncate64: ::c_int = 46; +pub const SYS_ftruncate: ::c_int = 46; +pub const SYS_futex: ::c_int = 98; +pub const SYS_futimesat: ::c_int = 1066; +pub const SYS_getcpu: ::c_int = 168; +pub const SYS_getcwd: ::c_int = 17; +pub const SYS_getdents64: ::c_int = 61; +pub const SYS_getdents: ::c_int = 1065; +pub const SYS_getegid: ::c_int = 177; +pub const SYS_geteuid: ::c_int = 175; +pub const SYS_getgid: ::c_int = 176; +pub const SYS_getgroups: ::c_int = 158; +pub const SYS_getitimer: ::c_int = 102; +pub const SYS_get_mempolicy: ::c_int = 236; +pub const SYS_getpeername: ::c_int = 205; +pub const SYS_getpgid: ::c_int = 155; +pub const SYS_getpgrp: ::c_int = 1060; +pub const SYS_getpid: ::c_int = 172; +pub const SYS_getppid: ::c_int = 173; +pub const SYS_getpriority: ::c_int = 141; +pub const SYS_getrandom: ::c_int = 278; +pub const SYS_getresgid: ::c_int = 150; +pub const SYS_getresuid: ::c_int = 148; +pub const SYS_getrlimit: ::c_int = 163; +pub const SYS_get_robust_list: ::c_int = 100; +pub const SYS_getrusage: ::c_int = 165; +pub const SYS_getsid: ::c_int = 156; +pub const SYS_getsockname: ::c_int = 204; +pub const SYS_getsockopt: ::c_int = 209; +pub const SYS_gettid: ::c_int = 178; +pub const SYS_gettimeofday: ::c_int = 169; +pub const SYS_getuid: ::c_int = 174; +pub const SYS_getxattr: ::c_int = 8; +pub const SYS_init_module: ::c_int = 105; +pub const SYS_inotify_add_watch: ::c_int = 27; +pub const SYS_inotify_init1: ::c_int = 26; +pub const SYS_inotify_init: ::c_int = 1043; +pub const SYS_inotify_rm_watch: ::c_int = 28; +pub const SYS_io_cancel: ::c_int = 3; +pub const SYS_ioctl: ::c_int = 29; +pub const SYS_io_destroy: ::c_int = 1; +pub const SYS_io_getevents: ::c_int = 4; +pub const SYS_ioprio_get: ::c_int = 31; +pub const SYS_ioprio_set: ::c_int = 30; +pub const SYS_io_setup: ::c_int = 0; +pub const SYS_io_submit: ::c_int = 2; +pub const SYS_kcmp: ::c_int = 272; +pub const SYS_kexec_load: ::c_int = 104; +pub const SYS_keyctl: ::c_int = 219; +pub const SYS_kill: ::c_int = 129; +pub const SYS_lchown: ::c_int = 1032; +pub const SYS_lgetxattr: ::c_int = 9; +pub const SYS_linkat: ::c_int = 37; +pub const SYS_link: ::c_int = 1025; +pub const SYS_listen: ::c_int = 201; +pub const SYS_listxattr: ::c_int = 11; +pub const SYS_llistxattr: ::c_int = 12; +pub const SYS__llseek: ::c_int = 62; +pub const SYS_lookup_dcookie: ::c_int = 18; +pub const SYS_lremovexattr: ::c_int = 15; +pub const SYS_lseek: ::c_int = 62; +pub const SYS_lsetxattr: ::c_int = 6; +pub const SYS_lstat64: ::c_int = 1039; +pub const SYS_lstat: ::c_int = 1039; +pub const SYS_madvise: ::c_int = 233; +pub const SYS_mbind: ::c_int = 235; +pub const SYS_memfd_create: ::c_int = 279; +pub const SYS_migrate_pages: ::c_int = 238; +pub const SYS_mincore: ::c_int = 232; +pub const SYS_mkdirat: ::c_int = 34; +pub const SYS_mkdir: ::c_int = 1030; +pub const SYS_mknodat: ::c_int = 33; +pub const SYS_mknod: ::c_int = 1027; +pub const SYS_mlockall: ::c_int = 230; +pub const SYS_mlock: ::c_int = 228; +pub const SYS_mmap2: ::c_int = 222; +pub const SYS_mount: ::c_int = 40; +pub const SYS_move_pages: ::c_int = 239; +pub const SYS_mprotect: ::c_int = 226; +pub const SYS_mq_getsetattr: ::c_int = 185; +pub const SYS_mq_notify: ::c_int = 184; +pub const SYS_mq_open: ::c_int = 180; +pub const SYS_mq_timedreceive: ::c_int = 183; +pub const SYS_mq_timedsend: ::c_int = 182; +pub const SYS_mq_unlink: ::c_int = 181; +pub const SYS_mremap: ::c_int = 216; +pub const SYS_msgctl: ::c_int = 187; +pub const SYS_msgget: ::c_int = 186; +pub const SYS_msgrcv: ::c_int = 188; +pub const SYS_msgsnd: ::c_int = 189; +pub const SYS_msync: ::c_int = 227; +pub const SYS_munlockall: ::c_int = 231; +pub const SYS_munlock: ::c_int = 229; +pub const SYS_munmap: ::c_int = 215; +pub const SYS_name_to_handle_at: ::c_int = 264; +pub const SYS_nanosleep: ::c_int = 101; +pub const SYS_newfstatat: ::c_int = 79; +pub const SYS_nfsservctl: ::c_int = 42; +pub const SYS_oldwait4: ::c_int = 1072; +pub const SYS_openat: ::c_int = 56; +pub const SYS_open_by_handle_at: ::c_int = 265; +pub const SYS_open: ::c_int = 1024; +pub const SYS_pause: ::c_int = 1061; +pub const SYS_perf_event_open: ::c_int = 241; +pub const SYS_personality: ::c_int = 92; +pub const SYS_pipe2: ::c_int = 59; +pub const SYS_pipe: ::c_int = 1040; +pub const SYS_pivot_root: ::c_int = 41; +pub const SYS_poll: ::c_int = 1068; +pub const SYS_ppoll: ::c_int = 73; +pub const SYS_prctl: ::c_int = 167; +pub const SYS_pread64: ::c_int = 67; +pub const SYS_preadv: ::c_int = 69; +pub const SYS_prlimit64: ::c_int = 261; +pub const SYS_process_vm_readv: ::c_int = 270; +pub const SYS_process_vm_writev: ::c_int = 271; +pub const SYS_pselect6: ::c_int = 72; +pub const SYS_ptrace: ::c_int = 117; +pub const SYS_pwrite64: ::c_int = 68; +pub const SYS_pwritev: ::c_int = 70; +pub const SYS_quotactl: ::c_int = 60; +pub const SYS_readahead: ::c_int = 213; +pub const SYS_read: ::c_int = 63; +pub const SYS_readlinkat: ::c_int = 78; +pub const SYS_readlink: ::c_int = 1035; +pub const SYS_readv: ::c_int = 65; +pub const SYS_reboot: ::c_int = 142; +pub const SYS_recv: ::c_int = 1073; +pub const SYS_recvfrom: ::c_int = 207; +pub const SYS_recvmmsg: ::c_int = 243; +pub const SYS_recvmsg: ::c_int = 212; +pub const SYS_remap_file_pages: ::c_int = 234; +pub const SYS_removexattr: ::c_int = 14; +pub const SYS_renameat2: ::c_int = 276; +pub const SYS_renameat: ::c_int = 38; +pub const SYS_rename: ::c_int = 1034; +pub const SYS_request_key: ::c_int = 218; +pub const SYS_restart_syscall: ::c_int = 128; +pub const SYS_rmdir: ::c_int = 1031; +pub const SYS_rt_sigaction: ::c_int = 134; +pub const SYS_rt_sigpending: ::c_int = 136; +pub const SYS_rt_sigprocmask: ::c_int = 135; +pub const SYS_rt_sigqueueinfo: ::c_int = 138; +pub const SYS_rt_sigreturn: ::c_int = 139; +pub const SYS_rt_sigsuspend: ::c_int = 133; +pub const SYS_rt_sigtimedwait: ::c_int = 137; +pub const SYS_rt_tgsigqueueinfo: ::c_int = 240; +pub const SYS_sched_getaffinity: ::c_int = 123; +pub const SYS_sched_getattr: ::c_int = 275; +pub const SYS_sched_getparam: ::c_int = 121; +pub const SYS_sched_get_priority_max: ::c_int = 125; +pub const SYS_sched_get_priority_min: ::c_int = 126; +pub const SYS_sched_getscheduler: ::c_int = 120; +pub const SYS_sched_rr_get_interval: ::c_int = 127; +pub const SYS_sched_setaffinity: ::c_int = 122; +pub const SYS_sched_setattr: ::c_int = 274; +pub const SYS_sched_setparam: ::c_int = 118; +pub const SYS_sched_setscheduler: ::c_int = 119; +pub const SYS_sched_yield: ::c_int = 124; +pub const SYS_seccomp: ::c_int = 277; +pub const SYS_select: ::c_int = 1067; +pub const SYS_semctl: ::c_int = 191; +pub const SYS_semget: ::c_int = 190; +pub const SYS_semop: ::c_int = 193; +pub const SYS_semtimedop: ::c_int = 192; +pub const SYS_send: ::c_int = 1074; +pub const SYS_sendfile64: ::c_int = 71; +pub const SYS_sendfile: ::c_int = 71; +pub const SYS_sendmmsg: ::c_int = 269; +pub const SYS_sendmsg: ::c_int = 211; +pub const SYS_sendto: ::c_int = 206; +pub const SYS_setdomainname: ::c_int = 162; +pub const SYS_setfsgid: ::c_int = 152; +pub const SYS_setfsuid: ::c_int = 151; +pub const SYS_setgid: ::c_int = 144; +pub const SYS_setgroups: ::c_int = 159; +pub const SYS_sethostname: ::c_int = 161; +pub const SYS_setitimer: ::c_int = 103; +pub const SYS_set_mempolicy: ::c_int = 237; +pub const SYS_setns: ::c_int = 268; +pub const SYS_setpgid: ::c_int = 154; +pub const SYS_setpriority: ::c_int = 140; +pub const SYS_setregid: ::c_int = 143; +pub const SYS_setresgid: ::c_int = 149; +pub const SYS_setresuid: ::c_int = 147; +pub const SYS_setreuid: ::c_int = 145; +pub const SYS_setrlimit: ::c_int = 164; +pub const SYS_set_robust_list: ::c_int = 99; +pub const SYS_setsid: ::c_int = 157; +pub const SYS_setsockopt: ::c_int = 208; +pub const SYS_set_tid_address: ::c_int = 96; +pub const SYS_settimeofday: ::c_int = 170; +pub const SYS_setuid: ::c_int = 146; +pub const SYS_setxattr: ::c_int = 5; +pub const SYS_shmat: ::c_int = 196; +pub const SYS_shmctl: ::c_int = 195; +pub const SYS_shmdt: ::c_int = 197; +pub const SYS_shmget: ::c_int = 194; +pub const SYS_shutdown: ::c_int = 210; +pub const SYS_sigaltstack: ::c_int = 132; +pub const SYS_signalfd4: ::c_int = 74; +pub const SYS_signalfd: ::c_int = 1045; +pub const SYS_socket: ::c_int = 198; +pub const SYS_socketpair: ::c_int = 199; +pub const SYS_splice: ::c_int = 76; +pub const SYS_stat64: ::c_int = 1038; +pub const SYS_stat: ::c_int = 1038; +pub const SYS_statfs64: ::c_int = 43; +pub const SYS_swapoff: ::c_int = 225; +pub const SYS_swapon: ::c_int = 224; +pub const SYS_symlinkat: ::c_int = 36; +pub const SYS_symlink: ::c_int = 1036; +pub const SYS_sync: ::c_int = 81; +pub const SYS_sync_file_range2: ::c_int = 84; +pub const SYS_sync_file_range: ::c_int = 84; +pub const SYS_syncfs: ::c_int = 267; +pub const SYS_syscalls: ::c_int = 1080; +pub const SYS__sysctl: ::c_int = 1078; +pub const SYS_sysinfo: ::c_int = 179; +pub const SYS_syslog: ::c_int = 116; +pub const SYS_tee: ::c_int = 77; +pub const SYS_tgkill: ::c_int = 131; +pub const SYS_time: ::c_int = 1062; +pub const SYS_timer_create: ::c_int = 107; +pub const SYS_timer_delete: ::c_int = 111; +pub const SYS_timerfd_create: ::c_int = 85; +pub const SYS_timerfd_gettime: ::c_int = 87; +pub const SYS_timerfd_settime: ::c_int = 86; +pub const SYS_timer_getoverrun: ::c_int = 109; +pub const SYS_timer_gettime: ::c_int = 108; +pub const SYS_timer_settime: ::c_int = 110; +pub const SYS_times: ::c_int = 153; +pub const SYS_tkill: ::c_int = 130; +pub const SYS_truncate64: ::c_int = 45; +pub const SYS_truncate: ::c_int = 45; +pub const SYS_umask: ::c_int = 166; +pub const SYS_umount2: ::c_int = 39; +pub const SYS_umount: ::c_int = 1076; +pub const SYS_uname: ::c_int = 160; +pub const SYS_unlinkat: ::c_int = 35; +pub const SYS_unlink: ::c_int = 1026; +pub const SYS_unshare: ::c_int = 97; +pub const SYS_uselib: ::c_int = 1077; +pub const SYS_ustat: ::c_int = 1070; +pub const SYS_utime: ::c_int = 1063; +pub const SYS_utimensat: ::c_int = 88; +pub const SYS_utimes: ::c_int = 1037; +pub const SYS_vfork: ::c_int = 1071; +pub const SYS_vhangup: ::c_int = 58; +pub const SYS_vmsplice: ::c_int = 75; +pub const SYS_wait4: ::c_int = 260; +pub const SYS_waitid: ::c_int = 95; +pub const SYS_write: ::c_int = 64; +pub const SYS_writev: ::c_int = 66; +pub const SYS_statx: ::c_int = 291; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const TIOCM_LOOP: ::c_int = 32768; +pub const TIOCM_OUT1: ::c_int = 8192; +pub const TIOCM_OUT2: ::c_int = 16384; +pub const TIOCSER_TEMT: ::c_int = 1; +pub const TOSTOP: ::c_int = 256; +pub const VEOF: ::c_int = 4; +pub const VEOL2: ::c_int = 16; +pub const VEOL: ::c_int = 11; +pub const VMIN: ::c_int = 6; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs new file mode 100644 index 00000000..8c228eba --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f32; 4] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs new file mode 100644 index 00000000..2fb405bb --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs @@ -0,0 +1,788 @@ +pub type c_char = i8; +pub type wchar_t = ::c_int; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __st_padding1: [::c_long; 2], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_padding2: [::c_long; 2], + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + __st_padding3: ::c_long, + pub st_blocks: ::blkcnt_t, + __st_padding4: [::c_long; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_padding1: [::c_long; 2], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_padding2: [::c_long; 2], + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + __st_padding3: ::c_long, + pub st_blocks: ::blkcnt64_t, + __st_padding4: [::c_long; 14], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __unused1: ::c_int, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __unused1: ::c_int, + #[cfg(target_endian = "big")] + __unused2: ::c_int, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __unused2: ::c_int, + #[cfg(target_endian = "big")] + __unused3: ::c_int, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 5], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 5], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const O_DIRECT: ::c_int = 0o100000; +pub const O_DIRECTORY: ::c_int = 0o200000; +pub const O_NOFOLLOW: ::c_int = 0o400000; +pub const O_ASYNC: ::c_int = 0o10000; +pub const O_LARGEFILE: ::c_int = 0x2000; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const O_APPEND: ::c_int = 0o010; +pub const O_CREAT: ::c_int = 0o400; +pub const O_EXCL: ::c_int = 0o2000; +pub const O_NOCTTY: ::c_int = 0o4000; +pub const O_NONBLOCK: ::c_int = 0o200; +pub const O_SYNC: ::c_int = 0o40020; +pub const O_RSYNC: ::c_int = 0o40020; +pub const O_DSYNC: ::c_int = 0o020; + +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_NORESERVE: ::c_int = 0x0400; +pub const MAP_POPULATE: ::c_int = 0x10000; +pub const MAP_NONBLOCK: ::c_int = 0x20000; +pub const MAP_STACK: ::c_int = 0x40000; +pub const MAP_HUGETLB: ::c_int = 0x80000; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const EHWPOISON: ::c_int = 168; +pub const ERFKILL: ::c_int = 167; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 8; +pub const SA_NOCLDWAIT: ::c_int = 0x10000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGWINCH: ::c_int = 20; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGCONT: ::c_int = 25; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGURG: ::c_int = 21; +pub const SIGIO: ::c_int = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGSTKFLT: ::c_int = 7; +pub const SIGPOLL: ::c_int = ::SIGIO; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; + +pub const EXTPROC: ::tcflag_t = 0o200000; + +pub const F_GETLK: ::c_int = 33; +pub const F_GETOWN: ::c_int = 23; +pub const F_SETLK: ::c_int = 34; +pub const F_SETLKW: ::c_int = 35; +pub const F_SETOWN: ::c_int = 24; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0o000400; +pub const TOSTOP: ::tcflag_t = 0o100000; +pub const FLUSHO: ::tcflag_t = 0o020000; + +pub const POLLWRNORM: ::c_short = 0x4; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +pub const SYS_pwritev2: ::c_long = 4000 + 362; +pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; +pub const SYS_pkey_alloc: ::c_long = 4000 + 364; +pub const SYS_pkey_free: ::c_long = 4000 + 365; +pub const SYS_statx: ::c_long = 4000 + 366; +pub const SYS_pidfd_send_signal: ::c_long = 4000 + 424; +pub const SYS_io_uring_setup: ::c_long = 4000 + 425; +pub const SYS_io_uring_enter: ::c_long = 4000 + 426; +pub const SYS_io_uring_register: ::c_long = 4000 + 427; +pub const SYS_open_tree: ::c_long = 4000 + 428; +pub const SYS_move_mount: ::c_long = 4000 + 429; +pub const SYS_fsopen: ::c_long = 4000 + 430; +pub const SYS_fsconfig: ::c_long = 4000 + 431; +pub const SYS_fsmount: ::c_long = 4000 + 432; +pub const SYS_fspick: ::c_long = 4000 + 433; +pub const SYS_pidfd_open: ::c_long = 4000 + 434; +pub const SYS_clone3: ::c_long = 4000 + 435; +pub const SYS_close_range: ::c_long = 4000 + 436; +pub const SYS_openat2: ::c_long = 4000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 4000 + 438; +pub const SYS_faccessat2: ::c_long = 4000 + 439; +pub const SYS_process_madvise: ::c_long = 4000 + 440; +pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; +pub const SYS_mount_setattr: ::c_long = 4000 + 442; +pub const SYS_quotactl_fd: ::c_long = 4000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; +pub const SYS_memfd_secret: ::c_long = 4000 + 447; +pub const SYS_process_mrelease: ::c_long = 4000 + 448; +pub const SYS_futex_waitv: ::c_long = 4000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs new file mode 100644 index 00000000..cecd6dca --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs @@ -0,0 +1,65 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type nlink_t = u32; +pub type blksize_t = ::c_long; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; +pub type regoff_t = ::c_int; + +s! { + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 4], + } +} + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + +cfg_if! { + if #[cfg(any(target_arch = "x86"))] { + mod x86; + pub use self::x86::*; + } else if #[cfg(any(target_arch = "mips"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(any(target_arch = "arm"))] { + mod arm; + pub use self::arm::*; + } else if #[cfg(any(target_arch = "powerpc"))] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(any(target_arch = "hexagon"))] { + mod hexagon; + pub use self::hexagon::*; + } else if #[cfg(any(target_arch = "riscv32"))] { + mod riscv32; + pub use self::riscv32::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs new file mode 100644 index 00000000..bdf25455 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs @@ -0,0 +1,802 @@ +pub type c_char = u8; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_short, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_short, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 2], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __pad1: ::c_int, + __pad2: ::c_longlong, + __pad3: ::c_longlong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + __unused1: ::c_int, + pub shm_atime: ::time_t, + __unused2: ::c_int, + pub shm_dtime: ::time_t, + __unused3: ::c_int, + pub shm_ctime: ::time_t, + __unused4: ::c_int, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __unused1: ::c_int, + pub msg_stime: ::time_t, + __unused2: ::c_int, + pub msg_rtime: ::time_t, + __unused3: ::c_int, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const SIGSTKSZ: ::size_t = 10240; +pub const MINSIGSTKSZ: ::size_t = 4096; + +pub const O_DIRECT: ::c_int = 0x20000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_LARGEFILE: ::c_int = 0x10000; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; +pub const CBAUD: ::tcflag_t = 0o0000377; +pub const TAB1: ::c_int = 0x00000400; +pub const TAB2: ::c_int = 0x00000800; +pub const TAB3: ::c_int = 0x00000C00; +pub const CR1: ::c_int = 0x00001000; +pub const CR2: ::c_int = 0x00002000; +pub const CR3: ::c_int = 0x00003000; +pub const FF1: ::c_int = 0x00004000; +pub const BS1: ::c_int = 0x00008000; +pub const VT1: ::c_int = 0x00010000; +pub const VWERASE: usize = 10; +pub const VREPRINT: usize = 11; +pub const VSUSP: usize = 12; +pub const VSTART: usize = 13; +pub const VSTOP: usize = 14; +pub const VDISCARD: usize = 16; +pub const VTIME: usize = 7; +pub const IXON: ::tcflag_t = 0x00000200; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const ONLCR: ::tcflag_t = 0x00000002; +pub const CSIZE: ::tcflag_t = 0x00000300; +pub const CS6: ::tcflag_t = 0x00000100; +pub const CS7: ::tcflag_t = 0x00000200; +pub const CS8: ::tcflag_t = 0x00000300; +pub const CSTOPB: ::tcflag_t = 0x00000400; +pub const CREAD: ::tcflag_t = 0x00000800; +pub const PARENB: ::tcflag_t = 0x00001000; +pub const PARODD: ::tcflag_t = 0x00002000; +pub const HUPCL: ::tcflag_t = 0x00004000; +pub const CLOCAL: ::tcflag_t = 0x00008000; +pub const ECHOKE: ::tcflag_t = 0x00000001; +pub const ECHOE: ::tcflag_t = 0x00000002; +pub const ECHOK: ::tcflag_t = 0x00000004; +pub const ECHONL: ::tcflag_t = 0x00000010; +pub const ECHOPRT: ::tcflag_t = 0x00000020; +pub const ECHOCTL: ::tcflag_t = 0x00000040; +pub const ISIG: ::tcflag_t = 0x00000080; +pub const ICANON: ::tcflag_t = 0x00000100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const CIBAUD: ::tcflag_t = 0o00077600000; +pub const CBAUDEX: ::tcflag_t = 0o000020; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o001400; +pub const CRDLY: ::tcflag_t = 0o030000; +pub const TABDLY: ::tcflag_t = 0o006000; +pub const BSDLY: ::tcflag_t = 0o100000; +pub const FFDLY: ::tcflag_t = 0o040000; +pub const VTDLY: ::tcflag_t = 0o200000; +pub const XTABS: ::tcflag_t = 0o006000; +pub const B57600: ::speed_t = 0o000020; +pub const B115200: ::speed_t = 0o000021; +pub const B230400: ::speed_t = 0o000022; +pub const B460800: ::speed_t = 0o000023; +pub const B500000: ::speed_t = 0o000024; +pub const B576000: ::speed_t = 0o000025; +pub const B921600: ::speed_t = 0o000026; +pub const B1000000: ::speed_t = 0o000027; +pub const B1152000: ::speed_t = 0o000030; +pub const B1500000: ::speed_t = 0o000031; +pub const B2000000: ::speed_t = 0o000032; +pub const B2500000: ::speed_t = 0o000033; +pub const B3000000: ::speed_t = 0o000034; +pub const B3500000: ::speed_t = 0o000035; +pub const B4000000: ::speed_t = 0o000036; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x00080; +pub const MAP_NORESERVE: ::c_int = 0x00040; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const PTRACE_SYSEMU: ::c_int = 0x1d; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 0x1e; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EDEADLOCK: ::c_int = 58; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const EXTPROC: ::tcflag_t = 0x10000000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: ::tcflag_t = 0x00000400; +pub const TOSTOP: ::tcflag_t = 0x00400000; +pub const FLUSHO: ::tcflag_t = 0x00800000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; +pub const SYS_putpmsg: ::c_long = 188; +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; +pub const SYS_readahead: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_fcntl64: ::c_long = 204; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_sendfile64: ::c_long = 226; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_fadvise64: ::c_long = 233; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_fadvise64_64: ::c_long = 254; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_fstatat64: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +pub const SYS_preadv2: ::c_long = 380; +pub const SYS_pwritev2: ::c_long = 381; +pub const SYS_kexec_file_load: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_pkey_alloc: ::c_long = 384; +pub const SYS_pkey_free: ::c_long = 385; +pub const SYS_pkey_mprotect: ::c_long = 386; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs new file mode 100644 index 00000000..048268c9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: (i64, f64) + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs new file mode 100644 index 00000000..f963f645 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs @@ -0,0 +1,798 @@ +//! RISC-V-specific definitions for 32-bit linux-like values + +pub type c_char = u8; +pub type wchar_t = ::c_int; + +s! { + pub struct pthread_attr_t { + __size: [::c_ulong; 7], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2usize], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [u64; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused5: ::c_ulong, + __unused6: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_int, + pub msg_rtime: ::time_t, + __unused2: ::c_int, + pub msg_ctime: ::time_t, + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } +} + +//pub const RLIM_INFINITY: ::rlim_t = !0; +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const TIOCGSOFTCAR: ::c_ulong = 21529; +pub const TIOCSSOFTCAR: ::c_ulong = 21530; +pub const TIOCGRS485: ::c_int = 21550; +pub const TIOCSRS485: ::c_int = 21551; +//pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +//pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +//pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +//pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +//pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 1052672; +pub const MAP_GROWSDOWN: ::c_int = 256; +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 8; +pub const SA_SIGINFO: ::c_int = 4; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const POLLWRNORM: ::c_short = 256; +pub const POLLWRBAND: ::c_short = 512; +pub const O_ASYNC: ::c_int = 8192; +pub const O_NDELAY: ::c_int = 2048; +pub const EFD_NONBLOCK: ::c_int = 2048; +pub const F_SETOWN: ::c_int = 8; +pub const F_GETOWN: ::c_int = 9; +pub const F_GETLK: ::c_int = 12; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const SFD_NONBLOCK: ::c_int = 2048; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +pub const TIOCLINUX: ::c_ulong = 21532; +pub const TIOCGSERIAL: ::c_ulong = 21534; +pub const TIOCEXCL: ::c_ulong = 21516; +pub const TIOCNXCL: ::c_ulong = 21517; +pub const TIOCSCTTY: ::c_ulong = 21518; +pub const TIOCSTI: ::c_ulong = 21522; +pub const TIOCMGET: ::c_ulong = 21525; +pub const TIOCMBIS: ::c_ulong = 21526; +pub const TIOCMBIC: ::c_ulong = 21527; +pub const TIOCMSET: ::c_ulong = 21528; +pub const TIOCCONS: ::c_ulong = 21533; +pub const TIOCM_ST: ::c_int = 8; +pub const TIOCM_SR: ::c_int = 16; +pub const TIOCM_CTS: ::c_int = 32; +pub const TIOCM_CAR: ::c_int = 64; +pub const TIOCM_RNG: ::c_int = 128; +pub const TIOCM_DSR: ::c_int = 256; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const O_DIRECT: ::c_int = 16384; +pub const O_DIRECTORY: ::c_int = 65536; +pub const O_LARGEFILE: ::c_int = 0o0100000; +pub const O_NOFOLLOW: ::c_int = 131072; +pub const MAP_HUGETLB: ::c_int = 262144; +pub const MAP_LOCKED: ::c_int = 8192; +pub const MAP_NORESERVE: ::c_int = 16384; +pub const MAP_ANON: ::c_int = 32; +pub const MAP_ANONYMOUS: ::c_int = 32; +pub const MAP_DENYWRITE: ::c_int = 2048; +pub const MAP_EXECUTABLE: ::c_int = 4096; +pub const MAP_POPULATE: ::c_int = 32768; +pub const MAP_NONBLOCK: ::c_int = 65536; +pub const MAP_STACK: ::c_int = 131072; +pub const MAP_SYNC: ::c_int = 0x080000; +pub const EDEADLOCK: ::c_int = 35; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const FIOCLEX: ::c_int = 21585; +pub const FIONCLEX: ::c_int = 21584; +pub const FIONBIO: ::c_int = 21537; +pub const MCL_CURRENT: ::c_int = 1; +pub const MCL_FUTURE: ::c_int = 2; +pub const MCL_ONFAULT: ::c_int = 4; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 4111; +pub const TAB1: ::tcflag_t = 2048; +pub const TAB2: ::tcflag_t = 4096; +pub const TAB3: ::tcflag_t = 6144; +pub const CR1: ::tcflag_t = 512; +pub const CR2: ::tcflag_t = 1024; +pub const CR3: ::tcflag_t = 1536; +pub const FF1: ::tcflag_t = 32768; +pub const BS1: ::tcflag_t = 8192; +pub const VT1: ::tcflag_t = 16384; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 1024; +pub const IXOFF: ::tcflag_t = 4096; +pub const ONLCR: ::tcflag_t = 4; +pub const CSIZE: ::tcflag_t = 48; +pub const CS6: ::tcflag_t = 16; +pub const CS7: ::tcflag_t = 32; +pub const CS8: ::tcflag_t = 48; +pub const CSTOPB: ::tcflag_t = 64; +pub const CREAD: ::tcflag_t = 128; +pub const PARENB: ::tcflag_t = 256; +pub const PARODD: ::tcflag_t = 512; +pub const HUPCL: ::tcflag_t = 1024; +pub const CLOCAL: ::tcflag_t = 2048; +pub const ECHOKE: ::tcflag_t = 2048; +pub const ECHOE: ::tcflag_t = 16; +pub const ECHOK: ::tcflag_t = 32; +pub const ECHONL: ::tcflag_t = 64; +pub const ECHOPRT: ::tcflag_t = 1024; +pub const ECHOCTL: ::tcflag_t = 512; +pub const ISIG: ::tcflag_t = 1; +pub const ICANON: ::tcflag_t = 2; +pub const PENDIN: ::tcflag_t = 16384; +pub const NOFLSH: ::tcflag_t = 128; +pub const CIBAUD: ::tcflag_t = 269418496; +pub const CBAUDEX: ::tcflag_t = 4096; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 2; +pub const NLDLY: ::tcflag_t = 256; +pub const CRDLY: ::tcflag_t = 1536; +pub const TABDLY: ::tcflag_t = 6144; +pub const BSDLY: ::tcflag_t = 8192; +pub const FFDLY: ::tcflag_t = 32768; +pub const VTDLY: ::tcflag_t = 16384; +pub const XTABS: ::tcflag_t = 6144; +pub const B0: ::speed_t = 0; +pub const B50: ::speed_t = 1; +pub const B75: ::speed_t = 2; +pub const B110: ::speed_t = 3; +pub const B134: ::speed_t = 4; +pub const B150: ::speed_t = 5; +pub const B200: ::speed_t = 6; +pub const B300: ::speed_t = 7; +pub const B600: ::speed_t = 8; +pub const B1200: ::speed_t = 9; +pub const B1800: ::speed_t = 10; +pub const B2400: ::speed_t = 11; +pub const B4800: ::speed_t = 12; +pub const B9600: ::speed_t = 13; +pub const B19200: ::speed_t = 14; +pub const B38400: ::speed_t = 15; +pub const EXTA: ::speed_t = 14; +pub const EXTB: ::speed_t = 15; +pub const B57600: ::speed_t = 4097; +pub const B115200: ::speed_t = 4098; +pub const B230400: ::speed_t = 4099; +pub const B460800: ::speed_t = 4100; +pub const B500000: ::speed_t = 4101; +pub const B576000: ::speed_t = 4102; +pub const B921600: ::speed_t = 4103; +pub const B1000000: ::speed_t = 4104; +pub const B1152000: ::speed_t = 4105; +pub const B1500000: ::speed_t = 4106; +pub const B2000000: ::speed_t = 4107; +pub const B2500000: ::speed_t = 4108; +pub const B3000000: ::speed_t = 4109; +pub const B3500000: ::speed_t = 4110; +pub const B4000000: ::speed_t = 4111; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 32768; +pub const TOSTOP: ::tcflag_t = 256; +pub const FLUSHO: ::tcflag_t = 4096; +pub const EXTPROC: ::tcflag_t = 65536; +pub const TCGETS: ::c_int = 21505; +pub const TCSETS: ::c_int = 21506; +pub const TCSETSW: ::c_int = 21507; +pub const TCSETSF: ::c_int = 21508; +pub const TCGETA: ::c_int = 21509; +pub const TCSETA: ::c_int = 21510; +pub const TCSETAW: ::c_int = 21511; +pub const TCSETAF: ::c_int = 21512; +pub const TCSBRK: ::c_int = 21513; +pub const TCXONC: ::c_int = 21514; +pub const TCFLSH: ::c_int = 21515; +pub const TIOCINQ: ::c_int = 21531; +pub const TIOCGPGRP: ::c_int = 21519; +pub const TIOCSPGRP: ::c_int = 21520; +pub const TIOCOUTQ: ::c_int = 21521; +pub const TIOCGWINSZ: ::c_int = 21523; +pub const TIOCSWINSZ: ::c_int = 21524; +pub const FIONREAD: ::c_int = 21531; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_close: ::c_long = 57; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_brk: ::c_long = 214; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_dup: ::c_long = 23; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_sendfile: ::c_long = 71; +pub const SYS_socket: ::c_long = 198; +pub const SYS_connect: ::c_long = 203; +pub const SYS_accept: ::c_long = 202; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_exit: ::c_long = 93; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_kill: ::c_long = 129; +pub const SYS_uname: ::c_long = 160; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semop: ::c_long = 193; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_flock: ::c_long = 32; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_umask: ::c_long = 166; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_times: ::c_long = 153; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_personality: ::c_long = 92; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_sync: ::c_long = 81; +pub const SYS_acct: ::c_long = 89; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_mount: ::c_long = 40; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_futex: ::c_long = 98; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_fadvise64: ::c_long = 223; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_openat: ::c_long = 56; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_setns: ::c_long = 268; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/align.rs new file mode 100644 index 00000000..79544176 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 3] + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs new file mode 100644 index 00000000..12280851 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs @@ -0,0 +1,968 @@ +pub type c_char = i8; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_int, + pub msg_rtime: ::time_t, + __unused2: ::c_int, + pub msg_ctime: ::time_t, + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct mcontext_t { + __private: [u32; 22] + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +s_no_extra_traits! { + pub struct user_fpxregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub twd: ::c_ushort, + pub fop: ::c_ushort, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub mxcsr: ::c_long, + __reserved: ::c_long, + pub st_space: [::c_long; 32], + pub xmm_space: [::c_long; 32], + padding: [::c_long; 56], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpxregs_struct { + fn eq(&self, other: &user_fpxregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.twd == other.twd + && self.fop == other.fop + && self.fip == other.fip + && self.fcs == other.fcs + && self.foo == other.foo + && self.fos == other.fos + && self.mxcsr == other.mxcsr + // Ignore __reserved field + && self.st_space == other.st_space + && self.xmm_space == other.xmm_space + // Ignore padding field + } + } + + impl Eq for user_fpxregs_struct {} + + impl ::fmt::Debug for user_fpxregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpxregs_struct") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("twd", &self.twd) + .field("fop", &self.fop) + .field("fip", &self.fip) + .field("fcs", &self.fcs) + .field("foo", &self.foo) + .field("fos", &self.fos) + .field("mxcsr", &self.mxcsr) + // Ignore __reserved field + .field("st_space", &self.st_space) + .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpxregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.twd.hash(state); + self.fop.hash(state); + self.fip.hash(state); + self.fcs.hash(state); + self.foo.hash(state); + self.fos.hash(state); + self.mxcsr.hash(state); + // Ignore __reserved field + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_32BIT: ::c_int = 0x0040; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const PTRACE_SYSEMU: ::c_int = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 32; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86old: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_vm86: ::c_long = 166; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_set_thread_area: ::c_long = 243; +pub const SYS_get_thread_area: ::c_long = 244; +pub const SYS_io_setup: ::c_long = 245; +pub const SYS_io_destroy: ::c_long = 246; +pub const SYS_io_getevents: ::c_long = 247; +pub const SYS_io_submit: ::c_long = 248; +pub const SYS_io_cancel: ::c_long = 249; +pub const SYS_fadvise64: ::c_long = 250; +pub const SYS_exit_group: ::c_long = 252; +pub const SYS_lookup_dcookie: ::c_long = 253; +pub const SYS_epoll_create: ::c_long = 254; +pub const SYS_epoll_ctl: ::c_long = 255; +pub const SYS_epoll_wait: ::c_long = 256; +pub const SYS_remap_file_pages: ::c_long = 257; +pub const SYS_set_tid_address: ::c_long = 258; +pub const SYS_timer_create: ::c_long = 259; +pub const SYS_timer_settime: ::c_long = 260; +pub const SYS_timer_gettime: ::c_long = 261; +pub const SYS_timer_getoverrun: ::c_long = 262; +pub const SYS_timer_delete: ::c_long = 263; +pub const SYS_clock_settime: ::c_long = 264; +pub const SYS_clock_gettime: ::c_long = 265; +pub const SYS_clock_getres: ::c_long = 266; +pub const SYS_clock_nanosleep: ::c_long = 267; +pub const SYS_statfs64: ::c_long = 268; +pub const SYS_fstatfs64: ::c_long = 269; +pub const SYS_tgkill: ::c_long = 270; +pub const SYS_utimes: ::c_long = 271; +pub const SYS_fadvise64_64: ::c_long = 272; +pub const SYS_vserver: ::c_long = 273; +pub const SYS_mbind: ::c_long = 274; +pub const SYS_get_mempolicy: ::c_long = 275; +pub const SYS_set_mempolicy: ::c_long = 276; +pub const SYS_mq_open: ::c_long = 277; +pub const SYS_mq_unlink: ::c_long = 278; +pub const SYS_mq_timedsend: ::c_long = 279; +pub const SYS_mq_timedreceive: ::c_long = 280; +pub const SYS_mq_notify: ::c_long = 281; +pub const SYS_mq_getsetattr: ::c_long = 282; +pub const SYS_kexec_load: ::c_long = 283; +pub const SYS_waitid: ::c_long = 284; +pub const SYS_add_key: ::c_long = 286; +pub const SYS_request_key: ::c_long = 287; +pub const SYS_keyctl: ::c_long = 288; +pub const SYS_ioprio_set: ::c_long = 289; +pub const SYS_ioprio_get: ::c_long = 290; +pub const SYS_inotify_init: ::c_long = 291; +pub const SYS_inotify_add_watch: ::c_long = 292; +pub const SYS_inotify_rm_watch: ::c_long = 293; +pub const SYS_migrate_pages: ::c_long = 294; +pub const SYS_openat: ::c_long = 295; +pub const SYS_mkdirat: ::c_long = 296; +pub const SYS_mknodat: ::c_long = 297; +pub const SYS_fchownat: ::c_long = 298; +pub const SYS_futimesat: ::c_long = 299; +pub const SYS_fstatat64: ::c_long = 300; +pub const SYS_unlinkat: ::c_long = 301; +pub const SYS_renameat: ::c_long = 302; +pub const SYS_linkat: ::c_long = 303; +pub const SYS_symlinkat: ::c_long = 304; +pub const SYS_readlinkat: ::c_long = 305; +pub const SYS_fchmodat: ::c_long = 306; +pub const SYS_faccessat: ::c_long = 307; +pub const SYS_pselect6: ::c_long = 308; +pub const SYS_ppoll: ::c_long = 309; +pub const SYS_unshare: ::c_long = 310; +pub const SYS_set_robust_list: ::c_long = 311; +pub const SYS_get_robust_list: ::c_long = 312; +pub const SYS_splice: ::c_long = 313; +pub const SYS_sync_file_range: ::c_long = 314; +pub const SYS_tee: ::c_long = 315; +pub const SYS_vmsplice: ::c_long = 316; +pub const SYS_move_pages: ::c_long = 317; +pub const SYS_getcpu: ::c_long = 318; +pub const SYS_epoll_pwait: ::c_long = 319; +pub const SYS_utimensat: ::c_long = 320; +pub const SYS_signalfd: ::c_long = 321; +pub const SYS_timerfd_create: ::c_long = 322; +pub const SYS_eventfd: ::c_long = 323; +pub const SYS_fallocate: ::c_long = 324; +pub const SYS_timerfd_settime: ::c_long = 325; +pub const SYS_timerfd_gettime: ::c_long = 326; +pub const SYS_signalfd4: ::c_long = 327; +pub const SYS_eventfd2: ::c_long = 328; +pub const SYS_epoll_create1: ::c_long = 329; +pub const SYS_dup3: ::c_long = 330; +pub const SYS_pipe2: ::c_long = 331; +pub const SYS_inotify_init1: ::c_long = 332; +pub const SYS_preadv: ::c_long = 333; +pub const SYS_pwritev: ::c_long = 334; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 335; +pub const SYS_perf_event_open: ::c_long = 336; +pub const SYS_recvmmsg: ::c_long = 337; +pub const SYS_fanotify_init: ::c_long = 338; +pub const SYS_fanotify_mark: ::c_long = 339; +pub const SYS_prlimit64: ::c_long = 340; +pub const SYS_name_to_handle_at: ::c_long = 341; +pub const SYS_open_by_handle_at: ::c_long = 342; +pub const SYS_clock_adjtime: ::c_long = 343; +pub const SYS_syncfs: ::c_long = 344; +pub const SYS_sendmmsg: ::c_long = 345; +pub const SYS_setns: ::c_long = 346; +pub const SYS_process_vm_readv: ::c_long = 347; +pub const SYS_process_vm_writev: ::c_long = 348; +pub const SYS_kcmp: ::c_long = 349; +pub const SYS_finit_module: ::c_long = 350; +pub const SYS_sched_setattr: ::c_long = 351; +pub const SYS_sched_getattr: ::c_long = 352; +pub const SYS_renameat2: ::c_long = 353; +pub const SYS_seccomp: ::c_long = 354; +pub const SYS_getrandom: ::c_long = 355; +pub const SYS_memfd_create: ::c_long = 356; +pub const SYS_bpf: ::c_long = 357; +pub const SYS_execveat: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_userfaultfd: ::c_long = 374; +pub const SYS_membarrier: ::c_long = 375; +pub const SYS_mlock2: ::c_long = 376; +pub const SYS_copy_file_range: ::c_long = 377; +pub const SYS_preadv2: ::c_long = 378; +pub const SYS_pwritev2: ::c_long = 379; +pub const SYS_pkey_mprotect: ::c_long = 380; +pub const SYS_pkey_alloc: ::c_long = 381; +pub const SYS_pkey_free: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +// offsets in user_regs_structs, from sys/reg.h +pub const EBX: ::c_int = 0; +pub const ECX: ::c_int = 1; +pub const EDX: ::c_int = 2; +pub const ESI: ::c_int = 3; +pub const EDI: ::c_int = 4; +pub const EBP: ::c_int = 5; +pub const EAX: ::c_int = 6; +pub const DS: ::c_int = 7; +pub const ES: ::c_int = 8; +pub const FS: ::c_int = 9; +pub const GS: ::c_int = 10; +pub const ORIG_EAX: ::c_int = 11; +pub const EIP: ::c_int = 12; +pub const CS: ::c_int = 13; +pub const EFL: ::c_int = 14; +pub const UESP: ::c_int = 15; +pub const SS: ::c_int = 16; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs new file mode 100644 index 00000000..a4bf9bff --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs @@ -0,0 +1,42 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} + +s! { + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub fault_address: ::c_ulong, + pub regs: [::c_ulong; 31], + pub sp: ::c_ulong, + pub pc: ::c_ulong, + pub pstate: ::c_ulong, + __reserved: [[u64; 32]; 16], + } + + #[repr(align(8))] + pub struct clone_args { + pub flags: ::c_ulonglong, + pub pidfd: ::c_ulonglong, + pub child_tid: ::c_ulonglong, + pub parent_tid: ::c_ulonglong, + pub exit_signal: ::c_ulonglong, + pub stack: ::c_ulonglong, + pub stack_size: ::c_ulonglong, + pub tls: ::c_ulonglong, + pub set_tid: ::c_ulonglong, + pub set_tid_size: ::c_ulonglong, + pub cgroup: ::c_ulonglong, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs new file mode 100644 index 00000000..4535e73e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs @@ -0,0 +1,7 @@ +s! { + pub struct user_fpsimd_struct { + pub vregs: [::__uint128_t; 32], + pub fpsr: u32, + pub fpcr: u32, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs new file mode 100644 index 00000000..54e072b3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs @@ -0,0 +1,658 @@ +pub type c_char = u8; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; +pub type wchar_t = u32; +pub type nlink_t = u32; +pub type blksize_t = ::c_int; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_uint; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_uint; 2], + } + + pub struct user_regs_struct { + pub regs: [::c_ulonglong; 31], + pub sp: ::c_ulonglong, + pub pc: ::c_ulonglong, + pub pstate: ::c_ulonglong, + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } +} + +pub const O_APPEND: ::c_int = 1024; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_LARGEFILE: ::c_int = 0x20000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +// bits/hwcap.h +pub const HWCAP_FP: ::c_ulong = 1 << 0; +pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +pub const HWCAP_EVTSTRM: ::c_ulong = 1 << 2; +pub const HWCAP_AES: ::c_ulong = 1 << 3; +pub const HWCAP_PMULL: ::c_ulong = 1 << 4; +pub const HWCAP_SHA1: ::c_ulong = 1 << 5; +pub const HWCAP_SHA2: ::c_ulong = 1 << 6; +pub const HWCAP_CRC32: ::c_ulong = 1 << 7; +pub const HWCAP_ATOMICS: ::c_ulong = 1 << 8; +pub const HWCAP_FPHP: ::c_ulong = 1 << 9; +pub const HWCAP_ASIMDHP: ::c_ulong = 1 << 10; +pub const HWCAP_CPUID: ::c_ulong = 1 << 11; +pub const HWCAP_ASIMDRDM: ::c_ulong = 1 << 12; +pub const HWCAP_JSCVT: ::c_ulong = 1 << 13; +pub const HWCAP_FCMA: ::c_ulong = 1 << 14; +pub const HWCAP_LRCPC: ::c_ulong = 1 << 15; +pub const HWCAP_DCPOP: ::c_ulong = 1 << 16; +pub const HWCAP_SHA3: ::c_ulong = 1 << 17; +pub const HWCAP_SM3: ::c_ulong = 1 << 18; +pub const HWCAP_SM4: ::c_ulong = 1 << 19; +pub const HWCAP_ASIMDDP: ::c_ulong = 1 << 20; +pub const HWCAP_SHA512: ::c_ulong = 1 << 21; +pub const HWCAP_SVE: ::c_ulong = 1 << 22; +pub const HWCAP_ASIMDFHM: ::c_ulong = 1 << 23; +pub const HWCAP_DIT: ::c_ulong = 1 << 24; +pub const HWCAP_USCAT: ::c_ulong = 1 << 25; +pub const HWCAP_ILRCPC: ::c_ulong = 1 << 26; +pub const HWCAP_FLAGM: ::c_ulong = 1 << 27; +pub const HWCAP_SSBS: ::c_ulong = 1 << 28; +pub const HWCAP_SB: ::c_ulong = 1 << 29; +pub const HWCAP_PACA: ::c_ulong = 1 << 30; +pub const HWCAP_PACG: ::c_ulong = 1 << 31; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const MINSIGSTKSZ: ::size_t = 6144; +pub const SIGSTKSZ: ::size_t = 12288; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_dup: ::c_long = 23; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_flock: ::c_long = 32; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_renameat: ::c_long = 38; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_mount: ::c_long = 40; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_openat: ::c_long = 56; +pub const SYS_close: ::c_long = 57; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_sync: ::c_long = 81; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_acct: ::c_long = 89; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_personality: ::c_long = 92; +pub const SYS_exit: ::c_long = 93; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_futex: ::c_long = 98; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_kill: ::c_long = 129; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_times: ::c_long = 153; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_uname: ::c_long = 160; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_umask: ::c_long = 166; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_semop: ::c_long = 193; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_socket: ::c_long = 198; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_accept: ::c_long = 202; +pub const SYS_connect: ::c_long = 203; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_brk: ::c_long = 214; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_setns: ::c_long = 268; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const EDEADLK: ::c_int = 35; +pub const EDEADLOCK: ::c_int = EDEADLK; + +pub const EXTPROC: ::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} + +cfg_if! { + if #[cfg(libc_int128)] { + mod int128; + pub use self::int128::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs new file mode 100644 index 00000000..18fa6c66 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs @@ -0,0 +1,688 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; +pub type nlink_t = u64; +pub type blksize_t = i64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __pad1: [::c_int; 3], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: [::c_uint; 2], + pub st_size: ::off_t, + __pad3: ::c_int, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + __pad4: ::c_uint, + pub st_blocks: ::blkcnt_t, + __pad5: [::c_int; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad1: [::c_int; 3], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad2: [::c_uint; 2], + pub st_size: ::off_t, + __pad3: ::c_int, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + __pad4: ::c_uint, + pub st_blocks: ::blkcnt_t, + __pad5: [::c_int; 14], + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 5], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 5], + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __pad1: ::c_int, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const SYS_read: ::c_long = 5000 + 0; +pub const SYS_write: ::c_long = 5000 + 1; +pub const SYS_open: ::c_long = 5000 + 2; +pub const SYS_close: ::c_long = 5000 + 3; +pub const SYS_stat: ::c_long = 5000 + 4; +pub const SYS_fstat: ::c_long = 5000 + 5; +pub const SYS_lstat: ::c_long = 5000 + 6; +pub const SYS_poll: ::c_long = 5000 + 7; +pub const SYS_lseek: ::c_long = 5000 + 8; +pub const SYS_mmap: ::c_long = 5000 + 9; +pub const SYS_mprotect: ::c_long = 5000 + 10; +pub const SYS_munmap: ::c_long = 5000 + 11; +pub const SYS_brk: ::c_long = 5000 + 12; +pub const SYS_rt_sigaction: ::c_long = 5000 + 13; +pub const SYS_rt_sigprocmask: ::c_long = 5000 + 14; +pub const SYS_ioctl: ::c_long = 5000 + 15; +pub const SYS_pread64: ::c_long = 5000 + 16; +pub const SYS_pwrite64: ::c_long = 5000 + 17; +pub const SYS_readv: ::c_long = 5000 + 18; +pub const SYS_writev: ::c_long = 5000 + 19; +pub const SYS_access: ::c_long = 5000 + 20; +pub const SYS_pipe: ::c_long = 5000 + 21; +pub const SYS__newselect: ::c_long = 5000 + 22; +pub const SYS_sched_yield: ::c_long = 5000 + 23; +pub const SYS_mremap: ::c_long = 5000 + 24; +pub const SYS_msync: ::c_long = 5000 + 25; +pub const SYS_mincore: ::c_long = 5000 + 26; +pub const SYS_madvise: ::c_long = 5000 + 27; +pub const SYS_shmget: ::c_long = 5000 + 28; +pub const SYS_shmat: ::c_long = 5000 + 29; +pub const SYS_shmctl: ::c_long = 5000 + 30; +pub const SYS_dup: ::c_long = 5000 + 31; +pub const SYS_dup2: ::c_long = 5000 + 32; +pub const SYS_pause: ::c_long = 5000 + 33; +pub const SYS_nanosleep: ::c_long = 5000 + 34; +pub const SYS_getitimer: ::c_long = 5000 + 35; +pub const SYS_setitimer: ::c_long = 5000 + 36; +pub const SYS_alarm: ::c_long = 5000 + 37; +pub const SYS_getpid: ::c_long = 5000 + 38; +pub const SYS_sendfile: ::c_long = 5000 + 39; +pub const SYS_socket: ::c_long = 5000 + 40; +pub const SYS_connect: ::c_long = 5000 + 41; +pub const SYS_accept: ::c_long = 5000 + 42; +pub const SYS_sendto: ::c_long = 5000 + 43; +pub const SYS_recvfrom: ::c_long = 5000 + 44; +pub const SYS_sendmsg: ::c_long = 5000 + 45; +pub const SYS_recvmsg: ::c_long = 5000 + 46; +pub const SYS_shutdown: ::c_long = 5000 + 47; +pub const SYS_bind: ::c_long = 5000 + 48; +pub const SYS_listen: ::c_long = 5000 + 49; +pub const SYS_getsockname: ::c_long = 5000 + 50; +pub const SYS_getpeername: ::c_long = 5000 + 51; +pub const SYS_socketpair: ::c_long = 5000 + 52; +pub const SYS_setsockopt: ::c_long = 5000 + 53; +pub const SYS_getsockopt: ::c_long = 5000 + 54; +pub const SYS_clone: ::c_long = 5000 + 55; +pub const SYS_fork: ::c_long = 5000 + 56; +pub const SYS_execve: ::c_long = 5000 + 57; +pub const SYS_exit: ::c_long = 5000 + 58; +pub const SYS_wait4: ::c_long = 5000 + 59; +pub const SYS_kill: ::c_long = 5000 + 60; +pub const SYS_uname: ::c_long = 5000 + 61; +pub const SYS_semget: ::c_long = 5000 + 62; +pub const SYS_semop: ::c_long = 5000 + 63; +pub const SYS_semctl: ::c_long = 5000 + 64; +pub const SYS_shmdt: ::c_long = 5000 + 65; +pub const SYS_msgget: ::c_long = 5000 + 66; +pub const SYS_msgsnd: ::c_long = 5000 + 67; +pub const SYS_msgrcv: ::c_long = 5000 + 68; +pub const SYS_msgctl: ::c_long = 5000 + 69; +pub const SYS_fcntl: ::c_long = 5000 + 70; +pub const SYS_flock: ::c_long = 5000 + 71; +pub const SYS_fsync: ::c_long = 5000 + 72; +pub const SYS_fdatasync: ::c_long = 5000 + 73; +pub const SYS_truncate: ::c_long = 5000 + 74; +pub const SYS_ftruncate: ::c_long = 5000 + 75; +pub const SYS_getdents: ::c_long = 5000 + 76; +pub const SYS_getcwd: ::c_long = 5000 + 77; +pub const SYS_chdir: ::c_long = 5000 + 78; +pub const SYS_fchdir: ::c_long = 5000 + 79; +pub const SYS_rename: ::c_long = 5000 + 80; +pub const SYS_mkdir: ::c_long = 5000 + 81; +pub const SYS_rmdir: ::c_long = 5000 + 82; +pub const SYS_creat: ::c_long = 5000 + 83; +pub const SYS_link: ::c_long = 5000 + 84; +pub const SYS_unlink: ::c_long = 5000 + 85; +pub const SYS_symlink: ::c_long = 5000 + 86; +pub const SYS_readlink: ::c_long = 5000 + 87; +pub const SYS_chmod: ::c_long = 5000 + 88; +pub const SYS_fchmod: ::c_long = 5000 + 89; +pub const SYS_chown: ::c_long = 5000 + 90; +pub const SYS_fchown: ::c_long = 5000 + 91; +pub const SYS_lchown: ::c_long = 5000 + 92; +pub const SYS_umask: ::c_long = 5000 + 93; +pub const SYS_gettimeofday: ::c_long = 5000 + 94; +pub const SYS_getrlimit: ::c_long = 5000 + 95; +pub const SYS_getrusage: ::c_long = 5000 + 96; +pub const SYS_sysinfo: ::c_long = 5000 + 97; +pub const SYS_times: ::c_long = 5000 + 98; +pub const SYS_ptrace: ::c_long = 5000 + 99; +pub const SYS_getuid: ::c_long = 5000 + 100; +pub const SYS_syslog: ::c_long = 5000 + 101; +pub const SYS_getgid: ::c_long = 5000 + 102; +pub const SYS_setuid: ::c_long = 5000 + 103; +pub const SYS_setgid: ::c_long = 5000 + 104; +pub const SYS_geteuid: ::c_long = 5000 + 105; +pub const SYS_getegid: ::c_long = 5000 + 106; +pub const SYS_setpgid: ::c_long = 5000 + 107; +pub const SYS_getppid: ::c_long = 5000 + 108; +pub const SYS_getpgrp: ::c_long = 5000 + 109; +pub const SYS_setsid: ::c_long = 5000 + 110; +pub const SYS_setreuid: ::c_long = 5000 + 111; +pub const SYS_setregid: ::c_long = 5000 + 112; +pub const SYS_getgroups: ::c_long = 5000 + 113; +pub const SYS_setgroups: ::c_long = 5000 + 114; +pub const SYS_setresuid: ::c_long = 5000 + 115; +pub const SYS_getresuid: ::c_long = 5000 + 116; +pub const SYS_setresgid: ::c_long = 5000 + 117; +pub const SYS_getresgid: ::c_long = 5000 + 118; +pub const SYS_getpgid: ::c_long = 5000 + 119; +pub const SYS_setfsuid: ::c_long = 5000 + 120; +pub const SYS_setfsgid: ::c_long = 5000 + 121; +pub const SYS_getsid: ::c_long = 5000 + 122; +pub const SYS_capget: ::c_long = 5000 + 123; +pub const SYS_capset: ::c_long = 5000 + 124; +pub const SYS_rt_sigpending: ::c_long = 5000 + 125; +pub const SYS_rt_sigtimedwait: ::c_long = 5000 + 126; +pub const SYS_rt_sigqueueinfo: ::c_long = 5000 + 127; +pub const SYS_rt_sigsuspend: ::c_long = 5000 + 128; +pub const SYS_sigaltstack: ::c_long = 5000 + 129; +pub const SYS_utime: ::c_long = 5000 + 130; +pub const SYS_mknod: ::c_long = 5000 + 131; +pub const SYS_personality: ::c_long = 5000 + 132; +pub const SYS_ustat: ::c_long = 5000 + 133; +pub const SYS_statfs: ::c_long = 5000 + 134; +pub const SYS_fstatfs: ::c_long = 5000 + 135; +pub const SYS_sysfs: ::c_long = 5000 + 136; +pub const SYS_getpriority: ::c_long = 5000 + 137; +pub const SYS_setpriority: ::c_long = 5000 + 138; +pub const SYS_sched_setparam: ::c_long = 5000 + 139; +pub const SYS_sched_getparam: ::c_long = 5000 + 140; +pub const SYS_sched_setscheduler: ::c_long = 5000 + 141; +pub const SYS_sched_getscheduler: ::c_long = 5000 + 142; +pub const SYS_sched_get_priority_max: ::c_long = 5000 + 143; +pub const SYS_sched_get_priority_min: ::c_long = 5000 + 144; +pub const SYS_sched_rr_get_interval: ::c_long = 5000 + 145; +pub const SYS_mlock: ::c_long = 5000 + 146; +pub const SYS_munlock: ::c_long = 5000 + 147; +pub const SYS_mlockall: ::c_long = 5000 + 148; +pub const SYS_munlockall: ::c_long = 5000 + 149; +pub const SYS_vhangup: ::c_long = 5000 + 150; +pub const SYS_pivot_root: ::c_long = 5000 + 151; +pub const SYS__sysctl: ::c_long = 5000 + 152; +pub const SYS_prctl: ::c_long = 5000 + 153; +pub const SYS_adjtimex: ::c_long = 5000 + 154; +pub const SYS_setrlimit: ::c_long = 5000 + 155; +pub const SYS_chroot: ::c_long = 5000 + 156; +pub const SYS_sync: ::c_long = 5000 + 157; +pub const SYS_acct: ::c_long = 5000 + 158; +pub const SYS_settimeofday: ::c_long = 5000 + 159; +pub const SYS_mount: ::c_long = 5000 + 160; +pub const SYS_umount2: ::c_long = 5000 + 161; +pub const SYS_swapon: ::c_long = 5000 + 162; +pub const SYS_swapoff: ::c_long = 5000 + 163; +pub const SYS_reboot: ::c_long = 5000 + 164; +pub const SYS_sethostname: ::c_long = 5000 + 165; +pub const SYS_setdomainname: ::c_long = 5000 + 166; +pub const SYS_create_module: ::c_long = 5000 + 167; +pub const SYS_init_module: ::c_long = 5000 + 168; +pub const SYS_delete_module: ::c_long = 5000 + 169; +pub const SYS_get_kernel_syms: ::c_long = 5000 + 170; +pub const SYS_query_module: ::c_long = 5000 + 171; +pub const SYS_quotactl: ::c_long = 5000 + 172; +pub const SYS_nfsservctl: ::c_long = 5000 + 173; +pub const SYS_getpmsg: ::c_long = 5000 + 174; +pub const SYS_putpmsg: ::c_long = 5000 + 175; +pub const SYS_afs_syscall: ::c_long = 5000 + 176; +pub const SYS_gettid: ::c_long = 5000 + 178; +pub const SYS_readahead: ::c_long = 5000 + 179; +pub const SYS_setxattr: ::c_long = 5000 + 180; +pub const SYS_lsetxattr: ::c_long = 5000 + 181; +pub const SYS_fsetxattr: ::c_long = 5000 + 182; +pub const SYS_getxattr: ::c_long = 5000 + 183; +pub const SYS_lgetxattr: ::c_long = 5000 + 184; +pub const SYS_fgetxattr: ::c_long = 5000 + 185; +pub const SYS_listxattr: ::c_long = 5000 + 186; +pub const SYS_llistxattr: ::c_long = 5000 + 187; +pub const SYS_flistxattr: ::c_long = 5000 + 188; +pub const SYS_removexattr: ::c_long = 5000 + 189; +pub const SYS_lremovexattr: ::c_long = 5000 + 190; +pub const SYS_fremovexattr: ::c_long = 5000 + 191; +pub const SYS_tkill: ::c_long = 5000 + 192; +pub const SYS_futex: ::c_long = 5000 + 194; +pub const SYS_sched_setaffinity: ::c_long = 5000 + 195; +pub const SYS_sched_getaffinity: ::c_long = 5000 + 196; +pub const SYS_cacheflush: ::c_long = 5000 + 197; +pub const SYS_cachectl: ::c_long = 5000 + 198; +pub const SYS_sysmips: ::c_long = 5000 + 199; +pub const SYS_io_setup: ::c_long = 5000 + 200; +pub const SYS_io_destroy: ::c_long = 5000 + 201; +pub const SYS_io_getevents: ::c_long = 5000 + 202; +pub const SYS_io_submit: ::c_long = 5000 + 203; +pub const SYS_io_cancel: ::c_long = 5000 + 204; +pub const SYS_exit_group: ::c_long = 5000 + 205; +pub const SYS_lookup_dcookie: ::c_long = 5000 + 206; +pub const SYS_epoll_create: ::c_long = 5000 + 207; +pub const SYS_epoll_ctl: ::c_long = 5000 + 208; +pub const SYS_epoll_wait: ::c_long = 5000 + 209; +pub const SYS_remap_file_pages: ::c_long = 5000 + 210; +pub const SYS_rt_sigreturn: ::c_long = 5000 + 211; +pub const SYS_set_tid_address: ::c_long = 5000 + 212; +pub const SYS_restart_syscall: ::c_long = 5000 + 213; +pub const SYS_semtimedop: ::c_long = 5000 + 214; +pub const SYS_fadvise64: ::c_long = 5000 + 215; +pub const SYS_timer_create: ::c_long = 5000 + 216; +pub const SYS_timer_settime: ::c_long = 5000 + 217; +pub const SYS_timer_gettime: ::c_long = 5000 + 218; +pub const SYS_timer_getoverrun: ::c_long = 5000 + 219; +pub const SYS_timer_delete: ::c_long = 5000 + 220; +pub const SYS_clock_settime: ::c_long = 5000 + 221; +pub const SYS_clock_gettime: ::c_long = 5000 + 222; +pub const SYS_clock_getres: ::c_long = 5000 + 223; +pub const SYS_clock_nanosleep: ::c_long = 5000 + 224; +pub const SYS_tgkill: ::c_long = 5000 + 225; +pub const SYS_utimes: ::c_long = 5000 + 226; +pub const SYS_mbind: ::c_long = 5000 + 227; +pub const SYS_get_mempolicy: ::c_long = 5000 + 228; +pub const SYS_set_mempolicy: ::c_long = 5000 + 229; +pub const SYS_mq_open: ::c_long = 5000 + 230; +pub const SYS_mq_unlink: ::c_long = 5000 + 231; +pub const SYS_mq_timedsend: ::c_long = 5000 + 232; +pub const SYS_mq_timedreceive: ::c_long = 5000 + 233; +pub const SYS_mq_notify: ::c_long = 5000 + 234; +pub const SYS_mq_getsetattr: ::c_long = 5000 + 235; +pub const SYS_vserver: ::c_long = 5000 + 236; +pub const SYS_waitid: ::c_long = 5000 + 237; +/* pub const SYS_sys_setaltroot: ::c_long = 5000 + 238; */ +pub const SYS_add_key: ::c_long = 5000 + 239; +pub const SYS_request_key: ::c_long = 5000 + 240; +pub const SYS_keyctl: ::c_long = 5000 + 241; +pub const SYS_set_thread_area: ::c_long = 5000 + 242; +pub const SYS_inotify_init: ::c_long = 5000 + 243; +pub const SYS_inotify_add_watch: ::c_long = 5000 + 244; +pub const SYS_inotify_rm_watch: ::c_long = 5000 + 245; +pub const SYS_migrate_pages: ::c_long = 5000 + 246; +pub const SYS_openat: ::c_long = 5000 + 247; +pub const SYS_mkdirat: ::c_long = 5000 + 248; +pub const SYS_mknodat: ::c_long = 5000 + 249; +pub const SYS_fchownat: ::c_long = 5000 + 250; +pub const SYS_futimesat: ::c_long = 5000 + 251; +pub const SYS_newfstatat: ::c_long = 5000 + 252; +pub const SYS_unlinkat: ::c_long = 5000 + 253; +pub const SYS_renameat: ::c_long = 5000 + 254; +pub const SYS_linkat: ::c_long = 5000 + 255; +pub const SYS_symlinkat: ::c_long = 5000 + 256; +pub const SYS_readlinkat: ::c_long = 5000 + 257; +pub const SYS_fchmodat: ::c_long = 5000 + 258; +pub const SYS_faccessat: ::c_long = 5000 + 259; +pub const SYS_pselect6: ::c_long = 5000 + 260; +pub const SYS_ppoll: ::c_long = 5000 + 261; +pub const SYS_unshare: ::c_long = 5000 + 262; +pub const SYS_splice: ::c_long = 5000 + 263; +pub const SYS_sync_file_range: ::c_long = 5000 + 264; +pub const SYS_tee: ::c_long = 5000 + 265; +pub const SYS_vmsplice: ::c_long = 5000 + 266; +pub const SYS_move_pages: ::c_long = 5000 + 267; +pub const SYS_set_robust_list: ::c_long = 5000 + 268; +pub const SYS_get_robust_list: ::c_long = 5000 + 269; +pub const SYS_kexec_load: ::c_long = 5000 + 270; +pub const SYS_getcpu: ::c_long = 5000 + 271; +pub const SYS_epoll_pwait: ::c_long = 5000 + 272; +pub const SYS_ioprio_set: ::c_long = 5000 + 273; +pub const SYS_ioprio_get: ::c_long = 5000 + 274; +pub const SYS_utimensat: ::c_long = 5000 + 275; +pub const SYS_signalfd: ::c_long = 5000 + 276; +pub const SYS_timerfd: ::c_long = 5000 + 277; +pub const SYS_eventfd: ::c_long = 5000 + 278; +pub const SYS_fallocate: ::c_long = 5000 + 279; +pub const SYS_timerfd_create: ::c_long = 5000 + 280; +pub const SYS_timerfd_gettime: ::c_long = 5000 + 281; +pub const SYS_timerfd_settime: ::c_long = 5000 + 282; +pub const SYS_signalfd4: ::c_long = 5000 + 283; +pub const SYS_eventfd2: ::c_long = 5000 + 284; +pub const SYS_epoll_create1: ::c_long = 5000 + 285; +pub const SYS_dup3: ::c_long = 5000 + 286; +pub const SYS_pipe2: ::c_long = 5000 + 287; +pub const SYS_inotify_init1: ::c_long = 5000 + 288; +pub const SYS_preadv: ::c_long = 5000 + 289; +pub const SYS_pwritev: ::c_long = 5000 + 290; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 5000 + 291; +pub const SYS_perf_event_open: ::c_long = 5000 + 292; +pub const SYS_accept4: ::c_long = 5000 + 293; +pub const SYS_recvmmsg: ::c_long = 5000 + 294; +pub const SYS_fanotify_init: ::c_long = 5000 + 295; +pub const SYS_fanotify_mark: ::c_long = 5000 + 296; +pub const SYS_prlimit64: ::c_long = 5000 + 297; +pub const SYS_name_to_handle_at: ::c_long = 5000 + 298; +pub const SYS_open_by_handle_at: ::c_long = 5000 + 299; +pub const SYS_clock_adjtime: ::c_long = 5000 + 300; +pub const SYS_syncfs: ::c_long = 5000 + 301; +pub const SYS_sendmmsg: ::c_long = 5000 + 302; +pub const SYS_setns: ::c_long = 5000 + 303; +pub const SYS_process_vm_readv: ::c_long = 5000 + 304; +pub const SYS_process_vm_writev: ::c_long = 5000 + 305; +pub const SYS_kcmp: ::c_long = 5000 + 306; +pub const SYS_finit_module: ::c_long = 5000 + 307; +pub const SYS_getdents64: ::c_long = 5000 + 308; +pub const SYS_sched_setattr: ::c_long = 5000 + 309; +pub const SYS_sched_getattr: ::c_long = 5000 + 310; +pub const SYS_renameat2: ::c_long = 5000 + 311; +pub const SYS_seccomp: ::c_long = 5000 + 312; +pub const SYS_getrandom: ::c_long = 5000 + 313; +pub const SYS_memfd_create: ::c_long = 5000 + 314; +pub const SYS_bpf: ::c_long = 5000 + 315; +pub const SYS_execveat: ::c_long = 5000 + 316; +pub const SYS_userfaultfd: ::c_long = 5000 + 317; +pub const SYS_membarrier: ::c_long = 5000 + 318; +pub const SYS_mlock2: ::c_long = 5000 + 319; +pub const SYS_copy_file_range: ::c_long = 5000 + 320; +pub const SYS_preadv2: ::c_long = 5000 + 321; +pub const SYS_pwritev2: ::c_long = 5000 + 322; +pub const SYS_pkey_mprotect: ::c_long = 5000 + 323; +pub const SYS_pkey_alloc: ::c_long = 5000 + 324; +pub const SYS_pkey_free: ::c_long = 5000 + 325; +pub const SYS_statx: ::c_long = 5000 + 326; +pub const SYS_pidfd_send_signal: ::c_long = 5000 + 424; +pub const SYS_io_uring_setup: ::c_long = 5000 + 425; +pub const SYS_io_uring_enter: ::c_long = 5000 + 426; +pub const SYS_io_uring_register: ::c_long = 5000 + 427; +pub const SYS_open_tree: ::c_long = 5000 + 428; +pub const SYS_move_mount: ::c_long = 5000 + 429; +pub const SYS_fsopen: ::c_long = 5000 + 430; +pub const SYS_fsconfig: ::c_long = 5000 + 431; +pub const SYS_fsmount: ::c_long = 5000 + 432; +pub const SYS_fspick: ::c_long = 5000 + 433; +pub const SYS_pidfd_open: ::c_long = 5000 + 434; +pub const SYS_clone3: ::c_long = 5000 + 435; +pub const SYS_close_range: ::c_long = 5000 + 436; +pub const SYS_openat2: ::c_long = 5000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 5000 + 438; +pub const SYS_faccessat2: ::c_long = 5000 + 439; +pub const SYS_process_madvise: ::c_long = 5000 + 440; +pub const SYS_epoll_pwait2: ::c_long = 5000 + 441; +pub const SYS_mount_setattr: ::c_long = 5000 + 442; +pub const SYS_quotactl_fd: ::c_long = 5000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 5000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 5000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 5000 + 446; +pub const SYS_memfd_secret: ::c_long = 5000 + 447; +pub const SYS_process_mrelease: ::c_long = 5000 + 448; +pub const SYS_futex_waitv: ::c_long = 5000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 5000 + 450; + +pub const O_DIRECT: ::c_int = 0x8000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x4010; +pub const O_RSYNC: ::c_int = 0x4010; +pub const O_DSYNC: ::c_int = 0x10; +pub const O_ASYNC: ::c_int = 0x1000; +pub const O_LARGEFILE: ::c_int = 0x2000; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_POPULATE: ::c_int = 0x10000; +pub const MAP_NONBLOCK: ::c_int = 0x20000; +pub const MAP_STACK: ::c_int = 0x40000; +pub const MAP_HUGETLB: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGWINCH: ::c_int = 20; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGCONT: ::c_int = 25; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGURG: ::c_int = 21; +pub const SIGIO: ::c_int = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 22; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const EXTPROC: ::tcflag_t = 0o200000; + +pub const F_GETLK: ::c_int = 14; +pub const F_GETOWN: ::c_int = 23; +pub const F_SETOWN: ::c_int = 24; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const EHWPOISON: ::c_int = 168; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs new file mode 100644 index 00000000..05586cdb --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs @@ -0,0 +1,163 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type regoff_t = ::c_long; + +s! { + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct pthread_attr_t { + __size: [u64; 7] + } + + pub struct sigset_t { + __val: [::c_ulong; 16], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + #[cfg(target_endian = "big")] + __pad1: ::c_int, + pub msg_iovlen: ::c_int, + #[cfg(target_endian = "little")] + __pad1: ::c_int, + pub msg_control: *mut ::c_void, + #[cfg(target_endian = "big")] + __pad2: ::c_int, + pub msg_controllen: ::socklen_t, + #[cfg(target_endian = "little")] + __pad2: ::c_int, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + #[cfg(target_endian = "big")] + pub __pad1: ::c_int, + pub cmsg_len: ::socklen_t, + #[cfg(target_endian = "little")] + pub __pad1: ::c_int, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 8], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } +} + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "mips64")] { + mod mips64; + pub use self::mips64::*; + } else if #[cfg(any(target_arch = "powerpc64"))] { + mod powerpc64; + pub use self::powerpc64::*; + } else if #[cfg(any(target_arch = "s390x"))] { + mod s390x; + pub use self::s390x::*; + } else if #[cfg(any(target_arch = "x86_64"))] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(any(target_arch = "riscv64"))] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs new file mode 100644 index 00000000..202abe87 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs @@ -0,0 +1,695 @@ +pub type c_char = u8; +pub type wchar_t = i32; +pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; +pub type nlink_t = u64; +pub type blksize_t = ::c_long; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 3], + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_32BIT: ::c_int = 0x0040; +pub const O_APPEND: ::c_int = 1024; +pub const O_DIRECT: ::c_int = 0x20000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_LARGEFILE: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const PTRACE_SYSEMU: ::c_int = 0x1d; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 0x1e; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const SIGSTKSZ: ::size_t = 10240; +pub const MINSIGSTKSZ: ::size_t = 4096; + +// Syscall table +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_waitpid: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sgetmask: ::c_long = 68; +pub const SYS_ssetmask: ::c_long = 69; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrlimit: ::c_long = 76; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::c_long = 84; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; /* some people actually want streams */ +pub const SYS_putpmsg: ::c_long = 188; /* some people actually want streams */ +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; /* SuS compliant getrlimit */ +pub const SYS_readahead: ::c_long = 191; +pub const SYS_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_newfstatat: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +pub const SYS_preadv2: ::c_long = 380; +pub const SYS_pwritev2: ::c_long = 381; +pub const SYS_kexec_file_load: ::c_long = 382; +pub const SYS_statx: ::c_long = 383; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +pub const EDEADLK: ::c_int = 58; +pub const EDEADLOCK: ::c_int = EDEADLK; + +pub const EXTPROC: ::tcflag_t = 0x10000000; +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: ::tcflag_t = 0x00000400; +pub const TOSTOP: ::tcflag_t = 0x00400000; +pub const FLUSHO: ::tcflag_t = 0x00800000; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; +pub const CBAUD: ::tcflag_t = 0xff; +pub const TAB1: ::c_int = 0x400; +pub const TAB2: ::c_int = 0x800; +pub const TAB3: ::c_int = 0xc00; +pub const CR1: ::c_int = 0x1000; +pub const CR2: ::c_int = 0x2000; +pub const CR3: ::c_int = 0x3000; +pub const FF1: ::c_int = 0x4000; +pub const BS1: ::c_int = 0x8000; +pub const VT1: ::c_int = 0x10000; +pub const VWERASE: usize = 10; +pub const VREPRINT: usize = 11; +pub const VSUSP: usize = 12; +pub const VSTART: usize = 13; +pub const VSTOP: usize = 14; +pub const VDISCARD: usize = 16; +pub const VTIME: usize = 7; +pub const IXON: ::tcflag_t = 0x00000200; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const ONLCR: ::tcflag_t = 0x2; +pub const CSIZE: ::tcflag_t = 0x00000300; + +pub const CS6: ::tcflag_t = 0x00000100; +pub const CS7: ::tcflag_t = 0x00000200; +pub const CS8: ::tcflag_t = 0x00000300; +pub const CSTOPB: ::tcflag_t = 0x00000400; +pub const CREAD: ::tcflag_t = 0x00000800; +pub const PARENB: ::tcflag_t = 0x00001000; +pub const PARODD: ::tcflag_t = 0x00002000; +pub const HUPCL: ::tcflag_t = 0x00004000; +pub const CLOCAL: ::tcflag_t = 0x00008000; +pub const ECHOKE: ::tcflag_t = 0x00000001; +pub const ECHOE: ::tcflag_t = 0x00000002; +pub const ECHOK: ::tcflag_t = 0x00000004; +pub const ECHONL: ::tcflag_t = 0x00000010; +pub const ECHOPRT: ::tcflag_t = 0x00000020; +pub const ECHOCTL: ::tcflag_t = 0x00000040; +pub const ISIG: ::tcflag_t = 0x00000080; +pub const ICANON: ::tcflag_t = 0x00000100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; + +pub const CIBAUD: ::tcflag_t = 0o77600000; +pub const CBAUDEX: ::tcflag_t = 0o0000020; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o0001400; +pub const CRDLY: ::tcflag_t = 0o0030000; +pub const TABDLY: ::tcflag_t = 0o0006000; +pub const BSDLY: ::tcflag_t = 0o0100000; +pub const FFDLY: ::tcflag_t = 0o0040000; +pub const VTDLY: ::tcflag_t = 0o0200000; +pub const XTABS: ::tcflag_t = 0o00006000; + +pub const B57600: ::speed_t = 0o00020; +pub const B115200: ::speed_t = 0o00021; +pub const B230400: ::speed_t = 0o00022; +pub const B460800: ::speed_t = 0o00023; +pub const B500000: ::speed_t = 0o00024; +pub const B576000: ::speed_t = 0o00025; +pub const B921600: ::speed_t = 0o00026; +pub const B1000000: ::speed_t = 0o00027; +pub const B1152000: ::speed_t = 0o00030; +pub const B1500000: ::speed_t = 0o00031; +pub const B2000000: ::speed_t = 0o00032; +pub const B2500000: ::speed_t = 0o00033; +pub const B3000000: ::speed_t = 0o00034; +pub const B3500000: ::speed_t = 0o00035; +pub const B4000000: ::speed_t = 0o00036; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs new file mode 100644 index 00000000..48d152a5 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs @@ -0,0 +1,44 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct ucontext_t { + pub __uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_sigmask: ::sigset_t, + pub uc_mcontext: mcontext_t, + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct mcontext_t { + pub __gregs: [::c_ulong; 32], + pub __fpregs: __riscv_mc_fp_state, + } + + #[allow(missing_debug_implementations)] + pub union __riscv_mc_fp_state { + pub __f: __riscv_mc_f_ext_state, + pub __d: __riscv_mc_d_ext_state, + pub __q: __riscv_mc_q_ext_state, + } + + #[allow(missing_debug_implementations)] + pub struct __riscv_mc_f_ext_state { + pub __f: [::c_uint; 32], + pub __fcsr: ::c_uint, + } + + #[allow(missing_debug_implementations)] + pub struct __riscv_mc_d_ext_state { + pub __f: [::c_ulonglong; 32], + pub __fcsr: ::c_uint, + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct __riscv_mc_q_ext_state { + pub __f: [::c_ulonglong; 64], + pub __fcsr: ::c_uint, + pub __glibc_reserved: [::c_uint; 3], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs new file mode 100644 index 00000000..393f54d3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs @@ -0,0 +1,727 @@ +//! RISC-V-specific definitions for 64-bit linux-like values + +pub type c_char = u8; +pub type wchar_t = ::c_int; + +pub type nlink_t = ::c_uint; +pub type blksize_t = ::c_int; +pub type fsblkcnt64_t = ::c_ulong; +pub type fsfilcnt64_t = ::c_ulong; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct pthread_attr_t { + __size: [::c_ulong; 7], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2usize], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub __pad1: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub __pad2: ::c_int, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_int; 2], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_frsize: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_favail: ::fsfilcnt64_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + #[doc(hidden)] + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] + pub _pad: [::c_int; 29], + _align: [u64; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused5: ::c_ulong, + __unused6: ::c_ulong, + } +} + +pub const SYS_read: ::c_long = 63; +pub const SYS_write: ::c_long = 64; +pub const SYS_close: ::c_long = 57; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_lseek: ::c_long = 62; +pub const SYS_mmap: ::c_long = 222; +pub const SYS_mprotect: ::c_long = 226; +pub const SYS_munmap: ::c_long = 215; +pub const SYS_brk: ::c_long = 214; +pub const SYS_rt_sigaction: ::c_long = 134; +pub const SYS_rt_sigprocmask: ::c_long = 135; +pub const SYS_rt_sigreturn: ::c_long = 139; +pub const SYS_ioctl: ::c_long = 29; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_readv: ::c_long = 65; +pub const SYS_writev: ::c_long = 66; +pub const SYS_sched_yield: ::c_long = 124; +pub const SYS_mremap: ::c_long = 216; +pub const SYS_msync: ::c_long = 227; +pub const SYS_mincore: ::c_long = 232; +pub const SYS_madvise: ::c_long = 233; +pub const SYS_shmget: ::c_long = 194; +pub const SYS_shmat: ::c_long = 196; +pub const SYS_shmctl: ::c_long = 195; +pub const SYS_dup: ::c_long = 23; +pub const SYS_nanosleep: ::c_long = 101; +pub const SYS_getitimer: ::c_long = 102; +pub const SYS_setitimer: ::c_long = 103; +pub const SYS_getpid: ::c_long = 172; +pub const SYS_sendfile: ::c_long = 71; +pub const SYS_socket: ::c_long = 198; +pub const SYS_connect: ::c_long = 203; +pub const SYS_accept: ::c_long = 202; +pub const SYS_sendto: ::c_long = 206; +pub const SYS_recvfrom: ::c_long = 207; +pub const SYS_sendmsg: ::c_long = 211; +pub const SYS_recvmsg: ::c_long = 212; +pub const SYS_shutdown: ::c_long = 210; +pub const SYS_bind: ::c_long = 200; +pub const SYS_listen: ::c_long = 201; +pub const SYS_getsockname: ::c_long = 204; +pub const SYS_getpeername: ::c_long = 205; +pub const SYS_socketpair: ::c_long = 199; +pub const SYS_setsockopt: ::c_long = 208; +pub const SYS_getsockopt: ::c_long = 209; +pub const SYS_clone: ::c_long = 220; +pub const SYS_execve: ::c_long = 221; +pub const SYS_exit: ::c_long = 93; +pub const SYS_wait4: ::c_long = 260; +pub const SYS_kill: ::c_long = 129; +pub const SYS_uname: ::c_long = 160; +pub const SYS_semget: ::c_long = 190; +pub const SYS_semop: ::c_long = 193; +pub const SYS_semctl: ::c_long = 191; +pub const SYS_shmdt: ::c_long = 197; +pub const SYS_msgget: ::c_long = 186; +pub const SYS_msgsnd: ::c_long = 189; +pub const SYS_msgrcv: ::c_long = 188; +pub const SYS_msgctl: ::c_long = 187; +pub const SYS_fcntl: ::c_long = 25; +pub const SYS_flock: ::c_long = 32; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +pub const SYS_truncate: ::c_long = 45; +pub const SYS_ftruncate: ::c_long = 46; +pub const SYS_getcwd: ::c_long = 17; +pub const SYS_chdir: ::c_long = 49; +pub const SYS_fchdir: ::c_long = 50; +pub const SYS_fchmod: ::c_long = 52; +pub const SYS_fchown: ::c_long = 55; +pub const SYS_umask: ::c_long = 166; +pub const SYS_gettimeofday: ::c_long = 169; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_getrusage: ::c_long = 165; +pub const SYS_sysinfo: ::c_long = 179; +pub const SYS_times: ::c_long = 153; +pub const SYS_ptrace: ::c_long = 117; +pub const SYS_getuid: ::c_long = 174; +pub const SYS_syslog: ::c_long = 116; +pub const SYS_getgid: ::c_long = 176; +pub const SYS_setuid: ::c_long = 146; +pub const SYS_setgid: ::c_long = 144; +pub const SYS_geteuid: ::c_long = 175; +pub const SYS_getegid: ::c_long = 177; +pub const SYS_setpgid: ::c_long = 154; +pub const SYS_getppid: ::c_long = 173; +pub const SYS_setsid: ::c_long = 157; +pub const SYS_setreuid: ::c_long = 145; +pub const SYS_setregid: ::c_long = 143; +pub const SYS_getgroups: ::c_long = 158; +pub const SYS_setgroups: ::c_long = 159; +pub const SYS_setresuid: ::c_long = 147; +pub const SYS_getresuid: ::c_long = 148; +pub const SYS_setresgid: ::c_long = 149; +pub const SYS_getresgid: ::c_long = 150; +pub const SYS_getpgid: ::c_long = 155; +pub const SYS_setfsuid: ::c_long = 151; +pub const SYS_setfsgid: ::c_long = 152; +pub const SYS_getsid: ::c_long = 156; +pub const SYS_capget: ::c_long = 90; +pub const SYS_capset: ::c_long = 91; +pub const SYS_rt_sigpending: ::c_long = 136; +pub const SYS_rt_sigtimedwait: ::c_long = 137; +pub const SYS_rt_sigqueueinfo: ::c_long = 138; +pub const SYS_rt_sigsuspend: ::c_long = 133; +pub const SYS_sigaltstack: ::c_long = 132; +pub const SYS_personality: ::c_long = 92; +pub const SYS_statfs: ::c_long = 43; +pub const SYS_fstatfs: ::c_long = 44; +pub const SYS_getpriority: ::c_long = 141; +pub const SYS_setpriority: ::c_long = 140; +pub const SYS_sched_setparam: ::c_long = 118; +pub const SYS_sched_getparam: ::c_long = 121; +pub const SYS_sched_setscheduler: ::c_long = 119; +pub const SYS_sched_getscheduler: ::c_long = 120; +pub const SYS_sched_get_priority_max: ::c_long = 125; +pub const SYS_sched_get_priority_min: ::c_long = 126; +pub const SYS_sched_rr_get_interval: ::c_long = 127; +pub const SYS_mlock: ::c_long = 228; +pub const SYS_munlock: ::c_long = 229; +pub const SYS_mlockall: ::c_long = 230; +pub const SYS_munlockall: ::c_long = 231; +pub const SYS_vhangup: ::c_long = 58; +pub const SYS_pivot_root: ::c_long = 41; +pub const SYS_prctl: ::c_long = 167; +pub const SYS_adjtimex: ::c_long = 171; +pub const SYS_setrlimit: ::c_long = 164; +pub const SYS_chroot: ::c_long = 51; +pub const SYS_sync: ::c_long = 81; +pub const SYS_acct: ::c_long = 89; +pub const SYS_settimeofday: ::c_long = 170; +pub const SYS_mount: ::c_long = 40; +pub const SYS_umount2: ::c_long = 39; +pub const SYS_swapon: ::c_long = 224; +pub const SYS_swapoff: ::c_long = 225; +pub const SYS_reboot: ::c_long = 142; +pub const SYS_sethostname: ::c_long = 161; +pub const SYS_setdomainname: ::c_long = 162; +pub const SYS_init_module: ::c_long = 105; +pub const SYS_delete_module: ::c_long = 106; +pub const SYS_quotactl: ::c_long = 60; +pub const SYS_nfsservctl: ::c_long = 42; +pub const SYS_gettid: ::c_long = 178; +pub const SYS_readahead: ::c_long = 213; +pub const SYS_setxattr: ::c_long = 5; +pub const SYS_lsetxattr: ::c_long = 6; +pub const SYS_fsetxattr: ::c_long = 7; +pub const SYS_getxattr: ::c_long = 8; +pub const SYS_lgetxattr: ::c_long = 9; +pub const SYS_fgetxattr: ::c_long = 10; +pub const SYS_listxattr: ::c_long = 11; +pub const SYS_llistxattr: ::c_long = 12; +pub const SYS_flistxattr: ::c_long = 13; +pub const SYS_removexattr: ::c_long = 14; +pub const SYS_lremovexattr: ::c_long = 15; +pub const SYS_fremovexattr: ::c_long = 16; +pub const SYS_tkill: ::c_long = 130; +pub const SYS_futex: ::c_long = 98; +pub const SYS_sched_setaffinity: ::c_long = 122; +pub const SYS_sched_getaffinity: ::c_long = 123; +pub const SYS_io_setup: ::c_long = 0; +pub const SYS_io_destroy: ::c_long = 1; +pub const SYS_io_getevents: ::c_long = 4; +pub const SYS_io_submit: ::c_long = 2; +pub const SYS_io_cancel: ::c_long = 3; +pub const SYS_lookup_dcookie: ::c_long = 18; +pub const SYS_remap_file_pages: ::c_long = 234; +pub const SYS_getdents64: ::c_long = 61; +pub const SYS_set_tid_address: ::c_long = 96; +pub const SYS_restart_syscall: ::c_long = 128; +pub const SYS_semtimedop: ::c_long = 192; +pub const SYS_fadvise64: ::c_long = 223; +pub const SYS_timer_create: ::c_long = 107; +pub const SYS_timer_settime: ::c_long = 110; +pub const SYS_timer_gettime: ::c_long = 108; +pub const SYS_timer_getoverrun: ::c_long = 109; +pub const SYS_timer_delete: ::c_long = 111; +pub const SYS_clock_settime: ::c_long = 112; +pub const SYS_clock_gettime: ::c_long = 113; +pub const SYS_clock_getres: ::c_long = 114; +pub const SYS_clock_nanosleep: ::c_long = 115; +pub const SYS_exit_group: ::c_long = 94; +pub const SYS_epoll_ctl: ::c_long = 21; +pub const SYS_tgkill: ::c_long = 131; +pub const SYS_mbind: ::c_long = 235; +pub const SYS_set_mempolicy: ::c_long = 237; +pub const SYS_get_mempolicy: ::c_long = 236; +pub const SYS_mq_open: ::c_long = 180; +pub const SYS_mq_unlink: ::c_long = 181; +pub const SYS_mq_timedsend: ::c_long = 182; +pub const SYS_mq_timedreceive: ::c_long = 183; +pub const SYS_mq_notify: ::c_long = 184; +pub const SYS_mq_getsetattr: ::c_long = 185; +pub const SYS_kexec_load: ::c_long = 104; +pub const SYS_waitid: ::c_long = 95; +pub const SYS_add_key: ::c_long = 217; +pub const SYS_request_key: ::c_long = 218; +pub const SYS_keyctl: ::c_long = 219; +pub const SYS_ioprio_set: ::c_long = 30; +pub const SYS_ioprio_get: ::c_long = 31; +pub const SYS_inotify_add_watch: ::c_long = 27; +pub const SYS_inotify_rm_watch: ::c_long = 28; +pub const SYS_migrate_pages: ::c_long = 238; +pub const SYS_openat: ::c_long = 56; +pub const SYS_mkdirat: ::c_long = 34; +pub const SYS_mknodat: ::c_long = 33; +pub const SYS_fchownat: ::c_long = 54; +pub const SYS_newfstatat: ::c_long = 79; +pub const SYS_unlinkat: ::c_long = 35; +pub const SYS_linkat: ::c_long = 37; +pub const SYS_symlinkat: ::c_long = 36; +pub const SYS_readlinkat: ::c_long = 78; +pub const SYS_fchmodat: ::c_long = 53; +pub const SYS_faccessat: ::c_long = 48; +pub const SYS_pselect6: ::c_long = 72; +pub const SYS_ppoll: ::c_long = 73; +pub const SYS_unshare: ::c_long = 97; +pub const SYS_set_robust_list: ::c_long = 99; +pub const SYS_get_robust_list: ::c_long = 100; +pub const SYS_splice: ::c_long = 76; +pub const SYS_tee: ::c_long = 77; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_vmsplice: ::c_long = 75; +pub const SYS_move_pages: ::c_long = 239; +pub const SYS_utimensat: ::c_long = 88; +pub const SYS_epoll_pwait: ::c_long = 22; +pub const SYS_timerfd_create: ::c_long = 85; +pub const SYS_fallocate: ::c_long = 47; +pub const SYS_timerfd_settime: ::c_long = 86; +pub const SYS_timerfd_gettime: ::c_long = 87; +pub const SYS_accept4: ::c_long = 242; +pub const SYS_signalfd4: ::c_long = 74; +pub const SYS_eventfd2: ::c_long = 19; +pub const SYS_epoll_create1: ::c_long = 20; +pub const SYS_dup3: ::c_long = 24; +pub const SYS_pipe2: ::c_long = 59; +pub const SYS_inotify_init1: ::c_long = 26; +pub const SYS_preadv: ::c_long = 69; +pub const SYS_pwritev: ::c_long = 70; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; +pub const SYS_perf_event_open: ::c_long = 241; +pub const SYS_recvmmsg: ::c_long = 243; +pub const SYS_fanotify_init: ::c_long = 262; +pub const SYS_fanotify_mark: ::c_long = 263; +pub const SYS_prlimit64: ::c_long = 261; +pub const SYS_name_to_handle_at: ::c_long = 264; +pub const SYS_open_by_handle_at: ::c_long = 265; +pub const SYS_clock_adjtime: ::c_long = 266; +pub const SYS_syncfs: ::c_long = 267; +pub const SYS_sendmmsg: ::c_long = 269; +pub const SYS_setns: ::c_long = 268; +pub const SYS_getcpu: ::c_long = 168; +pub const SYS_process_vm_readv: ::c_long = 270; +pub const SYS_process_vm_writev: ::c_long = 271; +pub const SYS_kcmp: ::c_long = 272; +pub const SYS_finit_module: ::c_long = 273; +pub const SYS_sched_setattr: ::c_long = 274; +pub const SYS_sched_getattr: ::c_long = 275; +pub const SYS_renameat2: ::c_long = 276; +pub const SYS_seccomp: ::c_long = 277; +pub const SYS_getrandom: ::c_long = 278; +pub const SYS_memfd_create: ::c_long = 279; +pub const SYS_bpf: ::c_long = 280; +pub const SYS_execveat: ::c_long = 281; +pub const SYS_userfaultfd: ::c_long = 282; +pub const SYS_membarrier: ::c_long = 283; +pub const SYS_mlock2: ::c_long = 284; +pub const SYS_copy_file_range: ::c_long = 285; +pub const SYS_preadv2: ::c_long = 286; +pub const SYS_pwritev2: ::c_long = 287; +pub const SYS_pkey_mprotect: ::c_long = 288; +pub const SYS_pkey_alloc: ::c_long = 289; +pub const SYS_pkey_free: ::c_long = 290; +pub const SYS_statx: ::c_long = 291; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; + +pub const O_APPEND: ::c_int = 1024; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_LARGEFILE: ::c_int = 0; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const EDEADLK: ::c_int = 35; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const EXTPROC: ::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const NGREG: usize = 32; +pub const REG_PC: usize = 0; +pub const REG_RA: usize = 1; +pub const REG_SP: usize = 2; +pub const REG_TP: usize = 4; +pub const REG_S0: usize = 8; +pub const REG_S1: usize = 9; +pub const REG_A0: usize = 10; +pub const REG_S2: usize = 18; +pub const REG_NARGS: usize = 8; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs new file mode 100644 index 00000000..aa4cbf87 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs @@ -0,0 +1,724 @@ +pub type blksize_t = i64; +pub type c_char = u8; +pub type nlink_t = u64; +pub type wchar_t = i32; +pub type greg_t = u64; +pub type __u64 = u64; +pub type __s64 = i64; + +s! { + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __pad1: ::c_long, + __pad2: ::c_long, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + __unused: [::c_long; 3], + } + + pub struct statfs { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 4], + } + + pub struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 4], + } +} + +s_no_extra_traits! { + // FIXME: This is actually a union. + pub struct fpreg_t { + pub d: ::c_double, + // f: ::c_float, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg_t { + fn eq(&self, other: &fpreg_t) -> bool { + self.d == other.d + } + } + + impl Eq for fpreg_t {} + + impl ::fmt::Debug for fpreg_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg_t") + .field("d", &self.d) + .finish() + } + } + + impl ::hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = unsafe { ::mem::transmute(self.d) }; + d.hash(state); + } + } + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; + +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +pub const EDEADLK: ::c_int = 35; +pub const ENOSYS: ::c_int = 38; +pub const ENOTCONN: ::c_int = 107; +pub const ETIMEDOUT: ::c_int = 110; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_LARGEFILE: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 2048; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 4; +pub const SIGBUS: ::c_int = 7; +pub const SIGSTKSZ: ::size_t = 0x2000; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIG_SETMASK: ::c_int = 2; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const O_NOCTTY: ::c_int = 256; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const PTRACE_SYSEMU: ::c_int = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 32; + +pub const EDEADLOCK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGCHLD: ::c_int = 17; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const O_ASYNC: ::c_int = 0x2000; + +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; + +pub const VTIME: usize = 5; +pub const VSWTC: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const FF1: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const CBAUD: ::speed_t = 0o010017; +pub const CSIZE: ::tcflag_t = 0o000060; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +pub const CREAD: ::tcflag_t = 0o000200; +pub const PARENB: ::tcflag_t = 0o000400; +pub const PARODD: ::tcflag_t = 0o001000; +pub const HUPCL: ::tcflag_t = 0o002000; +pub const CLOCAL: ::tcflag_t = 0o004000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; +pub const CIBAUD: ::tcflag_t = 0o02003600000; + +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const XCASE: ::tcflag_t = 0o000004; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const PENDIN: ::tcflag_t = 0o040000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; + +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_restart_syscall: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_signal: ::c_long = 48; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_lookup_dcookie: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_getdents: ::c_long = 141; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_readahead: ::c_long = 222; +pub const SYS_setxattr: ::c_long = 224; +pub const SYS_lsetxattr: ::c_long = 225; +pub const SYS_fsetxattr: ::c_long = 226; +pub const SYS_getxattr: ::c_long = 227; +pub const SYS_lgetxattr: ::c_long = 228; +pub const SYS_fgetxattr: ::c_long = 229; +pub const SYS_listxattr: ::c_long = 230; +pub const SYS_llistxattr: ::c_long = 231; +pub const SYS_flistxattr: ::c_long = 232; +pub const SYS_removexattr: ::c_long = 233; +pub const SYS_lremovexattr: ::c_long = 234; +pub const SYS_fremovexattr: ::c_long = 235; +pub const SYS_gettid: ::c_long = 236; +pub const SYS_tkill: ::c_long = 237; +pub const SYS_futex: ::c_long = 238; +pub const SYS_sched_setaffinity: ::c_long = 239; +pub const SYS_sched_getaffinity: ::c_long = 240; +pub const SYS_tgkill: ::c_long = 241; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_epoll_create: ::c_long = 249; +pub const SYS_epoll_ctl: ::c_long = 250; +pub const SYS_epoll_wait: ::c_long = 251; +pub const SYS_set_tid_address: ::c_long = 252; +pub const SYS_fadvise64: ::c_long = 253; +pub const SYS_timer_create: ::c_long = 254; +pub const SYS_timer_settime: ::c_long = 255; +pub const SYS_timer_gettime: ::c_long = 256; +pub const SYS_timer_getoverrun: ::c_long = 257; +pub const SYS_timer_delete: ::c_long = 258; +pub const SYS_clock_settime: ::c_long = 259; +pub const SYS_clock_gettime: ::c_long = 260; +pub const SYS_clock_getres: ::c_long = 261; +pub const SYS_clock_nanosleep: ::c_long = 262; +pub const SYS_statfs64: ::c_long = 265; +pub const SYS_fstatfs64: ::c_long = 266; +pub const SYS_remap_file_pages: ::c_long = 267; +pub const SYS_mbind: ::c_long = 268; +pub const SYS_get_mempolicy: ::c_long = 269; +pub const SYS_set_mempolicy: ::c_long = 270; +pub const SYS_mq_open: ::c_long = 271; +pub const SYS_mq_unlink: ::c_long = 272; +pub const SYS_mq_timedsend: ::c_long = 273; +pub const SYS_mq_timedreceive: ::c_long = 274; +pub const SYS_mq_notify: ::c_long = 275; +pub const SYS_mq_getsetattr: ::c_long = 276; +pub const SYS_kexec_load: ::c_long = 277; +pub const SYS_add_key: ::c_long = 278; +pub const SYS_request_key: ::c_long = 279; +pub const SYS_keyctl: ::c_long = 280; +pub const SYS_waitid: ::c_long = 281; +pub const SYS_ioprio_set: ::c_long = 282; +pub const SYS_ioprio_get: ::c_long = 283; +pub const SYS_inotify_init: ::c_long = 284; +pub const SYS_inotify_add_watch: ::c_long = 285; +pub const SYS_inotify_rm_watch: ::c_long = 286; +pub const SYS_migrate_pages: ::c_long = 287; +pub const SYS_openat: ::c_long = 288; +pub const SYS_mkdirat: ::c_long = 289; +pub const SYS_mknodat: ::c_long = 290; +pub const SYS_fchownat: ::c_long = 291; +pub const SYS_futimesat: ::c_long = 292; +pub const SYS_unlinkat: ::c_long = 294; +pub const SYS_renameat: ::c_long = 295; +pub const SYS_linkat: ::c_long = 296; +pub const SYS_symlinkat: ::c_long = 297; +pub const SYS_readlinkat: ::c_long = 298; +pub const SYS_fchmodat: ::c_long = 299; +pub const SYS_faccessat: ::c_long = 300; +pub const SYS_pselect6: ::c_long = 301; +pub const SYS_ppoll: ::c_long = 302; +pub const SYS_unshare: ::c_long = 303; +pub const SYS_set_robust_list: ::c_long = 304; +pub const SYS_get_robust_list: ::c_long = 305; +pub const SYS_splice: ::c_long = 306; +pub const SYS_sync_file_range: ::c_long = 307; +pub const SYS_tee: ::c_long = 308; +pub const SYS_vmsplice: ::c_long = 309; +pub const SYS_move_pages: ::c_long = 310; +pub const SYS_getcpu: ::c_long = 311; +pub const SYS_epoll_pwait: ::c_long = 312; +pub const SYS_utimes: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_utimensat: ::c_long = 315; +pub const SYS_signalfd: ::c_long = 316; +pub const SYS_timerfd: ::c_long = 317; +pub const SYS_eventfd: ::c_long = 318; +pub const SYS_timerfd_create: ::c_long = 319; +pub const SYS_timerfd_settime: ::c_long = 320; +pub const SYS_timerfd_gettime: ::c_long = 321; +pub const SYS_signalfd4: ::c_long = 322; +pub const SYS_eventfd2: ::c_long = 323; +pub const SYS_inotify_init1: ::c_long = 324; +pub const SYS_pipe2: ::c_long = 325; +pub const SYS_dup3: ::c_long = 326; +pub const SYS_epoll_create1: ::c_long = 327; +pub const SYS_preadv: ::c_long = 328; +pub const SYS_pwritev: ::c_long = 329; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 330; +pub const SYS_perf_event_open: ::c_long = 331; +pub const SYS_fanotify_init: ::c_long = 332; +pub const SYS_fanotify_mark: ::c_long = 333; +pub const SYS_prlimit64: ::c_long = 334; +pub const SYS_name_to_handle_at: ::c_long = 335; +pub const SYS_open_by_handle_at: ::c_long = 336; +pub const SYS_clock_adjtime: ::c_long = 337; +pub const SYS_syncfs: ::c_long = 338; +pub const SYS_setns: ::c_long = 339; +pub const SYS_process_vm_readv: ::c_long = 340; +pub const SYS_process_vm_writev: ::c_long = 341; +pub const SYS_s390_runtime_instr: ::c_long = 342; +pub const SYS_kcmp: ::c_long = 343; +pub const SYS_finit_module: ::c_long = 344; +pub const SYS_sched_setattr: ::c_long = 345; +pub const SYS_sched_getattr: ::c_long = 346; +pub const SYS_renameat2: ::c_long = 347; +pub const SYS_seccomp: ::c_long = 348; +pub const SYS_getrandom: ::c_long = 349; +pub const SYS_memfd_create: ::c_long = 350; +pub const SYS_bpf: ::c_long = 351; +pub const SYS_s390_pci_mmio_write: ::c_long = 352; +pub const SYS_s390_pci_mmio_read: ::c_long = 353; +pub const SYS_execveat: ::c_long = 354; +pub const SYS_userfaultfd: ::c_long = 355; +pub const SYS_membarrier: ::c_long = 356; +pub const SYS_recvmmsg: ::c_long = 357; +pub const SYS_sendmmsg: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_mlock2: ::c_long = 374; +pub const SYS_copy_file_range: ::c_long = 375; +pub const SYS_preadv2: ::c_long = 376; +pub const SYS_pwritev2: ::c_long = 377; +pub const SYS_lchown: ::c_long = 198; +pub const SYS_setuid: ::c_long = 213; +pub const SYS_getuid: ::c_long = 199; +pub const SYS_setgid: ::c_long = 214; +pub const SYS_getgid: ::c_long = 200; +pub const SYS_geteuid: ::c_long = 201; +pub const SYS_setreuid: ::c_long = 203; +pub const SYS_setregid: ::c_long = 204; +pub const SYS_getrlimit: ::c_long = 191; +pub const SYS_getgroups: ::c_long = 205; +pub const SYS_fchown: ::c_long = 207; +pub const SYS_setresuid: ::c_long = 208; +pub const SYS_setresgid: ::c_long = 210; +pub const SYS_getresgid: ::c_long = 211; +pub const SYS_select: ::c_long = 142; +pub const SYS_getegid: ::c_long = 202; +pub const SYS_setgroups: ::c_long = 206; +pub const SYS_getresuid: ::c_long = 209; +pub const SYS_chown: ::c_long = 212; +pub const SYS_setfsuid: ::c_long = 215; +pub const SYS_setfsgid: ::c_long = 216; +pub const SYS_newfstatat: ::c_long = 293; +pub const SYS_statx: ::c_long = 379; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs new file mode 100644 index 00000000..94391a01 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs @@ -0,0 +1,25 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + +} + +s! { + #[repr(align(8))] + pub struct clone_args { + pub flags: ::c_ulonglong, + pub pidfd: ::c_ulonglong, + pub child_tid: ::c_ulonglong, + pub parent_tid: ::c_ulonglong, + pub exit_signal: ::c_ulonglong, + pub stack: ::c_ulonglong, + pub stack_size: ::c_ulonglong, + pub tls: ::c_ulonglong, + pub set_tid: ::c_ulonglong, + pub set_tid_size: ::c_ulonglong, + pub cgroup: ::c_ulonglong, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs new file mode 100644 index 00000000..4d178680 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs @@ -0,0 +1,915 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = ::c_long; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; +pub type greg_t = i64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + __pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 3], + } + + pub struct user_regs_struct { + pub r15: ::c_ulong, + pub r14: ::c_ulong, + pub r13: ::c_ulong, + pub r12: ::c_ulong, + pub rbp: ::c_ulong, + pub rbx: ::c_ulong, + pub r11: ::c_ulong, + pub r10: ::c_ulong, + pub r9: ::c_ulong, + pub r8: ::c_ulong, + pub rax: ::c_ulong, + pub rcx: ::c_ulong, + pub rdx: ::c_ulong, + pub rsi: ::c_ulong, + pub rdi: ::c_ulong, + pub orig_rax: ::c_ulong, + pub rip: ::c_ulong, + pub cs: ::c_ulong, + pub eflags: ::c_ulong, + pub rsp: ::c_ulong, + pub ss: ::c_ulong, + pub fs_base: ::c_ulong, + pub gs_base: ::c_ulong, + pub ds: ::c_ulong, + pub es: ::c_ulong, + pub fs: ::c_ulong, + pub gs: ::c_ulong, + } + + pub struct user { + pub regs: user_regs_struct, + pub u_fpvalid: ::c_int, + pub i387: user_fpregs_struct, + pub u_tsize: ::c_ulong, + pub u_dsize: ::c_ulong, + pub u_ssize: ::c_ulong, + pub start_code: ::c_ulong, + pub start_stack: ::c_ulong, + pub signal: ::c_long, + __reserved: ::c_int, + #[cfg(target_pointer_width = "32")] + __pad1: u32, + pub u_ar0: *mut user_regs_struct, + #[cfg(target_pointer_width = "32")] + __pad2: u32, + pub u_fpstate: *mut user_fpregs_struct, + pub magic: ::c_ulong, + pub u_comm: [::c_char; 32], + pub u_debugreg: [::c_ulong; 8], + } + + // GitHub repo: ifduyue/musl/ + // commit: b4b1e10364c8737a632be61582e05a8d3acf5690 + // file: arch/x86_64/bits/signal.h#L80-L84 + pub struct mcontext_t { + pub gregs: [greg_t; 23], + __private: [u64; 9], + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } +} + +s_no_extra_traits! { + pub struct user_fpregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub ftw: ::c_ushort, + pub fop: ::c_ushort, + pub rip: ::c_ulong, + pub rdp: ::c_ulong, + pub mxcsr: ::c_uint, + pub mxcr_mask: ::c_uint, + pub st_space: [::c_uint; 32], + pub xmm_space: [::c_uint; 64], + padding: [::c_uint; 24], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpregs_struct { + fn eq(&self, other: &user_fpregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.ftw == other.ftw + && self.fop == other.fop + && self.rip == other.rip + && self.rdp == other.rdp + && self.mxcsr == other.mxcsr + && self.mxcr_mask == other.mxcr_mask + && self.st_space == other.st_space + && self + .xmm_space + .iter() + .zip(other.xmm_space.iter()) + .all(|(a,b)| a == b) + // Ignore padding field + } + } + + impl Eq for user_fpregs_struct {} + + impl ::fmt::Debug for user_fpregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpregs_struct") + .field("cwd", &self.cwd) + .field("ftw", &self.ftw) + .field("fop", &self.fop) + .field("rip", &self.rip) + .field("rdp", &self.rdp) + .field("mxcsr", &self.mxcsr) + .field("mxcr_mask", &self.mxcr_mask) + .field("st_space", &self.st_space) + // FIXME: .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.ftw.hash(state); + self.fop.hash(state); + self.rip.hash(state); + self.rdp.hash(state); + self.mxcsr.hash(state); + self.mxcr_mask.hash(state); + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + +// Syscall table + +pub const SYS_read: ::c_long = 0; +pub const SYS_write: ::c_long = 1; +pub const SYS_open: ::c_long = 2; +pub const SYS_close: ::c_long = 3; +pub const SYS_stat: ::c_long = 4; +pub const SYS_fstat: ::c_long = 5; +pub const SYS_lstat: ::c_long = 6; +pub const SYS_poll: ::c_long = 7; +pub const SYS_lseek: ::c_long = 8; +pub const SYS_mmap: ::c_long = 9; +pub const SYS_mprotect: ::c_long = 10; +pub const SYS_munmap: ::c_long = 11; +pub const SYS_brk: ::c_long = 12; +pub const SYS_rt_sigaction: ::c_long = 13; +pub const SYS_rt_sigprocmask: ::c_long = 14; +pub const SYS_rt_sigreturn: ::c_long = 15; +pub const SYS_ioctl: ::c_long = 16; +pub const SYS_pread64: ::c_long = 17; +pub const SYS_pwrite64: ::c_long = 18; +pub const SYS_readv: ::c_long = 19; +pub const SYS_writev: ::c_long = 20; +pub const SYS_access: ::c_long = 21; +pub const SYS_pipe: ::c_long = 22; +pub const SYS_select: ::c_long = 23; +pub const SYS_sched_yield: ::c_long = 24; +pub const SYS_mremap: ::c_long = 25; +pub const SYS_msync: ::c_long = 26; +pub const SYS_mincore: ::c_long = 27; +pub const SYS_madvise: ::c_long = 28; +pub const SYS_shmget: ::c_long = 29; +pub const SYS_shmat: ::c_long = 30; +pub const SYS_shmctl: ::c_long = 31; +pub const SYS_dup: ::c_long = 32; +pub const SYS_dup2: ::c_long = 33; +pub const SYS_pause: ::c_long = 34; +pub const SYS_nanosleep: ::c_long = 35; +pub const SYS_getitimer: ::c_long = 36; +pub const SYS_alarm: ::c_long = 37; +pub const SYS_setitimer: ::c_long = 38; +pub const SYS_getpid: ::c_long = 39; +pub const SYS_sendfile: ::c_long = 40; +pub const SYS_socket: ::c_long = 41; +pub const SYS_connect: ::c_long = 42; +pub const SYS_accept: ::c_long = 43; +pub const SYS_sendto: ::c_long = 44; +pub const SYS_recvfrom: ::c_long = 45; +pub const SYS_sendmsg: ::c_long = 46; +pub const SYS_recvmsg: ::c_long = 47; +pub const SYS_shutdown: ::c_long = 48; +pub const SYS_bind: ::c_long = 49; +pub const SYS_listen: ::c_long = 50; +pub const SYS_getsockname: ::c_long = 51; +pub const SYS_getpeername: ::c_long = 52; +pub const SYS_socketpair: ::c_long = 53; +pub const SYS_setsockopt: ::c_long = 54; +pub const SYS_getsockopt: ::c_long = 55; +pub const SYS_clone: ::c_long = 56; +pub const SYS_fork: ::c_long = 57; +pub const SYS_vfork: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_exit: ::c_long = 60; +pub const SYS_wait4: ::c_long = 61; +pub const SYS_kill: ::c_long = 62; +pub const SYS_uname: ::c_long = 63; +pub const SYS_semget: ::c_long = 64; +pub const SYS_semop: ::c_long = 65; +pub const SYS_semctl: ::c_long = 66; +pub const SYS_shmdt: ::c_long = 67; +pub const SYS_msgget: ::c_long = 68; +pub const SYS_msgsnd: ::c_long = 69; +pub const SYS_msgrcv: ::c_long = 70; +pub const SYS_msgctl: ::c_long = 71; +pub const SYS_fcntl: ::c_long = 72; +pub const SYS_flock: ::c_long = 73; +pub const SYS_fsync: ::c_long = 74; +pub const SYS_fdatasync: ::c_long = 75; +pub const SYS_truncate: ::c_long = 76; +pub const SYS_ftruncate: ::c_long = 77; +pub const SYS_getdents: ::c_long = 78; +pub const SYS_getcwd: ::c_long = 79; +pub const SYS_chdir: ::c_long = 80; +pub const SYS_fchdir: ::c_long = 81; +pub const SYS_rename: ::c_long = 82; +pub const SYS_mkdir: ::c_long = 83; +pub const SYS_rmdir: ::c_long = 84; +pub const SYS_creat: ::c_long = 85; +pub const SYS_link: ::c_long = 86; +pub const SYS_unlink: ::c_long = 87; +pub const SYS_symlink: ::c_long = 88; +pub const SYS_readlink: ::c_long = 89; +pub const SYS_chmod: ::c_long = 90; +pub const SYS_fchmod: ::c_long = 91; +pub const SYS_chown: ::c_long = 92; +pub const SYS_fchown: ::c_long = 93; +pub const SYS_lchown: ::c_long = 94; +pub const SYS_umask: ::c_long = 95; +pub const SYS_gettimeofday: ::c_long = 96; +pub const SYS_getrlimit: ::c_long = 97; +pub const SYS_getrusage: ::c_long = 98; +pub const SYS_sysinfo: ::c_long = 99; +pub const SYS_times: ::c_long = 100; +pub const SYS_ptrace: ::c_long = 101; +pub const SYS_getuid: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_getgid: ::c_long = 104; +pub const SYS_setuid: ::c_long = 105; +pub const SYS_setgid: ::c_long = 106; +pub const SYS_geteuid: ::c_long = 107; +pub const SYS_getegid: ::c_long = 108; +pub const SYS_setpgid: ::c_long = 109; +pub const SYS_getppid: ::c_long = 110; +pub const SYS_getpgrp: ::c_long = 111; +pub const SYS_setsid: ::c_long = 112; +pub const SYS_setreuid: ::c_long = 113; +pub const SYS_setregid: ::c_long = 114; +pub const SYS_getgroups: ::c_long = 115; +pub const SYS_setgroups: ::c_long = 116; +pub const SYS_setresuid: ::c_long = 117; +pub const SYS_getresuid: ::c_long = 118; +pub const SYS_setresgid: ::c_long = 119; +pub const SYS_getresgid: ::c_long = 120; +pub const SYS_getpgid: ::c_long = 121; +pub const SYS_setfsuid: ::c_long = 122; +pub const SYS_setfsgid: ::c_long = 123; +pub const SYS_getsid: ::c_long = 124; +pub const SYS_capget: ::c_long = 125; +pub const SYS_capset: ::c_long = 126; +pub const SYS_rt_sigpending: ::c_long = 127; +pub const SYS_rt_sigtimedwait: ::c_long = 128; +pub const SYS_rt_sigqueueinfo: ::c_long = 129; +pub const SYS_rt_sigsuspend: ::c_long = 130; +pub const SYS_sigaltstack: ::c_long = 131; +pub const SYS_utime: ::c_long = 132; +pub const SYS_mknod: ::c_long = 133; +pub const SYS_uselib: ::c_long = 134; +pub const SYS_personality: ::c_long = 135; +pub const SYS_ustat: ::c_long = 136; +pub const SYS_statfs: ::c_long = 137; +pub const SYS_fstatfs: ::c_long = 138; +pub const SYS_sysfs: ::c_long = 139; +pub const SYS_getpriority: ::c_long = 140; +pub const SYS_setpriority: ::c_long = 141; +pub const SYS_sched_setparam: ::c_long = 142; +pub const SYS_sched_getparam: ::c_long = 143; +pub const SYS_sched_setscheduler: ::c_long = 144; +pub const SYS_sched_getscheduler: ::c_long = 145; +pub const SYS_sched_get_priority_max: ::c_long = 146; +pub const SYS_sched_get_priority_min: ::c_long = 147; +pub const SYS_sched_rr_get_interval: ::c_long = 148; +pub const SYS_mlock: ::c_long = 149; +pub const SYS_munlock: ::c_long = 150; +pub const SYS_mlockall: ::c_long = 151; +pub const SYS_munlockall: ::c_long = 152; +pub const SYS_vhangup: ::c_long = 153; +pub const SYS_modify_ldt: ::c_long = 154; +pub const SYS_pivot_root: ::c_long = 155; +pub const SYS__sysctl: ::c_long = 156; +pub const SYS_prctl: ::c_long = 157; +pub const SYS_arch_prctl: ::c_long = 158; +pub const SYS_adjtimex: ::c_long = 159; +pub const SYS_setrlimit: ::c_long = 160; +pub const SYS_chroot: ::c_long = 161; +pub const SYS_sync: ::c_long = 162; +pub const SYS_acct: ::c_long = 163; +pub const SYS_settimeofday: ::c_long = 164; +pub const SYS_mount: ::c_long = 165; +pub const SYS_umount2: ::c_long = 166; +pub const SYS_swapon: ::c_long = 167; +pub const SYS_swapoff: ::c_long = 168; +pub const SYS_reboot: ::c_long = 169; +pub const SYS_sethostname: ::c_long = 170; +pub const SYS_setdomainname: ::c_long = 171; +pub const SYS_iopl: ::c_long = 172; +pub const SYS_ioperm: ::c_long = 173; +pub const SYS_create_module: ::c_long = 174; +pub const SYS_init_module: ::c_long = 175; +pub const SYS_delete_module: ::c_long = 176; +pub const SYS_get_kernel_syms: ::c_long = 177; +pub const SYS_query_module: ::c_long = 178; +pub const SYS_quotactl: ::c_long = 179; +pub const SYS_nfsservctl: ::c_long = 180; +pub const SYS_getpmsg: ::c_long = 181; +pub const SYS_putpmsg: ::c_long = 182; +pub const SYS_afs_syscall: ::c_long = 183; +pub const SYS_tuxcall: ::c_long = 184; +pub const SYS_security: ::c_long = 185; +pub const SYS_gettid: ::c_long = 186; +pub const SYS_readahead: ::c_long = 187; +pub const SYS_setxattr: ::c_long = 188; +pub const SYS_lsetxattr: ::c_long = 189; +pub const SYS_fsetxattr: ::c_long = 190; +pub const SYS_getxattr: ::c_long = 191; +pub const SYS_lgetxattr: ::c_long = 192; +pub const SYS_fgetxattr: ::c_long = 193; +pub const SYS_listxattr: ::c_long = 194; +pub const SYS_llistxattr: ::c_long = 195; +pub const SYS_flistxattr: ::c_long = 196; +pub const SYS_removexattr: ::c_long = 197; +pub const SYS_lremovexattr: ::c_long = 198; +pub const SYS_fremovexattr: ::c_long = 199; +pub const SYS_tkill: ::c_long = 200; +pub const SYS_time: ::c_long = 201; +pub const SYS_futex: ::c_long = 202; +pub const SYS_sched_setaffinity: ::c_long = 203; +pub const SYS_sched_getaffinity: ::c_long = 204; +pub const SYS_set_thread_area: ::c_long = 205; +pub const SYS_io_setup: ::c_long = 206; +pub const SYS_io_destroy: ::c_long = 207; +pub const SYS_io_getevents: ::c_long = 208; +pub const SYS_io_submit: ::c_long = 209; +pub const SYS_io_cancel: ::c_long = 210; +pub const SYS_get_thread_area: ::c_long = 211; +pub const SYS_lookup_dcookie: ::c_long = 212; +pub const SYS_epoll_create: ::c_long = 213; +pub const SYS_epoll_ctl_old: ::c_long = 214; +pub const SYS_epoll_wait_old: ::c_long = 215; +pub const SYS_remap_file_pages: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_set_tid_address: ::c_long = 218; +pub const SYS_restart_syscall: ::c_long = 219; +pub const SYS_semtimedop: ::c_long = 220; +pub const SYS_fadvise64: ::c_long = 221; +pub const SYS_timer_create: ::c_long = 222; +pub const SYS_timer_settime: ::c_long = 223; +pub const SYS_timer_gettime: ::c_long = 224; +pub const SYS_timer_getoverrun: ::c_long = 225; +pub const SYS_timer_delete: ::c_long = 226; +pub const SYS_clock_settime: ::c_long = 227; +pub const SYS_clock_gettime: ::c_long = 228; +pub const SYS_clock_getres: ::c_long = 229; +pub const SYS_clock_nanosleep: ::c_long = 230; +pub const SYS_exit_group: ::c_long = 231; +pub const SYS_epoll_wait: ::c_long = 232; +pub const SYS_epoll_ctl: ::c_long = 233; +pub const SYS_tgkill: ::c_long = 234; +pub const SYS_utimes: ::c_long = 235; +pub const SYS_vserver: ::c_long = 236; +pub const SYS_mbind: ::c_long = 237; +pub const SYS_set_mempolicy: ::c_long = 238; +pub const SYS_get_mempolicy: ::c_long = 239; +pub const SYS_mq_open: ::c_long = 240; +pub const SYS_mq_unlink: ::c_long = 241; +pub const SYS_mq_timedsend: ::c_long = 242; +pub const SYS_mq_timedreceive: ::c_long = 243; +pub const SYS_mq_notify: ::c_long = 244; +pub const SYS_mq_getsetattr: ::c_long = 245; +pub const SYS_kexec_load: ::c_long = 246; +pub const SYS_waitid: ::c_long = 247; +pub const SYS_add_key: ::c_long = 248; +pub const SYS_request_key: ::c_long = 249; +pub const SYS_keyctl: ::c_long = 250; +pub const SYS_ioprio_set: ::c_long = 251; +pub const SYS_ioprio_get: ::c_long = 252; +pub const SYS_inotify_init: ::c_long = 253; +pub const SYS_inotify_add_watch: ::c_long = 254; +pub const SYS_inotify_rm_watch: ::c_long = 255; +pub const SYS_migrate_pages: ::c_long = 256; +pub const SYS_openat: ::c_long = 257; +pub const SYS_mkdirat: ::c_long = 258; +pub const SYS_mknodat: ::c_long = 259; +pub const SYS_fchownat: ::c_long = 260; +pub const SYS_futimesat: ::c_long = 261; +pub const SYS_newfstatat: ::c_long = 262; +pub const SYS_unlinkat: ::c_long = 263; +pub const SYS_renameat: ::c_long = 264; +pub const SYS_linkat: ::c_long = 265; +pub const SYS_symlinkat: ::c_long = 266; +pub const SYS_readlinkat: ::c_long = 267; +pub const SYS_fchmodat: ::c_long = 268; +pub const SYS_faccessat: ::c_long = 269; +pub const SYS_pselect6: ::c_long = 270; +pub const SYS_ppoll: ::c_long = 271; +pub const SYS_unshare: ::c_long = 272; +pub const SYS_set_robust_list: ::c_long = 273; +pub const SYS_get_robust_list: ::c_long = 274; +pub const SYS_splice: ::c_long = 275; +pub const SYS_tee: ::c_long = 276; +pub const SYS_sync_file_range: ::c_long = 277; +pub const SYS_vmsplice: ::c_long = 278; +pub const SYS_move_pages: ::c_long = 279; +pub const SYS_utimensat: ::c_long = 280; +pub const SYS_epoll_pwait: ::c_long = 281; +pub const SYS_signalfd: ::c_long = 282; +pub const SYS_timerfd_create: ::c_long = 283; +pub const SYS_eventfd: ::c_long = 284; +pub const SYS_fallocate: ::c_long = 285; +pub const SYS_timerfd_settime: ::c_long = 286; +pub const SYS_timerfd_gettime: ::c_long = 287; +pub const SYS_accept4: ::c_long = 288; +pub const SYS_signalfd4: ::c_long = 289; +pub const SYS_eventfd2: ::c_long = 290; +pub const SYS_epoll_create1: ::c_long = 291; +pub const SYS_dup3: ::c_long = 292; +pub const SYS_pipe2: ::c_long = 293; +pub const SYS_inotify_init1: ::c_long = 294; +pub const SYS_preadv: ::c_long = 295; +pub const SYS_pwritev: ::c_long = 296; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 297; +pub const SYS_perf_event_open: ::c_long = 298; +pub const SYS_recvmmsg: ::c_long = 299; +pub const SYS_fanotify_init: ::c_long = 300; +pub const SYS_fanotify_mark: ::c_long = 301; +pub const SYS_prlimit64: ::c_long = 302; +pub const SYS_name_to_handle_at: ::c_long = 303; +pub const SYS_open_by_handle_at: ::c_long = 304; +pub const SYS_clock_adjtime: ::c_long = 305; +pub const SYS_syncfs: ::c_long = 306; +pub const SYS_sendmmsg: ::c_long = 307; +pub const SYS_setns: ::c_long = 308; +pub const SYS_getcpu: ::c_long = 309; +pub const SYS_process_vm_readv: ::c_long = 310; +pub const SYS_process_vm_writev: ::c_long = 311; +pub const SYS_kcmp: ::c_long = 312; +pub const SYS_finit_module: ::c_long = 313; +pub const SYS_sched_setattr: ::c_long = 314; +pub const SYS_sched_getattr: ::c_long = 315; +pub const SYS_renameat2: ::c_long = 316; +pub const SYS_seccomp: ::c_long = 317; +pub const SYS_getrandom: ::c_long = 318; +pub const SYS_memfd_create: ::c_long = 319; +pub const SYS_kexec_file_load: ::c_long = 320; +pub const SYS_bpf: ::c_long = 321; +pub const SYS_execveat: ::c_long = 322; +pub const SYS_userfaultfd: ::c_long = 323; +pub const SYS_membarrier: ::c_long = 324; +pub const SYS_mlock2: ::c_long = 325; +pub const SYS_copy_file_range: ::c_long = 326; +pub const SYS_preadv2: ::c_long = 327; +pub const SYS_pwritev2: ::c_long = 328; +pub const SYS_pkey_mprotect: ::c_long = 329; +pub const SYS_pkey_alloc: ::c_long = 330; +pub const SYS_pkey_free: ::c_long = 331; +pub const SYS_statx: ::c_long = 332; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +// offsets in mcontext_t.gregs from bits/signal.h +// GitHub repo: ifduyue/musl/ +// commit: b4b1e10364c8737a632be61582e05a8d3acf5690 +// file: arch/x86_64/bits/signal.h#L9-L56 +pub const REG_R8: ::c_int = 0; +pub const REG_R9: ::c_int = 1; +pub const REG_R10: ::c_int = 2; +pub const REG_R11: ::c_int = 3; +pub const REG_R12: ::c_int = 4; +pub const REG_R13: ::c_int = 5; +pub const REG_R14: ::c_int = 6; +pub const REG_R15: ::c_int = 7; +pub const REG_RDI: ::c_int = 8; +pub const REG_RSI: ::c_int = 9; +pub const REG_RBP: ::c_int = 10; +pub const REG_RBX: ::c_int = 11; +pub const REG_RDX: ::c_int = 12; +pub const REG_RAX: ::c_int = 13; +pub const REG_RCX: ::c_int = 14; +pub const REG_RSP: ::c_int = 15; +pub const REG_RIP: ::c_int = 16; +pub const REG_EFL: ::c_int = 17; +pub const REG_CSGSFS: ::c_int = 18; +pub const REG_ERR: ::c_int = 19; +pub const REG_TRAPNO: ::c_int = 20; +pub const REG_OLDMASK: ::c_int = 21; +pub const REG_CR2: ::c_int = 22; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_32BIT: ::c_int = 0x0040; +pub const O_APPEND: ::c_int = 1024; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_LARGEFILE: ::c_int = 0; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const PTRACE_SYSEMU: ::c_int = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 32; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const EDEADLK: ::c_int = 35; +pub const EDEADLOCK: ::c_int = EDEADLK; + +pub const EXTPROC: ::tcflag_t = 0x00010000; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs new file mode 100644 index 00000000..27c1d258 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs @@ -0,0 +1,241 @@ +#[inline] +pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int { + ::creat(path, mode) +} + +#[inline] +pub unsafe extern "C" fn fallocate64( + fd: ::c_int, + mode: ::c_int, + offset: ::off64_t, + len: ::off64_t, +) -> ::c_int { + ::fallocate(fd, mode, offset, len) +} + +#[inline] +pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int { + ::fgetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE { + ::fopen(pathname, mode) +} + +#[inline] +pub unsafe extern "C" fn freopen64( + pathname: *const ::c_char, + mode: *const ::c_char, + stream: *mut ::FILE, +) -> *mut ::FILE { + ::freopen(pathname, mode, stream) +} + +#[inline] +pub unsafe extern "C" fn fseeko64( + stream: *mut ::FILE, + offset: ::off64_t, + whence: ::c_int, +) -> ::c_int { + ::fseeko(stream, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int { + ::fsetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int { + ::fstat(fildes, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatat64( + fd: ::c_int, + path: *const ::c_char, + buf: *mut ::stat64, + flag: ::c_int, +) -> ::c_int { + ::fstatat(fd, path, buf as *mut _, flag) +} + +#[inline] +pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int { + ::fstatfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int { + ::fstatvfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t { + ::ftello(stream) +} + +#[inline] +pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int { + ::ftruncate(fd, length) +} + +#[inline] +pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int { + ::getrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t { + ::lseek(fd, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int { + ::lstat(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn mmap64( + addr: *mut ::c_void, + length: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: ::off64_t, +) -> *mut ::c_void { + ::mmap(addr, length, prot, flags, fd, offset) +} + +// These functions are variadic in the C ABI since the `mode` argument is "optional". Variadic +// `extern "C"` functions are unstable in Rust so we cannot write a shim function for these +// entrypoints. See https://github.com/rust-lang/rust/issues/44930. +// +// These aliases are mostly fine though, neither function takes a LFS64-namespaced type as an +// argument, nor do their names clash with any declared types. +pub use open as open64; +pub use openat as openat64; + +#[inline] +pub unsafe extern "C" fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advice: ::c_int, +) -> ::c_int { + ::posix_fadvise(fd, offset, len, advice) +} + +#[inline] +pub unsafe extern "C" fn posix_fallocate64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, +) -> ::c_int { + ::posix_fallocate(fd, offset, len) +} + +#[inline] +pub unsafe extern "C" fn pread64( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pread(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::preadv(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn prlimit64( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit64, + old_limit: *mut ::rlimit64, +) -> ::c_int { + ::prlimit(pid, resource, new_limit as *mut _, old_limit as *mut _) +} + +#[inline] +pub unsafe extern "C" fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pwrite(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::pwritev(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 { + ::readdir(dirp) as *mut _ +} + +#[inline] +pub unsafe extern "C" fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, +) -> ::c_int { + ::readdir_r(dirp, entry as *mut _, result as *mut _) +} + +#[inline] +pub unsafe extern "C" fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut ::off64_t, + count: ::size_t, +) -> ::ssize_t { + ::sendfile(out_fd, in_fd, offset, count) +} + +#[inline] +pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int { + ::setrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int { + ::stat(pathname, statbuf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int { + ::statfs(pathname, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int { + ::statvfs(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE { + ::tmpfile() +} + +#[inline] +pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int { + ::truncate(path, length) +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/mod.rs new file mode 100644 index 00000000..a4c1f708 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/musl/mod.rs @@ -0,0 +1,927 @@ +pub type pthread_t = *mut ::c_void; +pub type clock_t = c_long; +#[cfg_attr( + not(feature = "rustc-dep-of-std"), + deprecated( + since = "0.2.80", + note = "This type is changed to 64-bit in musl 1.2.0, \ + we'll follow that change in the future release. \ + See #1848 for more info." + ) +)] +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i64; + +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulonglong; +pub type fsfilcnt_t = ::c_ulonglong; +pub type rlim_t = ::c_ulonglong; + +cfg_if! { + if #[cfg(doc)] { + // Used in `linux::arch` to define ioctl constants. + pub(crate) type Ioctl = ::c_int; + } else { + #[doc(hidden)] + pub type Ioctl = ::c_int; + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_sigfault { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + si_addr: *mut ::c_void, + } + (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_si_value { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_timerid: ::c_int, + _si_overrun: ::c_int, + si_value: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_si_value)).si_value + } +} + +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, + } + impl ::Copy for sifields_sigchld {} + impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + self.sifields().sigchld.si_stime + } + } + } +} + +s! { + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + #[cfg(target_pointer_width = "32")] + __dummy4: [::c_char; 24], + #[cfg(target_pointer_width = "64")] + __dummy4: [::c_char; 16], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + #[cfg(target_pointer_width = "32")] + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct flock64 { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off64_t, + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } + + pub struct regex_t { + __re_nsub: ::size_t, + __opaque: *mut ::c_void, + __padding: [*mut ::c_void; 4usize], + __nsub2: ::size_t, + __padding2: ::c_char, + } + + pub struct rtentry { + pub rt_pad1: ::c_ulong, + pub rt_dst: ::sockaddr, + pub rt_gateway: ::sockaddr, + pub rt_genmask: ::sockaddr, + pub rt_flags: ::c_ushort, + pub rt_pad2: ::c_short, + pub rt_pad3: ::c_ulong, + pub rt_tos: ::c_uchar, + pub rt_class: ::c_uchar, + #[cfg(target_pointer_width = "64")] + pub rt_pad4: [::c_short; 3usize], + #[cfg(not(target_pointer_width = "64"))] + pub rt_pad4: [::c_short; 1usize], + pub rt_metric: ::c_short, + pub rt_dev: *mut ::c_char, + pub rt_mtu: ::c_ulong, + pub rt_window: ::c_ulong, + pub rt_irtt: ::c_ushort, + } + + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + pub struct Elf64_Chdr { + pub ch_type: ::Elf64_Word, + pub ch_reserved: ::Elf64_Word, + pub ch_size: ::Elf64_Xword, + pub ch_addralign: ::Elf64_Xword, + } + + pub struct Elf32_Chdr { + pub ch_type: ::Elf32_Word, + pub ch_size: ::Elf32_Word, + pub ch_addralign: ::Elf32_Word, + } + + pub struct timex { + pub modes: ::c_uint, + pub offset: ::c_long, + pub freq: ::c_long, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub status: ::c_int, + pub constant: ::c_long, + pub precision: ::c_long, + pub tolerance: ::c_long, + pub time: ::timeval, + pub tick: ::c_long, + pub ppsfreq: ::c_long, + pub jitter: ::c_long, + pub shift: ::c_int, + pub stabil: ::c_long, + pub jitcnt: ::c_long, + pub calcnt: ::c_long, + pub errcnt: ::c_long, + pub stbcnt: ::c_long, + pub tai: ::c_int, + pub __padding: [::c_int; 11], + } + + pub struct ntptimeval { + pub time: ::timeval, + pub maxerror: ::c_long, + pub esterror: ::c_long, + } + + // linux/if_xdp.h + + pub struct sockaddr_xdp { + pub sxdp_family: ::__u16, + pub sxdp_flags: ::__u16, + pub sxdp_ifindex: ::__u32, + pub sxdp_queue_id: ::__u32, + pub sxdp_shared_umem_fd: ::__u32, + } + + pub struct xdp_ring_offset { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + pub flags: ::__u64, + } + + pub struct xdp_mmap_offsets { + pub rx: xdp_ring_offset, + pub tx: xdp_ring_offset, + pub fr: xdp_ring_offset, + pub cr: xdp_ring_offset, + } + + pub struct xdp_ring_offset_v1 { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + } + + pub struct xdp_mmap_offsets_v1 { + pub rx: xdp_ring_offset_v1, + pub tx: xdp_ring_offset_v1, + pub fr: xdp_ring_offset_v1, + pub cr: xdp_ring_offset_v1, + } + + pub struct xdp_umem_reg { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + pub flags: ::__u32, + } + + pub struct xdp_umem_reg_v1 { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + } + + pub struct xdp_statistics { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + pub rx_ring_full: ::__u64, + pub rx_fill_ring_empty_descs: ::__u64, + pub tx_ring_empty_descs: ::__u64, + } + + pub struct xdp_statistics_v1 { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + } + + pub struct xdp_options { + pub flags: ::__u32, + } + + pub struct xdp_desc { + pub addr: ::__u64, + pub len: ::__u32, + pub options: ::__u32, + } +} + +s_no_extra_traits! { + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + // FIXME: musl added paddings and adjusted + // layout in 1.2.0 but our CI is still 1.1.24. + // So, I'm leaving some fields as cfg for now. + // ref. https://github.com/bminor/musl/commit/ + // 1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 + // + // OpenHarmony uses the musl 1.2 layout. + pub struct utmpx { + pub ut_type: ::c_short, + __ut_pad1: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; 32], + pub ut_id: [::c_char; 4], + pub ut_user: [::c_char; 32], + pub ut_host: [::c_char; 256], + pub ut_exit: __exit_status, + + #[cfg(target_env = "musl")] + pub ut_session: ::c_long, + + #[cfg(target_env = "ohos")] + #[cfg(target_endian = "little")] + pub ut_session: ::c_int, + #[cfg(target_env = "ohos")] + #[cfg(target_endian = "little")] + __ut_pad2: ::c_int, + + #[cfg(target_env = "ohos")] + #[cfg(not(target_endian = "little"))] + __ut_pad2: ::c_int, + #[cfg(target_env = "ohos")] + #[cfg(not(target_endian = "little"))] + pub ut_session: ::c_int, + + pub ut_tv: ::timeval, + pub ut_addr_v6: [::c_uint; 4], + __unused: [::c_char; 20], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sysinfo {} + + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + //&& self.__ut_pad1 == other.__ut_pad1 + && self.ut_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + //&& self.__ut_pad2 == other.__ut_pad2 + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__unused == other.__unused + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + //.field("__ut_pad1", &self.__ut_pad1) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + //FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + //.field("__ut_pad2", &self.__ut_pad2) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__unused", &self.__unused) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + //self.__ut_pad1.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + //self.__ut_pad2.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__unused.hash(state); + } + } + } +} + +// include/sys/mman.h +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +pub const MAP_HUGE_SHIFT: ::c_int = 26; +pub const MAP_HUGE_MASK: ::c_int = 0x3f; + +pub const MAP_HUGE_64KB: ::c_int = 16 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_512KB: ::c_int = 19 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_1MB: ::c_int = 20 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_2MB: ::c_int = 21 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_8MB: ::c_int = 23 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_16MB: ::c_int = 24 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_32MB: ::c_int = 25 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_256MB: ::c_int = 28 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_512MB: ::c_int = 29 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_1GB: ::c_int = 30 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_2GB: ::c_int = 31 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_16GB: ::c_int = 34 << MAP_HUGE_SHIFT; + +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const FILENAME_MAX: ::c_uint = 4096; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_EXEC: ::c_int = 0o10000000; +pub const O_SEARCH: ::c_int = 0o10000000; +pub const O_ACCMODE: ::c_int = 0o10000003; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; + +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; +pub const SOCK_PACKET: ::c_int = 10; + +pub const SOMAXCONN: ::c_int = 128; + +#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] +pub const SIGUNUSED: ::c_int = ::SIGSYS; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +pub const CPU_SETSIZE: ::c_int = 128; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_GETREGS: ::c_int = 12; +pub const PTRACE_SETREGS: ::c_int = 13; +pub const PTRACE_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_GETFPXREGS: ::c_int = 18; +pub const PTRACE_SETFPXREGS: ::c_int = 19; +pub const PTRACE_SYSCALL: ::c_int = 24; +pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; +pub const PTRACE_GETREGSET: ::c_int = 0x4204; +pub const PTRACE_SETREGSET: ::c_int = 0x4205; +pub const PTRACE_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; +pub const PTRACE_GETSIGMASK: ::c_uint = 0x420a; +pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const AF_XDP: ::c_int = 44; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; +pub const PF_XDP: ::c_int = AF_XDP; + +pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const PIDFD_NONBLOCK: ::c_uint = O_NONBLOCK as ::c_uint; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; + +pub const REG_OK: ::c_int = 0; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const ADJ_OFFSET: ::c_uint = 0x0001; +pub const ADJ_FREQUENCY: ::c_uint = 0x0002; +pub const ADJ_MAXERROR: ::c_uint = 0x0004; +pub const ADJ_ESTERROR: ::c_uint = 0x0008; +pub const ADJ_STATUS: ::c_uint = 0x0010; +pub const ADJ_TIMECONST: ::c_uint = 0x0020; +pub const ADJ_TAI: ::c_uint = 0x0080; +pub const ADJ_SETOFFSET: ::c_uint = 0x0100; +pub const ADJ_MICRO: ::c_uint = 0x1000; +pub const ADJ_NANO: ::c_uint = 0x2000; +pub const ADJ_TICK: ::c_uint = 0x4000; +pub const ADJ_OFFSET_SINGLESHOT: ::c_uint = 0x8001; +pub const ADJ_OFFSET_SS_READ: ::c_uint = 0xa001; +pub const MOD_OFFSET: ::c_uint = ADJ_OFFSET; +pub const MOD_FREQUENCY: ::c_uint = ADJ_FREQUENCY; +pub const MOD_MAXERROR: ::c_uint = ADJ_MAXERROR; +pub const MOD_ESTERROR: ::c_uint = ADJ_ESTERROR; +pub const MOD_STATUS: ::c_uint = ADJ_STATUS; +pub const MOD_TIMECONST: ::c_uint = ADJ_TIMECONST; +pub const MOD_CLKB: ::c_uint = ADJ_TICK; +pub const MOD_CLKA: ::c_uint = ADJ_OFFSET_SINGLESHOT; +pub const MOD_TAI: ::c_uint = ADJ_TAI; +pub const MOD_MICRO: ::c_uint = ADJ_MICRO; +pub const MOD_NANO: ::c_uint = ADJ_NANO; +pub const STA_PLL: ::c_int = 0x0001; +pub const STA_PPSFREQ: ::c_int = 0x0002; +pub const STA_PPSTIME: ::c_int = 0x0004; +pub const STA_FLL: ::c_int = 0x0008; +pub const STA_INS: ::c_int = 0x0010; +pub const STA_DEL: ::c_int = 0x0020; +pub const STA_UNSYNC: ::c_int = 0x0040; +pub const STA_FREQHOLD: ::c_int = 0x0080; +pub const STA_PPSSIGNAL: ::c_int = 0x0100; +pub const STA_PPSJITTER: ::c_int = 0x0200; +pub const STA_PPSWANDER: ::c_int = 0x0400; +pub const STA_PPSERROR: ::c_int = 0x0800; +pub const STA_CLOCKERR: ::c_int = 0x1000; +pub const STA_NANO: ::c_int = 0x2000; +pub const STA_MODE: ::c_int = 0x4000; +pub const STA_CLK: ::c_int = 0x8000; +pub const STA_RONLY: ::c_int = STA_PPSSIGNAL + | STA_PPSJITTER + | STA_PPSWANDER + | STA_PPSERROR + | STA_CLOCKERR + | STA_NANO + | STA_MODE + | STA_CLK; + +pub const TIME_OK: ::c_int = 0; +pub const TIME_INS: ::c_int = 1; +pub const TIME_DEL: ::c_int = 2; +pub const TIME_OOP: ::c_int = 3; +pub const TIME_WAIT: ::c_int = 4; +pub const TIME_ERROR: ::c_int = 5; +pub const TIME_BAD: ::c_int = TIME_ERROR; +pub const MAXTC: ::c_long = 6; + +pub const SOL_XDP: ::c_int = 283; + +// linux/if_xdp.h +pub const XDP_SHARED_UMEM: ::__u16 = 1 << 0; +pub const XDP_COPY: ::__u16 = 1 << 1; +pub const XDP_ZEROCOPY: ::__u16 = 1 << 2; +pub const XDP_USE_NEED_WAKEUP: ::__u16 = 1 << 3; +pub const XDP_USE_SG: ::__u16 = 1 << 4; + +pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG: ::__u32 = 1 << 0; + +pub const XDP_RING_NEED_WAKEUP: ::__u32 = 1 << 0; + +pub const XDP_MMAP_OFFSETS: ::c_int = 1; +pub const XDP_RX_RING: ::c_int = 2; +pub const XDP_TX_RING: ::c_int = 3; +pub const XDP_UMEM_REG: ::c_int = 4; +pub const XDP_UMEM_FILL_RING: ::c_int = 5; +pub const XDP_UMEM_COMPLETION_RING: ::c_int = 6; +pub const XDP_STATISTICS: ::c_int = 7; +pub const XDP_OPTIONS: ::c_int = 8; + +pub const XDP_OPTIONS_ZEROCOPY: ::__u32 = 1 << 0; + +pub const XDP_PGOFF_RX_RING: ::off_t = 0; +pub const XDP_PGOFF_TX_RING: ::off_t = 0x80000000; +pub const XDP_UMEM_PGOFF_FILL_RING: ::c_ulonglong = 0x100000000; +pub const XDP_UMEM_PGOFF_COMPLETION_RING: ::c_ulonglong = 0x180000000; + +pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: ::c_int = 48; +pub const XSK_UNALIGNED_BUF_ADDR_MASK: ::c_ulonglong = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1; + +pub const XDP_PKT_CONTD: ::__u32 = 1 << 0; + +cfg_if! { + if #[cfg(target_arch = "s390x")] { + pub const POSIX_FADV_DONTNEED: ::c_int = 6; + pub const POSIX_FADV_NOREUSE: ::c_int = 7; + } else { + pub const POSIX_FADV_DONTNEED: ::c_int = 4; + pub const POSIX_FADV_NOREUSE: ::c_int = 5; + } +} + +extern "C" { + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_uint, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_uint, + timeout: *mut ::timespec, + ) -> ::c_int; + + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn prlimit( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit, + old_limit: *mut ::rlimit, + ) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn ptrace(request: ::c_int, ...) -> ::c_long; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + // Musl targets need the `mask` argument of `fanotify_mark` be specified + // `::c_ulonglong` instead of `u64` or there will be a type mismatch between + // `long long unsigned int` and the expected `uint64_t`. + pub fn fanotify_mark( + fd: ::c_int, + flags: ::c_uint, + mask: ::c_ulonglong, + dirfd: ::c_int, + path: *const ::c_char, + ) -> ::c_int; + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; + + // Added in `musl` 1.1.20 + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); + // Added in `musl` 1.2.2 + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn adjtimex(buf: *mut ::timex) -> ::c_int; + pub fn clock_adjtime(clk_id: ::clockid_t, buf: *mut ::timex) -> ::c_int; + + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + + pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int; + pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + + pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + + pub fn asctime_r(tm: *const ::tm, buf: *mut ::c_char) -> *mut ::c_char; + + pub fn strftime( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + ) -> ::size_t; + pub fn strftime_l( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + locale: ::locale_t, + ) -> ::size_t; + pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; + + pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; +} + +// Alias to 64 to mimic glibc's LFS64 support +mod lfs64; +pub use self::lfs64::*; + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "powerpc64", + target_arch = "s390x", + target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } else if #[cfg(any(target_arch = "x86", + target_arch = "mips", + target_arch = "powerpc", + target_arch = "hexagon", + target_arch = "riscv32", + target_arch = "arm"))] { + mod b32; + pub use self::b32::*; + } else { } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/no_align.rs new file mode 100644 index 00000000..328a5cc4 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/no_align.rs @@ -0,0 +1,144 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutexattr_t { + #[cfg(any(target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64", + all(target_arch = "aarch64", + any(target_env = "musl", target_env = "ohos"))))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64", + all(target_arch = "aarch64", + any(target_env = "musl", target_env = "ohos")))))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __align: [::c_int; 0], + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + + pub struct pthread_barrierattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_BARRIERATTR_T], + } + + pub struct fanotify_event_metadata { + __align: [::c_long; 0], + pub event_len: __u32, + pub vers: __u8, + pub reserved: __u8, + pub metadata_len: __u16, + pub mask: __u64, + pub fd: ::c_int, + pub pid: ::c_int, + } + } + + s_no_extra_traits! { + pub struct pthread_cond_t { + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __align: [*const ::c_void; 0], + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_barrier_t { + #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_BARRIER_T], + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs new file mode 100644 index 00000000..e2e2cb84 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs @@ -0,0 +1,9 @@ +s! { + // linux/openat2.h + #[non_exhaustive] + pub struct open_how { + pub flags: ::__u64, + pub mode: ::__u64, + pub resolve: ::__u64, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/align.rs new file mode 100644 index 00000000..e6610bb7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/align.rs @@ -0,0 +1,28 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs new file mode 100644 index 00000000..4a0e0746 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs new file mode 100644 index 00000000..cff82f00 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs @@ -0,0 +1,925 @@ +pub type c_char = u8; +pub type wchar_t = ::c_uint; +pub type c_long = i32; +pub type c_ulong = u32; +pub type time_t = ::c_long; + +pub type clock_t = ::c_long; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type off_t = ::c_long; +pub type pthread_t = ::c_ulong; +pub type suseconds_t = ::c_long; + +pub type nlink_t = ::c_uint; +pub type blksize_t = ::c_long; +pub type blkcnt_t = ::c_long; + +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; + +s! { + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct pthread_attr_t { + __size: [::c_long; 9], + } + + pub struct stat { + pub st_dev: ::c_ulonglong, + __pad1: ::c_ushort, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + __pad2: ::c_ushort, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __unused4: ::c_ulong, + __unused5: ::c_ulong, + } + + pub struct stat64 + { + pub st_dev: ::c_ulonglong, + pub __pad1: ::c_uint, + pub __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + pub __pad2: ::c_uint, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino64_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } + + pub struct statfs { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_int, + pub f_frsize: ::c_int, + pub f_flags: ::c_int, + pub f_spare: [::c_int; 4], + } + + pub struct statfs64 { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_int, + pub f_frsize: ::c_int, + pub f_flags: ::c_int, + pub f_spare: [::c_int; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct sigset_t { + __val: [::c_ulong; 2], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_ulong, + pub sa_restorer: ::Option, + pub sa_mask: sigset_t, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_ulong, + pub msg_rtime: ::time_t, + __unused2: ::c_ulong, + pub msg_ctime: ::time_t, + __unused3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong, + } +} + +pub const O_CLOEXEC: ::c_int = 0o2000000; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_COND_COMPAT_T: usize = 12; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const NCCS: usize = 32; + +// I wasn't able to find those constants +// in uclibc build environment for armv7 +pub const MAP_HUGETLB: ::c_int = 0x040000; // from linux/other/mod.rs + +// autogenerated constants with hand tuned types +pub const B0: ::speed_t = 0; +pub const B1000000: ::speed_t = 0x1008; +pub const B110: ::speed_t = 0x3; +pub const B115200: ::speed_t = 0x1002; +pub const B1152000: ::speed_t = 0x1009; +pub const B1200: ::speed_t = 0x9; +pub const B134: ::speed_t = 0x4; +pub const B150: ::speed_t = 0x5; +pub const B1500000: ::speed_t = 0x100a; +pub const B1800: ::speed_t = 0xa; +pub const B19200: ::speed_t = 0xe; +pub const B200: ::speed_t = 0x6; +pub const B2000000: ::speed_t = 0x100b; +pub const B230400: ::speed_t = 0x1003; +pub const B2400: ::speed_t = 0xb; +pub const B2500000: ::speed_t = 0x100c; +pub const B300: ::speed_t = 0x7; +pub const B3000000: ::speed_t = 0x100d; +pub const B3500000: ::speed_t = 0x100e; +pub const B38400: ::speed_t = 0xf; +pub const B4000000: ::speed_t = 0x100f; +pub const B460800: ::speed_t = 0x1004; +pub const B4800: ::speed_t = 0xc; +pub const B50: ::speed_t = 0x1; +pub const B500000: ::speed_t = 0x1005; +pub const B57600: ::speed_t = 0x1001; +pub const B576000: ::speed_t = 0x1006; +pub const B600: ::speed_t = 0x8; +pub const B75: ::speed_t = 0x2; +pub const B921600: ::speed_t = 0x1007; +pub const B9600: ::speed_t = 0xd; +pub const BS1: ::c_int = 0x2000; +pub const BSDLY: ::c_int = 0x2000; +pub const CBAUD: ::tcflag_t = 0x100f; +pub const CBAUDEX: ::tcflag_t = 0x1000; +pub const CIBAUD: ::tcflag_t = 0x100f0000; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const CPU_SETSIZE: ::c_int = 0x400; +pub const CR1: ::c_int = 0x200; +pub const CR2: ::c_int = 0x400; +pub const CR3: ::c_int = 0x600; +pub const CRDLY: ::c_int = 0x600; +pub const CREAD: ::tcflag_t = 0x80; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const EADDRINUSE: ::c_int = 0x62; +pub const EADDRNOTAVAIL: ::c_int = 0x63; +pub const EADV: ::c_int = 0x44; +pub const EAFNOSUPPORT: ::c_int = 0x61; +pub const EALREADY: ::c_int = 0x72; +pub const EBADE: ::c_int = 0x34; +pub const EBADFD: ::c_int = 0x4d; +pub const EBADMSG: ::c_int = 0x4a; +pub const EBADR: ::c_int = 0x35; +pub const EBADRQC: ::c_int = 0x38; +pub const EBADSLT: ::c_int = 0x39; +pub const EBFONT: ::c_int = 0x3b; +pub const ECANCELED: ::c_int = 0x7d; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHRNG: ::c_int = 0x2c; +pub const ECOMM: ::c_int = 0x46; +pub const ECONNABORTED: ::c_int = 0x67; +pub const ECONNREFUSED: ::c_int = 0x6f; +pub const ECONNRESET: ::c_int = 0x68; +pub const EDEADLK: ::c_int = 0x23; +pub const EDESTADDRREQ: ::c_int = 0x59; +pub const EDOTDOT: ::c_int = 0x49; +pub const EDQUOT: ::c_int = 0x7a; +pub const EFD_CLOEXEC: ::c_int = 0x80000; +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const EHOSTDOWN: ::c_int = 0x70; +pub const EHOSTUNREACH: ::c_int = 0x71; +pub const EHWPOISON: ::c_int = 0x85; +pub const EIDRM: ::c_int = 0x2b; +pub const EILSEQ: ::c_int = 0x54; +pub const EINPROGRESS: ::c_int = 0x73; +pub const EISCONN: ::c_int = 0x6a; +pub const EISNAM: ::c_int = 0x78; +pub const EKEYEXPIRED: ::c_int = 0x7f; +pub const EKEYREJECTED: ::c_int = 0x81; +pub const EKEYREVOKED: ::c_int = 0x80; +pub const EL2HLT: ::c_int = 0x33; +pub const EL2NSYNC: ::c_int = 0x2d; +pub const EL3HLT: ::c_int = 0x2e; +pub const EL3RST: ::c_int = 0x2f; +pub const ELIBACC: ::c_int = 0x4f; +pub const ELIBBAD: ::c_int = 0x50; +pub const ELIBEXEC: ::c_int = 0x53; +pub const ELIBMAX: ::c_int = 0x52; +pub const ELIBSCN: ::c_int = 0x51; +pub const ELNRNG: ::c_int = 0x30; +pub const ELOOP: ::c_int = 0x28; +pub const EMEDIUMTYPE: ::c_int = 0x7c; +pub const EMSGSIZE: ::c_int = 0x5a; +pub const EMULTIHOP: ::c_int = 0x48; +pub const ENAMETOOLONG: ::c_int = 0x24; +pub const ENAVAIL: ::c_int = 0x77; +pub const ENETDOWN: ::c_int = 0x64; +pub const ENETRESET: ::c_int = 0x66; +pub const ENETUNREACH: ::c_int = 0x65; +pub const ENOANO: ::c_int = 0x37; +pub const ENOBUFS: ::c_int = 0x69; +pub const ENOCSI: ::c_int = 0x32; +pub const ENODATA: ::c_int = 0x3d; +pub const ENOKEY: ::c_int = 0x7e; +pub const ENOLCK: ::c_int = 0x25; +pub const ENOLINK: ::c_int = 0x43; +pub const ENOMEDIUM: ::c_int = 0x7b; +pub const ENOMSG: ::c_int = 0x2a; +pub const ENONET: ::c_int = 0x40; +pub const ENOPKG: ::c_int = 0x41; +pub const ENOPROTOOPT: ::c_int = 0x5c; +pub const ENOSR: ::c_int = 0x3f; +pub const ENOSTR: ::c_int = 0x3c; +pub const ENOSYS: ::c_int = 0x26; +pub const ENOTCONN: ::c_int = 0x6b; +pub const ENOTEMPTY: ::c_int = 0x27; +pub const ENOTNAM: ::c_int = 0x76; +pub const ENOTRECOVERABLE: ::c_int = 0x83; +pub const ENOTSOCK: ::c_int = 0x58; +pub const ENOTUNIQ: ::c_int = 0x4c; +pub const EOPNOTSUPP: ::c_int = 0x5f; +pub const EOVERFLOW: ::c_int = 0x4b; +pub const EOWNERDEAD: ::c_int = 0x82; +pub const EPFNOSUPPORT: ::c_int = 0x60; +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +pub const EPROTO: ::c_int = 0x47; +pub const EPROTONOSUPPORT: ::c_int = 0x5d; +pub const EPROTOTYPE: ::c_int = 0x5b; +pub const EREMCHG: ::c_int = 0x4e; +pub const EREMOTE: ::c_int = 0x42; +pub const EREMOTEIO: ::c_int = 0x79; +pub const ERESTART: ::c_int = 0x55; +pub const ERFKILL: ::c_int = 0x84; +pub const ESHUTDOWN: ::c_int = 0x6c; +pub const ESOCKTNOSUPPORT: ::c_int = 0x5e; +pub const ESRMNT: ::c_int = 0x45; +pub const ESTALE: ::c_int = 0x74; +pub const ESTRPIPE: ::c_int = 0x56; +pub const ETIME: ::c_int = 0x3e; +pub const ETIMEDOUT: ::c_int = 0x6e; +pub const ETOOMANYREFS: ::c_int = 0x6d; +pub const EUCLEAN: ::c_int = 0x75; +pub const EUNATCH: ::c_int = 0x31; +pub const EUSERS: ::c_int = 0x57; +pub const EXFULL: ::c_int = 0x36; +pub const FF1: ::c_int = 0x8000; +pub const FFDLY: ::c_int = 0x8000; +pub const FLUSHO: ::tcflag_t = 0x1000; +pub const F_GETLK: ::c_int = 0x5; +pub const F_SETLK: ::c_int = 0x6; +pub const F_SETLKW: ::c_int = 0x7; +pub const HUPCL: ::tcflag_t = 0x400; +pub const ICANON: ::tcflag_t = 0x2; +pub const IEXTEN: ::tcflag_t = 0x8000; +pub const ISIG: ::tcflag_t = 0x1; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const IXON: ::tcflag_t = 0x400; +pub const MAP_ANON: ::c_int = 0x20; +pub const MAP_ANONYMOUS: ::c_int = 0x20; +pub const MAP_DENYWRITE: ::c_int = 0x800; +pub const MAP_EXECUTABLE: ::c_int = 0x1000; +pub const MAP_GROWSDOWN: ::c_int = 0x100; +pub const MAP_LOCKED: ::c_int = 0x2000; +pub const MAP_NONBLOCK: ::c_int = 0x10000; +pub const MAP_NORESERVE: ::c_int = 0x4000; +pub const MAP_POPULATE: ::c_int = 0x8000; +pub const MAP_STACK: ::c_int = 0x20000; +pub const NLDLY: ::tcflag_t = 0x100; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const OLCUC: ::tcflag_t = 0x2; +pub const ONLCR: ::tcflag_t = 0x4; +pub const O_ACCMODE: ::c_int = 0x3; +pub const O_APPEND: ::c_int = 0x400; +pub const O_ASYNC: ::c_int = 0o20000; +pub const O_CREAT: ::c_int = 0x40; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_DSYNC: ::c_int = O_SYNC; +pub const O_EXCL: ::c_int = 0x80; +pub const O_FSYNC: ::c_int = O_SYNC; +pub const O_LARGEFILE: ::c_int = 0o400000; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_NOCTTY: ::c_int = 0x100; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x800; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_RSYNC: ::c_int = O_SYNC; +pub const O_SYNC: ::c_int = 0o10000; +pub const O_TRUNC: ::c_int = 0x200; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const POLLWRBAND: ::c_short = 0x200; +pub const POLLWRNORM: ::c_short = 0x100; +pub const PTHREAD_STACK_MIN: ::size_t = 16384; +pub const RTLD_GLOBAL: ::c_int = 0x00100; +pub const PIDFD_NONBLOCK: ::c_int = 0x800; + +// These are typed unsigned to match sigaction +pub const SA_NOCLDSTOP: ::c_ulong = 0x1; +pub const SA_NOCLDWAIT: ::c_ulong = 0x2; +pub const SA_SIGINFO: ::c_ulong = 0x4; +pub const SA_NODEFER: ::c_ulong = 0x40000000; +pub const SA_ONSTACK: ::c_ulong = 0x8000000; +pub const SA_RESETHAND: ::c_ulong = 0x80000000; +pub const SA_RESTART: ::c_ulong = 0x10000000; + +pub const SFD_CLOEXEC: ::c_int = 0x80000; +pub const SFD_NONBLOCK: ::c_int = 0x800; +pub const SIGBUS: ::c_int = 0x7; +pub const SIGCHLD: ::c_int = 0x11; +pub const SIGCONT: ::c_int = 0x12; +pub const SIGIO: ::c_int = 0x1d; +pub const SIGPROF: ::c_int = 0x1b; +pub const SIGPWR: ::c_int = 0x1e; +pub const SIGSTKFLT: ::c_int = 0x10; +pub const SIGSTKSZ: ::size_t = 8192; +pub const SIGSTOP: ::c_int = 0x13; +pub const SIGSYS: ::c_int = 0x1f; +pub const SIGTSTP: ::c_int = 0x14; +pub const SIGTTIN: ::c_int = 0x15; +pub const SIGTTOU: ::c_int = 0x16; +pub const SIGURG: ::c_int = 0x17; +pub const SIGUSR1: ::c_int = 0xa; +pub const SIGUSR2: ::c_int = 0xc; +pub const SIGVTALRM: ::c_int = 0x1a; +pub const SIGWINCH: ::c_int = 0x1c; +pub const SIGXCPU: ::c_int = 0x18; +pub const SIGXFSZ: ::c_int = 0x19; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_SETMASK: ::c_int = 0x2; +pub const SIG_UNBLOCK: ::c_int = 0x1; +pub const SOCK_DGRAM: ::c_int = 0x2; +pub const SOCK_NONBLOCK: ::c_int = 0o0004000; +pub const SOCK_SEQPACKET: ::c_int = 0x5; +pub const SOCK_STREAM: ::c_int = 0x1; + +pub const TAB1: ::c_int = 0x800; +pub const TAB2: ::c_int = 0x1000; +pub const TAB3: ::c_int = 0x1800; +pub const TABDLY: ::c_int = 0x1800; +pub const TCSADRAIN: ::c_int = 0x1; +pub const TCSAFLUSH: ::c_int = 0x2; +pub const TCSANOW: ::c_int = 0; +pub const TOSTOP: ::tcflag_t = 0x100; +pub const VDISCARD: usize = 0xd; +pub const VEOF: usize = 0x4; +pub const VEOL: usize = 0xb; +pub const VEOL2: usize = 0x10; +pub const VMIN: usize = 0x6; +pub const VREPRINT: usize = 0xc; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VSUSP: usize = 0xa; +pub const VSWTC: usize = 0x7; +pub const VT1: ::c_int = 0x4000; +pub const VTDLY: ::c_int = 0x4000; +pub const VTIME: usize = 0x5; +pub const VWERASE: usize = 0xe; +pub const XTABS: ::tcflag_t = 0x1800; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; + +// Syscall table is copied from src/unix/notbsd/linux/musl/b32/arm.rs +pub const SYS_restart_syscall: ::c_long = 0; +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_setreuid: ::c_long = 70; +pub const SYS_setregid: ::c_long = 71; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::c_long = 142; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::c_long = 171; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_chown: ::c_long = 182; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::c_long = 191; +pub const SYS_mmap2: ::c_long = 192; +pub const SYS_truncate64: ::c_long = 193; +pub const SYS_ftruncate64: ::c_long = 194; +pub const SYS_stat64: ::c_long = 195; +pub const SYS_lstat64: ::c_long = 196; +pub const SYS_fstat64: ::c_long = 197; +pub const SYS_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +pub const SYS_pwritev2: ::c_long = 393; +pub const SYS_pkey_mprotect: ::c_long = 394; +pub const SYS_pkey_alloc: ::c_long = 395; +pub const SYS_pkey_free: ::c_long = 396; +// FIXME: should be a `c_long` too, but a bug slipped in. +pub const SYS_statx: ::c_int = 397; +pub const SYS_pidfd_send_signal: ::c_long = 424; +pub const SYS_io_uring_setup: ::c_long = 425; +pub const SYS_io_uring_enter: ::c_long = 426; +pub const SYS_io_uring_register: ::c_long = 427; +pub const SYS_open_tree: ::c_long = 428; +pub const SYS_move_mount: ::c_long = 429; +pub const SYS_fsopen: ::c_long = 430; +pub const SYS_fsconfig: ::c_long = 431; +pub const SYS_fsmount: ::c_long = 432; +pub const SYS_fspick: ::c_long = 433; +pub const SYS_pidfd_open: ::c_long = 434; +pub const SYS_clone3: ::c_long = 435; +pub const SYS_close_range: ::c_long = 436; +pub const SYS_openat2: ::c_long = 437; +pub const SYS_pidfd_getfd: ::c_long = 438; +pub const SYS_faccessat2: ::c_long = 439; +pub const SYS_process_madvise: ::c_long = 440; +pub const SYS_epoll_pwait2: ::c_long = 441; +pub const SYS_mount_setattr: ::c_long = 442; +pub const SYS_quotactl_fd: ::c_long = 443; +pub const SYS_landlock_create_ruleset: ::c_long = 444; +pub const SYS_landlock_add_rule: ::c_long = 445; +pub const SYS_landlock_restrict_self: ::c_long = 446; +pub const SYS_memfd_secret: ::c_long = 447; +pub const SYS_process_mrelease: ::c_long = 448; +pub const SYS_futex_waitv: ::c_long = 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs new file mode 100644 index 00000000..e32bf673 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs new file mode 100644 index 00000000..4a0e0746 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs new file mode 100644 index 00000000..a5aca85a --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs @@ -0,0 +1,692 @@ +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type clock_t = i32; +pub type time_t = i32; +pub type suseconds_t = i32; +pub type wchar_t = i32; +pub type off_t = i32; +pub type ino_t = u32; +pub type blkcnt_t = i32; +pub type blksize_t = i32; +pub type nlink_t = u32; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + st_pad1: [::c_long; 2], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_pad2: [::c_long; 1], + pub st_size: ::off_t, + st_pad3: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + st_pad1: [::c_long; 2], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + st_pad2: [::c_long; 2], + pub st_size: ::off64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 14], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_favail: ::fsfilcnt64_t, + pub f_fsid: ::c_ulong, + pub __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigaction { + pub sa_flags: ::c_uint, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + _restorer: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct sigset_t { + __val: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __glibc_reserved1: ::c_ulong, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved1: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved2: ::c_ulong, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved2: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved3: ::c_ulong, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_files: ::fsblkcnt64_t, + pub f_ffree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 5], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_sysid: ::c_long, + pub l_pid: ::pid_t, + pad: [::c_long; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } +} + +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS__newselect: ::c_long = 4000 + 142; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_pread64: ::c_long = 4000 + 200; +pub const SYS_pwrite64: ::c_long = 4000 + 201; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_fadvise64: ::c_long = 4000 + 254; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_fstatat64: ::c_long = 4000 + 293; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +pub const SYS_pwritev2: ::c_long = 4000 + 362; +pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; +pub const SYS_pkey_alloc: ::c_long = 4000 + 364; +pub const SYS_pkey_free: ::c_long = 4000 + 365; +pub const SYS_statx: ::c_long = 4000 + 366; +pub const SYS_pidfd_send_signal: ::c_long = 4000 + 424; +pub const SYS_io_uring_setup: ::c_long = 4000 + 425; +pub const SYS_io_uring_enter: ::c_long = 4000 + 426; +pub const SYS_io_uring_register: ::c_long = 4000 + 427; +pub const SYS_open_tree: ::c_long = 4000 + 428; +pub const SYS_move_mount: ::c_long = 4000 + 429; +pub const SYS_fsopen: ::c_long = 4000 + 430; +pub const SYS_fsconfig: ::c_long = 4000 + 431; +pub const SYS_fsmount: ::c_long = 4000 + 432; +pub const SYS_fspick: ::c_long = 4000 + 433; +pub const SYS_pidfd_open: ::c_long = 4000 + 434; +pub const SYS_clone3: ::c_long = 4000 + 435; +pub const SYS_close_range: ::c_long = 4000 + 436; +pub const SYS_openat2: ::c_long = 4000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 4000 + 438; +pub const SYS_faccessat2: ::c_long = 4000 + 439; +pub const SYS_process_madvise: ::c_long = 4000 + 440; +pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; +pub const SYS_mount_setattr: ::c_long = 4000 + 442; +pub const SYS_quotactl_fd: ::c_long = 4000 + 443; +pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; +pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; +pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; +pub const SYS_memfd_secret: ::c_long = 4000 + 447; +pub const SYS_process_mrelease: ::c_long = 4000 + 448; +pub const SYS_futex_waitv: ::c_long = 4000 + 449; +pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; + +#[link(name = "util")] +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn glob64( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t, + ) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + pub fn pthread_attr_getaffinity_np( + attr: *const ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t, + ) -> ::c_int; + pub fn pthread_attr_setaffinity_np( + attr: *mut ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs new file mode 100644 index 00000000..e32bf673 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs new file mode 100644 index 00000000..21e21907 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + __size: [::c_char; 32], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs new file mode 100644 index 00000000..8ca100fc --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs @@ -0,0 +1,207 @@ +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = u64; +pub type nlink_t = u64; +pub type off_t = i64; +pub type suseconds_t = i64; +pub type time_t = i64; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_ulong; 1], + pub st_size: ::off_t, + st_pad3: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad4: ::c_long, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 7], + } + + pub struct stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 7], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + _restorer: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct sigset_t { + __size: [::c_ulong; 16], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } +} + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +pub const SYS_gettid: ::c_long = 5178; // Valid for n64 + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs new file mode 100644 index 00000000..8909114c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs @@ -0,0 +1,7 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs new file mode 100644 index 00000000..56bfcc5d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs @@ -0,0 +1,310 @@ +pub type pthread_t = ::c_ulong; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const TMP_MAX: ::c_uint = 238328; +pub const _SC_2_C_VERSION: ::c_int = 96; +pub const O_ACCMODE: ::c_int = 3; +pub const O_DIRECT: ::c_int = 0x8000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_NOATIME: ::c_int = 0x40000; +pub const O_PATH: ::c_int = 0o010000000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x10; +pub const O_RSYNC: ::c_int = 0x10; +pub const O_DSYNC: ::c_int = 0x10; +pub const O_FSYNC: ::c_int = 0x10; +pub const O_ASYNC: ::c_int = 0x1000; +pub const O_LARGEFILE: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x80; + +pub const SOCK_NONBLOCK: ::c_int = 128; +pub const PIDFD_NONBLOCK: ::c_int = 128; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const FFDLY: ::c_int = 0o0100000; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_ANONYMOUS: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_POPULATE: ::c_int = 0x10000; +pub const MAP_NONBLOCK: ::c_int = 0x20000; +pub const MAP_STACK: ::c_int = 0x40000; + +pub const NLDLY: ::tcflag_t = 0o0000400; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SA_ONSTACK: ::c_uint = 0x08000000; +pub const SA_SIGINFO: ::c_uint = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGWINCH: ::c_int = 20; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGCONT: ::c_int = 25; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGURG: ::c_int = 21; +pub const SIGIO: ::c_int = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const PTHREAD_STACK_MIN: ::size_t = 16384; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const TCSANOW: ::c_int = 0x540e; +pub const TCSADRAIN: ::c_int = 0x540f; +pub const TCSAFLUSH: ::c_int = 0x5410; + +pub const CPU_SETSIZE: ::c_int = 0x400; + +pub const EFD_NONBLOCK: ::c_int = 0x80; + +pub const F_GETLK: ::c_int = 14; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; + +pub const SFD_NONBLOCK: ::c_int = 0x80; + +pub const RTLD_GLOBAL: ::c_int = 0x4; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const CBAUDEX: ::tcflag_t = 0o0010000; +pub const CIBAUD: ::tcflag_t = 0o002003600000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const TABDLY: ::tcflag_t = 0o0014000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const FF1: ::tcflag_t = 0x00008000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const BSDLY: ::tcflag_t = 0o0020000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const VWERASE: usize = 14; +pub const XTABS: ::tcflag_t = 0o0014000; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSWTC: usize = 7; +pub const VTDLY: ::c_int = 0o0040000; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const OLCUC: ::tcflag_t = 0o0000002; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CRDLY: ::c_int = 0o0003000; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; + +pub const MAP_HUGETLB: ::c_int = 0x80000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +cfg_if! { + if #[cfg(target_arch = "mips")] { + mod mips32; + pub use self::mips32::*; + } else if #[cfg(target_arch = "mips64")] { + mod mips64; + pub use self::mips64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs new file mode 100644 index 00000000..48b03e9e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs @@ -0,0 +1,392 @@ +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type regoff_t = ::c_int; +pub type rlim_t = ::c_ulong; +pub type __rlimit_resource_t = ::c_ulong; +pub type __priority_which_t = ::c_uint; + +cfg_if! { + if #[cfg(doc)] { + // Used in `linux::arch` to define ioctl constants. + pub(crate) type Ioctl = ::c_ulong; + } else { + #[doc(hidden)] + pub type Ioctl = ::c_ulong; + } +} + +s! { + pub struct statvfs { // Different than GNU! + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + #[cfg(target_pointer_width = "32")] + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct regex_t { + __buffer: *mut ::c_void, + __allocated: ::size_t, + __used: ::size_t, + __syntax: ::c_ulong, + __fastmap: *mut ::c_char, + __translate: *mut ::c_char, + __re_nsub: ::size_t, + __bitfield: u8, + } + + pub struct rtentry { + pub rt_pad1: ::c_ulong, + pub rt_dst: ::sockaddr, + pub rt_gateway: ::sockaddr, + pub rt_genmask: ::sockaddr, + pub rt_flags: ::c_ushort, + pub rt_pad2: ::c_short, + pub rt_pad3: ::c_ulong, + pub rt_tos: ::c_uchar, + pub rt_class: ::c_uchar, + #[cfg(target_pointer_width = "64")] + pub rt_pad4: [::c_short; 3usize], + #[cfg(not(target_pointer_width = "64"))] + pub rt_pad4: ::c_short, + pub rt_metric: ::c_short, + pub rt_dev: *mut ::c_char, + pub rt_mtu: ::c_ulong, + pub rt_window: ::c_ulong, + pub rt_irtt: ::c_ushort, + } + + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + pub struct ptrace_peeksiginfo_args { + pub off: ::__u64, + pub flags: ::__u32, + pub nr: ::__s32, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_sigfault { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + si_addr: *mut ::c_void, + } + (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_si_value { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_timerid: ::c_int, + _si_overrun: ::c_int, + si_value: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_si_value)).si_value + } +} + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const AF_VSOCK: ::c_int = 40; + +// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the +// following are only available on newer Linux versions than the versions +// currently used in CI in some configurations, so we define them here. +pub const BINDERFS_SUPER_MAGIC: ::c_long = 0x6c6f6f70; +pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_GETREGS: ::c_int = 12; +pub const PTRACE_SETREGS: ::c_int = 13; +pub const PTRACE_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_GETFPXREGS: ::c_int = 18; +pub const PTRACE_SETFPXREGS: ::c_int = 19; +pub const PTRACE_SYSCALL: ::c_int = 24; +pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; +pub const PTRACE_GETREGSET: ::c_int = 0x4204; +pub const PTRACE_SETREGSET: ::c_int = 0x4205; +pub const PTRACE_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +// These are different than GNU! +pub const LC_CTYPE: ::c_int = 0; +pub const LC_NUMERIC: ::c_int = 1; +pub const LC_TIME: ::c_int = 3; +pub const LC_COLLATE: ::c_int = 4; +pub const LC_MONETARY: ::c_int = 2; +pub const LC_MESSAGES: ::c_int = 5; +pub const LC_ALL: ::c_int = 6; +// end different section + +// MS_ flags for mount(2) +pub const MS_RMT_MASK: ::c_ulong = ::MS_RDONLY | ::MS_SYNCHRONOUS | ::MS_MANDLOCK | ::MS_I_VERSION; + +pub const ENOTSUP: ::c_int = EOPNOTSUPP; + +pub const IPV6_JOIN_GROUP: ::c_int = 20; +pub const IPV6_LEAVE_GROUP: ::c_int = 21; + +// These are different from GNU +pub const ABDAY_1: ::nl_item = 0x300; +pub const ABDAY_2: ::nl_item = 0x301; +pub const ABDAY_3: ::nl_item = 0x302; +pub const ABDAY_4: ::nl_item = 0x303; +pub const ABDAY_5: ::nl_item = 0x304; +pub const ABDAY_6: ::nl_item = 0x305; +pub const ABDAY_7: ::nl_item = 0x306; +pub const DAY_1: ::nl_item = 0x307; +pub const DAY_2: ::nl_item = 0x308; +pub const DAY_3: ::nl_item = 0x309; +pub const DAY_4: ::nl_item = 0x30A; +pub const DAY_5: ::nl_item = 0x30B; +pub const DAY_6: ::nl_item = 0x30C; +pub const DAY_7: ::nl_item = 0x30D; +pub const ABMON_1: ::nl_item = 0x30E; +pub const ABMON_2: ::nl_item = 0x30F; +pub const ABMON_3: ::nl_item = 0x310; +pub const ABMON_4: ::nl_item = 0x311; +pub const ABMON_5: ::nl_item = 0x312; +pub const ABMON_6: ::nl_item = 0x313; +pub const ABMON_7: ::nl_item = 0x314; +pub const ABMON_8: ::nl_item = 0x315; +pub const ABMON_9: ::nl_item = 0x316; +pub const ABMON_10: ::nl_item = 0x317; +pub const ABMON_11: ::nl_item = 0x318; +pub const ABMON_12: ::nl_item = 0x319; +pub const MON_1: ::nl_item = 0x31A; +pub const MON_2: ::nl_item = 0x31B; +pub const MON_3: ::nl_item = 0x31C; +pub const MON_4: ::nl_item = 0x31D; +pub const MON_5: ::nl_item = 0x31E; +pub const MON_6: ::nl_item = 0x31F; +pub const MON_7: ::nl_item = 0x320; +pub const MON_8: ::nl_item = 0x321; +pub const MON_9: ::nl_item = 0x322; +pub const MON_10: ::nl_item = 0x323; +pub const MON_11: ::nl_item = 0x324; +pub const MON_12: ::nl_item = 0x325; +pub const AM_STR: ::nl_item = 0x326; +pub const PM_STR: ::nl_item = 0x327; +pub const D_T_FMT: ::nl_item = 0x328; +pub const D_FMT: ::nl_item = 0x329; +pub const T_FMT: ::nl_item = 0x32A; +pub const T_FMT_AMPM: ::nl_item = 0x32B; +pub const ERA: ::nl_item = 0x32C; +pub const ERA_D_FMT: ::nl_item = 0x32E; +pub const ALT_DIGITS: ::nl_item = 0x32F; +pub const ERA_D_T_FMT: ::nl_item = 0x330; +pub const ERA_T_FMT: ::nl_item = 0x331; +pub const CODESET: ::nl_item = 10; +pub const CRNCYSTR: ::nl_item = 0x215; +pub const RADIXCHAR: ::nl_item = 0x100; +pub const THOUSEP: ::nl_item = 0x101; +pub const NOEXPR: ::nl_item = 0x501; +pub const YESSTR: ::nl_item = 0x502; +pub const NOSTR: ::nl_item = 0x503; + +// Different than Gnu. +pub const FILENAME_MAX: ::c_uint = 4095; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const SOMAXCONN: ::c_int = 128; + +pub const ST_RELATIME: ::c_ulong = 4096; + +pub const AF_NFC: ::c_int = PF_NFC; +pub const BUFSIZ: ::c_int = 4096; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const EXTA: ::c_uint = B19200; +pub const EXTB: ::c_uint = B38400; +pub const EXTPROC: ::tcflag_t = 0200000; +pub const FOPEN_MAX: ::c_int = 16; +pub const F_GETOWN: ::c_int = 9; +pub const F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; +pub const F_RDLCK: ::c_int = 0; +pub const F_SETOWN: ::c_int = 8; +pub const F_UNLCK: ::c_int = 2; +pub const F_WRLCK: ::c_int = 1; +pub const IPV6_MULTICAST_ALL: ::c_int = 29; +pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30; +pub const MAP_HUGE_SHIFT: ::c_int = 26; +pub const MAP_HUGE_MASK: ::c_int = 0x3f; +pub const MAP_HUGE_64KB: ::c_int = 16 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_512KB: ::c_int = 19 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_1MB: ::c_int = 20 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_2MB: ::c_int = 21 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_8MB: ::c_int = 23 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_16MB: ::c_int = 24 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_32MB: ::c_int = 25 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_256MB: ::c_int = 28 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_512MB: ::c_int = 29 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_1GB: ::c_int = 30 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_2GB: ::c_int = 31 << MAP_HUGE_SHIFT; +pub const MAP_HUGE_16GB: ::c_int = 34 << MAP_HUGE_SHIFT; +pub const MINSIGSTKSZ: ::c_int = 2048; +pub const MSG_COPY: ::c_int = 040000; +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; +pub const PACKET_MR_UNICAST: ::c_int = 3; +pub const PF_NFC: ::c_int = 39; +pub const PF_VSOCK: ::c_int = 40; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; +pub const PTRACE_EVENT_STOP: ::c_int = 128; +pub const PTRACE_GETSIGMASK: ::c_uint = 0x420a; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; +pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b; +pub const RTLD_NOLOAD: ::c_int = 0x00004; +pub const RUSAGE_THREAD: ::c_int = 1; +pub const SHM_EXEC: ::c_int = 0100000; +pub const SIGPOLL: ::c_int = SIGIO; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const UDP_GRO: ::c_int = 104; +pub const UDP_SEGMENT: ::c_int = 103; +pub const YESEXPR: ::c_int = ((5) << 8) | (0); + +extern "C" { + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + + pub fn pthread_rwlockattr_getkind_np( + attr: *const ::pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut ::pthread_rwlockattr_t, + val: ::c_int, + ) -> ::c_int; + + pub fn ptrace(request: ::c_uint, ...) -> ::c_long; + + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::pid_t; + + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + pub fn pwritev( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + pub fn preadv( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + + pub fn sethostid(hostid: ::c_long) -> ::c_int; + pub fn fanotify_mark( + fd: ::c_int, + flags: ::c_uint, + mask: u64, + dirfd: ::c_int, + path: *const ::c_char, + ) -> ::c_int; + pub fn getrlimit64(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit64) -> ::c_int; + pub fn setrlimit64(resource: ::__rlimit_resource_t, rlim: *const ::rlimit64) -> ::c_int; + pub fn getrlimit(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::__rlimit_resource_t, rlim: *const ::rlimit) -> ::c_int; + pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::__priority_which_t, who: ::id_t, prio: ::c_int) -> ::c_int; +} + +cfg_if! { + if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else { + pub use unsupported_target; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs new file mode 100644 index 00000000..a73dbded --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs @@ -0,0 +1,53 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(any(libc_align, + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any( + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs new file mode 100644 index 00000000..56a0e37f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs @@ -0,0 +1,53 @@ +/// L4Re specifics +/// This module contains definitions required by various L4Re libc backends. +/// Some of them are formally not part of the libc, but are a dependency of the +/// libc and hence we should provide them here. + +pub type l4_umword_t = ::c_ulong; // Unsigned machine word. +pub type pthread_t = *mut ::c_void; + +s! { + /// CPU sets. + pub struct l4_sched_cpu_set_t { + // from the L4Re docs + /// Combination of granularity and offset. + /// + /// The granularity defines how many CPUs each bit in map describes. + /// The offset is the number of the first CPU described by the first + /// bit in the bitmap. + /// offset must be a multiple of 2^graularity. + /// + /// | MSB | LSB | + /// | ---------------- | ------------------- | + /// | 8bit granularity | 24bit offset .. | + gran_offset: l4_umword_t , + /// Bitmap of CPUs. + map: l4_umword_t , + } +} + +#[cfg(target_os = "l4re")] +#[allow(missing_debug_implementations)] +pub struct pthread_attr_t { + pub __detachstate: ::c_int, + pub __schedpolicy: ::c_int, + pub __schedparam: super::__sched_param, + pub __inheritsched: ::c_int, + pub __scope: ::c_int, + pub __guardsize: ::size_t, + pub __stackaddr_set: ::c_int, + pub __stackaddr: *mut ::c_void, // better don't use it + pub __stacksize: ::size_t, + // L4Re specifics + pub affinity: l4_sched_cpu_set_t, + pub create_flags: ::c_uint, +} + +// L4Re requires a min stack size of 64k; that isn't defined in uClibc, but +// somewhere in the core libraries. uClibc wants 16k, but that's not enough. +pub const PTHREAD_STACK_MIN: usize = 65536; + +// Misc other constants required for building. +pub const SIGIO: ::c_int = 29; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs new file mode 100644 index 00000000..390119e3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs @@ -0,0 +1,345 @@ +//! Definitions for uclibc on 64bit systems +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type clock_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type fsword_t = ::c_long; +pub type ino_t = ::c_ulong; +pub type nlink_t = ::c_uint; +pub type off_t = ::c_long; +// [uClibc docs] Note stat64 has the same shape as stat for x86-64. +pub type stat64 = stat; +pub type suseconds_t = ::c_long; +pub type time_t = ::c_int; +pub type wchar_t = ::c_int; + +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; +pub type __u64 = ::c_ulong; +pub type __s64 = ::c_long; + +s! { + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, // read / write + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + #[cfg(not(target_os = "l4re"))] + pub struct pthread_attr_t { + __detachstate: ::c_int, + __schedpolicy: ::c_int, + __schedparam: __sched_param, + __inheritsched: ::c_int, + __scope: ::c_int, + __guardsize: ::size_t, + __stackaddr_set: ::c_int, + __stackaddr: *mut ::c_void, // better don't use it + __stacksize: ::size_t, + } + + pub struct __sched_param { + __sched_priority: ::c_int, + } + + pub struct siginfo_t { + si_signo: ::c_int, // signal number + si_errno: ::c_int, // if not zero: error value of signal, see errno.h + si_code: ::c_int, // signal code + pub _pad: [::c_int; 28], // unported union + _align: [usize; 0], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, // segment size in bytes + pub shm_atime: ::time_t, // time of last shmat() + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __ignored1: ::c_ulong, + __ignored2: ::c_ulong, + } + + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + // ------------------------------------------------------------ + // definitions below are *unverified* and might **break** the software +// pub struct in_addr { +// pub s_addr: in_addr_t, +// } +// +// pub struct in6_addr { +// pub s6_addr: [u8; 16], +// #[cfg(not(libc_align))] +// __align: [u32; 0], +// } + + pub struct stat { + pub st_dev: ::c_ulong, + pub st_ino: ::ino_t, + // According to uclibc/libc/sysdeps/linux/x86_64/bits/stat.h, order of + // nlink and mode are swapped on 64 bit systems. + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, // dev_t + pub st_size: off_t, // file size + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_ulong, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_ulong, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_ulong, + st_pad4: [::c_long; 3] + } + + pub struct sigaction { + pub sa_handler: ::sighandler_t, + pub sa_flags: ::c_ulong, + pub sa_restorer: ::Option, + pub sa_mask: ::sigset_t, + } + + pub struct stack_t { // FIXME + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct statfs { // FIXME + pub f_type: fsword_t, + pub f_bsize: fsword_t, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: fsword_t, + pub f_frsize: fsword_t, + f_spare: [fsword_t; 5], + } + + pub struct statfs64 { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_files: ::fsfilcnt64_t, + pub f_ffree: ::fsfilcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_int, + pub f_frsize: ::c_int, + pub f_flags: ::c_int, + pub f_spare: [::c_int; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct msghdr { // FIXME + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct termios { // FIXME + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct sigset_t { // FIXME + __val: [::c_ulong; 16], + } + + pub struct sysinfo { // FIXME + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct glob_t { // FIXME + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct cpu_set_t { // FIXME + #[cfg(target_pointer_width = "32")] + bits: [u32; 32], + #[cfg(target_pointer_width = "64")] + bits: [u64; 16], + } + + pub struct fsid_t { // FIXME + __val: [::c_int; 2], + } + + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } +} + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct dirent { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_name: [::c_char; 256], + } +} + +// constants +pub const ENAMETOOLONG: ::c_int = 36; // File name too long +pub const ENOTEMPTY: ::c_int = 39; // Directory not empty +pub const ELOOP: ::c_int = 40; // Too many symbolic links encountered +pub const EADDRINUSE: ::c_int = 98; // Address already in use +pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address +pub const ENETDOWN: ::c_int = 100; // Network is down +pub const ENETUNREACH: ::c_int = 101; // Network is unreachable +pub const ECONNABORTED: ::c_int = 103; // Software caused connection abort +pub const ECONNREFUSED: ::c_int = 111; // Connection refused +pub const ECONNRESET: ::c_int = 104; // Connection reset by peer +pub const EDEADLK: ::c_int = 35; // Resource deadlock would occur +pub const ENOSYS: ::c_int = 38; // Function not implemented +pub const ENOTCONN: ::c_int = 107; // Transport endpoint is not connected +pub const ETIMEDOUT: ::c_int = 110; // connection timed out +pub const ESTALE: ::c_int = 116; // Stale file handle +pub const EHOSTUNREACH: ::c_int = 113; // No route to host +pub const EDQUOT: ::c_int = 122; // Quota exceeded +pub const EOPNOTSUPP: ::c_int = 0x5f; +pub const ENODATA: ::c_int = 0x3d; +pub const O_APPEND: ::c_int = 02000; +pub const O_ACCMODE: ::c_int = 0003; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_CREAT: ::c_int = 0100; +pub const O_DIRECTORY: ::c_int = 0200000; +pub const O_EXCL: ::c_int = 0200; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_NONBLOCK: ::c_int = 04000; +pub const O_TRUNC: ::c_int = 01000; +pub const NCCS: usize = 32; +pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const SOCK_DGRAM: ::c_int = 2; // connectionless, unreliable datagrams +pub const SOCK_STREAM: ::c_int = 1; // …/common/bits/socket_type.h +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const PIDFD_NONBLOCK: ::c_int = 04000; + +cfg_if! { + if #[cfg(target_os = "l4re")] { + mod l4re; + pub use self::l4re::*; + } else { + mod other; + pub use other::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs new file mode 100644 index 00000000..481577cf --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs @@ -0,0 +1,5 @@ +// Thestyle checker discourages the use of #[cfg], so this has to go into a +// separate module +pub type pthread_t = ::c_ulong; + +pub const PTHREAD_STACK_MIN: usize = 16384; diff --git a/utshell-0.5.0/vendor/libc/src/unix/linux_like/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/linux_like/mod.rs new file mode 100644 index 00000000..35c7598c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/linux_like/mod.rs @@ -0,0 +1,1899 @@ +pub type sa_family_t = u16; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type clockid_t = ::c_int; +pub type timer_t = *mut ::c_void; +pub type key_t = ::c_int; +pub type id_t = ::c_uint; + +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum timezone {} +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ip_mreqn { + pub imr_multiaddr: in_addr, + pub imr_address: in_addr, + pub imr_ifindex: ::c_int, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + pub imr_sourceaddr: in_addr, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + // The order of the `ai_addr` field in this struct is crucial + // for converting between the Rust and C types. + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + + #[cfg(any(target_os = "linux", + target_os = "emscripten"))] + pub ai_addr: *mut ::sockaddr, + + pub ai_canonname: *mut c_char, + + #[cfg(target_os = "android")] + pub ai_addr: *mut ::sockaddr, + + pub ai_next: *mut addrinfo, + } + + pub struct sockaddr_ll { + pub sll_family: ::c_ushort, + pub sll_protocol: ::c_ushort, + pub sll_ifindex: ::c_int, + pub sll_hatype: ::c_ushort, + pub sll_pkttype: ::c_uchar, + pub sll_halen: ::c_uchar, + pub sll_addr: [::c_uchar; 8] + } + + pub struct fd_set { + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_long, + pub tm_zone: *const ::c_char, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_low_priority: ::c_int, + #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_repl_period: ::timespec, + #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_init_budget: ::timespec, + #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_max_repl: ::c_int, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct in_pktinfo { + pub ipi_ifindex: ::c_int, + pub ipi_spec_dst: ::in_addr, + pub ipi_addr: ::in_addr, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut c_char, + pub ifa_flags: ::c_uint, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_ifu: *mut ::sockaddr, // FIXME This should be a union + pub ifa_data: *mut ::c_void + } + + pub struct in6_rtmsg { + rtmsg_dst: ::in6_addr, + rtmsg_src: ::in6_addr, + rtmsg_gateway: ::in6_addr, + rtmsg_type: u32, + rtmsg_dst_len: u16, + rtmsg_src_len: u16, + rtmsg_metric: u32, + rtmsg_info: ::c_ulong, + rtmsg_flags: u32, + rtmsg_ifindex: ::c_int, + } + + pub struct arpreq { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + pub arp_dev: [::c_char; 16], + } + + pub struct arpreq_old { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + } + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } +} + +s_no_extra_traits! { + #[cfg_attr( + any( + all( + target_arch = "x86", + not(target_env = "musl"), + not(target_os = "android")), + target_arch = "x86_64"), + repr(packed))] + pub struct epoll_event { + pub events: u32, + pub u64: u64, + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + #[cfg(target_pointer_width = "32")] + __ss_pad2: [u8; 128 - 2 - 4], + #[cfg(target_pointer_width = "64")] + __ss_pad2: [u8; 128 - 2 - 8], + __ss_align: ::size_t, + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + // Actually a union. We only expose sigev_notify_thread_id because it's + // the most useful member + pub sigev_notify_thread_id: ::c_int, + #[cfg(target_pointer_width = "64")] + __unused1: [::c_int; 11], + #[cfg(target_pointer_width = "32")] + __unused1: [::c_int; 12] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for epoll_event { + fn eq(&self, other: &epoll_event) -> bool { + self.events == other.events + && self.u64 == other.u64 + } + } + impl Eq for epoll_event {} + impl ::fmt::Debug for epoll_event { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let events = self.events; + let u64 = self.u64; + f.debug_struct("epoll_event") + .field("events", &events) + .field("u64", &u64) + .finish() + } + } + impl ::hash::Hash for epoll_event { + fn hash(&self, state: &mut H) { + let events = self.events; + let u64 = self.u64; + events.hash(state); + u64.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + && self + .domainname + .iter() + .zip(other.domainname.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for utsname {} + + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + // FIXME: .field("domainname", &self.domainname) + .finish() + } + } + + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + self.domainname.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_value == other.sigev_value + && self.sigev_signo == other.sigev_signo + && self.sigev_notify == other.sigev_notify + && self.sigev_notify_thread_id + == other.sigev_notify_thread_id + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_value", &self.sigev_value) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_notify", &self.sigev_notify) + .field("sigev_notify_thread_id", + &self.sigev_notify_thread_id) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_value.hash(state); + self.sigev_signo.hash(state); + self.sigev_notify.hash(state); + self.sigev_notify_thread_id.hash(state); + } + } + } +} + +// intentionally not public, only used for fd_set +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + const ULONG_SIZE: usize = 32; + } else if #[cfg(target_pointer_width = "64")] { + const ULONG_SIZE: usize = 64; + } else { + // Unknown target_pointer_width + } +} + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; + +// Linux-specific fcntls +pub const F_SETLEASE: ::c_int = 1024; +pub const F_GETLEASE: ::c_int = 1025; +pub const F_NOTIFY: ::c_int = 1026; +pub const F_CANCELLK: ::c_int = 1029; +pub const F_DUPFD_CLOEXEC: ::c_int = 1030; +pub const F_SETPIPE_SZ: ::c_int = 1031; +pub const F_GETPIPE_SZ: ::c_int = 1032; +pub const F_ADD_SEALS: ::c_int = 1033; +pub const F_GET_SEALS: ::c_int = 1034; + +pub const F_SEAL_SEAL: ::c_int = 0x0001; +pub const F_SEAL_SHRINK: ::c_int = 0x0002; +pub const F_SEAL_GROW: ::c_int = 0x0004; +pub const F_SEAL_WRITE: ::c_int = 0x0008; + +// FIXME(#235): Include file sealing fcntls once we have a way to verify them. + +pub const SIGTRAP: ::c_int = 5; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6; +pub const CLOCK_BOOTTIME: ::clockid_t = 7; +pub const CLOCK_REALTIME_ALARM: ::clockid_t = 8; +pub const CLOCK_BOOTTIME_ALARM: ::clockid_t = 9; +pub const CLOCK_TAI: ::clockid_t = 11; +pub const TIMER_ABSTIME: ::c_int = 1; + +pub const RUSAGE_SELF: ::c_int = 0; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; + +pub const SOCK_CLOEXEC: ::c_int = O_CLOEXEC; + +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_IFMT: ::mode_t = 61440; +pub const S_IRWXU: ::mode_t = 448; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IRWXG: ::mode_t = 56; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IRWXO: ::mode_t = 7; +pub const S_IXOTH: ::mode_t = 1; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IROTH: ::mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const XATTR_CREATE: ::c_int = 0x1; +pub const XATTR_REPLACE: ::c_int = 0x2; + +cfg_if! { + if #[cfg(target_os = "android")] { + pub const RLIM64_INFINITY: ::c_ulonglong = !0; + } else { + pub const RLIM64_INFINITY: ::rlim64_t = !0; + } +} + +cfg_if! { + if #[cfg(target_env = "ohos")] { + pub const LC_CTYPE: ::c_int = 0; + pub const LC_NUMERIC: ::c_int = 1; + pub const LC_TIME: ::c_int = 2; + pub const LC_COLLATE: ::c_int = 3; + pub const LC_MONETARY: ::c_int = 4; + pub const LC_MESSAGES: ::c_int = 5; + pub const LC_PAPER: ::c_int = 6; + pub const LC_NAME: ::c_int = 7; + pub const LC_ADDRESS: ::c_int = 8; + pub const LC_TELEPHONE: ::c_int = 9; + pub const LC_MEASUREMENT: ::c_int = 10; + pub const LC_IDENTIFICATION: ::c_int = 11; + pub const LC_ALL: ::c_int = 12; + } else if #[cfg(not(target_env = "uclibc"))] { + pub const LC_CTYPE: ::c_int = 0; + pub const LC_NUMERIC: ::c_int = 1; + pub const LC_TIME: ::c_int = 2; + pub const LC_COLLATE: ::c_int = 3; + pub const LC_MONETARY: ::c_int = 4; + pub const LC_MESSAGES: ::c_int = 5; + pub const LC_ALL: ::c_int = 6; + } +} + +pub const LC_CTYPE_MASK: ::c_int = 1 << LC_CTYPE; +pub const LC_NUMERIC_MASK: ::c_int = 1 << LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << LC_TIME; +pub const LC_COLLATE_MASK: ::c_int = 1 << LC_COLLATE; +pub const LC_MONETARY_MASK: ::c_int = 1 << LC_MONETARY; +pub const LC_MESSAGES_MASK: ::c_int = 1 << LC_MESSAGES; +// LC_ALL_MASK defined per platform + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +// MS_ flags for msync(2) +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0004; + +// MS_ flags for mount(2) +pub const MS_RDONLY: ::c_ulong = 0x01; +pub const MS_NOSUID: ::c_ulong = 0x02; +pub const MS_NODEV: ::c_ulong = 0x04; +pub const MS_NOEXEC: ::c_ulong = 0x08; +pub const MS_SYNCHRONOUS: ::c_ulong = 0x10; +pub const MS_REMOUNT: ::c_ulong = 0x20; +pub const MS_MANDLOCK: ::c_ulong = 0x40; +pub const MS_DIRSYNC: ::c_ulong = 0x80; +pub const MS_NOATIME: ::c_ulong = 0x0400; +pub const MS_NODIRATIME: ::c_ulong = 0x0800; +pub const MS_BIND: ::c_ulong = 0x1000; +pub const MS_MOVE: ::c_ulong = 0x2000; +pub const MS_REC: ::c_ulong = 0x4000; +pub const MS_SILENT: ::c_ulong = 0x8000; +pub const MS_POSIXACL: ::c_ulong = 0x010000; +pub const MS_UNBINDABLE: ::c_ulong = 0x020000; +pub const MS_PRIVATE: ::c_ulong = 0x040000; +pub const MS_SLAVE: ::c_ulong = 0x080000; +pub const MS_SHARED: ::c_ulong = 0x100000; +pub const MS_RELATIME: ::c_ulong = 0x200000; +pub const MS_KERNMOUNT: ::c_ulong = 0x400000; +pub const MS_I_VERSION: ::c_ulong = 0x800000; +pub const MS_STRICTATIME: ::c_ulong = 0x1000000; +pub const MS_LAZYTIME: ::c_ulong = 0x2000000; +pub const MS_ACTIVE: ::c_ulong = 0x40000000; +pub const MS_MGC_VAL: ::c_ulong = 0xc0ed0000; +pub const MS_MGC_MSK: ::c_ulong = 0xffff0000; + +pub const SCM_RIGHTS: ::c_int = 0x01; +pub const SCM_CREDENTIALS: ::c_int = 0x02; + +pub const PROT_GROWSDOWN: ::c_int = 0x1000000; +pub const PROT_GROWSUP: ::c_int = 0x2000000; + +pub const MAP_TYPE: ::c_int = 0x000f; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 8; +pub const MADV_REMOVE: ::c_int = 9; +pub const MADV_DONTFORK: ::c_int = 10; +pub const MADV_DOFORK: ::c_int = 11; +pub const MADV_MERGEABLE: ::c_int = 12; +pub const MADV_UNMERGEABLE: ::c_int = 13; +pub const MADV_HUGEPAGE: ::c_int = 14; +pub const MADV_NOHUGEPAGE: ::c_int = 15; +pub const MADV_DONTDUMP: ::c_int = 16; +pub const MADV_DODUMP: ::c_int = 17; +pub const MADV_WIPEONFORK: ::c_int = 18; +pub const MADV_KEEPONFORK: ::c_int = 19; +pub const MADV_COLD: ::c_int = 20; +pub const MADV_PAGEOUT: ::c_int = 21; +pub const MADV_HWPOISON: ::c_int = 100; +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + pub const MADV_POPULATE_READ: ::c_int = 22; + pub const MADV_POPULATE_WRITE: ::c_int = 23; + pub const MADV_DONTNEED_LOCKED: ::c_int = 24; + } +} + +pub const IFF_UP: ::c_int = 0x1; +pub const IFF_BROADCAST: ::c_int = 0x2; +pub const IFF_DEBUG: ::c_int = 0x4; +pub const IFF_LOOPBACK: ::c_int = 0x8; +pub const IFF_POINTOPOINT: ::c_int = 0x10; +pub const IFF_NOTRAILERS: ::c_int = 0x20; +pub const IFF_RUNNING: ::c_int = 0x40; +pub const IFF_NOARP: ::c_int = 0x80; +pub const IFF_PROMISC: ::c_int = 0x100; +pub const IFF_ALLMULTI: ::c_int = 0x200; +pub const IFF_MASTER: ::c_int = 0x400; +pub const IFF_SLAVE: ::c_int = 0x800; +pub const IFF_MULTICAST: ::c_int = 0x1000; +pub const IFF_PORTSEL: ::c_int = 0x2000; +pub const IFF_AUTOMEDIA: ::c_int = 0x4000; +pub const IFF_DYNAMIC: ::c_int = 0x8000; + +pub const SOL_IP: ::c_int = 0; +pub const SOL_TCP: ::c_int = 6; +pub const SOL_UDP: ::c_int = 17; +pub const SOL_IPV6: ::c_int = 41; +pub const SOL_ICMPV6: ::c_int = 58; +pub const SOL_RAW: ::c_int = 255; +pub const SOL_DECNET: ::c_int = 261; +pub const SOL_X25: ::c_int = 262; +pub const SOL_PACKET: ::c_int = 263; +pub const SOL_ATM: ::c_int = 264; +pub const SOL_AAL: ::c_int = 265; +pub const SOL_IRDA: ::c_int = 266; +pub const SOL_NETBEUI: ::c_int = 267; +pub const SOL_LLC: ::c_int = 268; +pub const SOL_DCCP: ::c_int = 269; +pub const SOL_NETLINK: ::c_int = 270; +pub const SOL_TIPC: ::c_int = 271; +pub const SOL_BLUETOOTH: ::c_int = 274; +pub const SOL_ALG: ::c_int = 279; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_AX25: ::c_int = 3; +pub const AF_IPX: ::c_int = 4; +pub const AF_APPLETALK: ::c_int = 5; +pub const AF_NETROM: ::c_int = 6; +pub const AF_BRIDGE: ::c_int = 7; +pub const AF_ATMPVC: ::c_int = 8; +pub const AF_X25: ::c_int = 9; +pub const AF_INET6: ::c_int = 10; +pub const AF_ROSE: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_NETBEUI: ::c_int = 13; +pub const AF_SECURITY: ::c_int = 14; +pub const AF_KEY: ::c_int = 15; +pub const AF_NETLINK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = AF_NETLINK; +pub const AF_PACKET: ::c_int = 17; +pub const AF_ASH: ::c_int = 18; +pub const AF_ECONET: ::c_int = 19; +pub const AF_ATMSVC: ::c_int = 20; +pub const AF_RDS: ::c_int = 21; +pub const AF_SNA: ::c_int = 22; +pub const AF_IRDA: ::c_int = 23; +pub const AF_PPPOX: ::c_int = 24; +pub const AF_WANPIPE: ::c_int = 25; +pub const AF_LLC: ::c_int = 26; +pub const AF_CAN: ::c_int = 29; +pub const AF_TIPC: ::c_int = 30; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_IUCV: ::c_int = 32; +pub const AF_RXRPC: ::c_int = 33; +pub const AF_ISDN: ::c_int = 34; +pub const AF_PHONET: ::c_int = 35; +pub const AF_IEEE802154: ::c_int = 36; +pub const AF_CAIF: ::c_int = 37; +pub const AF_ALG: ::c_int = 38; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_AX25: ::c_int = AF_AX25; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_NETROM: ::c_int = AF_NETROM; +pub const PF_BRIDGE: ::c_int = AF_BRIDGE; +pub const PF_ATMPVC: ::c_int = AF_ATMPVC; +pub const PF_X25: ::c_int = AF_X25; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_ROSE: ::c_int = AF_ROSE; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_NETBEUI: ::c_int = AF_NETBEUI; +pub const PF_SECURITY: ::c_int = AF_SECURITY; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_NETLINK: ::c_int = AF_NETLINK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_PACKET: ::c_int = AF_PACKET; +pub const PF_ASH: ::c_int = AF_ASH; +pub const PF_ECONET: ::c_int = AF_ECONET; +pub const PF_ATMSVC: ::c_int = AF_ATMSVC; +pub const PF_RDS: ::c_int = AF_RDS; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_IRDA: ::c_int = AF_IRDA; +pub const PF_PPPOX: ::c_int = AF_PPPOX; +pub const PF_WANPIPE: ::c_int = AF_WANPIPE; +pub const PF_LLC: ::c_int = AF_LLC; +pub const PF_CAN: ::c_int = AF_CAN; +pub const PF_TIPC: ::c_int = AF_TIPC; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_IUCV: ::c_int = AF_IUCV; +pub const PF_RXRPC: ::c_int = AF_RXRPC; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_PHONET: ::c_int = AF_PHONET; +pub const PF_IEEE802154: ::c_int = AF_IEEE802154; +pub const PF_CAIF: ::c_int = AF_CAIF; +pub const PF_ALG: ::c_int = AF_ALG; + +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTROUTE: ::c_int = 4; +pub const MSG_CTRUNC: ::c_int = 8; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_DONTWAIT: ::c_int = 0x40; +pub const MSG_EOR: ::c_int = 0x80; +pub const MSG_WAITALL: ::c_int = 0x100; +pub const MSG_FIN: ::c_int = 0x200; +pub const MSG_SYN: ::c_int = 0x400; +pub const MSG_CONFIRM: ::c_int = 0x800; +pub const MSG_RST: ::c_int = 0x1000; +pub const MSG_ERRQUEUE: ::c_int = 0x2000; +pub const MSG_NOSIGNAL: ::c_int = 0x4000; +pub const MSG_MORE: ::c_int = 0x8000; +pub const MSG_WAITFORONE: ::c_int = 0x10000; +pub const MSG_FASTOPEN: ::c_int = 0x20000000; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x40000000; + +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const IP_TOS: ::c_int = 1; +pub const IP_TTL: ::c_int = 2; +pub const IP_HDRINCL: ::c_int = 3; +pub const IP_OPTIONS: ::c_int = 4; +pub const IP_ROUTER_ALERT: ::c_int = 5; +pub const IP_RECVOPTS: ::c_int = 6; +pub const IP_RETOPTS: ::c_int = 7; +pub const IP_PKTINFO: ::c_int = 8; +pub const IP_PKTOPTIONS: ::c_int = 9; +pub const IP_MTU_DISCOVER: ::c_int = 10; +pub const IP_RECVERR: ::c_int = 11; +pub const IP_RECVTTL: ::c_int = 12; +pub const IP_RECVTOS: ::c_int = 13; +pub const IP_MTU: ::c_int = 14; +pub const IP_FREEBIND: ::c_int = 15; +pub const IP_IPSEC_POLICY: ::c_int = 16; +pub const IP_XFRM_POLICY: ::c_int = 17; +pub const IP_PASSSEC: ::c_int = 18; +pub const IP_TRANSPARENT: ::c_int = 19; +pub const IP_ORIGDSTADDR: ::c_int = 20; +pub const IP_RECVORIGDSTADDR: ::c_int = IP_ORIGDSTADDR; +pub const IP_MINTTL: ::c_int = 21; +pub const IP_NODEFRAG: ::c_int = 22; +pub const IP_CHECKSUM: ::c_int = 23; +pub const IP_BIND_ADDRESS_NO_PORT: ::c_int = 24; +pub const IP_MULTICAST_IF: ::c_int = 32; +pub const IP_MULTICAST_TTL: ::c_int = 33; +pub const IP_MULTICAST_LOOP: ::c_int = 34; +pub const IP_ADD_MEMBERSHIP: ::c_int = 35; +pub const IP_DROP_MEMBERSHIP: ::c_int = 36; +pub const IP_UNBLOCK_SOURCE: ::c_int = 37; +pub const IP_BLOCK_SOURCE: ::c_int = 38; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 39; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 40; +pub const IP_MSFILTER: ::c_int = 41; +pub const IP_MULTICAST_ALL: ::c_int = 49; +pub const IP_UNICAST_IF: ::c_int = 50; + +pub const IP_DEFAULT_MULTICAST_TTL: ::c_int = 1; +pub const IP_DEFAULT_MULTICAST_LOOP: ::c_int = 1; + +pub const IP_PMTUDISC_DONT: ::c_int = 0; +pub const IP_PMTUDISC_WANT: ::c_int = 1; +pub const IP_PMTUDISC_DO: ::c_int = 2; +pub const IP_PMTUDISC_PROBE: ::c_int = 3; +pub const IP_PMTUDISC_INTERFACE: ::c_int = 4; +pub const IP_PMTUDISC_OMIT: ::c_int = 5; + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// DCCP +pub const IPPROTO_DCCP: ::c_int = 33; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_MTP: ::c_int = 92; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_COMP: ::c_int = 108; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_MH: ::c_int = 135; +pub const IPPROTO_UDPLITE: ::c_int = 136; +/// raw IP packet +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_BEETPH: ::c_int = 94; +pub const IPPROTO_MPLS: ::c_int = 137; +/// Multipath TCP +pub const IPPROTO_MPTCP: ::c_int = 262; +/// Ethernet-within-IPv6 encapsulation. +pub const IPPROTO_ETHERNET: ::c_int = 143; + +pub const MCAST_EXCLUDE: ::c_int = 0; +pub const MCAST_INCLUDE: ::c_int = 1; +pub const MCAST_JOIN_GROUP: ::c_int = 42; +pub const MCAST_BLOCK_SOURCE: ::c_int = 43; +pub const MCAST_UNBLOCK_SOURCE: ::c_int = 44; +pub const MCAST_LEAVE_GROUP: ::c_int = 45; +pub const MCAST_JOIN_SOURCE_GROUP: ::c_int = 46; +pub const MCAST_LEAVE_SOURCE_GROUP: ::c_int = 47; +pub const MCAST_MSFILTER: ::c_int = 48; + +pub const IPV6_ADDRFORM: ::c_int = 1; +pub const IPV6_2292PKTINFO: ::c_int = 2; +pub const IPV6_2292HOPOPTS: ::c_int = 3; +pub const IPV6_2292DSTOPTS: ::c_int = 4; +pub const IPV6_2292RTHDR: ::c_int = 5; +pub const IPV6_2292PKTOPTIONS: ::c_int = 6; +pub const IPV6_CHECKSUM: ::c_int = 7; +pub const IPV6_2292HOPLIMIT: ::c_int = 8; +pub const IPV6_NEXTHOP: ::c_int = 9; +pub const IPV6_AUTHHDR: ::c_int = 10; +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +pub const IPV6_MULTICAST_LOOP: ::c_int = 19; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21; +pub const IPV6_ROUTER_ALERT: ::c_int = 22; +pub const IPV6_MTU_DISCOVER: ::c_int = 23; +pub const IPV6_MTU: ::c_int = 24; +pub const IPV6_RECVERR: ::c_int = 25; +pub const IPV6_V6ONLY: ::c_int = 26; +pub const IPV6_JOIN_ANYCAST: ::c_int = 27; +pub const IPV6_LEAVE_ANYCAST: ::c_int = 28; +pub const IPV6_IPSEC_POLICY: ::c_int = 34; +pub const IPV6_XFRM_POLICY: ::c_int = 35; +pub const IPV6_HDRINCL: ::c_int = 36; +pub const IPV6_RECVPKTINFO: ::c_int = 49; +pub const IPV6_PKTINFO: ::c_int = 50; +pub const IPV6_RECVHOPLIMIT: ::c_int = 51; +pub const IPV6_HOPLIMIT: ::c_int = 52; +pub const IPV6_RECVHOPOPTS: ::c_int = 53; +pub const IPV6_HOPOPTS: ::c_int = 54; +pub const IPV6_RTHDRDSTOPTS: ::c_int = 55; +pub const IPV6_RECVRTHDR: ::c_int = 56; +pub const IPV6_RTHDR: ::c_int = 57; +pub const IPV6_RECVDSTOPTS: ::c_int = 58; +pub const IPV6_DSTOPTS: ::c_int = 59; +pub const IPV6_RECVPATHMTU: ::c_int = 60; +pub const IPV6_PATHMTU: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; +pub const IPV6_RECVTCLASS: ::c_int = 66; +pub const IPV6_TCLASS: ::c_int = 67; +pub const IPV6_AUTOFLOWLABEL: ::c_int = 70; +pub const IPV6_ADDR_PREFERENCES: ::c_int = 72; +pub const IPV6_MINHOPCOUNT: ::c_int = 73; +pub const IPV6_ORIGDSTADDR: ::c_int = 74; +pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; +pub const IPV6_TRANSPARENT: ::c_int = 75; +pub const IPV6_UNICAST_IF: ::c_int = 76; +pub const IPV6_PREFER_SRC_TMP: ::c_int = 0x0001; +pub const IPV6_PREFER_SRC_PUBLIC: ::c_int = 0x0002; +pub const IPV6_PREFER_SRC_PUBTMP_DEFAULT: ::c_int = 0x0100; +pub const IPV6_PREFER_SRC_COA: ::c_int = 0x0004; +pub const IPV6_PREFER_SRC_HOME: ::c_int = 0x0400; +pub const IPV6_PREFER_SRC_CGA: ::c_int = 0x0008; +pub const IPV6_PREFER_SRC_NONCGA: ::c_int = 0x0800; + +pub const IPV6_PMTUDISC_DONT: ::c_int = 0; +pub const IPV6_PMTUDISC_WANT: ::c_int = 1; +pub const IPV6_PMTUDISC_DO: ::c_int = 2; +pub const IPV6_PMTUDISC_PROBE: ::c_int = 3; +pub const IPV6_PMTUDISC_INTERFACE: ::c_int = 4; +pub const IPV6_PMTUDISC_OMIT: ::c_int = 5; + +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; +pub const TCP_CORK: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_SYNCNT: ::c_int = 7; +pub const TCP_LINGER2: ::c_int = 8; +pub const TCP_DEFER_ACCEPT: ::c_int = 9; +pub const TCP_WINDOW_CLAMP: ::c_int = 10; +pub const TCP_INFO: ::c_int = 11; +pub const TCP_QUICKACK: ::c_int = 12; +pub const TCP_CONGESTION: ::c_int = 13; +pub const TCP_MD5SIG: ::c_int = 14; +cfg_if! { + if #[cfg(all(target_os = "linux", any( + target_env = "gnu", + target_env = "musl", + target_env = "ohos" + )))] { + // WARN: deprecated + pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; + } +} +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; +pub const TCP_NOTSENT_LOWAT: ::c_int = 25; +pub const TCP_CC_INFO: ::c_int = 26; +pub const TCP_SAVE_SYN: ::c_int = 27; +pub const TCP_SAVED_SYN: ::c_int = 28; +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + // NOTE: emscripten doesn't support these options yet. + + pub const TCP_REPAIR_WINDOW: ::c_int = 29; + pub const TCP_FASTOPEN_CONNECT: ::c_int = 30; + pub const TCP_ULP: ::c_int = 31; + pub const TCP_MD5SIG_EXT: ::c_int = 32; + pub const TCP_FASTOPEN_KEY: ::c_int = 33; + pub const TCP_FASTOPEN_NO_COOKIE: ::c_int = 34; + pub const TCP_ZEROCOPY_RECEIVE: ::c_int = 35; + pub const TCP_INQ: ::c_int = 36; + pub const TCP_CM_INQ: ::c_int = TCP_INQ; + // NOTE: Some CI images doesn't have this option yet. + // pub const TCP_TX_DELAY: ::c_int = 37; + pub const TCP_MD5SIG_MAXKEYLEN: usize = 80; + } +} + +pub const SO_DEBUG: ::c_int = 1; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const PATH_MAX: ::c_int = 4096; + +pub const UIO_MAXIOV: ::c_int = 1024; + +pub const FD_SETSIZE: usize = 1024; + +pub const EPOLLIN: ::c_int = 0x1; +pub const EPOLLPRI: ::c_int = 0x2; +pub const EPOLLOUT: ::c_int = 0x4; +pub const EPOLLERR: ::c_int = 0x8; +pub const EPOLLHUP: ::c_int = 0x10; +pub const EPOLLRDNORM: ::c_int = 0x40; +pub const EPOLLRDBAND: ::c_int = 0x80; +pub const EPOLLWRNORM: ::c_int = 0x100; +pub const EPOLLWRBAND: ::c_int = 0x200; +pub const EPOLLMSG: ::c_int = 0x400; +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +pub const EPOLLWAKEUP: ::c_int = 0x20000000; +pub const EPOLLONESHOT: ::c_int = 0x40000000; +pub const EPOLLET: ::c_int = 0x80000000; + +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLL_CTL_DEL: ::c_int = 2; + +pub const MNT_FORCE: ::c_int = 0x1; +pub const MNT_DETACH: ::c_int = 0x2; +pub const MNT_EXPIRE: ::c_int = 0x4; +pub const UMOUNT_NOFOLLOW: ::c_int = 0x8; + +pub const Q_GETFMT: ::c_int = 0x800004; +pub const Q_GETINFO: ::c_int = 0x800005; +pub const Q_SETINFO: ::c_int = 0x800006; +pub const QIF_BLIMITS: u32 = 1; +pub const QIF_SPACE: u32 = 2; +pub const QIF_ILIMITS: u32 = 4; +pub const QIF_INODES: u32 = 8; +pub const QIF_BTIME: u32 = 16; +pub const QIF_ITIME: u32 = 32; +pub const QIF_LIMITS: u32 = 5; +pub const QIF_USAGE: u32 = 10; +pub const QIF_TIMES: u32 = 48; +pub const QIF_ALL: u32 = 63; + +pub const Q_SYNC: ::c_int = 0x800001; +pub const Q_QUOTAON: ::c_int = 0x800002; +pub const Q_QUOTAOFF: ::c_int = 0x800003; +pub const Q_GETQUOTA: ::c_int = 0x800007; +pub const Q_SETQUOTA: ::c_int = 0x800008; + +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00000100; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const CR0: ::tcflag_t = 0x00000000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const VT0: ::tcflag_t = 0x00000000; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VLNEXT: usize = 15; +pub const IGNBRK: ::tcflag_t = 0x00000001; +pub const BRKINT: ::tcflag_t = 0x00000002; +pub const IGNPAR: ::tcflag_t = 0x00000004; +pub const PARMRK: ::tcflag_t = 0x00000008; +pub const INPCK: ::tcflag_t = 0x00000010; +pub const ISTRIP: ::tcflag_t = 0x00000020; +pub const INLCR: ::tcflag_t = 0x00000040; +pub const IGNCR: ::tcflag_t = 0x00000080; +pub const ICRNL: ::tcflag_t = 0x00000100; +pub const IXANY: ::tcflag_t = 0x00000800; +pub const IMAXBEL: ::tcflag_t = 0x00002000; +pub const OPOST: ::tcflag_t = 0x1; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CRTSCTS: ::tcflag_t = 0x80000000; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const OCRNL: ::tcflag_t = 0o000010; +pub const ONOCR: ::tcflag_t = 0o000020; +pub const ONLRET: ::tcflag_t = 0o000040; +pub const OFILL: ::tcflag_t = 0o000100; +pub const OFDEL: ::tcflag_t = 0o000200; + +pub const CLONE_VM: ::c_int = 0x100; +pub const CLONE_FS: ::c_int = 0x200; +pub const CLONE_FILES: ::c_int = 0x400; +pub const CLONE_SIGHAND: ::c_int = 0x800; +pub const CLONE_PTRACE: ::c_int = 0x2000; +pub const CLONE_VFORK: ::c_int = 0x4000; +pub const CLONE_PARENT: ::c_int = 0x8000; +pub const CLONE_THREAD: ::c_int = 0x10000; +pub const CLONE_NEWNS: ::c_int = 0x20000; +pub const CLONE_SYSVSEM: ::c_int = 0x40000; +pub const CLONE_SETTLS: ::c_int = 0x80000; +pub const CLONE_PARENT_SETTID: ::c_int = 0x100000; +pub const CLONE_CHILD_CLEARTID: ::c_int = 0x200000; +pub const CLONE_DETACHED: ::c_int = 0x400000; +pub const CLONE_UNTRACED: ::c_int = 0x800000; +pub const CLONE_CHILD_SETTID: ::c_int = 0x01000000; +pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; +pub const CLONE_NEWUTS: ::c_int = 0x04000000; +pub const CLONE_NEWIPC: ::c_int = 0x08000000; +pub const CLONE_NEWUSER: ::c_int = 0x10000000; +pub const CLONE_NEWPID: ::c_int = 0x20000000; +pub const CLONE_NEWNET: ::c_int = 0x40000000; +pub const CLONE_IO: ::c_int = 0x80000000; + +pub const WNOHANG: ::c_int = 0x00000001; +pub const WUNTRACED: ::c_int = 0x00000002; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WEXITED: ::c_int = 0x00000004; +pub const WCONTINUED: ::c_int = 0x00000008; +pub const WNOWAIT: ::c_int = 0x01000000; + +// Options for personality(2). +pub const ADDR_NO_RANDOMIZE: ::c_int = 0x0040000; +pub const MMAP_PAGE_ZERO: ::c_int = 0x0100000; +pub const ADDR_COMPAT_LAYOUT: ::c_int = 0x0200000; +pub const READ_IMPLIES_EXEC: ::c_int = 0x0400000; +pub const ADDR_LIMIT_32BIT: ::c_int = 0x0800000; +pub const SHORT_INODE: ::c_int = 0x1000000; +pub const WHOLE_SECONDS: ::c_int = 0x2000000; +pub const STICKY_TIMEOUTS: ::c_int = 0x4000000; +pub const ADDR_LIMIT_3GB: ::c_int = 0x8000000; + +// Options set using PTRACE_SETOPTIONS. +pub const PTRACE_O_TRACESYSGOOD: ::c_int = 0x00000001; +pub const PTRACE_O_TRACEFORK: ::c_int = 0x00000002; +pub const PTRACE_O_TRACEVFORK: ::c_int = 0x00000004; +pub const PTRACE_O_TRACECLONE: ::c_int = 0x00000008; +pub const PTRACE_O_TRACEEXEC: ::c_int = 0x00000010; +pub const PTRACE_O_TRACEVFORKDONE: ::c_int = 0x00000020; +pub const PTRACE_O_TRACEEXIT: ::c_int = 0x00000040; +pub const PTRACE_O_TRACESECCOMP: ::c_int = 0x00000080; +pub const PTRACE_O_SUSPEND_SECCOMP: ::c_int = 0x00200000; +pub const PTRACE_O_EXITKILL: ::c_int = 0x00100000; +pub const PTRACE_O_MASK: ::c_int = 0x003000ff; + +// Wait extended result codes for the above trace options. +pub const PTRACE_EVENT_FORK: ::c_int = 1; +pub const PTRACE_EVENT_VFORK: ::c_int = 2; +pub const PTRACE_EVENT_CLONE: ::c_int = 3; +pub const PTRACE_EVENT_EXEC: ::c_int = 4; +pub const PTRACE_EVENT_VFORK_DONE: ::c_int = 5; +pub const PTRACE_EVENT_EXIT: ::c_int = 6; +pub const PTRACE_EVENT_SECCOMP: ::c_int = 7; + +pub const __WNOTHREAD: ::c_int = 0x20000000; +pub const __WALL: ::c_int = 0x40000000; +pub const __WCLONE: ::c_int = 0x80000000; + +pub const SPLICE_F_MOVE: ::c_uint = 0x01; +pub const SPLICE_F_NONBLOCK: ::c_uint = 0x02; +pub const SPLICE_F_MORE: ::c_uint = 0x04; +pub const SPLICE_F_GIFT: ::c_uint = 0x08; + +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_LAZY: ::c_int = 1; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x100; +pub const AT_REMOVEDIR: ::c_int = 0x200; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; +pub const AT_NO_AUTOMOUNT: ::c_int = 0x800; +pub const AT_EMPTY_PATH: ::c_int = 0x1000; +pub const AT_RECURSIVE: ::c_int = 0x8000; + +pub const LOG_CRON: ::c_int = 9 << 3; +pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +pub const LOG_FTP: ::c_int = 11 << 3; +pub const LOG_PERROR: ::c_int = 0x20; + +pub const PIPE_BUF: usize = 4096; + +pub const SI_LOAD_SHIFT: ::c_uint = 16; + +// si_code values for SIGBUS signal +pub const BUS_ADRALN: ::c_int = 1; +pub const BUS_ADRERR: ::c_int = 2; +pub const BUS_OBJERR: ::c_int = 3; +// Linux-specific si_code values for SIGBUS signal +pub const BUS_MCEERR_AR: ::c_int = 4; +pub const BUS_MCEERR_AO: ::c_int = 5; + +// si_code values for SIGCHLD signal +pub const CLD_EXITED: ::c_int = 1; +pub const CLD_KILLED: ::c_int = 2; +pub const CLD_DUMPED: ::c_int = 3; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const SIGEV_SIGNAL: ::c_int = 0; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + pub const P_PIDFD: idtype_t = 3; + } +} + +pub const UTIME_OMIT: c_long = 1073741822; +pub const UTIME_NOW: c_long = 1073741823; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLRDBAND: ::c_short = 0x080; +#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] +pub const POLLRDHUP: ::c_short = 0x2000; +#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] +pub const POLLRDHUP: ::c_short = 0x800; + +pub const IPTOS_LOWDELAY: u8 = 0x10; +pub const IPTOS_THROUGHPUT: u8 = 0x08; +pub const IPTOS_RELIABILITY: u8 = 0x04; +pub const IPTOS_MINCOST: u8 = 0x02; + +pub const IPTOS_PREC_NETCONTROL: u8 = 0xe0; +pub const IPTOS_PREC_INTERNETCONTROL: u8 = 0xc0; +pub const IPTOS_PREC_CRITIC_ECP: u8 = 0xa0; +pub const IPTOS_PREC_FLASHOVERRIDE: u8 = 0x80; +pub const IPTOS_PREC_FLASH: u8 = 0x60; +pub const IPTOS_PREC_IMMEDIATE: u8 = 0x40; +pub const IPTOS_PREC_PRIORITY: u8 = 0x20; +pub const IPTOS_PREC_ROUTINE: u8 = 0x00; + +pub const IPTOS_ECN_MASK: u8 = 0x03; +pub const IPTOS_ECN_ECT1: u8 = 0x01; +pub const IPTOS_ECN_ECT0: u8 = 0x02; +pub const IPTOS_ECN_CE: u8 = 0x03; + +pub const IPOPT_COPY: u8 = 0x80; +pub const IPOPT_CLASS_MASK: u8 = 0x60; +pub const IPOPT_NUMBER_MASK: u8 = 0x1f; + +pub const IPOPT_CONTROL: u8 = 0x00; +pub const IPOPT_RESERVED1: u8 = 0x20; +pub const IPOPT_MEASUREMENT: u8 = 0x40; +pub const IPOPT_RESERVED2: u8 = 0x60; +pub const IPOPT_END: u8 = 0 | IPOPT_CONTROL; +pub const IPOPT_NOOP: u8 = 1 | IPOPT_CONTROL; +pub const IPOPT_SEC: u8 = 2 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_LSRR: u8 = 3 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_TIMESTAMP: u8 = 4 | IPOPT_MEASUREMENT; +pub const IPOPT_RR: u8 = 7 | IPOPT_CONTROL; +pub const IPOPT_SID: u8 = 8 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_SSRR: u8 = 9 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_RA: u8 = 20 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPVERSION: u8 = 4; +pub const MAXTTL: u8 = 255; +pub const IPDEFTTL: u8 = 64; +pub const IPOPT_OPTVAL: u8 = 0; +pub const IPOPT_OLEN: u8 = 1; +pub const IPOPT_OFFSET: u8 = 2; +pub const IPOPT_MINOFF: u8 = 4; +pub const MAX_IPOPTLEN: u8 = 40; +pub const IPOPT_NOP: u8 = IPOPT_NOOP; +pub const IPOPT_EOL: u8 = IPOPT_END; +pub const IPOPT_TS: u8 = IPOPT_TIMESTAMP; +pub const IPOPT_TS_TSONLY: u8 = 0; +pub const IPOPT_TS_TSANDADDR: u8 = 1; +pub const IPOPT_TS_PRESPEC: u8 = 3; + +pub const ARPOP_RREQUEST: u16 = 3; +pub const ARPOP_RREPLY: u16 = 4; +pub const ARPOP_InREQUEST: u16 = 8; +pub const ARPOP_InREPLY: u16 = 9; +pub const ARPOP_NAK: u16 = 10; + +pub const ATF_NETMASK: ::c_int = 0x20; +pub const ATF_DONTPUB: ::c_int = 0x40; + +pub const ARPHRD_NETROM: u16 = 0; +pub const ARPHRD_ETHER: u16 = 1; +pub const ARPHRD_EETHER: u16 = 2; +pub const ARPHRD_AX25: u16 = 3; +pub const ARPHRD_PRONET: u16 = 4; +pub const ARPHRD_CHAOS: u16 = 5; +pub const ARPHRD_IEEE802: u16 = 6; +pub const ARPHRD_ARCNET: u16 = 7; +pub const ARPHRD_APPLETLK: u16 = 8; +pub const ARPHRD_DLCI: u16 = 15; +pub const ARPHRD_ATM: u16 = 19; +pub const ARPHRD_METRICOM: u16 = 23; +pub const ARPHRD_IEEE1394: u16 = 24; +pub const ARPHRD_EUI64: u16 = 27; +pub const ARPHRD_INFINIBAND: u16 = 32; + +pub const ARPHRD_SLIP: u16 = 256; +pub const ARPHRD_CSLIP: u16 = 257; +pub const ARPHRD_SLIP6: u16 = 258; +pub const ARPHRD_CSLIP6: u16 = 259; +pub const ARPHRD_RSRVD: u16 = 260; +pub const ARPHRD_ADAPT: u16 = 264; +pub const ARPHRD_ROSE: u16 = 270; +pub const ARPHRD_X25: u16 = 271; +pub const ARPHRD_HWX25: u16 = 272; +pub const ARPHRD_CAN: u16 = 280; +pub const ARPHRD_PPP: u16 = 512; +pub const ARPHRD_CISCO: u16 = 513; +pub const ARPHRD_HDLC: u16 = ARPHRD_CISCO; +pub const ARPHRD_LAPB: u16 = 516; +pub const ARPHRD_DDCMP: u16 = 517; +pub const ARPHRD_RAWHDLC: u16 = 518; + +pub const ARPHRD_TUNNEL: u16 = 768; +pub const ARPHRD_TUNNEL6: u16 = 769; +pub const ARPHRD_FRAD: u16 = 770; +pub const ARPHRD_SKIP: u16 = 771; +pub const ARPHRD_LOOPBACK: u16 = 772; +pub const ARPHRD_LOCALTLK: u16 = 773; +pub const ARPHRD_FDDI: u16 = 774; +pub const ARPHRD_BIF: u16 = 775; +pub const ARPHRD_SIT: u16 = 776; +pub const ARPHRD_IPDDP: u16 = 777; +pub const ARPHRD_IPGRE: u16 = 778; +pub const ARPHRD_PIMREG: u16 = 779; +pub const ARPHRD_HIPPI: u16 = 780; +pub const ARPHRD_ASH: u16 = 781; +pub const ARPHRD_ECONET: u16 = 782; +pub const ARPHRD_IRDA: u16 = 783; +pub const ARPHRD_FCPP: u16 = 784; +pub const ARPHRD_FCAL: u16 = 785; +pub const ARPHRD_FCPL: u16 = 786; +pub const ARPHRD_FCFABRIC: u16 = 787; +pub const ARPHRD_IEEE802_TR: u16 = 800; +pub const ARPHRD_IEEE80211: u16 = 801; +pub const ARPHRD_IEEE80211_PRISM: u16 = 802; +pub const ARPHRD_IEEE80211_RADIOTAP: u16 = 803; +pub const ARPHRD_IEEE802154: u16 = 804; + +pub const ARPHRD_VOID: u16 = 0xFFFF; +pub const ARPHRD_NONE: u16 = 0xFFFE; + +cfg_if! { + if #[cfg(target_os = "emscripten")] { + // Emscripten does not define any `*_SUPER_MAGIC` constants. + } else if #[cfg(not(target_arch = "s390x"))] { + pub const ADFS_SUPER_MAGIC: ::c_long = 0x0000adf5; + pub const AFFS_SUPER_MAGIC: ::c_long = 0x0000adff; + pub const AFS_SUPER_MAGIC: ::c_long = 0x5346414f; + pub const AUTOFS_SUPER_MAGIC: ::c_long = 0x0187; + pub const BPF_FS_MAGIC: ::c_long = 0xcafe4a11; + pub const BTRFS_SUPER_MAGIC: ::c_long = 0x9123683e; + pub const CGROUP2_SUPER_MAGIC: ::c_long = 0x63677270; + pub const CGROUP_SUPER_MAGIC: ::c_long = 0x27e0eb; + pub const CODA_SUPER_MAGIC: ::c_long = 0x73757245; + pub const CRAMFS_MAGIC: ::c_long = 0x28cd3d45; + pub const DEBUGFS_MAGIC: ::c_long = 0x64626720; + pub const DEVPTS_SUPER_MAGIC: ::c_long = 0x1cd1; + pub const ECRYPTFS_SUPER_MAGIC: ::c_long = 0xf15f; + pub const EFS_SUPER_MAGIC: ::c_long = 0x00414a53; + pub const EXT2_SUPER_MAGIC: ::c_long = 0x0000ef53; + pub const EXT3_SUPER_MAGIC: ::c_long = 0x0000ef53; + pub const EXT4_SUPER_MAGIC: ::c_long = 0x0000ef53; + pub const F2FS_SUPER_MAGIC: ::c_long = 0xf2f52010; + pub const FUSE_SUPER_MAGIC: ::c_long = 0x65735546; + pub const FUTEXFS_SUPER_MAGIC: ::c_long = 0xbad1dea; + pub const HOSTFS_SUPER_MAGIC: ::c_long = 0x00c0ffee; + pub const HPFS_SUPER_MAGIC: ::c_long = 0xf995e849; + pub const HUGETLBFS_MAGIC: ::c_long = 0x958458f6; + pub const ISOFS_SUPER_MAGIC: ::c_long = 0x00009660; + pub const JFFS2_SUPER_MAGIC: ::c_long = 0x000072b6; + pub const MINIX2_SUPER_MAGIC2: ::c_long = 0x00002478; + pub const MINIX2_SUPER_MAGIC: ::c_long = 0x00002468; + pub const MINIX3_SUPER_MAGIC: ::c_long = 0x4d5a; + pub const MINIX_SUPER_MAGIC2: ::c_long = 0x0000138f; + pub const MINIX_SUPER_MAGIC: ::c_long = 0x0000137f; + pub const MSDOS_SUPER_MAGIC: ::c_long = 0x00004d44; + pub const NCP_SUPER_MAGIC: ::c_long = 0x0000564c; + pub const NFS_SUPER_MAGIC: ::c_long = 0x00006969; + pub const NILFS_SUPER_MAGIC: ::c_long = 0x3434; + pub const OCFS2_SUPER_MAGIC: ::c_long = 0x7461636f; + pub const OPENPROM_SUPER_MAGIC: ::c_long = 0x00009fa1; + pub const OVERLAYFS_SUPER_MAGIC: ::c_long = 0x794c7630; + pub const PROC_SUPER_MAGIC: ::c_long = 0x00009fa0; + pub const QNX4_SUPER_MAGIC: ::c_long = 0x0000002f; + pub const QNX6_SUPER_MAGIC: ::c_long = 0x68191122; + pub const RDTGROUP_SUPER_MAGIC: ::c_long = 0x7655821; + pub const REISERFS_SUPER_MAGIC: ::c_long = 0x52654973; + pub const SECURITYFS_MAGIC: ::c_long = 0x73636673; + pub const SELINUX_MAGIC: ::c_long = 0xf97cff8c; + pub const SMACK_MAGIC: ::c_long = 0x43415d53; + pub const SMB_SUPER_MAGIC: ::c_long = 0x0000517b; + pub const SYSFS_MAGIC: ::c_long = 0x62656572; + pub const TMPFS_MAGIC: ::c_long = 0x01021994; + pub const TRACEFS_MAGIC: ::c_long = 0x74726163; + pub const UDF_SUPER_MAGIC: ::c_long = 0x15013346; + pub const USBDEVICE_SUPER_MAGIC: ::c_long = 0x00009fa2; + pub const XENFS_SUPER_MAGIC: ::c_long = 0xabba1974; + pub const NSFS_MAGIC: ::c_long = 0x6e736673; + } else if #[cfg(target_arch = "s390x")] { + pub const ADFS_SUPER_MAGIC: ::c_uint = 0x0000adf5; + pub const AFFS_SUPER_MAGIC: ::c_uint = 0x0000adff; + pub const AFS_SUPER_MAGIC: ::c_uint = 0x5346414f; + pub const AUTOFS_SUPER_MAGIC: ::c_uint = 0x0187; + pub const BPF_FS_MAGIC: ::c_uint = 0xcafe4a11; + pub const BTRFS_SUPER_MAGIC: ::c_uint = 0x9123683e; + pub const CGROUP2_SUPER_MAGIC: ::c_uint = 0x63677270; + pub const CGROUP_SUPER_MAGIC: ::c_uint = 0x27e0eb; + pub const CODA_SUPER_MAGIC: ::c_uint = 0x73757245; + pub const CRAMFS_MAGIC: ::c_uint = 0x28cd3d45; + pub const DEBUGFS_MAGIC: ::c_uint = 0x64626720; + pub const DEVPTS_SUPER_MAGIC: ::c_uint = 0x1cd1; + pub const ECRYPTFS_SUPER_MAGIC: ::c_uint = 0xf15f; + pub const EFS_SUPER_MAGIC: ::c_uint = 0x00414a53; + pub const EXT2_SUPER_MAGIC: ::c_uint = 0x0000ef53; + pub const EXT3_SUPER_MAGIC: ::c_uint = 0x0000ef53; + pub const EXT4_SUPER_MAGIC: ::c_uint = 0x0000ef53; + pub const F2FS_SUPER_MAGIC: ::c_uint = 0xf2f52010; + pub const FUSE_SUPER_MAGIC: ::c_uint = 0x65735546; + pub const FUTEXFS_SUPER_MAGIC: ::c_uint = 0xbad1dea; + pub const HOSTFS_SUPER_MAGIC: ::c_uint = 0x00c0ffee; + pub const HPFS_SUPER_MAGIC: ::c_uint = 0xf995e849; + pub const HUGETLBFS_MAGIC: ::c_uint = 0x958458f6; + pub const ISOFS_SUPER_MAGIC: ::c_uint = 0x00009660; + pub const JFFS2_SUPER_MAGIC: ::c_uint = 0x000072b6; + pub const MINIX2_SUPER_MAGIC2: ::c_uint = 0x00002478; + pub const MINIX2_SUPER_MAGIC: ::c_uint = 0x00002468; + pub const MINIX3_SUPER_MAGIC: ::c_uint = 0x4d5a; + pub const MINIX_SUPER_MAGIC2: ::c_uint = 0x0000138f; + pub const MINIX_SUPER_MAGIC: ::c_uint = 0x0000137f; + pub const MSDOS_SUPER_MAGIC: ::c_uint = 0x00004d44; + pub const NCP_SUPER_MAGIC: ::c_uint = 0x0000564c; + pub const NFS_SUPER_MAGIC: ::c_uint = 0x00006969; + pub const NILFS_SUPER_MAGIC: ::c_uint = 0x3434; + pub const OCFS2_SUPER_MAGIC: ::c_uint = 0x7461636f; + pub const OPENPROM_SUPER_MAGIC: ::c_uint = 0x00009fa1; + pub const OVERLAYFS_SUPER_MAGIC: ::c_uint = 0x794c7630; + pub const PROC_SUPER_MAGIC: ::c_uint = 0x00009fa0; + pub const QNX4_SUPER_MAGIC: ::c_uint = 0x0000002f; + pub const QNX6_SUPER_MAGIC: ::c_uint = 0x68191122; + pub const RDTGROUP_SUPER_MAGIC: ::c_uint = 0x7655821; + pub const REISERFS_SUPER_MAGIC: ::c_uint = 0x52654973; + pub const SECURITYFS_MAGIC: ::c_uint = 0x73636673; + pub const SELINUX_MAGIC: ::c_uint = 0xf97cff8c; + pub const SMACK_MAGIC: ::c_uint = 0x43415d53; + pub const SMB_SUPER_MAGIC: ::c_uint = 0x0000517b; + pub const SYSFS_MAGIC: ::c_uint = 0x62656572; + pub const TMPFS_MAGIC: ::c_uint = 0x01021994; + pub const TRACEFS_MAGIC: ::c_uint = 0x74726163; + pub const UDF_SUPER_MAGIC: ::c_uint = 0x15013346; + pub const USBDEVICE_SUPER_MAGIC: ::c_uint = 0x00009fa2; + pub const XENFS_SUPER_MAGIC: ::c_uint = 0xabba1974; + pub const NSFS_MAGIC: ::c_uint = 0x6e736673; + } +} + +const_fn! { + {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } +} + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { + cmsg.offset(1) as *mut ::c_uchar + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub fn SIGRTMAX() -> ::c_int { + unsafe { __libc_current_sigrtmax() } + } + + pub fn SIGRTMIN() -> ::c_int { + unsafe { __libc_current_sigrtmin() } + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0x7f) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } + + pub {const} fn W_EXITCODE(ret: ::c_int, sig: ::c_int) -> ::c_int { + (ret << 8) | sig + } + + pub {const} fn W_STOPCODE(sig: ::c_int) -> ::c_int { + (sig << 8) | 0x7f + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub {const} fn IPOPT_COPIED(o: u8) -> u8 { + o & IPOPT_COPY + } + + pub {const} fn IPOPT_CLASS(o: u8) -> u8 { + o & IPOPT_CLASS_MASK + } + + pub {const} fn IPOPT_NUMBER(o: u8) -> u8 { + o & IPOPT_NUMBER_MASK + } + + pub {const} fn IPTOS_ECN(x: u8) -> u8 { + x & ::IPTOS_ECN_MASK + } + + #[allow(ellipsis_inclusive_range_patterns)] + pub {const} fn KERNEL_VERSION(a: u32, b: u32, c: u32) -> u32 { + ((a << 16) + (b << 8)) + match c { + 0 ... 255 => c, + _ => 255, + } + } +} + +extern "C" { + #[doc(hidden)] + pub fn __libc_current_sigrtmax() -> ::c_int; + #[doc(hidden)] + pub fn __libc_current_sigrtmin() -> ::c_int; + + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn mincore(addr: *mut ::c_void, len: ::size_t, vec: *mut ::c_uchar) -> ::c_int; + + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn setgroups(ngroups: ::size_t, ptr: *const ::gid_t) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + pub fn clearenv() -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + #[deprecated( + since = "0.2.66", + note = "causes memory corruption, see rust-lang/libc#1596" + )] + pub fn vfork() -> ::pid_t; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; +} + +// LFS64 extensions +// +// * musl and Emscripten has 64-bit versions only so aliases the LFS64 symbols to the standard ones +// * ulibc doesn't have preadv64/pwritev64 +cfg_if! { + if #[cfg(not(any(target_env = "musl", target_os = "emscripten")))] { + extern "C" { + pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int; + pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int; + pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int; + pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int; + pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int; + pub fn fstatat64( + dirfd: ::c_int, + pathname: *const c_char, + buf: *mut stat64, + flags: ::c_int, + ) -> ::c_int; + pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int; + pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t; + pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int; + pub fn mmap64( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off64_t, + ) -> *mut ::c_void; + pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn openat64(fd: ::c_int, path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advise: ::c_int, + ) -> ::c_int; + pub fn pread64( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: off64_t + ) -> ::ssize_t; + pub fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: off64_t, + ) -> ::ssize_t; + pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64; + pub fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, + ) -> ::c_int; + pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int; + pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(not(any(target_env = "uclibc", target_env = "musl", target_os = "emscripten")))] { + extern "C" { + pub fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + pub fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + } + } +} + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + extern "C" { + // uclibc has separate non-const version of this function + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::pid_t; + // uclibc has separate non-const version of this function + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(target_os = "emscripten")] { + mod emscripten; + pub use self::emscripten::*; + } else if #[cfg(target_os = "linux")] { + mod linux; + pub use self::linux::*; + } else if #[cfg(target_os = "l4re")] { + mod linux; + pub use self::linux::*; + } else if #[cfg(target_os = "android")] { + mod android; + pub use self::android::*; + } else { + // Unknown target_os + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/mod.rs new file mode 100644 index 00000000..3dca8330 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/mod.rs @@ -0,0 +1,1616 @@ +//! Definitions found commonly among almost all Unix derivatives +//! +//! More functions and definitions can be found in the more specific modules +//! according to the platform in question. + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type pid_t = i32; +pub type in_addr_t = u32; +pub type in_port_t = u16; +pub type sighandler_t = ::size_t; +pub type cc_t = ::c_uchar; + +cfg_if! { + if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] { + pub type uid_t = ::c_ushort; + pub type gid_t = ::c_ushort; + } else if #[cfg(target_os = "nto")] { + pub type uid_t = i32; + pub type gid_t = i32; + } else { + pub type uid_t = u32; + pub type gid_t = u32; + } +} + +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum DIR {} +} +pub type locale_t = *mut ::c_void; + +s! { + pub struct group { + pub gr_name: *mut ::c_char, + pub gr_passwd: *mut ::c_char, + pub gr_gid: ::gid_t, + pub gr_mem: *mut *mut ::c_char, + } + + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + // linux x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=16437 + pub struct timespec { + pub tv_sec: time_t, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tv_nsec: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tv_nsec: ::c_long, + } + + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad1: u32, + pub ru_ixrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad2: u32, + pub ru_idrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad3: u32, + pub ru_isrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad4: u32, + pub ru_minflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad5: u32, + pub ru_majflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad6: u32, + pub ru_nswap: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad7: u32, + pub ru_inblock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad8: u32, + pub ru_oublock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad9: u32, + pub ru_msgsnd: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad10: u32, + pub ru_msgrcv: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad11: u32, + pub ru_nsignals: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad12: u32, + pub ru_nvcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad13: u32, + pub ru_nivcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: u32, + + #[cfg(any(target_env = "musl", target_env = "ohos", target_os = "emscripten"))] + __reserved: [c_long; 16], + } + + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + #[cfg(target_os = "android")] + pub ipv6mr_interface: ::c_int, + #[cfg(not(target_os = "android"))] + pub ipv6mr_interface: ::c_uint, + } + + pub struct hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: ::c_int, + pub h_length: ::c_int, + pub h_addr_list: *mut *mut ::c_char, + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: ::size_t, + } + + pub struct pollfd { + pub fd: ::c_int, + pub events: ::c_short, + pub revents: ::c_short, + } + + pub struct winsize { + pub ws_row: ::c_ushort, + pub ws_col: ::c_ushort, + pub ws_xpixel: ::c_ushort, + pub ws_ypixel: ::c_ushort, + } + + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct sigval { + // Actually a union of an int and a void* + pub sival_ptr: *mut ::c_void + } + + // + pub struct itimerval { + pub it_interval: ::timeval, + pub it_value: ::timeval, + } + + // + pub struct tms { + pub tms_utime: ::clock_t, + pub tms_stime: ::clock_t, + pub tms_cutime: ::clock_t, + pub tms_cstime: ::clock_t, + } + + pub struct servent { + pub s_name: *mut ::c_char, + pub s_aliases: *mut *mut ::c_char, + pub s_port: ::c_int, + pub s_proto: *mut ::c_char, + } + + pub struct protoent { + pub p_name: *mut ::c_char, + pub p_aliases: *mut *mut ::c_char, + pub p_proto: ::c_int, + } +} + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +pub const SIG_DFL: sighandler_t = 0 as sighandler_t; +pub const SIG_IGN: sighandler_t = 1 as sighandler_t; +pub const SIG_ERR: sighandler_t = !0 as sighandler_t; +cfg_if! { + if #[cfg(not(target_os = "nto"))] { + pub const DT_UNKNOWN: u8 = 0; + pub const DT_FIFO: u8 = 1; + pub const DT_CHR: u8 = 2; + pub const DT_DIR: u8 = 4; + pub const DT_BLK: u8 = 6; + pub const DT_REG: u8 = 8; + pub const DT_LNK: u8 = 10; + pub const DT_SOCK: u8 = 12; + } +} +cfg_if! { + if #[cfg(not(target_os = "redox"))] { + pub const FD_CLOEXEC: ::c_int = 0x1; + } +} + +cfg_if! { + if #[cfg(not(target_os = "nto"))] + { + pub const USRQUOTA: ::c_int = 0; + pub const GRPQUOTA: ::c_int = 1; + } +} +pub const SIGIOT: ::c_int = 6; + +pub const S_ISUID: ::mode_t = 0x800; +pub const S_ISGID: ::mode_t = 0x400; +pub const S_ISVTX: ::mode_t = 0x200; + +cfg_if! { + if #[cfg(not(any(target_os = "haiku", target_os = "illumos", + target_os = "solaris")))] { + pub const IF_NAMESIZE: ::size_t = 16; + pub const IFNAMSIZ: ::size_t = IF_NAMESIZE; + } +} + +pub const LOG_EMERG: ::c_int = 0; +pub const LOG_ALERT: ::c_int = 1; +pub const LOG_CRIT: ::c_int = 2; +pub const LOG_ERR: ::c_int = 3; +pub const LOG_WARNING: ::c_int = 4; +pub const LOG_NOTICE: ::c_int = 5; +pub const LOG_INFO: ::c_int = 6; +pub const LOG_DEBUG: ::c_int = 7; + +pub const LOG_KERN: ::c_int = 0; +pub const LOG_USER: ::c_int = 1 << 3; +pub const LOG_MAIL: ::c_int = 2 << 3; +pub const LOG_DAEMON: ::c_int = 3 << 3; +pub const LOG_AUTH: ::c_int = 4 << 3; +pub const LOG_SYSLOG: ::c_int = 5 << 3; +pub const LOG_LPR: ::c_int = 6 << 3; +pub const LOG_NEWS: ::c_int = 7 << 3; +pub const LOG_UUCP: ::c_int = 8 << 3; +pub const LOG_LOCAL0: ::c_int = 16 << 3; +pub const LOG_LOCAL1: ::c_int = 17 << 3; +pub const LOG_LOCAL2: ::c_int = 18 << 3; +pub const LOG_LOCAL3: ::c_int = 19 << 3; +pub const LOG_LOCAL4: ::c_int = 20 << 3; +pub const LOG_LOCAL5: ::c_int = 21 << 3; +pub const LOG_LOCAL6: ::c_int = 22 << 3; +pub const LOG_LOCAL7: ::c_int = 23 << 3; + +cfg_if! { + if #[cfg(not(target_os = "haiku"))] { + pub const LOG_PID: ::c_int = 0x01; + pub const LOG_CONS: ::c_int = 0x02; + pub const LOG_ODELAY: ::c_int = 0x04; + pub const LOG_NDELAY: ::c_int = 0x08; + pub const LOG_NOWAIT: ::c_int = 0x10; + } +} +pub const LOG_PRIMASK: ::c_int = 7; +pub const LOG_FACMASK: ::c_int = 0x3f8; + +cfg_if! { + if #[cfg(not(target_os = "nto"))] + { + pub const PRIO_MIN: ::c_int = -20; + pub const PRIO_MAX: ::c_int = 20; + } +} +pub const IPPROTO_ICMP: ::c_int = 1; +pub const IPPROTO_ICMPV6: ::c_int = 58; +pub const IPPROTO_TCP: ::c_int = 6; +pub const IPPROTO_UDP: ::c_int = 17; +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const INADDR_LOOPBACK: in_addr_t = 2130706433; +pub const INADDR_ANY: in_addr_t = 0; +pub const INADDR_BROADCAST: in_addr_t = 4294967295; +pub const INADDR_NONE: in_addr_t = 4294967295; + +pub const ARPOP_REQUEST: u16 = 1; +pub const ARPOP_REPLY: u16 = 2; + +pub const ATF_COM: ::c_int = 0x02; +pub const ATF_PERM: ::c_int = 0x04; +pub const ATF_PUBL: ::c_int = 0x08; +pub const ATF_USETRAILERS: ::c_int = 0x10; + +cfg_if! { + if #[cfg(any(target_os = "l4re", target_os = "espidf"))] { + // required libraries for L4Re and the ESP-IDF framework are linked externally, ATM + } else if #[cfg(feature = "std")] { + // cargo build, don't pull in anything extra as the std dep + // already pulls in all libs. + } else if #[cfg(all(target_os = "linux", + any(target_env = "gnu", target_env = "uclibc"), + feature = "rustc-dep-of-std"))] { + #[link(name = "util", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "rt", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "pthread", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "m", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "dl", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "gcc", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "util", cfg(not(target_feature = "crt-static")))] + #[link(name = "rt", cfg(not(target_feature = "crt-static")))] + #[link(name = "pthread", cfg(not(target_feature = "crt-static")))] + #[link(name = "m", cfg(not(target_feature = "crt-static")))] + #[link(name = "dl", cfg(not(target_feature = "crt-static")))] + #[link(name = "c", cfg(not(target_feature = "crt-static")))] + extern {} + } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + #[cfg_attr(feature = "rustc-dep-of-std", + link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static")))] + #[cfg_attr(feature = "rustc-dep-of-std", + link(name = "c", cfg(not(target_feature = "crt-static"))))] + extern {} + } else if #[cfg(target_os = "emscripten")] { + #[link(name = "c")] + extern {} + } else if #[cfg(all(target_os = "android", feature = "rustc-dep-of-std"))] { + #[link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "m", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "m", cfg(not(target_feature = "crt-static")))] + #[link(name = "c", cfg(not(target_feature = "crt-static")))] + extern {} + } else if #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "android", + target_os = "openbsd", + target_os = "nto", + ))] { + #[link(name = "c")] + #[link(name = "m")] + extern {} + } else if #[cfg(target_os = "haiku")] { + #[link(name = "root")] + #[link(name = "network")] + extern {} + } else if #[cfg(target_env = "newlib")] { + #[link(name = "c")] + #[link(name = "m")] + extern {} + } else if #[cfg(target_env = "illumos")] { + #[link(name = "c")] + #[link(name = "m")] + extern {} + } else if #[cfg(target_os = "redox")] { + #[cfg_attr(feature = "rustc-dep-of-std", + link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static")))] + #[cfg_attr(feature = "rustc-dep-of-std", + link(name = "c", cfg(not(target_feature = "crt-static"))))] + extern {} + } else if #[cfg(target_env = "aix")] { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "bsd")] + #[link(name = "pthread")] + extern {} + } else { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "rt")] + #[link(name = "pthread")] + extern {} + } +} + +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum FILE {} + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum fpos_t {} // FIXME: fill this out with a struct +} + +extern "C" { + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn isblank(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + pub fn qsort( + base: *mut c_void, + num: size_t, + size: size_t, + compar: ::Option c_int>, + ); + pub fn bsearch( + key: *const c_void, + base: *const c_void, + num: size_t, + size: size_t, + compar: ::Option c_int>, + ) -> *mut c_void; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fopen$UNIX2003" + )] + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "freopen$UNIX2003" + )] + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fputs$UNIX2003" + )] + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fwrite$UNIX2003" + )] + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + #[cfg_attr(target_os = "netbsd", link_name = "__fgetpos50")] + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__fsetpos50")] + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn clearerr(stream: *mut FILE); + pub fn perror(s: *const c_char); + pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; + pub fn atol(s: *const c_char) -> c_long; + pub fn atoll(s: *const c_char) -> c_longlong; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "strtod$UNIX2003" + )] + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; + pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; + pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; + pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "system$UNIX2003" + )] + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn stpcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strndup(cs: *const c_char, n: size_t) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "strerror$UNIX2003" + )] + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; + pub fn strtok_r(s: *mut c_char, t: *const c_char, p: *mut *mut c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn strsignal(sig: c_int) -> *mut c_char; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; +} + +extern "C" { + #[cfg_attr(target_os = "netbsd", link_name = "__getpwnam50")] + pub fn getpwnam(name: *const ::c_char) -> *mut passwd; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwuid50")] + pub fn getpwuid(uid: ::uid_t) -> *mut passwd; + + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "linux", not(target_env = "uclibc")), + link_name = "__isoc99_fscanf" + )] + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "linux", not(target_env = "uclibc")), + link_name = "__isoc99_scanf" + )] + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "linux", not(target_env = "uclibc")), + link_name = "__isoc99_sscanf" + )] + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "netbsd", link_name = "__socket30")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_socket")] + #[cfg_attr(target_os = "espidf", link_name = "lwip_socket")] + pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "connect$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_connect")] + #[cfg_attr(target_os = "espidf", link_name = "lwip_connect")] + pub fn connect(socket: ::c_int, address: *const sockaddr, len: socklen_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "listen$UNIX2003" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_listen")] + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "accept$UNIX2003" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_accept")] + pub fn accept(socket: ::c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getpeername$UNIX2003" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_getpeername")] + pub fn getpeername( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getsockname$UNIX2003" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_getsockname")] + pub fn getsockname( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + #[cfg_attr(target_os = "espidf", link_name = "lwip_setsockopt")] + pub fn setsockopt( + socket: ::c_int, + level: ::c_int, + name: ::c_int, + value: *const ::c_void, + option_len: socklen_t, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "socketpair$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_socketpair")] + pub fn socketpair( + domain: ::c_int, + type_: ::c_int, + protocol: ::c_int, + socket_vector: *mut ::c_int, + ) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sendto$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendto")] + #[cfg_attr(target_os = "espidf", link_name = "lwip_sendto")] + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; + #[cfg_attr(target_os = "espidf", link_name = "lwip_shutdown")] + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "chmod$UNIX2003" + )] + pub fn chmod(path: *const c_char, mode: mode_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fchmod$UNIX2003" + )] + pub fn fchmod(fd: ::c_int, mode: mode_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "fstat$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__fstat50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "fstat@FBSD_1.0" + )] + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "stat$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__stat50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "stat@FBSD_1.0" + )] + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn pclose(stream: *mut ::FILE) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fdopen$UNIX2003" + )] + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "open$UNIX2003" + )] + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "creat$UNIX2003" + )] + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fcntl$UNIX2003" + )] + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "opendir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "opendir$INODE64$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__opendir30")] + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "readdir$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__readdir30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "readdir@FBSD_1.0" + )] + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "closedir$UNIX2003" + )] + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "rewinddir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "rewinddir$INODE64$UNIX2003" + )] + pub fn rewinddir(dirp: *mut ::DIR); + + pub fn fchmodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fchown(fd: ::c_int, owner: ::uid_t, group: ::gid_t) -> ::c_int; + pub fn fchownat( + dirfd: ::c_int, + pathname: *const ::c_char, + owner: ::uid_t, + group: ::gid_t, + flags: ::c_int, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "fstatat$INODE64" + )] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "fstatat@FBSD_1.1" + )] + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn alarm(seconds: ::c_uint) -> ::c_uint; + pub fn chdir(dir: *const c_char) -> ::c_int; + pub fn fchdir(dirfd: ::c_int) -> ::c_int; + pub fn chown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "lchown$UNIX2003" + )] + pub fn lchown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "close$NOCANCEL$UNIX2003" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "close$NOCANCEL" + )] + pub fn close(fd: ::c_int) -> ::c_int; + pub fn dup(fd: ::c_int) -> ::c_int; + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> ::c_int; + pub fn execle(path: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execlp(file: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execve( + prog: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn fork() -> pid_t; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; + pub fn getegid() -> gid_t; + pub fn geteuid() -> uid_t; + pub fn getgid() -> gid_t; + pub fn getgroups(ngroups_max: ::c_int, groups: *mut gid_t) -> ::c_int; + #[cfg_attr(target_os = "illumos", link_name = "getloginx")] + pub fn getlogin() -> *mut c_char; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getopt$UNIX2003" + )] + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn getpgid(pid: pid_t) -> pid_t; + pub fn getpgrp() -> pid_t; + pub fn getpid() -> pid_t; + pub fn getppid() -> pid_t; + pub fn getuid() -> uid_t; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pipe(fds: *mut ::c_int) -> ::c_int; + pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "read$UNIX2003" + )] + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t) -> ::ssize_t; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn seteuid(uid: uid_t) -> ::c_int; + pub fn setegid(gid: gid_t) -> ::c_int; + pub fn setgid(gid: gid_t) -> ::c_int; + pub fn setpgid(pid: pid_t, pgid: pid_t) -> ::c_int; + pub fn setsid() -> pid_t; + pub fn setuid(uid: uid_t) -> ::c_int; + pub fn setreuid(ruid: uid_t, euid: uid_t) -> ::c_int; + pub fn setregid(rgid: gid_t, egid: gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sleep$UNIX2003" + )] + pub fn sleep(secs: ::c_uint) -> ::c_uint; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "nanosleep$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__nanosleep50")] + pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> ::c_int; + pub fn tcgetpgrp(fd: ::c_int) -> pid_t; + pub fn tcsetpgrp(fd: ::c_int, pgrp: ::pid_t) -> ::c_int; + pub fn ttyname(fd: ::c_int) -> *mut c_char; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "ttyname_r$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__posix_ttyname_r")] + pub fn ttyname_r(fd: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn unlink(c: *const c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "wait$UNIX2003" + )] + pub fn wait(status: *mut ::c_int) -> pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "waitpid$UNIX2003" + )] + pub fn waitpid(pid: pid_t, status: *mut ::c_int, options: ::c_int) -> pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "write$UNIX2003" + )] + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pread$UNIX2003" + )] + pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pwrite$UNIX2003" + )] + pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn umask(mask: mode_t) -> mode_t; + + #[cfg_attr(target_os = "netbsd", link_name = "__utime50")] + pub fn utime(file: *const c_char, buf: *const utimbuf) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "kill$UNIX2003" + )] + pub fn kill(pid: pid_t, sig: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "killpg$UNIX2003" + )] + pub fn killpg(pgrp: pid_t, sig: ::c_int) -> ::c_int; + + pub fn mlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn munlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn mlockall(flags: ::c_int) -> ::c_int; + pub fn munlockall() -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "mmap$UNIX2003" + )] + pub fn mmap( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off_t, + ) -> *mut ::c_void; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "munmap$UNIX2003" + )] + pub fn munmap(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + + pub fn if_nametoindex(ifname: *const c_char) -> ::c_uint; + pub fn if_indextoname(ifindex: ::c_uint, ifname: *mut ::c_char) -> *mut ::c_char; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "lstat$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__lstat50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "lstat@FBSD_1.0" + )] + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fsync$UNIX2003" + )] + pub fn fsync(fd: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setenv$UNIX2003" + )] + pub fn setenv(name: *const c_char, val: *const c_char, overwrite: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "unsetenv$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__unsetenv13")] + pub fn unsetenv(name: *const c_char) -> ::c_int; + + pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int; + + pub fn truncate(path: *const c_char, length: off_t) -> ::c_int; + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t; + + #[cfg_attr(target_os = "netbsd", link_name = "__getrusage50")] + pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int; + + #[cfg_attr( + any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos" + ), + link_name = "realpath$DARWIN_EXTSN" + )] + pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char; + + pub fn flock(fd: ::c_int, operation: ::c_int) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__times13")] + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn pthread_self() -> ::pthread_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_join$UNIX2003" + )] + pub fn pthread_join(native: ::pthread_t, value: *mut *mut ::c_void) -> ::c_int; + pub fn pthread_exit(value: *mut ::c_void) -> !; + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_destroy(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstacksize( + attr: *const ::pthread_attr_t, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stack_size: ::size_t) -> ::c_int; + pub fn pthread_attr_setdetachstate(attr: *mut ::pthread_attr_t, state: ::c_int) -> ::c_int; + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__libc_thr_yield")] + pub fn sched_yield() -> ::c_int; + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: ::Option, + ) -> ::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ::c_void) -> ::c_int; + pub fn pthread_mutex_init( + lock: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> ::c_int; + pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> ::c_int; + + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_mutexattr_destroy$UNIX2003" + )] + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> ::c_int; + pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_init$UNIX2003" + )] + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) + -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_wait$UNIX2003" + )] + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_timedwait$UNIX2003" + )] + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_condattr_init(attr: *mut pthread_condattr_t) -> ::c_int; + pub fn pthread_condattr_destroy(attr: *mut pthread_condattr_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_init$UNIX2003" + )] + pub fn pthread_rwlock_init( + lock: *mut pthread_rwlock_t, + attr: *const pthread_rwlockattr_t, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_destroy$UNIX2003" + )] + pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_rdlock$UNIX2003" + )] + pub fn pthread_rwlock_rdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_tryrdlock$UNIX2003" + )] + pub fn pthread_rwlock_tryrdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_wrlock$UNIX2003" + )] + pub fn pthread_rwlock_wrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_trywrlock$UNIX2003" + )] + pub fn pthread_rwlock_trywrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_unlock$UNIX2003" + )] + pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> ::c_int; + pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> ::c_int; + + #[cfg_attr(target_os = "illumos", link_name = "__xnet_getsockopt")] + #[cfg_attr(target_os = "espidf", link_name = "lwip_getsockopt")] + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + pub fn raise(signum: ::c_int) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__utimes50")] + pub fn utimes(filename: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn dlopen(filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + pub fn dlerror() -> *mut ::c_char; + pub fn dlsym(handle: *mut ::c_void, symbol: *const ::c_char) -> *mut ::c_void; + pub fn dlclose(handle: *mut ::c_void) -> ::c_int; + + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_getaddrinfo")] + #[cfg_attr(target_os = "espidf", link_name = "lwip_getaddrinfo")] + pub fn getaddrinfo( + node: *const c_char, + service: *const c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "espidf", link_name = "lwip_freeaddrinfo")] + pub fn freeaddrinfo(res: *mut addrinfo); + pub fn hstrerror(errcode: ::c_int) -> *const ::c_char; + pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char; + #[cfg_attr( + any( + all( + target_os = "linux", + not(any(target_env = "musl", target_env = "ohos")) + ), + target_os = "freebsd", + target_os = "dragonfly", + target_os = "haiku" + ), + link_name = "__res_init" + )] + #[cfg_attr( + any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos" + ), + link_name = "res_9_init" + )] + pub fn res_init() -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime_r50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__localtime_r50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn localtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "mktime$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__mktime50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn mktime(tm: *mut tm) -> time_t; + #[cfg_attr(target_os = "netbsd", link_name = "__time50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn time(time: *mut time_t) -> time_t; + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn gmtime(time_p: *const time_t) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__locatime50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn localtime(time_p: *const time_t) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__difftime50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn difftime(time1: time_t, time0: time_t) -> ::c_double; + #[cfg_attr(target_os = "netbsd", link_name = "__timegm50")] + #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn timegm(tm: *mut ::tm) -> time_t; + + #[cfg_attr(target_os = "netbsd", link_name = "__mknod50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "mknod@FBSD_1.0" + )] + pub fn mknod(pathname: *const ::c_char, mode: ::mode_t, dev: ::dev_t) -> ::c_int; + pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn endservent(); + pub fn getservbyname(name: *const ::c_char, proto: *const ::c_char) -> *mut servent; + pub fn getservbyport(port: ::c_int, proto: *const ::c_char) -> *mut servent; + pub fn getservent() -> *mut servent; + pub fn setservent(stayopen: ::c_int); + pub fn getprotobyname(name: *const ::c_char) -> *mut protoent; + pub fn getprotobynumber(proto: ::c_int) -> *mut protoent; + pub fn chroot(name: *const ::c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "usleep$UNIX2003" + )] + pub fn usleep(secs: ::c_uint) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "send$UNIX2003" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_send")] + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "recv$UNIX2003" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_recv")] + pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "putenv$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__putenv50")] + pub fn putenv(string: *mut c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "poll$UNIX2003" + )] + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "select$1050" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "select$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__select50")] + pub fn select( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval, + ) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__setlocale50")] + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sem_wait$UNIX2003" + )] + pub fn sem_wait(sem: *mut sem_t) -> ::c_int; + pub fn sem_trywait(sem: *mut sem_t) -> ::c_int; + pub fn sem_post(sem: *mut sem_t) -> ::c_int; + pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")] + pub fn sigemptyset(set: *mut sigset_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")] + pub fn sigaddset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigfillset14")] + pub fn sigfillset(set: *mut sigset_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigdelset14")] + pub fn sigdelset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigismember14")] + pub fn sigismember(set: *const sigset_t, signum: ::c_int) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__sigprocmask14")] + pub fn sigprocmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigpending14")] + pub fn sigpending(set: *mut sigset_t) -> ::c_int; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn mkfifo(path: *const c_char, mode: mode_t) -> ::c_int; + + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "tcdrain$UNIX2003" + )] + pub fn tcdrain(fd: ::c_int) -> ::c_int; + pub fn cfgetispeed(termios: *const ::termios) -> ::speed_t; + pub fn cfgetospeed(termios: *const ::termios) -> ::speed_t; + pub fn cfsetispeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn cfsetospeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn tcgetattr(fd: ::c_int, termios: *mut ::termios) -> ::c_int; + pub fn tcsetattr(fd: ::c_int, optional_actions: ::c_int, termios: *const ::termios) -> ::c_int; + pub fn tcflow(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcflush(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcgetsid(fd: ::c_int) -> ::pid_t; + pub fn tcsendbreak(fd: ::c_int, duration: ::c_int) -> ::c_int; + pub fn mkstemp(template: *mut ::c_char) -> ::c_int; + pub fn mkdtemp(template: *mut ::c_char) -> *mut ::c_char; + + pub fn tmpnam(ptr: *mut ::c_char) -> *mut ::c_char; + + pub fn openlog(ident: *const ::c_char, logopt: ::c_int, facility: ::c_int); + pub fn closelog(); + pub fn setlogmask(maskpri: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "macos", link_name = "syslog$DARWIN_EXTSN")] + pub fn syslog(priority: ::c_int, message: *const ::c_char, ...); + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "nice$UNIX2003" + )] + pub fn nice(incr: ::c_int) -> ::c_int; + + pub fn grantpt(fd: ::c_int) -> ::c_int; + pub fn posix_openpt(flags: ::c_int) -> ::c_int; + pub fn ptsname(fd: ::c_int) -> *mut ::c_char; + pub fn unlockpt(fd: ::c_int) -> ::c_int; + + pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t; + + pub fn lockf(fd: ::c_int, cmd: ::c_int, len: ::off_t) -> ::c_int; + +} + +cfg_if! { + if #[cfg(not(any(target_os = "emscripten", + target_os = "android", + target_os = "haiku", + target_os = "nto")))] { + extern "C" { + pub fn adjtime(delta: *const timeval, olddelta: *mut timeval) -> ::c_int; + pub fn stpncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + } + } +} + +cfg_if! { + if #[cfg(not(target_os = "aix"))] { + extern "C" { + pub fn dladdr(addr: *const ::c_void, info: *mut Dl_info) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(not(any(target_env = "uclibc", target_os = "nto")))] { + extern "C" { + pub fn open_wmemstream( + ptr: *mut *mut wchar_t, + sizeloc: *mut size_t, + ) -> *mut FILE; + } + } +} + +cfg_if! { + if #[cfg(not(target_os = "redox"))] { + extern { + pub fn getsid(pid: pid_t) -> pid_t; + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "pause$UNIX2003")] + pub fn pause() -> ::c_int; + + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, + mode: ::mode_t) -> ::c_int; + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, + flags: ::c_int, ...) -> ::c_int; + + #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"), + link_name = "fdopendir$INODE64")] + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "fdopendir$INODE64$UNIX2003")] + pub fn fdopendir(fd: ::c_int) -> *mut ::DIR; + + #[cfg_attr(all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "readdir_r$INODE64")] + #[cfg_attr(target_os = "netbsd", link_name = "__readdir_r30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "readdir_r@FBSD_1.0" + )] + #[allow(non_autolinks)] // FIXME: `<>` breaks line length limit. + /// The 64-bit libc on Solaris and illumos only has readdir_r. If a + /// 32-bit Solaris or illumos target is ever created, it should use + /// __posix_readdir_r. See libc(3LIB) on Solaris or illumos: + /// https://illumos.org/man/3lib/libc + /// https://docs.oracle.com/cd/E36784_01/html/E36873/libc-3lib.html + /// https://www.unix.com/man-page/opensolaris/3LIB/libc/ + pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, + result: *mut *mut ::dirent) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(target_os = "nto")] { + extern { + pub fn readlinkat(dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t) -> ::c_int; + pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::c_int; + pub fn pselect( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn sigaction( + signum: ::c_int, + act: *const sigaction, + oldact: *mut sigaction + ) -> ::c_int; + } + } else { + extern { + pub fn readlinkat(dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t) -> ::ssize_t; + pub fn fmemopen(buf: *mut c_void, size: size_t, mode: *const c_char) -> *mut FILE; + pub fn open_memstream(ptr: *mut *mut c_char, sizeloc: *mut size_t) -> *mut FILE; + pub fn atexit(cb: extern "C" fn()) -> c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigaction14")] + pub fn sigaction( + signum: ::c_int, + act: *const sigaction, + oldact: *mut sigaction + ) -> ::c_int; + pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "pselect$1050" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pselect$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__pselect50")] + pub fn pselect( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(not(any(target_os = "solaris", + target_os = "illumos", + target_os = "nto", + )))] { + extern { + pub fn cfmakeraw(termios: *mut ::termios); + pub fn cfsetspeed(termios: *mut ::termios, + speed: ::speed_t) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(target_env = "newlib")] { + mod newlib; + pub use self::newlib::*; + } else if #[cfg(any(target_os = "linux", + target_os = "l4re", + target_os = "android", + target_os = "emscripten"))] { + mod linux_like; + pub use self::linux_like::*; + } else if #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd"))] { + mod bsd; + pub use self::bsd::*; + } else if #[cfg(any(target_os = "solaris", + target_os = "illumos"))] { + mod solarish; + pub use self::solarish::*; + } else if #[cfg(target_os = "haiku")] { + mod haiku; + pub use self::haiku::*; + } else if #[cfg(target_os = "redox")] { + mod redox; + pub use self::redox::*; + } else if #[cfg(target_os = "nto")] { + mod nto; + pub use self::nto::*; + } else if #[cfg(target_os = "aix")] { + mod aix; + pub use self::aix::*; + } else if #[cfg(target_os = "hurd")] { + mod hurd; + pub use self::hurd::*; + } else { + // Unknown target_os + } +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/aarch64/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/aarch64/mod.rs new file mode 100644 index 00000000..2b4713c9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/aarch64/mod.rs @@ -0,0 +1,54 @@ +pub type clock_t = ::c_long; +pub type c_char = u8; +pub type wchar_t = u32; + +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } +} + +pub const AF_INET6: ::c_int = 23; + +pub const FIONBIO: ::c_ulong = 1; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; + +pub const SOL_SOCKET: ::c_int = 65535; + +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTWAIT: ::c_int = 4; +pub const MSG_DONTROUTE: ::c_int = 0; +pub const MSG_WAITALL: ::c_int = 0; +pub const MSG_MORE: ::c_int = 0; +pub const MSG_NOSIGNAL: ::c_int = 0; + +pub use crate::unix::newlib::generic::{dirent, sigset_t, stat}; diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/align.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/align.rs new file mode 100644 index 00000000..db9beb83 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/align.rs @@ -0,0 +1,61 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + pub struct pthread_mutex_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + pub struct pthread_rwlock_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(8))] + pub struct pthread_cond_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/arm/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/arm/mod.rs new file mode 100644 index 00000000..23b75977 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/arm/mod.rs @@ -0,0 +1,56 @@ +pub type clock_t = ::c_long; +pub type c_char = u8; +pub type wchar_t = u32; + +pub type c_long = i32; +pub type c_ulong = u32; + +s! { + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + pub __ss_padding: [u8; 26], + } +} + +pub const AF_INET6: ::c_int = 23; + +pub const FIONBIO: ::c_ulong = 1; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLHUP: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLOUT: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; + +pub const SOL_SOCKET: ::c_int = 65535; + +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTWAIT: ::c_int = 4; +pub const MSG_DONTROUTE: ::c_int = 0; +pub const MSG_WAITALL: ::c_int = 0; +pub const MSG_MORE: ::c_int = 0; +pub const MSG_NOSIGNAL: ::c_int = 0; + +pub use crate::unix::newlib::generic::{dirent, sigset_t, stat}; diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/espidf/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/espidf/mod.rs new file mode 100644 index 00000000..409d7ad9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/espidf/mod.rs @@ -0,0 +1,110 @@ +pub type clock_t = ::c_ulong; +pub type c_char = i8; +pub type wchar_t = u32; + +pub type c_long = i32; +pub type c_ulong = u32; + +s! { + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct sockaddr_un { + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108], + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } + + pub struct sockaddr_storage { + pub s2_len: u8, + pub ss_family: ::sa_family_t, + pub s2_data1: [::c_char; 2], + pub s2_data2: [u32; 3], + pub s2_data3: [u32; 3], + } +} + +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET6: ::c_int = 10; + +pub const FIONBIO: ::c_ulong = 2147772030; + +pub const POLLIN: ::c_short = 1 << 0; +pub const POLLRDNORM: ::c_short = 1 << 1; +pub const POLLRDBAND: ::c_short = 1 << 2; +pub const POLLPRI: ::c_short = POLLRDBAND; +pub const POLLOUT: ::c_short = 1 << 3; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLWRBAND: ::c_short = 1 << 4; +pub const POLLERR: ::c_short = 1 << 5; +pub const POLLHUP: ::c_short = 1 << 6; + +pub const SOL_SOCKET: ::c_int = 0xfff; + +pub const MSG_OOB: ::c_int = 0x04; +pub const MSG_PEEK: ::c_int = 0x01; +pub const MSG_DONTWAIT: ::c_int = 0x08; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_WAITALL: ::c_int = 0x02; +pub const MSG_MORE: ::c_int = 0x10; +pub const MSG_NOSIGNAL: ::c_int = 0x20; +pub const MSG_TRUNC: ::c_int = 0x04; +pub const MSG_CTRUNC: ::c_int = 0x08; +pub const MSG_EOR: ::c_int = 0x08; + +pub const PTHREAD_STACK_MIN: ::size_t = 768; + +extern "C" { + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + + #[link_name = "lwip_sendmsg"] + pub fn sendmsg(s: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + #[link_name = "lwip_recvmsg"] + pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + pub fn eventfd(initval: ::c_uint, flags: ::c_int) -> ::c_int; +} + +pub use crate::unix::newlib::generic::{dirent, sigset_t, stat}; diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/generic.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/generic.rs new file mode 100644 index 00000000..e45413a7 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/generic.rs @@ -0,0 +1,33 @@ +//! Common types used by most newlib platforms + +s! { + pub struct sigset_t { + __val: [::c_ulong; 16], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_spare1: ::c_long, + pub st_mtime: ::time_t, + pub st_spare2: ::c_long, + pub st_ctime: ::time_t, + pub st_spare3: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_spare4: [::c_long; 2usize], + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256usize], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/horizon/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/horizon/mod.rs new file mode 100644 index 00000000..9c70f7b0 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/horizon/mod.rs @@ -0,0 +1,270 @@ +//! ARMv6K Nintendo 3DS C Newlib definitions + +pub type c_char = u8; +pub type c_long = i32; +pub type c_ulong = u32; + +pub type wchar_t = ::c_uint; + +pub type u_register_t = ::c_uint; +pub type u_char = ::c_uchar; +pub type u_short = ::c_ushort; +pub type u_int = ::c_uint; +pub type u_long = c_ulong; +pub type ushort = ::c_ushort; +pub type uint = ::c_uint; +pub type ulong = c_ulong; +pub type clock_t = c_ulong; +pub type daddr_t = c_long; +pub type caddr_t = *mut c_char; +pub type sbintime_t = ::c_longlong; +pub type sigset_t = ::c_ulong; + +s! { + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 26usize], + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + pub __ss_padding: [::c_char; 26usize], + } + + pub struct sockaddr_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + } + + pub struct sockaddr_in6 { + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_un { + pub sun_len: ::c_uchar, + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 104usize], + } + + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atim: ::timespec, + pub st_mtim: ::timespec, + pub st_ctim: ::timespec, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_spare4: [::c_long; 2usize], + } +} + +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_SIGNAL: ::c_int = 2; +pub const SIGEV_THREAD: ::c_int = 3; +pub const SA_NOCLDSTOP: ::c_int = 1; +pub const MINSIGSTKSZ: ::c_int = 2048; +pub const SIGSTKSZ: ::c_int = 8192; +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 0; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGTRAP: ::c_int = 5; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGBUS: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGSYS: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGURG: ::c_int = 16; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGCONT: ::c_int = 19; +pub const SIGCHLD: ::c_int = 20; +pub const SIGCLD: ::c_int = 20; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGIO: ::c_int = 23; +pub const SIGPOLL: ::c_int = 23; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGLOST: ::c_int = 29; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const NSIG: ::c_int = 32; +pub const CLOCK_ENABLED: ::c_uint = 1; +pub const CLOCK_DISABLED: ::c_uint = 0; +pub const CLOCK_ALLOWED: ::c_uint = 1; +pub const CLOCK_DISALLOWED: ::c_uint = 0; +pub const TIMER_ABSTIME: ::c_uint = 4; +pub const SOL_SOCKET: ::c_int = 65535; +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTWAIT: ::c_int = 4; +pub const MSG_DONTROUTE: ::c_int = 0; +pub const MSG_WAITALL: ::c_int = 0; +pub const MSG_MORE: ::c_int = 0; +pub const MSG_NOSIGNAL: ::c_int = 0; +pub const SOL_CONFIG: ::c_uint = 65534; + +pub const _SC_PAGESIZE: ::c_int = 8; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51; + +pub const PTHREAD_STACK_MIN: ::size_t = 4096; +pub const WNOHANG: ::c_int = 1; + +pub const POLLIN: ::c_short = 0x0001; +pub const POLLPRI: ::c_short = 0x0002; +pub const POLLOUT: ::c_short = 0x0004; +pub const POLLRDNORM: ::c_short = 0x0040; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLRDBAND: ::c_short = 0x0080; +pub const POLLWRBAND: ::c_short = 0x0100; +pub const POLLERR: ::c_short = 0x0008; +pub const POLLHUP: ::c_short = 0x0010; +pub const POLLNVAL: ::c_short = 0x0020; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_BADHINTS: ::c_int = 12; +pub const EAI_PROTOCOL: ::c_int = 13; +pub const EAI_OVERFLOW: ::c_int = 14; +pub const EAI_MAX: ::c_int = 15; + +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET6: ::c_int = 23; + +pub const FIONBIO: ::c_ulong = 1; + +pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void; + +// For pthread get/setschedparam +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; + +// For getrandom() +pub const GRND_NONBLOCK: ::c_uint = 0x1; +pub const GRND_RANDOM: ::c_uint = 0x2; + +// Horizon OS works doesn't or can't hold any of this information +safe_f! { + pub {const} fn WIFSTOPPED(_status: ::c_int) -> bool { + false + } + + pub {const} fn WSTOPSIG(_status: ::c_int) -> ::c_int { + 0 + } + + pub {const} fn WIFCONTINUED(_status: ::c_int) -> bool { + true + } + + pub {const} fn WIFSIGNALED(_status: ::c_int) -> bool { + false + } + + pub {const} fn WTERMSIG(_status: ::c_int) -> ::c_int { + 0 + } + + pub {const} fn WIFEXITED(_status: ::c_int) -> bool { + true + } + + pub {const} fn WEXITSTATUS(_status: ::c_int) -> ::c_int { + 0 + } + + pub {const} fn WCOREDUMP(_status: ::c_int) -> bool { + false + } +} + +extern "C" { + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + + pub fn pthread_attr_getschedparam( + attr: *const ::pthread_attr_t, + param: *mut sched_param, + ) -> ::c_int; + + pub fn pthread_attr_setschedparam( + attr: *mut ::pthread_attr_t, + param: *const sched_param, + ) -> ::c_int; + + pub fn pthread_attr_getprocessorid_np( + attr: *const ::pthread_attr_t, + processor_id: *mut ::c_int, + ) -> ::c_int; + + pub fn pthread_attr_setprocessorid_np( + attr: *mut ::pthread_attr_t, + processor_id: ::c_int, + ) -> ::c_int; + + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn pthread_condattr_getclock( + attr: *const ::pthread_condattr_t, + clock_id: *mut ::clockid_t, + ) -> ::c_int; + + pub fn pthread_condattr_setclock( + attr: *mut ::pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + + pub fn pthread_getprocessorid_np() -> ::c_int; + + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + + pub fn gethostid() -> ::c_long; +} + +pub use crate::unix::newlib::generic::dirent; diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/mod.rs new file mode 100644 index 00000000..a572cc38 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/mod.rs @@ -0,0 +1,798 @@ +pub type blkcnt_t = i32; +pub type blksize_t = i32; + +pub type clockid_t = ::c_ulong; + +cfg_if! { + if #[cfg(any(target_os = "espidf"))] { + pub type dev_t = ::c_short; + pub type ino_t = ::c_ushort; + pub type off_t = ::c_long; + } else if #[cfg(any(target_os = "vita"))] { + pub type dev_t = ::c_short; + pub type ino_t = ::c_ushort; + pub type off_t = ::c_int; + } else { + pub type dev_t = u32; + pub type ino_t = u32; + pub type off_t = i64; + } +} + +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u32; +pub type id_t = u32; +pub type key_t = ::c_int; +pub type loff_t = ::c_longlong; +pub type mode_t = ::c_uint; +pub type nfds_t = u32; +pub type nlink_t = ::c_ushort; +pub type pthread_t = ::c_ulong; +pub type pthread_key_t = ::c_uint; +pub type rlim_t = u32; + +cfg_if! { + if #[cfg(target_os = "horizon")] { + pub type sa_family_t = u16; + } else { + pub type sa_family_t = u8; + } +} + +pub type socklen_t = u32; +pub type speed_t = u32; +pub type suseconds_t = i32; +pub type tcflag_t = ::c_uint; +pub type useconds_t = u32; + +cfg_if! { + if #[cfg(any(target_os = "horizon", all(target_os = "espidf", espidf_time64)))] { + pub type time_t = ::c_longlong; + } else { + pub type time_t = i32; + } +} + +s! { + // The order of the `ai_addr` field in this struct is crucial + // for converting between the Rust and C types. + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + + #[cfg(target_os = "espidf")] + pub ai_addr: *mut sockaddr, + + pub ai_canonname: *mut ::c_char, + + #[cfg(not(any( + target_os = "espidf", + all(libc_cfg_target_vendor, target_arch = "powerpc", target_vendor = "nintendo"))))] + pub ai_addr: *mut sockaddr, + + pub ai_next: *mut addrinfo, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: ::c_int, + pub h_length: ::c_int, + pub h_addr_list: *mut *mut ::c_char, + pub h_addr: *mut ::c_char, + } + + pub struct pollfd { + pub fd: ::c_int, + pub events: ::c_int, + pub revents: ::c_int, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: fsblkcnt_t, + pub f_bfree: fsblkcnt_t, + pub f_bavail: fsblkcnt_t, + pub f_files: fsfilcnt_t, + pub f_ffree: fsfilcnt_t, + pub f_favail: fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct sigaction { + pub sa_handler: extern fn(arg1: ::c_int), + pub sa_mask: sigset_t, + pub sa_flags: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: usize, + } + + pub struct fd_set { // Unverified + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } + + pub struct passwd { // Unverified + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct termios { // Unverified + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct sem_t { // Unverified + __size: [::c_char; 16], + } + + pub struct Dl_info { // Unverified + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct utsname { // Unverified + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct cpu_set_t { // Unverified + bits: [u32; 32], + } + + pub struct pthread_attr_t { // Unverified + __size: [u8; __SIZEOF_PTHREAD_ATTR_T] + } + + pub struct pthread_rwlockattr_t { // Unverified + __size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T] + } +} + +// unverified constants +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} +pub const NCCS: usize = 32; + +cfg_if! { + if #[cfg(target_os = "espidf")] { + const __PTHREAD_INITIALIZER_BYTE: u8 = 0xff; + pub const __SIZEOF_PTHREAD_ATTR_T: usize = 32; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 12; + pub const __SIZEOF_PTHREAD_COND_T: usize = 4; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 12; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + } else if #[cfg(target_os = "vita")] { + const __PTHREAD_INITIALIZER_BYTE: u8 = 0xff; + pub const __SIZEOF_PTHREAD_ATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_COND_T: usize = 4; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 4; + } else { + const __PTHREAD_INITIALIZER_BYTE: u8 = 0; + pub const __SIZEOF_PTHREAD_ATTR_T: usize = 56; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + } +} + +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __PTHREAD_MUTEX_HAVE_PREV: usize = 1; +pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: usize = 1; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; + +cfg_if! { + if #[cfg(any(target_os = "horizon", target_os = "espidf"))] { + pub const FD_SETSIZE: usize = 64; + } else if #[cfg(target_os = "vita")] { + pub const FD_SETSIZE: usize = 256; + } else { + pub const FD_SETSIZE: usize = 1024; + } +} +// intentionally not public, only used for fd_set +const ULONG_SIZE: usize = 32; + +// Other constants +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const EDEADLK: ::c_int = 45; +pub const ENOLCK: ::c_int = 46; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENOLINK: ::c_int = 67; +pub const EPROTO: ::c_int = 71; +pub const EMULTIHOP: ::c_int = 74; +pub const EBADMSG: ::c_int = 77; +pub const EFTYPE: ::c_int = 79; +pub const ENOSYS: ::c_int = 88; +pub const ENOTEMPTY: ::c_int = 90; +pub const ENAMETOOLONG: ::c_int = 91; +pub const ELOOP: ::c_int = 92; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EAFNOSUPPORT: ::c_int = 106; +pub const EPROTOTYPE: ::c_int = 107; +pub const ENOTSOCK: ::c_int = 108; +pub const ENOPROTOOPT: ::c_int = 109; +pub const ECONNREFUSED: ::c_int = 111; +pub const EADDRINUSE: ::c_int = 112; +pub const ECONNABORTED: ::c_int = 113; +pub const ENETUNREACH: ::c_int = 114; +pub const ENETDOWN: ::c_int = 115; +pub const ETIMEDOUT: ::c_int = 116; +pub const EHOSTDOWN: ::c_int = 117; +pub const EHOSTUNREACH: ::c_int = 118; +pub const EINPROGRESS: ::c_int = 119; +pub const EALREADY: ::c_int = 120; +pub const EDESTADDRREQ: ::c_int = 121; +pub const EMSGSIZE: ::c_int = 122; +pub const EPROTONOSUPPORT: ::c_int = 123; +pub const EADDRNOTAVAIL: ::c_int = 125; +pub const ENETRESET: ::c_int = 126; +pub const EISCONN: ::c_int = 127; +pub const ENOTCONN: ::c_int = 128; +pub const ETOOMANYREFS: ::c_int = 129; +pub const EDQUOT: ::c_int = 132; +pub const ESTALE: ::c_int = 133; +pub const ENOTSUP: ::c_int = 134; +pub const EILSEQ: ::c_int = 138; +pub const EOVERFLOW: ::c_int = 139; +pub const ECANCELED: ::c_int = 140; +pub const ENOTRECOVERABLE: ::c_int = 141; +pub const EOWNERDEAD: ::c_int = 142; +pub const EWOULDBLOCK: ::c_int = 11; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_RGETLK: ::c_int = 10; +pub const F_RSETLK: ::c_int = 11; +pub const F_CNVT: ::c_int = 12; +pub const F_RSETLKW: ::c_int = 13; +pub const F_DUPFD_CLOEXEC: ::c_int = 14; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 512; +pub const O_TRUNC: ::c_int = 1024; +pub const O_EXCL: ::c_int = 2048; +pub const O_SYNC: ::c_int = 8192; +pub const O_NONBLOCK: ::c_int = 16384; + +pub const O_ACCMODE: ::c_int = 3; +pub const O_CLOEXEC: ::c_int = 0x80000; + +pub const RTLD_LAZY: ::c_int = 0x1; + +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; + +pub const FIOCLEX: ::c_ulong = 0x20006601; +pub const FIONCLEX: ::c_ulong = 0x20006602; + +pub const S_BLKSIZE: ::mode_t = 1024; +pub const S_IREAD: ::mode_t = 256; +pub const S_IWRITE: ::mode_t = 128; +pub const S_IEXEC: ::mode_t = 64; +pub const S_ENFMT: ::mode_t = 1024; +pub const S_IFMT: ::mode_t = 61440; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IROTH: ::mode_t = 4; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IXOTH: ::mode_t = 1; + +pub const SOL_TCP: ::c_int = 6; + +pub const PF_UNSPEC: ::c_int = 0; +pub const PF_INET: ::c_int = 2; +pub const PF_INET6: ::c_int = 23; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_INET: ::c_int = 2; + +pub const CLOCK_REALTIME: ::clockid_t = 1; +pub const CLOCK_MONOTONIC: ::clockid_t = 4; +pub const CLOCK_BOOTTIME: ::clockid_t = 4; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const SO_BINTIME: ::c_int = 0x2000; +pub const SO_NO_OFFLOAD: ::c_int = 0x4000; +pub const SO_NO_DDP: ::c_int = 0x8000; +pub const SO_REUSEPORT_LB: ::c_int = 0x10000; +pub const SO_LABEL: ::c_int = 0x1009; +pub const SO_PEERLABEL: ::c_int = 0x1010; +pub const SO_LISTENQLIMIT: ::c_int = 0x1011; +pub const SO_LISTENQLEN: ::c_int = 0x1012; +pub const SO_LISTENINCQLEN: ::c_int = 0x1013; +pub const SO_SETFIB: ::c_int = 0x1014; +pub const SO_USER_COOKIE: ::c_int = 0x1015; +pub const SO_PROTOCOL: ::c_int = 0x1016; +pub const SO_PROTOTYPE: ::c_int = SO_PROTOCOL; +pub const SO_VENDOR: ::c_int = 0x80000000; +pub const SO_DEBUG: ::c_int = 0x01; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_TIMESTAMP: ::c_int = 0x0400; +pub const SO_NOSIGPIPE: ::c_int = 0x0800; +pub const SO_ACCEPTFILTER: ::c_int = 0x1000; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +cfg_if! { + if #[cfg(target_os = "horizon")] { + pub const SO_ERROR: ::c_int = 0x1009; + } else { + pub const SO_ERROR: ::c_int = 0x1007; + } +} +pub const SO_TYPE: ::c_int = 0x1008; + +pub const SOCK_CLOEXEC: ::c_int = O_CLOEXEC; + +pub const INET_ADDRSTRLEN: ::c_int = 16; + +// https://github.com/bminor/newlib/blob/HEAD/newlib/libc/sys/linux/include/net/if.h#L121 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_NOTRAILERS: ::c_int = 0x20; // avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions +pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit +pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit +pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit +pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; // use alternate physical connection +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + +cfg_if! { + if #[cfg(target_os = "vita")] { + pub const TCP_NODELAY: ::c_int = 1; + pub const TCP_MAXSEG: ::c_int = 2; + } else { + pub const TCP_NODELAY: ::c_int = 8193; + pub const TCP_MAXSEG: ::c_int = 8194; + } +} + +pub const TCP_NOPUSH: ::c_int = 4; +pub const TCP_NOOPT: ::c_int = 8; +pub const TCP_KEEPIDLE: ::c_int = 256; +pub const TCP_KEEPINTVL: ::c_int = 512; +pub const TCP_KEEPCNT: ::c_int = 1024; + +cfg_if! { + if #[cfg(target_os = "horizon")] { + pub const IP_TOS: ::c_int = 7; + } else { + pub const IP_TOS: ::c_int = 3; + } +} +cfg_if! { + if #[cfg(target_os = "vita")] { + pub const IP_TTL: ::c_int = 4; + } else { + pub const IP_TTL: ::c_int = 8; + } +} +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; +cfg_if! { + if #[cfg(target_os = "vita")] { + pub const IP_ADD_MEMBERSHIP: ::c_int = 12; + pub const IP_DROP_MEMBERSHIP: ::c_int = 13; + } else { + pub const IP_ADD_MEMBERSHIP: ::c_int = 11; + pub const IP_DROP_MEMBERSHIP: ::c_int = 12; + } +} +pub const IPV6_UNICAST_HOPS: ::c_int = 4; +pub const IPV6_MULTICAST_IF: ::c_int = 9; +pub const IPV6_MULTICAST_HOPS: ::c_int = 10; +pub const IPV6_MULTICAST_LOOP: ::c_int = 11; +pub const IPV6_V6ONLY: ::c_int = 27; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 12; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 13; + +pub const HOST_NOT_FOUND: ::c_int = 1; +pub const NO_DATA: ::c_int = 2; +pub const NO_ADDRESS: ::c_int = 2; +pub const NO_RECOVERY: ::c_int = 3; +pub const TRY_AGAIN: ::c_int = 4; + +pub const AI_PASSIVE: ::c_int = 1; +pub const AI_CANONNAME: ::c_int = 2; +pub const AI_NUMERICHOST: ::c_int = 4; +pub const AI_NUMERICSERV: ::c_int = 0; +pub const AI_ADDRCONFIG: ::c_int = 0; + +pub const NI_MAXHOST: ::c_int = 1025; +pub const NI_MAXSERV: ::c_int = 32; +pub const NI_NOFQDN: ::c_int = 1; +pub const NI_NUMERICHOST: ::c_int = 2; +pub const NI_NAMEREQD: ::c_int = 4; +pub const NI_NUMERICSERV: ::c_int = 0; +pub const NI_DGRAM: ::c_int = 0; + +cfg_if! { + // Defined in vita/mod.rs for "vita" + if #[cfg(not(target_os = "vita"))] { + pub const EAI_FAMILY: ::c_int = -303; + pub const EAI_MEMORY: ::c_int = -304; + pub const EAI_NONAME: ::c_int = -305; + pub const EAI_SOCKTYPE: ::c_int = -307; + } +} + +pub const EXIT_SUCCESS: ::c_int = 0; +pub const EXIT_FAILURE: ::c_int = 1; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + #[cfg_attr(target_os = "linux", link_name = "__xpg_strerror_r")] + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "espidf", link_name = "lwip_bind")] + pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) -> ::c_int; + pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_gettime(clock_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_getres(clock_id: ::clockid_t, res: *mut ::timespec) -> ::c_int; + #[cfg_attr(target_os = "espidf", link_name = "lwip_close")] + pub fn closesocket(sockfd: ::c_int) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "espidf", link_name = "lwip_recvfrom")] + pub fn recvfrom( + fd: ::c_int, + buf: *mut ::c_void, + n: usize, + flags: ::c_int, + addr: *mut sockaddr, + addr_len: *mut socklen_t, + ) -> isize; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + pub fn getnameinfo( + sa: *const sockaddr, + salen: socklen_t, + host: *mut ::c_char, + hostlen: socklen_t, + serv: *mut ::c_char, + servlen: socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn uname(buf: *mut ::utsname) -> ::c_int; +} + +mod generic; + +cfg_if! { + if #[cfg(target_os = "espidf")] { + mod espidf; + pub use self::espidf::*; + } else if #[cfg(target_os = "horizon")] { + mod horizon; + pub use self::horizon::*; + } else if #[cfg(target_os = "vita")] { + mod vita; + pub use self::vita::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else { + // Only tested on ARM so far. Other platforms might have different + // definitions for types and constants. + pub use target_arch_not_implemented; + } +} + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/no_align.rs new file mode 100644 index 00000000..ce3aca4e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/no_align.rs @@ -0,0 +1,51 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { // Unverified + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { // Unverified + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { // Unverified + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { // Unverified + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { // Unverified + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + }; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/powerpc/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/powerpc/mod.rs new file mode 100644 index 00000000..10faadbd --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/powerpc/mod.rs @@ -0,0 +1,16 @@ +pub type clock_t = ::c_ulong; +pub type c_char = u8; +pub type wchar_t = ::c_int; + +pub type c_long = i32; +pub type c_ulong = u32; + +pub use crate::unix::newlib::generic::{dirent, sigset_t, stat}; + +// the newlib shipped with devkitPPC does not support the following components: +// - sockaddr +// - AF_INET6 +// - FIONBIO +// - POLL* +// - SOL_SOCKET +// - MSG_* diff --git a/utshell-0.5.0/vendor/libc/src/unix/newlib/vita/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/newlib/vita/mod.rs new file mode 100644 index 00000000..d4c6955f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/newlib/vita/mod.rs @@ -0,0 +1,236 @@ +pub type clock_t = ::c_long; + +pub type c_char = i8; +pub type wchar_t = u32; + +pub type c_long = i32; +pub type c_ulong = u32; + +pub type sigset_t = ::c_ulong; + +s! { + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_vport: ::in_port_t, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_vport: ::in_port_t, + pub sin_zero: [u8; 6], + } + + pub struct sockaddr_un { + pub ss_len: u8, + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108usize], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + pub __ss_pad1: [u8; 2], + pub __ss_align: i64, + pub __ss_pad2: [u8; 116], + } + + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_mtime: ::time_t, + pub st_ctime: ::time_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_spare4: [::c_long; 2usize], + } + + #[repr(align(8))] + pub struct dirent { + __offset: [u8; 88], + pub d_name: [::c_char; 256usize], + __pad: [u8; 8], + } +} + +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET6: ::c_int = 24; + +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOMAXCONN: ::c_int = 128; + +pub const FIONBIO: ::c_ulong = 1; + +pub const POLLIN: ::c_short = 0x0001; +pub const POLLPRI: ::c_short = POLLIN; +pub const POLLOUT: ::c_short = 0x0004; +pub const POLLRDNORM: ::c_short = POLLIN; +pub const POLLRDBAND: ::c_short = POLLIN; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLWRBAND: ::c_short = POLLOUT; +pub const POLLERR: ::c_short = 0x0008; +pub const POLLHUP: ::c_short = 0x0010; +pub const POLLNVAL: ::c_short = 0x0020; + +pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_NONBLOCK: ::c_int = 0x1100; + +pub const MSG_OOB: ::c_int = 0x1; +pub const MSG_PEEK: ::c_int = 0x2; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_EOR: ::c_int = 0x8; +pub const MSG_TRUNC: ::c_int = 0x10; +pub const MSG_CTRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_DONTWAIT: ::c_int = 0x80; +pub const MSG_BCAST: ::c_int = 0x100; +pub const MSG_MCAST: ::c_int = 0x200; + +pub const UTIME_OMIT: c_long = -1; +pub const AT_FDCWD: ::c_int = -2; + +pub const O_DIRECTORY: ::c_int = 0x200000; +pub const O_NOFOLLOW: ::c_int = 0x100000; + +pub const AT_EACCESS: ::c_int = 1; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 2; +pub const AT_SYMLINK_FOLLOW: ::c_int = 4; +pub const AT_REMOVEDIR: ::c_int = 8; + +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGTRAP: ::c_int = 5; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGBUS: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGSYS: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_ADDRFAMILY: ::c_int = -9; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const _SC_PAGESIZE: ::c_int = 8; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51; +pub const PTHREAD_STACK_MIN: ::size_t = 32 * 1024; + +pub const IP_HDRINCL: ::c_int = 2; + +extern "C" { + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + pub fn sendmsg(s: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + + pub fn pthread_attr_getschedparam( + attr: *const ::pthread_attr_t, + param: *mut sched_param, + ) -> ::c_int; + + pub fn pthread_attr_setschedparam( + attr: *mut ::pthread_attr_t, + param: *const sched_param, + ) -> ::c_int; + + pub fn pthread_attr_getprocessorid_np( + attr: *const ::pthread_attr_t, + processor_id: *mut ::c_int, + ) -> ::c_int; + + pub fn pthread_attr_setprocessorid_np( + attr: *mut ::pthread_attr_t, + processor_id: ::c_int, + ) -> ::c_int; + + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn pthread_condattr_getclock( + attr: *const ::pthread_condattr_t, + clock_id: *mut ::clockid_t, + ) -> ::c_int; + + pub fn pthread_condattr_setclock( + attr: *mut ::pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + + pub fn pthread_getprocessorid_np() -> ::c_int; + + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/no_align.rs b/utshell-0.5.0/vendor/libc/src/unix/no_align.rs new file mode 100644 index 00000000..f6b9f4c1 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/no_align.rs @@ -0,0 +1,6 @@ +s! { + pub struct in6_addr { + pub s6_addr: [u8; 16], + __align: [u32; 0], + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/nto/aarch64.rs b/utshell-0.5.0/vendor/libc/src/unix/nto/aarch64.rs new file mode 100644 index 00000000..6faf8159 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/nto/aarch64.rs @@ -0,0 +1,36 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; +pub type time_t = i64; + +s! { + pub struct aarch64_qreg_t { + pub qlo: u64, + pub qhi: u64, + } + + pub struct aarch64_fpu_registers { + pub reg: [::aarch64_qreg_t; 32], + pub fpsr: u32, + pub fpcr: u32, + } + + pub struct aarch64_cpu_registers { + pub gpr: [u64; 32], + pub elr: u64, + pub pstate: u64, + } + + #[repr(align(16))] + pub struct mcontext_t { + pub cpu: ::aarch64_cpu_registers, + pub fpu: ::aarch64_fpu_registers, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/nto/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/nto/mod.rs new file mode 100644 index 00000000..9eef2345 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/nto/mod.rs @@ -0,0 +1,3508 @@ +pub type clock_t = u32; + +pub type sa_family_t = u8; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type clockid_t = ::c_int; +pub type timer_t = ::c_int; +pub type key_t = ::c_uint; +pub type id_t = ::c_int; + +pub type useconds_t = u32; +pub type dev_t = u32; +pub type socklen_t = u32; +pub type mode_t = u32; +pub type rlim64_t = u64; +pub type mqd_t = ::c_int; +pub type nfds_t = ::c_uint; +pub type idtype_t = ::c_uint; +pub type errno_t = ::c_int; +pub type rsize_t = c_ulong; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; +pub type Elf32_Lword = u64; +pub type Elf32_Sword = i32; + +pub type Elf64_Half = u16; +pub type Elf64_Word = u32; +pub type Elf64_Off = u64; +pub type Elf64_Addr = u64; +pub type Elf64_Xword = u64; +pub type Elf64_Sxword = i64; +pub type Elf64_Lword = u64; +pub type Elf64_Sword = i32; + +pub type Elf32_Section = u16; +pub type Elf64_Section = u16; + +pub type _Time32t = u32; + +pub type pthread_t = ::c_int; +pub type regoff_t = ::ssize_t; + +pub type nlink_t = u32; +pub type blksize_t = u32; +pub type suseconds_t = i32; + +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = u64; +pub type msgqnum_t = u64; +pub type msglen_t = u64; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type rlim_t = u64; +pub type posix_spawn_file_actions_t = *mut ::c_void; +pub type posix_spawnattr_t = ::uintptr_t; + +pub type pthread_mutex_t = ::sync_t; +pub type pthread_mutexattr_t = ::_sync_attr; +pub type pthread_cond_t = ::sync_t; +pub type pthread_condattr_t = ::_sync_attr; +pub type pthread_rwlockattr_t = ::_sync_attr; +pub type pthread_key_t = ::c_int; +pub type pthread_spinlock_t = sync_t; +pub type pthread_barrierattr_t = _sync_attr; +pub type sem_t = sync_t; + +pub type nl_item = ::c_int; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +s! { + pub struct dirent_extra { + pub d_datalen: u16, + pub d_type: u16, + pub d_reserved: u32, + } + + pub struct stat { + pub st_ino: ::ino_t, + pub st_size: ::off_t, + pub st_dev: ::dev_t, + pub st_rdev: ::dev_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub __old_st_mtime: ::_Time32t, + pub __old_st_atime: ::_Time32t, + pub __old_st_ctime: ::_Time32t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_blocksize: ::blksize_t, + pub st_nblocks: i32, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_mtim: ::timespec, + pub st_atim: ::timespec, + pub st_ctim: ::timespec, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + #[repr(packed)] + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [i8; 8], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + // The order of the `ai_addr` field in this struct is crucial + // for converting between the Rust and C types. + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct fd_set { + fds_bits: [::c_uint; 2 * FD_SETSIZE / ULONG_SIZE], + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_long, + pub tm_zone: *const ::c_char, + } + + #[repr(align(8))] + pub struct sched_param { + pub sched_priority: ::c_int, + pub sched_curpriority: ::c_int, + pub reserved: [::c_int; 10], + } + + #[repr(align(8))] + pub struct __sched_param { + pub __sched_priority: ::c_int, + pub __sched_curpriority: ::c_int, + pub reserved: [::c_int; 10], + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct lconv { + pub currency_symbol: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub frac_digits: ::c_char, + pub int_frac_digits: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub n_sign_posn: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + + pub decimal_point: *mut ::c_char, + pub grouping: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + + pub _Frac_grouping: *mut ::c_char, + pub _Frac_sep: *mut ::c_char, + pub _False: *mut ::c_char, + pub _True: *mut ::c_char, + + pub _No: *mut ::c_char, + pub _Yes: *mut ::c_char, + pub _Nostr: *mut ::c_char, + pub _Yesstr: *mut ::c_char, + pub _Reserved: [*mut ::c_char; 8], + } + + pub struct in_pktinfo { + pub ipi_addr: ::in_addr, + pub ipi_ifindex: ::c_uint, + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut c_char, + pub ifa_flags: ::c_uint, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_dstaddr: *mut ::sockaddr, + pub ifa_data: *mut ::c_void + } + + pub struct arpreq { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + } + + #[repr(packed)] + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + #[repr(align(8))] + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + __data: [u8; 36], // union + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_int, + pub sa_mask: ::sigset_t, + } + + pub struct _sync { + _union: ::c_uint, + __owner: ::c_uint, + } + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::c_int, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_errfunc: extern "C" fn(*const ::c_char, ::c_int) -> ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_age: *mut ::c_char, + pub pw_comment: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct Elf32_Ehdr { + pub e_ident: [::c_uchar; 16], + pub e_type: Elf32_Half, + pub e_machine: Elf32_Half, + pub e_version: Elf32_Word, + pub e_entry: Elf32_Addr, + pub e_phoff: Elf32_Off, + pub e_shoff: Elf32_Off, + pub e_flags: Elf32_Word, + pub e_ehsize: Elf32_Half, + pub e_phentsize: Elf32_Half, + pub e_phnum: Elf32_Half, + pub e_shentsize: Elf32_Half, + pub e_shnum: Elf32_Half, + pub e_shstrndx: Elf32_Half, + } + + pub struct Elf64_Ehdr { + pub e_ident: [::c_uchar; 16], + pub e_type: Elf64_Half, + pub e_machine: Elf64_Half, + pub e_version: Elf64_Word, + pub e_entry: Elf64_Addr, + pub e_phoff: Elf64_Off, + pub e_shoff: Elf64_Off, + pub e_flags: Elf64_Word, + pub e_ehsize: Elf64_Half, + pub e_phentsize: Elf64_Half, + pub e_phnum: Elf64_Half, + pub e_shentsize: Elf64_Half, + pub e_shnum: Elf64_Half, + pub e_shstrndx: Elf64_Half, + } + + pub struct Elf32_Sym { + pub st_name: Elf32_Word, + pub st_value: Elf32_Addr, + pub st_size: Elf32_Word, + pub st_info: ::c_uchar, + pub st_other: ::c_uchar, + pub st_shndx: Elf32_Section, + } + + pub struct Elf64_Sym { + pub st_name: Elf64_Word, + pub st_info: ::c_uchar, + pub st_other: ::c_uchar, + pub st_shndx: Elf64_Section, + pub st_value: Elf64_Addr, + pub st_size: Elf64_Xword, + } + + pub struct Elf32_Phdr { + pub p_type: Elf32_Word, + pub p_offset: Elf32_Off, + pub p_vaddr: Elf32_Addr, + pub p_paddr: Elf32_Addr, + pub p_filesz: Elf32_Word, + pub p_memsz: Elf32_Word, + pub p_flags: Elf32_Word, + pub p_align: Elf32_Word, + } + + pub struct Elf64_Phdr { + pub p_type: Elf64_Word, + pub p_flags: Elf64_Word, + pub p_offset: Elf64_Off, + pub p_vaddr: Elf64_Addr, + pub p_paddr: Elf64_Addr, + pub p_filesz: Elf64_Xword, + pub p_memsz: Elf64_Xword, + pub p_align: Elf64_Xword, + } + + pub struct Elf32_Shdr { + pub sh_name: Elf32_Word, + pub sh_type: Elf32_Word, + pub sh_flags: Elf32_Word, + pub sh_addr: Elf32_Addr, + pub sh_offset: Elf32_Off, + pub sh_size: Elf32_Word, + pub sh_link: Elf32_Word, + pub sh_info: Elf32_Word, + pub sh_addralign: Elf32_Word, + pub sh_entsize: Elf32_Word, + } + + pub struct Elf64_Shdr { + pub sh_name: Elf64_Word, + pub sh_type: Elf64_Word, + pub sh_flags: Elf64_Xword, + pub sh_addr: Elf64_Addr, + pub sh_offset: Elf64_Off, + pub sh_size: Elf64_Xword, + pub sh_link: Elf64_Word, + pub sh_info: Elf64_Word, + pub sh_addralign: Elf64_Xword, + pub sh_entsize: Elf64_Xword, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: u32, + pub cookie: u32, + pub len: u32 + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS], + __reserved: [::c_uint; 3], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct mallinfo { + pub arena: ::c_int, + pub ordblks: ::c_int, + pub smblks: ::c_int, + pub hblks: ::c_int, + pub hblkhd: ::c_int, + pub usmblks: ::c_int, + pub fsmblks: ::c_int, + pub uordblks: ::c_int, + pub fordblks: ::c_int, + pub keepcost: ::c_int, + } + + pub struct flock { + pub l_type: i16, + pub l_whence: i16, + pub l_zero1: i32, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_sysid: u32, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_basetype: [::c_char; 16], + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + f_filler: [::c_uint; 21], + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_offset: off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + pub aio_lio_opcode: ::c_int, + pub _aio_lio_state: *mut ::c_void, + _aio_pad: [::c_int; 3], + pub _aio_next: *mut ::aiocb, + pub _aio_flag: ::c_uint, + pub _aio_iotype: ::c_uint, + pub _aio_result: ::ssize_t, + pub _aio_error: ::c_uint, + pub _aio_suspend: *mut ::c_void, + pub _aio_plist: *mut ::c_void, + pub _aio_policy: ::c_int, + pub _aio_param: ::__sched_param, + } + + pub struct pthread_attr_t { + __data1: ::c_long, + __data2: [u8; 96] + } + + pub struct ipc_perm { + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub seq: ::c_uint, + pub key: ::key_t, + _reserved: [::c_int; 4], + } + + pub struct regex_t { + re_magic: ::c_int, + re_nsub: ::size_t, + re_endp: *const ::c_char, + re_g: *mut ::c_void, + } + + pub struct _thread_attr { + pub __flags: ::c_int, + pub __stacksize: ::size_t, + pub __stackaddr: *mut ::c_void, + pub __exitfunc: ::Option, + pub __policy: ::c_int, + pub __param: ::__sched_param, + pub __guardsize: ::c_uint, + pub __prealloc: ::c_uint, + __spare: [::c_int; 2], + } + + pub struct _sync_attr { + pub __protocol: ::c_int, + pub __flags: ::c_int, + pub __prioceiling: ::c_int, + pub __clockid: ::c_int, + pub __count: ::c_int, + __reserved: [::c_int; 3], + } + + pub struct sockcred { + pub sc_uid: ::uid_t, + pub sc_euid: ::uid_t, + pub sc_gid: ::gid_t, + pub sc_egid: ::gid_t, + pub sc_ngroups: ::c_int, + pub sc_groups: [::gid_t; 1], + } + + pub struct bpf_program { + pub bf_len: ::c_uint, + pub bf_insns: *mut ::bpf_insn, + } + + pub struct bpf_stat { + pub bs_recv: u64, + pub bs_drop: u64, + pub bs_capt: u64, + bs_padding: [u64; 13], + } + + pub struct bpf_version { + pub bv_major: ::c_ushort, + pub bv_minor: ::c_ushort, + } + + pub struct bpf_hdr { + pub bh_tstamp: ::timeval, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: u16, + } + + pub struct bpf_insn { + pub code: u16, + pub jt: ::c_uchar, + pub jf: ::c_uchar, + pub k: u32, + } + + pub struct bpf_dltlist { + pub bfl_len: ::c_uint, + pub bfl_list: *mut ::c_uint, + } + + pub struct unpcbid { + pub unp_pid: ::pid_t, + pub unp_euid: ::uid_t, + pub unp_egid: ::gid_t, + } + + pub struct dl_phdr_info { + pub dlpi_addr: ::Elf64_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const ::Elf64_Phdr, + pub dlpi_phnum: ::Elf64_Half, + } + + #[repr(align(8))] + pub struct ucontext_t { + pub uc_link: *mut ucontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_stack: stack_t, + pub uc_mcontext: mcontext_t, + } +} + +s_no_extra_traits! { + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 104] + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: sa_family_t, + __ss_pad1: [::c_char; 6], + __ss_align: i64, + __ss_pad2: [::c_char; 112], + } + + pub struct utsname { + pub sysname: [::c_char; _SYSNAME_SIZE], + pub nodename: [::c_char; _SYSNAME_SIZE], + pub release: [::c_char; _SYSNAME_SIZE], + pub version: [::c_char; _SYSNAME_SIZE], + pub machine: [::c_char; _SYSNAME_SIZE], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub __padding1: ::c_int, + pub sigev_signo: ::c_int, // union + pub __padding2: ::c_int, + pub sigev_value: ::sigval, + __sigev_un2: usize, // union + + } + pub struct dirent { + pub d_ino: ::ino_t, + pub d_offset: ::off_t, + pub d_reclen: ::c_short, + pub d_namelen: ::c_short, + pub d_name: [::c_char; 1], // flex array + } + + pub struct sigset_t { + __val: [u32; 2], + } + + pub struct mq_attr { + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_flags: ::c_long, + pub mq_curmsgs: ::c_long, + pub mq_sendwait: ::c_long, + pub mq_recvwait: ::c_long, + } + + pub struct msg { + pub msg_next: *mut ::msg, + pub msg_type: ::c_long, + pub msg_ts: ::c_ushort, + pub msg_spot: ::c_short, + _pad: [u8; 4], + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_first: *mut ::msg, + pub msg_last: *mut ::msg, + pub msg_cbytes: ::msglen_t, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + pub msg_stime: ::time_t, + msg_pad1: ::c_long, + pub msg_rtime: ::time_t, + msg_pad2: ::c_long, + pub msg_ctime: ::time_t, + msg_pad3: ::c_long, + msg_pad4: [::c_long; 4], + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::sa_family_t, + pub sdl_index: u16, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 12], + } + + pub struct sync_t { + __u: ::c_uint, // union + pub __owner: ::c_uint, + } + + #[repr(align(4))] + pub struct pthread_barrier_t { // union + __pad: [u8; 28], // union + } + + pub struct pthread_rwlock_t { + pub __active: ::c_int, + pub __blockedwriters: ::c_int, + pub __blockedreaders: ::c_int, + pub __heavy: ::c_int, + pub __lock: ::pthread_mutex_t, // union + pub __rcond: ::pthread_cond_t, // union + pub __wcond: ::pthread_cond_t, // union + pub __owner: ::c_uint, + pub __spare: ::c_uint, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + // sigevent + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + && self.__sigev_un2 + == other.__sigev_un2 + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .field("__sigev_un2", + &self.__sigev_un2) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + self.__sigev_un2.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_len == other.sun_len + && self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_len", &self.sun_len) + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_len.hash(state); + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + // sigset_t + impl PartialEq for sigset_t { + fn eq(&self, other: &sigset_t) -> bool { + self.__val == other.__val + } + } + impl Eq for sigset_t {} + impl ::fmt::Debug for sigset_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigset_t") + .field("__val", &self.__val) + .finish() + } + } + impl ::hash::Hash for sigset_t { + fn hash(&self, state: &mut H) { + self.__val.hash(state); + } + } + + // msg + impl ::fmt::Debug for msg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("msg") + .field("msg_next", &self.msg_next) + .field("msg_type", &self.msg_type) + .field("msg_ts", &self.msg_ts) + .field("msg_spot", &self.msg_spot) + .finish() + } + } + + // msqid_ds + impl ::fmt::Debug for msqid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("msqid_ds") + .field("msg_perm", &self.msg_perm) + .field("msg_first", &self.msg_first) + .field("msg_cbytes", &self.msg_cbytes) + .field("msg_qnum", &self.msg_qnum) + .field("msg_qbytes", &self.msg_qbytes) + .field("msg_lspid", &self.msg_lspid) + .field("msg_lrpid", &self.msg_lrpid) + .field("msg_stime", &self.msg_stime) + .field("msg_rtime", &self.msg_rtime) + .field("msg_ctime", &self.msg_ctime) + .finish() + } + } + + // sockaddr_dl + impl ::fmt::Debug for sockaddr_dl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_dl") + .field("sdl_len", &self.sdl_len) + .field("sdl_family", &self.sdl_family) + .field("sdl_index", &self.sdl_index) + .field("sdl_type", &self.sdl_type) + .field("sdl_nlen", &self.sdl_nlen) + .field("sdl_alen", &self.sdl_alen) + .field("sdl_slen", &self.sdl_slen) + .field("sdl_data", &self.sdl_data) + .finish() + } + } + impl PartialEq for sockaddr_dl { + fn eq(&self, other: &sockaddr_dl) -> bool { + self.sdl_len == other.sdl_len + && self.sdl_family == other.sdl_family + && self.sdl_index == other.sdl_index + && self.sdl_type == other.sdl_type + && self.sdl_nlen == other.sdl_nlen + && self.sdl_alen == other.sdl_alen + && self.sdl_slen == other.sdl_slen + && self + .sdl_data + .iter() + .zip(other.sdl_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_dl {} + impl ::hash::Hash for sockaddr_dl { + fn hash(&self, state: &mut H) { + self.sdl_len.hash(state); + self.sdl_family.hash(state); + self.sdl_index.hash(state); + self.sdl_type.hash(state); + self.sdl_nlen.hash(state); + self.sdl_alen.hash(state); + self.sdl_slen.hash(state); + self.sdl_data.hash(state); + } + } + + // sync_t + impl ::fmt::Debug for sync_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sync_t") + .field("__owner", &self.__owner) + .field("__u", &self.__u) + .finish() + } + } + + // pthread_barrier_t + impl ::fmt::Debug for pthread_barrier_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_barrier_t") + .field("__pad", &self.__pad) + .finish() + } + } + + // pthread_rwlock_t + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("__active", &self.__active) + .field("__blockedwriters", &self.__blockedwriters) + .field("__blockedreaders", &self.__blockedreaders) + .field("__heavy", &self.__heavy) + .field("__lock", &self.__lock) + .field("__rcond", &self.__rcond) + .field("__wcond", &self.__wcond) + .field("__owner", &self.__owner) + .field("__spare", &self.__spare) + .finish() + } + } + + // syspage_entry + impl ::fmt::Debug for syspage_entry { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("syspage_entry") + .field("size", &self.size) + .field("total_size", &self.total_size) + .field("type_", &self.type_) + .field("num_cpu", &self.num_cpu) + .field("system_private", &self.system_private) + .field("old_asinfo", &self.old_asinfo) + .field("hwinfo", &self.hwinfo) + .field("old_cpuinfo", &self.old_cpuinfo) + .field("old_cacheattr", &self.old_cacheattr) + .field("qtime", &self.qtime) + .field("callout", &self.callout) + .field("callin", &self.callin) + .field("typed_strings", &self.typed_strings) + .field("strings", &self.strings) + .field("old_intrinfo", &self.old_intrinfo) + .field("smp", &self.smp) + .field("pminfo", &self.pminfo) + .field("old_mdriver", &self.old_mdriver) + .field("new_asinfo", &self.new_asinfo) + .field("new_cpuinfo", &self.new_cpuinfo) + .field("new_cacheattr", &self.new_cacheattr) + .field("new_intrinfo", &self.new_intrinfo) + .field("new_mdriver", &self.new_mdriver) + .finish() + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a,b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a,b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a,b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a,b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utsname {} + + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for mq_attr { + fn eq(&self, other: &mq_attr) -> bool { + self.mq_maxmsg == other.mq_maxmsg && + self.mq_msgsize == other.mq_msgsize && + self.mq_flags == other.mq_flags && + self.mq_curmsgs == other.mq_curmsgs && + self.mq_msgsize == other.mq_msgsize && + self.mq_sendwait == other.mq_sendwait && + self.mq_recvwait == other.mq_recvwait + } + } + + impl Eq for mq_attr {} + + impl ::fmt::Debug for mq_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mq_attr") + .field("mq_maxmsg", &self.mq_maxmsg) + .field("mq_msgsize", &self.mq_msgsize) + .field("mq_flags", &self.mq_flags) + .field("mq_curmsgs", &self.mq_curmsgs) + .field("mq_msgsize", &self.mq_msgsize) + .field("mq_sendwait", &self.mq_sendwait) + .field("mq_recvwait", &self.mq_recvwait) + .finish() + } + } + impl ::hash::Hash for mq_attr { + fn hash(&self, state: &mut H) { + self.mq_maxmsg.hash(state); + self.mq_msgsize.hash(state); + self.mq_flags.hash(state); + self.mq_curmsgs.hash(state); + self.mq_sendwait.hash(state); + self.mq_recvwait.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_offset == other.d_offset + && self.d_reclen == other.d_reclen + && self.d_namelen == other.d_namelen + && self + .d_name[..self.d_namelen as _] + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_offset", &self.d_offset) + .field("d_reclen", &self.d_reclen) + .field("d_namelen", &self.d_namelen) + .field("d_name", &&self.d_name[..self.d_namelen as _]) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_offset.hash(state); + self.d_reclen.hash(state); + self.d_namelen.hash(state); + self.d_name[..self.d_namelen as _].hash(state); + } + } + } +} + +pub const _SYSNAME_SIZE: usize = 256 + 1; +pub const RLIM_INFINITY: ::rlim_t = 0xfffffffffffffffd; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +// intentionally not public, only used for fd_set +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + const ULONG_SIZE: usize = 32; + } else if #[cfg(target_pointer_width = "64")] { + const ULONG_SIZE: usize = 64; + } else { + // Unknown target_pointer_width + } +} + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 32767; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 2; +pub const _IOLBF: ::c_int = 1; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; + +pub const F_DUPFD_CLOEXEC: ::c_int = 5; + +pub const SIGTRAP: ::c_int = 5; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 2; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 4; +pub const TIMER_ABSTIME: ::c_uint = 0x80000000; + +pub const RUSAGE_SELF: ::c_int = 0; + +pub const F_OK: ::c_int = 0; +pub const X_OK: ::c_int = 1; +pub const W_OK: ::c_int = 2; +pub const R_OK: ::c_int = 4; + +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +pub const PROT_NONE: ::c_int = 0x00000000; +pub const PROT_READ: ::c_int = 0x00000100; +pub const PROT_WRITE: ::c_int = 0x00000200; +pub const PROT_EXEC: ::c_int = 0x00000400; + +pub const MAP_FILE: ::c_int = 0; +pub const MAP_SHARED: ::c_int = 1; +pub const MAP_PRIVATE: ::c_int = 2; +pub const MAP_FIXED: ::c_int = 0x10; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const MS_ASYNC: ::c_int = 1; +pub const MS_INVALIDATE: ::c_int = 4; +pub const MS_SYNC: ::c_int = 2; + +pub const SCM_RIGHTS: ::c_int = 0x01; +pub const SCM_TIMESTAMP: ::c_int = 0x02; +pub const SCM_CREDS: ::c_int = 0x04; + +pub const MAP_TYPE: ::c_int = 0x3; + +pub const IFF_UP: ::c_int = 0x00000001; +pub const IFF_BROADCAST: ::c_int = 0x00000002; +pub const IFF_DEBUG: ::c_int = 0x00000004; +pub const IFF_LOOPBACK: ::c_int = 0x00000008; +pub const IFF_POINTOPOINT: ::c_int = 0x00000010; +pub const IFF_NOTRAILERS: ::c_int = 0x00000020; +pub const IFF_RUNNING: ::c_int = 0x00000040; +pub const IFF_NOARP: ::c_int = 0x00000080; +pub const IFF_PROMISC: ::c_int = 0x00000100; +pub const IFF_ALLMULTI: ::c_int = 0x00000200; +pub const IFF_MULTICAST: ::c_int = 0x00008000; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_IPX: ::c_int = 23; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_INET6: ::c_int = 24; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_SNA: ::c_int = 11; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_ISDN: ::c_int = 26; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = PF_LOCAL; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_INET6: ::c_int = AF_INET6; +pub const pseudo_AF_KEY: ::c_int = 29; +pub const PF_KEY: ::c_int = pseudo_AF_KEY; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_SNA: ::c_int = AF_SNA; + +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_ISDN: ::c_int = AF_ISDN; + +pub const SOMAXCONN: ::c_int = 128; + +pub const MSG_OOB: ::c_int = 0x0001; +pub const MSG_PEEK: ::c_int = 0x0002; +pub const MSG_DONTROUTE: ::c_int = 0x0004; +pub const MSG_CTRUNC: ::c_int = 0x0020; +pub const MSG_TRUNC: ::c_int = 0x0010; +pub const MSG_DONTWAIT: ::c_int = 0x0080; +pub const MSG_EOR: ::c_int = 0x0008; +pub const MSG_WAITALL: ::c_int = 0x0040; +pub const MSG_NOSIGNAL: ::c_int = 0x0800; +pub const MSG_WAITFORONE: ::c_int = 0x2000; + +pub const IP_TOS: ::c_int = 3; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_OPTIONS: ::c_int = 1; +pub const IP_RECVOPTS: ::c_int = 5; +pub const IP_RETOPTS: ::c_int = 8; +pub const IP_PKTINFO: ::c_int = 25; +pub const IP_IPSEC_POLICY_COMPAT: ::c_int = 22; +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_DEFAULT_MULTICAST_TTL: ::c_int = 1; +pub const IP_DEFAULT_MULTICAST_LOOP: ::c_int = 1; + +pub const IPPROTO_HOPOPTS: ::c_int = 0; +pub const IPPROTO_IGMP: ::c_int = 2; +pub const IPPROTO_IPIP: ::c_int = 4; +pub const IPPROTO_EGP: ::c_int = 8; +pub const IPPROTO_PUP: ::c_int = 12; +pub const IPPROTO_IDP: ::c_int = 22; +pub const IPPROTO_TP: ::c_int = 29; +pub const IPPROTO_ROUTING: ::c_int = 43; +pub const IPPROTO_FRAGMENT: ::c_int = 44; +pub const IPPROTO_RSVP: ::c_int = 46; +pub const IPPROTO_GRE: ::c_int = 47; +pub const IPPROTO_ESP: ::c_int = 50; +pub const IPPROTO_AH: ::c_int = 51; +pub const IPPROTO_NONE: ::c_int = 59; +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_ENCAP: ::c_int = 98; +pub const IPPROTO_PIM: ::c_int = 103; +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MAX: ::c_int = 256; +pub const IPPROTO_CARP: ::c_int = 112; +pub const IPPROTO_DIVERT: ::c_int = 259; +pub const IPPROTO_DONE: ::c_int = 257; +pub const IPPROTO_EON: ::c_int = 80; +pub const IPPROTO_ETHERIP: ::c_int = 97; +pub const IPPROTO_GGP: ::c_int = 3; +pub const IPPROTO_IPCOMP: ::c_int = 108; +pub const IPPROTO_MOBILE: ::c_int = 55; + +pub const IPV6_RTHDR_LOOSE: ::c_int = 0; +pub const IPV6_RTHDR_STRICT: ::c_int = 1; +pub const IPV6_UNICAST_HOPS: ::c_int = 4; +pub const IPV6_MULTICAST_IF: ::c_int = 9; +pub const IPV6_MULTICAST_HOPS: ::c_int = 10; +pub const IPV6_MULTICAST_LOOP: ::c_int = 11; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; +pub const IPV6_CHECKSUM: ::c_int = 26; +pub const IPV6_V6ONLY: ::c_int = 27; +pub const IPV6_IPSEC_POLICY_COMPAT: ::c_int = 28; +pub const IPV6_RTHDRDSTOPTS: ::c_int = 35; +pub const IPV6_RECVPKTINFO: ::c_int = 36; +pub const IPV6_RECVHOPLIMIT: ::c_int = 37; +pub const IPV6_RECVRTHDR: ::c_int = 38; +pub const IPV6_RECVHOPOPTS: ::c_int = 39; +pub const IPV6_RECVDSTOPTS: ::c_int = 40; +pub const IPV6_RECVPATHMTU: ::c_int = 43; +pub const IPV6_PATHMTU: ::c_int = 44; +pub const IPV6_PKTINFO: ::c_int = 46; +pub const IPV6_HOPLIMIT: ::c_int = 47; +pub const IPV6_NEXTHOP: ::c_int = 48; +pub const IPV6_HOPOPTS: ::c_int = 49; +pub const IPV6_DSTOPTS: ::c_int = 50; +pub const IPV6_RECVTCLASS: ::c_int = 57; +pub const IPV6_TCLASS: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; + +pub const TCP_NODELAY: ::c_int = 0x01; +pub const TCP_MAXSEG: ::c_int = 0x02; +pub const TCP_MD5SIG: ::c_int = 0x10; +pub const TCP_KEEPALIVE: ::c_int = 0x04; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 0x1; +pub const LOCK_EX: ::c_int = 0x2; +pub const LOCK_NB: ::c_int = 0x4; +pub const LOCK_UN: ::c_int = 0x8; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const PATH_MAX: ::c_int = 1024; + +pub const UIO_MAXIOV: ::c_int = 1024; + +pub const FD_SETSIZE: usize = 256; + +pub const TCIOFF: ::c_int = 0x0002; +pub const TCION: ::c_int = 0x0003; +pub const TCOOFF: ::c_int = 0x0000; +pub const TCOON: ::c_int = 0x0001; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const NL0: ::tcflag_t = 0x000; +pub const NL1: ::tcflag_t = 0x100; +pub const TAB0: ::tcflag_t = 0x0000; +pub const CR0: ::tcflag_t = 0x000; +pub const FF0: ::tcflag_t = 0x0000; +pub const BS0: ::tcflag_t = 0x0000; +pub const VT0: ::tcflag_t = 0x0000; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VLNEXT: usize = 15; +pub const IGNBRK: ::tcflag_t = 0x00000001; +pub const BRKINT: ::tcflag_t = 0x00000002; +pub const IGNPAR: ::tcflag_t = 0x00000004; +pub const PARMRK: ::tcflag_t = 0x00000008; +pub const INPCK: ::tcflag_t = 0x00000010; +pub const ISTRIP: ::tcflag_t = 0x00000020; +pub const INLCR: ::tcflag_t = 0x00000040; +pub const IGNCR: ::tcflag_t = 0x00000080; +pub const ICRNL: ::tcflag_t = 0x00000100; +pub const IXANY: ::tcflag_t = 0x00000800; +pub const IMAXBEL: ::tcflag_t = 0x00002000; +pub const OPOST: ::tcflag_t = 0x00000001; +pub const CS5: ::tcflag_t = 0x00; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const OCRNL: ::tcflag_t = 0x00000008; +pub const ONOCR: ::tcflag_t = 0x00000010; +pub const ONLRET: ::tcflag_t = 0x00000020; +pub const OFILL: ::tcflag_t = 0x00000040; +pub const OFDEL: ::tcflag_t = 0x00000080; + +pub const WNOHANG: ::c_int = 0x0040; +pub const WUNTRACED: ::c_int = 0x0004; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WEXITED: ::c_int = 0x0001; +pub const WCONTINUED: ::c_int = 0x0008; +pub const WNOWAIT: ::c_int = 0x0080; +pub const WTRAPPED: ::c_int = 0x0002; + +pub const RTLD_LOCAL: ::c_int = 0x0200; +pub const RTLD_LAZY: ::c_int = 0x0001; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 2; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 1; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_EACCESS: ::c_int = 0x0001; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x0002; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x0004; +pub const AT_REMOVEDIR: ::c_int = 0x0008; + +pub const LOG_CRON: ::c_int = 9 << 3; +pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +pub const LOG_FTP: ::c_int = 11 << 3; +pub const LOG_PERROR: ::c_int = 0x20; + +pub const PIPE_BUF: usize = 5120; + +pub const CLD_EXITED: ::c_int = 1; +pub const CLD_KILLED: ::c_int = 2; +pub const CLD_DUMPED: ::c_int = 3; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const UTIME_OMIT: c_long = 0x40000002; +pub const UTIME_NOW: c_long = 0x40000001; + +pub const POLLIN: ::c_short = POLLRDNORM | POLLRDBAND; +pub const POLLPRI: ::c_short = 0x0008; +pub const POLLOUT: ::c_short = 0x0002; +pub const POLLERR: ::c_short = 0x0020; +pub const POLLHUP: ::c_short = 0x0040; +pub const POLLNVAL: ::c_short = 0x1000; +pub const POLLRDNORM: ::c_short = 0x0001; +pub const POLLRDBAND: ::c_short = 0x0004; + +pub const IPTOS_LOWDELAY: u8 = 0x10; +pub const IPTOS_THROUGHPUT: u8 = 0x08; +pub const IPTOS_RELIABILITY: u8 = 0x04; +pub const IPTOS_MINCOST: u8 = 0x02; + +pub const IPTOS_PREC_NETCONTROL: u8 = 0xe0; +pub const IPTOS_PREC_INTERNETCONTROL: u8 = 0xc0; +pub const IPTOS_PREC_CRITIC_ECP: u8 = 0xa0; +pub const IPTOS_PREC_FLASHOVERRIDE: u8 = 0x80; +pub const IPTOS_PREC_FLASH: u8 = 0x60; +pub const IPTOS_PREC_IMMEDIATE: u8 = 0x40; +pub const IPTOS_PREC_PRIORITY: u8 = 0x20; +pub const IPTOS_PREC_ROUTINE: u8 = 0x00; + +pub const IPTOS_ECN_MASK: u8 = 0x03; +pub const IPTOS_ECN_ECT1: u8 = 0x01; +pub const IPTOS_ECN_ECT0: u8 = 0x02; +pub const IPTOS_ECN_CE: u8 = 0x03; + +pub const IPOPT_CONTROL: u8 = 0x00; +pub const IPOPT_RESERVED1: u8 = 0x20; +pub const IPOPT_RESERVED2: u8 = 0x60; +pub const IPOPT_LSRR: u8 = 131; +pub const IPOPT_RR: u8 = 7; +pub const IPOPT_SSRR: u8 = 137; +pub const IPDEFTTL: u8 = 64; +pub const IPOPT_OPTVAL: u8 = 0; +pub const IPOPT_OLEN: u8 = 1; +pub const IPOPT_OFFSET: u8 = 2; +pub const IPOPT_MINOFF: u8 = 4; +pub const IPOPT_NOP: u8 = 1; +pub const IPOPT_EOL: u8 = 0; +pub const IPOPT_TS: u8 = 68; +pub const IPOPT_TS_TSONLY: u8 = 0; +pub const IPOPT_TS_TSANDADDR: u8 = 1; +pub const IPOPT_TS_PRESPEC: u8 = 3; + +pub const MAX_IPOPTLEN: u8 = 40; +pub const IPVERSION: u8 = 4; +pub const MAXTTL: u8 = 255; + +pub const ARPHRD_ETHER: u16 = 1; +pub const ARPHRD_IEEE802: u16 = 6; +pub const ARPHRD_ARCNET: u16 = 7; +pub const ARPHRD_IEEE1394: u16 = 24; + +pub const SOL_SOCKET: ::c_int = 0xffff; + +pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_BINDTODEVICE: ::c_int = 0x0800; +pub const SO_TIMESTAMP: ::c_int = 0x0400; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; + +pub const TIOCM_LE: ::c_int = 0x0100; +pub const TIOCM_DTR: ::c_int = 0x0001; +pub const TIOCM_RTS: ::c_int = 0x0002; +pub const TIOCM_ST: ::c_int = 0x0200; +pub const TIOCM_SR: ::c_int = 0x0400; +pub const TIOCM_CTS: ::c_int = 0x1000; +pub const TIOCM_CAR: ::c_int = TIOCM_CD; +pub const TIOCM_CD: ::c_int = 0x8000; +pub const TIOCM_RNG: ::c_int = TIOCM_RI; +pub const TIOCM_RI: ::c_int = 0x4000; +pub const TIOCM_DSR: ::c_int = 0x2000; + +pub const SCHED_OTHER: ::c_int = 3; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; + +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_CREAT: ::c_int = 0o001000; +pub const IPC_EXCL: ::c_int = 0o002000; +pub const IPC_NOWAIT: ::c_int = 0o004000; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; + +pub const MSG_NOERROR: ::c_int = 0o010000; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0xFFFFFFFFFFFFFFFF as *mut sem_t; + +pub const AI_PASSIVE: ::c_int = 0x00000001; +pub const AI_CANONNAME: ::c_int = 0x00000002; +pub const AI_NUMERICHOST: ::c_int = 0x00000004; + +pub const AI_NUMERICSERV: ::c_int = 0x00000008; + +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 14; + +pub const NI_NUMERICHOST: ::c_int = 0x00000002; +pub const NI_NUMERICSERV: ::c_int = 0x00000008; +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +pub const NI_DGRAM: ::c_int = 0x00000010; + +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 2; +pub const AIO_ALLDONE: ::c_int = 1; +pub const LIO_READ: ::c_int = 1; +pub const LIO_WRITE: ::c_int = 2; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WAIT: ::c_int = 1; +pub const LIO_NOWAIT: ::c_int = 0; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x00000010; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x00000001; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x00000004; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x00000002; +pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x00000400; +pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x00000040; + +pub const IPTOS_ECN_NOT_ECT: u8 = 0x00; + +pub const RTF_UP: ::c_ushort = 0x0001; +pub const RTF_GATEWAY: ::c_ushort = 0x0002; + +pub const RTF_HOST: ::c_ushort = 0x0004; +pub const RTF_DYNAMIC: ::c_ushort = 0x0010; +pub const RTF_MODIFIED: ::c_ushort = 0x0020; +pub const RTF_REJECT: ::c_ushort = 0x0008; +pub const RTF_STATIC: ::c_ushort = 0x0800; +pub const RTF_XRESOLVE: ::c_ushort = 0x0200; +pub const RTF_BROADCAST: u32 = 0x80000; +pub const RTM_NEWADDR: u16 = 0xc; +pub const RTM_DELADDR: u16 = 0xd; +pub const RTA_DST: ::c_ushort = 0x1; +pub const RTA_GATEWAY: ::c_ushort = 0x2; + +pub const UDP_ENCAP: ::c_int = 100; + +pub const IN_ACCESS: u32 = 0x00000001; +pub const IN_MODIFY: u32 = 0x00000002; +pub const IN_ATTRIB: u32 = 0x00000004; +pub const IN_CLOSE_WRITE: u32 = 0x00000008; +pub const IN_CLOSE_NOWRITE: u32 = 0x00000010; +pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE; +pub const IN_OPEN: u32 = 0x00000020; +pub const IN_MOVED_FROM: u32 = 0x00000040; +pub const IN_MOVED_TO: u32 = 0x00000080; +pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO; +pub const IN_CREATE: u32 = 0x00000100; +pub const IN_DELETE: u32 = 0x00000200; +pub const IN_DELETE_SELF: u32 = 0x00000400; +pub const IN_MOVE_SELF: u32 = 0x00000800; +pub const IN_UNMOUNT: u32 = 0x00002000; +pub const IN_Q_OVERFLOW: u32 = 0x00004000; +pub const IN_IGNORED: u32 = 0x00008000; +pub const IN_ONLYDIR: u32 = 0x01000000; +pub const IN_DONT_FOLLOW: u32 = 0x02000000; + +pub const IN_ISDIR: u32 = 0x40000000; +pub const IN_ONESHOT: u32 = 0x80000000; + +pub const REG_EXTENDED: ::c_int = 0o0001; +pub const REG_ICASE: ::c_int = 0o0002; +pub const REG_NEWLINE: ::c_int = 0o0010; +pub const REG_NOSUB: ::c_int = 0o0004; + +pub const REG_NOTBOL: ::c_int = 0o00001; +pub const REG_NOTEOL: ::c_int = 0o00002; + +pub const REG_ENOSYS: ::c_int = 17; +pub const REG_NOMATCH: ::c_int = 1; +pub const REG_BADPAT: ::c_int = 2; +pub const REG_ECOLLATE: ::c_int = 3; +pub const REG_ECTYPE: ::c_int = 4; +pub const REG_EESCAPE: ::c_int = 5; +pub const REG_ESUBREG: ::c_int = 6; +pub const REG_EBRACK: ::c_int = 7; +pub const REG_EPAREN: ::c_int = 8; +pub const REG_EBRACE: ::c_int = 9; +pub const REG_BADBR: ::c_int = 10; +pub const REG_ERANGE: ::c_int = 11; +pub const REG_ESPACE: ::c_int = 12; +pub const REG_BADRPT: ::c_int = 13; + +// errno.h +pub const EOK: ::c_int = 0; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EDEADLK: ::c_int = 45; +pub const ENOLCK: ::c_int = 46; +pub const ECANCELED: ::c_int = 47; +pub const EDQUOT: ::c_int = 49; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EBFONT: ::c_int = 57; +pub const EOWNERDEAD: ::c_int = 58; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EMULTIHOP: ::c_int = 74; +pub const EBADMSG: ::c_int = 77; +pub const ENAMETOOLONG: ::c_int = 78; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ENOSYS: ::c_int = 89; +pub const ELOOP: ::c_int = 90; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const ENOTEMPTY: ::c_int = 93; +pub const EUSERS: ::c_int = 94; +pub const ENOTRECOVERABLE: ::c_int = 95; +pub const EOPNOTSUPP: ::c_int = 103; +pub const EFPOS: ::c_int = 110; +pub const ESTALE: ::c_int = 122; +pub const EINPROGRESS: ::c_int = 236; +pub const EALREADY: ::c_int = 237; +pub const ENOTSOCK: ::c_int = 238; +pub const EDESTADDRREQ: ::c_int = 239; +pub const EMSGSIZE: ::c_int = 240; +pub const EPROTOTYPE: ::c_int = 241; +pub const ENOPROTOOPT: ::c_int = 242; +pub const EPROTONOSUPPORT: ::c_int = 243; +pub const ESOCKTNOSUPPORT: ::c_int = 244; +pub const EPFNOSUPPORT: ::c_int = 246; +pub const EAFNOSUPPORT: ::c_int = 247; +pub const EADDRINUSE: ::c_int = 248; +pub const EADDRNOTAVAIL: ::c_int = 249; +pub const ENETDOWN: ::c_int = 250; +pub const ENETUNREACH: ::c_int = 251; +pub const ENETRESET: ::c_int = 252; +pub const ECONNABORTED: ::c_int = 253; +pub const ECONNRESET: ::c_int = 254; +pub const ENOBUFS: ::c_int = 255; +pub const EISCONN: ::c_int = 256; +pub const ENOTCONN: ::c_int = 257; +pub const ESHUTDOWN: ::c_int = 258; +pub const ETOOMANYREFS: ::c_int = 259; +pub const ETIMEDOUT: ::c_int = 260; +pub const ECONNREFUSED: ::c_int = 261; +pub const EHOSTDOWN: ::c_int = 264; +pub const EHOSTUNREACH: ::c_int = 265; +pub const EBADRPC: ::c_int = 272; +pub const ERPCMISMATCH: ::c_int = 273; +pub const EPROGUNAVAIL: ::c_int = 274; +pub const EPROGMISMATCH: ::c_int = 275; +pub const EPROCUNAVAIL: ::c_int = 276; +pub const ENOREMOTE: ::c_int = 300; +pub const ENONDP: ::c_int = 301; +pub const EBADFSYS: ::c_int = 302; +pub const EMORE: ::c_int = 309; +pub const ECTRLTERM: ::c_int = 310; +pub const ENOLIC: ::c_int = 311; +pub const ESRVRFAULT: ::c_int = 312; +pub const EENDIAN: ::c_int = 313; +pub const ESECTYPEINVAL: ::c_int = 314; + +pub const RUSAGE_CHILDREN: ::c_int = -1; +pub const L_tmpnam: ::c_uint = 255; + +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 9; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 14; +pub const _PC_ASYNC_IO: ::c_int = 12; +pub const _PC_PRIO_IO: ::c_int = 13; +pub const _PC_SOCK_MAXBUF: ::c_int = 15; +pub const _PC_FILESIZEBITS: ::c_int = 16; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 22; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 23; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 24; +pub const _PC_REC_XFER_ALIGN: ::c_int = 25; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 21; +pub const _PC_SYMLINK_MAX: ::c_int = 17; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_NGROUPS_MAX: ::c_int = 4; +pub const _SC_OPEN_MAX: ::c_int = 5; +pub const _SC_JOB_CONTROL: ::c_int = 6; +pub const _SC_SAVED_IDS: ::c_int = 7; +pub const _SC_VERSION: ::c_int = 8; +pub const _SC_PASS_MAX: ::c_int = 9; +pub const _SC_PAGESIZE: ::c_int = 11; +pub const _SC_XOPEN_VERSION: ::c_int = 12; +pub const _SC_STREAM_MAX: ::c_int = 13; +pub const _SC_TZNAME_MAX: ::c_int = 14; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 15; +pub const _SC_AIO_MAX: ::c_int = 16; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 17; +pub const _SC_DELAYTIMER_MAX: ::c_int = 18; +pub const _SC_MQ_OPEN_MAX: ::c_int = 19; +pub const _SC_MQ_PRIO_MAX: ::c_int = 20; +pub const _SC_RTSIG_MAX: ::c_int = 21; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 22; +pub const _SC_SEM_VALUE_MAX: ::c_int = 23; +pub const _SC_SIGQUEUE_MAX: ::c_int = 24; +pub const _SC_TIMER_MAX: ::c_int = 25; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 26; +pub const _SC_FSYNC: ::c_int = 27; +pub const _SC_MAPPED_FILES: ::c_int = 28; +pub const _SC_MEMLOCK: ::c_int = 29; +pub const _SC_MEMLOCK_RANGE: ::c_int = 30; +pub const _SC_MEMORY_PROTECTION: ::c_int = 31; +pub const _SC_MESSAGE_PASSING: ::c_int = 32; +pub const _SC_PRIORITIZED_IO: ::c_int = 33; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 34; +pub const _SC_REALTIME_SIGNALS: ::c_int = 35; +pub const _SC_SEMAPHORES: ::c_int = 36; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 37; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 38; +pub const _SC_TIMERS: ::c_int = 39; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 40; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 41; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 42; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 43; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 44; +pub const _SC_THREAD_STACK_MIN: ::c_int = 45; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 46; +pub const _SC_TTY_NAME_MAX: ::c_int = 47; +pub const _SC_THREADS: ::c_int = 48; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 49; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 50; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 51; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 52; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 53; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 54; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 55; +pub const _SC_2_CHAR_TERM: ::c_int = 56; +pub const _SC_2_C_BIND: ::c_int = 57; +pub const _SC_2_C_DEV: ::c_int = 58; +pub const _SC_2_C_VERSION: ::c_int = 59; +pub const _SC_2_FORT_DEV: ::c_int = 60; +pub const _SC_2_FORT_RUN: ::c_int = 61; +pub const _SC_2_LOCALEDEF: ::c_int = 62; +pub const _SC_2_SW_DEV: ::c_int = 63; +pub const _SC_2_UPE: ::c_int = 64; +pub const _SC_2_VERSION: ::c_int = 65; +pub const _SC_ATEXIT_MAX: ::c_int = 66; +pub const _SC_AVPHYS_PAGES: ::c_int = 67; +pub const _SC_BC_BASE_MAX: ::c_int = 68; +pub const _SC_BC_DIM_MAX: ::c_int = 69; +pub const _SC_BC_SCALE_MAX: ::c_int = 70; +pub const _SC_BC_STRING_MAX: ::c_int = 71; +pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 72; +pub const _SC_CHAR_BIT: ::c_int = 73; +pub const _SC_CHAR_MAX: ::c_int = 74; +pub const _SC_CHAR_MIN: ::c_int = 75; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 76; +pub const _SC_EQUIV_CLASS_MAX: ::c_int = 77; +pub const _SC_EXPR_NEST_MAX: ::c_int = 78; +pub const _SC_INT_MAX: ::c_int = 79; +pub const _SC_INT_MIN: ::c_int = 80; +pub const _SC_LINE_MAX: ::c_int = 81; +pub const _SC_LONG_BIT: ::c_int = 82; +pub const _SC_MB_LEN_MAX: ::c_int = 83; +pub const _SC_NL_ARGMAX: ::c_int = 84; +pub const _SC_NL_LANGMAX: ::c_int = 85; +pub const _SC_NL_MSGMAX: ::c_int = 86; +pub const _SC_NL_NMAX: ::c_int = 87; +pub const _SC_NL_SETMAX: ::c_int = 88; +pub const _SC_NL_TEXTMAX: ::c_int = 89; +pub const _SC_NPROCESSORS_CONF: ::c_int = 90; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 91; +pub const _SC_NZERO: ::c_int = 92; +pub const _SC_PHYS_PAGES: ::c_int = 93; +pub const _SC_PII: ::c_int = 94; +pub const _SC_PII_INTERNET: ::c_int = 95; +pub const _SC_PII_INTERNET_DGRAM: ::c_int = 96; +pub const _SC_PII_INTERNET_STREAM: ::c_int = 97; +pub const _SC_PII_OSI: ::c_int = 98; +pub const _SC_PII_OSI_CLTS: ::c_int = 99; +pub const _SC_PII_OSI_COTS: ::c_int = 100; +pub const _SC_PII_OSI_M: ::c_int = 101; +pub const _SC_PII_SOCKET: ::c_int = 102; +pub const _SC_PII_XTI: ::c_int = 103; +pub const _SC_POLL: ::c_int = 104; +pub const _SC_RE_DUP_MAX: ::c_int = 105; +pub const _SC_SCHAR_MAX: ::c_int = 106; +pub const _SC_SCHAR_MIN: ::c_int = 107; +pub const _SC_SELECT: ::c_int = 108; +pub const _SC_SHRT_MAX: ::c_int = 109; +pub const _SC_SHRT_MIN: ::c_int = 110; +pub const _SC_SSIZE_MAX: ::c_int = 111; +pub const _SC_T_IOV_MAX: ::c_int = 112; +pub const _SC_UCHAR_MAX: ::c_int = 113; +pub const _SC_UINT_MAX: ::c_int = 114; +pub const _SC_UIO_MAXIOV: ::c_int = 115; +pub const _SC_ULONG_MAX: ::c_int = 116; +pub const _SC_USHRT_MAX: ::c_int = 117; +pub const _SC_WORD_BIT: ::c_int = 118; +pub const _SC_XOPEN_CRYPT: ::c_int = 119; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 120; +pub const _SC_XOPEN_SHM: ::c_int = 121; +pub const _SC_XOPEN_UNIX: ::c_int = 122; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 123; +pub const _SC_XOPEN_XPG2: ::c_int = 124; +pub const _SC_XOPEN_XPG3: ::c_int = 125; +pub const _SC_XOPEN_XPG4: ::c_int = 126; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 127; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 128; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 129; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 130; +pub const _SC_ADVISORY_INFO: ::c_int = 131; +pub const _SC_CPUTIME: ::c_int = 132; +pub const _SC_SPAWN: ::c_int = 133; +pub const _SC_SPORADIC_SERVER: ::c_int = 134; +pub const _SC_THREAD_CPUTIME: ::c_int = 135; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 136; +pub const _SC_TIMEOUTS: ::c_int = 137; +pub const _SC_BARRIERS: ::c_int = 138; +pub const _SC_CLOCK_SELECTION: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 140; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 141; +pub const _SC_SPIN_LOCKS: ::c_int = 142; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 143; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 144; +pub const _SC_TRACE: ::c_int = 145; +pub const _SC_TRACE_INHERIT: ::c_int = 146; +pub const _SC_TRACE_LOG: ::c_int = 147; +pub const _SC_2_PBS: ::c_int = 148; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 149; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 150; +pub const _SC_2_PBS_LOCATE: ::c_int = 151; +pub const _SC_2_PBS_MESSAGE: ::c_int = 152; +pub const _SC_2_PBS_TRACK: ::c_int = 153; +pub const _SC_HOST_NAME_MAX: ::c_int = 154; +pub const _SC_IOV_MAX: ::c_int = 155; +pub const _SC_IPV6: ::c_int = 156; +pub const _SC_RAW_SOCKETS: ::c_int = 157; +pub const _SC_REGEXP: ::c_int = 158; +pub const _SC_SHELL: ::c_int = 159; +pub const _SC_SS_REPL_MAX: ::c_int = 160; +pub const _SC_SYMLOOP_MAX: ::c_int = 161; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 162; +pub const _SC_TRACE_NAME_MAX: ::c_int = 163; +pub const _SC_TRACE_SYS_MAX: ::c_int = 164; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 165; +pub const _SC_V6_ILP32_OFF32: ::c_int = 166; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 167; +pub const _SC_V6_LP64_OFF64: ::c_int = 168; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 169; +pub const _SC_XOPEN_REALTIME: ::c_int = 170; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 171; +pub const _SC_XOPEN_LEGACY: ::c_int = 172; +pub const _SC_XOPEN_STREAMS: ::c_int = 173; +pub const _SC_V7_ILP32_OFF32: ::c_int = 176; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V7_LP64_OFF64: ::c_int = 178; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 179; + +pub const GLOB_ERR: ::c_int = 0x0001; +pub const GLOB_MARK: ::c_int = 0x0002; +pub const GLOB_NOSORT: ::c_int = 0x0004; +pub const GLOB_DOOFFS: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_APPEND: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x0040; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const S_IEXEC: mode_t = ::S_IXUSR; +pub const S_IWRITE: mode_t = ::S_IWUSR; +pub const S_IREAD: mode_t = ::S_IRUSR; + +pub const S_IFIFO: ::mode_t = 0x1000; +pub const S_IFCHR: ::mode_t = 0x2000; +pub const S_IFDIR: ::mode_t = 0x4000; +pub const S_IFBLK: ::mode_t = 0x6000; +pub const S_IFREG: ::mode_t = 0x8000; +pub const S_IFLNK: ::mode_t = 0xA000; +pub const S_IFSOCK: ::mode_t = 0xC000; +pub const S_IFMT: ::mode_t = 0xF000; + +pub const S_IXOTH: ::mode_t = 0o000001; +pub const S_IWOTH: ::mode_t = 0o000002; +pub const S_IROTH: ::mode_t = 0o000004; +pub const S_IRWXO: ::mode_t = 0o000007; +pub const S_IXGRP: ::mode_t = 0o000010; +pub const S_IWGRP: ::mode_t = 0o000020; +pub const S_IRGRP: ::mode_t = 0o000040; +pub const S_IRWXG: ::mode_t = 0o000070; +pub const S_IXUSR: ::mode_t = 0o000100; +pub const S_IWUSR: ::mode_t = 0o000200; +pub const S_IRUSR: ::mode_t = 0o000400; +pub const S_IRWXU: ::mode_t = 0o000700; + +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +pub const ST_RDONLY: ::c_ulong = 0x01; +pub const ST_NOSUID: ::c_ulong = 0x04; +pub const ST_NOEXEC: ::c_ulong = 0x02; +pub const ST_NOATIME: ::c_ulong = 0x20; + +pub const RTLD_NEXT: *mut ::c_void = -3i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = -2i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x0002; + +pub const EMPTY: ::c_short = 0; +pub const RUN_LVL: ::c_short = 1; +pub const BOOT_TIME: ::c_short = 2; +pub const NEW_TIME: ::c_short = 4; +pub const OLD_TIME: ::c_short = 3; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const USER_PROCESS: ::c_short = 7; +pub const DEAD_PROCESS: ::c_short = 8; +pub const ACCOUNTING: ::c_short = 9; + +pub const ENOTSUP: ::c_int = 48; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 26 * 26 * 26; +pub const FOPEN_MAX: ::c_uint = 16; +pub const FILENAME_MAX: ::c_uint = 255; + +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const M_KEEP: ::c_int = 4; +pub const REG_STARTEND: ::c_int = 0o00004; +pub const VEOF: usize = 4; + +pub const RTLD_GLOBAL: ::c_int = 0x0100; +pub const RTLD_NOLOAD: ::c_int = 0x0004; + +pub const O_RDONLY: ::c_int = 0o000000; +pub const O_WRONLY: ::c_int = 0o000001; +pub const O_RDWR: ::c_int = 0o000002; + +pub const O_EXEC: ::c_int = 0o00003; +pub const O_ASYNC: ::c_int = 0o0200000; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const O_TRUNC: ::c_int = 0o001000; +pub const O_CLOEXEC: ::c_int = 0o020000; +pub const O_DIRECTORY: ::c_int = 0o4000000; +pub const O_ACCMODE: ::c_int = 0o000007; +pub const O_APPEND: ::c_int = 0o000010; +pub const O_CREAT: ::c_int = 0o000400; +pub const O_EXCL: ::c_int = 0o002000; +pub const O_NOCTTY: ::c_int = 0o004000; +pub const O_NONBLOCK: ::c_int = 0o000200; +pub const O_SYNC: ::c_int = 0o000040; +pub const O_RSYNC: ::c_int = 0o000100; +pub const O_DSYNC: ::c_int = 0o000020; +pub const O_NOFOLLOW: ::c_int = 0o010000; + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_CLOEXEC: ::c_int = 0x10000000; + +pub const SA_SIGINFO: ::c_int = 0x0002; +pub const SA_NOCLDWAIT: ::c_int = 0x0020; +pub const SA_NODEFER: ::c_int = 0x0010; +pub const SA_RESETHAND: ::c_int = 0x0004; +pub const SA_NOCLDSTOP: ::c_int = 0x0001; + +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGWINCH: ::c_int = 20; +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGCONT: ::c_int = 25; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGURG: ::c_int = 21; +pub const SIGIO: ::c_int = SIGPOLL; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 22; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; + +pub const POLLWRNORM: ::c_short = ::POLLOUT; +pub const POLLWRBAND: ::c_short = 0x0010; + +pub const F_SETLK: ::c_int = 106; +pub const F_SETLKW: ::c_int = 107; +pub const F_ALLOCSP: ::c_int = 110; +pub const F_FREESP: ::c_int = 111; +pub const F_GETLK: ::c_int = 114; + +pub const F_RDLCK: ::c_int = 1; +pub const F_WRLCK: ::c_int = 2; +pub const F_UNLCK: ::c_int = 3; + +pub const NCCS: usize = 40; + +pub const MAP_ANON: ::c_int = MAP_ANONYMOUS; +pub const MAP_ANONYMOUS: ::c_int = 0x00080000; + +pub const MCL_CURRENT: ::c_int = 0x000000001; +pub const MCL_FUTURE: ::c_int = 0x000000002; + +pub const _TIO_CBAUD: ::tcflag_t = 15; +pub const CBAUD: ::tcflag_t = _TIO_CBAUD; +pub const TAB1: ::tcflag_t = 0x0800; +pub const TAB2: ::tcflag_t = 0x1000; +pub const TAB3: ::tcflag_t = 0x1800; +pub const CR1: ::tcflag_t = 0x200; +pub const CR2: ::tcflag_t = 0x400; +pub const CR3: ::tcflag_t = 0x600; +pub const FF1: ::tcflag_t = 0x8000; +pub const BS1: ::tcflag_t = 0x2000; +pub const VT1: ::tcflag_t = 0x4000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 17; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x00000004; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const OLCUC: ::tcflag_t = 0x00000002; +pub const NLDLY: ::tcflag_t = 0x00000100; +pub const CRDLY: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0x00002000; +pub const FFDLY: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0x00004000; +pub const XTABS: ::tcflag_t = 0x1800; + +pub const B0: ::speed_t = 0; +pub const B50: ::speed_t = 1; +pub const B75: ::speed_t = 2; +pub const B110: ::speed_t = 3; +pub const B134: ::speed_t = 4; +pub const B150: ::speed_t = 5; +pub const B200: ::speed_t = 6; +pub const B300: ::speed_t = 7; +pub const B600: ::speed_t = 8; +pub const B1200: ::speed_t = 9; +pub const B1800: ::speed_t = 10; +pub const B2400: ::speed_t = 11; +pub const B4800: ::speed_t = 12; +pub const B9600: ::speed_t = 13; +pub const B19200: ::speed_t = 14; +pub const B38400: ::speed_t = 15; +pub const EXTA: ::speed_t = 14; +pub const EXTB: ::speed_t = 15; +pub const B57600: ::speed_t = 57600; +pub const B115200: ::speed_t = 115200; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 16; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; + +pub const TCSANOW: ::c_int = 0x0001; +pub const TCSADRAIN: ::c_int = 0x0002; +pub const TCSAFLUSH: ::c_int = 0x0004; + +pub const HW_MACHINE: ::c_int = 1; +pub const HW_MODEL: ::c_int = 2; +pub const HW_NCPU: ::c_int = 3; +pub const HW_BYTEORDER: ::c_int = 4; +pub const HW_PHYSMEM: ::c_int = 5; +pub const HW_USERMEM: ::c_int = 6; +pub const HW_PAGESIZE: ::c_int = 7; +pub const HW_DISKNAMES: ::c_int = 8; +pub const HW_IOSTATS: ::c_int = 9; +pub const HW_MACHINE_ARCH: ::c_int = 10; +pub const HW_ALIGNBYTES: ::c_int = 11; +pub const HW_CNMAGIC: ::c_int = 12; +pub const HW_PHYSMEM64: ::c_int = 13; +pub const HW_USERMEM64: ::c_int = 14; +pub const HW_IOSTATNAMES: ::c_int = 15; +pub const HW_MAXID: ::c_int = 15; + +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_VFS: ::c_int = 3; +pub const CTL_NET: ::c_int = 4; +pub const CTL_DEBUG: ::c_int = 5; +pub const CTL_HW: ::c_int = 6; +pub const CTL_MACHDEP: ::c_int = 7; +pub const CTL_USER: ::c_int = 8; +pub const CTL_QNX: ::c_int = 9; +pub const CTL_PROC: ::c_int = 10; +pub const CTL_VENDOR: ::c_int = 11; +pub const CTL_EMUL: ::c_int = 12; +pub const CTL_SECURITY: ::c_int = 13; +pub const CTL_MAXID: ::c_int = 14; + +pub const DAY_1: ::nl_item = 8; +pub const DAY_2: ::nl_item = 9; +pub const DAY_3: ::nl_item = 10; +pub const DAY_4: ::nl_item = 11; +pub const DAY_5: ::nl_item = 12; +pub const DAY_6: ::nl_item = 13; +pub const DAY_7: ::nl_item = 14; + +pub const MON_1: ::nl_item = 22; +pub const MON_2: ::nl_item = 23; +pub const MON_3: ::nl_item = 24; +pub const MON_4: ::nl_item = 25; +pub const MON_5: ::nl_item = 26; +pub const MON_6: ::nl_item = 27; +pub const MON_7: ::nl_item = 28; +pub const MON_8: ::nl_item = 29; +pub const MON_9: ::nl_item = 30; +pub const MON_10: ::nl_item = 31; +pub const MON_11: ::nl_item = 32; +pub const MON_12: ::nl_item = 33; + +pub const ABDAY_1: ::nl_item = 15; +pub const ABDAY_2: ::nl_item = 16; +pub const ABDAY_3: ::nl_item = 17; +pub const ABDAY_4: ::nl_item = 18; +pub const ABDAY_5: ::nl_item = 19; +pub const ABDAY_6: ::nl_item = 20; +pub const ABDAY_7: ::nl_item = 21; + +pub const ABMON_1: ::nl_item = 34; +pub const ABMON_2: ::nl_item = 35; +pub const ABMON_3: ::nl_item = 36; +pub const ABMON_4: ::nl_item = 37; +pub const ABMON_5: ::nl_item = 38; +pub const ABMON_6: ::nl_item = 39; +pub const ABMON_7: ::nl_item = 40; +pub const ABMON_8: ::nl_item = 41; +pub const ABMON_9: ::nl_item = 42; +pub const ABMON_10: ::nl_item = 43; +pub const ABMON_11: ::nl_item = 44; +pub const ABMON_12: ::nl_item = 45; + +pub const AF_ARP: ::c_int = 28; +pub const AF_CCITT: ::c_int = 10; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_CNT: ::c_int = 21; +pub const AF_COIP: ::c_int = 20; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_E164: ::c_int = 26; +pub const AF_ECMA: ::c_int = 8; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_IEEE80211: ::c_int = 32; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_ISO: ::c_int = 7; +pub const AF_LAT: ::c_int = 14; +pub const AF_LINK: ::c_int = 18; +pub const AF_NATM: ::c_int = 27; +pub const AF_NS: ::c_int = 6; +pub const AF_OSI: ::c_int = 7; +pub const AF_PUP: ::c_int = 4; +pub const ALT_DIGITS: ::nl_item = 50; +pub const AM_STR: ::nl_item = 6; +pub const B76800: ::speed_t = 76800; + +pub const BIOCFLUSH: ::c_int = 17000; +pub const BIOCGBLEN: ::c_int = 1074020966; +pub const BIOCGDLT: ::c_int = 1074020970; +pub const BIOCGDLTLIST: ::c_int = -1072676233; +pub const BIOCGETIF: ::c_int = 1083196011; +pub const BIOCGHDRCMPLT: ::c_int = 1074020980; +pub const BIOCGRTIMEOUT: ::c_int = 1074807406; +pub const BIOCGSEESENT: ::c_int = 1074020984; +pub const BIOCGSTATS: ::c_int = 1082147439; +pub const BIOCIMMEDIATE: ::c_int = -2147204496; +pub const BIOCPROMISC: ::c_int = 17001; +pub const BIOCSBLEN: ::c_int = -1073462682; +pub const BIOCSDLT: ::c_int = -2147204490; +pub const BIOCSETF: ::c_int = -2146418073; +pub const BIOCSETIF: ::c_int = -2138029460; +pub const BIOCSHDRCMPLT: ::c_int = -2147204491; +pub const BIOCSRTIMEOUT: ::c_int = -2146418067; +pub const BIOCSSEESENT: ::c_int = -2147204487; +pub const BIOCVERSION: ::c_int = 1074020977; + +pub const BPF_ALIGNMENT: usize = ::mem::size_of::<::c_long>(); +pub const CHAR_BIT: usize = 8; +pub const CODESET: ::nl_item = 1; +pub const CRNCYSTR: ::nl_item = 55; + +pub const D_FLAG_FILTER: ::c_int = 0x00000001; +pub const D_FLAG_STAT: ::c_int = 0x00000002; +pub const D_FLAG_STAT_FORM_MASK: ::c_int = 0x000000f0; +pub const D_FLAG_STAT_FORM_T32_2001: ::c_int = 0x00000010; +pub const D_FLAG_STAT_FORM_T32_2008: ::c_int = 0x00000020; +pub const D_FLAG_STAT_FORM_T64_2008: ::c_int = 0x00000030; +pub const D_FLAG_STAT_FORM_UNSET: ::c_int = 0x00000000; + +pub const D_FMT: ::nl_item = 3; +pub const D_GETFLAG: ::c_int = 1; +pub const D_SETFLAG: ::c_int = 2; +pub const D_T_FMT: ::nl_item = 2; +pub const ERA: ::nl_item = 46; +pub const ERA_D_FMT: ::nl_item = 47; +pub const ERA_D_T_FMT: ::nl_item = 48; +pub const ERA_T_FMT: ::nl_item = 49; +pub const RADIXCHAR: ::nl_item = 51; +pub const THOUSEP: ::nl_item = 52; +pub const YESEXPR: ::nl_item = 53; +pub const NOEXPR: ::nl_item = 54; +pub const F_GETOWN: ::c_int = 35; + +pub const FIONBIO: ::c_int = -2147195266; +pub const FIOASYNC: ::c_int = -2147195267; +pub const FIOCLEX: ::c_int = 26113; +pub const FIOGETOWN: ::c_int = 1074030203; +pub const FIONCLEX: ::c_int = 26114; +pub const FIONREAD: ::c_int = 1074030207; +pub const FIONSPACE: ::c_int = 1074030200; +pub const FIONWRITE: ::c_int = 1074030201; +pub const FIOSETOWN: ::c_int = -2147195268; + +pub const F_SETOWN: ::c_int = 36; +pub const IFF_ACCEPTRTADV: ::c_int = 0x40000000; +pub const IFF_IP6FORWARDING: ::c_int = 0x20000000; +pub const IFF_LINK0: ::c_int = 0x00001000; +pub const IFF_LINK1: ::c_int = 0x00002000; +pub const IFF_LINK2: ::c_int = 0x00004000; +pub const IFF_OACTIVE: ::c_int = 0x00000400; +pub const IFF_SHIM: ::c_int = 0x80000000; +pub const IFF_SIMPLEX: ::c_int = 0x00000800; +pub const IHFLOW: tcflag_t = 0x00000001; +pub const IIDLE: tcflag_t = 0x00000008; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_RECVIF: ::c_int = 20; +pub const IPTOS_ECN_NOTECT: u8 = 0x00; +pub const IUCLC: tcflag_t = 0x00000200; +pub const IUTF8: tcflag_t = 0x0004000; + +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_ARND: ::c_int = 81; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_IOV_MAX: ::c_int = 38; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_LOGSIGEXIT: ::c_int = 46; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_MAXID: ::c_int = 83; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_ARGS: ::c_int = 48; +pub const KERN_PROC_ENV: ::c_int = 3; +pub const KERN_PROC_GID: ::c_int = 7; +pub const KERN_PROC_PGRP: ::c_int = 2; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_RGID: ::c_int = 8; +pub const KERN_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_SESSION: ::c_int = 3; +pub const KERN_PROC_TTY: ::c_int = 4; +pub const KERN_PROC_UID: ::c_int = 5; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_VNODE: ::c_int = 13; + +pub const LC_ALL: ::c_int = 63; +pub const LC_COLLATE: ::c_int = 1; +pub const LC_CTYPE: ::c_int = 2; +pub const LC_MESSAGES: ::c_int = 32; +pub const LC_MONETARY: ::c_int = 4; +pub const LC_NUMERIC: ::c_int = 8; +pub const LC_TIME: ::c_int = 16; + +pub const LOCAL_CONNWAIT: ::c_int = 0x0002; +pub const LOCAL_CREDS: ::c_int = 0x0001; +pub const LOCAL_PEEREID: ::c_int = 0x0003; + +pub const MAP_STACK: ::c_int = 0x00001000; +pub const MNT_NOEXEC: ::c_int = 0x02; +pub const MNT_NOSUID: ::c_int = 0x04; +pub const MNT_RDONLY: ::c_int = 0x01; + +pub const MSG_NOTIFICATION: ::c_int = 0x0400; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 4; +pub const NI_NUMERICSCOPE: ::c_int = 0x00000040; +pub const OHFLOW: tcflag_t = 0x00000002; +pub const P_ALL: idtype_t = 0; +pub const PARSTK: tcflag_t = 0x00000004; +pub const PF_ARP: ::c_int = 28; +pub const PF_CCITT: ::c_int = 10; +pub const PF_CHAOS: ::c_int = 5; +pub const PF_CNT: ::c_int = 21; +pub const PF_COIP: ::c_int = 20; +pub const PF_DATAKIT: ::c_int = 9; +pub const PF_DECnet: ::c_int = 12; +pub const PF_DLI: ::c_int = 13; +pub const PF_ECMA: ::c_int = 8; +pub const PF_HYLINK: ::c_int = 15; +pub const PF_IMPLINK: ::c_int = 3; +pub const PF_ISO: ::c_int = 7; +pub const PF_LAT: ::c_int = 14; +pub const PF_LINK: ::c_int = 18; +pub const PF_NATM: ::c_int = 27; +pub const PF_OSI: ::c_int = 7; +pub const PF_PIP: ::c_int = 25; +pub const PF_PUP: ::c_int = 4; +pub const PF_RTIP: ::c_int = 22; +pub const PF_XTP: ::c_int = 19; +pub const PM_STR: ::nl_item = 7; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 2; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 1; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const _POSIX_VDISABLE: ::c_int = 0; +pub const P_PGID: idtype_t = 2; +pub const P_PID: idtype_t = 1; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_USER: ::c_int = 2; +pub const pseudo_AF_HDRCMPLT: ::c_int = 30; +pub const pseudo_AF_PIP: ::c_int = 25; +pub const pseudo_AF_RTIP: ::c_int = 22; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const REG_ASSERT: ::c_int = 15; +pub const REG_ATOI: ::c_int = 255; +pub const REG_BACKR: ::c_int = 0x400; +pub const REG_BASIC: ::c_int = 0x00; +pub const REG_DUMP: ::c_int = 0x80; +pub const REG_EMPTY: ::c_int = 14; +pub const REG_INVARG: ::c_int = 16; +pub const REG_ITOA: ::c_int = 0o400; +pub const REG_LARGE: ::c_int = 0x200; +pub const REG_NOSPEC: ::c_int = 0x10; +pub const REG_OK: ::c_int = 0; +pub const REG_PEND: ::c_int = 0x20; +pub const REG_TRACE: ::c_int = 0x100; + +pub const RLIMIT_AS: ::c_int = 6; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_MEMLOCK: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 5; +pub const RLIMIT_NPROC: ::c_int = 8; +pub const RLIMIT_RSS: ::c_int = 6; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_VMEM: ::c_int = 6; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 14; + +pub const SCHED_ADJTOHEAD: ::c_int = 5; +pub const SCHED_ADJTOTAIL: ::c_int = 6; +pub const SCHED_MAXPOLICY: ::c_int = 7; +pub const SCHED_SETPRIO: ::c_int = 7; +pub const SCHED_SPORADIC: ::c_int = 4; + +pub const SHM_ANON: *mut ::c_char = -1isize as *mut ::c_char; +pub const SIGCLD: ::c_int = SIGCHLD; +pub const SIGDEADLK: ::c_int = 7; +pub const SIGEMT: ::c_int = 7; +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 129; +pub const SIGEV_THREAD: ::c_int = 135; +pub const SIOCGIFADDR: ::c_int = -1064277727; +pub const SO_FIB: ::c_int = 0x100a; +pub const SO_OVERFLOWED: ::c_int = 0x1009; +pub const SO_SETFIB: ::c_int = 0x100a; +pub const SO_TXPRIO: ::c_int = 0x100b; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_VLANPRIO: ::c_int = 0x100c; +pub const _SS_ALIGNSIZE: usize = ::mem::size_of::(); +pub const _SS_MAXSIZE: usize = 128; +pub const _SS_PAD1SIZE: usize = _SS_ALIGNSIZE - 2; +pub const _SS_PAD2SIZE: usize = _SS_MAXSIZE - 2 - _SS_PAD1SIZE - _SS_ALIGNSIZE; +pub const TC_CPOSIX: tcflag_t = CLOCAL | CREAD | CSIZE | CSTOPB | HUPCL | PARENB | PARODD; +pub const TCGETS: ::c_int = 0x404c540d; +pub const TC_IPOSIX: tcflag_t = + BRKINT | ICRNL | IGNBRK | IGNPAR | INLCR | INPCK | ISTRIP | IXOFF | IXON | PARMRK; +pub const TC_LPOSIX: tcflag_t = + ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG | NOFLSH | TOSTOP; +pub const TC_OPOSIX: tcflag_t = OPOST; +pub const T_FMT_AMPM: ::nl_item = 5; + +pub const TIOCCBRK: ::c_int = 29818; +pub const TIOCCDTR: ::c_int = 29816; +pub const TIOCDRAIN: ::c_int = 29790; +pub const TIOCEXCL: ::c_int = 29709; +pub const TIOCFLUSH: ::c_int = -2147191792; +pub const TIOCGETA: ::c_int = 1078752275; +pub const TIOCGPGRP: ::c_int = 1074033783; +pub const TIOCGWINSZ: ::c_int = 1074295912; +pub const TIOCMBIC: ::c_int = -2147191701; +pub const TIOCMBIS: ::c_int = -2147191700; +pub const TIOCMGET: ::c_int = 1074033770; +pub const TIOCMSET: ::c_int = -2147191699; +pub const TIOCNOTTY: ::c_int = 29809; +pub const TIOCNXCL: ::c_int = 29710; +pub const TIOCOUTQ: ::c_int = 1074033779; +pub const TIOCPKT: ::c_int = -2147191696; +pub const TIOCPKT_DATA: ::c_int = 0x00; +pub const TIOCPKT_DOSTOP: ::c_int = 0x20; +pub const TIOCPKT_FLUSHREAD: ::c_int = 0x01; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 0x02; +pub const TIOCPKT_IOCTL: ::c_int = 0x40; +pub const TIOCPKT_NOSTOP: ::c_int = 0x10; +pub const TIOCPKT_START: ::c_int = 0x08; +pub const TIOCPKT_STOP: ::c_int = 0x04; +pub const TIOCSBRK: ::c_int = 29819; +pub const TIOCSCTTY: ::c_int = 29793; +pub const TIOCSDTR: ::c_int = 29817; +pub const TIOCSETA: ::c_int = -2142473196; +pub const TIOCSETAF: ::c_int = -2142473194; +pub const TIOCSETAW: ::c_int = -2142473195; +pub const TIOCSPGRP: ::c_int = -2147191690; +pub const TIOCSTART: ::c_int = 29806; +pub const TIOCSTI: ::c_int = -2147388302; +pub const TIOCSTOP: ::c_int = 29807; +pub const TIOCSWINSZ: ::c_int = -2146929561; + +pub const USER_CS_PATH: ::c_int = 1; +pub const USER_BC_BASE_MAX: ::c_int = 2; +pub const USER_BC_DIM_MAX: ::c_int = 3; +pub const USER_BC_SCALE_MAX: ::c_int = 4; +pub const USER_BC_STRING_MAX: ::c_int = 5; +pub const USER_COLL_WEIGHTS_MAX: ::c_int = 6; +pub const USER_EXPR_NEST_MAX: ::c_int = 7; +pub const USER_LINE_MAX: ::c_int = 8; +pub const USER_RE_DUP_MAX: ::c_int = 9; +pub const USER_POSIX2_VERSION: ::c_int = 10; +pub const USER_POSIX2_C_BIND: ::c_int = 11; +pub const USER_POSIX2_C_DEV: ::c_int = 12; +pub const USER_POSIX2_CHAR_TERM: ::c_int = 13; +pub const USER_POSIX2_FORT_DEV: ::c_int = 14; +pub const USER_POSIX2_FORT_RUN: ::c_int = 15; +pub const USER_POSIX2_LOCALEDEF: ::c_int = 16; +pub const USER_POSIX2_SW_DEV: ::c_int = 17; +pub const USER_POSIX2_UPE: ::c_int = 18; +pub const USER_STREAM_MAX: ::c_int = 19; +pub const USER_TZNAME_MAX: ::c_int = 20; +pub const USER_ATEXIT_MAX: ::c_int = 21; +pub const USER_MAXID: ::c_int = 22; + +pub const VDOWN: usize = 31; +pub const VINS: usize = 32; +pub const VDEL: usize = 33; +pub const VRUB: usize = 34; +pub const VCAN: usize = 35; +pub const VHOME: usize = 36; +pub const VEND: usize = 37; +pub const VSPARE3: usize = 38; +pub const VSPARE4: usize = 39; +pub const VSWTCH: usize = 7; +pub const VDSUSP: usize = 11; +pub const VFWD: usize = 18; +pub const VLOGIN: usize = 19; +pub const VPREFIX: usize = 20; +pub const VSUFFIX: usize = 24; +pub const VLEFT: usize = 28; +pub const VRIGHT: usize = 29; +pub const VUP: usize = 30; +pub const XCASE: tcflag_t = 0x00000004; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0x00; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x01; + +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 3; +pub const PTHREAD_STACK_MIN: ::size_t = 256; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = 0; +pub const PTHREAD_MUTEX_STALLED: ::c_int = 0x00; +pub const PTHREAD_MUTEX_ROBUST: ::c_int = 0x10; +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0x00; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 0x01; + +pub const PTHREAD_KEYS_MAX: usize = 128; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __u: 0x80000000, + __owner: 0xffffffff, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __u: CLOCK_REALTIME as u32, + __owner: 0xfffffffb, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __active: 0, + __blockedwriters: 0, + __blockedreaders: 0, + __heavy: 0, + __lock: PTHREAD_MUTEX_INITIALIZER, + __rcond: PTHREAD_COND_INITIALIZER, + __wcond: PTHREAD_COND_INITIALIZER, + __owner: -2i32 as ::c_uint, + __spare: 0, +}; + +const_fn! { + {const} fn _CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } + + {const} fn _ALIGN(p: usize, b: usize) -> usize { + (p + b - 1) & !(b-1) + } +} + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + let msg = _CMSG_ALIGN((*cmsg).cmsg_len as usize); + let next = cmsg as usize + msg + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + if next > (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + msg) as *mut ::cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_CMSG_ALIGN(::mem::size_of::()) + _CMSG_ALIGN(length as usize) ) + as ::c_uint + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } + + pub fn _DEXTRA_FIRST(_d: *const dirent) -> *mut ::dirent_extra { + let _f = &((*(_d)).d_name) as *const _; + let _s = _d as usize; + + _ALIGN(_s + _f as usize - _s + (*_d).d_namelen as usize + 1, 8) as *mut ::dirent_extra + } + + pub fn _DEXTRA_VALID(_x: *const ::dirent_extra, _d: *const dirent) -> bool { + let sz = _x as usize - _d as usize + ::mem::size_of::<::dirent_extra>(); + let rsz = (*_d).d_reclen as usize; + + if sz > rsz || sz + (*_x).d_datalen as usize > rsz { + false + } else { + true + } + } + + pub fn _DEXTRA_NEXT(_x: *const ::dirent_extra) -> *mut ::dirent_extra { + _ALIGN( + _x as usize + ::mem::size_of::<::dirent_extra>() + (*_x).d_datalen as usize, 8 + ) as *mut ::dirent_extra + } + + pub fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { + ngrps - 1 + } else { + 0 + }; + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + ((dev as ::c_uint) >> 10) & 0x3f + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + (dev as ::c_uint) & 0x3ff + } +} + +safe_f! { + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0x7f) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } + + pub {const} fn IPTOS_ECN(x: u8) -> u8 { + x & ::IPTOS_ECN_MASK + } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + ((major << 10) | (minor)) as ::dev_t + } +} + +// Network related functions are provided by libsocket and regex +// functions are provided by libregex. +#[link(name = "socket")] +#[link(name = "regex")] + +extern "C" { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn mknodat( + __fd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: ::dev_t, + ) -> ::c_int; + + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> *mut ::c_char; + pub fn clearenv() -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + pub fn wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::c_int; + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; + + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + pub fn getpeereid(socket: ::c_int, euid: *mut ::uid_t, egid: *mut ::gid_t) -> ::c_int; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn setspent(); + pub fn endspent(); + + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + + pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + info: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int; + + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn glob( + pattern: *const c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sync(); + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn umount(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::c_void) -> ::c_int; + pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + pub fn mount( + special_device: *const ::c_char, + mount_directory: *const ::c_char, + flags: ::c_int, + mount_type: *const ::c_char, + mount_data: *const ::c_void, + mount_datalen: ::c_int, + ) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; + pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn pthread_barrierattr_init(__attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_destroy(__attr: *mut ::pthread_barrierattr_t) -> ::c_int; + pub fn pthread_barrierattr_getpshared( + __attr: *const ::pthread_barrierattr_t, + __pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_barrierattr_setpshared( + __attr: *mut ::pthread_barrierattr_t, + __pshared: ::c_int, + ) -> ::c_int; + pub fn pthread_barrier_init( + __barrier: *mut ::pthread_barrier_t, + __attr: *const ::pthread_barrierattr_t, + __count: ::c_uint, + ) -> ::c_int; + pub fn pthread_barrier_destroy(__barrier: *mut ::pthread_barrier_t) -> ::c_int; + pub fn pthread_barrier_wait(__barrier: *mut ::pthread_barrier_t) -> ::c_int; + + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn pthread_condattr_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_getrobust( + attr: *const pthread_mutexattr_t, + robustness: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setrobust( + attr: *mut pthread_mutexattr_t, + robustness: ::c_int, + ) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; + pub fn setitimer( + which: ::c_int, + value: *const ::itimerval, + ovalue: *mut ::itimerval, + ) -> ::c_int; + pub fn posix_spawn( + pid: *mut ::pid_t, + path: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnp( + pid: *mut ::pid_t, + file: *const ::c_char, + file_actions: *const ::posix_spawn_file_actions_t, + attrp: *const ::posix_spawnattr_t, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; + pub fn posix_spawnattr_getsigdefault( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigdefault( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getsigmask( + attr: *const posix_spawnattr_t, + default: *mut ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_setsigmask( + attr: *mut posix_spawnattr_t, + default: *const ::sigset_t, + ) -> ::c_int; + pub fn posix_spawnattr_getflags( + attr: *const posix_spawnattr_t, + flags: *mut ::c_short, + ) -> ::c_int; + pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; + pub fn posix_spawnattr_getpgroup( + attr: *const posix_spawnattr_t, + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; + pub fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + flags: *mut ::c_int, + ) -> ::c_int; + pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; + pub fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + param: *const ::sched_param, + ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_addopen( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + path: *const ::c_char, + oflag: ::c_int, + mode: ::mode_t, + ) -> ::c_int; + pub fn posix_spawn_file_actions_addclose( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; + pub fn posix_spawn_file_actions_adddup2( + actions: *mut posix_spawn_file_actions_t, + fd: ::c_int, + newfd: ::c_int, + ) -> ::c_int; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::c_int; + + pub fn gettid() -> ::pid_t; + + pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_uint, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_uint, + timeout: *mut ::timespec, + ) -> ::c_int; + + pub fn mallopt(param: ::c_int, value: i64) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + pub fn mallinfo() -> ::mallinfo; + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + __bufsize: ::c_int, + __result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::c_int) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; + + pub fn sysctl( + _: *const ::c_int, + _: ::c_uint, + _: *mut ::c_void, + _: *mut ::size_t, + _: *const ::c_void, + _: ::size_t, + ) -> ::c_int; + + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlp: *const ::rlimit) -> ::c_int; + + pub fn lio_listio( + __mode: ::c_int, + __list: *const *mut aiocb, + __nent: ::c_int, + __sig: *mut sigevent, + ) -> ::c_int; + + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *const dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; + + pub fn regcomp( + __preg: *mut ::regex_t, + __pattern: *const ::c_char, + __cflags: ::c_int, + ) -> ::c_int; + pub fn regexec( + __preg: *const ::regex_t, + __str: *const ::c_char, + __nmatch: ::size_t, + __pmatch: *mut ::regmatch_t, + __eflags: ::c_int, + ) -> ::c_int; + pub fn regerror( + __errcode: ::c_int, + __preg: *const ::regex_t, + __errbuf: *mut ::c_char, + __errbuf_size: ::size_t, + ) -> ::size_t; + pub fn regfree(__preg: *mut ::regex_t); + pub fn dirfd(__dirp: *mut ::DIR) -> ::c_int; + pub fn dircntl(dir: *mut ::DIR, cmd: ::c_int, ...) -> ::c_int; + + pub fn aio_cancel(__fd: ::c_int, __aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_error(__aiocbp: *const ::aiocb) -> ::c_int; + pub fn aio_fsync(__operation: ::c_int, __aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_read(__aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_return(__aiocpb: *mut ::aiocb) -> ::ssize_t; + pub fn aio_suspend( + __list: *const *const ::aiocb, + __nent: ::c_int, + __timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_write(__aiocpb: *mut ::aiocb) -> ::c_int; + + pub fn mq_close(__mqdes: ::mqd_t) -> ::c_int; + pub fn mq_getattr(__mqdes: ::mqd_t, __mqstat: *mut ::mq_attr) -> ::c_int; + pub fn mq_notify(__mqdes: ::mqd_t, __notification: *const ::sigevent) -> ::c_int; + pub fn mq_open(__name: *const ::c_char, __oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_receive( + __mqdes: ::mqd_t, + __msg_ptr: *mut ::c_char, + __msg_len: ::size_t, + __msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_send( + __mqdes: ::mqd_t, + __msg_ptr: *const ::c_char, + __msg_len: ::size_t, + __msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_setattr( + __mqdes: ::mqd_t, + __mqstat: *const mq_attr, + __omqstat: *mut mq_attr, + ) -> ::c_int; + pub fn mq_timedreceive( + __mqdes: ::mqd_t, + __msg_ptr: *mut ::c_char, + __msg_len: ::size_t, + __msg_prio: *mut ::c_uint, + __abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_timedsend( + __mqdes: ::mqd_t, + __msg_ptr: *const ::c_char, + __msg_len: ::size_t, + __msg_prio: ::c_uint, + __abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_unlink(__name: *const ::c_char) -> ::c_int; + pub fn __get_errno_ptr() -> *mut ::c_int; + + // System page, see https://www.qnx.com/developers/docs/7.1#com.qnx.doc.neutrino.building/topic/syspage/syspage_about.html + pub static mut _syspage_ptr: *mut syspage_entry; + + // Function on the stack after a call to pthread_create(). This is used + // as a sentinel to work around an infitnite loop in the unwinding code. + pub fn __my_thread_exit(value_ptr: *mut *const ::c_void); +} + +// Models the implementation in stdlib.h. Ctest will fail if trying to use the +// default symbol from libc +pub unsafe fn atexit(cb: extern "C" fn()) -> ::c_int { + extern "C" { + static __dso_handle: *mut ::c_void; + pub fn __cxa_atexit( + cb: extern "C" fn(), + __arg: *mut ::c_void, + __dso: *mut ::c_void, + ) -> ::c_int; + } + __cxa_atexit(cb, 0 as *mut ::c_void, __dso_handle) +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_si_addr { + _pad: [u8; 32], + si_addr: *mut ::c_void, + } + (*(self as *const siginfo_t as *const siginfo_si_addr)).si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_si_value { + _pad: [u8; 32], + si_value: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_si_value)).si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + #[repr(C)] + struct siginfo_si_pid { + _pad: [u8; 16], + si_pid: ::pid_t, + } + (*(self as *const siginfo_t as *const siginfo_si_pid)).si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + #[repr(C)] + struct siginfo_si_uid { + _pad: [u8; 24], + si_uid: ::uid_t, + } + (*(self as *const siginfo_t as *const siginfo_si_uid)).si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + #[repr(C)] + struct siginfo_si_status { + _pad: [u8; 28], + si_status: ::c_int, + } + (*(self as *const siginfo_t as *const siginfo_si_status)).si_status + } +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } + else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } + else { + panic!("Unsupported arch"); + } +} + +mod neutrino; +pub use self::neutrino::*; diff --git a/utshell-0.5.0/vendor/libc/src/unix/nto/neutrino.rs b/utshell-0.5.0/vendor/libc/src/unix/nto/neutrino.rs new file mode 100644 index 00000000..1a6f7da9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/nto/neutrino.rs @@ -0,0 +1,1288 @@ +pub type nto_job_t = ::sync_t; + +s! { + pub struct syspage_entry_info { + pub entry_off: u16, + pub entry_size: u16, + } + pub struct syspage_array_info { + entry_off: u16, + entry_size: u16, + element_size: u16, + } + + pub struct intrspin { + pub value: ::c_uint, // volatile + } + + pub struct iov_t { + pub iov_base: *mut ::c_void, // union + pub iov_len: ::size_t, + } + + pub struct _itimer { + pub nsec: u64, + pub interval_nsec: u64, + } + + pub struct _msg_info64 { + pub nd: u32, + pub srcnd: u32, + pub pid: ::pid_t, + pub tid: i32, + pub chid: i32, + pub scoid: i32, + pub coid: i32, + pub priority: i16, + pub flags: i16, + pub msglen: isize, + pub srcmsglen: isize, + pub dstmsglen: isize, + pub type_id: u32, + reserved: u32, + } + + pub struct _cred_info { + pub ruid: ::uid_t, + pub euid: ::uid_t, + pub suid: ::uid_t, + pub rgid: ::gid_t, + pub egid: ::gid_t, + pub sgid: ::gid_t, + pub ngroups: u32, + pub grouplist: [::gid_t; 8], + } + + pub struct _client_info { + pub nd: u32, + pub pid: ::pid_t, + pub sid: ::pid_t, + pub flags: u32, + pub cred: ::_cred_info, + } + + pub struct _client_able { + pub ability: u32, + pub flags: u32, + pub range_lo: u64, + pub range_hi: u64, + } + + pub struct nto_channel_config { + pub event: ::sigevent, + pub num_pulses: ::c_uint, + pub rearm_threshold: ::c_uint, + pub options: ::c_uint, + reserved: [::c_uint; 3], + } + + // TODO: The following structures are defined in a header file which doesn't + // appear as part of the default headers found in a standard installation + // of Neutrino 7.1 SDP. Commented out for now. + //pub struct _asyncmsg_put_header { + // pub err: ::c_int, + // pub iov: *mut ::iov_t, + // pub parts: ::c_int, + // pub handle: ::c_uint, + // pub cb: ::Option< + // unsafe extern "C" fn( + // err: ::c_int, + // buf: *mut ::c_void, + // handle: ::c_uint, + // ) -> ::c_int>, + // pub put_hdr_flags: ::c_uint, + //} + + //pub struct _asyncmsg_connection_attr { + // pub call_back: ::Option< + // unsafe extern "C" fn( + // err: ::c_int, + // buff: *mut ::c_void, + // handle: ::c_uint, + // ) -> ::c_int>, + // pub buffer_size: ::size_t, + // pub max_num_buffer: ::c_uint, + // pub trigger_num_msg: ::c_uint, + // pub trigger_time: ::_itimer, + // reserve: ::c_uint, + //} + + //pub struct _asyncmsg_connection_descriptor { + // pub flags: ::c_uint, + // pub sendq_size: ::c_uint, + // pub sendq_head: ::c_uint, + // pub sendq_tail: ::c_uint, + // pub sendq_free: ::c_uint, + // pub err: ::c_int, + // pub ev: ::sigevent, + // pub num_curmsg: ::c_uint, + // pub ttimer: ::timer_t, + // pub block_con: ::pthread_cond_t, + // pub mu: ::pthread_mutex_t, + // reserved: ::c_uint, + // pub attr: ::_asyncmsg_connection_attr, + // pub reserves: [::c_uint; 3], + // pub sendq: [::_asyncmsg_put_header; 1], // flexarray + //} + + pub struct __c_anonymous_struct_ev { + pub event: ::sigevent, + pub coid: ::c_int, + } + + pub struct _channel_connect_attr { // union + pub ev: ::__c_anonymous_struct_ev, + } + + pub struct _sighandler_info { + pub siginfo: ::siginfo_t, + pub handler: ::Option, + pub context: *mut ::c_void, + } + + pub struct __c_anonymous_struct_time { + pub length: ::c_uint, + pub scale: ::c_uint, + } + + pub struct _idle_hook { + pub hook_size: ::c_uint, + pub cmd: ::c_uint, + pub mode: ::c_uint, + pub latency: ::c_uint, + pub next_fire: u64, + pub curr_time: u64, + pub tod_adjust: u64, + pub resp: ::c_uint, + pub time: __c_anonymous_struct_time, + pub trigger: ::sigevent, + pub intrs: *mut ::c_uint, + pub block_stack_size: ::c_uint, + } + + pub struct _clockadjust { + pub tick_count: u32, + pub tick_nsec_inc: i32, + } + + pub struct qtime_entry { + pub cycles_per_sec: u64, + pub nsec_tod_adjust: u64, // volatile + pub nsec: u64, // volatile + pub nsec_inc: u32, + pub boot_time: u32, + pub adjust: _clockadjust, + pub timer_rate: u32, + pub timer_scale: i32, + pub timer_load: u32, + pub intr: i32, + pub epoch: u32, + pub flags: u32, + pub rr_interval_mul: u32, + pub timer_load_hi: u32, + pub nsec_stable: u64, // volatile + pub timer_load_max: u64, + pub timer_prog_time: u32, + spare: [u32; 7], + } + + pub struct _sched_info { + pub priority_min: ::c_int, + pub priority_max: ::c_int, + pub interval: u64, + pub priority_priv: ::c_int, + reserved: [::c_int; 11], + } + + pub struct _timer_info { + pub itime: ::_itimer, + pub otime: ::_itimer, + pub flags: u32, + pub tid: i32, + pub notify: i32, + pub clockid: ::clockid_t, + pub overruns: u32, + pub event: ::sigevent, // union + } + + pub struct _clockperiod { + pub nsec: u32, + pub fract: i32, + } +} + +s_no_extra_traits! { + + #[repr(align(8))] + pub struct syspage_entry { + pub size: u16, + pub total_size: u16, + pub type_: u16, + pub num_cpu: u16, + pub system_private: syspage_entry_info, + pub old_asinfo: syspage_entry_info, + pub __mangle_name_to_cause_compilation_errs_meminfo: syspage_entry_info, + pub hwinfo: syspage_entry_info, + pub old_cpuinfo: syspage_entry_info, + pub old_cacheattr: syspage_entry_info, + pub qtime: syspage_entry_info, + pub callout: syspage_entry_info, + pub callin: syspage_entry_info, + pub typed_strings: syspage_entry_info, + pub strings: syspage_entry_info, + pub old_intrinfo: syspage_entry_info, + pub smp: syspage_entry_info, + pub pminfo: syspage_entry_info, + pub old_mdriver: syspage_entry_info, + spare0: [u32; 1], + __reserved: [u8; 160], // anonymous union with architecture dependent structs + pub new_asinfo: syspage_array_info, + pub new_cpuinfo: syspage_array_info, + pub new_cacheattr: syspage_array_info, + pub new_intrinfo: syspage_array_info, + pub new_mdriver: syspage_array_info, + } +} + +pub const SYSMGR_PID: u32 = 1; +pub const SYSMGR_CHID: u32 = 1; +pub const SYSMGR_COID: u32 = _NTO_SIDE_CHANNEL; +pub const SYSMGR_HANDLE: u32 = 0; + +pub const STATE_DEAD: ::c_int = 0x00; +pub const STATE_RUNNING: ::c_int = 0x01; +pub const STATE_READY: ::c_int = 0x02; +pub const STATE_STOPPED: ::c_int = 0x03; +pub const STATE_SEND: ::c_int = 0x04; +pub const STATE_RECEIVE: ::c_int = 0x05; +pub const STATE_REPLY: ::c_int = 0x06; +pub const STATE_STACK: ::c_int = 0x07; +pub const STATE_WAITTHREAD: ::c_int = 0x08; +pub const STATE_WAITPAGE: ::c_int = 0x09; +pub const STATE_SIGSUSPEND: ::c_int = 0x0a; +pub const STATE_SIGWAITINFO: ::c_int = 0x0b; +pub const STATE_NANOSLEEP: ::c_int = 0x0c; +pub const STATE_MUTEX: ::c_int = 0x0d; +pub const STATE_CONDVAR: ::c_int = 0x0e; +pub const STATE_JOIN: ::c_int = 0x0f; +pub const STATE_INTR: ::c_int = 0x10; +pub const STATE_SEM: ::c_int = 0x11; +pub const STATE_WAITCTX: ::c_int = 0x12; +pub const STATE_NET_SEND: ::c_int = 0x13; +pub const STATE_NET_REPLY: ::c_int = 0x14; +pub const STATE_MAX: ::c_int = 0x18; + +pub const _NTO_TIMEOUT_RECEIVE: i32 = 1 << STATE_RECEIVE; +pub const _NTO_TIMEOUT_SEND: i32 = 1 << STATE_SEND; +pub const _NTO_TIMEOUT_REPLY: i32 = 1 << STATE_REPLY; +pub const _NTO_TIMEOUT_SIGSUSPEND: i32 = 1 << STATE_SIGSUSPEND; +pub const _NTO_TIMEOUT_SIGWAITINFO: i32 = 1 << STATE_SIGWAITINFO; +pub const _NTO_TIMEOUT_NANOSLEEP: i32 = 1 << STATE_NANOSLEEP; +pub const _NTO_TIMEOUT_MUTEX: i32 = 1 << STATE_MUTEX; +pub const _NTO_TIMEOUT_CONDVAR: i32 = 1 << STATE_CONDVAR; +pub const _NTO_TIMEOUT_JOIN: i32 = 1 << STATE_JOIN; +pub const _NTO_TIMEOUT_INTR: i32 = 1 << STATE_INTR; +pub const _NTO_TIMEOUT_SEM: i32 = 1 << STATE_SEM; + +pub const _NTO_MI_ENDIAN_BIG: u32 = 1; +pub const _NTO_MI_ENDIAN_DIFF: u32 = 2; +pub const _NTO_MI_UNBLOCK_REQ: u32 = 256; +pub const _NTO_MI_NET_CRED_DIRTY: u32 = 512; +pub const _NTO_MI_CONSTRAINED: u32 = 1024; +pub const _NTO_MI_CHROOT: u32 = 2048; +pub const _NTO_MI_BITS_64: u32 = 4096; +pub const _NTO_MI_BITS_DIFF: u32 = 8192; +pub const _NTO_MI_SANDBOX: u32 = 16384; + +pub const _NTO_CI_ENDIAN_BIG: u32 = 1; +pub const _NTO_CI_BKGND_PGRP: u32 = 4; +pub const _NTO_CI_ORPHAN_PGRP: u32 = 8; +pub const _NTO_CI_STOPPED: u32 = 128; +pub const _NTO_CI_UNABLE: u32 = 256; +pub const _NTO_CI_TYPE_ID: u32 = 512; +pub const _NTO_CI_CHROOT: u32 = 2048; +pub const _NTO_CI_BITS_64: u32 = 4096; +pub const _NTO_CI_SANDBOX: u32 = 16384; +pub const _NTO_CI_LOADER: u32 = 32768; +pub const _NTO_CI_FULL_GROUPS: u32 = 2147483648; + +pub const _NTO_TI_ACTIVE: u32 = 1; +pub const _NTO_TI_ABSOLUTE: u32 = 2; +pub const _NTO_TI_EXPIRED: u32 = 4; +pub const _NTO_TI_TOD_BASED: u32 = 8; +pub const _NTO_TI_TARGET_PROCESS: u32 = 16; +pub const _NTO_TI_REPORT_TOLERANCE: u32 = 32; +pub const _NTO_TI_PRECISE: u32 = 64; +pub const _NTO_TI_TOLERANT: u32 = 128; +pub const _NTO_TI_WAKEUP: u32 = 256; +pub const _NTO_TI_PROCESS_TOLERANT: u32 = 512; +pub const _NTO_TI_HIGH_RESOLUTION: u32 = 1024; + +pub const _PULSE_TYPE: u32 = 0; +pub const _PULSE_SUBTYPE: u32 = 0; +pub const _PULSE_CODE_UNBLOCK: i32 = -32; +pub const _PULSE_CODE_DISCONNECT: i32 = -33; +pub const _PULSE_CODE_THREADDEATH: i32 = -34; +pub const _PULSE_CODE_COIDDEATH: i32 = -35; +pub const _PULSE_CODE_NET_ACK: i32 = -36; +pub const _PULSE_CODE_NET_UNBLOCK: i32 = -37; +pub const _PULSE_CODE_NET_DETACH: i32 = -38; +pub const _PULSE_CODE_RESTART: i32 = -39; +pub const _PULSE_CODE_NORESTART: i32 = -40; +pub const _PULSE_CODE_UNBLOCK_RESTART: i32 = -41; +pub const _PULSE_CODE_UNBLOCK_TIMER: i32 = -42; +pub const _PULSE_CODE_MINAVAIL: u32 = 0; +pub const _PULSE_CODE_MAXAVAIL: u32 = 127; + +pub const _NTO_HARD_FLAGS_END: u32 = 1; + +pub const _NTO_PULSE_IF_UNIQUE: u32 = 4096; +pub const _NTO_PULSE_REPLACE: u32 = 8192; + +pub const _NTO_PF_NOCLDSTOP: u32 = 1; +pub const _NTO_PF_LOADING: u32 = 2; +pub const _NTO_PF_TERMING: u32 = 4; +pub const _NTO_PF_ZOMBIE: u32 = 8; +pub const _NTO_PF_NOZOMBIE: u32 = 16; +pub const _NTO_PF_FORKED: u32 = 32; +pub const _NTO_PF_ORPHAN_PGRP: u32 = 64; +pub const _NTO_PF_STOPPED: u32 = 128; +pub const _NTO_PF_DEBUG_STOPPED: u32 = 256; +pub const _NTO_PF_BKGND_PGRP: u32 = 512; +pub const _NTO_PF_NOISYNC: u32 = 1024; +pub const _NTO_PF_CONTINUED: u32 = 2048; +pub const _NTO_PF_CHECK_INTR: u32 = 4096; +pub const _NTO_PF_COREDUMP: u32 = 8192; +pub const _NTO_PF_RING0: u32 = 32768; +pub const _NTO_PF_SLEADER: u32 = 65536; +pub const _NTO_PF_WAITINFO: u32 = 131072; +pub const _NTO_PF_DESTROYALL: u32 = 524288; +pub const _NTO_PF_NOCOREDUMP: u32 = 1048576; +pub const _NTO_PF_WAITDONE: u32 = 4194304; +pub const _NTO_PF_TERM_WAITING: u32 = 8388608; +pub const _NTO_PF_ASLR: u32 = 16777216; +pub const _NTO_PF_EXECED: u32 = 33554432; +pub const _NTO_PF_APP_STOPPED: u32 = 67108864; +pub const _NTO_PF_64BIT: u32 = 134217728; +pub const _NTO_PF_NET: u32 = 268435456; +pub const _NTO_PF_NOLAZYSTACK: u32 = 536870912; +pub const _NTO_PF_NOEXEC_STACK: u32 = 1073741824; +pub const _NTO_PF_LOADER_PERMS: u32 = 2147483648; + +pub const _NTO_TF_INTR_PENDING: u32 = 65536; +pub const _NTO_TF_DETACHED: u32 = 131072; +pub const _NTO_TF_SHR_MUTEX: u32 = 262144; +pub const _NTO_TF_SHR_MUTEX_EUID: u32 = 524288; +pub const _NTO_TF_THREADS_HOLD: u32 = 1048576; +pub const _NTO_TF_UNBLOCK_REQ: u32 = 4194304; +pub const _NTO_TF_ALIGN_FAULT: u32 = 16777216; +pub const _NTO_TF_SSTEP: u32 = 33554432; +pub const _NTO_TF_ALLOCED_STACK: u32 = 67108864; +pub const _NTO_TF_NOMULTISIG: u32 = 134217728; +pub const _NTO_TF_LOW_LATENCY: u32 = 268435456; +pub const _NTO_TF_IOPRIV: u32 = 2147483648; + +pub const _NTO_TCTL_IO_PRIV: u32 = 1; +pub const _NTO_TCTL_THREADS_HOLD: u32 = 2; +pub const _NTO_TCTL_THREADS_CONT: u32 = 3; +pub const _NTO_TCTL_RUNMASK: u32 = 4; +pub const _NTO_TCTL_ALIGN_FAULT: u32 = 5; +pub const _NTO_TCTL_RUNMASK_GET_AND_SET: u32 = 6; +pub const _NTO_TCTL_PERFCOUNT: u32 = 7; +pub const _NTO_TCTL_ONE_THREAD_HOLD: u32 = 8; +pub const _NTO_TCTL_ONE_THREAD_CONT: u32 = 9; +pub const _NTO_TCTL_RUNMASK_GET_AND_SET_INHERIT: u32 = 10; +pub const _NTO_TCTL_NAME: u32 = 11; +pub const _NTO_TCTL_RCM_GET_AND_SET: u32 = 12; +pub const _NTO_TCTL_SHR_MUTEX: u32 = 13; +pub const _NTO_TCTL_IO: u32 = 14; +pub const _NTO_TCTL_NET_KIF_GET_AND_SET: u32 = 15; +pub const _NTO_TCTL_LOW_LATENCY: u32 = 16; +pub const _NTO_TCTL_ADD_EXIT_EVENT: u32 = 17; +pub const _NTO_TCTL_DEL_EXIT_EVENT: u32 = 18; +pub const _NTO_TCTL_IO_LEVEL: u32 = 19; +pub const _NTO_TCTL_RESERVED: u32 = 2147483648; +pub const _NTO_TCTL_IO_LEVEL_INHERIT: u32 = 1073741824; +pub const _NTO_IO_LEVEL_NONE: u32 = 1; +pub const _NTO_IO_LEVEL_1: u32 = 2; +pub const _NTO_IO_LEVEL_2: u32 = 3; + +pub const _NTO_THREAD_NAME_MAX: u32 = 100; + +pub const _NTO_CHF_FIXED_PRIORITY: u32 = 1; +pub const _NTO_CHF_UNBLOCK: u32 = 2; +pub const _NTO_CHF_THREAD_DEATH: u32 = 4; +pub const _NTO_CHF_DISCONNECT: u32 = 8; +pub const _NTO_CHF_NET_MSG: u32 = 16; +pub const _NTO_CHF_SENDER_LEN: u32 = 32; +pub const _NTO_CHF_COID_DISCONNECT: u32 = 64; +pub const _NTO_CHF_REPLY_LEN: u32 = 128; +pub const _NTO_CHF_PULSE_POOL: u32 = 256; +pub const _NTO_CHF_ASYNC_NONBLOCK: u32 = 512; +pub const _NTO_CHF_ASYNC: u32 = 1024; +pub const _NTO_CHF_GLOBAL: u32 = 2048; +pub const _NTO_CHF_PRIVATE: u32 = 4096; +pub const _NTO_CHF_MSG_PAUSING: u32 = 8192; +pub const _NTO_CHF_INHERIT_RUNMASK: u32 = 16384; +pub const _NTO_CHF_UNBLOCK_TIMER: u32 = 32768; + +pub const _NTO_CHO_CUSTOM_EVENT: u32 = 1; + +pub const _NTO_COF_CLOEXEC: u32 = 1; +pub const _NTO_COF_DEAD: u32 = 2; +pub const _NTO_COF_NOSHARE: u32 = 64; +pub const _NTO_COF_NETCON: u32 = 128; +pub const _NTO_COF_NONBLOCK: u32 = 256; +pub const _NTO_COF_ASYNC: u32 = 512; +pub const _NTO_COF_GLOBAL: u32 = 1024; +pub const _NTO_COF_NOEVENT: u32 = 2048; +pub const _NTO_COF_INSECURE: u32 = 4096; +pub const _NTO_COF_REG_EVENTS: u32 = 8192; +pub const _NTO_COF_UNREG_EVENTS: u32 = 16384; +pub const _NTO_COF_MASK: u32 = 65535; + +pub const _NTO_SIDE_CHANNEL: u32 = 1073741824; + +pub const _NTO_CONNECTION_SCOID: u32 = 65536; +pub const _NTO_GLOBAL_CHANNEL: u32 = 1073741824; + +pub const _NTO_TIMEOUT_MASK: u32 = (1 << STATE_MAX) - 1; +pub const _NTO_TIMEOUT_ACTIVE: u32 = 1 << STATE_MAX; +pub const _NTO_TIMEOUT_IMMEDIATE: u32 = 1 << (STATE_MAX + 1); + +pub const _NTO_IC_LATENCY: u32 = 0; + +pub const _NTO_INTR_FLAGS_END: u32 = 1; +pub const _NTO_INTR_FLAGS_NO_UNMASK: u32 = 2; +pub const _NTO_INTR_FLAGS_PROCESS: u32 = 4; +pub const _NTO_INTR_FLAGS_TRK_MSK: u32 = 8; +pub const _NTO_INTR_FLAGS_ARRAY: u32 = 16; +pub const _NTO_INTR_FLAGS_EXCLUSIVE: u32 = 32; +pub const _NTO_INTR_FLAGS_FPU: u32 = 64; + +pub const _NTO_INTR_CLASS_EXTERNAL: u32 = 0; +pub const _NTO_INTR_CLASS_SYNTHETIC: u32 = 2147418112; + +pub const _NTO_INTR_SPARE: u32 = 2147483647; + +pub const _NTO_HOOK_IDLE: u32 = 2147418113; +pub const _NTO_HOOK_OVERDRIVE: u32 = 2147418114; +pub const _NTO_HOOK_LAST: u32 = 2147418114; +pub const _NTO_HOOK_IDLE2_FLAG: u32 = 32768; + +pub const _NTO_IH_CMD_SLEEP_SETUP: u32 = 1; +pub const _NTO_IH_CMD_SLEEP_BLOCK: u32 = 2; +pub const _NTO_IH_CMD_SLEEP_WAKEUP: u32 = 4; +pub const _NTO_IH_CMD_SLEEP_ONLINE: u32 = 8; +pub const _NTO_IH_RESP_NEEDS_BLOCK: u32 = 1; +pub const _NTO_IH_RESP_NEEDS_WAKEUP: u32 = 2; +pub const _NTO_IH_RESP_NEEDS_ONLINE: u32 = 4; +pub const _NTO_IH_RESP_SYNC_TIME: u32 = 16; +pub const _NTO_IH_RESP_SYNC_TLB: u32 = 32; +pub const _NTO_IH_RESP_SUGGEST_OFFLINE: u32 = 256; +pub const _NTO_IH_RESP_SLEEP_MODE_REACHED: u32 = 512; +pub const _NTO_IH_RESP_DELIVER_INTRS: u32 = 1024; + +pub const _NTO_READIOV_SEND: u32 = 0; +pub const _NTO_READIOV_REPLY: u32 = 1; + +pub const _NTO_KEYDATA_VTID: u32 = 2147483648; + +pub const _NTO_KEYDATA_PATHSIGN: u32 = 32768; +pub const _NTO_KEYDATA_OP_MASK: u32 = 255; +pub const _NTO_KEYDATA_VERIFY: u32 = 0; +pub const _NTO_KEYDATA_CALCULATE: u32 = 1; +pub const _NTO_KEYDATA_CALCULATE_REUSE: u32 = 2; +pub const _NTO_KEYDATA_PATHSIGN_VERIFY: u32 = 32768; +pub const _NTO_KEYDATA_PATHSIGN_CALCULATE: u32 = 32769; +pub const _NTO_KEYDATA_PATHSIGN_CALCULATE_REUSE: u32 = 32770; + +pub const _NTO_SCTL_SETPRIOCEILING: u32 = 1; +pub const _NTO_SCTL_GETPRIOCEILING: u32 = 2; +pub const _NTO_SCTL_SETEVENT: u32 = 3; +pub const _NTO_SCTL_MUTEX_WAKEUP: u32 = 4; +pub const _NTO_SCTL_MUTEX_CONSISTENT: u32 = 5; +pub const _NTO_SCTL_SEM_VALUE: u32 = 6; + +pub const _NTO_CLIENTINFO_GETGROUPS: u32 = 1; +pub const _NTO_CLIENTINFO_GETTYPEID: u32 = 2; + +extern "C" { + pub fn ChannelCreate(__flags: ::c_uint) -> ::c_int; + pub fn ChannelCreate_r(__flags: ::c_uint) -> ::c_int; + pub fn ChannelCreatePulsePool( + __flags: ::c_uint, + __config: *const nto_channel_config, + ) -> ::c_int; + pub fn ChannelCreateExt( + __flags: ::c_uint, + __mode: ::mode_t, + __bufsize: usize, + __maxnumbuf: ::c_uint, + __ev: *const ::sigevent, + __cred: *mut _cred_info, + ) -> ::c_int; + pub fn ChannelDestroy(__chid: ::c_int) -> ::c_int; + pub fn ChannelDestroy_r(__chid: ::c_int) -> ::c_int; + pub fn ConnectAttach( + __nd: u32, + __pid: ::pid_t, + __chid: ::c_int, + __index: ::c_uint, + __flags: ::c_int, + ) -> ::c_int; + pub fn ConnectAttach_r( + __nd: u32, + __pid: ::pid_t, + __chid: ::c_int, + __index: ::c_uint, + __flags: ::c_int, + ) -> ::c_int; + + // TODO: The following function uses a structure defined in a header file + // which doesn't appear as part of the default headers found in a + // standard installation of Neutrino 7.1 SDP. Commented out for now. + //pub fn ConnectAttachExt( + // __nd: u32, + // __pid: ::pid_t, + // __chid: ::c_int, + // __index: ::c_uint, + // __flags: ::c_int, + // __cd: *mut _asyncmsg_connection_descriptor, + //) -> ::c_int; + pub fn ConnectDetach(__coid: ::c_int) -> ::c_int; + pub fn ConnectDetach_r(__coid: ::c_int) -> ::c_int; + pub fn ConnectServerInfo(__pid: ::pid_t, __coid: ::c_int, __info: *mut _msg_info64) -> ::c_int; + pub fn ConnectServerInfo_r( + __pid: ::pid_t, + __coid: ::c_int, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn ConnectClientInfoExtraArgs( + __scoid: ::c_int, + __info_pp: *mut _client_info, + __ngroups: ::c_int, + __abilities: *mut _client_able, + __nable: ::c_int, + __type_id: *mut ::c_uint, + ) -> ::c_int; + pub fn ConnectClientInfoExtraArgs_r( + __scoid: ::c_int, + __info_pp: *mut _client_info, + __ngroups: ::c_int, + __abilities: *mut _client_able, + __nable: ::c_int, + __type_id: *mut ::c_uint, + ) -> ::c_int; + pub fn ConnectClientInfo( + __scoid: ::c_int, + __info: *mut _client_info, + __ngroups: ::c_int, + ) -> ::c_int; + pub fn ConnectClientInfo_r( + __scoid: ::c_int, + __info: *mut _client_info, + __ngroups: ::c_int, + ) -> ::c_int; + pub fn ConnectClientInfoExt( + __scoid: ::c_int, + __info_pp: *mut *mut _client_info, + flags: ::c_int, + ) -> ::c_int; + pub fn ClientInfoExtFree(__info_pp: *mut *mut _client_info) -> ::c_int; + pub fn ConnectClientInfoAble( + __scoid: ::c_int, + __info_pp: *mut *mut _client_info, + flags: ::c_int, + abilities: *mut _client_able, + nable: ::c_int, + ) -> ::c_int; + pub fn ConnectFlags( + __pid: ::pid_t, + __coid: ::c_int, + __mask: ::c_uint, + __bits: ::c_uint, + ) -> ::c_int; + pub fn ConnectFlags_r( + __pid: ::pid_t, + __coid: ::c_int, + __mask: ::c_uint, + __bits: ::c_uint, + ) -> ::c_int; + pub fn ChannelConnectAttr( + __id: ::c_uint, + __old_attr: *mut _channel_connect_attr, + __new_attr: *mut _channel_connect_attr, + __flags: ::c_uint, + ) -> ::c_int; + pub fn MsgSend( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSend_r( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendnc( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendnc_r( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendsv( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendsv_r( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendsvnc( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendsvnc_r( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendvs( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendvs_r( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendvsnc( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendvsnc_r( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __rmsg: *mut ::c_void, + __rbytes: usize, + ) -> ::c_long; + pub fn MsgSendv( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendv_r( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendvnc( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgSendvnc_r( + __coid: ::c_int, + __siov: *const ::iovec, + __sparts: usize, + __riov: *const ::iovec, + __rparts: usize, + ) -> ::c_long; + pub fn MsgReceive( + __chid: ::c_int, + __msg: *mut ::c_void, + __bytes: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceive_r( + __chid: ::c_int, + __msg: *mut ::c_void, + __bytes: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceivev( + __chid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceivev_r( + __chid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceivePulse( + __chid: ::c_int, + __pulse: *mut ::c_void, + __bytes: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceivePulse_r( + __chid: ::c_int, + __pulse: *mut ::c_void, + __bytes: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceivePulsev( + __chid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReceivePulsev_r( + __chid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __info: *mut _msg_info64, + ) -> ::c_int; + pub fn MsgReply( + __rcvid: ::c_int, + __status: ::c_long, + __msg: *const ::c_void, + __bytes: usize, + ) -> ::c_int; + pub fn MsgReply_r( + __rcvid: ::c_int, + __status: ::c_long, + __msg: *const ::c_void, + __bytes: usize, + ) -> ::c_int; + pub fn MsgReplyv( + __rcvid: ::c_int, + __status: ::c_long, + __iov: *const ::iovec, + __parts: usize, + ) -> ::c_int; + pub fn MsgReplyv_r( + __rcvid: ::c_int, + __status: ::c_long, + __iov: *const ::iovec, + __parts: usize, + ) -> ::c_int; + pub fn MsgReadiov( + __rcvid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __offset: usize, + __flags: ::c_int, + ) -> isize; + pub fn MsgReadiov_r( + __rcvid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __offset: usize, + __flags: ::c_int, + ) -> isize; + pub fn MsgRead( + __rcvid: ::c_int, + __msg: *mut ::c_void, + __bytes: usize, + __offset: usize, + ) -> isize; + pub fn MsgRead_r( + __rcvid: ::c_int, + __msg: *mut ::c_void, + __bytes: usize, + __offset: usize, + ) -> isize; + pub fn MsgReadv( + __rcvid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __offset: usize, + ) -> isize; + pub fn MsgReadv_r( + __rcvid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __offset: usize, + ) -> isize; + pub fn MsgWrite( + __rcvid: ::c_int, + __msg: *const ::c_void, + __bytes: usize, + __offset: usize, + ) -> isize; + pub fn MsgWrite_r( + __rcvid: ::c_int, + __msg: *const ::c_void, + __bytes: usize, + __offset: usize, + ) -> isize; + pub fn MsgWritev( + __rcvid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __offset: usize, + ) -> isize; + pub fn MsgWritev_r( + __rcvid: ::c_int, + __iov: *const ::iovec, + __parts: usize, + __offset: usize, + ) -> isize; + pub fn MsgSendPulse( + __coid: ::c_int, + __priority: ::c_int, + __code: ::c_int, + __value: ::c_int, + ) -> ::c_int; + pub fn MsgSendPulse_r( + __coid: ::c_int, + __priority: ::c_int, + __code: ::c_int, + __value: ::c_int, + ) -> ::c_int; + pub fn MsgSendPulsePtr( + __coid: ::c_int, + __priority: ::c_int, + __code: ::c_int, + __value: *mut ::c_void, + ) -> ::c_int; + pub fn MsgSendPulsePtr_r( + __coid: ::c_int, + __priority: ::c_int, + __code: ::c_int, + __value: *mut ::c_void, + ) -> ::c_int; + pub fn MsgDeliverEvent(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; + pub fn MsgDeliverEvent_r(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; + pub fn MsgVerifyEvent(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; + pub fn MsgVerifyEvent_r(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; + pub fn MsgRegisterEvent(__event: *mut ::sigevent, __coid: ::c_int) -> ::c_int; + pub fn MsgRegisterEvent_r(__event: *mut ::sigevent, __coid: ::c_int) -> ::c_int; + pub fn MsgUnregisterEvent(__event: *const ::sigevent) -> ::c_int; + pub fn MsgUnregisterEvent_r(__event: *const ::sigevent) -> ::c_int; + pub fn MsgInfo(__rcvid: ::c_int, __info: *mut _msg_info64) -> ::c_int; + pub fn MsgInfo_r(__rcvid: ::c_int, __info: *mut _msg_info64) -> ::c_int; + pub fn MsgKeyData( + __rcvid: ::c_int, + __oper: ::c_int, + __key: u32, + __newkey: *mut u32, + __iov: *const ::iovec, + __parts: ::c_int, + ) -> ::c_int; + pub fn MsgKeyData_r( + __rcvid: ::c_int, + __oper: ::c_int, + __key: u32, + __newkey: *mut u32, + __iov: *const ::iovec, + __parts: ::c_int, + ) -> ::c_int; + pub fn MsgError(__rcvid: ::c_int, __err: ::c_int) -> ::c_int; + pub fn MsgError_r(__rcvid: ::c_int, __err: ::c_int) -> ::c_int; + pub fn MsgCurrent(__rcvid: ::c_int) -> ::c_int; + pub fn MsgCurrent_r(__rcvid: ::c_int) -> ::c_int; + pub fn MsgSendAsyncGbl( + __coid: ::c_int, + __smsg: *const ::c_void, + __sbytes: usize, + __msg_prio: ::c_uint, + ) -> ::c_int; + pub fn MsgSendAsync(__coid: ::c_int) -> ::c_int; + pub fn MsgReceiveAsyncGbl( + __chid: ::c_int, + __rmsg: *mut ::c_void, + __rbytes: usize, + __info: *mut _msg_info64, + __coid: ::c_int, + ) -> ::c_int; + pub fn MsgReceiveAsync(__chid: ::c_int, __iov: *const ::iovec, __parts: ::c_uint) -> ::c_int; + pub fn MsgPause(__rcvid: ::c_int, __cookie: ::c_uint) -> ::c_int; + pub fn MsgPause_r(__rcvid: ::c_int, __cookie: ::c_uint) -> ::c_int; + + pub fn SignalKill( + __nd: u32, + __pid: ::pid_t, + __tid: ::c_int, + __signo: ::c_int, + __code: ::c_int, + __value: ::c_int, + ) -> ::c_int; + pub fn SignalKill_r( + __nd: u32, + __pid: ::pid_t, + __tid: ::c_int, + __signo: ::c_int, + __code: ::c_int, + __value: ::c_int, + ) -> ::c_int; + pub fn SignalKillSigval( + __nd: u32, + __pid: ::pid_t, + __tid: ::c_int, + __signo: ::c_int, + __code: ::c_int, + __value: *const ::sigval, + ) -> ::c_int; + pub fn SignalKillSigval_r( + __nd: u32, + __pid: ::pid_t, + __tid: ::c_int, + __signo: ::c_int, + __code: ::c_int, + __value: *const ::sigval, + ) -> ::c_int; + pub fn SignalReturn(__info: *mut _sighandler_info) -> ::c_int; + pub fn SignalFault(__sigcode: ::c_uint, __regs: *mut ::c_void, __refaddr: usize) -> ::c_int; + pub fn SignalAction( + __pid: ::pid_t, + __sigstub: unsafe extern "C" fn(), + __signo: ::c_int, + __act: *const ::sigaction, + __oact: *mut ::sigaction, + ) -> ::c_int; + pub fn SignalAction_r( + __pid: ::pid_t, + __sigstub: unsafe extern "C" fn(), + __signo: ::c_int, + __act: *const ::sigaction, + __oact: *mut ::sigaction, + ) -> ::c_int; + pub fn SignalProcmask( + __pid: ::pid_t, + __tid: ::c_int, + __how: ::c_int, + __set: *const ::sigset_t, + __oldset: *mut ::sigset_t, + ) -> ::c_int; + pub fn SignalProcmask_r( + __pid: ::pid_t, + __tid: ::c_int, + __how: ::c_int, + __set: *const ::sigset_t, + __oldset: *mut ::sigset_t, + ) -> ::c_int; + pub fn SignalSuspend(__set: *const ::sigset_t) -> ::c_int; + pub fn SignalSuspend_r(__set: *const ::sigset_t) -> ::c_int; + pub fn SignalWaitinfo(__set: *const ::sigset_t, __info: *mut ::siginfo_t) -> ::c_int; + pub fn SignalWaitinfo_r(__set: *const ::sigset_t, __info: *mut ::siginfo_t) -> ::c_int; + pub fn SignalWaitinfoMask( + __set: *const ::sigset_t, + __info: *mut ::siginfo_t, + __mask: *const ::sigset_t, + ) -> ::c_int; + pub fn SignalWaitinfoMask_r( + __set: *const ::sigset_t, + __info: *mut ::siginfo_t, + __mask: *const ::sigset_t, + ) -> ::c_int; + pub fn ThreadCreate( + __pid: ::pid_t, + __func: unsafe extern "C" fn(__arg: *mut ::c_void) -> *mut ::c_void, + __arg: *mut ::c_void, + __attr: *const ::_thread_attr, + ) -> ::c_int; + pub fn ThreadCreate_r( + __pid: ::pid_t, + __func: unsafe extern "C" fn(__arg: *mut ::c_void) -> *mut ::c_void, + __arg: *mut ::c_void, + __attr: *const ::_thread_attr, + ) -> ::c_int; + + pub fn ThreadDestroy(__tid: ::c_int, __priority: ::c_int, __status: *mut ::c_void) -> ::c_int; + pub fn ThreadDestroy_r(__tid: ::c_int, __priority: ::c_int, __status: *mut ::c_void) + -> ::c_int; + pub fn ThreadDetach(__tid: ::c_int) -> ::c_int; + pub fn ThreadDetach_r(__tid: ::c_int) -> ::c_int; + pub fn ThreadJoin(__tid: ::c_int, __status: *mut *mut ::c_void) -> ::c_int; + pub fn ThreadJoin_r(__tid: ::c_int, __status: *mut *mut ::c_void) -> ::c_int; + pub fn ThreadCancel(__tid: ::c_int, __canstub: unsafe extern "C" fn()) -> ::c_int; + pub fn ThreadCancel_r(__tid: ::c_int, __canstub: unsafe extern "C" fn()) -> ::c_int; + pub fn ThreadCtl(__cmd: ::c_int, __data: *mut ::c_void) -> ::c_int; + pub fn ThreadCtl_r(__cmd: ::c_int, __data: *mut ::c_void) -> ::c_int; + pub fn ThreadCtlExt( + __pid: ::pid_t, + __tid: ::c_int, + __cmd: ::c_int, + __data: *mut ::c_void, + ) -> ::c_int; + pub fn ThreadCtlExt_r( + __pid: ::pid_t, + __tid: ::c_int, + __cmd: ::c_int, + __data: *mut ::c_void, + ) -> ::c_int; + + pub fn InterruptHookTrace( + __handler: ::Option *const ::sigevent>, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptHookIdle( + __handler: ::Option, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptHookIdle2( + __handler: ::Option< + unsafe extern "C" fn(arg1: ::c_uint, arg2: *mut syspage_entry, arg3: *mut _idle_hook), + >, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptHookOverdriveEvent(__event: *const ::sigevent, __flags: ::c_uint) -> ::c_int; + pub fn InterruptAttachEvent( + __intr: ::c_int, + __event: *const ::sigevent, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptAttachEvent_r( + __intr: ::c_int, + __event: *const ::sigevent, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptAttach( + __intr: ::c_int, + __handler: ::Option< + unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const ::sigevent, + >, + __area: *const ::c_void, + __size: ::c_int, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptAttach_r( + __intr: ::c_int, + __handler: ::Option< + unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const ::sigevent, + >, + __area: *const ::c_void, + __size: ::c_int, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptAttachArray( + __intr: ::c_int, + __handler: ::Option< + unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const *const ::sigevent, + >, + __area: *const ::c_void, + __size: ::c_int, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptAttachArray_r( + __intr: ::c_int, + __handler: ::Option< + unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const *const ::sigevent, + >, + __area: *const ::c_void, + __size: ::c_int, + __flags: ::c_uint, + ) -> ::c_int; + pub fn InterruptDetach(__id: ::c_int) -> ::c_int; + pub fn InterruptDetach_r(__id: ::c_int) -> ::c_int; + pub fn InterruptWait(__flags: ::c_int, __timeout: *const u64) -> ::c_int; + pub fn InterruptWait_r(__flags: ::c_int, __timeout: *const u64) -> ::c_int; + pub fn InterruptCharacteristic( + __type: ::c_int, + __id: ::c_int, + __new: *mut ::c_uint, + __old: *mut ::c_uint, + ) -> ::c_int; + pub fn InterruptCharacteristic_r( + __type: ::c_int, + __id: ::c_int, + __new: *mut ::c_uint, + __old: *mut ::c_uint, + ) -> ::c_int; + + pub fn SchedGet(__pid: ::pid_t, __tid: ::c_int, __param: *mut ::sched_param) -> ::c_int; + pub fn SchedGet_r(__pid: ::pid_t, __tid: ::c_int, __param: *mut ::sched_param) -> ::c_int; + pub fn SchedGetCpuNum() -> ::c_uint; + pub fn SchedSet( + __pid: ::pid_t, + __tid: ::c_int, + __algorithm: ::c_int, + __param: *const ::sched_param, + ) -> ::c_int; + pub fn SchedSet_r( + __pid: ::pid_t, + __tid: ::c_int, + __algorithm: ::c_int, + __param: *const ::sched_param, + ) -> ::c_int; + pub fn SchedInfo(__pid: ::pid_t, __algorithm: ::c_int, __info: *mut ::_sched_info) -> ::c_int; + pub fn SchedInfo_r(__pid: ::pid_t, __algorithm: ::c_int, __info: *mut ::_sched_info) + -> ::c_int; + pub fn SchedYield() -> ::c_int; + pub fn SchedYield_r() -> ::c_int; + pub fn SchedCtl(__cmd: ::c_int, __data: *mut ::c_void, __length: usize) -> ::c_int; + pub fn SchedCtl_r(__cmd: ::c_int, __data: *mut ::c_void, __length: usize) -> ::c_int; + pub fn SchedJobCreate(__job: *mut nto_job_t) -> ::c_int; + pub fn SchedJobCreate_r(__job: *mut nto_job_t) -> ::c_int; + pub fn SchedJobDestroy(__job: *mut nto_job_t) -> ::c_int; + pub fn SchedJobDestroy_r(__job: *mut nto_job_t) -> ::c_int; + pub fn SchedWaypoint( + __job: *mut nto_job_t, + __new: *const i64, + __max: *const i64, + __old: *mut i64, + ) -> ::c_int; + pub fn SchedWaypoint_r( + __job: *mut nto_job_t, + __new: *const i64, + __max: *const i64, + __old: *mut i64, + ) -> ::c_int; + + pub fn TimerCreate(__id: ::clockid_t, __notify: *const ::sigevent) -> ::c_int; + pub fn TimerCreate_r(__id: ::clockid_t, __notify: *const ::sigevent) -> ::c_int; + pub fn TimerDestroy(__id: ::timer_t) -> ::c_int; + pub fn TimerDestroy_r(__id: ::timer_t) -> ::c_int; + pub fn TimerSettime( + __id: ::timer_t, + __flags: ::c_int, + __itime: *const ::_itimer, + __oitime: *mut ::_itimer, + ) -> ::c_int; + pub fn TimerSettime_r( + __id: ::timer_t, + __flags: ::c_int, + __itime: *const ::_itimer, + __oitime: *mut ::_itimer, + ) -> ::c_int; + pub fn TimerInfo( + __pid: ::pid_t, + __id: ::timer_t, + __flags: ::c_int, + __info: *mut ::_timer_info, + ) -> ::c_int; + pub fn TimerInfo_r( + __pid: ::pid_t, + __id: ::timer_t, + __flags: ::c_int, + __info: *mut ::_timer_info, + ) -> ::c_int; + pub fn TimerAlarm( + __id: ::clockid_t, + __itime: *const ::_itimer, + __otime: *mut ::_itimer, + ) -> ::c_int; + pub fn TimerAlarm_r( + __id: ::clockid_t, + __itime: *const ::_itimer, + __otime: *mut ::_itimer, + ) -> ::c_int; + pub fn TimerTimeout( + __id: ::clockid_t, + __flags: ::c_int, + __notify: *const ::sigevent, + __ntime: *const u64, + __otime: *mut u64, + ) -> ::c_int; + pub fn TimerTimeout_r( + __id: ::clockid_t, + __flags: ::c_int, + __notify: *const ::sigevent, + __ntime: *const u64, + __otime: *mut u64, + ) -> ::c_int; + + pub fn SyncTypeCreate( + __type: ::c_uint, + __sync: *mut ::sync_t, + __attr: *const ::_sync_attr, + ) -> ::c_int; + pub fn SyncTypeCreate_r( + __type: ::c_uint, + __sync: *mut ::sync_t, + __attr: *const ::_sync_attr, + ) -> ::c_int; + pub fn SyncDestroy(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncDestroy_r(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncCtl(__cmd: ::c_int, __sync: *mut ::sync_t, __data: *mut ::c_void) -> ::c_int; + pub fn SyncCtl_r(__cmd: ::c_int, __sync: *mut ::sync_t, __data: *mut ::c_void) -> ::c_int; + pub fn SyncMutexEvent(__sync: *mut ::sync_t, event: *const ::sigevent) -> ::c_int; + pub fn SyncMutexEvent_r(__sync: *mut ::sync_t, event: *const ::sigevent) -> ::c_int; + pub fn SyncMutexLock(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncMutexLock_r(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncMutexUnlock(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncMutexUnlock_r(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncMutexRevive(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncMutexRevive_r(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncCondvarWait(__sync: *mut ::sync_t, __mutex: *mut ::sync_t) -> ::c_int; + pub fn SyncCondvarWait_r(__sync: *mut ::sync_t, __mutex: *mut ::sync_t) -> ::c_int; + pub fn SyncCondvarSignal(__sync: *mut ::sync_t, __all: ::c_int) -> ::c_int; + pub fn SyncCondvarSignal_r(__sync: *mut ::sync_t, __all: ::c_int) -> ::c_int; + pub fn SyncSemPost(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncSemPost_r(__sync: *mut ::sync_t) -> ::c_int; + pub fn SyncSemWait(__sync: *mut ::sync_t, __tryto: ::c_int) -> ::c_int; + pub fn SyncSemWait_r(__sync: *mut ::sync_t, __tryto: ::c_int) -> ::c_int; + + pub fn ClockTime(__id: ::clockid_t, _new: *const u64, __old: *mut u64) -> ::c_int; + pub fn ClockTime_r(__id: ::clockid_t, _new: *const u64, __old: *mut u64) -> ::c_int; + pub fn ClockAdjust( + __id: ::clockid_t, + _new: *const ::_clockadjust, + __old: *mut ::_clockadjust, + ) -> ::c_int; + pub fn ClockAdjust_r( + __id: ::clockid_t, + _new: *const ::_clockadjust, + __old: *mut ::_clockadjust, + ) -> ::c_int; + pub fn ClockPeriod( + __id: ::clockid_t, + _new: *const ::_clockperiod, + __old: *mut ::_clockperiod, + __reserved: ::c_int, + ) -> ::c_int; + pub fn ClockPeriod_r( + __id: ::clockid_t, + _new: *const ::_clockperiod, + __old: *mut ::_clockperiod, + __reserved: ::c_int, + ) -> ::c_int; + pub fn ClockId(__pid: ::pid_t, __tid: ::c_int) -> ::c_int; + pub fn ClockId_r(__pid: ::pid_t, __tid: ::c_int) -> ::c_int; + + // + //TODO: The following commented out functions are implemented in assembly. + // We can implmement them either via a C stub or rust's inline assembly. + // + //pub fn InterruptEnable(); + //pub fn InterruptDisable(); + pub fn InterruptMask(__intr: ::c_int, __id: ::c_int) -> ::c_int; + pub fn InterruptUnmask(__intr: ::c_int, __id: ::c_int) -> ::c_int; + //pub fn InterruptLock(__spin: *mut ::intrspin); + //pub fn InterruptUnlock(__spin: *mut ::intrspin); + //pub fn InterruptStatus() -> ::c_uint; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/nto/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/nto/x86_64.rs new file mode 100644 index 00000000..3a1d230b --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/nto/x86_64.rs @@ -0,0 +1,132 @@ +pub type c_char = i8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; +pub type time_t = i64; + +s! { + #[repr(align(8))] + pub struct x86_64_cpu_registers { + pub rdi: u64, + pub rsi: u64, + pub rdx: u64, + pub r10: u64, + pub r8: u64, + pub r9: u64, + pub rax: u64, + pub rbx: u64, + pub rbp: u64, + pub rcx: u64, + pub r11: u64, + pub r12: u64, + pub r13: u64, + pub r14: u64, + pub r15: u64, + pub rip: u64, + pub cs: u32, + rsvd1: u32, + pub rflags: u64, + pub rsp: u64, + pub ss: u32, + rsvd2: u32, + } + + #[repr(align(8))] + pub struct mcontext_t { + pub cpu: x86_64_cpu_registers, + #[cfg(libc_union)] + pub fpu: x86_64_fpu_registers, + #[cfg(not(libc_union))] + __reserved: [u8; 1024], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct fsave_area_64 { + pub fpu_control_word: u32, + pub fpu_status_word: u32, + pub fpu_tag_word: u32, + pub fpu_ip: u32, + pub fpu_cs: u32, + pub fpu_op: u32, + pub fpu_ds: u32, + pub st_regs: [u8; 80], + } + + pub struct fxsave_area_64 { + pub fpu_control_word: u16, + pub fpu_status_word: u16, + pub fpu_tag_word: u16, + pub fpu_operand: u16, + pub fpu_rip: u64, + pub fpu_rdp: u64, + pub mxcsr: u32, + pub mxcsr_mask: u32, + pub st_regs: [u8; 128], + pub xmm_regs: [u8; 128], + reserved2: [u8; 224], + } + + pub struct fpu_extention_savearea_64 { + pub other: [u8; 512], + pub xstate_bv: u64, + pub xstate_undef: [u64; 7], + pub xstate_info: [u8; 224], + } +} + +s_no_extra_traits! { + #[cfg(libc_union)] + pub union x86_64_fpu_registers { + pub fsave_area: fsave_area_64, + pub fxsave_area: fxsave_area_64, + pub xsave_area: fpu_extention_savearea_64, + pub data: [u8; 1024], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[cfg(libc_union)] + impl Eq for x86_64_fpu_registers {} + + #[cfg(libc_union)] + impl PartialEq for x86_64_fpu_registers { + fn eq(&self, other: &x86_64_fpu_registers) -> bool { + unsafe { + self.fsave_area == other.fsave_area + || self.fxsave_area == other.fxsave_area + || self.xsave_area == other.xsave_area + } + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for x86_64_fpu_registers { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("x86_64_fpu_registers") + .field("fsave_area", &self.fsave_area) + .field("fxsave_area", &self.fxsave_area) + .field("xsave_area", &self.xsave_area) + .finish() + } + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for x86_64_fpu_registers { + fn hash(&self, state: &mut H) { + unsafe { + self.fsave_area.hash(state); + self.fxsave_area.hash(state); + self.xsave_area.hash(state); + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/redox/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/redox/mod.rs new file mode 100644 index 00000000..19315c38 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/redox/mod.rs @@ -0,0 +1,1416 @@ +pub type c_char = i8; +pub type wchar_t = i32; + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + pub type c_long = i32; + pub type c_ulong = u32; + } +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub type c_long = i64; + pub type c_ulong = u64; + } +} + +pub type blkcnt_t = ::c_ulong; +pub type blksize_t = ::c_long; +pub type clock_t = ::c_long; +pub type clockid_t = ::c_int; +pub type dev_t = ::c_long; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type mode_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type nlink_t = ::c_ulong; +pub type off_t = ::c_longlong; +pub type pthread_t = *mut ::c_void; +// Must be usize due to library/std/sys_common/thread_local.rs, +// should technically be *mut ::c_void +pub type pthread_key_t = usize; +pub type rlim_t = ::c_ulonglong; +pub type sa_family_t = u16; +pub type sem_t = *mut ::c_void; +pub type sigset_t = ::c_ulonglong; +pub type socklen_t = u32; +pub type speed_t = u32; +pub type suseconds_t = ::c_int; +pub type tcflag_t = u32; +pub type time_t = ::c_longlong; +pub type id_t = ::c_uint; +pub type pid_t = usize; +pub type uid_t = u32; +pub type gid_t = u32; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +s_no_extra_traits! { + #[repr(C)] + pub struct utsname { + pub sysname: [::c_char; UTSLENGTH], + pub nodename: [::c_char; UTSLENGTH], + pub release: [::c_char; UTSLENGTH], + pub version: [::c_char; UTSLENGTH], + pub machine: [::c_char; UTSLENGTH], + pub domainname: [::c_char; UTSLENGTH], + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_un { + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + __ss_padding: [ + u8; + 128 - + ::core::mem::size_of::() - + ::core::mem::size_of::() + ], + __ss_align: ::c_ulong, + } +} + +s! { + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::size_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut ::addrinfo, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct epoll_event { + pub events: u32, + pub u64: u64, + pub _pad: u64, + } + + pub struct fd_set { + fds_bits: [::c_ulong; ::FD_SETSIZE / ULONG_SIZE], + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: ::in_addr, + pub imr_interface: ::in_addr, + } + + pub struct lconv { + pub currency_symbol: *const ::c_char, + pub decimal_point: *const ::c_char, + pub frac_digits: ::c_char, + pub grouping: *const ::c_char, + pub int_curr_symbol: *const ::c_char, + pub int_frac_digits: ::c_char, + pub mon_decimal_point: *const ::c_char, + pub mon_grouping: *const ::c_char, + pub mon_thousands_sep: *const ::c_char, + pub negative_sign: *const ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub n_sign_posn: ::c_char, + pub positive_sign: *const ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub thousands_sep: *const ::c_char, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_ulong, + pub sa_restorer: ::Option, + pub sa_mask: ::sigset_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } + + pub struct sockaddr_in6 { + pub sin6_family: ::sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + _pad: [::c_char; 24], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + pub tm_gmtoff: ::c_long, + pub tm_zone: *const ::c_char, + } + + pub struct ucred { + pub pid: pid_t, + pub uid: uid_t, + pub gid: gid_t, + } + + #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] + #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] + pub struct pthread_attr_t { + bytes: [u8; _PTHREAD_ATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_barrier_t { + bytes: [u8; _PTHREAD_BARRIER_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_barrierattr_t { + bytes: [u8; _PTHREAD_BARRIERATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_mutex_t { + bytes: [u8; _PTHREAD_MUTEX_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_rwlock_t { + bytes: [u8; _PTHREAD_RWLOCK_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_mutexattr_t { + bytes: [u8; _PTHREAD_MUTEXATTR_SIZE], + } + #[repr(C)] + #[repr(align(1))] + pub struct pthread_rwlockattr_t { + bytes: [u8; _PTHREAD_RWLOCKATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_cond_t { + bytes: [u8; _PTHREAD_COND_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_condattr_t { + bytes: [u8; _PTHREAD_CONDATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_once_t { + bytes: [u8; _PTHREAD_ONCE_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_spinlock_t { + bytes: [u8; _PTHREAD_SPINLOCK_SIZE], + } +} +const _PTHREAD_ATTR_SIZE: usize = 32; +const _PTHREAD_RWLOCKATTR_SIZE: usize = 1; +const _PTHREAD_RWLOCK_SIZE: usize = 4; +const _PTHREAD_BARRIER_SIZE: usize = 24; +const _PTHREAD_BARRIERATTR_SIZE: usize = 4; +const _PTHREAD_CONDATTR_SIZE: usize = 8; +const _PTHREAD_COND_SIZE: usize = 8; +const _PTHREAD_MUTEX_SIZE: usize = 12; +const _PTHREAD_MUTEXATTR_SIZE: usize = 20; +const _PTHREAD_ONCE_SIZE: usize = 4; +const _PTHREAD_SPINLOCK_SIZE: usize = 4; + +pub const UTSLENGTH: usize = 65; + +// intentionally not public, only used for fd_set +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + const ULONG_SIZE: usize = 32; + } else if #[cfg(target_pointer_width = "64")] { + const ULONG_SIZE: usize = 64; + } else { + // Unknown target_pointer_width + } +} + +// limits.h +pub const PATH_MAX: ::c_int = 4096; + +// fcntl.h +pub const F_GETLK: ::c_int = 5; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_ULOCK: ::c_int = 0; +pub const F_LOCK: ::c_int = 1; +pub const F_TLOCK: ::c_int = 2; +pub const F_TEST: ::c_int = 3; + +// FIXME: relibc { +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +// } + +// dlfcn.h +pub const RTLD_LAZY: ::c_int = 0x0001; +pub const RTLD_NOW: ::c_int = 0x0002; +pub const RTLD_GLOBAL: ::c_int = 0x0100; +pub const RTLD_LOCAL: ::c_int = 0x0000; + +// errno.h +pub const EPERM: ::c_int = 1; /* Operation not permitted */ +pub const ENOENT: ::c_int = 2; /* No such file or directory */ +pub const ESRCH: ::c_int = 3; /* No such process */ +pub const EINTR: ::c_int = 4; /* Interrupted system call */ +pub const EIO: ::c_int = 5; /* I/O error */ +pub const ENXIO: ::c_int = 6; /* No such device or address */ +pub const E2BIG: ::c_int = 7; /* Argument list too long */ +pub const ENOEXEC: ::c_int = 8; /* Exec format error */ +pub const EBADF: ::c_int = 9; /* Bad file number */ +pub const ECHILD: ::c_int = 10; /* No child processes */ +pub const EAGAIN: ::c_int = 11; /* Try again */ +pub const ENOMEM: ::c_int = 12; /* Out of memory */ +pub const EACCES: ::c_int = 13; /* Permission denied */ +pub const EFAULT: ::c_int = 14; /* Bad address */ +pub const ENOTBLK: ::c_int = 15; /* Block device required */ +pub const EBUSY: ::c_int = 16; /* Device or resource busy */ +pub const EEXIST: ::c_int = 17; /* File exists */ +pub const EXDEV: ::c_int = 18; /* Cross-device link */ +pub const ENODEV: ::c_int = 19; /* No such device */ +pub const ENOTDIR: ::c_int = 20; /* Not a directory */ +pub const EISDIR: ::c_int = 21; /* Is a directory */ +pub const EINVAL: ::c_int = 22; /* Invalid argument */ +pub const ENFILE: ::c_int = 23; /* File table overflow */ +pub const EMFILE: ::c_int = 24; /* Too many open files */ +pub const ENOTTY: ::c_int = 25; /* Not a typewriter */ +pub const ETXTBSY: ::c_int = 26; /* Text file busy */ +pub const EFBIG: ::c_int = 27; /* File too large */ +pub const ENOSPC: ::c_int = 28; /* No space left on device */ +pub const ESPIPE: ::c_int = 29; /* Illegal seek */ +pub const EROFS: ::c_int = 30; /* Read-only file system */ +pub const EMLINK: ::c_int = 31; /* Too many links */ +pub const EPIPE: ::c_int = 32; /* Broken pipe */ +pub const EDOM: ::c_int = 33; /* Math argument out of domain of func */ +pub const ERANGE: ::c_int = 34; /* Math result not representable */ +pub const EDEADLK: ::c_int = 35; /* Resource deadlock would occur */ +pub const ENAMETOOLONG: ::c_int = 36; /* File name too long */ +pub const ENOLCK: ::c_int = 37; /* No record locks available */ +pub const ENOSYS: ::c_int = 38; /* Function not implemented */ +pub const ENOTEMPTY: ::c_int = 39; /* Directory not empty */ +pub const ELOOP: ::c_int = 40; /* Too many symbolic links encountered */ +pub const EWOULDBLOCK: ::c_int = 41; /* Operation would block */ +pub const ENOMSG: ::c_int = 42; /* No message of desired type */ +pub const EIDRM: ::c_int = 43; /* Identifier removed */ +pub const ECHRNG: ::c_int = 44; /* Channel number out of range */ +pub const EL2NSYNC: ::c_int = 45; /* Level 2 not synchronized */ +pub const EL3HLT: ::c_int = 46; /* Level 3 halted */ +pub const EL3RST: ::c_int = 47; /* Level 3 reset */ +pub const ELNRNG: ::c_int = 48; /* Link number out of range */ +pub const EUNATCH: ::c_int = 49; /* Protocol driver not attached */ +pub const ENOCSI: ::c_int = 50; /* No CSI structure available */ +pub const EL2HLT: ::c_int = 51; /* Level 2 halted */ +pub const EBADE: ::c_int = 52; /* Invalid exchange */ +pub const EBADR: ::c_int = 53; /* Invalid request descriptor */ +pub const EXFULL: ::c_int = 54; /* Exchange full */ +pub const ENOANO: ::c_int = 55; /* No anode */ +pub const EBADRQC: ::c_int = 56; /* Invalid request code */ +pub const EBADSLT: ::c_int = 57; /* Invalid slot */ +pub const EDEADLOCK: ::c_int = 58; /* Resource deadlock would occur */ +pub const EBFONT: ::c_int = 59; /* Bad font file format */ +pub const ENOSTR: ::c_int = 60; /* Device not a stream */ +pub const ENODATA: ::c_int = 61; /* No data available */ +pub const ETIME: ::c_int = 62; /* Timer expired */ +pub const ENOSR: ::c_int = 63; /* Out of streams resources */ +pub const ENONET: ::c_int = 64; /* Machine is not on the network */ +pub const ENOPKG: ::c_int = 65; /* Package not installed */ +pub const EREMOTE: ::c_int = 66; /* Object is remote */ +pub const ENOLINK: ::c_int = 67; /* Link has been severed */ +pub const EADV: ::c_int = 68; /* Advertise error */ +pub const ESRMNT: ::c_int = 69; /* Srmount error */ +pub const ECOMM: ::c_int = 70; /* Communication error on send */ +pub const EPROTO: ::c_int = 71; /* Protocol error */ +pub const EMULTIHOP: ::c_int = 72; /* Multihop attempted */ +pub const EDOTDOT: ::c_int = 73; /* RFS specific error */ +pub const EBADMSG: ::c_int = 74; /* Not a data message */ +pub const EOVERFLOW: ::c_int = 75; /* Value too large for defined data type */ +pub const ENOTUNIQ: ::c_int = 76; /* Name not unique on network */ +pub const EBADFD: ::c_int = 77; /* File descriptor in bad state */ +pub const EREMCHG: ::c_int = 78; /* Remote address changed */ +pub const ELIBACC: ::c_int = 79; /* Can not access a needed shared library */ +pub const ELIBBAD: ::c_int = 80; /* Accessing a corrupted shared library */ +pub const ELIBSCN: ::c_int = 81; /* .lib section in a.out corrupted */ +/* Attempting to link in too many shared libraries */ +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; /* Cannot exec a shared library directly */ +pub const EILSEQ: ::c_int = 84; /* Illegal byte sequence */ +/* Interrupted system call should be restarted */ +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; /* Streams pipe error */ +pub const EUSERS: ::c_int = 87; /* Too many users */ +pub const ENOTSOCK: ::c_int = 88; /* Socket operation on non-socket */ +pub const EDESTADDRREQ: ::c_int = 89; /* Destination address required */ +pub const EMSGSIZE: ::c_int = 90; /* Message too long */ +pub const EPROTOTYPE: ::c_int = 91; /* Protocol wrong type for socket */ +pub const ENOPROTOOPT: ::c_int = 92; /* Protocol not available */ +pub const EPROTONOSUPPORT: ::c_int = 93; /* Protocol not supported */ +pub const ESOCKTNOSUPPORT: ::c_int = 94; /* Socket type not supported */ +/* Operation not supported on transport endpoint */ +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; /* Protocol family not supported */ +/* Address family not supported by protocol */ +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; /* Address already in use */ +pub const EADDRNOTAVAIL: ::c_int = 99; /* Cannot assign requested address */ +pub const ENETDOWN: ::c_int = 100; /* Network is down */ +pub const ENETUNREACH: ::c_int = 101; /* Network is unreachable */ +/* Network dropped connection because of reset */ +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; /* Software caused connection abort */ +pub const ECONNRESET: ::c_int = 104; /* Connection reset by peer */ +pub const ENOBUFS: ::c_int = 105; /* No buffer space available */ +pub const EISCONN: ::c_int = 106; /* Transport endpoint is already connected */ +pub const ENOTCONN: ::c_int = 107; /* Transport endpoint is not connected */ +/* Cannot send after transport endpoint shutdown */ +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; /* Too many references: cannot splice */ +pub const ETIMEDOUT: ::c_int = 110; /* Connection timed out */ +pub const ECONNREFUSED: ::c_int = 111; /* Connection refused */ +pub const EHOSTDOWN: ::c_int = 112; /* Host is down */ +pub const EHOSTUNREACH: ::c_int = 113; /* No route to host */ +pub const EALREADY: ::c_int = 114; /* Operation already in progress */ +pub const EINPROGRESS: ::c_int = 115; /* Operation now in progress */ +pub const ESTALE: ::c_int = 116; /* Stale NFS file handle */ +pub const EUCLEAN: ::c_int = 117; /* Structure needs cleaning */ +pub const ENOTNAM: ::c_int = 118; /* Not a XENIX named type file */ +pub const ENAVAIL: ::c_int = 119; /* No XENIX semaphores available */ +pub const EISNAM: ::c_int = 120; /* Is a named type file */ +pub const EREMOTEIO: ::c_int = 121; /* Remote I/O error */ +pub const EDQUOT: ::c_int = 122; /* Quota exceeded */ +pub const ENOMEDIUM: ::c_int = 123; /* No medium found */ +pub const EMEDIUMTYPE: ::c_int = 124; /* Wrong medium type */ +pub const ECANCELED: ::c_int = 125; /* Operation Canceled */ +pub const ENOKEY: ::c_int = 126; /* Required key not available */ +pub const EKEYEXPIRED: ::c_int = 127; /* Key has expired */ +pub const EKEYREVOKED: ::c_int = 128; /* Key has been revoked */ +pub const EKEYREJECTED: ::c_int = 129; /* Key was rejected by service */ +pub const EOWNERDEAD: ::c_int = 130; /* Owner died */ +pub const ENOTRECOVERABLE: ::c_int = 131; /* State not recoverable */ + +// fcntl.h +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +// FIXME: relibc { +pub const F_DUPFD_CLOEXEC: ::c_int = ::F_DUPFD; +// } +pub const FD_CLOEXEC: ::c_int = 0x0100_0000; +pub const O_RDONLY: ::c_int = 0x0001_0000; +pub const O_WRONLY: ::c_int = 0x0002_0000; +pub const O_RDWR: ::c_int = 0x0003_0000; +pub const O_ACCMODE: ::c_int = 0x0003_0000; +pub const O_NONBLOCK: ::c_int = 0x0004_0000; +pub const O_APPEND: ::c_int = 0x0008_0000; +pub const O_SHLOCK: ::c_int = 0x0010_0000; +pub const O_EXLOCK: ::c_int = 0x0020_0000; +pub const O_ASYNC: ::c_int = 0x0040_0000; +pub const O_FSYNC: ::c_int = 0x0080_0000; +pub const O_CLOEXEC: ::c_int = 0x0100_0000; +pub const O_CREAT: ::c_int = 0x0200_0000; +pub const O_TRUNC: ::c_int = 0x0400_0000; +pub const O_EXCL: ::c_int = 0x0800_0000; +pub const O_DIRECTORY: ::c_int = 0x1000_0000; +pub const O_PATH: ::c_int = 0x2000_0000; +pub const O_SYMLINK: ::c_int = 0x4000_0000; +// Negative to allow it to be used as int +// FIXME: Fix negative values missing from includes +pub const O_NOFOLLOW: ::c_int = -0x8000_0000; + +// locale.h +pub const LC_ALL: ::c_int = 0; +pub const LC_COLLATE: ::c_int = 1; +pub const LC_CTYPE: ::c_int = 2; +pub const LC_MESSAGES: ::c_int = 3; +pub const LC_MONETARY: ::c_int = 4; +pub const LC_NUMERIC: ::c_int = 5; +pub const LC_TIME: ::c_int = 6; + +// netdb.h +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; +pub const AI_NUMERICSERV: ::c_int = 0x0400; +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_ADDRFAMILY: ::c_int = -9; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; +pub const NI_MAXHOST: ::c_int = 1025; +pub const NI_MAXSERV: ::c_int = 32; +pub const NI_NUMERICHOST: ::c_int = 0x0001; +pub const NI_NUMERICSERV: ::c_int = 0x0002; +pub const NI_NOFQDN: ::c_int = 0x0004; +pub const NI_NAMEREQD: ::c_int = 0x0008; +pub const NI_DGRAM: ::c_int = 0x0010; + +// netinet/in.h +// FIXME: relibc { +pub const IP_TTL: ::c_int = 2; +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +pub const IPV6_MULTICAST_LOOP: ::c_int = 19; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21; +pub const IPV6_V6ONLY: ::c_int = 26; +pub const IP_MULTICAST_IF: ::c_int = 32; +pub const IP_MULTICAST_TTL: ::c_int = 33; +pub const IP_MULTICAST_LOOP: ::c_int = 34; +pub const IP_ADD_MEMBERSHIP: ::c_int = 35; +pub const IP_DROP_MEMBERSHIP: ::c_int = 36; +pub const IPPROTO_RAW: ::c_int = 255; +// } + +// netinet/tcp.h +pub const TCP_NODELAY: ::c_int = 1; +// FIXME: relibc { +pub const TCP_KEEPIDLE: ::c_int = 1; +// } + +// poll.h +pub const POLLIN: ::c_short = 0x001; +pub const POLLPRI: ::c_short = 0x002; +pub const POLLOUT: ::c_short = 0x004; +pub const POLLERR: ::c_short = 0x008; +pub const POLLHUP: ::c_short = 0x010; +pub const POLLNVAL: ::c_short = 0x020; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLRDBAND: ::c_short = 0x080; +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +// pthread.h +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_INITIALIZER: ::pthread_mutex_t = ::pthread_mutex_t { + bytes: [0; _PTHREAD_MUTEX_SIZE], +}; +pub const PTHREAD_COND_INITIALIZER: ::pthread_cond_t = ::pthread_cond_t { + bytes: [0; _PTHREAD_COND_SIZE], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: ::pthread_rwlock_t = ::pthread_rwlock_t { + bytes: [0; _PTHREAD_RWLOCK_SIZE], +}; +pub const PTHREAD_STACK_MIN: ::size_t = 4096; + +// signal.h +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGTRAP: ::c_int = 5; +pub const SIGABRT: ::c_int = 6; +pub const SIGBUS: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGUSR1: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGUSR2: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGCHLD: ::c_int = 17; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGURG: ::c_int = 23; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGIO: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIGSYS: ::c_int = 31; +pub const NSIG: ::c_int = 32; + +pub const SA_NOCLDSTOP: ::c_ulong = 0x00000001; +pub const SA_NOCLDWAIT: ::c_ulong = 0x00000002; +pub const SA_SIGINFO: ::c_ulong = 0x00000004; +pub const SA_RESTORER: ::c_ulong = 0x04000000; +pub const SA_ONSTACK: ::c_ulong = 0x08000000; +pub const SA_RESTART: ::c_ulong = 0x10000000; +pub const SA_NODEFER: ::c_ulong = 0x40000000; +pub const SA_RESETHAND: ::c_ulong = 0x80000000; + +// sys/file.h +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +// sys/epoll.h +pub const EPOLL_CLOEXEC: ::c_int = 0x0100_0000; +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_DEL: ::c_int = 2; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLLIN: ::c_int = 1; +pub const EPOLLPRI: ::c_int = 0; +pub const EPOLLOUT: ::c_int = 2; +pub const EPOLLRDNORM: ::c_int = 0; +pub const EPOLLNVAL: ::c_int = 0; +pub const EPOLLRDBAND: ::c_int = 0; +pub const EPOLLWRNORM: ::c_int = 0; +pub const EPOLLWRBAND: ::c_int = 0; +pub const EPOLLMSG: ::c_int = 0; +pub const EPOLLERR: ::c_int = 0; +pub const EPOLLHUP: ::c_int = 0; +pub const EPOLLRDHUP: ::c_int = 0; +pub const EPOLLEXCLUSIVE: ::c_int = 0; +pub const EPOLLWAKEUP: ::c_int = 0; +pub const EPOLLONESHOT: ::c_int = 0; +pub const EPOLLET: ::c_int = 0; + +// sys/stat.h +pub const S_IFMT: ::c_int = 0o0_170_000; +pub const S_IFDIR: ::c_int = 0o040_000; +pub const S_IFCHR: ::c_int = 0o020_000; +pub const S_IFBLK: ::c_int = 0o060_000; +pub const S_IFREG: ::c_int = 0o100_000; +pub const S_IFIFO: ::c_int = 0o010_000; +pub const S_IFLNK: ::c_int = 0o120_000; +pub const S_IFSOCK: ::c_int = 0o140_000; +pub const S_IRWXU: ::c_int = 0o0_700; +pub const S_IRUSR: ::c_int = 0o0_400; +pub const S_IWUSR: ::c_int = 0o0_200; +pub const S_IXUSR: ::c_int = 0o0_100; +pub const S_IRWXG: ::c_int = 0o0_070; +pub const S_IRGRP: ::c_int = 0o0_040; +pub const S_IWGRP: ::c_int = 0o0_020; +pub const S_IXGRP: ::c_int = 0o0_010; +pub const S_IRWXO: ::c_int = 0o0_007; +pub const S_IROTH: ::c_int = 0o0_004; +pub const S_IWOTH: ::c_int = 0o0_002; +pub const S_IXOTH: ::c_int = 0o0_001; + +// stdlib.h +pub const EXIT_SUCCESS: ::c_int = 0; +pub const EXIT_FAILURE: ::c_int = 1; + +// sys/ioctl.h +// FIXME: relibc { +pub const FIONREAD: ::c_ulong = 0x541B; +pub const FIONBIO: ::c_ulong = 0x5421; +pub const FIOCLEX: ::c_ulong = 0x5451; +// } +pub const TCGETS: ::c_ulong = 0x5401; +pub const TCSETS: ::c_ulong = 0x5402; +pub const TCFLSH: ::c_ulong = 0x540B; +pub const TIOCSCTTY: ::c_ulong = 0x540E; +pub const TIOCGPGRP: ::c_ulong = 0x540F; +pub const TIOCSPGRP: ::c_ulong = 0x5410; +pub const TIOCGWINSZ: ::c_ulong = 0x5413; +pub const TIOCSWINSZ: ::c_ulong = 0x5414; + +// sys/mman.h +pub const PROT_NONE: ::c_int = 0x0000; +pub const PROT_READ: ::c_int = 0x0004; +pub const PROT_WRITE: ::c_int = 0x0002; +pub const PROT_EXEC: ::c_int = 0x0001; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; + +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_FAILED: *mut ::c_void = !0 as _; + +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0004; + +// sys/select.h +pub const FD_SETSIZE: usize = 1024; + +// sys/socket.h +pub const AF_INET: ::c_int = 2; +pub const AF_INET6: ::c_int = 10; +pub const AF_UNIX: ::c_int = 1; +pub const AF_UNSPEC: ::c_int = 0; +pub const PF_INET: ::c_int = 2; +pub const PF_INET6: ::c_int = 10; +pub const PF_UNIX: ::c_int = 1; +pub const PF_UNSPEC: ::c_int = 0; +pub const MSG_CTRUNC: ::c_int = 8; +pub const MSG_DONTROUTE: ::c_int = 4; +pub const MSG_EOR: ::c_int = 128; +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_TRUNC: ::c_int = 32; +pub const MSG_DONTWAIT: ::c_int = 64; +pub const MSG_WAITALL: ::c_int = 256; +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; +pub const SO_DEBUG: ::c_int = 1; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_NONBLOCK: ::c_int = 0o4_000; +pub const SOCK_CLOEXEC: ::c_int = 0o2_000_000; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOL_SOCKET: ::c_int = 1; +pub const SOMAXCONN: ::c_int = 128; + +// sys/termios.h +pub const VEOF: usize = 0; +pub const VEOL: usize = 1; +pub const VEOL2: usize = 2; +pub const VERASE: usize = 3; +pub const VWERASE: usize = 4; +pub const VKILL: usize = 5; +pub const VREPRINT: usize = 6; +pub const VSWTC: usize = 7; +pub const VINTR: usize = 8; +pub const VQUIT: usize = 9; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 12; +pub const VSTOP: usize = 13; +pub const VLNEXT: usize = 14; +pub const VDISCARD: usize = 15; +pub const VMIN: usize = 16; +pub const VTIME: usize = 17; +pub const NCCS: usize = 32; + +pub const IGNBRK: ::tcflag_t = 0o000_001; +pub const BRKINT: ::tcflag_t = 0o000_002; +pub const IGNPAR: ::tcflag_t = 0o000_004; +pub const PARMRK: ::tcflag_t = 0o000_010; +pub const INPCK: ::tcflag_t = 0o000_020; +pub const ISTRIP: ::tcflag_t = 0o000_040; +pub const INLCR: ::tcflag_t = 0o000_100; +pub const IGNCR: ::tcflag_t = 0o000_200; +pub const ICRNL: ::tcflag_t = 0o000_400; +pub const IXON: ::tcflag_t = 0o001_000; +pub const IXOFF: ::tcflag_t = 0o002_000; + +pub const OPOST: ::tcflag_t = 0o000_001; +pub const ONLCR: ::tcflag_t = 0o000_002; +pub const OLCUC: ::tcflag_t = 0o000_004; +pub const OCRNL: ::tcflag_t = 0o000_010; +pub const ONOCR: ::tcflag_t = 0o000_020; +pub const ONLRET: ::tcflag_t = 0o000_040; +pub const OFILL: ::tcflag_t = 0o0000_100; +pub const OFDEL: ::tcflag_t = 0o0000_200; + +pub const B0: speed_t = 0o000_000; +pub const B50: speed_t = 0o000_001; +pub const B75: speed_t = 0o000_002; +pub const B110: speed_t = 0o000_003; +pub const B134: speed_t = 0o000_004; +pub const B150: speed_t = 0o000_005; +pub const B200: speed_t = 0o000_006; +pub const B300: speed_t = 0o000_007; +pub const B600: speed_t = 0o000_010; +pub const B1200: speed_t = 0o000_011; +pub const B1800: speed_t = 0o000_012; +pub const B2400: speed_t = 0o000_013; +pub const B4800: speed_t = 0o000_014; +pub const B9600: speed_t = 0o000_015; +pub const B19200: speed_t = 0o000_016; +pub const B38400: speed_t = 0o000_017; + +pub const B57600: speed_t = 0o0_020; +pub const B115200: speed_t = 0o0_021; +pub const B230400: speed_t = 0o0_022; +pub const B460800: speed_t = 0o0_023; +pub const B500000: speed_t = 0o0_024; +pub const B576000: speed_t = 0o0_025; +pub const B921600: speed_t = 0o0_026; +pub const B1000000: speed_t = 0o0_027; +pub const B1152000: speed_t = 0o0_030; +pub const B1500000: speed_t = 0o0_031; +pub const B2000000: speed_t = 0o0_032; +pub const B2500000: speed_t = 0o0_033; +pub const B3000000: speed_t = 0o0_034; +pub const B3500000: speed_t = 0o0_035; +pub const B4000000: speed_t = 0o0_036; + +pub const CSIZE: ::tcflag_t = 0o001_400; +pub const CS5: ::tcflag_t = 0o000_000; +pub const CS6: ::tcflag_t = 0o000_400; +pub const CS7: ::tcflag_t = 0o001_000; +pub const CS8: ::tcflag_t = 0o001_400; + +pub const CSTOPB: ::tcflag_t = 0o002_000; +pub const CREAD: ::tcflag_t = 0o004_000; +pub const PARENB: ::tcflag_t = 0o010_000; +pub const PARODD: ::tcflag_t = 0o020_000; +pub const HUPCL: ::tcflag_t = 0o040_000; + +pub const CLOCAL: ::tcflag_t = 0o0100000; + +pub const ISIG: ::tcflag_t = 0x0000_0080; +pub const ICANON: ::tcflag_t = 0x0000_0100; +pub const ECHO: ::tcflag_t = 0x0000_0008; +pub const ECHOE: ::tcflag_t = 0x0000_0002; +pub const ECHOK: ::tcflag_t = 0x0000_0004; +pub const ECHONL: ::tcflag_t = 0x0000_0010; +pub const NOFLSH: ::tcflag_t = 0x8000_0000; +pub const TOSTOP: ::tcflag_t = 0x0040_0000; +pub const IEXTEN: ::tcflag_t = 0x0000_0400; + +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; + +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +// sys/wait.h +pub const WNOHANG: ::c_int = 1; +pub const WUNTRACED: ::c_int = 2; + +pub const WSTOPPED: ::c_int = 2; +pub const WEXITED: ::c_int = 4; +pub const WCONTINUED: ::c_int = 8; +pub const WNOWAIT: ::c_int = 0x0100_0000; + +pub const __WNOTHREAD: ::c_int = 0x2000_0000; +pub const __WALL: ::c_int = 0x4000_0000; +#[allow(overflowing_literals)] +pub const __WCLONE: ::c_int = 0x8000_0000; + +// time.h +pub const CLOCK_REALTIME: ::c_int = 1; +pub const CLOCK_MONOTONIC: ::c_int = 4; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCKS_PER_SEC: ::clock_t = 1_000_000; + +// unistd.h +// POSIX.1 { +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +// ... +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = 30; +// ... +pub const _SC_RE_DUP_MAX: ::c_int = 44; +// ... +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +// ... +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +// ... +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +// } POSIX.1 + +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; + +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +// wait.h +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0x7f + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0x7f) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } +} + +extern "C" { + // errno.h + pub fn __errno_location() -> *mut ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + // unistd.h + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + + // grp.h + pub fn getgrent() -> *mut ::group; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + + // malloc.h + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + + // netdb.h + pub fn getnameinfo( + addr: *const ::sockaddr, + addrlen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + // pthread.h + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn pthread_create( + tid: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + start: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + arg: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + + //pty.h + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::c_int; + + // pwd.h + pub fn getpwent() -> *mut passwd; + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + + // signal.h + pub fn pthread_sigmask( + how: ::c_int, + set: *const ::sigset_t, + oldset: *mut ::sigset_t, + ) -> ::c_int; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sigtimedwait( + set: *const sigset_t, + sig: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + + // stdlib.h + pub fn getsubopt( + optionp: *mut *mut c_char, + tokens: *const *mut c_char, + valuep: *mut *mut c_char, + ) -> ::c_int; + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + // string.h + pub fn explicit_bzero(p: *mut ::c_void, len: ::size_t); + pub fn strlcat(dst: *mut ::c_char, src: *const ::c_char, siz: ::size_t) -> ::size_t; + pub fn strlcpy(dst: *mut ::c_char, src: *const ::c_char, siz: ::size_t) -> ::size_t; + + // sys/epoll.h + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + + // sys/ioctl.h + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + + // sys/mman.h + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + // sys/resource.h + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + // sys/socket.h + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + + // sys/stat.h + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + + // sys/uio.h + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + // sys/utsname.h + pub fn uname(utsname: *mut utsname) -> ::c_int; + + // time.h + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + + // utmp.h + pub fn login_tty(fd: ::c_int) -> ::c_int; +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sockaddr_un {} + + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_align == self.__ss_align + && self + .__ss_padding + .iter() + .zip(other.__ss_padding.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_padding", &self.__ss_padding) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_padding.hash(state); + self.__ss_align.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + && self + .domainname + .iter() + .zip(other.domainname.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for utsname {} + + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + // FIXME: .field("domainname", &self.domainname) + .finish() + } + } + + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + self.domainname.hash(state); + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/compat.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/compat.rs new file mode 100644 index 00000000..cbf955a3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/compat.rs @@ -0,0 +1,220 @@ +// Common functions that are unfortunately missing on illumos and +// Solaris, but often needed by other crates. + +use core::cmp::min; +use unix::solarish::*; + +const PTEM: &[u8] = b"ptem\0"; +const LDTERM: &[u8] = b"ldterm\0"; + +pub unsafe fn cfmakeraw(termios: *mut ::termios) { + (*termios).c_iflag &= + !(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + (*termios).c_oflag &= !OPOST; + (*termios).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + (*termios).c_cflag &= !(CSIZE | PARENB); + (*termios).c_cflag |= CS8; + + // By default, most software expects a pending read to block until at + // least one byte becomes available. As per termio(7I), this requires + // setting the MIN and TIME parameters appropriately. + // + // As a somewhat unfortunate artefact of history, the MIN and TIME slots + // in the control character array overlap with the EOF and EOL slots used + // for canonical mode processing. Because the EOF character needs to be + // the ASCII EOT value (aka Control-D), it has the byte value 4. When + // switching to raw mode, this is interpreted as a MIN value of 4; i.e., + // reads will block until at least four bytes have been input. + // + // Other platforms with a distinct MIN slot like Linux and FreeBSD appear + // to default to a MIN value of 1, so we'll force that value here: + (*termios).c_cc[VMIN] = 1; + (*termios).c_cc[VTIME] = 0; +} + +pub unsafe fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int { + // Neither of these functions on illumos or Solaris actually ever + // return an error + ::cfsetispeed(termios, speed); + ::cfsetospeed(termios, speed); + 0 +} + +unsafe fn bail(fdm: ::c_int, fds: ::c_int) -> ::c_int { + let e = *___errno(); + if fds >= 0 { + ::close(fds); + } + if fdm >= 0 { + ::close(fdm); + } + *___errno() = e; + return -1; +} + +pub unsafe fn openpty( + amain: *mut ::c_int, + asubord: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, +) -> ::c_int { + // Open the main pseudo-terminal device, making sure not to set it as the + // controlling terminal for this process: + let fdm = ::posix_openpt(O_RDWR | O_NOCTTY); + if fdm < 0 { + return -1; + } + + // Set permissions and ownership on the subordinate device and unlock it: + if ::grantpt(fdm) < 0 || ::unlockpt(fdm) < 0 { + return bail(fdm, -1); + } + + // Get the path name of the subordinate device: + let subordpath = ::ptsname(fdm); + if subordpath.is_null() { + return bail(fdm, -1); + } + + // Open the subordinate device without setting it as the controlling + // terminal for this process: + let fds = ::open(subordpath, O_RDWR | O_NOCTTY); + if fds < 0 { + return bail(fdm, -1); + } + + // Check if the STREAMS modules are already pushed: + let setup = ::ioctl(fds, I_FIND, LDTERM.as_ptr()); + if setup < 0 { + return bail(fdm, fds); + } else if setup == 0 { + // The line discipline is not present, so push the appropriate STREAMS + // modules for the subordinate device: + if ::ioctl(fds, I_PUSH, PTEM.as_ptr()) < 0 || ::ioctl(fds, I_PUSH, LDTERM.as_ptr()) < 0 { + return bail(fdm, fds); + } + } + + // If provided, set the terminal parameters: + if !termp.is_null() && ::tcsetattr(fds, TCSAFLUSH, termp) != 0 { + return bail(fdm, fds); + } + + // If provided, set the window size: + if !winp.is_null() && ::ioctl(fds, TIOCSWINSZ, winp) < 0 { + return bail(fdm, fds); + } + + // If the caller wants the name of the subordinate device, copy it out. + // + // Note that this is a terrible interface: there appears to be no standard + // upper bound on the copy length for this pointer. Nobody should pass + // anything but NULL here, preferring instead to use ptsname(3C) directly. + if !name.is_null() { + ::strcpy(name, subordpath); + } + + *amain = fdm; + *asubord = fds; + 0 +} + +pub unsafe fn forkpty( + amain: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, +) -> ::pid_t { + let mut fds = -1; + + if openpty(amain, &mut fds, name, termp, winp) != 0 { + return -1; + } + + let pid = ::fork(); + if pid < 0 { + return bail(*amain, fds); + } else if pid > 0 { + // In the parent process, we close the subordinate device and return the + // process ID of the new child: + ::close(fds); + return pid; + } + + // The rest of this function executes in the child process. + + // Close the main side of the pseudo-terminal pair: + ::close(*amain); + + // Use TIOCSCTTY to set the subordinate device as our controlling + // terminal. This will fail (with ENOTTY) if we are not the leader in + // our own session, so we call setsid() first. Finally, arrange for + // the pseudo-terminal to occupy the standard I/O descriptors. + if ::setsid() < 0 + || ::ioctl(fds, TIOCSCTTY, 0) < 0 + || ::dup2(fds, 0) < 0 + || ::dup2(fds, 1) < 0 + || ::dup2(fds, 2) < 0 + { + // At this stage there are no particularly good ways to handle failure. + // Exit as abruptly as possible, using _exit() to avoid messing with any + // state still shared with the parent process. + ::_exit(EXIT_FAILURE); + } + // Close the inherited descriptor, taking care to avoid closing the standard + // descriptors by mistake: + if fds > 2 { + ::close(fds); + } + + 0 +} + +pub unsafe fn getpwent_r( + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, +) -> ::c_int { + let old_errno = *::___errno(); + *::___errno() = 0; + *result = native_getpwent_r( + pwd, + buf, + min(buflen, ::c_int::max_value() as ::size_t) as ::c_int, + ); + + let ret = if (*result).is_null() { + *::___errno() + } else { + 0 + }; + *::___errno() = old_errno; + + ret +} + +pub unsafe fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, +) -> ::c_int { + let old_errno = *::___errno(); + *::___errno() = 0; + *result = native_getgrent_r( + grp, + buf, + min(buflen, ::c_int::max_value() as ::size_t) as ::c_int, + ); + + let ret = if (*result).is_null() { + *::___errno() + } else { + 0 + }; + *::___errno() = old_errno; + + ret +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/illumos.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/illumos.rs new file mode 100644 index 00000000..404f013d --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/illumos.rs @@ -0,0 +1,88 @@ +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_amp: *mut ::c_void, + pub shm_lkcnt: ::c_ushort, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_cnattch: ::c_ulong, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_pad4: [i64; 4], + } + + pub struct fil_info { + pub fi_flags: ::c_int, + pub fi_pos: ::c_int, + pub fi_name: [::c_char; ::FILNAME_MAX as usize], + } +} + +pub const AF_LOCAL: ::c_int = 1; // AF_UNIX +pub const AF_FILE: ::c_int = 1; // AF_UNIX + +pub const EFD_SEMAPHORE: ::c_int = 0x1; +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const TCP_KEEPIDLE: ::c_int = 34; +pub const TCP_KEEPCNT: ::c_int = 35; +pub const TCP_KEEPINTVL: ::c_int = 36; +pub const TCP_CONGESTION: ::c_int = 37; + +// These constants are correct for 64-bit programs or 32-bit programs that are +// not using large-file mode. If Rust ever supports anything other than 64-bit +// compilation on illumos, this may require adjustment: +pub const F_OFD_GETLK: ::c_int = 47; +pub const F_OFD_SETLK: ::c_int = 48; +pub const F_OFD_SETLKW: ::c_int = 49; +pub const F_FLOCK: ::c_int = 53; +pub const F_FLOCKW: ::c_int = 54; + +pub const F_DUPFD_CLOEXEC: ::c_int = 37; +pub const F_DUP2FD_CLOEXEC: ::c_int = 36; + +pub const FIL_ATTACH: ::c_int = 0x1; +pub const FIL_DETACH: ::c_int = 0x2; +pub const FIL_LIST: ::c_int = 0x3; +pub const FILNAME_MAX: ::c_int = 32; +pub const FILF_PROG: ::c_int = 0x1; +pub const FILF_AUTO: ::c_int = 0x2; +pub const FILF_BYPASS: ::c_int = 0x4; +pub const SOL_FILTER: ::c_int = 0xfffc; + +pub const MADV_PURGE: ::c_int = 9; + +pub const B1000000: ::speed_t = 24; +pub const B1152000: ::speed_t = 25; +pub const B1500000: ::speed_t = 26; +pub const B2000000: ::speed_t = 27; +pub const B2500000: ::speed_t = 28; +pub const B3000000: ::speed_t = 29; +pub const B3500000: ::speed_t = 30; +pub const B4000000: ::speed_t = 31; + +// sys/systeminfo.h +pub const SI_ADDRESS_WIDTH: ::c_int = 520; + +extern "C" { + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn mincore(addr: ::caddr_t, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + + pub fn pset_bind_lwp( + pset: ::psetid_t, + id: ::id_t, + pid: ::pid_t, + opset: *mut ::psetid_t, + ) -> ::c_int; + pub fn pset_getloadavg(pset: ::psetid_t, load: *mut ::c_double, num: ::c_int) -> ::c_int; + + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn getpagesizes2(pagesize: *mut ::size_t, nelem: ::c_int) -> ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/mod.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/mod.rs new file mode 100644 index 00000000..c68cfba3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/mod.rs @@ -0,0 +1,3309 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type caddr_t = *mut ::c_char; + +pub type clockid_t = ::c_int; +pub type blkcnt_t = ::c_long; +pub type clock_t = ::c_long; +pub type daddr_t = ::c_long; +pub type dev_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type key_t = ::c_int; +pub type major_t = ::c_uint; +pub type minor_t = ::c_uint; +pub type mode_t = ::c_uint; +pub type nlink_t = ::c_uint; +pub type rlim_t = ::c_ulong; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type time_t = ::c_long; +pub type timer_t = ::c_int; +pub type wchar_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type projid_t = ::c_int; +pub type zoneid_t = ::c_int; +pub type psetid_t = ::c_int; +pub type processorid_t = ::c_int; +pub type chipid_t = ::c_int; +pub type ctid_t = ::id_t; + +pub type suseconds_t = ::c_long; +pub type off_t = ::c_long; +pub type useconds_t = ::c_uint; +pub type socklen_t = ::c_uint; +pub type sa_family_t = u16; +pub type pthread_t = ::c_uint; +pub type pthread_key_t = ::c_uint; +pub type thread_t = ::c_uint; +pub type blksize_t = ::c_int; +pub type nl_item = ::c_int; +pub type mqd_t = *mut ::c_void; +pub type id_t = ::c_int; +pub type idtype_t = ::c_uint; +pub type shmatt_t = ::c_ulong; + +pub type lgrp_rsrc_t = ::c_int; +pub type lgrp_affinity_t = ::c_int; +pub type lgrp_id_t = ::id_t; +pub type lgrp_mem_size_t = ::c_longlong; +pub type lgrp_cookie_t = ::uintptr_t; +pub type lgrp_content_t = ::c_uint; +pub type lgrp_lat_between_t = ::c_uint; +pub type lgrp_mem_size_flag_t = ::c_uint; +pub type lgrp_view_t = ::c_uint; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum ucred_t {} +impl ::Copy for ucred_t {} +impl ::Clone for ucred_t { + fn clone(&self) -> ucred_t { + *self + } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_sourceaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ipc_perm { + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub seq: ::c_uint, + pub key: ::key_t, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8] + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + pub __sin6_src_id: u32 + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_age: *mut ::c_char, + pub pw_comment: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut ::c_char, + pub ifa_flags: ::c_ulong, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_dstaddr: *mut ::sockaddr, + pub ifa_data: *mut ::c_void + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct pthread_attr_t { + __pthread_attrp: *mut ::c_void + } + + pub struct pthread_mutex_t { + __pthread_mutex_flag1: u16, + __pthread_mutex_flag2: u8, + __pthread_mutex_ceiling: u8, + __pthread_mutex_type: u16, + __pthread_mutex_magic: u16, + __pthread_mutex_lock: u64, + __pthread_mutex_data: u64 + } + + pub struct pthread_mutexattr_t { + __pthread_mutexattrp: *mut ::c_void + } + + pub struct pthread_cond_t { + __pthread_cond_flag: [u8; 4], + __pthread_cond_type: u16, + __pthread_cond_magic: u16, + __pthread_cond_data: u64 + } + + pub struct pthread_condattr_t { + __pthread_condattrp: *mut ::c_void, + } + + pub struct pthread_rwlock_t { + __pthread_rwlock_readers: i32, + __pthread_rwlock_type: u16, + __pthread_rwlock_magic: u16, + __pthread_rwlock_mutex: ::pthread_mutex_t, + __pthread_rwlock_readercv: ::pthread_cond_t, + __pthread_rwlock_writercv: ::pthread_cond_t + } + + pub struct pthread_rwlockattr_t { + __pthread_rwlockattrp: *mut ::c_void, + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_name: [::c_char; 3] + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + __unused1: *mut ::c_void, + __unused2: ::c_int, + __unused3: ::c_int, + __unused4: ::c_int, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + __unused9: *mut ::c_void, + __unused10: *mut ::c_void, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + #[cfg(target_arch = "sparc64")] + __sparcv9_pad: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct sigset_t { + bits: [u32; 4], + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_basetype: [::c_char; 16], + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_fstr: [::c_char; 32] + } + + pub struct sendfilevec_t { + pub sfv_fd: ::c_int, + pub sfv_flag: ::c_uint, + pub sfv_off: ::off_t, + pub sfv_len: ::size_t, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + sched_pad: [::c_int; 8] + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __unused: [::c_char; 16] + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS] + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct sem_t { + pub sem_count: u32, + pub sem_type: u16, + pub sem_magic: u16, + pub sem_pad1: [u64; 3], + pub sem_pad2: [u64; 2] + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_sysid: ::c_int, + pub l_pid: ::pid_t, + pub l_pad: [::c_long; 4] + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + _pad: [::c_int; 12] + } + + pub struct port_event { + pub portev_events: ::c_int, + pub portev_source: ::c_ushort, + pub portev_pad: ::c_ushort, + pub portev_object: ::uintptr_t, + pub portev_user: *mut ::c_void, + } + + pub struct port_notify { + pub portnfy_port: ::c_int, + pub portnfy_user: *mut ::c_void, + } + + pub struct exit_status { + e_termination: ::c_short, + e_exit: ::c_short, + } + + pub struct utmp { + pub ut_user: [::c_char; 8], + pub ut_id: [::c_char; 4], + pub ut_line: [::c_char; 12], + pub ut_pid: ::c_short, + pub ut_type: ::c_short, + pub ut_exit: exit_status, + pub ut_time: ::time_t, + } + + pub struct timex { + pub modes: u32, + pub offset: i32, + pub freq: i32, + pub maxerror: i32, + pub esterror: i32, + pub status: i32, + pub constant: i32, + pub precision: i32, + pub tolerance: i32, + pub ppsfreq: i32, + pub jitter: i32, + pub shift: i32, + pub stabil: i32, + pub jitcnt: i32, + pub calcnt: i32, + pub errcnt: i32, + pub stbcnt: i32, + } + + pub struct ntptimeval { + pub time: ::timeval, + pub maxerror: i32, + pub esterror: i32, + } + + pub struct mmapobj_result_t { + pub mr_addr: ::caddr_t, + pub mr_msize: ::size_t, + pub mr_fsize: ::size_t, + pub mr_offset: ::size_t, + pub mr_prot: ::c_uint, + pub mr_flags: ::c_uint, + } + + pub struct lgrp_affinity_args { + pub idtype: ::idtype_t, + pub id: ::id_t, + pub lgrp: ::lgrp_id_t, + pub aff: ::lgrp_affinity_t, + } + + pub struct processor_info_t { + pub pi_state: ::c_int, + pub pi_processor_type: [::c_char; PI_TYPELEN as usize], + pub pi_fputypes: [::c_char; PI_FPUTYPE as usize], + pub pi_clock: ::c_int, + } + + pub struct option { + pub name: *const ::c_char, + pub has_arg: ::c_int, + pub flag: *mut ::c_int, + pub val: ::c_int, + } +} + +s_no_extra_traits! { + #[cfg_attr(all( + any(target_arch = "x86", target_arch = "x86_64"), + libc_packedN + ), repr(packed(4)))] + #[cfg_attr(all( + any(target_arch = "x86", target_arch = "x86_64"), + not(libc_packedN) + ), repr(packed))] + pub struct epoll_event { + pub events: u32, + pub u64: u64, + } + + pub struct utmpx { + pub ut_user: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_exit: exit_status, + pub ut_tv: ::timeval, + pub ut_session: ::c_int, + pub ut_pad: [::c_int; _UTX_PADSIZE], + pub ut_syslen: ::c_short, + pub ut_host: [::c_char; _UTX_HOSTSIZE], + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [c_char; 108] + } + + pub struct utsname { + pub sysname: [::c_char; 257], + pub nodename: [::c_char; 257], + pub release: [::c_char; 257], + pub version: [::c_char; 257], + pub machine: [::c_char; 257], + } + + pub struct fd_set { + #[cfg(target_pointer_width = "64")] + fds_bits: [i64; FD_SETSIZE / 64], + #[cfg(target_pointer_width = "32")] + fds_bits: [i32; FD_SETSIZE / 32], + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 240], + } + + #[cfg_attr(all(target_pointer_width = "64", libc_align), repr(align(8)))] + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + #[cfg(target_pointer_width = "64")] + pub si_pad: ::c_int, + + __data_pad: [::c_int; SIGINFO_DATA_SIZE], + } + + pub struct sockaddr_dl { + pub sdl_family: ::c_ushort, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 244], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + pub ss_sp: *mut ::c_void, + pub sigev_notify_attributes: *const ::pthread_attr_t, + __sigev_pad2: ::c_int, + } + + #[cfg(libc_union)] + #[cfg_attr(libc_align, repr(align(16)))] + pub union pad128_t { + // pub _q in this structure would be a "long double", of 16 bytes + pub _l: [i32; 4], + } + + #[cfg(libc_union)] + #[cfg_attr(libc_align, repr(align(16)))] + pub union upad128_t { + // pub _q in this structure would be a "long double", of 16 bytes + pub _l: [u32; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_user == other.ut_user + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_syslen == other.ut_syslen + && self.ut_pad == other.ut_pad + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_user", &self.ut_user) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + .field("ut_pid", &self.ut_pid) + .field("ut_type", &self.ut_type) + .field("ut_exit", &self.ut_exit) + .field("ut_tv", &self.ut_tv) + .field("ut_session", &self.ut_session) + .field("ut_pad", &self.ut_pad) + .field("ut_syslen", &self.ut_syslen) + .field("ut_host", &&self.ut_host[..]) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_user.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_syslen.hash(state); + self.ut_pad.hash(state); + } + } + + impl PartialEq for epoll_event { + fn eq(&self, other: &epoll_event) -> bool { + self.events == other.events + && self.u64 == other.u64 + } + } + impl Eq for epoll_event {} + impl ::fmt::Debug for epoll_event { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let events = self.events; + let u64 = self.u64; + f.debug_struct("epoll_event") + .field("events", &events) + .field("u64", &u64) + .finish() + } + } + impl ::hash::Hash for epoll_event { + fn hash(&self, state: &mut H) { + let events = self.events; + let u64 = self.u64; + events.hash(state); + u64.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for utsname {} + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for fd_set { + fn eq(&self, other: &fd_set) -> bool { + self.fds_bits + .iter() + .zip(other.fds_bits.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for fd_set {} + impl ::fmt::Debug for fd_set { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fd_set") + // FIXME: .field("fds_bits", &self.fds_bits) + .finish() + } + } + impl ::hash::Hash for fd_set { + fn hash(&self, state: &mut H) { + self.fds_bits.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl siginfo_t { + /// The siginfo_t will have differing contents based on the delivered signal. Based on + /// `si_signo`, this determines how many of the `c_int` pad fields contain valid data + /// exposed by the C unions. + /// + /// It is not yet exhausitive for the OS-defined types, and defaults to assuming the + /// entire data pad area is "valid" for otherwise unrecognized signal numbers. + fn data_field_count(&self) -> usize { + match self.si_signo { + ::SIGSEGV | ::SIGBUS | ::SIGILL | ::SIGTRAP | ::SIGFPE => { + ::mem::size_of::() / ::mem::size_of::<::c_int>() + } + ::SIGCLD => ::mem::size_of::() / ::mem::size_of::<::c_int>(), + ::SIGHUP + | ::SIGINT + | ::SIGQUIT + | ::SIGABRT + | ::SIGSYS + | ::SIGPIPE + | ::SIGALRM + | ::SIGTERM + | ::SIGUSR1 + | ::SIGUSR2 + | ::SIGPWR + | ::SIGWINCH + | ::SIGURG => ::mem::size_of::() / ::mem::size_of::<::c_int>(), + _ => SIGINFO_DATA_SIZE, + } + } + } + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + if self.si_signo == other.si_signo + && self.si_code == other.si_code + && self.si_errno == other.si_errno { + // FIXME: The `si_pad` field in the 64-bit version of the struct is ignored + // (for now) when doing comparisons. + + let field_count = self.data_field_count(); + self.__data_pad[..field_count] + .iter() + .zip(other.__data_pad[..field_count].iter()) + .all(|(a, b)| a == b) + } else { + false + } + } + } + impl Eq for siginfo_t {} + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) + // FIXME: .field("__pad", &self.__pad) + .finish() + } + } + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.hash(state); + + // FIXME: The `si_pad` field in the 64-bit version of the struct is ignored + // (for now) when doing hashing. + + let field_count = self.data_field_count(); + self.__data_pad[..field_count].hash(state) + } + } + + impl PartialEq for sockaddr_dl { + fn eq(&self, other: &sockaddr_dl) -> bool { + self.sdl_family == other.sdl_family + && self.sdl_index == other.sdl_index + && self.sdl_type == other.sdl_type + && self.sdl_nlen == other.sdl_nlen + && self.sdl_alen == other.sdl_alen + && self.sdl_slen == other.sdl_slen + && self + .sdl_data + .iter() + .zip(other.sdl_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_dl {} + impl ::fmt::Debug for sockaddr_dl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_dl") + .field("sdl_family", &self.sdl_family) + .field("sdl_index", &self.sdl_index) + .field("sdl_type", &self.sdl_type) + .field("sdl_nlen", &self.sdl_nlen) + .field("sdl_alen", &self.sdl_alen) + .field("sdl_slen", &self.sdl_slen) + // FIXME: .field("sdl_data", &self.sdl_data) + .finish() + } + } + impl ::hash::Hash for sockaddr_dl { + fn hash(&self, state: &mut H) { + self.sdl_family.hash(state); + self.sdl_index.hash(state); + self.sdl_type.hash(state); + self.sdl_nlen.hash(state); + self.sdl_alen.hash(state); + self.sdl_slen.hash(state); + self.sdl_data.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_notify == other.sigev_notify + && self.sigev_signo == other.sigev_signo + && self.sigev_value == other.sigev_value + && self.ss_sp == other.ss_sp + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_notify", &self.sigev_notify) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_value", &self.sigev_value) + .field("ss_sp", &self.ss_sp) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_notify.hash(state); + self.sigev_signo.hash(state); + self.sigev_value.hash(state); + self.ss_sp.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for pad128_t { + fn eq(&self, other: &pad128_t) -> bool { + unsafe { + // FIXME: self._q == other._q || + self._l == other._l + } + } + } + #[cfg(libc_union)] + impl Eq for pad128_t {} + #[cfg(libc_union)] + impl ::fmt::Debug for pad128_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("pad128_t") + // FIXME: .field("_q", &{self._q}) + .field("_l", &{self._l}) + .finish() + } + } + } + #[cfg(libc_union)] + impl ::hash::Hash for pad128_t { + fn hash(&self, state: &mut H) { + unsafe { + // FIXME: state.write_i64(self._q as i64); + self._l.hash(state); + } + } + } + #[cfg(libc_union)] + impl PartialEq for upad128_t { + fn eq(&self, other: &upad128_t) -> bool { + unsafe { + // FIXME: self._q == other._q || + self._l == other._l + } + } + } + #[cfg(libc_union)] + impl Eq for upad128_t {} + #[cfg(libc_union)] + impl ::fmt::Debug for upad128_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("upad128_t") + // FIXME: .field("_q", &{self._q}) + .field("_l", &{self._l}) + .finish() + } + } + } + #[cfg(libc_union)] + impl ::hash::Hash for upad128_t { + fn hash(&self, state: &mut H) { + unsafe { + // FIXME: state.write_i64(self._q as i64); + self._l.hash(state); + } + } + } + } +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + const SIGINFO_DATA_SIZE: usize = 60; + } else { + const SIGINFO_DATA_SIZE: usize = 29; + } +} + +#[repr(C)] +struct siginfo_fault { + addr: *mut ::c_void, + trapno: ::c_int, + pc: *mut ::caddr_t, +} +impl ::Copy for siginfo_fault {} +impl ::Clone for siginfo_fault { + fn clone(&self) -> Self { + *self + } +} + +#[repr(C)] +struct siginfo_cldval { + utime: ::clock_t, + status: ::c_int, + stime: ::clock_t, +} +impl ::Copy for siginfo_cldval {} +impl ::Clone for siginfo_cldval { + fn clone(&self) -> Self { + *self + } +} + +#[repr(C)] +struct siginfo_killval { + uid: ::uid_t, + value: ::sigval, + // Pad out to match the SIGCLD value size + _pad: *mut ::c_void, +} +impl ::Copy for siginfo_killval {} +impl ::Clone for siginfo_killval { + fn clone(&self) -> Self { + *self + } +} + +#[repr(C)] +struct siginfo_sigcld { + pid: ::pid_t, + val: siginfo_cldval, + ctid: ::ctid_t, + zoneid: ::zoneid_t, +} +impl ::Copy for siginfo_sigcld {} +impl ::Clone for siginfo_sigcld { + fn clone(&self) -> Self { + *self + } +} + +#[repr(C)] +struct siginfo_kill { + pid: ::pid_t, + val: siginfo_killval, + ctid: ::ctid_t, + zoneid: ::zoneid_t, +} +impl ::Copy for siginfo_kill {} +impl ::Clone for siginfo_kill { + fn clone(&self) -> Self { + *self + } +} + +impl siginfo_t { + unsafe fn sidata(&self) -> T { + *((&self.__data_pad) as *const ::c_int as *const T) + } + pub unsafe fn si_addr(&self) -> *mut ::c_void { + let sifault: siginfo_fault = self.sidata(); + sifault.addr + } + pub unsafe fn si_uid(&self) -> ::uid_t { + let kill: siginfo_kill = self.sidata(); + kill.val.uid + } + pub unsafe fn si_value(&self) -> ::sigval { + let kill: siginfo_kill = self.sidata(); + kill.val.value + } + pub unsafe fn si_pid(&self) -> ::pid_t { + let sigcld: siginfo_sigcld = self.sidata(); + sigcld.pid + } + pub unsafe fn si_status(&self) -> ::c_int { + let sigcld: siginfo_sigcld = self.sidata(); + sigcld.val.status + } + pub unsafe fn si_utime(&self) -> ::c_long { + let sigcld: siginfo_sigcld = self.sidata(); + sigcld.val.utime + } + pub unsafe fn si_stime(&self) -> ::c_long { + let sigcld: siginfo_sigcld = self.sidata(); + sigcld.val.stime + } +} + +pub const LC_CTYPE: ::c_int = 0; +pub const LC_NUMERIC: ::c_int = 1; +pub const LC_TIME: ::c_int = 2; +pub const LC_COLLATE: ::c_int = 3; +pub const LC_MONETARY: ::c_int = 4; +pub const LC_MESSAGES: ::c_int = 5; +pub const LC_ALL: ::c_int = 6; +pub const LC_CTYPE_MASK: ::c_int = 1 << LC_CTYPE; +pub const LC_NUMERIC_MASK: ::c_int = 1 << LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << LC_TIME; +pub const LC_COLLATE_MASK: ::c_int = 1 << LC_COLLATE; +pub const LC_MONETARY_MASK: ::c_int = 1 << LC_MONETARY; +pub const LC_MESSAGES_MASK: ::c_int = 1 << LC_MESSAGES; +pub const LC_ALL_MASK: ::c_int = LC_CTYPE_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK + | LC_COLLATE_MASK + | LC_MONETARY_MASK + | LC_MESSAGES_MASK; + +pub const DAY_1: ::nl_item = 1; +pub const DAY_2: ::nl_item = 2; +pub const DAY_3: ::nl_item = 3; +pub const DAY_4: ::nl_item = 4; +pub const DAY_5: ::nl_item = 5; +pub const DAY_6: ::nl_item = 6; +pub const DAY_7: ::nl_item = 7; + +pub const ABDAY_1: ::nl_item = 8; +pub const ABDAY_2: ::nl_item = 9; +pub const ABDAY_3: ::nl_item = 10; +pub const ABDAY_4: ::nl_item = 11; +pub const ABDAY_5: ::nl_item = 12; +pub const ABDAY_6: ::nl_item = 13; +pub const ABDAY_7: ::nl_item = 14; + +pub const MON_1: ::nl_item = 15; +pub const MON_2: ::nl_item = 16; +pub const MON_3: ::nl_item = 17; +pub const MON_4: ::nl_item = 18; +pub const MON_5: ::nl_item = 19; +pub const MON_6: ::nl_item = 20; +pub const MON_7: ::nl_item = 21; +pub const MON_8: ::nl_item = 22; +pub const MON_9: ::nl_item = 23; +pub const MON_10: ::nl_item = 24; +pub const MON_11: ::nl_item = 25; +pub const MON_12: ::nl_item = 26; + +pub const ABMON_1: ::nl_item = 27; +pub const ABMON_2: ::nl_item = 28; +pub const ABMON_3: ::nl_item = 29; +pub const ABMON_4: ::nl_item = 30; +pub const ABMON_5: ::nl_item = 31; +pub const ABMON_6: ::nl_item = 32; +pub const ABMON_7: ::nl_item = 33; +pub const ABMON_8: ::nl_item = 34; +pub const ABMON_9: ::nl_item = 35; +pub const ABMON_10: ::nl_item = 36; +pub const ABMON_11: ::nl_item = 37; +pub const ABMON_12: ::nl_item = 38; + +pub const RADIXCHAR: ::nl_item = 39; +pub const THOUSEP: ::nl_item = 40; +pub const YESSTR: ::nl_item = 41; +pub const NOSTR: ::nl_item = 42; +pub const CRNCYSTR: ::nl_item = 43; + +pub const D_T_FMT: ::nl_item = 44; +pub const D_FMT: ::nl_item = 45; +pub const T_FMT: ::nl_item = 46; +pub const AM_STR: ::nl_item = 47; +pub const PM_STR: ::nl_item = 48; + +pub const CODESET: ::nl_item = 49; +pub const T_FMT_AMPM: ::nl_item = 50; +pub const ERA: ::nl_item = 51; +pub const ERA_D_FMT: ::nl_item = 52; +pub const ERA_D_T_FMT: ::nl_item = 53; +pub const ERA_T_FMT: ::nl_item = 54; +pub const ALT_DIGITS: ::nl_item = 55; +pub const YESEXPR: ::nl_item = 56; +pub const NOEXPR: ::nl_item = 57; +pub const _DATE_FMT: ::nl_item = 58; +pub const MAXSTRMSG: ::nl_item = 58; + +pub const PATH_MAX: ::c_int = 1024; + +pub const SA_ONSTACK: ::c_int = 0x00000001; +pub const SA_RESETHAND: ::c_int = 0x00000002; +pub const SA_RESTART: ::c_int = 0x00000004; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NODEFER: ::c_int = 0x00000010; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +pub const SA_NOCLDSTOP: ::c_int = 0x00020000; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const FIOCLEX: ::c_int = 0x20006601; +pub const FIONCLEX: ::c_int = 0x20006602; +pub const FIONREAD: ::c_int = 0x4004667f; +pub const FIONBIO: ::c_int = 0x8004667e; +pub const FIOASYNC: ::c_int = 0x8004667d; +pub const FIOSETOWN: ::c_int = 0x8004667c; +pub const FIOGETOWN: ::c_int = 0x4004667b; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGCLD: ::c_int = ::SIGCHLD; +pub const SIGBUS: ::c_int = 10; +pub const SIGINFO: ::c_int = 41; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_SIGNAL: ::c_int = 2; +pub const SIGEV_THREAD: ::c_int = 3; + +pub const CLD_EXITED: ::c_int = 1; +pub const CLD_KILLED: ::c_int = 2; +pub const CLD_DUMPED: ::c_int = 3; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const IP_RECVDSTADDR: ::c_int = 0x7; +pub const IP_SEC_OPT: ::c_int = 0x22; + +pub const IPV6_UNICAST_HOPS: ::c_int = 0x5; +pub const IPV6_MULTICAST_IF: ::c_int = 0x6; +pub const IPV6_MULTICAST_HOPS: ::c_int = 0x7; +pub const IPV6_MULTICAST_LOOP: ::c_int = 0x8; +pub const IPV6_RECVPKTINFO: ::c_int = 0x12; +pub const IPV6_SEC_OPT: ::c_int = 0x22; +pub const IPV6_V6ONLY: ::c_int = 0x27; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const FD_SETSIZE: usize = 65536; + } else { + pub const FD_SETSIZE: usize = 1024; + } +} + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; + +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const NI_MAXSERV: ::socklen_t = 32; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 32767; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 4; +pub const _IOLBF: ::c_int = 64; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 25; +pub const TMP_MAX: ::c_uint = 17576; + +pub const GRND_NONBLOCK: ::c_uint = 0x0001; +pub const GRND_RANDOM: ::c_uint = 0x0002; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; +pub const O_NDELAY: ::c_int = 0x04; +pub const O_APPEND: ::c_int = 8; +pub const O_DSYNC: ::c_int = 0x40; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_TRUNC: ::c_int = 512; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_SEARCH: ::c_int = 0x200000; +pub const O_EXEC: ::c_int = 0x400000; +pub const O_CLOEXEC: ::c_int = 0x800000; +pub const O_ACCMODE: ::c_int = 0x600003; +pub const O_XATTR: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x1000000; +pub const O_DIRECT: ::c_int = 0x2000000; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +pub const S_IFREG: mode_t = 32768; +pub const S_IFLNK: mode_t = 40960; +pub const S_IFSOCK: mode_t = 49152; +pub const S_IFMT: mode_t = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_GETLK: ::c_int = 14; +pub const F_ALLOCSP: ::c_int = 10; +pub const F_FREESP: ::c_int = 11; +pub const F_BLOCKS: ::c_int = 18; +pub const F_BLKSIZE: ::c_int = 19; +pub const F_SHARE: ::c_int = 40; +pub const F_UNSHARE: ::c_int = 41; +pub const F_ISSTREAM: ::c_int = 13; +pub const F_PRIV: ::c_int = 15; +pub const F_NPRIV: ::c_int = 16; +pub const F_QUOTACTL: ::c_int = 17; +pub const F_GETOWN: ::c_int = 23; +pub const F_SETOWN: ::c_int = 24; +pub const F_REVOKE: ::c_int = 25; +pub const F_HASREMOTELOCKS: ::c_int = 26; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGSYS: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGPWR: ::c_int = 19; +pub const SIGWINCH: ::c_int = 20; +pub const SIGURG: ::c_int = 21; +pub const SIGPOLL: ::c_int = 22; +pub const SIGIO: ::c_int = SIGPOLL; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGCONT: ::c_int = 25; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; + +pub const WNOHANG: ::c_int = 0x40; +pub const WUNTRACED: ::c_int = 0x04; + +pub const WEXITED: ::c_int = 0x01; +pub const WTRAPPED: ::c_int = 0x02; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WCONTINUED: ::c_int = 0x08; +pub const WNOWAIT: ::c_int = 0x80; + +pub const AT_FDCWD: ::c_int = 0xffd19553; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x1000; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x2000; +pub const AT_REMOVEDIR: ::c_int = 0x1; +pub const _AT_TRIGGER: ::c_int = 0x2; +pub const AT_EACCESS: ::c_int = 0x4; + +pub const P_PID: idtype_t = 0; +pub const P_PPID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; +pub const P_SID: idtype_t = 3; +pub const P_CID: idtype_t = 4; +pub const P_UID: idtype_t = 5; +pub const P_GID: idtype_t = 6; +pub const P_ALL: idtype_t = 7; +pub const P_LWPID: idtype_t = 8; +pub const P_TASKID: idtype_t = 9; +pub const P_PROJID: idtype_t = 10; +pub const P_POOLID: idtype_t = 11; +pub const P_ZONEID: idtype_t = 12; +pub const P_CTID: idtype_t = 13; +pub const P_CPUID: idtype_t = 14; +pub const P_PSETID: idtype_t = 15; + +pub const PBIND_NONE: ::processorid_t = -1; +pub const PBIND_QUERY: ::processorid_t = -2; +pub const PBIND_HARD: ::processorid_t = -3; +pub const PBIND_SOFT: ::processorid_t = -4; + +pub const PS_NONE: ::c_int = -1; +pub const PS_QUERY: ::c_int = -2; +pub const PS_MYID: ::c_int = -3; +pub const PS_SOFT: ::c_int = -4; +pub const PS_HARD: ::c_int = -5; +pub const PS_QUERY_TYPE: ::c_int = -6; +pub const PS_SYSTEM: ::c_int = 1; +pub const PS_PRIVATE: ::c_int = 2; + +pub const UTIME_OMIT: c_long = -2; +pub const UTIME_NOW: c_long = -1; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const MAP_FILE: ::c_int = 0; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_NORESERVE: ::c_int = 0x40; +pub const MAP_ANON: ::c_int = 0x0100; +pub const MAP_ANONYMOUS: ::c_int = 0x0100; +pub const MAP_RENAME: ::c_int = 0x20; +pub const MAP_ALIGN: ::c_int = 0x200; +pub const MAP_TEXT: ::c_int = 0x400; +pub const MAP_INITDATA: ::c_int = 0x800; +pub const MAP_32BIT: ::c_int = 0x80; +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const MS_SYNC: ::c_int = 0x0004; +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; + +pub const MMOBJ_PADDING: ::c_uint = 0x10000; +pub const MMOBJ_INTERPRET: ::c_uint = 0x20000; +pub const MR_PADDING: ::c_uint = 0x1; +pub const MR_HDR_ELF: ::c_uint = 0x2; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EDEADLK: ::c_int = 45; +pub const ENOLCK: ::c_int = 46; +pub const ECANCELED: ::c_int = 47; +pub const ENOTSUP: ::c_int = 48; +pub const EDQUOT: ::c_int = 49; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EBFONT: ::c_int = 57; +pub const EOWNERDEAD: ::c_int = 58; +pub const ENOTRECOVERABLE: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const ELOCKUNMAPPED: ::c_int = 72; +pub const ENOTACTIVE: ::c_int = 73; +pub const EMULTIHOP: ::c_int = 74; +pub const EADI: ::c_int = 75; +pub const EBADMSG: ::c_int = 77; +pub const ENAMETOOLONG: ::c_int = 78; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ENOSYS: ::c_int = 89; +pub const ELOOP: ::c_int = 90; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const ENOTEMPTY: ::c_int = 93; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 12; + +pub const NI_NOFQDN: ::c_uint = 0x0001; +pub const NI_NUMERICHOST: ::c_uint = 0x0002; +pub const NI_NAMEREQD: ::c_uint = 0x0004; +pub const NI_NUMERICSERV: ::c_uint = 0x0008; +pub const NI_DGRAM: ::c_uint = 0x0010; +pub const NI_WITHSCOPEID: ::c_uint = 0x0020; +pub const NI_NUMERICSCOPE: ::c_uint = 0x0040; + +pub const F_DUPFD: ::c_int = 0; +pub const F_DUP2FD: ::c_int = 9; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +pub const F_GETXFL: ::c_int = 45; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 32; +pub const GLOB_DOOFFS: ::c_int = 16; +pub const GLOB_ERR: ::c_int = 1; +pub const GLOB_MARK: ::c_int = 2; +pub const GLOB_NOCHECK: ::c_int = 8; +pub const GLOB_NOSORT: ::c_int = 4; +pub const GLOB_NOESCAPE: ::c_int = 64; + +pub const GLOB_NOSPACE: ::c_int = -2; +pub const GLOB_ABORTED: ::c_int = -1; +pub const GLOB_NOMATCH: ::c_int = -3; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLNORM: ::c_short = 0x0040; +pub const POLLRDNORM: ::c_short = 0x0040; +pub const POLLWRNORM: ::c_short = 0x4; /* POLLOUT */ +pub const POLLRDBAND: ::c_short = 0x0080; +pub const POLLWRBAND: ::c_short = 0x0100; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x40; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_PROCESS_PRIVATE: ::c_ushort = 0; +pub const PTHREAD_STACK_MIN: ::size_t = 4096; + +pub const SIGSTKSZ: ::size_t = 8192; + +// https://illumos.org/man/3c/clock_gettime +// https://github.com/illumos/illumos-gate/ +// blob/HEAD/usr/src/lib/libc/amd64/sys/__clock_gettime.s +// clock_gettime(3c) doesn't seem to accept anything other than CLOCK_REALTIME +// or __CLOCK_REALTIME0 +// +// https://github.com/illumos/illumos-gate/ +// blob/HEAD/usr/src/uts/common/sys/time_impl.h +// Confusing! CLOCK_HIGHRES==CLOCK_MONOTONIC==4 +// __CLOCK_REALTIME0==0 is an obsoleted version of CLOCK_REALTIME==3 +pub const CLOCK_REALTIME: ::clockid_t = 3; +pub const CLOCK_MONOTONIC: ::clockid_t = 4; +pub const TIMER_RELTIME: ::c_int = 0; +pub const TIMER_ABSTIME: ::c_int = 1; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_NOFILE: ::c_int = 5; +pub const RLIMIT_VMEM: ::c_int = 6; +pub const RLIMIT_AS: ::c_int = RLIMIT_VMEM; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: rlim_t = 7; +pub const RLIM_INFINITY: rlim_t = 0xfffffffffffffffd; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 5; +pub const MADV_ACCESS_DEFAULT: ::c_int = 6; +pub const MADV_ACCESS_LWP: ::c_int = 7; +pub const MADV_ACCESS_MANY: ::c_int = 8; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NS: ::c_int = 6; +pub const AF_NBS: ::c_int = 7; +pub const AF_ECMA: ::c_int = 8; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_NIT: ::c_int = 17; +pub const AF_802: ::c_int = 18; +pub const AF_OSI: ::c_int = 19; +pub const AF_X25: ::c_int = 20; +pub const AF_OSINET: ::c_int = 21; +pub const AF_GOSIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_ROUTE: ::c_int = 24; +pub const AF_LINK: ::c_int = 25; +pub const AF_INET6: ::c_int = 26; +pub const AF_KEY: ::c_int = 27; +pub const AF_NCA: ::c_int = 28; +pub const AF_POLICY: ::c_int = 29; +pub const AF_INET_OFFLOAD: ::c_int = 30; +pub const AF_TRILL: ::c_int = 31; +pub const AF_PACKET: ::c_int = 32; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_LOCAL: ::c_int = PF_UNIX; +pub const PF_FILE: ::c_int = PF_UNIX; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_IMPLINK: ::c_int = AF_IMPLINK; +pub const PF_PUP: ::c_int = AF_PUP; +pub const PF_CHAOS: ::c_int = AF_CHAOS; +pub const PF_NS: ::c_int = AF_NS; +pub const PF_NBS: ::c_int = AF_NBS; +pub const PF_ECMA: ::c_int = AF_ECMA; +pub const PF_DATAKIT: ::c_int = AF_DATAKIT; +pub const PF_CCITT: ::c_int = AF_CCITT; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_DLI: ::c_int = AF_DLI; +pub const PF_LAT: ::c_int = AF_LAT; +pub const PF_HYLINK: ::c_int = AF_HYLINK; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_NIT: ::c_int = AF_NIT; +pub const PF_802: ::c_int = AF_802; +pub const PF_OSI: ::c_int = AF_OSI; +pub const PF_X25: ::c_int = AF_X25; +pub const PF_OSINET: ::c_int = AF_OSINET; +pub const PF_GOSIP: ::c_int = AF_GOSIP; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_LINK: ::c_int = AF_LINK; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_NCA: ::c_int = AF_NCA; +pub const PF_POLICY: ::c_int = AF_POLICY; +pub const PF_INET_OFFLOAD: ::c_int = AF_INET_OFFLOAD; +pub const PF_TRILL: ::c_int = AF_TRILL; +pub const PF_PACKET: ::c_int = AF_PACKET; + +pub const SOCK_DGRAM: ::c_int = 1; +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 4; +pub const SOCK_RDM: ::c_int = 5; +pub const SOCK_SEQPACKET: ::c_int = 6; +pub const IP_MULTICAST_IF: ::c_int = 16; +pub const IP_MULTICAST_TTL: ::c_int = 17; +pub const IP_MULTICAST_LOOP: ::c_int = 18; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_ADD_MEMBERSHIP: ::c_int = 19; +pub const IP_DROP_MEMBERSHIP: ::c_int = 20; +pub const IPV6_JOIN_GROUP: ::c_int = 9; +pub const IPV6_LEAVE_GROUP: ::c_int = 10; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 23; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 24; +pub const IP_BLOCK_SOURCE: ::c_int = 21; +pub const IP_UNBLOCK_SOURCE: ::c_int = 22; + +// These TCP socket options are common between illumos and Solaris, while higher +// numbers have generally diverged: +pub const TCP_NODELAY: ::c_int = 0x1; +pub const TCP_MAXSEG: ::c_int = 0x2; +pub const TCP_KEEPALIVE: ::c_int = 0x8; +pub const TCP_NOTIFY_THRESHOLD: ::c_int = 0x10; +pub const TCP_ABORT_THRESHOLD: ::c_int = 0x11; +pub const TCP_CONN_NOTIFY_THRESHOLD: ::c_int = 0x12; +pub const TCP_CONN_ABORT_THRESHOLD: ::c_int = 0x13; +pub const TCP_RECVDSTADDR: ::c_int = 0x14; +pub const TCP_INIT_CWND: ::c_int = 0x15; +pub const TCP_KEEPALIVE_THRESHOLD: ::c_int = 0x16; +pub const TCP_KEEPALIVE_ABORT_THRESHOLD: ::c_int = 0x17; +pub const TCP_CORK: ::c_int = 0x18; +pub const TCP_RTO_INITIAL: ::c_int = 0x19; +pub const TCP_RTO_MIN: ::c_int = 0x1a; +pub const TCP_RTO_MAX: ::c_int = 0x1b; +pub const TCP_LINGER2: ::c_int = 0x1c; + +pub const UDP_NAT_T_ENDPOINT: ::c_int = 0x0103; + +pub const SOMAXCONN: ::c_int = 128; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x01; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_PROTOTYPE: ::c_int = 0x1009; +pub const SO_DOMAIN: ::c_int = 0x100c; +pub const SO_TIMESTAMP: ::c_int = 0x1013; + +pub const SCM_RIGHTS: ::c_int = 0x1010; +pub const SCM_UCRED: ::c_int = 0x1012; +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +pub const MSG_OOB: ::c_int = 0x1; +pub const MSG_PEEK: ::c_int = 0x2; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_EOR: ::c_int = 0x8; +pub const MSG_CTRUNC: ::c_int = 0x10; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_DONTWAIT: ::c_int = 0x80; +pub const MSG_NOTIFICATION: ::c_int = 0x100; +pub const MSG_NOSIGNAL: ::c_int = 0x200; +pub const MSG_DUPCTRL: ::c_int = 0x800; +pub const MSG_XPG4_2: ::c_int = 0x8000; +pub const MSG_MAXIOVLEN: ::c_int = 16; + +pub const IF_NAMESIZE: ::size_t = 32; +pub const IFNAMSIZ: ::size_t = 16; + +// https://docs.oracle.com/cd/E23824_01/html/821-1475/if-7p.html +pub const IFF_UP: ::c_int = 0x0000000001; // Address is up +pub const IFF_BROADCAST: ::c_int = 0x0000000002; // Broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x0000000004; // Turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x0000000008; // Loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x0000000010; // Interface is p-to-p +pub const IFF_NOTRAILERS: ::c_int = 0x0000000020; // Avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x0000000040; // Resources allocated +pub const IFF_NOARP: ::c_int = 0x0000000080; // No address res. protocol +pub const IFF_PROMISC: ::c_int = 0x0000000100; // Receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0000000200; // Receive all multicast pkts +pub const IFF_INTELLIGENT: ::c_int = 0x0000000400; // Protocol code on board +pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast + +// Multicast using broadcst. add. +pub const IFF_MULTI_BCAST: ::c_int = 0x0000001000; +pub const IFF_UNNUMBERED: ::c_int = 0x0000002000; // Non-unique address +pub const IFF_DHCPRUNNING: ::c_int = 0x0000004000; // DHCP controls interface +pub const IFF_PRIVATE: ::c_int = 0x0000008000; // Do not advertise +pub const IFF_NOXMIT: ::c_int = 0x0000010000; // Do not transmit pkts + +// No address - just on-link subnet +pub const IFF_NOLOCAL: ::c_int = 0x0000020000; +pub const IFF_DEPRECATED: ::c_int = 0x0000040000; // Address is deprecated +pub const IFF_ADDRCONF: ::c_int = 0x0000080000; // Addr. from stateless addrconf +pub const IFF_ROUTER: ::c_int = 0x0000100000; // Router on interface +pub const IFF_NONUD: ::c_int = 0x0000200000; // No NUD on interface +pub const IFF_ANYCAST: ::c_int = 0x0000400000; // Anycast address +pub const IFF_NORTEXCH: ::c_int = 0x0000800000; // Don't xchange rout. info +pub const IFF_IPV4: ::c_int = 0x0001000000; // IPv4 interface +pub const IFF_IPV6: ::c_int = 0x0002000000; // IPv6 interface +pub const IFF_NOFAILOVER: ::c_int = 0x0008000000; // in.mpathd test address +pub const IFF_FAILED: ::c_int = 0x0010000000; // Interface has failed +pub const IFF_STANDBY: ::c_int = 0x0020000000; // Interface is a hot-spare +pub const IFF_INACTIVE: ::c_int = 0x0040000000; // Functioning but not used +pub const IFF_OFFLINE: ::c_int = 0x0080000000; // Interface is offline + // If CoS marking is supported +pub const IFF_COS_ENABLED: ::c_longlong = 0x0200000000; +pub const IFF_PREFERRED: ::c_longlong = 0x0400000000; // Prefer as source addr. +pub const IFF_TEMPORARY: ::c_longlong = 0x0800000000; // RFC3041 +pub const IFF_FIXEDMTU: ::c_longlong = 0x1000000000; // MTU set with SIOCSLIFMTU +pub const IFF_VIRTUAL: ::c_longlong = 0x2000000000; // Cannot send/receive pkts +pub const IFF_DUPLICATE: ::c_longlong = 0x4000000000; // Local address in use +pub const IFF_IPMP: ::c_longlong = 0x8000000000; // IPMP IP interface + +// sys/ipc.h: +pub const IPC_ALLOC: ::c_int = 0x8000; +pub const IPC_CREAT: ::c_int = 0x200; +pub const IPC_EXCL: ::c_int = 0x400; +pub const IPC_NOWAIT: ::c_int = 0x800; +pub const IPC_PRIVATE: key_t = 0; +pub const IPC_RMID: ::c_int = 10; +pub const IPC_SET: ::c_int = 11; +pub const IPC_SEAT: ::c_int = 12; + +// sys/shm.h +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_SHARE_MMU: ::c_int = 0o40000; +pub const SHM_PAGEABLE: ::c_int = 0o100000; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const F_RDLCK: ::c_short = 1; +pub const F_WRLCK: ::c_short = 2; +pub const F_UNLCK: ::c_short = 3; + +pub const O_SYNC: ::c_int = 16; +pub const O_NONBLOCK: ::c_int = 128; + +pub const IPPROTO_RAW: ::c_int = 255; + +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SYNC_IO: ::c_int = 12; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_SYMLINK_MAX: ::c_int = 18; +pub const _PC_2_SYMLINKS: ::c_int = 19; +pub const _PC_ACL_ENABLED: ::c_int = 20; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 21; +pub const _PC_CASE_BEHAVIOR: ::c_int = 22; +pub const _PC_SATTR_ENABLED: ::c_int = 23; +pub const _PC_SATTR_EXISTS: ::c_int = 24; +pub const _PC_ACCESS_FILTERING: ::c_int = 25; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 26; +pub const _PC_FILESIZEBITS: ::c_int = 67; +pub const _PC_XATTR_ENABLED: ::c_int = 100; +pub const _PC_LAST: ::c_int = 101; +pub const _PC_XATTR_EXISTS: ::c_int = 101; + +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_NGROUPS_MAX: ::c_int = 4; +pub const _SC_OPEN_MAX: ::c_int = 5; +pub const _SC_JOB_CONTROL: ::c_int = 6; +pub const _SC_SAVED_IDS: ::c_int = 7; +pub const _SC_VERSION: ::c_int = 8; +pub const _SC_PASS_MAX: ::c_int = 9; +pub const _SC_LOGNAME_MAX: ::c_int = 10; +pub const _SC_PAGESIZE: ::c_int = 11; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_XOPEN_VERSION: ::c_int = 12; +pub const _SC_NPROCESSORS_CONF: ::c_int = 14; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 15; +pub const _SC_STREAM_MAX: ::c_int = 16; +pub const _SC_TZNAME_MAX: ::c_int = 17; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 18; +pub const _SC_AIO_MAX: ::c_int = 19; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 20; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 21; +pub const _SC_DELAYTIMER_MAX: ::c_int = 22; +pub const _SC_FSYNC: ::c_int = 23; +pub const _SC_MAPPED_FILES: ::c_int = 24; +pub const _SC_MEMLOCK: ::c_int = 25; +pub const _SC_MEMLOCK_RANGE: ::c_int = 26; +pub const _SC_MEMORY_PROTECTION: ::c_int = 27; +pub const _SC_MESSAGE_PASSING: ::c_int = 28; +pub const _SC_MQ_OPEN_MAX: ::c_int = 29; +pub const _SC_MQ_PRIO_MAX: ::c_int = 30; +pub const _SC_PRIORITIZED_IO: ::c_int = 31; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 32; +pub const _SC_REALTIME_SIGNALS: ::c_int = 33; +pub const _SC_RTSIG_MAX: ::c_int = 34; +pub const _SC_SEMAPHORES: ::c_int = 35; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 36; +pub const _SC_SEM_VALUE_MAX: ::c_int = 37; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 38; +pub const _SC_SIGQUEUE_MAX: ::c_int = 39; +pub const _SC_SIGRT_MIN: ::c_int = 40; +pub const _SC_SIGRT_MAX: ::c_int = 41; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 42; +pub const _SC_TIMERS: ::c_int = 43; +pub const _SC_TIMER_MAX: ::c_int = 44; +pub const _SC_2_C_BIND: ::c_int = 45; +pub const _SC_2_C_DEV: ::c_int = 46; +pub const _SC_2_C_VERSION: ::c_int = 47; +pub const _SC_2_FORT_DEV: ::c_int = 48; +pub const _SC_2_FORT_RUN: ::c_int = 49; +pub const _SC_2_LOCALEDEF: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_UPE: ::c_int = 52; +pub const _SC_2_VERSION: ::c_int = 53; +pub const _SC_BC_BASE_MAX: ::c_int = 54; +pub const _SC_BC_DIM_MAX: ::c_int = 55; +pub const _SC_BC_SCALE_MAX: ::c_int = 56; +pub const _SC_BC_STRING_MAX: ::c_int = 57; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 58; +pub const _SC_EXPR_NEST_MAX: ::c_int = 59; +pub const _SC_LINE_MAX: ::c_int = 60; +pub const _SC_RE_DUP_MAX: ::c_int = 61; +pub const _SC_XOPEN_CRYPT: ::c_int = 62; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 63; +pub const _SC_XOPEN_SHM: ::c_int = 64; +pub const _SC_2_CHAR_TERM: ::c_int = 66; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 67; +pub const _SC_ATEXIT_MAX: ::c_int = 76; +pub const _SC_IOV_MAX: ::c_int = 77; +pub const _SC_XOPEN_UNIX: ::c_int = 78; +pub const _SC_T_IOV_MAX: ::c_int = 79; +pub const _SC_PHYS_PAGES: ::c_int = 500; +pub const _SC_AVPHYS_PAGES: ::c_int = 501; +pub const _SC_COHER_BLKSZ: ::c_int = 503; +pub const _SC_SPLIT_CACHE: ::c_int = 504; +pub const _SC_ICACHE_SZ: ::c_int = 505; +pub const _SC_DCACHE_SZ: ::c_int = 506; +pub const _SC_ICACHE_LINESZ: ::c_int = 507; +pub const _SC_DCACHE_LINESZ: ::c_int = 508; +pub const _SC_ICACHE_BLKSZ: ::c_int = 509; +pub const _SC_DCACHE_BLKSZ: ::c_int = 510; +pub const _SC_DCACHE_TBLKSZ: ::c_int = 511; +pub const _SC_ICACHE_ASSOC: ::c_int = 512; +pub const _SC_DCACHE_ASSOC: ::c_int = 513; +pub const _SC_MAXPID: ::c_int = 514; +pub const _SC_STACK_PROT: ::c_int = 515; +pub const _SC_NPROCESSORS_MAX: ::c_int = 516; +pub const _SC_CPUID_MAX: ::c_int = 517; +pub const _SC_EPHID_MAX: ::c_int = 518; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 568; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 569; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 570; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 571; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 572; +pub const _SC_THREAD_STACK_MIN: ::c_int = 573; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 574; +pub const _SC_TTY_NAME_MAX: ::c_int = 575; +pub const _SC_THREADS: ::c_int = 576; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 577; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 578; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 579; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 580; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 581; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 582; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 583; +pub const _SC_XOPEN_LEGACY: ::c_int = 717; +pub const _SC_XOPEN_REALTIME: ::c_int = 718; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 719; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 720; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 721; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 722; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 723; +pub const _SC_2_PBS: ::c_int = 724; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 725; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 726; +pub const _SC_2_PBS_LOCATE: ::c_int = 728; +pub const _SC_2_PBS_MESSAGE: ::c_int = 729; +pub const _SC_2_PBS_TRACK: ::c_int = 730; +pub const _SC_ADVISORY_INFO: ::c_int = 731; +pub const _SC_BARRIERS: ::c_int = 732; +pub const _SC_CLOCK_SELECTION: ::c_int = 733; +pub const _SC_CPUTIME: ::c_int = 734; +pub const _SC_HOST_NAME_MAX: ::c_int = 735; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 736; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 737; +pub const _SC_REGEXP: ::c_int = 738; +pub const _SC_SHELL: ::c_int = 739; +pub const _SC_SPAWN: ::c_int = 740; +pub const _SC_SPIN_LOCKS: ::c_int = 741; +pub const _SC_SPORADIC_SERVER: ::c_int = 742; +pub const _SC_SS_REPL_MAX: ::c_int = 743; +pub const _SC_SYMLOOP_MAX: ::c_int = 744; +pub const _SC_THREAD_CPUTIME: ::c_int = 745; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 746; +pub const _SC_TIMEOUTS: ::c_int = 747; +pub const _SC_TRACE: ::c_int = 748; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 749; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 750; +pub const _SC_TRACE_INHERIT: ::c_int = 751; +pub const _SC_TRACE_LOG: ::c_int = 752; +pub const _SC_TRACE_NAME_MAX: ::c_int = 753; +pub const _SC_TRACE_SYS_MAX: ::c_int = 754; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 755; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 756; +pub const _SC_V6_ILP32_OFF32: ::c_int = 757; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 758; +pub const _SC_V6_LP64_OFF64: ::c_int = 759; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 760; +pub const _SC_XOPEN_STREAMS: ::c_int = 761; +pub const _SC_IPV6: ::c_int = 762; +pub const _SC_RAW_SOCKETS: ::c_int = 763; + +pub const _MUTEX_MAGIC: u16 = 0x4d58; // MX +pub const _COND_MAGIC: u16 = 0x4356; // CV +pub const _RWL_MAGIC: u16 = 0x5257; // RW + +pub const NCCS: usize = 19; + +pub const LOG_CRON: ::c_int = 15 << 3; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __pthread_mutex_flag1: 0, + __pthread_mutex_flag2: 0, + __pthread_mutex_ceiling: 0, + __pthread_mutex_type: PTHREAD_PROCESS_PRIVATE, + __pthread_mutex_magic: _MUTEX_MAGIC, + __pthread_mutex_lock: 0, + __pthread_mutex_data: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __pthread_cond_flag: [0; 4], + __pthread_cond_type: PTHREAD_PROCESS_PRIVATE, + __pthread_cond_magic: _COND_MAGIC, + __pthread_cond_data: 0, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __pthread_rwlock_readers: 0, + __pthread_rwlock_type: PTHREAD_PROCESS_PRIVATE, + __pthread_rwlock_magic: _RWL_MAGIC, + __pthread_rwlock_mutex: PTHREAD_MUTEX_INITIALIZER, + __pthread_rwlock_readercv: PTHREAD_COND_INITIALIZER, + __pthread_rwlock_writercv: PTHREAD_COND_INITIALIZER, +}; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 4; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; + +pub const RTLD_NEXT: *mut ::c_void = -1isize as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; +pub const RTLD_SELF: *mut ::c_void = -3isize as *mut ::c_void; +pub const RTLD_PROBE: *mut ::c_void = -4isize as *mut ::c_void; + +pub const RTLD_LAZY: ::c_int = 0x1; +pub const RTLD_NOW: ::c_int = 0x2; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_LOCAL: ::c_int = 0x0; +pub const RTLD_PARENT: ::c_int = 0x200; +pub const RTLD_GROUP: ::c_int = 0x400; +pub const RTLD_WORLD: ::c_int = 0x800; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_FIRST: ::c_int = 0x2000; +pub const RTLD_CONFGEN: ::c_int = 0x10000; + +pub const PORT_SOURCE_AIO: ::c_int = 1; +pub const PORT_SOURCE_TIMER: ::c_int = 2; +pub const PORT_SOURCE_USER: ::c_int = 3; +pub const PORT_SOURCE_FD: ::c_int = 4; +pub const PORT_SOURCE_ALERT: ::c_int = 5; +pub const PORT_SOURCE_MQ: ::c_int = 6; +pub const PORT_SOURCE_FILE: ::c_int = 7; + +pub const NONROOT_USR: ::c_short = 2; +pub const _UTX_USERSIZE: usize = 32; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_PADSIZE: usize = 5; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 257; +pub const EMPTY: ::c_short = 0; +pub const RUN_LVL: ::c_short = 1; +pub const BOOT_TIME: ::c_short = 2; +pub const OLD_TIME: ::c_short = 3; +pub const NEW_TIME: ::c_short = 4; +pub const INIT_PROCESS: ::c_short = 5; +pub const LOGIN_PROCESS: ::c_short = 6; +pub const USER_PROCESS: ::c_short = 7; +pub const DEAD_PROCESS: ::c_short = 8; +pub const ACCOUNTING: ::c_short = 9; +pub const DOWN_TIME: ::c_short = 10; + +const _TIOC: ::c_int = ('T' as i32) << 8; +const tIOC: ::c_int = ('t' as i32) << 8; +pub const TCGETA: ::c_int = _TIOC | 1; +pub const TCSETA: ::c_int = _TIOC | 2; +pub const TCSETAW: ::c_int = _TIOC | 3; +pub const TCSETAF: ::c_int = _TIOC | 4; +pub const TCSBRK: ::c_int = _TIOC | 5; +pub const TCXONC: ::c_int = _TIOC | 6; +pub const TCFLSH: ::c_int = _TIOC | 7; +pub const TCDSET: ::c_int = _TIOC | 32; +pub const TCGETS: ::c_int = _TIOC | 13; +pub const TCSETS: ::c_int = _TIOC | 14; +pub const TCSANOW: ::c_int = _TIOC | 14; +pub const TCSETSW: ::c_int = _TIOC | 15; +pub const TCSADRAIN: ::c_int = _TIOC | 15; +pub const TCSETSF: ::c_int = _TIOC | 16; +pub const TCSAFLUSH: ::c_int = _TIOC | 16; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TIOC: ::c_int = _TIOC; +pub const TIOCKBON: ::c_int = _TIOC | 8; +pub const TIOCKBOF: ::c_int = _TIOC | 9; +pub const TIOCGWINSZ: ::c_int = _TIOC | 104; +pub const TIOCSWINSZ: ::c_int = _TIOC | 103; +pub const TIOCGSOFTCAR: ::c_int = _TIOC | 105; +pub const TIOCSSOFTCAR: ::c_int = _TIOC | 106; +pub const TIOCGPPS: ::c_int = _TIOC | 125; +pub const TIOCSPPS: ::c_int = _TIOC | 126; +pub const TIOCGPPSEV: ::c_int = _TIOC | 127; +pub const TIOCGETD: ::c_int = tIOC | 0; +pub const TIOCSETD: ::c_int = tIOC | 1; +pub const TIOCHPCL: ::c_int = tIOC | 2; +pub const TIOCGETP: ::c_int = tIOC | 8; +pub const TIOCSETP: ::c_int = tIOC | 9; +pub const TIOCSETN: ::c_int = tIOC | 10; +pub const TIOCEXCL: ::c_int = tIOC | 13; +pub const TIOCNXCL: ::c_int = tIOC | 14; +pub const TIOCFLUSH: ::c_int = tIOC | 16; +pub const TIOCSETC: ::c_int = tIOC | 17; +pub const TIOCGETC: ::c_int = tIOC | 18; +pub const TIOCLBIS: ::c_int = tIOC | 127; +pub const TIOCLBIC: ::c_int = tIOC | 126; +pub const TIOCLSET: ::c_int = tIOC | 125; +pub const TIOCLGET: ::c_int = tIOC | 124; +pub const TIOCSBRK: ::c_int = tIOC | 123; +pub const TIOCCBRK: ::c_int = tIOC | 122; +pub const TIOCSDTR: ::c_int = tIOC | 121; +pub const TIOCCDTR: ::c_int = tIOC | 120; +pub const TIOCSLTC: ::c_int = tIOC | 117; +pub const TIOCGLTC: ::c_int = tIOC | 116; +pub const TIOCOUTQ: ::c_int = tIOC | 115; +pub const TIOCNOTTY: ::c_int = tIOC | 113; +pub const TIOCSCTTY: ::c_int = tIOC | 132; +pub const TIOCSTOP: ::c_int = tIOC | 111; +pub const TIOCSTART: ::c_int = tIOC | 110; +pub const TIOCSILOOP: ::c_int = tIOC | 109; +pub const TIOCCILOOP: ::c_int = tIOC | 108; +pub const TIOCGPGRP: ::c_int = tIOC | 20; +pub const TIOCSPGRP: ::c_int = tIOC | 21; +pub const TIOCGSID: ::c_int = tIOC | 22; +pub const TIOCSTI: ::c_int = tIOC | 23; +pub const TIOCMSET: ::c_int = tIOC | 26; +pub const TIOCMBIS: ::c_int = tIOC | 27; +pub const TIOCMBIC: ::c_int = tIOC | 28; +pub const TIOCMGET: ::c_int = tIOC | 29; +pub const TIOCREMOTE: ::c_int = tIOC | 30; +pub const TIOCSIGNAL: ::c_int = tIOC | 31; + +pub const TIOCM_LE: ::c_int = 0o0001; +pub const TIOCM_DTR: ::c_int = 0o0002; +pub const TIOCM_RTS: ::c_int = 0o0004; +pub const TIOCM_ST: ::c_int = 0o0010; +pub const TIOCM_SR: ::c_int = 0o0020; +pub const TIOCM_CTS: ::c_int = 0o0040; +pub const TIOCM_CAR: ::c_int = 0o0100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RNG: ::c_int = 0o0200; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const TIOCM_DSR: ::c_int = 0o0400; + +pub const EPOLLIN: ::c_int = 0x1; +pub const EPOLLPRI: ::c_int = 0x2; +pub const EPOLLOUT: ::c_int = 0x4; +pub const EPOLLRDNORM: ::c_int = 0x40; +pub const EPOLLRDBAND: ::c_int = 0x80; +pub const EPOLLWRNORM: ::c_int = 0x100; +pub const EPOLLWRBAND: ::c_int = 0x200; +pub const EPOLLMSG: ::c_int = 0x400; +pub const EPOLLERR: ::c_int = 0x8; +pub const EPOLLHUP: ::c_int = 0x10; +pub const EPOLLET: ::c_int = 0x80000000; +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLONESHOT: ::c_int = 0x40000000; +pub const EPOLLWAKEUP: ::c_int = 0x20000000; +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLL_CTL_DEL: ::c_int = 2; + +/* termios */ +pub const B0: speed_t = 0; +pub const B50: speed_t = 1; +pub const B75: speed_t = 2; +pub const B110: speed_t = 3; +pub const B134: speed_t = 4; +pub const B150: speed_t = 5; +pub const B200: speed_t = 6; +pub const B300: speed_t = 7; +pub const B600: speed_t = 8; +pub const B1200: speed_t = 9; +pub const B1800: speed_t = 10; +pub const B2400: speed_t = 11; +pub const B4800: speed_t = 12; +pub const B9600: speed_t = 13; +pub const B19200: speed_t = 14; +pub const B38400: speed_t = 15; +pub const B57600: speed_t = 16; +pub const B76800: speed_t = 17; +pub const B115200: speed_t = 18; +pub const B153600: speed_t = 19; +pub const B230400: speed_t = 20; +pub const B307200: speed_t = 21; +pub const B460800: speed_t = 22; +pub const B921600: speed_t = 23; +pub const CSTART: ::tcflag_t = 0o21; +pub const CSTOP: ::tcflag_t = 0o23; +pub const CSWTCH: ::tcflag_t = 0o32; +pub const CBAUD: ::tcflag_t = 0o17; +pub const CIBAUD: ::tcflag_t = 0o3600000; +pub const CBAUDEXT: ::tcflag_t = 0o10000000; +pub const CIBAUDEXT: ::tcflag_t = 0o20000000; +pub const CSIZE: ::tcflag_t = 0o000060; +pub const CS5: ::tcflag_t = 0; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +pub const ECHO: ::tcflag_t = 0o000010; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const IGNBRK: ::tcflag_t = 0o000001; +pub const BRKINT: ::tcflag_t = 0o000002; +pub const IGNPAR: ::tcflag_t = 0o000004; +pub const PARMRK: ::tcflag_t = 0o000010; +pub const INPCK: ::tcflag_t = 0o000020; +pub const ISTRIP: ::tcflag_t = 0o000040; +pub const INLCR: ::tcflag_t = 0o000100; +pub const IGNCR: ::tcflag_t = 0o000200; +pub const ICRNL: ::tcflag_t = 0o000400; +pub const IUCLC: ::tcflag_t = 0o001000; +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; +pub const IXANY: ::tcflag_t = 0o004000; +pub const IMAXBEL: ::tcflag_t = 0o020000; +pub const DOSMODE: ::tcflag_t = 0o100000; +pub const OPOST: ::tcflag_t = 0o000001; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const OCRNL: ::tcflag_t = 0o000010; +pub const ONOCR: ::tcflag_t = 0o000020; +pub const ONLRET: ::tcflag_t = 0o000040; +pub const OFILL: ::tcflag_t = 0o0000100; +pub const OFDEL: ::tcflag_t = 0o0000200; +pub const CREAD: ::tcflag_t = 0o000200; +pub const PARENB: ::tcflag_t = 0o000400; +pub const PARODD: ::tcflag_t = 0o001000; +pub const HUPCL: ::tcflag_t = 0o002000; +pub const CLOCAL: ::tcflag_t = 0o004000; +pub const CRTSXOFF: ::tcflag_t = 0o10000000000; +pub const CRTSCTS: ::tcflag_t = 0o20000000000; +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const IEXTEN: ::tcflag_t = 0o100000; +pub const TOSTOP: ::tcflag_t = 0o000400; +pub const FLUSHO: ::tcflag_t = 0o020000; +pub const PENDIN: ::tcflag_t = 0o040000; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VEOF: usize = 4; +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const VTIME: usize = 5; +pub const VSWTCH: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const VLNEXT: usize = 15; +pub const VSTATUS: usize = 16; +pub const VERASE2: usize = 17; + +// +const STR: ::c_int = (b'S' as ::c_int) << 8; +pub const I_NREAD: ::c_int = STR | 0o1; +pub const I_PUSH: ::c_int = STR | 0o2; +pub const I_POP: ::c_int = STR | 0o3; +pub const I_LOOK: ::c_int = STR | 0o4; +pub const I_FLUSH: ::c_int = STR | 0o5; +pub const I_SRDOPT: ::c_int = STR | 0o6; +pub const I_GRDOPT: ::c_int = STR | 0o7; +pub const I_STR: ::c_int = STR | 0o10; +pub const I_SETSIG: ::c_int = STR | 0o11; +pub const I_GETSIG: ::c_int = STR | 0o12; +pub const I_FIND: ::c_int = STR | 0o13; +pub const I_LINK: ::c_int = STR | 0o14; +pub const I_UNLINK: ::c_int = STR | 0o15; +pub const I_PEEK: ::c_int = STR | 0o17; +pub const I_FDINSERT: ::c_int = STR | 0o20; +pub const I_SENDFD: ::c_int = STR | 0o21; +pub const I_RECVFD: ::c_int = STR | 0o16; +pub const I_SWROPT: ::c_int = STR | 0o23; +pub const I_GWROPT: ::c_int = STR | 0o24; +pub const I_LIST: ::c_int = STR | 0o25; +pub const I_PLINK: ::c_int = STR | 0o26; +pub const I_PUNLINK: ::c_int = STR | 0o27; +pub const I_ANCHOR: ::c_int = STR | 0o30; +pub const I_FLUSHBAND: ::c_int = STR | 0o34; +pub const I_CKBAND: ::c_int = STR | 0o35; +pub const I_GETBAND: ::c_int = STR | 0o36; +pub const I_ATMARK: ::c_int = STR | 0o37; +pub const I_SETCLTIME: ::c_int = STR | 0o40; +pub const I_GETCLTIME: ::c_int = STR | 0o41; +pub const I_CANPUT: ::c_int = STR | 0o42; +pub const I_SERROPT: ::c_int = STR | 0o43; +pub const I_GERROPT: ::c_int = STR | 0o44; +pub const I_ESETSIG: ::c_int = STR | 0o45; +pub const I_EGETSIG: ::c_int = STR | 0o46; +pub const __I_PUSH_NOCTTY: ::c_int = STR | 0o47; + +// 3SOCKET flags +pub const SOCK_CLOEXEC: ::c_int = 0x080000; +pub const SOCK_NONBLOCK: ::c_int = 0x100000; +pub const SOCK_NDELAY: ::c_int = 0x200000; + +// +pub const SCALE_KG: ::c_int = 1 << 6; +pub const SCALE_KF: ::c_int = 1 << 16; +pub const SCALE_KH: ::c_int = 1 << 2; +pub const MAXTC: ::c_int = 1 << 6; +pub const SCALE_PHASE: ::c_int = 1 << 22; +pub const SCALE_USEC: ::c_int = 1 << 16; +pub const SCALE_UPDATE: ::c_int = SCALE_KG * MAXTC; +pub const FINEUSEC: ::c_int = 1 << 22; +pub const MAXPHASE: ::c_int = 512000; +pub const MAXFREQ: ::c_int = 512 * SCALE_USEC; +pub const MAXTIME: ::c_int = 200 << PPS_AVG; +pub const MINSEC: ::c_int = 16; +pub const MAXSEC: ::c_int = 1200; +pub const PPS_AVG: ::c_int = 2; +pub const PPS_SHIFT: ::c_int = 2; +pub const PPS_SHIFTMAX: ::c_int = 8; +pub const PPS_VALID: ::c_int = 120; +pub const MAXGLITCH: ::c_int = 30; +pub const MOD_OFFSET: u32 = 0x0001; +pub const MOD_FREQUENCY: u32 = 0x0002; +pub const MOD_MAXERROR: u32 = 0x0004; +pub const MOD_ESTERROR: u32 = 0x0008; +pub const MOD_STATUS: u32 = 0x0010; +pub const MOD_TIMECONST: u32 = 0x0020; +pub const MOD_CLKB: u32 = 0x4000; +pub const MOD_CLKA: u32 = 0x8000; +pub const STA_PLL: u32 = 0x0001; +pub const STA_PPSFREQ: i32 = 0x0002; +pub const STA_PPSTIME: i32 = 0x0004; +pub const STA_FLL: i32 = 0x0008; +pub const STA_INS: i32 = 0x0010; +pub const STA_DEL: i32 = 0x0020; +pub const STA_UNSYNC: i32 = 0x0040; +pub const STA_FREQHOLD: i32 = 0x0080; +pub const STA_PPSSIGNAL: i32 = 0x0100; +pub const STA_PPSJITTER: i32 = 0x0200; +pub const STA_PPSWANDER: i32 = 0x0400; +pub const STA_PPSERROR: i32 = 0x0800; +pub const STA_CLOCKERR: i32 = 0x1000; +pub const STA_RONLY: i32 = + STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR | STA_CLOCKERR; +pub const TIME_OK: i32 = 0; +pub const TIME_INS: i32 = 1; +pub const TIME_DEL: i32 = 2; +pub const TIME_OOP: i32 = 3; +pub const TIME_WAIT: i32 = 4; +pub const TIME_ERROR: i32 = 5; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_SYS: ::c_int = 3; +pub const SCHED_IA: ::c_int = 4; +pub const SCHED_FSS: ::c_int = 5; +pub const SCHED_FX: ::c_int = 6; + +// sys/priv.h +pub const PRIV_DEBUG: ::c_uint = 0x0001; +pub const PRIV_AWARE: ::c_uint = 0x0002; +pub const PRIV_AWARE_INHERIT: ::c_uint = 0x0004; +pub const __PROC_PROTECT: ::c_uint = 0x0008; +pub const NET_MAC_AWARE: ::c_uint = 0x0010; +pub const NET_MAC_AWARE_INHERIT: ::c_uint = 0x0020; +pub const PRIV_AWARE_RESET: ::c_uint = 0x0040; +pub const PRIV_XPOLICY: ::c_uint = 0x0080; +pub const PRIV_PFEXEC: ::c_uint = 0x0100; +pub const PRIV_USER: ::c_uint = PRIV_DEBUG + | NET_MAC_AWARE + | NET_MAC_AWARE_INHERIT + | PRIV_XPOLICY + | PRIV_AWARE_RESET + | PRIV_PFEXEC; + +// sys/systeminfo.h +pub const SI_SYSNAME: ::c_int = 1; +pub const SI_HOSTNAME: ::c_int = 2; +pub const SI_RELEASE: ::c_int = 3; +pub const SI_VERSION: ::c_int = 4; +pub const SI_MACHINE: ::c_int = 5; +pub const SI_ARCHITECTURE: ::c_int = 6; +pub const SI_HW_SERIAL: ::c_int = 7; +pub const SI_HW_PROVIDER: ::c_int = 8; +pub const SI_SET_HOSTNAME: ::c_int = 258; +pub const SI_SET_SRPC_DOMAIN: ::c_int = 265; +pub const SI_PLATFORM: ::c_int = 513; +pub const SI_ISALIST: ::c_int = 514; +pub const SI_DHCP_CACHE: ::c_int = 515; +pub const SI_ARCHITECTURE_32: ::c_int = 516; +pub const SI_ARCHITECTURE_64: ::c_int = 517; +pub const SI_ARCHITECTURE_K: ::c_int = 518; +pub const SI_ARCHITECTURE_NATIVE: ::c_int = 519; + +// sys/lgrp_user.h +pub const LGRP_COOKIE_NONE: ::lgrp_cookie_t = 0; +pub const LGRP_AFF_NONE: ::lgrp_affinity_t = 0x0; +pub const LGRP_AFF_WEAK: ::lgrp_affinity_t = 0x10; +pub const LGRP_AFF_STRONG: ::lgrp_affinity_t = 0x100; +pub const LGRP_RSRC_COUNT: ::lgrp_rsrc_t = 2; +pub const LGRP_RSRC_CPU: ::lgrp_rsrc_t = 0; +pub const LGRP_RSRC_MEM: ::lgrp_rsrc_t = 1; +pub const LGRP_CONTENT_ALL: ::lgrp_content_t = 0; +pub const LGRP_CONTENT_HIERARCHY: ::lgrp_content_t = LGRP_CONTENT_ALL; +pub const LGRP_CONTENT_DIRECT: ::lgrp_content_t = 1; +pub const LGRP_LAT_CPU_TO_MEM: ::lgrp_lat_between_t = 0; +pub const LGRP_MEM_SZ_FREE: ::lgrp_mem_size_flag_t = 0; +pub const LGRP_MEM_SZ_INSTALLED: ::lgrp_mem_size_flag_t = 1; +pub const LGRP_VIEW_CALLER: ::lgrp_view_t = 0; +pub const LGRP_VIEW_OS: ::lgrp_view_t = 1; + +// sys/processor.h + +pub const P_OFFLINE: ::c_int = 0x001; +pub const P_ONLINE: ::c_int = 0x002; +pub const P_STATUS: ::c_int = 0x003; +pub const P_FAULTED: ::c_int = 0x004; +pub const P_POWEROFF: ::c_int = 0x005; +pub const P_NOINTR: ::c_int = 0x006; +pub const P_SPARE: ::c_int = 0x007; +pub const P_DISABLED: ::c_int = 0x008; +pub const P_FORCED: ::c_int = 0x10000000; +pub const PI_TYPELEN: ::c_int = 16; +pub const PI_FPUTYPE: ::c_int = 32; + +// sys/auxv.h +pub const AT_SUN_HWCAP: ::c_uint = 2009; +pub const AT_SUN_HWCAP2: ::c_uint = 2023; +pub const AT_SUN_FPTYPE: ::c_uint = 2027; + +// As per sys/socket.h, header alignment must be 8 bytes on SPARC +// and 4 bytes everywhere else: +#[cfg(target_arch = "sparc64")] +const _CMSG_HDR_ALIGNMENT: usize = 8; +#[cfg(not(target_arch = "sparc64"))] +const _CMSG_HDR_ALIGNMENT: usize = 4; + +const _CMSG_DATA_ALIGNMENT: usize = ::mem::size_of::<::c_int>(); + +const NEWDEV: ::c_int = 1; + +// sys/sendfile.h +pub const SFV_FD_SELF: ::c_int = -2; + +const_fn! { + {const} fn _CMSG_HDR_ALIGN(p: usize) -> usize { + (p + _CMSG_HDR_ALIGNMENT - 1) & !(_CMSG_HDR_ALIGNMENT - 1) + } + + {const} fn _CMSG_DATA_ALIGN(p: usize) -> usize { + (p + _CMSG_DATA_ALIGNMENT - 1) & !(_CMSG_DATA_ALIGNMENT - 1) + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + _CMSG_DATA_ALIGN(cmsg.offset(1) as usize) as *mut ::c_uchar + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _CMSG_DATA_ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr { + if ((*mhdr).msg_controllen as usize) < ::mem::size_of::<::cmsghdr>() { + 0 as *mut ::cmsghdr + } else { + (*mhdr).msg_control as *mut ::cmsghdr + } + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize + + ::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + _CMSG_HDR_ALIGN(::mem::size_of::<::cmsghdr>() as usize + + length as usize) as ::c_uint + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xFF) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xFF + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7F + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0xffff) == 0xffff + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status & 0xff00) >> 8 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0xff) > 0) && (status & 0xff00 == 0) + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + ((status & 0xff) == 0x7f) && ((status & 0xff00) != 0) + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } + + pub {const} fn MR_GET_TYPE(flags: ::c_uint) -> ::c_uint { + flags & 0x0000ffff + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn getrandom(bbuf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn settimeofday(tp: *const ::timeval, tz: *const ::c_void) -> ::c_int; + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + pub fn stack_getbounds(sp: *mut ::stack_t) -> ::c_int; + pub fn getgrouplist( + name: *const ::c_char, + basegid: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn ___errno() -> *mut ::c_int; + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn getprogname() -> *const ::c_char; + pub fn setprogname(name: *const ::c_char); + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_attr_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_condattr_getclock( + attr: *const pthread_condattr_t, + clock_id: *mut clockid_t, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_getname_np(tid: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_setname_np(tid: ::pthread_t, name: *const ::c_char) -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + + #[cfg_attr(target_os = "illumos", link_name = "_glob_ext")] + pub fn glob( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + + #[cfg_attr(target_os = "illumos", link_name = "_globfree_ext")] + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + + pub fn shmget(key: key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn recvfrom( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn futimesat(fd: ::c_int, path: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn futimens(dirfd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + #[cfg_attr(target_os = "illumos", link_name = "__xnet_bind")] + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendmsg")] + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + #[cfg_attr(target_os = "illumos", link_name = "__xnet_recvmsg")] + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn accept4( + fd: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + flags: ::c_int, + ) -> ::c_int; + + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; + pub fn port_create() -> ::c_int; + pub fn port_associate( + port: ::c_int, + source: ::c_int, + object: ::uintptr_t, + events: ::c_int, + user: *mut ::c_void, + ) -> ::c_int; + pub fn port_dissociate(port: ::c_int, source: ::c_int, object: ::uintptr_t) -> ::c_int; + pub fn port_get(port: ::c_int, pe: *mut port_event, timeout: *mut ::timespec) -> ::c_int; + pub fn port_getn( + port: ::c_int, + pe_list: *mut port_event, + max: ::c_uint, + nget: *mut ::c_uint, + timeout: *mut ::timespec, + ) -> ::c_int; + pub fn port_send(port: ::c_int, events: ::c_int, user: *mut ::c_void) -> ::c_int; + pub fn port_sendn( + port_list: *mut ::c_int, + error_list: *mut ::c_int, + nent: ::c_uint, + events: ::c_int, + user: *mut ::c_void, + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrgid_r" + )] + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + + // The epoll functions are actually only present on illumos. However, + // there are things using epoll on illumos (built using the + // x86_64-pc-solaris target) which would break until the illumos target is + // present in rustc. + pub fn epoll_pwait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + sigmask: *const ::sigset_t, + ) -> ::c_int; + + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrnam_r" + )] + pub fn getgrnam_r( + name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn thr_self() -> ::thread_t; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut sched_param) -> ::c_int; + pub fn sched_setparam(pid: ::pid_t, param: *const sched_param) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwnam_r" + )] + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwuid_r" + )] + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "getpwent_r" + )] + fn native_getpwent_r(pwd: *mut passwd, buf: *mut ::c_char, buflen: ::c_int) -> *mut passwd; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "getgrent_r" + )] + fn native_getgrent_r(grp: *mut ::group, buf: *mut ::c_char, buflen: ::c_int) -> *mut ::group; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_sigwait" + )] + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + + pub fn makeutx(ux: *const utmpx) -> *mut utmpx; + pub fn modutx(ux: *const utmpx) -> *mut utmpx; + pub fn updwtmpx(file: *const ::c_char, ut: *const utmpx) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); + + pub fn endutent(); + pub fn getutent() -> *mut utmp; + pub fn getutid(u: *const utmp) -> *mut utmp; + pub fn getutline(u: *const utmp) -> *mut utmp; + pub fn pututline(u: *const utmp) -> *mut utmp; + pub fn setutent(); + pub fn utmpname(file: *const ::c_char) -> ::c_int; + + pub fn getutmp(ux: *const utmpx, u: *mut utmp); + pub fn getutmpx(u: *const utmp, ux: *mut utmpx); + pub fn updwtmp(file: *const ::c_char, u: *mut utmp); + + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + pub fn timer_create(clock_id: clockid_t, evp: *mut sigevent, timerid: *mut timer_t) -> ::c_int; + pub fn timer_delete(timerid: timer_t) -> ::c_int; + pub fn timer_getoverrun(timerid: timer_t) -> ::c_int; + pub fn timer_gettime(timerid: timer_t, value: *mut itimerspec) -> ::c_int; + pub fn timer_settime( + timerid: timer_t, + flags: ::c_int, + value: *const itimerspec, + ovalue: *mut itimerspec, + ) -> ::c_int; + + pub fn ucred_get(pid: ::pid_t) -> *mut ucred_t; + pub fn getpeerucred(fd: ::c_int, ucred: *mut *mut ucred_t) -> ::c_int; + + pub fn ucred_free(ucred: *mut ucred_t); + + pub fn ucred_geteuid(ucred: *const ucred_t) -> ::uid_t; + pub fn ucred_getruid(ucred: *const ucred_t) -> ::uid_t; + pub fn ucred_getsuid(ucred: *const ucred_t) -> ::uid_t; + pub fn ucred_getegid(ucred: *const ucred_t) -> ::gid_t; + pub fn ucred_getrgid(ucred: *const ucred_t) -> ::gid_t; + pub fn ucred_getsgid(ucred: *const ucred_t) -> ::gid_t; + pub fn ucred_getgroups(ucred: *const ucred_t, groups: *mut *const ::gid_t) -> ::c_int; + pub fn ucred_getpid(ucred: *const ucred_t) -> ::pid_t; + pub fn ucred_getprojid(ucred: *const ucred_t) -> projid_t; + pub fn ucred_getzoneid(ucred: *const ucred_t) -> zoneid_t; + pub fn ucred_getpflags(ucred: *const ucred_t, flags: ::c_uint) -> ::c_uint; + + pub fn ucred_size() -> ::size_t; + + pub fn pset_create(newpset: *mut ::psetid_t) -> ::c_int; + pub fn pset_destroy(pset: ::psetid_t) -> ::c_int; + pub fn pset_assign(pset: ::psetid_t, cpu: ::processorid_t, opset: *mut psetid_t) -> ::c_int; + pub fn pset_info( + pset: ::psetid_t, + tpe: *mut ::c_int, + numcpus: *mut ::c_uint, + cpulist: *mut processorid_t, + ) -> ::c_int; + pub fn pset_bind( + pset: ::psetid_t, + idtype: ::idtype_t, + id: ::id_t, + opset: *mut psetid_t, + ) -> ::c_int; + pub fn pset_list(pset: *mut psetid_t, numpsets: *mut ::c_uint) -> ::c_int; + pub fn pset_setattr(pset: psetid_t, attr: ::c_uint) -> ::c_int; + pub fn pset_getattr(pset: psetid_t, attr: *mut ::c_uint) -> ::c_int; + pub fn processor_bind( + idtype: ::idtype_t, + id: ::id_t, + new_binding: ::processorid_t, + old_binding: *mut processorid_t, + ) -> ::c_int; + pub fn p_online(processorid: ::processorid_t, flag: ::c_int) -> ::c_int; + pub fn processor_info(processorid: ::processorid_t, infop: *mut processor_info_t) -> ::c_int; + + pub fn getexecname() -> *const ::c_char; + + pub fn gethostid() -> ::c_long; + + pub fn getpflags(flags: ::c_uint) -> ::c_uint; + pub fn setpflags(flags: ::c_uint, value: ::c_uint) -> ::c_int; + + pub fn sysinfo(command: ::c_int, buf: *mut ::c_char, count: ::c_long) -> ::c_int; + + pub fn faccessat(fd: ::c_int, path: *const ::c_char, amode: ::c_int, flag: ::c_int) -> ::c_int; + + // #include + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut dl_phdr_info, + size: usize, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + pub fn getpagesize() -> ::c_int; + pub fn getpagesizes(pagesize: *mut ::size_t, nelem: ::c_int) -> ::c_int; + pub fn mmapobj( + fd: ::c_int, + flags: ::c_uint, + storage: *mut mmapobj_result_t, + elements: *mut ::c_uint, + arg: *mut ::c_void, + ) -> ::c_int; + pub fn meminfo( + inaddr: *const u64, + addr_count: ::c_int, + info_req: *const ::c_uint, + info_count: ::c_int, + outdata: *mut u64, + validity: *mut ::c_uint, + ) -> ::c_int; + + pub fn strcasecmp_l(s1: *const ::c_char, s2: *const ::c_char, loc: ::locale_t) -> ::c_int; + pub fn strncasecmp_l( + s1: *const ::c_char, + s2: *const ::c_char, + n: ::size_t, + loc: ::locale_t, + ) -> ::c_int; + pub fn strsep(string: *mut *mut ::c_char, delim: *const ::c_char) -> *mut ::c_char; + + pub fn getisax(array: *mut u32, n: ::c_uint) -> ::c_uint; + + pub fn backtrace(buffer: *mut *mut ::c_void, size: ::c_int) -> ::c_int; + pub fn backtrace_symbols(buffer: *const *mut ::c_void, size: ::c_int) -> *mut *mut ::c_char; + pub fn backtrace_symbols_fd(buffer: *const *mut ::c_void, size: ::c_int, fd: ::c_int); + + pub fn getopt_long( + argc: ::c_int, + argv: *const *mut c_char, + optstring: *const c_char, + longopts: *const option, + longindex: *mut ::c_int, + ) -> ::c_int; + + pub fn sync(); + + pub fn __major(version: ::c_int, devnum: ::dev_t) -> ::major_t; + pub fn __minor(version: ::c_int, devnum: ::dev_t) -> ::minor_t; + pub fn __makedev(version: ::c_int, majdev: ::major_t, mindev: ::minor_t) -> ::dev_t; +} + +#[link(name = "sendfile")] +extern "C" { + pub fn sendfile(out_fd: ::c_int, in_fd: ::c_int, off: *mut ::off_t, len: ::size_t) + -> ::ssize_t; + pub fn sendfilev( + fildes: ::c_int, + vec: *const sendfilevec_t, + sfvcnt: ::c_int, + xferred: *mut ::size_t, + ) -> ::ssize_t; +} + +#[link(name = "lgrp")] +extern "C" { + pub fn lgrp_init(view: lgrp_view_t) -> lgrp_cookie_t; + pub fn lgrp_fini(cookie: lgrp_cookie_t) -> ::c_int; + pub fn lgrp_affinity_get( + idtype: ::idtype_t, + id: ::id_t, + lgrp: ::lgrp_id_t, + ) -> ::lgrp_affinity_t; + pub fn lgrp_affinity_set( + idtype: ::idtype_t, + id: ::id_t, + lgrp: ::lgrp_id_t, + aff: lgrp_affinity_t, + ) -> ::lgrp_affinity_t; + pub fn lgrp_cpus( + cookie: ::lgrp_cookie_t, + lgrp: ::lgrp_id_t, + cpuids: *mut ::processorid_t, + count: ::c_uint, + content: ::lgrp_content_t, + ) -> ::c_int; + pub fn lgrp_mem_size( + cookie: ::lgrp_cookie_t, + lgrp: ::lgrp_id_t, + tpe: ::lgrp_mem_size_flag_t, + content: ::lgrp_content_t, + ) -> ::lgrp_mem_size_t; + pub fn lgrp_nlgrps(cookie: ::lgrp_cookie_t) -> ::c_int; + pub fn lgrp_view(cookie: ::lgrp_cookie_t) -> ::lgrp_view_t; + pub fn lgrp_home(idtype: ::idtype_t, id: ::id_t) -> ::lgrp_id_t; + pub fn lgrp_version(version: ::c_int) -> ::c_int; + pub fn lgrp_resources( + cookie: ::lgrp_cookie_t, + lgrp: ::lgrp_id_t, + lgrps: *mut ::lgrp_id_t, + count: ::c_uint, + tpe: ::lgrp_rsrc_t, + ) -> ::c_int; + pub fn lgrp_root(cookie: ::lgrp_cookie_t) -> ::lgrp_id_t; +} + +pub unsafe fn major(device: ::dev_t) -> ::major_t { + __major(NEWDEV, device) +} + +pub unsafe fn minor(device: ::dev_t) -> ::minor_t { + __minor(NEWDEV, device) +} + +pub unsafe fn makedev(maj: ::major_t, min: ::minor_t) -> ::dev_t { + __makedev(NEWDEV, maj, min) +} + +mod compat; +pub use self::compat::*; + +cfg_if! { + if #[cfg(target_os = "illumos")] { + mod illumos; + pub use self::illumos::*; + } else if #[cfg(target_os = "solaris")] { + mod solaris; + pub use self::solaris::*; + } else { + // Unknown target_os + } +} + +cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + mod x86_common; + pub use self::x86_64::*; + pub use self::x86_common::*; + } else if #[cfg(target_arch = "x86")] { + mod x86; + mod x86_common; + pub use self::x86::*; + pub use self::x86_common::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/solaris.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/solaris.rs new file mode 100644 index 00000000..80bad281 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/solaris.rs @@ -0,0 +1,101 @@ +pub type door_attr_t = ::c_uint; +pub type door_id_t = ::c_ulonglong; + +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_flags: ::uintptr_t, + pub shm_lkcnt: ::c_ushort, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_cnattch: ::c_ulong, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_amp: *mut ::c_void, + pub shm_gransize: u64, + pub shm_allocated: u64, + pub shm_pad4: [i64; 1], + } + + pub struct door_desc_t__d_data__d_desc { + pub d_descriptor: ::c_int, + pub d_id: ::door_id_t + } +} + +s_no_extra_traits! { + #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] + pub union door_desc_t__d_data { + pub d_desc: door_desc_t__d_data__d_desc, + d_resv: [::c_int; 5], /* Check out /usr/include/sys/door.h */ + } + + #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] + pub struct door_desc_t { + pub d_attributes: door_attr_t, + pub d_data: door_desc_t__d_data, + } + + #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] + pub struct door_arg_t { + pub data_ptr: *const ::c_char, + pub data_size: ::size_t, + pub desc_ptr: *const door_desc_t, + pub dec_num: ::c_uint, + pub rbuf: *const ::c_char, + pub rsize: ::size_t, + } +} + +pub const PORT_SOURCE_POSTWAIT: ::c_int = 8; +pub const PORT_SOURCE_SIGNAL: ::c_int = 9; + +pub const AF_LOCAL: ::c_int = 0; +pub const AF_FILE: ::c_int = 0; + +pub const TCP_KEEPIDLE: ::c_int = 0x1d; +pub const TCP_KEEPINTVL: ::c_int = 0x1e; +pub const TCP_KEEPCNT: ::c_int = 0x1f; + +pub const F_DUPFD_CLOEXEC: ::c_int = 47; +pub const F_DUPFD_CLOFORK: ::c_int = 49; +pub const F_DUP2FD_CLOEXEC: ::c_int = 48; +pub const F_DUP2FD_CLOFORK: ::c_int = 50; + +extern "C" { + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + + pub fn door_call(d: ::c_int, params: *const door_arg_t) -> ::c_int; + pub fn door_return( + data_ptr: *const ::c_char, + data_size: ::size_t, + desc_ptr: *const door_desc_t, + num_desc: ::c_uint, + ); + pub fn door_create( + server_procedure: extern "C" fn( + cookie: *const ::c_void, + argp: *const ::c_char, + arg_size: ::size_t, + dp: *const door_desc_t, + n_desc: ::c_uint, + ), + cookie: *const ::c_void, + attributes: door_attr_t, + ) -> ::c_int; + + pub fn fattach(fildes: ::c_int, path: *const ::c_char) -> ::c_int; + + pub fn pthread_getattr_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + + pub fn euidaccess(path: *const ::c_char, amode: ::c_int) -> ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/x86.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/x86.rs new file mode 100644 index 00000000..23f52ad3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/x86.rs @@ -0,0 +1,29 @@ +pub type Elf32_Addr = ::c_ulong; +pub type Elf32_Half = ::c_ushort; +pub type Elf32_Off = ::c_ulong; +pub type Elf32_Sword = ::c_long; +pub type Elf32_Word = ::c_ulong; +pub type Elf32_Lword = ::c_ulonglong; +pub type Elf32_Phdr = __c_anonymous_Elf32_Phdr; + +s! { + pub struct __c_anonymous_Elf32_Phdr { + pub p_type: ::Elf32_Word, + pub p_offset: ::Elf32_Off, + pub p_vaddr: ::Elf32_Addr, + pub p_paddr: ::Elf32_Addr, + pub p_filesz: ::Elf32_Word, + pub p_memsz: ::Elf32_Word, + pub p_flags: ::Elf32_Word, + pub p_align: ::Elf32_Word, + } + + pub struct dl_phdr_info { + pub dlpi_addr: ::Elf32_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const ::Elf32_Phdr, + pub dlpi_phnum: ::Elf32_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + } +} diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/x86_64.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/x86_64.rs new file mode 100644 index 00000000..bca552f3 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/x86_64.rs @@ -0,0 +1,190 @@ +pub type greg_t = ::c_long; + +pub type Elf64_Addr = ::c_ulong; +pub type Elf64_Half = ::c_ushort; +pub type Elf64_Off = ::c_ulong; +pub type Elf64_Sword = ::c_int; +pub type Elf64_Sxword = ::c_long; +pub type Elf64_Word = ::c_uint; +pub type Elf64_Xword = ::c_ulong; +pub type Elf64_Lword = ::c_ulong; +pub type Elf64_Phdr = __c_anonymous_Elf64_Phdr; + +s! { + pub struct __c_anonymous_fpchip_state { + pub cw: u16, + pub sw: u16, + pub fctw: u8, + pub __fx_rsvd: u8, + pub fop: u16, + pub rip: u64, + pub rdp: u64, + pub mxcsr: u32, + pub mxcsr_mask: u32, + pub st: [::upad128_t; 8], + pub xmm: [::upad128_t; 16], + pub __fx_ign: [::upad128_t; 6], + pub status: u32, + pub xstatus: u32, + } + + pub struct __c_anonymous_Elf64_Phdr { + pub p_type: ::Elf64_Word, + pub p_flags: ::Elf64_Word, + pub p_offset: ::Elf64_Off, + pub p_vaddr: ::Elf64_Addr, + pub p_paddr: ::Elf64_Addr, + pub p_filesz: ::Elf64_Xword, + pub p_memsz: ::Elf64_Xword, + pub p_align: ::Elf64_Xword, + } + + pub struct dl_phdr_info { + pub dlpi_addr: ::Elf64_Addr, + pub dlpi_name: *const ::c_char, + pub dlpi_phdr: *const ::Elf64_Phdr, + pub dlpi_phnum: ::Elf64_Half, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + } +} + +s_no_extra_traits! { + #[cfg(libc_union)] + pub union __c_anonymous_fp_reg_set { + pub fpchip_state: __c_anonymous_fpchip_state, + pub f_fpregs: [[u32; 13]; 10], + } + + pub struct fpregset_t { + pub fp_reg_set: __c_anonymous_fp_reg_set, + } + + pub struct mcontext_t { + pub gregs: [::greg_t; 28], + pub fpregs: fpregset_t, + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_filler: [::c_long; 5], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_fp_reg_set { + fn eq(&self, other: &__c_anonymous_fp_reg_set) -> bool { + unsafe { + self.fpchip_state == other.fpchip_state || + self. + f_fpregs. + iter(). + zip(other.f_fpregs.iter()). + all(|(a, b)| a == b) + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_fp_reg_set {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_fp_reg_set { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous_fp_reg_set") + .field("fpchip_state", &{self.fpchip_state}) + .field("f_fpregs", &{self.f_fpregs}) + .finish() + } + } + } + impl PartialEq for fpregset_t { + fn eq(&self, other: &fpregset_t) -> bool { + self.fp_reg_set == other.fp_reg_set + } + } + impl Eq for fpregset_t {} + impl ::fmt::Debug for fpregset_t { + fn fmt(&self, f:&mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpregset_t") + .field("fp_reg_set", &self.fp_reg_set) + .finish() + } + } + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.gregs == other.gregs && + self.fpregs == other.fpregs + } + } + impl Eq for mcontext_t {} + impl ::fmt::Debug for mcontext_t { + fn fmt(&self, f:&mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mcontext_t") + .field("gregs", &self.gregs) + .field("fpregs", &self.fpregs) + .finish() + } + } + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_sigmask == other.uc_sigmask + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_filler == other.uc_filler + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f:&mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_sigmask", &self.uc_sigmask) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_filler", &self.uc_filler) + .finish() + } + } + + } +} + +// sys/regset.h + +pub const REG_GSBASE: ::c_int = 27; +pub const REG_FSBASE: ::c_int = 26; +pub const REG_DS: ::c_int = 25; +pub const REG_ES: ::c_int = 24; +pub const REG_GS: ::c_int = 23; +pub const REG_FS: ::c_int = 22; +pub const REG_SS: ::c_int = 21; +pub const REG_RSP: ::c_int = 20; +pub const REG_RFL: ::c_int = 19; +pub const REG_CS: ::c_int = 18; +pub const REG_RIP: ::c_int = 17; +pub const REG_ERR: ::c_int = 16; +pub const REG_TRAPNO: ::c_int = 15; +pub const REG_RAX: ::c_int = 14; +pub const REG_RCX: ::c_int = 13; +pub const REG_RDX: ::c_int = 12; +pub const REG_RBX: ::c_int = 11; +pub const REG_RBP: ::c_int = 10; +pub const REG_RSI: ::c_int = 9; +pub const REG_RDI: ::c_int = 8; +pub const REG_R8: ::c_int = 7; +pub const REG_R9: ::c_int = 6; +pub const REG_R10: ::c_int = 5; +pub const REG_R11: ::c_int = 4; +pub const REG_R12: ::c_int = 3; +pub const REG_R13: ::c_int = 2; +pub const REG_R14: ::c_int = 1; +pub const REG_R15: ::c_int = 0; diff --git a/utshell-0.5.0/vendor/libc/src/unix/solarish/x86_common.rs b/utshell-0.5.0/vendor/libc/src/unix/solarish/x86_common.rs new file mode 100644 index 00000000..515f2349 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/unix/solarish/x86_common.rs @@ -0,0 +1,65 @@ +// AT_SUN_HWCAP +pub const AV_386_FPU: u32 = 0x00001; +pub const AV_386_TSC: u32 = 0x00002; +pub const AV_386_CX8: u32 = 0x00004; +pub const AV_386_SEP: u32 = 0x00008; +pub const AV_386_AMD_SYSC: u32 = 0x00010; +pub const AV_386_CMOV: u32 = 0x00020; +pub const AV_386_MMX: u32 = 0x00040; +pub const AV_386_AMD_MMX: u32 = 0x00080; +pub const AV_386_AMD_3DNow: u32 = 0x00100; +pub const AV_386_AMD_3DNowx: u32 = 0x00200; +pub const AV_386_FXSR: u32 = 0x00400; +pub const AV_386_SSE: u32 = 0x00800; +pub const AV_386_SSE2: u32 = 0x01000; +pub const AV_386_CX16: u32 = 0x10000; +pub const AV_386_AHF: u32 = 0x20000; +pub const AV_386_TSCP: u32 = 0x40000; +pub const AV_386_AMD_SSE4A: u32 = 0x80000; +pub const AV_386_POPCNT: u32 = 0x100000; +pub const AV_386_AMD_LZCNT: u32 = 0x200000; +pub const AV_386_SSSE3: u32 = 0x400000; +pub const AV_386_SSE4_1: u32 = 0x800000; +pub const AV_386_SSE4_2: u32 = 0x1000000; +pub const AV_386_MOVBE: u32 = 0x2000000; +pub const AV_386_AES: u32 = 0x4000000; +pub const AV_386_PCLMULQDQ: u32 = 0x8000000; +pub const AV_386_XSAVE: u32 = 0x10000000; +pub const AV_386_AVX: u32 = 0x20000000; +pub const AV_386_VMX: u32 = 0x40000000; +pub const AV_386_AMD_SVM: u32 = 0x80000000; +// AT_SUN_HWCAP2 +pub const AV_386_2_F16C: u32 = 0x00000001; +pub const AV_386_2_RDRAND: u32 = 0x00000002; +pub const AV_386_2_BMI1: u32 = 0x00000004; +pub const AV_386_2_BMI2: u32 = 0x00000008; +pub const AV_386_2_FMA: u32 = 0x00000010; +pub const AV_386_2_AVX2: u32 = 0x00000020; +pub const AV_386_2_ADX: u32 = 0x00000040; +pub const AV_386_2_RDSEED: u32 = 0x00000080; +pub const AV_386_2_AVX512F: u32 = 0x00000100; +pub const AV_386_2_AVX512DQ: u32 = 0x00000200; +pub const AV_386_2_AVX512IFMA: u32 = 0x00000400; +pub const AV_386_2_AVX512PF: u32 = 0x00000800; +pub const AV_386_2_AVX512ER: u32 = 0x00001000; +pub const AV_386_2_AVX512CD: u32 = 0x00002000; +pub const AV_386_2_AVX512BW: u32 = 0x00004000; +pub const AV_386_2_AVX512VL: u32 = 0x00008000; +pub const AV_386_2_AVX512VBMI: u32 = 0x00010000; +pub const AV_386_2_AVX512VPOPCDQ: u32 = 0x00020000; +pub const AV_386_2_AVX512_4NNIW: u32 = 0x00040000; +pub const AV_386_2_AVX512_4FMAPS: u32 = 0x00080000; +pub const AV_386_2_SHA: u32 = 0x00100000; +pub const AV_386_2_FSGSBASE: u32 = 0x00200000; +pub const AV_386_2_CLFLUSHOPT: u32 = 0x00400000; +pub const AV_386_2_CLWB: u32 = 0x00800000; +pub const AV_386_2_MONITORX: u32 = 0x01000000; +pub const AV_386_2_CLZERO: u32 = 0x02000000; +pub const AV_386_2_AVX512_VNNI: u32 = 0x04000000; +pub const AV_386_2_VPCLMULQDQ: u32 = 0x08000000; +pub const AV_386_2_VAES: u32 = 0x10000000; +// AT_SUN_FPTYPE +pub const AT_386_FPINFO_NONE: u32 = 0; +pub const AT_386_FPINFO_FXSAVE: u32 = 1; +pub const AT_386_FPINFO_XSAVE: u32 = 2; +pub const AT_386_FPINFO_XSAVE_AMD: u32 = 3; diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/aarch64.rs b/utshell-0.5.0/vendor/libc/src/vxworks/aarch64.rs new file mode 100644 index 00000000..4032488b --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/aarch64.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/arm.rs b/utshell-0.5.0/vendor/libc/src/vxworks/arm.rs new file mode 100644 index 00000000..55240068 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/arm.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/mod.rs b/utshell-0.5.0/vendor/libc/src/vxworks/mod.rs new file mode 100644 index 00000000..43afbc3e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/mod.rs @@ -0,0 +1,1947 @@ +//! Interface to VxWorks C library + +use core::mem::size_of; +use core::ptr::null_mut; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +impl ::Copy for DIR {} +impl ::Clone for DIR { + fn clone(&self) -> DIR { + *self + } +} + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type uintptr_t = usize; +pub type intptr_t = isize; +pub type ptrdiff_t = isize; +pub type size_t = ::uintptr_t; +pub type ssize_t = ::intptr_t; + +pub type pid_t = ::c_int; +pub type in_addr_t = u32; +pub type sighandler_t = ::size_t; +pub type cpuset_t = u32; + +pub type blkcnt_t = ::c_long; +pub type blksize_t = ::c_long; +pub type ino_t = ::c_ulong; + +pub type rlim_t = ::c_ulong; +pub type suseconds_t = ::c_long; +pub type time_t = ::c_long; + +pub type errno_t = ::c_int; + +pub type useconds_t = ::c_ulong; + +pub type socklen_t = ::c_uint; + +pub type pthread_t = ::c_ulong; + +pub type clockid_t = ::c_int; + +//defined for the structs +pub type dev_t = ::c_ulong; +pub type mode_t = ::c_int; +pub type nlink_t = ::c_ulong; +pub type uid_t = ::c_ushort; +pub type gid_t = ::c_ushort; +pub type sigset_t = ::c_ulonglong; +pub type key_t = ::c_long; + +pub type nfds_t = ::c_uint; +pub type stat64 = ::stat; + +pub type pthread_key_t = ::c_ulong; + +// From b_off_t.h +pub type off_t = ::c_longlong; +pub type off64_t = off_t; + +// From b_BOOL.h +pub type BOOL = ::c_int; + +// From vxWind.h .. +pub type _Vx_OBJ_HANDLE = ::c_int; +pub type _Vx_TASK_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_MSG_Q_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_SEM_ID_KERNEL = ::_Vx_OBJ_HANDLE; +pub type _Vx_RTP_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_SD_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_CONDVAR_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_SEM_ID = *mut ::_Vx_semaphore; +pub type OBJ_HANDLE = ::_Vx_OBJ_HANDLE; +pub type TASK_ID = ::OBJ_HANDLE; +pub type MSG_Q_ID = ::OBJ_HANDLE; +pub type SEM_ID_KERNEL = ::OBJ_HANDLE; +pub type RTP_ID = ::OBJ_HANDLE; +pub type SD_ID = ::OBJ_HANDLE; +pub type CONDVAR_ID = ::OBJ_HANDLE; + +// From vxTypes.h +pub type _Vx_usr_arg_t = isize; +pub type _Vx_exit_code_t = isize; +pub type _Vx_ticks_t = ::c_uint; +pub type _Vx_ticks64_t = ::c_ulonglong; + +pub type sa_family_t = ::c_uchar; + +// mqueue.h +pub type mqd_t = ::c_int; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum _Vx_semaphore {} +impl ::Copy for _Vx_semaphore {} +impl ::Clone for _Vx_semaphore { + fn clone(&self) -> _Vx_semaphore { + *self + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.si_status + } +} + +s! { + // b_pthread_condattr_t.h + pub struct pthread_condattr_t { + pub condAttrStatus: ::c_int, + pub condAttrPshared: ::c_int, + pub condAttrClockId: ::clockid_t, + } + + // b_pthread_cond_t.h + pub struct pthread_cond_t{ + pub condSemId: ::_Vx_SEM_ID, + pub condValid: ::c_int, + pub condInitted: ::c_int, + pub condRefCount: ::c_int, + pub condMutex: *mut ::pthread_mutex_t, + pub condAttr: ::pthread_condattr_t, + pub condSemName: [::c_char; _PTHREAD_SHARED_SEM_NAME_MAX] + } + + // b_pthread_rwlockattr_t.h + pub struct pthread_rwlockattr_t { + pub rwlockAttrStatus: ::c_int, + pub rwlockAttrPshared: ::c_int, + pub rwlockAttrMaxReaders: ::c_uint, + pub rwlockAttrConformOpt: ::c_uint, + } + + // b_pthread_rwlock_t.h + pub struct pthread_rwlock_t { + pub rwlockSemId: :: _Vx_SEM_ID, + pub rwlockReadersRefCount: ::c_uint, + pub rwlockValid: ::c_int, + pub rwlockInitted: ::c_int, + pub rwlockAttr: ::pthread_rwlockattr_t, + pub rwlockSemName: [::c_char; _PTHREAD_SHARED_SEM_NAME_MAX] + } + + // b_struct_timeval.h + pub struct timeval { + pub tv_sec: ::time_t, + pub tv_usec: ::suseconds_t, + } + + // socket.h + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct sockaddr { + pub sa_len : ::c_uchar, + pub sa_family : sa_family_t, + pub sa_data : [::c_char; 14], + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: ::size_t, + } + + pub struct msghdr { + pub msg_name: *mut c_void, + pub msg_namelen: socklen_t, + pub msg_iov: *mut iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut c_void, + pub msg_controllen: socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + // poll.h + pub struct pollfd { + pub fd : ::c_int, + pub events : ::c_short, + pub revents : ::c_short, + } + + // resource.h + pub struct rlimit { + pub rlim_cur : ::rlim_t, + pub rlim_max : ::rlim_t, + } + + // stat.h + pub struct stat { + pub st_dev : ::dev_t, + pub st_ino : ::ino_t, + pub st_mode : ::mode_t, + pub st_nlink : ::nlink_t, + pub st_uid : ::uid_t, + pub st_gid : ::gid_t, + pub st_rdev : ::dev_t, + pub st_size : ::off_t, + pub st_atime : ::time_t, + pub st_mtime : ::time_t, + pub st_ctime : ::time_t, + pub st_blksize : ::blksize_t, + pub st_blocks : ::blkcnt_t, + pub st_attrib : ::c_uchar, + pub st_reserved1 : ::c_int, + pub st_reserved2 : ::c_int, + pub st_reserved3 : ::c_int, + pub st_reserved4 : ::c_int, + } + + //b_struct__Timespec.h + pub struct _Timespec { + pub tv_sec : ::time_t, + pub tv_nsec : ::c_long, + } + + // b_struct__Sched_param.h + pub struct _Sched_param { + pub sched_priority: ::c_int, /* scheduling priority */ + pub sched_ss_low_priority: ::c_int, /* low scheduling priority */ + pub sched_ss_repl_period: ::_Timespec, /* replenishment period */ + pub sched_ss_init_budget: ::_Timespec, /* initial budget */ + pub sched_ss_max_repl: ::c_int, /* max pending replenishment */ + + } + + // b_pthread_attr_t.h + pub struct pthread_attr_t { + pub threadAttrStatus : ::c_int, + pub threadAttrStacksize : ::size_t, + pub threadAttrStackaddr : *mut ::c_void, + pub threadAttrGuardsize : ::size_t, + pub threadAttrDetachstate : ::c_int, + pub threadAttrContentionscope : ::c_int, + pub threadAttrInheritsched : ::c_int, + pub threadAttrSchedpolicy : ::c_int, + pub threadAttrName : *mut ::c_char, + pub threadAttrOptions : ::c_int, + pub threadAttrSchedparam : ::_Sched_param, + } + + // signal.h + + pub struct sigaction { + pub sa_u : ::sa_u_t, + pub sa_mask : ::sigset_t, + pub sa_flags : ::c_int, + } + + // b_stack_t.h + pub struct stack_t { + pub ss_sp : *mut ::c_void, + pub ss_size : ::size_t, + pub ss_flags : ::c_int, + } + + // signal.h + pub struct siginfo_t { + pub si_signo : ::c_int, + pub si_code : ::c_int, + pub si_value : ::sigval, + pub si_errno : ::c_int, + pub si_status: ::c_int, + pub si_addr: *mut ::c_void, + pub si_uid: ::uid_t, + pub si_pid: ::pid_t, + } + + // pthread.h (krnl) + // b_pthread_mutexattr_t.h (usr) + pub struct pthread_mutexattr_t { + mutexAttrStatus : ::c_int, + mutexAttrPshared : ::c_int, + mutexAttrProtocol : ::c_int, + mutexAttrPrioceiling : ::c_int, + mutexAttrType : ::c_int, + } + + // pthread.h (krnl) + // b_pthread_mutex_t.h (usr) + pub struct pthread_mutex_t { + pub mutexSemId: ::_Vx_SEM_ID, /*_Vx_SEM_ID ..*/ + pub mutexValid: ::c_int, + pub mutexInitted: ::c_int, + pub mutexCondRefCount: ::c_int, + pub mutexSavPriority: ::c_int, + pub mutexAttr: ::pthread_mutexattr_t, + pub mutexSemName: [::c_char; _PTHREAD_SHARED_SEM_NAME_MAX], + } + + // b_struct_timespec.h + pub struct timespec { + pub tv_sec: ::time_t, + pub tv_nsec: ::c_long, + } + + // time.h + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + } + + // in.h + pub struct in_addr { + pub s_addr: in_addr_t, + } + + // in.h + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + // in6.h + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + // in6.h + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: ::c_uint, + } + + // netdb.h + pub struct addrinfo { + pub ai_flags : ::c_int, + pub ai_family : ::c_int, + pub ai_socktype : ::c_int, + pub ai_protocol : ::c_int, + pub ai_addrlen : ::size_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr : *mut ::sockaddr, + pub ai_next : *mut ::addrinfo, + } + + // in.h + pub struct sockaddr_in { + pub sin_len : u8, + pub sin_family: u8, + pub sin_port : u16, + pub sin_addr : ::in_addr, + pub sin_zero : [::c_char; 8], + } + + // in6.h + pub struct sockaddr_in6 { + pub sin6_len : u8, + pub sin6_family : u8, + pub sin6_port : u16, + pub sin6_flowinfo: u32, + pub sin6_addr : ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct mq_attr { + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_flags: ::c_long, + pub mq_curmsgs: ::c_long, + } +} + +s_no_extra_traits! { + // dirent.h + pub struct dirent { + pub d_ino : ::ino_t, + pub d_name : [::c_char; _PARM_NAME_MAX as usize + 1], + } + + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 104] + } + + // rtpLibCommon.h + pub struct RTP_DESC { + pub status : ::c_int, + pub options : u32, + pub entrAddr : *mut ::c_void, + pub initTaskId: ::TASK_ID, + pub parentId : ::RTP_ID, + pub pathName : [::c_char; VX_RTP_NAME_LENGTH as usize + 1], + pub taskCnt : ::c_int, + pub textStart : *mut ::c_void, + pub textEnd : *mut ::c_void, + } + // socket.h + pub struct sockaddr_storage { + pub ss_len : ::c_uchar, + pub ss_family : ::sa_family_t, + pub __ss_pad1 : [::c_char; _SS_PAD1SIZE], + pub __ss_align : i32, + pub __ss_pad2 : [::c_char; _SS_PAD2SIZE], + } + + pub union sa_u_t { + pub sa_handler : ::Option !>, + pub sa_sigaction: ::Option !>, + } + + pub union sigval { + pub sival_int : ::c_int, + pub sival_ptr : *mut ::c_void, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_name", &&self.d_name[..]) + .finish() + } + } + + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_len", &self.sun_len) + .field("sun_family", &self.sun_family) + .field("sun_path", &&self.sun_path[..]) + .finish() + } + } + + impl ::fmt::Debug for RTP_DESC { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("RTP_DESC") + .field("status", &self.status) + .field("options", &self.options) + .field("entrAddr", &self.entrAddr) + .field("initTaskId", &self.initTaskId) + .field("parentId", &self.parentId) + .field("pathName", &&self.pathName[..]) + .field("taskCnt", &self.taskCnt) + .field("textStart", &self.textStart) + .field("textEnd", &self.textEnd) + .finish() + } + } + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &&self.__ss_pad1[..]) + .field("__ss_align", &self.__ss_align) + .field("__ss_pad2", &&self.__ss_pad2[..]) + .finish() + } + } + + impl PartialEq for sa_u_t { + fn eq(&self, other: &sa_u_t) -> bool { + unsafe { + let h1 = match self.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + let h2 = match other.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + h1 == h2 + } + } + } + impl Eq for sa_u_t {} + impl ::fmt::Debug for sa_u_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + let h = match self.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + + f.debug_struct("sa_u_t") + .field("sa_handler", &h) + .finish() + } + } + } + impl ::hash::Hash for sa_u_t { + fn hash(&self, state: &mut H) { + unsafe { + let h = match self.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + h.hash(state) + } + } + } + + impl PartialEq for sigval { + fn eq(&self, other: &sigval) -> bool { + unsafe { self.sival_ptr as usize == other.sival_ptr as usize } + } + } + impl Eq for sigval {} + impl ::fmt::Debug for sigval { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigval") + .field("sival_ptr", unsafe { &(self.sival_ptr as usize) }) + .finish() + } + } + impl ::hash::Hash for sigval { + fn hash(&self, state: &mut H) { + unsafe { (self.sival_ptr as usize).hash(state) }; + } + } + } +} + +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const EXIT_SUCCESS: ::c_int = 0; +pub const EXIT_FAILURE: ::c_int = 1; + +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; + +// FIXME: This is not defined in vxWorks, but we have to define it here +// to make the building pass for getrandom and std +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; + +//Clock Lib Stuff +pub const CLOCK_REALTIME: ::c_int = 0x0; +pub const CLOCK_MONOTONIC: ::c_int = 0x1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::c_int = 0x2; +pub const CLOCK_THREAD_CPUTIME_ID: ::c_int = 0x3; +pub const TIMER_ABSTIME: ::c_int = 0x1; +pub const TIMER_RELTIME: ::c_int = 0x0; + +// PTHREAD STUFF +pub const PTHREAD_INITIALIZED_OBJ: ::c_int = 0xF70990EF; +pub const PTHREAD_DESTROYED_OBJ: ::c_int = -1; +pub const PTHREAD_VALID_OBJ: ::c_int = 0xEC542A37; +pub const PTHREAD_INVALID_OBJ: ::c_int = -1; +pub const PTHREAD_UNUSED_YET_OBJ: ::c_int = -1; + +pub const PTHREAD_PRIO_NONE: ::c_int = 0; +pub const PTHREAD_PRIO_INHERIT: ::c_int = 1; +pub const PTHREAD_PRIO_PROTECT: ::c_int = 2; + +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_STACK_MIN: usize = 4096; +pub const _PTHREAD_SHARED_SEM_NAME_MAX: usize = 30; + +// ERRNO STUFF +pub const OK: ::c_int = 0; +pub const EPERM: ::c_int = 1; /* Not owner */ +pub const ENOENT: ::c_int = 2; /* No such file or directory */ +pub const ESRCH: ::c_int = 3; /* No such process */ +pub const EINTR: ::c_int = 4; /* Interrupted system call */ +pub const EIO: ::c_int = 5; /* I/O error */ +pub const ENXIO: ::c_int = 6; /* No such device or address */ +pub const E2BIG: ::c_int = 7; /* Arg list too long */ +pub const ENOEXEC: ::c_int = 8; /* Exec format error */ +pub const EBADF: ::c_int = 9; /* Bad file number */ +pub const ECHILD: ::c_int = 10; /* No children */ +pub const EAGAIN: ::c_int = 11; /* No more processes */ +pub const ENOMEM: ::c_int = 12; /* Not enough core */ +pub const EACCES: ::c_int = 13; /* Permission denied */ +pub const EFAULT: ::c_int = 14; +pub const ENOTEMPTY: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENAMETOOLONG: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDEADLK: ::c_int = 33; +pub const ERANGE: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENOTSOCK: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +pub const ESHUTDOWN: ::c_int = 58; +pub const ETOOMANYREFS: ::c_int = 59; +pub const ETIMEDOUT: ::c_int = 60; +pub const ECONNREFUSED: ::c_int = 61; +pub const ENETDOWN: ::c_int = 62; +pub const ETXTBSY: ::c_int = 63; +pub const ELOOP: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const EINPROGRESS: ::c_int = 68; +pub const EALREADY: ::c_int = 69; +pub const EWOULDBLOCK: ::c_int = 70; +pub const ENOSYS: ::c_int = 71; +pub const EDQUOT: ::c_int = 83; +pub const ESTALE: ::c_int = 88; + +// NFS errnos: Refer to pkgs_v2/storage/fs/nfs/h/nfs/nfsCommon.h +const M_nfsStat: ::c_int = 48 << 16; +enum nfsstat { + NFSERR_REMOTE = 71, + NFSERR_WFLUSH = 99, + NFSERR_BADHANDLE = 10001, + NFSERR_NOT_SYNC = 10002, + NFSERR_BAD_COOKIE = 10003, + NFSERR_TOOSMALL = 10005, + NFSERR_BADTYPE = 10007, + NFSERR_JUKEBOX = 10008, +} + +pub const S_nfsLib_NFS_OK: ::c_int = OK; +pub const S_nfsLib_NFSERR_PERM: ::c_int = EPERM; +pub const S_nfsLib_NFSERR_NOENT: ::c_int = ENOENT; +pub const S_nfsLib_NFSERR_IO: ::c_int = EIO; +pub const S_nfsLib_NFSERR_NXIO: ::c_int = ENXIO; +pub const S_nfsLib_NFSERR_ACCESS: ::c_int = EACCES; +pub const S_nfsLib_NFSERR_EXIST: ::c_int = EEXIST; +pub const S_nfsLib_NFSERR_ENODEV: ::c_int = ENODEV; +pub const S_nfsLib_NFSERR_NOTDIR: ::c_int = ENOTDIR; +pub const S_nfsLib_NFSERR_ISDIR: ::c_int = EISDIR; +pub const S_nfsLib_NFSERR_INVAL: ::c_int = EINVAL; +pub const S_nfsLib_NFSERR_FBIG: ::c_int = EFBIG; +pub const S_nfsLib_NFSERR_NOSPC: ::c_int = ENOSPC; +pub const S_nfsLib_NFSERR_ROFS: ::c_int = EROFS; +pub const S_nfsLib_NFSERR_NAMETOOLONG: ::c_int = ENAMETOOLONG; +pub const S_nfsLib_NFSERR_NOTEMPTY: ::c_int = ENOTEMPTY; +pub const S_nfsLib_NFSERR_DQUOT: ::c_int = EDQUOT; +pub const S_nfsLib_NFSERR_STALE: ::c_int = ESTALE; +pub const S_nfsLib_NFSERR_WFLUSH: ::c_int = M_nfsStat | nfsstat::NFSERR_WFLUSH as ::c_int; +pub const S_nfsLib_NFSERR_REMOTE: ::c_int = M_nfsStat | nfsstat::NFSERR_REMOTE as ::c_int; +pub const S_nfsLib_NFSERR_BADHANDLE: ::c_int = M_nfsStat | nfsstat::NFSERR_BADHANDLE as ::c_int; +pub const S_nfsLib_NFSERR_NOT_SYNC: ::c_int = M_nfsStat | nfsstat::NFSERR_NOT_SYNC as ::c_int; +pub const S_nfsLib_NFSERR_BAD_COOKIE: ::c_int = M_nfsStat | nfsstat::NFSERR_BAD_COOKIE as ::c_int; +pub const S_nfsLib_NFSERR_NOTSUPP: ::c_int = EOPNOTSUPP; +pub const S_nfsLib_NFSERR_TOOSMALL: ::c_int = M_nfsStat | nfsstat::NFSERR_TOOSMALL as ::c_int; +pub const S_nfsLib_NFSERR_SERVERFAULT: ::c_int = EIO; +pub const S_nfsLib_NFSERR_BADTYPE: ::c_int = M_nfsStat | nfsstat::NFSERR_BADTYPE as ::c_int; +pub const S_nfsLib_NFSERR_JUKEBOX: ::c_int = M_nfsStat | nfsstat::NFSERR_JUKEBOX as ::c_int; + +// in.h +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const IP_TTL: ::c_int = 4; +pub const IP_MULTICAST_IF: ::c_int = 9; +pub const IP_MULTICAST_TTL: ::c_int = 10; +pub const IP_MULTICAST_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; + +// in6.h +pub const IPV6_V6ONLY: ::c_int = 1; +pub const IPV6_UNICAST_HOPS: ::c_int = 4; +pub const IPV6_MULTICAST_IF: ::c_int = 9; +pub const IPV6_MULTICAST_HOPS: ::c_int = 10; +pub const IPV6_MULTICAST_LOOP: ::c_int = 11; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 12; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 13; + +// STAT Stuff +pub const S_IFMT: ::c_int = 0xf000; +pub const S_IFIFO: ::c_int = 0x1000; +pub const S_IFCHR: ::c_int = 0x2000; +pub const S_IFDIR: ::c_int = 0x4000; +pub const S_IFBLK: ::c_int = 0x6000; +pub const S_IFREG: ::c_int = 0x8000; +pub const S_IFLNK: ::c_int = 0xa000; +pub const S_IFSHM: ::c_int = 0xb000; +pub const S_IFSOCK: ::c_int = 0xc000; +pub const S_ISUID: ::c_int = 0x0800; +pub const S_ISGID: ::c_int = 0x0400; +pub const S_ISTXT: ::c_int = 0x0200; +pub const S_IRUSR: ::c_int = 0x0100; +pub const S_IWUSR: ::c_int = 0x0080; +pub const S_IXUSR: ::c_int = 0x0040; +pub const S_IRWXU: ::c_int = 0x01c0; +pub const S_IRGRP: ::c_int = 0x0020; +pub const S_IWGRP: ::c_int = 0x0010; +pub const S_IXGRP: ::c_int = 0x0008; +pub const S_IRWXG: ::c_int = 0x0038; +pub const S_IROTH: ::c_int = 0x0004; +pub const S_IWOTH: ::c_int = 0x0002; +pub const S_IXOTH: ::c_int = 0x0001; +pub const S_IRWXO: ::c_int = 0x0007; + +// socket.h +pub const SOL_SOCKET: ::c_int = 0xffff; + +pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_RCVLOWAT: ::c_int = 0x0012; +pub const SO_SNDLOWAT: ::c_int = 0x0013; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_ACCEPTCONN: ::c_int = 0x001e; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_REUSEPORT: ::c_int = 0x0200; + +pub const SO_VLAN: ::c_int = 0x8000; + +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_BINDTODEVICE: ::c_int = 0x1010; +pub const SO_OOBINLINE: ::c_int = 0x1011; +pub const SO_CONNTIMEO: ::c_int = 0x100a; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_PACKET: ::c_int = 10; + +pub const _SS_MAXSIZE: usize = 128; +pub const _SS_ALIGNSIZE: usize = size_of::(); +pub const _SS_PAD1SIZE: usize = _SS_ALIGNSIZE - size_of::<::c_uchar>() - size_of::<::sa_family_t>(); +pub const _SS_PAD2SIZE: usize = _SS_MAXSIZE + - size_of::<::c_uchar>() + - size_of::<::sa_family_t>() + - _SS_PAD1SIZE + - _SS_ALIGNSIZE; + +pub const MSG_OOB: ::c_int = 0x0001; +pub const MSG_PEEK: ::c_int = 0x0002; +pub const MSG_DONTROUTE: ::c_int = 0x0004; +pub const MSG_EOR: ::c_int = 0x0008; +pub const MSG_TRUNC: ::c_int = 0x0010; +pub const MSG_CTRUNC: ::c_int = 0x0020; +pub const MSG_WAITALL: ::c_int = 0x0040; +pub const MSG_DONTWAIT: ::c_int = 0x0080; +pub const MSG_EOF: ::c_int = 0x0100; +pub const MSG_EXP: ::c_int = 0x0200; +pub const MSG_MBUF: ::c_int = 0x0400; +pub const MSG_NOTIFICATION: ::c_int = 0x0800; +pub const MSG_COMPAT: ::c_int = 0x8000; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_INET: ::c_int = 2; +pub const AF_NETLINK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const AF_PACKET: ::c_int = 19; +pub const pseudo_AF_KEY: ::c_int = 27; +pub const AF_KEY: ::c_int = pseudo_AF_KEY; +pub const AF_INET6: ::c_int = 28; +pub const AF_SOCKDEV: ::c_int = 31; +pub const AF_TIPC: ::c_int = 33; +pub const AF_MIPC: ::c_int = 34; +pub const AF_MIPC_SAFE: ::c_int = 35; +pub const AF_MAX: ::c_int = 37; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const IPPROTO_TCP: ::c_int = 6; +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; +pub const TCP_NOPUSH: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; + +// ioLib.h +pub const FIONREAD: ::c_int = 0x40040001; +pub const FIOFLUSH: ::c_int = 2; +pub const FIOOPTIONS: ::c_int = 3; +pub const FIOBAUDRATE: ::c_int = 4; +pub const FIODISKFORMAT: ::c_int = 5; +pub const FIODISKINIT: ::c_int = 6; +pub const FIOSEEK: ::c_int = 7; +pub const FIOWHERE: ::c_int = 8; +pub const FIODIRENTRY: ::c_int = 9; +pub const FIORENAME: ::c_int = 10; +pub const FIOREADYCHANGE: ::c_int = 11; +pub const FIODISKCHANGE: ::c_int = 13; +pub const FIOCANCEL: ::c_int = 14; +pub const FIOSQUEEZE: ::c_int = 15; +pub const FIOGETNAME: ::c_int = 18; +pub const FIONBIO: ::c_int = 0x90040010; + +// limits.h +pub const PATH_MAX: ::c_int = _PARM_PATH_MAX; +pub const _POSIX_PATH_MAX: ::c_int = 256; + +// Some poll stuff +pub const POLLIN: ::c_short = 0x0001; +pub const POLLPRI: ::c_short = 0x0002; +pub const POLLOUT: ::c_short = 0x0004; +pub const POLLRDNORM: ::c_short = 0x0040; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLRDBAND: ::c_short = 0x0080; +pub const POLLWRBAND: ::c_short = 0x0100; +pub const POLLERR: ::c_short = 0x0008; +pub const POLLHUP: ::c_short = 0x0010; +pub const POLLNVAL: ::c_short = 0x0020; + +// fnctlcom.h +pub const FD_CLOEXEC: ::c_int = 1; +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_DUPFD_CLOEXEC: ::c_int = 14; + +// signal.h +pub const SIG_DFL: sighandler_t = 0 as sighandler_t; +pub const SIG_IGN: sighandler_t = 1 as sighandler_t; +pub const SIG_ERR: sighandler_t = -1 as isize as sighandler_t; + +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGTRAP: ::c_int = 5; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGBUS: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGFMT: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGCNCL: ::c_int = 16; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGCONT: ::c_int = 19; +pub const SIGCHLD: ::c_int = 20; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; + +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +pub const SI_SYNC: ::c_int = 0; +pub const SI_USER: ::c_int = -1; +pub const SI_QUEUE: ::c_int = -2; +pub const SI_TIMER: ::c_int = -3; +pub const SI_ASYNCIO: ::c_int = -4; +pub const SI_MESGQ: ::c_int = -5; +pub const SI_CHILD: ::c_int = -6; +pub const SI_KILL: ::c_int = SI_USER; + +// vxParams.h definitions +pub const _PARM_NAME_MAX: ::c_int = 255; +pub const _PARM_PATH_MAX: ::c_int = 1024; + +// WAIT STUFF +pub const WNOHANG: ::c_int = 0x01; +pub const WUNTRACED: ::c_int = 0x02; + +const PTHREAD_MUTEXATTR_INITIALIZER: pthread_mutexattr_t = pthread_mutexattr_t { + mutexAttrStatus: PTHREAD_INITIALIZED_OBJ, + mutexAttrProtocol: PTHREAD_PRIO_NONE, + mutexAttrPrioceiling: 0, + mutexAttrType: PTHREAD_MUTEX_DEFAULT, + mutexAttrPshared: 1, +}; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + mutexSemId: null_mut(), + mutexValid: PTHREAD_VALID_OBJ, + mutexInitted: PTHREAD_UNUSED_YET_OBJ, + mutexCondRefCount: 0, + mutexSavPriority: -1, + mutexAttr: PTHREAD_MUTEXATTR_INITIALIZER, + mutexSemName: [0; _PTHREAD_SHARED_SEM_NAME_MAX], +}; + +const PTHREAD_CONDATTR_INITIALIZER: pthread_condattr_t = pthread_condattr_t { + condAttrStatus: 0xf70990ef, + condAttrPshared: 1, + condAttrClockId: CLOCK_REALTIME, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + condSemId: null_mut(), + condValid: PTHREAD_VALID_OBJ, + condInitted: PTHREAD_UNUSED_YET_OBJ, + condRefCount: 0, + condMutex: null_mut(), + condAttr: PTHREAD_CONDATTR_INITIALIZER, + condSemName: [0; _PTHREAD_SHARED_SEM_NAME_MAX], +}; + +const PTHREAD_RWLOCKATTR_INITIALIZER: pthread_rwlockattr_t = pthread_rwlockattr_t { + rwlockAttrStatus: PTHREAD_INITIALIZED_OBJ, + rwlockAttrPshared: 1, + rwlockAttrMaxReaders: 0, + rwlockAttrConformOpt: 1, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + rwlockSemId: null_mut(), + rwlockReadersRefCount: 0, + rwlockValid: PTHREAD_VALID_OBJ, + rwlockInitted: PTHREAD_UNUSED_YET_OBJ, + rwlockAttr: PTHREAD_RWLOCKATTR_INITIALIZER, + rwlockSemName: [0; _PTHREAD_SHARED_SEM_NAME_MAX], +}; + +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; + +// rtpLibCommon.h +pub const VX_RTP_NAME_LENGTH: ::c_int = 255; +pub const RTP_ID_ERROR: ::RTP_ID = -1; + +// h/public/unistd.h +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 21; // Via unistd.h +pub const _SC_PAGESIZE: ::c_int = 39; +pub const O_ACCMODE: ::c_int = 3; +pub const O_CLOEXEC: ::c_int = 0x100000; // fcntlcom +pub const O_EXCL: ::c_int = 0x0800; +pub const O_CREAT: ::c_int = 0x0200; +pub const O_TRUNC: ::c_int = 0x0400; +pub const O_APPEND: ::c_int = 0x0008; +pub const O_RDWR: ::c_int = 0x0002; +pub const O_WRONLY: ::c_int = 0x0001; +pub const O_RDONLY: ::c_int = 0; +pub const O_NONBLOCK: ::c_int = 0x4000; + +// mman.h +pub const PROT_NONE: ::c_int = 0x0000; +pub const PROT_READ: ::c_int = 0x0001; +pub const PROT_WRITE: ::c_int = 0x0002; +pub const PROT_EXEC: ::c_int = 0x0004; + +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_ANON: ::c_int = 0x0004; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_CONTIG: ::c_int = 0x0020; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +f! { + pub {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + let next = cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize) + + CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next <= max { + (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } else { + 0 as *mut ::cmsghdr + } + } + + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize > 0 { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } +} + +extern "C" { + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn isblank(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); + pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; + pub fn atol(s: *const c_char) -> c_long; + pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; + pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; + pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; + pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn atexit(cb: extern "C" fn()) -> c_int; + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; +} + +extern "C" { + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + pub fn fchown(fd: ::c_int, owner: ::uid_t, group: ::gid_t) -> ::c_int; + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn alarm(seconds: ::c_uint) -> ::c_uint; + pub fn fchdir(dirfd: ::c_int) -> ::c_int; + pub fn chown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getegid() -> gid_t; + pub fn geteuid() -> uid_t; + pub fn getgroups(ngroups_max: ::c_int, groups: *mut gid_t) -> ::c_int; + pub fn getlogin() -> *mut c_char; + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pause() -> ::c_int; + pub fn seteuid(uid: uid_t) -> ::c_int; + pub fn setegid(gid: gid_t) -> ::c_int; + pub fn sleep(secs: ::c_uint) -> ::c_uint; + pub fn ttyname(fd: ::c_int) -> *mut c_char; + pub fn wait(status: *mut ::c_int) -> pid_t; + pub fn umask(mask: mode_t) -> mode_t; + pub fn mlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn mlockall(flags: ::c_int) -> ::c_int; + pub fn munlockall() -> ::c_int; + + pub fn mmap( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off_t, + ) -> *mut ::c_void; + pub fn munmap(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + pub fn truncate(path: *const c_char, length: off_t) -> ::c_int; + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn pthread_exit(value: *mut ::c_void) -> !; + pub fn pthread_attr_setdetachstate(attr: *mut ::pthread_attr_t, state: ::c_int) -> ::c_int; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn sigaddset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + + pub fn sigaction(signum: ::c_int, act: *const sigaction, oldact: *mut sigaction) -> ::c_int; + + pub fn utimes(filename: *const ::c_char, times: *const ::timeval) -> ::c_int; + + #[link_name = "_rtld_dlopen"] + pub fn dlopen(filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + + #[link_name = "_rtld_dlerror"] + pub fn dlerror() -> *mut ::c_char; + + #[link_name = "_rtld_dlsym"] + pub fn dlsym(handle: *mut ::c_void, symbol: *const ::c_char) -> *mut ::c_void; + + #[link_name = "_rtld_dlclose"] + pub fn dlclose(handle: *mut ::c_void) -> ::c_int; + + #[link_name = "_rtld_dladdr"] + pub fn dladdr(addr: *mut ::c_void, info: *mut Dl_info) -> ::c_int; + + // time.h + pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn localtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn mktime(tm: *mut tm) -> time_t; + pub fn time(time: *mut time_t) -> time_t; + pub fn gmtime(time_p: *const time_t) -> *mut tm; + pub fn localtime(time_p: *const time_t) -> *mut tm; + pub fn timegm(tm: *mut tm) -> time_t; + pub fn difftime(time1: time_t, time0: time_t) -> ::c_double; + pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn usleep(secs: ::useconds_t) -> ::c_int; + pub fn putenv(string: *mut c_char) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + + pub fn sigprocmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sigpending(set: *mut sigset_t) -> ::c_int; + + pub fn mkfifo(path: *const c_char, mode: mode_t) -> ::c_int; + + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + pub fn mkstemp(template: *mut ::c_char) -> ::c_int; + + pub fn tmpnam(ptr: *mut ::c_char) -> *mut ::c_char; + + pub fn openlog(ident: *const ::c_char, logopt: ::c_int, facility: ::c_int); + pub fn closelog(); + pub fn setlogmask(maskpri: ::c_int) -> ::c_int; + pub fn syslog(priority: ::c_int, message: *const ::c_char, ...); + pub fn getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t; + +} + +extern "C" { + // stdlib.h + pub fn memalign(block_size: ::size_t, size_arg: ::size_t) -> *mut ::c_void; + + // ioLib.h + pub fn getcwd(buf: *mut ::c_char, size: ::size_t) -> *mut ::c_char; + + // ioLib.h + pub fn chdir(attr: *const ::c_char) -> ::c_int; + + // pthread.h + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutexattr_settype(pAttr: *mut ::pthread_mutexattr_t, pType: ::c_int) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_init( + mutex: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_timedlock(attr: *mut pthread_mutex_t, spec: *const timespec) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_attr_setname(pAttr: *mut ::pthread_attr_t, name: *mut ::c_char) -> ::c_int; + + // pthread.h + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stacksize: ::size_t) -> ::c_int; + + // pthread.h + pub fn pthread_attr_getstacksize(attr: *const ::pthread_attr_t, size: *mut ::size_t) + -> ::c_int; + + // pthread.h + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + + // pthread.h + pub fn pthread_create( + pThread: *mut ::pthread_t, + pAttr: *const ::pthread_attr_t, + start_routine: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + + // pthread.h + pub fn pthread_attr_destroy(thread: *mut ::pthread_attr_t) -> ::c_int; + + // pthread.h + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + + // int pthread_atfork (void (*)(void), void (*)(void), void (*)(void)); + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + // stat.h + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + + // stat.h + pub fn lstat(path: *const ::c_char, buf: *mut stat) -> ::c_int; + + // unistd.h + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + // dirent.h + pub fn readdir_r(pDir: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) + -> ::c_int; + + // dirent.h + pub fn readdir(pDir: *mut ::DIR) -> *mut ::dirent; + + // fcntl.h or + // ioLib.h + pub fn open(path: *const ::c_char, oflag: ::c_int, ...) -> ::c_int; + + // poll.h + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_init(attr: *mut ::pthread_condattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_destroy(attr: *mut ::pthread_condattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_getclock( + pAttr: *const ::pthread_condattr_t, + pClockId: *mut ::clockid_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_setclock( + pAttr: *mut ::pthread_condattr_t, + clockId: ::clockid_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_cond_init( + cond: *mut ::pthread_cond_t, + attr: *const ::pthread_condattr_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int; + + // pthread.h + pub fn pthread_cond_signal(cond: *mut ::pthread_cond_t) -> ::c_int; + + // pthread.h + pub fn pthread_cond_broadcast(cond: *mut ::pthread_cond_t) -> ::c_int; + + // pthread.h + pub fn pthread_cond_wait(cond: *mut ::pthread_cond_t, mutex: *mut ::pthread_mutex_t) + -> ::c_int; + + // pthread.h + pub fn pthread_rwlockattr_init(attr: *mut ::pthread_rwlockattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlockattr_destroy(attr: *mut ::pthread_rwlockattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlockattr_setmaxreaders( + attr: *mut ::pthread_rwlockattr_t, + attr2: ::c_uint, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_init( + attr: *mut ::pthread_rwlock_t, + host: *const ::pthread_rwlockattr_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_destroy(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_rdlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_tryrdlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_timedrdlock( + attr: *mut ::pthread_rwlock_t, + host: *const ::timespec, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_wrlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_trywrlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_timedwrlock( + attr: *mut ::pthread_rwlock_t, + host: *const ::timespec, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_unlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_key_create( + key: *mut ::pthread_key_t, + dtor: ::Option, + ) -> ::c_int; + + // pthread.h + pub fn pthread_key_delete(key: ::pthread_key_t) -> ::c_int; + + // pthread.h + pub fn pthread_setspecific(key: ::pthread_key_t, value: *const ::c_void) -> ::c_int; + + // pthread.h + pub fn pthread_getspecific(key: ::pthread_key_t) -> *mut ::c_void; + + // pthread.h + pub fn pthread_cond_timedwait( + cond: *mut ::pthread_cond_t, + mutex: *mut ::pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + + // pthread.h + pub fn pthread_attr_getname(attr: *mut ::pthread_attr_t, name: *mut *mut ::c_char) -> ::c_int; + + // pthread.h + pub fn pthread_join(thread: ::pthread_t, status: *mut *mut ::c_void) -> ::c_int; + + // pthread.h + pub fn pthread_self() -> ::pthread_t; + + // clockLib.h + pub fn clock_gettime(clock_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + + // clockLib.h + pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + + // clockLib.h + pub fn clock_getres(clock_id: ::clockid_t, res: *mut ::timespec) -> ::c_int; + + // clockLib.h + pub fn clock_nanosleep( + clock_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + + // timerLib.h + pub fn nanosleep(rqtp: *const ::timespec, rmtp: *mut ::timespec) -> ::c_int; + + // socket.h + pub fn accept(s: ::c_int, addr: *mut ::sockaddr, addrlen: *mut ::socklen_t) -> ::c_int; + + // socket.h + pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) -> ::c_int; + + // socket.h + pub fn connect(s: ::c_int, name: *const ::sockaddr, namelen: ::socklen_t) -> ::c_int; + + // socket.h + pub fn getpeername(s: ::c_int, name: *mut ::sockaddr, namelen: *mut ::socklen_t) -> ::c_int; + + // socket.h + pub fn getsockname( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + + // socket.h + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + + // socket.h + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + + // socket.h + pub fn recv(s: ::c_int, buf: *mut ::c_void, bufLen: ::size_t, flags: ::c_int) -> ::ssize_t; + + // socket.h + pub fn recvfrom( + s: ::c_int, + buf: *mut ::c_void, + bufLen: ::size_t, + flags: ::c_int, + from: *mut ::sockaddr, + pFromLen: *mut ::socklen_t, + ) -> ::ssize_t; + + pub fn recvmsg(socket: ::c_int, mp: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + // socket.h + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + + pub fn sendmsg(socket: ::c_int, mp: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + + // socket.h + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; + + // socket.h + pub fn setsockopt( + socket: ::c_int, + level: ::c_int, + name: ::c_int, + value: *const ::c_void, + option_len: socklen_t, + ) -> ::c_int; + + // socket.h + pub fn shutdown(s: ::c_int, how: ::c_int) -> ::c_int; + + // socket.h + pub fn socket(domain: ::c_int, _type: ::c_int, protocol: ::c_int) -> ::c_int; + + // icotl.h + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + // fcntl.h + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + + // ntp_rfc2553.h for kernel + // netdb.h for user + pub fn gai_strerror(errcode: ::c_int) -> *mut ::c_char; + + // ioLib.h or + // unistd.h + pub fn close(fd: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t) -> ::ssize_t; + + // ioLib.h or + // unistd.h + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t; + + // ioLib.h or + // unistd.h + pub fn isatty(fd: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn dup(src: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn pipe(fds: *mut ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn unlink(pathname: *const ::c_char) -> ::c_int; + + // unistd.h and + // ioLib.h + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + + // netdb.h + pub fn getaddrinfo( + node: *const ::c_char, + service: *const ::c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + + // netdb.h + pub fn freeaddrinfo(res: *mut addrinfo); + + // signal.h + pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t; + + // unistd.h + pub fn getpid() -> pid_t; + + // unistd.h + pub fn getppid() -> pid_t; + + // wait.h + pub fn waitpid(pid: pid_t, status: *mut ::c_int, optons: ::c_int) -> pid_t; + + // unistd.h + pub fn sysconf(attr: ::c_int) -> ::c_long; + + // stdlib.h + pub fn setenv( + // setenv.c + envVarName: *const ::c_char, + envVarValue: *const ::c_char, + overwrite: ::c_int, + ) -> ::c_int; + + // stdlib.h + pub fn unsetenv( + // setenv.c + envVarName: *const ::c_char, + ) -> ::c_int; + + // stdlib.h + pub fn realpath(fileName: *const ::c_char, resolvedName: *mut ::c_char) -> *mut ::c_char; + + // unistd.h + pub fn link(src: *const ::c_char, dst: *const ::c_char) -> ::c_int; + + // unistd.h + pub fn readlink(path: *const ::c_char, buf: *mut ::c_char, bufsize: ::size_t) -> ::ssize_t; + + // unistd.h + pub fn symlink(path1: *const ::c_char, path2: *const ::c_char) -> ::c_int; + + // dirent.h + pub fn opendir(name: *const ::c_char) -> *mut ::DIR; + + // unistd.h + pub fn rmdir(path: *const ::c_char) -> ::c_int; + + // stat.h + pub fn mkdir(dirName: *const ::c_char, mode: ::mode_t) -> ::c_int; + + // stat.h + pub fn chmod(path: *const ::c_char, mode: ::mode_t) -> ::c_int; + + // stat.h + pub fn fchmod(attr1: ::c_int, attr2: ::mode_t) -> ::c_int; + + // unistd.h + pub fn fsync(fd: ::c_int) -> ::c_int; + + // dirent.h + pub fn closedir(ptr: *mut ::DIR) -> ::c_int; + + // sched.h + pub fn sched_yield() -> ::c_int; + + // errnoLib.h + pub fn errnoSet(err: ::c_int) -> ::c_int; + + // errnoLib.h + pub fn errnoGet() -> ::c_int; + + // unistd.h + pub fn _exit(status: ::c_int) -> !; + + // unistd.h + pub fn setgid(gid: ::gid_t) -> ::c_int; + + // unistd.h + pub fn getgid() -> ::gid_t; + + // unistd.h + pub fn setuid(uid: ::uid_t) -> ::c_int; + + // unistd.h + pub fn getuid() -> ::uid_t; + + // signal.h + pub fn sigemptyset(__set: *mut sigset_t) -> ::c_int; + + // pthread.h for kernel + // signal.h for user + pub fn pthread_sigmask( + __how: ::c_int, + __set: *const sigset_t, + __oset: *mut sigset_t, + ) -> ::c_int; + + // signal.h for user + pub fn kill(__pid: pid_t, __signo: ::c_int) -> ::c_int; + + // signal.h for user + pub fn sigqueue(__pid: pid_t, __signo: ::c_int, __value: ::sigval) -> ::c_int; + + // signal.h for user + pub fn _sigqueue( + rtpId: ::RTP_ID, + signo: ::c_int, + pValue: *const ::sigval, + sigCode: ::c_int, + ) -> ::c_int; + + // signal.h + pub fn taskKill(taskId: ::TASK_ID, signo: ::c_int) -> ::c_int; + + // signal.h + pub fn raise(__signo: ::c_int) -> ::c_int; + + // taskLibCommon.h + pub fn taskIdSelf() -> ::TASK_ID; + pub fn taskDelay(ticks: ::_Vx_ticks_t) -> ::c_int; + + // rtpLibCommon.h + pub fn rtpInfoGet(rtpId: ::RTP_ID, rtpStruct: *mut ::RTP_DESC) -> ::c_int; + pub fn rtpSpawn( + pubrtpFileName: *const ::c_char, + argv: *mut *const ::c_char, + envp: *mut *const ::c_char, + priority: ::c_int, + uStackSize: ::size_t, + options: ::c_int, + taskOptions: ::c_int, + ) -> RTP_ID; + + // ioLib.h + pub fn _realpath(fileName: *const ::c_char, resolvedName: *mut ::c_char) -> *mut ::c_char; + + // pathLib.h + pub fn _pathIsAbsolute(filepath: *const ::c_char, pNameTail: *mut *const ::c_char) -> BOOL; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + // randomNumGen.h + pub fn randBytes(buf: *mut c_uchar, length: c_int) -> c_int; + pub fn randABytes(buf: *mut c_uchar, length: c_int) -> c_int; + pub fn randUBytes(buf: *mut c_uchar, length: c_int) -> c_int; + pub fn randSecure() -> c_int; + + // mqueue.h + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn mq_receive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + ) -> ::ssize_t; + pub fn mq_timedreceive( + mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msg_prio: *mut ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn mq_send( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + ) -> ::c_int; + pub fn mq_timedsend( + mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msg_prio: ::c_uint, + abs_timeout: *const ::timespec, + ) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; +} + +//Dummy functions, these don't really exist in VxWorks. + +// wait.h macros +safe_f! { + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xFF00) == 0 + } + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0xFF00) != 0 + } + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xFF0000) != 0 + } + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status & 0xFF + } + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xFF + } + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 16) & 0xFF + } +} + +pub fn pread(_fd: ::c_int, _buf: *mut ::c_void, _count: ::size_t, _offset: off64_t) -> ::ssize_t { + -1 +} + +pub fn pwrite( + _fd: ::c_int, + _buf: *const ::c_void, + _count: ::size_t, + _offset: off64_t, +) -> ::ssize_t { + -1 +} +pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int { + // check to see if align is a power of 2 and if align is a multiple + // of sizeof(void *) + if (align & align - 1 != 0) || (align as usize % size_of::<::size_t>() != 0) { + return ::EINVAL; + } + + unsafe { + // posix_memalign should not set errno + let e = ::errnoGet(); + + let temp = memalign(align, size); + ::errnoSet(e as ::c_int); + + if temp.is_null() { + ::ENOMEM + } else { + *memptr = temp; + 0 + } + } +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc64; + pub use self::powerpc64::*; + } else { + // Unknown target_arch + } +} diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/powerpc.rs b/utshell-0.5.0/vendor/libc/src/vxworks/powerpc.rs new file mode 100644 index 00000000..55240068 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/powerpc.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/powerpc64.rs b/utshell-0.5.0/vendor/libc/src/vxworks/powerpc64.rs new file mode 100644 index 00000000..4032488b --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/powerpc64.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/x86.rs b/utshell-0.5.0/vendor/libc/src/vxworks/x86.rs new file mode 100644 index 00000000..e617bb83 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/x86.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/utshell-0.5.0/vendor/libc/src/vxworks/x86_64.rs b/utshell-0.5.0/vendor/libc/src/vxworks/x86_64.rs new file mode 100644 index 00000000..5e95ea25 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/vxworks/x86_64.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/utshell-0.5.0/vendor/libc/src/wasi.rs b/utshell-0.5.0/vendor/libc/src/wasi.rs new file mode 100644 index 00000000..ae490bf9 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/wasi.rs @@ -0,0 +1,831 @@ +use super::{Send, Sync}; + +pub use ffi::c_void; + +pub type c_char = i8; +pub type c_uchar = u8; +pub type c_schar = i8; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; +pub type size_t = usize; +pub type ssize_t = isize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type off_t = i64; +pub type pid_t = i32; +pub type clock_t = c_longlong; +pub type time_t = c_longlong; +pub type c_double = f64; +pub type c_float = f32; +pub type ino_t = u64; +pub type sigset_t = c_uchar; +pub type suseconds_t = c_longlong; +pub type mode_t = u32; +pub type dev_t = u64; +pub type uid_t = u32; +pub type gid_t = u32; +pub type nlink_t = u64; +pub type blksize_t = c_long; +pub type blkcnt_t = i64; +pub type nfds_t = c_ulong; +pub type wchar_t = i32; +pub type nl_item = c_int; +pub type __wasi_rights_t = u64; + +s_no_extra_traits! { + #[repr(align(16))] + #[allow(missing_debug_implementations)] + pub struct max_align_t { + priv_: [f64; 4] + } +} + +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum FILE {} +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum __locale_struct {} + +pub type locale_t = *mut __locale_struct; + +s_paren! { + // in wasi-libc clockid_t is const struct __clockid* (where __clockid is an opaque struct), + // but that's an implementation detail that we don't want to have to deal with + #[repr(transparent)] + #[allow(dead_code)] + pub struct clockid_t(*const u8); +} + +unsafe impl Send for clockid_t {} +unsafe impl Sync for clockid_t {} + +s! { + #[repr(align(8))] + pub struct fpos_t { + data: [u8; 16], + } + + pub struct tm { + pub tm_sec: c_int, + pub tm_min: c_int, + pub tm_hour: c_int, + pub tm_mday: c_int, + pub tm_mon: c_int, + pub tm_year: c_int, + pub tm_wday: c_int, + pub tm_yday: c_int, + pub tm_isdst: c_int, + pub __tm_gmtoff: c_int, + pub __tm_zone: *const c_char, + pub __tm_nsec: c_int, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + pub struct tms { + pub tms_utime: clock_t, + pub tms_stime: clock_t, + pub tms_cutime: clock_t, + pub tms_cstime: clock_t, + } + + pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, + } + + pub struct iovec { + pub iov_base: *mut c_void, + pub iov_len: size_t, + } + + pub struct lconv { + pub decimal_point: *mut c_char, + pub thousands_sep: *mut c_char, + pub grouping: *mut c_char, + pub int_curr_symbol: *mut c_char, + pub currency_symbol: *mut c_char, + pub mon_decimal_point: *mut c_char, + pub mon_thousands_sep: *mut c_char, + pub mon_grouping: *mut c_char, + pub positive_sign: *mut c_char, + pub negative_sign: *mut c_char, + pub int_frac_digits: c_char, + pub frac_digits: c_char, + pub p_cs_precedes: c_char, + pub p_sep_by_space: c_char, + pub n_cs_precedes: c_char, + pub n_sep_by_space: c_char, + pub p_sign_posn: c_char, + pub n_sign_posn: c_char, + pub int_p_cs_precedes: c_char, + pub int_p_sep_by_space: c_char, + pub int_n_cs_precedes: c_char, + pub int_n_sep_by_space: c_char, + pub int_p_sign_posn: c_char, + pub int_n_sign_posn: c_char, + } + + pub struct pollfd { + pub fd: c_int, + pub events: c_short, + pub revents: c_short, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + } + + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_nlink: nlink_t, + pub st_mode: mode_t, + pub st_uid: uid_t, + pub st_gid: gid_t, + __pad0: c_uint, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + __reserved: [c_longlong; 3], + } +} + +// Declare dirent outside of s! so that it doesn't implement Copy, Eq, Hash, +// etc., since it contains a flexible array member with a dynamic size. +#[repr(C)] +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub struct dirent { + pub d_ino: ino_t, + pub d_type: c_uchar, + /// d_name is declared in WASI libc as a flexible array member, which + /// can't be directly expressed in Rust. As an imperfect workaround, + /// declare it as a zero-length array instead. + pub d_name: [c_char; 0], +} + +pub const EXIT_SUCCESS: c_int = 0; +pub const EXIT_FAILURE: c_int = 1; +pub const STDIN_FILENO: c_int = 0; +pub const STDOUT_FILENO: c_int = 1; +pub const STDERR_FILENO: c_int = 2; +pub const SEEK_SET: c_int = 0; +pub const SEEK_CUR: c_int = 1; +pub const SEEK_END: c_int = 2; +pub const _IOFBF: c_int = 0; +pub const _IONBF: c_int = 2; +pub const _IOLBF: c_int = 1; +pub const F_GETFD: c_int = 1; +pub const F_SETFD: c_int = 2; +pub const F_GETFL: c_int = 3; +pub const F_SETFL: c_int = 4; +pub const FD_CLOEXEC: c_int = 1; +pub const FD_SETSIZE: size_t = 1024; +pub const O_APPEND: c_int = 0x0001; +pub const O_DSYNC: c_int = 0x0002; +pub const O_NONBLOCK: c_int = 0x0004; +pub const O_RSYNC: c_int = 0x0008; +pub const O_SYNC: c_int = 0x0010; +pub const O_CREAT: c_int = 0x0001 << 12; +pub const O_DIRECTORY: c_int = 0x0002 << 12; +pub const O_EXCL: c_int = 0x0004 << 12; +pub const O_TRUNC: c_int = 0x0008 << 12; +pub const O_NOFOLLOW: c_int = 0x01000000; +pub const O_EXEC: c_int = 0x02000000; +pub const O_RDONLY: c_int = 0x04000000; +pub const O_SEARCH: c_int = 0x08000000; +pub const O_WRONLY: c_int = 0x10000000; +pub const O_CLOEXEC: c_int = 0x0; +pub const O_RDWR: c_int = O_WRONLY | O_RDONLY; +pub const O_ACCMODE: c_int = O_EXEC | O_RDWR | O_SEARCH; +pub const O_NOCTTY: c_int = 0x0; +pub const POSIX_FADV_DONTNEED: c_int = 4; +pub const POSIX_FADV_NOREUSE: c_int = 5; +pub const POSIX_FADV_NORMAL: c_int = 0; +pub const POSIX_FADV_RANDOM: c_int = 2; +pub const POSIX_FADV_SEQUENTIAL: c_int = 1; +pub const POSIX_FADV_WILLNEED: c_int = 3; +pub const AT_FDCWD: ::c_int = -2; +pub const AT_EACCESS: c_int = 0x0; +pub const AT_SYMLINK_NOFOLLOW: c_int = 0x1; +pub const AT_SYMLINK_FOLLOW: c_int = 0x2; +pub const AT_REMOVEDIR: c_int = 0x4; +pub const UTIME_OMIT: c_long = 0xfffffffe; +pub const UTIME_NOW: c_long = 0xffffffff; +pub const S_IFIFO: mode_t = 49152; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +pub const S_IFREG: mode_t = 32768; +pub const S_IFLNK: mode_t = 40960; +pub const S_IFSOCK: mode_t = 49152; +pub const S_IFMT: mode_t = 57344; +pub const S_IRWXO: mode_t = 0x7; +pub const S_IXOTH: mode_t = 0x1; +pub const S_IWOTH: mode_t = 0x2; +pub const S_IROTH: mode_t = 0x4; +pub const S_IRWXG: mode_t = 0x38; +pub const S_IXGRP: mode_t = 0x8; +pub const S_IWGRP: mode_t = 0x10; +pub const S_IRGRP: mode_t = 0x20; +pub const S_IRWXU: mode_t = 0x1c0; +pub const S_IXUSR: mode_t = 0x40; +pub const S_IWUSR: mode_t = 0x80; +pub const S_IRUSR: mode_t = 0x100; +pub const S_ISVTX: mode_t = 0x200; +pub const S_ISGID: mode_t = 0x400; +pub const S_ISUID: mode_t = 0x800; +pub const DT_UNKNOWN: u8 = 0; +pub const DT_BLK: u8 = 1; +pub const DT_CHR: u8 = 2; +pub const DT_DIR: u8 = 3; +pub const DT_REG: u8 = 4; +pub const DT_LNK: u8 = 7; +pub const FIONREAD: c_int = 1; +pub const FIONBIO: c_int = 2; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const POLLIN: ::c_short = 0x1; +pub const POLLOUT: ::c_short = 0x2; +pub const POLLERR: ::c_short = 0x1000; +pub const POLLHUP: ::c_short = 0x2000; +pub const POLLNVAL: ::c_short = 0x4000; +pub const POLLRDNORM: ::c_short = 0x1; +pub const POLLWRNORM: ::c_short = 0x2; + +pub const E2BIG: c_int = 1; +pub const EACCES: c_int = 2; +pub const EADDRINUSE: c_int = 3; +pub const EADDRNOTAVAIL: c_int = 4; +pub const EAFNOSUPPORT: c_int = 5; +pub const EAGAIN: c_int = 6; +pub const EALREADY: c_int = 7; +pub const EBADF: c_int = 8; +pub const EBADMSG: c_int = 9; +pub const EBUSY: c_int = 10; +pub const ECANCELED: c_int = 11; +pub const ECHILD: c_int = 12; +pub const ECONNABORTED: c_int = 13; +pub const ECONNREFUSED: c_int = 14; +pub const ECONNRESET: c_int = 15; +pub const EDEADLK: c_int = 16; +pub const EDESTADDRREQ: c_int = 17; +pub const EDOM: c_int = 18; +pub const EDQUOT: c_int = 19; +pub const EEXIST: c_int = 20; +pub const EFAULT: c_int = 21; +pub const EFBIG: c_int = 22; +pub const EHOSTUNREACH: c_int = 23; +pub const EIDRM: c_int = 24; +pub const EILSEQ: c_int = 25; +pub const EINPROGRESS: c_int = 26; +pub const EINTR: c_int = 27; +pub const EINVAL: c_int = 28; +pub const EIO: c_int = 29; +pub const EISCONN: c_int = 30; +pub const EISDIR: c_int = 31; +pub const ELOOP: c_int = 32; +pub const EMFILE: c_int = 33; +pub const EMLINK: c_int = 34; +pub const EMSGSIZE: c_int = 35; +pub const EMULTIHOP: c_int = 36; +pub const ENAMETOOLONG: c_int = 37; +pub const ENETDOWN: c_int = 38; +pub const ENETRESET: c_int = 39; +pub const ENETUNREACH: c_int = 40; +pub const ENFILE: c_int = 41; +pub const ENOBUFS: c_int = 42; +pub const ENODEV: c_int = 43; +pub const ENOENT: c_int = 44; +pub const ENOEXEC: c_int = 45; +pub const ENOLCK: c_int = 46; +pub const ENOLINK: c_int = 47; +pub const ENOMEM: c_int = 48; +pub const ENOMSG: c_int = 49; +pub const ENOPROTOOPT: c_int = 50; +pub const ENOSPC: c_int = 51; +pub const ENOSYS: c_int = 52; +pub const ENOTCONN: c_int = 53; +pub const ENOTDIR: c_int = 54; +pub const ENOTEMPTY: c_int = 55; +pub const ENOTRECOVERABLE: c_int = 56; +pub const ENOTSOCK: c_int = 57; +pub const ENOTSUP: c_int = 58; +pub const ENOTTY: c_int = 59; +pub const ENXIO: c_int = 60; +pub const EOVERFLOW: c_int = 61; +pub const EOWNERDEAD: c_int = 62; +pub const EPERM: c_int = 63; +pub const EPIPE: c_int = 64; +pub const EPROTO: c_int = 65; +pub const EPROTONOSUPPORT: c_int = 66; +pub const EPROTOTYPE: c_int = 67; +pub const ERANGE: c_int = 68; +pub const EROFS: c_int = 69; +pub const ESPIPE: c_int = 70; +pub const ESRCH: c_int = 71; +pub const ESTALE: c_int = 72; +pub const ETIMEDOUT: c_int = 73; +pub const ETXTBSY: c_int = 74; +pub const EXDEV: c_int = 75; +pub const ENOTCAPABLE: c_int = 76; +pub const EOPNOTSUPP: c_int = ENOTSUP; +pub const EWOULDBLOCK: c_int = EAGAIN; + +pub const _SC_PAGESIZE: c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_IOV_MAX: c_int = 60; +pub const _SC_SYMLOOP_MAX: c_int = 173; + +pub static CLOCK_MONOTONIC: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) }; +pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t = + unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) }; +pub static CLOCK_REALTIME: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) }; +pub static CLOCK_THREAD_CPUTIME_ID: clockid_t = + unsafe { clockid_t(ptr_addr_of!(_CLOCK_THREAD_CPUTIME_ID)) }; + +pub const ABDAY_1: ::nl_item = 0x20000; +pub const ABDAY_2: ::nl_item = 0x20001; +pub const ABDAY_3: ::nl_item = 0x20002; +pub const ABDAY_4: ::nl_item = 0x20003; +pub const ABDAY_5: ::nl_item = 0x20004; +pub const ABDAY_6: ::nl_item = 0x20005; +pub const ABDAY_7: ::nl_item = 0x20006; + +pub const DAY_1: ::nl_item = 0x20007; +pub const DAY_2: ::nl_item = 0x20008; +pub const DAY_3: ::nl_item = 0x20009; +pub const DAY_4: ::nl_item = 0x2000A; +pub const DAY_5: ::nl_item = 0x2000B; +pub const DAY_6: ::nl_item = 0x2000C; +pub const DAY_7: ::nl_item = 0x2000D; + +pub const ABMON_1: ::nl_item = 0x2000E; +pub const ABMON_2: ::nl_item = 0x2000F; +pub const ABMON_3: ::nl_item = 0x20010; +pub const ABMON_4: ::nl_item = 0x20011; +pub const ABMON_5: ::nl_item = 0x20012; +pub const ABMON_6: ::nl_item = 0x20013; +pub const ABMON_7: ::nl_item = 0x20014; +pub const ABMON_8: ::nl_item = 0x20015; +pub const ABMON_9: ::nl_item = 0x20016; +pub const ABMON_10: ::nl_item = 0x20017; +pub const ABMON_11: ::nl_item = 0x20018; +pub const ABMON_12: ::nl_item = 0x20019; + +pub const MON_1: ::nl_item = 0x2001A; +pub const MON_2: ::nl_item = 0x2001B; +pub const MON_3: ::nl_item = 0x2001C; +pub const MON_4: ::nl_item = 0x2001D; +pub const MON_5: ::nl_item = 0x2001E; +pub const MON_6: ::nl_item = 0x2001F; +pub const MON_7: ::nl_item = 0x20020; +pub const MON_8: ::nl_item = 0x20021; +pub const MON_9: ::nl_item = 0x20022; +pub const MON_10: ::nl_item = 0x20023; +pub const MON_11: ::nl_item = 0x20024; +pub const MON_12: ::nl_item = 0x20025; + +pub const AM_STR: ::nl_item = 0x20026; +pub const PM_STR: ::nl_item = 0x20027; + +pub const D_T_FMT: ::nl_item = 0x20028; +pub const D_FMT: ::nl_item = 0x20029; +pub const T_FMT: ::nl_item = 0x2002A; +pub const T_FMT_AMPM: ::nl_item = 0x2002B; + +pub const ERA: ::nl_item = 0x2002C; +pub const ERA_D_FMT: ::nl_item = 0x2002E; +pub const ALT_DIGITS: ::nl_item = 0x2002F; +pub const ERA_D_T_FMT: ::nl_item = 0x20030; +pub const ERA_T_FMT: ::nl_item = 0x20031; + +pub const CODESET: ::nl_item = 14; +pub const CRNCYSTR: ::nl_item = 0x4000F; +pub const RADIXCHAR: ::nl_item = 0x10000; +pub const THOUSEP: ::nl_item = 0x10001; +pub const YESEXPR: ::nl_item = 0x50000; +pub const NOEXPR: ::nl_item = 0x50001; +pub const YESSTR: ::nl_item = 0x50002; +pub const NOSTR: ::nl_item = 0x50003; + +#[cfg_attr( + feature = "rustc-dep-of-std", + link( + name = "c", + kind = "static", + modifiers = "-bundle", + cfg(target_feature = "crt-static") + ) +)] +#[cfg_attr( + feature = "rustc-dep-of-std", + link(name = "c", cfg(not(target_feature = "crt-static"))) +)] +extern "C" { + pub fn _Exit(code: c_int) -> !; + pub fn _exit(code: c_int) -> !; + pub fn abort() -> !; + pub fn aligned_alloc(a: size_t, b: size_t) -> *mut c_void; + pub fn calloc(amt: size_t, amt2: size_t) -> *mut c_void; + pub fn exit(code: c_int) -> !; + pub fn free(ptr: *mut c_void); + pub fn getenv(s: *const c_char) -> *mut c_char; + pub fn malloc(amt: size_t) -> *mut c_void; + pub fn malloc_usable_size(ptr: *mut c_void) -> size_t; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + pub fn rand() -> c_int; + pub fn read(fd: c_int, ptr: *mut c_void, size: size_t) -> ssize_t; + pub fn realloc(ptr: *mut c_void, amt: size_t) -> *mut c_void; + pub fn setenv(k: *const c_char, v: *const c_char, a: c_int) -> c_int; + pub fn unsetenv(k: *const c_char) -> c_int; + pub fn clearenv() -> ::c_int; + pub fn write(fd: c_int, ptr: *const c_void, size: size_t) -> ssize_t; + pub static mut environ: *mut *mut c_char; + pub fn fopen(a: *const c_char, b: *const c_char) -> *mut FILE; + pub fn freopen(a: *const c_char, b: *const c_char, f: *mut FILE) -> *mut FILE; + pub fn fclose(f: *mut FILE) -> c_int; + pub fn remove(a: *const c_char) -> c_int; + pub fn rename(a: *const c_char, b: *const c_char) -> c_int; + pub fn feof(f: *mut FILE) -> c_int; + pub fn ferror(f: *mut FILE) -> c_int; + pub fn fflush(f: *mut FILE) -> c_int; + pub fn clearerr(f: *mut FILE); + pub fn fseek(f: *mut FILE, b: c_long, c: c_int) -> c_int; + pub fn ftell(f: *mut FILE) -> c_long; + pub fn rewind(f: *mut FILE); + pub fn fgetpos(f: *mut FILE, pos: *mut fpos_t) -> c_int; + pub fn fsetpos(f: *mut FILE, pos: *const fpos_t) -> c_int; + pub fn fread(buf: *mut c_void, a: size_t, b: size_t, f: *mut FILE) -> size_t; + pub fn fwrite(buf: *const c_void, a: size_t, b: size_t, f: *mut FILE) -> size_t; + pub fn fgetc(f: *mut FILE) -> c_int; + pub fn getc(f: *mut FILE) -> c_int; + pub fn getchar() -> c_int; + pub fn ungetc(a: c_int, f: *mut FILE) -> c_int; + pub fn fputc(a: c_int, f: *mut FILE) -> c_int; + pub fn putc(a: c_int, f: *mut FILE) -> c_int; + pub fn putchar(a: c_int) -> c_int; + pub fn fputs(a: *const c_char, f: *mut FILE) -> c_int; + pub fn puts(a: *const c_char) -> c_int; + pub fn perror(a: *const c_char); + pub fn srand(a: c_uint); + pub fn atexit(a: extern "C" fn()) -> c_int; + pub fn at_quick_exit(a: extern "C" fn()) -> c_int; + pub fn quick_exit(a: c_int) -> !; + pub fn posix_memalign(a: *mut *mut c_void, b: size_t, c: size_t) -> c_int; + pub fn rand_r(a: *mut c_uint) -> c_int; + pub fn random() -> c_long; + pub fn srandom(a: c_uint); + pub fn putenv(a: *mut c_char) -> c_int; + pub fn clock() -> clock_t; + pub fn time(a: *mut time_t) -> time_t; + pub fn difftime(a: time_t, b: time_t) -> c_double; + pub fn mktime(a: *mut tm) -> time_t; + pub fn strftime(a: *mut c_char, b: size_t, c: *const c_char, d: *const tm) -> size_t; + pub fn gmtime(a: *const time_t) -> *mut tm; + pub fn gmtime_r(a: *const time_t, b: *mut tm) -> *mut tm; + pub fn localtime(a: *const time_t) -> *mut tm; + pub fn localtime_r(a: *const time_t, b: *mut tm) -> *mut tm; + pub fn asctime_r(a: *const tm, b: *mut c_char) -> *mut c_char; + pub fn ctime_r(a: *const time_t, b: *mut c_char) -> *mut c_char; + + static _CLOCK_MONOTONIC: u8; + static _CLOCK_PROCESS_CPUTIME_ID: u8; + static _CLOCK_REALTIME: u8; + static _CLOCK_THREAD_CPUTIME_ID: u8; + pub fn nanosleep(a: *const timespec, b: *mut timespec) -> c_int; + pub fn clock_getres(a: clockid_t, b: *mut timespec) -> c_int; + pub fn clock_gettime(a: clockid_t, b: *mut timespec) -> c_int; + pub fn clock_nanosleep(a: clockid_t, a2: c_int, b: *const timespec, c: *mut timespec) -> c_int; + + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn isblank(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; + pub fn atol(s: *const c_char) -> c_long; + pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; + pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; + pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; + pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strndup(cs: *const c_char, n: size_t) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + pub fn fdopendir(fd: ::c_int) -> *mut ::DIR; + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int, ...) -> ::c_int; + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn readlinkat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t, + ) -> ::ssize_t; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn close(fd: ::c_int) -> ::c_int; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn sleep(secs: ::c_uint) -> ::c_uint; + pub fn unlink(c: *const c_char) -> ::c_int; + pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn fsync(fd: ::c_int) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + + pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int; + + pub fn truncate(path: *const c_char, length: off_t) -> ::c_int; + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn usleep(secs: ::c_uint) -> ::c_int; + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; + + pub fn timegm(tm: *mut ::tm) -> time_t; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + + pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t; + + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn abs(i: c_int) -> c_int; + pub fn labs(i: c_long) -> c_long; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn sched_yield() -> ::c_int; + pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; + pub fn chdir(dir: *const c_char) -> ::c_int; + + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + pub fn nl_langinfo_l(item: ::nl_item, loc: ::locale_t) -> *mut ::c_char; + + pub fn __wasilibc_register_preopened_fd(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_fd_renumber(fd: c_int, newfd: c_int) -> c_int; + pub fn __wasilibc_unlinkat(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_rmdirat(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_find_relpath( + path: *const c_char, + abs_prefix: *mut *const c_char, + relative_path: *mut *mut c_char, + relative_path_len: usize, + ) -> c_int; + pub fn __wasilibc_tell(fd: c_int) -> ::off_t; + pub fn __wasilibc_nocwd___wasilibc_unlinkat(dirfd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_nocwd___wasilibc_rmdirat(dirfd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_nocwd_linkat( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_symlinkat( + target: *const c_char, + dirfd: c_int, + path: *const c_char, + ) -> c_int; + pub fn __wasilibc_nocwd_readlinkat( + dirfd: c_int, + path: *const c_char, + buf: *mut c_char, + bufsize: usize, + ) -> isize; + pub fn __wasilibc_nocwd_faccessat( + dirfd: c_int, + path: *const c_char, + mode: c_int, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_renameat( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + ) -> c_int; + pub fn __wasilibc_nocwd_openat_nomode(dirfd: c_int, path: *const c_char, flags: c_int) + -> c_int; + pub fn __wasilibc_nocwd_fstatat( + dirfd: c_int, + path: *const c_char, + buf: *mut stat, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_mkdirat_nomode(dirfd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_nocwd_utimensat( + dirfd: c_int, + path: *const c_char, + times: *const ::timespec, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_opendirat(dirfd: c_int, path: *const c_char) -> *mut ::DIR; + pub fn __wasilibc_access(pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; + pub fn __wasilibc_stat(pathname: *const c_char, buf: *mut stat, flags: c_int) -> c_int; + pub fn __wasilibc_utimens( + pathname: *const c_char, + times: *const ::timespec, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_link(oldpath: *const c_char, newpath: *const c_char, flags: c_int) -> c_int; + pub fn __wasilibc_link_oldat( + olddirfd: c_int, + oldpath: *const c_char, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_link_newat( + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_rename_oldat( + olddirfd: c_int, + oldpath: *const c_char, + newpath: *const c_char, + ) -> c_int; + pub fn __wasilibc_rename_newat( + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + ) -> c_int; + + pub fn arc4random() -> u32; + pub fn arc4random_buf(a: *mut c_void, b: size_t); + pub fn arc4random_uniform(a: u32) -> u32; + + pub fn __errno_location() -> *mut ::c_int; +} diff --git a/utshell-0.5.0/vendor/libc/src/windows/gnu/align.rs b/utshell-0.5.0/vendor/libc/src/windows/gnu/align.rs new file mode 100644 index 00000000..3af99e3c --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/windows/gnu/align.rs @@ -0,0 +1,19 @@ +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + } + } else if #[cfg(target_pointer_width = "32")] { + s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 6] + } + } + } +} diff --git a/utshell-0.5.0/vendor/libc/src/windows/gnu/mod.rs b/utshell-0.5.0/vendor/libc/src/windows/gnu/mod.rs new file mode 100644 index 00000000..3e7d38b8 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/windows/gnu/mod.rs @@ -0,0 +1,23 @@ +pub const L_tmpnam: ::c_uint = 14; +pub const TMP_MAX: ::c_uint = 0x7fff; + +// stdio file descriptor numbers +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +extern "C" { + pub fn strcasecmp(s1: *const ::c_char, s2: *const ::c_char) -> ::c_int; + pub fn strncasecmp(s1: *const ::c_char, s2: *const ::c_char, n: ::size_t) -> ::c_int; + + // NOTE: For MSVC target, `wmemchr` is only a inline function in `` + // header file. We cannot find a way to link to that symbol from Rust. + pub fn wmemchr(cx: *const ::wchar_t, c: ::wchar_t, n: ::size_t) -> *mut ::wchar_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/utshell-0.5.0/vendor/libc/src/windows/mod.rs b/utshell-0.5.0/vendor/libc/src/windows/mod.rs new file mode 100644 index 00000000..196f1f2e --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/windows/mod.rs @@ -0,0 +1,601 @@ +//! Windows CRT definitions + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; +pub type sighandler_t = usize; + +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = u16; + +pub type clock_t = i32; + +pub type errno_t = ::c_int; + +cfg_if! { + if #[cfg(all(target_arch = "x86", target_env = "gnu"))] { + pub type time_t = i32; + } else { + pub type time_t = i64; + } +} + +pub type off_t = i32; +pub type dev_t = u32; +pub type ino_t = u16; +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} +pub type time64_t = i64; + +pub type SOCKET = ::uintptr_t; + +s! { + // note this is the struct called stat64 in Windows. Not stat, nor stati64. + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: u16, + pub st_nlink: ::c_short, + pub st_uid: ::c_short, + pub st_gid: ::c_short, + pub st_rdev: dev_t, + pub st_size: i64, + pub st_atime: time64_t, + pub st_mtime: time64_t, + pub st_ctime: time64_t, + } + + // note that this is called utimbuf64 in Windows + pub struct utimbuf { + pub actime: time64_t, + pub modtime: time64_t, + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int, + } + + pub struct timeval { + pub tv_sec: c_long, + pub tv_usec: c_long, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + pub struct sockaddr { + pub sa_family: c_ushort, + pub sa_data: [c_char; 14], + } +} + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 32767; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 4; +pub const _IOLBF: ::c_int = 64; +pub const BUFSIZ: ::c_uint = 512; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 260; + +// fcntl.h +pub const O_RDONLY: ::c_int = 0x0000; +pub const O_WRONLY: ::c_int = 0x0001; +pub const O_RDWR: ::c_int = 0x0002; +pub const O_APPEND: ::c_int = 0x0008; +pub const O_CREAT: ::c_int = 0x0100; +pub const O_TRUNC: ::c_int = 0x0200; +pub const O_EXCL: ::c_int = 0x0400; +pub const O_TEXT: ::c_int = 0x4000; +pub const O_BINARY: ::c_int = 0x8000; +pub const _O_WTEXT: ::c_int = 0x10000; +pub const _O_U16TEXT: ::c_int = 0x20000; +pub const _O_U8TEXT: ::c_int = 0x40000; +pub const O_RAW: ::c_int = O_BINARY; +pub const O_NOINHERIT: ::c_int = 0x0080; +pub const O_TEMPORARY: ::c_int = 0x0040; +pub const _O_SHORT_LIVED: ::c_int = 0x1000; +pub const _O_OBTAIN_DIR: ::c_int = 0x2000; +pub const O_SEQUENTIAL: ::c_int = 0x0020; +pub const O_RANDOM: ::c_int = 0x0010; + +pub const S_IFCHR: ::c_int = 8192; +pub const S_IFDIR: ::c_int = 16384; +pub const S_IFREG: ::c_int = 32768; +pub const S_IFMT: ::c_int = 61440; +pub const S_IEXEC: ::c_int = 64; +pub const S_IWRITE: ::c_int = 128; +pub const S_IREAD: ::c_int = 256; + +pub const LC_ALL: ::c_int = 0; +pub const LC_COLLATE: ::c_int = 1; +pub const LC_CTYPE: ::c_int = 2; +pub const LC_MONETARY: ::c_int = 3; +pub const LC_NUMERIC: ::c_int = 4; +pub const LC_TIME: ::c_int = 5; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const EDEADLK: ::c_int = 36; +pub const EDEADLOCK: ::c_int = 36; +pub const ENAMETOOLONG: ::c_int = 38; +pub const ENOLCK: ::c_int = 39; +pub const ENOSYS: ::c_int = 40; +pub const ENOTEMPTY: ::c_int = 41; +pub const EILSEQ: ::c_int = 42; +pub const STRUNCATE: ::c_int = 80; + +// POSIX Supplement (from errno.h) +pub const EADDRINUSE: ::c_int = 100; +pub const EADDRNOTAVAIL: ::c_int = 101; +pub const EAFNOSUPPORT: ::c_int = 102; +pub const EALREADY: ::c_int = 103; +pub const EBADMSG: ::c_int = 104; +pub const ECANCELED: ::c_int = 105; +pub const ECONNABORTED: ::c_int = 106; +pub const ECONNREFUSED: ::c_int = 107; +pub const ECONNRESET: ::c_int = 108; +pub const EDESTADDRREQ: ::c_int = 109; +pub const EHOSTUNREACH: ::c_int = 110; +pub const EIDRM: ::c_int = 111; +pub const EINPROGRESS: ::c_int = 112; +pub const EISCONN: ::c_int = 113; +pub const ELOOP: ::c_int = 114; +pub const EMSGSIZE: ::c_int = 115; +pub const ENETDOWN: ::c_int = 116; +pub const ENETRESET: ::c_int = 117; +pub const ENETUNREACH: ::c_int = 118; +pub const ENOBUFS: ::c_int = 119; +pub const ENODATA: ::c_int = 120; +pub const ENOLINK: ::c_int = 121; +pub const ENOMSG: ::c_int = 122; +pub const ENOPROTOOPT: ::c_int = 123; +pub const ENOSR: ::c_int = 124; +pub const ENOSTR: ::c_int = 125; +pub const ENOTCONN: ::c_int = 126; +pub const ENOTRECOVERABLE: ::c_int = 127; +pub const ENOTSOCK: ::c_int = 128; +pub const ENOTSUP: ::c_int = 129; +pub const EOPNOTSUPP: ::c_int = 130; +pub const EOVERFLOW: ::c_int = 132; +pub const EOWNERDEAD: ::c_int = 133; +pub const EPROTO: ::c_int = 134; +pub const EPROTONOSUPPORT: ::c_int = 135; +pub const EPROTOTYPE: ::c_int = 136; +pub const ETIME: ::c_int = 137; +pub const ETIMEDOUT: ::c_int = 138; +pub const ETXTBSY: ::c_int = 139; +pub const EWOULDBLOCK: ::c_int = 140; + +// signal codes +pub const SIGINT: ::c_int = 2; +pub const SIGILL: ::c_int = 4; +pub const SIGFPE: ::c_int = 8; +pub const SIGSEGV: ::c_int = 11; +pub const SIGTERM: ::c_int = 15; +pub const SIGABRT: ::c_int = 22; +pub const NSIG: ::c_int = 23; + +pub const SIG_ERR: ::c_int = -1; +pub const SIG_DFL: ::sighandler_t = 0; +pub const SIG_IGN: ::sighandler_t = 1; +pub const SIG_GET: ::sighandler_t = 2; +pub const SIG_SGE: ::sighandler_t = 3; +pub const SIG_ACK: ::sighandler_t = 4; + +// inline comment below appeases style checker +#[cfg(all(target_env = "msvc", feature = "rustc-dep-of-std"))] // " if " +#[link(name = "msvcrt", cfg(not(target_feature = "crt-static")))] +#[link(name = "libcmt", cfg(target_feature = "crt-static"))] +extern "C" {} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +// Special handling for all print and scan type functions because of https://github.com/rust-lang/libc/issues/2860 +cfg_if! { + if #[cfg(not(feature = "rustc-dep-of-std"))] { + #[cfg_attr( + all(windows, target_env = "msvc"), + link(name = "legacy_stdio_definitions") + )] + extern "C" { + pub fn printf(format: *const c_char, ...) -> ::c_int; + pub fn fprintf(stream: *mut FILE, format: *const c_char, ...) -> ::c_int; + } + } +} + +extern "C" { + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn isblank(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); + pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; + pub fn atol(s: *const c_char) -> c_long; + pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; + pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; + pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; + pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn _msize(p: *mut c_void) -> size_t; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; + pub fn atexit(cb: extern "C" fn()) -> c_int; + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn abs(i: c_int) -> c_int; + pub fn labs(i: c_long) -> c_long; + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); + + pub fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t; + pub fn raise(signum: c_int) -> c_int; + + #[link_name = "_gmtime64_s"] + pub fn gmtime_s(destTime: *mut tm, srcTime: *const time_t) -> ::c_int; + #[link_name = "_localtime64_s"] + pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> ::errno_t; + #[link_name = "_time64"] + pub fn time(destTime: *mut time_t) -> time_t; + #[link_name = "_chmod"] + pub fn chmod(path: *const c_char, mode: ::c_int) -> ::c_int; + #[link_name = "_wchmod"] + pub fn wchmod(path: *const wchar_t, mode: ::c_int) -> ::c_int; + #[link_name = "_mkdir"] + pub fn mkdir(path: *const c_char) -> ::c_int; + #[link_name = "_wrmdir"] + pub fn wrmdir(path: *const wchar_t) -> ::c_int; + #[link_name = "_fstat64"] + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + #[link_name = "_stat64"] + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + #[link_name = "_wstat64"] + pub fn wstat(path: *const wchar_t, buf: *mut stat) -> ::c_int; + #[link_name = "_wutime64"] + pub fn wutime(file: *const wchar_t, buf: *mut utimbuf) -> ::c_int; + #[link_name = "_popen"] + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + #[link_name = "_pclose"] + pub fn pclose(stream: *mut ::FILE) -> ::c_int; + #[link_name = "_fdopen"] + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + #[link_name = "_fileno"] + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + #[link_name = "_open"] + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + #[link_name = "_wopen"] + pub fn wopen(path: *const wchar_t, oflag: ::c_int, ...) -> ::c_int; + #[link_name = "_creat"] + pub fn creat(path: *const c_char, mode: ::c_int) -> ::c_int; + #[link_name = "_access"] + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + #[link_name = "_chdir"] + pub fn chdir(dir: *const c_char) -> ::c_int; + #[link_name = "_close"] + pub fn close(fd: ::c_int) -> ::c_int; + #[link_name = "_dup"] + pub fn dup(fd: ::c_int) -> ::c_int; + #[link_name = "_dup2"] + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + #[link_name = "_execl"] + pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexecl"] + pub fn wexecl(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execle"] + pub fn execle(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexecle"] + pub fn wexecle(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execlp"] + pub fn execlp(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexeclp"] + pub fn wexeclp(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execlpe"] + pub fn execlpe(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexeclpe"] + pub fn wexeclpe(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execv"] + pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::intptr_t; + #[link_name = "_execve"] + pub fn execve( + prog: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + #[link_name = "_execvp"] + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + #[link_name = "_execvpe"] + pub fn execvpe( + c: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + #[link_name = "_wexecv"] + pub fn wexecv(prog: *const wchar_t, argv: *const *const wchar_t) -> ::intptr_t; + #[link_name = "_wexecve"] + pub fn wexecve( + prog: *const wchar_t, + argv: *const *const wchar_t, + envp: *const *const wchar_t, + ) -> ::intptr_t; + #[link_name = "_wexecvp"] + pub fn wexecvp(c: *const wchar_t, argv: *const *const wchar_t) -> ::intptr_t; + #[link_name = "_wexecvpe"] + pub fn wexecvpe( + c: *const wchar_t, + argv: *const *const wchar_t, + envp: *const *const wchar_t, + ) -> ::intptr_t; + #[link_name = "_getcwd"] + pub fn getcwd(buf: *mut c_char, size: ::c_int) -> *mut c_char; + #[link_name = "_getpid"] + pub fn getpid() -> ::c_int; + #[link_name = "_isatty"] + pub fn isatty(fd: ::c_int) -> ::c_int; + #[link_name = "_lseek"] + pub fn lseek(fd: ::c_int, offset: c_long, origin: ::c_int) -> c_long; + #[link_name = "_lseeki64"] + pub fn lseek64(fd: ::c_int, offset: c_longlong, origin: ::c_int) -> c_longlong; + #[link_name = "_pipe"] + pub fn pipe(fds: *mut ::c_int, psize: ::c_uint, textmode: ::c_int) -> ::c_int; + #[link_name = "_read"] + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::c_uint) -> ::c_int; + #[link_name = "_rmdir"] + pub fn rmdir(path: *const c_char) -> ::c_int; + #[link_name = "_unlink"] + pub fn unlink(c: *const c_char) -> ::c_int; + #[link_name = "_write"] + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::c_uint) -> ::c_int; + #[link_name = "_commit"] + pub fn commit(fd: ::c_int) -> ::c_int; + #[link_name = "_get_osfhandle"] + pub fn get_osfhandle(fd: ::c_int) -> ::intptr_t; + #[link_name = "_open_osfhandle"] + pub fn open_osfhandle(osfhandle: ::intptr_t, flags: ::c_int) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const c_char) -> *mut c_char; + #[link_name = "_wsetlocale"] + pub fn wsetlocale(category: ::c_int, locale: *const wchar_t) -> *mut wchar_t; + #[link_name = "_aligned_malloc"] + pub fn aligned_malloc(size: size_t, alignment: size_t) -> *mut c_void; + #[link_name = "_aligned_free"] + pub fn aligned_free(ptr: *mut ::c_void); + #[link_name = "_putenv"] + pub fn putenv(envstring: *const ::c_char) -> ::c_int; + #[link_name = "_wputenv"] + pub fn wputenv(envstring: *const ::wchar_t) -> ::c_int; + #[link_name = "_putenv_s"] + pub fn putenv_s(envstring: *const ::c_char, value_string: *const ::c_char) -> ::errno_t; + #[link_name = "_wputenv_s"] + pub fn wputenv_s(envstring: *const ::wchar_t, value_string: *const ::wchar_t) -> ::errno_t; +} + +extern "system" { + pub fn listen(s: SOCKET, backlog: ::c_int) -> ::c_int; + pub fn accept(s: SOCKET, addr: *mut ::sockaddr, addrlen: *mut ::c_int) -> SOCKET; + pub fn bind(s: SOCKET, name: *const ::sockaddr, namelen: ::c_int) -> ::c_int; + pub fn connect(s: SOCKET, name: *const ::sockaddr, namelen: ::c_int) -> ::c_int; + pub fn getpeername(s: SOCKET, name: *mut ::sockaddr, nameln: *mut ::c_int) -> ::c_int; + pub fn getsockname(s: SOCKET, name: *mut ::sockaddr, nameln: *mut ::c_int) -> ::c_int; + pub fn getsockopt( + s: SOCKET, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_char, + optlen: *mut ::c_int, + ) -> ::c_int; + pub fn recvfrom( + s: SOCKET, + buf: *mut ::c_char, + len: ::c_int, + flags: ::c_int, + from: *mut ::sockaddr, + fromlen: *mut ::c_int, + ) -> ::c_int; + pub fn sendto( + s: SOCKET, + buf: *const ::c_char, + len: ::c_int, + flags: ::c_int, + to: *const ::sockaddr, + tolen: ::c_int, + ) -> ::c_int; + pub fn setsockopt( + s: SOCKET, + level: ::c_int, + optname: ::c_int, + optval: *const ::c_char, + optlen: ::c_int, + ) -> ::c_int; + pub fn socket(af: ::c_int, socket_type: ::c_int, protocol: ::c_int) -> SOCKET; +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} + +cfg_if! { + if #[cfg(all(target_env = "gnu"))] { + mod gnu; + pub use self::gnu::*; + } else if #[cfg(all(target_env = "msvc"))] { + mod msvc; + pub use self::msvc::*; + } else { + // Unknown target_env + } +} diff --git a/utshell-0.5.0/vendor/libc/src/windows/msvc/mod.rs b/utshell-0.5.0/vendor/libc/src/windows/msvc/mod.rs new file mode 100644 index 00000000..f5a1d95f --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/windows/msvc/mod.rs @@ -0,0 +1,20 @@ +pub const L_tmpnam: ::c_uint = 260; +pub const TMP_MAX: ::c_uint = 0x7fff_ffff; + +// POSIX Supplement (from errno.h) +// This particular error code is only currently available in msvc toolchain +pub const EOTHER: ::c_int = 131; + +extern "C" { + #[link_name = "_stricmp"] + pub fn stricmp(s1: *const ::c_char, s2: *const ::c_char) -> ::c_int; + #[link_name = "_strnicmp"] + pub fn strnicmp(s1: *const ::c_char, s2: *const ::c_char, n: ::size_t) -> ::c_int; + #[link_name = "_memccpy"] + pub fn memccpy( + dest: *mut ::c_void, + src: *const ::c_void, + c: ::c_int, + count: ::size_t, + ) -> *mut ::c_void; +} diff --git a/utshell-0.5.0/vendor/libc/src/xous.rs b/utshell-0.5.0/vendor/libc/src/xous.rs new file mode 100644 index 00000000..e6c0c257 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/src/xous.rs @@ -0,0 +1,49 @@ +//! Xous C type definitions + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type off_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = u32; + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff --git a/utshell-0.5.0/vendor/libc/tests/const_fn.rs b/utshell-0.5.0/vendor/libc/tests/const_fn.rs new file mode 100644 index 00000000..0e7e1864 --- /dev/null +++ b/utshell-0.5.0/vendor/libc/tests/const_fn.rs @@ -0,0 +1,5 @@ +#![cfg(libc_const_extern_fn)] // If this does not hold, the file is empty + +#[cfg(target_os = "linux")] +const _FOO: libc::c_uint = unsafe { libc::CMSG_SPACE(1) }; +//^ if CMSG_SPACE is not const, this will fail to compile diff --git a/utshell-0.5.0/vendor/memchr/.cargo-checksum.json b/utshell-0.5.0/vendor/memchr/.cargo-checksum.json new file mode 100644 index 00000000..f4963802 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"fdeda7d32fa12e4a1589d13c74ae5fd4f1065d0219ba73f8492e28248d84d146","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"51d941627e004588863b137918e908e34c4d599d12e03afd3e489e2bb61e3704","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","build.rs":"5638d9b60d40f44db96767ce32246de42158571364cce92531a85307ac7eda6c","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","scripts/make-byte-frequency-table":"21d1ded41fe5a780507bb88e1910d471b4081cc626a48891a408712e45b7b2bf","src/cow.rs":"a23c3b009e5215b5c3ac46627a5dd844235bef0136d76b3fc1eeeb744565c125","src/lib.rs":"9430cd37b13399df8f8c27a752ccdf6422a563e24171d1b4802424f9193a8f37","src/memchr/c.rs":"34f7caf79316f4b03908832fdbd4aff367f2bc30eae291478cc5a0a108ce6e76","src/memchr/fallback.rs":"48764f18b7ff1f00a9ac1c4ed8ec96ad11f7b09b2d062a8ed3fe81160add627d","src/memchr/iter.rs":"61463e7fa22ca8f212c2cbfb882af0c87b0fb1bc6b4676678a4822a581ec1037","src/memchr/mod.rs":"d5bfc881c7c089e1a0825209a4d21c3f792f38c6f16f3bc715d0d539477376b6","src/memchr/naive.rs":"c7453bc99cc4e58eb37cf5a50c88688833e50a270ee1849baefddb8acc0ccd94","src/memchr/x86/avx.rs":"3c2750174ce7ff033daa4096e7961bbee9a2da898068266b27dee22ef8cfddad","src/memchr/x86/mod.rs":"a642d5aefdb7452ead4ab7946b5c6cfb6cc6df636dcd0ebbd6f5e6e1ac8305c0","src/memchr/x86/sse2.rs":"79ede1aba71a655e86eb5873d682c5da26933bffa4fffd7042a2313f18cf4675","src/memchr/x86/sse42.rs":"de4c6f354dbfec170876cddb8d9157b35928f96ed2339a0c5d094cc953a2f52d","src/memmem/byte_frequencies.rs":"2fb85b381c038c1e44ce94294531cdcd339dca48b1e61f41455666e802cbbc9e","src/memmem/genericsimd.rs":"9ce7283db0994438eb6df2bea6ad984e80512b6f643ebae7ae7d82eb5d39fa11","src/memmem/mod.rs":"949fb8e11a23030d59b34fd8c7c196150f133e909a8448705c77a751c436907d","src/memmem/prefilter/fallback.rs":"d32248c41aa09701c2410c52f948bbe009dd1b13a01b444ce0fb8c4b4e404ede","src/memmem/prefilter/genericsimd.rs":"57d5523cf0299b37ef1dd1b351e3d387d5070f2f7ecffc9a9ca66528101ebd3f","src/memmem/prefilter/mod.rs":"ad8b4ac72c025f11d6b641c5fc0888468112758dcdc6bb72b43f932d2005ea4e","src/memmem/prefilter/wasm.rs":"14f684412fca35445a94760a6973d772dfd22d329ebae3b52b525d2a1f3acd63","src/memmem/prefilter/x86/avx.rs":"e344cae36a88b59c07a1c1d395edeb9c636a399e1528ce69b2bc7c94d8d8bb0b","src/memmem/prefilter/x86/mod.rs":"df2d84b23b22574383c281d33671a121b5faf7b1a48dd6f67c3085cd02cd4498","src/memmem/prefilter/x86/sse.rs":"daa648fc2a90d37299803a80d632e8a47a30ce8719d0ac2a2ea2cde3b30b6fef","src/memmem/rabinkarp.rs":"9b44eb092524a51792eba4deaca6c6d3cbc51db98cb548ea4fa7e5d8988cc71a","src/memmem/rarebytes.rs":"571082c71fc3dca5e4304171d41fb3c44e241df6dcd88bac4d7a15b52f9521e0","src/memmem/twoway.rs":"102f8bbb29696d5656cd2f5a1769a3af96d044fb09972881455cfb6424d6b50a","src/memmem/util.rs":"0194d40b912137e2352863af9cc1c0273baf97fdf6b27799628680846c06febd","src/memmem/vector.rs":"96e6f45f8ad11a822c4f18393839225d7f40f898ad657e109ba1b3288af0ef8f","src/memmem/wasm.rs":"87da03c964f054db30cc972d07a74e8902ec1248e2338ecd1dbac430f43fffc2","src/memmem/x86/avx.rs":"de85dbc415603c844baf94fbc92d676a738dd4b99246be468bd5f7be5921b25f","src/memmem/x86/mod.rs":"5012fca41b91caf229278aa221e8dd514ede497fe4938d64562d03fef2fc46e6","src/memmem/x86/sse.rs":"148a40c0952aca8b16d9eb3e724a5b9b60693bc7b2bcc5209bcc43c94faf560a","src/tests/memchr/iter.rs":"b68c7ecdb6222c5dbf61212e6863f78f98ad343868a74cb8612692fc790240b2","src/tests/memchr/memchr.rs":"09589c5899324c9b26ea4513c80389a2ffdf6ddc460031e2ca8da43bd493ae3f","src/tests/memchr/mod.rs":"29e0855f946c7babf603b3d610a29235a56a26a4c867fef0768542388eac4c95","src/tests/memchr/simple.rs":"b9997903ede972272c01c1750522a20692a28488cc7c5cf745ea83ff96d65fe3","src/tests/memchr/testdata.rs":"3e34377fe60eca3687d1ebc66127bd631af27ceaccc8f08806a293199b69a83f","src/tests/mod.rs":"9054a2a2f9af140f305ca29155d942fafbac9fb0874067611adc8a5990546be4","src/tests/x86_64-soft_float.json":"c0e416487fe9b4809534edb7db2a9eff3453dc40d9f1e23362c37f45a77ec717"},"package":"2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/memchr/COPYING b/utshell-0.5.0/vendor/memchr/COPYING new file mode 100644 index 00000000..bb9c20a0 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/COPYING @@ -0,0 +1,3 @@ +This project is dual-licensed under the Unlicense and MIT licenses. + +You may use this code under the terms of either license. diff --git a/utshell-0.5.0/vendor/memchr/Cargo.toml b/utshell-0.5.0/vendor/memchr/Cargo.toml new file mode 100644 index 00000000..63019528 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/Cargo.toml @@ -0,0 +1,78 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "memchr" +version = "2.5.0" +authors = [ + "Andrew Gallant ", + "bluss", +] +exclude = [ + "/bench", + "/.github", + "/fuzz", +] +description = "Safe interface to memchr." +homepage = "https://github.com/BurntSushi/memchr" +documentation = "https://docs.rs/memchr/" +readme = "README.md" +keywords = [ + "memchr", + "char", + "scan", + "strchr", + "string", +] +license = "Unlicense/MIT" +repository = "https://github.com/BurntSushi/memchr" + +[profile.bench] +debug = true + +[profile.release] +debug = true + +[profile.test] +opt-level = 3 +debug = true + +[lib] +name = "memchr" +bench = false + +[dependencies.compiler_builtins] +version = "0.1.2" +optional = true + +[dependencies.core] +version = "1.0.0" +optional = true +package = "rustc-std-workspace-core" + +[dependencies.libc] +version = "0.2.18" +optional = true +default-features = false + +[dev-dependencies.quickcheck] +version = "1.0.3" +default-features = false + +[features] +default = ["std"] +rustc-dep-of-std = [ + "core", + "compiler_builtins", +] +std = [] +use_std = ["std"] diff --git a/utshell-0.5.0/vendor/memchr/LICENSE-MIT b/utshell-0.5.0/vendor/memchr/LICENSE-MIT new file mode 100644 index 00000000..3b0a5dc0 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/memchr/README.md b/utshell-0.5.0/vendor/memchr/README.md new file mode 100644 index 00000000..77a7a0f5 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/README.md @@ -0,0 +1,107 @@ +memchr +====== +This library provides heavily optimized routines for string search primitives. + +[![Build status](https://github.com/BurntSushi/memchr/workflows/ci/badge.svg)](https://github.com/BurntSushi/memchr/actions) +[![Crates.io](https://img.shields.io/crates/v/memchr.svg)](https://crates.io/crates/memchr) + +Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/). + + +### Documentation + +[https://docs.rs/memchr](https://docs.rs/memchr) + + +### Overview + +* The top-level module provides routines for searching for 1, 2 or 3 bytes + in the forward or reverse direction. When searching for more than one byte, + positions are considered a match if the byte at that position matches any + of the bytes. +* The `memmem` sub-module provides forward and reverse substring search + routines. + +In all such cases, routines operate on `&[u8]` without regard to encoding. This +is exactly what you want when searching either UTF-8 or arbitrary bytes. + +### Compiling without the standard library + +memchr links to the standard library by default, but you can disable the +`std` feature if you want to use it in a `#![no_std]` crate: + +```toml +[dependencies] +memchr = { version = "2", default-features = false } +``` + +On x86 platforms, when the `std` feature is disabled, the SSE2 accelerated +implementations will be used. When `std` is enabled, AVX accelerated +implementations will be used if the CPU is determined to support it at runtime. + +### Using libc + +`memchr` is a routine that is part of libc, although this crate does not use +libc by default. Instead, it uses its own routines, which are either vectorized +or generic fallback routines. In general, these should be competitive with +what's in libc, although this has not been tested for all architectures. If +using `memchr` from libc is desirable and a vectorized routine is not otherwise +available in this crate, then enabling the `libc` feature will use libc's +version of `memchr`. + +The rest of the functions in this crate, e.g., `memchr2` or `memrchr3` and the +substring search routines, will always use the implementations in this crate. +One exception to this is `memrchr`, which is an extension in `libc` found on +Linux. On Linux, `memrchr` is used in precisely the same scenario as `memchr`, +as described above. + + +### Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.41.1`. + +The current policy is that the minimum Rust version required to use this crate +can be increased in minor version updates. For example, if `crate 1.0` requires +Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust +1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum +version of Rust. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. + + +### Testing strategy + +Given the complexity of the code in this crate, along with the pervasive use +of `unsafe`, this crate has an extensive testing strategy. It combines multiple +approaches: + +* Hand-written tests. +* Exhaustive-style testing meant to exercise all possible branching and offset + calculations. +* Property based testing through [`quickcheck`](https://github.com/BurntSushi/quickcheck). +* Fuzz testing through [`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz). +* A huge suite of benchmarks that are also run as tests. Benchmarks always + confirm that the expected result occurs. + +Improvements to the testing infrastructure are very welcome. + + +### Algorithms used + +At time of writing, this crate's implementation of substring search actually +has a few different algorithms to choose from depending on the situation. + +* For very small haystacks, + [Rabin-Karp](https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm) + is used to reduce latency. Rabin-Karp has very small overhead and can often + complete before other searchers have even been constructed. +* For small needles, a variant of the + ["Generic SIMD"](http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd) + algorithm is used. Instead of using the first and last bytes, a heuristic is + used to select bytes based on a background distribution of byte frequencies. +* In all other cases, + [Two-Way](https://en.wikipedia.org/wiki/Two-way_string-matching_algorithm) + is used. If possible, a prefilter based on the "Generic SIMD" algorithm + linked above is used to find candidates quickly. A dynamic heuristic is used + to detect if the prefilter is ineffective, and if so, disables it. diff --git a/utshell-0.5.0/vendor/memchr/UNLICENSE b/utshell-0.5.0/vendor/memchr/UNLICENSE new file mode 100644 index 00000000..68a49daa --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/utshell-0.5.0/vendor/memchr/build.rs b/utshell-0.5.0/vendor/memchr/build.rs new file mode 100644 index 00000000..584a6085 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/build.rs @@ -0,0 +1,88 @@ +use std::env; + +fn main() { + enable_simd_optimizations(); + enable_libc(); +} + +// This adds various simd cfgs if this compiler and target support it. +// +// This can be disabled with RUSTFLAGS="--cfg memchr_disable_auto_simd", but +// this is generally only intended for testing. +// +// On targets which don't feature SSE2, this is disabled, as LLVM wouln't know +// how to work with SSE2 operands. Enabling SSE4.2 and AVX on SSE2-only targets +// is not a problem. In that case, the fastest option will be chosen at +// runtime. +fn enable_simd_optimizations() { + if is_env_set("CARGO_CFG_MEMCHR_DISABLE_AUTO_SIMD") { + return; + } + let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + match &arch[..] { + "x86_64" => { + if !target_has_feature("sse2") { + return; + } + println!("cargo:rustc-cfg=memchr_runtime_simd"); + println!("cargo:rustc-cfg=memchr_runtime_sse2"); + println!("cargo:rustc-cfg=memchr_runtime_sse42"); + println!("cargo:rustc-cfg=memchr_runtime_avx"); + } + "wasm32" | "wasm64" => { + if !target_has_feature("simd128") { + return; + } + println!("cargo:rustc-cfg=memchr_runtime_simd"); + println!("cargo:rustc-cfg=memchr_runtime_wasm128"); + } + _ => {} + } +} + +// This adds a `memchr_libc` cfg if and only if libc can be used, if no other +// better option is available. +// +// This could be performed in the source code, but it's simpler to do it once +// here and consolidate it into one cfg knob. +// +// Basically, we use libc only if its enabled and if we aren't targeting a +// known bad platform. For example, wasm32 doesn't have a libc and the +// performance of memchr on Windows is seemingly worse than the fallback +// implementation. +fn enable_libc() { + const NO_ARCH: &'static [&'static str] = &["wasm32", "windows"]; + const NO_ENV: &'static [&'static str] = &["sgx"]; + + if !is_feature_set("LIBC") { + return; + } + + let arch = match env::var("CARGO_CFG_TARGET_ARCH") { + Err(_) => return, + Ok(arch) => arch, + }; + let env = match env::var("CARGO_CFG_TARGET_ENV") { + Err(_) => return, + Ok(env) => env, + }; + if NO_ARCH.contains(&&*arch) || NO_ENV.contains(&&*env) { + return; + } + + println!("cargo:rustc-cfg=memchr_libc"); +} + +fn is_feature_set(name: &str) -> bool { + is_env_set(&format!("CARGO_FEATURE_{}", name)) +} + +fn is_env_set(name: &str) -> bool { + env::var_os(name).is_some() +} + +fn target_has_feature(feature: &str) -> bool { + env::var("CARGO_CFG_TARGET_FEATURE") + .map(|features| features.contains(feature)) + .unwrap_or(false) +} diff --git a/utshell-0.5.0/vendor/memchr/rustfmt.toml b/utshell-0.5.0/vendor/memchr/rustfmt.toml new file mode 100644 index 00000000..aa37a218 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 79 +use_small_heuristics = "max" diff --git a/utshell-0.5.0/vendor/memchr/scripts/make-byte-frequency-table b/utshell-0.5.0/vendor/memchr/scripts/make-byte-frequency-table new file mode 100755 index 00000000..37eeca7b --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/scripts/make-byte-frequency-table @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +# This does simple normalized frequency analysis on UTF-8 encoded text. The +# result of the analysis is translated to a ranked list, where every byte is +# assigned a rank. This list is written to src/freqs.rs. +# +# Currently, the frequencies are generated from the following corpuses: +# +# * The CIA world fact book +# * The source code of rustc +# * Septuaginta + +from __future__ import absolute_import, division, print_function + +import argparse +from collections import Counter +import sys + +preamble = ''' +// NOTE: The following code was generated by "scripts/frequencies.py", do not +// edit directly +'''.lstrip() + + +def eprint(*args, **kwargs): + kwargs['file'] = sys.stderr + print(*args, **kwargs) + + +def main(): + p = argparse.ArgumentParser() + p.add_argument('corpus', metavar='FILE', nargs='+') + args = p.parse_args() + + # Get frequency counts of each byte. + freqs = Counter() + for i in range(0, 256): + freqs[i] = 0 + + eprint('reading entire corpus into memory') + corpus = [] + for fpath in args.corpus: + corpus.append(open(fpath, 'rb').read()) + + eprint('computing byte frequencies') + for c in corpus: + for byte in c: + freqs[byte] += 1.0 / float(len(c)) + + eprint('writing Rust code') + # Get the rank of each byte. A lower rank => lower relative frequency. + rank = [0] * 256 + for i, (byte, _) in enumerate(freqs.most_common()): + # print(byte) + rank[byte] = 255 - i + + # Forcefully set the highest rank possible for bytes that start multi-byte + # UTF-8 sequences. The idea here is that a continuation byte will be more + # discerning in a homogenous haystack. + for byte in range(0xC0, 0xFF + 1): + rank[byte] = 255 + + # Now write Rust. + olines = ['pub const BYTE_FREQUENCIES: [u8; 256] = ['] + for byte in range(256): + olines.append(' %3d, // %r' % (rank[byte], chr(byte))) + olines.append('];') + + print(preamble) + print('\n'.join(olines)) + + +if __name__ == '__main__': + main() diff --git a/utshell-0.5.0/vendor/memchr/src/cow.rs b/utshell-0.5.0/vendor/memchr/src/cow.rs new file mode 100644 index 00000000..0b7d0dad --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/cow.rs @@ -0,0 +1,97 @@ +use core::ops; + +/// A specialized copy-on-write byte string. +/// +/// The purpose of this type is to permit usage of a "borrowed or owned +/// byte string" in a way that keeps std/no-std compatibility. That is, in +/// no-std mode, this type devolves into a simple &[u8] with no owned variant +/// available. We can't just use a plain Cow because Cow is not in core. +#[derive(Clone, Debug)] +pub struct CowBytes<'a>(Imp<'a>); + +// N.B. We don't use std::borrow::Cow here since we can get away with a +// Box<[u8]> for our use case, which is 1/3 smaller than the Vec that +// a Cow<[u8]> would use. +#[cfg(feature = "std")] +#[derive(Clone, Debug)] +enum Imp<'a> { + Borrowed(&'a [u8]), + Owned(Box<[u8]>), +} + +#[cfg(not(feature = "std"))] +#[derive(Clone, Debug)] +struct Imp<'a>(&'a [u8]); + +impl<'a> ops::Deref for CowBytes<'a> { + type Target = [u8]; + + #[inline(always)] + fn deref(&self) -> &[u8] { + self.as_slice() + } +} + +impl<'a> CowBytes<'a> { + /// Create a new borrowed CowBytes. + #[inline(always)] + pub fn new>(bytes: &'a B) -> CowBytes<'a> { + CowBytes(Imp::new(bytes.as_ref())) + } + + /// Create a new owned CowBytes. + #[cfg(feature = "std")] + #[inline(always)] + pub fn new_owned(bytes: Box<[u8]>) -> CowBytes<'static> { + CowBytes(Imp::Owned(bytes)) + } + + /// Return a borrowed byte string, regardless of whether this is an owned + /// or borrowed byte string internally. + #[inline(always)] + pub fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } + + /// Return an owned version of this copy-on-write byte string. + /// + /// If this is already an owned byte string internally, then this is a + /// no-op. Otherwise, the internal byte string is copied. + #[cfg(feature = "std")] + #[inline(always)] + pub fn into_owned(self) -> CowBytes<'static> { + match self.0 { + Imp::Borrowed(b) => CowBytes::new_owned(Box::from(b)), + Imp::Owned(b) => CowBytes::new_owned(b), + } + } +} + +impl<'a> Imp<'a> { + #[cfg(feature = "std")] + #[inline(always)] + pub fn new(bytes: &'a [u8]) -> Imp<'a> { + Imp::Borrowed(bytes) + } + + #[cfg(not(feature = "std"))] + #[inline(always)] + pub fn new(bytes: &'a [u8]) -> Imp<'a> { + Imp(bytes) + } + + #[cfg(feature = "std")] + #[inline(always)] + pub fn as_slice(&self) -> &[u8] { + match self { + Imp::Owned(ref x) => x, + Imp::Borrowed(x) => x, + } + } + + #[cfg(not(feature = "std"))] + #[inline(always)] + pub fn as_slice(&self) -> &[u8] { + self.0 + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/lib.rs b/utshell-0.5.0/vendor/memchr/src/lib.rs new file mode 100644 index 00000000..e0b4ce3f --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/lib.rs @@ -0,0 +1,181 @@ +/*! +This library provides heavily optimized routines for string search primitives. + +# Overview + +This section gives a brief high level overview of what this crate offers. + +* The top-level module provides routines for searching for 1, 2 or 3 bytes + in the forward or reverse direction. When searching for more than one byte, + positions are considered a match if the byte at that position matches any + of the bytes. +* The [`memmem`] sub-module provides forward and reverse substring search + routines. + +In all such cases, routines operate on `&[u8]` without regard to encoding. This +is exactly what you want when searching either UTF-8 or arbitrary bytes. + +# Example: using `memchr` + +This example shows how to use `memchr` to find the first occurrence of `z` in +a haystack: + +``` +use memchr::memchr; + +let haystack = b"foo bar baz quuz"; +assert_eq!(Some(10), memchr(b'z', haystack)); +``` + +# Example: matching one of three possible bytes + +This examples shows how to use `memrchr3` to find occurrences of `a`, `b` or +`c`, starting at the end of the haystack. + +``` +use memchr::memchr3_iter; + +let haystack = b"xyzaxyzbxyzc"; + +let mut it = memchr3_iter(b'a', b'b', b'c', haystack).rev(); +assert_eq!(Some(11), it.next()); +assert_eq!(Some(7), it.next()); +assert_eq!(Some(3), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: iterating over substring matches + +This example shows how to use the [`memmem`] sub-module to find occurrences of +a substring in a haystack. + +``` +use memchr::memmem; + +let haystack = b"foo bar foo baz foo"; + +let mut it = memmem::find_iter(haystack, "foo"); +assert_eq!(Some(0), it.next()); +assert_eq!(Some(8), it.next()); +assert_eq!(Some(16), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: repeating a search for the same needle + +It may be possible for the overhead of constructing a substring searcher to be +measurable in some workloads. In cases where the same needle is used to search +many haystacks, it is possible to do construction once and thus to avoid it for +subsequent searches. This can be done with a [`memmem::Finder`]: + +``` +use memchr::memmem; + +let finder = memmem::Finder::new("foo"); + +assert_eq!(Some(4), finder.find(b"baz foo quux")); +assert_eq!(None, finder.find(b"quux baz bar")); +``` + +# Why use this crate? + +At first glance, the APIs provided by this crate might seem weird. Why provide +a dedicated routine like `memchr` for something that could be implemented +clearly and trivially in one line: + +``` +fn memchr(needle: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == needle) +} +``` + +Or similarly, why does this crate provide substring search routines when Rust's +core library already provides them? + +``` +fn search(haystack: &str, needle: &str) -> Option { + haystack.find(needle) +} +``` + +The primary reason for both of them to exist is performance. When it comes to +performance, at a high level at least, there are two primary ways to look at +it: + +* **Throughput**: For this, think about it as, "given some very large haystack + and a byte that never occurs in that haystack, how long does it take to + search through it and determine that it, in fact, does not occur?" +* **Latency**: For this, think about it as, "given a tiny haystack---just a + few bytes---how long does it take to determine if a byte is in it?" + +The `memchr` routine in this crate has _slightly_ worse latency than the +solution presented above, however, its throughput can easily be over an +order of magnitude faster. This is a good general purpose trade off to make. +You rarely lose, but often gain big. + +**NOTE:** The name `memchr` comes from the corresponding routine in libc. A key +advantage of using this library is that its performance is not tied to its +quality of implementation in the libc you happen to be using, which can vary +greatly from platform to platform. + +But what about substring search? This one is a bit more complicated. The +primary reason for its existence is still indeed performance, but it's also +useful because Rust's core library doesn't actually expose any substring +search routine on arbitrary bytes. The only substring search routine that +exists works exclusively on valid UTF-8. + +So if you have valid UTF-8, is there a reason to use this over the standard +library substring search routine? Yes. This routine is faster on almost every +metric, including latency. The natural question then, is why isn't this +implementation in the standard library, even if only for searching on UTF-8? +The reason is that the implementation details for using SIMD in the standard +library haven't quite been worked out yet. + +**NOTE:** Currently, only `x86_64` targets have highly accelerated +implementations of substring search. For `memchr`, all targets have +somewhat-accelerated implementations, while only `x86_64` targets have highly +accelerated implementations. This limitation is expected to be lifted once the +standard library exposes a platform independent SIMD API. + +# Crate features + +* **std** - When enabled (the default), this will permit this crate to use + features specific to the standard library. Currently, the only thing used + from the standard library is runtime SIMD CPU feature detection. This means + that this feature must be enabled to get AVX accelerated routines. When + `std` is not enabled, this crate will still attempt to use SSE2 accelerated + routines on `x86_64`. +* **libc** - When enabled (**not** the default), this library will use your + platform's libc implementation of `memchr` (and `memrchr` on Linux). This + can be useful on non-`x86_64` targets where the fallback implementation in + this crate is not as good as the one found in your libc. All other routines + (e.g., `memchr[23]` and substring search) unconditionally use the + implementation in this crate. +*/ + +#![deny(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] +// It's not worth trying to gate all code on just miri, so turn off relevant +// dead code warnings. +#![cfg_attr(miri, allow(dead_code, unused_macros))] + +// Supporting 8-bit (or others) would be fine. If you need it, please submit a +// bug report at https://github.com/BurntSushi/memchr +#[cfg(not(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64" +)))] +compile_error!("memchr currently not supported on non-{16,32,64}"); + +pub use crate::memchr::{ + memchr, memchr2, memchr2_iter, memchr3, memchr3_iter, memchr_iter, + memrchr, memrchr2, memrchr2_iter, memrchr3, memrchr3_iter, memrchr_iter, + Memchr, Memchr2, Memchr3, +}; + +mod cow; +mod memchr; +pub mod memmem; +#[cfg(test)] +mod tests; diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/c.rs b/utshell-0.5.0/vendor/memchr/src/memchr/c.rs new file mode 100644 index 00000000..608aabc9 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/c.rs @@ -0,0 +1,44 @@ +// This module defines safe wrappers around memchr (POSIX) and memrchr (GNU +// extension). + +#![allow(dead_code)] + +use libc::{c_int, c_void, size_t}; + +pub fn memchr(needle: u8, haystack: &[u8]) -> Option { + // SAFETY: This is safe to call since all pointers are valid. + let p = unsafe { + libc::memchr( + haystack.as_ptr() as *const c_void, + needle as c_int, + haystack.len() as size_t, + ) + }; + if p.is_null() { + None + } else { + Some(p as usize - (haystack.as_ptr() as usize)) + } +} + +// memrchr is a GNU extension. We know it's available on Linux at least. +#[cfg(target_os = "linux")] +pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { + // GNU's memrchr() will - unlike memchr() - error if haystack is empty. + if haystack.is_empty() { + return None; + } + // SAFETY: This is safe to call since all pointers are valid. + let p = unsafe { + libc::memrchr( + haystack.as_ptr() as *const c_void, + needle as c_int, + haystack.len() as size_t, + ) + }; + if p.is_null() { + None + } else { + Some(p as usize - (haystack.as_ptr() as usize)) + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/fallback.rs b/utshell-0.5.0/vendor/memchr/src/memchr/fallback.rs new file mode 100644 index 00000000..b01f224f --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/fallback.rs @@ -0,0 +1,329 @@ +// This module defines pure Rust platform independent implementations of all +// the memchr routines. We do our best to make them fast. Some of them may even +// get auto-vectorized. + +use core::{cmp, usize}; + +#[cfg(target_pointer_width = "16")] +const USIZE_BYTES: usize = 2; + +#[cfg(target_pointer_width = "32")] +const USIZE_BYTES: usize = 4; + +#[cfg(target_pointer_width = "64")] +const USIZE_BYTES: usize = 8; + +// The number of bytes to loop at in one iteration of memchr/memrchr. +const LOOP_SIZE: usize = 2 * USIZE_BYTES; + +/// Return `true` if `x` contains any zero byte. +/// +/// From *Matters Computational*, J. Arndt +/// +/// "The idea is to subtract one from each of the bytes and then look for +/// bytes where the borrow propagated all the way to the most significant +/// bit." +#[inline(always)] +fn contains_zero_byte(x: usize) -> bool { + const LO_U64: u64 = 0x0101010101010101; + const HI_U64: u64 = 0x8080808080808080; + + const LO_USIZE: usize = LO_U64 as usize; + const HI_USIZE: usize = HI_U64 as usize; + + x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0 +} + +/// Repeat the given byte into a word size number. That is, every 8 bits +/// is equivalent to the given byte. For example, if `b` is `\x4E` or +/// `01001110` in binary, then the returned value on a 32-bit system would be: +/// `01001110_01001110_01001110_01001110`. +#[inline(always)] +fn repeat_byte(b: u8) -> usize { + (b as usize) * (usize::MAX / 255) +} + +pub fn memchr(n1: u8, haystack: &[u8]) -> Option { + let vn1 = repeat_byte(n1); + let confirm = |byte| byte == n1; + let loop_size = cmp::min(LOOP_SIZE, haystack.len()); + let align = USIZE_BYTES - 1; + let start_ptr = haystack.as_ptr(); + let mut ptr = start_ptr; + + unsafe { + let end_ptr = start_ptr.add(haystack.len()); + if haystack.len() < USIZE_BYTES { + return forward_search(start_ptr, end_ptr, ptr, confirm); + } + + let chunk = (ptr as *const usize).read_unaligned(); + if contains_zero_byte(chunk ^ vn1) { + return forward_search(start_ptr, end_ptr, ptr, confirm); + } + + ptr = ptr.add(USIZE_BYTES - (start_ptr as usize & align)); + debug_assert!(ptr > start_ptr); + debug_assert!(end_ptr.sub(USIZE_BYTES) >= start_ptr); + while loop_size == LOOP_SIZE && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let a = *(ptr as *const usize); + let b = *(ptr.add(USIZE_BYTES) as *const usize); + let eqa = contains_zero_byte(a ^ vn1); + let eqb = contains_zero_byte(b ^ vn1); + if eqa || eqb { + break; + } + ptr = ptr.add(LOOP_SIZE); + } + forward_search(start_ptr, end_ptr, ptr, confirm) + } +} + +/// Like `memchr`, but searches for two bytes instead of one. +pub fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + let vn1 = repeat_byte(n1); + let vn2 = repeat_byte(n2); + let confirm = |byte| byte == n1 || byte == n2; + let align = USIZE_BYTES - 1; + let start_ptr = haystack.as_ptr(); + let mut ptr = start_ptr; + + unsafe { + let end_ptr = start_ptr.add(haystack.len()); + if haystack.len() < USIZE_BYTES { + return forward_search(start_ptr, end_ptr, ptr, confirm); + } + + let chunk = (ptr as *const usize).read_unaligned(); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + if eq1 || eq2 { + return forward_search(start_ptr, end_ptr, ptr, confirm); + } + + ptr = ptr.add(USIZE_BYTES - (start_ptr as usize & align)); + debug_assert!(ptr > start_ptr); + debug_assert!(end_ptr.sub(USIZE_BYTES) >= start_ptr); + while ptr <= end_ptr.sub(USIZE_BYTES) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let chunk = *(ptr as *const usize); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + if eq1 || eq2 { + break; + } + ptr = ptr.add(USIZE_BYTES); + } + forward_search(start_ptr, end_ptr, ptr, confirm) + } +} + +/// Like `memchr`, but searches for three bytes instead of one. +pub fn memchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + let vn1 = repeat_byte(n1); + let vn2 = repeat_byte(n2); + let vn3 = repeat_byte(n3); + let confirm = |byte| byte == n1 || byte == n2 || byte == n3; + let align = USIZE_BYTES - 1; + let start_ptr = haystack.as_ptr(); + let mut ptr = start_ptr; + + unsafe { + let end_ptr = start_ptr.add(haystack.len()); + if haystack.len() < USIZE_BYTES { + return forward_search(start_ptr, end_ptr, ptr, confirm); + } + + let chunk = (ptr as *const usize).read_unaligned(); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + let eq3 = contains_zero_byte(chunk ^ vn3); + if eq1 || eq2 || eq3 { + return forward_search(start_ptr, end_ptr, ptr, confirm); + } + + ptr = ptr.add(USIZE_BYTES - (start_ptr as usize & align)); + debug_assert!(ptr > start_ptr); + debug_assert!(end_ptr.sub(USIZE_BYTES) >= start_ptr); + while ptr <= end_ptr.sub(USIZE_BYTES) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let chunk = *(ptr as *const usize); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + let eq3 = contains_zero_byte(chunk ^ vn3); + if eq1 || eq2 || eq3 { + break; + } + ptr = ptr.add(USIZE_BYTES); + } + forward_search(start_ptr, end_ptr, ptr, confirm) + } +} + +/// Return the last index matching the byte `x` in `text`. +pub fn memrchr(n1: u8, haystack: &[u8]) -> Option { + let vn1 = repeat_byte(n1); + let confirm = |byte| byte == n1; + let loop_size = cmp::min(LOOP_SIZE, haystack.len()); + let align = USIZE_BYTES - 1; + let start_ptr = haystack.as_ptr(); + + unsafe { + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + if haystack.len() < USIZE_BYTES { + return reverse_search(start_ptr, end_ptr, ptr, confirm); + } + + let chunk = (ptr.sub(USIZE_BYTES) as *const usize).read_unaligned(); + if contains_zero_byte(chunk ^ vn1) { + return reverse_search(start_ptr, end_ptr, ptr, confirm); + } + + ptr = (end_ptr as usize & !align) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let a = *(ptr.sub(2 * USIZE_BYTES) as *const usize); + let b = *(ptr.sub(1 * USIZE_BYTES) as *const usize); + let eqa = contains_zero_byte(a ^ vn1); + let eqb = contains_zero_byte(b ^ vn1); + if eqa || eqb { + break; + } + ptr = ptr.sub(loop_size); + } + reverse_search(start_ptr, end_ptr, ptr, confirm) + } +} + +/// Like `memrchr`, but searches for two bytes instead of one. +pub fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + let vn1 = repeat_byte(n1); + let vn2 = repeat_byte(n2); + let confirm = |byte| byte == n1 || byte == n2; + let align = USIZE_BYTES - 1; + let start_ptr = haystack.as_ptr(); + + unsafe { + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + if haystack.len() < USIZE_BYTES { + return reverse_search(start_ptr, end_ptr, ptr, confirm); + } + + let chunk = (ptr.sub(USIZE_BYTES) as *const usize).read_unaligned(); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + if eq1 || eq2 { + return reverse_search(start_ptr, end_ptr, ptr, confirm); + } + + ptr = (end_ptr as usize & !align) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while ptr >= start_ptr.add(USIZE_BYTES) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let chunk = *(ptr.sub(USIZE_BYTES) as *const usize); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + if eq1 || eq2 { + break; + } + ptr = ptr.sub(USIZE_BYTES); + } + reverse_search(start_ptr, end_ptr, ptr, confirm) + } +} + +/// Like `memrchr`, but searches for three bytes instead of one. +pub fn memrchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + let vn1 = repeat_byte(n1); + let vn2 = repeat_byte(n2); + let vn3 = repeat_byte(n3); + let confirm = |byte| byte == n1 || byte == n2 || byte == n3; + let align = USIZE_BYTES - 1; + let start_ptr = haystack.as_ptr(); + + unsafe { + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + if haystack.len() < USIZE_BYTES { + return reverse_search(start_ptr, end_ptr, ptr, confirm); + } + + let chunk = (ptr.sub(USIZE_BYTES) as *const usize).read_unaligned(); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + let eq3 = contains_zero_byte(chunk ^ vn3); + if eq1 || eq2 || eq3 { + return reverse_search(start_ptr, end_ptr, ptr, confirm); + } + + ptr = (end_ptr as usize & !align) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while ptr >= start_ptr.add(USIZE_BYTES) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let chunk = *(ptr.sub(USIZE_BYTES) as *const usize); + let eq1 = contains_zero_byte(chunk ^ vn1); + let eq2 = contains_zero_byte(chunk ^ vn2); + let eq3 = contains_zero_byte(chunk ^ vn3); + if eq1 || eq2 || eq3 { + break; + } + ptr = ptr.sub(USIZE_BYTES); + } + reverse_search(start_ptr, end_ptr, ptr, confirm) + } +} + +#[inline(always)] +unsafe fn forward_search bool>( + start_ptr: *const u8, + end_ptr: *const u8, + mut ptr: *const u8, + confirm: F, +) -> Option { + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr); + + while ptr < end_ptr { + if confirm(*ptr) { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + None +} + +#[inline(always)] +unsafe fn reverse_search bool>( + start_ptr: *const u8, + end_ptr: *const u8, + mut ptr: *const u8, + confirm: F, +) -> Option { + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr); + + while ptr > start_ptr { + ptr = ptr.offset(-1); + if confirm(*ptr) { + return Some(sub(ptr, start_ptr)); + } + } + None +} + +/// Subtract `b` from `a` and return the difference. `a` should be greater than +/// or equal to `b`. +fn sub(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/iter.rs b/utshell-0.5.0/vendor/memchr/src/memchr/iter.rs new file mode 100644 index 00000000..16e203f6 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/iter.rs @@ -0,0 +1,173 @@ +use crate::{memchr, memchr2, memchr3, memrchr, memrchr2, memrchr3}; + +macro_rules! iter_next { + // Common code for the memchr iterators: + // update haystack and position and produce the index + // + // self: &mut Self where Self is the iterator + // search_result: Option which is the result of the corresponding + // memchr function. + // + // Returns Option (the next iterator element) + ($self_:expr, $search_result:expr) => { + $search_result.map(move |index| { + // split and take the remaining back half + $self_.haystack = $self_.haystack.split_at(index + 1).1; + let found_position = $self_.position + index; + $self_.position = found_position + 1; + found_position + }) + }; +} + +macro_rules! iter_next_back { + ($self_:expr, $search_result:expr) => { + $search_result.map(move |index| { + // split and take the remaining front half + $self_.haystack = $self_.haystack.split_at(index).0; + $self_.position + index + }) + }; +} + +/// An iterator for `memchr`. +pub struct Memchr<'a> { + needle: u8, + // The haystack to iterate over + haystack: &'a [u8], + // The index + position: usize, +} + +impl<'a> Memchr<'a> { + /// Creates a new iterator that yields all positions of needle in haystack. + #[inline] + pub fn new(needle: u8, haystack: &[u8]) -> Memchr<'_> { + Memchr { needle: needle, haystack: haystack, position: 0 } + } +} + +impl<'a> Iterator for Memchr<'a> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + iter_next!(self, memchr(self.needle, self.haystack)) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.haystack.len())) + } +} + +impl<'a> DoubleEndedIterator for Memchr<'a> { + #[inline] + fn next_back(&mut self) -> Option { + iter_next_back!(self, memrchr(self.needle, self.haystack)) + } +} + +/// An iterator for `memchr2`. +pub struct Memchr2<'a> { + needle1: u8, + needle2: u8, + // The haystack to iterate over + haystack: &'a [u8], + // The index + position: usize, +} + +impl<'a> Memchr2<'a> { + /// Creates a new iterator that yields all positions of needle in haystack. + #[inline] + pub fn new(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2<'_> { + Memchr2 { + needle1: needle1, + needle2: needle2, + haystack: haystack, + position: 0, + } + } +} + +impl<'a> Iterator for Memchr2<'a> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + iter_next!(self, memchr2(self.needle1, self.needle2, self.haystack)) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.haystack.len())) + } +} + +impl<'a> DoubleEndedIterator for Memchr2<'a> { + #[inline] + fn next_back(&mut self) -> Option { + iter_next_back!( + self, + memrchr2(self.needle1, self.needle2, self.haystack) + ) + } +} + +/// An iterator for `memchr3`. +pub struct Memchr3<'a> { + needle1: u8, + needle2: u8, + needle3: u8, + // The haystack to iterate over + haystack: &'a [u8], + // The index + position: usize, +} + +impl<'a> Memchr3<'a> { + /// Create a new `Memchr3` that's initialized to zero with a haystack + #[inline] + pub fn new( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], + ) -> Memchr3<'_> { + Memchr3 { + needle1: needle1, + needle2: needle2, + needle3: needle3, + haystack: haystack, + position: 0, + } + } +} + +impl<'a> Iterator for Memchr3<'a> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + iter_next!( + self, + memchr3(self.needle1, self.needle2, self.needle3, self.haystack) + ) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.haystack.len())) + } +} + +impl<'a> DoubleEndedIterator for Memchr3<'a> { + #[inline] + fn next_back(&mut self) -> Option { + iter_next_back!( + self, + memrchr3(self.needle1, self.needle2, self.needle3, self.haystack) + ) + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/mod.rs b/utshell-0.5.0/vendor/memchr/src/memchr/mod.rs new file mode 100644 index 00000000..09ce6ef3 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/mod.rs @@ -0,0 +1,410 @@ +use core::iter::Rev; + +pub use self::iter::{Memchr, Memchr2, Memchr3}; + +// N.B. If you're looking for the cfg knobs for libc, see build.rs. +#[cfg(memchr_libc)] +mod c; +#[allow(dead_code)] +pub mod fallback; +mod iter; +pub mod naive; +#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] +mod x86; + +/// An iterator over all occurrences of the needle in a haystack. +#[inline] +pub fn memchr_iter(needle: u8, haystack: &[u8]) -> Memchr<'_> { + Memchr::new(needle, haystack) +} + +/// An iterator over all occurrences of the needles in a haystack. +#[inline] +pub fn memchr2_iter(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2<'_> { + Memchr2::new(needle1, needle2, haystack) +} + +/// An iterator over all occurrences of the needles in a haystack. +#[inline] +pub fn memchr3_iter( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Memchr3<'_> { + Memchr3::new(needle1, needle2, needle3, haystack) +} + +/// An iterator over all occurrences of the needle in a haystack, in reverse. +#[inline] +pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev> { + Memchr::new(needle, haystack).rev() +} + +/// An iterator over all occurrences of the needles in a haystack, in reverse. +#[inline] +pub fn memrchr2_iter( + needle1: u8, + needle2: u8, + haystack: &[u8], +) -> Rev> { + Memchr2::new(needle1, needle2, haystack).rev() +} + +/// An iterator over all occurrences of the needles in a haystack, in reverse. +#[inline] +pub fn memrchr3_iter( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Rev> { + Memchr3::new(needle1, needle2, needle3, haystack).rev() +} + +/// Search for the first occurrence of a byte in a slice. +/// +/// This returns the index corresponding to the first occurrence of `needle` in +/// `haystack`, or `None` if one is not found. If an index is returned, it is +/// guaranteed to be less than `usize::MAX`. +/// +/// While this is operationally the same as something like +/// `haystack.iter().position(|&b| b == needle)`, `memchr` will use a highly +/// optimized routine that can be up to an order of magnitude faster in some +/// cases. +/// +/// # Example +/// +/// This shows how to find the first position of a byte in a byte string. +/// +/// ``` +/// use memchr::memchr; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr(b'k', haystack), Some(8)); +/// ``` +#[inline] +pub fn memchr(needle: u8, haystack: &[u8]) -> Option { + #[cfg(miri)] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + naive::memchr(n1, haystack) + } + + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + x86::memchr(n1, haystack) + } + + #[cfg(all( + memchr_libc, + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + c::memchr(n1, haystack) + } + + #[cfg(all( + not(memchr_libc), + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + fallback::memchr(n1, haystack) + } + + if haystack.is_empty() { + None + } else { + imp(needle, haystack) + } +} + +/// Like `memchr`, but searches for either of two bytes instead of just one. +/// +/// This returns the index corresponding to the first occurrence of `needle1` +/// or the first occurrence of `needle2` in `haystack` (whichever occurs +/// earlier), or `None` if neither one is found. If an index is returned, it is +/// guaranteed to be less than `usize::MAX`. +/// +/// While this is operationally the same as something like +/// `haystack.iter().position(|&b| b == needle1 || b == needle2)`, `memchr2` +/// will use a highly optimized routine that can be up to an order of magnitude +/// faster in some cases. +/// +/// # Example +/// +/// This shows how to find the first position of either of two bytes in a byte +/// string. +/// +/// ``` +/// use memchr::memchr2; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr2(b'k', b'q', haystack), Some(4)); +/// ``` +#[inline] +pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option { + #[cfg(miri)] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + naive::memchr2(n1, n2, haystack) + } + + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + x86::memchr2(n1, n2, haystack) + } + + #[cfg(all( + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + fallback::memchr2(n1, n2, haystack) + } + + if haystack.is_empty() { + None + } else { + imp(needle1, needle2, haystack) + } +} + +/// Like `memchr`, but searches for any of three bytes instead of just one. +/// +/// This returns the index corresponding to the first occurrence of `needle1`, +/// the first occurrence of `needle2`, or the first occurrence of `needle3` in +/// `haystack` (whichever occurs earliest), or `None` if none are found. If an +/// index is returned, it is guaranteed to be less than `usize::MAX`. +/// +/// While this is operationally the same as something like +/// `haystack.iter().position(|&b| b == needle1 || b == needle2 || +/// b == needle3)`, `memchr3` will use a highly optimized routine that can be +/// up to an order of magnitude faster in some cases. +/// +/// # Example +/// +/// This shows how to find the first position of any of three bytes in a byte +/// string. +/// +/// ``` +/// use memchr::memchr3; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr3(b'k', b'q', b'e', haystack), Some(2)); +/// ``` +#[inline] +pub fn memchr3( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Option { + #[cfg(miri)] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + naive::memchr3(n1, n2, n3, haystack) + } + + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + x86::memchr3(n1, n2, n3, haystack) + } + + #[cfg(all( + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + fallback::memchr3(n1, n2, n3, haystack) + } + + if haystack.is_empty() { + None + } else { + imp(needle1, needle2, needle3, haystack) + } +} + +/// Search for the last occurrence of a byte in a slice. +/// +/// This returns the index corresponding to the last occurrence of `needle` in +/// `haystack`, or `None` if one is not found. If an index is returned, it is +/// guaranteed to be less than `usize::MAX`. +/// +/// While this is operationally the same as something like +/// `haystack.iter().rposition(|&b| b == needle)`, `memrchr` will use a highly +/// optimized routine that can be up to an order of magnitude faster in some +/// cases. +/// +/// # Example +/// +/// This shows how to find the last position of a byte in a byte string. +/// +/// ``` +/// use memchr::memrchr; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr(b'o', haystack), Some(17)); +/// ``` +#[inline] +pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { + #[cfg(miri)] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + naive::memrchr(n1, haystack) + } + + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + x86::memrchr(n1, haystack) + } + + #[cfg(all( + memchr_libc, + target_os = "linux", + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri) + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + c::memrchr(n1, haystack) + } + + #[cfg(all( + not(all(memchr_libc, target_os = "linux")), + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + fallback::memrchr(n1, haystack) + } + + if haystack.is_empty() { + None + } else { + imp(needle, haystack) + } +} + +/// Like `memrchr`, but searches for either of two bytes instead of just one. +/// +/// This returns the index corresponding to the last occurrence of `needle1` or +/// the last occurrence of `needle2` in `haystack` (whichever occurs later), or +/// `None` if neither one is found. If an index is returned, it is guaranteed +/// to be less than `usize::MAX`. +/// +/// While this is operationally the same as something like +/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2)`, `memrchr2` +/// will use a highly optimized routine that can be up to an order of magnitude +/// faster in some cases. +/// +/// # Example +/// +/// This shows how to find the last position of either of two bytes in a byte +/// string. +/// +/// ``` +/// use memchr::memrchr2; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr2(b'k', b'q', haystack), Some(8)); +/// ``` +#[inline] +pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option { + #[cfg(miri)] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + naive::memrchr2(n1, n2, haystack) + } + + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + x86::memrchr2(n1, n2, haystack) + } + + #[cfg(all( + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + fallback::memrchr2(n1, n2, haystack) + } + + if haystack.is_empty() { + None + } else { + imp(needle1, needle2, haystack) + } +} + +/// Like `memrchr`, but searches for any of three bytes instead of just one. +/// +/// This returns the index corresponding to the last occurrence of `needle1`, +/// the last occurrence of `needle2`, or the last occurrence of `needle3` in +/// `haystack` (whichever occurs later), or `None` if none are found. If an +/// index is returned, it is guaranteed to be less than `usize::MAX`. +/// +/// While this is operationally the same as something like +/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2 || +/// b == needle3)`, `memrchr3` will use a highly optimized routine that can be +/// up to an order of magnitude faster in some cases. +/// +/// # Example +/// +/// This shows how to find the last position of any of three bytes in a byte +/// string. +/// +/// ``` +/// use memchr::memrchr3; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr3(b'k', b'q', b'e', haystack), Some(8)); +/// ``` +#[inline] +pub fn memrchr3( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Option { + #[cfg(miri)] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + naive::memrchr3(n1, n2, n3, haystack) + } + + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + x86::memrchr3(n1, n2, n3, haystack) + } + + #[cfg(all( + not(all(target_arch = "x86_64", memchr_runtime_simd)), + not(miri), + ))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + fallback::memrchr3(n1, n2, n3, haystack) + } + + if haystack.is_empty() { + None + } else { + imp(needle1, needle2, needle3, haystack) + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/naive.rs b/utshell-0.5.0/vendor/memchr/src/memchr/naive.rs new file mode 100644 index 00000000..3f3053d4 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/naive.rs @@ -0,0 +1,25 @@ +#![allow(dead_code)] + +pub fn memchr(n1: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == n1) +} + +pub fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == n1 || b == n2) +} + +pub fn memchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == n1 || b == n2 || b == n3) +} + +pub fn memrchr(n1: u8, haystack: &[u8]) -> Option { + haystack.iter().rposition(|&b| b == n1) +} + +pub fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + haystack.iter().rposition(|&b| b == n1 || b == n2) +} + +pub fn memrchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + haystack.iter().rposition(|&b| b == n1 || b == n2 || b == n3) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/x86/avx.rs b/utshell-0.5.0/vendor/memchr/src/memchr/x86/avx.rs new file mode 100644 index 00000000..53512309 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/x86/avx.rs @@ -0,0 +1,755 @@ +use core::{arch::x86_64::*, cmp, mem::size_of}; + +use super::sse2; + +const VECTOR_SIZE: usize = size_of::<__m256i>(); +const VECTOR_ALIGN: usize = VECTOR_SIZE - 1; + +// The number of bytes to loop at in one iteration of memchr/memrchr. +const LOOP_SIZE: usize = 4 * VECTOR_SIZE; + +// The number of bytes to loop at in one iteration of memchr2/memrchr2 and +// memchr3/memrchr3. There was no observable difference between 128 and 64 +// bytes in benchmarks. memchr3 in particular only gets a very slight speed up +// from the loop unrolling. +const LOOP_SIZE2: usize = 2 * VECTOR_SIZE; + +#[target_feature(enable = "avx2")] +pub unsafe fn memchr(n1: u8, haystack: &[u8]) -> Option { + // For a high level explanation for how this algorithm works, see the + // sse2 implementation. The avx implementation here is the same, but with + // 256-bit vectors instead of 128-bit vectors. + + // This routine is called whenever a match is detected. It is specifically + // marked as unlineable because it improves the codegen of the unrolled + // loop below. Inlining this seems to cause codegen with some extra adds + // and a load that aren't necessary. This seems to result in about a 10% + // improvement for the memchr1/crate/huge/never benchmark. + // + // Interestingly, I couldn't observe a similar improvement for memrchr. + #[cold] + #[inline(never)] + #[target_feature(enable = "avx2")] + unsafe fn matched( + start_ptr: *const u8, + ptr: *const u8, + eqa: __m256i, + eqb: __m256i, + eqc: __m256i, + eqd: __m256i, + ) -> usize { + let mut at = sub(ptr, start_ptr); + let mask = _mm256_movemask_epi8(eqa); + if mask != 0 { + return at + forward_pos(mask); + } + + at += VECTOR_SIZE; + let mask = _mm256_movemask_epi8(eqb); + if mask != 0 { + return at + forward_pos(mask); + } + + at += VECTOR_SIZE; + let mask = _mm256_movemask_epi8(eqc); + if mask != 0 { + return at + forward_pos(mask); + } + + at += VECTOR_SIZE; + let mask = _mm256_movemask_epi8(eqd); + debug_assert!(mask != 0); + at + forward_pos(mask) + } + + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + // For small haystacks, defer to the SSE2 implementation. Codegen + // suggests this completely avoids touching the AVX vectors. + return sse2::memchr(n1, haystack); + } + + let vn1 = _mm256_set1_epi8(n1 as i8); + let loop_size = cmp::min(LOOP_SIZE, haystack.len()); + if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr); + while loop_size == LOOP_SIZE && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm256_load_si256(ptr as *const __m256i); + let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i); + let c = _mm256_load_si256(ptr.add(2 * VECTOR_SIZE) as *const __m256i); + let d = _mm256_load_si256(ptr.add(3 * VECTOR_SIZE) as *const __m256i); + let eqa = _mm256_cmpeq_epi8(vn1, a); + let eqb = _mm256_cmpeq_epi8(vn1, b); + let eqc = _mm256_cmpeq_epi8(vn1, c); + let eqd = _mm256_cmpeq_epi8(vn1, d); + let or1 = _mm256_or_si256(eqa, eqb); + let or2 = _mm256_or_si256(eqc, eqd); + let or3 = _mm256_or_si256(or1, or2); + + if _mm256_movemask_epi8(or3) != 0 { + return Some(matched(start_ptr, ptr, eqa, eqb, eqc, eqd)); + } + ptr = ptr.add(loop_size); + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + debug_assert!(sub(end_ptr, ptr) >= VECTOR_SIZE); + + if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return forward_search1(start_ptr, end_ptr, ptr, vn1); + } + None +} + +#[target_feature(enable = "avx2")] +pub unsafe fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + #[cold] + #[inline(never)] + #[target_feature(enable = "avx2")] + unsafe fn matched( + start_ptr: *const u8, + ptr: *const u8, + eqa1: __m256i, + eqa2: __m256i, + eqb1: __m256i, + eqb2: __m256i, + ) -> usize { + let mut at = sub(ptr, start_ptr); + let mask1 = _mm256_movemask_epi8(eqa1); + let mask2 = _mm256_movemask_epi8(eqa2); + if mask1 != 0 || mask2 != 0 { + return at + forward_pos2(mask1, mask2); + } + + at += VECTOR_SIZE; + let mask1 = _mm256_movemask_epi8(eqb1); + let mask2 = _mm256_movemask_epi8(eqb2); + at + forward_pos2(mask1, mask2) + } + + let vn1 = _mm256_set1_epi8(n1 as i8); + let vn2 = _mm256_set1_epi8(n2 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr < end_ptr { + if *ptr == n1 || *ptr == n2 { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + return None; + } + + if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr); + while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm256_load_si256(ptr as *const __m256i); + let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i); + let eqa1 = _mm256_cmpeq_epi8(vn1, a); + let eqb1 = _mm256_cmpeq_epi8(vn1, b); + let eqa2 = _mm256_cmpeq_epi8(vn2, a); + let eqb2 = _mm256_cmpeq_epi8(vn2, b); + let or1 = _mm256_or_si256(eqa1, eqb1); + let or2 = _mm256_or_si256(eqa2, eqb2); + let or3 = _mm256_or_si256(or1, or2); + if _mm256_movemask_epi8(or3) != 0 { + return Some(matched(start_ptr, ptr, eqa1, eqa2, eqb1, eqb2)); + } + ptr = ptr.add(loop_size); + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return forward_search2(start_ptr, end_ptr, ptr, vn1, vn2); + } + None +} + +#[target_feature(enable = "avx2")] +pub unsafe fn memchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + #[cold] + #[inline(never)] + #[target_feature(enable = "avx2")] + unsafe fn matched( + start_ptr: *const u8, + ptr: *const u8, + eqa1: __m256i, + eqa2: __m256i, + eqa3: __m256i, + eqb1: __m256i, + eqb2: __m256i, + eqb3: __m256i, + ) -> usize { + let mut at = sub(ptr, start_ptr); + let mask1 = _mm256_movemask_epi8(eqa1); + let mask2 = _mm256_movemask_epi8(eqa2); + let mask3 = _mm256_movemask_epi8(eqa3); + if mask1 != 0 || mask2 != 0 || mask3 != 0 { + return at + forward_pos3(mask1, mask2, mask3); + } + + at += VECTOR_SIZE; + let mask1 = _mm256_movemask_epi8(eqb1); + let mask2 = _mm256_movemask_epi8(eqb2); + let mask3 = _mm256_movemask_epi8(eqb3); + at + forward_pos3(mask1, mask2, mask3) + } + + let vn1 = _mm256_set1_epi8(n1 as i8); + let vn2 = _mm256_set1_epi8(n2 as i8); + let vn3 = _mm256_set1_epi8(n3 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr < end_ptr { + if *ptr == n1 || *ptr == n2 || *ptr == n3 { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + return None; + } + + if let Some(i) = forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) { + return Some(i); + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr); + while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm256_load_si256(ptr as *const __m256i); + let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i); + let eqa1 = _mm256_cmpeq_epi8(vn1, a); + let eqb1 = _mm256_cmpeq_epi8(vn1, b); + let eqa2 = _mm256_cmpeq_epi8(vn2, a); + let eqb2 = _mm256_cmpeq_epi8(vn2, b); + let eqa3 = _mm256_cmpeq_epi8(vn3, a); + let eqb3 = _mm256_cmpeq_epi8(vn3, b); + let or1 = _mm256_or_si256(eqa1, eqb1); + let or2 = _mm256_or_si256(eqa2, eqb2); + let or3 = _mm256_or_si256(eqa3, eqb3); + let or4 = _mm256_or_si256(or1, or2); + let or5 = _mm256_or_si256(or3, or4); + if _mm256_movemask_epi8(or5) != 0 { + return Some(matched( + start_ptr, ptr, eqa1, eqa2, eqa3, eqb1, eqb2, eqb3, + )); + } + ptr = ptr.add(loop_size); + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + if let Some(i) = + forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) + { + return Some(i); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3); + } + None +} + +#[target_feature(enable = "avx2")] +pub unsafe fn memrchr(n1: u8, haystack: &[u8]) -> Option { + let vn1 = _mm256_set1_epi8(n1 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr > start_ptr { + ptr = ptr.offset(-1); + if *ptr == n1 { + return Some(sub(ptr, start_ptr)); + } + } + return None; + } + + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + + ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + ptr = ptr.sub(loop_size); + let a = _mm256_load_si256(ptr as *const __m256i); + let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i); + let c = _mm256_load_si256(ptr.add(2 * VECTOR_SIZE) as *const __m256i); + let d = _mm256_load_si256(ptr.add(3 * VECTOR_SIZE) as *const __m256i); + let eqa = _mm256_cmpeq_epi8(vn1, a); + let eqb = _mm256_cmpeq_epi8(vn1, b); + let eqc = _mm256_cmpeq_epi8(vn1, c); + let eqd = _mm256_cmpeq_epi8(vn1, d); + let or1 = _mm256_or_si256(eqa, eqb); + let or2 = _mm256_or_si256(eqc, eqd); + let or3 = _mm256_or_si256(or1, or2); + if _mm256_movemask_epi8(or3) != 0 { + let mut at = sub(ptr.add(3 * VECTOR_SIZE), start_ptr); + let mask = _mm256_movemask_epi8(eqd); + if mask != 0 { + return Some(at + reverse_pos(mask)); + } + + at -= VECTOR_SIZE; + let mask = _mm256_movemask_epi8(eqc); + if mask != 0 { + return Some(at + reverse_pos(mask)); + } + + at -= VECTOR_SIZE; + let mask = _mm256_movemask_epi8(eqb); + if mask != 0 { + return Some(at + reverse_pos(mask)); + } + + at -= VECTOR_SIZE; + let mask = _mm256_movemask_epi8(eqa); + debug_assert!(mask != 0); + return Some(at + reverse_pos(mask)); + } + } + while ptr >= start_ptr.add(VECTOR_SIZE) { + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + } + if ptr > start_ptr { + debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE); + return reverse_search1(start_ptr, end_ptr, start_ptr, vn1); + } + None +} + +#[target_feature(enable = "avx2")] +pub unsafe fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + let vn1 = _mm256_set1_epi8(n1 as i8); + let vn2 = _mm256_set1_epi8(n2 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr > start_ptr { + ptr = ptr.offset(-1); + if *ptr == n1 || *ptr == n2 { + return Some(sub(ptr, start_ptr)); + } + } + return None; + } + + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + + ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + ptr = ptr.sub(loop_size); + let a = _mm256_load_si256(ptr as *const __m256i); + let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i); + let eqa1 = _mm256_cmpeq_epi8(vn1, a); + let eqb1 = _mm256_cmpeq_epi8(vn1, b); + let eqa2 = _mm256_cmpeq_epi8(vn2, a); + let eqb2 = _mm256_cmpeq_epi8(vn2, b); + let or1 = _mm256_or_si256(eqa1, eqb1); + let or2 = _mm256_or_si256(eqa2, eqb2); + let or3 = _mm256_or_si256(or1, or2); + if _mm256_movemask_epi8(or3) != 0 { + let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr); + let mask1 = _mm256_movemask_epi8(eqb1); + let mask2 = _mm256_movemask_epi8(eqb2); + if mask1 != 0 || mask2 != 0 { + return Some(at + reverse_pos2(mask1, mask2)); + } + + at -= VECTOR_SIZE; + let mask1 = _mm256_movemask_epi8(eqa1); + let mask2 = _mm256_movemask_epi8(eqa2); + return Some(at + reverse_pos2(mask1, mask2)); + } + } + while ptr >= start_ptr.add(VECTOR_SIZE) { + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + } + if ptr > start_ptr { + debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE); + return reverse_search2(start_ptr, end_ptr, start_ptr, vn1, vn2); + } + None +} + +#[target_feature(enable = "avx2")] +pub unsafe fn memrchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + let vn1 = _mm256_set1_epi8(n1 as i8); + let vn2 = _mm256_set1_epi8(n2 as i8); + let vn3 = _mm256_set1_epi8(n3 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr > start_ptr { + ptr = ptr.offset(-1); + if *ptr == n1 || *ptr == n2 || *ptr == n3 { + return Some(sub(ptr, start_ptr)); + } + } + return None; + } + + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) { + return Some(i); + } + + ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + ptr = ptr.sub(loop_size); + let a = _mm256_load_si256(ptr as *const __m256i); + let b = _mm256_load_si256(ptr.add(VECTOR_SIZE) as *const __m256i); + let eqa1 = _mm256_cmpeq_epi8(vn1, a); + let eqb1 = _mm256_cmpeq_epi8(vn1, b); + let eqa2 = _mm256_cmpeq_epi8(vn2, a); + let eqb2 = _mm256_cmpeq_epi8(vn2, b); + let eqa3 = _mm256_cmpeq_epi8(vn3, a); + let eqb3 = _mm256_cmpeq_epi8(vn3, b); + let or1 = _mm256_or_si256(eqa1, eqb1); + let or2 = _mm256_or_si256(eqa2, eqb2); + let or3 = _mm256_or_si256(eqa3, eqb3); + let or4 = _mm256_or_si256(or1, or2); + let or5 = _mm256_or_si256(or3, or4); + if _mm256_movemask_epi8(or5) != 0 { + let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr); + let mask1 = _mm256_movemask_epi8(eqb1); + let mask2 = _mm256_movemask_epi8(eqb2); + let mask3 = _mm256_movemask_epi8(eqb3); + if mask1 != 0 || mask2 != 0 || mask3 != 0 { + return Some(at + reverse_pos3(mask1, mask2, mask3)); + } + + at -= VECTOR_SIZE; + let mask1 = _mm256_movemask_epi8(eqa1); + let mask2 = _mm256_movemask_epi8(eqa2); + let mask3 = _mm256_movemask_epi8(eqa3); + return Some(at + reverse_pos3(mask1, mask2, mask3)); + } + } + while ptr >= start_ptr.add(VECTOR_SIZE) { + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = + reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) + { + return Some(i); + } + } + if ptr > start_ptr { + debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE); + return reverse_search3(start_ptr, end_ptr, start_ptr, vn1, vn2, vn3); + } + None +} + +#[target_feature(enable = "avx2")] +unsafe fn forward_search1( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m256i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm256_loadu_si256(ptr as *const __m256i); + let mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(chunk, vn1)); + if mask != 0 { + Some(sub(ptr, start_ptr) + forward_pos(mask)) + } else { + None + } +} + +#[target_feature(enable = "avx2")] +unsafe fn forward_search2( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m256i, + vn2: __m256i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm256_loadu_si256(ptr as *const __m256i); + let eq1 = _mm256_cmpeq_epi8(chunk, vn1); + let eq2 = _mm256_cmpeq_epi8(chunk, vn2); + if _mm256_movemask_epi8(_mm256_or_si256(eq1, eq2)) != 0 { + let mask1 = _mm256_movemask_epi8(eq1); + let mask2 = _mm256_movemask_epi8(eq2); + Some(sub(ptr, start_ptr) + forward_pos2(mask1, mask2)) + } else { + None + } +} + +#[target_feature(enable = "avx2")] +unsafe fn forward_search3( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m256i, + vn2: __m256i, + vn3: __m256i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm256_loadu_si256(ptr as *const __m256i); + let eq1 = _mm256_cmpeq_epi8(chunk, vn1); + let eq2 = _mm256_cmpeq_epi8(chunk, vn2); + let eq3 = _mm256_cmpeq_epi8(chunk, vn3); + let or = _mm256_or_si256(eq1, eq2); + if _mm256_movemask_epi8(_mm256_or_si256(or, eq3)) != 0 { + let mask1 = _mm256_movemask_epi8(eq1); + let mask2 = _mm256_movemask_epi8(eq2); + let mask3 = _mm256_movemask_epi8(eq3); + Some(sub(ptr, start_ptr) + forward_pos3(mask1, mask2, mask3)) + } else { + None + } +} + +#[target_feature(enable = "avx2")] +unsafe fn reverse_search1( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m256i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm256_loadu_si256(ptr as *const __m256i); + let mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(vn1, chunk)); + if mask != 0 { + Some(sub(ptr, start_ptr) + reverse_pos(mask)) + } else { + None + } +} + +#[target_feature(enable = "avx2")] +unsafe fn reverse_search2( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m256i, + vn2: __m256i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm256_loadu_si256(ptr as *const __m256i); + let eq1 = _mm256_cmpeq_epi8(chunk, vn1); + let eq2 = _mm256_cmpeq_epi8(chunk, vn2); + if _mm256_movemask_epi8(_mm256_or_si256(eq1, eq2)) != 0 { + let mask1 = _mm256_movemask_epi8(eq1); + let mask2 = _mm256_movemask_epi8(eq2); + Some(sub(ptr, start_ptr) + reverse_pos2(mask1, mask2)) + } else { + None + } +} + +#[target_feature(enable = "avx2")] +unsafe fn reverse_search3( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m256i, + vn2: __m256i, + vn3: __m256i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm256_loadu_si256(ptr as *const __m256i); + let eq1 = _mm256_cmpeq_epi8(chunk, vn1); + let eq2 = _mm256_cmpeq_epi8(chunk, vn2); + let eq3 = _mm256_cmpeq_epi8(chunk, vn3); + let or = _mm256_or_si256(eq1, eq2); + if _mm256_movemask_epi8(_mm256_or_si256(or, eq3)) != 0 { + let mask1 = _mm256_movemask_epi8(eq1); + let mask2 = _mm256_movemask_epi8(eq2); + let mask3 = _mm256_movemask_epi8(eq3); + Some(sub(ptr, start_ptr) + reverse_pos3(mask1, mask2, mask3)) + } else { + None + } +} + +/// Compute the position of the first matching byte from the given mask. The +/// position returned is always in the range [0, 31]. +/// +/// The mask given is expected to be the result of _mm256_movemask_epi8. +fn forward_pos(mask: i32) -> usize { + // We are dealing with little endian here, where the most significant byte + // is at a higher address. That means the least significant bit that is set + // corresponds to the position of our first matching byte. That position + // corresponds to the number of zeros after the least significant bit. + mask.trailing_zeros() as usize +} + +/// Compute the position of the first matching byte from the given masks. The +/// position returned is always in the range [0, 31]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm256_movemask_epi8, +/// where at least one of the masks is non-zero (i.e., indicates a match). +fn forward_pos2(mask1: i32, mask2: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0); + + forward_pos(mask1 | mask2) +} + +/// Compute the position of the first matching byte from the given masks. The +/// position returned is always in the range [0, 31]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm256_movemask_epi8, +/// where at least one of the masks is non-zero (i.e., indicates a match). +fn forward_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0); + + forward_pos(mask1 | mask2 | mask3) +} + +/// Compute the position of the last matching byte from the given mask. The +/// position returned is always in the range [0, 31]. +/// +/// The mask given is expected to be the result of _mm256_movemask_epi8. +fn reverse_pos(mask: i32) -> usize { + // We are dealing with little endian here, where the most significant byte + // is at a higher address. That means the most significant bit that is set + // corresponds to the position of our last matching byte. The position from + // the end of the mask is therefore the number of leading zeros in a 32 + // bit integer, and the position from the start of the mask is therefore + // 32 - (leading zeros) - 1. + VECTOR_SIZE - (mask as u32).leading_zeros() as usize - 1 +} + +/// Compute the position of the last matching byte from the given masks. The +/// position returned is always in the range [0, 31]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm256_movemask_epi8, +/// where at least one of the masks is non-zero (i.e., indicates a match). +fn reverse_pos2(mask1: i32, mask2: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0); + + reverse_pos(mask1 | mask2) +} + +/// Compute the position of the last matching byte from the given masks. The +/// position returned is always in the range [0, 31]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm256_movemask_epi8, +/// where at least one of the masks is non-zero (i.e., indicates a match). +fn reverse_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0); + + reverse_pos(mask1 | mask2 | mask3) +} + +/// Subtract `b` from `a` and return the difference. `a` should be greater than +/// or equal to `b`. +fn sub(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/x86/mod.rs b/utshell-0.5.0/vendor/memchr/src/memchr/x86/mod.rs new file mode 100644 index 00000000..aec35dbf --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/x86/mod.rs @@ -0,0 +1,148 @@ +use super::fallback; + +// We only use AVX when we can detect at runtime whether it's available, which +// requires std. +#[cfg(feature = "std")] +mod avx; +mod sse2; + +/// This macro employs a gcc-like "ifunc" trick where by upon first calling +/// `memchr` (for example), CPU feature detection will be performed at runtime +/// to determine the best implementation to use. After CPU feature detection +/// is done, we replace `memchr`'s function pointer with the selection. Upon +/// subsequent invocations, the CPU-specific routine is invoked directly, which +/// skips the CPU feature detection and subsequent branch that's required. +/// +/// While this typically doesn't matter for rare occurrences or when used on +/// larger haystacks, `memchr` can be called in tight loops where the overhead +/// of this branch can actually add up *and is measurable*. This trick was +/// necessary to bring this implementation up to glibc's speeds for the 'tiny' +/// benchmarks, for example. +/// +/// At some point, I expect the Rust ecosystem will get a nice macro for doing +/// exactly this, at which point, we can replace our hand-jammed version of it. +/// +/// N.B. The ifunc strategy does prevent function inlining of course, but +/// on modern CPUs, you'll probably end up with the AVX2 implementation, +/// which probably can't be inlined anyway---unless you've compiled your +/// entire program with AVX2 enabled. However, even then, the various memchr +/// implementations aren't exactly small, so inlining might not help anyway! +/// +/// # Safety +/// +/// Callers must ensure that fnty is function pointer type. +#[cfg(feature = "std")] +macro_rules! unsafe_ifunc { + ($fnty:ty, $name:ident, $haystack:ident, $($needle:ident),+) => {{ + use std::{mem, sync::atomic::{AtomicPtr, Ordering}}; + + type FnRaw = *mut (); + + static FN: AtomicPtr<()> = AtomicPtr::new(detect as FnRaw); + + fn detect($($needle: u8),+, haystack: &[u8]) -> Option { + let fun = + if cfg!(memchr_runtime_avx) && is_x86_feature_detected!("avx2") { + avx::$name as FnRaw + } else if cfg!(memchr_runtime_sse2) { + sse2::$name as FnRaw + } else { + fallback::$name as FnRaw + }; + FN.store(fun as FnRaw, Ordering::Relaxed); + // SAFETY: By virtue of the caller contract, $fnty is a function + // pointer, which is always safe to transmute with a *mut (). + // Also, if 'fun is the AVX routine, then it is guaranteed to be + // supported since we checked the avx2 feature. + unsafe { + mem::transmute::(fun)($($needle),+, haystack) + } + } + + // SAFETY: By virtue of the caller contract, $fnty is a function + // pointer, which is always safe to transmute with a *mut (). Also, if + // 'fun is the AVX routine, then it is guaranteed to be supported since + // we checked the avx2 feature. + unsafe { + let fun = FN.load(Ordering::Relaxed); + mem::transmute::(fun)($($needle),+, $haystack) + } + }} +} + +/// When std isn't available to provide runtime CPU feature detection, or if +/// runtime CPU feature detection has been explicitly disabled, then just +/// call our optimized SSE2 routine directly. SSE2 is avalbale on all x86_64 +/// targets, so no CPU feature detection is necessary. +/// +/// # Safety +/// +/// There are no safety requirements for this definition of the macro. It is +/// safe for all inputs since it is restricted to either the fallback routine +/// or the SSE routine, which is always safe to call on x86_64. +#[cfg(not(feature = "std"))] +macro_rules! unsafe_ifunc { + ($fnty:ty, $name:ident, $haystack:ident, $($needle:ident),+) => {{ + if cfg!(memchr_runtime_sse2) { + unsafe { sse2::$name($($needle),+, $haystack) } + } else { + fallback::$name($($needle),+, $haystack) + } + }} +} + +#[inline(always)] +pub fn memchr(n1: u8, haystack: &[u8]) -> Option { + unsafe_ifunc!(fn(u8, &[u8]) -> Option, memchr, haystack, n1) +} + +#[inline(always)] +pub fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + unsafe_ifunc!( + fn(u8, u8, &[u8]) -> Option, + memchr2, + haystack, + n1, + n2 + ) +} + +#[inline(always)] +pub fn memchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + unsafe_ifunc!( + fn(u8, u8, u8, &[u8]) -> Option, + memchr3, + haystack, + n1, + n2, + n3 + ) +} + +#[inline(always)] +pub fn memrchr(n1: u8, haystack: &[u8]) -> Option { + unsafe_ifunc!(fn(u8, &[u8]) -> Option, memrchr, haystack, n1) +} + +#[inline(always)] +pub fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + unsafe_ifunc!( + fn(u8, u8, &[u8]) -> Option, + memrchr2, + haystack, + n1, + n2 + ) +} + +#[inline(always)] +pub fn memrchr3(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + unsafe_ifunc!( + fn(u8, u8, u8, &[u8]) -> Option, + memrchr3, + haystack, + n1, + n2, + n3 + ) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/x86/sse2.rs b/utshell-0.5.0/vendor/memchr/src/memchr/x86/sse2.rs new file mode 100644 index 00000000..b7b3a932 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/x86/sse2.rs @@ -0,0 +1,791 @@ +use core::{arch::x86_64::*, cmp, mem::size_of}; + +const VECTOR_SIZE: usize = size_of::<__m128i>(); +const VECTOR_ALIGN: usize = VECTOR_SIZE - 1; + +// The number of bytes to loop at in one iteration of memchr/memrchr. +const LOOP_SIZE: usize = 4 * VECTOR_SIZE; + +// The number of bytes to loop at in one iteration of memchr2/memrchr2 and +// memchr3/memrchr3. There was no observable difference between 64 and 32 bytes +// in benchmarks. memchr3 in particular only gets a very slight speed up from +// the loop unrolling. +const LOOP_SIZE2: usize = 2 * VECTOR_SIZE; + +#[target_feature(enable = "sse2")] +pub unsafe fn memchr(n1: u8, haystack: &[u8]) -> Option { + // What follows is a fast SSE2-only algorithm to detect the position of + // `n1` in `haystack` if it exists. From what I know, this is the "classic" + // algorithm. I believe it can be found in places like glibc and Go's + // standard library. It appears to be well known and is elaborated on in + // more detail here: https://gms.tf/stdfind-and-memchr-optimizations.html + // + // While this routine is very long, the basic idea is actually very simple + // and can be expressed straight-forwardly in pseudo code: + // + // needle = (n1 << 15) | (n1 << 14) | ... | (n1 << 1) | n1 + // // Note: shift amount in bytes + // + // while i <= haystack.len() - 16: + // // A 16 byte vector. Each byte in chunk corresponds to a byte in + // // the haystack. + // chunk = haystack[i:i+16] + // // Compare bytes in needle with bytes in chunk. The result is a 16 + // // byte chunk where each byte is 0xFF if the corresponding bytes + // // in needle and chunk were equal, or 0x00 otherwise. + // eqs = cmpeq(needle, chunk) + // // Return a 32 bit integer where the most significant 16 bits + // // are always 0 and the lower 16 bits correspond to whether the + // // most significant bit in the correspond byte in `eqs` is set. + // // In other words, `mask as u16` has bit i set if and only if + // // needle[i] == chunk[i]. + // mask = movemask(eqs) + // + // // Mask is 0 if there is no match, and non-zero otherwise. + // if mask != 0: + // // trailing_zeros tells us the position of the least significant + // // bit that is set. + // return i + trailing_zeros(mask) + // + // // haystack length may not be a multiple of 16, so search the rest. + // while i < haystack.len(): + // if haystack[i] == n1: + // return i + // + // // No match found. + // return NULL + // + // In fact, we could loosely translate the above code to Rust line-for-line + // and it would be a pretty fast algorithm. But, we pull out all the stops + // to go as fast as possible: + // + // 1. We use aligned loads. That is, we do some finagling to make sure our + // primary loop not only proceeds in increments of 16 bytes, but that + // the address of haystack's pointer that we dereference is aligned to + // 16 bytes. 16 is a magic number here because it is the size of SSE2 + // 128-bit vector. (For the AVX2 algorithm, 32 is the magic number.) + // Therefore, to get aligned loads, our pointer's address must be evenly + // divisible by 16. + // 2. Our primary loop proceeds 64 bytes at a time instead of 16. It's + // kind of like loop unrolling, but we combine the equality comparisons + // using a vector OR such that we only need to extract a single mask to + // determine whether a match exists or not. If so, then we do some + // book-keeping to determine the precise location but otherwise mush on. + // 3. We use our "chunk" comparison routine in as many places as possible, + // even if it means using unaligned loads. In particular, if haystack + // starts with an unaligned address, then we do an unaligned load to + // search the first 16 bytes. We then start our primary loop at the + // smallest subsequent aligned address, which will actually overlap with + // previously searched bytes. But we're OK with that. We do a similar + // dance at the end of our primary loop. Finally, to avoid a + // byte-at-a-time loop at the end, we do a final 16 byte unaligned load + // that may overlap with a previous load. This is OK because it converts + // a loop into a small number of very fast vector instructions. + // + // The primary downside of this algorithm is that it's effectively + // completely unsafe. Therefore, we have to be super careful to avoid + // undefined behavior: + // + // 1. We use raw pointers everywhere. Not only does dereferencing a pointer + // require the pointer to be valid, but we actually can't even store the + // address of an invalid pointer (unless it's 1 past the end of + // haystack) without sacrificing performance. + // 2. _mm_loadu_si128 is used when you don't care about alignment, and + // _mm_load_si128 is used when you do care. You cannot use the latter + // on unaligned pointers. + // 3. We make liberal use of debug_assert! to check assumptions. + // 4. We make a concerted effort to stick with pointers instead of indices. + // Indices are nicer because there's less to worry about with them (see + // above about pointer offsets), but I could not get the compiler to + // produce as good of code as what the below produces. In any case, + // pointers are what we really care about here, and alignment is + // expressed a bit more naturally with them. + // + // In general, most of the algorithms in this crate have a similar + // structure to what you see below, so this comment applies fairly well to + // all of them. + + let vn1 = _mm_set1_epi8(n1 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr < end_ptr { + if *ptr == n1 { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + return None; + } + + if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr); + while loop_size == LOOP_SIZE && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let c = _mm_load_si128(ptr.add(2 * VECTOR_SIZE) as *const __m128i); + let d = _mm_load_si128(ptr.add(3 * VECTOR_SIZE) as *const __m128i); + let eqa = _mm_cmpeq_epi8(vn1, a); + let eqb = _mm_cmpeq_epi8(vn1, b); + let eqc = _mm_cmpeq_epi8(vn1, c); + let eqd = _mm_cmpeq_epi8(vn1, d); + let or1 = _mm_or_si128(eqa, eqb); + let or2 = _mm_or_si128(eqc, eqd); + let or3 = _mm_or_si128(or1, or2); + if _mm_movemask_epi8(or3) != 0 { + let mut at = sub(ptr, start_ptr); + let mask = _mm_movemask_epi8(eqa); + if mask != 0 { + return Some(at + forward_pos(mask)); + } + + at += VECTOR_SIZE; + let mask = _mm_movemask_epi8(eqb); + if mask != 0 { + return Some(at + forward_pos(mask)); + } + + at += VECTOR_SIZE; + let mask = _mm_movemask_epi8(eqc); + if mask != 0 { + return Some(at + forward_pos(mask)); + } + + at += VECTOR_SIZE; + let mask = _mm_movemask_epi8(eqd); + debug_assert!(mask != 0); + return Some(at + forward_pos(mask)); + } + ptr = ptr.add(loop_size); + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + debug_assert!(sub(end_ptr, ptr) >= VECTOR_SIZE); + + if let Some(i) = forward_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return forward_search1(start_ptr, end_ptr, ptr, vn1); + } + None +} + +#[target_feature(enable = "sse2")] +pub unsafe fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + let vn1 = _mm_set1_epi8(n1 as i8); + let vn2 = _mm_set1_epi8(n2 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr < end_ptr { + if *ptr == n1 || *ptr == n2 { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + return None; + } + + if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr); + while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let eqa1 = _mm_cmpeq_epi8(vn1, a); + let eqb1 = _mm_cmpeq_epi8(vn1, b); + let eqa2 = _mm_cmpeq_epi8(vn2, a); + let eqb2 = _mm_cmpeq_epi8(vn2, b); + let or1 = _mm_or_si128(eqa1, eqb1); + let or2 = _mm_or_si128(eqa2, eqb2); + let or3 = _mm_or_si128(or1, or2); + if _mm_movemask_epi8(or3) != 0 { + let mut at = sub(ptr, start_ptr); + let mask1 = _mm_movemask_epi8(eqa1); + let mask2 = _mm_movemask_epi8(eqa2); + if mask1 != 0 || mask2 != 0 { + return Some(at + forward_pos2(mask1, mask2)); + } + + at += VECTOR_SIZE; + let mask1 = _mm_movemask_epi8(eqb1); + let mask2 = _mm_movemask_epi8(eqb2); + return Some(at + forward_pos2(mask1, mask2)); + } + ptr = ptr.add(loop_size); + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + if let Some(i) = forward_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return forward_search2(start_ptr, end_ptr, ptr, vn1, vn2); + } + None +} + +#[target_feature(enable = "sse2")] +pub unsafe fn memchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + let vn1 = _mm_set1_epi8(n1 as i8); + let vn2 = _mm_set1_epi8(n2 as i8); + let vn3 = _mm_set1_epi8(n3 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr < end_ptr { + if *ptr == n1 || *ptr == n2 || *ptr == n3 { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + return None; + } + + if let Some(i) = forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) { + return Some(i); + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr && end_ptr.sub(VECTOR_SIZE) >= start_ptr); + while loop_size == LOOP_SIZE2 && ptr <= end_ptr.sub(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let eqa1 = _mm_cmpeq_epi8(vn1, a); + let eqb1 = _mm_cmpeq_epi8(vn1, b); + let eqa2 = _mm_cmpeq_epi8(vn2, a); + let eqb2 = _mm_cmpeq_epi8(vn2, b); + let eqa3 = _mm_cmpeq_epi8(vn3, a); + let eqb3 = _mm_cmpeq_epi8(vn3, b); + let or1 = _mm_or_si128(eqa1, eqb1); + let or2 = _mm_or_si128(eqa2, eqb2); + let or3 = _mm_or_si128(eqa3, eqb3); + let or4 = _mm_or_si128(or1, or2); + let or5 = _mm_or_si128(or3, or4); + if _mm_movemask_epi8(or5) != 0 { + let mut at = sub(ptr, start_ptr); + let mask1 = _mm_movemask_epi8(eqa1); + let mask2 = _mm_movemask_epi8(eqa2); + let mask3 = _mm_movemask_epi8(eqa3); + if mask1 != 0 || mask2 != 0 || mask3 != 0 { + return Some(at + forward_pos3(mask1, mask2, mask3)); + } + + at += VECTOR_SIZE; + let mask1 = _mm_movemask_epi8(eqb1); + let mask2 = _mm_movemask_epi8(eqb2); + let mask3 = _mm_movemask_epi8(eqb3); + return Some(at + forward_pos3(mask1, mask2, mask3)); + } + ptr = ptr.add(loop_size); + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + if let Some(i) = + forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) + { + return Some(i); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3); + } + None +} + +#[target_feature(enable = "sse2")] +pub unsafe fn memrchr(n1: u8, haystack: &[u8]) -> Option { + let vn1 = _mm_set1_epi8(n1 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr > start_ptr { + ptr = ptr.offset(-1); + if *ptr == n1 { + return Some(sub(ptr, start_ptr)); + } + } + return None; + } + + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + + ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + ptr = ptr.sub(loop_size); + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let c = _mm_load_si128(ptr.add(2 * VECTOR_SIZE) as *const __m128i); + let d = _mm_load_si128(ptr.add(3 * VECTOR_SIZE) as *const __m128i); + let eqa = _mm_cmpeq_epi8(vn1, a); + let eqb = _mm_cmpeq_epi8(vn1, b); + let eqc = _mm_cmpeq_epi8(vn1, c); + let eqd = _mm_cmpeq_epi8(vn1, d); + let or1 = _mm_or_si128(eqa, eqb); + let or2 = _mm_or_si128(eqc, eqd); + let or3 = _mm_or_si128(or1, or2); + if _mm_movemask_epi8(or3) != 0 { + let mut at = sub(ptr.add(3 * VECTOR_SIZE), start_ptr); + let mask = _mm_movemask_epi8(eqd); + if mask != 0 { + return Some(at + reverse_pos(mask)); + } + + at -= VECTOR_SIZE; + let mask = _mm_movemask_epi8(eqc); + if mask != 0 { + return Some(at + reverse_pos(mask)); + } + + at -= VECTOR_SIZE; + let mask = _mm_movemask_epi8(eqb); + if mask != 0 { + return Some(at + reverse_pos(mask)); + } + + at -= VECTOR_SIZE; + let mask = _mm_movemask_epi8(eqa); + debug_assert!(mask != 0); + return Some(at + reverse_pos(mask)); + } + } + while ptr >= start_ptr.add(VECTOR_SIZE) { + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search1(start_ptr, end_ptr, ptr, vn1) { + return Some(i); + } + } + if ptr > start_ptr { + debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE); + return reverse_search1(start_ptr, end_ptr, start_ptr, vn1); + } + None +} + +#[target_feature(enable = "sse2")] +pub unsafe fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + let vn1 = _mm_set1_epi8(n1 as i8); + let vn2 = _mm_set1_epi8(n2 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr > start_ptr { + ptr = ptr.offset(-1); + if *ptr == n1 || *ptr == n2 { + return Some(sub(ptr, start_ptr)); + } + } + return None; + } + + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + + ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + ptr = ptr.sub(loop_size); + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let eqa1 = _mm_cmpeq_epi8(vn1, a); + let eqb1 = _mm_cmpeq_epi8(vn1, b); + let eqa2 = _mm_cmpeq_epi8(vn2, a); + let eqb2 = _mm_cmpeq_epi8(vn2, b); + let or1 = _mm_or_si128(eqa1, eqb1); + let or2 = _mm_or_si128(eqa2, eqb2); + let or3 = _mm_or_si128(or1, or2); + if _mm_movemask_epi8(or3) != 0 { + let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr); + let mask1 = _mm_movemask_epi8(eqb1); + let mask2 = _mm_movemask_epi8(eqb2); + if mask1 != 0 || mask2 != 0 { + return Some(at + reverse_pos2(mask1, mask2)); + } + + at -= VECTOR_SIZE; + let mask1 = _mm_movemask_epi8(eqa1); + let mask2 = _mm_movemask_epi8(eqa2); + return Some(at + reverse_pos2(mask1, mask2)); + } + } + while ptr >= start_ptr.add(VECTOR_SIZE) { + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search2(start_ptr, end_ptr, ptr, vn1, vn2) { + return Some(i); + } + } + if ptr > start_ptr { + debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE); + return reverse_search2(start_ptr, end_ptr, start_ptr, vn1, vn2); + } + None +} + +#[target_feature(enable = "sse2")] +pub unsafe fn memrchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + let vn1 = _mm_set1_epi8(n1 as i8); + let vn2 = _mm_set1_epi8(n2 as i8); + let vn3 = _mm_set1_epi8(n3 as i8); + let len = haystack.len(); + let loop_size = cmp::min(LOOP_SIZE2, len); + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let mut ptr = end_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr > start_ptr { + ptr = ptr.offset(-1); + if *ptr == n1 || *ptr == n2 || *ptr == n3 { + return Some(sub(ptr, start_ptr)); + } + } + return None; + } + + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) { + return Some(i); + } + + ptr = (end_ptr as usize & !VECTOR_ALIGN) as *const u8; + debug_assert!(start_ptr <= ptr && ptr <= end_ptr); + while loop_size == LOOP_SIZE2 && ptr >= start_ptr.add(loop_size) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + ptr = ptr.sub(loop_size); + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let eqa1 = _mm_cmpeq_epi8(vn1, a); + let eqb1 = _mm_cmpeq_epi8(vn1, b); + let eqa2 = _mm_cmpeq_epi8(vn2, a); + let eqb2 = _mm_cmpeq_epi8(vn2, b); + let eqa3 = _mm_cmpeq_epi8(vn3, a); + let eqb3 = _mm_cmpeq_epi8(vn3, b); + let or1 = _mm_or_si128(eqa1, eqb1); + let or2 = _mm_or_si128(eqa2, eqb2); + let or3 = _mm_or_si128(eqa3, eqb3); + let or4 = _mm_or_si128(or1, or2); + let or5 = _mm_or_si128(or3, or4); + if _mm_movemask_epi8(or5) != 0 { + let mut at = sub(ptr.add(VECTOR_SIZE), start_ptr); + let mask1 = _mm_movemask_epi8(eqb1); + let mask2 = _mm_movemask_epi8(eqb2); + let mask3 = _mm_movemask_epi8(eqb3); + if mask1 != 0 || mask2 != 0 || mask3 != 0 { + return Some(at + reverse_pos3(mask1, mask2, mask3)); + } + + at -= VECTOR_SIZE; + let mask1 = _mm_movemask_epi8(eqa1); + let mask2 = _mm_movemask_epi8(eqa2); + let mask3 = _mm_movemask_epi8(eqa3); + return Some(at + reverse_pos3(mask1, mask2, mask3)); + } + } + while ptr >= start_ptr.add(VECTOR_SIZE) { + ptr = ptr.sub(VECTOR_SIZE); + if let Some(i) = + reverse_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3) + { + return Some(i); + } + } + if ptr > start_ptr { + debug_assert!(sub(ptr, start_ptr) < VECTOR_SIZE); + return reverse_search3(start_ptr, end_ptr, start_ptr, vn1, vn2, vn3); + } + None +} + +#[target_feature(enable = "sse2")] +pub unsafe fn forward_search1( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m128i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let mask = _mm_movemask_epi8(_mm_cmpeq_epi8(chunk, vn1)); + if mask != 0 { + Some(sub(ptr, start_ptr) + forward_pos(mask)) + } else { + None + } +} + +#[target_feature(enable = "sse2")] +unsafe fn forward_search2( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m128i, + vn2: __m128i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let eq1 = _mm_cmpeq_epi8(chunk, vn1); + let eq2 = _mm_cmpeq_epi8(chunk, vn2); + if _mm_movemask_epi8(_mm_or_si128(eq1, eq2)) != 0 { + let mask1 = _mm_movemask_epi8(eq1); + let mask2 = _mm_movemask_epi8(eq2); + Some(sub(ptr, start_ptr) + forward_pos2(mask1, mask2)) + } else { + None + } +} + +#[target_feature(enable = "sse2")] +pub unsafe fn forward_search3( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m128i, + vn2: __m128i, + vn3: __m128i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let eq1 = _mm_cmpeq_epi8(chunk, vn1); + let eq2 = _mm_cmpeq_epi8(chunk, vn2); + let eq3 = _mm_cmpeq_epi8(chunk, vn3); + let or = _mm_or_si128(eq1, eq2); + if _mm_movemask_epi8(_mm_or_si128(or, eq3)) != 0 { + let mask1 = _mm_movemask_epi8(eq1); + let mask2 = _mm_movemask_epi8(eq2); + let mask3 = _mm_movemask_epi8(eq3); + Some(sub(ptr, start_ptr) + forward_pos3(mask1, mask2, mask3)) + } else { + None + } +} + +#[target_feature(enable = "sse2")] +unsafe fn reverse_search1( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m128i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let mask = _mm_movemask_epi8(_mm_cmpeq_epi8(vn1, chunk)); + if mask != 0 { + Some(sub(ptr, start_ptr) + reverse_pos(mask)) + } else { + None + } +} + +#[target_feature(enable = "sse2")] +unsafe fn reverse_search2( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m128i, + vn2: __m128i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let eq1 = _mm_cmpeq_epi8(chunk, vn1); + let eq2 = _mm_cmpeq_epi8(chunk, vn2); + if _mm_movemask_epi8(_mm_or_si128(eq1, eq2)) != 0 { + let mask1 = _mm_movemask_epi8(eq1); + let mask2 = _mm_movemask_epi8(eq2); + Some(sub(ptr, start_ptr) + reverse_pos2(mask1, mask2)) + } else { + None + } +} + +#[target_feature(enable = "sse2")] +unsafe fn reverse_search3( + start_ptr: *const u8, + end_ptr: *const u8, + ptr: *const u8, + vn1: __m128i, + vn2: __m128i, + vn3: __m128i, +) -> Option { + debug_assert!(sub(end_ptr, start_ptr) >= VECTOR_SIZE); + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr.sub(VECTOR_SIZE)); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let eq1 = _mm_cmpeq_epi8(chunk, vn1); + let eq2 = _mm_cmpeq_epi8(chunk, vn2); + let eq3 = _mm_cmpeq_epi8(chunk, vn3); + let or = _mm_or_si128(eq1, eq2); + if _mm_movemask_epi8(_mm_or_si128(or, eq3)) != 0 { + let mask1 = _mm_movemask_epi8(eq1); + let mask2 = _mm_movemask_epi8(eq2); + let mask3 = _mm_movemask_epi8(eq3); + Some(sub(ptr, start_ptr) + reverse_pos3(mask1, mask2, mask3)) + } else { + None + } +} + +/// Compute the position of the first matching byte from the given mask. The +/// position returned is always in the range [0, 15]. +/// +/// The mask given is expected to be the result of _mm_movemask_epi8. +fn forward_pos(mask: i32) -> usize { + // We are dealing with little endian here, where the most significant byte + // is at a higher address. That means the least significant bit that is set + // corresponds to the position of our first matching byte. That position + // corresponds to the number of zeros after the least significant bit. + mask.trailing_zeros() as usize +} + +/// Compute the position of the first matching byte from the given masks. The +/// position returned is always in the range [0, 15]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm_movemask_epi8, where +/// at least one of the masks is non-zero (i.e., indicates a match). +fn forward_pos2(mask1: i32, mask2: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0); + + forward_pos(mask1 | mask2) +} + +/// Compute the position of the first matching byte from the given masks. The +/// position returned is always in the range [0, 15]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm_movemask_epi8, where +/// at least one of the masks is non-zero (i.e., indicates a match). +fn forward_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0); + + forward_pos(mask1 | mask2 | mask3) +} + +/// Compute the position of the last matching byte from the given mask. The +/// position returned is always in the range [0, 15]. +/// +/// The mask given is expected to be the result of _mm_movemask_epi8. +fn reverse_pos(mask: i32) -> usize { + // We are dealing with little endian here, where the most significant byte + // is at a higher address. That means the most significant bit that is set + // corresponds to the position of our last matching byte. The position from + // the end of the mask is therefore the number of leading zeros in a 16 + // bit integer, and the position from the start of the mask is therefore + // 16 - (leading zeros) - 1. + VECTOR_SIZE - (mask as u16).leading_zeros() as usize - 1 +} + +/// Compute the position of the last matching byte from the given masks. The +/// position returned is always in the range [0, 15]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm_movemask_epi8, where +/// at least one of the masks is non-zero (i.e., indicates a match). +fn reverse_pos2(mask1: i32, mask2: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0); + + reverse_pos(mask1 | mask2) +} + +/// Compute the position of the last matching byte from the given masks. The +/// position returned is always in the range [0, 15]. Each mask corresponds to +/// the equality comparison of a single byte. +/// +/// The masks given are expected to be the result of _mm_movemask_epi8, where +/// at least one of the masks is non-zero (i.e., indicates a match). +fn reverse_pos3(mask1: i32, mask2: i32, mask3: i32) -> usize { + debug_assert!(mask1 != 0 || mask2 != 0 || mask3 != 0); + + reverse_pos(mask1 | mask2 | mask3) +} + +/// Subtract `b` from `a` and return the difference. `a` should be greater than +/// or equal to `b`. +fn sub(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memchr/x86/sse42.rs b/utshell-0.5.0/vendor/memchr/src/memchr/x86/sse42.rs new file mode 100644 index 00000000..da38e50c --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memchr/x86/sse42.rs @@ -0,0 +1,72 @@ +// This code is unused. PCMPESTRI is gratuitously slow. I imagine it might +// start winning with a hypothetical memchr4 (or greater). This technique might +// also be good for exposing searches over ranges of bytes, but that departs +// from the standard memchr API, so it's not clear whether we actually want +// that or not. +// +// N.B. PCMPISTRI appears to be about twice as fast as PCMPESTRI, which is kind +// of neat. Unfortunately, UTF-8 strings can contain NUL bytes, which means +// I don't see a way of effectively using PCMPISTRI unless there's some fast +// way to replace zero bytes with a byte that is not not a needle byte. + +use core::{arch::x86_64::*, mem::size_of}; + +use x86::sse2; + +const VECTOR_SIZE: usize = size_of::<__m128i>(); +const CONTROL_ANY: i32 = _SIDD_UBYTE_OPS + | _SIDD_CMP_EQUAL_ANY + | _SIDD_POSITIVE_POLARITY + | _SIDD_LEAST_SIGNIFICANT; + +#[target_feature(enable = "sse4.2")] +pub unsafe fn memchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + let vn1 = _mm_set1_epi8(n1 as i8); + let vn2 = _mm_set1_epi8(n2 as i8); + let vn3 = _mm_set1_epi8(n3 as i8); + let vn = _mm_setr_epi8( + n1 as i8, n2 as i8, n3 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ); + let len = haystack.len(); + let start_ptr = haystack.as_ptr(); + let end_ptr = haystack[haystack.len()..].as_ptr(); + let mut ptr = start_ptr; + + if haystack.len() < VECTOR_SIZE { + while ptr < end_ptr { + if *ptr == n1 || *ptr == n2 || *ptr == n3 { + return Some(sub(ptr, start_ptr)); + } + ptr = ptr.offset(1); + } + return None; + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let res = _mm_cmpestri(vn, 3, chunk, 16, CONTROL_ANY); + if res < 16 { + return Some(sub(ptr, start_ptr) + res as usize); + } + ptr = ptr.add(VECTOR_SIZE); + } + if ptr < end_ptr { + debug_assert!(sub(end_ptr, ptr) < VECTOR_SIZE); + ptr = ptr.sub(VECTOR_SIZE - sub(end_ptr, ptr)); + debug_assert_eq!(sub(end_ptr, ptr), VECTOR_SIZE); + + return sse2::forward_search3(start_ptr, end_ptr, ptr, vn1, vn2, vn3); + } + None +} + +/// Subtract `b` from `a` and return the difference. `a` should be greater than +/// or equal to `b`. +fn sub(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/byte_frequencies.rs b/utshell-0.5.0/vendor/memchr/src/memmem/byte_frequencies.rs new file mode 100644 index 00000000..c313b629 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/byte_frequencies.rs @@ -0,0 +1,258 @@ +pub const BYTE_FREQUENCIES: [u8; 256] = [ + 55, // '\x00' + 52, // '\x01' + 51, // '\x02' + 50, // '\x03' + 49, // '\x04' + 48, // '\x05' + 47, // '\x06' + 46, // '\x07' + 45, // '\x08' + 103, // '\t' + 242, // '\n' + 66, // '\x0b' + 67, // '\x0c' + 229, // '\r' + 44, // '\x0e' + 43, // '\x0f' + 42, // '\x10' + 41, // '\x11' + 40, // '\x12' + 39, // '\x13' + 38, // '\x14' + 37, // '\x15' + 36, // '\x16' + 35, // '\x17' + 34, // '\x18' + 33, // '\x19' + 56, // '\x1a' + 32, // '\x1b' + 31, // '\x1c' + 30, // '\x1d' + 29, // '\x1e' + 28, // '\x1f' + 255, // ' ' + 148, // '!' + 164, // '"' + 149, // '#' + 136, // '$' + 160, // '%' + 155, // '&' + 173, // "'" + 221, // '(' + 222, // ')' + 134, // '*' + 122, // '+' + 232, // ',' + 202, // '-' + 215, // '.' + 224, // '/' + 208, // '0' + 220, // '1' + 204, // '2' + 187, // '3' + 183, // '4' + 179, // '5' + 177, // '6' + 168, // '7' + 178, // '8' + 200, // '9' + 226, // ':' + 195, // ';' + 154, // '<' + 184, // '=' + 174, // '>' + 126, // '?' + 120, // '@' + 191, // 'A' + 157, // 'B' + 194, // 'C' + 170, // 'D' + 189, // 'E' + 162, // 'F' + 161, // 'G' + 150, // 'H' + 193, // 'I' + 142, // 'J' + 137, // 'K' + 171, // 'L' + 176, // 'M' + 185, // 'N' + 167, // 'O' + 186, // 'P' + 112, // 'Q' + 175, // 'R' + 192, // 'S' + 188, // 'T' + 156, // 'U' + 140, // 'V' + 143, // 'W' + 123, // 'X' + 133, // 'Y' + 128, // 'Z' + 147, // '[' + 138, // '\\' + 146, // ']' + 114, // '^' + 223, // '_' + 151, // '`' + 249, // 'a' + 216, // 'b' + 238, // 'c' + 236, // 'd' + 253, // 'e' + 227, // 'f' + 218, // 'g' + 230, // 'h' + 247, // 'i' + 135, // 'j' + 180, // 'k' + 241, // 'l' + 233, // 'm' + 246, // 'n' + 244, // 'o' + 231, // 'p' + 139, // 'q' + 245, // 'r' + 243, // 's' + 251, // 't' + 235, // 'u' + 201, // 'v' + 196, // 'w' + 240, // 'x' + 214, // 'y' + 152, // 'z' + 182, // '{' + 205, // '|' + 181, // '}' + 127, // '~' + 27, // '\x7f' + 212, // '\x80' + 211, // '\x81' + 210, // '\x82' + 213, // '\x83' + 228, // '\x84' + 197, // '\x85' + 169, // '\x86' + 159, // '\x87' + 131, // '\x88' + 172, // '\x89' + 105, // '\x8a' + 80, // '\x8b' + 98, // '\x8c' + 96, // '\x8d' + 97, // '\x8e' + 81, // '\x8f' + 207, // '\x90' + 145, // '\x91' + 116, // '\x92' + 115, // '\x93' + 144, // '\x94' + 130, // '\x95' + 153, // '\x96' + 121, // '\x97' + 107, // '\x98' + 132, // '\x99' + 109, // '\x9a' + 110, // '\x9b' + 124, // '\x9c' + 111, // '\x9d' + 82, // '\x9e' + 108, // '\x9f' + 118, // '\xa0' + 141, // '¡' + 113, // '¢' + 129, // '£' + 119, // '¤' + 125, // 'Â¥' + 165, // '¦' + 117, // '§' + 92, // '¨' + 106, // '©' + 83, // 'ª' + 72, // '«' + 99, // '¬' + 93, // '\xad' + 65, // '®' + 79, // '¯' + 166, // '°' + 237, // '±' + 163, // '²' + 199, // '³' + 190, // '´' + 225, // 'µ' + 209, // '¶' + 203, // '·' + 198, // '¸' + 217, // '¹' + 219, // 'º' + 206, // '»' + 234, // '¼' + 248, // '½' + 158, // '¾' + 239, // '¿' + 255, // 'À' + 255, // 'Ã' + 255, // 'Â' + 255, // 'Ã' + 255, // 'Ä' + 255, // 'Ã…' + 255, // 'Æ' + 255, // 'Ç' + 255, // 'È' + 255, // 'É' + 255, // 'Ê' + 255, // 'Ë' + 255, // 'ÃŒ' + 255, // 'Ã' + 255, // 'ÃŽ' + 255, // 'Ã' + 255, // 'Ã' + 255, // 'Ñ' + 255, // 'Ã’' + 255, // 'Ó' + 255, // 'Ô' + 255, // 'Õ' + 255, // 'Ö' + 255, // '×' + 255, // 'Ø' + 255, // 'Ù' + 255, // 'Ú' + 255, // 'Û' + 255, // 'Ü' + 255, // 'Ã' + 255, // 'Þ' + 255, // 'ß' + 255, // 'à' + 255, // 'á' + 255, // 'â' + 255, // 'ã' + 255, // 'ä' + 255, // 'Ã¥' + 255, // 'æ' + 255, // 'ç' + 255, // 'è' + 255, // 'é' + 255, // 'ê' + 255, // 'ë' + 255, // 'ì' + 255, // 'í' + 255, // 'î' + 255, // 'ï' + 255, // 'ð' + 255, // 'ñ' + 255, // 'ò' + 255, // 'ó' + 255, // 'ô' + 255, // 'õ' + 255, // 'ö' + 255, // '÷' + 255, // 'ø' + 255, // 'ù' + 255, // 'ú' + 255, // 'û' + 255, // 'ü' + 255, // 'ý' + 255, // 'þ' + 255, // 'ÿ' +]; diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/genericsimd.rs b/utshell-0.5.0/vendor/memchr/src/memmem/genericsimd.rs new file mode 100644 index 00000000..28bfdab8 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/genericsimd.rs @@ -0,0 +1,266 @@ +use core::mem::size_of; + +use crate::memmem::{util::memcmp, vector::Vector, NeedleInfo}; + +/// The minimum length of a needle required for this algorithm. The minimum +/// is 2 since a length of 1 should just use memchr and a length of 0 isn't +/// a case handled by this searcher. +pub(crate) const MIN_NEEDLE_LEN: usize = 2; + +/// The maximum length of a needle required for this algorithm. +/// +/// In reality, there is no hard max here. The code below can handle any +/// length needle. (Perhaps that suggests there are missing optimizations.) +/// Instead, this is a heuristic and a bound guaranteeing our linear time +/// complexity. +/// +/// It is a heuristic because when a candidate match is found, memcmp is run. +/// For very large needles with lots of false positives, memcmp can make the +/// code run quite slow. +/// +/// It is a bound because the worst case behavior with memcmp is multiplicative +/// in the size of the needle and haystack, and we want to keep that additive. +/// This bound ensures we still meet that bound theoretically, since it's just +/// a constant. We aren't acting in bad faith here, memcmp on tiny needles +/// is so fast that even in pathological cases (see pathological vector +/// benchmarks), this is still just as fast or faster in practice. +/// +/// This specific number was chosen by tweaking a bit and running benchmarks. +/// The rare-medium-needle, for example, gets about 5% faster by using this +/// algorithm instead of a prefilter-accelerated Two-Way. There's also a +/// theoretical desire to keep this number reasonably low, to mitigate the +/// impact of pathological cases. I did try 64, and some benchmarks got a +/// little better, and others (particularly the pathological ones), got a lot +/// worse. So... 32 it is? +pub(crate) const MAX_NEEDLE_LEN: usize = 32; + +/// The implementation of the forward vector accelerated substring search. +/// +/// This is extremely similar to the prefilter vector module by the same name. +/// The key difference is that this is not a prefilter. Instead, it handles +/// confirming its own matches. The trade off is that this only works with +/// smaller needles. The speed up here is that an inlined memcmp on a tiny +/// needle is very quick, even on pathological inputs. This is much better than +/// combining a prefilter with Two-Way, where using Two-Way to confirm the +/// match has higher latency. +/// +/// So why not use this for all needles? We could, and it would probably work +/// really well on most inputs. But its worst case is multiplicative and we +/// want to guarantee worst case additive time. Some of the benchmarks try to +/// justify this (see the pathological ones). +/// +/// The prefilter variant of this has more comments. Also note that we only +/// implement this for forward searches for now. If you have a compelling use +/// case for accelerated reverse search, please file an issue. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Forward { + rare1i: u8, + rare2i: u8, +} + +impl Forward { + /// Create a new "generic simd" forward searcher. If one could not be + /// created from the given inputs, then None is returned. + pub(crate) fn new(ninfo: &NeedleInfo, needle: &[u8]) -> Option { + let (rare1i, rare2i) = ninfo.rarebytes.as_rare_ordered_u8(); + // If the needle is too short or too long, give up. Also, give up + // if the rare bytes detected are at the same position. (It likely + // suggests a degenerate case, although it should technically not be + // possible.) + if needle.len() < MIN_NEEDLE_LEN + || needle.len() > MAX_NEEDLE_LEN + || rare1i == rare2i + { + return None; + } + Some(Forward { rare1i, rare2i }) + } + + /// Returns the minimum length of haystack that is needed for this searcher + /// to work for a particular vector. Passing a haystack with a length + /// smaller than this will cause `fwd_find` to panic. + #[inline(always)] + pub(crate) fn min_haystack_len(&self) -> usize { + self.rare2i as usize + size_of::() + } +} + +/// Searches the given haystack for the given needle. The needle given should +/// be the same as the needle that this searcher was initialized with. +/// +/// # Panics +/// +/// When the given haystack has a length smaller than `min_haystack_len`. +/// +/// # Safety +/// +/// Since this is meant to be used with vector functions, callers need to +/// specialize this inside of a function with a `target_feature` attribute. +/// Therefore, callers must ensure that whatever target feature is being used +/// supports the vector functions that this function is specialized for. (For +/// the specific vector functions used, see the Vector trait implementations.) +#[inline(always)] +pub(crate) unsafe fn fwd_find( + fwd: &Forward, + haystack: &[u8], + needle: &[u8], +) -> Option { + // It would be nice if we didn't have this check here, since the meta + // searcher should handle it for us. But without this, I don't think we + // guarantee that end_ptr.sub(needle.len()) won't result in UB. We could + // put it as part of the safety contract, but it makes it more complicated + // than necessary. + if haystack.len() < needle.len() { + return None; + } + let min_haystack_len = fwd.min_haystack_len::(); + assert!(haystack.len() >= min_haystack_len, "haystack too small"); + debug_assert!(needle.len() <= haystack.len()); + debug_assert!( + needle.len() >= MIN_NEEDLE_LEN, + "needle must be at least {} bytes", + MIN_NEEDLE_LEN, + ); + debug_assert!( + needle.len() <= MAX_NEEDLE_LEN, + "needle must be at most {} bytes", + MAX_NEEDLE_LEN, + ); + + let (rare1i, rare2i) = (fwd.rare1i as usize, fwd.rare2i as usize); + let rare1chunk = V::splat(needle[rare1i]); + let rare2chunk = V::splat(needle[rare2i]); + + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let max_ptr = end_ptr.sub(min_haystack_len); + let mut ptr = start_ptr; + + // N.B. I did experiment with unrolling the loop to deal with size(V) + // bytes at a time and 2*size(V) bytes at a time. The double unroll was + // marginally faster while the quadruple unroll was unambiguously slower. + // In the end, I decided the complexity from unrolling wasn't worth it. I + // used the memmem/krate/prebuilt/huge-en/ benchmarks to compare. + while ptr <= max_ptr { + let m = fwd_find_in_chunk( + fwd, needle, ptr, end_ptr, rare1chunk, rare2chunk, !0, + ); + if let Some(chunki) = m { + return Some(matched(start_ptr, ptr, chunki)); + } + ptr = ptr.add(size_of::()); + } + if ptr < end_ptr { + let remaining = diff(end_ptr, ptr); + debug_assert!( + remaining < min_haystack_len, + "remaining bytes should be smaller than the minimum haystack \ + length of {}, but there are {} bytes remaining", + min_haystack_len, + remaining, + ); + if remaining < needle.len() { + return None; + } + debug_assert!( + max_ptr < ptr, + "after main loop, ptr should have exceeded max_ptr", + ); + let overlap = diff(ptr, max_ptr); + debug_assert!( + overlap > 0, + "overlap ({}) must always be non-zero", + overlap, + ); + debug_assert!( + overlap < size_of::(), + "overlap ({}) cannot possibly be >= than a vector ({})", + overlap, + size_of::(), + ); + // The mask has all of its bits set except for the first N least + // significant bits, where N=overlap. This way, any matches that + // occur in find_in_chunk within the overlap are automatically + // ignored. + let mask = !((1 << overlap) - 1); + ptr = max_ptr; + let m = fwd_find_in_chunk( + fwd, needle, ptr, end_ptr, rare1chunk, rare2chunk, mask, + ); + if let Some(chunki) = m { + return Some(matched(start_ptr, ptr, chunki)); + } + } + None +} + +/// Search for an occurrence of two rare bytes from the needle in the chunk +/// pointed to by ptr, with the end of the haystack pointed to by end_ptr. When +/// an occurrence is found, memcmp is run to check if a match occurs at the +/// corresponding position. +/// +/// rare1chunk and rare2chunk correspond to vectors with the rare1 and rare2 +/// bytes repeated in each 8-bit lane, respectively. +/// +/// mask should have bits set corresponding the positions in the chunk in which +/// matches are considered. This is only used for the last vector load where +/// the beginning of the vector might have overlapped with the last load in +/// the main loop. The mask lets us avoid visiting positions that have already +/// been discarded as matches. +/// +/// # Safety +/// +/// It must be safe to do an unaligned read of size(V) bytes starting at both +/// (ptr + rare1i) and (ptr + rare2i). It must also be safe to do unaligned +/// loads on ptr up to (end_ptr - needle.len()). +#[inline(always)] +unsafe fn fwd_find_in_chunk( + fwd: &Forward, + needle: &[u8], + ptr: *const u8, + end_ptr: *const u8, + rare1chunk: V, + rare2chunk: V, + mask: u32, +) -> Option { + let chunk0 = V::load_unaligned(ptr.add(fwd.rare1i as usize)); + let chunk1 = V::load_unaligned(ptr.add(fwd.rare2i as usize)); + + let eq0 = chunk0.cmpeq(rare1chunk); + let eq1 = chunk1.cmpeq(rare2chunk); + + let mut match_offsets = eq0.and(eq1).movemask() & mask; + while match_offsets != 0 { + let offset = match_offsets.trailing_zeros() as usize; + let ptr = ptr.add(offset); + if end_ptr.sub(needle.len()) < ptr { + return None; + } + let chunk = core::slice::from_raw_parts(ptr, needle.len()); + if memcmp(needle, chunk) { + return Some(offset); + } + match_offsets &= match_offsets - 1; + } + None +} + +/// Accepts a chunk-relative offset and returns a haystack relative offset +/// after updating the prefilter state. +/// +/// See the same function with the same name in the prefilter variant of this +/// algorithm to learned why it's tagged with inline(never). Even here, where +/// the function is simpler, inlining it leads to poorer codegen. (Although +/// it does improve some benchmarks, like prebuiltiter/huge-en/common-you.) +#[cold] +#[inline(never)] +fn matched(start_ptr: *const u8, ptr: *const u8, chunki: usize) -> usize { + diff(ptr, start_ptr) + chunki +} + +/// Subtract `b` from `a` and return the difference. `a` must be greater than +/// or equal to `b`. +fn diff(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/mod.rs b/utshell-0.5.0/vendor/memchr/src/memmem/mod.rs new file mode 100644 index 00000000..e1cd1aec --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/mod.rs @@ -0,0 +1,1321 @@ +/*! +This module provides forward and reverse substring search routines. + +Unlike the standard library's substring search routines, these work on +arbitrary bytes. For all non-empty needles, these routines will report exactly +the same values as the corresponding routines in the standard library. For +the empty needle, the standard library reports matches only at valid UTF-8 +boundaries, where as these routines will report matches at every position. + +Other than being able to work on arbitrary bytes, the primary reason to prefer +these routines over the standard library routines is that these will generally +be faster. In some cases, significantly so. + +# Example: iterating over substring matches + +This example shows how to use [`find_iter`] to find occurrences of a substring +in a haystack. + +``` +use memchr::memmem; + +let haystack = b"foo bar foo baz foo"; + +let mut it = memmem::find_iter(haystack, "foo"); +assert_eq!(Some(0), it.next()); +assert_eq!(Some(8), it.next()); +assert_eq!(Some(16), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: iterating over substring matches in reverse + +This example shows how to use [`rfind_iter`] to find occurrences of a substring +in a haystack starting from the end of the haystack. + +**NOTE:** This module does not implement double ended iterators, so reverse +searches aren't done by calling `rev` on a forward iterator. + +``` +use memchr::memmem; + +let haystack = b"foo bar foo baz foo"; + +let mut it = memmem::rfind_iter(haystack, "foo"); +assert_eq!(Some(16), it.next()); +assert_eq!(Some(8), it.next()); +assert_eq!(Some(0), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: repeating a search for the same needle + +It may be possible for the overhead of constructing a substring searcher to be +measurable in some workloads. In cases where the same needle is used to search +many haystacks, it is possible to do construction once and thus to avoid it for +subsequent searches. This can be done with a [`Finder`] (or a [`FinderRev`] for +reverse searches). + +``` +use memchr::memmem; + +let finder = memmem::Finder::new("foo"); + +assert_eq!(Some(4), finder.find(b"baz foo quux")); +assert_eq!(None, finder.find(b"quux baz bar")); +``` +*/ + +pub use self::prefilter::Prefilter; + +use crate::{ + cow::CowBytes, + memmem::{ + prefilter::{Pre, PrefilterFn, PrefilterState}, + rabinkarp::NeedleHash, + rarebytes::RareNeedleBytes, + }, +}; + +/// Defines a suite of quickcheck properties for forward and reverse +/// substring searching. +/// +/// This is defined in this specific spot so that it can be used freely among +/// the different substring search implementations. I couldn't be bothered to +/// fight with the macro-visibility rules enough to figure out how to stuff it +/// somewhere more convenient. +#[cfg(all(test, feature = "std"))] +macro_rules! define_memmem_quickcheck_tests { + ($fwd:expr, $rev:expr) => { + use crate::memmem::proptests; + + quickcheck::quickcheck! { + fn qc_fwd_prefix_is_substring(bs: Vec) -> bool { + proptests::prefix_is_substring(false, &bs, $fwd) + } + + fn qc_fwd_suffix_is_substring(bs: Vec) -> bool { + proptests::suffix_is_substring(false, &bs, $fwd) + } + + fn qc_fwd_matches_naive( + haystack: Vec, + needle: Vec + ) -> bool { + proptests::matches_naive(false, &haystack, &needle, $fwd) + } + + fn qc_rev_prefix_is_substring(bs: Vec) -> bool { + proptests::prefix_is_substring(true, &bs, $rev) + } + + fn qc_rev_suffix_is_substring(bs: Vec) -> bool { + proptests::suffix_is_substring(true, &bs, $rev) + } + + fn qc_rev_matches_naive( + haystack: Vec, + needle: Vec + ) -> bool { + proptests::matches_naive(true, &haystack, &needle, $rev) + } + } + }; +} + +/// Defines a suite of "simple" hand-written tests for a substring +/// implementation. +/// +/// This is defined here for the same reason that +/// define_memmem_quickcheck_tests is defined here. +#[cfg(test)] +macro_rules! define_memmem_simple_tests { + ($fwd:expr, $rev:expr) => { + use crate::memmem::testsimples; + + #[test] + fn simple_forward() { + testsimples::run_search_tests_fwd($fwd); + } + + #[test] + fn simple_reverse() { + testsimples::run_search_tests_rev($rev); + } + }; +} + +mod byte_frequencies; +#[cfg(memchr_runtime_simd)] +mod genericsimd; +mod prefilter; +mod rabinkarp; +mod rarebytes; +mod twoway; +mod util; +#[cfg(memchr_runtime_simd)] +mod vector; +#[cfg(all(memchr_runtime_wasm128))] +mod wasm; +#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] +mod x86; + +/// Returns an iterator over all non-overlapping occurrences of a substring in +/// a haystack. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar foo baz foo"; +/// let mut it = memmem::find_iter(haystack, b"foo"); +/// assert_eq!(Some(0), it.next()); +/// assert_eq!(Some(8), it.next()); +/// assert_eq!(Some(16), it.next()); +/// assert_eq!(None, it.next()); +/// ``` +#[inline] +pub fn find_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>( + haystack: &'h [u8], + needle: &'n N, +) -> FindIter<'h, 'n> { + FindIter::new(haystack, Finder::new(needle)) +} + +/// Returns a reverse iterator over all non-overlapping occurrences of a +/// substring in a haystack. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar foo baz foo"; +/// let mut it = memmem::rfind_iter(haystack, b"foo"); +/// assert_eq!(Some(16), it.next()); +/// assert_eq!(Some(8), it.next()); +/// assert_eq!(Some(0), it.next()); +/// assert_eq!(None, it.next()); +/// ``` +#[inline] +pub fn rfind_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>( + haystack: &'h [u8], + needle: &'n N, +) -> FindRevIter<'h, 'n> { + FindRevIter::new(haystack, FinderRev::new(needle)) +} + +/// Returns the index of the first occurrence of the given needle. +/// +/// Note that if you're are searching for the same needle in many different +/// small haystacks, it may be faster to initialize a [`Finder`] once, +/// and reuse it for each search. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar baz"; +/// assert_eq!(Some(0), memmem::find(haystack, b"foo")); +/// assert_eq!(Some(4), memmem::find(haystack, b"bar")); +/// assert_eq!(None, memmem::find(haystack, b"quux")); +/// ``` +#[inline] +pub fn find(haystack: &[u8], needle: &[u8]) -> Option { + if haystack.len() < 64 { + rabinkarp::find(haystack, needle) + } else { + Finder::new(needle).find(haystack) + } +} + +/// Returns the index of the last occurrence of the given needle. +/// +/// Note that if you're are searching for the same needle in many different +/// small haystacks, it may be faster to initialize a [`FinderRev`] once, +/// and reuse it for each search. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar baz"; +/// assert_eq!(Some(0), memmem::rfind(haystack, b"foo")); +/// assert_eq!(Some(4), memmem::rfind(haystack, b"bar")); +/// assert_eq!(Some(8), memmem::rfind(haystack, b"ba")); +/// assert_eq!(None, memmem::rfind(haystack, b"quux")); +/// ``` +#[inline] +pub fn rfind(haystack: &[u8], needle: &[u8]) -> Option { + if haystack.len() < 64 { + rabinkarp::rfind(haystack, needle) + } else { + FinderRev::new(needle).rfind(haystack) + } +} + +/// An iterator over non-overlapping substring matches. +/// +/// Matches are reported by the byte offset at which they begin. +/// +/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the +/// needle. +#[derive(Debug)] +pub struct FindIter<'h, 'n> { + haystack: &'h [u8], + prestate: PrefilterState, + finder: Finder<'n>, + pos: usize, +} + +impl<'h, 'n> FindIter<'h, 'n> { + #[inline(always)] + pub(crate) fn new( + haystack: &'h [u8], + finder: Finder<'n>, + ) -> FindIter<'h, 'n> { + let prestate = finder.searcher.prefilter_state(); + FindIter { haystack, prestate, finder, pos: 0 } + } + + /// Convert this iterator into its owned variant, such that it no longer + /// borrows the finder and needle. + /// + /// If this is already an owned iterator, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "std")] + #[inline] + pub fn into_owned(self) -> FindIter<'h, 'static> { + FindIter { + haystack: self.haystack, + prestate: self.prestate, + finder: self.finder.into_owned(), + pos: self.pos, + } + } +} + +impl<'h, 'n> Iterator for FindIter<'h, 'n> { + type Item = usize; + + fn next(&mut self) -> Option { + if self.pos > self.haystack.len() { + return None; + } + let result = self + .finder + .searcher + .find(&mut self.prestate, &self.haystack[self.pos..]); + match result { + None => None, + Some(i) => { + let pos = self.pos + i; + self.pos = pos + core::cmp::max(1, self.finder.needle().len()); + Some(pos) + } + } + } +} + +/// An iterator over non-overlapping substring matches in reverse. +/// +/// Matches are reported by the byte offset at which they begin. +/// +/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the +/// needle. +#[derive(Debug)] +pub struct FindRevIter<'h, 'n> { + haystack: &'h [u8], + finder: FinderRev<'n>, + /// When searching with an empty needle, this gets set to `None` after + /// we've yielded the last element at `0`. + pos: Option, +} + +impl<'h, 'n> FindRevIter<'h, 'n> { + #[inline(always)] + pub(crate) fn new( + haystack: &'h [u8], + finder: FinderRev<'n>, + ) -> FindRevIter<'h, 'n> { + let pos = Some(haystack.len()); + FindRevIter { haystack, finder, pos } + } + + /// Convert this iterator into its owned variant, such that it no longer + /// borrows the finder and needle. + /// + /// If this is already an owned iterator, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "std")] + #[inline] + pub fn into_owned(self) -> FindRevIter<'h, 'static> { + FindRevIter { + haystack: self.haystack, + finder: self.finder.into_owned(), + pos: self.pos, + } + } +} + +impl<'h, 'n> Iterator for FindRevIter<'h, 'n> { + type Item = usize; + + fn next(&mut self) -> Option { + let pos = match self.pos { + None => return None, + Some(pos) => pos, + }; + let result = self.finder.rfind(&self.haystack[..pos]); + match result { + None => None, + Some(i) => { + if pos == i { + self.pos = pos.checked_sub(1); + } else { + self.pos = Some(i); + } + Some(i) + } + } + } +} + +/// A single substring searcher fixed to a particular needle. +/// +/// The purpose of this type is to permit callers to construct a substring +/// searcher that can be used to search haystacks without the overhead of +/// constructing the searcher in the first place. This is a somewhat niche +/// concern when it's necessary to re-use the same needle to search multiple +/// different haystacks with as little overhead as possible. In general, using +/// [`find`] is good enough, but `Finder` is useful when you can meaningfully +/// observe searcher construction time in a profile. +/// +/// When the `std` feature is enabled, then this type has an `into_owned` +/// version which permits building a `Finder` that is not connected to +/// the lifetime of its needle. +#[derive(Clone, Debug)] +pub struct Finder<'n> { + searcher: Searcher<'n>, +} + +impl<'n> Finder<'n> { + /// Create a new finder for the given needle. + #[inline] + pub fn new>(needle: &'n B) -> Finder<'n> { + FinderBuilder::new().build_forward(needle) + } + + /// Returns the index of the first occurrence of this needle in the given + /// haystack. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::Finder; + /// + /// let haystack = b"foo bar baz"; + /// assert_eq!(Some(0), Finder::new("foo").find(haystack)); + /// assert_eq!(Some(4), Finder::new("bar").find(haystack)); + /// assert_eq!(None, Finder::new("quux").find(haystack)); + /// ``` + pub fn find(&self, haystack: &[u8]) -> Option { + self.searcher.find(&mut self.searcher.prefilter_state(), haystack) + } + + /// Returns an iterator over all occurrences of a substring in a haystack. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::Finder; + /// + /// let haystack = b"foo bar foo baz foo"; + /// let finder = Finder::new(b"foo"); + /// let mut it = finder.find_iter(haystack); + /// assert_eq!(Some(0), it.next()); + /// assert_eq!(Some(8), it.next()); + /// assert_eq!(Some(16), it.next()); + /// assert_eq!(None, it.next()); + /// ``` + #[inline] + pub fn find_iter<'a, 'h>( + &'a self, + haystack: &'h [u8], + ) -> FindIter<'h, 'a> { + FindIter::new(haystack, self.as_ref()) + } + + /// Convert this finder into its owned variant, such that it no longer + /// borrows the needle. + /// + /// If this is already an owned finder, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "std")] + #[inline] + pub fn into_owned(self) -> Finder<'static> { + Finder { searcher: self.searcher.into_owned() } + } + + /// Convert this finder into its borrowed variant. + /// + /// This is primarily useful if your finder is owned and you'd like to + /// store its borrowed variant in some intermediate data structure. + /// + /// Note that the lifetime parameter of the returned finder is tied to the + /// lifetime of `self`, and may be shorter than the `'n` lifetime of the + /// needle itself. Namely, a finder's needle can be either borrowed or + /// owned, so the lifetime of the needle returned must necessarily be the + /// shorter of the two. + #[inline] + pub fn as_ref(&self) -> Finder<'_> { + Finder { searcher: self.searcher.as_ref() } + } + + /// Returns the needle that this finder searches for. + /// + /// Note that the lifetime of the needle returned is tied to the lifetime + /// of the finder, and may be shorter than the `'n` lifetime. Namely, a + /// finder's needle can be either borrowed or owned, so the lifetime of the + /// needle returned must necessarily be the shorter of the two. + #[inline] + pub fn needle(&self) -> &[u8] { + self.searcher.needle() + } +} + +/// A single substring reverse searcher fixed to a particular needle. +/// +/// The purpose of this type is to permit callers to construct a substring +/// searcher that can be used to search haystacks without the overhead of +/// constructing the searcher in the first place. This is a somewhat niche +/// concern when it's necessary to re-use the same needle to search multiple +/// different haystacks with as little overhead as possible. In general, +/// using [`rfind`] is good enough, but `FinderRev` is useful when you can +/// meaningfully observe searcher construction time in a profile. +/// +/// When the `std` feature is enabled, then this type has an `into_owned` +/// version which permits building a `FinderRev` that is not connected to +/// the lifetime of its needle. +#[derive(Clone, Debug)] +pub struct FinderRev<'n> { + searcher: SearcherRev<'n>, +} + +impl<'n> FinderRev<'n> { + /// Create a new reverse finder for the given needle. + #[inline] + pub fn new>(needle: &'n B) -> FinderRev<'n> { + FinderBuilder::new().build_reverse(needle) + } + + /// Returns the index of the last occurrence of this needle in the given + /// haystack. + /// + /// The haystack may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::FinderRev; + /// + /// let haystack = b"foo bar baz"; + /// assert_eq!(Some(0), FinderRev::new("foo").rfind(haystack)); + /// assert_eq!(Some(4), FinderRev::new("bar").rfind(haystack)); + /// assert_eq!(None, FinderRev::new("quux").rfind(haystack)); + /// ``` + pub fn rfind>(&self, haystack: B) -> Option { + self.searcher.rfind(haystack.as_ref()) + } + + /// Returns a reverse iterator over all occurrences of a substring in a + /// haystack. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::FinderRev; + /// + /// let haystack = b"foo bar foo baz foo"; + /// let finder = FinderRev::new(b"foo"); + /// let mut it = finder.rfind_iter(haystack); + /// assert_eq!(Some(16), it.next()); + /// assert_eq!(Some(8), it.next()); + /// assert_eq!(Some(0), it.next()); + /// assert_eq!(None, it.next()); + /// ``` + #[inline] + pub fn rfind_iter<'a, 'h>( + &'a self, + haystack: &'h [u8], + ) -> FindRevIter<'h, 'a> { + FindRevIter::new(haystack, self.as_ref()) + } + + /// Convert this finder into its owned variant, such that it no longer + /// borrows the needle. + /// + /// If this is already an owned finder, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "std")] + #[inline] + pub fn into_owned(self) -> FinderRev<'static> { + FinderRev { searcher: self.searcher.into_owned() } + } + + /// Convert this finder into its borrowed variant. + /// + /// This is primarily useful if your finder is owned and you'd like to + /// store its borrowed variant in some intermediate data structure. + /// + /// Note that the lifetime parameter of the returned finder is tied to the + /// lifetime of `self`, and may be shorter than the `'n` lifetime of the + /// needle itself. Namely, a finder's needle can be either borrowed or + /// owned, so the lifetime of the needle returned must necessarily be the + /// shorter of the two. + #[inline] + pub fn as_ref(&self) -> FinderRev<'_> { + FinderRev { searcher: self.searcher.as_ref() } + } + + /// Returns the needle that this finder searches for. + /// + /// Note that the lifetime of the needle returned is tied to the lifetime + /// of the finder, and may be shorter than the `'n` lifetime. Namely, a + /// finder's needle can be either borrowed or owned, so the lifetime of the + /// needle returned must necessarily be the shorter of the two. + #[inline] + pub fn needle(&self) -> &[u8] { + self.searcher.needle() + } +} + +/// A builder for constructing non-default forward or reverse memmem finders. +/// +/// A builder is primarily useful for configuring a substring searcher. +/// Currently, the only configuration exposed is the ability to disable +/// heuristic prefilters used to speed up certain searches. +#[derive(Clone, Debug, Default)] +pub struct FinderBuilder { + config: SearcherConfig, +} + +impl FinderBuilder { + /// Create a new finder builder with default settings. + pub fn new() -> FinderBuilder { + FinderBuilder::default() + } + + /// Build a forward finder using the given needle from the current + /// settings. + pub fn build_forward<'n, B: ?Sized + AsRef<[u8]>>( + &self, + needle: &'n B, + ) -> Finder<'n> { + Finder { searcher: Searcher::new(self.config, needle.as_ref()) } + } + + /// Build a reverse finder using the given needle from the current + /// settings. + pub fn build_reverse<'n, B: ?Sized + AsRef<[u8]>>( + &self, + needle: &'n B, + ) -> FinderRev<'n> { + FinderRev { searcher: SearcherRev::new(needle.as_ref()) } + } + + /// Configure the prefilter setting for the finder. + /// + /// See the documentation for [`Prefilter`] for more discussion on why + /// you might want to configure this. + pub fn prefilter(&mut self, prefilter: Prefilter) -> &mut FinderBuilder { + self.config.prefilter = prefilter; + self + } +} + +/// The internal implementation of a forward substring searcher. +/// +/// The reality is that this is a "meta" searcher. Namely, depending on a +/// variety of parameters (CPU support, target, needle size, haystack size and +/// even dynamic properties such as prefilter effectiveness), the actual +/// algorithm employed to do substring search may change. +#[derive(Clone, Debug)] +struct Searcher<'n> { + /// The actual needle we're searching for. + /// + /// A CowBytes is like a Cow<[u8]>, except in no_std environments, it is + /// specialized to a single variant (the borrowed form). + needle: CowBytes<'n>, + /// A collection of facts computed on the needle that are useful for more + /// than one substring search algorithm. + ninfo: NeedleInfo, + /// A prefilter function, if it was deemed appropriate. + /// + /// Some substring search implementations (like Two-Way) benefit greatly + /// if we can quickly find candidate starting positions for a match. + prefn: Option, + /// The actual substring implementation in use. + kind: SearcherKind, +} + +/// A collection of facts computed about a search needle. +/// +/// We group these things together because it's useful to be able to hand them +/// to prefilters or substring algorithms that want them. +#[derive(Clone, Copy, Debug)] +pub(crate) struct NeedleInfo { + /// The offsets of "rare" bytes detected in the needle. + /// + /// This is meant to be a heuristic in order to maximize the effectiveness + /// of vectorized code. Namely, vectorized code tends to focus on only + /// one or two bytes. If we pick bytes from the needle that occur + /// infrequently, then more time will be spent in the vectorized code and + /// will likely make the overall search (much) faster. + /// + /// Of course, this is only a heuristic based on a background frequency + /// distribution of bytes. But it tends to work very well in practice. + pub(crate) rarebytes: RareNeedleBytes, + /// A Rabin-Karp hash of the needle. + /// + /// This is store here instead of in a more specific Rabin-Karp search + /// since Rabin-Karp may be used even if another SearchKind corresponds + /// to some other search implementation. e.g., If measurements suggest RK + /// is faster in some cases or if a search implementation can't handle + /// particularly small haystack. (Moreover, we cannot use RK *generally*, + /// since its worst case time is multiplicative. Instead, we only use it + /// some small haystacks, where "small" is a constant.) + pub(crate) nhash: NeedleHash, +} + +/// Configuration for substring search. +#[derive(Clone, Copy, Debug, Default)] +struct SearcherConfig { + /// This permits changing the behavior of the prefilter, since it can have + /// a variable impact on performance. + prefilter: Prefilter, +} + +#[derive(Clone, Debug)] +enum SearcherKind { + /// A special case for empty needles. An empty needle always matches, even + /// in an empty haystack. + Empty, + /// This is used whenever the needle is a single byte. In this case, we + /// always use memchr. + OneByte(u8), + /// Two-Way is the generic work horse and is what provides our additive + /// linear time guarantee. In general, it's used when the needle is bigger + /// than 8 bytes or so. + TwoWay(twoway::Forward), + #[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] + GenericSIMD128(x86::sse::Forward), + #[cfg(memchr_runtime_wasm128)] + GenericSIMD128(wasm::Forward), + #[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] + GenericSIMD256(x86::avx::Forward), +} + +impl<'n> Searcher<'n> { + fn new(config: SearcherConfig, needle: &'n [u8]) -> Searcher<'n> { + use self::SearcherKind::*; + + let ninfo = NeedleInfo::new(needle); + let mk = |kind: SearcherKind| { + let prefn = prefilter::forward( + &config.prefilter, + &ninfo.rarebytes, + needle, + ); + Searcher { needle: CowBytes::new(needle), ninfo, prefn, kind } + }; + if needle.len() == 0 { + return mk(Empty); + } + if needle.len() == 1 { + return mk(OneByte(needle[0])); + } + #[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] + { + if let Some(fwd) = x86::avx::Forward::new(&ninfo, needle) { + return mk(GenericSIMD256(fwd)); + } else if let Some(fwd) = x86::sse::Forward::new(&ninfo, needle) { + return mk(GenericSIMD128(fwd)); + } + } + #[cfg(all(target_arch = "wasm32", memchr_runtime_simd))] + { + if let Some(fwd) = wasm::Forward::new(&ninfo, needle) { + return mk(GenericSIMD128(fwd)); + } + } + + mk(TwoWay(twoway::Forward::new(needle))) + } + + /// Return a fresh prefilter state that can be used with this searcher. + /// A prefilter state is used to track the effectiveness of a searcher's + /// prefilter for speeding up searches. Therefore, the prefilter state + /// should generally be reused on subsequent searches (such as in an + /// iterator). For searches on a different haystack, then a new prefilter + /// state should be used. + /// + /// This always initializes a valid (but possibly inert) prefilter state + /// even if this searcher does not have a prefilter enabled. + fn prefilter_state(&self) -> PrefilterState { + if self.prefn.is_none() { + PrefilterState::inert() + } else { + PrefilterState::new() + } + } + + fn needle(&self) -> &[u8] { + self.needle.as_slice() + } + + fn as_ref(&self) -> Searcher<'_> { + use self::SearcherKind::*; + + let kind = match self.kind { + Empty => Empty, + OneByte(b) => OneByte(b), + TwoWay(tw) => TwoWay(tw), + #[cfg(all(not(miri), memchr_runtime_simd))] + GenericSIMD128(gs) => GenericSIMD128(gs), + #[cfg(all( + not(miri), + target_arch = "x86_64", + memchr_runtime_simd + ))] + GenericSIMD256(gs) => GenericSIMD256(gs), + }; + Searcher { + needle: CowBytes::new(self.needle()), + ninfo: self.ninfo, + prefn: self.prefn, + kind, + } + } + + #[cfg(feature = "std")] + fn into_owned(self) -> Searcher<'static> { + use self::SearcherKind::*; + + let kind = match self.kind { + Empty => Empty, + OneByte(b) => OneByte(b), + TwoWay(tw) => TwoWay(tw), + #[cfg(all(not(miri), memchr_runtime_simd))] + GenericSIMD128(gs) => GenericSIMD128(gs), + #[cfg(all( + not(miri), + target_arch = "x86_64", + memchr_runtime_simd + ))] + GenericSIMD256(gs) => GenericSIMD256(gs), + }; + Searcher { + needle: self.needle.into_owned(), + ninfo: self.ninfo, + prefn: self.prefn, + kind, + } + } + + /// Implements forward substring search by selecting the implementation + /// chosen at construction and executing it on the given haystack with the + /// prefilter's current state of effectiveness. + #[inline(always)] + fn find( + &self, + state: &mut PrefilterState, + haystack: &[u8], + ) -> Option { + use self::SearcherKind::*; + + let needle = self.needle(); + if haystack.len() < needle.len() { + return None; + } + match self.kind { + Empty => Some(0), + OneByte(b) => crate::memchr(b, haystack), + TwoWay(ref tw) => { + // For very short haystacks (e.g., where the prefilter probably + // can't run), it's faster to just run RK. + if rabinkarp::is_fast(haystack, needle) { + rabinkarp::find_with(&self.ninfo.nhash, haystack, needle) + } else { + self.find_tw(tw, state, haystack, needle) + } + } + #[cfg(all(not(miri), memchr_runtime_simd))] + GenericSIMD128(ref gs) => { + // The SIMD matcher can't handle particularly short haystacks, + // so we fall back to RK in these cases. + if haystack.len() < gs.min_haystack_len() { + rabinkarp::find_with(&self.ninfo.nhash, haystack, needle) + } else { + gs.find(haystack, needle) + } + } + #[cfg(all( + not(miri), + target_arch = "x86_64", + memchr_runtime_simd + ))] + GenericSIMD256(ref gs) => { + // The SIMD matcher can't handle particularly short haystacks, + // so we fall back to RK in these cases. + if haystack.len() < gs.min_haystack_len() { + rabinkarp::find_with(&self.ninfo.nhash, haystack, needle) + } else { + gs.find(haystack, needle) + } + } + } + } + + /// Calls Two-Way on the given haystack/needle. + /// + /// This is marked as unlineable since it seems to have a better overall + /// effect on benchmarks. However, this is one of those cases where + /// inlining it results an improvement in other benchmarks too, so I + /// suspect we just don't have enough data yet to make the right call here. + /// + /// I suspect the main problem is that this function contains two different + /// inlined copies of Two-Way: one with and one without prefilters enabled. + #[inline(never)] + fn find_tw( + &self, + tw: &twoway::Forward, + state: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], + ) -> Option { + if let Some(prefn) = self.prefn { + // We used to look at the length of a haystack here. That is, if + // it was too small, then don't bother with the prefilter. But two + // things changed: the prefilter falls back to memchr for small + // haystacks, and, above, Rabin-Karp is employed for tiny haystacks + // anyway. + if state.is_effective() { + let mut pre = Pre { state, prefn, ninfo: &self.ninfo }; + return tw.find(Some(&mut pre), haystack, needle); + } + } + tw.find(None, haystack, needle) + } +} + +impl NeedleInfo { + pub(crate) fn new(needle: &[u8]) -> NeedleInfo { + NeedleInfo { + rarebytes: RareNeedleBytes::forward(needle), + nhash: NeedleHash::forward(needle), + } + } +} + +/// The internal implementation of a reverse substring searcher. +/// +/// See the forward searcher docs for more details. Currently, the reverse +/// searcher is considerably simpler since it lacks prefilter support. This +/// was done because it adds a lot of code, and more surface area to test. And +/// in particular, it's not clear whether a prefilter on reverse searching is +/// worth it. (If you have a compelling use case, please file an issue!) +#[derive(Clone, Debug)] +struct SearcherRev<'n> { + /// The actual needle we're searching for. + needle: CowBytes<'n>, + /// A Rabin-Karp hash of the needle. + nhash: NeedleHash, + /// The actual substring implementation in use. + kind: SearcherRevKind, +} + +#[derive(Clone, Debug)] +enum SearcherRevKind { + /// A special case for empty needles. An empty needle always matches, even + /// in an empty haystack. + Empty, + /// This is used whenever the needle is a single byte. In this case, we + /// always use memchr. + OneByte(u8), + /// Two-Way is the generic work horse and is what provides our additive + /// linear time guarantee. In general, it's used when the needle is bigger + /// than 8 bytes or so. + TwoWay(twoway::Reverse), +} + +impl<'n> SearcherRev<'n> { + fn new(needle: &'n [u8]) -> SearcherRev<'n> { + use self::SearcherRevKind::*; + + let kind = if needle.len() == 0 { + Empty + } else if needle.len() == 1 { + OneByte(needle[0]) + } else { + TwoWay(twoway::Reverse::new(needle)) + }; + SearcherRev { + needle: CowBytes::new(needle), + nhash: NeedleHash::reverse(needle), + kind, + } + } + + fn needle(&self) -> &[u8] { + self.needle.as_slice() + } + + fn as_ref(&self) -> SearcherRev<'_> { + use self::SearcherRevKind::*; + + let kind = match self.kind { + Empty => Empty, + OneByte(b) => OneByte(b), + TwoWay(tw) => TwoWay(tw), + }; + SearcherRev { + needle: CowBytes::new(self.needle()), + nhash: self.nhash, + kind, + } + } + + #[cfg(feature = "std")] + fn into_owned(self) -> SearcherRev<'static> { + use self::SearcherRevKind::*; + + let kind = match self.kind { + Empty => Empty, + OneByte(b) => OneByte(b), + TwoWay(tw) => TwoWay(tw), + }; + SearcherRev { + needle: self.needle.into_owned(), + nhash: self.nhash, + kind, + } + } + + /// Implements reverse substring search by selecting the implementation + /// chosen at construction and executing it on the given haystack with the + /// prefilter's current state of effectiveness. + #[inline(always)] + fn rfind(&self, haystack: &[u8]) -> Option { + use self::SearcherRevKind::*; + + let needle = self.needle(); + if haystack.len() < needle.len() { + return None; + } + match self.kind { + Empty => Some(haystack.len()), + OneByte(b) => crate::memrchr(b, haystack), + TwoWay(ref tw) => { + // For very short haystacks (e.g., where the prefilter probably + // can't run), it's faster to just run RK. + if rabinkarp::is_fast(haystack, needle) { + rabinkarp::rfind_with(&self.nhash, haystack, needle) + } else { + tw.rfind(haystack, needle) + } + } + } + } +} + +/// This module defines some generic quickcheck properties useful for testing +/// any substring search algorithm. It also runs those properties for the +/// top-level public API memmem routines. (The properties are also used to +/// test various substring search implementations more granularly elsewhere as +/// well.) +#[cfg(all(test, feature = "std", not(miri)))] +mod proptests { + // N.B. This defines the quickcheck tests using the properties defined + // below. Because of macro-visibility weirdness, the actual macro is + // defined at the top of this file. + define_memmem_quickcheck_tests!(super::find, super::rfind); + + /// Check that every prefix of the given byte string is a substring. + pub(crate) fn prefix_is_substring( + reverse: bool, + bs: &[u8], + mut search: impl FnMut(&[u8], &[u8]) -> Option, + ) -> bool { + if bs.is_empty() { + return true; + } + for i in 0..(bs.len() - 1) { + let prefix = &bs[..i]; + if reverse { + assert_eq!(naive_rfind(bs, prefix), search(bs, prefix)); + } else { + assert_eq!(naive_find(bs, prefix), search(bs, prefix)); + } + } + true + } + + /// Check that every suffix of the given byte string is a substring. + pub(crate) fn suffix_is_substring( + reverse: bool, + bs: &[u8], + mut search: impl FnMut(&[u8], &[u8]) -> Option, + ) -> bool { + if bs.is_empty() { + return true; + } + for i in 0..(bs.len() - 1) { + let suffix = &bs[i..]; + if reverse { + assert_eq!(naive_rfind(bs, suffix), search(bs, suffix)); + } else { + assert_eq!(naive_find(bs, suffix), search(bs, suffix)); + } + } + true + } + + /// Check that naive substring search matches the result of the given search + /// algorithm. + pub(crate) fn matches_naive( + reverse: bool, + haystack: &[u8], + needle: &[u8], + mut search: impl FnMut(&[u8], &[u8]) -> Option, + ) -> bool { + if reverse { + naive_rfind(haystack, needle) == search(haystack, needle) + } else { + naive_find(haystack, needle) == search(haystack, needle) + } + } + + /// Naively search forwards for the given needle in the given haystack. + fn naive_find(haystack: &[u8], needle: &[u8]) -> Option { + if needle.is_empty() { + return Some(0); + } else if haystack.len() < needle.len() { + return None; + } + for i in 0..(haystack.len() - needle.len() + 1) { + if needle == &haystack[i..i + needle.len()] { + return Some(i); + } + } + None + } + + /// Naively search in reverse for the given needle in the given haystack. + fn naive_rfind(haystack: &[u8], needle: &[u8]) -> Option { + if needle.is_empty() { + return Some(haystack.len()); + } else if haystack.len() < needle.len() { + return None; + } + for i in (0..(haystack.len() - needle.len() + 1)).rev() { + if needle == &haystack[i..i + needle.len()] { + return Some(i); + } + } + None + } +} + +/// This module defines some hand-written "simple" substring tests. It +/// also provides routines for easily running them on any substring search +/// implementation. +#[cfg(test)] +mod testsimples { + define_memmem_simple_tests!(super::find, super::rfind); + + /// Each test is a (needle, haystack, expected_fwd, expected_rev) tuple. + type SearchTest = + (&'static str, &'static str, Option, Option); + + const SEARCH_TESTS: &'static [SearchTest] = &[ + ("", "", Some(0), Some(0)), + ("", "a", Some(0), Some(1)), + ("", "ab", Some(0), Some(2)), + ("", "abc", Some(0), Some(3)), + ("a", "", None, None), + ("a", "a", Some(0), Some(0)), + ("a", "aa", Some(0), Some(1)), + ("a", "ba", Some(1), Some(1)), + ("a", "bba", Some(2), Some(2)), + ("a", "bbba", Some(3), Some(3)), + ("a", "bbbab", Some(3), Some(3)), + ("a", "bbbabb", Some(3), Some(3)), + ("a", "bbbabbb", Some(3), Some(3)), + ("a", "bbbbbb", None, None), + ("ab", "", None, None), + ("ab", "a", None, None), + ("ab", "b", None, None), + ("ab", "ab", Some(0), Some(0)), + ("ab", "aab", Some(1), Some(1)), + ("ab", "aaab", Some(2), Some(2)), + ("ab", "abaab", Some(0), Some(3)), + ("ab", "baaab", Some(3), Some(3)), + ("ab", "acb", None, None), + ("ab", "abba", Some(0), Some(0)), + ("abc", "ab", None, None), + ("abc", "abc", Some(0), Some(0)), + ("abc", "abcz", Some(0), Some(0)), + ("abc", "abczz", Some(0), Some(0)), + ("abc", "zabc", Some(1), Some(1)), + ("abc", "zzabc", Some(2), Some(2)), + ("abc", "azbc", None, None), + ("abc", "abzc", None, None), + ("abczdef", "abczdefzzzzzzzzzzzzzzzzzzzz", Some(0), Some(0)), + ("abczdef", "zzzzzzzzzzzzzzzzzzzzabczdef", Some(20), Some(20)), + ("xyz", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxyz", Some(32), Some(32)), + // Failures caught by quickcheck. + ("\u{0}\u{15}", "\u{0}\u{15}\u{15}\u{0}", Some(0), Some(0)), + ("\u{0}\u{1e}", "\u{1e}\u{0}", None, None), + ]; + + /// Run the substring search tests. `search` should be a closure that + /// accepts a haystack and a needle and returns the starting position + /// of the first occurrence of needle in the haystack, or `None` if one + /// doesn't exist. + pub(crate) fn run_search_tests_fwd( + mut search: impl FnMut(&[u8], &[u8]) -> Option, + ) { + for &(needle, haystack, expected_fwd, _) in SEARCH_TESTS { + let (n, h) = (needle.as_bytes(), haystack.as_bytes()); + assert_eq!( + expected_fwd, + search(h, n), + "needle: {:?}, haystack: {:?}, expected: {:?}", + n, + h, + expected_fwd + ); + } + } + + /// Run the substring search tests. `search` should be a closure that + /// accepts a haystack and a needle and returns the starting position of + /// the last occurrence of needle in the haystack, or `None` if one doesn't + /// exist. + pub(crate) fn run_search_tests_rev( + mut search: impl FnMut(&[u8], &[u8]) -> Option, + ) { + for &(needle, haystack, _, expected_rev) in SEARCH_TESTS { + let (n, h) = (needle.as_bytes(), haystack.as_bytes()); + assert_eq!( + expected_rev, + search(h, n), + "needle: {:?}, haystack: {:?}, expected: {:?}", + n, + h, + expected_rev + ); + } + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/fallback.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/fallback.rs new file mode 100644 index 00000000..ae1bbccb --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/fallback.rs @@ -0,0 +1,122 @@ +/* +This module implements a "fallback" prefilter that only relies on memchr to +function. While memchr works best when it's explicitly vectorized, its +fallback implementations are fast enough to make a prefilter like this +worthwhile. + +The essence of this implementation is to identify two rare bytes in a needle +based on a background frequency distribution of bytes. We then run memchr on the +rarer byte. For each match, we use the second rare byte as a guard to quickly +check if a match is possible. If the position passes the guard test, then we do +a naive memcmp to confirm the match. + +In practice, this formulation works amazingly well, primarily because of the +heuristic use of a background frequency distribution. However, it does have a +number of weaknesses where it can get quite slow when its background frequency +distribution doesn't line up with the haystack being searched. This is why we +have specialized vector routines that essentially take this idea and move the +guard check into vectorized code. (Those specialized vector routines do still +make use of the background frequency distribution of bytes though.) + +This fallback implementation was originally formulated in regex many moons ago: +https://github.com/rust-lang/regex/blob/3db8722d0b204a85380fe2a65e13d7065d7dd968/src/literal/imp.rs#L370-L501 +Prior to that, I'm not aware of anyone using this technique in any prominent +substring search implementation. Although, I'm sure folks have had this same +insight long before me. + +Another version of this also appeared in bstr: +https://github.com/BurntSushi/bstr/blob/a444256ca7407fe180ee32534688549655b7a38e/src/search/prefilter.rs#L83-L340 +*/ + +use crate::memmem::{ + prefilter::{PrefilterFnTy, PrefilterState}, + NeedleInfo, +}; + +// Check that the functions below satisfy the Prefilter function type. +const _: PrefilterFnTy = find; + +/// Look for a possible occurrence of needle. The position returned +/// corresponds to the beginning of the occurrence, if one exists. +/// +/// Callers may assume that this never returns false negatives (i.e., it +/// never misses an actual occurrence), but must check that the returned +/// position corresponds to a match. That is, it can return false +/// positives. +/// +/// This should only be used when Freqy is constructed for forward +/// searching. +pub(crate) fn find( + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], +) -> Option { + let mut i = 0; + let (rare1i, rare2i) = ninfo.rarebytes.as_rare_usize(); + let (rare1, rare2) = ninfo.rarebytes.as_rare_bytes(needle); + while prestate.is_effective() { + // Use a fast vectorized implementation to skip to the next + // occurrence of the rarest byte (heuristically chosen) in the + // needle. + let found = crate::memchr(rare1, &haystack[i..])?; + prestate.update(found); + i += found; + + // If we can't align our first match with the haystack, then a + // match is impossible. + if i < rare1i { + i += 1; + continue; + } + + // Align our rare2 byte with the haystack. A mismatch means that + // a match is impossible. + let aligned_rare2i = i - rare1i + rare2i; + if haystack.get(aligned_rare2i) != Some(&rare2) { + i += 1; + continue; + } + + // We've done what we can. There might be a match here. + return Some(i - rare1i); + } + // The only way we get here is if we believe our skipping heuristic + // has become ineffective. We're allowed to return false positives, + // so return the position at which we advanced to, aligned to the + // haystack. + Some(i.saturating_sub(rare1i)) +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use super::*; + + fn freqy_find(haystack: &[u8], needle: &[u8]) -> Option { + let ninfo = NeedleInfo::new(needle); + let mut prestate = PrefilterState::new(); + find(&mut prestate, &ninfo, haystack, needle) + } + + #[test] + fn freqy_forward() { + assert_eq!(Some(0), freqy_find(b"BARFOO", b"BAR")); + assert_eq!(Some(3), freqy_find(b"FOOBAR", b"BAR")); + assert_eq!(Some(0), freqy_find(b"zyzz", b"zyzy")); + assert_eq!(Some(2), freqy_find(b"zzzy", b"zyzy")); + assert_eq!(None, freqy_find(b"zazb", b"zyzy")); + assert_eq!(Some(0), freqy_find(b"yzyy", b"yzyz")); + assert_eq!(Some(2), freqy_find(b"yyyz", b"yzyz")); + assert_eq!(None, freqy_find(b"yayb", b"yzyz")); + } + + #[test] + #[cfg(not(miri))] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + + // SAFETY: super::find is safe to call for all inputs and on all + // platforms. + unsafe { PrefilterTest::run_all_tests(super::find) }; + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/genericsimd.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/genericsimd.rs new file mode 100644 index 00000000..1a6e3873 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/genericsimd.rs @@ -0,0 +1,207 @@ +use core::mem::size_of; + +use crate::memmem::{ + prefilter::{PrefilterFnTy, PrefilterState}, + vector::Vector, + NeedleInfo, +}; + +/// The implementation of the forward vector accelerated candidate finder. +/// +/// This is inspired by the "generic SIMD" algorithm described here: +/// http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd +/// +/// The main difference is that this is just a prefilter. That is, it reports +/// candidates once they are seen and doesn't attempt to confirm them. Also, +/// the bytes this routine uses to check for candidates are selected based on +/// an a priori background frequency distribution. This means that on most +/// haystacks, this will on average spend more time in vectorized code than you +/// would if you just selected the first and last bytes of the needle. +/// +/// Note that a non-prefilter variant of this algorithm can be found in the +/// parent module, but it only works on smaller needles. +/// +/// `prestate`, `ninfo`, `haystack` and `needle` are the four prefilter +/// function parameters. `fallback` is a prefilter that is used if the haystack +/// is too small to be handled with the given vector size. +/// +/// This routine is not safe because it is intended for callers to specialize +/// this with a particular vector (e.g., __m256i) and then call it with the +/// relevant target feature (e.g., avx2) enabled. +/// +/// # Panics +/// +/// If `needle.len() <= 1`, then this panics. +/// +/// # Safety +/// +/// Since this is meant to be used with vector functions, callers need to +/// specialize this inside of a function with a `target_feature` attribute. +/// Therefore, callers must ensure that whatever target feature is being used +/// supports the vector functions that this function is specialized for. (For +/// the specific vector functions used, see the Vector trait implementations.) +#[inline(always)] +pub(crate) unsafe fn find( + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], + fallback: PrefilterFnTy, +) -> Option { + assert!(needle.len() >= 2, "needle must be at least 2 bytes"); + let (rare1i, rare2i) = ninfo.rarebytes.as_rare_ordered_usize(); + let min_haystack_len = rare2i + size_of::(); + if haystack.len() < min_haystack_len { + return fallback(prestate, ninfo, haystack, needle); + } + + let start_ptr = haystack.as_ptr(); + let end_ptr = start_ptr.add(haystack.len()); + let max_ptr = end_ptr.sub(min_haystack_len); + let mut ptr = start_ptr; + + let rare1chunk = V::splat(needle[rare1i]); + let rare2chunk = V::splat(needle[rare2i]); + + // N.B. I did experiment with unrolling the loop to deal with size(V) + // bytes at a time and 2*size(V) bytes at a time. The double unroll + // was marginally faster while the quadruple unroll was unambiguously + // slower. In the end, I decided the complexity from unrolling wasn't + // worth it. I used the memmem/krate/prebuilt/huge-en/ benchmarks to + // compare. + while ptr <= max_ptr { + let m = find_in_chunk2(ptr, rare1i, rare2i, rare1chunk, rare2chunk); + if let Some(chunki) = m { + return Some(matched(prestate, start_ptr, ptr, chunki)); + } + ptr = ptr.add(size_of::()); + } + if ptr < end_ptr { + // This routine immediately quits if a candidate match is found. + // That means that if we're here, no candidate matches have been + // found at or before 'ptr'. Thus, we don't need to mask anything + // out even though we might technically search part of the haystack + // that we've already searched (because we know it can't match). + ptr = max_ptr; + let m = find_in_chunk2(ptr, rare1i, rare2i, rare1chunk, rare2chunk); + if let Some(chunki) = m { + return Some(matched(prestate, start_ptr, ptr, chunki)); + } + } + prestate.update(haystack.len()); + None +} + +// Below are two different techniques for checking whether a candidate +// match exists in a given chunk or not. find_in_chunk2 checks two bytes +// where as find_in_chunk3 checks three bytes. The idea behind checking +// three bytes is that while we do a bit more work per iteration, we +// decrease the chances of a false positive match being reported and thus +// make the search faster overall. This actually works out for the +// memmem/krate/prebuilt/huge-en/never-all-common-bytes benchmark, where +// using find_in_chunk3 is about 25% faster than find_in_chunk2. However, +// it turns out that find_in_chunk2 is faster for all other benchmarks, so +// perhaps the extra check isn't worth it in practice. +// +// For now, we go with find_in_chunk2, but we leave find_in_chunk3 around +// to make it easy to switch to and benchmark when possible. + +/// Search for an occurrence of two rare bytes from the needle in the current +/// chunk pointed to by ptr. +/// +/// rare1chunk and rare2chunk correspond to vectors with the rare1 and rare2 +/// bytes repeated in each 8-bit lane, respectively. +/// +/// # Safety +/// +/// It must be safe to do an unaligned read of size(V) bytes starting at both +/// (ptr + rare1i) and (ptr + rare2i). +#[inline(always)] +unsafe fn find_in_chunk2( + ptr: *const u8, + rare1i: usize, + rare2i: usize, + rare1chunk: V, + rare2chunk: V, +) -> Option { + let chunk0 = V::load_unaligned(ptr.add(rare1i)); + let chunk1 = V::load_unaligned(ptr.add(rare2i)); + + let eq0 = chunk0.cmpeq(rare1chunk); + let eq1 = chunk1.cmpeq(rare2chunk); + + let match_offsets = eq0.and(eq1).movemask(); + if match_offsets == 0 { + return None; + } + Some(match_offsets.trailing_zeros() as usize) +} + +/// Search for an occurrence of two rare bytes and the first byte (even if one +/// of the rare bytes is equivalent to the first byte) from the needle in the +/// current chunk pointed to by ptr. +/// +/// firstchunk, rare1chunk and rare2chunk correspond to vectors with the first, +/// rare1 and rare2 bytes repeated in each 8-bit lane, respectively. +/// +/// # Safety +/// +/// It must be safe to do an unaligned read of size(V) bytes starting at ptr, +/// (ptr + rare1i) and (ptr + rare2i). +#[allow(dead_code)] +#[inline(always)] +unsafe fn find_in_chunk3( + ptr: *const u8, + rare1i: usize, + rare2i: usize, + firstchunk: V, + rare1chunk: V, + rare2chunk: V, +) -> Option { + let chunk0 = V::load_unaligned(ptr); + let chunk1 = V::load_unaligned(ptr.add(rare1i)); + let chunk2 = V::load_unaligned(ptr.add(rare2i)); + + let eq0 = chunk0.cmpeq(firstchunk); + let eq1 = chunk1.cmpeq(rare1chunk); + let eq2 = chunk2.cmpeq(rare2chunk); + + let match_offsets = eq0.and(eq1).and(eq2).movemask(); + if match_offsets == 0 { + return None; + } + Some(match_offsets.trailing_zeros() as usize) +} + +/// Accepts a chunk-relative offset and returns a haystack relative offset +/// after updating the prefilter state. +/// +/// Why do we use this unlineable function when a search completes? Well, +/// I don't know. Really. Obviously this function was not here initially. +/// When doing profiling, the codegen for the inner loop here looked bad and +/// I didn't know why. There were a couple extra 'add' instructions and an +/// extra 'lea' instruction that I couldn't explain. I hypothesized that the +/// optimizer was having trouble untangling the hot code in the loop from the +/// code that deals with a candidate match. By putting the latter into an +/// unlineable function, it kind of forces the issue and it had the intended +/// effect: codegen improved measurably. It's good for a ~10% improvement +/// across the board on the memmem/krate/prebuilt/huge-en/ benchmarks. +#[cold] +#[inline(never)] +fn matched( + prestate: &mut PrefilterState, + start_ptr: *const u8, + ptr: *const u8, + chunki: usize, +) -> usize { + let found = diff(ptr, start_ptr) + chunki; + prestate.update(found); + found +} + +/// Subtract `b` from `a` and return the difference. `a` must be greater than +/// or equal to `b`. +fn diff(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/mod.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/mod.rs new file mode 100644 index 00000000..015d3b27 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/mod.rs @@ -0,0 +1,570 @@ +use crate::memmem::{rarebytes::RareNeedleBytes, NeedleInfo}; + +mod fallback; +#[cfg(memchr_runtime_simd)] +mod genericsimd; +#[cfg(all(not(miri), target_arch = "wasm32", memchr_runtime_simd))] +mod wasm; +#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] +mod x86; + +/// The maximum frequency rank permitted for the fallback prefilter. If the +/// rarest byte in the needle has a frequency rank above this value, then no +/// prefilter is used if the fallback prefilter would otherwise be selected. +const MAX_FALLBACK_RANK: usize = 250; + +/// A combination of prefilter effectiveness state, the prefilter function and +/// the needle info required to run a prefilter. +/// +/// For the most part, these are grouped into a single type for convenience, +/// instead of needing to pass around all three as distinct function +/// parameters. +pub(crate) struct Pre<'a> { + /// State that tracks the effectiveness of a prefilter. + pub(crate) state: &'a mut PrefilterState, + /// The actual prefilter function. + pub(crate) prefn: PrefilterFn, + /// Information about a needle, such as its RK hash and rare byte offsets. + pub(crate) ninfo: &'a NeedleInfo, +} + +impl<'a> Pre<'a> { + /// Call this prefilter on the given haystack with the given needle. + #[inline(always)] + pub(crate) fn call( + &mut self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + self.prefn.call(self.state, self.ninfo, haystack, needle) + } + + /// Return true if and only if this prefilter should be used. + #[inline(always)] + pub(crate) fn should_call(&mut self) -> bool { + self.state.is_effective() + } +} + +/// A prefilter function. +/// +/// A prefilter function describes both forward and reverse searches. +/// (Although, we don't currently implement prefilters for reverse searching.) +/// In the case of a forward search, the position returned corresponds to +/// the starting offset of a match (confirmed or possible). Its minimum +/// value is `0`, and its maximum value is `haystack.len() - 1`. In the case +/// of a reverse search, the position returned corresponds to the position +/// immediately after a match (confirmed or possible). Its minimum value is `1` +/// and its maximum value is `haystack.len()`. +/// +/// In both cases, the position returned is the starting (or ending) point of a +/// _possible_ match. That is, returning a false positive is okay. A prefilter, +/// however, must never return any false negatives. That is, if a match exists +/// at a particular position `i`, then a prefilter _must_ return that position. +/// It cannot skip past it. +/// +/// # Safety +/// +/// A prefilter function is not safe to create, since not all prefilters are +/// safe to call in all contexts. (e.g., A prefilter that uses AVX instructions +/// may only be called on x86_64 CPUs with the relevant AVX feature enabled.) +/// Thus, callers must ensure that when a prefilter function is created that it +/// is safe to call for the current environment. +#[derive(Clone, Copy)] +pub(crate) struct PrefilterFn(PrefilterFnTy); + +/// The type of a prefilter function. All prefilters must satisfy this +/// signature. +/// +/// Using a function pointer like this does inhibit inlining, but it does +/// eliminate branching and the extra costs associated with copying a larger +/// enum. Note also, that using Box can't really work +/// here, since we want to work in contexts that don't have dynamic memory +/// allocation. Moreover, in the default configuration of this crate on x86_64 +/// CPUs released in the past ~decade, we will use an AVX2-optimized prefilter, +/// which generally won't be inlineable into the surrounding code anyway. +/// (Unless AVX2 is enabled at compile time, but this is typically rare, since +/// it produces a non-portable binary.) +pub(crate) type PrefilterFnTy = unsafe fn( + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], +) -> Option; + +// If the haystack is too small for SSE2, then just run memchr on the +// rarest byte and be done with it. (It is likely that this code path is +// rarely exercised, since a higher level routine will probably dispatch to +// Rabin-Karp for such a small haystack.) +#[cfg(memchr_runtime_simd)] +fn simple_memchr_fallback( + _prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], +) -> Option { + let (rare, _) = ninfo.rarebytes.as_rare_ordered_usize(); + crate::memchr(needle[rare], haystack).map(|i| i.saturating_sub(rare)) +} + +impl PrefilterFn { + /// Create a new prefilter function from the function pointer given. + /// + /// # Safety + /// + /// Callers must ensure that the given prefilter function is safe to call + /// for all inputs in the current environment. For example, if the given + /// prefilter function uses AVX instructions, then the caller must ensure + /// that the appropriate AVX CPU features are enabled. + pub(crate) unsafe fn new(prefn: PrefilterFnTy) -> PrefilterFn { + PrefilterFn(prefn) + } + + /// Call the underlying prefilter function with the given arguments. + pub fn call( + self, + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], + ) -> Option { + // SAFETY: Callers have the burden of ensuring that a prefilter + // function is safe to call for all inputs in the current environment. + unsafe { (self.0)(prestate, ninfo, haystack, needle) } + } +} + +impl core::fmt::Debug for PrefilterFn { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + "".fmt(f) + } +} + +/// Prefilter controls whether heuristics are used to accelerate searching. +/// +/// A prefilter refers to the idea of detecting candidate matches very quickly, +/// and then confirming whether those candidates are full matches. This +/// idea can be quite effective since it's often the case that looking for +/// candidates can be a lot faster than running a complete substring search +/// over the entire input. Namely, looking for candidates can be done with +/// extremely fast vectorized code. +/// +/// The downside of a prefilter is that it assumes false positives (which are +/// candidates generated by a prefilter that aren't matches) are somewhat rare +/// relative to the frequency of full matches. That is, if a lot of false +/// positives are generated, then it's possible for search time to be worse +/// than if the prefilter wasn't enabled in the first place. +/// +/// Another downside of a prefilter is that it can result in highly variable +/// performance, where some cases are extraordinarily fast and others aren't. +/// Typically, variable performance isn't a problem, but it may be for your use +/// case. +/// +/// The use of prefilters in this implementation does use a heuristic to detect +/// when a prefilter might not be carrying its weight, and will dynamically +/// disable its use. Nevertheless, this configuration option gives callers +/// the ability to disable prefilters if you have knowledge that they won't be +/// useful. +#[derive(Clone, Copy, Debug)] +#[non_exhaustive] +pub enum Prefilter { + /// Never used a prefilter in substring search. + None, + /// Automatically detect whether a heuristic prefilter should be used. If + /// it is used, then heuristics will be used to dynamically disable the + /// prefilter if it is believed to not be carrying its weight. + Auto, +} + +impl Default for Prefilter { + fn default() -> Prefilter { + Prefilter::Auto + } +} + +impl Prefilter { + pub(crate) fn is_none(&self) -> bool { + match *self { + Prefilter::None => true, + _ => false, + } + } +} + +/// PrefilterState tracks state associated with the effectiveness of a +/// prefilter. It is used to track how many bytes, on average, are skipped by +/// the prefilter. If this average dips below a certain threshold over time, +/// then the state renders the prefilter inert and stops using it. +/// +/// A prefilter state should be created for each search. (Where creating an +/// iterator is treated as a single search.) A prefilter state should only be +/// created from a `Freqy`. e.g., An inert `Freqy` will produce an inert +/// `PrefilterState`. +#[derive(Clone, Debug)] +pub(crate) struct PrefilterState { + /// The number of skips that has been executed. This is always 1 greater + /// than the actual number of skips. The special sentinel value of 0 + /// indicates that the prefilter is inert. This is useful to avoid + /// additional checks to determine whether the prefilter is still + /// "effective." Once a prefilter becomes inert, it should no longer be + /// used (according to our heuristics). + skips: u32, + /// The total number of bytes that have been skipped. + skipped: u32, +} + +impl PrefilterState { + /// The minimum number of skip attempts to try before considering whether + /// a prefilter is effective or not. + const MIN_SKIPS: u32 = 50; + + /// The minimum amount of bytes that skipping must average. + /// + /// This value was chosen based on varying it and checking + /// the microbenchmarks. In particular, this can impact the + /// pathological/repeated-{huge,small} benchmarks quite a bit if it's set + /// too low. + const MIN_SKIP_BYTES: u32 = 8; + + /// Create a fresh prefilter state. + pub(crate) fn new() -> PrefilterState { + PrefilterState { skips: 1, skipped: 0 } + } + + /// Create a fresh prefilter state that is always inert. + pub(crate) fn inert() -> PrefilterState { + PrefilterState { skips: 0, skipped: 0 } + } + + /// Update this state with the number of bytes skipped on the last + /// invocation of the prefilter. + #[inline] + pub(crate) fn update(&mut self, skipped: usize) { + self.skips = self.skips.saturating_add(1); + // We need to do this dance since it's technically possible for + // `skipped` to overflow a `u32`. (And we use a `u32` to reduce the + // size of a prefilter state.) + if skipped > core::u32::MAX as usize { + self.skipped = core::u32::MAX; + } else { + self.skipped = self.skipped.saturating_add(skipped as u32); + } + } + + /// Return true if and only if this state indicates that a prefilter is + /// still effective. + #[inline] + pub(crate) fn is_effective(&mut self) -> bool { + if self.is_inert() { + return false; + } + if self.skips() < PrefilterState::MIN_SKIPS { + return true; + } + if self.skipped >= PrefilterState::MIN_SKIP_BYTES * self.skips() { + return true; + } + + // We're inert. + self.skips = 0; + false + } + + #[inline] + fn is_inert(&self) -> bool { + self.skips == 0 + } + + #[inline] + fn skips(&self) -> u32 { + self.skips.saturating_sub(1) + } +} + +/// Determine which prefilter function, if any, to use. +/// +/// This only applies to x86_64 when runtime SIMD detection is enabled (which +/// is the default). In general, we try to use an AVX prefilter, followed by +/// SSE and then followed by a generic one based on memchr. +#[inline(always)] +pub(crate) fn forward( + config: &Prefilter, + rare: &RareNeedleBytes, + needle: &[u8], +) -> Option { + if config.is_none() || needle.len() <= 1 { + return None; + } + + #[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))] + { + #[cfg(feature = "std")] + { + if cfg!(memchr_runtime_avx) { + if is_x86_feature_detected!("avx2") { + // SAFETY: x86::avx::find only requires the avx2 feature, + // which we've just checked above. + return unsafe { Some(PrefilterFn::new(x86::avx::find)) }; + } + } + } + if cfg!(memchr_runtime_sse2) { + // SAFETY: x86::sse::find only requires the sse2 feature, which is + // guaranteed to be available on x86_64. + return unsafe { Some(PrefilterFn::new(x86::sse::find)) }; + } + } + #[cfg(all(not(miri), target_arch = "wasm32", memchr_runtime_simd))] + { + // SAFETY: `wasm::find` is actually a safe function + // + // Also note that the `if true` is here to prevent, on wasm with simd, + // rustc warning about the code below being dead code. + if true { + return unsafe { Some(PrefilterFn::new(wasm::find)) }; + } + } + // Check that our rarest byte has a reasonably low rank. The main issue + // here is that the fallback prefilter can perform pretty poorly if it's + // given common bytes. So we try to avoid the worst cases here. + let (rare1_rank, _) = rare.as_ranks(needle); + if rare1_rank <= MAX_FALLBACK_RANK { + // SAFETY: fallback::find is safe to call in all environments. + return unsafe { Some(PrefilterFn::new(fallback::find)) }; + } + None +} + +/// Return the minimum length of the haystack in which a prefilter should be +/// used. If the haystack is below this length, then it's probably not worth +/// the overhead of running the prefilter. +/// +/// We used to look at the length of a haystack here. That is, if it was too +/// small, then don't bother with the prefilter. But two things changed: +/// the prefilter falls back to memchr for small haystacks, and, at the +/// meta-searcher level, Rabin-Karp is employed for tiny haystacks anyway. +/// +/// We keep it around for now in case we want to bring it back. +#[allow(dead_code)] +pub(crate) fn minimum_len(_haystack: &[u8], needle: &[u8]) -> usize { + // If the haystack length isn't greater than needle.len() * FACTOR, then + // no prefilter will be used. The presumption here is that since there + // are so few bytes to check, it's not worth running the prefilter since + // there will need to be a validation step anyway. Thus, the prefilter is + // largely redundant work. + // + // Increase the factor noticeably hurts the + // memmem/krate/prebuilt/teeny-*/never-john-watson benchmarks. + const PREFILTER_LENGTH_FACTOR: usize = 2; + const VECTOR_MIN_LENGTH: usize = 16; + let min = core::cmp::max( + VECTOR_MIN_LENGTH, + PREFILTER_LENGTH_FACTOR * needle.len(), + ); + // For haystacks with length==min, we still want to avoid the prefilter, + // so add 1. + min + 1 +} + +#[cfg(all(test, feature = "std", not(miri)))] +pub(crate) mod tests { + use std::convert::{TryFrom, TryInto}; + + use super::*; + use crate::memmem::{ + prefilter::PrefilterFnTy, rabinkarp, rarebytes::RareNeedleBytes, + }; + + // Below is a small jig that generates prefilter tests. The main purpose + // of this jig is to generate tests of varying needle/haystack lengths + // in order to try and exercise all code paths in our prefilters. And in + // particular, this is especially important for vectorized prefilters where + // certain code paths might only be exercised at certain lengths. + + /// A test that represents the input and expected output to a prefilter + /// function. The test should be able to run with any prefilter function + /// and get the expected output. + pub(crate) struct PrefilterTest { + // These fields represent the inputs and expected output of a forwards + // prefilter function. + pub(crate) ninfo: NeedleInfo, + pub(crate) haystack: Vec, + pub(crate) needle: Vec, + pub(crate) output: Option, + } + + impl PrefilterTest { + /// Run all generated forward prefilter tests on the given prefn. + /// + /// # Safety + /// + /// Callers must ensure that the given prefilter function pointer is + /// safe to call for all inputs in the current environment. + pub(crate) unsafe fn run_all_tests(prefn: PrefilterFnTy) { + PrefilterTest::run_all_tests_filter(prefn, |_| true) + } + + /// Run all generated forward prefilter tests that pass the given + /// predicate on the given prefn. + /// + /// # Safety + /// + /// Callers must ensure that the given prefilter function pointer is + /// safe to call for all inputs in the current environment. + pub(crate) unsafe fn run_all_tests_filter( + prefn: PrefilterFnTy, + mut predicate: impl FnMut(&PrefilterTest) -> bool, + ) { + for seed in PREFILTER_TEST_SEEDS { + for test in seed.generate() { + if predicate(&test) { + test.run(prefn); + } + } + } + } + + /// Create a new prefilter test from a seed and some chose offsets to + /// rare bytes in the seed's needle. + /// + /// If a valid test could not be constructed, then None is returned. + /// (Currently, we take the approach of massaging tests to be valid + /// instead of rejecting them outright.) + fn new( + seed: PrefilterTestSeed, + rare1i: usize, + rare2i: usize, + haystack_len: usize, + needle_len: usize, + output: Option, + ) -> Option { + let mut rare1i: u8 = rare1i.try_into().unwrap(); + let mut rare2i: u8 = rare2i.try_into().unwrap(); + // The '#' byte is never used in a haystack (unless we're expecting + // a match), while the '@' byte is never used in a needle. + let mut haystack = vec![b'@'; haystack_len]; + let mut needle = vec![b'#'; needle_len]; + needle[0] = seed.first; + needle[rare1i as usize] = seed.rare1; + needle[rare2i as usize] = seed.rare2; + // If we're expecting a match, then make sure the needle occurs + // in the haystack at the expected position. + if let Some(i) = output { + haystack[i..i + needle.len()].copy_from_slice(&needle); + } + // If the operations above lead to rare offsets pointing to the + // non-first occurrence of a byte, then adjust it. This might lead + // to redundant tests, but it's simpler than trying to change the + // generation process I think. + if let Some(i) = crate::memchr(seed.rare1, &needle) { + rare1i = u8::try_from(i).unwrap(); + } + if let Some(i) = crate::memchr(seed.rare2, &needle) { + rare2i = u8::try_from(i).unwrap(); + } + let ninfo = NeedleInfo { + rarebytes: RareNeedleBytes::new(rare1i, rare2i), + nhash: rabinkarp::NeedleHash::forward(&needle), + }; + Some(PrefilterTest { ninfo, haystack, needle, output }) + } + + /// Run this specific test on the given prefilter function. If the + /// outputs do no match, then this routine panics with a failure + /// message. + /// + /// # Safety + /// + /// Callers must ensure that the given prefilter function pointer is + /// safe to call for all inputs in the current environment. + unsafe fn run(&self, prefn: PrefilterFnTy) { + let mut prestate = PrefilterState::new(); + assert_eq!( + self.output, + prefn( + &mut prestate, + &self.ninfo, + &self.haystack, + &self.needle + ), + "ninfo: {:?}, haystack(len={}): {:?}, needle(len={}): {:?}", + self.ninfo, + self.haystack.len(), + std::str::from_utf8(&self.haystack).unwrap(), + self.needle.len(), + std::str::from_utf8(&self.needle).unwrap(), + ); + } + } + + /// A set of prefilter test seeds. Each seed serves as the base for the + /// generation of many other tests. In essence, the seed captures the + /// "rare" and first bytes among our needle. The tests generated from each + /// seed essentially vary the length of the needle and haystack, while + /// using the rare/first byte configuration from the seed. + /// + /// The purpose of this is to test many different needle/haystack lengths. + /// In particular, some of the vector optimizations might only have bugs + /// in haystacks of a certain size. + const PREFILTER_TEST_SEEDS: &[PrefilterTestSeed] = &[ + PrefilterTestSeed { first: b'x', rare1: b'y', rare2: b'z' }, + PrefilterTestSeed { first: b'x', rare1: b'x', rare2: b'z' }, + PrefilterTestSeed { first: b'x', rare1: b'y', rare2: b'x' }, + PrefilterTestSeed { first: b'x', rare1: b'x', rare2: b'x' }, + PrefilterTestSeed { first: b'x', rare1: b'y', rare2: b'y' }, + ]; + + /// Data that describes a single prefilter test seed. + #[derive(Clone, Copy)] + struct PrefilterTestSeed { + first: u8, + rare1: u8, + rare2: u8, + } + + impl PrefilterTestSeed { + /// Generate a series of prefilter tests from this seed. + fn generate(self) -> impl Iterator { + let len_start = 2; + // The iterator below generates *a lot* of tests. The number of + // tests was chosen somewhat empirically to be "bearable" when + // running the test suite. + // + // We use an iterator here because the collective haystacks of all + // these test cases add up to enough memory to OOM a conservative + // sandbox or a small laptop. + (len_start..=40).flat_map(move |needle_len| { + let rare_start = len_start - 1; + (rare_start..needle_len).flat_map(move |rare1i| { + (rare1i..needle_len).flat_map(move |rare2i| { + (needle_len..=66).flat_map(move |haystack_len| { + PrefilterTest::new( + self, + rare1i, + rare2i, + haystack_len, + needle_len, + None, + ) + .into_iter() + .chain( + (0..=(haystack_len - needle_len)).flat_map( + move |output| { + PrefilterTest::new( + self, + rare1i, + rare2i, + haystack_len, + needle_len, + Some(output), + ) + }, + ), + ) + }) + }) + }) + }) + } + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/wasm.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/wasm.rs new file mode 100644 index 00000000..5470c922 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/wasm.rs @@ -0,0 +1,39 @@ +use core::arch::wasm32::v128; + +use crate::memmem::{ + prefilter::{PrefilterFnTy, PrefilterState}, + NeedleInfo, +}; + +// Check that the functions below satisfy the Prefilter function type. +const _: PrefilterFnTy = find; + +/// A `v128`-accelerated candidate finder for single-substring search. +#[target_feature(enable = "simd128")] +pub(crate) fn find( + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], +) -> Option { + unsafe { + super::genericsimd::find::( + prestate, + ninfo, + haystack, + needle, + super::simple_memchr_fallback, + ) + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + #[test] + #[cfg(not(miri))] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + // SAFETY: super::find is safe to call for all inputs on x86. + unsafe { PrefilterTest::run_all_tests(super::find) }; + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/avx.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/avx.rs new file mode 100644 index 00000000..fb11f335 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/avx.rs @@ -0,0 +1,46 @@ +use core::arch::x86_64::__m256i; + +use crate::memmem::{ + prefilter::{PrefilterFnTy, PrefilterState}, + NeedleInfo, +}; + +// Check that the functions below satisfy the Prefilter function type. +const _: PrefilterFnTy = find; + +/// An AVX2 accelerated candidate finder for single-substring search. +/// +/// # Safety +/// +/// Callers must ensure that the avx2 CPU feature is enabled in the current +/// environment. +#[target_feature(enable = "avx2")] +pub(crate) unsafe fn find( + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], +) -> Option { + super::super::genericsimd::find::<__m256i>( + prestate, + ninfo, + haystack, + needle, + super::sse::find, + ) +} + +#[cfg(test)] +mod tests { + #[test] + #[cfg(not(miri))] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + if !is_x86_feature_detected!("avx2") { + return; + } + // SAFETY: The safety of super::find only requires that the current + // CPU support AVX2, which we checked above. + unsafe { PrefilterTest::run_all_tests(super::find) }; + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/mod.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/mod.rs new file mode 100644 index 00000000..91381e51 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/mod.rs @@ -0,0 +1,5 @@ +// We only use AVX when we can detect at runtime whether it's available, which +// requires std. +#[cfg(feature = "std")] +pub(crate) mod avx; +pub(crate) mod sse; diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/sse.rs b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/sse.rs new file mode 100644 index 00000000..b1c48e1e --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/prefilter/x86/sse.rs @@ -0,0 +1,42 @@ +use core::arch::x86_64::__m128i; + +use crate::memmem::{ + prefilter::{PrefilterFnTy, PrefilterState}, + NeedleInfo, +}; + +// Check that the functions below satisfy the Prefilter function type. +const _: PrefilterFnTy = find; + +/// An SSE2 accelerated candidate finder for single-substring search. +/// +/// # Safety +/// +/// Callers must ensure that the sse2 CPU feature is enabled in the current +/// environment. This feature should be enabled in all x86_64 targets. +#[target_feature(enable = "sse2")] +pub(crate) unsafe fn find( + prestate: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], +) -> Option { + super::super::genericsimd::find::<__m128i>( + prestate, + ninfo, + haystack, + needle, + super::super::simple_memchr_fallback, + ) +} + +#[cfg(all(test, feature = "std"))] +mod tests { + #[test] + #[cfg(not(miri))] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + // SAFETY: super::find is safe to call for all inputs on x86. + unsafe { PrefilterTest::run_all_tests(super::find) }; + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/rabinkarp.rs b/utshell-0.5.0/vendor/memchr/src/memmem/rabinkarp.rs new file mode 100644 index 00000000..daa4015d --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/rabinkarp.rs @@ -0,0 +1,233 @@ +/* +This module implements the classical Rabin-Karp substring search algorithm, +with no extra frills. While its use would seem to break our time complexity +guarantee of O(m+n) (RK's time complexity is O(mn)), we are careful to only +ever use RK on a constant subset of haystacks. The main point here is that +RK has good latency properties for small needles/haystacks. It's very quick +to compute a needle hash and zip through the haystack when compared to +initializing Two-Way, for example. And this is especially useful for cases +where the haystack is just too short for vector instructions to do much good. + +The hashing function used here is the same one recommended by ESMAJ. + +Another choice instead of Rabin-Karp would be Shift-Or. But its latency +isn't quite as good since its preprocessing time is a bit more expensive +(both in practice and in theory). However, perhaps Shift-Or has a place +somewhere else for short patterns. I think the main problem is that it +requires space proportional to the alphabet and the needle. If we, for +example, supported needles up to length 16, then the total table size would be +len(alphabet)*size_of::()==512 bytes. Which isn't exactly small, and it's +probably bad to put that on the stack. So ideally, we'd throw it on the heap, +but we'd really like to write as much code without using alloc/std as possible. +But maybe it's worth the special casing. It's a TODO to benchmark. + +Wikipedia has a decent explanation, if a bit heavy on the theory: +https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm + +But ESMAJ provides something a bit more concrete: +http://www-igm.univ-mlv.fr/~lecroq/string/node5.html + +Finally, aho-corasick uses Rabin-Karp for multiple pattern match in some cases: +https://github.com/BurntSushi/aho-corasick/blob/3852632f10587db0ff72ef29e88d58bf305a0946/src/packed/rabinkarp.rs +*/ + +/// Whether RK is believed to be very fast for the given needle/haystack. +pub(crate) fn is_fast(haystack: &[u8], _needle: &[u8]) -> bool { + haystack.len() < 16 +} + +/// Search for the first occurrence of needle in haystack using Rabin-Karp. +pub(crate) fn find(haystack: &[u8], needle: &[u8]) -> Option { + find_with(&NeedleHash::forward(needle), haystack, needle) +} + +/// Search for the first occurrence of needle in haystack using Rabin-Karp with +/// a pre-computed needle hash. +pub(crate) fn find_with( + nhash: &NeedleHash, + mut haystack: &[u8], + needle: &[u8], +) -> Option { + if haystack.len() < needle.len() { + return None; + } + let start = haystack.as_ptr() as usize; + let mut hash = Hash::from_bytes_fwd(&haystack[..needle.len()]); + // N.B. I've experimented with unrolling this loop, but couldn't realize + // any obvious gains. + loop { + if nhash.eq(hash) && is_prefix(haystack, needle) { + return Some(haystack.as_ptr() as usize - start); + } + if needle.len() >= haystack.len() { + return None; + } + hash.roll(&nhash, haystack[0], haystack[needle.len()]); + haystack = &haystack[1..]; + } +} + +/// Search for the last occurrence of needle in haystack using Rabin-Karp. +pub(crate) fn rfind(haystack: &[u8], needle: &[u8]) -> Option { + rfind_with(&NeedleHash::reverse(needle), haystack, needle) +} + +/// Search for the last occurrence of needle in haystack using Rabin-Karp with +/// a pre-computed needle hash. +pub(crate) fn rfind_with( + nhash: &NeedleHash, + mut haystack: &[u8], + needle: &[u8], +) -> Option { + if haystack.len() < needle.len() { + return None; + } + let mut hash = + Hash::from_bytes_rev(&haystack[haystack.len() - needle.len()..]); + loop { + if nhash.eq(hash) && is_suffix(haystack, needle) { + return Some(haystack.len() - needle.len()); + } + if needle.len() >= haystack.len() { + return None; + } + hash.roll( + &nhash, + haystack[haystack.len() - 1], + haystack[haystack.len() - needle.len() - 1], + ); + haystack = &haystack[..haystack.len() - 1]; + } +} + +/// A hash derived from a needle. +#[derive(Clone, Copy, Debug, Default)] +pub(crate) struct NeedleHash { + /// The actual hash. + hash: Hash, + /// The factor needed to multiply a byte by in order to subtract it from + /// the hash. It is defined to be 2^(n-1) (using wrapping exponentiation), + /// where n is the length of the needle. This is how we "remove" a byte + /// from the hash once the hash window rolls past it. + hash_2pow: u32, +} + +impl NeedleHash { + /// Create a new Rabin-Karp hash for the given needle for use in forward + /// searching. + pub(crate) fn forward(needle: &[u8]) -> NeedleHash { + let mut nh = NeedleHash { hash: Hash::new(), hash_2pow: 1 }; + if needle.is_empty() { + return nh; + } + nh.hash.add(needle[0]); + for &b in needle.iter().skip(1) { + nh.hash.add(b); + nh.hash_2pow = nh.hash_2pow.wrapping_shl(1); + } + nh + } + + /// Create a new Rabin-Karp hash for the given needle for use in reverse + /// searching. + pub(crate) fn reverse(needle: &[u8]) -> NeedleHash { + let mut nh = NeedleHash { hash: Hash::new(), hash_2pow: 1 }; + if needle.is_empty() { + return nh; + } + nh.hash.add(needle[needle.len() - 1]); + for &b in needle.iter().rev().skip(1) { + nh.hash.add(b); + nh.hash_2pow = nh.hash_2pow.wrapping_shl(1); + } + nh + } + + /// Return true if the hashes are equivalent. + fn eq(&self, hash: Hash) -> bool { + self.hash == hash + } +} + +/// A Rabin-Karp hash. This might represent the hash of a needle, or the hash +/// of a rolling window in the haystack. +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub(crate) struct Hash(u32); + +impl Hash { + /// Create a new hash that represents the empty string. + pub(crate) fn new() -> Hash { + Hash(0) + } + + /// Create a new hash from the bytes given for use in forward searches. + pub(crate) fn from_bytes_fwd(bytes: &[u8]) -> Hash { + let mut hash = Hash::new(); + for &b in bytes { + hash.add(b); + } + hash + } + + /// Create a new hash from the bytes given for use in reverse searches. + fn from_bytes_rev(bytes: &[u8]) -> Hash { + let mut hash = Hash::new(); + for &b in bytes.iter().rev() { + hash.add(b); + } + hash + } + + /// Add 'new' and remove 'old' from this hash. The given needle hash should + /// correspond to the hash computed for the needle being searched for. + /// + /// This is meant to be used when the rolling window of the haystack is + /// advanced. + fn roll(&mut self, nhash: &NeedleHash, old: u8, new: u8) { + self.del(nhash, old); + self.add(new); + } + + /// Add a byte to this hash. + fn add(&mut self, byte: u8) { + self.0 = self.0.wrapping_shl(1).wrapping_add(byte as u32); + } + + /// Remove a byte from this hash. The given needle hash should correspond + /// to the hash computed for the needle being searched for. + fn del(&mut self, nhash: &NeedleHash, byte: u8) { + let factor = nhash.hash_2pow; + self.0 = self.0.wrapping_sub((byte as u32).wrapping_mul(factor)); + } +} + +/// Returns true if the given needle is a prefix of the given haystack. +/// +/// We forcefully don't inline the is_prefix call and hint at the compiler that +/// it is unlikely to be called. This causes the inner rabinkarp loop above +/// to be a bit tighter and leads to some performance improvement. See the +/// memmem/krate/prebuilt/sliceslice-words/words benchmark. +#[cold] +#[inline(never)] +fn is_prefix(haystack: &[u8], needle: &[u8]) -> bool { + crate::memmem::util::is_prefix(haystack, needle) +} + +/// Returns true if the given needle is a suffix of the given haystack. +/// +/// See is_prefix for why this is forcefully not inlined. +#[cold] +#[inline(never)] +fn is_suffix(haystack: &[u8], needle: &[u8]) -> bool { + crate::memmem::util::is_suffix(haystack, needle) +} + +#[cfg(test)] +mod simpletests { + define_memmem_simple_tests!(super::find, super::rfind); +} + +#[cfg(all(test, feature = "std", not(miri)))] +mod proptests { + define_memmem_quickcheck_tests!(super::find, super::rfind); +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/rarebytes.rs b/utshell-0.5.0/vendor/memchr/src/memmem/rarebytes.rs new file mode 100644 index 00000000..fb33f689 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/rarebytes.rs @@ -0,0 +1,136 @@ +/// A heuristic frequency based detection of rare bytes for substring search. +/// +/// This detector attempts to pick out two bytes in a needle that are predicted +/// to occur least frequently. The purpose is to use these bytes to implement +/// fast candidate search using vectorized code. +/// +/// A set of offsets is only computed for needles of length 2 or greater. +/// Smaller needles should be special cased by the substring search algorithm +/// in use. (e.g., Use memchr for single byte needles.) +/// +/// Note that we use `u8` to represent the offsets of the rare bytes in a +/// needle to reduce space usage. This means that rare byte occurring after the +/// first 255 bytes in a needle will never be used. +#[derive(Clone, Copy, Debug, Default)] +pub(crate) struct RareNeedleBytes { + /// The leftmost offset of the rarest byte in the needle, according to + /// pre-computed frequency analysis. The "leftmost offset" means that + /// rare1i <= i for all i where needle[i] == needle[rare1i]. + rare1i: u8, + /// The leftmost offset of the second rarest byte in the needle, according + /// to pre-computed frequency analysis. The "leftmost offset" means that + /// rare2i <= i for all i where needle[i] == needle[rare2i]. + /// + /// The second rarest byte is used as a type of guard for quickly detecting + /// a mismatch if the first byte matches. This is a hedge against + /// pathological cases where the pre-computed frequency analysis may be + /// off. (But of course, does not prevent *all* pathological cases.) + /// + /// In general, rare1i != rare2i by construction, although there is no hard + /// requirement that they be different. However, since the case of a single + /// byte needle is handled specially by memchr itself, rare2i generally + /// always should be different from rare1i since it would otherwise be + /// ineffective as a guard. + rare2i: u8, +} + +impl RareNeedleBytes { + /// Create a new pair of rare needle bytes with the given offsets. This is + /// only used in tests for generating input data. + #[cfg(all(test, feature = "std"))] + pub(crate) fn new(rare1i: u8, rare2i: u8) -> RareNeedleBytes { + RareNeedleBytes { rare1i, rare2i } + } + + /// Detect the leftmost offsets of the two rarest bytes in the given + /// needle. + pub(crate) fn forward(needle: &[u8]) -> RareNeedleBytes { + if needle.len() <= 1 || needle.len() > core::u8::MAX as usize { + // For needles bigger than u8::MAX, our offsets aren't big enough. + // (We make our offsets small to reduce stack copying.) + // If you have a use case for it, please file an issue. In that + // case, we should probably just adjust the routine below to pick + // some rare bytes from the first 255 bytes of the needle. + // + // Also note that for needles of size 0 or 1, they are special + // cased in Two-Way. + // + // TODO: Benchmar this. + return RareNeedleBytes { rare1i: 0, rare2i: 0 }; + } + + // Find the rarest two bytes. We make them distinct by construction. + let (mut rare1, mut rare1i) = (needle[0], 0); + let (mut rare2, mut rare2i) = (needle[1], 1); + if rank(rare2) < rank(rare1) { + core::mem::swap(&mut rare1, &mut rare2); + core::mem::swap(&mut rare1i, &mut rare2i); + } + for (i, &b) in needle.iter().enumerate().skip(2) { + if rank(b) < rank(rare1) { + rare2 = rare1; + rare2i = rare1i; + rare1 = b; + rare1i = i as u8; + } else if b != rare1 && rank(b) < rank(rare2) { + rare2 = b; + rare2i = i as u8; + } + } + // While not strictly required, we really don't want these to be + // equivalent. If they were, it would reduce the effectiveness of + // candidate searching using these rare bytes by increasing the rate of + // false positives. + assert_ne!(rare1i, rare2i); + RareNeedleBytes { rare1i, rare2i } + } + + /// Return the rare bytes in the given needle in the forward direction. + /// The needle given must be the same one given to the RareNeedleBytes + /// constructor. + pub(crate) fn as_rare_bytes(&self, needle: &[u8]) -> (u8, u8) { + (needle[self.rare1i as usize], needle[self.rare2i as usize]) + } + + /// Return the rare offsets such that the first offset is always <= to the + /// second offset. This is useful when the caller doesn't care whether + /// rare1 is rarer than rare2, but just wants to ensure that they are + /// ordered with respect to one another. + #[cfg(memchr_runtime_simd)] + pub(crate) fn as_rare_ordered_usize(&self) -> (usize, usize) { + let (rare1i, rare2i) = self.as_rare_ordered_u8(); + (rare1i as usize, rare2i as usize) + } + + /// Like as_rare_ordered_usize, but returns the offsets as their native + /// u8 values. + #[cfg(memchr_runtime_simd)] + pub(crate) fn as_rare_ordered_u8(&self) -> (u8, u8) { + if self.rare1i <= self.rare2i { + (self.rare1i, self.rare2i) + } else { + (self.rare2i, self.rare1i) + } + } + + /// Return the rare offsets as usize values in the order in which they were + /// constructed. rare1, for example, is constructed as the "rarer" byte, + /// and thus, callers may want to treat it differently from rare2. + pub(crate) fn as_rare_usize(&self) -> (usize, usize) { + (self.rare1i as usize, self.rare2i as usize) + } + + /// Return the byte frequency rank of each byte. The higher the rank, the + /// more frequency the byte is predicted to be. The needle given must be + /// the same one given to the RareNeedleBytes constructor. + pub(crate) fn as_ranks(&self, needle: &[u8]) -> (usize, usize) { + let (b1, b2) = self.as_rare_bytes(needle); + (rank(b1), rank(b2)) + } +} + +/// Return the heuristical frequency rank of the given byte. A lower rank +/// means the byte is believed to occur less frequently. +fn rank(b: u8) -> usize { + crate::memmem::byte_frequencies::BYTE_FREQUENCIES[b as usize] as usize +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/twoway.rs b/utshell-0.5.0/vendor/memchr/src/memmem/twoway.rs new file mode 100644 index 00000000..7f82ed15 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/twoway.rs @@ -0,0 +1,878 @@ +use core::cmp; + +use crate::memmem::{prefilter::Pre, util}; + +/// Two-Way search in the forward direction. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Forward(TwoWay); + +/// Two-Way search in the reverse direction. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Reverse(TwoWay); + +/// An implementation of the TwoWay substring search algorithm, with heuristics +/// for accelerating search based on frequency analysis. +/// +/// This searcher supports forward and reverse search, although not +/// simultaneously. It runs in O(n + m) time and O(1) space, where +/// `n ~ len(needle)` and `m ~ len(haystack)`. +/// +/// The implementation here roughly matches that which was developed by +/// Crochemore and Perrin in their 1991 paper "Two-way string-matching." The +/// changes in this implementation are 1) the use of zero-based indices, 2) a +/// heuristic skip table based on the last byte (borrowed from Rust's standard +/// library) and 3) the addition of heuristics for a fast skip loop. That is, +/// (3) this will detect bytes that are believed to be rare in the needle and +/// use fast vectorized instructions to find their occurrences quickly. The +/// Two-Way algorithm is then used to confirm whether a match at that location +/// occurred. +/// +/// The heuristic for fast skipping is automatically shut off if it's +/// detected to be ineffective at search time. Generally, this only occurs in +/// pathological cases. But this is generally necessary in order to preserve +/// a `O(n + m)` time bound. +/// +/// The code below is fairly complex and not obviously correct at all. It's +/// likely necessary to read the Two-Way paper cited above in order to fully +/// grok this code. The essence of it is: +/// +/// 1) Do something to detect a "critical" position in the needle. +/// 2) For the current position in the haystack, look if needle[critical..] +/// matches at that position. +/// 3) If so, look if needle[..critical] matches. +/// 4) If a mismatch occurs, shift the search by some amount based on the +/// critical position and a pre-computed shift. +/// +/// This type is wrapped in Forward and Reverse types that expose consistent +/// forward or reverse APIs. +#[derive(Clone, Copy, Debug)] +struct TwoWay { + /// A small bitset used as a quick prefilter (in addition to the faster + /// SIMD based prefilter). Namely, a bit 'i' is set if and only if b%64==i + /// for any b in the needle. + /// + /// When used as a prefilter, if the last byte at the current candidate + /// position is NOT in this set, then we can skip that entire candidate + /// position (the length of the needle). This is essentially the shift + /// trick found in Boyer-Moore, but only applied to bytes that don't appear + /// in the needle. + /// + /// N.B. This trick was inspired by something similar in std's + /// implementation of Two-Way. + byteset: ApproximateByteSet, + /// A critical position in needle. Specifically, this position corresponds + /// to beginning of either the minimal or maximal suffix in needle. (N.B. + /// See SuffixType below for why "minimal" isn't quite the correct word + /// here.) + /// + /// This is the position at which every search begins. Namely, search + /// starts by scanning text to the right of this position, and only if + /// there's a match does the text to the left of this position get scanned. + critical_pos: usize, + /// The amount we shift by in the Two-Way search algorithm. This + /// corresponds to the "small period" and "large period" cases. + shift: Shift, +} + +impl Forward { + /// Create a searcher that uses the Two-Way algorithm by searching forwards + /// through any haystack. + pub(crate) fn new(needle: &[u8]) -> Forward { + if needle.is_empty() { + return Forward(TwoWay::empty()); + } + + let byteset = ApproximateByteSet::new(needle); + let min_suffix = Suffix::forward(needle, SuffixKind::Minimal); + let max_suffix = Suffix::forward(needle, SuffixKind::Maximal); + let (period_lower_bound, critical_pos) = + if min_suffix.pos > max_suffix.pos { + (min_suffix.period, min_suffix.pos) + } else { + (max_suffix.period, max_suffix.pos) + }; + let shift = Shift::forward(needle, period_lower_bound, critical_pos); + Forward(TwoWay { byteset, critical_pos, shift }) + } + + /// Find the position of the first occurrence of this searcher's needle in + /// the given haystack. If one does not exist, then return None. + /// + /// This accepts prefilter state that is useful when using the same + /// searcher multiple times, such as in an iterator. + /// + /// Callers must guarantee that the needle is non-empty and its length is + /// <= the haystack's length. + #[inline(always)] + pub(crate) fn find( + &self, + pre: Option<&mut Pre<'_>>, + haystack: &[u8], + needle: &[u8], + ) -> Option { + debug_assert!(!needle.is_empty(), "needle should not be empty"); + debug_assert!(needle.len() <= haystack.len(), "haystack too short"); + + match self.0.shift { + Shift::Small { period } => { + self.find_small_imp(pre, haystack, needle, period) + } + Shift::Large { shift } => { + self.find_large_imp(pre, haystack, needle, shift) + } + } + } + + /// Like find, but handles the degenerate substring test cases. This is + /// only useful for conveniently testing this substring implementation in + /// isolation. + #[cfg(test)] + fn find_general( + &self, + pre: Option<&mut Pre<'_>>, + haystack: &[u8], + needle: &[u8], + ) -> Option { + if needle.is_empty() { + Some(0) + } else if haystack.len() < needle.len() { + None + } else { + self.find(pre, haystack, needle) + } + } + + // Each of the two search implementations below can be accelerated by a + // prefilter, but it is not always enabled. To avoid its overhead when + // its disabled, we explicitly inline each search implementation based on + // whether a prefilter will be used or not. The decision on which to use + // is made in the parent meta searcher. + + #[inline(always)] + fn find_small_imp( + &self, + mut pre: Option<&mut Pre<'_>>, + haystack: &[u8], + needle: &[u8], + period: usize, + ) -> Option { + let last_byte = needle.len() - 1; + let mut pos = 0; + let mut shift = 0; + while pos + needle.len() <= haystack.len() { + let mut i = cmp::max(self.0.critical_pos, shift); + if let Some(pre) = pre.as_mut() { + if pre.should_call() { + pos += pre.call(&haystack[pos..], needle)?; + shift = 0; + i = self.0.critical_pos; + if pos + needle.len() > haystack.len() { + return None; + } + } + } + if !self.0.byteset.contains(haystack[pos + last_byte]) { + pos += needle.len(); + shift = 0; + continue; + } + while i < needle.len() && needle[i] == haystack[pos + i] { + i += 1; + } + if i < needle.len() { + pos += i - self.0.critical_pos + 1; + shift = 0; + } else { + let mut j = self.0.critical_pos; + while j > shift && needle[j] == haystack[pos + j] { + j -= 1; + } + if j <= shift && needle[shift] == haystack[pos + shift] { + return Some(pos); + } + pos += period; + shift = needle.len() - period; + } + } + None + } + + #[inline(always)] + fn find_large_imp( + &self, + mut pre: Option<&mut Pre<'_>>, + haystack: &[u8], + needle: &[u8], + shift: usize, + ) -> Option { + let last_byte = needle.len() - 1; + let mut pos = 0; + 'outer: while pos + needle.len() <= haystack.len() { + if let Some(pre) = pre.as_mut() { + if pre.should_call() { + pos += pre.call(&haystack[pos..], needle)?; + if pos + needle.len() > haystack.len() { + return None; + } + } + } + + if !self.0.byteset.contains(haystack[pos + last_byte]) { + pos += needle.len(); + continue; + } + let mut i = self.0.critical_pos; + while i < needle.len() && needle[i] == haystack[pos + i] { + i += 1; + } + if i < needle.len() { + pos += i - self.0.critical_pos + 1; + } else { + for j in (0..self.0.critical_pos).rev() { + if needle[j] != haystack[pos + j] { + pos += shift; + continue 'outer; + } + } + return Some(pos); + } + } + None + } +} + +impl Reverse { + /// Create a searcher that uses the Two-Way algorithm by searching in + /// reverse through any haystack. + pub(crate) fn new(needle: &[u8]) -> Reverse { + if needle.is_empty() { + return Reverse(TwoWay::empty()); + } + + let byteset = ApproximateByteSet::new(needle); + let min_suffix = Suffix::reverse(needle, SuffixKind::Minimal); + let max_suffix = Suffix::reverse(needle, SuffixKind::Maximal); + let (period_lower_bound, critical_pos) = + if min_suffix.pos < max_suffix.pos { + (min_suffix.period, min_suffix.pos) + } else { + (max_suffix.period, max_suffix.pos) + }; + // let critical_pos = needle.len() - critical_pos; + let shift = Shift::reverse(needle, period_lower_bound, critical_pos); + Reverse(TwoWay { byteset, critical_pos, shift }) + } + + /// Find the position of the last occurrence of this searcher's needle + /// in the given haystack. If one does not exist, then return None. + /// + /// This will automatically initialize prefilter state. This should only + /// be used for one-off searches. + /// + /// Callers must guarantee that the needle is non-empty and its length is + /// <= the haystack's length. + #[inline(always)] + pub(crate) fn rfind( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + debug_assert!(!needle.is_empty(), "needle should not be empty"); + debug_assert!(needle.len() <= haystack.len(), "haystack too short"); + // For the reverse case, we don't use a prefilter. It's plausible that + // perhaps we should, but it's a lot of additional code to do it, and + // it's not clear that it's actually worth it. If you have a really + // compelling use case for this, please file an issue. + match self.0.shift { + Shift::Small { period } => { + self.rfind_small_imp(haystack, needle, period) + } + Shift::Large { shift } => { + self.rfind_large_imp(haystack, needle, shift) + } + } + } + + /// Like rfind, but handles the degenerate substring test cases. This is + /// only useful for conveniently testing this substring implementation in + /// isolation. + #[cfg(test)] + fn rfind_general(&self, haystack: &[u8], needle: &[u8]) -> Option { + if needle.is_empty() { + Some(haystack.len()) + } else if haystack.len() < needle.len() { + None + } else { + self.rfind(haystack, needle) + } + } + + #[inline(always)] + fn rfind_small_imp( + &self, + haystack: &[u8], + needle: &[u8], + period: usize, + ) -> Option { + let nlen = needle.len(); + let mut pos = haystack.len(); + let mut shift = nlen; + while pos >= nlen { + if !self.0.byteset.contains(haystack[pos - nlen]) { + pos -= nlen; + shift = nlen; + continue; + } + let mut i = cmp::min(self.0.critical_pos, shift); + while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] { + i -= 1; + } + if i > 0 || needle[0] != haystack[pos - nlen] { + pos -= self.0.critical_pos - i + 1; + shift = nlen; + } else { + let mut j = self.0.critical_pos; + while j < shift && needle[j] == haystack[pos - nlen + j] { + j += 1; + } + if j >= shift { + return Some(pos - nlen); + } + pos -= period; + shift = period; + } + } + None + } + + #[inline(always)] + fn rfind_large_imp( + &self, + haystack: &[u8], + needle: &[u8], + shift: usize, + ) -> Option { + let nlen = needle.len(); + let mut pos = haystack.len(); + while pos >= nlen { + if !self.0.byteset.contains(haystack[pos - nlen]) { + pos -= nlen; + continue; + } + let mut i = self.0.critical_pos; + while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] { + i -= 1; + } + if i > 0 || needle[0] != haystack[pos - nlen] { + pos -= self.0.critical_pos - i + 1; + } else { + let mut j = self.0.critical_pos; + while j < nlen && needle[j] == haystack[pos - nlen + j] { + j += 1; + } + if j == nlen { + return Some(pos - nlen); + } + pos -= shift; + } + } + None + } +} + +impl TwoWay { + fn empty() -> TwoWay { + TwoWay { + byteset: ApproximateByteSet::new(b""), + critical_pos: 0, + shift: Shift::Large { shift: 0 }, + } + } +} + +/// A representation of the amount we're allowed to shift by during Two-Way +/// search. +/// +/// When computing a critical factorization of the needle, we find the position +/// of the critical factorization by finding the needle's maximal (or minimal) +/// suffix, along with the period of that suffix. It turns out that the period +/// of that suffix is a lower bound on the period of the needle itself. +/// +/// This lower bound is equivalent to the actual period of the needle in +/// some cases. To describe that case, we denote the needle as `x` where +/// `x = uv` and `v` is the lexicographic maximal suffix of `v`. The lower +/// bound given here is always the period of `v`, which is `<= period(x)`. The +/// case where `period(v) == period(x)` occurs when `len(u) < (len(x) / 2)` and +/// where `u` is a suffix of `v[0..period(v)]`. +/// +/// This case is important because the search algorithm for when the +/// periods are equivalent is slightly different than the search algorithm +/// for when the periods are not equivalent. In particular, when they aren't +/// equivalent, we know that the period of the needle is no less than half its +/// length. In this case, we shift by an amount less than or equal to the +/// period of the needle (determined by the maximum length of the components +/// of the critical factorization of `x`, i.e., `max(len(u), len(v))`).. +/// +/// The above two cases are represented by the variants below. Each entails +/// a different instantiation of the Two-Way search algorithm. +/// +/// N.B. If we could find a way to compute the exact period in all cases, +/// then we could collapse this case analysis and simplify the algorithm. The +/// Two-Way paper suggests this is possible, but more reading is required to +/// grok why the authors didn't pursue that path. +#[derive(Clone, Copy, Debug)] +enum Shift { + Small { period: usize }, + Large { shift: usize }, +} + +impl Shift { + /// Compute the shift for a given needle in the forward direction. + /// + /// This requires a lower bound on the period and a critical position. + /// These can be computed by extracting both the minimal and maximal + /// lexicographic suffixes, and choosing the right-most starting position. + /// The lower bound on the period is then the period of the chosen suffix. + fn forward( + needle: &[u8], + period_lower_bound: usize, + critical_pos: usize, + ) -> Shift { + let large = cmp::max(critical_pos, needle.len() - critical_pos); + if critical_pos * 2 >= needle.len() { + return Shift::Large { shift: large }; + } + + let (u, v) = needle.split_at(critical_pos); + if !util::is_suffix(&v[..period_lower_bound], u) { + return Shift::Large { shift: large }; + } + Shift::Small { period: period_lower_bound } + } + + /// Compute the shift for a given needle in the reverse direction. + /// + /// This requires a lower bound on the period and a critical position. + /// These can be computed by extracting both the minimal and maximal + /// lexicographic suffixes, and choosing the left-most starting position. + /// The lower bound on the period is then the period of the chosen suffix. + fn reverse( + needle: &[u8], + period_lower_bound: usize, + critical_pos: usize, + ) -> Shift { + let large = cmp::max(critical_pos, needle.len() - critical_pos); + if (needle.len() - critical_pos) * 2 >= needle.len() { + return Shift::Large { shift: large }; + } + + let (v, u) = needle.split_at(critical_pos); + if !util::is_prefix(&v[v.len() - period_lower_bound..], u) { + return Shift::Large { shift: large }; + } + Shift::Small { period: period_lower_bound } + } +} + +/// A suffix extracted from a needle along with its period. +#[derive(Debug)] +struct Suffix { + /// The starting position of this suffix. + /// + /// If this is a forward suffix, then `&bytes[pos..]` can be used. If this + /// is a reverse suffix, then `&bytes[..pos]` can be used. That is, for + /// forward suffixes, this is an inclusive starting position, where as for + /// reverse suffixes, this is an exclusive ending position. + pos: usize, + /// The period of this suffix. + /// + /// Note that this is NOT necessarily the period of the string from which + /// this suffix comes from. (It is always less than or equal to the period + /// of the original string.) + period: usize, +} + +impl Suffix { + fn forward(needle: &[u8], kind: SuffixKind) -> Suffix { + debug_assert!(!needle.is_empty()); + + // suffix represents our maximal (or minimal) suffix, along with + // its period. + let mut suffix = Suffix { pos: 0, period: 1 }; + // The start of a suffix in `needle` that we are considering as a + // more maximal (or minimal) suffix than what's in `suffix`. + let mut candidate_start = 1; + // The current offset of our suffixes that we're comparing. + // + // When the characters at this offset are the same, then we mush on + // to the next position since no decision is possible. When the + // candidate's character is greater (or lesser) than the corresponding + // character than our current maximal (or minimal) suffix, then the + // current suffix is changed over to the candidate and we restart our + // search. Otherwise, the candidate suffix is no good and we restart + // our search on the next candidate. + // + // The three cases above correspond to the three cases in the loop + // below. + let mut offset = 0; + + while candidate_start + offset < needle.len() { + let current = needle[suffix.pos + offset]; + let candidate = needle[candidate_start + offset]; + match kind.cmp(current, candidate) { + SuffixOrdering::Accept => { + suffix = Suffix { pos: candidate_start, period: 1 }; + candidate_start += 1; + offset = 0; + } + SuffixOrdering::Skip => { + candidate_start += offset + 1; + offset = 0; + suffix.period = candidate_start - suffix.pos; + } + SuffixOrdering::Push => { + if offset + 1 == suffix.period { + candidate_start += suffix.period; + offset = 0; + } else { + offset += 1; + } + } + } + } + suffix + } + + fn reverse(needle: &[u8], kind: SuffixKind) -> Suffix { + debug_assert!(!needle.is_empty()); + + // See the comments in `forward` for how this works. + let mut suffix = Suffix { pos: needle.len(), period: 1 }; + if needle.len() == 1 { + return suffix; + } + let mut candidate_start = needle.len() - 1; + let mut offset = 0; + + while offset < candidate_start { + let current = needle[suffix.pos - offset - 1]; + let candidate = needle[candidate_start - offset - 1]; + match kind.cmp(current, candidate) { + SuffixOrdering::Accept => { + suffix = Suffix { pos: candidate_start, period: 1 }; + candidate_start -= 1; + offset = 0; + } + SuffixOrdering::Skip => { + candidate_start -= offset + 1; + offset = 0; + suffix.period = suffix.pos - candidate_start; + } + SuffixOrdering::Push => { + if offset + 1 == suffix.period { + candidate_start -= suffix.period; + offset = 0; + } else { + offset += 1; + } + } + } + } + suffix + } +} + +/// The kind of suffix to extract. +#[derive(Clone, Copy, Debug)] +enum SuffixKind { + /// Extract the smallest lexicographic suffix from a string. + /// + /// Technically, this doesn't actually pick the smallest lexicographic + /// suffix. e.g., Given the choice between `a` and `aa`, this will choose + /// the latter over the former, even though `a < aa`. The reasoning for + /// this isn't clear from the paper, but it still smells like a minimal + /// suffix. + Minimal, + /// Extract the largest lexicographic suffix from a string. + /// + /// Unlike `Minimal`, this really does pick the maximum suffix. e.g., Given + /// the choice between `z` and `zz`, this will choose the latter over the + /// former. + Maximal, +} + +/// The result of comparing corresponding bytes between two suffixes. +#[derive(Clone, Copy, Debug)] +enum SuffixOrdering { + /// This occurs when the given candidate byte indicates that the candidate + /// suffix is better than the current maximal (or minimal) suffix. That is, + /// the current candidate suffix should supplant the current maximal (or + /// minimal) suffix. + Accept, + /// This occurs when the given candidate byte excludes the candidate suffix + /// from being better than the current maximal (or minimal) suffix. That + /// is, the current candidate suffix should be dropped and the next one + /// should be considered. + Skip, + /// This occurs when no decision to accept or skip the candidate suffix + /// can be made, e.g., when corresponding bytes are equivalent. In this + /// case, the next corresponding bytes should be compared. + Push, +} + +impl SuffixKind { + /// Returns true if and only if the given candidate byte indicates that + /// it should replace the current suffix as the maximal (or minimal) + /// suffix. + fn cmp(self, current: u8, candidate: u8) -> SuffixOrdering { + use self::SuffixOrdering::*; + + match self { + SuffixKind::Minimal if candidate < current => Accept, + SuffixKind::Minimal if candidate > current => Skip, + SuffixKind::Minimal => Push, + SuffixKind::Maximal if candidate > current => Accept, + SuffixKind::Maximal if candidate < current => Skip, + SuffixKind::Maximal => Push, + } + } +} + +/// A bitset used to track whether a particular byte exists in a needle or not. +/// +/// Namely, bit 'i' is set if and only if byte%64==i for any byte in the +/// needle. If a particular byte in the haystack is NOT in this set, then one +/// can conclude that it is also not in the needle, and thus, one can advance +/// in the haystack by needle.len() bytes. +#[derive(Clone, Copy, Debug)] +struct ApproximateByteSet(u64); + +impl ApproximateByteSet { + /// Create a new set from the given needle. + fn new(needle: &[u8]) -> ApproximateByteSet { + let mut bits = 0; + for &b in needle { + bits |= 1 << (b % 64); + } + ApproximateByteSet(bits) + } + + /// Return true if and only if the given byte might be in this set. This + /// may return a false positive, but will never return a false negative. + #[inline(always)] + fn contains(&self, byte: u8) -> bool { + self.0 & (1 << (byte % 64)) != 0 + } +} + +#[cfg(all(test, feature = "std", not(miri)))] +mod tests { + use quickcheck::quickcheck; + + use super::*; + + define_memmem_quickcheck_tests!( + super::simpletests::twoway_find, + super::simpletests::twoway_rfind + ); + + /// Convenience wrapper for computing the suffix as a byte string. + fn get_suffix_forward(needle: &[u8], kind: SuffixKind) -> (&[u8], usize) { + let s = Suffix::forward(needle, kind); + (&needle[s.pos..], s.period) + } + + /// Convenience wrapper for computing the reverse suffix as a byte string. + fn get_suffix_reverse(needle: &[u8], kind: SuffixKind) -> (&[u8], usize) { + let s = Suffix::reverse(needle, kind); + (&needle[..s.pos], s.period) + } + + /// Return all of the non-empty suffixes in the given byte string. + fn suffixes(bytes: &[u8]) -> Vec<&[u8]> { + (0..bytes.len()).map(|i| &bytes[i..]).collect() + } + + /// Return the lexicographically maximal suffix of the given byte string. + fn naive_maximal_suffix_forward(needle: &[u8]) -> &[u8] { + let mut sufs = suffixes(needle); + sufs.sort(); + sufs.pop().unwrap() + } + + /// Return the lexicographically maximal suffix of the reverse of the given + /// byte string. + fn naive_maximal_suffix_reverse(needle: &[u8]) -> Vec { + let mut reversed = needle.to_vec(); + reversed.reverse(); + let mut got = naive_maximal_suffix_forward(&reversed).to_vec(); + got.reverse(); + got + } + + #[test] + fn suffix_forward() { + macro_rules! assert_suffix_min { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_forward($given.as_bytes(), SuffixKind::Minimal); + let got_suffix = std::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + macro_rules! assert_suffix_max { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_forward($given.as_bytes(), SuffixKind::Maximal); + let got_suffix = std::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + assert_suffix_min!("a", "a", 1); + assert_suffix_max!("a", "a", 1); + + assert_suffix_min!("ab", "ab", 2); + assert_suffix_max!("ab", "b", 1); + + assert_suffix_min!("ba", "a", 1); + assert_suffix_max!("ba", "ba", 2); + + assert_suffix_min!("abc", "abc", 3); + assert_suffix_max!("abc", "c", 1); + + assert_suffix_min!("acb", "acb", 3); + assert_suffix_max!("acb", "cb", 2); + + assert_suffix_min!("cba", "a", 1); + assert_suffix_max!("cba", "cba", 3); + + assert_suffix_min!("abcabc", "abcabc", 3); + assert_suffix_max!("abcabc", "cabc", 3); + + assert_suffix_min!("abcabcabc", "abcabcabc", 3); + assert_suffix_max!("abcabcabc", "cabcabc", 3); + + assert_suffix_min!("abczz", "abczz", 5); + assert_suffix_max!("abczz", "zz", 1); + + assert_suffix_min!("zzabc", "abc", 3); + assert_suffix_max!("zzabc", "zzabc", 5); + + assert_suffix_min!("aaa", "aaa", 1); + assert_suffix_max!("aaa", "aaa", 1); + + assert_suffix_min!("foobar", "ar", 2); + assert_suffix_max!("foobar", "r", 1); + } + + #[test] + fn suffix_reverse() { + macro_rules! assert_suffix_min { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_reverse($given.as_bytes(), SuffixKind::Minimal); + let got_suffix = std::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + macro_rules! assert_suffix_max { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_reverse($given.as_bytes(), SuffixKind::Maximal); + let got_suffix = std::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + assert_suffix_min!("a", "a", 1); + assert_suffix_max!("a", "a", 1); + + assert_suffix_min!("ab", "a", 1); + assert_suffix_max!("ab", "ab", 2); + + assert_suffix_min!("ba", "ba", 2); + assert_suffix_max!("ba", "b", 1); + + assert_suffix_min!("abc", "a", 1); + assert_suffix_max!("abc", "abc", 3); + + assert_suffix_min!("acb", "a", 1); + assert_suffix_max!("acb", "ac", 2); + + assert_suffix_min!("cba", "cba", 3); + assert_suffix_max!("cba", "c", 1); + + assert_suffix_min!("abcabc", "abca", 3); + assert_suffix_max!("abcabc", "abcabc", 3); + + assert_suffix_min!("abcabcabc", "abcabca", 3); + assert_suffix_max!("abcabcabc", "abcabcabc", 3); + + assert_suffix_min!("abczz", "a", 1); + assert_suffix_max!("abczz", "abczz", 5); + + assert_suffix_min!("zzabc", "zza", 3); + assert_suffix_max!("zzabc", "zz", 1); + + assert_suffix_min!("aaa", "aaa", 1); + assert_suffix_max!("aaa", "aaa", 1); + } + + quickcheck! { + fn qc_suffix_forward_maximal(bytes: Vec) -> bool { + if bytes.is_empty() { + return true; + } + + let (got, _) = get_suffix_forward(&bytes, SuffixKind::Maximal); + let expected = naive_maximal_suffix_forward(&bytes); + got == expected + } + + fn qc_suffix_reverse_maximal(bytes: Vec) -> bool { + if bytes.is_empty() { + return true; + } + + let (got, _) = get_suffix_reverse(&bytes, SuffixKind::Maximal); + let expected = naive_maximal_suffix_reverse(&bytes); + expected == got + } + } +} + +#[cfg(test)] +mod simpletests { + use super::*; + + pub(crate) fn twoway_find( + haystack: &[u8], + needle: &[u8], + ) -> Option { + Forward::new(needle).find_general(None, haystack, needle) + } + + pub(crate) fn twoway_rfind( + haystack: &[u8], + needle: &[u8], + ) -> Option { + Reverse::new(needle).rfind_general(haystack, needle) + } + + define_memmem_simple_tests!(twoway_find, twoway_rfind); + + // This is a regression test caught by quickcheck that exercised a bug in + // the reverse small period handling. The bug was that we were using 'if j + // == shift' to determine if a match occurred, but the correct guard is 'if + // j >= shift', which matches the corresponding guard in the forward impl. + #[test] + fn regression_rev_small_period() { + let rfind = super::simpletests::twoway_rfind; + let haystack = "ababaz"; + let needle = "abab"; + assert_eq!(Some(0), rfind(haystack.as_bytes(), needle.as_bytes())); + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/util.rs b/utshell-0.5.0/vendor/memchr/src/memmem/util.rs new file mode 100644 index 00000000..de0e385e --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/util.rs @@ -0,0 +1,88 @@ +// These routines are meant to be optimized specifically for low latency as +// compared to the equivalent routines offered by std. (Which may invoke the +// dynamic linker and call out to libc, which introduces a bit more latency +// than we'd like.) + +/// Returns true if and only if needle is a prefix of haystack. +#[inline(always)] +pub(crate) fn is_prefix(haystack: &[u8], needle: &[u8]) -> bool { + needle.len() <= haystack.len() && memcmp(&haystack[..needle.len()], needle) +} + +/// Returns true if and only if needle is a suffix of haystack. +#[inline(always)] +pub(crate) fn is_suffix(haystack: &[u8], needle: &[u8]) -> bool { + needle.len() <= haystack.len() + && memcmp(&haystack[haystack.len() - needle.len()..], needle) +} + +/// Return true if and only if x.len() == y.len() && x[i] == y[i] for all +/// 0 <= i < x.len(). +/// +/// Why not just use actual memcmp for this? Well, memcmp requires calling out +/// to libc, and this routine is called in fairly hot code paths. Other than +/// just calling out to libc, it also seems to result in worse codegen. By +/// rolling our own memcmp in pure Rust, it seems to appear more friendly to +/// the optimizer. +/// +/// We mark this as inline always, although, some callers may not want it +/// inlined for better codegen (like Rabin-Karp). In that case, callers are +/// advised to create a non-inlineable wrapper routine that calls memcmp. +#[inline(always)] +pub(crate) fn memcmp(x: &[u8], y: &[u8]) -> bool { + if x.len() != y.len() { + return false; + } + // If we don't have enough bytes to do 4-byte at a time loads, then + // fall back to the naive slow version. + // + // TODO: We could do a copy_nonoverlapping combined with a mask instead + // of a loop. Benchmark it. + if x.len() < 4 { + for (&b1, &b2) in x.iter().zip(y) { + if b1 != b2 { + return false; + } + } + return true; + } + // When we have 4 or more bytes to compare, then proceed in chunks of 4 at + // a time using unaligned loads. + // + // Also, why do 4 byte loads instead of, say, 8 byte loads? The reason is + // that this particular version of memcmp is likely to be called with tiny + // needles. That means that if we do 8 byte loads, then a higher proportion + // of memcmp calls will use the slower variant above. With that said, this + // is a hypothesis and is only loosely supported by benchmarks. There's + // likely some improvement that could be made here. The main thing here + // though is to optimize for latency, not throughput. + + // SAFETY: Via the conditional above, we know that both `px` and `py` + // have the same length, so `px < pxend` implies that `py < pyend`. + // Thus, derefencing both `px` and `py` in the loop below is safe. + // + // Moreover, we set `pxend` and `pyend` to be 4 bytes before the actual + // end of of `px` and `py`. Thus, the final dereference outside of the + // loop is guaranteed to be valid. (The final comparison will overlap with + // the last comparison done in the loop for lengths that aren't multiples + // of four.) + // + // Finally, we needn't worry about alignment here, since we do unaligned + // loads. + unsafe { + let (mut px, mut py) = (x.as_ptr(), y.as_ptr()); + let (pxend, pyend) = (px.add(x.len() - 4), py.add(y.len() - 4)); + while px < pxend { + let vx = (px as *const u32).read_unaligned(); + let vy = (py as *const u32).read_unaligned(); + if vx != vy { + return false; + } + px = px.add(4); + py = py.add(4); + } + let vx = (pxend as *const u32).read_unaligned(); + let vy = (pyend as *const u32).read_unaligned(); + vx == vy + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/vector.rs b/utshell-0.5.0/vendor/memchr/src/memmem/vector.rs new file mode 100644 index 00000000..b81165f8 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/vector.rs @@ -0,0 +1,131 @@ +/// A trait for describing vector operations used by vectorized searchers. +/// +/// The trait is highly constrained to low level vector operations needed. In +/// general, it was invented mostly to be generic over x86's __m128i and +/// __m256i types. It's likely that once std::simd becomes a thing, we can +/// migrate to that since the operations required are quite simple. +/// +/// TODO: Consider moving this trait up a level and using it to implement +/// memchr as well. The trait might need to grow one or two methods, but +/// otherwise should be close to sufficient already. +/// +/// # Safety +/// +/// All methods are not safe since they are intended to be implemented using +/// vendor intrinsics, which are also not safe. Callers must ensure that the +/// appropriate target features are enabled in the calling function, and that +/// the current CPU supports them. All implementations should avoid marking the +/// routines with #[target_feature] and instead mark them as #[inline(always)] +/// to ensure they get appropriately inlined. (inline(always) cannot be used +/// with target_feature.) +pub(crate) trait Vector: Copy + core::fmt::Debug { + /// _mm_set1_epi8 or _mm256_set1_epi8 + unsafe fn splat(byte: u8) -> Self; + /// _mm_loadu_si128 or _mm256_loadu_si256 + unsafe fn load_unaligned(data: *const u8) -> Self; + /// _mm_movemask_epi8 or _mm256_movemask_epi8 + unsafe fn movemask(self) -> u32; + /// _mm_cmpeq_epi8 or _mm256_cmpeq_epi8 + unsafe fn cmpeq(self, vector2: Self) -> Self; + /// _mm_and_si128 or _mm256_and_si256 + unsafe fn and(self, vector2: Self) -> Self; +} + +#[cfg(target_arch = "x86_64")] +mod x86sse { + use super::Vector; + use core::arch::x86_64::*; + + impl Vector for __m128i { + #[inline(always)] + unsafe fn splat(byte: u8) -> __m128i { + _mm_set1_epi8(byte as i8) + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> __m128i { + _mm_loadu_si128(data as *const __m128i) + } + + #[inline(always)] + unsafe fn movemask(self) -> u32 { + _mm_movemask_epi8(self) as u32 + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> __m128i { + _mm_cmpeq_epi8(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> __m128i { + _mm_and_si128(self, vector2) + } + } +} + +#[cfg(all(feature = "std", target_arch = "x86_64"))] +mod x86avx { + use super::Vector; + use core::arch::x86_64::*; + + impl Vector for __m256i { + #[inline(always)] + unsafe fn splat(byte: u8) -> __m256i { + _mm256_set1_epi8(byte as i8) + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> __m256i { + _mm256_loadu_si256(data as *const __m256i) + } + + #[inline(always)] + unsafe fn movemask(self) -> u32 { + _mm256_movemask_epi8(self) as u32 + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> __m256i { + _mm256_cmpeq_epi8(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> __m256i { + _mm256_and_si256(self, vector2) + } + } +} + +#[cfg(target_arch = "wasm32")] +mod wasm_simd128 { + use super::Vector; + use core::arch::wasm32::*; + + impl Vector for v128 { + #[inline(always)] + unsafe fn splat(byte: u8) -> v128 { + u8x16_splat(byte) + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> v128 { + v128_load(data.cast()) + } + + #[inline(always)] + unsafe fn movemask(self) -> u32 { + u8x16_bitmask(self).into() + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> v128 { + u8x16_eq(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> v128 { + v128_and(self, vector2) + } + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/wasm.rs b/utshell-0.5.0/vendor/memchr/src/memmem/wasm.rs new file mode 100644 index 00000000..4e3ea985 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/wasm.rs @@ -0,0 +1,75 @@ +use core::arch::wasm32::v128; + +use crate::memmem::{genericsimd, NeedleInfo}; + +/// A `v128` accelerated vectorized substring search routine that only works on +/// small needles. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Forward(genericsimd::Forward); + +impl Forward { + /// Create a new "generic simd" forward searcher. If one could not be + /// created from the given inputs, then None is returned. + pub(crate) fn new(ninfo: &NeedleInfo, needle: &[u8]) -> Option { + if !cfg!(memchr_runtime_simd) { + return None; + } + genericsimd::Forward::new(ninfo, needle).map(Forward) + } + + /// Returns the minimum length of haystack that is needed for this searcher + /// to work. Passing a haystack with a length smaller than this will cause + /// `find` to panic. + #[inline(always)] + pub(crate) fn min_haystack_len(&self) -> usize { + self.0.min_haystack_len::() + } + + #[inline(always)] + pub(crate) fn find( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + self.find_impl(haystack, needle) + } + + /// The implementation of find marked with the appropriate target feature. + #[target_feature(enable = "simd128")] + fn find_impl(&self, haystack: &[u8], needle: &[u8]) -> Option { + unsafe { genericsimd::fwd_find::(&self.0, haystack, needle) } + } +} + +#[cfg(all(test, feature = "std", not(miri)))] +mod tests { + use crate::memmem::{prefilter::PrefilterState, NeedleInfo}; + + fn find( + _: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], + ) -> Option { + super::Forward::new(ninfo, needle).unwrap().find(haystack, needle) + } + + #[test] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + + unsafe { + PrefilterTest::run_all_tests_filter(find, |t| { + // This substring searcher only works on certain configs, so + // filter our tests such that Forward::new will be guaranteed + // to succeed. (And also remove tests with a haystack that is + // too small.) + let fwd = match super::Forward::new(&t.ninfo, &t.needle) { + None => return false, + Some(fwd) => fwd, + }; + t.haystack.len() >= fwd.min_haystack_len() + }) + } + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/x86/avx.rs b/utshell-0.5.0/vendor/memchr/src/memmem/x86/avx.rs new file mode 100644 index 00000000..ce168dd3 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/x86/avx.rs @@ -0,0 +1,139 @@ +#[cfg(not(feature = "std"))] +pub(crate) use self::nostd::Forward; +#[cfg(feature = "std")] +pub(crate) use self::std::Forward; + +#[cfg(feature = "std")] +mod std { + use core::arch::x86_64::{__m128i, __m256i}; + + use crate::memmem::{genericsimd, NeedleInfo}; + + /// An AVX accelerated vectorized substring search routine that only works + /// on small needles. + #[derive(Clone, Copy, Debug)] + pub(crate) struct Forward(genericsimd::Forward); + + impl Forward { + /// Create a new "generic simd" forward searcher. If one could not be + /// created from the given inputs, then None is returned. + pub(crate) fn new( + ninfo: &NeedleInfo, + needle: &[u8], + ) -> Option { + if !cfg!(memchr_runtime_avx) || !is_x86_feature_detected!("avx2") { + return None; + } + genericsimd::Forward::new(ninfo, needle).map(Forward) + } + + /// Returns the minimum length of haystack that is needed for this + /// searcher to work. Passing a haystack with a length smaller than + /// this will cause `find` to panic. + #[inline(always)] + pub(crate) fn min_haystack_len(&self) -> usize { + self.0.min_haystack_len::<__m128i>() + } + + #[inline(always)] + pub(crate) fn find( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + // SAFETY: The only way a Forward value can exist is if the avx2 + // target feature is enabled. This is the only safety requirement + // for calling the genericsimd searcher. + unsafe { self.find_impl(haystack, needle) } + } + + /// The implementation of find marked with the appropriate target + /// feature. + /// + /// # Safety + /// + /// Callers must ensure that the avx2 CPU feature is enabled in the + /// current environment. + #[target_feature(enable = "avx2")] + unsafe fn find_impl( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + if haystack.len() < self.0.min_haystack_len::<__m256i>() { + genericsimd::fwd_find::<__m128i>(&self.0, haystack, needle) + } else { + genericsimd::fwd_find::<__m256i>(&self.0, haystack, needle) + } + } + } +} + +// We still define the avx "forward" type on nostd to make caller code a bit +// simpler. This avoids needing a lot more conditional compilation. +#[cfg(not(feature = "std"))] +mod nostd { + use crate::memmem::NeedleInfo; + + #[derive(Clone, Copy, Debug)] + pub(crate) struct Forward(()); + + impl Forward { + pub(crate) fn new( + ninfo: &NeedleInfo, + needle: &[u8], + ) -> Option { + None + } + + pub(crate) fn min_haystack_len(&self) -> usize { + unreachable!() + } + + pub(crate) fn find( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + unreachable!() + } + } +} + +#[cfg(all(test, feature = "std", not(miri)))] +mod tests { + use crate::memmem::{prefilter::PrefilterState, NeedleInfo}; + + fn find( + _: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], + ) -> Option { + super::Forward::new(ninfo, needle).unwrap().find(haystack, needle) + } + + #[test] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + + if !is_x86_feature_detected!("avx2") { + return; + } + // SAFETY: The safety of find only requires that the current CPU + // support AVX2, which we checked above. + unsafe { + PrefilterTest::run_all_tests_filter(find, |t| { + // This substring searcher only works on certain configs, so + // filter our tests such that Forward::new will be guaranteed + // to succeed. (And also remove tests with a haystack that is + // too small.) + let fwd = match super::Forward::new(&t.ninfo, &t.needle) { + None => return false, + Some(fwd) => fwd, + }; + t.haystack.len() >= fwd.min_haystack_len() + }) + } + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/x86/mod.rs b/utshell-0.5.0/vendor/memchr/src/memmem/x86/mod.rs new file mode 100644 index 00000000..c1cc73fe --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/x86/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod avx; +pub(crate) mod sse; diff --git a/utshell-0.5.0/vendor/memchr/src/memmem/x86/sse.rs b/utshell-0.5.0/vendor/memchr/src/memmem/x86/sse.rs new file mode 100644 index 00000000..22e7d993 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/memmem/x86/sse.rs @@ -0,0 +1,89 @@ +use core::arch::x86_64::__m128i; + +use crate::memmem::{genericsimd, NeedleInfo}; + +/// An SSE accelerated vectorized substring search routine that only works on +/// small needles. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Forward(genericsimd::Forward); + +impl Forward { + /// Create a new "generic simd" forward searcher. If one could not be + /// created from the given inputs, then None is returned. + pub(crate) fn new(ninfo: &NeedleInfo, needle: &[u8]) -> Option { + if !cfg!(memchr_runtime_sse2) { + return None; + } + genericsimd::Forward::new(ninfo, needle).map(Forward) + } + + /// Returns the minimum length of haystack that is needed for this searcher + /// to work. Passing a haystack with a length smaller than this will cause + /// `find` to panic. + #[inline(always)] + pub(crate) fn min_haystack_len(&self) -> usize { + self.0.min_haystack_len::<__m128i>() + } + + #[inline(always)] + pub(crate) fn find( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + // SAFETY: sse2 is enabled on all x86_64 targets, so this is always + // safe to call. + unsafe { self.find_impl(haystack, needle) } + } + + /// The implementation of find marked with the appropriate target feature. + /// + /// # Safety + /// + /// This is safe to call in all cases since sse2 is guaranteed to be part + /// of x86_64. It is marked as unsafe because of the target feature + /// attribute. + #[target_feature(enable = "sse2")] + unsafe fn find_impl( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + genericsimd::fwd_find::<__m128i>(&self.0, haystack, needle) + } +} + +#[cfg(all(test, feature = "std", not(miri)))] +mod tests { + use crate::memmem::{prefilter::PrefilterState, NeedleInfo}; + + fn find( + _: &mut PrefilterState, + ninfo: &NeedleInfo, + haystack: &[u8], + needle: &[u8], + ) -> Option { + super::Forward::new(ninfo, needle).unwrap().find(haystack, needle) + } + + #[test] + fn prefilter_permutations() { + use crate::memmem::prefilter::tests::PrefilterTest; + + // SAFETY: sse2 is enabled on all x86_64 targets, so this is always + // safe to call. + unsafe { + PrefilterTest::run_all_tests_filter(find, |t| { + // This substring searcher only works on certain configs, so + // filter our tests such that Forward::new will be guaranteed + // to succeed. (And also remove tests with a haystack that is + // too small.) + let fwd = match super::Forward::new(&t.ninfo, &t.needle) { + None => return false, + Some(fwd) => fwd, + }; + t.haystack.len() >= fwd.min_haystack_len() + }) + } + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/tests/memchr/iter.rs b/utshell-0.5.0/vendor/memchr/src/tests/memchr/iter.rs new file mode 100644 index 00000000..80ea5c27 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/memchr/iter.rs @@ -0,0 +1,230 @@ +use quickcheck::quickcheck; + +use crate::{tests::memchr::testdata::memchr_tests, Memchr, Memchr2, Memchr3}; + +#[test] +fn memchr1_iter() { + for test in memchr_tests() { + test.iter_one(false, Memchr::new); + } +} + +#[test] +fn memchr2_iter() { + for test in memchr_tests() { + test.iter_two(false, Memchr2::new); + } +} + +#[test] +fn memchr3_iter() { + for test in memchr_tests() { + test.iter_three(false, Memchr3::new); + } +} + +#[test] +fn memrchr1_iter() { + for test in memchr_tests() { + test.iter_one(true, |n1, corpus| Memchr::new(n1, corpus).rev()); + } +} + +#[test] +fn memrchr2_iter() { + for test in memchr_tests() { + test.iter_two(true, |n1, n2, corpus| { + Memchr2::new(n1, n2, corpus).rev() + }) + } +} + +#[test] +fn memrchr3_iter() { + for test in memchr_tests() { + test.iter_three(true, |n1, n2, n3, corpus| { + Memchr3::new(n1, n2, n3, corpus).rev() + }) + } +} + +quickcheck! { + fn qc_memchr_double_ended_iter( + needle: u8, data: Vec, take_side: Vec + ) -> bool { + // make nonempty + let mut take_side = take_side; + if take_side.is_empty() { take_side.push(true) }; + + let iter = Memchr::new(needle, &data); + let all_found = double_ended_take( + iter, take_side.iter().cycle().cloned()); + + all_found.iter().cloned().eq(positions1(needle, &data)) + } + + fn qc_memchr2_double_ended_iter( + needle1: u8, needle2: u8, data: Vec, take_side: Vec + ) -> bool { + // make nonempty + let mut take_side = take_side; + if take_side.is_empty() { take_side.push(true) }; + + let iter = Memchr2::new(needle1, needle2, &data); + let all_found = double_ended_take( + iter, take_side.iter().cycle().cloned()); + + all_found.iter().cloned().eq(positions2(needle1, needle2, &data)) + } + + fn qc_memchr3_double_ended_iter( + needle1: u8, needle2: u8, needle3: u8, + data: Vec, take_side: Vec + ) -> bool { + // make nonempty + let mut take_side = take_side; + if take_side.is_empty() { take_side.push(true) }; + + let iter = Memchr3::new(needle1, needle2, needle3, &data); + let all_found = double_ended_take( + iter, take_side.iter().cycle().cloned()); + + all_found + .iter() + .cloned() + .eq(positions3(needle1, needle2, needle3, &data)) + } + + fn qc_memchr1_iter(data: Vec) -> bool { + let needle = 0; + let answer = positions1(needle, &data); + answer.eq(Memchr::new(needle, &data)) + } + + fn qc_memchr1_rev_iter(data: Vec) -> bool { + let needle = 0; + let answer = positions1(needle, &data); + answer.rev().eq(Memchr::new(needle, &data).rev()) + } + + fn qc_memchr2_iter(data: Vec) -> bool { + let needle1 = 0; + let needle2 = 1; + let answer = positions2(needle1, needle2, &data); + answer.eq(Memchr2::new(needle1, needle2, &data)) + } + + fn qc_memchr2_rev_iter(data: Vec) -> bool { + let needle1 = 0; + let needle2 = 1; + let answer = positions2(needle1, needle2, &data); + answer.rev().eq(Memchr2::new(needle1, needle2, &data).rev()) + } + + fn qc_memchr3_iter(data: Vec) -> bool { + let needle1 = 0; + let needle2 = 1; + let needle3 = 2; + let answer = positions3(needle1, needle2, needle3, &data); + answer.eq(Memchr3::new(needle1, needle2, needle3, &data)) + } + + fn qc_memchr3_rev_iter(data: Vec) -> bool { + let needle1 = 0; + let needle2 = 1; + let needle3 = 2; + let answer = positions3(needle1, needle2, needle3, &data); + answer.rev().eq(Memchr3::new(needle1, needle2, needle3, &data).rev()) + } + + fn qc_memchr1_iter_size_hint(data: Vec) -> bool { + // test that the size hint is within reasonable bounds + let needle = 0; + let mut iter = Memchr::new(needle, &data); + let mut real_count = data + .iter() + .filter(|&&elt| elt == needle) + .count(); + + while let Some(index) = iter.next() { + real_count -= 1; + let (lower, upper) = iter.size_hint(); + assert!(lower <= real_count); + assert!(upper.unwrap() >= real_count); + assert!(upper.unwrap() <= data.len() - index); + } + true + } +} + +// take items from a DEI, taking front for each true and back for each false. +// Return a vector with the concatenation of the fronts and the reverse of the +// backs. +fn double_ended_take(mut iter: I, take_side: J) -> Vec +where + I: DoubleEndedIterator, + J: Iterator, +{ + let mut found_front = Vec::new(); + let mut found_back = Vec::new(); + + for take_front in take_side { + if take_front { + if let Some(pos) = iter.next() { + found_front.push(pos); + } else { + break; + } + } else { + if let Some(pos) = iter.next_back() { + found_back.push(pos); + } else { + break; + } + }; + } + + let mut all_found = found_front; + all_found.extend(found_back.into_iter().rev()); + all_found +} + +// return an iterator of the 0-based indices of haystack that match the needle +fn positions1<'a>( + n1: u8, + haystack: &'a [u8], +) -> Box + 'a> { + let it = haystack + .iter() + .enumerate() + .filter(move |&(_, &b)| b == n1) + .map(|t| t.0); + Box::new(it) +} + +fn positions2<'a>( + n1: u8, + n2: u8, + haystack: &'a [u8], +) -> Box + 'a> { + let it = haystack + .iter() + .enumerate() + .filter(move |&(_, &b)| b == n1 || b == n2) + .map(|t| t.0); + Box::new(it) +} + +fn positions3<'a>( + n1: u8, + n2: u8, + n3: u8, + haystack: &'a [u8], +) -> Box + 'a> { + let it = haystack + .iter() + .enumerate() + .filter(move |&(_, &b)| b == n1 || b == n2 || b == n3) + .map(|t| t.0); + Box::new(it) +} diff --git a/utshell-0.5.0/vendor/memchr/src/tests/memchr/memchr.rs b/utshell-0.5.0/vendor/memchr/src/tests/memchr/memchr.rs new file mode 100644 index 00000000..ac955ed6 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/memchr/memchr.rs @@ -0,0 +1,134 @@ +use quickcheck::quickcheck; + +use crate::{ + memchr, + memchr::{fallback, naive}, + memchr2, memchr3, memrchr, memrchr2, memrchr3, + tests::memchr::testdata::memchr_tests, +}; + +#[test] +fn memchr1_find() { + for test in memchr_tests() { + test.one(false, memchr); + } +} + +#[test] +fn memchr1_fallback_find() { + for test in memchr_tests() { + test.one(false, fallback::memchr); + } +} + +#[test] +fn memchr2_find() { + for test in memchr_tests() { + test.two(false, memchr2); + } +} + +#[test] +fn memchr2_fallback_find() { + for test in memchr_tests() { + test.two(false, fallback::memchr2); + } +} + +#[test] +fn memchr3_find() { + for test in memchr_tests() { + test.three(false, memchr3); + } +} + +#[test] +fn memchr3_fallback_find() { + for test in memchr_tests() { + test.three(false, fallback::memchr3); + } +} + +#[test] +fn memrchr1_find() { + for test in memchr_tests() { + test.one(true, memrchr); + } +} + +#[test] +fn memrchr1_fallback_find() { + for test in memchr_tests() { + test.one(true, fallback::memrchr); + } +} + +#[test] +fn memrchr2_find() { + for test in memchr_tests() { + test.two(true, memrchr2); + } +} + +#[test] +fn memrchr2_fallback_find() { + for test in memchr_tests() { + test.two(true, fallback::memrchr2); + } +} + +#[test] +fn memrchr3_find() { + for test in memchr_tests() { + test.three(true, memrchr3); + } +} + +#[test] +fn memrchr3_fallback_find() { + for test in memchr_tests() { + test.three(true, fallback::memrchr3); + } +} + +quickcheck! { + fn qc_memchr1_matches_naive(n1: u8, corpus: Vec) -> bool { + memchr(n1, &corpus) == naive::memchr(n1, &corpus) + } +} + +quickcheck! { + fn qc_memchr2_matches_naive(n1: u8, n2: u8, corpus: Vec) -> bool { + memchr2(n1, n2, &corpus) == naive::memchr2(n1, n2, &corpus) + } +} + +quickcheck! { + fn qc_memchr3_matches_naive( + n1: u8, n2: u8, n3: u8, + corpus: Vec + ) -> bool { + memchr3(n1, n2, n3, &corpus) == naive::memchr3(n1, n2, n3, &corpus) + } +} + +quickcheck! { + fn qc_memrchr1_matches_naive(n1: u8, corpus: Vec) -> bool { + memrchr(n1, &corpus) == naive::memrchr(n1, &corpus) + } +} + +quickcheck! { + fn qc_memrchr2_matches_naive(n1: u8, n2: u8, corpus: Vec) -> bool { + memrchr2(n1, n2, &corpus) == naive::memrchr2(n1, n2, &corpus) + } +} + +quickcheck! { + fn qc_memrchr3_matches_naive( + n1: u8, n2: u8, n3: u8, + corpus: Vec + ) -> bool { + memrchr3(n1, n2, n3, &corpus) == naive::memrchr3(n1, n2, n3, &corpus) + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/tests/memchr/mod.rs b/utshell-0.5.0/vendor/memchr/src/tests/memchr/mod.rs new file mode 100644 index 00000000..79f94ab5 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/memchr/mod.rs @@ -0,0 +1,7 @@ +#[cfg(all(feature = "std", not(miri)))] +mod iter; +#[cfg(all(feature = "std", not(miri)))] +mod memchr; +mod simple; +#[cfg(all(feature = "std", not(miri)))] +mod testdata; diff --git a/utshell-0.5.0/vendor/memchr/src/tests/memchr/simple.rs b/utshell-0.5.0/vendor/memchr/src/tests/memchr/simple.rs new file mode 100644 index 00000000..bed5b486 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/memchr/simple.rs @@ -0,0 +1,23 @@ +// Simple tests using MIRI. These are intended only to be a simple exercise of +// memchr when tests are run under miri. These are mostly necessary because the +// other tests are far more extensive and take too long to run under miri. +// +// These tests are also run when the 'std' feature is not enabled. + +use crate::{memchr, memchr2, memchr3, memrchr, memrchr2, memrchr3}; + +#[test] +fn simple() { + assert_eq!(memchr(b'a', b"abcda"), Some(0)); + assert_eq!(memchr(b'z', b"abcda"), None); + assert_eq!(memchr2(b'a', b'z', b"abcda"), Some(0)); + assert_eq!(memchr2(b'z', b'y', b"abcda"), None); + assert_eq!(memchr3(b'a', b'z', b'b', b"abcda"), Some(0)); + assert_eq!(memchr3(b'z', b'y', b'x', b"abcda"), None); + assert_eq!(memrchr(b'a', b"abcda"), Some(4)); + assert_eq!(memrchr(b'z', b"abcda"), None); + assert_eq!(memrchr2(b'a', b'z', b"abcda"), Some(4)); + assert_eq!(memrchr2(b'z', b'y', b"abcda"), None); + assert_eq!(memrchr3(b'a', b'z', b'b', b"abcda"), Some(4)); + assert_eq!(memrchr3(b'z', b'y', b'x', b"abcda"), None); +} diff --git a/utshell-0.5.0/vendor/memchr/src/tests/memchr/testdata.rs b/utshell-0.5.0/vendor/memchr/src/tests/memchr/testdata.rs new file mode 100644 index 00000000..6dda5246 --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/memchr/testdata.rs @@ -0,0 +1,351 @@ +use std::iter::repeat; + +/// Create a sequence of tests that should be run by memchr implementations. +pub fn memchr_tests() -> Vec { + let mut tests = Vec::new(); + for statict in MEMCHR_TESTS { + assert!(!statict.corpus.contains("%"), "% is not allowed in corpora"); + assert!(!statict.corpus.contains("#"), "# is not allowed in corpora"); + assert!(!statict.needles.contains(&b'%'), "% is an invalid needle"); + assert!(!statict.needles.contains(&b'#'), "# is an invalid needle"); + + let t = MemchrTest { + corpus: statict.corpus.to_string(), + needles: statict.needles.to_vec(), + positions: statict.positions.to_vec(), + }; + tests.push(t.clone()); + tests.extend(t.expand()); + } + tests +} + +/// A set of tests for memchr-like functions. +/// +/// These tests mostly try to cover the short string cases. We cover the longer +/// string cases via the benchmarks (which are tests themselves), via +/// quickcheck tests and via automatic expansion of each test case (by +/// increasing the corpus size). Finally, we cover different alignment cases +/// in the tests by varying the starting point of the slice. +const MEMCHR_TESTS: &[MemchrTestStatic] = &[ + // one needle (applied to memchr + memchr2 + memchr3) + MemchrTestStatic { corpus: "a", needles: &[b'a'], positions: &[0] }, + MemchrTestStatic { corpus: "aa", needles: &[b'a'], positions: &[0, 1] }, + MemchrTestStatic { + corpus: "aaa", + needles: &[b'a'], + positions: &[0, 1, 2], + }, + MemchrTestStatic { corpus: "", needles: &[b'a'], positions: &[] }, + MemchrTestStatic { corpus: "z", needles: &[b'a'], positions: &[] }, + MemchrTestStatic { corpus: "zz", needles: &[b'a'], positions: &[] }, + MemchrTestStatic { corpus: "zza", needles: &[b'a'], positions: &[2] }, + MemchrTestStatic { corpus: "zaza", needles: &[b'a'], positions: &[1, 3] }, + MemchrTestStatic { corpus: "zzza", needles: &[b'a'], positions: &[3] }, + MemchrTestStatic { corpus: "\x00a", needles: &[b'a'], positions: &[1] }, + MemchrTestStatic { corpus: "\x00", needles: &[b'\x00'], positions: &[0] }, + MemchrTestStatic { + corpus: "\x00\x00", + needles: &[b'\x00'], + positions: &[0, 1], + }, + MemchrTestStatic { + corpus: "\x00a\x00", + needles: &[b'\x00'], + positions: &[0, 2], + }, + MemchrTestStatic { + corpus: "zzzzzzzzzzzzzzzza", + needles: &[b'a'], + positions: &[16], + }, + MemchrTestStatic { + corpus: "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzza", + needles: &[b'a'], + positions: &[32], + }, + // two needles (applied to memchr2 + memchr3) + MemchrTestStatic { + corpus: "az", + needles: &[b'a', b'z'], + positions: &[0, 1], + }, + MemchrTestStatic { + corpus: "az", + needles: &[b'a', b'z'], + positions: &[0, 1], + }, + MemchrTestStatic { corpus: "az", needles: &[b'x', b'y'], positions: &[] }, + MemchrTestStatic { corpus: "az", needles: &[b'a', b'y'], positions: &[0] }, + MemchrTestStatic { corpus: "az", needles: &[b'x', b'z'], positions: &[1] }, + MemchrTestStatic { + corpus: "yyyyaz", + needles: &[b'a', b'z'], + positions: &[4, 5], + }, + MemchrTestStatic { + corpus: "yyyyaz", + needles: &[b'z', b'a'], + positions: &[4, 5], + }, + // three needles (applied to memchr3) + MemchrTestStatic { + corpus: "xyz", + needles: &[b'x', b'y', b'z'], + positions: &[0, 1, 2], + }, + MemchrTestStatic { + corpus: "zxy", + needles: &[b'x', b'y', b'z'], + positions: &[0, 1, 2], + }, + MemchrTestStatic { + corpus: "zxy", + needles: &[b'x', b'a', b'z'], + positions: &[0, 1], + }, + MemchrTestStatic { + corpus: "zxy", + needles: &[b't', b'a', b'z'], + positions: &[0], + }, + MemchrTestStatic { + corpus: "yxz", + needles: &[b't', b'a', b'z'], + positions: &[2], + }, +]; + +/// A description of a test on a memchr like function. +#[derive(Clone, Debug)] +pub struct MemchrTest { + /// The thing to search. We use `&str` instead of `&[u8]` because they + /// are nicer to write in tests, and we don't miss much since memchr + /// doesn't care about UTF-8. + /// + /// Corpora cannot contain either '%' or '#'. We use these bytes when + /// expanding test cases into many test cases, and we assume they are not + /// used. If they are used, `memchr_tests` will panic. + corpus: String, + /// The needles to search for. This is intended to be an "alternation" of + /// needles. The number of needles may cause this test to be skipped for + /// some memchr variants. For example, a test with 2 needles cannot be used + /// to test `memchr`, but can be used to test `memchr2` and `memchr3`. + /// However, a test with only 1 needle can be used to test all of `memchr`, + /// `memchr2` and `memchr3`. We achieve this by filling in the needles with + /// bytes that we never used in the corpus (such as '#'). + needles: Vec, + /// The positions expected to match for all of the needles. + positions: Vec, +} + +/// Like MemchrTest, but easier to define as a constant. +#[derive(Clone, Debug)] +pub struct MemchrTestStatic { + corpus: &'static str, + needles: &'static [u8], + positions: &'static [usize], +} + +impl MemchrTest { + pub fn one Option>(&self, reverse: bool, f: F) { + let needles = match self.needles(1) { + None => return, + Some(needles) => needles, + }; + // We test different alignments here. Since some implementations use + // AVX2, which can read 32 bytes at a time, we test at least that. + // Moreover, with loop unrolling, we sometimes process 64 (sse2) or 128 + // (avx) bytes at a time, so we include that in our offsets as well. + // + // You might think this would cause most needles to not be found, but + // we actually expand our tests to include corpus sizes all the way up + // to >500 bytes, so we should exercise most branches. + for align in 0..130 { + let corpus = self.corpus(align); + assert_eq!( + self.positions(align, reverse).get(0).cloned(), + f(needles[0], corpus.as_bytes()), + "search for {:?} failed in: {:?} (len: {}, alignment: {})", + needles[0] as char, + corpus, + corpus.len(), + align + ); + } + } + + pub fn two Option>( + &self, + reverse: bool, + f: F, + ) { + let needles = match self.needles(2) { + None => return, + Some(needles) => needles, + }; + for align in 0..130 { + let corpus = self.corpus(align); + assert_eq!( + self.positions(align, reverse).get(0).cloned(), + f(needles[0], needles[1], corpus.as_bytes()), + "search for {:?}|{:?} failed in: {:?} \ + (len: {}, alignment: {})", + needles[0] as char, + needles[1] as char, + corpus, + corpus.len(), + align + ); + } + } + + pub fn three Option>( + &self, + reverse: bool, + f: F, + ) { + let needles = match self.needles(3) { + None => return, + Some(needles) => needles, + }; + for align in 0..130 { + let corpus = self.corpus(align); + assert_eq!( + self.positions(align, reverse).get(0).cloned(), + f(needles[0], needles[1], needles[2], corpus.as_bytes()), + "search for {:?}|{:?}|{:?} failed in: {:?} \ + (len: {}, alignment: {})", + needles[0] as char, + needles[1] as char, + needles[2] as char, + corpus, + corpus.len(), + align + ); + } + } + + pub fn iter_one<'a, I, F>(&'a self, reverse: bool, f: F) + where + F: FnOnce(u8, &'a [u8]) -> I, + I: Iterator, + { + if let Some(ns) = self.needles(1) { + self.iter(reverse, f(ns[0], self.corpus.as_bytes())); + } + } + + pub fn iter_two<'a, I, F>(&'a self, reverse: bool, f: F) + where + F: FnOnce(u8, u8, &'a [u8]) -> I, + I: Iterator, + { + if let Some(ns) = self.needles(2) { + self.iter(reverse, f(ns[0], ns[1], self.corpus.as_bytes())); + } + } + + pub fn iter_three<'a, I, F>(&'a self, reverse: bool, f: F) + where + F: FnOnce(u8, u8, u8, &'a [u8]) -> I, + I: Iterator, + { + if let Some(ns) = self.needles(3) { + self.iter(reverse, f(ns[0], ns[1], ns[2], self.corpus.as_bytes())); + } + } + + /// Test that the positions yielded by the given iterator match the + /// positions in this test. If reverse is true, then reverse the positions + /// before comparing them. + fn iter>(&self, reverse: bool, it: I) { + assert_eq!( + self.positions(0, reverse), + it.collect::>(), + r"search for {:?} failed in: {:?}", + self.needles.iter().map(|&b| b as char).collect::>(), + self.corpus + ); + } + + /// Expand this test into many variations of the same test. + /// + /// In particular, this will generate more tests with larger corpus sizes. + /// The expected positions are updated to maintain the integrity of the + /// test. + /// + /// This is important in testing a memchr implementation, because there are + /// often different cases depending on the length of the corpus. + /// + /// Note that we extend the corpus by adding `%` bytes, which we + /// don't otherwise use as a needle. + fn expand(&self) -> Vec { + let mut more = Vec::new(); + + // Add bytes to the start of the corpus. + for i in 1..515 { + let mut t = self.clone(); + let mut new_corpus: String = repeat('%').take(i).collect(); + new_corpus.push_str(&t.corpus); + t.corpus = new_corpus; + t.positions = t.positions.into_iter().map(|p| p + i).collect(); + more.push(t); + } + // Add bytes to the end of the corpus. + for i in 1..515 { + let mut t = self.clone(); + let padding: String = repeat('%').take(i).collect(); + t.corpus.push_str(&padding); + more.push(t); + } + + more + } + + /// Return the corpus at the given alignment. + /// + /// If the alignment exceeds the length of the corpus, then this returns + /// an empty slice. + fn corpus(&self, align: usize) -> &str { + self.corpus.get(align..).unwrap_or("") + } + + /// Return exactly `count` needles from this test. If this test has less + /// than `count` needles, then add `#` until the number of needles + /// matches `count`. If this test has more than `count` needles, then + /// return `None` (because there is no way to use this test data for a + /// search using fewer needles). + fn needles(&self, count: usize) -> Option> { + if self.needles.len() > count { + return None; + } + + let mut needles = self.needles.to_vec(); + for _ in needles.len()..count { + // we assume # is never used in tests. + needles.push(b'#'); + } + Some(needles) + } + + /// Return the positions in this test, reversed if `reverse` is true. + /// + /// If alignment is given, then all positions greater than or equal to that + /// alignment are offset by the alignment. Positions less than the + /// alignment are dropped. + fn positions(&self, align: usize, reverse: bool) -> Vec { + let positions = if reverse { + let mut positions = self.positions.to_vec(); + positions.reverse(); + positions + } else { + self.positions.to_vec() + }; + positions + .into_iter() + .filter(|&p| p >= align) + .map(|p| p - align) + .collect() + } +} diff --git a/utshell-0.5.0/vendor/memchr/src/tests/mod.rs b/utshell-0.5.0/vendor/memchr/src/tests/mod.rs new file mode 100644 index 00000000..f4d406cd --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/mod.rs @@ -0,0 +1,15 @@ +mod memchr; + +// For debugging, particularly in CI, print out the byte order of the current +// target. +#[cfg(all(feature = "std", target_endian = "little"))] +#[test] +fn byte_order() { + eprintln!("LITTLE ENDIAN"); +} + +#[cfg(all(feature = "std", target_endian = "big"))] +#[test] +fn byte_order() { + eprintln!("BIG ENDIAN"); +} diff --git a/utshell-0.5.0/vendor/memchr/src/tests/x86_64-soft_float.json b/utshell-0.5.0/vendor/memchr/src/tests/x86_64-soft_float.json new file mode 100644 index 00000000..b77649ef --- /dev/null +++ b/utshell-0.5.0/vendor/memchr/src/tests/x86_64-soft_float.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "arch": "x86_64", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float", + "executables": true, + "disable-redzone": true, + "panic-strategy": "abort" +} diff --git a/utshell-0.5.0/vendor/memoffset/.cargo-checksum.json b/utshell-0.5.0/vendor/memoffset/.cargo-checksum.json new file mode 100644 index 00000000..01e3e71c --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"2556143c764ef2315fe44ff0ec43af47ca70b260fd64aa53f57dc42760d7132d","LICENSE":"3234ac55816264ee7b6c7ee27efd61cf0a1fe775806870e3d9b4c41ea73c5cb1","README.md":"299c8957a769bac2a71f9c63064c58a8b54e613e3bf03d41a889f0b428eb4a9c","build.rs":"6d677e33a1c98d588c97ec7985d4d5c3b954683e0a73c3dc53d79db4fbb5e638","ci/miri.sh":"ad7410b0a5bd6e346f55e9d96ec0719a085a2d1ce266bddfe6fe73333a1eb8ec","src/lib.rs":"e7976d295371a3c1e0cf31b0d50210cd6b1135caba3a5111403a97ec6175c0a2","src/offset_of.rs":"e5e3062947f61418cb48220a0d17604411b5ce651b5945c06b876f26c50220b2","src/raw_field.rs":"295cc971d64e51f3d053e56c692ae6ef3bb58915298f1ec49bb695b767daff46","src/span_of.rs":"03bfb743c2dee2e5fbb9568bcbbe9f24ace3e18488a6924d26812fcb9e3c425a"},"package":"5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/memoffset/Cargo.toml b/utshell-0.5.0/vendor/memoffset/Cargo.toml new file mode 100644 index 00000000..2874e312 --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/Cargo.toml @@ -0,0 +1,29 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +name = "memoffset" +version = "0.6.5" +authors = ["Gilad Naaman "] +description = "offset_of functionality for Rust structs." +readme = "README.md" +keywords = ["mem", "offset", "offset_of", "offsetof"] +categories = ["no-std"] +license = "MIT" +repository = "https://github.com/Gilnaa/memoffset" +[dev-dependencies.doc-comment] +version = "0.3" +[build-dependencies.autocfg] +version = "1" + +[features] +default = [] +unstable_const = [] diff --git a/utshell-0.5.0/vendor/memoffset/LICENSE b/utshell-0.5.0/vendor/memoffset/LICENSE new file mode 100644 index 00000000..61f60813 --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017 Gilad Naaman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/utshell-0.5.0/vendor/memoffset/README.md b/utshell-0.5.0/vendor/memoffset/README.md new file mode 100644 index 00000000..9e93c2bc --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/README.md @@ -0,0 +1,65 @@ +# memoffset # + +[![](https://img.shields.io/crates/v/memoffset.svg)](https://crates.io/crates/memoffset) + +C-Like `offset_of` functionality for Rust structs. + +Introduces the following macros: + * `offset_of!` for obtaining the offset of a member of a struct. + * `offset_of_tuple!` for obtaining the offset of a member of a tuple. (Requires Rust 1.20+) + * `span_of!` for obtaining the range that a field, or fields, span. + +`memoffset` works under `no_std` environments. + +## Usage ## +Add the following dependency to your `Cargo.toml`: + +```toml +[dependencies] +memoffset = "0.6" +``` + +These versions will compile fine with rustc versions greater or equal to 1.19. + +## Examples ## +```rust +use memoffset::{offset_of, span_of}; + +#[repr(C, packed)] +struct Foo { + a: u32, + b: u32, + c: [u8; 5], + d: u32, +} + +fn main() { + assert_eq!(offset_of!(Foo, b), 4); + assert_eq!(offset_of!(Foo, d), 4+4+5); + + assert_eq!(span_of!(Foo, a), 0..4); + assert_eq!(span_of!(Foo, a .. c), 0..8); + assert_eq!(span_of!(Foo, a ..= c), 0..13); + assert_eq!(span_of!(Foo, ..= d), 0..17); + assert_eq!(span_of!(Foo, b ..), 4..17); +} +``` + +## Feature flags ## + +### Usage in constants ### +`memoffset` has **experimental** support for compile-time `offset_of!` on a nightly compiler. + +In order to use it, you must enable the `unstable_const` crate feature and several compiler features. + +Cargo.toml: +```toml +[dependencies.memoffset] +version = "0.6" +features = ["unstable_const"] +``` + +Your crate root: (`lib.rs`/`main.rs`) +```rust,ignore +#![feature(const_ptr_offset_from, const_refs_to_cell)] +``` diff --git a/utshell-0.5.0/vendor/memoffset/build.rs b/utshell-0.5.0/vendor/memoffset/build.rs new file mode 100644 index 00000000..0604c195 --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/build.rs @@ -0,0 +1,22 @@ +extern crate autocfg; + +fn main() { + let ac = autocfg::new(); + + // Check for a minimum version for a few features + if ac.probe_rustc_version(1, 20) { + println!("cargo:rustc-cfg=tuple_ty"); + } + if ac.probe_rustc_version(1, 31) { + println!("cargo:rustc-cfg=allow_clippy"); + } + if ac.probe_rustc_version(1, 36) { + println!("cargo:rustc-cfg=maybe_uninit"); + } + if ac.probe_rustc_version(1, 40) { + println!("cargo:rustc-cfg=doctests"); + } + if ac.probe_rustc_version(1, 51) { + println!("cargo:rustc-cfg=raw_ref_macros"); + } +} diff --git a/utshell-0.5.0/vendor/memoffset/ci/miri.sh b/utshell-0.5.0/vendor/memoffset/ci/miri.sh new file mode 100755 index 00000000..5aea2ecd --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/ci/miri.sh @@ -0,0 +1,14 @@ +set -ex + +# Install Miri. +MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri) +echo "Installing latest nightly with Miri: $MIRI_NIGHTLY" +rustup default "$MIRI_NIGHTLY" +rustup component add miri + +# Run tests. +cargo miri test +cargo miri test --all-features + +# Restore old state in case Travis uses this cache for other jobs. +rustup default nightly diff --git a/utshell-0.5.0/vendor/memoffset/src/lib.rs b/utshell-0.5.0/vendor/memoffset/src/lib.rs new file mode 100644 index 00000000..d80ff174 --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/src/lib.rs @@ -0,0 +1,92 @@ +// Copyright (c) 2017 Gilad Naaman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +//! A crate used for calculating offsets of struct members and their spans. +//! +//! This functionality currently can not be used in compile time code such as `const` or `const fn` definitions. +//! +//! ## Examples +//! ``` +//! use memoffset::{offset_of, span_of}; +//! +//! #[repr(C, packed)] +//! struct HelpMeIAmTrappedInAStructFactory { +//! help_me_before_they_: [u8; 15], +//! a: u32 +//! } +//! +//! fn main() { +//! assert_eq!(offset_of!(HelpMeIAmTrappedInAStructFactory, a), 15); +//! assert_eq!(span_of!(HelpMeIAmTrappedInAStructFactory, a), 15..19); +//! assert_eq!(span_of!(HelpMeIAmTrappedInAStructFactory, help_me_before_they_ .. a), 0..15); +//! } +//! ``` +//! +//! This functionality can be useful, for example, for checksum calculations: +//! +//! ```ignore +//! #[repr(C, packed)] +//! struct Message { +//! header: MessageHeader, +//! fragment_index: u32, +//! fragment_count: u32, +//! payload: [u8; 1024], +//! checksum: u16 +//! } +//! +//! let checksum_range = &raw[span_of!(Message, header..checksum)]; +//! let checksum = crc16(checksum_range); +//! ``` + +#![no_std] +#![cfg_attr( + feature = "unstable_const", + feature(const_ptr_offset_from, const_refs_to_cell) +)] + +#[macro_use] +#[cfg(doctests)] +#[cfg(doctest)] +extern crate doc_comment; +#[cfg(doctests)] +#[cfg(doctest)] +doctest!("../README.md"); + +/// Hidden module for things the macros need to access. +#[doc(hidden)] +pub mod __priv { + #[doc(hidden)] + pub use core::mem; + #[doc(hidden)] + pub use core::ptr; + + /// Use type inference to obtain the size of the pointee (without actually using the pointer). + #[doc(hidden)] + pub fn size_of_pointee(_ptr: *const T) -> usize { + mem::size_of::() + } +} + +#[macro_use] +mod raw_field; +#[macro_use] +mod offset_of; +#[macro_use] +mod span_of; diff --git a/utshell-0.5.0/vendor/memoffset/src/offset_of.rs b/utshell-0.5.0/vendor/memoffset/src/offset_of.rs new file mode 100644 index 00000000..8596e45c --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/src/offset_of.rs @@ -0,0 +1,282 @@ +// Copyright (c) 2017 Gilad Naaman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/// Macro to create a local `base_ptr` raw pointer of the given type, avoiding UB as +/// much as is possible currently. +#[cfg(maybe_uninit)] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__let_base_ptr { + ($name:ident, $type:ty) => { + // No UB here, and the pointer does not dangle, either. + // But we have to make sure that `uninit` lives long enough, + // so it has to be in the same scope as `$name`. That's why + // `let_base_ptr` declares a variable (several, actually) + // instead of returning one. + let uninit = $crate::__priv::mem::MaybeUninit::<$type>::uninit(); + let $name: *const $type = uninit.as_ptr(); + }; +} +#[cfg(not(maybe_uninit))] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__let_base_ptr { + ($name:ident, $type:ty) => { + // No UB right here, but we will later dereference this pointer to + // offset into a field, and that is UB because the pointer is dangling. + let $name = $crate::__priv::mem::align_of::<$type>() as *const $type; + }; +} + +/// Macro to compute the distance between two pointers. +#[cfg(feature = "unstable_const")] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset_offset_from_unsafe { + ($field:expr, $base:expr) => {{ + let field = $field; // evaluate $field outside the `unsafe` block + let base = $base; // evaluate $base outside the `unsafe` block + // Compute offset, with unstable `offset_from` for const-compatibility. + // (Requires the pointers to not dangle, but we already need that for `raw_field!` anyway.) + unsafe { (field as *const u8).offset_from(base as *const u8) as usize } + }}; +} +#[cfg(not(feature = "unstable_const"))] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset_offset_from_unsafe { + ($field:expr, $base:expr) => { + // Compute offset. + ($field as usize) - ($base as usize) + }; +} + +/// Calculates the offset of the specified field from the start of the named struct. +/// +/// ## Examples +/// ``` +/// use memoffset::offset_of; +/// +/// #[repr(C, packed)] +/// struct Foo { +/// a: u32, +/// b: u64, +/// c: [u8; 5] +/// } +/// +/// fn main() { +/// assert_eq!(offset_of!(Foo, a), 0); +/// assert_eq!(offset_of!(Foo, b), 4); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! offset_of { + ($parent:path, $field:tt) => {{ + // Get a base pointer (non-dangling if rustc supports `MaybeUninit`). + _memoffset__let_base_ptr!(base_ptr, $parent); + // Get field pointer. + let field_ptr = raw_field!(base_ptr, $parent, $field); + // Compute offset. + _memoffset_offset_from_unsafe!(field_ptr, base_ptr) + }}; +} + +/// Calculates the offset of the specified field from the start of the tuple. +/// +/// ## Examples +/// ``` +/// use memoffset::offset_of_tuple; +/// +/// fn main() { +/// assert!(offset_of_tuple!((u8, u32), 1) >= 0, "Tuples do not have a defined layout"); +/// } +/// ``` +#[cfg(tuple_ty)] +#[macro_export(local_inner_macros)] +macro_rules! offset_of_tuple { + ($parent:ty, $field:tt) => {{ + // Get a base pointer (non-dangling if rustc supports `MaybeUninit`). + _memoffset__let_base_ptr!(base_ptr, $parent); + // Get field pointer. + let field_ptr = raw_field_tuple!(base_ptr, $parent, $field); + // Compute offset. + _memoffset_offset_from_unsafe!(field_ptr, base_ptr) + }}; +} + +#[cfg(test)] +mod tests { + #[test] + fn offset_simple() { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(offset_of!(Foo, a), 0); + assert_eq!(offset_of!(Foo, b), 4); + assert_eq!(offset_of!(Foo, c), 8); + } + + #[test] + #[cfg_attr(miri, ignore)] // this creates unaligned references + fn offset_simple_packed() { + #[repr(C, packed)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(offset_of!(Foo, a), 0); + assert_eq!(offset_of!(Foo, b), 4); + assert_eq!(offset_of!(Foo, c), 6); + } + + #[test] + fn tuple_struct() { + #[repr(C)] + struct Tup(i32, i32); + + assert_eq!(offset_of!(Tup, 0), 0); + assert_eq!(offset_of!(Tup, 1), 4); + } + + #[test] + fn path() { + mod sub { + #[repr(C)] + pub struct Foo { + pub x: u32, + } + } + + assert_eq!(offset_of!(sub::Foo, x), 0); + } + + #[test] + fn inside_generic_method() { + struct Pair(T, U); + + fn foo(_: Pair) -> usize { + offset_of!(Pair, 1) + } + + assert_eq!(foo(Pair(0, 0)), 4); + } + + #[cfg(tuple_ty)] + #[test] + fn test_tuple_offset() { + let f = (0i32, 0.0f32, 0u8); + let f_ptr = &f as *const _; + let f1_ptr = &f.1 as *const _; + + assert_eq!( + f1_ptr as usize - f_ptr as usize, + offset_of_tuple!((i32, f32, u8), 1) + ); + } + + #[test] + fn test_raw_field() { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + let f: Foo = Foo { + a: 0, + b: [0, 0], + c: 0, + }; + let f_ptr = &f as *const _; + assert_eq!(f_ptr as usize + 0, raw_field!(f_ptr, Foo, a) as usize); + assert_eq!(f_ptr as usize + 4, raw_field!(f_ptr, Foo, b) as usize); + assert_eq!(f_ptr as usize + 8, raw_field!(f_ptr, Foo, c) as usize); + } + + #[cfg(tuple_ty)] + #[test] + fn test_raw_field_tuple() { + let t = (0u32, 0u8, false); + let t_ptr = &t as *const _; + let t_addr = t_ptr as usize; + + assert_eq!( + &t.0 as *const _ as usize - t_addr, + raw_field_tuple!(t_ptr, (u32, u8, bool), 0) as usize - t_addr + ); + assert_eq!( + &t.1 as *const _ as usize - t_addr, + raw_field_tuple!(t_ptr, (u32, u8, bool), 1) as usize - t_addr + ); + assert_eq!( + &t.2 as *const _ as usize - t_addr, + raw_field_tuple!(t_ptr, (u32, u8, bool), 2) as usize - t_addr + ); + } + + #[cfg(feature = "unstable_const")] + #[test] + fn const_offset() { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!([0; offset_of!(Foo, b)].len(), 4); + } + + #[cfg(feature = "unstable_const")] + #[test] + fn const_offset_interior_mutable() { + #[repr(C)] + struct Foo { + a: u32, + b: core::cell::Cell, + } + + assert_eq!([0; offset_of!(Foo, b)].len(), 4); + } + + #[cfg(feature = "unstable_const")] + #[test] + fn const_fn_offset() { + const fn test_fn() -> usize { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + offset_of!(Foo, b) + } + + assert_eq!([0; test_fn()].len(), 4); + } +} diff --git a/utshell-0.5.0/vendor/memoffset/src/raw_field.rs b/utshell-0.5.0/vendor/memoffset/src/raw_field.rs new file mode 100644 index 00000000..a8dd2b35 --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/src/raw_field.rs @@ -0,0 +1,117 @@ +// Copyright (c) 2020 Gilad Naaman, Ralf Jung +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/// `addr_of!`, or just ref-then-cast when that is not available. +#[cfg(raw_ref_macros)] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__addr_of { + ($path:expr) => {{ + $crate::__priv::ptr::addr_of!($path) + }}; +} +#[cfg(not(raw_ref_macros))] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__addr_of { + ($path:expr) => {{ + // This is UB because we create an intermediate reference to uninitialized memory. + // Nothing we can do about that without `addr_of!` though. + &$path as *const _ + }}; +} + +/// Deref-coercion protection macro. +#[cfg(allow_clippy)] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__field_check { + ($type:path, $field:tt) => { + // Make sure the field actually exists. This line ensures that a + // compile-time error is generated if $field is accessed through a + // Deref impl. + #[allow(clippy::unneeded_field_pattern)] + let $type { $field: _, .. }; + }; +} +#[cfg(not(allow_clippy))] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__field_check { + ($type:path, $field:tt) => { + // Make sure the field actually exists. This line ensures that a + // compile-time error is generated if $field is accessed through a + // Deref impl. + let $type { $field: _, .. }; + }; +} + +/// Deref-coercion protection macro. +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__field_check_tuple { + ($type:ty, $field:tt) => { + // Make sure the type argument is a tuple + let (_, ..): $type; + }; +} + +/// Computes a const raw pointer to the given field of the given base pointer +/// to the given parent type. +/// +/// The `base` pointer *must not* be dangling, but it *may* point to +/// uninitialized memory. +#[macro_export(local_inner_macros)] +macro_rules! raw_field { + ($base:expr, $parent:path, $field:tt) => {{ + _memoffset__field_check!($parent, $field); + let base = $base; // evaluate $base outside the `unsafe` block + + // Get the field address. + // Crucially, we know that this will not trigger a deref coercion because + // of the field check we did above. + #[allow(unused_unsafe)] // for when the macro is used in an unsafe block + unsafe { + _memoffset__addr_of!((*(base as *const $parent)).$field) + } + }}; +} + +/// Computes a const raw pointer to the given field of the given base pointer +/// to the given parent tuple typle. +/// +/// The `base` pointer *must not* be dangling, but it *may* point to +/// uninitialized memory. +#[cfg(tuple_ty)] +#[macro_export(local_inner_macros)] +macro_rules! raw_field_tuple { + ($base:expr, $parent:ty, $field:tt) => {{ + _memoffset__field_check_tuple!($parent, $field); + let base = $base; // evaluate $base outside the `unsafe` block + + // Get the field address. + // Crucially, we know that this will not trigger a deref coercion because + // of the field check we did above. + #[allow(unused_unsafe)] // for when the macro is used in an unsafe block + unsafe { + _memoffset__addr_of!((*(base as *const $parent)).$field) + } + }}; +} diff --git a/utshell-0.5.0/vendor/memoffset/src/span_of.rs b/utshell-0.5.0/vendor/memoffset/src/span_of.rs new file mode 100644 index 00000000..aab9d0ac --- /dev/null +++ b/utshell-0.5.0/vendor/memoffset/src/span_of.rs @@ -0,0 +1,256 @@ +// Copyright (c) 2017 Gilad Naaman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/// Reexport for `local_inner_macros`; see +/// . +#[doc(hidden)] +#[macro_export] +macro_rules! _memoffset__compile_error { + ($($inner:tt)*) => { + compile_error! { $($inner)* } + } +} + +/// Produces a range instance representing the sub-slice containing the specified member. +/// +/// This macro provides 2 forms of differing functionalities. +/// +/// The first form is identical to the appearance of the `offset_of!` macro. +/// +/// ```ignore +/// span_of!(Struct, member) +/// ``` +/// +/// The second form of `span_of!` returns a sub-slice which starts at one field, and ends at another. +/// The general pattern of this form is: +/// +/// ```ignore +/// // Exclusive +/// span_of!(Struct, member_a .. member_b) +/// // Inclusive +/// span_of!(Struct, member_a ..= member_b) +/// +/// // Open-ended ranges +/// span_of!(Struct, .. end) +/// span_of!(Struct, start ..) +/// ``` +/// +/// *Note*: +/// This macro uses recursion in order to resolve the range expressions, so there is a limit to +/// the complexity of the expression. +/// In order to raise the limit, the compiler's recursion limit should be lifted. +/// +/// ## Examples +/// ``` +/// use memoffset::span_of; +/// +/// #[repr(C)] +/// struct Florp { +/// a: u32 +/// } +/// +/// #[repr(C)] +/// struct Blarg { +/// x: [u32; 2], +/// y: [u8; 56], +/// z: Florp, +/// egg: [[u8; 4]; 4] +/// } +/// +/// fn main() { +/// assert_eq!(0..84, span_of!(Blarg, ..)); +/// assert_eq!(0..8, span_of!(Blarg, .. y)); +/// assert_eq!(0..64, span_of!(Blarg, ..= y)); +/// assert_eq!(0..8, span_of!(Blarg, x)); +/// assert_eq!(8..84, span_of!(Blarg, y ..)); +/// assert_eq!(0..8, span_of!(Blarg, x .. y)); +/// assert_eq!(0..64, span_of!(Blarg, x ..= y)); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! span_of { + (@helper $root:ident, [] ..=) => { + _memoffset__compile_error!("Expected a range, found '..='") + }; + (@helper $root:ident, [] ..) => { + _memoffset__compile_error!("Expected a range, found '..'") + }; + // No explicit begin for range. + (@helper $root:ident, $parent:path, [] ..) => {{ + ($root as usize, + $root as usize + $crate::__priv::size_of_pointee($root)) + }}; + (@helper $root:ident, $parent:path, [] ..= $end:tt) => {{ + let end = raw_field!($root, $parent, $end); + ($root as usize, end as usize + $crate::__priv::size_of_pointee(end)) + }}; + (@helper $root:ident, $parent:path, [] .. $end:tt) => {{ + ($root as usize, raw_field!($root, $parent, $end) as usize) + }}; + // Explicit begin and end for range. + (@helper $root:ident, $parent:path, # $begin:tt [] ..= $end:tt) => {{ + let begin = raw_field!($root, $parent, $begin); + let end = raw_field!($root, $parent, $end); + (begin as usize, end as usize + $crate::__priv::size_of_pointee(end)) + }}; + (@helper $root:ident, $parent:path, # $begin:tt [] .. $end:tt) => {{ + (raw_field!($root, $parent, $begin) as usize, + raw_field!($root, $parent, $end) as usize) + }}; + // No explicit end for range. + (@helper $root:ident, $parent:path, # $begin:tt [] ..) => {{ + (raw_field!($root, $parent, $begin) as usize, + $root as usize + $crate::__priv::size_of_pointee($root)) + }}; + (@helper $root:ident, $parent:path, # $begin:tt [] ..=) => {{ + _memoffset__compile_error!( + "Found inclusive range to the end of a struct. Did you mean '..' instead of '..='?") + }}; + // Just one field. + (@helper $root:ident, $parent:path, # $field:tt []) => {{ + let field = raw_field!($root, $parent, $field); + (field as usize, field as usize + $crate::__priv::size_of_pointee(field)) + }}; + // Parsing. + (@helper $root:ident, $parent:path, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => {{ + span_of!(@helper $root, $parent, $(#$begin)* #$tt [] $($rest)*) + }}; + (@helper $root:ident, $parent:path, [] $tt:tt $($rest:tt)*) => {{ + span_of!(@helper $root, $parent, #$tt [] $($rest)*) + }}; + + // Entry point. + ($sty:path, $($exp:tt)+) => ({ + // Get a base pointer. + _memoffset__let_base_ptr!(root, $sty); + let base = root as usize; + let (begin, end) = span_of!(@helper root, $sty, [] $($exp)*); + begin-base..end-base + }); +} + +#[cfg(test)] +mod tests { + use core::mem; + + #[test] + fn span_simple() { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(span_of!(Foo, a), 0..4); + assert_eq!(span_of!(Foo, b), 4..6); + assert_eq!(span_of!(Foo, c), 8..8 + 8); + } + + #[test] + #[cfg_attr(miri, ignore)] // this creates unaligned references + fn span_simple_packed() { + #[repr(C, packed)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(span_of!(Foo, a), 0..4); + assert_eq!(span_of!(Foo, b), 4..6); + assert_eq!(span_of!(Foo, c), 6..6 + 8); + } + + #[test] + fn span_forms() { + #[repr(C)] + struct Florp { + a: u32, + } + + #[repr(C)] + struct Blarg { + x: u64, + y: [u8; 56], + z: Florp, + egg: [[u8; 4]; 5], + } + + // Love me some brute force + assert_eq!(0..8, span_of!(Blarg, x)); + assert_eq!(64..68, span_of!(Blarg, z)); + assert_eq!(68..mem::size_of::(), span_of!(Blarg, egg)); + + assert_eq!(8..64, span_of!(Blarg, y..z)); + assert_eq!(0..64, span_of!(Blarg, x..=y)); + } + + #[test] + fn ig_test() { + #[repr(C)] + struct Member { + foo: u32, + } + + #[repr(C)] + struct Test { + x: u64, + y: [u8; 56], + z: Member, + egg: [[u8; 4]; 4], + } + + assert_eq!(span_of!(Test, ..x), 0..0); + assert_eq!(span_of!(Test, ..=x), 0..8); + assert_eq!(span_of!(Test, ..y), 0..8); + assert_eq!(span_of!(Test, ..=y), 0..64); + assert_eq!(span_of!(Test, ..z), 0..64); + assert_eq!(span_of!(Test, ..=z), 0..68); + assert_eq!(span_of!(Test, ..egg), 0..68); + assert_eq!(span_of!(Test, ..=egg), 0..84); + assert_eq!(span_of!(Test, ..), 0..mem::size_of::()); + assert_eq!( + span_of!(Test, x..), + offset_of!(Test, x)..mem::size_of::() + ); + assert_eq!( + span_of!(Test, y..), + offset_of!(Test, y)..mem::size_of::() + ); + + assert_eq!( + span_of!(Test, z..), + offset_of!(Test, z)..mem::size_of::() + ); + assert_eq!( + span_of!(Test, egg..), + offset_of!(Test, egg)..mem::size_of::() + ); + assert_eq!( + span_of!(Test, x..y), + offset_of!(Test, x)..offset_of!(Test, y) + ); + assert_eq!( + span_of!(Test, x..=y), + offset_of!(Test, x)..offset_of!(Test, y) + mem::size_of::<[u8; 56]>() + ); + } +} diff --git a/utshell-0.5.0/vendor/nix/.cargo-checksum.json b/utshell-0.5.0/vendor/nix/.cargo-checksum.json new file mode 100644 index 00000000..d0d5906e --- /dev/null +++ b/utshell-0.5.0/vendor/nix/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"b11b7bc8ef50b261f8f6de922591212436d8d7c40746c2e6984df3885a91629e","Cargo.toml":"f8cd7e0bd5c43f7f55ef56cdcda2916ffeb5db7497b49bb73d1516b2c84e9ebc","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"0bbe5a44884e8315d018df67c691cb57d059a30c3f3dd221beb3eee56cb5cf1f","src/dir.rs":"dd5f9ee16c5daad44700fb7e3b8b09a32006f3efc394a51fec97aa3e9a8b316e","src/env.rs":"028bc5e20139ebba418a655a2978a53335dc7680bf1de43d2c8333dd72cfa5c4","src/errno.rs":"190812028a266c587ad54bf942bd821af8d796e9399276c7fd7c93f0d52793ae","src/fcntl.rs":"ea8f43d8fec0b6c3b7d903333e4c1ce85611684a4afd561c55cfe4b61a979e94","src/features.rs":"1e1e0247662466f6998d3a405c8742ce807fce3a27823575bd235e771c2392ac","src/ifaddrs.rs":"9500e10bed93ca6e376c3877b448b42c51ed27d1d67693e819bfb175fa768012","src/kmod.rs":"9031edb7b0a8ed1d6635163c9c32490537d5c204e9794cce9dc2db24ead60957","src/lib.rs":"1384fe677c3a53b48b3d4c41a91ade3611b2751cdd35a0712b3237d20be393fe","src/macros.rs":"e23d7d8be22ef0bf9febaaf2739585453103607c0139bd3995a324e4a16d011e","src/mount/bsd.rs":"114878b4f2ad712236965fc3ed227d37ea56f57156266709b526002c5b65aa6e","src/mount/linux.rs":"d938612abe89d2cf0d375b335a570ba4831f2009d3ef6c7e786ccbc398bf2c15","src/mount/mod.rs":"5c9d906d4760ac1a3767949e2cab69d7fa683c454c06045919c58a90689d439f","src/mqueue.rs":"8e227acb520020b06338bceb8e7e11705564e5f4d96ab51e0815dcadc01a8b4e","src/net/if_.rs":"74dcfa81b1b77303cd8047ca4e2ab60b8fcebaa4a01dc860dd0fec65ab334eb4","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"cae2182481438f27e14e4c1a88e1835ff371423c0cc8f685ffb0b479dd102e2e","src/pty.rs":"e94219e1981cb023d4f3c22edbe26c87f7508fa25b96b9f74b3b36436aebe2fb","src/sched.rs":"22ba33ee394ef23fbde7d1fca1f2f24fc487dd447b7c28d82c9165a0822b2894","src/sys/aio.rs":"9181e01eeef5ff6f89dec1eca58ba814a80df72736b955cd1b92278d5c79bea6","src/sys/epoll.rs":"6d9bcd668010ba26abb9c5ede9f3e238a56ce4949a5c51ee80853fc8e3c37607","src/sys/event.rs":"d69b7b86bed60d7bf609c636545a5d92f7f9ece7fd69db0e662f6d7e57f3237c","src/sys/eventfd.rs":"bc8009f19e8b93b03d0202896e10bd08497f34e2987bb8ce864d6cde11eab892","src/sys/inotify.rs":"215c4217f698b47f73f4418f98f331f06ca93d35e01c6f522e5fa6a156554174","src/sys/ioctl/bsd.rs":"bbd02e30b0a78c1cb22777d9b00cfcbba9c68505cffc06118ac68474cf6fea39","src/sys/ioctl/linux.rs":"028181834d119b834bf399f2b8a6176cc57e75144693f28f32059d087d8c8018","src/sys/ioctl/mod.rs":"89b20579476b2e0254e0ecb1b41830cccd7027a22cbdb816a9d4ec3924842ac1","src/sys/memfd.rs":"72a153df4da17ea0cc4ce90ee3c47c5bec24c6e32fbb4ee7c77c1a89d79efbdd","src/sys/mman.rs":"cf4970c2ec4eb668926267679bfb7b41e653190f719d7bd1ef768623e53117a3","src/sys/mod.rs":"1be43a6d0d40661851f222b305841555897168b7e75bd9bc9c7f1962bba93369","src/sys/personality.rs":"99677190a5a81e07fc2c5c2e4b9abacf0fd555776dd0eb266fa86b8f9e965dbf","src/sys/pthread.rs":"258cdf7ff0b61a4afa6d228109e4cb4fb88d859bb8dfe6c959d95130fb010906","src/sys/ptrace/bsd.rs":"ca948c863fa55de1f9fc8eabd9fd7803054df08a6ee5044b2a6a7de49a321819","src/sys/ptrace/linux.rs":"ca780ecf61416252e45dd10b5ffa6120c65b22ec4362d4f2fbd554a9bcaf1084","src/sys/ptrace/mod.rs":"671a6ccac955e75d5998f7e53ffc45ed4c7b6522a0f24a0937d60141f692dd39","src/sys/quota.rs":"d3127892f419939d63f75b9326d50e0866f7bdd92c9dcbd1cb3b6890a13b016c","src/sys/reboot.rs":"dbb1faeeb6525f1952a20cb75adbd76b0681b6214501f747cc154be2bbff7594","src/sys/resource.rs":"ee83c0a39e600c496e62592b65f8ca67c761ff9f00f30bb4bfd5cd5897281dad","src/sys/select.rs":"d30e8dfcfa46f6bd8d8b86676ad09d7aa6f1d7747d2c9601b9bb4f5ccf44b59f","src/sys/sendfile.rs":"637b09a267813c6adf72b6b74235175ed5347e3816777881ba8a9ab192c3e497","src/sys/signal.rs":"485c85a0d24a20ecf13c1d35ed740ee40498d9067cb3c0228f63323f89ba4de5","src/sys/signalfd.rs":"309eb1be7d72e8391acb5ba82b07cd6cf6fb26ddb3af914373f8889add6f52dd","src/sys/socket/addr.rs":"bda779dcb72777282a0d80ac53b7bbac49b4d3aa24c6af71c182522744b1424a","src/sys/socket/mod.rs":"0338e7922696da25e3fb3bdf487ba7ed44b0fcef382c2cccd5cf39d38046786e","src/sys/socket/sockopt.rs":"2c0ccd6aa1eb5d06057813f5098ff8541a4001eb634a5f3db888d8d4d802cd5e","src/sys/stat.rs":"a7b30aa54033579aea16af4c904b3935c3816a72615537178ad6366b6c8cb381","src/sys/statfs.rs":"4cb48cbfe45b74f706bdf85e9b4e8a8dc1c1ac36d8ff77d6fc065dc8de7da9f5","src/sys/statvfs.rs":"1e17f417675722690354e03184de9b9bfc1ba4367d2dc5446952ed71f67a0270","src/sys/sysinfo.rs":"b4519b1ca091c9dbe94d2a6fd6304944bf3df5626973d2c6884022559706f0d9","src/sys/termios.rs":"484bb987e35064e4483c0cd3074400e1635b793e4aa50c14eaed4baafed4fefc","src/sys/time.rs":"4ccd06e22757a52b25d407d7a58faca8e686871f13c637f665e8ea5b1ae05d8f","src/sys/timer.rs":"5bf5068e3fe0050e7b79ed674569682c57f77bd24581ea7c7d58747989343c37","src/sys/timerfd.rs":"ee960c8475d26f01edbbeebcc8e5104a91d028d95aeec1de9d73f3f779130bb8","src/sys/uio.rs":"5824d6167065f8d5db552d1a5f86ef08ef661cd278b7d636baafc0b62d752ad4","src/sys/utsname.rs":"7f1c75dd550c9637a023a4629df571bcd292d53feee7b18f9f80dce425e65bea","src/sys/wait.rs":"5b21039400633d85aa49e153cc927cbf32d05df33c1d6a365921af2432b9495d","src/time.rs":"63ae33f73c79a70c811f87af2edd34e21ce93a3f89b3f176e35065fa1ece3ad7","src/ucontext.rs":"863d783443be1307477daf1970a42594d17d637aba94c8e5b63d5d9a49ea624b","src/unistd.rs":"02b107acc17e4078675dc330866abbe1395a257ef082803816d2e589248af267","test/common/mod.rs":"1d7e28e3635754664cd056f3a1079232ff5c118df619e1d0551a9972eb0b3cd6","test/sys/mod.rs":"87b2891d83067ff21f72b8ff7fde3019dc45b6877282ac278b6da151de45c7a7","test/sys/test_aio.rs":"d2d9e9eb67a1075e43321413666a47195a03b84adf4faf235785e5d0b9158d50","test/sys/test_aio_drop.rs":"614070155fa16a979b7341d001639c5ce24a1d6f632c3abce45a5a6d49c4039b","test/sys/test_epoll.rs":"ffe95e36c79e37426ef8e8ca3b137b7f35ea0333ce666a20a4b7878db17680e9","test/sys/test_inotify.rs":"a141b9a995892547b51ceeb6761a70a6b86d37e8f38d13ea2c497b81b4b0f49f","test/sys/test_ioctl.rs":"00ccc5afb665e533a0a4b6d6a6be438bcaea19fce335390feef4e91d17b3036c","test/sys/test_mman.rs":"f66da7990aea0b61f6e1c006fcd31389a42fa2f0ce6fdb7b02dfe314a533e32d","test/sys/test_pthread.rs":"ace36a2f5587f1874854281b4fd84e4e4d892a1e3c5cc38ced57975739522ad6","test/sys/test_ptrace.rs":"0385eebc8b1b8c72f655b745769decd9143ad83018198375982da0896310456b","test/sys/test_select.rs":"54cea1c34ad28d5770a613c1c3cbc3b1064b22037ec2b9d3fcd422d3be9e60a7","test/sys/test_signal.rs":"acc9941227bd3e2afad323613c2b8c83902ed0486d3745fd72704f395924f1e4","test/sys/test_signalfd.rs":"0e1060143e2612c490bc3d0168d0bbb042ef55e3f1d91d2578b9e42e4310a14d","test/sys/test_socket.rs":"9e86d4c15f256154f2626e663163ce823645f2934dc97edd6fc99a5f1df9164f","test/sys/test_sockopt.rs":"4cd62c722ff39624cadf4abb03c47bdd8f5f471d5d410022057966e6fa29321f","test/sys/test_stat.rs":"6630a28217fd708bb84cd4f7e7101836b74f2420f9888923fdab664ccc331c1d","test/sys/test_sysinfo.rs":"ffd49bc96375914a2c4a4a59730cae8072f85771e2c4a80d3403df38d967e272","test/sys/test_termios.rs":"e5bcef10c84bd7583d600d5601835bcb3cfc88781cb283ab0185bbef5faf4327","test/sys/test_timerfd.rs":"cfed3abf58118611d08f6985251a7739cff67108e11214222a1d2394a3a026ce","test/sys/test_uio.rs":"32656bd0a5699e4d019aa928edf104637937179782914a82d50d37226e84c421","test/sys/test_wait.rs":"6fd59fffeeb09ff620c359baefd062ba777598982b6cb001ccc07b6bc7605493","test/test.rs":"9f43d5001eefe1fe85ce20c4dab24474296a76d127dc25b39b4d8bd8798be45c","test/test_clearenv.rs":"45ca548035b3c20ec87314715feaba2be973709a635d85b8cde46fd1d9f1ecd4","test/test_dir.rs":"ae3c11c58cb06da6557aa2a839c6653c54cd7724283fffe9df5a5d3feabdd89a","test/test_fcntl.rs":"75febe19a7fb19063db75b012fc17feb264a8796569d9cc18c313da2c2cce806","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"b4ae25841c2f06f32de9f1acd8230eeccd7095721302ebe78ad454e4e4f9c783","test/test_mount.rs":"6dd242b6e23c9c39e1a75612bbea62573898818ab374c3c032c2cdb97033554d","test/test_mq.rs":"136071f24131aac0e65d5f29ac18e3806641dfae1164813f5570c0e3a6f70553","test/test_net.rs":"f2912327ebb2a3d37e6cff02a5ac3106cf889cc5c74404db4ef0034059ba26f1","test/test_nix_path.rs":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","test/test_nmount.rs":"d6c112547bb80968170b5497cda4b6cbf69dabec6f51d494bd52298995ceff18","test/test_poll.rs":"3e0b8f0397ba080785c61a3bfc3d637bc87f324bc4e52b5f1bf3ca0d32dbc9fe","test/test_pty.rs":"b26238a0783746cb31880e11eebc1913149be999ce75fbc2d6677bdd1e2731b2","test/test_ptymaster_drop.rs":"ae63c815f5028ddc67d194e86559483018ab1816316bdb917f40cee9364fd8a5","test/test_resource.rs":"40aef790ab745cec31a4b333d2ca406b462aa9bdf4a6d3756371e498b8d51e9a","test/test_sched.rs":"d2c8065cbec77d25230f03683dfde99828c0fa463969a5a8f50ebf913091d6bc","test/test_sendfile.rs":"bb41b4f3621b518e397d3a5b5ad3c5dcef3fe506afe516eab7572fbab92b77e3","test/test_stat.rs":"c407ca47a5258750076d041afad2f6add4c3563be36628bde1c5b314f5d0765d","test/test_time.rs":"f7a21b1e279e60e84909d5dadda97ded66d3326b131fe317badf9af0a1b50335","test/test_timer.rs":"3ae20d364f075d2811f3ff94eda9886682cc21d8807656007d2464fe36d1e361","test/test_unistd.rs":"214d5edf633685b7911d103d86d7e0325a9e448f3a27b56f50c7714eddb5e547"},"package":"f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/nix/CHANGELOG.md b/utshell-0.5.0/vendor/nix/CHANGELOG.md new file mode 100644 index 00000000..a4a1c41b --- /dev/null +++ b/utshell-0.5.0/vendor/nix/CHANGELOG.md @@ -0,0 +1,1442 @@ +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](https://semver.org/). + +## [0.25.1] - 2022-12-02 +### Added + +- Added `SockaddrStorage::{as_unix_addr, as_unix_addr_mut}` + ([#1871](https://github.com/nix-rust/nix/pull/1871)) + +### Changed + +### Fixed + +- Workaround XNU bug causing netmasks returned by `getifaddrs` to misbehave. + ([#1788](https://github.com/nix-rust/nix/pull/1788)) +- Fix microsecond calculation for `TimeSpec`. + ([#1801](https://github.com/nix-rust/nix/pull/1801)) +- Fix `User::from_name` and `Group::from_name` panicking + when given a name containing a nul. + ([#1815](https://github.com/nix-rust/nix/pull/1815)) +- Fix `User::from_uid` and `User::from_name` crash on Android platform. + ([#1824](https://github.com/nix-rust/nix/pull/1824)) +- Fixed using `SockaddrStorage` to store a Unix-domain socket address on Linux. + ([#1871](https://github.com/nix-rust/nix/pull/1871)) +- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`. + ([#1821](https://github.com/nix-rust/nix/pull/1821)) + +### Removed + +## [0.25.0] - 2022-08-13 +### Added + +- Added `faccessat` + ([#1780](https://github.com/nix-rust/nix/pull/1780)) +- Added `memfd` on Android. + (#[1773](https://github.com/nix-rust/nix/pull/1773)) +- Added `ETH_P_ALL` to `SockProtocol` enum + (#[1768](https://github.com/nix-rust/nix/pull/1768)) +- Added four non-standard Linux `SysconfVar` variants + (#[1761](https://github.com/nix-rust/nix/pull/1761)) +- Added const constructors for `TimeSpec` and `TimeVal` + (#[1760](https://github.com/nix-rust/nix/pull/1760)) +- Added `chflags`. + (#[1758](https://github.com/nix-rust/nix/pull/1758)) +- Added `aio_writev` and `aio_readv`. + (#[1713](https://github.com/nix-rust/nix/pull/1713)) +- impl `From` for `Uid` and `From` for `Gid` + (#[1727](https://github.com/nix-rust/nix/pull/1727)) +- impl `From` for `std::net::SocketAddrV4` and + impl `From` for `std::net::SocketAddrV6`. + (#[1711](https://github.com/nix-rust/nix/pull/1711)) +- Added support for the `x86_64-unknown-haiku` target. + (#[1703](https://github.com/nix-rust/nix/pull/1703)) +- Added `ptrace::read_user` and `ptrace::write_user` for Linux. + (#[1697](https://github.com/nix-rust/nix/pull/1697)) +- Added `getrusage` and helper types `UsageWho` and `Usage` + (#[1747](https://github.com/nix-rust/nix/pull/1747)) +- Added the `DontRoute` SockOpt + (#[1752](https://github.com/nix-rust/nix/pull/1752)) +- Added `signal::SigSet::from_sigset_t_unchecked()`. + (#[1741](https://github.com/nix-rust/nix/pull/1741)) +- Added the `Ipv4OrigDstAddr` sockopt and control message. + (#[1772](https://github.com/nix-rust/nix/pull/1772)) +- Added the `Ipv6OrigDstAddr` sockopt and control message. + (#[1772](https://github.com/nix-rust/nix/pull/1772)) +- Added the `Ipv4SendSrcAddr` control message. + (#[1776](https://github.com/nix-rust/nix/pull/1776)) + +### Changed + +- Rewrote the aio module. The new module: + * Does more type checking at compile time rather than runtime. + * Gives the caller control over whether and when to `Box` an aio operation. + * Changes the type of the `priority` arguments to `i32`. + * Changes the return type of `aio_return` to `usize`. + (#[1713](https://github.com/nix-rust/nix/pull/1713)) +- `nix::poll::ppoll`: `sigmask` parameter is now optional. + (#[1739](https://github.com/nix-rust/nix/pull/1739)) +- Changed `gethostname` to return an owned `OsString`. + (#[1745](https://github.com/nix-rust/nix/pull/1745)) +- `signal:SigSet` is now marked as `repr(transparent)`. + (#[1741](https://github.com/nix-rust/nix/pull/1741)) + +### Removed + +- Removed support for resubmitting partially complete `lio_listio` operations. + It was too complicated, and didn't fit Nix's theme of zero-cost abstractions. + Instead, it can be reimplemented downstream. + (#[1713](https://github.com/nix-rust/nix/pull/1713)) + +## [0.24.2] - 2022-07-17 +### Fixed + +- Fixed buffer overflow in `nix::sys::socket::recvfrom`. + (#[1763](https://github.com/nix-rust/nix/pull/1763)) +- Enabled `SockaddrStorage::{as_link_addr, as_link_addr_mut}` for Linux-like + operating systems. + (#[1729](https://github.com/nix-rust/nix/pull/1729)) +- Fixed `SockaddrLike::from_raw` implementations for `VsockAddr` and + `SysControlAddr`. + (#[1736](https://github.com/nix-rust/nix/pull/1736)) + +## [0.24.1] - 2022-04-22 +### Fixed + +- Fixed `UnixAddr::size` on Linux-based OSes. + (#[1702](https://github.com/nix-rust/nix/pull/1702)) + +## [0.24.0] - 2022-04-21 +### Added + +- Added fine-grained features flags. Most Nix functionality can now be + conditionally enabled. By default, all features are enabled. + (#[1611](https://github.com/nix-rust/nix/pull/1611)) +- Added statfs FS type magic constants for `target_os = "android"` + and synced constants with libc v0.2.121. + (#[1690](https://github.com/nix-rust/nix/pull/1690)) +- Added `fexecve` on DragonFly. + (#[1577](https://github.com/nix-rust/nix/pull/1577)) +- `sys::uio::IoVec` is now `Send` and `Sync` + (#[1582](https://github.com/nix-rust/nix/pull/1582)) +- Added `EPOLLEXCLUSIVE` on Android. + (#[1567](https://github.com/nix-rust/nix/pull/1567)) +- Added `fdatasync` for FreeBSD, Fuchsia, NetBSD, and OpenBSD. + (#[1581](https://github.com/nix-rust/nix/pull/1581)) +- Added `sched_setaffinity` and `sched_getaffinity` on DragonFly. + (#[1537](https://github.com/nix-rust/nix/pull/1537)) +- Added `posix_fallocate` on DragonFly. + (#[1621](https://github.com/nix-rust/nix/pull/1621)) +- Added `SO_TIMESTAMPING` support + (#[1547](https://github.com/nix-rust/nix/pull/1547)) +- Added getter methods to `MqAttr` struct + (#[1619](https://github.com/nix-rust/nix/pull/1619)) +- Added the `TxTime` sockopt and control message. + (#[1564](https://github.com/nix-rust/nix/pull/1564)) +- Added POSIX per-process timer support + (#[1622](https://github.com/nix-rust/nix/pull/1622)) +- Added `sendfile` on DragonFly. + (#[1615](https://github.com/nix-rust/nix/pull/1615)) +- Added `UMOUNT_NOFOLLOW`, `FUSE_SUPER_MAGIC` on Linux. + (#[1634](https://github.com/nix-rust/nix/pull/1634)) +- Added `getresuid`, `setresuid`, `getresgid`, and `setresgid` on DragonFly, FreeBSD, and OpenBSD. + (#[1628](https://github.com/nix-rust/nix/pull/1628)) +- Added `MAP_FIXED_NOREPLACE` on Linux. + (#[1636](https://github.com/nix-rust/nix/pull/1636)) +- Added `fspacectl` on FreeBSD + (#[1640](https://github.com/nix-rust/nix/pull/1640)) +- Added `accept4` on DragonFly, Emscripten, Fuchsia, Illumos, and NetBSD. + (#[1654](https://github.com/nix-rust/nix/pull/1654)) +- Added `AsRawFd` implementation on `OwningIter`. + (#[1563](https://github.com/nix-rust/nix/pull/1563)) +- Added `process_vm_readv` and `process_vm_writev` on Android. + (#[1557](https://github.com/nix-rust/nix/pull/1557)) +- Added `nix::uncontext` module on s390x. + (#[1662](https://github.com/nix-rust/nix/pull/1662)) +- Implemented `Extend`, `FromIterator`, and `IntoIterator` for `SigSet` and + added `SigSet::iter` and `SigSetIter`. + (#[1553](https://github.com/nix-rust/nix/pull/1553)) +- Added `ENOTRECOVERABLE` and `EOWNERDEAD` error codes on DragonFly. + (#[1665](https://github.com/nix-rust/nix/pull/1665)) +- Implemented `Read` and `Write` for `&PtyMaster` + (#[1664](https://github.com/nix-rust/nix/pull/1664)) +- Added `MSG_NOSIGNAL` for Android, Dragonfly, FreeBSD, Fuchsia, Haiku, Illumos, Linux, NetBSD, OpenBSD and Solaris. + (#[1670](https://github.com/nix-rust/nix/pull/1670)) +- Added `waitid`. + (#[1584](https://github.com/nix-rust/nix/pull/1584)) +- Added `Ipv6DontFrag` for android, iOS, linux and macOS. +- Added `IpDontFrag` for iOS, macOS. + (#[1692](https://github.com/nix-rust/nix/pull/1692)) + +### Changed + +- `mqueue` functions now operate on a distinct type, `nix::mqueue::MqdT`. + Accessors take this type by reference, not by value. + (#[1639](https://github.com/nix-rust/nix/pull/1639)) +- Removed `SigSet::extend` in favor of `>::extend`. + Because of this change, you now need `use std::iter::Extend` to call `extend` + on a `SigSet`. + (#[1553](https://github.com/nix-rust/nix/pull/1553)) +- Removed the the `PATH_MAX` restriction from APIs accepting paths. Paths + will now be allocated on the heap if they are too long. In addition, large + instruction count improvements (~30x) were made to path handling. + (#[1656](https://github.com/nix-rust/nix/pull/1656)) +- Changed `getrlimit` and `setrlimit` to use `rlim_t` directly + instead of `Option`. + (#[1668](https://github.com/nix-rust/nix/pull/1668)) +- Deprecated `InetAddr` and `SockAddr` in favor of `SockaddrIn`, `SockaddrIn6`, + and `SockaddrStorage`. + (#[1684](https://github.com/nix-rust/nix/pull/1684)) +- Deprecated `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` in favor of their equivalents + from the standard library. + (#[1685](https://github.com/nix-rust/nix/pull/1685)) +- `uname` now returns a `Result` instead of just a `UtsName` and + ignoring failures from libc. And getters on the `UtsName` struct now return + an `&OsStr` instead of `&str`. + (#[1672](https://github.com/nix-rust/nix/pull/1672)) +- Replaced `IoVec` with `IoSlice` and `IoSliceMut`, and replaced `IoVec::from_slice` with + `IoSlice::new`. (#[1643](https://github.com/nix-rust/nix/pull/1643)) + +### Fixed + +- `InetAddr::from_std` now sets the `sin_len`/`sin6_len` fields on the BSDs. + (#[1642](https://github.com/nix-rust/nix/pull/1642)) +- Fixed a panic in `LinkAddr::addr`. That function now returns an `Option`. + (#[1675](https://github.com/nix-rust/nix/pull/1675)) + (#[1677](https://github.com/nix-rust/nix/pull/1677)) + +### Removed + +- Removed public access to the inner fields of `NetlinkAddr`, `AlgAddr`, + `SysControlAddr`, `LinkAddr`, and `VsockAddr`. + (#[1614](https://github.com/nix-rust/nix/pull/1614)) +- Removed `EventFlag::EV_SYSFLAG`. + (#[1635](https://github.com/nix-rust/nix/pull/1635)) + +## [0.23.1] - 2021-12-16 + +### Changed + +- Relaxed the bitflags requirement from 1.3.1 to 1.1. This partially reverts + #1492. From now on, the MSRV is not guaranteed to work with all versions of + all dependencies, just with some version of all dependencies. + (#[1607](https://github.com/nix-rust/nix/pull/1607)) + +### Fixed + +- Fixed soundness issues in `FdSet::insert`, `FdSet::remove`, and + `FdSet::contains` involving file descriptors outside of the range + `0..FD_SETSIZE`. + (#[1575](https://github.com/nix-rust/nix/pull/1575)) + +## [0.23.0] - 2021-09-28 +### Added + +- Added the `LocalPeerCred` sockopt. + (#[1482](https://github.com/nix-rust/nix/pull/1482)) +- Added `TimeSpec::from_duration` and `TimeSpec::from_timespec` + (#[1465](https://github.com/nix-rust/nix/pull/1465)) +- Added `IPV6_V6ONLY` sockopt. + (#[1470](https://github.com/nix-rust/nix/pull/1470)) +- Added `impl From for libc::passwd` trait implementation to convert a `User` + into a `libc::passwd`. Consumes the `User` struct to give ownership over + the member pointers. + (#[1471](https://github.com/nix-rust/nix/pull/1471)) +- Added `pthread_kill`. + (#[1472](https://github.com/nix-rust/nix/pull/1472)) +- Added `mknodat`. + (#[1473](https://github.com/nix-rust/nix/pull/1473)) +- Added `setrlimit` and `getrlimit`. + (#[1302](https://github.com/nix-rust/nix/pull/1302)) +- Added `ptrace::interrupt` method for platforms that support `PTRACE_INTERRUPT` + (#[1422](https://github.com/nix-rust/nix/pull/1422)) +- Added `IP6T_SO_ORIGINAL_DST` sockopt. + (#[1490](https://github.com/nix-rust/nix/pull/1490)) +- Added the `PTRACE_EVENT_STOP` variant to the `sys::ptrace::Event` enum + (#[1335](https://github.com/nix-rust/nix/pull/1335)) +- Exposed `SockAddr::from_raw_sockaddr` + (#[1447](https://github.com/nix-rust/nix/pull/1447)) +- Added `TcpRepair` + (#[1503](https://github.com/nix-rust/nix/pull/1503)) +- Enabled `pwritev` and `preadv` for more operating systems. + (#[1511](https://github.com/nix-rust/nix/pull/1511)) +- Added support for `TCP_MAXSEG` TCP Maximum Segment Size socket options + (#[1292](https://github.com/nix-rust/nix/pull/1292)) +- Added `Ipv4RecvErr` and `Ipv6RecvErr` sockopts and associated control messages. + (#[1514](https://github.com/nix-rust/nix/pull/1514)) +- Added `AsRawFd` implementation on `PollFd`. + (#[1516](https://github.com/nix-rust/nix/pull/1516)) +- Added `Ipv4Ttl` and `Ipv6Ttl` sockopts. + (#[1515](https://github.com/nix-rust/nix/pull/1515)) +- Added `MAP_EXCL`, `MAP_ALIGNED_SUPER`, and `MAP_CONCEAL` mmap flags, and + exposed `MAP_ANONYMOUS` for all operating systems. + (#[1522](https://github.com/nix-rust/nix/pull/1522)) + (#[1525](https://github.com/nix-rust/nix/pull/1525)) + (#[1531](https://github.com/nix-rust/nix/pull/1531)) + (#[1534](https://github.com/nix-rust/nix/pull/1534)) +- Added read/write accessors for 'events' on `PollFd`. + (#[1517](https://github.com/nix-rust/nix/pull/1517)) + +### Changed + +- `FdSet::{contains, highest, fds}` no longer require a mutable reference. + (#[1464](https://github.com/nix-rust/nix/pull/1464)) +- `User::gecos` and corresponding `libc::passwd::pw_gecos` are supported on + 64-bit Android, change conditional compilation to include the field in + 64-bit Android builds + (#[1471](https://github.com/nix-rust/nix/pull/1471)) +- `eventfd`s are supported on Android, change conditional compilation to + include `sys::eventfd::eventfd` and `sys::eventfd::EfdFlags`for Android + builds. + (#[1481](https://github.com/nix-rust/nix/pull/1481)) +- Most enums that come from C, for example `Errno`, are now marked as + `#[non_exhaustive]`. + (#[1474](https://github.com/nix-rust/nix/pull/1474)) +- Many more functions, mostly contructors, are now `const`. + (#[1476](https://github.com/nix-rust/nix/pull/1476)) + (#[1492](https://github.com/nix-rust/nix/pull/1492)) +- `sys::event::KEvent::filter` now returns a `Result` instead of being + infalliable. The only cases where it will now return an error are cases + where it previously would've had undefined behavior. + (#[1484](https://github.com/nix-rust/nix/pull/1484)) +- Minimum supported Rust version is now 1.46.0. + ([#1492](https://github.com/nix-rust/nix/pull/1492)) +- Rework `UnixAddr` to encapsulate internals better in order to fix soundness + issues. No longer allows creating a `UnixAddr` from a raw `sockaddr_un`. + ([#1496](https://github.com/nix-rust/nix/pull/1496)) +- Raised bitflags to 1.3.0 and the MSRV to 1.46.0. + ([#1492](https://github.com/nix-rust/nix/pull/1492)) + +### Fixed + +- `posix_fadvise` now returns errors in the conventional way, rather than as a + non-zero value in `Ok()`. + (#[1538](https://github.com/nix-rust/nix/pull/1538)) +- Added more errno definitions for better backwards compatibility with + Nix 0.21.0. + (#[1467](https://github.com/nix-rust/nix/pull/1467)) +- Fixed potential undefined behavior in `Signal::try_from` on some platforms. + (#[1484](https://github.com/nix-rust/nix/pull/1484)) +- Fixed buffer overflow in `unistd::getgrouplist`. + (#[1545](https://github.com/nix-rust/nix/pull/1545)) + + +### Removed + +- Removed a couple of termios constants on redox that were never actually + supported. + (#[1483](https://github.com/nix-rust/nix/pull/1483)) +- Removed `nix::sys::signal::NSIG`. It was of dubious utility, and not correct + for all platforms. + (#[1484](https://github.com/nix-rust/nix/pull/1484)) +- Removed support for 32-bit Apple targets, since they've been dropped by both + Rustc and Xcode. + (#[1492](https://github.com/nix-rust/nix/pull/1492)) +- Deprecated `SockAddr/InetAddr::to_str` in favor of `ToString::to_string` + (#[1495](https://github.com/nix-rust/nix/pull/1495)) +- Removed `SigevNotify` on OpenBSD and Redox. + (#[1511](https://github.com/nix-rust/nix/pull/1511)) + +## [0.22.0] - 9 July 2021 +### Added +- Added `if_nameindex` (#[1445](https://github.com/nix-rust/nix/pull/1445)) +- Added `nmount` for FreeBSD. + (#[1453](https://github.com/nix-rust/nix/pull/1453)) +- Added `IpFreebind` socket option (sockopt) on Linux, Fuchsia and Android. + (#[1456](https://github.com/nix-rust/nix/pull/1456)) +- Added `TcpUserTimeout` socket option (sockopt) on Linux and Fuchsia. + (#[1457](https://github.com/nix-rust/nix/pull/1457)) +- Added `renameat2` for Linux + (#[1458](https://github.com/nix-rust/nix/pull/1458)) +- Added `RxqOvfl` support on Linux, Fuchsia and Android. + (#[1455](https://github.com/nix-rust/nix/pull/1455)) + +### Changed +- `ptsname_r` now returns a lossily-converted string in the event of bad UTF, + just like `ptsname`. + ([#1446](https://github.com/nix-rust/nix/pull/1446)) +- Nix's error type is now a simple wrapper around the platform's Errno. This + means it is now `Into`. It's also `Clone`, `Copy`, `Eq`, and + has a small fixed size. It also requires less typing. For example, the old + enum variant `nix::Error::Sys(nix::errno::Errno::EINVAL)` is now simply + `nix::Error::EINVAL`. + ([#1446](https://github.com/nix-rust/nix/pull/1446)) + +### Fixed +### Removed + +## [0.21.0] - 31 May 2021 +### Added +- Added `getresuid` and `getresgid` + (#[1430](https://github.com/nix-rust/nix/pull/1430)) +- Added TIMESTAMPNS support for linux + (#[1402](https://github.com/nix-rust/nix/pull/1402)) +- Added `sendfile64` (#[1439](https://github.com/nix-rust/nix/pull/1439)) +- Added `MS_LAZYTIME` to `MsFlags` + (#[1437](https://github.com/nix-rust/nix/pull/1437)) + +### Changed +- Made `forkpty` unsafe, like `fork` + (#[1390](https://github.com/nix-rust/nix/pull/1390)) +- Made `Uid`, `Gid` and `Pid` methods `from_raw` and `as_raw` a `const fn` + (#[1429](https://github.com/nix-rust/nix/pull/1429)) +- Made `Uid::is_root` a `const fn` + (#[1429](https://github.com/nix-rust/nix/pull/1429)) +- `AioCb` is now always pinned. Once a `libc::aiocb` gets sent to the kernel, + its address in memory must not change. Nix now enforces that by using + `std::pin`. Most users won't need to change anything, except when using + `aio_suspend`. See that method's documentation for the new usage. + (#[1440](https://github.com/nix-rust/nix/pull/1440)) +- `LioCb` is now constructed using a distinct `LioCbBuilder` struct. This + avoids a soundness issue with the old `LioCb`. Usage is similar but + construction now uses the builder pattern. See the documentation for + details. + (#[1440](https://github.com/nix-rust/nix/pull/1440)) +- Minimum supported Rust version is now 1.41.0. + ([#1440](https://github.com/nix-rust/nix/pull/1440)) +- Errno aliases are now associated consts on `Errno`, instead of consts in the + `errno` module. + (#[1452](https://github.com/nix-rust/nix/pull/1452)) + +### Fixed +- Allow `sockaddr_ll` size, as reported by the Linux kernel, to be smaller then it's definition + (#[1395](https://github.com/nix-rust/nix/pull/1395)) +- Fix spurious errors using `sendmmsg` with multiple cmsgs + (#[1414](https://github.com/nix-rust/nix/pull/1414)) +- Added `Errno::EOPNOTSUPP` to FreeBSD, where it was missing. + (#[1452](https://github.com/nix-rust/nix/pull/1452)) + +### Removed + +- Removed `sys::socket::accept4` from Android arm because libc removed it in + version 0.2.87. + ([#1399](https://github.com/nix-rust/nix/pull/1399)) +- `AioCb::from_boxed_slice` and `AioCb::from_boxed_mut_slice` have been + removed. They were useful with earlier versions of Rust, but should no + longer be needed now that async/await are available. `AioCb`s now work + exclusively with borrowed buffers, not owned ones. + (#[1440](https://github.com/nix-rust/nix/pull/1440)) +- Removed some Errno values from platforms where they aren't actually defined. + (#[1452](https://github.com/nix-rust/nix/pull/1452)) + +## [0.20.0] - 20 February 2021 +### Added + +- Added a `passwd` field to `Group` (#[1338](https://github.com/nix-rust/nix/pull/1338)) +- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306)) +- Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331)) +- Added limited Fuchsia support (#[1285](https://github.com/nix-rust/nix/pull/1285)) +- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342)) +- Implemented `IntoIterator` for `Dir` + (#[1333](https://github.com/nix-rust/nix/pull/1333)). + +### Changed + +- Minimum supported Rust version is now 1.40.0. + ([#1356](https://github.com/nix-rust/nix/pull/1356)) +- i686-apple-darwin has been demoted to Tier 2 support, because it's deprecated + by Xcode. + (#[1350](https://github.com/nix-rust/nix/pull/1350)) +- Fixed calling `recvfrom` on an `AddrFamily::Packet` socket + (#[1344](https://github.com/nix-rust/nix/pull/1344)) + +### Fixed +- `TimerFd` now closes the underlying fd on drop. + ([#1381](https://github.com/nix-rust/nix/pull/1381)) +- Define `*_MAGIC` filesystem constants on Linux s390x + (#[1372](https://github.com/nix-rust/nix/pull/1372)) +- mqueue, sysinfo, timespec, statfs, test_ptrace_syscall() on x32 + (#[1366](https://github.com/nix-rust/nix/pull/1366)) + +### Removed + +- `Dir`, `SignalFd`, and `PtyMaster` are no longer `Clone`. + (#[1382](https://github.com/nix-rust/nix/pull/1382)) +- Removed `SockLevel`, which hasn't been used for a few years + (#[1362](https://github.com/nix-rust/nix/pull/1362)) +- Removed both `Copy` and `Clone` from `TimerFd`. + ([#1381](https://github.com/nix-rust/nix/pull/1381)) + +## [0.19.1] - 28 November 2020 +### Fixed +- Fixed bugs in `recvmmsg`. + (#[1341](https://github.com/nix-rust/nix/pull/1341)) + +## [0.19.0] - 6 October 2020 +### Added +- Added Netlink protocol families to the `SockProtocol` enum + (#[1289](https://github.com/nix-rust/nix/pull/1289)) +- Added `clock_gettime`, `clock_settime`, `clock_getres`, + `clock_getcpuclockid` functions and `ClockId` struct. + (#[1281](https://github.com/nix-rust/nix/pull/1281)) +- Added wrapper functions for `PTRACE_SYSEMU` and `PTRACE_SYSEMU_SINGLESTEP`. + (#[1300](https://github.com/nix-rust/nix/pull/1300)) +- Add support for Vsock on Android rather than just Linux. + (#[1301](https://github.com/nix-rust/nix/pull/1301)) +- Added `TCP_KEEPCNT` and `TCP_KEEPINTVL` TCP keepalive options. + (#[1283](https://github.com/nix-rust/nix/pull/1283)) +### Changed +- Expose `SeekData` and `SeekHole` on all Linux targets + (#[1284](https://github.com/nix-rust/nix/pull/1284)) +- Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s). + (#[1278](https://github.com/nix-rust/nix/pull/1278)) +- Made `unistd::fork` an unsafe funtion, bringing it in line with [libstd's decision](https://github.com/rust-lang/rust/pull/58059). + (#[1293](https://github.com/nix-rust/nix/pull/1293)) +### Fixed +### Removed + +## [0.18.0] - 26 July 2020 +### Added +- Added `fchown(2)` wrapper. + (#[1257](https://github.com/nix-rust/nix/pull/1257)) +- Added support on linux systems for `MAP_HUGE_`_`SIZE`_ family of flags. + (#[1211](https://github.com/nix-rust/nix/pull/1211)) +- Added support for `F_OFD_*` `fcntl` commands on Linux and Android. + (#[1195](https://github.com/nix-rust/nix/pull/1195)) +- Added `env::clearenv()`: calls `libc::clearenv` on platforms + where it's available, and clears the environment of all variables + via `std::env::vars` and `std::env::remove_var` on others. + (#[1185](https://github.com/nix-rust/nix/pull/1185)) +- `FsType` inner value made public. + (#[1187](https://github.com/nix-rust/nix/pull/1187)) +- Added `unistd::setfsuid` and `unistd::setfsgid` to set the user or group + identity for filesystem checks per-thread. + (#[1163](https://github.com/nix-rust/nix/pull/1163)) +- Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189)) +- Added `select::FdSet::fds` method to iterate over file descriptors in a set. + ([#1207](https://github.com/nix-rust/nix/pull/1207)) +- Added support for UDP generic segmentation offload (GSO) and generic + receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209)) +- Added support for `sendmmsg` and `recvmmsg` calls + (#[1208](https://github.com/nix-rust/nix/pull/1208)) +- Added support for `SCM_CREDS` messages (`UnixCredentials`) on FreeBSD/DragonFly + (#[1216](https://github.com/nix-rust/nix/pull/1216)) +- Added `BindToDevice` socket option (sockopt) on Linux + (#[1233](https://github.com/nix-rust/nix/pull/1233)) +- Added `EventFilter` bitflags for `EV_DISPATCH` and `EV_RECEIPT` on OpenBSD. + (#[1252](https://github.com/nix-rust/nix/pull/1252)) +- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage`. + (#[1222](https://github.com/nix-rust/nix/pull/1222)) +- `CpuSet` and `UnixCredentials` now implement `Default`. + (#[1244](https://github.com/nix-rust/nix/pull/1244)) +- Added `unistd::ttyname` + (#[1259](https://github.com/nix-rust/nix/pull/1259)) +- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage` for iOS and Android. + (#[1265](https://github.com/nix-rust/nix/pull/1265)) +- Added support for `TimerFd`. + (#[1261](https://github.com/nix-rust/nix/pull/1261)) + +### Changed +- Changed `fallocate` return type from `c_int` to `()` (#[1201](https://github.com/nix-rust/nix/pull/1201)) +- Enabled `sys::ptrace::setregs` and `sys::ptrace::getregs` on x86_64-unknown-linux-musl target + (#[1198](https://github.com/nix-rust/nix/pull/1198)) +- On Linux, `ptrace::write` is now an `unsafe` function. Caveat programmer. + (#[1245](https://github.com/nix-rust/nix/pull/1245)) +- `execv`, `execve`, `execvp` and `execveat` in `::nix::unistd` and `reboot` in + `::nix::sys::reboot` now return `Result` instead of `Result` (#[1239](https://github.com/nix-rust/nix/pull/1239)) +- `sys::socket::sockaddr_storage_to_addr` is no longer `unsafe`. So is + `offset_of!`. +- `sys::socket::sockaddr_storage_to_addr`, `offset_of!`, and `Errno::clear` are + no longer `unsafe`. +- `SockAddr::as_ffi_pair`,`sys::socket::sockaddr_storage_to_addr`, `offset_of!`, + and `Errno::clear` are no longer `unsafe`. + (#[1244](https://github.com/nix-rust/nix/pull/1244)) +- Several `Inotify` methods now take `self` by value instead of by reference + (#[1244](https://github.com/nix-rust/nix/pull/1244)) +- `nix::poll::ppoll`: `timeout` parameter is now optional, None is equivalent for infinite timeout. + +### Fixed + +- Fixed `getsockopt`. The old code produced UB which triggers a panic with + Rust 1.44.0. + (#[1214](https://github.com/nix-rust/nix/pull/1214)) + +- Fixed a bug in nix::unistd that would result in an infinite loop + when a group or user lookup required a buffer larger than + 16KB. (#[1198](https://github.com/nix-rust/nix/pull/1198)) +- Fixed unaligned casting of `cmsg_data` to `af_alg_iv` (#[1206](https://github.com/nix-rust/nix/pull/1206)) +- Fixed `readlink`/`readlinkat` when reading symlinks longer than `PATH_MAX` (#[1231](https://github.com/nix-rust/nix/pull/1231)) +- `PollFd`, `EpollEvent`, `IpMembershipRequest`, `Ipv6MembershipRequest`, + `TimeVal`, and `IoVec` are now `repr(transparent)`. This is required for + correctness's sake across all architectures and compilers, though now bugs + have been reported so far. + (#[1243](https://github.com/nix-rust/nix/pull/1243)) +- Fixed unaligned pointer read in `Inotify::read_events`. + (#[1244](https://github.com/nix-rust/nix/pull/1244)) + +### Removed + +- Removed `sys::socket::addr::from_libc_sockaddr` from the public API. + (#[1215](https://github.com/nix-rust/nix/pull/1215)) +- Removed `sys::termios::{get_libc_termios, get_libc_termios_mut, update_wrapper` + from the public API. These were previously hidden in the docs but still usable + by downstream. + (#[1235](https://github.com/nix-rust/nix/pull/1235)) + +- Nix no longer implements `NixPath` for `Option

where P: NixPath`. Most + Nix functions that accept `NixPath` arguments can't do anything useful with + `None`. The exceptions (`mount` and `quotactl_sync`) already take explicitly + optional arguments. + (#[1242](https://github.com/nix-rust/nix/pull/1242)) + +- Removed `unistd::daemon` and `unistd::pipe2` on OSX and ios + (#[1255](https://github.com/nix-rust/nix/pull/1255)) + +- Removed `sys::event::FilterFlag::NOTE_EXIT_REPARENTED` and + `sys::event::FilterFlag::NOTE_REAP` on OSX and ios. + (#[1255](https://github.com/nix-rust/nix/pull/1255)) + +- Removed `sys::ptrace::ptrace` on Android and Linux. + (#[1255](https://github.com/nix-rust/nix/pull/1255)) + +- Dropped support for powerpc64-unknown-linux-gnu + (#[1266](https://github.com/nix-rust/nix/pull/1268)) + +## [0.17.0] - 3 February 2020 +### Added +- Add `CLK_TCK` to `SysconfVar` + (#[1177](https://github.com/nix-rust/nix/pull/1177)) +### Changed +### Fixed +### Removed +- Removed deprecated Error::description from error types + (#[1175](https://github.com/nix-rust/nix/pull/1175)) + +## [0.16.1] - 23 December 2019 +### Added +### Changed +### Fixed + +- Fixed the build for OpenBSD + (#[1168](https://github.com/nix-rust/nix/pull/1168)) + +### Removed + +## [0.16.0] - 1 December 2019 +### Added +- Added `ptrace::seize()`: similar to `attach()` on Linux + but with better-defined semantics. + (#[1154](https://github.com/nix-rust/nix/pull/1154)) + +- Added `Signal::as_str()`: returns signal name as `&'static str` + (#[1138](https://github.com/nix-rust/nix/pull/1138)) + +- Added `posix_fallocate`. + ([#1105](https://github.com/nix-rust/nix/pull/1105)) + +- Implemented `Default` for `FdSet` + ([#1107](https://github.com/nix-rust/nix/pull/1107)) + +- Added `NixPath::is_empty`. + ([#1107](https://github.com/nix-rust/nix/pull/1107)) + +- Added `mkfifoat` + ([#1133](https://github.com/nix-rust/nix/pull/1133)) + +- Added `User::from_uid`, `User::from_name`, `User::from_gid` and + `Group::from_name`, + ([#1139](https://github.com/nix-rust/nix/pull/1139)) + +- Added `linkat` + ([#1101](https://github.com/nix-rust/nix/pull/1101)) + +- Added `sched_getaffinity`. + ([#1148](https://github.com/nix-rust/nix/pull/1148)) + +- Added optional `Signal` argument to `ptrace::{detach, syscall}` for signal + injection. ([#1083](https://github.com/nix-rust/nix/pull/1083)) + +### Changed +- `sys::termios::BaudRate` now implements `TryFrom` instead of + `From`. The old `From` implementation would panic on failure. + ([#1159](https://github.com/nix-rust/nix/pull/1159)) + +- `sys::socket::ControlMessage::ScmCredentials` and + `sys::socket::ControlMessageOwned::ScmCredentials` now wrap `UnixCredentials` + rather than `libc::ucred`. + ([#1160](https://github.com/nix-rust/nix/pull/1160)) + +- `sys::socket::recvmsg` now takes a plain `Vec` instead of a `CmsgBuffer` + implementor. If you were already using `cmsg_space!`, then you needn't worry. + ([#1156](https://github.com/nix-rust/nix/pull/1156)) + +- `sys::socket::recvfrom` now returns + `Result<(usize, Option)>` instead of `Result<(usize, SockAddr)>`. + ([#1145](https://github.com/nix-rust/nix/pull/1145)) + +- `Signal::from_c_int` has been replaced by `Signal::try_from` + ([#1113](https://github.com/nix-rust/nix/pull/1113)) + +- Changed `readlink` and `readlinkat` to return `OsString` + ([#1109](https://github.com/nix-rust/nix/pull/1109)) + + ```rust + # use nix::fcntl::{readlink, readlinkat}; + // the buffer argument of `readlink` and `readlinkat` has been removed, + // and the return value is now an owned type (`OsString`). + // Existing code can be updated by removing the buffer argument + // and removing any clone or similar operation on the output + + // old code `readlink(&path, &mut buf)` can be replaced with the following + let _: OsString = readlink(&path); + + // old code `readlinkat(dirfd, &path, &mut buf)` can be replaced with the following + let _: OsString = readlinkat(dirfd, &path); + ``` + +- Minimum supported Rust version is now 1.36.0. + ([#1108](https://github.com/nix-rust/nix/pull/1108)) + +- `Ipv4Addr::octets`, `Ipv4Addr::to_std`, `Error::as_errno`, + `ForkResult::is_child`, `ForkResult::is_parent`, `Gid::as_raw`, + `Uid::is_root`, `Uid::as_raw`, `Pid::as_raw`, and `PollFd::revents` now take + `self` by value. + ([#1107](https://github.com/nix-rust/nix/pull/1107)) + +- Type `&CString` for parameters of `exec(v|ve|vp|vpe|veat)` are changed to `&CStr`. + ([#1121](https://github.com/nix-rust/nix/pull/1121)) + +### Fixed +- Fix length of abstract socket addresses + ([#1120](https://github.com/nix-rust/nix/pull/1120)) + +- Fix initialization of msghdr in recvmsg/sendmsg when built with musl + ([#1136](https://github.com/nix-rust/nix/pull/1136)) + +### Removed +- Remove the deprecated `CmsgSpace`. + ([#1156](https://github.com/nix-rust/nix/pull/1156)) + +## [0.15.0] - 10 August 2019 +### Added +- Added `MSG_WAITALL` to `MsgFlags` in `sys::socket`. + ([#1079](https://github.com/nix-rust/nix/pull/1079)) +- Implemented `Clone`, `Copy`, `Debug`, `Eq`, `Hash`, and `PartialEq` for most + types that support them. ([#1035](https://github.com/nix-rust/nix/pull/1035)) +- Added `copy_file_range` wrapper + ([#1069](https://github.com/nix-rust/nix/pull/1069)) +- Add `mkdirat`. + ([#1084](https://github.com/nix-rust/nix/pull/1084)) +- Add `posix_fadvise`. + ([#1089](https://github.com/nix-rust/nix/pull/1089)) +- Added `AF_VSOCK` to `AddressFamily`. + ([#1091](https://github.com/nix-rust/nix/pull/1091)) +- Add `unlinkat` + ([#1058](https://github.com/nix-rust/nix/pull/1058)) +- Add `renameat`. + ([#1097](https://github.com/nix-rust/nix/pull/1097)) + +### Changed +- Support for `ifaddrs` now present when building for Android. + ([#1077](https://github.com/nix-rust/nix/pull/1077)) +- Minimum supported Rust version is now 1.31.0 + ([#1035](https://github.com/nix-rust/nix/pull/1035)) + ([#1095](https://github.com/nix-rust/nix/pull/1095)) +- Now functions `statfs()` and `fstatfs()` return result with `Statfs` wrapper + ([#928](https://github.com/nix-rust/nix/pull/928)) + +### Fixed +- Enabled `sched_yield` for all nix hosts. + ([#1090](https://github.com/nix-rust/nix/pull/1090)) + +### Removed + +## [0.14.1] - 2019-06-06 +### Added +- Macros exported by `nix` may now be imported via `use` on the Rust 2018 + edition without importing helper macros on Linux targets. + ([#1066](https://github.com/nix-rust/nix/pull/1066)) + + For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported + without importing the `convert_ioctl_res!` macro. + + ```rust + use nix::ioctl_read_bad; + + ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); + ``` + +### Changed +- Changed some public types from reexports of libc types like `uint32_t` to the + native equivalents like `u32.` + ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) + +### Fixed +- Fix the build on Android and Linux/mips with recent versions of libc. + ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) + +### Removed + +## [0.14.0] - 2019-05-21 +### Added +- Add IP_RECVIF & IP_RECVDSTADDR. Enable IP_PKTINFO and IP6_PKTINFO on netbsd/openbsd. + ([#1002](https://github.com/nix-rust/nix/pull/1002)) +- Added `inotify_init1`, `inotify_add_watch` and `inotify_rm_watch` wrappers for + Android and Linux. ([#1016](https://github.com/nix-rust/nix/pull/1016)) +- Add `ALG_SET_IV`, `ALG_SET_OP` and `ALG_SET_AEAD_ASSOCLEN` control messages and `AF_ALG` + socket types on Linux and Android ([#1031](https://github.com/nix-rust/nix/pull/1031)) +- Add killpg + ([#1034](https://github.com/nix-rust/nix/pull/1034)) +- Added ENOTSUP errno support for Linux and Android. + ([#969](https://github.com/nix-rust/nix/pull/969)) +- Add several errno constants from OpenBSD 6.2 + ([#1036](https://github.com/nix-rust/nix/pull/1036)) +- Added `from_std` and `to_std` methods for `sys::socket::IpAddr` + ([#1043](https://github.com/nix-rust/nix/pull/1043)) +- Added `nix::unistd:seteuid` and `nix::unistd::setegid` for those platforms that do + not support `setresuid` nor `setresgid` respectively. + ([#1044](https://github.com/nix-rust/nix/pull/1044)) +- Added a `access` wrapper + ([#1045](https://github.com/nix-rust/nix/pull/1045)) +- Add `forkpty` + ([#1042](https://github.com/nix-rust/nix/pull/1042)) +- Add `sched_yield` + ([#1050](https://github.com/nix-rust/nix/pull/1050)) + +### Changed +- `PollFd` event flags renamed to `PollFlags` ([#1024](https://github.com/nix-rust/nix/pull/1024/)) +- `recvmsg` now returns an Iterator over `ControlMessageOwned` objects rather + than `ControlMessage` objects. This is sadly not backwards-compatible. Fix + code like this: + ```rust + if let ControlMessage::ScmRights(&fds) = cmsg { + ``` + + By replacing it with code like this: + ```rust + if let ControlMessageOwned::ScmRights(fds) = cmsg { + ``` + ([#1020](https://github.com/nix-rust/nix/pull/1020)) +- Replaced `CmsgSpace` with the `cmsg_space` macro. + ([#1020](https://github.com/nix-rust/nix/pull/1020)) + +### Fixed +- Fixed multiple bugs when using `sendmsg` and `recvmsg` with ancillary control messages + ([#1020](https://github.com/nix-rust/nix/pull/1020)) +- Macros exported by `nix` may now be imported via `use` on the Rust 2018 + edition without importing helper macros for BSD targets. + ([#1041](https://github.com/nix-rust/nix/pull/1041)) + + For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported + without importing the `convert_ioctl_res!` macro. + + ```rust + use nix::ioctl_read_bad; + + ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); + ``` + +### Removed +- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX + and iOS. + ([#1033](https://github.com/nix-rust/nix/pull/1033)) +- `PTRACE_GETREGS`, `PTRACE_SETREGS`, `PTRACE_GETFPREGS`, and + `PTRACE_SETFPREGS` have been removed from some platforms where they never + should've been defined in the first place. + ([#1055](https://github.com/nix-rust/nix/pull/1055)) + +## [0.13.0] - 2019-01-15 +### Added +- Added PKTINFO(V4) & V6PKTINFO cmsg support - Android/FreeBSD/iOS/Linux/MacOS. + ([#990](https://github.com/nix-rust/nix/pull/990)) +- Added support of CString type in `setsockopt`. + ([#972](https://github.com/nix-rust/nix/pull/972)) +- Added option `TCP_CONGESTION` in `setsockopt`. + ([#972](https://github.com/nix-rust/nix/pull/972)) +- Added `symlinkat` wrapper. + ([#997](https://github.com/nix-rust/nix/pull/997)) +- Added `ptrace::{getregs, setregs}`. + ([#1010](https://github.com/nix-rust/nix/pull/1010)) +- Added `nix::sys::signal::signal`. + ([#817](https://github.com/nix-rust/nix/pull/817)) +- Added an `mprotect` wrapper. + ([#991](https://github.com/nix-rust/nix/pull/991)) + +### Changed +### Fixed +- `lutimes` never worked on OpenBSD as it is not implemented on OpenBSD. It has + been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000)) +- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on + either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000)) + +### Removed + +## [0.12.0] 2018-11-28 + +### Added +- Added `FromStr` and `Display` impls for `nix::sys::Signal` + ([#884](https://github.com/nix-rust/nix/pull/884)) +- Added a `sync` wrapper. + ([#961](https://github.com/nix-rust/nix/pull/961)) +- Added a `sysinfo` wrapper. + ([#922](https://github.com/nix-rust/nix/pull/922)) +- Support the `SO_PEERCRED` socket option and the `UnixCredentials` type on all Linux and Android targets. + ([#921](https://github.com/nix-rust/nix/pull/921)) +- Added support for `SCM_CREDENTIALS`, allowing to send process credentials over Unix sockets. + ([#923](https://github.com/nix-rust/nix/pull/923)) +- Added a `dir` module for reading directories (wraps `fdopendir`, `readdir`, and `rewinddir`). + ([#916](https://github.com/nix-rust/nix/pull/916)) +- Added `kmod` module that allows loading and unloading kernel modules on Linux. + ([#930](https://github.com/nix-rust/nix/pull/930)) +- Added `futimens` and `utimesat` wrappers ([#944](https://github.com/nix-rust/nix/pull/944)), + an `lutimes` wrapper ([#967](https://github.com/nix-rust/nix/pull/967)), + and a `utimes` wrapper ([#946](https://github.com/nix-rust/nix/pull/946)). +- Added `AF_UNSPEC` wrapper to `AddressFamily` ([#948](https://github.com/nix-rust/nix/pull/948)) +- Added the `mode_t` public alias within `sys::stat`. + ([#954](https://github.com/nix-rust/nix/pull/954)) +- Added a `truncate` wrapper. + ([#956](https://github.com/nix-rust/nix/pull/956)) +- Added a `fchownat` wrapper. + ([#955](https://github.com/nix-rust/nix/pull/955)) +- Added support for `ptrace` on BSD operating systems ([#949](https://github.com/nix-rust/nix/pull/949)) +- Added `ptrace` functions for reads and writes to tracee memory and ptrace kill + ([#949](https://github.com/nix-rust/nix/pull/949)) ([#958](https://github.com/nix-rust/nix/pull/958)) +- Added a `acct` wrapper module for enabling and disabling process accounting + ([#952](https://github.com/nix-rust/nix/pull/952)) +- Added the `time_t` and `suseconds_t` public aliases within `sys::time`. + ([#968](https://github.com/nix-rust/nix/pull/968)) +- Added `unistd::execvpe` for Haiku, Linux and OpenBSD + ([#975](https://github.com/nix-rust/nix/pull/975)) +- Added `Error::as_errno`. + ([#977](https://github.com/nix-rust/nix/pull/977)) + +### Changed +- Increased required Rust version to 1.24.1 + ([#900](https://github.com/nix-rust/nix/pull/900)) + ([#966](https://github.com/nix-rust/nix/pull/966)) + +### Fixed +- Made `preadv` take immutable slice of IoVec. + ([#914](https://github.com/nix-rust/nix/pull/914)) +- Fixed passing multiple file descriptors over Unix Sockets. + ([#918](https://github.com/nix-rust/nix/pull/918)) + +### Removed + +## [0.11.0] 2018-06-01 + +### Added +- Added `sendfile` on FreeBSD and Darwin. + ([#901](https://github.com/nix-rust/nix/pull/901)) +- Added `pselect` + ([#894](https://github.com/nix-rust/nix/pull/894)) +- Exposed `preadv` and `pwritev` on the BSDs. + ([#883](https://github.com/nix-rust/nix/pull/883)) +- Added `mlockall` and `munlockall` + ([#876](https://github.com/nix-rust/nix/pull/876)) +- Added `SO_MARK` on Linux. + ([#873](https://github.com/nix-rust/nix/pull/873)) +- Added safe support for nearly any buffer type in the `sys::aio` module. + ([#872](https://github.com/nix-rust/nix/pull/872)) +- Added `sys::aio::LioCb` as a wrapper for `libc::lio_listio`. + ([#872](https://github.com/nix-rust/nix/pull/872)) +- Added `unistd::getsid` + ([#850](https://github.com/nix-rust/nix/pull/850)) +- Added `alarm`. ([#830](https://github.com/nix-rust/nix/pull/830)) +- Added interface flags `IFF_NO_PI, IFF_TUN, IFF_TAP` on linux-like systems. + ([#853](https://github.com/nix-rust/nix/pull/853)) +- Added `statvfs` module to all MacOS and Linux architectures. + ([#832](https://github.com/nix-rust/nix/pull/832)) +- Added `EVFILT_EMPTY`, `EVFILT_PROCDESC`, and `EVFILT_SENDFILE` on FreeBSD. + ([#825](https://github.com/nix-rust/nix/pull/825)) +- Exposed `termios::cfmakesane` on FreeBSD. + ([#825](https://github.com/nix-rust/nix/pull/825)) +- Exposed `MSG_CMSG_CLOEXEC` on *BSD. + ([#825](https://github.com/nix-rust/nix/pull/825)) +- Added `fchmod`, `fchmodat`. + ([#857](https://github.com/nix-rust/nix/pull/857)) +- Added `request_code_write_int!` on FreeBSD/DragonFlyBSD + ([#833](https://github.com/nix-rust/nix/pull/833)) + +### Changed +- `Display` and `Debug` for `SysControlAddr` now includes all fields. + ([#837](https://github.com/nix-rust/nix/pull/837)) +- `ioctl!` has been replaced with a family of `ioctl_*!` macros. + ([#833](https://github.com/nix-rust/nix/pull/833)) +- `io!`, `ior!`, `iow!`, and `iorw!` has been renamed to `request_code_none!`, `request_code_read!`, + `request_code_write!`, and `request_code_readwrite!` respectively. These have also now been exposed + in the documentation. + ([#833](https://github.com/nix-rust/nix/pull/833)) +- Enabled more `ptrace::Request` definitions for uncommon Linux platforms + ([#892](https://github.com/nix-rust/nix/pull/892)) +- Emulation of `FD_CLOEXEC` and `O_NONBLOCK` was removed from `socket()`, `accept4()`, and + `socketpair()`. + ([#907](https://github.com/nix-rust/nix/pull/907)) + +### Fixed +- Fixed possible panics when using `SigAction::flags` on Linux + ([#869](https://github.com/nix-rust/nix/pull/869)) +- Properly exposed 460800 and 921600 baud rates on NetBSD + ([#837](https://github.com/nix-rust/nix/pull/837)) +- Fixed `ioctl_write_int!` on FreeBSD/DragonFlyBSD + ([#833](https://github.com/nix-rust/nix/pull/833)) +- `ioctl_write_int!` now properly supports passing a `c_ulong` as the parameter on Linux non-musl targets + ([#833](https://github.com/nix-rust/nix/pull/833)) + +### Removed +- Removed explicit support for the `bytes` crate from the `sys::aio` module. + See `sys::aio::AioCb::from_boxed_slice` examples for alternatives. + ([#872](https://github.com/nix-rust/nix/pull/872)) +- Removed `sys::aio::lio_listio`. Use `sys::aio::LioCb::listio` instead. + ([#872](https://github.com/nix-rust/nix/pull/872)) +- Removed emulated `accept4()` from macos, ios, and netbsd targets + ([#907](https://github.com/nix-rust/nix/pull/907)) +- Removed `IFF_NOTRAILERS` on OpenBSD, as it has been removed in OpenBSD 6.3 + ([#893](https://github.com/nix-rust/nix/pull/893)) + +## [0.10.0] 2018-01-26 + +### Added +- Added specialized wrapper: `sys::ptrace::step` + ([#852](https://github.com/nix-rust/nix/pull/852)) +- Added `AioCb::from_ptr` and `AioCb::from_mut_ptr` + ([#820](https://github.com/nix-rust/nix/pull/820)) +- Added specialized wrappers: `sys::ptrace::{traceme, syscall, cont, attach}`. Using the matching routines + with `sys::ptrace::ptrace` is now deprecated. +- Added `nix::poll` module for all platforms + ([#672](https://github.com/nix-rust/nix/pull/672)) +- Added `nix::ppoll` function for FreeBSD and DragonFly + ([#672](https://github.com/nix-rust/nix/pull/672)) +- Added protocol families in `AddressFamily` enum. + ([#647](https://github.com/nix-rust/nix/pull/647)) +- Added the `pid()` method to `WaitStatus` for extracting the PID. + ([#722](https://github.com/nix-rust/nix/pull/722)) +- Added `nix::unistd:fexecve`. + ([#727](https://github.com/nix-rust/nix/pull/727)) +- Expose `uname()` on all platforms. + ([#739](https://github.com/nix-rust/nix/pull/739)) +- Expose `signalfd` module on Android as well. + ([#739](https://github.com/nix-rust/nix/pull/739)) +- Added `nix::sys::ptrace::detach`. + ([#749](https://github.com/nix-rust/nix/pull/749)) +- Added timestamp socket control message variant: + `nix::sys::socket::ControlMessage::ScmTimestamp` + ([#663](https://github.com/nix-rust/nix/pull/663)) +- Added socket option variant that enables the timestamp socket + control message: `nix::sys::socket::sockopt::ReceiveTimestamp` + ([#663](https://github.com/nix-rust/nix/pull/663)) +- Added more accessor methods for `AioCb` + ([#773](https://github.com/nix-rust/nix/pull/773)) +- Add `nix::sys::fallocate` + ([#768](https:://github.com/nix-rust/nix/pull/768)) +- Added `nix::unistd::mkfifo`. + ([#602](https://github.com/nix-rust/nix/pull/774)) +- Added `ptrace::Options::PTRACE_O_EXITKILL` on Linux and Android. + ([#771](https://github.com/nix-rust/nix/pull/771)) +- Added `nix::sys::uio::{process_vm_readv, process_vm_writev}` on Linux + ([#568](https://github.com/nix-rust/nix/pull/568)) +- Added `nix::unistd::{getgroups, setgroups, getgrouplist, initgroups}`. ([#733](https://github.com/nix-rust/nix/pull/733)) +- Added `nix::sys::socket::UnixAddr::as_abstract` on Linux and Android. + ([#785](https://github.com/nix-rust/nix/pull/785)) +- Added `nix::unistd::execveat` on Linux and Android. + ([#800](https://github.com/nix-rust/nix/pull/800)) +- Added the `from_raw()` method to `WaitStatus` for converting raw status values + to `WaitStatus` independent of syscalls. + ([#741](https://github.com/nix-rust/nix/pull/741)) +- Added more standard trait implementations for various types. + ([#814](https://github.com/nix-rust/nix/pull/814)) +- Added `sigprocmask` to the signal module. + ([#826](https://github.com/nix-rust/nix/pull/826)) +- Added `nix::sys::socket::LinkAddr` on Linux and all bsdlike system. + ([#813](https://github.com/nix-rust/nix/pull/813)) +- Add socket options for `IP_TRANSPARENT` / `BIND_ANY`. + ([#835](https://github.com/nix-rust/nix/pull/835)) + +### Changed +- Exposed the `mqueue` module for all supported operating systems. + ([#834](https://github.com/nix-rust/nix/pull/834)) +- Use native `pipe2` on all BSD targets. Users should notice no difference. + ([#777](https://github.com/nix-rust/nix/pull/777)) +- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692)) +- Marked `sys::ptrace::ptrace` as `unsafe`. +- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument + has changed type from `c_int` to `SockProtocol`. + It accepts a `None` value for default protocol that was specified with zero using `c_int`. + ([#647](https://github.com/nix-rust/nix/pull/647)) +- Made `select` easier to use, adding the ability to automatically calculate the `nfds` parameter using the new + `FdSet::highest` ([#701](https://github.com/nix-rust/nix/pull/701)) +- Exposed `unistd::setresuid` and `unistd::setresgid` on FreeBSD and OpenBSD + ([#721](https://github.com/nix-rust/nix/pull/721)) +- Refactored the `statvfs` module removing extraneous API functions and the + `statvfs::vfs` module. Additionally `(f)statvfs()` now return the struct + directly. And the returned `Statvfs` struct now exposes its data through + accessor methods. ([#729](https://github.com/nix-rust/nix/pull/729)) +- The `addr` argument to `madvise` and `msync` is now `*mut` to better match the + libc API. ([#731](https://github.com/nix-rust/nix/pull/731)) +- `shm_open` and `shm_unlink` are no longer exposed on Android targets, where + they are not officially supported. ([#731](https://github.com/nix-rust/nix/pull/731)) +- `MapFlags`, `MmapAdvise`, and `MsFlags` expose some more variants and only + officially-supported variants are provided for each target. + ([#731](https://github.com/nix-rust/nix/pull/731)) +- Marked `pty::ptsname` function as `unsafe` + ([#744](https://github.com/nix-rust/nix/pull/744)) +- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly. + ([#749](https://github.com/nix-rust/nix/pull/749)) +- `AioCb::Drop` will now panic if the `AioCb` is still in-progress ([#715](https://github.com/nix-rust/nix/pull/715)) +- Restricted `nix::sys::socket::UnixAddr::new_abstract` to Linux and Android only. + ([#785](https://github.com/nix-rust/nix/pull/785)) +- The `ucred` struct has been removed in favor of a `UserCredentials` struct that + contains only getters for its fields. + ([#814](https://github.com/nix-rust/nix/pull/814)) +- Both `ip_mreq` and `ipv6_mreq` have been replaced with `IpMembershipRequest` and + `Ipv6MembershipRequest`. + ([#814](https://github.com/nix-rust/nix/pull/814)) +- Removed return type from `pause`. + ([#829](https://github.com/nix-rust/nix/pull/829)) +- Changed the termios APIs to allow for using a `u32` instead of the `BaudRate` + enum on BSD platforms to support arbitrary baud rates. See the module docs for + `nix::sys::termios` for more details. + ([#843](https://github.com/nix-rust/nix/pull/843)) + +### Fixed +- Fix compilation and tests for OpenBSD targets + ([#688](https://github.com/nix-rust/nix/pull/688)) +- Fixed error handling in `AioCb::fsync`, `AioCb::read`, and `AioCb::write`. + It is no longer an error to drop an `AioCb` that failed to enqueue in the OS. + ([#715](https://github.com/nix-rust/nix/pull/715)) +- Fix potential memory corruption on non-Linux platforms when using + `sendmsg`/`recvmsg`, caused by mismatched `msghdr` definition. + ([#648](https://github.com/nix-rust/nix/pull/648)) + +### Removed +- `AioCb::from_boxed_slice` has been removed. It was never actually safe. Use + `from_bytes` or `from_bytes_mut` instead. + ([#820](https://github.com/nix-rust/nix/pull/820)) +- The syscall module has been removed. This only exposed enough functionality for + `memfd_create()` and `pivot_root()`, which are still exposed as separate functions. + ([#747](https://github.com/nix-rust/nix/pull/747)) +- The `Errno` variants are no longer reexported from the `errno` module. `Errno` itself is no longer reexported from the + crate root and instead must be accessed using the `errno` module. ([#696](https://github.com/nix-rust/nix/pull/696)) +- Removed `MS_VERBOSE`, `MS_NOSEC`, and `MS_BORN` from `MsFlags`. These + are internal kernel flags and should never have been exposed. + ([#814](https://github.com/nix-rust/nix/pull/814)) + + +## [0.9.0] 2017-07-23 + +### Added +- Added `sysconf`, `pathconf`, and `fpathconf` + ([#630](https://github.com/nix-rust/nix/pull/630) +- Added `sys::signal::SigAction::{ flags, mask, handler}` + ([#611](https://github.com/nix-rust/nix/pull/609) +- Added `nix::sys::pthread::pthread_self` + ([#591](https://github.com/nix-rust/nix/pull/591) +- Added `AioCb::from_boxed_slice` + ([#582](https://github.com/nix-rust/nix/pull/582) +- Added `nix::unistd::{openat, fstatat, readlink, readlinkat}` + ([#551](https://github.com/nix-rust/nix/pull/551)) +- Added `nix::pty::{grantpt, posix_openpt, ptsname/ptsname_r, unlockpt}` + ([#556](https://github.com/nix-rust/nix/pull/556) +- Added `nix::ptr::openpty` + ([#456](https://github.com/nix-rust/nix/pull/456)) +- Added `nix::ptrace::{ptrace_get_data, ptrace_getsiginfo, ptrace_setsiginfo + and nix::Error::UnsupportedOperation}` + ([#614](https://github.com/nix-rust/nix/pull/614)) +- Added `cfmakeraw`, `cfsetspeed`, and `tcgetsid`. ([#527](https://github.com/nix-rust/nix/pull/527)) +- Added "bad none", "bad write_ptr", "bad write_int", and "bad readwrite" variants to the `ioctl!` + macro. ([#670](https://github.com/nix-rust/nix/pull/670)) +- On Linux and Android, added support for receiving `PTRACE_O_TRACESYSGOOD` + events from `wait` and `waitpid` using `WaitStatus::PtraceSyscall` + ([#566](https://github.com/nix-rust/nix/pull/566)). + +### Changed +- The `ioctl!` macro and its variants now allow the generated functions to have + doccomments. ([#661](https://github.com/nix-rust/nix/pull/661)) +- Changed `ioctl!(write ...)` into `ioctl!(write_ptr ...)` and `ioctl!(write_int ..)` variants + to more clearly separate those use cases. ([#670](https://github.com/nix-rust/nix/pull/670)) +- Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe. + ([#559](https://github.com/nix-rust/nix/pull/559)) +- Minimum supported Rust version is now 1.13. +- Removed `revents` argument from `PollFd::new()` as it's an output argument and + will be overwritten regardless of value. + ([#542](https://github.com/nix-rust/nix/pull/542)) +- Changed type signature of `sys::select::FdSet::contains` to make `self` + immutable ([#564](https://github.com/nix-rust/nix/pull/564)) +- Introduced wrapper types for `gid_t`, `pid_t`, and `uid_t` as `Gid`, `Pid`, and `Uid` + respectively. Various functions have been changed to use these new types as + arguments. ([#629](https://github.com/nix-rust/nix/pull/629)) +- Fixed compilation on all Android and iOS targets ([#527](https://github.com/nix-rust/nix/pull/527)) + and promoted them to Tier 2 support. +- `nix::sys::statfs::{statfs,fstatfs}` uses statfs definition from `libc::statfs` instead of own linux specific type `nix::sys::Statfs`. + Also file system type constants like `nix::sys::statfs::ADFS_SUPER_MAGIC` were removed in favor of the libc equivalent. + ([#561](https://github.com/nix-rust/nix/pull/561)) +- Revised the termios API including additional tests and documentation and exposed it on iOS. ([#527](https://github.com/nix-rust/nix/pull/527)) +- `eventfd`, `signalfd`, and `pwritev`/`preadv` functionality is now included by default for all + supported platforms. ([#681](https://github.com/nix-rust/nix/pull/561)) +- The `ioctl!` macro's plain variants has been replaced with "bad read" to be consistent with + other variants. The generated functions also have more strict types for their arguments. The + "*_buf" variants also now calculate total array size and take slice references for improved type + safety. The documentation has also been dramatically improved. + ([#670](https://github.com/nix-rust/nix/pull/670)) + +### Removed +- Removed `io::Error` from `nix::Error` and the conversion from `nix::Error` to `Errno` + ([#614](https://github.com/nix-rust/nix/pull/614)) +- All feature flags have been removed in favor of conditional compilation on supported platforms. + `execvpe` is no longer supported, but this was already broken and will be added back in the next + release. ([#681](https://github.com/nix-rust/nix/pull/561)) +- Removed `ioc_*` functions and many helper constants and macros within the `ioctl` module. These + should always have been private and only the `ioctl!` should be used in public code. + ([#670](https://github.com/nix-rust/nix/pull/670)) + +### Fixed +- Fixed multiple issues compiling under different archetectures and OSes. + Now compiles on Linux/MIPS ([#538](https://github.com/nix-rust/nix/pull/538)), + `Linux/PPC` ([#553](https://github.com/nix-rust/nix/pull/553)), + `MacOS/x86_64,i686` ([#553](https://github.com/nix-rust/nix/pull/553)), + `NetBSD/x64_64` ([#538](https://github.com/nix-rust/nix/pull/538)), + `FreeBSD/x86_64,i686` ([#536](https://github.com/nix-rust/nix/pull/536)), and + `Android` ([#631](https://github.com/nix-rust/nix/pull/631)). +- `bind` and `errno_location` now work correctly on `Android` + ([#631](https://github.com/nix-rust/nix/pull/631)) +- Added `nix::ptrace` on all Linux-kernel-based platforms + [#624](https://github.com/nix-rust/nix/pull/624). Previously it was + only available on x86, x86-64, and ARM, and also not on Android. +- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter. + ([#623](https://github.com/nix-rust/nix/pull/623)) +- Multiple constants related to the termios API have now been properly defined for + all supported platforms. ([#527](https://github.com/nix-rust/nix/pull/527)) +- `ioctl!` macro now supports working with non-int datatypes and properly supports all platforms. + ([#670](https://github.com/nix-rust/nix/pull/670)) + +## [0.8.1] 2017-04-16 + +### Fixed +- Fixed build on FreeBSD. (Cherry-picked + [a859ee3c](https://github.com/nix-rust/nix/commit/a859ee3c9396dfdb118fcc2c8ecc697e2d303467)) + +## [0.8.0] 2017-03-02 + +### Added +- Added `::nix::sys::termios::BaudRate` enum to provide portable baudrate + values. ([#518](https://github.com/nix-rust/nix/pull/518)) +- Added a new `WaitStatus::PtraceEvent` to support ptrace events on Linux + and Android ([#438](https://github.com/nix-rust/nix/pull/438)) +- Added support for POSIX AIO + ([#483](https://github.com/nix-rust/nix/pull/483)) + ([#506](https://github.com/nix-rust/nix/pull/506)) +- Added support for XNU system control sockets + ([#478](https://github.com/nix-rust/nix/pull/478)) +- Added support for `ioctl` calls on BSD platforms + ([#478](https://github.com/nix-rust/nix/pull/478)) +- Added struct `TimeSpec` + ([#475](https://github.com/nix-rust/nix/pull/475)) + ([#483](https://github.com/nix-rust/nix/pull/483)) +- Added complete definitions for all kqueue-related constants on all supported + OSes + ([#415](https://github.com/nix-rust/nix/pull/415)) +- Added function `epoll_create1` and bitflags `EpollCreateFlags` in + `::nix::sys::epoll` in order to support `::libc::epoll_create1`. + ([#410](https://github.com/nix-rust/nix/pull/410)) +- Added `setresuid` and `setresgid` for Linux in `::nix::unistd` + ([#448](https://github.com/nix-rust/nix/pull/448)) +- Added `getpgid` in `::nix::unistd` + ([#433](https://github.com/nix-rust/nix/pull/433)) +- Added `tcgetpgrp` and `tcsetpgrp` in `::nix::unistd` + ([#451](https://github.com/nix-rust/nix/pull/451)) +- Added `CLONE_NEWCGROUP` in `::nix::sched` + ([#457](https://github.com/nix-rust/nix/pull/457)) +- Added `getpgrp` in `::nix::unistd` + ([#491](https://github.com/nix-rust/nix/pull/491)) +- Added `fchdir` in `::nix::unistd` + ([#497](https://github.com/nix-rust/nix/pull/497)) +- Added `major` and `minor` in `::nix::sys::stat` for decomposing `dev_t` + ([#508](https://github.com/nix-rust/nix/pull/508)) +- Fixed the style of many bitflags and use `libc` in more places. + ([#503](https://github.com/nix-rust/nix/pull/503)) +- Added `ppoll` in `::nix::poll` + ([#520](https://github.com/nix-rust/nix/pull/520)) +- Added support for getting and setting pipe size with fcntl(2) on Linux + ([#540](https://github.com/nix-rust/nix/pull/540)) + +### Changed +- `::nix::sys::termios::{cfgetispeed, cfsetispeed, cfgetospeed, cfsetospeed}` + switched to use `BaudRate` enum from `speed_t`. + ([#518](https://github.com/nix-rust/nix/pull/518)) +- `epoll_ctl` now could accept None as argument `event` + when op is `EpollOp::EpollCtlDel`. + ([#480](https://github.com/nix-rust/nix/pull/480)) +- Removed the `bad` keyword from the `ioctl!` macro + ([#478](https://github.com/nix-rust/nix/pull/478)) +- Changed `TimeVal` into an opaque Newtype + ([#475](https://github.com/nix-rust/nix/pull/475)) +- `kill`'s signature, defined in `::nix::sys::signal`, changed, so that the + signal parameter has type `T: Into>`. `None` as an argument + for that parameter will result in a 0 passed to libc's `kill`, while a + `Some`-argument will result in the previous behavior for the contained + `Signal`. + ([#445](https://github.com/nix-rust/nix/pull/445)) +- The minimum supported version of rustc is now 1.7.0. + ([#444](https://github.com/nix-rust/nix/pull/444)) +- Changed `KEvent` to an opaque structure that may only be modified by its + constructor and the `ev_set` method. + ([#415](https://github.com/nix-rust/nix/pull/415)) + ([#442](https://github.com/nix-rust/nix/pull/442)) + ([#463](https://github.com/nix-rust/nix/pull/463)) +- `pipe2` now calls `libc::pipe2` where available. Previously it was emulated + using `pipe`, which meant that setting `O_CLOEXEC` was not atomic. + ([#427](https://github.com/nix-rust/nix/pull/427)) +- Renamed `EpollEventKind` to `EpollFlags` in `::nix::sys::epoll` in order for + it to conform with our conventions. + ([#410](https://github.com/nix-rust/nix/pull/410)) +- `EpollEvent` in `::nix::sys::epoll` is now an opaque proxy for + `::libc::epoll_event`. The formerly public field `events` is now be read-only + accessible with the new method `events()` of `EpollEvent`. Instances of + `EpollEvent` can be constructed using the new method `new()` of EpollEvent. + ([#410](https://github.com/nix-rust/nix/pull/410)) +- `SigFlags` in `::nix::sys::signal` has be renamed to `SigmaskHow` and its type + has changed from `bitflags` to `enum` in order to conform to our conventions. + ([#460](https://github.com/nix-rust/nix/pull/460)) +- `sethostname` now takes a `&str` instead of a `&[u8]` as this provides an API + that makes more sense in normal, correct usage of the API. +- `gethostname` previously did not expose the actual length of the hostname + written from the underlying system call at all. This has been updated to + return a `&CStr` within the provided buffer that is always properly + NUL-terminated (this is not guaranteed by the call with all platforms/libc + implementations). +- Exposed all fcntl(2) operations at the module level, so they can be + imported direclty instead of via `FcntlArg` enum. + ([#541](https://github.com/nix-rust/nix/pull/541)) + +### Fixed +- Fixed multiple issues with Unix domain sockets on non-Linux OSes + ([#474](https://github.com/nix-rust/nix/pull/415)) +- Fixed using kqueue with `EVFILT_USER` on FreeBSD + ([#415](https://github.com/nix-rust/nix/pull/415)) +- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg + functions on that same OS. + ([#397](https://github.com/nix-rust/nix/pull/397)) +- Fixed an off-by-one bug in `UnixAddr::new_abstract` in `::nix::sys::socket`. + ([#429](https://github.com/nix-rust/nix/pull/429)) +- Fixed clone passing a potentially unaligned stack. + ([#490](https://github.com/nix-rust/nix/pull/490)) +- Fixed mkdev not creating a `dev_t` the same way as libc. + ([#508](https://github.com/nix-rust/nix/pull/508)) + +## [0.7.0] 2016-09-09 + +### Added +- Added `lseek` and `lseek64` in `::nix::unistd` + ([#377](https://github.com/nix-rust/nix/pull/377)) +- Added `mkdir` and `getcwd` in `::nix::unistd` + ([#416](https://github.com/nix-rust/nix/pull/416)) +- Added accessors `sigmask_mut` and `sigmask` to `UContext` in + `::nix::ucontext`. + ([#370](https://github.com/nix-rust/nix/pull/370)) +- Added `WUNTRACED` to `WaitPidFlag` in `::nix::sys::wait` for non-_linux_ + targets. + ([#379](https://github.com/nix-rust/nix/pull/379)) +- Added new module `::nix::sys::reboot` with enumeration `RebootMode` and + functions `reboot` and `set_cad_enabled`. Currently for _linux_ only. + ([#386](https://github.com/nix-rust/nix/pull/386)) +- `FdSet` in `::nix::sys::select` now also implements `Clone`. + ([#405](https://github.com/nix-rust/nix/pull/405)) +- Added `F_FULLFSYNC` to `FcntlArg` in `::nix::fcntl` for _apple_ targets. + ([#407](https://github.com/nix-rust/nix/pull/407)) +- Added `CpuSet::unset` in `::nix::sched`. + ([#402](https://github.com/nix-rust/nix/pull/402)) +- Added constructor method `new()` to `PollFd` in `::nix::poll`, in order to + allow creation of objects, after removing public access to members. + ([#399](https://github.com/nix-rust/nix/pull/399)) +- Added method `revents()` to `PollFd` in `::nix::poll`, in order to provide + read access to formerly public member `revents`. + ([#399](https://github.com/nix-rust/nix/pull/399)) +- Added `MSG_CMSG_CLOEXEC` to `MsgFlags` in `::nix::sys::socket` for _linux_ only. + ([#422](https://github.com/nix-rust/nix/pull/422)) + +### Changed +- Replaced the reexported integer constants for signals by the enumeration + `Signal` in `::nix::sys::signal`. + ([#362](https://github.com/nix-rust/nix/pull/362)) +- Renamed `EventFdFlag` to `EfdFlags` in `::nix::sys::eventfd`. + ([#383](https://github.com/nix-rust/nix/pull/383)) +- Changed the result types of `CpuSet::is_set` and `CpuSet::set` in + `::nix::sched` to `Result` and `Result<()>`, respectively. They now + return `EINVAL`, if an invalid argument for the `field` parameter is passed. + ([#402](https://github.com/nix-rust/nix/pull/402)) +- `MqAttr` in `::nix::mqueue` is now an opaque proxy for `::libc::mq_attr`, + which has the same structure as the old `MqAttr`. The field `mq_flags` of + `::libc::mq_attr` is readable using the new method `flags()` of `MqAttr`. + `MqAttr` also no longer implements `Debug`. + ([#392](https://github.com/nix-rust/nix/pull/392)) +- The parameter `msq_prio` of `mq_receive` with type `u32` in `::nix::mqueue` + was replaced by a parameter named `msg_prio` with type `&mut u32`, so that + the message priority can be obtained by the caller. + ([#392](https://github.com/nix-rust/nix/pull/392)) +- The type alias `MQd` in `::nix::queue` was replaced by the type alias + `libc::mqd_t`, both of which are aliases for the same type. + ([#392](https://github.com/nix-rust/nix/pull/392)) + +### Removed +- Type alias `SigNum` from `::nix::sys::signal`. + ([#362](https://github.com/nix-rust/nix/pull/362)) +- Type alias `CpuMask` from `::nix::shed`. + ([#402](https://github.com/nix-rust/nix/pull/402)) +- Removed public fields from `PollFd` in `::nix::poll`. (See also added method + `revents()`. + ([#399](https://github.com/nix-rust/nix/pull/399)) + +### Fixed +- Fixed the build problem for NetBSD (Note, that we currently do not support + it, so it might already be broken again). + ([#389](https://github.com/nix-rust/nix/pull/389)) +- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg + functions on that same OS. + ([#397](https://github.com/nix-rust/nix/pull/397)) + +## [0.6.0] 2016-06-10 + +### Added +- Added `gettid` in `::nix::unistd` for _linux_ and _android_. + ([#293](https://github.com/nix-rust/nix/pull/293)) +- Some _mips_ support in `::nix::sched` and `::nix::sys::syscall`. + ([#301](https://github.com/nix-rust/nix/pull/301)) +- Added `SIGNALFD_SIGINFO_SIZE` in `::nix::sys::signalfd`. + ([#309](https://github.com/nix-rust/nix/pull/309)) +- Added new module `::nix::ucontext` with struct `UContext`. Currently for + _linux_ only. + ([#311](https://github.com/nix-rust/nix/pull/311)) +- Added `EPOLLEXCLUSIVE` to `EpollEventKind` in `::nix::sys::epoll`. + ([#330](https://github.com/nix-rust/nix/pull/330)) +- Added `pause` to `::nix::unistd`. + ([#336](https://github.com/nix-rust/nix/pull/336)) +- Added `sleep` to `::nix::unistd`. + ([#351](https://github.com/nix-rust/nix/pull/351)) +- Added `S_IFDIR`, `S_IFLNK`, `S_IFMT` to `SFlag` in `::nix::sys::stat`. + ([#359](https://github.com/nix-rust/nix/pull/359)) +- Added `clear` and `extend` functions to `SigSet`'s implementation in + `::nix::sys::signal`. + ([#347](https://github.com/nix-rust/nix/pull/347)) +- `sockaddr_storage_to_addr` in `::nix::sys::socket` now supports `sockaddr_nl` + on _linux_ and _android_. + ([#366](https://github.com/nix-rust/nix/pull/366)) +- Added support for `SO_ORIGINAL_DST` in `::nix::sys::socket` on _linux_. + ([#367](https://github.com/nix-rust/nix/pull/367)) +- Added `SIGINFO` in `::nix::sys::signal` for the _macos_ target as well as + `SIGPWR` and `SIGSTKFLT` in `::nix::sys::signal` for non-_macos_ targets. + ([#361](https://github.com/nix-rust/nix/pull/361)) + +### Changed +- Changed the structure `IoVec` in `::nix::sys::uio`. + ([#304](https://github.com/nix-rust/nix/pull/304)) +- Replaced `CREATE_NEW_FD` by `SIGNALFD_NEW` in `::nix::sys::signalfd`. + ([#309](https://github.com/nix-rust/nix/pull/309)) +- Renamed `SaFlag` to `SaFlags` and `SigFlag` to `SigFlags` in + `::nix::sys::signal`. + ([#314](https://github.com/nix-rust/nix/pull/314)) +- Renamed `Fork` to `ForkResult` and changed its fields in `::nix::unistd`. + ([#332](https://github.com/nix-rust/nix/pull/332)) +- Added the `signal` parameter to `clone`'s signature in `::nix::sched`. + ([#344](https://github.com/nix-rust/nix/pull/344)) +- `execv`, `execve`, and `execvp` now return `Result` instead of + `Result<()>` in `::nix::unistd`. + ([#357](https://github.com/nix-rust/nix/pull/357)) + +### Fixed +- Improved the conversion from `std::net::SocketAddr` to `InetAddr` in + `::nix::sys::socket::addr`. + ([#335](https://github.com/nix-rust/nix/pull/335)) + +## [0.5.0] 2016-03-01 diff --git a/utshell-0.5.0/vendor/nix/Cargo.toml b/utshell-0.5.0/vendor/nix/Cargo.toml new file mode 100644 index 00000000..a2b305ca --- /dev/null +++ b/utshell-0.5.0/vendor/nix/Cargo.toml @@ -0,0 +1,185 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.46" +name = "nix" +version = "0.25.1" +authors = ["The nix-rust Project Developers"] +include = [ + "src/**/*", + "test/**/*", + "LICENSE", + "README.md", + "CHANGELOG.md", +] +description = "Rust friendly bindings to *nix APIs" +readme = "README.md" +categories = ["os::unix-apis"] +license = "MIT" +repository = "https://github.com/nix-rust/nix" + +[package.metadata.docs.rs] +rustdoc-args = [ + "--cfg", + "docsrs", +] +targets = [ + "x86_64-unknown-linux-gnu", + "aarch64-linux-android", + "x86_64-apple-darwin", + "aarch64-apple-ios", + "x86_64-unknown-freebsd", + "x86_64-unknown-openbsd", + "x86_64-unknown-netbsd", + "x86_64-unknown-dragonfly", + "x86_64-fuchsia", + "x86_64-unknown-redox", + "x86_64-unknown-illumos", +] + +[[test]] +name = "test" +path = "test/test.rs" + +[[test]] +name = "test-aio-drop" +path = "test/sys/test_aio_drop.rs" + +[[test]] +name = "test-clearenv" +path = "test/test_clearenv.rs" + +[[test]] +name = "test-mount" +path = "test/test_mount.rs" +harness = false + +[[test]] +name = "test-ptymaster-drop" +path = "test/test_ptymaster_drop.rs" + +[dependencies.bitflags] +version = "1.1" + +[dependencies.cfg-if] +version = "1.0" + +[dependencies.libc] +version = "0.2.127" +features = ["extra_traits"] + +[dependencies.pin-utils] +version = "0.1.0" +optional = true + +[dev-dependencies.assert-impl] +version = "0.1" + +[dev-dependencies.lazy_static] +version = "1.4" + +[dev-dependencies.parking_lot] +version = "0.11.2" + +[dev-dependencies.rand] +version = "0.8" + +[dev-dependencies.semver] +version = "1.0.7" + +[dev-dependencies.tempfile] +version = "3.3.0" + +[build-dependencies.autocfg] +version = "1.1.0" + +[features] +acct = [] +aio = ["pin-utils"] +default = [ + "acct", + "aio", + "dir", + "env", + "event", + "feature", + "fs", + "hostname", + "inotify", + "ioctl", + "kmod", + "mman", + "mount", + "mqueue", + "net", + "personality", + "poll", + "process", + "pthread", + "ptrace", + "quota", + "reboot", + "resource", + "sched", + "signal", + "socket", + "term", + "time", + "ucontext", + "uio", + "user", + "zerocopy", +] +dir = ["fs"] +env = [] +event = [] +feature = [] +fs = [] +hostname = [] +inotify = [] +ioctl = [] +kmod = [] +mman = [] +mount = ["uio"] +mqueue = ["fs"] +net = ["socket"] +personality = [] +poll = [] +process = [] +pthread = [] +ptrace = ["process"] +quota = [] +reboot = [] +resource = [] +sched = ["process"] +signal = ["process"] +socket = ["memoffset"] +term = [] +time = [] +ucontext = ["signal"] +uio = [] +user = ["feature"] +zerocopy = [ + "fs", + "uio", +] + +[target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dev-dependencies.caps] +version = "0.5.3" + +[target."cfg(not(target_os = \"redox\"))".dependencies.memoffset] +version = "0.6.3" +optional = true + +[target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl] +version = "0.4" diff --git a/utshell-0.5.0/vendor/nix/LICENSE b/utshell-0.5.0/vendor/nix/LICENSE new file mode 100644 index 00000000..aff9096f --- /dev/null +++ b/utshell-0.5.0/vendor/nix/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Carl Lerche + nix-rust Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/nix/README.md b/utshell-0.5.0/vendor/nix/README.md new file mode 100644 index 00000000..7c13cf20 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/README.md @@ -0,0 +1,105 @@ +# Rust bindings to *nix APIs + +[![Cirrus Build Status](https://api.cirrus-ci.com/github/nix-rust/nix.svg)](https://cirrus-ci.com/github/nix-rust/nix) +[![crates.io](https://img.shields.io/crates/v/nix.svg)](https://crates.io/crates/nix) + +[Documentation (Releases)](https://docs.rs/nix/) + +Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin, +...). The goal is to not provide a 100% unified interface, but to unify +what can be while still providing platform specific APIs. + +For many system APIs, Nix provides a safe alternative to the unsafe APIs +exposed by the [libc crate](https://github.com/rust-lang/libc). This is done by +wrapping the libc functionality with types/abstractions that enforce legal/safe +usage. + + +As an example of what Nix provides, examine the differences between what is +exposed by libc and nix for the +[gethostname](https://man7.org/linux/man-pages/man2/gethostname.2.html) system +call: + +```rust,ignore +// libc api (unsafe, requires handling return code/errno) +pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int; + +// nix api (returns a nix::Result) +pub fn gethostname() -> Result; +``` + +## Supported Platforms + +nix target support consists of two tiers. While nix attempts to support all +platforms supported by [libc](https://github.com/rust-lang/libc), only some +platforms are actively supported due to either technical or manpower +limitations. Support for platforms is split into three tiers: + + * Tier 1 - Builds and tests for this target are run in CI. Failures of either + block the inclusion of new code. + * Tier 2 - Builds for this target are run in CI. Failures during the build + blocks the inclusion of new code. Tests may be run, but failures + in tests don't block the inclusion of new code. + * Tier 3 - Builds for this target are run in CI. Failures during the build + *do not* block the inclusion of new code. Testing may be run, but + failures in tests don't block the inclusion of new code. + +The following targets are supported by `nix`: + +Tier 1: + * aarch64-unknown-linux-gnu + * arm-unknown-linux-gnueabi + * armv7-unknown-linux-gnueabihf + * i686-unknown-freebsd + * i686-unknown-linux-gnu + * i686-unknown-linux-musl + * mips-unknown-linux-gnu + * mips64-unknown-linux-gnuabi64 + * mips64el-unknown-linux-gnuabi64 + * mipsel-unknown-linux-gnu + * powerpc64le-unknown-linux-gnu + * x86_64-apple-darwin + * x86_64-unknown-freebsd + * x86_64-unknown-linux-gnu + * x86_64-unknown-linux-musl + +Tier 2: + * aarch64-apple-darwin + * aarch64-apple-ios + * aarch64-linux-android + * arm-linux-androideabi + * arm-unknown-linux-musleabi + * armv7-linux-androideabi + * i686-linux-android + * powerpc-unknown-linux-gnu + * s390x-unknown-linux-gnu + * x86_64-apple-ios + * x86_64-linux-android + * x86_64-unknown-illumos + * x86_64-unknown-netbsd + +Tier 3: + * armv7-unknown-linux-uclibceabihf + * x86_64-fuchsia + * x86_64-unknown-dragonfly + * x86_64-unknown-haiku + * x86_64-unknown-linux-gnux32 + * x86_64-unknown-openbsd + * x86_64-unknown-redox + +## Minimum Supported Rust Version (MSRV) + +nix is supported on Rust 1.46.0 and higher. Its MSRV will not be +changed in the future without bumping the major or minor version. + +## Contributing + +Contributions are very welcome. Please See [CONTRIBUTING](CONTRIBUTING.md) for +additional details. + +Feel free to join us in [the nix-rust/nix](https://gitter.im/nix-rust/nix) channel on Gitter to +discuss `nix` development. + +## License + +Nix is licensed under the MIT license. See [LICENSE](LICENSE) for more details. diff --git a/utshell-0.5.0/vendor/nix/src/dir.rs b/utshell-0.5.0/vendor/nix/src/dir.rs new file mode 100644 index 00000000..8b41db60 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/dir.rs @@ -0,0 +1,259 @@ +//! List directory contents + +use crate::{Error, NixPath, Result}; +use crate::errno::Errno; +use crate::fcntl::{self, OFlag}; +use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; +use std::ptr; +use std::ffi; +use crate::sys; +use cfg_if::cfg_if; + +#[cfg(target_os = "linux")] +use libc::{dirent64 as dirent, readdir64_r as readdir_r}; + +#[cfg(not(target_os = "linux"))] +use libc::{dirent, readdir_r}; + +/// An open directory. +/// +/// This is a lower-level interface than `std::fs::ReadDir`. Notable differences: +/// * can be opened from a file descriptor (as returned by `openat`, perhaps before knowing +/// if the path represents a file or directory). +/// * implements `AsRawFd`, so it can be passed to `fstat`, `openat`, etc. +/// The file descriptor continues to be owned by the `Dir`, so callers must not keep a `RawFd` +/// after the `Dir` is dropped. +/// * can be iterated through multiple times without closing and reopening the file +/// descriptor. Each iteration rewinds when finished. +/// * returns entries for `.` (current directory) and `..` (parent directory). +/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc +/// does). +#[derive(Debug, Eq, Hash, PartialEq)] +pub struct Dir( + ptr::NonNull +); + +impl Dir { + /// Opens the given path as with `fcntl::open`. + pub fn open(path: &P, oflag: OFlag, + mode: sys::stat::Mode) -> Result { + let fd = fcntl::open(path, oflag, mode)?; + Dir::from_fd(fd) + } + + /// Opens the given path as with `fcntl::openat`. + pub fn openat(dirfd: RawFd, path: &P, oflag: OFlag, + mode: sys::stat::Mode) -> Result { + let fd = fcntl::openat(dirfd, path, oflag, mode)?; + Dir::from_fd(fd) + } + + /// Converts from a descriptor-based object, closing the descriptor on success or failure. + #[inline] + pub fn from(fd: F) -> Result { + Dir::from_fd(fd.into_raw_fd()) + } + + /// Converts from a file descriptor, closing it on success or failure. + #[cfg_attr(has_doc_alias, doc(alias("fdopendir")))] + pub fn from_fd(fd: RawFd) -> Result { + let d = ptr::NonNull::new(unsafe { libc::fdopendir(fd) }).ok_or_else(|| { + let e = Error::last(); + unsafe { libc::close(fd) }; + e + })?; + Ok(Dir(d)) + } + + /// Returns an iterator of `Result` which rewinds when finished. + pub fn iter(&mut self) -> Iter { + Iter(self) + } +} + +// `Dir` is not `Sync`. With the current implementation, it could be, but according to +// https://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html, +// future versions of POSIX are likely to obsolete `readdir_r` and specify that it's unsafe to +// call `readdir` simultaneously from multiple threads. +// +// `Dir` is safe to pass from one thread to another, as it's not reference-counted. +unsafe impl Send for Dir {} + +impl AsRawFd for Dir { + fn as_raw_fd(&self) -> RawFd { + unsafe { libc::dirfd(self.0.as_ptr()) } + } +} + +impl Drop for Dir { + fn drop(&mut self) { + let e = Errno::result(unsafe { libc::closedir(self.0.as_ptr()) }); + if !std::thread::panicking() && e == Err(Errno::EBADF) { + panic!("Closing an invalid file descriptor!"); + }; + } +} + +fn next(dir: &mut Dir) -> Option> { + unsafe { + // Note: POSIX specifies that portable applications should dynamically allocate a + // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1 + // for the NUL byte. It doesn't look like the std library does this; it just uses + // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate). + // Probably fine here too then. + let mut ent = std::mem::MaybeUninit::::uninit(); + let mut result = ptr::null_mut(); + if let Err(e) = Errno::result( + readdir_r(dir.0.as_ptr(), ent.as_mut_ptr(), &mut result)) + { + return Some(Err(e)); + } + if result.is_null() { + return None; + } + assert_eq!(result, ent.as_mut_ptr()); + Some(Ok(Entry(ent.assume_init()))) + } +} + +/// Return type of [`Dir::iter`]. +#[derive(Debug, Eq, Hash, PartialEq)] +pub struct Iter<'d>(&'d mut Dir); + +impl<'d> Iterator for Iter<'d> { + type Item = Result; + + fn next(&mut self) -> Option { + next(self.0) + } +} + +impl<'d> Drop for Iter<'d> { + fn drop(&mut self) { + unsafe { libc::rewinddir((self.0).0.as_ptr()) } + } +} + +/// The return type of [Dir::into_iter] +#[derive(Debug, Eq, Hash, PartialEq)] +pub struct OwningIter(Dir); + +impl Iterator for OwningIter { + type Item = Result; + + fn next(&mut self) -> Option { + next(&mut self.0) + } +} + +/// The file descriptor continues to be owned by the `OwningIter`, +/// so callers must not keep a `RawFd` after the `OwningIter` is dropped. +impl AsRawFd for OwningIter { + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() + } +} + +impl IntoIterator for Dir { + type Item = Result; + type IntoIter = OwningIter; + + /// Creates a owning iterator, that is, one that takes ownership of the + /// `Dir`. The `Dir` cannot be used after calling this. This can be useful + /// when you have a function that both creates a `Dir` instance and returns + /// an `Iterator`. + /// + /// Example: + /// + /// ``` + /// use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode}; + /// use std::{iter::Iterator, string::String}; + /// + /// fn ls_upper(dirname: &str) -> impl Iterator { + /// let d = Dir::open(dirname, OFlag::O_DIRECTORY, Mode::S_IXUSR).unwrap(); + /// d.into_iter().map(|x| x.unwrap().file_name().as_ref().to_string_lossy().to_ascii_uppercase()) + /// } + /// ``` + fn into_iter(self) -> Self::IntoIter { + OwningIter(self) + } +} + +/// A directory entry, similar to `std::fs::DirEntry`. +/// +/// Note that unlike the std version, this may represent the `.` or `..` entries. +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct Entry(dirent); + +/// Type of file referenced by a directory entry +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +pub enum Type { + /// FIFO (Named pipe) + Fifo, + /// Character device + CharacterDevice, + /// Directory + Directory, + /// Block device + BlockDevice, + /// Regular file + File, + /// Symbolic link + Symlink, + /// Unix-domain socket + Socket, +} + +impl Entry { + /// Returns the inode number (`d_ino`) of the underlying `dirent`. + #[allow(clippy::useless_conversion)] // Not useless on all OSes + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + pub fn ino(&self) -> u64 { + cfg_if! { + if #[cfg(any(target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "l4re", + target_os = "linux", + target_os = "macos", + target_os = "solaris"))] { + self.0.d_ino as u64 + } else { + u64::from(self.0.d_fileno) + } + } + } + + /// Returns the bare file name of this directory entry without any other leading path component. + pub fn file_name(&self) -> &ffi::CStr { + unsafe { ::std::ffi::CStr::from_ptr(self.0.d_name.as_ptr()) } + } + + /// Returns the type of this directory entry, if known. + /// + /// See platform `readdir(3)` or `dirent(5)` manpage for when the file type is known; + /// notably, some Linux filesystems don't implement this. The caller should use `stat` or + /// `fstat` if this returns `None`. + pub fn file_type(&self) -> Option { + #[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))] + match self.0.d_type { + libc::DT_FIFO => Some(Type::Fifo), + libc::DT_CHR => Some(Type::CharacterDevice), + libc::DT_DIR => Some(Type::Directory), + libc::DT_BLK => Some(Type::BlockDevice), + libc::DT_REG => Some(Type::File), + libc::DT_LNK => Some(Type::Symlink), + libc::DT_SOCK => Some(Type::Socket), + /* libc::DT_UNKNOWN | */ _ => None, + } + + // illumos, Solaris, and Haiku systems do not have the d_type member at all: + #[cfg(any(target_os = "illumos", target_os = "solaris", target_os = "haiku"))] + None + } +} diff --git a/utshell-0.5.0/vendor/nix/src/env.rs b/utshell-0.5.0/vendor/nix/src/env.rs new file mode 100644 index 00000000..95177a1d --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/env.rs @@ -0,0 +1,64 @@ +//! Environment variables +use cfg_if::cfg_if; +use std::fmt; + +/// Indicates that [`clearenv`] failed for some unknown reason +#[derive(Clone, Copy, Debug)] +pub struct ClearEnvError; + +impl fmt::Display for ClearEnvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "clearenv failed") + } +} + +impl std::error::Error for ClearEnvError {} + +/// Clear the environment of all name-value pairs. +/// +/// On platforms where libc provides `clearenv()`, it will be used. libc's +/// `clearenv()` is documented to return an error code but not set errno; if the +/// return value indicates a failure, this function will return +/// [`ClearEnvError`]. +/// +/// On platforms where libc does not provide `clearenv()`, a fallback +/// implementation will be used that iterates over all environment variables and +/// removes them one-by-one. +/// +/// # Safety +/// +/// This function is not threadsafe and can cause undefined behavior in +/// combination with `std::env` or other program components that access the +/// environment. See, for example, the discussion on `std::env::remove_var`; this +/// function is a case of an "inherently unsafe non-threadsafe API" dealing with +/// the environment. +/// +/// The caller must ensure no other threads access the process environment while +/// this function executes and that no raw pointers to an element of libc's +/// `environ` is currently held. The latter is not an issue if the only other +/// environment access in the program is via `std::env`, but the requirement on +/// thread safety must still be upheld. +pub unsafe fn clearenv() -> std::result::Result<(), ClearEnvError> { + cfg_if! { + if #[cfg(any(target_os = "fuchsia", + target_os = "wasi", + target_env = "uclibc", + target_os = "linux", + target_os = "android", + target_os = "emscripten"))] { + let ret = libc::clearenv(); + } else { + use std::env; + for (name, _) in env::vars_os() { + env::remove_var(name); + } + let ret = 0; + } + } + + if ret == 0 { + Ok(()) + } else { + Err(ClearEnvError) + } +} diff --git a/utshell-0.5.0/vendor/nix/src/errno.rs b/utshell-0.5.0/vendor/nix/src/errno.rs new file mode 100644 index 00000000..0c5b0eda --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/errno.rs @@ -0,0 +1,3286 @@ +use crate::{Error, Result}; +use cfg_if::cfg_if; +use libc::{c_int, c_void}; +use std::convert::TryFrom; +use std::{error, fmt, io}; + +pub use self::consts::*; + +cfg_if! { + if #[cfg(any(target_os = "freebsd", + target_os = "ios", + target_os = "macos"))] { + unsafe fn errno_location() -> *mut c_int { + libc::__error() + } + } else if #[cfg(any(target_os = "android", + target_os = "netbsd", + target_os = "openbsd"))] { + unsafe fn errno_location() -> *mut c_int { + libc::__errno() + } + } else if #[cfg(any(target_os = "linux", + target_os = "redox", + target_os = "dragonfly", + target_os = "fuchsia"))] { + unsafe fn errno_location() -> *mut c_int { + libc::__errno_location() + } + } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] { + unsafe fn errno_location() -> *mut c_int { + libc::___errno() + } + } else if #[cfg(any(target_os = "haiku",))] { + unsafe fn errno_location() -> *mut c_int { + libc::_errnop() + } + } +} + +/// Sets the platform-specific errno to no-error +fn clear() { + // Safe because errno is a thread-local variable + unsafe { + *errno_location() = 0; + } +} + +/// Returns the platform-specific value of errno +pub fn errno() -> i32 { + unsafe { *errno_location() } +} + +impl Errno { + /// Convert this `Error` to an [`Errno`](enum.Errno.html). + /// + /// # Example + /// + /// ``` + /// # use nix::Error; + /// # use nix::errno::Errno; + /// let e = Error::from(Errno::EPERM); + /// assert_eq!(Some(Errno::EPERM), e.as_errno()); + /// ``` + #[deprecated(since = "0.22.0", note = "It's a no-op now; just delete it.")] + pub const fn as_errno(self) -> Option { + Some(self) + } + + /// Create a nix Error from a given errno + #[deprecated(since = "0.22.0", note = "It's a no-op now; just delete it.")] + #[allow(clippy::wrong_self_convention)] // False positive + pub fn from_errno(errno: Errno) -> Error { + errno + } + + /// Create a new invalid argument error (`EINVAL`) + #[deprecated(since = "0.22.0", note = "Use Errno::EINVAL instead")] + pub const fn invalid_argument() -> Error { + Errno::EINVAL + } + + pub fn last() -> Self { + last() + } + + pub fn desc(self) -> &'static str { + desc(self) + } + + pub const fn from_i32(err: i32) -> Errno { + from_i32(err) + } + + pub fn clear() { + clear() + } + + /// Returns `Ok(value)` if it does not contain the sentinel value. This + /// should not be used when `-1` is not the errno sentinel value. + #[inline] + pub fn result>(value: S) -> Result { + if value == S::sentinel() { + Err(Self::last()) + } else { + Ok(value) + } + } + + /// Backwards compatibility hack for Nix <= 0.21.0 users + /// + /// In older versions of Nix, `Error::Sys` was an enum variant. Now it's a + /// function, which is compatible with most of the former use cases of the + /// enum variant. But you should use `Error(Errno::...)` instead. + #[deprecated(since = "0.22.0", note = "Use Errno::... instead")] + #[allow(non_snake_case)] + #[inline] + pub const fn Sys(errno: Errno) -> Error { + errno + } +} + +/// The sentinel value indicates that a function failed and more detailed +/// information about the error can be found in `errno` +pub trait ErrnoSentinel: Sized { + fn sentinel() -> Self; +} + +impl ErrnoSentinel for isize { + fn sentinel() -> Self { + -1 + } +} + +impl ErrnoSentinel for i32 { + fn sentinel() -> Self { + -1 + } +} + +impl ErrnoSentinel for i64 { + fn sentinel() -> Self { + -1 + } +} + +impl ErrnoSentinel for *mut c_void { + fn sentinel() -> Self { + -1isize as *mut c_void + } +} + +impl ErrnoSentinel for libc::sighandler_t { + fn sentinel() -> Self { + libc::SIG_ERR + } +} + +impl error::Error for Errno {} + +impl fmt::Display for Errno { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}: {}", self, self.desc()) + } +} + +impl From for io::Error { + fn from(err: Errno) -> Self { + io::Error::from_raw_os_error(err as i32) + } +} + +impl TryFrom for Errno { + type Error = io::Error; + + fn try_from(ioerror: io::Error) -> std::result::Result { + ioerror.raw_os_error().map(Errno::from_i32).ok_or(ioerror) + } +} + +fn last() -> Errno { + Errno::from_i32(errno()) +} + +fn desc(errno: Errno) -> &'static str { + use self::Errno::*; + match errno { + UnknownErrno => "Unknown errno", + EPERM => "Operation not permitted", + ENOENT => "No such file or directory", + ESRCH => "No such process", + EINTR => "Interrupted system call", + EIO => "I/O error", + ENXIO => "No such device or address", + E2BIG => "Argument list too long", + ENOEXEC => "Exec format error", + EBADF => "Bad file number", + ECHILD => "No child processes", + EAGAIN => "Try again", + ENOMEM => "Out of memory", + EACCES => "Permission denied", + EFAULT => "Bad address", + #[cfg(not(target_os = "haiku"))] + ENOTBLK => "Block device required", + EBUSY => "Device or resource busy", + EEXIST => "File exists", + EXDEV => "Cross-device link", + ENODEV => "No such device", + ENOTDIR => "Not a directory", + EISDIR => "Is a directory", + EINVAL => "Invalid argument", + ENFILE => "File table overflow", + EMFILE => "Too many open files", + ENOTTY => "Not a typewriter", + ETXTBSY => "Text file busy", + EFBIG => "File too large", + ENOSPC => "No space left on device", + ESPIPE => "Illegal seek", + EROFS => "Read-only file system", + EMLINK => "Too many links", + EPIPE => "Broken pipe", + EDOM => "Math argument out of domain of func", + ERANGE => "Math result not representable", + EDEADLK => "Resource deadlock would occur", + ENAMETOOLONG => "File name too long", + ENOLCK => "No record locks available", + ENOSYS => "Function not implemented", + ENOTEMPTY => "Directory not empty", + ELOOP => "Too many symbolic links encountered", + ENOMSG => "No message of desired type", + EIDRM => "Identifier removed", + EINPROGRESS => "Operation now in progress", + EALREADY => "Operation already in progress", + ENOTSOCK => "Socket operation on non-socket", + EDESTADDRREQ => "Destination address required", + EMSGSIZE => "Message too long", + EPROTOTYPE => "Protocol wrong type for socket", + ENOPROTOOPT => "Protocol not available", + EPROTONOSUPPORT => "Protocol not supported", + #[cfg(not(target_os = "haiku"))] + ESOCKTNOSUPPORT => "Socket type not supported", + #[cfg(not(target_os = "haiku"))] + EPFNOSUPPORT => "Protocol family not supported", + #[cfg(not(target_os = "haiku"))] + EAFNOSUPPORT => "Address family not supported by protocol", + EADDRINUSE => "Address already in use", + EADDRNOTAVAIL => "Cannot assign requested address", + ENETDOWN => "Network is down", + ENETUNREACH => "Network is unreachable", + ENETRESET => "Network dropped connection because of reset", + ECONNABORTED => "Software caused connection abort", + ECONNRESET => "Connection reset by peer", + ENOBUFS => "No buffer space available", + EISCONN => "Transport endpoint is already connected", + ENOTCONN => "Transport endpoint is not connected", + ESHUTDOWN => "Cannot send after transport endpoint shutdown", + #[cfg(not(target_os = "haiku"))] + ETOOMANYREFS => "Too many references: cannot splice", + ETIMEDOUT => "Connection timed out", + ECONNREFUSED => "Connection refused", + EHOSTDOWN => "Host is down", + EHOSTUNREACH => "No route to host", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ECHRNG => "Channel number out of range", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EL2NSYNC => "Level 2 not synchronized", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EL3HLT => "Level 3 halted", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EL3RST => "Level 3 reset", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ELNRNG => "Link number out of range", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EUNATCH => "Protocol driver not attached", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOCSI => "No CSI structure available", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EL2HLT => "Level 2 halted", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EBADE => "Invalid exchange", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EBADR => "Invalid request descriptor", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EXFULL => "Exchange full", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOANO => "No anode", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EBADRQC => "Invalid request code", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EBADSLT => "Invalid slot", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EBFONT => "Bad font file format", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOSTR => "Device not a stream", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENODATA => "No data available", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ETIME => "Timer expired", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOSR => "Out of streams resources", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENONET => "Machine is not on the network", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOPKG => "Package not installed", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EREMOTE => "Object is remote", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOLINK => "Link has been severed", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EADV => "Advertise error", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ESRMNT => "Srmount error", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ECOMM => "Communication error on send", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EPROTO => "Protocol error", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EMULTIHOP => "Multihop attempted", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EDOTDOT => "RFS specific error", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EBADMSG => "Not a data message", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + EBADMSG => "Trying to read unreadable message", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia", + target_os = "haiku" + ))] + EOVERFLOW => "Value too large for defined data type", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ENOTUNIQ => "Name not unique on network", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EBADFD => "File descriptor in bad state", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EREMCHG => "Remote address changed", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ELIBACC => "Can not access a needed shared library", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ELIBBAD => "Accessing a corrupted shared library", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ELIBSCN => ".lib section in a.out corrupted", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ELIBMAX => "Attempting to link in too many shared libraries", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ELIBEXEC => "Cannot exec a shared library directly", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia", + target_os = "openbsd" + ))] + EILSEQ => "Illegal byte sequence", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ERESTART => "Interrupted system call should be restarted", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + ESTRPIPE => "Streams pipe error", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia" + ))] + EUSERS => "Too many users", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia", + target_os = "netbsd", + target_os = "redox" + ))] + EOPNOTSUPP => "Operation not supported on transport endpoint", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + ESTALE => "Stale file handle", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EUCLEAN => "Structure needs cleaning", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + ENOTNAM => "Not a XENIX named type file", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + ENAVAIL => "No XENIX semaphores available", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EISNAM => "Is a named type file", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EREMOTEIO => "Remote I/O error", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EDQUOT => "Quota exceeded", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia", + target_os = "openbsd", + target_os = "dragonfly" + ))] + ENOMEDIUM => "No medium found", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia", + target_os = "openbsd" + ))] + EMEDIUMTYPE => "Wrong medium type", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "fuchsia", + target_os = "haiku" + ))] + ECANCELED => "Operation canceled", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + ENOKEY => "Required key not available", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EKEYEXPIRED => "Key has expired", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EKEYREVOKED => "Key has been revoked", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EKEYREJECTED => "Key was rejected by service", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + EOWNERDEAD => "Owner died", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + EOWNERDEAD => "Process died with lock", + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia" + ))] + ENOTRECOVERABLE => "State not recoverable", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + ENOTRECOVERABLE => "Lock is not recoverable", + + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "fuchsia" + ))] + ERFKILL => "Operation not possible due to RF-kill", + + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "fuchsia" + ))] + EHWPOISON => "Memory page has hardware error", + + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + EDOOFUS => "Programming error", + + #[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "redox" + ))] + EMULTIHOP => "Multihop attempted", + + #[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "redox" + ))] + ENOLINK => "Link has been severed", + + #[cfg(target_os = "freebsd")] + ENOTCAPABLE => "Capabilities insufficient", + + #[cfg(target_os = "freebsd")] + ECAPMODE => "Not permitted in capability mode", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + ENEEDAUTH => "Need authenticator", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox", + target_os = "illumos", + target_os = "solaris" + ))] + EOVERFLOW => "Value too large to be stored in data type", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "netbsd", + target_os = "redox", + target_os = "haiku" + ))] + EILSEQ => "Illegal byte sequence", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "haiku" + ))] + ENOATTR => "Attribute not found", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox", + target_os = "haiku" + ))] + EBADMSG => "Bad message", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox", + target_os = "haiku" + ))] + EPROTO => "Protocol error", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd" + ))] + ENOTRECOVERABLE => "State not recoverable", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd" + ))] + EOWNERDEAD => "Previous owner died", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris", + target_os = "haiku" + ))] + ENOTSUP => "Operation not supported", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EPROCLIM => "Too many processes", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox" + ))] + EUSERS => "Too many users", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox", + target_os = "illumos", + target_os = "solaris", + target_os = "haiku" + ))] + EDQUOT => "Disc quota exceeded", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox", + target_os = "illumos", + target_os = "solaris", + target_os = "haiku" + ))] + ESTALE => "Stale NFS file handle", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox" + ))] + EREMOTE => "Too many levels of remote in path", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EBADRPC => "RPC struct is bad", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + ERPCMISMATCH => "RPC version wrong", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EPROGUNAVAIL => "RPC prog. not avail", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EPROGMISMATCH => "Program version wrong", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EPROCUNAVAIL => "Bad procedure for program", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EFTYPE => "Inappropriate file type or format", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd" + ))] + EAUTH => "Authentication error", + + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "openbsd", + target_os = "netbsd", + target_os = "redox" + ))] + ECANCELED => "Operation canceled", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + EPWROFF => "Device power is off", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + EDEVERR => "Device error, e.g. paper out", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + EBADEXEC => "Bad executable", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + EBADARCH => "Bad CPU type in executable", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + ESHLIBVERS => "Shared library version mismatch", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + EBADMACHO => "Malformed Macho file", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "netbsd", + target_os = "haiku" + ))] + EMULTIHOP => "Reserved", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "netbsd", + target_os = "redox" + ))] + ENODATA => "No message available on STREAM", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "netbsd", + target_os = "haiku" + ))] + ENOLINK => "Reserved", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "netbsd", + target_os = "redox" + ))] + ENOSR => "No STREAM resources", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "netbsd", + target_os = "redox" + ))] + ENOSTR => "Not a STREAM", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "netbsd", + target_os = "redox" + ))] + ETIME => "STREAM ioctl timeout", + + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "illumos", + target_os = "solaris" + ))] + EOPNOTSUPP => "Operation not supported on socket", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + ENOPOLICY => "No such policy registered", + + #[cfg(any(target_os = "macos", target_os = "ios"))] + EQFULL => "Interface output queue is full", + + #[cfg(target_os = "openbsd")] + EOPNOTSUPP => "Operation not supported", + + #[cfg(target_os = "openbsd")] + EIPSEC => "IPsec processing failure", + + #[cfg(target_os = "dragonfly")] + EASYNC => "Async", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + EDEADLOCK => "Resource deadlock would occur", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + ELOCKUNMAPPED => "Locked lock was unmapped", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + ENOTACTIVE => "Facility is not active", + } +} + +#[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EAGAIN = libc::EAGAIN, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EDEADLK = libc::EDEADLK, + ENAMETOOLONG = libc::ENAMETOOLONG, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + ENOTEMPTY = libc::ENOTEMPTY, + ELOOP = libc::ELOOP, + ENOMSG = libc::ENOMSG, + EIDRM = libc::EIDRM, + ECHRNG = libc::ECHRNG, + EL2NSYNC = libc::EL2NSYNC, + EL3HLT = libc::EL3HLT, + EL3RST = libc::EL3RST, + ELNRNG = libc::ELNRNG, + EUNATCH = libc::EUNATCH, + ENOCSI = libc::ENOCSI, + EL2HLT = libc::EL2HLT, + EBADE = libc::EBADE, + EBADR = libc::EBADR, + EXFULL = libc::EXFULL, + ENOANO = libc::ENOANO, + EBADRQC = libc::EBADRQC, + EBADSLT = libc::EBADSLT, + EBFONT = libc::EBFONT, + ENOSTR = libc::ENOSTR, + ENODATA = libc::ENODATA, + ETIME = libc::ETIME, + ENOSR = libc::ENOSR, + ENONET = libc::ENONET, + ENOPKG = libc::ENOPKG, + EREMOTE = libc::EREMOTE, + ENOLINK = libc::ENOLINK, + EADV = libc::EADV, + ESRMNT = libc::ESRMNT, + ECOMM = libc::ECOMM, + EPROTO = libc::EPROTO, + EMULTIHOP = libc::EMULTIHOP, + EDOTDOT = libc::EDOTDOT, + EBADMSG = libc::EBADMSG, + EOVERFLOW = libc::EOVERFLOW, + ENOTUNIQ = libc::ENOTUNIQ, + EBADFD = libc::EBADFD, + EREMCHG = libc::EREMCHG, + ELIBACC = libc::ELIBACC, + ELIBBAD = libc::ELIBBAD, + ELIBSCN = libc::ELIBSCN, + ELIBMAX = libc::ELIBMAX, + ELIBEXEC = libc::ELIBEXEC, + EILSEQ = libc::EILSEQ, + ERESTART = libc::ERESTART, + ESTRPIPE = libc::ESTRPIPE, + EUSERS = libc::EUSERS, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + EOPNOTSUPP = libc::EOPNOTSUPP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + EALREADY = libc::EALREADY, + EINPROGRESS = libc::EINPROGRESS, + ESTALE = libc::ESTALE, + EUCLEAN = libc::EUCLEAN, + ENOTNAM = libc::ENOTNAM, + ENAVAIL = libc::ENAVAIL, + EISNAM = libc::EISNAM, + EREMOTEIO = libc::EREMOTEIO, + EDQUOT = libc::EDQUOT, + ENOMEDIUM = libc::ENOMEDIUM, + EMEDIUMTYPE = libc::EMEDIUMTYPE, + ECANCELED = libc::ECANCELED, + ENOKEY = libc::ENOKEY, + EKEYEXPIRED = libc::EKEYEXPIRED, + EKEYREVOKED = libc::EKEYREVOKED, + EKEYREJECTED = libc::EKEYREJECTED, + EOWNERDEAD = libc::EOWNERDEAD, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + #[cfg(not(any(target_os = "android", target_arch = "mips")))] + ERFKILL = libc::ERFKILL, + #[cfg(not(any(target_os = "android", target_arch = "mips")))] + EHWPOISON = libc::EHWPOISON, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EDEADLOCK instead" + )] + pub const EDEADLOCK: Errno = Errno::EDEADLK; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ENOTSUP instead" + )] + pub const ENOTSUP: Errno = Errno::EOPNOTSUPP; + + impl Errno { + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + pub const EDEADLOCK: Errno = Errno::EDEADLK; + pub const ENOTSUP: Errno = Errno::EOPNOTSUPP; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EAGAIN => EAGAIN, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EDEADLK => EDEADLK, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::ENOTEMPTY => ENOTEMPTY, + libc::ELOOP => ELOOP, + libc::ENOMSG => ENOMSG, + libc::EIDRM => EIDRM, + libc::ECHRNG => ECHRNG, + libc::EL2NSYNC => EL2NSYNC, + libc::EL3HLT => EL3HLT, + libc::EL3RST => EL3RST, + libc::ELNRNG => ELNRNG, + libc::EUNATCH => EUNATCH, + libc::ENOCSI => ENOCSI, + libc::EL2HLT => EL2HLT, + libc::EBADE => EBADE, + libc::EBADR => EBADR, + libc::EXFULL => EXFULL, + libc::ENOANO => ENOANO, + libc::EBADRQC => EBADRQC, + libc::EBADSLT => EBADSLT, + libc::EBFONT => EBFONT, + libc::ENOSTR => ENOSTR, + libc::ENODATA => ENODATA, + libc::ETIME => ETIME, + libc::ENOSR => ENOSR, + libc::ENONET => ENONET, + libc::ENOPKG => ENOPKG, + libc::EREMOTE => EREMOTE, + libc::ENOLINK => ENOLINK, + libc::EADV => EADV, + libc::ESRMNT => ESRMNT, + libc::ECOMM => ECOMM, + libc::EPROTO => EPROTO, + libc::EMULTIHOP => EMULTIHOP, + libc::EDOTDOT => EDOTDOT, + libc::EBADMSG => EBADMSG, + libc::EOVERFLOW => EOVERFLOW, + libc::ENOTUNIQ => ENOTUNIQ, + libc::EBADFD => EBADFD, + libc::EREMCHG => EREMCHG, + libc::ELIBACC => ELIBACC, + libc::ELIBBAD => ELIBBAD, + libc::ELIBSCN => ELIBSCN, + libc::ELIBMAX => ELIBMAX, + libc::ELIBEXEC => ELIBEXEC, + libc::EILSEQ => EILSEQ, + libc::ERESTART => ERESTART, + libc::ESTRPIPE => ESTRPIPE, + libc::EUSERS => EUSERS, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::EALREADY => EALREADY, + libc::EINPROGRESS => EINPROGRESS, + libc::ESTALE => ESTALE, + libc::EUCLEAN => EUCLEAN, + libc::ENOTNAM => ENOTNAM, + libc::ENAVAIL => ENAVAIL, + libc::EISNAM => EISNAM, + libc::EREMOTEIO => EREMOTEIO, + libc::EDQUOT => EDQUOT, + libc::ENOMEDIUM => ENOMEDIUM, + libc::EMEDIUMTYPE => EMEDIUMTYPE, + libc::ECANCELED => ECANCELED, + libc::ENOKEY => ENOKEY, + libc::EKEYEXPIRED => EKEYEXPIRED, + libc::EKEYREVOKED => EKEYREVOKED, + libc::EKEYREJECTED => EKEYREJECTED, + libc::EOWNERDEAD => EOWNERDEAD, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + #[cfg(not(any(target_os = "android", target_arch = "mips")))] + libc::ERFKILL => ERFKILL, + #[cfg(not(any(target_os = "android", target_arch = "mips")))] + libc::EHWPOISON => EHWPOISON, + _ => UnknownErrno, + } + } +} + +#[cfg(any(target_os = "macos", target_os = "ios"))] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + ENOTSUP = libc::ENOTSUP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EPROCLIM = libc::EPROCLIM, + EUSERS = libc::EUSERS, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + EREMOTE = libc::EREMOTE, + EBADRPC = libc::EBADRPC, + ERPCMISMATCH = libc::ERPCMISMATCH, + EPROGUNAVAIL = libc::EPROGUNAVAIL, + EPROGMISMATCH = libc::EPROGMISMATCH, + EPROCUNAVAIL = libc::EPROCUNAVAIL, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EFTYPE = libc::EFTYPE, + EAUTH = libc::EAUTH, + ENEEDAUTH = libc::ENEEDAUTH, + EPWROFF = libc::EPWROFF, + EDEVERR = libc::EDEVERR, + EOVERFLOW = libc::EOVERFLOW, + EBADEXEC = libc::EBADEXEC, + EBADARCH = libc::EBADARCH, + ESHLIBVERS = libc::ESHLIBVERS, + EBADMACHO = libc::EBADMACHO, + ECANCELED = libc::ECANCELED, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + EILSEQ = libc::EILSEQ, + ENOATTR = libc::ENOATTR, + EBADMSG = libc::EBADMSG, + EMULTIHOP = libc::EMULTIHOP, + ENODATA = libc::ENODATA, + ENOLINK = libc::ENOLINK, + ENOSR = libc::ENOSR, + ENOSTR = libc::ENOSTR, + EPROTO = libc::EPROTO, + ETIME = libc::ETIME, + EOPNOTSUPP = libc::EOPNOTSUPP, + ENOPOLICY = libc::ENOPOLICY, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + EOWNERDEAD = libc::EOWNERDEAD, + EQFULL = libc::EQFULL, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ELAST instead" + )] + pub const ELAST: Errno = Errno::EQFULL; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EDEADLOCK instead" + )] + pub const EDEADLOCK: Errno = Errno::EDEADLK; + + impl Errno { + pub const ELAST: Errno = Errno::EQFULL; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + pub const EDEADLOCK: Errno = Errno::EDEADLK; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::ENOTSUP => ENOTSUP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EPROCLIM => EPROCLIM, + libc::EUSERS => EUSERS, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::EREMOTE => EREMOTE, + libc::EBADRPC => EBADRPC, + libc::ERPCMISMATCH => ERPCMISMATCH, + libc::EPROGUNAVAIL => EPROGUNAVAIL, + libc::EPROGMISMATCH => EPROGMISMATCH, + libc::EPROCUNAVAIL => EPROCUNAVAIL, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EFTYPE => EFTYPE, + libc::EAUTH => EAUTH, + libc::ENEEDAUTH => ENEEDAUTH, + libc::EPWROFF => EPWROFF, + libc::EDEVERR => EDEVERR, + libc::EOVERFLOW => EOVERFLOW, + libc::EBADEXEC => EBADEXEC, + libc::EBADARCH => EBADARCH, + libc::ESHLIBVERS => ESHLIBVERS, + libc::EBADMACHO => EBADMACHO, + libc::ECANCELED => ECANCELED, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::EILSEQ => EILSEQ, + libc::ENOATTR => ENOATTR, + libc::EBADMSG => EBADMSG, + libc::EMULTIHOP => EMULTIHOP, + libc::ENODATA => ENODATA, + libc::ENOLINK => ENOLINK, + libc::ENOSR => ENOSR, + libc::ENOSTR => ENOSTR, + libc::EPROTO => EPROTO, + libc::ETIME => ETIME, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::ENOPOLICY => ENOPOLICY, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::EOWNERDEAD => EOWNERDEAD, + libc::EQFULL => EQFULL, + _ => UnknownErrno, + } + } +} + +#[cfg(target_os = "freebsd")] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + ENOTSUP = libc::ENOTSUP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EPROCLIM = libc::EPROCLIM, + EUSERS = libc::EUSERS, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + EREMOTE = libc::EREMOTE, + EBADRPC = libc::EBADRPC, + ERPCMISMATCH = libc::ERPCMISMATCH, + EPROGUNAVAIL = libc::EPROGUNAVAIL, + EPROGMISMATCH = libc::EPROGMISMATCH, + EPROCUNAVAIL = libc::EPROCUNAVAIL, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EFTYPE = libc::EFTYPE, + EAUTH = libc::EAUTH, + ENEEDAUTH = libc::ENEEDAUTH, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + EOVERFLOW = libc::EOVERFLOW, + ECANCELED = libc::ECANCELED, + EILSEQ = libc::EILSEQ, + ENOATTR = libc::ENOATTR, + EDOOFUS = libc::EDOOFUS, + EBADMSG = libc::EBADMSG, + EMULTIHOP = libc::EMULTIHOP, + ENOLINK = libc::ENOLINK, + EPROTO = libc::EPROTO, + ENOTCAPABLE = libc::ENOTCAPABLE, + ECAPMODE = libc::ECAPMODE, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + EOWNERDEAD = libc::EOWNERDEAD, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ELAST instead" + )] + pub const ELAST: Errno = Errno::EOWNERDEAD; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EDEADLOCK instead" + )] + pub const EDEADLOCK: Errno = Errno::EDEADLK; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EOPNOTSUPP instead" + )] + pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; + + impl Errno { + pub const ELAST: Errno = Errno::EOWNERDEAD; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + pub const EDEADLOCK: Errno = Errno::EDEADLK; + pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::ENOTSUP => ENOTSUP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EPROCLIM => EPROCLIM, + libc::EUSERS => EUSERS, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::EREMOTE => EREMOTE, + libc::EBADRPC => EBADRPC, + libc::ERPCMISMATCH => ERPCMISMATCH, + libc::EPROGUNAVAIL => EPROGUNAVAIL, + libc::EPROGMISMATCH => EPROGMISMATCH, + libc::EPROCUNAVAIL => EPROCUNAVAIL, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EFTYPE => EFTYPE, + libc::EAUTH => EAUTH, + libc::ENEEDAUTH => ENEEDAUTH, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::EOVERFLOW => EOVERFLOW, + libc::ECANCELED => ECANCELED, + libc::EILSEQ => EILSEQ, + libc::ENOATTR => ENOATTR, + libc::EDOOFUS => EDOOFUS, + libc::EBADMSG => EBADMSG, + libc::EMULTIHOP => EMULTIHOP, + libc::ENOLINK => ENOLINK, + libc::EPROTO => EPROTO, + libc::ENOTCAPABLE => ENOTCAPABLE, + libc::ECAPMODE => ECAPMODE, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::EOWNERDEAD => EOWNERDEAD, + _ => UnknownErrno, + } + } +} + +#[cfg(target_os = "dragonfly")] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + ENOTSUP = libc::ENOTSUP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EPROCLIM = libc::EPROCLIM, + EUSERS = libc::EUSERS, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + EREMOTE = libc::EREMOTE, + EBADRPC = libc::EBADRPC, + ERPCMISMATCH = libc::ERPCMISMATCH, + EPROGUNAVAIL = libc::EPROGUNAVAIL, + EPROGMISMATCH = libc::EPROGMISMATCH, + EPROCUNAVAIL = libc::EPROCUNAVAIL, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EFTYPE = libc::EFTYPE, + EAUTH = libc::EAUTH, + ENEEDAUTH = libc::ENEEDAUTH, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + EOVERFLOW = libc::EOVERFLOW, + ECANCELED = libc::ECANCELED, + EILSEQ = libc::EILSEQ, + ENOATTR = libc::ENOATTR, + EDOOFUS = libc::EDOOFUS, + EBADMSG = libc::EBADMSG, + EMULTIHOP = libc::EMULTIHOP, + ENOLINK = libc::ENOLINK, + EPROTO = libc::EPROTO, + ENOMEDIUM = libc::ENOMEDIUM, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + EOWNERDEAD = libc::EOWNERDEAD, + EASYNC = libc::EASYNC, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ELAST instead" + )] + pub const ELAST: Errno = Errno::EASYNC; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EDEADLOCK instead" + )] + pub const EDEADLOCK: Errno = Errno::EDEADLK; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EOPNOTSUPP instead" + )] + pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; + + impl Errno { + pub const ELAST: Errno = Errno::EASYNC; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + pub const EDEADLOCK: Errno = Errno::EDEADLK; + pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::ENOTSUP => ENOTSUP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EPROCLIM => EPROCLIM, + libc::EUSERS => EUSERS, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::EREMOTE => EREMOTE, + libc::EBADRPC => EBADRPC, + libc::ERPCMISMATCH => ERPCMISMATCH, + libc::EPROGUNAVAIL => EPROGUNAVAIL, + libc::EPROGMISMATCH => EPROGMISMATCH, + libc::EPROCUNAVAIL => EPROCUNAVAIL, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EFTYPE => EFTYPE, + libc::EAUTH => EAUTH, + libc::ENEEDAUTH => ENEEDAUTH, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::EOVERFLOW => EOVERFLOW, + libc::ECANCELED => ECANCELED, + libc::EILSEQ => EILSEQ, + libc::ENOATTR => ENOATTR, + libc::EDOOFUS => EDOOFUS, + libc::EBADMSG => EBADMSG, + libc::EMULTIHOP => EMULTIHOP, + libc::ENOLINK => ENOLINK, + libc::EPROTO => EPROTO, + libc::ENOMEDIUM => ENOMEDIUM, + libc::EASYNC => EASYNC, + _ => UnknownErrno, + } + } +} + +#[cfg(target_os = "openbsd")] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + EOPNOTSUPP = libc::EOPNOTSUPP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EPROCLIM = libc::EPROCLIM, + EUSERS = libc::EUSERS, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + EREMOTE = libc::EREMOTE, + EBADRPC = libc::EBADRPC, + ERPCMISMATCH = libc::ERPCMISMATCH, + EPROGUNAVAIL = libc::EPROGUNAVAIL, + EPROGMISMATCH = libc::EPROGMISMATCH, + EPROCUNAVAIL = libc::EPROCUNAVAIL, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EFTYPE = libc::EFTYPE, + EAUTH = libc::EAUTH, + ENEEDAUTH = libc::ENEEDAUTH, + EIPSEC = libc::EIPSEC, + ENOATTR = libc::ENOATTR, + EILSEQ = libc::EILSEQ, + ENOMEDIUM = libc::ENOMEDIUM, + EMEDIUMTYPE = libc::EMEDIUMTYPE, + EOVERFLOW = libc::EOVERFLOW, + ECANCELED = libc::ECANCELED, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + ENOTSUP = libc::ENOTSUP, + EBADMSG = libc::EBADMSG, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + EOWNERDEAD = libc::EOWNERDEAD, + EPROTO = libc::EPROTO, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ELAST instead" + )] + pub const ELAST: Errno = Errno::ENOTSUP; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + + impl Errno { + pub const ELAST: Errno = Errno::ENOTSUP; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EPROCLIM => EPROCLIM, + libc::EUSERS => EUSERS, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::EREMOTE => EREMOTE, + libc::EBADRPC => EBADRPC, + libc::ERPCMISMATCH => ERPCMISMATCH, + libc::EPROGUNAVAIL => EPROGUNAVAIL, + libc::EPROGMISMATCH => EPROGMISMATCH, + libc::EPROCUNAVAIL => EPROCUNAVAIL, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EFTYPE => EFTYPE, + libc::EAUTH => EAUTH, + libc::ENEEDAUTH => ENEEDAUTH, + libc::EIPSEC => EIPSEC, + libc::ENOATTR => ENOATTR, + libc::EILSEQ => EILSEQ, + libc::ENOMEDIUM => ENOMEDIUM, + libc::EMEDIUMTYPE => EMEDIUMTYPE, + libc::EOVERFLOW => EOVERFLOW, + libc::ECANCELED => ECANCELED, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::ENOTSUP => ENOTSUP, + libc::EBADMSG => EBADMSG, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::EOWNERDEAD => EOWNERDEAD, + libc::EPROTO => EPROTO, + _ => UnknownErrno, + } + } +} + +#[cfg(target_os = "netbsd")] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + EOPNOTSUPP = libc::EOPNOTSUPP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EPROCLIM = libc::EPROCLIM, + EUSERS = libc::EUSERS, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + EREMOTE = libc::EREMOTE, + EBADRPC = libc::EBADRPC, + ERPCMISMATCH = libc::ERPCMISMATCH, + EPROGUNAVAIL = libc::EPROGUNAVAIL, + EPROGMISMATCH = libc::EPROGMISMATCH, + EPROCUNAVAIL = libc::EPROCUNAVAIL, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EFTYPE = libc::EFTYPE, + EAUTH = libc::EAUTH, + ENEEDAUTH = libc::ENEEDAUTH, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + EOVERFLOW = libc::EOVERFLOW, + EILSEQ = libc::EILSEQ, + ENOTSUP = libc::ENOTSUP, + ECANCELED = libc::ECANCELED, + EBADMSG = libc::EBADMSG, + ENODATA = libc::ENODATA, + ENOSR = libc::ENOSR, + ENOSTR = libc::ENOSTR, + ETIME = libc::ETIME, + ENOATTR = libc::ENOATTR, + EMULTIHOP = libc::EMULTIHOP, + ENOLINK = libc::ENOLINK, + EPROTO = libc::EPROTO, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ELAST instead" + )] + pub const ELAST: Errno = Errno::ENOTSUP; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + + impl Errno { + pub const ELAST: Errno = Errno::ENOTSUP; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EPROCLIM => EPROCLIM, + libc::EUSERS => EUSERS, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::EREMOTE => EREMOTE, + libc::EBADRPC => EBADRPC, + libc::ERPCMISMATCH => ERPCMISMATCH, + libc::EPROGUNAVAIL => EPROGUNAVAIL, + libc::EPROGMISMATCH => EPROGMISMATCH, + libc::EPROCUNAVAIL => EPROCUNAVAIL, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EFTYPE => EFTYPE, + libc::EAUTH => EAUTH, + libc::ENEEDAUTH => ENEEDAUTH, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::EOVERFLOW => EOVERFLOW, + libc::EILSEQ => EILSEQ, + libc::ENOTSUP => ENOTSUP, + libc::ECANCELED => ECANCELED, + libc::EBADMSG => EBADMSG, + libc::ENODATA => ENODATA, + libc::ENOSR => ENOSR, + libc::ENOSTR => ENOSTR, + libc::ETIME => ETIME, + libc::ENOATTR => ENOATTR, + libc::EMULTIHOP => EMULTIHOP, + libc::ENOLINK => ENOLINK, + libc::EPROTO => EPROTO, + _ => UnknownErrno, + } + } +} + +#[cfg(target_os = "redox")] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + EOPNOTSUPP = libc::EOPNOTSUPP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EUSERS = libc::EUSERS, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + EREMOTE = libc::EREMOTE, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + EOVERFLOW = libc::EOVERFLOW, + EILSEQ = libc::EILSEQ, + ECANCELED = libc::ECANCELED, + EBADMSG = libc::EBADMSG, + ENODATA = libc::ENODATA, + ENOSR = libc::ENOSR, + ENOSTR = libc::ENOSTR, + ETIME = libc::ETIME, + EMULTIHOP = libc::EMULTIHOP, + ENOLINK = libc::ENOLINK, + EPROTO = libc::EPROTO, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + + impl Errno { + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EUSERS => EUSERS, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::EREMOTE => EREMOTE, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::EOVERFLOW => EOVERFLOW, + libc::EILSEQ => EILSEQ, + libc::ECANCELED => ECANCELED, + libc::EBADMSG => EBADMSG, + libc::ENODATA => ENODATA, + libc::ENOSR => ENOSR, + libc::ENOSTR => ENOSTR, + libc::ETIME => ETIME, + libc::EMULTIHOP => EMULTIHOP, + libc::ENOLINK => ENOLINK, + libc::EPROTO => EPROTO, + _ => UnknownErrno, + } + } +} + +#[cfg(any(target_os = "illumos", target_os = "solaris"))] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EAGAIN = libc::EAGAIN, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + ENOMSG = libc::ENOMSG, + EIDRM = libc::EIDRM, + ECHRNG = libc::ECHRNG, + EL2NSYNC = libc::EL2NSYNC, + EL3HLT = libc::EL3HLT, + EL3RST = libc::EL3RST, + ELNRNG = libc::ELNRNG, + EUNATCH = libc::EUNATCH, + ENOCSI = libc::ENOCSI, + EL2HLT = libc::EL2HLT, + EDEADLK = libc::EDEADLK, + ENOLCK = libc::ENOLCK, + ECANCELED = libc::ECANCELED, + ENOTSUP = libc::ENOTSUP, + EDQUOT = libc::EDQUOT, + EBADE = libc::EBADE, + EBADR = libc::EBADR, + EXFULL = libc::EXFULL, + ENOANO = libc::ENOANO, + EBADRQC = libc::EBADRQC, + EBADSLT = libc::EBADSLT, + EDEADLOCK = libc::EDEADLOCK, + EBFONT = libc::EBFONT, + EOWNERDEAD = libc::EOWNERDEAD, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + ENOSTR = libc::ENOSTR, + ENODATA = libc::ENODATA, + ETIME = libc::ETIME, + ENOSR = libc::ENOSR, + ENONET = libc::ENONET, + ENOPKG = libc::ENOPKG, + EREMOTE = libc::EREMOTE, + ENOLINK = libc::ENOLINK, + EADV = libc::EADV, + ESRMNT = libc::ESRMNT, + ECOMM = libc::ECOMM, + EPROTO = libc::EPROTO, + ELOCKUNMAPPED = libc::ELOCKUNMAPPED, + ENOTACTIVE = libc::ENOTACTIVE, + EMULTIHOP = libc::EMULTIHOP, + EBADMSG = libc::EBADMSG, + ENAMETOOLONG = libc::ENAMETOOLONG, + EOVERFLOW = libc::EOVERFLOW, + ENOTUNIQ = libc::ENOTUNIQ, + EBADFD = libc::EBADFD, + EREMCHG = libc::EREMCHG, + ELIBACC = libc::ELIBACC, + ELIBBAD = libc::ELIBBAD, + ELIBSCN = libc::ELIBSCN, + ELIBMAX = libc::ELIBMAX, + ELIBEXEC = libc::ELIBEXEC, + EILSEQ = libc::EILSEQ, + ENOSYS = libc::ENOSYS, + ELOOP = libc::ELOOP, + ERESTART = libc::ERESTART, + ESTRPIPE = libc::ESTRPIPE, + ENOTEMPTY = libc::ENOTEMPTY, + EUSERS = libc::EUSERS, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + EOPNOTSUPP = libc::EOPNOTSUPP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + EALREADY = libc::EALREADY, + EINPROGRESS = libc::EINPROGRESS, + ESTALE = libc::ESTALE, + } + + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::ELAST instead" + )] + pub const ELAST: Errno = Errno::ELAST; + #[deprecated( + since = "0.22.1", + note = "use nix::errno::Errno::EWOULDBLOCK instead" + )] + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + + impl Errno { + pub const ELAST: Errno = Errno::ESTALE; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EAGAIN => EAGAIN, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::ENOMSG => ENOMSG, + libc::EIDRM => EIDRM, + libc::ECHRNG => ECHRNG, + libc::EL2NSYNC => EL2NSYNC, + libc::EL3HLT => EL3HLT, + libc::EL3RST => EL3RST, + libc::ELNRNG => ELNRNG, + libc::EUNATCH => EUNATCH, + libc::ENOCSI => ENOCSI, + libc::EL2HLT => EL2HLT, + libc::EDEADLK => EDEADLK, + libc::ENOLCK => ENOLCK, + libc::ECANCELED => ECANCELED, + libc::ENOTSUP => ENOTSUP, + libc::EDQUOT => EDQUOT, + libc::EBADE => EBADE, + libc::EBADR => EBADR, + libc::EXFULL => EXFULL, + libc::ENOANO => ENOANO, + libc::EBADRQC => EBADRQC, + libc::EBADSLT => EBADSLT, + libc::EDEADLOCK => EDEADLOCK, + libc::EBFONT => EBFONT, + libc::EOWNERDEAD => EOWNERDEAD, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::ENOSTR => ENOSTR, + libc::ENODATA => ENODATA, + libc::ETIME => ETIME, + libc::ENOSR => ENOSR, + libc::ENONET => ENONET, + libc::ENOPKG => ENOPKG, + libc::EREMOTE => EREMOTE, + libc::ENOLINK => ENOLINK, + libc::EADV => EADV, + libc::ESRMNT => ESRMNT, + libc::ECOMM => ECOMM, + libc::EPROTO => EPROTO, + libc::ELOCKUNMAPPED => ELOCKUNMAPPED, + libc::ENOTACTIVE => ENOTACTIVE, + libc::EMULTIHOP => EMULTIHOP, + libc::EBADMSG => EBADMSG, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EOVERFLOW => EOVERFLOW, + libc::ENOTUNIQ => ENOTUNIQ, + libc::EBADFD => EBADFD, + libc::EREMCHG => EREMCHG, + libc::ELIBACC => ELIBACC, + libc::ELIBBAD => ELIBBAD, + libc::ELIBSCN => ELIBSCN, + libc::ELIBMAX => ELIBMAX, + libc::ELIBEXEC => ELIBEXEC, + libc::EILSEQ => EILSEQ, + libc::ENOSYS => ENOSYS, + libc::ELOOP => ELOOP, + libc::ERESTART => ERESTART, + libc::ESTRPIPE => ESTRPIPE, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EUSERS => EUSERS, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::EALREADY => EALREADY, + libc::EINPROGRESS => EINPROGRESS, + libc::ESTALE => ESTALE, + _ => UnknownErrno, + } + } +} + +#[cfg(target_os = "haiku")] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + #[non_exhaustive] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EDEADLK = libc::EDEADLK, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + EAGAIN = libc::EAGAIN, + EINPROGRESS = libc::EINPROGRESS, + EALREADY = libc::EALREADY, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ENOTSUP = libc::ENOTSUP, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + ELOOP = libc::ELOOP, + ENAMETOOLONG = libc::ENAMETOOLONG, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + ENOTEMPTY = libc::ENOTEMPTY, + EDQUOT = libc::EDQUOT, + ESTALE = libc::ESTALE, + ENOLCK = libc::ENOLCK, + ENOSYS = libc::ENOSYS, + EIDRM = libc::EIDRM, + ENOMSG = libc::ENOMSG, + EOVERFLOW = libc::EOVERFLOW, + ECANCELED = libc::ECANCELED, + EILSEQ = libc::EILSEQ, + ENOATTR = libc::ENOATTR, + EBADMSG = libc::EBADMSG, + EMULTIHOP = libc::EMULTIHOP, + ENOLINK = libc::ENOLINK, + EPROTO = libc::EPROTO, + } + + impl Errno { + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + pub const EDEADLOCK: Errno = Errno::EDEADLK; + pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; + } + + pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EDEADLK => EDEADLK, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::EAGAIN => EAGAIN, + libc::EINPROGRESS => EINPROGRESS, + libc::EALREADY => EALREADY, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ENOTSUP => ENOTSUP, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::ELOOP => ELOOP, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EDQUOT => EDQUOT, + libc::ESTALE => ESTALE, + libc::ENOLCK => ENOLCK, + libc::ENOSYS => ENOSYS, + libc::EIDRM => EIDRM, + libc::ENOMSG => ENOMSG, + libc::EOVERFLOW => EOVERFLOW, + libc::ECANCELED => ECANCELED, + libc::EILSEQ => EILSEQ, + libc::ENOATTR => ENOATTR, + libc::EBADMSG => EBADMSG, + libc::EMULTIHOP => EMULTIHOP, + libc::ENOLINK => ENOLINK, + libc::EPROTO => EPROTO, + _ => UnknownErrno, + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/fcntl.rs b/utshell-0.5.0/vendor/nix/src/fcntl.rs new file mode 100644 index 00000000..65082834 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/fcntl.rs @@ -0,0 +1,882 @@ +use crate::errno::Errno; +use libc::{self, c_char, c_int, c_uint, size_t, ssize_t}; +use std::ffi::OsString; +#[cfg(not(target_os = "redox"))] +use std::os::raw; +use std::os::unix::ffi::OsStringExt; +use std::os::unix::io::RawFd; + +#[cfg(feature = "fs")] +use crate::{sys::stat::Mode, NixPath, Result}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use std::ptr; // For splice and copy_file_range + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "wasi", + target_env = "uclibc", + target_os = "freebsd" +))] +#[cfg(feature = "fs")] +pub use self::posix_fadvise::{posix_fadvise, PosixFadviseAdvice}; + +#[cfg(not(target_os = "redox"))] +#[cfg(any(feature = "fs", feature = "process"))] +libc_bitflags! { + #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "process"))))] + pub struct AtFlags: c_int { + AT_REMOVEDIR; + AT_SYMLINK_FOLLOW; + AT_SYMLINK_NOFOLLOW; + #[cfg(any(target_os = "android", target_os = "linux"))] + AT_NO_AUTOMOUNT; + #[cfg(any(target_os = "android", target_os = "linux"))] + AT_EMPTY_PATH; + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + AT_EACCESS; + } +} + +#[cfg(any(feature = "fs", feature = "term"))] +libc_bitflags!( + /// Configuration options for opened files. + #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "term"))))] + pub struct OFlag: c_int { + /// Mask for the access mode of the file. + O_ACCMODE; + /// Use alternate I/O semantics. + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_ALT_IO; + /// Open the file in append-only mode. + O_APPEND; + /// Generate a signal when input or output becomes possible. + #[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_ASYNC; + /// Closes the file descriptor once an `execve` call is made. + /// + /// Also sets the file offset to the beginning of the file. + O_CLOEXEC; + /// Create the file if it does not exist. + O_CREAT; + /// Try to minimize cache effects of the I/O for this file. + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_DIRECT; + /// If the specified path isn't a directory, fail. + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_DIRECTORY; + /// Implicitly follow each `write()` with an `fdatasync()`. + #[cfg(any(target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_DSYNC; + /// Error out if a file was not created. + O_EXCL; + /// Open for execute only. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_EXEC; + /// Open with an exclusive file lock. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_EXLOCK; + /// Same as `O_SYNC`. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + all(target_os = "linux", not(target_env = "musl")), + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_FSYNC; + /// Allow files whose sizes can't be represented in an `off_t` to be opened. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_LARGEFILE; + /// Do not update the file last access time during `read(2)`s. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_NOATIME; + /// Don't attach the device as the process' controlling terminal. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_NOCTTY; + /// Same as `O_NONBLOCK`. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_NDELAY; + /// `open()` will fail if the given path is a symbolic link. + O_NOFOLLOW; + /// When possible, open the file in nonblocking mode. + O_NONBLOCK; + /// Don't deliver `SIGPIPE`. + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_NOSIGPIPE; + /// Obtain a file descriptor for low-level access. + /// + /// The file itself is not opened and other file operations will fail. + #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_PATH; + /// Only allow reading. + /// + /// This should not be combined with `O_WRONLY` or `O_RDWR`. + O_RDONLY; + /// Allow both reading and writing. + /// + /// This should not be combined with `O_WRONLY` or `O_RDONLY`. + O_RDWR; + /// Similar to `O_DSYNC` but applies to `read`s instead. + #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_RSYNC; + /// Skip search permission checks. + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_SEARCH; + /// Open with a shared file lock. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_SHLOCK; + /// Implicitly follow each `write()` with an `fsync()`. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_SYNC; + /// Create an unnamed temporary file. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_TMPFILE; + /// Truncate an existing regular file to 0 length if it allows writing. + O_TRUNC; + /// Restore default TTY attributes. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_TTY_INIT; + /// Only allow writing. + /// + /// This should not be combined with `O_RDONLY` or `O_RDWR`. + O_WRONLY; + } +); + +feature! { +#![feature = "fs"] + +// The conversion is not identical on all operating systems. +#[allow(clippy::useless_conversion)] +pub fn open(path: &P, oflag: OFlag, mode: Mode) -> Result { + let fd = path.with_nix_path(|cstr| { + unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) } + })?; + + Errno::result(fd) +} + +// The conversion is not identical on all operating systems. +#[allow(clippy::useless_conversion)] +#[cfg(not(target_os = "redox"))] +pub fn openat( + dirfd: RawFd, + path: &P, + oflag: OFlag, + mode: Mode, +) -> Result { + let fd = path.with_nix_path(|cstr| { + unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) } + })?; + Errno::result(fd) +} + +#[cfg(not(target_os = "redox"))] +pub fn renameat( + old_dirfd: Option, + old_path: &P1, + new_dirfd: Option, + new_path: &P2, +) -> Result<()> { + let res = old_path.with_nix_path(|old_cstr| { + new_path.with_nix_path(|new_cstr| unsafe { + libc::renameat( + at_rawfd(old_dirfd), + old_cstr.as_ptr(), + at_rawfd(new_dirfd), + new_cstr.as_ptr(), + ) + }) + })??; + Errno::result(res).map(drop) +} +} + +#[cfg(all(target_os = "linux", target_env = "gnu",))] +#[cfg(feature = "fs")] +libc_bitflags! { + #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct RenameFlags: u32 { + RENAME_EXCHANGE; + RENAME_NOREPLACE; + RENAME_WHITEOUT; + } +} + +feature! { +#![feature = "fs"] +#[cfg(all( + target_os = "linux", + target_env = "gnu", +))] +pub fn renameat2( + old_dirfd: Option, + old_path: &P1, + new_dirfd: Option, + new_path: &P2, + flags: RenameFlags, +) -> Result<()> { + let res = old_path.with_nix_path(|old_cstr| { + new_path.with_nix_path(|new_cstr| unsafe { + libc::renameat2( + at_rawfd(old_dirfd), + old_cstr.as_ptr(), + at_rawfd(new_dirfd), + new_cstr.as_ptr(), + flags.bits(), + ) + }) + })??; + Errno::result(res).map(drop) +} + +fn wrap_readlink_result(mut v: Vec, len: ssize_t) -> Result { + unsafe { v.set_len(len as usize) } + v.shrink_to_fit(); + Ok(OsString::from_vec(v.to_vec())) +} + +fn readlink_maybe_at( + dirfd: Option, + path: &P, + v: &mut Vec, +) -> Result { + path.with_nix_path(|cstr| unsafe { + match dirfd { + #[cfg(target_os = "redox")] + Some(_) => unreachable!(), + #[cfg(not(target_os = "redox"))] + Some(dirfd) => libc::readlinkat( + dirfd, + cstr.as_ptr(), + v.as_mut_ptr() as *mut c_char, + v.capacity() as size_t, + ), + None => libc::readlink( + cstr.as_ptr(), + v.as_mut_ptr() as *mut c_char, + v.capacity() as size_t, + ), + } + }) +} + +fn inner_readlink(dirfd: Option, path: &P) -> Result { + let mut v = Vec::with_capacity(libc::PATH_MAX as usize); + // simple case: result is strictly less than `PATH_MAX` + let res = readlink_maybe_at(dirfd, path, &mut v)?; + let len = Errno::result(res)?; + debug_assert!(len >= 0); + if (len as usize) < v.capacity() { + return wrap_readlink_result(v, res); + } + // Uh oh, the result is too long... + // Let's try to ask lstat how many bytes to allocate. + let reported_size = match dirfd { + #[cfg(target_os = "redox")] + Some(_) => unreachable!(), + #[cfg(any(target_os = "android", target_os = "linux"))] + Some(dirfd) => { + let flags = if path.is_empty() { AtFlags::AT_EMPTY_PATH } else { AtFlags::empty() }; + super::sys::stat::fstatat(dirfd, path, flags | AtFlags::AT_SYMLINK_NOFOLLOW) + }, + #[cfg(not(any(target_os = "android", target_os = "linux", target_os = "redox")))] + Some(dirfd) => super::sys::stat::fstatat(dirfd, path, AtFlags::AT_SYMLINK_NOFOLLOW), + None => super::sys::stat::lstat(path) + } + .map(|x| x.st_size) + .unwrap_or(0); + let mut try_size = if reported_size > 0 { + // Note: even if `lstat`'s apparently valid answer turns out to be + // wrong, we will still read the full symlink no matter what. + reported_size as usize + 1 + } else { + // If lstat doesn't cooperate, or reports an error, be a little less + // precise. + (libc::PATH_MAX as usize).max(128) << 1 + }; + loop { + v.reserve_exact(try_size); + let res = readlink_maybe_at(dirfd, path, &mut v)?; + let len = Errno::result(res)?; + debug_assert!(len >= 0); + if (len as usize) < v.capacity() { + break wrap_readlink_result(v, res); + } else { + // Ugh! Still not big enough! + match try_size.checked_shl(1) { + Some(next_size) => try_size = next_size, + // It's absurd that this would happen, but handle it sanely + // anyway. + None => break Err(Errno::ENAMETOOLONG), + } + } + } +} + +pub fn readlink(path: &P) -> Result { + inner_readlink(None, path) +} + +#[cfg(not(target_os = "redox"))] +pub fn readlinkat(dirfd: RawFd, path: &P) -> Result { + inner_readlink(Some(dirfd), path) +} + +/// Computes the raw fd consumed by a function of the form `*at`. +#[cfg(not(target_os = "redox"))] +pub(crate) fn at_rawfd(fd: Option) -> raw::c_int { + match fd { + None => libc::AT_FDCWD, + Some(fd) => fd, + } +} +} + +#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] +#[cfg(feature = "fs")] +libc_bitflags!( + /// Additional flags for file sealing, which allows for limiting operations on a file. + #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct SealFlag: c_int { + /// Prevents further calls to `fcntl()` with `F_ADD_SEALS`. + F_SEAL_SEAL; + /// The file cannot be reduced in size. + F_SEAL_SHRINK; + /// The size of the file cannot be increased. + F_SEAL_GROW; + /// The file contents cannot be modified. + F_SEAL_WRITE; + } +); + +#[cfg(feature = "fs")] +libc_bitflags!( + /// Additional configuration flags for `fcntl`'s `F_SETFD`. + #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct FdFlag: c_int { + /// The file descriptor will automatically be closed during a successful `execve(2)`. + FD_CLOEXEC; + } +); + +feature! { +#![feature = "fs"] + +#[cfg(not(target_os = "redox"))] +#[derive(Debug, Eq, Hash, PartialEq)] +#[non_exhaustive] +pub enum FcntlArg<'a> { + F_DUPFD(RawFd), + F_DUPFD_CLOEXEC(RawFd), + F_GETFD, + F_SETFD(FdFlag), // FD_FLAGS + F_GETFL, + F_SETFL(OFlag), // O_NONBLOCK + F_SETLK(&'a libc::flock), + F_SETLKW(&'a libc::flock), + F_GETLK(&'a mut libc::flock), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_OFD_SETLK(&'a libc::flock), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_OFD_SETLKW(&'a libc::flock), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_OFD_GETLK(&'a mut libc::flock), + #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_ADD_SEALS(SealFlag), + #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_GET_SEALS, + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_FULLFSYNC, + #[cfg(any(target_os = "linux", target_os = "android"))] + F_GETPIPE_SZ, + #[cfg(any(target_os = "linux", target_os = "android"))] + F_SETPIPE_SZ(c_int), + // TODO: Rest of flags +} + +#[cfg(target_os = "redox")] +#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] +#[non_exhaustive] +pub enum FcntlArg { + F_DUPFD(RawFd), + F_DUPFD_CLOEXEC(RawFd), + F_GETFD, + F_SETFD(FdFlag), // FD_FLAGS + F_GETFL, + F_SETFL(OFlag), // O_NONBLOCK +} +pub use self::FcntlArg::*; + +// TODO: Figure out how to handle value fcntl returns +pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { + let res = unsafe { + match arg { + F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd), + F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd), + F_GETFD => libc::fcntl(fd, libc::F_GETFD), + F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()), + F_GETFL => libc::fcntl(fd, libc::F_GETFL), + F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()), + #[cfg(not(target_os = "redox"))] + F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock), + #[cfg(not(target_os = "redox"))] + F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock), + #[cfg(not(target_os = "redox"))] + F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock), + #[cfg(any(target_os = "android", target_os = "linux"))] + F_OFD_SETLK(flock) => libc::fcntl(fd, libc::F_OFD_SETLK, flock), + #[cfg(any(target_os = "android", target_os = "linux"))] + F_OFD_SETLKW(flock) => libc::fcntl(fd, libc::F_OFD_SETLKW, flock), + #[cfg(any(target_os = "android", target_os = "linux"))] + F_OFD_GETLK(flock) => libc::fcntl(fd, libc::F_OFD_GETLK, flock), + #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()), + #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS), + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size), + } + }; + + Errno::result(res) +} + +// TODO: convert to libc_enum +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[non_exhaustive] +pub enum FlockArg { + LockShared, + LockExclusive, + Unlock, + LockSharedNonblock, + LockExclusiveNonblock, + UnlockNonblock, +} + +#[cfg(not(target_os = "redox"))] +pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> { + use self::FlockArg::*; + + let res = unsafe { + match arg { + LockShared => libc::flock(fd, libc::LOCK_SH), + LockExclusive => libc::flock(fd, libc::LOCK_EX), + Unlock => libc::flock(fd, libc::LOCK_UN), + LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB), + LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB), + UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB), + } + }; + + Errno::result(res).map(drop) +} +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(feature = "zerocopy")] +libc_bitflags! { + /// Additional flags to `splice` and friends. + #[cfg_attr(docsrs, doc(cfg(feature = "zerocopy")))] + pub struct SpliceFFlags: c_uint { + /// Request that pages be moved instead of copied. + /// + /// Not applicable to `vmsplice`. + SPLICE_F_MOVE; + /// Do not block on I/O. + SPLICE_F_NONBLOCK; + /// Hint that more data will be coming in a subsequent splice. + /// + /// Not applicable to `vmsplice`. + SPLICE_F_MORE; + /// Gift the user pages to the kernel. + /// + /// Not applicable to `splice`. + SPLICE_F_GIFT; + } +} + +feature! { +#![feature = "zerocopy"] + +/// Copy a range of data from one file to another +/// +/// The `copy_file_range` system call performs an in-kernel copy between +/// file descriptors `fd_in` and `fd_out` without the additional cost of +/// transferring data from the kernel to user space and then back into the +/// kernel. It copies up to `len` bytes of data from file descriptor `fd_in` to +/// file descriptor `fd_out`, overwriting any data that exists within the +/// requested range of the target file. +/// +/// If the `off_in` and/or `off_out` arguments are used, the values +/// will be mutated to reflect the new position within the file after +/// copying. If they are not used, the relevant filedescriptors will be seeked +/// to the new position. +/// +/// On successful completion the number of bytes actually copied will be +/// returned. +#[cfg(any(target_os = "android", target_os = "linux"))] +pub fn copy_file_range( + fd_in: RawFd, + off_in: Option<&mut libc::loff_t>, + fd_out: RawFd, + off_out: Option<&mut libc::loff_t>, + len: usize, +) -> Result { + let off_in = off_in + .map(|offset| offset as *mut libc::loff_t) + .unwrap_or(ptr::null_mut()); + let off_out = off_out + .map(|offset| offset as *mut libc::loff_t) + .unwrap_or(ptr::null_mut()); + + let ret = unsafe { + libc::syscall( + libc::SYS_copy_file_range, + fd_in, + off_in, + fd_out, + off_out, + len, + 0, + ) + }; + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn splice( + fd_in: RawFd, + off_in: Option<&mut libc::loff_t>, + fd_out: RawFd, + off_out: Option<&mut libc::loff_t>, + len: usize, + flags: SpliceFFlags, +) -> Result { + let off_in = off_in + .map(|offset| offset as *mut libc::loff_t) + .unwrap_or(ptr::null_mut()); + let off_out = off_out + .map(|offset| offset as *mut libc::loff_t) + .unwrap_or(ptr::null_mut()); + + let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) }; + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result { + let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) }; + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn vmsplice( + fd: RawFd, + iov: &[std::io::IoSlice<'_>], + flags: SpliceFFlags + ) -> Result +{ + let ret = unsafe { + libc::vmsplice( + fd, + iov.as_ptr() as *const libc::iovec, + iov.len(), + flags.bits(), + ) + }; + Errno::result(ret).map(|r| r as usize) +} +} + +#[cfg(any(target_os = "linux"))] +#[cfg(feature = "fs")] +libc_bitflags!( + /// Mode argument flags for fallocate determining operation performed on a given range. + #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct FallocateFlags: c_int { + /// File size is not changed. + /// + /// offset + len can be greater than file size. + FALLOC_FL_KEEP_SIZE; + /// Deallocates space by creating a hole. + /// + /// Must be ORed with FALLOC_FL_KEEP_SIZE. Byte range starts at offset and continues for len bytes. + FALLOC_FL_PUNCH_HOLE; + /// Removes byte range from a file without leaving a hole. + /// + /// Byte range to collapse starts at offset and continues for len bytes. + FALLOC_FL_COLLAPSE_RANGE; + /// Zeroes space in specified byte range. + /// + /// Byte range starts at offset and continues for len bytes. + FALLOC_FL_ZERO_RANGE; + /// Increases file space by inserting a hole within the file size. + /// + /// Does not overwrite existing data. Hole starts at offset and continues for len bytes. + FALLOC_FL_INSERT_RANGE; + /// Shared file data extants are made private to the file. + /// + /// Gaurantees that a subsequent write will not fail due to lack of space. + FALLOC_FL_UNSHARE_RANGE; + } +); + +feature! { +#![feature = "fs"] + +/// Manipulates file space. +/// +/// Allows the caller to directly manipulate the allocated disk space for the +/// file referred to by fd. +#[cfg(any(target_os = "linux"))] +#[cfg(feature = "fs")] +pub fn fallocate( + fd: RawFd, + mode: FallocateFlags, + offset: libc::off_t, + len: libc::off_t, +) -> Result<()> { + let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) }; + Errno::result(res).map(drop) +} + +/// Argument to [`fspacectl`] describing the range to zero. The first member is +/// the file offset, and the second is the length of the region. +#[cfg(any(target_os = "freebsd"))] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct SpacectlRange(pub libc::off_t, pub libc::off_t); + +#[cfg(any(target_os = "freebsd"))] +impl SpacectlRange { + #[inline] + pub fn is_empty(&self) -> bool { + self.1 == 0 + } + + #[inline] + pub fn len(&self) -> libc::off_t { + self.1 + } + + #[inline] + pub fn offset(&self) -> libc::off_t { + self.0 + } +} + +/// Punch holes in a file. +/// +/// `fspacectl` instructs the file system to deallocate a portion of a file. +/// After a successful operation, this region of the file will return all zeroes +/// if read. If the file system supports deallocation, then it may free the +/// underlying storage, too. +/// +/// # Arguments +/// +/// - `fd` - File to operate on +/// - `range.0` - File offset at which to begin deallocation +/// - `range.1` - Length of the region to deallocate +/// +/// # Returns +/// +/// The operation may deallocate less than the entire requested region. On +/// success, it returns the region that still remains to be deallocated. The +/// caller should loop until the returned region is empty. +/// +/// # Example +/// +#[cfg_attr(fbsd14, doc = " ```")] +#[cfg_attr(not(fbsd14), doc = " ```no_run")] +/// # use std::io::Write; +/// # use std::os::unix::fs::FileExt; +/// # use std::os::unix::io::AsRawFd; +/// # use nix::fcntl::*; +/// # use tempfile::tempfile; +/// const INITIAL: &[u8] = b"0123456789abcdef"; +/// let mut f = tempfile().unwrap(); +/// f.write_all(INITIAL).unwrap(); +/// let mut range = SpacectlRange(3, 6); +/// while (!range.is_empty()) { +/// range = fspacectl(f.as_raw_fd(), range).unwrap(); +/// } +/// let mut buf = vec![0; INITIAL.len()]; +/// f.read_exact_at(&mut buf, 0).unwrap(); +/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef"); +/// ``` +#[cfg(target_os = "freebsd")] +pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result { + let mut rqsr = libc::spacectl_range{r_offset: range.0, r_len: range.1}; + let res = unsafe { libc::fspacectl( + fd, + libc::SPACECTL_DEALLOC, // Only one command is supported ATM + &rqsr, + 0, // No flags are currently supported + &mut rqsr + )}; + Errno::result(res).map(|_| SpacectlRange(rqsr.r_offset, rqsr.r_len)) +} + +/// Like [`fspacectl`], but will never return incomplete. +/// +/// # Arguments +/// +/// - `fd` - File to operate on +/// - `offset` - File offset at which to begin deallocation +/// - `len` - Length of the region to deallocate +/// +/// # Returns +/// +/// Returns `()` on success. On failure, the region may or may not be partially +/// deallocated. +/// +/// # Example +/// +#[cfg_attr(fbsd14, doc = " ```")] +#[cfg_attr(not(fbsd14), doc = " ```no_run")] +/// # use std::io::Write; +/// # use std::os::unix::fs::FileExt; +/// # use std::os::unix::io::AsRawFd; +/// # use nix::fcntl::*; +/// # use tempfile::tempfile; +/// const INITIAL: &[u8] = b"0123456789abcdef"; +/// let mut f = tempfile().unwrap(); +/// f.write_all(INITIAL).unwrap(); +/// fspacectl_all(f.as_raw_fd(), 3, 6).unwrap(); +/// let mut buf = vec![0; INITIAL.len()]; +/// f.read_exact_at(&mut buf, 0).unwrap(); +/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef"); +/// ``` +#[cfg(target_os = "freebsd")] +pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t) + -> Result<()> +{ + let mut rqsr = libc::spacectl_range{r_offset: offset, r_len: len}; + while rqsr.r_len > 0 { + let res = unsafe { libc::fspacectl( + fd, + libc::SPACECTL_DEALLOC, // Only one command is supported ATM + &rqsr, + 0, // No flags are currently supported + &mut rqsr + )}; + Errno::result(res)?; + } + Ok(()) +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "wasi", + target_env = "uclibc", + target_os = "freebsd" +))] +mod posix_fadvise { + use crate::errno::Errno; + use std::os::unix::io::RawFd; + use crate::Result; + + #[cfg(feature = "fs")] + libc_enum! { + #[repr(i32)] + #[non_exhaustive] + #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub enum PosixFadviseAdvice { + POSIX_FADV_NORMAL, + POSIX_FADV_SEQUENTIAL, + POSIX_FADV_RANDOM, + POSIX_FADV_NOREUSE, + POSIX_FADV_WILLNEED, + POSIX_FADV_DONTNEED, + } + } + + feature! { + #![feature = "fs"] + pub fn posix_fadvise( + fd: RawFd, + offset: libc::off_t, + len: libc::off_t, + advice: PosixFadviseAdvice, + ) -> Result<()> { + let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) }; + + if res == 0 { + Ok(()) + } else { + Err(Errno::from_i32(res)) + } + } + } +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "wasi", + target_os = "freebsd" +))] +pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<()> { + let res = unsafe { libc::posix_fallocate(fd, offset, len) }; + match Errno::result(res) { + Err(err) => Err(err), + Ok(0) => Ok(()), + Ok(errno) => Err(Errno::from_i32(errno)), + } +} +} diff --git a/utshell-0.5.0/vendor/nix/src/features.rs b/utshell-0.5.0/vendor/nix/src/features.rs new file mode 100644 index 00000000..d2adc169 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/features.rs @@ -0,0 +1,124 @@ +//! Feature tests for OS functionality +pub use self::os::*; + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod os { + use std::os::unix::ffi::OsStrExt; + use crate::sys::utsname::uname; + use crate::Result; + + // Features: + // * atomic cloexec on socket: 2.6.27 + // * pipe2: 2.6.27 + // * accept4: 2.6.28 + + static VERS_UNKNOWN: usize = 1; + static VERS_2_6_18: usize = 2; + static VERS_2_6_27: usize = 3; + static VERS_2_6_28: usize = 4; + static VERS_3: usize = 5; + + #[inline] + fn digit(dst: &mut usize, b: u8) { + *dst *= 10; + *dst += (b - b'0') as usize; + } + + fn parse_kernel_version() -> Result { + let u = uname()?; + + let mut curr: usize = 0; + let mut major: usize = 0; + let mut minor: usize = 0; + let mut patch: usize = 0; + + for &b in u.release().as_bytes() { + if curr >= 3 { + break; + } + + match b { + b'.' | b'-' => { + curr += 1; + } + b'0'..=b'9' => { + match curr { + 0 => digit(&mut major, b), + 1 => digit(&mut minor, b), + _ => digit(&mut patch, b), + } + } + _ => break, + } + } + + Ok(if major >= 3 { + VERS_3 + } else if major >= 2 { + if minor >= 7 { + VERS_UNKNOWN + } else if minor >= 6 { + if patch >= 28 { + VERS_2_6_28 + } else if patch >= 27 { + VERS_2_6_27 + } else { + VERS_2_6_18 + } + } else { + VERS_UNKNOWN + } + } else { + VERS_UNKNOWN + }) + } + + fn kernel_version() -> Result { + static mut KERNEL_VERS: usize = 0; + + unsafe { + if KERNEL_VERS == 0 { + KERNEL_VERS = parse_kernel_version()?; + } + + Ok(KERNEL_VERS) + } + } + + /// Check if the OS supports atomic close-on-exec for sockets + pub fn socket_atomic_cloexec() -> bool { + kernel_version().map(|version| version >= VERS_2_6_27).unwrap_or(false) + } + + #[test] + pub fn test_parsing_kernel_version() { + assert!(kernel_version().unwrap() > 0); + } +} + +#[cfg(any( + target_os = "dragonfly", // Since ??? + target_os = "freebsd", // Since 10.0 + target_os = "illumos", // Since ??? + target_os = "netbsd", // Since 6.0 + target_os = "openbsd", // Since 5.7 + target_os = "redox", // Since 1-july-2020 +))] +mod os { + /// Check if the OS supports atomic close-on-exec for sockets + pub const fn socket_atomic_cloexec() -> bool { + true + } +} + +#[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "fuchsia", + target_os = "haiku", + target_os = "solaris"))] +mod os { + /// Check if the OS supports atomic close-on-exec for sockets + pub const fn socket_atomic_cloexec() -> bool { + false + } +} diff --git a/utshell-0.5.0/vendor/nix/src/ifaddrs.rs b/utshell-0.5.0/vendor/nix/src/ifaddrs.rs new file mode 100644 index 00000000..c886add6 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/ifaddrs.rs @@ -0,0 +1,213 @@ +//! Query network interface addresses +//! +//! Uses the Linux and/or BSD specific function `getifaddrs` to query the list +//! of interfaces and their associated addresses. + +use cfg_if::cfg_if; +#[cfg(any(target_os = "ios", target_os = "macos"))] +use std::convert::TryFrom; +use std::ffi; +use std::iter::Iterator; +use std::mem; +use std::option::Option; + +use crate::{Result, Errno}; +use crate::sys::socket::{SockaddrLike, SockaddrStorage}; +use crate::net::if_::*; + +/// Describes a single address for an interface as returned by `getifaddrs`. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct InterfaceAddress { + /// Name of the network interface + pub interface_name: String, + /// Flags as from `SIOCGIFFLAGS` ioctl + pub flags: InterfaceFlags, + /// Network address of this interface + pub address: Option, + /// Netmask of this interface + pub netmask: Option, + /// Broadcast address of this interface, if applicable + pub broadcast: Option, + /// Point-to-point destination address + pub destination: Option, +} + +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] { + fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr { + info.ifa_ifu + } + } else { + fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr { + info.ifa_dstaddr + } + } +} + +/// Workaround a bug in XNU where netmasks will always have the wrong size in +/// the sa_len field due to the kernel ignoring trailing zeroes in the structure +/// when setting the field. See https://github.com/nix-rust/nix/issues/1709#issuecomment-1199304470 +/// +/// To fix this, we stack-allocate a new sockaddr_storage, zero it out, and +/// memcpy sa_len of the netmask to that new storage. Finally, we reset the +/// ss_len field to sizeof(sockaddr_storage). This is supposedly valid as all +/// members of the sockaddr_storage are "ok" with being zeroed out (there are +/// no pointers). +#[cfg(any(target_os = "ios", target_os = "macos"))] +unsafe fn workaround_xnu_bug(info: &libc::ifaddrs) -> Option { + let src_sock = info.ifa_netmask; + if src_sock.is_null() { + return None; + } + + let mut dst_sock = mem::MaybeUninit::::zeroed(); + + // memcpy only sa_len bytes, assume the rest is zero + std::ptr::copy_nonoverlapping( + src_sock as *const u8, + dst_sock.as_mut_ptr() as *mut u8, + (*src_sock).sa_len.into(), + ); + + // Initialize ss_len to sizeof(libc::sockaddr_storage). + (*dst_sock.as_mut_ptr()).ss_len = + u8::try_from(mem::size_of::()).unwrap(); + let dst_sock = dst_sock.assume_init(); + + let dst_sock_ptr = + &dst_sock as *const libc::sockaddr_storage as *const libc::sockaddr; + + SockaddrStorage::from_raw(dst_sock_ptr, None) +} + +impl InterfaceAddress { + /// Create an `InterfaceAddress` from the libc struct. + fn from_libc_ifaddrs(info: &libc::ifaddrs) -> InterfaceAddress { + let ifname = unsafe { ffi::CStr::from_ptr(info.ifa_name) }; + let address = unsafe { SockaddrStorage::from_raw(info.ifa_addr, None) }; + #[cfg(any(target_os = "ios", target_os = "macos"))] + let netmask = unsafe { workaround_xnu_bug(info) }; + #[cfg(not(any(target_os = "ios", target_os = "macos")))] + let netmask = + unsafe { SockaddrStorage::from_raw(info.ifa_netmask, None) }; + let mut addr = InterfaceAddress { + interface_name: ifname.to_string_lossy().to_string(), + flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32), + address, + netmask, + broadcast: None, + destination: None, + }; + + let ifu = get_ifu_from_sockaddr(info); + if addr.flags.contains(InterfaceFlags::IFF_POINTOPOINT) { + addr.destination = unsafe { SockaddrStorage::from_raw(ifu, None) }; + } else if addr.flags.contains(InterfaceFlags::IFF_BROADCAST) { + addr.broadcast = unsafe { SockaddrStorage::from_raw(ifu, None) }; + } + + addr + } +} + +/// Holds the results of `getifaddrs`. +/// +/// Use the function `getifaddrs` to create this Iterator. Note that the +/// actual list of interfaces can be iterated once and will be freed as +/// soon as the Iterator goes out of scope. +#[derive(Debug, Eq, Hash, PartialEq)] +pub struct InterfaceAddressIterator { + base: *mut libc::ifaddrs, + next: *mut libc::ifaddrs, +} + +impl Drop for InterfaceAddressIterator { + fn drop(&mut self) { + unsafe { libc::freeifaddrs(self.base) }; + } +} + +impl Iterator for InterfaceAddressIterator { + type Item = InterfaceAddress; + fn next(&mut self) -> Option<::Item> { + match unsafe { self.next.as_ref() } { + Some(ifaddr) => { + self.next = ifaddr.ifa_next; + Some(InterfaceAddress::from_libc_ifaddrs(ifaddr)) + } + None => None, + } + } +} + +/// Get interface addresses using libc's `getifaddrs` +/// +/// Note that the underlying implementation differs between OSes. Only the +/// most common address families are supported by the nix crate (due to +/// lack of time and complexity of testing). The address family is encoded +/// in the specific variant of `SockaddrStorage` returned for the fields +/// `address`, `netmask`, `broadcast`, and `destination`. For any entry not +/// supported, the returned list will contain a `None` entry. +/// +/// # Example +/// ``` +/// let addrs = nix::ifaddrs::getifaddrs().unwrap(); +/// for ifaddr in addrs { +/// match ifaddr.address { +/// Some(address) => { +/// println!("interface {} address {}", +/// ifaddr.interface_name, address); +/// }, +/// None => { +/// println!("interface {} with unsupported address family", +/// ifaddr.interface_name); +/// } +/// } +/// } +/// ``` +pub fn getifaddrs() -> Result { + let mut addrs = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit(); + unsafe { + Errno::result(libc::getifaddrs(addrs.as_mut_ptr())).map(|_| { + InterfaceAddressIterator { + base: addrs.assume_init(), + next: addrs.assume_init(), + } + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // Only checks if `getifaddrs` can be invoked without panicking. + #[test] + fn test_getifaddrs() { + let _ = getifaddrs(); + } + + // Ensures getting the netmask works, and in particular that + // `workaround_xnu_bug` works properly. + #[test] + fn test_getifaddrs_netmask_correct() { + let addrs = getifaddrs().unwrap(); + for iface in addrs { + let sock = if let Some(sock) = iface.netmask { + sock + } else { + continue; + }; + if sock.family() == Some(crate::sys::socket::AddressFamily::Inet) { + let _ = sock.as_sockaddr_in().unwrap(); + return; + } else if sock.family() + == Some(crate::sys::socket::AddressFamily::Inet6) + { + let _ = sock.as_sockaddr_in6().unwrap(); + return; + } + } + panic!("No address?"); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/kmod.rs b/utshell-0.5.0/vendor/nix/src/kmod.rs new file mode 100644 index 00000000..c42068c7 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/kmod.rs @@ -0,0 +1,122 @@ +//! Load and unload kernel modules. +//! +//! For more details see + +use std::ffi::CStr; +use std::os::unix::io::AsRawFd; + +use crate::errno::Errno; +use crate::Result; + +/// Loads a kernel module from a buffer. +/// +/// It loads an ELF image into kernel space, +/// performs any necessary symbol relocations, +/// initializes module parameters to values provided by the caller, +/// and then runs the module's init function. +/// +/// This function requires `CAP_SYS_MODULE` privilege. +/// +/// The `module_image` argument points to a buffer containing the binary image +/// to be loaded. The buffer should contain a valid ELF image +/// built for the running kernel. +/// +/// The `param_values` argument is a string containing space-delimited specifications +/// of the values for module parameters. +/// Each of the parameter specifications has the form: +/// +/// `name[=value[,value...]]` +/// +/// # Example +/// +/// ```no_run +/// use std::fs::File; +/// use std::io::Read; +/// use std::ffi::CString; +/// use nix::kmod::init_module; +/// +/// let mut f = File::open("mykernel.ko").unwrap(); +/// let mut contents: Vec = Vec::new(); +/// f.read_to_end(&mut contents).unwrap(); +/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap(); +/// ``` +/// +/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information. +pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> { + let res = unsafe { + libc::syscall( + libc::SYS_init_module, + module_image.as_ptr(), + module_image.len(), + param_values.as_ptr(), + ) + }; + + Errno::result(res).map(drop) +} + +libc_bitflags!( + /// Flags used by the `finit_module` function. + pub struct ModuleInitFlags: libc::c_uint { + /// Ignore symbol version hashes. + MODULE_INIT_IGNORE_MODVERSIONS; + /// Ignore kernel version magic. + MODULE_INIT_IGNORE_VERMAGIC; + } +); + +/// Loads a kernel module from a given file descriptor. +/// +/// # Example +/// +/// ```no_run +/// use std::fs::File; +/// use std::ffi::CString; +/// use nix::kmod::{finit_module, ModuleInitFlags}; +/// +/// let f = File::open("mymod.ko").unwrap(); +/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap(); +/// ``` +/// +/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information. +pub fn finit_module(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> { + let res = unsafe { + libc::syscall( + libc::SYS_finit_module, + fd.as_raw_fd(), + param_values.as_ptr(), + flags.bits(), + ) + }; + + Errno::result(res).map(drop) +} + +libc_bitflags!( + /// Flags used by `delete_module`. + /// + /// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) + /// for a detailed description how these flags work. + pub struct DeleteModuleFlags: libc::c_int { + O_NONBLOCK; + O_TRUNC; + } +); + +/// Unloads the kernel module with the given name. +/// +/// # Example +/// +/// ```no_run +/// use std::ffi::CString; +/// use nix::kmod::{delete_module, DeleteModuleFlags}; +/// +/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap(); +/// ``` +/// +/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) for more information. +pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> { + let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) }; + + Errno::result(res).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/lib.rs b/utshell-0.5.0/vendor/nix/src/lib.rs new file mode 100644 index 00000000..770258dd --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/lib.rs @@ -0,0 +1,334 @@ +//! Rust friendly bindings to the various *nix system functions. +//! +//! Modules are structured according to the C header file that they would be +//! defined in. +//! +//! # Features +//! +//! Nix uses the following Cargo features to enable optional functionality. +//! They may be enabled in any combination. +//! * `acct` - Process accounting +//! * `aio` - POSIX AIO +//! * `dir` - Stuff relating to directory iteration +//! * `env` - Manipulate environment variables +//! * `event` - Event-driven APIs, like `kqueue` and `epoll` +//! * `feature` - Query characteristics of the OS at runtime +//! * `fs` - File system functionality +//! * `hostname` - Get and set the system's hostname +//! * `inotify` - Linux's `inotify` file system notification API +//! * `ioctl` - The `ioctl` syscall, and wrappers for my specific instances +//! * `kmod` - Load and unload kernel modules +//! * `mman` - Stuff relating to memory management +//! * `mount` - Mount and unmount file systems +//! * `mqueue` - POSIX message queues +//! * `net` - Networking-related functionality +//! * `personality` - Set the process execution domain +//! * `poll` - APIs like `poll` and `select` +//! * `process` - Stuff relating to running processes +//! * `pthread` - POSIX threads +//! * `ptrace` - Process tracing and debugging +//! * `quota` - File system quotas +//! * `reboot` - Reboot the system +//! * `resource` - Process resource limits +//! * `sched` - Manipulate process's scheduling +//! * `socket` - Sockets, whether for networking or local use +//! * `signal` - Send and receive signals to processes +//! * `term` - Terminal control APIs +//! * `time` - Query the operating system's clocks +//! * `ucontext` - User thread context +//! * `uio` - Vectored I/O +//! * `user` - Stuff relating to users and groups +//! * `zerocopy` - APIs like `sendfile` and `copy_file_range` +#![crate_name = "nix"] +#![cfg(unix)] +#![cfg_attr(docsrs, doc(cfg(all())))] +#![allow(non_camel_case_types)] +#![cfg_attr(test, deny(warnings))] +#![recursion_limit = "500"] +#![deny(unused)] +#![allow(unused_macros)] +#![cfg_attr(not(feature = "default"), allow(unused_imports))] +#![deny(unstable_features)] +#![deny(missing_copy_implementations)] +#![deny(missing_debug_implementations)] +#![warn(missing_docs)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(clippy::cast_ptr_alignment)] + +// Re-exported external crates +pub use libc; + +// Private internal modules +#[macro_use] +mod macros; + +// Public crates +#[cfg(not(target_os = "redox"))] +feature! { + #![feature = "dir"] + pub mod dir; +} +feature! { + #![feature = "env"] + pub mod env; +} +#[allow(missing_docs)] +pub mod errno; +feature! { + #![feature = "feature"] + + #[deny(missing_docs)] + pub mod features; +} +#[allow(missing_docs)] +pub mod fcntl; +feature! { + #![feature = "net"] + + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] + #[deny(missing_docs)] + pub mod ifaddrs; + #[cfg(not(target_os = "redox"))] + #[deny(missing_docs)] + pub mod net; +} +#[cfg(any(target_os = "android", target_os = "linux"))] +feature! { + #![feature = "kmod"] + #[allow(missing_docs)] + pub mod kmod; +} +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +feature! { + #![feature = "mount"] + pub mod mount; +} +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd" +))] +feature! { + #![feature = "mqueue"] + pub mod mqueue; +} +feature! { + #![feature = "poll"] + pub mod poll; +} +#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] +feature! { + #![feature = "term"] + #[deny(missing_docs)] + pub mod pty; +} +feature! { + #![feature = "sched"] + pub mod sched; +} +pub mod sys; +feature! { + #![feature = "time"] + #[allow(missing_docs)] + pub mod time; +} +// This can be implemented for other platforms as soon as libc +// provides bindings for them. +#[cfg(all( + target_os = "linux", + any(target_arch = "s390x", target_arch = "x86", target_arch = "x86_64") +))] +feature! { + #![feature = "ucontext"] + #[allow(missing_docs)] + pub mod ucontext; +} +#[allow(missing_docs)] +pub mod unistd; + +use std::ffi::{CStr, CString, OsStr}; +use std::mem::MaybeUninit; +use std::os::unix::ffi::OsStrExt; +use std::path::{Path, PathBuf}; +use std::{ptr, result, slice}; + +use errno::Errno; + +/// Nix Result Type +pub type Result = result::Result; + +/// Nix's main error type. +/// +/// It's a wrapper around Errno. As such, it's very interoperable with +/// [`std::io::Error`], but it has the advantages of: +/// * `Clone` +/// * `Copy` +/// * `Eq` +/// * Small size +/// * Represents all of the system's errnos, instead of just the most common +/// ones. +pub type Error = Errno; + +/// Common trait used to represent file system paths by many Nix functions. +pub trait NixPath { + /// Is the path empty? + fn is_empty(&self) -> bool; + + /// Length of the path in bytes + fn len(&self) -> usize; + + /// Execute a function with this path as a `CStr`. + /// + /// Mostly used internally by Nix. + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T; +} + +impl NixPath for str { + fn is_empty(&self) -> bool { + NixPath::is_empty(OsStr::new(self)) + } + + fn len(&self) -> usize { + NixPath::len(OsStr::new(self)) + } + + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T, + { + OsStr::new(self).with_nix_path(f) + } +} + +impl NixPath for OsStr { + fn is_empty(&self) -> bool { + self.as_bytes().is_empty() + } + + fn len(&self) -> usize { + self.as_bytes().len() + } + + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T, + { + self.as_bytes().with_nix_path(f) + } +} + +impl NixPath for CStr { + fn is_empty(&self) -> bool { + self.to_bytes().is_empty() + } + + fn len(&self) -> usize { + self.to_bytes().len() + } + + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T, + { + Ok(f(self)) + } +} + +impl NixPath for [u8] { + fn is_empty(&self) -> bool { + self.is_empty() + } + + fn len(&self) -> usize { + self.len() + } + + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T, + { + // The real PATH_MAX is typically 4096, but it's statistically unlikely to have a path + // longer than ~300 bytes. See the the PR description to get stats for your own machine. + // https://github.com/nix-rust/nix/pull/1656 + // + // By being smaller than a memory page, we also avoid the compiler inserting a probe frame: + // https://docs.rs/compiler_builtins/latest/compiler_builtins/probestack/index.html + const MAX_STACK_ALLOCATION: usize = 1024; + + if self.len() >= MAX_STACK_ALLOCATION { + return with_nix_path_allocating(self, f); + } + + let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit(); + let buf_ptr = buf.as_mut_ptr() as *mut u8; + + unsafe { + ptr::copy_nonoverlapping(self.as_ptr(), buf_ptr, self.len()); + buf_ptr.add(self.len()).write(0); + } + + match CStr::from_bytes_with_nul(unsafe { + slice::from_raw_parts(buf_ptr, self.len() + 1) + }) { + Ok(s) => Ok(f(s)), + Err(_) => Err(Errno::EINVAL), + } + } +} + +#[cold] +#[inline(never)] +fn with_nix_path_allocating(from: &[u8], f: F) -> Result +where + F: FnOnce(&CStr) -> T, +{ + match CString::new(from) { + Ok(s) => Ok(f(&s)), + Err(_) => Err(Errno::EINVAL), + } +} + +impl NixPath for Path { + fn is_empty(&self) -> bool { + NixPath::is_empty(self.as_os_str()) + } + + fn len(&self) -> usize { + NixPath::len(self.as_os_str()) + } + + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T, + { + self.as_os_str().with_nix_path(f) + } +} + +impl NixPath for PathBuf { + fn is_empty(&self) -> bool { + NixPath::is_empty(self.as_os_str()) + } + + fn len(&self) -> usize { + NixPath::len(self.as_os_str()) + } + + fn with_nix_path(&self, f: F) -> Result + where + F: FnOnce(&CStr) -> T, + { + self.as_os_str().with_nix_path(f) + } +} diff --git a/utshell-0.5.0/vendor/nix/src/macros.rs b/utshell-0.5.0/vendor/nix/src/macros.rs new file mode 100644 index 00000000..99e0de88 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/macros.rs @@ -0,0 +1,328 @@ +// Thanks to Tokio for this macro +macro_rules! feature { + ( + #![$meta:meta] + $($item:item)* + ) => { + $( + #[cfg($meta)] + #[cfg_attr(docsrs, doc(cfg($meta)))] + $item + )* + } +} + +/// The `libc_bitflags!` macro helps with a common use case of defining a public bitflags type +/// with values from the libc crate. It is used the same way as the `bitflags!` macro, except +/// that only the name of the flag value has to be given. +/// +/// The `libc` crate must be in scope with the name `libc`. +/// +/// # Example +/// ```ignore +/// libc_bitflags!{ +/// pub struct ProtFlags: libc::c_int { +/// PROT_NONE; +/// PROT_READ; +/// /// PROT_WRITE enables write protect +/// PROT_WRITE; +/// PROT_EXEC; +/// #[cfg(any(target_os = "linux", target_os = "android"))] +/// PROT_GROWSDOWN; +/// #[cfg(any(target_os = "linux", target_os = "android"))] +/// PROT_GROWSUP; +/// } +/// } +/// ``` +/// +/// Example with casting, due to a mistake in libc. In this example, the +/// various flags have different types, so we cast the broken ones to the right +/// type. +/// +/// ```ignore +/// libc_bitflags!{ +/// pub struct SaFlags: libc::c_ulong { +/// SA_NOCLDSTOP as libc::c_ulong; +/// SA_NOCLDWAIT; +/// SA_NODEFER as libc::c_ulong; +/// SA_ONSTACK; +/// SA_RESETHAND as libc::c_ulong; +/// SA_RESTART as libc::c_ulong; +/// SA_SIGINFO; +/// } +/// } +/// ``` +macro_rules! libc_bitflags { + ( + $(#[$outer:meta])* + pub struct $BitFlags:ident: $T:ty { + $( + $(#[$inner:ident $($args:tt)*])* + $Flag:ident $(as $cast:ty)*; + )+ + } + ) => { + ::bitflags::bitflags! { + $(#[$outer])* + pub struct $BitFlags: $T { + $( + $(#[$inner $($args)*])* + const $Flag = libc::$Flag $(as $cast)*; + )+ + } + } + }; +} + +/// The `libc_enum!` macro helps with a common use case of defining an enum exclusively using +/// values from the `libc` crate. This macro supports both `pub` and private `enum`s. +/// +/// The `libc` crate must be in scope with the name `libc`. +/// +/// # Example +/// ```ignore +/// libc_enum!{ +/// pub enum ProtFlags { +/// PROT_NONE, +/// PROT_READ, +/// PROT_WRITE, +/// PROT_EXEC, +/// #[cfg(any(target_os = "linux", target_os = "android"))] +/// PROT_GROWSDOWN, +/// #[cfg(any(target_os = "linux", target_os = "android"))] +/// PROT_GROWSUP, +/// } +/// } +/// ``` +// Some targets don't use all rules. +#[allow(unknown_lints)] +#[allow(unused_macro_rules)] +macro_rules! libc_enum { + // Exit rule. + (@make_enum + name: $BitFlags:ident, + { + $v:vis + attrs: [$($attrs:tt)*], + entries: [$($entries:tt)*], + } + ) => { + $($attrs)* + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + $v enum $BitFlags { + $($entries)* + } + }; + + // Exit rule including TryFrom + (@make_enum + name: $BitFlags:ident, + { + $v:vis + attrs: [$($attrs:tt)*], + entries: [$($entries:tt)*], + from_type: $repr:path, + try_froms: [$($try_froms:tt)*] + } + ) => { + $($attrs)* + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + $v enum $BitFlags { + $($entries)* + } + impl ::std::convert::TryFrom<$repr> for $BitFlags { + type Error = $crate::Error; + #[allow(unused_doc_comments)] + fn try_from(x: $repr) -> $crate::Result { + match x { + $($try_froms)* + _ => Err($crate::Error::EINVAL) + } + } + } + }; + + // Done accumulating. + (@accumulate_entries + name: $BitFlags:ident, + { + $v:vis + attrs: $attrs:tt, + }, + $entries:tt, + $try_froms:tt; + ) => { + libc_enum! { + @make_enum + name: $BitFlags, + { + $v + attrs: $attrs, + entries: $entries, + } + } + }; + + // Done accumulating and want TryFrom + (@accumulate_entries + name: $BitFlags:ident, + { + $v:vis + attrs: $attrs:tt, + from_type: $repr:path, + }, + $entries:tt, + $try_froms:tt; + ) => { + libc_enum! { + @make_enum + name: $BitFlags, + { + $v + attrs: $attrs, + entries: $entries, + from_type: $repr, + try_froms: $try_froms + } + } + }; + + // Munch an attr. + (@accumulate_entries + name: $BitFlags:ident, + $prefix:tt, + [$($entries:tt)*], + [$($try_froms:tt)*]; + #[$attr:meta] $($tail:tt)* + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, + $prefix, + [ + $($entries)* + #[$attr] + ], + [ + $($try_froms)* + #[$attr] + ]; + $($tail)* + } + }; + + // Munch last ident if not followed by a comma. + (@accumulate_entries + name: $BitFlags:ident, + $prefix:tt, + [$($entries:tt)*], + [$($try_froms:tt)*]; + $entry:ident + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, + $prefix, + [ + $($entries)* + $entry = libc::$entry, + ], + [ + $($try_froms)* + libc::$entry => Ok($BitFlags::$entry), + ]; + } + }; + + // Munch an ident; covers terminating comma case. + (@accumulate_entries + name: $BitFlags:ident, + $prefix:tt, + [$($entries:tt)*], + [$($try_froms:tt)*]; + $entry:ident, + $($tail:tt)* + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, + $prefix, + [ + $($entries)* + $entry = libc::$entry, + ], + [ + $($try_froms)* + libc::$entry => Ok($BitFlags::$entry), + ]; + $($tail)* + } + }; + + // Munch an ident and cast it to the given type; covers terminating comma. + (@accumulate_entries + name: $BitFlags:ident, + $prefix:tt, + [$($entries:tt)*], + [$($try_froms:tt)*]; + $entry:ident as $ty:ty, + $($tail:tt)* + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, + $prefix, + [ + $($entries)* + $entry = libc::$entry as $ty, + ], + [ + $($try_froms)* + libc::$entry as $ty => Ok($BitFlags::$entry), + ]; + $($tail)* + } + }; + + // Entry rule. + ( + $(#[$attr:meta])* + $v:vis enum $BitFlags:ident { + $($vals:tt)* + } + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, + { + $v + attrs: [$(#[$attr])*], + }, + [], + []; + $($vals)* + } + }; + + // Entry rule including TryFrom + ( + $(#[$attr:meta])* + $v:vis enum $BitFlags:ident { + $($vals:tt)* + } + impl TryFrom<$repr:path> + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, + { + $v + attrs: [$(#[$attr])*], + from_type: $repr, + }, + [], + []; + $($vals)* + } + }; +} diff --git a/utshell-0.5.0/vendor/nix/src/mount/bsd.rs b/utshell-0.5.0/vendor/nix/src/mount/bsd.rs new file mode 100644 index 00000000..109522f9 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/mount/bsd.rs @@ -0,0 +1,443 @@ +use crate::{ + Error, + Errno, + NixPath, + Result, +}; +use libc::{c_char, c_int, c_uint, c_void}; +use std::{ + borrow::Cow, + ffi::{CString, CStr}, + fmt, + io, + marker::PhantomData, +}; + + +libc_bitflags!( + /// Used with [`Nmount::nmount`]. + pub struct MntFlags: c_int { + /// ACL support enabled. + #[cfg(any(target_os = "netbsd", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_ACLS; + /// All I/O to the file system should be done asynchronously. + MNT_ASYNC; + /// dir should instead be a file system ID encoded as “FSID:val0:val1â€. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_BYFSID; + /// Force a read-write mount even if the file system appears to be + /// unclean. + MNT_FORCE; + /// GEOM journal support enabled. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_GJOURNAL; + /// MAC support for objects. + #[cfg(any(target_os = "macos", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_MULTILABEL; + /// Disable read clustering. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_NOCLUSTERR; + /// Disable write clustering. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_NOCLUSTERW; + /// Enable NFS version 4 ACLs. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_NFS4ACLS; + /// Do not update access times. + MNT_NOATIME; + /// Disallow program execution. + MNT_NOEXEC; + /// Do not honor setuid or setgid bits on files when executing them. + MNT_NOSUID; + /// Do not follow symlinks. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_NOSYMFOLLOW; + /// Mount read-only. + MNT_RDONLY; + /// Causes the vfs subsystem to update its data structures pertaining to + /// the specified already mounted file system. + MNT_RELOAD; + /// Create a snapshot of the file system. + /// + /// See [mksnap_ffs(8)](https://www.freebsd.org/cgi/man.cgi?query=mksnap_ffs) + #[cfg(any(target_os = "macos", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_SNAPSHOT; + /// Using soft updates. + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_SOFTDEP; + /// Directories with the SUID bit set chown new files to their own + /// owner. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_SUIDDIR; + /// All I/O to the file system should be done synchronously. + MNT_SYNCHRONOUS; + /// Union with underlying fs. + #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_UNION; + /// Indicates that the mount command is being applied to an already + /// mounted file system. + MNT_UPDATE; + /// Check vnode use counts. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MNT_NONBUSY; + } +); + + +/// The Error type of [`Nmount::nmount`]. +/// +/// It wraps an [`Errno`], but also may contain an additional message returned +/// by `nmount(2)`. +#[derive(Debug)] +pub struct NmountError { + errno: Error, + errmsg: Option +} + +impl NmountError { + /// Returns the additional error string sometimes generated by `nmount(2)`. + pub fn errmsg(&self) -> Option<&str> { + self.errmsg.as_deref() + } + + /// Returns the inner [`Error`] + pub const fn error(&self) -> Error { + self.errno + } + + fn new(error: Error, errmsg: Option<&CStr>) -> Self { + Self { + errno: error, + errmsg: errmsg.map(CStr::to_string_lossy).map(Cow::into_owned) + } + } +} + +impl std::error::Error for NmountError {} + +impl fmt::Display for NmountError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(errmsg) = &self.errmsg { + write!(f, "{:?}: {}: {}", self.errno, errmsg, self.errno.desc()) + } else { + write!(f, "{:?}: {}", self.errno, self.errno.desc()) + } + } +} + +impl From for io::Error { + fn from(err: NmountError) -> Self { + err.errno.into() + } +} + +/// Result type of [`Nmount::nmount`]. +pub type NmountResult = std::result::Result<(), NmountError>; + +/// Mount a FreeBSD file system. +/// +/// The `nmount(2)` system call works similarly to the `mount(8)` program; it +/// takes its options as a series of name-value pairs. Most of the values are +/// strings, as are all of the names. The `Nmount` structure builds up an +/// argument list and then executes the syscall. +/// +/// # Examples +/// +/// To mount `target` onto `mountpoint` with `nullfs`: +/// ``` +/// # use nix::unistd::Uid; +/// # use ::sysctl::{CtlValue, Sysctl}; +/// # let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap(); +/// # if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap() { +/// # return; +/// # }; +/// use nix::mount::{MntFlags, Nmount, unmount}; +/// use std::ffi::CString; +/// use tempfile::tempdir; +/// +/// let mountpoint = tempdir().unwrap(); +/// let target = tempdir().unwrap(); +/// +/// let fstype = CString::new("fstype").unwrap(); +/// let nullfs = CString::new("nullfs").unwrap(); +/// Nmount::new() +/// .str_opt(&fstype, &nullfs) +/// .str_opt_owned("fspath", mountpoint.path().to_str().unwrap()) +/// .str_opt_owned("target", target.path().to_str().unwrap()) +/// .nmount(MntFlags::empty()).unwrap(); +/// +/// unmount(mountpoint.path(), MntFlags::empty()).unwrap(); +/// ``` +/// +/// # See Also +/// * [`nmount(2)`](https://www.freebsd.org/cgi/man.cgi?query=nmount) +/// * [`nullfs(5)`](https://www.freebsd.org/cgi/man.cgi?query=nullfs) +#[cfg(target_os = "freebsd")] +#[cfg_attr(docsrs, doc(cfg(all())))] +#[derive(Debug, Default)] +pub struct Nmount<'a>{ + // n.b. notgull: In reality, this is a list that contains + // both mutable and immutable pointers. + // Be careful using this. + iov: Vec, + is_owned: Vec, + marker: PhantomData<&'a ()>, +} + +#[cfg(target_os = "freebsd")] +#[cfg_attr(docsrs, doc(cfg(all())))] +impl<'a> Nmount<'a> { + /// Helper function to push a slice onto the `iov` array. + fn push_slice(&mut self, val: &'a [u8], is_owned: bool) { + self.iov.push(libc::iovec { + iov_base: val.as_ptr() as *mut _, + iov_len: val.len(), + }); + self.is_owned.push(is_owned); + } + + /// Helper function to push a pointer and its length onto the `iov` array. + fn push_pointer_and_length(&mut self, val: *const u8, len: usize, is_owned: bool) { + self.iov.push(libc::iovec { + iov_base: val as *mut _, + iov_len: len, + }); + self.is_owned.push(is_owned); + } + + /// Helper function to push a `nix` path as owned. + fn push_nix_path(&mut self, val: &P) { + val.with_nix_path(|s| { + let len = s.to_bytes_with_nul().len(); + let ptr = s.to_owned().into_raw() as *const u8; + + self.push_pointer_and_length(ptr, len, true); + }).unwrap(); + } + + /// Add an opaque mount option. + /// + /// Some file systems take binary-valued mount options. They can be set + /// with this method. + /// + /// # Safety + /// + /// Unsafe because it will cause `Nmount::nmount` to dereference a raw + /// pointer. The user is responsible for ensuring that `val` is valid and + /// its lifetime outlives `self`! An easy way to do that is to give the + /// value a larger scope than `name` + /// + /// # Examples + /// ``` + /// use libc::c_void; + /// use nix::mount::Nmount; + /// use std::ffi::CString; + /// use std::mem; + /// + /// // Note that flags outlives name + /// let mut flags: u32 = 0xdeadbeef; + /// let name = CString::new("flags").unwrap(); + /// let p = &mut flags as *mut u32 as *mut c_void; + /// let len = mem::size_of_val(&flags); + /// let mut nmount = Nmount::new(); + /// unsafe { nmount.mut_ptr_opt(&name, p, len) }; + /// ``` + pub unsafe fn mut_ptr_opt( + &mut self, + name: &'a CStr, + val: *mut c_void, + len: usize + ) -> &mut Self + { + self.push_slice(name.to_bytes_with_nul(), false); + self.push_pointer_and_length(val.cast(), len, false); + self + } + + /// Add a mount option that does not take a value. + /// + /// # Examples + /// ``` + /// use nix::mount::Nmount; + /// use std::ffi::CString; + /// + /// let read_only = CString::new("ro").unwrap(); + /// Nmount::new() + /// .null_opt(&read_only); + /// ``` + pub fn null_opt(&mut self, name: &'a CStr) -> &mut Self { + self.push_slice(name.to_bytes_with_nul(), false); + self.push_slice(&[], false); + self + } + + /// Add a mount option that does not take a value, but whose name must be + /// owned. + /// + /// + /// This has higher runtime cost than [`Nmount::null_opt`], but is useful + /// when the name's lifetime doesn't outlive the `Nmount`, or it's a + /// different string type than `CStr`. + /// + /// # Examples + /// ``` + /// use nix::mount::Nmount; + /// + /// let read_only = "ro"; + /// let mut nmount: Nmount<'static> = Nmount::new(); + /// nmount.null_opt_owned(read_only); + /// ``` + pub fn null_opt_owned(&mut self, name: &P) -> &mut Self + { + self.push_nix_path(name); + self.push_slice(&[], false); + self + } + + /// Add a mount option as a [`CStr`]. + /// + /// # Examples + /// ``` + /// use nix::mount::Nmount; + /// use std::ffi::CString; + /// + /// let fstype = CString::new("fstype").unwrap(); + /// let nullfs = CString::new("nullfs").unwrap(); + /// Nmount::new() + /// .str_opt(&fstype, &nullfs); + /// ``` + pub fn str_opt( + &mut self, + name: &'a CStr, + val: &'a CStr + ) -> &mut Self + { + self.push_slice(name.to_bytes_with_nul(), false); + self.push_slice(val.to_bytes_with_nul(), false); + self + } + + /// Add a mount option as an owned string. + /// + /// This has higher runtime cost than [`Nmount::str_opt`], but is useful + /// when the value's lifetime doesn't outlive the `Nmount`, or it's a + /// different string type than `CStr`. + /// + /// # Examples + /// ``` + /// use nix::mount::Nmount; + /// use std::path::Path; + /// + /// let mountpoint = Path::new("/mnt"); + /// Nmount::new() + /// .str_opt_owned("fspath", mountpoint.to_str().unwrap()); + /// ``` + pub fn str_opt_owned(&mut self, name: &P1, val: &P2) -> &mut Self + where P1: ?Sized + NixPath, + P2: ?Sized + NixPath + { + self.push_nix_path(name); + self.push_nix_path(val); + self + } + + /// Create a new `Nmount` struct with no options + pub fn new() -> Self { + Self::default() + } + + /// Actually mount the file system. + pub fn nmount(&mut self, flags: MntFlags) -> NmountResult { + const ERRMSG_NAME: &[u8] = b"errmsg\0"; + let mut errmsg = vec![0u8; 255]; + + // nmount can return extra error information via a "errmsg" return + // argument. + self.push_slice(ERRMSG_NAME, false); + + // SAFETY: we are pushing a mutable iovec here, so we can't use + // the above method + self.iov.push(libc::iovec { + iov_base: errmsg.as_mut_ptr() as *mut c_void, + iov_len: errmsg.len(), + }); + + let niov = self.iov.len() as c_uint; + let iovp = self.iov.as_mut_ptr() as *mut libc::iovec; + let res = unsafe { + libc::nmount(iovp, niov, flags.bits) + }; + match Errno::result(res) { + Ok(_) => Ok(()), + Err(error) => { + let errmsg = match errmsg.iter().position(|&x| x == 0) { + None => None, + Some(0) => None, + Some(n) => { + let sl = &errmsg[0..n + 1]; + Some(CStr::from_bytes_with_nul(sl).unwrap()) + } + }; + Err(NmountError::new(error, errmsg)) + } + } + } +} + +#[cfg(target_os = "freebsd")] +impl<'a> Drop for Nmount<'a> { + fn drop(&mut self) { + for (iov, is_owned) in self.iov.iter().zip(self.is_owned.iter()) { + if *is_owned { + // Free the owned string. Safe because we recorded ownership, + // and Nmount does not implement Clone. + unsafe { + drop(CString::from_raw(iov.iov_base as *mut c_char)); + } + } + } + } +} + +/// Unmount the file system mounted at `mountpoint`. +/// +/// Useful flags include +/// * `MNT_FORCE` - Unmount even if still in use. +/// * `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID +/// encoded as `FSID:val0:val1`, where `val0` and `val1` +/// are the contents of the `fsid_t val[]` array in decimal. +/// The file system that has the specified file system ID +/// will be unmounted. See +/// [`statfs`](crate::sys::statfs::statfs) to determine the +/// `fsid`. +pub fn unmount

(mountpoint: &P, flags: MntFlags) -> Result<()> + where P: ?Sized + NixPath +{ + let res = mountpoint.with_nix_path(|cstr| { + unsafe { libc::unmount(cstr.as_ptr(), flags.bits) } + })?; + + Errno::result(res).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/mount/linux.rs b/utshell-0.5.0/vendor/nix/src/mount/linux.rs new file mode 100644 index 00000000..4c976dcb --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/mount/linux.rs @@ -0,0 +1,112 @@ +#![allow(missing_docs)] +use libc::{self, c_ulong, c_int}; +use crate::{Result, NixPath}; +use crate::errno::Errno; + +libc_bitflags!( + pub struct MsFlags: c_ulong { + /// Mount read-only + MS_RDONLY; + /// Ignore suid and sgid bits + MS_NOSUID; + /// Disallow access to device special files + MS_NODEV; + /// Disallow program execution + MS_NOEXEC; + /// Writes are synced at once + MS_SYNCHRONOUS; + /// Alter flags of a mounted FS + MS_REMOUNT; + /// Allow mandatory locks on a FS + MS_MANDLOCK; + /// Directory modifications are synchronous + MS_DIRSYNC; + /// Do not update access times + MS_NOATIME; + /// Do not update directory access times + MS_NODIRATIME; + /// Linux 2.4.0 - Bind directory at different place + MS_BIND; + MS_MOVE; + MS_REC; + MS_SILENT; + MS_POSIXACL; + MS_UNBINDABLE; + MS_PRIVATE; + MS_SLAVE; + MS_SHARED; + MS_RELATIME; + MS_KERNMOUNT; + MS_I_VERSION; + MS_STRICTATIME; + MS_LAZYTIME; + MS_ACTIVE; + MS_NOUSER; + MS_RMT_MASK; + MS_MGC_VAL; + MS_MGC_MSK; + } +); + +libc_bitflags!( + pub struct MntFlags: c_int { + MNT_FORCE; + MNT_DETACH; + MNT_EXPIRE; + UMOUNT_NOFOLLOW; + } +); + +pub fn mount( + source: Option<&P1>, + target: &P2, + fstype: Option<&P3>, + flags: MsFlags, + data: Option<&P4>) -> Result<()> { + + fn with_opt_nix_path(p: Option<&P>, f: F) -> Result + where P: ?Sized + NixPath, + F: FnOnce(*const libc::c_char) -> T + { + match p { + Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())), + None => Ok(f(std::ptr::null())) + } + } + + let res = with_opt_nix_path(source, |s| { + target.with_nix_path(|t| { + with_opt_nix_path(fstype, |ty| { + with_opt_nix_path(data, |d| { + unsafe { + libc::mount( + s, + t.as_ptr(), + ty, + flags.bits, + d as *const libc::c_void + ) + } + }) + }) + }) + })????; + + Errno::result(res).map(drop) +} + +pub fn umount(target: &P) -> Result<()> { + let res = target.with_nix_path(|cstr| { + unsafe { libc::umount(cstr.as_ptr()) } + })?; + + Errno::result(res).map(drop) +} + +pub fn umount2(target: &P, flags: MntFlags) -> Result<()> { + let res = target.with_nix_path(|cstr| { + unsafe { libc::umount2(cstr.as_ptr(), flags.bits) } + })?; + + Errno::result(res).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/mount/mod.rs b/utshell-0.5.0/vendor/nix/src/mount/mod.rs new file mode 100644 index 00000000..e89c1a07 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/mount/mod.rs @@ -0,0 +1,23 @@ +//! Mount file systems +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod linux; + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use self::linux::*; + +#[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod bsd; + +#[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd" + ))] +pub use self::bsd::*; diff --git a/utshell-0.5.0/vendor/nix/src/mqueue.rs b/utshell-0.5.0/vendor/nix/src/mqueue.rs new file mode 100644 index 00000000..e3c0c43e --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/mqueue.rs @@ -0,0 +1,248 @@ +//! Posix Message Queue functions +//! +//! # Example +//! +// no_run because a kernel module may be required. +//! ```no_run +//! # use std::ffi::CString; +//! # use nix::mqueue::*; +//! use nix::sys::stat::Mode; +//! +//! const MSG_SIZE: mq_attr_member_t = 32; +//! let mq_name= CString::new("/a_nix_test_queue").unwrap(); +//! +//! let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; +//! let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; +//! let mqd0 = mq_open(&mq_name, oflag0, mode, None).unwrap(); +//! let msg_to_send = b"msg_1"; +//! mq_send(&mqd0, msg_to_send, 1).unwrap(); +//! +//! let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY; +//! let mqd1 = mq_open(&mq_name, oflag1, mode, None).unwrap(); +//! let mut buf = [0u8; 32]; +//! let mut prio = 0u32; +//! let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap(); +//! assert_eq!(prio, 1); +//! assert_eq!(msg_to_send, &buf[0..len]); +//! +//! mq_close(mqd1).unwrap(); +//! mq_close(mqd0).unwrap(); +//! ``` +//! [Further reading and details on the C API](https://man7.org/linux/man-pages/man7/mq_overview.7.html) + +use crate::Result; +use crate::errno::Errno; + +use libc::{self, c_char, mqd_t, size_t}; +use std::ffi::CStr; +use crate::sys::stat::Mode; +use std::mem; + +libc_bitflags!{ + /// Used with [`mq_open`]. + pub struct MQ_OFlag: libc::c_int { + /// Open the message queue for receiving messages. + O_RDONLY; + /// Open the queue for sending messages. + O_WRONLY; + /// Open the queue for both receiving and sending messages + O_RDWR; + /// Create a message queue. + O_CREAT; + /// If set along with `O_CREAT`, `mq_open` will fail if the message + /// queue name exists. + O_EXCL; + /// `mq_send` and `mq_receive` should fail with `EAGAIN` rather than + /// wait for resources that are not currently available. + O_NONBLOCK; + /// Set the close-on-exec flag for the message queue descriptor. + O_CLOEXEC; + } +} + +/// A message-queue attribute, optionally used with [`mq_setattr`] and +/// [`mq_getattr`] and optionally [`mq_open`], +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct MqAttr { + mq_attr: libc::mq_attr, +} + +/// Identifies an open POSIX Message Queue +// A safer wrapper around libc::mqd_t, which is a pointer on some platforms +// Deliberately is not Clone to prevent use-after-close scenarios +#[repr(transparent)] +#[derive(Debug)] +#[allow(missing_copy_implementations)] +pub struct MqdT(mqd_t); + +// x32 compatibility +// See https://sourceware.org/bugzilla/show_bug.cgi?id=21279 +/// Size of a message queue attribute member +#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub type mq_attr_member_t = i64; +/// Size of a message queue attribute member +#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub type mq_attr_member_t = libc::c_long; + +impl MqAttr { + /// Create a new message queue attribute + /// + /// # Arguments + /// + /// - `mq_flags`: Either `0` or `O_NONBLOCK`. + /// - `mq_maxmsg`: Maximum number of messages on the queue. + /// - `mq_msgsize`: Maximum message size in bytes. + /// - `mq_curmsgs`: Number of messages currently in the queue. + pub fn new(mq_flags: mq_attr_member_t, + mq_maxmsg: mq_attr_member_t, + mq_msgsize: mq_attr_member_t, + mq_curmsgs: mq_attr_member_t) + -> MqAttr + { + let mut attr = mem::MaybeUninit::::uninit(); + unsafe { + let p = attr.as_mut_ptr(); + (*p).mq_flags = mq_flags; + (*p).mq_maxmsg = mq_maxmsg; + (*p).mq_msgsize = mq_msgsize; + (*p).mq_curmsgs = mq_curmsgs; + MqAttr { mq_attr: attr.assume_init() } + } + } + + /// The current flags, either `0` or `O_NONBLOCK`. + pub const fn flags(&self) -> mq_attr_member_t { + self.mq_attr.mq_flags + } + + /// The max number of messages that can be held by the queue + pub const fn maxmsg(&self) -> mq_attr_member_t { + self.mq_attr.mq_maxmsg + } + + /// The maximum size of each message (in bytes) + pub const fn msgsize(&self) -> mq_attr_member_t { + self.mq_attr.mq_msgsize + } + + /// The number of messages currently held in the queue + pub const fn curmsgs(&self) -> mq_attr_member_t { + self.mq_attr.mq_curmsgs + } +} + + +/// Open a message queue +/// +/// See also [`mq_open(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html) +// The mode.bits cast is only lossless on some OSes +#[allow(clippy::cast_lossless)] +pub fn mq_open(name: &CStr, + oflag: MQ_OFlag, + mode: Mode, + attr: Option<&MqAttr>) + -> Result { + let res = match attr { + Some(mq_attr) => unsafe { + libc::mq_open(name.as_ptr(), + oflag.bits(), + mode.bits() as libc::c_int, + &mq_attr.mq_attr as *const libc::mq_attr) + }, + None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) }, + }; + Errno::result(res).map(MqdT) +} + +/// Remove a message queue +/// +/// See also [`mq_unlink(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html) +pub fn mq_unlink(name: &CStr) -> Result<()> { + let res = unsafe { libc::mq_unlink(name.as_ptr()) }; + Errno::result(res).map(drop) +} + +/// Close a message queue +/// +/// See also [`mq_close(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html) +pub fn mq_close(mqdes: MqdT) -> Result<()> { + let res = unsafe { libc::mq_close(mqdes.0) }; + Errno::result(res).map(drop) +} + +/// Receive a message from a message queue +/// +/// See also [`mq_receive(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html) +pub fn mq_receive(mqdes: &MqdT, message: &mut [u8], msg_prio: &mut u32) -> Result { + let len = message.len() as size_t; + let res = unsafe { + libc::mq_receive(mqdes.0, + message.as_mut_ptr() as *mut c_char, + len, + msg_prio as *mut u32) + }; + Errno::result(res).map(|r| r as usize) +} + +/// Send a message to a message queue +/// +/// See also [`mq_send(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html) +pub fn mq_send(mqdes: &MqdT, message: &[u8], msq_prio: u32) -> Result<()> { + let res = unsafe { + libc::mq_send(mqdes.0, + message.as_ptr() as *const c_char, + message.len(), + msq_prio) + }; + Errno::result(res).map(drop) +} + +/// Get message queue attributes +/// +/// See also [`mq_getattr(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html) +pub fn mq_getattr(mqd: &MqdT) -> Result { + let mut attr = mem::MaybeUninit::::uninit(); + let res = unsafe { libc::mq_getattr(mqd.0, attr.as_mut_ptr()) }; + Errno::result(res).map(|_| unsafe{MqAttr { mq_attr: attr.assume_init() }}) +} + +/// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored +/// Returns the old attributes +/// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html) +pub fn mq_setattr(mqd: &MqdT, newattr: &MqAttr) -> Result { + let mut attr = mem::MaybeUninit::::uninit(); + let res = unsafe { + libc::mq_setattr(mqd.0, &newattr.mq_attr as *const libc::mq_attr, attr.as_mut_ptr()) + }; + Errno::result(res).map(|_| unsafe{ MqAttr { mq_attr: attr.assume_init() }}) +} + +/// Convenience function. +/// Sets the `O_NONBLOCK` attribute for a given message queue descriptor +/// Returns the old attributes +#[allow(clippy::useless_conversion)] // Not useless on all OSes +pub fn mq_set_nonblock(mqd: &MqdT) -> Result { + let oldattr = mq_getattr(mqd)?; + let newattr = MqAttr::new(mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()), + oldattr.mq_attr.mq_maxmsg, + oldattr.mq_attr.mq_msgsize, + oldattr.mq_attr.mq_curmsgs); + mq_setattr(mqd, &newattr) +} + +/// Convenience function. +/// Removes `O_NONBLOCK` attribute for a given message queue descriptor +/// Returns the old attributes +pub fn mq_remove_nonblock(mqd: &MqdT) -> Result { + let oldattr = mq_getattr(mqd)?; + let newattr = MqAttr::new(0, + oldattr.mq_attr.mq_maxmsg, + oldattr.mq_attr.mq_msgsize, + oldattr.mq_attr.mq_curmsgs); + mq_setattr(mqd, &newattr) +} diff --git a/utshell-0.5.0/vendor/nix/src/net/if_.rs b/utshell-0.5.0/vendor/nix/src/net/if_.rs new file mode 100644 index 00000000..045efad9 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/net/if_.rs @@ -0,0 +1,468 @@ +//! Network interface name resolution. +//! +//! Uses Linux and/or POSIX functions to resolve interface names like "eth0" +//! or "socan1" into device numbers. + +use crate::{Error, NixPath, Result}; +use libc::c_uint; + +/// Resolve an interface into a interface number. +pub fn if_nametoindex(name: &P) -> Result { + let if_index = name.with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?; + + if if_index == 0 { + Err(Error::last()) + } else { + Ok(if_index) + } +} + +libc_bitflags!( + /// Standard interface flags, used by `getifaddrs` + pub struct InterfaceFlags: libc::c_int { + /// Interface is running. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_UP; + /// Valid broadcast address set. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_BROADCAST; + /// Internal debugging flag. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(not(target_os = "haiku"))] + IFF_DEBUG; + /// Interface is a loopback interface. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_LOOPBACK; + /// Interface is a point-to-point link. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_POINTOPOINT; + /// Avoid use of trailers. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOTRAILERS; + /// Interface manages own routes. + #[cfg(any(target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_SMART; + /// Resources allocated. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_RUNNING; + /// No arp protocol, L2 destination address not set. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_NOARP; + /// Interface is in promiscuous mode. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_PROMISC; + /// Receive all multicast packets. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_ALLMULTI; + /// Master of a load balancing bundle. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_MASTER; + /// transmission in progress, tx hardware queue is full + #[cfg(any(target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_OACTIVE; + /// Protocol code on board. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_INTELLIGENT; + /// Slave of a load balancing bundle. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_SLAVE; + /// Can't hear own transmissions. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_SIMPLEX; + /// Supports multicast. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_MULTICAST; + /// Per link layer defined bit. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LINK0; + /// Multicast using broadcast. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_MULTI_BCAST; + /// Is able to select media type via ifmap. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PORTSEL; + /// Per link layer defined bit. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LINK1; + /// Non-unique address. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_UNNUMBERED; + /// Auto media selection active. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_AUTOMEDIA; + /// Per link layer defined bit. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LINK2; + /// Use alternate physical connection. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "ios"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ALTPHYS; + /// DHCP controls interface. + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DHCPRUNNING; + /// The addresses are lost when the interface goes down. (see + /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DYNAMIC; + /// Do not advertise. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PRIVATE; + /// Driver signals L1 up. Volatile. + #[cfg(any(target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LOWER_UP; + /// Interface is in polling mode. + #[cfg(any(target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_POLLING_COMPAT; + /// Unconfigurable using ioctl(2). + #[cfg(any(target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_CANTCONFIG; + /// Do not transmit packets. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOXMIT; + /// Driver signals dormant. Volatile. + #[cfg(any(target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DORMANT; + /// User-requested promisc mode. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PPROMISC; + /// Just on-link subnet. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOLOCAL; + /// Echo sent packets. Volatile. + #[cfg(any(target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ECHO; + /// User-requested monitor mode. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_MONITOR; + /// Address is deprecated. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DEPRECATED; + /// Static ARP. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_STATICARP; + /// Address from stateless addrconf. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ADDRCONF; + /// Interface is in polling mode. + #[cfg(any(target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NPOLLING; + /// Router on interface. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ROUTER; + /// Interface is in polling mode. + #[cfg(any(target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IDIRECT; + /// Interface is winding down + #[cfg(any(target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DYING; + /// No NUD on interface. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NONUD; + /// Interface is being renamed + #[cfg(any(target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_RENAMING; + /// Anycast address. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ANYCAST; + /// Don't exchange routing info. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NORTEXCH; + /// Do not provide packet information + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NO_PI as libc::c_int; + /// TUN device (no Ethernet headers) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_TUN as libc::c_int; + /// TAP device + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_TAP as libc::c_int; + /// IPv4 interface. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IPV4; + /// IPv6 interface. + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IPV6; + /// in.mpathd test address + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOFAILOVER; + /// Interface has failed + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_FAILED; + /// Interface is a hot-spare + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_STANDBY; + /// Functioning but not used + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_INACTIVE; + /// Interface is offline + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_OFFLINE; + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_COS_ENABLED; + /// Prefer as source addr. + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PREFERRED; + /// RFC3041 + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_TEMPORARY; + /// MTU set with SIOCSLIFMTU + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_FIXEDMTU; + /// Cannot send / receive packets + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_VIRTUAL; + /// Local address in use + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DUPLICATE; + /// IPMP IP interface + #[cfg(target_os = "solaris")] + #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IPMP; + } +); + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod if_nameindex { + use super::*; + + use std::ffi::CStr; + use std::fmt; + use std::marker::PhantomData; + use std::ptr::NonNull; + + /// A network interface. Has a name like "eth0" or "wlp4s0" or "wlan0", as well as an index + /// (1, 2, 3, etc) that identifies it in the OS's networking stack. + #[allow(missing_copy_implementations)] + #[repr(transparent)] + pub struct Interface(libc::if_nameindex); + + impl Interface { + /// Obtain the index of this interface. + pub fn index(&self) -> c_uint { + self.0.if_index + } + + /// Obtain the name of this interface. + pub fn name(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.if_name) } + } + } + + impl fmt::Debug for Interface { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Interface") + .field("index", &self.index()) + .field("name", &self.name()) + .finish() + } + } + + /// A list of the network interfaces available on this system. Obtained from [`if_nameindex()`]. + pub struct Interfaces { + ptr: NonNull, + } + + impl Interfaces { + /// Iterate over the interfaces in this list. + #[inline] + pub fn iter(&self) -> InterfacesIter<'_> { + self.into_iter() + } + + /// Convert this to a slice of interfaces. Note that the underlying interfaces list is + /// null-terminated, so calling this calculates the length. If random access isn't needed, + /// [`Interfaces::iter()`] should be used instead. + pub fn to_slice(&self) -> &[Interface] { + let ifs = self.ptr.as_ptr() as *const Interface; + let len = self.iter().count(); + unsafe { std::slice::from_raw_parts(ifs, len) } + } + } + + impl Drop for Interfaces { + fn drop(&mut self) { + unsafe { libc::if_freenameindex(self.ptr.as_ptr()) }; + } + } + + impl fmt::Debug for Interfaces { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.to_slice().fmt(f) + } + } + + impl<'a> IntoIterator for &'a Interfaces { + type IntoIter = InterfacesIter<'a>; + type Item = &'a Interface; + #[inline] + fn into_iter(self) -> Self::IntoIter { + InterfacesIter { + ptr: self.ptr.as_ptr(), + _marker: PhantomData, + } + } + } + + /// An iterator over the interfaces in an [`Interfaces`]. + #[derive(Debug)] + pub struct InterfacesIter<'a> { + ptr: *const libc::if_nameindex, + _marker: PhantomData<&'a Interfaces>, + } + + impl<'a> Iterator for InterfacesIter<'a> { + type Item = &'a Interface; + #[inline] + fn next(&mut self) -> Option { + unsafe { + if (*self.ptr).if_index == 0 { + None + } else { + let ret = &*(self.ptr as *const Interface); + self.ptr = self.ptr.add(1); + Some(ret) + } + } + } + } + + /// Retrieve a list of the network interfaces available on the local system. + /// + /// ``` + /// let interfaces = nix::net::if_::if_nameindex().unwrap(); + /// for iface in &interfaces { + /// println!("Interface #{} is called {}", iface.index(), iface.name().to_string_lossy()); + /// } + /// ``` + pub fn if_nameindex() -> Result { + unsafe { + let ifs = libc::if_nameindex(); + let ptr = NonNull::new(ifs).ok_or_else(Error::last)?; + Ok(Interfaces { ptr }) + } + } +} +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +pub use if_nameindex::*; diff --git a/utshell-0.5.0/vendor/nix/src/net/mod.rs b/utshell-0.5.0/vendor/nix/src/net/mod.rs new file mode 100644 index 00000000..079fcfde --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/net/mod.rs @@ -0,0 +1,4 @@ +//! Functionality involving network interfaces +// To avoid clashing with the keyword "if", we use "if_" as the module name. +// The original header is called "net/if.h". +pub mod if_; diff --git a/utshell-0.5.0/vendor/nix/src/poll.rs b/utshell-0.5.0/vendor/nix/src/poll.rs new file mode 100644 index 00000000..3004d24c --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/poll.rs @@ -0,0 +1,175 @@ +//! Wait for events to trigger on specific file descriptors +use std::os::unix::io::{AsRawFd, RawFd}; + +use crate::Result; +use crate::errno::Errno; + +/// This is a wrapper around `libc::pollfd`. +/// +/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and +/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest +/// for a specific file descriptor. +/// +/// After a call to `poll` or `ppoll`, the events that occurred can be +/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`. +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct PollFd { + pollfd: libc::pollfd, +} + +impl PollFd { + /// Creates a new `PollFd` specifying the events of interest + /// for a given file descriptor. + pub const fn new(fd: RawFd, events: PollFlags) -> PollFd { + PollFd { + pollfd: libc::pollfd { + fd, + events: events.bits(), + revents: PollFlags::empty().bits(), + }, + } + } + + /// Returns the events that occurred in the last call to `poll` or `ppoll`. Will only return + /// `None` if the kernel provides status flags that Nix does not know about. + pub fn revents(self) -> Option { + PollFlags::from_bits(self.pollfd.revents) + } + + /// The events of interest for this `PollFd`. + pub fn events(self) -> PollFlags { + PollFlags::from_bits(self.pollfd.events).unwrap() + } + + /// Modify the events of interest for this `PollFd`. + pub fn set_events(&mut self, events: PollFlags) { + self.pollfd.events = events.bits(); + } +} + +impl AsRawFd for PollFd { + fn as_raw_fd(&self) -> RawFd { + self.pollfd.fd + } +} + +libc_bitflags! { + /// These flags define the different events that can be monitored by `poll` and `ppoll` + pub struct PollFlags: libc::c_short { + /// There is data to read. + POLLIN; + /// There is some exceptional condition on the file descriptor. + /// + /// Possibilities include: + /// + /// * There is out-of-band data on a TCP socket (see + /// [tcp(7)](https://man7.org/linux/man-pages/man7/tcp.7.html)). + /// * A pseudoterminal master in packet mode has seen a state + /// change on the slave (see + /// [ioctl_tty(2)](https://man7.org/linux/man-pages/man2/ioctl_tty.2.html)). + /// * A cgroup.events file has been modified (see + /// [cgroups(7)](https://man7.org/linux/man-pages/man7/cgroups.7.html)). + POLLPRI; + /// Writing is now possible, though a write larger that the + /// available space in a socket or pipe will still block (unless + /// `O_NONBLOCK` is set). + POLLOUT; + /// Equivalent to [`POLLIN`](constant.POLLIN.html) + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + POLLRDNORM; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Equivalent to [`POLLOUT`](constant.POLLOUT.html) + POLLWRNORM; + /// Priority band data can be read (generally unused on Linux). + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + POLLRDBAND; + /// Priority data may be written. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + POLLWRBAND; + /// Error condition (only returned in + /// [`PollFd::revents`](struct.PollFd.html#method.revents); + /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)). + /// This bit is also set for a file descriptor referring to the + /// write end of a pipe when the read end has been closed. + POLLERR; + /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents); + /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)). + /// Note that when reading from a channel such as a pipe or a stream + /// socket, this event merely indicates that the peer closed its + /// end of the channel. Subsequent reads from the channel will + /// return 0 (end of file) only after all outstanding data in the + /// channel has been consumed. + POLLHUP; + /// Invalid request: `fd` not open (only returned in + /// [`PollFd::revents`](struct.PollFd.html#method.revents); + /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)). + POLLNVAL; + } +} + +/// `poll` waits for one of a set of file descriptors to become ready to perform I/O. +/// ([`poll(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)) +/// +/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll. +/// The function will return as soon as any event occur for any of these `PollFd`s. +/// +/// The `timeout` argument specifies the number of milliseconds that `poll()` +/// should block waiting for a file descriptor to become ready. The call +/// will block until either: +/// +/// * a file descriptor becomes ready; +/// * the call is interrupted by a signal handler; or +/// * the timeout expires. +/// +/// Note that the timeout interval will be rounded up to the system clock +/// granularity, and kernel scheduling delays mean that the blocking +/// interval may overrun by a small amount. Specifying a negative value +/// in timeout means an infinite timeout. Specifying a timeout of zero +/// causes `poll()` to return immediately, even if no file descriptors are +/// ready. +pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result { + let res = unsafe { + libc::poll(fds.as_mut_ptr() as *mut libc::pollfd, + fds.len() as libc::nfds_t, + timeout) + }; + + Errno::result(res) +} + +feature! { +#![feature = "signal"] +/// `ppoll()` allows an application to safely wait until either a file +/// descriptor becomes ready or until a signal is caught. +/// ([`poll(2)`](https://man7.org/linux/man-pages/man2/poll.2.html)) +/// +/// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it +/// with the `sigmask` argument. If you want `ppoll` to block indefinitely, +/// specify `None` as `timeout` (it is like `timeout = -1` for `poll`). +/// If `sigmask` is `None`, then no signal mask manipulation is performed, +/// so in that case `ppoll` differs from `poll` only in the precision of the +/// timeout argument. +/// +#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] +pub fn ppoll( + fds: &mut [PollFd], + timeout: Option, + sigmask: Option + ) -> Result +{ + let timeout = timeout.as_ref().map_or(core::ptr::null(), |r| r.as_ref()); + let sigmask = sigmask.as_ref().map_or(core::ptr::null(), |r| r.as_ref()); + let res = unsafe { + libc::ppoll(fds.as_mut_ptr() as *mut libc::pollfd, + fds.len() as libc::nfds_t, + timeout, + sigmask) + }; + Errno::result(res) +} +} diff --git a/utshell-0.5.0/vendor/nix/src/pty.rs b/utshell-0.5.0/vendor/nix/src/pty.rs new file mode 100644 index 00000000..bb266a65 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/pty.rs @@ -0,0 +1,371 @@ +//! Create master and slave virtual pseudo-terminals (PTYs) + +pub use libc::pid_t as SessionId; +pub use libc::winsize as Winsize; + +use std::ffi::CStr; +use std::io; +use std::mem; +use std::os::unix::prelude::*; + +use crate::sys::termios::Termios; +#[cfg(feature = "process")] +use crate::unistd::{ForkResult, Pid}; +use crate::{Result, fcntl, unistd}; +use crate::errno::Errno; + +/// Representation of a master/slave pty pair +/// +/// This is returned by `openpty`. Note that this type does *not* implement `Drop`, so the user +/// must manually close the file descriptors. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct OpenptyResult { + /// The master port in a virtual pty pair + pub master: RawFd, + /// The slave port in a virtual pty pair + pub slave: RawFd, +} + +feature! { +#![feature = "process"] +/// Representation of a master with a forked pty +/// +/// This is returned by `forkpty`. Note that this type does *not* implement `Drop`, so the user +/// must manually close the file descriptors. +#[derive(Clone, Copy, Debug)] +pub struct ForkptyResult { + /// The master port in a virtual pty pair + pub master: RawFd, + /// Metadata about forked process + pub fork_result: ForkResult, +} +} + + +/// Representation of the Master device in a master/slave pty pair +/// +/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY +/// functions are given the correct file descriptor. Additionally this type implements `Drop`, +/// so that when it's consumed or goes out of scope, it's automatically cleaned-up. +#[derive(Debug, Eq, Hash, PartialEq)] +pub struct PtyMaster(RawFd); + +impl AsRawFd for PtyMaster { + fn as_raw_fd(&self) -> RawFd { + self.0 + } +} + +impl IntoRawFd for PtyMaster { + fn into_raw_fd(self) -> RawFd { + let fd = self.0; + mem::forget(self); + fd + } +} + +impl Drop for PtyMaster { + fn drop(&mut self) { + // On drop, we ignore errors like EINTR and EIO because there's no clear + // way to handle them, we can't return anything, and (on FreeBSD at + // least) the file descriptor is deallocated in these cases. However, + // we must panic on EBADF, because it is always an error to close an + // invalid file descriptor. That frequently indicates a double-close + // condition, which can cause confusing errors for future I/O + // operations. + let e = unistd::close(self.0); + if e == Err(Errno::EBADF) { + panic!("Closing an invalid file descriptor!"); + }; + } +} + +impl io::Read for PtyMaster { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + unistd::read(self.0, buf).map_err(io::Error::from) + } +} + +impl io::Write for PtyMaster { + fn write(&mut self, buf: &[u8]) -> io::Result { + unistd::write(self.0, buf).map_err(io::Error::from) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl io::Read for &PtyMaster { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + unistd::read(self.0, buf).map_err(io::Error::from) + } +} + +impl io::Write for &PtyMaster { + fn write(&mut self, buf: &[u8]) -> io::Result { + unistd::write(self.0, buf).map_err(io::Error::from) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +/// Grant access to a slave pseudoterminal (see +/// [`grantpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html)) +/// +/// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the +/// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave. +#[inline] +pub fn grantpt(fd: &PtyMaster) -> Result<()> { + if unsafe { libc::grantpt(fd.as_raw_fd()) } < 0 { + return Err(Errno::last()); + } + + Ok(()) +} + +/// Open a pseudoterminal device (see +/// [`posix_openpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html)) +/// +/// `posix_openpt()` returns a file descriptor to an existing unused pseudoterminal master device. +/// +/// # Examples +/// +/// A common use case with this function is to open both a master and slave PTY pair. This can be +/// done as follows: +/// +/// ``` +/// use std::path::Path; +/// use nix::fcntl::{OFlag, open}; +/// use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt}; +/// use nix::sys::stat::Mode; +/// +/// # #[allow(dead_code)] +/// # fn run() -> nix::Result<()> { +/// // Open a new PTY master +/// let master_fd = posix_openpt(OFlag::O_RDWR)?; +/// +/// // Allow a slave to be generated for it +/// grantpt(&master_fd)?; +/// unlockpt(&master_fd)?; +/// +/// // Get the name of the slave +/// let slave_name = unsafe { ptsname(&master_fd) }?; +/// +/// // Try to open the slave +/// let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?; +/// # Ok(()) +/// # } +/// ``` +#[inline] +pub fn posix_openpt(flags: fcntl::OFlag) -> Result { + let fd = unsafe { + libc::posix_openpt(flags.bits()) + }; + + if fd < 0 { + return Err(Errno::last()); + } + + Ok(PtyMaster(fd)) +} + +/// Get the name of the slave pseudoterminal (see +/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html)) +/// +/// `ptsname()` returns the name of the slave pseudoterminal device corresponding to the master +/// referred to by `fd`. +/// +/// This value is useful for opening the slave pty once the master has already been opened with +/// `posix_openpt()`. +/// +/// # Safety +/// +/// `ptsname()` mutates global variables and is *not* threadsafe. +/// Mutating global variables is always considered `unsafe` by Rust and this +/// function is marked as `unsafe` to reflect that. +/// +/// For a threadsafe and non-`unsafe` alternative on Linux, see `ptsname_r()`. +#[inline] +pub unsafe fn ptsname(fd: &PtyMaster) -> Result { + let name_ptr = libc::ptsname(fd.as_raw_fd()); + if name_ptr.is_null() { + return Err(Errno::last()); + } + + let name = CStr::from_ptr(name_ptr); + Ok(name.to_string_lossy().into_owned()) +} + +/// Get the name of the slave pseudoterminal (see +/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html)) +/// +/// `ptsname_r()` returns the name of the slave pseudoterminal device corresponding to the master +/// referred to by `fd`. This is the threadsafe version of `ptsname()`, but it is not part of the +/// POSIX standard and is instead a Linux-specific extension. +/// +/// This value is useful for opening the slave ptty once the master has already been opened with +/// `posix_openpt()`. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +#[inline] +pub fn ptsname_r(fd: &PtyMaster) -> Result { + let mut name_buf = Vec::::with_capacity(64); + let name_buf_ptr = name_buf.as_mut_ptr(); + let cname = unsafe { + let cap = name_buf.capacity(); + if libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, cap) != 0 { + return Err(crate::Error::last()); + } + CStr::from_ptr(name_buf.as_ptr()) + }; + + let name = cname.to_string_lossy().into_owned(); + Ok(name) +} + +/// Unlock a pseudoterminal master/slave pseudoterminal pair (see +/// [`unlockpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html)) +/// +/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal +/// referred to by `fd`. This must be called before trying to open the slave side of a +/// pseudoterminal. +#[inline] +pub fn unlockpt(fd: &PtyMaster) -> Result<()> { + if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 { + return Err(Errno::last()); + } + + Ok(()) +} + + +/// Create a new pseudoterminal, returning the slave and master file descriptors +/// in `OpenptyResult` +/// (see [`openpty`](https://man7.org/linux/man-pages/man3/openpty.3.html)). +/// +/// If `winsize` is not `None`, the window size of the slave will be set to +/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's +/// terminal settings of the slave will be set to the values in `termios`. +#[inline] +pub fn openpty<'a, 'b, T: Into>, U: Into>>(winsize: T, termios: U) -> Result { + use std::ptr; + + let mut slave = mem::MaybeUninit::::uninit(); + let mut master = mem::MaybeUninit::::uninit(); + let ret = { + match (termios.into(), winsize.into()) { + (Some(termios), Some(winsize)) => { + let inner_termios = termios.get_libc_termios(); + unsafe { + libc::openpty( + master.as_mut_ptr(), + slave.as_mut_ptr(), + ptr::null_mut(), + &*inner_termios as *const libc::termios as *mut _, + winsize as *const Winsize as *mut _, + ) + } + } + (None, Some(winsize)) => { + unsafe { + libc::openpty( + master.as_mut_ptr(), + slave.as_mut_ptr(), + ptr::null_mut(), + ptr::null_mut(), + winsize as *const Winsize as *mut _, + ) + } + } + (Some(termios), None) => { + let inner_termios = termios.get_libc_termios(); + unsafe { + libc::openpty( + master.as_mut_ptr(), + slave.as_mut_ptr(), + ptr::null_mut(), + &*inner_termios as *const libc::termios as *mut _, + ptr::null_mut(), + ) + } + } + (None, None) => { + unsafe { + libc::openpty( + master.as_mut_ptr(), + slave.as_mut_ptr(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ) + } + } + } + }; + + Errno::result(ret)?; + + unsafe { + Ok(OpenptyResult { + master: master.assume_init(), + slave: slave.assume_init(), + }) + } +} + +feature! { +#![feature = "process"] +/// Create a new pseudoterminal, returning the master file descriptor and forked pid. +/// in `ForkptyResult` +/// (see [`forkpty`](https://man7.org/linux/man-pages/man3/forkpty.3.html)). +/// +/// If `winsize` is not `None`, the window size of the slave will be set to +/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's +/// terminal settings of the slave will be set to the values in `termios`. +/// +/// # Safety +/// +/// In a multithreaded program, only [async-signal-safe] functions like `pause` +/// and `_exit` may be called by the child (the parent isn't restricted). Note +/// that memory allocation may **not** be async-signal-safe and thus must be +/// prevented. +/// +/// Those functions are only a small subset of your operating system's API, so +/// special care must be taken to only invoke code you can control and audit. +/// +/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html +pub unsafe fn forkpty<'a, 'b, T: Into>, U: Into>>( + winsize: T, + termios: U, +) -> Result { + use std::ptr; + + let mut master = mem::MaybeUninit::::uninit(); + + let term = match termios.into() { + Some(termios) => { + let inner_termios = termios.get_libc_termios(); + &*inner_termios as *const libc::termios as *mut _ + }, + None => ptr::null_mut(), + }; + + let win = winsize + .into() + .map(|ws| ws as *const Winsize as *mut _) + .unwrap_or(ptr::null_mut()); + + let res = libc::forkpty(master.as_mut_ptr(), ptr::null_mut(), term, win); + + let fork_result = Errno::result(res).map(|res| match res { + 0 => ForkResult::Child, + res => ForkResult::Parent { child: Pid::from_raw(res) }, + })?; + + Ok(ForkptyResult { + master: master.assume_init(), + fork_result, + }) +} +} diff --git a/utshell-0.5.0/vendor/nix/src/sched.rs b/utshell-0.5.0/vendor/nix/src/sched.rs new file mode 100644 index 00000000..e9a326e2 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sched.rs @@ -0,0 +1,294 @@ +//! Execution scheduling +//! +//! See Also +//! [sched.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sched.h.html) +use crate::{Errno, Result}; + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use self::sched_linux_like::*; + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod sched_linux_like { + use crate::errno::Errno; + use libc::{self, c_int, c_void}; + use std::mem; + use std::option::Option; + use std::os::unix::io::RawFd; + use crate::unistd::Pid; + use crate::Result; + + // For some functions taking with a parameter of type CloneFlags, + // only a subset of these flags have an effect. + libc_bitflags! { + /// Options for use with [`clone`] + pub struct CloneFlags: c_int { + /// The calling process and the child process run in the same + /// memory space. + CLONE_VM; + /// The caller and the child process share the same filesystem + /// information. + CLONE_FS; + /// The calling process and the child process share the same file + /// descriptor table. + CLONE_FILES; + /// The calling process and the child process share the same table + /// of signal handlers. + CLONE_SIGHAND; + /// If the calling process is being traced, then trace the child + /// also. + CLONE_PTRACE; + /// The execution of the calling process is suspended until the + /// child releases its virtual memory resources via a call to + /// execve(2) or _exit(2) (as with vfork(2)). + CLONE_VFORK; + /// The parent of the new child (as returned by getppid(2)) + /// will be the same as that of the calling process. + CLONE_PARENT; + /// The child is placed in the same thread group as the calling + /// process. + CLONE_THREAD; + /// The cloned child is started in a new mount namespace. + CLONE_NEWNS; + /// The child and the calling process share a single list of System + /// V semaphore adjustment values + CLONE_SYSVSEM; + // Not supported by Nix due to lack of varargs support in Rust FFI + // CLONE_SETTLS; + // Not supported by Nix due to lack of varargs support in Rust FFI + // CLONE_PARENT_SETTID; + // Not supported by Nix due to lack of varargs support in Rust FFI + // CLONE_CHILD_CLEARTID; + /// Unused since Linux 2.6.2 + #[deprecated(since = "0.23.0", note = "Deprecated by Linux 2.6.2")] + CLONE_DETACHED; + /// A tracing process cannot force `CLONE_PTRACE` on this child + /// process. + CLONE_UNTRACED; + // Not supported by Nix due to lack of varargs support in Rust FFI + // CLONE_CHILD_SETTID; + /// Create the process in a new cgroup namespace. + CLONE_NEWCGROUP; + /// Create the process in a new UTS namespace. + CLONE_NEWUTS; + /// Create the process in a new IPC namespace. + CLONE_NEWIPC; + /// Create the process in a new user namespace. + CLONE_NEWUSER; + /// Create the process in a new PID namespace. + CLONE_NEWPID; + /// Create the process in a new network namespace. + CLONE_NEWNET; + /// The new process shares an I/O context with the calling process. + CLONE_IO; + } + } + + /// Type for the function executed by [`clone`]. + pub type CloneCb<'a> = Box isize + 'a>; + + /// `clone` create a child process + /// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html)) + /// + /// `stack` is a reference to an array which will hold the stack of the new + /// process. Unlike when calling `clone(2)` from C, the provided stack + /// address need not be the highest address of the region. Nix will take + /// care of that requirement. The user only needs to provide a reference to + /// a normally allocated buffer. + pub fn clone( + mut cb: CloneCb, + stack: &mut [u8], + flags: CloneFlags, + signal: Option, + ) -> Result { + extern "C" fn callback(data: *mut CloneCb) -> c_int { + let cb: &mut CloneCb = unsafe { &mut *data }; + (*cb)() as c_int + } + + let res = unsafe { + let combined = flags.bits() | signal.unwrap_or(0); + let ptr = stack.as_mut_ptr().add(stack.len()); + let ptr_aligned = ptr.sub(ptr as usize % 16); + libc::clone( + mem::transmute( + callback as extern "C" fn(*mut Box isize>) -> i32, + ), + ptr_aligned as *mut c_void, + combined, + &mut cb as *mut _ as *mut c_void, + ) + }; + + Errno::result(res).map(Pid::from_raw) + } + + /// disassociate parts of the process execution context + /// + /// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html) + pub fn unshare(flags: CloneFlags) -> Result<()> { + let res = unsafe { libc::unshare(flags.bits()) }; + + Errno::result(res).map(drop) + } + + /// reassociate thread with a namespace + /// + /// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html) + pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> { + let res = unsafe { libc::setns(fd, nstype.bits()) }; + + Errno::result(res).map(drop) + } +} + +#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))] +pub use self::sched_affinity::*; + +#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))] +mod sched_affinity { + use crate::errno::Errno; + use std::mem; + use crate::unistd::Pid; + use crate::Result; + + /// CpuSet represent a bit-mask of CPUs. + /// CpuSets are used by sched_setaffinity and + /// sched_getaffinity for example. + /// + /// This is a wrapper around `libc::cpu_set_t`. + #[repr(C)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct CpuSet { + cpu_set: libc::cpu_set_t, + } + + impl CpuSet { + /// Create a new and empty CpuSet. + pub fn new() -> CpuSet { + CpuSet { + cpu_set: unsafe { mem::zeroed() }, + } + } + + /// Test to see if a CPU is in the CpuSet. + /// `field` is the CPU id to test + pub fn is_set(&self, field: usize) -> Result { + if field >= CpuSet::count() { + Err(Errno::EINVAL) + } else { + Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) }) + } + } + + /// Add a CPU to CpuSet. + /// `field` is the CPU id to add + pub fn set(&mut self, field: usize) -> Result<()> { + if field >= CpuSet::count() { + Err(Errno::EINVAL) + } else { + unsafe { libc::CPU_SET(field, &mut self.cpu_set); } + Ok(()) + } + } + + /// Remove a CPU from CpuSet. + /// `field` is the CPU id to remove + pub fn unset(&mut self, field: usize) -> Result<()> { + if field >= CpuSet::count() { + Err(Errno::EINVAL) + } else { + unsafe { libc::CPU_CLR(field, &mut self.cpu_set);} + Ok(()) + } + } + + /// Return the maximum number of CPU in CpuSet + pub const fn count() -> usize { + 8 * mem::size_of::() + } + } + + impl Default for CpuSet { + fn default() -> Self { + Self::new() + } + } + + /// `sched_setaffinity` set a thread's CPU affinity mask + /// ([`sched_setaffinity(2)`](https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html)) + /// + /// `pid` is the thread ID to update. + /// If pid is zero, then the calling thread is updated. + /// + /// The `cpuset` argument specifies the set of CPUs on which the thread + /// will be eligible to run. + /// + /// # Example + /// + /// Binding the current thread to CPU 0 can be done as follows: + /// + /// ```rust,no_run + /// use nix::sched::{CpuSet, sched_setaffinity}; + /// use nix::unistd::Pid; + /// + /// let mut cpu_set = CpuSet::new(); + /// cpu_set.set(0).unwrap(); + /// sched_setaffinity(Pid::from_raw(0), &cpu_set).unwrap(); + /// ``` + pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> { + let res = unsafe { + libc::sched_setaffinity( + pid.into(), + mem::size_of::() as libc::size_t, + &cpuset.cpu_set, + ) + }; + + Errno::result(res).map(drop) + } + + /// `sched_getaffinity` get a thread's CPU affinity mask + /// ([`sched_getaffinity(2)`](https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)) + /// + /// `pid` is the thread ID to check. + /// If pid is zero, then the calling thread is checked. + /// + /// Returned `cpuset` is the set of CPUs on which the thread + /// is eligible to run. + /// + /// # Example + /// + /// Checking if the current thread can run on CPU 0 can be done as follows: + /// + /// ```rust,no_run + /// use nix::sched::sched_getaffinity; + /// use nix::unistd::Pid; + /// + /// let cpu_set = sched_getaffinity(Pid::from_raw(0)).unwrap(); + /// if cpu_set.is_set(0).unwrap() { + /// println!("Current thread can run on CPU 0"); + /// } + /// ``` + pub fn sched_getaffinity(pid: Pid) -> Result { + let mut cpuset = CpuSet::new(); + let res = unsafe { + libc::sched_getaffinity( + pid.into(), + mem::size_of::() as libc::size_t, + &mut cpuset.cpu_set, + ) + }; + + Errno::result(res).and(Ok(cpuset)) + } +} + +/// Explicitly yield the processor to other threads. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html) +pub fn sched_yield() -> Result<()> { + let res = unsafe { libc::sched_yield() }; + + Errno::result(res).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/aio.rs b/utshell-0.5.0/vendor/nix/src/sys/aio.rs new file mode 100644 index 00000000..6ff88469 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/aio.rs @@ -0,0 +1,1244 @@ +// vim: tw=80 +//! POSIX Asynchronous I/O +//! +//! The POSIX AIO interface is used for asynchronous I/O on files and disk-like +//! devices. It supports [`read`](struct.AioRead.html#method.new), +//! [`write`](struct.AioWrite.html#method.new), +//! [`fsync`](struct.AioFsync.html#method.new), +//! [`readv`](struct.AioReadv.html#method.new), and +//! [`writev`](struct.AioWritev.html#method.new), operations, subject to +//! platform support. Completion +//! notifications can optionally be delivered via +//! [signals](../signal/enum.SigevNotify.html#variant.SigevSignal), via the +//! [`aio_suspend`](fn.aio_suspend.html) function, or via polling. Some +//! platforms support other completion +//! notifications, such as +//! [kevent](../signal/enum.SigevNotify.html#variant.SigevKevent). +//! +//! Multiple operations may be submitted in a batch with +//! [`lio_listio`](fn.lio_listio.html), though the standard does not guarantee +//! that they will be executed atomically. +//! +//! Outstanding operations may be cancelled with +//! [`cancel`](trait.Aio.html#method.cancel) or +//! [`aio_cancel_all`](fn.aio_cancel_all.html), though the operating system may +//! not support this for all filesystems and devices. +#[cfg(target_os = "freebsd")] +use std::io::{IoSlice, IoSliceMut}; +use std::{ + convert::TryFrom, + fmt::{self, Debug}, + marker::{PhantomData, PhantomPinned}, + mem, + os::unix::io::RawFd, + pin::Pin, + ptr, + thread, +}; + +use libc::{c_void, off_t}; +use pin_utils::unsafe_pinned; + +use crate::{ + errno::Errno, + sys::{signal::*, time::TimeSpec}, + Result, +}; + +libc_enum! { + /// Mode for `AioCb::fsync`. Controls whether only data or both data and + /// metadata are synced. + #[repr(i32)] + #[non_exhaustive] + pub enum AioFsyncMode { + /// do it like `fsync` + O_SYNC, + /// on supported operating systems only, do it like `fdatasync` + #[cfg(any(target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + O_DSYNC + } + impl TryFrom +} + +libc_enum! { + /// Mode for [`lio_listio`](fn.lio_listio.html) + #[repr(i32)] + pub enum LioMode { + /// Requests that [`lio_listio`](fn.lio_listio.html) block until all + /// requested operations have been completed + LIO_WAIT, + /// Requests that [`lio_listio`](fn.lio_listio.html) return immediately + LIO_NOWAIT, + } +} + +/// Return values for [`AioCb::cancel`](struct.AioCb.html#method.cancel) and +/// [`aio_cancel_all`](fn.aio_cancel_all.html) +#[repr(i32)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum AioCancelStat { + /// All outstanding requests were canceled + AioCanceled = libc::AIO_CANCELED, + /// Some requests were not canceled. Their status should be checked with + /// `AioCb::error` + AioNotCanceled = libc::AIO_NOTCANCELED, + /// All of the requests have already finished + AioAllDone = libc::AIO_ALLDONE, +} + +/// Newtype that adds Send and Sync to libc::aiocb, which contains raw pointers +#[repr(transparent)] +struct LibcAiocb(libc::aiocb); + +unsafe impl Send for LibcAiocb {} +unsafe impl Sync for LibcAiocb {} + +/// Base class for all AIO operations. Should only be used directly when +/// checking for completion. +// We could create some kind of AsPinnedMut trait, and implement it for all aio +// ops, allowing the crate's users to get pinned references to `AioCb`. That +// could save some code for things like polling methods. But IMHO it would +// provide polymorphism at the wrong level. Instead, the best place for +// polymorphism is at the level of `Futures`. +#[repr(C)] +struct AioCb { + aiocb: LibcAiocb, + /// Could this `AioCb` potentially have any in-kernel state? + // It would be really nice to perform the in-progress check entirely at + // compile time. But I can't figure out how, because: + // * Future::poll takes a `Pin<&mut self>` rather than `self`, and + // * Rust's lack of an equivalent of C++'s Guaranteed Copy Elision means + // that there's no way to write an AioCb constructor that neither boxes + // the object itself, nor moves it during return. + in_progress: bool, +} + +impl AioCb { + pin_utils::unsafe_unpinned!(aiocb: LibcAiocb); + + fn aio_return(mut self: Pin<&mut Self>) -> Result { + self.in_progress = false; + unsafe { + let p: *mut libc::aiocb = &mut self.aiocb.0; + Errno::result(libc::aio_return(p)) + } + .map(|r| r as usize) + } + + fn cancel(mut self: Pin<&mut Self>) -> Result { + let r = unsafe { + libc::aio_cancel(self.aiocb.0.aio_fildes, &mut self.aiocb.0) + }; + match r { + libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled), + libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled), + libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone), + -1 => Err(Errno::last()), + _ => panic!("unknown aio_cancel return value"), + } + } + + fn common_init(fd: RawFd, prio: i32, sigev_notify: SigevNotify) -> Self { + // Use mem::zeroed instead of explicitly zeroing each field, because the + // number and name of reserved fields is OS-dependent. On some OSes, + // some reserved fields are used the kernel for state, and must be + // explicitly zeroed when allocated. + let mut a = unsafe { mem::zeroed::() }; + a.aio_fildes = fd; + a.aio_reqprio = prio; + a.aio_sigevent = SigEvent::new(sigev_notify).sigevent(); + AioCb { + aiocb: LibcAiocb(a), + in_progress: false, + } + } + + fn error(self: Pin<&mut Self>) -> Result<()> { + let r = unsafe { libc::aio_error(&self.aiocb().0) }; + match r { + 0 => Ok(()), + num if num > 0 => Err(Errno::from_i32(num)), + -1 => Err(Errno::last()), + num => panic!("unknown aio_error return value {:?}", num), + } + } + + fn in_progress(&self) -> bool { + self.in_progress + } + + fn set_in_progress(mut self: Pin<&mut Self>) { + self.as_mut().in_progress = true; + } + + /// Update the notification settings for an existing AIO operation that has + /// not yet been submitted. + // Takes a normal reference rather than a pinned one because this method is + // normally called before the object needs to be pinned, that is, before + // it's been submitted to the kernel. + fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) { + assert!( + !self.in_progress, + "Can't change notification settings for an in-progress operation" + ); + self.aiocb.0.aio_sigevent = SigEvent::new(sigev_notify).sigevent(); + } +} + +impl Debug for AioCb { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("AioCb") + .field("aiocb", &self.aiocb.0) + .field("in_progress", &self.in_progress) + .finish() + } +} + +impl Drop for AioCb { + /// If the `AioCb` has no remaining state in the kernel, just drop it. + /// Otherwise, dropping constitutes a resource leak, which is an error + fn drop(&mut self) { + assert!( + thread::panicking() || !self.in_progress, + "Dropped an in-progress AioCb" + ); + } +} + +/// Methods common to all AIO operations +pub trait Aio { + /// The return type of [`Aio::aio_return`]. + type Output; + + /// Retrieve return status of an asynchronous operation. + /// + /// Should only be called once for each operation, after [`Aio::error`] + /// indicates that it has completed. The result is the same as for the + /// synchronous `read(2)`, `write(2)`, of `fsync(2)` functions. + /// + /// # References + /// + /// [aio_return](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_return.html) + fn aio_return(self: Pin<&mut Self>) -> Result; + + /// Cancels an outstanding AIO request. + /// + /// The operating system is not required to implement cancellation for all + /// file and device types. Even if it does, there is no guarantee that the + /// operation has not already completed. So the caller must check the + /// result and handle operations that were not canceled or that have already + /// completed. + /// + /// # Examples + /// + /// Cancel an outstanding aio operation. Note that we must still call + /// `aio_return` to free resources, even though we don't care about the + /// result. + /// + /// ``` + /// # use nix::errno::Errno; + /// # use nix::Error; + /// # use nix::sys::aio::*; + /// # use nix::sys::signal::SigevNotify; + /// # use std::{thread, time}; + /// # use std::io::Write; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; + /// let wbuf = b"CDEF"; + /// let mut f = tempfile().unwrap(); + /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), + /// 2, //offset + /// &wbuf[..], + /// 0, //priority + /// SigevNotify::SigevNone)); + /// aiocb.as_mut().submit().unwrap(); + /// let cs = aiocb.as_mut().cancel().unwrap(); + /// if cs == AioCancelStat::AioNotCanceled { + /// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) { + /// thread::sleep(time::Duration::from_millis(10)); + /// } + /// } + /// // Must call `aio_return`, but ignore the result + /// let _ = aiocb.as_mut().aio_return(); + /// ``` + /// + /// # References + /// + /// [aio_cancel](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html) + fn cancel(self: Pin<&mut Self>) -> Result; + + /// Retrieve error status of an asynchronous operation. + /// + /// If the request has not yet completed, returns `EINPROGRESS`. Otherwise, + /// returns `Ok` or any other error. + /// + /// # Examples + /// + /// Issue an aio operation and use `error` to poll for completion. Polling + /// is an alternative to `aio_suspend`, used by most of the other examples. + /// + /// ``` + /// # use nix::errno::Errno; + /// # use nix::Error; + /// # use nix::sys::aio::*; + /// # use nix::sys::signal::SigevNotify; + /// # use std::{thread, time}; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; + /// const WBUF: &[u8] = b"abcdef123456"; + /// let mut f = tempfile().unwrap(); + /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), + /// 2, //offset + /// WBUF, + /// 0, //priority + /// SigevNotify::SigevNone)); + /// aiocb.as_mut().submit().unwrap(); + /// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) { + /// thread::sleep(time::Duration::from_millis(10)); + /// } + /// assert_eq!(aiocb.as_mut().aio_return().unwrap(), WBUF.len()); + /// ``` + /// + /// # References + /// + /// [aio_error](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_error.html) + fn error(self: Pin<&mut Self>) -> Result<()>; + + /// Returns the underlying file descriptor associated with the operation. + fn fd(&self) -> RawFd; + + /// Does this operation currently have any in-kernel state? + /// + /// Dropping an operation that does have in-kernel state constitutes a + /// resource leak. + /// + /// # Examples + /// + /// ``` + /// # use nix::errno::Errno; + /// # use nix::Error; + /// # use nix::sys::aio::*; + /// # use nix::sys::signal::SigevNotify::SigevNone; + /// # use std::{thread, time}; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; + /// let f = tempfile().unwrap(); + /// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC, + /// 0, SigevNone)); + /// assert!(!aiof.as_mut().in_progress()); + /// aiof.as_mut().submit().expect("aio_fsync failed early"); + /// assert!(aiof.as_mut().in_progress()); + /// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) { + /// thread::sleep(time::Duration::from_millis(10)); + /// } + /// aiof.as_mut().aio_return().expect("aio_fsync failed late"); + /// assert!(!aiof.as_mut().in_progress()); + /// ``` + fn in_progress(&self) -> bool; + + /// Returns the priority of the `AioCb` + fn priority(&self) -> i32; + + /// Update the notification settings for an existing AIO operation that has + /// not yet been submitted. + fn set_sigev_notify(&mut self, sev: SigevNotify); + + /// Returns the `SigEvent` that will be used for notification. + fn sigevent(&self) -> SigEvent; + + /// Actually start the I/O operation. + /// + /// After calling this method and until [`Aio::aio_return`] returns `Ok`, + /// the structure may not be moved in memory. + fn submit(self: Pin<&mut Self>) -> Result<()>; +} + +macro_rules! aio_methods { + () => { + fn cancel(self: Pin<&mut Self>) -> Result { + self.aiocb().cancel() + } + + fn error(self: Pin<&mut Self>) -> Result<()> { + self.aiocb().error() + } + + fn fd(&self) -> RawFd { + self.aiocb.aiocb.0.aio_fildes + } + + fn in_progress(&self) -> bool { + self.aiocb.in_progress() + } + + fn priority(&self) -> i32 { + self.aiocb.aiocb.0.aio_reqprio + } + + fn set_sigev_notify(&mut self, sev: SigevNotify) { + self.aiocb.set_sigev_notify(sev) + } + + fn sigevent(&self) -> SigEvent { + SigEvent::from(&self.aiocb.aiocb.0.aio_sigevent) + } + }; + ($func:ident) => { + aio_methods!(); + + fn aio_return(self: Pin<&mut Self>) -> Result<::Output> { + self.aiocb().aio_return() + } + + fn submit(mut self: Pin<&mut Self>) -> Result<()> { + let p: *mut libc::aiocb = &mut self.as_mut().aiocb().aiocb.0; + Errno::result({ unsafe { libc::$func(p) } }).map(|_| { + self.aiocb().set_in_progress(); + }) + } + }; +} + +/// An asynchronous version of `fsync(2)`. +/// +/// # References +/// +/// [aio_fsync](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_fsync.html) +/// # Examples +/// +/// ``` +/// # use nix::errno::Errno; +/// # use nix::Error; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify::SigevNone; +/// # use std::{thread, time}; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// let f = tempfile().unwrap(); +/// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC, +/// 0, SigevNone)); +/// aiof.as_mut().submit().expect("aio_fsync failed early"); +/// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// aiof.as_mut().aio_return().expect("aio_fsync failed late"); +/// ``` +#[derive(Debug)] +#[repr(transparent)] +pub struct AioFsync { + aiocb: AioCb, + _pin: PhantomPinned, +} + +impl AioFsync { + unsafe_pinned!(aiocb: AioCb); + + /// Returns the operation's fsync mode: data and metadata or data only? + pub fn mode(&self) -> AioFsyncMode { + AioFsyncMode::try_from(self.aiocb.aiocb.0.aio_lio_opcode).unwrap() + } + + /// Create a new `AioFsync`. + /// + /// # Arguments + /// + /// * `fd`: File descriptor to sync. + /// * `mode`: Whether to sync file metadata too, or just data. + /// * `prio`: If POSIX Prioritized IO is supported, then the + /// operation will be prioritized at the process's + /// priority level minus `prio`. + /// * `sigev_notify`: Determines how you will be notified of event + /// completion. + pub fn new( + fd: RawFd, + mode: AioFsyncMode, + prio: i32, + sigev_notify: SigevNotify, + ) -> Self { + let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); + // To save some memory, store mode in an unused field of the AioCb. + // True it isn't very much memory, but downstream creates will likely + // create an enum containing this and other AioCb variants and pack + // those enums into data structures like Vec, so it adds up. + aiocb.aiocb.0.aio_lio_opcode = mode as libc::c_int; + AioFsync { + aiocb, + _pin: PhantomPinned, + } + } +} + +impl Aio for AioFsync { + type Output = (); + + aio_methods!(); + + fn aio_return(self: Pin<&mut Self>) -> Result<()> { + self.aiocb().aio_return().map(drop) + } + + fn submit(mut self: Pin<&mut Self>) -> Result<()> { + let aiocb = &mut self.as_mut().aiocb().aiocb.0; + let mode = mem::replace(&mut aiocb.aio_lio_opcode, 0); + let p: *mut libc::aiocb = aiocb; + Errno::result(unsafe { libc::aio_fsync(mode, p) }).map(|_| { + self.aiocb().set_in_progress(); + }) + } +} + +// AioFsync does not need AsMut, since it can't be used with lio_listio + +impl AsRef for AioFsync { + fn as_ref(&self) -> &libc::aiocb { + &self.aiocb.aiocb.0 + } +} + +/// Asynchronously reads from a file descriptor into a buffer +/// +/// # References +/// +/// [aio_read](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_read.html) +/// +/// # Examples +/// +/// +/// ``` +/// # use nix::errno::Errno; +/// # use nix::Error; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use std::{thread, time}; +/// # use std::io::Write; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// const INITIAL: &[u8] = b"abcdef123456"; +/// const LEN: usize = 4; +/// let mut rbuf = vec![0; LEN]; +/// let mut f = tempfile().unwrap(); +/// f.write_all(INITIAL).unwrap(); +/// { +/// let mut aior = Box::pin( +/// AioRead::new( +/// f.as_raw_fd(), +/// 2, //offset +/// &mut rbuf, +/// 0, //priority +/// SigevNotify::SigevNone +/// ) +/// ); +/// aior.as_mut().submit().unwrap(); +/// while (aior.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// assert_eq!(aior.as_mut().aio_return().unwrap(), LEN); +/// } +/// assert_eq!(rbuf, b"cdef"); +/// ``` +#[derive(Debug)] +#[repr(transparent)] +pub struct AioRead<'a> { + aiocb: AioCb, + _data: PhantomData<&'a [u8]>, + _pin: PhantomPinned, +} + +impl<'a> AioRead<'a> { + unsafe_pinned!(aiocb: AioCb); + + /// Returns the requested length of the aio operation in bytes + /// + /// This method returns the *requested* length of the operation. To get the + /// number of bytes actually read or written by a completed operation, use + /// `aio_return` instead. + pub fn nbytes(&self) -> usize { + self.aiocb.aiocb.0.aio_nbytes + } + + /// Create a new `AioRead`, placing the data in a mutable slice. + /// + /// # Arguments + /// + /// * `fd`: File descriptor to read from + /// * `offs`: File offset + /// * `buf`: A memory buffer. It must outlive the `AioRead`. + /// * `prio`: If POSIX Prioritized IO is supported, then the + /// operation will be prioritized at the process's + /// priority level minus `prio` + /// * `sigev_notify`: Determines how you will be notified of event + /// completion. + pub fn new( + fd: RawFd, + offs: off_t, + buf: &'a mut [u8], + prio: i32, + sigev_notify: SigevNotify, + ) -> Self { + let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); + aiocb.aiocb.0.aio_nbytes = buf.len(); + aiocb.aiocb.0.aio_buf = buf.as_mut_ptr() as *mut c_void; + aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READ; + aiocb.aiocb.0.aio_offset = offs; + AioRead { + aiocb, + _data: PhantomData, + _pin: PhantomPinned, + } + } + + /// Returns the file offset of the operation. + pub fn offset(&self) -> off_t { + self.aiocb.aiocb.0.aio_offset + } +} + +impl<'a> Aio for AioRead<'a> { + type Output = usize; + + aio_methods!(aio_read); +} + +impl<'a> AsMut for AioRead<'a> { + fn as_mut(&mut self) -> &mut libc::aiocb { + &mut self.aiocb.aiocb.0 + } +} + +impl<'a> AsRef for AioRead<'a> { + fn as_ref(&self) -> &libc::aiocb { + &self.aiocb.aiocb.0 + } +} + +/// Asynchronously reads from a file descriptor into a scatter/gather list of buffers. +/// +/// # References +/// +/// [aio_readv](https://www.freebsd.org/cgi/man.cgi?query=aio_readv) +/// +/// # Examples +/// +/// +#[cfg_attr(fbsd14, doc = " ```")] +#[cfg_attr(not(fbsd14), doc = " ```no_run")] +/// # use nix::errno::Errno; +/// # use nix::Error; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use std::{thread, time}; +/// # use std::io::{IoSliceMut, Write}; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// const INITIAL: &[u8] = b"abcdef123456"; +/// let mut rbuf0 = vec![0; 4]; +/// let mut rbuf1 = vec![0; 2]; +/// let expected_len = rbuf0.len() + rbuf1.len(); +/// let mut rbufs = [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)]; +/// let mut f = tempfile().unwrap(); +/// f.write_all(INITIAL).unwrap(); +/// { +/// let mut aior = Box::pin( +/// AioReadv::new( +/// f.as_raw_fd(), +/// 2, //offset +/// &mut rbufs, +/// 0, //priority +/// SigevNotify::SigevNone +/// ) +/// ); +/// aior.as_mut().submit().unwrap(); +/// while (aior.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// assert_eq!(aior.as_mut().aio_return().unwrap(), expected_len); +/// } +/// assert_eq!(rbuf0, b"cdef"); +/// assert_eq!(rbuf1, b"12"); +/// ``` +#[cfg(target_os = "freebsd")] +#[derive(Debug)] +#[repr(transparent)] +pub struct AioReadv<'a> { + aiocb: AioCb, + _data: PhantomData<&'a [&'a [u8]]>, + _pin: PhantomPinned, +} + +#[cfg(target_os = "freebsd")] +impl<'a> AioReadv<'a> { + unsafe_pinned!(aiocb: AioCb); + + /// Returns the number of buffers the operation will read into. + pub fn iovlen(&self) -> usize { + self.aiocb.aiocb.0.aio_nbytes + } + + /// Create a new `AioReadv`, placing the data in a list of mutable slices. + /// + /// # Arguments + /// + /// * `fd`: File descriptor to read from + /// * `offs`: File offset + /// * `bufs`: A scatter/gather list of memory buffers. They must + /// outlive the `AioReadv`. + /// * `prio`: If POSIX Prioritized IO is supported, then the + /// operation will be prioritized at the process's + /// priority level minus `prio` + /// * `sigev_notify`: Determines how you will be notified of event + /// completion. + pub fn new( + fd: RawFd, + offs: off_t, + bufs: &mut [IoSliceMut<'a>], + prio: i32, + sigev_notify: SigevNotify, + ) -> Self { + let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); + // In vectored mode, aio_nbytes stores the length of the iovec array, + // not the byte count. + aiocb.aiocb.0.aio_nbytes = bufs.len(); + aiocb.aiocb.0.aio_buf = bufs.as_mut_ptr() as *mut c_void; + aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READV; + aiocb.aiocb.0.aio_offset = offs; + AioReadv { + aiocb, + _data: PhantomData, + _pin: PhantomPinned, + } + } + + /// Returns the file offset of the operation. + pub fn offset(&self) -> off_t { + self.aiocb.aiocb.0.aio_offset + } +} + +#[cfg(target_os = "freebsd")] +impl<'a> Aio for AioReadv<'a> { + type Output = usize; + + aio_methods!(aio_readv); +} + +#[cfg(target_os = "freebsd")] +impl<'a> AsMut for AioReadv<'a> { + fn as_mut(&mut self) -> &mut libc::aiocb { + &mut self.aiocb.aiocb.0 + } +} + +#[cfg(target_os = "freebsd")] +impl<'a> AsRef for AioReadv<'a> { + fn as_ref(&self) -> &libc::aiocb { + &self.aiocb.aiocb.0 + } +} + +/// Asynchronously writes from a buffer to a file descriptor +/// +/// # References +/// +/// [aio_write](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_write.html) +/// +/// # Examples +/// +/// ``` +/// # use nix::errno::Errno; +/// # use nix::Error; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use std::{thread, time}; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// const WBUF: &[u8] = b"abcdef123456"; +/// let mut f = tempfile().unwrap(); +/// let mut aiow = Box::pin( +/// AioWrite::new( +/// f.as_raw_fd(), +/// 2, //offset +/// WBUF, +/// 0, //priority +/// SigevNotify::SigevNone +/// ) +/// ); +/// aiow.as_mut().submit().unwrap(); +/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); +/// ``` +#[derive(Debug)] +#[repr(transparent)] +pub struct AioWrite<'a> { + aiocb: AioCb, + _data: PhantomData<&'a [u8]>, + _pin: PhantomPinned, +} + +impl<'a> AioWrite<'a> { + unsafe_pinned!(aiocb: AioCb); + + /// Returns the requested length of the aio operation in bytes + /// + /// This method returns the *requested* length of the operation. To get the + /// number of bytes actually read or written by a completed operation, use + /// `aio_return` instead. + pub fn nbytes(&self) -> usize { + self.aiocb.aiocb.0.aio_nbytes + } + + /// Construct a new `AioWrite`. + /// + /// # Arguments + /// + /// * `fd`: File descriptor to write to + /// * `offs`: File offset + /// * `buf`: A memory buffer. It must outlive the `AioWrite`. + /// * `prio`: If POSIX Prioritized IO is supported, then the + /// operation will be prioritized at the process's + /// priority level minus `prio` + /// * `sigev_notify`: Determines how you will be notified of event + /// completion. + pub fn new( + fd: RawFd, + offs: off_t, + buf: &'a [u8], + prio: i32, + sigev_notify: SigevNotify, + ) -> Self { + let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); + aiocb.aiocb.0.aio_nbytes = buf.len(); + // casting an immutable buffer to a mutable pointer looks unsafe, + // but technically its only unsafe to dereference it, not to create + // it. Type Safety guarantees that we'll never pass aiocb to + // aio_read or aio_readv. + aiocb.aiocb.0.aio_buf = buf.as_ptr() as *mut c_void; + aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITE; + aiocb.aiocb.0.aio_offset = offs; + AioWrite { + aiocb, + _data: PhantomData, + _pin: PhantomPinned, + } + } + + /// Returns the file offset of the operation. + pub fn offset(&self) -> off_t { + self.aiocb.aiocb.0.aio_offset + } +} + +impl<'a> Aio for AioWrite<'a> { + type Output = usize; + + aio_methods!(aio_write); +} + +impl<'a> AsMut for AioWrite<'a> { + fn as_mut(&mut self) -> &mut libc::aiocb { + &mut self.aiocb.aiocb.0 + } +} + +impl<'a> AsRef for AioWrite<'a> { + fn as_ref(&self) -> &libc::aiocb { + &self.aiocb.aiocb.0 + } +} + +/// Asynchronously writes from a scatter/gather list of buffers to a file descriptor. +/// +/// # References +/// +/// [aio_writev](https://www.freebsd.org/cgi/man.cgi?query=aio_writev) +/// +/// # Examples +/// +#[cfg_attr(fbsd14, doc = " ```")] +#[cfg_attr(not(fbsd14), doc = " ```no_run")] +/// # use nix::errno::Errno; +/// # use nix::Error; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use std::{thread, time}; +/// # use std::io::IoSlice; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// const wbuf0: &[u8] = b"abcdef"; +/// const wbuf1: &[u8] = b"123456"; +/// let len = wbuf0.len() + wbuf1.len(); +/// let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)]; +/// let mut f = tempfile().unwrap(); +/// let mut aiow = Box::pin( +/// AioWritev::new( +/// f.as_raw_fd(), +/// 2, //offset +/// &wbufs, +/// 0, //priority +/// SigevNotify::SigevNone +/// ) +/// ); +/// aiow.as_mut().submit().unwrap(); +/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// assert_eq!(aiow.as_mut().aio_return().unwrap(), len); +/// ``` +#[cfg(target_os = "freebsd")] +#[derive(Debug)] +#[repr(transparent)] +pub struct AioWritev<'a> { + aiocb: AioCb, + _data: PhantomData<&'a [&'a [u8]]>, + _pin: PhantomPinned, +} + +#[cfg(target_os = "freebsd")] +impl<'a> AioWritev<'a> { + unsafe_pinned!(aiocb: AioCb); + + /// Returns the number of buffers the operation will read into. + pub fn iovlen(&self) -> usize { + self.aiocb.aiocb.0.aio_nbytes + } + + /// Construct a new `AioWritev`. + /// + /// # Arguments + /// + /// * `fd`: File descriptor to write to + /// * `offs`: File offset + /// * `bufs`: A scatter/gather list of memory buffers. They must + /// outlive the `AioWritev`. + /// * `prio`: If POSIX Prioritized IO is supported, then the + /// operation will be prioritized at the process's + /// priority level minus `prio` + /// * `sigev_notify`: Determines how you will be notified of event + /// completion. + pub fn new( + fd: RawFd, + offs: off_t, + bufs: &[IoSlice<'a>], + prio: i32, + sigev_notify: SigevNotify, + ) -> Self { + let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); + // In vectored mode, aio_nbytes stores the length of the iovec array, + // not the byte count. + aiocb.aiocb.0.aio_nbytes = bufs.len(); + // casting an immutable buffer to a mutable pointer looks unsafe, + // but technically its only unsafe to dereference it, not to create + // it. Type Safety guarantees that we'll never pass aiocb to + // aio_read or aio_readv. + aiocb.aiocb.0.aio_buf = bufs.as_ptr() as *mut c_void; + aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITEV; + aiocb.aiocb.0.aio_offset = offs; + AioWritev { + aiocb, + _data: PhantomData, + _pin: PhantomPinned, + } + } + + /// Returns the file offset of the operation. + pub fn offset(&self) -> off_t { + self.aiocb.aiocb.0.aio_offset + } +} + +#[cfg(target_os = "freebsd")] +impl<'a> Aio for AioWritev<'a> { + type Output = usize; + + aio_methods!(aio_writev); +} + +#[cfg(target_os = "freebsd")] +impl<'a> AsMut for AioWritev<'a> { + fn as_mut(&mut self) -> &mut libc::aiocb { + &mut self.aiocb.aiocb.0 + } +} + +#[cfg(target_os = "freebsd")] +impl<'a> AsRef for AioWritev<'a> { + fn as_ref(&self) -> &libc::aiocb { + &self.aiocb.aiocb.0 + } +} + +/// Cancels outstanding AIO requests for a given file descriptor. +/// +/// # Examples +/// +/// Issue an aio operation, then cancel all outstanding operations on that file +/// descriptor. +/// +/// ``` +/// # use nix::errno::Errno; +/// # use nix::Error; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use std::{thread, time}; +/// # use std::io::Write; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// let wbuf = b"CDEF"; +/// let mut f = tempfile().unwrap(); +/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), +/// 2, //offset +/// &wbuf[..], +/// 0, //priority +/// SigevNotify::SigevNone)); +/// aiocb.as_mut().submit().unwrap(); +/// let cs = aio_cancel_all(f.as_raw_fd()).unwrap(); +/// if cs == AioCancelStat::AioNotCanceled { +/// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// } +/// // Must call `aio_return`, but ignore the result +/// let _ = aiocb.as_mut().aio_return(); +/// ``` +/// +/// # References +/// +/// [`aio_cancel`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html) +pub fn aio_cancel_all(fd: RawFd) -> Result { + match unsafe { libc::aio_cancel(fd, ptr::null_mut()) } { + libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled), + libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled), + libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone), + -1 => Err(Errno::last()), + _ => panic!("unknown aio_cancel return value"), + } +} + +/// Suspends the calling process until at least one of the specified operations +/// have completed, a signal is delivered, or the timeout has passed. +/// +/// If `timeout` is `None`, `aio_suspend` will block indefinitely. +/// +/// # Examples +/// +/// Use `aio_suspend` to block until an aio operation completes. +/// +/// ``` +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use std::os::unix::io::AsRawFd; +/// # use tempfile::tempfile; +/// const WBUF: &[u8] = b"abcdef123456"; +/// let mut f = tempfile().unwrap(); +/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), +/// 2, //offset +/// WBUF, +/// 0, //priority +/// SigevNotify::SigevNone)); +/// aiocb.as_mut().submit().unwrap(); +/// aio_suspend(&[&*aiocb], None).expect("aio_suspend failed"); +/// assert_eq!(aiocb.as_mut().aio_return().unwrap() as usize, WBUF.len()); +/// ``` +/// # References +/// +/// [`aio_suspend`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_suspend.html) +pub fn aio_suspend( + list: &[&dyn AsRef], + timeout: Option, +) -> Result<()> { + let p = list as *const [&dyn AsRef] + as *const [*const libc::aiocb] + as *const *const libc::aiocb; + let timep = match timeout { + None => ptr::null::(), + Some(x) => x.as_ref() as *const libc::timespec, + }; + Errno::result(unsafe { libc::aio_suspend(p, list.len() as i32, timep) }) + .map(drop) +} + +/// Submits multiple asynchronous I/O requests with a single system call. +/// +/// They are not guaranteed to complete atomically, and the order in which the +/// requests are carried out is not specified. Reads, and writes may be freely +/// mixed. +/// +/// # Examples +/// +/// Use `lio_listio` to submit an aio operation and wait for its completion. In +/// this case, there is no need to use aio_suspend to wait or `error` to poll. +/// This mode is useful for otherwise-synchronous programs that want to execute +/// a handful of I/O operations in parallel. +/// ``` +/// # use std::os::unix::io::AsRawFd; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use tempfile::tempfile; +/// const WBUF: &[u8] = b"abcdef123456"; +/// let mut f = tempfile().unwrap(); +/// let mut aiow = Box::pin(AioWrite::new( +/// f.as_raw_fd(), +/// 2, // offset +/// WBUF, +/// 0, // priority +/// SigevNotify::SigevNone +/// )); +/// lio_listio(LioMode::LIO_WAIT, &mut[aiow.as_mut()], SigevNotify::SigevNone) +/// .unwrap(); +/// // At this point, we are guaranteed that aiow is complete. +/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); +/// ``` +/// +/// Use `lio_listio` to submit multiple asynchronous operations with a single +/// syscall, but receive notification individually. This is an efficient +/// technique for reducing overall context-switch overhead, especially when +/// combined with kqueue. +/// ``` +/// # use std::os::unix::io::AsRawFd; +/// # use std::thread; +/// # use std::time; +/// # use nix::errno::Errno; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::SigevNotify; +/// # use tempfile::tempfile; +/// const WBUF: &[u8] = b"abcdef123456"; +/// let mut f = tempfile().unwrap(); +/// let mut aiow = Box::pin(AioWrite::new( +/// f.as_raw_fd(), +/// 2, // offset +/// WBUF, +/// 0, // priority +/// SigevNotify::SigevNone +/// )); +/// lio_listio(LioMode::LIO_NOWAIT, &mut[aiow.as_mut()], SigevNotify::SigevNone) +/// .unwrap(); +/// // We must wait for the completion of each individual operation +/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); +/// ``` +/// +/// Use `lio_listio` to submit multiple operations, and receive notification +/// only when all of them are complete. This can be useful when there is some +/// logical relationship between the operations. But beware! Errors or system +/// resource limitations may cause `lio_listio` to return `EIO`, `EAGAIN`, or +/// `EINTR`, in which case some but not all operations may have been submitted. +/// In that case, you must check the status of each individual operation, and +/// possibly resubmit some. +/// ``` +/// # use libc::c_int; +/// # use std::os::unix::io::AsRawFd; +/// # use std::sync::atomic::{AtomicBool, Ordering}; +/// # use std::thread; +/// # use std::time; +/// # use lazy_static::lazy_static; +/// # use nix::errno::Errno; +/// # use nix::sys::aio::*; +/// # use nix::sys::signal::*; +/// # use tempfile::tempfile; +/// lazy_static! { +/// pub static ref SIGNALED: AtomicBool = AtomicBool::new(false); +/// } +/// +/// extern fn sigfunc(_: c_int) { +/// SIGNALED.store(true, Ordering::Relaxed); +/// } +/// let sa = SigAction::new(SigHandler::Handler(sigfunc), +/// SaFlags::SA_RESETHAND, +/// SigSet::empty()); +/// SIGNALED.store(false, Ordering::Relaxed); +/// unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); +/// +/// const WBUF: &[u8] = b"abcdef123456"; +/// let mut f = tempfile().unwrap(); +/// let mut aiow = Box::pin(AioWrite::new( +/// f.as_raw_fd(), +/// 2, // offset +/// WBUF, +/// 0, // priority +/// SigevNotify::SigevNone +/// )); +/// let sev = SigevNotify::SigevSignal { signal: Signal::SIGUSR2, si_value: 0 }; +/// lio_listio(LioMode::LIO_NOWAIT, &mut[aiow.as_mut()], sev).unwrap(); +/// while !SIGNALED.load(Ordering::Relaxed) { +/// thread::sleep(time::Duration::from_millis(10)); +/// } +/// // At this point, since `lio_listio` returned success and delivered its +/// // notification, we know that all operations are complete. +/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); +/// ``` +pub fn lio_listio( + mode: LioMode, + list: &mut [Pin<&mut dyn AsMut>], + sigev_notify: SigevNotify, +) -> Result<()> { + let p = list as *mut [Pin<&mut dyn AsMut>] + as *mut [*mut libc::aiocb] + as *mut *mut libc::aiocb; + let sigev = SigEvent::new(sigev_notify); + let sigevp = &mut sigev.sigevent() as *mut libc::sigevent; + Errno::result(unsafe { + libc::lio_listio(mode as i32, p, list.len() as i32, sigevp) + }) + .map(drop) +} + +#[cfg(test)] +mod t { + use super::*; + + /// aio_suspend relies on casting Rust Aio* struct pointers to libc::aiocb + /// pointers. This test ensures that such casts are valid. + #[test] + fn casting() { + let sev = SigevNotify::SigevNone; + let aiof = AioFsync::new(666, AioFsyncMode::O_SYNC, 0, sev); + assert_eq!( + aiof.as_ref() as *const libc::aiocb, + &aiof as *const AioFsync as *const libc::aiocb + ); + + let mut rbuf = []; + let aior = AioRead::new(666, 0, &mut rbuf, 0, sev); + assert_eq!( + aior.as_ref() as *const libc::aiocb, + &aior as *const AioRead as *const libc::aiocb + ); + + let wbuf = []; + let aiow = AioWrite::new(666, 0, &wbuf, 0, sev); + assert_eq!( + aiow.as_ref() as *const libc::aiocb, + &aiow as *const AioWrite as *const libc::aiocb + ); + } + + #[cfg(target_os = "freebsd")] + #[test] + fn casting_vectored() { + let sev = SigevNotify::SigevNone; + + let mut rbuf = []; + let mut rbufs = [IoSliceMut::new(&mut rbuf)]; + let aiorv = AioReadv::new(666, 0, &mut rbufs[..], 0, sev); + assert_eq!( + aiorv.as_ref() as *const libc::aiocb, + &aiorv as *const AioReadv as *const libc::aiocb + ); + + let wbuf = []; + let wbufs = [IoSlice::new(&wbuf)]; + let aiowv = AioWritev::new(666, 0, &wbufs, 0, sev); + assert_eq!( + aiowv.as_ref() as *const libc::aiocb, + &aiowv as *const AioWritev as *const libc::aiocb + ); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/epoll.rs b/utshell-0.5.0/vendor/nix/src/sys/epoll.rs new file mode 100644 index 00000000..8141ff5c --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/epoll.rs @@ -0,0 +1,108 @@ +use crate::Result; +use crate::errno::Errno; +use libc::{self, c_int}; +use std::os::unix::io::RawFd; +use std::ptr; +use std::mem; + +libc_bitflags!( + pub struct EpollFlags: c_int { + EPOLLIN; + EPOLLPRI; + EPOLLOUT; + EPOLLRDNORM; + EPOLLRDBAND; + EPOLLWRNORM; + EPOLLWRBAND; + EPOLLMSG; + EPOLLERR; + EPOLLHUP; + EPOLLRDHUP; + EPOLLEXCLUSIVE; + #[cfg(not(target_arch = "mips"))] + EPOLLWAKEUP; + EPOLLONESHOT; + EPOLLET; + } +); + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(i32)] +#[non_exhaustive] +pub enum EpollOp { + EpollCtlAdd = libc::EPOLL_CTL_ADD, + EpollCtlDel = libc::EPOLL_CTL_DEL, + EpollCtlMod = libc::EPOLL_CTL_MOD, +} + +libc_bitflags!{ + pub struct EpollCreateFlags: c_int { + EPOLL_CLOEXEC; + } +} + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct EpollEvent { + event: libc::epoll_event, +} + +impl EpollEvent { + pub fn new(events: EpollFlags, data: u64) -> Self { + EpollEvent { event: libc::epoll_event { events: events.bits() as u32, u64: data } } + } + + pub fn empty() -> Self { + unsafe { mem::zeroed::() } + } + + pub fn events(&self) -> EpollFlags { + EpollFlags::from_bits(self.event.events as c_int).unwrap() + } + + pub fn data(&self) -> u64 { + self.event.u64 + } +} + +#[inline] +pub fn epoll_create() -> Result { + let res = unsafe { libc::epoll_create(1024) }; + + Errno::result(res) +} + +#[inline] +pub fn epoll_create1(flags: EpollCreateFlags) -> Result { + let res = unsafe { libc::epoll_create1(flags.bits()) }; + + Errno::result(res) +} + +#[inline] +pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()> + where T: Into> +{ + let mut event: Option<&mut EpollEvent> = event.into(); + if event.is_none() && op != EpollOp::EpollCtlDel { + Err(Errno::EINVAL) + } else { + let res = unsafe { + if let Some(ref mut event) = event { + libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) + } else { + libc::epoll_ctl(epfd, op as c_int, fd, ptr::null_mut()) + } + }; + Errno::result(res).map(drop) + } +} + +#[inline] +pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result { + let res = unsafe { + libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int) + }; + + Errno::result(res).map(|r| r as usize) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/event.rs b/utshell-0.5.0/vendor/nix/src/sys/event.rs new file mode 100644 index 00000000..0d0d23a4 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/event.rs @@ -0,0 +1,346 @@ +/* TOOD: Implement for other kqueue based systems + */ + +use crate::{Errno, Result}; +#[cfg(not(target_os = "netbsd"))] +use libc::{timespec, time_t, c_int, c_long, intptr_t, uintptr_t}; +#[cfg(target_os = "netbsd")] +use libc::{timespec, time_t, c_long, intptr_t, uintptr_t, size_t}; +use std::convert::TryInto; +use std::mem; +use std::os::unix::io::RawFd; +use std::ptr; + +// Redefine kevent in terms of programmer-friendly enums and bitfields. +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct KEvent { + kevent: libc::kevent, +} + +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "openbsd"))] +type type_of_udata = *mut libc::c_void; +#[cfg(any(target_os = "netbsd"))] +type type_of_udata = intptr_t; + +#[cfg(target_os = "netbsd")] +type type_of_event_filter = u32; +#[cfg(not(target_os = "netbsd"))] +type type_of_event_filter = i16; +libc_enum! { + #[cfg_attr(target_os = "netbsd", repr(u32))] + #[cfg_attr(not(target_os = "netbsd"), repr(i16))] + #[non_exhaustive] + pub enum EventFilter { + EVFILT_AIO, + /// Returns whenever there is no remaining data in the write buffer + #[cfg(target_os = "freebsd")] + EVFILT_EMPTY, + #[cfg(target_os = "dragonfly")] + EVFILT_EXCEPT, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos"))] + EVFILT_FS, + #[cfg(target_os = "freebsd")] + EVFILT_LIO, + #[cfg(any(target_os = "ios", target_os = "macos"))] + EVFILT_MACHPORT, + EVFILT_PROC, + /// Returns events associated with the process referenced by a given + /// process descriptor, created by `pdfork()`. The events to monitor are: + /// + /// - NOTE_EXIT: the process has exited. The exit status will be stored in data. + #[cfg(target_os = "freebsd")] + EVFILT_PROCDESC, + EVFILT_READ, + /// Returns whenever an asynchronous `sendfile()` call completes. + #[cfg(target_os = "freebsd")] + EVFILT_SENDFILE, + EVFILT_SIGNAL, + EVFILT_TIMER, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos"))] + EVFILT_USER, + #[cfg(any(target_os = "ios", target_os = "macos"))] + EVFILT_VM, + EVFILT_VNODE, + EVFILT_WRITE, + } + impl TryFrom +} + +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "openbsd"))] +pub type type_of_event_flag = u16; +#[cfg(any(target_os = "netbsd"))] +pub type type_of_event_flag = u32; +libc_bitflags!{ + pub struct EventFlag: type_of_event_flag { + EV_ADD; + EV_CLEAR; + EV_DELETE; + EV_DISABLE; + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + EV_DISPATCH; + #[cfg(target_os = "freebsd")] + EV_DROP; + EV_ENABLE; + EV_EOF; + EV_ERROR; + #[cfg(any(target_os = "macos", target_os = "ios"))] + EV_FLAG0; + EV_FLAG1; + #[cfg(target_os = "dragonfly")] + EV_NODATA; + EV_ONESHOT; + #[cfg(any(target_os = "macos", target_os = "ios"))] + EV_OOBAND; + #[cfg(any(target_os = "macos", target_os = "ios"))] + EV_POLL; + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + EV_RECEIPT; + } +} + +libc_bitflags!( + pub struct FilterFlag: u32 { + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_ABSOLUTE; + NOTE_ATTRIB; + NOTE_CHILD; + NOTE_DELETE; + #[cfg(target_os = "openbsd")] + NOTE_EOF; + NOTE_EXEC; + NOTE_EXIT; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_EXITSTATUS; + NOTE_EXTEND; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_FFAND; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_FFCOPY; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_FFCTRLMASK; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_FFLAGSMASK; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_FFNOP; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_FFOR; + NOTE_FORK; + NOTE_LINK; + NOTE_LOWAT; + #[cfg(target_os = "freebsd")] + NOTE_MSECONDS; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_NONE; + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))] + NOTE_NSECONDS; + #[cfg(target_os = "dragonfly")] + NOTE_OOB; + NOTE_PCTRLMASK; + NOTE_PDATAMASK; + NOTE_RENAME; + NOTE_REVOKE; + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))] + NOTE_SECONDS; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_SIGNAL; + NOTE_TRACK; + NOTE_TRACKERR; + #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly"))] + NOTE_TRIGGER; + #[cfg(target_os = "openbsd")] + NOTE_TRUNCATE; + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))] + NOTE_USECONDS; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_VM_ERROR; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_VM_PRESSURE; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_VM_PRESSURE_SUDDEN_TERMINATE; + #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_VM_PRESSURE_TERMINATE; + NOTE_WRITE; + } +); + +pub fn kqueue() -> Result { + let res = unsafe { libc::kqueue() }; + + Errno::result(res) +} + + +// KEvent can't derive Send because on some operating systems, udata is defined +// as a void*. However, KEvent's public API always treats udata as an intptr_t, +// which is safe to Send. +unsafe impl Send for KEvent { +} + +impl KEvent { + #[allow(clippy::needless_update)] // Not needless on all platforms. + pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag, + fflags:FilterFlag, data: intptr_t, udata: intptr_t) -> KEvent { + KEvent { kevent: libc::kevent { + ident, + filter: filter as type_of_event_filter, + flags: flags.bits(), + fflags: fflags.bits(), + // data can be either i64 or intptr_t, depending on platform + data: data as _, + udata: udata as type_of_udata, + .. unsafe { mem::zeroed() } + } } + } + + pub fn ident(&self) -> uintptr_t { + self.kevent.ident + } + + pub fn filter(&self) -> Result { + self.kevent.filter.try_into() + } + + pub fn flags(&self) -> EventFlag { + EventFlag::from_bits(self.kevent.flags).unwrap() + } + + pub fn fflags(&self) -> FilterFlag { + FilterFlag::from_bits(self.kevent.fflags).unwrap() + } + + pub fn data(&self) -> intptr_t { + self.kevent.data as intptr_t + } + + pub fn udata(&self) -> intptr_t { + self.kevent.udata as intptr_t + } +} + +pub fn kevent(kq: RawFd, + changelist: &[KEvent], + eventlist: &mut [KEvent], + timeout_ms: usize) -> Result { + + // Convert ms to timespec + let timeout = timespec { + tv_sec: (timeout_ms / 1000) as time_t, + tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long + }; + + kevent_ts(kq, changelist, eventlist, Some(timeout)) +} + +#[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd"))] +type type_of_nchanges = c_int; +#[cfg(target_os = "netbsd")] +type type_of_nchanges = size_t; + +pub fn kevent_ts(kq: RawFd, + changelist: &[KEvent], + eventlist: &mut [KEvent], + timeout_opt: Option) -> Result { + + let res = unsafe { + libc::kevent( + kq, + changelist.as_ptr() as *const libc::kevent, + changelist.len() as type_of_nchanges, + eventlist.as_mut_ptr() as *mut libc::kevent, + eventlist.len() as type_of_nchanges, + if let Some(ref timeout) = timeout_opt {timeout as *const timespec} else {ptr::null()}) + }; + + Errno::result(res).map(|r| r as usize) +} + +#[inline] +pub fn ev_set(ev: &mut KEvent, + ident: usize, + filter: EventFilter, + flags: EventFlag, + fflags: FilterFlag, + udata: intptr_t) { + + ev.kevent.ident = ident as uintptr_t; + ev.kevent.filter = filter as type_of_event_filter; + ev.kevent.flags = flags.bits(); + ev.kevent.fflags = fflags.bits(); + ev.kevent.data = 0; + ev.kevent.udata = udata as type_of_udata; +} + +#[test] +fn test_struct_kevent() { + use std::mem; + + let udata : intptr_t = 12345; + + let actual = KEvent::new(0xdead_beef, + EventFilter::EVFILT_READ, + EventFlag::EV_ONESHOT | EventFlag::EV_ADD, + FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT, + 0x1337, + udata); + assert_eq!(0xdead_beef, actual.ident()); + let filter = actual.kevent.filter; + assert_eq!(libc::EVFILT_READ, filter); + assert_eq!(libc::EV_ONESHOT | libc::EV_ADD, actual.flags().bits()); + assert_eq!(libc::NOTE_CHILD | libc::NOTE_EXIT, actual.fflags().bits()); + assert_eq!(0x1337, actual.data()); + assert_eq!(udata as type_of_udata, actual.udata() as type_of_udata); + assert_eq!(mem::size_of::(), mem::size_of::()); +} + +#[test] +fn test_kevent_filter() { + let udata : intptr_t = 12345; + + let actual = KEvent::new(0xdead_beef, + EventFilter::EVFILT_READ, + EventFlag::EV_ONESHOT | EventFlag::EV_ADD, + FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT, + 0x1337, + udata); + assert_eq!(EventFilter::EVFILT_READ, actual.filter().unwrap()); +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/eventfd.rs b/utshell-0.5.0/vendor/nix/src/sys/eventfd.rs new file mode 100644 index 00000000..c54f952f --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/eventfd.rs @@ -0,0 +1,17 @@ +use std::os::unix::io::RawFd; +use crate::Result; +use crate::errno::Errno; + +libc_bitflags! { + pub struct EfdFlags: libc::c_int { + EFD_CLOEXEC; // Since Linux 2.6.27 + EFD_NONBLOCK; // Since Linux 2.6.27 + EFD_SEMAPHORE; // Since Linux 2.6.30 + } +} + +pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result { + let res = unsafe { libc::eventfd(initval, flags.bits()) }; + + Errno::result(res).map(|r| r as RawFd) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/inotify.rs b/utshell-0.5.0/vendor/nix/src/sys/inotify.rs new file mode 100644 index 00000000..b19dbe12 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/inotify.rs @@ -0,0 +1,257 @@ +//! Monitoring API for filesystem events. +//! +//! Inotify is a Linux-only API to monitor filesystems events. +//! +//! For more documentation, please read [inotify(7)](https://man7.org/linux/man-pages/man7/inotify.7.html). +//! +//! # Examples +//! +//! Monitor all events happening in directory "test": +//! ```no_run +//! # use nix::sys::inotify::{AddWatchFlags,InitFlags,Inotify}; +//! # +//! // We create a new inotify instance. +//! let instance = Inotify::init(InitFlags::empty()).unwrap(); +//! +//! // We add a new watch on directory "test" for all events. +//! let wd = instance.add_watch("test", AddWatchFlags::IN_ALL_EVENTS).unwrap(); +//! +//! loop { +//! // We read from our inotify instance for events. +//! let events = instance.read_events().unwrap(); +//! println!("Events: {:?}", events); +//! } +//! ``` + +use libc::{ + c_char, + c_int, +}; +use std::ffi::{OsString,OsStr,CStr}; +use std::os::unix::ffi::OsStrExt; +use std::mem::{MaybeUninit, size_of}; +use std::os::unix::io::{RawFd,AsRawFd,FromRawFd}; +use std::ptr; +use crate::unistd::read; +use crate::Result; +use crate::NixPath; +use crate::errno::Errno; +use cfg_if::cfg_if; + +libc_bitflags! { + /// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html). + pub struct AddWatchFlags: u32 { + /// File was accessed. + IN_ACCESS; + /// File was modified. + IN_MODIFY; + /// Metadata changed. + IN_ATTRIB; + /// Writable file was closed. + IN_CLOSE_WRITE; + /// Nonwritable file was closed. + IN_CLOSE_NOWRITE; + /// File was opened. + IN_OPEN; + /// File was moved from X. + IN_MOVED_FROM; + /// File was moved to Y. + IN_MOVED_TO; + /// Subfile was created. + IN_CREATE; + /// Subfile was deleted. + IN_DELETE; + /// Self was deleted. + IN_DELETE_SELF; + /// Self was moved. + IN_MOVE_SELF; + + /// Backing filesystem was unmounted. + IN_UNMOUNT; + /// Event queue overflowed. + IN_Q_OVERFLOW; + /// File was ignored. + IN_IGNORED; + + /// Combination of `IN_CLOSE_WRITE` and `IN_CLOSE_NOWRITE`. + IN_CLOSE; + /// Combination of `IN_MOVED_FROM` and `IN_MOVED_TO`. + IN_MOVE; + + /// Only watch the path if it is a directory. + IN_ONLYDIR; + /// Don't follow symlinks. + IN_DONT_FOLLOW; + + /// Event occurred against directory. + IN_ISDIR; + /// Only send event once. + IN_ONESHOT; + /// All of the events. + IN_ALL_EVENTS; + } +} + +libc_bitflags! { + /// Configuration options for [`inotify_init1`](fn.inotify_init1.html). + pub struct InitFlags: c_int { + /// Set the `FD_CLOEXEC` flag on the file descriptor. + IN_CLOEXEC; + /// Set the `O_NONBLOCK` flag on the open file description referred to by the new file descriptor. + IN_NONBLOCK; + } +} + +/// An inotify instance. This is also a file descriptor, you can feed it to +/// other interfaces consuming file descriptors, epoll for example. +#[derive(Debug, Clone, Copy)] +pub struct Inotify { + fd: RawFd +} + +/// This object is returned when you create a new watch on an inotify instance. +/// It is then returned as part of an event once triggered. It allows you to +/// know which watch triggered which event. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)] +pub struct WatchDescriptor { + wd: i32 +} + +/// A single inotify event. +/// +/// For more documentation see, [inotify(7)](https://man7.org/linux/man-pages/man7/inotify.7.html). +#[derive(Debug)] +pub struct InotifyEvent { + /// Watch descriptor. This field corresponds to the watch descriptor you + /// were issued when calling add_watch. It allows you to know which watch + /// this event comes from. + pub wd: WatchDescriptor, + /// Event mask. This field is a bitfield describing the exact event that + /// occured. + pub mask: AddWatchFlags, + /// This cookie is a number that allows you to connect related events. For + /// now only IN_MOVED_FROM and IN_MOVED_TO can be connected. + pub cookie: u32, + /// Filename. This field exists only if the event was triggered for a file + /// inside the watched directory. + pub name: Option +} + +impl Inotify { + /// Initialize a new inotify instance. + /// + /// Returns a Result containing an inotify instance. + /// + /// For more information see, [inotify_init(2)](https://man7.org/linux/man-pages/man2/inotify_init.2.html). + pub fn init(flags: InitFlags) -> Result { + let res = Errno::result(unsafe { + libc::inotify_init1(flags.bits()) + }); + + res.map(|fd| Inotify { fd }) + } + + /// Adds a new watch on the target file or directory. + /// + /// Returns a watch descriptor. This is not a File Descriptor! + /// + /// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html). + pub fn add_watch(self, + path: &P, + mask: AddWatchFlags) + -> Result + { + let res = path.with_nix_path(|cstr| { + unsafe { + libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits()) + } + })?; + + Errno::result(res).map(|wd| WatchDescriptor { wd }) + } + + /// Removes an existing watch using the watch descriptor returned by + /// inotify_add_watch. + /// + /// Returns an EINVAL error if the watch descriptor is invalid. + /// + /// For more information see, [inotify_rm_watch(2)](https://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html). + pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> { + cfg_if! { + if #[cfg(target_os = "linux")] { + let arg = wd.wd; + } else if #[cfg(target_os = "android")] { + let arg = wd.wd as u32; + } + } + let res = unsafe { libc::inotify_rm_watch(self.fd, arg) }; + + Errno::result(res).map(drop) + } + + /// Reads a collection of events from the inotify file descriptor. This call + /// can either be blocking or non blocking depending on whether IN_NONBLOCK + /// was set at initialization. + /// + /// Returns as many events as available. If the call was non blocking and no + /// events could be read then the EAGAIN error is returned. + pub fn read_events(self) -> Result> { + let header_size = size_of::(); + const BUFSIZ: usize = 4096; + let mut buffer = [0u8; BUFSIZ]; + let mut events = Vec::new(); + let mut offset = 0; + + let nread = read(self.fd, &mut buffer)?; + + while (nread - offset) >= header_size { + let event = unsafe { + let mut event = MaybeUninit::::uninit(); + ptr::copy_nonoverlapping( + buffer.as_ptr().add(offset), + event.as_mut_ptr() as *mut u8, + (BUFSIZ - offset).min(header_size) + ); + event.assume_init() + }; + + let name = match event.len { + 0 => None, + _ => { + let ptr = unsafe { + buffer + .as_ptr() + .add(offset + header_size) + as *const c_char + }; + let cstr = unsafe { CStr::from_ptr(ptr) }; + + Some(OsStr::from_bytes(cstr.to_bytes()).to_owned()) + } + }; + + events.push(InotifyEvent { + wd: WatchDescriptor { wd: event.wd }, + mask: AddWatchFlags::from_bits_truncate(event.mask), + cookie: event.cookie, + name + }); + + offset += header_size + event.len as usize; + } + + Ok(events) + } +} + +impl AsRawFd for Inotify { + fn as_raw_fd(&self) -> RawFd { + self.fd + } +} + +impl FromRawFd for Inotify { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + Inotify { fd } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/ioctl/bsd.rs b/utshell-0.5.0/vendor/nix/src/sys/ioctl/bsd.rs new file mode 100644 index 00000000..307994cb --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/ioctl/bsd.rs @@ -0,0 +1,129 @@ +/// The datatype used for the ioctl number +#[doc(hidden)] +#[cfg(not(target_os = "illumos"))] +pub type ioctl_num_type = ::libc::c_ulong; + +#[doc(hidden)] +#[cfg(target_os = "illumos")] +pub type ioctl_num_type = ::libc::c_int; + +/// The datatype used for the 3rd argument +#[doc(hidden)] +pub type ioctl_param_type = ::libc::c_int; + +mod consts { + use crate::sys::ioctl::ioctl_num_type; + #[doc(hidden)] + pub const VOID: ioctl_num_type = 0x2000_0000; + #[doc(hidden)] + pub const OUT: ioctl_num_type = 0x4000_0000; + #[doc(hidden)] + #[allow(overflowing_literals)] + pub const IN: ioctl_num_type = 0x8000_0000; + #[doc(hidden)] + pub const INOUT: ioctl_num_type = IN | OUT; + #[doc(hidden)] + pub const IOCPARM_MASK: ioctl_num_type = 0x1fff; +} + +pub use self::consts::*; + +#[macro_export] +#[doc(hidden)] +macro_rules! ioc { + ($inout:expr, $group:expr, $num:expr, $len:expr) => { + $inout + | (($len as $crate::sys::ioctl::ioctl_num_type + & $crate::sys::ioctl::IOCPARM_MASK) + << 16) + | (($group as $crate::sys::ioctl::ioctl_num_type) << 8) + | ($num as $crate::sys::ioctl::ioctl_num_type) + }; +} + +/// Generate an ioctl request code for a command that passes no data. +/// +/// This is equivalent to the `_IO()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_none!()` directly. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// const KVMIO: u8 = 0xAE; +/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! request_code_none { + ($g:expr, $n:expr) => { + ioc!($crate::sys::ioctl::VOID, $g, $n, 0) + }; +} + +/// Generate an ioctl request code for a command that passes an integer +/// +/// This is equivalent to the `_IOWINT()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_write_int!()` directly. +#[macro_export(local_inner_macros)] +macro_rules! request_code_write_int { + ($g:expr, $n:expr) => { + ioc!( + $crate::sys::ioctl::VOID, + $g, + $n, + ::std::mem::size_of::<$crate::libc::c_int>() + ) + }; +} + +/// Generate an ioctl request code for a command that reads. +/// +/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_read!()` directly. +/// +/// The read/write direction is relative to userland, so this +/// command would be userland is reading and the kernel is +/// writing. +#[macro_export(local_inner_macros)] +macro_rules! request_code_read { + ($g:expr, $n:expr, $len:expr) => { + ioc!($crate::sys::ioctl::OUT, $g, $n, $len) + }; +} + +/// Generate an ioctl request code for a command that writes. +/// +/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_write!()` directly. +/// +/// The read/write direction is relative to userland, so this +/// command would be userland is writing and the kernel is +/// reading. +#[macro_export(local_inner_macros)] +macro_rules! request_code_write { + ($g:expr, $n:expr, $len:expr) => { + ioc!($crate::sys::ioctl::IN, $g, $n, $len) + }; +} + +/// Generate an ioctl request code for a command that reads and writes. +/// +/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_readwrite!()` directly. +#[macro_export(local_inner_macros)] +macro_rules! request_code_readwrite { + ($g:expr, $n:expr, $len:expr) => { + ioc!($crate::sys::ioctl::INOUT, $g, $n, $len) + }; +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/ioctl/linux.rs b/utshell-0.5.0/vendor/nix/src/sys/ioctl/linux.rs new file mode 100644 index 00000000..0c0a2090 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/ioctl/linux.rs @@ -0,0 +1,172 @@ +/// The datatype used for the ioctl number +#[cfg(any(target_os = "android", target_env = "musl"))] +#[doc(hidden)] +pub type ioctl_num_type = ::libc::c_int; +#[cfg(not(any(target_os = "android", target_env = "musl")))] +#[doc(hidden)] +pub type ioctl_num_type = ::libc::c_ulong; +/// The datatype used for the 3rd argument +#[doc(hidden)] +pub type ioctl_param_type = ::libc::c_ulong; + +#[doc(hidden)] +pub const NRBITS: ioctl_num_type = 8; +#[doc(hidden)] +pub const TYPEBITS: ioctl_num_type = 8; + +#[cfg(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "sparc64" +))] +mod consts { + #[doc(hidden)] + pub const NONE: u8 = 1; + #[doc(hidden)] + pub const READ: u8 = 2; + #[doc(hidden)] + pub const WRITE: u8 = 4; + #[doc(hidden)] + pub const SIZEBITS: u8 = 13; + #[doc(hidden)] + pub const DIRBITS: u8 = 3; +} + +// "Generic" ioctl protocol +#[cfg(any( + target_arch = "x86", + target_arch = "arm", + target_arch = "s390x", + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv32", + target_arch = "riscv64" +))] +mod consts { + #[doc(hidden)] + pub const NONE: u8 = 0; + #[doc(hidden)] + pub const READ: u8 = 2; + #[doc(hidden)] + pub const WRITE: u8 = 1; + #[doc(hidden)] + pub const SIZEBITS: u8 = 14; + #[doc(hidden)] + pub const DIRBITS: u8 = 2; +} + +pub use self::consts::*; + +#[doc(hidden)] +pub const NRSHIFT: ioctl_num_type = 0; +#[doc(hidden)] +pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type; +#[doc(hidden)] +pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type; +#[doc(hidden)] +pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type; + +#[doc(hidden)] +pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1; +#[doc(hidden)] +pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1; +#[doc(hidden)] +pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1; +#[doc(hidden)] +pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1; + +/// Encode an ioctl command. +#[macro_export] +#[doc(hidden)] +macro_rules! ioc { + ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => { + (($dir as $crate::sys::ioctl::ioctl_num_type + & $crate::sys::ioctl::DIRMASK) + << $crate::sys::ioctl::DIRSHIFT) + | (($ty as $crate::sys::ioctl::ioctl_num_type + & $crate::sys::ioctl::TYPEMASK) + << $crate::sys::ioctl::TYPESHIFT) + | (($nr as $crate::sys::ioctl::ioctl_num_type + & $crate::sys::ioctl::NRMASK) + << $crate::sys::ioctl::NRSHIFT) + | (($sz as $crate::sys::ioctl::ioctl_num_type + & $crate::sys::ioctl::SIZEMASK) + << $crate::sys::ioctl::SIZESHIFT) + }; +} + +/// Generate an ioctl request code for a command that passes no data. +/// +/// This is equivalent to the `_IO()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_none!()` directly. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// const KVMIO: u8 = 0xAE; +/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! request_code_none { + ($ty:expr, $nr:expr) => { + ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0) + }; +} + +/// Generate an ioctl request code for a command that reads. +/// +/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_read!()` directly. +/// +/// The read/write direction is relative to userland, so this +/// command would be userland is reading and the kernel is +/// writing. +#[macro_export(local_inner_macros)] +macro_rules! request_code_read { + ($ty:expr, $nr:expr, $sz:expr) => { + ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz) + }; +} + +/// Generate an ioctl request code for a command that writes. +/// +/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_write!()` directly. +/// +/// The read/write direction is relative to userland, so this +/// command would be userland is writing and the kernel is +/// reading. +#[macro_export(local_inner_macros)] +macro_rules! request_code_write { + ($ty:expr, $nr:expr, $sz:expr) => { + ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz) + }; +} + +/// Generate an ioctl request code for a command that reads and writes. +/// +/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API. +/// +/// You should only use this macro directly if the `ioctl` you're working +/// with is "bad" and you cannot use `ioctl_readwrite!()` directly. +#[macro_export(local_inner_macros)] +macro_rules! request_code_readwrite { + ($ty:expr, $nr:expr, $sz:expr) => { + ioc!( + $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, + $ty, + $nr, + $sz + ) + }; +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/ioctl/mod.rs b/utshell-0.5.0/vendor/nix/src/sys/ioctl/mod.rs new file mode 100644 index 00000000..98d6b5c9 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/ioctl/mod.rs @@ -0,0 +1,786 @@ +//! Provide helpers for making ioctl system calls. +//! +//! This library is pretty low-level and messy. `ioctl` is not fun. +//! +//! What is an `ioctl`? +//! =================== +//! +//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new +//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be +//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file +//! descriptor. +//! +//! It is common to see `ioctl`s used for the following purposes: +//! +//! * Provide read/write access to out-of-band data related to a device such as configuration +//! (for instance, setting serial port options) +//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI +//! devices). +//! * Provide access to control functions on a device (for example, on Linux you can send +//! commands like pause, resume, and eject to the CDROM device. +//! * Do whatever else the device driver creator thought made most sense. +//! +//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard. +//! They operate on file descriptors and have an identifier that specifies what the ioctl is. +//! Additionally they may read or write data and therefore need to pass along a data pointer. +//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also +//! be difficult. +//! +//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some +//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into +//! subcomponents (For linux this is documented in +//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)): +//! +//! * Number: The actual ioctl ID +//! * Type: A grouping of ioctls for a common purpose or driver +//! * Size: The size in bytes of the data that will be transferred +//! * Direction: Whether there is any data and if it's read, write, or both +//! +//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead +//! preferring to use the 4 components above to generate the final ioctl identifier. Because of +//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are +//! commonly referred to as "bad" in `ioctl` documentation. +//! +//! Defining `ioctl`s +//! ================= +//! +//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public +//! unsafe functions that can then be used for calling the ioctl. This macro has a few different +//! ways it can be used depending on the specific ioctl you're working with. +//! +//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This +//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in +//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR` +//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h +//! const SPI_IOC_TYPE_MODE: u8 = 1; +//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); +//! # fn main() {} +//! ``` +//! +//! This generates the function: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! # use std::mem; +//! # use nix::{libc, Result}; +//! # use nix::errno::Errno; +//! # use nix::libc::c_int as c_int; +//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h +//! # const SPI_IOC_TYPE_MODE: u8 = 1; +//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result { +//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::()), data); +//! Errno::result(res) +//! } +//! # fn main() {} +//! ``` +//! +//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s. +//! These are generated by assuming the return value of the ioctl is `-1` on error and everything +//! else is a valid return value. If this is not the case, `Result::map` can be used to map some +//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function. +//! +//! Writing `ioctl`s generally use pointers as their data source and these should use the +//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the +//! `ioctl_write_int!` macro. This variant does not take a type as the last argument: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! const HCI_IOC_MAGIC: u8 = b'k'; +//! const HCI_IOC_HCIDEVUP: u8 = 1; +//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); +//! # fn main() {} +//! ``` +//! +//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro +//! doesn't take a type and so it is declared similar to the `write_int` variant shown above. +//! +//! The mode for a given `ioctl` should be clear from the documentation if it has good +//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl` +//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite" +//! respectively. To determine the specific `write_` variant to use you'll need to find +//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used, +//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the +//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a +//! large number of `ioctl`s and describes their argument data type. +//! +//! Using "bad" `ioctl`s +//! -------------------- +//! +//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of +//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the +//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these +//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates +//! the ioctl number and instead use the defined value directly. +//! +//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor. +//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! # #[cfg(any(target_os = "android", target_os = "linux"))] +//! # use nix::libc::TCGETS as TCGETS; +//! # #[cfg(any(target_os = "android", target_os = "linux"))] +//! # use nix::libc::termios as termios; +//! # #[cfg(any(target_os = "android", target_os = "linux"))] +//! ioctl_read_bad!(tcgets, TCGETS, termios); +//! # fn main() {} +//! ``` +//! +//! The generated function has the same form as that generated by `ioctl_read!`: +//! +//! ```text +//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result; +//! ``` +//! +//! Working with Arrays +//! ------------------- +//! +//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf` +//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that +//! there are no "bad" versions for working with buffers. The generated functions include a `len` +//! argument to specify the number of elements (where the type of each element is specified in the +//! macro). +//! +//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl` +//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs. +//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like: +//! +//! ```C +//! #define SPI_IOC_MAGIC 'k' +//! #define SPI_MSGSIZE(N) ... +//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) +//! ``` +//! +//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's +//! needed to define this `ioctl` is: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h +//! const SPI_IOC_TYPE_MESSAGE: u8 = 0; +//! # pub struct spi_ioc_transfer(u64); +//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); +//! # fn main() {} +//! ``` +//! +//! This generates a function like: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! # use std::mem; +//! # use nix::{libc, Result}; +//! # use nix::errno::Errno; +//! # use nix::libc::c_int as c_int; +//! # const SPI_IOC_MAGIC: u8 = b'k'; +//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0; +//! # pub struct spi_ioc_transfer(u64); +//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result { +//! let res = libc::ioctl(fd, +//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::()), +//! data); +//! Errno::result(res) +//! } +//! # fn main() {} +//! ``` +//! +//! Finding `ioctl` Documentation +//! ----------------------------- +//! +//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot +//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are +//! documented directly in the headers defining their constants, but others have more extensive +//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`). +//! +//! Documenting the Generated Functions +//! =================================== +//! +//! In many cases, users will wish for the functions generated by the `ioctl` +//! macro to be public and documented. For this reason, the generated functions +//! are public by default. If you wish to hide the ioctl, you will need to put +//! them in a private module. +//! +//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an +//! example : +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! # use nix::libc::c_int; +//! ioctl_read! { +//! /// Make the given terminal the controlling terminal of the calling process. The calling +//! /// process must be a session leader and not have a controlling terminal already. If the +//! /// terminal is already the controlling terminal of a different session group then the +//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the +//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen +//! /// and all processes that had it as controlling terminal lose it. +//! tiocsctty, b't', 19, c_int +//! } +//! +//! # fn main() {} +//! ``` +use cfg_if::cfg_if; + +#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] +#[macro_use] +mod linux; + +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "redox" +))] +pub use self::linux::*; + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "haiku", + target_os = "openbsd" +))] +#[macro_use] +mod bsd; + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "haiku", + target_os = "openbsd" +))] +pub use self::bsd::*; + +/// Convert raw ioctl return value to a Nix result +#[macro_export] +#[doc(hidden)] +macro_rules! convert_ioctl_res { + ($w:expr) => {{ + $crate::errno::Errno::result($w) + }}; +} + +/// Generates a wrapper function for an ioctl that passes no data to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as: +/// +/// ```C +/// #define VIDIOC_LOG_STATUS _IO('V', 70) +/// ``` +/// +/// This can be implemented in Rust like: +/// +/// ```no_run +/// # #[macro_use] extern crate nix; +/// ioctl_none!(log_status, b'V', 70); +/// fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_none { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type)) + } + ) +} + +/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl request code +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// ```no_run +/// # #[macro_use] extern crate nix; +/// # use libc::TIOCNXCL; +/// # use std::fs::File; +/// # use std::os::unix::io::AsRawFd; +/// ioctl_none_bad!(tiocnxcl, TIOCNXCL); +/// fn main() { +/// let file = File::open("/dev/ttyUSB0").unwrap(); +/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap(); +/// } +/// ``` +// TODO: add an example using request_code_*!() +#[macro_export(local_inner_macros)] +macro_rules! ioctl_none_bad { + ($(#[$attr:meta])* $name:ident, $nr:expr) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) + } + ) +} + +/// Generates a wrapper function for an ioctl that reads data from the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h +/// const SPI_IOC_TYPE_MODE: u8 = 1; +/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_read { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: *mut $ty) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl request code +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// # #[cfg(any(target_os = "android", target_os = "linux"))] +/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_read_bad { + ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: *mut $ty) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// # pub struct v4l2_audio {} +/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_write_ptr { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: *const $ty) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl request code +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// # #[cfg(any(target_os = "android", target_os = "linux"))] +/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_write_ptr_bad { + ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: *const $ty) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +cfg_if! { + if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] { + /// Generates a wrapper function for a ioctl that writes an integer to the kernel. + /// + /// The arguments to this macro are: + /// + /// * The function name + /// * The ioctl identifier + /// * The ioctl sequence number + /// + /// The generated function has the following signature: + /// + /// ```rust,ignore + /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result + /// ``` + /// + /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: + /// * BSD - `libc::c_int` + /// * Linux - `libc::c_ulong` + /// + /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). + /// + /// # Example + /// + /// ``` + /// # #[macro_use] extern crate nix; + /// ioctl_write_int!(vt_activate, b'v', 4); + /// # fn main() {} + /// ``` + #[macro_export(local_inner_macros)] + macro_rules! ioctl_write_int { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: $crate::sys::ioctl::ioctl_param_type) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) + } + } else { + /// Generates a wrapper function for a ioctl that writes an integer to the kernel. + /// + /// The arguments to this macro are: + /// + /// * The function name + /// * The ioctl identifier + /// * The ioctl sequence number + /// + /// The generated function has the following signature: + /// + /// ```rust,ignore + /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result + /// ``` + /// + /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: + /// * BSD - `libc::c_int` + /// * Linux - `libc::c_ulong` + /// + /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). + /// + /// # Example + /// + /// ``` + /// # #[macro_use] extern crate nix; + /// const HCI_IOC_MAGIC: u8 = b'k'; + /// const HCI_IOC_HCIDEVUP: u8 = 1; + /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); + /// # fn main() {} + /// ``` + #[macro_export(local_inner_macros)] + macro_rules! ioctl_write_int { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: $crate::sys::ioctl::ioctl_param_type) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) + } + } +} + +/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl request code +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Examples +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// # #[cfg(any(target_os = "android", target_os = "linux"))] +/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK); +/// # fn main() {} +/// ``` +/// +/// ```rust +/// # #[macro_use] extern crate nix; +/// const KVMIO: u8 = 0xAE; +/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_write_int_bad { + ($(#[$attr:meta])* $name:ident, $nr:expr) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: $crate::libc::c_int) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for an ioctl that reads and writes data to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// # pub struct v4l2_audio {} +/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_readwrite { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: *mut $ty) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl request code +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +// TODO: Find an example for ioctl_readwrite_bad +#[macro_export(local_inner_macros)] +macro_rules! ioctl_readwrite_bad { + ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: *mut $ty) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +// TODO: Find an example for ioctl_read_buf +#[macro_export(local_inner_macros)] +macro_rules! ioctl_read_buf { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: &mut [$ty]) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +/// +/// # Examples +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h +/// const SPI_IOC_TYPE_MESSAGE: u8 = 0; +/// # pub struct spi_ioc_transfer(u64); +/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); +/// # fn main() {} +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! ioctl_write_buf { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: &[$ty]) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} + +/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel. +/// +/// The arguments to this macro are: +/// +/// * The function name +/// * The ioctl identifier +/// * The ioctl sequence number +/// * The data type passed by this ioctl +/// +/// The generated function has the following signature: +/// +/// ```rust,ignore +/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result +/// ``` +/// +/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). +// TODO: Find an example for readwrite_buf +#[macro_export(local_inner_macros)] +macro_rules! ioctl_readwrite_buf { + ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( + $(#[$attr])* + pub unsafe fn $name(fd: $crate::libc::c_int, + data: &mut [$ty]) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/memfd.rs b/utshell-0.5.0/vendor/nix/src/sys/memfd.rs new file mode 100644 index 00000000..642676b4 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/memfd.rs @@ -0,0 +1,47 @@ +//! Interfaces for managing memory-backed files. + +use std::os::unix::io::RawFd; +use crate::Result; +use crate::errno::Errno; +use std::ffi::CStr; + +libc_bitflags!( + /// Options that change the behavior of [`memfd_create`]. + pub struct MemFdCreateFlag: libc::c_uint { + /// Set the close-on-exec ([`FD_CLOEXEC`]) flag on the new file descriptor. + /// + /// By default, the new file descriptor is set to remain open across an [`execve`] + /// (the `FD_CLOEXEC` flag is initially disabled). This flag can be used to change + /// this default. The file offset is set to the beginning of the file (see [`lseek`]). + /// + /// See also the description of the `O_CLOEXEC` flag in [`open(2)`]. + /// + /// [`execve`]: crate::unistd::execve + /// [`lseek`]: crate::unistd::lseek + /// [`FD_CLOEXEC`]: crate::fcntl::FdFlag::FD_CLOEXEC + /// [`open(2)`]: https://man7.org/linux/man-pages/man2/open.2.html + MFD_CLOEXEC; + /// Allow sealing operations on this file. + /// + /// See also the file sealing notes given in [`memfd_create(2)`]. + /// + /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html + MFD_ALLOW_SEALING; + } +); + +/// Creates an anonymous file that lives in memory, and return a file-descriptor to it. +/// +/// The file behaves like a regular file, and so can be modified, truncated, memory-mapped, and so on. +/// However, unlike a regular file, it lives in RAM and has a volatile backing storage. +/// +/// For more information, see [`memfd_create(2)`]. +/// +/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html +pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result { + let res = unsafe { + libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) + }; + + Errno::result(res).map(|r| r as RawFd) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/mman.rs b/utshell-0.5.0/vendor/nix/src/sys/mman.rs new file mode 100644 index 00000000..700e231c --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/mman.rs @@ -0,0 +1,569 @@ +//! Memory management declarations. + +use crate::Result; +#[cfg(not(target_os = "android"))] +use crate::NixPath; +use crate::errno::Errno; +#[cfg(not(target_os = "android"))] +#[cfg(feature = "fs")] +use crate::{fcntl::OFlag, sys::stat::Mode}; +use libc::{self, c_int, c_void, size_t, off_t}; +use std::os::unix::io::RawFd; + +libc_bitflags!{ + /// Desired memory protection of a memory mapping. + pub struct ProtFlags: c_int { + /// Pages cannot be accessed. + PROT_NONE; + /// Pages can be read. + PROT_READ; + /// Pages can be written. + PROT_WRITE; + /// Pages can be executed + PROT_EXEC; + /// Apply protection up to the end of a mapping that grows upwards. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PROT_GROWSDOWN; + /// Apply protection down to the beginning of a mapping that grows downwards. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PROT_GROWSUP; + } +} + +libc_bitflags!{ + /// Additional parameters for [`mmap`]. + pub struct MapFlags: c_int { + /// Compatibility flag. Ignored. + MAP_FILE; + /// Share this mapping. Mutually exclusive with `MAP_PRIVATE`. + MAP_SHARED; + /// Create a private copy-on-write mapping. Mutually exclusive with `MAP_SHARED`. + MAP_PRIVATE; + /// Place the mapping at exactly the address specified in `addr`. + MAP_FIXED; + /// Place the mapping at exactly the address specified in `addr`, but never clobber an existing range. + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_FIXED_NOREPLACE; + /// To be used with `MAP_FIXED`, to forbid the system + /// to select a different address than the one specified. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_EXCL; + /// Synonym for `MAP_ANONYMOUS`. + MAP_ANON; + /// The mapping is not backed by any file. + MAP_ANONYMOUS; + /// Put the mapping into the first 2GB of the process address space. + #[cfg(any(all(any(target_os = "android", target_os = "linux"), + any(target_arch = "x86", target_arch = "x86_64")), + all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")), + all(target_os = "freebsd", target_pointer_width = "64")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_32BIT; + /// Used for stacks; indicates to the kernel that the mapping should extend downward in memory. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_GROWSDOWN; + /// Compatibility flag. Ignored. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_DENYWRITE; + /// Compatibility flag. Ignored. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_EXECUTABLE; + /// Mark the mmaped region to be locked in the same way as `mlock(2)`. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_LOCKED; + /// Do not reserve swap space for this mapping. + /// + /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD. + #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NORESERVE; + /// Populate page tables for a mapping. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_POPULATE; + /// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NONBLOCK; + /// Allocate the mapping using "huge pages." + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGETLB; + /// Make use of 64KB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_64KB; + /// Make use of 512KB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_512KB; + /// Make use of 1MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_1MB; + /// Make use of 2MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_2MB; + /// Make use of 8MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_8MB; + /// Make use of 16MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_16MB; + /// Make use of 32MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_32MB; + /// Make use of 256MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_256MB; + /// Make use of 512MB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_512MB; + /// Make use of 1GB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_1GB; + /// Make use of 2GB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_2GB; + /// Make use of 16GB huge page (must be supported by the system) + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGE_16GB; + + /// Lock the mapped region into memory as with `mlock(2)`. + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_WIRED; + /// Causes dirtied data in the specified range to be flushed to disk only when necessary. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NOSYNC; + /// Rename private pages to a file. + /// + /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD. + #[cfg(any(target_os = "netbsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_RENAME; + /// Region may contain semaphores. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HASSEMAPHORE; + /// Region grows down, like a stack. + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_STACK; + /// Pages in this mapping are not retained in the kernel's memory cache. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NOCACHE; + /// Allows the W/X bit on the page, it's necessary on aarch64 architecture. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_JIT; + /// Allows to use large pages, underlying alignment based on size. + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_ALIGNED_SUPER; + /// Pages will be discarded in the core dumps. + #[cfg(target_os = "openbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_CONCEAL; + } +} + +#[cfg(any(target_os = "linux", target_os = "netbsd"))] +libc_bitflags!{ + /// Options for [`mremap`]. + pub struct MRemapFlags: c_int { + /// Permit the kernel to relocate the mapping to a new virtual address, if necessary. + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MREMAP_MAYMOVE; + /// Place the mapping at exactly the address specified in `new_address`. + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MREMAP_FIXED; + /// Place the mapping at exactly the address specified in `new_address`. + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_FIXED; + /// Allows to duplicate the mapping to be able to apply different flags on the copy. + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_REMAPDUP; + } +} + +libc_enum!{ + /// Usage information for a range of memory to allow for performance optimizations by the kernel. + /// + /// Used by [`madvise`]. + #[repr(i32)] + #[non_exhaustive] + pub enum MmapAdvise { + /// No further special treatment. This is the default. + MADV_NORMAL, + /// Expect random page references. + MADV_RANDOM, + /// Expect sequential page references. + MADV_SEQUENTIAL, + /// Expect access in the near future. + MADV_WILLNEED, + /// Do not expect access in the near future. + MADV_DONTNEED, + /// Free up a given range of pages and its associated backing store. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_REMOVE, + /// Do not make pages in this range available to the child after a `fork(2)`. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DONTFORK, + /// Undo the effect of `MADV_DONTFORK`. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DOFORK, + /// Poison the given pages. + /// + /// Subsequent references to those pages are treated like hardware memory corruption. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_HWPOISON, + /// Enable Kernel Samepage Merging (KSM) for the given pages. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_MERGEABLE, + /// Undo the effect of `MADV_MERGEABLE` + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_UNMERGEABLE, + /// Preserve the memory of each page but offline the original page. + #[cfg(any(target_os = "android", + all(target_os = "linux", any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "s390x", + target_arch = "x86", + target_arch = "x86_64", + target_arch = "sparc64"))))] + MADV_SOFT_OFFLINE, + /// Enable Transparent Huge Pages (THP) for pages in the given range. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_HUGEPAGE, + /// Undo the effect of `MADV_HUGEPAGE`. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_NOHUGEPAGE, + /// Exclude the given range from a core dump. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DONTDUMP, + /// Undo the effect of an earlier `MADV_DONTDUMP`. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DODUMP, + /// Specify that the application no longer needs the pages in the given range. + MADV_FREE, + /// Request that the system not flush the current range to disk unless it needs to. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_NOSYNC, + /// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_AUTOSYNC, + /// Region is not included in a core file. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_NOCORE, + /// Include region in a core file + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_CORE, + /// This process should not be killed when swap space is exhausted. + #[cfg(any(target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_PROTECT, + /// Invalidate the hardware page table for the given region. + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_INVAL, + /// Set the offset of the page directory page to `value` for the virtual page table. + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_SETMAP, + /// Indicates that the application will not need the data in the given range. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_ZERO_WIRED_PAGES, + /// Pages can be reused (by anyone). + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_FREE_REUSABLE, + /// Caller wants to reuse those pages. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_FREE_REUSE, + // Darwin doesn't document this flag's behavior. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + #[allow(missing_docs)] + MADV_CAN_REUSE, + } +} + +libc_bitflags!{ + /// Configuration flags for [`msync`]. + pub struct MsFlags: c_int { + /// Schedule an update but return immediately. + MS_ASYNC; + /// Invalidate all cached data. + MS_INVALIDATE; + /// Invalidate pages, but leave them mapped. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MS_KILLPAGES; + /// Deactivate pages, but leave them mapped. + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MS_DEACTIVATE; + /// Perform an update and wait for it to complete. + MS_SYNC; + } +} + +#[cfg(not(target_os = "haiku"))] +libc_bitflags!{ + /// Flags for [`mlockall`]. + pub struct MlockAllFlags: c_int { + /// Lock pages that are currently mapped into the address space of the process. + MCL_CURRENT; + /// Lock pages which will become mapped into the address space of the process in the future. + MCL_FUTURE; + } +} + +/// Locks all memory pages that contain part of the address range with `length` +/// bytes starting at `addr`. +/// +/// Locked pages never move to the swap area. +/// +/// # Safety +/// +/// `addr` must meet all the requirements described in the [`mlock(2)`] man page. +/// +/// [`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html +pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> { + Errno::result(libc::mlock(addr, length)).map(drop) +} + +/// Unlocks all memory pages that contain part of the address range with +/// `length` bytes starting at `addr`. +/// +/// # Safety +/// +/// `addr` must meet all the requirements described in the [`munlock(2)`] man +/// page. +/// +/// [`munlock(2)`]: https://man7.org/linux/man-pages/man2/munlock.2.html +pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> { + Errno::result(libc::munlock(addr, length)).map(drop) +} + +/// Locks all memory pages mapped into this process' address space. +/// +/// Locked pages never move to the swap area. For more information, see [`mlockall(2)`]. +/// +/// [`mlockall(2)`]: https://man7.org/linux/man-pages/man2/mlockall.2.html +#[cfg(not(target_os = "haiku"))] +pub fn mlockall(flags: MlockAllFlags) -> Result<()> { + unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop) +} + +/// Unlocks all memory pages mapped into this process' address space. +/// +/// For more information, see [`munlockall(2)`]. +/// +/// [`munlockall(2)`]: https://man7.org/linux/man-pages/man2/munlockall.2.html +#[cfg(not(target_os = "haiku"))] +pub fn munlockall() -> Result<()> { + unsafe { Errno::result(libc::munlockall()) }.map(drop) +} + +/// allocate memory, or map files or devices into memory +/// +/// # Safety +/// +/// See the [`mmap(2)`] man page for detailed requirements. +/// +/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html +pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> { + let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset); + + if ret == libc::MAP_FAILED { + Err(Errno::last()) + } else { + Ok(ret) + } +} + +/// Expands (or shrinks) an existing memory mapping, potentially moving it at +/// the same time. +/// +/// # Safety +/// +/// See the `mremap(2)` [man page](https://man7.org/linux/man-pages/man2/mremap.2.html) for +/// detailed requirements. +#[cfg(any(target_os = "linux", target_os = "netbsd"))] +pub unsafe fn mremap( + addr: *mut c_void, + old_size: size_t, + new_size: size_t, + flags: MRemapFlags, + new_address: Option<* mut c_void>, +) -> Result<*mut c_void> { + #[cfg(target_os = "linux")] + let ret = libc::mremap(addr, old_size, new_size, flags.bits(), new_address.unwrap_or(std::ptr::null_mut())); + #[cfg(target_os = "netbsd")] + let ret = libc::mremap( + addr, + old_size, + new_address.unwrap_or(std::ptr::null_mut()), + new_size, + flags.bits(), + ); + + if ret == libc::MAP_FAILED { + Err(Errno::last()) + } else { + Ok(ret) + } +} + +/// remove a mapping +/// +/// # Safety +/// +/// `addr` must meet all the requirements described in the [`munmap(2)`] man +/// page. +/// +/// [`munmap(2)`]: https://man7.org/linux/man-pages/man2/munmap.2.html +pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> { + Errno::result(libc::munmap(addr, len)).map(drop) +} + +/// give advice about use of memory +/// +/// # Safety +/// +/// See the [`madvise(2)`] man page. Take special care when using +/// [`MmapAdvise::MADV_FREE`]. +/// +/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html +pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> { + Errno::result(libc::madvise(addr, length, advise as i32)).map(drop) +} + +/// Set protection of memory mapping. +/// +/// See [`mprotect(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for +/// details. +/// +/// # Safety +/// +/// Calls to `mprotect` are inherently unsafe, as changes to memory protections can lead to +/// SIGSEGVs. +/// +/// ``` +/// # use nix::libc::size_t; +/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags}; +/// # use std::ptr; +/// const ONE_K: size_t = 1024; +/// let mut slice: &mut [u8] = unsafe { +/// let mem = mmap(ptr::null_mut(), ONE_K, ProtFlags::PROT_NONE, +/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap(); +/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap(); +/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) +/// }; +/// assert_eq!(slice[0], 0x00); +/// slice[0] = 0xFF; +/// assert_eq!(slice[0], 0xFF); +/// ``` +pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Result<()> { + Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop) +} + +/// synchronize a mapped region +/// +/// # Safety +/// +/// `addr` must meet all the requirements described in the [`msync(2)`] man +/// page. +/// +/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html +pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> { + Errno::result(libc::msync(addr, length, flags.bits())).map(drop) +} + +#[cfg(not(target_os = "android"))] +feature! { +#![feature = "fs"] +/// Creates and opens a new, or opens an existing, POSIX shared memory object. +/// +/// For more information, see [`shm_open(3)`]. +/// +/// [`shm_open(3)`]: https://man7.org/linux/man-pages/man3/shm_open.3.html +pub fn shm_open

( + name: &P, + flag: OFlag, + mode: Mode + ) -> Result + where P: ?Sized + NixPath +{ + let ret = name.with_nix_path(|cstr| { + #[cfg(any(target_os = "macos", target_os = "ios"))] + unsafe { + libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint) + } + #[cfg(not(any(target_os = "macos", target_os = "ios")))] + unsafe { + libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t) + } + })?; + + Errno::result(ret) +} +} + +/// Performs the converse of [`shm_open`], removing an object previously created. +/// +/// For more information, see [`shm_unlink(3)`]. +/// +/// [`shm_unlink(3)`]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html +#[cfg(not(target_os = "android"))] +pub fn shm_unlink(name: &P) -> Result<()> { + let ret = name.with_nix_path(|cstr| { + unsafe { libc::shm_unlink(cstr.as_ptr()) } + })?; + + Errno::result(ret).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/mod.rs b/utshell-0.5.0/vendor/nix/src/sys/mod.rs new file mode 100644 index 00000000..979d623b --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/mod.rs @@ -0,0 +1,228 @@ +//! Mostly platform-specific functionality +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + all(target_os = "linux", not(target_env = "uclibc")), + target_os = "macos", + target_os = "netbsd" +))] +feature! { + #![feature = "aio"] + pub mod aio; +} + +feature! { + #![feature = "event"] + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[allow(missing_docs)] + pub mod epoll; + + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[allow(missing_docs)] + pub mod event; + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[allow(missing_docs)] + pub mod eventfd; +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "redox", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd" +))] +#[cfg(feature = "ioctl")] +#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] +#[macro_use] +pub mod ioctl; + +#[cfg(any(target_os = "android", target_os = "linux"))] +feature! { + #![feature = "fs"] + pub mod memfd; +} + +#[cfg(not(target_os = "redox"))] +feature! { + #![feature = "mman"] + pub mod mman; +} + +#[cfg(target_os = "linux")] +feature! { + #![feature = "personality"] + pub mod personality; +} + +feature! { + #![feature = "pthread"] + pub mod pthread; +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd" +))] +feature! { + #![feature = "ptrace"] + #[allow(missing_docs)] + pub mod ptrace; +} + +#[cfg(target_os = "linux")] +feature! { + #![feature = "quota"] + pub mod quota; +} + +#[cfg(target_os = "linux")] +feature! { + #![feature = "reboot"] + pub mod reboot; +} + +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "illumos", + target_os = "haiku" +)))] +feature! { + #![feature = "resource"] + pub mod resource; +} + +#[cfg(not(target_os = "redox"))] +feature! { + #![feature = "poll"] + pub mod select; +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos" +))] +feature! { + #![feature = "zerocopy"] + pub mod sendfile; +} + +pub mod signal; + +#[cfg(any(target_os = "android", target_os = "linux"))] +feature! { + #![feature = "signal"] + #[allow(missing_docs)] + pub mod signalfd; +} + +#[cfg(not(target_os = "redox"))] +feature! { + #![feature = "socket"] + #[allow(missing_docs)] + pub mod socket; +} + +feature! { + #![feature = "fs"] + #[allow(missing_docs)] + pub mod stat; +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "openbsd" +))] +feature! { + #![feature = "fs"] + pub mod statfs; +} + +feature! { + #![feature = "fs"] + pub mod statvfs; +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +#[allow(missing_docs)] +pub mod sysinfo; + +feature! { + #![feature = "term"] + #[allow(missing_docs)] + pub mod termios; +} + +#[allow(missing_docs)] +pub mod time; + +feature! { + #![feature = "uio"] + pub mod uio; +} + +feature! { + #![feature = "feature"] + pub mod utsname; +} + +feature! { + #![feature = "process"] + pub mod wait; +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +feature! { + #![feature = "inotify"] + pub mod inotify; +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +feature! { + #![feature = "time"] + pub mod timerfd; +} + +#[cfg(all( + any( + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd" + ), + feature = "time", + feature = "signal" +))] +feature! { + #![feature = "time"] + pub mod timer; +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/personality.rs b/utshell-0.5.0/vendor/nix/src/sys/personality.rs new file mode 100644 index 00000000..9e285ae6 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/personality.rs @@ -0,0 +1,97 @@ +//! Process execution domains +use crate::Result; +use crate::errno::Errno; + +use libc::{self, c_int, c_ulong}; + +libc_bitflags! { + /// Flags used and returned by [`get()`](fn.get.html) and + /// [`set()`](fn.set.html). + pub struct Persona: c_int { + /// Provide the legacy virtual address space layout. + ADDR_COMPAT_LAYOUT; + /// Disable address-space-layout randomization. + ADDR_NO_RANDOMIZE; + /// Limit the address space to 32 bits. + ADDR_LIMIT_32BIT; + /// Use `0xc0000000` as the offset at which to search a virtual memory + /// chunk on [`mmap(2)`], otherwise use `0xffffe000`. + /// + /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html + ADDR_LIMIT_3GB; + /// User-space function pointers to signal handlers point to descriptors. + #[cfg(not(any(target_env = "musl", target_env = "uclibc")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + FDPIC_FUNCPTRS; + /// Map page 0 as read-only. + MMAP_PAGE_ZERO; + /// `PROT_READ` implies `PROT_EXEC` for [`mmap(2)`]. + /// + /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html + READ_IMPLIES_EXEC; + /// No effects. + SHORT_INODE; + /// [`select(2)`], [`pselect(2)`], and [`ppoll(2)`] do not modify the + /// returned timeout argument when interrupted by a signal handler. + /// + /// [`select(2)`]: https://man7.org/linux/man-pages/man2/select.2.html + /// [`pselect(2)`]: https://man7.org/linux/man-pages/man2/pselect.2.html + /// [`ppoll(2)`]: https://man7.org/linux/man-pages/man2/ppoll.2.html + STICKY_TIMEOUTS; + /// Have [`uname(2)`] report a 2.6.40+ version number rather than a 3.x + /// version number. + /// + /// [`uname(2)`]: https://man7.org/linux/man-pages/man2/uname.2.html + #[cfg(not(any(target_env = "musl", target_env = "uclibc")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + UNAME26; + /// No effects. + WHOLE_SECONDS; + } +} + +/// Retrieve the current process personality. +/// +/// Returns a Result containing a Persona instance. +/// +/// Example: +/// +/// ``` +/// # use nix::sys::personality::{self, Persona}; +/// let pers = personality::get().unwrap(); +/// assert!(!pers.contains(Persona::WHOLE_SECONDS)); +/// ``` +pub fn get() -> Result { + let res = unsafe { + libc::personality(0xFFFFFFFF) + }; + + Errno::result(res).map(Persona::from_bits_truncate) +} + +/// Set the current process personality. +/// +/// Returns a Result containing the *previous* personality for the +/// process, as a Persona. +/// +/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html) +/// +/// **NOTE**: This call **replaces** the current personality entirely. +/// To **update** the personality, first call `get()` and then `set()` +/// with the modified persona. +/// +/// Example: +/// +/// ``` +/// # use nix::sys::personality::{self, Persona}; +/// let mut pers = personality::get().unwrap(); +/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE)); +/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE).unwrap(); +/// ``` +pub fn set(persona: Persona) -> Result { + let res = unsafe { + libc::personality(persona.bits() as c_ulong) + }; + + Errno::result(res).map(Persona::from_bits_truncate) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/pthread.rs b/utshell-0.5.0/vendor/nix/src/sys/pthread.rs new file mode 100644 index 00000000..6bad03a4 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/pthread.rs @@ -0,0 +1,43 @@ +//! Low level threading primitives + +#[cfg(not(target_os = "redox"))] +use crate::errno::Errno; +#[cfg(not(target_os = "redox"))] +use crate::Result; +use libc::{self, pthread_t}; + +/// Identifies an individual thread. +pub type Pthread = pthread_t; + +/// Obtain ID of the calling thread (see +/// [`pthread_self(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html) +/// +/// The thread ID returned by `pthread_self()` is not the same thing as +/// the kernel thread ID returned by a call to `gettid(2)`. +#[inline] +pub fn pthread_self() -> Pthread { + unsafe { libc::pthread_self() } +} + +feature! { +#![feature = "signal"] + +/// Send a signal to a thread (see [`pthread_kill(3)`]). +/// +/// If `signal` is `None`, `pthread_kill` will only preform error checking and +/// won't send any signal. +/// +/// [`pthread_kill(3)`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html +#[allow(clippy::not_unsafe_ptr_arg_deref)] +#[cfg(not(target_os = "redox"))] +pub fn pthread_kill(thread: Pthread, signal: T) -> Result<()> + where T: Into> +{ + let sig = match signal.into() { + Some(s) => s as libc::c_int, + None => 0, + }; + let res = unsafe { libc::pthread_kill(thread, sig) }; + Errno::result(res).map(drop) +} +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/ptrace/bsd.rs b/utshell-0.5.0/vendor/nix/src/sys/ptrace/bsd.rs new file mode 100644 index 00000000..c4cc7403 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/ptrace/bsd.rs @@ -0,0 +1,187 @@ +use cfg_if::cfg_if; +use crate::errno::Errno; +use libc::{self, c_int}; +use std::ptr; +use crate::sys::signal::Signal; +use crate::unistd::Pid; +use crate::Result; + +pub type RequestType = c_int; + +cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "openbsd"))] { + #[doc(hidden)] + pub type AddressType = *mut ::libc::c_char; + } else { + #[doc(hidden)] + pub type AddressType = *mut ::libc::c_void; + } +} + +libc_enum! { + #[repr(i32)] + /// Ptrace Request enum defining the action to be taken. + #[non_exhaustive] + pub enum Request { + PT_TRACE_ME, + PT_READ_I, + PT_READ_D, + #[cfg(target_os = "macos")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PT_READ_U, + PT_WRITE_I, + PT_WRITE_D, + #[cfg(target_os = "macos")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PT_WRITE_U, + PT_CONTINUE, + PT_KILL, + #[cfg(any(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos"), + all(target_os = "openbsd", target_arch = "x86_64"), + all(target_os = "netbsd", any(target_arch = "x86_64", + target_arch = "powerpc"))))] + PT_STEP, + PT_ATTACH, + PT_DETACH, + #[cfg(target_os = "macos")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PT_SIGEXC, + #[cfg(target_os = "macos")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PT_THUPDATE, + #[cfg(target_os = "macos")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PT_ATTACHEXC + } +} + +unsafe fn ptrace_other( + request: Request, + pid: Pid, + addr: AddressType, + data: c_int, +) -> Result { + Errno::result(libc::ptrace( + request as RequestType, + libc::pid_t::from(pid), + addr, + data, + )).map(|_| 0) +} + +/// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)` +/// +/// Indicates that this process is to be traced by its parent. +/// This is the only ptrace request to be issued by the tracee. +pub fn traceme() -> Result<()> { + unsafe { ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0).map(drop) } +} + +/// Attach to a running process, as with `ptrace(PT_ATTACH, ...)` +/// +/// Attaches to the process specified by `pid`, making it a tracee of the calling process. +pub fn attach(pid: Pid) -> Result<()> { + unsafe { ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) } +} + +/// Detaches the current running process, as with `ptrace(PT_DETACH, ...)` +/// +/// Detaches from the process specified by `pid` allowing it to run freely, optionally delivering a +/// signal specified by `sig`. +pub fn detach>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as c_int, + None => 0, + }; + unsafe { + ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), data).map(drop) + } +} + +/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)` +/// +/// Continues the execution of the process with PID `pid`, optionally +/// delivering a signal specified by `sig`. +pub fn cont>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as c_int, + None => 0, + }; + unsafe { + // Ignore the useless return value + ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data).map(drop) + } +} + +/// Issues a kill request as with `ptrace(PT_KILL, ...)` +/// +/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);` +pub fn kill(pid: Pid) -> Result<()> { + unsafe { + ptrace_other(Request::PT_KILL, pid, 0 as AddressType, 0).map(drop) + } +} + +/// Move the stopped tracee process forward by a single step as with +/// `ptrace(PT_STEP, ...)` +/// +/// Advances the execution of the process with PID `pid` by a single step optionally delivering a +/// signal specified by `sig`. +/// +/// # Example +/// ```rust +/// use nix::sys::ptrace::step; +/// use nix::unistd::Pid; +/// use nix::sys::signal::Signal; +/// use nix::sys::wait::*; +/// // If a process changes state to the stopped state because of a SIGUSR1 +/// // signal, this will step the process forward and forward the user +/// // signal to the stopped process +/// match waitpid(Pid::from_raw(-1), None) { +/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => { +/// let _ = step(pid, Signal::SIGUSR1); +/// } +/// _ => {}, +/// } +/// ``` +#[cfg( + any( + any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"), + all(target_os = "openbsd", target_arch = "x86_64"), + all(target_os = "netbsd", + any(target_arch = "x86_64", target_arch = "powerpc") + ) + ) +)] +pub fn step>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as c_int, + None => 0, + }; + unsafe { ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop) } +} + +/// Reads a word from a processes memory at the given address +// Technically, ptrace doesn't dereference the pointer. It passes it directly +// to the kernel. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn read(pid: Pid, addr: AddressType) -> Result { + unsafe { + // Traditionally there was a difference between reading data or + // instruction memory but not in modern systems. + ptrace_other(Request::PT_READ_D, pid, addr, 0) + } +} + +/// Writes a word into the processes memory at the given address +// Technically, ptrace doesn't dereference the pointer. It passes it directly +// to the kernel. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn write(pid: Pid, addr: AddressType, data: c_int) -> Result<()> { + unsafe { ptrace_other(Request::PT_WRITE_D, pid, addr, data).map(drop) } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/ptrace/linux.rs b/utshell-0.5.0/vendor/nix/src/sys/ptrace/linux.rs new file mode 100644 index 00000000..1d9b241c --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/ptrace/linux.rs @@ -0,0 +1,504 @@ +//! For detailed description of the ptrace requests, consult `man ptrace`. + +use cfg_if::cfg_if; +use std::{mem, ptr}; +use crate::Result; +use crate::errno::Errno; +use libc::{self, c_void, c_long, siginfo_t}; +use crate::unistd::Pid; +use crate::sys::signal::Signal; + +pub type AddressType = *mut ::libc::c_void; + +#[cfg(all( + target_os = "linux", + any(all(target_arch = "x86_64", + any(target_env = "gnu", target_env = "musl")), + all(target_arch = "x86", target_env = "gnu")) +))] +use libc::user_regs_struct; + +cfg_if! { + if #[cfg(any(all(target_os = "linux", target_arch = "s390x"), + all(target_os = "linux", target_env = "gnu"), + target_env = "uclibc"))] { + #[doc(hidden)] + pub type RequestType = ::libc::c_uint; + } else { + #[doc(hidden)] + pub type RequestType = ::libc::c_int; + } +} + +libc_enum!{ + #[cfg_attr(not(any(target_env = "musl", target_env = "uclibc", target_os = "android")), repr(u32))] + #[cfg_attr(any(target_env = "musl", target_env = "uclibc", target_os = "android"), repr(i32))] + /// Ptrace Request enum defining the action to be taken. + #[non_exhaustive] + pub enum Request { + PTRACE_TRACEME, + PTRACE_PEEKTEXT, + PTRACE_PEEKDATA, + PTRACE_PEEKUSER, + PTRACE_POKETEXT, + PTRACE_POKEDATA, + PTRACE_POKEUSER, + PTRACE_CONT, + PTRACE_KILL, + PTRACE_SINGLESTEP, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), + all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", + target_pointer_width = "32"))))] + PTRACE_GETREGS, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), + all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", + target_pointer_width = "32"))))] + PTRACE_SETREGS, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), + all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", + target_pointer_width = "32"))))] + PTRACE_GETFPREGS, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), + all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", + target_pointer_width = "32"))))] + PTRACE_SETFPREGS, + PTRACE_ATTACH, + PTRACE_DETACH, + #[cfg(all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86", + target_arch = "x86_64")))] + PTRACE_GETFPXREGS, + #[cfg(all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86", + target_arch = "x86_64")))] + PTRACE_SETFPXREGS, + PTRACE_SYSCALL, + PTRACE_SETOPTIONS, + PTRACE_GETEVENTMSG, + PTRACE_GETSIGINFO, + PTRACE_SETSIGINFO, + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] + PTRACE_GETREGSET, + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] + PTRACE_SETREGSET, + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PTRACE_SEIZE, + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + PTRACE_INTERRUPT, + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] + PTRACE_LISTEN, + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] + PTRACE_PEEKSIGINFO, + #[cfg(all(target_os = "linux", target_env = "gnu", + any(target_arch = "x86", target_arch = "x86_64")))] + PTRACE_SYSEMU, + #[cfg(all(target_os = "linux", target_env = "gnu", + any(target_arch = "x86", target_arch = "x86_64")))] + PTRACE_SYSEMU_SINGLESTEP, + } +} + +libc_enum!{ + #[repr(i32)] + /// Using the ptrace options the tracer can configure the tracee to stop + /// at certain events. This enum is used to define those events as defined + /// in `man ptrace`. + #[non_exhaustive] + pub enum Event { + /// Event that stops before a return from fork or clone. + PTRACE_EVENT_FORK, + /// Event that stops before a return from vfork or clone. + PTRACE_EVENT_VFORK, + /// Event that stops before a return from clone. + PTRACE_EVENT_CLONE, + /// Event that stops before a return from execve. + PTRACE_EVENT_EXEC, + /// Event for a return from vfork. + PTRACE_EVENT_VFORK_DONE, + /// Event for a stop before an exit. Unlike the waitpid Exit status program. + /// registers can still be examined + PTRACE_EVENT_EXIT, + /// Stop triggered by a seccomp rule on a tracee. + PTRACE_EVENT_SECCOMP, + /// Stop triggered by the `INTERRUPT` syscall, or a group stop, + /// or when a new child is attached. + PTRACE_EVENT_STOP, + } +} + +libc_bitflags! { + /// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request. + /// See `man ptrace` for more details. + pub struct Options: libc::c_int { + /// When delivering system call traps set a bit to allow tracer to + /// distinguish between normal stops or syscall stops. May not work on + /// all systems. + PTRACE_O_TRACESYSGOOD; + /// Stop tracee at next fork and start tracing the forked process. + PTRACE_O_TRACEFORK; + /// Stop tracee at next vfork call and trace the vforked process. + PTRACE_O_TRACEVFORK; + /// Stop tracee at next clone call and trace the cloned process. + PTRACE_O_TRACECLONE; + /// Stop tracee at next execve call. + PTRACE_O_TRACEEXEC; + /// Stop tracee at vfork completion. + PTRACE_O_TRACEVFORKDONE; + /// Stop tracee at next exit call. Stops before exit commences allowing + /// tracer to see location of exit and register states. + PTRACE_O_TRACEEXIT; + /// Stop tracee when a SECCOMP_RET_TRACE rule is triggered. See `man seccomp` for more + /// details. + PTRACE_O_TRACESECCOMP; + /// Send a SIGKILL to the tracee if the tracer exits. This is useful + /// for ptrace jailers to prevent tracees from escaping their control. + PTRACE_O_EXITKILL; + } +} + +fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result { + let ret = unsafe { + Errno::clear(); + libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data) + }; + match Errno::result(ret) { + Ok(..) | Err(Errno::UnknownErrno) => Ok(ret), + err @ Err(..) => err, + } +} + +/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)` +#[cfg(all( + target_os = "linux", + any(all(target_arch = "x86_64", + any(target_env = "gnu", target_env = "musl")), + all(target_arch = "x86", target_env = "gnu")) +))] +pub fn getregs(pid: Pid) -> Result { + ptrace_get_data::(Request::PTRACE_GETREGS, pid) +} + +/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)` +#[cfg(all( + target_os = "linux", + any(all(target_arch = "x86_64", + any(target_env = "gnu", target_env = "musl")), + all(target_arch = "x86", target_env = "gnu")) +))] +pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { + let res = unsafe { + libc::ptrace(Request::PTRACE_SETREGS as RequestType, + libc::pid_t::from(pid), + ptr::null_mut::(), + ®s as *const _ as *const c_void) + }; + Errno::result(res).map(drop) +} + +/// Function for ptrace requests that return values from the data field. +/// Some ptrace get requests populate structs or larger elements than `c_long` +/// and therefore use the data field to return values. This function handles these +/// requests. +fn ptrace_get_data(request: Request, pid: Pid) -> Result { + let mut data = mem::MaybeUninit::uninit(); + let res = unsafe { + libc::ptrace(request as RequestType, + libc::pid_t::from(pid), + ptr::null_mut::(), + data.as_mut_ptr() as *const _ as *const c_void) + }; + Errno::result(res)?; + Ok(unsafe{ data.assume_init() }) +} + +unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result { + Errno::result(libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)).map(|_| 0) +} + +/// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`. +pub fn setoptions(pid: Pid, options: Options) -> Result<()> { + let res = unsafe { + libc::ptrace(Request::PTRACE_SETOPTIONS as RequestType, + libc::pid_t::from(pid), + ptr::null_mut::(), + options.bits() as *mut c_void) + }; + Errno::result(res).map(drop) +} + +/// Gets a ptrace event as described by `ptrace(PTRACE_GETEVENTMSG,...)` +pub fn getevent(pid: Pid) -> Result { + ptrace_get_data::(Request::PTRACE_GETEVENTMSG, pid) +} + +/// Get siginfo as with `ptrace(PTRACE_GETSIGINFO,...)` +pub fn getsiginfo(pid: Pid) -> Result { + ptrace_get_data::(Request::PTRACE_GETSIGINFO, pid) +} + +/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)` +pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> { + let ret = unsafe{ + Errno::clear(); + libc::ptrace(Request::PTRACE_SETSIGINFO as RequestType, + libc::pid_t::from(pid), + ptr::null_mut::(), + sig as *const _ as *const c_void) + }; + match Errno::result(ret) { + Ok(_) => Ok(()), + Err(e) => Err(e), + } +} + +/// Sets the process as traceable, as with `ptrace(PTRACE_TRACEME, ...)` +/// +/// Indicates that this process is to be traced by its parent. +/// This is the only ptrace request to be issued by the tracee. +pub fn traceme() -> Result<()> { + unsafe { + ptrace_other( + Request::PTRACE_TRACEME, + Pid::from_raw(0), + ptr::null_mut(), + ptr::null_mut(), + ).map(drop) // ignore the useless return value + } +} + +/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSCALL, ...)` +/// +/// Arranges for the tracee to be stopped at the next entry to or exit from a system call, +/// optionally delivering a signal specified by `sig`. +pub fn syscall>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as i32 as *mut c_void, + None => ptr::null_mut(), + }; + unsafe { + ptrace_other( + Request::PTRACE_SYSCALL, + pid, + ptr::null_mut(), + data, + ).map(drop) // ignore the useless return value + } +} + +/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSEMU, ...)` +/// +/// In contrast to the `syscall` function, the syscall stopped at will not be executed. +/// Thus the the tracee will only be stopped once per syscall, +/// optionally delivering a signal specified by `sig`. +#[cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86", target_arch = "x86_64")))] +pub fn sysemu>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as i32 as *mut c_void, + None => ptr::null_mut(), + }; + unsafe { + ptrace_other(Request::PTRACE_SYSEMU, pid, ptr::null_mut(), data).map(drop) + // ignore the useless return value + } +} + +/// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)` +/// +/// Attaches to the process specified by `pid`, making it a tracee of the calling process. +pub fn attach(pid: Pid) -> Result<()> { + unsafe { + ptrace_other( + Request::PTRACE_ATTACH, + pid, + ptr::null_mut(), + ptr::null_mut(), + ).map(drop) // ignore the useless return value + } +} + +/// Attach to a running process, as with `ptrace(PTRACE_SEIZE, ...)` +/// +/// Attaches to the process specified in pid, making it a tracee of the calling process. +#[cfg(target_os = "linux")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn seize(pid: Pid, options: Options) -> Result<()> { + unsafe { + ptrace_other( + Request::PTRACE_SEIZE, + pid, + ptr::null_mut(), + options.bits() as *mut c_void, + ).map(drop) // ignore the useless return value + } +} + +/// Detaches the current running process, as with `ptrace(PTRACE_DETACH, ...)` +/// +/// Detaches from the process specified by `pid` allowing it to run freely, optionally delivering a +/// signal specified by `sig`. +pub fn detach>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as i32 as *mut c_void, + None => ptr::null_mut(), + }; + unsafe { + ptrace_other( + Request::PTRACE_DETACH, + pid, + ptr::null_mut(), + data + ).map(drop) + } +} + +/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)` +/// +/// Continues the execution of the process with PID `pid`, optionally +/// delivering a signal specified by `sig`. +pub fn cont>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as i32 as *mut c_void, + None => ptr::null_mut(), + }; + unsafe { + ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop) // ignore the useless return value + } +} + +/// Stop a tracee, as with `ptrace(PTRACE_INTERRUPT, ...)` +/// +/// This request is equivalent to `ptrace(PTRACE_INTERRUPT, ...)` +#[cfg(target_os = "linux")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn interrupt(pid: Pid) -> Result<()> { + unsafe { + ptrace_other(Request::PTRACE_INTERRUPT, pid, ptr::null_mut(), ptr::null_mut()).map(drop) + } +} + +/// Issues a kill request as with `ptrace(PTRACE_KILL, ...)` +/// +/// This request is equivalent to `ptrace(PTRACE_CONT, ..., SIGKILL);` +pub fn kill(pid: Pid) -> Result<()> { + unsafe { + ptrace_other(Request::PTRACE_KILL, pid, ptr::null_mut(), ptr::null_mut()).map(drop) + } +} + +/// Move the stopped tracee process forward by a single step as with +/// `ptrace(PTRACE_SINGLESTEP, ...)` +/// +/// Advances the execution of the process with PID `pid` by a single step optionally delivering a +/// signal specified by `sig`. +/// +/// # Example +/// ```rust +/// use nix::sys::ptrace::step; +/// use nix::unistd::Pid; +/// use nix::sys::signal::Signal; +/// use nix::sys::wait::*; +/// +/// // If a process changes state to the stopped state because of a SIGUSR1 +/// // signal, this will step the process forward and forward the user +/// // signal to the stopped process +/// match waitpid(Pid::from_raw(-1), None) { +/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => { +/// let _ = step(pid, Signal::SIGUSR1); +/// } +/// _ => {}, +/// } +/// ``` +pub fn step>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as i32 as *mut c_void, + None => ptr::null_mut(), + }; + unsafe { + ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data).map(drop) + } +} + +/// Move the stopped tracee process forward by a single step or stop at the next syscall +/// as with `ptrace(PTRACE_SYSEMU_SINGLESTEP, ...)` +/// +/// Advances the execution by a single step or until the next syscall. +/// In case the tracee is stopped at a syscall, the syscall will not be executed. +/// Optionally, the signal specified by `sig` is delivered to the tracee upon continuation. +#[cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86", target_arch = "x86_64")))] +pub fn sysemu_step>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as i32 as *mut c_void, + None => ptr::null_mut(), + }; + unsafe { + ptrace_other( + Request::PTRACE_SYSEMU_SINGLESTEP, + pid, + ptr::null_mut(), + data, + ) + .map(drop) // ignore the useless return value + } +} + +/// Reads a word from a processes memory at the given address +pub fn read(pid: Pid, addr: AddressType) -> Result { + ptrace_peek(Request::PTRACE_PEEKDATA, pid, addr, ptr::null_mut()) +} + +/// Writes a word into the processes memory at the given address +/// +/// # Safety +/// +/// The `data` argument is passed directly to `ptrace(2)`. Read that man page +/// for guidance. +pub unsafe fn write( + pid: Pid, + addr: AddressType, + data: *mut c_void) -> Result<()> +{ + ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop) +} + +/// Reads a word from a user area at `offset`. +/// The user struct definition can be found in `/usr/include/sys/user.h`. +pub fn read_user(pid: Pid, offset: AddressType) -> Result { + ptrace_peek(Request::PTRACE_PEEKUSER, pid, offset, ptr::null_mut()) +} + +/// Writes a word to a user area at `offset`. +/// The user struct definition can be found in `/usr/include/sys/user.h`. +/// +/// # Safety +/// +/// The `data` argument is passed directly to `ptrace(2)`. Read that man page +/// for guidance. +pub unsafe fn write_user( + pid: Pid, + offset: AddressType, + data: *mut c_void) -> Result<()> +{ + ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/ptrace/mod.rs b/utshell-0.5.0/vendor/nix/src/sys/ptrace/mod.rs new file mode 100644 index 00000000..782c3040 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/ptrace/mod.rs @@ -0,0 +1,22 @@ +///! Provides helpers for making ptrace system calls + +#[cfg(any(target_os = "android", target_os = "linux"))] +mod linux; + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use self::linux::*; + +#[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] +mod bsd; + +#[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd" + ))] +pub use self::bsd::*; diff --git a/utshell-0.5.0/vendor/nix/src/sys/quota.rs b/utshell-0.5.0/vendor/nix/src/sys/quota.rs new file mode 100644 index 00000000..f3b4c02d --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/quota.rs @@ -0,0 +1,277 @@ +//! Set and configure disk quotas for users, groups, or projects. +//! +//! # Examples +//! +//! Enabling and setting a quota: +//! +//! ```rust,no_run +//! # use nix::sys::quota::{Dqblk, quotactl_on, quotactl_set, QuotaFmt, QuotaType, QuotaValidFlags}; +//! quotactl_on(QuotaType::USRQUOTA, "/dev/sda1", QuotaFmt::QFMT_VFS_V1, "aquota.user").unwrap(); +//! let mut dqblk: Dqblk = Default::default(); +//! dqblk.set_blocks_hard_limit(10000); +//! dqblk.set_blocks_soft_limit(8000); +//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS).unwrap(); +//! ``` +use std::default::Default; +use std::{mem, ptr}; +use libc::{self, c_int, c_char}; +use crate::{Result, NixPath}; +use crate::errno::Errno; + +struct QuotaCmd(QuotaSubCmd, QuotaType); + +impl QuotaCmd { + #[allow(unused_unsafe)] + fn as_int(&self) -> c_int { + unsafe { libc::QCMD(self.0 as i32, self.1 as i32) } + } +} + +// linux quota version >= 2 +libc_enum!{ + #[repr(i32)] + enum QuotaSubCmd { + Q_SYNC, + Q_QUOTAON, + Q_QUOTAOFF, + Q_GETQUOTA, + Q_SETQUOTA, + } +} + +libc_enum!{ + /// The scope of the quota. + #[repr(i32)] + #[non_exhaustive] + pub enum QuotaType { + /// Specify a user quota + USRQUOTA, + /// Specify a group quota + GRPQUOTA, + } +} + +libc_enum!{ + /// The type of quota format to use. + #[repr(i32)] + #[non_exhaustive] + pub enum QuotaFmt { + /// Use the original quota format. + QFMT_VFS_OLD, + /// Use the standard VFS v0 quota format. + /// + /// Handles 32-bit UIDs/GIDs and quota limits up to 232 bytes/232 inodes. + QFMT_VFS_V0, + /// Use the VFS v1 quota format. + /// + /// Handles 32-bit UIDs/GIDs and quota limits of 264 bytes/264 inodes. + QFMT_VFS_V1, + } +} + +libc_bitflags!( + /// Indicates the quota fields that are valid to read from. + #[derive(Default)] + pub struct QuotaValidFlags: u32 { + /// The block hard & soft limit fields. + QIF_BLIMITS; + /// The current space field. + QIF_SPACE; + /// The inode hard & soft limit fields. + QIF_ILIMITS; + /// The current inodes field. + QIF_INODES; + /// The disk use time limit field. + QIF_BTIME; + /// The file quote time limit field. + QIF_ITIME; + /// All block & inode limits. + QIF_LIMITS; + /// The space & inodes usage fields. + QIF_USAGE; + /// The time limit fields. + QIF_TIMES; + /// All fields. + QIF_ALL; + } +); + +/// Wrapper type for `if_dqblk` +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct Dqblk(libc::dqblk); + +impl Default for Dqblk { + fn default() -> Dqblk { + Dqblk(libc::dqblk { + dqb_bhardlimit: 0, + dqb_bsoftlimit: 0, + dqb_curspace: 0, + dqb_ihardlimit: 0, + dqb_isoftlimit: 0, + dqb_curinodes: 0, + dqb_btime: 0, + dqb_itime: 0, + dqb_valid: 0, + }) + } +} + +impl Dqblk { + /// The absolute limit on disk quota blocks allocated. + pub fn blocks_hard_limit(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) { + Some(self.0.dqb_bhardlimit) + } else { + None + } + } + + /// Set the absolute limit on disk quota blocks allocated. + pub fn set_blocks_hard_limit(&mut self, limit: u64) { + self.0.dqb_bhardlimit = limit; + } + + /// Preferred limit on disk quota blocks + pub fn blocks_soft_limit(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) { + Some(self.0.dqb_bsoftlimit) + } else { + None + } + } + + /// Set the preferred limit on disk quota blocks allocated. + pub fn set_blocks_soft_limit(&mut self, limit: u64) { + self.0.dqb_bsoftlimit = limit; + } + + /// Current occupied space (bytes). + pub fn occupied_space(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_SPACE) { + Some(self.0.dqb_curspace) + } else { + None + } + } + + /// Maximum number of allocated inodes. + pub fn inodes_hard_limit(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) { + Some(self.0.dqb_ihardlimit) + } else { + None + } + } + + /// Set the maximum number of allocated inodes. + pub fn set_inodes_hard_limit(&mut self, limit: u64) { + self.0.dqb_ihardlimit = limit; + } + + /// Preferred inode limit + pub fn inodes_soft_limit(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) { + Some(self.0.dqb_isoftlimit) + } else { + None + } + } + + /// Set the preferred limit of allocated inodes. + pub fn set_inodes_soft_limit(&mut self, limit: u64) { + self.0.dqb_isoftlimit = limit; + } + + /// Current number of allocated inodes. + pub fn allocated_inodes(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_INODES) { + Some(self.0.dqb_curinodes) + } else { + None + } + } + + /// Time limit for excessive disk use. + pub fn block_time_limit(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_BTIME) { + Some(self.0.dqb_btime) + } else { + None + } + } + + /// Set the time limit for excessive disk use. + pub fn set_block_time_limit(&mut self, limit: u64) { + self.0.dqb_btime = limit; + } + + /// Time limit for excessive files. + pub fn inode_time_limit(&self) -> Option { + let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_ITIME) { + Some(self.0.dqb_itime) + } else { + None + } + } + + /// Set the time limit for excessive files. + pub fn set_inode_time_limit(&mut self, limit: u64) { + self.0.dqb_itime = limit; + } +} + +fn quotactl(cmd: QuotaCmd, special: Option<&P>, id: c_int, addr: *mut c_char) -> Result<()> { + unsafe { + Errno::clear(); + let res = match special { + Some(dev) => dev.with_nix_path(|path| libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)), + None => Ok(libc::quotactl(cmd.as_int(), ptr::null(), id, addr)), + }?; + + Errno::result(res).map(drop) + } +} + +/// Turn on disk quotas for a block device. +pub fn quotactl_on(which: QuotaType, special: &P, format: QuotaFmt, quota_file: &P) -> Result<()> { + quota_file.with_nix_path(|path| { + let mut path_copy = path.to_bytes_with_nul().to_owned(); + let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char; + quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAON, which), Some(special), format as c_int, p) + })? +} + +/// Disable disk quotas for a block device. +pub fn quotactl_off(which: QuotaType, special: &P) -> Result<()> { + quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which), Some(special), 0, ptr::null_mut()) +} + +/// Update the on-disk copy of quota usages for a filesystem. +/// +/// If `special` is `None`, then all file systems with active quotas are sync'd. +pub fn quotactl_sync(which: QuotaType, special: Option<&P>) -> Result<()> { + quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut()) +} + +/// Get disk quota limits and current usage for the given user/group id. +pub fn quotactl_get(which: QuotaType, special: &P, id: c_int) -> Result { + let mut dqblk = mem::MaybeUninit::uninit(); + quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, dqblk.as_mut_ptr() as *mut c_char)?; + Ok(unsafe{ Dqblk(dqblk.assume_init())}) +} + +/// Configure quota values for the specified fields for a given user/group id. +pub fn quotactl_set(which: QuotaType, special: &P, id: c_int, dqblk: &Dqblk, fields: QuotaValidFlags) -> Result<()> { + let mut dqblk_copy = *dqblk; + dqblk_copy.0.dqb_valid = fields.bits(); + quotactl(QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which), Some(special), id, &mut dqblk_copy as *mut _ as *mut c_char) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/reboot.rs b/utshell-0.5.0/vendor/nix/src/sys/reboot.rs new file mode 100644 index 00000000..2a8009e4 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/reboot.rs @@ -0,0 +1,52 @@ +//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete. + +use crate::Result; +use crate::errno::Errno; +use std::convert::Infallible; +use std::mem::drop; + +libc_enum! { + /// How exactly should the system be rebooted. + /// + /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for + /// enabling/disabling Ctrl-Alt-Delete. + #[repr(i32)] + #[non_exhaustive] + pub enum RebootMode { + /// Halt the system. + RB_HALT_SYSTEM, + /// Execute a kernel that has been loaded earlier with + /// [`kexec_load(2)`](https://man7.org/linux/man-pages/man2/kexec_load.2.html). + RB_KEXEC, + /// Stop the system and switch off power, if possible. + RB_POWER_OFF, + /// Restart the system. + RB_AUTOBOOT, + // we do not support Restart2. + /// Suspend the system using software suspend. + RB_SW_SUSPEND, + } +} + +/// Reboots or shuts down the system. +pub fn reboot(how: RebootMode) -> Result { + unsafe { + libc::reboot(how as libc::c_int) + }; + Err(Errno::last()) +} + +/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete). +/// +/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C. +pub fn set_cad_enabled(enable: bool) -> Result<()> { + let cmd = if enable { + libc::RB_ENABLE_CAD + } else { + libc::RB_DISABLE_CAD + }; + let res = unsafe { + libc::reboot(cmd) + }; + Errno::result(res).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/resource.rs b/utshell-0.5.0/vendor/nix/src/sys/resource.rs new file mode 100644 index 00000000..e9a11d95 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/resource.rs @@ -0,0 +1,437 @@ +//! Configure the process resource limits. +use cfg_if::cfg_if; +use libc::{c_int, c_long, rusage}; + +use crate::errno::Errno; +use crate::sys::time::TimeVal; +use crate::Result; +pub use libc::rlim_t; +use std::mem; + +cfg_if! { + if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{ + use libc::{__rlimit_resource_t, rlimit}; + } else if #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "dragonfly", + all(target_os = "linux", not(target_env = "gnu")) + ))]{ + use libc::rlimit; + } +} + +libc_enum! { + /// Types of process resources. + /// + /// The Resource enum is platform dependent. Check different platform + /// manuals for more details. Some platform links have been provided for + /// easier reference (non-exhaustive). + /// + /// * [Linux](https://man7.org/linux/man-pages/man2/getrlimit.2.html) + /// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=setrlimit) + /// * [NetBSD](https://man.netbsd.org/setrlimit.2) + + // linux-gnu uses u_int as resource enum, which is implemented in libc as + // well. + // + // https://gcc.gnu.org/legacy-ml/gcc/2015-08/msg00441.html + // https://github.com/rust-lang/libc/blob/master/src/unix/linux_like/linux/gnu/mod.rs + #[cfg_attr(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")), repr(u32))] + #[cfg_attr(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "dragonfly", + all(target_os = "linux", not(any(target_env = "gnu", target_env = "uclibc"))) + ), repr(i32))] + #[non_exhaustive] + pub enum Resource { + #[cfg(not(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum amount (in bytes) of virtual memory the process is + /// allowed to map. + RLIMIT_AS, + /// The largest size (in bytes) core(5) file that may be created. + RLIMIT_CORE, + /// The maximum amount of cpu time (in seconds) to be used by each + /// process. + RLIMIT_CPU, + /// The maximum size (in bytes) of the data segment for a process + RLIMIT_DATA, + /// The largest size (in bytes) file that may be created. + RLIMIT_FSIZE, + /// The maximum number of open files for this process. + RLIMIT_NOFILE, + /// The maximum size (in bytes) of the stack segment for a process. + RLIMIT_STACK, + + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum number of kqueues this user id is allowed to create. + RLIMIT_KQUEUES, + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// A limit on the combined number of flock locks and fcntl leases that + /// this process may establish. + RLIMIT_LOCKS, + + #[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + target_os = "linux", + target_os = "netbsd" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum size (in bytes) which a process may lock into memory + /// using the mlock(2) system call. + RLIMIT_MEMLOCK, + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// A limit on the number of bytes that can be allocated for POSIX + /// message queues for the real user ID of the calling process. + RLIMIT_MSGQUEUE, + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// A ceiling to which the process's nice value can be raised using + /// setpriority or nice. + RLIMIT_NICE, + + #[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "linux", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum number of simultaneous processes for this user id. + RLIMIT_NPROC, + + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum number of pseudo-terminals this user id is allowed to + /// create. + RLIMIT_NPTS, + + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "linux", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// When there is memory pressure and swap is available, prioritize + /// eviction of a process' resident pages beyond this amount (in bytes). + RLIMIT_RSS, + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// A ceiling on the real-time priority that may be set for this process + /// using sched_setscheduler and sched_set†param. + RLIMIT_RTPRIO, + + #[cfg(any(target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// A limit (in microseconds) on the amount of CPU time that a process + /// scheduled under a real-time scheduling policy may con†sume without + /// making a blocking system call. + RLIMIT_RTTIME, + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// A limit on the number of signals that may be queued for the real + /// user ID of the calling process. + RLIMIT_SIGPENDING, + + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum size (in bytes) of socket buffer usage for this user. + RLIMIT_SBSIZE, + + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum size (in bytes) of the swap space that may be reserved + /// or used by all of this user id's processes. + RLIMIT_SWAP, + + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// An alias for RLIMIT_AS. + RLIMIT_VMEM, + } +} + +/// Get the current processes resource limits +/// +/// The special value `RLIM_INFINITY` indicates that no limit will be +/// enforced. +/// +/// # Parameters +/// +/// * `resource`: The [`Resource`] that we want to get the limits of. +/// +/// # Examples +/// +/// ``` +/// # use nix::sys::resource::{getrlimit, Resource}; +/// +/// let (soft_limit, hard_limit) = getrlimit(Resource::RLIMIT_NOFILE).unwrap(); +/// println!("current soft_limit: {}", soft_limit); +/// println!("current hard_limit: {}", hard_limit); +/// ``` +/// +/// # References +/// +/// [getrlimit(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html#tag_16_215) +/// +/// [`Resource`]: enum.Resource.html +pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> { + let mut old_rlim = mem::MaybeUninit::::uninit(); + + cfg_if! { + if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{ + let res = unsafe { libc::getrlimit(resource as __rlimit_resource_t, old_rlim.as_mut_ptr()) }; + } else { + let res = unsafe { libc::getrlimit(resource as c_int, old_rlim.as_mut_ptr()) }; + } + } + + Errno::result(res).map(|_| { + let rlimit { rlim_cur, rlim_max } = unsafe { old_rlim.assume_init() }; + (rlim_cur, rlim_max) + }) +} + +/// Set the current processes resource limits +/// +/// # Parameters +/// +/// * `resource`: The [`Resource`] that we want to set the limits of. +/// * `soft_limit`: The value that the kernel enforces for the corresponding +/// resource. +/// * `hard_limit`: The ceiling for the soft limit. Must be lower or equal to +/// the current hard limit for non-root users. +/// +/// The special value `RLIM_INFINITY` indicates that no limit will be +/// enforced. +/// +/// # Examples +/// +/// ``` +/// # use nix::sys::resource::{setrlimit, Resource}; +/// +/// let soft_limit = 512; +/// let hard_limit = 1024; +/// setrlimit(Resource::RLIMIT_NOFILE, soft_limit, hard_limit).unwrap(); +/// ``` +/// +/// # References +/// +/// [setrlimit(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html#tag_16_215) +/// +/// [`Resource`]: enum.Resource.html +/// +/// Note: `setrlimit` provides a safe wrapper to libc's `setrlimit`. +pub fn setrlimit(resource: Resource, soft_limit: rlim_t, hard_limit: rlim_t) -> Result<()> { + let new_rlim = rlimit { + rlim_cur: soft_limit, + rlim_max: hard_limit, + }; + cfg_if! { + if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{ + let res = unsafe { libc::setrlimit(resource as __rlimit_resource_t, &new_rlim as *const rlimit) }; + }else{ + let res = unsafe { libc::setrlimit(resource as c_int, &new_rlim as *const rlimit) }; + } + } + + Errno::result(res).map(drop) +} + +libc_enum! { + /// Whose resource usage should be returned by [`getrusage`]. + #[repr(i32)] + #[non_exhaustive] + pub enum UsageWho { + /// Resource usage for the current process. + RUSAGE_SELF, + + /// Resource usage for all the children that have terminated and been waited for. + RUSAGE_CHILDREN, + + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Resource usage for the calling thread. + RUSAGE_THREAD, + } +} + +/// Output of `getrusage` with information about resource usage. Some of the fields +/// may be unused in some platforms, and will be always zeroed out. See their manuals +/// for details. +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct Usage(rusage); + +impl AsRef for Usage { + fn as_ref(&self) -> &rusage { + &self.0 + } +} + +impl AsMut for Usage { + fn as_mut(&mut self) -> &mut rusage { + &mut self.0 + } +} + +impl Usage { + /// Total amount of time spent executing in user mode. + pub fn user_time(&self) -> TimeVal { + TimeVal::from(self.0.ru_utime) + } + + /// Total amount of time spent executing in kernel mode. + pub fn system_time(&self) -> TimeVal { + TimeVal::from(self.0.ru_stime) + } + + /// The resident set size at its peak, in kilobytes. + pub fn max_rss(&self) -> c_long { + self.0.ru_maxrss + } + + /// Integral value expressed in kilobytes times ticks of execution indicating + /// the amount of text memory shared with other processes. + pub fn shared_integral(&self) -> c_long { + self.0.ru_ixrss + } + + /// Integral value expressed in kilobytes times ticks of execution indicating + /// the amount of unshared memory used by data. + pub fn unshared_data_integral(&self) -> c_long { + self.0.ru_idrss + } + + /// Integral value expressed in kilobytes times ticks of execution indicating + /// the amount of unshared memory used for stack space. + pub fn unshared_stack_integral(&self) -> c_long { + self.0.ru_isrss + } + + /// Number of page faults that were served without resorting to I/O, with pages + /// that have been allocated previously by the kernel. + pub fn minor_page_faults(&self) -> c_long { + self.0.ru_minflt + } + + /// Number of page faults that were served through I/O (i.e. swap). + pub fn major_page_faults(&self) -> c_long { + self.0.ru_majflt + } + + /// Number of times all of the memory was fully swapped out. + pub fn full_swaps(&self) -> c_long { + self.0.ru_nswap + } + + /// Number of times a read was done from a block device. + pub fn block_reads(&self) -> c_long { + self.0.ru_inblock + } + + /// Number of times a write was done to a block device. + pub fn block_writes(&self) -> c_long { + self.0.ru_oublock + } + + /// Number of IPC messages sent. + pub fn ipc_sends(&self) -> c_long { + self.0.ru_msgsnd + } + + /// Number of IPC messages received. + pub fn ipc_receives(&self) -> c_long { + self.0.ru_msgrcv + } + + /// Number of signals received. + pub fn signals(&self) -> c_long { + self.0.ru_nsignals + } + + /// Number of times a context switch was voluntarily invoked. + pub fn voluntary_context_switches(&self) -> c_long { + self.0.ru_nvcsw + } + + /// Number of times a context switch was imposed by the kernel (usually due to + /// time slice expiring or preemption by a higher priority process). + pub fn involuntary_context_switches(&self) -> c_long { + self.0.ru_nivcsw + } +} + +/// Get usage information for a process, its children or the current thread +/// +/// Real time information can be obtained for either the current process or (in some +/// systems) thread, but information about children processes is only provided for +/// those that have terminated and been waited for (see [`super::wait::wait`]). +/// +/// Some information may be missing depending on the platform, and the way information +/// is provided for children may also vary. Check the manuals for details. +/// +/// # References +/// +/// * [getrusage(2)](https://pubs.opengroup.org/onlinepubs/009696699/functions/getrusage.html) +/// * [Linux](https://man7.org/linux/man-pages/man2/getrusage.2.html) +/// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=getrusage) +/// * [NetBSD](https://man.netbsd.org/getrusage.2) +/// * [MacOS](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getrusage.2.html) +/// +/// [`UsageWho`]: enum.UsageWho.html +/// +/// Note: `getrusage` provides a safe wrapper to libc's [`libc::getrusage`]. +pub fn getrusage(who: UsageWho) -> Result { + unsafe { + let mut rusage = mem::MaybeUninit::::uninit(); + let res = libc::getrusage(who as c_int, rusage.as_mut_ptr()); + Errno::result(res).map(|_| Usage(rusage.assume_init())) + } +} + +#[cfg(test)] +mod test { + use super::{getrusage, UsageWho}; + + #[test] + pub fn test_self_cpu_time() { + // Make sure some CPU time is used. + let mut numbers: Vec = (1..1_000_000).collect(); + numbers.iter_mut().for_each(|item| *item *= 2); + + // FIXME: this is here to help ensure the compiler does not optimize the whole + // thing away. Replace the assert with test::black_box once stabilized. + assert_eq!(numbers[100..200].iter().sum::(), 30_100); + + let usage = getrusage(UsageWho::RUSAGE_SELF).expect("Failed to call getrusage for SELF"); + let rusage = usage.as_ref(); + + let user = usage.user_time(); + assert!(user.tv_sec() > 0 || user.tv_usec() > 0); + assert_eq!(user.tv_sec(), rusage.ru_utime.tv_sec); + assert_eq!(user.tv_usec(), rusage.ru_utime.tv_usec); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/select.rs b/utshell-0.5.0/vendor/nix/src/sys/select.rs new file mode 100644 index 00000000..ab4f68f5 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/select.rs @@ -0,0 +1,434 @@ +//! Portably monitor a group of file descriptors for readiness. +use std::convert::TryFrom; +use std::iter::FusedIterator; +use std::mem; +use std::ops::Range; +use std::os::unix::io::RawFd; +use std::ptr::{null, null_mut}; +use libc::{self, c_int}; +use crate::Result; +use crate::errno::Errno; +use crate::sys::time::{TimeSpec, TimeVal}; + +pub use libc::FD_SETSIZE; + +/// Contains a set of file descriptors used by [`select`] +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct FdSet(libc::fd_set); + +fn assert_fd_valid(fd: RawFd) { + assert!( + usize::try_from(fd).map_or(false, |fd| fd < FD_SETSIZE), + "fd must be in the range 0..FD_SETSIZE", + ); +} + +impl FdSet { + /// Create an empty `FdSet` + pub fn new() -> FdSet { + let mut fdset = mem::MaybeUninit::uninit(); + unsafe { + libc::FD_ZERO(fdset.as_mut_ptr()); + FdSet(fdset.assume_init()) + } + } + + /// Add a file descriptor to an `FdSet` + pub fn insert(&mut self, fd: RawFd) { + assert_fd_valid(fd); + unsafe { libc::FD_SET(fd, &mut self.0) }; + } + + /// Remove a file descriptor from an `FdSet` + pub fn remove(&mut self, fd: RawFd) { + assert_fd_valid(fd); + unsafe { libc::FD_CLR(fd, &mut self.0) }; + } + + /// Test an `FdSet` for the presence of a certain file descriptor. + pub fn contains(&self, fd: RawFd) -> bool { + assert_fd_valid(fd); + unsafe { libc::FD_ISSET(fd, &self.0) } + } + + /// Remove all file descriptors from this `FdSet`. + pub fn clear(&mut self) { + unsafe { libc::FD_ZERO(&mut self.0) }; + } + + /// Finds the highest file descriptor in the set. + /// + /// Returns `None` if the set is empty. + /// + /// This can be used to calculate the `nfds` parameter of the [`select`] function. + /// + /// # Example + /// + /// ``` + /// # use nix::sys::select::FdSet; + /// let mut set = FdSet::new(); + /// set.insert(4); + /// set.insert(9); + /// assert_eq!(set.highest(), Some(9)); + /// ``` + /// + /// [`select`]: fn.select.html + pub fn highest(&self) -> Option { + self.fds(None).next_back() + } + + /// Returns an iterator over the file descriptors in the set. + /// + /// For performance, it takes an optional higher bound: the iterator will + /// not return any elements of the set greater than the given file + /// descriptor. + /// + /// # Examples + /// + /// ``` + /// # use nix::sys::select::FdSet; + /// # use std::os::unix::io::RawFd; + /// let mut set = FdSet::new(); + /// set.insert(4); + /// set.insert(9); + /// let fds: Vec = set.fds(None).collect(); + /// assert_eq!(fds, vec![4, 9]); + /// ``` + #[inline] + pub fn fds(&self, highest: Option) -> Fds { + Fds { + set: self, + range: 0..highest.map(|h| h as usize + 1).unwrap_or(FD_SETSIZE), + } + } +} + +impl Default for FdSet { + fn default() -> Self { + Self::new() + } +} + +/// Iterator over `FdSet`. +#[derive(Debug)] +pub struct Fds<'a> { + set: &'a FdSet, + range: Range, +} + +impl<'a> Iterator for Fds<'a> { + type Item = RawFd; + + fn next(&mut self) -> Option { + for i in &mut self.range { + if self.set.contains(i as RawFd) { + return Some(i as RawFd); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.range.size_hint(); + (0, upper) + } +} + +impl<'a> DoubleEndedIterator for Fds<'a> { + #[inline] + fn next_back(&mut self) -> Option { + while let Some(i) = self.range.next_back() { + if self.set.contains(i as RawFd) { + return Some(i as RawFd); + } + } + None + } +} + +impl<'a> FusedIterator for Fds<'a> {} + +/// Monitors file descriptors for readiness +/// +/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all +/// file descriptors that are ready for the given operation are set. +/// +/// When this function returns, `timeout` has an implementation-defined value. +/// +/// # Parameters +/// +/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this +/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1 +/// to the maximum of that. +/// * `readfds`: File descriptors to check for being ready to read. +/// * `writefds`: File descriptors to check for being ready to write. +/// * `errorfds`: File descriptors to check for pending error conditions. +/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block +/// indefinitely). +/// +/// # References +/// +/// [select(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html) +/// +/// [`FdSet::highest`]: struct.FdSet.html#method.highest +pub fn select<'a, N, R, W, E, T>(nfds: N, + readfds: R, + writefds: W, + errorfds: E, + timeout: T) -> Result +where + N: Into>, + R: Into>, + W: Into>, + E: Into>, + T: Into>, +{ + let mut readfds = readfds.into(); + let mut writefds = writefds.into(); + let mut errorfds = errorfds.into(); + let timeout = timeout.into(); + + let nfds = nfds.into().unwrap_or_else(|| { + readfds.iter_mut() + .chain(writefds.iter_mut()) + .chain(errorfds.iter_mut()) + .map(|set| set.highest().unwrap_or(-1)) + .max() + .unwrap_or(-1) + 1 + }); + + let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval) + .unwrap_or(null_mut()); + + let res = unsafe { + libc::select(nfds, readfds, writefds, errorfds, timeout) + }; + + Errno::result(res) +} + +feature! { +#![feature = "signal"] + +use crate::sys::signal::SigSet; + +/// Monitors file descriptors for readiness with an altered signal mask. +/// +/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all +/// file descriptors that are ready for the given operation are set. +/// +/// When this function returns, the original signal mask is restored. +/// +/// Unlike [`select`](#fn.select), `pselect` does not mutate the `timeout` value. +/// +/// # Parameters +/// +/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this +/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1 +/// to the maximum of that. +/// * `readfds`: File descriptors to check for read readiness +/// * `writefds`: File descriptors to check for write readiness +/// * `errorfds`: File descriptors to check for pending error conditions. +/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block +/// indefinitely). +/// * `sigmask`: Signal mask to activate while waiting for file descriptors to turn +/// ready (`None` to set no alternative signal mask). +/// +/// # References +/// +/// [pselect(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html) +/// +/// [The new pselect() system call](https://lwn.net/Articles/176911/) +/// +/// [`FdSet::highest`]: struct.FdSet.html#method.highest +pub fn pselect<'a, N, R, W, E, T, S>(nfds: N, + readfds: R, + writefds: W, + errorfds: E, + timeout: T, + sigmask: S) -> Result +where + N: Into>, + R: Into>, + W: Into>, + E: Into>, + T: Into>, + S: Into>, +{ + let mut readfds = readfds.into(); + let mut writefds = writefds.into(); + let mut errorfds = errorfds.into(); + let sigmask = sigmask.into(); + let timeout = timeout.into(); + + let nfds = nfds.into().unwrap_or_else(|| { + readfds.iter_mut() + .chain(writefds.iter_mut()) + .chain(errorfds.iter_mut()) + .map(|set| set.highest().unwrap_or(-1)) + .max() + .unwrap_or(-1) + 1 + }); + + let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let timeout = timeout.map(|ts| ts.as_ref() as *const libc::timespec).unwrap_or(null()); + let sigmask = sigmask.map(|sm| sm.as_ref() as *const libc::sigset_t).unwrap_or(null()); + + let res = unsafe { + libc::pselect(nfds, readfds, writefds, errorfds, timeout, sigmask) + }; + + Errno::result(res) +} +} + +#[cfg(test)] +mod tests { + use super::*; + use std::os::unix::io::RawFd; + use crate::sys::time::{TimeVal, TimeValLike}; + use crate::unistd::{write, pipe}; + + #[test] + fn fdset_insert() { + let mut fd_set = FdSet::new(); + + for i in 0..FD_SETSIZE { + assert!(!fd_set.contains(i as RawFd)); + } + + fd_set.insert(7); + + assert!(fd_set.contains(7)); + } + + #[test] + fn fdset_remove() { + let mut fd_set = FdSet::new(); + + for i in 0..FD_SETSIZE { + assert!(!fd_set.contains(i as RawFd)); + } + + fd_set.insert(7); + fd_set.remove(7); + + for i in 0..FD_SETSIZE { + assert!(!fd_set.contains(i as RawFd)); + } + } + + #[test] + fn fdset_clear() { + let mut fd_set = FdSet::new(); + fd_set.insert(1); + fd_set.insert((FD_SETSIZE / 2) as RawFd); + fd_set.insert((FD_SETSIZE - 1) as RawFd); + + fd_set.clear(); + + for i in 0..FD_SETSIZE { + assert!(!fd_set.contains(i as RawFd)); + } + } + + #[test] + fn fdset_highest() { + let mut set = FdSet::new(); + assert_eq!(set.highest(), None); + set.insert(0); + assert_eq!(set.highest(), Some(0)); + set.insert(90); + assert_eq!(set.highest(), Some(90)); + set.remove(0); + assert_eq!(set.highest(), Some(90)); + set.remove(90); + assert_eq!(set.highest(), None); + + set.insert(4); + set.insert(5); + set.insert(7); + assert_eq!(set.highest(), Some(7)); + } + + #[test] + fn fdset_fds() { + let mut set = FdSet::new(); + assert_eq!(set.fds(None).collect::>(), vec![]); + set.insert(0); + assert_eq!(set.fds(None).collect::>(), vec![0]); + set.insert(90); + assert_eq!(set.fds(None).collect::>(), vec![0, 90]); + + // highest limit + assert_eq!(set.fds(Some(89)).collect::>(), vec![0]); + assert_eq!(set.fds(Some(90)).collect::>(), vec![0, 90]); + } + + #[test] + fn test_select() { + let (r1, w1) = pipe().unwrap(); + write(w1, b"hi!").unwrap(); + let (r2, _w2) = pipe().unwrap(); + + let mut fd_set = FdSet::new(); + fd_set.insert(r1); + fd_set.insert(r2); + + let mut timeout = TimeVal::seconds(10); + assert_eq!(1, select(None, + &mut fd_set, + None, + None, + &mut timeout).unwrap()); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } + + #[test] + fn test_select_nfds() { + let (r1, w1) = pipe().unwrap(); + write(w1, b"hi!").unwrap(); + let (r2, _w2) = pipe().unwrap(); + + let mut fd_set = FdSet::new(); + fd_set.insert(r1); + fd_set.insert(r2); + + let mut timeout = TimeVal::seconds(10); + assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1), + &mut fd_set, + None, + None, + &mut timeout).unwrap()); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } + + #[test] + fn test_select_nfds2() { + let (r1, w1) = pipe().unwrap(); + write(w1, b"hi!").unwrap(); + let (r2, _w2) = pipe().unwrap(); + + let mut fd_set = FdSet::new(); + fd_set.insert(r1); + fd_set.insert(r2); + + let mut timeout = TimeVal::seconds(10); + assert_eq!(1, select(::std::cmp::max(r1, r2) + 1, + &mut fd_set, + None, + None, + &mut timeout).unwrap()); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/sendfile.rs b/utshell-0.5.0/vendor/nix/src/sys/sendfile.rs new file mode 100644 index 00000000..2ebcdf48 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/sendfile.rs @@ -0,0 +1,277 @@ +//! Send data from a file to a socket, bypassing userland. + +use cfg_if::cfg_if; +use std::os::unix::io::RawFd; +use std::ptr; + +use libc::{self, off_t}; + +use crate::Result; +use crate::errno::Errno; + +/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`. +/// +/// Returns a `Result` with the number of bytes written. +/// +/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will +/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified +/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to +/// the byte after the last byte copied. +/// +/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket. +/// +/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html) +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn sendfile( + out_fd: RawFd, + in_fd: RawFd, + offset: Option<&mut off_t>, + count: usize, +) -> Result { + let offset = offset + .map(|offset| offset as *mut _) + .unwrap_or(ptr::null_mut()); + let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) }; + Errno::result(ret).map(|r| r as usize) +} + +/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`. +/// +/// Returns a `Result` with the number of bytes written. +/// +/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will +/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified +/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to +/// the byte after the last byte copied. +/// +/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket. +/// +/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html) +#[cfg(target_os = "linux")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn sendfile64( + out_fd: RawFd, + in_fd: RawFd, + offset: Option<&mut libc::off64_t>, + count: usize, +) -> Result { + let offset = offset + .map(|offset| offset as *mut _) + .unwrap_or(ptr::null_mut()); + let ret = unsafe { libc::sendfile64(out_fd, in_fd, offset, count) }; + Errno::result(ret).map(|r| r as usize) +} + +cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos"))] { + use std::io::IoSlice; + + #[derive(Clone, Debug)] + struct SendfileHeaderTrailer<'a>( + libc::sf_hdtr, + Option>>, + Option>>, + ); + + impl<'a> SendfileHeaderTrailer<'a> { + fn new( + headers: Option<&'a [&'a [u8]]>, + trailers: Option<&'a [&'a [u8]]> + ) -> SendfileHeaderTrailer<'a> { + let header_iovecs: Option>> = + headers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect()); + let trailer_iovecs: Option>> = + trailers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect()); + SendfileHeaderTrailer( + libc::sf_hdtr { + headers: { + header_iovecs + .as_ref() + .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec + }, + hdr_cnt: header_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32, + trailers: { + trailer_iovecs + .as_ref() + .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec + }, + trl_cnt: trailer_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32 + }, + header_iovecs, + trailer_iovecs, + ) + } + } + } +} + +cfg_if! { + if #[cfg(target_os = "freebsd")] { + use libc::c_int; + + libc_bitflags!{ + /// Configuration options for [`sendfile`.](fn.sendfile.html) + pub struct SfFlags: c_int { + /// Causes `sendfile` to return EBUSY instead of blocking when attempting to read a + /// busy page. + SF_NODISKIO; + /// Causes `sendfile` to sleep until the network stack releases its reference to the + /// VM pages read. When `sendfile` returns, the data is not guaranteed to have been + /// sent, but it is safe to modify the file. + SF_SYNC; + /// Causes `sendfile` to cache exactly the number of pages specified in the + /// `readahead` parameter, disabling caching heuristics. + SF_USER_READAHEAD; + /// Causes `sendfile` not to cache the data read. + SF_NOCACHE; + } + } + + /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`. + /// + /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if + /// an error occurs. + /// + /// `in_fd` must describe a regular file or shared memory object. `out_sock` must describe a + /// stream socket. + /// + /// If `offset` falls past the end of the file, the function returns success and zero bytes + /// written. + /// + /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of + /// file (EOF). + /// + /// `headers` and `trailers` specify optional slices of byte slices to be sent before and + /// after the data read from `in_fd`, respectively. The length of headers and trailers sent + /// is included in the returned count of bytes written. The values of `offset` and `count` + /// do not apply to headers or trailers. + /// + /// `readahead` specifies the minimum number of pages to cache in memory ahead of the page + /// currently being sent. + /// + /// For more information, see + /// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2) + #[allow(clippy::too_many_arguments)] + pub fn sendfile( + in_fd: RawFd, + out_sock: RawFd, + offset: off_t, + count: Option, + headers: Option<&[&[u8]]>, + trailers: Option<&[&[u8]]>, + flags: SfFlags, + readahead: u16 + ) -> (Result<()>, off_t) { + // Readahead goes in upper 16 bits + // Flags goes in lower 16 bits + // see `man 2 sendfile` + let ra32 = u32::from(readahead); + let flags: u32 = (ra32 << 16) | (flags.bits() as u32); + let mut bytes_sent: off_t = 0; + let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); + let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); + let return_code = unsafe { + libc::sendfile(in_fd, + out_sock, + offset, + count.unwrap_or(0), + hdtr_ptr as *mut libc::sf_hdtr, + &mut bytes_sent as *mut off_t, + flags as c_int) + }; + (Errno::result(return_code).and(Ok(())), bytes_sent) + } + } else if #[cfg(target_os = "dragonfly")] { + /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`. + /// + /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if + /// an error occurs. + /// + /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket. + /// + /// If `offset` falls past the end of the file, the function returns success and zero bytes + /// written. + /// + /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of + /// file (EOF). + /// + /// `headers` and `trailers` specify optional slices of byte slices to be sent before and + /// after the data read from `in_fd`, respectively. The length of headers and trailers sent + /// is included in the returned count of bytes written. The values of `offset` and `count` + /// do not apply to headers or trailers. + /// + /// For more information, see + /// [the sendfile(2) man page.](https://leaf.dragonflybsd.org/cgi/web-man?command=sendfile§ion=2) + pub fn sendfile( + in_fd: RawFd, + out_sock: RawFd, + offset: off_t, + count: Option, + headers: Option<&[&[u8]]>, + trailers: Option<&[&[u8]]>, + ) -> (Result<()>, off_t) { + let mut bytes_sent: off_t = 0; + let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); + let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); + let return_code = unsafe { + libc::sendfile(in_fd, + out_sock, + offset, + count.unwrap_or(0), + hdtr_ptr as *mut libc::sf_hdtr, + &mut bytes_sent as *mut off_t, + 0) + }; + (Errno::result(return_code).and(Ok(())), bytes_sent) + } + } else if #[cfg(any(target_os = "ios", target_os = "macos"))] { + /// Read bytes from `in_fd` starting at `offset` and write up to `count` bytes to + /// `out_sock`. + /// + /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if + /// an error occurs. + /// + /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket. + /// + /// If `offset` falls past the end of the file, the function returns success and zero bytes + /// written. + /// + /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of + /// file (EOF). + /// + /// `hdtr` specifies an optional list of headers and trailers to be sent before and after + /// the data read from `in_fd`, respectively. The length of headers and trailers sent is + /// included in the returned count of bytes written. If any headers are specified and + /// `count` is non-zero, the length of the headers will be counted in the limit of total + /// bytes sent. Trailers do not count toward the limit of bytes sent and will always be sent + /// regardless. The value of `offset` does not affect headers or trailers. + /// + /// For more information, see + /// [the sendfile(2) man page.](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html) + pub fn sendfile( + in_fd: RawFd, + out_sock: RawFd, + offset: off_t, + count: Option, + headers: Option<&[&[u8]]>, + trailers: Option<&[&[u8]]> + ) -> (Result<()>, off_t) { + let mut len = count.unwrap_or(0); + let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); + let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); + let return_code = unsafe { + libc::sendfile(in_fd, + out_sock, + offset, + &mut len as *mut off_t, + hdtr_ptr as *mut libc::sf_hdtr, + 0) + }; + (Errno::result(return_code).and(Ok(())), len) + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/signal.rs b/utshell-0.5.0/vendor/nix/src/sys/signal.rs new file mode 100644 index 00000000..0da9c74a --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/signal.rs @@ -0,0 +1,1347 @@ +// Portions of this file are Copyright 2014 The Rust Project Developers. +// See https://www.rust-lang.org/policies/licenses. + +//! Operating system signals. + +use crate::errno::Errno; +use crate::{Error, Result}; +use cfg_if::cfg_if; +use std::fmt; +use std::mem; +#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] +use std::os::unix::io::RawFd; +use std::ptr; +use std::str::FromStr; + +#[cfg(not(any(target_os = "openbsd", target_os = "redox")))] +#[cfg(any(feature = "aio", feature = "signal"))] +pub use self::sigevent::*; + +#[cfg(any(feature = "aio", feature = "process", feature = "signal"))] +libc_enum! { + /// Types of operating system signals + // Currently there is only one definition of c_int in libc, as well as only one + // type for signal constants. + // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately + // this is not (yet) possible. + #[repr(i32)] + #[non_exhaustive] + #[cfg_attr(docsrs, doc(cfg(any(feature = "aio", feature = "signal"))))] + pub enum Signal { + /// Hangup + SIGHUP, + /// Interrupt + SIGINT, + /// Quit + SIGQUIT, + /// Illegal instruction (not reset when caught) + SIGILL, + /// Trace trap (not reset when caught) + SIGTRAP, + /// Abort + SIGABRT, + /// Bus error + SIGBUS, + /// Floating point exception + SIGFPE, + /// Kill (cannot be caught or ignored) + SIGKILL, + /// User defined signal 1 + SIGUSR1, + /// Segmentation violation + SIGSEGV, + /// User defined signal 2 + SIGUSR2, + /// Write on a pipe with no one to read it + SIGPIPE, + /// Alarm clock + SIGALRM, + /// Software termination signal from kill + SIGTERM, + /// Stack fault (obsolete) + #[cfg(all(any(target_os = "android", target_os = "emscripten", + target_os = "fuchsia", target_os = "linux"), + not(any(target_arch = "mips", target_arch = "mips64", + target_arch = "sparc64"))))] + SIGSTKFLT, + /// To parent on child stop or exit + SIGCHLD, + /// Continue a stopped process + SIGCONT, + /// Sendable stop signal not from tty + SIGSTOP, + /// Stop signal from tty + SIGTSTP, + /// To readers pgrp upon background tty read + SIGTTIN, + /// Like TTIN if (tp->t_local<OSTOP) + SIGTTOU, + /// Urgent condition on IO channel + SIGURG, + /// Exceeded CPU time limit + SIGXCPU, + /// Exceeded file size limit + SIGXFSZ, + /// Virtual time alarm + SIGVTALRM, + /// Profiling time alarm + SIGPROF, + /// Window size changes + SIGWINCH, + /// Input/output possible signal + #[cfg(not(target_os = "haiku"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SIGIO, + #[cfg(any(target_os = "android", target_os = "emscripten", + target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Power failure imminent. + SIGPWR, + /// Bad system call + SIGSYS, + #[cfg(not(any(target_os = "android", target_os = "emscripten", + target_os = "fuchsia", target_os = "linux", + target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Emulator trap + SIGEMT, + #[cfg(not(any(target_os = "android", target_os = "emscripten", + target_os = "fuchsia", target_os = "linux", + target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Information request + SIGINFO, + } + impl TryFrom +} + +#[cfg(feature = "signal")] +impl FromStr for Signal { + type Err = Error; + fn from_str(s: &str) -> Result { + Ok(match s { + "SIGHUP" => Signal::SIGHUP, + "SIGINT" => Signal::SIGINT, + "SIGQUIT" => Signal::SIGQUIT, + "SIGILL" => Signal::SIGILL, + "SIGTRAP" => Signal::SIGTRAP, + "SIGABRT" => Signal::SIGABRT, + "SIGBUS" => Signal::SIGBUS, + "SIGFPE" => Signal::SIGFPE, + "SIGKILL" => Signal::SIGKILL, + "SIGUSR1" => Signal::SIGUSR1, + "SIGSEGV" => Signal::SIGSEGV, + "SIGUSR2" => Signal::SIGUSR2, + "SIGPIPE" => Signal::SIGPIPE, + "SIGALRM" => Signal::SIGALRM, + "SIGTERM" => Signal::SIGTERM, + #[cfg(all( + any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ), + not(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc64" + )) + ))] + "SIGSTKFLT" => Signal::SIGSTKFLT, + "SIGCHLD" => Signal::SIGCHLD, + "SIGCONT" => Signal::SIGCONT, + "SIGSTOP" => Signal::SIGSTOP, + "SIGTSTP" => Signal::SIGTSTP, + "SIGTTIN" => Signal::SIGTTIN, + "SIGTTOU" => Signal::SIGTTOU, + "SIGURG" => Signal::SIGURG, + "SIGXCPU" => Signal::SIGXCPU, + "SIGXFSZ" => Signal::SIGXFSZ, + "SIGVTALRM" => Signal::SIGVTALRM, + "SIGPROF" => Signal::SIGPROF, + "SIGWINCH" => Signal::SIGWINCH, + #[cfg(not(target_os = "haiku"))] + "SIGIO" => Signal::SIGIO, + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + "SIGPWR" => Signal::SIGPWR, + "SIGSYS" => Signal::SIGSYS, + #[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux", + target_os = "redox", + target_os = "haiku" + )))] + "SIGEMT" => Signal::SIGEMT, + #[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux", + target_os = "redox", + target_os = "haiku" + )))] + "SIGINFO" => Signal::SIGINFO, + _ => return Err(Errno::EINVAL), + }) + } +} + +#[cfg(feature = "signal")] +impl Signal { + /// Returns name of signal. + /// + /// This function is equivalent to `>::as_ref()`, + /// with difference that returned string is `'static` + /// and not bound to `self`'s lifetime. + pub const fn as_str(self) -> &'static str { + match self { + Signal::SIGHUP => "SIGHUP", + Signal::SIGINT => "SIGINT", + Signal::SIGQUIT => "SIGQUIT", + Signal::SIGILL => "SIGILL", + Signal::SIGTRAP => "SIGTRAP", + Signal::SIGABRT => "SIGABRT", + Signal::SIGBUS => "SIGBUS", + Signal::SIGFPE => "SIGFPE", + Signal::SIGKILL => "SIGKILL", + Signal::SIGUSR1 => "SIGUSR1", + Signal::SIGSEGV => "SIGSEGV", + Signal::SIGUSR2 => "SIGUSR2", + Signal::SIGPIPE => "SIGPIPE", + Signal::SIGALRM => "SIGALRM", + Signal::SIGTERM => "SIGTERM", + #[cfg(all( + any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ), + not(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc64" + )) + ))] + Signal::SIGSTKFLT => "SIGSTKFLT", + Signal::SIGCHLD => "SIGCHLD", + Signal::SIGCONT => "SIGCONT", + Signal::SIGSTOP => "SIGSTOP", + Signal::SIGTSTP => "SIGTSTP", + Signal::SIGTTIN => "SIGTTIN", + Signal::SIGTTOU => "SIGTTOU", + Signal::SIGURG => "SIGURG", + Signal::SIGXCPU => "SIGXCPU", + Signal::SIGXFSZ => "SIGXFSZ", + Signal::SIGVTALRM => "SIGVTALRM", + Signal::SIGPROF => "SIGPROF", + Signal::SIGWINCH => "SIGWINCH", + #[cfg(not(target_os = "haiku"))] + Signal::SIGIO => "SIGIO", + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + Signal::SIGPWR => "SIGPWR", + Signal::SIGSYS => "SIGSYS", + #[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux", + target_os = "redox", + target_os = "haiku" + )))] + Signal::SIGEMT => "SIGEMT", + #[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux", + target_os = "redox", + target_os = "haiku" + )))] + Signal::SIGINFO => "SIGINFO", + } + } +} + +#[cfg(feature = "signal")] +impl AsRef for Signal { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +#[cfg(feature = "signal")] +impl fmt::Display for Signal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_ref()) + } +} + +#[cfg(feature = "signal")] +pub use self::Signal::*; + +#[cfg(target_os = "redox")] +#[cfg(feature = "signal")] +const SIGNALS: [Signal; 29] = [ + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, + SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, + SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, + SIGPROF, SIGWINCH, SIGIO, SIGSYS, +]; +#[cfg(target_os = "haiku")] +#[cfg(feature = "signal")] +const SIGNALS: [Signal; 28] = [ + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, + SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, + SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, + SIGPROF, SIGWINCH, SIGSYS, +]; +#[cfg(all( + any( + target_os = "linux", + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia" + ), + not(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc64" + )) +))] +#[cfg(feature = "signal")] +const SIGNALS: [Signal; 31] = [ + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, + SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGSTKFLT, SIGCHLD, + SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, + SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS, +]; +#[cfg(all( + any( + target_os = "linux", + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia" + ), + any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64") +))] +#[cfg(feature = "signal")] +const SIGNALS: [Signal; 30] = [ + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, + SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, + SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, + SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS, +]; +#[cfg(not(any( + target_os = "linux", + target_os = "android", + target_os = "fuchsia", + target_os = "emscripten", + target_os = "redox", + target_os = "haiku" +)))] +#[cfg(feature = "signal")] +const SIGNALS: [Signal; 31] = [ + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, + SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, + SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, + SIGPROF, SIGWINCH, SIGIO, SIGSYS, SIGEMT, SIGINFO, +]; + +feature! { +#![feature = "signal"] + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +/// Iterate through all signals defined by this operating system +pub struct SignalIterator { + next: usize, +} + +impl Iterator for SignalIterator { + type Item = Signal; + + fn next(&mut self) -> Option { + if self.next < SIGNALS.len() { + let next_signal = SIGNALS[self.next]; + self.next += 1; + Some(next_signal) + } else { + None + } + } +} + +impl Signal { + /// Iterate through all signals defined by this OS + pub const fn iterator() -> SignalIterator { + SignalIterator{next: 0} + } +} + +/// Alias for [`SIGABRT`] +pub const SIGIOT : Signal = SIGABRT; +/// Alias for [`SIGIO`] +#[cfg(not(target_os = "haiku"))] +pub const SIGPOLL : Signal = SIGIO; +/// Alias for [`SIGSYS`] +pub const SIGUNUSED : Signal = SIGSYS; + +cfg_if! { + if #[cfg(target_os = "redox")] { + type SaFlags_t = libc::c_ulong; + } else if #[cfg(target_env = "uclibc")] { + type SaFlags_t = libc::c_ulong; + } else { + type SaFlags_t = libc::c_int; + } +} +} + +#[cfg(feature = "signal")] +libc_bitflags! { + /// Controls the behavior of a [`SigAction`] + #[cfg_attr(docsrs, doc(cfg(feature = "signal")))] + pub struct SaFlags: SaFlags_t { + /// When catching a [`Signal::SIGCHLD`] signal, the signal will be + /// generated only when a child process exits, not when a child process + /// stops. + SA_NOCLDSTOP; + /// When catching a [`Signal::SIGCHLD`] signal, the system will not + /// create zombie processes when children of the calling process exit. + SA_NOCLDWAIT; + /// Further occurrences of the delivered signal are not masked during + /// the execution of the handler. + SA_NODEFER; + /// The system will deliver the signal to the process on a signal stack, + /// specified by each thread with sigaltstack(2). + SA_ONSTACK; + /// The handler is reset back to the default at the moment the signal is + /// delivered. + SA_RESETHAND; + /// Requests that certain system calls restart if interrupted by this + /// signal. See the man page for complete details. + SA_RESTART; + /// This flag is controlled internally by Nix. + SA_SIGINFO; + } +} + +#[cfg(feature = "signal")] +libc_enum! { + /// Specifies how certain functions should manipulate a signal mask + #[repr(i32)] + #[non_exhaustive] + #[cfg_attr(docsrs, doc(cfg(feature = "signal")))] + pub enum SigmaskHow { + /// The new mask is the union of the current mask and the specified set. + SIG_BLOCK, + /// The new mask is the intersection of the current mask and the + /// complement of the specified set. + SIG_UNBLOCK, + /// The current mask is replaced by the specified set. + SIG_SETMASK, + } +} + +feature! { +#![feature = "signal"] + +use crate::unistd::Pid; +use std::iter::Extend; +use std::iter::FromIterator; +use std::iter::IntoIterator; + +/// Specifies a set of [`Signal`]s that may be blocked, waited for, etc. +// We are using `transparent` here to be super sure that `SigSet` +// is represented exactly like the `sigset_t` struct from C. +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct SigSet { + sigset: libc::sigset_t +} + +impl SigSet { + /// Initialize to include all signals. + #[cfg_attr(has_doc_alias, doc(alias("sigfillset")))] + pub fn all() -> SigSet { + let mut sigset = mem::MaybeUninit::uninit(); + let _ = unsafe { libc::sigfillset(sigset.as_mut_ptr()) }; + + unsafe{ SigSet { sigset: sigset.assume_init() } } + } + + /// Initialize to include nothing. + #[cfg_attr(has_doc_alias, doc(alias("sigemptyset")))] + pub fn empty() -> SigSet { + let mut sigset = mem::MaybeUninit::uninit(); + let _ = unsafe { libc::sigemptyset(sigset.as_mut_ptr()) }; + + unsafe{ SigSet { sigset: sigset.assume_init() } } + } + + /// Add the specified signal to the set. + #[cfg_attr(has_doc_alias, doc(alias("sigaddset")))] + pub fn add(&mut self, signal: Signal) { + unsafe { libc::sigaddset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) }; + } + + /// Remove all signals from this set. + #[cfg_attr(has_doc_alias, doc(alias("sigemptyset")))] + pub fn clear(&mut self) { + unsafe { libc::sigemptyset(&mut self.sigset as *mut libc::sigset_t) }; + } + + /// Remove the specified signal from this set. + #[cfg_attr(has_doc_alias, doc(alias("sigdelset")))] + pub fn remove(&mut self, signal: Signal) { + unsafe { libc::sigdelset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) }; + } + + /// Return whether this set includes the specified signal. + #[cfg_attr(has_doc_alias, doc(alias("sigismember")))] + pub fn contains(&self, signal: Signal) -> bool { + let res = unsafe { libc::sigismember(&self.sigset as *const libc::sigset_t, signal as libc::c_int) }; + + match res { + 1 => true, + 0 => false, + _ => unreachable!("unexpected value from sigismember"), + } + } + + /// Returns an iterator that yields the signals contained in this set. + pub fn iter(&self) -> SigSetIter<'_> { + self.into_iter() + } + + /// Gets the currently blocked (masked) set of signals for the calling thread. + pub fn thread_get_mask() -> Result { + let mut oldmask = mem::MaybeUninit::uninit(); + do_pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(oldmask.as_mut_ptr()))?; + Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}}) + } + + /// Sets the set of signals as the signal mask for the calling thread. + pub fn thread_set_mask(&self) -> Result<()> { + pthread_sigmask(SigmaskHow::SIG_SETMASK, Some(self), None) + } + + /// Adds the set of signals to the signal mask for the calling thread. + pub fn thread_block(&self) -> Result<()> { + pthread_sigmask(SigmaskHow::SIG_BLOCK, Some(self), None) + } + + /// Removes the set of signals from the signal mask for the calling thread. + pub fn thread_unblock(&self) -> Result<()> { + pthread_sigmask(SigmaskHow::SIG_UNBLOCK, Some(self), None) + } + + /// Sets the set of signals as the signal mask, and returns the old mask. + pub fn thread_swap_mask(&self, how: SigmaskHow) -> Result { + let mut oldmask = mem::MaybeUninit::uninit(); + do_pthread_sigmask(how, Some(self), Some(oldmask.as_mut_ptr()))?; + Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}}) + } + + /// Suspends execution of the calling thread until one of the signals in the + /// signal mask becomes pending, and returns the accepted signal. + #[cfg(not(target_os = "redox"))] // RedoxFS does not yet support sigwait + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn wait(&self) -> Result { + use std::convert::TryFrom; + + let mut signum = mem::MaybeUninit::uninit(); + let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, signum.as_mut_ptr()) }; + + Errno::result(res).map(|_| unsafe { + Signal::try_from(signum.assume_init()).unwrap() + }) + } + + /// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the + /// `libc::sigset_t` is already initialized. + /// + /// # Safety + /// + /// The `sigset` passed in must be a valid an initialized `libc::sigset_t` by calling either + /// [`sigemptyset(3)`](https://man7.org/linux/man-pages/man3/sigemptyset.3p.html) or + /// [`sigfillset(3)`](https://man7.org/linux/man-pages/man3/sigfillset.3p.html). + /// Otherwise, the results are undefined. + pub unsafe fn from_sigset_t_unchecked(sigset: libc::sigset_t) -> SigSet { + SigSet { sigset } + } +} + +impl AsRef for SigSet { + fn as_ref(&self) -> &libc::sigset_t { + &self.sigset + } +} + +// TODO: Consider specialization for the case where T is &SigSet and libc::sigorset is available. +impl Extend for SigSet { + fn extend(&mut self, iter: T) + where T: IntoIterator { + for signal in iter { + self.add(signal); + } + } +} + +impl FromIterator for SigSet { + fn from_iter(iter: T) -> Self + where T: IntoIterator { + let mut sigset = SigSet::empty(); + sigset.extend(iter); + sigset + } +} + +/// Iterator for a [`SigSet`]. +/// +/// Call [`SigSet::iter`] to create an iterator. +#[derive(Clone, Debug)] +pub struct SigSetIter<'a> { + sigset: &'a SigSet, + inner: SignalIterator, +} + +impl Iterator for SigSetIter<'_> { + type Item = Signal; + fn next(&mut self) -> Option { + loop { + match self.inner.next() { + None => return None, + Some(signal) if self.sigset.contains(signal) => return Some(signal), + Some(_signal) => continue, + } + } + } +} + +impl<'a> IntoIterator for &'a SigSet { + type Item = Signal; + type IntoIter = SigSetIter<'a>; + fn into_iter(self) -> Self::IntoIter { + SigSetIter { sigset: self, inner: Signal::iterator() } + } +} + +/// A signal handler. +#[allow(unknown_lints)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum SigHandler { + /// Default signal handling. + SigDfl, + /// Request that the signal be ignored. + SigIgn, + /// Use the given signal-catching function, which takes in the signal. + Handler(extern fn(libc::c_int)), + /// Use the given signal-catching function, which takes in the signal, information about how + /// the signal was generated, and a pointer to the threads `ucontext_t`. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SigAction(extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void)) +} + +/// Action to take on receipt of a signal. Corresponds to `sigaction`. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct SigAction { + sigaction: libc::sigaction +} + +impl SigAction { + /// Creates a new action. + /// + /// The `SA_SIGINFO` bit in the `flags` argument is ignored (it will be set only if `handler` + /// is the `SigAction` variant). `mask` specifies other signals to block during execution of + /// the signal-catching function. + pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction { + unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) { + (*p).sa_sigaction = match handler { + SigHandler::SigDfl => libc::SIG_DFL, + SigHandler::SigIgn => libc::SIG_IGN, + SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize, + #[cfg(not(target_os = "redox"))] + SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize, + }; + } + + let mut s = mem::MaybeUninit::::uninit(); + unsafe { + let p = s.as_mut_ptr(); + install_sig(p, handler); + (*p).sa_flags = match handler { + #[cfg(not(target_os = "redox"))] + SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(), + _ => (flags - SaFlags::SA_SIGINFO).bits(), + }; + (*p).sa_mask = mask.sigset; + + SigAction { sigaction: s.assume_init() } + } + } + + /// Returns the flags set on the action. + pub fn flags(&self) -> SaFlags { + SaFlags::from_bits_truncate(self.sigaction.sa_flags) + } + + /// Returns the set of signals that are blocked during execution of the action's + /// signal-catching function. + pub fn mask(&self) -> SigSet { + SigSet { sigset: self.sigaction.sa_mask } + } + + /// Returns the action's handler. + pub fn handler(&self) -> SigHandler { + match self.sigaction.sa_sigaction { + libc::SIG_DFL => SigHandler::SigDfl, + libc::SIG_IGN => SigHandler::SigIgn, + #[cfg(not(target_os = "redox"))] + p if self.flags().contains(SaFlags::SA_SIGINFO) => + SigHandler::SigAction( + // Safe for one of two reasons: + // * The SigHandler was created by SigHandler::new, in which + // case the pointer is correct, or + // * The SigHandler was created by signal or sigaction, which + // are unsafe functions, so the caller should've somehow + // ensured that it is correctly initialized. + unsafe{ + *(&p as *const usize + as *const extern fn(_, _, _)) + } + as extern fn(_, _, _)), + p => SigHandler::Handler( + // Safe for one of two reasons: + // * The SigHandler was created by SigHandler::new, in which + // case the pointer is correct, or + // * The SigHandler was created by signal or sigaction, which + // are unsafe functions, so the caller should've somehow + // ensured that it is correctly initialized. + unsafe{ + *(&p as *const usize + as *const extern fn(libc::c_int)) + } + as extern fn(libc::c_int)), + } + } +} + +/// Changes the action taken by a process on receipt of a specific signal. +/// +/// `signal` can be any signal except `SIGKILL` or `SIGSTOP`. On success, it returns the previous +/// action for the given signal. If `sigaction` fails, no new signal handler is installed. +/// +/// # Safety +/// +/// * Signal handlers may be called at any point during execution, which limits +/// what is safe to do in the body of the signal-catching function. Be certain +/// to only make syscalls that are explicitly marked safe for signal handlers +/// and only share global data using atomics. +/// +/// * There is also no guarantee that the old signal handler was installed +/// correctly. If it was installed by this crate, it will be. But if it was +/// installed by, for example, C code, then there is no guarantee its function +/// pointer is valid. In that case, this function effectively dereferences a +/// raw pointer of unknown provenance. +pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result { + let mut oldact = mem::MaybeUninit::::uninit(); + + let res = libc::sigaction(signal as libc::c_int, + &sigaction.sigaction as *const libc::sigaction, + oldact.as_mut_ptr()); + + Errno::result(res).map(|_| SigAction { sigaction: oldact.assume_init() }) +} + +/// Signal management (see [signal(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html)) +/// +/// Installs `handler` for the given `signal`, returning the previous signal +/// handler. `signal` should only be used following another call to `signal` or +/// if the current handler is the default. The return value of `signal` is +/// undefined after setting the handler with [`sigaction`][SigActionFn]. +/// +/// # Safety +/// +/// If the pointer to the previous signal handler is invalid, undefined +/// behavior could be invoked when casting it back to a [`SigAction`][SigActionStruct]. +/// +/// # Examples +/// +/// Ignore `SIGINT`: +/// +/// ```no_run +/// # use nix::sys::signal::{self, Signal, SigHandler}; +/// unsafe { signal::signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap(); +/// ``` +/// +/// Use a signal handler to set a flag variable: +/// +/// ```no_run +/// # #[macro_use] extern crate lazy_static; +/// # use std::convert::TryFrom; +/// # use std::sync::atomic::{AtomicBool, Ordering}; +/// # use nix::sys::signal::{self, Signal, SigHandler}; +/// lazy_static! { +/// static ref SIGNALED: AtomicBool = AtomicBool::new(false); +/// } +/// +/// extern fn handle_sigint(signal: libc::c_int) { +/// let signal = Signal::try_from(signal).unwrap(); +/// SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed); +/// } +/// +/// fn main() { +/// let handler = SigHandler::Handler(handle_sigint); +/// unsafe { signal::signal(Signal::SIGINT, handler) }.unwrap(); +/// } +/// ``` +/// +/// # Errors +/// +/// Returns [`Error(Errno::EOPNOTSUPP)`] if `handler` is +/// [`SigAction`][SigActionStruct]. Use [`sigaction`][SigActionFn] instead. +/// +/// `signal` also returns any error from `libc::signal`, such as when an attempt +/// is made to catch a signal that cannot be caught or to ignore a signal that +/// cannot be ignored. +/// +/// [`Error::UnsupportedOperation`]: ../../enum.Error.html#variant.UnsupportedOperation +/// [SigActionStruct]: struct.SigAction.html +/// [sigactionFn]: fn.sigaction.html +pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result { + let signal = signal as libc::c_int; + let res = match handler { + SigHandler::SigDfl => libc::signal(signal, libc::SIG_DFL), + SigHandler::SigIgn => libc::signal(signal, libc::SIG_IGN), + SigHandler::Handler(handler) => libc::signal(signal, handler as libc::sighandler_t), + #[cfg(not(target_os = "redox"))] + SigHandler::SigAction(_) => return Err(Errno::ENOTSUP), + }; + Errno::result(res).map(|oldhandler| { + match oldhandler { + libc::SIG_DFL => SigHandler::SigDfl, + libc::SIG_IGN => SigHandler::SigIgn, + p => SigHandler::Handler( + *(&p as *const usize + as *const extern fn(libc::c_int)) + as extern fn(libc::c_int)), + } + }) +} + +fn do_pthread_sigmask(how: SigmaskHow, + set: Option<&SigSet>, + oldset: Option<*mut libc::sigset_t>) -> Result<()> { + if set.is_none() && oldset.is_none() { + return Ok(()) + } + + let res = unsafe { + // if set or oldset is None, pass in null pointers instead + libc::pthread_sigmask(how as libc::c_int, + set.map_or_else(ptr::null::, + |s| &s.sigset as *const libc::sigset_t), + oldset.unwrap_or(ptr::null_mut()) + ) + }; + + Errno::result(res).map(drop) +} + +/// Manages the signal mask (set of blocked signals) for the calling thread. +/// +/// If the `set` parameter is `Some(..)`, then the signal mask will be updated with the signal set. +/// The `how` flag decides the type of update. If `set` is `None`, `how` will be ignored, +/// and no modification will take place. +/// +/// If the 'oldset' parameter is `Some(..)` then the current signal mask will be written into it. +/// +/// If both `set` and `oldset` is `Some(..)`, the current signal mask will be written into oldset, +/// and then it will be updated with `set`. +/// +/// If both `set` and `oldset` is None, this function is a no-op. +/// +/// For more information, visit the [`pthread_sigmask`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html), +/// or [`sigprocmask`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages. +pub fn pthread_sigmask(how: SigmaskHow, + set: Option<&SigSet>, + oldset: Option<&mut SigSet>) -> Result<()> +{ + do_pthread_sigmask(how, set, oldset.map(|os| &mut os.sigset as *mut _ )) +} + +/// Examine and change blocked signals. +/// +/// For more information see the [`sigprocmask` man +/// pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html). +pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut SigSet>) -> Result<()> { + if set.is_none() && oldset.is_none() { + return Ok(()) + } + + let res = unsafe { + // if set or oldset is None, pass in null pointers instead + libc::sigprocmask(how as libc::c_int, + set.map_or_else(ptr::null::, + |s| &s.sigset as *const libc::sigset_t), + oldset.map_or_else(ptr::null_mut::, + |os| &mut os.sigset as *mut libc::sigset_t)) + }; + + Errno::result(res).map(drop) +} + +/// Send a signal to a process +/// +/// # Arguments +/// +/// * `pid` - Specifies which processes should receive the signal. +/// - If positive, specifies an individual process +/// - If zero, the signal will be sent to all processes whose group +/// ID is equal to the process group ID of the sender. This is a +/// variant of [`killpg`]. +/// - If `-1` and the process has super-user privileges, the signal +/// is sent to all processes exclusing system processes. +/// - If less than `-1`, the signal is sent to all processes whose +/// process group ID is equal to the absolute value of `pid`. +/// * `signal` - Signal to send. If `None`, error checking is performed +/// but no signal is actually sent. +/// +/// See Also +/// [`kill(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html) +pub fn kill>>(pid: Pid, signal: T) -> Result<()> { + let res = unsafe { libc::kill(pid.into(), + match signal.into() { + Some(s) => s as libc::c_int, + None => 0, + }) }; + + Errno::result(res).map(drop) +} + +/// Send a signal to a process group +/// +/// # Arguments +/// +/// * `pgrp` - Process group to signal. If less then or equal 1, the behavior +/// is platform-specific. +/// * `signal` - Signal to send. If `None`, `killpg` will only preform error +/// checking and won't send any signal. +/// +/// See Also [killpg(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html). +#[cfg(not(target_os = "fuchsia"))] +pub fn killpg>>(pgrp: Pid, signal: T) -> Result<()> { + let res = unsafe { libc::killpg(pgrp.into(), + match signal.into() { + Some(s) => s as libc::c_int, + None => 0, + }) }; + + Errno::result(res).map(drop) +} + +/// Send a signal to the current thread +/// +/// See Also [raise(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html) +pub fn raise(signal: Signal) -> Result<()> { + let res = unsafe { libc::raise(signal as libc::c_int) }; + + Errno::result(res).map(drop) +} +} + +feature! { +#![any(feature = "aio", feature = "signal")] + +/// Identifies a thread for [`SigevNotify::SigevThreadId`] +#[cfg(target_os = "freebsd")] +pub type type_of_thread_id = libc::lwpid_t; +/// Identifies a thread for [`SigevNotify::SigevThreadId`] +#[cfg(target_os = "linux")] +pub type type_of_thread_id = libc::pid_t; + +/// Specifies the notification method used by a [`SigEvent`] +// sigval is actually a union of a int and a void*. But it's never really used +// as a pointer, because neither libc nor the kernel ever dereference it. nix +// therefore presents it as an intptr_t, which is how kevent uses it. +#[cfg(not(any(target_os = "openbsd", target_os = "redox")))] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum SigevNotify { + /// No notification will be delivered + SigevNone, + /// Notify by delivering a signal to the process. + SigevSignal { + /// Signal to deliver + signal: Signal, + /// Will be present in the `si_value` field of the [`libc::siginfo_t`] + /// structure of the queued signal. + si_value: libc::intptr_t + }, + // Note: SIGEV_THREAD is not implemented because libc::sigevent does not + // expose a way to set the union members needed by SIGEV_THREAD. + /// Notify by delivering an event to a kqueue. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SigevKevent { + /// File descriptor of the kqueue to notify. + kq: RawFd, + /// Will be contained in the kevent's `udata` field. + udata: libc::intptr_t + }, + /// Notify by delivering a signal to a thread. + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SigevThreadId { + /// Signal to send + signal: Signal, + /// LWP ID of the thread to notify + thread_id: type_of_thread_id, + /// Will be present in the `si_value` field of the [`libc::siginfo_t`] + /// structure of the queued signal. + si_value: libc::intptr_t + }, +} +} + +#[cfg(not(any(target_os = "openbsd", target_os = "redox")))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod sigevent { + feature! { + #![any(feature = "aio", feature = "signal")] + + use std::mem; + use std::ptr; + use super::SigevNotify; + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + use super::type_of_thread_id; + + /// Used to request asynchronous notification of the completion of certain + /// events, such as POSIX AIO and timers. + #[repr(C)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct SigEvent { + sigevent: libc::sigevent + } + + impl SigEvent { + /// **Note:** this constructor does not allow the user to set the + /// `sigev_notify_kevent_flags` field. That's considered ok because on FreeBSD + /// at least those flags don't do anything useful. That field is part of a + /// union that shares space with the more genuinely useful fields. + /// + /// **Note:** This constructor also doesn't allow the caller to set the + /// `sigev_notify_function` or `sigev_notify_attributes` fields, which are + /// required for `SIGEV_THREAD`. That's considered ok because on no operating + /// system is `SIGEV_THREAD` the most efficient way to deliver AIO + /// notification. FreeBSD and DragonFly BSD programs should prefer `SIGEV_KEVENT`. + /// Linux, Solaris, and portable programs should prefer `SIGEV_THREAD_ID` or + /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the + /// more genuinely useful `sigev_notify_thread_id` + // Allow invalid_value warning on Fuchsia only. + // See https://github.com/nix-rust/nix/issues/1441 + #[cfg_attr(target_os = "fuchsia", allow(invalid_value))] + pub fn new(sigev_notify: SigevNotify) -> SigEvent { + let mut sev = unsafe { mem::MaybeUninit::::zeroed().assume_init() }; + sev.sigev_notify = match sigev_notify { + SigevNotify::SigevNone => libc::SIGEV_NONE, + SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL, + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT, + #[cfg(target_os = "freebsd")] + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))] + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(all(target_os = "linux", target_env = "uclibc"))] + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))] + SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined + }; + sev.sigev_signo = match sigev_notify { + SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int, + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + SigevNotify::SigevKevent{ kq, ..} => kq, + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int, + _ => 0 + }; + sev.sigev_value.sival_ptr = match sigev_notify { + SigevNotify::SigevNone => ptr::null_mut::(), + SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void, + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void, + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void, + }; + SigEvent::set_tid(&mut sev, &sigev_notify); + SigEvent{sigevent: sev} + } + + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) { + sev.sigev_notify_thread_id = match *sigev_notify { + SigevNotify::SigevThreadId { thread_id, .. } => thread_id, + _ => 0 as type_of_thread_id + }; + } + + #[cfg(not(any(target_os = "freebsd", target_os = "linux")))] + fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) { + } + + /// Return a copy of the inner structure + pub fn sigevent(&self) -> libc::sigevent { + self.sigevent + } + + /// Returns a mutable pointer to the `sigevent` wrapped by `self` + pub fn as_mut_ptr(&mut self) -> *mut libc::sigevent { + &mut self.sigevent + } + } + + impl<'a> From<&'a libc::sigevent> for SigEvent { + fn from(sigevent: &libc::sigevent) -> Self { + SigEvent{ sigevent: *sigevent } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[cfg(not(target_os = "redox"))] + use std::thread; + + #[test] + fn test_contains() { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + assert!(mask.contains(SIGUSR1)); + assert!(!mask.contains(SIGUSR2)); + + let all = SigSet::all(); + assert!(all.contains(SIGUSR1)); + assert!(all.contains(SIGUSR2)); + } + + #[test] + fn test_clear() { + let mut set = SigSet::all(); + set.clear(); + for signal in Signal::iterator() { + assert!(!set.contains(signal)); + } + } + + #[test] + fn test_from_str_round_trips() { + for signal in Signal::iterator() { + assert_eq!(signal.as_ref().parse::().unwrap(), signal); + assert_eq!(signal.to_string().parse::().unwrap(), signal); + } + } + + #[test] + fn test_from_str_invalid_value() { + let errval = Err(Errno::EINVAL); + assert_eq!("NOSIGNAL".parse::(), errval); + assert_eq!("kill".parse::(), errval); + assert_eq!("9".parse::(), errval); + } + + #[test] + fn test_extend() { + let mut one_signal = SigSet::empty(); + one_signal.add(SIGUSR1); + + let mut two_signals = SigSet::empty(); + two_signals.add(SIGUSR2); + two_signals.extend(&one_signal); + + assert!(two_signals.contains(SIGUSR1)); + assert!(two_signals.contains(SIGUSR2)); + } + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_thread_signal_set_mask() { + thread::spawn(|| { + let prev_mask = SigSet::thread_get_mask() + .expect("Failed to get existing signal mask!"); + + let mut test_mask = prev_mask; + test_mask.add(SIGUSR1); + + test_mask.thread_set_mask().expect("assertion failed"); + let new_mask = + SigSet::thread_get_mask().expect("Failed to get new mask!"); + + assert!(new_mask.contains(SIGUSR1)); + assert!(!new_mask.contains(SIGUSR2)); + + prev_mask + .thread_set_mask() + .expect("Failed to revert signal mask!"); + }) + .join() + .unwrap(); + } + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_thread_signal_block() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + mask.thread_block().expect("assertion failed"); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); + }) + .join() + .unwrap(); + } + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_thread_signal_unblock() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + mask.thread_unblock().expect("assertion failed"); + + assert!(!SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); + }) + .join() + .unwrap(); + } + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_thread_signal_swap() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + mask.thread_block().unwrap(); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); + + let mut mask2 = SigSet::empty(); + mask2.add(SIGUSR2); + + let oldmask = + mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK).unwrap(); + + assert!(oldmask.contains(SIGUSR1)); + assert!(!oldmask.contains(SIGUSR2)); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2)); + }) + .join() + .unwrap(); + } + + #[test] + fn test_from_and_into_iterator() { + let sigset = SigSet::from_iter(vec![Signal::SIGUSR1, Signal::SIGUSR2]); + let signals = sigset.into_iter().collect::>(); + assert_eq!(signals, [Signal::SIGUSR1, Signal::SIGUSR2]); + } + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_sigaction() { + thread::spawn(|| { + extern "C" fn test_sigaction_handler(_: libc::c_int) {} + extern "C" fn test_sigaction_action( + _: libc::c_int, + _: *mut libc::siginfo_t, + _: *mut libc::c_void, + ) { + } + + let handler_sig = SigHandler::Handler(test_sigaction_handler); + + let flags = + SaFlags::SA_ONSTACK | SaFlags::SA_RESTART | SaFlags::SA_SIGINFO; + + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + let action_sig = SigAction::new(handler_sig, flags, mask); + + assert_eq!( + action_sig.flags(), + SaFlags::SA_ONSTACK | SaFlags::SA_RESTART + ); + assert_eq!(action_sig.handler(), handler_sig); + + mask = action_sig.mask(); + assert!(mask.contains(SIGUSR1)); + assert!(!mask.contains(SIGUSR2)); + + let handler_act = SigHandler::SigAction(test_sigaction_action); + let action_act = SigAction::new(handler_act, flags, mask); + assert_eq!(action_act.handler(), handler_act); + + let action_dfl = SigAction::new(SigHandler::SigDfl, flags, mask); + assert_eq!(action_dfl.handler(), SigHandler::SigDfl); + + let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask); + assert_eq!(action_ign.handler(), SigHandler::SigIgn); + }) + .join() + .unwrap(); + } + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_sigwait() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + mask.add(SIGUSR2); + mask.thread_block().unwrap(); + + raise(SIGUSR1).unwrap(); + assert_eq!(mask.wait().unwrap(), SIGUSR1); + }) + .join() + .unwrap(); + } + + #[test] + fn test_from_sigset_t_unchecked() { + let src_set = SigSet::empty(); + let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) }; + + for signal in Signal::iterator() { + assert!(!set.contains(signal)); + } + + let src_set = SigSet::all(); + let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) }; + + for signal in Signal::iterator() { + assert!(set.contains(signal)); + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/signalfd.rs b/utshell-0.5.0/vendor/nix/src/sys/signalfd.rs new file mode 100644 index 00000000..166bb9d2 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/signalfd.rs @@ -0,0 +1,171 @@ +//! Interface for the `signalfd` syscall. +//! +//! # Signal discarding +//! When a signal can't be delivered to a process (or thread), it will become a pending signal. +//! Failure to deliver could happen if the signal is blocked by every thread in the process or if +//! the signal handler is still handling a previous signal. +//! +//! If a signal is sent to a process (or thread) that already has a pending signal of the same +//! type, it will be discarded. This means that if signals of the same type are received faster than +//! they are processed, some of those signals will be dropped. Because of this limitation, +//! `signalfd` in itself cannot be used for reliable communication between processes or threads. +//! +//! Once the signal is unblocked, or the signal handler is finished, and a signal is still pending +//! (ie. not consumed from a signalfd) it will be delivered to the signal handler. +//! +//! Please note that signal discarding is not specific to `signalfd`, but also happens with regular +//! signal handlers. +use crate::unistd; +use crate::Result; +use crate::errno::Errno; +pub use crate::sys::signal::{self, SigSet}; +pub use libc::signalfd_siginfo as siginfo; + +use std::os::unix::io::{RawFd, AsRawFd}; +use std::mem; + + +libc_bitflags!{ + pub struct SfdFlags: libc::c_int { + SFD_NONBLOCK; + SFD_CLOEXEC; + } +} + +pub const SIGNALFD_NEW: RawFd = -1; +#[deprecated(since = "0.23.0", note = "use mem::size_of::() instead")] +pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::(); + +/// Creates a new file descriptor for reading signals. +/// +/// **Important:** please read the module level documentation about signal discarding before using +/// this function! +/// +/// The `mask` parameter specifies the set of signals that can be accepted via this file descriptor. +/// +/// A signal must be blocked on every thread in a process, otherwise it won't be visible from +/// signalfd (the default handler will be invoked instead). +/// +/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html) +pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result { + unsafe { + Errno::result(libc::signalfd(fd as libc::c_int, mask.as_ref(), flags.bits())) + } +} + +/// A helper struct for creating, reading and closing a `signalfd` instance. +/// +/// **Important:** please read the module level documentation about signal discarding before using +/// this struct! +/// +/// # Examples +/// +/// ``` +/// # use nix::sys::signalfd::*; +/// // Set the thread to block the SIGUSR1 signal, otherwise the default handler will be used +/// let mut mask = SigSet::empty(); +/// mask.add(signal::SIGUSR1); +/// mask.thread_block().unwrap(); +/// +/// // Signals are queued up on the file descriptor +/// let mut sfd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap(); +/// +/// match sfd.read_signal() { +/// // we caught a signal +/// Ok(Some(sig)) => (), +/// // there were no signals waiting (only happens when the SFD_NONBLOCK flag is set, +/// // otherwise the read_signal call blocks) +/// Ok(None) => (), +/// Err(err) => (), // some error happend +/// } +/// ``` +#[derive(Debug, Eq, Hash, PartialEq)] +pub struct SignalFd(RawFd); + +impl SignalFd { + pub fn new(mask: &SigSet) -> Result { + Self::with_flags(mask, SfdFlags::empty()) + } + + pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result { + let fd = signalfd(SIGNALFD_NEW, mask, flags)?; + + Ok(SignalFd(fd)) + } + + pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> { + signalfd(self.0, mask, SfdFlags::empty()).map(drop) + } + + pub fn read_signal(&mut self) -> Result> { + let mut buffer = mem::MaybeUninit::::uninit(); + + let size = mem::size_of_val(&buffer); + let res = Errno::result(unsafe { + libc::read(self.0, buffer.as_mut_ptr() as *mut libc::c_void, size) + }).map(|r| r as usize); + match res { + Ok(x) if x == size => Ok(Some(unsafe { buffer.assume_init() })), + Ok(_) => unreachable!("partial read on signalfd"), + Err(Errno::EAGAIN) => Ok(None), + Err(error) => Err(error) + } + } +} + +impl Drop for SignalFd { + fn drop(&mut self) { + let e = unistd::close(self.0); + if !std::thread::panicking() && e == Err(Errno::EBADF) { + panic!("Closing an invalid file descriptor!"); + }; + } +} + +impl AsRawFd for SignalFd { + fn as_raw_fd(&self) -> RawFd { + self.0 + } +} + +impl Iterator for SignalFd { + type Item = siginfo; + + fn next(&mut self) -> Option { + match self.read_signal() { + Ok(Some(sig)) => Some(sig), + Ok(None) | Err(_) => None, + } + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn create_signalfd() { + let mask = SigSet::empty(); + SignalFd::new(&mask).unwrap(); + } + + #[test] + fn create_signalfd_with_opts() { + let mask = SigSet::empty(); + SignalFd::with_flags( + &mask, + SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK, + ) + .unwrap(); + } + + #[test] + fn read_empty_signalfd() { + let mask = SigSet::empty(); + let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap(); + + let res = fd.read_signal(); + assert!(res.unwrap().is_none()); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/socket/addr.rs b/utshell-0.5.0/vendor/nix/src/sys/socket/addr.rs new file mode 100644 index 00000000..a86d8a91 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/socket/addr.rs @@ -0,0 +1,2973 @@ +use super::sa_family_t; +use cfg_if::cfg_if; +use crate::{Result, NixPath}; +use crate::errno::Errno; +use memoffset::offset_of; +use std::{fmt, mem, net, ptr, slice}; +use std::convert::TryInto; +use std::ffi::OsStr; +use std::hash::{Hash, Hasher}; +use std::path::Path; +use std::os::unix::ffi::OsStrExt; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::sys::socket::addr::netlink::NetlinkAddr; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::sys::socket::addr::alg::AlgAddr; +#[cfg(any(target_os = "ios", target_os = "macos"))] +use std::os::unix::io::RawFd; +#[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))] +use crate::sys::socket::addr::sys_control::SysControlAddr; +#[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "haiku", + target_os = "fuchsia"))] +#[cfg(feature = "net")] +pub use self::datalink::LinkAddr; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use self::vsock::VsockAddr; + +/// Convert a std::net::Ipv4Addr into the libc form. +#[cfg(feature = "net")] +pub(crate) fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr { + let octets = addr.octets(); + libc::in_addr { + s_addr: u32::to_be(((octets[0] as u32) << 24) | + ((octets[1] as u32) << 16) | + ((octets[2] as u32) << 8) | + (octets[3] as u32)) + } +} + +/// Convert a std::net::Ipv6Addr into the libc form. +#[cfg(feature = "net")] +pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr { + libc::in6_addr { + s6_addr: addr.octets() + } +} + +/// These constants specify the protocol family to be used +/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) +/// +/// # References +/// +/// [address_families(7)](https://man7.org/linux/man-pages/man7/address_families.7.html) +// Should this be u8? +#[repr(i32)] +#[non_exhaustive] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] +pub enum AddressFamily { + /// Local communication (see [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html)) + Unix = libc::AF_UNIX, + /// IPv4 Internet protocols (see [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html)) + Inet = libc::AF_INET, + /// IPv6 Internet protocols (see [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html)) + Inet6 = libc::AF_INET6, + /// Kernel user interface device (see [`netlink(7)`](https://man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Netlink = libc::AF_NETLINK, + /// Low level packet interface (see [`packet(7)`](https://man7.org/linux/man-pages/man7/packet.7.html)) + #[cfg(any(target_os = "android", + target_os = "linux", + target_os = "illumos", + target_os = "fuchsia", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Packet = libc::AF_PACKET, + /// KEXT Controls and Notifications + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + System = libc::AF_SYSTEM, + /// Amateur radio AX.25 protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Ax25 = libc::AF_AX25, + /// IPX - Novell protocols + Ipx = libc::AF_IPX, + /// AppleTalk + AppleTalk = libc::AF_APPLETALK, + /// AX.25 packet layer protocol. + /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetRom = libc::AF_NETROM, + /// Can't be used for creating sockets; mostly used for bridge + /// links in + /// [rtnetlink(7)](https://man7.org/linux/man-pages/man7/rtnetlink.7.html) + /// protocol commands. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Bridge = libc::AF_BRIDGE, + /// Access to raw ATM PVCs + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AtmPvc = libc::AF_ATMPVC, + /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](https://man7.org/linux/man-pages/man7/x25.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + X25 = libc::AF_X25, + /// RATS (Radio Amateur Telecommunications Society) Open + /// Systems environment (ROSE) AX.25 packet layer protocol. + /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Rose = libc::AF_ROSE, + /// DECet protocol sockets. + #[cfg(not(target_os = "haiku"))] + Decnet = libc::AF_DECnet, + /// Reserved for "802.2LLC project"; never used. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetBeui = libc::AF_NETBEUI, + /// This was a short-lived (between Linux 2.1.30 and + /// 2.1.99pre2) protocol family for firewall upcalls. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Security = libc::AF_SECURITY, + /// Key management protocol. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Key = libc::AF_KEY, + #[allow(missing_docs)] // Not documented anywhere that I can find + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Ash = libc::AF_ASH, + /// Acorn Econet protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Econet = libc::AF_ECONET, + /// Access to ATM Switched Virtual Circuits + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AtmSvc = libc::AF_ATMSVC, + /// Reliable Datagram Sockets (RDS) protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Rds = libc::AF_RDS, + /// IBM SNA + #[cfg(not(target_os = "haiku"))] + Sna = libc::AF_SNA, + /// Socket interface over IrDA + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Irda = libc::AF_IRDA, + /// Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Pppox = libc::AF_PPPOX, + /// Legacy protocol for wide area network (WAN) connectivity that was used + /// by Sangoma WAN cards + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Wanpipe = libc::AF_WANPIPE, + /// Logical link control (IEEE 802.2 LLC) protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Llc = libc::AF_LLC, + /// InfiniBand native addressing + #[cfg(all(target_os = "linux", not(target_env = "uclibc")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Ib = libc::AF_IB, + /// Multiprotocol Label Switching + #[cfg(all(target_os = "linux", not(target_env = "uclibc")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Mpls = libc::AF_MPLS, + /// Controller Area Network automotive bus protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Can = libc::AF_CAN, + /// TIPC, "cluster domain sockets" protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Tipc = libc::AF_TIPC, + /// Bluetooth low-level socket protocol + #[cfg(not(any(target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Bluetooth = libc::AF_BLUETOOTH, + /// IUCV (inter-user communication vehicle) z/VM protocol for + /// hypervisor-guest interaction + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Iucv = libc::AF_IUCV, + /// Rx, Andrew File System remote procedure call protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + RxRpc = libc::AF_RXRPC, + /// New "modular ISDN" driver interface protocol + #[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Isdn = libc::AF_ISDN, + /// Nokia cellular modem IPC/RPC interface + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Phonet = libc::AF_PHONET, + /// IEEE 802.15.4 WPAN (wireless personal area network) raw packet protocol + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Ieee802154 = libc::AF_IEEE802154, + /// Ericsson's Communication CPU to Application CPU interface (CAIF) + /// protocol. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Caif = libc::AF_CAIF, + /// Interface to kernel crypto API + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Alg = libc::AF_ALG, + /// Near field communication + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + Nfc = libc::AF_NFC, + /// VMWare VSockets protocol for hypervisor-guest interaction. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Vsock = libc::AF_VSOCK, + /// ARPANet IMP addresses + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ImpLink = libc::AF_IMPLINK, + /// PUP protocols, e.g. BSP + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Pup = libc::AF_PUP, + /// MIT CHAOS protocols + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Chaos = libc::AF_CHAOS, + /// Novell and Xerox protocol + #[cfg(any(target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Ns = libc::AF_NS, + #[allow(missing_docs)] // Not documented anywhere that I can find + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Iso = libc::AF_ISO, + /// Bell Labs virtual circuit switch ? + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Datakit = libc::AF_DATAKIT, + /// CCITT protocols, X.25 etc + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Ccitt = libc::AF_CCITT, + /// DEC Direct data link interface + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Dli = libc::AF_DLI, + #[allow(missing_docs)] // Not documented anywhere that I can find + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Lat = libc::AF_LAT, + /// NSC Hyperchannel + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Hylink = libc::AF_HYLINK, + /// Link layer interface + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Link = libc::AF_LINK, + /// connection-oriented IP, aka ST II + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Coip = libc::AF_COIP, + /// Computer Network Technology + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Cnt = libc::AF_CNT, + /// Native ATM access + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Natm = libc::AF_NATM, + /// Unspecified address family, (see [`getaddrinfo(3)`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Unspec = libc::AF_UNSPEC, +} + +impl AddressFamily { + /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from + /// the `sa_family` field of a `sockaddr`. + /// + /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet + /// and System. Returns None for unsupported or unknown address families. + pub const fn from_i32(family: i32) -> Option { + match family { + libc::AF_UNIX => Some(AddressFamily::Unix), + libc::AF_INET => Some(AddressFamily::Inet), + libc::AF_INET6 => Some(AddressFamily::Inet6), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => Some(AddressFamily::Netlink), + #[cfg(any(target_os = "macos", target_os = "macos"))] + libc::AF_SYSTEM => Some(AddressFamily::System), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_PACKET => Some(AddressFamily::Packet), + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] + libc::AF_LINK => Some(AddressFamily::Link), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => Some(AddressFamily::Vsock), + _ => None + } + } +} + +feature! { +#![feature = "net"] + +#[deprecated( + since = "0.24.0", + note = "use SockaddrIn, SockaddrIn6, or SockaddrStorage instead" +)] +#[allow(missing_docs)] // Since they're all deprecated anyway +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum InetAddr { + V4(libc::sockaddr_in), + V6(libc::sockaddr_in6), +} + +#[allow(missing_docs)] // It's deprecated anyway +#[allow(deprecated)] +impl InetAddr { + #[allow(clippy::needless_update)] // It isn't needless on all OSes + pub fn from_std(std: &net::SocketAddr) -> InetAddr { + match *std { + net::SocketAddr::V4(ref addr) => { + InetAddr::V4(libc::sockaddr_in { + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "hermit", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + sin_len: mem::size_of::() as u8, + sin_family: AddressFamily::Inet as sa_family_t, + sin_port: addr.port().to_be(), // network byte order + sin_addr: Ipv4Addr::from_std(addr.ip()).0, + .. unsafe { mem::zeroed() } + }) + } + net::SocketAddr::V6(ref addr) => { + InetAddr::V6(libc::sockaddr_in6 { + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "hermit", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + sin6_len: mem::size_of::() as u8, + sin6_family: AddressFamily::Inet6 as sa_family_t, + sin6_port: addr.port().to_be(), // network byte order + sin6_addr: Ipv6Addr::from_std(addr.ip()).0, + sin6_flowinfo: addr.flowinfo(), // host byte order + sin6_scope_id: addr.scope_id(), // host byte order + .. unsafe { mem::zeroed() } + }) + } + } + } + + #[allow(clippy::needless_update)] // It isn't needless on all OSes + pub fn new(ip: IpAddr, port: u16) -> InetAddr { + match ip { + IpAddr::V4(ref ip) => { + InetAddr::V4(libc::sockaddr_in { + sin_family: AddressFamily::Inet as sa_family_t, + sin_port: port.to_be(), + sin_addr: ip.0, + .. unsafe { mem::zeroed() } + }) + } + IpAddr::V6(ref ip) => { + InetAddr::V6(libc::sockaddr_in6 { + sin6_family: AddressFamily::Inet6 as sa_family_t, + sin6_port: port.to_be(), + sin6_addr: ip.0, + .. unsafe { mem::zeroed() } + }) + } + } + } + /// Gets the IP address associated with this socket address. + pub const fn ip(&self) -> IpAddr { + match *self { + InetAddr::V4(ref sa) => IpAddr::V4(Ipv4Addr(sa.sin_addr)), + InetAddr::V6(ref sa) => IpAddr::V6(Ipv6Addr(sa.sin6_addr)), + } + } + + /// Gets the port number associated with this socket address + pub const fn port(&self) -> u16 { + match *self { + InetAddr::V6(ref sa) => u16::from_be(sa.sin6_port), + InetAddr::V4(ref sa) => u16::from_be(sa.sin_port), + } + } + + pub fn to_std(&self) -> net::SocketAddr { + match *self { + InetAddr::V4(ref sa) => net::SocketAddr::V4( + net::SocketAddrV4::new( + Ipv4Addr(sa.sin_addr).to_std(), + self.port())), + InetAddr::V6(ref sa) => net::SocketAddr::V6( + net::SocketAddrV6::new( + Ipv6Addr(sa.sin6_addr).to_std(), + self.port(), + sa.sin6_flowinfo, + sa.sin6_scope_id)), + } + } + + #[deprecated(since = "0.23.0", note = "use .to_string() instead")] + pub fn to_str(&self) -> String { + format!("{}", self) + } +} + +#[allow(deprecated)] +impl fmt::Display for InetAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + InetAddr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()), + InetAddr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()), + } + } +} + +/* + * + * ===== IpAddr ===== + * + */ +#[allow(missing_docs)] // Since they're all deprecated anyway +#[allow(deprecated)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[deprecated( + since = "0.24.0", + note = "Use std::net::IpAddr instead" +)] +pub enum IpAddr { + V4(Ipv4Addr), + V6(Ipv6Addr), +} + +#[allow(deprecated)] +#[allow(missing_docs)] // Since they're all deprecated anyway +impl IpAddr { + /// Create a new IpAddr that contains an IPv4 address. + /// + /// The result will represent the IP address a.b.c.d + pub const fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr { + IpAddr::V4(Ipv4Addr::new(a, b, c, d)) + } + + /// Create a new IpAddr that contains an IPv6 address. + /// + /// The result will represent the IP address a:b:c:d:e:f + #[allow(clippy::many_single_char_names)] + #[allow(clippy::too_many_arguments)] + pub const fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr { + IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h)) + } + + pub fn from_std(std: &net::IpAddr) -> IpAddr { + match *std { + net::IpAddr::V4(ref std) => IpAddr::V4(Ipv4Addr::from_std(std)), + net::IpAddr::V6(ref std) => IpAddr::V6(Ipv6Addr::from_std(std)), + } + } + + pub const fn to_std(&self) -> net::IpAddr { + match *self { + IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()), + IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()), + } + } +} + +#[allow(deprecated)] +impl fmt::Display for IpAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + IpAddr::V4(ref v4) => v4.fmt(f), + IpAddr::V6(ref v6) => v6.fmt(f) + } + } +} + +/* + * + * ===== Ipv4Addr ===== + * + */ + +#[deprecated( + since = "0.24.0", + note = "Use std::net::Ipv4Addr instead" +)] +#[allow(missing_docs)] // Since they're all deprecated anyway +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct Ipv4Addr(pub libc::in_addr); + +#[allow(deprecated)] +#[allow(missing_docs)] // Since they're all deprecated anyway +impl Ipv4Addr { + #[allow(clippy::identity_op)] // More readable this way + pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { + let ip = (((a as u32) << 24) | + ((b as u32) << 16) | + ((c as u32) << 8) | + ((d as u32) << 0)).to_be(); + + Ipv4Addr(libc::in_addr { s_addr: ip }) + } + + // Use pass by reference for symmetry with Ipv6Addr::from_std + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn from_std(std: &net::Ipv4Addr) -> Ipv4Addr { + let bits = std.octets(); + Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3]) + } + + pub const fn any() -> Ipv4Addr { + Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY }) + } + + pub const fn octets(self) -> [u8; 4] { + let bits = u32::from_be(self.0.s_addr); + [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8] + } + + pub const fn to_std(self) -> net::Ipv4Addr { + let bits = self.octets(); + net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3]) + } +} + +#[allow(deprecated)] +impl fmt::Display for Ipv4Addr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let octets = self.octets(); + write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]) + } +} + +/* + * + * ===== Ipv6Addr ===== + * + */ + +#[deprecated( + since = "0.24.0", + note = "Use std::net::Ipv6Addr instead" +)] +#[allow(missing_docs)] // Since they're all deprecated anyway +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct Ipv6Addr(pub libc::in6_addr); + +// Note that IPv6 addresses are stored in big endian order on all architectures. +// See https://tools.ietf.org/html/rfc1700 or consult your favorite search +// engine. + +macro_rules! to_u8_array { + ($($num:ident),*) => { + [ $(($num>>8) as u8, ($num&0xff) as u8,)* ] + } +} + +macro_rules! to_u16_array { + ($slf:ident, $($first:expr, $second:expr),*) => { + [$( (($slf.0.s6_addr[$first] as u16) << 8) + $slf.0.s6_addr[$second] as u16,)*] + } +} + +#[allow(deprecated)] +#[allow(missing_docs)] // Since they're all deprecated anyway +impl Ipv6Addr { + #[allow(clippy::many_single_char_names)] + #[allow(clippy::too_many_arguments)] + pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr { + Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)}) + } + + pub fn from_std(std: &net::Ipv6Addr) -> Ipv6Addr { + let s = std.segments(); + Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]) + } + + /// Return the eight 16-bit segments that make up this address + pub const fn segments(&self) -> [u16; 8] { + to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) + } + + pub const fn to_std(&self) -> net::Ipv6Addr { + let s = self.segments(); + net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]) + } +} + +#[allow(deprecated)] +impl fmt::Display for Ipv6Addr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.to_std().fmt(fmt) + } +} +} + +/// A wrapper around `sockaddr_un`. +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct UnixAddr { + // INVARIANT: sun & sun_len are valid as defined by docs for from_raw_parts + sun: libc::sockaddr_un, + /// The length of the valid part of `sun`, including the sun_family field + /// but excluding any trailing nul. + // On the BSDs, this field is built into sun + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + sun_len: u8 +} + +// linux man page unix(7) says there are 3 kinds of unix socket: +// pathname: addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1 +// unnamed: addrlen = sizeof(sa_family_t) +// abstract: addren > sizeof(sa_family_t), name = sun_path[..(addrlen - sizeof(sa_family_t))] +// +// what we call path_len = addrlen - offsetof(struct sockaddr_un, sun_path) +#[derive(PartialEq, Eq, Hash)] +enum UnixAddrKind<'a> { + Pathname(&'a Path), + Unnamed, + #[cfg(any(target_os = "android", target_os = "linux"))] + Abstract(&'a [u8]), +} +impl<'a> UnixAddrKind<'a> { + /// Safety: sun & sun_len must be valid + unsafe fn get(sun: &'a libc::sockaddr_un, sun_len: u8) -> Self { + assert!(sun_len as usize >= offset_of!(libc::sockaddr_un, sun_path)); + let path_len = sun_len as usize - offset_of!(libc::sockaddr_un, sun_path); + if path_len == 0 { + return Self::Unnamed; + } + #[cfg(any(target_os = "android", target_os = "linux"))] + if sun.sun_path[0] == 0 { + let name = + slice::from_raw_parts(sun.sun_path.as_ptr().add(1) as *const u8, path_len - 1); + return Self::Abstract(name); + } + let pathname = slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len); + if pathname.last() == Some(&0) { + // A trailing NUL is not considered part of the path, and it does + // not need to be included in the addrlen passed to functions like + // bind(). However, Linux adds a trailing NUL, even if one was not + // originally present, when returning addrs from functions like + // getsockname() (the BSDs do not do that). So we need to filter + // out any trailing NUL here, so sockaddrs can round-trip through + // the kernel and still compare equal. + Self::Pathname(Path::new(OsStr::from_bytes(&pathname[0..pathname.len() - 1]))) + } else { + Self::Pathname(Path::new(OsStr::from_bytes(pathname))) + } + } +} + +impl UnixAddr { + /// Create a new sockaddr_un representing a filesystem path. + pub fn new(path: &P) -> Result { + path.with_nix_path(|cstr| { + unsafe { + let mut ret = libc::sockaddr_un { + sun_family: AddressFamily::Unix as sa_family_t, + .. mem::zeroed() + }; + + let bytes = cstr.to_bytes(); + + if bytes.len() >= ret.sun_path.len() { + return Err(Errno::ENAMETOOLONG); + } + + let sun_len = (bytes.len() + + offset_of!(libc::sockaddr_un, sun_path)).try_into() + .unwrap(); + + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + { + ret.sun_len = sun_len; + } + ptr::copy_nonoverlapping(bytes.as_ptr(), + ret.sun_path.as_mut_ptr() as *mut u8, + bytes.len()); + + Ok(UnixAddr::from_raw_parts(ret, sun_len)) + } + })? + } + + /// Create a new `sockaddr_un` representing an address in the "abstract namespace". + /// + /// The leading nul byte for the abstract namespace is automatically added; + /// thus the input `path` is expected to be the bare name, not NUL-prefixed. + /// This is a Linux-specific extension, primarily used to allow chrooted + /// processes to communicate with processes having a different filesystem view. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_abstract(path: &[u8]) -> Result { + unsafe { + let mut ret = libc::sockaddr_un { + sun_family: AddressFamily::Unix as sa_family_t, + .. mem::zeroed() + }; + + if path.len() >= ret.sun_path.len() { + return Err(Errno::ENAMETOOLONG); + } + let sun_len = (path.len() + + 1 + + offset_of!(libc::sockaddr_un, sun_path)).try_into() + .unwrap(); + + // Abstract addresses are represented by sun_path[0] == + // b'\0', so copy starting one byte in. + ptr::copy_nonoverlapping(path.as_ptr(), + ret.sun_path.as_mut_ptr().offset(1) as *mut u8, + path.len()); + + Ok(UnixAddr::from_raw_parts(ret, sun_len)) + } + } + + /// Create a UnixAddr from a raw `sockaddr_un` struct and a size. `sun_len` + /// is the size of the valid portion of the struct, excluding any trailing + /// NUL. + /// + /// # Safety + /// This pair of sockaddr_un & sun_len must be a valid unix addr, which + /// means: + /// - sun_len >= offset_of(sockaddr_un, sun_path) + /// - sun_len <= sockaddr_un.sun_path.len() - offset_of(sockaddr_un, sun_path) + /// - if this is a unix addr with a pathname, sun.sun_path is a + /// fs path, not necessarily nul-terminated. + pub(crate) unsafe fn from_raw_parts(sun: libc::sockaddr_un, sun_len: u8) -> UnixAddr { + cfg_if!{ + if #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + { + UnixAddr { sun, sun_len } + } else { + assert_eq!(sun_len, sun.sun_len); + UnixAddr {sun} + } + } + } + + fn kind(&self) -> UnixAddrKind<'_> { + // SAFETY: our sockaddr is always valid because of the invariant on the struct + unsafe { UnixAddrKind::get(&self.sun, self.sun_len()) } + } + + /// If this address represents a filesystem path, return that path. + pub fn path(&self) -> Option<&Path> { + match self.kind() { + UnixAddrKind::Pathname(path) => Some(path), + _ => None, + } + } + + /// If this address represents an abstract socket, return its name. + /// + /// For abstract sockets only the bare name is returned, without the + /// leading NUL byte. `None` is returned for unnamed or path-backed sockets. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn as_abstract(&self) -> Option<&[u8]> { + match self.kind() { + UnixAddrKind::Abstract(name) => Some(name), + _ => None, + } + } + + /// Returns the addrlen of this socket - `offsetof(struct sockaddr_un, sun_path)` + #[inline] + pub fn path_len(&self) -> usize { + self.sun_len() as usize - offset_of!(libc::sockaddr_un, sun_path) + } + /// Returns a pointer to the raw `sockaddr_un` struct + #[inline] + pub fn as_ptr(&self) -> *const libc::sockaddr_un { + &self.sun + } + /// Returns a mutable pointer to the raw `sockaddr_un` struct + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut libc::sockaddr_un { + &mut self.sun + } + + fn sun_len(&self)-> u8 { + cfg_if!{ + if #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + { + self.sun_len + } else { + self.sun.sun_len + } + } + } +} + +impl private::SockaddrLikePriv for UnixAddr {} +impl SockaddrLike for UnixAddr { + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + fn len(&self) -> libc::socklen_t { + self.sun_len.into() + } + + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if (l as usize) < offset_of!(libc::sockaddr_un, sun_path) || + l > u8::MAX as libc::socklen_t + { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_UNIX { + return None; + } + let mut su: libc::sockaddr_un = mem::zeroed(); + let sup = &mut su as *mut libc::sockaddr_un as *mut u8; + cfg_if!{ + if #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] { + let su_len = len.unwrap_or( + mem::size_of::() as libc::socklen_t + ); + } else { + let su_len = len.unwrap_or((*addr).sa_len as libc::socklen_t); + } + }; + ptr::copy(addr as *const u8, sup, su_len as usize); + Some(Self::from_raw_parts(su, su_len as u8)) + } + + fn size() -> libc::socklen_t where Self: Sized { + mem::size_of::() as libc::socklen_t + } +} + +impl AsRef for UnixAddr { + fn as_ref(&self) -> &libc::sockaddr_un { + &self.sun + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +fn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result { + use fmt::Write; + f.write_str("@\"")?; + for &b in abs { + use fmt::Display; + char::from(b).escape_default().fmt(f)?; + } + f.write_char('"')?; + Ok(()) +} + +impl fmt::Display for UnixAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.kind() { + UnixAddrKind::Pathname(path) => path.display().fmt(f), + UnixAddrKind::Unnamed => f.pad(""), + #[cfg(any(target_os = "android", target_os = "linux"))] + UnixAddrKind::Abstract(name) => fmt_abstract(name, f), + } + } +} + +impl PartialEq for UnixAddr { + fn eq(&self, other: &UnixAddr) -> bool { + self.kind() == other.kind() + } +} + +impl Eq for UnixAddr {} + +impl Hash for UnixAddr { + fn hash(&self, s: &mut H) { + self.kind().hash(s) + } +} + +/// Anything that, in C, can be cast back and forth to `sockaddr`. +/// +/// Most implementors also implement `AsRef` to access their +/// inner type read-only. +#[allow(clippy::len_without_is_empty)] +pub trait SockaddrLike: private::SockaddrLikePriv { + /// Returns a raw pointer to the inner structure. Useful for FFI. + fn as_ptr(&self) -> *const libc::sockaddr { + self as *const Self as *const libc::sockaddr + } + + /// Unsafe constructor from a variable length source + /// + /// Some C APIs from provide `len`, and others do not. If it's provided it + /// will be validated. If not, it will be guessed based on the family. + /// + /// # Arguments + /// + /// - `addr`: raw pointer to something that can be cast to a + /// `libc::sockaddr`. For example, `libc::sockaddr_in`, + /// `libc::sockaddr_in6`, etc. + /// - `len`: For fixed-width types like `sockaddr_in`, it will be + /// validated if present and ignored if not. For variable-width + /// types it is required and must be the total length of valid + /// data. For example, if `addr` points to a + /// named `sockaddr_un`, then `len` must be the length of the + /// structure up to but not including the trailing NUL. + /// + /// # Safety + /// + /// `addr` must be valid for the specific type of sockaddr. `len`, if + /// present, must not exceed the length of valid data in `addr`. + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized; + + /// Return the address family of this socket + /// + /// # Examples + /// One common use is to match on the family of a union type, like this: + /// ``` + /// # use nix::sys::socket::*; + /// let fd = socket(AddressFamily::Inet, SockType::Stream, + /// SockFlag::empty(), None).unwrap(); + /// let ss: SockaddrStorage = getsockname(fd).unwrap(); + /// match ss.family().unwrap() { + /// AddressFamily::Inet => println!("{}", ss.as_sockaddr_in().unwrap()), + /// AddressFamily::Inet6 => println!("{}", ss.as_sockaddr_in6().unwrap()), + /// _ => println!("Unexpected address family") + /// } + /// ``` + fn family(&self) -> Option { + // Safe since all implementors have a sa_family field at the same + // address, and they're all repr(C) + AddressFamily::from_i32( + unsafe { + (*(self as *const Self as *const libc::sockaddr)).sa_family as i32 + } + ) + } + + cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] { + /// Return the length of valid data in the sockaddr structure. + /// + /// For fixed-size sockaddrs, this should be the size of the + /// structure. But for variable-sized types like [`UnixAddr`] it + /// may be less. + fn len(&self) -> libc::socklen_t { + // Safe since all implementors have a sa_len field at the same + // address, and they're all repr(transparent). + // Robust for all implementors. + unsafe { + (*(self as *const Self as *const libc::sockaddr)).sa_len + }.into() + } + } else { + /// Return the length of valid data in the sockaddr structure. + /// + /// For fixed-size sockaddrs, this should be the size of the + /// structure. But for variable-sized types like [`UnixAddr`] it + /// may be less. + fn len(&self) -> libc::socklen_t { + // No robust default implementation is possible without an + // sa_len field. Implementors with a variable size must + // override this method. + mem::size_of_val(self) as libc::socklen_t + } + } + } + + /// Return the available space in the structure + fn size() -> libc::socklen_t where Self: Sized { + mem::size_of::() as libc::socklen_t + } +} + +impl private::SockaddrLikePriv for () { + fn as_mut_ptr(&mut self) -> *mut libc::sockaddr { + ptr::null_mut() + } +} + +/// `()` can be used in place of a real Sockaddr when no address is expected, +/// for example for a field of `Option where S: SockaddrLike`. +// If this RFC ever stabilizes, then ! will be a better choice. +// https://github.com/rust-lang/rust/issues/35121 +impl SockaddrLike for () { + fn as_ptr(&self) -> *const libc::sockaddr { + ptr::null() + } + + unsafe fn from_raw(_: *const libc::sockaddr, _: Option) + -> Option where Self: Sized + { + None + } + + fn family(&self) -> Option { + None + } + + fn len(&self) -> libc::socklen_t { + 0 + } +} + +/// An IPv4 socket address +// This is identical to net::SocketAddrV4. But the standard library +// doesn't allow direct access to the libc fields, which we need. So we +// reimplement it here. +#[cfg(feature = "net")] +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct SockaddrIn(libc::sockaddr_in); + +#[cfg(feature = "net")] +impl SockaddrIn { + /// Returns the IP address associated with this socket address, in native + /// endian. + pub const fn ip(&self) -> libc::in_addr_t { + u32::from_be(self.0.sin_addr.s_addr) + } + + /// Creates a new socket address from IPv4 octets and a port number. + pub fn new(a: u8, b: u8, c: u8, d: u8, port: u16) -> Self { + Self(libc::sockaddr_in { + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "haiku", + target_os = "openbsd"))] + sin_len: Self::size() as u8, + sin_family: AddressFamily::Inet as sa_family_t, + sin_port: u16::to_be(port), + sin_addr: libc::in_addr { + s_addr: u32::from_ne_bytes([a, b, c, d]) + }, + sin_zero: unsafe{mem::zeroed()} + }) + } + + /// Returns the port number associated with this socket address, in native + /// endian. + pub const fn port(&self) -> u16 { + u16::from_be(self.0.sin_port) + } +} + +#[cfg(feature = "net")] +impl private::SockaddrLikePriv for SockaddrIn {} +#[cfg(feature = "net")] +impl SockaddrLike for SockaddrIn { + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_INET { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } +} + +#[cfg(feature = "net")] +impl AsRef for SockaddrIn { + fn as_ref(&self) -> &libc::sockaddr_in { + &self.0 + } +} + +#[cfg(feature = "net")] +impl fmt::Display for SockaddrIn { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let ne = u32::from_be(self.0.sin_addr.s_addr); + let port = u16::from_be(self.0.sin_port); + write!(f, "{}.{}.{}.{}:{}", + ne >> 24, + (ne >> 16) & 0xFF, + (ne >> 8) & 0xFF, + ne & 0xFF, + port) + } +} + +#[cfg(feature = "net")] +impl From for SockaddrIn { + fn from(addr: net::SocketAddrV4) -> Self { + Self(libc::sockaddr_in{ + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "hermit", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + sin_len: mem::size_of::() as u8, + sin_family: AddressFamily::Inet as sa_family_t, + sin_port: addr.port().to_be(), // network byte order + sin_addr: ipv4addr_to_libc(*addr.ip()), + .. unsafe { mem::zeroed() } + }) + } +} + +#[cfg(feature = "net")] +impl From for net::SocketAddrV4 { + fn from(addr: SockaddrIn) -> Self { + net::SocketAddrV4::new( + net::Ipv4Addr::from(addr.0.sin_addr.s_addr.to_ne_bytes()), + u16::from_be(addr.0.sin_port) + ) + } +} + +#[cfg(feature = "net")] +impl std::str::FromStr for SockaddrIn { + type Err = net::AddrParseError; + + fn from_str(s: &str) -> std::result::Result { + net::SocketAddrV4::from_str(s).map(SockaddrIn::from) + } +} + +/// An IPv6 socket address +#[cfg(feature = "net")] +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct SockaddrIn6(libc::sockaddr_in6); + +#[cfg(feature = "net")] +impl SockaddrIn6 { + /// Returns the flow information associated with this address. + pub const fn flowinfo(&self) -> u32 { + self.0.sin6_flowinfo + } + + /// Returns the IP address associated with this socket address. + pub fn ip(&self) -> net::Ipv6Addr { + net::Ipv6Addr::from(self.0.sin6_addr.s6_addr) + } + + /// Returns the port number associated with this socket address, in native + /// endian. + pub const fn port(&self) -> u16 { + u16::from_be(self.0.sin6_port) + } + + /// Returns the scope ID associated with this address. + pub const fn scope_id(&self) -> u32 { + self.0.sin6_scope_id + } +} + +#[cfg(feature = "net")] +impl private::SockaddrLikePriv for SockaddrIn6 {} +#[cfg(feature = "net")] +impl SockaddrLike for SockaddrIn6 { + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_INET6 { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } +} + +#[cfg(feature = "net")] +impl AsRef for SockaddrIn6 { + fn as_ref(&self) -> &libc::sockaddr_in6 { + &self.0 + } +} + +#[cfg(feature = "net")] +impl fmt::Display for SockaddrIn6 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // These things are really hard to display properly. Easier to let std + // do it. + let std = net::SocketAddrV6::new(self.ip(), self.port(), + self.flowinfo(), self.scope_id()); + std.fmt(f) + } +} + +#[cfg(feature = "net")] +impl From for SockaddrIn6 { + fn from(addr: net::SocketAddrV6) -> Self { + #[allow(clippy::needless_update)] // It isn't needless on Illumos + Self(libc::sockaddr_in6{ + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "hermit", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + sin6_len: mem::size_of::() as u8, + sin6_family: AddressFamily::Inet6 as sa_family_t, + sin6_port: addr.port().to_be(), // network byte order + sin6_addr: ipv6addr_to_libc(addr.ip()), + sin6_flowinfo: addr.flowinfo(), // host byte order + sin6_scope_id: addr.scope_id(), // host byte order + .. unsafe { mem::zeroed() } + }) + } +} + +#[cfg(feature = "net")] +impl From for net::SocketAddrV6 { + fn from(addr: SockaddrIn6) -> Self { + net::SocketAddrV6::new( + net::Ipv6Addr::from(addr.0.sin6_addr.s6_addr), + u16::from_be(addr.0.sin6_port), + u32::from_be(addr.0.sin6_flowinfo), + u32::from_be(addr.0.sin6_scope_id) + ) + } +} + +#[cfg(feature = "net")] +impl std::str::FromStr for SockaddrIn6 { + type Err = net::AddrParseError; + + fn from_str(s: &str) -> std::result::Result { + net::SocketAddrV6::from_str(s).map(SockaddrIn6::from) + } +} + + +/// A container for any sockaddr type +/// +/// Just like C's `sockaddr_storage`, this type is large enough to hold any type +/// of sockaddr. It can be used as an argument with functions like +/// [`bind`](super::bind) and [`getsockname`](super::getsockname). Though it is +/// a union, it can be safely accessed through the `as_*` methods. +/// +/// # Example +/// ``` +/// # use nix::sys::socket::*; +/// # use std::str::FromStr; +/// let localhost = SockaddrIn::from_str("127.0.0.1:8081").unwrap(); +/// let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), +/// None).unwrap(); +/// bind(fd, &localhost).expect("bind"); +/// let ss: SockaddrStorage = getsockname(fd).expect("getsockname"); +/// assert_eq!(&localhost, ss.as_sockaddr_in().unwrap()); +/// ``` +#[derive(Clone, Copy, Eq)] +#[repr(C)] +pub union SockaddrStorage { + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + alg: AlgAddr, + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + dl: LinkAddr, + #[cfg(any(target_os = "android", target_os = "linux"))] + nl: NetlinkAddr, + #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))] + #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] + sctl: SysControlAddr, + #[cfg(feature = "net")] + sin: SockaddrIn, + #[cfg(feature = "net")] + sin6: SockaddrIn6, + ss: libc::sockaddr_storage, + su: UnixAddr, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + vsock: VsockAddr +} +impl private::SockaddrLikePriv for SockaddrStorage {} +impl SockaddrLike for SockaddrStorage { + unsafe fn from_raw(addr: *const libc::sockaddr, l: Option) + -> Option where Self: Sized + { + if addr.is_null() { + return None; + } + if let Some(len) = l { + let ulen = len as usize; + if ulen < offset_of!(libc::sockaddr, sa_data) || + ulen > mem::size_of::() { + None + } else{ + let mut ss: libc::sockaddr_storage = mem::zeroed(); + let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8; + ptr::copy(addr as *const u8, ssp, len as usize); + #[cfg(any( + target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + if i32::from(ss.ss_family) == libc::AF_UNIX { + // Safe because we UnixAddr is strictly smaller than + // SockaddrStorage, and we just initialized the structure. + (*(&mut ss as *mut libc::sockaddr_storage as *mut UnixAddr)).sun_len = len as u8; + } + Some(Self { ss }) + } + } else { + // If length is not available and addr is of a fixed-length type, + // copy it. If addr is of a variable length type and len is not + // available, then there's nothing we can do. + match (*addr).sa_family as i32 { + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_ALG => AlgAddr::from_raw(addr, l) + .map(|alg| Self { alg}), + #[cfg(feature = "net")] + libc::AF_INET => SockaddrIn::from_raw(addr, l) + .map(|sin| Self{ sin}), + #[cfg(feature = "net")] + libc::AF_INET6 => SockaddrIn6::from_raw(addr, l) + .map(|sin6| Self{ sin6}), + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "haiku", + target_os = "openbsd"))] + #[cfg(feature = "net")] + libc::AF_LINK => LinkAddr::from_raw(addr, l) + .map(|dl| Self{ dl}), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => NetlinkAddr::from_raw(addr, l) + .map(|nl| Self{ nl }), + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg(feature = "net")] + libc::AF_PACKET => LinkAddr::from_raw(addr, l) + .map(|dl| Self{ dl}), + #[cfg(all(feature = "ioctl", + any(target_os = "ios", target_os = "macos")))] + libc::AF_SYSTEM => SysControlAddr::from_raw(addr, l) + .map(|sctl| Self {sctl}), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => VsockAddr::from_raw(addr, l) + .map(|vsock| Self{vsock}), + _ => None + } + } + } + + #[cfg(any( + target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + fn len(&self) -> libc::socklen_t { + match self.as_unix_addr() { + // The UnixAddr type knows its own length + Some(ua) => ua.len(), + // For all else, we're just a boring SockaddrStorage + None => mem::size_of_val(self) as libc::socklen_t + } + } +} + +macro_rules! accessors { + ( + $fname:ident, + $fname_mut:ident, + $sockty:ty, + $family:expr, + $libc_ty:ty, + $field:ident) => + { + /// Safely and falliably downcast to an immutable reference + pub fn $fname(&self) -> Option<&$sockty> { + if self.family() == Some($family) && + self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t + { + // Safe because family and len are validated + Some(unsafe{&self.$field}) + } else { + None + } + } + + /// Safely and falliably downcast to a mutable reference + pub fn $fname_mut(&mut self) -> Option<&mut $sockty> { + if self.family() == Some($family) && + self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t + { + // Safe because family and len are validated + Some(unsafe{&mut self.$field}) + } else { + None + } + } + } +} + +impl SockaddrStorage { + /// Downcast to an immutable `[UnixAddr]` reference. + pub fn as_unix_addr(&self) -> Option<&UnixAddr> { + cfg_if! { + if #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + { + let p = unsafe{ &self.ss as *const libc::sockaddr_storage }; + // Safe because UnixAddr is strictly smaller than + // sockaddr_storage, and we're fully initialized + let len = unsafe { + (*(p as *const UnixAddr )).sun_len as usize + }; + } else { + let len = self.len() as usize; + } + } + // Sanity checks + if self.family() != Some(AddressFamily::Unix) || + len < offset_of!(libc::sockaddr_un, sun_path) || + len > mem::size_of::() { + None + } else { + Some(unsafe{&self.su}) + } + } + + /// Downcast to a mutable `[UnixAddr]` reference. + pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> { + cfg_if! { + if #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux" + ))] + { + let p = unsafe{ &self.ss as *const libc::sockaddr_storage }; + // Safe because UnixAddr is strictly smaller than + // sockaddr_storage, and we're fully initialized + let len = unsafe { + (*(p as *const UnixAddr )).sun_len as usize + }; + } else { + let len = self.len() as usize; + } + } + // Sanity checks + if self.family() != Some(AddressFamily::Unix) || + len < offset_of!(libc::sockaddr_un, sun_path) || + len > mem::size_of::() { + None + } else { + Some(unsafe{&mut self.su}) + } + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + accessors!{as_alg_addr, as_alg_addr_mut, AlgAddr, + AddressFamily::Alg, libc::sockaddr_alg, alg} + + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "linux"))] + #[cfg(feature = "net")] + accessors!{ + as_link_addr, as_link_addr_mut, LinkAddr, + AddressFamily::Packet, libc::sockaddr_ll, dl} + + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg(feature = "net")] + accessors!{ + as_link_addr, as_link_addr_mut, LinkAddr, + AddressFamily::Link, libc::sockaddr_dl, dl} + + #[cfg(feature = "net")] + accessors!{ + as_sockaddr_in, as_sockaddr_in_mut, SockaddrIn, + AddressFamily::Inet, libc::sockaddr_in, sin} + + #[cfg(feature = "net")] + accessors!{ + as_sockaddr_in6, as_sockaddr_in6_mut, SockaddrIn6, + AddressFamily::Inet6, libc::sockaddr_in6, sin6} + + #[cfg(any(target_os = "android", target_os = "linux"))] + accessors!{as_netlink_addr, as_netlink_addr_mut, NetlinkAddr, + AddressFamily::Netlink, libc::sockaddr_nl, nl} + + #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))] + #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] + accessors!{as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr, + AddressFamily::System, libc::sockaddr_ctl, sctl} + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + accessors!{as_vsock_addr, as_vsock_addr_mut, VsockAddr, + AddressFamily::Vsock, libc::sockaddr_vm, vsock} +} + +impl fmt::Debug for SockaddrStorage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SockaddrStorage") + // Safe because sockaddr_storage has the least specific + // field types + .field("ss", unsafe{&self.ss}) + .finish() + } +} + +impl fmt::Display for SockaddrStorage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + unsafe { + match self.ss.ss_family as i32 { + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_ALG => self.alg.fmt(f), + #[cfg(feature = "net")] + libc::AF_INET => self.sin.fmt(f), + #[cfg(feature = "net")] + libc::AF_INET6 => self.sin6.fmt(f), + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg(feature = "net")] + libc::AF_LINK => self.dl.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => self.nl.fmt(f), + #[cfg(any(target_os = "android", + target_os = "linux", + target_os = "fuchsia" + ))] + #[cfg(feature = "net")] + libc::AF_PACKET => self.dl.fmt(f), + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg(feature = "ioctl")] + libc::AF_SYSTEM => self.sctl.fmt(f), + libc::AF_UNIX => self.su.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => self.vsock.fmt(f), + _ => "

".fmt(f) + } + } + } +} + +#[cfg(feature = "net")] +impl From for SockaddrStorage { + fn from(s: net::SocketAddrV4) -> Self { + unsafe { + let mut ss: Self = mem::zeroed(); + ss.sin = SockaddrIn::from(s); + ss + } + } +} + +#[cfg(feature = "net")] +impl From for SockaddrStorage { + fn from(s: net::SocketAddrV6) -> Self { + unsafe { + let mut ss: Self = mem::zeroed(); + ss.sin6 = SockaddrIn6::from(s); + ss + } + } +} + +#[cfg(feature = "net")] +impl From for SockaddrStorage { + fn from(s: net::SocketAddr) -> Self { + match s { + net::SocketAddr::V4(sa4) => Self::from(sa4), + net::SocketAddr::V6(sa6) => Self::from(sa6), + } + } +} + +impl Hash for SockaddrStorage { + fn hash(&self, s: &mut H) { + unsafe { + match self.ss.ss_family as i32 { + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_ALG => self.alg.hash(s), + #[cfg(feature = "net")] + libc::AF_INET => self.sin.hash(s), + #[cfg(feature = "net")] + libc::AF_INET6 => self.sin6.hash(s), + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg(feature = "net")] + libc::AF_LINK => self.dl.hash(s), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => self.nl.hash(s), + #[cfg(any(target_os = "android", + target_os = "linux", + target_os = "fuchsia" + ))] + #[cfg(feature = "net")] + libc::AF_PACKET => self.dl.hash(s), + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg(feature = "ioctl")] + libc::AF_SYSTEM => self.sctl.hash(s), + libc::AF_UNIX => self.su.hash(s), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => self.vsock.hash(s), + _ => self.ss.hash(s) + } + } + } +} + +impl PartialEq for SockaddrStorage { + fn eq(&self, other: &Self) -> bool { + unsafe { + match (self.ss.ss_family as i32, other.ss.ss_family as i32) { + #[cfg(any(target_os = "android", target_os = "linux"))] + (libc::AF_ALG, libc::AF_ALG) => self.alg == other.alg, + #[cfg(feature = "net")] + (libc::AF_INET, libc::AF_INET) => self.sin == other.sin, + #[cfg(feature = "net")] + (libc::AF_INET6, libc::AF_INET6) => self.sin6 == other.sin6, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg(feature = "net")] + (libc::AF_LINK, libc::AF_LINK) => self.dl == other.dl, + #[cfg(any(target_os = "android", target_os = "linux"))] + (libc::AF_NETLINK, libc::AF_NETLINK) => self.nl == other.nl, + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg(feature = "net")] + (libc::AF_PACKET, libc::AF_PACKET) => self.dl == other.dl, + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg(feature = "ioctl")] + (libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl, + (libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su, + #[cfg(any(target_os = "android", target_os = "linux"))] + (libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock, + _ => false, + } + } + } +} + +mod private { + pub trait SockaddrLikePriv { + /// Returns a mutable raw pointer to the inner structure. + /// + /// # Safety + /// + /// This method is technically safe, but modifying the inner structure's + /// `family` or `len` fields may result in violating Nix's invariants. + /// It is best to use this method only with foreign functions that do + /// not change the sockaddr type. + fn as_mut_ptr(&mut self) -> *mut libc::sockaddr { + self as *mut Self as *mut libc::sockaddr + } + } +} + +/// Represents a socket address +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[deprecated( + since = "0.24.0", + note = "use SockaddrLike or SockaddrStorage instead" +)] +#[allow(missing_docs)] // Since they're all deprecated anyway +#[allow(deprecated)] +#[non_exhaustive] +pub enum SockAddr { + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Inet(InetAddr), + Unix(UnixAddr), + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Netlink(NetlinkAddr), + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Alg(AlgAddr), + #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))] + #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] + SysControl(SysControlAddr), + /// Datalink address (MAC) + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Link(LinkAddr), + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + Vsock(VsockAddr), +} + +#[allow(missing_docs)] // Since they're all deprecated anyway +#[allow(deprecated)] +impl SockAddr { + feature! { + #![feature = "net"] + pub fn new_inet(addr: InetAddr) -> SockAddr { + SockAddr::Inet(addr) + } + } + + pub fn new_unix(path: &P) -> Result { + Ok(SockAddr::Unix(UnixAddr::new(path)?)) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_netlink(pid: u32, groups: u32) -> SockAddr { + SockAddr::Netlink(NetlinkAddr::new(pid, groups)) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_alg(alg_type: &str, alg_name: &str) -> SockAddr { + SockAddr::Alg(AlgAddr::new(alg_type, alg_name)) + } + + feature! { + #![feature = "ioctl"] + #[cfg(any(target_os = "ios", target_os = "macos"))] + pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result { + SysControlAddr::from_name(sockfd, name, unit).map(SockAddr::SysControl) + } + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_vsock(cid: u32, port: u32) -> SockAddr { + SockAddr::Vsock(VsockAddr::new(cid, port)) + } + + pub fn family(&self) -> AddressFamily { + match *self { + #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet, + #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6, + SockAddr::Unix(..) => AddressFamily::Unix, + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Netlink(..) => AddressFamily::Netlink, + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Alg(..) => AddressFamily::Alg, + #[cfg(all(feature = "ioctl", + any(target_os = "ios", target_os = "macos")))] + SockAddr::SysControl(..) => AddressFamily::System, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + SockAddr::Link(..) => AddressFamily::Packet, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] + #[cfg(feature = "net")] + SockAddr::Link(..) => AddressFamily::Link, + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Vsock(..) => AddressFamily::Vsock, + } + } + + #[deprecated(since = "0.23.0", note = "use .to_string() instead")] + pub fn to_str(&self) -> String { + format!("{}", self) + } + + /// Creates a `SockAddr` struct from libc's sockaddr. + /// + /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System. + /// Returns None for unsupported families. + /// + /// # Safety + /// + /// unsafe because it takes a raw pointer as argument. The caller must + /// ensure that the pointer is valid. + #[cfg(not(target_os = "fuchsia"))] + #[cfg(feature = "net")] + pub(crate) unsafe fn from_libc_sockaddr(addr: *const libc::sockaddr) -> Option { + if addr.is_null() { + None + } else { + match AddressFamily::from_i32(i32::from((*addr).sa_family)) { + Some(AddressFamily::Unix) => None, + #[cfg(feature = "net")] + Some(AddressFamily::Inet) => Some(SockAddr::Inet( + InetAddr::V4(ptr::read_unaligned(addr as *const _)))), + #[cfg(feature = "net")] + Some(AddressFamily::Inet6) => Some(SockAddr::Inet( + InetAddr::V6(ptr::read_unaligned(addr as *const _)))), + #[cfg(any(target_os = "android", target_os = "linux"))] + Some(AddressFamily::Netlink) => Some(SockAddr::Netlink( + NetlinkAddr(ptr::read_unaligned(addr as *const _)))), + #[cfg(all(feature = "ioctl", + any(target_os = "ios", target_os = "macos")))] + Some(AddressFamily::System) => Some(SockAddr::SysControl( + SysControlAddr(ptr::read_unaligned(addr as *const _)))), + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + Some(AddressFamily::Packet) => Some(SockAddr::Link( + LinkAddr(ptr::read_unaligned(addr as *const _)))), + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] + #[cfg(feature = "net")] + Some(AddressFamily::Link) => { + let ether_addr = LinkAddr(ptr::read_unaligned(addr as *const _)); + if ether_addr.is_empty() { + None + } else { + Some(SockAddr::Link(ether_addr)) + } + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + Some(AddressFamily::Vsock) => Some(SockAddr::Vsock( + VsockAddr(ptr::read_unaligned(addr as *const _)))), + // Other address families are currently not supported and simply yield a None + // entry instead of a proper conversion to a `SockAddr`. + Some(_) | None => None, + } + } + } + + /// Conversion from nix's SockAddr type to the underlying libc sockaddr type. + /// + /// This is useful for interfacing with other libc functions that don't yet have nix wrappers. + /// Returns a reference to the underlying data type (as a sockaddr reference) along + /// with the size of the actual data type. sockaddr is commonly used as a proxy for + /// a superclass as C doesn't support inheritance, so many functions that take + /// a sockaddr * need to take the size of the underlying type as well and then internally cast it back. + pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) { + match *self { + #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V4(ref addr)) => ( + // This cast is always allowed in C + unsafe { + &*(addr as *const libc::sockaddr_in as *const libc::sockaddr) + }, + mem::size_of_val(addr) as libc::socklen_t + ), + #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V6(ref addr)) => ( + // This cast is always allowed in C + unsafe { + &*(addr as *const libc::sockaddr_in6 as *const libc::sockaddr) + }, + mem::size_of_val(addr) as libc::socklen_t + ), + SockAddr::Unix(ref unix_addr) => ( + // This cast is always allowed in C + unsafe { + &*(&unix_addr.sun as *const libc::sockaddr_un as *const libc::sockaddr) + }, + unix_addr.sun_len() as libc::socklen_t + ), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Netlink(NetlinkAddr(ref sa)) => ( + // This cast is always allowed in C + unsafe { + &*(sa as *const libc::sockaddr_nl as *const libc::sockaddr) + }, + mem::size_of_val(sa) as libc::socklen_t + ), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Alg(AlgAddr(ref sa)) => ( + // This cast is always allowed in C + unsafe { + &*(sa as *const libc::sockaddr_alg as *const libc::sockaddr) + }, + mem::size_of_val(sa) as libc::socklen_t + ), + #[cfg(all(feature = "ioctl", + any(target_os = "ios", target_os = "macos")))] + SockAddr::SysControl(SysControlAddr(ref sa)) => ( + // This cast is always allowed in C + unsafe { + &*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr) + }, + mem::size_of_val(sa) as libc::socklen_t + + ), + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + SockAddr::Link(LinkAddr(ref addr)) => ( + // This cast is always allowed in C + unsafe { + &*(addr as *const libc::sockaddr_ll as *const libc::sockaddr) + }, + mem::size_of_val(addr) as libc::socklen_t + ), + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg(feature = "net")] + SockAddr::Link(LinkAddr(ref addr)) => ( + // This cast is always allowed in C + unsafe { + &*(addr as *const libc::sockaddr_dl as *const libc::sockaddr) + }, + mem::size_of_val(addr) as libc::socklen_t + ), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Vsock(VsockAddr(ref sa)) => ( + // This cast is always allowed in C + unsafe { + &*(sa as *const libc::sockaddr_vm as *const libc::sockaddr) + }, + mem::size_of_val(sa) as libc::socklen_t + ), + } + } +} + +#[allow(deprecated)] +impl fmt::Display for SockAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + #[cfg(feature = "net")] + SockAddr::Inet(ref inet) => inet.fmt(f), + SockAddr::Unix(ref unix) => unix.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Netlink(ref nl) => nl.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Alg(ref nl) => nl.fmt(f), + #[cfg(all(feature = "ioctl", + any(target_os = "ios", target_os = "macos")))] + SockAddr::SysControl(ref sc) => sc.fmt(f), + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] + #[cfg(feature = "net")] + SockAddr::Link(ref ether_addr) => ether_addr.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Vsock(ref svm) => svm.fmt(f), + } + } +} + +#[cfg(not(target_os = "fuchsia"))] +#[cfg(feature = "net")] +#[allow(deprecated)] +impl private::SockaddrLikePriv for SockAddr {} +#[cfg(not(target_os = "fuchsia"))] +#[cfg(feature = "net")] +#[allow(deprecated)] +impl SockaddrLike for SockAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, _len: Option) + -> Option + { + Self::from_libc_sockaddr(addr) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub mod netlink { + use crate::sys::socket::addr::AddressFamily; + use libc::{sa_family_t, sockaddr_nl}; + use std::{fmt, mem}; + use super::*; + + /// Address for the Linux kernel user interface device. + /// + /// # References + /// + /// [netlink(7)](https://man7.org/linux/man-pages/man7/netlink.7.html) + #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] + #[repr(transparent)] + pub struct NetlinkAddr(pub(in super::super) sockaddr_nl); + + impl NetlinkAddr { + /// Construct a new socket address from its port ID and multicast groups + /// mask. + pub fn new(pid: u32, groups: u32) -> NetlinkAddr { + let mut addr: sockaddr_nl = unsafe { mem::zeroed() }; + addr.nl_family = AddressFamily::Netlink as sa_family_t; + addr.nl_pid = pid; + addr.nl_groups = groups; + + NetlinkAddr(addr) + } + + /// Return the socket's port ID. + pub const fn pid(&self) -> u32 { + self.0.nl_pid + } + + /// Return the socket's multicast groups mask + pub const fn groups(&self) -> u32 { + self.0.nl_groups + } + } + + impl private::SockaddrLikePriv for NetlinkAddr {} + impl SockaddrLike for NetlinkAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_NETLINK { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } + } + + impl AsRef for NetlinkAddr { + fn as_ref(&self) -> &libc::sockaddr_nl { + &self.0 + } + } + + impl fmt::Display for NetlinkAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "pid: {} groups: {}", self.pid(), self.groups()) + } + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub mod alg { + use libc::{AF_ALG, sockaddr_alg, c_char}; + use std::{fmt, mem, str}; + use std::hash::{Hash, Hasher}; + use std::ffi::CStr; + use super::*; + + /// Socket address for the Linux kernel crypto API + #[derive(Copy, Clone)] + #[repr(transparent)] + pub struct AlgAddr(pub(in super::super) sockaddr_alg); + + impl private::SockaddrLikePriv for AlgAddr {} + impl SockaddrLike for AlgAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, l: Option) + -> Option where Self: Sized + { + if let Some(l) = l { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_ALG { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } + } + + impl AsRef for AlgAddr { + fn as_ref(&self) -> &libc::sockaddr_alg { + &self.0 + } + } + + // , PartialEq, Eq, Debug, Hash + impl PartialEq for AlgAddr { + fn eq(&self, other: &Self) -> bool { + let (inner, other) = (self.0, other.0); + (inner.salg_family, &inner.salg_type[..], inner.salg_feat, inner.salg_mask, &inner.salg_name[..]) == + (other.salg_family, &other.salg_type[..], other.salg_feat, other.salg_mask, &other.salg_name[..]) + } + } + + impl Eq for AlgAddr {} + + impl Hash for AlgAddr { + fn hash(&self, s: &mut H) { + let inner = self.0; + (inner.salg_family, &inner.salg_type[..], inner.salg_feat, inner.salg_mask, &inner.salg_name[..]).hash(s); + } + } + + impl AlgAddr { + /// Construct an `AF_ALG` socket from its cipher name and type. + pub fn new(alg_type: &str, alg_name: &str) -> AlgAddr { + let mut addr: sockaddr_alg = unsafe { mem::zeroed() }; + addr.salg_family = AF_ALG as u16; + addr.salg_type[..alg_type.len()].copy_from_slice(alg_type.to_string().as_bytes()); + addr.salg_name[..alg_name.len()].copy_from_slice(alg_name.to_string().as_bytes()); + + AlgAddr(addr) + } + + + /// Return the socket's cipher type, for example `hash` or `aead`. + pub fn alg_type(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char) } + } + + /// Return the socket's cipher name, for example `sha1`. + pub fn alg_name(&self) -> &CStr { + unsafe { CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char) } + } + } + + impl fmt::Display for AlgAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "type: {} alg: {}", + self.alg_name().to_string_lossy(), + self.alg_type().to_string_lossy()) + } + } + + impl fmt::Debug for AlgAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } + } +} + +feature! { +#![feature = "ioctl"] +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub mod sys_control { + use crate::sys::socket::addr::AddressFamily; + use libc::{self, c_uchar}; + use std::{fmt, mem, ptr}; + use std::os::unix::io::RawFd; + use crate::{Errno, Result}; + use super::{private, SockaddrLike}; + + // FIXME: Move type into `libc` + #[repr(C)] + #[derive(Clone, Copy)] + #[allow(missing_debug_implementations)] + pub struct ctl_ioc_info { + pub ctl_id: u32, + pub ctl_name: [c_uchar; MAX_KCTL_NAME], + } + + const CTL_IOC_MAGIC: u8 = b'N'; + const CTL_IOC_INFO: u8 = 3; + const MAX_KCTL_NAME: usize = 96; + + ioctl_readwrite!(ctl_info, CTL_IOC_MAGIC, CTL_IOC_INFO, ctl_ioc_info); + + /// Apple system control socket + /// + /// # References + /// + /// https://developer.apple.com/documentation/kernel/sockaddr_ctl + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + #[repr(transparent)] + pub struct SysControlAddr(pub(in super::super) libc::sockaddr_ctl); + + impl private::SockaddrLikePriv for SysControlAddr {} + impl SockaddrLike for SysControlAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_SYSTEM { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } + } + + impl AsRef for SysControlAddr { + fn as_ref(&self) -> &libc::sockaddr_ctl { + &self.0 + } + } + + impl SysControlAddr { + /// Construct a new `SysControlAddr` from its kernel unique identifier + /// and unit number. + pub const fn new(id: u32, unit: u32) -> SysControlAddr { + let addr = libc::sockaddr_ctl { + sc_len: mem::size_of::() as c_uchar, + sc_family: AddressFamily::System as c_uchar, + ss_sysaddr: libc::AF_SYS_CONTROL as u16, + sc_id: id, + sc_unit: unit, + sc_reserved: [0; 5] + }; + + SysControlAddr(addr) + } + + /// Construct a new `SysControlAddr` from its human readable name and + /// unit number. + pub fn from_name(sockfd: RawFd, name: &str, unit: u32) -> Result { + if name.len() > MAX_KCTL_NAME { + return Err(Errno::ENAMETOOLONG); + } + + let mut ctl_name = [0; MAX_KCTL_NAME]; + ctl_name[..name.len()].clone_from_slice(name.as_bytes()); + let mut info = ctl_ioc_info { ctl_id: 0, ctl_name }; + + unsafe { ctl_info(sockfd, &mut info)?; } + + Ok(SysControlAddr::new(info.ctl_id, unit)) + } + + /// Return the kernel unique identifier + pub const fn id(&self) -> u32 { + self.0.sc_id + } + + /// Return the kernel controller private unit number. + pub const fn unit(&self) -> u32 { + self.0.sc_unit + } + } + + impl fmt::Display for SysControlAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self, f) + } + } +} +} + + +#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod datalink { + feature! { + #![feature = "net"] + use super::{fmt, mem, private, ptr, SockaddrLike}; + + /// Hardware Address + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + #[repr(transparent)] + pub struct LinkAddr(pub(in super::super) libc::sockaddr_ll); + + impl LinkAddr { + /// Physical-layer protocol + pub fn protocol(&self) -> u16 { + self.0.sll_protocol + } + + /// Interface number + pub fn ifindex(&self) -> usize { + self.0.sll_ifindex as usize + } + + /// ARP hardware type + pub fn hatype(&self) -> u16 { + self.0.sll_hatype + } + + /// Packet type + pub fn pkttype(&self) -> u8 { + self.0.sll_pkttype + } + + /// Length of MAC address + pub fn halen(&self) -> usize { + self.0.sll_halen as usize + } + + /// Physical-layer address (MAC) + // Returns an Option just for cross-platform compatibility + pub fn addr(&self) -> Option<[u8; 6]> { + Some([ + self.0.sll_addr[0], + self.0.sll_addr[1], + self.0.sll_addr[2], + self.0.sll_addr[3], + self.0.sll_addr[4], + self.0.sll_addr[5], + ]) + } + } + + impl fmt::Display for LinkAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(addr) = self.addr() { + write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", + addr[0], + addr[1], + addr[2], + addr[3], + addr[4], + addr[5]) + } else { + Ok(()) + } + } + } + impl private::SockaddrLikePriv for LinkAddr {} + impl SockaddrLike for LinkAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, + len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_PACKET { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } + } + + impl AsRef for LinkAddr { + fn as_ref(&self) -> &libc::sockaddr_ll { + &self.0 + } + } + + } +} + +#[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "illumos", + target_os = "netbsd", + target_os = "haiku", + target_os = "openbsd"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +mod datalink { + feature! { + #![feature = "net"] + use super::{fmt, mem, private, ptr, SockaddrLike}; + + /// Hardware Address + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + #[repr(transparent)] + pub struct LinkAddr(pub(in super::super) libc::sockaddr_dl); + + impl LinkAddr { + /// interface index, if != 0, system given index for interface + #[cfg(not(target_os = "haiku"))] + pub fn ifindex(&self) -> usize { + self.0.sdl_index as usize + } + + /// Datalink type + #[cfg(not(target_os = "haiku"))] + pub fn datalink_type(&self) -> u8 { + self.0.sdl_type + } + + /// MAC address start position + pub fn nlen(&self) -> usize { + self.0.sdl_nlen as usize + } + + /// link level address length + pub fn alen(&self) -> usize { + self.0.sdl_alen as usize + } + + /// link layer selector length + #[cfg(not(target_os = "haiku"))] + pub fn slen(&self) -> usize { + self.0.sdl_slen as usize + } + + /// if link level address length == 0, + /// or `sdl_data` not be larger. + pub fn is_empty(&self) -> bool { + let nlen = self.nlen(); + let alen = self.alen(); + let data_len = self.0.sdl_data.len(); + + alen == 0 || nlen + alen >= data_len + } + + /// Physical-layer address (MAC) + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + pub fn addr(&self) -> Option<[u8; 6]> { + let nlen = self.nlen(); + let data = self.0.sdl_data; + + if self.is_empty() { + None + } else { + Some([ + data[nlen] as u8, + data[nlen + 1] as u8, + data[nlen + 2] as u8, + data[nlen + 3] as u8, + data[nlen + 4] as u8, + data[nlen + 5] as u8, + ]) + } + } + } + + impl fmt::Display for LinkAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(addr) = self.addr() { + write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", + addr[0], + addr[1], + addr[2], + addr[3], + addr[4], + addr[5]) + } else { + Ok(()) + } + } + } + impl private::SockaddrLikePriv for LinkAddr {} + impl SockaddrLike for LinkAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, + len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_LINK { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } + } + + impl AsRef for LinkAddr { + fn as_ref(&self) -> &libc::sockaddr_dl { + &self.0 + } + } + + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub mod vsock { + use crate::sys::socket::addr::AddressFamily; + use libc::{sa_family_t, sockaddr_vm}; + use std::{fmt, mem}; + use std::hash::{Hash, Hasher}; + use super::*; + + /// Socket address for VMWare VSockets protocol + /// + /// # References + /// + /// [vsock(7)](https://man7.org/linux/man-pages/man7/vsock.7.html) + #[derive(Copy, Clone)] + #[repr(transparent)] + pub struct VsockAddr(pub(in super::super) sockaddr_vm); + + impl private::SockaddrLikePriv for VsockAddr {} + impl SockaddrLike for VsockAddr { + unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) + -> Option where Self: Sized + { + if let Some(l) = len { + if l != mem::size_of::() as libc::socklen_t { + return None; + } + } + if (*addr).sa_family as i32 != libc::AF_VSOCK { + return None; + } + Some(Self(ptr::read_unaligned(addr as *const _))) + } + } + + impl AsRef for VsockAddr { + fn as_ref(&self) -> &libc::sockaddr_vm { + &self.0 + } + } + + impl PartialEq for VsockAddr { + fn eq(&self, other: &Self) -> bool { + let (inner, other) = (self.0, other.0); + (inner.svm_family, inner.svm_cid, inner.svm_port) == + (other.svm_family, other.svm_cid, other.svm_port) + } + } + + impl Eq for VsockAddr {} + + impl Hash for VsockAddr { + fn hash(&self, s: &mut H) { + let inner = self.0; + (inner.svm_family, inner.svm_cid, inner.svm_port).hash(s); + } + } + + /// VSOCK Address + /// + /// The address for AF_VSOCK socket is defined as a combination of a + /// 32-bit Context Identifier (CID) and a 32-bit port number. + impl VsockAddr { + /// Construct a `VsockAddr` from its raw fields. + pub fn new(cid: u32, port: u32) -> VsockAddr { + let mut addr: sockaddr_vm = unsafe { mem::zeroed() }; + addr.svm_family = AddressFamily::Vsock as sa_family_t; + addr.svm_cid = cid; + addr.svm_port = port; + + VsockAddr(addr) + } + + /// Context Identifier (CID) + pub fn cid(&self) -> u32 { + self.0.svm_cid + } + + /// Port number + pub fn port(&self) -> u32 { + self.0.svm_port + } + } + + impl fmt::Display for VsockAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "cid: {} port: {}", self.cid(), self.port()) + } + } + + impl fmt::Debug for VsockAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + mod types { + use super::*; + + #[test] + fn test_ipv4addr_to_libc() { + let s = std::net::Ipv4Addr::new(1, 2, 3, 4); + let l = ipv4addr_to_libc(s); + assert_eq!(l.s_addr, u32::to_be(0x01020304)); + } + + #[test] + fn test_ipv6addr_to_libc() { + let s = std::net::Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8); + let l = ipv6addr_to_libc(&s); + assert_eq!(l.s6_addr, [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8]); + } + } + + mod link { + #![allow(clippy::cast_ptr_alignment)] + + use super::*; + #[cfg(any(target_os = "ios", + target_os = "macos", + target_os = "illumos" + ))] + use super::super::super::socklen_t; + + /// Don't panic when trying to display an empty datalink address + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[test] + fn test_datalink_display() { + use super::super::LinkAddr; + use std::mem; + + let la = LinkAddr(libc::sockaddr_dl{ + sdl_len: 56, + sdl_family: 18, + sdl_index: 5, + sdl_type: 24, + sdl_nlen: 3, + sdl_alen: 0, + sdl_slen: 0, + .. unsafe{mem::zeroed()} + }); + format!("{}", la); + } + + #[cfg(all( + any(target_os = "android", + target_os = "fuchsia", + target_os = "linux"), + target_endian = "little" + ))] + #[test] + fn linux_loopback() { + #[repr(align(2))] + struct Raw([u8; 20]); + + let bytes = Raw([17u8, 0, 0, 0, 1, 0, 0, 0, 4, 3, 0, 6, 1, 2, 3, 4, 5, 6, 0, 0]); + let sa = bytes.0.as_ptr() as *const libc::sockaddr; + let len = None; + let sock_addr = unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap(); + assert_eq!(sock_addr.family(), Some(AddressFamily::Packet)); + match sock_addr.as_link_addr() { + Some(dl) => assert_eq!(dl.addr(), Some([1, 2, 3, 4, 5, 6])), + None => panic!("Can't unwrap sockaddr storage") + } + } + + #[cfg(any(target_os = "ios", + target_os = "macos" + ))] + #[test] + fn macos_loopback() { + let bytes = [20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0]; + let sa = bytes.as_ptr() as *const libc::sockaddr; + let len = Some(bytes.len() as socklen_t); + let sock_addr = unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap(); + assert_eq!(sock_addr.family(), Some(AddressFamily::Link)); + match sock_addr.as_link_addr() { + Some(dl) => { + assert!(dl.addr().is_none()); + }, + None => panic!("Can't unwrap sockaddr storage") + } + } + + #[cfg(any(target_os = "ios", + target_os = "macos" + ))] + #[test] + fn macos_tap() { + let bytes = [20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35, 76, -80]; + let ptr = bytes.as_ptr(); + let sa = ptr as *const libc::sockaddr; + let len = Some(bytes.len() as socklen_t); + + let sock_addr = unsafe { SockaddrStorage::from_raw(sa, len).unwrap() }; + assert_eq!(sock_addr.family(), Some(AddressFamily::Link)); + match sock_addr.as_link_addr() { + Some(dl) => assert_eq!(dl.addr(), + Some([24u8, 101, 144, 221, 76, 176])), + None => panic!("Can't unwrap sockaddr storage") + } + } + + #[cfg(target_os = "illumos")] + #[test] + fn illumos_tap() { + let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176]; + let ptr = bytes.as_ptr(); + let sa = ptr as *const libc::sockaddr; + let len = Some(bytes.len() as socklen_t); + let _sock_addr = unsafe { SockaddrStorage::from_raw(sa, len) }; + + assert!(_sock_addr.is_some()); + + let sock_addr = _sock_addr.unwrap(); + + assert_eq!(sock_addr.family().unwrap(), AddressFamily::Link); + + assert_eq!(sock_addr.as_link_addr().unwrap().addr(), + Some([24u8, 101, 144, 221, 76, 176])); + } + + #[test] + fn size() { + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd", + target_os = "haiku"))] + let l = mem::size_of::(); + #[cfg(any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux"))] + let l = mem::size_of::(); + assert_eq!( LinkAddr::size() as usize, l); + } + } + + mod sockaddr_in { + use super::*; + use std::str::FromStr; + + #[test] + fn display() { + let s = "127.0.0.1:8080"; + let addr = SockaddrIn::from_str(s).unwrap(); + assert_eq!(s, format!("{}", addr)); + } + + #[test] + fn size() { + assert_eq!(mem::size_of::(), + SockaddrIn::size() as usize); + } + } + + mod sockaddr_in6 { + use super::*; + use std::str::FromStr; + + #[test] + fn display() { + let s = "[1234:5678:90ab:cdef::1111:2222]:8080"; + let addr = SockaddrIn6::from_str(s).unwrap(); + assert_eq!(s, format!("{}", addr)); + } + + #[test] + fn size() { + assert_eq!(mem::size_of::(), + SockaddrIn6::size() as usize); + } + } + + mod sockaddr_storage { + use super::*; + + #[test] + fn from_sockaddr_un_named() { + let ua = UnixAddr::new("/var/run/mysock").unwrap(); + let ptr = ua.as_ptr() as *const libc::sockaddr; + let ss = unsafe { + SockaddrStorage::from_raw(ptr, Some(ua.len())) + }.unwrap(); + assert_eq!(ss.len(), ua.len()); + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[test] + fn from_sockaddr_un_abstract_named() { + let name = String::from("nix\0abstract\0test"); + let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap(); + let ptr = ua.as_ptr() as *const libc::sockaddr; + let ss = unsafe { + SockaddrStorage::from_raw(ptr, Some(ua.len())) + }.unwrap(); + assert_eq!(ss.len(), ua.len()); + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[test] + fn from_sockaddr_un_abstract_unnamed() { + let empty = String::new(); + let ua = UnixAddr::new_abstract(empty.as_bytes()).unwrap(); + let ptr = ua.as_ptr() as *const libc::sockaddr; + let ss = unsafe { + SockaddrStorage::from_raw(ptr, Some(ua.len())) + }.unwrap(); + assert_eq!(ss.len(), ua.len()); + } + } + + mod unixaddr { + use super::*; + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[test] + fn abstract_sun_path() { + let name = String::from("nix\0abstract\0test"); + let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap(); + + let sun_path1 = unsafe { &(*addr.as_ptr()).sun_path[..addr.path_len()] }; + let sun_path2 = [0, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116]; + assert_eq!(sun_path1, sun_path2); + } + + #[test] + fn size() { + assert_eq!(mem::size_of::(), + UnixAddr::size() as usize); + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/socket/mod.rs b/utshell-0.5.0/vendor/nix/src/sys/socket/mod.rs new file mode 100644 index 00000000..5f8e6b30 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/socket/mod.rs @@ -0,0 +1,2254 @@ +//! Socket interface functions +//! +//! [Further reading](https://man7.org/linux/man-pages/man7/socket.7.html) +use cfg_if::cfg_if; +use crate::{Result, errno::Errno}; +use libc::{self, c_void, c_int, iovec, socklen_t, size_t, + CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_LEN}; +use std::convert::{TryFrom, TryInto}; +use std::{mem, ptr, slice}; +use std::os::unix::io::RawFd; +#[cfg(feature = "net")] +use std::net; +#[cfg(target_os = "linux")] +#[cfg(feature = "uio")] +use crate::sys::time::TimeSpec; +#[cfg(feature = "uio")] +use crate::sys::time::TimeVal; +use std::io::{IoSlice, IoSliceMut}; + +#[deny(missing_docs)] +mod addr; +#[deny(missing_docs)] +pub mod sockopt; + +/* + * + * ===== Re-exports ===== + * + */ + +pub use self::addr::{SockaddrLike, SockaddrStorage}; + +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] +#[allow(deprecated)] +pub use self::addr::{ + AddressFamily, + SockAddr, + UnixAddr, +}; +#[allow(deprecated)] +#[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))] +#[cfg(feature = "net")] +pub use self::addr::{ + InetAddr, + IpAddr, + Ipv4Addr, + Ipv6Addr, + LinkAddr, + SockaddrIn, + SockaddrIn6 +}; +#[cfg(any(target_os = "illumos", target_os = "solaris"))] +#[allow(deprecated)] +pub use self::addr::{ + AddressFamily, + SockAddr, + UnixAddr, +}; +#[allow(deprecated)] +#[cfg(any(target_os = "illumos", target_os = "solaris", target_os = "haiku"))] +#[cfg(feature = "net")] +pub use self::addr::{ + InetAddr, + IpAddr, + Ipv4Addr, + Ipv6Addr, + SockaddrIn, + SockaddrIn6 +}; + +#[cfg(any(target_os = "ios", target_os = "macos"))] +#[cfg(feature = "ioctl")] +pub use crate::sys::socket::addr::sys_control::SysControlAddr; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use crate::sys::socket::addr::netlink::NetlinkAddr; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use crate::sys::socket::addr::alg::AlgAddr; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use crate::sys::socket::addr::vsock::VsockAddr; + +#[cfg(feature = "uio")] +pub use libc::{cmsghdr, msghdr}; +pub use libc::{ + sa_family_t, + sockaddr, + sockaddr_storage, + sockaddr_un, +}; +#[cfg(feature = "net")] +pub use libc::{sockaddr_in, sockaddr_in6}; + +// Needed by the cmsg_space macro +#[doc(hidden)] +pub use libc::{c_uint, CMSG_SPACE}; + +#[cfg(feature = "net")] +use crate::sys::socket::addr::{ipv4addr_to_libc, ipv6addr_to_libc}; + +/// These constants are used to specify the communication semantics +/// when creating a socket with [`socket()`](fn.socket.html) +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[repr(i32)] +#[non_exhaustive] +pub enum SockType { + /// Provides sequenced, reliable, two-way, connection- + /// based byte streams. An out-of-band data transmission + /// mechanism may be supported. + Stream = libc::SOCK_STREAM, + /// Supports datagrams (connectionless, unreliable + /// messages of a fixed maximum length). + Datagram = libc::SOCK_DGRAM, + /// Provides a sequenced, reliable, two-way connection- + /// based data transmission path for datagrams of fixed + /// maximum length; a consumer is required to read an + /// entire packet with each input system call. + SeqPacket = libc::SOCK_SEQPACKET, + /// Provides raw network protocol access. + Raw = libc::SOCK_RAW, + /// Provides a reliable datagram layer that does not + /// guarantee ordering. + #[cfg(not(any(target_os = "haiku")))] + Rdm = libc::SOCK_RDM, +} +// The TryFrom impl could've been derived using libc_enum!. But for +// backwards-compatibility with Nix-0.25.0 we manually implement it, so as to +// keep the old variant names. +impl TryFrom for SockType { + type Error = crate::Error; + + fn try_from(x: i32) -> Result { + match x { + libc::SOCK_STREAM => Ok(Self::Stream), + libc::SOCK_DGRAM => Ok(Self::Datagram), + libc::SOCK_SEQPACKET => Ok(Self::SeqPacket), + libc::SOCK_RAW => Ok(Self::Raw), + #[cfg(not(any(target_os = "haiku")))] + libc::SOCK_RDM => Ok(Self::Rdm), + _ => Err(Errno::EINVAL) + } + } +} + +/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) +/// to specify the protocol to use. +#[repr(i32)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[non_exhaustive] +pub enum SockProtocol { + /// TCP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html)) + Tcp = libc::IPPROTO_TCP, + /// UDP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html)) + Udp = libc::IPPROTO_UDP, + /// Allows applications and other KEXTs to be notified when certain kernel events occur + /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + KextEvent = libc::SYSPROTO_EVENT, + /// Allows applications to configure and control a KEXT + /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + KextControl = libc::SYSPROTO_CONTROL, + /// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link + // parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkRoute = libc::NETLINK_ROUTE, + /// Reserved for user-mode socket protocols + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkUserSock = libc::NETLINK_USERSOCK, + /// Query information about sockets of various protocol families from the kernel + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkSockDiag = libc::NETLINK_SOCK_DIAG, + /// SELinux event notifications. + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkSELinux = libc::NETLINK_SELINUX, + /// Open-iSCSI + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkISCSI = libc::NETLINK_ISCSI, + /// Auditing + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkAudit = libc::NETLINK_AUDIT, + /// Access to FIB lookup from user space + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP, + /// Netfilter subsystem + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkNetFilter = libc::NETLINK_NETFILTER, + /// SCSI Transports + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT, + /// Infiniband RDMA + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkRDMA = libc::NETLINK_RDMA, + /// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module. + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkIPv6Firewall = libc::NETLINK_IP6_FW, + /// DECnet routing messages + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG, + /// Kernel messages to user space + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT, + /// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow + /// configuration of the kernel crypto API. + /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NetlinkCrypto = libc::NETLINK_CRYPTO, + /// Non-DIX type protocol number defined for the Ethernet IEEE 802.3 interface that allows packets of all protocols + /// defined in the interface to be received. + /// ([ref](https://man7.org/linux/man-pages/man7/packet.7.html)) + // The protocol number is fed into the socket syscall in network byte order. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + EthAll = libc::ETH_P_ALL.to_be(), +} + +#[cfg(any(target_os = "linux"))] +libc_bitflags! { + /// Configuration flags for `SO_TIMESTAMPING` interface + /// + /// For use with [`Timestamping`][sockopt::Timestamping]. + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + pub struct TimestampingFlag: c_uint { + /// Report any software timestamps when available. + SOF_TIMESTAMPING_SOFTWARE; + /// Report hardware timestamps as generated by SOF_TIMESTAMPING_TX_HARDWARE when available. + SOF_TIMESTAMPING_RAW_HARDWARE; + /// Collect transmiting timestamps as reported by hardware + SOF_TIMESTAMPING_TX_HARDWARE; + /// Collect transmiting timestamps as reported by software + SOF_TIMESTAMPING_TX_SOFTWARE; + /// Collect receiving timestamps as reported by hardware + SOF_TIMESTAMPING_RX_HARDWARE; + /// Collect receiving timestamps as reported by software + SOF_TIMESTAMPING_RX_SOFTWARE; + } +} + +libc_bitflags!{ + /// Additional socket options + pub struct SockFlag: c_int { + /// Set non-blocking mode on the new socket + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_NONBLOCK; + /// Set close-on-exec on the new descriptor + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_CLOEXEC; + /// Return `EPIPE` instead of raising `SIGPIPE` + #[cfg(target_os = "netbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_NOSIGPIPE; + /// For domains `AF_INET(6)`, only allow `connect(2)`, `sendto(2)`, or `sendmsg(2)` + /// to the DNS port (typically 53) + #[cfg(target_os = "openbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_DNS; + } +} + +libc_bitflags!{ + /// Flags for send/recv and their relatives + pub struct MsgFlags: c_int { + /// Sends or requests out-of-band data on sockets that support this notion + /// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also + /// support out-of-band data. + MSG_OOB; + /// Peeks at an incoming message. The data is treated as unread and the next + /// [`recv()`](fn.recv.html) + /// or similar function shall still return this data. + MSG_PEEK; + /// Receive operation blocks until the full amount of data can be + /// returned. The function may return smaller amount of data if a signal + /// is caught, an error or disconnect occurs. + MSG_WAITALL; + /// Enables nonblocking operation; if the operation would block, + /// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar + /// behavior to setting the `O_NONBLOCK` flag + /// (via the [`fcntl`](../../fcntl/fn.fcntl.html) + /// `F_SETFL` operation), but differs in that `MSG_DONTWAIT` is a per- + /// call option, whereas `O_NONBLOCK` is a setting on the open file + /// description (see [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)), + /// which will affect all threads in + /// the calling process and as well as other processes that hold + /// file descriptors referring to the same open file description. + MSG_DONTWAIT; + /// Receive flags: Control Data was discarded (buffer too small) + MSG_CTRUNC; + /// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram + /// (since Linux 2.4.27/2.6.8), + /// netlink (since Linux 2.6.22) and UNIX datagram (since Linux 3.4) + /// sockets: return the real length of the packet or datagram, even + /// when it was longer than the passed buffer. Not implemented for UNIX + /// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets. + /// + /// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp). + MSG_TRUNC; + /// Terminates a record (when this notion is supported, as for + /// sockets of type [`SeqPacket`](enum.SockType.html)). + MSG_EOR; + /// This flag specifies that queued errors should be received from + /// the socket error queue. (For more details, see + /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom)) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MSG_ERRQUEUE; + /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain + /// file descriptor using the `SCM_RIGHTS` operation (described in + /// [unix(7)](https://linux.die.net/man/7/unix)). + /// This flag is useful for the same reasons as the `O_CLOEXEC` flag of + /// [open(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html). + /// + /// Only used in [`recvmsg`](fn.recvmsg.html) function. + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MSG_CMSG_CLOEXEC; + /// Requests not to send `SIGPIPE` errors when the other end breaks the connection. + /// (For more details, see [send(2)](https://linux.die.net/man/2/send)). + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MSG_NOSIGNAL; + } +} + +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + /// Unix credentials of the sending process. + /// + /// This struct is used with the `SO_PEERCRED` ancillary message + /// and the `SCM_CREDENTIALS` control message for UNIX sockets. + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct UnixCredentials(libc::ucred); + + impl UnixCredentials { + /// Creates a new instance with the credentials of the current process + pub fn new() -> Self { + // Safe because these FFI functions are inherently safe + unsafe { + UnixCredentials(libc::ucred { + pid: libc::getpid(), + uid: libc::getuid(), + gid: libc::getgid() + }) + } + } + + /// Returns the process identifier + pub fn pid(&self) -> libc::pid_t { + self.0.pid + } + + /// Returns the user identifier + pub fn uid(&self) -> libc::uid_t { + self.0.uid + } + + /// Returns the group identifier + pub fn gid(&self) -> libc::gid_t { + self.0.gid + } + } + + impl Default for UnixCredentials { + fn default() -> Self { + Self::new() + } + } + + impl From for UnixCredentials { + fn from(cred: libc::ucred) -> Self { + UnixCredentials(cred) + } + } + + impl From for libc::ucred { + fn from(uc: UnixCredentials) -> Self { + uc.0 + } + } + } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] { + /// Unix credentials of the sending process. + /// + /// This struct is used with the `SCM_CREDS` ancillary message for UNIX sockets. + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct UnixCredentials(libc::cmsgcred); + + impl UnixCredentials { + /// Returns the process identifier + pub fn pid(&self) -> libc::pid_t { + self.0.cmcred_pid + } + + /// Returns the real user identifier + pub fn uid(&self) -> libc::uid_t { + self.0.cmcred_uid + } + + /// Returns the effective user identifier + pub fn euid(&self) -> libc::uid_t { + self.0.cmcred_euid + } + + /// Returns the real group identifier + pub fn gid(&self) -> libc::gid_t { + self.0.cmcred_gid + } + + /// Returns a list group identifiers (the first one being the effective GID) + pub fn groups(&self) -> &[libc::gid_t] { + unsafe { + slice::from_raw_parts( + self.0.cmcred_groups.as_ptr() as *const libc::gid_t, + self.0.cmcred_ngroups as _ + ) + } + } + } + + impl From for UnixCredentials { + fn from(cred: libc::cmsgcred) -> Self { + UnixCredentials(cred) + } + } + } +} + +cfg_if!{ + if #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "ios" + ))] { + /// Return type of [`LocalPeerCred`](crate::sys::socket::sockopt::LocalPeerCred) + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct XuCred(libc::xucred); + + impl XuCred { + /// Structure layout version + pub fn version(&self) -> u32 { + self.0.cr_version + } + + /// Effective user ID + pub fn uid(&self) -> libc::uid_t { + self.0.cr_uid + } + + /// Returns a list of group identifiers (the first one being the + /// effective GID) + pub fn groups(&self) -> &[libc::gid_t] { + &self.0.cr_groups + } + } + } +} + +feature! { +#![feature = "net"] +/// Request for multicast socket operations +/// +/// This is a wrapper type around `ip_mreq`. +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct IpMembershipRequest(libc::ip_mreq); + +impl IpMembershipRequest { + /// Instantiate a new `IpMembershipRequest` + /// + /// If `interface` is `None`, then `Ipv4Addr::any()` will be used for the interface. + pub fn new(group: net::Ipv4Addr, interface: Option) + -> Self + { + let imr_addr = match interface { + None => net::Ipv4Addr::UNSPECIFIED, + Some(addr) => addr + }; + IpMembershipRequest(libc::ip_mreq { + imr_multiaddr: ipv4addr_to_libc(group), + imr_interface: ipv4addr_to_libc(imr_addr) + }) + } +} + +/// Request for ipv6 multicast socket operations +/// +/// This is a wrapper type around `ipv6_mreq`. +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Ipv6MembershipRequest(libc::ipv6_mreq); + +impl Ipv6MembershipRequest { + /// Instantiate a new `Ipv6MembershipRequest` + pub const fn new(group: net::Ipv6Addr) -> Self { + Ipv6MembershipRequest(libc::ipv6_mreq { + ipv6mr_multiaddr: ipv6addr_to_libc(&group), + ipv6mr_interface: 0, + }) + } +} +} + +feature! { +#![feature = "uio"] + +/// Create a buffer large enough for storing some control messages as returned +/// by [`recvmsg`](fn.recvmsg.html). +/// +/// # Examples +/// +/// ``` +/// # #[macro_use] extern crate nix; +/// # use nix::sys::time::TimeVal; +/// # use std::os::unix::io::RawFd; +/// # fn main() { +/// // Create a buffer for a `ControlMessageOwned::ScmTimestamp` message +/// let _ = cmsg_space!(TimeVal); +/// // Create a buffer big enough for a `ControlMessageOwned::ScmRights` message +/// // with two file descriptors +/// let _ = cmsg_space!([RawFd; 2]); +/// // Create a buffer big enough for a `ControlMessageOwned::ScmRights` message +/// // and a `ControlMessageOwned::ScmTimestamp` message +/// let _ = cmsg_space!(RawFd, TimeVal); +/// # } +/// ``` +// Unfortunately, CMSG_SPACE isn't a const_fn, or else we could return a +// stack-allocated array. +#[macro_export] +macro_rules! cmsg_space { + ( $( $x:ty ),* ) => { + { + let mut space = 0; + $( + // CMSG_SPACE is always safe + space += unsafe { + $crate::sys::socket::CMSG_SPACE(::std::mem::size_of::<$x>() as $crate::sys::socket::c_uint) + } as usize; + )* + Vec::::with_capacity(space) + } + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct RecvMsg<'a, S> { + pub bytes: usize, + cmsghdr: Option<&'a cmsghdr>, + pub address: Option, + pub flags: MsgFlags, + mhdr: msghdr, +} + +impl<'a, S> RecvMsg<'a, S> { + /// Iterate over the valid control messages pointed to by this + /// msghdr. + pub fn cmsgs(&self) -> CmsgIterator { + CmsgIterator { + cmsghdr: self.cmsghdr, + mhdr: &self.mhdr + } + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct CmsgIterator<'a> { + /// Control message buffer to decode from. Must adhere to cmsg alignment. + cmsghdr: Option<&'a cmsghdr>, + mhdr: &'a msghdr +} + +impl<'a> Iterator for CmsgIterator<'a> { + type Item = ControlMessageOwned; + + fn next(&mut self) -> Option { + match self.cmsghdr { + None => None, // No more messages + Some(hdr) => { + // Get the data. + // Safe if cmsghdr points to valid data returned by recvmsg(2) + let cm = unsafe { Some(ControlMessageOwned::decode_from(hdr))}; + // Advance the internal pointer. Safe if mhdr and cmsghdr point + // to valid data returned by recvmsg(2) + self.cmsghdr = unsafe { + let p = CMSG_NXTHDR(self.mhdr as *const _, hdr as *const _); + p.as_ref() + }; + cm + } + } + } +} + +/// A type-safe wrapper around a single control message, as used with +/// [`recvmsg`](#fn.recvmsg). +/// +/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html) +// Nix version 0.13.0 and earlier used ControlMessage for both recvmsg and +// sendmsg. However, on some platforms the messages returned by recvmsg may be +// unaligned. ControlMessageOwned takes those messages by copy, obviating any +// alignment issues. +// +// See https://github.com/nix-rust/nix/issues/999 +#[derive(Clone, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum ControlMessageOwned { + /// Received version of [`ControlMessage::ScmRights`] + ScmRights(Vec), + /// Received version of [`ControlMessage::ScmCredentials`] + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ScmCredentials(UnixCredentials), + /// Received version of [`ControlMessage::ScmCreds`] + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ScmCreds(UnixCredentials), + /// A message of type `SCM_TIMESTAMP`, containing the time the + /// packet was received by the kernel. + /// + /// See the kernel's explanation in "SO_TIMESTAMP" of + /// [networking/timestamping](https://www.kernel.org/doc/Documentation/networking/timestamping.txt). + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate nix; + /// # use nix::sys::socket::*; + /// # use nix::sys::time::*; + /// # use std::io::{IoSlice, IoSliceMut}; + /// # use std::time::*; + /// # use std::str::FromStr; + /// # fn main() { + /// // Set up + /// let message = "OhayÅ!".as_bytes(); + /// let in_socket = socket( + /// AddressFamily::Inet, + /// SockType::Datagram, + /// SockFlag::empty(), + /// None).unwrap(); + /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap(); + /// let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap(); + /// bind(in_socket, &localhost).unwrap(); + /// let address: SockaddrIn = getsockname(in_socket).unwrap(); + /// // Get initial time + /// let time0 = SystemTime::now(); + /// // Send the message + /// let iov = [IoSlice::new(message)]; + /// let flags = MsgFlags::empty(); + /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap(); + /// assert_eq!(message.len(), l); + /// // Receive the message + /// let mut buffer = vec![0u8; message.len()]; + /// let mut cmsgspace = cmsg_space!(TimeVal); + /// let mut iov = [IoSliceMut::new(&mut buffer)]; + /// let r = recvmsg::(in_socket, &mut iov, Some(&mut cmsgspace), flags) + /// .unwrap(); + /// let rtime = match r.cmsgs().next() { + /// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime, + /// Some(_) => panic!("Unexpected control message"), + /// None => panic!("No control message") + /// }; + /// // Check the final time + /// let time1 = SystemTime::now(); + /// // the packet's received timestamp should lie in-between the two system + /// // times, unless the system clock was adjusted in the meantime. + /// let rduration = Duration::new(rtime.tv_sec() as u64, + /// rtime.tv_usec() as u32 * 1000); + /// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration); + /// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap()); + /// // Close socket + /// nix::unistd::close(in_socket).unwrap(); + /// # } + /// ``` + ScmTimestamp(TimeVal), + /// A set of nanosecond resolution timestamps + /// + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + #[cfg(all(target_os = "linux"))] + ScmTimestampsns(Timestamps), + /// Nanoseconds resolution timestamp + /// + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + #[cfg(all(target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ScmTimestampns(TimeSpec), + #[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + ))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4PacketInfo(libc::in_pktinfo), + #[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "openbsd", + target_os = "netbsd", + ))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6PacketInfo(libc::in6_pktinfo), + #[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4RecvIf(libc::sockaddr_dl), + #[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4RecvDstAddr(libc::in_addr), + #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4OrigDstAddr(libc::sockaddr_in), + #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6OrigDstAddr(libc::sockaddr_in6), + + /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP + /// packets from a single sender. + /// Fixed-size payloads are following one by one in a receive buffer. + /// This Control Message indicates the size of all smaller packets, + /// except, maybe, the last one. + /// + /// `UdpGroSegment` socket option should be enabled on a socket + /// to allow receiving GRO packets. + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + UdpGroSegments(u16), + + /// SO_RXQ_OVFL indicates that an unsigned 32 bit value + /// ancilliary msg (cmsg) should be attached to recieved + /// skbs indicating the number of packets dropped by the + /// socket between the last recieved packet and this + /// received packet. + /// + /// `RxqOvfl` socket option should be enabled on a socket + /// to allow receiving the drop counter. + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + RxqOvfl(u32), + + /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4RecvErr(libc::sock_extended_err, Option), + /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6RecvErr(libc::sock_extended_err, Option), + + /// Catch-all variant for unimplemented cmsg types. + #[doc(hidden)] + Unknown(UnknownCmsg), +} + +/// For representing packet timestamps via `SO_TIMESTAMPING` interface +#[cfg(all(target_os = "linux"))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Timestamps { + /// software based timestamp, usually one containing data + pub system: TimeSpec, + /// legacy timestamp, usually empty + pub hw_trans: TimeSpec, + /// hardware based timestamp + pub hw_raw: TimeSpec, +} + +impl ControlMessageOwned { + /// Decodes a `ControlMessageOwned` from raw bytes. + /// + /// This is only safe to call if the data is correct for the message type + /// specified in the header. Normally, the kernel ensures that this is the + /// case. "Correct" in this case includes correct length, alignment and + /// actual content. + // Clippy complains about the pointer alignment of `p`, not understanding + // that it's being fed to a function that can handle that. + #[allow(clippy::cast_ptr_alignment)] + unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned + { + let p = CMSG_DATA(header); + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + let len = header as *const _ as usize + header.cmsg_len as usize + - p as usize; + match (header.cmsg_level, header.cmsg_type) { + (libc::SOL_SOCKET, libc::SCM_RIGHTS) => { + let n = len / mem::size_of::(); + let mut fds = Vec::with_capacity(n); + for i in 0..n { + let fdp = (p as *const RawFd).add(i); + fds.push(ptr::read_unaligned(fdp)); + } + ControlMessageOwned::ScmRights(fds) + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + (libc::SOL_SOCKET, libc::SCM_CREDENTIALS) => { + let cred: libc::ucred = ptr::read_unaligned(p as *const _); + ControlMessageOwned::ScmCredentials(cred.into()) + } + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + (libc::SOL_SOCKET, libc::SCM_CREDS) => { + let cred: libc::cmsgcred = ptr::read_unaligned(p as *const _); + ControlMessageOwned::ScmCreds(cred.into()) + } + #[cfg(not(target_os = "haiku"))] + (libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => { + let tv: libc::timeval = ptr::read_unaligned(p as *const _); + ControlMessageOwned::ScmTimestamp(TimeVal::from(tv)) + }, + #[cfg(all(target_os = "linux"))] + (libc::SOL_SOCKET, libc::SCM_TIMESTAMPNS) => { + let ts: libc::timespec = ptr::read_unaligned(p as *const _); + ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts)) + } + #[cfg(all(target_os = "linux"))] + (libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => { + let tp = p as *const libc::timespec; + let ts: libc::timespec = ptr::read_unaligned(tp); + let system = TimeSpec::from(ts); + let ts: libc::timespec = ptr::read_unaligned(tp.add(1)); + let hw_trans = TimeSpec::from(ts); + let ts: libc::timespec = ptr::read_unaligned(tp.add(2)); + let hw_raw = TimeSpec::from(ts); + let timestamping = Timestamps { system, hw_trans, hw_raw }; + ControlMessageOwned::ScmTimestampsns(timestamping) + } + #[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos" + ))] + #[cfg(feature = "net")] + (libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => { + let info = ptr::read_unaligned(p as *const libc::in6_pktinfo); + ControlMessageOwned::Ipv6PacketInfo(info) + } + #[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + ))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_PKTINFO) => { + let info = ptr::read_unaligned(p as *const libc::in_pktinfo); + ControlMessageOwned::Ipv4PacketInfo(info) + } + #[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVIF) => { + let dl = ptr::read_unaligned(p as *const libc::sockaddr_dl); + ControlMessageOwned::Ipv4RecvIf(dl) + }, + #[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => { + let dl = ptr::read_unaligned(p as *const libc::in_addr); + ControlMessageOwned::Ipv4RecvDstAddr(dl) + }, + #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => { + let dl = ptr::read_unaligned(p as *const libc::sockaddr_in); + ControlMessageOwned::Ipv4OrigDstAddr(dl) + }, + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + (libc::SOL_UDP, libc::UDP_GRO) => { + let gso_size: u16 = ptr::read_unaligned(p as *const _); + ControlMessageOwned::UdpGroSegments(gso_size) + }, + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + (libc::SOL_SOCKET, libc::SO_RXQ_OVFL) => { + let drop_counter = ptr::read_unaligned(p as *const u32); + ControlMessageOwned::RxqOvfl(drop_counter) + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVERR) => { + let (err, addr) = Self::recv_err_helper::(p, len); + ControlMessageOwned::Ipv4RecvErr(err, addr) + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IPV6, libc::IPV6_RECVERR) => { + let (err, addr) = Self::recv_err_helper::(p, len); + ControlMessageOwned::Ipv6RecvErr(err, addr) + }, + #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] + #[cfg(feature = "net")] + (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => { + let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6); + ControlMessageOwned::Ipv6OrigDstAddr(dl) + }, + (_, _) => { + let sl = slice::from_raw_parts(p, len); + let ucmsg = UnknownCmsg(*header, Vec::::from(sl)); + ControlMessageOwned::Unknown(ucmsg) + } + } + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + #[allow(clippy::cast_ptr_alignment)] // False positive + unsafe fn recv_err_helper(p: *mut libc::c_uchar, len: usize) -> (libc::sock_extended_err, Option) { + let ee = p as *const libc::sock_extended_err; + let err = ptr::read_unaligned(ee); + + // For errors originating on the network, SO_EE_OFFENDER(ee) points inside the p[..len] + // CMSG_DATA buffer. For local errors, there is no address included in the control + // message, and SO_EE_OFFENDER(ee) points beyond the end of the buffer. So, we need to + // validate that the address object is in-bounds before we attempt to copy it. + let addrp = libc::SO_EE_OFFENDER(ee) as *const T; + + if addrp.offset(1) as usize - (p as usize) > len { + (err, None) + } else { + (err, Some(ptr::read_unaligned(addrp))) + } + } +} + +/// A type-safe zero-copy wrapper around a single control message, as used wih +/// [`sendmsg`](#fn.sendmsg). More types may be added to this enum; do not +/// exhaustively pattern-match it. +/// +/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html) +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum ControlMessage<'a> { + /// A message of type `SCM_RIGHTS`, containing an array of file + /// descriptors passed between processes. + /// + /// See the description in the "Ancillary messages" section of the + /// [unix(7) man page](https://man7.org/linux/man-pages/man7/unix.7.html). + /// + /// Using multiple `ScmRights` messages for a single `sendmsg` call isn't + /// recommended since it causes platform-dependent behaviour: It might + /// swallow all but the first `ScmRights` message or fail with `EINVAL`. + /// Instead, you can put all fds to be passed into a single `ScmRights` + /// message. + ScmRights(&'a [RawFd]), + /// A message of type `SCM_CREDENTIALS`, containing the pid, uid and gid of + /// a process connected to the socket. + /// + /// This is similar to the socket option `SO_PEERCRED`, but requires a + /// process to explicitly send its credentials. A process running as root is + /// allowed to specify any credentials, while credentials sent by other + /// processes are verified by the kernel. + /// + /// For further information, please refer to the + /// [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html) man page. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ScmCredentials(&'a UnixCredentials), + /// A message of type `SCM_CREDS`, containing the pid, uid, euid, gid and groups of + /// a process connected to the socket. + /// + /// This is similar to the socket options `LOCAL_CREDS` and `LOCAL_PEERCRED`, but + /// requires a process to explicitly send its credentials. + /// + /// Credentials are always overwritten by the kernel, so this variant does have + /// any data, unlike the receive-side + /// [`ControlMessageOwned::ScmCreds`]. + /// + /// For further information, please refer to the + /// [`unix(4)`](https://www.freebsd.org/cgi/man.cgi?query=unix) man page. + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ScmCreds, + + /// Set IV for `AF_ALG` crypto API. + /// + /// For further information, please refer to the + /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html) + #[cfg(any( + target_os = "android", + target_os = "linux", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AlgSetIv(&'a [u8]), + /// Set crypto operation for `AF_ALG` crypto API. It may be one of + /// `ALG_OP_ENCRYPT` or `ALG_OP_DECRYPT` + /// + /// For further information, please refer to the + /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html) + #[cfg(any( + target_os = "android", + target_os = "linux", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AlgSetOp(&'a libc::c_int), + /// Set the length of associated authentication data (AAD) (applicable only to AEAD algorithms) + /// for `AF_ALG` crypto API. + /// + /// For further information, please refer to the + /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html) + #[cfg(any( + target_os = "android", + target_os = "linux", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AlgSetAeadAssoclen(&'a u32), + + /// UDP GSO makes it possible for applications to generate network packets + /// for a virtual MTU much greater than the real one. + /// The length of the send data no longer matches the expected length on + /// the wire. + /// The size of the datagram payload as it should appear on the wire may be + /// passed through this control message. + /// Send buffer should consist of multiple fixed-size wire payloads + /// following one by one, and the last, possibly smaller one. + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + UdpGsoSegments(&'a u16), + + /// Configure the sending addressing and interface for v4 + /// + /// For further information, please refer to the + /// [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html) man page. + #[cfg(any(target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "android", + target_os = "ios",))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4PacketInfo(&'a libc::in_pktinfo), + + /// Configure the sending addressing and interface for v6 + /// + /// For further information, please refer to the + /// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page. + #[cfg(any(target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "freebsd", + target_os = "android", + target_os = "ios",))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6PacketInfo(&'a libc::in6_pktinfo), + + /// Configure the IPv4 source address with `IP_SENDSRCADDR`. + #[cfg(any( + target_os = "netbsd", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + ))] + #[cfg(feature = "net")] + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4SendSrcAddr(&'a libc::in_addr), + + /// SO_RXQ_OVFL indicates that an unsigned 32 bit value + /// ancilliary msg (cmsg) should be attached to recieved + /// skbs indicating the number of packets dropped by the + /// socket between the last recieved packet and this + /// received packet. + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + RxqOvfl(&'a u32), + + /// Configure the transmission time of packets. + /// + /// For further information, please refer to the + /// [`tc-etf(8)`](https://man7.org/linux/man-pages/man8/tc-etf.8.html) man + /// page. + #[cfg(target_os = "linux")] + TxTime(&'a u64), +} + +// An opaque structure used to prevent cmsghdr from being a public type +#[doc(hidden)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct UnknownCmsg(cmsghdr, Vec); + +impl<'a> ControlMessage<'a> { + /// The value of CMSG_SPACE on this message. + /// Safe because CMSG_SPACE is always safe + fn space(&self) -> usize { + unsafe{CMSG_SPACE(self.len() as libc::c_uint) as usize} + } + + /// The value of CMSG_LEN on this message. + /// Safe because CMSG_LEN is always safe + #[cfg(any(target_os = "android", + all(target_os = "linux", not(target_env = "musl"))))] + fn cmsg_len(&self) -> usize { + unsafe{CMSG_LEN(self.len() as libc::c_uint) as usize} + } + + #[cfg(not(any(target_os = "android", + all(target_os = "linux", not(target_env = "musl")))))] + fn cmsg_len(&self) -> libc::c_uint { + unsafe{CMSG_LEN(self.len() as libc::c_uint)} + } + + /// Return a reference to the payload data as a byte pointer + fn copy_to_cmsg_data(&self, cmsg_data: *mut u8) { + let data_ptr = match *self { + ControlMessage::ScmRights(fds) => { + fds as *const _ as *const u8 + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::ScmCredentials(creds) => { + &creds.0 as *const libc::ucred as *const u8 + } + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + ControlMessage::ScmCreds => { + // The kernel overwrites the data, we just zero it + // to make sure it's not uninitialized memory + unsafe { ptr::write_bytes(cmsg_data, 0, self.len()) }; + return + } + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(iv) => { + #[allow(deprecated)] // https://github.com/rust-lang/libc/issues/1501 + let af_alg_iv = libc::af_alg_iv { + ivlen: iv.len() as u32, + iv: [0u8; 0], + }; + + let size = mem::size_of_val(&af_alg_iv); + + unsafe { + ptr::copy_nonoverlapping( + &af_alg_iv as *const _ as *const u8, + cmsg_data, + size, + ); + ptr::copy_nonoverlapping( + iv.as_ptr(), + cmsg_data.add(size), + iv.len() + ); + }; + + return + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetOp(op) => { + op as *const _ as *const u8 + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetAeadAssoclen(len) => { + len as *const _ as *const u8 + }, + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + ControlMessage::UdpGsoSegments(gso_size) => { + gso_size as *const _ as *const u8 + }, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "android", + target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd", + target_os = "android", target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8, + #[cfg(any(target_os = "netbsd", target_os = "freebsd", + target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(feature = "net")] + ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8, + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + ControlMessage::RxqOvfl(drop_count) => { + drop_count as *const _ as *const u8 + }, + #[cfg(target_os = "linux")] + ControlMessage::TxTime(tx_time) => { + tx_time as *const _ as *const u8 + }, + }; + unsafe { + ptr::copy_nonoverlapping( + data_ptr, + cmsg_data, + self.len() + ) + }; + } + + /// The size of the payload, excluding its cmsghdr + fn len(&self) -> usize { + match *self { + ControlMessage::ScmRights(fds) => { + mem::size_of_val(fds) + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::ScmCredentials(creds) => { + mem::size_of_val(creds) + } + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + ControlMessage::ScmCreds => { + mem::size_of::() + } + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(iv) => { + mem::size_of_val(&iv) + iv.len() + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetOp(op) => { + mem::size_of_val(op) + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetAeadAssoclen(len) => { + mem::size_of_val(len) + }, + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + ControlMessage::UdpGsoSegments(gso_size) => { + mem::size_of_val(gso_size) + }, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "android", + target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info), + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd", + target_os = "android", target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info), + #[cfg(any(target_os = "netbsd", target_os = "freebsd", + target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(feature = "net")] + ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr), + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + ControlMessage::RxqOvfl(drop_count) => { + mem::size_of_val(drop_count) + }, + #[cfg(target_os = "linux")] + ControlMessage::TxTime(tx_time) => { + mem::size_of_val(tx_time) + }, + } + } + + /// Returns the value to put into the `cmsg_level` field of the header. + fn cmsg_level(&self) -> libc::c_int { + match *self { + ControlMessage::ScmRights(_) => libc::SOL_SOCKET, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET, + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + ControlMessage::ScmCreds => libc::SOL_SOCKET, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) | + ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG, + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "android", + target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd", + target_os = "android", target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6, + #[cfg(any(target_os = "netbsd", target_os = "freebsd", + target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(feature = "net")] + ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP, + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET, + #[cfg(target_os = "linux")] + ControlMessage::TxTime(_) => libc::SOL_SOCKET, + } + } + + /// Returns the value to put into the `cmsg_type` field of the header. + fn cmsg_type(&self) -> libc::c_int { + match *self { + ControlMessage::ScmRights(_) => libc::SCM_RIGHTS, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS, + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + ControlMessage::ScmCreds => libc::SCM_CREDS, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(_) => { + libc::ALG_SET_IV + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetOp(_) => { + libc::ALG_SET_OP + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetAeadAssoclen(_) => { + libc::ALG_SET_AEAD_ASSOCLEN + }, + #[cfg(target_os = "linux")] + #[cfg(feature = "net")] + ControlMessage::UdpGsoSegments(_) => { + libc::UDP_SEGMENT + }, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "android", + target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd", + target_os = "android", target_os = "ios",))] + #[cfg(feature = "net")] + ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO, + #[cfg(any(target_os = "netbsd", target_os = "freebsd", + target_os = "openbsd", target_os = "dragonfly"))] + #[cfg(feature = "net")] + ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + ControlMessage::RxqOvfl(_) => { + libc::SO_RXQ_OVFL + }, + #[cfg(target_os = "linux")] + ControlMessage::TxTime(_) => { + libc::SCM_TXTIME + }, + } + } + + // Unsafe: cmsg must point to a valid cmsghdr with enough space to + // encode self. + unsafe fn encode_into(&self, cmsg: *mut cmsghdr) { + (*cmsg).cmsg_level = self.cmsg_level(); + (*cmsg).cmsg_type = self.cmsg_type(); + (*cmsg).cmsg_len = self.cmsg_len(); + self.copy_to_cmsg_data(CMSG_DATA(cmsg)); + } +} + + +/// Send data in scatter-gather vectors to a socket, possibly accompanied +/// by ancillary data. Optionally direct the message at the given address, +/// as with sendto. +/// +/// Allocates if cmsgs is nonempty. +/// +/// # Examples +/// When not directing to any specific address, use `()` for the generic type +/// ``` +/// # use nix::sys::socket::*; +/// # use nix::unistd::pipe; +/// # use std::io::IoSlice; +/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, +/// SockFlag::empty()) +/// .unwrap(); +/// let (r, w) = pipe().unwrap(); +/// +/// let iov = [IoSlice::new(b"hello")]; +/// let fds = [r]; +/// let cmsg = ControlMessage::ScmRights(&fds); +/// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(); +/// ``` +/// When directing to a specific address, the generic type will be inferred. +/// ``` +/// # use nix::sys::socket::*; +/// # use nix::unistd::pipe; +/// # use std::io::IoSlice; +/// # use std::str::FromStr; +/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap(); +/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), +/// None).unwrap(); +/// let (r, w) = pipe().unwrap(); +/// +/// let iov = [IoSlice::new(b"hello")]; +/// let fds = [r]; +/// let cmsg = ControlMessage::ScmRights(&fds); +/// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap(); +/// ``` +pub fn sendmsg(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage], + flags: MsgFlags, addr: Option<&S>) -> Result + where S: SockaddrLike +{ + let capacity = cmsgs.iter().map(|c| c.space()).sum(); + + // First size the buffer needed to hold the cmsgs. It must be zeroed, + // because subsequent code will not clear the padding bytes. + let mut cmsg_buffer = vec![0u8; capacity]; + + let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr); + + let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) }; + + Errno::result(ret).map(|r| r as usize) +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", +))] +#[derive(Debug)] +pub struct SendMmsgData<'a, I, C, S> + where + I: AsRef<[IoSlice<'a>]>, + C: AsRef<[ControlMessage<'a>]>, + S: SockaddrLike + 'a +{ + pub iov: I, + pub cmsgs: C, + pub addr: Option, + pub _lt: std::marker::PhantomData<&'a I>, +} + +/// An extension of `sendmsg` that allows the caller to transmit multiple +/// messages on a socket using a single system call. This has performance +/// benefits for some applications. +/// +/// Allocations are performed for cmsgs and to build `msghdr` buffer +/// +/// # Arguments +/// +/// * `fd`: Socket file descriptor +/// * `data`: Struct that implements `IntoIterator` with `SendMmsgData` items +/// * `flags`: Optional flags passed directly to the operating system. +/// +/// # Returns +/// `Vec` with numbers of sent bytes on each sent message. +/// +/// # References +/// [`sendmsg`](fn.sendmsg.html) +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", +))] +pub fn sendmmsg<'a, I, C, S>( + fd: RawFd, + data: impl std::iter::IntoIterator>, + flags: MsgFlags +) -> Result> + where + I: AsRef<[IoSlice<'a>]> + 'a, + C: AsRef<[ControlMessage<'a>]> + 'a, + S: SockaddrLike + 'a +{ + let iter = data.into_iter(); + + let size_hint = iter.size_hint(); + let reserve_items = size_hint.1.unwrap_or(size_hint.0); + + let mut output = Vec::::with_capacity(reserve_items); + + let mut cmsgs_buffers = Vec::>::with_capacity(reserve_items); + + for d in iter { + let capacity: usize = d.cmsgs.as_ref().iter().map(|c| c.space()).sum(); + let mut cmsgs_buffer = vec![0u8; capacity]; + + output.push(libc::mmsghdr { + msg_hdr: pack_mhdr_to_send( + &mut cmsgs_buffer, + &d.iov, + &d.cmsgs, + d.addr.as_ref() + ), + msg_len: 0, + }); + cmsgs_buffers.push(cmsgs_buffer); + }; + + let ret = unsafe { libc::sendmmsg(fd, output.as_mut_ptr(), output.len() as _, flags.bits() as _) }; + + let sent_messages = Errno::result(ret)? as usize; + let mut sent_bytes = Vec::with_capacity(sent_messages); + + for item in &output { + sent_bytes.push(item.msg_len as usize); + } + + Ok(sent_bytes) +} + + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", +))] +#[derive(Debug)] +pub struct RecvMmsgData<'a, I> + where + I: AsRef<[IoSliceMut<'a>]> + 'a, +{ + pub iov: I, + pub cmsg_buffer: Option<&'a mut Vec>, +} + +/// An extension of `recvmsg` that allows the caller to receive multiple +/// messages from a socket using a single system call. This has +/// performance benefits for some applications. +/// +/// `iov` and `cmsg_buffer` should be constructed similarly to `recvmsg` +/// +/// Multiple allocations are performed +/// +/// # Arguments +/// +/// * `fd`: Socket file descriptor +/// * `data`: Struct that implements `IntoIterator` with `RecvMmsgData` items +/// * `flags`: Optional flags passed directly to the operating system. +/// +/// # RecvMmsgData +/// +/// * `iov`: Scatter-gather list of buffers to receive the message +/// * `cmsg_buffer`: Space to receive ancillary data. Should be created by +/// [`cmsg_space!`](../../macro.cmsg_space.html) +/// +/// # Returns +/// A `Vec` with multiple `RecvMsg`, one per received message +/// +/// # References +/// - [`recvmsg`](fn.recvmsg.html) +/// - [`RecvMsg`](struct.RecvMsg.html) +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", +))] +#[allow(clippy::needless_collect)] // Complicated false positive +pub fn recvmmsg<'a, I, S>( + fd: RawFd, + data: impl std::iter::IntoIterator, + IntoIter=impl ExactSizeIterator + Iterator>>, + flags: MsgFlags, + timeout: Option +) -> Result>> + where + I: AsRef<[IoSliceMut<'a>]> + 'a, + S: Copy + SockaddrLike + 'a +{ + let iter = data.into_iter(); + + let num_messages = iter.len(); + + let mut output: Vec = Vec::with_capacity(num_messages); + + // Addresses should be pre-allocated. pack_mhdr_to_receive will store them + // as raw pointers, so we may not move them. Turn the vec into a boxed + // slice so we won't inadvertently reallocate the vec. + let mut addresses = vec![mem::MaybeUninit::uninit(); num_messages] + .into_boxed_slice(); + + let results: Vec<_> = iter.enumerate().map(|(i, d)| { + let (msg_controllen, mhdr) = unsafe { + pack_mhdr_to_receive( + d.iov.as_ref(), + &mut d.cmsg_buffer, + addresses[i].as_mut_ptr(), + ) + }; + + output.push( + libc::mmsghdr { + msg_hdr: mhdr, + msg_len: 0, + } + ); + + (msg_controllen, &mut d.cmsg_buffer) + }).collect(); + + let timeout = if let Some(mut t) = timeout { + t.as_mut() as *mut libc::timespec + } else { + ptr::null_mut() + }; + + let ret = unsafe { libc::recvmmsg(fd, output.as_mut_ptr(), output.len() as _, flags.bits() as _, timeout) }; + + let _ = Errno::result(ret)?; + + Ok(output + .into_iter() + .take(ret as usize) + .zip(addresses.iter().map(|addr| unsafe{addr.assume_init()})) + .zip(results.into_iter()) + .map(|((mmsghdr, address), (msg_controllen, cmsg_buffer))| { + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + unsafe { + read_mhdr( + mmsghdr.msg_hdr, + mmsghdr.msg_len as isize, + msg_controllen, + address, + cmsg_buffer + ) + } + }) + .collect()) +} + +unsafe fn read_mhdr<'a, S>( + mhdr: msghdr, + r: isize, + msg_controllen: usize, + address: S, + cmsg_buffer: &mut Option<&'a mut Vec> +) -> RecvMsg<'a, S> + where S: SockaddrLike +{ + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + let cmsghdr = { + if mhdr.msg_controllen > 0 { + // got control message(s) + cmsg_buffer + .as_mut() + .unwrap() + .set_len(mhdr.msg_controllen as usize); + debug_assert!(!mhdr.msg_control.is_null()); + debug_assert!(msg_controllen >= mhdr.msg_controllen as usize); + CMSG_FIRSTHDR(&mhdr as *const msghdr) + } else { + ptr::null() + }.as_ref() + }; + + RecvMsg { + bytes: r as usize, + cmsghdr, + address: Some(address), + flags: MsgFlags::from_bits_truncate(mhdr.msg_flags), + mhdr, + } +} + +unsafe fn pack_mhdr_to_receive<'outer, 'inner, I, S>( + iov: I, + cmsg_buffer: &mut Option<&mut Vec>, + address: *mut S, +) -> (usize, msghdr) + where + I: AsRef<[IoSliceMut<'inner>]> + 'outer, + S: SockaddrLike + 'outer +{ + let (msg_control, msg_controllen) = cmsg_buffer.as_mut() + .map(|v| (v.as_mut_ptr(), v.capacity())) + .unwrap_or((ptr::null_mut(), 0)); + + let mhdr = { + // Musl's msghdr has private fields, so this is the only way to + // initialize it. + let mut mhdr = mem::MaybeUninit::::zeroed(); + let p = mhdr.as_mut_ptr(); + (*p).msg_name = (*address).as_mut_ptr() as *mut c_void; + (*p).msg_namelen = S::size(); + (*p).msg_iov = iov.as_ref().as_ptr() as *mut iovec; + (*p).msg_iovlen = iov.as_ref().len() as _; + (*p).msg_control = msg_control as *mut c_void; + (*p).msg_controllen = msg_controllen as _; + (*p).msg_flags = 0; + mhdr.assume_init() + }; + + (msg_controllen, mhdr) +} + +fn pack_mhdr_to_send<'a, I, C, S>( + cmsg_buffer: &mut [u8], + iov: I, + cmsgs: C, + addr: Option<&S> +) -> msghdr + where + I: AsRef<[IoSlice<'a>]>, + C: AsRef<[ControlMessage<'a>]>, + S: SockaddrLike + 'a +{ + let capacity = cmsg_buffer.len(); + + // The message header must be initialized before the individual cmsgs. + let cmsg_ptr = if capacity > 0 { + cmsg_buffer.as_ptr() as *mut c_void + } else { + ptr::null_mut() + }; + + let mhdr = unsafe { + // Musl's msghdr has private fields, so this is the only way to + // initialize it. + let mut mhdr = mem::MaybeUninit::::zeroed(); + let p = mhdr.as_mut_ptr(); + (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()) as *mut _; + (*p).msg_namelen = addr.map(S::len).unwrap_or(0); + // transmute iov into a mutable pointer. sendmsg doesn't really mutate + // the buffer, but the standard says that it takes a mutable pointer + (*p).msg_iov = iov.as_ref().as_ptr() as *mut _; + (*p).msg_iovlen = iov.as_ref().len() as _; + (*p).msg_control = cmsg_ptr; + (*p).msg_controllen = capacity as _; + (*p).msg_flags = 0; + mhdr.assume_init() + }; + + // Encode each cmsg. This must happen after initializing the header because + // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields. + // CMSG_FIRSTHDR is always safe + let mut pmhdr: *mut cmsghdr = unsafe { CMSG_FIRSTHDR(&mhdr as *const msghdr) }; + for cmsg in cmsgs.as_ref() { + assert_ne!(pmhdr, ptr::null_mut()); + // Safe because we know that pmhdr is valid, and we initialized it with + // sufficient space + unsafe { cmsg.encode_into(pmhdr) }; + // Safe because mhdr is valid + pmhdr = unsafe { CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr) }; + } + + mhdr +} + +/// Receive message in scatter-gather vectors from a socket, and +/// optionally receive ancillary data into the provided buffer. +/// If no ancillary data is desired, use () as the type parameter. +/// +/// # Arguments +/// +/// * `fd`: Socket file descriptor +/// * `iov`: Scatter-gather list of buffers to receive the message +/// * `cmsg_buffer`: Space to receive ancillary data. Should be created by +/// [`cmsg_space!`](../../macro.cmsg_space.html) +/// * `flags`: Optional flags passed directly to the operating system. +/// +/// # References +/// [recvmsg(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html) +pub fn recvmsg<'a, 'outer, 'inner, S>(fd: RawFd, iov: &'outer mut [IoSliceMut<'inner>], + mut cmsg_buffer: Option<&'a mut Vec>, + flags: MsgFlags) -> Result> + where S: SockaddrLike + 'a +{ + let mut address = mem::MaybeUninit::uninit(); + + let (msg_controllen, mut mhdr) = unsafe { + pack_mhdr_to_receive::<_, S>(iov, &mut cmsg_buffer, address.as_mut_ptr()) + }; + + let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) }; + + let r = Errno::result(ret)?; + + Ok(unsafe { read_mhdr(mhdr, r, msg_controllen, address.assume_init(), &mut cmsg_buffer) }) +} +} + + +/// Create an endpoint for communication +/// +/// The `protocol` specifies a particular protocol to be used with the +/// socket. Normally only a single protocol exists to support a +/// particular socket type within a given protocol family, in which case +/// protocol can be specified as `None`. However, it is possible that many +/// protocols may exist, in which case a particular protocol must be +/// specified in this manner. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html) +pub fn socket>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result { + let protocol = match protocol.into() { + None => 0, + Some(p) => p as c_int, + }; + + // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a + // little easier to understand by separating it out. So we have to merge these bitfields + // here. + let mut ty = ty as c_int; + ty |= flags.bits(); + + let res = unsafe { libc::socket(domain as c_int, ty, protocol) }; + + Errno::result(res) +} + +/// Create a pair of connected sockets +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html) +pub fn socketpair>>(domain: AddressFamily, ty: SockType, protocol: T, + flags: SockFlag) -> Result<(RawFd, RawFd)> { + let protocol = match protocol.into() { + None => 0, + Some(p) => p as c_int, + }; + + // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a + // little easier to understand by separating it out. So we have to merge these bitfields + // here. + let mut ty = ty as c_int; + ty |= flags.bits(); + + let mut fds = [-1, -1]; + + let res = unsafe { libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) }; + Errno::result(res)?; + + Ok((fds[0], fds[1])) +} + +/// Listen for connections on a socket +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html) +pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> { + let res = unsafe { libc::listen(sockfd, backlog as c_int) }; + + Errno::result(res).map(drop) +} + +/// Bind a name to a socket +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html) +pub fn bind(fd: RawFd, addr: &dyn SockaddrLike) -> Result<()> { + let res = unsafe { + libc::bind(fd, addr.as_ptr(), addr.len()) + }; + + Errno::result(res).map(drop) +} + +/// Accept a connection on a socket +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html) +pub fn accept(sockfd: RawFd) -> Result { + let res = unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) }; + + Errno::result(res) +} + +/// Accept a connection on a socket +/// +/// [Further reading](https://man7.org/linux/man-pages/man2/accept.2.html) +#[cfg(any(all( + target_os = "android", + any( + target_arch = "aarch64", + target_arch = "x86", + target_arch = "x86_64" + ) + ), + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] +pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result { + let res = unsafe { libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) }; + + Errno::result(res) +} + +/// Initiate a connection on a socket +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html) +pub fn connect(fd: RawFd, addr: &dyn SockaddrLike) -> Result<()> { + let res = unsafe { + libc::connect(fd, addr.as_ptr(), addr.len()) + }; + + Errno::result(res).map(drop) +} + +/// Receive data from a connection-oriented socket. Returns the number of +/// bytes read +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html) +pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result { + unsafe { + let ret = libc::recv( + sockfd, + buf.as_ptr() as *mut c_void, + buf.len() as size_t, + flags.bits()); + + Errno::result(ret).map(|r| r as usize) + } +} + +/// Receive data from a connectionless or connection-oriented socket. Returns +/// the number of bytes read and, for connectionless sockets, the socket +/// address of the sender. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html) +pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) + -> Result<(usize, Option)> +{ + unsafe { + let mut addr = mem::MaybeUninit::::uninit(); + let mut len = mem::size_of_val(&addr) as socklen_t; + + let ret = Errno::result(libc::recvfrom( + sockfd, + buf.as_ptr() as *mut c_void, + buf.len() as size_t, + 0, + addr.as_mut_ptr() as *mut libc::sockaddr, + &mut len as *mut socklen_t))? as usize; + + Ok((ret, T::from_raw( + addr.assume_init().as_ptr() as *const libc::sockaddr, + Some(len)) + )) + } +} + +/// Send a message to a socket +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html) +pub fn sendto(fd: RawFd, buf: &[u8], addr: &dyn SockaddrLike, flags: MsgFlags) -> Result { + let ret = unsafe { + libc::sendto( + fd, + buf.as_ptr() as *const c_void, + buf.len() as size_t, + flags.bits(), + addr.as_ptr(), + addr.len() + ) + }; + + Errno::result(ret).map(|r| r as usize) +} + +/// Send data to a connection-oriented socket. Returns the number of bytes read +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html) +pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result { + let ret = unsafe { + libc::send(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits()) + }; + + Errno::result(ret).map(|r| r as usize) +} + +/* + * + * ===== Socket Options ===== + * + */ + +/// Represents a socket option that can be retrieved. +pub trait GetSockOpt : Copy { + type Val; + + /// Look up the value of this socket option on the given socket. + fn get(&self, fd: RawFd) -> Result; +} + +/// Represents a socket option that can be set. +pub trait SetSockOpt : Clone { + type Val; + + /// Set the value of this socket option on the given socket. + fn set(&self, fd: RawFd, val: &Self::Val) -> Result<()>; +} + +/// Get the current value for the requested socket option +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html) +pub fn getsockopt(fd: RawFd, opt: O) -> Result { + opt.get(fd) +} + +/// Sets the value for the requested socket option +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html) +/// +/// # Examples +/// +/// ``` +/// use nix::sys::socket::setsockopt; +/// use nix::sys::socket::sockopt::KeepAlive; +/// use std::net::TcpListener; +/// use std::os::unix::io::AsRawFd; +/// +/// let listener = TcpListener::bind("0.0.0.0:0").unwrap(); +/// let fd = listener.as_raw_fd(); +/// let res = setsockopt(fd, KeepAlive, &true); +/// assert!(res.is_ok()); +/// ``` +pub fn setsockopt(fd: RawFd, opt: O, val: &O::Val) -> Result<()> { + opt.set(fd, val) +} + +/// Get the address of the peer connected to the socket `fd`. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html) +pub fn getpeername(fd: RawFd) -> Result { + unsafe { + let mut addr = mem::MaybeUninit::::uninit(); + let mut len = T::size(); + + let ret = libc::getpeername( + fd, + addr.as_mut_ptr() as *mut libc::sockaddr, + &mut len + ); + + Errno::result(ret)?; + + T::from_raw(addr.assume_init().as_ptr(), Some(len)) + .ok_or(Errno::EINVAL) + } +} + +/// Get the current address to which the socket `fd` is bound. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html) +pub fn getsockname(fd: RawFd) -> Result { + unsafe { + let mut addr = mem::MaybeUninit::::uninit(); + let mut len = T::size(); + + let ret = libc::getsockname( + fd, + addr.as_mut_ptr() as *mut libc::sockaddr, + &mut len + ); + + Errno::result(ret)?; + + T::from_raw(addr.assume_init().as_ptr(), Some(len)) + .ok_or(Errno::EINVAL) + } +} + +/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a +/// certain size. +/// +/// In C this would usually be done by casting. The `len` argument +/// should be the number of bytes in the `sockaddr_storage` that are actually +/// allocated and valid. It must be at least as large as all the useful parts +/// of the structure. Note that in the case of a `sockaddr_un`, `len` need not +/// include the terminating null. +#[deprecated( + since = "0.24.0", + note = "use SockaddrLike or SockaddrStorage instead" +)] +#[allow(deprecated)] +pub fn sockaddr_storage_to_addr( + addr: &sockaddr_storage, + len: usize) -> Result { + + assert!(len <= mem::size_of::()); + if len < mem::size_of_val(&addr.ss_family) { + return Err(Errno::ENOTCONN); + } + + match c_int::from(addr.ss_family) { + #[cfg(feature = "net")] + libc::AF_INET => { + assert!(len >= mem::size_of::()); + let sin = unsafe { + *(addr as *const sockaddr_storage as *const sockaddr_in) + }; + Ok(SockAddr::Inet(InetAddr::V4(sin))) + } + #[cfg(feature = "net")] + libc::AF_INET6 => { + assert!(len >= mem::size_of::()); + let sin6 = unsafe { + *(addr as *const _ as *const sockaddr_in6) + }; + Ok(SockAddr::Inet(InetAddr::V6(sin6))) + } + libc::AF_UNIX => { + unsafe { + let sun = *(addr as *const _ as *const sockaddr_un); + let sun_len = len.try_into().unwrap(); + Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, sun_len))) + } + } + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "net")] + libc::AF_PACKET => { + use libc::sockaddr_ll; + // Don't assert anything about the size. + // Apparently the Linux kernel can return smaller sizes when + // the value in the last element of sockaddr_ll (`sll_addr`) is + // smaller than the declared size of that field + let sll = unsafe { + *(addr as *const _ as *const sockaddr_ll) + }; + Ok(SockAddr::Link(LinkAddr(sll))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => { + use libc::sockaddr_nl; + let snl = unsafe { + *(addr as *const _ as *const sockaddr_nl) + }; + Ok(SockAddr::Netlink(NetlinkAddr(snl))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_ALG => { + use libc::sockaddr_alg; + let salg = unsafe { + *(addr as *const _ as *const sockaddr_alg) + }; + Ok(SockAddr::Alg(AlgAddr(salg))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => { + use libc::sockaddr_vm; + let svm = unsafe { + *(addr as *const _ as *const sockaddr_vm) + }; + Ok(SockAddr::Vsock(VsockAddr(svm))) + } + af => panic!("unexpected address family {}", af), + } +} + + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum Shutdown { + /// Further receptions will be disallowed. + Read, + /// Further transmissions will be disallowed. + Write, + /// Further receptions and transmissions will be disallowed. + Both, +} + +/// Shut down part of a full-duplex connection. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html) +pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { + unsafe { + use libc::shutdown; + + let how = match how { + Shutdown::Read => libc::SHUT_RD, + Shutdown::Write => libc::SHUT_WR, + Shutdown::Both => libc::SHUT_RDWR, + }; + + Errno::result(shutdown(df, how)).map(drop) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn can_use_cmsg_space() { + let _ = cmsg_space!(u8); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/socket/sockopt.rs b/utshell-0.5.0/vendor/nix/src/sys/socket/sockopt.rs new file mode 100644 index 00000000..204f1064 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/socket/sockopt.rs @@ -0,0 +1,1031 @@ +//! Socket options as used by `setsockopt` and `getsockopt`. +use cfg_if::cfg_if; +use super::{GetSockOpt, SetSockOpt}; +use crate::Result; +use crate::errno::Errno; +use crate::sys::time::TimeVal; +use libc::{self, c_int, c_void, socklen_t}; +use std::convert::TryFrom; +use std::mem::{ + self, + MaybeUninit +}; +use std::os::unix::io::RawFd; +use std::ffi::{OsStr, OsString}; +#[cfg(target_family = "unix")] +use std::os::unix::ffi::OsStrExt; + +// Constants +// TCP_CA_NAME_MAX isn't defined in user space include files +#[cfg(any(target_os = "freebsd", target_os = "linux"))] +#[cfg(feature = "net")] +const TCP_CA_NAME_MAX: usize = 16; + +/// Helper for implementing `SetSockOpt` for a given socket option. See +/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html). +/// +/// This macro aims to help implementing `SetSockOpt` for different socket options that accept +/// different kinds of data to be used with `setsockopt`. +/// +/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option +/// you are implementing represents a simple type. +/// +/// # Arguments +/// +/// * `$name:ident`: name of the type you want to implement `SetSockOpt` for. +/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets* +/// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), +/// and more. Please refer to your system manual for more options. Will be passed as the second +/// argument (`level`) to the `setsockopt` call. +/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`, +/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`) +/// to the `setsockopt` call. +/// * Type of the value that you are going to set. +/// * Type that implements the `Set` trait for the type from the previous item (like `SetBool` for +/// `bool`, `SetUsize` for `usize`, etc.). +macro_rules! setsockopt_impl { + ($name:ident, $level:expr, $flag:path, $ty:ty, $setter:ty) => { + impl SetSockOpt for $name { + type Val = $ty; + + fn set(&self, fd: RawFd, val: &$ty) -> Result<()> { + unsafe { + let setter: $setter = Set::new(val); + + let res = libc::setsockopt(fd, $level, $flag, + setter.ffi_ptr(), + setter.ffi_len()); + Errno::result(res).map(drop) + } + } + } + } +} + +/// Helper for implementing `GetSockOpt` for a given socket option. See +/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html). +/// +/// This macro aims to help implementing `GetSockOpt` for different socket options that accept +/// different kinds of data to be use with `getsockopt`. +/// +/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option +/// you are implementing represents a simple type. +/// +/// # Arguments +/// +/// * Name of the type you want to implement `GetSockOpt` for. +/// * Socket layer, or a `protocol level`: could be *raw sockets* (`lic::SOL_SOCKET`), *ip +/// protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), and more. Please refer +/// to your system manual for more options. Will be passed as the second argument (`level`) to +/// the `getsockopt` call. +/// * A flag to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`, +/// `libc::SO_ORIGINAL_DST` and others. Will be passed as the third argument (`option_name`) to +/// the `getsockopt` call. +/// * Type of the value that you are going to get. +/// * Type that implements the `Get` trait for the type from the previous item (`GetBool` for +/// `bool`, `GetUsize` for `usize`, etc.). +macro_rules! getsockopt_impl { + ($name:ident, $level:expr, $flag:path, $ty:ty, $getter:ty) => { + impl GetSockOpt for $name { + type Val = $ty; + + fn get(&self, fd: RawFd) -> Result<$ty> { + unsafe { + let mut getter: $getter = Get::uninit(); + + let res = libc::getsockopt(fd, $level, $flag, + getter.ffi_ptr(), + getter.ffi_len()); + Errno::result(res)?; + + match <$ty>::try_from(getter.assume_init()) { + Err(_) => Err(Errno::EINVAL), + Ok(r) => Ok(r) + } + } + } + } + } +} + +/// Helper to generate the sockopt accessors. See +/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html) and +/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html). +/// +/// This macro aims to help implementing `GetSockOpt` and `SetSockOpt` for different socket options +/// that accept different kinds of data to be use with `getsockopt` and `setsockopt` respectively. +/// +/// Basically this macro wraps up the [`getsockopt_impl!`](macro.getsockopt_impl.html) and +/// [`setsockopt_impl!`](macro.setsockopt_impl.html) macros. +/// +/// # Arguments +/// +/// * `GetOnly`, `SetOnly` or `Both`: whether you want to implement only getter, only setter or +/// both of them. +/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for. +/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets* +/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), +/// and more. Please refer to your system manual for more options. Will be passed as the second +/// argument (`level`) to the `getsockopt`/`setsockopt` call. +/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`, +/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`) +/// to the `setsockopt`/`getsockopt` call. +/// * `$ty:ty`: type of the value that will be get/set. +/// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`. +/// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`. +// Some targets don't use all rules. +#[allow(unknown_lints)] +#[allow(unused_macro_rules)] +macro_rules! sockopt_impl { + ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, bool) => { + sockopt_impl!($(#[$attr])* + $name, GetOnly, $level, $flag, bool, GetBool); + }; + + ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, u8) => { + sockopt_impl!($(#[$attr])* $name, GetOnly, $level, $flag, u8, GetU8); + }; + + ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, usize) => + { + sockopt_impl!($(#[$attr])* + $name, GetOnly, $level, $flag, usize, GetUsize); + }; + + ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, bool) => { + sockopt_impl!($(#[$attr])* + $name, SetOnly, $level, $flag, bool, SetBool); + }; + + ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, u8) => { + sockopt_impl!($(#[$attr])* $name, SetOnly, $level, $flag, u8, SetU8); + }; + + ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, usize) => + { + sockopt_impl!($(#[$attr])* + $name, SetOnly, $level, $flag, usize, SetUsize); + }; + + ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, bool) => { + sockopt_impl!($(#[$attr])* + $name, Both, $level, $flag, bool, GetBool, SetBool); + }; + + ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, u8) => { + sockopt_impl!($(#[$attr])* + $name, Both, $level, $flag, u8, GetU8, SetU8); + }; + + ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, usize) => { + sockopt_impl!($(#[$attr])* + $name, Both, $level, $flag, usize, GetUsize, SetUsize); + }; + + ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, + OsString<$array:ty>) => + { + sockopt_impl!($(#[$attr])* + $name, Both, $level, $flag, OsString, GetOsString<$array>, + SetOsString); + }; + + /* + * Matchers with generic getter types must be placed at the end, so + * they'll only match _after_ specialized matchers fail + */ + ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, $ty:ty) => + { + sockopt_impl!($(#[$attr])* + $name, GetOnly, $level, $flag, $ty, GetStruct<$ty>); + }; + + ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, $ty:ty, + $getter:ty) => + { + $(#[$attr])* + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct $name; + + getsockopt_impl!($name, $level, $flag, $ty, $getter); + }; + + ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, $ty:ty) => + { + sockopt_impl!($(#[$attr])* + $name, SetOnly, $level, $flag, $ty, SetStruct<$ty>); + }; + + ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, $ty:ty, + $setter:ty) => + { + $(#[$attr])* + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct $name; + + setsockopt_impl!($name, $level, $flag, $ty, $setter); + }; + + ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, $ty:ty, + $getter:ty, $setter:ty) => + { + $(#[$attr])* + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct $name; + + setsockopt_impl!($name, $level, $flag, $ty, $setter); + getsockopt_impl!($name, $level, $flag, $ty, $getter); + }; + + ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, $ty:ty) => { + sockopt_impl!($(#[$attr])* + $name, Both, $level, $flag, $ty, GetStruct<$ty>, + SetStruct<$ty>); + }; +} + +/* + * + * ===== Define sockopts ===== + * + */ + +sockopt_impl!( + /// Enables local address reuse + ReuseAddr, Both, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool +); +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] +sockopt_impl!( + /// Permits multiple AF_INET or AF_INET6 sockets to be bound to an + /// identical socket address. + ReusePort, Both, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool); +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Under most circumstances, TCP sends data when it is presented; when + /// outstanding data has not yet been acknowledged, it gathers small amounts + /// of output to be sent in a single packet once an acknowledgement is + /// received. For a small number of clients, such as window systems that + /// send a stream of mouse events which receive no replies, this + /// packetization may cause significant delays. The boolean option + /// TCP_NODELAY defeats this algorithm. + TcpNoDelay, Both, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool); +sockopt_impl!( + /// When enabled, a close(2) or shutdown(2) will not return until all + /// queued messages for the socket have been successfully sent or the + /// linger timeout has been reached. + Linger, Both, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger); +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Join a multicast group + IpAddMembership, SetOnly, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, + super::IpMembershipRequest); +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Leave a multicast group. + IpDropMembership, SetOnly, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, + super::IpMembershipRequest); +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + #[cfg(feature = "net")] + sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Join an IPv6 multicast group. + Ipv6AddMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest); + #[cfg(feature = "net")] + sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Leave an IPv6 multicast group. + Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest); + } else if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] { + #[cfg(feature = "net")] + sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Join an IPv6 multicast group. + Ipv6AddMembership, SetOnly, libc::IPPROTO_IPV6, + libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest); + #[cfg(feature = "net")] + sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Leave an IPv6 multicast group. + Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, + libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest); + } +} +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Set or read the time-to-live value of outgoing multicast packets for + /// this socket. + IpMulticastTtl, Both, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8); +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Set or read a boolean integer argument that determines whether sent + /// multicast packets should be looped back to the local sockets. + IpMulticastLoop, Both, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool); +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// If enabled, this boolean option allows binding to an IP address that + /// is nonlocal or does not (yet) exist. + IpFreebind, Both, libc::IPPROTO_IP, libc::IP_FREEBIND, bool); +sockopt_impl!( + /// Specify the receiving timeout until reporting an error. + ReceiveTimeout, Both, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal); +sockopt_impl!( + /// Specify the sending timeout until reporting an error. + SendTimeout, Both, libc::SOL_SOCKET, libc::SO_SNDTIMEO, TimeVal); +sockopt_impl!( + /// Set or get the broadcast flag. + Broadcast, Both, libc::SOL_SOCKET, libc::SO_BROADCAST, bool); +sockopt_impl!( + /// If this option is enabled, out-of-band data is directly placed into + /// the receive data stream. + OobInline, Both, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool); +sockopt_impl!( + /// Get and clear the pending socket error. + SocketError, GetOnly, libc::SOL_SOCKET, libc::SO_ERROR, i32); +sockopt_impl!( + /// Set or get the don't route flag. + DontRoute, Both, libc::SOL_SOCKET, libc::SO_DONTROUTE, bool); +sockopt_impl!( + /// Enable sending of keep-alive messages on connection-oriented sockets. + KeepAlive, Both, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool); +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "ios" +))] +sockopt_impl!( + /// Get the credentials of the peer process of a connected unix domain + /// socket. + LocalPeerCred, GetOnly, 0, libc::LOCAL_PEERCRED, super::XuCred); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Return the credentials of the foreign process connected to this socket. + PeerCredentials, GetOnly, libc::SOL_SOCKET, libc::SO_PEERCRED, super::UnixCredentials); +#[cfg(any(target_os = "ios", + target_os = "macos"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Specify the amount of time, in seconds, that the connection must be idle + /// before keepalive probes (if enabled) are sent. + TcpKeepAlive, Both, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32); +#[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The time (in seconds) the connection needs to remain idle before TCP + /// starts sending keepalive probes + TcpKeepIdle, Both, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32); +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + sockopt_impl!( + /// The maximum segment size for outgoing TCP packets. + TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32); + } else { + sockopt_impl!( + /// The maximum segment size for outgoing TCP packets. + TcpMaxSeg, GetOnly, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32); + } +} +#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The maximum number of keepalive probes TCP should send before + /// dropping the connection. + TcpKeepCount, Both, libc::IPPROTO_TCP, libc::TCP_KEEPCNT, u32); +#[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "linux"))] +sockopt_impl!( + #[allow(missing_docs)] + // Not documented by Linux! + TcpRepair, Both, libc::IPPROTO_TCP, libc::TCP_REPAIR, u32); +#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The time (in seconds) between individual keepalive probes. + TcpKeepInterval, Both, libc::IPPROTO_TCP, libc::TCP_KEEPINTVL, u32); +#[cfg(any(target_os = "fuchsia", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Specifies the maximum amount of time in milliseconds that transmitted + /// data may remain unacknowledged before TCP will forcibly close the + /// corresponding connection + TcpUserTimeout, Both, libc::IPPROTO_TCP, libc::TCP_USER_TIMEOUT, u32); +sockopt_impl!( + /// Sets or gets the maximum socket receive buffer in bytes. + RcvBuf, Both, libc::SOL_SOCKET, libc::SO_RCVBUF, usize); +sockopt_impl!( + /// Sets or gets the maximum socket send buffer in bytes. + SndBuf, Both, libc::SOL_SOCKET, libc::SO_SNDBUF, usize); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can + /// perform the same task as `SO_RCVBUF`, but the `rmem_max limit` can be + /// overridden. + RcvBufForce, SetOnly, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usize); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can + /// perform the same task as `SO_SNDBUF`, but the `wmem_max` limit can be + /// overridden. + SndBufForce, SetOnly, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize); +sockopt_impl!( + /// Gets the socket type as an integer. + SockType, GetOnly, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType, GetStruct); +sockopt_impl!( + /// Returns a value indicating whether or not this socket has been marked to + /// accept connections with `listen(2)`. + AcceptConn, GetOnly, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Bind this socket to a particular device like “eth0â€. + BindToDevice, Both, libc::SOL_SOCKET, libc::SO_BINDTODEVICE, OsString<[u8; libc::IFNAMSIZ]>); +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + #[allow(missing_docs)] + // Not documented by Linux! + OriginalDst, GetOnly, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + #[allow(missing_docs)] + // Not documented by Linux! + Ip6tOriginalDst, GetOnly, libc::SOL_IPV6, libc::IP6T_SO_ORIGINAL_DST, libc::sockaddr_in6); +#[cfg(any(target_os = "linux"))] +sockopt_impl!( + /// Specifies exact type of timestamping information collected by the kernel + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + Timestamping, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPING, super::TimestampingFlag); +#[cfg(not(target_os = "haiku"))] +sockopt_impl!( + /// Enable or disable the receiving of the `SO_TIMESTAMP` control message. + ReceiveTimestamp, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool); +#[cfg(all(target_os = "linux"))] +sockopt_impl!( + /// Enable or disable the receiving of the `SO_TIMESTAMPNS` control message. + ReceiveTimestampns, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPNS, bool); +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Setting this boolean option enables transparent proxying on this socket. + IpTransparent, Both, libc::SOL_IP, libc::IP_TRANSPARENT, bool); +#[cfg(target_os = "openbsd")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Allows the socket to be bound to addresses which are not local to the + /// machine, so it can be used to make a transparent proxy. + BindAny, Both, libc::SOL_SOCKET, libc::SO_BINDANY, bool); +#[cfg(target_os = "freebsd")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Can `bind(2)` to any address, even one not bound to any available + /// network interface in the system. + BindAny, Both, libc::IPPROTO_IP, libc::IP_BINDANY, bool); +#[cfg(target_os = "linux")] +sockopt_impl!( + /// Set the mark for each packet sent through this socket (similar to the + /// netfilter MARK target but socket-based). + Mark, Both, libc::SOL_SOCKET, libc::SO_MARK, u32); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Enable or disable the receiving of the `SCM_CREDENTIALS` control + /// message. + PassCred, Both, libc::SOL_SOCKET, libc::SO_PASSCRED, bool); +#[cfg(any(target_os = "freebsd", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// This option allows the caller to set the TCP congestion control + /// algorithm to be used, on a per-socket basis. + TcpCongestion, Both, libc::IPPROTO_TCP, libc::TCP_CONGESTION, OsString<[u8; TCP_CA_NAME_MAX]>); +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", +))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Pass an `IP_PKTINFO` ancillary message that contains a pktinfo + /// structure that supplies some information about the incoming packet. + Ipv4PacketInfo, Both, libc::IPPROTO_IP, libc::IP_PKTINFO, bool); +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Set delivery of the `IPV6_PKTINFO` control message on incoming + /// datagrams. + Ipv6RecvPacketInfo, Both, libc::IPPROTO_IPV6, libc::IPV6_RECVPKTINFO, bool); +#[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The `recvmsg(2)` call returns a `struct sockaddr_dl` corresponding to + /// the interface on which the packet was received. + Ipv4RecvIf, Both, libc::IPPROTO_IP, libc::IP_RECVIF, bool); +#[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The `recvmsg(2)` call will return the destination IP address for a UDP + /// datagram. + Ipv4RecvDstAddr, Both, libc::IPPROTO_IP, libc::IP_RECVDSTADDR, bool); +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The `recvmsg(2)` call will return the destination IP address for a UDP + /// datagram. + Ipv4OrigDstAddr, Both, libc::IPPROTO_IP, libc::IP_ORIGDSTADDR, bool); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + #[allow(missing_docs)] + // Not documented by Linux! + UdpGsoSegment, Both, libc::SOL_UDP, libc::UDP_SEGMENT, libc::c_int); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + #[allow(missing_docs)] + // Not documented by Linux! + UdpGroSegment, Both, libc::IPPROTO_UDP, libc::UDP_GRO, bool); +#[cfg(target_os = "linux")] +sockopt_impl!( + /// Configures the behavior of time-based transmission of packets, for use + /// with the `TxTime` control message. + TxTime, Both, libc::SOL_SOCKET, libc::SO_TXTIME, libc::sock_txtime); +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +sockopt_impl!( + /// Indicates that an unsigned 32-bit value ancillary message (cmsg) should + /// be attached to received skbs indicating the number of packets dropped by + /// the socket since its creation. + RxqOvfl, Both, libc::SOL_SOCKET, libc::SO_RXQ_OVFL, libc::c_int); +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The socket is restricted to sending and receiving IPv6 packets only. + Ipv6V6Only, Both, libc::IPPROTO_IPV6, libc::IPV6_V6ONLY, bool); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Enable extended reliable error message passing. + Ipv4RecvErr, Both, libc::IPPROTO_IP, libc::IP_RECVERR, bool); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Control receiving of asynchronous error options. + Ipv6RecvErr, Both, libc::IPPROTO_IPV6, libc::IPV6_RECVERR, bool); +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +sockopt_impl!( + /// Set or retrieve the current time-to-live field that is used in every + /// packet sent from this socket. + Ipv4Ttl, Both, libc::IPPROTO_IP, libc::IP_TTL, libc::c_int); +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +sockopt_impl!( + /// Set the unicast hop limit for the socket. + Ipv6Ttl, Both, libc::IPPROTO_IPV6, libc::IPV6_UNICAST_HOPS, libc::c_int); +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// The `recvmsg(2)` call will return the destination IP address for a UDP + /// datagram. + Ipv6OrigDstAddr, Both, libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR, bool); +#[cfg(any(target_os = "ios", target_os = "macos"))] +sockopt_impl!( + /// Set "don't fragment packet" flag on the IP packet. + IpDontFrag, Both, libc::IPPROTO_IP, libc::IP_DONTFRAG, bool); +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", +))] +sockopt_impl!( + /// Set "don't fragment packet" flag on the IPv6 packet. + Ipv6DontFrag, Both, libc::IPPROTO_IPV6, libc::IPV6_DONTFRAG, bool); + +#[allow(missing_docs)] +// Not documented by Linux! +#[cfg(any(target_os = "android", target_os = "linux"))] +#[derive(Copy, Clone, Debug)] +pub struct AlgSetAeadAuthSize; + +// ALG_SET_AEAD_AUTH_SIZE read the length from passed `option_len` +// See https://elixir.bootlin.com/linux/v4.4/source/crypto/af_alg.c#L222 +#[cfg(any(target_os = "android", target_os = "linux"))] +impl SetSockOpt for AlgSetAeadAuthSize { + type Val = usize; + + fn set(&self, fd: RawFd, val: &usize) -> Result<()> { + unsafe { + let res = libc::setsockopt(fd, + libc::SOL_ALG, + libc::ALG_SET_AEAD_AUTHSIZE, + ::std::ptr::null(), + *val as libc::socklen_t); + Errno::result(res).map(drop) + } + } +} + +#[allow(missing_docs)] +// Not documented by Linux! +#[cfg(any(target_os = "android", target_os = "linux"))] +#[derive(Clone, Debug)] +pub struct AlgSetKey(::std::marker::PhantomData); + +#[cfg(any(target_os = "android", target_os = "linux"))] +impl Default for AlgSetKey { + fn default() -> Self { + AlgSetKey(Default::default()) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +impl SetSockOpt for AlgSetKey where T: AsRef<[u8]> + Clone { + type Val = T; + + fn set(&self, fd: RawFd, val: &T) -> Result<()> { + unsafe { + let res = libc::setsockopt(fd, + libc::SOL_ALG, + libc::ALG_SET_KEY, + val.as_ref().as_ptr() as *const _, + val.as_ref().len() as libc::socklen_t); + Errno::result(res).map(drop) + } + } +} + +/* + * + * ===== Accessor helpers ===== + * + */ + +/// Helper trait that describes what is expected from a `GetSockOpt` getter. +trait Get { + /// Returns an uninitialized value. + fn uninit() -> Self; + /// Returns a pointer to the stored value. This pointer will be passed to the system's + /// `getsockopt` call (`man 3p getsockopt`, argument `option_value`). + fn ffi_ptr(&mut self) -> *mut c_void; + /// Returns length of the stored value. This pointer will be passed to the system's + /// `getsockopt` call (`man 3p getsockopt`, argument `option_len`). + fn ffi_len(&mut self) -> *mut socklen_t; + /// Returns the hopefully initialized inner value. + unsafe fn assume_init(self) -> T; +} + +/// Helper trait that describes what is expected from a `SetSockOpt` setter. +trait Set<'a, T> { + /// Initialize the setter with a given value. + fn new(val: &'a T) -> Self; + /// Returns a pointer to the stored value. This pointer will be passed to the system's + /// `setsockopt` call (`man 3p setsockopt`, argument `option_value`). + fn ffi_ptr(&self) -> *const c_void; + /// Returns length of the stored value. This pointer will be passed to the system's + /// `setsockopt` call (`man 3p setsockopt`, argument `option_len`). + fn ffi_len(&self) -> socklen_t; +} + +/// Getter for an arbitrary `struct`. +struct GetStruct { + len: socklen_t, + val: MaybeUninit, +} + +impl Get for GetStruct { + fn uninit() -> Self { + GetStruct { + len: mem::size_of::() as socklen_t, + val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { + self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + + unsafe fn assume_init(self) -> T { + assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); + self.val.assume_init() + } +} + +/// Setter for an arbitrary `struct`. +struct SetStruct<'a, T: 'static> { + ptr: &'a T, +} + +impl<'a, T> Set<'a, T> for SetStruct<'a, T> { + fn new(ptr: &'a T) -> SetStruct<'a, T> { + SetStruct { ptr } + } + + fn ffi_ptr(&self) -> *const c_void { + self.ptr as *const T as *const c_void + } + + fn ffi_len(&self) -> socklen_t { + mem::size_of::() as socklen_t + } +} + +/// Getter for a boolean value. +struct GetBool { + len: socklen_t, + val: MaybeUninit, +} + +impl Get for GetBool { + fn uninit() -> Self { + GetBool { + len: mem::size_of::() as socklen_t, + val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { + self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + + unsafe fn assume_init(self) -> bool { + assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); + self.val.assume_init() != 0 + } +} + +/// Setter for a boolean value. +struct SetBool { + val: c_int, +} + +impl<'a> Set<'a, bool> for SetBool { + fn new(val: &'a bool) -> SetBool { + SetBool { val: i32::from(*val) } + } + + fn ffi_ptr(&self) -> *const c_void { + &self.val as *const c_int as *const c_void + } + + fn ffi_len(&self) -> socklen_t { + mem::size_of::() as socklen_t + } +} + +/// Getter for an `u8` value. +struct GetU8 { + len: socklen_t, + val: MaybeUninit, +} + +impl Get for GetU8 { + fn uninit() -> Self { + GetU8 { + len: mem::size_of::() as socklen_t, + val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { + self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + + unsafe fn assume_init(self) -> u8 { + assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); + self.val.assume_init() + } +} + +/// Setter for an `u8` value. +struct SetU8 { + val: u8, +} + +impl<'a> Set<'a, u8> for SetU8 { + fn new(val: &'a u8) -> SetU8 { + SetU8 { val: *val } + } + + fn ffi_ptr(&self) -> *const c_void { + &self.val as *const u8 as *const c_void + } + + fn ffi_len(&self) -> socklen_t { + mem::size_of::() as socklen_t + } +} + +/// Getter for an `usize` value. +struct GetUsize { + len: socklen_t, + val: MaybeUninit, +} + +impl Get for GetUsize { + fn uninit() -> Self { + GetUsize { + len: mem::size_of::() as socklen_t, + val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { + self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + + unsafe fn assume_init(self) -> usize { + assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); + self.val.assume_init() as usize + } +} + +/// Setter for an `usize` value. +struct SetUsize { + val: c_int, +} + +impl<'a> Set<'a, usize> for SetUsize { + fn new(val: &'a usize) -> SetUsize { + SetUsize { val: *val as c_int } + } + + fn ffi_ptr(&self) -> *const c_void { + &self.val as *const c_int as *const c_void + } + + fn ffi_len(&self) -> socklen_t { + mem::size_of::() as socklen_t + } +} + +/// Getter for a `OsString` value. +struct GetOsString> { + len: socklen_t, + val: MaybeUninit, +} + +impl> Get for GetOsString { + fn uninit() -> Self { + GetOsString { + len: mem::size_of::() as socklen_t, + val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { + self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + + unsafe fn assume_init(self) -> OsString { + let len = self.len as usize; + let mut v = self.val.assume_init(); + OsStr::from_bytes(&v.as_mut()[0..len]).to_owned() + } +} + +/// Setter for a `OsString` value. +struct SetOsString<'a> { + val: &'a OsStr, +} + +impl<'a> Set<'a, OsString> for SetOsString<'a> { + fn new(val: &'a OsString) -> SetOsString { + SetOsString { val: val.as_os_str() } + } + + fn ffi_ptr(&self) -> *const c_void { + self.val.as_bytes().as_ptr() as *const c_void + } + + fn ffi_len(&self) -> socklen_t { + self.val.len() as socklen_t + } +} + + +#[cfg(test)] +mod test { + #[cfg(any(target_os = "android", target_os = "linux"))] + #[test] + fn can_get_peercred_on_unix_socket() { + use super::super::*; + + let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap(); + let a_cred = getsockopt(a, super::PeerCredentials).unwrap(); + let b_cred = getsockopt(b, super::PeerCredentials).unwrap(); + assert_eq!(a_cred, b_cred); + assert_ne!(a_cred.pid(), 0); + } + + #[test] + fn is_socket_type_unix() { + use super::super::*; + use crate::unistd::close; + + let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap(); + let a_type = getsockopt(a, super::SockType).unwrap(); + assert_eq!(a_type, SockType::Stream); + close(a).unwrap(); + close(b).unwrap(); + } + + #[test] + fn is_socket_type_dgram() { + use super::super::*; + use crate::unistd::close; + + let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap(); + let s_type = getsockopt(s, super::SockType).unwrap(); + assert_eq!(s_type, SockType::Datagram); + close(s).unwrap(); + } + + #[cfg(any(target_os = "freebsd", + target_os = "linux"))] + #[test] + fn can_get_listen_on_tcp_socket() { + use super::super::*; + use crate::unistd::close; + + let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap(); + let s_listening = getsockopt(s, super::AcceptConn).unwrap(); + assert!(!s_listening); + listen(s, 10).unwrap(); + let s_listening2 = getsockopt(s, super::AcceptConn).unwrap(); + assert!(s_listening2); + close(s).unwrap(); + } + +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/stat.rs b/utshell-0.5.0/vendor/nix/src/sys/stat.rs new file mode 100644 index 00000000..8b7627d5 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/stat.rs @@ -0,0 +1,436 @@ +pub use libc::{dev_t, mode_t}; +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))] +pub use libc::c_uint; +#[cfg(any( + target_os = "netbsd", + target_os = "freebsd", + target_os = "dragonfly" +))] +pub use libc::c_ulong; +pub use libc::stat as FileStat; + +use crate::{Result, NixPath, errno::Errno}; +#[cfg(not(target_os = "redox"))] +use crate::fcntl::{AtFlags, at_rawfd}; +use std::mem; +use std::os::unix::io::RawFd; +use crate::sys::time::{TimeSpec, TimeVal}; + +libc_bitflags!( + /// "File type" flags for `mknod` and related functions. + pub struct SFlag: mode_t { + S_IFIFO; + S_IFCHR; + S_IFDIR; + S_IFBLK; + S_IFREG; + S_IFLNK; + S_IFSOCK; + S_IFMT; + } +); + +libc_bitflags! { + /// "File mode / permissions" flags. + pub struct Mode: mode_t { + S_IRWXU; + S_IRUSR; + S_IWUSR; + S_IXUSR; + S_IRWXG; + S_IRGRP; + S_IWGRP; + S_IXGRP; + S_IRWXO; + S_IROTH; + S_IWOTH; + S_IXOTH; + S_ISUID as mode_t; + S_ISGID as mode_t; + S_ISVTX as mode_t; + } +} + +#[cfg(any(target_os = "macos", target_os = "ios", target_os="openbsd"))] +pub type type_of_file_flag = c_uint; +#[cfg(any( + target_os = "netbsd", + target_os = "freebsd", + target_os = "dragonfly" +))] +pub type type_of_file_flag = c_ulong; + +#[cfg(any( + target_os = "openbsd", + target_os = "netbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "macos", + target_os = "ios" +))] +libc_bitflags! { + /// File flags. + #[cfg_attr(docsrs, doc(cfg(all())))] + pub struct FileFlag: type_of_file_flag { + /// The file may only be appended to. + SF_APPEND; + /// The file has been archived. + SF_ARCHIVED; + #[cfg(any(target_os = "dragonfly"))] + SF_CACHE; + /// The file may not be changed. + SF_IMMUTABLE; + /// Indicates a WAPBL journal file. + #[cfg(any(target_os = "netbsd"))] + SF_LOG; + /// Do not retain history for file + #[cfg(any(target_os = "dragonfly"))] + SF_NOHISTORY; + /// The file may not be renamed or deleted. + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + SF_NOUNLINK; + /// Mask of superuser changeable flags + SF_SETTABLE; + /// Snapshot is invalid. + #[cfg(any(target_os = "netbsd"))] + SF_SNAPINVAL; + /// The file is a snapshot file. + #[cfg(any(target_os = "netbsd", target_os = "freebsd"))] + SF_SNAPSHOT; + #[cfg(any(target_os = "dragonfly"))] + SF_XLINK; + /// The file may only be appended to. + UF_APPEND; + /// The file needs to be archived. + #[cfg(any(target_os = "freebsd"))] + UF_ARCHIVE; + #[cfg(any(target_os = "dragonfly"))] + UF_CACHE; + /// File is compressed at the file system level. + #[cfg(any(target_os = "macos", target_os = "ios"))] + UF_COMPRESSED; + /// The file may be hidden from directory listings at the application's + /// discretion. + #[cfg(any( + target_os = "freebsd", + target_os = "macos", + target_os = "ios", + ))] + UF_HIDDEN; + /// The file may not be changed. + UF_IMMUTABLE; + /// Do not dump the file. + UF_NODUMP; + #[cfg(any(target_os = "dragonfly"))] + UF_NOHISTORY; + /// The file may not be renamed or deleted. + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + UF_NOUNLINK; + /// The file is offline, or has the Windows and CIFS + /// `FILE_ATTRIBUTE_OFFLINE` attribute. + #[cfg(any(target_os = "freebsd"))] + UF_OFFLINE; + /// The directory is opaque when viewed through a union stack. + UF_OPAQUE; + /// The file is read only, and may not be written or appended. + #[cfg(any(target_os = "freebsd"))] + UF_READONLY; + /// The file contains a Windows reparse point. + #[cfg(any(target_os = "freebsd"))] + UF_REPARSE; + /// Mask of owner changeable flags. + UF_SETTABLE; + /// The file has the Windows `FILE_ATTRIBUTE_SPARSE_FILE` attribute. + #[cfg(any(target_os = "freebsd"))] + UF_SPARSE; + /// The file has the DOS, Windows and CIFS `FILE_ATTRIBUTE_SYSTEM` + /// attribute. + #[cfg(any(target_os = "freebsd"))] + UF_SYSTEM; + /// File renames and deletes are tracked. + #[cfg(any(target_os = "macos", target_os = "ios"))] + UF_TRACKED; + #[cfg(any(target_os = "dragonfly"))] + UF_XLINK; + } +} + +/// Create a special or ordinary file, by pathname. +pub fn mknod(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> { + let res = path.with_nix_path(|cstr| unsafe { + libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) + })?; + + Errno::result(res).map(drop) +} + +/// Create a special or ordinary file, relative to a given directory. +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn mknodat( + dirfd: RawFd, + path: &P, + kind: SFlag, + perm: Mode, + dev: dev_t, +) -> Result<()> { + let res = path.with_nix_path(|cstr| unsafe { + libc::mknodat(dirfd, cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) + })?; + + Errno::result(res).map(drop) +} + +#[cfg(target_os = "linux")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub const fn major(dev: dev_t) -> u64 { + ((dev >> 32) & 0xffff_f000) | + ((dev >> 8) & 0x0000_0fff) +} + +#[cfg(target_os = "linux")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub const fn minor(dev: dev_t) -> u64 { + ((dev >> 12) & 0xffff_ff00) | + ((dev ) & 0x0000_00ff) +} + +#[cfg(target_os = "linux")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub const fn makedev(major: u64, minor: u64) -> dev_t { + ((major & 0xffff_f000) << 32) | + ((major & 0x0000_0fff) << 8) | + ((minor & 0xffff_ff00) << 12) | + (minor & 0x0000_00ff) +} + +pub fn umask(mode: Mode) -> Mode { + let prev = unsafe { libc::umask(mode.bits() as mode_t) }; + Mode::from_bits(prev).expect("[BUG] umask returned invalid Mode") +} + +pub fn stat(path: &P) -> Result { + let mut dst = mem::MaybeUninit::uninit(); + let res = path.with_nix_path(|cstr| { + unsafe { + libc::stat(cstr.as_ptr(), dst.as_mut_ptr()) + } + })?; + + Errno::result(res)?; + + Ok(unsafe{dst.assume_init()}) +} + +pub fn lstat(path: &P) -> Result { + let mut dst = mem::MaybeUninit::uninit(); + let res = path.with_nix_path(|cstr| { + unsafe { + libc::lstat(cstr.as_ptr(), dst.as_mut_ptr()) + } + })?; + + Errno::result(res)?; + + Ok(unsafe{dst.assume_init()}) +} + +pub fn fstat(fd: RawFd) -> Result { + let mut dst = mem::MaybeUninit::uninit(); + let res = unsafe { libc::fstat(fd, dst.as_mut_ptr()) }; + + Errno::result(res)?; + + Ok(unsafe{dst.assume_init()}) +} + +#[cfg(not(target_os = "redox"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn fstatat(dirfd: RawFd, pathname: &P, f: AtFlags) -> Result { + let mut dst = mem::MaybeUninit::uninit(); + let res = pathname.with_nix_path(|cstr| { + unsafe { libc::fstatat(dirfd, cstr.as_ptr(), dst.as_mut_ptr(), f.bits() as libc::c_int) } + })?; + + Errno::result(res)?; + + Ok(unsafe{dst.assume_init()}) +} + +/// Change the file permission bits of the file specified by a file descriptor. +/// +/// # References +/// +/// [fchmod(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html). +pub fn fchmod(fd: RawFd, mode: Mode) -> Result<()> { + let res = unsafe { libc::fchmod(fd, mode.bits() as mode_t) }; + + Errno::result(res).map(drop) +} + +/// Flags for `fchmodat` function. +#[derive(Clone, Copy, Debug)] +pub enum FchmodatFlags { + FollowSymlink, + NoFollowSymlink, +} + +/// Change the file permission bits. +/// +/// The file to be changed is determined relative to the directory associated +/// with the file descriptor `dirfd` or the current working directory +/// if `dirfd` is `None`. +/// +/// If `flag` is `FchmodatFlags::NoFollowSymlink` and `path` names a symbolic link, +/// then the mode of the symbolic link is changed. +/// +/// `fchmodat(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to +/// a call `libc::chmod(path, mode)`. That's why `chmod` is unimplemented +/// in the `nix` crate. +/// +/// # References +/// +/// [fchmodat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html). +#[cfg(not(target_os = "redox"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn fchmodat( + dirfd: Option, + path: &P, + mode: Mode, + flag: FchmodatFlags, +) -> Result<()> { + let atflag = + match flag { + FchmodatFlags::FollowSymlink => AtFlags::empty(), + FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, + }; + let res = path.with_nix_path(|cstr| unsafe { + libc::fchmodat( + at_rawfd(dirfd), + cstr.as_ptr(), + mode.bits() as mode_t, + atflag.bits() as libc::c_int, + ) + })?; + + Errno::result(res).map(drop) +} + +/// Change the access and modification times of a file. +/// +/// `utimes(path, times)` is identical to +/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)`. The former +/// is a deprecated API so prefer using the latter if the platforms you care +/// about support it. +/// +/// # References +/// +/// [utimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html). +pub fn utimes(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> { + let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = path.with_nix_path(|cstr| unsafe { + libc::utimes(cstr.as_ptr(), ×[0]) + })?; + + Errno::result(res).map(drop) +} + +/// Change the access and modification times of a file without following symlinks. +/// +/// `lutimes(path, times)` is identical to +/// `utimensat(None, path, times, UtimensatFlags::NoFollowSymlink)`. The former +/// is a deprecated API so prefer using the latter if the platforms you care +/// about support it. +/// +/// # References +/// +/// [lutimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lutimes.html). +#[cfg(any(target_os = "linux", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn lutimes(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> { + let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = path.with_nix_path(|cstr| unsafe { + libc::lutimes(cstr.as_ptr(), ×[0]) + })?; + + Errno::result(res).map(drop) +} + +/// Change the access and modification times of the file specified by a file descriptor. +/// +/// # References +/// +/// [futimens(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html). +#[inline] +pub fn futimens(fd: RawFd, atime: &TimeSpec, mtime: &TimeSpec) -> Result<()> { + let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = unsafe { libc::futimens(fd, ×[0]) }; + + Errno::result(res).map(drop) +} + +/// Flags for `utimensat` function. +// TODO: replace with fcntl::AtFlags +#[derive(Clone, Copy, Debug)] +pub enum UtimensatFlags { + FollowSymlink, + NoFollowSymlink, +} + +/// Change the access and modification times of a file. +/// +/// The file to be changed is determined relative to the directory associated +/// with the file descriptor `dirfd` or the current working directory +/// if `dirfd` is `None`. +/// +/// If `flag` is `UtimensatFlags::NoFollowSymlink` and `path` names a symbolic link, +/// then the mode of the symbolic link is changed. +/// +/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)` is identical to +/// `utimes(path, times)`. The latter is a deprecated API so prefer using the +/// former if the platforms you care about support it. +/// +/// # References +/// +/// [utimensat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html). +#[cfg(not(target_os = "redox"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn utimensat( + dirfd: Option, + path: &P, + atime: &TimeSpec, + mtime: &TimeSpec, + flag: UtimensatFlags +) -> Result<()> { + let atflag = + match flag { + UtimensatFlags::FollowSymlink => AtFlags::empty(), + UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, + }; + let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = path.with_nix_path(|cstr| unsafe { + libc::utimensat( + at_rawfd(dirfd), + cstr.as_ptr(), + ×[0], + atflag.bits() as libc::c_int, + ) + })?; + + Errno::result(res).map(drop) +} + +#[cfg(not(target_os = "redox"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn mkdirat(fd: RawFd, path: &P, mode: Mode) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t) } + })?; + + Errno::result(res).map(drop) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/statfs.rs b/utshell-0.5.0/vendor/nix/src/sys/statfs.rs new file mode 100644 index 00000000..81e7be5a --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/statfs.rs @@ -0,0 +1,764 @@ +//! Get filesystem statistics, non-portably +//! +//! See [`statvfs`](crate::sys::statvfs) for a portable alternative. +use std::fmt::{self, Debug}; +use std::mem; +use std::os::unix::io::AsRawFd; +#[cfg(not(any(target_os = "linux", target_os = "android")))] +use std::ffi::CStr; + +use crate::{NixPath, Result, errno::Errno}; + +/// Identifies a mounted file system +#[cfg(target_os = "android")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub type fsid_t = libc::__fsid_t; +/// Identifies a mounted file system +#[cfg(not(target_os = "android"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub type fsid_t = libc::fsid_t; + +/// Describes a mounted file system +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct Statfs(libc::statfs); + +#[cfg(target_os = "freebsd")] +type fs_type_t = u32; +#[cfg(target_os = "android")] +type fs_type_t = libc::c_ulong; +#[cfg(all(target_os = "linux", target_arch = "s390x"))] +type fs_type_t = libc::c_uint; +#[cfg(all(target_os = "linux", target_env = "musl"))] +type fs_type_t = libc::c_ulong; +#[cfg(all(target_os = "linux", target_env = "uclibc"))] +type fs_type_t = libc::c_int; +#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))] +type fs_type_t = libc::__fsword_t; + +/// Describes the file system type as known by the operating system. +#[cfg(any( + target_os = "freebsd", + target_os = "android", + all(target_os = "linux", target_arch = "s390x"), + all(target_os = "linux", target_env = "musl"), + all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))), +))] +#[derive(Eq, Copy, Clone, PartialEq, Debug)] +pub struct FsType(pub fs_type_t); + +// These constants are defined without documentation in the Linux headers, so we +// can't very well document them here. +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const AFS_SUPER_MAGIC: FsType = FsType(libc::AFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const AUTOFS_SUPER_MAGIC: FsType = FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const BPF_FS_MAGIC: FsType = FsType(libc::BPF_FS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const BTRFS_SUPER_MAGIC: FsType = FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const DEBUGFS_MAGIC: FsType = FsType(libc::DEBUGFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const DEVPTS_SUPER_MAGIC: FsType = FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const ECRYPTFS_SUPER_MAGIC: FsType = FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const F2FS_SUPER_MAGIC: FsType = FsType(libc::F2FS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const FUSE_SUPER_MAGIC: FsType = FsType(libc::FUSE_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const FUTEXFS_SUPER_MAGIC: FsType = FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const HOSTFS_SUPER_MAGIC: FsType = FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const MINIX3_SUPER_MAGIC: FsType = FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const NILFS_SUPER_MAGIC: FsType = FsType(libc::NILFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const OCFS2_SUPER_MAGIC: FsType = FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const QNX6_SUPER_MAGIC: FsType = FsType(libc::QNX6_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const RDTGROUP_SUPER_MAGIC: FsType = FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const SECURITYFS_MAGIC: FsType = FsType(libc::SECURITYFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const SELINUX_MAGIC: FsType = FsType(libc::SELINUX_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const SMACK_MAGIC: FsType = FsType(libc::SMACK_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const SYSFS_MAGIC: FsType = FsType(libc::SYSFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const TRACEFS_MAGIC: FsType = FsType(libc::TRACEFS_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const UDF_SUPER_MAGIC: FsType = FsType(libc::UDF_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t); +#[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(missing_docs)] +pub const XENFS_SUPER_MAGIC: FsType = FsType(libc::XENFS_SUPER_MAGIC as fs_type_t); + + +impl Statfs { + /// Magic code defining system type + #[cfg(not(any( + target_os = "openbsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "macos" + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn filesystem_type(&self) -> FsType { + FsType(self.0.f_type) + } + + /// Magic code defining system type + #[cfg(not(any(target_os = "linux", target_os = "android")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn filesystem_type_name(&self) -> &str { + let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) }; + c_str.to_str().unwrap() + } + + /// Optimal transfer block size + #[cfg(any(target_os = "ios", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> i32 { + self.0.f_iosize + } + + /// Optimal transfer block size + #[cfg(target_os = "openbsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> u32 { + self.0.f_iosize + } + + /// Optimal transfer block size + #[cfg(all(target_os = "linux", target_arch = "s390x"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> u32 { + self.0.f_bsize + } + + /// Optimal transfer block size + #[cfg(any( + target_os = "android", + all(target_os = "linux", target_env = "musl") + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> libc::c_ulong { + self.0.f_bsize + } + + /// Optimal transfer block size + #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> libc::__fsword_t { + self.0.f_bsize + } + + /// Optimal transfer block size + #[cfg(all(target_os = "linux", target_env = "uclibc"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> libc::c_int { + self.0.f_bsize + } + + /// Optimal transfer block size + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> libc::c_long { + self.0.f_iosize + } + + /// Optimal transfer block size + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> u64 { + self.0.f_iosize + } + + /// Size of a block + #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> u32 { + self.0.f_bsize + } + + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 + #[cfg(all(target_os = "linux", target_arch = "s390x"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> u32 { + self.0.f_bsize + } + + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 + #[cfg(all(target_os = "linux", target_env = "musl"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_ulong { + self.0.f_bsize + } + + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 + #[cfg(all(target_os = "linux", target_env = "uclibc"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_int { + self.0.f_bsize + } + + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 + #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::__fsword_t { + self.0.f_bsize + } + + /// Size of a block + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> u64 { + self.0.f_bsize + } + + /// Size of a block + #[cfg(target_os = "android")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_ulong { + self.0.f_bsize + } + + /// Size of a block + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_long { + self.0.f_bsize + } + + /// Maximum length of filenames + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> u32 { + self.0.f_namemax + } + + /// Maximum length of filenames + #[cfg(all(target_os = "linux", target_arch = "s390x"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> u32 { + self.0.f_namelen + } + + /// Maximum length of filenames + #[cfg(all(target_os = "linux", target_env = "musl"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> libc::c_ulong { + self.0.f_namelen + } + + /// Maximum length of filenames + #[cfg(all(target_os = "linux", target_env = "uclibc"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> libc::c_int { + self.0.f_namelen + } + + /// Maximum length of filenames + #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> libc::__fsword_t { + self.0.f_namelen + } + + /// Maximum length of filenames + #[cfg(target_os = "android")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> libc::c_ulong { + self.0.f_namelen + } + + /// Total data blocks in filesystem + #[cfg(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks(&self) -> u64 { + self.0.f_blocks + } + + /// Total data blocks in filesystem + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks(&self) -> libc::c_long { + self.0.f_blocks + } + + /// Total data blocks in filesystem + #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks(&self) -> u64 { + self.0.f_blocks + } + + /// Total data blocks in filesystem + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))) + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks(&self) -> libc::c_ulong { + self.0.f_blocks + } + + /// Free blocks in filesystem + #[cfg(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_free(&self) -> u64 { + self.0.f_bfree + } + + /// Free blocks in filesystem + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_free(&self) -> libc::c_long { + self.0.f_bfree + } + + /// Free blocks in filesystem + #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_free(&self) -> u64 { + self.0.f_bfree + } + + /// Free blocks in filesystem + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))) + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_free(&self) -> libc::c_ulong { + self.0.f_bfree + } + + /// Free blocks available to unprivileged user + #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> u64 { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> libc::c_long { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> i64 { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user + #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> u64 { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))) + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> libc::c_ulong { + self.0.f_bavail + } + + /// Total file nodes in filesystem + #[cfg(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files(&self) -> u64 { + self.0.f_files + } + + /// Total file nodes in filesystem + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files(&self) -> libc::c_long { + self.0.f_files + } + + /// Total file nodes in filesystem + #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files(&self) -> libc::fsfilcnt_t { + self.0.f_files + } + + /// Total file nodes in filesystem + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))) + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files(&self) -> libc::c_ulong { + self.0.f_files + } + + /// Free file nodes in filesystem + #[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> u64 { + self.0.f_ffree + } + + /// Free file nodes in filesystem + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> libc::c_long { + self.0.f_ffree + } + + /// Free file nodes in filesystem + #[cfg(target_os = "freebsd")] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> i64 { + self.0.f_ffree + } + + /// Free file nodes in filesystem + #[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> libc::fsfilcnt_t { + self.0.f_ffree + } + + /// Free file nodes in filesystem + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "android", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))) + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> libc::c_ulong { + self.0.f_ffree + } + + /// Filesystem ID + pub fn filesystem_id(&self) -> fsid_t { + self.0.f_fsid + } +} + +impl Debug for Statfs { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Statfs") + .field("optimal_transfer_size", &self.optimal_transfer_size()) + .field("block_size", &self.block_size()) + .field("blocks", &self.blocks()) + .field("blocks_free", &self.blocks_free()) + .field("blocks_available", &self.blocks_available()) + .field("files", &self.files()) + .field("files_free", &self.files_free()) + .field("filesystem_id", &self.filesystem_id()) + .finish() + } +} + +/// Describes a mounted file system. +/// +/// The result is OS-dependent. For a portable alternative, see +/// [`statvfs`](crate::sys::statvfs::statvfs). +/// +/// # Arguments +/// +/// `path` - Path to any file within the file system to describe +pub fn statfs(path: &P) -> Result { + unsafe { + let mut stat = mem::MaybeUninit::::uninit(); + let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?; + Errno::result(res).map(|_| Statfs(stat.assume_init())) + } +} + +/// Describes a mounted file system. +/// +/// The result is OS-dependent. For a portable alternative, see +/// [`fstatvfs`](crate::sys::statvfs::fstatvfs). +/// +/// # Arguments +/// +/// `fd` - File descriptor of any open file within the file system to describe +pub fn fstatfs(fd: &T) -> Result { + unsafe { + let mut stat = mem::MaybeUninit::::uninit(); + Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr())) + .map(|_| Statfs(stat.assume_init())) + } +} + +#[cfg(test)] +mod test { + use std::fs::File; + + use crate::sys::statfs::*; + use crate::sys::statvfs::*; + use std::path::Path; + + #[test] + fn statfs_call() { + check_statfs("/tmp"); + check_statfs("/dev"); + check_statfs("/run"); + check_statfs("/"); + } + + #[test] + fn fstatfs_call() { + check_fstatfs("/tmp"); + check_fstatfs("/dev"); + check_fstatfs("/run"); + check_fstatfs("/"); + } + + fn check_fstatfs(path: &str) { + if !Path::new(path).exists() { + return; + } + let vfs = statvfs(path.as_bytes()).unwrap(); + let file = File::open(path).unwrap(); + let fs = fstatfs(&file).unwrap(); + assert_fs_equals(fs, vfs); + } + + fn check_statfs(path: &str) { + if !Path::new(path).exists() { + return; + } + let vfs = statvfs(path.as_bytes()).unwrap(); + let fs = statfs(path.as_bytes()).unwrap(); + assert_fs_equals(fs, vfs); + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn assert_fs_equals(fs: Statfs, vfs: Statvfs) { + assert_eq!(fs.files() as u64, vfs.files() as u64); + assert_eq!(fs.blocks() as u64, vfs.blocks() as u64); + assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64); + } + + // This test is ignored because files_free/blocks_free can change after statvfs call and before + // statfs call. + #[test] + #[ignore] + fn statfs_call_strict() { + check_statfs_strict("/tmp"); + check_statfs_strict("/dev"); + check_statfs_strict("/run"); + check_statfs_strict("/"); + } + + // This test is ignored because files_free/blocks_free can change after statvfs call and before + // fstatfs call. + #[test] + #[ignore] + fn fstatfs_call_strict() { + check_fstatfs_strict("/tmp"); + check_fstatfs_strict("/dev"); + check_fstatfs_strict("/run"); + check_fstatfs_strict("/"); + } + + fn check_fstatfs_strict(path: &str) { + if !Path::new(path).exists() { + return; + } + let vfs = statvfs(path.as_bytes()); + let file = File::open(path).unwrap(); + let fs = fstatfs(&file); + assert_fs_equals_strict(fs.unwrap(), vfs.unwrap()) + } + + fn check_statfs_strict(path: &str) { + if !Path::new(path).exists() { + return; + } + let vfs = statvfs(path.as_bytes()); + let fs = statfs(path.as_bytes()); + assert_fs_equals_strict(fs.unwrap(), vfs.unwrap()) + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) { + assert_eq!(fs.files_free() as u64, vfs.files_free() as u64); + assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64); + assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64); + assert_eq!(fs.files() as u64, vfs.files() as u64); + assert_eq!(fs.blocks() as u64, vfs.blocks() as u64); + assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/statvfs.rs b/utshell-0.5.0/vendor/nix/src/sys/statvfs.rs new file mode 100644 index 00000000..38b1fdcc --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/statvfs.rs @@ -0,0 +1,174 @@ +//! Get filesystem statistics +//! +//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html) +//! for more details. +use std::mem; +use std::os::unix::io::AsRawFd; + +use libc::{self, c_ulong}; + +use crate::{Result, NixPath, errno::Errno}; + +#[cfg(not(target_os = "redox"))] +libc_bitflags!( + /// File system mount Flags + #[repr(C)] + #[derive(Default)] + pub struct FsFlags: c_ulong { + /// Read Only + #[cfg(not(target_os = "haiku"))] + ST_RDONLY; + /// Do not allow the set-uid bits to have an effect + #[cfg(not(target_os = "haiku"))] + ST_NOSUID; + /// Do not interpret character or block-special devices + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NODEV; + /// Do not allow execution of binaries on the filesystem + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NOEXEC; + /// All IO should be done synchronously + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_SYNCHRONOUS; + /// Allow mandatory locks on the filesystem + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_MANDLOCK; + /// Write on file/directory/symlink + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_WRITE; + /// Append-only file + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_APPEND; + /// Immutable file + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_IMMUTABLE; + /// Do not update access times on files + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NOATIME; + /// Do not update access times on files + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NODIRATIME; + /// Update access time relative to modify/change time + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ST_RELATIME; + } +); + +/// Wrapper around the POSIX `statvfs` struct +/// +/// For more information see the [`statvfs(3)` man pages](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html). +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct Statvfs(libc::statvfs); + +impl Statvfs { + /// get the file system block size + pub fn block_size(&self) -> c_ulong { + self.0.f_bsize + } + + /// Get the fundamental file system block size + pub fn fragment_size(&self) -> c_ulong { + self.0.f_frsize + } + + /// Get the number of blocks. + /// + /// Units are in units of `fragment_size()` + pub fn blocks(&self) -> libc::fsblkcnt_t { + self.0.f_blocks + } + + /// Get the number of free blocks in the file system + pub fn blocks_free(&self) -> libc::fsblkcnt_t { + self.0.f_bfree + } + + /// Get the number of free blocks for unprivileged users + pub fn blocks_available(&self) -> libc::fsblkcnt_t { + self.0.f_bavail + } + + /// Get the total number of file inodes + pub fn files(&self) -> libc::fsfilcnt_t { + self.0.f_files + } + + /// Get the number of free file inodes + pub fn files_free(&self) -> libc::fsfilcnt_t { + self.0.f_ffree + } + + /// Get the number of free file inodes for unprivileged users + pub fn files_available(&self) -> libc::fsfilcnt_t { + self.0.f_favail + } + + /// Get the file system id + pub fn filesystem_id(&self) -> c_ulong { + self.0.f_fsid + } + + /// Get the mount flags + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn flags(&self) -> FsFlags { + FsFlags::from_bits_truncate(self.0.f_flag) + } + + /// Get the maximum filename length + pub fn name_max(&self) -> c_ulong { + self.0.f_namemax + } + +} + +/// Return a `Statvfs` object with information about the `path` +pub fn statvfs(path: &P) -> Result { + unsafe { + Errno::clear(); + let mut stat = mem::MaybeUninit::::uninit(); + let res = path.with_nix_path(|path| + libc::statvfs(path.as_ptr(), stat.as_mut_ptr()) + )?; + + Errno::result(res).map(|_| Statvfs(stat.assume_init())) + } +} + +/// Return a `Statvfs` object with information about `fd` +pub fn fstatvfs(fd: &T) -> Result { + unsafe { + Errno::clear(); + let mut stat = mem::MaybeUninit::::uninit(); + Errno::result(libc::fstatvfs(fd.as_raw_fd(), stat.as_mut_ptr())) + .map(|_| Statvfs(stat.assume_init())) + } +} + +#[cfg(test)] +mod test { + use std::fs::File; + use crate::sys::statvfs::*; + + #[test] + fn statvfs_call() { + statvfs(&b"/"[..]).unwrap(); + } + + #[test] + fn fstatvfs_call() { + let root = File::open("/").unwrap(); + fstatvfs(&root).unwrap(); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/sysinfo.rs b/utshell-0.5.0/vendor/nix/src/sys/sysinfo.rs new file mode 100644 index 00000000..e8aa00b0 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/sysinfo.rs @@ -0,0 +1,83 @@ +use libc::{self, SI_LOAD_SHIFT}; +use std::time::Duration; +use std::{cmp, mem}; + +use crate::errno::Errno; +use crate::Result; + +/// System info structure returned by `sysinfo`. +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct SysInfo(libc::sysinfo); + +// The fields are c_ulong on 32-bit linux, u64 on 64-bit linux; x32's ulong is u32 +#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] +type mem_blocks_t = u64; +#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] +type mem_blocks_t = libc::c_ulong; + +impl SysInfo { + /// Returns the load average tuple. + /// + /// The returned values represent the load average over time intervals of + /// 1, 5, and 15 minutes, respectively. + pub fn load_average(&self) -> (f64, f64, f64) { + ( + self.0.loads[0] as f64 / (1 << SI_LOAD_SHIFT) as f64, + self.0.loads[1] as f64 / (1 << SI_LOAD_SHIFT) as f64, + self.0.loads[2] as f64 / (1 << SI_LOAD_SHIFT) as f64, + ) + } + + /// Returns the time since system boot. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + pub fn uptime(&self) -> Duration { + // Truncate negative values to 0 + Duration::from_secs(cmp::max(self.0.uptime, 0) as u64) + } + + /// Current number of processes. + pub fn process_count(&self) -> u16 { + self.0.procs + } + + /// Returns the amount of swap memory in Bytes. + pub fn swap_total(&self) -> u64 { + self.scale_mem(self.0.totalswap) + } + + /// Returns the amount of unused swap memory in Bytes. + pub fn swap_free(&self) -> u64 { + self.scale_mem(self.0.freeswap) + } + + /// Returns the total amount of installed RAM in Bytes. + pub fn ram_total(&self) -> u64 { + self.scale_mem(self.0.totalram) + } + + /// Returns the amount of completely unused RAM in Bytes. + /// + /// "Unused" in this context means that the RAM in neither actively used by + /// programs, nor by the operating system as disk cache or buffer. It is + /// "wasted" RAM since it currently serves no purpose. + pub fn ram_unused(&self) -> u64 { + self.scale_mem(self.0.freeram) + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn scale_mem(&self, units: mem_blocks_t) -> u64 { + units as u64 * self.0.mem_unit as u64 + } +} + +/// Returns system information. +/// +/// [See `sysinfo(2)`](https://man7.org/linux/man-pages/man2/sysinfo.2.html). +pub fn sysinfo() -> Result { + let mut info = mem::MaybeUninit::uninit(); + let res = unsafe { libc::sysinfo(info.as_mut_ptr()) }; + Errno::result(res).map(|_| unsafe { SysInfo(info.assume_init()) }) +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/termios.rs b/utshell-0.5.0/vendor/nix/src/sys/termios.rs new file mode 100644 index 00000000..d85db4d7 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/termios.rs @@ -0,0 +1,1118 @@ +//! An interface for controlling asynchronous communication ports +//! +//! This interface provides a safe wrapper around the termios subsystem defined by POSIX. The +//! underlying types are all implemented in libc for most platforms and either wrapped in safer +//! types here or exported directly. +//! +//! If you are unfamiliar with the `termios` API, you should first read the +//! [API documentation](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html) and +//! then come back to understand how `nix` safely wraps it. +//! +//! It should be noted that this API incurs some runtime overhead above the base `libc` definitions. +//! As this interface is not used with high-bandwidth information, this should be fine in most +//! cases. The primary cost when using this API is that the `Termios` datatype here duplicates the +//! standard fields of the underlying `termios` struct and uses safe type wrappers for those fields. +//! This means that when crossing the FFI interface to the underlying C library, data is first +//! copied into the underlying `termios` struct, then the operation is done, and the data is copied +//! back (with additional sanity checking) into the safe wrapper types. The `termios` struct is +//! relatively small across all platforms (on the order of 32-64 bytes). +//! +//! The following examples highlight some of the API use cases such that users coming from using C +//! or reading the standard documentation will understand how to use the safe API exposed here. +//! +//! Example disabling processing of the end-of-file control character: +//! +//! ``` +//! # use self::nix::sys::termios::SpecialCharacterIndices::VEOF; +//! # use self::nix::sys::termios::{_POSIX_VDISABLE, Termios}; +//! # let mut termios: Termios = unsafe { std::mem::zeroed() }; +//! termios.control_chars[VEOF as usize] = _POSIX_VDISABLE; +//! ``` +//! +//! The flags within `Termios` are defined as bitfields using the `bitflags` crate. This provides +//! an interface for working with bitfields that is similar to working with the raw unsigned +//! integer types but offers type safety because of the internal checking that values will always +//! be a valid combination of the defined flags. +//! +//! An example showing some of the basic operations for interacting with the control flags: +//! +//! ``` +//! # use self::nix::sys::termios::{ControlFlags, Termios}; +//! # let mut termios: Termios = unsafe { std::mem::zeroed() }; +//! termios.control_flags & ControlFlags::CSIZE == ControlFlags::CS5; +//! termios.control_flags |= ControlFlags::CS5; +//! ``` +//! +//! # Baud rates +//! +//! This API is not consistent across platforms when it comes to `BaudRate`: Android and Linux both +//! only support the rates specified by the `BaudRate` enum through their termios API while the BSDs +//! support arbitrary baud rates as the values of the `BaudRate` enum constants are the same integer +//! value of the constant (`B9600` == `9600`). Therefore the `nix::termios` API uses the following +//! conventions: +//! +//! * `cfgetispeed()` - Returns `u32` on BSDs, `BaudRate` on Android/Linux +//! * `cfgetospeed()` - Returns `u32` on BSDs, `BaudRate` on Android/Linux +//! * `cfsetispeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux +//! * `cfsetospeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux +//! * `cfsetspeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux +//! +//! The most common use case of specifying a baud rate using the enum will work the same across +//! platforms: +//! +//! ```rust +//! # use nix::sys::termios::{BaudRate, cfsetispeed, cfsetospeed, cfsetspeed, Termios}; +//! # fn main() { +//! # let mut t: Termios = unsafe { std::mem::zeroed() }; +//! cfsetispeed(&mut t, BaudRate::B9600).unwrap(); +//! cfsetospeed(&mut t, BaudRate::B9600).unwrap(); +//! cfsetspeed(&mut t, BaudRate::B9600).unwrap(); +//! # } +//! ``` +//! +//! Additionally round-tripping baud rates is consistent across platforms: +//! +//! ```rust +//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetispeed, cfsetspeed, Termios}; +//! # fn main() { +//! # let mut t: Termios = unsafe { std::mem::zeroed() }; +//! # cfsetspeed(&mut t, BaudRate::B9600).unwrap(); +//! let speed = cfgetispeed(&t); +//! assert_eq!(speed, cfgetospeed(&t)); +//! cfsetispeed(&mut t, speed).unwrap(); +//! # } +//! ``` +//! +//! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`: +//! +#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd"), + doc = " ```rust,ignore")] +#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd")), + doc = " ```rust")] +//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios}; +//! # fn main() { +//! # let mut t: Termios = unsafe { std::mem::zeroed() }; +//! # cfsetspeed(&mut t, BaudRate::B9600); +//! assert_eq!(cfgetispeed(&t), BaudRate::B9600); +//! assert_eq!(cfgetospeed(&t), BaudRate::B9600); +//! # } +//! ``` +//! +//! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s: +//! +#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd"), + doc = " ```rust")] +#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd")), + doc = " ```rust,ignore")] +//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios}; +//! # fn main() { +//! # let mut t: Termios = unsafe { std::mem::zeroed() }; +//! # cfsetspeed(&mut t, 9600u32); +//! assert_eq!(cfgetispeed(&t), 9600u32); +//! assert_eq!(cfgetospeed(&t), 9600u32); +//! # } +//! ``` +//! +//! It's trivial to convert from a `BaudRate` to a `u32` on BSDs: +//! +#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd"), + doc = " ```rust")] +#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd")), + doc = " ```rust,ignore")] +//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios}; +//! # fn main() { +//! # let mut t: Termios = unsafe { std::mem::zeroed() }; +//! # cfsetspeed(&mut t, 9600u32); +//! assert_eq!(cfgetispeed(&t), BaudRate::B9600.into()); +//! assert_eq!(u32::from(BaudRate::B9600), 9600u32); +//! # } +//! ``` +//! +//! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support) +//! by specifying baud rates directly using `u32`s: +//! +#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd"), + doc = " ```rust")] +#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", + target_os = "macos", target_os = "netbsd", target_os = "openbsd")), + doc = " ```rust,ignore")] +//! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios}; +//! # fn main() { +//! # let mut t: Termios = unsafe { std::mem::zeroed() }; +//! cfsetispeed(&mut t, 9600u32); +//! cfsetospeed(&mut t, 9600u32); +//! cfsetspeed(&mut t, 9600u32); +//! # } +//! ``` +use cfg_if::cfg_if; +use crate::Result; +use crate::errno::Errno; +use libc::{self, c_int, tcflag_t}; +use std::cell::{Ref, RefCell}; +use std::convert::From; +use std::mem; +use std::os::unix::io::RawFd; + +#[cfg(feature = "process")] +use crate::unistd::Pid; + +/// Stores settings for the termios API +/// +/// This is a wrapper around the `libc::termios` struct that provides a safe interface for the +/// standard fields. The only safe way to obtain an instance of this struct is to extract it from +/// an open port using `tcgetattr()`. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Termios { + inner: RefCell, + /// Input mode flags (see `termios.c_iflag` documentation) + pub input_flags: InputFlags, + /// Output mode flags (see `termios.c_oflag` documentation) + pub output_flags: OutputFlags, + /// Control mode flags (see `termios.c_cflag` documentation) + pub control_flags: ControlFlags, + /// Local mode flags (see `termios.c_lflag` documentation) + pub local_flags: LocalFlags, + /// Control characters (see `termios.c_cc` documentation) + pub control_chars: [libc::cc_t; NCCS], +} + +impl Termios { + /// Exposes an immutable reference to the underlying `libc::termios` data structure. + /// + /// This is not part of `nix`'s public API because it requires additional work to maintain type + /// safety. + pub(crate) fn get_libc_termios(&self) -> Ref { + { + let mut termios = self.inner.borrow_mut(); + termios.c_iflag = self.input_flags.bits(); + termios.c_oflag = self.output_flags.bits(); + termios.c_cflag = self.control_flags.bits(); + termios.c_lflag = self.local_flags.bits(); + termios.c_cc = self.control_chars; + } + self.inner.borrow() + } + + /// Exposes the inner `libc::termios` datastore within `Termios`. + /// + /// This is unsafe because if this is used to modify the inner `libc::termios` struct, it will + /// not automatically update the safe wrapper type around it. In this case it should also be + /// paired with a call to `update_wrapper()` so that the wrapper-type and internal + /// representation stay consistent. + pub(crate) unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios { + { + let mut termios = self.inner.borrow_mut(); + termios.c_iflag = self.input_flags.bits(); + termios.c_oflag = self.output_flags.bits(); + termios.c_cflag = self.control_flags.bits(); + termios.c_lflag = self.local_flags.bits(); + termios.c_cc = self.control_chars; + } + self.inner.as_ptr() + } + + /// Updates the wrapper values from the internal `libc::termios` data structure. + pub(crate) fn update_wrapper(&mut self) { + let termios = *self.inner.borrow_mut(); + self.input_flags = InputFlags::from_bits_truncate(termios.c_iflag); + self.output_flags = OutputFlags::from_bits_truncate(termios.c_oflag); + self.control_flags = ControlFlags::from_bits_truncate(termios.c_cflag); + self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag); + self.control_chars = termios.c_cc; + } +} + +impl From for Termios { + fn from(termios: libc::termios) -> Self { + Termios { + inner: RefCell::new(termios), + input_flags: InputFlags::from_bits_truncate(termios.c_iflag), + output_flags: OutputFlags::from_bits_truncate(termios.c_oflag), + control_flags: ControlFlags::from_bits_truncate(termios.c_cflag), + local_flags: LocalFlags::from_bits_truncate(termios.c_lflag), + control_chars: termios.c_cc, + } + } +} + +impl From for libc::termios { + fn from(termios: Termios) -> Self { + termios.inner.into_inner() + } +} + +libc_enum!{ + /// Baud rates supported by the system. + /// + /// For the BSDs, arbitrary baud rates can be specified by using `u32`s directly instead of this + /// enum. + /// + /// B0 is special and will disable the port. + #[cfg_attr(all(any(target_os = "haiku"), target_pointer_width = "64"), repr(u8))] + #[cfg_attr(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64"), repr(u64))] + #[cfg_attr(not(all(any(target_os = "ios", target_os = "macos", target_os = "haiku"), target_pointer_width = "64")), repr(u32))] + #[non_exhaustive] + pub enum BaudRate { + B0, + B50, + B75, + B110, + B134, + B150, + B200, + B300, + B600, + B1200, + B1800, + B2400, + B4800, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B7200, + B9600, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B14400, + B19200, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B28800, + B38400, + B57600, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B76800, + B115200, + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B153600, + B230400, + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B307200, + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B460800, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B500000, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B576000, + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B921600, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B1000000, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B1152000, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B1500000, + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B2000000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B2500000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B3000000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B3500000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + B4000000, + } + impl TryFrom +} + +#[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] +impl From for u32 { + fn from(b: BaudRate) -> u32 { + b as u32 + } +} + +#[cfg(target_os = "haiku")] +impl From for u8 { + fn from(b: BaudRate) -> u8 { + b as u8 + } +} + + +// TODO: Add TCSASOFT, which will require treating this as a bitfield. +libc_enum! { + /// Specify when a port configuration change should occur. + /// + /// Used as an argument to `tcsetattr()` + #[repr(i32)] + #[non_exhaustive] + pub enum SetArg { + /// The change will occur immediately + TCSANOW, + /// The change occurs after all output has been written + TCSADRAIN, + /// Same as `TCSADRAIN`, but will also flush the input buffer + TCSAFLUSH, + } +} + +libc_enum! { + /// Specify a combination of the input and output buffers to flush + /// + /// Used as an argument to `tcflush()`. + #[repr(i32)] + #[non_exhaustive] + pub enum FlushArg { + /// Flush data that was received but not read + TCIFLUSH, + /// Flush data written but not transmitted + TCOFLUSH, + /// Flush both received data not read and written data not transmitted + TCIOFLUSH, + } +} + +libc_enum! { + /// Specify how transmission flow should be altered + /// + /// Used as an argument to `tcflow()`. + #[repr(i32)] + #[non_exhaustive] + pub enum FlowArg { + /// Suspend transmission + TCOOFF, + /// Resume transmission + TCOON, + /// Transmit a STOP character, which should disable a connected terminal device + TCIOFF, + /// Transmit a START character, which should re-enable a connected terminal device + TCION, + } +} + +// TODO: Make this usable directly as a slice index. +#[cfg(not(target_os = "haiku"))] +libc_enum! { + /// Indices into the `termios.c_cc` array for special characters. + #[repr(usize)] + #[non_exhaustive] + pub enum SpecialCharacterIndices { + VDISCARD, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VDSUSP, + VEOF, + VEOL, + VEOL2, + VERASE, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VERASE2, + VINTR, + VKILL, + VLNEXT, + #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"), + target_os = "illumos", target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VMIN, + VQUIT, + VREPRINT, + VSTART, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VSTATUS, + VSTOP, + VSUSP, + #[cfg(target_os = "linux")] + #[cfg_attr(docsrs, doc(cfg(all())))] + VSWTC, + #[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VSWTCH, + #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"), + target_os = "illumos", target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VTIME, + VWERASE, + #[cfg(target_os = "dragonfly")] + #[cfg_attr(docsrs, doc(cfg(all())))] + VCHECKPT, + } +} + +#[cfg(any(all(target_os = "linux", target_arch = "sparc64"), + target_os = "illumos", target_os = "solaris"))] +impl SpecialCharacterIndices { + pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF; + pub const VTIME: SpecialCharacterIndices = SpecialCharacterIndices::VEOL; +} + +pub use libc::NCCS; +#[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub use libc::_POSIX_VDISABLE; + +libc_bitflags! { + /// Flags for configuring the input mode of a terminal + pub struct InputFlags: tcflag_t { + IGNBRK; + BRKINT; + IGNPAR; + PARMRK; + INPCK; + ISTRIP; + INLCR; + IGNCR; + ICRNL; + IXON; + IXOFF; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IXANY; + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IMAXBEL; + #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IUTF8; + } +} + +libc_bitflags! { + /// Flags for configuring the output mode of a terminal + pub struct OutputFlags: tcflag_t { + OPOST; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "linux", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + OLCUC; + ONLCR; + OCRNL as tcflag_t; + ONOCR as tcflag_t; + ONLRET as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + OFILL as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + OFDEL as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NL0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NL1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CR0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CR1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CR2 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CR3 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + TAB0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + TAB1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + TAB2 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + TAB3 as tcflag_t; + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + XTABS; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BS0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BS1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VT0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VT1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + FF0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + FF1 as tcflag_t; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + OXTABS; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ONOEOT as tcflag_t; + + // Bitmasks for use with OutputFlags to select specific settings + // These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110 + // is resolved. + + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NLDLY as tcflag_t; // FIXME: Datatype needs to be corrected in libc for mac + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CRDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + TABDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BSDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + VTDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + FFDLY as tcflag_t; + } +} + +libc_bitflags! { + /// Flags for setting the control mode of a terminal + pub struct ControlFlags: tcflag_t { + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CIGNORE; + CS5; + CS6; + CS7; + CS8; + CSTOPB; + CREAD; + PARENB; + PARODD; + HUPCL; + CLOCAL; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CRTSCTS; + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CBAUD; + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "mips"))))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CMSPAR; + #[cfg(any(target_os = "android", + all(target_os = "linux", + not(any(target_arch = "powerpc", target_arch = "powerpc64")))))] + CIBAUD; + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CBAUDEX; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MDMBUF; + #[cfg(any(target_os = "netbsd", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CHWFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CCTS_OFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CRTS_IFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CDTR_IFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CDSR_OFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + CCAR_OFLOW; + + // Bitmasks for use with ControlFlags to select specific settings + // These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110 + // is resolved. + + CSIZE; + } +} + +libc_bitflags! { + /// Flags for setting any local modes + pub struct LocalFlags: tcflag_t { + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ECHOKE; + ECHOE; + ECHOK; + ECHO; + ECHONL; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ECHOPRT; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ECHOCTL; + ISIG; + ICANON; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ALTWERASE; + IEXTEN; + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + EXTPROC; + TOSTOP; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + FLUSHO; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + NOKERNINFO; + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PENDIN; + NOFLSH; + } +} + +cfg_if!{ + if #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] { + /// Get input baud rate (see + /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). + /// + /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + pub fn cfgetispeed(termios: &Termios) -> u32 { + let inner_termios = termios.get_libc_termios(); + unsafe { libc::cfgetispeed(&*inner_termios) as u32 } + } + + /// Get output baud rate (see + /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). + /// + /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + pub fn cfgetospeed(termios: &Termios) -> u32 { + let inner_termios = termios.get_libc_termios(); + unsafe { libc::cfgetospeed(&*inner_termios) as u32 } + } + + /// Set input baud rate (see + /// [cfsetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)). + /// + /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure. + pub fn cfsetispeed>(termios: &mut Termios, baud: T) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetispeed(inner_termios, baud.into() as libc::speed_t) }; + termios.update_wrapper(); + Errno::result(res).map(drop) + } + + /// Set output baud rate (see + /// [cfsetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)). + /// + /// `cfsetospeed()` sets the output baud rate in the given termios structure. + pub fn cfsetospeed>(termios: &mut Termios, baud: T) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetospeed(inner_termios, baud.into() as libc::speed_t) }; + termios.update_wrapper(); + Errno::result(res).map(drop) + } + + /// Set both the input and output baud rates (see + /// [termios(3)](https://www.freebsd.org/cgi/man.cgi?query=cfsetspeed)). + /// + /// `cfsetspeed()` sets the input and output baud rate in the given termios structure. Note that + /// this is part of the 4.4BSD standard and not part of POSIX. + pub fn cfsetspeed>(termios: &mut Termios, baud: T) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetspeed(inner_termios, baud.into() as libc::speed_t) }; + termios.update_wrapper(); + Errno::result(res).map(drop) + } + } else { + use std::convert::TryInto; + + /// Get input baud rate (see + /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). + /// + /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure. + pub fn cfgetispeed(termios: &Termios) -> BaudRate { + let inner_termios = termios.get_libc_termios(); + unsafe { libc::cfgetispeed(&*inner_termios) }.try_into().unwrap() + } + + /// Get output baud rate (see + /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). + /// + /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure. + pub fn cfgetospeed(termios: &Termios) -> BaudRate { + let inner_termios = termios.get_libc_termios(); + unsafe { libc::cfgetospeed(&*inner_termios) }.try_into().unwrap() + } + + /// Set input baud rate (see + /// [cfsetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)). + /// + /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure. + pub fn cfsetispeed(termios: &mut Termios, baud: BaudRate) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetispeed(inner_termios, baud as libc::speed_t) }; + termios.update_wrapper(); + Errno::result(res).map(drop) + } + + /// Set output baud rate (see + /// [cfsetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)). + /// + /// `cfsetospeed()` sets the output baud rate in the given `Termios` structure. + pub fn cfsetospeed(termios: &mut Termios, baud: BaudRate) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetospeed(inner_termios, baud as libc::speed_t) }; + termios.update_wrapper(); + Errno::result(res).map(drop) + } + + /// Set both the input and output baud rates (see + /// [termios(3)](https://www.freebsd.org/cgi/man.cgi?query=cfsetspeed)). + /// + /// `cfsetspeed()` sets the input and output baud rate in the given `Termios` structure. Note that + /// this is part of the 4.4BSD standard and not part of POSIX. + #[cfg(not(target_os = "haiku"))] + pub fn cfsetspeed(termios: &mut Termios, baud: BaudRate) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetspeed(inner_termios, baud as libc::speed_t) }; + termios.update_wrapper(); + Errno::result(res).map(drop) + } + } +} + +/// Configures the port to something like the "raw" mode of the old Version 7 terminal driver (see +/// [termios(3)](https://man7.org/linux/man-pages/man3/termios.3.html)). +/// +/// `cfmakeraw()` configures the termios structure such that input is available character-by- +/// character, echoing is disabled, and all special input and output processing is disabled. Note +/// that this is a non-standard function, but is available on Linux and BSDs. +pub fn cfmakeraw(termios: &mut Termios) { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + unsafe { + libc::cfmakeraw(inner_termios); + } + termios.update_wrapper(); +} + +/// Configures the port to "sane" mode (like the configuration of a newly created terminal) (see +/// [tcsetattr(3)](https://www.freebsd.org/cgi/man.cgi?query=tcsetattr)). +/// +/// Note that this is a non-standard function, available on FreeBSD. +#[cfg(target_os = "freebsd")] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn cfmakesane(termios: &mut Termios) { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + unsafe { + libc::cfmakesane(inner_termios); + } + termios.update_wrapper(); +} + +/// Return the configuration of a port +/// [tcgetattr(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetattr.html)). +/// +/// `tcgetattr()` returns a `Termios` structure with the current configuration for a port. Modifying +/// this structure *will not* reconfigure the port, instead the modifications should be done to +/// the `Termios` structure and then the port should be reconfigured using `tcsetattr()`. +pub fn tcgetattr(fd: RawFd) -> Result { + let mut termios = mem::MaybeUninit::uninit(); + + let res = unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) }; + + Errno::result(res)?; + + unsafe { Ok(termios.assume_init().into()) } +} + +/// Set the configuration for a terminal (see +/// [tcsetattr(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetattr.html)). +/// +/// `tcsetattr()` reconfigures the given port based on a given `Termios` structure. This change +/// takes affect at a time specified by `actions`. Note that this function may return success if +/// *any* of the parameters were successfully set, not only if all were set successfully. +pub fn tcsetattr(fd: RawFd, actions: SetArg, termios: &Termios) -> Result<()> { + let inner_termios = termios.get_libc_termios(); + Errno::result(unsafe { libc::tcsetattr(fd, actions as c_int, &*inner_termios) }).map(drop) +} + +/// Block until all output data is written (see +/// [tcdrain(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcdrain.html)). +pub fn tcdrain(fd: RawFd) -> Result<()> { + Errno::result(unsafe { libc::tcdrain(fd) }).map(drop) +} + +/// Suspend or resume the transmission or reception of data (see +/// [tcflow(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflow.html)). +/// +/// `tcflow()` suspends of resumes the transmission or reception of data for the given port +/// depending on the value of `action`. +pub fn tcflow(fd: RawFd, action: FlowArg) -> Result<()> { + Errno::result(unsafe { libc::tcflow(fd, action as c_int) }).map(drop) +} + +/// Discard data in the output or input queue (see +/// [tcflush(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflush.html)). +/// +/// `tcflush()` will discard data for a terminal port in the input queue, output queue, or both +/// depending on the value of `action`. +pub fn tcflush(fd: RawFd, action: FlushArg) -> Result<()> { + Errno::result(unsafe { libc::tcflush(fd, action as c_int) }).map(drop) +} + +/// Send a break for a specific duration (see +/// [tcsendbreak(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsendbreak.html)). +/// +/// When using asynchronous data transmission `tcsendbreak()` will transmit a continuous stream +/// of zero-valued bits for an implementation-defined duration. +pub fn tcsendbreak(fd: RawFd, duration: c_int) -> Result<()> { + Errno::result(unsafe { libc::tcsendbreak(fd, duration) }).map(drop) +} + +feature! { +#![feature = "process"] +/// Get the session controlled by the given terminal (see +/// [tcgetsid(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetsid.html)). +pub fn tcgetsid(fd: RawFd) -> Result { + let res = unsafe { libc::tcgetsid(fd) }; + + Errno::result(res).map(Pid::from_raw) +} +} + +#[cfg(test)] +mod test { + use super::*; + use std::convert::TryFrom; + + #[test] + fn try_from() { + assert_eq!(Ok(BaudRate::B0), BaudRate::try_from(libc::B0)); + #[cfg(not(target_os = "haiku"))] + BaudRate::try_from(999999999).expect_err("assertion failed"); + #[cfg(target_os = "haiku")] + BaudRate::try_from(99).expect_err("assertion failed"); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/time.rs b/utshell-0.5.0/vendor/nix/src/sys/time.rs new file mode 100644 index 00000000..3d0bb5c7 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/time.rs @@ -0,0 +1,809 @@ +#[cfg_attr(target_env = "musl", allow(deprecated))] +// https://github.com/rust-lang/libc/issues/1848 +pub use libc::{suseconds_t, time_t}; +use libc::{timespec, timeval}; +use std::convert::From; +use std::time::Duration; +use std::{cmp, fmt, ops}; + +const TIMESPEC_ZERO: libc::timespec = unsafe { + std::mem::transmute([0u8; std::mem::size_of::()]) +}; + +#[cfg(any( + all(feature = "time", any(target_os = "android", target_os = "linux")), + all( + any( + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd" + ), + feature = "time", + feature = "signal" + ) +))] +pub(crate) mod timer { + use crate::sys::time::{TimeSpec, TIMESPEC_ZERO}; + use bitflags::bitflags; + + #[derive(Debug, Clone, Copy)] + pub(crate) struct TimerSpec(libc::itimerspec); + + impl TimerSpec { + pub const fn none() -> Self { + Self(libc::itimerspec { + it_interval: TIMESPEC_ZERO, + it_value: TIMESPEC_ZERO, + }) + } + } + + impl AsMut for TimerSpec { + fn as_mut(&mut self) -> &mut libc::itimerspec { + &mut self.0 + } + } + + impl AsRef for TimerSpec { + fn as_ref(&self) -> &libc::itimerspec { + &self.0 + } + } + + impl From for TimerSpec { + fn from(expiration: Expiration) -> TimerSpec { + match expiration { + Expiration::OneShot(t) => TimerSpec(libc::itimerspec { + it_interval: TIMESPEC_ZERO, + it_value: *t.as_ref(), + }), + Expiration::IntervalDelayed(start, interval) => { + TimerSpec(libc::itimerspec { + it_interval: *interval.as_ref(), + it_value: *start.as_ref(), + }) + } + Expiration::Interval(t) => TimerSpec(libc::itimerspec { + it_interval: *t.as_ref(), + it_value: *t.as_ref(), + }), + } + } + } + + /// An enumeration allowing the definition of the expiration time of an alarm, + /// recurring or not. + #[derive(Debug, Clone, Copy, Eq, PartialEq)] + pub enum Expiration { + /// Alarm will trigger once after the time given in `TimeSpec` + OneShot(TimeSpec), + /// Alarm will trigger after a specified delay and then every interval of + /// time. + IntervalDelayed(TimeSpec, TimeSpec), + /// Alarm will trigger every specified interval of time. + Interval(TimeSpec), + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + bitflags! { + /// Flags that are used for arming the timer. + pub struct TimerSetTimeFlags: libc::c_int { + const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME; + } + } + #[cfg(any( + target_os = "freebsd", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "illumos" + ))] + bitflags! { + /// Flags that are used for arming the timer. + pub struct TimerSetTimeFlags: libc::c_int { + const TFD_TIMER_ABSTIME = libc::TIMER_ABSTIME; + } + } + + impl From for Expiration { + fn from(timerspec: TimerSpec) -> Expiration { + match timerspec { + TimerSpec(libc::itimerspec { + it_interval: + libc::timespec { + tv_sec: 0, + tv_nsec: 0, + .. + }, + it_value: ts, + }) => Expiration::OneShot(ts.into()), + TimerSpec(libc::itimerspec { + it_interval: int_ts, + it_value: val_ts, + }) => { + if (int_ts.tv_sec == val_ts.tv_sec) + && (int_ts.tv_nsec == val_ts.tv_nsec) + { + Expiration::Interval(int_ts.into()) + } else { + Expiration::IntervalDelayed( + val_ts.into(), + int_ts.into(), + ) + } + } + } + } + } +} + +pub trait TimeValLike: Sized { + #[inline] + fn zero() -> Self { + Self::seconds(0) + } + + #[inline] + fn hours(hours: i64) -> Self { + let secs = hours + .checked_mul(SECS_PER_HOUR) + .expect("TimeValLike::hours ouf of bounds"); + Self::seconds(secs) + } + + #[inline] + fn minutes(minutes: i64) -> Self { + let secs = minutes + .checked_mul(SECS_PER_MINUTE) + .expect("TimeValLike::minutes out of bounds"); + Self::seconds(secs) + } + + fn seconds(seconds: i64) -> Self; + fn milliseconds(milliseconds: i64) -> Self; + fn microseconds(microseconds: i64) -> Self; + fn nanoseconds(nanoseconds: i64) -> Self; + + #[inline] + fn num_hours(&self) -> i64 { + self.num_seconds() / 3600 + } + + #[inline] + fn num_minutes(&self) -> i64 { + self.num_seconds() / 60 + } + + fn num_seconds(&self) -> i64; + fn num_milliseconds(&self) -> i64; + fn num_microseconds(&self) -> i64; + fn num_nanoseconds(&self) -> i64; +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct TimeSpec(timespec); + +const NANOS_PER_SEC: i64 = 1_000_000_000; +const SECS_PER_MINUTE: i64 = 60; +const SECS_PER_HOUR: i64 = 3600; + +#[cfg(target_pointer_width = "64")] +const TS_MAX_SECONDS: i64 = (i64::MAX / NANOS_PER_SEC) - 1; + +#[cfg(target_pointer_width = "32")] +const TS_MAX_SECONDS: i64 = isize::MAX as i64; + +const TS_MIN_SECONDS: i64 = -TS_MAX_SECONDS; + +// x32 compatibility +// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437 +#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] +type timespec_tv_nsec_t = i64; +#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] +type timespec_tv_nsec_t = libc::c_long; + +impl From for TimeSpec { + fn from(ts: timespec) -> Self { + Self(ts) + } +} + +impl From for TimeSpec { + fn from(duration: Duration) -> Self { + Self::from_duration(duration) + } +} + +impl From for Duration { + fn from(timespec: TimeSpec) -> Self { + Duration::new(timespec.0.tv_sec as u64, timespec.0.tv_nsec as u32) + } +} + +impl AsRef for TimeSpec { + fn as_ref(&self) -> ×pec { + &self.0 + } +} + +impl AsMut for TimeSpec { + fn as_mut(&mut self) -> &mut timespec { + &mut self.0 + } +} + +impl Ord for TimeSpec { + // The implementation of cmp is simplified by assuming that the struct is + // normalized. That is, tv_nsec must always be within [0, 1_000_000_000) + fn cmp(&self, other: &TimeSpec) -> cmp::Ordering { + if self.tv_sec() == other.tv_sec() { + self.tv_nsec().cmp(&other.tv_nsec()) + } else { + self.tv_sec().cmp(&other.tv_sec()) + } + } +} + +impl PartialOrd for TimeSpec { + fn partial_cmp(&self, other: &TimeSpec) -> Option { + Some(self.cmp(other)) + } +} + +impl TimeValLike for TimeSpec { + #[inline] + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 + fn seconds(seconds: i64) -> TimeSpec { + assert!( + (TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&seconds), + "TimeSpec out of bounds; seconds={}", + seconds + ); + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = seconds as time_t; + ts.tv_nsec = 0; + TimeSpec(ts) + } + + #[inline] + fn milliseconds(milliseconds: i64) -> TimeSpec { + let nanoseconds = milliseconds + .checked_mul(1_000_000) + .expect("TimeSpec::milliseconds out of bounds"); + + TimeSpec::nanoseconds(nanoseconds) + } + + /// Makes a new `TimeSpec` with given number of microseconds. + #[inline] + fn microseconds(microseconds: i64) -> TimeSpec { + let nanoseconds = microseconds + .checked_mul(1_000) + .expect("TimeSpec::milliseconds out of bounds"); + + TimeSpec::nanoseconds(nanoseconds) + } + + /// Makes a new `TimeSpec` with given number of nanoseconds. + #[inline] + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 + fn nanoseconds(nanoseconds: i64) -> TimeSpec { + let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC); + assert!( + (TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs), + "TimeSpec out of bounds" + ); + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = secs as time_t; + ts.tv_nsec = nanos as timespec_tv_nsec_t; + TimeSpec(ts) + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn num_seconds(&self) -> i64 { + if self.tv_sec() < 0 && self.tv_nsec() > 0 { + (self.tv_sec() + 1) as i64 + } else { + self.tv_sec() as i64 + } + } + + fn num_milliseconds(&self) -> i64 { + self.num_nanoseconds() / 1_000_000 + } + + fn num_microseconds(&self) -> i64 { + self.num_nanoseconds() / 1_000 + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn num_nanoseconds(&self) -> i64 { + let secs = self.num_seconds() * 1_000_000_000; + let nsec = self.nanos_mod_sec(); + secs + nsec as i64 + } +} + +impl TimeSpec { + /// Construct a new `TimeSpec` from its components + #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 + pub const fn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self { + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = seconds; + ts.tv_nsec = nanoseconds; + Self(ts) + } + + fn nanos_mod_sec(&self) -> timespec_tv_nsec_t { + if self.tv_sec() < 0 && self.tv_nsec() > 0 { + self.tv_nsec() - NANOS_PER_SEC as timespec_tv_nsec_t + } else { + self.tv_nsec() + } + } + + #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 + pub const fn tv_sec(&self) -> time_t { + self.0.tv_sec + } + + pub const fn tv_nsec(&self) -> timespec_tv_nsec_t { + self.0.tv_nsec + } + + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 + pub const fn from_duration(duration: Duration) -> Self { + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = duration.as_secs() as time_t; + ts.tv_nsec = duration.subsec_nanos() as timespec_tv_nsec_t; + TimeSpec(ts) + } + + pub const fn from_timespec(timespec: timespec) -> Self { + Self(timespec) + } +} + +impl ops::Neg for TimeSpec { + type Output = TimeSpec; + + fn neg(self) -> TimeSpec { + TimeSpec::nanoseconds(-self.num_nanoseconds()) + } +} + +impl ops::Add for TimeSpec { + type Output = TimeSpec; + + fn add(self, rhs: TimeSpec) -> TimeSpec { + TimeSpec::nanoseconds(self.num_nanoseconds() + rhs.num_nanoseconds()) + } +} + +impl ops::Sub for TimeSpec { + type Output = TimeSpec; + + fn sub(self, rhs: TimeSpec) -> TimeSpec { + TimeSpec::nanoseconds(self.num_nanoseconds() - rhs.num_nanoseconds()) + } +} + +impl ops::Mul for TimeSpec { + type Output = TimeSpec; + + fn mul(self, rhs: i32) -> TimeSpec { + let usec = self + .num_nanoseconds() + .checked_mul(i64::from(rhs)) + .expect("TimeSpec multiply out of bounds"); + + TimeSpec::nanoseconds(usec) + } +} + +impl ops::Div for TimeSpec { + type Output = TimeSpec; + + fn div(self, rhs: i32) -> TimeSpec { + let usec = self.num_nanoseconds() / i64::from(rhs); + TimeSpec::nanoseconds(usec) + } +} + +impl fmt::Display for TimeSpec { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (abs, sign) = if self.tv_sec() < 0 { + (-*self, "-") + } else { + (*self, "") + }; + + let sec = abs.tv_sec(); + + write!(f, "{}", sign)?; + + if abs.tv_nsec() == 0 { + if abs.tv_sec() == 1 { + write!(f, "{} second", sec)?; + } else { + write!(f, "{} seconds", sec)?; + } + } else if abs.tv_nsec() % 1_000_000 == 0 { + write!(f, "{}.{:03} seconds", sec, abs.tv_nsec() / 1_000_000)?; + } else if abs.tv_nsec() % 1_000 == 0 { + write!(f, "{}.{:06} seconds", sec, abs.tv_nsec() / 1_000)?; + } else { + write!(f, "{}.{:09} seconds", sec, abs.tv_nsec())?; + } + + Ok(()) + } +} + +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct TimeVal(timeval); + +const MICROS_PER_SEC: i64 = 1_000_000; + +#[cfg(target_pointer_width = "64")] +const TV_MAX_SECONDS: i64 = (i64::MAX / MICROS_PER_SEC) - 1; + +#[cfg(target_pointer_width = "32")] +const TV_MAX_SECONDS: i64 = isize::MAX as i64; + +const TV_MIN_SECONDS: i64 = -TV_MAX_SECONDS; + +impl AsRef for TimeVal { + fn as_ref(&self) -> &timeval { + &self.0 + } +} + +impl AsMut for TimeVal { + fn as_mut(&mut self) -> &mut timeval { + &mut self.0 + } +} + +impl Ord for TimeVal { + // The implementation of cmp is simplified by assuming that the struct is + // normalized. That is, tv_usec must always be within [0, 1_000_000) + fn cmp(&self, other: &TimeVal) -> cmp::Ordering { + if self.tv_sec() == other.tv_sec() { + self.tv_usec().cmp(&other.tv_usec()) + } else { + self.tv_sec().cmp(&other.tv_sec()) + } + } +} + +impl PartialOrd for TimeVal { + fn partial_cmp(&self, other: &TimeVal) -> Option { + Some(self.cmp(other)) + } +} + +impl TimeValLike for TimeVal { + #[inline] + fn seconds(seconds: i64) -> TimeVal { + assert!( + (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&seconds), + "TimeVal out of bounds; seconds={}", + seconds + ); + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 + TimeVal(timeval { + tv_sec: seconds as time_t, + tv_usec: 0, + }) + } + + #[inline] + fn milliseconds(milliseconds: i64) -> TimeVal { + let microseconds = milliseconds + .checked_mul(1_000) + .expect("TimeVal::milliseconds out of bounds"); + + TimeVal::microseconds(microseconds) + } + + /// Makes a new `TimeVal` with given number of microseconds. + #[inline] + fn microseconds(microseconds: i64) -> TimeVal { + let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); + assert!( + (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), + "TimeVal out of bounds" + ); + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 + TimeVal(timeval { + tv_sec: secs as time_t, + tv_usec: micros as suseconds_t, + }) + } + + /// Makes a new `TimeVal` with given number of nanoseconds. Some precision + /// will be lost + #[inline] + fn nanoseconds(nanoseconds: i64) -> TimeVal { + let microseconds = nanoseconds / 1000; + let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); + assert!( + (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), + "TimeVal out of bounds" + ); + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 + TimeVal(timeval { + tv_sec: secs as time_t, + tv_usec: micros as suseconds_t, + }) + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn num_seconds(&self) -> i64 { + if self.tv_sec() < 0 && self.tv_usec() > 0 { + (self.tv_sec() + 1) as i64 + } else { + self.tv_sec() as i64 + } + } + + fn num_milliseconds(&self) -> i64 { + self.num_microseconds() / 1_000 + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + fn num_microseconds(&self) -> i64 { + let secs = self.num_seconds() * 1_000_000; + let usec = self.micros_mod_sec(); + secs + usec as i64 + } + + fn num_nanoseconds(&self) -> i64 { + self.num_microseconds() * 1_000 + } +} + +impl TimeVal { + /// Construct a new `TimeVal` from its components + #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 + pub const fn new(seconds: time_t, microseconds: suseconds_t) -> Self { + Self(timeval { + tv_sec: seconds, + tv_usec: microseconds, + }) + } + + fn micros_mod_sec(&self) -> suseconds_t { + if self.tv_sec() < 0 && self.tv_usec() > 0 { + self.tv_usec() - MICROS_PER_SEC as suseconds_t + } else { + self.tv_usec() + } + } + + #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 + pub const fn tv_sec(&self) -> time_t { + self.0.tv_sec + } + + pub const fn tv_usec(&self) -> suseconds_t { + self.0.tv_usec + } +} + +impl ops::Neg for TimeVal { + type Output = TimeVal; + + fn neg(self) -> TimeVal { + TimeVal::microseconds(-self.num_microseconds()) + } +} + +impl ops::Add for TimeVal { + type Output = TimeVal; + + fn add(self, rhs: TimeVal) -> TimeVal { + TimeVal::microseconds(self.num_microseconds() + rhs.num_microseconds()) + } +} + +impl ops::Sub for TimeVal { + type Output = TimeVal; + + fn sub(self, rhs: TimeVal) -> TimeVal { + TimeVal::microseconds(self.num_microseconds() - rhs.num_microseconds()) + } +} + +impl ops::Mul for TimeVal { + type Output = TimeVal; + + fn mul(self, rhs: i32) -> TimeVal { + let usec = self + .num_microseconds() + .checked_mul(i64::from(rhs)) + .expect("TimeVal multiply out of bounds"); + + TimeVal::microseconds(usec) + } +} + +impl ops::Div for TimeVal { + type Output = TimeVal; + + fn div(self, rhs: i32) -> TimeVal { + let usec = self.num_microseconds() / i64::from(rhs); + TimeVal::microseconds(usec) + } +} + +impl fmt::Display for TimeVal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (abs, sign) = if self.tv_sec() < 0 { + (-*self, "-") + } else { + (*self, "") + }; + + let sec = abs.tv_sec(); + + write!(f, "{}", sign)?; + + if abs.tv_usec() == 0 { + if abs.tv_sec() == 1 { + write!(f, "{} second", sec)?; + } else { + write!(f, "{} seconds", sec)?; + } + } else if abs.tv_usec() % 1000 == 0 { + write!(f, "{}.{:03} seconds", sec, abs.tv_usec() / 1000)?; + } else { + write!(f, "{}.{:06} seconds", sec, abs.tv_usec())?; + } + + Ok(()) + } +} + +impl From for TimeVal { + fn from(tv: timeval) -> Self { + TimeVal(tv) + } +} + +#[inline] +fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) { + (div_floor_64(this, other), mod_floor_64(this, other)) +} + +#[inline] +fn div_floor_64(this: i64, other: i64) -> i64 { + match div_rem_64(this, other) { + (d, r) if (r > 0 && other < 0) || (r < 0 && other > 0) => d - 1, + (d, _) => d, + } +} + +#[inline] +fn mod_floor_64(this: i64, other: i64) -> i64 { + match this % other { + r if (r > 0 && other < 0) || (r < 0 && other > 0) => r + other, + r => r, + } +} + +#[inline] +fn div_rem_64(this: i64, other: i64) -> (i64, i64) { + (this / other, this % other) +} + +#[cfg(test)] +mod test { + use super::{TimeSpec, TimeVal, TimeValLike}; + use std::time::Duration; + + #[test] + pub fn test_timespec() { + assert_ne!(TimeSpec::seconds(1), TimeSpec::zero()); + assert_eq!( + TimeSpec::seconds(1) + TimeSpec::seconds(2), + TimeSpec::seconds(3) + ); + assert_eq!( + TimeSpec::minutes(3) + TimeSpec::seconds(2), + TimeSpec::seconds(182) + ); + } + + #[test] + pub fn test_timespec_from() { + let duration = Duration::new(123, 123_456_789); + let timespec = TimeSpec::nanoseconds(123_123_456_789); + + assert_eq!(TimeSpec::from(duration), timespec); + assert_eq!(Duration::from(timespec), duration); + } + + #[test] + pub fn test_timespec_neg() { + let a = TimeSpec::seconds(1) + TimeSpec::nanoseconds(123); + let b = TimeSpec::seconds(-1) + TimeSpec::nanoseconds(-123); + + assert_eq!(a, -b); + } + + #[test] + pub fn test_timespec_ord() { + assert_eq!(TimeSpec::seconds(1), TimeSpec::nanoseconds(1_000_000_000)); + assert!(TimeSpec::seconds(1) < TimeSpec::nanoseconds(1_000_000_001)); + assert!(TimeSpec::seconds(1) > TimeSpec::nanoseconds(999_999_999)); + assert!(TimeSpec::seconds(-1) < TimeSpec::nanoseconds(-999_999_999)); + assert!(TimeSpec::seconds(-1) > TimeSpec::nanoseconds(-1_000_000_001)); + } + + #[test] + pub fn test_timespec_fmt() { + assert_eq!(TimeSpec::zero().to_string(), "0 seconds"); + assert_eq!(TimeSpec::seconds(42).to_string(), "42 seconds"); + assert_eq!(TimeSpec::milliseconds(42).to_string(), "0.042 seconds"); + assert_eq!(TimeSpec::microseconds(42).to_string(), "0.000042 seconds"); + assert_eq!( + TimeSpec::nanoseconds(42).to_string(), + "0.000000042 seconds" + ); + assert_eq!(TimeSpec::seconds(-86401).to_string(), "-86401 seconds"); + } + + #[test] + pub fn test_timeval() { + assert_ne!(TimeVal::seconds(1), TimeVal::zero()); + assert_eq!( + TimeVal::seconds(1) + TimeVal::seconds(2), + TimeVal::seconds(3) + ); + assert_eq!( + TimeVal::minutes(3) + TimeVal::seconds(2), + TimeVal::seconds(182) + ); + } + + #[test] + pub fn test_timeval_ord() { + assert_eq!(TimeVal::seconds(1), TimeVal::microseconds(1_000_000)); + assert!(TimeVal::seconds(1) < TimeVal::microseconds(1_000_001)); + assert!(TimeVal::seconds(1) > TimeVal::microseconds(999_999)); + assert!(TimeVal::seconds(-1) < TimeVal::microseconds(-999_999)); + assert!(TimeVal::seconds(-1) > TimeVal::microseconds(-1_000_001)); + } + + #[test] + pub fn test_timeval_neg() { + let a = TimeVal::seconds(1) + TimeVal::microseconds(123); + let b = TimeVal::seconds(-1) + TimeVal::microseconds(-123); + + assert_eq!(a, -b); + } + + #[test] + pub fn test_timeval_fmt() { + assert_eq!(TimeVal::zero().to_string(), "0 seconds"); + assert_eq!(TimeVal::seconds(42).to_string(), "42 seconds"); + assert_eq!(TimeVal::milliseconds(42).to_string(), "0.042 seconds"); + assert_eq!(TimeVal::microseconds(42).to_string(), "0.000042 seconds"); + assert_eq!(TimeVal::nanoseconds(1402).to_string(), "0.000001 seconds"); + assert_eq!(TimeVal::seconds(-86401).to_string(), "-86401 seconds"); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/timer.rs b/utshell-0.5.0/vendor/nix/src/sys/timer.rs new file mode 100644 index 00000000..45ce0e5b --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/timer.rs @@ -0,0 +1,179 @@ +//! Timer API via signals. +//! +//! Timer is a POSIX API to create timers and get expiration notifications +//! through queued Unix signals, for the current process. This is similar to +//! Linux's timerfd mechanism, except that API is specific to Linux and makes +//! use of file polling. +//! +//! For more documentation, please read [timer_create](https://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html). +//! +//! # Examples +//! +//! Create an interval timer that signals SIGALARM every 250 milliseconds. +//! +//! ```no_run +//! use nix::sys::signal::{self, SigEvent, SigHandler, SigevNotify, Signal}; +//! use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags}; +//! use nix::time::ClockId; +//! use std::convert::TryFrom; +//! use std::sync::atomic::{AtomicU64, Ordering}; +//! use std::thread::yield_now; +//! use std::time::Duration; +//! +//! const SIG: Signal = Signal::SIGALRM; +//! static ALARMS: AtomicU64 = AtomicU64::new(0); +//! +//! extern "C" fn handle_alarm(signal: libc::c_int) { +//! let signal = Signal::try_from(signal).unwrap(); +//! if signal == SIG { +//! ALARMS.fetch_add(1, Ordering::Relaxed); +//! } +//! } +//! +//! fn main() { +//! let clockid = ClockId::CLOCK_MONOTONIC; +//! let sigevent = SigEvent::new(SigevNotify::SigevSignal { +//! signal: SIG, +//! si_value: 0, +//! }); +//! +//! let mut timer = Timer::new(clockid, sigevent).unwrap(); +//! let expiration = Expiration::Interval(Duration::from_millis(250).into()); +//! let flags = TimerSetTimeFlags::empty(); +//! timer.set(expiration, flags).expect("could not set timer"); +//! +//! let handler = SigHandler::Handler(handle_alarm); +//! unsafe { signal::signal(SIG, handler) }.unwrap(); +//! +//! loop { +//! let alarms = ALARMS.load(Ordering::Relaxed); +//! if alarms >= 10 { +//! println!("total alarms handled: {}", alarms); +//! break; +//! } +//! yield_now() +//! } +//! } +//! ``` +use crate::sys::signal::SigEvent; +use crate::sys::time::timer::TimerSpec; +pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags}; +use crate::time::ClockId; +use crate::{errno::Errno, Result}; +use core::mem; + +/// A Unix signal per-process timer. +#[derive(Debug)] +#[repr(transparent)] +pub struct Timer(libc::timer_t); + +impl Timer { + /// Creates a new timer based on the clock defined by `clockid`. The details + /// of the signal and its handler are defined by the passed `sigevent`. + #[cfg_attr(has_doc_alias, doc(alias("timer_create")))] + pub fn new(clockid: ClockId, mut sigevent: SigEvent) -> Result { + let mut timer_id: mem::MaybeUninit = mem::MaybeUninit::uninit(); + Errno::result(unsafe { + libc::timer_create( + clockid.as_raw(), + sigevent.as_mut_ptr(), + timer_id.as_mut_ptr(), + ) + }) + .map(|_| { + // SAFETY: libc::timer_create is responsible for initializing + // timer_id. + unsafe { Self(timer_id.assume_init()) } + }) + } + + /// Set a new alarm on the timer. + /// + /// # Types of alarm + /// + /// There are 3 types of alarms you can set: + /// + /// - one shot: the alarm will trigger once after the specified amount of + /// time. + /// Example: I want an alarm to go off in 60s and then disable itself. + /// + /// - interval: the alarm will trigger every specified interval of time. + /// Example: I want an alarm to go off every 60s. The alarm will first + /// go off 60s after I set it and every 60s after that. The alarm will + /// not disable itself. + /// + /// - interval delayed: the alarm will trigger after a certain amount of + /// time and then trigger at a specified interval. + /// Example: I want an alarm to go off every 60s but only start in 1h. + /// The alarm will first trigger 1h after I set it and then every 60s + /// after that. The alarm will not disable itself. + /// + /// # Relative vs absolute alarm + /// + /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass + /// to the `Expiration` you want is relative. If however you want an alarm + /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`. + /// Then the one shot TimeSpec and the delay TimeSpec of the delayed + /// interval are going to be interpreted as absolute. + /// + /// # Disabling alarms + /// + /// Note: Only one alarm can be set for any given timer. Setting a new alarm + /// actually removes the previous one. + /// + /// Note: Setting a one shot alarm with a 0s TimeSpec disable the alarm + /// altogether. + #[cfg_attr(has_doc_alias, doc(alias("timer_settime")))] + pub fn set(&mut self, expiration: Expiration, flags: TimerSetTimeFlags) -> Result<()> { + let timerspec: TimerSpec = expiration.into(); + Errno::result(unsafe { + libc::timer_settime( + self.0, + flags.bits(), + timerspec.as_ref(), + core::ptr::null_mut(), + ) + }) + .map(drop) + } + + /// Get the parameters for the alarm currently set, if any. + #[cfg_attr(has_doc_alias, doc(alias("timer_gettime")))] + pub fn get(&self) -> Result> { + let mut timerspec = TimerSpec::none(); + Errno::result(unsafe { libc::timer_gettime(self.0, timerspec.as_mut()) }).map(|_| { + if timerspec.as_ref().it_interval.tv_sec == 0 + && timerspec.as_ref().it_interval.tv_nsec == 0 + && timerspec.as_ref().it_value.tv_sec == 0 + && timerspec.as_ref().it_value.tv_nsec == 0 + { + None + } else { + Some(timerspec.into()) + } + }) + } + + /// Return the number of timers that have overrun + /// + /// Each timer is able to queue one signal to the process at a time, meaning + /// if the signal is not handled before the next expiration the timer has + /// 'overrun'. This function returns how many times that has happened to + /// this timer, up to `libc::DELAYTIMER_MAX`. If more than the maximum + /// number of overruns have happened the return is capped to the maximum. + #[cfg_attr(has_doc_alias, doc(alias("timer_getoverrun")))] + pub fn overruns(&self) -> i32 { + unsafe { libc::timer_getoverrun(self.0) } + } +} + +impl Drop for Timer { + fn drop(&mut self) { + if !std::thread::panicking() { + let result = Errno::result(unsafe { libc::timer_delete(self.0) }); + if let Err(Errno::EINVAL) = result { + panic!("close of Timer encountered EINVAL"); + } + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/timerfd.rs b/utshell-0.5.0/vendor/nix/src/sys/timerfd.rs new file mode 100644 index 00000000..42860658 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/timerfd.rs @@ -0,0 +1,205 @@ +//! Timer API via file descriptors. +//! +//! Timer FD is a Linux-only API to create timers and get expiration +//! notifications through file descriptors. +//! +//! For more documentation, please read [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html). +//! +//! # Examples +//! +//! Create a new one-shot timer that expires after 1 second. +//! ``` +//! # use std::os::unix::io::AsRawFd; +//! # use nix::sys::timerfd::{TimerFd, ClockId, TimerFlags, TimerSetTimeFlags, +//! # Expiration}; +//! # use nix::sys::time::{TimeSpec, TimeValLike}; +//! # use nix::unistd::read; +//! # +//! // We create a new monotonic timer. +//! let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()) +//! .unwrap(); +//! +//! // We set a new one-shot timer in 1 seconds. +//! timer.set( +//! Expiration::OneShot(TimeSpec::seconds(1)), +//! TimerSetTimeFlags::empty() +//! ).unwrap(); +//! +//! // We wait for the timer to expire. +//! timer.wait().unwrap(); +//! ``` +use crate::sys::time::timer::TimerSpec; +pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags}; +use crate::unistd::read; +use crate::{errno::Errno, Result}; +use libc::c_int; +use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; + +/// A timerfd instance. This is also a file descriptor, you can feed it to +/// other interfaces consuming file descriptors, epoll for example. +#[derive(Debug)] +pub struct TimerFd { + fd: RawFd, +} + +impl AsRawFd for TimerFd { + fn as_raw_fd(&self) -> RawFd { + self.fd + } +} + +impl FromRawFd for TimerFd { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + TimerFd { fd } + } +} + +libc_enum! { + /// The type of the clock used to mark the progress of the timer. For more + /// details on each kind of clock, please refer to [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html). + #[repr(i32)] + #[non_exhaustive] + pub enum ClockId { + /// A settable system-wide real-time clock. + CLOCK_REALTIME, + /// A non-settable monotonically increasing clock. + /// + /// Does not change after system startup. + /// Does not measure time while the system is suspended. + CLOCK_MONOTONIC, + /// Like `CLOCK_MONOTONIC`, except that `CLOCK_BOOTTIME` includes the time + /// that the system was suspended. + CLOCK_BOOTTIME, + /// Like `CLOCK_REALTIME`, but will wake the system if it is suspended. + CLOCK_REALTIME_ALARM, + /// Like `CLOCK_BOOTTIME`, but will wake the system if it is suspended. + CLOCK_BOOTTIME_ALARM, + } +} + +libc_bitflags! { + /// Additional flags to change the behaviour of the file descriptor at the + /// time of creation. + pub struct TimerFlags: c_int { + /// Set the `O_NONBLOCK` flag on the open file description referred to by the new file descriptor. + TFD_NONBLOCK; + /// Set the `FD_CLOEXEC` flag on the file descriptor. + TFD_CLOEXEC; + } +} + +impl TimerFd { + /// Creates a new timer based on the clock defined by `clockid`. The + /// underlying fd can be assigned specific flags with `flags` (CLOEXEC, + /// NONBLOCK). The underlying fd will be closed on drop. + #[cfg_attr(has_doc_alias, doc(alias("timerfd_create")))] + pub fn new(clockid: ClockId, flags: TimerFlags) -> Result { + Errno::result(unsafe { libc::timerfd_create(clockid as i32, flags.bits()) }) + .map(|fd| Self { fd }) + } + + /// Sets a new alarm on the timer. + /// + /// # Types of alarm + /// + /// There are 3 types of alarms you can set: + /// + /// - one shot: the alarm will trigger once after the specified amount of + /// time. + /// Example: I want an alarm to go off in 60s and then disable itself. + /// + /// - interval: the alarm will trigger every specified interval of time. + /// Example: I want an alarm to go off every 60s. The alarm will first + /// go off 60s after I set it and every 60s after that. The alarm will + /// not disable itself. + /// + /// - interval delayed: the alarm will trigger after a certain amount of + /// time and then trigger at a specified interval. + /// Example: I want an alarm to go off every 60s but only start in 1h. + /// The alarm will first trigger 1h after I set it and then every 60s + /// after that. The alarm will not disable itself. + /// + /// # Relative vs absolute alarm + /// + /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass + /// to the `Expiration` you want is relative. If however you want an alarm + /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`. + /// Then the one shot TimeSpec and the delay TimeSpec of the delayed + /// interval are going to be interpreted as absolute. + /// + /// # Disabling alarms + /// + /// Note: Only one alarm can be set for any given timer. Setting a new alarm + /// actually removes the previous one. + /// + /// Note: Setting a one shot alarm with a 0s TimeSpec disables the alarm + /// altogether. + #[cfg_attr(has_doc_alias, doc(alias("timerfd_settime")))] + pub fn set(&self, expiration: Expiration, flags: TimerSetTimeFlags) -> Result<()> { + let timerspec: TimerSpec = expiration.into(); + Errno::result(unsafe { + libc::timerfd_settime( + self.fd, + flags.bits(), + timerspec.as_ref(), + std::ptr::null_mut(), + ) + }) + .map(drop) + } + + /// Get the parameters for the alarm currently set, if any. + #[cfg_attr(has_doc_alias, doc(alias("timerfd_gettime")))] + pub fn get(&self) -> Result> { + let mut timerspec = TimerSpec::none(); + Errno::result(unsafe { libc::timerfd_gettime(self.fd, timerspec.as_mut()) }).map(|_| { + if timerspec.as_ref().it_interval.tv_sec == 0 + && timerspec.as_ref().it_interval.tv_nsec == 0 + && timerspec.as_ref().it_value.tv_sec == 0 + && timerspec.as_ref().it_value.tv_nsec == 0 + { + None + } else { + Some(timerspec.into()) + } + }) + } + + /// Remove the alarm if any is set. + #[cfg_attr(has_doc_alias, doc(alias("timerfd_settime")))] + pub fn unset(&self) -> Result<()> { + Errno::result(unsafe { + libc::timerfd_settime( + self.fd, + TimerSetTimeFlags::empty().bits(), + TimerSpec::none().as_ref(), + std::ptr::null_mut(), + ) + }) + .map(drop) + } + + /// Wait for the configured alarm to expire. + /// + /// Note: If the alarm is unset, then you will wait forever. + pub fn wait(&self) -> Result<()> { + while let Err(e) = read(self.fd, &mut [0u8; 8]) { + if e != Errno::EINTR { + return Err(e); + } + } + + Ok(()) + } +} + +impl Drop for TimerFd { + fn drop(&mut self) { + if !std::thread::panicking() { + let result = Errno::result(unsafe { libc::close(self.fd) }); + if let Err(Errno::EBADF) = result { + panic!("close of TimerFd encountered EBADF"); + } + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/uio.rs b/utshell-0.5.0/vendor/nix/src/sys/uio.rs new file mode 100644 index 00000000..7cddb372 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/uio.rs @@ -0,0 +1,270 @@ +//! Vectored I/O + +use crate::Result; +use crate::errno::Errno; +use libc::{self, c_int, c_void, size_t, off_t}; +use std::io::{IoSlice, IoSliceMut}; +use std::marker::PhantomData; +use std::os::unix::io::RawFd; + +/// Low-level vectored write to a raw file descriptor +/// +/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html) +pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result { + // SAFETY: to quote the documentation for `IoSlice`: + // + // [IoSlice] is semantically a wrapper around a &[u8], but is + // guaranteed to be ABI compatible with the iovec type on Unix + // platforms. + // + // Because it is ABI compatible, a pointer cast here is valid + let res = unsafe { libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) }; + + Errno::result(res).map(|r| r as usize) +} + +/// Low-level vectored read from a raw file descriptor +/// +/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html) +pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result { + // SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec + let res = unsafe { libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) }; + + Errno::result(res).map(|r| r as usize) +} + +/// Write to `fd` at `offset` from buffers in `iov`. +/// +/// Buffers in `iov` will be written in order until all buffers have been written +/// or an error occurs. The file offset is not changed. +/// +/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html) +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], + offset: off_t) -> Result { + + #[cfg(target_env = "uclibc")] + let offset = offset as libc::off64_t; // uclibc doesn't use off_t + + // SAFETY: same as in writev() + let res = unsafe { + libc::pwritev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset) + }; + + Errno::result(res).map(|r| r as usize) +} + +/// Read from `fd` at `offset` filling buffers in `iov`. +/// +/// Buffers in `iov` will be filled in order until all buffers have been filled, +/// no more bytes are available, or an error occurs. The file offset is not +/// changed. +/// +/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html) +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn preadv(fd: RawFd, iov: &mut [IoSliceMut<'_>], + offset: off_t) -> Result { + #[cfg(target_env = "uclibc")] + let offset = offset as libc::off64_t; // uclibc doesn't use off_t + + // SAFETY: same as in readv() + let res = unsafe { + libc::preadv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset) + }; + + Errno::result(res).map(|r| r as usize) +} + +/// Low-level write to a file, with specified offset. +/// +/// See also [pwrite(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html) +// TODO: move to unistd +pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result { + let res = unsafe { + libc::pwrite(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, + offset) + }; + + Errno::result(res).map(|r| r as usize) +} + +/// Low-level read from a file, with specified offset. +/// +/// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html) +// TODO: move to unistd +pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result{ + let res = unsafe { + libc::pread(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t, + offset) + }; + + Errno::result(res).map(|r| r as usize) +} + +/// A slice of memory in a remote process, starting at address `base` +/// and consisting of `len` bytes. +/// +/// This is the same underlying C structure as `IoSlice`, +/// except that it refers to memory in some other process, and is +/// therefore not represented in Rust by an actual slice as `IoSlice` is. It +/// is used with [`process_vm_readv`](fn.process_vm_readv.html) +/// and [`process_vm_writev`](fn.process_vm_writev.html). +#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct RemoteIoVec { + /// The starting address of this slice (`iov_base`). + pub base: usize, + /// The number of bytes in this slice (`iov_len`). + pub len: usize, +} + +/// A vector of buffers. +/// +/// Vectored I/O methods like [`writev`] and [`readv`] use this structure for +/// both reading and writing. Each `IoVec` specifies the base address and +/// length of an area in memory. +#[deprecated( + since = "0.24.0", + note = "`IoVec` is no longer used in the public interface, use `IoSlice` or `IoSliceMut` instead" +)] +#[repr(transparent)] +#[allow(renamed_and_removed_lints)] +#[allow(clippy::unknown_clippy_lints)] +// Clippy false positive: https://github.com/rust-lang/rust-clippy/issues/8867 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct IoVec(pub(crate) libc::iovec, PhantomData); + +#[allow(deprecated)] +impl IoVec { + /// View the `IoVec` as a Rust slice. + #[deprecated( + since = "0.24.0", + note = "Use the `Deref` impl of `IoSlice` or `IoSliceMut` instead" + )] + #[inline] + pub fn as_slice(&self) -> &[u8] { + use std::slice; + + unsafe { + slice::from_raw_parts( + self.0.iov_base as *const u8, + self.0.iov_len) + } + } +} + +#[allow(deprecated)] +impl<'a> IoVec<&'a [u8]> { + /// Create an `IoVec` from a Rust slice. + #[deprecated( + since = "0.24.0", + note = "Use `IoSlice::new` instead" + )] + pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> { + IoVec(libc::iovec { + iov_base: buf.as_ptr() as *mut c_void, + iov_len: buf.len() as size_t, + }, PhantomData) + } +} + +#[allow(deprecated)] +impl<'a> IoVec<&'a mut [u8]> { + /// Create an `IoVec` from a mutable Rust slice. + #[deprecated( + since = "0.24.0", + note = "Use `IoSliceMut::new` instead" + )] + pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> { + IoVec(libc::iovec { + iov_base: buf.as_ptr() as *mut c_void, + iov_len: buf.len() as size_t, + }, PhantomData) + } +} + +// The only reason IoVec isn't automatically Send+Sync is because libc::iovec +// contains raw pointers. +#[allow(deprecated)] +unsafe impl Send for IoVec where T: Send {} +#[allow(deprecated)] +unsafe impl Sync for IoVec where T: Sync {} + +feature! { +#![feature = "process"] + +/// Write data directly to another process's virtual memory +/// (see [`process_vm_writev`(2)]). +/// +/// `local_iov` is a list of [`IoSlice`]s containing the data to be written, +/// and `remote_iov` is a list of [`RemoteIoVec`]s identifying where the +/// data should be written in the target process. On success, returns the +/// number of bytes written, which will always be a whole +/// number of `remote_iov` chunks. +/// +/// This requires the same permissions as debugging the process using +/// [ptrace]: you must either be a privileged process (with +/// `CAP_SYS_PTRACE`), or you must be running as the same user as the +/// target process and the OS must have unprivileged debugging enabled. +/// +/// This function is only available on Linux and Android(SDK23+). +/// +/// [`process_vm_writev`(2)]: https://man7.org/linux/man-pages/man2/process_vm_writev.2.html +/// [ptrace]: ../ptrace/index.html +/// [`IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html +/// [`RemoteIoVec`]: struct.RemoteIoVec.html +#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))] +pub fn process_vm_writev( + pid: crate::unistd::Pid, + local_iov: &[IoSlice<'_>], + remote_iov: &[RemoteIoVec]) -> Result +{ + let res = unsafe { + libc::process_vm_writev(pid.into(), + local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong, + remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0) + }; + + Errno::result(res).map(|r| r as usize) +} + +/// Read data directly from another process's virtual memory +/// (see [`process_vm_readv`(2)]). +/// +/// `local_iov` is a list of [`IoSliceMut`]s containing the buffer to copy +/// data into, and `remote_iov` is a list of [`RemoteIoVec`]s identifying +/// where the source data is in the target process. On success, +/// returns the number of bytes written, which will always be a whole +/// number of `remote_iov` chunks. +/// +/// This requires the same permissions as debugging the process using +/// [`ptrace`]: you must either be a privileged process (with +/// `CAP_SYS_PTRACE`), or you must be running as the same user as the +/// target process and the OS must have unprivileged debugging enabled. +/// +/// This function is only available on Linux and Android(SDK23+). +/// +/// [`process_vm_readv`(2)]: https://man7.org/linux/man-pages/man2/process_vm_readv.2.html +/// [`ptrace`]: ../ptrace/index.html +/// [`IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html +/// [`RemoteIoVec`]: struct.RemoteIoVec.html +#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))] +pub fn process_vm_readv( + pid: crate::unistd::Pid, + local_iov: &mut [IoSliceMut<'_>], + remote_iov: &[RemoteIoVec]) -> Result +{ + let res = unsafe { + libc::process_vm_readv(pid.into(), + local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong, + remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0) + }; + + Errno::result(res).map(|r| r as usize) +} +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/utsname.rs b/utshell-0.5.0/vendor/nix/src/sys/utsname.rs new file mode 100644 index 00000000..5bd3a539 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/utsname.rs @@ -0,0 +1,77 @@ +//! Get system identification +use std::mem; +use std::os::unix::ffi::OsStrExt; +use std::ffi::OsStr; +use libc::c_char; +use crate::{Errno, Result}; + +/// Describes the running system. Return type of [`uname`]. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct UtsName(libc::utsname); + +impl UtsName { + /// Name of the operating system implementation. + pub fn sysname(&self) -> &OsStr { + cast_and_trim(&self.0.sysname) + } + + /// Network name of this machine. + pub fn nodename(&self) -> &OsStr { + cast_and_trim(&self.0.nodename) + } + + /// Release level of the operating system. + pub fn release(&self) -> &OsStr { + cast_and_trim(&self.0.release) + } + + /// Version level of the operating system. + pub fn version(&self) -> &OsStr { + cast_and_trim(&self.0.version) + } + + /// Machine hardware platform. + pub fn machine(&self) -> &OsStr { + cast_and_trim(&self.0.machine) + } +} + +/// Get system identification +pub fn uname() -> Result { + unsafe { + let mut ret = mem::MaybeUninit::zeroed(); + Errno::result(libc::uname(ret.as_mut_ptr()))?; + Ok(UtsName(ret.assume_init())) + } +} + +fn cast_and_trim(slice: &[c_char]) -> &OsStr { + let length = slice.iter().position(|&byte| byte == 0).unwrap_or(slice.len()); + let bytes = unsafe { + std::slice::from_raw_parts(slice.as_ptr().cast(), length) + }; + + OsStr::from_bytes(bytes) +} + +#[cfg(test)] +mod test { + #[cfg(target_os = "linux")] + #[test] + pub fn test_uname_linux() { + assert_eq!(super::uname().unwrap().sysname(), "Linux"); + } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + #[test] + pub fn test_uname_darwin() { + assert_eq!(super::uname().unwrap().sysname(), "Darwin"); + } + + #[cfg(target_os = "freebsd")] + #[test] + pub fn test_uname_freebsd() { + assert_eq!(super::uname().unwrap().sysname(), "FreeBSD"); + } +} diff --git a/utshell-0.5.0/vendor/nix/src/sys/wait.rs b/utshell-0.5.0/vendor/nix/src/sys/wait.rs new file mode 100644 index 00000000..5fb2075f --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/sys/wait.rs @@ -0,0 +1,381 @@ +//! Wait for a process to change status +use crate::errno::Errno; +use crate::sys::signal::Signal; +use crate::unistd::Pid; +use crate::Result; +use cfg_if::cfg_if; +use libc::{self, c_int}; +use std::convert::TryFrom; +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "uclibc")), +))] +use std::os::unix::io::RawFd; + +libc_bitflags!( + /// Controls the behavior of [`waitpid`]. + pub struct WaitPidFlag: c_int { + /// Do not block when there are no processes wishing to report status. + WNOHANG; + /// Report the status of selected processes which are stopped due to a + /// [`SIGTTIN`](crate::sys::signal::Signal::SIGTTIN), + /// [`SIGTTOU`](crate::sys::signal::Signal::SIGTTOU), + /// [`SIGTSTP`](crate::sys::signal::Signal::SIGTSTP), or + /// [`SIGSTOP`](crate::sys::signal::Signal::SIGSTOP) signal. + WUNTRACED; + /// Report the status of selected processes which have terminated. + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "redox", + target_os = "macos", + target_os = "netbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + WEXITED; + /// Report the status of selected processes that have continued from a + /// job control stop by receiving a + /// [`SIGCONT`](crate::sys::signal::Signal::SIGCONT) signal. + WCONTINUED; + /// An alias for WUNTRACED. + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "redox", + target_os = "macos", + target_os = "netbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + WSTOPPED; + /// Don't reap, just poll status. + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "redox", + target_os = "macos", + target_os = "netbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + WNOWAIT; + /// Don't wait on children of other threads in this group + #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + __WNOTHREAD; + /// Wait on all children, regardless of type + #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + __WALL; + /// Wait for "clone" children only. + #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + __WCLONE; + } +); + +/// Possible return values from `wait()` or `waitpid()`. +/// +/// Each status (other than `StillAlive`) describes a state transition +/// in a child process `Pid`, such as the process exiting or stopping, +/// plus additional data about the transition if any. +/// +/// Note that there are two Linux-specific enum variants, `PtraceEvent` +/// and `PtraceSyscall`. Portable code should avoid exhaustively +/// matching on `WaitStatus`. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum WaitStatus { + /// The process exited normally (as with `exit()` or returning from + /// `main`) with the given exit code. This case matches the C macro + /// `WIFEXITED(status)`; the second field is `WEXITSTATUS(status)`. + Exited(Pid, i32), + /// The process was killed by the given signal. The third field + /// indicates whether the signal generated a core dump. This case + /// matches the C macro `WIFSIGNALED(status)`; the last two fields + /// correspond to `WTERMSIG(status)` and `WCOREDUMP(status)`. + Signaled(Pid, Signal, bool), + /// The process is alive, but was stopped by the given signal. This + /// is only reported if `WaitPidFlag::WUNTRACED` was passed. This + /// case matches the C macro `WIFSTOPPED(status)`; the second field + /// is `WSTOPSIG(status)`. + Stopped(Pid, Signal), + /// The traced process was stopped by a `PTRACE_EVENT_*` event. See + /// [`nix::sys::ptrace`] and [`ptrace`(2)] for more information. All + /// currently-defined events use `SIGTRAP` as the signal; the third + /// field is the `PTRACE_EVENT_*` value of the event. + /// + /// [`nix::sys::ptrace`]: ../ptrace/index.html + /// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html + #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PtraceEvent(Pid, Signal, c_int), + /// The traced process was stopped by execution of a system call, + /// and `PTRACE_O_TRACESYSGOOD` is in effect. See [`ptrace`(2)] for + /// more information. + /// + /// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html + #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PtraceSyscall(Pid), + /// The process was previously stopped but has resumed execution + /// after receiving a `SIGCONT` signal. This is only reported if + /// `WaitPidFlag::WCONTINUED` was passed. This case matches the C + /// macro `WIFCONTINUED(status)`. + Continued(Pid), + /// There are currently no state changes to report in any awaited + /// child process. This is only returned if `WaitPidFlag::WNOHANG` + /// was used (otherwise `wait()` or `waitpid()` would block until + /// there was something to report). + StillAlive, +} + +impl WaitStatus { + /// Extracts the PID from the WaitStatus unless it equals StillAlive. + pub fn pid(&self) -> Option { + use self::WaitStatus::*; + match *self { + Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => Some(p), + StillAlive => None, + #[cfg(any(target_os = "android", target_os = "linux"))] + PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p), + } + } +} + +fn exited(status: i32) -> bool { + libc::WIFEXITED(status) +} + +fn exit_status(status: i32) -> i32 { + libc::WEXITSTATUS(status) +} + +fn signaled(status: i32) -> bool { + libc::WIFSIGNALED(status) +} + +fn term_signal(status: i32) -> Result { + Signal::try_from(libc::WTERMSIG(status)) +} + +fn dumped_core(status: i32) -> bool { + libc::WCOREDUMP(status) +} + +fn stopped(status: i32) -> bool { + libc::WIFSTOPPED(status) +} + +fn stop_signal(status: i32) -> Result { + Signal::try_from(libc::WSTOPSIG(status)) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +fn syscall_stop(status: i32) -> bool { + // From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect + // of delivering SIGTRAP | 0x80 as the signal number for syscall + // stops. This allows easily distinguishing syscall stops from + // genuine SIGTRAP signals. + libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80 +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +fn stop_additional(status: i32) -> c_int { + (status >> 16) as c_int +} + +fn continued(status: i32) -> bool { + libc::WIFCONTINUED(status) +} + +impl WaitStatus { + /// Convert a raw `wstatus` as returned by `waitpid`/`wait` into a `WaitStatus` + /// + /// # Errors + /// + /// Returns an `Error` corresponding to `EINVAL` for invalid status values. + /// + /// # Examples + /// + /// Convert a `wstatus` obtained from `libc::waitpid` into a `WaitStatus`: + /// + /// ``` + /// use nix::sys::wait::WaitStatus; + /// use nix::sys::signal::Signal; + /// let pid = nix::unistd::Pid::from_raw(1); + /// let status = WaitStatus::from_raw(pid, 0x0002); + /// assert_eq!(status, Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false))); + /// ``` + pub fn from_raw(pid: Pid, status: i32) -> Result { + Ok(if exited(status) { + WaitStatus::Exited(pid, exit_status(status)) + } else if signaled(status) { + WaitStatus::Signaled(pid, term_signal(status)?, dumped_core(status)) + } else if stopped(status) { + cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + fn decode_stopped(pid: Pid, status: i32) -> Result { + let status_additional = stop_additional(status); + Ok(if syscall_stop(status) { + WaitStatus::PtraceSyscall(pid) + } else if status_additional == 0 { + WaitStatus::Stopped(pid, stop_signal(status)?) + } else { + WaitStatus::PtraceEvent(pid, stop_signal(status)?, + stop_additional(status)) + }) + } + } else { + fn decode_stopped(pid: Pid, status: i32) -> Result { + Ok(WaitStatus::Stopped(pid, stop_signal(status)?)) + } + } + } + return decode_stopped(pid, status); + } else { + assert!(continued(status)); + WaitStatus::Continued(pid) + }) + } + + /// Convert a `siginfo_t` as returned by `waitid` to a `WaitStatus` + /// + /// # Errors + /// + /// Returns an `Error` corresponding to `EINVAL` for invalid values. + /// + /// # Safety + /// + /// siginfo_t is actually a union, not all fields may be initialized. + /// The functions si_pid() and si_status() must be valid to call on + /// the passed siginfo_t. + #[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "haiku", + all(target_os = "linux", not(target_env = "uclibc")), + ))] + unsafe fn from_siginfo(siginfo: &libc::siginfo_t) -> Result { + let si_pid = siginfo.si_pid(); + if si_pid == 0 { + return Ok(WaitStatus::StillAlive); + } + + assert_eq!(siginfo.si_signo, libc::SIGCHLD); + + let pid = Pid::from_raw(si_pid); + let si_status = siginfo.si_status(); + + let status = match siginfo.si_code { + libc::CLD_EXITED => WaitStatus::Exited(pid, si_status), + libc::CLD_KILLED | libc::CLD_DUMPED => WaitStatus::Signaled( + pid, + Signal::try_from(si_status)?, + siginfo.si_code == libc::CLD_DUMPED, + ), + libc::CLD_STOPPED => WaitStatus::Stopped(pid, Signal::try_from(si_status)?), + libc::CLD_CONTINUED => WaitStatus::Continued(pid), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::CLD_TRAPPED => { + if si_status == libc::SIGTRAP | 0x80 { + WaitStatus::PtraceSyscall(pid) + } else { + WaitStatus::PtraceEvent( + pid, + Signal::try_from(si_status & 0xff)?, + (si_status >> 8) as c_int, + ) + } + } + _ => return Err(Errno::EINVAL), + }; + + Ok(status) + } +} + +/// Wait for a process to change status +/// +/// See also [waitpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html) +pub fn waitpid>>(pid: P, options: Option) -> Result { + use self::WaitStatus::*; + + let mut status: i32 = 0; + + let option_bits = match options { + Some(bits) => bits.bits(), + None => 0, + }; + + let res = unsafe { + libc::waitpid( + pid.into().unwrap_or_else(|| Pid::from_raw(-1)).into(), + &mut status as *mut c_int, + option_bits, + ) + }; + + match Errno::result(res)? { + 0 => Ok(StillAlive), + res => WaitStatus::from_raw(Pid::from_raw(res), status), + } +} + +/// Wait for any child process to change status or a signal is received. +/// +/// See also [wait(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html) +pub fn wait() -> Result { + waitpid(None, None) +} + +/// The ID argument for `waitid` +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "haiku", + all(target_os = "linux", not(target_env = "uclibc")), +))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Id { + /// Wait for any child + All, + /// Wait for the child whose process ID matches the given PID + Pid(Pid), + /// Wait for the child whose process group ID matches the given PID + /// + /// If the PID is zero, the caller's process group is used since Linux 5.4. + PGid(Pid), + /// Wait for the child referred to by the given PID file descriptor + #[cfg(any(target_os = "android", target_os = "linux"))] + PIDFd(RawFd), +} + +/// Wait for a process to change status +/// +/// See also [waitid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitid.html) +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "haiku", + all(target_os = "linux", not(target_env = "uclibc")), +))] +pub fn waitid(id: Id, flags: WaitPidFlag) -> Result { + let (idtype, idval) = match id { + Id::All => (libc::P_ALL, 0), + Id::Pid(pid) => (libc::P_PID, pid.as_raw() as libc::id_t), + Id::PGid(pid) => (libc::P_PGID, pid.as_raw() as libc::id_t), + #[cfg(any(target_os = "android", target_os = "linux"))] + Id::PIDFd(fd) => (libc::P_PIDFD, fd as libc::id_t), + }; + + let siginfo = unsafe { + // Memory is zeroed rather than uninitialized, as not all platforms + // initialize the memory in the StillAlive case + let mut siginfo: libc::siginfo_t = std::mem::zeroed(); + Errno::result(libc::waitid(idtype, idval, &mut siginfo, flags.bits()))?; + siginfo + }; + + unsafe { WaitStatus::from_siginfo(&siginfo) } +} diff --git a/utshell-0.5.0/vendor/nix/src/time.rs b/utshell-0.5.0/vendor/nix/src/time.rs new file mode 100644 index 00000000..6a385b90 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/time.rs @@ -0,0 +1,269 @@ +use crate::sys::time::TimeSpec; +#[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux", + target_os = "android", + target_os = "emscripten", +))] +#[cfg(feature = "process")] +use crate::unistd::Pid; +use crate::{Errno, Result}; +use libc::{self, clockid_t}; +use std::mem::MaybeUninit; + +/// Clock identifier +/// +/// Newtype pattern around `clockid_t` (which is just alias). It prevents bugs caused by +/// accidentally passing wrong value. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct ClockId(clockid_t); + +impl ClockId { + /// Creates `ClockId` from raw `clockid_t` + pub const fn from_raw(clk_id: clockid_t) -> Self { + ClockId(clk_id) + } + + feature! { + #![feature = "process"] + /// Returns `ClockId` of a `pid` CPU-time clock + #[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux", + target_os = "android", + target_os = "emscripten", + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn pid_cpu_clock_id(pid: Pid) -> Result { + clock_getcpuclockid(pid) + } + } + + /// Returns resolution of the clock id + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn res(self) -> Result { + clock_getres(self) + } + + /// Returns the current time on the clock id + pub fn now(self) -> Result { + clock_gettime(self) + } + + /// Sets time to `timespec` on the clock id + #[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "redox", + target_os = "hermit", + )))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn set_time(self, timespec: TimeSpec) -> Result<()> { + clock_settime(self, timespec) + } + + /// Gets the raw `clockid_t` wrapped by `self` + pub const fn as_raw(self) -> clockid_t { + self.0 + } + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_BOOTTIME: ClockId = ClockId(libc::CLOCK_BOOTTIME); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_BOOTTIME_ALARM: ClockId = ClockId(libc::CLOCK_BOOTTIME_ALARM); + pub const CLOCK_MONOTONIC: ClockId = ClockId(libc::CLOCK_MONOTONIC); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_MONOTONIC_COARSE: ClockId = ClockId(libc::CLOCK_MONOTONIC_COARSE); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_MONOTONIC_FAST: ClockId = ClockId(libc::CLOCK_MONOTONIC_FAST); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_MONOTONIC_PRECISE: ClockId = ClockId(libc::CLOCK_MONOTONIC_PRECISE); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_MONOTONIC_RAW: ClockId = ClockId(libc::CLOCK_MONOTONIC_RAW); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "redox", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_PROCESS_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_PROCESS_CPUTIME_ID); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_PROF: ClockId = ClockId(libc::CLOCK_PROF); + pub const CLOCK_REALTIME: ClockId = ClockId(libc::CLOCK_REALTIME); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_REALTIME_ALARM: ClockId = ClockId(libc::CLOCK_REALTIME_ALARM); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_REALTIME_COARSE: ClockId = ClockId(libc::CLOCK_REALTIME_COARSE); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_REALTIME_FAST: ClockId = ClockId(libc::CLOCK_REALTIME_FAST); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_REALTIME_PRECISE: ClockId = ClockId(libc::CLOCK_REALTIME_PRECISE); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_SECOND: ClockId = ClockId(libc::CLOCK_SECOND); + #[cfg(any( + target_os = "emscripten", + target_os = "fuchsia", + all(target_os = "linux", target_env = "musl") + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_SGI_CYCLE: ClockId = ClockId(libc::CLOCK_SGI_CYCLE); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_TAI: ClockId = ClockId(libc::CLOCK_TAI); + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "ios", + target_os = "macos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux" + ))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_THREAD_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_THREAD_CPUTIME_ID); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_UPTIME: ClockId = ClockId(libc::CLOCK_UPTIME); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_UPTIME_FAST: ClockId = ClockId(libc::CLOCK_UPTIME_FAST); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_UPTIME_PRECISE: ClockId = ClockId(libc::CLOCK_UPTIME_PRECISE); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub const CLOCK_VIRTUAL: ClockId = ClockId(libc::CLOCK_VIRTUAL); +} + +impl From for clockid_t { + fn from(clock_id: ClockId) -> Self { + clock_id.as_raw() + } +} + +impl From for ClockId { + fn from(clk_id: clockid_t) -> Self { + ClockId::from_raw(clk_id) + } +} + +impl std::fmt::Display for ClockId { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + std::fmt::Display::fmt(&self.0, f) + } +} + +/// Get the resolution of the specified clock, (see +/// [clock_getres(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_getres.html)). +#[cfg(not(target_os = "redox"))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn clock_getres(clock_id: ClockId) -> Result { + let mut c_time: MaybeUninit = MaybeUninit::uninit(); + let ret = unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) }; + Errno::result(ret)?; + let res = unsafe { c_time.assume_init() }; + Ok(TimeSpec::from(res)) +} + +/// Get the time of the specified clock, (see +/// [clock_gettime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_gettime.html)). +pub fn clock_gettime(clock_id: ClockId) -> Result { + let mut c_time: MaybeUninit = MaybeUninit::uninit(); + let ret = unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) }; + Errno::result(ret)?; + let res = unsafe { c_time.assume_init() }; + Ok(TimeSpec::from(res)) +} + +/// Set the time of the specified clock, (see +/// [clock_settime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_settime.html)). +#[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "redox", + target_os = "hermit", +)))] +#[cfg_attr(docsrs, doc(cfg(all())))] +pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> { + let ret = unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) }; + Errno::result(ret).map(drop) +} + +/// Get the clock id of the specified process id, (see +/// [clock_getcpuclockid(3)](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_getcpuclockid.html)). +#[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux", + target_os = "android", + target_os = "emscripten", +))] +#[cfg(feature = "process")] +#[cfg_attr(docsrs, doc(cfg(feature = "process")))] +pub fn clock_getcpuclockid(pid: Pid) -> Result { + let mut clk_id: MaybeUninit = MaybeUninit::uninit(); + let ret = unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) }; + if ret == 0 { + let res = unsafe { clk_id.assume_init() }; + Ok(ClockId::from(res)) + } else { + Err(Errno::from_i32(ret)) + } +} diff --git a/utshell-0.5.0/vendor/nix/src/ucontext.rs b/utshell-0.5.0/vendor/nix/src/ucontext.rs new file mode 100644 index 00000000..f2338bd4 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/ucontext.rs @@ -0,0 +1,43 @@ +#[cfg(not(target_env = "musl"))] +use crate::Result; +#[cfg(not(target_env = "musl"))] +use crate::errno::Errno; +#[cfg(not(target_env = "musl"))] +use std::mem; +use crate::sys::signal::SigSet; + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct UContext { + context: libc::ucontext_t, +} + +impl UContext { + #[cfg(not(target_env = "musl"))] + pub fn get() -> Result { + let mut context = mem::MaybeUninit::::uninit(); + let res = unsafe { libc::getcontext(context.as_mut_ptr()) }; + Errno::result(res).map(|_| unsafe { + UContext { context: context.assume_init()} + }) + } + + #[cfg(not(target_env = "musl"))] + pub fn set(&self) -> Result<()> { + let res = unsafe { + libc::setcontext(&self.context as *const libc::ucontext_t) + }; + Errno::result(res).map(drop) + } + + pub fn sigmask_mut(&mut self) -> &mut SigSet { + unsafe { + &mut *(&mut self.context.uc_sigmask as *mut libc::sigset_t as *mut SigSet) + } + } + + pub fn sigmask(&self) -> &SigSet { + unsafe { + &*(&self.context.uc_sigmask as *const libc::sigset_t as *const SigSet) + } + } +} diff --git a/utshell-0.5.0/vendor/nix/src/unistd.rs b/utshell-0.5.0/vendor/nix/src/unistd.rs new file mode 100644 index 00000000..570b8698 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/src/unistd.rs @@ -0,0 +1,3352 @@ +//! Safe wrappers around functions found in libc "unistd.h" header + +use crate::errno::{self, Errno}; +#[cfg(not(target_os = "redox"))] +#[cfg(feature = "fs")] +use crate::fcntl::{at_rawfd, AtFlags}; +#[cfg(feature = "fs")] +use crate::fcntl::{fcntl, FcntlArg::F_SETFD, FdFlag, OFlag}; +#[cfg(all( + feature = "fs", + any( + target_os = "openbsd", + target_os = "netbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "macos", + target_os = "ios" + ) +))] +use crate::sys::stat::FileFlag; +#[cfg(feature = "fs")] +use crate::sys::stat::Mode; +use crate::{Error, NixPath, Result}; +#[cfg(not(target_os = "redox"))] +use cfg_if::cfg_if; +use libc::{ + self, c_char, c_int, c_long, c_uint, c_void, gid_t, mode_t, off_t, pid_t, + size_t, uid_t, PATH_MAX, +}; +use std::convert::Infallible; +use std::ffi::{CStr, OsString}; +#[cfg(not(target_os = "redox"))] +use std::ffi::{CString, OsStr}; +#[cfg(not(target_os = "redox"))] +use std::os::unix::ffi::OsStrExt; +use std::os::unix::ffi::OsStringExt; +use std::os::unix::io::RawFd; +use std::path::PathBuf; +use std::{fmt, mem, ptr}; + +feature! { + #![feature = "fs"] + #[cfg(any(target_os = "android", target_os = "linux"))] + pub use self::pivot_root::*; +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "openbsd" +))] +pub use self::setres::*; + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "openbsd" +))] +pub use self::getres::*; + +feature! { +#![feature = "user"] + +/// User identifier +/// +/// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally +/// passing wrong value. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct Uid(uid_t); + +impl Uid { + /// Creates `Uid` from raw `uid_t`. + pub const fn from_raw(uid: uid_t) -> Self { + Uid(uid) + } + + /// Returns Uid of calling process. This is practically a more Rusty alias for `getuid`. + #[cfg_attr(has_doc_alias, doc(alias("getuid")))] + pub fn current() -> Self { + getuid() + } + + /// Returns effective Uid of calling process. This is practically a more Rusty alias for `geteuid`. + #[cfg_attr(has_doc_alias, doc(alias("geteuid")))] + pub fn effective() -> Self { + geteuid() + } + + /// Returns true if the `Uid` represents privileged user - root. (If it equals zero.) + pub const fn is_root(self) -> bool { + self.0 == ROOT.0 + } + + /// Get the raw `uid_t` wrapped by `self`. + pub const fn as_raw(self) -> uid_t { + self.0 + } +} + +impl From for uid_t { + fn from(uid: Uid) -> Self { + uid.0 + } +} + +impl From for Uid { + fn from(uid: uid_t) -> Self { + Uid(uid) + } +} + +impl fmt::Display for Uid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + +/// Constant for UID = 0 +pub const ROOT: Uid = Uid(0); + +/// Group identifier +/// +/// Newtype pattern around `gid_t` (which is just alias). It prevents bugs caused by accidentally +/// passing wrong value. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct Gid(gid_t); + +impl Gid { + /// Creates `Gid` from raw `gid_t`. + pub const fn from_raw(gid: gid_t) -> Self { + Gid(gid) + } + + /// Returns Gid of calling process. This is practically a more Rusty alias for `getgid`. + #[cfg_attr(has_doc_alias, doc(alias("getgid")))] + pub fn current() -> Self { + getgid() + } + + /// Returns effective Gid of calling process. This is practically a more Rusty alias for `getegid`. + #[cfg_attr(has_doc_alias, doc(alias("getegid")))] + pub fn effective() -> Self { + getegid() + } + + /// Get the raw `gid_t` wrapped by `self`. + pub const fn as_raw(self) -> gid_t { + self.0 + } +} + +impl From for gid_t { + fn from(gid: Gid) -> Self { + gid.0 + } +} + +impl From for Gid { + fn from(gid: gid_t) -> Self { + Gid(gid) + } +} + +impl fmt::Display for Gid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} +} + +feature! { +#![feature = "process"] +/// Process identifier +/// +/// Newtype pattern around `pid_t` (which is just alias). It prevents bugs caused by accidentally +/// passing wrong value. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct Pid(pid_t); + +impl Pid { + /// Creates `Pid` from raw `pid_t`. + pub const fn from_raw(pid: pid_t) -> Self { + Pid(pid) + } + + /// Returns PID of calling process + #[cfg_attr(has_doc_alias, doc(alias("getpid")))] + pub fn this() -> Self { + getpid() + } + + /// Returns PID of parent of calling process + #[cfg_attr(has_doc_alias, doc(alias("getppid")))] + pub fn parent() -> Self { + getppid() + } + + /// Get the raw `pid_t` wrapped by `self`. + pub const fn as_raw(self) -> pid_t { + self.0 + } +} + +impl From for pid_t { + fn from(pid: Pid) -> Self { + pid.0 + } +} + +impl fmt::Display for Pid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + + +/// Represents the successful result of calling `fork` +/// +/// When `fork` is called, the process continues execution in the parent process +/// and in the new child. This return type can be examined to determine whether +/// you are now executing in the parent process or in the child. +#[derive(Clone, Copy, Debug)] +pub enum ForkResult { + Parent { child: Pid }, + Child, +} + +impl ForkResult { + + /// Return `true` if this is the child process of the `fork()` + #[inline] + pub fn is_child(self) -> bool { + matches!(self, ForkResult::Child) + } + + /// Returns `true` if this is the parent process of the `fork()` + #[inline] + pub fn is_parent(self) -> bool { + !self.is_child() + } +} + +/// Create a new child process duplicating the parent process ([see +/// fork(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)). +/// +/// After successfully calling the fork system call, a second process will +/// be created which is identical to the original except for the pid and the +/// return value of this function. As an example: +/// +/// ``` +/// use nix::{sys::wait::waitpid,unistd::{fork, ForkResult, write}}; +/// +/// match unsafe{fork()} { +/// Ok(ForkResult::Parent { child, .. }) => { +/// println!("Continuing execution in parent process, new child has pid: {}", child); +/// waitpid(child, None).unwrap(); +/// } +/// Ok(ForkResult::Child) => { +/// // Unsafe to use `println!` (or `unwrap`) here. See Safety. +/// write(libc::STDOUT_FILENO, "I'm a new child process\n".as_bytes()).ok(); +/// unsafe { libc::_exit(0) }; +/// } +/// Err(_) => println!("Fork failed"), +/// } +/// ``` +/// +/// This will print something like the following (order nondeterministic). The +/// thing to note is that you end up with two processes continuing execution +/// immediately after the fork call but with different match arms. +/// +/// ```text +/// Continuing execution in parent process, new child has pid: 1234 +/// I'm a new child process +/// ``` +/// +/// # Safety +/// +/// In a multithreaded program, only [async-signal-safe] functions like `pause` +/// and `_exit` may be called by the child (the parent isn't restricted). Note +/// that memory allocation may **not** be async-signal-safe and thus must be +/// prevented. +/// +/// Those functions are only a small subset of your operating system's API, so +/// special care must be taken to only invoke code you can control and audit. +/// +/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html +#[inline] +pub unsafe fn fork() -> Result { + use self::ForkResult::*; + let res = libc::fork(); + + Errno::result(res).map(|res| match res { + 0 => Child, + res => Parent { child: Pid(res) }, + }) +} + +/// Get the pid of this process (see +/// [getpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html)). +/// +/// Since you are running code, there is always a pid to return, so there +/// is no error case that needs to be handled. +#[inline] +pub fn getpid() -> Pid { + Pid(unsafe { libc::getpid() }) +} + +/// Get the pid of this processes' parent (see +/// [getpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html)). +/// +/// There is always a parent pid to return, so there is no error case that needs +/// to be handled. +#[inline] +pub fn getppid() -> Pid { + Pid(unsafe { libc::getppid() }) // no error handling, according to man page: "These functions are always successful." +} + +/// Set a process group ID (see +/// [setpgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html)). +/// +/// Set the process group id (PGID) of a particular process. If a pid of zero +/// is specified, then the pid of the calling process is used. Process groups +/// may be used to group together a set of processes in order for the OS to +/// apply some operations across the group. +/// +/// `setsid()` may be used to create a new process group. +#[inline] +pub fn setpgid(pid: Pid, pgid: Pid) -> Result<()> { + let res = unsafe { libc::setpgid(pid.into(), pgid.into()) }; + Errno::result(res).map(drop) +} +#[inline] +pub fn getpgid(pid: Option) -> Result { + let res = unsafe { libc::getpgid(pid.unwrap_or(Pid(0)).into()) }; + Errno::result(res).map(Pid) +} + +/// Create new session and set process group id (see +/// [setsid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html)). +#[inline] +pub fn setsid() -> Result { + Errno::result(unsafe { libc::setsid() }).map(Pid) +} + +/// Get the process group ID of a session leader +/// [getsid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html). +/// +/// Obtain the process group ID of the process that is the session leader of the process specified +/// by pid. If pid is zero, it specifies the calling process. +#[inline] +#[cfg(not(target_os = "redox"))] +pub fn getsid(pid: Option) -> Result { + let res = unsafe { libc::getsid(pid.unwrap_or(Pid(0)).into()) }; + Errno::result(res).map(Pid) +} +} + +feature! { +#![all(feature = "process", feature = "term")] +/// Get the terminal foreground process group (see +/// [tcgetpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html)). +/// +/// Get the group process id (GPID) of the foreground process group on the +/// terminal associated to file descriptor (FD). +#[inline] +pub fn tcgetpgrp(fd: c_int) -> Result { + let res = unsafe { libc::tcgetpgrp(fd) }; + Errno::result(res).map(Pid) +} +/// Set the terminal foreground process group (see +/// [tcgetpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html)). +/// +/// Get the group process id (PGID) to the foreground process group on the +/// terminal associated to file descriptor (FD). +#[inline] +pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> { + let res = unsafe { libc::tcsetpgrp(fd, pgrp.into()) }; + Errno::result(res).map(drop) +} +} + +feature! { +#![feature = "process"] +/// Get the group id of the calling process (see +///[getpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html)). +/// +/// Get the process group id (PGID) of the calling process. +/// According to the man page it is always successful. +#[inline] +pub fn getpgrp() -> Pid { + Pid(unsafe { libc::getpgrp() }) +} + +/// Get the caller's thread ID (see +/// [gettid(2)](https://man7.org/linux/man-pages/man2/gettid.2.html). +/// +/// This function is only available on Linux based systems. In a single +/// threaded process, the main thread will have the same ID as the process. In +/// a multithreaded process, each thread will have a unique thread id but the +/// same process ID. +/// +/// No error handling is required as a thread id should always exist for any +/// process, even if threads are not being used. +#[cfg(any(target_os = "linux", target_os = "android"))] +#[inline] +pub fn gettid() -> Pid { + Pid(unsafe { libc::syscall(libc::SYS_gettid) as pid_t }) +} +} + +feature! { +#![feature = "fs"] +/// Create a copy of the specified file descriptor (see +/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)). +/// +/// The new file descriptor will be have a new index but refer to the same +/// resource as the old file descriptor and the old and new file descriptors may +/// be used interchangeably. The new and old file descriptor share the same +/// underlying resource, offset, and file status flags. The actual index used +/// for the file descriptor will be the lowest fd index that is available. +/// +/// The two file descriptors do not share file descriptor flags (e.g. `OFlag::FD_CLOEXEC`). +#[inline] +pub fn dup(oldfd: RawFd) -> Result { + let res = unsafe { libc::dup(oldfd) }; + + Errno::result(res) +} + +/// Create a copy of the specified file descriptor using the specified fd (see +/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)). +/// +/// This function behaves similar to `dup()` except that it will try to use the +/// specified fd instead of allocating a new one. See the man pages for more +/// detail on the exact behavior of this function. +#[inline] +pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result { + let res = unsafe { libc::dup2(oldfd, newfd) }; + + Errno::result(res) +} + +/// Create a new copy of the specified file descriptor using the specified fd +/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)). +/// +/// This function behaves similar to `dup2()` but allows for flags to be +/// specified. +pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { + dup3_polyfill(oldfd, newfd, flags) +} + +#[inline] +fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { + if oldfd == newfd { + return Err(Errno::EINVAL); + } + + let fd = dup2(oldfd, newfd)?; + + if flags.contains(OFlag::O_CLOEXEC) { + if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) { + let _ = close(fd); + return Err(e); + } + } + + Ok(fd) +} + +/// Change the current working directory of the calling process (see +/// [chdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html)). +/// +/// This function may fail in a number of different scenarios. See the man +/// pages for additional details on possible failure cases. +#[inline] +pub fn chdir(path: &P) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::chdir(cstr.as_ptr()) } + })?; + + Errno::result(res).map(drop) +} + +/// Change the current working directory of the process to the one +/// given as an open file descriptor (see +/// [fchdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html)). +/// +/// This function may fail in a number of different scenarios. See the man +/// pages for additional details on possible failure cases. +#[inline] +#[cfg(not(target_os = "fuchsia"))] +pub fn fchdir(dirfd: RawFd) -> Result<()> { + let res = unsafe { libc::fchdir(dirfd) }; + + Errno::result(res).map(drop) +} + +/// Creates new directory `path` with access rights `mode`. (see [mkdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html)) +/// +/// # Errors +/// +/// There are several situations where mkdir might fail: +/// +/// - current user has insufficient rights in the parent directory +/// - the path already exists +/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X) +/// +/// # Example +/// +/// ```rust +/// use nix::unistd; +/// use nix::sys::stat; +/// use tempfile::tempdir; +/// +/// let tmp_dir1 = tempdir().unwrap(); +/// let tmp_dir2 = tmp_dir1.path().join("new_dir"); +/// +/// // create new directory and give read, write and execute rights to the owner +/// match unistd::mkdir(&tmp_dir2, stat::Mode::S_IRWXU) { +/// Ok(_) => println!("created {:?}", tmp_dir2), +/// Err(err) => println!("Error creating directory: {}", err), +/// } +/// ``` +#[inline] +pub fn mkdir(path: &P, mode: Mode) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t) } + })?; + + Errno::result(res).map(drop) +} + +/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`. +/// +/// # Errors +/// +/// There are several situations where mkfifo might fail: +/// +/// - current user has insufficient rights in the parent directory +/// - the path already exists +/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X) +/// +/// For a full list consult +/// [posix specification](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html) +/// +/// # Example +/// +/// ```rust +/// use nix::unistd; +/// use nix::sys::stat; +/// use tempfile::tempdir; +/// +/// let tmp_dir = tempdir().unwrap(); +/// let fifo_path = tmp_dir.path().join("foo.pipe"); +/// +/// // create new fifo and give read, write and execute rights to the owner +/// match unistd::mkfifo(&fifo_path, stat::Mode::S_IRWXU) { +/// Ok(_) => println!("created {:?}", fifo_path), +/// Err(err) => println!("Error creating fifo: {}", err), +/// } +/// ``` +#[inline] +#[cfg(not(target_os = "redox"))] // RedoxFS does not support fifo yet +pub fn mkfifo(path: &P, mode: Mode) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) } + })?; + + Errno::result(res).map(drop) +} + +/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`. +/// +/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor. +/// +/// If `dirfd` is `None`, then `path` is relative to the current working directory. +/// +/// # References +/// +/// [mkfifoat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html). +// mkfifoat is not implemented in OSX or android +#[inline] +#[cfg(not(any( + target_os = "macos", target_os = "ios", target_os = "haiku", + target_os = "android", target_os = "redox")))] +pub fn mkfifoat(dirfd: Option, path: &P, mode: Mode) -> Result<()> { + let res = path.with_nix_path(|cstr| unsafe { + libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t) + })?; + + Errno::result(res).map(drop) +} + +/// Creates a symbolic link at `path2` which points to `path1`. +/// +/// If `dirfd` has a value, then `path2` is relative to directory associated +/// with the file descriptor. +/// +/// If `dirfd` is `None`, then `path2` is relative to the current working +/// directory. This is identical to `libc::symlink(path1, path2)`. +/// +/// See also [symlinkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlinkat.html). +#[cfg(not(target_os = "redox"))] +pub fn symlinkat( + path1: &P1, + dirfd: Option, + path2: &P2) -> Result<()> { + let res = + path1.with_nix_path(|path1| { + path2.with_nix_path(|path2| { + unsafe { + libc::symlinkat( + path1.as_ptr(), + dirfd.unwrap_or(libc::AT_FDCWD), + path2.as_ptr() + ) + } + }) + })??; + Errno::result(res).map(drop) +} +} + +// Double the buffer capacity up to limit. In case it already has +// reached the limit, return Errno::ERANGE. +#[cfg(any(feature = "fs", feature = "user"))] +fn reserve_double_buffer_size(buf: &mut Vec, limit: usize) -> Result<()> { + use std::cmp::min; + + if buf.capacity() >= limit { + return Err(Errno::ERANGE); + } + + let capacity = min(buf.capacity() * 2, limit); + buf.reserve(capacity); + + Ok(()) +} + +feature! { +#![feature = "fs"] + +/// Returns the current directory as a `PathBuf` +/// +/// Err is returned if the current user doesn't have the permission to read or search a component +/// of the current path. +/// +/// # Example +/// +/// ```rust +/// use nix::unistd; +/// +/// // assume that we are allowed to get current directory +/// let dir = unistd::getcwd().unwrap(); +/// println!("The current directory is {:?}", dir); +/// ``` +#[inline] +pub fn getcwd() -> Result { + let mut buf = Vec::with_capacity(512); + loop { + unsafe { + let ptr = buf.as_mut_ptr() as *mut c_char; + + // The buffer must be large enough to store the absolute pathname plus + // a terminating null byte, or else null is returned. + // To safely handle this we start with a reasonable size (512 bytes) + // and double the buffer size upon every error + if !libc::getcwd(ptr, buf.capacity()).is_null() { + let len = CStr::from_ptr(buf.as_ptr() as *const c_char).to_bytes().len(); + buf.set_len(len); + buf.shrink_to_fit(); + return Ok(PathBuf::from(OsString::from_vec(buf))); + } else { + let error = Errno::last(); + // ERANGE means buffer was too small to store directory name + if error != Errno::ERANGE { + return Err(error); + } + } + + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?; + } + } +} +} + +feature! { +#![all(feature = "user", feature = "fs")] + +/// Computes the raw UID and GID values to pass to a `*chown` call. +// The cast is not unnecessary on all platforms. +#[allow(clippy::unnecessary_cast)] +fn chown_raw_ids(owner: Option, group: Option) -> (libc::uid_t, libc::gid_t) { + // According to the POSIX specification, -1 is used to indicate that owner and group + // are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap + // around to get -1. + let uid = owner.map(Into::into) + .unwrap_or_else(|| (0 as uid_t).wrapping_sub(1)); + let gid = group.map(Into::into) + .unwrap_or_else(|| (0 as gid_t).wrapping_sub(1)); + (uid, gid) +} + +/// Change the ownership of the file at `path` to be owned by the specified +/// `owner` (user) and `group` (see +/// [chown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html)). +/// +/// The owner/group for the provided path name will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +#[inline] +pub fn chown(path: &P, owner: Option, group: Option) -> Result<()> { + let res = path.with_nix_path(|cstr| { + let (uid, gid) = chown_raw_ids(owner, group); + unsafe { libc::chown(cstr.as_ptr(), uid, gid) } + })?; + + Errno::result(res).map(drop) +} + +/// Change the ownership of the file referred to by the open file descriptor `fd` to be owned by +/// the specified `owner` (user) and `group` (see +/// [fchown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)). +/// +/// The owner/group for the provided file will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +#[inline] +pub fn fchown(fd: RawFd, owner: Option, group: Option) -> Result<()> { + let (uid, gid) = chown_raw_ids(owner, group); + let res = unsafe { libc::fchown(fd, uid, gid) }; + Errno::result(res).map(drop) +} + +/// Flags for `fchownat` function. +#[derive(Clone, Copy, Debug)] +pub enum FchownatFlags { + FollowSymlink, + NoFollowSymlink, +} + +/// Change the ownership of the file at `path` to be owned by the specified +/// `owner` (user) and `group`. +/// +/// The owner/group for the provided path name will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +/// +/// The file to be changed is determined relative to the directory associated +/// with the file descriptor `dirfd` or the current working directory +/// if `dirfd` is `None`. +/// +/// If `flag` is `FchownatFlags::NoFollowSymlink` and `path` names a symbolic link, +/// then the mode of the symbolic link is changed. +/// +/// `fchownat(None, path, owner, group, FchownatFlags::NoFollowSymlink)` is identical to +/// a call `libc::lchown(path, owner, group)`. That's why `lchown` is unimplemented in +/// the `nix` crate. +/// +/// # References +/// +/// [fchownat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html). +#[cfg(not(target_os = "redox"))] +pub fn fchownat( + dirfd: Option, + path: &P, + owner: Option, + group: Option, + flag: FchownatFlags, +) -> Result<()> { + let atflag = + match flag { + FchownatFlags::FollowSymlink => AtFlags::empty(), + FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, + }; + let res = path.with_nix_path(|cstr| unsafe { + let (uid, gid) = chown_raw_ids(owner, group); + libc::fchownat(at_rawfd(dirfd), cstr.as_ptr(), uid, gid, + atflag.bits() as libc::c_int) + })?; + + Errno::result(res).map(drop) +} +} + +feature! { +#![feature = "process"] +fn to_exec_array>(args: &[S]) -> Vec<*const c_char> { + use std::iter::once; + args.iter() + .map(|s| s.as_ref().as_ptr()) + .chain(once(ptr::null())) + .collect() +} + +/// Replace the current process image with a new one (see +/// [exec(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). +/// +/// See the `::nix::unistd::execve` system call for additional details. `execv` +/// performs the same action but does not allow for customization of the +/// environment for the new process. +#[inline] +pub fn execv>(path: &CStr, argv: &[S]) -> Result { + let args_p = to_exec_array(argv); + + unsafe { + libc::execv(path.as_ptr(), args_p.as_ptr()) + }; + + Err(Errno::last()) +} + + +/// Replace the current process image with a new one (see +/// [execve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). +/// +/// The execve system call allows for another process to be "called" which will +/// replace the current process image. That is, this process becomes the new +/// command that is run. On success, this function will not return. Instead, +/// the new program will run until it exits. +/// +/// `::nix::unistd::execv` and `::nix::unistd::execve` take as arguments a slice +/// of `::std::ffi::CString`s for `args` and `env` (for `execve`). Each element +/// in the `args` list is an argument to the new process. Each element in the +/// `env` list should be a string in the form "key=value". +#[inline] +pub fn execve, SE: AsRef>(path: &CStr, args: &[SA], env: &[SE]) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + + unsafe { + libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + }; + + Err(Errno::last()) +} + +/// Replace the current process image with a new one and replicate shell `PATH` +/// searching behavior (see +/// [exec(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). +/// +/// See `::nix::unistd::execve` for additional details. `execvp` behaves the +/// same as execv except that it will examine the `PATH` environment variables +/// for file names not specified with a leading slash. For example, `execv` +/// would not work if "bash" was specified for the path argument, but `execvp` +/// would assuming that a bash executable was on the system `PATH`. +#[inline] +pub fn execvp>(filename: &CStr, args: &[S]) -> Result { + let args_p = to_exec_array(args); + + unsafe { + libc::execvp(filename.as_ptr(), args_p.as_ptr()) + }; + + Err(Errno::last()) +} + +/// Replace the current process image with a new one and replicate shell `PATH` +/// searching behavior (see +/// [`execvpe(3)`](https://man7.org/linux/man-pages/man3/exec.3.html)). +/// +/// This functions like a combination of `execvp(2)` and `execve(2)` to pass an +/// environment and have a search path. See these two for additional +/// information. +#[cfg(any(target_os = "haiku", + target_os = "linux", + target_os = "openbsd"))] +pub fn execvpe, SE: AsRef>(filename: &CStr, args: &[SA], env: &[SE]) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + + unsafe { + libc::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + }; + + Err(Errno::last()) +} + +/// Replace the current process image with a new one (see +/// [fexecve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html)). +/// +/// The `fexecve` function allows for another process to be "called" which will +/// replace the current process image. That is, this process becomes the new +/// command that is run. On success, this function will not return. Instead, +/// the new program will run until it exits. +/// +/// This function is similar to `execve`, except that the program to be executed +/// is referenced as a file descriptor instead of a path. +#[cfg(any(target_os = "android", + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd"))] +#[inline] +pub fn fexecve ,SE: AsRef>(fd: RawFd, args: &[SA], env: &[SE]) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + + unsafe { + libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr()) + }; + + Err(Errno::last()) +} + +/// Execute program relative to a directory file descriptor (see +/// [execveat(2)](https://man7.org/linux/man-pages/man2/execveat.2.html)). +/// +/// The `execveat` function allows for another process to be "called" which will +/// replace the current process image. That is, this process becomes the new +/// command that is run. On success, this function will not return. Instead, +/// the new program will run until it exits. +/// +/// This function is similar to `execve`, except that the program to be executed +/// is referenced as a file descriptor to the base directory plus a path. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub fn execveat,SE: AsRef>(dirfd: RawFd, pathname: &CStr, args: &[SA], + env: &[SE], flags: super::fcntl::AtFlags) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + + unsafe { + libc::syscall(libc::SYS_execveat, dirfd, pathname.as_ptr(), + args_p.as_ptr(), env_p.as_ptr(), flags); + }; + + Err(Errno::last()) +} + +/// Daemonize this process by detaching from the controlling terminal (see +/// [daemon(3)](https://man7.org/linux/man-pages/man3/daemon.3.html)). +/// +/// When a process is launched it is typically associated with a parent and it, +/// in turn, by its controlling terminal/process. In order for a process to run +/// in the "background" it must daemonize itself by detaching itself. Under +/// posix, this is done by doing the following: +/// +/// 1. Parent process (this one) forks +/// 2. Parent process exits +/// 3. Child process continues to run. +/// +/// `nochdir`: +/// +/// * `nochdir = true`: The current working directory after daemonizing will +/// be the current working directory. +/// * `nochdir = false`: The current working directory after daemonizing will +/// be the root direcory, `/`. +/// +/// `noclose`: +/// +/// * `noclose = true`: The process' current stdin, stdout, and stderr file +/// descriptors will remain identical after daemonizing. +/// * `noclose = false`: The process' stdin, stdout, and stderr will point to +/// `/dev/null` after daemonizing. +#[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] +pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> { + let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) }; + Errno::result(res).map(drop) +} +} + +feature! { +#![feature = "hostname"] + +/// Set the system host name (see +/// [sethostname(2)](https://man7.org/linux/man-pages/man2/gethostname.2.html)). +/// +/// Given a name, attempt to update the system host name to the given string. +/// On some systems, the host name is limited to as few as 64 bytes. An error +/// will be returned if the name is not valid or the current process does not +/// have permissions to update the host name. +#[cfg(not(target_os = "redox"))] +pub fn sethostname>(name: S) -> Result<()> { + // Handle some differences in type of the len arg across platforms. + cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "solaris", ))] { + type sethostname_len_t = c_int; + } else { + type sethostname_len_t = size_t; + } + } + let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char; + let len = name.as_ref().len() as sethostname_len_t; + + let res = unsafe { libc::sethostname(ptr, len) }; + Errno::result(res).map(drop) +} + +/// Get the host name and store it in an internally allocated buffer, returning an +/// `OsString` on success (see +/// [gethostname(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)). +/// +/// This function call attempts to get the host name for the running system and +/// store it in an internal buffer, returning it as an `OsString` if successful. +/// +/// ```no_run +/// use nix::unistd; +/// +/// let hostname = unistd::gethostname().expect("Failed getting hostname"); +/// let hostname = hostname.into_string().expect("Hostname wasn't valid UTF-8"); +/// println!("Hostname: {}", hostname); +/// ``` +pub fn gethostname() -> Result { + // The capacity is the max length of a hostname plus the NUL terminator. + let mut buffer: Vec = Vec::with_capacity(256); + let ptr = buffer.as_mut_ptr() as *mut c_char; + let len = buffer.capacity() as size_t; + + let res = unsafe { libc::gethostname(ptr, len) }; + Errno::result(res).map(|_| { + unsafe { + buffer.as_mut_ptr().wrapping_add(len - 1).write(0); // ensure always null-terminated + let len = CStr::from_ptr(buffer.as_ptr() as *const c_char).len(); + buffer.set_len(len); + } + OsString::from_vec(buffer) + }) +} +} + +/// Close a raw file descriptor +/// +/// Be aware that many Rust types implicitly close-on-drop, including +/// `std::fs::File`. Explicitly closing them with this method too can result in +/// a double-close condition, which can cause confusing `EBADF` errors in +/// seemingly unrelated code. Caveat programmer. See also +/// [close(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html). +/// +/// # Examples +/// +/// ```no_run +/// use std::os::unix::io::AsRawFd; +/// use nix::unistd::close; +/// +/// let f = tempfile::tempfile().unwrap(); +/// close(f.as_raw_fd()).unwrap(); // Bad! f will also close on drop! +/// ``` +/// +/// ```rust +/// use std::os::unix::io::IntoRawFd; +/// use nix::unistd::close; +/// +/// let f = tempfile::tempfile().unwrap(); +/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f +/// ``` +pub fn close(fd: RawFd) -> Result<()> { + let res = unsafe { libc::close(fd) }; + Errno::result(res).map(drop) +} + +/// Read from a raw file descriptor. +/// +/// See also [read(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html) +pub fn read(fd: RawFd, buf: &mut [u8]) -> Result { + let res = unsafe { + libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) + }; + + Errno::result(res).map(|r| r as usize) +} + +/// Write to a raw file descriptor. +/// +/// See also [write(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html) +pub fn write(fd: RawFd, buf: &[u8]) -> Result { + let res = unsafe { + libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) + }; + + Errno::result(res).map(|r| r as usize) +} + +feature! { +#![feature = "fs"] + +/// Directive that tells [`lseek`] and [`lseek64`] what the offset is relative to. +/// +/// [`lseek`]: ./fn.lseek.html +/// [`lseek64`]: ./fn.lseek64.html +#[repr(i32)] +#[derive(Clone, Copy, Debug)] +pub enum Whence { + /// Specify an offset relative to the start of the file. + SeekSet = libc::SEEK_SET, + /// Specify an offset relative to the current file location. + SeekCur = libc::SEEK_CUR, + /// Specify an offset relative to the end of the file. + SeekEnd = libc::SEEK_END, + /// Specify an offset relative to the next location in the file greater than or + /// equal to offset that contains some data. If offset points to + /// some data, then the file offset is set to offset. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "solaris"))] + SeekData = libc::SEEK_DATA, + /// Specify an offset relative to the next hole in the file greater than + /// or equal to offset. If offset points into the middle of a hole, then + /// the file offset should be set to offset. If there is no hole past offset, + /// then the file offset should be adjusted to the end of the file (i.e., there + /// is an implicit hole at the end of any file). + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "solaris"))] + SeekHole = libc::SEEK_HOLE +} + +/// Move the read/write file offset. +/// +/// See also [lseek(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html) +pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result { + let res = unsafe { libc::lseek(fd, offset, whence as i32) }; + + Errno::result(res).map(|r| r as off_t) +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result { + let res = unsafe { libc::lseek64(fd, offset, whence as i32) }; + + Errno::result(res).map(|r| r as libc::off64_t) +} +} + +/// Create an interprocess channel. +/// +/// See also [pipe(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html) +pub fn pipe() -> std::result::Result<(RawFd, RawFd), Error> { + let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); + + let res = unsafe { libc::pipe(fds.as_mut_ptr() as *mut c_int) }; + + Error::result(res)?; + + unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) } +} + +feature! { +#![feature = "fs"] +/// Like `pipe`, but allows setting certain file descriptor flags. +/// +/// The following flags are supported, and will be set atomically as the pipe is +/// created: +/// +/// - `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors. +#[cfg_attr(target_os = "linux", doc = "- `O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode.")] +#[cfg_attr(target_os = "netbsd", doc = "- `O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`.")] +/// - `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe. +/// +/// See also [pipe(2)](https://man7.org/linux/man-pages/man2/pipe.2.html) +#[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "redox", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] +pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { + let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); + + let res = unsafe { + libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits()) + }; + + Errno::result(res)?; + + unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) } +} + +/// Truncate a file to a specified length +/// +/// See also +/// [truncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html) +#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] +pub fn truncate(path: &P, len: off_t) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { + libc::truncate(cstr.as_ptr(), len) + } + })?; + + Errno::result(res).map(drop) +} + +/// Truncate a file to a specified length +/// +/// See also +/// [ftruncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html) +pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> { + Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop) +} + +pub fn isatty(fd: RawFd) -> Result { + unsafe { + // ENOTTY means `fd` is a valid file descriptor, but not a TTY, so + // we return `Ok(false)` + if libc::isatty(fd) == 1 { + Ok(true) + } else { + match Errno::last() { + Errno::ENOTTY => Ok(false), + err => Err(err), + } + } + } +} + +/// Flags for `linkat` function. +#[derive(Clone, Copy, Debug)] +pub enum LinkatFlags { + SymlinkFollow, + NoSymlinkFollow, +} + +/// Link one file to another file +/// +/// Creates a new link (directory entry) at `newpath` for the existing file at `oldpath`. In the +/// case of a relative `oldpath`, the path is interpreted relative to the directory associated +/// with file descriptor `olddirfd` instead of the current working directory and similiarly for +/// `newpath` and file descriptor `newdirfd`. In case `flag` is LinkatFlags::SymlinkFollow and +/// `oldpath` names a symoblic link, a new link for the target of the symbolic link is created. +/// If either `olddirfd` or `newdirfd` is `None`, `AT_FDCWD` is used respectively where `oldpath` +/// and/or `newpath` is then interpreted relative to the current working directory of the calling +/// process. If either `oldpath` or `newpath` is absolute, then `dirfd` is ignored. +/// +/// # References +/// See also [linkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html) +#[cfg(not(target_os = "redox"))] // RedoxFS does not support symlinks yet +pub fn linkat( + olddirfd: Option, + oldpath: &P, + newdirfd: Option, + newpath: &P, + flag: LinkatFlags, +) -> Result<()> { + + let atflag = + match flag { + LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW, + LinkatFlags::NoSymlinkFollow => AtFlags::empty(), + }; + + let res = + oldpath.with_nix_path(|oldcstr| { + newpath.with_nix_path(|newcstr| { + unsafe { + libc::linkat( + at_rawfd(olddirfd), + oldcstr.as_ptr(), + at_rawfd(newdirfd), + newcstr.as_ptr(), + atflag.bits() as libc::c_int + ) + } + }) + })??; + Errno::result(res).map(drop) +} + + +/// Remove a directory entry +/// +/// See also [unlink(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html) +pub fn unlink(path: &P) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { + libc::unlink(cstr.as_ptr()) + } + })?; + Errno::result(res).map(drop) +} + +/// Flags for `unlinkat` function. +#[derive(Clone, Copy, Debug)] +pub enum UnlinkatFlags { + RemoveDir, + NoRemoveDir, +} + +/// Remove a directory entry +/// +/// In the case of a relative path, the directory entry to be removed is determined relative to +/// the directory associated with the file descriptor `dirfd` or the current working directory +/// if `dirfd` is `None`. In the case of an absolute `path` `dirfd` is ignored. If `flag` is +/// `UnlinkatFlags::RemoveDir` then removal of the directory entry specified by `dirfd` and `path` +/// is performed. +/// +/// # References +/// See also [unlinkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html) +#[cfg(not(target_os = "redox"))] +pub fn unlinkat( + dirfd: Option, + path: &P, + flag: UnlinkatFlags, +) -> Result<()> { + let atflag = + match flag { + UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR, + UnlinkatFlags::NoRemoveDir => AtFlags::empty(), + }; + let res = path.with_nix_path(|cstr| { + unsafe { + libc::unlinkat(at_rawfd(dirfd), cstr.as_ptr(), atflag.bits() as libc::c_int) + } + })?; + Errno::result(res).map(drop) +} + + +#[inline] +#[cfg(not(target_os = "fuchsia"))] +pub fn chroot(path: &P) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::chroot(cstr.as_ptr()) } + })?; + + Errno::result(res).map(drop) +} + +/// Commit filesystem caches to disk +/// +/// See also [sync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html) +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd" +))] +pub fn sync() { + unsafe { libc::sync() }; +} + +/// Synchronize changes to a file +/// +/// See also [fsync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html) +#[inline] +pub fn fsync(fd: RawFd) -> Result<()> { + let res = unsafe { libc::fsync(fd) }; + + Errno::result(res).map(drop) +} + +/// Synchronize the data of a file +/// +/// See also +/// [fdatasync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html) +#[cfg(any(target_os = "linux", + target_os = "android", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris"))] +#[inline] +pub fn fdatasync(fd: RawFd) -> Result<()> { + let res = unsafe { libc::fdatasync(fd) }; + + Errno::result(res).map(drop) +} +} + +feature! { +#![feature = "user"] + +/// Get a real user ID +/// +/// See also [getuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html) +// POSIX requires that getuid is always successful, so no need to check return +// value or errno. +#[inline] +pub fn getuid() -> Uid { + Uid(unsafe { libc::getuid() }) +} + +/// Get the effective user ID +/// +/// See also [geteuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html) +// POSIX requires that geteuid is always successful, so no need to check return +// value or errno. +#[inline] +pub fn geteuid() -> Uid { + Uid(unsafe { libc::geteuid() }) +} + +/// Get the real group ID +/// +/// See also [getgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html) +// POSIX requires that getgid is always successful, so no need to check return +// value or errno. +#[inline] +pub fn getgid() -> Gid { + Gid(unsafe { libc::getgid() }) +} + +/// Get the effective group ID +/// +/// See also [getegid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html) +// POSIX requires that getegid is always successful, so no need to check return +// value or errno. +#[inline] +pub fn getegid() -> Gid { + Gid(unsafe { libc::getegid() }) +} + +/// Set the effective user ID +/// +/// See also [seteuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/seteuid.html) +#[inline] +pub fn seteuid(euid: Uid) -> Result<()> { + let res = unsafe { libc::seteuid(euid.into()) }; + + Errno::result(res).map(drop) +} + +/// Set the effective group ID +/// +/// See also [setegid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html) +#[inline] +pub fn setegid(egid: Gid) -> Result<()> { + let res = unsafe { libc::setegid(egid.into()) }; + + Errno::result(res).map(drop) +} + +/// Set the user ID +/// +/// See also [setuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html) +#[inline] +pub fn setuid(uid: Uid) -> Result<()> { + let res = unsafe { libc::setuid(uid.into()) }; + + Errno::result(res).map(drop) +} + +/// Set the group ID +/// +/// See also [setgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html) +#[inline] +pub fn setgid(gid: Gid) -> Result<()> { + let res = unsafe { libc::setgid(gid.into()) }; + + Errno::result(res).map(drop) +} +} + +feature! { +#![all(feature = "fs", feature = "user")] +/// Set the user identity used for filesystem checks per-thread. +/// On both success and failure, this call returns the previous filesystem user +/// ID of the caller. +/// +/// See also [setfsuid(2)](https://man7.org/linux/man-pages/man2/setfsuid.2.html) +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn setfsuid(uid: Uid) -> Uid { + let prev_fsuid = unsafe { libc::setfsuid(uid.into()) }; + Uid::from_raw(prev_fsuid as uid_t) +} + +/// Set the group identity used for filesystem checks per-thread. +/// On both success and failure, this call returns the previous filesystem group +/// ID of the caller. +/// +/// See also [setfsgid(2)](https://man7.org/linux/man-pages/man2/setfsgid.2.html) +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn setfsgid(gid: Gid) -> Gid { + let prev_fsgid = unsafe { libc::setfsgid(gid.into()) }; + Gid::from_raw(prev_fsgid as gid_t) +} +} + +feature! { +#![feature = "user"] + +/// Get the list of supplementary group IDs of the calling process. +/// +/// [Further reading](https://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html) +/// +/// **Note:** This function is not available for Apple platforms. On those +/// platforms, checking group membership should be achieved via communication +/// with the `opendirectoryd` service. +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub fn getgroups() -> Result> { + // First get the maximum number of groups. The value returned + // shall always be greater than or equal to one and less than or + // equal to the value of {NGROUPS_MAX} + 1. + let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) { + Ok(Some(n)) => (n + 1) as usize, + Ok(None) | Err(_) => ::max_value(), + }; + + // Next, get the number of groups so we can size our Vec + let ngroups = unsafe { libc::getgroups(0, ptr::null_mut()) }; + + // If there are no supplementary groups, return early. + // This prevents a potential buffer over-read if the number of groups + // increases from zero before the next call. It would return the total + // number of groups beyond the capacity of the buffer. + if ngroups == 0 { + return Ok(Vec::new()); + } + + // Now actually get the groups. We try multiple times in case the number of + // groups has changed since the first call to getgroups() and the buffer is + // now too small. + let mut groups = Vec::::with_capacity(Errno::result(ngroups)? as usize); + loop { + // FIXME: On the platforms we currently support, the `Gid` struct has + // the same representation in memory as a bare `gid_t`. This is not + // necessarily the case on all Rust platforms, though. See RFC 1785. + let ngroups = unsafe { + libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t) + }; + + match Errno::result(ngroups) { + Ok(s) => { + unsafe { groups.set_len(s as usize) }; + return Ok(groups); + }, + Err(Errno::EINVAL) => { + // EINVAL indicates that the buffer size was too + // small, resize it up to ngroups_max as limit. + reserve_double_buffer_size(&mut groups, ngroups_max) + .or(Err(Errno::EINVAL))?; + }, + Err(e) => return Err(e) + } + } +} + +/// Set the list of supplementary group IDs for the calling process. +/// +/// [Further reading](https://man7.org/linux/man-pages/man2/getgroups.2.html) +/// +/// **Note:** This function is not available for Apple platforms. On those +/// platforms, group membership management should be achieved via communication +/// with the `opendirectoryd` service. +/// +/// # Examples +/// +/// `setgroups` can be used when dropping privileges from the root user to a +/// specific user and group. For example, given the user `www-data` with UID +/// `33` and the group `backup` with the GID `34`, one could switch the user as +/// follows: +/// +/// ```rust,no_run +/// # use std::error::Error; +/// # use nix::unistd::*; +/// # +/// # fn try_main() -> Result<(), Box> { +/// let uid = Uid::from_raw(33); +/// let gid = Gid::from_raw(34); +/// setgroups(&[gid])?; +/// setgid(gid)?; +/// setuid(uid)?; +/// # +/// # Ok(()) +/// # } +/// # +/// # try_main().unwrap(); +/// ``` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))] +pub fn setgroups(groups: &[Gid]) -> Result<()> { + cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "illumos", + target_os = "openbsd"))] { + type setgroups_ngroups_t = c_int; + } else { + type setgroups_ngroups_t = size_t; + } + } + // FIXME: On the platforms we currently support, the `Gid` struct has the + // same representation in memory as a bare `gid_t`. This is not necessarily + // the case on all Rust platforms, though. See RFC 1785. + let res = unsafe { + libc::setgroups(groups.len() as setgroups_ngroups_t, groups.as_ptr() as *const gid_t) + }; + + Errno::result(res).map(drop) +} + +/// Calculate the supplementary group access list. +/// +/// Gets the group IDs of all groups that `user` is a member of. The additional +/// group `group` is also added to the list. +/// +/// [Further reading](https://man7.org/linux/man-pages/man3/getgrouplist.3.html) +/// +/// **Note:** This function is not available for Apple platforms. On those +/// platforms, checking group membership should be achieved via communication +/// with the `opendirectoryd` service. +/// +/// # Errors +/// +/// Although the `getgrouplist()` call does not return any specific +/// errors on any known platforms, this implementation will return a system +/// error of `EINVAL` if the number of groups to be fetched exceeds the +/// `NGROUPS_MAX` sysconf value. This mimics the behaviour of `getgroups()` +/// and `setgroups()`. Additionally, while some implementations will return a +/// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation +/// will only ever return the complete list or else an error. +#[cfg(not(any(target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "redox")))] +pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) { + Ok(Some(n)) => n as c_int, + Ok(None) | Err(_) => ::max_value(), + }; + use std::cmp::min; + let mut groups = Vec::::with_capacity(min(ngroups_max, 8) as usize); + cfg_if! { + if #[cfg(any(target_os = "ios", target_os = "macos"))] { + type getgrouplist_group_t = c_int; + } else { + type getgrouplist_group_t = gid_t; + } + } + let gid: gid_t = group.into(); + loop { + let mut ngroups = groups.capacity() as i32; + let ret = unsafe { + libc::getgrouplist(user.as_ptr(), + gid as getgrouplist_group_t, + groups.as_mut_ptr() as *mut getgrouplist_group_t, + &mut ngroups) + }; + + // BSD systems only return 0 or -1, Linux returns ngroups on success. + if ret >= 0 { + unsafe { groups.set_len(ngroups as usize) }; + return Ok(groups); + } else if ret == -1 { + // Returns -1 if ngroups is too small, but does not set errno. + // BSD systems will still fill the groups buffer with as many + // groups as possible, but Linux manpages do not mention this + // behavior. + reserve_double_buffer_size(&mut groups, ngroups_max as usize) + .map_err(|_| Errno::EINVAL)?; + } + } +} + +/// Initialize the supplementary group access list. +/// +/// Sets the supplementary group IDs for the calling process using all groups +/// that `user` is a member of. The additional group `group` is also added to +/// the list. +/// +/// [Further reading](https://man7.org/linux/man-pages/man3/initgroups.3.html) +/// +/// **Note:** This function is not available for Apple platforms. On those +/// platforms, group membership management should be achieved via communication +/// with the `opendirectoryd` service. +/// +/// # Examples +/// +/// `initgroups` can be used when dropping privileges from the root user to +/// another user. For example, given the user `www-data`, we could look up the +/// UID and GID for the user in the system's password database (usually found +/// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`, +/// respectively, one could switch the user as follows: +/// +/// ```rust,no_run +/// # use std::error::Error; +/// # use std::ffi::CString; +/// # use nix::unistd::*; +/// # +/// # fn try_main() -> Result<(), Box> { +/// let user = CString::new("www-data").unwrap(); +/// let uid = Uid::from_raw(33); +/// let gid = Gid::from_raw(33); +/// initgroups(&user, gid)?; +/// setgid(gid)?; +/// setuid(uid)?; +/// # +/// # Ok(()) +/// # } +/// # +/// # try_main().unwrap(); +/// ``` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))] +pub fn initgroups(user: &CStr, group: Gid) -> Result<()> { + cfg_if! { + if #[cfg(any(target_os = "ios", target_os = "macos"))] { + type initgroups_group_t = c_int; + } else { + type initgroups_group_t = gid_t; + } + } + let gid: gid_t = group.into(); + let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) }; + + Errno::result(res).map(drop) +} +} + +feature! { +#![feature = "signal"] + +/// Suspend the thread until a signal is received. +/// +/// See also [pause(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html). +#[inline] +#[cfg(not(target_os = "redox"))] +pub fn pause() { + unsafe { libc::pause() }; +} + +pub mod alarm { + //! Alarm signal scheduling. + //! + //! Scheduling an alarm will trigger a `SIGALRM` signal when the time has + //! elapsed, which has to be caught, because the default action for the + //! signal is to terminate the program. This signal also can't be ignored + //! because the system calls like `pause` will not be interrupted, see the + //! second example below. + //! + //! # Examples + //! + //! Canceling an alarm: + //! + //! ``` + //! use nix::unistd::alarm; + //! + //! // Set an alarm for 60 seconds from now. + //! alarm::set(60); + //! + //! // Cancel the above set alarm, which returns the number of seconds left + //! // of the previously set alarm. + //! assert_eq!(alarm::cancel(), Some(60)); + //! ``` + //! + //! Scheduling an alarm and waiting for the signal: + //! +#![cfg_attr(target_os = "redox", doc = " ```rust,ignore")] +#![cfg_attr(not(target_os = "redox"), doc = " ```rust")] + //! use std::time::{Duration, Instant}; + //! + //! use nix::unistd::{alarm, pause}; + //! use nix::sys::signal::*; + //! + //! // We need to setup an empty signal handler to catch the alarm signal, + //! // otherwise the program will be terminated once the signal is delivered. + //! extern fn signal_handler(_: nix::libc::c_int) { } + //! let sa = SigAction::new( + //! SigHandler::Handler(signal_handler), + //! SaFlags::SA_RESTART, + //! SigSet::empty() + //! ); + //! unsafe { + //! sigaction(Signal::SIGALRM, &sa); + //! } + //! + //! let start = Instant::now(); + //! + //! // Set an alarm for 1 second from now. + //! alarm::set(1); + //! + //! // Pause the process until the alarm signal is received. + //! let mut sigset = SigSet::empty(); + //! sigset.add(Signal::SIGALRM); + //! sigset.wait(); + //! + //! assert!(start.elapsed() >= Duration::from_secs(1)); + //! ``` + //! + //! # References + //! + //! See also [alarm(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html). + + /// Schedule an alarm signal. + /// + /// This will cause the system to generate a `SIGALRM` signal for the + /// process after the specified number of seconds have elapsed. + /// + /// Returns the leftover time of a previously set alarm if there was one. + pub fn set(secs: libc::c_uint) -> Option { + assert!(secs != 0, "passing 0 to `alarm::set` is not allowed, to cancel an alarm use `alarm::cancel`"); + alarm(secs) + } + + /// Cancel an previously set alarm signal. + /// + /// Returns the leftover time of a previously set alarm if there was one. + pub fn cancel() -> Option { + alarm(0) + } + + fn alarm(secs: libc::c_uint) -> Option { + match unsafe { libc::alarm(secs) } { + 0 => None, + secs => Some(secs), + } + } +} +} + +/// Suspend execution for an interval of time +/// +/// See also [sleep(2)](https://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05) +// Per POSIX, does not fail +#[inline] +pub fn sleep(seconds: c_uint) -> c_uint { + unsafe { libc::sleep(seconds) } +} + +feature! { +#![feature = "acct"] + +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +pub mod acct { + use crate::{Result, NixPath}; + use crate::errno::Errno; + use std::ptr; + + /// Enable process accounting + /// + /// See also [acct(2)](https://linux.die.net/man/2/acct) + pub fn enable(filename: &P) -> Result<()> { + let res = filename.with_nix_path(|cstr| { + unsafe { libc::acct(cstr.as_ptr()) } + })?; + + Errno::result(res).map(drop) + } + + /// Disable process accounting + pub fn disable() -> Result<()> { + let res = unsafe { libc::acct(ptr::null()) }; + + Errno::result(res).map(drop) + } +} +} + +feature! { +#![feature = "fs"] +/// Creates a regular file which persists even after process termination +/// +/// * `template`: a path whose 6 rightmost characters must be X, e.g. `/tmp/tmpfile_XXXXXX` +/// * returns: tuple of file descriptor and filename +/// +/// Err is returned either if no temporary filename could be created or the template doesn't +/// end with XXXXXX +/// +/// See also [mkstemp(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkstemp.html) +/// +/// # Example +/// +/// ```rust +/// use nix::unistd; +/// +/// let _ = match unistd::mkstemp("/tmp/tempfile_XXXXXX") { +/// Ok((fd, path)) => { +/// unistd::unlink(path.as_path()).unwrap(); // flag file to be deleted at app termination +/// fd +/// } +/// Err(e) => panic!("mkstemp failed: {}", e) +/// }; +/// // do something with fd +/// ``` +#[inline] +pub fn mkstemp(template: &P) -> Result<(RawFd, PathBuf)> { + let mut path = template.with_nix_path(|path| {path.to_bytes_with_nul().to_owned()})?; + let p = path.as_mut_ptr() as *mut _; + let fd = unsafe { libc::mkstemp(p) }; + let last = path.pop(); // drop the trailing nul + debug_assert!(last == Some(b'\0')); + let pathname = OsString::from_vec(path); + Errno::result(fd)?; + Ok((fd, PathBuf::from(pathname))) +} +} + +feature! { +#![all(feature = "fs", feature = "feature")] + +/// Variable names for `pathconf` +/// +/// Nix uses the same naming convention for these variables as the +/// [getconf(1)](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility. +/// That is, `PathconfVar` variables have the same name as the abstract +/// variables shown in the `pathconf(2)` man page. Usually, it's the same as +/// the C variable name without the leading `_PC_`. +/// +/// POSIX 1003.1-2008 standardizes all of these variables, but some OSes choose +/// not to implement variables that cannot change at runtime. +/// +/// # References +/// +/// - [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) +/// - [limits.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) +/// - [unistd.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html) +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(i32)] +#[non_exhaustive] +pub enum PathconfVar { + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux", + target_os = "netbsd", target_os = "openbsd", target_os = "redox"))] + /// Minimum number of bits needed to represent, as a signed integer value, + /// the maximum size of a regular file allowed in the specified directory. + #[cfg_attr(docsrs, doc(cfg(all())))] + FILESIZEBITS = libc::_PC_FILESIZEBITS, + /// Maximum number of links to a single file. + LINK_MAX = libc::_PC_LINK_MAX, + /// Maximum number of bytes in a terminal canonical input line. + MAX_CANON = libc::_PC_MAX_CANON, + /// Minimum number of bytes for which space is available in a terminal input + /// queue; therefore, the maximum number of bytes a conforming application + /// may require to be typed as input before reading them. + MAX_INPUT = libc::_PC_MAX_INPUT, + /// Maximum number of bytes in a filename (not including the terminating + /// null of a filename string). + NAME_MAX = libc::_PC_NAME_MAX, + /// Maximum number of bytes the implementation will store as a pathname in a + /// user-supplied buffer of unspecified size, including the terminating null + /// character. Minimum number the implementation will accept as the maximum + /// number of bytes in a pathname. + PATH_MAX = libc::_PC_PATH_MAX, + /// Maximum number of bytes that is guaranteed to be atomic when writing to + /// a pipe. + PIPE_BUF = libc::_PC_PIPE_BUF, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "illumos", + target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "redox", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Symbolic links can be created. + POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "linux", target_os = "openbsd", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Minimum number of bytes of storage actually allocated for any portion of + /// a file. + POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "linux", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Recommended increment for file transfer sizes between the + /// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values. + POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "linux", target_os = "openbsd", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Maximum recommended file transfer size. + POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "linux", target_os = "openbsd", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Minimum recommended file transfer size. + POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "linux", target_os = "openbsd", target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Recommended file transfer buffer alignment. + POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_os = "redox", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Maximum number of bytes in a symbolic link. + SYMLINK_MAX = libc::_PC_SYMLINK_MAX, + /// The use of `chown` and `fchown` is restricted to a process with + /// appropriate privileges, and to changing the group ID of a file only to + /// the effective group ID of the process or to one of its supplementary + /// group IDs. + _POSIX_CHOWN_RESTRICTED = libc::_PC_CHOWN_RESTRICTED, + /// Pathname components longer than {NAME_MAX} generate an error. + _POSIX_NO_TRUNC = libc::_PC_NO_TRUNC, + /// This symbol shall be defined to be the value of a character that shall + /// disable terminal special character handling. + _POSIX_VDISABLE = libc::_PC_VDISABLE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "openbsd", + target_os = "redox", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Asynchronous input or output operations may be performed for the + /// associated file. + _POSIX_ASYNC_IO = libc::_PC_ASYNC_IO, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "openbsd", + target_os = "redox", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Prioritized input or output operations may be performed for the + /// associated file. + _POSIX_PRIO_IO = libc::_PC_PRIO_IO, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_os = "redox", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Synchronized input or output operations may be performed for the + /// associated file. + _POSIX_SYNC_IO = libc::_PC_SYNC_IO, + #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The resolution in nanoseconds for all file timestamps. + _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION +} + +/// Like `pathconf`, but works with file descriptors instead of paths (see +/// [fpathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)) +/// +/// # Parameters +/// +/// - `fd`: The file descriptor whose variable should be interrogated +/// - `var`: The pathconf variable to lookup +/// +/// # Returns +/// +/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its +/// implementation level (for option variables). Implementation levels are +/// usually a decimal-coded date, such as 200112 for POSIX 2001.12 +/// - `Ok(None)`: the variable has no limit (for limit variables) or is +/// unsupported (for option variables) +/// - `Err(x)`: an error occurred +pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result> { + let raw = unsafe { + Errno::clear(); + libc::fpathconf(fd, var as c_int) + }; + if raw == -1 { + if errno::errno() == 0 { + Ok(None) + } else { + Err(Errno::last()) + } + } else { + Ok(Some(raw)) + } +} + +/// Get path-dependent configurable system variables (see +/// [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)) +/// +/// Returns the value of a path-dependent configurable system variable. Most +/// supported variables also have associated compile-time constants, but POSIX +/// allows their values to change at runtime. There are generally two types of +/// `pathconf` variables: options and limits. See [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) for more details. +/// +/// # Parameters +/// +/// - `path`: Lookup the value of `var` for this file or directory +/// - `var`: The `pathconf` variable to lookup +/// +/// # Returns +/// +/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its +/// implementation level (for option variables). Implementation levels are +/// usually a decimal-coded date, such as 200112 for POSIX 2001.12 +/// - `Ok(None)`: the variable has no limit (for limit variables) or is +/// unsupported (for option variables) +/// - `Err(x)`: an error occurred +pub fn pathconf(path: &P, var: PathconfVar) -> Result> { + let raw = path.with_nix_path(|cstr| { + unsafe { + Errno::clear(); + libc::pathconf(cstr.as_ptr(), var as c_int) + } + })?; + if raw == -1 { + if errno::errno() == 0 { + Ok(None) + } else { + Err(Errno::last()) + } + } else { + Ok(Some(raw)) + } +} +} + +feature! { +#![feature = "feature"] + +/// Variable names for `sysconf` +/// +/// Nix uses the same naming convention for these variables as the +/// [getconf(1)](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility. +/// That is, `SysconfVar` variables have the same name as the abstract variables +/// shown in the `sysconf(3)` man page. Usually, it's the same as the C +/// variable name without the leading `_SC_`. +/// +/// All of these symbols are standardized by POSIX 1003.1-2008, but haven't been +/// implemented by all platforms. +/// +/// # References +/// +/// - [sysconf(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html) +/// - [unistd.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html) +/// - [limits.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(i32)] +#[non_exhaustive] +pub enum SysconfVar { + /// Maximum number of I/O operations in a single list I/O call supported by + /// the implementation. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AIO_LISTIO_MAX = libc::_SC_AIO_LISTIO_MAX, + /// Maximum number of outstanding asynchronous I/O operations supported by + /// the implementation. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + AIO_MAX = libc::_SC_AIO_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The maximum amount by which a process can decrease its asynchronous I/O + /// priority level from its own scheduling priority. + AIO_PRIO_DELTA_MAX = libc::_SC_AIO_PRIO_DELTA_MAX, + /// Maximum length of argument to the exec functions including environment data. + ARG_MAX = libc::_SC_ARG_MAX, + /// Maximum number of functions that may be registered with `atexit`. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + ATEXIT_MAX = libc::_SC_ATEXIT_MAX, + /// Maximum obase values allowed by the bc utility. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BC_BASE_MAX = libc::_SC_BC_BASE_MAX, + /// Maximum number of elements permitted in an array by the bc utility. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BC_DIM_MAX = libc::_SC_BC_DIM_MAX, + /// Maximum scale value allowed by the bc utility. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BC_SCALE_MAX = libc::_SC_BC_SCALE_MAX, + /// Maximum length of a string constant accepted by the bc utility. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + BC_STRING_MAX = libc::_SC_BC_STRING_MAX, + /// Maximum number of simultaneous processes per real user ID. + CHILD_MAX = libc::_SC_CHILD_MAX, + // The number of clock ticks per second. + CLK_TCK = libc::_SC_CLK_TCK, + /// Maximum number of weights that can be assigned to an entry of the + /// LC_COLLATE order keyword in the locale definition file + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + COLL_WEIGHTS_MAX = libc::_SC_COLL_WEIGHTS_MAX, + /// Maximum number of timer expiration overruns. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + DELAYTIMER_MAX = libc::_SC_DELAYTIMER_MAX, + /// Maximum number of expressions that can be nested within parentheses by + /// the expr utility. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Maximum length of a host name (not including the terminating null) as + /// returned from the `gethostname` function + HOST_NAME_MAX = libc::_SC_HOST_NAME_MAX, + /// Maximum number of iovec structures that one process has available for + /// use with `readv` or `writev`. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + IOV_MAX = libc::_SC_IOV_MAX, + /// Unless otherwise noted, the maximum length, in bytes, of a utility's + /// input line (either standard input or another file), when the utility is + /// described as processing text files. The length includes room for the + /// trailing newline. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + LINE_MAX = libc::_SC_LINE_MAX, + /// Maximum length of a login name. + #[cfg(not(target_os = "haiku"))] + LOGIN_NAME_MAX = libc::_SC_LOGIN_NAME_MAX, + /// Maximum number of simultaneous supplementary group IDs per process. + NGROUPS_MAX = libc::_SC_NGROUPS_MAX, + /// Initial size of `getgrgid_r` and `getgrnam_r` data buffers + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + GETGR_R_SIZE_MAX = libc::_SC_GETGR_R_SIZE_MAX, + /// Initial size of `getpwuid_r` and `getpwnam_r` data buffers + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + GETPW_R_SIZE_MAX = libc::_SC_GETPW_R_SIZE_MAX, + /// The maximum number of open message queue descriptors a process may hold. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MQ_OPEN_MAX = libc::_SC_MQ_OPEN_MAX, + /// The maximum number of message priorities supported by the implementation. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + MQ_PRIO_MAX = libc::_SC_MQ_PRIO_MAX, + /// A value one greater than the maximum value that the system may assign to + /// a newly-created file descriptor. + OPEN_MAX = libc::_SC_OPEN_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Advisory Information option. + _POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports barriers. + _POSIX_BARRIERS = libc::_SC_BARRIERS, + /// The implementation supports asynchronous input and output. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports clock selection. + _POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Process CPU-Time Clocks option. + _POSIX_CPUTIME = libc::_SC_CPUTIME, + /// The implementation supports the File Synchronization option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_FSYNC = libc::_SC_FSYNC, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the IPv6 option. + _POSIX_IPV6 = libc::_SC_IPV6, + /// The implementation supports job control. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_JOB_CONTROL = libc::_SC_JOB_CONTROL, + /// The implementation supports memory mapped Files. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MAPPED_FILES = libc::_SC_MAPPED_FILES, + /// The implementation supports the Process Memory Locking option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MEMLOCK = libc::_SC_MEMLOCK, + /// The implementation supports the Range Memory Locking option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MEMLOCK_RANGE = libc::_SC_MEMLOCK_RANGE, + /// The implementation supports memory protection. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MEMORY_PROTECTION = libc::_SC_MEMORY_PROTECTION, + /// The implementation supports the Message Passing option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MESSAGE_PASSING = libc::_SC_MESSAGE_PASSING, + /// The implementation supports the Monotonic Clock option. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "illumos", target_os = "ios", target_os="linux", + target_os = "macos", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Prioritized Input and Output option. + _POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO, + /// The implementation supports the Process Scheduling option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Raw Sockets option. + _POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports read-write locks. + _POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS, + #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports realtime signals. + _POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Regular Expression Handling option. + _POSIX_REGEXP = libc::_SC_REGEXP, + /// Each process has a saved set-user-ID and a saved set-group-ID. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SAVED_IDS = libc::_SC_SAVED_IDS, + /// The implementation supports semaphores. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SEMAPHORES = libc::_SC_SEMAPHORES, + /// The implementation supports the Shared Memory Objects option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the POSIX shell. + _POSIX_SHELL = libc::_SC_SHELL, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Spawn option. + _POSIX_SPAWN = libc::_SC_SPAWN, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports spin locks. + _POSIX_SPIN_LOCKS = libc::_SC_SPIN_LOCKS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Process Sporadic Server option. + _POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX, + /// The implementation supports the Synchronized Input and Output option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SYNCHRONIZED_IO = libc::_SC_SYNCHRONIZED_IO, + /// The implementation supports the Thread Stack Address Attribute option. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_ATTR_STACKADDR = libc::_SC_THREAD_ATTR_STACKADDR, + /// The implementation supports the Thread Stack Size Attribute option. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Thread CPU-Time Clocks option. + _POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME, + /// The implementation supports the Non-Robust Mutex Priority Inheritance + /// option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_PRIO_INHERIT = libc::_SC_THREAD_PRIO_INHERIT, + /// The implementation supports the Non-Robust Mutex Priority Protection option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_PRIO_PROTECT = libc::_SC_THREAD_PRIO_PROTECT, + /// The implementation supports the Thread Execution Scheduling option. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Thread Process-Shared Synchronization + /// option. + _POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED, + #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Robust Mutex Priority Inheritance option. + _POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT, + #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Robust Mutex Priority Protection option. + _POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT, + /// The implementation supports thread-safe functions. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Thread Sporadic Server option. + _POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER, + /// The implementation supports threads. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREADS = libc::_SC_THREADS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports timeouts. + _POSIX_TIMEOUTS = libc::_SC_TIMEOUTS, + /// The implementation supports timers. + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TIMERS = libc::_SC_TIMERS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace option. + _POSIX_TRACE = libc::_SC_TRACE, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace Event Filter option. + _POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_EVENT_NAME_MAX = libc::_SC_TRACE_EVENT_NAME_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace Inherit option. + _POSIX_TRACE_INHERIT = libc::_SC_TRACE_INHERIT, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace Log option. + _POSIX_TRACE_LOG = libc::_SC_TRACE_LOG, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_USER_EVENT_MAX = libc::_SC_TRACE_USER_EVENT_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Typed Memory Objects option. + _POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS, + /// Integer value indicating version of this standard (C-language binding) + /// to which the implementation conforms. For implementations conforming to + /// POSIX.1-2008, the value shall be 200809L. + _POSIX_VERSION = libc::_SC_VERSION, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with + /// 32-bit `int`, `long`, `pointer`, and `off_t` types. + _POSIX_V6_ILP32_OFF32 = libc::_SC_V6_ILP32_OFF32, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with + /// 32-bit `int`, `long`, and pointer types and an `off_t` type using at + /// least 64 bits. + _POSIX_V6_ILP32_OFFBIG = libc::_SC_V6_ILP32_OFFBIG, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with + /// 32-bit `int` and 64-bit `long`, `pointer`, and `off_t` types. + _POSIX_V6_LP64_OFF64 = libc::_SC_V6_LP64_OFF64, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with an + /// `int` type using at least 32 bits and `long`, pointer, and `off_t` types + /// using at least 64 bits. + _POSIX_V6_LPBIG_OFFBIG = libc::_SC_V6_LPBIG_OFFBIG, + /// The implementation supports the C-Language Binding option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_C_BIND = libc::_SC_2_C_BIND, + /// The implementation supports the C-Language Development Utilities option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_C_DEV = libc::_SC_2_C_DEV, + /// The implementation supports the Terminal Characteristics option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_CHAR_TERM = libc::_SC_2_CHAR_TERM, + /// The implementation supports the FORTRAN Development Utilities option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_FORT_DEV = libc::_SC_2_FORT_DEV, + /// The implementation supports the FORTRAN Runtime Utilities option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_FORT_RUN = libc::_SC_2_FORT_RUN, + /// The implementation supports the creation of locales by the localedef + /// utility. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Environment Services and Utilities + /// option. + _POSIX2_PBS = libc::_SC_2_PBS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Accounting option. + _POSIX2_PBS_ACCOUNTING = libc::_SC_2_PBS_ACCOUNTING, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Checkpoint/Restart option. + _POSIX2_PBS_CHECKPOINT = libc::_SC_2_PBS_CHECKPOINT, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Locate Batch Job Request option. + _POSIX2_PBS_LOCATE = libc::_SC_2_PBS_LOCATE, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Job Message Request option. + _POSIX2_PBS_MESSAGE = libc::_SC_2_PBS_MESSAGE, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Track Batch Job Request option. + _POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK, + /// The implementation supports the Software Development Utilities option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_SW_DEV = libc::_SC_2_SW_DEV, + /// The implementation supports the User Portability Utilities option. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_UPE = libc::_SC_2_UPE, + /// Integer value indicating version of the Shell and Utilities volume of + /// POSIX.1 to which the implementation conforms. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_VERSION = libc::_SC_2_VERSION, + /// The size of a system page in bytes. + /// + /// POSIX also defines an alias named `PAGESIZE`, but Rust does not allow two + /// enum constants to have the same value, so nix omits `PAGESIZE`. + PAGE_SIZE = libc::_SC_PAGE_SIZE, + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_DESTRUCTOR_ITERATIONS = libc::_SC_THREAD_DESTRUCTOR_ITERATIONS, + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_KEYS_MAX = libc::_SC_THREAD_KEYS_MAX, + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_STACK_MIN = libc::_SC_THREAD_STACK_MIN, + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX, + #[cfg(not(target_os = "haiku"))] + RE_DUP_MAX = libc::_SC_RE_DUP_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + RTSIG_MAX = libc::_SC_RTSIG_MAX, + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SEM_VALUE_MAX = libc::_SC_SEM_VALUE_MAX, + #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os = "openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SIGQUEUE_MAX = libc::_SC_SIGQUEUE_MAX, + STREAM_MAX = libc::_SC_STREAM_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX, + #[cfg(not(target_os = "redox"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + TIMER_MAX = libc::_SC_TIMER_MAX, + TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX, + TZNAME_MAX = libc::_SC_TZNAME_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the X/Open Encryption Option Group. + _XOPEN_CRYPT = libc::_SC_XOPEN_CRYPT, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Issue 4, Version 2 Enhanced + /// Internationalization Option Group. + _XOPEN_ENH_I18N = libc::_SC_XOPEN_ENH_I18N, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _XOPEN_LEGACY = libc::_SC_XOPEN_LEGACY, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the X/Open Realtime Option Group. + _XOPEN_REALTIME = libc::_SC_XOPEN_REALTIME, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the X/Open Realtime Threads Option Group. + _XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS, + /// The implementation supports the Issue 4, Version 2 Shared Memory Option + /// Group. + #[cfg(not(any(target_os = "redox", target_os = "haiku")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + _XOPEN_SHM = libc::_SC_XOPEN_SHM, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the XSI STREAMS Option Group. + _XOPEN_STREAMS = libc::_SC_XOPEN_STREAMS, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the XSI option + _XOPEN_UNIX = libc::_SC_XOPEN_UNIX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] + #[cfg_attr(docsrs, doc(cfg(all())))] + /// Integer value indicating version of the X/Open Portability Guide to + /// which the implementation conforms. + _XOPEN_VERSION = libc::_SC_XOPEN_VERSION, + /// The number of pages of physical memory. Note that it is possible for + /// the product of this value to overflow. + #[cfg(any(target_os="android", target_os="linux"))] + _PHYS_PAGES = libc::_SC_PHYS_PAGES, + /// The number of currently available pages of physical memory. + #[cfg(any(target_os="android", target_os="linux"))] + _AVPHYS_PAGES = libc::_SC_AVPHYS_PAGES, + /// The number of processors configured. + #[cfg(any(target_os="android", target_os="linux"))] + _NPROCESSORS_CONF = libc::_SC_NPROCESSORS_CONF, + /// The number of processors currently online (available). + #[cfg(any(target_os="android", target_os="linux"))] + _NPROCESSORS_ONLN = libc::_SC_NPROCESSORS_ONLN, +} + +/// Get configurable system variables (see +/// [sysconf(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html)) +/// +/// Returns the value of a configurable system variable. Most supported +/// variables also have associated compile-time constants, but POSIX +/// allows their values to change at runtime. There are generally two types of +/// sysconf variables: options and limits. See sysconf(3) for more details. +/// +/// # Returns +/// +/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its +/// implementation level (for option variables). Implementation levels are +/// usually a decimal-coded date, such as 200112 for POSIX 2001.12 +/// - `Ok(None)`: the variable has no limit (for limit variables) or is +/// unsupported (for option variables) +/// - `Err(x)`: an error occurred +pub fn sysconf(var: SysconfVar) -> Result> { + let raw = unsafe { + Errno::clear(); + libc::sysconf(var as c_int) + }; + if raw == -1 { + if errno::errno() == 0 { + Ok(None) + } else { + Err(Errno::last()) + } + } else { + Ok(Some(raw)) + } +} +} + +feature! { +#![feature = "fs"] + +#[cfg(any(target_os = "android", target_os = "linux"))] +mod pivot_root { + use crate::{Result, NixPath}; + use crate::errno::Errno; + + pub fn pivot_root( + new_root: &P1, put_old: &P2) -> Result<()> { + let res = new_root.with_nix_path(|new_root| { + put_old.with_nix_path(|put_old| { + unsafe { + libc::syscall(libc::SYS_pivot_root, new_root.as_ptr(), put_old.as_ptr()) + } + }) + })??; + + Errno::result(res).map(drop) + } +} +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "openbsd" +))] +mod setres { + feature! { + #![feature = "user"] + + use crate::Result; + use crate::errno::Errno; + use super::{Uid, Gid}; + + /// Sets the real, effective, and saved uid. + /// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html)) + /// + /// * `ruid`: real user id + /// * `euid`: effective user id + /// * `suid`: saved user id + /// * returns: Ok or libc error code. + /// + /// Err is returned if the user doesn't have permission to set this UID. + #[inline] + pub fn setresuid(ruid: Uid, euid: Uid, suid: Uid) -> Result<()> { + let res = unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) }; + + Errno::result(res).map(drop) + } + + /// Sets the real, effective, and saved gid. + /// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html)) + /// + /// * `rgid`: real group id + /// * `egid`: effective group id + /// * `sgid`: saved group id + /// * returns: Ok or libc error code. + /// + /// Err is returned if the user doesn't have permission to set this GID. + #[inline] + pub fn setresgid(rgid: Gid, egid: Gid, sgid: Gid) -> Result<()> { + let res = unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) }; + + Errno::result(res).map(drop) + } + } +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "openbsd" +))] +mod getres { + feature! { + #![feature = "user"] + + use crate::Result; + use crate::errno::Errno; + use super::{Uid, Gid}; + + /// Real, effective and saved user IDs. + #[derive(Debug, Copy, Clone, Eq, PartialEq)] + pub struct ResUid { + pub real: Uid, + pub effective: Uid, + pub saved: Uid + } + + /// Real, effective and saved group IDs. + #[derive(Debug, Copy, Clone, Eq, PartialEq)] + pub struct ResGid { + pub real: Gid, + pub effective: Gid, + pub saved: Gid + } + + /// Gets the real, effective, and saved user IDs. + /// + /// ([see getresuid(2)](http://man7.org/linux/man-pages/man2/getresuid.2.html)) + /// + /// #Returns + /// + /// - `Ok((Uid, Uid, Uid))`: tuple of real, effective and saved uids on success. + /// - `Err(x)`: libc error code on failure. + /// + #[inline] + pub fn getresuid() -> Result { + let mut ruid = libc::uid_t::max_value(); + let mut euid = libc::uid_t::max_value(); + let mut suid = libc::uid_t::max_value(); + let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) }; + + Errno::result(res).map(|_| ResUid{ real: Uid(ruid), effective: Uid(euid), saved: Uid(suid) }) + } + + /// Gets the real, effective, and saved group IDs. + /// + /// ([see getresgid(2)](http://man7.org/linux/man-pages/man2/getresgid.2.html)) + /// + /// #Returns + /// + /// - `Ok((Gid, Gid, Gid))`: tuple of real, effective and saved gids on success. + /// - `Err(x)`: libc error code on failure. + /// + #[inline] + pub fn getresgid() -> Result { + let mut rgid = libc::gid_t::max_value(); + let mut egid = libc::gid_t::max_value(); + let mut sgid = libc::gid_t::max_value(); + let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) }; + + Errno::result(res).map(|_| ResGid { real: Gid(rgid), effective: Gid(egid), saved: Gid(sgid) } ) + } + } +} + +#[cfg(feature = "fs")] +libc_bitflags! { + /// Options for access() + #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct AccessFlags : c_int { + /// Test for existence of file. + F_OK; + /// Test for read permission. + R_OK; + /// Test for write permission. + W_OK; + /// Test for execute (search) permission. + X_OK; + } +} + +feature! { +#![feature = "fs"] + +/// Checks the file named by `path` for accessibility according to the flags given by `amode` +/// See [access(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html) +pub fn access(path: &P, amode: AccessFlags) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { + libc::access(cstr.as_ptr(), amode.bits) + } + })?; + Errno::result(res).map(drop) +} + +/// Checks the file named by `path` for accessibility according to the flags given by `mode` +/// +/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor. +/// +/// If `dirfd` is `None`, then `path` is relative to the current working directory. +/// +/// # References +/// +/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html) +// illumos: faccessat(2) appears to be supported, but the libc crate does not provide a binding. +// redox: does not appear to support the *at family of syscalls. +#[cfg(not(any(target_os = "illumos", target_os = "redox")))] +pub fn faccessat(dirfd: Option, path: &P, mode: AccessFlags, flags: AtFlags) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { + libc::faccessat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits(), flags.bits()) + } + })?; + Errno::result(res).map(drop) +} +} + +feature! { +#![feature = "user"] + +/// Representation of a User, based on `libc::passwd` +/// +/// The reason some fields in this struct are `String` and others are `CString` is because some +/// fields are based on the user's locale, which could be non-UTF8, while other fields are +/// guaranteed to conform to [`NAME_REGEX`](https://serverfault.com/a/73101/407341), which only +/// contains ASCII. +#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct User { + /// Username + pub name: String, + /// User password (probably hashed) + pub passwd: CString, + /// User ID + pub uid: Uid, + /// Group ID + pub gid: Gid, + /// User information + #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] + pub gecos: CString, + /// Home directory + pub dir: PathBuf, + /// Path to shell + pub shell: PathBuf, + /// Login class + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub class: CString, + /// Last password change + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub change: libc::time_t, + /// Expiration time of account + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + #[cfg_attr(docsrs, doc(cfg(all())))] + pub expire: libc::time_t +} + +#[cfg(not(target_os = "redox"))] //RedoxFS does not support passwd +impl From<&libc::passwd> for User { + fn from(pw: &libc::passwd) -> User { + unsafe { + User { + name: if pw.pw_name.is_null() { Default::default() } else { CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned() }, + passwd: if pw.pw_passwd.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes()).unwrap() }, + #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] + gecos: if pw.pw_gecos.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes()).unwrap() }, + dir: if pw.pw_dir.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_dir).to_bytes())) }, + shell: if pw.pw_shell.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_shell).to_bytes())) }, + uid: Uid::from_raw(pw.pw_uid), + gid: Gid::from_raw(pw.pw_gid), + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes()).unwrap(), + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + change: pw.pw_change, + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + expire: pw.pw_expire + } + } + } +} + +#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd +impl From for libc::passwd { + fn from(u: User) -> Self { + let name = match CString::new(u.name) { + Ok(n) => n.into_raw(), + Err(_) => CString::new("").unwrap().into_raw(), + }; + let dir = match u.dir.into_os_string().into_string() { + Ok(s) => CString::new(s.as_str()).unwrap().into_raw(), + Err(_) => CString::new("").unwrap().into_raw(), + }; + let shell = match u.shell.into_os_string().into_string() { + Ok(s) => CString::new(s.as_str()).unwrap().into_raw(), + Err(_) => CString::new("").unwrap().into_raw(), + }; + Self { + pw_name: name, + pw_passwd: u.passwd.into_raw(), + #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] + pw_gecos: u.gecos.into_raw(), + pw_dir: dir, + pw_shell: shell, + pw_uid: u.uid.0, + pw_gid: u.gid.0, + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + pw_class: u.class.into_raw(), + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + pw_change: u.change, + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] + pw_expire: u.expire, + #[cfg(target_os = "illumos")] + pw_age: CString::new("").unwrap().into_raw(), + #[cfg(target_os = "illumos")] + pw_comment: CString::new("").unwrap().into_raw(), + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + pw_fields: 0, + } + } +} + +#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd +impl User { + fn from_anything(f: F) -> Result> + where + F: Fn(*mut libc::passwd, + *mut c_char, + libc::size_t, + *mut *mut libc::passwd) -> libc::c_int + { + let buflimit = 1048576; + let bufsize = match sysconf(SysconfVar::GETPW_R_SIZE_MAX) { + Ok(Some(n)) => n as usize, + Ok(None) | Err(_) => 16384, + }; + + let mut cbuf = Vec::with_capacity(bufsize); + let mut pwd = mem::MaybeUninit::::uninit(); + let mut res = ptr::null_mut(); + + loop { + let error = f(pwd.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res); + if error == 0 { + if res.is_null() { + return Ok(None); + } else { + let pwd = unsafe { pwd.assume_init() }; + return Ok(Some(User::from(&pwd))); + } + } else if Errno::last() == Errno::ERANGE { + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut cbuf, buflimit)?; + } else { + return Err(Errno::last()); + } + } + } + + /// Get a user by UID. + /// + /// Internally, this function calls + /// [getpwuid_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// + /// ``` + /// use nix::unistd::{Uid, User}; + /// // Returns an Result>, thus the double unwrap. + /// let res = User::from_uid(Uid::from_raw(0)).unwrap().unwrap(); + /// assert_eq!(res.name, "root"); + /// ``` + pub fn from_uid(uid: Uid) -> Result> { + User::from_anything(|pwd, cbuf, cap, res| { + unsafe { libc::getpwuid_r(uid.0, pwd, cbuf, cap, res) } + }) + } + + /// Get a user by name. + /// + /// Internally, this function calls + /// [getpwnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// + /// ``` + /// use nix::unistd::User; + /// // Returns an Result>, thus the double unwrap. + /// let res = User::from_name("root").unwrap().unwrap(); + /// assert_eq!(res.name, "root"); + /// ``` + pub fn from_name(name: &str) -> Result> { + let name = match CString::new(name) { + Ok(c_str) => c_str, + Err(_nul_error) => return Ok(None), + }; + User::from_anything(|pwd, cbuf, cap, res| { + unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) } + }) + } +} + +/// Representation of a Group, based on `libc::group` +#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Group { + /// Group name + pub name: String, + /// Group password + pub passwd: CString, + /// Group ID + pub gid: Gid, + /// List of Group members + pub mem: Vec +} + +#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd +impl From<&libc::group> for Group { + fn from(gr: &libc::group) -> Group { + unsafe { + Group { + name: CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned(), + passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes()).unwrap(), + gid: Gid::from_raw(gr.gr_gid), + mem: Group::members(gr.gr_mem) + } + } + } +} + +#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd +impl Group { + unsafe fn members(mem: *mut *mut c_char) -> Vec { + let mut ret = Vec::new(); + + for i in 0.. { + let u = mem.offset(i); + if (*u).is_null() { + break; + } else { + let s = CStr::from_ptr(*u).to_string_lossy().into_owned(); + ret.push(s); + } + } + + ret + } + + fn from_anything(f: F) -> Result> + where + F: Fn(*mut libc::group, + *mut c_char, + libc::size_t, + *mut *mut libc::group) -> libc::c_int + { + let buflimit = 1048576; + let bufsize = match sysconf(SysconfVar::GETGR_R_SIZE_MAX) { + Ok(Some(n)) => n as usize, + Ok(None) | Err(_) => 16384, + }; + + let mut cbuf = Vec::with_capacity(bufsize); + let mut grp = mem::MaybeUninit::::uninit(); + let mut res = ptr::null_mut(); + + loop { + let error = f(grp.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res); + if error == 0 { + if res.is_null() { + return Ok(None); + } else { + let grp = unsafe { grp.assume_init() }; + return Ok(Some(Group::from(&grp))); + } + } else if Errno::last() == Errno::ERANGE { + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut cbuf, buflimit)?; + } else { + return Err(Errno::last()); + } + } + } + + /// Get a group by GID. + /// + /// Internally, this function calls + /// [getgrgid_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// + // Disable this test on all OS except Linux as root group may not exist. + #[cfg_attr(not(target_os = "linux"), doc = " ```no_run")] + #[cfg_attr(target_os = "linux", doc = " ```")] + /// use nix::unistd::{Gid, Group}; + /// // Returns an Result>, thus the double unwrap. + /// let res = Group::from_gid(Gid::from_raw(0)).unwrap().unwrap(); + /// assert!(res.name == "root"); + /// ``` + pub fn from_gid(gid: Gid) -> Result> { + Group::from_anything(|grp, cbuf, cap, res| { + unsafe { libc::getgrgid_r(gid.0, grp, cbuf, cap, res) } + }) + } + + /// Get a group by name. + /// + /// Internally, this function calls + /// [getgrnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// + // Disable this test on all OS except Linux as root group may not exist. + #[cfg_attr(not(target_os = "linux"), doc = " ```no_run")] + #[cfg_attr(target_os = "linux", doc = " ```")] + /// use nix::unistd::Group; + /// // Returns an Result>, thus the double unwrap. + /// let res = Group::from_name("root").unwrap().unwrap(); + /// assert!(res.name == "root"); + /// ``` + pub fn from_name(name: &str) -> Result> { + let name = match CString::new(name) { + Ok(c_str) => c_str, + Err(_nul_error) => return Ok(None), + }; + Group::from_anything(|grp, cbuf, cap, res| { + unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) } + }) + } +} +} + +feature! { +#![feature = "term"] + +/// Get the name of the terminal device that is open on file descriptor fd +/// (see [`ttyname(3)`](https://man7.org/linux/man-pages/man3/ttyname.3.html)). +#[cfg(not(target_os = "fuchsia"))] +pub fn ttyname(fd: RawFd) -> Result { + const PATH_MAX: usize = libc::PATH_MAX as usize; + let mut buf = vec![0_u8; PATH_MAX]; + let c_buf = buf.as_mut_ptr() as *mut libc::c_char; + + let ret = unsafe { libc::ttyname_r(fd, c_buf, buf.len()) }; + if ret != 0 { + return Err(Errno::from_i32(ret)); + } + + let nul = buf.iter().position(|c| *c == b'\0').unwrap(); + buf.truncate(nul); + Ok(OsString::from_vec(buf).into()) +} +} + +feature! { +#![all(feature = "socket", feature = "user")] + +/// Get the effective user ID and group ID associated with a Unix domain socket. +/// +/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid) +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", +))] +pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> { + let mut uid = 1; + let mut gid = 1; + + let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) }; + + Errno::result(ret).map(|_| (Uid(uid), Gid(gid))) +} +} + +feature! { +#![all(feature = "fs")] + +/// Set the file flags. +/// +/// See also [chflags(2)](https://www.freebsd.org/cgi/man.cgi?query=chflags&sektion=2) +#[cfg(any( + target_os = "openbsd", + target_os = "netbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "macos", + target_os = "ios" +))] +pub fn chflags(path: &P, flags: FileFlag) -> Result<()> { + let res = path.with_nix_path(|cstr| unsafe { + libc::chflags(cstr.as_ptr(), flags.bits()) + })?; + + Errno::result(res).map(drop) +} +} diff --git a/utshell-0.5.0/vendor/nix/test/common/mod.rs b/utshell-0.5.0/vendor/nix/test/common/mod.rs new file mode 100644 index 00000000..bb056aab --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/common/mod.rs @@ -0,0 +1,149 @@ +use cfg_if::cfg_if; + +#[macro_export] +macro_rules! skip { + ($($reason: expr),+) => { + use ::std::io::{self, Write}; + + let stderr = io::stderr(); + let mut handle = stderr.lock(); + writeln!(handle, $($reason),+).unwrap(); + return; + } +} + +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + #[macro_export] macro_rules! require_capability { + ($name:expr, $capname:ident) => { + use ::caps::{Capability, CapSet, has_cap}; + + if !has_cap(None, CapSet::Effective, Capability::$capname) + .unwrap() + { + skip!("{} requires capability {}. Skipping test.", $name, Capability::$capname); + } + } + } + } else if #[cfg(not(target_os = "redox"))] { + #[macro_export] macro_rules! require_capability { + ($name:expr, $capname:ident) => {} + } + } +} + +/// Skip the test if we don't have the ability to mount file systems. +#[cfg(target_os = "freebsd")] +#[macro_export] +macro_rules! require_mount { + ($name:expr) => { + use ::sysctl::{CtlValue, Sysctl}; + use nix::unistd::Uid; + + let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap(); + if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap() + { + skip!( + "{} requires the ability to mount file systems. Skipping test.", + $name + ); + } + }; +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +#[macro_export] +macro_rules! skip_if_cirrus { + ($reason:expr) => { + if std::env::var_os("CIRRUS_CI").is_some() { + skip!("{}", $reason); + } + }; +} + +#[cfg(target_os = "freebsd")] +#[macro_export] +macro_rules! skip_if_jailed { + ($name:expr) => { + use ::sysctl::{CtlValue, Sysctl}; + + let ctl = ::sysctl::Ctl::new("security.jail.jailed").unwrap(); + if let CtlValue::Int(1) = ctl.value().unwrap() { + skip!("{} cannot run in a jail. Skipping test.", $name); + } + }; +} + +#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] +#[macro_export] +macro_rules! skip_if_not_root { + ($name:expr) => { + use nix::unistd::Uid; + + if !Uid::current().is_root() { + skip!("{} requires root privileges. Skipping test.", $name); + } + }; +} + +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + #[macro_export] macro_rules! skip_if_seccomp { + ($name:expr) => { + if let Ok(s) = std::fs::read_to_string("/proc/self/status") { + for l in s.lines() { + let mut fields = l.split_whitespace(); + if fields.next() == Some("Seccomp:") && + fields.next() != Some("0") + { + skip!("{} cannot be run in Seccomp mode. Skipping test.", + stringify!($name)); + } + } + } + } + } + } else if #[cfg(not(target_os = "redox"))] { + #[macro_export] macro_rules! skip_if_seccomp { + ($name:expr) => {} + } + } +} + +cfg_if! { + if #[cfg(target_os = "linux")] { + #[macro_export] macro_rules! require_kernel_version { + ($name:expr, $version_requirement:expr) => { + use semver::{Version, VersionReq}; + + let version_requirement = VersionReq::parse($version_requirement) + .expect("Bad match_version provided"); + + let uname = nix::sys::utsname::uname().unwrap(); + println!("{}", uname.sysname().to_str().unwrap()); + println!("{}", uname.nodename().to_str().unwrap()); + println!("{}", uname.release().to_str().unwrap()); + println!("{}", uname.version().to_str().unwrap()); + println!("{}", uname.machine().to_str().unwrap()); + + // Fix stuff that the semver parser can't handle + let fixed_release = &uname.release().to_str().unwrap().to_string() + // Fedora 33 reports version as 4.18.el8_2.x86_64 or + // 5.18.200-fc33.x86_64. Remove the underscore. + .replace("_", "-") + // Cirrus-CI reports version as 4.19.112+ . Remove the + + .replace("+", ""); + let mut version = Version::parse(fixed_release).unwrap(); + + //Keep only numeric parts + version.pre = semver::Prerelease::EMPTY; + version.build = semver::BuildMetadata::EMPTY; + + if !version_requirement.matches(&version) { + skip!("Skip {} because kernel version `{}` doesn't match the requirement `{}`", + stringify!($name), version, version_requirement); + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/mod.rs b/utshell-0.5.0/vendor/nix/test/sys/mod.rs new file mode 100644 index 00000000..20312120 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/mod.rs @@ -0,0 +1,60 @@ +mod test_signal; + +// NOTE: DragonFly lacks a kernel-level implementation of Posix AIO as of +// this writing. There is an user-level implementation, but whether aio +// works or not heavily depends on which pthread implementation is chosen +// by the user at link time. For this reason we do not want to run aio test +// cases on DragonFly. +#[cfg(any( + target_os = "freebsd", + target_os = "ios", + all(target_os = "linux", not(target_env = "uclibc")), + target_os = "macos", + target_os = "netbsd" +))] +mod test_aio; +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +mod test_ioctl; +#[cfg(not(target_os = "redox"))] +mod test_mman; +#[cfg(not(target_os = "redox"))] +mod test_select; +#[cfg(target_os = "linux")] +mod test_signalfd; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +mod test_socket; +#[cfg(not(any(target_os = "redox")))] +mod test_sockopt; +mod test_stat; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod test_sysinfo; +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +mod test_termios; +mod test_uio; +mod test_wait; + +#[cfg(any(target_os = "android", target_os = "linux"))] +mod test_epoll; +#[cfg(target_os = "linux")] +mod test_inotify; +mod test_pthread; +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd" +))] +mod test_ptrace; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod test_timerfd; diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_aio.rs b/utshell-0.5.0/vendor/nix/test/sys/test_aio.rs new file mode 100644 index 00000000..6a36f3e7 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_aio.rs @@ -0,0 +1,626 @@ +use std::{ + io::{Read, Seek, SeekFrom, Write}, + ops::Deref, + os::unix::io::AsRawFd, + pin::Pin, + sync::atomic::{AtomicBool, Ordering}, + thread, time, +}; + +use libc::c_int; +use nix::{ + errno::*, + sys::{ + aio::*, + signal::{ + sigaction, SaFlags, SigAction, SigHandler, SigSet, SigevNotify, + Signal, + }, + time::{TimeSpec, TimeValLike}, + }, +}; +use tempfile::tempfile; + +lazy_static! { + pub static ref SIGNALED: AtomicBool = AtomicBool::new(false); +} + +extern "C" fn sigfunc(_: c_int) { + SIGNALED.store(true, Ordering::Relaxed); +} + +// Helper that polls an AioCb for completion or error +macro_rules! poll_aio { + ($aiocb: expr) => { + loop { + let err = $aiocb.as_mut().error(); + if err != Err(Errno::EINPROGRESS) { + break err; + }; + thread::sleep(time::Duration::from_millis(10)); + } + }; +} + +mod aio_fsync { + use super::*; + + #[test] + fn test_accessors() { + let aiocb = AioFsync::new( + 1001, + AioFsyncMode::O_SYNC, + 42, + SigevNotify::SigevSignal { + signal: Signal::SIGUSR2, + si_value: 99, + }, + ); + assert_eq!(1001, aiocb.fd()); + assert_eq!(AioFsyncMode::O_SYNC, aiocb.mode()); + assert_eq!(42, aiocb.priority()); + let sev = aiocb.sigevent().sigevent(); + assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); + assert_eq!(99, sev.sigev_value.sival_ptr as i64); + } + + /// `AioFsync::submit` should not modify the `AioCb` object if + /// `libc::aio_fsync` returns an error + // Skip on Linux, because Linux's AIO implementation can't detect errors + // synchronously + #[test] + #[cfg(any(target_os = "freebsd", target_os = "macos"))] + fn error() { + use std::mem; + + const INITIAL: &[u8] = b"abcdef123456"; + // Create an invalid AioFsyncMode + let mode = unsafe { mem::transmute(666) }; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let mut aiof = Box::pin(AioFsync::new( + f.as_raw_fd(), + mode, + 0, + SigevNotify::SigevNone, + )); + let err = aiof.as_mut().submit(); + err.expect_err("assertion failed"); + } + + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn ok() { + const INITIAL: &[u8] = b"abcdef123456"; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let fd = f.as_raw_fd(); + let mut aiof = Box::pin(AioFsync::new( + fd, + AioFsyncMode::O_SYNC, + 0, + SigevNotify::SigevNone, + )); + aiof.as_mut().submit().unwrap(); + poll_aio!(&mut aiof).unwrap(); + aiof.as_mut().aio_return().unwrap(); + } +} + +mod aio_read { + use super::*; + + #[test] + fn test_accessors() { + let mut rbuf = vec![0; 4]; + let aiocb = AioRead::new( + 1001, + 2, //offset + &mut rbuf, + 42, //priority + SigevNotify::SigevSignal { + signal: Signal::SIGUSR2, + si_value: 99, + }, + ); + assert_eq!(1001, aiocb.fd()); + assert_eq!(4, aiocb.nbytes()); + assert_eq!(2, aiocb.offset()); + assert_eq!(42, aiocb.priority()); + let sev = aiocb.sigevent().sigevent(); + assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); + assert_eq!(99, sev.sigev_value.sival_ptr as i64); + } + + // Tests AioWrite.cancel. We aren't trying to test the OS's implementation, + // only our bindings. So it's sufficient to check that cancel + // returned any AioCancelStat value. + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn cancel() { + const INITIAL: &[u8] = b"abcdef123456"; + let mut rbuf = vec![0; 4]; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let fd = f.as_raw_fd(); + let mut aior = + Box::pin(AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone)); + aior.as_mut().submit().unwrap(); + + aior.as_mut().cancel().unwrap(); + + // Wait for aiow to complete, but don't care whether it succeeded + let _ = poll_aio!(&mut aior); + let _ = aior.as_mut().aio_return(); + } + + /// `AioRead::submit` should not modify the `AioCb` object if + /// `libc::aio_read` returns an error + // Skip on Linux, because Linux's AIO implementation can't detect errors + // synchronously + #[test] + #[cfg(any(target_os = "freebsd", target_os = "macos"))] + fn error() { + const INITIAL: &[u8] = b"abcdef123456"; + let mut rbuf = vec![0; 4]; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let mut aior = Box::pin(AioRead::new( + f.as_raw_fd(), + -1, //an invalid offset + &mut rbuf, + 0, //priority + SigevNotify::SigevNone, + )); + aior.as_mut().submit().expect_err("assertion failed"); + } + + // Test a simple aio operation with no completion notification. We must + // poll for completion + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn ok() { + const INITIAL: &[u8] = b"abcdef123456"; + let mut rbuf = vec![0; 4]; + const EXPECT: &[u8] = b"cdef"; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + { + let fd = f.as_raw_fd(); + let mut aior = Box::pin(AioRead::new( + fd, + 2, + &mut rbuf, + 0, + SigevNotify::SigevNone, + )); + aior.as_mut().submit().unwrap(); + + let err = poll_aio!(&mut aior); + assert_eq!(err, Ok(())); + assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len()); + } + assert_eq!(EXPECT, rbuf.deref().deref()); + } + + // Like ok, but allocates the structure on the stack. + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn on_stack() { + const INITIAL: &[u8] = b"abcdef123456"; + let mut rbuf = vec![0; 4]; + const EXPECT: &[u8] = b"cdef"; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + { + let fd = f.as_raw_fd(); + let mut aior = + AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone); + let mut aior = unsafe { Pin::new_unchecked(&mut aior) }; + aior.as_mut().submit().unwrap(); + + let err = poll_aio!(&mut aior); + assert_eq!(err, Ok(())); + assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len()); + } + assert_eq!(EXPECT, rbuf.deref().deref()); + } +} + +#[cfg(target_os = "freebsd")] +#[cfg(fbsd14)] +mod aio_readv { + use std::io::IoSliceMut; + + use super::*; + + #[test] + fn test_accessors() { + let mut rbuf0 = vec![0; 4]; + let mut rbuf1 = vec![0; 8]; + let mut rbufs = + [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)]; + let aiocb = AioReadv::new( + 1001, + 2, //offset + &mut rbufs, + 42, //priority + SigevNotify::SigevSignal { + signal: Signal::SIGUSR2, + si_value: 99, + }, + ); + assert_eq!(1001, aiocb.fd()); + assert_eq!(2, aiocb.iovlen()); + assert_eq!(2, aiocb.offset()); + assert_eq!(42, aiocb.priority()); + let sev = aiocb.sigevent().sigevent(); + assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); + assert_eq!(99, sev.sigev_value.sival_ptr as i64); + } + + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn ok() { + const INITIAL: &[u8] = b"abcdef123456"; + let mut rbuf0 = vec![0; 4]; + let mut rbuf1 = vec![0; 2]; + let mut rbufs = + [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)]; + const EXPECT0: &[u8] = b"cdef"; + const EXPECT1: &[u8] = b"12"; + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + { + let fd = f.as_raw_fd(); + let mut aior = Box::pin(AioReadv::new( + fd, + 2, + &mut rbufs, + 0, + SigevNotify::SigevNone, + )); + aior.as_mut().submit().unwrap(); + + let err = poll_aio!(&mut aior); + assert_eq!(err, Ok(())); + assert_eq!( + aior.as_mut().aio_return().unwrap(), + EXPECT0.len() + EXPECT1.len() + ); + } + assert_eq!(&EXPECT0, &rbuf0); + assert_eq!(&EXPECT1, &rbuf1); + } +} + +mod aio_write { + use super::*; + + #[test] + fn test_accessors() { + let wbuf = vec![0; 4]; + let aiocb = AioWrite::new( + 1001, + 2, //offset + &wbuf, + 42, //priority + SigevNotify::SigevSignal { + signal: Signal::SIGUSR2, + si_value: 99, + }, + ); + assert_eq!(1001, aiocb.fd()); + assert_eq!(4, aiocb.nbytes()); + assert_eq!(2, aiocb.offset()); + assert_eq!(42, aiocb.priority()); + let sev = aiocb.sigevent().sigevent(); + assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); + assert_eq!(99, sev.sigev_value.sival_ptr as i64); + } + + // Tests AioWrite.cancel. We aren't trying to test the OS's implementation, + // only our bindings. So it's sufficient to check that cancel + // returned any AioCancelStat value. + #[test] + #[cfg_attr(target_env = "musl", ignore)] + fn cancel() { + let wbuf: &[u8] = b"CDEF"; + + let f = tempfile().unwrap(); + let mut aiow = Box::pin(AioWrite::new( + f.as_raw_fd(), + 0, + wbuf, + 0, + SigevNotify::SigevNone, + )); + aiow.as_mut().submit().unwrap(); + let err = aiow.as_mut().error(); + assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS)); + + aiow.as_mut().cancel().unwrap(); + + // Wait for aiow to complete, but don't care whether it succeeded + let _ = poll_aio!(&mut aiow); + let _ = aiow.as_mut().aio_return(); + } + + // Test a simple aio operation with no completion notification. We must + // poll for completion. + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn ok() { + const INITIAL: &[u8] = b"abcdef123456"; + let wbuf = "CDEF".to_string().into_bytes(); + let mut rbuf = Vec::new(); + const EXPECT: &[u8] = b"abCDEF123456"; + + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let mut aiow = Box::pin(AioWrite::new( + f.as_raw_fd(), + 2, + &wbuf, + 0, + SigevNotify::SigevNone, + )); + aiow.as_mut().submit().unwrap(); + + let err = poll_aio!(&mut aiow); + assert_eq!(err, Ok(())); + assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len()); + + f.seek(SeekFrom::Start(0)).unwrap(); + let len = f.read_to_end(&mut rbuf).unwrap(); + assert_eq!(len, EXPECT.len()); + assert_eq!(rbuf, EXPECT); + } + + // Like ok, but allocates the structure on the stack. + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn on_stack() { + const INITIAL: &[u8] = b"abcdef123456"; + let wbuf = "CDEF".to_string().into_bytes(); + let mut rbuf = Vec::new(); + const EXPECT: &[u8] = b"abCDEF123456"; + + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let mut aiow = AioWrite::new( + f.as_raw_fd(), + 2, //offset + &wbuf, + 0, //priority + SigevNotify::SigevNone, + ); + let mut aiow = unsafe { Pin::new_unchecked(&mut aiow) }; + aiow.as_mut().submit().unwrap(); + + let err = poll_aio!(&mut aiow); + assert_eq!(err, Ok(())); + assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len()); + + f.seek(SeekFrom::Start(0)).unwrap(); + let len = f.read_to_end(&mut rbuf).unwrap(); + assert_eq!(len, EXPECT.len()); + assert_eq!(rbuf, EXPECT); + } + + /// `AioWrite::write` should not modify the `AioCb` object if + /// `libc::aio_write` returns an error. + // Skip on Linux, because Linux's AIO implementation can't detect errors + // synchronously + #[test] + #[cfg(any(target_os = "freebsd", target_os = "macos"))] + fn error() { + let wbuf = "CDEF".to_string().into_bytes(); + let mut aiow = Box::pin(AioWrite::new( + 666, // An invalid file descriptor + 0, //offset + &wbuf, + 0, //priority + SigevNotify::SigevNone, + )); + aiow.as_mut().submit().expect_err("assertion failed"); + // Dropping the AioWrite at this point should not panic + } +} + +#[cfg(target_os = "freebsd")] +#[cfg(fbsd14)] +mod aio_writev { + use std::io::IoSlice; + + use super::*; + + #[test] + fn test_accessors() { + let wbuf0 = vec![0; 4]; + let wbuf1 = vec![0; 8]; + let wbufs = [IoSlice::new(&wbuf0), IoSlice::new(&wbuf1)]; + let aiocb = AioWritev::new( + 1001, + 2, //offset + &wbufs, + 42, //priority + SigevNotify::SigevSignal { + signal: Signal::SIGUSR2, + si_value: 99, + }, + ); + assert_eq!(1001, aiocb.fd()); + assert_eq!(2, aiocb.iovlen()); + assert_eq!(2, aiocb.offset()); + assert_eq!(42, aiocb.priority()); + let sev = aiocb.sigevent().sigevent(); + assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); + assert_eq!(99, sev.sigev_value.sival_ptr as i64); + } + + // Test a simple aio operation with no completion notification. We must + // poll for completion. + #[test] + #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] + fn ok() { + const INITIAL: &[u8] = b"abcdef123456"; + let wbuf0 = b"BC"; + let wbuf1 = b"DEF"; + let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)]; + let wlen = wbuf0.len() + wbuf1.len(); + let mut rbuf = Vec::new(); + const EXPECT: &[u8] = b"aBCDEF123456"; + + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let mut aiow = Box::pin(AioWritev::new( + f.as_raw_fd(), + 1, + &wbufs, + 0, + SigevNotify::SigevNone, + )); + aiow.as_mut().submit().unwrap(); + + let err = poll_aio!(&mut aiow); + assert_eq!(err, Ok(())); + assert_eq!(aiow.as_mut().aio_return().unwrap(), wlen); + + f.seek(SeekFrom::Start(0)).unwrap(); + let len = f.read_to_end(&mut rbuf).unwrap(); + assert_eq!(len, EXPECT.len()); + assert_eq!(rbuf, EXPECT); + } +} + +// Test an aio operation with completion delivered by a signal +#[test] +#[cfg_attr( + any( + all(target_env = "musl", target_arch = "x86_64"), + target_arch = "mips", + target_arch = "mips64" + ), + ignore +)] +fn sigev_signal() { + let _m = crate::SIGNAL_MTX.lock(); + let sa = SigAction::new( + SigHandler::Handler(sigfunc), + SaFlags::SA_RESETHAND, + SigSet::empty(), + ); + SIGNALED.store(false, Ordering::Relaxed); + unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); + + const INITIAL: &[u8] = b"abcdef123456"; + const WBUF: &[u8] = b"CDEF"; + let mut rbuf = Vec::new(); + const EXPECT: &[u8] = b"abCDEF123456"; + + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + let mut aiow = Box::pin(AioWrite::new( + f.as_raw_fd(), + 2, //offset + WBUF, + 0, //priority + SigevNotify::SigevSignal { + signal: Signal::SIGUSR2, + si_value: 0, //TODO: validate in sigfunc + }, + )); + aiow.as_mut().submit().unwrap(); + while !SIGNALED.load(Ordering::Relaxed) { + thread::sleep(time::Duration::from_millis(10)); + } + + assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); + f.seek(SeekFrom::Start(0)).unwrap(); + let len = f.read_to_end(&mut rbuf).unwrap(); + assert_eq!(len, EXPECT.len()); + assert_eq!(rbuf, EXPECT); +} + +// Tests using aio_cancel_all for all outstanding IOs. +#[test] +#[cfg_attr(target_env = "musl", ignore)] +fn test_aio_cancel_all() { + let wbuf: &[u8] = b"CDEF"; + + let f = tempfile().unwrap(); + let mut aiocb = Box::pin(AioWrite::new( + f.as_raw_fd(), + 0, //offset + wbuf, + 0, //priority + SigevNotify::SigevNone, + )); + aiocb.as_mut().submit().unwrap(); + let err = aiocb.as_mut().error(); + assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS)); + + aio_cancel_all(f.as_raw_fd()).unwrap(); + + // Wait for aiocb to complete, but don't care whether it succeeded + let _ = poll_aio!(&mut aiocb); + let _ = aiocb.as_mut().aio_return(); +} + +#[test] +// On Cirrus on Linux, this test fails due to a glibc bug. +// https://github.com/nix-rust/nix/issues/1099 +#[cfg_attr(target_os = "linux", ignore)] +// On Cirrus, aio_suspend is failing with EINVAL +// https://github.com/nix-rust/nix/issues/1361 +#[cfg_attr(target_os = "macos", ignore)] +fn test_aio_suspend() { + const INITIAL: &[u8] = b"abcdef123456"; + const WBUF: &[u8] = b"CDEFG"; + let timeout = TimeSpec::seconds(10); + let mut rbuf = vec![0; 4]; + let rlen = rbuf.len(); + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); + + let mut wcb = Box::pin(AioWrite::new( + f.as_raw_fd(), + 2, //offset + WBUF, + 0, //priority + SigevNotify::SigevNone, + )); + + let mut rcb = Box::pin(AioRead::new( + f.as_raw_fd(), + 8, //offset + &mut rbuf, + 0, //priority + SigevNotify::SigevNone, + )); + wcb.as_mut().submit().unwrap(); + rcb.as_mut().submit().unwrap(); + loop { + { + let cbbuf = [ + &*wcb as &dyn AsRef, + &*rcb as &dyn AsRef, + ]; + let r = aio_suspend(&cbbuf[..], Some(timeout)); + match r { + Err(Errno::EINTR) => continue, + Err(e) => panic!("aio_suspend returned {:?}", e), + Ok(_) => (), + }; + } + if rcb.as_mut().error() != Err(Errno::EINPROGRESS) + && wcb.as_mut().error() != Err(Errno::EINPROGRESS) + { + break; + } + } + + assert_eq!(wcb.as_mut().aio_return().unwrap(), WBUF.len()); + assert_eq!(rcb.as_mut().aio_return().unwrap(), rlen); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_aio_drop.rs b/utshell-0.5.0/vendor/nix/test/sys/test_aio_drop.rs new file mode 100644 index 00000000..bbe6623f --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_aio_drop.rs @@ -0,0 +1,35 @@ +// Test dropping an AioCb that hasn't yet finished. +// This must happen in its own process, because on OSX this test seems to hose +// the AIO subsystem and causes subsequent tests to fail +#[test] +#[should_panic(expected = "Dropped an in-progress AioCb")] +#[cfg(all( + not(target_env = "musl"), + not(target_env = "uclibc"), + any( + target_os = "linux", + target_os = "ios", + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd" + ) +))] +fn test_drop() { + use nix::sys::aio::*; + use nix::sys::signal::*; + use std::os::unix::io::AsRawFd; + use tempfile::tempfile; + + const WBUF: &[u8] = b"CDEF"; + + let f = tempfile().unwrap(); + f.set_len(6).unwrap(); + let mut aiocb = Box::pin(AioWrite::new( + f.as_raw_fd(), + 2, //offset + WBUF, + 0, //priority + SigevNotify::SigevNone, + )); + aiocb.as_mut().submit().unwrap(); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_epoll.rs b/utshell-0.5.0/vendor/nix/test/sys/test_epoll.rs new file mode 100644 index 00000000..91569159 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_epoll.rs @@ -0,0 +1,24 @@ +use nix::errno::Errno; +use nix::sys::epoll::{epoll_create1, epoll_ctl}; +use nix::sys::epoll::{EpollCreateFlags, EpollEvent, EpollFlags, EpollOp}; + +#[test] +pub fn test_epoll_errno() { + let efd = epoll_create1(EpollCreateFlags::empty()).unwrap(); + let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None); + result.expect_err("assertion failed"); + assert_eq!(result.unwrap_err(), Errno::ENOENT); + + let result = epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, None); + result.expect_err("assertion failed"); + assert_eq!(result.unwrap_err(), Errno::EINVAL); +} + +#[test] +pub fn test_epoll_ctl() { + let efd = epoll_create1(EpollCreateFlags::empty()).unwrap(); + let mut event = + EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, 1); + epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap(); + epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap(); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_inotify.rs b/utshell-0.5.0/vendor/nix/test/sys/test_inotify.rs new file mode 100644 index 00000000..bb5851a9 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_inotify.rs @@ -0,0 +1,65 @@ +use nix::errno::Errno; +use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify}; +use std::ffi::OsString; +use std::fs::{rename, File}; + +#[test] +pub fn test_inotify() { + let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap(); + let tempdir = tempfile::tempdir().unwrap(); + + instance + .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS) + .unwrap(); + + let events = instance.read_events(); + assert_eq!(events.unwrap_err(), Errno::EAGAIN); + + File::create(tempdir.path().join("test")).unwrap(); + + let events = instance.read_events().unwrap(); + assert_eq!(events[0].name, Some(OsString::from("test"))); +} + +#[test] +pub fn test_inotify_multi_events() { + let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap(); + let tempdir = tempfile::tempdir().unwrap(); + + instance + .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS) + .unwrap(); + + let events = instance.read_events(); + assert_eq!(events.unwrap_err(), Errno::EAGAIN); + + File::create(tempdir.path().join("test")).unwrap(); + rename(tempdir.path().join("test"), tempdir.path().join("test2")).unwrap(); + + // Now there should be 5 events in queue: + // - IN_CREATE on test + // - IN_OPEN on test + // - IN_CLOSE_WRITE on test + // - IN_MOVED_FROM on test with a cookie + // - IN_MOVED_TO on test2 with the same cookie + + let events = instance.read_events().unwrap(); + assert_eq!(events.len(), 5); + + assert_eq!(events[0].mask, AddWatchFlags::IN_CREATE); + assert_eq!(events[0].name, Some(OsString::from("test"))); + + assert_eq!(events[1].mask, AddWatchFlags::IN_OPEN); + assert_eq!(events[1].name, Some(OsString::from("test"))); + + assert_eq!(events[2].mask, AddWatchFlags::IN_CLOSE_WRITE); + assert_eq!(events[2].name, Some(OsString::from("test"))); + + assert_eq!(events[3].mask, AddWatchFlags::IN_MOVED_FROM); + assert_eq!(events[3].name, Some(OsString::from("test"))); + + assert_eq!(events[4].mask, AddWatchFlags::IN_MOVED_TO); + assert_eq!(events[4].name, Some(OsString::from("test2"))); + + assert_eq!(events[3].cookie, events[4].cookie); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_ioctl.rs b/utshell-0.5.0/vendor/nix/test/sys/test_ioctl.rs new file mode 100644 index 00000000..40f60cfd --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_ioctl.rs @@ -0,0 +1,376 @@ +#![allow(dead_code)] + +// Simple tests to ensure macro generated fns compile +ioctl_none_bad!(do_bad, 0x1234); +ioctl_read_bad!(do_bad_read, 0x1234, u16); +ioctl_write_int_bad!(do_bad_write_int, 0x1234); +ioctl_write_ptr_bad!(do_bad_write_ptr, 0x1234, u8); +ioctl_readwrite_bad!(do_bad_readwrite, 0x1234, u32); +ioctl_none!(do_none, 0, 0); +ioctl_read!(read_test, 0, 0, u32); +ioctl_write_int!(write_ptr_int, 0, 0); +ioctl_write_ptr!(write_ptr_u8, 0, 0, u8); +ioctl_write_ptr!(write_ptr_u32, 0, 0, u32); +ioctl_write_ptr!(write_ptr_u64, 0, 0, u64); +ioctl_readwrite!(readwrite_test, 0, 0, u64); +ioctl_read_buf!(readbuf_test, 0, 0, u32); +const SPI_IOC_MAGIC: u8 = b'k'; +const SPI_IOC_MESSAGE: u8 = 0; +ioctl_write_buf!(writebuf_test_consts, SPI_IOC_MAGIC, SPI_IOC_MESSAGE, u8); +ioctl_write_buf!(writebuf_test_u8, 0, 0, u8); +ioctl_write_buf!(writebuf_test_u32, 0, 0, u32); +ioctl_write_buf!(writebuf_test_u64, 0, 0, u64); +ioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32); + +// See C code for source of values for op calculations (does NOT work for mips/powerpc): +// https://gist.github.com/posborne/83ea6880770a1aef332e +// +// TODO: Need a way to compute these constants at test time. Using precomputed +// values is fragile and needs to be maintained. + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod linux { + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_none() { + if cfg!(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc", + target_arch = "powerpc64" + )) { + assert_eq!(request_code_none!(b'q', 10) as u32, 0x2000_710A); + assert_eq!(request_code_none!(b'a', 255) as u32, 0x2000_61FF); + } else { + assert_eq!(request_code_none!(b'q', 10) as u32, 0x0000_710A); + assert_eq!(request_code_none!(b'a', 255) as u32, 0x0000_61FF); + } + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_write() { + if cfg!(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc", + target_arch = "powerpc64" + )) { + assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x8001_7A0A); + assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x8200_7A0A); + } else { + assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x4001_7A0A); + assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x4200_7A0A); + } + } + + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_write_64() { + if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) { + assert_eq!( + request_code_write!(b'z', 10, 1u64 << 32) as u32, + 0x8000_7A0A + ); + } else { + assert_eq!( + request_code_write!(b'z', 10, 1u64 << 32) as u32, + 0x4000_7A0A + ); + } + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_read() { + if cfg!(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc", + target_arch = "powerpc64" + )) { + assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x4001_7A0A); + assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x4200_7A0A); + } else { + assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x8001_7A0A); + assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x8200_7A0A); + } + } + + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_64() { + if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) { + assert_eq!( + request_code_read!(b'z', 10, 1u64 << 32) as u32, + 0x4000_7A0A + ); + } else { + assert_eq!( + request_code_read!(b'z', 10, 1u64 << 32) as u32, + 0x8000_7A0A + ); + } + } + + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_read_write() { + assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A); + assert_eq!(request_code_readwrite!(b'z', 10, 512) as u32, 0xC200_7A0A); + } + + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_write_64() { + assert_eq!( + request_code_readwrite!(b'z', 10, 1u64 << 32) as u32, + 0xC000_7A0A + ); + } +} + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd" +))] +mod bsd { + #[test] + fn test_op_none() { + assert_eq!(request_code_none!(b'q', 10), 0x2000_710A); + assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF); + } + + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[test] + fn test_op_write_int() { + assert_eq!(request_code_write_int!(b'v', 4), 0x2004_7604); + assert_eq!(request_code_write_int!(b'p', 2), 0x2004_7002); + } + + #[test] + fn test_op_write() { + assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A); + assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A); + } + + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_write_64() { + assert_eq!(request_code_write!(b'z', 10, 1u64 << 32), 0x8000_7A0A); + } + + #[test] + fn test_op_read() { + assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A); + assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A); + } + + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_64() { + assert_eq!(request_code_read!(b'z', 10, 1u64 << 32), 0x4000_7A0A); + } + + #[test] + fn test_op_read_write() { + assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A); + assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A); + } + + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_write_64() { + assert_eq!(request_code_readwrite!(b'z', 10, 1u64 << 32), 0xC000_7A0A); + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +mod linux_ioctls { + use std::mem; + use std::os::unix::io::AsRawFd; + + use libc::{termios, TCGETS, TCSBRK, TCSETS, TIOCNXCL}; + use tempfile::tempfile; + + use nix::errno::Errno; + + ioctl_none_bad!(tiocnxcl, TIOCNXCL); + #[test] + fn test_ioctl_none_bad() { + let file = tempfile().unwrap(); + let res = unsafe { tiocnxcl(file.as_raw_fd()) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_read_bad!(tcgets, TCGETS, termios); + #[test] + fn test_ioctl_read_bad() { + let file = tempfile().unwrap(); + let mut termios = unsafe { mem::zeroed() }; + let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_write_int_bad!(tcsbrk, TCSBRK); + #[test] + fn test_ioctl_write_int_bad() { + let file = tempfile().unwrap(); + let res = unsafe { tcsbrk(file.as_raw_fd(), 0) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_write_ptr_bad!(tcsets, TCSETS, termios); + #[test] + fn test_ioctl_write_ptr_bad() { + let file = tempfile().unwrap(); + let termios: termios = unsafe { mem::zeroed() }; + let res = unsafe { tcsets(file.as_raw_fd(), &termios) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } + + // FIXME: Find a suitable example for `ioctl_readwrite_bad` + + // From linux/videodev2.h + ioctl_none!(log_status, b'V', 70); + #[test] + fn test_ioctl_none() { + let file = tempfile().unwrap(); + let res = unsafe { log_status(file.as_raw_fd()) }; + assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + #[repr(C)] + pub struct v4l2_audio { + index: u32, + name: [u8; 32], + capability: u32, + mode: u32, + reserved: [u32; 2], + } + + // From linux/videodev2.h + ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); + #[test] + fn test_ioctl_write_ptr() { + let file = tempfile().unwrap(); + let data: v4l2_audio = unsafe { mem::zeroed() }; + let res = unsafe { s_audio(file.as_raw_fd(), &data) }; + assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // From linux/net/bluetooth/hci_sock.h + const HCI_IOC_MAGIC: u8 = b'H'; + const HCI_IOC_HCIDEVUP: u8 = 201; + ioctl_write_int!(hcidevup, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); + #[test] + fn test_ioctl_write_int() { + let file = tempfile().unwrap(); + let res = unsafe { hcidevup(file.as_raw_fd(), 0) }; + assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // From linux/videodev2.h + ioctl_read!(g_audio, b'V', 33, v4l2_audio); + #[test] + fn test_ioctl_read() { + let file = tempfile().unwrap(); + let mut data: v4l2_audio = unsafe { mem::zeroed() }; + let res = unsafe { g_audio(file.as_raw_fd(), &mut data) }; + assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // From linux/videodev2.h + ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); + #[test] + fn test_ioctl_readwrite() { + let file = tempfile().unwrap(); + let mut data: v4l2_audio = unsafe { mem::zeroed() }; + let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) }; + assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // FIXME: Find a suitable example for `ioctl_read_buf`. + + #[repr(C)] + pub struct spi_ioc_transfer { + tx_buf: u64, + rx_buf: u64, + len: u32, + speed_hz: u32, + delay_usecs: u16, + bits_per_word: u8, + cs_change: u8, + tx_nbits: u8, + rx_nbits: u8, + pad: u16, + } + + // From linux/spi/spidev.h + ioctl_write_buf!( + spi_ioc_message, + super::SPI_IOC_MAGIC, + super::SPI_IOC_MESSAGE, + spi_ioc_transfer + ); + #[test] + fn test_ioctl_write_buf() { + let file = tempfile().unwrap(); + let data: [spi_ioc_transfer; 4] = unsafe { mem::zeroed() }; + let res = unsafe { spi_ioc_message(file.as_raw_fd(), &data[..]) }; + assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // FIXME: Find a suitable example for `ioctl_readwrite_buf`. +} + +#[cfg(target_os = "freebsd")] +mod freebsd_ioctls { + use std::mem; + use std::os::unix::io::AsRawFd; + + use libc::termios; + use tempfile::tempfile; + + use nix::errno::Errno; + + // From sys/sys/ttycom.h + const TTY_IOC_MAGIC: u8 = b't'; + const TTY_IOC_TYPE_NXCL: u8 = 14; + const TTY_IOC_TYPE_GETA: u8 = 19; + const TTY_IOC_TYPE_SETA: u8 = 20; + + ioctl_none!(tiocnxcl, TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL); + #[test] + fn test_ioctl_none() { + let file = tempfile().unwrap(); + let res = unsafe { tiocnxcl(file.as_raw_fd()) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_read!(tiocgeta, TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA, termios); + #[test] + fn test_ioctl_read() { + let file = tempfile().unwrap(); + let mut termios = unsafe { mem::zeroed() }; + let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_write_ptr!(tiocseta, TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA, termios); + #[test] + fn test_ioctl_write_ptr() { + let file = tempfile().unwrap(); + let termios: termios = unsafe { mem::zeroed() }; + let res = unsafe { tiocseta(file.as_raw_fd(), &termios) }; + assert_eq!(res, Err(Errno::ENOTTY)); + } +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_mman.rs b/utshell-0.5.0/vendor/nix/test/sys/test_mman.rs new file mode 100644 index 00000000..75cbf6ce --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_mman.rs @@ -0,0 +1,117 @@ +use nix::sys::mman::{mmap, MapFlags, ProtFlags}; + +#[test] +fn test_mmap_anonymous() { + unsafe { + let ptr = mmap( + std::ptr::null_mut(), + 1, + ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, + MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, + -1, + 0, + ) + .unwrap() as *mut u8; + assert_eq!(*ptr, 0x00u8); + *ptr = 0xffu8; + assert_eq!(*ptr, 0xffu8); + } +} + +#[test] +#[cfg(any(target_os = "linux", target_os = "netbsd"))] +fn test_mremap_grow() { + use nix::libc::{c_void, size_t}; + use nix::sys::mman::{mremap, MRemapFlags}; + + const ONE_K: size_t = 1024; + let slice: &mut [u8] = unsafe { + let mem = mmap( + std::ptr::null_mut(), + ONE_K, + ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, + MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, + -1, + 0, + ) + .unwrap(); + std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) + }; + assert_eq!(slice[ONE_K - 1], 0x00); + slice[ONE_K - 1] = 0xFF; + assert_eq!(slice[ONE_K - 1], 0xFF); + + let slice: &mut [u8] = unsafe { + #[cfg(target_os = "linux")] + let mem = mremap( + slice.as_mut_ptr() as *mut c_void, + ONE_K, + 10 * ONE_K, + MRemapFlags::MREMAP_MAYMOVE, + None, + ) + .unwrap(); + #[cfg(target_os = "netbsd")] + let mem = mremap( + slice.as_mut_ptr() as *mut c_void, + ONE_K, + 10 * ONE_K, + MRemapFlags::MAP_REMAPDUP, + None, + ) + .unwrap(); + std::slice::from_raw_parts_mut(mem as *mut u8, 10 * ONE_K) + }; + + // The first KB should still have the old data in it. + assert_eq!(slice[ONE_K - 1], 0xFF); + + // The additional range should be zero-init'd and accessible. + assert_eq!(slice[10 * ONE_K - 1], 0x00); + slice[10 * ONE_K - 1] = 0xFF; + assert_eq!(slice[10 * ONE_K - 1], 0xFF); +} + +#[test] +#[cfg(any(target_os = "linux", target_os = "netbsd"))] +// Segfaults for unknown reasons under QEMU for 32-bit targets +#[cfg_attr(all(target_pointer_width = "32", qemu), ignore)] +fn test_mremap_shrink() { + use nix::libc::{c_void, size_t}; + use nix::sys::mman::{mremap, MRemapFlags}; + + const ONE_K: size_t = 1024; + let slice: &mut [u8] = unsafe { + let mem = mmap( + std::ptr::null_mut(), + 10 * ONE_K, + ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, + MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, + -1, + 0, + ) + .unwrap(); + std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) + }; + assert_eq!(slice[ONE_K - 1], 0x00); + slice[ONE_K - 1] = 0xFF; + assert_eq!(slice[ONE_K - 1], 0xFF); + + let slice: &mut [u8] = unsafe { + let mem = mremap( + slice.as_mut_ptr() as *mut c_void, + 10 * ONE_K, + ONE_K, + MRemapFlags::empty(), + None, + ) + .unwrap(); + // Since we didn't supply MREMAP_MAYMOVE, the address should be the + // same. + assert_eq!(mem, slice.as_mut_ptr() as *mut c_void); + std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) + }; + + // The first KB should still be accessible and have the old data in it. + assert_eq!(slice[ONE_K - 1], 0xFF); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_pthread.rs b/utshell-0.5.0/vendor/nix/test/sys/test_pthread.rs new file mode 100644 index 00000000..ce048bae --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_pthread.rs @@ -0,0 +1,22 @@ +use nix::sys::pthread::*; + +#[cfg(any(target_env = "musl", target_os = "redox"))] +#[test] +fn test_pthread_self() { + let tid = pthread_self(); + assert!(!tid.is_null()); +} + +#[cfg(not(any(target_env = "musl", target_os = "redox")))] +#[test] +fn test_pthread_self() { + let tid = pthread_self(); + assert_ne!(tid, 0); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_pthread_kill_none() { + pthread_kill(pthread_self(), None) + .expect("Should be able to send signal to my thread."); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_ptrace.rs b/utshell-0.5.0/vendor/nix/test/sys/test_ptrace.rs new file mode 100644 index 00000000..530560fe --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_ptrace.rs @@ -0,0 +1,275 @@ +#[cfg(all( + target_os = "linux", + any(target_arch = "x86_64", target_arch = "x86"), + target_env = "gnu" +))] +use memoffset::offset_of; +use nix::errno::Errno; +use nix::sys::ptrace; +#[cfg(any(target_os = "android", target_os = "linux"))] +use nix::sys::ptrace::Options; +use nix::unistd::getpid; + +#[cfg(any(target_os = "android", target_os = "linux"))] +use std::mem; + +use crate::*; + +#[test] +fn test_ptrace() { + // Just make sure ptrace can be called at all, for now. + // FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS + require_capability!("test_ptrace", CAP_SYS_PTRACE); + let err = ptrace::attach(getpid()).unwrap_err(); + assert!( + err == Errno::EPERM || err == Errno::EINVAL || err == Errno::ENOSYS + ); +} + +// Just make sure ptrace_setoptions can be called at all, for now. +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptrace_setoptions() { + require_capability!("test_ptrace_setoptions", CAP_SYS_PTRACE); + let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD) + .unwrap_err(); + assert_ne!(err, Errno::EOPNOTSUPP); +} + +// Just make sure ptrace_getevent can be called at all, for now. +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptrace_getevent() { + require_capability!("test_ptrace_getevent", CAP_SYS_PTRACE); + let err = ptrace::getevent(getpid()).unwrap_err(); + assert_ne!(err, Errno::EOPNOTSUPP); +} + +// Just make sure ptrace_getsiginfo can be called at all, for now. +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptrace_getsiginfo() { + require_capability!("test_ptrace_getsiginfo", CAP_SYS_PTRACE); + if let Err(Errno::EOPNOTSUPP) = ptrace::getsiginfo(getpid()) { + panic!("ptrace_getsiginfo returns Errno::EOPNOTSUPP!"); + } +} + +// Just make sure ptrace_setsiginfo can be called at all, for now. +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptrace_setsiginfo() { + require_capability!("test_ptrace_setsiginfo", CAP_SYS_PTRACE); + let siginfo = unsafe { mem::zeroed() }; + if let Err(Errno::EOPNOTSUPP) = ptrace::setsiginfo(getpid(), &siginfo) { + panic!("ptrace_setsiginfo returns Errno::EOPNOTSUPP!"); + } +} + +#[test] +fn test_ptrace_cont() { + use nix::sys::ptrace; + use nix::sys::signal::{raise, Signal}; + use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus}; + use nix::unistd::fork; + use nix::unistd::ForkResult::*; + + require_capability!("test_ptrace_cont", CAP_SYS_PTRACE); + + let _m = crate::FORK_MTX.lock(); + + // FIXME: qemu-user doesn't implement ptrace on all architectures + // and returns ENOSYS in this case. + // We (ab)use this behavior to detect the affected platforms + // and skip the test then. + // On valid platforms the ptrace call should return Errno::EPERM, this + // is already tested by `test_ptrace`. + let err = ptrace::attach(getpid()).unwrap_err(); + if err == Errno::ENOSYS { + return; + } + + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => { + ptrace::traceme().unwrap(); + // As recommended by ptrace(2), raise SIGTRAP to pause the child + // until the parent is ready to continue + loop { + raise(Signal::SIGTRAP).unwrap(); + } + } + Parent { child } => { + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)) + ); + ptrace::cont(child, None).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)) + ); + ptrace::cont(child, Some(Signal::SIGKILL)).unwrap(); + match waitpid(child, None) { + Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) + if pid == child => + { + // FIXME It's been observed on some systems (apple) the + // tracee may not be killed but remain as a zombie process + // affecting other wait based tests. Add an extra kill just + // to make sure there are no zombies. + let _ = waitpid(child, Some(WaitPidFlag::WNOHANG)); + while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() { + let _ = waitpid(child, Some(WaitPidFlag::WNOHANG)); + } + } + _ => panic!("The process should have been killed"), + } + } + } +} + +#[cfg(target_os = "linux")] +#[test] +fn test_ptrace_interrupt() { + use nix::sys::ptrace; + use nix::sys::signal::Signal; + use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus}; + use nix::unistd::fork; + use nix::unistd::ForkResult::*; + use std::thread::sleep; + use std::time::Duration; + + require_capability!("test_ptrace_interrupt", CAP_SYS_PTRACE); + + let _m = crate::FORK_MTX.lock(); + + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => loop { + sleep(Duration::from_millis(1000)); + }, + Parent { child } => { + ptrace::seize(child, ptrace::Options::PTRACE_O_TRACESYSGOOD) + .unwrap(); + ptrace::interrupt(child).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::PtraceEvent(child, Signal::SIGTRAP, 128)) + ); + ptrace::syscall(child, None).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::PtraceSyscall(child)) + ); + ptrace::detach(child, Some(Signal::SIGKILL)).unwrap(); + match waitpid(child, None) { + Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) + if pid == child => + { + let _ = waitpid(child, Some(WaitPidFlag::WNOHANG)); + while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() { + let _ = waitpid(child, Some(WaitPidFlag::WNOHANG)); + } + } + _ => panic!("The process should have been killed"), + } + } + } +} + +// ptrace::{setoptions, getregs} are only available in these platforms +#[cfg(all( + target_os = "linux", + any(target_arch = "x86_64", target_arch = "x86"), + target_env = "gnu" +))] +#[test] +fn test_ptrace_syscall() { + use nix::sys::ptrace; + use nix::sys::signal::kill; + use nix::sys::signal::Signal; + use nix::sys::wait::{waitpid, WaitStatus}; + use nix::unistd::fork; + use nix::unistd::getpid; + use nix::unistd::ForkResult::*; + + require_capability!("test_ptrace_syscall", CAP_SYS_PTRACE); + + let _m = crate::FORK_MTX.lock(); + + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => { + ptrace::traceme().unwrap(); + // first sigstop until parent is ready to continue + let pid = getpid(); + kill(pid, Signal::SIGSTOP).unwrap(); + kill(pid, Signal::SIGTERM).unwrap(); + unsafe { + ::libc::_exit(0); + } + } + + Parent { child } => { + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Stopped(child, Signal::SIGSTOP)) + ); + + // set this option to recognize syscall-stops + ptrace::setoptions(child, ptrace::Options::PTRACE_O_TRACESYSGOOD) + .unwrap(); + + #[cfg(target_arch = "x86_64")] + let get_syscall_id = + || ptrace::getregs(child).unwrap().orig_rax as libc::c_long; + + #[cfg(target_arch = "x86")] + let get_syscall_id = + || ptrace::getregs(child).unwrap().orig_eax as libc::c_long; + + // this duplicates `get_syscall_id` for the purpose of testing `ptrace::read_user`. + #[cfg(target_arch = "x86_64")] + let rax_offset = offset_of!(libc::user_regs_struct, orig_rax); + #[cfg(target_arch = "x86")] + let rax_offset = offset_of!(libc::user_regs_struct, orig_eax); + + let get_syscall_from_user_area = || { + // Find the offset of `user.regs.rax` (or `user.regs.eax` for x86) + let rax_offset = offset_of!(libc::user, regs) + rax_offset; + ptrace::read_user(child, rax_offset as _).unwrap() + as libc::c_long + }; + + // kill entry + ptrace::syscall(child, None).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::PtraceSyscall(child)) + ); + assert_eq!(get_syscall_id(), ::libc::SYS_kill); + assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill); + + // kill exit + ptrace::syscall(child, None).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::PtraceSyscall(child)) + ); + assert_eq!(get_syscall_id(), ::libc::SYS_kill); + assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill); + + // receive signal + ptrace::syscall(child, None).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Stopped(child, Signal::SIGTERM)) + ); + + // inject signal + ptrace::syscall(child, Signal::SIGTERM).unwrap(); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Signaled(child, Signal::SIGTERM, false)) + ); + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_select.rs b/utshell-0.5.0/vendor/nix/test/sys/test_select.rs new file mode 100644 index 00000000..40bda4d9 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_select.rs @@ -0,0 +1,81 @@ +use nix::sys::select::*; +use nix::sys::signal::SigSet; +use nix::sys::time::{TimeSpec, TimeValLike}; +use nix::unistd::{pipe, write}; + +#[test] +pub fn test_pselect() { + let _mtx = crate::SIGNAL_MTX.lock(); + + let (r1, w1) = pipe().unwrap(); + write(w1, b"hi!").unwrap(); + let (r2, _w2) = pipe().unwrap(); + + let mut fd_set = FdSet::new(); + fd_set.insert(r1); + fd_set.insert(r2); + + let timeout = TimeSpec::seconds(10); + let sigmask = SigSet::empty(); + assert_eq!( + 1, + pselect(None, &mut fd_set, None, None, &timeout, &sigmask).unwrap() + ); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); +} + +#[test] +pub fn test_pselect_nfds2() { + let (r1, w1) = pipe().unwrap(); + write(w1, b"hi!").unwrap(); + let (r2, _w2) = pipe().unwrap(); + + let mut fd_set = FdSet::new(); + fd_set.insert(r1); + fd_set.insert(r2); + + let timeout = TimeSpec::seconds(10); + assert_eq!( + 1, + pselect( + ::std::cmp::max(r1, r2) + 1, + &mut fd_set, + None, + None, + &timeout, + None + ) + .unwrap() + ); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); +} + +macro_rules! generate_fdset_bad_fd_tests { + ($fd:expr, $($method:ident),* $(,)?) => { + $( + #[test] + #[should_panic] + fn $method() { + FdSet::new().$method($fd); + } + )* + } +} + +mod test_fdset_negative_fd { + use super::*; + generate_fdset_bad_fd_tests!(-1, insert, remove, contains); +} + +mod test_fdset_too_large_fd { + use super::*; + use std::convert::TryInto; + generate_fdset_bad_fd_tests!( + FD_SETSIZE.try_into().unwrap(), + insert, + remove, + contains, + ); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_signal.rs b/utshell-0.5.0/vendor/nix/test/sys/test_signal.rs new file mode 100644 index 00000000..3ad14f40 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_signal.rs @@ -0,0 +1,147 @@ +#[cfg(not(target_os = "redox"))] +use nix::errno::Errno; +use nix::sys::signal::*; +use nix::unistd::*; +use std::convert::TryFrom; +use std::sync::atomic::{AtomicBool, Ordering}; + +#[test] +fn test_kill_none() { + kill(getpid(), None).expect("Should be able to send signal to myself."); +} + +#[test] +#[cfg(not(target_os = "fuchsia"))] +fn test_killpg_none() { + killpg(getpgrp(), None) + .expect("Should be able to send signal to my process group."); +} + +#[test] +fn test_old_sigaction_flags() { + let _m = crate::SIGNAL_MTX.lock(); + + extern "C" fn handler(_: ::libc::c_int) {} + let act = SigAction::new( + SigHandler::Handler(handler), + SaFlags::empty(), + SigSet::empty(), + ); + let oact = unsafe { sigaction(SIGINT, &act) }.unwrap(); + let _flags = oact.flags(); + let oact = unsafe { sigaction(SIGINT, &act) }.unwrap(); + let _flags = oact.flags(); +} + +#[test] +fn test_sigprocmask_noop() { + sigprocmask(SigmaskHow::SIG_BLOCK, None, None) + .expect("this should be an effective noop"); +} + +#[test] +fn test_sigprocmask() { + let _m = crate::SIGNAL_MTX.lock(); + + // This needs to be a signal that rust doesn't use in the test harness. + const SIGNAL: Signal = Signal::SIGCHLD; + + let mut old_signal_set = SigSet::empty(); + sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set)) + .expect("expect to be able to retrieve old signals"); + + // Make sure the old set doesn't contain the signal, otherwise the following + // test don't make sense. + assert!( + !old_signal_set.contains(SIGNAL), + "the {:?} signal is already blocked, please change to a \ + different one", + SIGNAL + ); + + // Now block the signal. + let mut signal_set = SigSet::empty(); + signal_set.add(SIGNAL); + sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None) + .expect("expect to be able to block signals"); + + // And test it again, to make sure the change was effective. + old_signal_set.clear(); + sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set)) + .expect("expect to be able to retrieve old signals"); + assert!( + old_signal_set.contains(SIGNAL), + "expected the {:?} to be blocked", + SIGNAL + ); + + // Reset the signal. + sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None) + .expect("expect to be able to block signals"); +} + +lazy_static! { + static ref SIGNALED: AtomicBool = AtomicBool::new(false); +} + +extern "C" fn test_sigaction_handler(signal: libc::c_int) { + let signal = Signal::try_from(signal).unwrap(); + SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed); +} + +#[cfg(not(target_os = "redox"))] +extern "C" fn test_sigaction_action( + _: libc::c_int, + _: *mut libc::siginfo_t, + _: *mut libc::c_void, +) { +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_signal_sigaction() { + let _m = crate::SIGNAL_MTX.lock(); + + let action_handler = SigHandler::SigAction(test_sigaction_action); + assert_eq!( + unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), + Errno::ENOTSUP + ); +} + +#[test] +fn test_signal() { + let _m = crate::SIGNAL_MTX.lock(); + + unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap(); + raise(Signal::SIGINT).unwrap(); + assert_eq!( + unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), + SigHandler::SigIgn + ); + + let handler = SigHandler::Handler(test_sigaction_handler); + assert_eq!( + unsafe { signal(Signal::SIGINT, handler) }.unwrap(), + SigHandler::SigDfl + ); + raise(Signal::SIGINT).unwrap(); + assert!(SIGNALED.load(Ordering::Relaxed)); + + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] + assert_eq!( + unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), + handler + ); + + // System V based OSes (e.g. illumos and Solaris) always resets the + // disposition to SIG_DFL prior to calling the signal handler + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + assert_eq!( + unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), + SigHandler::SigDfl + ); + + // Restore default signal handler + unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_signalfd.rs b/utshell-0.5.0/vendor/nix/test/sys/test_signalfd.rs new file mode 100644 index 00000000..87153c95 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_signalfd.rs @@ -0,0 +1,27 @@ +use std::convert::TryFrom; + +#[test] +fn test_signalfd() { + use nix::sys::signal::{self, raise, SigSet, Signal}; + use nix::sys::signalfd::SignalFd; + + // Grab the mutex for altering signals so we don't interfere with other tests. + let _m = crate::SIGNAL_MTX.lock(); + + // Block the SIGUSR1 signal from automatic processing for this thread + let mut mask = SigSet::empty(); + mask.add(signal::SIGUSR1); + mask.thread_block().unwrap(); + + let mut fd = SignalFd::new(&mask).unwrap(); + + // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill` + // because `kill` with `getpid` isn't correct during multi-threaded execution like during a + // cargo test session. Instead use `raise` which does the correct thing by default. + raise(signal::SIGUSR1).expect("Error: raise(SIGUSR1) failed"); + + // And now catch that same signal. + let res = fd.read_signal().unwrap().unwrap(); + let signo = Signal::try_from(res.ssi_signo as i32).unwrap(); + assert_eq!(signo, signal::SIGUSR1); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_socket.rs b/utshell-0.5.0/vendor/nix/test/sys/test_socket.rs new file mode 100644 index 00000000..b4ca279d --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_socket.rs @@ -0,0 +1,2557 @@ +#[cfg(any(target_os = "linux", target_os = "android"))] +use crate::*; +use libc::{c_char, sockaddr_storage}; +#[allow(deprecated)] +use nix::sys::socket::InetAddr; +use nix::sys::socket::{ + getsockname, sockaddr, sockaddr_in6, AddressFamily, UnixAddr, +}; +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; +use std::mem::{self, MaybeUninit}; +use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; +use std::os::unix::io::RawFd; +use std::path::Path; +use std::slice; +use std::str::FromStr; + +#[allow(deprecated)] +#[test] +pub fn test_inetv4_addr_to_sock_addr() { + let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap(); + let addr = InetAddr::from_std(&actual); + + match addr { + InetAddr::V4(addr) => { + let ip: u32 = 0x7f00_0001; + let port: u16 = 3000; + let saddr = addr.sin_addr.s_addr; + + assert_eq!(saddr, ip.to_be()); + assert_eq!(addr.sin_port, port.to_be()); + } + _ => panic!("nope"), + } + + assert_eq!(addr.to_string(), "127.0.0.1:3000"); + + let inet = addr.to_std(); + assert_eq!(actual, inet); +} + +#[allow(deprecated)] +#[test] +pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() { + use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr}; + + let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap(); + let addr = InetAddr::from_std(&actual); + let sockaddr = SockAddr::new_inet(addr); + + let (storage, ffi_size) = { + let mut storage = MaybeUninit::::zeroed(); + let storage_ptr = storage.as_mut_ptr().cast::(); + let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair(); + assert_eq!(mem::size_of::(), ffi_size as usize); + unsafe { + storage_ptr.copy_from_nonoverlapping(ffi_ptr as *const sockaddr, 1); + (storage.assume_init(), ffi_size) + } + }; + + let from_storage = + sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); + assert_eq!(from_storage, sockaddr); + let from_storage = + sockaddr_storage_to_addr(&storage, mem::size_of::()) + .unwrap(); + assert_eq!(from_storage, sockaddr); +} + +#[cfg(any(target_os = "linux"))] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_timestamping() { + use nix::sys::socket::{ + recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping, + ControlMessageOwned, MsgFlags, SockFlag, SockType, SockaddrIn, + TimestampingFlag, + }; + use std::io::{IoSlice, IoSliceMut}; + + let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap(); + + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + nix::sys::socket::bind(rsock, &sock_addr).unwrap(); + + setsockopt(rsock, Timestamping, &TimestampingFlag::all()).unwrap(); + + let sbuf = [0u8; 2048]; + let mut rbuf = [0u8; 2048]; + let flags = MsgFlags::empty(); + let iov1 = [IoSlice::new(&sbuf)]; + let mut iov2 = [IoSliceMut::new(&mut rbuf)]; + + let mut cmsg = cmsg_space!(nix::sys::socket::Timestamps); + sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap(); + let recv = recvmsg::<()>(rsock, &mut iov2, Some(&mut cmsg), flags).unwrap(); + + let mut ts = None; + for c in recv.cmsgs() { + if let ControlMessageOwned::ScmTimestampsns(timestamps) = c { + ts = Some(timestamps.system); + } + } + let ts = ts.expect("ScmTimestampns is present"); + let sys_time = + ::nix::time::clock_gettime(::nix::time::ClockId::CLOCK_REALTIME) + .unwrap(); + let diff = if ts > sys_time { + ts - sys_time + } else { + sys_time - ts + }; + assert!(std::time::Duration::from(diff).as_secs() < 60); +} + +#[allow(deprecated)] +#[test] +pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() { + use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr}; + + let port: u16 = 3000; + let flowinfo: u32 = 1; + let scope_id: u32 = 2; + let ip: Ipv6Addr = "fe80::1".parse().unwrap(); + + let actual = + SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id)); + let addr = InetAddr::from_std(&actual); + let sockaddr = SockAddr::new_inet(addr); + + let (storage, ffi_size) = { + let mut storage = MaybeUninit::::zeroed(); + let storage_ptr = storage.as_mut_ptr().cast::(); + let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair(); + assert_eq!(mem::size_of::(), ffi_size as usize); + unsafe { + storage_ptr.copy_from_nonoverlapping( + (ffi_ptr as *const sockaddr).cast::(), + 1, + ); + (storage.assume_init(), ffi_size) + } + }; + + let from_storage = + sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); + assert_eq!(from_storage, sockaddr); + let from_storage = + sockaddr_storage_to_addr(&storage, mem::size_of::()) + .unwrap(); + assert_eq!(from_storage, sockaddr); +} + +#[test] +pub fn test_path_to_sock_addr() { + let path = "/foo/bar"; + let actual = Path::new(path); + let addr = UnixAddr::new(actual).unwrap(); + + let expect: &[c_char] = unsafe { + slice::from_raw_parts(path.as_ptr() as *const c_char, path.len()) + }; + assert_eq!(unsafe { &(*addr.as_ptr()).sun_path[..8] }, expect); + + assert_eq!(addr.path(), Some(actual)); +} + +fn calculate_hash(t: &T) -> u64 { + let mut s = DefaultHasher::new(); + t.hash(&mut s); + s.finish() +} + +#[test] +pub fn test_addr_equality_path() { + let path = "/foo/bar"; + let actual = Path::new(path); + let addr1 = UnixAddr::new(actual).unwrap(); + let mut addr2 = addr1; + + unsafe { (*addr2.as_mut_ptr()).sun_path[10] = 127 }; + + assert_eq!(addr1, addr2); + assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2)); +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[test] +pub fn test_abstract_sun_path_too_long() { + let name = String::from("nix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0testttttnix\0abstract\0test\0make\0sure\0this\0is\0long\0enough"); + let addr = UnixAddr::new_abstract(name.as_bytes()); + addr.expect_err("assertion failed"); +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[test] +pub fn test_addr_equality_abstract() { + let name = String::from("nix\0abstract\0test"); + let addr1 = UnixAddr::new_abstract(name.as_bytes()).unwrap(); + let mut addr2 = addr1; + + assert_eq!(addr1, addr2); + assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2)); + + unsafe { (*addr2.as_mut_ptr()).sun_path[17] = 127 }; + assert_ne!(addr1, addr2); + assert_ne!(calculate_hash(&addr1), calculate_hash(&addr2)); +} + +// Test getting/setting abstract addresses (without unix socket creation) +#[cfg(target_os = "linux")] +#[test] +pub fn test_abstract_uds_addr() { + let empty = String::new(); + let addr = UnixAddr::new_abstract(empty.as_bytes()).unwrap(); + let sun_path: [u8; 0] = []; + assert_eq!(addr.as_abstract(), Some(&sun_path[..])); + + let name = String::from("nix\0abstract\0test"); + let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap(); + let sun_path = [ + 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, + 115, 116, + ]; + assert_eq!(addr.as_abstract(), Some(&sun_path[..])); + assert_eq!(addr.path(), None); + + // Internally, name is null-prefixed (abstract namespace) + assert_eq!(unsafe { (*addr.as_ptr()).sun_path[0] }, 0); +} + +#[test] +pub fn test_getsockname() { + use nix::sys::socket::bind; + use nix::sys::socket::{socket, AddressFamily, SockFlag, SockType}; + + let tempdir = tempfile::tempdir().unwrap(); + let sockname = tempdir.path().join("sock"); + let sock = socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + let sockaddr = UnixAddr::new(&sockname).unwrap(); + bind(sock, &sockaddr).expect("bind failed"); + assert_eq!(sockaddr, getsockname(sock).expect("getsockname failed")); +} + +#[test] +pub fn test_socketpair() { + use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType}; + use nix::unistd::{read, write}; + + let (fd1, fd2) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + write(fd1, b"hello").unwrap(); + let mut buf = [0; 5]; + read(fd2, &mut buf).unwrap(); + + assert_eq!(&buf[..], b"hello"); +} + +#[test] +pub fn test_std_conversions() { + use nix::sys::socket::*; + + let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap(); + let sock_addr = SockaddrIn::from(std_sa); + assert_eq!(std_sa, sock_addr.into()); + + let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap(); + let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa); + assert_eq!(std_sa, sock_addr.into()); +} + +mod recvfrom { + use super::*; + use nix::sys::socket::*; + use nix::{errno::Errno, Result}; + use std::thread; + + const MSG: &[u8] = b"Hello, World!"; + + fn sendrecv( + rsock: RawFd, + ssock: RawFd, + f_send: Fs, + mut f_recv: Fr, + ) -> Option + where + Fs: Fn(RawFd, &[u8], MsgFlags) -> Result + Send + 'static, + Fr: FnMut(usize, Option), + { + let mut buf: [u8; 13] = [0u8; 13]; + let mut l = 0; + let mut from = None; + + let send_thread = thread::spawn(move || { + let mut l = 0; + while l < std::mem::size_of_val(MSG) { + l += f_send(ssock, &MSG[l..], MsgFlags::empty()).unwrap(); + } + }); + + while l < std::mem::size_of_val(MSG) { + let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap(); + f_recv(len, from_); + from = from_; + l += len; + } + assert_eq!(&buf, MSG); + send_thread.join().unwrap(); + from + } + + #[test] + pub fn stream() { + let (fd2, fd1) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + // Ignore from for stream sockets + let _ = sendrecv(fd1, fd2, send, |_, _| {}); + } + + #[test] + pub fn udp() { + let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap(); + let sock_addr = SockaddrIn::from(std_sa); + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + bind(rsock, &sock_addr).unwrap(); + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + let from = sendrecv( + rsock, + ssock, + move |s, m, flags| sendto(s, m, &sock_addr, flags), + |_, _| {}, + ); + // UDP sockets should set the from address + assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap()); + } + + #[cfg(target_os = "linux")] + mod udp_offload { + use super::*; + use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment}; + use std::io::IoSlice; + + #[test] + // Disable the test under emulation because it fails in Cirrus-CI. Lack + // of QEMU support is suspected. + #[cfg_attr(qemu, ignore)] + pub fn gso() { + require_kernel_version!(udp_offload::gso, ">= 4.18"); + + // In this test, we send the data and provide a GSO segment size. + // Since we are sending the buffer of size 13, six UDP packets + // with size 2 and two UDP packet with size 1 will be sent. + let segment_size: u16 = 2; + + let sock_addr = SockaddrIn::new(127, 0, 0, 1, 6791); + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + + setsockopt(rsock, UdpGsoSegment, &(segment_size as _)) + .expect("setsockopt UDP_SEGMENT failed"); + + bind(rsock, &sock_addr).unwrap(); + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + + let mut num_packets_received: i32 = 0; + + sendrecv( + rsock, + ssock, + move |s, m, flags| { + let iov = [IoSlice::new(m)]; + let cmsg = ControlMessage::UdpGsoSegments(&segment_size); + sendmsg(s, &iov, &[cmsg], flags, Some(&sock_addr)) + }, + { + let num_packets_received_ref = &mut num_packets_received; + + move |len, _| { + // check that we receive UDP packets with payload size + // less or equal to segment size + assert!(len <= segment_size as usize); + *num_packets_received_ref += 1; + } + }, + ); + + // Buffer size is 13, we will receive six packets of size 2, + // and one packet of size 1. + assert_eq!(7, num_packets_received); + } + + #[test] + // Disable the test on emulated platforms because it fails in Cirrus-CI. + // Lack of QEMU support is suspected. + #[cfg_attr(qemu, ignore)] + pub fn gro() { + require_kernel_version!(udp_offload::gro, ">= 5.3"); + + // It's hard to guarantee receiving GRO packets. Just checking + // that `setsockopt` doesn't fail with error + + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + + setsockopt(rsock, UdpGroSegment, &true) + .expect("setsockopt UDP_GRO failed"); + } + } + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + ))] + #[test] + pub fn udp_sendmmsg() { + use std::io::IoSlice; + + let std_sa = SocketAddrV4::from_str("127.0.0.1:6793").unwrap(); + let std_sa2 = SocketAddrV4::from_str("127.0.0.1:6794").unwrap(); + let sock_addr = SockaddrIn::from(std_sa); + let sock_addr2 = SockaddrIn::from(std_sa2); + + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + bind(rsock, &sock_addr).unwrap(); + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + + let from = sendrecv( + rsock, + ssock, + move |s, m, flags| { + let iov = [IoSlice::new(m)]; + let mut msgs = vec![SendMmsgData { + iov: &iov, + cmsgs: &[], + addr: Some(sock_addr), + _lt: Default::default(), + }]; + + let batch_size = 15; + + for _ in 0..batch_size { + msgs.push(SendMmsgData { + iov: &iov, + cmsgs: &[], + addr: Some(sock_addr2), + _lt: Default::default(), + }); + } + sendmmsg(s, msgs.iter(), flags).map(move |sent_bytes| { + assert!(!sent_bytes.is_empty()); + for sent in &sent_bytes { + assert_eq!(*sent, m.len()); + } + sent_bytes.len() + }) + }, + |_, _| {}, + ); + // UDP sockets should set the from address + assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap()); + } + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + ))] + #[test] + pub fn udp_recvmmsg() { + use nix::sys::socket::{recvmmsg, MsgFlags}; + use std::io::IoSliceMut; + + const NUM_MESSAGES_SENT: usize = 2; + const DATA: [u8; 2] = [1, 2]; + + let inet_addr = SocketAddrV4::from_str("127.0.0.1:6798").unwrap(); + let sock_addr = SockaddrIn::from(inet_addr); + + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + bind(rsock, &sock_addr).unwrap(); + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + + let send_thread = thread::spawn(move || { + for _ in 0..NUM_MESSAGES_SENT { + sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty()) + .unwrap(); + } + }); + + let mut msgs = std::collections::LinkedList::new(); + + // Buffers to receive exactly `NUM_MESSAGES_SENT` messages + let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT]; + let iovs: Vec<_> = receive_buffers + .iter_mut() + .map(|buf| [IoSliceMut::new(&mut buf[..])]) + .collect(); + + for iov in &iovs { + msgs.push_back(RecvMmsgData { + iov, + cmsg_buffer: None, + }) + } + + let res: Vec> = + recvmmsg(rsock, &mut msgs, MsgFlags::empty(), None) + .expect("recvmmsg"); + assert_eq!(res.len(), DATA.len()); + + for RecvMsg { address, bytes, .. } in res.into_iter() { + assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap()); + assert_eq!(DATA.len(), bytes); + } + + for buf in &receive_buffers { + assert_eq!(&buf[..DATA.len()], DATA); + } + + send_thread.join().unwrap(); + } + + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd", + ))] + #[test] + pub fn udp_recvmmsg_dontwait_short_read() { + use nix::sys::socket::{recvmmsg, MsgFlags}; + use std::io::IoSliceMut; + + const NUM_MESSAGES_SENT: usize = 2; + const DATA: [u8; 4] = [1, 2, 3, 4]; + + let inet_addr = SocketAddrV4::from_str("127.0.0.1:6799").unwrap(); + let sock_addr = SockaddrIn::from(inet_addr); + + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + bind(rsock, &sock_addr).unwrap(); + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + + let send_thread = thread::spawn(move || { + for _ in 0..NUM_MESSAGES_SENT { + sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty()) + .unwrap(); + } + }); + // Ensure we've sent all the messages before continuing so `recvmmsg` + // will return right away + send_thread.join().unwrap(); + + let mut msgs = std::collections::LinkedList::new(); + + // Buffers to receive >`NUM_MESSAGES_SENT` messages to ensure `recvmmsg` + // will return when there are fewer than requested messages in the + // kernel buffers when using `MSG_DONTWAIT`. + let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2]; + let iovs: Vec<_> = receive_buffers + .iter_mut() + .map(|buf| [IoSliceMut::new(&mut buf[..])]) + .collect(); + + for iov in &iovs { + msgs.push_back(RecvMmsgData { + iov, + cmsg_buffer: None, + }) + } + + let res: Vec> = + recvmmsg(rsock, &mut msgs, MsgFlags::MSG_DONTWAIT, None) + .expect("recvmmsg"); + assert_eq!(res.len(), NUM_MESSAGES_SENT); + + for RecvMsg { address, bytes, .. } in res.into_iter() { + assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap()); + assert_eq!(DATA.len(), bytes); + } + + for buf in &receive_buffers[..NUM_MESSAGES_SENT] { + assert_eq!(&buf[..DATA.len()], DATA); + } + } + + #[test] + pub fn udp_inet6() { + let addr = std::net::Ipv6Addr::from_str("::1").unwrap(); + let rport = 6789; + let rstd_sa = SocketAddrV6::new(addr, rport, 0, 0); + let raddr = SockaddrIn6::from(rstd_sa); + let sport = 6790; + let sstd_sa = SocketAddrV6::new(addr, sport, 0, 0); + let saddr = SockaddrIn6::from(sstd_sa); + let rsock = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("receive socket failed"); + match bind(rsock, &raddr) { + Err(Errno::EADDRNOTAVAIL) => { + println!("IPv6 not available, skipping test."); + return; + } + Err(e) => panic!("bind: {}", e), + Ok(()) => (), + } + let ssock = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + bind(ssock, &saddr).unwrap(); + let from = sendrecv( + rsock, + ssock, + move |s, m, flags| sendto(s, m, &raddr, flags), + |_, _| {}, + ); + assert_eq!(AddressFamily::Inet6, from.unwrap().family().unwrap()); + let osent_addr = from.unwrap(); + let sent_addr = osent_addr.as_sockaddr_in6().unwrap(); + assert_eq!(sent_addr.ip(), addr); + assert_eq!(sent_addr.port(), sport); + } +} + +// Test error handling of our recvmsg wrapper +#[test] +pub fn test_recvmsg_ebadf() { + use nix::errno::Errno; + use nix::sys::socket::{recvmsg, MsgFlags}; + use std::io::IoSliceMut; + + let mut buf = [0u8; 5]; + let mut iov = [IoSliceMut::new(&mut buf[..])]; + + let fd = -1; // Bad file descriptor + let r = recvmsg::<()>(fd, &mut iov, None, MsgFlags::empty()); + + assert_eq!(r.err().unwrap(), Errno::EBADF); +} + +// Disable the test on emulated platforms due to a bug in QEMU versions < +// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808 +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_scm_rights() { + use nix::sys::socket::{ + recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage, + ControlMessageOwned, MsgFlags, SockFlag, SockType, + }; + use nix::unistd::{close, pipe, read, write}; + use std::io::{IoSlice, IoSliceMut}; + + let (fd1, fd2) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + let (r, w) = pipe().unwrap(); + let mut received_r: Option = None; + + { + let iov = [IoSlice::new(b"hello")]; + let fds = [r]; + let cmsg = ControlMessage::ScmRights(&fds); + assert_eq!( + sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), + 5 + ); + close(r).unwrap(); + close(fd1).unwrap(); + } + + { + let mut buf = [0u8; 5]; + + let mut iov = [IoSliceMut::new(&mut buf[..])]; + let mut cmsgspace = cmsg_space!([RawFd; 1]); + let msg = recvmsg::<()>( + fd2, + &mut iov, + Some(&mut cmsgspace), + MsgFlags::empty(), + ) + .unwrap(); + + for cmsg in msg.cmsgs() { + if let ControlMessageOwned::ScmRights(fd) = cmsg { + assert_eq!(received_r, None); + assert_eq!(fd.len(), 1); + received_r = Some(fd[0]); + } else { + panic!("unexpected cmsg"); + } + } + assert_eq!(msg.bytes, 5); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + close(fd2).unwrap(); + } + + let received_r = received_r.expect("Did not receive passed fd"); + // Ensure that the received file descriptor works + write(w, b"world").unwrap(); + let mut buf = [0u8; 5]; + read(received_r, &mut buf).unwrap(); + assert_eq!(&buf[..], b"world"); + close(received_r).unwrap(); + close(w).unwrap(); +} + +// Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross +#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_af_alg_cipher() { + use nix::sys::socket::sockopt::AlgSetKey; + use nix::sys::socket::{ + accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr, + ControlMessage, MsgFlags, SockFlag, SockType, + }; + use nix::unistd::read; + use std::io::IoSlice; + + skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352"); + // Travis's seccomp profile blocks AF_ALG + // https://docs.docker.com/engine/security/seccomp/ + skip_if_seccomp!(test_af_alg_cipher); + + let alg_type = "skcipher"; + let alg_name = "ctr-aes-aesni"; + // 256-bits secret key + let key = vec![0u8; 32]; + // 16-bytes IV + let iv_len = 16; + let iv = vec![1u8; iv_len]; + // 256-bytes plain payload + let payload_len = 256; + let payload = vec![2u8; payload_len]; + + let sock = socket( + AddressFamily::Alg, + SockType::SeqPacket, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + let sockaddr = AlgAddr::new(alg_type, alg_name); + bind(sock, &sockaddr).expect("bind failed"); + + assert_eq!(sockaddr.alg_name().to_string_lossy(), alg_name); + assert_eq!(sockaddr.alg_type().to_string_lossy(), alg_type); + + setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt"); + let session_socket = accept(sock).expect("accept failed"); + + let msgs = [ + ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT), + ControlMessage::AlgSetIv(iv.as_slice()), + ]; + let iov = IoSlice::new(&payload); + sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) + .expect("sendmsg encrypt"); + + // allocate buffer for encrypted data + let mut encrypted = vec![0u8; payload_len]; + let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt"); + assert_eq!(num_bytes, payload_len); + + let iov = IoSlice::new(&encrypted); + + let iv = vec![1u8; iv_len]; + + let msgs = [ + ControlMessage::AlgSetOp(&libc::ALG_OP_DECRYPT), + ControlMessage::AlgSetIv(iv.as_slice()), + ]; + sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) + .expect("sendmsg decrypt"); + + // allocate buffer for decrypted data + let mut decrypted = vec![0u8; payload_len]; + let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt"); + + assert_eq!(num_bytes, payload_len); + assert_eq!(decrypted, payload); +} + +// Disable the test on emulated platforms due to not enabled support of AF_ALG +// in QEMU from rust cross +#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_af_alg_aead() { + use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT}; + use nix::fcntl::{fcntl, FcntlArg, OFlag}; + use nix::sys::socket::sockopt::{AlgSetAeadAuthSize, AlgSetKey}; + use nix::sys::socket::{ + accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr, + ControlMessage, MsgFlags, SockFlag, SockType, + }; + use nix::unistd::{close, read}; + use std::io::IoSlice; + + skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352"); + // Travis's seccomp profile blocks AF_ALG + // https://docs.docker.com/engine/security/seccomp/ + skip_if_seccomp!(test_af_alg_aead); + + let auth_size = 4usize; + let assoc_size = 16u32; + + let alg_type = "aead"; + let alg_name = "gcm(aes)"; + // 256-bits secret key + let key = vec![0u8; 32]; + // 12-bytes IV + let iv_len = 12; + let iv = vec![1u8; iv_len]; + // 256-bytes plain payload + let payload_len = 256; + let mut payload = + vec![2u8; payload_len + (assoc_size as usize) + auth_size]; + + for i in 0..assoc_size { + payload[i as usize] = 10; + } + + let len = payload.len(); + + for i in 0..auth_size { + payload[len - 1 - i] = 0; + } + + let sock = socket( + AddressFamily::Alg, + SockType::SeqPacket, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + let sockaddr = AlgAddr::new(alg_type, alg_name); + bind(sock, &sockaddr).expect("bind failed"); + + setsockopt(sock, AlgSetAeadAuthSize, &auth_size) + .expect("setsockopt AlgSetAeadAuthSize"); + setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt AlgSetKey"); + let session_socket = accept(sock).expect("accept failed"); + + let msgs = [ + ControlMessage::AlgSetOp(&ALG_OP_ENCRYPT), + ControlMessage::AlgSetIv(iv.as_slice()), + ControlMessage::AlgSetAeadAssoclen(&assoc_size), + ]; + + let iov = IoSlice::new(&payload); + sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) + .expect("sendmsg encrypt"); + + // allocate buffer for encrypted data + let mut encrypted = + vec![0u8; (assoc_size as usize) + payload_len + auth_size]; + let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt"); + assert_eq!(num_bytes, payload_len + auth_size + (assoc_size as usize)); + close(session_socket).expect("close"); + + for i in 0..assoc_size { + encrypted[i as usize] = 10; + } + + let iov = IoSlice::new(&encrypted); + + let iv = vec![1u8; iv_len]; + + let session_socket = accept(sock).expect("accept failed"); + + let msgs = [ + ControlMessage::AlgSetOp(&ALG_OP_DECRYPT), + ControlMessage::AlgSetIv(iv.as_slice()), + ControlMessage::AlgSetAeadAssoclen(&assoc_size), + ]; + sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) + .expect("sendmsg decrypt"); + + // allocate buffer for decrypted data + let mut decrypted = + vec![0u8; payload_len + (assoc_size as usize) + auth_size]; + // Starting with kernel 4.9, the interface changed slightly such that the + // authentication tag memory is only needed in the output buffer for encryption + // and in the input buffer for decryption. + // Do not block on read, as we may have fewer bytes than buffer size + fcntl(session_socket, FcntlArg::F_SETFL(OFlag::O_NONBLOCK)) + .expect("fcntl non_blocking"); + let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt"); + + assert!(num_bytes >= payload_len + (assoc_size as usize)); + assert_eq!( + decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))], + payload[(assoc_size as usize)..payload_len + (assoc_size as usize)] + ); +} + +// Verify `ControlMessage::Ipv4PacketInfo` for `sendmsg`. +// This creates a (udp) socket bound to localhost, then sends a message to +// itself but uses Ipv4PacketInfo to force the source address to be localhost. +// +// This would be a more interesting test if we could assume that the test host +// has more than one IP address (since we could select a different address to +// test from). +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "netbsd"))] +#[test] +pub fn test_sendmsg_ipv4packetinfo() { + use cfg_if::cfg_if; + use nix::sys::socket::{ + bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags, + SockFlag, SockType, SockaddrIn, + }; + use std::io::IoSlice; + + let sock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + let sock_addr = SockaddrIn::new(127, 0, 0, 1, 4000); + + bind(sock, &sock_addr).expect("bind failed"); + + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + cfg_if! { + if #[cfg(target_os = "netbsd")] { + let pi = libc::in_pktinfo { + ipi_ifindex: 0, /* Unspecified interface */ + ipi_addr: libc::in_addr { s_addr: 0 }, + }; + } else { + let pi = libc::in_pktinfo { + ipi_ifindex: 0, /* Unspecified interface */ + ipi_addr: libc::in_addr { s_addr: 0 }, + ipi_spec_dst: sock_addr.as_ref().sin_addr, + }; + } + } + + let cmsg = [ControlMessage::Ipv4PacketInfo(&pi)]; + + sendmsg(sock, &iov, &cmsg, MsgFlags::empty(), Some(&sock_addr)) + .expect("sendmsg"); +} + +// Verify `ControlMessage::Ipv6PacketInfo` for `sendmsg`. +// This creates a (udp) socket bound to ip6-localhost, then sends a message to +// itself but uses Ipv6PacketInfo to force the source address to be +// ip6-localhost. +// +// This would be a more interesting test if we could assume that the test host +// has more than one IP address (since we could select a different address to +// test from). +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "freebsd" +))] +#[test] +pub fn test_sendmsg_ipv6packetinfo() { + use nix::errno::Errno; + use nix::sys::socket::{ + bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags, + SockFlag, SockType, SockaddrIn6, + }; + use std::io::IoSlice; + + let sock = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap(); + let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa); + + if let Err(Errno::EADDRNOTAVAIL) = bind(sock, &sock_addr) { + println!("IPv6 not available, skipping test."); + return; + } + + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + let pi = libc::in6_pktinfo { + ipi6_ifindex: 0, /* Unspecified interface */ + ipi6_addr: sock_addr.as_ref().sin6_addr, + }; + + let cmsg = [ControlMessage::Ipv6PacketInfo(&pi)]; + + sendmsg::( + sock, + &iov, + &cmsg, + MsgFlags::empty(), + Some(&sock_addr), + ) + .expect("sendmsg"); +} + +// Verify that ControlMessage::Ipv4SendSrcAddr works for sendmsg. This +// creates a UDP socket bound to all local interfaces (0.0.0.0). It then +// sends message to itself at 127.0.0.1 while explicitly specifying +// 127.0.0.1 as the source address through an Ipv4SendSrcAddr +// (IP_SENDSRCADDR) control message. +// +// Note that binding to 0.0.0.0 is *required* on FreeBSD; sendmsg +// returns EINVAL otherwise. (See FreeBSD's ip(4) man page.) +#[cfg(any( + target_os = "netbsd", + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", +))] +#[test] +pub fn test_sendmsg_ipv4sendsrcaddr() { + use nix::sys::socket::{ + bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags, + SockFlag, SockType, SockaddrIn, + }; + use std::io::IoSlice; + + let sock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + let unspec_sock_addr = SockaddrIn::new(0, 0, 0, 0, 0); + bind(sock, &unspec_sock_addr).expect("bind failed"); + let bound_sock_addr: SockaddrIn = getsockname(sock).unwrap(); + let localhost_sock_addr: SockaddrIn = + SockaddrIn::new(127, 0, 0, 1, bound_sock_addr.port()); + + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + let cmsg = [ControlMessage::Ipv4SendSrcAddr( + &localhost_sock_addr.as_ref().sin_addr, + )]; + + sendmsg( + sock, + &iov, + &cmsg, + MsgFlags::empty(), + Some(&localhost_sock_addr), + ) + .expect("sendmsg"); +} + +/// Tests that passing multiple fds using a single `ControlMessage` works. +// Disable the test on emulated platforms due to a bug in QEMU versions < +// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808 +#[cfg_attr(qemu, ignore)] +#[test] +fn test_scm_rights_single_cmsg_multiple_fds() { + use nix::sys::socket::{ + recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags, + }; + use std::io::{IoSlice, IoSliceMut}; + use std::os::unix::io::{AsRawFd, RawFd}; + use std::os::unix::net::UnixDatagram; + use std::thread; + + let (send, receive) = UnixDatagram::pair().unwrap(); + let thread = thread::spawn(move || { + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + + let mut space = cmsg_space!([RawFd; 2]); + let msg = recvmsg::<()>( + receive.as_raw_fd(), + &mut iovec, + Some(&mut space), + MsgFlags::empty(), + ) + .unwrap(); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + + let mut cmsgs = msg.cmsgs(); + match cmsgs.next() { + Some(ControlMessageOwned::ScmRights(fds)) => { + assert_eq!( + fds.len(), + 2, + "unexpected fd count (expected 2 fds, got {})", + fds.len() + ); + } + _ => panic!(), + } + assert!(cmsgs.next().is_none(), "unexpected control msg"); + + assert_eq!(msg.bytes, 8); + assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + }); + + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout + let cmsg = [ControlMessage::ScmRights(&fds)]; + sendmsg::<()>(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None) + .unwrap(); + thread.join().unwrap(); +} + +// Verify `sendmsg` builds a valid `msghdr` when passing an empty +// `cmsgs` argument. This should result in a msghdr with a nullptr +// msg_control field and a msg_controllen of 0 when calling into the +// raw `sendmsg`. +#[test] +pub fn test_sendmsg_empty_cmsgs() { + use nix::sys::socket::{ + recvmsg, sendmsg, socketpair, AddressFamily, MsgFlags, SockFlag, + SockType, + }; + use nix::unistd::close; + use std::io::{IoSlice, IoSliceMut}; + + let (fd1, fd2) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + + { + let iov = [IoSlice::new(b"hello")]; + assert_eq!( + sendmsg::<()>(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), + 5 + ); + close(fd1).unwrap(); + } + + { + let mut buf = [0u8; 5]; + let mut iov = [IoSliceMut::new(&mut buf[..])]; + + let mut cmsgspace = cmsg_space!([RawFd; 1]); + let msg = recvmsg::<()>( + fd2, + &mut iov, + Some(&mut cmsgspace), + MsgFlags::empty(), + ) + .unwrap(); + + for _ in msg.cmsgs() { + panic!("unexpected cmsg"); + } + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + assert_eq!(msg.bytes, 5); + close(fd2).unwrap(); + } +} + +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "freebsd", + target_os = "dragonfly", +))] +#[test] +fn test_scm_credentials() { + use nix::sys::socket::{ + recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage, + ControlMessageOwned, MsgFlags, SockFlag, SockType, UnixCredentials, + }; + #[cfg(any(target_os = "android", target_os = "linux"))] + use nix::sys::socket::{setsockopt, sockopt::PassCred}; + use nix::unistd::{close, getgid, getpid, getuid}; + use std::io::{IoSlice, IoSliceMut}; + + let (send, recv) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + #[cfg(any(target_os = "android", target_os = "linux"))] + setsockopt(recv, PassCred, &true).unwrap(); + + { + let iov = [IoSlice::new(b"hello")]; + #[cfg(any(target_os = "android", target_os = "linux"))] + let cred = UnixCredentials::new(); + #[cfg(any(target_os = "android", target_os = "linux"))] + let cmsg = ControlMessage::ScmCredentials(&cred); + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + let cmsg = ControlMessage::ScmCreds; + assert_eq!( + sendmsg::<()>(send, &iov, &[cmsg], MsgFlags::empty(), None) + .unwrap(), + 5 + ); + close(send).unwrap(); + } + + { + let mut buf = [0u8; 5]; + let mut iov = [IoSliceMut::new(&mut buf[..])]; + + let mut cmsgspace = cmsg_space!(UnixCredentials); + let msg = recvmsg::<()>( + recv, + &mut iov, + Some(&mut cmsgspace), + MsgFlags::empty(), + ) + .unwrap(); + let mut received_cred = None; + + for cmsg in msg.cmsgs() { + let cred = match cmsg { + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessageOwned::ScmCredentials(cred) => cred, + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + ControlMessageOwned::ScmCreds(cred) => cred, + other => panic!("unexpected cmsg {:?}", other), + }; + assert!(received_cred.is_none()); + assert_eq!(cred.pid(), getpid().as_raw()); + assert_eq!(cred.uid(), getuid().as_raw()); + assert_eq!(cred.gid(), getgid().as_raw()); + received_cred = Some(cred); + } + received_cred.expect("no creds received"); + assert_eq!(msg.bytes, 5); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + close(recv).unwrap(); + } +} + +/// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single +/// `sendmsg` call. +#[cfg(any(target_os = "android", target_os = "linux"))] +// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation +// see https://bugs.launchpad.net/qemu/+bug/1781280 +#[cfg_attr(qemu, ignore)] +#[test] +fn test_scm_credentials_and_rights() { + let space = cmsg_space!(libc::ucred, RawFd); + test_impl_scm_credentials_and_rights(space); +} + +/// Ensure that passing a an oversized control message buffer to recvmsg +/// still works. +#[cfg(any(target_os = "android", target_os = "linux"))] +// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation +// see https://bugs.launchpad.net/qemu/+bug/1781280 +#[cfg_attr(qemu, ignore)] +#[test] +fn test_too_large_cmsgspace() { + let space = vec![0u8; 1024]; + test_impl_scm_credentials_and_rights(space); +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_impl_scm_credentials_and_rights(mut space: Vec) { + use libc::ucred; + use nix::sys::socket::sockopt::PassCred; + use nix::sys::socket::{ + recvmsg, sendmsg, setsockopt, socketpair, ControlMessage, + ControlMessageOwned, MsgFlags, SockFlag, SockType, + }; + use nix::unistd::{close, getgid, getpid, getuid, pipe, write}; + use std::io::{IoSlice, IoSliceMut}; + + let (send, recv) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + setsockopt(recv, PassCred, &true).unwrap(); + + let (r, w) = pipe().unwrap(); + let mut received_r: Option = None; + + { + let iov = [IoSlice::new(b"hello")]; + let cred = ucred { + pid: getpid().as_raw(), + uid: getuid().as_raw(), + gid: getgid().as_raw(), + } + .into(); + let fds = [r]; + let cmsgs = [ + ControlMessage::ScmCredentials(&cred), + ControlMessage::ScmRights(&fds), + ]; + assert_eq!( + sendmsg::<()>(send, &iov, &cmsgs, MsgFlags::empty(), None).unwrap(), + 5 + ); + close(r).unwrap(); + close(send).unwrap(); + } + + { + let mut buf = [0u8; 5]; + let mut iov = [IoSliceMut::new(&mut buf[..])]; + let msg = + recvmsg::<()>(recv, &mut iov, Some(&mut space), MsgFlags::empty()) + .unwrap(); + let mut received_cred = None; + + assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs"); + + for cmsg in msg.cmsgs() { + match cmsg { + ControlMessageOwned::ScmRights(fds) => { + assert_eq!(received_r, None, "already received fd"); + assert_eq!(fds.len(), 1); + received_r = Some(fds[0]); + } + ControlMessageOwned::ScmCredentials(cred) => { + assert!(received_cred.is_none()); + assert_eq!(cred.pid(), getpid().as_raw()); + assert_eq!(cred.uid(), getuid().as_raw()); + assert_eq!(cred.gid(), getgid().as_raw()); + received_cred = Some(cred); + } + _ => panic!("unexpected cmsg"), + } + } + received_cred.expect("no creds received"); + assert_eq!(msg.bytes, 5); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + close(recv).unwrap(); + } + + let received_r = received_r.expect("Did not receive passed fd"); + // Ensure that the received file descriptor works + write(w, b"world").unwrap(); + let mut buf = [0u8; 5]; + read(received_r, &mut buf).unwrap(); + assert_eq!(&buf[..], b"world"); + close(received_r).unwrap(); + close(w).unwrap(); +} + +// Test creating and using named unix domain sockets +#[test] +pub fn test_unixdomain() { + use nix::sys::socket::{accept, bind, connect, listen, socket, UnixAddr}; + use nix::sys::socket::{SockFlag, SockType}; + use nix::unistd::{close, read, write}; + use std::thread; + + let tempdir = tempfile::tempdir().unwrap(); + let sockname = tempdir.path().join("sock"); + let s1 = socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + let sockaddr = UnixAddr::new(&sockname).unwrap(); + bind(s1, &sockaddr).expect("bind failed"); + listen(s1, 10).expect("listen failed"); + + let thr = thread::spawn(move || { + let s2 = socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + connect(s2, &sockaddr).expect("connect failed"); + write(s2, b"hello").expect("write failed"); + close(s2).unwrap(); + }); + + let s3 = accept(s1).expect("accept failed"); + + let mut buf = [0; 5]; + read(s3, &mut buf).unwrap(); + close(s3).unwrap(); + close(s1).unwrap(); + thr.join().unwrap(); + + assert_eq!(&buf[..], b"hello"); +} + +// Test creating and using named system control sockets +#[cfg(any(target_os = "macos", target_os = "ios"))] +#[test] +pub fn test_syscontrol() { + use nix::errno::Errno; + use nix::sys::socket::{ + socket, SockFlag, SockProtocol, SockType, SysControlAddr, + }; + + let fd = socket( + AddressFamily::System, + SockType::Datagram, + SockFlag::empty(), + SockProtocol::KextControl, + ) + .expect("socket failed"); + SysControlAddr::from_name(fd, "com.apple.net.utun_control", 0) + .expect("resolving sys_control name failed"); + assert_eq!( + SysControlAddr::from_name(fd, "foo.bar.lol", 0).err(), + Some(Errno::ENOENT) + ); + + // requires root privileges + // connect(fd, &sockaddr).expect("connect failed"); +} + +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +fn loopback_address( + family: AddressFamily, +) -> Option { + use nix::ifaddrs::getifaddrs; + use nix::net::if_::*; + use nix::sys::socket::SockaddrLike; + use std::io; + use std::io::Write; + + let mut addrs = match getifaddrs() { + Ok(iter) => iter, + Err(e) => { + let stdioerr = io::stderr(); + let mut handle = stdioerr.lock(); + writeln!(handle, "getifaddrs: {:?}", e).unwrap(); + return None; + } + }; + // return first address matching family + addrs.find(|ifaddr| { + ifaddr.flags.contains(InterfaceFlags::IFF_LOOPBACK) + && ifaddr.address.as_ref().and_then(SockaddrLike::family) + == Some(family) + }) +} + +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", +))] +// qemu doesn't seem to be emulating this correctly in these architectures +#[cfg_attr( + all( + qemu, + any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc64", + ) + ), + ignore +)] +#[test] +pub fn test_recv_ipv4pktinfo() { + use nix::net::if_::*; + use nix::sys::socket::sockopt::Ipv4PacketInfo; + use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; + use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet); + let (lo_name, lo) = match lo_ifaddr { + Some(ifaddr) => ( + ifaddr.interface_name, + ifaddr.address.expect("Expect IPv4 address on interface"), + ), + None => return, + }; + let receive = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); + let sa: SockaddrIn = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv4PacketInfo, &true).expect("setsockopt failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) + .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + + let mut space = cmsg_space!(libc::in_pktinfo); + let msg = recvmsg::<()>( + receive, + &mut iovec, + Some(&mut space), + MsgFlags::empty(), + ) + .expect("recvmsg failed"); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + + let mut cmsgs = msg.cmsgs(); + if let Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) = cmsgs.next() + { + let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); + assert_eq!( + pktinfo.ipi_ifindex as libc::c_uint, i, + "unexpected ifindex (expected {}, got {})", + i, pktinfo.ipi_ifindex + ); + } + assert!(cmsgs.next().is_none(), "unexpected additional control msg"); + assert_eq!(msg.bytes, 8); + assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } +} + +#[cfg(any( + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +// qemu doesn't seem to be emulating this correctly in these architectures +#[cfg_attr( + all( + qemu, + any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc64", + ) + ), + ignore +)] +#[test] +pub fn test_recvif() { + use nix::net::if_::*; + use nix::sys::socket::sockopt::{Ipv4RecvDstAddr, Ipv4RecvIf}; + use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; + use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet); + let (lo_name, lo) = match lo_ifaddr { + Some(ifaddr) => ( + ifaddr.interface_name, + ifaddr.address.expect("Expect IPv4 address on interface"), + ), + None => return, + }; + let receive = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); + let sa: SockaddrIn = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv4RecvIf, &true) + .expect("setsockopt IP_RECVIF failed"); + setsockopt(receive, Ipv4RecvDstAddr, &true) + .expect("setsockopt IP_RECVDSTADDR failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) + .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + let mut space = cmsg_space!(libc::sockaddr_dl, libc::in_addr); + let msg = recvmsg::<()>( + receive, + &mut iovec, + Some(&mut space), + MsgFlags::empty(), + ) + .expect("recvmsg failed"); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs"); + + let mut rx_recvif = false; + let mut rx_recvdstaddr = false; + for cmsg in msg.cmsgs() { + match cmsg { + ControlMessageOwned::Ipv4RecvIf(dl) => { + rx_recvif = true; + let i = if_nametoindex(lo_name.as_bytes()) + .expect("if_nametoindex"); + assert_eq!( + dl.sdl_index as libc::c_uint, i, + "unexpected ifindex (expected {}, got {})", + i, dl.sdl_index + ); + } + ControlMessageOwned::Ipv4RecvDstAddr(addr) => { + rx_recvdstaddr = true; + if let Some(sin) = lo.as_sockaddr_in() { + assert_eq!(sin.as_ref().sin_addr.s_addr, + addr.s_addr, + "unexpected destination address (expected {}, got {})", + sin.as_ref().sin_addr.s_addr, + addr.s_addr); + } else { + panic!("unexpected Sockaddr"); + } + } + _ => panic!("unexpected additional control msg"), + } + } + assert!(rx_recvif); + assert!(rx_recvdstaddr); + assert_eq!(msg.bytes, 8); + assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } +} + +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_recvif_ipv4() { + use nix::sys::socket::sockopt::Ipv4OrigDstAddr; + use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; + use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet); + let (_lo_name, lo) = match lo_ifaddr { + Some(ifaddr) => ( + ifaddr.interface_name, + ifaddr.address.expect("Expect IPv4 address on interface"), + ), + None => return, + }; + let receive = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); + let sa: SockaddrIn = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv4OrigDstAddr, &true) + .expect("setsockopt IP_ORIGDSTADDR failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) + .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + let mut space = cmsg_space!(libc::sockaddr_in); + let msg = recvmsg::<()>( + receive, + &mut iovec, + Some(&mut space), + MsgFlags::empty(), + ) + .expect("recvmsg failed"); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs"); + + let mut rx_recvorigdstaddr = false; + for cmsg in msg.cmsgs() { + match cmsg { + ControlMessageOwned::Ipv4OrigDstAddr(addr) => { + rx_recvorigdstaddr = true; + if let Some(sin) = lo.as_sockaddr_in() { + assert_eq!(sin.as_ref().sin_addr.s_addr, + addr.sin_addr.s_addr, + "unexpected destination address (expected {}, got {})", + sin.as_ref().sin_addr.s_addr, + addr.sin_addr.s_addr); + } else { + panic!("unexpected Sockaddr"); + } + } + _ => panic!("unexpected additional control msg"), + } + } + assert!(rx_recvorigdstaddr); + assert_eq!(msg.bytes, 8); + assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } +} + +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[cfg_attr(qemu, ignore)] +#[test] +pub fn test_recvif_ipv6() { + use nix::sys::socket::sockopt::Ipv6OrigDstAddr; + use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; + use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet6); + let (_lo_name, lo) = match lo_ifaddr { + Some(ifaddr) => ( + ifaddr.interface_name, + ifaddr.address.expect("Expect IPv6 address on interface"), + ), + None => return, + }; + let receive = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); + let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv6OrigDstAddr, &true) + .expect("setsockopt IP_ORIGDSTADDR failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) + .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + let mut space = cmsg_space!(libc::sockaddr_in6); + let msg = recvmsg::<()>( + receive, + &mut iovec, + Some(&mut space), + MsgFlags::empty(), + ) + .expect("recvmsg failed"); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs"); + + let mut rx_recvorigdstaddr = false; + for cmsg in msg.cmsgs() { + match cmsg { + ControlMessageOwned::Ipv6OrigDstAddr(addr) => { + rx_recvorigdstaddr = true; + if let Some(sin) = lo.as_sockaddr_in6() { + assert_eq!(sin.as_ref().sin6_addr.s6_addr, + addr.sin6_addr.s6_addr, + "unexpected destination address (expected {:?}, got {:?})", + sin.as_ref().sin6_addr.s6_addr, + addr.sin6_addr.s6_addr); + } else { + panic!("unexpected Sockaddr"); + } + } + _ => panic!("unexpected additional control msg"), + } + } + assert!(rx_recvorigdstaddr); + assert_eq!(msg.bytes, 8); + assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } +} + +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +// qemu doesn't seem to be emulating this correctly in these architectures +#[cfg_attr( + all( + qemu, + any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "powerpc64", + ) + ), + ignore +)] +#[test] +pub fn test_recv_ipv6pktinfo() { + use nix::net::if_::*; + use nix::sys::socket::sockopt::Ipv6RecvPacketInfo; + use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; + use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet6); + let (lo_name, lo) = match lo_ifaddr { + Some(ifaddr) => ( + ifaddr.interface_name, + ifaddr.address.expect("Expect IPv6 address on interface"), + ), + None => return, + }; + let receive = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); + let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv6RecvPacketInfo, &true).expect("setsockopt failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) + .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + + let mut space = cmsg_space!(libc::in6_pktinfo); + let msg = recvmsg::<()>( + receive, + &mut iovec, + Some(&mut space), + MsgFlags::empty(), + ) + .expect("recvmsg failed"); + assert!(!msg + .flags + .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + + let mut cmsgs = msg.cmsgs(); + if let Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) = cmsgs.next() + { + let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); + assert_eq!( + pktinfo.ipi6_ifindex as libc::c_uint, i, + "unexpected ifindex (expected {}, got {})", + i, pktinfo.ipi6_ifindex + ); + } + assert!(cmsgs.next().is_none(), "unexpected additional control msg"); + assert_eq!(msg.bytes, 8); + assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(graviton, ignore = "Not supported by the CI environment")] +#[test] +pub fn test_vsock() { + use nix::errno::Errno; + use nix::sys::socket::{ + bind, connect, listen, socket, AddressFamily, SockFlag, SockType, + VsockAddr, + }; + use nix::unistd::close; + use std::thread; + + let port: u32 = 3000; + + let s1 = socket( + AddressFamily::Vsock, + SockType::Stream, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + // VMADDR_CID_HYPERVISOR is reserved, so we expect an EADDRNOTAVAIL error. + let sockaddr_hv = VsockAddr::new(libc::VMADDR_CID_HYPERVISOR, port); + assert_eq!(bind(s1, &sockaddr_hv).err(), Some(Errno::EADDRNOTAVAIL)); + + let sockaddr_any = VsockAddr::new(libc::VMADDR_CID_ANY, port); + assert_eq!(bind(s1, &sockaddr_any), Ok(())); + listen(s1, 10).expect("listen failed"); + + let thr = thread::spawn(move || { + let cid: u32 = libc::VMADDR_CID_HOST; + + let s2 = socket( + AddressFamily::Vsock, + SockType::Stream, + SockFlag::empty(), + None, + ) + .expect("socket failed"); + + let sockaddr_host = VsockAddr::new(cid, port); + + // The current implementation does not support loopback devices, so, + // for now, we expect a failure on the connect. + assert_ne!(connect(s2, &sockaddr_host), Ok(())); + + close(s2).unwrap(); + }); + + close(s1).unwrap(); + thr.join().unwrap(); +} + +// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +#[cfg(all(target_os = "linux"))] +#[test] +fn test_recvmsg_timestampns() { + use nix::sys::socket::*; + use nix::sys::time::*; + use std::io::{IoSlice, IoSliceMut}; + use std::time::*; + + // Set up + let message = "OhayÅ!".as_bytes(); + let in_socket = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap(); + let localhost = SockaddrIn::new(127, 0, 0, 1, 0); + bind(in_socket, &localhost).unwrap(); + let address: SockaddrIn = getsockname(in_socket).unwrap(); + // Get initial time + let time0 = SystemTime::now(); + // Send the message + let iov = [IoSlice::new(message)]; + let flags = MsgFlags::empty(); + let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap(); + assert_eq!(message.len(), l); + // Receive the message + let mut buffer = vec![0u8; message.len()]; + let mut cmsgspace = nix::cmsg_space!(TimeSpec); + + let mut iov = [IoSliceMut::new(&mut buffer)]; + let r = recvmsg::<()>(in_socket, &mut iov, Some(&mut cmsgspace), flags) + .unwrap(); + let rtime = match r.cmsgs().next() { + Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime, + Some(_) => panic!("Unexpected control message"), + None => panic!("No control message"), + }; + // Check the final time + let time1 = SystemTime::now(); + // the packet's received timestamp should lie in-between the two system + // times, unless the system clock was adjusted in the meantime. + let rduration = + Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32); + assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration); + assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap()); + // Close socket + nix::unistd::close(in_socket).unwrap(); +} + +// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +#[cfg(all(target_os = "linux"))] +#[test] +fn test_recvmmsg_timestampns() { + use nix::sys::socket::*; + use nix::sys::time::*; + use std::io::{IoSlice, IoSliceMut}; + use std::time::*; + + // Set up + let message = "OhayÅ!".as_bytes(); + let in_socket = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap(); + let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap(); + bind(in_socket, &localhost).unwrap(); + let address: SockaddrIn = getsockname(in_socket).unwrap(); + // Get initial time + let time0 = SystemTime::now(); + // Send the message + let iov = [IoSlice::new(message)]; + let flags = MsgFlags::empty(); + let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap(); + assert_eq!(message.len(), l); + // Receive the message + let mut buffer = vec![0u8; message.len()]; + let mut cmsgspace = nix::cmsg_space!(TimeSpec); + let iov = [IoSliceMut::new(&mut buffer)]; + let mut data = vec![RecvMmsgData { + iov, + cmsg_buffer: Some(&mut cmsgspace), + }]; + let r: Vec> = + recvmmsg(in_socket, &mut data, flags, None).unwrap(); + let rtime = match r[0].cmsgs().next() { + Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime, + Some(_) => panic!("Unexpected control message"), + None => panic!("No control message"), + }; + // Check the final time + let time1 = SystemTime::now(); + // the packet's received timestamp should lie in-between the two system + // times, unless the system clock was adjusted in the meantime. + let rduration = + Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32); + assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration); + assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap()); + // Close socket + nix::unistd::close(in_socket).unwrap(); +} + +// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[test] +fn test_recvmsg_rxq_ovfl() { + use nix::sys::socket::sockopt::{RcvBuf, RxqOvfl}; + use nix::sys::socket::*; + use nix::Error; + use std::io::{IoSlice, IoSliceMut}; + + let message = [0u8; 2048]; + let bufsize = message.len() * 2; + + let in_socket = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + let out_socket = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + + let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap(); + bind(in_socket, &localhost).unwrap(); + + let address: SockaddrIn = getsockname(in_socket).unwrap(); + connect(out_socket, &address).unwrap(); + + // Set SO_RXQ_OVFL flag. + setsockopt(in_socket, RxqOvfl, &1).unwrap(); + + // Set the receiver buffer size to hold only 2 messages. + setsockopt(in_socket, RcvBuf, &bufsize).unwrap(); + + let mut drop_counter = 0; + + for _ in 0..2 { + let iov = [IoSlice::new(&message)]; + let flags = MsgFlags::empty(); + + // Send the 3 messages (the receiver buffer can only hold 2 messages) + // to create an overflow. + for _ in 0..3 { + let l = + sendmsg(out_socket, &iov, &[], flags, Some(&address)).unwrap(); + assert_eq!(message.len(), l); + } + + // Receive the message and check the drop counter if any. + loop { + let mut buffer = vec![0u8; message.len()]; + let mut cmsgspace = nix::cmsg_space!(u32); + + let mut iov = [IoSliceMut::new(&mut buffer)]; + + match recvmsg::<()>( + in_socket, + &mut iov, + Some(&mut cmsgspace), + MsgFlags::MSG_DONTWAIT, + ) { + Ok(r) => { + drop_counter = match r.cmsgs().next() { + Some(ControlMessageOwned::RxqOvfl(drop_counter)) => { + drop_counter + } + Some(_) => panic!("Unexpected control message"), + None => 0, + }; + } + Err(Error::EAGAIN) => { + break; + } + _ => { + panic!("unknown recvmsg() error"); + } + } + } + } + + // One packet lost. + assert_eq!(drop_counter, 1); + + // Close sockets + nix::unistd::close(in_socket).unwrap(); + nix::unistd::close(out_socket).unwrap(); +} + +#[cfg(any(target_os = "linux", target_os = "android",))] +mod linux_errqueue { + use super::FromStr; + use nix::sys::socket::*; + + // Send a UDP datagram to a bogus destination address and observe an ICMP error (v4). + // + // Disable the test on QEMU because QEMU emulation of IP_RECVERR is broken (as documented on PR + // #1514). + #[cfg_attr(qemu, ignore)] + #[test] + fn test_recverr_v4() { + #[repr(u8)] + enum IcmpTypes { + DestUnreach = 3, // ICMP_DEST_UNREACH + } + #[repr(u8)] + enum IcmpUnreachCodes { + PortUnreach = 3, // ICMP_PORT_UNREACH + } + + test_recverr_impl::( + "127.0.0.1:6800", + AddressFamily::Inet, + sockopt::Ipv4RecvErr, + libc::SO_EE_ORIGIN_ICMP, + IcmpTypes::DestUnreach as u8, + IcmpUnreachCodes::PortUnreach as u8, + // Closure handles protocol-specific testing and returns generic sock_extended_err for + // protocol-independent test impl. + |cmsg| { + if let ControlMessageOwned::Ipv4RecvErr(ext_err, err_addr) = + cmsg + { + if let Some(origin) = err_addr { + // Validate that our network error originated from 127.0.0.1:0. + assert_eq!(origin.sin_family, AddressFamily::Inet as _); + assert_eq!( + origin.sin_addr.s_addr, + u32::from_be(0x7f000001) + ); + assert_eq!(origin.sin_port, 0); + } else { + panic!("Expected some error origin"); + } + *ext_err + } else { + panic!("Unexpected control message {:?}", cmsg); + } + }, + ) + } + + // Essentially the same test as v4. + // + // Disable the test on QEMU because QEMU emulation of IPV6_RECVERR is broken (as documented on + // PR #1514). + #[cfg_attr(qemu, ignore)] + #[test] + fn test_recverr_v6() { + #[repr(u8)] + enum IcmpV6Types { + DestUnreach = 1, // ICMPV6_DEST_UNREACH + } + #[repr(u8)] + enum IcmpV6UnreachCodes { + PortUnreach = 4, // ICMPV6_PORT_UNREACH + } + + test_recverr_impl::( + "[::1]:6801", + AddressFamily::Inet6, + sockopt::Ipv6RecvErr, + libc::SO_EE_ORIGIN_ICMP6, + IcmpV6Types::DestUnreach as u8, + IcmpV6UnreachCodes::PortUnreach as u8, + // Closure handles protocol-specific testing and returns generic sock_extended_err for + // protocol-independent test impl. + |cmsg| { + if let ControlMessageOwned::Ipv6RecvErr(ext_err, err_addr) = + cmsg + { + if let Some(origin) = err_addr { + // Validate that our network error originated from localhost:0. + assert_eq!( + origin.sin6_family, + AddressFamily::Inet6 as _ + ); + assert_eq!( + origin.sin6_addr.s6_addr, + std::net::Ipv6Addr::LOCALHOST.octets() + ); + assert_eq!(origin.sin6_port, 0); + } else { + panic!("Expected some error origin"); + } + *ext_err + } else { + panic!("Unexpected control message {:?}", cmsg); + } + }, + ) + } + + fn test_recverr_impl( + sa: &str, + af: AddressFamily, + opt: OPT, + ee_origin: u8, + ee_type: u8, + ee_code: u8, + testf: TESTF, + ) where + OPT: SetSockOpt, + TESTF: FnOnce(&ControlMessageOwned) -> libc::sock_extended_err, + { + use nix::errno::Errno; + use std::io::IoSliceMut; + + const MESSAGE_CONTENTS: &str = "ABCDEF"; + let std_sa = std::net::SocketAddr::from_str(sa).unwrap(); + let sock_addr = SockaddrStorage::from(std_sa); + let sock = socket(af, SockType::Datagram, SockFlag::SOCK_CLOEXEC, None) + .unwrap(); + setsockopt(sock, opt, &true).unwrap(); + if let Err(e) = sendto( + sock, + MESSAGE_CONTENTS.as_bytes(), + &sock_addr, + MsgFlags::empty(), + ) { + assert_eq!(e, Errno::EADDRNOTAVAIL); + println!("{:?} not available, skipping test.", af); + return; + } + + let mut buf = [0u8; 8]; + let mut iovec = [IoSliceMut::new(&mut buf)]; + let mut cspace = cmsg_space!(libc::sock_extended_err, SA); + + let msg = recvmsg( + sock, + &mut iovec, + Some(&mut cspace), + MsgFlags::MSG_ERRQUEUE, + ) + .unwrap(); + // The sent message / destination associated with the error is returned: + assert_eq!(msg.bytes, MESSAGE_CONTENTS.as_bytes().len()); + // recvmsg(2): "The original destination address of the datagram that caused the error is + // supplied via msg_name;" however, this is not literally true. E.g., an earlier version + // of this test used 0.0.0.0 (::0) as the destination address, which was mutated into + // 127.0.0.1 (::1). + assert_eq!(msg.address, Some(sock_addr)); + + // Check for expected control message. + let ext_err = match msg.cmsgs().next() { + Some(cmsg) => testf(&cmsg), + None => panic!("No control message"), + }; + + assert_eq!(ext_err.ee_errno, libc::ECONNREFUSED as u32); + assert_eq!(ext_err.ee_origin, ee_origin); + // ip(7): ee_type and ee_code are set from the type and code fields of the ICMP (ICMPv6) + // header. + assert_eq!(ext_err.ee_type, ee_type); + assert_eq!(ext_err.ee_code, ee_code); + // ip(7): ee_info contains the discovered MTU for EMSGSIZE errors. + assert_eq!(ext_err.ee_info, 0); + + let bytes = msg.bytes; + assert_eq!(&buf[..bytes], MESSAGE_CONTENTS.as_bytes()); + } +} + +// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +#[cfg(target_os = "linux")] +#[test] +pub fn test_txtime() { + use nix::sys::socket::{ + bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage, + MsgFlags, SockFlag, SockType, SockaddrIn, + }; + use nix::sys::time::TimeValLike; + use nix::time::{clock_gettime, ClockId}; + + require_kernel_version!(test_txtime, ">= 5.8"); + + let sock_addr = SockaddrIn::from_str("127.0.0.1:6802").unwrap(); + + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .expect("send socket failed"); + + let txtime_cfg = libc::sock_txtime { + clockid: libc::CLOCK_MONOTONIC, + flags: 0, + }; + setsockopt(ssock, sockopt::TxTime, &txtime_cfg).unwrap(); + + let rsock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + bind(rsock, &sock_addr).unwrap(); + + let sbuf = [0u8; 2048]; + let iov1 = [std::io::IoSlice::new(&sbuf)]; + + let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap(); + let delay = std::time::Duration::from_secs(1).into(); + let txtime = (now + delay).num_nanoseconds() as u64; + + let cmsg = ControlMessage::TxTime(&txtime); + sendmsg(ssock, &iov1, &[cmsg], MsgFlags::empty(), Some(&sock_addr)) + .unwrap(); + + let mut rbuf = [0u8; 2048]; + let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)]; + recvmsg::<()>(rsock, &mut iov2, None, MsgFlags::empty()).unwrap(); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_sockopt.rs b/utshell-0.5.0/vendor/nix/test/sys/test_sockopt.rs new file mode 100644 index 00000000..1dbdf19b --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_sockopt.rs @@ -0,0 +1,356 @@ +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::*; +use nix::sys::socket::{ + getsockopt, setsockopt, socket, sockopt, AddressFamily, SockFlag, + SockProtocol, SockType, +}; +use rand::{thread_rng, Rng}; + +// NB: FreeBSD supports LOCAL_PEERCRED for SOCK_SEQPACKET, but OSX does not. +#[cfg(any(target_os = "dragonfly", target_os = "freebsd",))] +#[test] +pub fn test_local_peercred_seqpacket() { + use nix::{ + sys::socket::socketpair, + unistd::{Gid, Uid}, + }; + + let (fd1, _fd2) = socketpair( + AddressFamily::Unix, + SockType::SeqPacket, + None, + SockFlag::empty(), + ) + .unwrap(); + let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap(); + assert_eq!(xucred.version(), 0); + assert_eq!(Uid::from_raw(xucred.uid()), Uid::current()); + assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current()); +} + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "ios" +))] +#[test] +pub fn test_local_peercred_stream() { + use nix::{ + sys::socket::socketpair, + unistd::{Gid, Uid}, + }; + + let (fd1, _fd2) = socketpair( + AddressFamily::Unix, + SockType::Stream, + None, + SockFlag::empty(), + ) + .unwrap(); + let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap(); + assert_eq!(xucred.version(), 0); + assert_eq!(Uid::from_raw(xucred.uid()), Uid::current()); + assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current()); +} + +#[cfg(target_os = "linux")] +#[test] +fn is_so_mark_functional() { + use nix::sys::socket::sockopt; + + require_capability!("is_so_mark_functional", CAP_NET_ADMIN); + + let s = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(s, sockopt::Mark, &1337).unwrap(); + let mark = getsockopt(s, sockopt::Mark).unwrap(); + assert_eq!(mark, 1337); +} + +#[test] +fn test_so_buf() { + let fd = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + SockProtocol::Udp, + ) + .unwrap(); + let bufsize: usize = thread_rng().gen_range(4096..131_072); + setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap(); + let actual = getsockopt(fd, sockopt::SndBuf).unwrap(); + assert!(actual >= bufsize); + setsockopt(fd, sockopt::RcvBuf, &bufsize).unwrap(); + let actual = getsockopt(fd, sockopt::RcvBuf).unwrap(); + assert!(actual >= bufsize); +} + +#[test] +fn test_so_tcp_maxseg() { + use nix::sys::socket::{accept, bind, connect, listen, SockaddrIn}; + use nix::unistd::{close, write}; + use std::net::SocketAddrV4; + use std::str::FromStr; + + let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap(); + let sock_addr = SockaddrIn::from(std_sa); + + let rsock = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + bind(rsock, &sock_addr).unwrap(); + listen(rsock, 10).unwrap(); + let initial = getsockopt(rsock, sockopt::TcpMaxSeg).unwrap(); + // Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some + // platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger + // than 700 + cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + let segsize: u32 = 873; + assert!(initial < segsize); + setsockopt(rsock, sockopt::TcpMaxSeg, &segsize).unwrap(); + } else { + assert!(initial < 700); + } + } + + // Connect and check the MSS that was advertised + let ssock = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + connect(ssock, &sock_addr).unwrap(); + let rsess = accept(rsock).unwrap(); + write(rsess, b"hello").unwrap(); + let actual = getsockopt(ssock, sockopt::TcpMaxSeg).unwrap(); + // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max + // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary. + cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + assert!((segsize - 100) <= actual); + assert!(actual <= segsize); + } else { + assert!(initial < actual); + assert!(536 < actual); + } + } + close(rsock).unwrap(); + close(ssock).unwrap(); +} + +#[test] +fn test_so_type() { + let sockfd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + + assert_eq!(Ok(SockType::Stream), getsockopt(sockfd, sockopt::SockType)); +} + +/// getsockopt(_, sockopt::SockType) should gracefully handle unknown socket +/// types. Regression test for https://github.com/nix-rust/nix/issues/1819 +#[cfg(any(target_os = "android", target_os = "linux",))] +#[test] +fn test_so_type_unknown() { + use nix::errno::Errno; + + require_capability!("test_so_type", CAP_NET_RAW); + let sockfd = unsafe { libc::socket(libc::AF_PACKET, libc::SOCK_PACKET, 0) }; + assert!(sockfd >= 0, "Error opening socket: {}", nix::Error::last()); + + assert_eq!(Err(Errno::EINVAL), getsockopt(sockfd, sockopt::SockType)); +} + +// The CI doesn't supported getsockopt and setsockopt on emulated processors. +// It's believed that a QEMU issue, the tests run ok on a fully emulated system. +// Current CI just run the binary with QEMU but the Kernel remains the same as the host. +// So the syscall doesn't work properly unless the kernel is also emulated. +#[test] +#[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + any(target_os = "freebsd", target_os = "linux") +))] +fn test_tcp_congestion() { + use std::ffi::OsString; + + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + + let val = getsockopt(fd, sockopt::TcpCongestion).unwrap(); + setsockopt(fd, sockopt::TcpCongestion, &val).unwrap(); + + setsockopt( + fd, + sockopt::TcpCongestion, + &OsString::from("tcp_congestion_does_not_exist"), + ) + .unwrap_err(); + + assert_eq!(getsockopt(fd, sockopt::TcpCongestion).unwrap(), val); +} + +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_bindtodevice() { + skip_if_not_root!("test_bindtodevice"); + + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + + let val = getsockopt(fd, sockopt::BindToDevice).unwrap(); + setsockopt(fd, sockopt::BindToDevice, &val).unwrap(); + + assert_eq!(getsockopt(fd, sockopt::BindToDevice).unwrap(), val); +} + +#[test] +fn test_so_tcp_keepalive() { + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(fd, sockopt::KeepAlive, &true).unwrap(); + assert!(getsockopt(fd, sockopt::KeepAlive).unwrap()); + + #[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux" + ))] + { + let x = getsockopt(fd, sockopt::TcpKeepIdle).unwrap(); + setsockopt(fd, sockopt::TcpKeepIdle, &(x + 1)).unwrap(); + assert_eq!(getsockopt(fd, sockopt::TcpKeepIdle).unwrap(), x + 1); + + let x = getsockopt(fd, sockopt::TcpKeepCount).unwrap(); + setsockopt(fd, sockopt::TcpKeepCount, &(x + 1)).unwrap(); + assert_eq!(getsockopt(fd, sockopt::TcpKeepCount).unwrap(), x + 1); + + let x = getsockopt(fd, sockopt::TcpKeepInterval).unwrap(); + setsockopt(fd, sockopt::TcpKeepInterval, &(x + 1)).unwrap(); + assert_eq!(getsockopt(fd, sockopt::TcpKeepInterval).unwrap(), x + 1); + } +} + +#[test] +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +fn test_ttl_opts() { + let fd4 = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(fd4, sockopt::Ipv4Ttl, &1) + .expect("setting ipv4ttl on an inet socket should succeed"); + let fd6 = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(fd6, sockopt::Ipv6Ttl, &1) + .expect("setting ipv6ttl on an inet6 socket should succeed"); +} + +#[test] +#[cfg(any(target_os = "ios", target_os = "macos"))] +fn test_dontfrag_opts() { + let fd4 = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(fd4, sockopt::IpDontFrag, &true) + .expect("setting IP_DONTFRAG on an inet stream socket should succeed"); + setsockopt(fd4, sockopt::IpDontFrag, &false).expect( + "unsetting IP_DONTFRAG on an inet stream socket should succeed", + ); + let fd4d = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(fd4d, sockopt::IpDontFrag, &true).expect( + "setting IP_DONTFRAG on an inet datagram socket should succeed", + ); + setsockopt(fd4d, sockopt::IpDontFrag, &false).expect( + "unsetting IP_DONTFRAG on an inet datagram socket should succeed", + ); +} + +#[test] +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", +))] +// Disable the test under emulation because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +fn test_v6dontfrag_opts() { + let fd6 = socket( + AddressFamily::Inet6, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + setsockopt(fd6, sockopt::Ipv6DontFrag, &true).expect( + "setting IPV6_DONTFRAG on an inet6 stream socket should succeed", + ); + setsockopt(fd6, sockopt::Ipv6DontFrag, &false).expect( + "unsetting IPV6_DONTFRAG on an inet6 stream socket should succeed", + ); + let fd6d = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, + ) + .unwrap(); + setsockopt(fd6d, sockopt::Ipv6DontFrag, &true).expect( + "setting IPV6_DONTFRAG on an inet6 datagram socket should succeed", + ); + setsockopt(fd6d, sockopt::Ipv6DontFrag, &false).expect( + "unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed", + ); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_stat.rs b/utshell-0.5.0/vendor/nix/test/sys/test_stat.rs new file mode 100644 index 00000000..426b4b65 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_stat.rs @@ -0,0 +1,29 @@ +// The conversion is not useless on all platforms. +#[allow(clippy::useless_conversion)] +#[cfg(target_os = "freebsd")] +#[test] +fn test_chflags() { + use nix::{ + sys::stat::{fstat, FileFlag}, + unistd::chflags, + }; + use std::os::unix::io::AsRawFd; + use tempfile::NamedTempFile; + + let f = NamedTempFile::new().unwrap(); + + let initial = FileFlag::from_bits_truncate( + fstat(f.as_raw_fd()).unwrap().st_flags.into(), + ); + // UF_OFFLINE is preserved by all FreeBSD file systems, but not interpreted + // in any way, so it's handy for testing. + let commanded = initial ^ FileFlag::UF_OFFLINE; + + chflags(f.path(), commanded).unwrap(); + + let changed = FileFlag::from_bits_truncate( + fstat(f.as_raw_fd()).unwrap().st_flags.into(), + ); + + assert_eq!(commanded, changed); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_sysinfo.rs b/utshell-0.5.0/vendor/nix/test/sys/test_sysinfo.rs new file mode 100644 index 00000000..2897366e --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_sysinfo.rs @@ -0,0 +1,20 @@ +use nix::sys::sysinfo::*; + +#[test] +fn sysinfo_works() { + let info = sysinfo().unwrap(); + + let (l1, l5, l15) = info.load_average(); + assert!(l1 >= 0.0); + assert!(l5 >= 0.0); + assert!(l15 >= 0.0); + + info.uptime(); // just test Duration construction + + assert!( + info.swap_free() <= info.swap_total(), + "more swap available than installed (free: {}, total: {})", + info.swap_free(), + info.swap_total() + ); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_termios.rs b/utshell-0.5.0/vendor/nix/test/sys/test_termios.rs new file mode 100644 index 00000000..aaf00084 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_termios.rs @@ -0,0 +1,136 @@ +use std::os::unix::prelude::*; +use tempfile::tempfile; + +use nix::errno::Errno; +use nix::fcntl; +use nix::pty::openpty; +use nix::sys::termios::{self, tcgetattr, LocalFlags, OutputFlags}; +use nix::unistd::{close, read, write}; + +/// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s +fn write_all(f: RawFd, buf: &[u8]) { + let mut len = 0; + while len < buf.len() { + len += write(f, &buf[len..]).unwrap(); + } +} + +// Test tcgetattr on a terminal +#[test] +fn test_tcgetattr_pty() { + // openpty uses ptname(3) internally + let _m = crate::PTSNAME_MTX.lock(); + + let pty = openpty(None, None).expect("openpty failed"); + termios::tcgetattr(pty.slave).unwrap(); + close(pty.master).expect("closing the master failed"); + close(pty.slave).expect("closing the slave failed"); +} + +// Test tcgetattr on something that isn't a terminal +#[test] +fn test_tcgetattr_enotty() { + let file = tempfile().unwrap(); + assert_eq!( + termios::tcgetattr(file.as_raw_fd()).err(), + Some(Errno::ENOTTY) + ); +} + +// Test tcgetattr on an invalid file descriptor +#[test] +fn test_tcgetattr_ebadf() { + assert_eq!(termios::tcgetattr(-1).err(), Some(Errno::EBADF)); +} + +// Test modifying output flags +#[test] +fn test_output_flags() { + // openpty uses ptname(3) internally + let _m = crate::PTSNAME_MTX.lock(); + + // Open one pty to get attributes for the second one + let mut termios = { + let pty = openpty(None, None).expect("openpty failed"); + assert!(pty.master > 0); + assert!(pty.slave > 0); + let termios = tcgetattr(pty.slave).expect("tcgetattr failed"); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + termios + }; + + // Make sure postprocessing '\r' isn't specified by default or this test is useless. + assert!(!termios + .output_flags + .contains(OutputFlags::OPOST | OutputFlags::OCRNL)); + + // Specify that '\r' characters should be transformed to '\n' + // OPOST is specified to enable post-processing + termios + .output_flags + .insert(OutputFlags::OPOST | OutputFlags::OCRNL); + + // Open a pty + let pty = openpty(None, &termios).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); + + // Write into the master + let string = "foofoofoo\r"; + write_all(pty.master, string.as_bytes()); + + // Read from the slave verifying that the output has been properly transformed + let mut buf = [0u8; 10]; + crate::read_exact(pty.slave, &mut buf); + let transformed_string = "foofoofoo\n"; + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + assert_eq!(&buf, transformed_string.as_bytes()); +} + +// Test modifying local flags +#[test] +fn test_local_flags() { + // openpty uses ptname(3) internally + let _m = crate::PTSNAME_MTX.lock(); + + // Open one pty to get attributes for the second one + let mut termios = { + let pty = openpty(None, None).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); + let termios = tcgetattr(pty.slave).unwrap(); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + termios + }; + + // Make sure echo is specified by default or this test is useless. + assert!(termios.local_flags.contains(LocalFlags::ECHO)); + + // Disable local echo + termios.local_flags.remove(LocalFlags::ECHO); + + // Open a new pty with our modified termios settings + let pty = openpty(None, &termios).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); + + // Set the master is in nonblocking mode or reading will never return. + let flags = fcntl::fcntl(pty.master, fcntl::F_GETFL).unwrap(); + let new_flags = + fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK; + fcntl::fcntl(pty.master, fcntl::F_SETFL(new_flags)).unwrap(); + + // Write into the master + let string = "foofoofoo\r"; + write_all(pty.master, string.as_bytes()); + + // Try to read from the master, which should not have anything as echoing was disabled. + let mut buf = [0u8; 10]; + let read = read(pty.master, &mut buf).unwrap_err(); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + assert_eq!(read, Errno::EAGAIN); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_timerfd.rs b/utshell-0.5.0/vendor/nix/test/sys/test_timerfd.rs new file mode 100644 index 00000000..08e29210 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_timerfd.rs @@ -0,0 +1,69 @@ +use nix::sys::time::{TimeSpec, TimeValLike}; +use nix::sys::timerfd::{ + ClockId, Expiration, TimerFd, TimerFlags, TimerSetTimeFlags, +}; +use std::time::Instant; + +#[test] +pub fn test_timerfd_oneshot() { + let timer = + TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap(); + + let before = Instant::now(); + + timer + .set( + Expiration::OneShot(TimeSpec::seconds(1)), + TimerSetTimeFlags::empty(), + ) + .unwrap(); + + timer.wait().unwrap(); + + let millis = before.elapsed().as_millis(); + assert!(millis > 900); +} + +#[test] +pub fn test_timerfd_interval() { + let timer = + TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap(); + + let before = Instant::now(); + timer + .set( + Expiration::IntervalDelayed( + TimeSpec::seconds(1), + TimeSpec::seconds(2), + ), + TimerSetTimeFlags::empty(), + ) + .unwrap(); + + timer.wait().unwrap(); + + let start_delay = before.elapsed().as_millis(); + assert!(start_delay > 900); + + timer.wait().unwrap(); + + let interval_delay = before.elapsed().as_millis(); + assert!(interval_delay > 2900); +} + +#[test] +pub fn test_timerfd_unset() { + let timer = + TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap(); + + timer + .set( + Expiration::OneShot(TimeSpec::seconds(1)), + TimerSetTimeFlags::empty(), + ) + .unwrap(); + + timer.unset().unwrap(); + + assert!(timer.get().unwrap().is_none()); +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_uio.rs b/utshell-0.5.0/vendor/nix/test/sys/test_uio.rs new file mode 100644 index 00000000..0f4b8a65 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_uio.rs @@ -0,0 +1,270 @@ +use nix::sys::uio::*; +use nix::unistd::*; +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng}; +use std::fs::OpenOptions; +use std::io::IoSlice; +use std::os::unix::io::AsRawFd; +use std::{cmp, iter}; + +#[cfg(not(target_os = "redox"))] +use std::io::IoSliceMut; + +use tempfile::tempdir; +#[cfg(not(target_os = "redox"))] +use tempfile::tempfile; + +#[test] +fn test_writev() { + let mut to_write = Vec::with_capacity(16 * 128); + for _ in 0..16 { + let s: String = thread_rng() + .sample_iter(&Alphanumeric) + .map(char::from) + .take(128) + .collect(); + let b = s.as_bytes(); + to_write.extend(b.iter().cloned()); + } + // Allocate and fill iovecs + let mut iovecs = Vec::new(); + let mut consumed = 0; + while consumed < to_write.len() { + let left = to_write.len() - consumed; + let slice_len = if left <= 64 { + left + } else { + thread_rng().gen_range(64..cmp::min(256, left)) + }; + let b = &to_write[consumed..consumed + slice_len]; + iovecs.push(IoSlice::new(b)); + consumed += slice_len; + } + let pipe_res = pipe(); + let (reader, writer) = pipe_res.expect("Couldn't create pipe"); + // FileDesc will close its filedesc (reader). + let mut read_buf: Vec = iter::repeat(0u8).take(128 * 16).collect(); + // Blocking io, should write all data. + let write_res = writev(writer, &iovecs); + let written = write_res.expect("couldn't write"); + // Check whether we written all data + assert_eq!(to_write.len(), written); + let read_res = read(reader, &mut read_buf[..]); + let read = read_res.expect("couldn't read"); + // Check we have read as much as we written + assert_eq!(read, written); + // Check equality of written and read data + assert_eq!(&to_write, &read_buf); + close(writer).expect("closed writer"); + close(reader).expect("closed reader"); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_readv() { + let s: String = thread_rng() + .sample_iter(&Alphanumeric) + .map(char::from) + .take(128) + .collect(); + let to_write = s.as_bytes().to_vec(); + let mut storage = Vec::new(); + let mut allocated = 0; + while allocated < to_write.len() { + let left = to_write.len() - allocated; + let vec_len = if left <= 64 { + left + } else { + thread_rng().gen_range(64..cmp::min(256, left)) + }; + let v: Vec = iter::repeat(0u8).take(vec_len).collect(); + storage.push(v); + allocated += vec_len; + } + let mut iovecs = Vec::with_capacity(storage.len()); + for v in &mut storage { + iovecs.push(IoSliceMut::new(&mut v[..])); + } + let (reader, writer) = pipe().expect("couldn't create pipe"); + // Blocking io, should write all data. + write(writer, &to_write).expect("write failed"); + let read = readv(reader, &mut iovecs[..]).expect("read failed"); + // Check whether we've read all data + assert_eq!(to_write.len(), read); + // Cccumulate data from iovecs + let mut read_buf = Vec::with_capacity(to_write.len()); + for iovec in &iovecs { + read_buf.extend(iovec.iter().cloned()); + } + // Check whether iovecs contain all written data + assert_eq!(read_buf.len(), to_write.len()); + // Check equality of written and read data + assert_eq!(&read_buf, &to_write); + close(reader).expect("couldn't close reader"); + close(writer).expect("couldn't close writer"); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_pwrite() { + use std::io::Read; + + let mut file = tempfile().unwrap(); + let buf = [1u8; 8]; + assert_eq!(Ok(8), pwrite(file.as_raw_fd(), &buf, 8)); + let mut file_content = Vec::new(); + file.read_to_end(&mut file_content).unwrap(); + let mut expected = vec![0u8; 8]; + expected.extend(vec![1; 8]); + assert_eq!(file_content, expected); +} + +#[test] +fn test_pread() { + use std::io::Write; + + let tempdir = tempdir().unwrap(); + + let path = tempdir.path().join("pread_test_file"); + let mut file = OpenOptions::new() + .write(true) + .read(true) + .create(true) + .truncate(true) + .open(path) + .unwrap(); + let file_content: Vec = (0..64).collect(); + file.write_all(&file_content).unwrap(); + + let mut buf = [0u8; 16]; + assert_eq!(Ok(16), pread(file.as_raw_fd(), &mut buf, 16)); + let expected: Vec<_> = (16..32).collect(); + assert_eq!(&buf[..], &expected[..]); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_pwritev() { + use std::io::Read; + + let to_write: Vec = (0..128).collect(); + let expected: Vec = [vec![0; 100], to_write.clone()].concat(); + + let iovecs = [ + IoSlice::new(&to_write[0..17]), + IoSlice::new(&to_write[17..64]), + IoSlice::new(&to_write[64..128]), + ]; + + let tempdir = tempdir().unwrap(); + + // pwritev them into a temporary file + let path = tempdir.path().join("pwritev_test_file"); + let mut file = OpenOptions::new() + .write(true) + .read(true) + .create(true) + .truncate(true) + .open(path) + .unwrap(); + + let written = pwritev(file.as_raw_fd(), &iovecs, 100).ok().unwrap(); + assert_eq!(written, to_write.len()); + + // Read the data back and make sure it matches + let mut contents = Vec::new(); + file.read_to_end(&mut contents).unwrap(); + assert_eq!(contents, expected); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_preadv() { + use std::io::Write; + + let to_write: Vec = (0..200).collect(); + let expected: Vec = (100..200).collect(); + + let tempdir = tempdir().unwrap(); + + let path = tempdir.path().join("preadv_test_file"); + + let mut file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .truncate(true) + .open(path) + .unwrap(); + file.write_all(&to_write).unwrap(); + + let mut buffers: Vec> = vec![vec![0; 24], vec![0; 1], vec![0; 75]]; + + { + // Borrow the buffers into IoVecs and preadv into them + let mut iovecs: Vec<_> = buffers + .iter_mut() + .map(|buf| IoSliceMut::new(&mut buf[..])) + .collect(); + assert_eq!(Ok(100), preadv(file.as_raw_fd(), &mut iovecs, 100)); + } + + let all = buffers.concat(); + assert_eq!(all, expected); +} + +#[test] +#[cfg(all(target_os = "linux", not(target_env = "uclibc")))] +// uclibc doesn't implement process_vm_readv +// qemu-user doesn't implement process_vm_readv/writev on most arches +#[cfg_attr(qemu, ignore)] +fn test_process_vm_readv() { + use crate::*; + use nix::sys::signal::*; + use nix::sys::wait::*; + use nix::unistd::ForkResult::*; + + require_capability!("test_process_vm_readv", CAP_SYS_PTRACE); + let _m = crate::FORK_MTX.lock(); + + // Pre-allocate memory in the child, since allocation isn't safe + // post-fork (~= async-signal-safe) + let mut vector = vec![1u8, 2, 3, 4, 5]; + + let (r, w) = pipe().unwrap(); + match unsafe { fork() }.expect("Error: Fork Failed") { + Parent { child } => { + close(w).unwrap(); + // wait for child + read(r, &mut [0u8]).unwrap(); + close(r).unwrap(); + + let ptr = vector.as_ptr() as usize; + let remote_iov = RemoteIoVec { base: ptr, len: 5 }; + let mut buf = vec![0u8; 5]; + + let ret = process_vm_readv( + child, + &mut [IoSliceMut::new(&mut buf)], + &[remote_iov], + ); + + kill(child, SIGTERM).unwrap(); + waitpid(child, None).unwrap(); + + assert_eq!(Ok(5), ret); + assert_eq!(20u8, buf.iter().sum()); + } + Child => { + let _ = close(r); + for i in &mut vector { + *i += 1; + } + let _ = write(w, b"\0"); + let _ = close(w); + loop { + pause(); + } + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/sys/test_wait.rs b/utshell-0.5.0/vendor/nix/test/sys/test_wait.rs new file mode 100644 index 00000000..d472f1ec --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/sys/test_wait.rs @@ -0,0 +1,257 @@ +use libc::_exit; +use nix::errno::Errno; +use nix::sys::signal::*; +use nix::sys::wait::*; +use nix::unistd::ForkResult::*; +use nix::unistd::*; + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_wait_signal() { + let _m = crate::FORK_MTX.lock(); + + // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe. + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => { + pause(); + unsafe { _exit(123) } + } + Parent { child } => { + kill(child, Some(SIGKILL)).expect("Error: Kill Failed"); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Signaled(child, SIGKILL, false)) + ); + } + } +} + +#[test] +#[cfg(any( + target_os = "android", + target_os = "freebsd", + //target_os = "haiku", + all(target_os = "linux", not(target_env = "uclibc")), +))] +#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] +fn test_waitid_signal() { + let _m = crate::FORK_MTX.lock(); + + // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe. + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => { + pause(); + unsafe { _exit(123) } + } + Parent { child } => { + kill(child, Some(SIGKILL)).expect("Error: Kill Failed"); + assert_eq!( + waitid(Id::Pid(child), WaitPidFlag::WEXITED), + Ok(WaitStatus::Signaled(child, SIGKILL, false)), + ); + } + } +} + +#[test] +fn test_wait_exit() { + let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is async-signal-safe. + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => unsafe { + _exit(12); + }, + Parent { child } => { + assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12))); + } + } +} + +#[cfg(not(target_os = "haiku"))] +#[test] +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "haiku", + all(target_os = "linux", not(target_env = "uclibc")), +))] +#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] +fn test_waitid_exit() { + let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is async-signal-safe. + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => unsafe { + _exit(12); + }, + Parent { child } => { + assert_eq!( + waitid(Id::Pid(child), WaitPidFlag::WEXITED), + Ok(WaitStatus::Exited(child, 12)), + ); + } + } +} + +#[test] +fn test_waitstatus_from_raw() { + let pid = Pid::from_raw(1); + assert_eq!( + WaitStatus::from_raw(pid, 0x0002), + Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false)) + ); + assert_eq!( + WaitStatus::from_raw(pid, 0x0200), + Ok(WaitStatus::Exited(pid, 2)) + ); + assert_eq!(WaitStatus::from_raw(pid, 0x7f7f), Err(Errno::EINVAL)); +} + +#[test] +fn test_waitstatus_pid() { + let _m = crate::FORK_MTX.lock(); + + match unsafe { fork() }.unwrap() { + Child => unsafe { _exit(0) }, + Parent { child } => { + let status = waitpid(child, None).unwrap(); + assert_eq!(status.pid(), Some(child)); + } + } +} + +#[test] +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "haiku", + all(target_os = "linux", not(target_env = "uclibc")), +))] +fn test_waitid_pid() { + let _m = crate::FORK_MTX.lock(); + + match unsafe { fork() }.unwrap() { + Child => unsafe { _exit(0) }, + Parent { child } => { + let status = waitid(Id::Pid(child), WaitPidFlag::WEXITED).unwrap(); + assert_eq!(status.pid(), Some(child)); + } + } +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +// FIXME: qemu-user doesn't implement ptrace on most arches +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod ptrace { + use crate::*; + use libc::_exit; + use nix::sys::ptrace::{self, Event, Options}; + use nix::sys::signal::*; + use nix::sys::wait::*; + use nix::unistd::ForkResult::*; + use nix::unistd::*; + + fn ptrace_child() -> ! { + ptrace::traceme().unwrap(); + // As recommended by ptrace(2), raise SIGTRAP to pause the child + // until the parent is ready to continue + raise(SIGTRAP).unwrap(); + unsafe { _exit(0) } + } + + fn ptrace_wait_parent(child: Pid) { + // Wait for the raised SIGTRAP + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::Stopped(child, SIGTRAP)) + ); + // We want to test a syscall stop and a PTRACE_EVENT stop + ptrace::setoptions( + child, + Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT, + ) + .expect("setoptions failed"); + + // First, stop on the next system call, which will be exit() + ptrace::syscall(child, None).expect("syscall failed"); + assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child))); + // Then get the ptrace event for the process exiting + ptrace::cont(child, None).expect("cont failed"); + assert_eq!( + waitpid(child, None), + Ok(WaitStatus::PtraceEvent( + child, + SIGTRAP, + Event::PTRACE_EVENT_EXIT as i32 + )) + ); + // Finally get the normal wait() result, now that the process has exited + ptrace::cont(child, None).expect("cont failed"); + assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0))); + } + + #[cfg(not(target_env = "uclibc"))] + fn ptrace_waitid_parent(child: Pid) { + // Wait for the raised SIGTRAP + // + // Unlike waitpid(), waitid() can distinguish trap events from regular + // stop events, so unlike ptrace_wait_parent(), we get a PtraceEvent here + assert_eq!( + waitid(Id::Pid(child), WaitPidFlag::WEXITED), + Ok(WaitStatus::PtraceEvent(child, SIGTRAP, 0)), + ); + // We want to test a syscall stop and a PTRACE_EVENT stop + ptrace::setoptions( + child, + Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT, + ) + .expect("setopts failed"); + + // First, stop on the next system call, which will be exit() + ptrace::syscall(child, None).expect("syscall failed"); + assert_eq!( + waitid(Id::Pid(child), WaitPidFlag::WEXITED), + Ok(WaitStatus::PtraceSyscall(child)), + ); + // Then get the ptrace event for the process exiting + ptrace::cont(child, None).expect("cont failed"); + assert_eq!( + waitid(Id::Pid(child), WaitPidFlag::WEXITED), + Ok(WaitStatus::PtraceEvent( + child, + SIGTRAP, + Event::PTRACE_EVENT_EXIT as i32 + )), + ); + // Finally get the normal wait() result, now that the process has exited + ptrace::cont(child, None).expect("cont failed"); + assert_eq!( + waitid(Id::Pid(child), WaitPidFlag::WEXITED), + Ok(WaitStatus::Exited(child, 0)), + ); + } + + #[test] + fn test_wait_ptrace() { + require_capability!("test_wait_ptrace", CAP_SYS_PTRACE); + let _m = crate::FORK_MTX.lock(); + + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => ptrace_child(), + Parent { child } => ptrace_wait_parent(child), + } + } + + #[test] + #[cfg(not(target_env = "uclibc"))] + fn test_waitid_ptrace() { + require_capability!("test_waitid_ptrace", CAP_SYS_PTRACE); + let _m = crate::FORK_MTX.lock(); + + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => ptrace_child(), + Parent { child } => ptrace_waitid_parent(child), + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/test.rs b/utshell-0.5.0/vendor/nix/test/test.rs new file mode 100644 index 00000000..f725ef97 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test.rs @@ -0,0 +1,123 @@ +#[macro_use] +extern crate cfg_if; +#[cfg_attr(not(any(target_os = "redox", target_os = "haiku")), macro_use)] +extern crate nix; +#[macro_use] +extern crate lazy_static; + +mod common; +mod sys; +#[cfg(not(target_os = "redox"))] +mod test_dir; +mod test_fcntl; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod test_kmod; +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fushsia", + target_os = "linux", + target_os = "netbsd" +))] +mod test_mq; +#[cfg(not(target_os = "redox"))] +mod test_net; +mod test_nix_path; +#[cfg(target_os = "freebsd")] +mod test_nmount; +mod test_poll; +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +mod test_pty; +mod test_resource; +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "linux" +))] +mod test_sched; +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos" +))] +mod test_sendfile; +mod test_stat; +mod test_time; +#[cfg(all( + any( + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd" + ), + feature = "time", + feature = "signal" +))] +mod test_timer; +mod test_unistd; + +use nix::unistd::{chdir, getcwd, read}; +use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; +use std::os::unix::io::RawFd; +use std::path::PathBuf; + +/// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s +fn read_exact(f: RawFd, buf: &mut [u8]) { + let mut len = 0; + while len < buf.len() { + // get_mut would be better than split_at_mut, but it requires nightly + let (_, remaining) = buf.split_at_mut(len); + len += read(f, remaining).unwrap(); + } +} + +lazy_static! { + /// Any test that changes the process's current working directory must grab + /// the RwLock exclusively. Any process that cares about the current + /// working directory must grab it shared. + pub static ref CWD_LOCK: RwLock<()> = RwLock::new(()); + /// Any test that creates child processes must grab this mutex, regardless + /// of what it does with those children. + pub static ref FORK_MTX: Mutex<()> = Mutex::new(()); + /// Any test that changes the process's supplementary groups must grab this + /// mutex + pub static ref GROUPS_MTX: Mutex<()> = Mutex::new(()); + /// Any tests that loads or unloads kernel modules must grab this mutex + pub static ref KMOD_MTX: Mutex<()> = Mutex::new(()); + /// Any test that calls ptsname(3) must grab this mutex. + pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(()); + /// Any test that alters signal handling must grab this mutex. + pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(()); +} + +/// RAII object that restores a test's original directory on drop +struct DirRestore<'a> { + d: PathBuf, + _g: RwLockWriteGuard<'a, ()>, +} + +impl<'a> DirRestore<'a> { + fn new() -> Self { + let guard = crate::CWD_LOCK.write(); + DirRestore { + _g: guard, + d: getcwd().unwrap(), + } + } +} + +impl<'a> Drop for DirRestore<'a> { + fn drop(&mut self) { + let r = chdir(&self.d); + if std::thread::panicking() { + r.unwrap(); + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/test_clearenv.rs b/utshell-0.5.0/vendor/nix/test/test_clearenv.rs new file mode 100644 index 00000000..28a77680 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_clearenv.rs @@ -0,0 +1,9 @@ +use std::env; + +#[test] +fn clearenv() { + env::set_var("FOO", "BAR"); + unsafe { nix::env::clearenv() }.unwrap(); + assert_eq!(env::var("FOO").unwrap_err(), env::VarError::NotPresent); + assert_eq!(env::vars().count(), 0); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_dir.rs b/utshell-0.5.0/vendor/nix/test/test_dir.rs new file mode 100644 index 00000000..2af4aa5c --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_dir.rs @@ -0,0 +1,65 @@ +use nix::dir::{Dir, Type}; +use nix::fcntl::OFlag; +use nix::sys::stat::Mode; +use std::fs::File; +use tempfile::tempdir; + +#[cfg(test)] +fn flags() -> OFlag { + #[cfg(target_os = "illumos")] + let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC; + + #[cfg(not(target_os = "illumos"))] + let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC | OFlag::O_DIRECTORY; + + f +} + +#[test] +#[allow(clippy::unnecessary_sort_by)] // False positive +fn read() { + let tmp = tempdir().unwrap(); + File::create(tmp.path().join("foo")).unwrap(); + std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); + let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); + let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect(); + entries.sort_by(|a, b| a.file_name().cmp(b.file_name())); + let entry_names: Vec<_> = entries + .iter() + .map(|e| e.file_name().to_str().unwrap().to_owned()) + .collect(); + assert_eq!(&entry_names[..], &[".", "..", "bar", "foo"]); + + // Check file types. The system is allowed to return DT_UNKNOWN (aka None here) but if it does + // return a type, ensure it's correct. + assert!(&[Some(Type::Directory), None].contains(&entries[0].file_type())); // .: dir + assert!(&[Some(Type::Directory), None].contains(&entries[1].file_type())); // ..: dir + assert!(&[Some(Type::Symlink), None].contains(&entries[2].file_type())); // bar: symlink + assert!(&[Some(Type::File), None].contains(&entries[3].file_type())); // foo: regular file +} + +#[test] +fn rewind() { + let tmp = tempdir().unwrap(); + let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); + let entries1: Vec<_> = dir + .iter() + .map(|e| e.unwrap().file_name().to_owned()) + .collect(); + let entries2: Vec<_> = dir + .iter() + .map(|e| e.unwrap().file_name().to_owned()) + .collect(); + let entries3: Vec<_> = dir + .into_iter() + .map(|e| e.unwrap().file_name().to_owned()) + .collect(); + assert_eq!(entries1, entries2); + assert_eq!(entries2, entries3); +} + +#[cfg(not(target_os = "haiku"))] +#[test] +fn ebadf() { + assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::EBADF); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_fcntl.rs b/utshell-0.5.0/vendor/nix/test/test_fcntl.rs new file mode 100644 index 00000000..345e04da --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_fcntl.rs @@ -0,0 +1,565 @@ +#[cfg(not(target_os = "redox"))] +use nix::errno::*; +#[cfg(not(target_os = "redox"))] +use nix::fcntl::{open, readlink, OFlag}; +#[cfg(not(target_os = "redox"))] +use nix::fcntl::{openat, readlinkat, renameat}; +#[cfg(all( + target_os = "linux", + target_env = "gnu", + any( + target_arch = "x86_64", + target_arch = "x32", + target_arch = "powerpc", + target_arch = "s390x" + ) +))] +use nix::fcntl::{renameat2, RenameFlags}; +#[cfg(not(target_os = "redox"))] +use nix::sys::stat::Mode; +#[cfg(not(target_os = "redox"))] +use nix::unistd::{close, read}; +#[cfg(not(target_os = "redox"))] +use std::fs::File; +#[cfg(not(target_os = "redox"))] +use std::io::prelude::*; +#[cfg(not(target_os = "redox"))] +use std::os::unix::fs; +#[cfg(not(target_os = "redox"))] +use tempfile::{self, NamedTempFile}; + +#[test] +#[cfg(not(target_os = "redox"))] +// QEMU does not handle openat well enough to satisfy this test +// https://gitlab.com/qemu-project/qemu/-/issues/829 +#[cfg_attr(qemu, ignore)] +fn test_openat() { + const CONTENTS: &[u8] = b"abcd"; + let mut tmp = NamedTempFile::new().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + + let dirfd = + open(tmp.path().parent().unwrap(), OFlag::empty(), Mode::empty()) + .unwrap(); + let fd = openat( + dirfd, + tmp.path().file_name().unwrap(), + OFlag::O_RDONLY, + Mode::empty(), + ) + .unwrap(); + + let mut buf = [0u8; 1024]; + assert_eq!(4, read(fd, &mut buf).unwrap()); + assert_eq!(CONTENTS, &buf[0..4]); + + close(fd).unwrap(); + close(dirfd).unwrap(); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_renameat() { + let old_dir = tempfile::tempdir().unwrap(); + let old_dirfd = + open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let old_path = old_dir.path().join("old"); + File::create(old_path).unwrap(); + let new_dir = tempfile::tempdir().unwrap(); + let new_dirfd = + open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap(); + assert_eq!( + renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap_err(), + Errno::ENOENT + ); + close(old_dirfd).unwrap(); + close(new_dirfd).unwrap(); + assert!(new_dir.path().join("new").exists()); +} + +#[test] +#[cfg(all( + target_os = "linux", + target_env = "gnu", + any( + target_arch = "x86_64", + target_arch = "x32", + target_arch = "powerpc", + target_arch = "s390x" + ) +))] +fn test_renameat2_behaves_like_renameat_with_no_flags() { + let old_dir = tempfile::tempdir().unwrap(); + let old_dirfd = + open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let old_path = old_dir.path().join("old"); + File::create(old_path).unwrap(); + let new_dir = tempfile::tempdir().unwrap(); + let new_dirfd = + open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + renameat2( + Some(old_dirfd), + "old", + Some(new_dirfd), + "new", + RenameFlags::empty(), + ) + .unwrap(); + assert_eq!( + renameat2( + Some(old_dirfd), + "old", + Some(new_dirfd), + "new", + RenameFlags::empty() + ) + .unwrap_err(), + Errno::ENOENT + ); + close(old_dirfd).unwrap(); + close(new_dirfd).unwrap(); + assert!(new_dir.path().join("new").exists()); +} + +#[test] +#[cfg(all( + target_os = "linux", + target_env = "gnu", + any( + target_arch = "x86_64", + target_arch = "x32", + target_arch = "powerpc", + target_arch = "s390x" + ) +))] +fn test_renameat2_exchange() { + let old_dir = tempfile::tempdir().unwrap(); + let old_dirfd = + open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let old_path = old_dir.path().join("old"); + { + let mut old_f = File::create(&old_path).unwrap(); + old_f.write_all(b"old").unwrap(); + } + let new_dir = tempfile::tempdir().unwrap(); + let new_dirfd = + open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let new_path = new_dir.path().join("new"); + { + let mut new_f = File::create(&new_path).unwrap(); + new_f.write_all(b"new").unwrap(); + } + renameat2( + Some(old_dirfd), + "old", + Some(new_dirfd), + "new", + RenameFlags::RENAME_EXCHANGE, + ) + .unwrap(); + let mut buf = String::new(); + let mut new_f = File::open(&new_path).unwrap(); + new_f.read_to_string(&mut buf).unwrap(); + assert_eq!(buf, "old"); + buf = "".to_string(); + let mut old_f = File::open(&old_path).unwrap(); + old_f.read_to_string(&mut buf).unwrap(); + assert_eq!(buf, "new"); + close(old_dirfd).unwrap(); + close(new_dirfd).unwrap(); +} + +#[test] +#[cfg(all( + target_os = "linux", + target_env = "gnu", + any( + target_arch = "x86_64", + target_arch = "x32", + target_arch = "powerpc", + target_arch = "s390x" + ) +))] +fn test_renameat2_noreplace() { + let old_dir = tempfile::tempdir().unwrap(); + let old_dirfd = + open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let old_path = old_dir.path().join("old"); + File::create(old_path).unwrap(); + let new_dir = tempfile::tempdir().unwrap(); + let new_dirfd = + open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let new_path = new_dir.path().join("new"); + File::create(new_path).unwrap(); + assert_eq!( + renameat2( + Some(old_dirfd), + "old", + Some(new_dirfd), + "new", + RenameFlags::RENAME_NOREPLACE + ) + .unwrap_err(), + Errno::EEXIST + ); + close(old_dirfd).unwrap(); + close(new_dirfd).unwrap(); + assert!(new_dir.path().join("new").exists()); + assert!(old_dir.path().join("old").exists()); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_readlink() { + let tempdir = tempfile::tempdir().unwrap(); + let src = tempdir.path().join("a"); + let dst = tempdir.path().join("b"); + println!("a: {:?}, b: {:?}", &src, &dst); + fs::symlink(src.as_path(), dst.as_path()).unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let expected_dir = src.to_str().unwrap(); + + assert_eq!(readlink(&dst).unwrap().to_str().unwrap(), expected_dir); + assert_eq!( + readlinkat(dirfd, "b").unwrap().to_str().unwrap(), + expected_dir + ); +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod linux_android { + use libc::loff_t; + use std::io::prelude::*; + use std::io::{IoSlice, SeekFrom}; + use std::os::unix::prelude::*; + + use nix::fcntl::*; + use nix::unistd::{close, pipe, read, write}; + + use tempfile::tempfile; + #[cfg(any(target_os = "linux"))] + use tempfile::NamedTempFile; + + use crate::*; + + /// This test creates a temporary file containing the contents + /// 'foobarbaz' and uses the `copy_file_range` call to transfer + /// 3 bytes at offset 3 (`bar`) to another empty file at offset 0. The + /// resulting file is read and should contain the contents `bar`. + /// The from_offset should be updated by the call to reflect + /// the 3 bytes read (6). + #[test] + // QEMU does not support copy_file_range. Skip under qemu + #[cfg_attr(qemu, ignore)] + fn test_copy_file_range() { + const CONTENTS: &[u8] = b"foobarbaz"; + + let mut tmp1 = tempfile().unwrap(); + let mut tmp2 = tempfile().unwrap(); + + tmp1.write_all(CONTENTS).unwrap(); + tmp1.flush().unwrap(); + + let mut from_offset: i64 = 3; + copy_file_range( + tmp1.as_raw_fd(), + Some(&mut from_offset), + tmp2.as_raw_fd(), + None, + 3, + ) + .unwrap(); + + let mut res: String = String::new(); + tmp2.seek(SeekFrom::Start(0)).unwrap(); + tmp2.read_to_string(&mut res).unwrap(); + + assert_eq!(res, String::from("bar")); + assert_eq!(from_offset, 6); + } + + #[test] + fn test_splice() { + const CONTENTS: &[u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + + let (rd, wr) = pipe().unwrap(); + let mut offset: loff_t = 5; + let res = splice( + tmp.as_raw_fd(), + Some(&mut offset), + wr, + None, + 2, + SpliceFFlags::empty(), + ) + .unwrap(); + + assert_eq!(2, res); + + let mut buf = [0u8; 1024]; + assert_eq!(2, read(rd, &mut buf).unwrap()); + assert_eq!(b"f1", &buf[0..2]); + assert_eq!(7, offset); + + close(rd).unwrap(); + close(wr).unwrap(); + } + + #[test] + fn test_tee() { + let (rd1, wr1) = pipe().unwrap(); + let (rd2, wr2) = pipe().unwrap(); + + write(wr1, b"abc").unwrap(); + let res = tee(rd1, wr2, 2, SpliceFFlags::empty()).unwrap(); + + assert_eq!(2, res); + + let mut buf = [0u8; 1024]; + + // Check the tee'd bytes are at rd2. + assert_eq!(2, read(rd2, &mut buf).unwrap()); + assert_eq!(b"ab", &buf[0..2]); + + // Check all the bytes are still at rd1. + assert_eq!(3, read(rd1, &mut buf).unwrap()); + assert_eq!(b"abc", &buf[0..3]); + + close(rd1).unwrap(); + close(wr1).unwrap(); + close(rd2).unwrap(); + close(wr2).unwrap(); + } + + #[test] + fn test_vmsplice() { + let (rd, wr) = pipe().unwrap(); + + let buf1 = b"abcdef"; + let buf2 = b"defghi"; + let iovecs = vec![IoSlice::new(&buf1[0..3]), IoSlice::new(&buf2[0..3])]; + + let res = vmsplice(wr, &iovecs[..], SpliceFFlags::empty()).unwrap(); + + assert_eq!(6, res); + + // Check the bytes can be read at rd. + let mut buf = [0u8; 32]; + assert_eq!(6, read(rd, &mut buf).unwrap()); + assert_eq!(b"abcdef", &buf[0..6]); + + close(rd).unwrap(); + close(wr).unwrap(); + } + + #[cfg(any(target_os = "linux"))] + #[test] + fn test_fallocate() { + let tmp = NamedTempFile::new().unwrap(); + + let fd = tmp.as_raw_fd(); + fallocate(fd, FallocateFlags::empty(), 0, 100).unwrap(); + + // Check if we read exactly 100 bytes + let mut buf = [0u8; 200]; + assert_eq!(100, read(fd, &mut buf).unwrap()); + } + + // The tests below are disabled for the listed targets + // due to OFD locks not being available in the kernel/libc + // versions used in the CI environment, probably because + // they run under QEMU. + + #[test] + #[cfg(all(target_os = "linux", not(target_env = "musl")))] + #[cfg_attr(target_env = "uclibc", ignore)] // uclibc doesn't support OFD locks, but the test should still compile + fn test_ofd_write_lock() { + use nix::sys::stat::fstat; + use std::mem; + + let tmp = NamedTempFile::new().unwrap(); + + let fd = tmp.as_raw_fd(); + let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap(); + if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC { + // OverlayFS is a union file system. It returns one inode value in + // stat(2), but a different one shows up in /proc/locks. So we must + // skip the test. + skip!("/proc/locks does not work on overlayfs"); + } + let inode = fstat(fd).expect("fstat failed").st_ino as usize; + + let mut flock: libc::flock = unsafe { + mem::zeroed() // required for Linux/mips + }; + flock.l_type = libc::F_WRLCK as libc::c_short; + flock.l_whence = libc::SEEK_SET as libc::c_short; + flock.l_start = 0; + flock.l_len = 0; + flock.l_pid = 0; + fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write lock failed"); + assert_eq!( + Some(("OFDLCK".to_string(), "WRITE".to_string())), + lock_info(inode) + ); + + flock.l_type = libc::F_UNLCK as libc::c_short; + fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write unlock failed"); + assert_eq!(None, lock_info(inode)); + } + + #[test] + #[cfg(all(target_os = "linux", not(target_env = "musl")))] + #[cfg_attr(target_env = "uclibc", ignore)] // uclibc doesn't support OFD locks, but the test should still compile + fn test_ofd_read_lock() { + use nix::sys::stat::fstat; + use std::mem; + + let tmp = NamedTempFile::new().unwrap(); + + let fd = tmp.as_raw_fd(); + let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap(); + if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC { + // OverlayFS is a union file system. It returns one inode value in + // stat(2), but a different one shows up in /proc/locks. So we must + // skip the test. + skip!("/proc/locks does not work on overlayfs"); + } + let inode = fstat(fd).expect("fstat failed").st_ino as usize; + + let mut flock: libc::flock = unsafe { + mem::zeroed() // required for Linux/mips + }; + flock.l_type = libc::F_RDLCK as libc::c_short; + flock.l_whence = libc::SEEK_SET as libc::c_short; + flock.l_start = 0; + flock.l_len = 0; + flock.l_pid = 0; + fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read lock failed"); + assert_eq!( + Some(("OFDLCK".to_string(), "READ".to_string())), + lock_info(inode) + ); + + flock.l_type = libc::F_UNLCK as libc::c_short; + fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read unlock failed"); + assert_eq!(None, lock_info(inode)); + } + + #[cfg(all(target_os = "linux", not(target_env = "musl")))] + fn lock_info(inode: usize) -> Option<(String, String)> { + use std::{fs::File, io::BufReader}; + + let file = File::open("/proc/locks").expect("open /proc/locks failed"); + let buf = BufReader::new(file); + + for line in buf.lines() { + let line = line.unwrap(); + let parts: Vec<_> = line.split_whitespace().collect(); + let lock_type = parts[1]; + let lock_access = parts[3]; + let ino_parts: Vec<_> = parts[5].split(':').collect(); + let ino: usize = ino_parts[2].parse().unwrap(); + if ino == inode { + return Some((lock_type.to_string(), lock_access.to_string())); + } + } + None + } +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "wasi", + target_env = "uclibc", + target_os = "freebsd" +))] +mod test_posix_fadvise { + + use nix::errno::Errno; + use nix::fcntl::*; + use nix::unistd::pipe; + use std::os::unix::io::{AsRawFd, RawFd}; + use tempfile::NamedTempFile; + + #[test] + fn test_success() { + let tmp = NamedTempFile::new().unwrap(); + let fd = tmp.as_raw_fd(); + posix_fadvise(fd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED) + .expect("posix_fadvise failed"); + } + + #[test] + fn test_errno() { + let (rd, _wr) = pipe().unwrap(); + let res = posix_fadvise( + rd as RawFd, + 0, + 100, + PosixFadviseAdvice::POSIX_FADV_WILLNEED, + ); + assert_eq!(res, Err(Errno::ESPIPE)); + } +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "wasi", + target_os = "freebsd" +))] +mod test_posix_fallocate { + + use nix::errno::Errno; + use nix::fcntl::*; + use nix::unistd::pipe; + use std::{ + io::Read, + os::unix::io::{AsRawFd, RawFd}, + }; + use tempfile::NamedTempFile; + + #[test] + fn success() { + const LEN: usize = 100; + let mut tmp = NamedTempFile::new().unwrap(); + let fd = tmp.as_raw_fd(); + let res = posix_fallocate(fd, 0, LEN as libc::off_t); + match res { + Ok(_) => { + let mut data = [1u8; LEN]; + assert_eq!(tmp.read(&mut data).expect("read failure"), LEN); + assert_eq!(&data[..], &[0u8; LEN][..]); + } + Err(Errno::EINVAL) => { + // POSIX requires posix_fallocate to return EINVAL both for + // invalid arguments (i.e. len < 0) and if the operation is not + // supported by the file system. + // There's no way to tell for sure whether the file system + // supports posix_fallocate, so we must pass the test if it + // returns EINVAL. + } + _ => res.unwrap(), + } + } + + #[test] + fn errno() { + let (rd, _wr) = pipe().unwrap(); + let err = posix_fallocate(rd as RawFd, 0, 100).unwrap_err(); + match err { + Errno::EINVAL | Errno::ENODEV | Errno::ESPIPE | Errno::EBADF => (), + errno => panic!("unexpected errno {}", errno,), + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/Makefile b/utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/Makefile new file mode 100644 index 00000000..74c99b77 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/Makefile @@ -0,0 +1,7 @@ +obj-m += hello.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean diff --git a/utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/hello.c b/utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/hello.c new file mode 100644 index 00000000..1c34987d --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_kmod/hello_mod/hello.c @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ or MIT + */ +#include +#include + +static int number= 1; +static char *who = "World"; + +module_param(number, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(myint, "Just some number"); +module_param(who, charp, 0000); +MODULE_PARM_DESC(who, "Whot to greet"); + +int init_module(void) +{ + printk(KERN_INFO "Hello %s (%d)!\n", who, number); + return 0; +} + +void cleanup_module(void) +{ + printk(KERN_INFO "Goodbye %s (%d)!\n", who, number); +} + +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/utshell-0.5.0/vendor/nix/test/test_kmod/mod.rs b/utshell-0.5.0/vendor/nix/test/test_kmod/mod.rs new file mode 100644 index 00000000..6f9aaa89 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_kmod/mod.rs @@ -0,0 +1,188 @@ +use crate::*; +use std::fs::copy; +use std::path::PathBuf; +use std::process::Command; +use tempfile::{tempdir, TempDir}; + +fn compile_kernel_module() -> (PathBuf, String, TempDir) { + let _m = crate::FORK_MTX.lock(); + + let tmp_dir = + tempdir().expect("unable to create temporary build directory"); + + copy( + "test/test_kmod/hello_mod/hello.c", + tmp_dir.path().join("hello.c"), + ) + .expect("unable to copy hello.c to temporary build directory"); + copy( + "test/test_kmod/hello_mod/Makefile", + tmp_dir.path().join("Makefile"), + ) + .expect("unable to copy Makefile to temporary build directory"); + + let status = Command::new("make") + .current_dir(tmp_dir.path()) + .status() + .expect("failed to run make"); + + assert!(status.success()); + + // Return the relative path of the build kernel module + (tmp_dir.path().join("hello.ko"), "hello".to_owned(), tmp_dir) +} + +use nix::errno::Errno; +use nix::kmod::{delete_module, DeleteModuleFlags}; +use nix::kmod::{finit_module, init_module, ModuleInitFlags}; +use std::ffi::CString; +use std::fs::File; +use std::io::Read; + +#[test] +fn test_finit_and_delete_module() { + require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let f = File::open(kmod_path).expect("unable to open kernel module"); + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_finit_and_delete_module_with_params() { + require_capability!( + "test_finit_and_delete_module_with_params", + CAP_SYS_MODULE + ); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let f = File::open(kmod_path).expect("unable to open kernel module"); + finit_module( + &f, + &CString::new("who=Rust number=2018").unwrap(), + ModuleInitFlags::empty(), + ) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_init_and_delete_module() { + require_capability!("test_init_and_delete_module", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let mut f = File::open(kmod_path).expect("unable to open kernel module"); + let mut contents: Vec = Vec::new(); + f.read_to_end(&mut contents) + .expect("unable to read kernel module content to buffer"); + init_module(&contents, &CString::new("").unwrap()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_init_and_delete_module_with_params() { + require_capability!( + "test_init_and_delete_module_with_params", + CAP_SYS_MODULE + ); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let mut f = File::open(kmod_path).expect("unable to open kernel module"); + let mut contents: Vec = Vec::new(); + f.read_to_end(&mut contents) + .expect("unable to read kernel module content to buffer"); + init_module(&contents, &CString::new("who=Nix number=2015").unwrap()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_finit_module_invalid() { + require_capability!("test_finit_module_invalid", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let kmod_path = "/dev/zero"; + + let f = File::open(kmod_path).expect("unable to open kernel module"); + let result = + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); + + assert_eq!(result.unwrap_err(), Errno::EINVAL); +} + +#[test] +fn test_finit_module_twice_and_delete_module() { + require_capability!( + "test_finit_module_twice_and_delete_module", + CAP_SYS_MODULE + ); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + + let f = File::open(kmod_path).expect("unable to open kernel module"); + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) + .expect("unable to load kernel module"); + + let result = + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); + + assert_eq!(result.unwrap_err(), Errno::EEXIST); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), + ) + .expect("unable to unload kernel module"); +} + +#[test] +fn test_delete_module_not_loaded() { + require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE); + let _m0 = crate::KMOD_MTX.lock(); + let _m1 = crate::CWD_LOCK.read(); + + let result = delete_module( + &CString::new("hello").unwrap(), + DeleteModuleFlags::empty(), + ); + + assert_eq!(result.unwrap_err(), Errno::ENOENT); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_mount.rs b/utshell-0.5.0/vendor/nix/test/test_mount.rs new file mode 100644 index 00000000..2fd612e3 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_mount.rs @@ -0,0 +1,271 @@ +mod common; + +// Implementation note: to allow unprivileged users to run it, this test makes +// use of user and mount namespaces. On systems that allow unprivileged user +// namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run +// without root. + +#[cfg(target_os = "linux")] +mod test_mount { + use std::fs::{self, File}; + use std::io::{self, Read, Write}; + use std::os::unix::fs::OpenOptionsExt; + use std::os::unix::fs::PermissionsExt; + use std::process::{self, Command}; + + use libc::{EACCES, EROFS}; + + use nix::errno::Errno; + use nix::mount::{mount, umount, MsFlags}; + use nix::sched::{unshare, CloneFlags}; + use nix::sys::stat::{self, Mode}; + use nix::unistd::getuid; + + static SCRIPT_CONTENTS: &[u8] = b"#!/bin/sh +exit 23"; + + const EXPECTED_STATUS: i32 = 23; + + const NONE: Option<&'static [u8]> = None; + #[allow(clippy::bind_instead_of_map)] // False positive + pub fn test_mount_tmpfs_without_flags_allows_rwx() { + let tempdir = tempfile::tempdir().unwrap(); + + mount( + NONE, + tempdir.path(), + Some(b"tmpfs".as_ref()), + MsFlags::empty(), + NONE, + ) + .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + let test_path = tempdir.path().join("test"); + + // Verify write. + fs::OpenOptions::new() + .create(true) + .write(true) + .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits()) + .open(&test_path) + .or_else(|e| { + if Errno::from_i32(e.raw_os_error().unwrap()) + == Errno::EOVERFLOW + { + // Skip tests on certain Linux kernels which have a bug + // regarding tmpfs in namespaces. + // Ubuntu 14.04 and 16.04 are known to be affected; 16.10 is + // not. There is no legitimate reason for open(2) to return + // EOVERFLOW here. + // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1659087 + let stderr = io::stderr(); + let mut handle = stderr.lock(); + writeln!( + handle, + "Buggy Linux kernel detected. Skipping test." + ) + .unwrap(); + process::exit(0); + } else { + panic!("open failed: {}", e); + } + }) + .and_then(|mut f| f.write(SCRIPT_CONTENTS)) + .unwrap_or_else(|e| panic!("write failed: {}", e)); + + // Verify read. + let mut buf = Vec::new(); + File::open(&test_path) + .and_then(|mut f| f.read_to_end(&mut buf)) + .unwrap_or_else(|e| panic!("read failed: {}", e)); + assert_eq!(buf, SCRIPT_CONTENTS); + + // Verify execute. + assert_eq!( + EXPECTED_STATUS, + Command::new(&test_path) + .status() + .unwrap_or_else(|e| panic!("exec failed: {}", e)) + .code() + .unwrap_or_else(|| panic!("child killed by signal")) + ); + + umount(tempdir.path()) + .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + pub fn test_mount_rdonly_disallows_write() { + let tempdir = tempfile::tempdir().unwrap(); + + mount( + NONE, + tempdir.path(), + Some(b"tmpfs".as_ref()), + MsFlags::MS_RDONLY, + NONE, + ) + .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + // EROFS: Read-only file system + assert_eq!( + EROFS, + File::create(tempdir.path().join("test")) + .unwrap_err() + .raw_os_error() + .unwrap() + ); + + umount(tempdir.path()) + .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + pub fn test_mount_noexec_disallows_exec() { + let tempdir = tempfile::tempdir().unwrap(); + + mount( + NONE, + tempdir.path(), + Some(b"tmpfs".as_ref()), + MsFlags::MS_NOEXEC, + NONE, + ) + .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + let test_path = tempdir.path().join("test"); + + fs::OpenOptions::new() + .create(true) + .write(true) + .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits()) + .open(&test_path) + .and_then(|mut f| f.write(SCRIPT_CONTENTS)) + .unwrap_or_else(|e| panic!("write failed: {}", e)); + + // Verify that we cannot execute despite a+x permissions being set. + let mode = stat::Mode::from_bits_truncate( + fs::metadata(&test_path) + .map(|md| md.permissions().mode()) + .unwrap_or_else(|e| panic!("metadata failed: {}", e)), + ); + + assert!( + mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH), + "{:?} did not have execute permissions", + &test_path + ); + + // EACCES: Permission denied + assert_eq!( + EACCES, + Command::new(&test_path) + .status() + .unwrap_err() + .raw_os_error() + .unwrap() + ); + + umount(tempdir.path()) + .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + pub fn test_mount_bind() { + let tempdir = tempfile::tempdir().unwrap(); + let file_name = "test"; + + { + let mount_point = tempfile::tempdir().unwrap(); + + mount( + Some(tempdir.path()), + mount_point.path(), + NONE, + MsFlags::MS_BIND, + NONE, + ) + .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + fs::OpenOptions::new() + .create(true) + .write(true) + .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits()) + .open(mount_point.path().join(file_name)) + .and_then(|mut f| f.write(SCRIPT_CONTENTS)) + .unwrap_or_else(|e| panic!("write failed: {}", e)); + + umount(mount_point.path()) + .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + // Verify the file written in the mount shows up in source directory, even + // after unmounting. + + let mut buf = Vec::new(); + File::open(tempdir.path().join(file_name)) + .and_then(|mut f| f.read_to_end(&mut buf)) + .unwrap_or_else(|e| panic!("read failed: {}", e)); + assert_eq!(buf, SCRIPT_CONTENTS); + } + + pub fn setup_namespaces() { + // Hold on to the uid in the parent namespace. + let uid = getuid(); + + unshare(CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_NEWUSER).unwrap_or_else(|e| { + let stderr = io::stderr(); + let mut handle = stderr.lock(); + writeln!(handle, + "unshare failed: {}. Are unprivileged user namespaces available?", + e).unwrap(); + writeln!(handle, "mount is not being tested").unwrap(); + // Exit with success because not all systems support unprivileged user namespaces, and + // that's not what we're testing for. + process::exit(0); + }); + + // Map user as uid 1000. + fs::OpenOptions::new() + .write(true) + .open("/proc/self/uid_map") + .and_then(|mut f| f.write(format!("1000 {} 1\n", uid).as_bytes())) + .unwrap_or_else(|e| panic!("could not write uid map: {}", e)); + } +} + +// Test runner + +/// Mimic normal test output (hackishly). +#[cfg(target_os = "linux")] +macro_rules! run_tests { + ( $($test_fn:ident),* ) => {{ + println!(); + + $( + print!("test test_mount::{} ... ", stringify!($test_fn)); + $test_fn(); + println!("ok"); + )* + + println!(); + }} +} + +#[cfg(target_os = "linux")] +fn main() { + use test_mount::{ + setup_namespaces, test_mount_bind, test_mount_noexec_disallows_exec, + test_mount_rdonly_disallows_write, + test_mount_tmpfs_without_flags_allows_rwx, + }; + skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1351"); + setup_namespaces(); + + run_tests!( + test_mount_tmpfs_without_flags_allows_rwx, + test_mount_rdonly_disallows_write, + test_mount_noexec_disallows_exec, + test_mount_bind + ); +} + +#[cfg(not(target_os = "linux"))] +fn main() {} diff --git a/utshell-0.5.0/vendor/nix/test/test_mq.rs b/utshell-0.5.0/vendor/nix/test/test_mq.rs new file mode 100644 index 00000000..7b48e7ac --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_mq.rs @@ -0,0 +1,190 @@ +use cfg_if::cfg_if; +use std::ffi::CString; +use std::str; + +use nix::errno::Errno; +use nix::mqueue::{mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send}; +use nix::mqueue::{MQ_OFlag, MqAttr}; +use nix::sys::stat::Mode; + +// Defined as a macro such that the error source is reported as the caller's location. +macro_rules! assert_attr_eq { + ($read_attr:ident, $initial_attr:ident) => { + cfg_if! { + if #[cfg(any(target_os = "dragonfly", target_os = "netbsd"))] { + // NetBSD (and others which inherit its implementation) include other flags + // in read_attr, such as those specified by oflag. Just make sure at least + // the correct bits are set. + assert_eq!($read_attr.flags() & $initial_attr.flags(), $initial_attr.flags()); + assert_eq!($read_attr.maxmsg(), $initial_attr.maxmsg()); + assert_eq!($read_attr.msgsize(), $initial_attr.msgsize()); + assert_eq!($read_attr.curmsgs(), $initial_attr.curmsgs()); + } else { + assert_eq!($read_attr, $initial_attr); + } + } + } +} + +#[test] +fn test_mq_send_and_receive() { + const MSG_SIZE: mq_attr_member_t = 32; + let attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/a_nix_test_queue".as_ref()).unwrap(); + + let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r0 = mq_open(mq_name, oflag0, mode, Some(&attr)); + if let Err(Errno::ENOSYS) = r0 { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd0 = r0.unwrap(); + let msg_to_send = "msg_1"; + mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap(); + + let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY; + let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap(); + let mut buf = [0u8; 32]; + let mut prio = 0u32; + let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap(); + assert_eq!(prio, 1); + + mq_close(mqd1).unwrap(); + mq_close(mqd0).unwrap(); + assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap()); +} + +#[test] +fn test_mq_getattr() { + use nix::mqueue::mq_getattr; + const MSG_SIZE: mq_attr_member_t = 32; + let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name, oflag, mode, Some(&initial_attr)); + if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + + let read_attr = mq_getattr(&mqd).unwrap(); + assert_attr_eq!(read_attr, initial_attr); + mq_close(mqd).unwrap(); +} + +// FIXME: Fix failures for mips in QEMU +#[test] +#[cfg_attr( + all(qemu, any(target_arch = "mips", target_arch = "mips64")), + ignore +)] +fn test_mq_setattr() { + use nix::mqueue::{mq_getattr, mq_setattr}; + const MSG_SIZE: mq_attr_member_t = 32; + let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name, oflag, mode, Some(&initial_attr)); + if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + + let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100); + let old_attr = mq_setattr(&mqd, &new_attr).unwrap(); + assert_attr_eq!(old_attr, initial_attr); + + // No changes here because according to the Linux man page only + // O_NONBLOCK can be set (see tests below) + #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] + { + let new_attr_get = mq_getattr(&mqd).unwrap(); + assert_ne!(new_attr_get, new_attr); + } + + let new_attr_non_blocking = MqAttr::new( + MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t, + 10, + MSG_SIZE, + 0, + ); + mq_setattr(&mqd, &new_attr_non_blocking).unwrap(); + let new_attr_get = mq_getattr(&mqd).unwrap(); + + // now the O_NONBLOCK flag has been set + #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] + { + assert_ne!(new_attr_get, initial_attr); + } + assert_attr_eq!(new_attr_get, new_attr_non_blocking); + mq_close(mqd).unwrap(); +} + +// FIXME: Fix failures for mips in QEMU +#[test] +#[cfg_attr( + all(qemu, any(target_arch = "mips", target_arch = "mips64")), + ignore +)] +fn test_mq_set_nonblocking() { + use nix::mqueue::{mq_getattr, mq_remove_nonblock, mq_set_nonblock}; + const MSG_SIZE: mq_attr_member_t = 32; + let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name, oflag, mode, Some(&initial_attr)); + if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + mq_set_nonblock(&mqd).unwrap(); + let new_attr = mq_getattr(&mqd); + let o_nonblock_bits = MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t; + assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, o_nonblock_bits); + mq_remove_nonblock(&mqd).unwrap(); + let new_attr = mq_getattr(&mqd); + assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, 0); + mq_close(mqd).unwrap(); +} + +#[test] +fn test_mq_unlink() { + use nix::mqueue::mq_unlink; + const MSG_SIZE: mq_attr_member_t = 32; + let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap(); + #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] + let mq_name_not_opened = + &CString::new(b"/mq_unlink_test".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name_opened, oflag, mode, Some(&initial_attr)); + if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + + let res_unlink = mq_unlink(mq_name_opened); + assert_eq!(res_unlink, Ok(())); + + // NetBSD (and others which inherit its implementation) defer removing the message + // queue name until all references are closed, whereas Linux and others remove the + // message queue name immediately. + #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] + { + let res_unlink_not_opened = mq_unlink(mq_name_not_opened); + assert_eq!(res_unlink_not_opened, Err(Errno::ENOENT)); + } + + mq_close(mqd).unwrap(); + let res_unlink_after_close = mq_unlink(mq_name_opened); + assert_eq!(res_unlink_after_close, Err(Errno::ENOENT)); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_net.rs b/utshell-0.5.0/vendor/nix/test/test_net.rs new file mode 100644 index 00000000..c44655a4 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_net.rs @@ -0,0 +1,19 @@ +use nix::net::if_::*; + +#[cfg(any(target_os = "android", target_os = "linux"))] +const LOOPBACK: &[u8] = b"lo"; + +#[cfg(not(any( + target_os = "android", + target_os = "linux", + target_os = "haiku" +)))] +const LOOPBACK: &[u8] = b"lo0"; + +#[cfg(target_os = "haiku")] +const LOOPBACK: &[u8] = b"loop"; + +#[test] +fn test_if_nametoindex() { + if_nametoindex(LOOPBACK).expect("assertion failed"); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_nix_path.rs b/utshell-0.5.0/vendor/nix/test/test_nix_path.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_nix_path.rs @@ -0,0 +1 @@ + diff --git a/utshell-0.5.0/vendor/nix/test/test_nmount.rs b/utshell-0.5.0/vendor/nix/test/test_nmount.rs new file mode 100644 index 00000000..dec806a5 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_nmount.rs @@ -0,0 +1,49 @@ +use crate::*; +use nix::{ + errno::Errno, + mount::{unmount, MntFlags, Nmount}, +}; +use std::{ffi::CString, fs::File, path::Path}; +use tempfile::tempdir; + +#[test] +fn ok() { + require_mount!("nullfs"); + + let mountpoint = tempdir().unwrap(); + let target = tempdir().unwrap(); + let _sentry = File::create(target.path().join("sentry")).unwrap(); + + let fstype = CString::new("fstype").unwrap(); + let nullfs = CString::new("nullfs").unwrap(); + Nmount::new() + .str_opt(&fstype, &nullfs) + .str_opt_owned("fspath", mountpoint.path().to_str().unwrap()) + .str_opt_owned("target", target.path().to_str().unwrap()) + .nmount(MntFlags::empty()) + .unwrap(); + + // Now check that the sentry is visible through the mountpoint + let exists = Path::exists(&mountpoint.path().join("sentry")); + + // Cleanup the mountpoint before asserting + unmount(mountpoint.path(), MntFlags::empty()).unwrap(); + + assert!(exists); +} + +#[test] +fn bad_fstype() { + let mountpoint = tempdir().unwrap(); + let target = tempdir().unwrap(); + let _sentry = File::create(target.path().join("sentry")).unwrap(); + + let e = Nmount::new() + .str_opt_owned("fspath", mountpoint.path().to_str().unwrap()) + .str_opt_owned("target", target.path().to_str().unwrap()) + .nmount(MntFlags::empty()) + .unwrap_err(); + + assert_eq!(e.error(), Errno::EINVAL); + assert_eq!(e.errmsg(), Some("Invalid fstype")); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_poll.rs b/utshell-0.5.0/vendor/nix/test/test_poll.rs new file mode 100644 index 00000000..53964e26 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_poll.rs @@ -0,0 +1,84 @@ +use nix::{ + errno::Errno, + poll::{poll, PollFd, PollFlags}, + unistd::{pipe, write}, +}; + +macro_rules! loop_while_eintr { + ($poll_expr: expr) => { + loop { + match $poll_expr { + Ok(nfds) => break nfds, + Err(Errno::EINTR) => (), + Err(e) => panic!("{}", e), + } + } + }; +} + +#[test] +fn test_poll() { + let (r, w) = pipe().unwrap(); + let mut fds = [PollFd::new(r, PollFlags::POLLIN)]; + + // Poll an idle pipe. Should timeout + let nfds = loop_while_eintr!(poll(&mut fds, 100)); + assert_eq!(nfds, 0); + assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN)); + + write(w, b".").unwrap(); + + // Poll a readable pipe. Should return an event. + let nfds = poll(&mut fds, 100).unwrap(); + assert_eq!(nfds, 1); + assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN)); +} + +// ppoll(2) is the same as poll except for how it handles timeouts and signals. +// Repeating the test for poll(2) should be sufficient to check that our +// bindings are correct. +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux" +))] +#[test] +fn test_ppoll() { + use nix::poll::ppoll; + use nix::sys::signal::SigSet; + use nix::sys::time::{TimeSpec, TimeValLike}; + + let timeout = TimeSpec::milliseconds(1); + let (r, w) = pipe().unwrap(); + let mut fds = [PollFd::new(r, PollFlags::POLLIN)]; + + // Poll an idle pipe. Should timeout + let sigset = SigSet::empty(); + let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), Some(sigset))); + assert_eq!(nfds, 0); + assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN)); + + write(w, b".").unwrap(); + + // Poll a readable pipe. Should return an event. + let nfds = ppoll(&mut fds, Some(timeout), None).unwrap(); + assert_eq!(nfds, 1); + assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN)); +} + +#[test] +fn test_pollfd_fd() { + use std::os::unix::io::AsRawFd; + + let pfd = PollFd::new(0x1234, PollFlags::empty()); + assert_eq!(pfd.as_raw_fd(), 0x1234); +} + +#[test] +fn test_pollfd_events() { + let mut pfd = PollFd::new(-1, PollFlags::POLLIN); + assert_eq!(pfd.events(), PollFlags::POLLIN); + pfd.set_events(PollFlags::POLLOUT); + assert_eq!(pfd.events(), PollFlags::POLLOUT); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_pty.rs b/utshell-0.5.0/vendor/nix/test/test_pty.rs new file mode 100644 index 00000000..5c27e2d6 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_pty.rs @@ -0,0 +1,313 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::os::unix::prelude::*; +use std::path::Path; +use tempfile::tempfile; + +use libc::{_exit, STDOUT_FILENO}; +use nix::fcntl::{open, OFlag}; +use nix::pty::*; +use nix::sys::stat; +use nix::sys::termios::*; +use nix::unistd::{close, pause, write}; + +/// Regression test for Issue #659 +/// This is the correct way to explicitly close a `PtyMaster` +#[test] +fn test_explicit_close() { + let mut f = { + let m = posix_openpt(OFlag::O_RDWR).unwrap(); + close(m.into_raw_fd()).unwrap(); + tempfile().unwrap() + }; + // This should work. But if there's been a double close, then it will + // return EBADF + f.write_all(b"whatever").unwrap(); +} + +/// Test equivalence of `ptsname` and `ptsname_r` +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptsname_equivalence() { + let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); + assert!(master_fd.as_raw_fd() > 0); + + // Get the name of the slave + let slave_name = unsafe { ptsname(&master_fd) }.unwrap(); + let slave_name_r = ptsname_r(&master_fd).unwrap(); + assert_eq!(slave_name, slave_name_r); +} + +/// Test data copying of `ptsname` +// TODO need to run in a subprocess, since ptsname is non-reentrant +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptsname_copy() { + let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); + assert!(master_fd.as_raw_fd() > 0); + + // Get the name of the slave + let slave_name1 = unsafe { ptsname(&master_fd) }.unwrap(); + let slave_name2 = unsafe { ptsname(&master_fd) }.unwrap(); + assert_eq!(slave_name1, slave_name2); + // Also make sure that the string was actually copied and they point to different parts of + // memory. + assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr()); +} + +/// Test data copying of `ptsname_r` +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptsname_r_copy() { + // Open a new PTTY master + let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); + assert!(master_fd.as_raw_fd() > 0); + + // Get the name of the slave + let slave_name1 = ptsname_r(&master_fd).unwrap(); + let slave_name2 = ptsname_r(&master_fd).unwrap(); + assert_eq!(slave_name1, slave_name2); + assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr()); +} + +/// Test that `ptsname` returns different names for different devices +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +fn test_ptsname_unique() { + let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap(); + assert!(master1_fd.as_raw_fd() > 0); + + // Open a second PTTY master + let master2_fd = posix_openpt(OFlag::O_RDWR).unwrap(); + assert!(master2_fd.as_raw_fd() > 0); + + // Get the name of the slave + let slave_name1 = unsafe { ptsname(&master1_fd) }.unwrap(); + let slave_name2 = unsafe { ptsname(&master2_fd) }.unwrap(); + assert_ne!(slave_name1, slave_name2); +} + +/// Common setup for testing PTTY pairs +fn open_ptty_pair() -> (PtyMaster, File) { + let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed"); + + // Allow a slave to be generated for it + grantpt(&master).expect("grantpt failed"); + unlockpt(&master).expect("unlockpt failed"); + + // Get the name of the slave + let slave_name = unsafe { ptsname(&master) }.expect("ptsname failed"); + + // Open the slave device + let slave_fd = + open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()) + .unwrap(); + + #[cfg(target_os = "illumos")] + // TODO: rewrite using ioctl! + #[allow(clippy::comparison_chain)] + { + use libc::{ioctl, I_FIND, I_PUSH}; + + // On illumos systems, as per pts(7D), one must push STREAMS modules + // after opening a device path returned from ptsname(). + let ptem = b"ptem\0"; + let ldterm = b"ldterm\0"; + let r = unsafe { ioctl(slave_fd, I_FIND, ldterm.as_ptr()) }; + if r < 0 { + panic!("I_FIND failure"); + } else if r == 0 { + if unsafe { ioctl(slave_fd, I_PUSH, ptem.as_ptr()) } < 0 { + panic!("I_PUSH ptem failure"); + } + if unsafe { ioctl(slave_fd, I_PUSH, ldterm.as_ptr()) } < 0 { + panic!("I_PUSH ldterm failure"); + } + } + } + + let slave = unsafe { File::from_raw_fd(slave_fd) }; + + (master, slave) +} + +/// Test opening a master/slave PTTY pair +/// +/// This uses a common `open_ptty_pair` because much of these functions aren't useful by +/// themselves. So for this test we perform the basic act of getting a file handle for a +/// master/slave PTTY pair, then just sanity-check the raw values. +#[test] +fn test_open_ptty_pair() { + let (master, slave) = open_ptty_pair(); + assert!(master.as_raw_fd() > 0); + assert!(slave.as_raw_fd() > 0); +} + +/// Put the terminal in raw mode. +fn make_raw(fd: RawFd) { + let mut termios = tcgetattr(fd).unwrap(); + cfmakeraw(&mut termios); + tcsetattr(fd, SetArg::TCSANOW, &termios).unwrap(); +} + +/// Test `io::Read` on the PTTY master +#[test] +fn test_read_ptty_pair() { + let (mut master, mut slave) = open_ptty_pair(); + make_raw(slave.as_raw_fd()); + + let mut buf = [0u8; 5]; + slave.write_all(b"hello").unwrap(); + master.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"hello"); + + let mut master = &master; + slave.write_all(b"hello").unwrap(); + master.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"hello"); +} + +/// Test `io::Write` on the PTTY master +#[test] +fn test_write_ptty_pair() { + let (mut master, mut slave) = open_ptty_pair(); + make_raw(slave.as_raw_fd()); + + let mut buf = [0u8; 5]; + master.write_all(b"adios").unwrap(); + slave.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"adios"); + + let mut master = &master; + master.write_all(b"adios").unwrap(); + slave.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"adios"); +} + +#[test] +fn test_openpty() { + // openpty uses ptname(3) internally + let _m = crate::PTSNAME_MTX.lock(); + + let pty = openpty(None, None).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); + + // Writing to one should be readable on the other one + let string = "foofoofoo\n"; + let mut buf = [0u8; 10]; + write(pty.master, string.as_bytes()).unwrap(); + crate::read_exact(pty.slave, &mut buf); + + assert_eq!(&buf, string.as_bytes()); + + // Read the echo as well + let echoed_string = "foofoofoo\r\n"; + let mut buf = [0u8; 11]; + crate::read_exact(pty.master, &mut buf); + assert_eq!(&buf, echoed_string.as_bytes()); + + let string2 = "barbarbarbar\n"; + let echoed_string2 = "barbarbarbar\r\n"; + let mut buf = [0u8; 14]; + write(pty.slave, string2.as_bytes()).unwrap(); + crate::read_exact(pty.master, &mut buf); + + assert_eq!(&buf, echoed_string2.as_bytes()); + + close(pty.master).unwrap(); + close(pty.slave).unwrap(); +} + +#[test] +fn test_openpty_with_termios() { + // openpty uses ptname(3) internally + let _m = crate::PTSNAME_MTX.lock(); + + // Open one pty to get attributes for the second one + let mut termios = { + let pty = openpty(None, None).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); + let termios = tcgetattr(pty.slave).unwrap(); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + termios + }; + // Make sure newlines are not transformed so the data is preserved when sent. + termios.output_flags.remove(OutputFlags::ONLCR); + + let pty = openpty(None, &termios).unwrap(); + // Must be valid file descriptors + assert!(pty.master > 0); + assert!(pty.slave > 0); + + // Writing to one should be readable on the other one + let string = "foofoofoo\n"; + let mut buf = [0u8; 10]; + write(pty.master, string.as_bytes()).unwrap(); + crate::read_exact(pty.slave, &mut buf); + + assert_eq!(&buf, string.as_bytes()); + + // read the echo as well + let echoed_string = "foofoofoo\n"; + crate::read_exact(pty.master, &mut buf); + assert_eq!(&buf, echoed_string.as_bytes()); + + let string2 = "barbarbarbar\n"; + let echoed_string2 = "barbarbarbar\n"; + let mut buf = [0u8; 13]; + write(pty.slave, string2.as_bytes()).unwrap(); + crate::read_exact(pty.master, &mut buf); + + assert_eq!(&buf, echoed_string2.as_bytes()); + + close(pty.master).unwrap(); + close(pty.slave).unwrap(); +} + +#[test] +fn test_forkpty() { + use nix::sys::signal::*; + use nix::sys::wait::wait; + use nix::unistd::ForkResult::*; + // forkpty calls openpty which uses ptname(3) internally. + let _m0 = crate::PTSNAME_MTX.lock(); + // forkpty spawns a child process + let _m1 = crate::FORK_MTX.lock(); + + let string = "naninani\n"; + let echoed_string = "naninani\r\n"; + let pty = unsafe { forkpty(None, None).unwrap() }; + match pty.fork_result { + Child => { + write(STDOUT_FILENO, string.as_bytes()).unwrap(); + pause(); // we need the child to stay alive until the parent calls read + unsafe { + _exit(0); + } + } + Parent { child } => { + let mut buf = [0u8; 10]; + assert!(child.as_raw() > 0); + crate::read_exact(pty.master, &mut buf); + kill(child, SIGTERM).unwrap(); + wait().unwrap(); // keep other tests using generic wait from getting our child + assert_eq!(&buf, echoed_string.as_bytes()); + close(pty.master).unwrap(); + } + } +} diff --git a/utshell-0.5.0/vendor/nix/test/test_ptymaster_drop.rs b/utshell-0.5.0/vendor/nix/test/test_ptymaster_drop.rs new file mode 100644 index 00000000..ffbaa569 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_ptymaster_drop.rs @@ -0,0 +1,20 @@ +#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] +mod t { + use nix::fcntl::OFlag; + use nix::pty::*; + use nix::unistd::close; + use std::os::unix::io::AsRawFd; + + /// Regression test for Issue #659 + /// + /// `PtyMaster` should panic rather than double close the file descriptor + /// This must run in its own test process because it deliberately creates a + /// race condition. + #[test] + #[should_panic(expected = "Closing an invalid file descriptor!")] + fn test_double_close() { + let m = posix_openpt(OFlag::O_RDWR).unwrap(); + close(m.as_raw_fd()).unwrap(); + drop(m); // should panic here + } +} diff --git a/utshell-0.5.0/vendor/nix/test/test_resource.rs b/utshell-0.5.0/vendor/nix/test/test_resource.rs new file mode 100644 index 00000000..2ab581ba --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_resource.rs @@ -0,0 +1,34 @@ +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "illumos", + target_os = "haiku" +)))] +use nix::sys::resource::{getrlimit, setrlimit, Resource}; + +/// Tests the RLIMIT_NOFILE functionality of getrlimit(), where the resource RLIMIT_NOFILE refers +/// to the maximum file descriptor number that can be opened by the process (aka the maximum number +/// of file descriptors that the process can open, since Linux 4.5). +/// +/// We first fetch the existing file descriptor maximum values using getrlimit(), then edit the +/// soft limit to make sure it has a new and distinct value to the hard limit. We then setrlimit() +/// to put the new soft limit in effect, and then getrlimit() once more to ensure the limits have +/// been updated. +#[test] +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "illumos", + target_os = "haiku" +)))] +pub fn test_resource_limits_nofile() { + let (mut soft_limit, hard_limit) = + getrlimit(Resource::RLIMIT_NOFILE).unwrap(); + + soft_limit -= 1; + assert_ne!(soft_limit, hard_limit); + setrlimit(Resource::RLIMIT_NOFILE, soft_limit, hard_limit).unwrap(); + + let (new_soft_limit, _) = getrlimit(Resource::RLIMIT_NOFILE).unwrap(); + assert_eq!(new_soft_limit, soft_limit); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_sched.rs b/utshell-0.5.0/vendor/nix/test/test_sched.rs new file mode 100644 index 00000000..ebf346db --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_sched.rs @@ -0,0 +1,35 @@ +use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet}; +use nix::unistd::Pid; + +#[test] +fn test_sched_affinity() { + // If pid is zero, then the mask of the calling process is returned. + let initial_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap(); + let mut at_least_one_cpu = false; + let mut last_valid_cpu = 0; + for field in 0..CpuSet::count() { + if initial_affinity.is_set(field).unwrap() { + at_least_one_cpu = true; + last_valid_cpu = field; + } + } + assert!(at_least_one_cpu); + + // Now restrict the running CPU + let mut new_affinity = CpuSet::new(); + new_affinity.set(last_valid_cpu).unwrap(); + sched_setaffinity(Pid::from_raw(0), &new_affinity).unwrap(); + + // And now re-check the affinity which should be only the one we set. + let updated_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap(); + for field in 0..CpuSet::count() { + // Should be set only for the CPU we set previously + assert_eq!( + updated_affinity.is_set(field).unwrap(), + field == last_valid_cpu + ) + } + + // Finally, reset the initial CPU set + sched_setaffinity(Pid::from_raw(0), &initial_affinity).unwrap(); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_sendfile.rs b/utshell-0.5.0/vendor/nix/test/test_sendfile.rs new file mode 100644 index 00000000..f73a3b56 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_sendfile.rs @@ -0,0 +1,208 @@ +use std::io::prelude::*; +use std::os::unix::prelude::*; + +use libc::off_t; +use nix::sys::sendfile::*; +use tempfile::tempfile; + +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + use nix::unistd::{close, pipe, read}; + } else if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos"))] { + use std::net::Shutdown; + use std::os::unix::net::UnixStream; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[test] +fn test_sendfile_linux() { + const CONTENTS: &[u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + + let (rd, wr) = pipe().unwrap(); + let mut offset: off_t = 5; + let res = sendfile(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap(); + + assert_eq!(2, res); + + let mut buf = [0u8; 1024]; + assert_eq!(2, read(rd, &mut buf).unwrap()); + assert_eq!(b"f1", &buf[0..2]); + assert_eq!(7, offset); + + close(rd).unwrap(); + close(wr).unwrap(); +} + +#[cfg(target_os = "linux")] +#[test] +fn test_sendfile64_linux() { + const CONTENTS: &[u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + + let (rd, wr) = pipe().unwrap(); + let mut offset: libc::off64_t = 5; + let res = sendfile64(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap(); + + assert_eq!(2, res); + + let mut buf = [0u8; 1024]; + assert_eq!(2, read(rd, &mut buf).unwrap()); + assert_eq!(b"f1", &buf[0..2]); + assert_eq!(7, offset); + + close(rd).unwrap(); + close(wr).unwrap(); +} + +#[cfg(target_os = "freebsd")] +#[test] +fn test_sendfile_freebsd() { + // Declare the content + let header_strings = + vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; + let body = "Xabcdef123456"; + let body_offset = 1; + let trailer_strings = vec!["\n", "Served by Make Believe\n"]; + + // Write the body to a file + let mut tmp = tempfile().unwrap(); + tmp.write_all(body.as_bytes()).unwrap(); + + // Prepare headers and trailers for sendfile + let headers: Vec<&[u8]> = + header_strings.iter().map(|s| s.as_bytes()).collect(); + let trailers: Vec<&[u8]> = + trailer_strings.iter().map(|s| s.as_bytes()).collect(); + + // Prepare socket pair + let (mut rd, wr) = UnixStream::pair().unwrap(); + + // Call the test method + let (res, bytes_written) = sendfile( + tmp.as_raw_fd(), + wr.as_raw_fd(), + body_offset as off_t, + None, + Some(headers.as_slice()), + Some(trailers.as_slice()), + SfFlags::empty(), + 0, + ); + assert!(res.is_ok()); + wr.shutdown(Shutdown::Both).unwrap(); + + // Prepare the expected result + let expected_string = header_strings.concat() + + &body[body_offset..] + + &trailer_strings.concat(); + + // Verify the message that was sent + assert_eq!(bytes_written as usize, expected_string.as_bytes().len()); + + let mut read_string = String::new(); + let bytes_read = rd.read_to_string(&mut read_string).unwrap(); + assert_eq!(bytes_written as usize, bytes_read); + assert_eq!(expected_string, read_string); +} + +#[cfg(target_os = "dragonfly")] +#[test] +fn test_sendfile_dragonfly() { + // Declare the content + let header_strings = + vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; + let body = "Xabcdef123456"; + let body_offset = 1; + let trailer_strings = vec!["\n", "Served by Make Believe\n"]; + + // Write the body to a file + let mut tmp = tempfile().unwrap(); + tmp.write_all(body.as_bytes()).unwrap(); + + // Prepare headers and trailers for sendfile + let headers: Vec<&[u8]> = + header_strings.iter().map(|s| s.as_bytes()).collect(); + let trailers: Vec<&[u8]> = + trailer_strings.iter().map(|s| s.as_bytes()).collect(); + + // Prepare socket pair + let (mut rd, wr) = UnixStream::pair().unwrap(); + + // Call the test method + let (res, bytes_written) = sendfile( + tmp.as_raw_fd(), + wr.as_raw_fd(), + body_offset as off_t, + None, + Some(headers.as_slice()), + Some(trailers.as_slice()), + ); + assert!(res.is_ok()); + wr.shutdown(Shutdown::Both).unwrap(); + + // Prepare the expected result + let expected_string = header_strings.concat() + + &body[body_offset..] + + &trailer_strings.concat(); + + // Verify the message that was sent + assert_eq!(bytes_written as usize, expected_string.as_bytes().len()); + + let mut read_string = String::new(); + let bytes_read = rd.read_to_string(&mut read_string).unwrap(); + assert_eq!(bytes_written as usize, bytes_read); + assert_eq!(expected_string, read_string); +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +#[test] +fn test_sendfile_darwin() { + // Declare the content + let header_strings = + vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; + let body = "Xabcdef123456"; + let body_offset = 1; + let trailer_strings = vec!["\n", "Served by Make Believe\n"]; + + // Write the body to a file + let mut tmp = tempfile().unwrap(); + tmp.write_all(body.as_bytes()).unwrap(); + + // Prepare headers and trailers for sendfile + let headers: Vec<&[u8]> = + header_strings.iter().map(|s| s.as_bytes()).collect(); + let trailers: Vec<&[u8]> = + trailer_strings.iter().map(|s| s.as_bytes()).collect(); + + // Prepare socket pair + let (mut rd, wr) = UnixStream::pair().unwrap(); + + // Call the test method + let (res, bytes_written) = sendfile( + tmp.as_raw_fd(), + wr.as_raw_fd(), + body_offset as off_t, + None, + Some(headers.as_slice()), + Some(trailers.as_slice()), + ); + assert!(res.is_ok()); + wr.shutdown(Shutdown::Both).unwrap(); + + // Prepare the expected result + let expected_string = header_strings.concat() + + &body[body_offset..] + + &trailer_strings.concat(); + + // Verify the message that was sent + assert_eq!(bytes_written as usize, expected_string.as_bytes().len()); + + let mut read_string = String::new(); + let bytes_read = rd.read_to_string(&mut read_string).unwrap(); + assert_eq!(bytes_written as usize, bytes_read); + assert_eq!(expected_string, read_string); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_stat.rs b/utshell-0.5.0/vendor/nix/test/test_stat.rs new file mode 100644 index 00000000..55f15c07 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_stat.rs @@ -0,0 +1,421 @@ +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use std::fs; +use std::fs::File; +#[cfg(not(target_os = "redox"))] +use std::os::unix::fs::symlink; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use std::os::unix::fs::PermissionsExt; +use std::os::unix::prelude::AsRawFd; +#[cfg(not(target_os = "redox"))] +use std::path::Path; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use std::time::{Duration, UNIX_EPOCH}; + +use libc::mode_t; +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +use libc::{S_IFLNK, S_IFMT}; + +#[cfg(not(target_os = "redox"))] +use nix::errno::Errno; +#[cfg(not(target_os = "redox"))] +use nix::fcntl; +#[cfg(any( + target_os = "linux", + target_os = "ios", + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd" +))] +use nix::sys::stat::lutimes; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use nix::sys::stat::utimensat; +#[cfg(not(target_os = "redox"))] +use nix::sys::stat::FchmodatFlags; +use nix::sys::stat::Mode; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use nix::sys::stat::UtimensatFlags; +#[cfg(not(target_os = "redox"))] +use nix::sys::stat::{self}; +use nix::sys::stat::{fchmod, stat}; +#[cfg(not(target_os = "redox"))] +use nix::sys::stat::{fchmodat, mkdirat}; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use nix::sys::stat::{futimens, utimes}; + +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +use nix::sys::stat::FileStat; + +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use nix::sys::time::{TimeSpec, TimeVal, TimeValLike}; +#[cfg(not(target_os = "redox"))] +use nix::unistd::chdir; + +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +use nix::Result; + +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +fn assert_stat_results(stat_result: Result) { + let stats = stat_result.expect("stat call failed"); + assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent + assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent + assert!(stats.st_mode > 0); // must be positive integer + assert_eq!(stats.st_nlink, 1); // there links created, must be 1 + assert_eq!(stats.st_size, 0); // size is 0 because we did not write anything to the file + assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent + assert!(stats.st_blocks <= 16); // Up to 16 blocks can be allocated for a blank file +} + +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +// (Android's st_blocks is ulonglong which is always non-negative.) +#[cfg_attr(target_os = "android", allow(unused_comparisons))] +#[allow(clippy::absurd_extreme_comparisons)] // Not absurd on all OSes +fn assert_lstat_results(stat_result: Result) { + let stats = stat_result.expect("stat call failed"); + assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent + assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent + assert!(stats.st_mode > 0); // must be positive integer + + // st_mode is c_uint (u32 on Android) while S_IFMT is mode_t + // (u16 on Android), and that will be a compile error. + // On other platforms they are the same (either both are u16 or u32). + assert_eq!( + (stats.st_mode as usize) & (S_IFMT as usize), + S_IFLNK as usize + ); // should be a link + assert_eq!(stats.st_nlink, 1); // there links created, must be 1 + assert!(stats.st_size > 0); // size is > 0 because it points to another file + assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent + + // st_blocks depends on whether the machine's file system uses fast + // or slow symlinks, so just make sure it's not negative + assert!(stats.st_blocks >= 0); +} + +#[test] +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +fn test_stat_and_fstat() { + use nix::sys::stat::fstat; + + let tempdir = tempfile::tempdir().unwrap(); + let filename = tempdir.path().join("foo.txt"); + let file = File::create(&filename).unwrap(); + + let stat_result = stat(&filename); + assert_stat_results(stat_result); + + let fstat_result = fstat(file.as_raw_fd()); + assert_stat_results(fstat_result); +} + +#[test] +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +fn test_fstatat() { + let tempdir = tempfile::tempdir().unwrap(); + let filename = tempdir.path().join("foo.txt"); + File::create(&filename).unwrap(); + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()); + + let result = + stat::fstatat(dirfd.unwrap(), &filename, fcntl::AtFlags::empty()); + assert_stat_results(result); +} + +#[test] +#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] +fn test_stat_fstat_lstat() { + use nix::sys::stat::{fstat, lstat}; + + let tempdir = tempfile::tempdir().unwrap(); + let filename = tempdir.path().join("bar.txt"); + let linkname = tempdir.path().join("barlink"); + + File::create(&filename).unwrap(); + symlink("bar.txt", &linkname).unwrap(); + let link = File::open(&linkname).unwrap(); + + // should be the same result as calling stat, + // since it's a regular file + let stat_result = stat(&filename); + assert_stat_results(stat_result); + + let lstat_result = lstat(&linkname); + assert_lstat_results(lstat_result); + + let fstat_result = fstat(link.as_raw_fd()); + assert_stat_results(fstat_result); +} + +#[test] +fn test_fchmod() { + let tempdir = tempfile::tempdir().unwrap(); + let filename = tempdir.path().join("foo.txt"); + let file = File::create(&filename).unwrap(); + + let mut mode1 = Mode::empty(); + mode1.insert(Mode::S_IRUSR); + mode1.insert(Mode::S_IWUSR); + fchmod(file.as_raw_fd(), mode1).unwrap(); + + let file_stat1 = stat(&filename).unwrap(); + assert_eq!(file_stat1.st_mode as mode_t & 0o7777, mode1.bits()); + + let mut mode2 = Mode::empty(); + mode2.insert(Mode::S_IROTH); + fchmod(file.as_raw_fd(), mode2).unwrap(); + + let file_stat2 = stat(&filename).unwrap(); + assert_eq!(file_stat2.st_mode as mode_t & 0o7777, mode2.bits()); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_fchmodat() { + let _dr = crate::DirRestore::new(); + let tempdir = tempfile::tempdir().unwrap(); + let filename = "foo.txt"; + let fullpath = tempdir.path().join(filename); + File::create(&fullpath).unwrap(); + + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + let mut mode1 = Mode::empty(); + mode1.insert(Mode::S_IRUSR); + mode1.insert(Mode::S_IWUSR); + fchmodat(Some(dirfd), filename, mode1, FchmodatFlags::FollowSymlink) + .unwrap(); + + let file_stat1 = stat(&fullpath).unwrap(); + assert_eq!(file_stat1.st_mode as mode_t & 0o7777, mode1.bits()); + + chdir(tempdir.path()).unwrap(); + + let mut mode2 = Mode::empty(); + mode2.insert(Mode::S_IROTH); + fchmodat(None, filename, mode2, FchmodatFlags::FollowSymlink).unwrap(); + + let file_stat2 = stat(&fullpath).unwrap(); + assert_eq!(file_stat2.st_mode as mode_t & 0o7777, mode2.bits()); +} + +/// Asserts that the atime and mtime in a file's metadata match expected values. +/// +/// The atime and mtime are expressed with a resolution of seconds because some file systems +/// (like macOS's HFS+) do not have higher granularity. +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn assert_times_eq( + exp_atime_sec: u64, + exp_mtime_sec: u64, + attr: &fs::Metadata, +) { + assert_eq!( + Duration::new(exp_atime_sec, 0), + attr.accessed().unwrap().duration_since(UNIX_EPOCH).unwrap() + ); + assert_eq!( + Duration::new(exp_mtime_sec, 0), + attr.modified().unwrap().duration_since(UNIX_EPOCH).unwrap() + ); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_utimes() { + let tempdir = tempfile::tempdir().unwrap(); + let fullpath = tempdir.path().join("file"); + drop(File::create(&fullpath).unwrap()); + + utimes(&fullpath, &TimeVal::seconds(9990), &TimeVal::seconds(5550)) + .unwrap(); + assert_times_eq(9990, 5550, &fs::metadata(&fullpath).unwrap()); +} + +#[test] +#[cfg(any( + target_os = "linux", + target_os = "ios", + target_os = "macos", + target_os = "freebsd", + target_os = "netbsd" +))] +fn test_lutimes() { + let tempdir = tempfile::tempdir().unwrap(); + let target = tempdir.path().join("target"); + let fullpath = tempdir.path().join("symlink"); + drop(File::create(&target).unwrap()); + symlink(&target, &fullpath).unwrap(); + + let exp_target_metadata = fs::symlink_metadata(&target).unwrap(); + lutimes(&fullpath, &TimeVal::seconds(4560), &TimeVal::seconds(1230)) + .unwrap(); + assert_times_eq(4560, 1230, &fs::symlink_metadata(&fullpath).unwrap()); + + let target_metadata = fs::symlink_metadata(&target).unwrap(); + assert_eq!( + exp_target_metadata.accessed().unwrap(), + target_metadata.accessed().unwrap(), + "atime of symlink target was unexpectedly modified" + ); + assert_eq!( + exp_target_metadata.modified().unwrap(), + target_metadata.modified().unwrap(), + "mtime of symlink target was unexpectedly modified" + ); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_futimens() { + let tempdir = tempfile::tempdir().unwrap(); + let fullpath = tempdir.path().join("file"); + drop(File::create(&fullpath).unwrap()); + + let fd = fcntl::open(&fullpath, fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + futimens(fd, &TimeSpec::seconds(10), &TimeSpec::seconds(20)).unwrap(); + assert_times_eq(10, 20, &fs::metadata(&fullpath).unwrap()); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_utimensat() { + let _dr = crate::DirRestore::new(); + let tempdir = tempfile::tempdir().unwrap(); + let filename = "foo.txt"; + let fullpath = tempdir.path().join(filename); + drop(File::create(&fullpath).unwrap()); + + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + utimensat( + Some(dirfd), + filename, + &TimeSpec::seconds(12345), + &TimeSpec::seconds(678), + UtimensatFlags::FollowSymlink, + ) + .unwrap(); + assert_times_eq(12345, 678, &fs::metadata(&fullpath).unwrap()); + + chdir(tempdir.path()).unwrap(); + + utimensat( + None, + filename, + &TimeSpec::seconds(500), + &TimeSpec::seconds(800), + UtimensatFlags::FollowSymlink, + ) + .unwrap(); + assert_times_eq(500, 800, &fs::metadata(&fullpath).unwrap()); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_mkdirat_success_path() { + let tempdir = tempfile::tempdir().unwrap(); + let filename = "example_subdir"; + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + mkdirat(dirfd, filename, Mode::S_IRWXU).expect("mkdirat failed"); + assert!(Path::exists(&tempdir.path().join(filename))); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_mkdirat_success_mode() { + let expected_bits = + stat::SFlag::S_IFDIR.bits() | stat::Mode::S_IRWXU.bits(); + let tempdir = tempfile::tempdir().unwrap(); + let filename = "example_subdir"; + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + mkdirat(dirfd, filename, Mode::S_IRWXU).expect("mkdirat failed"); + let permissions = fs::metadata(tempdir.path().join(filename)) + .unwrap() + .permissions(); + let mode = permissions.mode(); + assert_eq!(mode as mode_t, expected_bits) +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_mkdirat_fail() { + let tempdir = tempfile::tempdir().unwrap(); + let not_dir_filename = "example_not_dir"; + let filename = "example_subdir_dir"; + let dirfd = fcntl::open( + &tempdir.path().join(not_dir_filename), + fcntl::OFlag::O_CREAT, + stat::Mode::empty(), + ) + .unwrap(); + let result = mkdirat(dirfd, filename, Mode::S_IRWXU).unwrap_err(); + assert_eq!(result, Errno::ENOTDIR); +} + +#[test] +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "haiku", + target_os = "redox" +)))] +fn test_mknod() { + use stat::{lstat, mknod, SFlag}; + + let file_name = "test_file"; + let tempdir = tempfile::tempdir().unwrap(); + let target = tempdir.path().join(file_name); + mknod(&target, SFlag::S_IFREG, Mode::S_IRWXU, 0).unwrap(); + let mode = lstat(&target).unwrap().st_mode as mode_t; + assert_eq!(mode & libc::S_IFREG, libc::S_IFREG); + assert_eq!(mode & libc::S_IRWXU, libc::S_IRWXU); +} + +#[test] +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "haiku", + target_os = "redox" +)))] +fn test_mknodat() { + use fcntl::{AtFlags, OFlag}; + use nix::dir::Dir; + use stat::{fstatat, mknodat, SFlag}; + + let file_name = "test_file"; + let tempdir = tempfile::tempdir().unwrap(); + let target_dir = + Dir::open(tempdir.path(), OFlag::O_DIRECTORY, Mode::S_IRWXU).unwrap(); + mknodat( + target_dir.as_raw_fd(), + file_name, + SFlag::S_IFREG, + Mode::S_IRWXU, + 0, + ) + .unwrap(); + let mode = fstatat( + target_dir.as_raw_fd(), + file_name, + AtFlags::AT_SYMLINK_NOFOLLOW, + ) + .unwrap() + .st_mode as mode_t; + assert_eq!(mode & libc::S_IFREG, libc::S_IFREG); + assert_eq!(mode & libc::S_IRWXU, libc::S_IRWXU); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_time.rs b/utshell-0.5.0/vendor/nix/test/test_time.rs new file mode 100644 index 00000000..5f76e61a --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_time.rs @@ -0,0 +1,59 @@ +#[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux", + target_os = "android", + target_os = "emscripten", +))] +use nix::time::clock_getcpuclockid; +use nix::time::{clock_gettime, ClockId}; + +#[cfg(not(target_os = "redox"))] +#[test] +pub fn test_clock_getres() { + nix::time::clock_getres(ClockId::CLOCK_REALTIME).expect("assertion failed"); +} + +#[test] +pub fn test_clock_gettime() { + clock_gettime(ClockId::CLOCK_REALTIME).expect("assertion failed"); +} + +#[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux", + target_os = "android", + target_os = "emscripten", +))] +#[test] +pub fn test_clock_getcpuclockid() { + let clock_id = clock_getcpuclockid(nix::unistd::Pid::this()).unwrap(); + clock_gettime(clock_id).unwrap(); +} + +#[cfg(not(target_os = "redox"))] +#[test] +pub fn test_clock_id_res() { + ClockId::CLOCK_REALTIME.res().unwrap(); +} + +#[test] +pub fn test_clock_id_now() { + ClockId::CLOCK_REALTIME.now().unwrap(); +} + +#[cfg(any( + target_os = "freebsd", + target_os = "dragonfly", + target_os = "linux", + target_os = "android", + target_os = "emscripten", +))] +#[test] +pub fn test_clock_id_pid_cpu_clock_id() { + ClockId::pid_cpu_clock_id(nix::unistd::Pid::this()) + .map(ClockId::now) + .unwrap() + .unwrap(); +} diff --git a/utshell-0.5.0/vendor/nix/test/test_timer.rs b/utshell-0.5.0/vendor/nix/test/test_timer.rs new file mode 100644 index 00000000..ffd14686 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_timer.rs @@ -0,0 +1,102 @@ +use nix::sys::signal::{ + sigaction, SaFlags, SigAction, SigEvent, SigHandler, SigSet, SigevNotify, + Signal, +}; +use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags}; +use nix::time::ClockId; +use std::convert::TryFrom; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread; +use std::time::{Duration, Instant}; + +const SIG: Signal = Signal::SIGALRM; +static ALARM_CALLED: AtomicBool = AtomicBool::new(false); + +pub extern "C" fn handle_sigalarm(raw_signal: libc::c_int) { + let signal = Signal::try_from(raw_signal).unwrap(); + if signal == SIG { + ALARM_CALLED.store(true, Ordering::Release); + } +} + +#[test] +fn alarm_fires() { + // Avoid interfering with other signal using tests by taking a mutex shared + // among other tests in this crate. + let _m = crate::SIGNAL_MTX.lock(); + const TIMER_PERIOD: Duration = Duration::from_millis(100); + + // + // Setup + // + + // Create a handler for the test signal, `SIG`. The handler is responsible + // for flipping `ALARM_CALLED`. + let handler = SigHandler::Handler(handle_sigalarm); + let signal_action = + SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty()); + let old_handler = unsafe { + sigaction(SIG, &signal_action) + .expect("unable to set signal handler for alarm") + }; + + // Create the timer. We use the monotonic clock here, though any would do + // really. The timer is set to fire every 250 milliseconds with no delay for + // the initial firing. + let clockid = ClockId::CLOCK_MONOTONIC; + let sigevent = SigEvent::new(SigevNotify::SigevSignal { + signal: SIG, + si_value: 0, + }); + let mut timer = + Timer::new(clockid, sigevent).expect("failed to create timer"); + let expiration = Expiration::Interval(TIMER_PERIOD.into()); + let flags = TimerSetTimeFlags::empty(); + timer.set(expiration, flags).expect("could not set timer"); + + // + // Test + // + + // Determine that there's still an expiration tracked by the + // timer. Depending on when this runs either an `Expiration::Interval` or + // `Expiration::IntervalDelayed` will be present. That is, if the timer has + // not fired yet we'll get our original `expiration`, else the one that + // represents a delay to the next expiration. We're only interested in the + // timer still being extant. + match timer.get() { + Ok(Some(exp)) => assert!(matches!( + exp, + Expiration::Interval(..) | Expiration::IntervalDelayed(..) + )), + _ => panic!("timer lost its expiration"), + } + + // Wait for 2 firings of the alarm before checking that it has fired and + // been handled at least the once. If we wait for 3 seconds and the handler + // is never called something has gone sideways and the test fails. + let starttime = Instant::now(); + loop { + thread::sleep(2 * TIMER_PERIOD); + if ALARM_CALLED.load(Ordering::Acquire) { + break; + } + if starttime.elapsed() > Duration::from_secs(3) { + panic!("Timeout waiting for SIGALRM"); + } + } + + // Cleanup: + // 1) deregister the OS's timer. + // 2) Wait for a full timer period, since POSIX does not require that + // disabling the timer will clear pending signals, and on NetBSD at least + // it does not. + // 2) Replace the old signal handler now that we've completed the test. If + // the test fails this process panics, so the fact we might not get here + // is okay. + drop(timer); + thread::sleep(TIMER_PERIOD); + unsafe { + sigaction(SIG, &old_handler).expect("unable to reset signal handler"); + } +} diff --git a/utshell-0.5.0/vendor/nix/test/test_unistd.rs b/utshell-0.5.0/vendor/nix/test/test_unistd.rs new file mode 100644 index 00000000..08ba4544 --- /dev/null +++ b/utshell-0.5.0/vendor/nix/test/test_unistd.rs @@ -0,0 +1,1378 @@ +use libc::{_exit, mode_t, off_t}; +use nix::errno::Errno; +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +use nix::fcntl::readlink; +use nix::fcntl::OFlag; +#[cfg(not(target_os = "redox"))] +use nix::fcntl::{self, open}; +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt}; +#[cfg(not(target_os = "redox"))] +use nix::sys::signal::{ + sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, +}; +use nix::sys::stat::{self, Mode, SFlag}; +use nix::sys::wait::*; +use nix::unistd::ForkResult::*; +use nix::unistd::*; +use std::env; +#[cfg(not(any(target_os = "fuchsia", target_os = "redox")))] +use std::ffi::CString; +#[cfg(not(target_os = "redox"))] +use std::fs::DirBuilder; +use std::fs::{self, File}; +use std::io::Write; +use std::os::unix::prelude::*; +#[cfg(not(any( + target_os = "fuchsia", + target_os = "redox", + target_os = "haiku" +)))] +use std::path::Path; +use tempfile::{tempdir, tempfile}; + +use crate::*; + +#[test] +#[cfg(not(any(target_os = "netbsd")))] +fn test_fork_and_waitpid() { + let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is signal-safe + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => unsafe { _exit(0) }, + Parent { child } => { + // assert that child was created and pid > 0 + let child_raw: ::libc::pid_t = child.into(); + assert!(child_raw > 0); + let wait_status = waitpid(child, None); + match wait_status { + // assert that waitpid returned correct status and the pid is the one of the child + Ok(WaitStatus::Exited(pid_t, _)) => assert_eq!(pid_t, child), + + // panic, must never happen + s @ Ok(_) => { + panic!("Child exited {:?}, should never happen", s) + } + + // panic, waitpid should never fail + Err(s) => panic!("Error: waitpid returned Err({:?}", s), + } + } + } +} + +#[test] +fn test_wait() { + // Grab FORK_MTX so wait doesn't reap a different test's child process + let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is signal-safe + match unsafe { fork() }.expect("Error: Fork Failed") { + Child => unsafe { _exit(0) }, + Parent { child } => { + let wait_status = wait(); + + // just assert that (any) one child returns with WaitStatus::Exited + assert_eq!(wait_status, Ok(WaitStatus::Exited(child, 0))); + } + } +} + +#[test] +fn test_mkstemp() { + let mut path = env::temp_dir(); + path.push("nix_tempfile.XXXXXX"); + + let result = mkstemp(&path); + match result { + Ok((fd, path)) => { + close(fd).unwrap(); + unlink(path.as_path()).unwrap(); + } + Err(e) => panic!("mkstemp failed: {}", e), + } +} + +#[test] +fn test_mkstemp_directory() { + // mkstemp should fail if a directory is given + mkstemp(&env::temp_dir()).expect_err("assertion failed"); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_mkfifo() { + let tempdir = tempdir().unwrap(); + let mkfifo_fifo = tempdir.path().join("mkfifo_fifo"); + + mkfifo(&mkfifo_fifo, Mode::S_IRUSR).unwrap(); + + let stats = stat::stat(&mkfifo_fifo).unwrap(); + let typ = stat::SFlag::from_bits_truncate(stats.st_mode as mode_t); + assert_eq!(typ, SFlag::S_IFIFO); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_mkfifo_directory() { + // mkfifo should fail if a directory is given + mkfifo(&env::temp_dir(), Mode::S_IRUSR).expect_err("assertion failed"); +} + +#[test] +#[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "redox", + target_os = "haiku" +)))] +fn test_mkfifoat_none() { + let _m = crate::CWD_LOCK.read(); + + let tempdir = tempdir().unwrap(); + let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo"); + + mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap(); + + let stats = stat::stat(&mkfifoat_fifo).unwrap(); + let typ = stat::SFlag::from_bits_truncate(stats.st_mode); + assert_eq!(typ, SFlag::S_IFIFO); +} + +#[test] +#[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "redox", + target_os = "haiku" +)))] +fn test_mkfifoat() { + use nix::fcntl; + + let tempdir = tempdir().unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let mkfifoat_name = "mkfifoat_name"; + + mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap(); + + let stats = + stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap(); + let typ = stat::SFlag::from_bits_truncate(stats.st_mode); + assert_eq!(typ, SFlag::S_IFIFO); +} + +#[test] +#[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "redox", + target_os = "haiku" +)))] +fn test_mkfifoat_directory_none() { + let _m = crate::CWD_LOCK.read(); + + // mkfifoat should fail if a directory is given + mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR) + .expect_err("assertion failed"); +} + +#[test] +#[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "redox", + target_os = "haiku" +)))] +fn test_mkfifoat_directory() { + // mkfifoat should fail if a directory is given + let tempdir = tempdir().unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let mkfifoat_dir = "mkfifoat_dir"; + stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap(); + + mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR) + .expect_err("assertion failed"); +} + +#[test] +fn test_getpid() { + let pid: ::libc::pid_t = getpid().into(); + let ppid: ::libc::pid_t = getppid().into(); + assert!(pid > 0); + assert!(ppid > 0); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_getsid() { + let none_sid: ::libc::pid_t = getsid(None).unwrap().into(); + let pid_sid: ::libc::pid_t = getsid(Some(getpid())).unwrap().into(); + assert!(none_sid > 0); + assert_eq!(none_sid, pid_sid); +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod linux_android { + use nix::unistd::gettid; + + #[test] + fn test_gettid() { + let tid: ::libc::pid_t = gettid().into(); + assert!(tid > 0); + } +} + +#[test] +// `getgroups()` and `setgroups()` do not behave as expected on Apple platforms +#[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +fn test_setgroups() { + // Skip this test when not run as root as `setgroups()` requires root. + skip_if_not_root!("test_setgroups"); + + let _m = crate::GROUPS_MTX.lock(); + + // Save the existing groups + let old_groups = getgroups().unwrap(); + + // Set some new made up groups + let groups = [Gid::from_raw(123), Gid::from_raw(456)]; + setgroups(&groups).unwrap(); + + let new_groups = getgroups().unwrap(); + assert_eq!(new_groups, groups); + + // Revert back to the old groups + setgroups(&old_groups).unwrap(); +} + +#[test] +// `getgroups()` and `setgroups()` do not behave as expected on Apple platforms +#[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos" +)))] +fn test_initgroups() { + // Skip this test when not run as root as `initgroups()` and `setgroups()` + // require root. + skip_if_not_root!("test_initgroups"); + + let _m = crate::GROUPS_MTX.lock(); + + // Save the existing groups + let old_groups = getgroups().unwrap(); + + // It doesn't matter if the root user is not called "root" or if a user + // called "root" doesn't exist. We are just checking that the extra, + // made-up group, `123`, is set. + // FIXME: Test the other half of initgroups' functionality: whether the + // groups that the user belongs to are also set. + let user = CString::new("root").unwrap(); + let group = Gid::from_raw(123); + let group_list = getgrouplist(&user, group).unwrap(); + assert!(group_list.contains(&group)); + + initgroups(&user, group).unwrap(); + + let new_groups = getgroups().unwrap(); + assert_eq!(new_groups, group_list); + + // Revert back to the old groups + setgroups(&old_groups).unwrap(); +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox")))] +macro_rules! execve_test_factory ( + ($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => ( + + #[cfg(test)] + mod $test_name { + use std::ffi::CStr; + use super::*; + + const EMPTY: &'static [u8] = b"\0"; + const DASH_C: &'static [u8] = b"-c\0"; + const BIGARG: &'static [u8] = b"echo nix!!! && echo foo=$foo && echo baz=$baz\0"; + const FOO: &'static [u8] = b"foo=bar\0"; + const BAZ: &'static [u8] = b"baz=quux\0"; + + fn syscall_cstr_ref() -> Result { + $syscall( + $exe, + $(CString::new($pathname).unwrap().as_c_str(), )* + &[CStr::from_bytes_with_nul(EMPTY).unwrap(), + CStr::from_bytes_with_nul(DASH_C).unwrap(), + CStr::from_bytes_with_nul(BIGARG).unwrap()], + &[CStr::from_bytes_with_nul(FOO).unwrap(), + CStr::from_bytes_with_nul(BAZ).unwrap()] + $(, $flags)*) + } + + fn syscall_cstring() -> Result { + $syscall( + $exe, + $(CString::new($pathname).unwrap().as_c_str(), )* + &[CString::from(CStr::from_bytes_with_nul(EMPTY).unwrap()), + CString::from(CStr::from_bytes_with_nul(DASH_C).unwrap()), + CString::from(CStr::from_bytes_with_nul(BIGARG).unwrap())], + &[CString::from(CStr::from_bytes_with_nul(FOO).unwrap()), + CString::from(CStr::from_bytes_with_nul(BAZ).unwrap())] + $(, $flags)*) + } + + fn common_test(syscall: fn() -> Result) { + if "execveat" == stringify!($syscall) { + // Though undocumented, Docker's default seccomp profile seems to + // block this syscall. https://github.com/nix-rust/nix/issues/1122 + skip_if_seccomp!($test_name); + } + + let m = crate::FORK_MTX.lock(); + // The `exec`d process will write to `writer`, and we'll read that + // data from `reader`. + let (reader, writer) = pipe().unwrap(); + + // Safe: Child calls `exit`, `dup`, `close` and the provided `exec*` family function. + // NOTE: Technically, this makes the macro unsafe to use because you could pass anything. + // The tests make sure not to do that, though. + match unsafe{fork()}.unwrap() { + Child => { + // Make `writer` be the stdout of the new process. + dup2(writer, 1).unwrap(); + let r = syscall(); + let _ = std::io::stderr() + .write_all(format!("{:?}", r).as_bytes()); + // Should only get here in event of error + unsafe{ _exit(1) }; + }, + Parent { child } => { + // Wait for the child to exit. + let ws = waitpid(child, None); + drop(m); + assert_eq!(ws, Ok(WaitStatus::Exited(child, 0))); + // Read 1024 bytes. + let mut buf = [0u8; 1024]; + read(reader, &mut buf).unwrap(); + // It should contain the things we printed using `/bin/sh`. + let string = String::from_utf8_lossy(&buf); + assert!(string.contains("nix!!!")); + assert!(string.contains("foo=bar")); + assert!(string.contains("baz=quux")); + } + } + } + + // These tests frequently fail on musl, probably due to + // https://github.com/nix-rust/nix/issues/555 + #[cfg_attr(target_env = "musl", ignore)] + #[test] + fn test_cstr_ref() { + common_test(syscall_cstr_ref); + } + + // These tests frequently fail on musl, probably due to + // https://github.com/nix-rust/nix/issues/555 + #[cfg_attr(target_env = "musl", ignore)] + #[test] + fn test_cstring() { + common_test(syscall_cstring); + } + } + + ) +); + +cfg_if! { + if #[cfg(target_os = "android")] { + execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str()); + execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd()); + } else if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux"))] { + // These tests frequently fail on musl, probably due to + // https://github.com/nix-rust/nix/issues/555 + execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str()); + execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd()); + } else if #[cfg(any(target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] { + execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str()); + // No fexecve() on ios, macos, NetBSD, OpenBSD. + } +} + +#[cfg(any(target_os = "haiku", target_os = "linux", target_os = "openbsd"))] +execve_test_factory!(test_execvpe, execvpe, &CString::new("sh").unwrap()); + +cfg_if! { + if #[cfg(target_os = "android")] { + use nix::fcntl::AtFlags; + execve_test_factory!(test_execveat_empty, execveat, + File::open("/system/bin/sh").unwrap().into_raw_fd(), + "", AtFlags::AT_EMPTY_PATH); + execve_test_factory!(test_execveat_relative, execveat, + File::open("/system/bin/").unwrap().into_raw_fd(), + "./sh", AtFlags::empty()); + execve_test_factory!(test_execveat_absolute, execveat, + File::open("/").unwrap().into_raw_fd(), + "/system/bin/sh", AtFlags::empty()); + } else if #[cfg(all(target_os = "linux", any(target_arch ="x86_64", target_arch ="x86")))] { + use nix::fcntl::AtFlags; + execve_test_factory!(test_execveat_empty, execveat, File::open("/bin/sh").unwrap().into_raw_fd(), + "", AtFlags::AT_EMPTY_PATH); + execve_test_factory!(test_execveat_relative, execveat, File::open("/bin/").unwrap().into_raw_fd(), + "./sh", AtFlags::empty()); + execve_test_factory!(test_execveat_absolute, execveat, File::open("/").unwrap().into_raw_fd(), + "/bin/sh", AtFlags::empty()); + } +} + +#[test] +#[cfg(not(target_os = "fuchsia"))] +fn test_fchdir() { + // fchdir changes the process's cwd + let _dr = crate::DirRestore::new(); + + let tmpdir = tempdir().unwrap(); + let tmpdir_path = tmpdir.path().canonicalize().unwrap(); + let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd(); + + fchdir(tmpdir_fd).expect("assertion failed"); + assert_eq!(getcwd().unwrap(), tmpdir_path); + + close(tmpdir_fd).expect("assertion failed"); +} + +#[test] +fn test_getcwd() { + // chdir changes the process's cwd + let _dr = crate::DirRestore::new(); + + let tmpdir = tempdir().unwrap(); + let tmpdir_path = tmpdir.path().canonicalize().unwrap(); + chdir(&tmpdir_path).expect("assertion failed"); + assert_eq!(getcwd().unwrap(), tmpdir_path); + + // make path 500 chars longer so that buffer doubling in getcwd + // kicks in. Note: One path cannot be longer than 255 bytes + // (NAME_MAX) whole path cannot be longer than PATH_MAX (usually + // 4096 on linux, 1024 on macos) + let mut inner_tmp_dir = tmpdir_path; + for _ in 0..5 { + let newdir = "a".repeat(100); + inner_tmp_dir.push(newdir); + mkdir(inner_tmp_dir.as_path(), Mode::S_IRWXU) + .expect("assertion failed"); + } + chdir(inner_tmp_dir.as_path()).expect("assertion failed"); + assert_eq!(getcwd().unwrap(), inner_tmp_dir.as_path()); +} + +#[test] +fn test_chown() { + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + + let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + { + File::create(&path).unwrap(); + } + + chown(&path, uid, gid).unwrap(); + chown(&path, uid, None).unwrap(); + chown(&path, None, gid).unwrap(); + + fs::remove_file(&path).unwrap(); + chown(&path, uid, gid).unwrap_err(); +} + +#[test] +fn test_fchown() { + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + + let path = tempfile().unwrap(); + let fd = path.as_raw_fd(); + + fchown(fd, uid, gid).unwrap(); + fchown(fd, uid, None).unwrap(); + fchown(fd, None, gid).unwrap(); + fchown(999999999, uid, gid).unwrap_err(); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_fchownat() { + let _dr = crate::DirRestore::new(); + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + + let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + { + File::create(&path).unwrap(); + } + + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + + fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink) + .unwrap(); + + chdir(tempdir.path()).unwrap(); + fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap(); + + fs::remove_file(&path).unwrap(); + fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap_err(); +} + +#[test] +fn test_lseek() { + const CONTENTS: &[u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + let tmpfd = tmp.into_raw_fd(); + + let offset: off_t = 5; + lseek(tmpfd, offset, Whence::SeekSet).unwrap(); + + let mut buf = [0u8; 7]; + crate::read_exact(tmpfd, &mut buf); + assert_eq!(b"f123456", &buf); + + close(tmpfd).unwrap(); +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +#[test] +fn test_lseek64() { + const CONTENTS: &[u8] = b"abcdef123456"; + let mut tmp = tempfile().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + let tmpfd = tmp.into_raw_fd(); + + lseek64(tmpfd, 5, Whence::SeekSet).unwrap(); + + let mut buf = [0u8; 7]; + crate::read_exact(tmpfd, &mut buf); + assert_eq!(b"f123456", &buf); + + close(tmpfd).unwrap(); +} + +cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + macro_rules! require_acct{ + () => { + require_capability!("test_acct", CAP_SYS_PACCT); + } + } + } else if #[cfg(target_os = "freebsd")] { + macro_rules! require_acct{ + () => { + skip_if_not_root!("test_acct"); + skip_if_jailed!("test_acct"); + } + } + } else if #[cfg(not(any(target_os = "redox", target_os = "fuchsia", target_os = "haiku")))] { + macro_rules! require_acct{ + () => { + skip_if_not_root!("test_acct"); + } + } + } +} + +#[test] +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +fn test_acct() { + use std::process::Command; + use std::{thread, time}; + use tempfile::NamedTempFile; + + let _m = crate::FORK_MTX.lock(); + require_acct!(); + + let file = NamedTempFile::new().unwrap(); + let path = file.path().to_str().unwrap(); + + acct::enable(path).unwrap(); + + loop { + Command::new("echo").arg("Hello world").output().unwrap(); + let len = fs::metadata(path).unwrap().len(); + if len > 0 { + break; + } + thread::sleep(time::Duration::from_millis(10)); + } + acct::disable().unwrap(); +} + +#[test] +fn test_fpathconf_limited() { + let f = tempfile().unwrap(); + // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test + let path_max = fpathconf(f.as_raw_fd(), PathconfVar::PATH_MAX); + assert!( + path_max + .expect("fpathconf failed") + .expect("PATH_MAX is unlimited") + > 0 + ); +} + +#[test] +fn test_pathconf_limited() { + // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test + let path_max = pathconf("/", PathconfVar::PATH_MAX); + assert!( + path_max + .expect("pathconf failed") + .expect("PATH_MAX is unlimited") + > 0 + ); +} + +#[test] +fn test_sysconf_limited() { + // AFAIK, OPEN_MAX is limited on all platforms, so it makes a good test + let open_max = sysconf(SysconfVar::OPEN_MAX); + assert!( + open_max + .expect("sysconf failed") + .expect("OPEN_MAX is unlimited") + > 0 + ); +} + +#[cfg(target_os = "freebsd")] +#[test] +fn test_sysconf_unsupported() { + // I know of no sysconf variables that are unsupported everywhere, but + // _XOPEN_CRYPT is unsupported on FreeBSD 11.0, which is one of the platforms + // we test. + let open_max = sysconf(SysconfVar::_XOPEN_CRYPT); + assert!(open_max.expect("sysconf failed").is_none()) +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "openbsd" +))] +#[test] +fn test_getresuid() { + let resuids = getresuid().unwrap(); + assert_ne!(resuids.real.as_raw(), libc::uid_t::MAX); + assert_ne!(resuids.effective.as_raw(), libc::uid_t::MAX); + assert_ne!(resuids.saved.as_raw(), libc::uid_t::MAX); +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "openbsd" +))] +#[test] +fn test_getresgid() { + let resgids = getresgid().unwrap(); + assert_ne!(resgids.real.as_raw(), libc::gid_t::MAX); + assert_ne!(resgids.effective.as_raw(), libc::gid_t::MAX); + assert_ne!(resgids.saved.as_raw(), libc::gid_t::MAX); +} + +// Test that we can create a pair of pipes. No need to verify that they pass +// data; that's the domain of the OS, not nix. +#[test] +fn test_pipe() { + let (fd0, fd1) = pipe().unwrap(); + let m0 = stat::SFlag::from_bits_truncate( + stat::fstat(fd0).unwrap().st_mode as mode_t, + ); + // S_IFIFO means it's a pipe + assert_eq!(m0, SFlag::S_IFIFO); + let m1 = stat::SFlag::from_bits_truncate( + stat::fstat(fd1).unwrap().st_mode as mode_t, + ); + assert_eq!(m1, SFlag::S_IFIFO); +} + +// pipe2(2) is the same as pipe(2), except it allows setting some flags. Check +// that we can set a flag. +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris" +))] +#[test] +fn test_pipe2() { + use nix::fcntl::{fcntl, FcntlArg, FdFlag}; + + let (fd0, fd1) = pipe2(OFlag::O_CLOEXEC).unwrap(); + let f0 = FdFlag::from_bits_truncate(fcntl(fd0, FcntlArg::F_GETFD).unwrap()); + assert!(f0.contains(FdFlag::FD_CLOEXEC)); + let f1 = FdFlag::from_bits_truncate(fcntl(fd1, FcntlArg::F_GETFD).unwrap()); + assert!(f1.contains(FdFlag::FD_CLOEXEC)); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] +fn test_truncate() { + let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + + { + let mut tmp = File::create(&path).unwrap(); + const CONTENTS: &[u8] = b"12345678"; + tmp.write_all(CONTENTS).unwrap(); + } + + truncate(&path, 4).unwrap(); + + let metadata = fs::metadata(&path).unwrap(); + assert_eq!(4, metadata.len()); +} + +#[test] +fn test_ftruncate() { + let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + + let tmpfd = { + let mut tmp = File::create(&path).unwrap(); + const CONTENTS: &[u8] = b"12345678"; + tmp.write_all(CONTENTS).unwrap(); + tmp.into_raw_fd() + }; + + ftruncate(tmpfd, 2).unwrap(); + close(tmpfd).unwrap(); + + let metadata = fs::metadata(&path).unwrap(); + assert_eq!(2, metadata.len()); +} + +// Used in `test_alarm`. +#[cfg(not(target_os = "redox"))] +static mut ALARM_CALLED: bool = false; + +// Used in `test_alarm`. +#[cfg(not(target_os = "redox"))] +pub extern "C" fn alarm_signal_handler(raw_signal: libc::c_int) { + assert_eq!( + raw_signal, + libc::SIGALRM, + "unexpected signal: {}", + raw_signal + ); + unsafe { ALARM_CALLED = true }; +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_alarm() { + use std::{ + thread, + time::{Duration, Instant}, + }; + + // Maybe other tests that fork interfere with this one? + let _m = crate::SIGNAL_MTX.lock(); + + let handler = SigHandler::Handler(alarm_signal_handler); + let signal_action = + SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty()); + let old_handler = unsafe { + sigaction(Signal::SIGALRM, &signal_action) + .expect("unable to set signal handler for alarm") + }; + + // Set an alarm. + assert_eq!(alarm::set(60), None); + + // Overwriting an alarm should return the old alarm. + assert_eq!(alarm::set(1), Some(60)); + + // We should be woken up after 1 second by the alarm, so we'll sleep for 3 + // seconds to be sure. + let starttime = Instant::now(); + loop { + thread::sleep(Duration::from_millis(100)); + if unsafe { ALARM_CALLED } { + break; + } + if starttime.elapsed() > Duration::from_secs(3) { + panic!("Timeout waiting for SIGALRM"); + } + } + + // Reset the signal. + unsafe { + sigaction(Signal::SIGALRM, &old_handler) + .expect("unable to set signal handler for alarm"); + } +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_canceling_alarm() { + let _m = crate::SIGNAL_MTX.lock(); + + assert_eq!(alarm::cancel(), None); + + assert_eq!(alarm::set(60), None); + assert_eq!(alarm::cancel(), Some(60)); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_symlinkat() { + let _m = crate::CWD_LOCK.read(); + + let tempdir = tempdir().unwrap(); + + let target = tempdir.path().join("a"); + let linkpath = tempdir.path().join("b"); + symlinkat(&target, None, &linkpath).unwrap(); + assert_eq!( + readlink(&linkpath).unwrap().to_str().unwrap(), + target.to_str().unwrap() + ); + + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let target = "c"; + let linkpath = "d"; + symlinkat(target, Some(dirfd), linkpath).unwrap(); + assert_eq!( + readlink(&tempdir.path().join(linkpath)) + .unwrap() + .to_str() + .unwrap(), + target + ); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_linkat_file() { + let tempdir = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir.path().join(oldfilename); + + let newfilename = "bar.txt"; + let newfilepath = tempdir.path().join(newfilename); + + // Create file + File::create(oldfilepath).unwrap(); + + // Get file descriptor for base directory + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + // Attempt hard link file at relative path + linkat( + Some(dirfd), + oldfilename, + Some(dirfd), + newfilename, + LinkatFlags::SymlinkFollow, + ) + .unwrap(); + assert!(newfilepath.exists()); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_linkat_olddirfd_none() { + let _dr = crate::DirRestore::new(); + + let tempdir_oldfile = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir_oldfile.path().join(oldfilename); + + let tempdir_newfile = tempdir().unwrap(); + let newfilename = "bar.txt"; + let newfilepath = tempdir_newfile.path().join(newfilename); + + // Create file + File::create(oldfilepath).unwrap(); + + // Get file descriptor for base directory of new file + let dirfd = fcntl::open( + tempdir_newfile.path(), + fcntl::OFlag::empty(), + stat::Mode::empty(), + ) + .unwrap(); + + // Attempt hard link file using curent working directory as relative path for old file path + chdir(tempdir_oldfile.path()).unwrap(); + linkat( + None, + oldfilename, + Some(dirfd), + newfilename, + LinkatFlags::SymlinkFollow, + ) + .unwrap(); + assert!(newfilepath.exists()); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_linkat_newdirfd_none() { + let _dr = crate::DirRestore::new(); + + let tempdir_oldfile = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir_oldfile.path().join(oldfilename); + + let tempdir_newfile = tempdir().unwrap(); + let newfilename = "bar.txt"; + let newfilepath = tempdir_newfile.path().join(newfilename); + + // Create file + File::create(oldfilepath).unwrap(); + + // Get file descriptor for base directory of old file + let dirfd = fcntl::open( + tempdir_oldfile.path(), + fcntl::OFlag::empty(), + stat::Mode::empty(), + ) + .unwrap(); + + // Attempt hard link file using current working directory as relative path for new file path + chdir(tempdir_newfile.path()).unwrap(); + linkat( + Some(dirfd), + oldfilename, + None, + newfilename, + LinkatFlags::SymlinkFollow, + ) + .unwrap(); + assert!(newfilepath.exists()); +} + +#[test] +#[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "haiku" +)))] +fn test_linkat_no_follow_symlink() { + let _m = crate::CWD_LOCK.read(); + + let tempdir = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir.path().join(oldfilename); + + let symoldfilename = "symfoo.txt"; + let symoldfilepath = tempdir.path().join(symoldfilename); + + let newfilename = "nofollowsymbar.txt"; + let newfilepath = tempdir.path().join(newfilename); + + // Create file + File::create(&oldfilepath).unwrap(); + + // Create symlink to file + symlinkat(&oldfilepath, None, &symoldfilepath).unwrap(); + + // Get file descriptor for base directory + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + // Attempt link symlink of file at relative path + linkat( + Some(dirfd), + symoldfilename, + Some(dirfd), + newfilename, + LinkatFlags::NoSymlinkFollow, + ) + .unwrap(); + + // Assert newfile is actually a symlink to oldfile. + assert_eq!( + readlink(&newfilepath).unwrap().to_str().unwrap(), + oldfilepath.to_str().unwrap() + ); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "haiku")))] +fn test_linkat_follow_symlink() { + let _m = crate::CWD_LOCK.read(); + + let tempdir = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir.path().join(oldfilename); + + let symoldfilename = "symfoo.txt"; + let symoldfilepath = tempdir.path().join(symoldfilename); + + let newfilename = "nofollowsymbar.txt"; + let newfilepath = tempdir.path().join(newfilename); + + // Create file + File::create(&oldfilepath).unwrap(); + + // Create symlink to file + symlinkat(&oldfilepath, None, &symoldfilepath).unwrap(); + + // Get file descriptor for base directory + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + // Attempt link target of symlink of file at relative path + linkat( + Some(dirfd), + symoldfilename, + Some(dirfd), + newfilename, + LinkatFlags::SymlinkFollow, + ) + .unwrap(); + + let newfilestat = stat::stat(&newfilepath).unwrap(); + + // Check the file type of the new link + assert_eq!( + (stat::SFlag::from_bits_truncate(newfilestat.st_mode as mode_t) + & SFlag::S_IFMT), + SFlag::S_IFREG + ); + + // Check the number of hard links to the original file + assert_eq!(newfilestat.st_nlink, 2); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_unlinkat_dir_noremovedir() { + let tempdir = tempdir().unwrap(); + let dirname = "foo_dir"; + let dirpath = tempdir.path().join(dirname); + + // Create dir + DirBuilder::new().recursive(true).create(dirpath).unwrap(); + + // Get file descriptor for base directory + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + // Attempt unlink dir at relative path without proper flag + let err_result = + unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap_err(); + assert!(err_result == Errno::EISDIR || err_result == Errno::EPERM); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_unlinkat_dir_removedir() { + let tempdir = tempdir().unwrap(); + let dirname = "foo_dir"; + let dirpath = tempdir.path().join(dirname); + + // Create dir + DirBuilder::new().recursive(true).create(&dirpath).unwrap(); + + // Get file descriptor for base directory + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + // Attempt unlink dir at relative path with proper flag + unlinkat(Some(dirfd), dirname, UnlinkatFlags::RemoveDir).unwrap(); + assert!(!dirpath.exists()); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_unlinkat_file() { + let tempdir = tempdir().unwrap(); + let filename = "foo.txt"; + let filepath = tempdir.path().join(filename); + + // Create file + File::create(&filepath).unwrap(); + + // Get file descriptor for base directory + let dirfd = + fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) + .unwrap(); + + // Attempt unlink file at relative path + unlinkat(Some(dirfd), filename, UnlinkatFlags::NoRemoveDir).unwrap(); + assert!(!filepath.exists()); +} + +#[test] +fn test_access_not_existing() { + let tempdir = tempdir().unwrap(); + let dir = tempdir.path().join("does_not_exist.txt"); + assert_eq!( + access(&dir, AccessFlags::F_OK).err().unwrap(), + Errno::ENOENT + ); +} + +#[test] +fn test_access_file_exists() { + let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("does_exist.txt"); + let _file = File::create(path.clone()).unwrap(); + access(&path, AccessFlags::R_OK | AccessFlags::W_OK) + .expect("assertion failed"); +} + +//Clippy false positive https://github.com/rust-lang/rust-clippy/issues/9111 +#[allow(clippy::needless_borrow)] +#[cfg(not(target_os = "redox"))] +#[test] +fn test_user_into_passwd() { + // get the UID of the "nobody" user + #[cfg(not(target_os = "haiku"))] + let test_username = "nobody"; + // "nobody" unavailable on haiku + #[cfg(target_os = "haiku")] + let test_username = "user"; + + let nobody = User::from_name(test_username).unwrap().unwrap(); + let pwd: libc::passwd = nobody.into(); + let _: User = (&pwd).into(); +} + +/// Tests setting the filesystem UID with `setfsuid`. +#[cfg(any(target_os = "linux", target_os = "android"))] +#[test] +fn test_setfsuid() { + use std::os::unix::fs::PermissionsExt; + use std::{fs, io, thread}; + require_capability!("test_setfsuid", CAP_SETUID); + + // get the UID of the "nobody" user + let nobody = User::from_name("nobody").unwrap().unwrap(); + + // create a temporary file with permissions '-rw-r-----' + let file = tempfile::NamedTempFile::new_in("/var/tmp").unwrap(); + let temp_path = file.into_temp_path(); + let temp_path_2 = temp_path.to_path_buf(); + let mut permissions = fs::metadata(&temp_path).unwrap().permissions(); + permissions.set_mode(0o640); + + // spawn a new thread where to test setfsuid + thread::spawn(move || { + // set filesystem UID + let fuid = setfsuid(nobody.uid); + // trying to open the temporary file should fail with EACCES + let res = fs::File::open(&temp_path); + let err = res.expect_err("assertion failed"); + assert_eq!(err.kind(), io::ErrorKind::PermissionDenied); + + // assert fuid actually changes + let prev_fuid = setfsuid(Uid::from_raw(-1i32 as u32)); + assert_ne!(prev_fuid, fuid); + }) + .join() + .unwrap(); + + // open the temporary file with the current thread filesystem UID + fs::File::open(temp_path_2).unwrap(); +} + +#[test] +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +fn test_ttyname() { + let fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed"); + assert!(fd.as_raw_fd() > 0); + + // on linux, we can just call ttyname on the pty master directly, but + // apparently osx requires that ttyname is called on a slave pty (can't + // find this documented anywhere, but it seems to empirically be the case) + grantpt(&fd).expect("grantpt failed"); + unlockpt(&fd).expect("unlockpt failed"); + let sname = unsafe { ptsname(&fd) }.expect("ptsname failed"); + let fds = open(Path::new(&sname), OFlag::O_RDWR, stat::Mode::empty()) + .expect("open failed"); + assert!(fds > 0); + + let name = ttyname(fds).expect("ttyname failed"); + assert!(name.starts_with("/dev")); +} + +#[test] +#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] +fn test_ttyname_not_pty() { + let fd = File::open("/dev/zero").unwrap(); + assert!(fd.as_raw_fd() > 0); + assert_eq!(ttyname(fd.as_raw_fd()), Err(Errno::ENOTTY)); +} + +#[test] +#[cfg(not(any( + target_os = "redox", + target_os = "fuchsia", + target_os = "haiku" +)))] +fn test_ttyname_invalid_fd() { + assert_eq!(ttyname(-1), Err(Errno::EBADF)); +} + +#[test] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", +))] +fn test_getpeereid() { + use std::os::unix::net::UnixStream; + let (sock_a, sock_b) = UnixStream::pair().unwrap(); + + let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap(); + let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap(); + + let uid = geteuid(); + let gid = getegid(); + + assert_eq!(uid, uid_a); + assert_eq!(gid, gid_a); + assert_eq!(uid_a, uid_b); + assert_eq!(gid_a, gid_b); +} + +#[test] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", +))] +fn test_getpeereid_invalid_fd() { + // getpeereid is not POSIX, so error codes are inconsistent between different Unices. + getpeereid(-1).expect_err("assertion failed"); +} + +#[test] +#[cfg(not(any(target_os = "illumos", target_os = "redox")))] +fn test_faccessat_none_not_existing() { + use nix::fcntl::AtFlags; + let tempdir = tempfile::tempdir().unwrap(); + let dir = tempdir.path().join("does_not_exist.txt"); + assert_eq!( + faccessat(None, &dir, AccessFlags::F_OK, AtFlags::empty()) + .err() + .unwrap(), + Errno::ENOENT + ); +} + +#[test] +#[cfg(not(any(target_os = "illumos", target_os = "redox")))] +fn test_faccessat_not_existing() { + use nix::fcntl::AtFlags; + let tempdir = tempfile::tempdir().unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let not_exist_file = "does_not_exist.txt"; + assert_eq!( + faccessat( + Some(dirfd), + not_exist_file, + AccessFlags::F_OK, + AtFlags::empty(), + ) + .err() + .unwrap(), + Errno::ENOENT + ); +} + +#[test] +#[cfg(not(any(target_os = "illumos", target_os = "redox")))] +fn test_faccessat_none_file_exists() { + use nix::fcntl::AtFlags; + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().join("does_exist.txt"); + let _file = File::create(path.clone()).unwrap(); + assert!(faccessat( + None, + &path, + AccessFlags::R_OK | AccessFlags::W_OK, + AtFlags::empty(), + ) + .is_ok()); +} + +#[test] +#[cfg(not(any(target_os = "illumos", target_os = "redox")))] +fn test_faccessat_file_exists() { + use nix::fcntl::AtFlags; + let tempdir = tempfile::tempdir().unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let exist_file = "does_exist.txt"; + let path = tempdir.path().join(exist_file); + let _file = File::create(path.clone()).unwrap(); + assert!(faccessat( + Some(dirfd), + &path, + AccessFlags::R_OK | AccessFlags::W_OK, + AtFlags::empty(), + ) + .is_ok()); +} diff --git a/utshell-0.5.0/vendor/once_cell/.cargo-checksum.json b/utshell-0.5.0/vendor/once_cell/.cargo-checksum.json new file mode 100644 index 00000000..caab37c3 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"7ff04db6c2a6ced21b58219524d498badb330e0ad6b93f28483425271ae2ac0b","Cargo.lock":"28211a196240664763395cf7395322081f6b2ed95bbaaa88f3d883804bf55846","Cargo.toml":"004e48a3411bf746e354473e56b181f9f280b29acee96563df582e8ed553e1f1","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"e883909b29dc4d1c44270136fe2cfe7b2df6b416226b13928fdf9f1e15130be7","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_cs.rs":"888fc76a1f4e55b1ece3ef748b0aa6a47be2d8d928c10f89ae6b4f12330c0e55","src/imp_pl.rs":"cd69042890c25fd3db97a4762abea4b814c961eadaf5d6ed7c7db17a6abd4c5b","src/imp_std.rs":"0fe9a91bc55c7fab9371716394844390886f9e1d71a9edb6484e639662c7fe59","src/lib.rs":"9e15ec3eb0634ed96323e60534b0d4d8726a5f11c419ed2c8b2d17c5212c45b1","src/race.rs":"917f1bc0ba2887644da447a6e9e38990c9a12e3c41c980be37ee916bf79d7677","tests/it.rs":"41f50496463a0036c45ed138f158d221d379e50a91ca452ba8ffe8caa7a59e3a"},"package":"9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/once_cell/CHANGELOG.md b/utshell-0.5.0/vendor/once_cell/CHANGELOG.md new file mode 100644 index 00000000..152a72d7 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/CHANGELOG.md @@ -0,0 +1,220 @@ +# Changelog + +## Unreleased + +- + +## 1.17.2 + +- Avoid unnecessary synchronization in `Lazy::{force,deref}_mut()`, [#231](https://github.com/matklad/once_cell/pull/231). + +## 1.17.1 + +- Make `OnceRef` implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). + +## 1.17.0 + +- Add `race::OnceRef` for storing a `&'a T`. + +## 1.16.0 + +- Add `no_std` implementation based on `critical-section`, + [#195](https://github.com/matklad/once_cell/pull/195). +- Deprecate `atomic-polyfill` feature (use the new `critical-section` instead) + +## 1.15.0 + +- Increase minimal supported Rust version to 1.56.0. +- Implement `UnwindSafe` even if the `std` feature is disabled. + +## 1.14.0 + +- Add extension to `unsync` and `sync` `Lazy` mut API: + - `force_mut` + - `get_mut` + + +## 1.13.1 + +- Make implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). +- Upgrade `atomic-polyfill` to `1.0` + +## 1.13.0 + +- Add `Lazy::get`, similar to `OnceCell::get`. + +## 1.12.1 + +- Remove incorrect `debug_assert`. + +## 1.12.0 + +- Add `OnceCell::wait`, a blocking variant of `get`. + +## 1.11.0 + +- Add `OnceCell::with_value` to create initialized `OnceCell` in `const` context. +- Improve `Clone` implementation for `OnceCell`. +- Rewrite `parking_lot` version on top of `parking_lot_core`, for even smaller cells! + +## 1.10.0 + +- upgrade `parking_lot` to `0.12.0` (note that this bumps MSRV with `parking_lot` feature enabled to `1.49.0`). + +## 1.9.0 + +- Added an `atomic-polyfill` optional dependency to compile `race` on platforms without atomics + +## 1.8.0 + +- Add `try_insert` API -- a version of `set` that returns a reference. + +## 1.7.2 + +- Improve code size when using parking_lot feature. + +## 1.7.1 + +- Fix `race::OnceBox` to also impl `Default` even if `T` doesn't impl `Default`. + +## 1.7.0 + +- Hide the `race` module behind (default) `race` feature. + Turns out that adding `race` by default was a breaking change on some platforms without atomics. + In this release, we make the module opt-out. + Technically, this is a breaking change for those who use `race` with `no_default_features`. + Given that the `race` module itself only several days old, the breakage is deemed acceptable. + +## 1.6.0 + +- Add `Lazy::into_value` +- Stabilize `once_cell::race` module for "first one wins" no_std-compatible initialization flavor. +- Migrate from deprecated `compare_and_swap` to `compare_exchange`. + +## 1.5.2 + +- `OnceBox` API uses `Box`. + This a breaking change to unstable API. + +## 1.5.1 + +- MSRV is increased to `1.36.0`. +- document `once_cell::race` module. +- introduce `alloc` feature for `OnceBox`. +- fix `OnceBox::set`. + +## 1.5.0 + +- add new `once_cell::race` module for "first one wins" no_std-compatible initialization flavor. + The API is provisional, subject to change and is gated by the `unstable` cargo feature. + +## 1.4.1 + +- upgrade `parking_lot` to `0.11.0` +- make `sync::OnceCell` pass https://doc.rust-lang.org/nomicon/dropck.html#an-escape-hatch[dropck] with `parking_lot` feature enabled. + This fixes a (minor) semver-incompatible changed introduced in `1.4.0` + +## 1.4.0 + +- upgrade `parking_lot` to `0.10` (note that this bumps MSRV with `parking_lot` feature enabled to `1.36.0`). +- add `OnceCell::take`. +- upgrade crossbeam utils (private dependency) to `0.7`. + +## 1.3.1 + +- remove unnecessary `F: fmt::Debug` bound from `impl fmt::Debug for Lazy`. + +## 1.3.0 + +- `Lazy` now implements `DerefMut`. +- update implementation according to the latest changes in `std`. + +## 1.2.0 + +- add `sync::OnceCell::get_unchecked`. + +## 1.1.0 + +- implement `Default` for `Lazy`: it creates an empty `Lazy` which is initialized with `T::default` on first access. +- add `OnceCell::get_mut`. + +## 1.0.2 + +- actually add `#![no_std]` attribute if std feature is not enabled. + +## 1.0.1 + +- fix unsoundness in `Lazy` if the initializing function panics. Thanks [@xfix](https://github.com/xfix)! +- implement `RefUnwindSafe` for `Lazy`. +- share more code between `std` and `parking_lot` implementations. +- add F.A.Q section to the docs. + +## 1.0.0 + +- remove `parking_lot` from the list of default features. +- add `std` default feature. Without `std`, only `unsync` module is supported. +- implement `Eq` for `OnceCell`. +- fix wrong `Sync` bound on `sync::Lazy`. +- run the whole test suite with miri. + +## 0.2.7 + +- New implementation of `sync::OnceCell` if `parking_lot` feature is disabled. + It now employs a hand-rolled variant of `std::sync::Once`. +- `sync::OnceCell::get_or_try_init` works without `parking_lot` as well! +- document the effects of `parking_lot` feature: same performance but smaller types. + +## 0.2.6 + +- Updated `Lazy`'s `Deref` impl to requires only `FnOnce` instead of `Fn` + +## 0.2.5 + +- `Lazy` requires only `FnOnce` instead of `Fn` + +## 0.2.4 + +- nicer `fmt::Debug` implementation + +## 0.2.3 + +- update `parking_lot` to `0.9.0` +- fix stacked borrows violation in `unsync::OnceCell::get` +- implement `Clone` for `sync::OnceCell where T: Clone` + +## 0.2.2 + +- add `OnceCell::into_inner` which consumes a cell and returns an option + +## 0.2.1 + +- implement `sync::OnceCell::get_or_try_init` if `parking_lot` feature is enabled +- switch internal `unsafe` implementation of `sync::OnceCell` from `Once` to `Mutex` +- `sync::OnceCell::get_or_init` is twice as fast if cell is already initialized +- implement `std::panic::RefUnwindSafe` and `std::panic::UnwindSafe` for `OnceCell` +- better document behavior around panics + +## 0.2.0 + +- MSRV is now 1.31.1 +- `Lazy::new` and `OnceCell::new` are now const-fns +- `unsync_lazy` and `sync_lazy` macros are removed + +## 0.1.8 + +- update crossbeam-utils to 0.6 +- enable bors-ng + +## 0.1.7 + +- cells implement `PartialEq` and `From` +- MSRV is down to 1.24.1 +- update `parking_lot` to `0.7.1` + +## 0.1.6 + +- `unsync::OnceCell` is `Clone` if `T` is `Clone`. + +## 0.1.5 + +- No changelog until this point :( diff --git a/utshell-0.5.0/vendor/once_cell/Cargo.lock b/utshell-0.5.0/vendor/once_cell/Cargo.lock new file mode 100644 index 00000000..e4388044 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/Cargo.lock @@ -0,0 +1,173 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +dependencies = [ + "memchr", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d299f547288d6db8d5c3a2916f7b2f66134b15b8c1ac1c4357dd3b8752af7bb2" +dependencies = [ + "critical-section", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "crossbeam-utils" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +dependencies = [ + "cfg-if", + "once_cell 1.14.0", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "once_cell" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" + +[[package]] +name = "once_cell" +version = "1.17.2" +dependencies = [ + "atomic-polyfill", + "critical-section", + "crossbeam-utils", + "lazy_static", + "parking_lot_core", + "regex", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/utshell-0.5.0/vendor/once_cell/Cargo.toml b/utshell-0.5.0/vendor/once_cell/Cargo.toml new file mode 100644 index 00000000..025fa46e --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/Cargo.toml @@ -0,0 +1,109 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.56" +name = "once_cell" +version = "1.17.2" +authors = ["Aleksey Kladov "] +exclude = [ + "*.png", + "*.svg", + "/Cargo.lock.msrv", + "rustfmt.toml", +] +description = "Single assignment cells and lazy values." +documentation = "https://docs.rs/once_cell" +readme = "README.md" +keywords = [ + "lazy", + "static", +] +categories = [ + "rust-patterns", + "memory-management", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/matklad/once_cell" + +[package.metadata.docs.rs] +all-features = true + +[[example]] +name = "bench" +required-features = ["std"] + +[[example]] +name = "bench_acquire" +required-features = ["std"] + +[[example]] +name = "bench_vs_lazy_static" +required-features = ["std"] + +[[example]] +name = "lazy_static" +required-features = ["std"] + +[[example]] +name = "reentrant_init_deadlocks" +required-features = ["std"] + +[[example]] +name = "regex" +required-features = ["std"] + +[[example]] +name = "test_synchronization" +required-features = ["std"] + +[dependencies.atomic_polyfill] +version = "1" +optional = true +package = "atomic-polyfill" + +[dependencies.critical_section] +version = "1" +optional = true +package = "critical-section" + +[dependencies.parking_lot_core] +version = "0.9.3" +optional = true +default_features = false + +[dev-dependencies.critical_section] +version = "1.1.1" +features = ["std"] +package = "critical-section" + +[dev-dependencies.crossbeam-utils] +version = "0.8.7" + +[dev-dependencies.lazy_static] +version = "1.0.0" + +[dev-dependencies.regex] +version = "1.2.0" + +[features] +alloc = ["race"] +atomic-polyfill = ["critical-section"] +critical-section = [ + "critical_section", + "atomic_polyfill", +] +default = ["std"] +parking_lot = ["parking_lot_core"] +race = [] +std = ["alloc"] +unstable = [] diff --git a/utshell-0.5.0/vendor/once_cell/LICENSE-APACHE b/utshell-0.5.0/vendor/once_cell/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/once_cell/LICENSE-MIT b/utshell-0.5.0/vendor/once_cell/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/once_cell/README.md b/utshell-0.5.0/vendor/once_cell/README.md new file mode 100644 index 00000000..737f2def --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/README.md @@ -0,0 +1,58 @@ +

once_cell

+ + +[![Build Status](https://github.com/matklad/once_cell/actions/workflows/ci.yaml/badge.svg)](https://github.com/matklad/once_cell/actions) +[![Crates.io](https://img.shields.io/crates/v/once_cell.svg)](https://crates.io/crates/once_cell) +[![API reference](https://docs.rs/once_cell/badge.svg)](https://docs.rs/once_cell/) + +# Overview + +`once_cell` provides two new cell-like types, `unsync::OnceCell` and `sync::OnceCell`. `OnceCell` +might store arbitrary non-`Copy` types, can be assigned to at most once and provide direct access +to the stored contents. In a nutshell, API looks *roughly* like this: + +```rust +impl OnceCell { + fn new() -> OnceCell { ... } + fn set(&self, value: T) -> Result<(), T> { ... } + fn get(&self) -> Option<&T> { ... } +} +``` + +Note that, like with `RefCell` and `Mutex`, the `set` method requires only a shared reference. +Because of the single assignment restriction `get` can return an `&T` instead of `Ref` +or `MutexGuard`. + +`once_cell` also has a `Lazy` type, build on top of `OnceCell` which provides the same API as +the `lazy_static!` macro, but without using any macros: + +```rust +use std::{sync::Mutex, collections::HashMap}; +use once_cell::sync::Lazy; + +static GLOBAL_DATA: Lazy>> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert(13, "Spica".to_string()); + m.insert(74, "Hoyten".to_string()); + Mutex::new(m) +}); + +fn main() { + println!("{:?}", GLOBAL_DATA.lock().unwrap()); +} +``` + +More patterns and use-cases are in the [docs](https://docs.rs/once_cell/)! + +# Related crates + +* [double-checked-cell](https://github.com/niklasf/double-checked-cell) +* [lazy-init](https://crates.io/crates/lazy-init) +* [lazycell](https://crates.io/crates/lazycell) +* [mitochondria](https://crates.io/crates/mitochondria) +* [lazy_static](https://crates.io/crates/lazy_static) +* [async_once_cell](https://crates.io/crates/async_once_cell) +* [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring your own mutex) + +The API of `once_cell` is being proposed for inclusion in +[`std`](https://github.com/rust-lang/rfcs/pull/2788). diff --git a/utshell-0.5.0/vendor/once_cell/bors.toml b/utshell-0.5.0/vendor/once_cell/bors.toml new file mode 100644 index 00000000..b92b99ac --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/bors.toml @@ -0,0 +1,2 @@ +status = [ "Rust" ] +delete_merged_branches = true diff --git a/utshell-0.5.0/vendor/once_cell/examples/bench.rs b/utshell-0.5.0/vendor/once_cell/examples/bench.rs new file mode 100644 index 00000000..e6801258 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/bench.rs @@ -0,0 +1,28 @@ +use std::mem::size_of; + +use once_cell::sync::OnceCell; + +const N_THREADS: usize = 32; +const N_ROUNDS: usize = 100_000_000; + +static CELL: OnceCell = OnceCell::new(); + +fn main() { + let start = std::time::Instant::now(); + let threads = + (0..N_THREADS).map(|i| std::thread::spawn(move || thread_main(i))).collect::>(); + for thread in threads { + thread.join().unwrap(); + } + println!("{:?}", start.elapsed()); + println!("size_of::>() = {:?}", size_of::>()); + println!("size_of::>() = {:?}", size_of::>()); + println!("size_of::>() = {:?}", size_of::>()); +} + +fn thread_main(i: usize) { + for _ in 0..N_ROUNDS { + let &value = CELL.get_or_init(|| i); + assert!(value < N_THREADS) + } +} diff --git a/utshell-0.5.0/vendor/once_cell/examples/bench_acquire.rs b/utshell-0.5.0/vendor/once_cell/examples/bench_acquire.rs new file mode 100644 index 00000000..15180474 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/bench_acquire.rs @@ -0,0 +1,39 @@ +//! Benchmark the overhead that the synchronization of `OnceCell::get` causes. +//! We do some other operations that write to memory to get an imprecise but somewhat realistic +//! measurement. + +use once_cell::sync::OnceCell; +use std::sync::atomic::{AtomicUsize, Ordering}; + +const N_THREADS: usize = 16; +const N_ROUNDS: usize = 1_000_000; + +static CELL: OnceCell = OnceCell::new(); +static OTHER: AtomicUsize = AtomicUsize::new(0); + +fn main() { + let start = std::time::Instant::now(); + let threads = + (0..N_THREADS).map(|i| std::thread::spawn(move || thread_main(i))).collect::>(); + for thread in threads { + thread.join().unwrap(); + } + println!("{:?}", start.elapsed()); + println!("{:?}", OTHER.load(Ordering::Relaxed)); +} + +#[inline(never)] +fn thread_main(i: usize) { + // The operations we do here don't really matter, as long as we do multiple writes, and + // everything is messy enough to prevent the compiler from optimizing the loop away. + let mut data = [i; 128]; + let mut accum = 0usize; + for _ in 0..N_ROUNDS { + let _value = CELL.get_or_init(|| i + 1); + let k = OTHER.fetch_add(data[accum & 0x7F] as usize, Ordering::Relaxed); + for j in data.iter_mut() { + *j = (*j).wrapping_add(accum); + accum = accum.wrapping_add(k); + } + } +} diff --git a/utshell-0.5.0/vendor/once_cell/examples/bench_vs_lazy_static.rs b/utshell-0.5.0/vendor/once_cell/examples/bench_vs_lazy_static.rs new file mode 100644 index 00000000..c23b0124 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/bench_vs_lazy_static.rs @@ -0,0 +1,51 @@ +use lazy_static::lazy_static; +use once_cell::sync::Lazy; + +const N_THREADS: usize = 32; +const N_ROUNDS: usize = 100_000_000; + +static ONCE_CELL: Lazy> = Lazy::new(|| vec!["Spica".to_string(), "Hoyten".to_string()]); + +lazy_static! { + static ref LAZY_STATIC: Vec = vec!["Spica".to_string(), "Hoyten".to_string()]; +} + +fn main() { + let once_cell = { + let start = std::time::Instant::now(); + let threads = (0..N_THREADS) + .map(|_| std::thread::spawn(move || thread_once_cell())) + .collect::>(); + for thread in threads { + thread.join().unwrap(); + } + start.elapsed() + }; + let lazy_static = { + let start = std::time::Instant::now(); + let threads = (0..N_THREADS) + .map(|_| std::thread::spawn(move || thread_lazy_static())) + .collect::>(); + for thread in threads { + thread.join().unwrap(); + } + start.elapsed() + }; + + println!("once_cell: {:?}", once_cell); + println!("lazy_static: {:?}", lazy_static); +} + +fn thread_once_cell() { + for _ in 0..N_ROUNDS { + let len = ONCE_CELL.len(); + assert_eq!(len, 2) + } +} + +fn thread_lazy_static() { + for _ in 0..N_ROUNDS { + let len = LAZY_STATIC.len(); + assert_eq!(len, 2) + } +} diff --git a/utshell-0.5.0/vendor/once_cell/examples/lazy_static.rs b/utshell-0.5.0/vendor/once_cell/examples/lazy_static.rs new file mode 100644 index 00000000..3cdb19f2 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/lazy_static.rs @@ -0,0 +1,36 @@ +extern crate once_cell; + +use once_cell::sync::{Lazy, OnceCell}; +use std::collections::HashMap; + +static HASHMAP: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert(0, "foo"); + m.insert(1, "bar"); + m.insert(2, "baz"); + m +}); + +// Same, but completely without macros +fn hashmap() -> &'static HashMap { + static INSTANCE: OnceCell> = OnceCell::new(); + INSTANCE.get_or_init(|| { + let mut m = HashMap::new(); + m.insert(0, "foo"); + m.insert(1, "bar"); + m.insert(2, "baz"); + m + }) +} + +fn main() { + // First access to `HASHMAP` initializes it + println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap()); + + // Any further access to `HASHMAP` just returns the computed value + println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap()); + + // The same works for function-style: + assert_eq!(hashmap().get(&0), Some(&"foo")); + assert_eq!(hashmap().get(&1), Some(&"bar")); +} diff --git a/utshell-0.5.0/vendor/once_cell/examples/reentrant_init_deadlocks.rs b/utshell-0.5.0/vendor/once_cell/examples/reentrant_init_deadlocks.rs new file mode 100644 index 00000000..af4b5b7d --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/reentrant_init_deadlocks.rs @@ -0,0 +1,14 @@ +fn main() { + let cell = once_cell::sync::OnceCell::::new(); + cell.get_or_init(|| { + cell.get_or_init(|| 1); + 2 + }); +} + +/// Dummy test to make it seem hang when compiled as `--test` +/// See https://github.com/matklad/once_cell/issues/79 +#[test] +fn dummy_test() { + std::thread::sleep(std::time::Duration::from_secs(4)); +} diff --git a/utshell-0.5.0/vendor/once_cell/examples/regex.rs b/utshell-0.5.0/vendor/once_cell/examples/regex.rs new file mode 100644 index 00000000..4c4c2ea6 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/regex.rs @@ -0,0 +1,49 @@ +use std::{str::FromStr, time::Instant}; + +use regex::Regex; + +macro_rules! regex { + ($re:literal $(,)?) => {{ + static RE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); + RE.get_or_init(|| regex::Regex::new($re).unwrap()) + }}; +} + +fn slow() { + let s = r##"13.28.24.13 - - [10/Mar/2016:19:29:25 +0100] "GET /etc/lib/pChart2/examples/index.php?Action=View&Script=../../../../cnf/db.php HTTP/1.1" 404 151 "-" "HTTP_Request2/2.2.1 (http://pear.php.net/package/http_request2) PHP/5.3.16""##; + + let mut total = 0; + for _ in 0..1000 { + let re = Regex::new( + r##"^(\S+) (\S+) (\S+) \[([^]]+)\] "([^"]*)" (\d+) (\d+) "([^"]*)" "([^"]*)"$"##, + ) + .unwrap(); + let size = usize::from_str(re.captures(s).unwrap().get(7).unwrap().as_str()).unwrap(); + total += size; + } + println!("{}", total); +} + +fn fast() { + let s = r##"13.28.24.13 - - [10/Mar/2016:19:29:25 +0100] "GET /etc/lib/pChart2/examples/index.php?Action=View&Script=../../../../cnf/db.php HTTP/1.1" 404 151 "-" "HTTP_Request2/2.2.1 (http://pear.php.net/package/http_request2) PHP/5.3.16""##; + + let mut total = 0; + for _ in 0..1000 { + let re: &Regex = regex!( + r##"^(\S+) (\S+) (\S+) \[([^]]+)\] "([^"]*)" (\d+) (\d+) "([^"]*)" "([^"]*)"$"##, + ); + let size = usize::from_str(re.captures(s).unwrap().get(7).unwrap().as_str()).unwrap(); + total += size; + } + println!("{}", total); +} + +fn main() { + let t = Instant::now(); + slow(); + println!("slow: {:?}", t.elapsed()); + + let t = Instant::now(); + fast(); + println!("fast: {:?}", t.elapsed()); +} diff --git a/utshell-0.5.0/vendor/once_cell/examples/test_synchronization.rs b/utshell-0.5.0/vendor/once_cell/examples/test_synchronization.rs new file mode 100644 index 00000000..0d54f982 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/examples/test_synchronization.rs @@ -0,0 +1,38 @@ +//! Test if the OnceCell properly synchronizes. +//! Needs to be run in release mode. +//! +//! We create a `Vec` with `N_ROUNDS` of `OnceCell`s. All threads will walk the `Vec`, and race to +//! be the first one to initialize a cell. +//! Every thread adds the results of the cells it sees to an accumulator, which is compared at the +//! end. +//! All threads should end up with the same result. + +use once_cell::sync::OnceCell; + +const N_THREADS: usize = 32; +const N_ROUNDS: usize = 1_000_000; + +static CELLS: OnceCell>> = OnceCell::new(); +static RESULT: OnceCell = OnceCell::new(); + +fn main() { + let start = std::time::Instant::now(); + CELLS.get_or_init(|| vec![OnceCell::new(); N_ROUNDS]); + let threads = + (0..N_THREADS).map(|i| std::thread::spawn(move || thread_main(i))).collect::>(); + for thread in threads { + thread.join().unwrap(); + } + println!("{:?}", start.elapsed()); + println!("No races detected"); +} + +fn thread_main(i: usize) { + let cells = CELLS.get().unwrap(); + let mut accum = 0; + for cell in cells.iter() { + let &value = cell.get_or_init(|| i); + accum += value; + } + assert_eq!(RESULT.get_or_init(|| accum), &accum); +} diff --git a/utshell-0.5.0/vendor/once_cell/src/imp_cs.rs b/utshell-0.5.0/vendor/once_cell/src/imp_cs.rs new file mode 100644 index 00000000..668f18ec --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/src/imp_cs.rs @@ -0,0 +1,78 @@ +use core::panic::{RefUnwindSafe, UnwindSafe}; + +use atomic_polyfill::{AtomicBool, Ordering}; +use critical_section::{CriticalSection, Mutex}; + +use crate::unsync; + +pub(crate) struct OnceCell { + initialized: AtomicBool, + // Use `unsync::OnceCell` internally since `Mutex` does not provide + // interior mutability and to be able to re-use `get_or_try_init`. + value: Mutex>, +} + +// Why do we need `T: Send`? +// Thread A creates a `OnceCell` and shares it with +// scoped thread B, which fills the cell, which is +// then destroyed by A. That is, destructor observes +// a sent value. +unsafe impl Sync for OnceCell {} +unsafe impl Send for OnceCell {} + +impl RefUnwindSafe for OnceCell {} +impl UnwindSafe for OnceCell {} + +impl OnceCell { + pub(crate) const fn new() -> OnceCell { + OnceCell { initialized: AtomicBool::new(false), value: Mutex::new(unsync::OnceCell::new()) } + } + + pub(crate) const fn with_value(value: T) -> OnceCell { + OnceCell { + initialized: AtomicBool::new(true), + value: Mutex::new(unsync::OnceCell::with_value(value)), + } + } + + #[inline] + pub(crate) fn is_initialized(&self) -> bool { + self.initialized.load(Ordering::Acquire) + } + + #[cold] + pub(crate) fn initialize(&self, f: F) -> Result<(), E> + where + F: FnOnce() -> Result, + { + critical_section::with(|cs| { + let cell = self.value.borrow(cs); + cell.get_or_try_init(f).map(|_| { + self.initialized.store(true, Ordering::Release); + }) + }) + } + + /// Get the reference to the underlying value, without checking if the cell + /// is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + pub(crate) unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + // SAFETY: The caller ensures that the value is initialized and access synchronized. + crate::unwrap_unchecked(self.value.borrow(CriticalSection::new()).get()) + } + + #[inline] + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + self.value.get_mut().get_mut() + } + + #[inline] + pub(crate) fn into_inner(self) -> Option { + self.value.into_inner().into_inner() + } +} diff --git a/utshell-0.5.0/vendor/once_cell/src/imp_pl.rs b/utshell-0.5.0/vendor/once_cell/src/imp_pl.rs new file mode 100644 index 00000000..84d85938 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/src/imp_pl.rs @@ -0,0 +1,174 @@ +use std::{ + cell::UnsafeCell, + panic::{RefUnwindSafe, UnwindSafe}, + sync::atomic::{AtomicU8, Ordering}, +}; + +pub(crate) struct OnceCell { + state: AtomicU8, + value: UnsafeCell>, +} + +const INCOMPLETE: u8 = 0x0; +const RUNNING: u8 = 0x1; +const COMPLETE: u8 = 0x2; + +// Why do we need `T: Send`? +// Thread A creates a `OnceCell` and shares it with +// scoped thread B, which fills the cell, which is +// then destroyed by A. That is, destructor observes +// a sent value. +unsafe impl Sync for OnceCell {} +unsafe impl Send for OnceCell {} + +impl RefUnwindSafe for OnceCell {} +impl UnwindSafe for OnceCell {} + +impl OnceCell { + pub(crate) const fn new() -> OnceCell { + OnceCell { state: AtomicU8::new(INCOMPLETE), value: UnsafeCell::new(None) } + } + + pub(crate) const fn with_value(value: T) -> OnceCell { + OnceCell { state: AtomicU8::new(COMPLETE), value: UnsafeCell::new(Some(value)) } + } + + /// Safety: synchronizes with store to value via Release/Acquire. + #[inline] + pub(crate) fn is_initialized(&self) -> bool { + self.state.load(Ordering::Acquire) == COMPLETE + } + + /// Safety: synchronizes with store to value via `is_initialized` or mutex + /// lock/unlock, writes value only once because of the mutex. + #[cold] + pub(crate) fn initialize(&self, f: F) -> Result<(), E> + where + F: FnOnce() -> Result, + { + let mut f = Some(f); + let mut res: Result<(), E> = Ok(()); + let slot: *mut Option = self.value.get(); + initialize_inner(&self.state, &mut || { + // We are calling user-supplied function and need to be careful. + // - if it returns Err, we unlock mutex and return without touching anything + // - if it panics, we unlock mutex and propagate panic without touching anything + // - if it calls `set` or `get_or_try_init` re-entrantly, we get a deadlock on + // mutex, which is important for safety. We *could* detect this and panic, + // but that is more complicated + // - finally, if it returns Ok, we store the value and store the flag with + // `Release`, which synchronizes with `Acquire`s. + let f = unsafe { crate::unwrap_unchecked(f.take()) }; + match f() { + Ok(value) => unsafe { + // Safe b/c we have a unique access and no panic may happen + // until the cell is marked as initialized. + debug_assert!((*slot).is_none()); + *slot = Some(value); + true + }, + Err(err) => { + res = Err(err); + false + } + } + }); + res + } + + #[cold] + pub(crate) fn wait(&self) { + let key = &self.state as *const _ as usize; + unsafe { + parking_lot_core::park( + key, + || self.state.load(Ordering::Acquire) != COMPLETE, + || (), + |_, _| (), + parking_lot_core::DEFAULT_PARK_TOKEN, + None, + ); + } + } + + /// Get the reference to the underlying value, without checking if the cell + /// is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + pub(crate) unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + let slot = &*self.value.get(); + crate::unwrap_unchecked(slot.as_ref()) + } + + /// Gets the mutable reference to the underlying value. + /// Returns `None` if the cell is empty. + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + // Safe b/c we have an exclusive access + let slot: &mut Option = unsafe { &mut *self.value.get() }; + slot.as_mut() + } + + /// Consumes this `OnceCell`, returning the wrapped value. + /// Returns `None` if the cell was empty. + pub(crate) fn into_inner(self) -> Option { + self.value.into_inner() + } +} + +struct Guard<'a> { + state: &'a AtomicU8, + new_state: u8, +} + +impl<'a> Drop for Guard<'a> { + fn drop(&mut self) { + self.state.store(self.new_state, Ordering::Release); + unsafe { + let key = self.state as *const AtomicU8 as usize; + parking_lot_core::unpark_all(key, parking_lot_core::DEFAULT_UNPARK_TOKEN); + } + } +} + +// Note: this is intentionally monomorphic +#[inline(never)] +fn initialize_inner(state: &AtomicU8, init: &mut dyn FnMut() -> bool) { + loop { + let exchange = + state.compare_exchange_weak(INCOMPLETE, RUNNING, Ordering::Acquire, Ordering::Acquire); + match exchange { + Ok(_) => { + let mut guard = Guard { state, new_state: INCOMPLETE }; + if init() { + guard.new_state = COMPLETE; + } + return; + } + Err(COMPLETE) => return, + Err(RUNNING) => unsafe { + let key = state as *const AtomicU8 as usize; + parking_lot_core::park( + key, + || state.load(Ordering::Relaxed) == RUNNING, + || (), + |_, _| (), + parking_lot_core::DEFAULT_PARK_TOKEN, + None, + ); + }, + Err(INCOMPLETE) => (), + Err(_) => debug_assert!(false), + } + } +} + +#[test] +fn test_size() { + use std::mem::size_of; + + assert_eq!(size_of::>(), 1 * size_of::() + size_of::()); +} diff --git a/utshell-0.5.0/vendor/once_cell/src/imp_std.rs b/utshell-0.5.0/vendor/once_cell/src/imp_std.rs new file mode 100644 index 00000000..b65e091e --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/src/imp_std.rs @@ -0,0 +1,425 @@ +// There's a lot of scary concurrent code in this module, but it is copied from +// `std::sync::Once` with two changes: +// * no poisoning +// * init function can fail + +use std::{ + cell::{Cell, UnsafeCell}, + marker::PhantomData, + panic::{RefUnwindSafe, UnwindSafe}, + sync::atomic::{AtomicBool, AtomicPtr, Ordering}, + thread::{self, Thread}, +}; + +#[derive(Debug)] +pub(crate) struct OnceCell { + // This `queue` field is the core of the implementation. It encodes two + // pieces of information: + // + // * The current state of the cell (`INCOMPLETE`, `RUNNING`, `COMPLETE`) + // * Linked list of threads waiting for the current cell. + // + // State is encoded in two low bits. Only `INCOMPLETE` and `RUNNING` states + // allow waiters. + queue: AtomicPtr, + _marker: PhantomData<*mut Waiter>, + value: UnsafeCell>, +} + +// Why do we need `T: Send`? +// Thread A creates a `OnceCell` and shares it with +// scoped thread B, which fills the cell, which is +// then destroyed by A. That is, destructor observes +// a sent value. +unsafe impl Sync for OnceCell {} +unsafe impl Send for OnceCell {} + +impl RefUnwindSafe for OnceCell {} +impl UnwindSafe for OnceCell {} + +impl OnceCell { + pub(crate) const fn new() -> OnceCell { + OnceCell { + queue: AtomicPtr::new(INCOMPLETE_PTR), + _marker: PhantomData, + value: UnsafeCell::new(None), + } + } + + pub(crate) const fn with_value(value: T) -> OnceCell { + OnceCell { + queue: AtomicPtr::new(COMPLETE_PTR), + _marker: PhantomData, + value: UnsafeCell::new(Some(value)), + } + } + + /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst). + #[inline] + pub(crate) fn is_initialized(&self) -> bool { + // An `Acquire` load is enough because that makes all the initialization + // operations visible to us, and, this being a fast path, weaker + // ordering helps with performance. This `Acquire` synchronizes with + // `SeqCst` operations on the slow path. + self.queue.load(Ordering::Acquire) == COMPLETE_PTR + } + + /// Safety: synchronizes with store to value via SeqCst read from state, + /// writes value only once because we never get to INCOMPLETE state after a + /// successful write. + #[cold] + pub(crate) fn initialize(&self, f: F) -> Result<(), E> + where + F: FnOnce() -> Result, + { + let mut f = Some(f); + let mut res: Result<(), E> = Ok(()); + let slot: *mut Option = self.value.get(); + initialize_or_wait( + &self.queue, + Some(&mut || { + let f = unsafe { crate::unwrap_unchecked(f.take()) }; + match f() { + Ok(value) => { + unsafe { *slot = Some(value) }; + true + } + Err(err) => { + res = Err(err); + false + } + } + }), + ); + res + } + + #[cold] + pub(crate) fn wait(&self) { + initialize_or_wait(&self.queue, None); + } + + /// Get the reference to the underlying value, without checking if the cell + /// is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + pub(crate) unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + let slot = &*self.value.get(); + crate::unwrap_unchecked(slot.as_ref()) + } + + /// Gets the mutable reference to the underlying value. + /// Returns `None` if the cell is empty. + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + // Safe b/c we have a unique access. + unsafe { &mut *self.value.get() }.as_mut() + } + + /// Consumes this `OnceCell`, returning the wrapped value. + /// Returns `None` if the cell was empty. + #[inline] + pub(crate) fn into_inner(self) -> Option { + // Because `into_inner` takes `self` by value, the compiler statically + // verifies that it is not currently borrowed. + // So, it is safe to move out `Option`. + self.value.into_inner() + } +} + +// Three states that a OnceCell can be in, encoded into the lower bits of `queue` in +// the OnceCell structure. +const INCOMPLETE: usize = 0x0; +const RUNNING: usize = 0x1; +const COMPLETE: usize = 0x2; +const INCOMPLETE_PTR: *mut Waiter = INCOMPLETE as *mut Waiter; +const COMPLETE_PTR: *mut Waiter = COMPLETE as *mut Waiter; + +// Mask to learn about the state. All other bits are the queue of waiters if +// this is in the RUNNING state. +const STATE_MASK: usize = 0x3; + +/// Representation of a node in the linked list of waiters in the RUNNING state. +/// A waiters is stored on the stack of the waiting threads. +#[repr(align(4))] // Ensure the two lower bits are free to use as state bits. +struct Waiter { + thread: Cell>, + signaled: AtomicBool, + next: *mut Waiter, +} + +/// Drains and notifies the queue of waiters on drop. +struct Guard<'a> { + queue: &'a AtomicPtr, + new_queue: *mut Waiter, +} + +impl Drop for Guard<'_> { + fn drop(&mut self) { + let queue = self.queue.swap(self.new_queue, Ordering::AcqRel); + + let state = strict::addr(queue) & STATE_MASK; + assert_eq!(state, RUNNING); + + unsafe { + let mut waiter = strict::map_addr(queue, |q| q & !STATE_MASK); + while !waiter.is_null() { + let next = (*waiter).next; + let thread = (*waiter).thread.take().unwrap(); + (*waiter).signaled.store(true, Ordering::Release); + waiter = next; + thread.unpark(); + } + } + } +} + +// Corresponds to `std::sync::Once::call_inner`. +// +// Originally copied from std, but since modified to remove poisoning and to +// support wait. +// +// Note: this is intentionally monomorphic +#[inline(never)] +fn initialize_or_wait(queue: &AtomicPtr, mut init: Option<&mut dyn FnMut() -> bool>) { + let mut curr_queue = queue.load(Ordering::Acquire); + + loop { + let curr_state = strict::addr(curr_queue) & STATE_MASK; + match (curr_state, &mut init) { + (COMPLETE, _) => return, + (INCOMPLETE, Some(init)) => { + let exchange = queue.compare_exchange( + curr_queue, + strict::map_addr(curr_queue, |q| (q & !STATE_MASK) | RUNNING), + Ordering::Acquire, + Ordering::Acquire, + ); + if let Err(new_queue) = exchange { + curr_queue = new_queue; + continue; + } + let mut guard = Guard { queue, new_queue: INCOMPLETE_PTR }; + if init() { + guard.new_queue = COMPLETE_PTR; + } + return; + } + (INCOMPLETE, None) | (RUNNING, _) => { + wait(queue, curr_queue); + curr_queue = queue.load(Ordering::Acquire); + } + _ => debug_assert!(false), + } + } +} + +fn wait(queue: &AtomicPtr, mut curr_queue: *mut Waiter) { + let curr_state = strict::addr(curr_queue) & STATE_MASK; + loop { + let node = Waiter { + thread: Cell::new(Some(thread::current())), + signaled: AtomicBool::new(false), + next: strict::map_addr(curr_queue, |q| q & !STATE_MASK), + }; + let me = &node as *const Waiter as *mut Waiter; + + let exchange = queue.compare_exchange( + curr_queue, + strict::map_addr(me, |q| q | curr_state), + Ordering::Release, + Ordering::Relaxed, + ); + if let Err(new_queue) = exchange { + if strict::addr(new_queue) & STATE_MASK != curr_state { + return; + } + curr_queue = new_queue; + continue; + } + + while !node.signaled.load(Ordering::Acquire) { + thread::park(); + } + break; + } +} + +// Polyfill of strict provenance from https://crates.io/crates/sptr. +// +// Use free-standing function rather than a trait to keep things simple and +// avoid any potential conflicts with future stabile std API. +mod strict { + #[must_use] + #[inline] + pub(crate) fn addr(ptr: *mut T) -> usize + where + T: Sized, + { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the + // provenance). + unsafe { core::mem::transmute(ptr) } + } + + #[must_use] + #[inline] + pub(crate) fn with_addr(ptr: *mut T, addr: usize) -> *mut T + where + T: Sized, + { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // + // In the mean-time, this operation is defined to be "as if" it was + // a wrapping_offset, so we can emulate it as such. This should properly + // restore pointer provenance even under today's compiler. + let self_addr = self::addr(ptr) as isize; + let dest_addr = addr as isize; + let offset = dest_addr.wrapping_sub(self_addr); + + // This is the canonical desugarring of this operation, + // but `pointer::cast` was only stabilized in 1.38. + // self.cast::().wrapping_offset(offset).cast::() + (ptr as *mut u8).wrapping_offset(offset) as *mut T + } + + #[must_use] + #[inline] + pub(crate) fn map_addr(ptr: *mut T, f: impl FnOnce(usize) -> usize) -> *mut T + where + T: Sized, + { + self::with_addr(ptr, f(addr(ptr))) + } +} + +// These test are snatched from std as well. +#[cfg(test)] +mod tests { + use std::panic; + use std::{sync::mpsc::channel, thread}; + + use super::OnceCell; + + impl OnceCell { + fn init(&self, f: impl FnOnce() -> T) { + enum Void {} + let _ = self.initialize(|| Ok::(f())); + } + } + + #[test] + fn smoke_once() { + static O: OnceCell<()> = OnceCell::new(); + let mut a = 0; + O.init(|| a += 1); + assert_eq!(a, 1); + O.init(|| a += 1); + assert_eq!(a, 1); + } + + #[test] + fn stampede_once() { + static O: OnceCell<()> = OnceCell::new(); + static mut RUN: bool = false; + + let (tx, rx) = channel(); + for _ in 0..10 { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..4 { + thread::yield_now() + } + unsafe { + O.init(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + tx.send(()).unwrap(); + }); + } + + unsafe { + O.init(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + + for _ in 0..10 { + rx.recv().unwrap(); + } + } + + #[test] + fn poison_bad() { + static O: OnceCell<()> = OnceCell::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.init(|| panic!()); + }); + assert!(t.is_err()); + + // we can subvert poisoning, however + let mut called = false; + O.init(|| { + called = true; + }); + assert!(called); + + // once any success happens, we stop propagating the poison + O.init(|| {}); + } + + #[test] + fn wait_for_force_to_finish() { + static O: OnceCell<()> = OnceCell::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.init(|| panic!()); + }); + assert!(t.is_err()); + + // make sure someone's waiting inside the once via a force + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + let t1 = thread::spawn(move || { + O.init(|| { + tx1.send(()).unwrap(); + rx2.recv().unwrap(); + }); + }); + + rx1.recv().unwrap(); + + // put another waiter on the once + let t2 = thread::spawn(|| { + let mut called = false; + O.init(|| { + called = true; + }); + assert!(!called); + }); + + tx2.send(()).unwrap(); + + assert!(t1.join().is_ok()); + assert!(t2.join().is_ok()); + } + + #[test] + #[cfg(target_pointer_width = "64")] + fn test_size() { + use std::mem::size_of; + + assert_eq!(size_of::>(), 4 * size_of::()); + } +} diff --git a/utshell-0.5.0/vendor/once_cell/src/lib.rs b/utshell-0.5.0/vendor/once_cell/src/lib.rs new file mode 100644 index 00000000..4c2d0e41 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/src/lib.rs @@ -0,0 +1,1428 @@ +//! # Overview +//! +//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and +//! [`sync::OnceCell`]. A `OnceCell` might store arbitrary non-`Copy` types, can +//! be assigned to at most once and provides direct access to the stored +//! contents. The core API looks *roughly* like this (and there's much more +//! inside, read on!): +//! +//! ```rust,ignore +//! impl OnceCell { +//! const fn new() -> OnceCell { ... } +//! fn set(&self, value: T) -> Result<(), T> { ... } +//! fn get(&self) -> Option<&T> { ... } +//! } +//! ``` +//! +//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires +//! only a shared reference. Because of the single assignment restriction `get` +//! can return a `&T` instead of `Ref` or `MutexGuard`. +//! +//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait), +//! while the `unsync` one is not. +//! +//! [`unsync::OnceCell`]: unsync/struct.OnceCell.html +//! [`sync::OnceCell`]: sync/struct.OnceCell.html +//! [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html +//! [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html +//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html +//! +//! # Recipes +//! +//! `OnceCell` might be useful for a variety of patterns. +//! +//! ## Safe Initialization of Global Data +//! +//! ```rust +//! use std::{env, io}; +//! +//! use once_cell::sync::OnceCell; +//! +//! #[derive(Debug)] +//! pub struct Logger { +//! // ... +//! } +//! static INSTANCE: OnceCell = OnceCell::new(); +//! +//! impl Logger { +//! pub fn global() -> &'static Logger { +//! INSTANCE.get().expect("logger is not initialized") +//! } +//! +//! fn from_cli(args: env::Args) -> Result { +//! // ... +//! # Ok(Logger {}) +//! } +//! } +//! +//! fn main() { +//! let logger = Logger::from_cli(env::args()).unwrap(); +//! INSTANCE.set(logger).unwrap(); +//! // use `Logger::global()` from now on +//! } +//! ``` +//! +//! ## Lazy Initialized Global Data +//! +//! This is essentially the `lazy_static!` macro, but without a macro. +//! +//! ```rust +//! use std::{sync::Mutex, collections::HashMap}; +//! +//! use once_cell::sync::OnceCell; +//! +//! fn global_data() -> &'static Mutex> { +//! static INSTANCE: OnceCell>> = OnceCell::new(); +//! INSTANCE.get_or_init(|| { +//! let mut m = HashMap::new(); +//! m.insert(13, "Spica".to_string()); +//! m.insert(74, "Hoyten".to_string()); +//! Mutex::new(m) +//! }) +//! } +//! ``` +//! +//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to +//! streamline this pattern: +//! +//! ```rust +//! use std::{sync::Mutex, collections::HashMap}; +//! use once_cell::sync::Lazy; +//! +//! static GLOBAL_DATA: Lazy>> = Lazy::new(|| { +//! let mut m = HashMap::new(); +//! m.insert(13, "Spica".to_string()); +//! m.insert(74, "Hoyten".to_string()); +//! Mutex::new(m) +//! }); +//! +//! fn main() { +//! println!("{:?}", GLOBAL_DATA.lock().unwrap()); +//! } +//! ``` +//! +//! Note that the variable that holds `Lazy` is declared as `static`, *not* +//! `const`. This is important: using `const` instead compiles, but works wrong. +//! +//! [`sync::Lazy`]: sync/struct.Lazy.html +//! [`unsync::Lazy`]: unsync/struct.Lazy.html +//! +//! ## General purpose lazy evaluation +//! +//! Unlike `lazy_static!`, `Lazy` works with local variables. +//! +//! ```rust +//! use once_cell::unsync::Lazy; +//! +//! fn main() { +//! let ctx = vec![1, 2, 3]; +//! let thunk = Lazy::new(|| { +//! ctx.iter().sum::() +//! }); +//! assert_eq!(*thunk, 6); +//! } +//! ``` +//! +//! If you need a lazy field in a struct, you probably should use `OnceCell` +//! directly, because that will allow you to access `self` during +//! initialization. +//! +//! ```rust +//! use std::{fs, path::PathBuf}; +//! +//! use once_cell::unsync::OnceCell; +//! +//! struct Ctx { +//! config_path: PathBuf, +//! config: OnceCell, +//! } +//! +//! impl Ctx { +//! pub fn get_config(&self) -> Result<&str, std::io::Error> { +//! let cfg = self.config.get_or_try_init(|| { +//! fs::read_to_string(&self.config_path) +//! })?; +//! Ok(cfg.as_str()) +//! } +//! } +//! ``` +//! +//! ## Lazily Compiled Regex +//! +//! This is a `regex!` macro which takes a string literal and returns an +//! *expression* that evaluates to a `&'static Regex`: +//! +//! ``` +//! macro_rules! regex { +//! ($re:literal $(,)?) => {{ +//! static RE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); +//! RE.get_or_init(|| regex::Regex::new($re).unwrap()) +//! }}; +//! } +//! ``` +//! +//! This macro can be useful to avoid the "compile regex on every loop +//! iteration" problem. +//! +//! ## Runtime `include_bytes!` +//! +//! The `include_bytes` macro is useful to include test resources, but it slows +//! down test compilation a lot. An alternative is to load the resources at +//! runtime: +//! +//! ``` +//! use std::path::Path; +//! +//! use once_cell::sync::OnceCell; +//! +//! pub struct TestResource { +//! path: &'static str, +//! cell: OnceCell>, +//! } +//! +//! impl TestResource { +//! pub const fn new(path: &'static str) -> TestResource { +//! TestResource { path, cell: OnceCell::new() } +//! } +//! pub fn bytes(&self) -> &[u8] { +//! self.cell.get_or_init(|| { +//! let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); +//! let path = Path::new(dir.as_str()).join(self.path); +//! std::fs::read(&path).unwrap_or_else(|_err| { +//! panic!("failed to load test resource: {}", path.display()) +//! }) +//! }).as_slice() +//! } +//! } +//! +//! static TEST_IMAGE: TestResource = TestResource::new("test_data/lena.png"); +//! +//! #[test] +//! fn test_sobel_filter() { +//! let rgb: &[u8] = TEST_IMAGE.bytes(); +//! // ... +//! # drop(rgb); +//! } +//! ``` +//! +//! ## `lateinit` +//! +//! `LateInit` type for delayed initialization. It is reminiscent of Kotlin's +//! `lateinit` keyword and allows construction of cyclic data structures: +//! +//! +//! ``` +//! use once_cell::sync::OnceCell; +//! +//! pub struct LateInit { cell: OnceCell } +//! +//! impl LateInit { +//! pub fn init(&self, value: T) { +//! assert!(self.cell.set(value).is_ok()) +//! } +//! } +//! +//! impl Default for LateInit { +//! fn default() -> Self { LateInit { cell: OnceCell::default() } } +//! } +//! +//! impl std::ops::Deref for LateInit { +//! type Target = T; +//! fn deref(&self) -> &T { +//! self.cell.get().unwrap() +//! } +//! } +//! +//! #[derive(Default)] +//! struct A<'a> { +//! b: LateInit<&'a B<'a>>, +//! } +//! +//! #[derive(Default)] +//! struct B<'a> { +//! a: LateInit<&'a A<'a>> +//! } +//! +//! +//! fn build_cycle() { +//! let a = A::default(); +//! let b = B::default(); +//! a.b.init(&b); +//! b.a.init(&a); +//! +//! let _a = &a.b.a.b.a; +//! } +//! ``` +//! +//! # Comparison with std +//! +//! |`!Sync` types | Access Mode | Drawbacks | +//! |----------------------|------------------------|-----------------------------------------------| +//! |`Cell` | `T` | requires `T: Copy` for `get` | +//! |`RefCell` | `RefMut` / `Ref` | may panic at runtime | +//! |`unsync::OnceCell` | `&T` | assignable only once | +//! +//! |`Sync` types | Access Mode | Drawbacks | +//! |----------------------|------------------------|-----------------------------------------------| +//! |`AtomicT` | `T` | works only with certain `Copy` types | +//! |`Mutex` | `MutexGuard` | may deadlock at runtime, may block the thread | +//! |`sync::OnceCell` | `&T` | assignable only once, may block the thread | +//! +//! Technically, calling `get_or_init` will also cause a panic or a deadlock if +//! it recursively calls itself. However, because the assignment can happen only +//! once, such cases should be more rare than equivalents with `RefCell` and +//! `Mutex`. +//! +//! # Minimum Supported `rustc` Version +//! +//! This crate's minimum supported `rustc` version is `1.56.0`. +//! +//! If only the `std` feature is enabled, MSRV will be updated conservatively, +//! supporting at least latest 8 versions of the compiler. When using other +//! features, like `parking_lot`, MSRV might be updated more frequently, up to +//! the latest stable. In both cases, increasing MSRV is *not* considered a +//! semver-breaking change. +//! +//! # Implementation details +//! +//! The implementation is based on the +//! [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/) and +//! [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and +//! [`std::sync::Once`]. In some sense, `once_cell` just streamlines and unifies +//! those APIs. +//! +//! To implement a sync flavor of `OnceCell`, this crates uses either a custom +//! re-implementation of `std::sync::Once` or `parking_lot::Mutex`. This is +//! controlled by the `parking_lot` feature (disabled by default). Performance +//! is the same for both cases, but the `parking_lot` based `OnceCell` is +//! smaller by up to 16 bytes. +//! +//! This crate uses `unsafe`. +//! +//! [`std::sync::Once`]: https://doc.rust-lang.org/std/sync/struct.Once.html +//! +//! # F.A.Q. +//! +//! **Should I use the sync or unsync flavor?** +//! +//! Because Rust compiler checks thread safety for you, it's impossible to +//! accidentally use `unsync` where `sync` is required. So, use `unsync` in +//! single-threaded code and `sync` in multi-threaded. It's easy to switch +//! between the two if code becomes multi-threaded later. +//! +//! At the moment, `unsync` has an additional benefit that reentrant +//! initialization causes a panic, which might be easier to debug than a +//! deadlock. +//! +//! **Does this crate support async?** +//! +//! No, but you can use +//! [`async_once_cell`](https://crates.io/crates/async_once_cell) instead. +//! +//! **Does this crate support `no_std`?** +//! +//! Yes, but with caveats. `OnceCell` is a synchronization primitive which +//! _semantically_ relies on blocking. `OnceCell` guarantees that at most one +//! `f` will be called to compute the value. If two threads of execution call +//! `get_or_init` concurrently, one of them has to wait. +//! +//! Waiting fundamentally requires OS support. Execution environment needs to +//! understand who waits on whom to prevent deadlocks due to priority inversion. +//! You _could_ make code to compile by blindly using pure spinlocks, but the +//! runtime behavior would be subtly wrong. +//! +//! Given these constraints, `once_cell` provides the following options: +//! +//! - The `race` module provides similar, but distinct synchronization primitive +//! which is compatible with `no_std`. With `race`, the `f` function can be +//! called multiple times by different threads, but only one thread will win +//! to install the value. +//! - `critical-section` feature (with a `-`, not `_`) uses `critical_section` +//! to implement blocking. +//! +//! **Can I bring my own mutex?** +//! +//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to +//! allow just that. +//! +//! **Should I use `std::cell::OnceCell`, `once_cell`, or `lazy_static`?** +//! +//! If you can use `std` version (your MSRV is at least 1.70, and you don't need +//! extra features `once_cell` provides), use `std`. Otherwise, use `once_cell`. +//! Don't use `lazy_static`. +//! +//! # Related crates +//! +//! * Most of this crate's functionality is available in `std` starting with +//! Rust 1.70. See `std::cell::OnceCell` and `std::sync::OnceLock`. +//! * [double-checked-cell](https://github.com/niklasf/double-checked-cell) +//! * [lazy-init](https://crates.io/crates/lazy-init) +//! * [lazycell](https://crates.io/crates/lazycell) +//! * [mitochondria](https://crates.io/crates/mitochondria) +//! * [lazy_static](https://crates.io/crates/lazy_static) +//! * [async_once_cell](https://crates.io/crates/async_once_cell) +//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring +//! your own mutex) + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(all(feature = "critical-section", not(feature = "std")))] +#[path = "imp_cs.rs"] +mod imp; + +#[cfg(all(feature = "std", feature = "parking_lot"))] +#[path = "imp_pl.rs"] +mod imp; + +#[cfg(all(feature = "std", not(feature = "parking_lot")))] +#[path = "imp_std.rs"] +mod imp; + +/// Single-threaded version of `OnceCell`. +pub mod unsync { + use core::{ + cell::{Cell, UnsafeCell}, + fmt, mem, + ops::{Deref, DerefMut}, + panic::{RefUnwindSafe, UnwindSafe}, + }; + + use super::unwrap_unchecked; + + /// A cell which can be written to only once. It is not thread safe. + /// + /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&` + /// references to the contents. + /// + /// [`std::cell::RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// let value: &String = cell.get_or_init(|| { + /// "Hello, World!".to_string() + /// }); + /// assert_eq!(value, "Hello, World!"); + /// assert!(cell.get().is_some()); + /// ``` + pub struct OnceCell { + // Invariant: written to at most once. + inner: UnsafeCell>, + } + + // Similarly to a `Sync` bound on `sync::OnceCell`, we can use + // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`, + // by initializing the cell in closure and extracting the value in the + // `Drop`. + impl RefUnwindSafe for OnceCell {} + impl UnwindSafe for OnceCell {} + + impl Default for OnceCell { + fn default() -> Self { + Self::new() + } + } + + impl fmt::Debug for OnceCell { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { + Some(v) => f.debug_tuple("OnceCell").field(v).finish(), + None => f.write_str("OnceCell(Uninit)"), + } + } + } + + impl Clone for OnceCell { + fn clone(&self) -> OnceCell { + match self.get() { + Some(value) => OnceCell::with_value(value.clone()), + None => OnceCell::new(), + } + } + + fn clone_from(&mut self, source: &Self) { + match (self.get_mut(), source.get()) { + (Some(this), Some(source)) => this.clone_from(source), + _ => *self = source.clone(), + } + } + } + + impl PartialEq for OnceCell { + fn eq(&self, other: &Self) -> bool { + self.get() == other.get() + } + } + + impl Eq for OnceCell {} + + impl From for OnceCell { + fn from(value: T) -> Self { + OnceCell::with_value(value) + } + } + + impl OnceCell { + /// Creates a new empty cell. + pub const fn new() -> OnceCell { + OnceCell { inner: UnsafeCell::new(None) } + } + + /// Creates a new initialized cell. + pub const fn with_value(value: T) -> OnceCell { + OnceCell { inner: UnsafeCell::new(Some(value)) } + } + + /// Gets a reference to the underlying value. + /// + /// Returns `None` if the cell is empty. + #[inline] + pub fn get(&self) -> Option<&T> { + // Safe due to `inner`'s invariant of being written to at most once. + // Had multiple writes to `inner` been allowed, a reference to the + // value we return now would become dangling by a write of a + // different value later. + unsafe { &*self.inner.get() }.as_ref() + } + + /// Gets a mutable reference to the underlying value. + /// + /// Returns `None` if the cell is empty. + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// *cell.get_mut().unwrap() = 93; + /// assert_eq!(cell.get(), Some(&93)); + /// ``` + #[inline] + pub fn get_mut(&mut self) -> Option<&mut T> { + // Safe because we have unique access + unsafe { &mut *self.inner.get() }.as_mut() + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.set(92), Ok(())); + /// assert_eq!(cell.set(62), Err(62)); + /// + /// assert!(cell.get().is_some()); + /// ``` + pub fn set(&self, value: T) -> Result<(), T> { + match self.try_insert(value) { + Ok(_) => Ok(()), + Err((_, value)) => Err(value), + } + } + + /// Like [`set`](Self::set), but also returns a reference to the final cell value. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.try_insert(92), Ok(&92)); + /// assert_eq!(cell.try_insert(62), Err((&92, 62))); + /// + /// assert!(cell.get().is_some()); + /// ``` + pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { + if let Some(old) = self.get() { + return Err((old, value)); + } + + let slot = unsafe { &mut *self.inner.get() }; + // This is the only place where we set the slot, no races + // due to reentrancy/concurrency are possible, and we've + // checked that slot is currently `None`, so this write + // maintains the `inner`'s invariant. + *slot = Some(value); + Ok(unsafe { unwrap_unchecked(slot.as_ref()) }) + } + + /// Gets the contents of the cell, initializing it with `f` + /// if the cell was empty. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. Doing + /// so results in a panic. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// let value = cell.get_or_init(|| 92); + /// assert_eq!(value, &92); + /// let value = cell.get_or_init(|| unreachable!()); + /// assert_eq!(value, &92); + /// ``` + pub fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + enum Void {} + match self.get_or_try_init(|| Ok::(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. Doing + /// so results in a panic. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + /// assert!(cell.get().is_none()); + /// let value = cell.get_or_try_init(|| -> Result { + /// Ok(92) + /// }); + /// assert_eq!(value, Ok(&92)); + /// assert_eq!(cell.get(), Some(&92)) + /// ``` + pub fn get_or_try_init(&self, f: F) -> Result<&T, E> + where + F: FnOnce() -> Result, + { + if let Some(val) = self.get() { + return Ok(val); + } + let val = f()?; + // Note that *some* forms of reentrant initialization might lead to + // UB (see `reentrant_init` test). I believe that just removing this + // `assert`, while keeping `set/get` would be sound, but it seems + // better to panic, rather than to silently use an old value. + assert!(self.set(val).is_ok(), "reentrant init"); + Ok(unsafe { unwrap_unchecked(self.get()) }) + } + + /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state. + /// + /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized. + /// + /// # Examples + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.take(), None); + /// + /// let mut cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.take(), Some("hello".to_string())); + /// assert_eq!(cell.get(), None); + /// ``` + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// cell = OnceCell::new(); + /// ``` + pub fn take(&mut self) -> Option { + mem::take(self).into_inner() + } + + /// Consumes the `OnceCell`, returning the wrapped value. + /// + /// Returns `None` if the cell was empty. + /// + /// # Examples + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.into_inner(), None); + /// + /// let cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.into_inner(), Some("hello".to_string())); + /// ``` + pub fn into_inner(self) -> Option { + // Because `into_inner` takes `self` by value, the compiler statically verifies + // that it is not currently borrowed. So it is safe to move out `Option`. + self.inner.into_inner() + } + } + + /// A value which is initialized on the first access. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let lazy: Lazy = Lazy::new(|| { + /// println!("initializing"); + /// 92 + /// }); + /// println!("ready"); + /// println!("{}", *lazy); + /// println!("{}", *lazy); + /// + /// // Prints: + /// // ready + /// // initializing + /// // 92 + /// // 92 + /// ``` + pub struct Lazy T> { + cell: OnceCell, + init: Cell>, + } + + impl RefUnwindSafe for Lazy where OnceCell: RefUnwindSafe {} + + impl fmt::Debug for Lazy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + } + } + + impl Lazy { + /// Creates a new lazy value with the given initializing function. + /// + /// # Example + /// ``` + /// # fn main() { + /// use once_cell::unsync::Lazy; + /// + /// let hello = "Hello, World!".to_string(); + /// + /// let lazy = Lazy::new(|| hello.to_uppercase()); + /// + /// assert_eq!(&*lazy, "HELLO, WORLD!"); + /// # } + /// ``` + pub const fn new(init: F) -> Lazy { + Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) } + } + + /// Consumes this `Lazy` returning the stored value. + /// + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. + pub fn into_value(this: Lazy) -> Result { + let cell = this.cell; + let init = this.init; + cell.into_inner().ok_or_else(|| { + init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned")) + }) + } + } + + impl T> Lazy { + /// Forces the evaluation of this lazy value and returns a reference to + /// the result. + /// + /// This is equivalent to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force(&lazy), &92); + /// assert_eq!(&*lazy, &92); + /// ``` + pub fn force(this: &Lazy) -> &T { + this.cell.get_or_init(|| match this.init.take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }) + } + + /// Forces the evaluation of this lazy value and returns a mutable reference to + /// the result. + /// + /// This is equivalent to the `DerefMut` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force_mut(&mut lazy), &92); + /// assert_eq!(*lazy, 92); + /// ``` + pub fn force_mut(this: &mut Lazy) -> &mut T { + if this.cell.get_mut().is_none() { + let value = match this.init.get_mut().take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }; + this.cell = OnceCell::with_value(value); + } + this.cell.get_mut().unwrap_or_else(|| unreachable!()) + } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get(&lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get(&lazy), Some(&92)); + /// ``` + pub fn get(this: &Lazy) -> Option<&T> { + this.cell.get() + } + + /// Gets the mutable reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get_mut(&mut lazy), None); + /// assert_eq!(*lazy, 92); + /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92)); + /// ``` + pub fn get_mut(this: &mut Lazy) -> Option<&mut T> { + this.cell.get_mut() + } + } + + impl T> Deref for Lazy { + type Target = T; + fn deref(&self) -> &T { + Lazy::force(self) + } + } + + impl T> DerefMut for Lazy { + fn deref_mut(&mut self) -> &mut T { + Lazy::force_mut(self) + } + } + + impl Default for Lazy { + /// Creates a new lazy value using `Default` as the initializing function. + fn default() -> Lazy { + Lazy::new(T::default) + } + } +} + +/// Thread-safe, blocking version of `OnceCell`. +#[cfg(any(feature = "std", feature = "critical-section"))] +pub mod sync { + use core::{ + cell::Cell, + fmt, mem, + ops::{Deref, DerefMut}, + panic::RefUnwindSafe, + }; + + use super::{imp::OnceCell as Imp, unwrap_unchecked}; + + /// A thread-safe cell which can be written to only once. + /// + /// `OnceCell` provides `&` references to the contents without RAII guards. + /// + /// Reading a non-`None` value out of `OnceCell` establishes a + /// happens-before relationship with a corresponding write. For example, if + /// thread A initializes the cell with `get_or_init(f)`, and thread B + /// subsequently reads the result of this call, B also observes all the side + /// effects of `f`. + /// + /// # Example + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// static CELL: OnceCell = OnceCell::new(); + /// assert!(CELL.get().is_none()); + /// + /// std::thread::spawn(|| { + /// let value: &String = CELL.get_or_init(|| { + /// "Hello, World!".to_string() + /// }); + /// assert_eq!(value, "Hello, World!"); + /// }).join().unwrap(); + /// + /// let value: Option<&String> = CELL.get(); + /// assert!(value.is_some()); + /// assert_eq!(value.unwrap().as_str(), "Hello, World!"); + /// ``` + pub struct OnceCell(Imp); + + impl Default for OnceCell { + fn default() -> OnceCell { + OnceCell::new() + } + } + + impl fmt::Debug for OnceCell { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { + Some(v) => f.debug_tuple("OnceCell").field(v).finish(), + None => f.write_str("OnceCell(Uninit)"), + } + } + } + + impl Clone for OnceCell { + fn clone(&self) -> OnceCell { + match self.get() { + Some(value) => Self::with_value(value.clone()), + None => Self::new(), + } + } + + fn clone_from(&mut self, source: &Self) { + match (self.get_mut(), source.get()) { + (Some(this), Some(source)) => this.clone_from(source), + _ => *self = source.clone(), + } + } + } + + impl From for OnceCell { + fn from(value: T) -> Self { + Self::with_value(value) + } + } + + impl PartialEq for OnceCell { + fn eq(&self, other: &OnceCell) -> bool { + self.get() == other.get() + } + } + + impl Eq for OnceCell {} + + impl OnceCell { + /// Creates a new empty cell. + pub const fn new() -> OnceCell { + OnceCell(Imp::new()) + } + + /// Creates a new initialized cell. + pub const fn with_value(value: T) -> OnceCell { + OnceCell(Imp::with_value(value)) + } + + /// Gets the reference to the underlying value. + /// + /// Returns `None` if the cell is empty, or being initialized. This + /// method never blocks. + pub fn get(&self) -> Option<&T> { + if self.0.is_initialized() { + // Safe b/c value is initialized. + Some(unsafe { self.get_unchecked() }) + } else { + None + } + } + + /// Gets the reference to the underlying value, blocking the current + /// thread until it is set. + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell = std::sync::Arc::new(OnceCell::new()); + /// let t = std::thread::spawn({ + /// let cell = std::sync::Arc::clone(&cell); + /// move || cell.set(92).unwrap() + /// }); + /// + /// // Returns immediately, but might return None. + /// let _value_or_none = cell.get(); + /// + /// // Will return 92, but might block until the other thread does `.set`. + /// let value: &u32 = cell.wait(); + /// assert_eq!(*value, 92); + /// t.join().unwrap(); + /// ``` + #[cfg(feature = "std")] + pub fn wait(&self) -> &T { + if !self.0.is_initialized() { + self.0.wait() + } + debug_assert!(self.0.is_initialized()); + // Safe b/c of the wait call above and the fact that we didn't + // relinquish our borrow. + unsafe { self.get_unchecked() } + } + + /// Gets the mutable reference to the underlying value. + /// + /// Returns `None` if the cell is empty. + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// cell = OnceCell::new(); + /// ``` + #[inline] + pub fn get_mut(&mut self) -> Option<&mut T> { + self.0.get_mut() + } + + /// Get the reference to the underlying value, without checking if the + /// cell is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + #[inline] + pub unsafe fn get_unchecked(&self) -> &T { + self.0.get_unchecked() + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + /// + /// # Example + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// static CELL: OnceCell = OnceCell::new(); + /// + /// fn main() { + /// assert!(CELL.get().is_none()); + /// + /// std::thread::spawn(|| { + /// assert_eq!(CELL.set(92), Ok(())); + /// }).join().unwrap(); + /// + /// assert_eq!(CELL.set(62), Err(62)); + /// assert_eq!(CELL.get(), Some(&92)); + /// } + /// ``` + pub fn set(&self, value: T) -> Result<(), T> { + match self.try_insert(value) { + Ok(_) => Ok(()), + Err((_, value)) => Err(value), + } + } + + /// Like [`set`](Self::set), but also returns a reference to the final cell value. + /// + /// # Example + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.try_insert(92), Ok(&92)); + /// assert_eq!(cell.try_insert(62), Err((&92, 62))); + /// + /// assert!(cell.get().is_some()); + /// ``` + pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { + let mut value = Some(value); + let res = self.get_or_init(|| unsafe { unwrap_unchecked(value.take()) }); + match value { + None => Ok(res), + Some(value) => Err((res, value)), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell + /// was empty. + /// + /// Many threads may call `get_or_init` concurrently with different + /// initializing functions, but it is guaranteed that only one function + /// will be executed. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. The + /// exact outcome is unspecified. Current implementation deadlocks, but + /// this may be changed to a panic in the future. + /// + /// # Example + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// let value = cell.get_or_init(|| 92); + /// assert_eq!(value, &92); + /// let value = cell.get_or_init(|| unreachable!()); + /// assert_eq!(value, &92); + /// ``` + pub fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + enum Void {} + match self.get_or_try_init(|| Ok::(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and + /// the cell remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. + /// The exact outcome is unspecified. Current implementation + /// deadlocks, but this may be changed to a panic in the future. + /// + /// # Example + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + /// assert!(cell.get().is_none()); + /// let value = cell.get_or_try_init(|| -> Result { + /// Ok(92) + /// }); + /// assert_eq!(value, Ok(&92)); + /// assert_eq!(cell.get(), Some(&92)) + /// ``` + pub fn get_or_try_init(&self, f: F) -> Result<&T, E> + where + F: FnOnce() -> Result, + { + // Fast path check + if let Some(value) = self.get() { + return Ok(value); + } + + self.0.initialize(f)?; + + // Safe b/c value is initialized. + debug_assert!(self.0.is_initialized()); + Ok(unsafe { self.get_unchecked() }) + } + + /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state. + /// + /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized. + /// + /// # Examples + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.take(), None); + /// + /// let mut cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.take(), Some("hello".to_string())); + /// assert_eq!(cell.get(), None); + /// ``` + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// cell = OnceCell::new(); + /// ``` + pub fn take(&mut self) -> Option { + mem::take(self).into_inner() + } + + /// Consumes the `OnceCell`, returning the wrapped value. Returns + /// `None` if the cell was empty. + /// + /// # Examples + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.into_inner(), None); + /// + /// let cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.into_inner(), Some("hello".to_string())); + /// ``` + #[inline] + pub fn into_inner(self) -> Option { + self.0.into_inner() + } + } + + /// A value which is initialized on the first access. + /// + /// This type is thread-safe and can be used in statics. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// use once_cell::sync::Lazy; + /// + /// static HASHMAP: Lazy> = Lazy::new(|| { + /// println!("initializing"); + /// let mut m = HashMap::new(); + /// m.insert(13, "Spica".to_string()); + /// m.insert(74, "Hoyten".to_string()); + /// m + /// }); + /// + /// fn main() { + /// println!("ready"); + /// std::thread::spawn(|| { + /// println!("{:?}", HASHMAP.get(&13)); + /// }).join().unwrap(); + /// println!("{:?}", HASHMAP.get(&74)); + /// + /// // Prints: + /// // ready + /// // initializing + /// // Some("Spica") + /// // Some("Hoyten") + /// } + /// ``` + pub struct Lazy T> { + cell: OnceCell, + init: Cell>, + } + + impl fmt::Debug for Lazy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + } + } + + // We never create a `&F` from a `&Lazy` so it is fine to not impl + // `Sync` for `F`. We do create a `&mut Option` in `force`, but this is + // properly synchronized, so it only happens once so it also does not + // contribute to this impl. + unsafe impl Sync for Lazy where OnceCell: Sync {} + // auto-derived `Send` impl is OK. + + impl RefUnwindSafe for Lazy where OnceCell: RefUnwindSafe {} + + impl Lazy { + /// Creates a new lazy value with the given initializing + /// function. + pub const fn new(f: F) -> Lazy { + Lazy { cell: OnceCell::new(), init: Cell::new(Some(f)) } + } + + /// Consumes this `Lazy` returning the stored value. + /// + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. + pub fn into_value(this: Lazy) -> Result { + let cell = this.cell; + let init = this.init; + cell.into_inner().ok_or_else(|| { + init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned")) + }) + } + } + + impl T> Lazy { + /// Forces the evaluation of this lazy value and + /// returns a reference to the result. This is equivalent + /// to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force(&lazy), &92); + /// assert_eq!(&*lazy, &92); + /// ``` + pub fn force(this: &Lazy) -> &T { + this.cell.get_or_init(|| match this.init.take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }) + } + + /// Forces the evaluation of this lazy value and + /// returns a mutable reference to the result. This is equivalent + /// to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92); + /// ``` + pub fn force_mut(this: &mut Lazy) -> &mut T { + if this.cell.get_mut().is_none() { + let value = match this.init.get_mut().take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }; + this.cell = OnceCell::with_value(value); + } + this.cell.get_mut().unwrap_or_else(|| unreachable!()) + } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get(&lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get(&lazy), Some(&92)); + /// ``` + pub fn get(this: &Lazy) -> Option<&T> { + this.cell.get() + } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get_mut(&mut lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92)); + /// ``` + pub fn get_mut(this: &mut Lazy) -> Option<&mut T> { + this.cell.get_mut() + } + } + + impl T> Deref for Lazy { + type Target = T; + fn deref(&self) -> &T { + Lazy::force(self) + } + } + + impl T> DerefMut for Lazy { + fn deref_mut(&mut self) -> &mut T { + Lazy::force_mut(self) + } + } + + impl Default for Lazy { + /// Creates a new lazy value using `Default` as the initializing function. + fn default() -> Lazy { + Lazy::new(T::default) + } + } + + /// ```compile_fail + /// struct S(*mut ()); + /// unsafe impl Sync for S {} + /// + /// fn share(_: &T) {} + /// share(&once_cell::sync::OnceCell::::new()); + /// ``` + /// + /// ```compile_fail + /// struct S(*mut ()); + /// unsafe impl Sync for S {} + /// + /// fn share(_: &T) {} + /// share(&once_cell::sync::Lazy::::new(|| unimplemented!())); + /// ``` + fn _dummy() {} +} + +#[cfg(feature = "race")] +pub mod race; + +// Remove once MSRV is at least 1.58. +#[inline] +unsafe fn unwrap_unchecked(val: Option) -> T { + match val { + Some(value) => value, + None => { + debug_assert!(false); + core::hint::unreachable_unchecked() + } + } +} diff --git a/utshell-0.5.0/vendor/once_cell/src/race.rs b/utshell-0.5.0/vendor/once_cell/src/race.rs new file mode 100644 index 00000000..fe36fa17 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/src/race.rs @@ -0,0 +1,419 @@ +//! Thread-safe, non-blocking, "first one wins" flavor of `OnceCell`. +//! +//! If two threads race to initialize a type from the `race` module, they +//! don't block, execute initialization function together, but only one of +//! them stores the result. +//! +//! This module does not require `std` feature. +//! +//! # Atomic orderings +//! +//! All types in this module use `Acquire` and `Release` +//! [atomic orderings](Ordering) for all their operations. While this is not +//! strictly necessary for types other than `OnceBox`, it is useful for users as +//! it allows them to be certain that after `get` or `get_or_init` returns on +//! one thread, any side-effects caused by the setter thread prior to them +//! calling `set` or `get_or_init` will be made visible to that thread; without +//! it, it's possible for it to appear as if they haven't happened yet from the +//! getter thread's perspective. This is an acceptable tradeoff to make since +//! `Acquire` and `Release` have very little performance overhead on most +//! architectures versus `Relaxed`. + +#[cfg(feature = "critical-section")] +use atomic_polyfill as atomic; +#[cfg(not(feature = "critical-section"))] +use core::sync::atomic; + +use atomic::{AtomicPtr, AtomicUsize, Ordering}; +use core::cell::UnsafeCell; +use core::marker::PhantomData; +use core::num::NonZeroUsize; +use core::ptr; + +/// A thread-safe cell which can be written to only once. +#[derive(Default, Debug)] +pub struct OnceNonZeroUsize { + inner: AtomicUsize, +} + +impl OnceNonZeroUsize { + /// Creates a new empty cell. + #[inline] + pub const fn new() -> OnceNonZeroUsize { + OnceNonZeroUsize { inner: AtomicUsize::new(0) } + } + + /// Gets the underlying value. + #[inline] + pub fn get(&self) -> Option { + let val = self.inner.load(Ordering::Acquire); + NonZeroUsize::new(val) + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(())` if it was + /// full. + #[inline] + pub fn set(&self, value: NonZeroUsize) -> Result<(), ()> { + let exchange = + self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire); + match exchange { + Ok(_) => Ok(()), + Err(_) => Err(()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> NonZeroUsize + where + F: FnOnce() -> NonZeroUsize, + { + enum Void {} + match self.get_or_try_init(|| Ok::(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result + where + F: FnOnce() -> Result, + { + let val = self.inner.load(Ordering::Acquire); + let res = match NonZeroUsize::new(val) { + Some(it) => it, + None => { + let mut val = f()?.get(); + let exchange = + self.inner.compare_exchange(0, val, Ordering::AcqRel, Ordering::Acquire); + if let Err(old) = exchange { + val = old; + } + unsafe { NonZeroUsize::new_unchecked(val) } + } + }; + Ok(res) + } +} + +/// A thread-safe cell which can be written to only once. +#[derive(Default, Debug)] +pub struct OnceBool { + inner: OnceNonZeroUsize, +} + +impl OnceBool { + /// Creates a new empty cell. + #[inline] + pub const fn new() -> OnceBool { + OnceBool { inner: OnceNonZeroUsize::new() } + } + + /// Gets the underlying value. + #[inline] + pub fn get(&self) -> Option { + self.inner.get().map(OnceBool::from_usize) + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(())` if it was + /// full. + #[inline] + pub fn set(&self, value: bool) -> Result<(), ()> { + self.inner.set(OnceBool::to_usize(value)) + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> bool + where + F: FnOnce() -> bool, + { + OnceBool::from_usize(self.inner.get_or_init(|| OnceBool::to_usize(f()))) + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result + where + F: FnOnce() -> Result, + { + self.inner.get_or_try_init(|| f().map(OnceBool::to_usize)).map(OnceBool::from_usize) + } + + #[inline] + fn from_usize(value: NonZeroUsize) -> bool { + value.get() == 1 + } + + #[inline] + fn to_usize(value: bool) -> NonZeroUsize { + unsafe { NonZeroUsize::new_unchecked(if value { 1 } else { 2 }) } + } +} + +/// A thread-safe cell which can be written to only once. +pub struct OnceRef<'a, T> { + inner: AtomicPtr, + ghost: PhantomData>, +} + +// TODO: Replace UnsafeCell with SyncUnsafeCell once stabilized +unsafe impl<'a, T: Sync> Sync for OnceRef<'a, T> {} + +impl<'a, T> core::fmt::Debug for OnceRef<'a, T> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "OnceRef({:?})", self.inner) + } +} + +impl<'a, T> Default for OnceRef<'a, T> { + fn default() -> Self { + Self::new() + } +} + +impl<'a, T> OnceRef<'a, T> { + /// Creates a new empty cell. + pub const fn new() -> OnceRef<'a, T> { + OnceRef { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData } + } + + /// Gets a reference to the underlying value. + pub fn get(&self) -> Option<&'a T> { + let ptr = self.inner.load(Ordering::Acquire); + unsafe { ptr.as_ref() } + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + pub fn set(&self, value: &'a T) -> Result<(), ()> { + let ptr = value as *const T as *mut T; + let exchange = + self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::AcqRel, Ordering::Acquire); + match exchange { + Ok(_) => Ok(()), + Err(_) => Err(()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> &'a T + where + F: FnOnce() -> &'a T, + { + enum Void {} + match self.get_or_try_init(|| Ok::<&'a T, Void>(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result<&'a T, E> + where + F: FnOnce() -> Result<&'a T, E>, + { + let mut ptr = self.inner.load(Ordering::Acquire); + + if ptr.is_null() { + // TODO replace with `cast_mut` when MSRV reaches 1.65.0 (also in `set`) + ptr = f()? as *const T as *mut T; + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if let Err(old) = exchange { + ptr = old; + } + } + + Ok(unsafe { &*ptr }) + } + + /// ```compile_fail + /// use once_cell::race::OnceRef; + /// + /// let mut l = OnceRef::new(); + /// + /// { + /// let y = 2; + /// let mut r = OnceRef::new(); + /// r.set(&y).unwrap(); + /// core::mem::swap(&mut l, &mut r); + /// } + /// + /// // l now contains a dangling reference to y + /// eprintln!("uaf: {}", l.get().unwrap()); + /// ``` + fn _dummy() {} +} + +#[cfg(feature = "alloc")] +pub use self::once_box::OnceBox; + +#[cfg(feature = "alloc")] +mod once_box { + use super::atomic::{AtomicPtr, Ordering}; + use core::{marker::PhantomData, ptr}; + + use alloc::boxed::Box; + + /// A thread-safe cell which can be written to only once. + pub struct OnceBox { + inner: AtomicPtr, + ghost: PhantomData>>, + } + + impl core::fmt::Debug for OnceBox { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "OnceBox({:?})", self.inner.load(Ordering::Relaxed)) + } + } + + impl Default for OnceBox { + fn default() -> Self { + Self::new() + } + } + + impl Drop for OnceBox { + fn drop(&mut self) { + let ptr = *self.inner.get_mut(); + if !ptr.is_null() { + drop(unsafe { Box::from_raw(ptr) }) + } + } + } + + impl OnceBox { + /// Creates a new empty cell. + pub const fn new() -> OnceBox { + OnceBox { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData } + } + + /// Gets a reference to the underlying value. + pub fn get(&self) -> Option<&T> { + let ptr = self.inner.load(Ordering::Acquire); + if ptr.is_null() { + return None; + } + Some(unsafe { &*ptr }) + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + pub fn set(&self, value: Box) -> Result<(), Box> { + let ptr = Box::into_raw(value); + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if exchange.is_err() { + let value = unsafe { Box::from_raw(ptr) }; + return Err(value); + } + Ok(()) + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> Box, + { + enum Void {} + match self.get_or_try_init(|| Ok::, Void>(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result<&T, E> + where + F: FnOnce() -> Result, E>, + { + let mut ptr = self.inner.load(Ordering::Acquire); + + if ptr.is_null() { + let val = f()?; + ptr = Box::into_raw(val); + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if let Err(old) = exchange { + drop(unsafe { Box::from_raw(ptr) }); + ptr = old; + } + }; + Ok(unsafe { &*ptr }) + } + } + + unsafe impl Sync for OnceBox {} + + /// ```compile_fail + /// struct S(*mut ()); + /// unsafe impl Sync for S {} + /// + /// fn share(_: &T) {} + /// share(&once_cell::race::OnceBox::::new()); + /// ``` + fn _dummy() {} +} diff --git a/utshell-0.5.0/vendor/once_cell/tests/it.rs b/utshell-0.5.0/vendor/once_cell/tests/it.rs new file mode 100644 index 00000000..d18f0a16 --- /dev/null +++ b/utshell-0.5.0/vendor/once_cell/tests/it.rs @@ -0,0 +1,977 @@ +mod unsync { + use core::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + }; + + use once_cell::unsync::{Lazy, OnceCell}; + + #[test] + fn once_cell() { + let c = OnceCell::new(); + assert!(c.get().is_none()); + c.get_or_init(|| 92); + assert_eq!(c.get(), Some(&92)); + + c.get_or_init(|| panic!("Kabom!")); + assert_eq!(c.get(), Some(&92)); + } + + #[test] + fn once_cell_with_value() { + const CELL: OnceCell = OnceCell::with_value(12); + let cell = CELL; + assert_eq!(cell.get(), Some(&12)); + } + + #[test] + fn once_cell_get_mut() { + let mut c = OnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); + } + + #[test] + fn once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = OnceCell::new(); + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + assert_eq!(DROP_CNT.load(SeqCst), 1); + } + + #[test] + fn unsync_once_cell_drop_empty() { + let x = OnceCell::::new(); + drop(x); + } + + #[test] + fn clone() { + let s = OnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); + } + + #[test] + fn from_impl() { + assert_eq!(OnceCell::from("value").get(), Some(&"value")); + assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); + } + + #[test] + fn partialeq_impl() { + assert!(OnceCell::from("value") == OnceCell::from("value")); + assert!(OnceCell::from("foo") != OnceCell::from("bar")); + + assert!(OnceCell::::new() == OnceCell::new()); + assert!(OnceCell::::new() != OnceCell::from("value".to_owned())); + } + + #[test] + fn into_inner() { + let cell: OnceCell = OnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = OnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); + } + + #[test] + fn debug_impl() { + let cell = OnceCell::new(); + assert_eq!(format!("{:?}", cell), "OnceCell(Uninit)"); + cell.set("hello".to_string()).unwrap(); + assert_eq!(format!("{:?}", cell), "OnceCell(\"hello\")"); + } + + #[test] + fn lazy_new() { + let called = Cell::new(0); + let x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + } + + #[test] + fn lazy_deref_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + + *x /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); + } + + #[test] + fn lazy_force_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + assert_eq!(called.get(), 0); + let v = Lazy::force_mut(&mut x); + assert_eq!(called.get(), 1); + + *v /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); + } + + #[test] + fn lazy_get_mut() { + let called = Cell::new(0); + let mut x: Lazy = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + assert_eq!(*x, 92); + + let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); + assert_eq!(called.get(), 1); + + *mut_ref /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); + } + + #[test] + fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); + } + + #[test] + fn lazy_into_value() { + let l: Lazy = Lazy::new(|| panic!()); + assert!(matches!(Lazy::into_value(l), Err(_))); + let l = Lazy::new(|| -> i32 { 92 }); + Lazy::force(&l); + assert!(matches!(Lazy::into_value(l), Ok(92))); + } + + #[test] + #[cfg(feature = "std")] + fn lazy_poisoning() { + let x: Lazy = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = std::panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } + } + + #[test] + fn aliasing_in_get() { + let x = OnceCell::new(); + x.set(42).unwrap(); + let at_x = x.get().unwrap(); // --- (shared) borrow of inner `Option` --+ + let _ = x.set(27); // <-- temporary (unique) borrow of inner `Option` | + println!("{}", at_x); // <------- up until here ---------------------------+ + } + + #[test] + #[should_panic(expected = "reentrant init")] + fn reentrant_init() { + let x: OnceCell> = OnceCell::new(); + let dangling_ref: Cell> = Cell::new(None); + x.get_or_init(|| { + let r = x.get_or_init(|| Box::new(92)); + dangling_ref.set(Some(r)); + Box::new(62) + }); + eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); + } + + #[test] + // https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 + fn arrrrrrrrrrrrrrrrrrrrrr() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } + } +} + +#[cfg(any(feature = "std", feature = "critical-section"))] +mod sync { + use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; + + #[cfg(feature = "std")] + use std::sync::Barrier; + + #[cfg(not(feature = "std"))] + use core::cell::Cell; + + use crossbeam_utils::thread::scope; + + use once_cell::sync::{Lazy, OnceCell}; + + #[test] + fn once_cell() { + let c = OnceCell::new(); + assert!(c.get().is_none()); + scope(|s| { + s.spawn(|_| { + c.get_or_init(|| 92); + assert_eq!(c.get(), Some(&92)); + }); + }) + .unwrap(); + c.get_or_init(|| panic!("Kabom!")); + assert_eq!(c.get(), Some(&92)); + } + + #[test] + fn once_cell_with_value() { + static CELL: OnceCell = OnceCell::with_value(12); + assert_eq!(CELL.get(), Some(&12)); + } + + #[test] + fn once_cell_get_mut() { + let mut c = OnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); + } + + #[test] + fn once_cell_get_unchecked() { + let c = OnceCell::new(); + c.set(92).unwrap(); + unsafe { + assert_eq!(c.get_unchecked(), &92); + } + } + + #[test] + fn once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = OnceCell::new(); + scope(|s| { + s.spawn(|_| { + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + }); + }) + .unwrap(); + assert_eq!(DROP_CNT.load(SeqCst), 1); + } + + #[test] + fn once_cell_drop_empty() { + let x = OnceCell::::new(); + drop(x); + } + + #[test] + fn clone() { + let s = OnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); + } + + #[test] + fn get_or_try_init() { + let cell: OnceCell = OnceCell::new(); + assert!(cell.get().is_none()); + + let res = + std::panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + assert!(cell.get().is_none()); + + assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + + assert_eq!( + cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), + Ok(&"hello".to_string()) + ); + assert_eq!(cell.get(), Some(&"hello".to_string())); + } + + #[cfg(feature = "std")] + #[test] + fn wait() { + let cell: OnceCell = OnceCell::new(); + scope(|s| { + s.spawn(|_| cell.set("hello".to_string())); + let greeting = cell.wait(); + assert_eq!(greeting, "hello") + }) + .unwrap(); + } + + #[cfg(feature = "std")] + #[test] + fn get_or_init_stress() { + let n_threads = if cfg!(miri) { 30 } else { 1_000 }; + let n_cells = if cfg!(miri) { 30 } else { 1_000 }; + let cells: Vec<_> = std::iter::repeat_with(|| (Barrier::new(n_threads), OnceCell::new())) + .take(n_cells) + .collect(); + scope(|s| { + for t in 0..n_threads { + let cells = &cells; + s.spawn(move |_| { + for (i, (b, s)) in cells.iter().enumerate() { + b.wait(); + let j = if t % 2 == 0 { s.wait() } else { s.get_or_init(|| i) }; + assert_eq!(*j, i); + } + }); + } + }) + .unwrap(); + } + + #[test] + fn from_impl() { + assert_eq!(OnceCell::from("value").get(), Some(&"value")); + assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); + } + + #[test] + fn partialeq_impl() { + assert!(OnceCell::from("value") == OnceCell::from("value")); + assert!(OnceCell::from("foo") != OnceCell::from("bar")); + + assert!(OnceCell::::new() == OnceCell::new()); + assert!(OnceCell::::new() != OnceCell::from("value".to_owned())); + } + + #[test] + fn into_inner() { + let cell: OnceCell = OnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = OnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); + } + + #[test] + fn debug_impl() { + let cell = OnceCell::new(); + assert_eq!(format!("{:#?}", cell), "OnceCell(Uninit)"); + cell.set(vec!["hello", "world"]).unwrap(); + assert_eq!( + format!("{:#?}", cell), + r#"OnceCell( + [ + "hello", + "world", + ], +)"# + ); + } + + #[test] + #[cfg_attr(miri, ignore)] // miri doesn't support processes + #[cfg(feature = "std")] + fn reentrant_init() { + let examples_dir = { + let mut exe = std::env::current_exe().unwrap(); + exe.pop(); + exe.pop(); + exe.push("examples"); + exe + }; + let bin = examples_dir + .join("reentrant_init_deadlocks") + .with_extension(std::env::consts::EXE_EXTENSION); + let mut guard = Guard { child: std::process::Command::new(bin).spawn().unwrap() }; + std::thread::sleep(std::time::Duration::from_secs(2)); + let status = guard.child.try_wait().unwrap(); + assert!(status.is_none()); + + struct Guard { + child: std::process::Child, + } + + impl Drop for Guard { + fn drop(&mut self) { + let _ = self.child.kill(); + } + } + } + + #[cfg(not(feature = "std"))] + #[test] + #[should_panic(expected = "reentrant init")] + fn reentrant_init() { + let x: OnceCell> = OnceCell::new(); + let dangling_ref: Cell> = Cell::new(None); + x.get_or_init(|| { + let r = x.get_or_init(|| Box::new(92)); + dangling_ref.set(Some(r)); + Box::new(62) + }); + eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); + } + + #[test] + fn lazy_new() { + let called = AtomicUsize::new(0); + let x = Lazy::new(|| { + called.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(called.load(SeqCst), 0); + + scope(|s| { + s.spawn(|_| { + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + }); + }) + .unwrap(); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + } + + #[test] + fn lazy_deref_mut() { + let called = AtomicUsize::new(0); + let mut x = Lazy::new(|| { + called.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(called.load(SeqCst), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + + *x /= 2; + assert_eq!(*x, 46); + assert_eq!(called.load(SeqCst), 1); + } + + #[test] + fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); + } + + #[test] + fn static_lazy() { + static XS: Lazy> = Lazy::new(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }); + scope(|s| { + s.spawn(|_| { + assert_eq!(&*XS, &vec![1, 2, 3]); + }); + }) + .unwrap(); + assert_eq!(&*XS, &vec![1, 2, 3]); + } + + #[test] + fn static_lazy_via_fn() { + fn xs() -> &'static Vec { + static XS: OnceCell> = OnceCell::new(); + XS.get_or_init(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }) + } + assert_eq!(xs(), &vec![1, 2, 3]); + } + + #[test] + fn lazy_into_value() { + let l: Lazy = Lazy::new(|| panic!()); + assert!(matches!(Lazy::into_value(l), Err(_))); + let l = Lazy::new(|| -> i32 { 92 }); + Lazy::force(&l); + assert!(matches!(Lazy::into_value(l), Ok(92))); + } + + #[test] + fn lazy_poisoning() { + let x: Lazy = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = std::panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } + } + + #[test] + fn once_cell_is_sync_send() { + fn assert_traits() {} + assert_traits::>(); + assert_traits::>(); + } + + #[test] + fn eval_once_macro() { + macro_rules! eval_once { + (|| -> $ty:ty { + $($body:tt)* + }) => {{ + static ONCE_CELL: OnceCell<$ty> = OnceCell::new(); + fn init() -> $ty { + $($body)* + } + ONCE_CELL.get_or_init(init) + }}; + } + + let fib: &'static Vec = eval_once! { + || -> Vec { + let mut res = vec![1, 1]; + for i in 0..10 { + let next = res[i] + res[i + 1]; + res.push(next); + } + res + } + }; + assert_eq!(fib[5], 8) + } + + #[test] + fn once_cell_does_not_leak_partially_constructed_boxes() { + let n_tries = if cfg!(miri) { 10 } else { 100 }; + let n_readers = 10; + let n_writers = 3; + const MSG: &str = "Hello, World"; + + for _ in 0..n_tries { + let cell: OnceCell = OnceCell::new(); + scope(|scope| { + for _ in 0..n_readers { + scope.spawn(|_| loop { + if let Some(msg) = cell.get() { + assert_eq!(msg, MSG); + break; + } + }); + } + for _ in 0..n_writers { + let _ = scope.spawn(|_| cell.set(MSG.to_owned())); + } + }) + .unwrap() + } + } + + #[cfg(feature = "std")] + #[test] + fn get_does_not_block() { + let cell = OnceCell::new(); + let barrier = Barrier::new(2); + scope(|scope| { + scope.spawn(|_| { + cell.get_or_init(|| { + barrier.wait(); + barrier.wait(); + "hello".to_string() + }); + }); + barrier.wait(); + assert_eq!(cell.get(), None); + barrier.wait(); + }) + .unwrap(); + assert_eq!(cell.get(), Some(&"hello".to_string())); + } + + #[test] + // https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 + fn arrrrrrrrrrrrrrrrrrrrrr() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } + } +} + +#[cfg(feature = "race")] +mod race { + #[cfg(feature = "std")] + use std::sync::Barrier; + use std::{ + num::NonZeroUsize, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + }; + + use crossbeam_utils::thread::scope; + + use once_cell::race::{OnceBool, OnceNonZeroUsize}; + + #[test] + fn once_non_zero_usize_smoke_test() { + let cnt = AtomicUsize::new(0); + let cell = OnceNonZeroUsize::new(); + let val = NonZeroUsize::new(92).unwrap(); + scope(|s| { + s.spawn(|_| { + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + val + }), + val + ); + assert_eq!(cnt.load(SeqCst), 1); + + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + val + }), + val + ); + assert_eq!(cnt.load(SeqCst), 1); + }); + }) + .unwrap(); + assert_eq!(cell.get(), Some(val)); + assert_eq!(cnt.load(SeqCst), 1); + } + + #[test] + fn once_non_zero_usize_set() { + let val1 = NonZeroUsize::new(92).unwrap(); + let val2 = NonZeroUsize::new(62).unwrap(); + + let cell = OnceNonZeroUsize::new(); + + assert!(cell.set(val1).is_ok()); + assert_eq!(cell.get(), Some(val1)); + + assert!(cell.set(val2).is_err()); + assert_eq!(cell.get(), Some(val1)); + } + + #[cfg(feature = "std")] + #[test] + fn once_non_zero_usize_first_wins() { + let val1 = NonZeroUsize::new(92).unwrap(); + let val2 = NonZeroUsize::new(62).unwrap(); + + let cell = OnceNonZeroUsize::new(); + + let b1 = Barrier::new(2); + let b2 = Barrier::new(2); + let b3 = Barrier::new(2); + scope(|s| { + s.spawn(|_| { + let r1 = cell.get_or_init(|| { + b1.wait(); + b2.wait(); + val1 + }); + assert_eq!(r1, val1); + b3.wait(); + }); + b1.wait(); + s.spawn(|_| { + let r2 = cell.get_or_init(|| { + b2.wait(); + b3.wait(); + val2 + }); + assert_eq!(r2, val1); + }); + }) + .unwrap(); + + assert_eq!(cell.get(), Some(val1)); + } + + #[test] + fn once_bool_smoke_test() { + let cnt = AtomicUsize::new(0); + let cell = OnceBool::new(); + scope(|s| { + s.spawn(|_| { + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + false + }), + false + ); + assert_eq!(cnt.load(SeqCst), 1); + + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + false + }), + false + ); + assert_eq!(cnt.load(SeqCst), 1); + }); + }) + .unwrap(); + assert_eq!(cell.get(), Some(false)); + assert_eq!(cnt.load(SeqCst), 1); + } + + #[test] + fn once_bool_set() { + let cell = OnceBool::new(); + + assert!(cell.set(false).is_ok()); + assert_eq!(cell.get(), Some(false)); + + assert!(cell.set(true).is_err()); + assert_eq!(cell.get(), Some(false)); + } +} + +#[cfg(all(feature = "race", feature = "alloc"))] +mod race_once_box { + #[cfg(feature = "std")] + use std::sync::Barrier; + use std::sync::{ + atomic::{AtomicUsize, Ordering::SeqCst}, + Arc, + }; + + #[cfg(feature = "std")] + use crossbeam_utils::thread::scope; + + use once_cell::race::OnceBox; + + #[derive(Default)] + struct Heap { + total: Arc, + } + + #[derive(Debug)] + struct Pebble { + val: T, + total: Arc, + } + + impl Drop for Pebble { + fn drop(&mut self) { + self.total.fetch_sub(1, SeqCst); + } + } + + impl Heap { + fn total(&self) -> usize { + self.total.load(SeqCst) + } + fn new_pebble(&self, val: T) -> Pebble { + self.total.fetch_add(1, SeqCst); + Pebble { val, total: Arc::clone(&self.total) } + } + } + + #[cfg(feature = "std")] + #[test] + fn once_box_smoke_test() { + let heap = Heap::default(); + let global_cnt = AtomicUsize::new(0); + let cell = OnceBox::new(); + let b = Barrier::new(128); + scope(|s| { + for _ in 0..128 { + s.spawn(|_| { + let local_cnt = AtomicUsize::new(0); + cell.get_or_init(|| { + global_cnt.fetch_add(1, SeqCst); + local_cnt.fetch_add(1, SeqCst); + b.wait(); + Box::new(heap.new_pebble(())) + }); + assert_eq!(local_cnt.load(SeqCst), 1); + + cell.get_or_init(|| { + global_cnt.fetch_add(1, SeqCst); + local_cnt.fetch_add(1, SeqCst); + Box::new(heap.new_pebble(())) + }); + assert_eq!(local_cnt.load(SeqCst), 1); + }); + } + }) + .unwrap(); + assert!(cell.get().is_some()); + assert!(global_cnt.load(SeqCst) > 10); + + assert_eq!(heap.total(), 1); + drop(cell); + assert_eq!(heap.total(), 0); + } + + #[test] + fn once_box_set() { + let heap = Heap::default(); + let cell = OnceBox::new(); + assert!(cell.get().is_none()); + + assert!(cell.set(Box::new(heap.new_pebble("hello"))).is_ok()); + assert_eq!(cell.get().unwrap().val, "hello"); + assert_eq!(heap.total(), 1); + + assert!(cell.set(Box::new(heap.new_pebble("world"))).is_err()); + assert_eq!(cell.get().unwrap().val, "hello"); + assert_eq!(heap.total(), 1); + + drop(cell); + assert_eq!(heap.total(), 0); + } + + #[cfg(feature = "std")] + #[test] + fn once_box_first_wins() { + let cell = OnceBox::new(); + let val1 = 92; + let val2 = 62; + + let b1 = Barrier::new(2); + let b2 = Barrier::new(2); + let b3 = Barrier::new(2); + scope(|s| { + s.spawn(|_| { + let r1 = cell.get_or_init(|| { + b1.wait(); + b2.wait(); + Box::new(val1) + }); + assert_eq!(*r1, val1); + b3.wait(); + }); + b1.wait(); + s.spawn(|_| { + let r2 = cell.get_or_init(|| { + b2.wait(); + b3.wait(); + Box::new(val2) + }); + assert_eq!(*r2, val1); + }); + }) + .unwrap(); + + assert_eq!(cell.get(), Some(&val1)); + } + + #[test] + fn once_box_reentrant() { + let cell = OnceBox::new(); + let res = cell.get_or_init(|| { + cell.get_or_init(|| Box::new("hello".to_string())); + Box::new("world".to_string()) + }); + assert_eq!(res, "hello"); + } + + #[test] + fn once_box_default() { + struct Foo; + + let cell: OnceBox = Default::default(); + assert!(cell.get().is_none()); + } +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/.cargo-checksum.json b/utshell-0.5.0/vendor/pin-project-lite/.cargo-checksum.json new file mode 100644 index 00000000..f13fc41a --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"8746b4b5d094fb8998c411987f4145ece4b11107d1eab24fce3f8075f1d3dbb5","Cargo.toml":"39e8ac3108dc0099ea98f012927dba1eb4b93220f23e3366896bb2fa2f66870d","LICENSE-APACHE":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"84c64307110253c7348fb56e22ff36460b4b0c797fc931dbb748bef6921a8009","src/lib.rs":"94c2eb6f58fea1ecba2ada4c8e6d7a62f9ee54e0844200c5d6609549c896e8b5","tests/auxiliary/mod.rs":"7e263e987e09b77e384f734384a00a71c5b70230bb1b5376446ef003a8da9372","tests/compiletest.rs":"af34ced23541134e26259a52cae588520c7111e98bff59e0c2e2d73faf43ca3f","tests/drop_order.rs":"2cb31a8cd5cf4d9a4ba9faf25f99f0e85f9bd7b4778649f843d9c617c6af43fc","tests/expand/default/enum.expanded.rs":"7944e0ff3a49ef1bccff5681a32a0b306c5eaa7a5f4838132eca8e9a62d40722","tests/expand/default/enum.rs":"493d5752c4baa87ed4c48bd41b8e5e263fd5e3f43c4f9195818ef6d26951f63e","tests/expand/default/struct.expanded.rs":"c0a2a411462f2570340e095963c277da229f7b7dcbe661512ac5f051478d5905","tests/expand/default/struct.rs":"5a6e57d9b6d00cfd4e1e69f37ce0c9d5165a21230d0363f0791665b1015870ce","tests/expand/multifields/enum.expanded.rs":"fc3a86d536060cbd1aa58a2e565d00033f677c0e02f1dd1ee6e30e8379b152fe","tests/expand/multifields/enum.rs":"9c79270a7d6d1d42cf8194b579d79e7d44a3fd003243742f0a568ecf0a4f3be3","tests/expand/multifields/struct.expanded.rs":"cf2dd15e6a0a66afcb8c5d7fef235964a4326c91732de65597f880285fdffe2a","tests/expand/multifields/struct.rs":"17f0447d522d48f14d516808bd66baacebdf3ac38188df72f649702a893cda68","tests/expand/naming/enum-all.expanded.rs":"7944e0ff3a49ef1bccff5681a32a0b306c5eaa7a5f4838132eca8e9a62d40722","tests/expand/naming/enum-all.rs":"493d5752c4baa87ed4c48bd41b8e5e263fd5e3f43c4f9195818ef6d26951f63e","tests/expand/naming/enum-mut.expanded.rs":"49bd8b7e0a469823e1e7d4dbfcb7108ef5db16844ef7d4686cb6600768123877","tests/expand/naming/enum-mut.rs":"c1ff4ade049ebbceb2acb99dbc1af5db14de3ba9710ea1ff1b64348766a9e080","tests/expand/naming/enum-none.expanded.rs":"dbac25a5370153bad9165346c49f831d051b22f0c40bc4d81aa1dd44346d04cc","tests/expand/naming/enum-none.rs":"ff22be4ecf4168e2bc68ab249a0ed809a37e3b8e840ef8977d24209ef28ac839","tests/expand/naming/enum-ref.expanded.rs":"ec4dedf4618e6b9dc4e98a2846b769dc5c9ad9eb51cb645ebfcca09c9ec9458f","tests/expand/naming/enum-ref.rs":"394cbd5d872449e9226cd0834ce7117c395a582567584218dabbef4eb2c1fbac","tests/expand/naming/struct-all.expanded.rs":"1573eb22f4f68b2d2621a5b3d4bda0edfd38ef16efc7f29d9697fc5564a9f615","tests/expand/naming/struct-all.rs":"c13c0aacee85b8fca58f85d2d75d2e3907b3e7642f8710ed8c8e54d6015881cc","tests/expand/naming/struct-mut.expanded.rs":"6e52a2d4c9fe105307d2cf07882897027713ebcac94249aab7ba0a1ffc2f2f77","tests/expand/naming/struct-mut.rs":"9a7752a6d30e0b7033f3577a72676676900a642cdaf59f942179d1f2a8ba2bb0","tests/expand/naming/struct-none.expanded.rs":"c0a2a411462f2570340e095963c277da229f7b7dcbe661512ac5f051478d5905","tests/expand/naming/struct-none.rs":"5a6e57d9b6d00cfd4e1e69f37ce0c9d5165a21230d0363f0791665b1015870ce","tests/expand/naming/struct-ref.expanded.rs":"b8744cb83e6764c4c9718c4ad6898ce2c80420730456579ce250e1839bad6027","tests/expand/naming/struct-ref.rs":"33c4fd344b65650dee44087ada31d4b5acd9d122123360fb7d41718c46699574","tests/expand/not_unpin/enum.expanded.rs":"c71d04b6c6ed0c334724b395e44679111703adaf19f3d697f5bfce58f8313cfc","tests/expand/not_unpin/enum.rs":"b626f3390a6afa36ec3505bdb61457e8eb2a6eee58dc8ab5a85c9e1a10699b20","tests/expand/not_unpin/struct.expanded.rs":"e3bb42319076fa8ecfec3e47356bb5afc95da5454467a2b0b471f76ced0f284f","tests/expand/not_unpin/struct.rs":"84af744f600ef0c0276a64a07d427b28e0b649fb634fa9880a9fd8cd475517c9","tests/expand/pinned_drop/enum.expanded.rs":"9b7d9d0c16045400c93de9a47f39aae3859d922f81432f76f96e7dd81f27cdb8","tests/expand/pinned_drop/enum.rs":"3178d479b9b42dc74c5a2207f70c9959070672c03009021e335c34290ef620ba","tests/expand/pinned_drop/struct.expanded.rs":"e802ab01b59f09d6397f9235eab51e07859b2582465a39f5621fa4d33e270fd3","tests/expand/pinned_drop/struct.rs":"cf6a7b04451c59ce697c3ef15855c7740b0e72a6005b1f47db326bd93b1849c3","tests/expand/pub/enum.expanded.rs":"ddc80984cc8cfd30a27c385c3e53ae7c178d774a717040d0e791e81adc7004fe","tests/expand/pub/enum.rs":"5b60dd354a489b0326f5c4f1026b89d1471ddbb45906bc3046a65425c4e5e160","tests/expand/pub/struct.expanded.rs":"435a2322ab580327bfecd40b309b3f2079667ed627bc25bdb41ee03dae0596bb","tests/expand/pub/struct.rs":"15b7940ce0ad1d5d133dde1870319f2f96a000bfcf29508b8cce1a62876cbd80","tests/expandtest.rs":"66bd80992a1696994ec2d14c3edc36350a0cb896d8081f1c0f8893ebeed72d03","tests/include/basic.rs":"9e399b682bc74c899d26924c2cab52a911f7392e29300defb6521e561fafafe4","tests/lint.rs":"36005c64524a2ed4f738d22d5310539e063e75833e8ab1b81afa6c9d1ba14bf6","tests/proper_unpin.rs":"35894ab482a5409aa32b261ff729c0ce23230232ecf43b3227a401fd218828e1","tests/test.rs":"b5c1bde0fa45513b6a0f0f2126e70aa41a8f5aba2bdf55bfb2b8b6b415c0e98b","tests/ui/pin_project/conflict-drop.rs":"55e6809b5f59dd81e32c2c89b742c0c76db6b099a1d2621e5b882c0d20f92837","tests/ui/pin_project/conflict-drop.stderr":"7cadbfe2b8e9659c69e8d61d45128d3589444f563e1f179d6d4c9bd1d98e96e1","tests/ui/pin_project/conflict-unpin.rs":"eae4f6b2084e32001a5a965b4a9ebf76a3a628830ca5f93bf4799eea96accbf9","tests/ui/pin_project/conflict-unpin.stderr":"c5bc8f97a5917548eb66e6099adf9371416a02ffc4feb2e20432c60782cd6ba2","tests/ui/pin_project/invalid-bounds.rs":"f86f23d377df015182f2f5dae6464a4f98c37f2198e0646f721fedc4017cb82c","tests/ui/pin_project/invalid-bounds.stderr":"200e6fab99f8ebd75116294ba9c43ae9487563239f2d57462157f5cc47c37cc3","tests/ui/pin_project/invalid.rs":"7304bd4a5bac1419382742432cfa8af83535d7be8cfad52c661410e0e9e8207a","tests/ui/pin_project/invalid.stderr":"6e8693c3341972e329e7c7a1836f308c433e0ba677fc99808d75a53e695654b1","tests/ui/pin_project/overlapping_lifetime_names.rs":"36c849a4570c8c0c32ca6c01aa75afbe1136ef73d45f17eb66175e1936678722","tests/ui/pin_project/overlapping_lifetime_names.stderr":"6958a5c0c983f3ed782203d8f221e80e154b71cb4fe2a9fb633058ec636c4cbc","tests/ui/pin_project/overlapping_unpin_struct.rs":"9a126182d1fe15a30ac60bb223b376aad747d11293d3cf512ad2dce546e3725c","tests/ui/pin_project/overlapping_unpin_struct.stderr":"406feb5169cd79293853b76a5cc599e692d2af3b5169fca32cb5cf1cb2ad0fc0","tests/ui/pin_project/packed.rs":"1f1a34aafbff9a59b94cdf3a53df03e9fc661d9e27e0f9962bad7f9bdad03b14","tests/ui/pin_project/packed.stderr":"5c5f08d339d4e5e2596f1f8a64158d8c2df2ea7116c04a578004f30f48ca7b0a","tests/ui/pin_project/unpin_sneaky.rs":"12e97a387ce1af6ee6a567687674aab70e96962a48f2433c39976d0b3e2c3341","tests/ui/pin_project/unpin_sneaky.stderr":"7a540e26a0e9c66794bcc10cbc337b3459a9208d32b0012f0b55fb84cfc15cf1","tests/ui/pin_project/unsupported.rs":"14defa90e736f314bbbc219973929b77bdd22e5f7e4c4c88403db764f4d167d6","tests/ui/pin_project/unsupported.stderr":"7b161bda371caeb26df426fde4dadcff61a807ffd476b2344c6b77072d6c0cc0","tests/ui/pinned_drop/call-drop-inner.rs":"032260da1fc0e649d97167a8a4ac47eea915000efebdfdc490f050b6f9351027","tests/ui/pinned_drop/call-drop-inner.stderr":"abec9d82aeb49c860e313db0a3ad0d2024d7500750d4f9a0f8b0ce00478dbcbf","tests/ui/pinned_drop/conditional-drop-impl.rs":"0b28c74213cee83e7b27223d7d37f903f79abd3dddcc0f969e14047674908085","tests/ui/pinned_drop/conditional-drop-impl.stderr":"a845afaa89054f7c516029090a201f3beecf59d6e9e4fca18ca3678d27666a92"},"package":"8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/pin-project-lite/CHANGELOG.md b/utshell-0.5.0/vendor/pin-project-lite/CHANGELOG.md new file mode 100644 index 00000000..dc463fcd --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/CHANGELOG.md @@ -0,0 +1,242 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](https://semver.org). + + + +## [Unreleased] + +## [0.2.13] - 2023-08-25 + +- Allow attributes in impl and method of `PinnedDrop` implementation. + +## [0.2.12] - 2023-08-09 + +- Work around an issue where the projected types/methods appear in the documentation as if they were part of the public API if the visibility is not correctly parsed due to the rustc bug. See [#77](https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180) for details. + +## [0.2.11] - 2023-08-06 + +- Add support for `#[project(!Unpin)]`. This is equivalent to pin-project's [!Unpin](https://docs.rs/pin-project/latest/pin_project/attr.pin_project.html#unpin) option. ([#76](https://github.com/taiki-e/pin-project-lite/pull/76), thanks @matheus-consoli) + +## [0.2.10] - 2023-07-02 + +- Inline project methods. ([#74](https://github.com/taiki-e/pin-project-lite/pull/74), thanks @EFanZh) + +## [0.2.9] - 2022-04-26 + +- Improve compile time of `pin_project!` calls. ([#71](https://github.com/taiki-e/pin-project-lite/pull/71), thanks @nnethercote) + +## [0.2.8] - 2021-12-31 + +- Fix handling of trailing commas in `PinnedDrop` impl. ([#64](https://github.com/taiki-e/pin-project-lite/pull/64), thanks @Michael-J-Ward) + +## [0.2.7] - 2021-06-26 + +- [Support custom Drop implementation.](https://github.com/taiki-e/pin-project-lite/pull/25) See [#25](https://github.com/taiki-e/pin-project-lite/pull/25) for details. + +## [0.2.6] - 2021-03-04 + +- Support item attributes in any order. ([#57](https://github.com/taiki-e/pin-project-lite/pull/57), thanks @SabrinaJewson) + +## [0.2.5] - 2021-03-02 + +- [Prepare for removal of `safe_packed_borrows` lint.](https://github.com/taiki-e/pin-project-lite/pull/55) See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +## [0.2.4] - 2021-01-11 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- Add `project_replace`. ([#43](https://github.com/taiki-e/pin-project-lite/pull/43), thanks @Marwes) + +## [0.2.3] - 2021-01-09 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Suppress `clippy::unknown_clippy_lints` lint in generated code.](https://github.com/taiki-e/pin-project-lite/pull/47) + +## [0.2.2] - 2021-01-09 + +**Note:** This release has been yanked.** See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Suppress `clippy::ref_option_ref` lint in generated code.](https://github.com/taiki-e/pin-project-lite/pull/45) + +## [0.2.1] - 2021-01-05 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- Exclude unneeded files from crates.io. + +## [0.2.0] - 2020-11-13 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [`pin_project!` macro now supports enums.](https://github.com/taiki-e/pin-project-lite/pull/28) + + To use `pin_project!` on enums, you need to name the projection type returned from the method. + + ```rust + use pin_project_lite::pin_project; + use std::pin::Pin; + + pin_project! { + #[project = EnumProj] + enum Enum { + Variant { #[pin] pinned: T, unpinned: U }, + } + } + + impl Enum { + fn method(self: Pin<&mut Self>) { + match self.project() { + EnumProj::Variant { pinned, unpinned } => { + let _: Pin<&mut T> = pinned; + let _: &mut U = unpinned; + } + } + } + } + ``` + +- [Support naming the projection types.](https://github.com/taiki-e/pin-project-lite/pull/28) + + By passing an attribute with the same name as the method, you can name the projection type returned from the method: + + ```rust + use pin_project_lite::pin_project; + use std::pin::Pin; + + pin_project! { + #[project = StructProj] + struct Struct { + #[pin] + field: T, + } + } + + fn func(x: Pin<&mut Struct>) { + let StructProj { field } = x.project(); + let _: Pin<&mut T> = field; + } + ``` + +## [0.1.12] - 2021-03-02 + +- [Prepare for removal of `safe_packed_borrows` lint.](https://github.com/taiki-e/pin-project-lite/pull/55) See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +## [0.1.11] - 2020-10-20 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- Suppress `clippy::redundant_pub_crate` lint in generated code. + +- Documentation improvements. + +## [0.1.10] - 2020-10-01 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- Suppress `drop_bounds` lint, which will be added to rustc in the future. See [taiki-e/pin-project#272](https://github.com/taiki-e/pin-project/issues/272) for more details. + +## [0.1.9] - 2020-09-29 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Fix trailing comma support in generics.](https://github.com/taiki-e/pin-project-lite/pull/32) + +## [0.1.8] - 2020-09-26 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Fix compatibility of generated code with `forbid(future_incompatible)`.](https://github.com/taiki-e/pin-project-lite/pull/30) + + Note: This does not guarantee compatibility with `forbid(future_incompatible)` in the future. + If rustc adds a new lint, we may not be able to keep this. + +## [0.1.7] - 2020-06-04 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Support `?Sized` bounds in where clauses.](https://github.com/taiki-e/pin-project-lite/pull/22) + +- [Fix lifetime inference error when an associated type is used in fields.](https://github.com/taiki-e/pin-project-lite/pull/20) + +- Suppress `clippy::used_underscore_binding` lint in generated code. + +- Documentation improvements. + +## [0.1.6] - 2020-05-31 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Support lifetime bounds in where clauses.](https://github.com/taiki-e/pin-project-lite/pull/18) + +- Documentation improvements. + +## [0.1.5] - 2020-05-07 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Support overwriting the name of `core` crate.](https://github.com/taiki-e/pin-project-lite/pull/14) + +## [0.1.4] - 2020-01-20 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Support ?Sized bounds in generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/9) + +## [0.1.3] - 2020-01-20 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [Support lifetime bounds in generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/7) + +## [0.1.2] - 2020-01-05 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- Support recognizing default generic parameters. ([#6](https://github.com/taiki-e/pin-project-lite/pull/6), thanks @kennytm) + +## [0.1.1] - 2019-11-15 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +- [`pin_project!` macro now determines the visibility of the projection type/method is based on the original type.](https://github.com/taiki-e/pin-project-lite/pull/5) + +## [0.1.0] - 2019-10-22 + +**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details. + +Initial release + +[Unreleased]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.13...HEAD +[0.2.13]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.12...v0.2.13 +[0.2.12]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.11...v0.2.12 +[0.2.11]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.10...v0.2.11 +[0.2.10]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.9...v0.2.10 +[0.2.9]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.8...v0.2.9 +[0.2.8]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.7...v0.2.8 +[0.2.7]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.6...v0.2.7 +[0.2.6]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.5...v0.2.6 +[0.2.5]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.4...v0.2.5 +[0.2.4]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.3...v0.2.4 +[0.2.3]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.2...v0.2.3 +[0.2.2]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.1...v0.2.2 +[0.2.1]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.11...v0.2.0 +[0.1.12]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.11...v0.1.12 +[0.1.11]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.10...v0.1.11 +[0.1.10]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.9...v0.1.10 +[0.1.9]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.8...v0.1.9 +[0.1.8]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.7...v0.1.8 +[0.1.7]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.6...v0.1.7 +[0.1.6]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.5...v0.1.6 +[0.1.5]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.4...v0.1.5 +[0.1.4]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.3...v0.1.4 +[0.1.3]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.2...v0.1.3 +[0.1.2]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.1...v0.1.2 +[0.1.1]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.0...v0.1.1 +[0.1.0]: https://github.com/taiki-e/pin-project-lite/releases/tag/v0.1.0 diff --git a/utshell-0.5.0/vendor/pin-project-lite/Cargo.toml b/utshell-0.5.0/vendor/pin-project-lite/Cargo.toml new file mode 100644 index 00000000..ae3d4fbb --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/Cargo.toml @@ -0,0 +1,69 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.37" +name = "pin-project-lite" +version = "0.2.13" +exclude = [ + "/.*", + "/tools", + "/DEVELOPMENT.md", +] +description = """ +A lightweight version of pin-project written with declarative macros. +""" +readme = "README.md" +keywords = [ + "pin", + "macros", +] +categories = [ + "no-std", + "no-std::no-alloc", + "rust-patterns", +] +license = "Apache-2.0 OR MIT" +repository = "https://github.com/taiki-e/pin-project-lite" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +doc-scrape-examples = false + +[dev-dependencies.macrotest] +version = "1.0.9" + +[dev-dependencies.once_cell] +version = "=1.14" + +[dev-dependencies.proc-macro2] +version = "=1.0.65" + +[dev-dependencies.quote] +version = "=1.0.30" + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.serde] +version = "=1.0.156" + +[dev-dependencies.static_assertions] +version = "1" + +[dev-dependencies.toml] +version = "=0.5.9" + +[dev-dependencies.trybuild] +version = "=1.0.67" diff --git a/utshell-0.5.0/vendor/pin-project-lite/LICENSE-APACHE b/utshell-0.5.0/vendor/pin-project-lite/LICENSE-APACHE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/LICENSE-APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/utshell-0.5.0/vendor/pin-project-lite/LICENSE-MIT b/utshell-0.5.0/vendor/pin-project-lite/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/pin-project-lite/README.md b/utshell-0.5.0/vendor/pin-project-lite/README.md new file mode 100644 index 00000000..40b909ad --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/README.md @@ -0,0 +1,130 @@ +# pin-project-lite + +[![crates.io](https://img.shields.io/crates/v/pin-project-lite?style=flat-square&logo=rust)](https://crates.io/crates/pin-project-lite) +[![docs.rs](https://img.shields.io/badge/docs.rs-pin--project--lite-blue?style=flat-square&logo=docs.rs)](https://docs.rs/pin-project-lite) +[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license) +[![rustc](https://img.shields.io/badge/rustc-1.37+-blue?style=flat-square&logo=rust)](https://www.rust-lang.org) +[![build status](https://img.shields.io/github/actions/workflow/status/taiki-e/pin-project-lite/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/pin-project-lite/actions) + + +A lightweight version of [pin-project] written with declarative macros. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +pin-project-lite = "0.2" +``` + +*Compiler support: requires rustc 1.37+* + +## Examples + +[`pin_project!`] macro creates a projection type covering all the fields of +struct. + +```rust +use std::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +impl Struct { + fn method(self: Pin<&mut Self>) { + let this = self.project(); + let _: Pin<&mut T> = this.pinned; // Pinned reference to the field + let _: &mut U = this.unpinned; // Normal reference to the field + } +} +``` + +To use [`pin_project!`] on enums, you need to name the projection type +returned from the method. + +```rust +use std::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + enum Enum { + Variant { #[pin] pinned: T, unpinned: U }, + } +} + +impl Enum { + fn method(self: Pin<&mut Self>) { + match self.project() { + EnumProj::Variant { pinned, unpinned } => { + let _: Pin<&mut T> = pinned; + let _: &mut U = unpinned; + } + } + } +} +``` + +## [pin-project] vs pin-project-lite + +Here are some similarities and differences compared to [pin-project]. + +### Similar: Safety + +pin-project-lite guarantees safety in much the same way as [pin-project]. +Both are completely safe unless you write other unsafe code. + +### Different: Minimal design + +This library does not tackle as expansive of a range of use cases as +[pin-project] does. If your use case is not already covered, please use +[pin-project]. + +### Different: No proc-macro related dependencies + +This is the **only** reason to use this crate. However, **if you already +have proc-macro related dependencies in your crate's dependency graph, there +is no benefit from using this crate.** (Note: There is almost no difference +in the amount of code generated between [pin-project] and pin-project-lite.) + +### Different: No useful error messages + +This macro does not handle any invalid input. So error messages are not to +be useful in most cases. If you do need useful error messages, then upon +error you can pass the same input to [pin-project] to receive a helpful +description of the compile error. + +### Different: No support for custom Unpin implementation + +pin-project supports this by [`UnsafeUnpin`][unsafe-unpin]. (`!Unpin` is supported by both [pin-project][not-unpin] and [pin-project-lite][not-unpin-lite].) + +### Different: No support for tuple structs and tuple variants + +pin-project supports this. + +[not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin +[not-unpin-lite]: https://docs.rs/pin-project-lite/0.2/pin_project_lite/macro.pin_project.html#unpin +[pin-project]: https://github.com/taiki-e/pin-project +[unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin + + + +[`pin_project!`]: https://docs.rs/pin-project-lite/0.2/pin_project_lite/macro.pin_project.html + +## License + +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or +[MIT license](LICENSE-MIT) at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/pin-project-lite/src/lib.rs b/utshell-0.5.0/vendor/pin-project-lite/src/lib.rs new file mode 100644 index 00000000..6ec2021e --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/src/lib.rs @@ -0,0 +1,1682 @@ +/*! + +A lightweight version of [pin-project] written with declarative macros. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +pin-project-lite = "0.2" +``` + +*Compiler support: requires rustc 1.37+* + +## Examples + +[`pin_project!`] macro creates a projection type covering all the fields of +struct. + +```rust +use std::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +impl Struct { + fn method(self: Pin<&mut Self>) { + let this = self.project(); + let _: Pin<&mut T> = this.pinned; // Pinned reference to the field + let _: &mut U = this.unpinned; // Normal reference to the field + } +} +``` + +To use [`pin_project!`] on enums, you need to name the projection type +returned from the method. + +```rust +use std::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + enum Enum { + Variant { #[pin] pinned: T, unpinned: U }, + } +} + +impl Enum { + fn method(self: Pin<&mut Self>) { + match self.project() { + EnumProj::Variant { pinned, unpinned } => { + let _: Pin<&mut T> = pinned; + let _: &mut U = unpinned; + } + } + } +} +``` + +## [pin-project] vs pin-project-lite + +Here are some similarities and differences compared to [pin-project]. + +### Similar: Safety + +pin-project-lite guarantees safety in much the same way as [pin-project]. +Both are completely safe unless you write other unsafe code. + +### Different: Minimal design + +This library does not tackle as expansive of a range of use cases as +[pin-project] does. If your use case is not already covered, please use +[pin-project]. + +### Different: No proc-macro related dependencies + +This is the **only** reason to use this crate. However, **if you already +have proc-macro related dependencies in your crate's dependency graph, there +is no benefit from using this crate.** (Note: There is almost no difference +in the amount of code generated between [pin-project] and pin-project-lite.) + +### Different: No useful error messages + +This macro does not handle any invalid input. So error messages are not to +be useful in most cases. If you do need useful error messages, then upon +error you can pass the same input to [pin-project] to receive a helpful +description of the compile error. + +### Different: No support for custom Unpin implementation + +pin-project supports this by [`UnsafeUnpin`][unsafe-unpin]. (`!Unpin` is supported by both [pin-project][not-unpin] and [pin-project-lite][not-unpin-lite].) + +### Different: No support for tuple structs and tuple variants + +pin-project supports this. + +[not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin +[not-unpin-lite]: https://docs.rs/pin-project-lite/0.2/pin_project_lite/macro.pin_project.html#unpin +[pin-project]: https://github.com/taiki-e/pin-project +[unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin + + +*/ + +#![no_std] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_variables) + ) +))] +#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)] +#![warn( + clippy::pedantic, + // lints for public library + clippy::alloc_instead_of_core, + clippy::exhaustive_enums, + clippy::exhaustive_structs, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + // lints that help writing unsafe code + clippy::as_ptr_cast_mut, + clippy::default_union_representation, + clippy::trailing_empty_array, + clippy::transmute_undefined_repr, + clippy::undocumented_unsafe_blocks, +)] + +/// A macro that creates a projection type covering all the fields of struct. +/// +/// This macro creates a projection type according to the following rules: +/// +/// - For the field that uses `#[pin]` attribute, makes the pinned reference to the field. +/// - For the other fields, makes the unpinned reference to the field. +/// +/// And the following methods are implemented on the original type: +/// +/// ```rust +/// # use std::pin::Pin; +/// # type Projection<'a> = &'a (); +/// # type ProjectionRef<'a> = &'a (); +/// # trait Dox { +/// fn project(self: Pin<&mut Self>) -> Projection<'_>; +/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>; +/// # } +/// ``` +/// +/// By passing an attribute with the same name as the method to the macro, +/// you can name the projection type returned from the method. This allows you +/// to use pattern matching on the projected types. +/// +/// ```rust +/// # use pin_project_lite::pin_project; +/// # use std::pin::Pin; +/// pin_project! { +/// #[project = EnumProj] +/// enum Enum { +/// Variant { #[pin] field: T }, +/// } +/// } +/// +/// impl Enum { +/// fn method(self: Pin<&mut Self>) { +/// let this: EnumProj<'_, T> = self.project(); +/// match this { +/// EnumProj::Variant { field } => { +/// let _: Pin<&mut T> = field; +/// } +/// } +/// } +/// } +/// ``` +/// +/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional +/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving +/// out all unpinned fields in `Self`. +/// +/// ```rust +/// # use std::pin::Pin; +/// # type MyProjReplace = (); +/// # trait Dox { +/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace; +/// # } +/// ``` +/// +/// Also, note that the projection types returned by `project` and `project_ref` have +/// an additional lifetime at the beginning of generics. +/// +/// ```text +/// let this: EnumProj<'_, T> = self.project(); +/// ^^ +/// ``` +/// +/// The visibility of the projected types and projection methods is based on the +/// original type. However, if the visibility of the original type is `pub`, the +/// visibility of the projected types and the projection methods is downgraded +/// to `pub(crate)`. +/// +/// # Safety +/// +/// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate. +/// Both are completely safe unless you write other unsafe code. +/// +/// See [pin-project] crate for more details. +/// +/// # Examples +/// +/// ```rust +/// use std::pin::Pin; +/// +/// use pin_project_lite::pin_project; +/// +/// pin_project! { +/// struct Struct { +/// #[pin] +/// pinned: T, +/// unpinned: U, +/// } +/// } +/// +/// impl Struct { +/// fn method(self: Pin<&mut Self>) { +/// let this = self.project(); +/// let _: Pin<&mut T> = this.pinned; // Pinned reference to the field +/// let _: &mut U = this.unpinned; // Normal reference to the field +/// } +/// } +/// ``` +/// +/// To use `pin_project!` on enums, you need to name the projection type +/// returned from the method. +/// +/// ```rust +/// use std::pin::Pin; +/// +/// use pin_project_lite::pin_project; +/// +/// pin_project! { +/// #[project = EnumProj] +/// enum Enum { +/// Struct { +/// #[pin] +/// field: T, +/// }, +/// Unit, +/// } +/// } +/// +/// impl Enum { +/// fn method(self: Pin<&mut Self>) { +/// match self.project() { +/// EnumProj::Struct { field } => { +/// let _: Pin<&mut T> = field; +/// } +/// EnumProj::Unit => {} +/// } +/// } +/// } +/// ``` +/// +/// If you want to call the `project()` method multiple times or later use the +/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid +/// consuming the [`Pin`]. +/// +/// ```rust +/// use std::pin::Pin; +/// +/// use pin_project_lite::pin_project; +/// +/// pin_project! { +/// struct Struct { +/// #[pin] +/// field: T, +/// } +/// } +/// +/// impl Struct { +/// fn call_project_twice(mut self: Pin<&mut Self>) { +/// // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`. +/// self.as_mut().project(); +/// self.as_mut().project(); +/// } +/// } +/// ``` +/// +/// # `!Unpin` +/// +/// If you want to make sure `Unpin` is not implemented, use the `#[project(!Unpin)]` +/// attribute. +/// +/// ``` +/// use pin_project_lite::pin_project; +/// +/// pin_project! { +/// #[project(!Unpin)] +/// struct Struct { +/// #[pin] +/// field: T, +/// } +/// } +/// ``` +/// +/// This is equivalent to using `#[pin]` attribute for a [`PhantomPinned`] field. +/// +/// ```rust +/// use std::marker::PhantomPinned; +/// +/// use pin_project_lite::pin_project; +/// +/// pin_project! { +/// struct Struct { +/// field: T, +/// #[pin] +/// _pin: PhantomPinned, +/// } +/// } +/// ``` +/// +/// Note that using [`PhantomPinned`] without `#[pin]` or `#[project(!Unpin)]` +/// attribute has no effect. +/// +/// [`PhantomPinned`]: core::marker::PhantomPinned +/// [`Pin::as_mut`]: core::pin::Pin::as_mut +/// [`Pin`]: core::pin::Pin +/// [pin-project]: https://github.com/taiki-e/pin-project +#[macro_export] +macro_rules! pin_project { + ($($tt:tt)*) => { + $crate::__pin_project_internal! { + [][][][][] + $($tt)* + } + }; +} + +// limitations: +// - no support for tuple structs and tuple variant (wontfix). +// - no support for multiple trait/lifetime bounds. +// - no support for `Self` in where clauses. (wontfix) +// - no support for overlapping lifetime names. (wontfix) +// - no interoperability with other field attributes. +// - no useful error messages. (wontfix) +// etc... + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_expand { + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [$($proj_not_unpin_mark:ident)?] + [$proj_vis:vis] + [$(#[$attrs:meta])* $vis:vis $struct_ty_ident:ident $ident:ident] + [$($def_generics:tt)*] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $($body_data:tt)* + } + $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)? + ) => { + $crate::__pin_project_reconstruct! { + [$(#[$attrs])* $vis $struct_ty_ident $ident] + [$($def_generics)*] [$($impl_generics)*] + [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $($body_data)* + } + } + + $crate::__pin_project_make_proj_ty! { + [$($proj_mut_ident)?] + [$proj_vis $struct_ty_ident $ident] + [__pin_project_make_proj_field_mut] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $($body_data)* + } + } + $crate::__pin_project_make_proj_ty! { + [$($proj_ref_ident)?] + [$proj_vis $struct_ty_ident $ident] + [__pin_project_make_proj_field_ref] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $($body_data)* + } + } + $crate::__pin_project_make_proj_replace_ty! { + [$($proj_replace_ident)?] + [$proj_vis $struct_ty_ident] + [__pin_project_make_proj_field_replace] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $($body_data)* + } + } + + $crate::__pin_project_constant! { + [$(#[$attrs])* $vis $struct_ty_ident $ident] + [$($proj_mut_ident)?] [$($proj_ref_ident)?] [$($proj_replace_ident)?] + [$($proj_not_unpin_mark)?] + [$proj_vis] + [$($def_generics)*] [$($impl_generics)*] + [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $($body_data)* + } + $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)? + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_constant { + ( + [$(#[$attrs:meta])* $vis:vis struct $ident:ident] + [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?] + [$($proj_not_unpin_mark:ident)?] + [$proj_vis:vis] + [$($def_generics:tt)*] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident: $field_ty:ty + ),+ $(,)? + } + $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)? + ) => { + #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993 + #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 + // This lint warns of `clippy::*` generated by external macros. + // We allow this lint for compatibility with older compilers. + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct. + #[allow(clippy::used_underscore_binding)] + const _: () = { + $crate::__pin_project_make_proj_ty! { + [$($proj_mut_ident)? Projection] + [$proj_vis struct $ident] + [__pin_project_make_proj_field_mut] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $( + $(#[$pin])? + $field_vis $field: $field_ty + ),+ + } + } + $crate::__pin_project_make_proj_ty! { + [$($proj_ref_ident)? ProjectionRef] + [$proj_vis struct $ident] + [__pin_project_make_proj_field_ref] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + { + $( + $(#[$pin])? + $field_vis $field: $field_ty + ),+ + } + } + + impl <$($impl_generics)*> $ident <$($ty_generics)*> + $(where + $($where_clause)*)? + { + $crate::__pin_project_struct_make_proj_method! { + [$($proj_mut_ident)? Projection] + [$proj_vis] + [project get_unchecked_mut mut] + [$($ty_generics)*] + { + $( + $(#[$pin])? + $field_vis $field + ),+ + } + } + $crate::__pin_project_struct_make_proj_method! { + [$($proj_ref_ident)? ProjectionRef] + [$proj_vis] + [project_ref get_ref] + [$($ty_generics)*] + { + $( + $(#[$pin])? + $field_vis $field + ),+ + } + } + $crate::__pin_project_struct_make_proj_replace_method! { + [$($proj_replace_ident)?] + [$proj_vis] + [ProjectionReplace] + [$($ty_generics)*] + { + $( + $(#[$pin])? + $field_vis $field + ),+ + } + } + } + + $crate::__pin_project_make_unpin_impl! { + [$($proj_not_unpin_mark)?] + [$vis $ident] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + $( + $field: $crate::__pin_project_make_unpin_bound!( + $(#[$pin])? $field_ty + ) + ),+ + } + + $crate::__pin_project_make_drop_impl! { + [$ident] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)? + } + + // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct. + // + // Taking a reference to a packed field is UB, and applying + // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error. + // + // If the struct ends up having #[repr(packed)] applied somehow, + // this will generate an (unfriendly) error message. Under all reasonable + // circumstances, we'll detect the #[repr(packed)] attribute, and generate + // a much nicer error above. + // + // See https://github.com/taiki-e/pin-project/pull/34 for more details. + // + // Note: + // - Lint-based tricks aren't perfect, but they're much better than nothing: + // https://github.com/taiki-e/pin-project-lite/issues/26 + // + // - Enable both unaligned_references and safe_packed_borrows lints + // because unaligned_references lint does not exist in older compilers: + // https://github.com/taiki-e/pin-project-lite/pull/55 + // https://github.com/rust-lang/rust/pull/82525 + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>) + $(where + $($where_clause)*)? + { + $( + let _ = &this.$field; + )+ + } + }; + }; + ( + [$(#[$attrs:meta])* $vis:vis enum $ident:ident] + [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?] + [$($proj_not_unpin_mark:ident)?] + [$proj_vis:vis] + [$($def_generics:tt)*] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$variant_attrs:meta])* + $variant:ident $({ + $( + $(#[$pin:ident])? + $field:ident: $field_ty:ty + ),+ $(,)? + })? + ),+ $(,)? + } + $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)? + ) => { + #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 + // This lint warns of `clippy::*` generated by external macros. + // We allow this lint for compatibility with older compilers. + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::used_underscore_binding)] + const _: () = { + impl <$($impl_generics)*> $ident <$($ty_generics)*> + $(where + $($where_clause)*)? + { + $crate::__pin_project_enum_make_proj_method! { + [$($proj_mut_ident)?] + [$proj_vis] + [project get_unchecked_mut mut] + [$($ty_generics)*] + { + $( + $variant $({ + $( + $(#[$pin])? + $field + ),+ + })? + ),+ + } + } + $crate::__pin_project_enum_make_proj_method! { + [$($proj_ref_ident)?] + [$proj_vis] + [project_ref get_ref] + [$($ty_generics)*] + { + $( + $variant $({ + $( + $(#[$pin])? + $field + ),+ + })? + ),+ + } + } + $crate::__pin_project_enum_make_proj_replace_method! { + [$($proj_replace_ident)?] + [$proj_vis] + [$($ty_generics)*] + { + $( + $variant $({ + $( + $(#[$pin])? + $field + ),+ + })? + ),+ + } + } + } + + $crate::__pin_project_make_unpin_impl! { + [$($proj_not_unpin_mark)?] + [$vis $ident] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + $( + $variant: ($( + $( + $crate::__pin_project_make_unpin_bound!( + $(#[$pin])? $field_ty + ) + ),+ + )?) + ),+ + } + + $crate::__pin_project_make_drop_impl! { + [$ident] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)? + } + + // We don't need to check for '#[repr(packed)]', + // since it does not apply to enums. + }; + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_reconstruct { + ( + [$(#[$attrs:meta])* $vis:vis struct $ident:ident] + [$($def_generics:tt)*] [$($impl_generics:tt)*] + [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident: $field_ty:ty + ),+ $(,)? + } + ) => { + $(#[$attrs])* + $vis struct $ident $($def_generics)* + $(where + $($where_clause)*)? + { + $( + $field_vis $field: $field_ty + ),+ + } + }; + ( + [$(#[$attrs:meta])* $vis:vis enum $ident:ident] + [$($def_generics:tt)*] [$($impl_generics:tt)*] + [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$variant_attrs:meta])* + $variant:ident $({ + $( + $(#[$pin:ident])? + $field:ident: $field_ty:ty + ),+ $(,)? + })? + ),+ $(,)? + } + ) => { + $(#[$attrs])* + $vis enum $ident $($def_generics)* + $(where + $($where_clause)*)? + { + $( + $(#[$variant_attrs])* + $variant $({ + $( + $field: $field_ty + ),+ + })? + ),+ + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_ty { + ([] $($field:tt)*) => {}; + ( + [$proj_ty_ident:ident $default_ident:ident] + [$proj_vis:vis struct $ident:ident] + $($field:tt)* + ) => {}; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis struct $ident:ident] + [$__pin_project_make_proj_field:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident: $field_ty:ty + ),+ $(,)? + } + ) => { + $crate::__pin_project_make_proj_ty_body! { + [$proj_ty_ident] + [$proj_vis struct $ident] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + [ + $( + $field_vis $field: $crate::$__pin_project_make_proj_field!( + $(#[$pin])? $field_ty + ) + ),+ + ] + } + }; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis enum $ident:ident] + [$__pin_project_make_proj_field:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$variant_attrs:meta])* + $variant:ident $({ + $( + $(#[$pin:ident])? + $field:ident: $field_ty:ty + ),+ $(,)? + })? + ),+ $(,)? + } + ) => { + $crate::__pin_project_make_proj_ty_body! { + [$proj_ty_ident] + [$proj_vis enum $ident] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + [ + $( + $variant $({ + $( + $field: $crate::$__pin_project_make_proj_field!( + $(#[$pin])? $field_ty + ) + ),+ + })? + ),+ + ] + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_ty_body { + ( + [$proj_ty_ident:ident] + [$proj_vis:vis $struct_ty_ident:ident $ident:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + [$($body_data:tt)+] + ) => { + #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more. + #[allow(dead_code)] // This lint warns unused fields/variants. + #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 + // This lint warns of `clippy::*` generated by external macros. + // We allow this lint for compatibility with older compilers. + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] // This lint warns `&mut &mut `. (only needed for project) + #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct. + #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&>`. (only needed for project_ref) + #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326 + $proj_vis $struct_ty_ident $proj_ty_ident <'__pin, $($impl_generics)*> + where + $ident <$($ty_generics)*>: '__pin + $(, $($where_clause)*)? + { + $($body_data)+ + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_replace_ty { + ([] $($field:tt)*) => {}; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis struct] + [$__pin_project_make_proj_field:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident: $field_ty:ty + ),+ $(,)? + } + ) => { + $crate::__pin_project_make_proj_replace_ty_body! { + [$proj_ty_ident] + [$proj_vis struct] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + [ + $( + $field_vis $field: $crate::$__pin_project_make_proj_field!( + $(#[$pin])? $field_ty + ) + ),+ + ] + } + }; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis enum] + [$__pin_project_make_proj_field:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + { + $( + $(#[$variant_attrs:meta])* + $variant:ident $({ + $( + $(#[$pin:ident])? + $field:ident: $field_ty:ty + ),+ $(,)? + })? + ),+ $(,)? + } + ) => { + $crate::__pin_project_make_proj_replace_ty_body! { + [$proj_ty_ident] + [$proj_vis enum] + [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?] + [ + $( + $variant $({ + $( + $field: $crate::$__pin_project_make_proj_field!( + $(#[$pin])? $field_ty + ) + ),+ + })? + ),+ + ] + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_replace_ty_body { + ( + [$proj_ty_ident:ident] + [$proj_vis:vis $struct_ty_ident:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + [$($body_data:tt)+] + ) => { + #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more. + #[allow(dead_code)] // This lint warns unused fields/variants. + #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 + #[allow(clippy::mut_mut)] // This lint warns `&mut &mut `. (only needed for project) + #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct. + #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326 + $proj_vis $struct_ty_ident $proj_ty_ident <$($impl_generics)*> + where + $($($where_clause)*)? + { + $($body_data)+ + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_replace_block { + ( + [$($proj_path:tt)+] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident + ),+ + } + ) => { + let result = $($proj_path)* { + $( + $field: $crate::__pin_project_make_replace_field_proj!( + $(#[$pin])? $field + ) + ),+ + }; + + { + ( $( + $crate::__pin_project_make_unsafe_drop_in_place_guard!( + $(#[$pin])? $field + ), + )* ); + } + + result + }; + ([$($proj_path:tt)+]) => { $($proj_path)* }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_struct_make_proj_method { + ([] $($variant:tt)*) => {}; + ( + [$proj_ty_ident:ident $_ignored_default_arg:ident] + [$proj_vis:vis] + [$method_ident:ident $get_method:ident $($mut:ident)?] + [$($ty_generics:tt)*] + $($variant:tt)* + ) => { + $crate::__pin_project_struct_make_proj_method! { + [$proj_ty_ident] + [$proj_vis] + [$method_ident $get_method $($mut)?] + [$($ty_generics)*] + $($variant)* + } + }; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis] + [$method_ident:ident $get_method:ident $($mut:ident)?] + [$($ty_generics:tt)*] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident + ),+ + } + ) => { + #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more. + #[inline] + $proj_vis fn $method_ident<'__pin>( + self: $crate::__private::Pin<&'__pin $($mut)? Self>, + ) -> $proj_ty_ident <'__pin, $($ty_generics)*> { + unsafe { + let Self { $($field),* } = self.$get_method(); + $proj_ty_ident { + $( + $field: $crate::__pin_project_make_unsafe_field_proj!( + $(#[$pin])? $field + ) + ),+ + } + } + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_struct_make_proj_replace_method { + ([] $($field:tt)*) => {}; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis] + [$_proj_ty_ident:ident] + [$($ty_generics:tt)*] + { + $( + $(#[$pin:ident])? + $field_vis:vis $field:ident + ),+ + } + ) => { + #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more. + #[inline] + $proj_vis fn project_replace( + self: $crate::__private::Pin<&mut Self>, + replacement: Self, + ) -> $proj_ty_ident <$($ty_generics)*> { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + + // Destructors will run in reverse order, so next create a guard to overwrite + // `self` with the replacement value without calling destructors. + let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement); + + let Self { $($field),* } = &mut *__self_ptr; + + $crate::__pin_project_make_proj_replace_block! { + [$proj_ty_ident] + { + $( + $(#[$pin])? + $field + ),+ + } + } + } + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_enum_make_proj_method { + ([] $($variant:tt)*) => {}; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis] + [$method_ident:ident $get_method:ident $($mut:ident)?] + [$($ty_generics:tt)*] + { + $( + $variant:ident $({ + $( + $(#[$pin:ident])? + $field:ident + ),+ + })? + ),+ + } + ) => { + #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more. + #[inline] + $proj_vis fn $method_ident<'__pin>( + self: $crate::__private::Pin<&'__pin $($mut)? Self>, + ) -> $proj_ty_ident <'__pin, $($ty_generics)*> { + unsafe { + match self.$get_method() { + $( + Self::$variant $({ + $($field),+ + })? => { + $proj_ty_ident::$variant $({ + $( + $field: $crate::__pin_project_make_unsafe_field_proj!( + $(#[$pin])? $field + ) + ),+ + })? + } + ),+ + } + } + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_enum_make_proj_replace_method { + ([] $($field:tt)*) => {}; + ( + [$proj_ty_ident:ident] + [$proj_vis:vis] + [$($ty_generics:tt)*] + { + $( + $variant:ident $({ + $( + $(#[$pin:ident])? + $field:ident + ),+ + })? + ),+ + } + ) => { + #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more. + #[inline] + $proj_vis fn project_replace( + self: $crate::__private::Pin<&mut Self>, + replacement: Self, + ) -> $proj_ty_ident <$($ty_generics)*> { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + + // Destructors will run in reverse order, so next create a guard to overwrite + // `self` with the replacement value without calling destructors. + let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement); + + match &mut *__self_ptr { + $( + Self::$variant $({ + $($field),+ + })? => { + $crate::__pin_project_make_proj_replace_block! { + [$proj_ty_ident :: $variant] + $({ + $( + $(#[$pin])? + $field + ),+ + })? + } + } + ),+ + } + } + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_unpin_impl { + ( + [] + [$vis:vis $ident:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + $($field:tt)* + ) => { + // Automatically create the appropriate conditional `Unpin` implementation. + // + // Basically this is equivalent to the following code: + // ```rust + // impl Unpin for Struct where T: Unpin {} + // ``` + // + // However, if struct is public and there is a private type field, + // this would cause an E0446 (private type in public interface). + // + // When RFC 2145 is implemented (rust-lang/rust#48054), + // this will become a lint, rather then a hard error. + // + // As a workaround for this, we generate a new struct, containing all of the pinned + // fields from our #[pin_project] type. This struct is declared within + // a function, which makes it impossible to be named by user code. + // This guarantees that it will use the default auto-trait impl for Unpin - + // that is, it will implement Unpin iff all of its fields implement Unpin. + // This type can be safely declared as 'public', satisfying the privacy + // checker without actually allowing user code to access it. + // + // This allows users to apply the #[pin_project] attribute to types + // regardless of the privacy of the types of their fields. + // + // See also https://github.com/taiki-e/pin-project/pull/53. + #[allow(non_snake_case)] + $vis struct __Origin <'__pin, $($impl_generics)*> + $(where + $($where_clause)*)? + { + __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>, + $($field)* + } + impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*> + where + __Origin <'__pin, $($ty_generics)*>: $crate::__private::Unpin + $(, $($where_clause)*)? + { + } + }; + ( + [$proj_not_unpin_mark:ident] + [$vis:vis $ident:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + $($field:tt)* + ) => { + #[doc(hidden)] + impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*> + where + ( + ::core::marker::PhantomData<&'__pin ()>, + ::core::marker::PhantomPinned, + ): $crate::__private::Unpin + $(, $($where_clause)*)? + { + } + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_drop_impl { + ( + [$_ident:ident] + [$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?] + $(#[$drop_impl_attrs:meta])* + impl $(< + $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)? + $( $generics:ident + $(: $generics_bound:path)? + $(: ?$generics_unsized_bound:path)? + $(: $generics_lifetime_bound:lifetime)? + ),* + >)? PinnedDrop for $self_ty:ty + $(where + $( $where_clause_ty:ty + $(: $where_clause_bound:path)? + $(: ?$where_clause_unsized_bound:path)? + $(: $where_clause_lifetime_bound:lifetime)? + ),* $(,)? + )? + { + $(#[$drop_fn_attrs:meta])* + fn drop($($arg:ident)+: Pin<&mut Self>) { + $($tt:tt)* + } + } + ) => { + $(#[$drop_impl_attrs])* + impl $(< + $( $lifetime $(: $lifetime_bound)? ,)* + $( $generics + $(: $generics_bound)? + $(: ?$generics_unsized_bound)? + $(: $generics_lifetime_bound)? + ),* + >)? $crate::__private::Drop for $self_ty + $(where + $( $where_clause_ty + $(: $where_clause_bound)? + $(: ?$where_clause_unsized_bound)? + $(: $where_clause_lifetime_bound)? + ),* + )? + { + $(#[$drop_fn_attrs])* + fn drop(&mut self) { + // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe. + // This is because destructors can be called multiple times in safe code and + // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360). + // + // `__drop_inner` is defined as a safe method, but this is fine since + // `__drop_inner` is not accessible by the users and we call `__drop_inner` only + // once. + // + // Users can implement [`Drop`] safely using `pin_project!` and can drop a + // type that implements `PinnedDrop` using the [`drop`] function safely. + fn __drop_inner $(< + $( $lifetime $(: $lifetime_bound)? ,)* + $( $generics + $(: $generics_bound)? + $(: ?$generics_unsized_bound)? + $(: $generics_lifetime_bound)? + ),* + >)? ( + $($arg)+: $crate::__private::Pin<&mut $self_ty>, + ) + $(where + $( $where_clause_ty + $(: $where_clause_bound)? + $(: ?$where_clause_unsized_bound)? + $(: $where_clause_lifetime_bound)? + ),* + )? + { + // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`. + fn __drop_inner() {} + $($tt)* + } + + // Safety - we're in 'drop', so we know that 'self' will + // never move again. + let pinned_self: $crate::__private::Pin<&mut Self> + = unsafe { $crate::__private::Pin::new_unchecked(self) }; + // We call `__drop_inner` only once. Since `__DropInner::__drop_inner` + // is not accessible by the users, it is never called again. + __drop_inner(pinned_self); + } + } + }; + ( + [$ident:ident] + [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?] + ) => { + // Ensure that struct does not implement `Drop`. + // + // There are two possible cases: + // 1. The user type does not implement Drop. In this case, + // the first blanked impl will not apply to it. This code + // will compile, as there is only one impl of MustNotImplDrop for the user type + // 2. The user type does impl Drop. This will make the blanket impl applicable, + // which will then conflict with the explicit MustNotImplDrop impl below. + // This will result in a compilation error, which is exactly what we want. + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl <$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*> + $(where + $($where_clause)*)? + { + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_unpin_bound { + (#[pin] $field_ty:ty) => { + $field_ty + }; + ($field_ty:ty) => { + $crate::__private::AlwaysUnpin<$field_ty> + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_unsafe_field_proj { + (#[pin] $field:ident) => { + $crate::__private::Pin::new_unchecked($field) + }; + ($field:ident) => { + $field + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_replace_field_proj { + (#[pin] $field:ident) => { + $crate::__private::PhantomData + }; + ($field:ident) => { + $crate::__private::ptr::read($field) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_unsafe_drop_in_place_guard { + (#[pin] $field:ident) => { + $crate::__private::UnsafeDropInPlaceGuard::new($field) + }; + ($field:ident) => { + () + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_field_mut { + (#[pin] $field_ty:ty) => { + $crate::__private::Pin<&'__pin mut ($field_ty)> + }; + ($field_ty:ty) => { + &'__pin mut ($field_ty) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_field_ref { + (#[pin] $field_ty:ty) => { + $crate::__private::Pin<&'__pin ($field_ty)> + }; + ($field_ty:ty) => { + &'__pin ($field_ty) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_make_proj_field_replace { + (#[pin] $field_ty:ty) => { + $crate::__private::PhantomData<$field_ty> + }; + ($field_ty:ty) => { + $field_ty + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_internal { + // parsing proj_mut_ident + ( + [] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [$( ! $proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + + #[project = $proj_mut_ident:ident] + $($tt:tt)* + ) => { + $crate::__pin_project_internal! { + [$proj_mut_ident] + [$($proj_ref_ident)?] + [$($proj_replace_ident)?] + [$( ! $proj_not_unpin_mark)?] + [$($attrs)*] + $($tt)* + } + }; + // parsing proj_ref_ident + ( + [$($proj_mut_ident:ident)?] + [] + [$($proj_replace_ident:ident)?] + [$( ! $proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + + #[project_ref = $proj_ref_ident:ident] + $($tt:tt)* + ) => { + $crate::__pin_project_internal! { + [$($proj_mut_ident)?] + [$proj_ref_ident] + [$($proj_replace_ident)?] + [$( ! $proj_not_unpin_mark)?] + [$($attrs)*] + $($tt)* + } + }; + // parsing proj_replace_ident + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [] + [$( ! $proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + + #[project_replace = $proj_replace_ident:ident] + $($tt:tt)* + ) => { + $crate::__pin_project_internal! { + [$($proj_mut_ident)?] + [$($proj_ref_ident)?] + [$proj_replace_ident] + [$( ! $proj_not_unpin_mark)?] + [$($attrs)*] + $($tt)* + } + }; + // parsing !Unpin + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [] + [$($attrs:tt)*] + + #[project( ! $proj_not_unpin_mark:ident)] + $($tt:tt)* + ) => { + $crate::__pin_project_internal! { + [$($proj_mut_ident)?] + [$($proj_ref_ident)?] + [$($proj_replace_ident)?] + [ ! $proj_not_unpin_mark] + [$($attrs)*] + $($tt)* + } + }; + // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute + // there could be more to parse + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [$( ! $proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + + #[$($attr:tt)*] + $($tt:tt)* + ) => { + $crate::__pin_project_internal! { + [$($proj_mut_ident)?] + [$($proj_ref_ident)?] + [$($proj_replace_ident)?] + [$( ! $proj_not_unpin_mark)?] + [$($attrs)* #[$($attr)*]] + $($tt)* + } + }; + // now determine visibility + // if public, downgrade + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [$( ! $proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + pub $struct_ty_ident:ident $ident:ident + $($tt:tt)* + ) => { + $crate::__pin_project_parse_generics! { + [$($proj_mut_ident)?] + [$($proj_ref_ident)?] + [$($proj_replace_ident)?] + [$($proj_not_unpin_mark)?] + [$($attrs)*] + [pub $struct_ty_ident $ident pub(crate)] + $($tt)* + } + }; + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [$( ! $proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + $vis:vis $struct_ty_ident:ident $ident:ident + $($tt:tt)* + ) => { + $crate::__pin_project_parse_generics! { + [$($proj_mut_ident)?] + [$($proj_ref_ident)?] + [$($proj_replace_ident)?] + [$($proj_not_unpin_mark)?] + [$($attrs)*] + [$vis $struct_ty_ident $ident $vis] + $($tt)* + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __pin_project_parse_generics { + ( + [$($proj_mut_ident:ident)?] + [$($proj_ref_ident:ident)?] + [$($proj_replace_ident:ident)?] + [$($proj_not_unpin_mark:ident)?] + [$($attrs:tt)*] + [$vis:vis $struct_ty_ident:ident $ident:ident $proj_vis:vis] + $(< + $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)? + $( $generics:ident + $(: $generics_bound:path)? + $(: ?$generics_unsized_bound:path)? + $(: $generics_lifetime_bound:lifetime)? + $(= $generics_default:ty)? + ),* $(,)? + >)? + $(where + $( $where_clause_ty:ty + $(: $where_clause_bound:path)? + $(: ?$where_clause_unsized_bound:path)? + $(: $where_clause_lifetime_bound:lifetime)? + ),* $(,)? + )? + { + $($body_data:tt)* + } + $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)? + ) => { + $crate::__pin_project_expand! { + [$($proj_mut_ident)?] + [$($proj_ref_ident)?] + [$($proj_replace_ident)?] + [$($proj_not_unpin_mark)?] + [$proj_vis] + [$($attrs)* $vis $struct_ty_ident $ident] + [$(< + $( $lifetime $(: $lifetime_bound)? ,)* + $( $generics + $(: $generics_bound)? + $(: ?$generics_unsized_bound)? + $(: $generics_lifetime_bound)? + $(= $generics_default)? + ),* + >)?] + [$( + $( $lifetime $(: $lifetime_bound)? ,)* + $( $generics + $(: $generics_bound)? + $(: ?$generics_unsized_bound)? + $(: $generics_lifetime_bound)? + ),* + )?] + [$( $( $lifetime ,)* $( $generics ),* )?] + [$(where $( $where_clause_ty + $(: $where_clause_bound)? + $(: ?$where_clause_unsized_bound)? + $(: $where_clause_lifetime_bound)? + ),* )?] + { + $($body_data)* + } + $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)? + } + }; +} + +#[doc(hidden)] +pub mod __private { + use core::mem::ManuallyDrop; + #[doc(hidden)] + pub use core::{ + marker::{PhantomData, Unpin}, + ops::Drop, + pin::Pin, + ptr, + }; + + // This is an internal helper struct used by `pin_project!`. + #[doc(hidden)] + pub struct AlwaysUnpin(PhantomData); + + impl Unpin for AlwaysUnpin {} + + // This is an internal helper used to ensure a value is dropped. + #[doc(hidden)] + pub struct UnsafeDropInPlaceGuard(*mut T); + + impl UnsafeDropInPlaceGuard { + #[doc(hidden)] + pub unsafe fn new(ptr: *mut T) -> Self { + Self(ptr) + } + } + + impl Drop for UnsafeDropInPlaceGuard { + fn drop(&mut self) { + // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee + // that `ptr` is valid for drop when this guard is destructed. + unsafe { + ptr::drop_in_place(self.0); + } + } + } + + // This is an internal helper used to ensure a value is overwritten without + // its destructor being called. + #[doc(hidden)] + pub struct UnsafeOverwriteGuard { + target: *mut T, + value: ManuallyDrop, + } + + impl UnsafeOverwriteGuard { + #[doc(hidden)] + pub unsafe fn new(target: *mut T, value: T) -> Self { + Self { target, value: ManuallyDrop::new(value) } + } + } + + impl Drop for UnsafeOverwriteGuard { + fn drop(&mut self) { + // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee + // that `target` is valid for writes when this guard is destructed. + unsafe { + ptr::write(self.target, ptr::read(&*self.value)); + } + } + } +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/auxiliary/mod.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/auxiliary/mod.rs new file mode 100644 index 00000000..14570991 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/auxiliary/mod.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, unused_macros)] + +macro_rules! assert_unpin { + ($ty:ty) => { + static_assertions::assert_impl_all!($ty: Unpin); + }; +} +macro_rules! assert_not_unpin { + ($ty:ty) => { + static_assertions::assert_not_impl_all!($ty: Unpin); + }; +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/compiletest.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/compiletest.rs new file mode 100644 index 00000000..06712d01 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/compiletest.rs @@ -0,0 +1,16 @@ +#![cfg(not(miri))] +#![cfg(not(careful))] +#![warn(rust_2018_idioms, single_use_lifetimes)] + +use std::env; + +#[rustversion::attr(not(nightly), ignore)] +#[test] +fn ui() { + if env::var_os("CI").is_none() { + env::set_var("TRYBUILD", "overwrite"); + } + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/**/*.rs"); +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/drop_order.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/drop_order.rs new file mode 100644 index 00000000..6e5deaf1 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/drop_order.rs @@ -0,0 +1,169 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] + +// Refs: https://doc.rust-lang.org/reference/destructors.html + +use std::{cell::Cell, panic, pin::Pin, thread}; + +use pin_project_lite::pin_project; + +struct D<'a>(&'a Cell, usize); + +impl Drop for D<'_> { + fn drop(&mut self) { + if !thread::panicking() { + let old = self.0.replace(self.1); + assert_eq!(old, self.1 - 1); + } + } +} + +pin_project! { +#[project = StructPinnedProj] +#[project_ref = StructPinnedProjRef] +#[project_replace = StructPinnedProjReplace] +struct StructPinned<'a> { + #[pin] + f1: D<'a>, + #[pin] + f2: D<'a>, +} +} + +pin_project! { +#[project = StructUnpinnedProj] +#[project_ref = StructUnpinnedProjRef] +#[project_replace = StructUnpinnedProjReplace] +struct StructUnpinned<'a> { + f1: D<'a>, + f2: D<'a>, +} +} + +pin_project! { +#[project_replace = EnumProjReplace] +enum Enum<'a> { + #[allow(dead_code)] // false positive that fixed in Rust 1.38 + StructPinned { + #[pin] + f1: D<'a>, + #[pin] + f2: D<'a>, + }, + #[allow(dead_code)] // false positive that fixed in Rust 1.38 + StructUnpinned { + f1: D<'a>, + f2: D<'a>, + }, +} +} + +#[test] +fn struct_pinned() { + { + let c = Cell::new(0); + let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; + } + { + let c = Cell::new(0); + let mut x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) }); + } +} + +#[test] +fn struct_unpinned() { + { + let c = Cell::new(0); + let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; + } + { + let c = Cell::new(0); + let mut x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) }); + } +} + +#[test] +fn enum_struct() { + { + let c = Cell::new(0); + let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; + } + { + let c = Cell::new(0); + let mut x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) }); + } + + { + let c = Cell::new(0); + let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; + } + { + let c = Cell::new(0); + let mut x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) }); + } +} + +// https://github.com/rust-lang/rust/issues/47949 +// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111 +#[allow(clippy::many_single_char_names)] +#[test] +fn project_replace_panic() { + pin_project! { + #[project_replace = SProjReplace] + struct S { + #[pin] + pinned: T, + unpinned: U, + } + } + + struct D<'a>(&'a mut bool, bool); + impl Drop for D<'_> { + fn drop(&mut self) { + *self.0 = true; + if self.1 { + panic!(); + } + } + } + + let (mut a, mut b, mut c, mut d) = (false, false, false, false); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) }; + let _y = Pin::new(&mut x) + .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) }); + // Previous `x.pinned` was dropped and panicked when `project_replace` is + // called, so this is unreachable. + unreachable!(); + })); + assert!(res.is_err()); + assert!(a); + assert!(b); + assert!(c); + assert!(d); + + let (mut a, mut b, mut c, mut d) = (false, false, false, false); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + let mut x = S { pinned: D(&mut a, false), unpinned: D(&mut b, true) }; + { + let _y = Pin::new(&mut x) + .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) }); + // `_y` (previous `x.unpinned`) live to the end of this scope, so + // this is not unreachable. + // unreachable!(); + } + unreachable!(); + })); + assert!(res.is_err()); + assert!(a); + assert!(b); + assert!(c); + assert!(d); +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.expanded.rs new file mode 100644 index 00000000..456b8cc1 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.expanded.rs @@ -0,0 +1,143 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProj<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjRef<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjReplace { + Struct { pinned: ::pin_project_lite::__private::PhantomData, unpinned: U }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> EnumProj<'__pin, T, U> { + unsafe { + match self.get_unchecked_mut() { + Self::Struct { pinned, unpinned } => { + EnumProj::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProj::Unit, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> EnumProjRef<'__pin, T, U> { + unsafe { + match self.get_ref() { + Self::Struct { pinned, unpinned } => { + EnumProjRef::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProjRef::Unit, + } + } + } + #[doc(hidden)] + #[inline] + fn project_replace( + self: ::pin_project_lite::__private::Pin<&mut Self>, + replacement: Self, + ) -> EnumProjReplace { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new( + __self_ptr, + replacement, + ); + match &mut *__self_ptr { + Self::Struct { pinned, unpinned } => { + let result = EnumProjReplace::Struct { + pinned: ::pin_project_lite::__private::PhantomData, + unpinned: ::pin_project_lite::__private::ptr::read(unpinned), + }; + { + ( + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned, + ), + (), + ); + } + result + } + Self::Unit => EnumProjReplace::Unit, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.rs new file mode 100644 index 00000000..90d6860a --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/enum.rs @@ -0,0 +1,17 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project_replace = EnumProjReplace] + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.expanded.rs new file mode 100644 index 00000000..a9792e1f --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.expanded.rs @@ -0,0 +1,90 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct Projection<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + } + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct ProjectionRef<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> Projection<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + Projection { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> ProjectionRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + ProjectionRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.rs new file mode 100644 index 00000000..e5447c70 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/default/struct.rs @@ -0,0 +1,11 @@ +use pin_project_lite::pin_project; + +pin_project! { + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.expanded.rs new file mode 100644 index 00000000..f722a142 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.expanded.rs @@ -0,0 +1,89 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned1: T, pinned2: T, unpinned1: U, unpinned2: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjReplace { + Struct { + pinned1: ::pin_project_lite::__private::PhantomData, + pinned2: ::pin_project_lite::__private::PhantomData, + unpinned1: U, + unpinned2: U, + }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project_replace( + self: ::pin_project_lite::__private::Pin<&mut Self>, + replacement: Self, + ) -> EnumProjReplace { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new( + __self_ptr, + replacement, + ); + match &mut *__self_ptr { + Self::Struct { pinned1, pinned2, unpinned1, unpinned2 } => { + let result = EnumProjReplace::Struct { + pinned1: ::pin_project_lite::__private::PhantomData, + pinned2: ::pin_project_lite::__private::PhantomData, + unpinned1: ::pin_project_lite::__private::ptr::read( + unpinned1, + ), + unpinned2: ::pin_project_lite::__private::ptr::read( + unpinned2, + ), + }; + { + ( + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned1, + ), + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned2, + ), + (), + (), + ); + } + result + } + Self::Unit => EnumProjReplace::Unit, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: ( + T, + T, + ::pin_project_lite::__private::AlwaysUnpin, + ::pin_project_lite::__private::AlwaysUnpin, + ), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.rs new file mode 100644 index 00000000..c713362a --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/enum.rs @@ -0,0 +1,18 @@ +use pin_project_lite::pin_project; + +pin_project! { +#[project_replace = EnumProjReplace] +enum Enum { + Struct { + #[pin] + pinned1: T, + #[pin] + pinned2: T, + unpinned1: U, + unpinned2: U, + }, + Unit, +} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.expanded.rs new file mode 100644 index 00000000..83ebefe9 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.expanded.rs @@ -0,0 +1,151 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned1: T, + pinned2: T, + unpinned1: U, + unpinned2: U, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProjReplace { + pinned1: ::pin_project_lite::__private::PhantomData, + pinned2: ::pin_project_lite::__private::PhantomData, + unpinned1: U, + unpinned2: U, +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct Projection<'__pin, T, U> + where + Struct: '__pin, + { + pinned1: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + pinned2: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned1: &'__pin mut (U), + unpinned2: &'__pin mut (U), + } + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct ProjectionRef<'__pin, T, U> + where + Struct: '__pin, + { + pinned1: ::pin_project_lite::__private::Pin<&'__pin (T)>, + pinned2: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned1: &'__pin (U), + unpinned2: &'__pin (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> Projection<'__pin, T, U> { + unsafe { + let Self { pinned1, pinned2, unpinned1, unpinned2 } = self + .get_unchecked_mut(); + Projection { + pinned1: ::pin_project_lite::__private::Pin::new_unchecked(pinned1), + pinned2: ::pin_project_lite::__private::Pin::new_unchecked(pinned2), + unpinned1: unpinned1, + unpinned2: unpinned2, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> ProjectionRef<'__pin, T, U> { + unsafe { + let Self { pinned1, pinned2, unpinned1, unpinned2 } = self.get_ref(); + ProjectionRef { + pinned1: ::pin_project_lite::__private::Pin::new_unchecked(pinned1), + pinned2: ::pin_project_lite::__private::Pin::new_unchecked(pinned2), + unpinned1: unpinned1, + unpinned2: unpinned2, + } + } + } + #[doc(hidden)] + #[inline] + fn project_replace( + self: ::pin_project_lite::__private::Pin<&mut Self>, + replacement: Self, + ) -> StructProjReplace { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new( + __self_ptr, + replacement, + ); + let Self { pinned1, pinned2, unpinned1, unpinned2 } = &mut *__self_ptr; + let result = StructProjReplace { + pinned1: ::pin_project_lite::__private::PhantomData, + pinned2: ::pin_project_lite::__private::PhantomData, + unpinned1: ::pin_project_lite::__private::ptr::read(unpinned1), + unpinned2: ::pin_project_lite::__private::ptr::read(unpinned2), + }; + { + ( + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned1, + ), + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned2, + ), + (), + (), + ); + } + result + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned1: T, + pinned2: T, + unpinned1: ::pin_project_lite::__private::AlwaysUnpin, + unpinned2: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned1; + let _ = &this.pinned2; + let _ = &this.unpinned1; + let _ = &this.unpinned2; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.rs new file mode 100644 index 00000000..a1d45d16 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/multifields/struct.rs @@ -0,0 +1,15 @@ +use pin_project_lite::pin_project; + +pin_project! { +#[project_replace = StructProjReplace] +struct Struct { + #[pin] + pinned1: T, + #[pin] + pinned2: T, + unpinned1: U, + unpinned2: U, +} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.expanded.rs new file mode 100644 index 00000000..456b8cc1 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.expanded.rs @@ -0,0 +1,143 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProj<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjRef<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjReplace { + Struct { pinned: ::pin_project_lite::__private::PhantomData, unpinned: U }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> EnumProj<'__pin, T, U> { + unsafe { + match self.get_unchecked_mut() { + Self::Struct { pinned, unpinned } => { + EnumProj::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProj::Unit, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> EnumProjRef<'__pin, T, U> { + unsafe { + match self.get_ref() { + Self::Struct { pinned, unpinned } => { + EnumProjRef::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProjRef::Unit, + } + } + } + #[doc(hidden)] + #[inline] + fn project_replace( + self: ::pin_project_lite::__private::Pin<&mut Self>, + replacement: Self, + ) -> EnumProjReplace { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new( + __self_ptr, + replacement, + ); + match &mut *__self_ptr { + Self::Struct { pinned, unpinned } => { + let result = EnumProjReplace::Struct { + pinned: ::pin_project_lite::__private::PhantomData, + unpinned: ::pin_project_lite::__private::ptr::read(unpinned), + }; + { + ( + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned, + ), + (), + ); + } + result + } + Self::Unit => EnumProjReplace::Unit, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.rs new file mode 100644 index 00000000..90d6860a --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-all.rs @@ -0,0 +1,17 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project_replace = EnumProjReplace] + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.expanded.rs new file mode 100644 index 00000000..342588cf --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.expanded.rs @@ -0,0 +1,64 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProj<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> EnumProj<'__pin, T, U> { + unsafe { + match self.get_unchecked_mut() { + Self::Struct { pinned, unpinned } => { + EnumProj::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProj::Unit, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.rs new file mode 100644 index 00000000..69beecd1 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-mut.rs @@ -0,0 +1,15 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.expanded.rs new file mode 100644 index 00000000..fc3b3dca --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.expanded.rs @@ -0,0 +1,26 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum {} + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.rs new file mode 100644 index 00000000..b2e3f9d7 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-none.rs @@ -0,0 +1,14 @@ +use pin_project_lite::pin_project; + +pin_project! { + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.expanded.rs new file mode 100644 index 00000000..5270e129 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.expanded.rs @@ -0,0 +1,64 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjRef<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> EnumProjRef<'__pin, T, U> { + unsafe { + match self.get_ref() { + Self::Struct { pinned, unpinned } => { + EnumProjRef::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProjRef::Unit, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.rs new file mode 100644 index 00000000..480d592d --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/enum-ref.rs @@ -0,0 +1,15 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project_ref = EnumProjRef] + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.expanded.rs new file mode 100644 index 00000000..13c4079f --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.expanded.rs @@ -0,0 +1,128 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProj<'__pin, T, U> +where + Struct: '__pin, +{ + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProjRef<'__pin, T, U> +where + Struct: '__pin, +{ + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProjReplace { + pinned: ::pin_project_lite::__private::PhantomData, + unpinned: U, +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> StructProj<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + StructProj { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> StructProjRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + StructProjRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_replace( + self: ::pin_project_lite::__private::Pin<&mut Self>, + replacement: Self, + ) -> StructProjReplace { + unsafe { + let __self_ptr: *mut Self = self.get_unchecked_mut(); + let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new( + __self_ptr, + replacement, + ); + let Self { pinned, unpinned } = &mut *__self_ptr; + let result = StructProjReplace { + pinned: ::pin_project_lite::__private::PhantomData, + unpinned: ::pin_project_lite::__private::ptr::read(unpinned), + }; + { + ( + ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new( + pinned, + ), + (), + ); + } + result + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.rs new file mode 100644 index 00000000..cb087530 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-all.rs @@ -0,0 +1,14 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = StructProj] + #[project_ref = StructProjRef] + #[project_replace = StructProjReplace] + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.expanded.rs new file mode 100644 index 00000000..9b6dae89 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.expanded.rs @@ -0,0 +1,90 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProj<'__pin, T, U> +where + Struct: '__pin, +{ + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct ProjectionRef<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> StructProj<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + StructProj { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> ProjectionRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + ProjectionRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.rs new file mode 100644 index 00000000..59db4453 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-mut.rs @@ -0,0 +1,12 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = StructProj] + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.expanded.rs new file mode 100644 index 00000000..a9792e1f --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.expanded.rs @@ -0,0 +1,90 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct Projection<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + } + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct ProjectionRef<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> Projection<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + Projection { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> ProjectionRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + ProjectionRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.rs new file mode 100644 index 00000000..e5447c70 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-none.rs @@ -0,0 +1,11 @@ +use pin_project_lite::pin_project; + +pin_project! { + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.expanded.rs new file mode 100644 index 00000000..9fea20d3 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.expanded.rs @@ -0,0 +1,90 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProjRef<'__pin, T, U> +where + Struct: '__pin, +{ + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct Projection<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> Projection<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + Projection { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> StructProjRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + StructProjRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.rs new file mode 100644 index 00000000..6821af82 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/naming/struct-ref.rs @@ -0,0 +1,12 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project_ref = StructProjRef] + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.expanded.rs new file mode 100644 index 00000000..02cdc239 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.expanded.rs @@ -0,0 +1,99 @@ +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProj<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjRef<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> EnumProj<'__pin, T, U> { + unsafe { + match self.get_unchecked_mut() { + Self::Struct { pinned, unpinned } => { + EnumProj::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProj::Unit, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> EnumProjRef<'__pin, T, U> { + unsafe { + match self.get_ref() { + Self::Struct { pinned, unpinned } => { + EnumProjRef::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProjRef::Unit, + } + } + } + } + #[doc(hidden)] + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + ( + ::core::marker::PhantomData<&'__pin ()>, + ::core::marker::PhantomPinned, + ): ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.rs new file mode 100644 index 00000000..0896716b --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/enum.rs @@ -0,0 +1,17 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project(!Unpin)] + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.expanded.rs new file mode 100644 index 00000000..2e590b6b --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.expanded.rs @@ -0,0 +1,88 @@ +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProj<'__pin, T, U> +where + Struct: '__pin, +{ + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +struct StructProjRef<'__pin, T, U> +where + Struct: '__pin, +{ + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> StructProj<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + StructProj { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> StructProjRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + StructProjRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[doc(hidden)] + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + ( + ::core::marker::PhantomData<&'__pin ()>, + ::core::marker::PhantomPinned, + ): ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.rs new file mode 100644 index 00000000..0a2967f7 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/not_unpin/struct.rs @@ -0,0 +1,14 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = StructProj] + #[project(!Unpin)] + #[project_ref = StructProjRef] + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.expanded.rs new file mode 100644 index 00000000..03901ced --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.expanded.rs @@ -0,0 +1,112 @@ +use std::pin::Pin; +use pin_project_lite::pin_project; +enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProj<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +enum EnumProjRef<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> EnumProj<'__pin, T, U> { + unsafe { + match self.get_unchecked_mut() { + Self::Struct { pinned, unpinned } => { + EnumProj::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProj::Unit, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> EnumProjRef<'__pin, T, U> { + unsafe { + match self.get_ref() { + Self::Struct { pinned, unpinned } => { + EnumProjRef::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProjRef::Unit, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + impl ::pin_project_lite::__private::Drop for Enum { + fn drop(&mut self) { + fn __drop_inner( + this: ::pin_project_lite::__private::Pin<&mut Enum>, + ) { + fn __drop_inner() {} + let _ = this; + } + let pinned_self: ::pin_project_lite::__private::Pin<&mut Self> = unsafe { + ::pin_project_lite::__private::Pin::new_unchecked(self) + }; + __drop_inner(pinned_self); + } + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.rs new file mode 100644 index 00000000..5f3508c0 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/enum.rs @@ -0,0 +1,23 @@ +use std::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } + impl PinnedDrop for Enum { + fn drop(this: Pin<&mut Self>) { + let _ = this; + } + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.expanded.rs new file mode 100644 index 00000000..f3fa923f --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.expanded.rs @@ -0,0 +1,101 @@ +use std::pin::Pin; +use pin_project_lite::pin_project; +struct Struct { + pinned: T, + unpinned: U, +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct Projection<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + } + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + struct ProjectionRef<'__pin, T, U> + where + Struct: '__pin, + { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> Projection<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + Projection { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> ProjectionRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + ProjectionRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[allow(non_snake_case)] + struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + impl ::pin_project_lite::__private::Drop for Struct { + fn drop(&mut self) { + fn __drop_inner( + this: ::pin_project_lite::__private::Pin<&mut Struct>, + ) { + fn __drop_inner() {} + let _ = this; + } + let pinned_self: ::pin_project_lite::__private::Pin<&mut Self> = unsafe { + ::pin_project_lite::__private::Pin::new_unchecked(self) + }; + __drop_inner(pinned_self); + } + } + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.rs new file mode 100644 index 00000000..5400ecbb --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pinned_drop/struct.rs @@ -0,0 +1,18 @@ +use std::pin::Pin; + +use pin_project_lite::pin_project; + +pin_project! { + struct Struct { + #[pin] + pinned: T, + unpinned: U, + } + impl PinnedDrop for Struct { + fn drop(this: Pin<&mut Self>) { + let _ = this; + } + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.expanded.rs new file mode 100644 index 00000000..85c7770d --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.expanded.rs @@ -0,0 +1,101 @@ +use pin_project_lite::pin_project; +pub enum Enum { + Struct { pinned: T, unpinned: U }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +pub(crate) enum EnumProj<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + unpinned: &'__pin mut (U), + }, + Unit, +} +#[doc(hidden)] +#[allow(dead_code)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::mut_mut)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::ref_option_ref)] +#[allow(clippy::type_repetition_in_bounds)] +pub(crate) enum EnumProjRef<'__pin, T, U> +where + Enum: '__pin, +{ + Struct { + pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + unpinned: &'__pin (U), + }, + Unit, +} +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + impl Enum { + #[doc(hidden)] + #[inline] + pub(crate) fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> EnumProj<'__pin, T, U> { + unsafe { + match self.get_unchecked_mut() { + Self::Struct { pinned, unpinned } => { + EnumProj::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProj::Unit, + } + } + } + #[doc(hidden)] + #[inline] + pub(crate) fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> EnumProjRef<'__pin, T, U> { + unsafe { + match self.get_ref() { + Self::Struct { pinned, unpinned } => { + EnumProjRef::Struct { + pinned: ::pin_project_lite::__private::Pin::new_unchecked( + pinned, + ), + unpinned: unpinned, + } + } + Self::Unit => EnumProjRef::Unit, + } + } + } + } + #[allow(non_snake_case)] + pub struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + Struct: (T, ::pin_project_lite::__private::AlwaysUnpin), + Unit: (), + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Enum {} +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.rs new file mode 100644 index 00000000..d3968afd --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/enum.rs @@ -0,0 +1,16 @@ +use pin_project_lite::pin_project; + +pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + pub enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.expanded.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.expanded.rs new file mode 100644 index 00000000..a06783dc --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.expanded.rs @@ -0,0 +1,90 @@ +use pin_project_lite::pin_project; +pub struct Struct { + pub pinned: T, + pub unpinned: U, +} +#[allow(explicit_outlives_requirements)] +#[allow(single_use_lifetimes)] +#[allow(clippy::unknown_clippy_lints)] +#[allow(clippy::redundant_pub_crate)] +#[allow(clippy::used_underscore_binding)] +const _: () = { + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + pub(crate) struct Projection<'__pin, T, U> + where + Struct: '__pin, + { + pub pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>, + pub unpinned: &'__pin mut (U), + } + #[doc(hidden)] + #[allow(dead_code)] + #[allow(single_use_lifetimes)] + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::mut_mut)] + #[allow(clippy::redundant_pub_crate)] + #[allow(clippy::ref_option_ref)] + #[allow(clippy::type_repetition_in_bounds)] + pub(crate) struct ProjectionRef<'__pin, T, U> + where + Struct: '__pin, + { + pub pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>, + pub unpinned: &'__pin (U), + } + impl Struct { + #[doc(hidden)] + #[inline] + pub(crate) fn project<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin mut Self>, + ) -> Projection<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_unchecked_mut(); + Projection { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + #[doc(hidden)] + #[inline] + pub(crate) fn project_ref<'__pin>( + self: ::pin_project_lite::__private::Pin<&'__pin Self>, + ) -> ProjectionRef<'__pin, T, U> { + unsafe { + let Self { pinned, unpinned } = self.get_ref(); + ProjectionRef { + pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned), + unpinned: unpinned, + } + } + } + } + #[allow(non_snake_case)] + pub struct __Origin<'__pin, T, U> { + __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>, + pinned: T, + unpinned: ::pin_project_lite::__private::AlwaysUnpin, + } + impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct + where + __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin, + {} + trait MustNotImplDrop {} + #[allow(clippy::drop_bounds, drop_bounds)] + impl MustNotImplDrop for T {} + impl MustNotImplDrop for Struct {} + #[forbid(unaligned_references, safe_packed_borrows)] + fn __assert_not_repr_packed(this: &Struct) { + let _ = &this.pinned; + let _ = &this.unpinned; + } +}; +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.rs new file mode 100644 index 00000000..66590969 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expand/pub/struct.rs @@ -0,0 +1,11 @@ +use pin_project_lite::pin_project; + +pin_project! { + pub struct Struct { + #[pin] + pub pinned: T, + pub unpinned: U, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/expandtest.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/expandtest.rs new file mode 100644 index 00000000..04a06669 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/expandtest.rs @@ -0,0 +1,44 @@ +#![cfg(not(miri))] +#![cfg(not(careful))] +#![warn(rust_2018_idioms, single_use_lifetimes)] + +use std::{ + env, + process::{Command, ExitStatus, Stdio}, +}; + +const PATH: &str = "tests/expand/**/*.rs"; + +#[rustversion::attr(not(nightly), ignore)] +#[test] +fn expandtest() { + let is_ci = env::var_os("CI").is_some(); + let cargo = &*env::var("CARGO").unwrap_or_else(|_| "cargo".into()); + if !has_command(&[cargo, "expand"]) { + if is_ci { + panic!("expandtest requires cargo-expand"); + } + return; + } + + let args = &["--all-features"]; + if is_ci { + macrotest::expand_without_refresh_args(PATH, args); + } else { + env::set_var("MACROTEST", "overwrite"); + macrotest::expand_args(PATH, args); + } +} + +fn has_command(command: &[&str]) -> bool { + Command::new(command[0]) + .args(&command[1..]) + .arg("--version") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status() + .as_ref() + .map(ExitStatus::success) + .unwrap_or(false) +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/include/basic.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/include/basic.rs new file mode 100644 index 00000000..25121f21 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/include/basic.rs @@ -0,0 +1,35 @@ +// default pin_project! is completely safe. + +::pin_project_lite::pin_project! { + #[derive(Debug)] + pub struct DefaultStruct { + #[pin] + pub pinned: T, + pub unpinned: U, + } +} + +::pin_project_lite::pin_project! { + #[project = DefaultStructProj] + #[project_ref = DefaultStructProjRef] + #[derive(Debug)] + pub struct DefaultStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, + } +} + +::pin_project_lite::pin_project! { + #[project = DefaultEnumProj] + #[project_ref = DefaultEnumProjRef] + #[derive(Debug)] + pub enum DefaultEnum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/lint.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/lint.rs new file mode 100644 index 00000000..94f72fdd --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/lint.rs @@ -0,0 +1,281 @@ +// Check interoperability with rustc and clippy lints. + +#![forbid(unsafe_code)] +// for old compilers +#![allow(unknown_lints)] +#![warn(nonstandard_style, rust_2018_idioms, unused)] +// Note: This does not guarantee compatibility with forbidding these lints in the future. +// If rustc adds a new lint, we may not be able to keep this. +#![forbid(future_incompatible, rust_2018_compatibility, rust_2021_compatibility)] +// lints forbidden as a part of future_incompatible, rust_2018_compatibility, and rust_2021_compatibility are not included in the list below. +// elided_lifetimes_in_paths, explicit_outlives_requirements, unused_extern_crates: as a part of rust_2018_idioms +// unsafe_op_in_unsafe_fn: requires Rust 1.52. and, we don't generate unsafe fn. +// non_exhaustive_omitted_patterns, multiple_supertrait_upcastable: unstable +// unstable_features: no way to generate #![feature(..)] by macros, expect for unstable inner attribute. and this lint is deprecated: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#unstable-features +// unused_crate_dependencies, must_not_suspend: unrelated +// unsafe_code: checked in forbid_unsafe module +#![warn( + box_pointers, + deprecated_in_future, + fuzzy_provenance_casts, + invalid_reference_casting, + let_underscore_drop, + lossy_provenance_casts, + macro_use_extern_crate, + meta_variable_misuse, + missing_abi, + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + non_ascii_idents, + noop_method_call, + private_bounds, + private_interfaces, + single_use_lifetimes, + trivial_casts, + trivial_numeric_casts, + unnameable_types, + unreachable_pub, + unused_import_braces, + unused_lifetimes, + unused_qualifications, + unused_results, + unused_tuple_struct_fields, + variant_size_differences +)] +#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::restriction)] +#![allow(clippy::blanket_clippy_restriction_lints)] // this is a test, so enable all restriction lints intentionally. +#![allow( + clippy::exhaustive_enums, + clippy::exhaustive_structs, + clippy::min_ident_chars, + clippy::single_char_lifetime_names +)] // TODO + +pub mod basic { + include!("include/basic.rs"); +} + +pub mod box_pointers { + use pin_project_lite::pin_project; + + pin_project! { + #[derive(Debug)] + pub struct Struct { + #[pin] + pub p: Box, + pub u: Box, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + #[derive(Debug)] + pub enum Enum { + Struct { + #[pin] + p: Box, + u: Box, + }, + Unit, + } + } +} + +pub mod explicit_outlives_requirements { + use pin_project_lite::pin_project; + + pin_project! { + #[derive(Debug)] + pub struct Struct<'a, T, U> + where + T: ?Sized, + U: ?Sized, + { + #[pin] + pub pinned: &'a mut T, + pub unpinned: &'a mut U, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + #[derive(Debug)] + pub enum Enum<'a, T, U> + where + T: ?Sized, + U: ?Sized, + { + Struct { + #[pin] + pinned: &'a mut T, + unpinned: &'a mut U, + }, + Unit, + } + } +} + +pub mod variant_size_differences { + use pin_project_lite::pin_project; + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + #[allow(missing_debug_implementations, missing_copy_implementations)] // https://github.com/rust-lang/rust/pull/74060 + #[allow(variant_size_differences)] // for the type itself + #[allow(clippy::large_enum_variant)] // for the type itself + pub enum Enum { + V1 { f: u8 }, + V2 { f: [u8; 1024] }, + } + } +} + +pub mod clippy_mut_mut { + use pin_project_lite::pin_project; + + pin_project! { + #[derive(Debug)] + pub struct Struct<'a, T, U> { + #[pin] + pub pinned: &'a mut T, + pub unpinned: &'a mut U, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + #[derive(Debug)] + pub enum Enum<'a, T, U> { + Struct { + #[pin] + pinned: &'a mut T, + unpinned: &'a mut U, + }, + Unit, + } + } +} + +#[allow(unreachable_pub)] +mod clippy_redundant_pub_crate { + use pin_project_lite::pin_project; + + pin_project! { + #[derive(Debug)] + pub struct Struct { + #[pin] + pub pinned: T, + pub unpinned: U, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + #[derive(Debug)] + pub enum Enum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } + } +} + +#[allow(clippy::use_self)] +pub mod clippy_type_repetition_in_bounds { + use pin_project_lite::pin_project; + + pin_project! { + #[derive(Debug)] + pub struct Struct + where + Struct: Sized, + { + #[pin] + pub pinned: T, + pub unpinned: U, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + #[derive(Debug)] + pub enum Enum + where + Enum: Sized, + { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Unit, + } + } +} + +#[allow(missing_debug_implementations)] +pub mod clippy_used_underscore_binding { + use pin_project_lite::pin_project; + + pin_project! { + pub struct Struct { + #[pin] + pub _pinned: T, + pub _unpinned: U, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + pub enum Enum { + Struct { + #[pin] + _pinned: T, + _unpinned: U, + }, + } + } +} + +pub mod clippy_ref_option_ref { + use pin_project_lite::pin_project; + + pin_project! { + pub struct Struct<'a> { + #[pin] + pub _pinned: Option<&'a ()>, + pub _unpinned: Option<&'a ()>, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project(!Unpin)] + pub enum Enum<'a> { + Struct { + #[pin] + _pinned: Option<&'a ()>, + _unpinned: Option<&'a ()>, + }, + } + } +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/proper_unpin.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/proper_unpin.rs new file mode 100644 index 00000000..89235a4d --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/proper_unpin.rs @@ -0,0 +1,100 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] +#![allow(dead_code)] + +#[macro_use] +mod auxiliary; + +pub mod default { + use std::marker::PhantomPinned; + + use pin_project_lite::pin_project; + + struct Inner { + f: T, + } + + assert_unpin!(Inner<()>); + assert_not_unpin!(Inner); + + pin_project! { + struct Struct { + #[pin] + f1: Inner, + f2: U, + } + } + + assert_unpin!(Struct<(), ()>); + assert_unpin!(Struct<(), PhantomPinned>); + assert_not_unpin!(Struct); + assert_not_unpin!(Struct); + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum { + V1 { + #[pin] + f1: Inner, + f2: U, + }, + } + } + + assert_unpin!(Enum<(), ()>); + assert_unpin!(Enum<(), PhantomPinned>); + assert_not_unpin!(Enum); + assert_not_unpin!(Enum); + + pin_project! { + #[project(!Unpin)] + enum NotUnpinEnum { + V1 { + #[pin] f1: Inner, + f2: U, + } + } + } + + assert_not_unpin!(NotUnpinEnum<(), ()>); + + pin_project! { + struct TrivialBounds { + #[pin] + f: PhantomPinned, + } + } + + assert_not_unpin!(TrivialBounds); + + pin_project! { + struct PinRef<'a, T, U> { + #[pin] + f1: &'a mut Inner, + f2: U, + } + } + + assert_unpin!(PinRef<'_, PhantomPinned, PhantomPinned>); + + pin_project! { + #[project(!Unpin)] + struct NotUnpin { + #[pin] + u: U + } + } + + assert_not_unpin!(NotUnpin<()>); + + pin_project! { + #[project(!Unpin)] + struct NotUnpinRef<'a, T, U> { + #[pin] + f1: &'a mut Inner, + f2: U + } + } + + assert_not_unpin!(NotUnpinRef<'_, (), ()>); +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/test.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/test.rs new file mode 100644 index 00000000..d1289300 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/test.rs @@ -0,0 +1,698 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] +#![allow(dead_code)] + +#[macro_use] +mod auxiliary; + +use core::{ + marker::{PhantomData, PhantomPinned}, + pin::Pin, +}; + +use pin_project_lite::pin_project; + +#[test] +fn projection() { + pin_project! { + #[project = StructProj] + #[project_ref = StructProjRef] + #[project_replace = StructProjReplace] + #[derive(Default)] + struct Struct { + #[pin] + f1: T, + f2: U, + } + } + + let mut s = Struct { f1: 1, f2: 2 }; + let mut s_orig = Pin::new(&mut s); + let s = s_orig.as_mut().project(); + + let _: Pin<&mut i32> = s.f1; + assert_eq!(*s.f1, 1); + let _: &mut i32 = s.f2; + assert_eq!(*s.f2, 2); + + assert_eq!(s_orig.as_ref().f1, 1); + assert_eq!(s_orig.as_ref().f2, 2); + + let mut s = Struct { f1: 1, f2: 2 }; + let mut s = Pin::new(&mut s); + { + let StructProj { f1, f2 } = s.as_mut().project(); + let _: Pin<&mut i32> = f1; + let _: &mut i32 = f2; + } + { + let StructProjRef { f1, f2 } = s.as_ref().project_ref(); + let _: Pin<&i32> = f1; + let _: &i32 = f2; + } + + { + let StructProjReplace { f1: PhantomData, f2 } = + s.as_mut().project_replace(Struct::default()); + assert_eq!(f2, 2); + let StructProj { f1, f2 } = s.project(); + assert_eq!(*f1, 0); + assert_eq!(*f2, 0); + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[project_replace = EnumProjReplace] + #[derive(Eq, PartialEq, Debug)] + enum Enum { + Struct { + #[pin] + f1: C, + f2: D, + }, + Unit, + } + } + + let mut e = Enum::Struct { f1: 1, f2: 2 }; + let mut e = Pin::new(&mut e); + + match e.as_mut().project() { + EnumProj::Struct { f1, f2 } => { + let _: Pin<&mut i32> = f1; + assert_eq!(*f1, 1); + let _: &mut i32 = f2; + assert_eq!(*f2, 2); + } + EnumProj::Unit => unreachable!(), + } + + assert_eq!(&*e, &Enum::Struct { f1: 1, f2: 2 }); + + if let EnumProj::Struct { f1, f2 } = e.as_mut().project() { + let _: Pin<&mut i32> = f1; + assert_eq!(*f1, 1); + let _: &mut i32 = f2; + assert_eq!(*f2, 2); + } + + if let EnumProjReplace::Struct { f1: PhantomData, f2 } = e.as_mut().project_replace(Enum::Unit) + { + assert_eq!(f2, 2); + } +} + +#[test] +fn enum_project_set() { + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + #[derive(Eq, PartialEq, Debug)] + enum Enum { + V1 { #[pin] f: u8 }, + V2 { f: bool }, + } + } + + let mut e = Enum::V1 { f: 25 }; + let mut e_orig = Pin::new(&mut e); + let e_proj = e_orig.as_mut().project(); + + match e_proj { + EnumProj::V1 { f } => { + let new_e = Enum::V2 { f: f.as_ref().get_ref() == &25 }; + e_orig.set(new_e); + } + EnumProj::V2 { .. } => unreachable!(), + } + + assert_eq!(e, Enum::V2 { f: true }); +} + +#[test] +fn where_clause() { + pin_project! { + struct Struct + where + T: Copy, + { + f: T, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum + where + T: Copy, + { + V { f: T }, + } + } +} + +#[test] +fn where_clause_and_associated_type_field() { + pin_project! { + struct Struct1 + where + I: Iterator, + { + #[pin] + f1: I, + f2: I::Item, + } + } + + pin_project! { + struct Struct2 + where + I: Iterator, + { + #[pin] + f1: I, + f2: J, + } + } + + pin_project! { + pub struct Struct3 + where + T: 'static, + { + f: T, + } + } + + trait Static: 'static {} + + impl Static for Struct3 {} + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum + where + I: Iterator, + { + V1 { #[pin] f: I }, + V2 { f: I::Item }, + } + } +} + +#[test] +fn derive_copy() { + pin_project! { + #[derive(Clone, Copy)] + struct Struct { + f: T, + } + } + + fn is_copy() {} + + is_copy::>(); +} + +#[test] +fn move_out() { + struct NotCopy; + + pin_project! { + struct Struct { + f: NotCopy, + } + } + + let x = Struct { f: NotCopy }; + let _val: NotCopy = x.f; + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum { + V { f: NotCopy }, + } + } + + let x = Enum::V { f: NotCopy }; + #[allow(clippy::infallible_destructuring_match)] + let _val: NotCopy = match x { + Enum::V { f } => f, + }; +} + +#[test] +fn trait_bounds_on_type_generics() { + pin_project! { + pub struct Struct1<'a, T: ?Sized> { + f: &'a mut T, + } + } + + pin_project! { + pub struct Struct2<'a, T: ::core::fmt::Debug> { + f: &'a mut T, + } + } + + pin_project! { + pub struct Struct3<'a, T: core::fmt::Debug> { + f: &'a mut T, + } + } + + // pin_project! { + // pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> { + // f: &'a mut T, + // } + // } + + // pin_project! { + // pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> { + // f: &'a mut T, + // } + // } + + pin_project! { + pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> { + f: &'a mut T, + } + } + + let _: Struct6<'_> = Struct6 { f: &mut [0_u8; 16] }; + + pin_project! { + pub struct Struct7 { + f: T, + } + } + + trait Static: 'static {} + + impl Static for Struct7 {} + + pin_project! { + pub struct Struct8<'a, 'b: 'a> { + f1: &'a u8, + f2: &'b u8, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum<'a, T: ?Sized> { + V { f: &'a mut T }, + } + } +} + +#[test] +fn private_type_in_public_type() { + pin_project! { + pub struct PublicStruct { + #[pin] + inner: PrivateStruct, + } + } + + struct PrivateStruct(T); +} + +#[allow(clippy::needless_lifetimes)] +#[test] +fn lifetime_project() { + pin_project! { + struct Struct1 { + #[pin] + pinned: T, + unpinned: U, + } + } + + pin_project! { + struct Struct2<'a, T, U> { + #[pin] + pinned: &'a T, + unpinned: U, + } + } + + pin_project! { + #[project = EnumProj] + #[project_ref = EnumProjRef] + enum Enum { + V { + #[pin] + pinned: T, + unpinned: U, + }, + } + } + + impl Struct1 { + fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> { + self.project_ref().pinned + } + fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> { + self.project().pinned + } + fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> { + self.project_ref().pinned + } + fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> { + self.project().pinned + } + } + + impl<'b, T, U> Struct2<'b, T, U> { + fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b T> { + self.project_ref().pinned + } + fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b T> { + self.project().pinned + } + fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&&'b T> { + self.project_ref().pinned + } + fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut &'b T> { + self.project().pinned + } + } + + impl Enum { + fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> { + match self.project_ref() { + EnumProjRef::V { pinned, .. } => pinned, + } + } + fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> { + match self.project() { + EnumProj::V { pinned, .. } => pinned, + } + } + fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> { + match self.project_ref() { + EnumProjRef::V { pinned, .. } => pinned, + } + } + fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> { + match self.project() { + EnumProj::V { pinned, .. } => pinned, + } + } + } +} + +mod visibility { + use pin_project_lite::pin_project; + + pin_project! { + pub(crate) struct S { + pub f: u8, + } + } +} + +#[test] +fn visibility() { + let mut x = visibility::S { f: 0 }; + let x = Pin::new(&mut x); + let y = x.as_ref().project_ref(); + let _: &u8 = y.f; + let y = x.project(); + let _: &mut u8 = y.f; +} + +#[test] +fn trivial_bounds() { + pin_project! { + pub struct NoGenerics { + #[pin] + f: PhantomPinned, + } + } + + assert_not_unpin!(NoGenerics); +} + +#[test] +fn dst() { + pin_project! { + pub struct Struct1 { + f: T, + } + } + + let mut x = Struct1 { f: 0_u8 }; + let x: Pin<&mut Struct1> = Pin::new(&mut x as _); + let _: &mut (dyn core::fmt::Debug) = x.project().f; + + pin_project! { + pub struct Struct2 { + #[pin] + f: T, + } + } + + let mut x = Struct2 { f: 0_u8 }; + let x: Pin<&mut Struct2> = Pin::new(&mut x as _); + let _: Pin<&mut (dyn core::fmt::Debug + Unpin)> = x.project().f; + + pin_project! { + struct Struct3 + where + T: ?Sized, + { + f: T, + } + } + + pin_project! { + struct Struct4 + where + T: ?Sized, + { + #[pin] + f: T, + } + } + + pin_project! { + struct Struct11<'a, T: ?Sized, U: ?Sized> { + f1: &'a mut T, + f2: U, + } + } +} + +#[test] +fn dyn_type() { + pin_project! { + struct Struct1 { + f: dyn core::fmt::Debug, + } + } + + pin_project! { + struct Struct2 { + #[pin] + f: dyn core::fmt::Debug, + } + } + + pin_project! { + struct Struct3 { + f: dyn core::fmt::Debug + Send, + } + } + + pin_project! { + struct Struct4 { + #[pin] + f: dyn core::fmt::Debug + Send, + } + } +} + +#[test] +fn no_infer_outlives() { + trait Trait { + type Y; + } + + struct Struct1(A); + + impl Trait for Struct1 { + type Y = Option; + } + + pin_project! { + struct Struct2 { + _f: as Trait>::Y, + } + } +} + +// https://github.com/taiki-e/pin-project-lite/issues/31 +#[test] +fn trailing_comma() { + pub trait T {} + + pin_project! { + pub struct S1< + A: T, + B: T, + > { + f: (A, B), + } + } + + pin_project! { + pub struct S2< + A, + B, + > + where + A: T, + B: T, + { + f: (A, B), + } + } + + pin_project! { + #[allow(explicit_outlives_requirements)] + pub struct S3< + 'a, + A: 'a, + B: 'a, + > { + f: &'a (A, B), + } + } + + // pin_project! { + // pub struct S4< + // 'a, + // 'b: 'a, // <----- + // > { + // f: &'a &'b (), + // } + // } +} + +#[test] +fn attrs() { + pin_project! { + /// dox1 + #[derive(Clone)] + #[project = StructProj] + #[project_ref = StructProjRef] + /// dox2 + #[derive(Debug)] + /// dox3 + struct Struct { + // TODO + // /// dox4 + f: () + } + } + + pin_project! { + #[project = Enum1Proj] + #[project_ref = Enum1ProjRef] + enum Enum1 { + #[cfg(not(any()))] + V { + f: () + }, + } + } + + pin_project! { + /// dox1 + #[derive(Clone)] + #[project(!Unpin)] + #[project = Enum2Proj] + #[project_ref = Enum2ProjRef] + /// dox2 + #[derive(Debug)] + /// dox3 + enum Enum2 { + /// dox4 + V1 { + // TODO + // /// dox5 + f: () + }, + /// dox6 + V2, + } + } +} + +#[test] +fn pinned_drop() { + pin_project! { + pub struct Struct1<'a> { + was_dropped: &'a mut bool, + #[pin] + field: u8, + } + impl PinnedDrop for Struct1<'_> { + fn drop(this: Pin<&mut Self>) { + **this.project().was_dropped = true; + } + } + } + + let mut was_dropped = false; + drop(Struct1 { was_dropped: &mut was_dropped, field: 42 }); + assert!(was_dropped); + + pin_project! { + pub struct Struct2<'a> { + was_dropped: &'a mut bool, + #[pin] + field: u8, + } + impl PinnedDrop for Struct2<'_> { + fn drop(mut this: Pin<&mut Self>) { + **this.as_mut().project().was_dropped = true; + } + } + } + + trait Service { + type Error; + } + + pin_project! { + struct Struct3<'a, T, Request> + where + T: Service, + T::Error: std::error::Error, + { + was_dropped: &'a mut bool, + #[pin] + field: T, + req: Request, + } + + /// dox1 + impl PinnedDrop for Struct3<'_, T, Request> + where + T: Service, + T::Error: std::error::Error, + { + /// dox2 + fn drop(mut this: Pin<&mut Self>) { + **this.as_mut().project().was_dropped = true; + } + } + } +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.rs new file mode 100644 index 00000000..870059d6 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.rs @@ -0,0 +1,15 @@ +use pin_project_lite::pin_project; + +pin_project! { //~ ERROR E0119 + struct Foo { + #[pin] + future: T, + field: U, + } +} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.stderr new file mode 100644 index 00000000..8c870d75 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-drop.stderr @@ -0,0 +1,16 @@ +error[E0119]: conflicting implementations of trait `MustNotImplDrop` for type `Foo<_, _>` + --> tests/ui/pin_project/conflict-drop.rs:3:1 + | +3 | / pin_project! { //~ ERROR E0119 +4 | | struct Foo { +5 | | #[pin] +6 | | future: T, +7 | | field: U, +8 | | } +9 | | } + | | ^ + | | | + | |_first implementation here + | conflicting implementation for `Foo<_, _>` + | + = note: this error originates in the macro `$crate::__pin_project_make_drop_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.rs new file mode 100644 index 00000000..bdab20fc --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.rs @@ -0,0 +1,64 @@ +use pin_project_lite::pin_project; + +// The same implementation. + +pin_project! { //~ ERROR E0119 + struct Foo { + #[pin] + future: T, + field: U, + } +} + +// conflicting implementations +impl Unpin for Foo where T: Unpin {} // Conditional Unpin impl + +// The implementation that under different conditions. + +pin_project! { //~ ERROR E0119 + struct Bar { + #[pin] + future: T, + field: U, + } +} + +// conflicting implementations +impl Unpin for Bar {} // Non-conditional Unpin impl + +pin_project! { //~ ERROR E0119 + struct Baz { + #[pin] + future: T, + field: U, + } +} + +// conflicting implementations +impl Unpin for Baz {} // Conditional Unpin impl + +pin_project! { //~ ERROR E0119 + #[project(!Unpin)] + struct Qux { + #[pin] + future: T, + field: U, + } +} + +// conflicting implementations +impl Unpin for Qux {} // Non-conditional Unpin impl + +pin_project! { //~ ERROR E0119 + #[project(!Unpin)] + struct Fred { + #[pin] + future: T, + field: U, + } +} + +// conflicting implementations +impl Unpin for Fred {} // Conditional Unpin impl + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.stderr new file mode 100644 index 00000000..cf9818e0 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/conflict-unpin.stderr @@ -0,0 +1,84 @@ +error[E0119]: conflicting implementations of trait `Unpin` for type `Foo<_, _>` + --> tests/ui/pin_project/conflict-unpin.rs:5:1 + | +5 | / pin_project! { //~ ERROR E0119 +6 | | struct Foo { +7 | | #[pin] +8 | | future: T, +9 | | field: U, +10 | | } +11 | | } + | |_^ conflicting implementation for `Foo<_, _>` +... +14 | impl Unpin for Foo where T: Unpin {} // Conditional Unpin impl + | ------------------------------ first implementation here + | + = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `Unpin` for type `Bar<_, _>` + --> tests/ui/pin_project/conflict-unpin.rs:18:1 + | +18 | / pin_project! { //~ ERROR E0119 +19 | | struct Bar { +20 | | #[pin] +21 | | future: T, +22 | | field: U, +23 | | } +24 | | } + | |_^ conflicting implementation for `Bar<_, _>` +... +27 | impl Unpin for Bar {} // Non-conditional Unpin impl + | ------------------------------ first implementation here + | + = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `Unpin` for type `Baz<_, _>` + --> tests/ui/pin_project/conflict-unpin.rs:29:1 + | +29 | / pin_project! { //~ ERROR E0119 +30 | | struct Baz { +31 | | #[pin] +32 | | future: T, +33 | | field: U, +34 | | } +35 | | } + | |_^ conflicting implementation for `Baz<_, _>` +... +38 | impl Unpin for Baz {} // Conditional Unpin impl + | -------------------------------------------- first implementation here + | + = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `Unpin` for type `Qux<_, _>` + --> tests/ui/pin_project/conflict-unpin.rs:40:1 + | +40 | / pin_project! { //~ ERROR E0119 +41 | | #[project(!Unpin)] +42 | | struct Qux { +43 | | #[pin] +... | +46 | | } +47 | | } + | |_^ conflicting implementation for `Qux<_, _>` +... +50 | impl Unpin for Qux {} // Non-conditional Unpin impl + | ------------------------------ first implementation here + | + = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0119]: conflicting implementations of trait `Unpin` for type `Fred<_, _>` + --> tests/ui/pin_project/conflict-unpin.rs:52:1 + | +52 | / pin_project! { //~ ERROR E0119 +53 | | #[project(!Unpin)] +54 | | struct Fred { +55 | | #[pin] +... | +58 | | } +59 | | } + | |_^ conflicting implementation for `Fred<_, _>` +... +62 | impl Unpin for Fred {} // Conditional Unpin impl + | --------------------------------------------- first implementation here + | + = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.rs new file mode 100644 index 00000000..64b397a3 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.rs @@ -0,0 +1,93 @@ +use pin_project_lite::pin_project; + +pin_project! { + struct Generics1 { //~ ERROR no rules expected the token `:` + field: T, + } +} + +pin_project! { + struct Generics2 { //~ ERROR no rules expected the token `:` + field: T, + } +} + +pin_project! { + struct Generics3 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` + field: T, + } +} + +pin_project! { + struct Generics4 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` + field: T, + } +} + +pin_project! { + struct Generics5 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` + field: T, + } +} + +pin_project! { + struct Generics6 { //~ ERROR no rules expected the token `Sized` + field: T, + } +} + +pin_project! { + struct WhereClause1 + where + T: 'static : Sized //~ ERROR no rules expected the token `:` + { + field: T, + } +} + +pin_project! { + struct WhereClause2 + where + T: 'static : ?Sized //~ ERROR no rules expected the token `:` + { + field: T, + } +} + +pin_project! { + struct WhereClause3 + where + T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` + { + field: T, + } +} + +pin_project! { + struct WhereClause4 + where + T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` + { + field: T, + } +} + +pin_project! { + struct WhereClause5 + where + T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:` + { + field: T, + } +} + +pin_project! { + struct WhereClause6 + where + T: ?Sized : Sized //~ ERROR no rules expected the token `Sized` + { + field: T, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.stderr new file mode 100644 index 00000000..ae15b7a3 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid-bounds.stderr @@ -0,0 +1,470 @@ +error: no rules expected the token `:` + --> tests/ui/pin_project/invalid-bounds.rs:4:33 + | +4 | struct Generics1 { //~ ERROR no rules expected the token `:` + | ^ no rules expected this token in macro call + | +note: while trying to match `>` + --> src/lib.rs + | + | >)? + | ^ + +error: no rules expected the token `:` + --> tests/ui/pin_project/invalid-bounds.rs:10:33 + | +10 | struct Generics2 { //~ ERROR no rules expected the token `:` + | ^ no rules expected this token in macro call + | +note: while trying to match `>` + --> src/lib.rs + | + | >)? + | ^ + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:15:1 + | +15 | / pin_project! { +16 | | struct Generics3 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +17 | | field: T, +18 | | } +19 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:15:1 + | +15 | / pin_project! { +16 | | struct Generics3 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +17 | | field: T, +18 | | } +19 | | } + | | ^ + | | | + | |_expected one of `+`, `,`, `=`, or `>` + | unexpected token + | + = note: type ascription syntax has been removed, see issue #101728 + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:15:1 + | +15 | / pin_project! { +16 | | struct Generics3 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +17 | | field: T, +18 | | } +19 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:15:1 + | +15 | / pin_project! { +16 | | struct Generics3 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +17 | | field: T, +18 | | } +19 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:21:1 + | +21 | / pin_project! { +22 | | struct Generics4 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +23 | | field: T, +24 | | } +25 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:21:1 + | +21 | / pin_project! { +22 | | struct Generics4 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +23 | | field: T, +24 | | } +25 | | } + | | ^ + | | | + | |_expected one of `+`, `,`, `=`, or `>` + | unexpected token + | + = note: type ascription syntax has been removed, see issue #101728 + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:21:1 + | +21 | / pin_project! { +22 | | struct Generics4 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +23 | | field: T, +24 | | } +25 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:21:1 + | +21 | / pin_project! { +22 | | struct Generics4 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +23 | | field: T, +24 | | } +25 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:27:1 + | +27 | / pin_project! { +28 | | struct Generics5 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +29 | | field: T, +30 | | } +31 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:27:1 + | +27 | / pin_project! { +28 | | struct Generics5 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +29 | | field: T, +30 | | } +31 | | } + | | ^ + | | | + | |_expected one of `+`, `,`, `=`, or `>` + | unexpected token + | + = note: type ascription syntax has been removed, see issue #101728 + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:27:1 + | +27 | / pin_project! { +28 | | struct Generics5 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +29 | | field: T, +30 | | } +31 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, `=`, or `>`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:27:1 + | +27 | / pin_project! { +28 | | struct Generics5 { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:` +29 | | field: T, +30 | | } +31 | | } + | | ^ + | | | + | | expected one of `+`, `,`, `=`, or `>` + | |_unexpected token + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: no rules expected the token `Sized` + --> tests/ui/pin_project/invalid-bounds.rs:34:34 + | +34 | struct Generics6 { //~ ERROR no rules expected the token `Sized` + | ^^^^^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$generics_lifetime_bound:lifetime` + --> src/lib.rs + | + | $(: $generics_lifetime_bound:lifetime)? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: no rules expected the token `:` + --> tests/ui/pin_project/invalid-bounds.rs:42:20 + | +42 | T: 'static : Sized //~ ERROR no rules expected the token `:` + | ^ no rules expected this token in macro call + | +note: while trying to match `{` + --> src/lib.rs + | + | { + | ^ + +error: no rules expected the token `:` + --> tests/ui/pin_project/invalid-bounds.rs:51:20 + | +51 | T: 'static : ?Sized //~ ERROR no rules expected the token `:` + | ^ no rules expected this token in macro call + | +note: while trying to match `{` + --> src/lib.rs + | + | { + | ^ + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:57:1 + | +57 | / pin_project! { +58 | | struct WhereClause3 +59 | | where +60 | | T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +63 | | } +64 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, or `{`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:57:1 + | +57 | / pin_project! { +58 | | struct WhereClause3 +59 | | where +60 | | T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +63 | | } +64 | | } + | | ^ + | | | + | |_expected one of `+`, `,`, or `{` + | unexpected token + | + = note: type ascription syntax has been removed, see issue #101728 + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:57:1 + | +57 | / pin_project! { +58 | | struct WhereClause3 +59 | | where +60 | | T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +63 | | } +64 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:57:1 + | +57 | / pin_project! { +58 | | struct WhereClause3 +59 | | where +60 | | T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +63 | | } +64 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:66:1 + | +66 | / pin_project! { +67 | | struct WhereClause4 +68 | | where +69 | | T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +72 | | } +73 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, or `{`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:66:1 + | +66 | / pin_project! { +67 | | struct WhereClause4 +68 | | where +69 | | T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +72 | | } +73 | | } + | | ^ + | | | + | |_expected one of `+`, `,`, or `{` + | unexpected token + | + = note: type ascription syntax has been removed, see issue #101728 + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:66:1 + | +66 | / pin_project! { +67 | | struct WhereClause4 +68 | | where +69 | | T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +72 | | } +73 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:66:1 + | +66 | / pin_project! { +67 | | struct WhereClause4 +68 | | where +69 | | T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +72 | | } +73 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:75:1 + | +75 | / pin_project! { +76 | | struct WhereClause5 +77 | | where +78 | | T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +81 | | } +82 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `+`, `,`, or `{`, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:75:1 + | +75 | / pin_project! { +76 | | struct WhereClause5 +77 | | where +78 | | T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +81 | | } +82 | | } + | | ^ + | | | + | |_expected one of `+`, `,`, or `{` + | unexpected token + | + = note: type ascription syntax has been removed, see issue #101728 + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:75:1 + | +75 | / pin_project! { +76 | | struct WhereClause5 +77 | | where +78 | | T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +81 | | } +82 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected `{` after struct name, found `:` + --> tests/ui/pin_project/invalid-bounds.rs:75:1 + | +75 | / pin_project! { +76 | | struct WhereClause5 +77 | | where +78 | | T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:` +... | +81 | | } +82 | | } + | | ^ + | | | + | |_expected `{` after struct name + | in this macro invocation + | + = note: this error originates in the macro `$crate::__pin_project_parse_generics` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: no rules expected the token `Sized` + --> tests/ui/pin_project/invalid-bounds.rs:87:21 + | +87 | T: ?Sized : Sized //~ ERROR no rules expected the token `Sized` + | ^^^^^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$where_clause_lifetime_bound:lifetime` + --> src/lib.rs + | + | $(: $where_clause_lifetime_bound:lifetime)? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.rs new file mode 100644 index 00000000..e0ea61d4 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.rs @@ -0,0 +1,25 @@ +use pin_project_lite::pin_project; + +pin_project! { + struct A { + #[pin()] //~ ERROR no rules expected the token `(` + pinned: T, + } +} + +pin_project! { + #[pin] //~ ERROR cannot find attribute `pin` in this scope + struct B { + pinned: T, + } +} + +pin_project! { + struct C { + #[pin] + #[pin] //~ ERROR no rules expected the token `#` + pinned: T, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.stderr new file mode 100644 index 00000000..5d2e305c --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/invalid.stderr @@ -0,0 +1,53 @@ +error: no rules expected the token `(` + --> tests/ui/pin_project/invalid.rs:5:14 + | +5 | #[pin()] //~ ERROR no rules expected the token `(` + | ^ no rules expected this token in macro call + | +note: while trying to match `]` + --> src/lib.rs + | + | $(#[$pin:ident])? + | ^ + +error: no rules expected the token `(` + --> tests/ui/pin_project/invalid.rs:5:14 + | +5 | #[pin()] //~ ERROR no rules expected the token `(` + | ^ no rules expected this token in macro call + | +note: while trying to match `]` + --> src/lib.rs + | + | $(#[$pin:ident])? + | ^ + +error: no rules expected the token `#` + --> tests/ui/pin_project/invalid.rs:20:9 + | +20 | #[pin] //~ ERROR no rules expected the token `#` + | ^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$field_vis:vis` + --> src/lib.rs + | + | $field_vis:vis $field:ident: $field_ty:ty + | ^^^^^^^^^^^^^^ + +error: no rules expected the token `#` + --> tests/ui/pin_project/invalid.rs:20:9 + | +20 | #[pin] //~ ERROR no rules expected the token `#` + | ^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$field_vis:vis` + --> src/lib.rs + | + | $field_vis:vis $field:ident: $field_ty:ty + | ^^^^^^^^^^^^^^ + +error: cannot find attribute `pin` in this scope + --> tests/ui/pin_project/invalid.rs:11:7 + | +11 | #[pin] //~ ERROR cannot find attribute `pin` in this scope + | ^^^ diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.rs new file mode 100644 index 00000000..117c18d7 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.rs @@ -0,0 +1,10 @@ +use pin_project_lite::pin_project; + +pin_project! { //~ ERROR E0263,E0496 + pub struct Foo<'__pin, T> { + #[pin] + field: &'__pin mut T, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.stderr new file mode 100644 index 00000000..cfdffb2c --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_lifetime_names.stderr @@ -0,0 +1,75 @@ +error[E0403]: the name `'__pin` is already used for a generic parameter in this item's generic parameters + --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20 + | +3 | / pin_project! { //~ ERROR E0263,E0496 +4 | | pub struct Foo<'__pin, T> { + | | ^^^^^^ already used +5 | | #[pin] +6 | | field: &'__pin mut T, +7 | | } +8 | | } + | |_- first use of `'__pin` + +error[E0403]: the name `'__pin` is already used for a generic parameter in this item's generic parameters + --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20 + | +3 | / pin_project! { //~ ERROR E0263,E0496 +4 | | pub struct Foo<'__pin, T> { + | | ^^^^^^ already used +5 | | #[pin] +6 | | field: &'__pin mut T, +7 | | } +8 | | } + | |_- first use of `'__pin` + +error[E0496]: lifetime name `'__pin` shadows a lifetime name that is already in scope + --> tests/ui/pin_project/overlapping_lifetime_names.rs:3:1 + | +3 | / pin_project! { //~ ERROR E0263,E0496 +4 | | pub struct Foo<'__pin, T> { + | | ------ first declared here +5 | | #[pin] +6 | | field: &'__pin mut T, +7 | | } +8 | | } + | |_^ lifetime `'__pin` already in scope + | + = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0496]: lifetime name `'__pin` shadows a lifetime name that is already in scope + --> tests/ui/pin_project/overlapping_lifetime_names.rs:3:1 + | +3 | / pin_project! { //~ ERROR E0263,E0496 +4 | | pub struct Foo<'__pin, T> { + | | ------ first declared here +5 | | #[pin] +6 | | field: &'__pin mut T, +7 | | } +8 | | } + | |_^ lifetime `'__pin` already in scope + | + = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0403]: the name `'__pin` is already used for a generic parameter in this item's generic parameters + --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20 + | +3 | / pin_project! { //~ ERROR E0263,E0496 +4 | | pub struct Foo<'__pin, T> { + | | ^^^^^^ already used +5 | | #[pin] +6 | | field: &'__pin mut T, +7 | | } +8 | | } + | |_- first use of `'__pin` + +error[E0403]: the name `'__pin` is already used for a generic parameter in this item's generic parameters + --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20 + | +3 | / pin_project! { //~ ERROR E0263,E0496 +4 | | pub struct Foo<'__pin, T> { + | | ^^^^^^ already used +5 | | #[pin] +6 | | field: &'__pin mut T, +7 | | } +8 | | } + | |_- first use of `'__pin` diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.rs new file mode 100644 index 00000000..25131d17 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.rs @@ -0,0 +1,20 @@ +use std::marker::PhantomPinned; + +use pin_project_lite::pin_project; + +pin_project! { + struct Foo { + #[pin] + inner: T, + } +} + +struct __Origin {} + +impl Unpin for __Origin {} + +fn is_unpin() {} + +fn main() { + is_unpin::>(); //~ ERROR E0277 +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.stderr new file mode 100644 index 00000000..fd7d64f1 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/overlapping_unpin_struct.stderr @@ -0,0 +1,34 @@ +error[E0277]: `PhantomPinned` cannot be unpinned + --> tests/ui/pin_project/overlapping_unpin_struct.rs:19:16 + | +19 | is_unpin::>(); //~ ERROR E0277 + | ^^^^^^^^^^^^^^^^^^ within `_::__Origin<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +note: required because it appears within the type `__Origin<'_, PhantomPinned>` + --> tests/ui/pin_project/overlapping_unpin_struct.rs:5:1 + | +5 | / pin_project! { +6 | | struct Foo { +7 | | #[pin] +8 | | inner: T, +9 | | } +10 | | } + | |_^ +note: required for `Foo` to implement `Unpin` + --> tests/ui/pin_project/overlapping_unpin_struct.rs:5:1 + | +5 | / pin_project! { +6 | | struct Foo { +7 | | #[pin] +8 | | inner: T, +9 | | } +10 | | } + | |_^ unsatisfied trait bound introduced here +note: required by a bound in `is_unpin` + --> tests/ui/pin_project/overlapping_unpin_struct.rs:16:16 + | +16 | fn is_unpin() {} + | ^^^^^ required by this bound in `is_unpin` + = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.rs new file mode 100644 index 00000000..507a0385 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.rs @@ -0,0 +1,19 @@ +use pin_project_lite::pin_project; + +pin_project! { //~ ERROR reference to packed field is unaligned + #[repr(packed, C)] + struct Packed { + #[pin] + field: u16, + } +} + +pin_project! { //~ ERROR reference to packed field is unaligned + #[repr(packed(2))] + struct PackedN { + #[pin] + field: u32, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.stderr new file mode 100644 index 00000000..710ec08e --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/packed.stderr @@ -0,0 +1,101 @@ +error[E0793]: reference to packed field is unaligned + --> tests/ui/pin_project/packed.rs:3:1 + | +3 | / pin_project! { //~ ERROR reference to packed field is unaligned +4 | | #[repr(packed, C)] +5 | | struct Packed { +6 | | #[pin] +7 | | field: u16, +8 | | } +9 | | } + | |_^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0793]: reference to packed field is unaligned + --> tests/ui/pin_project/packed.rs:3:1 + | +3 | / pin_project! { //~ ERROR reference to packed field is unaligned +4 | | #[repr(packed, C)] +5 | | struct Packed { +6 | | #[pin] +7 | | field: u16, +8 | | } +9 | | } + | |_^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0793]: reference to packed field is unaligned + --> tests/ui/pin_project/packed.rs:3:1 + | +3 | / pin_project! { //~ ERROR reference to packed field is unaligned +4 | | #[repr(packed, C)] +5 | | struct Packed { +6 | | #[pin] +7 | | field: u16, +8 | | } +9 | | } + | |_^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::__pin_project_constant` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0793]: reference to packed field is unaligned + --> tests/ui/pin_project/packed.rs:11:1 + | +11 | / pin_project! { //~ ERROR reference to packed field is unaligned +12 | | #[repr(packed(2))] +13 | | struct PackedN { +14 | | #[pin] +15 | | field: u32, +16 | | } +17 | | } + | |_^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0793]: reference to packed field is unaligned + --> tests/ui/pin_project/packed.rs:11:1 + | +11 | / pin_project! { //~ ERROR reference to packed field is unaligned +12 | | #[repr(packed(2))] +13 | | struct PackedN { +14 | | #[pin] +15 | | field: u32, +16 | | } +17 | | } + | |_^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0793]: reference to packed field is unaligned + --> tests/ui/pin_project/packed.rs:11:1 + | +11 | / pin_project! { //~ ERROR reference to packed field is unaligned +12 | | #[repr(packed(2))] +13 | | struct PackedN { +14 | | #[pin] +15 | | field: u32, +16 | | } +17 | | } + | |_^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::__pin_project_constant` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.rs new file mode 100644 index 00000000..984cc2a2 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.rs @@ -0,0 +1,12 @@ +use pin_project_lite::pin_project; + +pin_project! { + struct Foo { + #[pin] + inner: u8, + } +} + +impl Unpin for __Origin {} //~ ERROR E0412,E0321 + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.stderr new file mode 100644 index 00000000..aadd1f97 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unpin_sneaky.stderr @@ -0,0 +1,5 @@ +error[E0412]: cannot find type `__Origin` in this scope + --> tests/ui/pin_project/unpin_sneaky.rs:10:16 + | +10 | impl Unpin for __Origin {} //~ ERROR E0412,E0321 + | ^^^^^^^^ not found in this scope diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.rs new file mode 100644 index 00000000..2f808362 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.rs @@ -0,0 +1,27 @@ +use pin_project_lite::pin_project; + +pin_project! { + struct Struct1 {} //~ ERROR no rules expected the token `}` +} + +pin_project! { + struct Struct2(); //~ ERROR no rules expected the token `(` +} + +pin_project! { + struct Struct3; //~ ERROR no rules expected the token `;` +} + +pin_project! { + enum Enum { //~ ERROR no rules expected the token `enum` + A(u8) + } +} + +pin_project! { + union Union { //~ ERROR no rules expected the token `union` + x: u8, + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.stderr new file mode 100644 index 00000000..f1d3b9c9 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pin_project/unsupported.stderr @@ -0,0 +1,115 @@ +error: no rules expected the token `}` + --> tests/ui/pin_project/unsupported.rs:3:1 + | +3 | / pin_project! { +4 | | struct Struct1 {} //~ ERROR no rules expected the token `}` +5 | | } + | |_^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$field_vis:vis` + --> src/lib.rs + | + | $field_vis:vis $field:ident: $field_ty:ty + | ^^^^^^^^^^^^^^ + = note: this error originates in the macro `$crate::__pin_project_expand` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: no rules expected the token `}` + --> tests/ui/pin_project/unsupported.rs:3:1 + | +3 | / pin_project! { +4 | | struct Struct1 {} //~ ERROR no rules expected the token `}` +5 | | } + | |_^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$field_vis:vis` + --> src/lib.rs + | + | $field_vis:vis $field:ident: $field_ty:ty + | ^^^^^^^^^^^^^^ + = note: this error originates in the macro `$crate::__pin_project_expand` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: no rules expected the token `(` + --> tests/ui/pin_project/unsupported.rs:8:19 + | +8 | struct Struct2(); //~ ERROR no rules expected the token `(` + | ^ no rules expected this token in macro call + | +note: while trying to match `{` + --> src/lib.rs + | + | { + | ^ + +error: no rules expected the token `;` + --> tests/ui/pin_project/unsupported.rs:12:19 + | +12 | struct Struct3; //~ ERROR no rules expected the token `;` + | ^ no rules expected this token in macro call + | +note: while trying to match `{` + --> src/lib.rs + | + | { + | ^ + +error: no rules expected the token `(` + --> tests/ui/pin_project/unsupported.rs:17:10 + | +17 | A(u8) + | ^ no rules expected this token in macro call + | +note: while trying to match `}` + --> src/lib.rs + | + | } + | ^ + +error: no rules expected the token `(` + --> tests/ui/pin_project/unsupported.rs:17:10 + | +17 | A(u8) + | ^ no rules expected this token in macro call + | +note: while trying to match `}` + --> src/lib.rs + | + | } + | ^ + +error: no rules expected the token `union` + --> tests/ui/pin_project/unsupported.rs:21:1 + | +21 | / pin_project! { +22 | | union Union { //~ ERROR no rules expected the token `union` +23 | | x: u8, +24 | | } +25 | | } + | |_^ no rules expected this token in macro call + | +note: while trying to match `struct` + --> src/lib.rs + | + | [$(#[$attrs:meta])* $vis:vis struct $ident:ident] + | ^^^^^^ + = note: captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens + = note: see for more information + = note: this error originates in the macro `$crate::__pin_project_expand` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: no rules expected the token `union` + --> tests/ui/pin_project/unsupported.rs:21:1 + | +21 | / pin_project! { +22 | | union Union { //~ ERROR no rules expected the token `union` +23 | | x: u8, +24 | | } +25 | | } + | |_^ no rules expected this token in macro call + | +note: while trying to match `struct` + --> src/lib.rs + | + | [$(#[$attrs:meta])* $vis:vis struct $ident:ident] + | ^^^^^^ + = note: captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens + = note: see for more information + = note: this error originates in the macro `$crate::__pin_project_expand` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.rs new file mode 100644 index 00000000..609b3beb --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.rs @@ -0,0 +1,17 @@ +use pin_project_lite::pin_project; + +pin_project! { + pub struct S { + #[pin] + field: u8, + } + impl PinnedDrop for S { + fn drop(this: Pin<&mut Self>) { + __drop_inner(this); + } + } +} + +fn main() { + let _x = S { field: 0 }; +} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.stderr new file mode 100644 index 00000000..a6226216 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/call-drop-inner.stderr @@ -0,0 +1,21 @@ +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> tests/ui/pinned_drop/call-drop-inner.rs:10:13 + | +10 | __drop_inner(this); + | ^^^^^^^^^^^^ ---- + | | + | unexpected argument of type `Pin<&mut S>` + | help: remove the extra argument + | +note: function defined here + --> tests/ui/pinned_drop/call-drop-inner.rs:3:1 + | +3 | / pin_project! { +4 | | pub struct S { +5 | | #[pin] +6 | | field: u8, +... | +12 | | } +13 | | } + | |_^ + = note: this error originates in the macro `$crate::__pin_project_make_drop_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.rs b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.rs new file mode 100644 index 00000000..68b01b26 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.rs @@ -0,0 +1,26 @@ +use pin_project_lite::pin_project; + +// In `Drop` impl, the implementor must specify the same requirement as type definition. + +struct DropImpl { + f: T, +} + +impl Drop for DropImpl { + //~^ ERROR E0367 + fn drop(&mut self) {} +} + +pin_project! { + //~^ ERROR E0367 + struct PinnedDropImpl { + #[pin] + f: T, + } + + impl PinnedDrop for PinnedDropImpl { + fn drop(_this: Pin<&mut Self>) {} + } +} + +fn main() {} diff --git a/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.stderr b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.stderr new file mode 100644 index 00000000..fe0ee79d --- /dev/null +++ b/utshell-0.5.0/vendor/pin-project-lite/tests/ui/pinned_drop/conditional-drop-impl.stderr @@ -0,0 +1,36 @@ +error[E0367]: `Drop` impl requires `T: Unpin` but the struct it is implemented for does not + --> tests/ui/pinned_drop/conditional-drop-impl.rs:9:9 + | +9 | impl Drop for DropImpl { + | ^^^^^ + | +note: the implementor must specify the same requirement + --> tests/ui/pinned_drop/conditional-drop-impl.rs:5:1 + | +5 | struct DropImpl { + | ^^^^^^^^^^^^^^^^^^ + +error[E0367]: `Drop` impl requires `T: Unpin` but the struct it is implemented for does not + --> tests/ui/pinned_drop/conditional-drop-impl.rs:14:1 + | +14 | / pin_project! { +15 | | //~^ ERROR E0367 +16 | | struct PinnedDropImpl { +17 | | #[pin] +... | +23 | | } +24 | | } + | |_^ + | +note: the implementor must specify the same requirement + --> tests/ui/pinned_drop/conditional-drop-impl.rs:14:1 + | +14 | / pin_project! { +15 | | //~^ ERROR E0367 +16 | | struct PinnedDropImpl { +17 | | #[pin] +... | +23 | | } +24 | | } + | |_^ + = note: this error originates in the macro `$crate::__pin_project_make_drop_impl` which comes from the expansion of the macro `pin_project` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/pin-utils/.cargo-checksum.json b/utshell-0.5.0/vendor/pin-utils/.cargo-checksum.json new file mode 100644 index 00000000..97116594 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"0f8296bda5b928d57bb84443422f21db3aa35d6873ce651297634d80c183dc6b","LICENSE-APACHE":"a4db788775cb25f2da419a7ccd3f1f89c3d2cfa8748fb25257596b88183b4c77","LICENSE-MIT":"28802412d2bfbafe432b305634413b41a984d30fba0df41d30aa2c8a2077c5b1","README.md":"1b0cfd43afdfb6bb718a65f9fa9954b8de3a2638f155ee021465b35f0ae98336","src/lib.rs":"bed1d1c013f78036a7288ac3ebbe07c097d9a5a435b1367085484529d784b4e0","src/projection.rs":"18dbf1a747c3c4eec31768a51e1cfbce2ec83dc80dc44a5a80bb67b21ac5715d","src/stack_pin.rs":"b79661dc21f5ab923d75e3ddb52d43faf68fba7c7d592ec1929d1fd5275d70d8","tests/projection.rs":"04dd66b306e9d43d01a181da38add1ae8b8dee9e1fd16a3a0f39571cbb467f62","tests/stack_pin.rs":"2b2245ef1fb99176dd7fef74601fe6b69d394831e20dcdbd73268b34e17ce032"},"package":"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/pin-utils/Cargo.toml b/utshell-0.5.0/vendor/pin-utils/Cargo.toml new file mode 100644 index 00000000..5e2f779d --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/Cargo.toml @@ -0,0 +1,22 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "pin-utils" +version = "0.1.0" +authors = ["Josef Brandl "] +description = "Utilities for pinning\n" +documentation = "https://docs.rs/pin-utils" +readme = "README.md" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang-nursery/pin-utils" diff --git a/utshell-0.5.0/vendor/pin-utils/LICENSE-APACHE b/utshell-0.5.0/vendor/pin-utils/LICENSE-APACHE new file mode 100644 index 00000000..66ccceda --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2018 The pin-utils authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/pin-utils/LICENSE-MIT b/utshell-0.5.0/vendor/pin-utils/LICENSE-MIT new file mode 100644 index 00000000..06e51c42 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2018 The pin-utils authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/pin-utils/README.md b/utshell-0.5.0/vendor/pin-utils/README.md new file mode 100644 index 00000000..93fdeb6f --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/README.md @@ -0,0 +1,42 @@ +# pin-utils + +Utilities for pinning + +[![Build Status](https://travis-ci.com/rust-lang-nursery/pin-utils.svg?branch=master)](https://travis-ci.com/rust-lang-nursery/pin-utils) +[![Crates.io](https://img.shields.io/crates/v/pin-utils.svg)](https://crates.io/crates/pin-utils) + +[Documentation](https://docs.rs/pin-utils) + +## Usage + +First, add this to your `Cargo.toml`: + +```toml +[dependencies] +pin-utils = "0.1.0-alpha.4" +``` + +Now, you can use it: + +```rust +use pin_utils::pin_mut; // And more... +``` + +The current version of pin-utils requires Rust 1.33 or later. + +# License + +This project is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in pin-utils by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/utshell-0.5.0/vendor/pin-utils/src/lib.rs b/utshell-0.5.0/vendor/pin-utils/src/lib.rs new file mode 100644 index 00000000..6198e982 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/src/lib.rs @@ -0,0 +1,17 @@ +//! Utilities for pinning + +#![no_std] +#![warn(missing_docs, missing_debug_implementations)] +#![deny(bare_trait_objects)] +#![allow(unknown_lints)] +#![doc(html_root_url = "https://docs.rs/pin-utils/0.1.0")] + +#[doc(hidden)] +pub mod core_reexport { + pub use core::*; +} + +#[macro_use] +mod stack_pin; +#[macro_use] +mod projection; diff --git a/utshell-0.5.0/vendor/pin-utils/src/projection.rs b/utshell-0.5.0/vendor/pin-utils/src/projection.rs new file mode 100644 index 00000000..6af90c56 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/src/projection.rs @@ -0,0 +1,100 @@ +/// A pinned projection of a struct field. +/// +/// # Safety +/// +/// To make using this macro safe, three things need to be ensured: +/// - If the struct implements [`Drop`], the [`drop`] method is not allowed to +/// move the value of the field. +/// - If the struct wants to implement [`Unpin`], it has to do so conditionally: +/// The struct can only implement [`Unpin`] if the field's type is [`Unpin`]. +/// - The struct must not be `#[repr(packed)]`. +/// +/// # Example +/// +/// ```rust +/// use pin_utils::unsafe_pinned; +/// use std::marker::Unpin; +/// use std::pin::Pin; +/// +/// struct Foo { +/// field: T, +/// } +/// +/// impl Foo { +/// unsafe_pinned!(field: T); +/// +/// fn baz(mut self: Pin<&mut Self>) { +/// let _: Pin<&mut T> = self.field(); // Pinned reference to the field +/// } +/// } +/// +/// impl Unpin for Foo {} // Conditional Unpin impl +/// ``` +/// +/// Note: borrowing the field multiple times requires using `.as_mut()` to +/// avoid consuming the `Pin`. +/// +/// [`Unpin`]: core::marker::Unpin +/// [`drop`]: Drop::drop +#[macro_export] +macro_rules! unsafe_pinned { + ($f:tt: $t:ty) => ( + #[allow(unsafe_code)] + fn $f<'__a>( + self: $crate::core_reexport::pin::Pin<&'__a mut Self> + ) -> $crate::core_reexport::pin::Pin<&'__a mut $t> { + unsafe { + $crate::core_reexport::pin::Pin::map_unchecked_mut( + self, |x| &mut x.$f + ) + } + } + ) +} + +/// An unpinned projection of a struct field. +/// +/// # Safety +/// +/// This macro is unsafe because it creates a method that returns a normal +/// non-pin reference to the struct field. It is up to the programmer to ensure +/// that the contained value can be considered not pinned in the current +/// context. +/// +/// # Example +/// +/// ```rust +/// use pin_utils::unsafe_unpinned; +/// use std::pin::Pin; +/// +/// struct Bar; +/// struct Foo { +/// field: Bar, +/// } +/// +/// impl Foo { +/// unsafe_unpinned!(field: Bar); +/// +/// fn baz(mut self: Pin<&mut Self>) { +/// let _: &mut Bar = self.field(); // Normal reference to the field +/// } +/// } +/// ``` +/// +/// Note: borrowing the field multiple times requires using `.as_mut()` to +/// avoid consuming the [`Pin`]. +/// +/// [`Pin`]: core::pin::Pin +#[macro_export] +macro_rules! unsafe_unpinned { + ($f:tt: $t:ty) => ( + #[allow(unsafe_code)] + fn $f<'__a>( + self: $crate::core_reexport::pin::Pin<&'__a mut Self> + ) -> &'__a mut $t { + unsafe { + &mut $crate::core_reexport::pin::Pin::get_unchecked_mut(self).$f + } + } + ) +} diff --git a/utshell-0.5.0/vendor/pin-utils/src/stack_pin.rs b/utshell-0.5.0/vendor/pin-utils/src/stack_pin.rs new file mode 100644 index 00000000..8a1ed2c5 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/src/stack_pin.rs @@ -0,0 +1,25 @@ +/// Pins a value on the stack. +/// +/// # Example +/// +/// ```rust +/// # use pin_utils::pin_mut; +/// # use core::pin::Pin; +/// # struct Foo {} +/// let foo = Foo { /* ... */ }; +/// pin_mut!(foo); +/// let _: Pin<&mut Foo> = foo; +/// ``` +#[macro_export] +macro_rules! pin_mut { + ($($x:ident),* $(,)?) => { $( + // Move the value to ensure that it is owned + let mut $x = $x; + // Shadow the original binding so that it can't be directly accessed + // ever again. + #[allow(unused_mut)] + let mut $x = unsafe { + $crate::core_reexport::pin::Pin::new_unchecked(&mut $x) + }; + )* } +} diff --git a/utshell-0.5.0/vendor/pin-utils/tests/projection.rs b/utshell-0.5.0/vendor/pin-utils/tests/projection.rs new file mode 100644 index 00000000..492c26d9 --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/tests/projection.rs @@ -0,0 +1,27 @@ +use pin_utils::{unsafe_pinned, unsafe_unpinned, pin_mut}; +use std::pin::Pin; +use std::marker::Unpin; + +struct Foo { + field1: T1, + field2: T2, +} + +impl Foo { + unsafe_pinned!(field1: T1); + unsafe_unpinned!(field2: T2); +} + +impl Unpin for Foo {} // Conditional Unpin impl + +#[test] +fn projection() { + let foo = Foo { field1: 1, field2: 2 }; + pin_mut!(foo); + + let x1: Pin<&mut i32> = foo.as_mut().field1(); + assert_eq!(*x1, 1); + + let x2: &mut i32 = foo.as_mut().field2(); + assert_eq!(*x2, 2); +} diff --git a/utshell-0.5.0/vendor/pin-utils/tests/stack_pin.rs b/utshell-0.5.0/vendor/pin-utils/tests/stack_pin.rs new file mode 100644 index 00000000..4b6758dc --- /dev/null +++ b/utshell-0.5.0/vendor/pin-utils/tests/stack_pin.rs @@ -0,0 +1,21 @@ +#![forbid(unsafe_code)] // pin_mut! is completely safe. + +use pin_utils::pin_mut; +use core::pin::Pin; + +#[test] +fn stack_pin() { + struct Foo {} + let foo = Foo {}; + pin_mut!(foo); + let _: Pin<&mut Foo> = foo; + + let bar = Foo {}; + let baz = Foo {}; + pin_mut!( + bar, + baz, + ); + let _: Pin<&mut Foo> = bar; + let _: Pin<&mut Foo> = baz; +} diff --git a/utshell-0.5.0/vendor/proc-macro2/.cargo-checksum.json b/utshell-0.5.0/vendor/proc-macro2/.cargo-checksum.json new file mode 100644 index 00000000..9368d276 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"cf58b9b5cd9abb5dca91d4d61809edcf425156bd8e9bb69e0398e00e74aa7af1","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c609b6865476d6c35879784e9155367a97a0da496aa5c3c61488440a20f59883","build.rs":"8b4facae0d125ca3b437b4f5ebcd6ea3da3fcc65fcfc2cf357ae544423aa4568","build/probe.rs":"971fd2178dc506ccdc5c2065c37b77696a4aee8e00330ca52625db4a857f68d3","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"7c3864497cb5298fd5d0e9f5ae5797860338a9a4263220a8e8eabecda1583797","src/fallback.rs":"2e668a1ed90243e6f627a0c85c73c61f5c4107d82e149de5960d806d5eae99f9","src/lib.rs":"ea7a33758942e0911d5545e57b6a726c5bca7960fe3eed58a46b692244ac575a","src/location.rs":"f55d2e61f1bb1af65e14ed04c9e91eb1ddbf8430e8c05f2048d1cd538d27368e","src/marker.rs":"c11c5a1be8bdf18be3fcd224393f350a9aae7ce282e19ce583c84910c6903a8f","src/parse.rs":"4b77cddbc2752bc4d38a65acd8b96b6786c5220d19b1e1b37810257b5d24132d","src/rcvec.rs":"1c3c48c4f819927cc445ae15ca3bb06775feff2fd1cb21901ae4c40c7e6b4e82","src/wrapper.rs":"029fc07e8adbea2dd2a0aab49b07c3fb9cd8bc0539ea85bf9166c46922933742","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"3190ee07dae510251f360db701ce257030f94a479b6689c3a9ef804bd5d8d099","tests/test.rs":"de9163d0b7d53a56de4c3d00acb415785e55c161becfe37b2a0c5d8d1931f14f","tests/test_fmt.rs":"b7743b612af65f2c88cbe109d50a093db7aa7e87f9e37bf45b7bbaeb240aa020","tests/test_size.rs":"acf05963c1e62052d769d237b50844a2c59b4182b491231b099a4f74e5456ab0"},"package":"e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/proc-macro2/Cargo.toml b/utshell-0.5.0/vendor/proc-macro2/Cargo.toml new file mode 100644 index 00000000..65506c21 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/Cargo.toml @@ -0,0 +1,76 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.56" +name = "proc-macro2" +version = "1.0.78" +authors = [ + "David Tolnay ", + "Alex Crichton ", +] +autobenches = false +description = "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case." +documentation = "https://docs.rs/proc-macro2" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = ["development-tools::procedural-macro-helpers"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/proc-macro2" + +[package.metadata.docs.rs] +rustc-args = [ + "--cfg", + "procmacro2_semver_exempt", +] +rustdoc-args = [ + "--cfg", + "procmacro2_semver_exempt", + "--cfg", + "doc_cfg", + "--generate-link-to-definition", +] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = ["span-locations"] + +[lib] +doc-scrape-examples = false + +[dependencies.unicode-ident] +version = "1.0" + +[dev-dependencies.flate2] +version = "1.0" + +[dev-dependencies.quote] +version = "1.0" +default_features = false + +[dev-dependencies.rayon] +version = "1.0" + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.tar] +version = "0.4" + +[features] +default = ["proc-macro"] +nightly = [] +proc-macro = [] +span-locations = [] diff --git a/utshell-0.5.0/vendor/proc-macro2/LICENSE-APACHE b/utshell-0.5.0/vendor/proc-macro2/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/utshell-0.5.0/vendor/proc-macro2/LICENSE-MIT b/utshell-0.5.0/vendor/proc-macro2/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/proc-macro2/README.md b/utshell-0.5.0/vendor/proc-macro2/README.md new file mode 100644 index 00000000..3a29ce8b --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/README.md @@ -0,0 +1,94 @@ +# proc-macro2 + +[github](https://github.com/dtolnay/proc-macro2) +[crates.io](https://crates.io/crates/proc-macro2) +[docs.rs](https://docs.rs/proc-macro2) +[build status](https://github.com/dtolnay/proc-macro2/actions?query=branch%3Amaster) + +A wrapper around the procedural macro API of the compiler's `proc_macro` crate. +This library serves two purposes: + +- **Bring proc-macro-like functionality to other contexts like build.rs and + main.rs.** Types from `proc_macro` are entirely specific to procedural macros + and cannot ever exist in code outside of a procedural macro. Meanwhile + `proc_macro2` types may exist anywhere including non-macro code. By developing + foundational libraries like [syn] and [quote] against `proc_macro2` rather + than `proc_macro`, the procedural macro ecosystem becomes easily applicable to + many other use cases and we avoid reimplementing non-macro equivalents of + those libraries. + +- **Make procedural macros unit testable.** As a consequence of being specific + to procedural macros, nothing that uses `proc_macro` can be executed from a + unit test. In order for helper libraries or components of a macro to be + testable in isolation, they must be implemented using `proc_macro2`. + +[syn]: https://github.com/dtolnay/syn +[quote]: https://github.com/dtolnay/quote + +## Usage + +```toml +[dependencies] +proc-macro2 = "1.0" +``` + +The skeleton of a typical procedural macro typically looks like this: + +```rust +extern crate proc_macro; + +#[proc_macro_derive(MyDerive)] +pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = proc_macro2::TokenStream::from(input); + + let output: proc_macro2::TokenStream = { + /* transform input */ + }; + + proc_macro::TokenStream::from(output) +} +``` + +If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate +parse errors correctly back to the compiler when parsing fails. + +[`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html + +## Unstable features + +The default feature set of proc-macro2 tracks the most recent stable compiler +API. Functionality in `proc_macro` that is not yet stable is not exposed by +proc-macro2 by default. + +To opt into the additional APIs available in the most recent nightly compiler, +the `procmacro2_semver_exempt` config flag must be passed to rustc. We will +polyfill those nightly-only APIs back to Rust 1.56.0. As these are unstable APIs +that track the nightly compiler, minor versions of proc-macro2 may make breaking +changes to them at any time. + +``` +RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build +``` + +Note that this must not only be done for your crate, but for any crate that +depends on your crate. This infectious nature is intentional, as it serves as a +reminder that you are outside of the normal semver guarantees. + +Semver exempt methods are marked as such in the proc-macro2 documentation. + +
+ +#### License + + +Licensed under either of
Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/utshell-0.5.0/vendor/proc-macro2/build.rs b/utshell-0.5.0/vendor/proc-macro2/build.rs new file mode 100644 index 00000000..3347f878 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/build.rs @@ -0,0 +1,202 @@ +// rustc-cfg emitted by the build script: +// +// "wrap_proc_macro" +// Wrap types from libproc_macro rather than polyfilling the whole API. +// Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set, +// because we can't emulate the unstable API without emulating everything +// else. Also enabled unconditionally on nightly, in which case the +// procmacro2_semver_exempt surface area is implemented by using the +// nightly-only proc_macro API. +// +// "hygiene" +// Enable Span::mixed_site() and non-dummy behavior of Span::resolved_at +// and Span::located_at. Enabled on Rust 1.45+. +// +// "proc_macro_span" +// Enable non-dummy behavior of Span::start and Span::end methods which +// requires an unstable compiler feature. Enabled when building with +// nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable +// features. +// +// "super_unstable" +// Implement the semver exempt API in terms of the nightly-only proc_macro +// API. Enabled when using procmacro2_semver_exempt on a nightly compiler. +// +// "span_locations" +// Provide methods Span::start and Span::end which give the line/column +// location of a token. Enabled by procmacro2_semver_exempt or the +// "span-locations" Cargo cfg. This is behind a cfg because tracking +// location inside spans is a performance hit. +// +// "is_available" +// Use proc_macro::is_available() to detect if the proc macro API is +// available or needs to be polyfilled instead of trying to use the proc +// macro API and catching a panic if it isn't available. Enabled on Rust +// 1.57+. + +use std::env; +use std::ffi::OsString; +use std::path::Path; +use std::process::{self, Command, Stdio}; +use std::str; +use std::u32; + +fn main() { + let rustc = rustc_minor_version().unwrap_or(u32::MAX); + + let docs_rs = env::var_os("DOCS_RS").is_some(); + let semver_exempt = cfg!(procmacro2_semver_exempt) || docs_rs; + if semver_exempt { + // https://github.com/dtolnay/proc-macro2/issues/147 + println!("cargo:rustc-cfg=procmacro2_semver_exempt"); + } + + if semver_exempt || cfg!(feature = "span-locations") { + println!("cargo:rustc-cfg=span_locations"); + } + + if rustc < 57 { + println!("cargo:rustc-cfg=no_is_available"); + } + + if rustc < 66 { + println!("cargo:rustc-cfg=no_source_text"); + } + + if !cfg!(feature = "proc-macro") { + println!("cargo:rerun-if-changed=build.rs"); + return; + } + + println!("cargo:rerun-if-changed=build/probe.rs"); + + let proc_macro_span; + let consider_rustc_bootstrap; + if compile_probe(false) { + // This is a nightly or dev compiler, so it supports unstable features + // regardless of RUSTC_BOOTSTRAP. No need to rerun build script if + // RUSTC_BOOTSTRAP is changed. + proc_macro_span = true; + consider_rustc_bootstrap = false; + } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") { + if compile_probe(true) { + // This is a stable or beta compiler for which the user has set + // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build script + // if they change it. + proc_macro_span = true; + consider_rustc_bootstrap = true; + } else if rustc_bootstrap == "1" { + // This compiler does not support the proc macro Span API in the + // form that proc-macro2 expects. No need to pay attention to + // RUSTC_BOOTSTRAP. + proc_macro_span = false; + consider_rustc_bootstrap = false; + } else { + // This is a stable or beta compiler for which RUSTC_BOOTSTRAP is + // set to restrict the use of unstable features by this crate. + proc_macro_span = false; + consider_rustc_bootstrap = true; + } + } else { + // Without RUSTC_BOOTSTRAP, this compiler does not support the proc + // macro Span API in the form that proc-macro2 expects, but try again if + // the user turns on unstable features. + proc_macro_span = false; + consider_rustc_bootstrap = true; + } + + if proc_macro_span || !semver_exempt { + println!("cargo:rustc-cfg=wrap_proc_macro"); + } + + if proc_macro_span { + println!("cargo:rustc-cfg=proc_macro_span"); + } + + if semver_exempt && proc_macro_span { + println!("cargo:rustc-cfg=super_unstable"); + } + + if consider_rustc_bootstrap { + println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP"); + } +} + +fn compile_probe(rustc_bootstrap: bool) -> bool { + if env::var_os("RUSTC_STAGE").is_some() { + // We are running inside rustc bootstrap. This is a highly non-standard + // environment with issues such as: + // + // https://github.com/rust-lang/cargo/issues/11138 + // https://github.com/rust-lang/rust/issues/114839 + // + // Let's just not use nightly features here. + return false; + } + + let rustc = cargo_env_var("RUSTC"); + let out_dir = cargo_env_var("OUT_DIR"); + let probefile = Path::new("build").join("probe.rs"); + + // Make sure to pick up Cargo rustc configuration. + let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") { + let mut cmd = Command::new(wrapper); + // The wrapper's first argument is supposed to be the path to rustc. + cmd.arg(rustc); + cmd + } else { + Command::new(rustc) + }; + + if !rustc_bootstrap { + cmd.env_remove("RUSTC_BOOTSTRAP"); + } + + cmd.stderr(Stdio::null()) + .arg("--edition=2021") + .arg("--crate-name=proc_macro2") + .arg("--crate-type=lib") + .arg("--emit=dep-info,metadata") + .arg("--out-dir") + .arg(out_dir) + .arg(probefile); + + if let Some(target) = env::var_os("TARGET") { + cmd.arg("--target").arg(target); + } + + // If Cargo wants to set RUSTFLAGS, use that. + if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { + if !rustflags.is_empty() { + for arg in rustflags.split('\x1f') { + cmd.arg(arg); + } + } + } + + match cmd.status() { + Ok(status) => status.success(), + Err(_) => false, + } +} + +fn rustc_minor_version() -> Option { + let rustc = cargo_env_var("RUSTC"); + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() +} + +fn cargo_env_var(key: &str) -> OsString { + env::var_os(key).unwrap_or_else(|| { + eprintln!( + "Environment variable ${} is not set during execution of build script", + key, + ); + process::exit(1); + }) +} diff --git a/utshell-0.5.0/vendor/proc-macro2/build/probe.rs b/utshell-0.5.0/vendor/proc-macro2/build/probe.rs new file mode 100644 index 00000000..2c4947a0 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/build/probe.rs @@ -0,0 +1,25 @@ +// This code exercises the surface area that we expect of Span's unstable API. +// If the current toolchain is able to compile it, then proc-macro2 is able to +// offer these APIs too. + +#![feature(proc_macro_span)] + +extern crate proc_macro; + +use core::ops::{Range, RangeBounds}; +use proc_macro::{Literal, Span}; + +pub fn byte_range(this: &Span) -> Range { + this.byte_range() +} + +pub fn join(this: &Span, other: Span) -> Option { + this.join(other) +} + +pub fn subspan>(this: &Literal, range: R) -> Option { + this.subspan(range) +} + +// Include in sccache cache key. +const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP"); diff --git a/utshell-0.5.0/vendor/proc-macro2/rust-toolchain.toml b/utshell-0.5.0/vendor/proc-macro2/rust-toolchain.toml new file mode 100644 index 00000000..20fe888c --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +components = ["rust-src"] diff --git a/utshell-0.5.0/vendor/proc-macro2/src/detection.rs b/utshell-0.5.0/vendor/proc-macro2/src/detection.rs new file mode 100644 index 00000000..beba7b23 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/detection.rs @@ -0,0 +1,75 @@ +use core::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Once; + +static WORKS: AtomicUsize = AtomicUsize::new(0); +static INIT: Once = Once::new(); + +pub(crate) fn inside_proc_macro() -> bool { + match WORKS.load(Ordering::Relaxed) { + 1 => return false, + 2 => return true, + _ => {} + } + + INIT.call_once(initialize); + inside_proc_macro() +} + +pub(crate) fn force_fallback() { + WORKS.store(1, Ordering::Relaxed); +} + +pub(crate) fn unforce_fallback() { + initialize(); +} + +#[cfg(not(no_is_available))] +fn initialize() { + let available = proc_macro::is_available(); + WORKS.store(available as usize + 1, Ordering::Relaxed); +} + +// Swap in a null panic hook to avoid printing "thread panicked" to stderr, +// then use catch_unwind to determine whether the compiler's proc_macro is +// working. When proc-macro2 is used from outside of a procedural macro all +// of the proc_macro crate's APIs currently panic. +// +// The Once is to prevent the possibility of this ordering: +// +// thread 1 calls take_hook, gets the user's original hook +// thread 1 calls set_hook with the null hook +// thread 2 calls take_hook, thinks null hook is the original hook +// thread 2 calls set_hook with the null hook +// thread 1 calls set_hook with the actual original hook +// thread 2 calls set_hook with what it thinks is the original hook +// +// in which the user's hook has been lost. +// +// There is still a race condition where a panic in a different thread can +// happen during the interval that the user's original panic hook is +// unregistered such that their hook is incorrectly not called. This is +// sufficiently unlikely and less bad than printing panic messages to stderr +// on correct use of this crate. Maybe there is a libstd feature request +// here. For now, if a user needs to guarantee that this failure mode does +// not occur, they need to call e.g. `proc_macro2::Span::call_site()` from +// the main thread before launching any other threads. +#[cfg(no_is_available)] +fn initialize() { + use std::panic::{self, PanicInfo}; + + type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static; + + let null_hook: Box = Box::new(|_panic_info| { /* ignore */ }); + let sanity_check = &*null_hook as *const PanicHook; + let original_hook = panic::take_hook(); + panic::set_hook(null_hook); + + let works = panic::catch_unwind(proc_macro::Span::call_site).is_ok(); + WORKS.store(works as usize + 1, Ordering::Relaxed); + + let hopefully_null_hook = panic::take_hook(); + panic::set_hook(original_hook); + if sanity_check != &*hopefully_null_hook { + panic!("observed race condition in proc_macro2::inside_proc_macro"); + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/extra.rs b/utshell-0.5.0/vendor/proc-macro2/src/extra.rs new file mode 100644 index 00000000..543ec1d9 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/extra.rs @@ -0,0 +1,151 @@ +//! Items which do not have a correspondence to any API in the proc_macro crate, +//! but are necessary to include in proc-macro2. + +use crate::fallback; +use crate::imp; +use crate::marker::{ProcMacroAutoTraits, MARKER}; +use crate::Span; +use core::fmt::{self, Debug}; + +/// Invalidate any `proc_macro2::Span` that exist on the current thread. +/// +/// The implementation of `Span` uses thread-local data structures and this +/// function clears them. Calling any method on a `Span` on the current thread +/// created prior to the invalidation will return incorrect values or crash. +/// +/// This function is useful for programs that process more than 232 +/// bytes of Rust source code on the same thread. Just like rustc, proc-macro2 +/// uses 32-bit source locations, and these wrap around when the total source +/// code processed by the same thread exceeds 232 bytes (4 +/// gigabytes). After a wraparound, `Span` methods such as `source_text()` can +/// return wrong data. +/// +/// # Example +/// +/// As of late 2023, there is 200 GB of Rust code published on crates.io. +/// Looking at just the newest version of every crate, it is 16 GB of code. So a +/// workload that involves parsing it all would overflow a 32-bit source +/// location unless spans are being invalidated. +/// +/// ``` +/// use flate2::read::GzDecoder; +/// use std::ffi::OsStr; +/// use std::io::{BufReader, Read}; +/// use std::str::FromStr; +/// use tar::Archive; +/// +/// rayon::scope(|s| { +/// for krate in every_version_of_every_crate() { +/// s.spawn(move |_| { +/// proc_macro2::extra::invalidate_current_thread_spans(); +/// +/// let reader = BufReader::new(krate); +/// let tar = GzDecoder::new(reader); +/// let mut archive = Archive::new(tar); +/// for entry in archive.entries().unwrap() { +/// let mut entry = entry.unwrap(); +/// let path = entry.path().unwrap(); +/// if path.extension() != Some(OsStr::new("rs")) { +/// continue; +/// } +/// let mut content = String::new(); +/// entry.read_to_string(&mut content).unwrap(); +/// match proc_macro2::TokenStream::from_str(&content) { +/// Ok(tokens) => {/* ... */}, +/// Err(_) => continue, +/// } +/// } +/// }); +/// } +/// }); +/// # +/// # fn every_version_of_every_crate() -> Vec { +/// # Vec::new() +/// # } +/// ``` +/// +/// # Panics +/// +/// This function is not applicable to and will panic if called from a +/// procedural macro. +#[cfg(span_locations)] +#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] +pub fn invalidate_current_thread_spans() { + crate::imp::invalidate_current_thread_spans(); +} + +/// An object that holds a [`Group`]'s `span_open()` and `span_close()` together +/// in a more compact representation than holding those 2 spans individually. +/// +/// [`Group`]: crate::Group +#[derive(Copy, Clone)] +pub struct DelimSpan { + inner: DelimSpanEnum, + _marker: ProcMacroAutoTraits, +} + +#[derive(Copy, Clone)] +enum DelimSpanEnum { + #[cfg(wrap_proc_macro)] + Compiler { + join: proc_macro::Span, + open: proc_macro::Span, + close: proc_macro::Span, + }, + Fallback(fallback::Span), +} + +impl DelimSpan { + pub(crate) fn new(group: &imp::Group) -> Self { + #[cfg(wrap_proc_macro)] + let inner = match group { + imp::Group::Compiler(group) => DelimSpanEnum::Compiler { + join: group.span(), + open: group.span_open(), + close: group.span_close(), + }, + imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), + }; + + #[cfg(not(wrap_proc_macro))] + let inner = DelimSpanEnum::Fallback(group.span()); + + DelimSpan { + inner, + _marker: MARKER, + } + } + + /// Returns a span covering the entire delimited group. + pub fn join(&self) -> Span { + match &self.inner { + #[cfg(wrap_proc_macro)] + DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), + DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), + } + } + + /// Returns a span for the opening punctuation of the group only. + pub fn open(&self) -> Span { + match &self.inner { + #[cfg(wrap_proc_macro)] + DelimSpanEnum::Compiler { open, .. } => Span::_new(imp::Span::Compiler(*open)), + DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), + } + } + + /// Returns a span for the closing punctuation of the group only. + pub fn close(&self) -> Span { + match &self.inner { + #[cfg(wrap_proc_macro)] + DelimSpanEnum::Compiler { close, .. } => Span::_new(imp::Span::Compiler(*close)), + DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), + } + } +} + +impl Debug for DelimSpan { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.join(), f) + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/fallback.rs b/utshell-0.5.0/vendor/proc-macro2/src/fallback.rs new file mode 100644 index 00000000..16bf645c --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/fallback.rs @@ -0,0 +1,1170 @@ +#[cfg(span_locations)] +use crate::location::LineColumn; +use crate::parse::{self, Cursor}; +use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; +use crate::{Delimiter, Spacing, TokenTree}; +#[cfg(all(span_locations, not(fuzzing)))] +use alloc::collections::BTreeMap; +#[cfg(all(span_locations, not(fuzzing)))] +use core::cell::RefCell; +#[cfg(span_locations)] +use core::cmp; +use core::fmt::{self, Debug, Display, Write}; +use core::mem::ManuallyDrop; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +use core::ptr; +use core::str::FromStr; +use std::path::PathBuf; + +/// Force use of proc-macro2's fallback implementation of the API for now, even +/// if the compiler's implementation is available. +pub fn force() { + #[cfg(wrap_proc_macro)] + crate::detection::force_fallback(); +} + +/// Resume using the compiler's implementation of the proc macro API if it is +/// available. +pub fn unforce() { + #[cfg(wrap_proc_macro)] + crate::detection::unforce_fallback(); +} + +#[derive(Clone)] +pub(crate) struct TokenStream { + inner: RcVec, +} + +#[derive(Debug)] +pub(crate) struct LexError { + pub(crate) span: Span, +} + +impl LexError { + pub(crate) fn span(&self) -> Span { + self.span + } + + pub(crate) fn call_site() -> Self { + LexError { + span: Span::call_site(), + } + } +} + +impl TokenStream { + pub fn new() -> Self { + TokenStream { + inner: RcVecBuilder::new().build(), + } + } + + pub fn is_empty(&self) -> bool { + self.inner.len() == 0 + } + + fn take_inner(self) -> RcVecBuilder { + let nodrop = ManuallyDrop::new(self); + unsafe { ptr::read(&nodrop.inner) }.make_owned() + } +} + +fn push_token_from_proc_macro(mut vec: RcVecMut, token: TokenTree) { + // https://github.com/dtolnay/proc-macro2/issues/235 + match token { + TokenTree::Literal(crate::Literal { + #[cfg(wrap_proc_macro)] + inner: crate::imp::Literal::Fallback(literal), + #[cfg(not(wrap_proc_macro))] + inner: literal, + .. + }) if literal.repr.starts_with('-') => { + push_negative_literal(vec, literal); + } + _ => vec.push(token), + } + + #[cold] + fn push_negative_literal(mut vec: RcVecMut, mut literal: Literal) { + literal.repr.remove(0); + let mut punct = crate::Punct::new('-', Spacing::Alone); + punct.set_span(crate::Span::_new_fallback(literal.span)); + vec.push(TokenTree::Punct(punct)); + vec.push(TokenTree::Literal(crate::Literal::_new_fallback(literal))); + } +} + +// Nonrecursive to prevent stack overflow. +impl Drop for TokenStream { + fn drop(&mut self) { + let mut inner = match self.inner.get_mut() { + Some(inner) => inner, + None => return, + }; + while let Some(token) = inner.pop() { + let group = match token { + TokenTree::Group(group) => group.inner, + _ => continue, + }; + #[cfg(wrap_proc_macro)] + let group = match group { + crate::imp::Group::Fallback(group) => group, + crate::imp::Group::Compiler(_) => continue, + }; + inner.extend(group.stream.take_inner()); + } + } +} + +pub(crate) struct TokenStreamBuilder { + inner: RcVecBuilder, +} + +impl TokenStreamBuilder { + pub fn new() -> Self { + TokenStreamBuilder { + inner: RcVecBuilder::new(), + } + } + + pub fn with_capacity(cap: usize) -> Self { + TokenStreamBuilder { + inner: RcVecBuilder::with_capacity(cap), + } + } + + pub fn push_token_from_parser(&mut self, tt: TokenTree) { + self.inner.push(tt); + } + + pub fn build(self) -> TokenStream { + TokenStream { + inner: self.inner.build(), + } + } +} + +#[cfg(span_locations)] +fn get_cursor(src: &str) -> Cursor { + #[cfg(fuzzing)] + return Cursor { rest: src, off: 1 }; + + // Create a dummy file & add it to the source map + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let mut sm = sm.borrow_mut(); + let span = sm.add_file(src); + Cursor { + rest: src, + off: span.lo, + } + }) +} + +#[cfg(not(span_locations))] +fn get_cursor(src: &str) -> Cursor { + Cursor { rest: src } +} + +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + // Create a dummy file & add it to the source map + let mut cursor = get_cursor(src); + + // Strip a byte order mark if present + const BYTE_ORDER_MARK: &str = "\u{feff}"; + if cursor.starts_with(BYTE_ORDER_MARK) { + cursor = cursor.advance(BYTE_ORDER_MARK.len()); + } + + parse::token_stream(cursor) + } +} + +impl Display for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("cannot parse string into token stream") + } +} + +impl Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut joint = false; + for (i, tt) in self.inner.iter().enumerate() { + if i != 0 && !joint { + write!(f, " ")?; + } + joint = false; + match tt { + TokenTree::Group(tt) => Display::fmt(tt, f), + TokenTree::Ident(tt) => Display::fmt(tt, f), + TokenTree::Punct(tt) => { + joint = tt.spacing() == Spacing::Joint; + Display::fmt(tt, f) + } + TokenTree::Literal(tt) => Display::fmt(tt, f), + }?; + } + + Ok(()) + } +} + +impl Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TokenStream ")?; + f.debug_list().entries(self.clone()).finish() + } +} + +#[cfg(feature = "proc-macro")] +impl From for TokenStream { + fn from(inner: proc_macro::TokenStream) -> Self { + inner + .to_string() + .parse() + .expect("compiler token stream parse failed") + } +} + +#[cfg(feature = "proc-macro")] +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + inner + .to_string() + .parse() + .expect("failed to parse to compiler tokens") + } +} + +impl From for TokenStream { + fn from(tree: TokenTree) -> Self { + let mut stream = RcVecBuilder::new(); + push_token_from_proc_macro(stream.as_mut(), tree); + TokenStream { + inner: stream.build(), + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(tokens: I) -> Self { + let mut stream = TokenStream::new(); + stream.extend(tokens); + stream + } +} + +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + let mut v = RcVecBuilder::new(); + + for stream in streams { + v.extend(stream.take_inner()); + } + + TokenStream { inner: v.build() } + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + let mut vec = self.inner.make_mut(); + tokens + .into_iter() + .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token)); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner.make_mut().extend(streams.into_iter().flatten()); + } +} + +pub(crate) type TokenTreeIter = RcVecIntoIter; + +impl IntoIterator for TokenStream { + type Item = TokenTree; + type IntoIter = TokenTreeIter; + + fn into_iter(self) -> TokenTreeIter { + self.take_inner().into_iter() + } +} + +#[derive(Clone, PartialEq, Eq)] +pub(crate) struct SourceFile { + path: PathBuf, +} + +impl SourceFile { + /// Get the path to this source file as a string. + pub fn path(&self) -> PathBuf { + self.path.clone() + } + + pub fn is_real(&self) -> bool { + false + } +} + +impl Debug for SourceFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SourceFile") + .field("path", &self.path()) + .field("is_real", &self.is_real()) + .finish() + } +} + +#[cfg(all(span_locations, not(fuzzing)))] +thread_local! { + static SOURCE_MAP: RefCell = RefCell::new(SourceMap { + // Start with a single dummy file which all call_site() and def_site() + // spans reference. + files: vec![FileInfo { + source_text: String::new(), + span: Span { lo: 0, hi: 0 }, + lines: vec![0], + char_index_to_byte_offset: BTreeMap::new(), + }], + }); +} + +#[cfg(span_locations)] +pub(crate) fn invalidate_current_thread_spans() { + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| sm.borrow_mut().files.truncate(1)); +} + +#[cfg(all(span_locations, not(fuzzing)))] +struct FileInfo { + source_text: String, + span: Span, + lines: Vec, + char_index_to_byte_offset: BTreeMap, +} + +#[cfg(all(span_locations, not(fuzzing)))] +impl FileInfo { + fn offset_line_column(&self, offset: usize) -> LineColumn { + assert!(self.span_within(Span { + lo: offset as u32, + hi: offset as u32, + })); + let offset = offset - self.span.lo as usize; + match self.lines.binary_search(&offset) { + Ok(found) => LineColumn { + line: found + 1, + column: 0, + }, + Err(idx) => LineColumn { + line: idx, + column: offset - self.lines[idx - 1], + }, + } + } + + fn span_within(&self, span: Span) -> bool { + span.lo >= self.span.lo && span.hi <= self.span.hi + } + + fn byte_range(&mut self, span: Span) -> Range { + let lo_char = (span.lo - self.span.lo) as usize; + + // Look up offset of the largest already-computed char index that is + // less than or equal to the current requested one. We resume counting + // chars from that point. + let (&last_char_index, &last_byte_offset) = self + .char_index_to_byte_offset + .range(..=lo_char) + .next_back() + .unwrap_or((&0, &0)); + + let lo_byte = if last_char_index == lo_char { + last_byte_offset + } else { + let total_byte_offset = match self.source_text[last_byte_offset..] + .char_indices() + .nth(lo_char - last_char_index) + { + Some((additional_offset, _ch)) => last_byte_offset + additional_offset, + None => self.source_text.len(), + }; + self.char_index_to_byte_offset + .insert(lo_char, total_byte_offset); + total_byte_offset + }; + + let trunc_lo = &self.source_text[lo_byte..]; + let char_len = (span.hi - span.lo) as usize; + lo_byte..match trunc_lo.char_indices().nth(char_len) { + Some((offset, _ch)) => lo_byte + offset, + None => self.source_text.len(), + } + } + + fn source_text(&mut self, span: Span) -> String { + let byte_range = self.byte_range(span); + self.source_text[byte_range].to_owned() + } +} + +/// Computes the offsets of each line in the given source string +/// and the total number of characters +#[cfg(all(span_locations, not(fuzzing)))] +fn lines_offsets(s: &str) -> (usize, Vec) { + let mut lines = vec![0]; + let mut total = 0; + + for ch in s.chars() { + total += 1; + if ch == '\n' { + lines.push(total); + } + } + + (total, lines) +} + +#[cfg(all(span_locations, not(fuzzing)))] +struct SourceMap { + files: Vec, +} + +#[cfg(all(span_locations, not(fuzzing)))] +impl SourceMap { + fn next_start_pos(&self) -> u32 { + // Add 1 so there's always space between files. + // + // We'll always have at least 1 file, as we initialize our files list + // with a dummy file. + self.files.last().unwrap().span.hi + 1 + } + + fn add_file(&mut self, src: &str) -> Span { + let (len, lines) = lines_offsets(src); + let lo = self.next_start_pos(); + let span = Span { + lo, + hi: lo + (len as u32), + }; + + self.files.push(FileInfo { + source_text: src.to_owned(), + span, + lines, + // Populated lazily by source_text(). + char_index_to_byte_offset: BTreeMap::new(), + }); + + span + } + + #[cfg(procmacro2_semver_exempt)] + fn filepath(&self, span: Span) -> PathBuf { + for (i, file) in self.files.iter().enumerate() { + if file.span_within(span) { + return PathBuf::from(if i == 0 { + "".to_owned() + } else { + format!("", i) + }); + } + } + unreachable!("Invalid span with no related FileInfo!"); + } + + fn fileinfo(&self, span: Span) -> &FileInfo { + for file in &self.files { + if file.span_within(span) { + return file; + } + } + unreachable!("Invalid span with no related FileInfo!"); + } + + fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo { + for file in &mut self.files { + if file.span_within(span) { + return file; + } + } + unreachable!("Invalid span with no related FileInfo!"); + } +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) struct Span { + #[cfg(span_locations)] + pub(crate) lo: u32, + #[cfg(span_locations)] + pub(crate) hi: u32, +} + +impl Span { + #[cfg(not(span_locations))] + pub fn call_site() -> Self { + Span {} + } + + #[cfg(span_locations)] + pub fn call_site() -> Self { + Span { lo: 0, hi: 0 } + } + + pub fn mixed_site() -> Self { + Span::call_site() + } + + #[cfg(procmacro2_semver_exempt)] + pub fn def_site() -> Self { + Span::call_site() + } + + pub fn resolved_at(&self, _other: Span) -> Span { + // Stable spans consist only of line/column information, so + // `resolved_at` and `located_at` only select which span the + // caller wants line/column information from. + *self + } + + pub fn located_at(&self, other: Span) -> Span { + other + } + + #[cfg(procmacro2_semver_exempt)] + pub fn source_file(&self) -> SourceFile { + #[cfg(fuzzing)] + return SourceFile { + path: PathBuf::from(""), + }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + let path = sm.filepath(*self); + SourceFile { path } + }) + } + + #[cfg(span_locations)] + pub fn byte_range(&self) -> Range { + #[cfg(fuzzing)] + return 0..0; + + #[cfg(not(fuzzing))] + { + if self.is_call_site() { + 0..0 + } else { + SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).byte_range(*self)) + } + } + } + + #[cfg(span_locations)] + pub fn start(&self) -> LineColumn { + #[cfg(fuzzing)] + return LineColumn { line: 0, column: 0 }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + let fi = sm.fileinfo(*self); + fi.offset_line_column(self.lo as usize) + }) + } + + #[cfg(span_locations)] + pub fn end(&self) -> LineColumn { + #[cfg(fuzzing)] + return LineColumn { line: 0, column: 0 }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + let fi = sm.fileinfo(*self); + fi.offset_line_column(self.hi as usize) + }) + } + + #[cfg(not(span_locations))] + pub fn join(&self, _other: Span) -> Option { + Some(Span {}) + } + + #[cfg(span_locations)] + pub fn join(&self, other: Span) -> Option { + #[cfg(fuzzing)] + return { + let _ = other; + None + }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + // If `other` is not within the same FileInfo as us, return None. + if !sm.fileinfo(*self).span_within(other) { + return None; + } + Some(Span { + lo: cmp::min(self.lo, other.lo), + hi: cmp::max(self.hi, other.hi), + }) + }) + } + + #[cfg(not(span_locations))] + pub fn source_text(&self) -> Option { + None + } + + #[cfg(span_locations)] + pub fn source_text(&self) -> Option { + #[cfg(fuzzing)] + return None; + + #[cfg(not(fuzzing))] + { + if self.is_call_site() { + None + } else { + Some(SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).source_text(*self))) + } + } + } + + #[cfg(not(span_locations))] + pub(crate) fn first_byte(self) -> Self { + self + } + + #[cfg(span_locations)] + pub(crate) fn first_byte(self) -> Self { + Span { + lo: self.lo, + hi: cmp::min(self.lo.saturating_add(1), self.hi), + } + } + + #[cfg(not(span_locations))] + pub(crate) fn last_byte(self) -> Self { + self + } + + #[cfg(span_locations)] + pub(crate) fn last_byte(self) -> Self { + Span { + lo: cmp::max(self.hi.saturating_sub(1), self.lo), + hi: self.hi, + } + } + + #[cfg(span_locations)] + fn is_call_site(&self) -> bool { + self.lo == 0 && self.hi == 0 + } +} + +impl Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + #[cfg(span_locations)] + return write!(f, "bytes({}..{})", self.lo, self.hi); + + #[cfg(not(span_locations))] + write!(f, "Span") + } +} + +pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { + #[cfg(span_locations)] + { + if span.is_call_site() { + return; + } + } + + if cfg!(span_locations) { + debug.field("span", &span); + } +} + +#[derive(Clone)] +pub(crate) struct Group { + delimiter: Delimiter, + stream: TokenStream, + span: Span, +} + +impl Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + Group { + delimiter, + stream, + span: Span::call_site(), + } + } + + pub fn delimiter(&self) -> Delimiter { + self.delimiter + } + + pub fn stream(&self) -> TokenStream { + self.stream.clone() + } + + pub fn span(&self) -> Span { + self.span + } + + pub fn span_open(&self) -> Span { + self.span.first_byte() + } + + pub fn span_close(&self) -> Span { + self.span.last_byte() + } + + pub fn set_span(&mut self, span: Span) { + self.span = span; + } +} + +impl Display for Group { + // We attempt to match libproc_macro's formatting. + // Empty parens: () + // Nonempty parens: (...) + // Empty brackets: [] + // Nonempty brackets: [...] + // Empty braces: { } + // Nonempty braces: { ... } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (open, close) = match self.delimiter { + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Brace => ("{ ", "}"), + Delimiter::Bracket => ("[", "]"), + Delimiter::None => ("", ""), + }; + + f.write_str(open)?; + Display::fmt(&self.stream, f)?; + if self.delimiter == Delimiter::Brace && !self.stream.inner.is_empty() { + f.write_str(" ")?; + } + f.write_str(close)?; + + Ok(()) + } +} + +impl Debug for Group { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut debug = fmt.debug_struct("Group"); + debug.field("delimiter", &self.delimiter); + debug.field("stream", &self.stream); + debug_span_field_if_nontrivial(&mut debug, self.span); + debug.finish() + } +} + +#[derive(Clone)] +pub(crate) struct Ident { + sym: String, + span: Span, + raw: bool, +} + +impl Ident { + #[track_caller] + pub fn new_checked(string: &str, span: Span) -> Self { + validate_ident(string); + Ident::new_unchecked(string, span) + } + + pub fn new_unchecked(string: &str, span: Span) -> Self { + Ident { + sym: string.to_owned(), + span, + raw: false, + } + } + + #[track_caller] + pub fn new_raw_checked(string: &str, span: Span) -> Self { + validate_ident_raw(string); + Ident::new_raw_unchecked(string, span) + } + + pub fn new_raw_unchecked(string: &str, span: Span) -> Self { + Ident { + sym: string.to_owned(), + span, + raw: true, + } + } + + pub fn span(&self) -> Span { + self.span + } + + pub fn set_span(&mut self, span: Span) { + self.span = span; + } +} + +pub(crate) fn is_ident_start(c: char) -> bool { + c == '_' || unicode_ident::is_xid_start(c) +} + +pub(crate) fn is_ident_continue(c: char) -> bool { + unicode_ident::is_xid_continue(c) +} + +#[track_caller] +fn validate_ident(string: &str) { + if string.is_empty() { + panic!("Ident is not allowed to be empty; use Option"); + } + + if string.bytes().all(|digit| b'0' <= digit && digit <= b'9') { + panic!("Ident cannot be a number; use Literal instead"); + } + + fn ident_ok(string: &str) -> bool { + let mut chars = string.chars(); + let first = chars.next().unwrap(); + if !is_ident_start(first) { + return false; + } + for ch in chars { + if !is_ident_continue(ch) { + return false; + } + } + true + } + + if !ident_ok(string) { + panic!("{:?} is not a valid Ident", string); + } +} + +#[track_caller] +fn validate_ident_raw(string: &str) { + validate_ident(string); + + match string { + "_" | "super" | "self" | "Self" | "crate" => { + panic!("`r#{}` cannot be a raw identifier", string); + } + _ => {} + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + self.sym == other.sym && self.raw == other.raw + } +} + +impl PartialEq for Ident +where + T: ?Sized + AsRef, +{ + fn eq(&self, other: &T) -> bool { + let other = other.as_ref(); + if self.raw { + other.starts_with("r#") && self.sym == other[2..] + } else { + self.sym == other + } + } +} + +impl Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.raw { + f.write_str("r#")?; + } + Display::fmt(&self.sym, f) + } +} + +#[allow(clippy::missing_fields_in_debug)] +impl Debug for Ident { + // Ident(proc_macro), Ident(r#union) + #[cfg(not(span_locations))] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut debug = f.debug_tuple("Ident"); + debug.field(&format_args!("{}", self)); + debug.finish() + } + + // Ident { + // sym: proc_macro, + // span: bytes(128..138) + // } + #[cfg(span_locations)] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut debug = f.debug_struct("Ident"); + debug.field("sym", &format_args!("{}", self)); + debug_span_field_if_nontrivial(&mut debug, self.span); + debug.finish() + } +} + +#[derive(Clone)] +pub(crate) struct Literal { + repr: String, + span: Span, +} + +macro_rules! suffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + Literal::_new(format!(concat!("{}", stringify!($kind)), n)) + } + )*) +} + +macro_rules! unsuffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + Literal::_new(n.to_string()) + } + )*) +} + +impl Literal { + pub(crate) fn _new(repr: String) -> Self { + Literal { + repr, + span: Span::call_site(), + } + } + + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { + Literal::_new(repr.to_owned()) + } + + suffixed_numbers! { + u8_suffixed => u8, + u16_suffixed => u16, + u32_suffixed => u32, + u64_suffixed => u64, + u128_suffixed => u128, + usize_suffixed => usize, + i8_suffixed => i8, + i16_suffixed => i16, + i32_suffixed => i32, + i64_suffixed => i64, + i128_suffixed => i128, + isize_suffixed => isize, + + f32_suffixed => f32, + f64_suffixed => f64, + } + + unsuffixed_numbers! { + u8_unsuffixed => u8, + u16_unsuffixed => u16, + u32_unsuffixed => u32, + u64_unsuffixed => u64, + u128_unsuffixed => u128, + usize_unsuffixed => usize, + i8_unsuffixed => i8, + i16_unsuffixed => i16, + i32_unsuffixed => i32, + i64_unsuffixed => i64, + i128_unsuffixed => i128, + isize_unsuffixed => isize, + } + + pub fn f32_unsuffixed(f: f32) -> Literal { + let mut s = f.to_string(); + if !s.contains('.') { + s.push_str(".0"); + } + Literal::_new(s) + } + + pub fn f64_unsuffixed(f: f64) -> Literal { + let mut s = f.to_string(); + if !s.contains('.') { + s.push_str(".0"); + } + Literal::_new(s) + } + + pub fn string(t: &str) -> Literal { + let mut repr = String::with_capacity(t.len() + 2); + repr.push('"'); + let mut chars = t.chars(); + while let Some(ch) = chars.next() { + if ch == '\0' { + repr.push_str( + if chars + .as_str() + .starts_with(|next| '0' <= next && next <= '7') + { + // circumvent clippy::octal_escapes lint + "\\x00" + } else { + "\\0" + }, + ); + } else if ch == '\'' { + // escape_debug turns this into "\'" which is unnecessary. + repr.push(ch); + } else { + repr.extend(ch.escape_debug()); + } + } + repr.push('"'); + Literal::_new(repr) + } + + pub fn character(t: char) -> Literal { + let mut repr = String::new(); + repr.push('\''); + if t == '"' { + // escape_debug turns this into '\"' which is unnecessary. + repr.push(t); + } else { + repr.extend(t.escape_debug()); + } + repr.push('\''); + Literal::_new(repr) + } + + pub fn byte_string(bytes: &[u8]) -> Literal { + let mut escaped = "b\"".to_string(); + let mut bytes = bytes.iter(); + while let Some(&b) = bytes.next() { + #[allow(clippy::match_overlapping_arm)] + match b { + b'\0' => escaped.push_str(match bytes.as_slice().first() { + // circumvent clippy::octal_escapes lint + Some(b'0'..=b'7') => r"\x00", + _ => r"\0", + }), + b'\t' => escaped.push_str(r"\t"), + b'\n' => escaped.push_str(r"\n"), + b'\r' => escaped.push_str(r"\r"), + b'"' => escaped.push_str("\\\""), + b'\\' => escaped.push_str("\\\\"), + b'\x20'..=b'\x7E' => escaped.push(b as char), + _ => { + let _ = write!(escaped, "\\x{:02X}", b); + } + } + } + escaped.push('"'); + Literal::_new(escaped) + } + + pub fn span(&self) -> Span { + self.span + } + + pub fn set_span(&mut self, span: Span) { + self.span = span; + } + + pub fn subspan>(&self, range: R) -> Option { + #[cfg(not(span_locations))] + { + let _ = range; + None + } + + #[cfg(span_locations)] + { + use core::ops::Bound; + + let lo = match range.start_bound() { + Bound::Included(start) => { + let start = u32::try_from(*start).ok()?; + self.span.lo.checked_add(start)? + } + Bound::Excluded(start) => { + let start = u32::try_from(*start).ok()?; + self.span.lo.checked_add(start)?.checked_add(1)? + } + Bound::Unbounded => self.span.lo, + }; + let hi = match range.end_bound() { + Bound::Included(end) => { + let end = u32::try_from(*end).ok()?; + self.span.lo.checked_add(end)?.checked_add(1)? + } + Bound::Excluded(end) => { + let end = u32::try_from(*end).ok()?; + self.span.lo.checked_add(end)? + } + Bound::Unbounded => self.span.hi, + }; + if lo <= hi && hi <= self.span.hi { + Some(Span { lo, hi }) + } else { + None + } + } + } +} + +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result { + let mut cursor = get_cursor(repr); + #[cfg(span_locations)] + let lo = cursor.off; + + let negative = cursor.starts_with_char('-'); + if negative { + cursor = cursor.advance(1); + if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { + return Err(LexError::call_site()); + } + } + + if let Ok((rest, mut literal)) = parse::literal(cursor) { + if rest.is_empty() { + if negative { + literal.repr.insert(0, '-'); + } + literal.span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; + return Ok(literal); + } + } + Err(LexError::call_site()) + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.repr, f) + } +} + +impl Debug for Literal { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut debug = fmt.debug_struct("Literal"); + debug.field("lit", &format_args!("{}", self.repr)); + debug_span_field_if_nontrivial(&mut debug, self.span); + debug.finish() + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/lib.rs b/utshell-0.5.0/vendor/proc-macro2/src/lib.rs new file mode 100644 index 00000000..01f2049c --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/lib.rs @@ -0,0 +1,1345 @@ +//! [![github]](https://github.com/dtolnay/proc-macro2) [![crates-io]](https://crates.io/crates/proc-macro2) [![docs-rs]](crate) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! A wrapper around the procedural macro API of the compiler's [`proc_macro`] +//! crate. This library serves two purposes: +//! +//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ +//! +//! - **Bring proc-macro-like functionality to other contexts like build.rs and +//! main.rs.** Types from `proc_macro` are entirely specific to procedural +//! macros and cannot ever exist in code outside of a procedural macro. +//! Meanwhile `proc_macro2` types may exist anywhere including non-macro code. +//! By developing foundational libraries like [syn] and [quote] against +//! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem +//! becomes easily applicable to many other use cases and we avoid +//! reimplementing non-macro equivalents of those libraries. +//! +//! - **Make procedural macros unit testable.** As a consequence of being +//! specific to procedural macros, nothing that uses `proc_macro` can be +//! executed from a unit test. In order for helper libraries or components of +//! a macro to be testable in isolation, they must be implemented using +//! `proc_macro2`. +//! +//! [syn]: https://github.com/dtolnay/syn +//! [quote]: https://github.com/dtolnay/quote +//! +//! # Usage +//! +//! The skeleton of a typical procedural macro typically looks like this: +//! +//! ``` +//! extern crate proc_macro; +//! +//! # const IGNORE: &str = stringify! { +//! #[proc_macro_derive(MyDerive)] +//! # }; +//! # #[cfg(wrap_proc_macro)] +//! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +//! let input = proc_macro2::TokenStream::from(input); +//! +//! let output: proc_macro2::TokenStream = { +//! /* transform input */ +//! # input +//! }; +//! +//! proc_macro::TokenStream::from(output) +//! } +//! ``` +//! +//! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to +//! propagate parse errors correctly back to the compiler when parsing fails. +//! +//! [`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html +//! +//! # Unstable features +//! +//! The default feature set of proc-macro2 tracks the most recent stable +//! compiler API. Functionality in `proc_macro` that is not yet stable is not +//! exposed by proc-macro2 by default. +//! +//! To opt into the additional APIs available in the most recent nightly +//! compiler, the `procmacro2_semver_exempt` config flag must be passed to +//! rustc. We will polyfill those nightly-only APIs back to Rust 1.56.0. As +//! these are unstable APIs that track the nightly compiler, minor versions of +//! proc-macro2 may make breaking changes to them at any time. +//! +//! ```sh +//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build +//! ``` +//! +//! Note that this must not only be done for your crate, but for any crate that +//! depends on your crate. This infectious nature is intentional, as it serves +//! as a reminder that you are outside of the normal semver guarantees. +//! +//! Semver exempt methods are marked as such in the proc-macro2 documentation. +//! +//! # Thread-Safety +//! +//! Most types in this crate are `!Sync` because the underlying compiler +//! types make use of thread-local memory, meaning they cannot be accessed from +//! a different thread. + +// Proc-macro2 types in rustdoc of other crates get linked to here. +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.78")] +#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] +#![cfg_attr(super_unstable, feature(proc_macro_def_site))] +#![cfg_attr(doc_cfg, feature(doc_cfg))] +#![deny(unsafe_op_in_unsafe_fn)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::checked_conversions, + clippy::doc_markdown, + clippy::items_after_statements, + clippy::iter_without_into_iter, + clippy::let_underscore_untyped, + clippy::manual_assert, + clippy::manual_range_contains, + clippy::missing_safety_doc, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::new_without_default, + clippy::return_self_not_must_use, + clippy::shadow_unrelated, + clippy::trivially_copy_pass_by_ref, + clippy::unnecessary_wraps, + clippy::unused_self, + clippy::used_underscore_binding, + clippy::vec_init_then_push +)] + +#[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))] +compile_error! {"\ + Something is not right. If you've tried to turn on \ + procmacro2_semver_exempt, you need to ensure that it \ + is turned on for the compilation of the proc-macro2 \ + build script as well. +"} + +#[cfg(all( + procmacro2_nightly_testing, + feature = "proc-macro", + not(proc_macro_span) +))] +compile_error! {"\ + Build script probe failed to compile. +"} + +extern crate alloc; + +#[cfg(feature = "proc-macro")] +extern crate proc_macro; + +mod marker; +mod parse; +mod rcvec; + +#[cfg(wrap_proc_macro)] +mod detection; + +// Public for proc_macro2::fallback::force() and unforce(), but those are quite +// a niche use case so we omit it from rustdoc. +#[doc(hidden)] +pub mod fallback; + +pub mod extra; + +#[cfg(not(wrap_proc_macro))] +use crate::fallback as imp; +#[path = "wrapper.rs"] +#[cfg(wrap_proc_macro)] +mod imp; + +#[cfg(span_locations)] +mod location; + +use crate::extra::DelimSpan; +use crate::marker::{ProcMacroAutoTraits, MARKER}; +use core::cmp::Ordering; +use core::fmt::{self, Debug, Display}; +use core::hash::{Hash, Hasher}; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +use core::str::FromStr; +use std::error::Error; +#[cfg(procmacro2_semver_exempt)] +use std::path::PathBuf; + +#[cfg(span_locations)] +#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] +pub use crate::location::LineColumn; + +/// An abstract stream of tokens, or more concretely a sequence of token trees. +/// +/// This type provides interfaces for iterating over token trees and for +/// collecting token trees into one stream. +/// +/// Token stream is both the input and output of `#[proc_macro]`, +/// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions. +#[derive(Clone)] +pub struct TokenStream { + inner: imp::TokenStream, + _marker: ProcMacroAutoTraits, +} + +/// Error returned from `TokenStream::from_str`. +pub struct LexError { + inner: imp::LexError, + _marker: ProcMacroAutoTraits, +} + +impl TokenStream { + fn _new(inner: imp::TokenStream) -> Self { + TokenStream { + inner, + _marker: MARKER, + } + } + + fn _new_fallback(inner: fallback::TokenStream) -> Self { + TokenStream { + inner: inner.into(), + _marker: MARKER, + } + } + + /// Returns an empty `TokenStream` containing no token trees. + pub fn new() -> Self { + TokenStream::_new(imp::TokenStream::new()) + } + + /// Checks if this `TokenStream` is empty. + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } +} + +/// `TokenStream::default()` returns an empty stream, +/// i.e. this is equivalent with `TokenStream::new()`. +impl Default for TokenStream { + fn default() -> Self { + TokenStream::new() + } +} + +/// Attempts to break the string into tokens and parse those tokens into a token +/// stream. +/// +/// May fail for a number of reasons, for example, if the string contains +/// unbalanced delimiters or characters not existing in the language. +/// +/// NOTE: Some errors may cause panics instead of returning `LexError`. We +/// reserve the right to change these errors into `LexError`s later. +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + let e = src.parse().map_err(|e| LexError { + inner: e, + _marker: MARKER, + })?; + Ok(TokenStream::_new(e)) + } +} + +#[cfg(feature = "proc-macro")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] +impl From for TokenStream { + fn from(inner: proc_macro::TokenStream) -> Self { + TokenStream::_new(inner.into()) + } +} + +#[cfg(feature = "proc-macro")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + inner.inner.into() + } +} + +impl From for TokenStream { + fn from(token: TokenTree) -> Self { + TokenStream::_new(imp::TokenStream::from(token)) + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner.extend(streams); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner + .extend(streams.into_iter().map(|stream| stream.inner)); + } +} + +/// Collects a number of token trees into a single stream. +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + TokenStream::_new(streams.into_iter().collect()) + } +} +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + TokenStream::_new(streams.into_iter().map(|i| i.inner).collect()) + } +} + +/// Prints the token stream as a string that is supposed to be losslessly +/// convertible back into the same token stream (modulo spans), except for +/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative +/// numeric literals. +impl Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +/// Prints token in a form convenient for debugging. +impl Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl LexError { + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } +} + +impl Debug for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl Display for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +impl Error for LexError {} + +/// The source file of a given `Span`. +/// +/// This type is semver exempt and not exposed by default. +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] +#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] +#[derive(Clone, PartialEq, Eq)] +pub struct SourceFile { + inner: imp::SourceFile, + _marker: ProcMacroAutoTraits, +} + +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] +impl SourceFile { + fn _new(inner: imp::SourceFile) -> Self { + SourceFile { + inner, + _marker: MARKER, + } + } + + /// Get the path to this source file. + /// + /// ### Note + /// + /// If the code span associated with this `SourceFile` was generated by an + /// external macro, this may not be an actual path on the filesystem. Use + /// [`is_real`] to check. + /// + /// Also note that even if `is_real` returns `true`, if + /// `--remap-path-prefix` was passed on the command line, the path as given + /// may not actually be valid. + /// + /// [`is_real`]: #method.is_real + pub fn path(&self) -> PathBuf { + self.inner.path() + } + + /// Returns `true` if this source file is a real source file, and not + /// generated by an external macro's expansion. + pub fn is_real(&self) -> bool { + self.inner.is_real() + } +} + +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] +impl Debug for SourceFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +/// A region of source code, along with macro expansion information. +#[derive(Copy, Clone)] +pub struct Span { + inner: imp::Span, + _marker: ProcMacroAutoTraits, +} + +impl Span { + fn _new(inner: imp::Span) -> Self { + Span { + inner, + _marker: MARKER, + } + } + + fn _new_fallback(inner: fallback::Span) -> Self { + Span { + inner: inner.into(), + _marker: MARKER, + } + } + + /// The span of the invocation of the current procedural macro. + /// + /// Identifiers created with this span will be resolved as if they were + /// written directly at the macro call location (call-site hygiene) and + /// other code at the macro call site will be able to refer to them as well. + pub fn call_site() -> Self { + Span::_new(imp::Span::call_site()) + } + + /// The span located at the invocation of the procedural macro, but with + /// local variables, labels, and `$crate` resolved at the definition site + /// of the macro. This is the same hygiene behavior as `macro_rules`. + pub fn mixed_site() -> Self { + Span::_new(imp::Span::mixed_site()) + } + + /// A span that resolves at the macro definition site. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(procmacro2_semver_exempt)] + #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + pub fn def_site() -> Self { + Span::_new(imp::Span::def_site()) + } + + /// Creates a new span with the same line/column information as `self` but + /// that resolves symbols as though it were at `other`. + pub fn resolved_at(&self, other: Span) -> Span { + Span::_new(self.inner.resolved_at(other.inner)) + } + + /// Creates a new span with the same name resolution behavior as `self` but + /// with the line/column information of `other`. + pub fn located_at(&self, other: Span) -> Span { + Span::_new(self.inner.located_at(other.inner)) + } + + /// Convert `proc_macro2::Span` to `proc_macro::Span`. + /// + /// This method is available when building with a nightly compiler, or when + /// building with rustc 1.29+ *without* semver exempt features. + /// + /// # Panics + /// + /// Panics if called from outside of a procedural macro. Unlike + /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within + /// the context of a procedural macro invocation. + #[cfg(wrap_proc_macro)] + pub fn unwrap(self) -> proc_macro::Span { + self.inner.unwrap() + } + + // Soft deprecated. Please use Span::unwrap. + #[cfg(wrap_proc_macro)] + #[doc(hidden)] + pub fn unstable(self) -> proc_macro::Span { + self.unwrap() + } + + /// The original source file into which this span points. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] + #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + pub fn source_file(&self) -> SourceFile { + SourceFile::_new(self.inner.source_file()) + } + + /// Returns the span's byte position range in the source file. + /// + /// This method requires the `"span-locations"` feature to be enabled. + /// + /// When executing in a procedural macro context, the returned range is only + /// accurate if compiled with a nightly toolchain. The stable toolchain does + /// not have this information available. When executing outside of a + /// procedural macro, such as main.rs or build.rs, the byte range is always + /// accurate regardless of toolchain. + #[cfg(span_locations)] + #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] + pub fn byte_range(&self) -> Range { + self.inner.byte_range() + } + + /// Get the starting line/column in the source file for this span. + /// + /// This method requires the `"span-locations"` feature to be enabled. + /// + /// When executing in a procedural macro context, the returned line/column + /// are only meaningful if compiled with a nightly toolchain. The stable + /// toolchain does not have this information available. When executing + /// outside of a procedural macro, such as main.rs or build.rs, the + /// line/column are always meaningful regardless of toolchain. + #[cfg(span_locations)] + #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] + pub fn start(&self) -> LineColumn { + self.inner.start() + } + + /// Get the ending line/column in the source file for this span. + /// + /// This method requires the `"span-locations"` feature to be enabled. + /// + /// When executing in a procedural macro context, the returned line/column + /// are only meaningful if compiled with a nightly toolchain. The stable + /// toolchain does not have this information available. When executing + /// outside of a procedural macro, such as main.rs or build.rs, the + /// line/column are always meaningful regardless of toolchain. + #[cfg(span_locations)] + #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] + pub fn end(&self) -> LineColumn { + self.inner.end() + } + + /// Create a new span encompassing `self` and `other`. + /// + /// Returns `None` if `self` and `other` are from different files. + /// + /// Warning: the underlying [`proc_macro::Span::join`] method is + /// nightly-only. When called from within a procedural macro not using a + /// nightly compiler, this method will always return `None`. + /// + /// [`proc_macro::Span::join`]: https://doc.rust-lang.org/proc_macro/struct.Span.html#method.join + pub fn join(&self, other: Span) -> Option { + self.inner.join(other.inner).map(Span::_new) + } + + /// Compares two spans to see if they're equal. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(procmacro2_semver_exempt)] + #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] + pub fn eq(&self, other: &Span) -> bool { + self.inner.eq(&other.inner) + } + + /// Returns the source text behind a span. This preserves the original + /// source code, including spaces and comments. It only returns a result if + /// the span corresponds to real source code. + /// + /// Note: The observable result of a macro should only rely on the tokens + /// and not on this source text. The result of this function is a best + /// effort to be used for diagnostics only. + pub fn source_text(&self) -> Option { + self.inner.source_text() + } +} + +/// Prints a span in a form convenient for debugging. +impl Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`). +#[derive(Clone)] +pub enum TokenTree { + /// A token stream surrounded by bracket delimiters. + Group(Group), + /// An identifier. + Ident(Ident), + /// A single punctuation character (`+`, `,`, `$`, etc.). + Punct(Punct), + /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc. + Literal(Literal), +} + +impl TokenTree { + /// Returns the span of this tree, delegating to the `span` method of + /// the contained token or a delimited stream. + pub fn span(&self) -> Span { + match self { + TokenTree::Group(t) => t.span(), + TokenTree::Ident(t) => t.span(), + TokenTree::Punct(t) => t.span(), + TokenTree::Literal(t) => t.span(), + } + } + + /// Configures the span for *only this token*. + /// + /// Note that if this token is a `Group` then this method will not configure + /// the span of each of the internal tokens, this will simply delegate to + /// the `set_span` method of each variant. + pub fn set_span(&mut self, span: Span) { + match self { + TokenTree::Group(t) => t.set_span(span), + TokenTree::Ident(t) => t.set_span(span), + TokenTree::Punct(t) => t.set_span(span), + TokenTree::Literal(t) => t.set_span(span), + } + } +} + +impl From for TokenTree { + fn from(g: Group) -> Self { + TokenTree::Group(g) + } +} + +impl From for TokenTree { + fn from(g: Ident) -> Self { + TokenTree::Ident(g) + } +} + +impl From for TokenTree { + fn from(g: Punct) -> Self { + TokenTree::Punct(g) + } +} + +impl From for TokenTree { + fn from(g: Literal) -> Self { + TokenTree::Literal(g) + } +} + +/// Prints the token tree as a string that is supposed to be losslessly +/// convertible back into the same token tree (modulo spans), except for +/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative +/// numeric literals. +impl Display for TokenTree { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenTree::Group(t) => Display::fmt(t, f), + TokenTree::Ident(t) => Display::fmt(t, f), + TokenTree::Punct(t) => Display::fmt(t, f), + TokenTree::Literal(t) => Display::fmt(t, f), + } + } +} + +/// Prints token tree in a form convenient for debugging. +impl Debug for TokenTree { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Each of these has the name in the struct type in the derived debug, + // so don't bother with an extra layer of indirection + match self { + TokenTree::Group(t) => Debug::fmt(t, f), + TokenTree::Ident(t) => { + let mut debug = f.debug_struct("Ident"); + debug.field("sym", &format_args!("{}", t)); + imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner); + debug.finish() + } + TokenTree::Punct(t) => Debug::fmt(t, f), + TokenTree::Literal(t) => Debug::fmt(t, f), + } + } +} + +/// A delimited token stream. +/// +/// A `Group` internally contains a `TokenStream` which is surrounded by +/// `Delimiter`s. +#[derive(Clone)] +pub struct Group { + inner: imp::Group, +} + +/// Describes how a sequence of token trees is delimited. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Delimiter { + /// `( ... )` + Parenthesis, + /// `{ ... }` + Brace, + /// `[ ... ]` + Bracket, + /// `Ø ... Ø` + /// + /// An implicit delimiter, that may, for example, appear around tokens + /// coming from a "macro variable" `$var`. It is important to preserve + /// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`. + /// Implicit delimiters may not survive roundtrip of a token stream through + /// a string. + None, +} + +impl Group { + fn _new(inner: imp::Group) -> Self { + Group { inner } + } + + fn _new_fallback(inner: fallback::Group) -> Self { + Group { + inner: inner.into(), + } + } + + /// Creates a new `Group` with the given delimiter and token stream. + /// + /// This constructor will set the span for this group to + /// `Span::call_site()`. To change the span you can use the `set_span` + /// method below. + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + Group { + inner: imp::Group::new(delimiter, stream.inner), + } + } + + /// Returns the punctuation used as the delimiter for this group: a set of + /// parentheses, square brackets, or curly braces. + pub fn delimiter(&self) -> Delimiter { + self.inner.delimiter() + } + + /// Returns the `TokenStream` of tokens that are delimited in this `Group`. + /// + /// Note that the returned token stream does not include the delimiter + /// returned above. + pub fn stream(&self) -> TokenStream { + TokenStream::_new(self.inner.stream()) + } + + /// Returns the span for the delimiters of this token stream, spanning the + /// entire `Group`. + /// + /// ```text + /// pub fn span(&self) -> Span { + /// ^^^^^^^ + /// ``` + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } + + /// Returns the span pointing to the opening delimiter of this group. + /// + /// ```text + /// pub fn span_open(&self) -> Span { + /// ^ + /// ``` + pub fn span_open(&self) -> Span { + Span::_new(self.inner.span_open()) + } + + /// Returns the span pointing to the closing delimiter of this group. + /// + /// ```text + /// pub fn span_close(&self) -> Span { + /// ^ + /// ``` + pub fn span_close(&self) -> Span { + Span::_new(self.inner.span_close()) + } + + /// Returns an object that holds this group's `span_open()` and + /// `span_close()` together (in a more compact representation than holding + /// those 2 spans individually). + pub fn delim_span(&self) -> DelimSpan { + DelimSpan::new(&self.inner) + } + + /// Configures the span for this `Group`'s delimiters, but not its internal + /// tokens. + /// + /// This method will **not** set the span of all the internal tokens spanned + /// by this group, but rather it will only set the span of the delimiter + /// tokens at the level of the `Group`. + pub fn set_span(&mut self, span: Span) { + self.inner.set_span(span.inner); + } +} + +/// Prints the group as a string that should be losslessly convertible back +/// into the same group (modulo spans), except for possibly `TokenTree::Group`s +/// with `Delimiter::None` delimiters. +impl Display for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, formatter) + } +} + +impl Debug for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, formatter) + } +} + +/// A `Punct` is a single punctuation character like `+`, `-` or `#`. +/// +/// Multicharacter operators like `+=` are represented as two instances of +/// `Punct` with different forms of `Spacing` returned. +#[derive(Clone)] +pub struct Punct { + ch: char, + spacing: Spacing, + span: Span, +} + +/// Whether a `Punct` is followed immediately by another `Punct` or followed by +/// another token or whitespace. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Spacing { + /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. + Alone, + /// E.g. `+` is `Joint` in `+=` or `'` is `Joint` in `'#`. + /// + /// Additionally, single quote `'` can join with identifiers to form + /// lifetimes `'ident`. + Joint, +} + +impl Punct { + /// Creates a new `Punct` from the given character and spacing. + /// + /// The `ch` argument must be a valid punctuation character permitted by the + /// language, otherwise the function will panic. + /// + /// The returned `Punct` will have the default span of `Span::call_site()` + /// which can be further configured with the `set_span` method below. + pub fn new(ch: char, spacing: Spacing) -> Self { + Punct { + ch, + spacing, + span: Span::call_site(), + } + } + + /// Returns the value of this punctuation character as `char`. + pub fn as_char(&self) -> char { + self.ch + } + + /// Returns the spacing of this punctuation character, indicating whether + /// it's immediately followed by another `Punct` in the token stream, so + /// they can potentially be combined into a multicharacter operator + /// (`Joint`), or it's followed by some other token or whitespace (`Alone`) + /// so the operator has certainly ended. + pub fn spacing(&self) -> Spacing { + self.spacing + } + + /// Returns the span for this punctuation character. + pub fn span(&self) -> Span { + self.span + } + + /// Configure the span for this punctuation character. + pub fn set_span(&mut self, span: Span) { + self.span = span; + } +} + +/// Prints the punctuation character as a string that should be losslessly +/// convertible back into the same character. +impl Display for Punct { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.ch, f) + } +} + +impl Debug for Punct { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut debug = fmt.debug_struct("Punct"); + debug.field("char", &self.ch); + debug.field("spacing", &self.spacing); + imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner); + debug.finish() + } +} + +/// A word of Rust code, which may be a keyword or legal variable name. +/// +/// An identifier consists of at least one Unicode code point, the first of +/// which has the XID_Start property and the rest of which have the XID_Continue +/// property. +/// +/// - The empty string is not an identifier. Use `Option`. +/// - A lifetime is not an identifier. Use `syn::Lifetime` instead. +/// +/// An identifier constructed with `Ident::new` is permitted to be a Rust +/// keyword, though parsing one through its [`Parse`] implementation rejects +/// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the +/// behaviour of `Ident::new`. +/// +/// [`Parse`]: https://docs.rs/syn/2.0/syn/parse/trait.Parse.html +/// +/// # Examples +/// +/// A new ident can be created from a string using the `Ident::new` function. +/// A span must be provided explicitly which governs the name resolution +/// behavior of the resulting identifier. +/// +/// ``` +/// use proc_macro2::{Ident, Span}; +/// +/// fn main() { +/// let call_ident = Ident::new("calligraphy", Span::call_site()); +/// +/// println!("{}", call_ident); +/// } +/// ``` +/// +/// An ident can be interpolated into a token stream using the `quote!` macro. +/// +/// ``` +/// use proc_macro2::{Ident, Span}; +/// use quote::quote; +/// +/// fn main() { +/// let ident = Ident::new("demo", Span::call_site()); +/// +/// // Create a variable binding whose name is this ident. +/// let expanded = quote! { let #ident = 10; }; +/// +/// // Create a variable binding with a slightly different name. +/// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site()); +/// let expanded = quote! { let #temp_ident = 10; }; +/// } +/// ``` +/// +/// A string representation of the ident is available through the `to_string()` +/// method. +/// +/// ``` +/// # use proc_macro2::{Ident, Span}; +/// # +/// # let ident = Ident::new("another_identifier", Span::call_site()); +/// # +/// // Examine the ident as a string. +/// let ident_string = ident.to_string(); +/// if ident_string.len() > 60 { +/// println!("Very long identifier: {}", ident_string) +/// } +/// ``` +#[derive(Clone)] +pub struct Ident { + inner: imp::Ident, + _marker: ProcMacroAutoTraits, +} + +impl Ident { + fn _new(inner: imp::Ident) -> Self { + Ident { + inner, + _marker: MARKER, + } + } + + /// Creates a new `Ident` with the given `string` as well as the specified + /// `span`. + /// + /// The `string` argument must be a valid identifier permitted by the + /// language, otherwise the function will panic. + /// + /// Note that `span`, currently in rustc, configures the hygiene information + /// for this identifier. + /// + /// As of this time `Span::call_site()` explicitly opts-in to "call-site" + /// hygiene meaning that identifiers created with this span will be resolved + /// as if they were written directly at the location of the macro call, and + /// other code at the macro call site will be able to refer to them as well. + /// + /// Later spans like `Span::def_site()` will allow to opt-in to + /// "definition-site" hygiene meaning that identifiers created with this + /// span will be resolved at the location of the macro definition and other + /// code at the macro call site will not be able to refer to them. + /// + /// Due to the current importance of hygiene this constructor, unlike other + /// tokens, requires a `Span` to be specified at construction. + /// + /// # Panics + /// + /// Panics if the input string is neither a keyword nor a legal variable + /// name. If you are not sure whether the string contains an identifier and + /// need to handle an error case, use + /// syn::parse_str::<Ident> + /// rather than `Ident::new`. + #[track_caller] + pub fn new(string: &str, span: Span) -> Self { + Ident::_new(imp::Ident::new_checked(string, span.inner)) + } + + /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). The + /// `string` argument must be a valid identifier permitted by the language + /// (including keywords, e.g. `fn`). Keywords which are usable in path + /// segments (e.g. `self`, `super`) are not supported, and will cause a + /// panic. + #[track_caller] + pub fn new_raw(string: &str, span: Span) -> Self { + Ident::_new(imp::Ident::new_raw_checked(string, span.inner)) + } + + /// Returns the span of this `Ident`. + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } + + /// Configures the span of this `Ident`, possibly changing its hygiene + /// context. + pub fn set_span(&mut self, span: Span) { + self.inner.set_span(span.inner); + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + self.inner == other.inner + } +} + +impl PartialEq for Ident +where + T: ?Sized + AsRef, +{ + fn eq(&self, other: &T) -> bool { + self.inner == other + } +} + +impl Eq for Ident {} + +impl PartialOrd for Ident { + fn partial_cmp(&self, other: &Ident) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Ident { + fn cmp(&self, other: &Ident) -> Ordering { + self.to_string().cmp(&other.to_string()) + } +} + +impl Hash for Ident { + fn hash(&self, hasher: &mut H) { + self.to_string().hash(hasher); + } +} + +/// Prints the identifier as a string that should be losslessly convertible back +/// into the same identifier. +impl Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +impl Debug for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +/// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`), +/// byte character (`b'a'`), an integer or floating point number with or without +/// a suffix (`1`, `1u8`, `2.3`, `2.3f32`). +/// +/// Boolean literals like `true` and `false` do not belong here, they are +/// `Ident`s. +#[derive(Clone)] +pub struct Literal { + inner: imp::Literal, + _marker: ProcMacroAutoTraits, +} + +macro_rules! suffixed_int_literals { + ($($name:ident => $kind:ident,)*) => ($( + /// Creates a new suffixed integer literal with the specified value. + /// + /// This function will create an integer like `1u32` where the integer + /// value specified is the first part of the token and the integral is + /// also suffixed at the end. Literals created from negative numbers may + /// not survive roundtrips through `TokenStream` or strings and may be + /// broken into two tokens (`-` and positive literal). + /// + /// Literals created through this method have the `Span::call_site()` + /// span by default, which can be configured with the `set_span` method + /// below. + pub fn $name(n: $kind) -> Literal { + Literal::_new(imp::Literal::$name(n)) + } + )*) +} + +macro_rules! unsuffixed_int_literals { + ($($name:ident => $kind:ident,)*) => ($( + /// Creates a new unsuffixed integer literal with the specified value. + /// + /// This function will create an integer like `1` where the integer + /// value specified is the first part of the token. No suffix is + /// specified on this token, meaning that invocations like + /// `Literal::i8_unsuffixed(1)` are equivalent to + /// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers + /// may not survive roundtrips through `TokenStream` or strings and may + /// be broken into two tokens (`-` and positive literal). + /// + /// Literals created through this method have the `Span::call_site()` + /// span by default, which can be configured with the `set_span` method + /// below. + pub fn $name(n: $kind) -> Literal { + Literal::_new(imp::Literal::$name(n)) + } + )*) +} + +impl Literal { + fn _new(inner: imp::Literal) -> Self { + Literal { + inner, + _marker: MARKER, + } + } + + fn _new_fallback(inner: fallback::Literal) -> Self { + Literal { + inner: inner.into(), + _marker: MARKER, + } + } + + suffixed_int_literals! { + u8_suffixed => u8, + u16_suffixed => u16, + u32_suffixed => u32, + u64_suffixed => u64, + u128_suffixed => u128, + usize_suffixed => usize, + i8_suffixed => i8, + i16_suffixed => i16, + i32_suffixed => i32, + i64_suffixed => i64, + i128_suffixed => i128, + isize_suffixed => isize, + } + + unsuffixed_int_literals! { + u8_unsuffixed => u8, + u16_unsuffixed => u16, + u32_unsuffixed => u32, + u64_unsuffixed => u64, + u128_unsuffixed => u128, + usize_unsuffixed => usize, + i8_unsuffixed => i8, + i16_unsuffixed => i16, + i32_unsuffixed => i32, + i64_unsuffixed => i64, + i128_unsuffixed => i128, + isize_unsuffixed => isize, + } + + /// Creates a new unsuffixed floating-point literal. + /// + /// This constructor is similar to those like `Literal::i8_unsuffixed` where + /// the float's value is emitted directly into the token but no suffix is + /// used, so it may be inferred to be a `f64` later in the compiler. + /// Literals created from negative numbers may not survive round-trips + /// through `TokenStream` or strings and may be broken into two tokens (`-` + /// and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f64_unsuffixed(f: f64) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f64_unsuffixed(f)) + } + + /// Creates a new suffixed floating-point literal. + /// + /// This constructor will create a literal like `1.0f64` where the value + /// specified is the preceding part of the token and `f64` is the suffix of + /// the token. This token will always be inferred to be an `f64` in the + /// compiler. Literals created from negative numbers may not survive + /// round-trips through `TokenStream` or strings and may be broken into two + /// tokens (`-` and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f64_suffixed(f: f64) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f64_suffixed(f)) + } + + /// Creates a new unsuffixed floating-point literal. + /// + /// This constructor is similar to those like `Literal::i8_unsuffixed` where + /// the float's value is emitted directly into the token but no suffix is + /// used, so it may be inferred to be a `f64` later in the compiler. + /// Literals created from negative numbers may not survive round-trips + /// through `TokenStream` or strings and may be broken into two tokens (`-` + /// and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f32_unsuffixed(f: f32) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f32_unsuffixed(f)) + } + + /// Creates a new suffixed floating-point literal. + /// + /// This constructor will create a literal like `1.0f32` where the value + /// specified is the preceding part of the token and `f32` is the suffix of + /// the token. This token will always be inferred to be an `f32` in the + /// compiler. Literals created from negative numbers may not survive + /// round-trips through `TokenStream` or strings and may be broken into two + /// tokens (`-` and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f32_suffixed(f: f32) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f32_suffixed(f)) + } + + /// String literal. + pub fn string(string: &str) -> Literal { + Literal::_new(imp::Literal::string(string)) + } + + /// Character literal. + pub fn character(ch: char) -> Literal { + Literal::_new(imp::Literal::character(ch)) + } + + /// Byte string literal. + pub fn byte_string(s: &[u8]) -> Literal { + Literal::_new(imp::Literal::byte_string(s)) + } + + /// Returns the span encompassing this literal. + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } + + /// Configures the span associated for this literal. + pub fn set_span(&mut self, span: Span) { + self.inner.set_span(span.inner); + } + + /// Returns a `Span` that is a subset of `self.span()` containing only + /// the source bytes in range `range`. Returns `None` if the would-be + /// trimmed span is outside the bounds of `self`. + /// + /// Warning: the underlying [`proc_macro::Literal::subspan`] method is + /// nightly-only. When called from within a procedural macro not using a + /// nightly compiler, this method will always return `None`. + /// + /// [`proc_macro::Literal::subspan`]: https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.subspan + pub fn subspan>(&self, range: R) -> Option { + self.inner.subspan(range).map(Span::_new) + } + + // Intended for the `quote!` macro to use when constructing a proc-macro2 + // token out of a macro_rules $:literal token, which is already known to be + // a valid literal. This avoids reparsing/validating the literal's string + // representation. This is not public API other than for quote. + #[doc(hidden)] + pub unsafe fn from_str_unchecked(repr: &str) -> Self { + Literal::_new(unsafe { imp::Literal::from_str_unchecked(repr) }) + } +} + +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result { + repr.parse().map(Literal::_new).map_err(|inner| LexError { + inner, + _marker: MARKER, + }) + } +} + +impl Debug for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +/// Public implementation details for the `TokenStream` type, such as iterators. +pub mod token_stream { + use crate::marker::{ProcMacroAutoTraits, MARKER}; + use crate::{imp, TokenTree}; + use core::fmt::{self, Debug}; + + pub use crate::TokenStream; + + /// An iterator over `TokenStream`'s `TokenTree`s. + /// + /// The iteration is "shallow", e.g. the iterator doesn't recurse into + /// delimited groups, and returns whole groups as token trees. + #[derive(Clone)] + pub struct IntoIter { + inner: imp::TokenTreeIter, + _marker: ProcMacroAutoTraits, + } + + impl Iterator for IntoIter { + type Item = TokenTree; + + fn next(&mut self) -> Option { + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + } + + impl Debug for IntoIter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TokenStream ")?; + f.debug_list().entries(self.clone()).finish() + } + } + + impl IntoIterator for TokenStream { + type Item = TokenTree; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter { + inner: self.inner.into_iter(), + _marker: MARKER, + } + } + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/location.rs b/utshell-0.5.0/vendor/proc-macro2/src/location.rs new file mode 100644 index 00000000..463026c2 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/location.rs @@ -0,0 +1,29 @@ +use core::cmp::Ordering; + +/// A line-column pair representing the start or end of a `Span`. +/// +/// This type is semver exempt and not exposed by default. +#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct LineColumn { + /// The 1-indexed line in the source file on which the span starts or ends + /// (inclusive). + pub line: usize, + /// The 0-indexed column (in UTF-8 characters) in the source file on which + /// the span starts or ends (inclusive). + pub column: usize, +} + +impl Ord for LineColumn { + fn cmp(&self, other: &Self) -> Ordering { + self.line + .cmp(&other.line) + .then(self.column.cmp(&other.column)) + } +} + +impl PartialOrd for LineColumn { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/marker.rs b/utshell-0.5.0/vendor/proc-macro2/src/marker.rs new file mode 100644 index 00000000..23b94ce6 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/marker.rs @@ -0,0 +1,17 @@ +use alloc::rc::Rc; +use core::marker::PhantomData; +use core::panic::{RefUnwindSafe, UnwindSafe}; + +// Zero sized marker with the correct set of autotrait impls we want all proc +// macro types to have. +#[derive(Copy, Clone)] +#[cfg_attr( + all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)), + derive(PartialEq, Eq) +)] +pub(crate) struct ProcMacroAutoTraits(PhantomData>); + +pub(crate) const MARKER: ProcMacroAutoTraits = ProcMacroAutoTraits(PhantomData); + +impl UnwindSafe for ProcMacroAutoTraits {} +impl RefUnwindSafe for ProcMacroAutoTraits {} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/parse.rs b/utshell-0.5.0/vendor/proc-macro2/src/parse.rs new file mode 100644 index 00000000..07239bc3 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/parse.rs @@ -0,0 +1,996 @@ +use crate::fallback::{ + self, is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream, + TokenStreamBuilder, +}; +use crate::{Delimiter, Punct, Spacing, TokenTree}; +use core::char; +use core::str::{Bytes, CharIndices, Chars}; + +#[derive(Copy, Clone, Eq, PartialEq)] +pub(crate) struct Cursor<'a> { + pub rest: &'a str, + #[cfg(span_locations)] + pub off: u32, +} + +impl<'a> Cursor<'a> { + pub fn advance(&self, bytes: usize) -> Cursor<'a> { + let (_front, rest) = self.rest.split_at(bytes); + Cursor { + rest, + #[cfg(span_locations)] + off: self.off + _front.chars().count() as u32, + } + } + + pub fn starts_with(&self, s: &str) -> bool { + self.rest.starts_with(s) + } + + pub fn starts_with_char(&self, ch: char) -> bool { + self.rest.starts_with(ch) + } + + pub fn starts_with_fn(&self, f: Pattern) -> bool + where + Pattern: FnMut(char) -> bool, + { + self.rest.starts_with(f) + } + + pub fn is_empty(&self) -> bool { + self.rest.is_empty() + } + + fn len(&self) -> usize { + self.rest.len() + } + + fn as_bytes(&self) -> &'a [u8] { + self.rest.as_bytes() + } + + fn bytes(&self) -> Bytes<'a> { + self.rest.bytes() + } + + fn chars(&self) -> Chars<'a> { + self.rest.chars() + } + + fn char_indices(&self) -> CharIndices<'a> { + self.rest.char_indices() + } + + fn parse(&self, tag: &str) -> Result, Reject> { + if self.starts_with(tag) { + Ok(self.advance(tag.len())) + } else { + Err(Reject) + } + } +} + +pub(crate) struct Reject; +type PResult<'a, O> = Result<(Cursor<'a>, O), Reject>; + +fn skip_whitespace(input: Cursor) -> Cursor { + let mut s = input; + + while !s.is_empty() { + let byte = s.as_bytes()[0]; + if byte == b'/' { + if s.starts_with("//") + && (!s.starts_with("///") || s.starts_with("////")) + && !s.starts_with("//!") + { + let (cursor, _) = take_until_newline_or_eof(s); + s = cursor; + continue; + } else if s.starts_with("/**/") { + s = s.advance(4); + continue; + } else if s.starts_with("/*") + && (!s.starts_with("/**") || s.starts_with("/***")) + && !s.starts_with("/*!") + { + match block_comment(s) { + Ok((rest, _)) => { + s = rest; + continue; + } + Err(Reject) => return s, + } + } + } + match byte { + b' ' | 0x09..=0x0d => { + s = s.advance(1); + continue; + } + b if b.is_ascii() => {} + _ => { + let ch = s.chars().next().unwrap(); + if is_whitespace(ch) { + s = s.advance(ch.len_utf8()); + continue; + } + } + } + return s; + } + s +} + +fn block_comment(input: Cursor) -> PResult<&str> { + if !input.starts_with("/*") { + return Err(Reject); + } + + let mut depth = 0usize; + let bytes = input.as_bytes(); + let mut i = 0usize; + let upper = bytes.len() - 1; + + while i < upper { + if bytes[i] == b'/' && bytes[i + 1] == b'*' { + depth += 1; + i += 1; // eat '*' + } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { + depth -= 1; + if depth == 0 { + return Ok((input.advance(i + 2), &input.rest[..i + 2])); + } + i += 1; // eat '/' + } + i += 1; + } + + Err(Reject) +} + +fn is_whitespace(ch: char) -> bool { + // Rust treats left-to-right mark and right-to-left mark as whitespace + ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' +} + +fn word_break(input: Cursor) -> Result { + match input.chars().next() { + Some(ch) if is_ident_continue(ch) => Err(Reject), + Some(_) | None => Ok(input), + } +} + +// Rustc's representation of a macro expansion error in expression position or +// type position. +const ERROR: &str = "(/*ERROR*/)"; + +pub(crate) fn token_stream(mut input: Cursor) -> Result { + let mut trees = TokenStreamBuilder::new(); + let mut stack = Vec::new(); + + loop { + input = skip_whitespace(input); + + if let Ok((rest, ())) = doc_comment(input, &mut trees) { + input = rest; + continue; + } + + #[cfg(span_locations)] + let lo = input.off; + + let first = match input.bytes().next() { + Some(first) => first, + None => match stack.last() { + None => return Ok(trees.build()), + #[cfg(span_locations)] + Some((lo, _frame)) => { + return Err(LexError { + span: Span { lo: *lo, hi: *lo }, + }) + } + #[cfg(not(span_locations))] + Some(_frame) => return Err(LexError { span: Span {} }), + }, + }; + + if let Some(open_delimiter) = match first { + b'(' if !input.starts_with(ERROR) => Some(Delimiter::Parenthesis), + b'[' => Some(Delimiter::Bracket), + b'{' => Some(Delimiter::Brace), + _ => None, + } { + input = input.advance(1); + let frame = (open_delimiter, trees); + #[cfg(span_locations)] + let frame = (lo, frame); + stack.push(frame); + trees = TokenStreamBuilder::new(); + } else if let Some(close_delimiter) = match first { + b')' => Some(Delimiter::Parenthesis), + b']' => Some(Delimiter::Bracket), + b'}' => Some(Delimiter::Brace), + _ => None, + } { + let frame = match stack.pop() { + Some(frame) => frame, + None => return Err(lex_error(input)), + }; + #[cfg(span_locations)] + let (lo, frame) = frame; + let (open_delimiter, outer) = frame; + if open_delimiter != close_delimiter { + return Err(lex_error(input)); + } + input = input.advance(1); + let mut g = Group::new(open_delimiter, trees.build()); + g.set_span(Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: input.off, + }); + trees = outer; + trees.push_token_from_parser(TokenTree::Group(crate::Group::_new_fallback(g))); + } else { + let (rest, mut tt) = match leaf_token(input) { + Ok((rest, tt)) => (rest, tt), + Err(Reject) => return Err(lex_error(input)), + }; + tt.set_span(crate::Span::_new_fallback(Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + })); + trees.push_token_from_parser(tt); + input = rest; + } + } +} + +fn lex_error(cursor: Cursor) -> LexError { + #[cfg(not(span_locations))] + let _ = cursor; + LexError { + span: Span { + #[cfg(span_locations)] + lo: cursor.off, + #[cfg(span_locations)] + hi: cursor.off, + }, + } +} + +fn leaf_token(input: Cursor) -> PResult { + if let Ok((input, l)) = literal(input) { + // must be parsed before ident + Ok((input, TokenTree::Literal(crate::Literal::_new_fallback(l)))) + } else if let Ok((input, p)) = punct(input) { + Ok((input, TokenTree::Punct(p))) + } else if let Ok((input, i)) = ident(input) { + Ok((input, TokenTree::Ident(i))) + } else if input.starts_with(ERROR) { + let rest = input.advance(ERROR.len()); + let repr = crate::Literal::_new_fallback(Literal::_new(ERROR.to_owned())); + Ok((rest, TokenTree::Literal(repr))) + } else { + Err(Reject) + } +} + +fn ident(input: Cursor) -> PResult { + if [ + "r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#", "c\"", "cr\"", "cr#", + ] + .iter() + .any(|prefix| input.starts_with(prefix)) + { + Err(Reject) + } else { + ident_any(input) + } +} + +fn ident_any(input: Cursor) -> PResult { + let raw = input.starts_with("r#"); + let rest = input.advance((raw as usize) << 1); + + let (rest, sym) = ident_not_raw(rest)?; + + if !raw { + let ident = crate::Ident::_new(crate::imp::Ident::new_unchecked( + sym, + fallback::Span::call_site(), + )); + return Ok((rest, ident)); + } + + match sym { + "_" | "super" | "self" | "Self" | "crate" => return Err(Reject), + _ => {} + } + + let ident = crate::Ident::_new(crate::imp::Ident::new_raw_unchecked( + sym, + fallback::Span::call_site(), + )); + Ok((rest, ident)) +} + +fn ident_not_raw(input: Cursor) -> PResult<&str> { + let mut chars = input.char_indices(); + + match chars.next() { + Some((_, ch)) if is_ident_start(ch) => {} + _ => return Err(Reject), + } + + let mut end = input.len(); + for (i, ch) in chars { + if !is_ident_continue(ch) { + end = i; + break; + } + } + + Ok((input.advance(end), &input.rest[..end])) +} + +pub(crate) fn literal(input: Cursor) -> PResult { + let rest = literal_nocapture(input)?; + let end = input.len() - rest.len(); + Ok((rest, Literal::_new(input.rest[..end].to_string()))) +} + +fn literal_nocapture(input: Cursor) -> Result { + if let Ok(ok) = string(input) { + Ok(ok) + } else if let Ok(ok) = byte_string(input) { + Ok(ok) + } else if let Ok(ok) = c_string(input) { + Ok(ok) + } else if let Ok(ok) = byte(input) { + Ok(ok) + } else if let Ok(ok) = character(input) { + Ok(ok) + } else if let Ok(ok) = float(input) { + Ok(ok) + } else if let Ok(ok) = int(input) { + Ok(ok) + } else { + Err(Reject) + } +} + +fn literal_suffix(input: Cursor) -> Cursor { + match ident_not_raw(input) { + Ok((input, _)) => input, + Err(Reject) => input, + } +} + +fn string(input: Cursor) -> Result { + if let Ok(input) = input.parse("\"") { + cooked_string(input) + } else if let Ok(input) = input.parse("r") { + raw_string(input) + } else { + Err(Reject) + } +} + +fn cooked_string(mut input: Cursor) -> Result { + let mut chars = input.char_indices(); + + while let Some((i, ch)) = chars.next() { + match ch { + '"' => { + let input = input.advance(i + 1); + return Ok(literal_suffix(input)); + } + '\r' => match chars.next() { + Some((_, '\n')) => {} + _ => break, + }, + '\\' => match chars.next() { + Some((_, 'x')) => { + backslash_x_char(&mut chars)?; + } + Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0')) => {} + Some((_, 'u')) => { + backslash_u(&mut chars)?; + } + Some((newline, ch @ ('\n' | '\r'))) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, ch as u8)?; + chars = input.char_indices(); + } + _ => break, + }, + _ch => {} + } + } + Err(Reject) +} + +fn raw_string(input: Cursor) -> Result { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + _ => {} + } + } + Err(Reject) +} + +fn byte_string(input: Cursor) -> Result { + if let Ok(input) = input.parse("b\"") { + cooked_byte_string(input) + } else if let Ok(input) = input.parse("br") { + raw_byte_string(input) + } else { + Err(Reject) + } +} + +fn cooked_byte_string(mut input: Cursor) -> Result { + let mut bytes = input.bytes().enumerate(); + while let Some((offset, b)) = bytes.next() { + match b { + b'"' => { + let input = input.advance(offset + 1); + return Ok(literal_suffix(input)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + b'\\' => match bytes.next() { + Some((_, b'x')) => { + backslash_x_byte(&mut bytes)?; + } + Some((_, b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"')) => {} + Some((newline, b @ (b'\n' | b'\r'))) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, b)?; + bytes = input.bytes().enumerate(); + } + _ => break, + }, + b if b.is_ascii() => {} + _ => break, + } + } + Err(Reject) +} + +fn delimiter_of_raw_string(input: Cursor) -> PResult<&str> { + for (i, byte) in input.bytes().enumerate() { + match byte { + b'"' => { + if i > 255 { + // https://github.com/rust-lang/rust/pull/95251 + return Err(Reject); + } + return Ok((input.advance(i + 1), &input.rest[..i])); + } + b'#' => {} + _ => break, + } + } + Err(Reject) +} + +fn raw_byte_string(input: Cursor) -> Result { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + other => { + if !other.is_ascii() { + break; + } + } + } + } + Err(Reject) +} + +fn c_string(input: Cursor) -> Result { + if let Ok(input) = input.parse("c\"") { + cooked_c_string(input) + } else if let Ok(input) = input.parse("cr") { + raw_c_string(input) + } else { + Err(Reject) + } +} + +fn raw_c_string(input: Cursor) -> Result { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + b'\0' => break, + _ => {} + } + } + Err(Reject) +} + +fn cooked_c_string(mut input: Cursor) -> Result { + let mut chars = input.char_indices(); + + while let Some((i, ch)) = chars.next() { + match ch { + '"' => { + let input = input.advance(i + 1); + return Ok(literal_suffix(input)); + } + '\r' => match chars.next() { + Some((_, '\n')) => {} + _ => break, + }, + '\\' => match chars.next() { + Some((_, 'x')) => { + backslash_x_nonzero(&mut chars)?; + } + Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"')) => {} + Some((_, 'u')) => { + if backslash_u(&mut chars)? == '\0' { + break; + } + } + Some((newline, ch @ ('\n' | '\r'))) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, ch as u8)?; + chars = input.char_indices(); + } + _ => break, + }, + '\0' => break, + _ch => {} + } + } + Err(Reject) +} + +fn byte(input: Cursor) -> Result { + let input = input.parse("b'")?; + let mut bytes = input.bytes().enumerate(); + let ok = match bytes.next().map(|(_, b)| b) { + Some(b'\\') => match bytes.next().map(|(_, b)| b) { + Some(b'x') => backslash_x_byte(&mut bytes).is_ok(), + Some(b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"') => true, + _ => false, + }, + b => b.is_some(), + }; + if !ok { + return Err(Reject); + } + let (offset, _) = bytes.next().ok_or(Reject)?; + if !input.chars().as_str().is_char_boundary(offset) { + return Err(Reject); + } + let input = input.advance(offset).parse("'")?; + Ok(literal_suffix(input)) +} + +fn character(input: Cursor) -> Result { + let input = input.parse("'")?; + let mut chars = input.char_indices(); + let ok = match chars.next().map(|(_, ch)| ch) { + Some('\\') => match chars.next().map(|(_, ch)| ch) { + Some('x') => backslash_x_char(&mut chars).is_ok(), + Some('u') => backslash_u(&mut chars).is_ok(), + Some('n' | 'r' | 't' | '\\' | '0' | '\'' | '"') => true, + _ => false, + }, + ch => ch.is_some(), + }; + if !ok { + return Err(Reject); + } + let (idx, _) = chars.next().ok_or(Reject)?; + let input = input.advance(idx).parse("'")?; + Ok(literal_suffix(input)) +} + +macro_rules! next_ch { + ($chars:ident @ $pat:pat) => { + match $chars.next() { + Some((_, ch)) => match ch { + $pat => ch, + _ => return Err(Reject), + }, + None => return Err(Reject), + } + }; +} + +fn backslash_x_char(chars: &mut I) -> Result<(), Reject> +where + I: Iterator, +{ + next_ch!(chars @ '0'..='7'); + next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + Ok(()) +} + +fn backslash_x_byte(chars: &mut I) -> Result<(), Reject> +where + I: Iterator, +{ + next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); + next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); + Ok(()) +} + +fn backslash_x_nonzero(chars: &mut I) -> Result<(), Reject> +where + I: Iterator, +{ + let first = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + let second = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + if first == '0' && second == '0' { + Err(Reject) + } else { + Ok(()) + } +} + +fn backslash_u(chars: &mut I) -> Result +where + I: Iterator, +{ + next_ch!(chars @ '{'); + let mut value = 0; + let mut len = 0; + for (_, ch) in chars { + let digit = match ch { + '0'..='9' => ch as u8 - b'0', + 'a'..='f' => 10 + ch as u8 - b'a', + 'A'..='F' => 10 + ch as u8 - b'A', + '_' if len > 0 => continue, + '}' if len > 0 => return char::from_u32(value).ok_or(Reject), + _ => break, + }; + if len == 6 { + break; + } + value *= 0x10; + value += u32::from(digit); + len += 1; + } + Err(Reject) +} + +fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> { + let mut whitespace = input.bytes().enumerate(); + loop { + if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') { + return Err(Reject); + } + match whitespace.next() { + Some((_, b @ (b' ' | b'\t' | b'\n' | b'\r'))) => { + last = b; + } + Some((offset, _)) => { + *input = input.advance(offset); + return Ok(()); + } + None => return Err(Reject), + } + } +} + +fn float(input: Cursor) -> Result { + let mut rest = float_digits(input)?; + if let Some(ch) = rest.chars().next() { + if is_ident_start(ch) { + rest = ident_not_raw(rest)?.0; + } + } + word_break(rest) +} + +fn float_digits(input: Cursor) -> Result { + let mut chars = input.chars().peekable(); + match chars.next() { + Some(ch) if '0' <= ch && ch <= '9' => {} + _ => return Err(Reject), + } + + let mut len = 1; + let mut has_dot = false; + let mut has_exp = false; + while let Some(&ch) = chars.peek() { + match ch { + '0'..='9' | '_' => { + chars.next(); + len += 1; + } + '.' => { + if has_dot { + break; + } + chars.next(); + if chars + .peek() + .map_or(false, |&ch| ch == '.' || is_ident_start(ch)) + { + return Err(Reject); + } + len += 1; + has_dot = true; + } + 'e' | 'E' => { + chars.next(); + len += 1; + has_exp = true; + break; + } + _ => break, + } + } + + if !(has_dot || has_exp) { + return Err(Reject); + } + + if has_exp { + let token_before_exp = if has_dot { + Ok(input.advance(len - 1)) + } else { + Err(Reject) + }; + let mut has_sign = false; + let mut has_exp_value = false; + while let Some(&ch) = chars.peek() { + match ch { + '+' | '-' => { + if has_exp_value { + break; + } + if has_sign { + return token_before_exp; + } + chars.next(); + len += 1; + has_sign = true; + } + '0'..='9' => { + chars.next(); + len += 1; + has_exp_value = true; + } + '_' => { + chars.next(); + len += 1; + } + _ => break, + } + } + if !has_exp_value { + return token_before_exp; + } + } + + Ok(input.advance(len)) +} + +fn int(input: Cursor) -> Result { + let mut rest = digits(input)?; + if let Some(ch) = rest.chars().next() { + if is_ident_start(ch) { + rest = ident_not_raw(rest)?.0; + } + } + word_break(rest) +} + +fn digits(mut input: Cursor) -> Result { + let base = if input.starts_with("0x") { + input = input.advance(2); + 16 + } else if input.starts_with("0o") { + input = input.advance(2); + 8 + } else if input.starts_with("0b") { + input = input.advance(2); + 2 + } else { + 10 + }; + + let mut len = 0; + let mut empty = true; + for b in input.bytes() { + match b { + b'0'..=b'9' => { + let digit = (b - b'0') as u64; + if digit >= base { + return Err(Reject); + } + } + b'a'..=b'f' => { + let digit = 10 + (b - b'a') as u64; + if digit >= base { + break; + } + } + b'A'..=b'F' => { + let digit = 10 + (b - b'A') as u64; + if digit >= base { + break; + } + } + b'_' => { + if empty && base == 10 { + return Err(Reject); + } + len += 1; + continue; + } + _ => break, + }; + len += 1; + empty = false; + } + if empty { + Err(Reject) + } else { + Ok(input.advance(len)) + } +} + +fn punct(input: Cursor) -> PResult { + let (rest, ch) = punct_char(input)?; + if ch == '\'' { + if ident_any(rest)?.0.starts_with_char('\'') { + Err(Reject) + } else { + Ok((rest, Punct::new('\'', Spacing::Joint))) + } + } else { + let kind = match punct_char(rest) { + Ok(_) => Spacing::Joint, + Err(Reject) => Spacing::Alone, + }; + Ok((rest, Punct::new(ch, kind))) + } +} + +fn punct_char(input: Cursor) -> PResult { + if input.starts_with("//") || input.starts_with("/*") { + // Do not accept `/` of a comment as a punct. + return Err(Reject); + } + + let mut chars = input.chars(); + let first = match chars.next() { + Some(ch) => ch, + None => { + return Err(Reject); + } + }; + let recognized = "~!@#$%^&*-=+|;:,<.>/?'"; + if recognized.contains(first) { + Ok((input.advance(first.len_utf8()), first)) + } else { + Err(Reject) + } +} + +fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> { + #[cfg(span_locations)] + let lo = input.off; + let (rest, (comment, inner)) = doc_comment_contents(input)?; + let fallback_span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; + let span = crate::Span::_new_fallback(fallback_span); + + let mut scan_for_bare_cr = comment; + while let Some(cr) = scan_for_bare_cr.find('\r') { + let rest = &scan_for_bare_cr[cr + 1..]; + if !rest.starts_with('\n') { + return Err(Reject); + } + scan_for_bare_cr = rest; + } + + let mut pound = Punct::new('#', Spacing::Alone); + pound.set_span(span); + trees.push_token_from_parser(TokenTree::Punct(pound)); + + if inner { + let mut bang = Punct::new('!', Spacing::Alone); + bang.set_span(span); + trees.push_token_from_parser(TokenTree::Punct(bang)); + } + + let doc_ident = crate::Ident::_new(crate::imp::Ident::new_unchecked("doc", fallback_span)); + let mut equal = Punct::new('=', Spacing::Alone); + equal.set_span(span); + let mut literal = crate::Literal::string(comment); + literal.set_span(span); + let mut bracketed = TokenStreamBuilder::with_capacity(3); + bracketed.push_token_from_parser(TokenTree::Ident(doc_ident)); + bracketed.push_token_from_parser(TokenTree::Punct(equal)); + bracketed.push_token_from_parser(TokenTree::Literal(literal)); + let group = Group::new(Delimiter::Bracket, bracketed.build()); + let mut group = crate::Group::_new_fallback(group); + group.set_span(span); + trees.push_token_from_parser(TokenTree::Group(group)); + + Ok((rest, ())) +} + +fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> { + if input.starts_with("//!") { + let input = input.advance(3); + let (input, s) = take_until_newline_or_eof(input); + Ok((input, (s, true))) + } else if input.starts_with("/*!") { + let (input, s) = block_comment(input)?; + Ok((input, (&s[3..s.len() - 2], true))) + } else if input.starts_with("///") { + let input = input.advance(3); + if input.starts_with_char('/') { + return Err(Reject); + } + let (input, s) = take_until_newline_or_eof(input); + Ok((input, (s, false))) + } else if input.starts_with("/**") && !input.rest[3..].starts_with('*') { + let (input, s) = block_comment(input)?; + Ok((input, (&s[3..s.len() - 2], false))) + } else { + Err(Reject) + } +} + +fn take_until_newline_or_eof(input: Cursor) -> (Cursor, &str) { + let chars = input.char_indices(); + + for (i, ch) in chars { + if ch == '\n' { + return (input.advance(i), &input.rest[..i]); + } else if ch == '\r' && input.rest[i + 1..].starts_with('\n') { + return (input.advance(i + 1), &input.rest[..i]); + } + } + + (input.advance(input.len()), input.rest) +} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/rcvec.rs b/utshell-0.5.0/vendor/proc-macro2/src/rcvec.rs new file mode 100644 index 00000000..37955afb --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/rcvec.rs @@ -0,0 +1,145 @@ +use alloc::rc::Rc; +use alloc::vec; +use core::mem; +use core::panic::RefUnwindSafe; +use core::slice; + +pub(crate) struct RcVec { + inner: Rc>, +} + +pub(crate) struct RcVecBuilder { + inner: Vec, +} + +pub(crate) struct RcVecMut<'a, T> { + inner: &'a mut Vec, +} + +#[derive(Clone)] +pub(crate) struct RcVecIntoIter { + inner: vec::IntoIter, +} + +impl RcVec { + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + pub fn len(&self) -> usize { + self.inner.len() + } + + pub fn iter(&self) -> slice::Iter { + self.inner.iter() + } + + pub fn make_mut(&mut self) -> RcVecMut + where + T: Clone, + { + RcVecMut { + inner: Rc::make_mut(&mut self.inner), + } + } + + pub fn get_mut(&mut self) -> Option> { + let inner = Rc::get_mut(&mut self.inner)?; + Some(RcVecMut { inner }) + } + + pub fn make_owned(mut self) -> RcVecBuilder + where + T: Clone, + { + let vec = if let Some(owned) = Rc::get_mut(&mut self.inner) { + mem::take(owned) + } else { + Vec::clone(&self.inner) + }; + RcVecBuilder { inner: vec } + } +} + +impl RcVecBuilder { + pub fn new() -> Self { + RcVecBuilder { inner: Vec::new() } + } + + pub fn with_capacity(cap: usize) -> Self { + RcVecBuilder { + inner: Vec::with_capacity(cap), + } + } + + pub fn push(&mut self, element: T) { + self.inner.push(element); + } + + pub fn extend(&mut self, iter: impl IntoIterator) { + self.inner.extend(iter); + } + + pub fn as_mut(&mut self) -> RcVecMut { + RcVecMut { + inner: &mut self.inner, + } + } + + pub fn build(self) -> RcVec { + RcVec { + inner: Rc::new(self.inner), + } + } +} + +impl<'a, T> RcVecMut<'a, T> { + pub fn push(&mut self, element: T) { + self.inner.push(element); + } + + pub fn extend(&mut self, iter: impl IntoIterator) { + self.inner.extend(iter); + } + + pub fn pop(&mut self) -> Option { + self.inner.pop() + } + + pub fn as_mut(&mut self) -> RcVecMut { + RcVecMut { inner: self.inner } + } +} + +impl Clone for RcVec { + fn clone(&self) -> Self { + RcVec { + inner: Rc::clone(&self.inner), + } + } +} + +impl IntoIterator for RcVecBuilder { + type Item = T; + type IntoIter = RcVecIntoIter; + + fn into_iter(self) -> Self::IntoIter { + RcVecIntoIter { + inner: self.inner.into_iter(), + } + } +} + +impl Iterator for RcVecIntoIter { + type Item = T; + + fn next(&mut self) -> Option { + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +impl RefUnwindSafe for RcVec where T: RefUnwindSafe {} diff --git a/utshell-0.5.0/vendor/proc-macro2/src/wrapper.rs b/utshell-0.5.0/vendor/proc-macro2/src/wrapper.rs new file mode 100644 index 00000000..a71043ab --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/src/wrapper.rs @@ -0,0 +1,954 @@ +use crate::detection::inside_proc_macro; +#[cfg(span_locations)] +use crate::location::LineColumn; +use crate::{fallback, Delimiter, Punct, Spacing, TokenTree}; +use core::fmt::{self, Debug, Display}; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +use core::str::FromStr; +use std::panic; +#[cfg(super_unstable)] +use std::path::PathBuf; + +#[derive(Clone)] +pub(crate) enum TokenStream { + Compiler(DeferredTokenStream), + Fallback(fallback::TokenStream), +} + +// Work around https://github.com/rust-lang/rust/issues/65080. +// In `impl Extend for TokenStream` which is used heavily by quote, +// we hold on to the appended tokens and do proc_macro::TokenStream::extend as +// late as possible to batch together consecutive uses of the Extend impl. +#[derive(Clone)] +pub(crate) struct DeferredTokenStream { + stream: proc_macro::TokenStream, + extra: Vec, +} + +pub(crate) enum LexError { + Compiler(proc_macro::LexError), + Fallback(fallback::LexError), + + // Rustc was supposed to return a LexError, but it panicked instead. + // https://github.com/rust-lang/rust/issues/58736 + CompilerPanic, +} + +#[cold] +fn mismatch(line: u32) -> ! { + #[cfg(procmacro2_backtrace)] + { + let backtrace = std::backtrace::Backtrace::force_capture(); + panic!("compiler/fallback mismatch #{}\n\n{}", line, backtrace) + } + #[cfg(not(procmacro2_backtrace))] + { + panic!("compiler/fallback mismatch #{}", line) + } +} + +impl DeferredTokenStream { + fn new(stream: proc_macro::TokenStream) -> Self { + DeferredTokenStream { + stream, + extra: Vec::new(), + } + } + + fn is_empty(&self) -> bool { + self.stream.is_empty() && self.extra.is_empty() + } + + fn evaluate_now(&mut self) { + // If-check provides a fast short circuit for the common case of `extra` + // being empty, which saves a round trip over the proc macro bridge. + // Improves macro expansion time in winrt by 6% in debug mode. + if !self.extra.is_empty() { + self.stream.extend(self.extra.drain(..)); + } + } + + fn into_token_stream(mut self) -> proc_macro::TokenStream { + self.evaluate_now(); + self.stream + } +} + +impl TokenStream { + pub fn new() -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) + } else { + TokenStream::Fallback(fallback::TokenStream::new()) + } + } + + pub fn is_empty(&self) -> bool { + match self { + TokenStream::Compiler(tts) => tts.is_empty(), + TokenStream::Fallback(tts) => tts.is_empty(), + } + } + + fn unwrap_nightly(self) -> proc_macro::TokenStream { + match self { + TokenStream::Compiler(s) => s.into_token_stream(), + TokenStream::Fallback(_) => mismatch(line!()), + } + } + + fn unwrap_stable(self) -> fallback::TokenStream { + match self { + TokenStream::Compiler(_) => mismatch(line!()), + TokenStream::Fallback(s) => s, + } + } +} + +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + if inside_proc_macro() { + Ok(TokenStream::Compiler(DeferredTokenStream::new( + proc_macro_parse(src)?, + ))) + } else { + Ok(TokenStream::Fallback(src.parse()?)) + } + } +} + +// Work around https://github.com/rust-lang/rust/issues/58736. +fn proc_macro_parse(src: &str) -> Result { + let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler)); + result.unwrap_or_else(|_| Err(LexError::CompilerPanic)) +} + +impl Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f), + TokenStream::Fallback(tts) => Display::fmt(tts, f), + } + } +} + +impl From for TokenStream { + fn from(inner: proc_macro::TokenStream) -> Self { + TokenStream::Compiler(DeferredTokenStream::new(inner)) + } +} + +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + match inner { + TokenStream::Compiler(inner) => inner.into_token_stream(), + TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(), + } + } +} + +impl From for TokenStream { + fn from(inner: fallback::TokenStream) -> Self { + TokenStream::Fallback(inner) + } +} + +// Assumes inside_proc_macro(). +fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { + match token { + TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(), + TokenTree::Punct(tt) => { + let spacing = match tt.spacing() { + Spacing::Joint => proc_macro::Spacing::Joint, + Spacing::Alone => proc_macro::Spacing::Alone, + }; + let mut punct = proc_macro::Punct::new(tt.as_char(), spacing); + punct.set_span(tt.span().inner.unwrap_nightly()); + punct.into() + } + TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(), + TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(), + } +} + +impl From for TokenStream { + fn from(token: TokenTree) -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into())) + } else { + TokenStream::Fallback(token.into()) + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(trees: I) -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new( + trees.into_iter().map(into_compiler_token).collect(), + )) + } else { + TokenStream::Fallback(trees.into_iter().collect()) + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + let mut streams = streams.into_iter(); + match streams.next() { + Some(TokenStream::Compiler(mut first)) => { + first.evaluate_now(); + first.stream.extend(streams.map(|s| match s { + TokenStream::Compiler(s) => s.into_token_stream(), + TokenStream::Fallback(_) => mismatch(line!()), + })); + TokenStream::Compiler(first) + } + Some(TokenStream::Fallback(mut first)) => { + first.extend(streams.map(|s| match s { + TokenStream::Fallback(s) => s, + TokenStream::Compiler(_) => mismatch(line!()), + })); + TokenStream::Fallback(first) + } + None => TokenStream::new(), + } + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, stream: I) { + match self { + TokenStream::Compiler(tts) => { + // Here is the reason for DeferredTokenStream. + for token in stream { + tts.extra.push(into_compiler_token(token)); + } + } + TokenStream::Fallback(tts) => tts.extend(stream), + } + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + match self { + TokenStream::Compiler(tts) => { + tts.evaluate_now(); + tts.stream + .extend(streams.into_iter().map(TokenStream::unwrap_nightly)); + } + TokenStream::Fallback(tts) => { + tts.extend(streams.into_iter().map(TokenStream::unwrap_stable)); + } + } + } +} + +impl Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f), + TokenStream::Fallback(tts) => Debug::fmt(tts, f), + } + } +} + +impl LexError { + pub(crate) fn span(&self) -> Span { + match self { + LexError::Compiler(_) | LexError::CompilerPanic => Span::call_site(), + LexError::Fallback(e) => Span::Fallback(e.span()), + } + } +} + +impl From for LexError { + fn from(e: proc_macro::LexError) -> Self { + LexError::Compiler(e) + } +} + +impl From for LexError { + fn from(e: fallback::LexError) -> Self { + LexError::Fallback(e) + } +} + +impl Debug for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + LexError::Compiler(e) => Debug::fmt(e, f), + LexError::Fallback(e) => Debug::fmt(e, f), + LexError::CompilerPanic => { + let fallback = fallback::LexError::call_site(); + Debug::fmt(&fallback, f) + } + } + } +} + +impl Display for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + LexError::Compiler(e) => Display::fmt(e, f), + LexError::Fallback(e) => Display::fmt(e, f), + LexError::CompilerPanic => { + let fallback = fallback::LexError::call_site(); + Display::fmt(&fallback, f) + } + } + } +} + +#[derive(Clone)] +pub(crate) enum TokenTreeIter { + Compiler(proc_macro::token_stream::IntoIter), + Fallback(fallback::TokenTreeIter), +} + +impl IntoIterator for TokenStream { + type Item = TokenTree; + type IntoIter = TokenTreeIter; + + fn into_iter(self) -> TokenTreeIter { + match self { + TokenStream::Compiler(tts) => { + TokenTreeIter::Compiler(tts.into_token_stream().into_iter()) + } + TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()), + } + } +} + +impl Iterator for TokenTreeIter { + type Item = TokenTree; + + fn next(&mut self) -> Option { + let token = match self { + TokenTreeIter::Compiler(iter) => iter.next()?, + TokenTreeIter::Fallback(iter) => return iter.next(), + }; + Some(match token { + proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(), + proc_macro::TokenTree::Punct(tt) => { + let spacing = match tt.spacing() { + proc_macro::Spacing::Joint => Spacing::Joint, + proc_macro::Spacing::Alone => Spacing::Alone, + }; + let mut o = Punct::new(tt.as_char(), spacing); + o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); + o.into() + } + proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(), + proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(), + }) + } + + fn size_hint(&self) -> (usize, Option) { + match self { + TokenTreeIter::Compiler(tts) => tts.size_hint(), + TokenTreeIter::Fallback(tts) => tts.size_hint(), + } + } +} + +#[derive(Clone, PartialEq, Eq)] +#[cfg(super_unstable)] +pub(crate) enum SourceFile { + Compiler(proc_macro::SourceFile), + Fallback(fallback::SourceFile), +} + +#[cfg(super_unstable)] +impl SourceFile { + fn nightly(sf: proc_macro::SourceFile) -> Self { + SourceFile::Compiler(sf) + } + + /// Get the path to this source file as a string. + pub fn path(&self) -> PathBuf { + match self { + SourceFile::Compiler(a) => a.path(), + SourceFile::Fallback(a) => a.path(), + } + } + + pub fn is_real(&self) -> bool { + match self { + SourceFile::Compiler(a) => a.is_real(), + SourceFile::Fallback(a) => a.is_real(), + } + } +} + +#[cfg(super_unstable)] +impl Debug for SourceFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SourceFile::Compiler(a) => Debug::fmt(a, f), + SourceFile::Fallback(a) => Debug::fmt(a, f), + } + } +} + +#[derive(Copy, Clone)] +pub(crate) enum Span { + Compiler(proc_macro::Span), + Fallback(fallback::Span), +} + +impl Span { + pub fn call_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::call_site()) + } else { + Span::Fallback(fallback::Span::call_site()) + } + } + + pub fn mixed_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::mixed_site()) + } else { + Span::Fallback(fallback::Span::mixed_site()) + } + } + + #[cfg(super_unstable)] + pub fn def_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::def_site()) + } else { + Span::Fallback(fallback::Span::def_site()) + } + } + + pub fn resolved_at(&self, other: Span) -> Span { + match (self, other) { + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), + (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + pub fn located_at(&self, other: Span) -> Span { + match (self, other) { + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), + (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + pub fn unwrap(self) -> proc_macro::Span { + match self { + Span::Compiler(s) => s, + Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"), + } + } + + #[cfg(super_unstable)] + pub fn source_file(&self) -> SourceFile { + match self { + Span::Compiler(s) => SourceFile::nightly(s.source_file()), + Span::Fallback(s) => SourceFile::Fallback(s.source_file()), + } + } + + #[cfg(span_locations)] + pub fn byte_range(&self) -> Range { + match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => s.byte_range(), + #[cfg(not(proc_macro_span))] + Span::Compiler(_) => 0..0, + Span::Fallback(s) => s.byte_range(), + } + } + + #[cfg(span_locations)] + pub fn start(&self) -> LineColumn { + match self { + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, + Span::Fallback(s) => s.start(), + } + } + + #[cfg(span_locations)] + pub fn end(&self) -> LineColumn { + match self { + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, + Span::Fallback(s) => s.end(), + } + } + + pub fn join(&self, other: Span) -> Option { + let ret = match (self, other) { + #[cfg(proc_macro_span)] + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), + _ => return None, + }; + Some(ret) + } + + #[cfg(super_unstable)] + pub fn eq(&self, other: &Span) -> bool { + match (self, other) { + (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), + (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), + _ => false, + } + } + + pub fn source_text(&self) -> Option { + match self { + #[cfg(not(no_source_text))] + Span::Compiler(s) => s.source_text(), + #[cfg(no_source_text)] + Span::Compiler(_) => None, + Span::Fallback(s) => s.source_text(), + } + } + + fn unwrap_nightly(self) -> proc_macro::Span { + match self { + Span::Compiler(s) => s, + Span::Fallback(_) => mismatch(line!()), + } + } +} + +impl From for crate::Span { + fn from(proc_span: proc_macro::Span) -> Self { + crate::Span::_new(Span::Compiler(proc_span)) + } +} + +impl From for Span { + fn from(inner: fallback::Span) -> Self { + Span::Fallback(inner) + } +} + +impl Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Span::Compiler(s) => Debug::fmt(s, f), + Span::Fallback(s) => Debug::fmt(s, f), + } + } +} + +pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { + match span { + Span::Compiler(s) => { + debug.field("span", &s); + } + Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s), + } +} + +#[derive(Clone)] +pub(crate) enum Group { + Compiler(proc_macro::Group), + Fallback(fallback::Group), +} + +impl Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + match stream { + TokenStream::Compiler(tts) => { + let delimiter = match delimiter { + Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis, + Delimiter::Bracket => proc_macro::Delimiter::Bracket, + Delimiter::Brace => proc_macro::Delimiter::Brace, + Delimiter::None => proc_macro::Delimiter::None, + }; + Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream())) + } + TokenStream::Fallback(stream) => { + Group::Fallback(fallback::Group::new(delimiter, stream)) + } + } + } + + pub fn delimiter(&self) -> Delimiter { + match self { + Group::Compiler(g) => match g.delimiter() { + proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, + proc_macro::Delimiter::Bracket => Delimiter::Bracket, + proc_macro::Delimiter::Brace => Delimiter::Brace, + proc_macro::Delimiter::None => Delimiter::None, + }, + Group::Fallback(g) => g.delimiter(), + } + } + + pub fn stream(&self) -> TokenStream { + match self { + Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), + Group::Fallback(g) => TokenStream::Fallback(g.stream()), + } + } + + pub fn span(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span()), + Group::Fallback(g) => Span::Fallback(g.span()), + } + } + + pub fn span_open(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span_open()), + Group::Fallback(g) => Span::Fallback(g.span_open()), + } + } + + pub fn span_close(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span_close()), + Group::Fallback(g) => Span::Fallback(g.span_close()), + } + } + + pub fn set_span(&mut self, span: Span) { + match (self, span) { + (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), + (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), + (Group::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Group::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + fn unwrap_nightly(self) -> proc_macro::Group { + match self { + Group::Compiler(g) => g, + Group::Fallback(_) => mismatch(line!()), + } + } +} + +impl From for Group { + fn from(g: fallback::Group) -> Self { + Group::Fallback(g) + } +} + +impl Display for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + Group::Compiler(group) => Display::fmt(group, formatter), + Group::Fallback(group) => Display::fmt(group, formatter), + } + } +} + +impl Debug for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + Group::Compiler(group) => Debug::fmt(group, formatter), + Group::Fallback(group) => Debug::fmt(group, formatter), + } + } +} + +#[derive(Clone)] +pub(crate) enum Ident { + Compiler(proc_macro::Ident), + Fallback(fallback::Ident), +} + +impl Ident { + #[track_caller] + pub fn new_checked(string: &str, span: Span) -> Self { + match span { + Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), + Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_checked(string, s)), + } + } + + pub fn new_unchecked(string: &str, span: fallback::Span) -> Self { + Ident::Fallback(fallback::Ident::new_unchecked(string, span)) + } + + #[track_caller] + pub fn new_raw_checked(string: &str, span: Span) -> Self { + match span { + Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), + Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw_checked(string, s)), + } + } + + pub fn new_raw_unchecked(string: &str, span: fallback::Span) -> Self { + Ident::Fallback(fallback::Ident::new_raw_unchecked(string, span)) + } + + pub fn span(&self) -> Span { + match self { + Ident::Compiler(t) => Span::Compiler(t.span()), + Ident::Fallback(t) => Span::Fallback(t.span()), + } + } + + pub fn set_span(&mut self, span: Span) { + match (self, span) { + (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), + (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), + (Ident::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Ident::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + fn unwrap_nightly(self) -> proc_macro::Ident { + match self { + Ident::Compiler(s) => s, + Ident::Fallback(_) => mismatch(line!()), + } + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + match (self, other) { + (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(), + (Ident::Fallback(t), Ident::Fallback(o)) => t == o, + (Ident::Compiler(_), Ident::Fallback(_)) => mismatch(line!()), + (Ident::Fallback(_), Ident::Compiler(_)) => mismatch(line!()), + } + } +} + +impl PartialEq for Ident +where + T: ?Sized + AsRef, +{ + fn eq(&self, other: &T) -> bool { + let other = other.as_ref(); + match self { + Ident::Compiler(t) => t.to_string() == other, + Ident::Fallback(t) => t == other, + } + } +} + +impl Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Ident::Compiler(t) => Display::fmt(t, f), + Ident::Fallback(t) => Display::fmt(t, f), + } + } +} + +impl Debug for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Ident::Compiler(t) => Debug::fmt(t, f), + Ident::Fallback(t) => Debug::fmt(t, f), + } + } +} + +#[derive(Clone)] +pub(crate) enum Literal { + Compiler(proc_macro::Literal), + Fallback(fallback::Literal), +} + +macro_rules! suffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::$name(n)) + } else { + Literal::Fallback(fallback::Literal::$name(n)) + } + } + )*) +} + +macro_rules! unsuffixed_integers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::$name(n)) + } else { + Literal::Fallback(fallback::Literal::$name(n)) + } + } + )*) +} + +impl Literal { + pub unsafe fn from_str_unchecked(repr: &str) -> Self { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::from_str(repr).expect("invalid literal")) + } else { + Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) }) + } + } + + suffixed_numbers! { + u8_suffixed => u8, + u16_suffixed => u16, + u32_suffixed => u32, + u64_suffixed => u64, + u128_suffixed => u128, + usize_suffixed => usize, + i8_suffixed => i8, + i16_suffixed => i16, + i32_suffixed => i32, + i64_suffixed => i64, + i128_suffixed => i128, + isize_suffixed => isize, + + f32_suffixed => f32, + f64_suffixed => f64, + } + + unsuffixed_integers! { + u8_unsuffixed => u8, + u16_unsuffixed => u16, + u32_unsuffixed => u32, + u64_unsuffixed => u64, + u128_unsuffixed => u128, + usize_unsuffixed => usize, + i8_unsuffixed => i8, + i16_unsuffixed => i16, + i32_unsuffixed => i32, + i64_unsuffixed => i64, + i128_unsuffixed => i128, + isize_unsuffixed => isize, + } + + pub fn f32_unsuffixed(f: f32) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) + } else { + Literal::Fallback(fallback::Literal::f32_unsuffixed(f)) + } + } + + pub fn f64_unsuffixed(f: f64) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) + } else { + Literal::Fallback(fallback::Literal::f64_unsuffixed(f)) + } + } + + pub fn string(t: &str) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::string(t)) + } else { + Literal::Fallback(fallback::Literal::string(t)) + } + } + + pub fn character(t: char) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::character(t)) + } else { + Literal::Fallback(fallback::Literal::character(t)) + } + } + + pub fn byte_string(bytes: &[u8]) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::byte_string(bytes)) + } else { + Literal::Fallback(fallback::Literal::byte_string(bytes)) + } + } + + pub fn span(&self) -> Span { + match self { + Literal::Compiler(lit) => Span::Compiler(lit.span()), + Literal::Fallback(lit) => Span::Fallback(lit.span()), + } + } + + pub fn set_span(&mut self, span: Span) { + match (self, span) { + (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), + (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), + (Literal::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Literal::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + pub fn subspan>(&self, range: R) -> Option { + match self { + #[cfg(proc_macro_span)] + Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler), + #[cfg(not(proc_macro_span))] + Literal::Compiler(_lit) => None, + Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback), + } + } + + fn unwrap_nightly(self) -> proc_macro::Literal { + match self { + Literal::Compiler(s) => s, + Literal::Fallback(_) => mismatch(line!()), + } + } +} + +impl From for Literal { + fn from(s: fallback::Literal) -> Self { + Literal::Fallback(s) + } +} + +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result { + if inside_proc_macro() { + let literal = proc_macro::Literal::from_str(repr)?; + Ok(Literal::Compiler(literal)) + } else { + let literal = fallback::Literal::from_str(repr)?; + Ok(Literal::Fallback(literal)) + } + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Literal::Compiler(t) => Display::fmt(t, f), + Literal::Fallback(t) => Display::fmt(t, f), + } + } +} + +impl Debug for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Literal::Compiler(t) => Debug::fmt(t, f), + Literal::Fallback(t) => Debug::fmt(t, f), + } + } +} + +#[cfg(span_locations)] +pub(crate) fn invalidate_current_thread_spans() { + if inside_proc_macro() { + panic!( + "proc_macro2::extra::invalidate_current_thread_spans is not available in procedural macros" + ); + } else { + crate::fallback::invalidate_current_thread_spans(); + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/tests/comments.rs b/utshell-0.5.0/vendor/proc-macro2/tests/comments.rs new file mode 100644 index 00000000..4f7236de --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/tests/comments.rs @@ -0,0 +1,105 @@ +#![allow(clippy::assertions_on_result_states)] + +use proc_macro2::{Delimiter, Literal, Spacing, TokenStream, TokenTree}; + +// #[doc = "..."] -> "..." +fn lit_of_outer_doc_comment(tokens: &TokenStream) -> Literal { + lit_of_doc_comment(tokens, false) +} + +// #![doc = "..."] -> "..." +fn lit_of_inner_doc_comment(tokens: &TokenStream) -> Literal { + lit_of_doc_comment(tokens, true) +} + +fn lit_of_doc_comment(tokens: &TokenStream, inner: bool) -> Literal { + let mut iter = tokens.clone().into_iter(); + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '#'); + assert_eq!(punct.spacing(), Spacing::Alone); + } + _ => panic!("wrong token {:?}", tokens), + } + if inner { + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '!'); + assert_eq!(punct.spacing(), Spacing::Alone); + } + _ => panic!("wrong token {:?}", tokens), + } + } + iter = match iter.next().unwrap() { + TokenTree::Group(group) => { + assert_eq!(group.delimiter(), Delimiter::Bracket); + assert!(iter.next().is_none(), "unexpected token {:?}", tokens); + group.stream().into_iter() + } + _ => panic!("wrong token {:?}", tokens), + }; + match iter.next().unwrap() { + TokenTree::Ident(ident) => assert_eq!(ident.to_string(), "doc"), + _ => panic!("wrong token {:?}", tokens), + } + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '='); + assert_eq!(punct.spacing(), Spacing::Alone); + } + _ => panic!("wrong token {:?}", tokens), + } + match iter.next().unwrap() { + TokenTree::Literal(literal) => { + assert!(iter.next().is_none(), "unexpected token {:?}", tokens); + literal + } + _ => panic!("wrong token {:?}", tokens), + } +} + +#[test] +fn closed_immediately() { + let stream = "/**/".parse::().unwrap(); + let tokens = stream.into_iter().collect::>(); + assert!(tokens.is_empty(), "not empty -- {:?}", tokens); +} + +#[test] +fn incomplete() { + assert!("/*/".parse::().is_err()); +} + +#[test] +fn lit() { + let stream = "/// doc".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc\""); + + let stream = "//! doc".parse::().unwrap(); + let lit = lit_of_inner_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc\""); + + let stream = "/** doc */".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc \""); + + let stream = "/*! doc */".parse::().unwrap(); + let lit = lit_of_inner_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc \""); +} + +#[test] +fn carriage_return() { + let stream = "///\r\n".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\"\""); + + let stream = "/**\r\n*/".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\"\\r\\n\""); + + "///\r".parse::().unwrap_err(); + "///\r \n".parse::().unwrap_err(); + "/**\r \n*/".parse::().unwrap_err(); +} diff --git a/utshell-0.5.0/vendor/proc-macro2/tests/features.rs b/utshell-0.5.0/vendor/proc-macro2/tests/features.rs new file mode 100644 index 00000000..073f6e60 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/tests/features.rs @@ -0,0 +1,8 @@ +#[test] +#[ignore] +fn make_sure_no_proc_macro() { + assert!( + !cfg!(feature = "proc-macro"), + "still compiled with proc_macro?" + ); +} diff --git a/utshell-0.5.0/vendor/proc-macro2/tests/marker.rs b/utshell-0.5.0/vendor/proc-macro2/tests/marker.rs new file mode 100644 index 00000000..d08fbfc1 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/tests/marker.rs @@ -0,0 +1,99 @@ +#![allow(clippy::extra_unused_type_parameters)] + +use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, +}; + +macro_rules! assert_impl { + ($ty:ident is $($marker:ident) and +) => { + #[test] + #[allow(non_snake_case)] + fn $ty() { + fn assert_implemented() {} + assert_implemented::<$ty>(); + } + }; + + ($ty:ident is not $($marker:ident) or +) => { + #[test] + #[allow(non_snake_case)] + fn $ty() { + $( + { + // Implemented for types that implement $marker. + trait IsNotImplemented { + fn assert_not_implemented() {} + } + impl IsNotImplemented for T {} + + // Implemented for the type being tested. + trait IsImplemented { + fn assert_not_implemented() {} + } + impl IsImplemented for $ty {} + + // If $ty does not implement $marker, there is no ambiguity + // in the following trait method call. + <$ty>::assert_not_implemented(); + } + )+ + } + }; +} + +assert_impl!(Delimiter is Send and Sync); +assert_impl!(Spacing is Send and Sync); + +assert_impl!(Group is not Send or Sync); +assert_impl!(Ident is not Send or Sync); +assert_impl!(LexError is not Send or Sync); +assert_impl!(Literal is not Send or Sync); +assert_impl!(Punct is not Send or Sync); +assert_impl!(Span is not Send or Sync); +assert_impl!(TokenStream is not Send or Sync); +assert_impl!(TokenTree is not Send or Sync); + +#[cfg(procmacro2_semver_exempt)] +mod semver_exempt { + use proc_macro2::{LineColumn, SourceFile}; + + assert_impl!(LineColumn is Send and Sync); + + assert_impl!(SourceFile is not Send or Sync); +} + +mod unwind_safe { + use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, + }; + #[cfg(procmacro2_semver_exempt)] + use proc_macro2::{LineColumn, SourceFile}; + use std::panic::{RefUnwindSafe, UnwindSafe}; + + macro_rules! assert_unwind_safe { + ($($types:ident)*) => { + $( + assert_impl!($types is UnwindSafe and RefUnwindSafe); + )* + }; + } + + assert_unwind_safe! { + Delimiter + Group + Ident + LexError + Literal + Punct + Spacing + Span + TokenStream + TokenTree + } + + #[cfg(procmacro2_semver_exempt)] + assert_unwind_safe! { + LineColumn + SourceFile + } +} diff --git a/utshell-0.5.0/vendor/proc-macro2/tests/test.rs b/utshell-0.5.0/vendor/proc-macro2/tests/test.rs new file mode 100644 index 00000000..486955cf --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/tests/test.rs @@ -0,0 +1,795 @@ +#![allow( + clippy::assertions_on_result_states, + clippy::items_after_statements, + clippy::non_ascii_literal, + clippy::octal_escapes +)] + +use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; +use std::iter; +use std::str::{self, FromStr}; + +#[test] +fn idents() { + assert_eq!( + Ident::new("String", Span::call_site()).to_string(), + "String" + ); + assert_eq!(Ident::new("fn", Span::call_site()).to_string(), "fn"); + assert_eq!(Ident::new("_", Span::call_site()).to_string(), "_"); +} + +#[test] +fn raw_idents() { + assert_eq!( + Ident::new_raw("String", Span::call_site()).to_string(), + "r#String" + ); + assert_eq!(Ident::new_raw("fn", Span::call_site()).to_string(), "r#fn"); +} + +#[test] +#[should_panic(expected = "`r#_` cannot be a raw identifier")] +fn ident_raw_underscore() { + Ident::new_raw("_", Span::call_site()); +} + +#[test] +#[should_panic(expected = "`r#super` cannot be a raw identifier")] +fn ident_raw_reserved() { + Ident::new_raw("super", Span::call_site()); +} + +#[test] +#[should_panic(expected = "Ident is not allowed to be empty; use Option")] +fn ident_empty() { + Ident::new("", Span::call_site()); +} + +#[test] +#[should_panic(expected = "Ident cannot be a number; use Literal instead")] +fn ident_number() { + Ident::new("255", Span::call_site()); +} + +#[test] +#[should_panic(expected = "\"a#\" is not a valid Ident")] +fn ident_invalid() { + Ident::new("a#", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn raw_ident_empty() { + Ident::new("r#", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn raw_ident_number() { + Ident::new("r#255", Span::call_site()); +} + +#[test] +#[should_panic(expected = "\"r#a#\" is not a valid Ident")] +fn raw_ident_invalid() { + Ident::new("r#a#", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn lifetime_empty() { + Ident::new("'", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn lifetime_number() { + Ident::new("'255", Span::call_site()); +} + +#[test] +#[should_panic(expected = r#""'a#" is not a valid Ident"#)] +fn lifetime_invalid() { + Ident::new("'a#", Span::call_site()); +} + +#[test] +fn literal_string() { + assert_eq!(Literal::string("foo").to_string(), "\"foo\""); + assert_eq!(Literal::string("\"").to_string(), "\"\\\"\""); + assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); + assert_eq!( + Literal::string("a\00b\07c\08d\0e\0").to_string(), + "\"a\\x000b\\x007c\\08d\\0e\\0\"", + ); + + "\"\\\r\n x\"".parse::().unwrap(); + "\"\\\r\n \rx\"".parse::().unwrap_err(); +} + +#[test] +fn literal_raw_string() { + "r\"\r\n\"".parse::().unwrap(); + + fn raw_string_literal_with_hashes(n: usize) -> String { + let mut literal = String::new(); + literal.push('r'); + literal.extend(iter::repeat('#').take(n)); + literal.push('"'); + literal.push('"'); + literal.extend(iter::repeat('#').take(n)); + literal + } + + raw_string_literal_with_hashes(255) + .parse::() + .unwrap(); + + // https://github.com/rust-lang/rust/pull/95251 + raw_string_literal_with_hashes(256) + .parse::() + .unwrap_err(); +} + +#[test] +fn literal_byte_string() { + assert_eq!(Literal::byte_string(b"").to_string(), "b\"\""); + assert_eq!( + Literal::byte_string(b"\0\t\n\r\"\\2\x10").to_string(), + "b\"\\0\\t\\n\\r\\\"\\\\2\\x10\"", + ); + assert_eq!( + Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(), + "b\"a\\x000b\\x007c\\08d\\0e\\0\"", + ); + + "b\"\\\r\n x\"".parse::().unwrap(); + "b\"\\\r\n \rx\"".parse::().unwrap_err(); + "b\"\\\r\n \u{a0}x\"".parse::().unwrap_err(); + "br\"\u{a0}\"".parse::().unwrap_err(); +} + +#[test] +fn literal_c_string() { + let strings = r###" + c"hello\x80我å«\u{1F980}" // from the RFC + cr"\" + cr##"Hello "world"!"## + c"\t\n\r\"\\" + "###; + + let mut tokens = strings.parse::().unwrap().into_iter(); + + for expected in &[ + r#"c"hello\x80我å«\u{1F980}""#, + r#"cr"\""#, + r###"cr##"Hello "world"!"##"###, + r#"c"\t\n\r\"\\""#, + ] { + match tokens.next().unwrap() { + TokenTree::Literal(literal) => { + assert_eq!(literal.to_string(), *expected); + } + unexpected => panic!("unexpected token: {:?}", unexpected), + } + } + + if let Some(unexpected) = tokens.next() { + panic!("unexpected token: {:?}", unexpected); + } + + for invalid in &[r#"c"\0""#, r#"c"\x00""#, r#"c"\u{0}""#, "c\"\0\""] { + if let Ok(unexpected) = invalid.parse::() { + panic!("unexpected token: {:?}", unexpected); + } + } +} + +#[test] +fn literal_character() { + assert_eq!(Literal::character('x').to_string(), "'x'"); + assert_eq!(Literal::character('\'').to_string(), "'\\''"); + assert_eq!(Literal::character('"').to_string(), "'\"'"); +} + +#[test] +fn literal_integer() { + assert_eq!(Literal::u8_suffixed(10).to_string(), "10u8"); + assert_eq!(Literal::u16_suffixed(10).to_string(), "10u16"); + assert_eq!(Literal::u32_suffixed(10).to_string(), "10u32"); + assert_eq!(Literal::u64_suffixed(10).to_string(), "10u64"); + assert_eq!(Literal::u128_suffixed(10).to_string(), "10u128"); + assert_eq!(Literal::usize_suffixed(10).to_string(), "10usize"); + + assert_eq!(Literal::i8_suffixed(10).to_string(), "10i8"); + assert_eq!(Literal::i16_suffixed(10).to_string(), "10i16"); + assert_eq!(Literal::i32_suffixed(10).to_string(), "10i32"); + assert_eq!(Literal::i64_suffixed(10).to_string(), "10i64"); + assert_eq!(Literal::i128_suffixed(10).to_string(), "10i128"); + assert_eq!(Literal::isize_suffixed(10).to_string(), "10isize"); + + assert_eq!(Literal::u8_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::u16_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::u32_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::u64_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::u128_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::usize_unsuffixed(10).to_string(), "10"); + + assert_eq!(Literal::i8_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::i16_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::i32_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::i64_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::i128_unsuffixed(10).to_string(), "10"); + assert_eq!(Literal::isize_unsuffixed(10).to_string(), "10"); +} + +#[test] +fn literal_float() { + assert_eq!(Literal::f32_suffixed(10.0).to_string(), "10f32"); + assert_eq!(Literal::f64_suffixed(10.0).to_string(), "10f64"); + + assert_eq!(Literal::f32_unsuffixed(10.0).to_string(), "10.0"); + assert_eq!(Literal::f64_unsuffixed(10.0).to_string(), "10.0"); +} + +#[test] +fn literal_suffix() { + fn token_count(p: &str) -> usize { + p.parse::().unwrap().into_iter().count() + } + + assert_eq!(token_count("999u256"), 1); + assert_eq!(token_count("999r#u256"), 3); + assert_eq!(token_count("1."), 1); + assert_eq!(token_count("1.f32"), 3); + assert_eq!(token_count("1.0_0"), 1); + assert_eq!(token_count("1._0"), 3); + assert_eq!(token_count("1._m"), 3); + assert_eq!(token_count("\"\"s"), 1); + assert_eq!(token_count("r\"\"r"), 1); + assert_eq!(token_count("b\"\"b"), 1); + assert_eq!(token_count("br\"\"br"), 1); + assert_eq!(token_count("r#\"\"#r"), 1); + assert_eq!(token_count("'c'c"), 1); + assert_eq!(token_count("b'b'b"), 1); + assert_eq!(token_count("0E"), 1); + assert_eq!(token_count("0o0A"), 1); + assert_eq!(token_count("0E--0"), 4); + assert_eq!(token_count("0.0ECMA"), 1); +} + +#[test] +fn literal_iter_negative() { + let negative_literal = Literal::i32_suffixed(-3); + let tokens = TokenStream::from(TokenTree::Literal(negative_literal)); + let mut iter = tokens.into_iter(); + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '-'); + assert_eq!(punct.spacing(), Spacing::Alone); + } + unexpected => panic!("unexpected token {:?}", unexpected), + } + match iter.next().unwrap() { + TokenTree::Literal(literal) => { + assert_eq!(literal.to_string(), "3i32"); + } + unexpected => panic!("unexpected token {:?}", unexpected), + } + assert!(iter.next().is_none()); +} + +#[test] +fn literal_parse() { + assert!("1".parse::().is_ok()); + assert!("-1".parse::().is_ok()); + assert!("-1u12".parse::().is_ok()); + assert!("1.0".parse::().is_ok()); + assert!("-1.0".parse::().is_ok()); + assert!("-1.0f12".parse::().is_ok()); + assert!("'a'".parse::().is_ok()); + assert!("\"\n\"".parse::().is_ok()); + assert!("0 1".parse::().is_err()); + assert!(" 0".parse::().is_err()); + assert!("0 ".parse::().is_err()); + assert!("/* comment */0".parse::().is_err()); + assert!("0/* comment */".parse::().is_err()); + assert!("0// comment".parse::().is_err()); + assert!("- 1".parse::().is_err()); + assert!("- 1.0".parse::().is_err()); + assert!("-\"\"".parse::().is_err()); +} + +#[test] +fn literal_span() { + let positive = "0.1".parse::().unwrap(); + let negative = "-0.1".parse::().unwrap(); + let subspan = positive.subspan(1..2); + + #[cfg(not(span_locations))] + { + let _ = negative; + assert!(subspan.is_none()); + } + + #[cfg(span_locations)] + { + assert_eq!(positive.span().start().column, 0); + assert_eq!(positive.span().end().column, 3); + assert_eq!(negative.span().start().column, 0); + assert_eq!(negative.span().end().column, 4); + assert_eq!(subspan.unwrap().source_text().unwrap(), "."); + } + + assert!(positive.subspan(1..4).is_none()); +} + +#[cfg(span_locations)] +#[test] +fn source_text() { + let input = " 𓀕 a z "; + let mut tokens = input + .parse::() + .unwrap() + .into_iter(); + + let first = tokens.next().unwrap(); + assert_eq!("𓀕", first.span().source_text().unwrap()); + + let second = tokens.next().unwrap(); + let third = tokens.next().unwrap(); + assert_eq!("z", third.span().source_text().unwrap()); + assert_eq!("a", second.span().source_text().unwrap()); +} + +#[test] +fn roundtrip() { + fn roundtrip(p: &str) { + println!("parse: {}", p); + let s = p.parse::().unwrap().to_string(); + println!("first: {}", s); + let s2 = s.parse::().unwrap().to_string(); + assert_eq!(s, s2); + } + roundtrip("a"); + roundtrip("<<"); + roundtrip("<<="); + roundtrip( + " + 1 + 1.0 + 1f32 + 2f64 + 1usize + 4isize + 4e10 + 1_000 + 1_0i32 + 8u8 + 9 + 0 + 0xffffffffffffffffffffffffffffffff + 1x + 1u80 + 1f320 + ", + ); + roundtrip("'a"); + roundtrip("'_"); + roundtrip("'static"); + roundtrip("'\\u{10__FFFF}'"); + roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\""); +} + +#[test] +fn fail() { + fn fail(p: &str) { + if let Ok(s) = p.parse::() { + panic!("should have failed to parse: {}\n{:#?}", p, s); + } + } + fail("' static"); + fail("r#1"); + fail("r#_"); + fail("\"\\u{0000000}\""); // overlong unicode escape (rust allows at most 6 hex digits) + fail("\"\\u{999999}\""); // outside of valid range of char + fail("\"\\u{_0}\""); // leading underscore + fail("\"\\u{}\""); // empty + fail("b\"\r\""); // bare carriage return in byte string + fail("r\"\r\""); // bare carriage return in raw string + fail("\"\\\r \""); // backslash carriage return + fail("'aa'aa"); + fail("br##\"\"#"); + fail("\"\\\n\u{85}\r\""); +} + +#[cfg(span_locations)] +#[test] +fn span_test() { + check_spans( + "\ +/// This is a document comment +testing 123 +{ + testing 234 +}", + &[ + (1, 0, 1, 30), // # + (1, 0, 1, 30), // [ ... ] + (1, 0, 1, 30), // doc + (1, 0, 1, 30), // = + (1, 0, 1, 30), // "This is..." + (2, 0, 2, 7), // testing + (2, 8, 2, 11), // 123 + (3, 0, 5, 1), // { ... } + (4, 2, 4, 9), // testing + (4, 10, 4, 13), // 234 + ], + ); +} + +#[cfg(procmacro2_semver_exempt)] +#[cfg(not(nightly))] +#[test] +fn default_span() { + let start = Span::call_site().start(); + assert_eq!(start.line, 1); + assert_eq!(start.column, 0); + let end = Span::call_site().end(); + assert_eq!(end.line, 1); + assert_eq!(end.column, 0); + let source_file = Span::call_site().source_file(); + assert_eq!(source_file.path().to_string_lossy(), ""); + assert!(!source_file.is_real()); +} + +#[cfg(procmacro2_semver_exempt)] +#[test] +fn span_join() { + let source1 = "aaa\nbbb" + .parse::() + .unwrap() + .into_iter() + .collect::>(); + let source2 = "ccc\nddd" + .parse::() + .unwrap() + .into_iter() + .collect::>(); + + assert!(source1[0].span().source_file() != source2[0].span().source_file()); + assert_eq!( + source1[0].span().source_file(), + source1[1].span().source_file() + ); + + let joined1 = source1[0].span().join(source1[1].span()); + let joined2 = source1[0].span().join(source2[0].span()); + assert!(joined1.is_some()); + assert!(joined2.is_none()); + + let start = joined1.unwrap().start(); + let end = joined1.unwrap().end(); + assert_eq!(start.line, 1); + assert_eq!(start.column, 0); + assert_eq!(end.line, 2); + assert_eq!(end.column, 3); + + assert_eq!( + joined1.unwrap().source_file(), + source1[0].span().source_file() + ); +} + +#[test] +fn no_panic() { + let s = str::from_utf8(b"b\'\xc2\x86 \x00\x00\x00^\"").unwrap(); + assert!(s.parse::().is_err()); +} + +#[test] +fn punct_before_comment() { + let mut tts = TokenStream::from_str("~// comment").unwrap().into_iter(); + match tts.next().unwrap() { + TokenTree::Punct(tt) => { + assert_eq!(tt.as_char(), '~'); + assert_eq!(tt.spacing(), Spacing::Alone); + } + wrong => panic!("wrong token {:?}", wrong), + } +} + +#[test] +fn joint_last_token() { + // This test verifies that we match the behavior of libproc_macro *not* in + // the range nightly-2020-09-06 through nightly-2020-09-10, in which this + // behavior was temporarily broken. + // See https://github.com/rust-lang/rust/issues/76399 + + let joint_punct = Punct::new(':', Spacing::Joint); + let stream = TokenStream::from(TokenTree::Punct(joint_punct)); + let punct = match stream.into_iter().next().unwrap() { + TokenTree::Punct(punct) => punct, + _ => unreachable!(), + }; + assert_eq!(punct.spacing(), Spacing::Joint); +} + +#[test] +fn raw_identifier() { + let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter(); + match tts.next().unwrap() { + TokenTree::Ident(raw) => assert_eq!("r#dyn", raw.to_string()), + wrong => panic!("wrong token {:?}", wrong), + } + assert!(tts.next().is_none()); +} + +#[test] +fn test_debug_ident() { + let ident = Ident::new("proc_macro", Span::call_site()); + + #[cfg(not(span_locations))] + let expected = "Ident(proc_macro)"; + + #[cfg(span_locations)] + let expected = "Ident { sym: proc_macro }"; + + assert_eq!(expected, format!("{:?}", ident)); +} + +#[test] +fn test_debug_tokenstream() { + let tts = TokenStream::from_str("[a + 1]").unwrap(); + + #[cfg(not(span_locations))] + let expected = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, + }, + Punct { + char: '+', + spacing: Alone, + }, + Literal { + lit: 1, + }, + ], + }, +]\ + "; + + #[cfg(not(span_locations))] + let expected_before_trailing_commas = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a + }, + Punct { + char: '+', + spacing: Alone + }, + Literal { + lit: 1 + } + ] + } +]\ + "; + + #[cfg(span_locations)] + let expected = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, + span: bytes(2..3), + }, + Punct { + char: '+', + spacing: Alone, + span: bytes(4..5), + }, + Literal { + lit: 1, + span: bytes(6..7), + }, + ], + span: bytes(1..8), + }, +]\ + "; + + #[cfg(span_locations)] + let expected_before_trailing_commas = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, + span: bytes(2..3) + }, + Punct { + char: '+', + spacing: Alone, + span: bytes(4..5) + }, + Literal { + lit: 1, + span: bytes(6..7) + } + ], + span: bytes(1..8) + } +]\ + "; + + let actual = format!("{:#?}", tts); + if actual.ends_with(",\n]") { + assert_eq!(expected, actual); + } else { + assert_eq!(expected_before_trailing_commas, actual); + } +} + +#[test] +fn default_tokenstream_is_empty() { + let default_token_stream = ::default(); + + assert!(default_token_stream.is_empty()); +} + +#[test] +fn tokenstream_size_hint() { + let tokens = "a b (c d) e".parse::().unwrap(); + + assert_eq!(tokens.into_iter().size_hint(), (4, Some(4))); +} + +#[test] +fn tuple_indexing() { + // This behavior may change depending on https://github.com/rust-lang/rust/pull/71322 + let mut tokens = "tuple.0.0".parse::().unwrap().into_iter(); + assert_eq!("tuple", tokens.next().unwrap().to_string()); + assert_eq!(".", tokens.next().unwrap().to_string()); + assert_eq!("0.0", tokens.next().unwrap().to_string()); + assert!(tokens.next().is_none()); +} + +#[cfg(span_locations)] +#[test] +fn non_ascii_tokens() { + check_spans("// abc", &[]); + check_spans("// ábc", &[]); + check_spans("// abc x", &[]); + check_spans("// ábc x", &[]); + check_spans("/* abc */ x", &[(1, 10, 1, 11)]); + check_spans("/* ábc */ x", &[(1, 10, 1, 11)]); + check_spans("/* ab\nc */ x", &[(2, 5, 2, 6)]); + check_spans("/* áb\nc */ x", &[(2, 5, 2, 6)]); + check_spans("/*** abc */ x", &[(1, 12, 1, 13)]); + check_spans("/*** ábc */ x", &[(1, 12, 1, 13)]); + check_spans(r#""abc""#, &[(1, 0, 1, 5)]); + check_spans(r#""ábc""#, &[(1, 0, 1, 5)]); + check_spans(r##"r#"abc"#"##, &[(1, 0, 1, 8)]); + check_spans(r##"r#"ábc"#"##, &[(1, 0, 1, 8)]); + check_spans("r#\"a\nc\"#", &[(1, 0, 2, 3)]); + check_spans("r#\"á\nc\"#", &[(1, 0, 2, 3)]); + check_spans("'a'", &[(1, 0, 1, 3)]); + check_spans("'á'", &[(1, 0, 1, 3)]); + check_spans("//! abc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("//! ábc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("//! abc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("//! ábc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("/*! abc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); + check_spans("/*! ábc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); + check_spans("/*! a\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); + check_spans("/*! á\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); + check_spans("abc", &[(1, 0, 1, 3)]); + check_spans("ábc", &[(1, 0, 1, 3)]); + check_spans("ábć", &[(1, 0, 1, 3)]); + check_spans("abc// foo", &[(1, 0, 1, 3)]); + check_spans("ábc// foo", &[(1, 0, 1, 3)]); + check_spans("ábć// foo", &[(1, 0, 1, 3)]); + check_spans("b\"a\\\n c\"", &[(1, 0, 2, 3)]); +} + +#[cfg(span_locations)] +fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) { + let ts = p.parse::().unwrap(); + check_spans_internal(ts, &mut lines); + assert!(lines.is_empty(), "leftover ranges: {:?}", lines); +} + +#[cfg(span_locations)] +fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) { + for i in ts { + if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() { + *lines = rest; + + let start = i.span().start(); + assert_eq!(start.line, sline, "sline did not match for {}", i); + assert_eq!(start.column, scol, "scol did not match for {}", i); + + let end = i.span().end(); + assert_eq!(end.line, eline, "eline did not match for {}", i); + assert_eq!(end.column, ecol, "ecol did not match for {}", i); + + if let TokenTree::Group(g) = i { + check_spans_internal(g.stream().clone(), lines); + } + } + } +} + +#[test] +fn whitespace() { + // space, horizontal tab, vertical tab, form feed, carriage return, line + // feed, non-breaking space, left-to-right mark, right-to-left mark + let various_spaces = " \t\u{b}\u{c}\r\n\u{a0}\u{200e}\u{200f}"; + let tokens = various_spaces.parse::().unwrap(); + assert_eq!(tokens.into_iter().count(), 0); + + let lone_carriage_returns = " \r \r\r\n "; + lone_carriage_returns.parse::().unwrap(); +} + +#[test] +fn byte_order_mark() { + let string = "\u{feff}foo"; + let tokens = string.parse::().unwrap(); + match tokens.into_iter().next().unwrap() { + TokenTree::Ident(ident) => assert_eq!(ident, "foo"), + _ => unreachable!(), + } + + let string = "foo\u{feff}"; + string.parse::().unwrap_err(); +} + +#[cfg(span_locations)] +fn create_span() -> proc_macro2::Span { + let tts: TokenStream = "1".parse().unwrap(); + match tts.into_iter().next().unwrap() { + TokenTree::Literal(literal) => literal.span(), + _ => unreachable!(), + } +} + +#[cfg(span_locations)] +#[test] +fn test_invalidate_current_thread_spans() { + let actual = format!("{:#?}", create_span()); + assert_eq!(actual, "bytes(1..2)"); + let actual = format!("{:#?}", create_span()); + assert_eq!(actual, "bytes(3..4)"); + + proc_macro2::extra::invalidate_current_thread_spans(); + + let actual = format!("{:#?}", create_span()); + // Test that span offsets have been reset after the call + // to invalidate_current_thread_spans() + assert_eq!(actual, "bytes(1..2)"); +} + +#[cfg(span_locations)] +#[test] +#[should_panic(expected = "Invalid span with no related FileInfo!")] +fn test_use_span_after_invalidation() { + let span = create_span(); + + proc_macro2::extra::invalidate_current_thread_spans(); + + span.source_text(); +} diff --git a/utshell-0.5.0/vendor/proc-macro2/tests/test_fmt.rs b/utshell-0.5.0/vendor/proc-macro2/tests/test_fmt.rs new file mode 100644 index 00000000..86a4c387 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/tests/test_fmt.rs @@ -0,0 +1,28 @@ +#![allow(clippy::from_iter_instead_of_collect)] + +use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; +use std::iter; + +#[test] +fn test_fmt_group() { + let ident = Ident::new("x", Span::call_site()); + let inner = TokenStream::from_iter(iter::once(TokenTree::Ident(ident))); + let parens_empty = Group::new(Delimiter::Parenthesis, TokenStream::new()); + let parens_nonempty = Group::new(Delimiter::Parenthesis, inner.clone()); + let brackets_empty = Group::new(Delimiter::Bracket, TokenStream::new()); + let brackets_nonempty = Group::new(Delimiter::Bracket, inner.clone()); + let braces_empty = Group::new(Delimiter::Brace, TokenStream::new()); + let braces_nonempty = Group::new(Delimiter::Brace, inner.clone()); + let none_empty = Group::new(Delimiter::None, TokenStream::new()); + let none_nonempty = Group::new(Delimiter::None, inner); + + // Matches libproc_macro. + assert_eq!("()", parens_empty.to_string()); + assert_eq!("(x)", parens_nonempty.to_string()); + assert_eq!("[]", brackets_empty.to_string()); + assert_eq!("[x]", brackets_nonempty.to_string()); + assert_eq!("{ }", braces_empty.to_string()); + assert_eq!("{ x }", braces_nonempty.to_string()); + assert_eq!("", none_empty.to_string()); + assert_eq!("x", none_nonempty.to_string()); +} diff --git a/utshell-0.5.0/vendor/proc-macro2/tests/test_size.rs b/utshell-0.5.0/vendor/proc-macro2/tests/test_size.rs new file mode 100644 index 00000000..46e58db4 --- /dev/null +++ b/utshell-0.5.0/vendor/proc-macro2/tests/test_size.rs @@ -0,0 +1,42 @@ +extern crate proc_macro; + +use std::mem; + +#[rustversion::attr(before(1.32), ignore)] +#[test] +fn test_proc_macro_span_size() { + assert_eq!(mem::size_of::(), 4); + assert_eq!(mem::size_of::>(), 4); +} + +#[cfg_attr(not(all(not(wrap_proc_macro), not(span_locations))), ignore)] +#[test] +fn test_proc_macro2_fallback_span_size_without_locations() { + assert_eq!(mem::size_of::(), 0); + assert_eq!(mem::size_of::>(), 1); +} + +#[cfg_attr(not(all(not(wrap_proc_macro), span_locations)), ignore)] +#[test] +fn test_proc_macro2_fallback_span_size_with_locations() { + assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::size_of::>(), 12); +} + +#[rustversion::attr(before(1.32), ignore)] +#[rustversion::attr( + since(1.32), + cfg_attr(not(all(wrap_proc_macro, not(span_locations))), ignore) +)] +#[test] +fn test_proc_macro2_wrapper_span_size_without_locations() { + assert_eq!(mem::size_of::(), 4); + assert_eq!(mem::size_of::>(), 8); +} + +#[cfg_attr(not(all(wrap_proc_macro, span_locations)), ignore)] +#[test] +fn test_proc_macro2_wrapper_span_size_with_locations() { + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::size_of::>(), 12); +} diff --git a/utshell-0.5.0/vendor/quote/.cargo-checksum.json b/utshell-0.5.0/vendor/quote/.cargo-checksum.json new file mode 100644 index 00000000..0d900a27 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"0ec1e0fd36354750321a12d04a5e4d9a8d5dc6a8af753183de50da55fc10391b","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"626e7079eab0baacf0fcaf3e244f407b2014ebaeca45905d72e8fb8bed18aaea","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/ext.rs":"9881576cac3e476a4bf04f9b601cf9a53b79399fb0ca9634e8b861ac91709843","src/format.rs":"c595015418f35e6992e710441b9999f09b2afe4678b138039d670d100c0bdd86","src/ident_fragment.rs":"0b3e6c2129e55910fd2d240e1e7efba6f1796801d24352d1c0bfbceb0e8b678f","src/lib.rs":"cef1b4c031d401fb87e88a2ed51858c5f8f471e62a6261c1ef0f55ef9e1906a1","src/runtime.rs":"7f37326edaeac2c42ed806b447eeba12e36dd4b1bc25fbf52f8eb23140f3be7a","src/spanned.rs":"3ccf5120593f35787442c0a37d243e802c5262e7f8b35aed503873008ec035c5","src/to_tokens.rs":"1c76311fcc82098e630056d71fd6f3929194ee31b0840e2aa643ed7e78026e3e","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"3be80741f84a707376c230d9cf70ce9537caa359691d8d4c34968e28175e4ad7","tests/ui/does-not-have-iter-interpolated-dup.rs":"ad13eea21d4cdd2ab6c082f633392e1ff20fb0d1af5f2177041e0bf7f30da695","tests/ui/does-not-have-iter-interpolated-dup.stderr":"90a4bdb9267535f5d2785940148338d6b7d905548051d2c9c5dcbd58f2c11d8e","tests/ui/does-not-have-iter-interpolated.rs":"83a5b3f240651adcbe4b6e51076d76d653ad439b37442cf4054f1fd3c073f3b7","tests/ui/does-not-have-iter-interpolated.stderr":"ae7c2739554c862b331705e82781aa4687a4375210cef6ae899a4be4a4ec2d97","tests/ui/does-not-have-iter-separated.rs":"fe413c48331d5e3a7ae5fef6a5892a90c72f610d54595879eb49d0a94154ba3f","tests/ui/does-not-have-iter-separated.stderr":"03fd560979ebcd5aa6f83858bc2c3c01ba6546c16335101275505304895c1ae9","tests/ui/does-not-have-iter.rs":"09dc9499d861b63cebb0848b855b78e2dc9497bfde37ba6339f3625ae009a62f","tests/ui/does-not-have-iter.stderr":"d6da483c29e232ced72059bbdf05d31afb1df9e02954edaa9cfaea1ec6df72dc","tests/ui/not-quotable.rs":"5759d0884943417609f28faadc70254a3e2fd3d9bd6ff7297a3fb70a77fafd8a","tests/ui/not-quotable.stderr":"459bdadbf1e73b9401cf7d5d578dc053774bb4e5aa25ad2abf25d6b0f61aa306","tests/ui/not-repeatable.rs":"a4b115c04e4e41049a05f5b69450503fbffeba031218b4189cb931839f7f9a9c","tests/ui/not-repeatable.stderr":"594249d59d16f039c16816f1aaf9933176994e296fcf81d1b8b24d5b66ae0d0a","tests/ui/wrong-type-span.rs":"6195e35ea844c0c52ba1cff5d790c3a371af6915d137d377834ad984229ef9ea","tests/ui/wrong-type-span.stderr":"cad072e40e0ecc04f375122ae41aede2f0da2a9244492b3fcf70249e59d1b128"},"package":"291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/quote/Cargo.toml b/utshell-0.5.0/vendor/quote/Cargo.toml new file mode 100644 index 00000000..f3222c25 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/Cargo.toml @@ -0,0 +1,50 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.56" +name = "quote" +version = "1.0.35" +authors = ["David Tolnay "] +autobenches = false +description = "Quasi-quoting macro quote!(...)" +documentation = "https://docs.rs/quote/" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = ["development-tools::procedural-macro-helpers"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/quote" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +doc-scrape-examples = false + +[dependencies.proc-macro2] +version = "1.0.74" +default-features = false + +[dev-dependencies.rustversion] +version = "1.0" + +[dev-dependencies.trybuild] +version = "1.0.66" +features = ["diff"] + +[features] +default = ["proc-macro"] +proc-macro = ["proc-macro2/proc-macro"] diff --git a/utshell-0.5.0/vendor/quote/LICENSE-APACHE b/utshell-0.5.0/vendor/quote/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/utshell-0.5.0/vendor/quote/LICENSE-MIT b/utshell-0.5.0/vendor/quote/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/quote/README.md b/utshell-0.5.0/vendor/quote/README.md new file mode 100644 index 00000000..bfc91a97 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/README.md @@ -0,0 +1,272 @@ +Rust Quasi-Quoting +================== + +[github](https://github.com/dtolnay/quote) +[crates.io](https://crates.io/crates/quote) +[docs.rs](https://docs.rs/quote) +[build status](https://github.com/dtolnay/quote/actions?query=branch%3Amaster) + +This crate provides the [`quote!`] macro for turning Rust syntax tree data +structures into tokens of source code. + +[`quote!`]: https://docs.rs/quote/1.0/quote/macro.quote.html + +Procedural macros in Rust receive a stream of tokens as input, execute arbitrary +Rust code to determine how to manipulate those tokens, and produce a stream of +tokens to hand back to the compiler to compile into the caller's crate. +Quasi-quoting is a solution to one piece of that — producing tokens to +return to the compiler. + +The idea of quasi-quoting is that we write *code* that we treat as *data*. +Within the `quote!` macro, we can write what looks like code to our text editor +or IDE. We get all the benefits of the editor's brace matching, syntax +highlighting, indentation, and maybe autocompletion. But rather than compiling +that as code into the current crate, we can treat it as data, pass it around, +mutate it, and eventually hand it back to the compiler as tokens to compile into +the macro caller's crate. + +This crate is motivated by the procedural macro use case, but is a +general-purpose Rust quasi-quoting library and is not specific to procedural +macros. + +```toml +[dependencies] +quote = "1.0" +``` + +*Version requirement: Quote supports rustc 1.56 and up.*
+[*Release notes*](https://github.com/dtolnay/quote/releases) + +
+ +## Syntax + +The quote crate provides a [`quote!`] macro within which you can write Rust code +that gets packaged into a [`TokenStream`] and can be treated as data. You should +think of `TokenStream` as representing a fragment of Rust source code. + +[`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html + +Within the `quote!` macro, interpolation is done with `#var`. Any type +implementing the [`quote::ToTokens`] trait can be interpolated. This includes +most Rust primitive types as well as most of the syntax tree types from [`syn`]. + +[`quote::ToTokens`]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html +[`syn`]: https://github.com/dtolnay/syn + +```rust +let tokens = quote! { + struct SerializeWith #generics #where_clause { + value: &'a #field_ty, + phantom: core::marker::PhantomData<#item_ty>, + } + + impl #generics serde::Serialize for SerializeWith #generics #where_clause { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + #path(self.value, serializer) + } + } + + SerializeWith { + value: #value, + phantom: core::marker::PhantomData::<#item_ty>, + } +}; +``` + +
+ +## Repetition + +Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This +iterates through the elements of any variable interpolated within the repetition +and inserts a copy of the repetition body for each one. The variables in an +interpolation may be anything that implements `IntoIterator`, including `Vec` or +a pre-existing iterator. + +- `#(#var)*` — no separators +- `#(#var),*` — the character before the asterisk is used as a separator +- `#( struct #var; )*` — the repetition can contain other things +- `#( #k => println!("{}", #v), )*` — even multiple interpolations + +Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter +does not produce a trailing comma. This matches the behavior of delimiters in +`macro_rules!`. + +
+ +## Returning tokens to the compiler + +The `quote!` macro evaluates to an expression of type +`proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to +return the type `proc_macro::TokenStream`. + +The difference between the two types is that `proc_macro` types are entirely +specific to procedural macros and cannot ever exist in code outside of a +procedural macro, while `proc_macro2` types may exist anywhere including tests +and non-macro code like main.rs and build.rs. This is why even the procedural +macro ecosystem is largely built around `proc_macro2`, because that ensures the +libraries are unit testable and accessible in non-macro contexts. + +There is a [`From`]-conversion in both directions so returning the output of +`quote!` from a procedural macro usually looks like `tokens.into()` or +`proc_macro::TokenStream::from(tokens)`. + +[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html + +
+ +## Examples + +### Combining quoted fragments + +Usually you don't end up constructing an entire final `TokenStream` in one +piece. Different parts may come from different helper functions. The tokens +produced by `quote!` themselves implement `ToTokens` and so can be interpolated +into later `quote!` invocations to build up a final result. + +```rust +let type_definition = quote! {...}; +let methods = quote! {...}; + +let tokens = quote! { + #type_definition + #methods +}; +``` + +### Constructing identifiers + +Suppose we have an identifier `ident` which came from somewhere in a macro +input and we need to modify it in some way for the macro output. Let's consider +prepending the identifier with an underscore. + +Simply interpolating the identifier next to an underscore will not have the +behavior of concatenating them. The underscore and the identifier will continue +to be two separate tokens as if you had written `_ x`. + +```rust +// incorrect +quote! { + let mut _#ident = 0; +} +``` + +The solution is to build a new identifier token with the correct value. As this +is such a common case, the `format_ident!` macro provides a convenient utility +for doing so correctly. + +```rust +let varname = format_ident!("_{}", ident); +quote! { + let mut #varname = 0; +} +``` + +Alternatively, the APIs provided by Syn and proc-macro2 can be used to directly +build the identifier. This is roughly equivalent to the above, but will not +handle `ident` being a raw identifier. + +```rust +let concatenated = format!("_{}", ident); +let varname = syn::Ident::new(&concatenated, ident.span()); +quote! { + let mut #varname = 0; +} +``` + +### Making method calls + +Let's say our macro requires some type specified in the macro input to have a +constructor called `new`. We have the type in a variable called `field_type` of +type `syn::Type` and want to invoke the constructor. + +```rust +// incorrect +quote! { + let value = #field_type::new(); +} +``` + +This works only sometimes. If `field_type` is `String`, the expanded code +contains `String::new()` which is fine. But if `field_type` is something like +`Vec` then the expanded code is `Vec::new()` which is invalid syntax. +Ordinarily in handwritten Rust we would write `Vec::::new()` but for macros +often the following is more convenient. + +```rust +quote! { + let value = <#field_type>::new(); +} +``` + +This expands to `>::new()` which behaves correctly. + +A similar pattern is appropriate for trait methods. + +```rust +quote! { + let value = <#field_type as core::default::Default>::default(); +} +``` + +
+ +## Hygiene + +Any interpolated tokens preserve the `Span` information provided by their +`ToTokens` implementation. Tokens that originate within a `quote!` invocation +are spanned with [`Span::call_site()`]. + +[`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site + +A different span can be provided explicitly through the [`quote_spanned!`] +macro. + +[`quote_spanned!`]: https://docs.rs/quote/1.0/quote/macro.quote_spanned.html + +
+ +## Non-macro code generators + +When using `quote` in a build.rs or main.rs and writing the output out to a +file, consider having the code generator pass the tokens through [prettyplease] +before writing. This way if an error occurs in the generated code it is +convenient for a human to read and debug. + +Be aware that no kind of hygiene or span information is retained when tokens are +written to a file; the conversion from tokens to source code is lossy. + +Example usage in build.rs: + +```rust +let output = quote! { ... }; +let syntax_tree = syn::parse2(output).unwrap(); +let formatted = prettyplease::unparse(&syntax_tree); + +let out_dir = env::var_os("OUT_DIR").unwrap(); +let dest_path = Path::new(&out_dir).join("out.rs"); +fs::write(dest_path, formatted).unwrap(); +``` + +[prettyplease]: https://github.com/dtolnay/prettyplease + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/utshell-0.5.0/vendor/quote/rust-toolchain.toml b/utshell-0.5.0/vendor/quote/rust-toolchain.toml new file mode 100644 index 00000000..20fe888c --- /dev/null +++ b/utshell-0.5.0/vendor/quote/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +components = ["rust-src"] diff --git a/utshell-0.5.0/vendor/quote/src/ext.rs b/utshell-0.5.0/vendor/quote/src/ext.rs new file mode 100644 index 00000000..92c2315b --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/ext.rs @@ -0,0 +1,110 @@ +use super::ToTokens; +use core::iter; +use proc_macro2::{TokenStream, TokenTree}; + +/// TokenStream extension trait with methods for appending tokens. +/// +/// This trait is sealed and cannot be implemented outside of the `quote` crate. +pub trait TokenStreamExt: private::Sealed { + /// For use by `ToTokens` implementations. + /// + /// Appends the token specified to this list of tokens. + fn append(&mut self, token: U) + where + U: Into; + + /// For use by `ToTokens` implementations. + /// + /// ``` + /// # use quote::{quote, TokenStreamExt, ToTokens}; + /// # use proc_macro2::TokenStream; + /// # + /// struct X; + /// + /// impl ToTokens for X { + /// fn to_tokens(&self, tokens: &mut TokenStream) { + /// tokens.append_all(&[true, false]); + /// } + /// } + /// + /// let tokens = quote!(#X); + /// assert_eq!(tokens.to_string(), "true false"); + /// ``` + fn append_all(&mut self, iter: I) + where + I: IntoIterator, + I::Item: ToTokens; + + /// For use by `ToTokens` implementations. + /// + /// Appends all of the items in the iterator `I`, separated by the tokens + /// `U`. + fn append_separated(&mut self, iter: I, op: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens; + + /// For use by `ToTokens` implementations. + /// + /// Appends all tokens in the iterator `I`, appending `U` after each + /// element, including after the last element of the iterator. + fn append_terminated(&mut self, iter: I, term: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens; +} + +impl TokenStreamExt for TokenStream { + fn append(&mut self, token: U) + where + U: Into, + { + self.extend(iter::once(token.into())); + } + + fn append_all(&mut self, iter: I) + where + I: IntoIterator, + I::Item: ToTokens, + { + for token in iter { + token.to_tokens(self); + } + } + + fn append_separated(&mut self, iter: I, op: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens, + { + for (i, token) in iter.into_iter().enumerate() { + if i > 0 { + op.to_tokens(self); + } + token.to_tokens(self); + } + } + + fn append_terminated(&mut self, iter: I, term: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens, + { + for token in iter { + token.to_tokens(self); + term.to_tokens(self); + } + } +} + +mod private { + use proc_macro2::TokenStream; + + pub trait Sealed {} + + impl Sealed for TokenStream {} +} diff --git a/utshell-0.5.0/vendor/quote/src/format.rs b/utshell-0.5.0/vendor/quote/src/format.rs new file mode 100644 index 00000000..3cddbd28 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/format.rs @@ -0,0 +1,168 @@ +/// Formatting macro for constructing `Ident`s. +/// +///
+/// +/// # Syntax +/// +/// Syntax is copied from the [`format!`] macro, supporting both positional and +/// named arguments. +/// +/// Only a limited set of formatting traits are supported. The current mapping +/// of format types to traits is: +/// +/// * `{}` ⇒ [`IdentFragment`] +/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal) +/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex) +/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex) +/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary) +/// +/// See [`std::fmt`] for more information. +/// +///
+/// +/// # IdentFragment +/// +/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by +/// default. This trait is like `Display`, with a few differences: +/// +/// * `IdentFragment` is only implemented for a limited set of types, such as +/// unsigned integers and strings. +/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present. +/// +/// [`IdentFragment`]: crate::IdentFragment +/// [`Ident`]: proc_macro2::Ident +/// +///
+/// +/// # Hygiene +/// +/// The [`Span`] of the first `Ident` argument is used as the span of the final +/// identifier, falling back to [`Span::call_site`] when no identifiers are +/// provided. +/// +/// ``` +/// # use quote::format_ident; +/// # let ident = format_ident!("Ident"); +/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it. +/// let my_ident = format_ident!("My{}{}", ident, "IsCool"); +/// assert_eq!(my_ident, "MyIdentIsCool"); +/// ``` +/// +/// Alternatively, the span can be overridden by passing the `span` named +/// argument. +/// +/// ``` +/// # use quote::format_ident; +/// # const IGNORE_TOKENS: &'static str = stringify! { +/// let my_span = /* ... */; +/// # }; +/// # let my_span = proc_macro2::Span::call_site(); +/// format_ident!("MyIdent", span = my_span); +/// ``` +/// +/// [`Span`]: proc_macro2::Span +/// [`Span::call_site`]: proc_macro2::Span::call_site +/// +///


+/// +/// # Panics +/// +/// This method will panic if the resulting formatted string is not a valid +/// identifier. +/// +///
+/// +/// # Examples +/// +/// Composing raw and non-raw identifiers: +/// ``` +/// # use quote::format_ident; +/// let my_ident = format_ident!("My{}", "Ident"); +/// assert_eq!(my_ident, "MyIdent"); +/// +/// let raw = format_ident!("r#Raw"); +/// assert_eq!(raw, "r#Raw"); +/// +/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw); +/// assert_eq!(my_ident_raw, "MyIdentIsRaw"); +/// ``` +/// +/// Integer formatting options: +/// ``` +/// # use quote::format_ident; +/// let num: u32 = 10; +/// +/// let decimal = format_ident!("Id_{}", num); +/// assert_eq!(decimal, "Id_10"); +/// +/// let octal = format_ident!("Id_{:o}", num); +/// assert_eq!(octal, "Id_12"); +/// +/// let binary = format_ident!("Id_{:b}", num); +/// assert_eq!(binary, "Id_1010"); +/// +/// let lower_hex = format_ident!("Id_{:x}", num); +/// assert_eq!(lower_hex, "Id_a"); +/// +/// let upper_hex = format_ident!("Id_{:X}", num); +/// assert_eq!(upper_hex, "Id_A"); +/// ``` +#[macro_export] +macro_rules! format_ident { + ($fmt:expr) => { + $crate::format_ident_impl!([ + $crate::__private::Option::None, + $fmt + ]) + }; + + ($fmt:expr, $($rest:tt)*) => { + $crate::format_ident_impl!([ + $crate::__private::Option::None, + $fmt + ] $($rest)*) + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! format_ident_impl { + // Final state + ([$span:expr, $($fmt:tt)*]) => { + $crate::__private::mk_ident( + &$crate::__private::format!($($fmt)*), + $span, + ) + }; + + // Span argument + ([$old:expr, $($fmt:tt)*] span = $span:expr) => { + $crate::format_ident_impl!([$old, $($fmt)*] span = $span,) + }; + ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => { + $crate::format_ident_impl!([ + $crate::__private::Option::Some::<$crate::__private::Span>($span), + $($fmt)* + ] $($rest)*) + }; + + // Named argument + ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => { + $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,) + }; + ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => { + match $crate::__private::IdentFragmentAdapter(&$arg) { + arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*), + } + }; + + // Positional argument + ([$span:expr, $($fmt:tt)*] $arg:expr) => { + $crate::format_ident_impl!([$span, $($fmt)*] $arg,) + }; + ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => { + match $crate::__private::IdentFragmentAdapter(&$arg) { + arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*), + } + }; +} diff --git a/utshell-0.5.0/vendor/quote/src/ident_fragment.rs b/utshell-0.5.0/vendor/quote/src/ident_fragment.rs new file mode 100644 index 00000000..6c2a9a87 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/ident_fragment.rs @@ -0,0 +1,88 @@ +use alloc::borrow::Cow; +use core::fmt; +use proc_macro2::{Ident, Span}; + +/// Specialized formatting trait used by `format_ident!`. +/// +/// [`Ident`] arguments formatted using this trait will have their `r#` prefix +/// stripped, if present. +/// +/// See [`format_ident!`] for more information. +/// +/// [`format_ident!`]: crate::format_ident +pub trait IdentFragment { + /// Format this value as an identifier fragment. + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result; + + /// Span associated with this `IdentFragment`. + /// + /// If non-`None`, may be inherited by formatted identifiers. + fn span(&self) -> Option { + None + } +} + +impl IdentFragment for &T { + fn span(&self) -> Option { + ::span(*self) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + IdentFragment::fmt(*self, f) + } +} + +impl IdentFragment for &mut T { + fn span(&self) -> Option { + ::span(*self) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + IdentFragment::fmt(*self, f) + } +} + +impl IdentFragment for Ident { + fn span(&self) -> Option { + Some(self.span()) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let id = self.to_string(); + if let Some(id) = id.strip_prefix("r#") { + fmt::Display::fmt(id, f) + } else { + fmt::Display::fmt(&id[..], f) + } + } +} + +impl IdentFragment for Cow<'_, T> +where + T: IdentFragment + ToOwned + ?Sized, +{ + fn span(&self) -> Option { + T::span(self) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + T::fmt(self, f) + } +} + +// Limited set of types which this is implemented for, as we want to avoid types +// which will often include non-identifier characters in their `Display` impl. +macro_rules! ident_fragment_display { + ($($T:ty),*) => { + $( + impl IdentFragment for $T { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } + } + )* + }; +} + +ident_fragment_display!(bool, str, String, char); +ident_fragment_display!(u8, u16, u32, u64, u128, usize); diff --git a/utshell-0.5.0/vendor/quote/src/lib.rs b/utshell-0.5.0/vendor/quote/src/lib.rs new file mode 100644 index 00000000..8b97abd7 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/lib.rs @@ -0,0 +1,1444 @@ +//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! This crate provides the [`quote!`] macro for turning Rust syntax tree data +//! structures into tokens of source code. +//! +//! [`quote!`]: macro.quote.html +//! +//! Procedural macros in Rust receive a stream of tokens as input, execute +//! arbitrary Rust code to determine how to manipulate those tokens, and produce +//! a stream of tokens to hand back to the compiler to compile into the caller's +//! crate. Quasi-quoting is a solution to one piece of that — producing +//! tokens to return to the compiler. +//! +//! The idea of quasi-quoting is that we write *code* that we treat as *data*. +//! Within the `quote!` macro, we can write what looks like code to our text +//! editor or IDE. We get all the benefits of the editor's brace matching, +//! syntax highlighting, indentation, and maybe autocompletion. But rather than +//! compiling that as code into the current crate, we can treat it as data, pass +//! it around, mutate it, and eventually hand it back to the compiler as tokens +//! to compile into the macro caller's crate. +//! +//! This crate is motivated by the procedural macro use case, but is a +//! general-purpose Rust quasi-quoting library and is not specific to procedural +//! macros. +//! +//! ```toml +//! [dependencies] +//! quote = "1.0" +//! ``` +//! +//!
+//! +//! # Example +//! +//! The following quasi-quoted block of code is something you might find in [a] +//! procedural macro having to do with data structure serialization. The `#var` +//! syntax performs interpolation of runtime variables into the quoted tokens. +//! Check out the documentation of the [`quote!`] macro for more detail about +//! the syntax. See also the [`quote_spanned!`] macro which is important for +//! implementing hygienic procedural macros. +//! +//! [a]: https://serde.rs/ +//! [`quote_spanned!`]: macro.quote_spanned.html +//! +//! ``` +//! # use quote::quote; +//! # +//! # let generics = ""; +//! # let where_clause = ""; +//! # let field_ty = ""; +//! # let item_ty = ""; +//! # let path = ""; +//! # let value = ""; +//! # +//! let tokens = quote! { +//! struct SerializeWith #generics #where_clause { +//! value: &'a #field_ty, +//! phantom: core::marker::PhantomData<#item_ty>, +//! } +//! +//! impl #generics serde::Serialize for SerializeWith #generics #where_clause { +//! fn serialize(&self, serializer: S) -> Result +//! where +//! S: serde::Serializer, +//! { +//! #path(self.value, serializer) +//! } +//! } +//! +//! SerializeWith { +//! value: #value, +//! phantom: core::marker::PhantomData::<#item_ty>, +//! } +//! }; +//! ``` +//! +//!
+//! +//! # Non-macro code generators +//! +//! When using `quote` in a build.rs or main.rs and writing the output out to a +//! file, consider having the code generator pass the tokens through +//! [prettyplease] before writing. This way if an error occurs in the generated +//! code it is convenient for a human to read and debug. +//! +//! [prettyplease]: https://github.com/dtolnay/prettyplease + +// Quote types in rustdoc of other crates get linked to here. +#![doc(html_root_url = "https://docs.rs/quote/1.0.35")] +#![allow( + clippy::doc_markdown, + clippy::missing_errors_doc, + clippy::missing_panics_doc, + clippy::module_name_repetitions, + // false positive https://github.com/rust-lang/rust-clippy/issues/6983 + clippy::wrong_self_convention, +)] + +extern crate alloc; + +#[cfg(feature = "proc-macro")] +extern crate proc_macro; + +mod ext; +mod format; +mod ident_fragment; +mod to_tokens; + +// Not public API. +#[doc(hidden)] +#[path = "runtime.rs"] +pub mod __private; + +pub use crate::ext::TokenStreamExt; +pub use crate::ident_fragment::IdentFragment; +pub use crate::to_tokens::ToTokens; + +// Not public API. +#[doc(hidden)] +pub mod spanned; + +/// The whole point. +/// +/// Performs variable interpolation against the input and produces it as +/// [`proc_macro2::TokenStream`]. +/// +/// Note: for returning tokens to the compiler in a procedural macro, use +/// `.into()` on the result to convert to [`proc_macro::TokenStream`]. +/// +/// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html +/// +///
+/// +/// # Interpolation +/// +/// Variable interpolation is done with `#var` (similar to `$var` in +/// `macro_rules!` macros). This grabs the `var` variable that is currently in +/// scope and inserts it in that location in the output tokens. Any type +/// implementing the [`ToTokens`] trait can be interpolated. This includes most +/// Rust primitive types as well as most of the syntax tree types from the [Syn] +/// crate. +/// +/// [`ToTokens`]: trait.ToTokens.html +/// [Syn]: https://github.com/dtolnay/syn +/// +/// Repetition is done using `#(...)*` or `#(...),*` again similar to +/// `macro_rules!`. This iterates through the elements of any variable +/// interpolated within the repetition and inserts a copy of the repetition body +/// for each one. The variables in an interpolation may be a `Vec`, slice, +/// `BTreeSet`, or any `Iterator`. +/// +/// - `#(#var)*` — no separators +/// - `#(#var),*` — the character before the asterisk is used as a separator +/// - `#( struct #var; )*` — the repetition can contain other tokens +/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations +/// +///
+/// +/// # Hygiene +/// +/// Any interpolated tokens preserve the `Span` information provided by their +/// `ToTokens` implementation. Tokens that originate within the `quote!` +/// invocation are spanned with [`Span::call_site()`]. +/// +/// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site +/// +/// A different span can be provided through the [`quote_spanned!`] macro. +/// +/// [`quote_spanned!`]: macro.quote_spanned.html +/// +///
+/// +/// # Return type +/// +/// The macro evaluates to an expression of type `proc_macro2::TokenStream`. +/// Meanwhile Rust procedural macros are expected to return the type +/// `proc_macro::TokenStream`. +/// +/// The difference between the two types is that `proc_macro` types are entirely +/// specific to procedural macros and cannot ever exist in code outside of a +/// procedural macro, while `proc_macro2` types may exist anywhere including +/// tests and non-macro code like main.rs and build.rs. This is why even the +/// procedural macro ecosystem is largely built around `proc_macro2`, because +/// that ensures the libraries are unit testable and accessible in non-macro +/// contexts. +/// +/// There is a [`From`]-conversion in both directions so returning the output of +/// `quote!` from a procedural macro usually looks like `tokens.into()` or +/// `proc_macro::TokenStream::from(tokens)`. +/// +/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html +/// +///
+/// +/// # Examples +/// +/// ### Procedural macro +/// +/// The structure of a basic procedural macro is as follows. Refer to the [Syn] +/// crate for further useful guidance on using `quote!` as part of a procedural +/// macro. +/// +/// [Syn]: https://github.com/dtolnay/syn +/// +/// ``` +/// # #[cfg(any())] +/// extern crate proc_macro; +/// # extern crate proc_macro2; +/// +/// # #[cfg(any())] +/// use proc_macro::TokenStream; +/// # use proc_macro2::TokenStream; +/// use quote::quote; +/// +/// # const IGNORE_TOKENS: &'static str = stringify! { +/// #[proc_macro_derive(HeapSize)] +/// # }; +/// pub fn derive_heap_size(input: TokenStream) -> TokenStream { +/// // Parse the input and figure out what implementation to generate... +/// # const IGNORE_TOKENS: &'static str = stringify! { +/// let name = /* ... */; +/// let expr = /* ... */; +/// # }; +/// # +/// # let name = 0; +/// # let expr = 0; +/// +/// let expanded = quote! { +/// // The generated impl. +/// impl heapsize::HeapSize for #name { +/// fn heap_size_of_children(&self) -> usize { +/// #expr +/// } +/// } +/// }; +/// +/// // Hand the output tokens back to the compiler. +/// TokenStream::from(expanded) +/// } +/// ``` +/// +///


+/// +/// ### Combining quoted fragments +/// +/// Usually you don't end up constructing an entire final `TokenStream` in one +/// piece. Different parts may come from different helper functions. The tokens +/// produced by `quote!` themselves implement `ToTokens` and so can be +/// interpolated into later `quote!` invocations to build up a final result. +/// +/// ``` +/// # use quote::quote; +/// # +/// let type_definition = quote! {...}; +/// let methods = quote! {...}; +/// +/// let tokens = quote! { +/// #type_definition +/// #methods +/// }; +/// ``` +/// +///


+/// +/// ### Constructing identifiers +/// +/// Suppose we have an identifier `ident` which came from somewhere in a macro +/// input and we need to modify it in some way for the macro output. Let's +/// consider prepending the identifier with an underscore. +/// +/// Simply interpolating the identifier next to an underscore will not have the +/// behavior of concatenating them. The underscore and the identifier will +/// continue to be two separate tokens as if you had written `_ x`. +/// +/// ``` +/// # use proc_macro2::{self as syn, Span}; +/// # use quote::quote; +/// # +/// # let ident = syn::Ident::new("i", Span::call_site()); +/// # +/// // incorrect +/// quote! { +/// let mut _#ident = 0; +/// } +/// # ; +/// ``` +/// +/// The solution is to build a new identifier token with the correct value. As +/// this is such a common case, the [`format_ident!`] macro provides a +/// convenient utility for doing so correctly. +/// +/// ``` +/// # use proc_macro2::{Ident, Span}; +/// # use quote::{format_ident, quote}; +/// # +/// # let ident = Ident::new("i", Span::call_site()); +/// # +/// let varname = format_ident!("_{}", ident); +/// quote! { +/// let mut #varname = 0; +/// } +/// # ; +/// ``` +/// +/// Alternatively, the APIs provided by Syn and proc-macro2 can be used to +/// directly build the identifier. This is roughly equivalent to the above, but +/// will not handle `ident` being a raw identifier. +/// +/// ``` +/// # use proc_macro2::{self as syn, Span}; +/// # use quote::quote; +/// # +/// # let ident = syn::Ident::new("i", Span::call_site()); +/// # +/// let concatenated = format!("_{}", ident); +/// let varname = syn::Ident::new(&concatenated, ident.span()); +/// quote! { +/// let mut #varname = 0; +/// } +/// # ; +/// ``` +/// +///


+/// +/// ### Making method calls +/// +/// Let's say our macro requires some type specified in the macro input to have +/// a constructor called `new`. We have the type in a variable called +/// `field_type` of type `syn::Type` and want to invoke the constructor. +/// +/// ``` +/// # use quote::quote; +/// # +/// # let field_type = quote!(...); +/// # +/// // incorrect +/// quote! { +/// let value = #field_type::new(); +/// } +/// # ; +/// ``` +/// +/// This works only sometimes. If `field_type` is `String`, the expanded code +/// contains `String::new()` which is fine. But if `field_type` is something +/// like `Vec` then the expanded code is `Vec::new()` which is invalid +/// syntax. Ordinarily in handwritten Rust we would write `Vec::::new()` +/// but for macros often the following is more convenient. +/// +/// ``` +/// # use quote::quote; +/// # +/// # let field_type = quote!(...); +/// # +/// quote! { +/// let value = <#field_type>::new(); +/// } +/// # ; +/// ``` +/// +/// This expands to `>::new()` which behaves correctly. +/// +/// A similar pattern is appropriate for trait methods. +/// +/// ``` +/// # use quote::quote; +/// # +/// # let field_type = quote!(...); +/// # +/// quote! { +/// let value = <#field_type as core::default::Default>::default(); +/// } +/// # ; +/// ``` +/// +///


+/// +/// ### Interpolating text inside of doc comments +/// +/// Neither doc comments nor string literals get interpolation behavior in +/// quote: +/// +/// ```compile_fail +/// quote! { +/// /// try to interpolate: #ident +/// /// +/// /// ... +/// } +/// ``` +/// +/// ```compile_fail +/// quote! { +/// #[doc = "try to interpolate: #ident"] +/// } +/// ``` +/// +/// Instead the best way to build doc comments that involve variables is by +/// formatting the doc string literal outside of quote. +/// +/// ```rust +/// # use proc_macro2::{Ident, Span}; +/// # use quote::quote; +/// # +/// # const IGNORE: &str = stringify! { +/// let msg = format!(...); +/// # }; +/// # +/// # let ident = Ident::new("var", Span::call_site()); +/// # let msg = format!("try to interpolate: {}", ident); +/// quote! { +/// #[doc = #msg] +/// /// +/// /// ... +/// } +/// # ; +/// ``` +/// +///


+/// +/// ### Indexing into a tuple struct +/// +/// When interpolating indices of a tuple or tuple struct, we need them not to +/// appears suffixed as integer literals by interpolating them as [`syn::Index`] +/// instead. +/// +/// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html +/// +/// ```compile_fail +/// let i = 0usize..self.fields.len(); +/// +/// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ... +/// // which is not valid syntax +/// quote! { +/// 0 #( + self.#i.heap_size() )* +/// } +/// ``` +/// +/// ``` +/// # use proc_macro2::{Ident, TokenStream}; +/// # use quote::quote; +/// # +/// # mod syn { +/// # use proc_macro2::{Literal, TokenStream}; +/// # use quote::{ToTokens, TokenStreamExt}; +/// # +/// # pub struct Index(usize); +/// # +/// # impl From for Index { +/// # fn from(i: usize) -> Self { +/// # Index(i) +/// # } +/// # } +/// # +/// # impl ToTokens for Index { +/// # fn to_tokens(&self, tokens: &mut TokenStream) { +/// # tokens.append(Literal::usize_unsuffixed(self.0)); +/// # } +/// # } +/// # } +/// # +/// # struct Struct { +/// # fields: Vec, +/// # } +/// # +/// # impl Struct { +/// # fn example(&self) -> TokenStream { +/// let i = (0..self.fields.len()).map(syn::Index::from); +/// +/// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ... +/// quote! { +/// 0 #( + self.#i.heap_size() )* +/// } +/// # } +/// # } +/// ``` +#[cfg(doc)] +#[macro_export] +macro_rules! quote { + ($($tt:tt)*) => { + ... + }; +} + +#[cfg(not(doc))] +#[macro_export] +macro_rules! quote { + () => { + $crate::__private::TokenStream::new() + }; + + // Special case rule for a single tt, for performance. + ($tt:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::quote_token!{$tt _s} + _s + }}; + + // Special case rules for two tts, for performance. + (# $var:ident) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::ToTokens::to_tokens(&$var, &mut _s); + _s + }}; + ($tt1:tt $tt2:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::quote_token!{$tt1 _s} + $crate::quote_token!{$tt2 _s} + _s + }}; + + // Rule for any other number of tokens. + ($($tt:tt)*) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::quote_each_token!{_s $($tt)*} + _s + }}; +} + +/// Same as `quote!`, but applies a given span to all tokens originating within +/// the macro invocation. +/// +///
+/// +/// # Syntax +/// +/// A span expression of type [`Span`], followed by `=>`, followed by the tokens +/// to quote. The span expression should be brief — use a variable for +/// anything more than a few characters. There should be no space before the +/// `=>` token. +/// +/// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html +/// +/// ``` +/// # use proc_macro2::Span; +/// # use quote::quote_spanned; +/// # +/// # const IGNORE_TOKENS: &'static str = stringify! { +/// let span = /* ... */; +/// # }; +/// # let span = Span::call_site(); +/// # let init = 0; +/// +/// // On one line, use parentheses. +/// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init))); +/// +/// // On multiple lines, place the span at the top and use braces. +/// let tokens = quote_spanned! {span=> +/// Box::into_raw(Box::new(#init)) +/// }; +/// ``` +/// +/// The lack of space before the `=>` should look jarring to Rust programmers +/// and this is intentional. The formatting is designed to be visibly +/// off-balance and draw the eye a particular way, due to the span expression +/// being evaluated in the context of the procedural macro and the remaining +/// tokens being evaluated in the generated code. +/// +///
+/// +/// # Hygiene +/// +/// Any interpolated tokens preserve the `Span` information provided by their +/// `ToTokens` implementation. Tokens that originate within the `quote_spanned!` +/// invocation are spanned with the given span argument. +/// +///
+/// +/// # Example +/// +/// The following procedural macro code uses `quote_spanned!` to assert that a +/// particular Rust type implements the [`Sync`] trait so that references can be +/// safely shared between threads. +/// +/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html +/// +/// ``` +/// # use quote::{quote_spanned, TokenStreamExt, ToTokens}; +/// # use proc_macro2::{Span, TokenStream}; +/// # +/// # struct Type; +/// # +/// # impl Type { +/// # fn span(&self) -> Span { +/// # Span::call_site() +/// # } +/// # } +/// # +/// # impl ToTokens for Type { +/// # fn to_tokens(&self, _tokens: &mut TokenStream) {} +/// # } +/// # +/// # let ty = Type; +/// # let call_site = Span::call_site(); +/// # +/// let ty_span = ty.span(); +/// let assert_sync = quote_spanned! {ty_span=> +/// struct _AssertSync where #ty: Sync; +/// }; +/// ``` +/// +/// If the assertion fails, the user will see an error like the following. The +/// input span of their type is highlighted in the error. +/// +/// ```text +/// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied +/// --> src/main.rs:10:21 +/// | +/// 10 | static ref PTR: *const () = &(); +/// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely +/// ``` +/// +/// In this example it is important for the where-clause to be spanned with the +/// line/column information of the user's input type so that error messages are +/// placed appropriately by the compiler. +#[cfg(doc)] +#[macro_export] +macro_rules! quote_spanned { + ($span:expr=> $($tt:tt)*) => { + ... + }; +} + +#[cfg(not(doc))] +#[macro_export] +macro_rules! quote_spanned { + ($span:expr=>) => {{ + let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::__private::TokenStream::new() + }}; + + // Special case rule for a single tt, for performance. + ($span:expr=> $tt:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::quote_token_spanned!{$tt _s _span} + _s + }}; + + // Special case rules for two tts, for performance. + ($span:expr=> # $var:ident) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::ToTokens::to_tokens(&$var, &mut _s); + _s + }}; + ($span:expr=> $tt1:tt $tt2:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::quote_token_spanned!{$tt1 _s _span} + $crate::quote_token_spanned!{$tt2 _s _span} + _s + }}; + + // Rule for any other number of tokens. + ($span:expr=> $($tt:tt)*) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::quote_each_token_spanned!{_s _span $($tt)*} + _s + }}; +} + +// Extract the names of all #metavariables and pass them to the $call macro. +// +// in: pounded_var_names!(then!(...) a #b c #( #d )* #e) +// out: then!(... b); +// then!(... d); +// then!(... e); +#[macro_export] +#[doc(hidden)] +macro_rules! pounded_var_names { + ($call:ident! $extra:tt $($tts:tt)*) => { + $crate::pounded_var_names_with_context!{$call! $extra + (@ $($tts)*) + ($($tts)* @) + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! pounded_var_names_with_context { + ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => { + $( + $crate::pounded_var_with_context!{$call! $extra $b1 $curr} + )* + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! pounded_var_with_context { + ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => { + $crate::pounded_var_names!{$call! $extra $($inner)*} + }; + + ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => { + $crate::pounded_var_names!{$call! $extra $($inner)*} + }; + + ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => { + $crate::pounded_var_names!{$call! $extra $($inner)*} + }; + + ($call:ident!($($extra:tt)*) # $var:ident) => { + $crate::$call!($($extra)* $var); + }; + + ($call:ident! $extra:tt $b1:tt $curr:tt) => {}; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! quote_bind_into_iter { + ($has_iter:ident $var:ident) => { + // `mut` may be unused if $var occurs multiple times in the list. + #[allow(unused_mut)] + let (mut $var, i) = $var.quote_into_iter(); + let $has_iter = $has_iter | i; + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! quote_bind_next_or_break { + ($var:ident) => { + let $var = match $var.next() { + Some(_x) => $crate::__private::RepInterp(_x), + None => break, + }; + }; +} + +// The obvious way to write this macro is as a tt muncher. This implementation +// does something more complex for two reasons. +// +// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which +// this implementation avoids because it isn't tail recursive. +// +// - Compile times for a tt muncher are quadratic relative to the length of +// the input. This implementation is linear, so it will be faster +// (potentially much faster) for big inputs. However, the constant factors +// of this implementation are higher than that of a tt muncher, so it is +// somewhat slower than a tt muncher if there are many invocations with +// short inputs. +// +// An invocation like this: +// +// quote_each_token!(_s a b c d e f g h i j); +// +// expands to this: +// +// quote_tokens_with_context!(_s +// (@ @ @ @ @ @ a b c d e f g h i j) +// (@ @ @ @ @ a b c d e f g h i j @) +// (@ @ @ @ a b c d e f g h i j @ @) +// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @) +// (@ @ a b c d e f g h i j @ @ @ @) +// (@ a b c d e f g h i j @ @ @ @ @) +// (a b c d e f g h i j @ @ @ @ @ @) +// ); +// +// which gets transposed and expanded to this: +// +// quote_token_with_context!(_s @ @ @ @ @ @ a); +// quote_token_with_context!(_s @ @ @ @ @ a b); +// quote_token_with_context!(_s @ @ @ @ a b c); +// quote_token_with_context!(_s @ @ @ (a) b c d); +// quote_token_with_context!(_s @ @ a (b) c d e); +// quote_token_with_context!(_s @ a b (c) d e f); +// quote_token_with_context!(_s a b c (d) e f g); +// quote_token_with_context!(_s b c d (e) f g h); +// quote_token_with_context!(_s c d e (f) g h i); +// quote_token_with_context!(_s d e f (g) h i j); +// quote_token_with_context!(_s e f g (h) i j @); +// quote_token_with_context!(_s f g h (i) j @ @); +// quote_token_with_context!(_s g h i (j) @ @ @); +// quote_token_with_context!(_s h i j @ @ @ @); +// quote_token_with_context!(_s i j @ @ @ @ @); +// quote_token_with_context!(_s j @ @ @ @ @ @); +// +// Without having used muncher-style recursion, we get one invocation of +// quote_token_with_context for each original tt, with three tts of context on +// either side. This is enough for the longest possible interpolation form (a +// repetition with separator, as in `# (#var) , *`) to be fully represented with +// the first or last tt in the middle. +// +// The middle tt (surrounded by parentheses) is the tt being processed. +// +// - When it is a `#`, quote_token_with_context can do an interpolation. The +// interpolation kind will depend on the three subsequent tts. +// +// - When it is within a later part of an interpolation, it can be ignored +// because the interpolation has already been done. +// +// - When it is not part of an interpolation it can be pushed as a single +// token into the output. +// +// - When the middle token is an unparenthesized `@`, that call is one of the +// first 3 or last 3 calls of quote_token_with_context and does not +// correspond to one of the original input tokens, so turns into nothing. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_each_token { + ($tokens:ident $($tts:tt)*) => { + $crate::quote_tokens_with_context!{$tokens + (@ @ @ @ @ @ $($tts)*) + (@ @ @ @ @ $($tts)* @) + (@ @ @ @ $($tts)* @ @) + (@ @ @ $(($tts))* @ @ @) + (@ @ $($tts)* @ @ @ @) + (@ $($tts)* @ @ @ @ @) + ($($tts)* @ @ @ @ @ @) + } + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_each_token_spanned { + ($tokens:ident $span:ident $($tts:tt)*) => { + $crate::quote_tokens_with_context_spanned!{$tokens $span + (@ @ @ @ @ @ $($tts)*) + (@ @ @ @ @ $($tts)* @) + (@ @ @ @ $($tts)* @ @) + (@ @ @ $(($tts))* @ @ @) + (@ @ $($tts)* @ @ @ @) + (@ $($tts)* @ @ @ @ @) + ($($tts)* @ @ @ @ @ @) + } + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_tokens_with_context { + ($tokens:ident + ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) + ($($curr:tt)*) + ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) + ) => { + $( + $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3} + )* + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_tokens_with_context_spanned { + ($tokens:ident $span:ident + ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) + ($($curr:tt)*) + ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) + ) => { + $( + $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3} + )* + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token_with_context { + // Unparenthesized `@` indicates this call does not correspond to one of the + // original input tokens. Ignore it. + ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; + + // A repetition with no separator. + ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ + use $crate::__private::ext::*; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + // This is `while true` instead of `loop` because if there are no + // iterators used inside of this repetition then the body would not + // contain any `break`, so the compiler would emit unreachable code + // warnings on anything below the loop. We use has_iter to detect and + // fail to compile when there are no iterators, so here we just work + // around the unneeded extra warning. + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + $crate::quote_each_token!{$tokens $($inner)*} + } + }}; + // ... and one step later. + ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; + // ... and one step later. + ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; + + // A repetition with separator. + ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ + use $crate::__private::ext::*; + let mut _i = 0usize; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + if _i > 0 { + $crate::quote_token!{$sep $tokens} + } + _i += 1; + $crate::quote_each_token!{$tokens $($inner)*} + } + }}; + // ... and one step later. + ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; + // ... and one step later. + ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; + // (A special case for `#(var)**`, where the first `*` is treated as the + // repetition symbol and the second `*` is treated as an ordinary token.) + ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { + // https://github.com/dtolnay/quote/issues/130 + $crate::quote_token!{* $tokens} + }; + // ... and one step later. + ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; + + // A non-repetition interpolation. + ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { + $crate::ToTokens::to_tokens(&$var, &mut $tokens); + }; + // ... and one step later. + ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; + + // An ordinary token, not part of any interpolation. + ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { + $crate::quote_token!{$curr $tokens} + }; +} + +// See the explanation on quote_each_token, and on the individual rules of +// quote_token_with_context. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token_with_context_spanned { + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ + use $crate::__private::ext::*; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + $crate::quote_each_token_spanned!{$tokens $span $($inner)*} + } + }}; + ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; + ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ + use $crate::__private::ext::*; + let mut _i = 0usize; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + if _i > 0 { + $crate::quote_token_spanned!{$sep $tokens $span} + } + _i += 1; + $crate::quote_each_token_spanned!{$tokens $span $($inner)*} + } + }}; + ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; + ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; + ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { + // https://github.com/dtolnay/quote/issues/130 + $crate::quote_token_spanned!{* $tokens $span} + }; + ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { + $crate::ToTokens::to_tokens(&$var, &mut $tokens); + }; + ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { + $crate::quote_token_spanned!{$curr $tokens $span} + }; +} + +// These rules are ordered by approximate token frequency, at least for the +// first 10 or so, to improve compile times. Having `ident` first is by far the +// most important because it's typically 2-3x more common than the next most +// common token. +// +// Separately, we put the token being matched in the very front so that failing +// rules may fail to match as quickly as possible. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token { + ($ident:ident $tokens:ident) => { + $crate::__private::push_ident(&mut $tokens, stringify!($ident)); + }; + + (:: $tokens:ident) => { + $crate::__private::push_colon2(&mut $tokens); + }; + + (( $($inner:tt)* ) $tokens:ident) => { + $crate::__private::push_group( + &mut $tokens, + $crate::__private::Delimiter::Parenthesis, + $crate::quote!($($inner)*), + ); + }; + + ([ $($inner:tt)* ] $tokens:ident) => { + $crate::__private::push_group( + &mut $tokens, + $crate::__private::Delimiter::Bracket, + $crate::quote!($($inner)*), + ); + }; + + ({ $($inner:tt)* } $tokens:ident) => { + $crate::__private::push_group( + &mut $tokens, + $crate::__private::Delimiter::Brace, + $crate::quote!($($inner)*), + ); + }; + + (# $tokens:ident) => { + $crate::__private::push_pound(&mut $tokens); + }; + + (, $tokens:ident) => { + $crate::__private::push_comma(&mut $tokens); + }; + + (. $tokens:ident) => { + $crate::__private::push_dot(&mut $tokens); + }; + + (; $tokens:ident) => { + $crate::__private::push_semi(&mut $tokens); + }; + + (: $tokens:ident) => { + $crate::__private::push_colon(&mut $tokens); + }; + + (+ $tokens:ident) => { + $crate::__private::push_add(&mut $tokens); + }; + + (+= $tokens:ident) => { + $crate::__private::push_add_eq(&mut $tokens); + }; + + (& $tokens:ident) => { + $crate::__private::push_and(&mut $tokens); + }; + + (&& $tokens:ident) => { + $crate::__private::push_and_and(&mut $tokens); + }; + + (&= $tokens:ident) => { + $crate::__private::push_and_eq(&mut $tokens); + }; + + (@ $tokens:ident) => { + $crate::__private::push_at(&mut $tokens); + }; + + (! $tokens:ident) => { + $crate::__private::push_bang(&mut $tokens); + }; + + (^ $tokens:ident) => { + $crate::__private::push_caret(&mut $tokens); + }; + + (^= $tokens:ident) => { + $crate::__private::push_caret_eq(&mut $tokens); + }; + + (/ $tokens:ident) => { + $crate::__private::push_div(&mut $tokens); + }; + + (/= $tokens:ident) => { + $crate::__private::push_div_eq(&mut $tokens); + }; + + (.. $tokens:ident) => { + $crate::__private::push_dot2(&mut $tokens); + }; + + (... $tokens:ident) => { + $crate::__private::push_dot3(&mut $tokens); + }; + + (..= $tokens:ident) => { + $crate::__private::push_dot_dot_eq(&mut $tokens); + }; + + (= $tokens:ident) => { + $crate::__private::push_eq(&mut $tokens); + }; + + (== $tokens:ident) => { + $crate::__private::push_eq_eq(&mut $tokens); + }; + + (>= $tokens:ident) => { + $crate::__private::push_ge(&mut $tokens); + }; + + (> $tokens:ident) => { + $crate::__private::push_gt(&mut $tokens); + }; + + (<= $tokens:ident) => { + $crate::__private::push_le(&mut $tokens); + }; + + (< $tokens:ident) => { + $crate::__private::push_lt(&mut $tokens); + }; + + (*= $tokens:ident) => { + $crate::__private::push_mul_eq(&mut $tokens); + }; + + (!= $tokens:ident) => { + $crate::__private::push_ne(&mut $tokens); + }; + + (| $tokens:ident) => { + $crate::__private::push_or(&mut $tokens); + }; + + (|= $tokens:ident) => { + $crate::__private::push_or_eq(&mut $tokens); + }; + + (|| $tokens:ident) => { + $crate::__private::push_or_or(&mut $tokens); + }; + + (? $tokens:ident) => { + $crate::__private::push_question(&mut $tokens); + }; + + (-> $tokens:ident) => { + $crate::__private::push_rarrow(&mut $tokens); + }; + + (<- $tokens:ident) => { + $crate::__private::push_larrow(&mut $tokens); + }; + + (% $tokens:ident) => { + $crate::__private::push_rem(&mut $tokens); + }; + + (%= $tokens:ident) => { + $crate::__private::push_rem_eq(&mut $tokens); + }; + + (=> $tokens:ident) => { + $crate::__private::push_fat_arrow(&mut $tokens); + }; + + (<< $tokens:ident) => { + $crate::__private::push_shl(&mut $tokens); + }; + + (<<= $tokens:ident) => { + $crate::__private::push_shl_eq(&mut $tokens); + }; + + (>> $tokens:ident) => { + $crate::__private::push_shr(&mut $tokens); + }; + + (>>= $tokens:ident) => { + $crate::__private::push_shr_eq(&mut $tokens); + }; + + (* $tokens:ident) => { + $crate::__private::push_star(&mut $tokens); + }; + + (- $tokens:ident) => { + $crate::__private::push_sub(&mut $tokens); + }; + + (-= $tokens:ident) => { + $crate::__private::push_sub_eq(&mut $tokens); + }; + + ($lifetime:lifetime $tokens:ident) => { + $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime)); + }; + + (_ $tokens:ident) => { + $crate::__private::push_underscore(&mut $tokens); + }; + + ($other:tt $tokens:ident) => { + $crate::__private::parse(&mut $tokens, stringify!($other)); + }; +} + +// See the comment above `quote_token!` about the rule ordering. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token_spanned { + ($ident:ident $tokens:ident $span:ident) => { + $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident)); + }; + + (:: $tokens:ident $span:ident) => { + $crate::__private::push_colon2_spanned(&mut $tokens, $span); + }; + + (( $($inner:tt)* ) $tokens:ident $span:ident) => { + $crate::__private::push_group_spanned( + &mut $tokens, + $span, + $crate::__private::Delimiter::Parenthesis, + $crate::quote_spanned!($span=> $($inner)*), + ); + }; + + ([ $($inner:tt)* ] $tokens:ident $span:ident) => { + $crate::__private::push_group_spanned( + &mut $tokens, + $span, + $crate::__private::Delimiter::Bracket, + $crate::quote_spanned!($span=> $($inner)*), + ); + }; + + ({ $($inner:tt)* } $tokens:ident $span:ident) => { + $crate::__private::push_group_spanned( + &mut $tokens, + $span, + $crate::__private::Delimiter::Brace, + $crate::quote_spanned!($span=> $($inner)*), + ); + }; + + (# $tokens:ident $span:ident) => { + $crate::__private::push_pound_spanned(&mut $tokens, $span); + }; + + (, $tokens:ident $span:ident) => { + $crate::__private::push_comma_spanned(&mut $tokens, $span); + }; + + (. $tokens:ident $span:ident) => { + $crate::__private::push_dot_spanned(&mut $tokens, $span); + }; + + (; $tokens:ident $span:ident) => { + $crate::__private::push_semi_spanned(&mut $tokens, $span); + }; + + (: $tokens:ident $span:ident) => { + $crate::__private::push_colon_spanned(&mut $tokens, $span); + }; + + (+ $tokens:ident $span:ident) => { + $crate::__private::push_add_spanned(&mut $tokens, $span); + }; + + (+= $tokens:ident $span:ident) => { + $crate::__private::push_add_eq_spanned(&mut $tokens, $span); + }; + + (& $tokens:ident $span:ident) => { + $crate::__private::push_and_spanned(&mut $tokens, $span); + }; + + (&& $tokens:ident $span:ident) => { + $crate::__private::push_and_and_spanned(&mut $tokens, $span); + }; + + (&= $tokens:ident $span:ident) => { + $crate::__private::push_and_eq_spanned(&mut $tokens, $span); + }; + + (@ $tokens:ident $span:ident) => { + $crate::__private::push_at_spanned(&mut $tokens, $span); + }; + + (! $tokens:ident $span:ident) => { + $crate::__private::push_bang_spanned(&mut $tokens, $span); + }; + + (^ $tokens:ident $span:ident) => { + $crate::__private::push_caret_spanned(&mut $tokens, $span); + }; + + (^= $tokens:ident $span:ident) => { + $crate::__private::push_caret_eq_spanned(&mut $tokens, $span); + }; + + (/ $tokens:ident $span:ident) => { + $crate::__private::push_div_spanned(&mut $tokens, $span); + }; + + (/= $tokens:ident $span:ident) => { + $crate::__private::push_div_eq_spanned(&mut $tokens, $span); + }; + + (.. $tokens:ident $span:ident) => { + $crate::__private::push_dot2_spanned(&mut $tokens, $span); + }; + + (... $tokens:ident $span:ident) => { + $crate::__private::push_dot3_spanned(&mut $tokens, $span); + }; + + (..= $tokens:ident $span:ident) => { + $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span); + }; + + (= $tokens:ident $span:ident) => { + $crate::__private::push_eq_spanned(&mut $tokens, $span); + }; + + (== $tokens:ident $span:ident) => { + $crate::__private::push_eq_eq_spanned(&mut $tokens, $span); + }; + + (>= $tokens:ident $span:ident) => { + $crate::__private::push_ge_spanned(&mut $tokens, $span); + }; + + (> $tokens:ident $span:ident) => { + $crate::__private::push_gt_spanned(&mut $tokens, $span); + }; + + (<= $tokens:ident $span:ident) => { + $crate::__private::push_le_spanned(&mut $tokens, $span); + }; + + (< $tokens:ident $span:ident) => { + $crate::__private::push_lt_spanned(&mut $tokens, $span); + }; + + (*= $tokens:ident $span:ident) => { + $crate::__private::push_mul_eq_spanned(&mut $tokens, $span); + }; + + (!= $tokens:ident $span:ident) => { + $crate::__private::push_ne_spanned(&mut $tokens, $span); + }; + + (| $tokens:ident $span:ident) => { + $crate::__private::push_or_spanned(&mut $tokens, $span); + }; + + (|= $tokens:ident $span:ident) => { + $crate::__private::push_or_eq_spanned(&mut $tokens, $span); + }; + + (|| $tokens:ident $span:ident) => { + $crate::__private::push_or_or_spanned(&mut $tokens, $span); + }; + + (? $tokens:ident $span:ident) => { + $crate::__private::push_question_spanned(&mut $tokens, $span); + }; + + (-> $tokens:ident $span:ident) => { + $crate::__private::push_rarrow_spanned(&mut $tokens, $span); + }; + + (<- $tokens:ident $span:ident) => { + $crate::__private::push_larrow_spanned(&mut $tokens, $span); + }; + + (% $tokens:ident $span:ident) => { + $crate::__private::push_rem_spanned(&mut $tokens, $span); + }; + + (%= $tokens:ident $span:ident) => { + $crate::__private::push_rem_eq_spanned(&mut $tokens, $span); + }; + + (=> $tokens:ident $span:ident) => { + $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span); + }; + + (<< $tokens:ident $span:ident) => { + $crate::__private::push_shl_spanned(&mut $tokens, $span); + }; + + (<<= $tokens:ident $span:ident) => { + $crate::__private::push_shl_eq_spanned(&mut $tokens, $span); + }; + + (>> $tokens:ident $span:ident) => { + $crate::__private::push_shr_spanned(&mut $tokens, $span); + }; + + (>>= $tokens:ident $span:ident) => { + $crate::__private::push_shr_eq_spanned(&mut $tokens, $span); + }; + + (* $tokens:ident $span:ident) => { + $crate::__private::push_star_spanned(&mut $tokens, $span); + }; + + (- $tokens:ident $span:ident) => { + $crate::__private::push_sub_spanned(&mut $tokens, $span); + }; + + (-= $tokens:ident $span:ident) => { + $crate::__private::push_sub_eq_spanned(&mut $tokens, $span); + }; + + ($lifetime:lifetime $tokens:ident $span:ident) => { + $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime)); + }; + + (_ $tokens:ident $span:ident) => { + $crate::__private::push_underscore_spanned(&mut $tokens, $span); + }; + + ($other:tt $tokens:ident $span:ident) => { + $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other)); + }; +} diff --git a/utshell-0.5.0/vendor/quote/src/runtime.rs b/utshell-0.5.0/vendor/quote/src/runtime.rs new file mode 100644 index 00000000..eff044a9 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/runtime.rs @@ -0,0 +1,530 @@ +use self::get_span::{GetSpan, GetSpanBase, GetSpanInner}; +use crate::{IdentFragment, ToTokens, TokenStreamExt}; +use core::fmt; +use core::iter; +use core::ops::BitOr; +use proc_macro2::{Group, Ident, Punct, Spacing, TokenTree}; + +#[doc(hidden)] +pub use alloc::format; +#[doc(hidden)] +pub use core::option::Option; + +#[doc(hidden)] +pub type Delimiter = proc_macro2::Delimiter; +#[doc(hidden)] +pub type Span = proc_macro2::Span; +#[doc(hidden)] +pub type TokenStream = proc_macro2::TokenStream; + +#[doc(hidden)] +pub struct HasIterator; // True +#[doc(hidden)] +pub struct ThereIsNoIteratorInRepetition; // False + +impl BitOr for ThereIsNoIteratorInRepetition { + type Output = ThereIsNoIteratorInRepetition; + fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> ThereIsNoIteratorInRepetition { + ThereIsNoIteratorInRepetition + } +} + +impl BitOr for HasIterator { + type Output = HasIterator; + fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> HasIterator { + HasIterator + } +} + +impl BitOr for ThereIsNoIteratorInRepetition { + type Output = HasIterator; + fn bitor(self, _rhs: HasIterator) -> HasIterator { + HasIterator + } +} + +impl BitOr for HasIterator { + type Output = HasIterator; + fn bitor(self, _rhs: HasIterator) -> HasIterator { + HasIterator + } +} + +/// Extension traits used by the implementation of `quote!`. These are defined +/// in separate traits, rather than as a single trait due to ambiguity issues. +/// +/// These traits expose a `quote_into_iter` method which should allow calling +/// whichever impl happens to be applicable. Calling that method repeatedly on +/// the returned value should be idempotent. +#[doc(hidden)] +pub mod ext { + use super::RepInterp; + use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter}; + use crate::ToTokens; + use alloc::collections::btree_set::{self, BTreeSet}; + use core::slice; + + /// Extension trait providing the `quote_into_iter` method on iterators. + #[doc(hidden)] + pub trait RepIteratorExt: Iterator + Sized { + fn quote_into_iter(self) -> (Self, HasIter) { + (self, HasIter) + } + } + + impl RepIteratorExt for T {} + + /// Extension trait providing the `quote_into_iter` method for + /// non-iterable types. These types interpolate the same value in each + /// iteration of the repetition. + #[doc(hidden)] + pub trait RepToTokensExt { + /// Pretend to be an iterator for the purposes of `quote_into_iter`. + /// This allows repeated calls to `quote_into_iter` to continue + /// correctly returning DoesNotHaveIter. + fn next(&self) -> Option<&Self> { + Some(self) + } + + fn quote_into_iter(&self) -> (&Self, DoesNotHaveIter) { + (self, DoesNotHaveIter) + } + } + + impl RepToTokensExt for T {} + + /// Extension trait providing the `quote_into_iter` method for types that + /// can be referenced as an iterator. + #[doc(hidden)] + pub trait RepAsIteratorExt<'q> { + type Iter: Iterator; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter); + } + + impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T { + type Iter = T::Iter; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + ::quote_into_iter(*self) + } + } + + impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T { + type Iter = T::Iter; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + ::quote_into_iter(*self) + } + } + + impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] { + type Iter = slice::Iter<'q, T>; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + (self.iter(), HasIter) + } + } + + impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec { + type Iter = slice::Iter<'q, T>; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + (self.iter(), HasIter) + } + } + + impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet { + type Iter = btree_set::Iter<'q, T>; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + (self.iter(), HasIter) + } + } + + impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp { + type Iter = T::Iter; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + self.0.quote_into_iter() + } + } +} + +// Helper type used within interpolations to allow for repeated binding names. +// Implements the relevant traits, and exports a dummy `next()` method. +#[derive(Copy, Clone)] +#[doc(hidden)] +pub struct RepInterp(pub T); + +impl RepInterp { + // This method is intended to look like `Iterator::next`, and is called when + // a name is bound multiple times, as the previous binding will shadow the + // original `Iterator` object. This allows us to avoid advancing the + // iterator multiple times per iteration. + pub fn next(self) -> Option { + Some(self.0) + } +} + +impl Iterator for RepInterp { + type Item = T::Item; + + fn next(&mut self) -> Option { + self.0.next() + } +} + +impl ToTokens for RepInterp { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens); + } +} + +#[doc(hidden)] +#[inline] +pub fn get_span(span: T) -> GetSpan { + GetSpan(GetSpanInner(GetSpanBase(span))) +} + +mod get_span { + use core::ops::Deref; + use proc_macro2::extra::DelimSpan; + use proc_macro2::Span; + + pub struct GetSpan(pub(crate) GetSpanInner); + + pub struct GetSpanInner(pub(crate) GetSpanBase); + + pub struct GetSpanBase(pub(crate) T); + + impl GetSpan { + #[inline] + pub fn __into_span(self) -> Span { + ((self.0).0).0 + } + } + + impl GetSpanInner { + #[inline] + pub fn __into_span(&self) -> Span { + (self.0).0.join() + } + } + + impl GetSpanBase { + #[allow(clippy::unused_self)] + pub fn __into_span(&self) -> T { + unreachable!() + } + } + + impl Deref for GetSpan { + type Target = GetSpanInner; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl Deref for GetSpanInner { + type Target = GetSpanBase; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } +} + +#[doc(hidden)] +pub fn push_group(tokens: &mut TokenStream, delimiter: Delimiter, inner: TokenStream) { + tokens.append(Group::new(delimiter, inner)); +} + +#[doc(hidden)] +pub fn push_group_spanned( + tokens: &mut TokenStream, + span: Span, + delimiter: Delimiter, + inner: TokenStream, +) { + let mut g = Group::new(delimiter, inner); + g.set_span(span); + tokens.append(g); +} + +#[doc(hidden)] +pub fn parse(tokens: &mut TokenStream, s: &str) { + let s: TokenStream = s.parse().expect("invalid token stream"); + tokens.extend(iter::once(s)); +} + +#[doc(hidden)] +pub fn parse_spanned(tokens: &mut TokenStream, span: Span, s: &str) { + let s: TokenStream = s.parse().expect("invalid token stream"); + tokens.extend(s.into_iter().map(|t| respan_token_tree(t, span))); +} + +// Token tree with every span replaced by the given one. +fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree { + match &mut token { + TokenTree::Group(g) => { + let stream = g + .stream() + .into_iter() + .map(|token| respan_token_tree(token, span)) + .collect(); + *g = Group::new(g.delimiter(), stream); + g.set_span(span); + } + other => other.set_span(span), + } + token +} + +#[doc(hidden)] +pub fn push_ident(tokens: &mut TokenStream, s: &str) { + let span = Span::call_site(); + push_ident_spanned(tokens, span, s); +} + +#[doc(hidden)] +pub fn push_ident_spanned(tokens: &mut TokenStream, span: Span, s: &str) { + tokens.append(ident_maybe_raw(s, span)); +} + +#[doc(hidden)] +pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) { + struct Lifetime<'a> { + name: &'a str, + state: u8, + } + + impl<'a> Iterator for Lifetime<'a> { + type Item = TokenTree; + + fn next(&mut self) -> Option { + match self.state { + 0 => { + self.state = 1; + Some(TokenTree::Punct(Punct::new('\'', Spacing::Joint))) + } + 1 => { + self.state = 2; + Some(TokenTree::Ident(Ident::new(self.name, Span::call_site()))) + } + _ => None, + } + } + } + + tokens.extend(Lifetime { + name: &lifetime[1..], + state: 0, + }); +} + +#[doc(hidden)] +pub fn push_lifetime_spanned(tokens: &mut TokenStream, span: Span, lifetime: &str) { + struct Lifetime<'a> { + name: &'a str, + span: Span, + state: u8, + } + + impl<'a> Iterator for Lifetime<'a> { + type Item = TokenTree; + + fn next(&mut self) -> Option { + match self.state { + 0 => { + self.state = 1; + let mut apostrophe = Punct::new('\'', Spacing::Joint); + apostrophe.set_span(self.span); + Some(TokenTree::Punct(apostrophe)) + } + 1 => { + self.state = 2; + Some(TokenTree::Ident(Ident::new(self.name, self.span))) + } + _ => None, + } + } + } + + tokens.extend(Lifetime { + name: &lifetime[1..], + span, + state: 0, + }); +} + +macro_rules! push_punct { + ($name:ident $spanned:ident $char1:tt) => { + #[doc(hidden)] + pub fn $name(tokens: &mut TokenStream) { + tokens.append(Punct::new($char1, Spacing::Alone)); + } + #[doc(hidden)] + pub fn $spanned(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; + ($name:ident $spanned:ident $char1:tt $char2:tt) => { + #[doc(hidden)] + pub fn $name(tokens: &mut TokenStream) { + tokens.append(Punct::new($char1, Spacing::Joint)); + tokens.append(Punct::new($char2, Spacing::Alone)); + } + #[doc(hidden)] + pub fn $spanned(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char2, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; + ($name:ident $spanned:ident $char1:tt $char2:tt $char3:tt) => { + #[doc(hidden)] + pub fn $name(tokens: &mut TokenStream) { + tokens.append(Punct::new($char1, Spacing::Joint)); + tokens.append(Punct::new($char2, Spacing::Joint)); + tokens.append(Punct::new($char3, Spacing::Alone)); + } + #[doc(hidden)] + pub fn $spanned(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char2, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char3, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; +} + +push_punct!(push_add push_add_spanned '+'); +push_punct!(push_add_eq push_add_eq_spanned '+' '='); +push_punct!(push_and push_and_spanned '&'); +push_punct!(push_and_and push_and_and_spanned '&' '&'); +push_punct!(push_and_eq push_and_eq_spanned '&' '='); +push_punct!(push_at push_at_spanned '@'); +push_punct!(push_bang push_bang_spanned '!'); +push_punct!(push_caret push_caret_spanned '^'); +push_punct!(push_caret_eq push_caret_eq_spanned '^' '='); +push_punct!(push_colon push_colon_spanned ':'); +push_punct!(push_colon2 push_colon2_spanned ':' ':'); +push_punct!(push_comma push_comma_spanned ','); +push_punct!(push_div push_div_spanned '/'); +push_punct!(push_div_eq push_div_eq_spanned '/' '='); +push_punct!(push_dot push_dot_spanned '.'); +push_punct!(push_dot2 push_dot2_spanned '.' '.'); +push_punct!(push_dot3 push_dot3_spanned '.' '.' '.'); +push_punct!(push_dot_dot_eq push_dot_dot_eq_spanned '.' '.' '='); +push_punct!(push_eq push_eq_spanned '='); +push_punct!(push_eq_eq push_eq_eq_spanned '=' '='); +push_punct!(push_ge push_ge_spanned '>' '='); +push_punct!(push_gt push_gt_spanned '>'); +push_punct!(push_le push_le_spanned '<' '='); +push_punct!(push_lt push_lt_spanned '<'); +push_punct!(push_mul_eq push_mul_eq_spanned '*' '='); +push_punct!(push_ne push_ne_spanned '!' '='); +push_punct!(push_or push_or_spanned '|'); +push_punct!(push_or_eq push_or_eq_spanned '|' '='); +push_punct!(push_or_or push_or_or_spanned '|' '|'); +push_punct!(push_pound push_pound_spanned '#'); +push_punct!(push_question push_question_spanned '?'); +push_punct!(push_rarrow push_rarrow_spanned '-' '>'); +push_punct!(push_larrow push_larrow_spanned '<' '-'); +push_punct!(push_rem push_rem_spanned '%'); +push_punct!(push_rem_eq push_rem_eq_spanned '%' '='); +push_punct!(push_fat_arrow push_fat_arrow_spanned '=' '>'); +push_punct!(push_semi push_semi_spanned ';'); +push_punct!(push_shl push_shl_spanned '<' '<'); +push_punct!(push_shl_eq push_shl_eq_spanned '<' '<' '='); +push_punct!(push_shr push_shr_spanned '>' '>'); +push_punct!(push_shr_eq push_shr_eq_spanned '>' '>' '='); +push_punct!(push_star push_star_spanned '*'); +push_punct!(push_sub push_sub_spanned '-'); +push_punct!(push_sub_eq push_sub_eq_spanned '-' '='); + +#[doc(hidden)] +pub fn push_underscore(tokens: &mut TokenStream) { + push_underscore_spanned(tokens, Span::call_site()); +} + +#[doc(hidden)] +pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) { + tokens.append(Ident::new("_", span)); +} + +// Helper method for constructing identifiers from the `format_ident!` macro, +// handling `r#` prefixes. +#[doc(hidden)] +pub fn mk_ident(id: &str, span: Option) -> Ident { + let span = span.unwrap_or_else(Span::call_site); + ident_maybe_raw(id, span) +} + +fn ident_maybe_raw(id: &str, span: Span) -> Ident { + if let Some(id) = id.strip_prefix("r#") { + Ident::new_raw(id, span) + } else { + Ident::new(id, span) + } +} + +// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!` +// macro, and exposes span information from these fragments. +// +// This struct also has forwarding implementations of the formatting traits +// `Octal`, `LowerHex`, `UpperHex`, and `Binary` to allow for their use within +// `format_ident!`. +#[derive(Copy, Clone)] +#[doc(hidden)] +pub struct IdentFragmentAdapter(pub T); + +impl IdentFragmentAdapter { + pub fn span(&self) -> Option { + self.0.span() + } +} + +impl fmt::Display for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + IdentFragment::fmt(&self.0, f) + } +} + +impl fmt::Octal for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Octal::fmt(&self.0, f) + } +} + +impl fmt::LowerHex for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::LowerHex::fmt(&self.0, f) + } +} + +impl fmt::UpperHex for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::UpperHex::fmt(&self.0, f) + } +} + +impl fmt::Binary for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Binary::fmt(&self.0, f) + } +} diff --git a/utshell-0.5.0/vendor/quote/src/spanned.rs b/utshell-0.5.0/vendor/quote/src/spanned.rs new file mode 100644 index 00000000..6eba6444 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/spanned.rs @@ -0,0 +1,50 @@ +use crate::ToTokens; +use proc_macro2::extra::DelimSpan; +use proc_macro2::{Span, TokenStream}; + +// Not public API other than via the syn crate. Use syn::spanned::Spanned. +pub trait Spanned: private::Sealed { + fn __span(&self) -> Span; +} + +impl Spanned for Span { + fn __span(&self) -> Span { + *self + } +} + +impl Spanned for DelimSpan { + fn __span(&self) -> Span { + self.join() + } +} + +impl Spanned for T { + fn __span(&self) -> Span { + join_spans(self.into_token_stream()) + } +} + +fn join_spans(tokens: TokenStream) -> Span { + let mut iter = tokens.into_iter().map(|tt| tt.span()); + + let first = match iter.next() { + Some(span) => span, + None => return Span::call_site(), + }; + + iter.fold(None, |_prev, next| Some(next)) + .and_then(|last| first.join(last)) + .unwrap_or(first) +} + +mod private { + use crate::ToTokens; + use proc_macro2::extra::DelimSpan; + use proc_macro2::Span; + + pub trait Sealed {} + impl Sealed for Span {} + impl Sealed for DelimSpan {} + impl Sealed for T {} +} diff --git a/utshell-0.5.0/vendor/quote/src/to_tokens.rs b/utshell-0.5.0/vendor/quote/src/to_tokens.rs new file mode 100644 index 00000000..23b6ec2c --- /dev/null +++ b/utshell-0.5.0/vendor/quote/src/to_tokens.rs @@ -0,0 +1,209 @@ +use super::TokenStreamExt; +use alloc::borrow::Cow; +use alloc::rc::Rc; +use core::iter; +use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree}; + +/// Types that can be interpolated inside a `quote!` invocation. +/// +/// [`quote!`]: macro.quote.html +pub trait ToTokens { + /// Write `self` to the given `TokenStream`. + /// + /// The token append methods provided by the [`TokenStreamExt`] extension + /// trait may be useful for implementing `ToTokens`. + /// + /// [`TokenStreamExt`]: trait.TokenStreamExt.html + /// + /// # Example + /// + /// Example implementation for a struct representing Rust paths like + /// `std::cmp::PartialEq`: + /// + /// ``` + /// use proc_macro2::{TokenTree, Spacing, Span, Punct, TokenStream}; + /// use quote::{TokenStreamExt, ToTokens}; + /// + /// pub struct Path { + /// pub global: bool, + /// pub segments: Vec, + /// } + /// + /// impl ToTokens for Path { + /// fn to_tokens(&self, tokens: &mut TokenStream) { + /// for (i, segment) in self.segments.iter().enumerate() { + /// if i > 0 || self.global { + /// // Double colon `::` + /// tokens.append(Punct::new(':', Spacing::Joint)); + /// tokens.append(Punct::new(':', Spacing::Alone)); + /// } + /// segment.to_tokens(tokens); + /// } + /// } + /// } + /// # + /// # pub struct PathSegment; + /// # + /// # impl ToTokens for PathSegment { + /// # fn to_tokens(&self, tokens: &mut TokenStream) { + /// # unimplemented!() + /// # } + /// # } + /// ``` + fn to_tokens(&self, tokens: &mut TokenStream); + + /// Convert `self` directly into a `TokenStream` object. + /// + /// This method is implicitly implemented using `to_tokens`, and acts as a + /// convenience method for consumers of the `ToTokens` trait. + fn to_token_stream(&self) -> TokenStream { + let mut tokens = TokenStream::new(); + self.to_tokens(&mut tokens); + tokens + } + + /// Convert `self` directly into a `TokenStream` object. + /// + /// This method is implicitly implemented using `to_tokens`, and acts as a + /// convenience method for consumers of the `ToTokens` trait. + fn into_token_stream(self) -> TokenStream + where + Self: Sized, + { + self.to_token_stream() + } +} + +impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl ToTokens for Box { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl ToTokens for Rc { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl ToTokens for Option { + fn to_tokens(&self, tokens: &mut TokenStream) { + if let Some(ref t) = *self { + t.to_tokens(tokens); + } + } +} + +impl ToTokens for str { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::string(self)); + } +} + +impl ToTokens for String { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.as_str().to_tokens(tokens); + } +} + +macro_rules! primitive { + ($($t:ident => $name:ident)*) => { + $( + impl ToTokens for $t { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::$name(*self)); + } + } + )* + }; +} + +primitive! { + i8 => i8_suffixed + i16 => i16_suffixed + i32 => i32_suffixed + i64 => i64_suffixed + i128 => i128_suffixed + isize => isize_suffixed + + u8 => u8_suffixed + u16 => u16_suffixed + u32 => u32_suffixed + u64 => u64_suffixed + u128 => u128_suffixed + usize => usize_suffixed + + f32 => f32_suffixed + f64 => f64_suffixed +} + +impl ToTokens for char { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::character(*self)); + } +} + +impl ToTokens for bool { + fn to_tokens(&self, tokens: &mut TokenStream) { + let word = if *self { "true" } else { "false" }; + tokens.append(Ident::new(word, Span::call_site())); + } +} + +impl ToTokens for Group { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for Ident { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for Punct { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for Literal { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for TokenTree { + fn to_tokens(&self, dst: &mut TokenStream) { + dst.append(self.clone()); + } +} + +impl ToTokens for TokenStream { + fn to_tokens(&self, dst: &mut TokenStream) { + dst.extend(iter::once(self.clone())); + } + + fn into_token_stream(self) -> TokenStream { + self + } +} diff --git a/utshell-0.5.0/vendor/quote/tests/compiletest.rs b/utshell-0.5.0/vendor/quote/tests/compiletest.rs new file mode 100644 index 00000000..7974a624 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/compiletest.rs @@ -0,0 +1,7 @@ +#[rustversion::attr(not(nightly), ignore)] +#[cfg_attr(miri, ignore)] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/utshell-0.5.0/vendor/quote/tests/test.rs b/utshell-0.5.0/vendor/quote/tests/test.rs new file mode 100644 index 00000000..eab4f55a --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/test.rs @@ -0,0 +1,549 @@ +#![allow( + clippy::disallowed_names, + clippy::let_underscore_untyped, + clippy::shadow_unrelated, + clippy::unseparated_literal_suffix, + clippy::used_underscore_binding +)] + +extern crate proc_macro; + +use std::borrow::Cow; +use std::collections::BTreeSet; + +use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, TokenStreamExt}; + +struct X; + +impl quote::ToTokens for X { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Ident::new("X", Span::call_site())); + } +} + +#[test] +fn test_quote_impl() { + let tokens = quote! { + impl<'a, T: ToTokens> ToTokens for &'a T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens) + } + } + }; + + let expected = concat!( + "impl < 'a , T : ToTokens > ToTokens for & 'a T { ", + "fn to_tokens (& self , tokens : & mut TokenStream) { ", + "(* * self) . to_tokens (tokens) ", + "} ", + "}" + ); + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_quote_spanned_impl() { + let span = Span::call_site(); + let tokens = quote_spanned! {span=> + impl<'a, T: ToTokens> ToTokens for &'a T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens) + } + } + }; + + let expected = concat!( + "impl < 'a , T : ToTokens > ToTokens for & 'a T { ", + "fn to_tokens (& self , tokens : & mut TokenStream) { ", + "(* * self) . to_tokens (tokens) ", + "} ", + "}" + ); + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_substitution() { + let x = X; + let tokens = quote!(#x <#x> (#x) [#x] {#x}); + + let expected = "X < X > (X) [X] { X }"; + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_iter() { + let primes = &[X, X, X, X]; + + assert_eq!("X X X X", quote!(#(#primes)*).to_string()); + + assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string()); + + assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string()); +} + +#[test] +fn test_array() { + let array: [u8; 40] = [0; 40]; + let _ = quote!(#(#array #array)*); + + let ref_array: &[u8; 40] = &[0; 40]; + let _ = quote!(#(#ref_array #ref_array)*); + + let ref_slice: &[u8] = &[0; 40]; + let _ = quote!(#(#ref_slice #ref_slice)*); + + let array: [X; 2] = [X, X]; // !Copy + let _ = quote!(#(#array #array)*); + + let ref_array: &[X; 2] = &[X, X]; + let _ = quote!(#(#ref_array #ref_array)*); + + let ref_slice: &[X] = &[X, X]; + let _ = quote!(#(#ref_slice #ref_slice)*); +} + +#[test] +fn test_advanced() { + let generics = quote!( <'a, T> ); + + let where_clause = quote!( where T: Serialize ); + + let field_ty = quote!(String); + + let item_ty = quote!(Cow<'a, str>); + + let path = quote!(SomeTrait::serialize_with); + + let value = quote!(self.x); + + let tokens = quote! { + struct SerializeWith #generics #where_clause { + value: &'a #field_ty, + phantom: ::std::marker::PhantomData<#item_ty>, + } + + impl #generics ::serde::Serialize for SerializeWith #generics #where_clause { + fn serialize(&self, s: &mut S) -> Result<(), S::Error> + where S: ::serde::Serializer + { + #path(self.value, s) + } + } + + SerializeWith { + value: #value, + phantom: ::std::marker::PhantomData::<#item_ty>, + } + }; + + let expected = concat!( + "struct SerializeWith < 'a , T > where T : Serialize { ", + "value : & 'a String , ", + "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ", + "} ", + "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ", + "fn serialize < S > (& self , s : & mut S) -> Result < () , S :: Error > ", + "where S : :: serde :: Serializer ", + "{ ", + "SomeTrait :: serialize_with (self . value , s) ", + "} ", + "} ", + "SerializeWith { ", + "value : self . x , ", + "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ", + "}" + ); + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_integer() { + let ii8 = -1i8; + let ii16 = -1i16; + let ii32 = -1i32; + let ii64 = -1i64; + let ii128 = -1i128; + let iisize = -1isize; + let uu8 = 1u8; + let uu16 = 1u16; + let uu32 = 1u32; + let uu64 = 1u64; + let uu128 = 1u128; + let uusize = 1usize; + + let tokens = quote! { + 1 1i32 1u256 + #ii8 #ii16 #ii32 #ii64 #ii128 #iisize + #uu8 #uu16 #uu32 #uu64 #uu128 #uusize + }; + let expected = + "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_floating() { + let e32 = 2.345f32; + + let e64 = 2.345f64; + + let tokens = quote! { + #e32 + #e64 + }; + let expected = concat!("2.345f32 2.345f64"); + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_char() { + let zero = '\u{1}'; + let pound = '#'; + let quote = '"'; + let apost = '\''; + let newline = '\n'; + let heart = '\u{2764}'; + + let tokens = quote! { + #zero #pound #quote #apost #newline #heart + }; + let expected = "'\\u{1}' '#' '\"' '\\'' '\\n' '\u{2764}'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_str() { + let s = "\u{1} a 'b \" c"; + let tokens = quote!(#s); + let expected = "\"\\u{1} a 'b \\\" c\""; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_string() { + let s = "\u{1} a 'b \" c".to_string(); + let tokens = quote!(#s); + let expected = "\"\\u{1} a 'b \\\" c\""; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_interpolated_literal() { + macro_rules! m { + ($literal:literal) => { + quote!($literal) + }; + } + + let tokens = m!(1); + let expected = "1"; + assert_eq!(expected, tokens.to_string()); + + let tokens = m!(-1); + let expected = "- 1"; + assert_eq!(expected, tokens.to_string()); + + let tokens = m!(true); + let expected = "true"; + assert_eq!(expected, tokens.to_string()); + + let tokens = m!(-true); + let expected = "- true"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_ident() { + let foo = Ident::new("Foo", Span::call_site()); + let bar = Ident::new(&format!("Bar{}", 7), Span::call_site()); + let tokens = quote!(struct #foo; enum #bar {}); + let expected = "struct Foo ; enum Bar7 { }"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_underscore() { + let tokens = quote!(let _;); + let expected = "let _ ;"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_duplicate() { + let ch = 'x'; + + let tokens = quote!(#ch #ch); + + let expected = "'x' 'x'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_fancy_repetition() { + let foo = vec!["a", "b"]; + let bar = vec![true, false]; + + let tokens = quote! { + #(#foo: #bar),* + }; + + let expected = r#""a" : true , "b" : false"#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_nested_fancy_repetition() { + let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']]; + + let tokens = quote! { + #( + #(#nested)* + ),* + }; + + let expected = "'a' 'b' 'c' , 'x' 'y' 'z'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_duplicate_name_repetition() { + let foo = &["a", "b"]; + + let tokens = quote! { + #(#foo: #foo),* + #(#foo: #foo),* + }; + + let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_duplicate_name_repetition_no_copy() { + let foo = vec!["a".to_owned(), "b".to_owned()]; + + let tokens = quote! { + #(#foo: #foo),* + }; + + let expected = r#""a" : "a" , "b" : "b""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_btreeset_repetition() { + let mut set = BTreeSet::new(); + set.insert("a".to_owned()); + set.insert("b".to_owned()); + + let tokens = quote! { + #(#set: #set),* + }; + + let expected = r#""a" : "a" , "b" : "b""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_variable_name_conflict() { + // The implementation of `#(...),*` uses the variable `_i` but it should be + // fine, if a little confusing when debugging. + let _i = vec!['a', 'b']; + let tokens = quote! { #(#_i),* }; + let expected = "'a' , 'b'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_nonrep_in_repetition() { + let rep = vec!["a", "b"]; + let nonrep = "c"; + + let tokens = quote! { + #(#rep #rep : #nonrep #nonrep),* + }; + + let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_empty_quote() { + let tokens = quote!(); + assert_eq!("", tokens.to_string()); +} + +#[test] +fn test_box_str() { + let b = "str".to_owned().into_boxed_str(); + let tokens = quote! { #b }; + assert_eq!("\"str\"", tokens.to_string()); +} + +#[test] +fn test_cow() { + let owned: Cow = Cow::Owned(Ident::new("owned", Span::call_site())); + + let ident = Ident::new("borrowed", Span::call_site()); + let borrowed = Cow::Borrowed(&ident); + + let tokens = quote! { #owned #borrowed }; + assert_eq!("owned borrowed", tokens.to_string()); +} + +#[test] +fn test_closure() { + fn field_i(i: usize) -> Ident { + format_ident!("__field{}", i) + } + + let fields = (0usize..3) + .map(field_i as fn(_) -> _) + .map(|var| quote! { #var }); + + let tokens = quote! { #(#fields)* }; + assert_eq!("__field0 __field1 __field2", tokens.to_string()); +} + +#[test] +fn test_append_tokens() { + let mut a = quote!(a); + let b = quote!(b); + a.append_all(b); + assert_eq!("a b", a.to_string()); +} + +#[test] +fn test_format_ident() { + let id0 = format_ident!("Aa"); + let id1 = format_ident!("Hello{x}", x = id0); + let id2 = format_ident!("Hello{x}", x = 5usize); + let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize); + let id4 = format_ident!("Aa", span = Span::call_site()); + let id5 = format_ident!("Hello{}", Cow::Borrowed("World")); + + assert_eq!(id0, "Aa"); + assert_eq!(id1, "HelloAa"); + assert_eq!(id2, "Hello5"); + assert_eq!(id3, "HelloAa_10"); + assert_eq!(id4, "Aa"); + assert_eq!(id5, "HelloWorld"); +} + +#[test] +fn test_format_ident_strip_raw() { + let id = format_ident!("r#struct"); + let my_id = format_ident!("MyId{}", id); + let raw_my_id = format_ident!("r#MyId{}", id); + + assert_eq!(id, "r#struct"); + assert_eq!(my_id, "MyIdstruct"); + assert_eq!(raw_my_id, "r#MyIdstruct"); +} + +#[test] +fn test_outer_line_comment() { + let tokens = quote! { + /// doc + }; + let expected = "# [doc = r\" doc\"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_inner_line_comment() { + let tokens = quote! { + //! doc + }; + let expected = "# ! [doc = r\" doc\"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_outer_block_comment() { + let tokens = quote! { + /** doc */ + }; + let expected = "# [doc = r\" doc \"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_inner_block_comment() { + let tokens = quote! { + /*! doc */ + }; + let expected = "# ! [doc = r\" doc \"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_outer_attr() { + let tokens = quote! { + #[inline] + }; + let expected = "# [inline]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_inner_attr() { + let tokens = quote! { + #![no_std] + }; + let expected = "# ! [no_std]"; + assert_eq!(expected, tokens.to_string()); +} + +// https://github.com/dtolnay/quote/issues/130 +#[test] +fn test_star_after_repetition() { + let c = vec!['0', '1']; + let tokens = quote! { + #( + f(#c); + )* + *out = None; + }; + let expected = "f ('0') ; f ('1') ; * out = None ;"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_quote_raw_id() { + let id = quote!(r#raw_id); + assert_eq!(id.to_string(), "r#raw_id"); +} + +#[test] +fn test_type_inference_for_span() { + trait CallSite { + fn get() -> Self; + } + + impl CallSite for Span { + fn get() -> Self { + Span::call_site() + } + } + + let span = Span::call_site(); + let _ = quote_spanned!(span=> ...); + + let delim_span = Group::new(Delimiter::Parenthesis, TokenStream::new()).delim_span(); + let _ = quote_spanned!(delim_span=> ...); + + let inferred = CallSite::get(); + let _ = quote_spanned!(inferred=> ...); + + if false { + let proc_macro_span = proc_macro::Span::call_site(); + let _ = quote_spanned!(proc_macro_span.into()=> ...); + } +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs new file mode 100644 index 00000000..0a39f415 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs @@ -0,0 +1,9 @@ +use quote::quote; + +fn main() { + let nonrep = ""; + + // Without some protection against repetitions with no iterator somewhere + // inside, this would loop infinitely. + quote!(#(#nonrep #nonrep)*); +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr new file mode 100644 index 00000000..99c20a56 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter-interpolated-dup.rs:8:5 + | +8 | quote!(#(#nonrep #nonrep)*); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs new file mode 100644 index 00000000..2c740cc0 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs @@ -0,0 +1,9 @@ +use quote::quote; + +fn main() { + let nonrep = ""; + + // Without some protection against repetitions with no iterator somewhere + // inside, this would loop infinitely. + quote!(#(#nonrep)*); +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr new file mode 100644 index 00000000..ef908131 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter-interpolated.rs:8:5 + | +8 | quote!(#(#nonrep)*); + | ^^^^^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.rs b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.rs new file mode 100644 index 00000000..c027243d --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.rs @@ -0,0 +1,5 @@ +use quote::quote; + +fn main() { + quote!(#(a b),*); +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.stderr b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.stderr new file mode 100644 index 00000000..7c6e30f2 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter-separated.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter-separated.rs:4:5 + | +4 | quote!(#(a b),*); + | ^^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.rs b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.rs new file mode 100644 index 00000000..8908353b --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.rs @@ -0,0 +1,5 @@ +use quote::quote; + +fn main() { + quote!(#(a b)*); +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.stderr b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.stderr new file mode 100644 index 00000000..0b13e5cb --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/does-not-have-iter.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter.rs:4:5 + | +4 | quote!(#(a b)*); + | ^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/quote/tests/ui/not-quotable.rs b/utshell-0.5.0/vendor/quote/tests/ui/not-quotable.rs new file mode 100644 index 00000000..f991c188 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/not-quotable.rs @@ -0,0 +1,7 @@ +use quote::quote; +use std::net::Ipv4Addr; + +fn main() { + let ip = Ipv4Addr::LOCALHOST; + let _ = quote! { #ip }; +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/not-quotable.stderr b/utshell-0.5.0/vendor/quote/tests/ui/not-quotable.stderr new file mode 100644 index 00000000..35cb6f2b --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/not-quotable.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied + --> tests/ui/not-quotable.rs:6:13 + | +6 | let _ = quote! { #ip }; + | ^^^^^^^^^^^^^^ + | | + | the trait `ToTokens` is not implemented for `Ipv4Addr` + | required by a bound introduced by this call + | + = help: the following other types implement trait `ToTokens`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + = note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.rs b/utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.rs new file mode 100644 index 00000000..a8f0fe77 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.rs @@ -0,0 +1,8 @@ +use quote::quote; + +struct Ipv4Addr; + +fn main() { + let ip = Ipv4Addr; + let _ = quote! { #(#ip)* }; +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.stderr b/utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.stderr new file mode 100644 index 00000000..2ed1da04 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/not-repeatable.stderr @@ -0,0 +1,35 @@ +error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied + --> tests/ui/not-repeatable.rs:7:13 + | +3 | struct Ipv4Addr; + | --------------- + | | + | method `quote_into_iter` not found for this struct + | doesn't satisfy `Ipv4Addr: Iterator` + | doesn't satisfy `Ipv4Addr: ToTokens` + | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt` + | doesn't satisfy `Ipv4Addr: ext::RepToTokensExt` +... +7 | let _ = quote! { #(#ip)* }; + | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Ipv4Addr: Iterator` + which is required by `Ipv4Addr: ext::RepIteratorExt` + `&Ipv4Addr: Iterator` + which is required by `&Ipv4Addr: ext::RepIteratorExt` + `Ipv4Addr: ToTokens` + which is required by `Ipv4Addr: ext::RepToTokensExt` + `&mut Ipv4Addr: Iterator` + which is required by `&mut Ipv4Addr: ext::RepIteratorExt` +note: the traits `ToTokens` and `Iterator` must be implemented + --> src/to_tokens.rs + | + | pub trait ToTokens { + | ^^^^^^^^^^^^^^^^^^ + | + ::: $RUST/core/src/iter/traits/iterator.rs + | + | pub trait Iterator { + | ^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.rs b/utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.rs new file mode 100644 index 00000000..d5601c8a --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.rs @@ -0,0 +1,7 @@ +use quote::quote_spanned; + +fn main() { + let span = ""; + let x = 0i32; + quote_spanned!(span=> #x); +} diff --git a/utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.stderr b/utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.stderr new file mode 100644 index 00000000..12ad3077 --- /dev/null +++ b/utshell-0.5.0/vendor/quote/tests/ui/wrong-type-span.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> tests/ui/wrong-type-span.rs:6:5 + | +6 | quote_spanned!(span=> #x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `Span`, found `&str` + | expected due to this + | + = note: this error originates in the macro `quote_spanned` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/utshell-0.5.0/vendor/rustc-hash/.cargo-checksum.json b/utshell-0.5.0/vendor/rustc-hash/.cargo-checksum.json new file mode 100644 index 00000000..544af9fd --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CODE_OF_CONDUCT.md":"edca092fde496419a9f1ba640048aa0270b62dfea576cd3175f0b53e3c230470","Cargo.toml":"647814b27b6fc4fbef1df70d796b53b723e776b68467372044e4182763007379","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"cac8197ac869d64a6efc26cab883a269392ae6db51f7453bca722f8f31d67c7c","src/lib.rs":"ddecafb5db609d0d8eebd19e4d98dc865e7e9282a4183421f9bd765c01a231c0"},"package":"08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/rustc-hash/CODE_OF_CONDUCT.md b/utshell-0.5.0/vendor/rustc-hash/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..d70b2b52 --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/CODE_OF_CONDUCT.md @@ -0,0 +1,40 @@ +# The Rust Code of Conduct + +A version of this document [can be found online](https://www.rust-lang.org/conduct.html). + +## Conduct + +**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org) + +* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. +* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. +* Please be kind and courteous. There's no need to be mean or rude. +* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. +* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. +* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. + +## Moderation + + +These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team]. + +1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) +2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. +3. Moderators will first respond to such remarks with a warning. +4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. +5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. +6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. +7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. +8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. + +In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. + +And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. + +The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. + +*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* + +[mod_team]: https://www.rust-lang.org/team.html#Moderation-team diff --git a/utshell-0.5.0/vendor/rustc-hash/Cargo.toml b/utshell-0.5.0/vendor/rustc-hash/Cargo.toml new file mode 100644 index 00000000..47330b7e --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/Cargo.toml @@ -0,0 +1,25 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "rustc-hash" +version = "1.1.0" +authors = ["The Rust Project Developers"] +description = "speed, non-cryptographic hash used in rustc" +readme = "README.md" +keywords = ["hash", "fxhash", "rustc"] +license = "Apache-2.0/MIT" +repository = "https://github.com/rust-lang-nursery/rustc-hash" + +[features] +default = ["std"] +std = [] diff --git a/utshell-0.5.0/vendor/rustc-hash/LICENSE-APACHE b/utshell-0.5.0/vendor/rustc-hash/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/rustc-hash/LICENSE-MIT b/utshell-0.5.0/vendor/rustc-hash/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/rustc-hash/README.md b/utshell-0.5.0/vendor/rustc-hash/README.md new file mode 100644 index 00000000..e33057ac --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/README.md @@ -0,0 +1,38 @@ +# rustc-hash + +[![crates.io](https://img.shields.io/crates/v/rustc-hash.svg)](https://crates.io/crates/rustc-hash) +[![Documentation](https://docs.rs/rustc-hash/badge.svg)](https://docs.rs/rustc-hash) + +A speedy hash algorithm used within rustc. The hashmap in liballoc by +default uses SipHash which isn't quite as speedy as we want. In the +compiler we're not really worried about DOS attempts, so we use a fast +non-cryptographic hash. + +This is the same as the algorithm used by Firefox -- which is a +homespun one not based on any widely-known algorithm -- though +modified to produce 64-bit hash values instead of 32-bit hash +values. It consistently out-performs an FNV-based hash within rustc +itself -- the collision rate is similar or slightly worse than FNV, +but the speed of the hash function itself is much higher because it +works on up to 8 bytes at a time. + +## Usage + +```rust +use rustc_hash::FxHashMap; + +let mut map: FxHashMap = FxHashMap::default(); +map.insert(22, 44); +``` + +### `no_std` + +This crate can be used as a `no_std` crate by disabling the `std` +feature, which is on by default, as follows: + +```toml +rustc-hash = { version = "1.0", default-features = false } +``` + +In this configuration, `FxHasher` is the only export, and the +`FxHashMap`/`FxHashSet` type aliases are omitted. diff --git a/utshell-0.5.0/vendor/rustc-hash/src/lib.rs b/utshell-0.5.0/vendor/rustc-hash/src/lib.rs new file mode 100644 index 00000000..ee9ad31a --- /dev/null +++ b/utshell-0.5.0/vendor/rustc-hash/src/lib.rs @@ -0,0 +1,148 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Fast, non-cryptographic hash used by rustc and Firefox. +//! +//! # Example +//! +//! ```rust +//! # #[cfg(feature = "std")] +//! # fn main() { +//! use rustc_hash::FxHashMap; +//! let mut map: FxHashMap = FxHashMap::default(); +//! map.insert(22, 44); +//! # } +//! # #[cfg(not(feature = "std"))] +//! # fn main() { } +//! ``` + +#![no_std] + +#[cfg(feature = "std")] +extern crate std; + +use core::convert::TryInto; +use core::default::Default; +#[cfg(feature = "std")] +use core::hash::BuildHasherDefault; +use core::hash::Hasher; +use core::mem::size_of; +use core::ops::BitXor; +#[cfg(feature = "std")] +use std::collections::{HashMap, HashSet}; + +/// Type alias for a hashmap using the `fx` hash algorithm. +#[cfg(feature = "std")] +pub type FxHashMap = HashMap>; + +/// Type alias for a hashmap using the `fx` hash algorithm. +#[cfg(feature = "std")] +pub type FxHashSet = HashSet>; + +/// A speedy hash algorithm for use within rustc. The hashmap in liballoc +/// by default uses SipHash which isn't quite as speedy as we want. In the +/// compiler we're not really worried about DOS attempts, so we use a fast +/// non-cryptographic hash. +/// +/// This is the same as the algorithm used by Firefox -- which is a homespun +/// one not based on any widely-known algorithm -- though modified to produce +/// 64-bit hash values instead of 32-bit hash values. It consistently +/// out-performs an FNV-based hash within rustc itself -- the collision rate is +/// similar or slightly worse than FNV, but the speed of the hash function +/// itself is much higher because it works on up to 8 bytes at a time. +pub struct FxHasher { + hash: usize, +} + +#[cfg(target_pointer_width = "32")] +const K: usize = 0x9e3779b9; +#[cfg(target_pointer_width = "64")] +const K: usize = 0x517cc1b727220a95; + +impl Default for FxHasher { + #[inline] + fn default() -> FxHasher { + FxHasher { hash: 0 } + } +} + +impl FxHasher { + #[inline] + fn add_to_hash(&mut self, i: usize) { + self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K); + } +} + +impl Hasher for FxHasher { + #[inline] + fn write(&mut self, mut bytes: &[u8]) { + #[cfg(target_pointer_width = "32")] + let read_usize = |bytes: &[u8]| u32::from_ne_bytes(bytes[..4].try_into().unwrap()); + #[cfg(target_pointer_width = "64")] + let read_usize = |bytes: &[u8]| u64::from_ne_bytes(bytes[..8].try_into().unwrap()); + + let mut hash = FxHasher { hash: self.hash }; + assert!(size_of::() <= 8); + while bytes.len() >= size_of::() { + hash.add_to_hash(read_usize(bytes) as usize); + bytes = &bytes[size_of::()..]; + } + if (size_of::() > 4) && (bytes.len() >= 4) { + hash.add_to_hash(u32::from_ne_bytes(bytes[..4].try_into().unwrap()) as usize); + bytes = &bytes[4..]; + } + if (size_of::() > 2) && bytes.len() >= 2 { + hash.add_to_hash(u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as usize); + bytes = &bytes[2..]; + } + if (size_of::() > 1) && bytes.len() >= 1 { + hash.add_to_hash(bytes[0] as usize); + } + self.hash = hash.hash; + } + + #[inline] + fn write_u8(&mut self, i: u8) { + self.add_to_hash(i as usize); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.add_to_hash(i as usize); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.add_to_hash(i as usize); + } + + #[cfg(target_pointer_width = "32")] + #[inline] + fn write_u64(&mut self, i: u64) { + self.add_to_hash(i as usize); + self.add_to_hash((i >> 32) as usize); + } + + #[cfg(target_pointer_width = "64")] + #[inline] + fn write_u64(&mut self, i: u64) { + self.add_to_hash(i as usize); + } + + #[inline] + fn write_usize(&mut self, i: usize) { + self.add_to_hash(i); + } + + #[inline] + fn finish(&self) -> u64 { + self.hash as u64 + } +} diff --git a/utshell-0.5.0/vendor/self_cell-0.10.3/.cargo-checksum.json b/utshell-0.5.0/vendor/self_cell-0.10.3/.cargo-checksum.json new file mode 100644 index 00000000..518c1837 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell-0.10.3/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"1aeb400d27fe5372f2684bf6f9d519ac38dd49d210184658fc5cd60a3ba3e091","LICENSE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","README.md":"ba005ba915be476f39b24f2a4810e259635793a872cf25923371473fe40a242c","src/lib.rs":"7ec262618ecdbf3a40ee8eae20792d43f416a31ac1390329d4403bbbc11a4366"},"package":"e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/self_cell-0.10.3/Cargo.toml b/utshell-0.5.0/vendor/self_cell-0.10.3/Cargo.toml new file mode 100644 index 00000000..81853d99 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell-0.10.3/Cargo.toml @@ -0,0 +1,45 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "self_cell" +version = "0.10.3" +authors = ["Lukas Bergdoll "] +include = [ + "src/*.rs", + "Cargo.toml", + "README.md", + "LICENSE", +] +description = "Safe-to-use proc-macro-free self-referential structs in stable Rust." +documentation = "https://docs.rs/self_cell" +readme = "README.md" +keywords = [ + "lifetime", + "borrowing", + "self", + "reference", + "intrusive", +] +categories = [ + "rust-patterns", + "memory-management", +] +license = "Apache-2.0" +repository = "https://github.com/Voultapher/self_cell" + +[dependencies.new_self_cell] +version = "1" +package = "self_cell" + +[features] +old_rust = ["new_self_cell/old_rust"] diff --git a/utshell-0.5.0/vendor/self_cell-0.10.3/LICENSE b/utshell-0.5.0/vendor/self_cell-0.10.3/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell-0.10.3/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/self_cell-0.10.3/README.md b/utshell-0.5.0/vendor/self_cell-0.10.3/README.md new file mode 100644 index 00000000..5b9464c1 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell-0.10.3/README.md @@ -0,0 +1,18 @@ +# Note on version 0.10.3 + +This version of `self_cell` is a re-export of the `self_cell` version `1` +meant for backwards-compatibly allowing `0.10` users to get current and +future soundness fixes. If you are adding `self_cell` as a dependency, +please use an up-to-date version directly. + +## Authors + +* **Lukas Bergdoll** - *Initial work* - [Voultapher](https://github.com/Voultapher) + +See also the list of [contributors](https://github.com/Voultapher/self_cell/contributors) +who participated in this project. + +## License + +This project is licensed under the Apache License, Version 2.0 - +see the [LICENSE.md](LICENSE.md) file for details. diff --git a/utshell-0.5.0/vendor/self_cell-0.10.3/src/lib.rs b/utshell-0.5.0/vendor/self_cell-0.10.3/src/lib.rs new file mode 100644 index 00000000..6b8fa478 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell-0.10.3/src/lib.rs @@ -0,0 +1,162 @@ +//! # Note on version 0.10.3 +//! +//! This version of `self_cell` is a re-export of the `self_cell` version `1` +//! meant for backwards-compatibly allowing `0.10` users to get current and +//! future soundness fixes. If you are adding `self_cell` as a dependency, +//! please use an up-to-date version directly. +//! +//! # Overview +//! +//! `self_cell` provides one macro-rules macro: [`self_cell`][`self_cell!`]. With this macro +//! you can create self-referential structs that are safe-to-use in stable Rust, +//! without leaking the struct internal lifetime. +//! +//! In a nutshell, the API looks *roughly* like this: +//! +//! ```ignore +//! // User code: +//! +//! self_cell!( +//! struct NewStructName { +//! owner: Owner, +//! +//! #[covariant] +//! dependent: Dependent, +//! } +//! +//! impl {Debug} +//! ); +//! +//! // Generated by macro: +//! +//! struct NewStructName(...); +//! +//! impl NewStructName { +//! fn new( +//! owner: Owner, +//! dependent_builder: impl for<'a> FnOnce(&'a Owner) -> Dependent<'a> +//! ) -> NewStructName { ... } +//! fn borrow_owner<'a>(&'a self) -> &'a Owner { ... } +//! fn borrow_dependent<'a>(&'a self) -> &'a Dependent<'a> { ... } +//! } +//! +//! impl Debug for NewStructName { ... } +//! ``` +//! +//! Self-referential structs are currently not supported with safe vanilla Rust. +//! The only reasonable safe alternative is to have the user juggle 2 separate +//! data structures which is a mess. The library solution ouroboros is really +//! expensive to compile due to its use of procedural macros. +//! +//! This alternative is `no_std`, uses no proc-macros, some self contained +//! unsafe and works on stable Rust, and is miri tested. With a total of less +//! than 300 lines of implementation code, which consists mostly of type and +//! trait implementations, this crate aims to be a good minimal solution to the +//! problem of self-referential structs. +//! +//! It has undergone [community code +//! review](https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775) +//! from experienced Rust users. +//! +//! ### Fast compile times +//! +//! ```txt +//! $ rm -rf target && cargo +nightly build -Z timings +//! +//! Compiling self_cell v0.7.0 +//! Completed self_cell v0.7.0 in 0.2s +//! ``` +//! +//! Because it does **not** use proc-macros, and has 0 dependencies +//! compile-times are fast. +//! +//! Measurements done on a slow laptop. +//! +//! ### A motivating use case +//! +//! ```rust +//! use self_cell::self_cell; +//! +//! #[derive(Debug, Eq, PartialEq)] +//! struct Ast<'a>(pub Vec<&'a str>); +//! +//! self_cell!( +//! struct AstCell { +//! owner: String, +//! +//! #[covariant] +//! dependent: Ast, +//! } +//! +//! impl {Debug, Eq, PartialEq} +//! ); +//! +//! fn build_ast_cell(code: &str) -> AstCell { +//! // Create owning String on stack. +//! let pre_processed_code = code.trim().to_string(); +//! +//! // Move String into AstCell, then build Ast inplace. +//! AstCell::new( +//! pre_processed_code, +//! |code| Ast(code.split(' ').filter(|word| word.len() > 1).collect()) +//! ) +//! } +//! +//! fn main() { +//! let ast_cell = build_ast_cell("fox = cat + dog"); +//! +//! println!("ast_cell -> {:?}", &ast_cell); +//! println!("ast_cell.borrow_owner() -> {:?}", ast_cell.borrow_owner()); +//! println!("ast_cell.borrow_dependent().0[1] -> {:?}", ast_cell.borrow_dependent().0[1]); +//! } +//! ``` +//! +//! ```txt +//! $ cargo run +//! +//! ast_cell -> AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) } +//! ast_cell.borrow_owner() -> "fox = cat + dog" +//! ast_cell.borrow_dependent().0[1] -> "cat" +//! ``` +//! +//! There is no way in safe Rust to have an API like `build_ast_cell`, as soon +//! as `Ast` depends on stack variables like `pre_processed_code` you can't +//! return the value out of the function anymore. You could move the +//! pre-processing into the caller but that gets ugly quickly because you can't +//! encapsulate things anymore. Note this is a somewhat niche use case, +//! self-referential structs should only be used when there is no good +//! alternative. +//! +//! Under the hood, it heap allocates a struct which it initializes first by +//! moving the owner value to it and then using the reference to this now +//! Pin/Immovable owner to construct the dependent inplace next to it. This +//! makes it safe to move the generated SelfCell but you have to pay for the +//! heap allocation. +//! +//! See the documentation for [`self_cell`][`self_cell!`] to dive further into the details. +//! +//! Or take a look at the advanced examples: +//! - [Example how to handle dependent construction that can +//! fail](https://github.com/Voultapher/self_cell/tree/main/examples/fallible_dependent_construction) +//! +//! - [How to build a lazy AST with +//! self_cell](https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast) +//! +//! - [How to use an owner type with +//! lifetime](https://github.com/Voultapher/self_cell/tree/main/examples/owner_with_lifetime) +//! +//! ### Min required rustc version +//! +//! By default the minimum required rustc version is 1.51. +//! +//! There is an optional feature you can enable called "old_rust" that enables +//! support down to rustc version 1.36. However this requires polyfilling std +//! library functionality for older rustc with technically UB versions. Testing +//! does not show older rustc versions (ab)using this. Use at your own risk. +//! +//! The minimum versions are a best effor and may change with any new major +//! release. + +#![no_std] + +pub use new_self_cell::self_cell; diff --git a/utshell-0.5.0/vendor/self_cell/.cargo-checksum.json b/utshell-0.5.0/vendor/self_cell/.cargo-checksum.json new file mode 100644 index 00000000..0acf9a87 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"dcef444570988a80fad1f947889e1fd63a4a5e5c29bb5483b290319021919728","LICENSE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","README.md":"212bd1321e9db9669af44b685e747ff9f93f42c1682cddfabd850dc0e7e60d9f","src/lib.rs":"427399c835d1afca459451ecc96f85ba25fb3c1da919dc3700b9b376aa4a6cba","src/unsafe_self_cell.rs":"177d2c2756b2378fdb261ede6065cff16f8ab54245d4fec86943a0d6b004b492"},"package":"58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/self_cell/Cargo.toml b/utshell-0.5.0/vendor/self_cell/Cargo.toml new file mode 100644 index 00000000..1826dc9a --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell/Cargo.toml @@ -0,0 +1,48 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "self_cell" +version = "1.0.3" +authors = ["Lukas Bergdoll "] +include = [ + "src/*.rs", + "Cargo.toml", + "README.md", + "LICENSE", +] +description = "Safe-to-use proc-macro-free self-referential structs in stable Rust." +documentation = "https://docs.rs/self_cell" +readme = "README.md" +keywords = [ + "lifetime", + "borrowing", + "self", + "reference", + "intrusive", +] +categories = [ + "rust-patterns", + "memory-management", +] +license = "Apache-2.0" +repository = "https://github.com/Voultapher/self_cell" + +[dependencies.rustversion] +version = ">=1" +optional = true + +[dev-dependencies.once_cell] +version = "=1.1.0" + +[features] +old_rust = ["rustversion"] diff --git a/utshell-0.5.0/vendor/self_cell/LICENSE b/utshell-0.5.0/vendor/self_cell/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utshell-0.5.0/vendor/self_cell/README.md b/utshell-0.5.0/vendor/self_cell/README.md new file mode 100644 index 00000000..dc8e8078 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell/README.md @@ -0,0 +1,184 @@ +[github](https://github.com/Voultapher/self_cell) +[crates.io](https://crates.io/crates/self_cell) +[docs.rs](https://docs.rs/self_cell) + +# `self_cell!` + +Use the macro-rules macro: `self_cell!` to create safe-to-use self-referential +structs in stable Rust, without leaking the struct internal lifetime. + +In a nutshell, the API looks *roughly* like this: + +```rust +// User code: + +self_cell!( + struct NewStructName { + owner: Owner, + + #[covariant] + dependent: Dependent, + } + + impl {Debug} +); + +// Generated by macro: + +struct NewStructName(...); + +impl NewStructName { + fn new( + owner: Owner, + dependent_builder: impl for<'a> FnOnce(&'a Owner) -> Dependent<'a> + ) -> NewStructName { ... } + fn borrow_owner<'a>(&'a self) -> &'a Owner { ... } + fn borrow_dependent<'a>(&'a self) -> &'a Dependent<'a> { ... } +} + +impl Debug for NewStructName { ... } +``` + +Self-referential structs are currently not supported with safe vanilla Rust. The +only reasonable safe alternative is to expect the user to juggle 2 separate data +structures which is a mess. The library solution ouroboros is really expensive +to compile due to its use of procedural macros. + +This alternative is `no_std`, uses no proc-macros, some self contained unsafe +and works on stable Rust, and is miri tested. With a total of less than 300 +lines of implementation code, which consists mostly of type and trait +implementations, this crate aims to be a good minimal solution to the problem of +self-referential structs. + +It has undergone [community code review](https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775) +from experienced Rust users. + +### Fast compile times + +``` +$ rm -rf target && cargo +nightly build -Z timings + +Compiling self_cell v0.9.0 +Completed self_cell v0.9.0 in 0.2s +``` + +Because it does **not** use proc-macros, and has 0 dependencies compile-times +are fast. + +Measurements done on a slow laptop. + +### A motivating use case + +```rust +use self_cell::self_cell; + +#[derive(Debug, Eq, PartialEq)] +struct Ast<'a>(pub Vec<&'a str>); + +self_cell!( + struct AstCell { + owner: String, + + #[covariant] + dependent: Ast, + } + + impl {Debug, Eq, PartialEq} +); + +fn build_ast_cell(code: &str) -> AstCell { + // Create owning String on stack. + let pre_processed_code = code.trim().to_string(); + + // Move String into AstCell, then build Ast inplace. + AstCell::new( + pre_processed_code, + |code| Ast(code.split(' ').filter(|word| word.len() > 1).collect()) + ) +} + +fn main() { + let ast_cell = build_ast_cell("fox = cat + dog"); + + println!("ast_cell -> {:?}", &ast_cell); + println!("ast_cell.borrow_owner() -> {:?}", ast_cell.borrow_owner()); + println!("ast_cell.borrow_dependent().0[1] -> {:?}", ast_cell.borrow_dependent().0[1]); +} +``` + +``` +$ cargo run + +ast_cell -> AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) } +ast_cell.borrow_owner() -> "fox = cat + dog" +ast_cell.borrow_dependent().0[1] -> "cat" +``` + +There is no way in safe Rust to have an API like `build_ast_cell`, as soon as +`Ast` depends on stack variables like `pre_processed_code` you can't return the +value out of the function anymore. You could move the pre-processing into the +caller but that gets ugly quickly because you can't encapsulate things anymore. +Note this is a somewhat niche use case, self-referential structs should only be +used when there is no good alternative. + +Under the hood, it heap allocates a struct which it initializes first by moving +the owner value to it and then using the reference to this now Pin/Immovable +owner to construct the dependent inplace next to it. This makes it safe to move +the generated SelfCell but you have to pay for the heap allocation. + +See the documentation for a more in-depth API overview and advanced examples: +https://docs.rs/self_cell + +### Installing + +[See cargo docs](https://doc.rust-lang.org/cargo/guide/). + +## Running the tests + +``` +cargo test + +cargo miri test +``` + +### Related projects + +- [ouroboros](https://github.com/joshua-maros/ouroboros) +- [rental](https://github.com/jpernst/rental) | soundness issues (tests fail with recent miri versions) and [deprecated](https://github.com/jpernst/rental#warning-this-crate-is-no-longer-maintained-or-supported) +- [Schroedinger](https://github.com/dureuill/sc) | [soundness issues](https://github.com/dureuill/sc/issues/1) +- [owning_ref](https://github.com/Kimundi/owning-ref-rs) | [soundness issues](https://rustsec.org/advisories/RUSTSEC-2022-0040.html) and [seems unmaintained](https://github.com/Kimundi/owning-ref-rs/issues/81) +- [ghost-cell](https://github.com/matthieu-m/ghost-cell) +- [qcell](https://github.com/uazu/qcell/) +- [selfref](https://docs.rs/selfref) + +## Min required rustc version + +By default the minimum required rustc version is 1.51. + +There is an optional feature you can enable called "old_rust" that enables +support down to rustc version 1.36. However this requires polyfilling std +library functionality for older rustc with technically UB versions. Testing does +not show older rustc versions (ab)using this. Use at your own risk. + +The minimum versions are best-effort and may change with any new major release. + +## Contributing + +Please respect the [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) when contributing. + +## Versioning + +We use [SemVer](http://semver.org/) for versioning. For the versions available, +see the [tags on this repository](https://github.com/Voultapher/self_cell/tags). + +## Authors + +* **Lukas Bergdoll** - *Initial work* - [Voultapher](https://github.com/Voultapher) + +See also the list of [contributors](https://github.com/Voultapher/self_cell/contributors) +who participated in this project. + +## License + +This project is licensed under the Apache License, Version 2.0 - +see the [LICENSE.md](LICENSE.md) file for details. diff --git a/utshell-0.5.0/vendor/self_cell/src/lib.rs b/utshell-0.5.0/vendor/self_cell/src/lib.rs new file mode 100644 index 00000000..d020723c --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell/src/lib.rs @@ -0,0 +1,670 @@ +//! # Overview +//! +//! `self_cell` provides one macro-rules macro: [`self_cell`]. With this macro +//! you can create self-referential structs that are safe-to-use in stable Rust, +//! without leaking the struct internal lifetime. +//! +//! In a nutshell, the API looks *roughly* like this: +//! +//! ```ignore +//! // User code: +//! +//! self_cell!( +//! struct NewStructName { +//! owner: Owner, +//! +//! #[covariant] +//! dependent: Dependent, +//! } +//! +//! impl {Debug} +//! ); +//! +//! // Generated by macro: +//! +//! struct NewStructName(...); +//! +//! impl NewStructName { +//! fn new( +//! owner: Owner, +//! dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a Owner) -> Dependent<'a> +//! ) -> NewStructName { ... } +//! fn borrow_owner<'a>(&'a self) -> &'a Owner { ... } +//! fn borrow_dependent<'a>(&'a self) -> &'a Dependent<'a> { ... } +//! } +//! +//! impl Debug for NewStructName { ... } +//! ``` +//! +//! Self-referential structs are currently not supported with safe vanilla Rust. +//! The only reasonable safe alternative is to have the user juggle 2 separate +//! data structures which is a mess. The library solution ouroboros is really +//! expensive to compile due to its use of procedural macros. +//! +//! This alternative is `no_std`, uses no proc-macros, some self contained +//! unsafe and works on stable Rust, and is miri tested. With a total of less +//! than 300 lines of implementation code, which consists mostly of type and +//! trait implementations, this crate aims to be a good minimal solution to the +//! problem of self-referential structs. +//! +//! It has undergone [community code +//! review](https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775) +//! from experienced Rust users. +//! +//! ### Fast compile times +//! +//! ```txt +//! $ rm -rf target && cargo +nightly build -Z timings +//! +//! Compiling self_cell v0.7.0 +//! Completed self_cell v0.7.0 in 0.2s +//! ``` +//! +//! Because it does **not** use proc-macros, and has 0 dependencies +//! compile-times are fast. +//! +//! Measurements done on a slow laptop. +//! +//! ### A motivating use case +//! +//! ```rust +//! use self_cell::self_cell; +//! +//! #[derive(Debug, Eq, PartialEq)] +//! struct Ast<'a>(pub Vec<&'a str>); +//! +//! self_cell!( +//! struct AstCell { +//! owner: String, +//! +//! #[covariant] +//! dependent: Ast, +//! } +//! +//! impl {Debug, Eq, PartialEq} +//! ); +//! +//! fn build_ast_cell(code: &str) -> AstCell { +//! // Create owning String on stack. +//! let pre_processed_code = code.trim().to_string(); +//! +//! // Move String into AstCell, then build Ast inplace. +//! AstCell::new( +//! pre_processed_code, +//! |code| Ast(code.split(' ').filter(|word| word.len() > 1).collect()) +//! ) +//! } +//! +//! fn main() { +//! let ast_cell = build_ast_cell("fox = cat + dog"); +//! +//! println!("ast_cell -> {:?}", &ast_cell); +//! println!("ast_cell.borrow_owner() -> {:?}", ast_cell.borrow_owner()); +//! println!("ast_cell.borrow_dependent().0[1] -> {:?}", ast_cell.borrow_dependent().0[1]); +//! } +//! ``` +//! +//! ```txt +//! $ cargo run +//! +//! ast_cell -> AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) } +//! ast_cell.borrow_owner() -> "fox = cat + dog" +//! ast_cell.borrow_dependent().0[1] -> "cat" +//! ``` +//! +//! There is no way in safe Rust to have an API like `build_ast_cell`, as soon +//! as `Ast` depends on stack variables like `pre_processed_code` you can't +//! return the value out of the function anymore. You could move the +//! pre-processing into the caller but that gets ugly quickly because you can't +//! encapsulate things anymore. Note this is a somewhat niche use case, +//! self-referential structs should only be used when there is no good +//! alternative. +//! +//! Under the hood, it heap allocates a struct which it initializes first by +//! moving the owner value to it and then using the reference to this now +//! Pin/Immovable owner to construct the dependent inplace next to it. This +//! makes it safe to move the generated SelfCell but you have to pay for the +//! heap allocation. +//! +//! See the documentation for [`self_cell`] to dive further into the details. +//! +//! Or take a look at the advanced examples: +//! - [Example how to handle dependent construction that can +//! fail](https://github.com/Voultapher/self_cell/tree/main/examples/fallible_dependent_construction) +//! +//! - [How to build a lazy AST with +//! self_cell](https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast) +//! +//! - [How to use an owner type with +//! lifetime](https://github.com/Voultapher/self_cell/tree/main/examples/owner_with_lifetime) +//! +//! ### Min required rustc version +//! +//! By default the minimum required rustc version is 1.51. +//! +//! There is an optional feature you can enable called "old_rust" that enables +//! support down to rustc version 1.36. However this requires polyfilling std +//! library functionality for older rustc with technically UB versions. Testing +//! does not show older rustc versions (ab)using this. Use at your own risk. +//! +//! The minimum versions are a best effor and may change with any new major +//! release. + +#![no_std] + +#[doc(hidden)] +pub extern crate alloc; + +#[doc(hidden)] +pub mod unsafe_self_cell; + +/// This macro declares a new struct of `$StructName` and implements traits +/// based on `$AutomaticDerive`. +/// +/// ### Example: +/// +/// ```rust +/// use self_cell::self_cell; +/// +/// #[derive(Debug, Eq, PartialEq)] +/// struct Ast<'a>(Vec<&'a str>); +/// +/// self_cell!( +/// #[doc(hidden)] +/// struct PackedAstCell { +/// owner: String, +/// +/// #[covariant] +/// dependent: Ast, +/// } +/// +/// impl {Debug, PartialEq, Eq, Hash} +/// ); +/// ``` +/// +/// See the crate overview to get a get an overview and a motivating example. +/// +/// ### Generated API: +/// +/// The macro implements these constructors: +/// +/// ```ignore +/// fn new( +/// owner: $Owner, +/// dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a $Owner) -> $Dependent<'a> +/// ) -> Self +/// ``` +/// +/// ```ignore +/// fn try_new( +/// owner: $Owner, +/// dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a $Owner) -> Result<$Dependent<'a>, Err> +/// ) -> Result +/// ``` +/// +/// ```ignore +/// fn try_new_or_recover( +/// owner: $Owner, +/// dependent_builder: impl for<'a> ::core::ops::FnOnce(&'a $Owner) -> Result<$Dependent<'a>, Err> +/// ) -> Result +/// ``` +/// +/// The macro implements these methods: +/// +/// ```ignore +/// fn borrow_owner<'a>(&'a self) -> &'a $Owner +/// ``` +/// +/// ```ignore +/// // Only available if dependent is covariant. +/// fn borrow_dependent<'a>(&'a self) -> &'a $Dependent<'a> +/// ``` +/// +/// ```ignore +/// fn with_dependent<'outer_fn, Ret>( +/// &'outer_fn self, +/// func: impl for<'a> ::core::ops::FnOnce(&'a $Owner, &'outer_fn $Dependent<'a> +/// ) -> Ret) -> Ret +/// ``` +/// +/// ```ignore +/// fn with_dependent_mut<'outer_fn, Ret>( +/// &'outer_fn mut self, +/// func: impl for<'a> ::core::ops::FnOnce(&'a $Owner, &'outer_fn mut $Dependent<'a>) -> Ret +/// ) -> Ret +/// ``` +/// +/// ```ignore +/// fn into_owner(self) -> $Owner +/// ``` +/// +/// +/// ### Parameters: +/// +/// - `$Vis:vis struct $StructName:ident` Name of the struct that will be +/// declared, this needs to be unique for the relevant scope. Example: `struct +/// AstCell` or `pub struct AstCell`. `$Vis` can be used to mark the struct +/// and all functions implemented by the macro as public. +/// +/// `$(#[$StructMeta:meta])*` allows you specify further meta items for this +/// struct, eg. `#[doc(hidden)] struct AstCell`. +/// +/// - `$Owner:ty` Type of owner. This has to have a `'static` lifetime. Example: +/// `String`. +/// +/// - `$Dependent:ident` Name of the dependent type without specified lifetime. +/// This can't be a nested type name. As workaround either create a type alias +/// `type Dep<'a> = Option>;` or create a new-type `struct +/// Dep<'a>(Option>);`. Example: `Ast`. +/// +/// `$Covariance:ident` Marker declaring if `$Dependent` is +/// [covariant](https://doc.rust-lang.org/nightly/nomicon/subtyping.html). +/// Possible Values: +/// +/// * **covariant**: This generates the direct reference accessor function +/// `borrow_dependent`. This is only safe to do if this compiles `fn +/// _assert_covariance<'x: 'y, 'y>(x: &'y $Dependent<'x>) -> &'y $Dependent<'y> +/// {x}`. Otherwise you could choose a lifetime that is too short for types +/// with interior mutability like `Cell`, which can lead to UB in safe code. +/// Which would violate the promise of this library that it is safe-to-use. +/// If you accidentally mark a type that is not covariant as covariant, you +/// will get a compile time error. +/// +/// * **not_covariant**: This generates no additional code but you can use the +/// `with_dependent` function. See [How to build a lazy AST with +/// self_cell](https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast) +/// for a usage example. +/// +/// In both cases you can use the `with_dependent_mut` function to mutate the +/// dependent value. This is safe to do because notionally you are replacing +/// pointers to a value not the other way around. +/// +/// - `impl {$($AutomaticDerive:ident),*},` Optional comma separated list of +/// optional automatic trait implementations. Possible Values: +/// +/// * **Debug**: Prints the debug representation of owner and dependent. +/// Example: `AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", +/// "cat", "dog"]) }` +/// +/// * **PartialEq**: Logic `*self.borrow_owner() == *other.borrow_owner()`, +/// this assumes that `Dependent<'a>::From<&'a Owner>` is deterministic, so +/// that only comparing owner is enough. +/// +/// * **Eq**: Will implement the trait marker `Eq` for `$StructName`. Beware +/// if you select this `Eq` will be implemented regardless if `$Owner` +/// implements `Eq`, that's an unfortunate technical limitation. +/// +/// * **Hash**: Logic `self.borrow_owner().hash(state);`, this assumes that +/// `Dependent<'a>::From<&'a Owner>` is deterministic, so that only hashing +/// owner is enough. +/// +/// All `AutomaticDerive` are optional and you can implement you own version +/// of these traits. The declared struct is part of your module and you are +/// free to implement any trait in any way you want. Access to the unsafe +/// internals is only possible via unsafe functions, so you can't accidentally +/// use them in safe code. +/// +/// There is limited nested cell support. Eg, having an owner with non static +/// references. Eg `struct ChildCell<'a> { owner: &'a String, ...`. You can +/// use any lifetime name you want, except `_q` and only a single lifetime is +/// supported, and can only be used in the owner. Due to macro_rules +/// limitations, no `AutomaticDerive` are supported if an owner lifetime is +/// provided. +/// +#[macro_export] +macro_rules! self_cell { +( + $(#[$StructMeta:meta])* + $Vis:vis struct $StructName:ident $(<$OwnerLifetime:lifetime>)? { + owner: $Owner:ty, + + #[$Covariance:ident] + dependent: $Dependent:ident, + } + + $(impl {$($AutomaticDerive:ident),*})? +) => { + #[repr(transparent)] + $(#[$StructMeta])* + $Vis struct $StructName $(<$OwnerLifetime>)? { + unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell< + $StructName$(<$OwnerLifetime>)?, + $Owner, + $Dependent<'static> + >, + + $(owner_marker: $crate::_covariant_owner_marker!($Covariance, $OwnerLifetime) ,)? + } + + impl $(<$OwnerLifetime>)? $StructName $(<$OwnerLifetime>)? { + /// Constructs a new self-referential struct. + /// + /// The provided `owner` will be moved into a heap allocated box. + /// Followed by construction of the dependent value, by calling + /// `dependent_builder` with a shared reference to the owner that + /// remains valid for the lifetime of the constructed struct. + $Vis fn new( + owner: $Owner, + dependent_builder: impl for<'_q> ::core::ops::FnOnce(&'_q $Owner) -> $Dependent<'_q> + ) -> Self { + use ::core::ptr::NonNull; + + unsafe { + // All this has to happen here, because there is not good way + // of passing the appropriate logic into UnsafeSelfCell::new + // short of assuming Dependent<'static> is the same as + // Dependent<'_q>, which I'm not confident is safe. + + // For this API to be safe there has to be no safe way to + // capture additional references in `dependent_builder` and then + // return them as part of Dependent. Eg. it should be impossible + // to express: '_q should outlive 'x here `fn + // bad<'_q>(outside_ref: &'_q String) -> impl for<'x> ::core::ops::FnOnce(&'x + // Owner) -> Dependent<'x>`. + + type JoinedCell<'_q $(, $OwnerLifetime)?> = + $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'_q>>; + + let layout = $crate::alloc::alloc::Layout::new::(); + assert!(layout.size() != 0); + + let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap(); + + let mut joined_ptr = joined_void_ptr.cast::(); + + let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr()); + + // Move owner into newly allocated space. + owner_ptr.write(owner); + + // Drop guard that cleans up should building the dependent panic. + let drop_guard = + $crate::unsafe_self_cell::OwnerAndCellDropGuard::new(joined_ptr); + + // Initialize dependent with owner reference in final place. + dependent_ptr.write(dependent_builder(&*owner_ptr)); + ::core::mem::forget(drop_guard); + + Self { + unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell::new( + joined_void_ptr, + ), + $(owner_marker: $crate::_covariant_owner_marker_ctor!($OwnerLifetime) ,)? + } + } + } + + /// Tries to create a new structure with a given dependent builder. + /// + /// Consumes owner on error. + $Vis fn try_new( + owner: $Owner, + dependent_builder: + impl for<'_q> ::core::ops::FnOnce(&'_q $Owner) -> ::core::result::Result<$Dependent<'_q>, Err> + ) -> ::core::result::Result { + use ::core::ptr::NonNull; + + unsafe { + // See fn new for more explanation. + + type JoinedCell<'_q $(, $OwnerLifetime)?> = + $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'_q>>; + + let layout = $crate::alloc::alloc::Layout::new::(); + assert!(layout.size() != 0); + + let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap(); + + let mut joined_ptr = joined_void_ptr.cast::(); + + let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr()); + + // Move owner into newly allocated space. + owner_ptr.write(owner); + + // Drop guard that cleans up should building the dependent panic. + let mut drop_guard = + $crate::unsafe_self_cell::OwnerAndCellDropGuard::new(joined_ptr); + + match dependent_builder(&*owner_ptr) { + ::core::result::Result::Ok(dependent) => { + dependent_ptr.write(dependent); + ::core::mem::forget(drop_guard); + + ::core::result::Result::Ok(Self { + unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell::new( + joined_void_ptr, + ), + $(owner_marker: $crate::_covariant_owner_marker_ctor!($OwnerLifetime) ,)? + }) + } + ::core::result::Result::Err(err) => ::core::result::Result::Err(err) + } + } + } + + /// Tries to create a new structure with a given dependent builder. + /// + /// Returns owner on error. + $Vis fn try_new_or_recover( + owner: $Owner, + dependent_builder: + impl for<'_q> ::core::ops::FnOnce(&'_q $Owner) -> ::core::result::Result<$Dependent<'_q>, Err> + ) -> ::core::result::Result { + use ::core::ptr::NonNull; + + unsafe { + // See fn new for more explanation. + + type JoinedCell<'_q $(, $OwnerLifetime)?> = + $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'_q>>; + + let layout = $crate::alloc::alloc::Layout::new::(); + assert!(layout.size() != 0); + + let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap(); + + let mut joined_ptr = joined_void_ptr.cast::(); + + let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr()); + + // Move owner into newly allocated space. + owner_ptr.write(owner); + + // Drop guard that cleans up should building the dependent panic. + let mut drop_guard = + $crate::unsafe_self_cell::OwnerAndCellDropGuard::new(joined_ptr); + + match dependent_builder(&*owner_ptr) { + ::core::result::Result::Ok(dependent) => { + dependent_ptr.write(dependent); + ::core::mem::forget(drop_guard); + + ::core::result::Result::Ok(Self { + unsafe_self_cell: $crate::unsafe_self_cell::UnsafeSelfCell::new( + joined_void_ptr, + ), + $(owner_marker: $crate::_covariant_owner_marker_ctor!($OwnerLifetime) ,)? + }) + } + ::core::result::Result::Err(err) => { + // In contrast to into_owner ptr::read, here no dependent + // ever existed in this function and so we are sure its + // drop impl can't access owner after the read. + // And err can't return a reference to owner. + let owner_on_err = ::core::ptr::read(owner_ptr); + + // Allowing drop_guard to finish would let it double free owner. + // So we dealloc the JoinedCell here manually. + ::core::mem::forget(drop_guard); + $crate::alloc::alloc::dealloc(joined_void_ptr.as_ptr(), layout); + + ::core::result::Result::Err((owner_on_err, err)) + } + } + } + } + + /// Borrows owner. + $Vis fn borrow_owner<'_q>(&'_q self) -> &'_q $Owner { + unsafe { self.unsafe_self_cell.borrow_owner::<$Dependent<'_q>>() } + } + + /// Calls given closure `func` with a shared reference to dependent. + $Vis fn with_dependent<'outer_fn, Ret>( + &'outer_fn self, + func: impl for<'_q> ::core::ops::FnOnce(&'_q $Owner, &'outer_fn $Dependent<'_q> + ) -> Ret) -> Ret { + unsafe { + func( + self.unsafe_self_cell.borrow_owner::<$Dependent>(), + self.unsafe_self_cell.borrow_dependent() + ) + } + } + + /// Calls given closure `func` with an unique reference to dependent. + $Vis fn with_dependent_mut<'outer_fn, Ret>( + &'outer_fn mut self, + func: impl for<'_q> ::core::ops::FnOnce(&'_q $Owner, &'outer_fn mut $Dependent<'_q>) -> Ret + ) -> Ret { + let (owner, dependent) = unsafe { + self.unsafe_self_cell.borrow_mut() + }; + + func(owner, dependent) + } + + $crate::_covariant_access!($Covariance, $Vis, $Dependent); + + /// Consumes `self` and returns the the owner. + $Vis fn into_owner(self) -> $Owner { + // This is only safe to do with repr(transparent). + let unsafe_self_cell = unsafe { ::core::mem::transmute::< + Self, + $crate::unsafe_self_cell::UnsafeSelfCell< + $StructName$(<$OwnerLifetime>)?, + $Owner, + $Dependent<'static> + > + >(self) }; + + let owner = unsafe { unsafe_self_cell.into_owner::<$Dependent>() }; + + owner + } + } + + impl $(<$OwnerLifetime>)? Drop for $StructName $(<$OwnerLifetime>)? { + fn drop(&mut self) { + unsafe { + self.unsafe_self_cell.drop_joined::<$Dependent>(); + } + } + } + + // The user has to choose which traits can and should be automatically + // implemented for the cell. + $($( + $crate::_impl_automatic_derive!($AutomaticDerive, $StructName); + )*)* +}; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! _covariant_access { + (covariant, $Vis:vis, $Dependent:ident) => { + /// Borrows dependent. + $Vis fn borrow_dependent<'_q>(&'_q self) -> &'_q $Dependent<'_q> { + fn _assert_covariance<'x: 'y, 'y>(x: &'y $Dependent<'x>) -> &'y $Dependent<'y> { + // This function only compiles for covariant types. + x // Change the macro invocation to not_covariant. + } + + unsafe { self.unsafe_self_cell.borrow_dependent() } + } + }; + (not_covariant, $Vis:vis, $Dependent:ident) => { + // For types that are not covariant it's unsafe to allow + // returning direct references. + // For example a lifetime that is too short could be chosen: + // See https://github.com/Voultapher/self_cell/issues/5 + }; + ($x:ident, $Vis:vis, $Dependent:ident) => { + compile_error!("This macro only accepts `covariant` or `not_covariant`"); + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! _covariant_owner_marker { + (covariant, $OwnerLifetime:lifetime) => { + // Ensure that contravariant owners don't imply covariance + // over the dependent. See issue https://github.com/Voultapher/self_cell/issues/18 + ::core::marker::PhantomData<&$OwnerLifetime ()> + }; + (not_covariant, $OwnerLifetime:lifetime) => { + // See the discussion in https://github.com/Voultapher/self_cell/pull/29 + // + // If the dependent is non_covariant, mark the owner as invariant over its + // lifetime. Otherwise unsound use is possible. + ::core::marker::PhantomData &$OwnerLifetime ()> + }; + ($x:ident, $OwnerLifetime:lifetime) => { + compile_error!("This macro only accepts `covariant` or `not_covariant`"); + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! _covariant_owner_marker_ctor { + ($OwnerLifetime:lifetime) => { + // Helper to optionally expand into PhantomData for construction. + ::core::marker::PhantomData + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! _impl_automatic_derive { + (Debug, $StructName:ident) => { + impl ::core::fmt::Debug for $StructName { + fn fmt( + &self, + fmt: &mut ::core::fmt::Formatter, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + self.with_dependent(|owner, dependent| { + fmt.debug_struct(stringify!($StructName)) + .field("owner", owner) + .field("dependent", dependent) + .finish() + }) + } + } + }; + (PartialEq, $StructName:ident) => { + impl ::core::cmp::PartialEq for $StructName { + fn eq(&self, other: &Self) -> bool { + *self.borrow_owner() == *other.borrow_owner() + } + } + }; + (Eq, $StructName:ident) => { + // TODO this should only be allowed if owner is Eq. + impl ::core::cmp::Eq for $StructName {} + }; + (Hash, $StructName:ident) => { + impl ::core::hash::Hash for $StructName { + fn hash(&self, state: &mut H) { + self.borrow_owner().hash(state); + } + } + }; + ($x:ident, $StructName:ident) => { + compile_error!(concat!( + "No automatic trait impl for trait: ", + stringify!($x) + )); + }; +} diff --git a/utshell-0.5.0/vendor/self_cell/src/unsafe_self_cell.rs b/utshell-0.5.0/vendor/self_cell/src/unsafe_self_cell.rs new file mode 100644 index 00000000..8a429ba2 --- /dev/null +++ b/utshell-0.5.0/vendor/self_cell/src/unsafe_self_cell.rs @@ -0,0 +1,225 @@ +#![allow(clippy::needless_lifetimes)] + +use core::marker::PhantomData; +use core::mem; +use core::ptr::{drop_in_place, read, NonNull}; + +extern crate alloc; + +use alloc::alloc::{dealloc, Layout}; + +// Self referential structs are currently not supported with safe vanilla Rust. +// The only reasonable safe alternative is to expect the user to juggle 2 separate +// data structures which is a mess. The library solution rental is both no longer +// maintained and really heavy to compile. So begrudgingly I rolled my own version. +// These are some of the core invariants we require for this to be safe to use. +// +// 1. owner is initialized when UnsafeSelfCell is constructed. +// 2. owner is NEVER changed again. +// 3. The pointer to owner and dependent never changes, even when moved. +// 4. The only access to owner and dependent is as immutable reference. +// 5. owner lives longer than dependent. + +#[doc(hidden)] +pub struct JoinedCell { + pub owner: Owner, + pub dependent: Dependent, +} + +// Library controlled struct that marks all accesses as unsafe. +// Because the macro generated struct impl can be extended, could be unsafe. +#[doc(hidden)] +pub struct UnsafeSelfCell { + joined_void_ptr: NonNull, + + // ContainedIn is necessary for type safety since we don't fully + // prohibit access to the UnsafeSelfCell; swapping between different + // structs can be unsafe otherwise, see Issue #17. + contained_in_marker: PhantomData, + + owner_marker: PhantomData, + // DependentStatic is only used to correctly derive Send and Sync. + dependent_marker: PhantomData, +} + +impl UnsafeSelfCell { + pub unsafe fn new(joined_void_ptr: NonNull) -> Self { + Self { + joined_void_ptr, + contained_in_marker: PhantomData, + owner_marker: PhantomData, + dependent_marker: PhantomData, + } + } + + // Calling any of these *unsafe* functions with the wrong Dependent type is UB. + + pub unsafe fn borrow_owner<'a, Dependent>(&'a self) -> &'a Owner { + let joined_ptr = self.joined_void_ptr.cast::>(); + + &(*joined_ptr.as_ptr()).owner + } + + pub unsafe fn borrow_dependent<'a, Dependent>(&'a self) -> &'a Dependent { + let joined_ptr = self.joined_void_ptr.cast::>(); + + &(*joined_ptr.as_ptr()).dependent + } + + pub unsafe fn borrow_mut<'a, Dependent>(&'a mut self) -> (&'a Owner, &'a mut Dependent) { + let joined_ptr = self.joined_void_ptr.cast::>(); + + // This function used to return `&'a mut JoinedCell`. + // It now creates two references to the fields instead to avoid claiming mutable access + // to the whole `JoinedCell` (including the owner!) here. + ( + &(*joined_ptr.as_ptr()).owner, + &mut (*joined_ptr.as_ptr()).dependent, + ) + } + + // Any subsequent use of this struct other than dropping it is UB. + pub unsafe fn drop_joined(&mut self) { + let joined_ptr = self.joined_void_ptr.cast::>(); + + // Also used in case drop_in_place(...dependent) fails + let _guard = OwnerAndCellDropGuard { joined_ptr }; + + // IMPORTANT dependent must be dropped before owner. + // We don't want to rely on an implicit order of struct fields. + // So we drop the struct, field by field manually. + drop_in_place(&mut (*joined_ptr.as_ptr()).dependent); + + // Dropping owner + // and deallocating + // due to _guard at end of scope. + } + + pub unsafe fn into_owner(self) -> Owner { + let joined_ptr = self.joined_void_ptr.cast::>(); + + // In case drop_in_place(...dependent) fails + let drop_guard = OwnerAndCellDropGuard::new(joined_ptr); + + // Drop dependent + drop_in_place(&mut (*joined_ptr.as_ptr()).dependent); + + mem::forget(drop_guard); + + let owner_ptr: *const Owner = &(*joined_ptr.as_ptr()).owner; + + // Move owner out so it can be returned. + // Must not read before dropping dependent!! (Which happened above.) + let owner = read(owner_ptr); + + // Deallocate JoinedCell + let layout = Layout::new::>(); + dealloc(self.joined_void_ptr.as_ptr(), layout); + + owner + } +} + +unsafe impl Send + for UnsafeSelfCell +where + // Only derive Send if Owner and DependentStatic is also Send + Owner: Send, + DependentStatic: Send, +{ +} + +unsafe impl Sync + for UnsafeSelfCell +where + // Only derive Sync if Owner and DependentStatic is also Sync + Owner: Sync, + DependentStatic: Sync, +{ +} + +// This struct is used to safely deallocate only the owner if dependent +// construction fails. +// +// mem::forget it once it's no longer needed or dtor will be UB. +#[doc(hidden)] +pub struct OwnerAndCellDropGuard { + joined_ptr: NonNull>, +} + +impl OwnerAndCellDropGuard { + pub unsafe fn new(joined_ptr: NonNull>) -> Self { + Self { joined_ptr } + } +} + +impl Drop for OwnerAndCellDropGuard { + fn drop(&mut self) { + struct DeallocGuard { + ptr: *mut u8, + layout: Layout, + } + impl Drop for DeallocGuard { + fn drop(&mut self) { + unsafe { dealloc(self.ptr, self.layout) } + } + } + + // Deallocate even when the drop_in_place(...owner) panics + let _guard = DeallocGuard { + ptr: self.joined_ptr.as_ptr() as *mut u8, + layout: Layout::new::>(), + }; + + unsafe { + // We must only drop owner and the struct itself, + // The whole point of this drop guard is to clean up the partially + // initialized struct should building the dependent fail. + drop_in_place(&mut (*self.joined_ptr.as_ptr()).owner); + } + + // Deallocation happens at end of scope + } +} + +// Older versions of rust do not support addr_of_mut!. What we want to do here +// is to emulate the behavior of that macro by going (incorrectly) via a +// reference cast. Technically this is UB, but testing does not show the older +// compiler versions (ab)using this. For discussions about this behavior see +// https://github.com/Voultapher/self_cell/pull/31 and +// https://github.com/Voultapher/self_cell/issues/30 and +// https://github.com/Voultapher/self_cell/pull/33 +// +// Because of 'procedural macros cannot expand to macro definitions' +// we have wrap this in functions. +impl JoinedCell { + #[doc(hidden)] + #[cfg(not(feature = "old_rust"))] + pub unsafe fn _field_pointers(this: *mut Self) -> (*mut Owner, *mut Dependent) { + let owner_ptr = core::ptr::addr_of_mut!((*this).owner); + let dependent_ptr = core::ptr::addr_of_mut!((*this).dependent); + + (owner_ptr, dependent_ptr) + } + + #[doc(hidden)] + #[cfg(feature = "old_rust")] + #[rustversion::since(1.51)] + pub unsafe fn _field_pointers(this: *mut Self) -> (*mut Owner, *mut Dependent) { + let owner_ptr = core::ptr::addr_of_mut!((*this).owner); + let dependent_ptr = core::ptr::addr_of_mut!((*this).dependent); + + (owner_ptr, dependent_ptr) + } + + #[doc(hidden)] + #[cfg(feature = "old_rust")] + #[rustversion::before(1.51)] + pub unsafe fn _field_pointers(this: *mut Self) -> (*mut Owner, *mut Dependent) { + // See comment above, technically this is UB. + let owner_ptr = &mut (*this).owner as *mut Owner; + let dependent_ptr = &mut (*this).dependent as *mut Dependent; + + (owner_ptr, dependent_ptr) + } +} diff --git a/utshell-0.5.0/vendor/slab/.cargo-checksum.json b/utshell-0.5.0/vendor/slab/.cargo-checksum.json new file mode 100644 index 00000000..704fdd3b --- /dev/null +++ b/utshell-0.5.0/vendor/slab/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"4ab78a6c79fcce5c853fa02902dc20ab217a41582f2c9204c517da57606e3508","Cargo.toml":"cc4f904c3a853b1b5efe9c36dd973e86ae72094ae27398b7c04ff05606517061","LICENSE":"8ce0830173fdac609dfb4ea603fdc002c2f4af0dc9b1a005653f5da9cf534b18","README.md":"6e8d6d493aec6526593ae9b05e3b21d3f878c5816a94af9d372598e03406b35f","build.rs":"2c008232a3ae7c83c166f61c2942314717976776a4dba38e9063cd8e57a1b9bd","src/builder.rs":"87e629b1f9853d910389635b27a42391f1681cd5638d81e386215211e8b67847","src/lib.rs":"7030188777c9e1a1b1649cc434ebee62b324f1d4212b0982157205892bfb3b5b","src/serde.rs":"e58650a04644cb732119f50eefe6a3066104b5b41be7074e12525e05e2ad21b7","tests/serde.rs":"bb28112509dbb6949528802d05a1b1e34d2e5ff9d3ba5f62aa801cfb3de7a78e","tests/slab.rs":"83f597daf9430d68553738facfd1fd00d9d718888fc5f7dc082ed9eb08a3a18d"},"package":"8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/slab/CHANGELOG.md b/utshell-0.5.0/vendor/slab/CHANGELOG.md new file mode 100644 index 00000000..f46a7979 --- /dev/null +++ b/utshell-0.5.0/vendor/slab/CHANGELOG.md @@ -0,0 +1,54 @@ +# 0.4.9 (August 22, 2023) + +* Avoid reallocations in `Slab::clone_from` (#137) + +# 0.4.8 (January 20, 2023) + +* Fixed documentation about overflow (#124) +* Document panic in `get2_mut` (#131) +* Refactoring (#129, #132) + +# 0.4.7 (July 19, 2022) + +* Use `#[track_caller]` on Rust 1.46+ (#119) +* Make `Slab::new` const on Rust 1.39+ (#119) + +# 0.4.6 (April 2, 2022) + +* Add `Slab::vacant_key` (#114) +* Fix stacked borrows violation in `Slab::get2_unchecked_mut` (#115) + +# 0.4.5 (October 13, 2021) + +* Add alternate debug output for listing items in the slab (#108) +* Fix typo in debug output of IntoIter (#109) +* Impl 'Clone' for 'Iter' (#110) + +# 0.4.4 (August 06, 2021) + +* Fix panic in `FromIterator` impl (#102) +* Fix compatibility with older clippy versions (#104) +* Add `try_remove` method (#89) +* Implement `ExactSizeIterator` and `FusedIterator` for iterators (#92) + +# 0.4.3 (April 20, 2021) + +* Add no_std support for Rust 1.36 and above (#71). +* Add `get2_mut` and `get2_unchecked_mut` methods (#65). +* Make `shrink_to_fit()` remove trailing vacant entries (#62). +* Implement `FromIterator<(usize, T)>` (#62). +* Implement `IntoIterator` (#62). +* Provide `size_hint()` of the iterators (#62). +* Make all iterators reversible (#62). +* Add `key_of()` method (#61) +* Add `compact()` method (#60) +* Add support for serde (#85) + +# 0.4.2 (January 11, 2019) + +* Add `Slab::drain` (#56). + +# 0.4.1 (July 15, 2018) + +* Improve `reserve` and `reserve_exact` (#37). +* Implement `Default` for `Slab` (#43). diff --git a/utshell-0.5.0/vendor/slab/Cargo.toml b/utshell-0.5.0/vendor/slab/Cargo.toml new file mode 100644 index 00000000..461bb8fa --- /dev/null +++ b/utshell-0.5.0/vendor/slab/Cargo.toml @@ -0,0 +1,55 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +rust-version = "1.31" +name = "slab" +version = "0.4.9" +authors = ["Carl Lerche "] +exclude = ["/.*"] +description = "Pre-allocated storage for a uniform data type" +readme = "README.md" +keywords = [ + "slab", + "allocator", + "no_std", +] +categories = [ + "memory-management", + "data-structures", + "no-std", +] +license = "MIT" +repository = "https://github.com/tokio-rs/slab" + +[dependencies.serde] +version = "1.0.95" +features = ["alloc"] +optional = true +default-features = false + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.serde] +version = "1" +features = ["derive"] + +[dev-dependencies.serde_test] +version = "1" + +[build-dependencies.autocfg] +version = "1" + +[features] +default = ["std"] +std = [] diff --git a/utshell-0.5.0/vendor/slab/LICENSE b/utshell-0.5.0/vendor/slab/LICENSE new file mode 100644 index 00000000..819ce211 --- /dev/null +++ b/utshell-0.5.0/vendor/slab/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2019 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/slab/README.md b/utshell-0.5.0/vendor/slab/README.md new file mode 100644 index 00000000..42813893 --- /dev/null +++ b/utshell-0.5.0/vendor/slab/README.md @@ -0,0 +1,51 @@ +# Slab + +Pre-allocated storage for a uniform data type. + +[![Crates.io][crates-badge]][crates-url] +[![Build Status][ci-badge]][ci-url] + +[crates-badge]: https://img.shields.io/crates/v/slab +[crates-url]: https://crates.io/crates/slab +[ci-badge]: https://img.shields.io/github/actions/workflow/status/tokio-rs/slab/ci.yml?branch=master +[ci-url]: https://github.com/tokio-rs/slab/actions + +[Documentation](https://docs.rs/slab) + +## Usage + +To use `slab`, first add this to your `Cargo.toml`: + +```toml +[dependencies] +slab = "0.4" +``` + +Next, add this to your crate: + +```rust +use slab::Slab; + +let mut slab = Slab::new(); + +let hello = slab.insert("hello"); +let world = slab.insert("world"); + +assert_eq!(slab[hello], "hello"); +assert_eq!(slab[world], "world"); + +slab[world] = "earth"; +assert_eq!(slab[world], "earth"); +``` + +See [documentation](https://docs.rs/slab) for more details. + +## License + +This project is licensed under the [MIT license](LICENSE). + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `slab` by you, shall be licensed as MIT, without any additional +terms or conditions. diff --git a/utshell-0.5.0/vendor/slab/build.rs b/utshell-0.5.0/vendor/slab/build.rs new file mode 100644 index 00000000..b60351aa --- /dev/null +++ b/utshell-0.5.0/vendor/slab/build.rs @@ -0,0 +1,24 @@ +fn main() { + let cfg = match autocfg::AutoCfg::new() { + Ok(cfg) => cfg, + Err(e) => { + // If we couldn't detect the compiler version and features, just + // print a warning. This isn't a fatal error: we can still build + // Slab, we just can't enable cfgs automatically. + println!( + "cargo:warning=slab: failed to detect compiler features: {}", + e + ); + return; + } + }; + // Note that this is `no_`*, not `has_*`. This allows treating as the latest + // stable rustc is used when the build script doesn't run. This is useful + // for non-cargo build systems that don't run the build script. + if !cfg.probe_rustc_version(1, 39) { + println!("cargo:rustc-cfg=slab_no_const_vec_new"); + } + if !cfg.probe_rustc_version(1, 46) { + println!("cargo:rustc-cfg=slab_no_track_caller"); + } +} diff --git a/utshell-0.5.0/vendor/slab/src/builder.rs b/utshell-0.5.0/vendor/slab/src/builder.rs new file mode 100644 index 00000000..8e50a201 --- /dev/null +++ b/utshell-0.5.0/vendor/slab/src/builder.rs @@ -0,0 +1,63 @@ +use crate::{Entry, Slab}; + +// Building `Slab` from pairs (usize, T). +pub(crate) struct Builder { + slab: Slab, + vacant_list_broken: bool, + first_vacant_index: Option, +} + +impl Builder { + pub(crate) fn with_capacity(capacity: usize) -> Self { + Self { + slab: Slab::with_capacity(capacity), + vacant_list_broken: false, + first_vacant_index: None, + } + } + pub(crate) fn pair(&mut self, key: usize, value: T) { + let slab = &mut self.slab; + if key < slab.entries.len() { + // iterator is not sorted, might need to recreate vacant list + if let Entry::Vacant(_) = slab.entries[key] { + self.vacant_list_broken = true; + slab.len += 1; + } + // if an element with this key already exists, replace it. + // This is consistent with HashMap and BtreeMap + slab.entries[key] = Entry::Occupied(value); + } else { + if self.first_vacant_index.is_none() && slab.entries.len() < key { + self.first_vacant_index = Some(slab.entries.len()); + } + // insert holes as necessary + while slab.entries.len() < key { + // add the entry to the start of the vacant list + let next = slab.next; + slab.next = slab.entries.len(); + slab.entries.push(Entry::Vacant(next)); + } + slab.entries.push(Entry::Occupied(value)); + slab.len += 1; + } + } + + pub(crate) fn build(self) -> Slab { + let mut slab = self.slab; + if slab.len == slab.entries.len() { + // no vacant entries, so next might not have been updated + slab.next = slab.entries.len(); + } else if self.vacant_list_broken { + slab.recreate_vacant_list(); + } else if let Some(first_vacant_index) = self.first_vacant_index { + let next = slab.entries.len(); + match &mut slab.entries[first_vacant_index] { + Entry::Vacant(n) => *n = next, + _ => unreachable!(), + } + } else { + unreachable!() + } + slab + } +} diff --git a/utshell-0.5.0/vendor/slab/src/lib.rs b/utshell-0.5.0/vendor/slab/src/lib.rs new file mode 100644 index 00000000..7fc6f1aa --- /dev/null +++ b/utshell-0.5.0/vendor/slab/src/lib.rs @@ -0,0 +1,1589 @@ +#![cfg_attr(not(feature = "std"), no_std)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + unreachable_pub +)] +#![doc(test( + no_crate_inject, + attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) +))] + +//! Pre-allocated storage for a uniform data type. +//! +//! `Slab` provides pre-allocated storage for a single data type. If many values +//! of a single type are being allocated, it can be more efficient to +//! pre-allocate the necessary storage. Since the size of the type is uniform, +//! memory fragmentation can be avoided. Storing, clearing, and lookup +//! operations become very cheap. +//! +//! While `Slab` may look like other Rust collections, it is not intended to be +//! used as a general purpose collection. The primary difference between `Slab` +//! and `Vec` is that `Slab` returns the key when storing the value. +//! +//! It is important to note that keys may be reused. In other words, once a +//! value associated with a given key is removed from a slab, that key may be +//! returned from future calls to `insert`. +//! +//! # Examples +//! +//! Basic storing and retrieval. +//! +//! ``` +//! # use slab::*; +//! let mut slab = Slab::new(); +//! +//! let hello = slab.insert("hello"); +//! let world = slab.insert("world"); +//! +//! assert_eq!(slab[hello], "hello"); +//! assert_eq!(slab[world], "world"); +//! +//! slab[world] = "earth"; +//! assert_eq!(slab[world], "earth"); +//! ``` +//! +//! Sometimes it is useful to be able to associate the key with the value being +//! inserted in the slab. This can be done with the `vacant_entry` API as such: +//! +//! ``` +//! # use slab::*; +//! let mut slab = Slab::new(); +//! +//! let hello = { +//! let entry = slab.vacant_entry(); +//! let key = entry.key(); +//! +//! entry.insert((key, "hello")); +//! key +//! }; +//! +//! assert_eq!(hello, slab[hello].0); +//! assert_eq!("hello", slab[hello].1); +//! ``` +//! +//! It is generally a good idea to specify the desired capacity of a slab at +//! creation time. Note that `Slab` will grow the internal capacity when +//! attempting to insert a new value once the existing capacity has been reached. +//! To avoid this, add a check. +//! +//! ``` +//! # use slab::*; +//! let mut slab = Slab::with_capacity(1024); +//! +//! // ... use the slab +//! +//! if slab.len() == slab.capacity() { +//! panic!("slab full"); +//! } +//! +//! slab.insert("the slab is not at capacity yet"); +//! ``` +//! +//! # Capacity and reallocation +//! +//! The capacity of a slab is the amount of space allocated for any future +//! values that will be inserted in the slab. This is not to be confused with +//! the *length* of the slab, which specifies the number of actual values +//! currently being inserted. If a slab's length is equal to its capacity, the +//! next value inserted into the slab will require growing the slab by +//! reallocating. +//! +//! For example, a slab with capacity 10 and length 0 would be an empty slab +//! with space for 10 more stored values. Storing 10 or fewer elements into the +//! slab will not change its capacity or cause reallocation to occur. However, +//! if the slab length is increased to 11 (due to another `insert`), it will +//! have to reallocate, which can be slow. For this reason, it is recommended to +//! use [`Slab::with_capacity`] whenever possible to specify how many values the +//! slab is expected to store. +//! +//! # Implementation +//! +//! `Slab` is backed by a `Vec` of slots. Each slot is either occupied or +//! vacant. `Slab` maintains a stack of vacant slots using a linked list. To +//! find a vacant slot, the stack is popped. When a slot is released, it is +//! pushed onto the stack. +//! +//! If there are no more available slots in the stack, then `Vec::reserve(1)` is +//! called and a new slot is created. +//! +//! [`Slab::with_capacity`]: struct.Slab.html#with_capacity + +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(feature = "std")] +extern crate std as alloc; + +#[cfg(feature = "serde")] +mod serde; + +mod builder; + +use alloc::vec::{self, Vec}; +use core::iter::{self, FromIterator, FusedIterator}; +use core::{fmt, mem, ops, slice}; + +/// Pre-allocated storage for a uniform data type +/// +/// See the [module documentation] for more details. +/// +/// [module documentation]: index.html +pub struct Slab { + // Chunk of memory + entries: Vec>, + + // Number of Filled elements currently in the slab + len: usize, + + // Offset of the next available slot in the slab. Set to the slab's + // capacity when the slab is full. + next: usize, +} + +impl Clone for Slab +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + entries: self.entries.clone(), + len: self.len, + next: self.next, + } + } + + fn clone_from(&mut self, source: &Self) { + self.entries.clone_from(&source.entries); + self.len = source.len; + self.next = source.next; + } +} + +impl Default for Slab { + fn default() -> Self { + Slab::new() + } +} + +/// A handle to a vacant entry in a `Slab`. +/// +/// `VacantEntry` allows constructing values with the key that they will be +/// assigned to. +/// +/// # Examples +/// +/// ``` +/// # use slab::*; +/// let mut slab = Slab::new(); +/// +/// let hello = { +/// let entry = slab.vacant_entry(); +/// let key = entry.key(); +/// +/// entry.insert((key, "hello")); +/// key +/// }; +/// +/// assert_eq!(hello, slab[hello].0); +/// assert_eq!("hello", slab[hello].1); +/// ``` +#[derive(Debug)] +pub struct VacantEntry<'a, T> { + slab: &'a mut Slab, + key: usize, +} + +/// A consuming iterator over the values stored in a `Slab` +pub struct IntoIter { + entries: iter::Enumerate>>, + len: usize, +} + +/// An iterator over the values stored in the `Slab` +pub struct Iter<'a, T> { + entries: iter::Enumerate>>, + len: usize, +} + +impl<'a, T> Clone for Iter<'a, T> { + fn clone(&self) -> Self { + Self { + entries: self.entries.clone(), + len: self.len, + } + } +} + +/// A mutable iterator over the values stored in the `Slab` +pub struct IterMut<'a, T> { + entries: iter::Enumerate>>, + len: usize, +} + +/// A draining iterator for `Slab` +pub struct Drain<'a, T> { + inner: vec::Drain<'a, Entry>, + len: usize, +} + +#[derive(Clone)] +enum Entry { + Vacant(usize), + Occupied(T), +} + +impl Slab { + /// Construct a new, empty `Slab`. + /// + /// The function does not allocate and the returned slab will have no + /// capacity until `insert` is called or capacity is explicitly reserved. + /// + /// This is `const fn` on Rust 1.39+. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let slab: Slab = Slab::new(); + /// ``` + #[cfg(not(slab_no_const_vec_new))] + pub const fn new() -> Self { + Self { + entries: Vec::new(), + next: 0, + len: 0, + } + } + /// Construct a new, empty `Slab`. + /// + /// The function does not allocate and the returned slab will have no + /// capacity until `insert` is called or capacity is explicitly reserved. + /// + /// This is `const fn` on Rust 1.39+. + #[cfg(slab_no_const_vec_new)] + pub fn new() -> Self { + Self { + entries: Vec::new(), + next: 0, + len: 0, + } + } + + /// Construct a new, empty `Slab` with the specified capacity. + /// + /// The returned slab will be able to store exactly `capacity` without + /// reallocating. If `capacity` is 0, the slab will not allocate. + /// + /// It is important to note that this function does not specify the *length* + /// of the returned slab, but only the capacity. For an explanation of the + /// difference between length and capacity, see [Capacity and + /// reallocation](index.html#capacity-and-reallocation). + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::with_capacity(10); + /// + /// // The slab contains no values, even though it has capacity for more + /// assert_eq!(slab.len(), 0); + /// + /// // These are all done without reallocating... + /// for i in 0..10 { + /// slab.insert(i); + /// } + /// + /// // ...but this may make the slab reallocate + /// slab.insert(11); + /// ``` + pub fn with_capacity(capacity: usize) -> Slab { + Slab { + entries: Vec::with_capacity(capacity), + next: 0, + len: 0, + } + } + + /// Return the number of values the slab can store without reallocating. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let slab: Slab = Slab::with_capacity(10); + /// assert_eq!(slab.capacity(), 10); + /// ``` + pub fn capacity(&self) -> usize { + self.entries.capacity() + } + + /// Reserve capacity for at least `additional` more values to be stored + /// without allocating. + /// + /// `reserve` does nothing if the slab already has sufficient capacity for + /// `additional` more values. If more capacity is required, a new segment of + /// memory will be allocated and all existing values will be copied into it. + /// As such, if the slab is already very large, a call to `reserve` can end + /// up being expensive. + /// + /// The slab may reserve more than `additional` extra space in order to + /// avoid frequent reallocations. Use `reserve_exact` instead to guarantee + /// that only the requested space is allocated. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// slab.insert("hello"); + /// slab.reserve(10); + /// assert!(slab.capacity() >= 11); + /// ``` + pub fn reserve(&mut self, additional: usize) { + if self.capacity() - self.len >= additional { + return; + } + let need_add = additional - (self.entries.len() - self.len); + self.entries.reserve(need_add); + } + + /// Reserve the minimum capacity required to store exactly `additional` + /// more values. + /// + /// `reserve_exact` does nothing if the slab already has sufficient capacity + /// for `additional` more values. If more capacity is required, a new segment + /// of memory will be allocated and all existing values will be copied into + /// it. As such, if the slab is already very large, a call to `reserve` can + /// end up being expensive. + /// + /// Note that the allocator may give the slab more space than it requests. + /// Therefore capacity can not be relied upon to be precisely minimal. + /// Prefer `reserve` if future insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// slab.insert("hello"); + /// slab.reserve_exact(10); + /// assert!(slab.capacity() >= 11); + /// ``` + pub fn reserve_exact(&mut self, additional: usize) { + if self.capacity() - self.len >= additional { + return; + } + let need_add = additional - (self.entries.len() - self.len); + self.entries.reserve_exact(need_add); + } + + /// Shrink the capacity of the slab as much as possible without invalidating keys. + /// + /// Because values cannot be moved to a different index, the slab cannot + /// shrink past any stored values. + /// It will drop down as close as possible to the length but the allocator may + /// still inform the underlying vector that there is space for a few more elements. + /// + /// This function can take O(n) time even when the capacity cannot be reduced + /// or the allocation is shrunk in place. Repeated calls run in O(1) though. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::with_capacity(10); + /// + /// for i in 0..3 { + /// slab.insert(i); + /// } + /// + /// slab.shrink_to_fit(); + /// assert!(slab.capacity() >= 3 && slab.capacity() < 10); + /// ``` + /// + /// The slab cannot shrink past the last present value even if previous + /// values are removed: + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::with_capacity(10); + /// + /// for i in 0..4 { + /// slab.insert(i); + /// } + /// + /// slab.remove(0); + /// slab.remove(3); + /// + /// slab.shrink_to_fit(); + /// assert!(slab.capacity() >= 3 && slab.capacity() < 10); + /// ``` + pub fn shrink_to_fit(&mut self) { + // Remove all vacant entries after the last occupied one, so that + // the capacity can be reduced to what is actually needed. + // If the slab is empty the vector can simply be cleared, but that + // optimization would not affect time complexity when T: Drop. + let len_before = self.entries.len(); + while let Some(&Entry::Vacant(_)) = self.entries.last() { + self.entries.pop(); + } + + // Removing entries breaks the list of vacant entries, + // so it must be repaired + if self.entries.len() != len_before { + // Some vacant entries were removed, so the list now likely¹ + // either contains references to the removed entries, or has an + // invalid end marker. Fix this by recreating the list. + self.recreate_vacant_list(); + // ¹: If the removed entries formed the tail of the list, with the + // most recently popped entry being the head of them, (so that its + // index is now the end marker) the list is still valid. + // Checking for that unlikely scenario of this infrequently called + // is not worth the code complexity. + } + + self.entries.shrink_to_fit(); + } + + /// Iterate through all entries to recreate and repair the vacant list. + /// self.len must be correct and is not modified. + fn recreate_vacant_list(&mut self) { + self.next = self.entries.len(); + // We can stop once we've found all vacant entries + let mut remaining_vacant = self.entries.len() - self.len; + if remaining_vacant == 0 { + return; + } + + // Iterate in reverse order so that lower keys are at the start of + // the vacant list. This way future shrinks are more likely to be + // able to remove vacant entries. + for (i, entry) in self.entries.iter_mut().enumerate().rev() { + if let Entry::Vacant(ref mut next) = *entry { + *next = self.next; + self.next = i; + remaining_vacant -= 1; + if remaining_vacant == 0 { + break; + } + } + } + } + + /// Reduce the capacity as much as possible, changing the key for elements when necessary. + /// + /// To allow updating references to the elements which must be moved to a new key, + /// this function takes a closure which is called before moving each element. + /// The second and third parameters to the closure are the current key and + /// new key respectively. + /// In case changing the key for one element turns out not to be possible, + /// the move can be cancelled by returning `false` from the closure. + /// In that case no further attempts at relocating elements is made. + /// If the closure unwinds, the slab will be left in a consistent state, + /// but the value that the closure panicked on might be removed. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// + /// let mut slab = Slab::with_capacity(10); + /// let a = slab.insert('a'); + /// slab.insert('b'); + /// slab.insert('c'); + /// slab.remove(a); + /// slab.compact(|&mut value, from, to| { + /// assert_eq!((value, from, to), ('c', 2, 0)); + /// true + /// }); + /// assert!(slab.capacity() >= 2 && slab.capacity() < 10); + /// ``` + /// + /// The value is not moved when the closure returns `Err`: + /// + /// ``` + /// # use slab::*; + /// + /// let mut slab = Slab::with_capacity(100); + /// let a = slab.insert('a'); + /// let b = slab.insert('b'); + /// slab.remove(a); + /// slab.compact(|&mut value, from, to| false); + /// assert_eq!(slab.iter().next(), Some((b, &'b'))); + /// ``` + pub fn compact(&mut self, mut rekey: F) + where + F: FnMut(&mut T, usize, usize) -> bool, + { + // If the closure unwinds, we need to restore a valid list of vacant entries + struct CleanupGuard<'a, T> { + slab: &'a mut Slab, + decrement: bool, + } + impl Drop for CleanupGuard<'_, T> { + fn drop(&mut self) { + if self.decrement { + // Value was popped and not pushed back on + self.slab.len -= 1; + } + self.slab.recreate_vacant_list(); + } + } + let mut guard = CleanupGuard { + slab: self, + decrement: true, + }; + + let mut occupied_until = 0; + // While there are vacant entries + while guard.slab.entries.len() > guard.slab.len { + // Find a value that needs to be moved, + // by popping entries until we find an occupied one. + // (entries cannot be empty because 0 is not greater than anything) + if let Some(Entry::Occupied(mut value)) = guard.slab.entries.pop() { + // Found one, now find a vacant entry to move it to + while let Some(&Entry::Occupied(_)) = guard.slab.entries.get(occupied_until) { + occupied_until += 1; + } + // Let the caller try to update references to the key + if !rekey(&mut value, guard.slab.entries.len(), occupied_until) { + // Changing the key failed, so push the entry back on at its old index. + guard.slab.entries.push(Entry::Occupied(value)); + guard.decrement = false; + guard.slab.entries.shrink_to_fit(); + return; + // Guard drop handles cleanup + } + // Put the value in its new spot + guard.slab.entries[occupied_until] = Entry::Occupied(value); + // ... and mark it as occupied (this is optional) + occupied_until += 1; + } + } + guard.slab.next = guard.slab.len; + guard.slab.entries.shrink_to_fit(); + // Normal cleanup is not necessary + mem::forget(guard); + } + + /// Clear the slab of all values. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// for i in 0..3 { + /// slab.insert(i); + /// } + /// + /// slab.clear(); + /// assert!(slab.is_empty()); + /// ``` + pub fn clear(&mut self) { + self.entries.clear(); + self.len = 0; + self.next = 0; + } + + /// Return the number of stored values. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// for i in 0..3 { + /// slab.insert(i); + /// } + /// + /// assert_eq!(3, slab.len()); + /// ``` + pub fn len(&self) -> usize { + self.len + } + + /// Return `true` if there are no values stored in the slab. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// assert!(slab.is_empty()); + /// + /// slab.insert(1); + /// assert!(!slab.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.len == 0 + } + + /// Return an iterator over the slab. + /// + /// This function should generally be **avoided** as it is not efficient. + /// Iterators must iterate over every slot in the slab even if it is + /// vacant. As such, a slab with a capacity of 1 million but only one + /// stored value must still iterate the million slots. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// for i in 0..3 { + /// slab.insert(i); + /// } + /// + /// let mut iterator = slab.iter(); + /// + /// assert_eq!(iterator.next(), Some((0, &0))); + /// assert_eq!(iterator.next(), Some((1, &1))); + /// assert_eq!(iterator.next(), Some((2, &2))); + /// assert_eq!(iterator.next(), None); + /// ``` + pub fn iter(&self) -> Iter<'_, T> { + Iter { + entries: self.entries.iter().enumerate(), + len: self.len, + } + } + + /// Return an iterator that allows modifying each value. + /// + /// This function should generally be **avoided** as it is not efficient. + /// Iterators must iterate over every slot in the slab even if it is + /// vacant. As such, a slab with a capacity of 1 million but only one + /// stored value must still iterate the million slots. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let key1 = slab.insert(0); + /// let key2 = slab.insert(1); + /// + /// for (key, val) in slab.iter_mut() { + /// if key == key1 { + /// *val += 2; + /// } + /// } + /// + /// assert_eq!(slab[key1], 2); + /// assert_eq!(slab[key2], 1); + /// ``` + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + IterMut { + entries: self.entries.iter_mut().enumerate(), + len: self.len, + } + } + + /// Return a reference to the value associated with the given key. + /// + /// If the given key is not associated with a value, then `None` is + /// returned. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// let key = slab.insert("hello"); + /// + /// assert_eq!(slab.get(key), Some(&"hello")); + /// assert_eq!(slab.get(123), None); + /// ``` + pub fn get(&self, key: usize) -> Option<&T> { + match self.entries.get(key) { + Some(Entry::Occupied(val)) => Some(val), + _ => None, + } + } + + /// Return a mutable reference to the value associated with the given key. + /// + /// If the given key is not associated with a value, then `None` is + /// returned. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// let key = slab.insert("hello"); + /// + /// *slab.get_mut(key).unwrap() = "world"; + /// + /// assert_eq!(slab[key], "world"); + /// assert_eq!(slab.get_mut(123), None); + /// ``` + pub fn get_mut(&mut self, key: usize) -> Option<&mut T> { + match self.entries.get_mut(key) { + Some(&mut Entry::Occupied(ref mut val)) => Some(val), + _ => None, + } + } + + /// Return two mutable references to the values associated with the two + /// given keys simultaneously. + /// + /// If any one of the given keys is not associated with a value, then `None` + /// is returned. + /// + /// This function can be used to get two mutable references out of one slab, + /// so that you can manipulate both of them at the same time, eg. swap them. + /// + /// # Panics + /// + /// This function will panic if `key1` and `key2` are the same. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// use std::mem; + /// + /// let mut slab = Slab::new(); + /// let key1 = slab.insert(1); + /// let key2 = slab.insert(2); + /// let (value1, value2) = slab.get2_mut(key1, key2).unwrap(); + /// mem::swap(value1, value2); + /// assert_eq!(slab[key1], 2); + /// assert_eq!(slab[key2], 1); + /// ``` + pub fn get2_mut(&mut self, key1: usize, key2: usize) -> Option<(&mut T, &mut T)> { + assert!(key1 != key2); + + let (entry1, entry2); + + if key1 > key2 { + let (slice1, slice2) = self.entries.split_at_mut(key1); + entry1 = slice2.get_mut(0); + entry2 = slice1.get_mut(key2); + } else { + let (slice1, slice2) = self.entries.split_at_mut(key2); + entry1 = slice1.get_mut(key1); + entry2 = slice2.get_mut(0); + } + + match (entry1, entry2) { + ( + Some(&mut Entry::Occupied(ref mut val1)), + Some(&mut Entry::Occupied(ref mut val2)), + ) => Some((val1, val2)), + _ => None, + } + } + + /// Return a reference to the value associated with the given key without + /// performing bounds checking. + /// + /// For a safe alternative see [`get`](Slab::get). + /// + /// This function should be used with care. + /// + /// # Safety + /// + /// The key must be within bounds. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// let key = slab.insert(2); + /// + /// unsafe { + /// assert_eq!(slab.get_unchecked(key), &2); + /// } + /// ``` + pub unsafe fn get_unchecked(&self, key: usize) -> &T { + match *self.entries.get_unchecked(key) { + Entry::Occupied(ref val) => val, + _ => unreachable!(), + } + } + + /// Return a mutable reference to the value associated with the given key + /// without performing bounds checking. + /// + /// For a safe alternative see [`get_mut`](Slab::get_mut). + /// + /// This function should be used with care. + /// + /// # Safety + /// + /// The key must be within bounds. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// let key = slab.insert(2); + /// + /// unsafe { + /// let val = slab.get_unchecked_mut(key); + /// *val = 13; + /// } + /// + /// assert_eq!(slab[key], 13); + /// ``` + pub unsafe fn get_unchecked_mut(&mut self, key: usize) -> &mut T { + match *self.entries.get_unchecked_mut(key) { + Entry::Occupied(ref mut val) => val, + _ => unreachable!(), + } + } + + /// Return two mutable references to the values associated with the two + /// given keys simultaneously without performing bounds checking and safety + /// condition checking. + /// + /// For a safe alternative see [`get2_mut`](Slab::get2_mut). + /// + /// This function should be used with care. + /// + /// # Safety + /// + /// - Both keys must be within bounds. + /// - The condition `key1 != key2` must hold. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// use std::mem; + /// + /// let mut slab = Slab::new(); + /// let key1 = slab.insert(1); + /// let key2 = slab.insert(2); + /// let (value1, value2) = unsafe { slab.get2_unchecked_mut(key1, key2) }; + /// mem::swap(value1, value2); + /// assert_eq!(slab[key1], 2); + /// assert_eq!(slab[key2], 1); + /// ``` + pub unsafe fn get2_unchecked_mut(&mut self, key1: usize, key2: usize) -> (&mut T, &mut T) { + debug_assert_ne!(key1, key2); + let ptr = self.entries.as_mut_ptr(); + let ptr1 = ptr.add(key1); + let ptr2 = ptr.add(key2); + match (&mut *ptr1, &mut *ptr2) { + (&mut Entry::Occupied(ref mut val1), &mut Entry::Occupied(ref mut val2)) => { + (val1, val2) + } + _ => unreachable!(), + } + } + + /// Get the key for an element in the slab. + /// + /// The reference must point to an element owned by the slab. + /// Otherwise this function will panic. + /// This is a constant-time operation because the key can be calculated + /// from the reference with pointer arithmetic. + /// + /// # Panics + /// + /// This function will panic if the reference does not point to an element + /// of the slab. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// + /// let mut slab = Slab::new(); + /// let key = slab.insert(String::from("foo")); + /// let value = &slab[key]; + /// assert_eq!(slab.key_of(value), key); + /// ``` + /// + /// Values are not compared, so passing a reference to a different location + /// will result in a panic: + /// + /// ```should_panic + /// # use slab::*; + /// + /// let mut slab = Slab::new(); + /// let key = slab.insert(0); + /// let bad = &0; + /// slab.key_of(bad); // this will panic + /// unreachable!(); + /// ``` + #[cfg_attr(not(slab_no_track_caller), track_caller)] + pub fn key_of(&self, present_element: &T) -> usize { + let element_ptr = present_element as *const T as usize; + let base_ptr = self.entries.as_ptr() as usize; + // Use wrapping subtraction in case the reference is bad + let byte_offset = element_ptr.wrapping_sub(base_ptr); + // The division rounds away any offset of T inside Entry + // The size of Entry is never zero even if T is due to Vacant(usize) + let key = byte_offset / mem::size_of::>(); + // Prevent returning unspecified (but out of bounds) values + if key >= self.entries.len() { + panic!("The reference points to a value outside this slab"); + } + // The reference cannot point to a vacant entry, because then it would not be valid + key + } + + /// Insert a value in the slab, returning key assigned to the value. + /// + /// The returned key can later be used to retrieve or remove the value using indexed + /// lookup and `remove`. Additional capacity is allocated if needed. See + /// [Capacity and reallocation](index.html#capacity-and-reallocation). + /// + /// # Panics + /// + /// Panics if the new storage in the vector exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// let key = slab.insert("hello"); + /// assert_eq!(slab[key], "hello"); + /// ``` + pub fn insert(&mut self, val: T) -> usize { + let key = self.next; + + self.insert_at(key, val); + + key + } + + /// Returns the key of the next vacant entry. + /// + /// This function returns the key of the vacant entry which will be used + /// for the next insertion. This is equivalent to + /// `slab.vacant_entry().key()`, but it doesn't require mutable access. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// assert_eq!(slab.vacant_key(), 0); + /// + /// slab.insert(0); + /// assert_eq!(slab.vacant_key(), 1); + /// + /// slab.insert(1); + /// slab.remove(0); + /// assert_eq!(slab.vacant_key(), 0); + /// ``` + pub fn vacant_key(&self) -> usize { + self.next + } + + /// Return a handle to a vacant entry allowing for further manipulation. + /// + /// This function is useful when creating values that must contain their + /// slab key. The returned `VacantEntry` reserves a slot in the slab and is + /// able to query the associated key. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let hello = { + /// let entry = slab.vacant_entry(); + /// let key = entry.key(); + /// + /// entry.insert((key, "hello")); + /// key + /// }; + /// + /// assert_eq!(hello, slab[hello].0); + /// assert_eq!("hello", slab[hello].1); + /// ``` + pub fn vacant_entry(&mut self) -> VacantEntry<'_, T> { + VacantEntry { + key: self.next, + slab: self, + } + } + + fn insert_at(&mut self, key: usize, val: T) { + self.len += 1; + + if key == self.entries.len() { + self.entries.push(Entry::Occupied(val)); + self.next = key + 1; + } else { + self.next = match self.entries.get(key) { + Some(&Entry::Vacant(next)) => next, + _ => unreachable!(), + }; + self.entries[key] = Entry::Occupied(val); + } + } + + /// Tries to remove the value associated with the given key, + /// returning the value if the key existed. + /// + /// The key is then released and may be associated with future stored + /// values. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let hello = slab.insert("hello"); + /// + /// assert_eq!(slab.try_remove(hello), Some("hello")); + /// assert!(!slab.contains(hello)); + /// ``` + pub fn try_remove(&mut self, key: usize) -> Option { + if let Some(entry) = self.entries.get_mut(key) { + // Swap the entry at the provided value + let prev = mem::replace(entry, Entry::Vacant(self.next)); + + match prev { + Entry::Occupied(val) => { + self.len -= 1; + self.next = key; + return val.into(); + } + _ => { + // Woops, the entry is actually vacant, restore the state + *entry = prev; + } + } + } + None + } + + /// Remove and return the value associated with the given key. + /// + /// The key is then released and may be associated with future stored + /// values. + /// + /// # Panics + /// + /// Panics if `key` is not associated with a value. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let hello = slab.insert("hello"); + /// + /// assert_eq!(slab.remove(hello), "hello"); + /// assert!(!slab.contains(hello)); + /// ``` + #[cfg_attr(not(slab_no_track_caller), track_caller)] + pub fn remove(&mut self, key: usize) -> T { + self.try_remove(key).expect("invalid key") + } + + /// Return `true` if a value is associated with the given key. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let hello = slab.insert("hello"); + /// assert!(slab.contains(hello)); + /// + /// slab.remove(hello); + /// + /// assert!(!slab.contains(hello)); + /// ``` + pub fn contains(&self, key: usize) -> bool { + match self.entries.get(key) { + Some(&Entry::Occupied(_)) => true, + _ => false, + } + } + + /// Retain only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` such that `f(usize, &mut e)` + /// returns false. This method operates in place and preserves the key + /// associated with the retained values. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let k1 = slab.insert(0); + /// let k2 = slab.insert(1); + /// let k3 = slab.insert(2); + /// + /// slab.retain(|key, val| key == k1 || *val == 1); + /// + /// assert!(slab.contains(k1)); + /// assert!(slab.contains(k2)); + /// assert!(!slab.contains(k3)); + /// + /// assert_eq!(2, slab.len()); + /// ``` + pub fn retain(&mut self, mut f: F) + where + F: FnMut(usize, &mut T) -> bool, + { + for i in 0..self.entries.len() { + let keep = match self.entries[i] { + Entry::Occupied(ref mut v) => f(i, v), + _ => true, + }; + + if !keep { + self.remove(i); + } + } + } + + /// Return a draining iterator that removes all elements from the slab and + /// yields the removed items. + /// + /// Note: Elements are removed even if the iterator is only partially + /// consumed or not consumed at all. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let _ = slab.insert(0); + /// let _ = slab.insert(1); + /// let _ = slab.insert(2); + /// + /// { + /// let mut drain = slab.drain(); + /// + /// assert_eq!(Some(0), drain.next()); + /// assert_eq!(Some(1), drain.next()); + /// assert_eq!(Some(2), drain.next()); + /// assert_eq!(None, drain.next()); + /// } + /// + /// assert!(slab.is_empty()); + /// ``` + pub fn drain(&mut self) -> Drain<'_, T> { + let old_len = self.len; + self.len = 0; + self.next = 0; + Drain { + inner: self.entries.drain(..), + len: old_len, + } + } +} + +impl ops::Index for Slab { + type Output = T; + + #[cfg_attr(not(slab_no_track_caller), track_caller)] + fn index(&self, key: usize) -> &T { + match self.entries.get(key) { + Some(Entry::Occupied(v)) => v, + _ => panic!("invalid key"), + } + } +} + +impl ops::IndexMut for Slab { + #[cfg_attr(not(slab_no_track_caller), track_caller)] + fn index_mut(&mut self, key: usize) -> &mut T { + match self.entries.get_mut(key) { + Some(&mut Entry::Occupied(ref mut v)) => v, + _ => panic!("invalid key"), + } + } +} + +impl IntoIterator for Slab { + type Item = (usize, T); + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter { + entries: self.entries.into_iter().enumerate(), + len: self.len, + } + } +} + +impl<'a, T> IntoIterator for &'a Slab { + type Item = (usize, &'a T); + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl<'a, T> IntoIterator for &'a mut Slab { + type Item = (usize, &'a mut T); + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +/// Create a slab from an iterator of key-value pairs. +/// +/// If the iterator produces duplicate keys, the previous value is replaced with the later one. +/// The keys does not need to be sorted beforehand, and this function always +/// takes O(n) time. +/// Note that the returned slab will use space proportional to the largest key, +/// so don't use `Slab` with untrusted keys. +/// +/// # Examples +/// +/// ``` +/// # use slab::*; +/// +/// let vec = vec![(2,'a'), (6,'b'), (7,'c')]; +/// let slab = vec.into_iter().collect::>(); +/// assert_eq!(slab.len(), 3); +/// assert!(slab.capacity() >= 8); +/// assert_eq!(slab[2], 'a'); +/// ``` +/// +/// With duplicate and unsorted keys: +/// +/// ``` +/// # use slab::*; +/// +/// let vec = vec![(20,'a'), (10,'b'), (11,'c'), (10,'d')]; +/// let slab = vec.into_iter().collect::>(); +/// assert_eq!(slab.len(), 3); +/// assert_eq!(slab[10], 'd'); +/// ``` +impl FromIterator<(usize, T)> for Slab { + fn from_iter(iterable: I) -> Self + where + I: IntoIterator, + { + let iterator = iterable.into_iter(); + let mut builder = builder::Builder::with_capacity(iterator.size_hint().0); + + for (key, value) in iterator { + builder.pair(key, value) + } + builder.build() + } +} + +impl fmt::Debug for Slab +where + T: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + if fmt.alternate() { + fmt.debug_map().entries(self.iter()).finish() + } else { + fmt.debug_struct("Slab") + .field("len", &self.len) + .field("cap", &self.capacity()) + .finish() + } + } +} + +impl fmt::Debug for IntoIter +where + T: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("IntoIter") + .field("remaining", &self.len) + .finish() + } +} + +impl fmt::Debug for Iter<'_, T> +where + T: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Iter") + .field("remaining", &self.len) + .finish() + } +} + +impl fmt::Debug for IterMut<'_, T> +where + T: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("IterMut") + .field("remaining", &self.len) + .finish() + } +} + +impl fmt::Debug for Drain<'_, T> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Drain").finish() + } +} + +// ===== VacantEntry ===== + +impl<'a, T> VacantEntry<'a, T> { + /// Insert a value in the entry, returning a mutable reference to the value. + /// + /// To get the key associated with the value, use `key` prior to calling + /// `insert`. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let hello = { + /// let entry = slab.vacant_entry(); + /// let key = entry.key(); + /// + /// entry.insert((key, "hello")); + /// key + /// }; + /// + /// assert_eq!(hello, slab[hello].0); + /// assert_eq!("hello", slab[hello].1); + /// ``` + pub fn insert(self, val: T) -> &'a mut T { + self.slab.insert_at(self.key, val); + + match self.slab.entries.get_mut(self.key) { + Some(&mut Entry::Occupied(ref mut v)) => v, + _ => unreachable!(), + } + } + + /// Return the key associated with this entry. + /// + /// A value stored in this entry will be associated with this key. + /// + /// # Examples + /// + /// ``` + /// # use slab::*; + /// let mut slab = Slab::new(); + /// + /// let hello = { + /// let entry = slab.vacant_entry(); + /// let key = entry.key(); + /// + /// entry.insert((key, "hello")); + /// key + /// }; + /// + /// assert_eq!(hello, slab[hello].0); + /// assert_eq!("hello", slab[hello].1); + /// ``` + pub fn key(&self) -> usize { + self.key + } +} + +// ===== IntoIter ===== + +impl Iterator for IntoIter { + type Item = (usize, T); + + fn next(&mut self) -> Option { + for (key, entry) in &mut self.entries { + if let Entry::Occupied(v) = entry { + self.len -= 1; + return Some((key, v)); + } + } + + debug_assert_eq!(self.len, 0); + None + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl DoubleEndedIterator for IntoIter { + fn next_back(&mut self) -> Option { + while let Some((key, entry)) = self.entries.next_back() { + if let Entry::Occupied(v) = entry { + self.len -= 1; + return Some((key, v)); + } + } + + debug_assert_eq!(self.len, 0); + None + } +} + +impl ExactSizeIterator for IntoIter { + fn len(&self) -> usize { + self.len + } +} + +impl FusedIterator for IntoIter {} + +// ===== Iter ===== + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = (usize, &'a T); + + fn next(&mut self) -> Option { + for (key, entry) in &mut self.entries { + if let Entry::Occupied(ref v) = *entry { + self.len -= 1; + return Some((key, v)); + } + } + + debug_assert_eq!(self.len, 0); + None + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl DoubleEndedIterator for Iter<'_, T> { + fn next_back(&mut self) -> Option { + while let Some((key, entry)) = self.entries.next_back() { + if let Entry::Occupied(ref v) = *entry { + self.len -= 1; + return Some((key, v)); + } + } + + debug_assert_eq!(self.len, 0); + None + } +} + +impl ExactSizeIterator for Iter<'_, T> { + fn len(&self) -> usize { + self.len + } +} + +impl FusedIterator for Iter<'_, T> {} + +// ===== IterMut ===== + +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = (usize, &'a mut T); + + fn next(&mut self) -> Option { + for (key, entry) in &mut self.entries { + if let Entry::Occupied(ref mut v) = *entry { + self.len -= 1; + return Some((key, v)); + } + } + + debug_assert_eq!(self.len, 0); + None + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl DoubleEndedIterator for IterMut<'_, T> { + fn next_back(&mut self) -> Option { + while let Some((key, entry)) = self.entries.next_back() { + if let Entry::Occupied(ref mut v) = *entry { + self.len -= 1; + return Some((key, v)); + } + } + + debug_assert_eq!(self.len, 0); + None + } +} + +impl ExactSizeIterator for IterMut<'_, T> { + fn len(&self) -> usize { + self.len + } +} + +impl FusedIterator for IterMut<'_, T> {} + +// ===== Drain ===== + +impl Iterator for Drain<'_, T> { + type Item = T; + + fn next(&mut self) -> Option { + for entry in &mut self.inner { + if let Entry::Occupied(v) = entry { + self.len -= 1; + return Some(v); + } + } + + debug_assert_eq!(self.len, 0); + None + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl DoubleEndedIterator for Drain<'_, T> { + fn next_back(&mut self) -> Option { + while let Some(entry) = self.inner.next_back() { + if let Entry::Occupied(v) = entry { + self.len -= 1; + return Some(v); + } + } + + debug_assert_eq!(self.len, 0); + None + } +} + +impl ExactSizeIterator for Drain<'_, T> { + fn len(&self) -> usize { + self.len + } +} + +impl FusedIterator for Drain<'_, T> {} diff --git a/utshell-0.5.0/vendor/slab/src/serde.rs b/utshell-0.5.0/vendor/slab/src/serde.rs new file mode 100644 index 00000000..894d59c1 --- /dev/null +++ b/utshell-0.5.0/vendor/slab/src/serde.rs @@ -0,0 +1,62 @@ +use core::fmt; +use core::marker::PhantomData; + +use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeMap, Serializer}; + +use super::{builder::Builder, Slab}; + +impl Serialize for Slab +where + T: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map_serializer = serializer.serialize_map(Some(self.len()))?; + for (key, value) in self { + map_serializer.serialize_key(&key)?; + map_serializer.serialize_value(value)?; + } + map_serializer.end() + } +} + +struct SlabVisitor(PhantomData); + +impl<'de, T> Visitor<'de> for SlabVisitor +where + T: Deserialize<'de>, +{ + type Value = Slab; + + fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "a map") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut builder = Builder::with_capacity(map.size_hint().unwrap_or(0)); + + while let Some((key, value)) = map.next_entry()? { + builder.pair(key, value) + } + + Ok(builder.build()) + } +} + +impl<'de, T> Deserialize<'de> for Slab +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_map(SlabVisitor(PhantomData)) + } +} diff --git a/utshell-0.5.0/vendor/slab/tests/serde.rs b/utshell-0.5.0/vendor/slab/tests/serde.rs new file mode 100644 index 00000000..1d4a204e --- /dev/null +++ b/utshell-0.5.0/vendor/slab/tests/serde.rs @@ -0,0 +1,49 @@ +#![cfg(feature = "serde")] +#![warn(rust_2018_idioms)] + +use serde::{Deserialize, Serialize}; +use serde_test::{assert_tokens, Token}; +use slab::Slab; + +#[derive(Debug, Serialize, Deserialize)] +#[serde(transparent)] +struct SlabPartialEq(Slab); + +impl PartialEq for SlabPartialEq { + fn eq(&self, other: &Self) -> bool { + self.0.len() == other.0.len() + && self + .0 + .iter() + .zip(other.0.iter()) + .all(|(this, other)| this.0 == other.0 && this.1 == other.1) + } +} + +#[test] +fn test_serde_empty() { + let slab = Slab::::new(); + assert_tokens( + &SlabPartialEq(slab), + &[Token::Map { len: Some(0) }, Token::MapEnd], + ); +} + +#[test] +fn test_serde() { + let vec = vec![(1, 2), (3, 4), (5, 6)]; + let slab: Slab<_> = vec.iter().cloned().collect(); + assert_tokens( + &SlabPartialEq(slab), + &[ + Token::Map { len: Some(3) }, + Token::U64(1), + Token::I32(2), + Token::U64(3), + Token::I32(4), + Token::U64(5), + Token::I32(6), + Token::MapEnd, + ], + ); +} diff --git a/utshell-0.5.0/vendor/slab/tests/slab.rs b/utshell-0.5.0/vendor/slab/tests/slab.rs new file mode 100644 index 00000000..4799c1dd --- /dev/null +++ b/utshell-0.5.0/vendor/slab/tests/slab.rs @@ -0,0 +1,733 @@ +#![warn(rust_2018_idioms)] + +use slab::*; + +use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; + +#[test] +fn insert_get_remove_one() { + let mut slab = Slab::new(); + assert!(slab.is_empty()); + + let key = slab.insert(10); + + assert_eq!(slab[key], 10); + assert_eq!(slab.get(key), Some(&10)); + assert!(!slab.is_empty()); + assert!(slab.contains(key)); + + assert_eq!(slab.remove(key), 10); + assert!(!slab.contains(key)); + assert!(slab.get(key).is_none()); +} + +#[test] +fn insert_get_many() { + let mut slab = Slab::with_capacity(10); + + for i in 0..10 { + let key = slab.insert(i + 10); + assert_eq!(slab[key], i + 10); + } + + assert_eq!(slab.capacity(), 10); + + // Storing another one grows the slab + let key = slab.insert(20); + assert_eq!(slab[key], 20); + + // Capacity grows by 2x + assert_eq!(slab.capacity(), 20); +} + +#[test] +fn insert_get_remove_many() { + let mut slab = Slab::with_capacity(10); + let mut keys = vec![]; + + for i in 0..10 { + for j in 0..10 { + let val = (i * 10) + j; + + let key = slab.insert(val); + keys.push((key, val)); + assert_eq!(slab[key], val); + } + + for (key, val) in keys.drain(..) { + assert_eq!(val, slab.remove(key)); + } + } + + assert_eq!(10, slab.capacity()); +} + +#[test] +fn insert_with_vacant_entry() { + let mut slab = Slab::with_capacity(1); + let key; + + { + let entry = slab.vacant_entry(); + key = entry.key(); + entry.insert(123); + } + + assert_eq!(123, slab[key]); +} + +#[test] +fn get_vacant_entry_without_using() { + let mut slab = Slab::::with_capacity(1); + let key = slab.vacant_entry().key(); + assert_eq!(key, slab.vacant_entry().key()); +} + +#[test] +#[should_panic(expected = "invalid key")] +fn invalid_get_panics() { + let slab = Slab::::with_capacity(1); + let _ = &slab[0]; +} + +#[test] +#[should_panic(expected = "invalid key")] +fn invalid_get_mut_panics() { + let mut slab = Slab::::new(); + let _ = &mut slab[0]; +} + +#[test] +#[should_panic(expected = "invalid key")] +fn double_remove_panics() { + let mut slab = Slab::::with_capacity(1); + let key = slab.insert(123); + slab.remove(key); + slab.remove(key); +} + +#[test] +#[should_panic(expected = "invalid key")] +fn invalid_remove_panics() { + let mut slab = Slab::::with_capacity(1); + slab.remove(0); +} + +#[test] +fn slab_get_mut() { + let mut slab = Slab::new(); + let key = slab.insert(1); + + slab[key] = 2; + assert_eq!(slab[key], 2); + + *slab.get_mut(key).unwrap() = 3; + assert_eq!(slab[key], 3); +} + +#[test] +fn key_of_tagged() { + let mut slab = Slab::new(); + slab.insert(0); + assert_eq!(slab.key_of(&slab[0]), 0); +} + +#[test] +fn key_of_layout_optimizable() { + // Entry<&str> doesn't need a discriminant tag because it can use the + // nonzero-ness of ptr and store Vacant's next at the same offset as len + let mut slab = Slab::new(); + slab.insert("foo"); + slab.insert("bar"); + let third = slab.insert("baz"); + slab.insert("quux"); + assert_eq!(slab.key_of(&slab[third]), third); +} + +#[test] +fn key_of_zst() { + let mut slab = Slab::new(); + slab.insert(()); + let second = slab.insert(()); + slab.insert(()); + assert_eq!(slab.key_of(&slab[second]), second); +} + +#[test] +fn reserve_does_not_allocate_if_available() { + let mut slab = Slab::with_capacity(10); + let mut keys = vec![]; + + for i in 0..6 { + keys.push(slab.insert(i)); + } + + for key in 0..4 { + slab.remove(key); + } + + assert!(slab.capacity() - slab.len() == 8); + + slab.reserve(8); + assert_eq!(10, slab.capacity()); +} + +#[test] +fn reserve_exact_does_not_allocate_if_available() { + let mut slab = Slab::with_capacity(10); + let mut keys = vec![]; + + for i in 0..6 { + keys.push(slab.insert(i)); + } + + for key in 0..4 { + slab.remove(key); + } + + assert!(slab.capacity() - slab.len() == 8); + + slab.reserve_exact(8); + assert_eq!(10, slab.capacity()); +} + +#[test] +#[should_panic(expected = "capacity overflow")] +fn reserve_does_panic_with_capacity_overflow() { + let mut slab = Slab::with_capacity(10); + slab.insert(true); + slab.reserve(std::isize::MAX as usize); +} + +#[test] +#[should_panic(expected = "capacity overflow")] +fn reserve_does_panic_with_capacity_overflow_bytes() { + let mut slab = Slab::with_capacity(10); + slab.insert(1u16); + slab.reserve((std::isize::MAX as usize) / 2); +} + +#[test] +#[should_panic(expected = "capacity overflow")] +fn reserve_exact_does_panic_with_capacity_overflow() { + let mut slab = Slab::with_capacity(10); + slab.insert(true); + slab.reserve_exact(std::isize::MAX as usize); +} + +#[test] +fn retain() { + let mut slab = Slab::with_capacity(2); + + let key1 = slab.insert(0); + let key2 = slab.insert(1); + + slab.retain(|key, x| { + assert_eq!(key, *x); + *x % 2 == 0 + }); + + assert_eq!(slab.len(), 1); + assert_eq!(slab[key1], 0); + assert!(!slab.contains(key2)); + + // Ensure consistency is retained + let key = slab.insert(123); + assert_eq!(key, key2); + + assert_eq!(2, slab.len()); + assert_eq!(2, slab.capacity()); + + // Inserting another element grows + let key = slab.insert(345); + assert_eq!(key, 2); + + assert_eq!(4, slab.capacity()); +} + +#[test] +fn into_iter() { + let mut slab = Slab::new(); + + for i in 0..8 { + slab.insert(i); + } + slab.remove(0); + slab.remove(4); + slab.remove(5); + slab.remove(7); + + let vals: Vec<_> = slab + .into_iter() + .inspect(|&(key, val)| assert_eq!(key, val)) + .map(|(_, val)| val) + .collect(); + assert_eq!(vals, vec![1, 2, 3, 6]); +} + +#[test] +fn into_iter_rev() { + let mut slab = Slab::new(); + + for i in 0..4 { + slab.insert(i); + } + + let mut iter = slab.into_iter(); + assert_eq!(iter.next_back(), Some((3, 3))); + assert_eq!(iter.next_back(), Some((2, 2))); + assert_eq!(iter.next(), Some((0, 0))); + assert_eq!(iter.next_back(), Some((1, 1))); + assert_eq!(iter.next_back(), None); + assert_eq!(iter.next(), None); +} + +#[test] +fn iter() { + let mut slab = Slab::new(); + + for i in 0..4 { + slab.insert(i); + } + + let vals: Vec<_> = slab + .iter() + .enumerate() + .map(|(i, (key, val))| { + assert_eq!(i, key); + *val + }) + .collect(); + assert_eq!(vals, vec![0, 1, 2, 3]); + + slab.remove(1); + + let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect(); + assert_eq!(vals, vec![0, 2, 3]); +} + +#[test] +fn iter_rev() { + let mut slab = Slab::new(); + + for i in 0..4 { + slab.insert(i); + } + slab.remove(0); + + let vals = slab.iter().rev().collect::>(); + assert_eq!(vals, vec![(3, &3), (2, &2), (1, &1)]); +} + +#[test] +fn iter_mut() { + let mut slab = Slab::new(); + + for i in 0..4 { + slab.insert(i); + } + + for (i, (key, e)) in slab.iter_mut().enumerate() { + assert_eq!(i, key); + *e += 1; + } + + let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect(); + assert_eq!(vals, vec![1, 2, 3, 4]); + + slab.remove(2); + + for (_, e) in slab.iter_mut() { + *e += 1; + } + + let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect(); + assert_eq!(vals, vec![2, 3, 5]); +} + +#[test] +fn iter_mut_rev() { + let mut slab = Slab::new(); + + for i in 0..4 { + slab.insert(i); + } + slab.remove(2); + + { + let mut iter = slab.iter_mut(); + assert_eq!(iter.next(), Some((0, &mut 0))); + let mut prev_key = !0; + for (key, e) in iter.rev() { + *e += 10; + assert!(prev_key > key); + prev_key = key; + } + } + + assert_eq!(slab[0], 0); + assert_eq!(slab[1], 11); + assert_eq!(slab[3], 13); + assert!(!slab.contains(2)); +} + +#[test] +fn from_iterator_sorted() { + let mut slab = (0..5).map(|i| (i, i)).collect::>(); + assert_eq!(slab.len(), 5); + assert_eq!(slab[0], 0); + assert_eq!(slab[2], 2); + assert_eq!(slab[4], 4); + assert_eq!(slab.vacant_entry().key(), 5); +} + +#[test] +fn from_iterator_new_in_order() { + // all new keys come in increasing order, but existing keys are overwritten + let mut slab = [(0, 'a'), (1, 'a'), (1, 'b'), (0, 'b'), (9, 'a'), (0, 'c')] + .iter() + .cloned() + .collect::>(); + assert_eq!(slab.len(), 3); + assert_eq!(slab[0], 'c'); + assert_eq!(slab[1], 'b'); + assert_eq!(slab[9], 'a'); + assert_eq!(slab.get(5), None); + assert_eq!(slab.vacant_entry().key(), 8); +} + +#[test] +fn from_iterator_unordered() { + let mut slab = vec![(1, "one"), (50, "fifty"), (3, "three"), (20, "twenty")] + .into_iter() + .collect::>(); + assert_eq!(slab.len(), 4); + assert_eq!(slab.vacant_entry().key(), 0); + let mut iter = slab.iter(); + assert_eq!(iter.next(), Some((1, &"one"))); + assert_eq!(iter.next(), Some((3, &"three"))); + assert_eq!(iter.next(), Some((20, &"twenty"))); + assert_eq!(iter.next(), Some((50, &"fifty"))); + assert_eq!(iter.next(), None); +} + +// https://github.com/tokio-rs/slab/issues/100 +#[test] +fn from_iterator_issue_100() { + let mut slab: slab::Slab<()> = vec![(1, ())].into_iter().collect(); + assert_eq!(slab.len(), 1); + assert_eq!(slab.insert(()), 0); + assert_eq!(slab.insert(()), 2); + assert_eq!(slab.insert(()), 3); + + let mut slab: slab::Slab<()> = vec![(1, ()), (2, ())].into_iter().collect(); + assert_eq!(slab.len(), 2); + assert_eq!(slab.insert(()), 0); + assert_eq!(slab.insert(()), 3); + assert_eq!(slab.insert(()), 4); + + let mut slab: slab::Slab<()> = vec![(1, ()), (3, ())].into_iter().collect(); + assert_eq!(slab.len(), 2); + assert_eq!(slab.insert(()), 2); + assert_eq!(slab.insert(()), 0); + assert_eq!(slab.insert(()), 4); + + let mut slab: slab::Slab<()> = vec![(0, ()), (2, ()), (3, ()), (5, ())] + .into_iter() + .collect(); + assert_eq!(slab.len(), 4); + assert_eq!(slab.insert(()), 4); + assert_eq!(slab.insert(()), 1); + assert_eq!(slab.insert(()), 6); +} + +#[test] +fn clear() { + let mut slab = Slab::new(); + + for i in 0..4 { + slab.insert(i); + } + + // clear full + slab.clear(); + assert!(slab.is_empty()); + + assert_eq!(0, slab.len()); + assert_eq!(4, slab.capacity()); + + for i in 0..2 { + slab.insert(i); + } + + let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect(); + assert_eq!(vals, vec![0, 1]); + + // clear half-filled + slab.clear(); + assert!(slab.is_empty()); +} + +#[test] +fn shrink_to_fit_empty() { + let mut slab = Slab::::with_capacity(20); + slab.shrink_to_fit(); + assert_eq!(slab.capacity(), 0); +} + +#[test] +fn shrink_to_fit_no_vacant() { + let mut slab = Slab::with_capacity(20); + slab.insert(String::new()); + slab.shrink_to_fit(); + assert!(slab.capacity() < 10); +} + +#[test] +fn shrink_to_fit_doesnt_move() { + let mut slab = Slab::with_capacity(8); + slab.insert("foo"); + let bar = slab.insert("bar"); + slab.insert("baz"); + let quux = slab.insert("quux"); + slab.remove(quux); + slab.remove(bar); + slab.shrink_to_fit(); + assert_eq!(slab.len(), 2); + assert!(slab.capacity() >= 3); + assert_eq!(slab.get(0), Some(&"foo")); + assert_eq!(slab.get(2), Some(&"baz")); + assert_eq!(slab.vacant_entry().key(), bar); +} + +#[test] +fn shrink_to_fit_doesnt_recreate_list_when_nothing_can_be_done() { + let mut slab = Slab::with_capacity(16); + for i in 0..4 { + slab.insert(Box::new(i)); + } + slab.remove(0); + slab.remove(2); + slab.remove(1); + assert_eq!(slab.vacant_entry().key(), 1); + slab.shrink_to_fit(); + assert_eq!(slab.len(), 1); + assert!(slab.capacity() >= 4); + assert_eq!(slab.vacant_entry().key(), 1); +} + +#[test] +fn compact_empty() { + let mut slab = Slab::new(); + slab.compact(|_, _, _| panic!()); + assert_eq!(slab.len(), 0); + assert_eq!(slab.capacity(), 0); + slab.reserve(20); + slab.compact(|_, _, _| panic!()); + assert_eq!(slab.len(), 0); + assert_eq!(slab.capacity(), 0); + slab.insert(0); + slab.insert(1); + slab.insert(2); + slab.remove(1); + slab.remove(2); + slab.remove(0); + slab.compact(|_, _, _| panic!()); + assert_eq!(slab.len(), 0); + assert_eq!(slab.capacity(), 0); +} + +#[test] +fn compact_no_moves_needed() { + let mut slab = Slab::new(); + for i in 0..10 { + slab.insert(i); + } + slab.remove(8); + slab.remove(9); + slab.remove(6); + slab.remove(7); + slab.compact(|_, _, _| panic!()); + assert_eq!(slab.len(), 6); + for ((index, &value), want) in slab.iter().zip(0..6) { + assert!(index == value); + assert_eq!(index, want); + } + assert!(slab.capacity() >= 6 && slab.capacity() < 10); +} + +#[test] +fn compact_moves_successfully() { + let mut slab = Slab::with_capacity(20); + for i in 0..10 { + slab.insert(i); + } + for &i in &[0, 5, 9, 6, 3] { + slab.remove(i); + } + let mut moved = 0; + slab.compact(|&mut v, from, to| { + assert!(from > to); + assert!(from >= 5); + assert!(to < 5); + assert_eq!(from, v); + moved += 1; + true + }); + assert_eq!(slab.len(), 5); + assert_eq!(moved, 2); + assert_eq!(slab.vacant_entry().key(), 5); + assert!(slab.capacity() >= 5 && slab.capacity() < 20); + let mut iter = slab.iter(); + assert_eq!(iter.next(), Some((0, &8))); + assert_eq!(iter.next(), Some((1, &1))); + assert_eq!(iter.next(), Some((2, &2))); + assert_eq!(iter.next(), Some((3, &7))); + assert_eq!(iter.next(), Some((4, &4))); + assert_eq!(iter.next(), None); +} + +#[test] +fn compact_doesnt_move_if_closure_errors() { + let mut slab = Slab::with_capacity(20); + for i in 0..10 { + slab.insert(i); + } + for &i in &[9, 3, 1, 4, 0] { + slab.remove(i); + } + slab.compact(|&mut v, from, to| { + assert!(from > to); + assert_eq!(from, v); + v != 6 + }); + assert_eq!(slab.len(), 5); + assert!(slab.capacity() >= 7 && slab.capacity() < 20); + assert_eq!(slab.vacant_entry().key(), 3); + let mut iter = slab.iter(); + assert_eq!(iter.next(), Some((0, &8))); + assert_eq!(iter.next(), Some((1, &7))); + assert_eq!(iter.next(), Some((2, &2))); + assert_eq!(iter.next(), Some((5, &5))); + assert_eq!(iter.next(), Some((6, &6))); + assert_eq!(iter.next(), None); +} + +#[test] +fn compact_handles_closure_panic() { + let mut slab = Slab::new(); + for i in 0..10 { + slab.insert(i); + } + for i in 1..6 { + slab.remove(i); + } + let result = catch_unwind(AssertUnwindSafe(|| { + slab.compact(|&mut v, from, to| { + assert!(from > to); + assert_eq!(from, v); + if v == 7 { + panic!("test"); + } + true + }) + })); + match result { + Err(ref payload) if payload.downcast_ref() == Some(&"test") => {} + Err(bug) => resume_unwind(bug), + Ok(()) => unreachable!(), + } + assert_eq!(slab.len(), 5 - 1); + assert_eq!(slab.vacant_entry().key(), 3); + let mut iter = slab.iter(); + assert_eq!(iter.next(), Some((0, &0))); + assert_eq!(iter.next(), Some((1, &9))); + assert_eq!(iter.next(), Some((2, &8))); + assert_eq!(iter.next(), Some((6, &6))); + assert_eq!(iter.next(), None); +} + +#[test] +fn fully_consumed_drain() { + let mut slab = Slab::new(); + + for i in 0..3 { + slab.insert(i); + } + + { + let mut drain = slab.drain(); + assert_eq!(Some(0), drain.next()); + assert_eq!(Some(1), drain.next()); + assert_eq!(Some(2), drain.next()); + assert_eq!(None, drain.next()); + } + + assert!(slab.is_empty()); +} + +#[test] +fn partially_consumed_drain() { + let mut slab = Slab::new(); + + for i in 0..3 { + slab.insert(i); + } + + { + let mut drain = slab.drain(); + assert_eq!(Some(0), drain.next()); + } + + assert!(slab.is_empty()) +} + +#[test] +fn drain_rev() { + let mut slab = Slab::new(); + for i in 0..10 { + slab.insert(i); + } + slab.remove(9); + + let vals: Vec = slab.drain().rev().collect(); + assert_eq!(vals, (0..9).rev().collect::>()); +} + +#[test] +fn try_remove() { + let mut slab = Slab::new(); + + let key = slab.insert(1); + + assert_eq!(slab.try_remove(key), Some(1)); + assert_eq!(slab.try_remove(key), None); + assert_eq!(slab.get(key), None); +} + +#[rustversion::since(1.39)] +#[test] +fn const_new() { + static _SLAB: Slab<()> = Slab::new(); +} + +#[test] +fn clone_from() { + let mut slab1 = Slab::new(); + let mut slab2 = Slab::new(); + for i in 0..5 { + slab1.insert(i); + slab2.insert(2 * i); + slab2.insert(2 * i + 1); + } + slab1.remove(1); + slab1.remove(3); + slab2.clone_from(&slab1); + + let mut iter2 = slab2.iter(); + assert_eq!(iter2.next(), Some((0, &0))); + assert_eq!(iter2.next(), Some((2, &2))); + assert_eq!(iter2.next(), Some((4, &4))); + assert_eq!(iter2.next(), None); + assert!(slab2.capacity() >= 10); +} diff --git a/utshell-0.5.0/vendor/smallvec/.cargo-checksum.json b/utshell-0.5.0/vendor/smallvec/.cargo-checksum.json new file mode 100644 index 00000000..bdb1fcd3 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"668bb964a243127d65605bb7a0d8d3c81bcbd8f7656a5b5734766ef534b4abcb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"d82015eae942ee5cf74ace8c3c260ee2c6b5bcbeeb87254d2c72622c747a708a","debug_metadata/README.md":"4d7f1c1b2c25ce2231ef71864d06e54323867459035b53bc9e00f66a0a44f82e","debug_metadata/smallvec.natvis":"3092ddebd8fffc3486536d7f27f8c5eae3a8a093d45cd8eeb3946ea2b0c35a15","scripts/run_miri.sh":"74a9f9adc43f986e81977b03846f7dd00122a0150bd8ec3fe4842a1a787e0f07","src/arbitrary.rs":"22e55cfbf60374945b30e6d0855129eff67cd8b878cef6fa997e1f4be67b9e3d","src/lib.rs":"25fe85b6ae7b3972211bf57aeded4c7b72c47e4d843c7a4ba66908442197b5a0","src/specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471","src/tests.rs":"29c6e5dad62ebfea74e5116ac4a344b127b91cfb769fe9ba8b02b53773cf7ec8","tests/debugger_visualizer.rs":"185456ad253957fc0c9e904ff8a1135397ac991c29fa3c60f75d8d81f7463022","tests/macro.rs":"22ad4f6f104a599fdcba19cad8834105b8656b212fb6c7573a427d447f5db14f"},"package":"e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/smallvec/Cargo.toml b/utshell-0.5.0/vendor/smallvec/Cargo.toml new file mode 100644 index 00000000..baba1531 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/Cargo.toml @@ -0,0 +1,72 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "smallvec" +version = "1.13.1" +authors = ["The Servo Project Developers"] +description = "'Small vector' optimization: store up to a small number of items on the stack" +documentation = "https://docs.rs/smallvec/" +readme = "README.md" +keywords = [ + "small", + "vec", + "vector", + "stack", + "no_std", +] +categories = ["data-structures"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/servo/rust-smallvec" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "docsrs", + "--generate-link-to-definition", +] + +[[test]] +name = "debugger_visualizer" +path = "tests/debugger_visualizer.rs" +test = false +required-features = ["debugger_visualizer"] + +[dependencies.arbitrary] +version = "1" +optional = true + +[dependencies.serde] +version = "1" +optional = true +default-features = false + +[dev-dependencies.bincode] +version = "1.0.1" + +[dev-dependencies.debugger_test] +version = "0.1.0" + +[dev-dependencies.debugger_test_parser] +version = "0.1.0" + +[features] +const_generics = [] +const_new = ["const_generics"] +debugger_visualizer = [] +drain_filter = [] +drain_keep_rest = ["drain_filter"] +may_dangle = [] +specialization = [] +union = [] +write = [] diff --git a/utshell-0.5.0/vendor/smallvec/LICENSE-APACHE b/utshell-0.5.0/vendor/smallvec/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/smallvec/LICENSE-MIT b/utshell-0.5.0/vendor/smallvec/LICENSE-MIT new file mode 100644 index 00000000..9729c128 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2018 The Servo Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/smallvec/README.md b/utshell-0.5.0/vendor/smallvec/README.md new file mode 100644 index 00000000..724637c6 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/README.md @@ -0,0 +1,26 @@ +rust-smallvec +============= + +[Documentation](https://docs.rs/smallvec/) + +[Release notes](https://github.com/servo/rust-smallvec/releases) + +"Small vector" optimization for Rust: store up to a small number of items on the stack + +## Example + +```rust +use smallvec::{SmallVec, smallvec}; + +// This SmallVec can hold up to 4 items on the stack: +let mut v: SmallVec<[i32; 4]> = smallvec![1, 2, 3, 4]; + +// It will automatically move its contents to the heap if +// contains more than four items: +v.push(5); + +// SmallVec points to a slice, so you can use normal slice +// indexing and other methods to access its contents: +v[0] = v[1] + v[2]; +v.sort(); +``` diff --git a/utshell-0.5.0/vendor/smallvec/benches/bench.rs b/utshell-0.5.0/vendor/smallvec/benches/bench.rs new file mode 100644 index 00000000..b6a8b857 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/benches/bench.rs @@ -0,0 +1,312 @@ +#![feature(test)] +#![allow(deprecated)] + +extern crate test; + +use self::test::Bencher; +use smallvec::{ExtendFromSlice, smallvec, SmallVec}; + +const VEC_SIZE: usize = 16; +const SPILLED_SIZE: usize = 100; + +trait Vector: for<'a> From<&'a [T]> + Extend + ExtendFromSlice { + fn new() -> Self; + fn push(&mut self, val: T); + fn pop(&mut self) -> Option; + fn remove(&mut self, p: usize) -> T; + fn insert(&mut self, n: usize, val: T); + fn from_elem(val: T, n: usize) -> Self; + fn from_elems(val: &[T]) -> Self; +} + +impl Vector for Vec { + fn new() -> Self { + Self::with_capacity(VEC_SIZE) + } + + fn push(&mut self, val: T) { + self.push(val) + } + + fn pop(&mut self) -> Option { + self.pop() + } + + fn remove(&mut self, p: usize) -> T { + self.remove(p) + } + + fn insert(&mut self, n: usize, val: T) { + self.insert(n, val) + } + + fn from_elem(val: T, n: usize) -> Self { + vec![val; n] + } + + fn from_elems(val: &[T]) -> Self { + val.to_owned() + } +} + +impl Vector for SmallVec<[T; VEC_SIZE]> { + fn new() -> Self { + Self::new() + } + + fn push(&mut self, val: T) { + self.push(val) + } + + fn pop(&mut self) -> Option { + self.pop() + } + + fn remove(&mut self, p: usize) -> T { + self.remove(p) + } + + fn insert(&mut self, n: usize, val: T) { + self.insert(n, val) + } + + fn from_elem(val: T, n: usize) -> Self { + smallvec![val; n] + } + + fn from_elems(val: &[T]) -> Self { + SmallVec::from_slice(val) + } +} + +macro_rules! make_benches { + ($typ:ty { $($b_name:ident => $g_name:ident($($args:expr),*),)* }) => { + $( + #[bench] + fn $b_name(b: &mut Bencher) { + $g_name::<$typ>($($args,)* b) + } + )* + } +} + +make_benches! { + SmallVec<[u64; VEC_SIZE]> { + bench_push => gen_push(SPILLED_SIZE as _), + bench_push_small => gen_push(VEC_SIZE as _), + bench_insert_push => gen_insert_push(SPILLED_SIZE as _), + bench_insert_push_small => gen_insert_push(VEC_SIZE as _), + bench_insert => gen_insert(SPILLED_SIZE as _), + bench_insert_small => gen_insert(VEC_SIZE as _), + bench_remove => gen_remove(SPILLED_SIZE as _), + bench_remove_small => gen_remove(VEC_SIZE as _), + bench_extend => gen_extend(SPILLED_SIZE as _), + bench_extend_small => gen_extend(VEC_SIZE as _), + bench_from_iter => gen_from_iter(SPILLED_SIZE as _), + bench_from_iter_small => gen_from_iter(VEC_SIZE as _), + bench_from_slice => gen_from_slice(SPILLED_SIZE as _), + bench_from_slice_small => gen_from_slice(VEC_SIZE as _), + bench_extend_from_slice => gen_extend_from_slice(SPILLED_SIZE as _), + bench_extend_from_slice_small => gen_extend_from_slice(VEC_SIZE as _), + bench_macro_from_elem => gen_from_elem(SPILLED_SIZE as _), + bench_macro_from_elem_small => gen_from_elem(VEC_SIZE as _), + bench_pushpop => gen_pushpop(), + } +} + +make_benches! { + Vec { + bench_push_vec => gen_push(SPILLED_SIZE as _), + bench_push_vec_small => gen_push(VEC_SIZE as _), + bench_insert_push_vec => gen_insert_push(SPILLED_SIZE as _), + bench_insert_push_vec_small => gen_insert_push(VEC_SIZE as _), + bench_insert_vec => gen_insert(SPILLED_SIZE as _), + bench_insert_vec_small => gen_insert(VEC_SIZE as _), + bench_remove_vec => gen_remove(SPILLED_SIZE as _), + bench_remove_vec_small => gen_remove(VEC_SIZE as _), + bench_extend_vec => gen_extend(SPILLED_SIZE as _), + bench_extend_vec_small => gen_extend(VEC_SIZE as _), + bench_from_iter_vec => gen_from_iter(SPILLED_SIZE as _), + bench_from_iter_vec_small => gen_from_iter(VEC_SIZE as _), + bench_from_slice_vec => gen_from_slice(SPILLED_SIZE as _), + bench_from_slice_vec_small => gen_from_slice(VEC_SIZE as _), + bench_extend_from_slice_vec => gen_extend_from_slice(SPILLED_SIZE as _), + bench_extend_from_slice_vec_small => gen_extend_from_slice(VEC_SIZE as _), + bench_macro_from_elem_vec => gen_from_elem(SPILLED_SIZE as _), + bench_macro_from_elem_vec_small => gen_from_elem(VEC_SIZE as _), + bench_pushpop_vec => gen_pushpop(), + } +} + +fn gen_push>(n: u64, b: &mut Bencher) { + #[inline(never)] + fn push_noinline>(vec: &mut V, x: u64) { + vec.push(x); + } + + b.iter(|| { + let mut vec = V::new(); + for x in 0..n { + push_noinline(&mut vec, x); + } + vec + }); +} + +fn gen_insert_push>(n: u64, b: &mut Bencher) { + #[inline(never)] + fn insert_push_noinline>(vec: &mut V, x: u64) { + vec.insert(x as usize, x); + } + + b.iter(|| { + let mut vec = V::new(); + for x in 0..n { + insert_push_noinline(&mut vec, x); + } + vec + }); +} + +fn gen_insert>(n: u64, b: &mut Bencher) { + #[inline(never)] + fn insert_noinline>(vec: &mut V, p: usize, x: u64) { + vec.insert(p, x) + } + + b.iter(|| { + let mut vec = V::new(); + // Always insert at position 0 so that we are subject to shifts of + // many different lengths. + vec.push(0); + for x in 0..n { + insert_noinline(&mut vec, 0, x); + } + vec + }); +} + +fn gen_remove>(n: usize, b: &mut Bencher) { + #[inline(never)] + fn remove_noinline>(vec: &mut V, p: usize) -> u64 { + vec.remove(p) + } + + b.iter(|| { + let mut vec = V::from_elem(0, n as _); + + for _ in 0..n { + remove_noinline(&mut vec, 0); + } + }); +} + +fn gen_extend>(n: u64, b: &mut Bencher) { + b.iter(|| { + let mut vec = V::new(); + vec.extend(0..n); + vec + }); +} + +fn gen_from_iter>(n: u64, b: &mut Bencher) { + let v: Vec = (0..n).collect(); + b.iter(|| { + let vec = V::from(&v); + vec + }); +} + +fn gen_from_slice>(n: u64, b: &mut Bencher) { + let v: Vec = (0..n).collect(); + b.iter(|| { + let vec = V::from_elems(&v); + vec + }); +} + +fn gen_extend_from_slice>(n: u64, b: &mut Bencher) { + let v: Vec = (0..n).collect(); + b.iter(|| { + let mut vec = V::new(); + vec.extend_from_slice(&v); + vec + }); +} + +fn gen_pushpop>(b: &mut Bencher) { + #[inline(never)] + fn pushpop_noinline>(vec: &mut V, x: u64) -> Option { + vec.push(x); + vec.pop() + } + + b.iter(|| { + let mut vec = V::new(); + for x in 0..SPILLED_SIZE as _ { + pushpop_noinline(&mut vec, x); + } + vec + }); +} + +fn gen_from_elem>(n: usize, b: &mut Bencher) { + b.iter(|| { + let vec = V::from_elem(42, n); + vec + }); +} + +#[bench] +fn bench_insert_many(b: &mut Bencher) { + #[inline(never)] + fn insert_many_noinline>( + vec: &mut SmallVec<[u64; VEC_SIZE]>, + index: usize, + iterable: I, + ) { + vec.insert_many(index, iterable) + } + + b.iter(|| { + let mut vec = SmallVec::<[u64; VEC_SIZE]>::new(); + insert_many_noinline(&mut vec, 0, 0..SPILLED_SIZE as _); + insert_many_noinline(&mut vec, 0, 0..SPILLED_SIZE as _); + vec + }); +} + +#[bench] +fn bench_insert_from_slice(b: &mut Bencher) { + let v: Vec = (0..SPILLED_SIZE as _).collect(); + b.iter(|| { + let mut vec = SmallVec::<[u64; VEC_SIZE]>::new(); + vec.insert_from_slice(0, &v); + vec.insert_from_slice(0, &v); + vec + }); +} + +#[bench] +fn bench_macro_from_list(b: &mut Bencher) { + b.iter(|| { + let vec: SmallVec<[u64; 16]> = smallvec![ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, + 0x80000, 0x100000, + ]; + vec + }); +} + +#[bench] +fn bench_macro_from_list_vec(b: &mut Bencher) { + b.iter(|| { + let vec: Vec = vec![ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, + 0x80000, 0x100000, + ]; + vec + }); +} diff --git a/utshell-0.5.0/vendor/smallvec/debug_metadata/README.md b/utshell-0.5.0/vendor/smallvec/debug_metadata/README.md new file mode 100644 index 00000000..9a5596ba --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/debug_metadata/README.md @@ -0,0 +1,111 @@ +## Debugger Visualizers + +Many languages and debuggers enable developers to control how a type is +displayed in a debugger. These are called "debugger visualizations" or "debugger +views". + +The Windows debuggers (WinDbg\CDB) support defining custom debugger visualizations using +the `Natvis` framework. To use Natvis, developers write XML documents using the natvis +schema that describe how debugger types should be displayed with the `.natvis` extension. +(See: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) +The Natvis files provide patterns which match type names a description of how to display +those types. + +The Natvis schema can be found either online (See: https://code.visualstudio.com/docs/cpp/natvis#_schema) +or locally at `\Xml\Schemas\1033\natvis.xsd`. + +The GNU debugger (GDB) supports defining custom debugger views using Pretty Printers. +Pretty printers are written as python scripts that describe how a type should be displayed +when loaded up in GDB/LLDB. (See: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html#Pretty-Printing) +The pretty printers provide patterns, which match type names, and for matching +types, describe how to display those types. (For writing a pretty printer, see: https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter). + +### Embedding Visualizers + +Through the use of the currently unstable `#[debugger_visualizer]` attribute, the `smallvec` +crate can embed debugger visualizers into the crate metadata. + +Currently the two types of visualizers supported are Natvis and Pretty printers. + +For Natvis files, when linking an executable with a crate that includes Natvis files, +the MSVC linker will embed the contents of all Natvis files into the generated `PDB`. + +For pretty printers, the compiler will encode the contents of the pretty printer +in the `.debug_gdb_scripts` section of the `ELF` generated. + +### Testing Visualizers + +The `smallvec` crate supports testing debugger visualizers defined for this crate. The entry point for +these tests are `tests/debugger_visualizer.rs`. These tests are defined using the `debugger_test` and +`debugger_test_parser` crates. The `debugger_test` crate is a proc macro crate which defines a +single proc macro attribute, `#[debugger_test]`. For more detailed information about this crate, +see https://crates.io/crates/debugger_test. The CI pipeline for the `smallvec` crate has been updated +to run the debugger visualizer tests to ensure debugger visualizers do not become broken/stale. + +The `#[debugger_test]` proc macro attribute may only be used on test functions and will run the +function under the debugger specified by the `debugger` meta item. + +This proc macro attribute has 3 required values: + +1. The first required meta item, `debugger`, takes a string value which specifies the debugger to launch. +2. The second required meta item, `commands`, takes a string of new line (`\n`) separated list of debugger +commands to run. +3. The third required meta item, `expected_statements`, takes a string of new line (`\n`) separated list of +statements that must exist in the debugger output. Pattern matching through regular expressions is also +supported by using the `pattern:` prefix for each expected statement. + +#### Example: + +```rust +#[debugger_test( + debugger = "cdb", + commands = "command1\ncommand2\ncommand3", + expected_statements = "statement1\nstatement2\nstatement3")] +fn test() { + +} +``` + +Using a multiline string is also supported, with a single debugger command/expected statement per line: + +```rust +#[debugger_test( + debugger = "cdb", + commands = " +command1 +command2 +command3", + expected_statements = " +statement1 +pattern:statement[0-9]+ +statement3")] +fn test() { + +} +``` + +In the example above, the second expected statement uses pattern matching through a regular expression +by using the `pattern:` prefix. + +#### Testing Locally + +Currently, only Natvis visualizations have been defined for the `smallvec` crate via `debug_metadata/smallvec.natvis`, +which means the `tests/debugger_visualizer.rs` tests need to be run on Windows using the `*-pc-windows-msvc` targets. +To run these tests locally, first ensure the debugging tools for Windows are installed or install them following +the steps listed here, [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). +Once the debugging tools have been installed, the tests can be run in the same manner as they are in the CI +pipeline. + +#### Note + +When running the debugger visualizer tests, `tests/debugger_visualizer.rs`, they need to be run consecutively +and not in parallel. This can be achieved by passing the flag `--test-threads=1` to rustc. This is due to +how the debugger tests are run. Each test marked with the `#[debugger_test]` attribute launches a debugger +and attaches it to the current test process. If tests are running in parallel, the test will try to attach +a debugger to the current process which may already have a debugger attached causing the test to fail. + +For example: + +``` +cargo test --test debugger_visualizer --features debugger_visualizer -- --test-threads=1 +``` diff --git a/utshell-0.5.0/vendor/smallvec/debug_metadata/smallvec.natvis b/utshell-0.5.0/vendor/smallvec/debug_metadata/smallvec.natvis new file mode 100644 index 00000000..8731860f --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/debug_metadata/smallvec.natvis @@ -0,0 +1,35 @@ + + + + + + + {{ len={len()} is_inline={is_inline()} }} + + is_inline() ? $T2 : capacity + len() + data_ptr() + + + len() + data_ptr() + + + + + + + + + {{ len={len()} is_inline={is_inline()} }} + + is_inline() ? $T2 : capacity + len() + + + len() + data_ptr() + + + + \ No newline at end of file diff --git a/utshell-0.5.0/vendor/smallvec/scripts/run_miri.sh b/utshell-0.5.0/vendor/smallvec/scripts/run_miri.sh new file mode 100644 index 00000000..010ceb06 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/scripts/run_miri.sh @@ -0,0 +1,24 @@ +#!/usr/bin/bash + +set -ex + +# Clean out our target dir, which may have artifacts compiled by a version of +# rust different from the one we're about to download. +cargo clean + +# Install and run the latest version of nightly where miri built successfully. +# Taken from: https://github.com/rust-lang/miri#running-miri-on-ci + +MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri) +echo "Installing latest nightly with Miri: $MIRI_NIGHTLY" +rustup override unset +rustup default "$MIRI_NIGHTLY" + +rustup component add miri +cargo miri setup + +cargo miri test --verbose +cargo miri test --verbose --features union +cargo miri test --verbose --all-features + +rustup override set nightly diff --git a/utshell-0.5.0/vendor/smallvec/src/arbitrary.rs b/utshell-0.5.0/vendor/smallvec/src/arbitrary.rs new file mode 100644 index 00000000..cbdfcb0e --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/src/arbitrary.rs @@ -0,0 +1,19 @@ +use crate::{Array, SmallVec}; +use arbitrary::{Arbitrary, Unstructured}; + +impl<'a, A: Array> Arbitrary<'a> for SmallVec +where + ::Item: Arbitrary<'a>, +{ + fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { + u.arbitrary_iter()?.collect() + } + + fn arbitrary_take_rest(u: Unstructured<'a>) -> arbitrary::Result { + u.arbitrary_take_rest_iter()?.collect() + } + + fn size_hint(depth: usize) -> (usize, Option) { + arbitrary::size_hint::and(::size_hint(depth), (0, None)) + } +} diff --git a/utshell-0.5.0/vendor/smallvec/src/lib.rs b/utshell-0.5.0/vendor/smallvec/src/lib.rs new file mode 100644 index 00000000..cadb5d8b --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/src/lib.rs @@ -0,0 +1,2471 @@ +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Small vectors in various sizes. These store a certain number of elements inline, and fall back +//! to the heap for larger allocations. This can be a useful optimization for improving cache +//! locality and reducing allocator traffic for workloads that fit within the inline buffer. +//! +//! ## `no_std` support +//! +//! By default, `smallvec` does not depend on `std`. However, the optional +//! `write` feature implements the `std::io::Write` trait for vectors of `u8`. +//! When this feature is enabled, `smallvec` depends on `std`. +//! +//! ## Optional features +//! +//! ### `serde` +//! +//! When this optional dependency is enabled, `SmallVec` implements the `serde::Serialize` and +//! `serde::Deserialize` traits. +//! +//! ### `write` +//! +//! When this feature is enabled, `SmallVec<[u8; _]>` implements the `std::io::Write` trait. +//! This feature is not compatible with `#![no_std]` programs. +//! +//! ### `union` +//! +//! **This feature requires Rust 1.49.** +//! +//! When the `union` feature is enabled `smallvec` will track its state (inline or spilled) +//! without the use of an enum tag, reducing the size of the `smallvec` by one machine word. +//! This means that there is potentially no space overhead compared to `Vec`. +//! Note that `smallvec` can still be larger than `Vec` if the inline buffer is larger than two +//! machine words. +//! +//! To use this feature add `features = ["union"]` in the `smallvec` section of Cargo.toml. +//! Note that this feature requires Rust 1.49. +//! +//! Tracking issue: [rust-lang/rust#55149](https://github.com/rust-lang/rust/issues/55149) +//! +//! ### `const_generics` +//! +//! **This feature requires Rust 1.51.** +//! +//! When this feature is enabled, `SmallVec` works with any arrays of any size, not just a fixed +//! list of sizes. +//! +//! ### `const_new` +//! +//! **This feature requires Rust 1.51.** +//! +//! This feature exposes the functions [`SmallVec::new_const`], [`SmallVec::from_const`], and [`smallvec_inline`] which enables the `SmallVec` to be initialized from a const context. +//! For details, see the +//! [Rust Reference](https://doc.rust-lang.org/reference/const_eval.html#const-functions). +//! +//! ### `drain_filter` +//! +//! **This feature is unstable.** It may change to match the unstable `drain_filter` method in libstd. +//! +//! Enables the `drain_filter` method, which produces an iterator that calls a user-provided +//! closure to determine which elements of the vector to remove and yield from the iterator. +//! +//! ### `drain_keep_rest` +//! +//! **This feature is unstable.** It may change to match the unstable `drain_keep_rest` method in libstd. +//! +//! Enables the `DrainFilter::keep_rest` method. +//! +//! ### `specialization` +//! +//! **This feature is unstable and requires a nightly build of the Rust toolchain.** +//! +//! When this feature is enabled, `SmallVec::from(slice)` has improved performance for slices +//! of `Copy` types. (Without this feature, you can use `SmallVec::from_slice` to get optimal +//! performance for `Copy` types.) +//! +//! Tracking issue: [rust-lang/rust#31844](https://github.com/rust-lang/rust/issues/31844) +//! +//! ### `may_dangle` +//! +//! **This feature is unstable and requires a nightly build of the Rust toolchain.** +//! +//! This feature makes the Rust compiler less strict about use of vectors that contain borrowed +//! references. For details, see the +//! [Rustonomicon](https://doc.rust-lang.org/1.42.0/nomicon/dropck.html#an-escape-hatch). +//! +//! Tracking issue: [rust-lang/rust#34761](https://github.com/rust-lang/rust/issues/34761) + +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(feature = "specialization", allow(incomplete_features))] +#![cfg_attr(feature = "specialization", feature(specialization))] +#![cfg_attr(feature = "may_dangle", feature(dropck_eyepatch))] +#![cfg_attr( + feature = "debugger_visualizer", + feature(debugger_visualizer), + debugger_visualizer(natvis_file = "../debug_metadata/smallvec.natvis") +)] +#![deny(missing_docs)] + +#[doc(hidden)] +pub extern crate alloc; + +#[cfg(any(test, feature = "write"))] +extern crate std; + +#[cfg(test)] +mod tests; + +#[allow(deprecated)] +use alloc::alloc::{Layout, LayoutErr}; +use alloc::boxed::Box; +use alloc::{vec, vec::Vec}; +use core::borrow::{Borrow, BorrowMut}; +use core::cmp; +use core::fmt; +use core::hash::{Hash, Hasher}; +use core::hint::unreachable_unchecked; +use core::iter::{repeat, FromIterator, FusedIterator, IntoIterator}; +use core::mem; +use core::mem::MaybeUninit; +use core::ops::{self, Range, RangeBounds}; +use core::ptr::{self, NonNull}; +use core::slice::{self, SliceIndex}; + +#[cfg(feature = "serde")] +use serde::{ + de::{Deserialize, Deserializer, SeqAccess, Visitor}, + ser::{Serialize, SerializeSeq, Serializer}, +}; + +#[cfg(feature = "serde")] +use core::marker::PhantomData; + +#[cfg(feature = "write")] +use std::io; + +#[cfg(feature = "drain_keep_rest")] +use core::mem::ManuallyDrop; + +/// Creates a [`SmallVec`] containing the arguments. +/// +/// `smallvec!` allows `SmallVec`s to be defined with the same syntax as array expressions. +/// There are two forms of this macro: +/// +/// - Create a [`SmallVec`] containing a given list of elements: +/// +/// ``` +/// # use smallvec::{smallvec, SmallVec}; +/// # fn main() { +/// let v: SmallVec<[_; 128]> = smallvec![1, 2, 3]; +/// assert_eq!(v[0], 1); +/// assert_eq!(v[1], 2); +/// assert_eq!(v[2], 3); +/// # } +/// ``` +/// +/// - Create a [`SmallVec`] from a given element and size: +/// +/// ``` +/// # use smallvec::{smallvec, SmallVec}; +/// # fn main() { +/// let v: SmallVec<[_; 0x8000]> = smallvec![1; 3]; +/// assert_eq!(v, SmallVec::from_buf([1, 1, 1])); +/// # } +/// ``` +/// +/// Note that unlike array expressions this syntax supports all elements +/// which implement [`Clone`] and the number of elements doesn't have to be +/// a constant. +/// +/// This will use `clone` to duplicate an expression, so one should be careful +/// using this with types having a nonstandard `Clone` implementation. For +/// example, `smallvec![Rc::new(1); 5]` will create a vector of five references +/// to the same boxed integer value, not five references pointing to independently +/// boxed integers. + +#[macro_export] +macro_rules! smallvec { + // count helper: transform any expression into 1 + (@one $x:expr) => (1usize); + ($elem:expr; $n:expr) => ({ + $crate::SmallVec::from_elem($elem, $n) + }); + ($($x:expr),*$(,)*) => ({ + let count = 0usize $(+ $crate::smallvec!(@one $x))*; + #[allow(unused_mut)] + let mut vec = $crate::SmallVec::new(); + if count <= vec.inline_size() { + $(vec.push($x);)* + vec + } else { + $crate::SmallVec::from_vec($crate::alloc::vec![$($x,)*]) + } + }); +} + +/// Creates an inline [`SmallVec`] containing the arguments. This macro is enabled by the feature `const_new`. +/// +/// `smallvec_inline!` allows `SmallVec`s to be defined with the same syntax as array expressions in `const` contexts. +/// The inline storage `A` will always be an array of the size specified by the arguments. +/// There are two forms of this macro: +/// +/// - Create a [`SmallVec`] containing a given list of elements: +/// +/// ``` +/// # use smallvec::{smallvec_inline, SmallVec}; +/// # fn main() { +/// const V: SmallVec<[i32; 3]> = smallvec_inline![1, 2, 3]; +/// assert_eq!(V[0], 1); +/// assert_eq!(V[1], 2); +/// assert_eq!(V[2], 3); +/// # } +/// ``` +/// +/// - Create a [`SmallVec`] from a given element and size: +/// +/// ``` +/// # use smallvec::{smallvec_inline, SmallVec}; +/// # fn main() { +/// const V: SmallVec<[i32; 3]> = smallvec_inline![1; 3]; +/// assert_eq!(V, SmallVec::from_buf([1, 1, 1])); +/// # } +/// ``` +/// +/// Note that the behavior mimics that of array expressions, in contrast to [`smallvec`]. +#[cfg(feature = "const_new")] +#[cfg_attr(docsrs, doc(cfg(feature = "const_new")))] +#[macro_export] +macro_rules! smallvec_inline { + // count helper: transform any expression into 1 + (@one $x:expr) => (1usize); + ($elem:expr; $n:expr) => ({ + $crate::SmallVec::<[_; $n]>::from_const([$elem; $n]) + }); + ($($x:expr),+ $(,)?) => ({ + const N: usize = 0usize $(+ $crate::smallvec_inline!(@one $x))*; + $crate::SmallVec::<[_; N]>::from_const([$($x,)*]) + }); +} + +/// `panic!()` in debug builds, optimization hint in release. +#[cfg(not(feature = "union"))] +macro_rules! debug_unreachable { + () => { + debug_unreachable!("entered unreachable code") + }; + ($e:expr) => { + if cfg!(debug_assertions) { + panic!($e); + } else { + unreachable_unchecked(); + } + }; +} + +/// Trait to be implemented by a collection that can be extended from a slice +/// +/// ## Example +/// +/// ```rust +/// use smallvec::{ExtendFromSlice, SmallVec}; +/// +/// fn initialize>(v: &mut V) { +/// v.extend_from_slice(b"Test!"); +/// } +/// +/// let mut vec = Vec::new(); +/// initialize(&mut vec); +/// assert_eq!(&vec, b"Test!"); +/// +/// let mut small_vec = SmallVec::<[u8; 8]>::new(); +/// initialize(&mut small_vec); +/// assert_eq!(&small_vec as &[_], b"Test!"); +/// ``` +#[doc(hidden)] +#[deprecated] +pub trait ExtendFromSlice { + /// Extends a collection from a slice of its element type + fn extend_from_slice(&mut self, other: &[T]); +} + +#[allow(deprecated)] +impl ExtendFromSlice for Vec { + fn extend_from_slice(&mut self, other: &[T]) { + Vec::extend_from_slice(self, other) + } +} + +/// Error type for APIs with fallible heap allocation +#[derive(Debug)] +pub enum CollectionAllocErr { + /// Overflow `usize::MAX` or other error during size computation + CapacityOverflow, + /// The allocator return an error + AllocErr { + /// The layout that was passed to the allocator + layout: Layout, + }, +} + +impl fmt::Display for CollectionAllocErr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Allocation error: {:?}", self) + } +} + +#[allow(deprecated)] +impl From for CollectionAllocErr { + fn from(_: LayoutErr) -> Self { + CollectionAllocErr::CapacityOverflow + } +} + +fn infallible(result: Result) -> T { + match result { + Ok(x) => x, + Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), + Err(CollectionAllocErr::AllocErr { layout }) => alloc::alloc::handle_alloc_error(layout), + } +} + +/// FIXME: use `Layout::array` when we require a Rust version where it’s stable +/// +fn layout_array(n: usize) -> Result { + let size = mem::size_of::() + .checked_mul(n) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + let align = mem::align_of::(); + Layout::from_size_align(size, align).map_err(|_| CollectionAllocErr::CapacityOverflow) +} + +unsafe fn deallocate(ptr: NonNull, capacity: usize) { + // This unwrap should succeed since the same did when allocating. + let layout = layout_array::(capacity).unwrap(); + alloc::alloc::dealloc(ptr.as_ptr() as *mut u8, layout) +} + +/// An iterator that removes the items from a `SmallVec` and yields them by value. +/// +/// Returned from [`SmallVec::drain`][1]. +/// +/// [1]: struct.SmallVec.html#method.drain +pub struct Drain<'a, T: 'a + Array> { + tail_start: usize, + tail_len: usize, + iter: slice::Iter<'a, T::Item>, + vec: NonNull>, +} + +impl<'a, T: 'a + Array> fmt::Debug for Drain<'a, T> +where + T::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() + } +} + +unsafe impl<'a, T: Sync + Array> Sync for Drain<'a, T> {} +unsafe impl<'a, T: Send + Array> Send for Drain<'a, T> {} + +impl<'a, T: 'a + Array> Iterator for Drain<'a, T> { + type Item = T::Item; + + #[inline] + fn next(&mut self) -> Option { + self.iter + .next() + .map(|reference| unsafe { ptr::read(reference) }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +impl<'a, T: 'a + Array> DoubleEndedIterator for Drain<'a, T> { + #[inline] + fn next_back(&mut self) -> Option { + self.iter + .next_back() + .map(|reference| unsafe { ptr::read(reference) }) + } +} + +impl<'a, T: Array> ExactSizeIterator for Drain<'a, T> { + #[inline] + fn len(&self) -> usize { + self.iter.len() + } +} + +impl<'a, T: Array> FusedIterator for Drain<'a, T> {} + +impl<'a, T: 'a + Array> Drop for Drain<'a, T> { + fn drop(&mut self) { + self.for_each(drop); + + if self.tail_len > 0 { + unsafe { + let source_vec = self.vec.as_mut(); + + // memmove back untouched tail, update to new length + let start = source_vec.len(); + let tail = self.tail_start; + if tail != start { + // as_mut_ptr creates a &mut, invalidating other pointers. + // This pattern avoids calling it with a pointer already present. + let ptr = source_vec.as_mut_ptr(); + let src = ptr.add(tail); + let dst = ptr.add(start); + ptr::copy(src, dst, self.tail_len); + } + source_vec.set_len(start + self.tail_len); + } + } + } +} + +#[cfg(feature = "drain_filter")] +/// An iterator which uses a closure to determine if an element should be removed. +/// +/// Returned from [`SmallVec::drain_filter`][1]. +/// +/// [1]: struct.SmallVec.html#method.drain_filter +pub struct DrainFilter<'a, T, F> +where + F: FnMut(&mut T::Item) -> bool, + T: Array, +{ + vec: &'a mut SmallVec, + /// The index of the item that will be inspected by the next call to `next`. + idx: usize, + /// The number of items that have been drained (removed) thus far. + del: usize, + /// The original length of `vec` prior to draining. + old_len: usize, + /// The filter test predicate. + pred: F, + /// A flag that indicates a panic has occurred in the filter test predicate. + /// This is used as a hint in the drop implementation to prevent consumption + /// of the remainder of the `DrainFilter`. Any unprocessed items will be + /// backshifted in the `vec`, but no further items will be dropped or + /// tested by the filter predicate. + panic_flag: bool, +} + +#[cfg(feature = "drain_filter")] +impl fmt::Debug for DrainFilter<'_, T, F> +where + F: FnMut(&mut T::Item) -> bool, + T: Array, + T::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("DrainFilter").field(&self.vec.as_slice()).finish() + } +} + +#[cfg(feature = "drain_filter")] +impl Iterator for DrainFilter<'_, T, F> +where + F: FnMut(&mut T::Item) -> bool, + T: Array, +{ + type Item = T::Item; + + fn next(&mut self) -> Option + { + unsafe { + while self.idx < self.old_len { + let i = self.idx; + let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); + self.panic_flag = true; + let drained = (self.pred)(&mut v[i]); + self.panic_flag = false; + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; + if drained { + self.del += 1; + return Some(ptr::read(&v[i])); + } else if self.del > 0 { + let del = self.del; + let src: *const Self::Item = &v[i]; + let dst: *mut Self::Item = &mut v[i - del]; + ptr::copy_nonoverlapping(src, dst, 1); + } + } + None + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.old_len - self.idx)) + } +} + +#[cfg(feature = "drain_filter")] +impl Drop for DrainFilter<'_, T, F> +where + F: FnMut(&mut T::Item) -> bool, + T: Array, +{ + fn drop(&mut self) { + struct BackshiftOnDrop<'a, 'b, T, F> + where + F: FnMut(&mut T::Item) -> bool, + T: Array + { + drain: &'b mut DrainFilter<'a, T, F>, + } + + impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F> + where + F: FnMut(&mut T::Item) -> bool, + T: Array + { + fn drop(&mut self) { + unsafe { + if self.drain.idx < self.drain.old_len && self.drain.del > 0 { + // This is a pretty messed up state, and there isn't really an + // obviously right thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the unprocessed + // elements and tell the vec that they still exist. The backshift + // is required to prevent a double-drop of the last successfully + // drained item prior to a panic in the predicate. + let ptr = self.drain.vec.as_mut_ptr(); + let src = ptr.add(self.drain.idx); + let dst = src.sub(self.drain.del); + let tail_len = self.drain.old_len - self.drain.idx; + src.copy_to(dst, tail_len); + } + self.drain.vec.set_len(self.drain.old_len - self.drain.del); + } + } + } + + let backshift = BackshiftOnDrop { drain: self }; + + // Attempt to consume any remaining elements if the filter predicate + // has not yet panicked. We'll backshift any remaining elements + // whether we've already panicked or if the consumption here panics. + if !backshift.drain.panic_flag { + backshift.drain.for_each(drop); + } + } +} + +#[cfg(feature = "drain_keep_rest")] +impl DrainFilter<'_, T, F> +where + F: FnMut(&mut T::Item) -> bool, + T: Array +{ + /// Keep unyielded elements in the source `Vec`. + /// + /// # Examples + /// + /// ``` + /// # use smallvec::{smallvec, SmallVec}; + /// + /// let mut vec: SmallVec<[char; 2]> = smallvec!['a', 'b', 'c']; + /// let mut drain = vec.drain_filter(|_| true); + /// + /// assert_eq!(drain.next().unwrap(), 'a'); + /// + /// // This call keeps 'b' and 'c' in the vec. + /// drain.keep_rest(); + /// + /// // If we wouldn't call `keep_rest()`, + /// // `vec` would be empty. + /// assert_eq!(vec, SmallVec::<[char; 2]>::from_slice(&['b', 'c'])); + /// ``` + pub fn keep_rest(self) + { + // At this moment layout looks like this: + // + // _____________________/-- old_len + // / \ + // [kept] [yielded] [tail] + // \_______/ ^-- idx + // \-- del + // + // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`) + // + // 1. Move [tail] after [kept] + // 2. Update length of the original vec to `old_len - del` + // a. In case of ZST, this is the only thing we want to do + // 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do + let mut this = ManuallyDrop::new(self); + + unsafe { + // ZSTs have no identity, so we don't need to move them around. + let needs_move = mem::size_of::() != 0; + + if needs_move && this.idx < this.old_len && this.del > 0 { + let ptr = this.vec.as_mut_ptr(); + let src = ptr.add(this.idx); + let dst = src.sub(this.del); + let tail_len = this.old_len - this.idx; + src.copy_to(dst, tail_len); + } + + let new_len = this.old_len - this.del; + this.vec.set_len(new_len); + } + } +} + +#[cfg(feature = "union")] +union SmallVecData { + inline: core::mem::ManuallyDrop>, + heap: (NonNull, usize), +} + +#[cfg(all(feature = "union", feature = "const_new"))] +impl SmallVecData<[T; N]> { + #[cfg_attr(docsrs, doc(cfg(feature = "const_new")))] + #[inline] + const fn from_const(inline: MaybeUninit<[T; N]>) -> Self { + SmallVecData { + inline: core::mem::ManuallyDrop::new(inline), + } + } +} + +#[cfg(feature = "union")] +impl SmallVecData { + #[inline] + unsafe fn inline(&self) -> ConstNonNull { + ConstNonNull::new(self.inline.as_ptr() as *const A::Item).unwrap() + } + #[inline] + unsafe fn inline_mut(&mut self) -> NonNull { + NonNull::new(self.inline.as_mut_ptr() as *mut A::Item).unwrap() + } + #[inline] + fn from_inline(inline: MaybeUninit) -> SmallVecData { + SmallVecData { + inline: core::mem::ManuallyDrop::new(inline), + } + } + #[inline] + unsafe fn into_inline(self) -> MaybeUninit { + core::mem::ManuallyDrop::into_inner(self.inline) + } + #[inline] + unsafe fn heap(&self) -> (ConstNonNull, usize) { + (ConstNonNull(self.heap.0), self.heap.1) + } + #[inline] + unsafe fn heap_mut(&mut self) -> (NonNull, &mut usize) { + let h = &mut self.heap; + (h.0, &mut h.1) + } + #[inline] + fn from_heap(ptr: NonNull, len: usize) -> SmallVecData { + SmallVecData { heap: (ptr, len) } + } +} + +#[cfg(not(feature = "union"))] +enum SmallVecData { + Inline(MaybeUninit), + // Using NonNull and NonZero here allows to reduce size of `SmallVec`. + Heap { + // Since we never allocate on heap + // unless our capacity is bigger than inline capacity + // heap capacity cannot be less than 1. + // Therefore, pointer cannot be null too. + ptr: NonNull, + len: usize, + }, +} + +#[cfg(all(not(feature = "union"), feature = "const_new"))] +impl SmallVecData<[T; N]> { + #[cfg_attr(docsrs, doc(cfg(feature = "const_new")))] + #[inline] + const fn from_const(inline: MaybeUninit<[T; N]>) -> Self { + SmallVecData::Inline(inline) + } +} + +#[cfg(not(feature = "union"))] +impl SmallVecData { + #[inline] + unsafe fn inline(&self) -> ConstNonNull { + match self { + SmallVecData::Inline(a) => ConstNonNull::new(a.as_ptr() as *const A::Item).unwrap(), + _ => debug_unreachable!(), + } + } + #[inline] + unsafe fn inline_mut(&mut self) -> NonNull { + match self { + SmallVecData::Inline(a) => NonNull::new(a.as_mut_ptr() as *mut A::Item).unwrap(), + _ => debug_unreachable!(), + } + } + #[inline] + fn from_inline(inline: MaybeUninit) -> SmallVecData { + SmallVecData::Inline(inline) + } + #[inline] + unsafe fn into_inline(self) -> MaybeUninit { + match self { + SmallVecData::Inline(a) => a, + _ => debug_unreachable!(), + } + } + #[inline] + unsafe fn heap(&self) -> (ConstNonNull, usize) { + match self { + SmallVecData::Heap { ptr, len } => (ConstNonNull(*ptr), *len), + _ => debug_unreachable!(), + } + } + #[inline] + unsafe fn heap_mut(&mut self) -> (NonNull, &mut usize) { + match self { + SmallVecData::Heap { ptr, len } => (*ptr, len), + _ => debug_unreachable!(), + } + } + #[inline] + fn from_heap(ptr: NonNull, len: usize) -> SmallVecData { + SmallVecData::Heap { ptr, len } + } +} + +unsafe impl Send for SmallVecData {} +unsafe impl Sync for SmallVecData {} + +/// A `Vec`-like container that can store a small number of elements inline. +/// +/// `SmallVec` acts like a vector, but can store a limited amount of data inline within the +/// `SmallVec` struct rather than in a separate allocation. If the data exceeds this limit, the +/// `SmallVec` will "spill" its data onto the heap, allocating a new buffer to hold it. +/// +/// The amount of data that a `SmallVec` can store inline depends on its backing store. The backing +/// store can be any type that implements the `Array` trait; usually it is a small fixed-sized +/// array. For example a `SmallVec<[u64; 8]>` can hold up to eight 64-bit integers inline. +/// +/// ## Example +/// +/// ```rust +/// use smallvec::SmallVec; +/// let mut v = SmallVec::<[u8; 4]>::new(); // initialize an empty vector +/// +/// // The vector can hold up to 4 items without spilling onto the heap. +/// v.extend(0..4); +/// assert_eq!(v.len(), 4); +/// assert!(!v.spilled()); +/// +/// // Pushing another element will force the buffer to spill: +/// v.push(4); +/// assert_eq!(v.len(), 5); +/// assert!(v.spilled()); +/// ``` +pub struct SmallVec { + // The capacity field is used to determine which of the storage variants is active: + // If capacity <= Self::inline_capacity() then the inline variant is used and capacity holds the current length of the vector (number of elements actually in use). + // If capacity > Self::inline_capacity() then the heap variant is used and capacity holds the size of the memory allocation. + capacity: usize, + data: SmallVecData, +} + +impl SmallVec { + /// Construct an empty vector + #[inline] + pub fn new() -> SmallVec { + // Try to detect invalid custom implementations of `Array`. Hopefully, + // this check should be optimized away entirely for valid ones. + assert!( + mem::size_of::() == A::size() * mem::size_of::() + && mem::align_of::() >= mem::align_of::() + ); + SmallVec { + capacity: 0, + data: SmallVecData::from_inline(MaybeUninit::uninit()), + } + } + + /// Construct an empty vector with enough capacity pre-allocated to store at least `n` + /// elements. + /// + /// Will create a heap allocation only if `n` is larger than the inline capacity. + /// + /// ``` + /// # use smallvec::SmallVec; + /// + /// let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(100); + /// + /// assert!(v.is_empty()); + /// assert!(v.capacity() >= 100); + /// ``` + #[inline] + pub fn with_capacity(n: usize) -> Self { + let mut v = SmallVec::new(); + v.reserve_exact(n); + v + } + + /// Construct a new `SmallVec` from a `Vec`. + /// + /// Elements will be copied to the inline buffer if `vec.capacity() <= Self::inline_capacity()`. + /// + /// ```rust + /// use smallvec::SmallVec; + /// + /// let vec = vec![1, 2, 3, 4, 5]; + /// let small_vec: SmallVec<[_; 3]> = SmallVec::from_vec(vec); + /// + /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + /// ``` + #[inline] + pub fn from_vec(mut vec: Vec) -> SmallVec { + if vec.capacity() <= Self::inline_capacity() { + // Cannot use Vec with smaller capacity + // because we use value of `Self::capacity` field as indicator. + unsafe { + let mut data = SmallVecData::::from_inline(MaybeUninit::uninit()); + let len = vec.len(); + vec.set_len(0); + ptr::copy_nonoverlapping(vec.as_ptr(), data.inline_mut().as_ptr(), len); + + SmallVec { + capacity: len, + data, + } + } + } else { + let (ptr, cap, len) = (vec.as_mut_ptr(), vec.capacity(), vec.len()); + mem::forget(vec); + let ptr = NonNull::new(ptr) + // See docs: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_mut_ptr + .expect("Cannot be null by `Vec` invariant"); + + SmallVec { + capacity: cap, + data: SmallVecData::from_heap(ptr, len), + } + } + } + + /// Constructs a new `SmallVec` on the stack from an `A` without + /// copying elements. + /// + /// ```rust + /// use smallvec::SmallVec; + /// + /// let buf = [1, 2, 3, 4, 5]; + /// let small_vec: SmallVec<_> = SmallVec::from_buf(buf); + /// + /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + /// ``` + #[inline] + pub fn from_buf(buf: A) -> SmallVec { + SmallVec { + capacity: A::size(), + data: SmallVecData::from_inline(MaybeUninit::new(buf)), + } + } + + /// Constructs a new `SmallVec` on the stack from an `A` without + /// copying elements. Also sets the length, which must be less or + /// equal to the size of `buf`. + /// + /// ```rust + /// use smallvec::SmallVec; + /// + /// let buf = [1, 2, 3, 4, 5, 0, 0, 0]; + /// let small_vec: SmallVec<_> = SmallVec::from_buf_and_len(buf, 5); + /// + /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + /// ``` + #[inline] + pub fn from_buf_and_len(buf: A, len: usize) -> SmallVec { + assert!(len <= A::size()); + unsafe { SmallVec::from_buf_and_len_unchecked(MaybeUninit::new(buf), len) } + } + + /// Constructs a new `SmallVec` on the stack from an `A` without + /// copying elements. Also sets the length. The user is responsible + /// for ensuring that `len <= A::size()`. + /// + /// ```rust + /// use smallvec::SmallVec; + /// use std::mem::MaybeUninit; + /// + /// let buf = [1, 2, 3, 4, 5, 0, 0, 0]; + /// let small_vec: SmallVec<_> = unsafe { + /// SmallVec::from_buf_and_len_unchecked(MaybeUninit::new(buf), 5) + /// }; + /// + /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + /// ``` + #[inline] + pub unsafe fn from_buf_and_len_unchecked(buf: MaybeUninit, len: usize) -> SmallVec { + SmallVec { + capacity: len, + data: SmallVecData::from_inline(buf), + } + } + + /// Sets the length of a vector. + /// + /// This will explicitly set the size of the vector, without actually + /// modifying its buffers, so it is up to the caller to ensure that the + /// vector is actually the specified size. + pub unsafe fn set_len(&mut self, new_len: usize) { + let (_, len_ptr, _) = self.triple_mut(); + *len_ptr = new_len; + } + + /// The maximum number of elements this vector can hold inline + #[inline] + fn inline_capacity() -> usize { + if mem::size_of::() > 0 { + A::size() + } else { + // For zero-size items code like `ptr.add(offset)` always returns the same pointer. + // Therefore all items are at the same address, + // and any array size has capacity for infinitely many items. + // The capacity is limited by the bit width of the length field. + // + // `Vec` also does this: + // https://github.com/rust-lang/rust/blob/1.44.0/src/liballoc/raw_vec.rs#L186 + // + // In our case, this also ensures that a smallvec of zero-size items never spills, + // and we never try to allocate zero bytes which `std::alloc::alloc` disallows. + core::usize::MAX + } + } + + /// The maximum number of elements this vector can hold inline + #[inline] + pub fn inline_size(&self) -> usize { + Self::inline_capacity() + } + + /// The number of elements stored in the vector + #[inline] + pub fn len(&self) -> usize { + self.triple().1 + } + + /// Returns `true` if the vector is empty + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// The number of items the vector can hold without reallocating + #[inline] + pub fn capacity(&self) -> usize { + self.triple().2 + } + + /// Returns a tuple with (data ptr, len, capacity) + /// Useful to get all `SmallVec` properties with a single check of the current storage variant. + #[inline] + fn triple(&self) -> (ConstNonNull, usize, usize) { + unsafe { + if self.spilled() { + let (ptr, len) = self.data.heap(); + (ptr, len, self.capacity) + } else { + (self.data.inline(), self.capacity, Self::inline_capacity()) + } + } + } + + /// Returns a tuple with (data ptr, len ptr, capacity) + #[inline] + fn triple_mut(&mut self) -> (NonNull, &mut usize, usize) { + unsafe { + if self.spilled() { + let (ptr, len_ptr) = self.data.heap_mut(); + (ptr, len_ptr, self.capacity) + } else { + ( + self.data.inline_mut(), + &mut self.capacity, + Self::inline_capacity(), + ) + } + } + } + + /// Returns `true` if the data has spilled into a separate heap-allocated buffer. + #[inline] + pub fn spilled(&self) -> bool { + self.capacity > Self::inline_capacity() + } + + /// Creates a draining iterator that removes the specified range in the vector + /// and yields the removed items. + /// + /// Note 1: The element range is removed even if the iterator is only + /// partially consumed or not consumed at all. + /// + /// Note 2: It is unspecified how many elements are removed from the vector + /// if the `Drain` value is leaked. + /// + /// # Panics + /// + /// Panics if the starting point is greater than the end point or if + /// the end point is greater than the length of the vector. + pub fn drain(&mut self, range: R) -> Drain<'_, A> + where + R: RangeBounds, + { + use core::ops::Bound::*; + + let len = self.len(); + let start = match range.start_bound() { + Included(&n) => n, + Excluded(&n) => n.checked_add(1).expect("Range start out of bounds"), + Unbounded => 0, + }; + let end = match range.end_bound() { + Included(&n) => n.checked_add(1).expect("Range end out of bounds"), + Excluded(&n) => n, + Unbounded => len, + }; + + assert!(start <= end); + assert!(end <= len); + + unsafe { + self.set_len(start); + + let range_slice = slice::from_raw_parts(self.as_ptr().add(start), end - start); + + Drain { + tail_start: end, + tail_len: len - end, + iter: range_slice.iter(), + // Since self is a &mut, passing it to a function would invalidate the slice iterator. + vec: NonNull::new_unchecked(self as *mut _), + } + } + } + + #[cfg(feature = "drain_filter")] + /// Creates an iterator which uses a closure to determine if an element should be removed. + /// + /// If the closure returns true, the element is removed and yielded. If the closure returns + /// false, the element will remain in the vector and will not be yielded by the iterator. + /// + /// Using this method is equivalent to the following code: + /// ``` + /// # use smallvec::SmallVec; + /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 }; + /// # let mut vec: SmallVec<[i32; 8]> = SmallVec::from_slice(&[1i32, 2, 3, 4, 5, 6]); + /// let mut i = 0; + /// while i < vec.len() { + /// if some_predicate(&mut vec[i]) { + /// let val = vec.remove(i); + /// // your code here + /// } else { + /// i += 1; + /// } + /// } + /// + /// # assert_eq!(vec, SmallVec::<[i32; 8]>::from_slice(&[1i32, 4, 5])); + /// ``` + /// /// + /// But `drain_filter` is easier to use. `drain_filter` is also more efficient, + /// because it can backshift the elements of the array in bulk. + /// + /// Note that `drain_filter` also lets you mutate every element in the filter closure, + /// regardless of whether you choose to keep or remove it. + /// + /// # Examples + /// + /// Splitting an array into evens and odds, reusing the original allocation: + /// + /// ``` + /// # use smallvec::SmallVec; + /// let mut numbers: SmallVec<[i32; 16]> = SmallVec::from_slice(&[1i32, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]); + /// + /// let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::>(); + /// let odds = numbers; + /// + /// assert_eq!(evens, SmallVec::<[i32; 16]>::from_slice(&[2i32, 4, 6, 8, 14])); + /// assert_eq!(odds, SmallVec::<[i32; 16]>::from_slice(&[1i32, 3, 5, 9, 11, 13, 15])); + /// ``` + pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, A, F,> + where + F: FnMut(&mut A::Item) -> bool, + { + let old_len = self.len(); + + // Guard against us getting leaked (leak amplification) + unsafe { + self.set_len(0); + } + + DrainFilter { vec: self, idx: 0, del: 0, old_len, pred: filter, panic_flag: false } + } + + /// Append an item to the vector. + #[inline] + pub fn push(&mut self, value: A::Item) { + unsafe { + let (mut ptr, mut len, cap) = self.triple_mut(); + if *len == cap { + self.reserve_one_unchecked(); + let (heap_ptr, heap_len) = self.data.heap_mut(); + ptr = heap_ptr; + len = heap_len; + } + ptr::write(ptr.as_ptr().add(*len), value); + *len += 1; + } + } + + /// Remove an item from the end of the vector and return it, or None if empty. + #[inline] + pub fn pop(&mut self) -> Option { + unsafe { + let (ptr, len_ptr, _) = self.triple_mut(); + let ptr: *const _ = ptr.as_ptr(); + if *len_ptr == 0 { + return None; + } + let last_index = *len_ptr - 1; + *len_ptr = last_index; + Some(ptr::read(ptr.add(last_index))) + } + } + + /// Moves all the elements of `other` into `self`, leaving `other` empty. + /// + /// # Example + /// + /// ``` + /// # use smallvec::{SmallVec, smallvec}; + /// let mut v0: SmallVec<[u8; 16]> = smallvec![1, 2, 3]; + /// let mut v1: SmallVec<[u8; 32]> = smallvec![4, 5, 6]; + /// v0.append(&mut v1); + /// assert_eq!(*v0, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(*v1, []); + /// ``` + pub fn append(&mut self, other: &mut SmallVec) + where + B: Array, + { + self.extend(other.drain(..)) + } + + /// Re-allocate to set the capacity to `max(new_cap, inline_size())`. + /// + /// Panics if `new_cap` is less than the vector's length + /// or if the capacity computation overflows `usize`. + pub fn grow(&mut self, new_cap: usize) { + infallible(self.try_grow(new_cap)) + } + + /// Re-allocate to set the capacity to `max(new_cap, inline_size())`. + /// + /// Panics if `new_cap` is less than the vector's length + pub fn try_grow(&mut self, new_cap: usize) -> Result<(), CollectionAllocErr> { + unsafe { + let unspilled = !self.spilled(); + let (ptr, &mut len, cap) = self.triple_mut(); + assert!(new_cap >= len); + if new_cap <= Self::inline_capacity() { + if unspilled { + return Ok(()); + } + self.data = SmallVecData::from_inline(MaybeUninit::uninit()); + ptr::copy_nonoverlapping(ptr.as_ptr(), self.data.inline_mut().as_ptr(), len); + self.capacity = len; + deallocate(ptr, cap); + } else if new_cap != cap { + let layout = layout_array::(new_cap)?; + debug_assert!(layout.size() > 0); + let new_alloc; + if unspilled { + new_alloc = NonNull::new(alloc::alloc::alloc(layout)) + .ok_or(CollectionAllocErr::AllocErr { layout })? + .cast(); + ptr::copy_nonoverlapping(ptr.as_ptr(), new_alloc.as_ptr(), len); + } else { + // This should never fail since the same succeeded + // when previously allocating `ptr`. + let old_layout = layout_array::(cap)?; + + let new_ptr = + alloc::alloc::realloc(ptr.as_ptr() as *mut u8, old_layout, layout.size()); + new_alloc = NonNull::new(new_ptr) + .ok_or(CollectionAllocErr::AllocErr { layout })? + .cast(); + } + self.data = SmallVecData::from_heap(new_alloc, len); + self.capacity = new_cap; + } + Ok(()) + } + } + + /// Reserve capacity for `additional` more elements to be inserted. + /// + /// May reserve more space to avoid frequent reallocations. + /// + /// Panics if the capacity computation overflows `usize`. + #[inline] + pub fn reserve(&mut self, additional: usize) { + infallible(self.try_reserve(additional)) + } + + /// Internal method used to grow in push() and insert(), where we know already we have to grow. + #[cold] + fn reserve_one_unchecked(&mut self) { + debug_assert_eq!(self.len(), self.capacity()); + let new_cap = self.len() + .checked_add(1) + .and_then(usize::checked_next_power_of_two) + .expect("capacity overflow"); + infallible(self.try_grow(new_cap)) + } + + /// Reserve capacity for `additional` more elements to be inserted. + /// + /// May reserve more space to avoid frequent reallocations. + pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + // prefer triple_mut() even if triple() would work so that the optimizer removes duplicated + // calls to it from callers. + let (_, &mut len, cap) = self.triple_mut(); + if cap - len >= additional { + return Ok(()); + } + let new_cap = len + .checked_add(additional) + .and_then(usize::checked_next_power_of_two) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + self.try_grow(new_cap) + } + + /// Reserve the minimum capacity for `additional` more elements to be inserted. + /// + /// Panics if the new capacity overflows `usize`. + pub fn reserve_exact(&mut self, additional: usize) { + infallible(self.try_reserve_exact(additional)) + } + + /// Reserve the minimum capacity for `additional` more elements to be inserted. + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + let (_, &mut len, cap) = self.triple_mut(); + if cap - len >= additional { + return Ok(()); + } + let new_cap = len + .checked_add(additional) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + self.try_grow(new_cap) + } + + /// Shrink the capacity of the vector as much as possible. + /// + /// When possible, this will move data from an external heap buffer to the vector's inline + /// storage. + pub fn shrink_to_fit(&mut self) { + if !self.spilled() { + return; + } + let len = self.len(); + if self.inline_size() >= len { + unsafe { + let (ptr, len) = self.data.heap(); + self.data = SmallVecData::from_inline(MaybeUninit::uninit()); + ptr::copy_nonoverlapping(ptr.as_ptr(), self.data.inline_mut().as_ptr(), len); + deallocate(ptr.0, self.capacity); + self.capacity = len; + } + } else if self.capacity() > len { + self.grow(len); + } + } + + /// Shorten the vector, keeping the first `len` elements and dropping the rest. + /// + /// If `len` is greater than or equal to the vector's current length, this has no + /// effect. + /// + /// This does not re-allocate. If you want the vector's capacity to shrink, call + /// `shrink_to_fit` after truncating. + pub fn truncate(&mut self, len: usize) { + unsafe { + let (ptr, len_ptr, _) = self.triple_mut(); + let ptr = ptr.as_ptr(); + while len < *len_ptr { + let last_index = *len_ptr - 1; + *len_ptr = last_index; + ptr::drop_in_place(ptr.add(last_index)); + } + } + } + + /// Extracts a slice containing the entire vector. + /// + /// Equivalent to `&s[..]`. + pub fn as_slice(&self) -> &[A::Item] { + self + } + + /// Extracts a mutable slice of the entire vector. + /// + /// Equivalent to `&mut s[..]`. + pub fn as_mut_slice(&mut self) -> &mut [A::Item] { + self + } + + /// Remove the element at position `index`, replacing it with the last element. + /// + /// This does not preserve ordering, but is O(1). + /// + /// Panics if `index` is out of bounds. + #[inline] + pub fn swap_remove(&mut self, index: usize) -> A::Item { + let len = self.len(); + self.swap(len - 1, index); + self.pop() + .unwrap_or_else(|| unsafe { unreachable_unchecked() }) + } + + /// Remove all elements from the vector. + #[inline] + pub fn clear(&mut self) { + self.truncate(0); + } + + /// Remove and return the element at position `index`, shifting all elements after it to the + /// left. + /// + /// Panics if `index` is out of bounds. + pub fn remove(&mut self, index: usize) -> A::Item { + unsafe { + let (ptr, len_ptr, _) = self.triple_mut(); + let len = *len_ptr; + assert!(index < len); + *len_ptr = len - 1; + let ptr = ptr.as_ptr().add(index); + let item = ptr::read(ptr); + ptr::copy(ptr.add(1), ptr, len - index - 1); + item + } + } + + /// Insert an element at position `index`, shifting all elements after it to the right. + /// + /// Panics if `index > len`. + pub fn insert(&mut self, index: usize, element: A::Item) { + unsafe { + let (mut ptr, mut len_ptr, cap) = self.triple_mut(); + if *len_ptr == cap { + self.reserve_one_unchecked(); + let (heap_ptr, heap_len_ptr) = self.data.heap_mut(); + ptr = heap_ptr; + len_ptr = heap_len_ptr; + } + let mut ptr = ptr.as_ptr(); + let len = *len_ptr; + ptr = ptr.add(index); + if index < len { + ptr::copy(ptr, ptr.add(1), len - index); + } else if index == len { + // No elements need shifting. + } else { + panic!("index exceeds length"); + } + *len_ptr = len + 1; + ptr::write(ptr, element); + } + } + + /// Insert multiple elements at position `index`, shifting all following elements toward the + /// back. + pub fn insert_many>(&mut self, index: usize, iterable: I) { + let mut iter = iterable.into_iter(); + if index == self.len() { + return self.extend(iter); + } + + let (lower_size_bound, _) = iter.size_hint(); + assert!(lower_size_bound <= core::isize::MAX as usize); // Ensure offset is indexable + assert!(index + lower_size_bound >= index); // Protect against overflow + + let mut num_added = 0; + let old_len = self.len(); + assert!(index <= old_len); + + unsafe { + // Reserve space for `lower_size_bound` elements. + self.reserve(lower_size_bound); + let start = self.as_mut_ptr(); + let ptr = start.add(index); + + // Move the trailing elements. + ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index); + + // In case the iterator panics, don't double-drop the items we just copied above. + self.set_len(0); + let mut guard = DropOnPanic { + start, + skip: index..(index + lower_size_bound), + len: old_len + lower_size_bound, + }; + + // The set_len above invalidates the previous pointers, so we must re-create them. + let start = self.as_mut_ptr(); + let ptr = start.add(index); + + while num_added < lower_size_bound { + let element = match iter.next() { + Some(x) => x, + None => break, + }; + let cur = ptr.add(num_added); + ptr::write(cur, element); + guard.skip.start += 1; + num_added += 1; + } + + if num_added < lower_size_bound { + // Iterator provided fewer elements than the hint. Move the tail backward. + ptr::copy( + ptr.add(lower_size_bound), + ptr.add(num_added), + old_len - index, + ); + } + // There are no more duplicate or uninitialized slots, so the guard is not needed. + self.set_len(old_len + num_added); + mem::forget(guard); + } + + // Insert any remaining elements one-by-one. + for element in iter { + self.insert(index + num_added, element); + num_added += 1; + } + + struct DropOnPanic { + start: *mut T, + skip: Range, // Space we copied-out-of, but haven't written-to yet. + len: usize, + } + + impl Drop for DropOnPanic { + fn drop(&mut self) { + for i in 0..self.len { + if !self.skip.contains(&i) { + unsafe { + ptr::drop_in_place(self.start.add(i)); + } + } + } + } + } + } + + /// Convert a `SmallVec` to a `Vec`, without reallocating if the `SmallVec` has already spilled onto + /// the heap. + pub fn into_vec(mut self) -> Vec { + if self.spilled() { + unsafe { + let (ptr, &mut len) = self.data.heap_mut(); + let v = Vec::from_raw_parts(ptr.as_ptr(), len, self.capacity); + mem::forget(self); + v + } + } else { + self.into_iter().collect() + } + } + + /// Converts a `SmallVec` into a `Box<[T]>` without reallocating if the `SmallVec` has already spilled + /// onto the heap. + /// + /// Note that this will drop any excess capacity. + pub fn into_boxed_slice(self) -> Box<[A::Item]> { + self.into_vec().into_boxed_slice() + } + + /// Convert the `SmallVec` into an `A` if possible. Otherwise return `Err(Self)`. + /// + /// This method returns `Err(Self)` if the `SmallVec` is too short (and the `A` contains uninitialized elements), + /// or if the `SmallVec` is too long (and all the elements were spilled to the heap). + pub fn into_inner(self) -> Result { + if self.spilled() || self.len() != A::size() { + // Note: A::size, not Self::inline_capacity + Err(self) + } else { + unsafe { + let data = ptr::read(&self.data); + mem::forget(self); + Ok(data.into_inline().assume_init()) + } + } + } + + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` such that `f(&e)` returns `false`. + /// This method operates in place and preserves the order of the retained + /// elements. + pub fn retain bool>(&mut self, mut f: F) { + let mut del = 0; + let len = self.len(); + for i in 0..len { + if !f(&mut self[i]) { + del += 1; + } else if del > 0 { + self.swap(i - del, i); + } + } + self.truncate(len - del); + } + + /// Retains only the elements specified by the predicate. + /// + /// This method is identical in behaviour to [`retain`]; it is included only + /// to maintain api-compatability with `std::Vec`, where the methods are + /// separate for historical reasons. + pub fn retain_mut bool>(&mut self, f: F) { + self.retain(f) + } + + /// Removes consecutive duplicate elements. + pub fn dedup(&mut self) + where + A::Item: PartialEq, + { + self.dedup_by(|a, b| a == b); + } + + /// Removes consecutive duplicate elements using the given equality relation. + pub fn dedup_by(&mut self, mut same_bucket: F) + where + F: FnMut(&mut A::Item, &mut A::Item) -> bool, + { + // See the implementation of Vec::dedup_by in the + // standard library for an explanation of this algorithm. + let len = self.len(); + if len <= 1 { + return; + } + + let ptr = self.as_mut_ptr(); + let mut w: usize = 1; + + unsafe { + for r in 1..len { + let p_r = ptr.add(r); + let p_wm1 = ptr.add(w - 1); + if !same_bucket(&mut *p_r, &mut *p_wm1) { + if r != w { + let p_w = p_wm1.add(1); + mem::swap(&mut *p_r, &mut *p_w); + } + w += 1; + } + } + } + + self.truncate(w); + } + + /// Removes consecutive elements that map to the same key. + pub fn dedup_by_key(&mut self, mut key: F) + where + F: FnMut(&mut A::Item) -> K, + K: PartialEq, + { + self.dedup_by(|a, b| key(a) == key(b)); + } + + /// Resizes the `SmallVec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `SmallVec` is extended by the difference, with each + /// additional slot filled with the result of calling the closure `f`. The return values from `f` + /// will end up in the `SmallVec` in the order they have been generated. + /// + /// If `new_len` is less than `len`, the `SmallVec` is simply truncated. + /// + /// This method uses a closure to create new values on every push. If you'd rather `Clone` a given + /// value, use `resize`. If you want to use the `Default` trait to generate values, you can pass + /// `Default::default()` as the second argument. + /// + /// Added for `std::vec::Vec` compatibility (added in Rust 1.33.0) + /// + /// ``` + /// # use smallvec::{smallvec, SmallVec}; + /// let mut vec : SmallVec<[_; 4]> = smallvec![1, 2, 3]; + /// vec.resize_with(5, Default::default); + /// assert_eq!(&*vec, &[1, 2, 3, 0, 0]); + /// + /// let mut vec : SmallVec<[_; 4]> = smallvec![]; + /// let mut p = 1; + /// vec.resize_with(4, || { p *= 2; p }); + /// assert_eq!(&*vec, &[2, 4, 8, 16]); + /// ``` + pub fn resize_with(&mut self, new_len: usize, f: F) + where + F: FnMut() -> A::Item, + { + let old_len = self.len(); + if old_len < new_len { + let mut f = f; + let additional = new_len - old_len; + self.reserve(additional); + for _ in 0..additional { + self.push(f()); + } + } else if old_len > new_len { + self.truncate(new_len); + } + } + + /// Creates a `SmallVec` directly from the raw components of another + /// `SmallVec`. + /// + /// # Safety + /// + /// This is highly unsafe, due to the number of invariants that aren't + /// checked: + /// + /// * `ptr` needs to have been previously allocated via `SmallVec` for its + /// spilled storage (at least, it's highly likely to be incorrect if it + /// wasn't). + /// * `ptr`'s `A::Item` type needs to be the same size and alignment that + /// it was allocated with + /// * `length` needs to be less than or equal to `capacity`. + /// * `capacity` needs to be the capacity that the pointer was allocated + /// with. + /// + /// Violating these may cause problems like corrupting the allocator's + /// internal data structures. + /// + /// Additionally, `capacity` must be greater than the amount of inline + /// storage `A` has; that is, the new `SmallVec` must need to spill over + /// into heap allocated storage. This condition is asserted against. + /// + /// The ownership of `ptr` is effectively transferred to the + /// `SmallVec` which may then deallocate, reallocate or change the + /// contents of memory pointed to by the pointer at will. Ensure + /// that nothing else uses the pointer after calling this + /// function. + /// + /// # Examples + /// + /// ``` + /// # use smallvec::{smallvec, SmallVec}; + /// use std::mem; + /// use std::ptr; + /// + /// fn main() { + /// let mut v: SmallVec<[_; 1]> = smallvec![1, 2, 3]; + /// + /// // Pull out the important parts of `v`. + /// let p = v.as_mut_ptr(); + /// let len = v.len(); + /// let cap = v.capacity(); + /// let spilled = v.spilled(); + /// + /// unsafe { + /// // Forget all about `v`. The heap allocation that stored the + /// // three values won't be deallocated. + /// mem::forget(v); + /// + /// // Overwrite memory with [4, 5, 6]. + /// // + /// // This is only safe if `spilled` is true! Otherwise, we are + /// // writing into the old `SmallVec`'s inline storage on the + /// // stack. + /// assert!(spilled); + /// for i in 0..len { + /// ptr::write(p.add(i), 4 + i); + /// } + /// + /// // Put everything back together into a SmallVec with a different + /// // amount of inline storage, but which is still less than `cap`. + /// let rebuilt = SmallVec::<[_; 2]>::from_raw_parts(p, len, cap); + /// assert_eq!(&*rebuilt, &[4, 5, 6]); + /// } + /// } + #[inline] + pub unsafe fn from_raw_parts(ptr: *mut A::Item, length: usize, capacity: usize) -> SmallVec { + // SAFETY: We require caller to provide same ptr as we alloc + // and we never alloc null pointer. + let ptr = unsafe { + debug_assert!(!ptr.is_null(), "Called `from_raw_parts` with null pointer."); + NonNull::new_unchecked(ptr) + }; + assert!(capacity > Self::inline_capacity()); + SmallVec { + capacity, + data: SmallVecData::from_heap(ptr, length), + } + } + + /// Returns a raw pointer to the vector's buffer. + pub fn as_ptr(&self) -> *const A::Item { + // We shadow the slice method of the same name to avoid going through + // `deref`, which creates an intermediate reference that may place + // additional safety constraints on the contents of the slice. + self.triple().0.as_ptr() + } + + /// Returns a raw mutable pointer to the vector's buffer. + pub fn as_mut_ptr(&mut self) -> *mut A::Item { + // We shadow the slice method of the same name to avoid going through + // `deref_mut`, which creates an intermediate reference that may place + // additional safety constraints on the contents of the slice. + self.triple_mut().0.as_ptr() + } +} + +impl SmallVec +where + A::Item: Copy, +{ + /// Copy the elements from a slice into a new `SmallVec`. + /// + /// For slices of `Copy` types, this is more efficient than `SmallVec::from(slice)`. + pub fn from_slice(slice: &[A::Item]) -> Self { + let len = slice.len(); + if len <= Self::inline_capacity() { + SmallVec { + capacity: len, + data: SmallVecData::from_inline(unsafe { + let mut data: MaybeUninit = MaybeUninit::uninit(); + ptr::copy_nonoverlapping( + slice.as_ptr(), + data.as_mut_ptr() as *mut A::Item, + len, + ); + data + }), + } + } else { + let mut b = slice.to_vec(); + let cap = b.capacity(); + let ptr = NonNull::new(b.as_mut_ptr()).expect("Vec always contain non null pointers."); + mem::forget(b); + SmallVec { + capacity: cap, + data: SmallVecData::from_heap(ptr, len), + } + } + } + + /// Copy elements from a slice into the vector at position `index`, shifting any following + /// elements toward the back. + /// + /// For slices of `Copy` types, this is more efficient than `insert`. + #[inline] + pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) { + self.reserve(slice.len()); + + let len = self.len(); + assert!(index <= len); + + unsafe { + let slice_ptr = slice.as_ptr(); + let ptr = self.as_mut_ptr().add(index); + ptr::copy(ptr, ptr.add(slice.len()), len - index); + ptr::copy_nonoverlapping(slice_ptr, ptr, slice.len()); + self.set_len(len + slice.len()); + } + } + + /// Copy elements from a slice and append them to the vector. + /// + /// For slices of `Copy` types, this is more efficient than `extend`. + #[inline] + pub fn extend_from_slice(&mut self, slice: &[A::Item]) { + let len = self.len(); + self.insert_from_slice(len, slice); + } +} + +impl SmallVec +where + A::Item: Clone, +{ + /// Resizes the vector so that its length is equal to `len`. + /// + /// If `len` is less than the current length, the vector simply truncated. + /// + /// If `len` is greater than the current length, `value` is appended to the + /// vector until its length equals `len`. + pub fn resize(&mut self, len: usize, value: A::Item) { + let old_len = self.len(); + + if len > old_len { + self.extend(repeat(value).take(len - old_len)); + } else { + self.truncate(len); + } + } + + /// Creates a `SmallVec` with `n` copies of `elem`. + /// ``` + /// use smallvec::SmallVec; + /// + /// let v = SmallVec::<[char; 128]>::from_elem('d', 2); + /// assert_eq!(v, SmallVec::from_buf(['d', 'd'])); + /// ``` + pub fn from_elem(elem: A::Item, n: usize) -> Self { + if n > Self::inline_capacity() { + vec![elem; n].into() + } else { + let mut v = SmallVec::::new(); + unsafe { + let (ptr, len_ptr, _) = v.triple_mut(); + let ptr = ptr.as_ptr(); + let mut local_len = SetLenOnDrop::new(len_ptr); + + for i in 0..n { + ::core::ptr::write(ptr.add(i), elem.clone()); + local_len.increment_len(1); + } + } + v + } + } +} + +impl ops::Deref for SmallVec { + type Target = [A::Item]; + #[inline] + fn deref(&self) -> &[A::Item] { + unsafe { + let (ptr, len, _) = self.triple(); + slice::from_raw_parts(ptr.as_ptr(), len) + } + } +} + +impl ops::DerefMut for SmallVec { + #[inline] + fn deref_mut(&mut self) -> &mut [A::Item] { + unsafe { + let (ptr, &mut len, _) = self.triple_mut(); + slice::from_raw_parts_mut(ptr.as_ptr(), len) + } + } +} + +impl AsRef<[A::Item]> for SmallVec { + #[inline] + fn as_ref(&self) -> &[A::Item] { + self + } +} + +impl AsMut<[A::Item]> for SmallVec { + #[inline] + fn as_mut(&mut self) -> &mut [A::Item] { + self + } +} + +impl Borrow<[A::Item]> for SmallVec { + #[inline] + fn borrow(&self) -> &[A::Item] { + self + } +} + +impl BorrowMut<[A::Item]> for SmallVec { + #[inline] + fn borrow_mut(&mut self) -> &mut [A::Item] { + self + } +} + +#[cfg(feature = "write")] +#[cfg_attr(docsrs, doc(cfg(feature = "write")))] +impl> io::Write for SmallVec { + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + self.extend_from_slice(buf); + Ok(buf.len()) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.extend_from_slice(buf); + Ok(()) + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl Serialize for SmallVec +where + A::Item: Serialize, +{ + fn serialize(&self, serializer: S) -> Result { + let mut state = serializer.serialize_seq(Some(self.len()))?; + for item in self { + state.serialize_element(&item)?; + } + state.end() + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl<'de, A: Array> Deserialize<'de> for SmallVec +where + A::Item: Deserialize<'de>, +{ + fn deserialize>(deserializer: D) -> Result { + deserializer.deserialize_seq(SmallVecVisitor { + phantom: PhantomData, + }) + } +} + +#[cfg(feature = "serde")] +struct SmallVecVisitor { + phantom: PhantomData, +} + +#[cfg(feature = "serde")] +impl<'de, A: Array> Visitor<'de> for SmallVecVisitor +where + A::Item: Deserialize<'de>, +{ + type Value = SmallVec; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: B) -> Result + where + B: SeqAccess<'de>, + { + use serde::de::Error; + let len = seq.size_hint().unwrap_or(0); + let mut values = SmallVec::new(); + values.try_reserve(len).map_err(B::Error::custom)?; + + while let Some(value) = seq.next_element()? { + values.push(value); + } + + Ok(values) + } +} + +#[cfg(feature = "specialization")] +trait SpecFrom { + fn spec_from(slice: S) -> SmallVec; +} + +#[cfg(feature = "specialization")] +mod specialization; + +#[cfg(feature = "arbitrary")] +mod arbitrary; + +#[cfg(feature = "specialization")] +impl<'a, A: Array> SpecFrom for SmallVec +where + A::Item: Copy, +{ + #[inline] + fn spec_from(slice: &'a [A::Item]) -> SmallVec { + SmallVec::from_slice(slice) + } +} + +impl<'a, A: Array> From<&'a [A::Item]> for SmallVec +where + A::Item: Clone, +{ + #[cfg(not(feature = "specialization"))] + #[inline] + fn from(slice: &'a [A::Item]) -> SmallVec { + slice.iter().cloned().collect() + } + + #[cfg(feature = "specialization")] + #[inline] + fn from(slice: &'a [A::Item]) -> SmallVec { + SmallVec::spec_from(slice) + } +} + +impl From> for SmallVec { + #[inline] + fn from(vec: Vec) -> SmallVec { + SmallVec::from_vec(vec) + } +} + +impl From for SmallVec { + #[inline] + fn from(array: A) -> SmallVec { + SmallVec::from_buf(array) + } +} + +impl> ops::Index for SmallVec { + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + &(**self)[index] + } +} + +impl> ops::IndexMut for SmallVec { + fn index_mut(&mut self, index: I) -> &mut I::Output { + &mut (&mut **self)[index] + } +} + +#[allow(deprecated)] +impl ExtendFromSlice for SmallVec +where + A::Item: Copy, +{ + fn extend_from_slice(&mut self, other: &[A::Item]) { + SmallVec::extend_from_slice(self, other) + } +} + +impl FromIterator for SmallVec { + #[inline] + fn from_iter>(iterable: I) -> SmallVec { + let mut v = SmallVec::new(); + v.extend(iterable); + v + } +} + +impl Extend for SmallVec { + fn extend>(&mut self, iterable: I) { + let mut iter = iterable.into_iter(); + let (lower_size_bound, _) = iter.size_hint(); + self.reserve(lower_size_bound); + + unsafe { + let (ptr, len_ptr, cap) = self.triple_mut(); + let ptr = ptr.as_ptr(); + let mut len = SetLenOnDrop::new(len_ptr); + while len.get() < cap { + if let Some(out) = iter.next() { + ptr::write(ptr.add(len.get()), out); + len.increment_len(1); + } else { + return; + } + } + } + + for elem in iter { + self.push(elem); + } + } +} + +impl fmt::Debug for SmallVec +where + A::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list().entries(self.iter()).finish() + } +} + +impl Default for SmallVec { + #[inline] + fn default() -> SmallVec { + SmallVec::new() + } +} + +#[cfg(feature = "may_dangle")] +unsafe impl<#[may_dangle] A: Array> Drop for SmallVec { + fn drop(&mut self) { + unsafe { + if self.spilled() { + let (ptr, &mut len) = self.data.heap_mut(); + Vec::from_raw_parts(ptr.as_ptr(), len, self.capacity); + } else { + ptr::drop_in_place(&mut self[..]); + } + } + } +} + +#[cfg(not(feature = "may_dangle"))] +impl Drop for SmallVec { + fn drop(&mut self) { + unsafe { + if self.spilled() { + let (ptr, &mut len) = self.data.heap_mut(); + drop(Vec::from_raw_parts(ptr.as_ptr(), len, self.capacity)); + } else { + ptr::drop_in_place(&mut self[..]); + } + } + } +} + +impl Clone for SmallVec +where + A::Item: Clone, +{ + #[inline] + fn clone(&self) -> SmallVec { + SmallVec::from(self.as_slice()) + } + + fn clone_from(&mut self, source: &Self) { + // Inspired from `impl Clone for Vec`. + + // drop anything that will not be overwritten + self.truncate(source.len()); + + // self.len <= other.len due to the truncate above, so the + // slices here are always in-bounds. + let (init, tail) = source.split_at(self.len()); + + // reuse the contained values' allocations/resources. + self.clone_from_slice(init); + self.extend(tail.iter().cloned()); + } +} + +impl PartialEq> for SmallVec +where + A::Item: PartialEq, +{ + #[inline] + fn eq(&self, other: &SmallVec) -> bool { + self[..] == other[..] + } +} + +impl Eq for SmallVec where A::Item: Eq {} + +impl PartialOrd for SmallVec +where + A::Item: PartialOrd, +{ + #[inline] + fn partial_cmp(&self, other: &SmallVec) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +impl Ord for SmallVec +where + A::Item: Ord, +{ + #[inline] + fn cmp(&self, other: &SmallVec) -> cmp::Ordering { + Ord::cmp(&**self, &**other) + } +} + +impl Hash for SmallVec +where + A::Item: Hash, +{ + fn hash(&self, state: &mut H) { + (**self).hash(state) + } +} + +unsafe impl Send for SmallVec where A::Item: Send {} + +/// An iterator that consumes a `SmallVec` and yields its items by value. +/// +/// Returned from [`SmallVec::into_iter`][1]. +/// +/// [1]: struct.SmallVec.html#method.into_iter +pub struct IntoIter { + data: SmallVec, + current: usize, + end: usize, +} + +impl fmt::Debug for IntoIter +where + A::Item: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("IntoIter").field(&self.as_slice()).finish() + } +} + +impl Clone for IntoIter +where + A::Item: Clone, +{ + fn clone(&self) -> IntoIter { + SmallVec::from(self.as_slice()).into_iter() + } +} + +impl Drop for IntoIter { + fn drop(&mut self) { + for _ in self {} + } +} + +impl Iterator for IntoIter { + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.current == self.end { + None + } else { + unsafe { + let current = self.current; + self.current += 1; + Some(ptr::read(self.data.as_ptr().add(current))) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let size = self.end - self.current; + (size, Some(size)) + } +} + +impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back(&mut self) -> Option { + if self.current == self.end { + None + } else { + unsafe { + self.end -= 1; + Some(ptr::read(self.data.as_ptr().add(self.end))) + } + } + } +} + +impl ExactSizeIterator for IntoIter {} +impl FusedIterator for IntoIter {} + +impl IntoIter { + /// Returns the remaining items of this iterator as a slice. + pub fn as_slice(&self) -> &[A::Item] { + let len = self.end - self.current; + unsafe { core::slice::from_raw_parts(self.data.as_ptr().add(self.current), len) } + } + + /// Returns the remaining items of this iterator as a mutable slice. + pub fn as_mut_slice(&mut self) -> &mut [A::Item] { + let len = self.end - self.current; + unsafe { core::slice::from_raw_parts_mut(self.data.as_mut_ptr().add(self.current), len) } + } +} + +impl IntoIterator for SmallVec { + type IntoIter = IntoIter; + type Item = A::Item; + fn into_iter(mut self) -> Self::IntoIter { + unsafe { + // Set SmallVec len to zero as `IntoIter` drop handles dropping of the elements + let len = self.len(); + self.set_len(0); + IntoIter { + data: self, + current: 0, + end: len, + } + } + } +} + +impl<'a, A: Array> IntoIterator for &'a SmallVec { + type IntoIter = slice::Iter<'a, A::Item>; + type Item = &'a A::Item; + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a, A: Array> IntoIterator for &'a mut SmallVec { + type IntoIter = slice::IterMut<'a, A::Item>; + type Item = &'a mut A::Item; + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +/// Types that can be used as the backing store for a [`SmallVec`]. +pub unsafe trait Array { + /// The type of the array's elements. + type Item; + /// Returns the number of items the array can hold. + fn size() -> usize; +} + +/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope. +/// +/// Copied from +struct SetLenOnDrop<'a> { + len: &'a mut usize, + local_len: usize, +} + +impl<'a> SetLenOnDrop<'a> { + #[inline] + fn new(len: &'a mut usize) -> Self { + SetLenOnDrop { + local_len: *len, + len, + } + } + + #[inline] + fn get(&self) -> usize { + self.local_len + } + + #[inline] + fn increment_len(&mut self, increment: usize) { + self.local_len += increment; + } +} + +impl<'a> Drop for SetLenOnDrop<'a> { + #[inline] + fn drop(&mut self) { + *self.len = self.local_len; + } +} + +#[cfg(feature = "const_new")] +impl SmallVec<[T; N]> { + /// Construct an empty vector. + /// + /// This is a `const` version of [`SmallVec::new`] that is enabled by the feature `const_new`, with the limitation that it only works for arrays. + #[cfg_attr(docsrs, doc(cfg(feature = "const_new")))] + #[inline] + pub const fn new_const() -> Self { + SmallVec { + capacity: 0, + data: SmallVecData::from_const(MaybeUninit::uninit()), + } + } + + /// The array passed as an argument is moved to be an inline version of `SmallVec`. + /// + /// This is a `const` version of [`SmallVec::from_buf`] that is enabled by the feature `const_new`, with the limitation that it only works for arrays. + #[cfg_attr(docsrs, doc(cfg(feature = "const_new")))] + #[inline] + pub const fn from_const(items: [T; N]) -> Self { + SmallVec { + capacity: N, + data: SmallVecData::from_const(MaybeUninit::new(items)), + } + } + + /// Constructs a new `SmallVec` on the stack from an array without + /// copying elements. Also sets the length. The user is responsible + /// for ensuring that `len <= N`. + /// + /// This is a `const` version of [`SmallVec::from_buf_and_len_unchecked`] that is enabled by the feature `const_new`, with the limitation that it only works for arrays. + #[cfg_attr(docsrs, doc(cfg(feature = "const_new")))] + #[inline] + pub const unsafe fn from_const_with_len_unchecked(items: [T; N], len: usize) -> Self { + SmallVec { + capacity: len, + data: SmallVecData::from_const(MaybeUninit::new(items)), + } + } +} + +#[cfg(feature = "const_generics")] +#[cfg_attr(docsrs, doc(cfg(feature = "const_generics")))] +unsafe impl Array for [T; N] { + type Item = T; + #[inline] + fn size() -> usize { + N + } +} + +#[cfg(not(feature = "const_generics"))] +macro_rules! impl_array( + ($($size:expr),+) => { + $( + unsafe impl Array for [T; $size] { + type Item = T; + #[inline] + fn size() -> usize { $size } + } + )+ + } +); + +#[cfg(not(feature = "const_generics"))] +impl_array!( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 36, 0x40, 0x60, 0x80, 0x100, 0x200, 0x400, 0x600, 0x800, 0x1000, + 0x2000, 0x4000, 0x6000, 0x8000, 0x10000, 0x20000, 0x40000, 0x60000, 0x80000, 0x10_0000 +); + +/// Convenience trait for constructing a `SmallVec` +pub trait ToSmallVec { + /// Construct a new `SmallVec` from a slice. + fn to_smallvec(&self) -> SmallVec; +} + +impl ToSmallVec for [A::Item] +where + A::Item: Copy, +{ + #[inline] + fn to_smallvec(&self) -> SmallVec { + SmallVec::from_slice(self) + } +} + +// Immutable counterpart for `NonNull`. +#[repr(transparent)] +struct ConstNonNull(NonNull); + +impl ConstNonNull { + #[inline] + fn new(ptr: *const T) -> Option { + NonNull::new(ptr as *mut T).map(Self) + } + #[inline] + fn as_ptr(self) -> *const T { + self.0.as_ptr() + } +} + +impl Clone for ConstNonNull { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for ConstNonNull {} diff --git a/utshell-0.5.0/vendor/smallvec/src/specialization.rs b/utshell-0.5.0/vendor/smallvec/src/specialization.rs new file mode 100644 index 00000000..658fa77a --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/src/specialization.rs @@ -0,0 +1,19 @@ +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementations that require `default fn`. + +use super::{Array, SmallVec, SpecFrom}; + +impl<'a, A: Array> SpecFrom for SmallVec +where + A::Item: Clone, +{ + #[inline] + default fn spec_from(slice: &'a [A::Item]) -> SmallVec { + slice.into_iter().cloned().collect() + } +} diff --git a/utshell-0.5.0/vendor/smallvec/src/tests.rs b/utshell-0.5.0/vendor/smallvec/src/tests.rs new file mode 100644 index 00000000..3eab846b --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/src/tests.rs @@ -0,0 +1,1025 @@ +use crate::{smallvec, SmallVec}; + +use std::iter::FromIterator; + +use alloc::borrow::ToOwned; +use alloc::boxed::Box; +use alloc::rc::Rc; +use alloc::{vec, vec::Vec}; + +#[test] +pub fn test_zero() { + let mut v = SmallVec::<[_; 0]>::new(); + assert!(!v.spilled()); + v.push(0usize); + assert!(v.spilled()); + assert_eq!(&*v, &[0]); +} + +// We heap allocate all these strings so that double frees will show up under valgrind. + +#[test] +pub fn test_inline() { + let mut v = SmallVec::<[_; 16]>::new(); + v.push("hello".to_owned()); + v.push("there".to_owned()); + assert_eq!(&*v, &["hello".to_owned(), "there".to_owned(),][..]); +} + +#[test] +pub fn test_spill() { + let mut v = SmallVec::<[_; 2]>::new(); + v.push("hello".to_owned()); + assert_eq!(v[0], "hello"); + v.push("there".to_owned()); + v.push("burma".to_owned()); + assert_eq!(v[0], "hello"); + v.push("shave".to_owned()); + assert_eq!( + &*v, + &[ + "hello".to_owned(), + "there".to_owned(), + "burma".to_owned(), + "shave".to_owned(), + ][..] + ); +} + +#[test] +pub fn test_double_spill() { + let mut v = SmallVec::<[_; 2]>::new(); + v.push("hello".to_owned()); + v.push("there".to_owned()); + v.push("burma".to_owned()); + v.push("shave".to_owned()); + v.push("hello".to_owned()); + v.push("there".to_owned()); + v.push("burma".to_owned()); + v.push("shave".to_owned()); + assert_eq!( + &*v, + &[ + "hello".to_owned(), + "there".to_owned(), + "burma".to_owned(), + "shave".to_owned(), + "hello".to_owned(), + "there".to_owned(), + "burma".to_owned(), + "shave".to_owned(), + ][..] + ); +} + +// https://github.com/servo/rust-smallvec/issues/4 +#[test] +fn issue_4() { + SmallVec::<[Box; 2]>::new(); +} + +// https://github.com/servo/rust-smallvec/issues/5 +#[test] +fn issue_5() { + assert!(Some(SmallVec::<[&u32; 2]>::new()).is_some()); +} + +#[test] +fn test_with_capacity() { + let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(1); + assert!(v.is_empty()); + assert!(!v.spilled()); + assert_eq!(v.capacity(), 3); + + let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(10); + assert!(v.is_empty()); + assert!(v.spilled()); + assert_eq!(v.capacity(), 10); +} + +#[test] +fn drain() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(3); + assert_eq!(v.drain(..).collect::>(), &[3]); + + // spilling the vec + v.push(3); + v.push(4); + v.push(5); + let old_capacity = v.capacity(); + assert_eq!(v.drain(1..).collect::>(), &[4, 5]); + // drain should not change the capacity + assert_eq!(v.capacity(), old_capacity); + + // Exercise the tail-shifting code when in the inline state + // This has the potential to produce UB due to aliasing + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(1); + v.push(2); + assert_eq!(v.drain(..1).collect::>(), &[1]); +} + +#[test] +fn drain_rev() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(3); + assert_eq!(v.drain(..).rev().collect::>(), &[3]); + + // spilling the vec + v.push(3); + v.push(4); + v.push(5); + assert_eq!(v.drain(..).rev().collect::>(), &[5, 4, 3]); +} + +#[test] +fn drain_forget() { + let mut v: SmallVec<[u8; 1]> = smallvec![0, 1, 2, 3, 4, 5, 6, 7]; + std::mem::forget(v.drain(2..5)); + assert_eq!(v.len(), 2); +} + +#[test] +fn into_iter() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(3); + assert_eq!(v.into_iter().collect::>(), &[3]); + + // spilling the vec + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(3); + v.push(4); + v.push(5); + assert_eq!(v.into_iter().collect::>(), &[3, 4, 5]); +} + +#[test] +fn into_iter_rev() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(3); + assert_eq!(v.into_iter().rev().collect::>(), &[3]); + + // spilling the vec + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(3); + v.push(4); + v.push(5); + assert_eq!(v.into_iter().rev().collect::>(), &[5, 4, 3]); +} + +#[test] +fn into_iter_drop() { + use std::cell::Cell; + + struct DropCounter<'a>(&'a Cell); + + impl<'a> Drop for DropCounter<'a> { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } + } + + { + let cell = Cell::new(0); + let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); + v.push(DropCounter(&cell)); + v.into_iter(); + assert_eq!(cell.get(), 1); + } + + { + let cell = Cell::new(0); + let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); + v.push(DropCounter(&cell)); + v.push(DropCounter(&cell)); + assert!(v.into_iter().next().is_some()); + assert_eq!(cell.get(), 2); + } + + { + let cell = Cell::new(0); + let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); + v.push(DropCounter(&cell)); + v.push(DropCounter(&cell)); + v.push(DropCounter(&cell)); + assert!(v.into_iter().next().is_some()); + assert_eq!(cell.get(), 3); + } + { + let cell = Cell::new(0); + let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new(); + v.push(DropCounter(&cell)); + v.push(DropCounter(&cell)); + v.push(DropCounter(&cell)); + { + let mut it = v.into_iter(); + assert!(it.next().is_some()); + assert!(it.next_back().is_some()); + } + assert_eq!(cell.get(), 3); + } +} + +#[test] +fn test_capacity() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.reserve(1); + assert_eq!(v.capacity(), 2); + assert!(!v.spilled()); + + v.reserve_exact(0x100); + assert!(v.capacity() >= 0x100); + + v.push(0); + v.push(1); + v.push(2); + v.push(3); + + v.shrink_to_fit(); + assert!(v.capacity() < 0x100); +} + +#[test] +fn test_truncate() { + let mut v: SmallVec<[Box; 8]> = SmallVec::new(); + + for x in 0..8 { + v.push(Box::new(x)); + } + v.truncate(4); + + assert_eq!(v.len(), 4); + assert!(!v.spilled()); + + assert_eq!(*v.swap_remove(1), 1); + assert_eq!(*v.remove(1), 3); + v.insert(1, Box::new(3)); + + assert_eq!(&v.iter().map(|v| **v).collect::>(), &[0, 3, 2]); +} + +#[test] +fn test_insert_many() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.insert_many(1, [5, 6].iter().cloned()); + assert_eq!( + &v.iter().map(|v| *v).collect::>(), + &[0, 5, 6, 1, 2, 3] + ); +} + +struct MockHintIter { + x: T, + hint: usize, +} +impl Iterator for MockHintIter { + type Item = T::Item; + fn next(&mut self) -> Option { + self.x.next() + } + fn size_hint(&self) -> (usize, Option) { + (self.hint, None) + } +} + +#[test] +fn test_insert_many_short_hint() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.insert_many( + 1, + MockHintIter { + x: [5, 6].iter().cloned(), + hint: 5, + }, + ); + assert_eq!( + &v.iter().map(|v| *v).collect::>(), + &[0, 5, 6, 1, 2, 3] + ); +} + +#[test] +fn test_insert_many_long_hint() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.insert_many( + 1, + MockHintIter { + x: [5, 6].iter().cloned(), + hint: 1, + }, + ); + assert_eq!( + &v.iter().map(|v| *v).collect::>(), + &[0, 5, 6, 1, 2, 3] + ); +} + +// https://github.com/servo/rust-smallvec/issues/96 +mod insert_many_panic { + use crate::{smallvec, SmallVec}; + use alloc::boxed::Box; + + struct PanicOnDoubleDrop { + dropped: Box, + } + + impl PanicOnDoubleDrop { + fn new() -> Self { + Self { + dropped: Box::new(false), + } + } + } + + impl Drop for PanicOnDoubleDrop { + fn drop(&mut self) { + assert!(!*self.dropped, "already dropped"); + *self.dropped = true; + } + } + + /// Claims to yield `hint` items, but actually yields `count`, then panics. + struct BadIter { + hint: usize, + count: usize, + } + + impl Iterator for BadIter { + type Item = PanicOnDoubleDrop; + fn size_hint(&self) -> (usize, Option) { + (self.hint, None) + } + fn next(&mut self) -> Option { + if self.count == 0 { + panic!() + } + self.count -= 1; + Some(PanicOnDoubleDrop::new()) + } + } + + #[test] + fn panic_early_at_start() { + let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = + smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; + let result = ::std::panic::catch_unwind(move || { + vec.insert_many(0, BadIter { hint: 1, count: 0 }); + }); + assert!(result.is_err()); + } + + #[test] + fn panic_early_in_middle() { + let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = + smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; + let result = ::std::panic::catch_unwind(move || { + vec.insert_many(1, BadIter { hint: 4, count: 2 }); + }); + assert!(result.is_err()); + } + + #[test] + fn panic_early_at_end() { + let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = + smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; + let result = ::std::panic::catch_unwind(move || { + vec.insert_many(2, BadIter { hint: 3, count: 1 }); + }); + assert!(result.is_err()); + } + + #[test] + fn panic_late_at_start() { + let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = + smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; + let result = ::std::panic::catch_unwind(move || { + vec.insert_many(0, BadIter { hint: 3, count: 5 }); + }); + assert!(result.is_err()); + } + + #[test] + fn panic_late_at_end() { + let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> = + smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),]; + let result = ::std::panic::catch_unwind(move || { + vec.insert_many(2, BadIter { hint: 3, count: 5 }); + }); + assert!(result.is_err()); + } +} + +#[test] +#[should_panic] +fn test_invalid_grow() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + v.extend(0..8); + v.grow(5); +} + +#[test] +#[should_panic] +fn drain_overflow() { + let mut v: SmallVec<[u8; 8]> = smallvec![0]; + v.drain(..=std::usize::MAX); +} + +#[test] +fn test_insert_from_slice() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.insert_from_slice(1, &[5, 6]); + assert_eq!( + &v.iter().map(|v| *v).collect::>(), + &[0, 5, 6, 1, 2, 3] + ); +} + +#[test] +fn test_extend_from_slice() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.extend_from_slice(&[5, 6]); + assert_eq!( + &v.iter().map(|v| *v).collect::>(), + &[0, 1, 2, 3, 5, 6] + ); +} + +#[test] +#[should_panic] +fn test_drop_panic_smallvec() { + // This test should only panic once, and not double panic, + // which would mean a double drop + struct DropPanic; + + impl Drop for DropPanic { + fn drop(&mut self) { + panic!("drop"); + } + } + + let mut v = SmallVec::<[_; 1]>::new(); + v.push(DropPanic); +} + +#[test] +fn test_eq() { + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + let mut b: SmallVec<[u32; 2]> = SmallVec::new(); + let mut c: SmallVec<[u32; 2]> = SmallVec::new(); + // a = [1, 2] + a.push(1); + a.push(2); + // b = [1, 2] + b.push(1); + b.push(2); + // c = [3, 4] + c.push(3); + c.push(4); + + assert!(a == b); + assert!(a != c); +} + +#[test] +fn test_ord() { + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + let mut b: SmallVec<[u32; 2]> = SmallVec::new(); + let mut c: SmallVec<[u32; 2]> = SmallVec::new(); + // a = [1] + a.push(1); + // b = [1, 1] + b.push(1); + b.push(1); + // c = [1, 2] + c.push(1); + c.push(2); + + assert!(a < b); + assert!(b > a); + assert!(b < c); + assert!(c > b); +} + +#[test] +fn test_hash() { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hash; + + { + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + let b = [1, 2]; + a.extend(b.iter().cloned()); + let mut hasher = DefaultHasher::new(); + assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher)); + } + { + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + let b = [1, 2, 11, 12]; + a.extend(b.iter().cloned()); + let mut hasher = DefaultHasher::new(); + assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher)); + } +} + +#[test] +fn test_as_ref() { + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + a.push(1); + assert_eq!(a.as_ref(), [1]); + a.push(2); + assert_eq!(a.as_ref(), [1, 2]); + a.push(3); + assert_eq!(a.as_ref(), [1, 2, 3]); +} + +#[test] +fn test_as_mut() { + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + a.push(1); + assert_eq!(a.as_mut(), [1]); + a.push(2); + assert_eq!(a.as_mut(), [1, 2]); + a.push(3); + assert_eq!(a.as_mut(), [1, 2, 3]); + a.as_mut()[1] = 4; + assert_eq!(a.as_mut(), [1, 4, 3]); +} + +#[test] +fn test_borrow() { + use std::borrow::Borrow; + + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + a.push(1); + assert_eq!(a.borrow(), [1]); + a.push(2); + assert_eq!(a.borrow(), [1, 2]); + a.push(3); + assert_eq!(a.borrow(), [1, 2, 3]); +} + +#[test] +fn test_borrow_mut() { + use std::borrow::BorrowMut; + + let mut a: SmallVec<[u32; 2]> = SmallVec::new(); + a.push(1); + assert_eq!(a.borrow_mut(), [1]); + a.push(2); + assert_eq!(a.borrow_mut(), [1, 2]); + a.push(3); + assert_eq!(a.borrow_mut(), [1, 2, 3]); + BorrowMut::<[u32]>::borrow_mut(&mut a)[1] = 4; + assert_eq!(a.borrow_mut(), [1, 4, 3]); +} + +#[test] +fn test_from() { + assert_eq!(&SmallVec::<[u32; 2]>::from(&[1][..])[..], [1]); + assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]); + + let vec = vec![]; + let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec); + assert_eq!(&*small_vec, &[]); + drop(small_vec); + + let vec = vec![1, 2, 3, 4, 5]; + let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec); + assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + drop(small_vec); + + let vec = vec![1, 2, 3, 4, 5]; + let small_vec: SmallVec<[u8; 1]> = SmallVec::from(vec); + assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + drop(small_vec); + + let array = [1]; + let small_vec: SmallVec<[u8; 1]> = SmallVec::from(array); + assert_eq!(&*small_vec, &[1]); + drop(small_vec); + + let array = [99; 128]; + let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array); + assert_eq!(&*small_vec, vec![99u8; 128].as_slice()); + drop(small_vec); +} + +#[test] +fn test_from_slice() { + assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]); + assert_eq!( + &SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..], + [1, 2, 3] + ); +} + +#[test] +fn test_exact_size_iterator() { + let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]); + assert_eq!(vec.clone().into_iter().len(), 3); + assert_eq!(vec.drain(..2).len(), 2); + assert_eq!(vec.into_iter().len(), 1); +} + +#[test] +fn test_into_iter_as_slice() { + let vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]); + let mut iter = vec.clone().into_iter(); + assert_eq!(iter.as_slice(), &[1, 2, 3]); + assert_eq!(iter.as_mut_slice(), &[1, 2, 3]); + iter.next(); + assert_eq!(iter.as_slice(), &[2, 3]); + assert_eq!(iter.as_mut_slice(), &[2, 3]); + iter.next_back(); + assert_eq!(iter.as_slice(), &[2]); + assert_eq!(iter.as_mut_slice(), &[2]); +} + +#[test] +fn test_into_iter_clone() { + // Test that the cloned iterator yields identical elements and that it owns its own copy + // (i.e. no use after move errors). + let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter(); + let mut clone_iter = iter.clone(); + while let Some(x) = iter.next() { + assert_eq!(x, clone_iter.next().unwrap()); + } + assert_eq!(clone_iter.next(), None); +} + +#[test] +fn test_into_iter_clone_partially_consumed_iterator() { + // Test that the cloned iterator only contains the remaining elements of the original iterator. + let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter().skip(1); + let mut clone_iter = iter.clone(); + while let Some(x) = iter.next() { + assert_eq!(x, clone_iter.next().unwrap()); + } + assert_eq!(clone_iter.next(), None); +} + +#[test] +fn test_into_iter_clone_empty_smallvec() { + let mut iter = SmallVec::<[u8; 2]>::new().into_iter(); + let mut clone_iter = iter.clone(); + assert_eq!(iter.next(), None); + assert_eq!(clone_iter.next(), None); +} + +#[test] +fn shrink_to_fit_unspill() { + let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3); + vec.pop(); + assert!(vec.spilled()); + vec.shrink_to_fit(); + assert!(!vec.spilled(), "shrink_to_fit will un-spill if possible"); +} + +#[test] +fn test_into_vec() { + let vec = SmallVec::<[u8; 2]>::from_iter(0..2); + assert_eq!(vec.into_vec(), vec![0, 1]); + + let vec = SmallVec::<[u8; 2]>::from_iter(0..3); + assert_eq!(vec.into_vec(), vec![0, 1, 2]); +} + +#[test] +fn test_into_inner() { + let vec = SmallVec::<[u8; 2]>::from_iter(0..2); + assert_eq!(vec.into_inner(), Ok([0, 1])); + + let vec = SmallVec::<[u8; 2]>::from_iter(0..1); + assert_eq!(vec.clone().into_inner(), Err(vec)); + + let vec = SmallVec::<[u8; 2]>::from_iter(0..3); + assert_eq!(vec.clone().into_inner(), Err(vec)); +} + +#[test] +fn test_from_vec() { + let vec = vec![]; + let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); + assert_eq!(&*small_vec, &[]); + drop(small_vec); + + let vec = vec![]; + let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec); + assert_eq!(&*small_vec, &[]); + drop(small_vec); + + let vec = vec![1]; + let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); + assert_eq!(&*small_vec, &[1]); + drop(small_vec); + + let vec = vec![1, 2, 3]; + let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); + assert_eq!(&*small_vec, &[1, 2, 3]); + drop(small_vec); + + let vec = vec![1, 2, 3, 4, 5]; + let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec); + assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + drop(small_vec); + + let vec = vec![1, 2, 3, 4, 5]; + let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec); + assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]); + drop(small_vec); +} + +#[test] +fn test_retain() { + // Test inline data storate + let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]); + sv.retain(|&mut i| i != 3); + assert_eq!(sv.pop(), Some(4)); + assert_eq!(sv.pop(), Some(2)); + assert_eq!(sv.pop(), Some(1)); + assert_eq!(sv.pop(), None); + + // Test spilled data storage + let mut sv: SmallVec<[i32; 3]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]); + sv.retain(|&mut i| i != 3); + assert_eq!(sv.pop(), Some(4)); + assert_eq!(sv.pop(), Some(2)); + assert_eq!(sv.pop(), Some(1)); + assert_eq!(sv.pop(), None); + + // Test that drop implementations are called for inline. + let one = Rc::new(1); + let mut sv: SmallVec<[Rc; 3]> = SmallVec::new(); + sv.push(Rc::clone(&one)); + assert_eq!(Rc::strong_count(&one), 2); + sv.retain(|_| false); + assert_eq!(Rc::strong_count(&one), 1); + + // Test that drop implementations are called for spilled data. + let mut sv: SmallVec<[Rc; 1]> = SmallVec::new(); + sv.push(Rc::clone(&one)); + sv.push(Rc::new(2)); + assert_eq!(Rc::strong_count(&one), 2); + sv.retain(|_| false); + assert_eq!(Rc::strong_count(&one), 1); +} + +#[test] +fn test_dedup() { + let mut dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 2, 3, 3]); + dupes.dedup(); + assert_eq!(&*dupes, &[1, 2, 3]); + + let mut empty: SmallVec<[i32; 5]> = SmallVec::new(); + empty.dedup(); + assert!(empty.is_empty()); + + let mut all_ones: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 1, 1, 1]); + all_ones.dedup(); + assert_eq!(all_ones.len(), 1); + + let mut no_dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 4, 5]); + no_dupes.dedup(); + assert_eq!(no_dupes.len(), 5); +} + +#[test] +fn test_resize() { + let mut v: SmallVec<[i32; 8]> = SmallVec::new(); + v.push(1); + v.resize(5, 0); + assert_eq!(v[..], [1, 0, 0, 0, 0][..]); + + v.resize(2, -1); + assert_eq!(v[..], [1, 0][..]); +} + +#[cfg(feature = "write")] +#[test] +fn test_write() { + use std::io::Write; + + let data = [1, 2, 3, 4, 5]; + + let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new(); + let len = small_vec.write(&data[..]).unwrap(); + assert_eq!(len, 5); + assert_eq!(small_vec.as_ref(), data.as_ref()); + + let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new(); + small_vec.write_all(&data[..]).unwrap(); + assert_eq!(small_vec.as_ref(), data.as_ref()); +} + +#[cfg(feature = "serde")] +#[test] +fn test_serde() { + use bincode::{config, deserialize}; + let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new(); + small_vec.push(1); + let encoded = config().limit(100).serialize(&small_vec).unwrap(); + let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap(); + assert_eq!(small_vec, decoded); + small_vec.push(2); + // Spill the vec + small_vec.push(3); + small_vec.push(4); + // Check again after spilling. + let encoded = config().limit(100).serialize(&small_vec).unwrap(); + let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap(); + assert_eq!(small_vec, decoded); +} + +#[test] +fn grow_to_shrink() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(1); + v.push(2); + v.push(3); + assert!(v.spilled()); + v.clear(); + // Shrink to inline. + v.grow(2); + assert!(!v.spilled()); + assert_eq!(v.capacity(), 2); + assert_eq!(v.len(), 0); + v.push(4); + assert_eq!(v[..], [4]); +} + +#[test] +fn resumable_extend() { + let s = "a b c"; + // This iterator yields: (Some('a'), None, Some('b'), None, Some('c')), None + let it = s + .chars() + .scan(0, |_, ch| if ch.is_whitespace() { None } else { Some(ch) }); + let mut v: SmallVec<[char; 4]> = SmallVec::new(); + v.extend(it); + assert_eq!(v[..], ['a']); +} + +// #139 +#[test] +fn uninhabited() { + enum Void {} + let _sv = SmallVec::<[Void; 8]>::new(); +} + +#[test] +fn grow_spilled_same_size() { + let mut v: SmallVec<[u8; 2]> = SmallVec::new(); + v.push(0); + v.push(1); + v.push(2); + assert!(v.spilled()); + assert_eq!(v.capacity(), 4); + // grow with the same capacity + v.grow(4); + assert_eq!(v.capacity(), 4); + assert_eq!(v[..], [0, 1, 2]); +} + +#[cfg(feature = "const_generics")] +#[test] +fn const_generics() { + let _v = SmallVec::<[i32; 987]>::default(); +} + +#[cfg(feature = "const_new")] +#[test] +fn const_new() { + let v = const_new_inner(); + assert_eq!(v.capacity(), 4); + assert_eq!(v.len(), 0); + let v = const_new_inline_sized(); + assert_eq!(v.capacity(), 4); + assert_eq!(v.len(), 4); + assert_eq!(v[0], 1); + let v = const_new_inline_args(); + assert_eq!(v.capacity(), 2); + assert_eq!(v.len(), 2); + assert_eq!(v[0], 1); + assert_eq!(v[1], 4); + let v = const_new_with_len(); + assert_eq!(v.capacity(), 4); + assert_eq!(v.len(), 3); + assert_eq!(v[0], 2); + assert_eq!(v[1], 5); + assert_eq!(v[2], 7); +} +#[cfg(feature = "const_new")] +const fn const_new_inner() -> SmallVec<[i32; 4]> { + SmallVec::<[i32; 4]>::new_const() +} +#[cfg(feature = "const_new")] +const fn const_new_inline_sized() -> SmallVec<[i32; 4]> { + crate::smallvec_inline![1; 4] +} +#[cfg(feature = "const_new")] +const fn const_new_inline_args() -> SmallVec<[i32; 2]> { + crate::smallvec_inline![1, 4] +} +#[cfg(feature = "const_new")] +const fn const_new_with_len() -> SmallVec<[i32; 4]> { + unsafe { + SmallVec::<[i32; 4]>::from_const_with_len_unchecked([2, 5, 7, 0], 3) + } +} + +#[test] +fn empty_macro() { + let _v: SmallVec<[u8; 1]> = smallvec![]; +} + +#[test] +fn zero_size_items() { + SmallVec::<[(); 0]>::new().push(()); +} + +#[test] +fn test_insert_many_overflow() { + let mut v: SmallVec<[u8; 1]> = SmallVec::new(); + v.push(123); + + // Prepare an iterator with small lower bound + let iter = (0u8..5).filter(|n| n % 2 == 0); + assert_eq!(iter.size_hint().0, 0); + + v.insert_many(0, iter); + assert_eq!(&*v, &[0, 2, 4, 123]); +} + +#[test] +fn test_clone_from() { + let mut a: SmallVec<[u8; 2]> = SmallVec::new(); + a.push(1); + a.push(2); + a.push(3); + + let mut b: SmallVec<[u8; 2]> = SmallVec::new(); + b.push(10); + + let mut c: SmallVec<[u8; 2]> = SmallVec::new(); + c.push(20); + c.push(21); + c.push(22); + + a.clone_from(&b); + assert_eq!(&*a, &[10]); + + b.clone_from(&c); + assert_eq!(&*b, &[20, 21, 22]); +} + +#[test] +fn test_size() { + use core::mem::size_of; + assert_eq!(24, size_of::>()); +} + +#[cfg(feature = "drain_filter")] +#[test] +fn drain_filter() { + let mut a: SmallVec<[u8; 2]> = smallvec![1u8, 2, 3, 4, 5, 6, 7, 8]; + + let b: SmallVec<[u8; 2]> = a.drain_filter(|x| *x % 3 == 0).collect(); + + assert_eq!(a, SmallVec::<[u8; 2]>::from_slice(&[1u8, 2, 4, 5, 7, 8])); + assert_eq!(b, SmallVec::<[u8; 2]>::from_slice(&[3u8, 6])); +} + +#[cfg(feature = "drain_keep_rest")] +#[test] +fn drain_keep_rest() { + let mut a: SmallVec<[i32; 3]> = smallvec![1i32, 2, 3, 4, 5, 6, 7, 8]; + let mut df = a.drain_filter(|x| *x % 2 == 0); + + assert_eq!(df.next().unwrap(), 2); + assert_eq!(df.next().unwrap(), 4); + + df.keep_rest(); + + assert_eq!(a, SmallVec::<[i32; 3]>::from_slice(&[1i32, 3, 5, 6, 7, 8])); +} diff --git a/utshell-0.5.0/vendor/smallvec/tests/debugger_visualizer.rs b/utshell-0.5.0/vendor/smallvec/tests/debugger_visualizer.rs new file mode 100644 index 00000000..b39aa9d9 --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/tests/debugger_visualizer.rs @@ -0,0 +1,68 @@ +use debugger_test::debugger_test; +use smallvec::{smallvec, SmallVec}; + +#[inline(never)] +fn __break() {} + +#[debugger_test( + debugger = "cdb", + commands = r#" +.nvlist +dx sv + +g + +dx sv + +g + +dx sv +"#, + expected_statements = r#" +sv : { len=0x2 is_inline=true } [Type: smallvec::SmallVec >] + [] [Type: smallvec::SmallVec >] + [capacity] : 4 + [len] : 0x2 [Type: unsigned __int64] + [0] : 1 [Type: int] + [1] : 2 [Type: int] + +sv : { len=0x5 is_inline=false } [Type: smallvec::SmallVec >] + [] [Type: smallvec::SmallVec >] + [capacity] : 0x8 [Type: unsigned __int64] + [len] : 0x5 [Type: unsigned __int64] + [0] : 5 [Type: int] + [1] : 2 [Type: int] + [2] : 3 [Type: int] + [3] : 4 [Type: int] + [4] : 5 [Type: int] + +sv : { len=0x5 is_inline=false } [Type: smallvec::SmallVec >] + [] [Type: smallvec::SmallVec >] + [capacity] : 0x8 [Type: unsigned __int64] + [len] : 0x5 [Type: unsigned __int64] + [0] : 2 [Type: int] + [1] : 3 [Type: int] + [2] : 4 [Type: int] + [3] : 5 [Type: int] + [4] : 5 [Type: int] +"# +)] +#[inline(never)] +fn test_debugger_visualizer() { + // This SmallVec can hold up to 4 items on the stack: + let mut sv: SmallVec<[i32; 4]> = smallvec![1, 2]; + __break(); + + // Overfill the SmallVec to move its contents to the heap + for i in 3..6 { + sv.push(i); + } + + // Update the contents of the first value of the SmallVec. + sv[0] = sv[1] + sv[2]; + __break(); + + // Sort the SmallVec in place. + sv.sort(); + __break(); +} diff --git a/utshell-0.5.0/vendor/smallvec/tests/macro.rs b/utshell-0.5.0/vendor/smallvec/tests/macro.rs new file mode 100644 index 00000000..fa52e79b --- /dev/null +++ b/utshell-0.5.0/vendor/smallvec/tests/macro.rs @@ -0,0 +1,24 @@ +/// This file tests `smallvec!` without actually having the macro in scope. +/// This forces any recursion to use a `$crate` prefix to reliably find itself. + +#[test] +fn smallvec() { + let mut vec: smallvec::SmallVec<[i32; 2]>; + + macro_rules! check { + ($init:tt) => { + vec = smallvec::smallvec! $init; + assert_eq!(*vec, *vec! $init); + } + } + + check!([0; 0]); + check!([1; 1]); + check!([2; 2]); + check!([3; 3]); + + check!([]); + check!([1]); + check!([1, 2]); + check!([1, 2, 3]); +} diff --git a/utshell-0.5.0/vendor/stable_deref_trait/.cargo-checksum.json b/utshell-0.5.0/vendor/stable_deref_trait/.cargo-checksum.json new file mode 100644 index 00000000..4070feb6 --- /dev/null +++ b/utshell-0.5.0/vendor/stable_deref_trait/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5a8352eba01791ecee28b37cfe1324fa48db52e35023b23a4f07ca84267abfd6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5e05b024f653a5ce199e77cbbbd42fb5553562ec714b819421ed0c3e552a75d7","README.md":"750fc2d57412de57566289e567b5674a666cc7a8a054f8c7129b8553f9003de7","src/lib.rs":"c68d43e0ec2727653cc2d37c396c8e60c9ed315b71aab331da8177b129887591"},"package":"a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/stable_deref_trait/Cargo.toml b/utshell-0.5.0/vendor/stable_deref_trait/Cargo.toml new file mode 100644 index 00000000..6bc26c3d --- /dev/null +++ b/utshell-0.5.0/vendor/stable_deref_trait/Cargo.toml @@ -0,0 +1,27 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "stable_deref_trait" +version = "1.2.0" +authors = ["Robert Grosse "] +description = "An unsafe marker trait for types like Box and Rc that dereference to a stable address even when moved, and hence can be used with libraries such as owning_ref and rental.\n" +documentation = "https://docs.rs/stable_deref_trait/1.2.0/stable_deref_trait" +readme = "README.md" +categories = ["memory-management", "no-std"] +license = "MIT/Apache-2.0" +repository = "https://github.com/storyyeller/stable_deref_trait" + +[features] +alloc = [] +default = ["std"] +std = ["alloc"] diff --git a/utshell-0.5.0/vendor/stable_deref_trait/LICENSE-APACHE b/utshell-0.5.0/vendor/stable_deref_trait/LICENSE-APACHE new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/utshell-0.5.0/vendor/stable_deref_trait/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/utshell-0.5.0/vendor/stable_deref_trait/LICENSE-MIT b/utshell-0.5.0/vendor/stable_deref_trait/LICENSE-MIT new file mode 100644 index 00000000..3bf61a09 --- /dev/null +++ b/utshell-0.5.0/vendor/stable_deref_trait/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Robert Grosse + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/utshell-0.5.0/vendor/stable_deref_trait/README.md b/utshell-0.5.0/vendor/stable_deref_trait/README.md new file mode 100644 index 00000000..24fd4b09 --- /dev/null +++ b/utshell-0.5.0/vendor/stable_deref_trait/README.md @@ -0,0 +1,23 @@ +This crate defines an unsafe marker trait, StableDeref, for container types which deref to a fixed address which is valid even when the containing type is moved. For example, Box, Vec, Rc, Arc and String implement this trait. Additionally, it defines CloneStableDeref for types like Rc where clones deref to the same address. + +It is intended to be used by crates such as [owning_ref](https://crates.io/crates/owning_ref) and [rental](https://crates.io/crates/rental), as well as library authors who wish to make their code interoperable with such crates. For example, if you write a custom Vec type, you can implement StableDeref, and then users will be able to use your custom Vec type together with owning_ref and rental. + +no_std support can be enabled by disabling default features (specifically "std"). In this case, the trait will not be implemented for the std types mentioned above, but you can still use it for your own types. + +Enable the "alloc" feature (with default-features disabled) to have this trait be implemented for the above types from the built-in `alloc` crate, specifically +* `alloc::boxed::Box` +* `alloc::vec::Vec` +* `alloc::rc::Rc` +* `alloc::arc::Arc` +* `alloc::string::String` + +For example, this crate can be built with alloc support via the following command: +`cargo build --no-default-features --features alloc` + +Or added as a `Cargo.toml` dependency as follows: +``` +[dependencies.stable_deref_trait] +version = "" +default-features = false +features = [ "alloc" ] +``` diff --git a/utshell-0.5.0/vendor/stable_deref_trait/src/lib.rs b/utshell-0.5.0/vendor/stable_deref_trait/src/lib.rs new file mode 100644 index 00000000..069f6cc2 --- /dev/null +++ b/utshell-0.5.0/vendor/stable_deref_trait/src/lib.rs @@ -0,0 +1,189 @@ +// Copyright 2017 Robert Grosse + +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! +This module defines an unsafe marker trait, StableDeref, for container types that deref to a fixed address which is valid even when the containing type is moved. For example, Box, Vec, Rc, Arc and String implement this trait. Additionally, it defines CloneStableDeref for types like Rc where clones deref to the same address. + +It is intended to be used by crates such as [owning_ref](https://crates.io/crates/owning_ref) and [rental](https://crates.io/crates/rental), as well as library authors who wish to make their code interoperable with such crates. For example, if you write a custom Vec type, you can implement StableDeref, and then users will be able to use your custom type together with owning_ref and rental. + +no_std support can be enabled by disabling default features (specifically "std"). In this case, the trait will not be implemented for the std types mentioned above, but you can still use it for your own types. +*/ + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +extern crate core; + +#[cfg(feature = "alloc")] +extern crate alloc; + +use core::ops::Deref; + + +/** +An unsafe marker trait for types that deref to a stable address, even when moved. For example, this is implemented by Box, Vec, Rc, Arc and String, among others. Even when a Box is moved, the underlying storage remains at a fixed location. + +More specifically, implementors must ensure that the result of calling deref() is valid for the lifetime of the object, not just the lifetime of the borrow, and that the deref is valid even if the object is moved. Also, it must be valid even after invoking arbitrary &self methods or doing anything transitively accessible from &Self. If Self also implements DerefMut, the same restrictions apply to deref_mut() and it must remain valid if anything transitively accessible from the result of deref_mut() is mutated/called. Additionally, multiple calls to deref, (and deref_mut if implemented) must return the same address. No requirements are placed on &mut self methods other than deref_mut() and drop(), if applicable. + +Basically, it must be valid to convert the result of deref() to a pointer, and later dereference that pointer, as long as the original object is still live, even if it has been moved or &self methods have been called on it. If DerefMut is also implemented, it must be valid to get pointers from deref() and deref_mut() and dereference them while the object is live, as long as you don't simultaneously dereference both of them. + +Additionally, Deref and DerefMut implementations must not panic, but users of the trait are not allowed to rely on this fact (so that this restriction can be removed later without breaking backwards compatibility, should the need arise). + +Here are some examples to help illustrate the requirements for implementing this trait: + +``` +# use std::ops::Deref; +struct Foo(u8); +impl Deref for Foo { + type Target = u8; + fn deref(&self) -> &Self::Target { &self.0 } +} +``` + +Foo cannot implement StableDeref because the int will move when Foo is moved, invalidating the result of deref(). + +``` +# use std::ops::Deref; +struct Foo(Box); +impl Deref for Foo { + type Target = u8; + fn deref(&self) -> &Self::Target { &*self.0 } +} +``` + +Foo can safely implement StableDeref, due to the use of Box. + + +``` +# use std::ops::Deref; +# use std::ops::DerefMut; +# use std::rc::Rc; +#[derive(Clone)] +struct Foo(Rc); +impl Deref for Foo { + type Target = u8; + fn deref(&self) -> &Self::Target { &*self.0 } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { Rc::make_mut(&mut self.0) } +} +``` + +This is a simple implementation of copy-on-write: Foo's deref_mut will copy the underlying int if it is not uniquely owned, ensuring unique access at the point where deref_mut() returns. However, Foo cannot implement StableDeref because calling deref_mut(), followed by clone().deref() will result in mutable and immutable references to the same location. Note that if the DerefMut implementation were removed, Foo could safely implement StableDeref. Likewise, if the Clone implementation were removed, it would be safe to implement StableDeref, although Foo would not be very useful in that case, (without clones, the rc will always be uniquely owned). + + +``` +# use std::ops::Deref; +struct Foo; +impl Deref for Foo { + type Target = str; + fn deref(&self) -> &Self::Target { &"Hello" } +} +``` +Foo can safely implement StableDeref. It doesn't own the data being derefed, but the data is gaurenteed to live long enough, due to it being 'static. + +``` +# use std::ops::Deref; +# use std::cell::Cell; +struct Foo(Cell); +impl Deref for Foo { + type Target = str; + fn deref(&self) -> &Self::Target { + let b = self.0.get(); + self.0.set(!b); + if b { &"Hello" } else { &"World" } + } +} +``` +Foo cannot safely implement StableDeref, even though every possible result of deref lives long enough. In order to safely implement StableAddress, multiple calls to deref must return the same result. + +``` +# use std::ops::Deref; +# use std::ops::DerefMut; +struct Foo(Box<(u8, u8)>); +impl Deref for Foo { + type Target = u8; + fn deref(&self) -> &Self::Target { &self.0.deref().0 } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0.deref_mut().1 } +} +``` + +Foo cannot implement StableDeref because deref and deref_mut return different addresses. + + +*/ +pub unsafe trait StableDeref: Deref {} + +/** +An unsafe marker trait for types where clones deref to the same address. This has all the requirements of StableDeref, and additionally requires that after calling clone(), both the old and new value deref to the same address. For example, Rc and Arc implement CloneStableDeref, but Box and Vec do not. + +Note that a single type should never implement both DerefMut and CloneStableDeref. If it did, this would let you get two mutable references to the same location, by cloning and then calling deref_mut() on both values. +*/ +pub unsafe trait CloneStableDeref: StableDeref + Clone {} + +///////////////////////////////////////////////////////////////////////////// +// std types integration +///////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::rc::Rc; +#[cfg(feature = "alloc")] +use alloc::sync::Arc; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +#[cfg(feature = "alloc")] +use alloc::string::String; + +#[cfg(feature = "std")] +use std::ffi::{CString, OsString}; +#[cfg(feature = "std")] +use std::path::PathBuf; +#[cfg(feature = "std")] +use std::sync::{MutexGuard, RwLockReadGuard, RwLockWriteGuard}; + +use core::cell::{Ref, RefMut}; + + +#[cfg(feature = "alloc")] +unsafe impl StableDeref for Box {} +#[cfg(feature = "alloc")] +unsafe impl StableDeref for Vec {} +#[cfg(feature = "alloc")] +unsafe impl StableDeref for String {} +#[cfg(feature = "std")] +unsafe impl StableDeref for CString {} +#[cfg(feature = "std")] +unsafe impl StableDeref for OsString {} +#[cfg(feature = "std")] +unsafe impl StableDeref for PathBuf {} + +#[cfg(feature = "alloc")] +unsafe impl StableDeref for Rc {} +#[cfg(feature = "alloc")] +unsafe impl CloneStableDeref for Rc {} +#[cfg(feature = "alloc")] +unsafe impl StableDeref for Arc {} +#[cfg(feature = "alloc")] +unsafe impl CloneStableDeref for Arc {} + +unsafe impl<'a, T: ?Sized> StableDeref for Ref<'a, T> {} +unsafe impl<'a, T: ?Sized> StableDeref for RefMut<'a, T> {} +#[cfg(feature = "std")] +unsafe impl<'a, T: ?Sized> StableDeref for MutexGuard<'a, T> {} +#[cfg(feature = "std")] +unsafe impl<'a, T: ?Sized> StableDeref for RwLockReadGuard<'a, T> {} +#[cfg(feature = "std")] +unsafe impl<'a, T: ?Sized> StableDeref for RwLockWriteGuard<'a, T> {} + +unsafe impl<'a, T: ?Sized> StableDeref for &'a T {} +unsafe impl<'a, T: ?Sized> CloneStableDeref for &'a T {} +unsafe impl<'a, T: ?Sized> StableDeref for &'a mut T {} diff --git a/utshell-0.5.0/vendor/syn/.cargo-checksum.json b/utshell-0.5.0/vendor/syn/.cargo-checksum.json new file mode 100644 index 00000000..e1d6c63a --- /dev/null +++ b/utshell-0.5.0/vendor/syn/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"096d9ca68883d01d86e64db90df5591fad182fa4a2e48fab75747164910bc451","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f6904878f9082d7d267b6d0d737ef211ff165cfd039a4d45ad88e9861f3e217f","benches/file.rs":"0a0527c78d849148cbb6118b4d36f72da7d4add865ba1a410e0a1be9e8dbfe0e","benches/rust.rs":"02585b90de2404241ed167f34d1d21da950ef48f1e3d7f718f4e01a5e3795e14","src/attr.rs":"7dc328025f9def00f634b1de958a93ac2b2f3fdfb11411600861c556bc821262","src/bigint.rs":"0299829b2f7a1a798fe2f7bc1680e4a10f9b6f4a852d09af4da2deab466c4242","src/buffer.rs":"30a9fffaf1b7a4fd8ca7eed5a9cde7a13d75d0b7b92569975bee1e7083d2555e","src/custom_keyword.rs":"b2e25cbe73d237b459140a38083ee21e4836ea444859b033f400652414630290","src/custom_punctuation.rs":"c2c344c9cdbebc66a5833eb0f9ded817ce9807dbb75b616283b2b60960d1ffb0","src/data.rs":"921eecc6a9909004019922c2f8fe217f45f75556c8d7e59d731c43b825330539","src/derive.rs":"8bb147e2e4490ccd891d71c5889904fb2718a2204d4597e337b3a8926f0fd52c","src/discouraged.rs":"c9b99a0447514d293a18cd5f61bdb257700c467cb74a60dd172fda9991bc8582","src/drops.rs":"013385f1dd95663f1afab41abc1e2eea04181998644828935ca564c74d6462ae","src/error.rs":"f0d80891d42459ae9d490f2c5a749b501f3d06acc6ae2429c3558fd5dea38d0d","src/export.rs":"b260cc49da1da3489e7755832bc8015cfad79e84f6c74e237f65ae25a2385e56","src/expr.rs":"ce965ff999c27eb1b779d3ee17e19fe1b3648ce8c3ed112ef9b8b87fb74396c9","src/ext.rs":"ed143b029af286e62ceb4310286a4ce894792dd588465face042b4199b39d329","src/file.rs":"b608c101bab989ede6dcf1fc5d4b5b9a710c2c324f0e27a47dab1d5aff598e1d","src/gen/clone.rs":"0f452c91a02d94a8b093226f438b39116025e49ed318d9e7c4ef20649039839d","src/gen/debug.rs":"e76f1b4ac8d81160f88e2b052dc30ecb0be2c0fe910751fe9aa43664dcec9670","src/gen/eq.rs":"1cf713c2f0cf3995b3fad5a1bc82d25370aeeb2409699bbf6a20b9773fcc8b81","src/gen/fold.rs":"c7b2265eb17dc3a1ba48d8245077fa0155e66dc51d368355511af0391e655034","src/gen/hash.rs":"e9e9533c6862373826835229521343cdf81ae4107f40b35ca47138a31d5b5e0a","src/gen/visit.rs":"d0407584b46d39f3c914b5732ff9643727a18c4b397d7df7dd378985be3ab333","src/gen/visit_mut.rs":"cb298bbd475f18f71cdf1156a43d173a1da642c39035c8b8d813e3a4b2246d04","src/gen_helper.rs":"750caab67ba0ba11a95ea28cd38026485227bb4aa114cdb497472386f60fdb35","src/generics.rs":"628f5d7157106db018b6f901e6c85b5c40a9c4b3cdf2bb4787691d5f570f6bc0","src/group.rs":"f5911e9cf2dc2dffab546590167c48de30409cb7708aa3307d22be143df720e4","src/ident.rs":"f93f74d04776e749607e944e30ce4396ec146dce41c64710f4cd7f323b75dca4","src/item.rs":"f5ca9a2de9a4d1dbe638f671870a4feca6590dce279b34457069383dce8d4c3a","src/lib.rs":"9322106e691792b51e601bb8f1a6a4bda17e4988a1259d64bf1d83d62ce66967","src/lifetime.rs":"f77ac2f4ee9205c71db9c6b63e1b90eac4b5ecfa330c553b7bbbf5400a65150b","src/lit.rs":"cb30dfbeda8ee8d9859c46759ad7837a14ded79d522be23137111522a4e5e39f","src/lookahead.rs":"376092f91a1c32e1b277db0a6790fdda151c9ec51bd971fe6a6545b5b9e73b5d","src/mac.rs":"deacf75bb99af8ea0d6a5ca54504b75b8cf9d814ad7d4148bb5d533c7f1e1aed","src/macros.rs":"e68e246752d67307f9afb5ada6c1d689ddc0b0d9a51d40ba6191427d1e1b8bdc","src/meta.rs":"969d8ccbdbc6ea2e4928a21831b791c57447b231e1373149e4c63b46f3951801","src/op.rs":"410a5cbc596afa81cfdf66c65ba2e21be7105b819a2a705dc0c0e6363ff1a715","src/parse.rs":"3da4e04afb84f9c955d90cfd47e987b11add203bee53dfb53c5af593e6fe4bf6","src/parse_macro_input.rs":"4a753b2a6dbfefd6dc93852d66b4f6d73ebd6b8b9be74019fc476f429b9a892d","src/parse_quote.rs":"c9065c39465543f91828d207d73354372a5aeda1d8d76c6ce47ddb7c33677c66","src/pat.rs":"d1fb776758e2fd74b3ef14d205d28c62e4bfd4279b37b7ca30af2683b51f6045","src/path.rs":"c5a496bb7911685cbf14c8a4526f1821139409779b8d3145f6c7c67ebb067ba2","src/print.rs":"22910bf0521ab868ebd7c62601c55912d12cfb400c65723e08e5cfa3a2d111c0","src/punctuated.rs":"e7e148c5d52713a6bf3f2057c251836dabd78feeee1f533c0baf7a1a83ee5806","src/restriction.rs":"e3bfe3c43083640224557f2130a8ea543ad929df66cb511d5ad661f534e3ab6b","src/sealed.rs":"6ece3b3dcb30f6bb98b93d83759ca7712ee8592bef9c0511141039c38765db0e","src/span.rs":"0a48e375e5c9768f6f64174a91ba6a255f4b021e2fb3548d8494e617f142601b","src/spanned.rs":"4b9bd65f60ab81922adfd0be8f03b6d50e98da3a5f525f242f9639aec4beac79","src/stmt.rs":"a4e7e9bea8b0d972499b92c2d19fa3f34e2fe4c32ed77198b2b88a30d1e445e0","src/thread.rs":"1f1deb1272525ab2af9a36aac4bce8f65b0e315adb1656641fd7075662f49222","src/token.rs":"e6b2373fb0465158d267bd25eac16266bd4b492d7dbe8ae4b5405a841a1ac57d","src/tt.rs":"32490509abcc4a5a3c7eb5628337172b3b49d30697d2f7b7df4d8045255c13da","src/ty.rs":"e5f754d037bfc32a99dc5bddbba05c6b405e3b2655d95fdcab05d6d8cf17612d","src/verbatim.rs":"87cbe82a90f48efb57ffd09141042698b3e011a21d0d5412154d80324b0a5ef0","src/whitespace.rs":"718a80c12cdd145358e2690f0f68ff7779a91ec17ce9fde9bb755f635fce69ad","tests/common/eq.rs":"396f03496a2c648bb2700a390cb32b11c74615235b449f5a2a6185fff04e2927","tests/common/mod.rs":"432ad35577f836a20b517d8c26ed994ac25fe73ef2f461c67688b61b99762015","tests/common/parse.rs":"a69236cfb2f73bb83bddd4c20a4130a73d1d8b74679eda3272bc5098a5b4d534","tests/debug/gen.rs":"daa5be1f3dc2379d5067137e0106874e0f3ed5eba7f2a8436fdada0bf33d7186","tests/debug/mod.rs":"b56136586267ae1812a937b69215dd053ada2c21717771d89dcd3ce52bcb27f5","tests/macros/mod.rs":"64b0da858096e7cf0f772e66bc1787a867e45897d7677de580c0a1f35c0f6852","tests/regression.rs":"e9565ea0efecb4136f099164ffcfa26e1996b0a27fb9c6659e90ad9bdd42e7b6","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/regression/issue1235.rs":"a2266b10c3f7c7af5734817ab0a3e8b309b51e7d177b63f26e67e6b744d280b0","tests/repo/mod.rs":"d92f0f9afa0613e95ab8ed1e7ec9b4d863b6eff5b790371ed8eac86f44902bf1","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"8982f6bc4e36510f924e288247473403e72697389ce9dda4e4b5ab0a8e49259f","tests/test_attribute.rs":"b35550a43bbd187bb330997ba36f90c65d8fc489135b1d32ef4547f145cb7612","tests/test_derive_input.rs":"99c4e6e45e3322ea9e269b309059c8a00fda1dcc03aed41f6e7d8c7e0a72fa2b","tests/test_expr.rs":"f7726efc959b860aa8aca6c51bc10c466cb1957774c1dfac24c3907cd8ea99a6","tests/test_generics.rs":"2fcc8575d695b568f3724b3b33d853b8fa6d9864eb816b5e3ca82420682e6155","tests/test_grouping.rs":"ecbe3324878b2e2be42640a3dec198620cff18731fcb95ee7e94eacd11d2fec1","tests/test_ident.rs":"9eb53d1e21edf23e7c9e14dc74dcc2b2538e9221e19dbcc0a44e3acc2e90f3f6","tests/test_item.rs":"9398997f2be33c89de52eb40f8c2fce86cf4ce5810fe709d2f20916ed6e2bb47","tests/test_iterators.rs":"f4dacb5f3a8e0473dfb0d27f05270d41e79eddb4759b1fad3e88e379b4731e17","tests/test_lit.rs":"8e30c2d7837673a742d77aef01212788bbd099182dd5c1d10ee474cfeb786c39","tests/test_meta.rs":"70fd75b42d1d913f05825c9e8280a4802e81de0b2343ad876850d2b7c588f0bf","tests/test_parse_buffer.rs":"92f5e898c1a6625011497f8cc8684eac0311850566ae9ab1848444305c9bdddf","tests/test_parse_quote.rs":"5bb7ec6773c3b878b3abedf17952948e707d8990b7e131605ee03d31f9ecae5b","tests/test_parse_stream.rs":"91a7ec997ea67d3c9d3028495345d89f2f67eb01bf11af3f99a1cef42a41aa05","tests/test_pat.rs":"8467fbef7cba36e6ce105cbc1a038b13ec154505bd34c863a18cfdfeac02c0b1","tests/test_path.rs":"b202244f034e58bf17e4c39bef696b0567e0ed42a63427ed4866acd14aaa90df","tests/test_precedence.rs":"f8b57c4a10ad249d3c6984cbe5db56a0c1e1381900dbc837fdc6f0e7f19221a7","tests/test_receiver.rs":"af64117acd66fbf42edc476f731ecd20c88009d9cb641dbd7a1d6384ae99ae73","tests/test_round_trip.rs":"23081225e68451398402d261c715cae897c84bcf0ca251f685a0603ba740a0da","tests/test_shebang.rs":"98e8a6690c04e0aad2893b747593620b51836fe704f50f5c6fe352609837138a","tests/test_should_parse.rs":"1d3535698a446e2755bfc360676bdb161841a1f454cdef6e7556c6d06a95c89d","tests/test_size.rs":"b446868d55ae820196aad03dba3aa3529b727ac0465113c6fc66706423a73350","tests/test_stmt.rs":"761946f7d020f37dcc9f3a6c4b17c8d26c30d609193ac13c0672a2833b80f6dc","tests/test_token_trees.rs":"d012da9c3c861073711b006bf6ffdc073821fb9fb0a08733628cdae57124d1f5","tests/test_ty.rs":"e0262eb0c65c06a5bd8781cf0e256d7f093182202e8160623f00de98594845d2","tests/test_visibility.rs":"cf4c93997cd88821ef7f8e2dd5d1586175cce4614407cd3bdf371ecc4d8abc44","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c"} \ No newline at end of file diff --git a/utshell-0.5.0/vendor/syn/Cargo.toml b/utshell-0.5.0/vendor/syn/Cargo.toml new file mode 100644 index 00000000..8ff76184 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/Cargo.toml @@ -0,0 +1,147 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.56" +name = "syn" +version = "2.0.51" +authors = ["David Tolnay "] +include = [ + "/benches/**", + "/Cargo.toml", + "/LICENSE-APACHE", + "/LICENSE-MIT", + "/README.md", + "/src/**", + "/tests/**", +] +description = "Parser for Rust source code" +documentation = "https://docs.rs/syn" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = [ + "development-tools::procedural-macro-helpers", + "parser-implementations", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/syn" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = [ + "--cfg", + "doc_cfg", + "--generate-link-to-definition", +] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = [ + "full", + "visit", + "visit-mut", + "fold", + "extra-traits", +] + +[lib] +doc-scrape-examples = false + +[[bench]] +name = "rust" +harness = false +required-features = [ + "full", + "parsing", +] + +[[bench]] +name = "file" +required-features = [ + "full", + "parsing", +] + +[dependencies.proc-macro2] +version = "1.0.75" +default-features = false + +[dependencies.quote] +version = "1.0.35" +optional = true +default-features = false + +[dependencies.unicode-ident] +version = "1" + +[dev-dependencies.anyhow] +version = "1" + +[dev-dependencies.automod] +version = "1" + +[dev-dependencies.flate2] +version = "1" + +[dev-dependencies.insta] +version = "1" + +[dev-dependencies.rayon] +version = "1" + +[dev-dependencies.ref-cast] +version = "1" + +[dev-dependencies.reqwest] +version = "0.11" +features = ["blocking"] + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.syn-test-suite] +version = "0" + +[dev-dependencies.tar] +version = "0.4.16" + +[dev-dependencies.termcolor] +version = "1" + +[dev-dependencies.walkdir] +version = "2.3.2" + +[features] +clone-impls = [] +default = [ + "derive", + "parsing", + "printing", + "clone-impls", + "proc-macro", +] +derive = [] +extra-traits = [] +fold = [] +full = [] +parsing = [] +printing = ["quote"] +proc-macro = [ + "proc-macro2/proc-macro", + "quote/proc-macro", +] +test = ["syn-test-suite/all-features"] +visit = [] +visit-mut = [] diff --git a/utshell-0.5.0/vendor/syn/LICENSE-APACHE b/utshell-0.5.0/vendor/syn/LICENSE-APACHE new file mode 100644 index 00000000..1b5ec8b7 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/utshell-0.5.0/vendor/syn/LICENSE-MIT b/utshell-0.5.0/vendor/syn/LICENSE-MIT new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/utshell-0.5.0/vendor/syn/README.md b/utshell-0.5.0/vendor/syn/README.md new file mode 100644 index 00000000..e8d99abc --- /dev/null +++ b/utshell-0.5.0/vendor/syn/README.md @@ -0,0 +1,284 @@ +Parser for Rust source code +=========================== + +[github](https://github.com/dtolnay/syn) +[crates.io](https://crates.io/crates/syn) +[docs.rs](https://docs.rs/syn) +[build status](https://github.com/dtolnay/syn/actions?query=branch%3Amaster) + +Syn is a parsing library for parsing a stream of Rust tokens into a syntax tree +of Rust source code. + +Currently this library is geared toward use in Rust procedural macros, but +contains some APIs that may be useful more generally. + +- **Data structures** — Syn provides a complete syntax tree that can represent + any valid Rust source code. The syntax tree is rooted at [`syn::File`] which + represents a full source file, but there are other entry points that may be + useful to procedural macros including [`syn::Item`], [`syn::Expr`] and + [`syn::Type`]. + +- **Derives** — Of particular interest to derive macros is [`syn::DeriveInput`] + which is any of the three legal input items to a derive macro. An example + below shows using this type in a library that can derive implementations of a + user-defined trait. + +- **Parsing** — Parsing in Syn is built around [parser functions] with the + signature `fn(ParseStream) -> Result`. Every syntax tree node defined by + Syn is individually parsable and may be used as a building block for custom + syntaxes, or you may dream up your own brand new syntax without involving any + of our syntax tree types. + +- **Location information** — Every token parsed by Syn is associated with a + `Span` that tracks line and column information back to the source of that + token. These spans allow a procedural macro to display detailed error messages + pointing to all the right places in the user's code. There is an example of + this below. + +- **Feature flags** — Functionality is aggressively feature gated so your + procedural macros enable only what they need, and do not pay in compile time + for all the rest. + +[`syn::File`]: https://docs.rs/syn/2.0/syn/struct.File.html +[`syn::Item`]: https://docs.rs/syn/2.0/syn/enum.Item.html +[`syn::Expr`]: https://docs.rs/syn/2.0/syn/enum.Expr.html +[`syn::Type`]: https://docs.rs/syn/2.0/syn/enum.Type.html +[`syn::DeriveInput`]: https://docs.rs/syn/2.0/syn/struct.DeriveInput.html +[parser functions]: https://docs.rs/syn/2.0/syn/parse/index.html + +*Version requirement: Syn supports rustc 1.56 and up.* + +[*Release notes*](https://github.com/dtolnay/syn/releases) + +
+ +## Resources + +The best way to learn about procedural macros is by writing some. Consider +working through [this procedural macro workshop][workshop] to get familiar with +the different types of procedural macros. The workshop contains relevant links +into the Syn documentation as you work through each project. + +[workshop]: https://github.com/dtolnay/proc-macro-workshop + +
+ +## Example of a derive macro + +The canonical derive macro using Syn looks like this. We write an ordinary Rust +function tagged with a `proc_macro_derive` attribute and the name of the trait +we are deriving. Any time that derive appears in the user's code, the Rust +compiler passes their data structure as tokens into our macro. We get to execute +arbitrary Rust code to figure out what to do with those tokens, then hand some +tokens back to the compiler to compile into the user's crate. + +[`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html + +```toml +[dependencies] +syn = "2.0" +quote = "1.0" + +[lib] +proc-macro = true +``` + +```rust +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +#[proc_macro_derive(MyMacro)] +pub fn my_macro(input: TokenStream) -> TokenStream { + // Parse the input tokens into a syntax tree + let input = parse_macro_input!(input as DeriveInput); + + // Build the output, possibly using quasi-quotation + let expanded = quote! { + // ... + }; + + // Hand the output tokens back to the compiler + TokenStream::from(expanded) +} +``` + +The [`heapsize`] example directory shows a complete working implementation of a +derive macro. The example derives a `HeapSize` trait which computes an estimate +of the amount of heap memory owned by a value. + +[`heapsize`]: examples/heapsize + +```rust +pub trait HeapSize { + /// Total number of bytes of heap memory owned by `self`. + fn heap_size_of_children(&self) -> usize; +} +``` + +The derive macro allows users to write `#[derive(HeapSize)]` on data structures +in their program. + +```rust +#[derive(HeapSize)] +struct Demo<'a, T: ?Sized> { + a: Box, + b: u8, + c: &'a str, + d: String, +} +``` + +
+ +## Spans and error reporting + +The token-based procedural macro API provides great control over where the +compiler's error messages are displayed in user code. Consider the error the +user sees if one of their field types does not implement `HeapSize`. + +```rust +#[derive(HeapSize)] +struct Broken { + ok: String, + bad: std::thread::Thread, +} +``` + +By tracking span information all the way through the expansion of a procedural +macro as shown in the `heapsize` example, token-based macros in Syn are able to +trigger errors that directly pinpoint the source of the problem. + +```console +error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied + --> src/main.rs:7:5 + | +7 | bad: std::thread::Thread, + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread` +``` + +
+ +## Parsing a custom syntax + +The [`lazy-static`] example directory shows the implementation of a +`functionlike!(...)` procedural macro in which the input tokens are parsed using +Syn's parsing API. + +[`lazy-static`]: examples/lazy-static + +The example reimplements the popular `lazy_static` crate from crates.io as a +procedural macro. + +```rust +lazy_static! { + static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap(); +} +``` + +The implementation shows how to trigger custom warnings and error messages on +the macro input. + +```console +warning: come on, pick a more creative name + --> src/main.rs:10:16 + | +10 | static ref FOO: String = "lazy_static".to_owned(); + | ^^^ +``` + +
+ +## Testing + +When testing macros, we often care not just that the macro can be used +successfully but also that when the macro is provided with invalid input it +produces maximally helpful error messages. Consider using the [`trybuild`] crate +to write tests for errors that are emitted by your macro or errors detected by +the Rust compiler in the expanded code following misuse of the macro. Such tests +help avoid regressions from later refactors that mistakenly make an error no +longer trigger or be less helpful than it used to be. + +[`trybuild`]: https://github.com/dtolnay/trybuild + +
+ +## Debugging + +When developing a procedural macro it can be helpful to look at what the +generated code looks like. Use `cargo rustc -- -Zunstable-options +--pretty=expanded` or the [`cargo expand`] subcommand. + +[`cargo expand`]: https://github.com/dtolnay/cargo-expand + +To show the expanded code for some crate that uses your procedural macro, run +`cargo expand` from that crate. To show the expanded code for one of your own +test cases, run `cargo expand --test the_test_case` where the last argument is +the name of the test file without the `.rs` extension. + +This write-up by Brandon W Maister discusses debugging in more detail: +[Debugging Rust's new Custom Derive system][debugging]. + +[debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/ + +
+ +## Optional features + +Syn puts a lot of functionality behind optional features in order to optimize +compile time for the most common use cases. The following features are +available. + +- **`derive`** *(enabled by default)* — Data structures for representing the + possible input to a derive macro, including structs and enums and types. +- **`full`** — Data structures for representing the syntax tree of all valid + Rust source code, including items and expressions. +- **`parsing`** *(enabled by default)* — Ability to parse input tokens into a + syntax tree node of a chosen type. +- **`printing`** *(enabled by default)* — Ability to print a syntax tree node as + tokens of Rust source code. +- **`visit`** — Trait for traversing a syntax tree. +- **`visit-mut`** — Trait for traversing and mutating in place a syntax tree. +- **`fold`** — Trait for transforming an owned syntax tree. +- **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree + types. +- **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree + types. +- **`proc-macro`** *(enabled by default)* — Runtime dependency on the dynamic + library libproc_macro from rustc toolchain. + +
+ +## Proc macro shim + +Syn operates on the token representation provided by the [proc-macro2] crate +from crates.io rather than using the compiler's built in proc-macro crate +directly. This enables code using Syn to execute outside of the context of a +procedural macro, such as in unit tests or build.rs, and we avoid needing +incompatible ecosystems for proc macros vs non-macro use cases. + +In general all of your code should be written against proc-macro2 rather than +proc-macro. The one exception is in the signatures of procedural macro entry +points, which are required by the language to use `proc_macro::TokenStream`. + +The proc-macro2 crate will automatically detect and use the compiler's data +structures when a procedural macro is active. + +[proc-macro2]: https://docs.rs/proc-macro2/1.0/proc_macro2/ + +
+ +#### License + + +Licensed under either of
Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/utshell-0.5.0/vendor/syn/benches/file.rs b/utshell-0.5.0/vendor/syn/benches/file.rs new file mode 100644 index 00000000..b4247239 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/benches/file.rs @@ -0,0 +1,57 @@ +// $ cargo bench --features full,test --bench file + +#![feature(rustc_private, test)] +#![recursion_limit = "1024"] +#![allow( + clippy::items_after_statements, + clippy::manual_let_else, + clippy::match_like_matches_macro, + clippy::missing_panics_doc, + clippy::must_use_candidate, + clippy::uninlined_format_args +)] + +extern crate test; + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[allow(dead_code)] +#[path = "../tests/repo/mod.rs"] +mod repo; + +use proc_macro2::{Span, TokenStream}; +use std::fs; +use std::str::FromStr; +use syn::parse::{ParseStream, Parser}; +use test::Bencher; + +const FILE: &str = "tests/rust/library/core/src/str/mod.rs"; + +fn get_tokens() -> TokenStream { + repo::clone_rust(); + let content = fs::read_to_string(FILE).unwrap(); + TokenStream::from_str(&content).unwrap() +} + +#[bench] +fn baseline(b: &mut Bencher) { + let tokens = get_tokens(); + b.iter(|| drop(tokens.clone())); +} + +#[bench] +fn create_token_buffer(b: &mut Bencher) { + let tokens = get_tokens(); + fn immediate_fail(_input: ParseStream) -> syn::Result<()> { + Err(syn::Error::new(Span::call_site(), "")) + } + b.iter(|| immediate_fail.parse2(tokens.clone())); +} + +#[bench] +fn parse_file(b: &mut Bencher) { + let tokens = get_tokens(); + b.iter(|| syn::parse2::(tokens.clone())); +} diff --git a/utshell-0.5.0/vendor/syn/benches/rust.rs b/utshell-0.5.0/vendor/syn/benches/rust.rs new file mode 100644 index 00000000..2f337089 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/benches/rust.rs @@ -0,0 +1,182 @@ +// $ cargo bench --features full,test --bench rust +// +// Syn only, useful for profiling: +// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full,test --bench rust + +#![cfg_attr(not(syn_only), feature(rustc_private))] +#![recursion_limit = "1024"] +#![allow( + clippy::arc_with_non_send_sync, + clippy::cast_lossless, + clippy::let_underscore_untyped, + clippy::manual_let_else, + clippy::match_like_matches_macro, + clippy::uninlined_format_args, + clippy::unnecessary_wraps +)] + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[allow(dead_code)] +#[path = "../tests/repo/mod.rs"] +mod repo; + +use std::fs; +use std::time::{Duration, Instant}; + +#[cfg(not(syn_only))] +mod tokenstream_parse { + use proc_macro2::TokenStream; + use std::str::FromStr; + + pub fn bench(content: &str) -> Result<(), ()> { + TokenStream::from_str(content).map(drop).map_err(drop) + } +} + +mod syn_parse { + pub fn bench(content: &str) -> Result<(), ()> { + syn::parse_file(content).map(drop).map_err(drop) + } +} + +#[cfg(not(syn_only))] +mod librustc_parse { + extern crate rustc_data_structures; + extern crate rustc_driver; + extern crate rustc_error_messages; + extern crate rustc_errors; + extern crate rustc_parse; + extern crate rustc_session; + extern crate rustc_span; + + use rustc_data_structures::sync::Lrc; + use rustc_error_messages::FluentBundle; + use rustc_errors::{emitter::Emitter, translation::Translate, DiagCtxt, Diagnostic}; + use rustc_session::parse::ParseSess; + use rustc_span::source_map::{FilePathMapping, SourceMap}; + use rustc_span::{edition::Edition, FileName}; + + pub fn bench(content: &str) -> Result<(), ()> { + struct SilentEmitter; + + impl Emitter for SilentEmitter { + fn emit_diagnostic(&mut self, _diag: Diagnostic) {} + fn source_map(&self) -> Option<&Lrc> { + None + } + } + + impl Translate for SilentEmitter { + fn fluent_bundle(&self) -> Option<&Lrc> { + None + } + fn fallback_fluent_bundle(&self) -> &FluentBundle { + panic!("silent emitter attempted to translate a diagnostic"); + } + } + + rustc_span::create_session_if_not_set_then(Edition::Edition2018, |_| { + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let emitter = Box::new(SilentEmitter); + let handler = DiagCtxt::with_emitter(emitter); + let sess = ParseSess::with_dcx(handler, source_map); + if let Err(diagnostic) = rustc_parse::parse_crate_from_source_str( + FileName::Custom("bench".to_owned()), + content.to_owned(), + &sess, + ) { + diagnostic.cancel(); + return Err(()); + }; + Ok(()) + }) + } +} + +#[cfg(not(syn_only))] +mod read_from_disk { + pub fn bench(content: &str) -> Result<(), ()> { + let _ = content; + Ok(()) + } +} + +fn exec(mut codepath: impl FnMut(&str) -> Result<(), ()>) -> Duration { + let begin = Instant::now(); + let mut success = 0; + let mut total = 0; + + ["tests/rust/compiler", "tests/rust/library"] + .iter() + .flat_map(|dir| { + walkdir::WalkDir::new(dir) + .into_iter() + .filter_entry(repo::base_dir_filter) + }) + .for_each(|entry| { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + return; + } + let content = fs::read_to_string(path).unwrap(); + let ok = codepath(&content).is_ok(); + success += ok as usize; + total += 1; + if !ok { + eprintln!("FAIL {}", path.display()); + } + }); + + assert_eq!(success, total); + begin.elapsed() +} + +fn main() { + repo::clone_rust(); + + macro_rules! testcases { + ($($(#[$cfg:meta])* $name:ident,)*) => { + [ + $( + $(#[$cfg])* + (stringify!($name), $name::bench as fn(&str) -> Result<(), ()>), + )* + ] + }; + } + + #[cfg(not(syn_only))] + { + let mut lines = 0; + let mut files = 0; + exec(|content| { + lines += content.lines().count(); + files += 1; + Ok(()) + }); + eprintln!("\n{} lines in {} files", lines, files); + } + + for (name, f) in testcases!( + #[cfg(not(syn_only))] + read_from_disk, + #[cfg(not(syn_only))] + tokenstream_parse, + syn_parse, + #[cfg(not(syn_only))] + librustc_parse, + ) { + eprint!("{:20}", format!("{}:", name)); + let elapsed = exec(f); + eprintln!( + "elapsed={}.{:03}s", + elapsed.as_secs(), + elapsed.subsec_millis(), + ); + } + eprintln!(); +} diff --git a/utshell-0.5.0/vendor/syn/src/attr.rs b/utshell-0.5.0/vendor/syn/src/attr.rs new file mode 100644 index 00000000..589e4278 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/attr.rs @@ -0,0 +1,793 @@ +#[cfg(feature = "parsing")] +use crate::error::Error; +#[cfg(feature = "parsing")] +use crate::error::Result; +use crate::expr::Expr; +use crate::mac::MacroDelimiter; +#[cfg(feature = "parsing")] +use crate::meta::{self, ParseNestedMeta}; +#[cfg(feature = "parsing")] +use crate::parse::{Parse, ParseStream, Parser}; +use crate::path::Path; +use crate::token; +use proc_macro2::TokenStream; +#[cfg(feature = "printing")] +use std::iter; +#[cfg(feature = "printing")] +use std::slice; + +ast_struct! { + /// An attribute, like `#[repr(transparent)]`. + /// + ///
+ /// + /// # Syntax + /// + /// Rust has six types of attributes. + /// + /// - Outer attributes like `#[repr(transparent)]`. These appear outside or + /// in front of the item they describe. + /// + /// - Inner attributes like `#![feature(proc_macro)]`. These appear inside + /// of the item they describe, usually a module. + /// + /// - Outer one-line doc comments like `/// Example`. + /// + /// - Inner one-line doc comments like `//! Please file an issue`. + /// + /// - Outer documentation blocks `/** Example */`. + /// + /// - Inner documentation blocks `/*! Please file an issue */`. + /// + /// The `style` field of type `AttrStyle` distinguishes whether an attribute + /// is outer or inner. + /// + /// Every attribute has a `path` that indicates the intended interpretation + /// of the rest of the attribute's contents. The path and the optional + /// additional contents are represented together in the `meta` field of the + /// attribute in three possible varieties: + /// + /// - Meta::Path — attributes whose information content conveys just a + /// path, for example the `#[test]` attribute. + /// + /// - Meta::List — attributes that carry arbitrary tokens after the + /// path, surrounded by a delimiter (parenthesis, bracket, or brace). For + /// example `#[derive(Copy)]` or `#[precondition(x < 5)]`. + /// + /// - Meta::NameValue — attributes with an `=` sign after the path, + /// followed by a Rust expression. For example `#[path = + /// "sys/windows.rs"]`. + /// + /// All doc comments are represented in the NameValue style with a path of + /// "doc", as this is how they are processed by the compiler and by + /// `macro_rules!` macros. + /// + /// ```text + /// #[derive(Copy, Clone)] + /// ~~~~~~Path + /// ^^^^^^^^^^^^^^^^^^^Meta::List + /// + /// #[path = "sys/windows.rs"] + /// ~~~~Path + /// ^^^^^^^^^^^^^^^^^^^^^^^Meta::NameValue + /// + /// #[test] + /// ^^^^Meta::Path + /// ``` + /// + ///
+ /// + /// # Parsing from tokens to Attribute + /// + /// This type does not implement the [`Parse`] trait and thus cannot be + /// parsed directly by [`ParseStream::parse`]. Instead use + /// [`ParseStream::call`] with one of the two parser functions + /// [`Attribute::parse_outer`] or [`Attribute::parse_inner`] depending on + /// which you intend to parse. + /// + /// [`Parse`]: crate::parse::Parse + /// [`ParseStream::parse`]: crate::parse::ParseBuffer::parse + /// [`ParseStream::call`]: crate::parse::ParseBuffer::call + /// + /// ``` + /// use syn::{Attribute, Ident, Result, Token}; + /// use syn::parse::{Parse, ParseStream}; + /// + /// // Parses a unit struct with attributes. + /// // + /// // #[path = "s.tmpl"] + /// // struct S; + /// struct UnitStruct { + /// attrs: Vec, + /// struct_token: Token![struct], + /// name: Ident, + /// semi_token: Token![;], + /// } + /// + /// impl Parse for UnitStruct { + /// fn parse(input: ParseStream) -> Result { + /// Ok(UnitStruct { + /// attrs: input.call(Attribute::parse_outer)?, + /// struct_token: input.parse()?, + /// name: input.parse()?, + /// semi_token: input.parse()?, + /// }) + /// } + /// } + /// ``` + /// + ///


+ /// + /// # Parsing from Attribute to structured arguments + /// + /// The grammar of attributes in Rust is very flexible, which makes the + /// syntax tree not that useful on its own. In particular, arguments of the + /// `Meta::List` variety of attribute are held in an arbitrary `tokens: + /// TokenStream`. Macros are expected to check the `path` of the attribute, + /// decide whether they recognize it, and then parse the remaining tokens + /// according to whatever grammar they wish to require for that kind of + /// attribute. Use [`parse_args()`] to parse those tokens into the expected + /// data structure. + /// + /// [`parse_args()`]: Attribute::parse_args + /// + ///


+ /// + /// # Doc comments + /// + /// The compiler transforms doc comments, such as `/// comment` and `/*! + /// comment */`, into attributes before macros are expanded. Each comment is + /// expanded into an attribute of the form `#[doc = r"comment"]`. + /// + /// As an example, the following `mod` items are expanded identically: + /// + /// ``` + /// # use syn::{ItemMod, parse_quote}; + /// let doc: ItemMod = parse_quote! { + /// /// Single line doc comments + /// /// We write so many! + /// /** + /// * Multi-line comments... + /// * May span many lines + /// */ + /// mod example { + /// //! Of course, they can be inner too + /// /*! And fit in a single line */ + /// } + /// }; + /// let attr: ItemMod = parse_quote! { + /// #[doc = r" Single line doc comments"] + /// #[doc = r" We write so many!"] + /// #[doc = r" + /// * Multi-line comments... + /// * May span many lines + /// "] + /// mod example { + /// #![doc = r" Of course, they can be inner too"] + /// #![doc = r" And fit in a single line "] + /// } + /// }; + /// assert_eq!(doc, attr); + /// ``` + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Attribute { + pub pound_token: Token![#], + pub style: AttrStyle, + pub bracket_token: token::Bracket, + pub meta: Meta, + } +} + +impl Attribute { + /// Returns the path that identifies the interpretation of this attribute. + /// + /// For example this would return the `test` in `#[test]`, the `derive` in + /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. + pub fn path(&self) -> &Path { + self.meta.path() + } + + /// Parse the arguments to the attribute as a syntax tree. + /// + /// This is similar to pulling out the `TokenStream` from `Meta::List` and + /// doing `syn::parse2::(meta_list.tokens)`, except that using + /// `parse_args` the error message has a more useful span when `tokens` is + /// empty. + /// + /// The surrounding delimiters are *not* included in the input to the + /// parser. + /// + /// ```text + /// #[my_attr(value < 5)] + /// ^^^^^^^^^ what gets parsed + /// ``` + /// + /// # Example + /// + /// ``` + /// use syn::{parse_quote, Attribute, Expr}; + /// + /// let attr: Attribute = parse_quote! { + /// #[precondition(value < 5)] + /// }; + /// + /// if attr.path().is_ident("precondition") { + /// let precondition: Expr = attr.parse_args()?; + /// // ... + /// } + /// # anyhow::Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_args(&self) -> Result { + self.parse_args_with(T::parse) + } + + /// Parse the arguments to the attribute using the given parser. + /// + /// # Example + /// + /// ``` + /// use syn::{parse_quote, Attribute}; + /// + /// let attr: Attribute = parse_quote! { + /// #[inception { #[brrrrrrraaaaawwwwrwrrrmrmrmmrmrmmmmm] }] + /// }; + /// + /// let bwom = attr.parse_args_with(Attribute::parse_outer)?; + /// + /// // Attribute does not have a Parse impl, so we couldn't directly do: + /// // let bwom: Attribute = attr.parse_args()?; + /// # anyhow::Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_args_with(&self, parser: F) -> Result { + match &self.meta { + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected attribute arguments in parentheses: {}[{}(...)]", + parsing::DisplayAttrStyle(&self.style), + parsing::DisplayPath(path), + ), + )), + Meta::NameValue(meta) => Err(Error::new( + meta.eq_token.span, + format_args!( + "expected parentheses: {}[{}(...)]", + parsing::DisplayAttrStyle(&self.style), + parsing::DisplayPath(&meta.path), + ), + )), + Meta::List(meta) => meta.parse_args_with(parser), + } + } + + /// Parse the arguments to the attribute, expecting it to follow the + /// conventional structure used by most of Rust's built-in attributes. + /// + /// The [*Meta Item Attribute Syntax*][syntax] section in the Rust reference + /// explains the convention in more detail. Not all attributes follow this + /// convention, so [`parse_args()`][Self::parse_args] is available if you + /// need to parse arbitrarily goofy attribute syntax. + /// + /// [syntax]: https://doc.rust-lang.org/reference/attributes.html#meta-item-attribute-syntax + /// + /// # Example + /// + /// We'll parse a struct, and then parse some of Rust's `#[repr]` attribute + /// syntax. + /// + /// ``` + /// use syn::{parenthesized, parse_quote, token, ItemStruct, LitInt}; + /// + /// let input: ItemStruct = parse_quote! { + /// #[repr(C, align(4))] + /// pub struct MyStruct(u16, u32); + /// }; + /// + /// let mut repr_c = false; + /// let mut repr_transparent = false; + /// let mut repr_align = None::; + /// let mut repr_packed = None::; + /// for attr in &input.attrs { + /// if attr.path().is_ident("repr") { + /// attr.parse_nested_meta(|meta| { + /// // #[repr(C)] + /// if meta.path.is_ident("C") { + /// repr_c = true; + /// return Ok(()); + /// } + /// + /// // #[repr(transparent)] + /// if meta.path.is_ident("transparent") { + /// repr_transparent = true; + /// return Ok(()); + /// } + /// + /// // #[repr(align(N))] + /// if meta.path.is_ident("align") { + /// let content; + /// parenthesized!(content in meta.input); + /// let lit: LitInt = content.parse()?; + /// let n: usize = lit.base10_parse()?; + /// repr_align = Some(n); + /// return Ok(()); + /// } + /// + /// // #[repr(packed)] or #[repr(packed(N))], omitted N means 1 + /// if meta.path.is_ident("packed") { + /// if meta.input.peek(token::Paren) { + /// let content; + /// parenthesized!(content in meta.input); + /// let lit: LitInt = content.parse()?; + /// let n: usize = lit.base10_parse()?; + /// repr_packed = Some(n); + /// } else { + /// repr_packed = Some(1); + /// } + /// return Ok(()); + /// } + /// + /// Err(meta.error("unrecognized repr")) + /// })?; + /// } + /// } + /// # anyhow::Ok(()) + /// ``` + /// + /// # Alternatives + /// + /// In some cases, for attributes which have nested layers of structured + /// content, the following less flexible approach might be more convenient: + /// + /// ``` + /// # use syn::{parse_quote, ItemStruct}; + /// # + /// # let input: ItemStruct = parse_quote! { + /// # #[repr(C, align(4))] + /// # pub struct MyStruct(u16, u32); + /// # }; + /// # + /// use syn::punctuated::Punctuated; + /// use syn::{parenthesized, token, Error, LitInt, Meta, Token}; + /// + /// let mut repr_c = false; + /// let mut repr_transparent = false; + /// let mut repr_align = None::; + /// let mut repr_packed = None::; + /// for attr in &input.attrs { + /// if attr.path().is_ident("repr") { + /// let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; + /// for meta in nested { + /// match meta { + /// // #[repr(C)] + /// Meta::Path(path) if path.is_ident("C") => { + /// repr_c = true; + /// } + /// + /// // #[repr(align(N))] + /// Meta::List(meta) if meta.path.is_ident("align") => { + /// let lit: LitInt = meta.parse_args()?; + /// let n: usize = lit.base10_parse()?; + /// repr_align = Some(n); + /// } + /// + /// /* ... */ + /// + /// _ => { + /// return Err(Error::new_spanned(meta, "unrecognized repr")); + /// } + /// } + /// } + /// } + /// } + /// # Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_nested_meta( + &self, + logic: impl FnMut(ParseNestedMeta) -> Result<()>, + ) -> Result<()> { + self.parse_args_with(meta::parser(logic)) + } + + /// Parses zero or more outer attributes from the stream. + /// + /// # Example + /// + /// See + /// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_outer(input: ParseStream) -> Result> { + let mut attrs = Vec::new(); + while input.peek(Token![#]) { + attrs.push(input.call(parsing::single_parse_outer)?); + } + Ok(attrs) + } + + /// Parses zero or more inner attributes from the stream. + /// + /// # Example + /// + /// See + /// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_inner(input: ParseStream) -> Result> { + let mut attrs = Vec::new(); + parsing::parse_inner(input, &mut attrs)?; + Ok(attrs) + } +} + +ast_enum! { + /// Distinguishes between attributes that decorate an item and attributes + /// that are contained within an item. + /// + /// # Outer attributes + /// + /// - `#[repr(transparent)]` + /// - `/// # Example` + /// - `/** Please file an issue */` + /// + /// # Inner attributes + /// + /// - `#![feature(proc_macro)]` + /// - `//! # Example` + /// - `/*! Please file an issue */` + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum AttrStyle { + Outer, + Inner(Token![!]), + } +} + +ast_enum_of_structs! { + /// Content of a compile-time structured attribute. + /// + /// ## Path + /// + /// A meta path is like the `test` in `#[test]`. + /// + /// ## List + /// + /// A meta list is like the `derive(Copy)` in `#[derive(Copy)]`. + /// + /// ## NameValue + /// + /// A name-value meta is like the `path = "..."` in `#[path = + /// "sys/windows.rs"]`. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum Meta { + Path(Path), + + /// A structured list within an attribute, like `derive(Copy, Clone)`. + List(MetaList), + + /// A name-value pair within an attribute, like `feature = "nightly"`. + NameValue(MetaNameValue), + } +} + +ast_struct! { + /// A structured list within an attribute, like `derive(Copy, Clone)`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct MetaList { + pub path: Path, + pub delimiter: MacroDelimiter, + pub tokens: TokenStream, + } +} + +ast_struct! { + /// A name-value pair within an attribute, like `feature = "nightly"`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct MetaNameValue { + pub path: Path, + pub eq_token: Token![=], + pub value: Expr, + } +} + +impl Meta { + /// Returns the path that begins this structured meta item. + /// + /// For example this would return the `test` in `#[test]`, the `derive` in + /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. + pub fn path(&self) -> &Path { + match self { + Meta::Path(path) => path, + Meta::List(meta) => &meta.path, + Meta::NameValue(meta) => &meta.path, + } + } + + /// Error if this is a `Meta::List` or `Meta::NameValue`. + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn require_path_only(&self) -> Result<&Path> { + let error_span = match self { + Meta::Path(path) => return Ok(path), + Meta::List(meta) => meta.delimiter.span().open(), + Meta::NameValue(meta) => meta.eq_token.span, + }; + Err(Error::new(error_span, "unexpected token in attribute")) + } + + /// Error if this is a `Meta::Path` or `Meta::NameValue`. + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn require_list(&self) -> Result<&MetaList> { + match self { + Meta::List(meta) => Ok(meta), + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected attribute arguments in parentheses: `{}(...)`", + parsing::DisplayPath(path), + ), + )), + Meta::NameValue(meta) => Err(Error::new(meta.eq_token.span, "expected `(`")), + } + } + + /// Error if this is a `Meta::Path` or `Meta::List`. + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn require_name_value(&self) -> Result<&MetaNameValue> { + match self { + Meta::NameValue(meta) => Ok(meta), + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected a value for this attribute: `{} = ...`", + parsing::DisplayPath(path), + ), + )), + Meta::List(meta) => Err(Error::new(meta.delimiter.span().open(), "expected `=`")), + } + } +} + +impl MetaList { + /// See [`Attribute::parse_args`]. + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_args(&self) -> Result { + self.parse_args_with(T::parse) + } + + /// See [`Attribute::parse_args_with`]. + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_args_with(&self, parser: F) -> Result { + let scope = self.delimiter.span().close(); + crate::parse::parse_scoped(parser, scope, self.tokens.clone()) + } + + /// See [`Attribute::parse_nested_meta`]. + #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_nested_meta( + &self, + logic: impl FnMut(ParseNestedMeta) -> Result<()>, + ) -> Result<()> { + self.parse_args_with(meta::parser(logic)) + } +} + +#[cfg(feature = "printing")] +pub(crate) trait FilterAttrs<'a> { + type Ret: Iterator; + + fn outer(self) -> Self::Ret; + #[cfg(feature = "full")] + fn inner(self) -> Self::Ret; +} + +#[cfg(feature = "printing")] +impl<'a> FilterAttrs<'a> for &'a [Attribute] { + type Ret = iter::Filter, fn(&&Attribute) -> bool>; + + fn outer(self) -> Self::Ret { + fn is_outer(attr: &&Attribute) -> bool { + match attr.style { + AttrStyle::Outer => true, + AttrStyle::Inner(_) => false, + } + } + self.iter().filter(is_outer) + } + + #[cfg(feature = "full")] + fn inner(self) -> Self::Ret { + fn is_inner(attr: &&Attribute) -> bool { + match attr.style { + AttrStyle::Inner(_) => true, + AttrStyle::Outer => false, + } + } + self.iter().filter(is_inner) + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; + use crate::error::Result; + use crate::expr::{Expr, ExprLit}; + use crate::lit::Lit; + use crate::parse::discouraged::Speculative as _; + use crate::parse::{Parse, ParseStream}; + use crate::path::Path; + use crate::{mac, token}; + use std::fmt::{self, Display}; + + pub(crate) fn parse_inner(input: ParseStream, attrs: &mut Vec) -> Result<()> { + while input.peek(Token![#]) && input.peek2(Token![!]) { + attrs.push(input.call(single_parse_inner)?); + } + Ok(()) + } + + pub(crate) fn single_parse_inner(input: ParseStream) -> Result { + let content; + Ok(Attribute { + pound_token: input.parse()?, + style: AttrStyle::Inner(input.parse()?), + bracket_token: bracketed!(content in input), + meta: content.parse()?, + }) + } + + pub(crate) fn single_parse_outer(input: ParseStream) -> Result { + let content; + Ok(Attribute { + pound_token: input.parse()?, + style: AttrStyle::Outer, + bracket_token: bracketed!(content in input), + meta: content.parse()?, + }) + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for Meta { + fn parse(input: ParseStream) -> Result { + let path = input.call(Path::parse_mod_style)?; + parse_meta_after_path(path, input) + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for MetaList { + fn parse(input: ParseStream) -> Result { + let path = input.call(Path::parse_mod_style)?; + parse_meta_list_after_path(path, input) + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for MetaNameValue { + fn parse(input: ParseStream) -> Result { + let path = input.call(Path::parse_mod_style)?; + parse_meta_name_value_after_path(path, input) + } + } + + pub(crate) fn parse_meta_after_path(path: Path, input: ParseStream) -> Result { + if input.peek(token::Paren) || input.peek(token::Bracket) || input.peek(token::Brace) { + parse_meta_list_after_path(path, input).map(Meta::List) + } else if input.peek(Token![=]) { + parse_meta_name_value_after_path(path, input).map(Meta::NameValue) + } else { + Ok(Meta::Path(path)) + } + } + + fn parse_meta_list_after_path(path: Path, input: ParseStream) -> Result { + let (delimiter, tokens) = mac::parse_delimiter(input)?; + Ok(MetaList { + path, + delimiter, + tokens, + }) + } + + fn parse_meta_name_value_after_path(path: Path, input: ParseStream) -> Result { + let eq_token: Token![=] = input.parse()?; + let ahead = input.fork(); + let lit: Option = ahead.parse()?; + let value = if let (Some(lit), true) = (lit, ahead.is_empty()) { + input.advance_to(&ahead); + Expr::Lit(ExprLit { + attrs: Vec::new(), + lit, + }) + } else if input.peek(Token![#]) && input.peek2(token::Bracket) { + return Err(input.error("unexpected attribute inside of attribute")); + } else { + input.parse()? + }; + Ok(MetaNameValue { + path, + eq_token, + value, + }) + } + + pub(super) struct DisplayAttrStyle<'a>(pub &'a AttrStyle); + + impl<'a> Display for DisplayAttrStyle<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(match self.0 { + AttrStyle::Outer => "#", + AttrStyle::Inner(_) => "#!", + }) + } + } + + pub(super) struct DisplayPath<'a>(pub &'a Path); + + impl<'a> Display for DisplayPath<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + for (i, segment) in self.0.segments.iter().enumerate() { + if i > 0 || self.0.leading_colon.is_some() { + formatter.write_str("::")?; + } + write!(formatter, "{}", segment.ident)?; + } + Ok(()) + } + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::attr::{AttrStyle, Attribute, MetaList, MetaNameValue}; + use proc_macro2::TokenStream; + use quote::ToTokens; + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for Attribute { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.pound_token.to_tokens(tokens); + if let AttrStyle::Inner(b) = &self.style { + b.to_tokens(tokens); + } + self.bracket_token.surround(tokens, |tokens| { + self.meta.to_tokens(tokens); + }); + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for MetaList { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.path.to_tokens(tokens); + self.delimiter.surround(tokens, self.tokens.clone()); + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for MetaNameValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.path.to_tokens(tokens); + self.eq_token.to_tokens(tokens); + self.value.to_tokens(tokens); + } + } +} diff --git a/utshell-0.5.0/vendor/syn/src/bigint.rs b/utshell-0.5.0/vendor/syn/src/bigint.rs new file mode 100644 index 00000000..66aaa937 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/bigint.rs @@ -0,0 +1,66 @@ +use std::ops::{AddAssign, MulAssign}; + +// For implementing base10_digits() accessor on LitInt. +pub(crate) struct BigInt { + digits: Vec, +} + +impl BigInt { + pub(crate) fn new() -> Self { + BigInt { digits: Vec::new() } + } + + pub(crate) fn to_string(&self) -> String { + let mut repr = String::with_capacity(self.digits.len()); + + let mut has_nonzero = false; + for digit in self.digits.iter().rev() { + has_nonzero |= *digit != 0; + if has_nonzero { + repr.push((*digit + b'0') as char); + } + } + + if repr.is_empty() { + repr.push('0'); + } + + repr + } + + fn reserve_two_digits(&mut self) { + let len = self.digits.len(); + let desired = + len + !self.digits.ends_with(&[0, 0]) as usize + !self.digits.ends_with(&[0]) as usize; + self.digits.resize(desired, 0); + } +} + +impl AddAssign for BigInt { + // Assumes increment <16. + fn add_assign(&mut self, mut increment: u8) { + self.reserve_two_digits(); + + let mut i = 0; + while increment > 0 { + let sum = self.digits[i] + increment; + self.digits[i] = sum % 10; + increment = sum / 10; + i += 1; + } + } +} + +impl MulAssign for BigInt { + // Assumes base <=16. + fn mul_assign(&mut self, base: u8) { + self.reserve_two_digits(); + + let mut carry = 0; + for digit in &mut self.digits { + let prod = *digit * base + carry; + *digit = prod % 10; + carry = prod / 10; + } + } +} diff --git a/utshell-0.5.0/vendor/syn/src/buffer.rs b/utshell-0.5.0/vendor/syn/src/buffer.rs new file mode 100644 index 00000000..86dec46a --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/buffer.rs @@ -0,0 +1,432 @@ +//! A stably addressed token buffer supporting efficient traversal based on a +//! cheaply copyable cursor. + +// This module is heavily commented as it contains most of the unsafe code in +// Syn, and caution should be used when editing it. The public-facing interface +// is 100% safe but the implementation is fragile internally. + +use crate::Lifetime; +use proc_macro2::extra::DelimSpan; +use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; +use std::cmp::Ordering; +use std::marker::PhantomData; + +/// Internal type which is used instead of `TokenTree` to represent a token tree +/// within a `TokenBuffer`. +enum Entry { + // Mimicking types from proc-macro. + // Group entries contain the offset to the matching End entry. + Group(Group, usize), + Ident(Ident), + Punct(Punct), + Literal(Literal), + // End entries contain the offset (negative) to the start of the buffer. + End(isize), +} + +/// A buffer that can be efficiently traversed multiple times, unlike +/// `TokenStream` which requires a deep copy in order to traverse more than +/// once. +pub struct TokenBuffer { + // NOTE: Do not implement clone on this - while the current design could be + // cloned, other designs which could be desirable may not be cloneable. + entries: Box<[Entry]>, +} + +impl TokenBuffer { + fn recursive_new(entries: &mut Vec, stream: TokenStream) { + for tt in stream { + match tt { + TokenTree::Ident(ident) => entries.push(Entry::Ident(ident)), + TokenTree::Punct(punct) => entries.push(Entry::Punct(punct)), + TokenTree::Literal(literal) => entries.push(Entry::Literal(literal)), + TokenTree::Group(group) => { + let group_start_index = entries.len(); + entries.push(Entry::End(0)); // we replace this below + Self::recursive_new(entries, group.stream()); + let group_end_index = entries.len(); + entries.push(Entry::End(-(group_end_index as isize))); + let group_end_offset = group_end_index - group_start_index; + entries[group_start_index] = Entry::Group(group, group_end_offset); + } + } + } + } + + /// Creates a `TokenBuffer` containing all the tokens from the input + /// `proc_macro::TokenStream`. + #[cfg(feature = "proc-macro")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] + pub fn new(stream: proc_macro::TokenStream) -> Self { + Self::new2(stream.into()) + } + + /// Creates a `TokenBuffer` containing all the tokens from the input + /// `proc_macro2::TokenStream`. + pub fn new2(stream: TokenStream) -> Self { + let mut entries = Vec::new(); + Self::recursive_new(&mut entries, stream); + entries.push(Entry::End(-(entries.len() as isize))); + Self { + entries: entries.into_boxed_slice(), + } + } + + /// Creates a cursor referencing the first token in the buffer and able to + /// traverse until the end of the buffer. + pub fn begin(&self) -> Cursor { + let ptr = self.entries.as_ptr(); + unsafe { Cursor::create(ptr, ptr.add(self.entries.len() - 1)) } + } +} + +/// A cheaply copyable cursor into a `TokenBuffer`. +/// +/// This cursor holds a shared reference into the immutable data which is used +/// internally to represent a `TokenStream`, and can be efficiently manipulated +/// and copied around. +/// +/// An empty `Cursor` can be created directly, or one may create a `TokenBuffer` +/// object and get a cursor to its first token with `begin()`. +pub struct Cursor<'a> { + // The current entry which the `Cursor` is pointing at. + ptr: *const Entry, + // This is the only `Entry::End` object which this cursor is allowed to + // point at. All other `End` objects are skipped over in `Cursor::create`. + scope: *const Entry, + // Cursor is covariant in 'a. This field ensures that our pointers are still + // valid. + marker: PhantomData<&'a Entry>, +} + +impl<'a> Cursor<'a> { + /// Creates a cursor referencing a static empty TokenStream. + pub fn empty() -> Self { + // It's safe in this situation for us to put an `Entry` object in global + // storage, despite it not actually being safe to send across threads + // (`Ident` is a reference into a thread-local table). This is because + // this entry never includes a `Ident` object. + // + // This wrapper struct allows us to break the rules and put a `Sync` + // object in global storage. + struct UnsafeSyncEntry(Entry); + unsafe impl Sync for UnsafeSyncEntry {} + static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End(0)); + + Cursor { + ptr: &EMPTY_ENTRY.0, + scope: &EMPTY_ENTRY.0, + marker: PhantomData, + } + } + + /// This create method intelligently exits non-explicitly-entered + /// `None`-delimited scopes when the cursor reaches the end of them, + /// allowing for them to be treated transparently. + unsafe fn create(mut ptr: *const Entry, scope: *const Entry) -> Self { + // NOTE: If we're looking at a `End`, we want to advance the cursor + // past it, unless `ptr == scope`, which means that we're at the edge of + // our cursor's scope. We should only have `ptr != scope` at the exit + // from None-delimited groups entered with `ignore_none`. + while let Entry::End(_) = unsafe { &*ptr } { + if ptr == scope { + break; + } + ptr = unsafe { ptr.add(1) }; + } + + Cursor { + ptr, + scope, + marker: PhantomData, + } + } + + /// Get the current entry. + fn entry(self) -> &'a Entry { + unsafe { &*self.ptr } + } + + /// Bump the cursor to point at the next token after the current one. This + /// is undefined behavior if the cursor is currently looking at an + /// `Entry::End`. + /// + /// If the cursor is looking at an `Entry::Group`, the bumped cursor will + /// point at the first token in the group (with the same scope end). + unsafe fn bump_ignore_group(self) -> Cursor<'a> { + unsafe { Cursor::create(self.ptr.offset(1), self.scope) } + } + + /// While the cursor is looking at a `None`-delimited group, move it to look + /// at the first token inside instead. If the group is empty, this will move + /// the cursor past the `None`-delimited group. + /// + /// WARNING: This mutates its argument. + fn ignore_none(&mut self) { + while let Entry::Group(group, _) = self.entry() { + if group.delimiter() == Delimiter::None { + unsafe { *self = self.bump_ignore_group() }; + } else { + break; + } + } + } + + /// Checks whether the cursor is currently pointing at the end of its valid + /// scope. + pub fn eof(self) -> bool { + // We're at eof if we're at the end of our scope. + self.ptr == self.scope + } + + /// If the cursor is pointing at a `Group` with the given delimiter, returns + /// a cursor into that group and one pointing to the next `TokenTree`. + pub fn group(mut self, delim: Delimiter) -> Option<(Cursor<'a>, DelimSpan, Cursor<'a>)> { + // If we're not trying to enter a none-delimited group, we want to + // ignore them. We have to make sure to _not_ ignore them when we want + // to enter them, of course. For obvious reasons. + if delim != Delimiter::None { + self.ignore_none(); + } + + if let Entry::Group(group, end_offset) = self.entry() { + if group.delimiter() == delim { + let span = group.delim_span(); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, span, after_group)); + } + } + + None + } + + pub(crate) fn any_group(self) -> Option<(Cursor<'a>, Delimiter, DelimSpan, Cursor<'a>)> { + if let Entry::Group(group, end_offset) = self.entry() { + let delimiter = group.delimiter(); + let span = group.delim_span(); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, delimiter, span, after_group)); + } + + None + } + + pub(crate) fn any_group_token(self) -> Option<(Group, Cursor<'a>)> { + if let Entry::Group(group, end_offset) = self.entry() { + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((group.clone(), after_group)); + } + + None + } + + /// If the cursor is pointing at a `Ident`, returns it along with a cursor + /// pointing at the next `TokenTree`. + pub fn ident(mut self) -> Option<(Ident, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump_ignore_group() })), + _ => None, + } + } + + /// If the cursor is pointing at a `Punct`, returns it along with a cursor + /// pointing at the next `TokenTree`. + pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() != '\'' => { + Some((punct.clone(), unsafe { self.bump_ignore_group() })) + } + _ => None, + } + } + + /// If the cursor is pointing at a `Literal`, return it along with a cursor + /// pointing at the next `TokenTree`. + pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump_ignore_group() })), + _ => None, + } + } + + /// If the cursor is pointing at a `Lifetime`, returns it along with a + /// cursor pointing at the next `TokenTree`. + pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { + let next = unsafe { self.bump_ignore_group() }; + let (ident, rest) = next.ident()?; + let lifetime = Lifetime { + apostrophe: punct.span(), + ident, + }; + Some((lifetime, rest)) + } + _ => None, + } + } + + /// Copies all remaining tokens visible from this cursor into a + /// `TokenStream`. + pub fn token_stream(self) -> TokenStream { + let mut tts = Vec::new(); + let mut cursor = self; + while let Some((tt, rest)) = cursor.token_tree() { + tts.push(tt); + cursor = rest; + } + tts.into_iter().collect() + } + + /// If the cursor is pointing at a `TokenTree`, returns it along with a + /// cursor pointing at the next `TokenTree`. + /// + /// Returns `None` if the cursor has reached the end of its stream. + /// + /// This method does not treat `None`-delimited groups as transparent, and + /// will return a `Group(None, ..)` if the cursor is looking at one. + pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> { + let (tree, len) = match self.entry() { + Entry::Group(group, end_offset) => (group.clone().into(), *end_offset), + Entry::Literal(literal) => (literal.clone().into(), 1), + Entry::Ident(ident) => (ident.clone().into(), 1), + Entry::Punct(punct) => (punct.clone().into(), 1), + Entry::End(_) => return None, + }; + + let rest = unsafe { Cursor::create(self.ptr.add(len), self.scope) }; + Some((tree, rest)) + } + + /// Returns the `Span` of the current token, or `Span::call_site()` if this + /// cursor points to eof. + pub fn span(self) -> Span { + match self.entry() { + Entry::Group(group, _) => group.span(), + Entry::Literal(literal) => literal.span(), + Entry::Ident(ident) => ident.span(), + Entry::Punct(punct) => punct.span(), + Entry::End(_) => Span::call_site(), + } + } + + /// Returns the `Span` of the token immediately prior to the position of + /// this cursor, or of the current token if there is no previous one. + #[cfg(any(feature = "full", feature = "derive"))] + pub(crate) fn prev_span(mut self) -> Span { + if start_of_buffer(self) < self.ptr { + self.ptr = unsafe { self.ptr.offset(-1) }; + if let Entry::End(_) = self.entry() { + // Locate the matching Group begin token. + let mut depth = 1; + loop { + self.ptr = unsafe { self.ptr.offset(-1) }; + match self.entry() { + Entry::Group(group, _) => { + depth -= 1; + if depth == 0 { + return group.span(); + } + } + Entry::End(_) => depth += 1, + Entry::Literal(_) | Entry::Ident(_) | Entry::Punct(_) => {} + } + } + } + } + self.span() + } + + /// Skip over the next token without cloning it. Returns `None` if this + /// cursor points to eof. + /// + /// This method treats `'lifetimes` as a single token. + pub(crate) fn skip(self) -> Option> { + let len = match self.entry() { + Entry::End(_) => return None, + + // Treat lifetimes as a single tt for the purposes of 'skip'. + Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { + match unsafe { &*self.ptr.add(1) } { + Entry::Ident(_) => 2, + _ => 1, + } + } + + Entry::Group(_, end_offset) => *end_offset, + _ => 1, + }; + + Some(unsafe { Cursor::create(self.ptr.add(len), self.scope) }) + } +} + +impl<'a> Copy for Cursor<'a> {} + +impl<'a> Clone for Cursor<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Eq for Cursor<'a> {} + +impl<'a> PartialEq for Cursor<'a> { + fn eq(&self, other: &Self) -> bool { + self.ptr == other.ptr + } +} + +impl<'a> PartialOrd for Cursor<'a> { + fn partial_cmp(&self, other: &Self) -> Option { + if same_buffer(*self, *other) { + Some(cmp_assuming_same_buffer(*self, *other)) + } else { + None + } + } +} + +pub(crate) fn same_scope(a: Cursor, b: Cursor) -> bool { + a.scope == b.scope +} + +pub(crate) fn same_buffer(a: Cursor, b: Cursor) -> bool { + start_of_buffer(a) == start_of_buffer(b) +} + +fn start_of_buffer(cursor: Cursor) -> *const Entry { + unsafe { + match &*cursor.scope { + Entry::End(offset) => cursor.scope.offset(*offset), + _ => unreachable!(), + } + } +} + +pub(crate) fn cmp_assuming_same_buffer(a: Cursor, b: Cursor) -> Ordering { + a.ptr.cmp(&b.ptr) +} + +pub(crate) fn open_span_of_group(cursor: Cursor) -> Span { + match cursor.entry() { + Entry::Group(group, _) => group.span_open(), + _ => cursor.span(), + } +} + +pub(crate) fn close_span_of_group(cursor: Cursor) -> Span { + match cursor.entry() { + Entry::Group(group, _) => group.span_close(), + _ => cursor.span(), + } +} diff --git a/utshell-0.5.0/vendor/syn/src/custom_keyword.rs b/utshell-0.5.0/vendor/syn/src/custom_keyword.rs new file mode 100644 index 00000000..6ce23db4 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/custom_keyword.rs @@ -0,0 +1,259 @@ +/// Define a type that supports parsing and printing a given identifier as if it +/// were a keyword. +/// +/// # Usage +/// +/// As a convention, it is recommended that this macro be invoked within a +/// module called `kw` or `keyword` and that the resulting parser be invoked +/// with a `kw::` or `keyword::` prefix. +/// +/// ``` +/// mod kw { +/// syn::custom_keyword!(whatever); +/// } +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in keyword token. +/// +/// - [Peeking] — `input.peek(kw::whatever)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #whatever_token ... )` +/// +/// - Construction from a [`Span`] — `let whatever_token = kw::whatever(sp)` +/// +/// - Field access to its span — `let sp = whatever_token.span` +/// +/// [Peeking]: crate::parse::ParseBuffer::peek +/// [Parsing]: crate::parse::ParseBuffer::parse +/// [Printing]: quote::ToTokens +/// [`Span`]: proc_macro2::Span +/// +/// # Example +/// +/// This example parses input that looks like `bool = true` or `str = "value"`. +/// The key must be either the identifier `bool` or the identifier `str`. If +/// `bool`, the value may be either `true` or `false`. If `str`, the value may +/// be any string literal. +/// +/// The symbols `bool` and `str` are not reserved keywords in Rust so these are +/// not considered keywords in the `syn::token` module. Like any other +/// identifier that is not a keyword, these can be declared as custom keywords +/// by crates that need to use them as such. +/// +/// ``` +/// use syn::{LitBool, LitStr, Result, Token}; +/// use syn::parse::{Parse, ParseStream}; +/// +/// mod kw { +/// syn::custom_keyword!(bool); +/// syn::custom_keyword!(str); +/// } +/// +/// enum Argument { +/// Bool { +/// bool_token: kw::bool, +/// eq_token: Token![=], +/// value: LitBool, +/// }, +/// Str { +/// str_token: kw::str, +/// eq_token: Token![=], +/// value: LitStr, +/// }, +/// } +/// +/// impl Parse for Argument { +/// fn parse(input: ParseStream) -> Result { +/// let lookahead = input.lookahead1(); +/// if lookahead.peek(kw::bool) { +/// Ok(Argument::Bool { +/// bool_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else if lookahead.peek(kw::str) { +/// Ok(Argument::Str { +/// str_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else { +/// Err(lookahead.error()) +/// } +/// } +/// } +/// ``` +#[macro_export] +macro_rules! custom_keyword { + ($ident:ident) => { + #[allow(non_camel_case_types)] + pub struct $ident { + pub span: $crate::__private::Span, + } + + #[doc(hidden)] + #[allow(dead_code, non_snake_case)] + pub fn $ident<__S: $crate::__private::IntoSpans<$crate::__private::Span>>( + span: __S, + ) -> $ident { + $ident { + span: $crate::__private::IntoSpans::into_spans(span), + } + } + + const _: () = { + impl $crate::__private::Default for $ident { + fn default() -> Self { + $ident { + span: $crate::__private::Span::call_site(), + } + } + } + + $crate::impl_parse_for_custom_keyword!($ident); + $crate::impl_to_tokens_for_custom_keyword!($ident); + $crate::impl_clone_for_custom_keyword!($ident); + $crate::impl_extra_traits_for_custom_keyword!($ident); + }; + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => { + // For peek. + impl $crate::__private::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { + if let $crate::__private::Some((ident, _rest)) = cursor.ident() { + ident == $crate::__private::stringify!($ident) + } else { + false + } + } + + fn display() -> &'static $crate::__private::str { + $crate::__private::concat!("`", $crate::__private::stringify!($ident), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + input.step(|cursor| { + if let $crate::__private::Some((ident, rest)) = cursor.ident() { + if ident == $crate::__private::stringify!($ident) { + return $crate::__private::Ok(($ident { span: ident.span() }, rest)); + } + } + $crate::__private::Err(cursor.error($crate::__private::concat!( + "expected `", + $crate::__private::stringify!($ident), + "`", + ))) + }) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { + let ident = $crate::Ident::new($crate::__private::stringify!($ident), self.span); + $crate::__private::TokenStreamExt::append(tokens, ident); + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::Copy for $ident {} + + #[allow(clippy::expl_impl_clone_on_copy)] + impl $crate::__private::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::Debug for $ident { + fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { + $crate::__private::Formatter::write_str( + f, + $crate::__private::concat!( + "Keyword [", + $crate::__private::stringify!($ident), + "]", + ), + ) + } + } + + impl $crate::__private::Eq for $ident {} + + impl $crate::__private::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::__private::bool { + true + } + } + + impl $crate::__private::Hash for $ident { + fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => {}; +} diff --git a/utshell-0.5.0/vendor/syn/src/custom_punctuation.rs b/utshell-0.5.0/vendor/syn/src/custom_punctuation.rs new file mode 100644 index 00000000..1b2c768f --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/custom_punctuation.rs @@ -0,0 +1,302 @@ +/// Define a type that supports parsing and printing a multi-character symbol +/// as if it were a punctuation token. +/// +/// # Usage +/// +/// ``` +/// syn::custom_punctuation!(LeftRightArrow, <=>); +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in punctuation token. +/// +/// - [Peeking] — `input.peek(LeftRightArrow)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #lrarrow ... )` +/// +/// - Construction from a [`Span`] — `let lrarrow = LeftRightArrow(sp)` +/// +/// - Construction from multiple [`Span`] — `let lrarrow = LeftRightArrow([sp, sp, sp])` +/// +/// - Field access to its spans — `let spans = lrarrow.spans` +/// +/// [Peeking]: crate::parse::ParseBuffer::peek +/// [Parsing]: crate::parse::ParseBuffer::parse +/// [Printing]: quote::ToTokens +/// [`Span`]: proc_macro2::Span +/// +/// # Example +/// +/// ``` +/// use proc_macro2::{TokenStream, TokenTree}; +/// use syn::parse::{Parse, ParseStream, Peek, Result}; +/// use syn::punctuated::Punctuated; +/// use syn::Expr; +/// +/// syn::custom_punctuation!(PathSeparator, ); +/// +/// // expr expr expr ... +/// struct PathSegments { +/// segments: Punctuated, +/// } +/// +/// impl Parse for PathSegments { +/// fn parse(input: ParseStream) -> Result { +/// let mut segments = Punctuated::new(); +/// +/// let first = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(first)?); +/// +/// while input.peek(PathSeparator) { +/// segments.push_punct(input.parse()?); +/// +/// let next = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(next)?); +/// } +/// +/// Ok(PathSegments { segments }) +/// } +/// } +/// +/// fn parse_until(input: ParseStream, end: E) -> Result { +/// let mut tokens = TokenStream::new(); +/// while !input.is_empty() && !input.peek(end) { +/// let next: TokenTree = input.parse()?; +/// tokens.extend(Some(next)); +/// } +/// Ok(tokens) +/// } +/// +/// fn main() { +/// let input = r#" a::b c::d::e "#; +/// let _: PathSegments = syn::parse_str(input).unwrap(); +/// } +/// ``` +#[macro_export] +macro_rules! custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + pub struct $ident { + pub spans: $crate::custom_punctuation_repr!($($tt)+), + } + + #[doc(hidden)] + #[allow(dead_code, non_snake_case)] + pub fn $ident<__S: $crate::__private::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>( + spans: __S, + ) -> $ident { + let _validate_len = 0 $(+ $crate::custom_punctuation_len!(strict, $tt))*; + $ident { + spans: $crate::__private::IntoSpans::into_spans(spans) + } + } + + const _: () = { + impl $crate::__private::Default for $ident { + fn default() -> Self { + $ident($crate::__private::Span::call_site()) + } + } + + $crate::impl_parse_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_to_tokens_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_clone_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_extra_traits_for_custom_punctuation!($ident, $($tt)+); + }; + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { + $crate::__private::peek_punct(cursor, $crate::stringify_punct!($($tt)+)) + } + + fn display() -> &'static $crate::__private::str { + $crate::__private::concat!("`", $crate::stringify_punct!($($tt)+), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + let spans: $crate::custom_punctuation_repr!($($tt)+) = + $crate::__private::parse_punct(input, $crate::stringify_punct!($($tt)+))?; + Ok($ident(spans)) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { + $crate::__private::print_punct($crate::stringify_punct!($($tt)+), &self.spans, tokens) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::Copy for $ident {} + + #[allow(clippy::expl_impl_clone_on_copy)] + impl $crate::__private::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::Debug for $ident { + fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { + $crate::__private::Formatter::write_str(f, $crate::__private::stringify!($ident)) + } + } + + impl $crate::__private::Eq for $ident {} + + impl $crate::__private::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::__private::bool { + true + } + } + + impl $crate::__private::Hash for $ident { + fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_repr { + ($($tt:tt)+) => { + [$crate::__private::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+] + }; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +#[rustfmt::skip] +macro_rules! custom_punctuation_len { + ($mode:ident, +) => { 1 }; + ($mode:ident, +=) => { 2 }; + ($mode:ident, &) => { 1 }; + ($mode:ident, &&) => { 2 }; + ($mode:ident, &=) => { 2 }; + ($mode:ident, @) => { 1 }; + ($mode:ident, !) => { 1 }; + ($mode:ident, ^) => { 1 }; + ($mode:ident, ^=) => { 2 }; + ($mode:ident, :) => { 1 }; + ($mode:ident, ::) => { 2 }; + ($mode:ident, ,) => { 1 }; + ($mode:ident, /) => { 1 }; + ($mode:ident, /=) => { 2 }; + ($mode:ident, .) => { 1 }; + ($mode:ident, ..) => { 2 }; + ($mode:ident, ...) => { 3 }; + ($mode:ident, ..=) => { 3 }; + ($mode:ident, =) => { 1 }; + ($mode:ident, ==) => { 2 }; + ($mode:ident, >=) => { 2 }; + ($mode:ident, >) => { 1 }; + ($mode:ident, <=) => { 2 }; + ($mode:ident, <) => { 1 }; + ($mode:ident, *=) => { 2 }; + ($mode:ident, !=) => { 2 }; + ($mode:ident, |) => { 1 }; + ($mode:ident, |=) => { 2 }; + ($mode:ident, ||) => { 2 }; + ($mode:ident, #) => { 1 }; + ($mode:ident, ?) => { 1 }; + ($mode:ident, ->) => { 2 }; + ($mode:ident, <-) => { 2 }; + ($mode:ident, %) => { 1 }; + ($mode:ident, %=) => { 2 }; + ($mode:ident, =>) => { 2 }; + ($mode:ident, ;) => { 1 }; + ($mode:ident, <<) => { 2 }; + ($mode:ident, <<=) => { 3 }; + ($mode:ident, >>) => { 2 }; + ($mode:ident, >>=) => { 3 }; + ($mode:ident, *) => { 1 }; + ($mode:ident, -) => { 1 }; + ($mode:ident, -=) => { 2 }; + ($mode:ident, ~) => { 1 }; + (lenient, $tt:tt) => { 0 }; + (strict, $tt:tt) => {{ $crate::custom_punctuation_unexpected!($tt); 0 }}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_unexpected { + () => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! stringify_punct { + ($($tt:tt)+) => { + $crate::__private::concat!($($crate::__private::stringify!($tt)),+) + }; +} diff --git a/utshell-0.5.0/vendor/syn/src/data.rs b/utshell-0.5.0/vendor/syn/src/data.rs new file mode 100644 index 00000000..9fb97e48 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/data.rs @@ -0,0 +1,423 @@ +use crate::attr::Attribute; +use crate::expr::Expr; +use crate::ident::Ident; +use crate::punctuated::{self, Punctuated}; +use crate::restriction::{FieldMutability, Visibility}; +use crate::token; +use crate::ty::Type; + +ast_struct! { + /// An enum variant. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Variant { + pub attrs: Vec, + + /// Name of the variant. + pub ident: Ident, + + /// Content stored in the variant. + pub fields: Fields, + + /// Explicit discriminant: `Variant = 1` + pub discriminant: Option<(Token![=], Expr)>, + } +} + +ast_enum_of_structs! { + /// Data stored within an enum variant or struct. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum Fields { + /// Named fields of a struct or struct variant such as `Point { x: f64, + /// y: f64 }`. + Named(FieldsNamed), + + /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. + Unnamed(FieldsUnnamed), + + /// Unit struct or unit variant such as `None`. + Unit, + } +} + +ast_struct! { + /// Named fields of a struct or struct variant such as `Point { x: f64, + /// y: f64 }`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct FieldsNamed { + pub brace_token: token::Brace, + pub named: Punctuated, + } +} + +ast_struct! { + /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct FieldsUnnamed { + pub paren_token: token::Paren, + pub unnamed: Punctuated, + } +} + +impl Fields { + /// Get an iterator over the borrowed [`Field`] items in this object. This + /// iterator can be used to iterate over a named or unnamed struct or + /// variant's fields uniformly. + pub fn iter(&self) -> punctuated::Iter { + match self { + Fields::Unit => crate::punctuated::empty_punctuated_iter(), + Fields::Named(f) => f.named.iter(), + Fields::Unnamed(f) => f.unnamed.iter(), + } + } + + /// Get an iterator over the mutably borrowed [`Field`] items in this + /// object. This iterator can be used to iterate over a named or unnamed + /// struct or variant's fields uniformly. + pub fn iter_mut(&mut self) -> punctuated::IterMut { + match self { + Fields::Unit => crate::punctuated::empty_punctuated_iter_mut(), + Fields::Named(f) => f.named.iter_mut(), + Fields::Unnamed(f) => f.unnamed.iter_mut(), + } + } + + /// Returns the number of fields. + pub fn len(&self) -> usize { + match self { + Fields::Unit => 0, + Fields::Named(f) => f.named.len(), + Fields::Unnamed(f) => f.unnamed.len(), + } + } + + /// Returns `true` if there are zero fields. + pub fn is_empty(&self) -> bool { + match self { + Fields::Unit => true, + Fields::Named(f) => f.named.is_empty(), + Fields::Unnamed(f) => f.unnamed.is_empty(), + } + } +} + +impl IntoIterator for Fields { + type Item = Field; + type IntoIter = punctuated::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + match self { + Fields::Unit => Punctuated::::new().into_iter(), + Fields::Named(f) => f.named.into_iter(), + Fields::Unnamed(f) => f.unnamed.into_iter(), + } + } +} + +impl<'a> IntoIterator for &'a Fields { + type Item = &'a Field; + type IntoIter = punctuated::Iter<'a, Field>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a> IntoIterator for &'a mut Fields { + type Item = &'a mut Field; + type IntoIter = punctuated::IterMut<'a, Field>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +ast_struct! { + /// A field of a struct or enum variant. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Field { + pub attrs: Vec, + + pub vis: Visibility, + + pub mutability: FieldMutability, + + /// Name of the field, if any. + /// + /// Fields of tuple structs have no names. + pub ident: Option, + + pub colon_token: Option, + + pub ty: Type, + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::Attribute; + use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant}; + use crate::error::Result; + use crate::expr::Expr; + use crate::ext::IdentExt as _; + use crate::ident::Ident; + #[cfg(not(feature = "full"))] + use crate::parse::discouraged::Speculative as _; + use crate::parse::{Parse, ParseStream}; + use crate::restriction::{FieldMutability, Visibility}; + use crate::token; + use crate::ty::Type; + use crate::verbatim; + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for Variant { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let _visibility: Visibility = input.parse()?; + let ident: Ident = input.parse()?; + let fields = if input.peek(token::Brace) { + Fields::Named(input.parse()?) + } else if input.peek(token::Paren) { + Fields::Unnamed(input.parse()?) + } else { + Fields::Unit + }; + let discriminant = if input.peek(Token![=]) { + let eq_token: Token![=] = input.parse()?; + #[cfg(feature = "full")] + let discriminant: Expr = input.parse()?; + #[cfg(not(feature = "full"))] + let discriminant = { + let begin = input.fork(); + let ahead = input.fork(); + let mut discriminant: Result = ahead.parse(); + if discriminant.is_ok() { + input.advance_to(&ahead); + } else if scan_lenient_discriminant(input).is_ok() { + discriminant = Ok(Expr::Verbatim(verbatim::between(&begin, input))); + } + discriminant? + }; + Some((eq_token, discriminant)) + } else { + None + }; + Ok(Variant { + attrs, + ident, + fields, + discriminant, + }) + } + } + + #[cfg(not(feature = "full"))] + pub(crate) fn scan_lenient_discriminant(input: ParseStream) -> Result<()> { + use crate::expr::Member; + use crate::lifetime::Lifetime; + use crate::lit::Lit; + use crate::lit::LitFloat; + use crate::op::{BinOp, UnOp}; + use crate::path::{self, AngleBracketedGenericArguments}; + use proc_macro2::Delimiter::{self, Brace, Bracket, Parenthesis}; + + let consume = |delimiter: Delimiter| { + Result::unwrap(input.step(|cursor| match cursor.group(delimiter) { + Some((_inside, _span, rest)) => Ok((true, rest)), + None => Ok((false, *cursor)), + })) + }; + + macro_rules! consume { + [$token:tt] => { + input.parse::>().unwrap().is_some() + }; + } + + let mut initial = true; + let mut depth = 0usize; + loop { + if initial { + if consume![&] { + input.parse::>()?; + } else if consume![if] || consume![match] || consume![while] { + depth += 1; + } else if input.parse::>()?.is_some() + || (consume(Brace) || consume(Bracket) || consume(Parenthesis)) + || (consume![async] || consume![const] || consume![loop] || consume![unsafe]) + && (consume(Brace) || break) + { + initial = false; + } else if consume![let] { + while !consume![=] { + if !((consume![|] || consume![ref] || consume![mut] || consume![@]) + || (consume![!] || input.parse::>()?.is_some()) + || (consume![..=] || consume![..] || consume![&] || consume![_]) + || (consume(Brace) || consume(Bracket) || consume(Parenthesis))) + { + path::parsing::qpath(input, true)?; + } + } + } else if input.parse::>()?.is_some() && !consume![:] { + break; + } else if input.parse::().is_err() { + path::parsing::qpath(input, true)?; + initial = consume![!] || depth == 0 && input.peek(token::Brace); + } + } else if input.is_empty() || input.peek(Token![,]) { + return Ok(()); + } else if depth > 0 && consume(Brace) { + if consume![else] && !consume(Brace) { + initial = consume![if] || break; + } else { + depth -= 1; + } + } else if input.parse::().is_ok() || (consume![..] | consume![=]) { + initial = true; + } else if consume![.] { + if input.parse::>()?.is_none() + && (input.parse::()?.is_named() && consume![::]) + { + AngleBracketedGenericArguments::do_parse(None, input)?; + } + } else if consume![as] { + input.parse::()?; + } else if !(consume(Brace) || consume(Bracket) || consume(Parenthesis)) { + break; + } + } + + Err(input.error("unsupported expression")) + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for FieldsNamed { + fn parse(input: ParseStream) -> Result { + let content; + Ok(FieldsNamed { + brace_token: braced!(content in input), + named: content.parse_terminated(Field::parse_named, Token![,])?, + }) + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for FieldsUnnamed { + fn parse(input: ParseStream) -> Result { + let content; + Ok(FieldsUnnamed { + paren_token: parenthesized!(content in input), + unnamed: content.parse_terminated(Field::parse_unnamed, Token![,])?, + }) + } + } + + impl Field { + /// Parses a named (braced struct) field. + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_named(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + + let unnamed_field = cfg!(feature = "full") && input.peek(Token![_]); + let ident = if unnamed_field { + input.call(Ident::parse_any) + } else { + input.parse() + }?; + + let colon_token: Token![:] = input.parse()?; + + let ty: Type = if unnamed_field + && (input.peek(Token![struct]) + || input.peek(Token![union]) && input.peek2(token::Brace)) + { + let begin = input.fork(); + input.call(Ident::parse_any)?; + input.parse::()?; + Type::Verbatim(verbatim::between(&begin, input)) + } else { + input.parse()? + }; + + Ok(Field { + attrs, + vis, + mutability: FieldMutability::None, + ident: Some(ident), + colon_token: Some(colon_token), + ty, + }) + } + + /// Parses an unnamed (tuple struct) field. + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + pub fn parse_unnamed(input: ParseStream) -> Result { + Ok(Field { + attrs: input.call(Attribute::parse_outer)?, + vis: input.parse()?, + mutability: FieldMutability::None, + ident: None, + colon_token: None, + ty: input.parse()?, + }) + } + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::data::{Field, FieldsNamed, FieldsUnnamed, Variant}; + use crate::print::TokensOrDefault; + use proc_macro2::TokenStream; + use quote::{ToTokens, TokenStreamExt}; + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for Variant { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.ident.to_tokens(tokens); + self.fields.to_tokens(tokens); + if let Some((eq_token, disc)) = &self.discriminant { + eq_token.to_tokens(tokens); + disc.to_tokens(tokens); + } + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for FieldsNamed { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.brace_token.surround(tokens, |tokens| { + self.named.to_tokens(tokens); + }); + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for FieldsUnnamed { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.paren_token.surround(tokens, |tokens| { + self.unnamed.to_tokens(tokens); + }); + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for Field { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.vis.to_tokens(tokens); + if let Some(ident) = &self.ident { + ident.to_tokens(tokens); + TokensOrDefault(&self.colon_token).to_tokens(tokens); + } + self.ty.to_tokens(tokens); + } + } +} diff --git a/utshell-0.5.0/vendor/syn/src/derive.rs b/utshell-0.5.0/vendor/syn/src/derive.rs new file mode 100644 index 00000000..dbb2cf6a --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/derive.rs @@ -0,0 +1,259 @@ +use crate::attr::Attribute; +use crate::data::{Fields, FieldsNamed, Variant}; +use crate::generics::Generics; +use crate::ident::Ident; +use crate::punctuated::Punctuated; +use crate::restriction::Visibility; +use crate::token; + +ast_struct! { + /// Data structure sent to a `proc_macro_derive` macro. + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] + pub struct DeriveInput { + pub attrs: Vec, + pub vis: Visibility, + pub ident: Ident, + pub generics: Generics, + pub data: Data, + } +} + +ast_enum! { + /// The storage of a struct, enum or union data structure. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] + pub enum Data { + Struct(DataStruct), + Enum(DataEnum), + Union(DataUnion), + } +} + +ast_struct! { + /// A struct input to a `proc_macro_derive` macro. + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] + pub struct DataStruct { + pub struct_token: Token![struct], + pub fields: Fields, + pub semi_token: Option, + } +} + +ast_struct! { + /// An enum input to a `proc_macro_derive` macro. + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] + pub struct DataEnum { + pub enum_token: Token![enum], + pub brace_token: token::Brace, + pub variants: Punctuated, + } +} + +ast_struct! { + /// An untagged union input to a `proc_macro_derive` macro. + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] + pub struct DataUnion { + pub union_token: Token![union], + pub fields: FieldsNamed, + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::Attribute; + use crate::data::{Fields, FieldsNamed, Variant}; + use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}; + use crate::error::Result; + use crate::generics::{Generics, WhereClause}; + use crate::ident::Ident; + use crate::parse::{Parse, ParseStream}; + use crate::punctuated::Punctuated; + use crate::restriction::Visibility; + use crate::token; + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for DeriveInput { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis = input.parse::()?; + + let lookahead = input.lookahead1(); + if lookahead.peek(Token![struct]) { + let struct_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, fields, semi) = data_struct(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Struct(DataStruct { + struct_token, + fields, + semi_token: semi, + }), + }) + } else if lookahead.peek(Token![enum]) { + let enum_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, brace, variants) = data_enum(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Enum(DataEnum { + enum_token, + brace_token: brace, + variants, + }), + }) + } else if lookahead.peek(Token![union]) { + let union_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, fields) = data_union(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Union(DataUnion { + union_token, + fields, + }), + }) + } else { + Err(lookahead.error()) + } + } + } + + pub(crate) fn data_struct( + input: ParseStream, + ) -> Result<(Option, Fields, Option)> { + let mut lookahead = input.lookahead1(); + let mut where_clause = None; + if lookahead.peek(Token![where]) { + where_clause = Some(input.parse()?); + lookahead = input.lookahead1(); + } + + if where_clause.is_none() && lookahead.peek(token::Paren) { + let fields = input.parse()?; + + lookahead = input.lookahead1(); + if lookahead.peek(Token![where]) { + where_clause = Some(input.parse()?); + lookahead = input.lookahead1(); + } + + if lookahead.peek(Token![;]) { + let semi = input.parse()?; + Ok((where_clause, Fields::Unnamed(fields), Some(semi))) + } else { + Err(lookahead.error()) + } + } else if lookahead.peek(token::Brace) { + let fields = input.parse()?; + Ok((where_clause, Fields::Named(fields), None)) + } else if lookahead.peek(Token![;]) { + let semi = input.parse()?; + Ok((where_clause, Fields::Unit, Some(semi))) + } else { + Err(lookahead.error()) + } + } + + pub(crate) fn data_enum( + input: ParseStream, + ) -> Result<( + Option, + token::Brace, + Punctuated, + )> { + let where_clause = input.parse()?; + + let content; + let brace = braced!(content in input); + let variants = content.parse_terminated(Variant::parse, Token![,])?; + + Ok((where_clause, brace, variants)) + } + + pub(crate) fn data_union(input: ParseStream) -> Result<(Option, FieldsNamed)> { + let where_clause = input.parse()?; + let fields = input.parse()?; + Ok((where_clause, fields)) + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::attr::FilterAttrs; + use crate::data::Fields; + use crate::derive::{Data, DeriveInput}; + use crate::print::TokensOrDefault; + use proc_macro2::TokenStream; + use quote::ToTokens; + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for DeriveInput { + fn to_tokens(&self, tokens: &mut TokenStream) { + for attr in self.attrs.outer() { + attr.to_tokens(tokens); + } + self.vis.to_tokens(tokens); + match &self.data { + Data::Struct(d) => d.struct_token.to_tokens(tokens), + Data::Enum(d) => d.enum_token.to_tokens(tokens), + Data::Union(d) => d.union_token.to_tokens(tokens), + } + self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); + match &self.data { + Data::Struct(data) => match &data.fields { + Fields::Named(fields) => { + self.generics.where_clause.to_tokens(tokens); + fields.to_tokens(tokens); + } + Fields::Unnamed(fields) => { + fields.to_tokens(tokens); + self.generics.where_clause.to_tokens(tokens); + TokensOrDefault(&data.semi_token).to_tokens(tokens); + } + Fields::Unit => { + self.generics.where_clause.to_tokens(tokens); + TokensOrDefault(&data.semi_token).to_tokens(tokens); + } + }, + Data::Enum(data) => { + self.generics.where_clause.to_tokens(tokens); + data.brace_token.surround(tokens, |tokens| { + data.variants.to_tokens(tokens); + }); + } + Data::Union(data) => { + self.generics.where_clause.to_tokens(tokens); + data.fields.to_tokens(tokens); + } + } + } + } +} diff --git a/utshell-0.5.0/vendor/syn/src/discouraged.rs b/utshell-0.5.0/vendor/syn/src/discouraged.rs new file mode 100644 index 00000000..7ed51c96 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/discouraged.rs @@ -0,0 +1,225 @@ +//! Extensions to the parsing API with niche applicability. + +use crate::buffer::Cursor; +use crate::error::Result; +use crate::parse::{inner_unexpected, ParseBuffer, Unexpected}; +use proc_macro2::extra::DelimSpan; +use proc_macro2::Delimiter; +use std::cell::Cell; +use std::mem; +use std::rc::Rc; + +/// Extensions to the `ParseStream` API to support speculative parsing. +pub trait Speculative { + /// Advance this parse stream to the position of a forked parse stream. + /// + /// This is the opposite operation to [`ParseStream::fork`]. You can fork a + /// parse stream, perform some speculative parsing, then join the original + /// stream to the fork to "commit" the parsing from the fork to the main + /// stream. + /// + /// If you can avoid doing this, you should, as it limits the ability to + /// generate useful errors. That said, it is often the only way to parse + /// syntax of the form `A* B*` for arbitrary syntax `A` and `B`. The problem + /// is that when the fork fails to parse an `A`, it's impossible to tell + /// whether that was because of a syntax error and the user meant to provide + /// an `A`, or that the `A`s are finished and it's time to start parsing + /// `B`s. Use with care. + /// + /// Also note that if `A` is a subset of `B`, `A* B*` can be parsed by + /// parsing `B*` and removing the leading members of `A` from the + /// repetition, bypassing the need to involve the downsides associated with + /// speculative parsing. + /// + /// [`ParseStream::fork`]: ParseBuffer::fork + /// + /// # Example + /// + /// There has been chatter about the possibility of making the colons in the + /// turbofish syntax like `path::to::` no longer required by accepting + /// `path::to` in expression position. Specifically, according to [RFC + /// 2544], [`PathSegment`] parsing should always try to consume a following + /// `<` token as the start of generic arguments, and reset to the `<` if + /// that fails (e.g. the token is acting as a less-than operator). + /// + /// This is the exact kind of parsing behavior which requires the "fork, + /// try, commit" behavior that [`ParseStream::fork`] discourages. With + /// `advance_to`, we can avoid having to parse the speculatively parsed + /// content a second time. + /// + /// This change in behavior can be implemented in syn by replacing just the + /// `Parse` implementation for `PathSegment`: + /// + /// ``` + /// # use syn::ext::IdentExt; + /// use syn::parse::discouraged::Speculative; + /// # use syn::parse::{Parse, ParseStream}; + /// # use syn::{Ident, PathArguments, Result, Token}; + /// + /// pub struct PathSegment { + /// pub ident: Ident, + /// pub arguments: PathArguments, + /// } + /// # + /// # impl From for PathSegment + /// # where + /// # T: Into, + /// # { + /// # fn from(ident: T) -> Self { + /// # PathSegment { + /// # ident: ident.into(), + /// # arguments: PathArguments::None, + /// # } + /// # } + /// # } + /// + /// impl Parse for PathSegment { + /// fn parse(input: ParseStream) -> Result { + /// if input.peek(Token![super]) + /// || input.peek(Token![self]) + /// || input.peek(Token![Self]) + /// || input.peek(Token![crate]) + /// { + /// let ident = input.call(Ident::parse_any)?; + /// return Ok(PathSegment::from(ident)); + /// } + /// + /// let ident = input.parse()?; + /// if input.peek(Token![::]) && input.peek3(Token![<]) { + /// return Ok(PathSegment { + /// ident, + /// arguments: PathArguments::AngleBracketed(input.parse()?), + /// }); + /// } + /// if input.peek(Token![<]) && !input.peek(Token![<=]) { + /// let fork = input.fork(); + /// if let Ok(arguments) = fork.parse() { + /// input.advance_to(&fork); + /// return Ok(PathSegment { + /// ident, + /// arguments: PathArguments::AngleBracketed(arguments), + /// }); + /// } + /// } + /// Ok(PathSegment::from(ident)) + /// } + /// } + /// + /// # syn::parse_str::("a").unwrap(); + /// ``` + /// + /// # Drawbacks + /// + /// The main drawback of this style of speculative parsing is in error + /// presentation. Even if the lookahead is the "correct" parse, the error + /// that is shown is that of the "fallback" parse. To use the same example + /// as the turbofish above, take the following unfinished "turbofish": + /// + /// ```text + /// let _ = f<&'a fn(), for<'a> serde::>(); + /// ``` + /// + /// If this is parsed as generic arguments, we can provide the error message + /// + /// ```text + /// error: expected identifier + /// --> src.rs:L:C + /// | + /// L | let _ = f<&'a fn(), for<'a> serde::>(); + /// | ^ + /// ``` + /// + /// but if parsed using the above speculative parsing, it falls back to + /// assuming that the `<` is a less-than when it fails to parse the generic + /// arguments, and tries to interpret the `&'a` as the start of a labelled + /// loop, resulting in the much less helpful error + /// + /// ```text + /// error: expected `:` + /// --> src.rs:L:C + /// | + /// L | let _ = f<&'a fn(), for<'a> serde::>(); + /// | ^^ + /// ``` + /// + /// This can be mitigated with various heuristics (two examples: show both + /// forks' parse errors, or show the one that consumed more tokens), but + /// when you can control the grammar, sticking to something that can be + /// parsed LL(3) and without the LL(*) speculative parsing this makes + /// possible, displaying reasonable errors becomes much more simple. + /// + /// [RFC 2544]: https://github.com/rust-lang/rfcs/pull/2544 + /// [`PathSegment`]: crate::PathSegment + /// + /// # Performance + /// + /// This method performs a cheap fixed amount of work that does not depend + /// on how far apart the two streams are positioned. + /// + /// # Panics + /// + /// The forked stream in the argument of `advance_to` must have been + /// obtained by forking `self`. Attempting to advance to any other stream + /// will cause a panic. + fn advance_to(&self, fork: &Self); +} + +impl<'a> Speculative for ParseBuffer<'a> { + fn advance_to(&self, fork: &Self) { + if !crate::buffer::same_scope(self.cursor(), fork.cursor()) { + panic!("Fork was not derived from the advancing parse stream"); + } + + let (self_unexp, self_sp) = inner_unexpected(self); + let (fork_unexp, fork_sp) = inner_unexpected(fork); + if !Rc::ptr_eq(&self_unexp, &fork_unexp) { + match (fork_sp, self_sp) { + // Unexpected set on the fork, but not on `self`, copy it over. + (Some(span), None) => { + self_unexp.set(Unexpected::Some(span)); + } + // Unexpected unset. Use chain to propagate errors from fork. + (None, None) => { + fork_unexp.set(Unexpected::Chain(self_unexp)); + + // Ensure toplevel 'unexpected' tokens from the fork don't + // bubble up the chain by replacing the root `unexpected` + // pointer, only 'unexpected' tokens from existing group + // parsers should bubble. + fork.unexpected + .set(Some(Rc::new(Cell::new(Unexpected::None)))); + } + // Unexpected has been set on `self`. No changes needed. + (_, Some(_)) => {} + } + } + + // See comment on `cell` in the struct definition. + self.cell + .set(unsafe { mem::transmute::>(fork.cursor()) }); + } +} + +/// Extensions to the `ParseStream` API to support manipulating invisible +/// delimiters the same as if they were visible. +pub trait AnyDelimiter { + /// Returns the delimiter, the span of the delimiter token, and the nested + /// contents for further parsing. + fn parse_any_delimiter(&self) -> Result<(Delimiter, DelimSpan, ParseBuffer)>; +} + +impl<'a> AnyDelimiter for ParseBuffer<'a> { + fn parse_any_delimiter(&self) -> Result<(Delimiter, DelimSpan, ParseBuffer)> { + self.step(|cursor| { + if let Some((content, delimiter, span, rest)) = cursor.any_group() { + let scope = crate::buffer::close_span_of_group(*cursor); + let nested = crate::parse::advance_step_cursor(cursor, content); + let unexpected = crate::parse::get_unexpected(self); + let content = crate::parse::new_parse_buffer(scope, nested, unexpected); + Ok(((delimiter, span, content), rest)) + } else { + Err(cursor.error("expected any delimiter")) + } + }) + } +} diff --git a/utshell-0.5.0/vendor/syn/src/drops.rs b/utshell-0.5.0/vendor/syn/src/drops.rs new file mode 100644 index 00000000..89b42d82 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/drops.rs @@ -0,0 +1,58 @@ +use std::iter; +use std::mem::ManuallyDrop; +use std::ops::{Deref, DerefMut}; +use std::option; +use std::slice; + +#[repr(transparent)] +pub(crate) struct NoDrop(ManuallyDrop); + +impl NoDrop { + pub(crate) fn new(value: T) -> Self + where + T: TrivialDrop, + { + NoDrop(ManuallyDrop::new(value)) + } +} + +impl Deref for NoDrop { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NoDrop { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +pub(crate) trait TrivialDrop {} + +impl TrivialDrop for iter::Empty {} +impl<'a, T> TrivialDrop for slice::Iter<'a, T> {} +impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {} +impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {} +impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {} + +#[test] +fn test_needs_drop() { + use std::mem::needs_drop; + + struct NeedsDrop; + + impl Drop for NeedsDrop { + fn drop(&mut self) {} + } + + assert!(needs_drop::()); + + // Test each of the types with a handwritten TrivialDrop impl above. + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); +} diff --git a/utshell-0.5.0/vendor/syn/src/error.rs b/utshell-0.5.0/vendor/syn/src/error.rs new file mode 100644 index 00000000..71247cde --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/error.rs @@ -0,0 +1,467 @@ +#[cfg(feature = "parsing")] +use crate::buffer::Cursor; +use crate::thread::ThreadBound; +use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, +}; +#[cfg(feature = "printing")] +use quote::ToTokens; +use std::fmt::{self, Debug, Display}; +use std::slice; +use std::vec; + +/// The result of a Syn parser. +pub type Result = std::result::Result; + +/// Error returned when a Syn parser cannot parse the input tokens. +/// +/// # Error reporting in proc macros +/// +/// The correct way to report errors back to the compiler from a procedural +/// macro is by emitting an appropriately spanned invocation of +/// [`compile_error!`] in the generated code. This produces a better diagnostic +/// message than simply panicking the macro. +/// +/// [`compile_error!`]: std::compile_error! +/// +/// When parsing macro input, the [`parse_macro_input!`] macro handles the +/// conversion to `compile_error!` automatically. +/// +/// [`parse_macro_input!`]: crate::parse_macro_input! +/// +/// ``` +/// # extern crate proc_macro; +/// # +/// use proc_macro::TokenStream; +/// use syn::parse::{Parse, ParseStream, Result}; +/// use syn::{parse_macro_input, ItemFn}; +/// +/// # const IGNORE: &str = stringify! { +/// #[proc_macro_attribute] +/// # }; +/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream { +/// let args = parse_macro_input!(args as MyAttrArgs); +/// let input = parse_macro_input!(input as ItemFn); +/// +/// /* ... */ +/// # TokenStream::new() +/// } +/// +/// struct MyAttrArgs { +/// # _k: [(); { stringify! { +/// ... +/// # }; 0 }] +/// } +/// +/// impl Parse for MyAttrArgs { +/// fn parse(input: ParseStream) -> Result { +/// # stringify! { +/// ... +/// # }; +/// # unimplemented!() +/// } +/// } +/// ``` +/// +/// For errors that arise later than the initial parsing stage, the +/// [`.to_compile_error()`] or [`.into_compile_error()`] methods can be used to +/// perform an explicit conversion to `compile_error!`. +/// +/// [`.to_compile_error()`]: Error::to_compile_error +/// [`.into_compile_error()`]: Error::into_compile_error +/// +/// ``` +/// # extern crate proc_macro; +/// # +/// # use proc_macro::TokenStream; +/// # use syn::{parse_macro_input, DeriveInput}; +/// # +/// # const IGNORE: &str = stringify! { +/// #[proc_macro_derive(MyDerive)] +/// # }; +/// pub fn my_derive(input: TokenStream) -> TokenStream { +/// let input = parse_macro_input!(input as DeriveInput); +/// +/// // fn(DeriveInput) -> syn::Result +/// expand::my_derive(input) +/// .unwrap_or_else(syn::Error::into_compile_error) +/// .into() +/// } +/// # +/// # mod expand { +/// # use proc_macro2::TokenStream; +/// # use syn::{DeriveInput, Result}; +/// # +/// # pub fn my_derive(input: DeriveInput) -> Result { +/// # unimplemented!() +/// # } +/// # } +/// ``` +pub struct Error { + messages: Vec, +} + +struct ErrorMessage { + // Span is implemented as an index into a thread-local interner to keep the + // size small. It is not safe to access from a different thread. We want + // errors to be Send and Sync to play nicely with ecosystem crates for error + // handling, so pin the span we're given to its original thread and assume + // it is Span::call_site if accessed from any other thread. + span: ThreadBound, + message: String, +} + +// Cannot use std::ops::Range because that does not implement Copy, +// whereas ThreadBound requires a Copy impl as a way to ensure no Drop impls +// are involved. +struct SpanRange { + start: Span, + end: Span, +} + +#[cfg(test)] +struct _Test +where + Error: Send + Sync; + +impl Error { + /// Usually the [`ParseStream::error`] method will be used instead, which + /// automatically uses the correct span from the current position of the + /// parse stream. + /// + /// Use `Error::new` when the error needs to be triggered on some span other + /// than where the parse stream is currently positioned. + /// + /// [`ParseStream::error`]: crate::parse::ParseBuffer::error + /// + /// # Example + /// + /// ``` + /// use syn::{Error, Ident, LitStr, Result, Token}; + /// use syn::parse::ParseStream; + /// + /// // Parses input that looks like `name = "string"` where the key must be + /// // the identifier `name` and the value may be any string literal. + /// // Returns the string literal. + /// fn parse_name(input: ParseStream) -> Result { + /// let name_token: Ident = input.parse()?; + /// if name_token != "name" { + /// // Trigger an error not on the current position of the stream, + /// // but on the position of the unexpected identifier. + /// return Err(Error::new(name_token.span(), "expected `name`")); + /// } + /// input.parse::()?; + /// let s: LitStr = input.parse()?; + /// Ok(s) + /// } + /// ``` + pub fn new(span: Span, message: T) -> Self { + return new(span, message.to_string()); + + fn new(span: Span, message: String) -> Error { + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { + start: span, + end: span, + }), + message, + }], + } + } + } + + /// Creates an error with the specified message spanning the given syntax + /// tree node. + /// + /// Unlike the `Error::new` constructor, this constructor takes an argument + /// `tokens` which is a syntax tree node. This allows the resulting `Error` + /// to attempt to span all tokens inside of `tokens`. While you would + /// typically be able to use the `Spanned` trait with the above `Error::new` + /// constructor, implementation limitations today mean that + /// `Error::new_spanned` may provide a higher-quality error message on + /// stable Rust. + /// + /// When in doubt it's recommended to stick to `Error::new` (or + /// `ParseStream::error`)! + #[cfg(feature = "printing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + pub fn new_spanned(tokens: T, message: U) -> Self { + return new_spanned(tokens.into_token_stream(), message.to_string()); + + fn new_spanned(tokens: TokenStream, message: String) -> Error { + let mut iter = tokens.into_iter(); + let start = iter.next().map_or_else(Span::call_site, |t| t.span()); + let end = iter.last().map_or(start, |t| t.span()); + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { start, end }), + message, + }], + } + } + } + + /// The source location of the error. + /// + /// Spans are not thread-safe so this function returns `Span::call_site()` + /// if called from a different thread than the one on which the `Error` was + /// originally created. + pub fn span(&self) -> Span { + let SpanRange { start, end } = match self.messages[0].span.get() { + Some(span) => *span, + None => return Span::call_site(), + }; + start.join(end).unwrap_or(start) + } + + /// Render the error as an invocation of [`compile_error!`]. + /// + /// The [`parse_macro_input!`] macro provides a convenient way to invoke + /// this method correctly in a procedural macro. + /// + /// [`compile_error!`]: std::compile_error! + /// [`parse_macro_input!`]: crate::parse_macro_input! + pub fn to_compile_error(&self) -> TokenStream { + self.messages + .iter() + .map(ErrorMessage::to_compile_error) + .collect() + } + + /// Render the error as an invocation of [`compile_error!`]. + /// + /// [`compile_error!`]: std::compile_error! + /// + /// # Example + /// + /// ``` + /// # extern crate proc_macro; + /// # + /// use proc_macro::TokenStream; + /// use syn::{parse_macro_input, DeriveInput, Error}; + /// + /// # const _: &str = stringify! { + /// #[proc_macro_derive(MyTrait)] + /// # }; + /// pub fn derive_my_trait(input: TokenStream) -> TokenStream { + /// let input = parse_macro_input!(input as DeriveInput); + /// my_trait::expand(input) + /// .unwrap_or_else(Error::into_compile_error) + /// .into() + /// } + /// + /// mod my_trait { + /// use proc_macro2::TokenStream; + /// use syn::{DeriveInput, Result}; + /// + /// pub(crate) fn expand(input: DeriveInput) -> Result { + /// /* ... */ + /// # unimplemented!() + /// } + /// } + /// ``` + pub fn into_compile_error(self) -> TokenStream { + self.to_compile_error() + } + + /// Add another error message to self such that when `to_compile_error()` is + /// called, both errors will be emitted together. + pub fn combine(&mut self, another: Error) { + self.messages.extend(another.messages); + } +} + +impl ErrorMessage { + fn to_compile_error(&self) -> TokenStream { + let (start, end) = match self.span.get() { + Some(range) => (range.start, range.end), + None => (Span::call_site(), Span::call_site()), + }; + + // ::core::compile_error!($message) + TokenStream::from_iter(vec![ + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Joint); + punct.set_span(start); + punct + }), + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Alone); + punct.set_span(start); + punct + }), + TokenTree::Ident(Ident::new("core", start)), + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Joint); + punct.set_span(start); + punct + }), + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Alone); + punct.set_span(start); + punct + }), + TokenTree::Ident(Ident::new("compile_error", start)), + TokenTree::Punct({ + let mut punct = Punct::new('!', Spacing::Alone); + punct.set_span(start); + punct + }), + TokenTree::Group({ + let mut group = Group::new(Delimiter::Brace, { + TokenStream::from_iter(vec![TokenTree::Literal({ + let mut string = Literal::string(&self.message); + string.set_span(end); + string + })]) + }); + group.set_span(end); + group + }), + ]) + } +} + +#[cfg(feature = "parsing")] +pub(crate) fn new_at(scope: Span, cursor: Cursor, message: T) -> Error { + if cursor.eof() { + Error::new(scope, format!("unexpected end of input, {}", message)) + } else { + let span = crate::buffer::open_span_of_group(cursor); + Error::new(span, message) + } +} + +#[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))] +pub(crate) fn new2(start: Span, end: Span, message: T) -> Error { + return new2(start, end, message.to_string()); + + fn new2(start: Span, end: Span, message: String) -> Error { + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { start, end }), + message, + }], + } + } +} + +impl Debug for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.messages.len() == 1 { + formatter + .debug_tuple("Error") + .field(&self.messages[0]) + .finish() + } else { + formatter + .debug_tuple("Error") + .field(&self.messages) + .finish() + } + } +} + +impl Debug for ErrorMessage { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.message, formatter) + } +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(&self.messages[0].message) + } +} + +impl Clone for Error { + fn clone(&self) -> Self { + Error { + messages: self.messages.clone(), + } + } +} + +impl Clone for ErrorMessage { + fn clone(&self) -> Self { + ErrorMessage { + span: self.span, + message: self.message.clone(), + } + } +} + +impl Clone for SpanRange { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SpanRange {} + +impl std::error::Error for Error {} + +impl From for Error { + fn from(err: LexError) -> Self { + Error::new(err.span(), err) + } +} + +impl IntoIterator for Error { + type Item = Error; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { + messages: self.messages.into_iter(), + } + } +} + +pub struct IntoIter { + messages: vec::IntoIter, +} + +impl Iterator for IntoIter { + type Item = Error; + + fn next(&mut self) -> Option { + Some(Error { + messages: vec![self.messages.next()?], + }) + } +} + +impl<'a> IntoIterator for &'a Error { + type Item = Error; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + Iter { + messages: self.messages.iter(), + } + } +} + +pub struct Iter<'a> { + messages: slice::Iter<'a, ErrorMessage>, +} + +impl<'a> Iterator for Iter<'a> { + type Item = Error; + + fn next(&mut self) -> Option { + Some(Error { + messages: vec![self.messages.next()?.clone()], + }) + } +} + +impl Extend for Error { + fn extend>(&mut self, iter: T) { + for err in iter { + self.combine(err); + } + } +} diff --git a/utshell-0.5.0/vendor/syn/src/export.rs b/utshell-0.5.0/vendor/syn/src/export.rs new file mode 100644 index 00000000..b9ea5c74 --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/export.rs @@ -0,0 +1,73 @@ +#[doc(hidden)] +pub use std::clone::Clone; +#[doc(hidden)] +pub use std::cmp::{Eq, PartialEq}; +#[doc(hidden)] +pub use std::concat; +#[doc(hidden)] +pub use std::default::Default; +#[doc(hidden)] +pub use std::fmt::Debug; +#[doc(hidden)] +pub use std::hash::{Hash, Hasher}; +#[doc(hidden)] +pub use std::marker::Copy; +#[doc(hidden)] +pub use std::option::Option::{None, Some}; +#[doc(hidden)] +pub use std::result::Result::{Err, Ok}; +#[doc(hidden)] +pub use std::stringify; + +#[doc(hidden)] +pub type Formatter<'a> = std::fmt::Formatter<'a>; +#[doc(hidden)] +pub type FmtResult = std::fmt::Result; + +#[doc(hidden)] +pub type bool = std::primitive::bool; +#[doc(hidden)] +pub type str = std::primitive::str; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use quote; + +#[doc(hidden)] +pub type Span = proc_macro2::Span; +#[doc(hidden)] +pub type TokenStream2 = proc_macro2::TokenStream; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::group::{parse_braces, parse_brackets, parse_parens}; + +#[doc(hidden)] +pub use crate::span::IntoSpans; + +#[cfg(all(feature = "parsing", feature = "printing"))] +#[doc(hidden)] +pub use crate::parse_quote::parse as parse_quote; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::token::parsing::{peek_punct, punct as parse_punct}; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use crate::token::printing::punct as print_punct; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::token::private::CustomToken; + +#[cfg(feature = "proc-macro")] +#[doc(hidden)] +pub type TokenStream = proc_macro::TokenStream; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use quote::{ToTokens, TokenStreamExt}; + +#[doc(hidden)] +pub struct private(pub(crate) ()); diff --git a/utshell-0.5.0/vendor/syn/src/expr.rs b/utshell-0.5.0/vendor/syn/src/expr.rs new file mode 100644 index 00000000..4229864a --- /dev/null +++ b/utshell-0.5.0/vendor/syn/src/expr.rs @@ -0,0 +1,3574 @@ +use crate::attr::Attribute; +#[cfg(feature = "full")] +use crate::generics::BoundLifetimes; +use crate::ident::Ident; +#[cfg(feature = "full")] +use crate::lifetime::Lifetime; +use crate::lit::Lit; +use crate::mac::Macro; +use crate::op::{BinOp, UnOp}; +#[cfg(feature = "full")] +use crate::pat::Pat; +use crate::path::{AngleBracketedGenericArguments, Path, QSelf}; +use crate::punctuated::Punctuated; +#[cfg(feature = "full")] +use crate::stmt::Block; +use crate::token; +#[cfg(feature = "full")] +use crate::ty::ReturnType; +use crate::ty::Type; +use proc_macro2::{Span, TokenStream}; +#[cfg(feature = "printing")] +use quote::IdentFragment; +#[cfg(feature = "printing")] +use std::fmt::{self, Display}; +use std::hash::{Hash, Hasher}; +#[cfg(all(feature = "parsing", feature = "full"))] +use std::mem; + +ast_enum_of_structs! { + /// A Rust expression. + /// + /// *This type is available only if Syn is built with the `"derive"` or `"full"` + /// feature, but most of the variants are not available unless "full" is enabled.* + /// + /// # Syntax tree enums + /// + /// This type is a syntax tree enum. In Syn this and other syntax tree enums + /// are designed to be traversed using the following rebinding idiom. + /// + /// ``` + /// # use syn::Expr; + /// # + /// # fn example(expr: Expr) { + /// # const IGNORE: &str = stringify! { + /// let expr: Expr = /* ... */; + /// # }; + /// match expr { + /// Expr::MethodCall(expr) => { + /// /* ... */ + /// } + /// Expr::Cast(expr) => { + /// /* ... */ + /// } + /// Expr::If(expr) => { + /// /* ... */ + /// } + /// + /// /* ... */ + /// # _ => {} + /// # } + /// # } + /// ``` + /// + /// We begin with a variable `expr` of type `Expr` that has no fields + /// (because it is an enum), and by matching on it and rebinding a variable + /// with the same name `expr` we effectively imbue our variable with all of + /// the data fields provided by the variant that it turned out to be. So for + /// example above if we ended up in the `MethodCall` case then we get to use + /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get + /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`. + /// + /// This approach avoids repeating the variant names twice on every line. + /// + /// ``` + /// # use syn::{Expr, ExprMethodCall}; + /// # + /// # fn example(expr: Expr) { + /// // Repetitive; recommend not doing this. + /// match expr { + /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { + /// # } + /// # _ => {} + /// # } + /// # } + /// ``` + /// + /// In general, the name to which a syntax tree enum variant is bound should + /// be a suitable name for the complete syntax tree enum type. + /// + /// ``` + /// # use syn::{Expr, ExprField}; + /// # + /// # fn example(discriminant: ExprField) { + /// // Binding is called `base` which is the name I would use if I were + /// // assigning `*discriminant.base` without an `if let`. + /// if let Expr::Tuple(base) = *discriminant.base { + /// # } + /// # } + /// ``` + /// + /// A sign that you may not be choosing the right variable names is if you + /// see names getting repeated in your code, like accessing + /// `receiver.receiver` or `pat.pat` or `cond.cond`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + #[non_exhaustive] + pub enum Expr { + /// A slice literal expression: `[a, b, c, d]`. + Array(ExprArray), + + /// An assignment expression: `a = compute()`. + Assign(ExprAssign), + + /// An async block: `async { ... }`. + Async(ExprAsync), + + /// An await expression: `fut.await`. + Await(ExprAwait), + + /// A binary operation: `a + b`, `a += b`. + Binary(ExprBinary), + + /// A blocked scope: `{ ... }`. + Block(ExprBlock), + + /// A `break`, with an optional label to break and an optional + /// expression. + Break(ExprBreak), + + /// A function call expression: `invoke(a, b)`. + Call(ExprCall), + + /// A cast expression: `foo as f64`. + Cast(ExprCast), + + /// A closure expression: `|a, b| a + b`. + Closure(ExprClosure), + + /// A const block: `const { ... }`. + Const(ExprConst), + + /// A `continue`, with an optional label. + Continue(ExprContinue), + + /// Access of a named struct field (`obj.k`) or unnamed tuple struct + /// field (`obj.0`). + Field(ExprField), + + /// A for loop: `for pat in expr { ... }`. + ForLoop(ExprForLoop), + + /// An expression contained within invisible delimiters. + /// + /// This variant is important for faithfully representing the precedence + /// of expressions and is related to `None`-delimited spans in a + /// `TokenStream`. + Group(ExprGroup), + + /// An `if` expression with an optional `else` block: `if expr { ... } + /// else { ... }`. + /// + /// The `else` branch expression may only be an `If` or `Block` + /// expression, not any of the other types of expression. + If(ExprIf), + + /// A square bracketed indexing expression: `vector[2]`. + Index(ExprIndex), + + /// The inferred value of a const generic argument, denoted `_`. + Infer(ExprInfer), + + /// A `let` guard: `let Some(x) = opt`. + Let(ExprLet), + + /// A literal in place of an expression: `1`, `"foo"`. + Lit(ExprLit), + + /// Conditionless loop: `loop { ... }`. + Loop(ExprLoop), + + /// A macro invocation expression: `format!("{}", q)`. + Macro(ExprMacro), + + /// A `match` expression: `match n { Some(n) => {}, None => {} }`. + Match(ExprMatch), + + /// A method call expression: `x.foo::(a, b)`. + MethodCall(ExprMethodCall), + + /// A parenthesized expression: `(a + b)`. + Paren(ExprParen), + + /// A path like `std::mem::replace` possibly containing generic + /// parameters and a qualified self-type. + /// + /// A plain identifier like `x` is a path of length 1. + Path(ExprPath), + + /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. + Range(ExprRange), + + /// A referencing operation: `&a` or `&mut a`. + Reference(ExprReference), + + /// An array literal constructed from one repeated element: `[0u8; N]`. + Repeat(ExprRepeat), + + /// A `return`, with an optional value to be returned. + Return(ExprReturn), + + /// A struct literal expression: `Point { x: 1, y: 1 }`. + /// + /// The `rest` provides the value of the remaining fields as in `S { a: + /// 1, b: 1, ..rest }`. + Struct(ExprStruct), + + /// A try-expression: `expr?`. + Try(ExprTry), + + /// A try block: `try { ... }`. + TryBlock(ExprTryBlock), + + /// A tuple expression: `(a, b, c, d)`. + Tuple(ExprTuple), + + /// A unary operation: `!x`, `*x`. + Unary(ExprUnary), + + /// An unsafe block: `unsafe { ... }`. + Unsafe(ExprUnsafe), + + /// Tokens in expression position not interpreted by Syn. + Verbatim(TokenStream), + + /// A while loop: `while expr { ... }`. + While(ExprWhile), + + /// A yield expression: `yield expr`. + Yield(ExprYield), + + // For testing exhaustiveness in downstream code, use the following idiom: + // + // match expr { + // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))] + // + // Expr::Array(expr) => {...} + // Expr::Assign(expr) => {...} + // ... + // Expr::Yield(expr) => {...} + // + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + } +} + +ast_struct! { + /// A slice literal expression: `[a, b, c, d]`. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + pub struct ExprArray #full { + pub attrs: Vec, + pub bracket_token: token::Bracket, + pub elems: Punctuated, + } +} + +ast_struct! { + /// An assignment expression: `a = compute()`. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + pub struct ExprAssign #full { + pub attrs: Vec, + pub left: Box, + pub eq_token: Token![=], + pub right: Box, + } +} + +ast_struct! { + /// An async block: `async { ... }`. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + pub struct ExprAsync #full { + pub attrs: Vec, + pub async_token: Token![async], + pub capture: Option, + pub block: Block, + } +} + +ast_struct! { + /// An await expression: `fut.await`. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + pub struct ExprAwait #full { + pub attrs: Vec, + pub base: Box, + pub dot_token: Token![.], + pub await_token: Token![await], + } +} + +ast_struct! { + /// A binary operation: `a + b`, `a += b`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct ExprBinary { + pub attrs: Vec, + pub left: Box, + pub op: BinOp, + pub right: Box, + } +} + +ast_struct! { + /// A blocked scope: `{ ... }`. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + pub struct ExprBlock #full { + pub attrs: Vec, + pub label: Option